Merge third_party/openssl from http://git.chromium.org/chromium/deps/openssl.git at 89348cf48391742cdbeb1aee3932fde25ff50e5a

This commit was generated by merge-from-chromium.py.

Change-Id: I79d2ed2b80c443a13a42b5d0f90be5d4fc1c3fa7
diff --git a/README.chromium b/README.chromium
new file mode 100644
index 0000000..9fd1e32
--- /dev/null
+++ b/README.chromium
@@ -0,0 +1,102 @@
+Name: openssl
+URL: http://openssl.org/source/
+Version: 1.0.0f
+License: BSDish
+License File: openssl/LICENSE
+License Android Compatible: yes
+Security Critical: yes
+
+Description:
+This is OpenSSL, the standard SSL/TLS library, which is used only in Android.
+
+It's an unmodified, upstream source except for the patches listed below.
+
+
+********************************************************************************
+The following patches are taken from Android Open Source Project.
+
+
+progs.patch:
+
+Fixup sources under the apps/ directory that are not built under the android environment.
+
+
+small_records.patch:
+
+Reduce OpenSSL memory consumption.
+SSL records may be as large as 16K, but are typically < 2K.  In
+addition, a historic bug in Windows allowed records to be as large
+32K.  OpenSSL statically allocates read and write buffers (34K and
+18K respectively) used for processing records.
+With this patch, OpenSSL statically allocates 4K + 4K buffers, with
+the option of dynamically growing buffers to 34K + 4K, which is a
+saving of 44K per connection for the typical case.
+
+
+handshake_cutthrough.patch
+
+Enables SSL3+ clients to send application data immediately following the
+Finished message even when negotiating full-handshakes.  With this patch,
+clients can negotiate SSL connections in 1-RTT even when performing
+full-handshakes.
+
+
+jsse.patch
+
+Support for JSSE implementation based on OpenSSL.
+
+
+npn.patch
+
+Transport Layer Security (TLS) Next Protocol Negotiation Extension
+
+
+sha1_armv4_large.patch
+
+This patch eliminates memory stores to addresses below SP.
+
+
+openssl_no_dtls1.patch
+
+Add missing #ifndef OPENSSL_NO_DTLS1
+
+
+********************************************************************************
+The following patches are needed to compile this openssl on Chromium and pass
+the related net unit tests.
+
+
+empty_OPENSSL_cpuid_setup.patch
+
+Use a empty implementation for function OPENSSL_cpuid_setup to resolve link
+error. We should figure out how to geenrate platform specific implementation
+of OPENSSL_cpuid_setup by leveraging crypto/*cpuid.pl.
+
+
+x509_hash_name_algorithm_change.patch
+
+There are many symbolic links under /etc/ssl/certs created by using hash of
+the pem certificates in order for OpenSSL to find those certificate.
+Openssl has a tool to help you create hash symbolic links. (See tools/c_rehash)
+However the new openssl changed the hash algorithm, Unless you compile/install
+the latest openssl library and re-create all related symbolic links, the new
+openssl can not find some certificates because the links of those certificates
+were created by using old hash algorithm, which causes some tests failed.
+This patch gives a way to find a certificate according to its hash by using both
+new algorithm and old algorithm.
+crbug.com/111045 is used to track this issue.
+
+
+tls_exporter.patch
+
+Keying Material Exporters for Transport Layer Security (RFC 5705).
+
+
+Android platform support
+
+Copy config/android/openssl/opensslconf.h from Android's
+external/openssl/include/openssl/opensslconf.h
+
+
+clang.patch
+Fix warnings when building with clang
diff --git a/buildinf.h b/buildinf.h
new file mode 100644
index 0000000..1a8e483
--- /dev/null
+++ b/buildinf.h
@@ -0,0 +1,7 @@
+/* crypto/Makefile usually creates the file at build time. Since we don't care
+ * about the build timestamp we fill in placeholder values. */
+#ifndef MK1MF_BUILD
+#define CFLAGS "-C flags not included-"
+#define PLATFORM "google"
+#define DATE "Sun Jan 1 00:00:00 GMT 1970"
+#endif
diff --git a/config/android/openssl/opensslconf.h b/config/android/openssl/opensslconf.h
new file mode 100644
index 0000000..26ac6ba
--- /dev/null
+++ b/config/android/openssl/opensslconf.h
@@ -0,0 +1,250 @@
+/* opensslconf.h */
+/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
+
+/* OpenSSL was configured with the following options: */
+#ifndef OPENSSL_DOING_MAKEDEPEND
+
+
+#ifndef OPENSSL_NO_CAST
+# define OPENSSL_NO_CAST
+#endif
+#ifndef OPENSSL_NO_GMP
+# define OPENSSL_NO_GMP
+#endif
+#ifndef OPENSSL_NO_IDEA
+# define OPENSSL_NO_IDEA
+#endif
+#ifndef OPENSSL_NO_JPAKE
+# define OPENSSL_NO_JPAKE
+#endif
+#ifndef OPENSSL_NO_KRB5
+# define OPENSSL_NO_KRB5
+#endif
+#ifndef OPENSSL_NO_MD2
+# define OPENSSL_NO_MD2
+#endif
+#ifndef OPENSSL_NO_RC5
+# define OPENSSL_NO_RC5
+#endif
+#ifndef OPENSSL_NO_RFC3779
+# define OPENSSL_NO_RFC3779
+#endif
+#ifndef OPENSSL_NO_SEED
+# define OPENSSL_NO_SEED
+#endif
+#ifndef OPENSSL_NO_SHA0
+# define OPENSSL_NO_SHA0
+#endif
+#ifndef OPENSSL_NO_STORE
+# define OPENSSL_NO_STORE
+#endif
+#ifndef OPENSSL_NO_WHRLPOOL
+# define OPENSSL_NO_WHRLPOOL
+#endif
+
+#endif /* OPENSSL_DOING_MAKEDEPEND */
+
+#ifndef OPENSSL_THREADS
+# define OPENSSL_THREADS
+#endif
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+# define OPENSSL_NO_DYNAMIC_ENGINE
+#endif
+
+/* The OPENSSL_NO_* macros are also defined as NO_* if the application
+   asks for it.  This is a transient feature that is provided for those
+   who haven't had the time to do the appropriate changes in their
+   applications.  */
+#ifdef OPENSSL_ALGORITHM_DEFINES
+# if defined(OPENSSL_NO_CAST) && !defined(NO_CAST)
+#  define NO_CAST
+# endif
+# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
+#  define NO_GMP
+# endif
+# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA)
+#  define NO_IDEA
+# endif
+# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
+#  define NO_JPAKE
+# endif
+# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
+#  define NO_KRB5
+# endif
+# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2)
+#  define NO_MD2
+# endif
+# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
+#  define NO_RC5
+# endif
+# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)
+#  define NO_RFC3779
+# endif
+# if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
+#  define NO_SEED
+# endif
+# if defined(OPENSSL_NO_SHA0) && !defined(NO_SHA0)
+#  define NO_SHA0
+# endif
+# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE)
+#  define NO_STORE
+# endif
+# if defined(OPENSSL_NO_WHRLPOOL) && !defined(NO_WHRLPOOL)
+#  define NO_WHRLPOOL
+# endif
+#endif
+
+/* crypto/opensslconf.h.in */
+
+/* Generate 80386 code? */
+#undef I386_ONLY
+
+#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
+#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
+#define ENGINESDIR "/usr/local/ssl/lib/engines"
+#define OPENSSLDIR "/usr/local/ssl"
+#endif
+#endif
+
+#undef OPENSSL_UNISTD
+#define OPENSSL_UNISTD <unistd.h>
+
+#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
+#define IDEA_INT unsigned int
+#endif
+
+#if defined(HEADER_MD2_H) && !defined(MD2_INT)
+#define MD2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC2_H) && !defined(RC2_INT)
+/* I need to put in a mod for the alpha - eay */
+#define RC2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC4_H)
+#if !defined(RC4_INT)
+/* using int types make the structure larger but make the code faster
+ * on most boxes I have tested - up to %20 faster. */
+/*
+ * I don't know what does "most" mean, but declaring "int" is a must on:
+ * - Intel P6 because partial register stalls are very expensive;
+ * - elder Alpha because it lacks byte load/store instructions;
+ */
+#define RC4_INT unsigned char
+#endif
+#if !defined(RC4_CHUNK)
+/*
+ * This enables code handling data aligned at natural CPU word
+ * boundary. See crypto/rc4/rc4_enc.c for further details.
+ */
+#define RC4_CHUNK unsigned long
+#endif
+#endif
+
+#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+#ifndef DES_LONG
+#define DES_LONG unsigned int
+#endif
+#endif
+
+#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
+#define CONFIG_HEADER_BN_H
+#define BN_LLONG
+
+/* Should we define BN_DIV2W here? */
+
+/* Only one for the following should be defined */
+#undef SIXTY_FOUR_BIT_LONG
+#undef SIXTY_FOUR_BIT
+#define THIRTY_TWO_BIT
+#endif
+
+#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
+#define CONFIG_HEADER_RC4_LOCL_H
+/* if this is defined data[i] is used instead of *data, this is a %20
+ * speedup on x86 */
+#undef RC4_INDEX
+#endif
+
+#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
+#define CONFIG_HEADER_BF_LOCL_H
+#define BF_PTR
+#endif /* HEADER_BF_LOCL_H */
+
+#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
+#define CONFIG_HEADER_DES_LOCL_H
+#ifndef DES_DEFAULT_OPTIONS
+/* the following is tweaked from a config script, that is why it is a
+ * protected undef/define */
+#ifndef DES_PTR
+#undef DES_PTR
+#endif
+
+/* This helps C compiler generate the correct code for multiple functional
+ * units.  It reduces register dependancies at the expense of 2 more
+ * registers */
+#ifndef DES_RISC1
+#undef DES_RISC1
+#endif
+
+#ifndef DES_RISC2
+#undef DES_RISC2
+#endif
+
+#if defined(DES_RISC1) && defined(DES_RISC2)
+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
+#endif
+
+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
+ * Very mucy CPU dependant */
+#ifndef DES_UNROLL
+#define DES_UNROLL
+#endif
+
+/* These default values were supplied by
+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
+ * They are only used if nothing else has been defined */
+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
+/* Special defines which change the way the code is built depending on the
+   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
+   even newer MIPS CPU's, but at the moment one size fits all for
+   optimization options.  Older Sparc's work better with only UNROLL, but
+   there's no way to tell at compile time what it is you're running on */
+ 
+#if defined( sun )		/* Newer Sparc's */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#elif defined( __ultrix )	/* Older MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined( __osf1__ )	/* Alpha */
+#  define DES_PTR
+#  define DES_RISC2
+#elif defined ( _AIX )		/* RS6000 */
+  /* Unknown */
+#elif defined( __hpux )		/* HP-PA */
+  /* Unknown */
+#elif defined( __aux )		/* 68K */
+  /* Unknown */
+#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
+#  define DES_UNROLL
+#elif defined( __sgi )		/* Newer MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined(i386) || defined(__i386__)	/* x86 boxes, should be gcc */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#endif /* Systems-specific speed defines */
+#endif
+
+#endif /* DES_DEFAULT_OPTIONS */
+#endif /* HEADER_DES_LOCL_H */
diff --git a/config/k8/openssl/opensslconf.h b/config/k8/openssl/opensslconf.h
new file mode 100644
index 0000000..f47e7b6
--- /dev/null
+++ b/config/k8/openssl/opensslconf.h
@@ -0,0 +1,278 @@
+/* opensslconf.h */
+/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
+
+/* OpenSSL was configured with the following options: */
+#ifndef OPENSSL_DOING_MAKEDEPEND
+
+
+#ifndef OPENSSL_NO_CAMELLIA
+# define OPENSSL_NO_CAMELLIA
+#endif
+#ifndef OPENSSL_NO_CAPIENG
+# define OPENSSL_NO_CAPIENG
+#endif
+#ifndef OPENSSL_NO_CMS
+# define OPENSSL_NO_CMS
+#endif
+#ifndef OPENSSL_NO_FIPS
+# define OPENSSL_NO_FIPS
+#endif
+#ifndef OPENSSL_NO_GMP
+# define OPENSSL_NO_GMP
+#endif
+#ifndef OPENSSL_NO_IDEA
+# define OPENSSL_NO_IDEA
+#endif
+#ifndef OPENSSL_NO_JPAKE
+# define OPENSSL_NO_JPAKE
+#endif
+#ifndef OPENSSL_NO_KRB5
+# define OPENSSL_NO_KRB5
+#endif
+#ifndef OPENSSL_NO_MDC2
+# define OPENSSL_NO_MDC2
+#endif
+#ifndef OPENSSL_NO_RC5
+# define OPENSSL_NO_RC5
+#endif
+#ifndef OPENSSL_NO_RFC3779
+# define OPENSSL_NO_RFC3779
+#endif
+#ifndef OPENSSL_NO_SEED
+# define OPENSSL_NO_SEED
+#endif
+#ifndef OPENSSL_NO_ASM
+# define OPENSSL_NO_ASM
+#endif
+
+#endif /* OPENSSL_DOING_MAKEDEPEND */
+
+#ifndef OPENSSL_THREADS
+# define OPENSSL_THREADS
+#endif
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+# define OPENSSL_NO_DYNAMIC_ENGINE
+#endif
+
+/* The OPENSSL_NO_* macros are also defined as NO_* if the application
+   asks for it.  This is a transient feature that is provided for those
+   who haven't had the time to do the appropriate changes in their
+   applications.  */
+#ifdef OPENSSL_ALGORITHM_DEFINES
+# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)
+#  define NO_CAMELLIA
+# endif
+# if defined(OPENSSL_NO_CAPIENG) && !defined(NO_CAPIENG)
+#  define NO_CAPIENG
+# endif
+# if defined(OPENSSL_NO_CMS) && !defined(NO_CMS)
+#  define NO_CMS
+# endif
+# if defined(OPENSSL_NO_FIPS) && !defined(NO_FIPS)
+#  define NO_FIPS
+# endif
+# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
+#  define NO_GMP
+# endif
+# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA)
+#  define NO_IDEA
+# endif
+# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
+#  define NO_JPAKE
+# endif
+# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
+#  define NO_KRB5
+# endif
+# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
+#  define NO_MDC2
+# endif
+# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
+#  define NO_RC5
+# endif
+# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)
+#  define NO_RFC3779
+# endif
+# if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
+#  define NO_SEED
+# endif
+#endif
+
+#define OPENSSL_CPUID_OBJ
+
+/* crypto/opensslconf.h.in */
+
+#ifdef OPENSSL_DOING_MAKEDEPEND
+
+/* Include any symbols here that have to be explicitly set to enable a feature
+ * that should be visible to makedepend.
+ *
+ * [Our "make depend" doesn't actually look at this, we use actual build settings
+ * instead; we want to make it easy to remove subdirectories with disabled algorithms.]
+ */
+
+#ifndef OPENSSL_FIPS
+#define OPENSSL_FIPS
+#endif
+
+#endif
+
+/* Generate 80386 code? */
+#undef I386_ONLY
+
+#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
+#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
+#define ENGINESDIR "/usr/local/ssl/lib/engines"
+#define OPENSSLDIR "/usr/local/ssl"
+#endif
+#endif
+
+#undef OPENSSL_UNISTD
+#define OPENSSL_UNISTD <unistd.h>
+#if !defined(SWIG)
+#include <unistd.h>
+#endif
+
+#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
+#define IDEA_INT unsigned int
+#endif
+
+#if defined(HEADER_MD2_H) && !defined(MD2_INT)
+#define MD2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC2_H) && !defined(RC2_INT)
+/* I need to put in a mod for the alpha - eay */
+#define RC2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC4_H)
+#if !defined(RC4_INT)
+/* using int types make the structure larger but make the code faster
+ * on most boxes I have tested - up to %20 faster. */
+/*
+ * I don't know what does "most" mean, but declaring "int" is a must on:
+ * - Intel P6 because partial register stalls are very expensive;
+ * - elder Alpha because it lacks byte load/store instructions;
+ */
+#define RC4_INT unsigned int
+#endif
+#if !defined(RC4_CHUNK)
+/*
+ * This enables code handling data aligned at natural CPU word
+ * boundary. See crypto/rc4/rc4_enc.c for further details.
+ */
+#define RC4_CHUNK unsigned long
+#endif
+#endif
+
+#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+#ifndef DES_LONG
+#define DES_LONG unsigned int
+#endif
+#endif
+
+#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
+#define CONFIG_HEADER_BN_H
+#undef BN_LLONG
+
+/* Should we define BN_DIV2W here? */
+
+/* Only one for the following should be defined */
+/* The prime number generation stuff may not work when
+ * EIGHT_BIT but I don't care since I've only used this mode
+ * for debuging the bignum libraries */
+#define SIXTY_FOUR_BIT_LONG
+#undef SIXTY_FOUR_BIT
+#undef THIRTY_TWO_BIT
+#undef SIXTEEN_BIT
+#undef EIGHT_BIT
+#endif
+
+#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
+#define CONFIG_HEADER_RC4_LOCL_H
+/* if this is defined data[i] is used instead of *data, this is a %20
+ * speedup on x86 */
+#undef RC4_INDEX
+#endif
+
+#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
+#define CONFIG_HEADER_BF_LOCL_H
+#undef BF_PTR
+#endif /* HEADER_BF_LOCL_H */
+
+#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
+#define CONFIG_HEADER_DES_LOCL_H
+#ifndef DES_DEFAULT_OPTIONS
+/* the following is tweaked from a config script, that is why it is a
+ * protected undef/define */
+#ifndef DES_PTR
+#undef DES_PTR
+#endif
+
+/* This helps C compiler generate the correct code for multiple functional
+ * units.  It reduces register dependancies at the expense of 2 more
+ * registers */
+#ifndef DES_RISC1
+#undef DES_RISC1
+#endif
+
+#ifndef DES_RISC2
+#undef DES_RISC2
+#endif
+
+#if defined(DES_RISC1) && defined(DES_RISC2)
+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
+#endif
+
+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
+ * Very mucy CPU dependant */
+#ifndef DES_UNROLL
+#define DES_UNROLL
+#endif
+
+/* These default values were supplied by
+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
+ * They are only used if nothing else has been defined */
+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
+/* Special defines which change the way the code is built depending on the
+   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
+   even newer MIPS CPU's, but at the moment one size fits all for
+   optimization options.  Older Sparc's work better with only UNROLL, but
+   there's no way to tell at compile time what it is you're running on */
+ 
+#if defined( sun )		/* Newer Sparc's */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#elif defined( __ultrix )	/* Older MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined( __osf1__ )	/* Alpha */
+#  define DES_PTR
+#  define DES_RISC2
+#elif defined ( _AIX )		/* RS6000 */
+  /* Unknown */
+#elif defined( __hpux )		/* HP-PA */
+  /* Unknown */
+#elif defined( __aux )		/* 68K */
+  /* Unknown */
+#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
+#  define DES_UNROLL
+#elif defined( __sgi )		/* Newer MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined(i386) || defined(__i386__)	/* x86 boxes, should be gcc */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#endif /* Systems-specific speed defines */
+#endif
+
+#endif /* DES_DEFAULT_OPTIONS */
+#endif /* HEADER_DES_LOCL_H */
diff --git a/config/piii/openssl/opensslconf.h b/config/piii/openssl/opensslconf.h
new file mode 100644
index 0000000..9725efa
--- /dev/null
+++ b/config/piii/openssl/opensslconf.h
@@ -0,0 +1,278 @@
+/* opensslconf.h */
+/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
+
+/* OpenSSL was configured with the following options: */
+#ifndef OPENSSL_DOING_MAKEDEPEND
+
+
+#ifndef OPENSSL_NO_CAMELLIA
+# define OPENSSL_NO_CAMELLIA
+#endif
+#ifndef OPENSSL_NO_CAPIENG
+# define OPENSSL_NO_CAPIENG
+#endif
+#ifndef OPENSSL_NO_CMS
+# define OPENSSL_NO_CMS
+#endif
+#ifndef OPENSSL_NO_FIPS
+# define OPENSSL_NO_FIPS
+#endif
+#ifndef OPENSSL_NO_GMP
+# define OPENSSL_NO_GMP
+#endif
+#ifndef OPENSSL_NO_IDEA
+# define OPENSSL_NO_IDEA
+#endif
+#ifndef OPENSSL_NO_JPAKE
+# define OPENSSL_NO_JPAKE
+#endif
+#ifndef OPENSSL_NO_KRB5
+# define OPENSSL_NO_KRB5
+#endif
+#ifndef OPENSSL_NO_MDC2
+# define OPENSSL_NO_MDC2
+#endif
+#ifndef OPENSSL_NO_RC5
+# define OPENSSL_NO_RC5
+#endif
+#ifndef OPENSSL_NO_RFC3779
+# define OPENSSL_NO_RFC3779
+#endif
+#ifndef OPENSSL_NO_SEED
+# define OPENSSL_NO_SEED
+#endif
+#ifndef OPENSSL_NO_ASM
+# define OPENSSL_NO_ASM
+#endif
+
+#endif /* OPENSSL_DOING_MAKEDEPEND */
+
+#ifndef OPENSSL_THREADS
+# define OPENSSL_THREADS
+#endif
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+# define OPENSSL_NO_DYNAMIC_ENGINE
+#endif
+
+/* The OPENSSL_NO_* macros are also defined as NO_* if the application
+   asks for it.  This is a transient feature that is provided for those
+   who haven't had the time to do the appropriate changes in their
+   applications.  */
+#ifdef OPENSSL_ALGORITHM_DEFINES
+# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)
+#  define NO_CAMELLIA
+# endif
+# if defined(OPENSSL_NO_CAPIENG) && !defined(NO_CAPIENG)
+#  define NO_CAPIENG
+# endif
+# if defined(OPENSSL_NO_CMS) && !defined(NO_CMS)
+#  define NO_CMS
+# endif
+# if defined(OPENSSL_NO_FIPS) && !defined(NO_FIPS)
+#  define NO_FIPS
+# endif
+# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
+#  define NO_GMP
+# endif
+# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA)
+#  define NO_IDEA
+# endif
+# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
+#  define NO_JPAKE
+# endif
+# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
+#  define NO_KRB5
+# endif
+# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
+#  define NO_MDC2
+# endif
+# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
+#  define NO_RC5
+# endif
+# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)
+#  define NO_RFC3779
+# endif
+# if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
+#  define NO_SEED
+# endif
+#endif
+
+#define OPENSSL_CPUID_OBJ
+
+/* crypto/opensslconf.h.in */
+
+#ifdef OPENSSL_DOING_MAKEDEPEND
+
+/* Include any symbols here that have to be explicitly set to enable a feature
+ * that should be visible to makedepend.
+ *
+ * [Our "make depend" doesn't actually look at this, we use actual build settings
+ * instead; we want to make it easy to remove subdirectories with disabled algorithms.]
+ */
+
+#ifndef OPENSSL_FIPS
+#define OPENSSL_FIPS
+#endif
+
+#endif
+
+/* Generate 80386 code? */
+#undef I386_ONLY
+
+#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
+#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
+#define ENGINESDIR "/usr/local/ssl/lib/engines"
+#define OPENSSLDIR "/usr/local/ssl"
+#endif
+#endif
+
+#undef OPENSSL_UNISTD
+#define OPENSSL_UNISTD <unistd.h>
+#if !defined(SWIG)
+#include <unistd.h>
+#endif
+
+#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
+#define IDEA_INT unsigned int
+#endif
+
+#if defined(HEADER_MD2_H) && !defined(MD2_INT)
+#define MD2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC2_H) && !defined(RC2_INT)
+/* I need to put in a mod for the alpha - eay */
+#define RC2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC4_H)
+#if !defined(RC4_INT)
+/* using int types make the structure larger but make the code faster
+ * on most boxes I have tested - up to %20 faster. */
+/*
+ * I don't know what does "most" mean, but declaring "int" is a must on:
+ * - Intel P6 because partial register stalls are very expensive;
+ * - elder Alpha because it lacks byte load/store instructions;
+ */
+#define RC4_INT unsigned int
+#endif
+#if !defined(RC4_CHUNK)
+/*
+ * This enables code handling data aligned at natural CPU word
+ * boundary. See crypto/rc4/rc4_enc.c for further details.
+ */
+#undef RC4_CHUNK
+#endif
+#endif
+
+#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+#ifndef DES_LONG
+#define DES_LONG unsigned long
+#endif
+#endif
+
+#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
+#define CONFIG_HEADER_BN_H
+#define BN_LLONG
+
+/* Should we define BN_DIV2W here? */
+
+/* Only one for the following should be defined */
+/* The prime number generation stuff may not work when
+ * EIGHT_BIT but I don't care since I've only used this mode
+ * for debuging the bignum libraries */
+#undef SIXTY_FOUR_BIT_LONG
+#undef SIXTY_FOUR_BIT
+#define THIRTY_TWO_BIT
+#undef SIXTEEN_BIT
+#undef EIGHT_BIT
+#endif
+
+#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
+#define CONFIG_HEADER_RC4_LOCL_H
+/* if this is defined data[i] is used instead of *data, this is a %20
+ * speedup on x86 */
+#define RC4_INDEX
+#endif
+
+#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
+#define CONFIG_HEADER_BF_LOCL_H
+#undef BF_PTR
+#endif /* HEADER_BF_LOCL_H */
+
+#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
+#define CONFIG_HEADER_DES_LOCL_H
+#ifndef DES_DEFAULT_OPTIONS
+/* the following is tweaked from a config script, that is why it is a
+ * protected undef/define */
+#ifndef DES_PTR
+#define DES_PTR
+#endif
+
+/* This helps C compiler generate the correct code for multiple functional
+ * units.  It reduces register dependancies at the expense of 2 more
+ * registers */
+#ifndef DES_RISC1
+#define DES_RISC1
+#endif
+
+#ifndef DES_RISC2
+#undef DES_RISC2
+#endif
+
+#if defined(DES_RISC1) && defined(DES_RISC2)
+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
+#endif
+
+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
+ * Very mucy CPU dependant */
+#ifndef DES_UNROLL
+#define DES_UNROLL
+#endif
+
+/* These default values were supplied by
+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
+ * They are only used if nothing else has been defined */
+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
+/* Special defines which change the way the code is built depending on the
+   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
+   even newer MIPS CPU's, but at the moment one size fits all for
+   optimization options.  Older Sparc's work better with only UNROLL, but
+   there's no way to tell at compile time what it is you're running on */
+ 
+#if defined( sun )		/* Newer Sparc's */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#elif defined( __ultrix )	/* Older MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined( __osf1__ )	/* Alpha */
+#  define DES_PTR
+#  define DES_RISC2
+#elif defined ( _AIX )		/* RS6000 */
+  /* Unknown */
+#elif defined( __hpux )		/* HP-PA */
+  /* Unknown */
+#elif defined( __aux )		/* 68K */
+  /* Unknown */
+#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
+#  define DES_UNROLL
+#elif defined( __sgi )		/* Newer MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined(i386) || defined(__i386__)	/* x86 boxes, should be gcc */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#endif /* Systems-specific speed defines */
+#endif
+
+#endif /* DES_DEFAULT_OPTIONS */
+#endif /* HEADER_DES_LOCL_H */
diff --git a/openssl.gyp b/openssl.gyp
new file mode 100644
index 0000000..c9bf79f
--- /dev/null
+++ b/openssl.gyp
@@ -0,0 +1,695 @@
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'targets': [
+    {
+      'target_name': 'openssl',
+      'type': '<(library)',
+      'defines': [
+        'L_ENDIAN',
+        'OPENSSL_THREADS',
+        'PURIFY',
+        'TERMIO',
+        '_REENTRANT',
+        # We do not use TLS over UDP on Chromium so far.
+        'OPENSSL_NO_DTLS1',
+      ],
+      'sources': [
+        'openssl/ssl/bio_ssl.c',
+        'openssl/ssl/d1_both.c',
+        'openssl/ssl/d1_clnt.c',
+        'openssl/ssl/d1_enc.c',
+        'openssl/ssl/d1_lib.c',
+        'openssl/ssl/d1_meth.c',
+        'openssl/ssl/d1_pkt.c',
+        'openssl/ssl/d1_srvr.c',
+        'openssl/ssl/kssl.c',
+        'openssl/ssl/s23_clnt.c',
+        'openssl/ssl/s23_lib.c',
+        'openssl/ssl/s23_meth.c',
+        'openssl/ssl/s23_pkt.c',
+        'openssl/ssl/s23_srvr.c',
+        'openssl/ssl/s2_clnt.c',
+        'openssl/ssl/s2_enc.c',
+        'openssl/ssl/s2_lib.c',
+        'openssl/ssl/s2_meth.c',
+        'openssl/ssl/s2_pkt.c',
+        'openssl/ssl/s2_srvr.c',
+        'openssl/ssl/s3_both.c',
+        'openssl/ssl/s3_clnt.c',
+        'openssl/ssl/s3_enc.c',
+        'openssl/ssl/s3_lib.c',
+        'openssl/ssl/s3_meth.c',
+        'openssl/ssl/s3_pkt.c',
+        'openssl/ssl/s3_srvr.c',
+        'openssl/ssl/ssl_algs.c',
+        'openssl/ssl/ssl_asn1.c',
+        'openssl/ssl/ssl_cert.c',
+        'openssl/ssl/ssl_ciph.c',
+        'openssl/ssl/ssl_err.c',
+        'openssl/ssl/ssl_err2.c',
+        'openssl/ssl/ssl_lib.c',
+        'openssl/ssl/ssl_rsa.c',
+        'openssl/ssl/ssl_sess.c',
+        'openssl/ssl/ssl_stat.c',
+        'openssl/ssl/ssl_txt.c',
+        'openssl/ssl/t1_clnt.c',
+        'openssl/ssl/t1_enc.c',
+        'openssl/ssl/t1_lib.c',
+        'openssl/ssl/t1_meth.c',
+        'openssl/ssl/t1_reneg.c',
+        'openssl/ssl/t1_srvr.c',
+
+        'openssl/crypto/aes/aes_cbc.c',
+        'openssl/crypto/aes/aes_cfb.c',
+        'openssl/crypto/aes/aes_core.c',
+        'openssl/crypto/aes/aes_ctr.c',
+        'openssl/crypto/aes/aes_ecb.c',
+        'openssl/crypto/aes/aes_ige.c',
+        'openssl/crypto/aes/aes_misc.c',
+        'openssl/crypto/aes/aes_ofb.c',
+        'openssl/crypto/aes/aes_wrap.c',
+        'openssl/crypto/asn1/a_bitstr.c',
+        'openssl/crypto/asn1/a_bool.c',
+        'openssl/crypto/asn1/a_bytes.c',
+        'openssl/crypto/asn1/a_d2i_fp.c',
+        'openssl/crypto/asn1/a_digest.c',
+        'openssl/crypto/asn1/a_dup.c',
+        'openssl/crypto/asn1/a_enum.c',
+        'openssl/crypto/asn1/a_gentm.c',
+        'openssl/crypto/asn1/a_i2d_fp.c',
+        'openssl/crypto/asn1/a_int.c',
+        'openssl/crypto/asn1/a_mbstr.c',
+        'openssl/crypto/asn1/a_object.c',
+        'openssl/crypto/asn1/a_octet.c',
+        'openssl/crypto/asn1/a_print.c',
+        'openssl/crypto/asn1/a_set.c',
+        'openssl/crypto/asn1/a_sign.c',
+        'openssl/crypto/asn1/a_strex.c',
+        'openssl/crypto/asn1/a_strnid.c',
+        'openssl/crypto/asn1/a_time.c',
+        'openssl/crypto/asn1/a_type.c',
+        'openssl/crypto/asn1/a_utctm.c',
+        'openssl/crypto/asn1/a_utf8.c',
+        'openssl/crypto/asn1/a_verify.c',
+        'openssl/crypto/asn1/ameth_lib.c',
+        'openssl/crypto/asn1/asn1_err.c',
+        'openssl/crypto/asn1/asn1_gen.c',
+        'openssl/crypto/asn1/asn1_lib.c',
+        'openssl/crypto/asn1/asn1_par.c',
+        'openssl/crypto/asn1/asn_mime.c',
+        'openssl/crypto/asn1/asn_moid.c',
+        'openssl/crypto/asn1/asn_pack.c',
+        'openssl/crypto/asn1/bio_asn1.c',
+        'openssl/crypto/asn1/bio_ndef.c',
+        'openssl/crypto/asn1/d2i_pr.c',
+        'openssl/crypto/asn1/d2i_pu.c',
+        'openssl/crypto/asn1/evp_asn1.c',
+        'openssl/crypto/asn1/f_enum.c',
+        'openssl/crypto/asn1/f_int.c',
+        'openssl/crypto/asn1/f_string.c',
+        'openssl/crypto/asn1/i2d_pr.c',
+        'openssl/crypto/asn1/i2d_pu.c',
+        'openssl/crypto/asn1/n_pkey.c',
+        'openssl/crypto/asn1/nsseq.c',
+        'openssl/crypto/asn1/p5_pbe.c',
+        'openssl/crypto/asn1/p5_pbev2.c',
+        'openssl/crypto/asn1/p8_pkey.c',
+        'openssl/crypto/asn1/t_bitst.c',
+        'openssl/crypto/asn1/t_crl.c',
+        'openssl/crypto/asn1/t_pkey.c',
+        'openssl/crypto/asn1/t_req.c',
+        'openssl/crypto/asn1/t_spki.c',
+        'openssl/crypto/asn1/t_x509.c',
+        'openssl/crypto/asn1/t_x509a.c',
+        'openssl/crypto/asn1/tasn_dec.c',
+        'openssl/crypto/asn1/tasn_enc.c',
+        'openssl/crypto/asn1/tasn_fre.c',
+        'openssl/crypto/asn1/tasn_new.c',
+        'openssl/crypto/asn1/tasn_prn.c',
+        'openssl/crypto/asn1/tasn_typ.c',
+        'openssl/crypto/asn1/tasn_utl.c',
+        'openssl/crypto/asn1/x_algor.c',
+        'openssl/crypto/asn1/x_attrib.c',
+        'openssl/crypto/asn1/x_bignum.c',
+        'openssl/crypto/asn1/x_crl.c',
+        'openssl/crypto/asn1/x_exten.c',
+        'openssl/crypto/asn1/x_info.c',
+        'openssl/crypto/asn1/x_long.c',
+        'openssl/crypto/asn1/x_name.c',
+        'openssl/crypto/asn1/x_nx509.c',
+        'openssl/crypto/asn1/x_pkey.c',
+        'openssl/crypto/asn1/x_pubkey.c',
+        'openssl/crypto/asn1/x_req.c',
+        'openssl/crypto/asn1/x_sig.c',
+        'openssl/crypto/asn1/x_spki.c',
+        'openssl/crypto/asn1/x_val.c',
+        'openssl/crypto/asn1/x_x509.c',
+        'openssl/crypto/asn1/x_x509a.c',
+        'openssl/crypto/bf/bf_cfb64.c',
+        'openssl/crypto/bf/bf_ecb.c',
+        'openssl/crypto/bf/bf_enc.c',
+        'openssl/crypto/bf/bf_enc.c',
+        'openssl/crypto/bf/bf_ofb64.c',
+        'openssl/crypto/bf/bf_skey.c',
+        'openssl/crypto/bio/b_dump.c',
+        'openssl/crypto/bio/b_print.c',
+        'openssl/crypto/bio/b_sock.c',
+        'openssl/crypto/bio/bf_buff.c',
+        'openssl/crypto/bio/bf_nbio.c',
+        'openssl/crypto/bio/bf_null.c',
+        'openssl/crypto/bio/bio_cb.c',
+        'openssl/crypto/bio/bio_err.c',
+        'openssl/crypto/bio/bio_lib.c',
+        'openssl/crypto/bio/bss_acpt.c',
+        'openssl/crypto/bio/bss_bio.c',
+        'openssl/crypto/bio/bss_conn.c',
+        'openssl/crypto/bio/bss_dgram.c',
+        'openssl/crypto/bio/bss_fd.c',
+        'openssl/crypto/bio/bss_file.c',
+        'openssl/crypto/bio/bss_log.c',
+        'openssl/crypto/bio/bss_mem.c',
+        'openssl/crypto/bio/bss_null.c',
+        'openssl/crypto/bio/bss_sock.c',
+        'openssl/crypto/bn/bn_add.c',
+        'openssl/crypto/bn/bn_asm.c',
+        'openssl/crypto/bn/bn_blind.c',
+        'openssl/crypto/bn/bn_const.c',
+        'openssl/crypto/bn/bn_ctx.c',
+        'openssl/crypto/bn/bn_depr.c',
+        'openssl/crypto/bn/bn_div.c',
+        'openssl/crypto/bn/bn_err.c',
+        'openssl/crypto/bn/bn_exp.c',
+        'openssl/crypto/bn/bn_exp2.c',
+        'openssl/crypto/bn/bn_gcd.c',
+        'openssl/crypto/bn/bn_gf2m.c',
+        'openssl/crypto/bn/bn_kron.c',
+        'openssl/crypto/bn/bn_lib.c',
+        'openssl/crypto/bn/bn_mod.c',
+        'openssl/crypto/bn/bn_mont.c',
+        'openssl/crypto/bn/bn_mpi.c',
+        'openssl/crypto/bn/bn_mul.c',
+        'openssl/crypto/bn/bn_nist.c',
+        'openssl/crypto/bn/bn_prime.c',
+        'openssl/crypto/bn/bn_print.c',
+        'openssl/crypto/bn/bn_rand.c',
+        'openssl/crypto/bn/bn_recp.c',
+        'openssl/crypto/bn/bn_shift.c',
+        'openssl/crypto/bn/bn_sqr.c',
+        'openssl/crypto/bn/bn_sqrt.c',
+        'openssl/crypto/bn/bn_word.c',
+        'openssl/crypto/buffer/buf_err.c',
+        'openssl/crypto/buffer/buffer.c',
+        'openssl/crypto/camellia/camellia.c',
+        'openssl/crypto/camellia/cmll_cbc.c',
+        'openssl/crypto/camellia/cmll_cfb.c',
+        'openssl/crypto/camellia/cmll_ctr.c',
+        'openssl/crypto/camellia/cmll_ecb.c',
+        'openssl/crypto/camellia/cmll_misc.c',
+        'openssl/crypto/camellia/cmll_ofb.c',
+        'openssl/crypto/cast/c_cfb64.c',
+        'openssl/crypto/cast/c_ecb.c',
+        'openssl/crypto/cast/c_enc.c',
+        'openssl/crypto/cast/c_ofb64.c',
+        'openssl/crypto/cast/c_skey.c',
+        'openssl/crypto/cms/cms_asn1.c',
+        'openssl/crypto/cms/cms_att.c',
+        'openssl/crypto/cms/cms_cd.c',
+        'openssl/crypto/cms/cms_dd.c',
+        'openssl/crypto/cms/cms_enc.c',
+        'openssl/crypto/cms/cms_env.c',
+        'openssl/crypto/cms/cms_err.c',
+        'openssl/crypto/cms/cms_ess.c',
+        'openssl/crypto/cms/cms_io.c',
+        'openssl/crypto/cms/cms_lib.c',
+        'openssl/crypto/cms/cms_sd.c',
+        'openssl/crypto/cms/cms_smime.c',
+        'openssl/crypto/comp/c_rle.c',
+        'openssl/crypto/comp/c_zlib.c',
+        'openssl/crypto/comp/comp_err.c',
+        'openssl/crypto/comp/comp_lib.c',
+        'openssl/crypto/conf/conf_api.c',
+        'openssl/crypto/conf/conf_def.c',
+        'openssl/crypto/conf/conf_err.c',
+        'openssl/crypto/conf/conf_lib.c',
+        'openssl/crypto/conf/conf_mall.c',
+        'openssl/crypto/conf/conf_mod.c',
+        'openssl/crypto/conf/conf_sap.c',
+        'openssl/crypto/cpt_err.c',
+        'openssl/crypto/cryptlib.c',
+        'openssl/crypto/cversion.c',
+        'openssl/crypto/des/cbc_cksm.c',
+        'openssl/crypto/des/cbc_enc.c',
+        'openssl/crypto/des/cfb64ede.c',
+        'openssl/crypto/des/cfb64enc.c',
+        'openssl/crypto/des/cfb_enc.c',
+        'openssl/crypto/des/des_enc.c',
+        'openssl/crypto/des/des_old.c',
+        'openssl/crypto/des/des_old2.c',
+        'openssl/crypto/des/ecb3_enc.c',
+        'openssl/crypto/des/ecb_enc.c',
+        'openssl/crypto/des/ede_cbcm_enc.c',
+        'openssl/crypto/des/enc_read.c',
+        'openssl/crypto/des/enc_writ.c',
+        'openssl/crypto/des/fcrypt.c',
+        'openssl/crypto/des/fcrypt_b.c',
+        'openssl/crypto/des/ofb64ede.c',
+        'openssl/crypto/des/ofb64enc.c',
+        'openssl/crypto/des/ofb_enc.c',
+        'openssl/crypto/des/pcbc_enc.c',
+        'openssl/crypto/des/qud_cksm.c',
+        'openssl/crypto/des/rand_key.c',
+        'openssl/crypto/des/read2pwd.c',
+        'openssl/crypto/des/rpc_enc.c',
+        'openssl/crypto/des/set_key.c',
+        'openssl/crypto/des/str2key.c',
+        'openssl/crypto/des/xcbc_enc.c',
+        'openssl/crypto/dh/dh_ameth.c',
+        'openssl/crypto/dh/dh_asn1.c',
+        'openssl/crypto/dh/dh_check.c',
+        'openssl/crypto/dh/dh_depr.c',
+        'openssl/crypto/dh/dh_err.c',
+        'openssl/crypto/dh/dh_gen.c',
+        'openssl/crypto/dh/dh_key.c',
+        'openssl/crypto/dh/dh_lib.c',
+        'openssl/crypto/dh/dh_pmeth.c',
+        'openssl/crypto/dh/dh_prn.c',
+        'openssl/crypto/dsa/dsa_ameth.c',
+        'openssl/crypto/dsa/dsa_asn1.c',
+        'openssl/crypto/dsa/dsa_depr.c',
+        'openssl/crypto/dsa/dsa_err.c',
+        'openssl/crypto/dsa/dsa_gen.c',
+        'openssl/crypto/dsa/dsa_key.c',
+        'openssl/crypto/dsa/dsa_lib.c',
+        'openssl/crypto/dsa/dsa_ossl.c',
+        'openssl/crypto/dsa/dsa_pmeth.c',
+        'openssl/crypto/dsa/dsa_prn.c',
+        'openssl/crypto/dsa/dsa_sign.c',
+        'openssl/crypto/dsa/dsa_vrf.c',
+        'openssl/crypto/dso/dso_beos.c',
+        'openssl/crypto/dso/dso_err.c',
+        'openssl/crypto/dso/dso_lib.c',
+        'openssl/crypto/dso/dso_null.c',
+        'openssl/crypto/dso/dso_openssl.c',
+        'openssl/crypto/ebcdic.c',
+        'openssl/crypto/ec/ec2_mult.c',
+        'openssl/crypto/ec/ec2_smpl.c',
+        'openssl/crypto/ec/ec_asn1.c',
+        'openssl/crypto/ec/ec_ameth.c',
+        'openssl/crypto/ec/ec_check.c',
+        'openssl/crypto/ec/ec_curve.c',
+        'openssl/crypto/ec/ec_cvt.c',
+        'openssl/crypto/ec/ec_err.c',
+        'openssl/crypto/ec/ec_key.c',
+        'openssl/crypto/ec/ec_lib.c',
+        'openssl/crypto/ec/ec_mult.c',
+        'openssl/crypto/ec/ec_pmeth.c',
+        'openssl/crypto/ec/ec_print.c',
+        'openssl/crypto/ec/eck_prn.c',
+        'openssl/crypto/ec/ecp_mont.c',
+        'openssl/crypto/ec/ecp_nist.c',
+        'openssl/crypto/ec/ecp_smpl.c',
+        'openssl/crypto/ecdh/ech_err.c',
+        'openssl/crypto/ecdh/ech_key.c',
+        'openssl/crypto/ecdh/ech_lib.c',
+        'openssl/crypto/ecdh/ech_ossl.c',
+        'openssl/crypto/ecdsa/ecs_asn1.c',
+        'openssl/crypto/ecdsa/ecs_err.c',
+        'openssl/crypto/ecdsa/ecs_lib.c',
+        'openssl/crypto/ecdsa/ecs_ossl.c',
+        'openssl/crypto/ecdsa/ecs_sign.c',
+        'openssl/crypto/ecdsa/ecs_vrf.c',
+        'openssl/crypto/engine/eng_all.c',
+        'openssl/crypto/engine/eng_cnf.c',
+        'openssl/crypto/engine/eng_cryptodev.c',
+        'openssl/crypto/engine/eng_ctrl.c',
+        'openssl/crypto/engine/eng_dyn.c',
+        'openssl/crypto/engine/eng_err.c',
+        'openssl/crypto/engine/eng_fat.c',
+        'openssl/crypto/engine/eng_init.c',
+        'openssl/crypto/engine/eng_lib.c',
+        'openssl/crypto/engine/eng_list.c',
+        'openssl/crypto/engine/eng_openssl.c',
+        'openssl/crypto/engine/eng_pkey.c',
+        'openssl/crypto/engine/eng_table.c',
+        'openssl/crypto/engine/tb_asnmth.c',
+        'openssl/crypto/engine/tb_cipher.c',
+        'openssl/crypto/engine/tb_dh.c',
+        'openssl/crypto/engine/tb_digest.c',
+        'openssl/crypto/engine/tb_dsa.c',
+        'openssl/crypto/engine/tb_ecdh.c',
+        'openssl/crypto/engine/tb_ecdsa.c',
+        'openssl/crypto/engine/tb_pkmeth.c',
+        'openssl/crypto/engine/tb_rand.c',
+        'openssl/crypto/engine/tb_rsa.c',
+        'openssl/crypto/engine/tb_store.c',
+        'openssl/crypto/err/err.c',
+        'openssl/crypto/err/err_all.c',
+        'openssl/crypto/err/err_prn.c',
+        'openssl/crypto/evp/bio_b64.c',
+        'openssl/crypto/evp/bio_enc.c',
+        'openssl/crypto/evp/bio_md.c',
+        'openssl/crypto/evp/bio_ok.c',
+        'openssl/crypto/evp/c_all.c',
+        'openssl/crypto/evp/c_allc.c',
+        'openssl/crypto/evp/c_alld.c',
+        'openssl/crypto/evp/digest.c',
+        'openssl/crypto/evp/e_aes.c',
+        'openssl/crypto/evp/e_bf.c',
+        'openssl/crypto/evp/e_camellia.c',
+        'openssl/crypto/evp/e_cast.c',
+        'openssl/crypto/evp/e_des.c',
+        'openssl/crypto/evp/e_des3.c',
+        'openssl/crypto/evp/e_null.c',
+        'openssl/crypto/evp/e_old.c',
+        'openssl/crypto/evp/e_rc2.c',
+        'openssl/crypto/evp/e_rc4.c',
+        'openssl/crypto/evp/e_rc5.c',
+        'openssl/crypto/evp/e_seed.c',
+        'openssl/crypto/evp/e_xcbc_d.c',
+        'openssl/crypto/evp/encode.c',
+        'openssl/crypto/evp/evp_acnf.c',
+        'openssl/crypto/evp/evp_enc.c',
+        'openssl/crypto/evp/evp_err.c',
+        'openssl/crypto/evp/evp_key.c',
+        'openssl/crypto/evp/evp_lib.c',
+        'openssl/crypto/evp/evp_pbe.c',
+        'openssl/crypto/evp/evp_pkey.c',
+        'openssl/crypto/evp/m_dss.c',
+        'openssl/crypto/evp/m_dss1.c',
+        'openssl/crypto/evp/m_ecdsa.c',
+        'openssl/crypto/evp/m_md2.c',
+        'openssl/crypto/evp/m_md4.c',
+        'openssl/crypto/evp/m_md5.c',
+        'openssl/crypto/evp/m_mdc2.c',
+        'openssl/crypto/evp/m_null.c',
+        'openssl/crypto/evp/m_ripemd.c',
+        'openssl/crypto/evp/m_sha.c',
+        'openssl/crypto/evp/m_sha1.c',
+        'openssl/crypto/evp/m_sigver.c',
+        'openssl/crypto/evp/m_wp.c',
+        'openssl/crypto/evp/names.c',
+        'openssl/crypto/evp/p5_crpt.c',
+        'openssl/crypto/evp/p5_crpt2.c',
+        'openssl/crypto/evp/p_dec.c',
+        'openssl/crypto/evp/p_enc.c',
+        'openssl/crypto/evp/p_lib.c',
+        'openssl/crypto/evp/p_open.c',
+        'openssl/crypto/evp/p_seal.c',
+        'openssl/crypto/evp/p_sign.c',
+        'openssl/crypto/evp/p_verify.c',
+        'openssl/crypto/evp/pmeth_fn.c',
+        'openssl/crypto/evp/pmeth_gn.c',
+        'openssl/crypto/evp/pmeth_lib.c',
+        'openssl/crypto/ex_data.c',
+        'openssl/crypto/hmac/hm_ameth.c',
+        'openssl/crypto/hmac/hm_pmeth.c',
+        'openssl/crypto/hmac/hmac.c',
+        'openssl/crypto/krb5/krb5_asn.c',
+        'openssl/crypto/lhash/lh_stats.c',
+        'openssl/crypto/lhash/lhash.c',
+        'openssl/crypto/md2/md2_dgst.c',
+        'openssl/crypto/md2/md2_one.c',
+        'openssl/crypto/md4/md4_dgst.c',
+        'openssl/crypto/md4/md4_one.c',
+        'openssl/crypto/md5/md5_dgst.c',
+        'openssl/crypto/md5/md5_one.c',
+        'openssl/crypto/mdc2/mdc2dgst.c',
+        'openssl/crypto/mdc2/mdc2_one.c',
+        'openssl/crypto/mem.c',
+        'openssl/crypto/mem_clr.c',
+        'openssl/crypto/mem_dbg.c',
+        'openssl/crypto/modes/cbc128.c',
+        'openssl/crypto/modes/cfb128.c',
+        'openssl/crypto/modes/ctr128.c',
+        'openssl/crypto/modes/cts128.c',
+        'openssl/crypto/modes/ofb128.c',
+        'openssl/crypto/o_dir.c',
+        'openssl/crypto/o_str.c',
+        'openssl/crypto/o_time.c',
+        'openssl/crypto/objects/o_names.c',
+        'openssl/crypto/objects/obj_dat.c',
+        'openssl/crypto/objects/obj_err.c',
+        'openssl/crypto/objects/obj_lib.c',
+        'openssl/crypto/objects/obj_xref.c',
+        'openssl/crypto/ocsp/ocsp_asn.c',
+        'openssl/crypto/ocsp/ocsp_cl.c',
+        'openssl/crypto/ocsp/ocsp_err.c',
+        'openssl/crypto/ocsp/ocsp_ext.c',
+        'openssl/crypto/ocsp/ocsp_ht.c',
+        'openssl/crypto/ocsp/ocsp_lib.c',
+        'openssl/crypto/ocsp/ocsp_prn.c',
+        'openssl/crypto/ocsp/ocsp_srv.c',
+        'openssl/crypto/ocsp/ocsp_vfy.c',
+        'openssl/crypto/pem/pem_all.c',
+        'openssl/crypto/pem/pem_err.c',
+        'openssl/crypto/pem/pem_info.c',
+        'openssl/crypto/pem/pem_lib.c',
+        'openssl/crypto/pem/pem_oth.c',
+        'openssl/crypto/pem/pem_pk8.c',
+        'openssl/crypto/pem/pem_pkey.c',
+        'openssl/crypto/pem/pem_seal.c',
+        'openssl/crypto/pem/pem_sign.c',
+        'openssl/crypto/pem/pem_x509.c',
+        'openssl/crypto/pem/pem_xaux.c',
+        'openssl/crypto/pem/pvkfmt.c',
+        'openssl/crypto/pkcs12/p12_add.c',
+        'openssl/crypto/pkcs12/p12_asn.c',
+        'openssl/crypto/pkcs12/p12_attr.c',
+        'openssl/crypto/pkcs12/p12_crpt.c',
+        'openssl/crypto/pkcs12/p12_crt.c',
+        'openssl/crypto/pkcs12/p12_decr.c',
+        'openssl/crypto/pkcs12/p12_init.c',
+        'openssl/crypto/pkcs12/p12_key.c',
+        'openssl/crypto/pkcs12/p12_kiss.c',
+        'openssl/crypto/pkcs12/p12_mutl.c',
+        'openssl/crypto/pkcs12/p12_npas.c',
+        'openssl/crypto/pkcs12/p12_p8d.c',
+        'openssl/crypto/pkcs12/p12_p8e.c',
+        'openssl/crypto/pkcs12/p12_utl.c',
+        'openssl/crypto/pkcs12/pk12err.c',
+        'openssl/crypto/pkcs7/bio_pk7.c',
+        'openssl/crypto/pkcs7/pk7_asn1.c',
+        'openssl/crypto/pkcs7/pk7_attr.c',
+        'openssl/crypto/pkcs7/pk7_doit.c',
+        'openssl/crypto/pkcs7/pk7_lib.c',
+        'openssl/crypto/pkcs7/pk7_mime.c',
+        'openssl/crypto/pkcs7/pk7_smime.c',
+        'openssl/crypto/pkcs7/pkcs7err.c',
+        'openssl/crypto/pqueue/pqueue.c',
+        'openssl/crypto/rand/md_rand.c',
+        'openssl/crypto/rand/rand_egd.c',
+        'openssl/crypto/rand/rand_err.c',
+        'openssl/crypto/rand/rand_lib.c',
+        'openssl/crypto/rand/rand_nw.c',
+        'openssl/crypto/rand/rand_os2.c',
+        'openssl/crypto/rand/rand_unix.c',
+        'openssl/crypto/rand/rand_win.c',
+        'openssl/crypto/rand/randfile.c',
+        'openssl/crypto/rc2/rc2_cbc.c',
+        'openssl/crypto/rc2/rc2_ecb.c',
+        'openssl/crypto/rc2/rc2_skey.c',
+        'openssl/crypto/rc2/rc2cfb64.c',
+        'openssl/crypto/rc2/rc2ofb64.c',
+        'openssl/crypto/rc4/rc4_enc.c',
+        'openssl/crypto/rc4/rc4_skey.c',
+        'openssl/crypto/ripemd/rmd_dgst.c',
+        'openssl/crypto/ripemd/rmd_one.c',
+        'openssl/crypto/rsa/rsa_ameth.c',
+        'openssl/crypto/rsa/rsa_asn1.c',
+        'openssl/crypto/rsa/rsa_chk.c',
+        'openssl/crypto/rsa/rsa_depr.c',
+        'openssl/crypto/rsa/rsa_eay.c',
+        'openssl/crypto/rsa/rsa_err.c',
+        'openssl/crypto/rsa/rsa_gen.c',
+        'openssl/crypto/rsa/rsa_lib.c',
+        'openssl/crypto/rsa/rsa_none.c',
+        'openssl/crypto/rsa/rsa_null.c',
+        'openssl/crypto/rsa/rsa_oaep.c',
+        'openssl/crypto/rsa/rsa_pk1.c',
+        'openssl/crypto/rsa/rsa_pmeth.c',
+        'openssl/crypto/rsa/rsa_prn.c',
+        'openssl/crypto/rsa/rsa_pss.c',
+        'openssl/crypto/rsa/rsa_saos.c',
+        'openssl/crypto/rsa/rsa_sign.c',
+        'openssl/crypto/rsa/rsa_ssl.c',
+        'openssl/crypto/rsa/rsa_x931.c',
+        'openssl/crypto/sha/sha1_one.c',
+        'openssl/crypto/sha/sha1dgst.c',
+        'openssl/crypto/sha/sha256.c',
+        'openssl/crypto/sha/sha512.c',
+        'openssl/crypto/sha/sha_dgst.c',
+        'openssl/crypto/sha/sha_one.c',
+        'openssl/crypto/stack/stack.c',
+        'openssl/crypto/store/str_err.c',
+        'openssl/crypto/store/str_lib.c',
+        'openssl/crypto/store/str_mem.c',
+        'openssl/crypto/store/str_meth.c',
+        'openssl/crypto/ts/ts_asn1.c',
+        'openssl/crypto/ts/ts_conf.c',
+        'openssl/crypto/ts/ts_err.c',
+        'openssl/crypto/ts/ts_lib.c',
+        'openssl/crypto/ts/ts_req_print.c',
+        'openssl/crypto/ts/ts_req_utils.c',
+        'openssl/crypto/ts/ts_rsp_print.c',
+        'openssl/crypto/ts/ts_rsp_sign.c',
+        'openssl/crypto/ts/ts_rsp_utils.c',
+        'openssl/crypto/ts/ts_rsp_verify.c',
+        'openssl/crypto/ts/ts_verify_ctx.c',
+        'openssl/crypto/txt_db/txt_db.c',
+        'openssl/crypto/ui/ui_compat.c',
+        'openssl/crypto/ui/ui_err.c',
+        'openssl/crypto/ui/ui_lib.c',
+        'openssl/crypto/ui/ui_openssl.c',
+        'openssl/crypto/ui/ui_util.c',
+        'openssl/crypto/uid.c',
+        'openssl/crypto/whrlpool/wp_block.c',
+        'openssl/crypto/whrlpool/wp_dgst.c',
+        'openssl/crypto/x509/by_dir.c',
+        'openssl/crypto/x509/by_file.c',
+        'openssl/crypto/x509/x509_att.c',
+        'openssl/crypto/x509/x509_cmp.c',
+        'openssl/crypto/x509/x509_d2.c',
+        'openssl/crypto/x509/x509_def.c',
+        'openssl/crypto/x509/x509_err.c',
+        'openssl/crypto/x509/x509_ext.c',
+        'openssl/crypto/x509/x509_lu.c',
+        'openssl/crypto/x509/x509_obj.c',
+        'openssl/crypto/x509/x509_r2x.c',
+        'openssl/crypto/x509/x509_req.c',
+        'openssl/crypto/x509/x509_set.c',
+        'openssl/crypto/x509/x509_trs.c',
+        'openssl/crypto/x509/x509_txt.c',
+        'openssl/crypto/x509/x509_v3.c',
+        'openssl/crypto/x509/x509_vfy.c',
+        'openssl/crypto/x509/x509_vpm.c',
+        'openssl/crypto/x509/x509cset.c',
+        'openssl/crypto/x509/x509name.c',
+        'openssl/crypto/x509/x509rset.c',
+        'openssl/crypto/x509/x509spki.c',
+        'openssl/crypto/x509/x509type.c',
+        'openssl/crypto/x509/x_all.c',
+        'openssl/crypto/x509v3/pcy_cache.c',
+        'openssl/crypto/x509v3/pcy_data.c',
+        'openssl/crypto/x509v3/pcy_lib.c',
+        'openssl/crypto/x509v3/pcy_map.c',
+        'openssl/crypto/x509v3/pcy_node.c',
+        'openssl/crypto/x509v3/pcy_tree.c',
+        'openssl/crypto/x509v3/v3_addr.c',
+        'openssl/crypto/x509v3/v3_akey.c',
+        'openssl/crypto/x509v3/v3_akeya.c',
+        'openssl/crypto/x509v3/v3_alt.c',
+        'openssl/crypto/x509v3/v3_asid.c',
+        'openssl/crypto/x509v3/v3_bcons.c',
+        'openssl/crypto/x509v3/v3_bitst.c',
+        'openssl/crypto/x509v3/v3_conf.c',
+        'openssl/crypto/x509v3/v3_cpols.c',
+        'openssl/crypto/x509v3/v3_crld.c',
+        'openssl/crypto/x509v3/v3_enum.c',
+        'openssl/crypto/x509v3/v3_extku.c',
+        'openssl/crypto/x509v3/v3_genn.c',
+        'openssl/crypto/x509v3/v3_ia5.c',
+        'openssl/crypto/x509v3/v3_info.c',
+        'openssl/crypto/x509v3/v3_int.c',
+        'openssl/crypto/x509v3/v3_lib.c',
+        'openssl/crypto/x509v3/v3_ncons.c',
+        'openssl/crypto/x509v3/v3_ocsp.c',
+        'openssl/crypto/x509v3/v3_pci.c',
+        'openssl/crypto/x509v3/v3_pcia.c',
+        'openssl/crypto/x509v3/v3_pcons.c',
+        'openssl/crypto/x509v3/v3_pku.c',
+        'openssl/crypto/x509v3/v3_pmaps.c',
+        'openssl/crypto/x509v3/v3_prn.c',
+        'openssl/crypto/x509v3/v3_purp.c',
+        'openssl/crypto/x509v3/v3_skey.c',
+        'openssl/crypto/x509v3/v3_sxnet.c',
+        'openssl/crypto/x509v3/v3_utl.c',
+        'openssl/crypto/x509v3/v3err.c',
+        'openssl/engines/e_4758cca.c',
+        'openssl/engines/e_aep.c',
+        'openssl/engines/e_atalla.c',
+        'openssl/engines/e_capi.c',
+        'openssl/engines/e_chil.c',
+        'openssl/engines/e_cswift.c',
+        'openssl/engines/e_gmp.c',
+        'openssl/engines/e_nuron.c',
+        'openssl/engines/e_sureware.c',
+        'openssl/engines/e_ubsec.c',
+      ],
+      'conditions': [
+        ['os_posix==1 and OS!="android"', {
+          'defines': [
+            # ENGINESDIR must be defined if OPENSSLDIR is.
+            'ENGINESDIR="/dev/null"',
+            # Set to ubuntu default path for convenience. If necessary, override
+            # this at runtime with the SSL_CERT_DIR environment variable.
+            'OPENSSLDIR="/etc/ssl"',
+          ],
+          'variables': {
+            'conditions': [
+              ['target_arch=="ia32"', {
+                'openssl_config_path': 'config/piii',
+              }, {
+                'openssl_config_path': 'config/k8',
+              }],
+            ],
+          },
+        }],
+        ['OS=="android"', {
+          'variables': {
+            'openssl_config_path': 'config/android',
+          },
+          'sources/': [
+            ['exclude', 'cast/.*$'],
+            ['exclude', 'crypto/md2/.*$'],
+            ['exclude', 'crypto/store/.*$'],
+            ['exclude', 'crypto/whrlpool/.$'],
+          ],
+        }, {
+          'sources/': [
+            ['exclude', 'camellia/.*$'],
+            ['exclude', 'cms/.*$'],
+            ['exclude', 'mdc2/.*$'],
+          ],
+        }],
+        ['clang==1', {
+          'cflags': [
+            # OpenSSL has a few |if ((foo == NULL))| checks.
+            '-Wno-parentheses-equality',
+            # OpenSSL uses several function-style macros and then ignores the
+            # returned value.
+            '-Wno-unused-value',
+          ],
+        }, { # Not clang. Disable all warnings.
+          'cflags': [
+            '-w',
+          ],
+        }]
+      ],
+      'include_dirs': [
+        '.',
+        'openssl',
+        'openssl/crypto',
+        'openssl/crypto/asn1',
+        'openssl/crypto/evp',
+        'openssl/crypto/store',
+        'openssl/include',
+        '<@(openssl_config_path)',
+      ],
+      'direct_dependent_settings': {
+        'include_dirs': [
+          'openssl/include',
+          '<@(openssl_config_path)',
+        ],
+      },
+    },
+  ],
+}
+
+# Local Variables:
+# tab-width:2
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=2 shiftwidth=2:
diff --git a/openssl/ACKNOWLEDGMENTS b/openssl/ACKNOWLEDGMENTS
new file mode 100644
index 0000000..fb6dd91
--- /dev/null
+++ b/openssl/ACKNOWLEDGMENTS
@@ -0,0 +1,25 @@
+The OpenSSL project depends on volunteer efforts and financial support from
+the end user community. That support comes in the form of donations and paid
+sponsorships, software support contracts, paid consulting services
+and commissioned software development.
+
+Since all these activities support the continued development and improvement
+of OpenSSL we consider all these clients and customers as sponsors of the
+OpenSSL project.
+
+We would like to identify and thank the following such sponsors for their past
+or current significant support of the OpenSSL project:
+
+Very significant support:
+
+	OpenGear: www.opengear.com
+
+Significant support:
+
+	PSW Group: www.psw.net
+
+Please note that we ask permission to identify sponsors and that some sponsors
+we consider eligible for inclusion here have requested to remain anonymous.
+
+Additional sponsorship or financial support is always welcome: for more
+information please contact the OpenSSL Software Foundation.
diff --git a/openssl/CHANGES b/openssl/CHANGES
new file mode 100644
index 0000000..03e744a
--- /dev/null
+++ b/openssl/CHANGES
@@ -0,0 +1,9570 @@
+
+ OpenSSL CHANGES
+ _______________
+
+ Changes between 1.0.0e and 1.0.0f [4 Jan 2012]
+
+  *) Nadhem Alfardan and Kenny Paterson have discovered an extension
+     of the Vaudenay padding oracle attack on CBC mode encryption
+     which enables an efficient plaintext recovery attack against
+     the OpenSSL implementation of DTLS. Their attack exploits timing
+     differences arising during decryption processing. A research
+     paper describing this attack can be found at:
+                  http://www.isg.rhul.ac.uk/~kp/dtls.pdf
+     Thanks go to Nadhem Alfardan and Kenny Paterson of the Information
+     Security Group at Royal Holloway, University of London
+     (www.isg.rhul.ac.uk) for discovering this flaw and to Robin Seggelmann
+     <seggelmann@fh-muenster.de> and Michael Tuexen <tuexen@fh-muenster.de>
+     for preparing the fix. (CVE-2011-4108)
+     [Robin Seggelmann, Michael Tuexen]
+
+  *) Clear bytes used for block padding of SSL 3.0 records.
+     (CVE-2011-4576)
+     [Adam Langley (Google)]
+
+  *) Only allow one SGC handshake restart for SSL/TLS. (CVE-2011-4619)
+     [Adam Langley (Google)]
+
+  *) Check parameters are not NULL in GOST ENGINE. (CVE-2012-0027)
+     [Andrey Kulikov <amdeich@gmail.com>]
+
+  *) Prevent malformed RFC3779 data triggering an assertion failure.
+     Thanks to Andrew Chi, BBN Technologies, for discovering the flaw
+     and Rob Austein <sra@hactrn.net> for fixing it. (CVE-2011-4577)
+     [Rob Austein <sra@hactrn.net>]
+
+  *) Improved PRNG seeding for VOS.
+     [Paul Green <Paul.Green@stratus.com>]
+
+  *) Fix ssl_ciph.c set-up race.
+     [Adam Langley (Google)]
+
+  *) Fix spurious failures in ecdsatest.c.
+     [Emilia Käsper (Google)]
+
+  *) Fix the BIO_f_buffer() implementation (which was mixing different
+     interpretations of the '..._len' fields).
+     [Adam Langley (Google)]
+
+  *) Fix handling of BN_BLINDING: now BN_BLINDING_invert_ex (rather than
+     BN_BLINDING_invert_ex) calls BN_BLINDING_update, ensuring that concurrent
+     threads won't reuse the same blinding coefficients.
+
+     This also avoids the need to obtain the CRYPTO_LOCK_RSA_BLINDING
+     lock to call BN_BLINDING_invert_ex, and avoids one use of
+     BN_BLINDING_update for each BN_BLINDING structure (previously,
+     the last update always remained unused).
+     [Emilia Käsper (Google)]
+
+  *) In ssl3_clear, preserve s3->init_extra along with s3->rbuf.
+     [Bob Buckholz (Google)]
+
+ Changes between 1.0.0d and 1.0.0e [6 Sep 2011]
+
+  *) Fix bug where CRLs with nextUpdate in the past are sometimes accepted
+     by initialising X509_STORE_CTX properly. (CVE-2011-3207)
+     [Kaspar Brand <ossl@velox.ch>]
+
+  *) Fix SSL memory handling for (EC)DH ciphersuites, in particular
+     for multi-threaded use of ECDH. (CVE-2011-3210)
+     [Adam Langley (Google)]
+
+  *) Fix x509_name_ex_d2i memory leak on bad inputs.
+     [Bodo Moeller]
+
+  *) Remove hard coded ecdsaWithSHA1 signature tests in ssl code and check
+     signature public key algorithm by using OID xref utilities instead.
+     Before this you could only use some ECC ciphersuites with SHA1 only.
+     [Steve Henson]
+
+  *) Add protection against ECDSA timing attacks as mentioned in the paper
+     by Billy Bob Brumley and Nicola Tuveri, see:
+
+	http://eprint.iacr.org/2011/232.pdf
+
+     [Billy Bob Brumley and Nicola Tuveri]
+
+ Changes between 1.0.0c and 1.0.0d [8 Feb 2011]
+
+  *) Fix parsing of OCSP stapling ClientHello extension. CVE-2011-0014
+     [Neel Mehta, Adam Langley, Bodo Moeller (Google)]
+
+  *) Fix bug in string printing code: if *any* escaping is enabled we must
+     escape the escape character (backslash) or the resulting string is
+     ambiguous.
+     [Steve Henson]
+
+ Changes between 1.0.0b and 1.0.0c  [2 Dec 2010]
+
+  *) Disable code workaround for ancient and obsolete Netscape browsers
+     and servers: an attacker can use it in a ciphersuite downgrade attack.
+     Thanks to Martin Rex for discovering this bug. CVE-2010-4180
+     [Steve Henson]
+
+  *) Fixed J-PAKE implementation error, originally discovered by
+     Sebastien Martini, further info and confirmation from Stefan
+     Arentz and Feng Hao. Note that this fix is a security fix. CVE-2010-4252
+     [Ben Laurie]
+
+ Changes between 1.0.0a and 1.0.0b  [16 Nov 2010]
+
+  *) Fix extension code to avoid race conditions which can result in a buffer
+     overrun vulnerability: resumed sessions must not be modified as they can
+     be shared by multiple threads. CVE-2010-3864
+     [Steve Henson]
+
+  *) Fix WIN32 build system to correctly link an ENGINE directory into
+     a DLL. 
+     [Steve Henson]
+
+ Changes between 1.0.0 and 1.0.0a  [01 Jun 2010]
+
+  *) Check return value of int_rsa_verify in pkey_rsa_verifyrecover 
+     (CVE-2010-1633)
+     [Steve Henson, Peter-Michael Hager <hager@dortmund.net>]
+
+ Changes between 0.9.8n and 1.0.0  [29 Mar 2010]
+
+  *) Add "missing" function EVP_CIPHER_CTX_copy(). This copies a cipher
+     context. The operation can be customised via the ctrl mechanism in
+     case ENGINEs want to include additional functionality.
+     [Steve Henson]
+
+  *) Tolerate yet another broken PKCS#8 key format: private key value negative.
+     [Steve Henson]
+
+  *) Add new -subject_hash_old and -issuer_hash_old options to x509 utility to
+     output hashes compatible with older versions of OpenSSL.
+     [Willy Weisz <weisz@vcpc.univie.ac.at>]
+
+  *) Fix compression algorithm handling: if resuming a session use the
+     compression algorithm of the resumed session instead of determining
+     it from client hello again. Don't allow server to change algorithm.
+     [Steve Henson]
+
+  *) Add load_crls() function to apps tidying load_certs() too. Add option
+     to verify utility to allow additional CRLs to be included.
+     [Steve Henson]
+
+  *) Update OCSP request code to permit adding custom headers to the request:
+     some responders need this.
+     [Steve Henson]
+
+  *) The function EVP_PKEY_sign() returns <=0 on error: check return code
+     correctly.
+     [Julia Lawall <julia@diku.dk>]
+
+  *) Update verify callback code in apps/s_cb.c and apps/verify.c, it
+     needlessly dereferenced structures, used obsolete functions and
+     didn't handle all updated verify codes correctly.
+     [Steve Henson]
+
+  *) Disable MD2 in the default configuration.
+     [Steve Henson]
+
+  *) In BIO_pop() and BIO_push() use the ctrl argument (which was NULL) to
+     indicate the initial BIO being pushed or popped. This makes it possible
+     to determine whether the BIO is the one explicitly called or as a result
+     of the ctrl being passed down the chain. Fix BIO_pop() and SSL BIOs so
+     it handles reference counts correctly and doesn't zero out the I/O bio
+     when it is not being explicitly popped. WARNING: applications which
+     included workarounds for the old buggy behaviour will need to be modified
+     or they could free up already freed BIOs.
+     [Steve Henson]
+
+  *) Extend the uni2asc/asc2uni => OPENSSL_uni2asc/OPENSSL_asc2uni
+     renaming to all platforms (within the 0.9.8 branch, this was
+     done conditionally on Netware platforms to avoid a name clash).
+     [Guenter <lists@gknw.net>]
+
+  *) Add ECDHE and PSK support to DTLS.
+     [Michael Tuexen <tuexen@fh-muenster.de>]
+
+  *) Add CHECKED_STACK_OF macro to safestack.h, otherwise safestack can't
+     be used on C++.
+     [Steve Henson]
+
+  *) Add "missing" function EVP_MD_flags() (without this the only way to
+     retrieve a digest flags is by accessing the structure directly. Update
+     EVP_MD_do_all*() and EVP_CIPHER_do_all*() to include the name a digest
+     or cipher is registered as in the "from" argument. Print out all
+     registered digests in the dgst usage message instead of manually 
+     attempting to work them out.
+     [Steve Henson]
+
+  *) If no SSLv2 ciphers are used don't use an SSLv2 compatible client hello:
+     this allows the use of compression and extensions. Change default cipher
+     string to remove SSLv2 ciphersuites. This effectively avoids ancient SSLv2
+     by default unless an application cipher string requests it.
+     [Steve Henson]
+
+  *) Alter match criteria in PKCS12_parse(). It used to try to use local
+     key ids to find matching certificates and keys but some PKCS#12 files
+     don't follow the (somewhat unwritten) rules and this strategy fails.
+     Now just gather all certificates together and the first private key
+     then look for the first certificate that matches the key.
+     [Steve Henson]
+
+  *) Support use of registered digest and cipher names for dgst and cipher
+     commands instead of having to add each one as a special case. So now
+     you can do:
+
+        openssl sha256 foo
+
+     as well as:
+
+        openssl dgst -sha256 foo
+
+     and this works for ENGINE based algorithms too.
+
+     [Steve Henson]
+
+  *) Update Gost ENGINE to support parameter files.
+     [Victor B. Wagner <vitus@cryptocom.ru>]
+
+  *) Support GeneralizedTime in ca utility. 
+     [Oliver Martin <oliver@volatilevoid.net>, Steve Henson]
+
+  *) Enhance the hash format used for certificate directory links. The new
+     form uses the canonical encoding (meaning equivalent names will work
+     even if they aren't identical) and uses SHA1 instead of MD5. This form
+     is incompatible with the older format and as a result c_rehash should
+     be used to rebuild symbolic links.
+     [Steve Henson]
+
+  *) Make PKCS#8 the default write format for private keys, replacing the
+     traditional format. This form is standardised, more secure and doesn't
+     include an implicit MD5 dependency.
+     [Steve Henson]
+
+  *) Add a $gcc_devteam_warn option to Configure. The idea is that any code
+     committed to OpenSSL should pass this lot as a minimum.
+     [Steve Henson]
+
+  *) Add session ticket override functionality for use by EAP-FAST.
+     [Jouni Malinen <j@w1.fi>]
+
+  *) Modify HMAC functions to return a value. Since these can be implemented
+     in an ENGINE errors can occur.
+     [Steve Henson]
+
+  *) Type-checked OBJ_bsearch_ex.
+     [Ben Laurie]
+
+  *) Type-checked OBJ_bsearch. Also some constification necessitated
+     by type-checking.  Still to come: TXT_DB, bsearch(?),
+     OBJ_bsearch_ex, qsort, CRYPTO_EX_DATA, ASN1_VALUE, ASN1_STRING,
+     CONF_VALUE.
+     [Ben Laurie]
+
+  *) New function OPENSSL_gmtime_adj() to add a specific number of days and
+     seconds to a tm structure directly, instead of going through OS
+     specific date routines. This avoids any issues with OS routines such
+     as the year 2038 bug. New *_adj() functions for ASN1 time structures
+     and X509_time_adj_ex() to cover the extended range. The existing
+     X509_time_adj() is still usable and will no longer have any date issues.
+     [Steve Henson]
+
+  *) Delta CRL support. New use deltas option which will attempt to locate
+     and search any appropriate delta CRLs available.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Support for CRLs partitioned by reason code. Reorganise CRL processing
+     code and add additional score elements. Validate alternate CRL paths
+     as part of the CRL checking and indicate a new error "CRL path validation
+     error" in this case. Applications wanting additional details can use
+     the verify callback and check the new "parent" field. If this is not
+     NULL CRL path validation is taking place. Existing applications wont
+     see this because it requires extended CRL support which is off by
+     default.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Support for freshest CRL extension.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Initial indirect CRL support. Currently only supported in the CRLs
+     passed directly and not via lookup. Process certificate issuer
+     CRL entry extension and lookup CRL entries by bother issuer name
+     and serial number. Check and process CRL issuer entry in IDP extension.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Add support for distinct certificate and CRL paths. The CRL issuer
+     certificate is validated separately in this case. Only enabled if
+     an extended CRL support flag is set: this flag will enable additional
+     CRL functionality in future.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Add support for policy mappings extension.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Fixes to pathlength constraint, self issued certificate handling,
+     policy processing to align with RFC3280 and PKITS tests.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Support for name constraints certificate extension. DN, email, DNS
+     and URI types are currently supported.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) To cater for systems that provide a pointer-based thread ID rather
+     than numeric, deprecate the current numeric thread ID mechanism and
+     replace it with a structure and associated callback type. This
+     mechanism allows a numeric "hash" to be extracted from a thread ID in
+     either case, and on platforms where pointers are larger than 'long',
+     mixing is done to help ensure the numeric 'hash' is usable even if it
+     can't be guaranteed unique. The default mechanism is to use "&errno"
+     as a pointer-based thread ID to distinguish between threads.
+
+     Applications that want to provide their own thread IDs should now use
+     CRYPTO_THREADID_set_callback() to register a callback that will call
+     either CRYPTO_THREADID_set_numeric() or CRYPTO_THREADID_set_pointer().
+
+     Note that ERR_remove_state() is now deprecated, because it is tied
+     to the assumption that thread IDs are numeric.  ERR_remove_state(0)
+     to free the current thread's error state should be replaced by
+     ERR_remove_thread_state(NULL).
+
+     (This new approach replaces the functions CRYPTO_set_idptr_callback(),
+     CRYPTO_get_idptr_callback(), and CRYPTO_thread_idptr() that existed in
+     OpenSSL 0.9.9-dev between June 2006 and August 2008. Also, if an
+     application was previously providing a numeric thread callback that
+     was inappropriate for distinguishing threads, then uniqueness might
+     have been obtained with &errno that happened immediately in the
+     intermediate development versions of OpenSSL; this is no longer the
+     case, the numeric thread callback will now override the automatic use
+     of &errno.)
+     [Geoff Thorpe, with help from Bodo Moeller]
+
+  *) Initial support for different CRL issuing certificates. This covers a
+     simple case where the self issued certificates in the chain exist and
+     the real CRL issuer is higher in the existing chain.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Removed effectively defunct crypto/store from the build.
+     [Ben Laurie]
+
+  *) Revamp of STACK to provide stronger type-checking. Still to come:
+     TXT_DB, bsearch(?), OBJ_bsearch, qsort, CRYPTO_EX_DATA, ASN1_VALUE,
+     ASN1_STRING, CONF_VALUE.
+     [Ben Laurie]
+
+  *) Add a new SSL_MODE_RELEASE_BUFFERS mode flag to release unused buffer
+     RAM on SSL connections.  This option can save about 34k per idle SSL.
+     [Nick Mathewson]
+
+  *) Revamp of LHASH to provide stronger type-checking. Still to come:
+     STACK, TXT_DB, bsearch, qsort.
+     [Ben Laurie]
+
+  *) Initial support for Cryptographic Message Syntax (aka CMS) based
+     on RFC3850, RFC3851 and RFC3852. New cms directory and cms utility,
+     support for data, signedData, compressedData, digestedData and
+     encryptedData, envelopedData types included. Scripts to check against
+     RFC4134 examples draft and interop and consistency checks of many
+     content types and variants.
+     [Steve Henson]
+
+  *) Add options to enc utility to support use of zlib compression BIO.
+     [Steve Henson]
+
+  *) Extend mk1mf to support importing of options and assembly language
+     files from Configure script, currently only included in VC-WIN32.
+     The assembly language rules can now optionally generate the source
+     files from the associated perl scripts.
+     [Steve Henson]
+
+  *) Implement remaining functionality needed to support GOST ciphersuites.
+     Interop testing has been performed using CryptoPro implementations.
+     [Victor B. Wagner <vitus@cryptocom.ru>]
+
+  *) s390x assembler pack.
+     [Andy Polyakov]
+
+  *) ARMv4 assembler pack. ARMv4 refers to v4 and later ISA, not CPU
+     "family."
+     [Andy Polyakov]
+
+  *) Implement Opaque PRF Input TLS extension as specified in
+     draft-rescorla-tls-opaque-prf-input-00.txt.  Since this is not an
+     official specification yet and no extension type assignment by
+     IANA exists, this extension (for now) will have to be explicitly
+     enabled when building OpenSSL by providing the extension number
+     to use.  For example, specify an option
+
+         -DTLSEXT_TYPE_opaque_prf_input=0x9527
+
+     to the "config" or "Configure" script to enable the extension,
+     assuming extension number 0x9527 (which is a completely arbitrary
+     and unofficial assignment based on the MD5 hash of the Internet
+     Draft).  Note that by doing so, you potentially lose
+     interoperability with other TLS implementations since these might
+     be using the same extension number for other purposes.
+
+     SSL_set_tlsext_opaque_prf_input(ssl, src, len) is used to set the
+     opaque PRF input value to use in the handshake.  This will create
+     an interal copy of the length-'len' string at 'src', and will
+     return non-zero for success.
+
+     To get more control and flexibility, provide a callback function
+     by using
+
+          SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb)
+          SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg)
+
+     where
+
+          int (*cb)(SSL *, void *peerinput, size_t len, void *arg);
+          void *arg;
+
+     Callback function 'cb' will be called in handshakes, and is
+     expected to use SSL_set_tlsext_opaque_prf_input() as appropriate.
+     Argument 'arg' is for application purposes (the value as given to
+     SSL_CTX_set_tlsext_opaque_prf_input_callback_arg() will directly
+     be provided to the callback function).  The callback function
+     has to return non-zero to report success: usually 1 to use opaque
+     PRF input just if possible, or 2 to enforce use of the opaque PRF
+     input.  In the latter case, the library will abort the handshake
+     if opaque PRF input is not successfully negotiated.
+
+     Arguments 'peerinput' and 'len' given to the callback function
+     will always be NULL and 0 in the case of a client.  A server will
+     see the client's opaque PRF input through these variables if
+     available (NULL and 0 otherwise).  Note that if the server
+     provides an opaque PRF input, the length must be the same as the
+     length of the client's opaque PRF input.
+
+     Note that the callback function will only be called when creating
+     a new session (session resumption can resume whatever was
+     previously negotiated), and will not be called in SSL 2.0
+     handshakes; thus, SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) or
+     SSL_set_options(ssl, SSL_OP_NO_SSLv2) is especially recommended
+     for applications that need to enforce opaque PRF input.
+
+     [Bodo Moeller]
+
+  *) Update ssl code to support digests other than SHA1+MD5 for handshake
+     MAC. 
+
+     [Victor B. Wagner <vitus@cryptocom.ru>]
+
+  *) Add RFC4507 support to OpenSSL. This includes the corrections in
+     RFC4507bis. The encrypted ticket format is an encrypted encoded
+     SSL_SESSION structure, that way new session features are automatically
+     supported.
+
+     If a client application caches session in an SSL_SESSION structure
+     support is transparent because tickets are now stored in the encoded
+     SSL_SESSION.
+     
+     The SSL_CTX structure automatically generates keys for ticket
+     protection in servers so again support should be possible
+     with no application modification.
+
+     If a client or server wishes to disable RFC4507 support then the option
+     SSL_OP_NO_TICKET can be set.
+
+     Add a TLS extension debugging callback to allow the contents of any client
+     or server extensions to be examined.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Final changes to avoid use of pointer pointer casts in OpenSSL.
+     OpenSSL should now compile cleanly on gcc 4.2
+     [Peter Hartley <pdh@utter.chaos.org.uk>, Steve Henson]
+
+  *) Update SSL library to use new EVP_PKEY MAC API. Include generic MAC
+     support including streaming MAC support: this is required for GOST
+     ciphersuite support.
+     [Victor B. Wagner <vitus@cryptocom.ru>, Steve Henson]
+
+  *) Add option -stream to use PKCS#7 streaming in smime utility. New
+     function i2d_PKCS7_bio_stream() and PEM_write_PKCS7_bio_stream()
+     to output in BER and PEM format.
+     [Steve Henson]
+
+  *) Experimental support for use of HMAC via EVP_PKEY interface. This
+     allows HMAC to be handled via the EVP_DigestSign*() interface. The
+     EVP_PKEY "key" in this case is the HMAC key, potentially allowing
+     ENGINE support for HMAC keys which are unextractable. New -mac and
+     -macopt options to dgst utility.
+     [Steve Henson]
+
+  *) New option -sigopt to dgst utility. Update dgst to use
+     EVP_Digest{Sign,Verify}*. These two changes make it possible to use
+     alternative signing paramaters such as X9.31 or PSS in the dgst 
+     utility.
+     [Steve Henson]
+
+  *) Change ssl_cipher_apply_rule(), the internal function that does
+     the work each time a ciphersuite string requests enabling
+     ("foo+bar"), moving ("+foo+bar"), disabling ("-foo+bar", or
+     removing ("!foo+bar") a class of ciphersuites: Now it maintains
+     the order of disabled ciphersuites such that those ciphersuites
+     that most recently went from enabled to disabled not only stay
+     in order with respect to each other, but also have higher priority
+     than other disabled ciphersuites the next time ciphersuites are
+     enabled again.
+
+     This means that you can now say, e.g., "PSK:-PSK:HIGH" to enable
+     the same ciphersuites as with "HIGH" alone, but in a specific
+     order where the PSK ciphersuites come first (since they are the
+     most recently disabled ciphersuites when "HIGH" is parsed).
+
+     Also, change ssl_create_cipher_list() (using this new
+     funcionality) such that between otherwise identical
+     cihpersuites, ephemeral ECDH is preferred over ephemeral DH in
+     the default order.
+     [Bodo Moeller]
+
+  *) Change ssl_create_cipher_list() so that it automatically
+     arranges the ciphersuites in reasonable order before starting
+     to process the rule string.  Thus, the definition for "DEFAULT"
+     (SSL_DEFAULT_CIPHER_LIST) now is just "ALL:!aNULL:!eNULL", but
+     remains equivalent to "AES:ALL:!aNULL:!eNULL:+aECDH:+kRSA:+RC4:@STRENGTH".
+     This makes it much easier to arrive at a reasonable default order
+     in applications for which anonymous ciphers are OK (meaning
+     that you can't actually use DEFAULT).
+     [Bodo Moeller; suggested by Victor Duchovni]
+
+  *) Split the SSL/TLS algorithm mask (as used for ciphersuite string
+     processing) into multiple integers instead of setting
+     "SSL_MKEY_MASK" bits, "SSL_AUTH_MASK" bits, "SSL_ENC_MASK",
+     "SSL_MAC_MASK", and "SSL_SSL_MASK" bits all in a single integer.
+     (These masks as well as the individual bit definitions are hidden
+     away into the non-exported interface ssl/ssl_locl.h, so this
+     change to the definition of the SSL_CIPHER structure shouldn't
+     affect applications.)  This give us more bits for each of these
+     categories, so there is no longer a need to coagulate AES128 and
+     AES256 into a single algorithm bit, and to coagulate Camellia128
+     and Camellia256 into a single algorithm bit, which has led to all
+     kinds of kludges.
+
+     Thus, among other things, the kludge introduced in 0.9.7m and
+     0.9.8e for masking out AES256 independently of AES128 or masking
+     out Camellia256 independently of AES256 is not needed here in 0.9.9.
+
+     With the change, we also introduce new ciphersuite aliases that
+     so far were missing: "AES128", "AES256", "CAMELLIA128", and
+     "CAMELLIA256".
+     [Bodo Moeller]
+
+  *) Add support for dsa-with-SHA224 and dsa-with-SHA256.
+     Use the leftmost N bytes of the signature input if the input is
+     larger than the prime q (with N being the size in bytes of q).
+     [Nils Larsch]
+
+  *) Very *very* experimental PKCS#7 streaming encoder support. Nothing uses
+     it yet and it is largely untested.
+     [Steve Henson]
+
+  *) Add support for the ecdsa-with-SHA224/256/384/512 signature types.
+     [Nils Larsch]
+
+  *) Initial incomplete changes to avoid need for function casts in OpenSSL
+     some compilers (gcc 4.2 and later) reject their use. Safestack is
+     reimplemented.  Update ASN1 to avoid use of legacy functions. 
+     [Steve Henson]
+
+  *) Win32/64 targets are linked with Winsock2.
+     [Andy Polyakov]
+
+  *) Add an X509_CRL_METHOD structure to allow CRL processing to be redirected
+     to external functions. This can be used to increase CRL handling 
+     efficiency especially when CRLs are very large by (for example) storing
+     the CRL revoked certificates in a database.
+     [Steve Henson]
+
+  *) Overhaul of by_dir code. Add support for dynamic loading of CRLs so
+     new CRLs added to a directory can be used. New command line option
+     -verify_return_error to s_client and s_server. This causes real errors
+     to be returned by the verify callback instead of carrying on no matter
+     what. This reflects the way a "real world" verify callback would behave.
+     [Steve Henson]
+
+  *) GOST engine, supporting several GOST algorithms and public key formats.
+     Kindly donated by Cryptocom.
+     [Cryptocom]
+
+  *) Partial support for Issuing Distribution Point CRL extension. CRLs
+     partitioned by DP are handled but no indirect CRL or reason partitioning
+     (yet). Complete overhaul of CRL handling: now the most suitable CRL is
+     selected via a scoring technique which handles IDP and AKID in CRLs.
+     [Steve Henson]
+
+  *) New X509_STORE_CTX callbacks lookup_crls() and lookup_certs() which
+     will ultimately be used for all verify operations: this will remove the
+     X509_STORE dependency on certificate verification and allow alternative
+     lookup methods.  X509_STORE based implementations of these two callbacks.
+     [Steve Henson]
+
+  *) Allow multiple CRLs to exist in an X509_STORE with matching issuer names.
+     Modify get_crl() to find a valid (unexpired) CRL if possible.
+     [Steve Henson]
+
+  *) New function X509_CRL_match() to check if two CRLs are identical. Normally
+     this would be called X509_CRL_cmp() but that name is already used by
+     a function that just compares CRL issuer names. Cache several CRL 
+     extensions in X509_CRL structure and cache CRLDP in X509.
+     [Steve Henson]
+
+  *) Store a "canonical" representation of X509_NAME structure (ASN1 Name)
+     this maps equivalent X509_NAME structures into a consistent structure.
+     Name comparison can then be performed rapidly using memcmp().
+     [Steve Henson]
+
+  *) Non-blocking OCSP request processing. Add -timeout option to ocsp 
+     utility.
+     [Steve Henson]
+
+  *) Allow digests to supply their own micalg string for S/MIME type using
+     the ctrl EVP_MD_CTRL_MICALG.
+     [Steve Henson]
+
+  *) During PKCS7 signing pass the PKCS7 SignerInfo structure to the
+     EVP_PKEY_METHOD before and after signing via the EVP_PKEY_CTRL_PKCS7_SIGN
+     ctrl. It can then customise the structure before and/or after signing
+     if necessary.
+     [Steve Henson]
+
+  *) New function OBJ_add_sigid() to allow application defined signature OIDs
+     to be added to OpenSSLs internal tables. New function OBJ_sigid_free()
+     to free up any added signature OIDs.
+     [Steve Henson]
+
+  *) New functions EVP_CIPHER_do_all(), EVP_CIPHER_do_all_sorted(),
+     EVP_MD_do_all() and EVP_MD_do_all_sorted() to enumerate internal
+     digest and cipher tables. New options added to openssl utility:
+     list-message-digest-algorithms and list-cipher-algorithms.
+     [Steve Henson]
+
+  *) Change the array representation of binary polynomials: the list
+     of degrees of non-zero coefficients is now terminated with -1.
+     Previously it was terminated with 0, which was also part of the
+     value; thus, the array representation was not applicable to
+     polynomials where t^0 has coefficient zero.  This change makes
+     the array representation useful in a more general context.
+     [Douglas Stebila]
+
+  *) Various modifications and fixes to SSL/TLS cipher string
+     handling.  For ECC, the code now distinguishes between fixed ECDH
+     with RSA certificates on the one hand and with ECDSA certificates
+     on the other hand, since these are separate ciphersuites.  The
+     unused code for Fortezza ciphersuites has been removed.
+
+     For consistency with EDH, ephemeral ECDH is now called "EECDH"
+     (not "ECDHE").  For consistency with the code for DH
+     certificates, use of ECDH certificates is now considered ECDH
+     authentication, not RSA or ECDSA authentication (the latter is
+     merely the CA's signing algorithm and not actively used in the
+     protocol).
+
+     The temporary ciphersuite alias "ECCdraft" is no longer
+     available, and ECC ciphersuites are no longer excluded from "ALL"
+     and "DEFAULT".  The following aliases now exist for RFC 4492
+     ciphersuites, most of these by analogy with the DH case:
+
+         kECDHr   - ECDH cert, signed with RSA
+         kECDHe   - ECDH cert, signed with ECDSA
+         kECDH    - ECDH cert (signed with either RSA or ECDSA)
+         kEECDH   - ephemeral ECDH
+         ECDH     - ECDH cert or ephemeral ECDH
+
+         aECDH    - ECDH cert
+         aECDSA   - ECDSA cert
+         ECDSA    - ECDSA cert
+
+         AECDH    - anonymous ECDH
+         EECDH    - non-anonymous ephemeral ECDH (equivalent to "kEECDH:-AECDH")
+
+     [Bodo Moeller]
+
+  *) Add additional S/MIME capabilities for AES and GOST ciphers if supported.
+     Use correct micalg parameters depending on digest(s) in signed message.
+     [Steve Henson]
+
+  *) Add engine support for EVP_PKEY_ASN1_METHOD. Add functions to process
+     an ENGINE asn1 method. Support ENGINE lookups in the ASN1 code.
+     [Steve Henson]
+
+  *) Initial engine support for EVP_PKEY_METHOD. New functions to permit
+     an engine to register a method. Add ENGINE lookups for methods and
+     functional reference processing.
+     [Steve Henson]
+
+  *) New functions EVP_Digest{Sign,Verify)*. These are enchance versions of
+     EVP_{Sign,Verify}* which allow an application to customise the signature
+     process.
+     [Steve Henson]
+
+  *) New -resign option to smime utility. This adds one or more signers
+     to an existing PKCS#7 signedData structure. Also -md option to use an
+     alternative message digest algorithm for signing.
+     [Steve Henson]
+
+  *) Tidy up PKCS#7 routines and add new functions to make it easier to
+     create PKCS7 structures containing multiple signers. Update smime
+     application to support multiple signers.
+     [Steve Henson]
+
+  *) New -macalg option to pkcs12 utility to allow setting of an alternative
+     digest MAC.
+     [Steve Henson]
+
+  *) Initial support for PKCS#5 v2.0 PRFs other than default SHA1 HMAC.
+     Reorganize PBE internals to lookup from a static table using NIDs,
+     add support for HMAC PBE OID translation. Add a EVP_CIPHER ctrl:
+     EVP_CTRL_PBE_PRF_NID this allows a cipher to specify an alternative
+     PRF which will be automatically used with PBES2.
+     [Steve Henson]
+
+  *) Replace the algorithm specific calls to generate keys in "req" with the
+     new API.
+     [Steve Henson]
+
+  *) Update PKCS#7 enveloped data routines to use new API. This is now
+     supported by any public key method supporting the encrypt operation. A
+     ctrl is added to allow the public key algorithm to examine or modify
+     the PKCS#7 RecipientInfo structure if it needs to: for RSA this is
+     a no op.
+     [Steve Henson]
+
+  *) Add a ctrl to asn1 method to allow a public key algorithm to express
+     a default digest type to use. In most cases this will be SHA1 but some
+     algorithms (such as GOST) need to specify an alternative digest. The
+     return value indicates how strong the prefernce is 1 means optional and
+     2 is mandatory (that is it is the only supported type). Modify
+     ASN1_item_sign() to accept a NULL digest argument to indicate it should
+     use the default md. Update openssl utilities to use the default digest
+     type for signing if it is not explicitly indicated.
+     [Steve Henson]
+
+  *) Use OID cross reference table in ASN1_sign() and ASN1_verify(). New 
+     EVP_MD flag EVP_MD_FLAG_PKEY_METHOD_SIGNATURE. This uses the relevant
+     signing method from the key type. This effectively removes the link
+     between digests and public key types.
+     [Steve Henson]
+
+  *) Add an OID cross reference table and utility functions. Its purpose is to
+     translate between signature OIDs such as SHA1WithrsaEncryption and SHA1,
+     rsaEncryption. This will allow some of the algorithm specific hackery
+     needed to use the correct OID to be removed. 
+     [Steve Henson]
+
+  *) Remove algorithm specific dependencies when setting PKCS7_SIGNER_INFO
+     structures for PKCS7_sign(). They are now set up by the relevant public
+     key ASN1 method.
+     [Steve Henson]
+
+  *) Add provisional EC pkey method with support for ECDSA and ECDH.
+     [Steve Henson]
+
+  *) Add support for key derivation (agreement) in the API, DH method and
+     pkeyutl.
+     [Steve Henson]
+
+  *) Add DSA pkey method and DH pkey methods, extend DH ASN1 method to support
+     public and private key formats. As a side effect these add additional 
+     command line functionality not previously available: DSA signatures can be
+     generated and verified using pkeyutl and DH key support and generation in
+     pkey, genpkey.
+     [Steve Henson]
+
+  *) BeOS support.
+     [Oliver Tappe <zooey@hirschkaefer.de>]
+
+  *) New make target "install_html_docs" installs HTML renditions of the
+     manual pages.
+     [Oliver Tappe <zooey@hirschkaefer.de>]
+
+  *) New utility "genpkey" this is analagous to "genrsa" etc except it can
+     generate keys for any algorithm. Extend and update EVP_PKEY_METHOD to
+     support key and parameter generation and add initial key generation
+     functionality for RSA.
+     [Steve Henson]
+
+  *) Add functions for main EVP_PKEY_method operations. The undocumented
+     functions EVP_PKEY_{encrypt,decrypt} have been renamed to
+     EVP_PKEY_{encrypt,decrypt}_old. 
+     [Steve Henson]
+
+  *) Initial definitions for EVP_PKEY_METHOD. This will be a high level public
+     key API, doesn't do much yet.
+     [Steve Henson]
+
+  *) New function EVP_PKEY_asn1_get0_info() to retrieve information about
+     public key algorithms. New option to openssl utility:
+     "list-public-key-algorithms" to print out info.
+     [Steve Henson]
+
+  *) Implement the Supported Elliptic Curves Extension for
+     ECC ciphersuites from draft-ietf-tls-ecc-12.txt.
+     [Douglas Stebila]
+
+  *) Don't free up OIDs in OBJ_cleanup() if they are in use by EVP_MD or
+     EVP_CIPHER structures to avoid later problems in EVP_cleanup().
+     [Steve Henson]
+
+  *) New utilities pkey and pkeyparam. These are similar to algorithm specific
+     utilities such as rsa, dsa, dsaparam etc except they process any key
+     type.
+     [Steve Henson]
+
+  *) Transfer public key printing routines to EVP_PKEY_ASN1_METHOD. New 
+     functions EVP_PKEY_print_public(), EVP_PKEY_print_private(),
+     EVP_PKEY_print_param() to print public key data from an EVP_PKEY
+     structure.
+     [Steve Henson]
+
+  *) Initial support for pluggable public key ASN1.
+     De-spaghettify the public key ASN1 handling. Move public and private
+     key ASN1 handling to a new EVP_PKEY_ASN1_METHOD structure. Relocate
+     algorithm specific handling to a single module within the relevant
+     algorithm directory. Add functions to allow (near) opaque processing
+     of public and private key structures.
+     [Steve Henson]
+
+  *) Implement the Supported Point Formats Extension for
+     ECC ciphersuites from draft-ietf-tls-ecc-12.txt.
+     [Douglas Stebila]
+
+  *) Add initial support for RFC 4279 PSK TLS ciphersuites. Add members
+     for the psk identity [hint] and the psk callback functions to the
+     SSL_SESSION, SSL and SSL_CTX structure.
+     
+     New ciphersuites:
+         PSK-RC4-SHA, PSK-3DES-EDE-CBC-SHA, PSK-AES128-CBC-SHA,
+         PSK-AES256-CBC-SHA
+ 
+     New functions:
+         SSL_CTX_use_psk_identity_hint
+         SSL_get_psk_identity_hint
+         SSL_get_psk_identity
+         SSL_use_psk_identity_hint
+
+     [Mika Kousa and Pasi Eronen of Nokia Corporation]
+
+  *) Add RFC 3161 compliant time stamp request creation, response generation
+     and response verification functionality.
+     [Zoltán Glózik <zglozik@opentsa.org>, The OpenTSA Project]
+
+  *) Add initial support for TLS extensions, specifically for the server_name
+     extension so far.  The SSL_SESSION, SSL_CTX, and SSL data structures now
+     have new members for a host name.  The SSL data structure has an
+     additional member SSL_CTX *initial_ctx so that new sessions can be
+     stored in that context to allow for session resumption, even after the
+     SSL has been switched to a new SSL_CTX in reaction to a client's
+     server_name extension.
+
+     New functions (subject to change):
+
+         SSL_get_servername()
+         SSL_get_servername_type()
+         SSL_set_SSL_CTX()
+
+     New CTRL codes and macros (subject to change):
+
+         SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
+                                 - SSL_CTX_set_tlsext_servername_callback()
+         SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG
+                                      - SSL_CTX_set_tlsext_servername_arg()
+         SSL_CTRL_SET_TLSEXT_HOSTNAME           - SSL_set_tlsext_host_name()
+
+     openssl s_client has a new '-servername ...' option.
+
+     openssl s_server has new options '-servername_host ...', '-cert2 ...',
+     '-key2 ...', '-servername_fatal' (subject to change).  This allows
+     testing the HostName extension for a specific single host name ('-cert'
+     and '-key' remain fallbacks for handshakes without HostName
+     negotiation).  If the unrecogninzed_name alert has to be sent, this by
+     default is a warning; it becomes fatal with the '-servername_fatal'
+     option.
+
+     [Peter Sylvester,  Remy Allais, Christophe Renou]
+
+  *) Whirlpool hash implementation is added.
+     [Andy Polyakov]
+
+  *) BIGNUM code on 64-bit SPARCv9 targets is switched from bn(64,64) to
+     bn(64,32). Because of instruction set limitations it doesn't have
+     any negative impact on performance. This was done mostly in order
+     to make it possible to share assembler modules, such as bn_mul_mont
+     implementations, between 32- and 64-bit builds without hassle.
+     [Andy Polyakov]
+
+  *) Move code previously exiled into file crypto/ec/ec2_smpt.c
+     to ec2_smpl.c, and no longer require the OPENSSL_EC_BIN_PT_COMP
+     macro.
+     [Bodo Moeller]
+
+  *) New candidate for BIGNUM assembler implementation, bn_mul_mont,
+     dedicated Montgomery multiplication procedure, is introduced.
+     BN_MONT_CTX is modified to allow bn_mul_mont to reach for higher
+     "64-bit" performance on certain 32-bit targets.
+     [Andy Polyakov]
+
+  *) New option SSL_OP_NO_COMP to disable use of compression selectively
+     in SSL structures. New SSL ctrl to set maximum send fragment size. 
+     Save memory by seeting the I/O buffer sizes dynamically instead of
+     using the maximum available value.
+     [Steve Henson]
+
+  *) New option -V for 'openssl ciphers'. This prints the ciphersuite code
+     in addition to the text details.
+     [Bodo Moeller]
+
+  *) Very, very preliminary EXPERIMENTAL support for printing of general
+     ASN1 structures. This currently produces rather ugly output and doesn't
+     handle several customised structures at all.
+     [Steve Henson]
+
+  *) Integrated support for PVK file format and some related formats such
+     as MS PUBLICKEYBLOB and PRIVATEKEYBLOB. Command line switches to support
+     these in the 'rsa' and 'dsa' utilities.
+     [Steve Henson]
+
+  *) Support for PKCS#1 RSAPublicKey format on rsa utility command line.
+     [Steve Henson]
+
+  *) Remove the ancient ASN1_METHOD code. This was only ever used in one
+     place for the (very old) "NETSCAPE" format certificates which are now
+     handled using new ASN1 code equivalents.
+     [Steve Henson]
+
+  *) Let the TLSv1_method() etc. functions return a 'const' SSL_METHOD
+     pointer and make the SSL_METHOD parameter in SSL_CTX_new,
+     SSL_CTX_set_ssl_version and SSL_set_ssl_method 'const'.
+     [Nils Larsch]
+
+  *) Modify CRL distribution points extension code to print out previously
+     unsupported fields. Enhance extension setting code to allow setting of
+     all fields.
+     [Steve Henson]
+
+  *) Add print and set support for Issuing Distribution Point CRL extension.
+     [Steve Henson]
+
+  *) Change 'Configure' script to enable Camellia by default.
+     [NTT]
+  
+ Changes between 0.9.8r and 0.9.8s [xx XXX xxxx]
+
+  *) Fix ssl_ciph.c set-up race.
+     [Adam Langley (Google)]
+
+  *) Fix spurious failures in ecdsatest.c.
+     [Emilia Käsper (Google)]
+
+  *) Fix the BIO_f_buffer() implementation (which was mixing different
+     interpretations of the '..._len' fields).
+     [Adam Langley (Google)]
+
+  *) Fix handling of BN_BLINDING: now BN_BLINDING_invert_ex (rather than
+     BN_BLINDING_invert_ex) calls BN_BLINDING_update, ensuring that concurrent
+     threads won't reuse the same blinding coefficients.
+
+     This also avoids the need to obtain the CRYPTO_LOCK_RSA_BLINDING
+     lock to call BN_BLINDING_invert_ex, and avoids one use of
+     BN_BLINDING_update for each BN_BLINDING structure (previously,
+     the last update always remained unused).
+     [Emilia Käsper (Google)]
+
+  *) Fix SSL memory handling for (EC)DH ciphersuites, in particular
+     for multi-threaded use of ECDH.
+     [Adam Langley (Google)]
+
+  *) Fix x509_name_ex_d2i memory leak on bad inputs.
+     [Bodo Moeller]
+
+  *) Add protection against ECDSA timing attacks as mentioned in the paper
+     by Billy Bob Brumley and Nicola Tuveri, see:
+
+	http://eprint.iacr.org/2011/232.pdf
+
+     [Billy Bob Brumley and Nicola Tuveri]
+
+ Changes between 0.9.8q and 0.9.8r [8 Feb 2011]
+
+  *) Fix parsing of OCSP stapling ClientHello extension. CVE-2011-0014
+     [Neel Mehta, Adam Langley, Bodo Moeller (Google)]
+
+  *) Fix bug in string printing code: if *any* escaping is enabled we must
+     escape the escape character (backslash) or the resulting string is
+     ambiguous.
+     [Steve Henson]
+
+ Changes between 0.9.8p and 0.9.8q [2 Dec 2010]
+
+  *) Disable code workaround for ancient and obsolete Netscape browsers
+     and servers: an attacker can use it in a ciphersuite downgrade attack.
+     Thanks to Martin Rex for discovering this bug. CVE-2010-4180
+     [Steve Henson]
+
+  *) Fixed J-PAKE implementation error, originally discovered by
+     Sebastien Martini, further info and confirmation from Stefan
+     Arentz and Feng Hao. Note that this fix is a security fix. CVE-2010-4252
+     [Ben Laurie]
+
+ Changes between 0.9.8o and 0.9.8p [16 Nov 2010]
+
+  *) Fix extension code to avoid race conditions which can result in a buffer
+     overrun vulnerability: resumed sessions must not be modified as they can
+     be shared by multiple threads. CVE-2010-3864
+     [Steve Henson]
+
+  *) Fix for double free bug in ssl/s3_clnt.c CVE-2010-2939
+     [Steve Henson]
+
+  *) Don't reencode certificate when calculating signature: cache and use
+     the original encoding instead. This makes signature verification of
+     some broken encodings work correctly.
+     [Steve Henson]
+
+  *) ec2_GF2m_simple_mul bugfix: compute correct result if the output EC_POINT
+     is also one of the inputs.
+     [Emilia Käsper <emilia.kasper@esat.kuleuven.be> (Google)]
+
+  *) Don't repeatedly append PBE algorithms to table if they already exist.
+     Sort table on each new add. This effectively makes the table read only
+     after all algorithms are added and subsequent calls to PKCS12_pbe_add
+     etc are non-op.
+     [Steve Henson]
+
+ Changes between 0.9.8n and 0.9.8o [01 Jun 2010]
+
+  [NB: OpenSSL 0.9.8o and later 0.9.8 patch levels were released after
+  OpenSSL 1.0.0.]
+
+  *) Correct a typo in the CMS ASN1 module which can result in invalid memory
+     access or freeing data twice (CVE-2010-0742)
+     [Steve Henson, Ronald Moesbergen <intercommit@gmail.com>]
+
+  *) Add SHA2 algorithms to SSL_library_init(). SHA2 is becoming far more
+     common in certificates and some applications which only call
+     SSL_library_init and not OpenSSL_add_all_algorithms() will fail.
+     [Steve Henson]
+
+  *) VMS fixes: 
+     Reduce copying into .apps and .test in makevms.com
+     Don't try to use blank CA certificate in CA.com
+     Allow use of C files from original directories in maketests.com
+     [Steven M. Schweda" <sms@antinode.info>]
+
+ Changes between 0.9.8m and 0.9.8n [24 Mar 2010]
+
+  *) When rejecting SSL/TLS records due to an incorrect version number, never
+     update s->server with a new major version number.  As of
+     - OpenSSL 0.9.8m if 'short' is a 16-bit type,
+     - OpenSSL 0.9.8f if 'short' is longer than 16 bits,
+     the previous behavior could result in a read attempt at NULL when
+     receiving specific incorrect SSL/TLS records once record payload
+     protection is active.  (CVE-2010-0740)
+     [Bodo Moeller, Adam Langley <agl@chromium.org>]
+
+  *) Fix for CVE-2010-0433 where some kerberos enabled versions of OpenSSL 
+     could be crashed if the relevant tables were not present (e.g. chrooted).
+     [Tomas Hoger <thoger@redhat.com>]
+
+ Changes between 0.9.8l and 0.9.8m [25 Feb 2010]
+
+  *) Always check bn_wexpend() return values for failure.  (CVE-2009-3245)
+     [Martin Olsson, Neel Mehta]
+
+  *) Fix X509_STORE locking: Every 'objs' access requires a lock (to
+     accommodate for stack sorting, always a write lock!).
+     [Bodo Moeller]
+
+  *) On some versions of WIN32 Heap32Next is very slow. This can cause
+     excessive delays in the RAND_poll(): over a minute. As a workaround
+     include a time check in the inner Heap32Next loop too.
+     [Steve Henson]
+
+  *) The code that handled flushing of data in SSL/TLS originally used the
+     BIO_CTRL_INFO ctrl to see if any data was pending first. This caused
+     the problem outlined in PR#1949. The fix suggested there however can
+     trigger problems with buggy BIO_CTRL_WPENDING (e.g. some versions
+     of Apache). So instead simplify the code to flush unconditionally.
+     This should be fine since flushing with no data to flush is a no op.
+     [Steve Henson]
+
+  *) Handle TLS versions 2.0 and later properly and correctly use the
+     highest version of TLS/SSL supported. Although TLS >= 2.0 is some way
+     off ancient servers have a habit of sticking around for a while...
+     [Steve Henson]
+
+  *) Modify compression code so it frees up structures without using the
+     ex_data callbacks. This works around a problem where some applications
+     call CRYPTO_cleanup_all_ex_data() before application exit (e.g. when
+     restarting) then use compression (e.g. SSL with compression) later.
+     This results in significant per-connection memory leaks and
+     has caused some security issues including CVE-2008-1678 and
+     CVE-2009-4355.
+     [Steve Henson]
+
+  *) Constify crypto/cast (i.e., <openssl/cast.h>): a CAST_KEY doesn't
+     change when encrypting or decrypting.
+     [Bodo Moeller]
+
+  *) Add option SSL_OP_LEGACY_SERVER_CONNECT which will allow clients to
+     connect and renegotiate with servers which do not support RI.
+     Until RI is more widely deployed this option is enabled by default.
+     [Steve Henson]
+
+  *) Add "missing" ssl ctrls to clear options and mode.
+     [Steve Henson]
+
+  *) If client attempts to renegotiate and doesn't support RI respond with
+     a no_renegotiation alert as required by RFC5746.  Some renegotiating
+     TLS clients will continue a connection gracefully when they receive
+     the alert. Unfortunately OpenSSL mishandled this alert and would hang
+     waiting for a server hello which it will never receive. Now we treat a
+     received no_renegotiation alert as a fatal error. This is because
+     applications requesting a renegotiation might well expect it to succeed
+     and would have no code in place to handle the server denying it so the
+     only safe thing to do is to terminate the connection.
+     [Steve Henson]
+
+  *) Add ctrl macro SSL_get_secure_renegotiation_support() which returns 1 if
+     peer supports secure renegotiation and 0 otherwise. Print out peer
+     renegotiation support in s_client/s_server.
+     [Steve Henson]
+
+  *) Replace the highly broken and deprecated SPKAC certification method with
+     the updated NID creation version. This should correctly handle UTF8.
+     [Steve Henson]
+
+  *) Implement RFC5746. Re-enable renegotiation but require the extension
+     as needed. Unfortunately, SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
+     turns out to be a bad idea. It has been replaced by
+     SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION which can be set with
+     SSL_CTX_set_options(). This is really not recommended unless you
+     know what you are doing.
+     [Eric Rescorla <ekr@networkresonance.com>, Ben Laurie, Steve Henson]
+
+  *) Fixes to stateless session resumption handling. Use initial_ctx when
+     issuing and attempting to decrypt tickets in case it has changed during
+     servername handling. Use a non-zero length session ID when attempting
+     stateless session resumption: this makes it possible to determine if
+     a resumption has occurred immediately after receiving server hello
+     (several places in OpenSSL subtly assume this) instead of later in
+     the handshake.
+     [Steve Henson]
+
+  *) The functions ENGINE_ctrl(), OPENSSL_isservice(),
+     CMS_get1_RecipientRequest() and RAND_bytes() can return <=0 on error
+     fixes for a few places where the return code is not checked
+     correctly.
+     [Julia Lawall <julia@diku.dk>]
+
+  *) Add --strict-warnings option to Configure script to include devteam
+     warnings in other configurations.
+     [Steve Henson]
+
+  *) Add support for --libdir option and LIBDIR variable in makefiles. This
+     makes it possible to install openssl libraries in locations which
+     have names other than "lib", for example "/usr/lib64" which some
+     systems need.
+     [Steve Henson, based on patch from Jeremy Utley]
+
+  *) Don't allow the use of leading 0x80 in OIDs. This is a violation of
+     X690 8.9.12 and can produce some misleading textual output of OIDs.
+     [Steve Henson, reported by Dan Kaminsky]
+
+  *) Delete MD2 from algorithm tables. This follows the recommendation in
+     several standards that it is not used in new applications due to
+     several cryptographic weaknesses. For binary compatibility reasons
+     the MD2 API is still compiled in by default.
+     [Steve Henson]
+
+  *) Add compression id to {d2i,i2d}_SSL_SESSION so it is correctly saved
+     and restored.
+     [Steve Henson]
+
+  *) Rename uni2asc and asc2uni functions to OPENSSL_uni2asc and
+     OPENSSL_asc2uni conditionally on Netware platforms to avoid a name
+     clash.
+     [Guenter <lists@gknw.net>]
+
+  *) Fix the server certificate chain building code to use X509_verify_cert(),
+     it used to have an ad-hoc builder which was unable to cope with anything
+     other than a simple chain.
+     [David Woodhouse <dwmw2@infradead.org>, Steve Henson]
+
+  *) Don't check self signed certificate signatures in X509_verify_cert()
+     by default (a flag can override this): it just wastes time without
+     adding any security. As a useful side effect self signed root CAs
+     with non-FIPS digests are now usable in FIPS mode.
+     [Steve Henson]
+
+  *) In dtls1_process_out_of_seq_message() the check if the current message
+     is already buffered was missing. For every new message was memory
+     allocated, allowing an attacker to perform an denial of service attack
+     with sending out of seq handshake messages until there is no memory
+     left. Additionally every future messege was buffered, even if the
+     sequence number made no sense and would be part of another handshake.
+     So only messages with sequence numbers less than 10 in advance will be
+     buffered.  (CVE-2009-1378)
+     [Robin Seggelmann, discovered by Daniel Mentz] 	
+
+  *) Records are buffered if they arrive with a future epoch to be
+     processed after finishing the corresponding handshake. There is
+     currently no limitation to this buffer allowing an attacker to perform
+     a DOS attack with sending records with future epochs until there is no
+     memory left. This patch adds the pqueue_size() function to detemine
+     the size of a buffer and limits the record buffer to 100 entries.
+     (CVE-2009-1377)
+     [Robin Seggelmann, discovered by Daniel Mentz] 	
+
+  *) Keep a copy of frag->msg_header.frag_len so it can be used after the
+     parent structure is freed.  (CVE-2009-1379)
+     [Daniel Mentz] 	
+
+  *) Handle non-blocking I/O properly in SSL_shutdown() call.
+     [Darryl Miles <darryl-mailinglists@netbauds.net>]
+
+  *) Add 2.5.4.* OIDs
+     [Ilya O. <vrghost@gmail.com>]
+
+ Changes between 0.9.8k and 0.9.8l  [5 Nov 2009]
+
+  *) Disable renegotiation completely - this fixes a severe security
+     problem (CVE-2009-3555) at the cost of breaking all
+     renegotiation. Renegotiation can be re-enabled by setting
+     SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION in s3->flags at
+     run-time. This is really not recommended unless you know what
+     you're doing.
+     [Ben Laurie]
+
+ Changes between 0.9.8j and 0.9.8k  [25 Mar 2009]
+
+  *) Don't set val to NULL when freeing up structures, it is freed up by
+     underlying code. If sizeof(void *) > sizeof(long) this can result in
+     zeroing past the valid field. (CVE-2009-0789)
+     [Paolo Ganci <Paolo.Ganci@AdNovum.CH>]
+
+  *) Fix bug where return value of CMS_SignerInfo_verify_content() was not
+     checked correctly. This would allow some invalid signed attributes to
+     appear to verify correctly. (CVE-2009-0591)
+     [Ivan Nestlerode <inestlerode@us.ibm.com>]
+
+  *) Reject UniversalString and BMPString types with invalid lengths. This
+     prevents a crash in ASN1_STRING_print_ex() which assumes the strings have
+     a legal length. (CVE-2009-0590)
+     [Steve Henson]
+
+  *) Set S/MIME signing as the default purpose rather than setting it 
+     unconditionally. This allows applications to override it at the store
+     level.
+     [Steve Henson]
+
+  *) Permit restricted recursion of ASN1 strings. This is needed in practice
+     to handle some structures.
+     [Steve Henson]
+
+  *) Improve efficiency of mem_gets: don't search whole buffer each time
+     for a '\n'
+     [Jeremy Shapiro <jnshapir@us.ibm.com>]
+
+  *) New -hex option for openssl rand.
+     [Matthieu Herrb]
+
+  *) Print out UTF8String and NumericString when parsing ASN1.
+     [Steve Henson]
+
+  *) Support NumericString type for name components.
+     [Steve Henson]
+
+  *) Allow CC in the environment to override the automatically chosen
+     compiler. Note that nothing is done to ensure flags work with the
+     chosen compiler.
+     [Ben Laurie]
+
+ Changes between 0.9.8i and 0.9.8j  [07 Jan 2009]
+
+  *) Properly check EVP_VerifyFinal() and similar return values
+     (CVE-2008-5077).
+     [Ben Laurie, Bodo Moeller, Google Security Team]
+
+  *) Enable TLS extensions by default.
+     [Ben Laurie]
+
+  *) Allow the CHIL engine to be loaded, whether the application is
+     multithreaded or not. (This does not release the developer from the
+     obligation to set up the dynamic locking callbacks.)
+     [Sander Temme <sander@temme.net>]
+
+  *) Use correct exit code if there is an error in dgst command.
+     [Steve Henson; problem pointed out by Roland Dirlewanger]
+
+  *) Tweak Configure so that you need to say "experimental-jpake" to enable
+     JPAKE, and need to use -DOPENSSL_EXPERIMENTAL_JPAKE in applications.
+     [Bodo Moeller]
+
+  *) Add experimental JPAKE support, including demo authentication in
+     s_client and s_server.
+     [Ben Laurie]
+
+  *) Set the comparison function in v3_addr_canonize().
+     [Rob Austein <sra@hactrn.net>]
+
+  *) Add support for XMPP STARTTLS in s_client.
+     [Philip Paeps <philip@freebsd.org>]
+
+  *) Change the server-side SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG behavior
+     to ensure that even with this option, only ciphersuites in the
+     server's preference list will be accepted.  (Note that the option
+     applies only when resuming a session, so the earlier behavior was
+     just about the algorithm choice for symmetric cryptography.)
+     [Bodo Moeller]
+
+ Changes between 0.9.8h and 0.9.8i  [15 Sep 2008]
+
+  *) Fix NULL pointer dereference if a DTLS server received
+     ChangeCipherSpec as first record (CVE-2009-1386).
+     [PR #1679]
+
+  *) Fix a state transitition in s3_srvr.c and d1_srvr.c
+     (was using SSL3_ST_CW_CLNT_HELLO_B, should be ..._ST_SW_SRVR_...).
+     [Nagendra Modadugu]
+
+  *) The fix in 0.9.8c that supposedly got rid of unsafe
+     double-checked locking was incomplete for RSA blinding,
+     addressing just one layer of what turns out to have been
+     doubly unsafe triple-checked locking.
+
+     So now fix this for real by retiring the MONT_HELPER macro
+     in crypto/rsa/rsa_eay.c.
+
+     [Bodo Moeller; problem pointed out by Marius Schilder]
+
+  *) Various precautionary measures:
+
+     - Avoid size_t integer overflow in HASH_UPDATE (md32_common.h).
+
+     - Avoid a buffer overflow in d2i_SSL_SESSION() (ssl_asn1.c).
+       (NB: This would require knowledge of the secret session ticket key
+       to exploit, in which case you'd be SOL either way.)
+
+     - Change bn_nist.c so that it will properly handle input BIGNUMs
+       outside the expected range.
+
+     - Enforce the 'num' check in BN_div() (bn_div.c) for non-BN_DEBUG
+       builds.
+
+     [Neel Mehta, Bodo Moeller]
+
+  *) Allow engines to be "soft loaded" - i.e. optionally don't die if
+     the load fails. Useful for distros.
+     [Ben Laurie and the FreeBSD team]
+
+  *) Add support for Local Machine Keyset attribute in PKCS#12 files.
+     [Steve Henson]
+
+  *) Fix BN_GF2m_mod_arr() top-bit cleanup code.
+     [Huang Ying]
+
+  *) Expand ENGINE to support engine supplied SSL client certificate functions.
+
+     This work was sponsored by Logica.
+     [Steve Henson]
+
+  *) Add CryptoAPI ENGINE to support use of RSA and DSA keys held in Windows
+     keystores. Support for SSL/TLS client authentication too.
+     Not compiled unless enable-capieng specified to Configure.
+
+     This work was sponsored by Logica.
+     [Steve Henson]
+
+  *) Fix bug in X509_ATTRIBUTE creation: dont set attribute using
+     ASN1_TYPE_set1 if MBSTRING flag set. This bug would crash certain
+     attribute creation routines such as certifcate requests and PKCS#12
+     files.
+     [Steve Henson]
+
+ Changes between 0.9.8g and 0.9.8h  [28 May 2008]
+
+  *) Fix flaw if 'Server Key exchange message' is omitted from a TLS
+     handshake which could lead to a cilent crash as found using the
+     Codenomicon TLS test suite (CVE-2008-1672) 
+     [Steve Henson, Mark Cox]
+
+  *) Fix double free in TLS server name extensions which could lead to
+     a remote crash found by Codenomicon TLS test suite (CVE-2008-0891) 
+     [Joe Orton]
+
+  *) Clear error queue in SSL_CTX_use_certificate_chain_file()
+
+     Clear the error queue to ensure that error entries left from
+     older function calls do not interfere with the correct operation.
+     [Lutz Jaenicke, Erik de Castro Lopo]
+
+  *) Remove root CA certificates of commercial CAs:
+
+     The OpenSSL project does not recommend any specific CA and does not
+     have any policy with respect to including or excluding any CA.
+     Therefore it does not make any sense to ship an arbitrary selection
+     of root CA certificates with the OpenSSL software.
+     [Lutz Jaenicke]
+
+  *) RSA OAEP patches to fix two separate invalid memory reads.
+     The first one involves inputs when 'lzero' is greater than
+     'SHA_DIGEST_LENGTH' (it would read about SHA_DIGEST_LENGTH bytes
+     before the beginning of from). The second one involves inputs where
+     the 'db' section contains nothing but zeroes (there is a one-byte
+     invalid read after the end of 'db').
+     [Ivan Nestlerode <inestlerode@us.ibm.com>]
+
+  *) Partial backport from 0.9.9-dev:
+
+     Introduce bn_mul_mont (dedicated Montgomery multiplication
+     procedure) as a candidate for BIGNUM assembler implementation.
+     While 0.9.9-dev uses assembler for various architectures, only
+     x86_64 is available by default here in the 0.9.8 branch, and
+     32-bit x86 is available through a compile-time setting.
+
+     To try the 32-bit x86 assembler implementation, use Configure
+     option "enable-montasm" (which exists only for this backport).
+
+     As "enable-montasm" for 32-bit x86 disclaims code stability
+     anyway, in this constellation we activate additional code
+     backported from 0.9.9-dev for further performance improvements,
+     namely BN_from_montgomery_word.  (To enable this otherwise,
+     e.g. x86_64, try "-DMONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD".)
+
+     [Andy Polyakov (backport partially by Bodo Moeller)]
+
+  *) Add TLS session ticket callback. This allows an application to set
+     TLS ticket cipher and HMAC keys rather than relying on hardcoded fixed
+     values. This is useful for key rollover for example where several key
+     sets may exist with different names.
+     [Steve Henson]
+
+  *) Reverse ENGINE-internal logic for caching default ENGINE handles.
+     This was broken until now in 0.9.8 releases, such that the only way
+     a registered ENGINE could be used (assuming it initialises
+     successfully on the host) was to explicitly set it as the default
+     for the relevant algorithms. This is in contradiction with 0.9.7
+     behaviour and the documentation. With this fix, when an ENGINE is
+     registered into a given algorithm's table of implementations, the
+     'uptodate' flag is reset so that auto-discovery will be used next
+     time a new context for that algorithm attempts to select an
+     implementation.
+     [Ian Lister (tweaked by Geoff Thorpe)]
+
+  *) Backport of CMS code to OpenSSL 0.9.8. This differs from the 0.9.9
+     implemention in the following ways:
+
+     Lack of EVP_PKEY_ASN1_METHOD means algorithm parameters have to be
+     hard coded.
+
+     Lack of BER streaming support means one pass streaming processing is
+     only supported if data is detached: setting the streaming flag is
+     ignored for embedded content.
+
+     CMS support is disabled by default and must be explicitly enabled
+     with the enable-cms configuration option.
+     [Steve Henson]
+
+  *) Update the GMP engine glue to do direct copies between BIGNUM and
+     mpz_t when openssl and GMP use the same limb size. Otherwise the
+     existing "conversion via a text string export" trick is still used.
+     [Paul Sheer <paulsheer@gmail.com>]
+
+  *) Zlib compression BIO. This is a filter BIO which compressed and
+     uncompresses any data passed through it.
+     [Steve Henson]
+
+  *) Add AES_wrap_key() and AES_unwrap_key() functions to implement
+     RFC3394 compatible AES key wrapping.
+     [Steve Henson]
+
+  *) Add utility functions to handle ASN1 structures. ASN1_STRING_set0():
+     sets string data without copying. X509_ALGOR_set0() and
+     X509_ALGOR_get0(): set and retrieve X509_ALGOR (AlgorithmIdentifier)
+     data. Attribute function X509at_get0_data_by_OBJ(): retrieves data
+     from an X509_ATTRIBUTE structure optionally checking it occurs only
+     once. ASN1_TYPE_set1(): set and ASN1_TYPE structure copying supplied
+     data.
+     [Steve Henson]
+
+  *) Fix BN flag handling in RSA_eay_mod_exp() and BN_MONT_CTX_set()
+     to get the expected BN_FLG_CONSTTIME behavior.
+     [Bodo Moeller (Google)]
+  
+  *) Netware support:
+
+     - fixed wrong usage of ioctlsocket() when build for LIBC BSD sockets
+     - fixed do_tests.pl to run the test suite with CLIB builds too (CLIB_OPT)
+     - added some more tests to do_tests.pl
+     - fixed RunningProcess usage so that it works with newer LIBC NDKs too
+     - removed usage of BN_LLONG for CLIB builds to avoid runtime dependency
+     - added new Configure targets netware-clib-bsdsock, netware-clib-gcc,
+       netware-clib-bsdsock-gcc, netware-libc-bsdsock-gcc
+     - various changes to netware.pl to enable gcc-cross builds on Win32
+       platform
+     - changed crypto/bio/b_sock.c to work with macro functions (CLIB BSD)
+     - various changes to fix missing prototype warnings
+     - fixed x86nasm.pl to create correct asm files for NASM COFF output
+     - added AES, WHIRLPOOL and CPUID assembler code to build files
+     - added missing AES assembler make rules to mk1mf.pl
+     - fixed order of includes in apps/ocsp.c so that e_os.h settings apply
+     [Guenter Knauf <eflash@gmx.net>]
+
+  *) Implement certificate status request TLS extension defined in RFC3546.
+     A client can set the appropriate parameters and receive the encoded
+     OCSP response via a callback. A server can query the supplied parameters
+     and set the encoded OCSP response in the callback. Add simplified examples
+     to s_client and s_server.
+     [Steve Henson]
+
+ Changes between 0.9.8f and 0.9.8g  [19 Oct 2007]
+
+  *) Fix various bugs:
+     + Binary incompatibility of ssl_ctx_st structure
+     + DTLS interoperation with non-compliant servers
+     + Don't call get_session_cb() without proposed session
+     + Fix ia64 assembler code
+     [Andy Polyakov, Steve Henson]
+
+ Changes between 0.9.8e and 0.9.8f  [11 Oct 2007]
+
+  *) DTLS Handshake overhaul. There were longstanding issues with
+     OpenSSL DTLS implementation, which were making it impossible for
+     RFC 4347 compliant client to communicate with OpenSSL server.
+     Unfortunately just fixing these incompatibilities would "cut off"
+     pre-0.9.8f clients. To allow for hassle free upgrade post-0.9.8e
+     server keeps tolerating non RFC compliant syntax. The opposite is
+     not true, 0.9.8f client can not communicate with earlier server.
+     This update even addresses CVE-2007-4995.
+     [Andy Polyakov]
+
+  *) Changes to avoid need for function casts in OpenSSL: some compilers
+     (gcc 4.2 and later) reject their use.
+     [Kurt Roeckx <kurt@roeckx.be>, Peter Hartley <pdh@utter.chaos.org.uk>,
+      Steve Henson]
+  
+  *) Add RFC4507 support to OpenSSL. This includes the corrections in
+     RFC4507bis. The encrypted ticket format is an encrypted encoded
+     SSL_SESSION structure, that way new session features are automatically
+     supported.
+
+     If a client application caches session in an SSL_SESSION structure
+     support is transparent because tickets are now stored in the encoded
+     SSL_SESSION.
+     
+     The SSL_CTX structure automatically generates keys for ticket
+     protection in servers so again support should be possible
+     with no application modification.
+
+     If a client or server wishes to disable RFC4507 support then the option
+     SSL_OP_NO_TICKET can be set.
+
+     Add a TLS extension debugging callback to allow the contents of any client
+     or server extensions to be examined.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Add initial support for TLS extensions, specifically for the server_name
+     extension so far.  The SSL_SESSION, SSL_CTX, and SSL data structures now
+     have new members for a host name.  The SSL data structure has an
+     additional member SSL_CTX *initial_ctx so that new sessions can be
+     stored in that context to allow for session resumption, even after the
+     SSL has been switched to a new SSL_CTX in reaction to a client's
+     server_name extension.
+
+     New functions (subject to change):
+
+         SSL_get_servername()
+         SSL_get_servername_type()
+         SSL_set_SSL_CTX()
+
+     New CTRL codes and macros (subject to change):
+
+         SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
+                                 - SSL_CTX_set_tlsext_servername_callback()
+         SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG
+                                      - SSL_CTX_set_tlsext_servername_arg()
+         SSL_CTRL_SET_TLSEXT_HOSTNAME           - SSL_set_tlsext_host_name()
+
+     openssl s_client has a new '-servername ...' option.
+
+     openssl s_server has new options '-servername_host ...', '-cert2 ...',
+     '-key2 ...', '-servername_fatal' (subject to change).  This allows
+     testing the HostName extension for a specific single host name ('-cert'
+     and '-key' remain fallbacks for handshakes without HostName
+     negotiation).  If the unrecogninzed_name alert has to be sent, this by
+     default is a warning; it becomes fatal with the '-servername_fatal'
+     option.
+
+     [Peter Sylvester,  Remy Allais, Christophe Renou, Steve Henson]
+
+  *) Add AES and SSE2 assembly language support to VC++ build.
+     [Steve Henson]
+
+  *) Mitigate attack on final subtraction in Montgomery reduction.
+     [Andy Polyakov]
+
+  *) Fix crypto/ec/ec_mult.c to work properly with scalars of value 0
+     (which previously caused an internal error).
+     [Bodo Moeller]
+
+  *) Squeeze another 10% out of IGE mode when in != out.
+     [Ben Laurie]
+
+  *) AES IGE mode speedup.
+     [Dean Gaudet (Google)]
+
+  *) Add the Korean symmetric 128-bit cipher SEED (see
+     http://www.kisa.or.kr/kisa/seed/jsp/seed_eng.jsp) and
+     add SEED ciphersuites from RFC 4162:
+
+        TLS_RSA_WITH_SEED_CBC_SHA      =  "SEED-SHA"
+        TLS_DHE_DSS_WITH_SEED_CBC_SHA  =  "DHE-DSS-SEED-SHA"
+        TLS_DHE_RSA_WITH_SEED_CBC_SHA  =  "DHE-RSA-SEED-SHA"
+        TLS_DH_anon_WITH_SEED_CBC_SHA  =  "ADH-SEED-SHA"
+
+     To minimize changes between patchlevels in the OpenSSL 0.9.8
+     series, SEED remains excluded from compilation unless OpenSSL
+     is configured with 'enable-seed'.
+     [KISA, Bodo Moeller]
+
+  *) Mitigate branch prediction attacks, which can be practical if a
+     single processor is shared, allowing a spy process to extract
+     information.  For detailed background information, see
+     http://eprint.iacr.org/2007/039 (O. Aciicmez, S. Gueron,
+     J.-P. Seifert, "New Branch Prediction Vulnerabilities in OpenSSL
+     and Necessary Software Countermeasures").  The core of the change
+     are new versions BN_div_no_branch() and
+     BN_mod_inverse_no_branch() of BN_div() and BN_mod_inverse(),
+     respectively, which are slower, but avoid the security-relevant
+     conditional branches.  These are automatically called by BN_div()
+     and BN_mod_inverse() if the flag BN_FLG_CONSTTIME is set for one
+     of the input BIGNUMs.  Also, BN_is_bit_set() has been changed to
+     remove a conditional branch.
+
+     BN_FLG_CONSTTIME is the new name for the previous
+     BN_FLG_EXP_CONSTTIME flag, since it now affects more than just
+     modular exponentiation.  (Since OpenSSL 0.9.7h, setting this flag
+     in the exponent causes BN_mod_exp_mont() to use the alternative
+     implementation in BN_mod_exp_mont_consttime().)  The old name
+     remains as a deprecated alias.
+
+     Similary, RSA_FLAG_NO_EXP_CONSTTIME is replaced by a more general
+     RSA_FLAG_NO_CONSTTIME flag since the RSA implementation now uses
+     constant-time implementations for more than just exponentiation.
+     Here too the old name is kept as a deprecated alias.
+
+     BN_BLINDING_new() will now use BN_dup() for the modulus so that
+     the BN_BLINDING structure gets an independent copy of the
+     modulus.  This means that the previous "BIGNUM *m" argument to
+     BN_BLINDING_new() and to BN_BLINDING_create_param() now
+     essentially becomes "const BIGNUM *m", although we can't actually
+     change this in the header file before 0.9.9.  It allows
+     RSA_setup_blinding() to use BN_with_flags() on the modulus to
+     enable BN_FLG_CONSTTIME.
+
+     [Matthew D Wood (Intel Corp)]
+
+  *) In the SSL/TLS server implementation, be strict about session ID
+     context matching (which matters if an application uses a single
+     external cache for different purposes).  Previously,
+     out-of-context reuse was forbidden only if SSL_VERIFY_PEER was
+     set.  This did ensure strict client verification, but meant that,
+     with applications using a single external cache for quite
+     different requirements, clients could circumvent ciphersuite
+     restrictions for a given session ID context by starting a session
+     in a different context.
+     [Bodo Moeller]
+
+  *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that
+     a ciphersuite string such as "DEFAULT:RSA" cannot enable
+     authentication-only ciphersuites.
+     [Bodo Moeller]
+
+  *) Update the SSL_get_shared_ciphers() fix CVE-2006-3738 which was
+     not complete and could lead to a possible single byte overflow
+     (CVE-2007-5135) [Ben Laurie]
+
+ Changes between 0.9.8d and 0.9.8e  [23 Feb 2007]
+
+  *) Since AES128 and AES256 (and similarly Camellia128 and
+     Camellia256) share a single mask bit in the logic of
+     ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a
+     kludge to work properly if AES128 is available and AES256 isn't
+     (or if Camellia128 is available and Camellia256 isn't).
+     [Victor Duchovni]
+
+  *) Fix the BIT STRING encoding generated by crypto/ec/ec_asn1.c
+     (within i2d_ECPrivateKey, i2d_ECPKParameters, i2d_ECParameters):
+     When a point or a seed is encoded in a BIT STRING, we need to
+     prevent the removal of trailing zero bits to get the proper DER
+     encoding.  (By default, crypto/asn1/a_bitstr.c assumes the case
+     of a NamedBitList, for which trailing 0 bits need to be removed.)
+     [Bodo Moeller]
+
+  *) Have SSL/TLS server implementation tolerate "mismatched" record
+     protocol version while receiving ClientHello even if the
+     ClientHello is fragmented.  (The server can't insist on the
+     particular protocol version it has chosen before the ServerHello
+     message has informed the client about his choice.)
+     [Bodo Moeller]
+
+  *) Add RFC 3779 support.
+     [Rob Austein for ARIN, Ben Laurie]
+
+  *) Load error codes if they are not already present instead of using a
+     static variable. This allows them to be cleanly unloaded and reloaded.
+     Improve header file function name parsing.
+     [Steve Henson]
+
+  *) extend SMTP and IMAP protocol emulation in s_client to use EHLO
+     or CAPABILITY handshake as required by RFCs.
+     [Goetz Babin-Ebell]
+
+ Changes between 0.9.8c and 0.9.8d  [28 Sep 2006]
+
+  *) Introduce limits to prevent malicious keys being able to
+     cause a denial of service.  (CVE-2006-2940)
+     [Steve Henson, Bodo Moeller]
+
+  *) Fix ASN.1 parsing of certain invalid structures that can result
+     in a denial of service.  (CVE-2006-2937)  [Steve Henson]
+
+  *) Fix buffer overflow in SSL_get_shared_ciphers() function. 
+     (CVE-2006-3738) [Tavis Ormandy and Will Drewry, Google Security Team]
+
+  *) Fix SSL client code which could crash if connecting to a
+     malicious SSLv2 server.  (CVE-2006-4343)
+     [Tavis Ormandy and Will Drewry, Google Security Team]
+
+  *) Since 0.9.8b, ciphersuite strings naming explicit ciphersuites
+     match only those.  Before that, "AES256-SHA" would be interpreted
+     as a pattern and match "AES128-SHA" too (since AES128-SHA got
+     the same strength classification in 0.9.7h) as we currently only
+     have a single AES bit in the ciphersuite description bitmap.
+     That change, however, also applied to ciphersuite strings such as
+     "RC4-MD5" that intentionally matched multiple ciphersuites --
+     namely, SSL 2.0 ciphersuites in addition to the more common ones
+     from SSL 3.0/TLS 1.0.
+
+     So we change the selection algorithm again: Naming an explicit
+     ciphersuite selects this one ciphersuite, and any other similar
+     ciphersuite (same bitmap) from *other* protocol versions.
+     Thus, "RC4-MD5" again will properly select both the SSL 2.0
+     ciphersuite and the SSL 3.0/TLS 1.0 ciphersuite.
+
+     Since SSL 2.0 does not have any ciphersuites for which the
+     128/256 bit distinction would be relevant, this works for now.
+     The proper fix will be to use different bits for AES128 and
+     AES256, which would have avoided the problems from the beginning;
+     however, bits are scarce, so we can only do this in a new release
+     (not just a patchlevel) when we can change the SSL_CIPHER
+     definition to split the single 'unsigned long mask' bitmap into
+     multiple values to extend the available space.
+
+     [Bodo Moeller]
+
+ Changes between 0.9.8b and 0.9.8c  [05 Sep 2006]
+
+  *) Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher
+     (CVE-2006-4339)  [Ben Laurie and Google Security Team]
+
+  *) Add AES IGE and biIGE modes.
+     [Ben Laurie]
+
+  *) Change the Unix randomness entropy gathering to use poll() when
+     possible instead of select(), since the latter has some
+     undesirable limitations.
+     [Darryl Miles via Richard Levitte and Bodo Moeller]
+
+  *) Disable "ECCdraft" ciphersuites more thoroughly.  Now special
+     treatment in ssl/ssl_ciph.s makes sure that these ciphersuites
+     cannot be implicitly activated as part of, e.g., the "AES" alias.
+     However, please upgrade to OpenSSL 0.9.9[-dev] for
+     non-experimental use of the ECC ciphersuites to get TLS extension
+     support, which is required for curve and point format negotiation
+     to avoid potential handshake problems.
+     [Bodo Moeller]
+
+  *) Disable rogue ciphersuites:
+
+      - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5")
+      - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5")
+      - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5")
+
+     The latter two were purportedly from
+     draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really
+     appear there.
+
+     Also deactivate the remaining ciphersuites from
+     draft-ietf-tls-56-bit-ciphersuites-01.txt.  These are just as
+     unofficial, and the ID has long expired.
+     [Bodo Moeller]
+
+  *) Fix RSA blinding Heisenbug (problems sometimes occured on
+     dual-core machines) and other potential thread-safety issues.
+     [Bodo Moeller]
+
+  *) Add the symmetric cipher Camellia (128-bit, 192-bit, 256-bit key
+     versions), which is now available for royalty-free use
+     (see http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html).
+     Also, add Camellia TLS ciphersuites from RFC 4132.
+
+     To minimize changes between patchlevels in the OpenSSL 0.9.8
+     series, Camellia remains excluded from compilation unless OpenSSL
+     is configured with 'enable-camellia'.
+     [NTT]
+
+  *) Disable the padding bug check when compression is in use. The padding
+     bug check assumes the first packet is of even length, this is not
+     necessarily true if compresssion is enabled and can result in false
+     positives causing handshake failure. The actual bug test is ancient
+     code so it is hoped that implementations will either have fixed it by
+     now or any which still have the bug do not support compression.
+     [Steve Henson]
+
+ Changes between 0.9.8a and 0.9.8b  [04 May 2006]
+
+  *) When applying a cipher rule check to see if string match is an explicit
+     cipher suite and only match that one cipher suite if it is.
+     [Steve Henson]
+
+  *) Link in manifests for VC++ if needed.
+     [Austin Ziegler <halostatue@gmail.com>]
+
+  *) Update support for ECC-based TLS ciphersuites according to
+     draft-ietf-tls-ecc-12.txt with proposed changes (but without
+     TLS extensions, which are supported starting with the 0.9.9
+     branch, not in the OpenSSL 0.9.8 branch).
+     [Douglas Stebila]
+
+  *) New functions EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free() to support
+     opaque EVP_CIPHER_CTX handling.
+     [Steve Henson]
+
+  *) Fixes and enhancements to zlib compression code. We now only use
+     "zlib1.dll" and use the default __cdecl calling convention on Win32
+     to conform with the standards mentioned here:
+           http://www.zlib.net/DLL_FAQ.txt
+     Static zlib linking now works on Windows and the new --with-zlib-include
+     --with-zlib-lib options to Configure can be used to supply the location
+     of the headers and library. Gracefully handle case where zlib library
+     can't be loaded.
+     [Steve Henson]
+
+  *) Several fixes and enhancements to the OID generation code. The old code
+     sometimes allowed invalid OIDs (1.X for X >= 40 for example), couldn't
+     handle numbers larger than ULONG_MAX, truncated printing and had a
+     non standard OBJ_obj2txt() behaviour.
+     [Steve Henson]
+
+  *) Add support for building of engines under engine/ as shared libraries
+     under VC++ build system.
+     [Steve Henson]
+
+  *) Corrected the numerous bugs in the Win32 path splitter in DSO.
+     Hopefully, we will not see any false combination of paths any more.
+     [Richard Levitte]
+
+ Changes between 0.9.8 and 0.9.8a  [11 Oct 2005]
+
+  *) Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING
+     (part of SSL_OP_ALL).  This option used to disable the
+     countermeasure against man-in-the-middle protocol-version
+     rollback in the SSL 2.0 server implementation, which is a bad
+     idea.  (CVE-2005-2969)
+
+     [Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center
+     for Information Security, National Institute of Advanced Industrial
+     Science and Technology [AIST], Japan)]
+
+  *) Add two function to clear and return the verify parameter flags.
+     [Steve Henson]
+
+  *) Keep cipherlists sorted in the source instead of sorting them at
+     runtime, thus removing the need for a lock.
+     [Nils Larsch]
+
+  *) Avoid some small subgroup attacks in Diffie-Hellman.
+     [Nick Mathewson and Ben Laurie]
+
+  *) Add functions for well-known primes.
+     [Nick Mathewson]
+
+  *) Extended Windows CE support.
+     [Satoshi Nakamura and Andy Polyakov]
+
+  *) Initialize SSL_METHOD structures at compile time instead of during
+     runtime, thus removing the need for a lock.
+     [Steve Henson]
+
+  *) Make PKCS7_decrypt() work even if no certificate is supplied by
+     attempting to decrypt each encrypted key in turn. Add support to
+     smime utility.
+     [Steve Henson]
+
+ Changes between 0.9.7h and 0.9.8  [05 Jul 2005]
+
+  [NB: OpenSSL 0.9.7i and later 0.9.7 patch levels were released after
+  OpenSSL 0.9.8.]
+
+  *) Add libcrypto.pc and libssl.pc for those who feel they need them.
+     [Richard Levitte]
+
+  *) Change CA.sh and CA.pl so they don't bundle the CSR and the private
+     key into the same file any more.
+     [Richard Levitte]
+
+  *) Add initial support for Win64, both IA64 and AMD64/x64 flavors.
+     [Andy Polyakov]
+
+  *) Add -utf8 command line and config file option to 'ca'.
+     [Stefan <stf@udoma.org]
+
+  *) Removed the macro des_crypt(), as it seems to conflict with some
+     libraries.  Use DES_crypt().
+     [Richard Levitte]
+
+  *) Correct naming of the 'chil' and '4758cca' ENGINEs. This
+     involves renaming the source and generated shared-libs for
+     both. The engines will accept the corrected or legacy ids
+     ('ncipher' and '4758_cca' respectively) when binding. NB,
+     this only applies when building 'shared'.
+     [Corinna Vinschen <vinschen@redhat.com> and Geoff Thorpe]
+
+  *) Add attribute functions to EVP_PKEY structure. Modify
+     PKCS12_create() to recognize a CSP name attribute and
+     use it. Make -CSP option work again in pkcs12 utility.
+     [Steve Henson]
+
+  *) Add new functionality to the bn blinding code:
+     - automatic re-creation of the BN_BLINDING parameters after
+       a fixed number of uses (currently 32)
+     - add new function for parameter creation
+     - introduce flags to control the update behaviour of the
+       BN_BLINDING parameters
+     - hide BN_BLINDING structure
+     Add a second BN_BLINDING slot to the RSA structure to improve
+     performance when a single RSA object is shared among several
+     threads.
+     [Nils Larsch]
+
+  *) Add support for DTLS.
+     [Nagendra Modadugu <nagendra@cs.stanford.edu> and Ben Laurie]
+
+  *) Add support for DER encoded private keys (SSL_FILETYPE_ASN1)
+     to SSL_CTX_use_PrivateKey_file() and SSL_use_PrivateKey_file()
+     [Walter Goulet]
+
+  *) Remove buggy and incompletet DH cert support from
+     ssl/ssl_rsa.c and ssl/s3_both.c
+     [Nils Larsch]
+
+  *) Use SHA-1 instead of MD5 as the default digest algorithm for
+     the apps/openssl applications.
+     [Nils Larsch]
+
+  *) Compile clean with "-Wall -Wmissing-prototypes
+     -Wstrict-prototypes -Wmissing-declarations -Werror". Currently
+     DEBUG_SAFESTACK must also be set.
+     [Ben Laurie]
+
+  *) Change ./Configure so that certain algorithms can be disabled by default.
+     The new counterpiece to "no-xxx" is "enable-xxx".
+
+     The patented RC5 and MDC2 algorithms will now be disabled unless
+     "enable-rc5" and "enable-mdc2", respectively, are specified.
+
+     (IDEA remains enabled despite being patented.  This is because IDEA
+     is frequently required for interoperability, and there is no license
+     fee for non-commercial use.  As before, "no-idea" can be used to
+     avoid this algorithm.)
+
+     [Bodo Moeller]
+
+  *) Add processing of proxy certificates (see RFC 3820).  This work was
+     sponsored by KTH (The Royal Institute of Technology in Stockholm) and
+     EGEE (Enabling Grids for E-science in Europe).
+     [Richard Levitte]
+
+  *) RC4 performance overhaul on modern architectures/implementations, such
+     as Intel P4, IA-64 and AMD64.
+     [Andy Polyakov]
+
+  *) New utility extract-section.pl. This can be used specify an alternative
+     section number in a pod file instead of having to treat each file as
+     a separate case in Makefile. This can be done by adding two lines to the
+     pod file:
+
+     =for comment openssl_section:XXX
+
+     The blank line is mandatory.
+
+     [Steve Henson]
+
+  *) New arguments -certform, -keyform and -pass for s_client and s_server
+     to allow alternative format key and certificate files and passphrase
+     sources.
+     [Steve Henson]
+
+  *) New structure X509_VERIFY_PARAM which combines current verify parameters,
+     update associated structures and add various utility functions.
+
+     Add new policy related verify parameters, include policy checking in 
+     standard verify code. Enhance 'smime' application with extra parameters
+     to support policy checking and print out.
+     [Steve Henson]
+
+  *) Add a new engine to support VIA PadLock ACE extensions in the VIA C3
+     Nehemiah processors. These extensions support AES encryption in hardware
+     as well as RNG (though RNG support is currently disabled).
+     [Michal Ludvig <michal@logix.cz>, with help from Andy Polyakov]
+
+  *) Deprecate BN_[get|set]_params() functions (they were ignored internally).
+     [Geoff Thorpe]
+
+  *) New FIPS 180-2 algorithms, SHA-224/-256/-384/-512 are implemented.
+     [Andy Polyakov and a number of other people]
+
+  *) Improved PowerPC platform support. Most notably BIGNUM assembler
+     implementation contributed by IBM.
+     [Suresh Chari, Peter Waltenberg, Andy Polyakov]
+
+  *) The new 'RSA_generate_key_ex' function now takes a BIGNUM for the public
+     exponent rather than 'unsigned long'. There is a corresponding change to
+     the new 'rsa_keygen' element of the RSA_METHOD structure.
+     [Jelte Jansen, Geoff Thorpe]
+
+  *) Functionality for creating the initial serial number file is now
+     moved from CA.pl to the 'ca' utility with a new option -create_serial.
+
+     (Before OpenSSL 0.9.7e, CA.pl used to initialize the serial
+     number file to 1, which is bound to cause problems.  To avoid
+     the problems while respecting compatibility between different 0.9.7
+     patchlevels, 0.9.7e  employed 'openssl x509 -next_serial' in
+     CA.pl for serial number initialization.  With the new release 0.9.8,
+     we can fix the problem directly in the 'ca' utility.)
+     [Steve Henson]
+
+  *) Reduced header interdepencies by declaring more opaque objects in
+     ossl_typ.h. As a consequence, including some headers (eg. engine.h) will
+     give fewer recursive includes, which could break lazy source code - so
+     this change is covered by the OPENSSL_NO_DEPRECATED symbol. As always,
+     developers should define this symbol when building and using openssl to
+     ensure they track the recommended behaviour, interfaces, [etc], but
+     backwards-compatible behaviour prevails when this isn't defined.
+     [Geoff Thorpe]
+
+  *) New function X509_POLICY_NODE_print() which prints out policy nodes.
+     [Steve Henson]
+
+  *) Add new EVP function EVP_CIPHER_CTX_rand_key and associated functionality.
+     This will generate a random key of the appropriate length based on the 
+     cipher context. The EVP_CIPHER can provide its own random key generation
+     routine to support keys of a specific form. This is used in the des and 
+     3des routines to generate a key of the correct parity. Update S/MIME
+     code to use new functions and hence generate correct parity DES keys.
+     Add EVP_CHECK_DES_KEY #define to return an error if the key is not 
+     valid (weak or incorrect parity).
+     [Steve Henson]
+
+  *) Add a local set of CRLs that can be used by X509_verify_cert() as well
+     as looking them up. This is useful when the verified structure may contain
+     CRLs, for example PKCS#7 signedData. Modify PKCS7_verify() to use any CRLs
+     present unless the new PKCS7_NO_CRL flag is asserted.
+     [Steve Henson]
+
+  *) Extend ASN1 oid configuration module. It now additionally accepts the
+     syntax:
+
+     shortName = some long name, 1.2.3.4
+     [Steve Henson]
+
+  *) Reimplemented the BN_CTX implementation. There is now no more static
+     limitation on the number of variables it can handle nor the depth of the
+     "stack" handling for BN_CTX_start()/BN_CTX_end() pairs. The stack
+     information can now expand as required, and rather than having a single
+     static array of bignums, BN_CTX now uses a linked-list of such arrays
+     allowing it to expand on demand whilst maintaining the usefulness of
+     BN_CTX's "bundling".
+     [Geoff Thorpe]
+
+  *) Add a missing BN_CTX parameter to the 'rsa_mod_exp' callback in RSA_METHOD
+     to allow all RSA operations to function using a single BN_CTX.
+     [Geoff Thorpe]
+
+  *) Preliminary support for certificate policy evaluation and checking. This
+     is initially intended to pass the tests outlined in "Conformance Testing
+     of Relying Party Client Certificate Path Processing Logic" v1.07.
+     [Steve Henson]
+
+  *) bn_dup_expand() has been deprecated, it was introduced in 0.9.7 and
+     remained unused and not that useful. A variety of other little bignum
+     tweaks and fixes have also been made continuing on from the audit (see
+     below).
+     [Geoff Thorpe]
+
+  *) Constify all or almost all d2i, c2i, s2i and r2i functions, along with
+     associated ASN1, EVP and SSL functions and old ASN1 macros.
+     [Richard Levitte]
+
+  *) BN_zero() only needs to set 'top' and 'neg' to zero for correct results,
+     and this should never fail. So the return value from the use of
+     BN_set_word() (which can fail due to needless expansion) is now deprecated;
+     if OPENSSL_NO_DEPRECATED is defined, BN_zero() is a void macro.
+     [Geoff Thorpe]
+
+  *) BN_CTX_get() should return zero-valued bignums, providing the same
+     initialised value as BN_new().
+     [Geoff Thorpe, suggested by Ulf Möller]
+
+  *) Support for inhibitAnyPolicy certificate extension.
+     [Steve Henson]
+
+  *) An audit of the BIGNUM code is underway, for which debugging code is
+     enabled when BN_DEBUG is defined. This makes stricter enforcements on what
+     is considered valid when processing BIGNUMs, and causes execution to
+     assert() when a problem is discovered. If BN_DEBUG_RAND is defined,
+     further steps are taken to deliberately pollute unused data in BIGNUM
+     structures to try and expose faulty code further on. For now, openssl will
+     (in its default mode of operation) continue to tolerate the inconsistent
+     forms that it has tolerated in the past, but authors and packagers should
+     consider trying openssl and their own applications when compiled with
+     these debugging symbols defined. It will help highlight potential bugs in
+     their own code, and will improve the test coverage for OpenSSL itself. At
+     some point, these tighter rules will become openssl's default to improve
+     maintainability, though the assert()s and other overheads will remain only
+     in debugging configurations. See bn.h for more details.
+     [Geoff Thorpe, Nils Larsch, Ulf Möller]
+
+  *) BN_CTX_init() has been deprecated, as BN_CTX is an opaque structure
+     that can only be obtained through BN_CTX_new() (which implicitly
+     initialises it). The presence of this function only made it possible
+     to overwrite an existing structure (and cause memory leaks).
+     [Geoff Thorpe]
+
+  *) Because of the callback-based approach for implementing LHASH as a
+     template type, lh_insert() adds opaque objects to hash-tables and
+     lh_doall() or lh_doall_arg() are typically used with a destructor callback
+     to clean up those corresponding objects before destroying the hash table
+     (and losing the object pointers). So some over-zealous constifications in
+     LHASH have been relaxed so that lh_insert() does not take (nor store) the
+     objects as "const" and the lh_doall[_arg] callback wrappers are not
+     prototyped to have "const" restrictions on the object pointers they are
+     given (and so aren't required to cast them away any more).
+     [Geoff Thorpe]
+
+  *) The tmdiff.h API was so ugly and minimal that our own timing utility
+     (speed) prefers to use its own implementation. The two implementations
+     haven't been consolidated as yet (volunteers?) but the tmdiff API has had
+     its object type properly exposed (MS_TM) instead of casting to/from "char
+     *". This may still change yet if someone realises MS_TM and "ms_time_***"
+     aren't necessarily the greatest nomenclatures - but this is what was used
+     internally to the implementation so I've used that for now.
+     [Geoff Thorpe]
+
+  *) Ensure that deprecated functions do not get compiled when
+     OPENSSL_NO_DEPRECATED is defined. Some "openssl" subcommands and a few of
+     the self-tests were still using deprecated key-generation functions so
+     these have been updated also.
+     [Geoff Thorpe]
+
+  *) Reorganise PKCS#7 code to separate the digest location functionality
+     into PKCS7_find_digest(), digest addtion into PKCS7_bio_add_digest().
+     New function PKCS7_set_digest() to set the digest type for PKCS#7
+     digestedData type. Add additional code to correctly generate the
+     digestedData type and add support for this type in PKCS7 initialization
+     functions.
+     [Steve Henson]
+
+  *) New function PKCS7_set0_type_other() this initializes a PKCS7 
+     structure of type "other".
+     [Steve Henson]
+
+  *) Fix prime generation loop in crypto/bn/bn_prime.pl by making
+     sure the loop does correctly stop and breaking ("division by zero")
+     modulus operations are not performed. The (pre-generated) prime
+     table crypto/bn/bn_prime.h was already correct, but it could not be
+     re-generated on some platforms because of the "division by zero"
+     situation in the script.
+     [Ralf S. Engelschall]
+
+  *) Update support for ECC-based TLS ciphersuites according to
+     draft-ietf-tls-ecc-03.txt: the KDF1 key derivation function with
+     SHA-1 now is only used for "small" curves (where the
+     representation of a field element takes up to 24 bytes); for
+     larger curves, the field element resulting from ECDH is directly
+     used as premaster secret.
+     [Douglas Stebila (Sun Microsystems Laboratories)]
+
+  *) Add code for kP+lQ timings to crypto/ec/ectest.c, and add SEC2
+     curve secp160r1 to the tests.
+     [Douglas Stebila (Sun Microsystems Laboratories)]
+
+  *) Add the possibility to load symbols globally with DSO.
+     [Götz Babin-Ebell <babin-ebell@trustcenter.de> via Richard Levitte]
+
+  *) Add the functions ERR_set_mark() and ERR_pop_to_mark() for better
+     control of the error stack.
+     [Richard Levitte]
+
+  *) Add support for STORE in ENGINE.
+     [Richard Levitte]
+
+  *) Add the STORE type.  The intention is to provide a common interface
+     to certificate and key stores, be they simple file-based stores, or
+     HSM-type store, or LDAP stores, or...
+     NOTE: The code is currently UNTESTED and isn't really used anywhere.
+     [Richard Levitte]
+
+  *) Add a generic structure called OPENSSL_ITEM.  This can be used to
+     pass a list of arguments to any function as well as provide a way
+     for a function to pass data back to the caller.
+     [Richard Levitte]
+
+  *) Add the functions BUF_strndup() and BUF_memdup().  BUF_strndup()
+     works like BUF_strdup() but can be used to duplicate a portion of
+     a string.  The copy gets NUL-terminated.  BUF_memdup() duplicates
+     a memory area.
+     [Richard Levitte]
+
+  *) Add the function sk_find_ex() which works like sk_find(), but will
+     return an index to an element even if an exact match couldn't be
+     found.  The index is guaranteed to point at the element where the
+     searched-for key would be inserted to preserve sorting order.
+     [Richard Levitte]
+
+  *) Add the function OBJ_bsearch_ex() which works like OBJ_bsearch() but
+     takes an extra flags argument for optional functionality.  Currently,
+     the following flags are defined:
+
+	OBJ_BSEARCH_VALUE_ON_NOMATCH
+	This one gets OBJ_bsearch_ex() to return a pointer to the first
+	element where the comparing function returns a negative or zero
+	number.
+
+	OBJ_BSEARCH_FIRST_VALUE_ON_MATCH
+	This one gets OBJ_bsearch_ex() to return a pointer to the first
+	element where the comparing function returns zero.  This is useful
+	if there are more than one element where the comparing function
+	returns zero.
+     [Richard Levitte]
+
+  *) Make it possible to create self-signed certificates with 'openssl ca'
+     in such a way that the self-signed certificate becomes part of the
+     CA database and uses the same mechanisms for serial number generation
+     as all other certificate signing.  The new flag '-selfsign' enables
+     this functionality.  Adapt CA.sh and CA.pl.in.
+     [Richard Levitte]
+
+  *) Add functionality to check the public key of a certificate request
+     against a given private.  This is useful to check that a certificate
+     request can be signed by that key (self-signing).
+     [Richard Levitte]
+
+  *) Make it possible to have multiple active certificates with the same
+     subject in the CA index file.  This is done only if the keyword
+     'unique_subject' is set to 'no' in the main CA section (default
+     if 'CA_default') of the configuration file.  The value is saved
+     with the database itself in a separate index attribute file,
+     named like the index file with '.attr' appended to the name.
+     [Richard Levitte]
+
+  *) Generate muti valued AVAs using '+' notation in config files for
+     req and dirName.
+     [Steve Henson]
+
+  *) Support for nameConstraints certificate extension.
+     [Steve Henson]
+
+  *) Support for policyConstraints certificate extension.
+     [Steve Henson]
+
+  *) Support for policyMappings certificate extension.
+     [Steve Henson]
+
+  *) Make sure the default DSA_METHOD implementation only uses its
+     dsa_mod_exp() and/or bn_mod_exp() handlers if they are non-NULL,
+     and change its own handlers to be NULL so as to remove unnecessary
+     indirection. This lets alternative implementations fallback to the
+     default implementation more easily.
+     [Geoff Thorpe]
+
+  *) Support for directoryName in GeneralName related extensions
+     in config files.
+     [Steve Henson]
+
+  *) Make it possible to link applications using Makefile.shared.
+     Make that possible even when linking against static libraries!
+     [Richard Levitte]
+
+  *) Support for single pass processing for S/MIME signing. This now
+     means that S/MIME signing can be done from a pipe, in addition
+     cleartext signing (multipart/signed type) is effectively streaming
+     and the signed data does not need to be all held in memory.
+
+     This is done with a new flag PKCS7_STREAM. When this flag is set
+     PKCS7_sign() only initializes the PKCS7 structure and the actual signing
+     is done after the data is output (and digests calculated) in
+     SMIME_write_PKCS7().
+     [Steve Henson]
+
+  *) Add full support for -rpath/-R, both in shared libraries and
+     applications, at least on the platforms where it's known how
+     to do it.
+     [Richard Levitte]
+
+  *) In crypto/ec/ec_mult.c, implement fast point multiplication with
+     precomputation, based on wNAF splitting: EC_GROUP_precompute_mult()
+     will now compute a table of multiples of the generator that
+     makes subsequent invocations of EC_POINTs_mul() or EC_POINT_mul()
+     faster (notably in the case of a single point multiplication,
+     scalar * generator).
+     [Nils Larsch, Bodo Moeller]
+
+  *) IPv6 support for certificate extensions. The various extensions
+     which use the IP:a.b.c.d can now take IPv6 addresses using the
+     formats of RFC1884 2.2 . IPv6 addresses are now also displayed
+     correctly.
+     [Steve Henson]
+
+  *) Added an ENGINE that implements RSA by performing private key
+     exponentiations with the GMP library. The conversions to and from
+     GMP's mpz_t format aren't optimised nor are any montgomery forms
+     cached, and on x86 it appears OpenSSL's own performance has caught up.
+     However there are likely to be other architectures where GMP could
+     provide a boost. This ENGINE is not built in by default, but it can be
+     specified at Configure time and should be accompanied by the necessary
+     linker additions, eg;
+         ./config -DOPENSSL_USE_GMP -lgmp
+     [Geoff Thorpe]
+
+  *) "openssl engine" will not display ENGINE/DSO load failure errors when
+     testing availability of engines with "-t" - the old behaviour is
+     produced by increasing the feature's verbosity with "-tt".
+     [Geoff Thorpe]
+
+  *) ECDSA routines: under certain error conditions uninitialized BN objects
+     could be freed. Solution: make sure initialization is performed early
+     enough. (Reported and fix supplied by Nils Larsch <nla@trustcenter.de>
+     via PR#459)
+     [Lutz Jaenicke]
+
+  *) Key-generation can now be implemented in RSA_METHOD, DSA_METHOD
+     and DH_METHOD (eg. by ENGINE implementations) to override the normal
+     software implementations. For DSA and DH, parameter generation can
+     also be overriden by providing the appropriate method callbacks.
+     [Geoff Thorpe]
+
+  *) Change the "progress" mechanism used in key-generation and
+     primality testing to functions that take a new BN_GENCB pointer in
+     place of callback/argument pairs. The new API functions have "_ex"
+     postfixes and the older functions are reimplemented as wrappers for
+     the new ones. The OPENSSL_NO_DEPRECATED symbol can be used to hide
+     declarations of the old functions to help (graceful) attempts to
+     migrate to the new functions. Also, the new key-generation API
+     functions operate on a caller-supplied key-structure and return
+     success/failure rather than returning a key or NULL - this is to
+     help make "keygen" another member function of RSA_METHOD etc.
+
+     Example for using the new callback interface:
+
+          int (*my_callback)(int a, int b, BN_GENCB *cb) = ...;
+          void *my_arg = ...;
+          BN_GENCB my_cb;
+
+          BN_GENCB_set(&my_cb, my_callback, my_arg);
+
+          return BN_is_prime_ex(some_bignum, BN_prime_checks, NULL, &cb);
+          /* For the meaning of a, b in calls to my_callback(), see the
+           * documentation of the function that calls the callback.
+           * cb will point to my_cb; my_arg can be retrieved as cb->arg.
+           * my_callback should return 1 if it wants BN_is_prime_ex()
+           * to continue, or 0 to stop.
+           */
+
+     [Geoff Thorpe]
+
+  *) Change the ZLIB compression method to be stateful, and make it
+     available to TLS with the number defined in 
+     draft-ietf-tls-compression-04.txt.
+     [Richard Levitte]
+
+  *) Add the ASN.1 structures and functions for CertificatePair, which
+     is defined as follows (according to X.509_4thEditionDraftV6.pdf):
+
+     CertificatePair ::= SEQUENCE {
+        forward		[0]	Certificate OPTIONAL,
+        reverse		[1]	Certificate OPTIONAL,
+        -- at least one of the pair shall be present -- }
+
+     Also implement the PEM functions to read and write certificate
+     pairs, and defined the PEM tag as "CERTIFICATE PAIR".
+
+     This needed to be defined, mostly for the sake of the LDAP
+     attribute crossCertificatePair, but may prove useful elsewhere as
+     well.
+     [Richard Levitte]
+
+  *) Make it possible to inhibit symlinking of shared libraries in
+     Makefile.shared, for Cygwin's sake.
+     [Richard Levitte]
+
+  *) Extend the BIGNUM API by creating a function 
+          void BN_set_negative(BIGNUM *a, int neg);
+     and a macro that behave like
+          int  BN_is_negative(const BIGNUM *a);
+
+     to avoid the need to access 'a->neg' directly in applications.
+     [Nils Larsch]
+
+  *) Implement fast modular reduction for pseudo-Mersenne primes
+     used in NIST curves (crypto/bn/bn_nist.c, crypto/ec/ecp_nist.c).
+     EC_GROUP_new_curve_GFp() will now automatically use this
+     if applicable.
+     [Nils Larsch <nla@trustcenter.de>]
+
+  *) Add new lock type (CRYPTO_LOCK_BN).
+     [Bodo Moeller]
+
+  *) Change the ENGINE framework to automatically load engines
+     dynamically from specific directories unless they could be
+     found to already be built in or loaded.  Move all the
+     current engines except for the cryptodev one to a new
+     directory engines/.
+     The engines in engines/ are built as shared libraries if
+     the "shared" options was given to ./Configure or ./config.
+     Otherwise, they are inserted in libcrypto.a.
+     /usr/local/ssl/engines is the default directory for dynamic
+     engines, but that can be overriden at configure time through
+     the usual use of --prefix and/or --openssldir, and at run
+     time with the environment variable OPENSSL_ENGINES.
+     [Geoff Thorpe and Richard Levitte]
+
+  *) Add Makefile.shared, a helper makefile to build shared
+     libraries.  Addapt Makefile.org.
+     [Richard Levitte]
+
+  *) Add version info to Win32 DLLs.
+     [Peter 'Luna' Runestig" <peter@runestig.com>]
+
+  *) Add new 'medium level' PKCS#12 API. Certificates and keys
+     can be added using this API to created arbitrary PKCS#12
+     files while avoiding the low level API.
+
+     New options to PKCS12_create(), key or cert can be NULL and
+     will then be omitted from the output file. The encryption
+     algorithm NIDs can be set to -1 for no encryption, the mac
+     iteration count can be set to 0 to omit the mac.
+
+     Enhance pkcs12 utility by making the -nokeys and -nocerts
+     options work when creating a PKCS#12 file. New option -nomac
+     to omit the mac, NONE can be set for an encryption algorithm.
+     New code is modified to use the enhanced PKCS12_create()
+     instead of the low level API.
+     [Steve Henson]
+
+  *) Extend ASN1 encoder to support indefinite length constructed
+     encoding. This can output sequences tags and octet strings in
+     this form. Modify pk7_asn1.c to support indefinite length
+     encoding. This is experimental and needs additional code to
+     be useful, such as an ASN1 bio and some enhanced streaming
+     PKCS#7 code.
+
+     Extend template encode functionality so that tagging is passed
+     down to the template encoder.
+     [Steve Henson]
+
+  *) Let 'openssl req' fail if an argument to '-newkey' is not
+     recognized instead of using RSA as a default.
+     [Bodo Moeller]
+
+  *) Add support for ECC-based ciphersuites from draft-ietf-tls-ecc-01.txt.
+     As these are not official, they are not included in "ALL";
+     the "ECCdraft" ciphersuite group alias can be used to select them.
+     [Vipul Gupta and Sumit Gupta (Sun Microsystems Laboratories)]
+
+  *) Add ECDH engine support.
+     [Nils Gura and Douglas Stebila (Sun Microsystems Laboratories)]
+
+  *) Add ECDH in new directory crypto/ecdh/.
+     [Douglas Stebila (Sun Microsystems Laboratories)]
+
+  *) Let BN_rand_range() abort with an error after 100 iterations
+     without success (which indicates a broken PRNG).
+     [Bodo Moeller]
+
+  *) Change BN_mod_sqrt() so that it verifies that the input value
+     is really the square of the return value.  (Previously,
+     BN_mod_sqrt would show GIGO behaviour.)
+     [Bodo Moeller]
+
+  *) Add named elliptic curves over binary fields from X9.62, SECG,
+     and WAP/WTLS; add OIDs that were still missing.
+
+     [Sheueling Chang Shantz and Douglas Stebila
+     (Sun Microsystems Laboratories)]
+
+  *) Extend the EC library for elliptic curves over binary fields
+     (new files ec2_smpl.c, ec2_smpt.c, ec2_mult.c in crypto/ec/).
+     New EC_METHOD:
+
+          EC_GF2m_simple_method
+
+     New API functions:
+
+          EC_GROUP_new_curve_GF2m
+          EC_GROUP_set_curve_GF2m
+          EC_GROUP_get_curve_GF2m
+          EC_POINT_set_affine_coordinates_GF2m
+          EC_POINT_get_affine_coordinates_GF2m
+          EC_POINT_set_compressed_coordinates_GF2m
+
+     Point compression for binary fields is disabled by default for
+     patent reasons (compile with OPENSSL_EC_BIN_PT_COMP defined to
+     enable it).
+
+     As binary polynomials are represented as BIGNUMs, various members
+     of the EC_GROUP and EC_POINT data structures can be shared
+     between the implementations for prime fields and binary fields;
+     the above ..._GF2m functions (except for EX_GROUP_new_curve_GF2m)
+     are essentially identical to their ..._GFp counterparts.
+     (For simplicity, the '..._GFp' prefix has been dropped from
+     various internal method names.)
+
+     An internal 'field_div' method (similar to 'field_mul' and
+     'field_sqr') has been added; this is used only for binary fields.
+
+     [Sheueling Chang Shantz and Douglas Stebila
+     (Sun Microsystems Laboratories)]
+
+  *) Optionally dispatch EC_POINT_mul(), EC_POINT_precompute_mult()
+     through methods ('mul', 'precompute_mult').
+
+     The generic implementations (now internally called 'ec_wNAF_mul'
+     and 'ec_wNAF_precomputed_mult') remain the default if these
+     methods are undefined.
+
+     [Sheueling Chang Shantz and Douglas Stebila
+     (Sun Microsystems Laboratories)]
+
+  *) New function EC_GROUP_get_degree, which is defined through
+     EC_METHOD.  For curves over prime fields, this returns the bit
+     length of the modulus.
+
+     [Sheueling Chang Shantz and Douglas Stebila
+     (Sun Microsystems Laboratories)]
+
+  *) New functions EC_GROUP_dup, EC_POINT_dup.
+     (These simply call ..._new  and ..._copy).
+
+     [Sheueling Chang Shantz and Douglas Stebila
+     (Sun Microsystems Laboratories)]
+
+  *) Add binary polynomial arithmetic software in crypto/bn/bn_gf2m.c.
+     Polynomials are represented as BIGNUMs (where the sign bit is not
+     used) in the following functions [macros]:  
+
+          BN_GF2m_add
+          BN_GF2m_sub             [= BN_GF2m_add]
+          BN_GF2m_mod             [wrapper for BN_GF2m_mod_arr]
+          BN_GF2m_mod_mul         [wrapper for BN_GF2m_mod_mul_arr]
+          BN_GF2m_mod_sqr         [wrapper for BN_GF2m_mod_sqr_arr]
+          BN_GF2m_mod_inv
+          BN_GF2m_mod_exp         [wrapper for BN_GF2m_mod_exp_arr]
+          BN_GF2m_mod_sqrt        [wrapper for BN_GF2m_mod_sqrt_arr]
+          BN_GF2m_mod_solve_quad  [wrapper for BN_GF2m_mod_solve_quad_arr]
+          BN_GF2m_cmp             [= BN_ucmp]
+
+     (Note that only the 'mod' functions are actually for fields GF(2^m).
+     BN_GF2m_add() is misnomer, but this is for the sake of consistency.)
+
+     For some functions, an the irreducible polynomial defining a
+     field can be given as an 'unsigned int[]' with strictly
+     decreasing elements giving the indices of those bits that are set;
+     i.e., p[] represents the polynomial
+          f(t) = t^p[0] + t^p[1] + ... + t^p[k]
+     where
+          p[0] > p[1] > ... > p[k] = 0.
+     This applies to the following functions:
+
+          BN_GF2m_mod_arr
+          BN_GF2m_mod_mul_arr
+          BN_GF2m_mod_sqr_arr
+          BN_GF2m_mod_inv_arr        [wrapper for BN_GF2m_mod_inv]
+          BN_GF2m_mod_div_arr        [wrapper for BN_GF2m_mod_div]
+          BN_GF2m_mod_exp_arr
+          BN_GF2m_mod_sqrt_arr
+          BN_GF2m_mod_solve_quad_arr
+          BN_GF2m_poly2arr
+          BN_GF2m_arr2poly
+
+     Conversion can be performed by the following functions:
+
+          BN_GF2m_poly2arr
+          BN_GF2m_arr2poly
+
+     bntest.c has additional tests for binary polynomial arithmetic.
+
+     Two implementations for BN_GF2m_mod_div() are available.
+     The default algorithm simply uses BN_GF2m_mod_inv() and
+     BN_GF2m_mod_mul().  The alternative algorithm is compiled in only
+     if OPENSSL_SUN_GF2M_DIV is defined (patent pending; read the
+     copyright notice in crypto/bn/bn_gf2m.c before enabling it).
+
+     [Sheueling Chang Shantz and Douglas Stebila
+     (Sun Microsystems Laboratories)]
+
+  *) Add new error code 'ERR_R_DISABLED' that can be used when some
+     functionality is disabled at compile-time.
+     [Douglas Stebila <douglas.stebila@sun.com>]
+
+  *) Change default behaviour of 'openssl asn1parse' so that more
+     information is visible when viewing, e.g., a certificate:
+
+     Modify asn1_parse2 (crypto/asn1/asn1_par.c) so that in non-'dump'
+     mode the content of non-printable OCTET STRINGs is output in a
+     style similar to INTEGERs, but with '[HEX DUMP]' prepended to
+     avoid the appearance of a printable string.
+     [Nils Larsch <nla@trustcenter.de>]
+
+  *) Add 'asn1_flag' and 'asn1_form' member to EC_GROUP with access
+     functions
+          EC_GROUP_set_asn1_flag()
+          EC_GROUP_get_asn1_flag()
+          EC_GROUP_set_point_conversion_form()
+          EC_GROUP_get_point_conversion_form()
+     These control ASN1 encoding details:
+     - Curves (i.e., groups) are encoded explicitly unless asn1_flag
+       has been set to OPENSSL_EC_NAMED_CURVE.
+     - Points are encoded in uncompressed form by default; options for
+       asn1_for are as for point2oct, namely
+          POINT_CONVERSION_COMPRESSED
+          POINT_CONVERSION_UNCOMPRESSED
+          POINT_CONVERSION_HYBRID
+
+     Also add 'seed' and 'seed_len' members to EC_GROUP with access
+     functions
+          EC_GROUP_set_seed()
+          EC_GROUP_get0_seed()
+          EC_GROUP_get_seed_len()
+     This is used only for ASN1 purposes (so far).
+     [Nils Larsch <nla@trustcenter.de>]
+
+  *) Add 'field_type' member to EC_METHOD, which holds the NID
+     of the appropriate field type OID.  The new function
+     EC_METHOD_get_field_type() returns this value.
+     [Nils Larsch <nla@trustcenter.de>]
+
+  *) Add functions 
+          EC_POINT_point2bn()
+          EC_POINT_bn2point()
+          EC_POINT_point2hex()
+          EC_POINT_hex2point()
+     providing useful interfaces to EC_POINT_point2oct() and
+     EC_POINT_oct2point().
+     [Nils Larsch <nla@trustcenter.de>]
+
+  *) Change internals of the EC library so that the functions
+          EC_GROUP_set_generator()
+          EC_GROUP_get_generator()
+          EC_GROUP_get_order()
+          EC_GROUP_get_cofactor()
+     are implemented directly in crypto/ec/ec_lib.c and not dispatched
+     to methods, which would lead to unnecessary code duplication when
+     adding different types of curves.
+     [Nils Larsch <nla@trustcenter.de> with input by Bodo Moeller]
+
+  *) Implement compute_wNAF (crypto/ec/ec_mult.c) without BIGNUM
+     arithmetic, and such that modified wNAFs are generated
+     (which avoid length expansion in many cases).
+     [Bodo Moeller]
+
+  *) Add a function EC_GROUP_check_discriminant() (defined via
+     EC_METHOD) that verifies that the curve discriminant is non-zero.
+
+     Add a function EC_GROUP_check() that makes some sanity tests
+     on a EC_GROUP, its generator and order.  This includes
+     EC_GROUP_check_discriminant().
+     [Nils Larsch <nla@trustcenter.de>]
+
+  *) Add ECDSA in new directory crypto/ecdsa/.
+
+     Add applications 'openssl ecparam' and 'openssl ecdsa'
+     (these are based on 'openssl dsaparam' and 'openssl dsa').
+
+     ECDSA support is also included in various other files across the
+     library.  Most notably,
+     - 'openssl req' now has a '-newkey ecdsa:file' option;
+     - EVP_PKCS82PKEY (crypto/evp/evp_pkey.c) now can handle ECDSA;
+     - X509_PUBKEY_get (crypto/asn1/x_pubkey.c) and
+       d2i_PublicKey (crypto/asn1/d2i_pu.c) have been modified to make
+       them suitable for ECDSA where domain parameters must be
+       extracted before the specific public key;
+     - ECDSA engine support has been added.
+     [Nils Larsch <nla@trustcenter.de>]
+
+  *) Include some named elliptic curves, and add OIDs from X9.62,
+     SECG, and WAP/WTLS.  Each curve can be obtained from the new
+     function
+          EC_GROUP_new_by_curve_name(),
+     and the list of available named curves can be obtained with
+          EC_get_builtin_curves().
+     Also add a 'curve_name' member to EC_GROUP objects, which can be
+     accessed via
+         EC_GROUP_set_curve_name()
+         EC_GROUP_get_curve_name()
+     [Nils Larsch <larsch@trustcenter.de, Bodo Moeller]
+ 
+  *) Remove a few calls to bn_wexpand() in BN_sqr() (the one in there
+     was actually never needed) and in BN_mul().  The removal in BN_mul()
+     required a small change in bn_mul_part_recursive() and the addition
+     of the functions bn_cmp_part_words(), bn_sub_part_words() and
+     bn_add_part_words(), which do the same thing as bn_cmp_words(),
+     bn_sub_words() and bn_add_words() except they take arrays with
+     differing sizes.
+     [Richard Levitte]
+
+ Changes between 0.9.7l and 0.9.7m  [23 Feb 2007]
+
+  *) Cleanse PEM buffers before freeing them since they may contain 
+     sensitive data.
+     [Benjamin Bennett <ben@psc.edu>]
+
+  *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that
+     a ciphersuite string such as "DEFAULT:RSA" cannot enable
+     authentication-only ciphersuites.
+     [Bodo Moeller]
+
+  *) Since AES128 and AES256 share a single mask bit in the logic of
+     ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a
+     kludge to work properly if AES128 is available and AES256 isn't.
+     [Victor Duchovni]
+
+  *) Expand security boundary to match 1.1.1 module.
+     [Steve Henson]
+
+  *) Remove redundant features: hash file source, editing of test vectors
+     modify fipsld to use external fips_premain.c signature.
+     [Steve Henson]
+
+  *) New perl script mkfipsscr.pl to create shell scripts or batch files to
+     run algorithm test programs.
+     [Steve Henson]
+
+  *) Make algorithm test programs more tolerant of whitespace.
+     [Steve Henson]
+
+  *) Have SSL/TLS server implementation tolerate "mismatched" record
+     protocol version while receiving ClientHello even if the
+     ClientHello is fragmented.  (The server can't insist on the
+     particular protocol version it has chosen before the ServerHello
+     message has informed the client about his choice.)
+     [Bodo Moeller]
+
+  *) Load error codes if they are not already present instead of using a
+     static variable. This allows them to be cleanly unloaded and reloaded.
+     [Steve Henson]
+
+ Changes between 0.9.7k and 0.9.7l  [28 Sep 2006]
+
+  *) Introduce limits to prevent malicious keys being able to
+     cause a denial of service.  (CVE-2006-2940)
+     [Steve Henson, Bodo Moeller]
+
+  *) Fix ASN.1 parsing of certain invalid structures that can result
+     in a denial of service.  (CVE-2006-2937)  [Steve Henson]
+
+  *) Fix buffer overflow in SSL_get_shared_ciphers() function. 
+     (CVE-2006-3738) [Tavis Ormandy and Will Drewry, Google Security Team]
+
+  *) Fix SSL client code which could crash if connecting to a
+     malicious SSLv2 server.  (CVE-2006-4343)
+     [Tavis Ormandy and Will Drewry, Google Security Team]
+
+  *) Change ciphersuite string processing so that an explicit
+     ciphersuite selects this one ciphersuite (so that "AES256-SHA"
+     will no longer include "AES128-SHA"), and any other similar
+     ciphersuite (same bitmap) from *other* protocol versions (so that
+     "RC4-MD5" will still include both the SSL 2.0 ciphersuite and the
+     SSL 3.0/TLS 1.0 ciphersuite).  This is a backport combining
+     changes from 0.9.8b and 0.9.8d.
+     [Bodo Moeller]
+
+ Changes between 0.9.7j and 0.9.7k  [05 Sep 2006]
+
+  *) Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher
+     (CVE-2006-4339)  [Ben Laurie and Google Security Team]
+
+  *) Change the Unix randomness entropy gathering to use poll() when
+     possible instead of select(), since the latter has some
+     undesirable limitations.
+     [Darryl Miles via Richard Levitte and Bodo Moeller]
+
+  *) Disable rogue ciphersuites:
+
+      - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5")
+      - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5")
+      - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5")
+
+     The latter two were purportedly from
+     draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really
+     appear there.
+
+     Also deactive the remaining ciphersuites from
+     draft-ietf-tls-56-bit-ciphersuites-01.txt.  These are just as
+     unofficial, and the ID has long expired.
+     [Bodo Moeller]
+
+  *) Fix RSA blinding Heisenbug (problems sometimes occured on
+     dual-core machines) and other potential thread-safety issues.
+     [Bodo Moeller]
+
+ Changes between 0.9.7i and 0.9.7j  [04 May 2006]
+
+  *) Adapt fipsld and the build system to link against the validated FIPS
+     module in FIPS mode.
+     [Steve Henson]
+
+  *) Fixes for VC++ 2005 build under Windows.
+     [Steve Henson]
+
+  *) Add new Windows build target VC-32-GMAKE for VC++. This uses GNU make 
+     from a Windows bash shell such as MSYS. It is autodetected from the
+     "config" script when run from a VC++ environment. Modify standard VC++
+     build to use fipscanister.o from the GNU make build. 
+     [Steve Henson]
+
+ Changes between 0.9.7h and 0.9.7i  [14 Oct 2005]
+
+  *) Wrapped the definition of EVP_MAX_MD_SIZE in a #ifdef OPENSSL_FIPS.
+     The value now differs depending on if you build for FIPS or not.
+     BEWARE!  A program linked with a shared FIPSed libcrypto can't be
+     safely run with a non-FIPSed libcrypto, as it may crash because of
+     the difference induced by this change.
+     [Andy Polyakov]
+
+ Changes between 0.9.7g and 0.9.7h  [11 Oct 2005]
+
+  *) Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING
+     (part of SSL_OP_ALL).  This option used to disable the
+     countermeasure against man-in-the-middle protocol-version
+     rollback in the SSL 2.0 server implementation, which is a bad
+     idea.  (CVE-2005-2969)
+
+     [Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center
+     for Information Security, National Institute of Advanced Industrial
+     Science and Technology [AIST], Japan)]
+
+  *) Minimal support for X9.31 signatures and PSS padding modes. This is
+     mainly for FIPS compliance and not fully integrated at this stage.
+     [Steve Henson]
+
+  *) For DSA signing, unless DSA_FLAG_NO_EXP_CONSTTIME is set, perform
+     the exponentiation using a fixed-length exponent.  (Otherwise,
+     the information leaked through timing could expose the secret key
+     after many signatures; cf. Bleichenbacher's attack on DSA with
+     biased k.)
+     [Bodo Moeller]
+
+  *) Make a new fixed-window mod_exp implementation the default for
+     RSA, DSA, and DH private-key operations so that the sequence of
+     squares and multiplies and the memory access pattern are
+     independent of the particular secret key.  This will mitigate
+     cache-timing and potential related attacks.
+
+     BN_mod_exp_mont_consttime() is the new exponentiation implementation,
+     and this is automatically used by BN_mod_exp_mont() if the new flag
+     BN_FLG_EXP_CONSTTIME is set for the exponent.  RSA, DSA, and DH
+     will use this BN flag for private exponents unless the flag
+     RSA_FLAG_NO_EXP_CONSTTIME, DSA_FLAG_NO_EXP_CONSTTIME, or
+     DH_FLAG_NO_EXP_CONSTTIME, respectively, is set.
+
+     [Matthew D Wood (Intel Corp), with some changes by Bodo Moeller]
+
+  *) Change the client implementation for SSLv23_method() and
+     SSLv23_client_method() so that is uses the SSL 3.0/TLS 1.0
+     Client Hello message format if the SSL_OP_NO_SSLv2 option is set.
+     (Previously, the SSL 2.0 backwards compatible Client Hello
+     message format would be used even with SSL_OP_NO_SSLv2.)
+     [Bodo Moeller]
+
+  *) Add support for smime-type MIME parameter in S/MIME messages which some
+     clients need.
+     [Steve Henson]
+
+  *) New function BN_MONT_CTX_set_locked() to set montgomery parameters in
+     a threadsafe manner. Modify rsa code to use new function and add calls
+     to dsa and dh code (which had race conditions before).
+     [Steve Henson]
+
+  *) Include the fixed error library code in the C error file definitions
+     instead of fixing them up at runtime. This keeps the error code
+     structures constant.
+     [Steve Henson]
+
+ Changes between 0.9.7f and 0.9.7g  [11 Apr 2005]
+
+  [NB: OpenSSL 0.9.7h and later 0.9.7 patch levels were released after
+  OpenSSL 0.9.8.]
+
+  *) Fixes for newer kerberos headers. NB: the casts are needed because
+     the 'length' field is signed on one version and unsigned on another
+     with no (?) obvious way to tell the difference, without these VC++
+     complains. Also the "definition" of FAR (blank) is no longer included
+     nor is the error ENOMEM. KRB5_PRIVATE has to be set to 1 to pick up
+     some needed definitions.
+     [Steve Henson]
+
+  *) Undo Cygwin change.
+     [Ulf Möller]
+
+  *) Added support for proxy certificates according to RFC 3820.
+     Because they may be a security thread to unaware applications,
+     they must be explicitely allowed in run-time.  See
+     docs/HOWTO/proxy_certificates.txt for further information.
+     [Richard Levitte]
+
+ Changes between 0.9.7e and 0.9.7f  [22 Mar 2005]
+
+  *) Use (SSL_RANDOM_VALUE - 4) bytes of pseudo random data when generating
+     server and client random values. Previously
+     (SSL_RANDOM_VALUE - sizeof(time_t)) would be used which would result in
+     less random data when sizeof(time_t) > 4 (some 64 bit platforms).
+
+     This change has negligible security impact because:
+
+     1. Server and client random values still have 24 bytes of pseudo random
+        data.
+
+     2. Server and client random values are sent in the clear in the initial
+        handshake.
+
+     3. The master secret is derived using the premaster secret (48 bytes in
+        size for static RSA ciphersuites) as well as client server and random
+        values.
+
+     The OpenSSL team would like to thank the UK NISCC for bringing this issue
+     to our attention. 
+
+     [Stephen Henson, reported by UK NISCC]
+
+  *) Use Windows randomness collection on Cygwin.
+     [Ulf Möller]
+
+  *) Fix hang in EGD/PRNGD query when communication socket is closed
+     prematurely by EGD/PRNGD.
+     [Darren Tucker <dtucker@zip.com.au> via Lutz Jänicke, resolves #1014]
+
+  *) Prompt for pass phrases when appropriate for PKCS12 input format.
+     [Steve Henson]
+
+  *) Back-port of selected performance improvements from development
+     branch, as well as improved support for PowerPC platforms.
+     [Andy Polyakov]
+
+  *) Add lots of checks for memory allocation failure, error codes to indicate
+     failure and freeing up memory if a failure occurs.
+     [Nauticus Networks SSL Team <openssl@nauticusnet.com>, Steve Henson]
+
+  *) Add new -passin argument to dgst.
+     [Steve Henson]
+
+  *) Perform some character comparisons of different types in X509_NAME_cmp:
+     this is needed for some certificates that reencode DNs into UTF8Strings
+     (in violation of RFC3280) and can't or wont issue name rollover
+     certificates.
+     [Steve Henson]
+
+  *) Make an explicit check during certificate validation to see that
+     the CA setting in each certificate on the chain is correct.  As a
+     side effect always do the following basic checks on extensions,
+     not just when there's an associated purpose to the check:
+
+      - if there is an unhandled critical extension (unless the user
+        has chosen to ignore this fault)
+      - if the path length has been exceeded (if one is set at all)
+      - that certain extensions fit the associated purpose (if one has
+        been given)
+     [Richard Levitte]
+
+ Changes between 0.9.7d and 0.9.7e  [25 Oct 2004]
+
+  *) Avoid a race condition when CRLs are checked in a multi threaded 
+     environment. This would happen due to the reordering of the revoked
+     entries during signature checking and serial number lookup. Now the
+     encoding is cached and the serial number sort performed under a lock.
+     Add new STACK function sk_is_sorted().
+     [Steve Henson]
+
+  *) Add Delta CRL to the extension code.
+     [Steve Henson]
+
+  *) Various fixes to s3_pkt.c so alerts are sent properly.
+     [David Holmes <d.holmes@f5.com>]
+
+  *) Reduce the chances of duplicate issuer name and serial numbers (in
+     violation of RFC3280) using the OpenSSL certificate creation utilities.
+     This is done by creating a random 64 bit value for the initial serial
+     number when a serial number file is created or when a self signed
+     certificate is created using 'openssl req -x509'. The initial serial
+     number file is created using 'openssl x509 -next_serial' in CA.pl
+     rather than being initialized to 1.
+     [Steve Henson]
+
+ Changes between 0.9.7c and 0.9.7d  [17 Mar 2004]
+
+  *) Fix null-pointer assignment in do_change_cipher_spec() revealed           
+     by using the Codenomicon TLS Test Tool (CVE-2004-0079)                    
+     [Joe Orton, Steve Henson]   
+
+  *) Fix flaw in SSL/TLS handshaking when using Kerberos ciphersuites
+     (CVE-2004-0112)
+     [Joe Orton, Steve Henson]   
+
+  *) Make it possible to have multiple active certificates with the same
+     subject in the CA index file.  This is done only if the keyword
+     'unique_subject' is set to 'no' in the main CA section (default
+     if 'CA_default') of the configuration file.  The value is saved
+     with the database itself in a separate index attribute file,
+     named like the index file with '.attr' appended to the name.
+     [Richard Levitte]
+
+  *) X509 verify fixes. Disable broken certificate workarounds when 
+     X509_V_FLAGS_X509_STRICT is set. Check CRL issuer has cRLSign set if
+     keyUsage extension present. Don't accept CRLs with unhandled critical
+     extensions: since verify currently doesn't process CRL extensions this
+     rejects a CRL with *any* critical extensions. Add new verify error codes
+     for these cases.
+     [Steve Henson]
+
+  *) When creating an OCSP nonce use an OCTET STRING inside the extnValue.
+     A clarification of RFC2560 will require the use of OCTET STRINGs and 
+     some implementations cannot handle the current raw format. Since OpenSSL
+     copies and compares OCSP nonces as opaque blobs without any attempt at
+     parsing them this should not create any compatibility issues.
+     [Steve Henson]
+
+  *) New md flag EVP_MD_CTX_FLAG_REUSE this allows md_data to be reused when
+     calling EVP_MD_CTX_copy_ex() to avoid calling OPENSSL_malloc(). Without
+     this HMAC (and other) operations are several times slower than OpenSSL
+     < 0.9.7.
+     [Steve Henson]
+
+  *) Print out GeneralizedTime and UTCTime in ASN1_STRING_print_ex().
+     [Peter Sylvester <Peter.Sylvester@EdelWeb.fr>]
+
+  *) Use the correct content when signing type "other".
+     [Steve Henson]
+
+ Changes between 0.9.7b and 0.9.7c  [30 Sep 2003]
+
+  *) Fix various bugs revealed by running the NISCC test suite:
+
+     Stop out of bounds reads in the ASN1 code when presented with
+     invalid tags (CVE-2003-0543 and CVE-2003-0544).
+     
+     Free up ASN1_TYPE correctly if ANY type is invalid (CVE-2003-0545).
+
+     If verify callback ignores invalid public key errors don't try to check
+     certificate signature with the NULL public key.
+
+     [Steve Henson]
+
+  *) New -ignore_err option in ocsp application to stop the server
+     exiting on the first error in a request.
+     [Steve Henson]
+
+  *) In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate
+     if the server requested one: as stated in TLS 1.0 and SSL 3.0
+     specifications.
+     [Steve Henson]
+
+  *) In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional
+     extra data after the compression methods not only for TLS 1.0
+     but also for SSL 3.0 (as required by the specification).
+     [Bodo Moeller; problem pointed out by Matthias Loepfe]
+
+  *) Change X509_certificate_type() to mark the key as exported/exportable
+     when it's 512 *bits* long, not 512 bytes.
+     [Richard Levitte]
+
+  *) Change AES_cbc_encrypt() so it outputs exact multiple of
+     blocks during encryption.
+     [Richard Levitte]
+
+  *) Various fixes to base64 BIO and non blocking I/O. On write 
+     flushes were not handled properly if the BIO retried. On read
+     data was not being buffered properly and had various logic bugs.
+     This also affects blocking I/O when the data being decoded is a
+     certain size.
+     [Steve Henson]
+
+  *) Various S/MIME bugfixes and compatibility changes:
+     output correct application/pkcs7 MIME type if
+     PKCS7_NOOLDMIMETYPE is set. Tolerate some broken signatures.
+     Output CR+LF for EOL if PKCS7_CRLFEOL is set (this makes opening
+     of files as .eml work). Correctly handle very long lines in MIME
+     parser.
+     [Steve Henson]
+
+ Changes between 0.9.7a and 0.9.7b  [10 Apr 2003]
+
+  *) Countermeasure against the Klima-Pokorny-Rosa extension of
+     Bleichbacher's attack on PKCS #1 v1.5 padding: treat
+     a protocol version number mismatch like a decryption error
+     in ssl3_get_client_key_exchange (ssl/s3_srvr.c).
+     [Bodo Moeller]
+
+  *) Turn on RSA blinding by default in the default implementation
+     to avoid a timing attack. Applications that don't want it can call
+     RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING.
+     They would be ill-advised to do so in most cases.
+     [Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller]
+
+  *) Change RSA blinding code so that it works when the PRNG is not
+     seeded (in this case, the secret RSA exponent is abused as
+     an unpredictable seed -- if it is not unpredictable, there
+     is no point in blinding anyway).  Make RSA blinding thread-safe
+     by remembering the creator's thread ID in rsa->blinding and
+     having all other threads use local one-time blinding factors
+     (this requires more computation than sharing rsa->blinding, but
+     avoids excessive locking; and if an RSA object is not shared
+     between threads, blinding will still be very fast).
+     [Bodo Moeller]
+
+  *) Fixed a typo bug that would cause ENGINE_set_default() to set an
+     ENGINE as defaults for all supported algorithms irrespective of
+     the 'flags' parameter. 'flags' is now honoured, so applications
+     should make sure they are passing it correctly.
+     [Geoff Thorpe]
+
+  *) Target "mingw" now allows native Windows code to be generated in
+     the Cygwin environment as well as with the MinGW compiler.
+     [Ulf Moeller] 
+
+ Changes between 0.9.7 and 0.9.7a  [19 Feb 2003]
+
+  *) In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked
+     via timing by performing a MAC computation even if incorrrect
+     block cipher padding has been found.  This is a countermeasure
+     against active attacks where the attacker has to distinguish
+     between bad padding and a MAC verification error. (CVE-2003-0078)
+
+     [Bodo Moeller; problem pointed out by Brice Canvel (EPFL),
+     Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and
+     Martin Vuagnoux (EPFL, Ilion)]
+
+  *) Make the no-err option work as intended.  The intention with no-err
+     is not to have the whole error stack handling routines removed from
+     libcrypto, it's only intended to remove all the function name and
+     reason texts, thereby removing some of the footprint that may not
+     be interesting if those errors aren't displayed anyway.
+
+     NOTE: it's still possible for any application or module to have it's
+     own set of error texts inserted.  The routines are there, just not
+     used by default when no-err is given.
+     [Richard Levitte]
+
+  *) Add support for FreeBSD on IA64.
+     [dirk.meyer@dinoex.sub.org via Richard Levitte, resolves #454]
+
+  *) Adjust DES_cbc_cksum() so it returns the same value as the MIT
+     Kerberos function mit_des_cbc_cksum().  Before this change,
+     the value returned by DES_cbc_cksum() was like the one from
+     mit_des_cbc_cksum(), except the bytes were swapped.
+     [Kevin Greaney <Kevin.Greaney@hp.com> and Richard Levitte]
+
+  *) Allow an application to disable the automatic SSL chain building.
+     Before this a rather primitive chain build was always performed in
+     ssl3_output_cert_chain(): an application had no way to send the 
+     correct chain if the automatic operation produced an incorrect result.
+
+     Now the chain builder is disabled if either:
+
+     1. Extra certificates are added via SSL_CTX_add_extra_chain_cert().
+
+     2. The mode flag SSL_MODE_NO_AUTO_CHAIN is set.
+
+     The reasoning behind this is that an application would not want the
+     auto chain building to take place if extra chain certificates are
+     present and it might also want a means of sending no additional
+     certificates (for example the chain has two certificates and the
+     root is omitted).
+     [Steve Henson]
+
+  *) Add the possibility to build without the ENGINE framework.
+     [Steven Reddie <smr@essemer.com.au> via Richard Levitte]
+
+  *) Under Win32 gmtime() can return NULL: check return value in
+     OPENSSL_gmtime(). Add error code for case where gmtime() fails.
+     [Steve Henson]
+
+  *) DSA routines: under certain error conditions uninitialized BN objects
+     could be freed. Solution: make sure initialization is performed early
+     enough. (Reported and fix supplied by Ivan D Nestlerode <nestler@MIT.EDU>,
+     Nils Larsch <nla@trustcenter.de> via PR#459)
+     [Lutz Jaenicke]
+
+  *) Another fix for SSLv2 session ID handling: the session ID was incorrectly
+     checked on reconnect on the client side, therefore session resumption
+     could still fail with a "ssl session id is different" error. This
+     behaviour is masked when SSL_OP_ALL is used due to
+     SSL_OP_MICROSOFT_SESS_ID_BUG being set.
+     Behaviour observed by Crispin Flowerday <crispin@flowerday.cx> as
+     followup to PR #377.
+     [Lutz Jaenicke]
+
+  *) IA-32 assembler support enhancements: unified ELF targets, support
+     for SCO/Caldera platforms, fix for Cygwin shared build.
+     [Andy Polyakov]
+
+  *) Add support for FreeBSD on sparc64.  As a consequence, support for
+     FreeBSD on non-x86 processors is separate from x86 processors on
+     the config script, much like the NetBSD support.
+     [Richard Levitte & Kris Kennaway <kris@obsecurity.org>]
+
+ Changes between 0.9.6h and 0.9.7  [31 Dec 2002]
+
+  [NB: OpenSSL 0.9.6i and later 0.9.6 patch levels were released after
+  OpenSSL 0.9.7.]
+
+  *) Fix session ID handling in SSLv2 client code: the SERVER FINISHED
+     code (06) was taken as the first octet of the session ID and the last
+     octet was ignored consequently. As a result SSLv2 client side session
+     caching could not have worked due to the session ID mismatch between
+     client and server.
+     Behaviour observed by Crispin Flowerday <crispin@flowerday.cx> as
+     PR #377.
+     [Lutz Jaenicke]
+
+  *) Change the declaration of needed Kerberos libraries to use EX_LIBS
+     instead of the special (and badly supported) LIBKRB5.  LIBKRB5 is
+     removed entirely.
+     [Richard Levitte]
+
+  *) The hw_ncipher.c engine requires dynamic locks.  Unfortunately, it
+     seems that in spite of existing for more than a year, many application
+     author have done nothing to provide the necessary callbacks, which
+     means that this particular engine will not work properly anywhere.
+     This is a very unfortunate situation which forces us, in the name
+     of usability, to give the hw_ncipher.c a static lock, which is part
+     of libcrypto.
+     NOTE: This is for the 0.9.7 series ONLY.  This hack will never
+     appear in 0.9.8 or later.  We EXPECT application authors to have
+     dealt properly with this when 0.9.8 is released (unless we actually
+     make such changes in the libcrypto locking code that changes will
+     have to be made anyway).
+     [Richard Levitte]
+
+  *) In asn1_d2i_read_bio() repeatedly call BIO_read() until all content
+     octets have been read, EOF or an error occurs. Without this change
+     some truncated ASN1 structures will not produce an error.
+     [Steve Henson]
+
+  *) Disable Heimdal support, since it hasn't been fully implemented.
+     Still give the possibility to force the use of Heimdal, but with
+     warnings and a request that patches get sent to openssl-dev.
+     [Richard Levitte]
+
+  *) Add the VC-CE target, introduce the WINCE sysname, and add
+     INSTALL.WCE and appropriate conditionals to make it build.
+     [Steven Reddie <smr@essemer.com.au> via Richard Levitte]
+
+  *) Change the DLL names for Cygwin to cygcrypto-x.y.z.dll and
+     cygssl-x.y.z.dll, where x, y and z are the major, minor and
+     edit numbers of the version.
+     [Corinna Vinschen <vinschen@redhat.com> and Richard Levitte]
+
+  *) Introduce safe string copy and catenation functions
+     (BUF_strlcpy() and BUF_strlcat()).
+     [Ben Laurie (CHATS) and Richard Levitte]
+
+  *) Avoid using fixed-size buffers for one-line DNs.
+     [Ben Laurie (CHATS)]
+
+  *) Add BUF_MEM_grow_clean() to avoid information leakage when
+     resizing buffers containing secrets, and use where appropriate.
+     [Ben Laurie (CHATS)]
+
+  *) Avoid using fixed size buffers for configuration file location.
+     [Ben Laurie (CHATS)]
+
+  *) Avoid filename truncation for various CA files.
+     [Ben Laurie (CHATS)]
+
+  *) Use sizeof in preference to magic numbers.
+     [Ben Laurie (CHATS)]
+
+  *) Avoid filename truncation in cert requests.
+     [Ben Laurie (CHATS)]
+
+  *) Add assertions to check for (supposedly impossible) buffer
+     overflows.
+     [Ben Laurie (CHATS)]
+
+  *) Don't cache truncated DNS entries in the local cache (this could
+     potentially lead to a spoofing attack).
+     [Ben Laurie (CHATS)]
+
+  *) Fix various buffers to be large enough for hex/decimal
+     representations in a platform independent manner.
+     [Ben Laurie (CHATS)]
+
+  *) Add CRYPTO_realloc_clean() to avoid information leakage when
+     resizing buffers containing secrets, and use where appropriate.
+     [Ben Laurie (CHATS)]
+
+  *) Add BIO_indent() to avoid much slightly worrying code to do
+     indents.
+     [Ben Laurie (CHATS)]
+
+  *) Convert sprintf()/BIO_puts() to BIO_printf().
+     [Ben Laurie (CHATS)]
+
+  *) buffer_gets() could terminate with the buffer only half
+     full. Fixed.
+     [Ben Laurie (CHATS)]
+
+  *) Add assertions to prevent user-supplied crypto functions from
+     overflowing internal buffers by having large block sizes, etc.
+     [Ben Laurie (CHATS)]
+
+  *) New OPENSSL_assert() macro (similar to assert(), but enabled
+     unconditionally).
+     [Ben Laurie (CHATS)]
+
+  *) Eliminate unused copy of key in RC4.
+     [Ben Laurie (CHATS)]
+
+  *) Eliminate unused and incorrectly sized buffers for IV in pem.h.
+     [Ben Laurie (CHATS)]
+
+  *) Fix off-by-one error in EGD path.
+     [Ben Laurie (CHATS)]
+
+  *) If RANDFILE path is too long, ignore instead of truncating.
+     [Ben Laurie (CHATS)]
+
+  *) Eliminate unused and incorrectly sized X.509 structure
+     CBCParameter.
+     [Ben Laurie (CHATS)]
+
+  *) Eliminate unused and dangerous function knumber().
+     [Ben Laurie (CHATS)]
+
+  *) Eliminate unused and dangerous structure, KSSL_ERR.
+     [Ben Laurie (CHATS)]
+
+  *) Protect against overlong session ID context length in an encoded
+     session object. Since these are local, this does not appear to be
+     exploitable.
+     [Ben Laurie (CHATS)]
+
+  *) Change from security patch (see 0.9.6e below) that did not affect
+     the 0.9.6 release series:
+
+     Remote buffer overflow in SSL3 protocol - an attacker could
+     supply an oversized master key in Kerberos-enabled versions.
+     (CVE-2002-0657)
+     [Ben Laurie (CHATS)]
+
+  *) Change the SSL kerb5 codes to match RFC 2712.
+     [Richard Levitte]
+
+  *) Make -nameopt work fully for req and add -reqopt switch.
+     [Michael Bell <michael.bell@rz.hu-berlin.de>, Steve Henson]
+
+  *) The "block size" for block ciphers in CFB and OFB mode should be 1.
+     [Steve Henson, reported by Yngve Nysaeter Pettersen <yngve@opera.com>]
+
+  *) Make sure tests can be performed even if the corresponding algorithms
+     have been removed entirely.  This was also the last step to make
+     OpenSSL compilable with DJGPP under all reasonable conditions.
+     [Richard Levitte, Doug Kaufman <dkaufman@rahul.net>]
+
+  *) Add cipher selection rules COMPLEMENTOFALL and COMPLEMENTOFDEFAULT
+     to allow version independent disabling of normally unselected ciphers,
+     which may be activated as a side-effect of selecting a single cipher.
+
+     (E.g., cipher list string "RSA" enables ciphersuites that are left
+     out of "ALL" because they do not provide symmetric encryption.
+     "RSA:!COMPLEMEMENTOFALL" avoids these unsafe ciphersuites.)
+     [Lutz Jaenicke, Bodo Moeller]
+
+  *) Add appropriate support for separate platform-dependent build
+     directories.  The recommended way to make a platform-dependent
+     build directory is the following (tested on Linux), maybe with
+     some local tweaks:
+
+	# Place yourself outside of the OpenSSL source tree.  In
+	# this example, the environment variable OPENSSL_SOURCE
+	# is assumed to contain the absolute OpenSSL source directory.
+	mkdir -p objtree/"`uname -s`-`uname -r`-`uname -m`"
+	cd objtree/"`uname -s`-`uname -r`-`uname -m`"
+	(cd $OPENSSL_SOURCE; find . -type f) | while read F; do
+		mkdir -p `dirname $F`
+		ln -s $OPENSSL_SOURCE/$F $F
+	done
+
+     To be absolutely sure not to disturb the source tree, a "make clean"
+     is a good thing.  If it isn't successfull, don't worry about it,
+     it probably means the source directory is very clean.
+     [Richard Levitte]
+
+  *) Make sure any ENGINE control commands make local copies of string
+     pointers passed to them whenever necessary. Otherwise it is possible
+     the caller may have overwritten (or deallocated) the original string
+     data when a later ENGINE operation tries to use the stored values.
+     [Götz Babin-Ebell <babinebell@trustcenter.de>]
+
+  *) Improve diagnostics in file reading and command-line digests.
+     [Ben Laurie aided and abetted by Solar Designer <solar@openwall.com>]
+
+  *) Add AES modes CFB and OFB to the object database.  Correct an
+     error in AES-CFB decryption.
+     [Richard Levitte]
+
+  *) Remove most calls to EVP_CIPHER_CTX_cleanup() in evp_enc.c, this 
+     allows existing EVP_CIPHER_CTX structures to be reused after
+     calling EVP_*Final(). This behaviour is used by encryption
+     BIOs and some applications. This has the side effect that
+     applications must explicitly clean up cipher contexts with
+     EVP_CIPHER_CTX_cleanup() or they will leak memory.
+     [Steve Henson]
+
+  *) Check the values of dna and dnb in bn_mul_recursive before calling
+     bn_mul_comba (a non zero value means the a or b arrays do not contain
+     n2 elements) and fallback to bn_mul_normal if either is not zero.
+     [Steve Henson]
+
+  *) Fix escaping of non-ASCII characters when using the -subj option
+     of the "openssl req" command line tool. (Robert Joop <joop@fokus.gmd.de>)
+     [Lutz Jaenicke]
+
+  *) Make object definitions compliant to LDAP (RFC2256): SN is the short
+     form for "surname", serialNumber has no short form.
+     Use "mail" as the short name for "rfc822Mailbox" according to RFC2798;
+     therefore remove "mail" short name for "internet 7".
+     The OID for unique identifiers in X509 certificates is
+     x500UniqueIdentifier, not uniqueIdentifier.
+     Some more OID additions. (Michael Bell <michael.bell@rz.hu-berlin.de>)
+     [Lutz Jaenicke]
+
+  *) Add an "init" command to the ENGINE config module and auto initialize
+     ENGINEs. Without any "init" command the ENGINE will be initialized 
+     after all ctrl commands have been executed on it. If init=1 the 
+     ENGINE is initailized at that point (ctrls before that point are run
+     on the uninitialized ENGINE and after on the initialized one). If
+     init=0 then the ENGINE will not be iniatialized at all.
+     [Steve Henson]
+
+  *) Fix the 'app_verify_callback' interface so that the user-defined
+     argument is actually passed to the callback: In the
+     SSL_CTX_set_cert_verify_callback() prototype, the callback
+     declaration has been changed from
+          int (*cb)()
+     into
+          int (*cb)(X509_STORE_CTX *,void *);
+     in ssl_verify_cert_chain (ssl/ssl_cert.c), the call
+          i=s->ctx->app_verify_callback(&ctx)
+     has been changed into
+          i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg).
+
+     To update applications using SSL_CTX_set_cert_verify_callback(),
+     a dummy argument can be added to their callback functions.
+     [D. K. Smetters <smetters@parc.xerox.com>]
+
+  *) Added the '4758cca' ENGINE to support IBM 4758 cards.
+     [Maurice Gittens <maurice@gittens.nl>, touchups by Geoff Thorpe]
+
+  *) Add and OPENSSL_LOAD_CONF define which will cause
+     OpenSSL_add_all_algorithms() to load the openssl.cnf config file.
+     This allows older applications to transparently support certain
+     OpenSSL features: such as crypto acceleration and dynamic ENGINE loading.
+     Two new functions OPENSSL_add_all_algorithms_noconf() which will never
+     load the config file and OPENSSL_add_all_algorithms_conf() which will
+     always load it have also been added.
+     [Steve Henson]
+
+  *) Add the OFB, CFB and CTR (all with 128 bit feedback) to AES.
+     Adjust NIDs and EVP layer.
+     [Stephen Sprunk <stephen@sprunk.org> and Richard Levitte]
+
+  *) Config modules support in openssl utility.
+
+     Most commands now load modules from the config file,
+     though in a few (such as version) this isn't done 
+     because it couldn't be used for anything.
+
+     In the case of ca and req the config file used is
+     the same as the utility itself: that is the -config
+     command line option can be used to specify an
+     alternative file.
+     [Steve Henson]
+
+  *) Move default behaviour from OPENSSL_config(). If appname is NULL
+     use "openssl_conf" if filename is NULL use default openssl config file.
+     [Steve Henson]
+
+  *) Add an argument to OPENSSL_config() to allow the use of an alternative
+     config section name. Add a new flag to tolerate a missing config file
+     and move code to CONF_modules_load_file().
+     [Steve Henson]
+
+  *) Support for crypto accelerator cards from Accelerated Encryption
+     Processing, www.aep.ie.  (Use engine 'aep')
+     The support was copied from 0.9.6c [engine] and adapted/corrected
+     to work with the new engine framework.
+     [AEP Inc. and Richard Levitte]
+
+  *) Support for SureWare crypto accelerator cards from Baltimore
+     Technologies.  (Use engine 'sureware')
+     The support was copied from 0.9.6c [engine] and adapted
+     to work with the new engine framework.
+     [Richard Levitte]
+
+  *) Have the CHIL engine fork-safe (as defined by nCipher) and actually
+     make the newer ENGINE framework commands for the CHIL engine work.
+     [Toomas Kiisk <vix@cyber.ee> and Richard Levitte]
+
+  *) Make it possible to produce shared libraries on ReliantUNIX.
+     [Robert Dahlem <Robert.Dahlem@ffm2.siemens.de> via Richard Levitte]
+
+  *) Add the configuration target debug-linux-ppro.
+     Make 'openssl rsa' use the general key loading routines
+     implemented in apps.c, and make those routines able to
+     handle the key format FORMAT_NETSCAPE and the variant
+     FORMAT_IISSGC.
+     [Toomas Kiisk <vix@cyber.ee> via Richard Levitte]
+
+ *) Fix a crashbug and a logic bug in hwcrhk_load_pubkey().
+     [Toomas Kiisk <vix@cyber.ee> via Richard Levitte]
+
+  *) Add -keyform to rsautl, and document -engine.
+     [Richard Levitte, inspired by Toomas Kiisk <vix@cyber.ee>]
+
+  *) Change BIO_new_file (crypto/bio/bss_file.c) to use new
+     BIO_R_NO_SUCH_FILE error code rather than the generic
+     ERR_R_SYS_LIB error code if fopen() fails with ENOENT.
+     [Ben Laurie]
+
+  *) Add new functions
+          ERR_peek_last_error
+          ERR_peek_last_error_line
+          ERR_peek_last_error_line_data.
+     These are similar to
+          ERR_peek_error
+          ERR_peek_error_line
+          ERR_peek_error_line_data,
+     but report on the latest error recorded rather than the first one
+     still in the error queue.
+     [Ben Laurie, Bodo Moeller]
+        
+  *) default_algorithms option in ENGINE config module. This allows things
+     like:
+     default_algorithms = ALL
+     default_algorithms = RSA, DSA, RAND, CIPHERS, DIGESTS
+     [Steve Henson]
+
+  *) Prelminary ENGINE config module.
+     [Steve Henson]
+
+  *) New experimental application configuration code.
+     [Steve Henson]
+
+  *) Change the AES code to follow the same name structure as all other
+     symmetric ciphers, and behave the same way.  Move everything to
+     the directory crypto/aes, thereby obsoleting crypto/rijndael.
+     [Stephen Sprunk <stephen@sprunk.org> and Richard Levitte]
+
+  *) SECURITY: remove unsafe setjmp/signal interaction from ui_openssl.c.
+     [Ben Laurie and Theo de Raadt]
+
+  *) Add option to output public keys in req command.
+     [Massimiliano Pala madwolf@openca.org]
+
+  *) Use wNAFs in EC_POINTs_mul() for improved efficiency
+     (up to about 10% better than before for P-192 and P-224).
+     [Bodo Moeller]
+
+  *) New functions/macros
+
+          SSL_CTX_set_msg_callback(ctx, cb)
+          SSL_CTX_set_msg_callback_arg(ctx, arg)
+          SSL_set_msg_callback(ssl, cb)
+          SSL_set_msg_callback_arg(ssl, arg)
+
+     to request calling a callback function
+
+          void cb(int write_p, int version, int content_type,
+                  const void *buf, size_t len, SSL *ssl, void *arg)
+
+     whenever a protocol message has been completely received
+     (write_p == 0) or sent (write_p == 1).  Here 'version' is the
+     protocol version  according to which the SSL library interprets
+     the current protocol message (SSL2_VERSION, SSL3_VERSION, or
+     TLS1_VERSION).  'content_type' is 0 in the case of SSL 2.0, or
+     the content type as defined in the SSL 3.0/TLS 1.0 protocol
+     specification (change_cipher_spec(20), alert(21), handshake(22)).
+     'buf' and 'len' point to the actual message, 'ssl' to the
+     SSL object, and 'arg' is the application-defined value set by
+     SSL[_CTX]_set_msg_callback_arg().
+
+     'openssl s_client' and 'openssl s_server' have new '-msg' options
+     to enable a callback that displays all protocol messages.
+     [Bodo Moeller]
+
+  *) Change the shared library support so shared libraries are built as
+     soon as the corresponding static library is finished, and thereby get
+     openssl and the test programs linked against the shared library.
+     This still only happens when the keyword "shard" has been given to
+     the configuration scripts.
+
+     NOTE: shared library support is still an experimental thing, and
+     backward binary compatibility is still not guaranteed.
+     ["Maciej W. Rozycki" <macro@ds2.pg.gda.pl> and Richard Levitte]
+
+  *) Add support for Subject Information Access extension.
+     [Peter Sylvester <Peter.Sylvester@EdelWeb.fr>]
+
+  *) Make BUF_MEM_grow() behaviour more consistent: Initialise to zero
+     additional bytes when new memory had to be allocated, not just
+     when reusing an existing buffer.
+     [Bodo Moeller]
+
+  *) New command line and configuration option 'utf8' for the req command.
+     This allows field values to be specified as UTF8 strings.
+     [Steve Henson]
+
+  *) Add -multi and -mr options to "openssl speed" - giving multiple parallel
+     runs for the former and machine-readable output for the latter.
+     [Ben Laurie]
+
+  *) Add '-noemailDN' option to 'openssl ca'.  This prevents inclusion
+     of the e-mail address in the DN (i.e., it will go into a certificate
+     extension only).  The new configuration file option 'email_in_dn = no'
+     has the same effect.
+     [Massimiliano Pala madwolf@openca.org]
+
+  *) Change all functions with names starting with des_ to be starting
+     with DES_ instead.  Add wrappers that are compatible with libdes,
+     but are named _ossl_old_des_*.  Finally, add macros that map the
+     des_* symbols to the corresponding _ossl_old_des_* if libdes
+     compatibility is desired.  If OpenSSL 0.9.6c compatibility is
+     desired, the des_* symbols will be mapped to DES_*, with one
+     exception.
+
+     Since we provide two compatibility mappings, the user needs to
+     define the macro OPENSSL_DES_LIBDES_COMPATIBILITY if libdes
+     compatibility is desired.  The default (i.e., when that macro
+     isn't defined) is OpenSSL 0.9.6c compatibility.
+
+     There are also macros that enable and disable the support of old
+     des functions altogether.  Those are OPENSSL_ENABLE_OLD_DES_SUPPORT
+     and OPENSSL_DISABLE_OLD_DES_SUPPORT.  If none or both of those
+     are defined, the default will apply: to support the old des routines.
+
+     In either case, one must include openssl/des.h to get the correct
+     definitions.  Do not try to just include openssl/des_old.h, that
+     won't work.
+
+     NOTE: This is a major break of an old API into a new one.  Software
+     authors are encouraged to switch to the DES_ style functions.  Some
+     time in the future, des_old.h and the libdes compatibility functions
+     will be disable (i.e. OPENSSL_DISABLE_OLD_DES_SUPPORT will be the
+     default), and then completely removed.
+     [Richard Levitte]
+
+  *) Test for certificates which contain unsupported critical extensions.
+     If such a certificate is found during a verify operation it is 
+     rejected by default: this behaviour can be overridden by either
+     handling the new error X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION or
+     by setting the verify flag X509_V_FLAG_IGNORE_CRITICAL. A new function
+     X509_supported_extension() has also been added which returns 1 if a
+     particular extension is supported.
+     [Steve Henson]
+
+  *) Modify the behaviour of EVP cipher functions in similar way to digests
+     to retain compatibility with existing code.
+     [Steve Henson]
+
+  *) Modify the behaviour of EVP_DigestInit() and EVP_DigestFinal() to retain
+     compatibility with existing code. In particular the 'ctx' parameter does
+     not have to be to be initialized before the call to EVP_DigestInit() and
+     it is tidied up after a call to EVP_DigestFinal(). New function
+     EVP_DigestFinal_ex() which does not tidy up the ctx. Similarly function
+     EVP_MD_CTX_copy() changed to not require the destination to be
+     initialized valid and new function EVP_MD_CTX_copy_ex() added which
+     requires the destination to be valid.
+
+     Modify all the OpenSSL digest calls to use EVP_DigestInit_ex(),
+     EVP_DigestFinal_ex() and EVP_MD_CTX_copy_ex().
+     [Steve Henson]
+
+  *) Change ssl3_get_message (ssl/s3_both.c) and the functions using it
+     so that complete 'Handshake' protocol structures are kept in memory
+     instead of overwriting 'msg_type' and 'length' with 'body' data.
+     [Bodo Moeller]
+
+  *) Add an implementation of SSL_add_dir_cert_subjects_to_stack for Win32.
+     [Massimo Santin via Richard Levitte]
+
+  *) Major restructuring to the underlying ENGINE code. This includes
+     reduction of linker bloat, separation of pure "ENGINE" manipulation
+     (initialisation, etc) from functionality dealing with implementations
+     of specific crypto iterfaces. This change also introduces integrated
+     support for symmetric ciphers and digest implementations - so ENGINEs
+     can now accelerate these by providing EVP_CIPHER and EVP_MD
+     implementations of their own. This is detailed in crypto/engine/README
+     as it couldn't be adequately described here. However, there are a few
+     API changes worth noting - some RSA, DSA, DH, and RAND functions that
+     were changed in the original introduction of ENGINE code have now
+     reverted back - the hooking from this code to ENGINE is now a good
+     deal more passive and at run-time, operations deal directly with
+     RSA_METHODs, DSA_METHODs (etc) as they did before, rather than
+     dereferencing through an ENGINE pointer any more. Also, the ENGINE
+     functions dealing with BN_MOD_EXP[_CRT] handlers have been removed -
+     they were not being used by the framework as there is no concept of a
+     BIGNUM_METHOD and they could not be generalised to the new
+     'ENGINE_TABLE' mechanism that underlies the new code. Similarly,
+     ENGINE_cpy() has been removed as it cannot be consistently defined in
+     the new code.
+     [Geoff Thorpe]
+
+  *) Change ASN1_GENERALIZEDTIME_check() to allow fractional seconds.
+     [Steve Henson]
+
+  *) Change mkdef.pl to sort symbols that get the same entry number,
+     and make sure the automatically generated functions ERR_load_*
+     become part of libeay.num as well.
+     [Richard Levitte]
+
+  *) New function SSL_renegotiate_pending().  This returns true once
+     renegotiation has been requested (either SSL_renegotiate() call
+     or HelloRequest/ClientHello receveived from the peer) and becomes
+     false once a handshake has been completed.
+     (For servers, SSL_renegotiate() followed by SSL_do_handshake()
+     sends a HelloRequest, but does not ensure that a handshake takes
+     place.  SSL_renegotiate_pending() is useful for checking if the
+     client has followed the request.)
+     [Bodo Moeller]
+
+  *) New SSL option SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION.
+     By default, clients may request session resumption even during
+     renegotiation (if session ID contexts permit); with this option,
+     session resumption is possible only in the first handshake.
+
+     SSL_OP_ALL is now 0x00000FFFL instead of 0x000FFFFFL.  This makes
+     more bits available for options that should not be part of
+     SSL_OP_ALL (such as SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION).
+     [Bodo Moeller]
+
+  *) Add some demos for certificate and certificate request creation.
+     [Steve Henson]
+
+  *) Make maximum certificate chain size accepted from the peer application
+     settable (SSL*_get/set_max_cert_list()), as proposed by
+     "Douglas E. Engert" <deengert@anl.gov>.
+     [Lutz Jaenicke]
+
+  *) Add support for shared libraries for Unixware-7
+     (Boyd Lynn Gerber <gerberb@zenez.com>).
+     [Lutz Jaenicke]
+
+  *) Add a "destroy" handler to ENGINEs that allows structural cleanup to
+     be done prior to destruction. Use this to unload error strings from
+     ENGINEs that load their own error strings. NB: This adds two new API
+     functions to "get" and "set" this destroy handler in an ENGINE.
+     [Geoff Thorpe]
+
+  *) Alter all existing ENGINE implementations (except "openssl" and
+     "openbsd") to dynamically instantiate their own error strings. This
+     makes them more flexible to be built both as statically-linked ENGINEs
+     and self-contained shared-libraries loadable via the "dynamic" ENGINE.
+     Also, add stub code to each that makes building them as self-contained
+     shared-libraries easier (see README.ENGINE).
+     [Geoff Thorpe]
+
+  *) Add a "dynamic" ENGINE that provides a mechanism for binding ENGINE
+     implementations into applications that are completely implemented in
+     self-contained shared-libraries. The "dynamic" ENGINE exposes control
+     commands that can be used to configure what shared-library to load and
+     to control aspects of the way it is handled. Also, made an update to
+     the README.ENGINE file that brings its information up-to-date and
+     provides some information and instructions on the "dynamic" ENGINE
+     (ie. how to use it, how to build "dynamic"-loadable ENGINEs, etc).
+     [Geoff Thorpe]
+
+  *) Make it possible to unload ranges of ERR strings with a new
+     "ERR_unload_strings" function.
+     [Geoff Thorpe]
+
+  *) Add a copy() function to EVP_MD.
+     [Ben Laurie]
+
+  *) Make EVP_MD routines take a context pointer instead of just the
+     md_data void pointer.
+     [Ben Laurie]
+
+  *) Add flags to EVP_MD and EVP_MD_CTX. EVP_MD_FLAG_ONESHOT indicates
+     that the digest can only process a single chunk of data
+     (typically because it is provided by a piece of
+     hardware). EVP_MD_CTX_FLAG_ONESHOT indicates that the application
+     is only going to provide a single chunk of data, and hence the
+     framework needn't accumulate the data for oneshot drivers.
+     [Ben Laurie]
+
+  *) As with "ERR", make it possible to replace the underlying "ex_data"
+     functions. This change also alters the storage and management of global
+     ex_data state - it's now all inside ex_data.c and all "class" code (eg.
+     RSA, BIO, SSL_CTX, etc) no longer stores its own STACKS and per-class
+     index counters. The API functions that use this state have been changed
+     to take a "class_index" rather than pointers to the class's local STACK
+     and counter, and there is now an API function to dynamically create new
+     classes. This centralisation allows us to (a) plug a lot of the
+     thread-safety problems that existed, and (b) makes it possible to clean
+     up all allocated state using "CRYPTO_cleanup_all_ex_data()". W.r.t. (b)
+     such data would previously have always leaked in application code and
+     workarounds were in place to make the memory debugging turn a blind eye
+     to it. Application code that doesn't use this new function will still
+     leak as before, but their memory debugging output will announce it now
+     rather than letting it slide.
+
+     Besides the addition of CRYPTO_cleanup_all_ex_data(), another API change
+     induced by the "ex_data" overhaul is that X509_STORE_CTX_init() now
+     has a return value to indicate success or failure.
+     [Geoff Thorpe]
+
+  *) Make it possible to replace the underlying "ERR" functions such that the
+     global state (2 LHASH tables and 2 locks) is only used by the "default"
+     implementation. This change also adds two functions to "get" and "set"
+     the implementation prior to it being automatically set the first time
+     any other ERR function takes place. Ie. an application can call "get",
+     pass the return value to a module it has just loaded, and that module
+     can call its own "set" function using that value. This means the
+     module's "ERR" operations will use (and modify) the error state in the
+     application and not in its own statically linked copy of OpenSSL code.
+     [Geoff Thorpe]
+
+  *) Give DH, DSA, and RSA types their own "**_up_ref()" function to increment
+     reference counts. This performs normal REF_PRINT/REF_CHECK macros on
+     the operation, and provides a more encapsulated way for external code
+     (crypto/evp/ and ssl/) to do this. Also changed the evp and ssl code
+     to use these functions rather than manually incrementing the counts.
+
+     Also rename "DSO_up()" function to more descriptive "DSO_up_ref()".
+     [Geoff Thorpe]
+
+  *) Add EVP test program.
+     [Ben Laurie]
+
+  *) Add symmetric cipher support to ENGINE. Expect the API to change!
+     [Ben Laurie]
+
+  *) New CRL functions: X509_CRL_set_version(), X509_CRL_set_issuer_name()
+     X509_CRL_set_lastUpdate(), X509_CRL_set_nextUpdate(), X509_CRL_sort(),
+     X509_REVOKED_set_serialNumber(), and X509_REVOKED_set_revocationDate().
+     These allow a CRL to be built without having to access X509_CRL fields
+     directly. Modify 'ca' application to use new functions.
+     [Steve Henson]
+
+  *) Move SSL_OP_TLS_ROLLBACK_BUG out of the SSL_OP_ALL list of recommended
+     bug workarounds. Rollback attack detection is a security feature.
+     The problem will only arise on OpenSSL servers when TLSv1 is not
+     available (sslv3_server_method() or SSL_OP_NO_TLSv1).
+     Software authors not wanting to support TLSv1 will have special reasons
+     for their choice and can explicitly enable this option.
+     [Bodo Moeller, Lutz Jaenicke]
+
+  *) Rationalise EVP so it can be extended: don't include a union of
+     cipher/digest structures, add init/cleanup functions for EVP_MD_CTX
+     (similar to those existing for EVP_CIPHER_CTX).
+     Usage example:
+
+         EVP_MD_CTX md;
+
+         EVP_MD_CTX_init(&md);             /* new function call */
+         EVP_DigestInit(&md, EVP_sha1());
+         EVP_DigestUpdate(&md, in, len);
+         EVP_DigestFinal(&md, out, NULL);
+         EVP_MD_CTX_cleanup(&md);          /* new function call */
+
+     [Ben Laurie]
+
+  *) Make DES key schedule conform to the usual scheme, as well as
+     correcting its structure. This means that calls to DES functions
+     now have to pass a pointer to a des_key_schedule instead of a
+     plain des_key_schedule (which was actually always a pointer
+     anyway): E.g.,
+
+         des_key_schedule ks;
+
+	 des_set_key_checked(..., &ks);
+	 des_ncbc_encrypt(..., &ks, ...);
+
+     (Note that a later change renames 'des_...' into 'DES_...'.)
+     [Ben Laurie]
+
+  *) Initial reduction of linker bloat: the use of some functions, such as
+     PEM causes large amounts of unused functions to be linked in due to
+     poor organisation. For example pem_all.c contains every PEM function
+     which has a knock on effect of linking in large amounts of (unused)
+     ASN1 code. Grouping together similar functions and splitting unrelated
+     functions prevents this.
+     [Steve Henson]
+
+  *) Cleanup of EVP macros.
+     [Ben Laurie]
+
+  *) Change historical references to {NID,SN,LN}_des_ede and ede3 to add the
+     correct _ecb suffix.
+     [Ben Laurie]
+
+  *) Add initial OCSP responder support to ocsp application. The
+     revocation information is handled using the text based index
+     use by the ca application. The responder can either handle
+     requests generated internally, supplied in files (for example
+     via a CGI script) or using an internal minimal server.
+     [Steve Henson]
+
+  *) Add configuration choices to get zlib compression for TLS.
+     [Richard Levitte]
+
+  *) Changes to Kerberos SSL for RFC 2712 compliance:
+     1.  Implemented real KerberosWrapper, instead of just using
+         KRB5 AP_REQ message.  [Thanks to Simon Wilkinson <sxw@sxw.org.uk>]
+     2.  Implemented optional authenticator field of KerberosWrapper.
+
+     Added openssl-style ASN.1 macros for Kerberos ticket, ap_req,
+     and authenticator structs; see crypto/krb5/.
+
+     Generalized Kerberos calls to support multiple Kerberos libraries.
+     [Vern Staats <staatsvr@asc.hpc.mil>,
+      Jeffrey Altman <jaltman@columbia.edu>
+      via Richard Levitte]
+
+  *) Cause 'openssl speed' to use fully hard-coded DSA keys as it
+     already does with RSA. testdsa.h now has 'priv_key/pub_key'
+     values for each of the key sizes rather than having just
+     parameters (and 'speed' generating keys each time).
+     [Geoff Thorpe]
+
+  *) Speed up EVP routines.
+     Before:
+encrypt
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+des-cbc           4408.85k     5560.51k     5778.46k     5862.20k     5825.16k
+des-cbc           4389.55k     5571.17k     5792.23k     5846.91k     5832.11k
+des-cbc           4394.32k     5575.92k     5807.44k     5848.37k     5841.30k
+decrypt
+des-cbc           3482.66k     5069.49k     5496.39k     5614.16k     5639.28k
+des-cbc           3480.74k     5068.76k     5510.34k     5609.87k     5635.52k
+des-cbc           3483.72k     5067.62k     5504.60k     5708.01k     5724.80k
+     After:
+encrypt
+des-cbc           4660.16k     5650.19k     5807.19k     5827.13k     5783.32k
+decrypt
+des-cbc           3624.96k     5258.21k     5530.91k     5624.30k     5628.26k
+     [Ben Laurie]
+
+  *) Added the OS2-EMX target.
+     ["Brian Havard" <brianh@kheldar.apana.org.au> and Richard Levitte]
+
+  *) Rewrite apps to use NCONF routines instead of the old CONF. New functions
+     to support NCONF routines in extension code. New function CONF_set_nconf()
+     to allow functions which take an NCONF to also handle the old LHASH
+     structure: this means that the old CONF compatible routines can be
+     retained (in particular wrt extensions) without having to duplicate the
+     code. New function X509V3_add_ext_nconf_sk to add extensions to a stack.
+     [Steve Henson]
+
+  *) Enhance the general user interface with mechanisms for inner control
+     and with possibilities to have yes/no kind of prompts.
+     [Richard Levitte]
+
+  *) Change all calls to low level digest routines in the library and
+     applications to use EVP. Add missing calls to HMAC_cleanup() and
+     don't assume HMAC_CTX can be copied using memcpy().
+     [Verdon Walker <VWalker@novell.com>, Steve Henson]
+
+  *) Add the possibility to control engines through control names but with
+     arbitrary arguments instead of just a string.
+     Change the key loaders to take a UI_METHOD instead of a callback
+     function pointer.  NOTE: this breaks binary compatibility with earlier
+     versions of OpenSSL [engine].
+     Adapt the nCipher code for these new conditions and add a card insertion
+     callback.
+     [Richard Levitte]
+
+  *) Enhance the general user interface with mechanisms to better support
+     dialog box interfaces, application-defined prompts, the possibility
+     to use defaults (for example default passwords from somewhere else)
+     and interrupts/cancellations.
+     [Richard Levitte]
+
+  *) Tidy up PKCS#12 attribute handling. Add support for the CSP name
+     attribute in PKCS#12 files, add new -CSP option to pkcs12 utility.
+     [Steve Henson]
+
+  *) Fix a memory leak in 'sk_dup()' in the case reallocation fails. (Also
+     tidy up some unnecessarily weird code in 'sk_new()').
+     [Geoff, reported by Diego Tartara <dtartara@novamens.com>]
+
+  *) Change the key loading routines for ENGINEs to use the same kind
+     callback (pem_password_cb) as all other routines that need this
+     kind of callback.
+     [Richard Levitte]
+
+  *) Increase ENTROPY_NEEDED to 32 bytes, as Rijndael can operate with
+     256 bit (=32 byte) keys. Of course seeding with more entropy bytes
+     than this minimum value is recommended.
+     [Lutz Jaenicke]
+
+  *) New random seeder for OpenVMS, using the system process statistics
+     that are easily reachable.
+     [Richard Levitte]
+
+  *) Windows apparently can't transparently handle global
+     variables defined in DLLs. Initialisations such as:
+
+        const ASN1_ITEM *it = &ASN1_INTEGER_it;
+
+     wont compile. This is used by the any applications that need to
+     declare their own ASN1 modules. This was fixed by adding the option
+     EXPORT_VAR_AS_FN to all Win32 platforms, although this isn't strictly
+     needed for static libraries under Win32.
+     [Steve Henson]
+
+  *) New functions X509_PURPOSE_set() and X509_TRUST_set() to handle
+     setting of purpose and trust fields. New X509_STORE trust and
+     purpose functions and tidy up setting in other SSL functions.
+     [Steve Henson]
+
+  *) Add copies of X509_STORE_CTX fields and callbacks to X509_STORE
+     structure. These are inherited by X509_STORE_CTX when it is 
+     initialised. This allows various defaults to be set in the
+     X509_STORE structure (such as flags for CRL checking and custom
+     purpose or trust settings) for functions which only use X509_STORE_CTX
+     internally such as S/MIME.
+
+     Modify X509_STORE_CTX_purpose_inherit() so it only sets purposes and
+     trust settings if they are not set in X509_STORE. This allows X509_STORE
+     purposes and trust (in S/MIME for example) to override any set by default.
+
+     Add command line options for CRL checking to smime, s_client and s_server
+     applications.
+     [Steve Henson]
+
+  *) Initial CRL based revocation checking. If the CRL checking flag(s)
+     are set then the CRL is looked up in the X509_STORE structure and
+     its validity and signature checked, then if the certificate is found
+     in the CRL the verify fails with a revoked error.
+
+     Various new CRL related callbacks added to X509_STORE_CTX structure.
+
+     Command line options added to 'verify' application to support this.
+
+     This needs some additional work, such as being able to handle multiple
+     CRLs with different times, extension based lookup (rather than just
+     by subject name) and ultimately more complete V2 CRL extension
+     handling.
+     [Steve Henson]
+
+  *) Add a general user interface API (crypto/ui/).  This is designed
+     to replace things like des_read_password and friends (backward
+     compatibility functions using this new API are provided).
+     The purpose is to remove prompting functions from the DES code
+     section as well as provide for prompting through dialog boxes in
+     a window system and the like.
+     [Richard Levitte]
+
+  *) Add "ex_data" support to ENGINE so implementations can add state at a
+     per-structure level rather than having to store it globally.
+     [Geoff]
+
+  *) Make it possible for ENGINE structures to be copied when retrieved by
+     ENGINE_by_id() if the ENGINE specifies a new flag: ENGINE_FLAGS_BY_ID_COPY.
+     This causes the "original" ENGINE structure to act like a template,
+     analogous to the RSA vs. RSA_METHOD type of separation. Because of this
+     operational state can be localised to each ENGINE structure, despite the
+     fact they all share the same "methods". New ENGINE structures returned in
+     this case have no functional references and the return value is the single
+     structural reference. This matches the single structural reference returned
+     by ENGINE_by_id() normally, when it is incremented on the pre-existing
+     ENGINE structure.
+     [Geoff]
+
+  *) Fix ASN1 decoder when decoding type ANY and V_ASN1_OTHER: since this
+     needs to match any other type at all we need to manually clear the
+     tag cache.
+     [Steve Henson]
+
+  *) Changes to the "openssl engine" utility to include;
+     - verbosity levels ('-v', '-vv', and '-vvv') that provide information
+       about an ENGINE's available control commands.
+     - executing control commands from command line arguments using the
+       '-pre' and '-post' switches. '-post' is only used if '-t' is
+       specified and the ENGINE is successfully initialised. The syntax for
+       the individual commands are colon-separated, for example;
+	 openssl engine chil -pre FORK_CHECK:0 -pre SO_PATH:/lib/test.so
+     [Geoff]
+
+  *) New dynamic control command support for ENGINEs. ENGINEs can now
+     declare their own commands (numbers), names (strings), descriptions,
+     and input types for run-time discovery by calling applications. A
+     subset of these commands are implicitly classed as "executable"
+     depending on their input type, and only these can be invoked through
+     the new string-based API function ENGINE_ctrl_cmd_string(). (Eg. this
+     can be based on user input, config files, etc). The distinction is
+     that "executable" commands cannot return anything other than a boolean
+     result and can only support numeric or string input, whereas some
+     discoverable commands may only be for direct use through
+     ENGINE_ctrl(), eg. supporting the exchange of binary data, function
+     pointers, or other custom uses. The "executable" commands are to
+     support parameterisations of ENGINE behaviour that can be
+     unambiguously defined by ENGINEs and used consistently across any
+     OpenSSL-based application. Commands have been added to all the
+     existing hardware-supporting ENGINEs, noticeably "SO_PATH" to allow
+     control over shared-library paths without source code alterations.
+     [Geoff]
+
+  *) Changed all ENGINE implementations to dynamically allocate their
+     ENGINEs rather than declaring them statically. Apart from this being
+     necessary with the removal of the ENGINE_FLAGS_MALLOCED distinction,
+     this also allows the implementations to compile without using the
+     internal engine_int.h header.
+     [Geoff]
+
+  *) Minor adjustment to "rand" code. RAND_get_rand_method() now returns a
+     'const' value. Any code that should be able to modify a RAND_METHOD
+     should already have non-const pointers to it (ie. they should only
+     modify their own ones).
+     [Geoff]
+
+  *) Made a variety of little tweaks to the ENGINE code.
+     - "atalla" and "ubsec" string definitions were moved from header files
+       to C code. "nuron" string definitions were placed in variables
+       rather than hard-coded - allowing parameterisation of these values
+       later on via ctrl() commands.
+     - Removed unused "#if 0"'d code.
+     - Fixed engine list iteration code so it uses ENGINE_free() to release
+       structural references.
+     - Constified the RAND_METHOD element of ENGINE structures.
+     - Constified various get/set functions as appropriate and added
+       missing functions (including a catch-all ENGINE_cpy that duplicates
+       all ENGINE values onto a new ENGINE except reference counts/state).
+     - Removed NULL parameter checks in get/set functions. Setting a method
+       or function to NULL is a way of cancelling out a previously set
+       value.  Passing a NULL ENGINE parameter is just plain stupid anyway
+       and doesn't justify the extra error symbols and code.
+     - Deprecate the ENGINE_FLAGS_MALLOCED define and move the area for
+       flags from engine_int.h to engine.h.
+     - Changed prototypes for ENGINE handler functions (init(), finish(),
+       ctrl(), key-load functions, etc) to take an (ENGINE*) parameter.
+     [Geoff]
+
+  *) Implement binary inversion algorithm for BN_mod_inverse in addition
+     to the algorithm using long division.  The binary algorithm can be
+     used only if the modulus is odd.  On 32-bit systems, it is faster
+     only for relatively small moduli (roughly 20-30% for 128-bit moduli,
+     roughly 5-15% for 256-bit moduli), so we use it only for moduli
+     up to 450 bits.  In 64-bit environments, the binary algorithm
+     appears to be advantageous for much longer moduli; here we use it
+     for moduli up to 2048 bits.
+     [Bodo Moeller]
+
+  *) Rewrite CHOICE field setting in ASN1_item_ex_d2i(). The old code
+     could not support the combine flag in choice fields.
+     [Steve Henson]
+
+  *) Add a 'copy_extensions' option to the 'ca' utility. This copies
+     extensions from a certificate request to the certificate.
+     [Steve Henson]
+
+  *) Allow multiple 'certopt' and 'nameopt' options to be separated
+     by commas. Add 'namopt' and 'certopt' options to the 'ca' config
+     file: this allows the display of the certificate about to be
+     signed to be customised, to allow certain fields to be included
+     or excluded and extension details. The old system didn't display
+     multicharacter strings properly, omitted fields not in the policy
+     and couldn't display additional details such as extensions.
+     [Steve Henson]
+
+  *) Function EC_POINTs_mul for multiple scalar multiplication
+     of an arbitrary number of elliptic curve points
+          \sum scalars[i]*points[i],
+     optionally including the generator defined for the EC_GROUP:
+          scalar*generator +  \sum scalars[i]*points[i].
+
+     EC_POINT_mul is a simple wrapper function for the typical case
+     that the point list has just one item (besides the optional
+     generator).
+     [Bodo Moeller]
+
+  *) First EC_METHODs for curves over GF(p):
+
+     EC_GFp_simple_method() uses the basic BN_mod_mul and BN_mod_sqr
+     operations and provides various method functions that can also
+     operate with faster implementations of modular arithmetic.     
+
+     EC_GFp_mont_method() reuses most functions that are part of
+     EC_GFp_simple_method, but uses Montgomery arithmetic.
+
+     [Bodo Moeller; point addition and point doubling
+     implementation directly derived from source code provided by
+     Lenka Fibikova <fibikova@exp-math.uni-essen.de>]
+
+  *) Framework for elliptic curves (crypto/ec/ec.h, crypto/ec/ec_lcl.h,
+     crypto/ec/ec_lib.c):
+
+     Curves are EC_GROUP objects (with an optional group generator)
+     based on EC_METHODs that are built into the library.
+
+     Points are EC_POINT objects based on EC_GROUP objects.
+
+     Most of the framework would be able to handle curves over arbitrary
+     finite fields, but as there are no obvious types for fields other
+     than GF(p), some functions are limited to that for now.
+     [Bodo Moeller]
+
+  *) Add the -HTTP option to s_server.  It is similar to -WWW, but requires
+     that the file contains a complete HTTP response.
+     [Richard Levitte]
+
+  *) Add the ec directory to mkdef.pl and mkfiles.pl. In mkdef.pl
+     change the def and num file printf format specifier from "%-40sXXX"
+     to "%-39s XXX". The latter will always guarantee a space after the
+     field while the former will cause them to run together if the field
+     is 40 of more characters long.
+     [Steve Henson]
+
+  *) Constify the cipher and digest 'method' functions and structures
+     and modify related functions to take constant EVP_MD and EVP_CIPHER
+     pointers.
+     [Steve Henson]
+
+  *) Hide BN_CTX structure details in bn_lcl.h instead of publishing them
+     in <openssl/bn.h>.  Also further increase BN_CTX_NUM to 32.
+     [Bodo Moeller]
+
+  *) Modify EVP_Digest*() routines so they now return values. Although the
+     internal software routines can never fail additional hardware versions
+     might.
+     [Steve Henson]
+
+  *) Clean up crypto/err/err.h and change some error codes to avoid conflicts:
+
+     Previously ERR_R_FATAL was too small and coincided with ERR_LIB_PKCS7
+     (= ERR_R_PKCS7_LIB); it is now 64 instead of 32.
+
+     ASN1 error codes
+          ERR_R_NESTED_ASN1_ERROR
+          ...
+          ERR_R_MISSING_ASN1_EOS
+     were 4 .. 9, conflicting with
+          ERR_LIB_RSA (= ERR_R_RSA_LIB)
+          ...
+          ERR_LIB_PEM (= ERR_R_PEM_LIB).
+     They are now 58 .. 63 (i.e., just below ERR_R_FATAL).
+
+     Add new error code 'ERR_R_INTERNAL_ERROR'.
+     [Bodo Moeller]
+
+  *) Don't overuse locks in crypto/err/err.c: For data retrieval, CRYPTO_r_lock
+     suffices.
+     [Bodo Moeller]
+
+  *) New option '-subj arg' for 'openssl req' and 'openssl ca'.  This
+     sets the subject name for a new request or supersedes the
+     subject name in a given request. Formats that can be parsed are
+          'CN=Some Name, OU=myOU, C=IT'
+     and
+          'CN=Some Name/OU=myOU/C=IT'.
+
+     Add options '-batch' and '-verbose' to 'openssl req'.
+     [Massimiliano Pala <madwolf@hackmasters.net>]
+
+  *) Introduce the possibility to access global variables through
+     functions on platform were that's the best way to handle exporting
+     global variables in shared libraries.  To enable this functionality,
+     one must configure with "EXPORT_VAR_AS_FN" or defined the C macro
+     "OPENSSL_EXPORT_VAR_AS_FUNCTION" in crypto/opensslconf.h (the latter
+     is normally done by Configure or something similar).
+
+     To implement a global variable, use the macro OPENSSL_IMPLEMENT_GLOBAL
+     in the source file (foo.c) like this:
+
+	OPENSSL_IMPLEMENT_GLOBAL(int,foo)=1;
+	OPENSSL_IMPLEMENT_GLOBAL(double,bar);
+
+     To declare a global variable, use the macros OPENSSL_DECLARE_GLOBAL
+     and OPENSSL_GLOBAL_REF in the header file (foo.h) like this:
+
+	OPENSSL_DECLARE_GLOBAL(int,foo);
+	#define foo OPENSSL_GLOBAL_REF(foo)
+	OPENSSL_DECLARE_GLOBAL(double,bar);
+	#define bar OPENSSL_GLOBAL_REF(bar)
+
+     The #defines are very important, and therefore so is including the
+     header file everywhere where the defined globals are used.
+
+     The macro OPENSSL_EXPORT_VAR_AS_FUNCTION also affects the definition
+     of ASN.1 items, but that structure is a bit different.
+
+     The largest change is in util/mkdef.pl which has been enhanced with
+     better and easier to understand logic to choose which symbols should
+     go into the Windows .def files as well as a number of fixes and code
+     cleanup (among others, algorithm keywords are now sorted
+     lexicographically to avoid constant rewrites).
+     [Richard Levitte]
+
+  *) In BN_div() keep a copy of the sign of 'num' before writing the
+     result to 'rm' because if rm==num the value will be overwritten
+     and produce the wrong result if 'num' is negative: this caused
+     problems with BN_mod() and BN_nnmod().
+     [Steve Henson]
+
+  *) Function OCSP_request_verify(). This checks the signature on an
+     OCSP request and verifies the signer certificate. The signer
+     certificate is just checked for a generic purpose and OCSP request
+     trust settings.
+     [Steve Henson]
+
+  *) Add OCSP_check_validity() function to check the validity of OCSP
+     responses. OCSP responses are prepared in real time and may only
+     be a few seconds old. Simply checking that the current time lies
+     between thisUpdate and nextUpdate max reject otherwise valid responses
+     caused by either OCSP responder or client clock inaccuracy. Instead
+     we allow thisUpdate and nextUpdate to fall within a certain period of
+     the current time. The age of the response can also optionally be
+     checked. Two new options -validity_period and -status_age added to
+     ocsp utility.
+     [Steve Henson]
+
+  *) If signature or public key algorithm is unrecognized print out its
+     OID rather that just UNKNOWN.
+     [Steve Henson]
+
+  *) Change OCSP_cert_to_id() to tolerate a NULL subject certificate and
+     OCSP_cert_id_new() a NULL serialNumber. This allows a partial certificate
+     ID to be generated from the issuer certificate alone which can then be
+     passed to OCSP_id_issuer_cmp().
+     [Steve Henson]
+
+  *) New compilation option ASN1_ITEM_FUNCTIONS. This causes the new
+     ASN1 modules to export functions returning ASN1_ITEM pointers
+     instead of the ASN1_ITEM structures themselves. This adds several
+     new macros which allow the underlying ASN1 function/structure to
+     be accessed transparently. As a result code should not use ASN1_ITEM
+     references directly (such as &X509_it) but instead use the relevant
+     macros (such as ASN1_ITEM_rptr(X509)). This option is to allow
+     use of the new ASN1 code on platforms where exporting structures
+     is problematical (for example in shared libraries) but exporting
+     functions returning pointers to structures is not.
+     [Steve Henson]
+
+  *) Add support for overriding the generation of SSL/TLS session IDs.
+     These callbacks can be registered either in an SSL_CTX or per SSL.
+     The purpose of this is to allow applications to control, if they wish,
+     the arbitrary values chosen for use as session IDs, particularly as it
+     can be useful for session caching in multiple-server environments. A
+     command-line switch for testing this (and any client code that wishes
+     to use such a feature) has been added to "s_server".
+     [Geoff Thorpe, Lutz Jaenicke]
+
+  *) Modify mkdef.pl to recognise and parse preprocessor conditionals
+     of the form '#if defined(...) || defined(...) || ...' and
+     '#if !defined(...) && !defined(...) && ...'.  This also avoids
+     the growing number of special cases it was previously handling.
+     [Richard Levitte]
+
+  *) Make all configuration macros available for application by making
+     sure they are available in opensslconf.h, by giving them names starting
+     with "OPENSSL_" to avoid conflicts with other packages and by making
+     sure e_os2.h will cover all platform-specific cases together with
+     opensslconf.h.
+     Additionally, it is now possible to define configuration/platform-
+     specific names (called "system identities").  In the C code, these
+     are prefixed with "OPENSSL_SYSNAME_".  e_os2.h will create another
+     macro with the name beginning with "OPENSSL_SYS_", which is determined
+     from "OPENSSL_SYSNAME_*" or compiler-specific macros depending on
+     what is available.
+     [Richard Levitte]
+
+  *) New option -set_serial to 'req' and 'x509' this allows the serial
+     number to use to be specified on the command line. Previously self
+     signed certificates were hard coded with serial number 0 and the 
+     CA options of 'x509' had to use a serial number in a file which was
+     auto incremented.
+     [Steve Henson]
+
+  *) New options to 'ca' utility to support V2 CRL entry extensions.
+     Currently CRL reason, invalidity date and hold instruction are
+     supported. Add new CRL extensions to V3 code and some new objects.
+     [Steve Henson]
+
+  *) New function EVP_CIPHER_CTX_set_padding() this is used to
+     disable standard block padding (aka PKCS#5 padding) in the EVP
+     API, which was previously mandatory. This means that the data is
+     not padded in any way and so the total length much be a multiple
+     of the block size, otherwise an error occurs.
+     [Steve Henson]
+
+  *) Initial (incomplete) OCSP SSL support.
+     [Steve Henson]
+
+  *) New function OCSP_parse_url(). This splits up a URL into its host,
+     port and path components: primarily to parse OCSP URLs. New -url
+     option to ocsp utility.
+     [Steve Henson]
+
+  *) New nonce behavior. The return value of OCSP_check_nonce() now 
+     reflects the various checks performed. Applications can decide
+     whether to tolerate certain situations such as an absent nonce
+     in a response when one was present in a request: the ocsp application
+     just prints out a warning. New function OCSP_add1_basic_nonce()
+     this is to allow responders to include a nonce in a response even if
+     the request is nonce-less.
+     [Steve Henson]
+
+  *) Disable stdin buffering in load_cert (apps/apps.c) so that no certs are
+     skipped when using openssl x509 multiple times on a single input file,
+     e.g. "(openssl x509 -out cert1; openssl x509 -out cert2) <certs".
+     [Bodo Moeller]
+
+  *) Make ASN1_UTCTIME_set_string() and ASN1_GENERALIZEDTIME_set_string()
+     set string type: to handle setting ASN1_TIME structures. Fix ca
+     utility to correctly initialize revocation date of CRLs.
+     [Steve Henson]
+
+  *) New option SSL_OP_CIPHER_SERVER_PREFERENCE allows the server to override
+     the clients preferred ciphersuites and rather use its own preferences.
+     Should help to work around M$ SGC (Server Gated Cryptography) bug in
+     Internet Explorer by ensuring unchanged hash method during stepup.
+     (Also replaces the broken/deactivated SSL_OP_NON_EXPORT_FIRST option.)
+     [Lutz Jaenicke]
+
+  *) Make mkdef.pl recognise all DECLARE_ASN1 macros, change rijndael
+     to aes and add a new 'exist' option to print out symbols that don't
+     appear to exist.
+     [Steve Henson]
+
+  *) Additional options to ocsp utility to allow flags to be set and
+     additional certificates supplied.
+     [Steve Henson]
+
+  *) Add the option -VAfile to 'openssl ocsp', so the user can give the
+     OCSP client a number of certificate to only verify the response
+     signature against.
+     [Richard Levitte]
+
+  *) Update Rijndael code to version 3.0 and change EVP AES ciphers to
+     handle the new API. Currently only ECB, CBC modes supported. Add new
+     AES OIDs.
+
+     Add TLS AES ciphersuites as described in RFC3268, "Advanced
+     Encryption Standard (AES) Ciphersuites for Transport Layer
+     Security (TLS)".  (In beta versions of OpenSSL 0.9.7, these were
+     not enabled by default and were not part of the "ALL" ciphersuite
+     alias because they were not yet official; they could be
+     explicitly requested by specifying the "AESdraft" ciphersuite
+     group alias.  In the final release of OpenSSL 0.9.7, the group
+     alias is called "AES" and is part of "ALL".)
+     [Ben Laurie, Steve  Henson, Bodo Moeller]
+
+  *) New function OCSP_copy_nonce() to copy nonce value (if present) from
+     request to response.
+     [Steve Henson]
+
+  *) Functions for OCSP responders. OCSP_request_onereq_count(),
+     OCSP_request_onereq_get0(), OCSP_onereq_get0_id() and OCSP_id_get0_info()
+     extract information from a certificate request. OCSP_response_create()
+     creates a response and optionally adds a basic response structure.
+     OCSP_basic_add1_status() adds a complete single response to a basic
+     response and returns the OCSP_SINGLERESP structure just added (to allow
+     extensions to be included for example). OCSP_basic_add1_cert() adds a
+     certificate to a basic response and OCSP_basic_sign() signs a basic
+     response with various flags. New helper functions ASN1_TIME_check()
+     (checks validity of ASN1_TIME structure) and ASN1_TIME_to_generalizedtime()
+     (converts ASN1_TIME to GeneralizedTime).
+     [Steve Henson]
+
+  *) Various new functions. EVP_Digest() combines EVP_Digest{Init,Update,Final}()
+     in a single operation. X509_get0_pubkey_bitstr() extracts the public_key
+     structure from a certificate. X509_pubkey_digest() digests the public_key
+     contents: this is used in various key identifiers. 
+     [Steve Henson]
+
+  *) Make sk_sort() tolerate a NULL argument.
+     [Steve Henson reported by Massimiliano Pala <madwolf@comune.modena.it>]
+
+  *) New OCSP verify flag OCSP_TRUSTOTHER. When set the "other" certificates
+     passed by the function are trusted implicitly. If any of them signed the
+     response then it is assumed to be valid and is not verified.
+     [Steve Henson]
+
+  *) In PKCS7_set_type() initialise content_type in PKCS7_ENC_CONTENT
+     to data. This was previously part of the PKCS7 ASN1 code. This
+     was causing problems with OpenSSL created PKCS#12 and PKCS#7 structures.
+     [Steve Henson, reported by Kenneth R. Robinette
+				<support@securenetterm.com>]
+
+  *) Add CRYPTO_push_info() and CRYPTO_pop_info() calls to new ASN1
+     routines: without these tracing memory leaks is very painful.
+     Fix leaks in PKCS12 and PKCS7 routines.
+     [Steve Henson]
+
+  *) Make X509_time_adj() cope with the new behaviour of ASN1_TIME_new().
+     Previously it initialised the 'type' argument to V_ASN1_UTCTIME which
+     effectively meant GeneralizedTime would never be used. Now it
+     is initialised to -1 but X509_time_adj() now has to check the value
+     and use ASN1_TIME_set() if the value is not V_ASN1_UTCTIME or
+     V_ASN1_GENERALIZEDTIME, without this it always uses GeneralizedTime.
+     [Steve Henson, reported by Kenneth R. Robinette
+				<support@securenetterm.com>]
+
+  *) Fixes to BN_to_ASN1_INTEGER when bn is zero. This would previously
+     result in a zero length in the ASN1_INTEGER structure which was
+     not consistent with the structure when d2i_ASN1_INTEGER() was used
+     and would cause ASN1_INTEGER_cmp() to fail. Enhance s2i_ASN1_INTEGER()
+     to cope with hex and negative integers. Fix bug in i2a_ASN1_INTEGER()
+     where it did not print out a minus for negative ASN1_INTEGER.
+     [Steve Henson]
+
+  *) Add summary printout to ocsp utility. The various functions which
+     convert status values to strings have been renamed to:
+     OCSP_response_status_str(), OCSP_cert_status_str() and
+     OCSP_crl_reason_str() and are no longer static. New options
+     to verify nonce values and to disable verification. OCSP response
+     printout format cleaned up.
+     [Steve Henson]
+
+  *) Add additional OCSP certificate checks. These are those specified
+     in RFC2560. This consists of two separate checks: the CA of the
+     certificate being checked must either be the OCSP signer certificate
+     or the issuer of the OCSP signer certificate. In the latter case the
+     OCSP signer certificate must contain the OCSP signing extended key
+     usage. This check is performed by attempting to match the OCSP
+     signer or the OCSP signer CA to the issuerNameHash and issuerKeyHash
+     in the OCSP_CERTID structures of the response.
+     [Steve Henson]
+
+  *) Initial OCSP certificate verification added to OCSP_basic_verify()
+     and related routines. This uses the standard OpenSSL certificate
+     verify routines to perform initial checks (just CA validity) and
+     to obtain the certificate chain. Then additional checks will be
+     performed on the chain. Currently the root CA is checked to see
+     if it is explicitly trusted for OCSP signing. This is used to set
+     a root CA as a global signing root: that is any certificate that
+     chains to that CA is an acceptable OCSP signing certificate.
+     [Steve Henson]
+
+  *) New '-extfile ...' option to 'openssl ca' for reading X.509v3
+     extensions from a separate configuration file.
+     As when reading extensions from the main configuration file,
+     the '-extensions ...' option may be used for specifying the
+     section to use.
+     [Massimiliano Pala <madwolf@comune.modena.it>]
+
+  *) New OCSP utility. Allows OCSP requests to be generated or
+     read. The request can be sent to a responder and the output
+     parsed, outputed or printed in text form. Not complete yet:
+     still needs to check the OCSP response validity.
+     [Steve Henson]
+
+  *) New subcommands for 'openssl ca':
+     'openssl ca -status <serial>' prints the status of the cert with
+     the given serial number (according to the index file).
+     'openssl ca -updatedb' updates the expiry status of certificates
+     in the index file.
+     [Massimiliano Pala <madwolf@comune.modena.it>]
+
+  *) New '-newreq-nodes' command option to CA.pl.  This is like
+     '-newreq', but calls 'openssl req' with the '-nodes' option
+     so that the resulting key is not encrypted.
+     [Damien Miller <djm@mindrot.org>]
+
+  *) New configuration for the GNU Hurd.
+     [Jonathan Bartlett <johnnyb@wolfram.com> via Richard Levitte]
+
+  *) Initial code to implement OCSP basic response verify. This
+     is currently incomplete. Currently just finds the signer's
+     certificate and verifies the signature on the response.
+     [Steve Henson]
+
+  *) New SSLeay_version code SSLEAY_DIR to determine the compiled-in
+     value of OPENSSLDIR.  This is available via the new '-d' option
+     to 'openssl version', and is also included in 'openssl version -a'.
+     [Bodo Moeller]
+
+  *) Allowing defining memory allocation callbacks that will be given
+     file name and line number information in additional arguments
+     (a const char* and an int).  The basic functionality remains, as
+     well as the original possibility to just replace malloc(),
+     realloc() and free() by functions that do not know about these
+     additional arguments.  To register and find out the current
+     settings for extended allocation functions, the following
+     functions are provided:
+
+	CRYPTO_set_mem_ex_functions
+	CRYPTO_set_locked_mem_ex_functions
+	CRYPTO_get_mem_ex_functions
+	CRYPTO_get_locked_mem_ex_functions
+
+     These work the same way as CRYPTO_set_mem_functions and friends.
+     CRYPTO_get_[locked_]mem_functions now writes 0 where such an
+     extended allocation function is enabled.
+     Similarly, CRYPTO_get_[locked_]mem_ex_functions writes 0 where
+     a conventional allocation function is enabled.
+     [Richard Levitte, Bodo Moeller]
+
+  *) Finish off removing the remaining LHASH function pointer casts.
+     There should no longer be any prototype-casting required when using
+     the LHASH abstraction, and any casts that remain are "bugs". See
+     the callback types and macros at the head of lhash.h for details
+     (and "OBJ_cleanup" in crypto/objects/obj_dat.c as an example).
+     [Geoff Thorpe]
+
+  *) Add automatic query of EGD sockets in RAND_poll() for the unix variant.
+     If /dev/[u]random devices are not available or do not return enough
+     entropy, EGD style sockets (served by EGD or PRNGD) will automatically
+     be queried.
+     The locations /var/run/egd-pool, /dev/egd-pool, /etc/egd-pool, and
+     /etc/entropy will be queried once each in this sequence, quering stops
+     when enough entropy was collected without querying more sockets.
+     [Lutz Jaenicke]
+
+  *) Change the Unix RAND_poll() variant to be able to poll several
+     random devices, as specified by DEVRANDOM, until a sufficient amount
+     of data has been collected.   We spend at most 10 ms on each file
+     (select timeout) and read in non-blocking mode.  DEVRANDOM now
+     defaults to the list "/dev/urandom", "/dev/random", "/dev/srandom"
+     (previously it was just the string "/dev/urandom"), so on typical
+     platforms the 10 ms delay will never occur.
+     Also separate out the Unix variant to its own file, rand_unix.c.
+     For VMS, there's a currently-empty rand_vms.c.
+     [Richard Levitte]
+
+  *) Move OCSP client related routines to ocsp_cl.c. These
+     provide utility functions which an application needing
+     to issue a request to an OCSP responder and analyse the
+     response will typically need: as opposed to those which an
+     OCSP responder itself would need which will be added later.
+
+     OCSP_request_sign() signs an OCSP request with an API similar
+     to PKCS7_sign(). OCSP_response_status() returns status of OCSP
+     response. OCSP_response_get1_basic() extracts basic response
+     from response. OCSP_resp_find_status(): finds and extracts status
+     information from an OCSP_CERTID structure (which will be created
+     when the request structure is built). These are built from lower
+     level functions which work on OCSP_SINGLERESP structures but
+     wont normally be used unless the application wishes to examine
+     extensions in the OCSP response for example.
+
+     Replace nonce routines with a pair of functions.
+     OCSP_request_add1_nonce() adds a nonce value and optionally
+     generates a random value. OCSP_check_nonce() checks the
+     validity of the nonce in an OCSP response.
+     [Steve Henson]
+
+  *) Change function OCSP_request_add() to OCSP_request_add0_id().
+     This doesn't copy the supplied OCSP_CERTID and avoids the
+     need to free up the newly created id. Change return type
+     to OCSP_ONEREQ to return the internal OCSP_ONEREQ structure.
+     This can then be used to add extensions to the request.
+     Deleted OCSP_request_new(), since most of its functionality
+     is now in OCSP_REQUEST_new() (and the case insensitive name
+     clash) apart from the ability to set the request name which
+     will be added elsewhere.
+     [Steve Henson]
+
+  *) Update OCSP API. Remove obsolete extensions argument from
+     various functions. Extensions are now handled using the new
+     OCSP extension code. New simple OCSP HTTP function which 
+     can be used to send requests and parse the response.
+     [Steve Henson]
+
+  *) Fix the PKCS#7 (S/MIME) code to work with new ASN1. Two new
+     ASN1_ITEM structures help with sign and verify. PKCS7_ATTR_SIGN
+     uses the special reorder version of SET OF to sort the attributes
+     and reorder them to match the encoded order. This resolves a long
+     standing problem: a verify on a PKCS7 structure just after signing
+     it used to fail because the attribute order did not match the
+     encoded order. PKCS7_ATTR_VERIFY does not reorder the attributes:
+     it uses the received order. This is necessary to tolerate some broken
+     software that does not order SET OF. This is handled by encoding
+     as a SEQUENCE OF but using implicit tagging (with UNIVERSAL class)
+     to produce the required SET OF.
+     [Steve Henson]
+
+  *) Have mk1mf.pl generate the macros OPENSSL_BUILD_SHLIBCRYPTO and
+     OPENSSL_BUILD_SHLIBSSL and use them appropriately in the header
+     files to get correct declarations of the ASN.1 item variables.
+     [Richard Levitte]
+
+  *) Rewrite of PKCS#12 code to use new ASN1 functionality. Replace many
+     PKCS#12 macros with real functions. Fix two unrelated ASN1 bugs:
+     asn1_check_tlen() would sometimes attempt to use 'ctx' when it was
+     NULL and ASN1_TYPE was not dereferenced properly in asn1_ex_c2i().
+     New ASN1 macro: DECLARE_ASN1_ITEM() which just declares the relevant
+     ASN1_ITEM and no wrapper functions.
+     [Steve Henson]
+
+  *) New functions or ASN1_item_d2i_fp() and ASN1_item_d2i_bio(). These
+     replace the old function pointer based I/O routines. Change most of
+     the *_d2i_bio() and *_d2i_fp() functions to use these.
+     [Steve Henson]
+
+  *) Enhance mkdef.pl to be more accepting about spacing in C preprocessor
+     lines, recognice more "algorithms" that can be deselected, and make
+     it complain about algorithm deselection that isn't recognised.
+     [Richard Levitte]
+
+  *) New ASN1 functions to handle dup, sign, verify, digest, pack and
+     unpack operations in terms of ASN1_ITEM. Modify existing wrappers
+     to use new functions. Add NO_ASN1_OLD which can be set to remove
+     some old style ASN1 functions: this can be used to determine if old
+     code will still work when these eventually go away.
+     [Steve Henson]
+
+  *) New extension functions for OCSP structures, these follow the
+     same conventions as certificates and CRLs.
+     [Steve Henson]
+
+  *) New function X509V3_add1_i2d(). This automatically encodes and
+     adds an extension. Its behaviour can be customised with various
+     flags to append, replace or delete. Various wrappers added for
+     certifcates and CRLs.
+     [Steve Henson]
+
+  *) Fix to avoid calling the underlying ASN1 print routine when
+     an extension cannot be parsed. Correct a typo in the
+     OCSP_SERVICELOC extension. Tidy up print OCSP format.
+     [Steve Henson]
+
+  *) Make mkdef.pl parse some of the ASN1 macros and add apropriate
+     entries for variables.
+     [Steve Henson]
+
+  *) Add functionality to apps/openssl.c for detecting locking
+     problems: As the program is single-threaded, all we have
+     to do is register a locking callback using an array for
+     storing which locks are currently held by the program.
+     [Bodo Moeller]
+
+  *) Use a lock around the call to CRYPTO_get_ex_new_index() in
+     SSL_get_ex_data_X509_STORE_idx(), which is used in
+     ssl_verify_cert_chain() and thus can be called at any time
+     during TLS/SSL handshakes so that thread-safety is essential.
+     Unfortunately, the ex_data design is not at all suited
+     for multi-threaded use, so it probably should be abolished.
+     [Bodo Moeller]
+
+  *) Added Broadcom "ubsec" ENGINE to OpenSSL.
+     [Broadcom, tweaked and integrated by Geoff Thorpe]
+
+  *) Move common extension printing code to new function
+     X509V3_print_extensions(). Reorganise OCSP print routines and
+     implement some needed OCSP ASN1 functions. Add OCSP extensions.
+     [Steve Henson]
+
+  *) New function X509_signature_print() to remove duplication in some
+     print routines.
+     [Steve Henson]
+
+  *) Add a special meaning when SET OF and SEQUENCE OF flags are both
+     set (this was treated exactly the same as SET OF previously). This
+     is used to reorder the STACK representing the structure to match the
+     encoding. This will be used to get round a problem where a PKCS7
+     structure which was signed could not be verified because the STACK
+     order did not reflect the encoded order.
+     [Steve Henson]
+
+  *) Reimplement the OCSP ASN1 module using the new code.
+     [Steve Henson]
+
+  *) Update the X509V3 code to permit the use of an ASN1_ITEM structure
+     for its ASN1 operations. The old style function pointers still exist
+     for now but they will eventually go away.
+     [Steve Henson]
+
+  *) Merge in replacement ASN1 code from the ASN1 branch. This almost
+     completely replaces the old ASN1 functionality with a table driven
+     encoder and decoder which interprets an ASN1_ITEM structure describing
+     the ASN1 module. Compatibility with the existing ASN1 API (i2d,d2i) is
+     largely maintained. Almost all of the old asn1_mac.h macro based ASN1
+     has also been converted to the new form.
+     [Steve Henson]
+
+  *) Change BN_mod_exp_recp so that negative moduli are tolerated
+     (the sign is ignored).  Similarly, ignore the sign in BN_MONT_CTX_set
+     so that BN_mod_exp_mont and BN_mod_exp_mont_word work
+     for negative moduli.
+     [Bodo Moeller]
+
+  *) Fix BN_uadd and BN_usub: Always return non-negative results instead
+     of not touching the result's sign bit.
+     [Bodo Moeller]
+
+  *) BN_div bugfix: If the result is 0, the sign (res->neg) must not be
+     set.
+     [Bodo Moeller]
+
+  *) Changed the LHASH code to use prototypes for callbacks, and created
+     macros to declare and implement thin (optionally static) functions
+     that provide type-safety and avoid function pointer casting for the
+     type-specific callbacks.
+     [Geoff Thorpe]
+
+  *) Added Kerberos Cipher Suites to be used with TLS, as written in
+     RFC 2712.
+     [Veers Staats <staatsvr@asc.hpc.mil>,
+      Jeffrey Altman <jaltman@columbia.edu>, via Richard Levitte]
+
+  *) Reformat the FAQ so the different questions and answers can be divided
+     in sections depending on the subject.
+     [Richard Levitte]
+
+  *) Have the zlib compression code load ZLIB.DLL dynamically under
+     Windows.
+     [Richard Levitte]
+
+  *) New function BN_mod_sqrt for computing square roots modulo a prime
+     (using the probabilistic Tonelli-Shanks algorithm unless
+     p == 3 (mod 4)  or  p == 5 (mod 8),  which are cases that can
+     be handled deterministically).
+     [Lenka Fibikova <fibikova@exp-math.uni-essen.de>, Bodo Moeller]
+
+  *) Make BN_mod_inverse faster by explicitly handling small quotients
+     in the Euclid loop. (Speed gain about 20% for small moduli [256 or
+     512 bits], about 30% for larger ones [1024 or 2048 bits].)
+     [Bodo Moeller]
+
+  *) New function BN_kronecker.
+     [Bodo Moeller]
+
+  *) Fix BN_gcd so that it works on negative inputs; the result is
+     positive unless both parameters are zero.
+     Previously something reasonably close to an infinite loop was
+     possible because numbers could be growing instead of shrinking
+     in the implementation of Euclid's algorithm.
+     [Bodo Moeller]
+
+  *) Fix BN_is_word() and BN_is_one() macros to take into account the
+     sign of the number in question.
+
+     Fix BN_is_word(a,w) to work correctly for w == 0.
+
+     The old BN_is_word(a,w) macro is now called BN_abs_is_word(a,w)
+     because its test if the absolute value of 'a' equals 'w'.
+     Note that BN_abs_is_word does *not* handle w == 0 reliably;
+     it exists mostly for use in the implementations of BN_is_zero(),
+     BN_is_one(), and BN_is_word().
+     [Bodo Moeller]
+
+  *) New function BN_swap.
+     [Bodo Moeller]
+
+  *) Use BN_nnmod instead of BN_mod in crypto/bn/bn_exp.c so that
+     the exponentiation functions are more likely to produce reasonable
+     results on negative inputs.
+     [Bodo Moeller]
+
+  *) Change BN_mod_mul so that the result is always non-negative.
+     Previously, it could be negative if one of the factors was negative;
+     I don't think anyone really wanted that behaviour.
+     [Bodo Moeller]
+
+  *) Move BN_mod_... functions into new file crypto/bn/bn_mod.c
+     (except for exponentiation, which stays in crypto/bn/bn_exp.c,
+     and BN_mod_mul_reciprocal, which stays in crypto/bn/bn_recp.c)
+     and add new functions:
+
+          BN_nnmod
+          BN_mod_sqr
+          BN_mod_add
+          BN_mod_add_quick
+          BN_mod_sub
+          BN_mod_sub_quick
+          BN_mod_lshift1
+          BN_mod_lshift1_quick
+          BN_mod_lshift
+          BN_mod_lshift_quick
+
+     These functions always generate non-negative results.
+
+     BN_nnmod otherwise is like BN_mod (if BN_mod computes a remainder  r
+     such that  |m| < r < 0,  BN_nnmod will output  rem + |m|  instead).
+
+     BN_mod_XXX_quick(r, a, [b,] m) generates the same result as
+     BN_mod_XXX(r, a, [b,] m, ctx), but requires that  a  [and  b]
+     be reduced modulo  m.
+     [Lenka Fibikova <fibikova@exp-math.uni-essen.de>, Bodo Moeller]
+
+#if 0
+     The following entry accidentily appeared in the CHANGES file
+     distributed with OpenSSL 0.9.7.  The modifications described in
+     it do *not* apply to OpenSSL 0.9.7.
+
+  *) Remove a few calls to bn_wexpand() in BN_sqr() (the one in there
+     was actually never needed) and in BN_mul().  The removal in BN_mul()
+     required a small change in bn_mul_part_recursive() and the addition
+     of the functions bn_cmp_part_words(), bn_sub_part_words() and
+     bn_add_part_words(), which do the same thing as bn_cmp_words(),
+     bn_sub_words() and bn_add_words() except they take arrays with
+     differing sizes.
+     [Richard Levitte]
+#endif
+
+  *) In 'openssl passwd', verify passwords read from the terminal
+     unless the '-salt' option is used (which usually means that
+     verification would just waste user's time since the resulting
+     hash is going to be compared with some given password hash)
+     or the new '-noverify' option is used.
+
+     This is an incompatible change, but it does not affect
+     non-interactive use of 'openssl passwd' (passwords on the command
+     line, '-stdin' option, '-in ...' option) and thus should not
+     cause any problems.
+     [Bodo Moeller]
+
+  *) Remove all references to RSAref, since there's no more need for it.
+     [Richard Levitte]
+
+  *) Make DSO load along a path given through an environment variable
+     (SHLIB_PATH) with shl_load().
+     [Richard Levitte]
+
+  *) Constify the ENGINE code as a result of BIGNUM constification.
+     Also constify the RSA code and most things related to it.  In a
+     few places, most notable in the depth of the ASN.1 code, ugly
+     casts back to non-const were required (to be solved at a later
+     time)
+     [Richard Levitte]
+
+  *) Make it so the openssl application has all engines loaded by default.
+     [Richard Levitte]
+
+  *) Constify the BIGNUM routines a little more.
+     [Richard Levitte]
+
+  *) Add the following functions:
+
+	ENGINE_load_cswift()
+	ENGINE_load_chil()
+	ENGINE_load_atalla()
+	ENGINE_load_nuron()
+	ENGINE_load_builtin_engines()
+
+     That way, an application can itself choose if external engines that
+     are built-in in OpenSSL shall ever be used or not.  The benefit is
+     that applications won't have to be linked with libdl or other dso
+     libraries unless it's really needed.
+
+     Changed 'openssl engine' to load all engines on demand.
+     Changed the engine header files to avoid the duplication of some
+     declarations (they differed!).
+     [Richard Levitte]
+
+  *) 'openssl engine' can now list capabilities.
+     [Richard Levitte]
+
+  *) Better error reporting in 'openssl engine'.
+     [Richard Levitte]
+
+  *) Never call load_dh_param(NULL) in s_server.
+     [Bodo Moeller]
+
+  *) Add engine application.  It can currently list engines by name and
+     identity, and test if they are actually available.
+     [Richard Levitte]
+
+  *) Improve RPM specification file by forcing symbolic linking and making
+     sure the installed documentation is also owned by root.root.
+     [Damien Miller <djm@mindrot.org>]
+
+  *) Give the OpenSSL applications more possibilities to make use of
+     keys (public as well as private) handled by engines.
+     [Richard Levitte]
+
+  *) Add OCSP code that comes from CertCo.
+     [Richard Levitte]
+
+  *) Add VMS support for the Rijndael code.
+     [Richard Levitte]
+
+  *) Added untested support for Nuron crypto accelerator.
+     [Ben Laurie]
+
+  *) Add support for external cryptographic devices.  This code was
+     previously distributed separately as the "engine" branch.
+     [Geoff Thorpe, Richard Levitte]
+
+  *) Rework the filename-translation in the DSO code. It is now possible to
+     have far greater control over how a "name" is turned into a filename
+     depending on the operating environment and any oddities about the
+     different shared library filenames on each system.
+     [Geoff Thorpe]
+
+  *) Support threads on FreeBSD-elf in Configure.
+     [Richard Levitte]
+
+  *) Fix for SHA1 assembly problem with MASM: it produces
+     warnings about corrupt line number information when assembling
+     with debugging information. This is caused by the overlapping
+     of two sections.
+     [Bernd Matthes <mainbug@celocom.de>, Steve Henson]
+
+  *) NCONF changes.
+     NCONF_get_number() has no error checking at all.  As a replacement,
+     NCONF_get_number_e() is defined (_e for "error checking") and is
+     promoted strongly.  The old NCONF_get_number is kept around for
+     binary backward compatibility.
+     Make it possible for methods to load from something other than a BIO,
+     by providing a function pointer that is given a name instead of a BIO.
+     For example, this could be used to load configuration data from an
+     LDAP server.
+     [Richard Levitte]
+
+  *) Fix for non blocking accept BIOs. Added new I/O special reason
+     BIO_RR_ACCEPT to cover this case. Previously use of accept BIOs
+     with non blocking I/O was not possible because no retry code was
+     implemented. Also added new SSL code SSL_WANT_ACCEPT to cover
+     this case.
+     [Steve Henson]
+
+  *) Added the beginnings of Rijndael support.
+     [Ben Laurie]
+
+  *) Fix for bug in DirectoryString mask setting. Add support for
+     X509_NAME_print_ex() in 'req' and X509_print_ex() function
+     to allow certificate printing to more controllable, additional
+     'certopt' option to 'x509' to allow new printing options to be
+     set.
+     [Steve Henson]
+
+  *) Clean old EAY MD5 hack from e_os.h.
+     [Richard Levitte]
+
+ Changes between 0.9.6l and 0.9.6m  [17 Mar 2004]
+
+  *) Fix null-pointer assignment in do_change_cipher_spec() revealed
+     by using the Codenomicon TLS Test Tool (CVE-2004-0079)
+     [Joe Orton, Steve Henson]
+
+ Changes between 0.9.6k and 0.9.6l  [04 Nov 2003]
+
+  *) Fix additional bug revealed by the NISCC test suite:
+
+     Stop bug triggering large recursion when presented with
+     certain ASN.1 tags (CVE-2003-0851)
+     [Steve Henson]
+
+ Changes between 0.9.6j and 0.9.6k  [30 Sep 2003]
+
+  *) Fix various bugs revealed by running the NISCC test suite:
+
+     Stop out of bounds reads in the ASN1 code when presented with
+     invalid tags (CVE-2003-0543 and CVE-2003-0544).
+     
+     If verify callback ignores invalid public key errors don't try to check
+     certificate signature with the NULL public key.
+
+     [Steve Henson]
+
+  *) In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate
+     if the server requested one: as stated in TLS 1.0 and SSL 3.0
+     specifications.
+     [Steve Henson]
+
+  *) In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional
+     extra data after the compression methods not only for TLS 1.0
+     but also for SSL 3.0 (as required by the specification).
+     [Bodo Moeller; problem pointed out by Matthias Loepfe]
+
+  *) Change X509_certificate_type() to mark the key as exported/exportable
+     when it's 512 *bits* long, not 512 bytes.
+     [Richard Levitte]
+
+ Changes between 0.9.6i and 0.9.6j  [10 Apr 2003]
+
+  *) Countermeasure against the Klima-Pokorny-Rosa extension of
+     Bleichbacher's attack on PKCS #1 v1.5 padding: treat
+     a protocol version number mismatch like a decryption error
+     in ssl3_get_client_key_exchange (ssl/s3_srvr.c).
+     [Bodo Moeller]
+
+  *) Turn on RSA blinding by default in the default implementation
+     to avoid a timing attack. Applications that don't want it can call
+     RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING.
+     They would be ill-advised to do so in most cases.
+     [Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller]
+
+  *) Change RSA blinding code so that it works when the PRNG is not
+     seeded (in this case, the secret RSA exponent is abused as
+     an unpredictable seed -- if it is not unpredictable, there
+     is no point in blinding anyway).  Make RSA blinding thread-safe
+     by remembering the creator's thread ID in rsa->blinding and
+     having all other threads use local one-time blinding factors
+     (this requires more computation than sharing rsa->blinding, but
+     avoids excessive locking; and if an RSA object is not shared
+     between threads, blinding will still be very fast).
+     [Bodo Moeller]
+
+ Changes between 0.9.6h and 0.9.6i  [19 Feb 2003]
+
+  *) In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked
+     via timing by performing a MAC computation even if incorrrect
+     block cipher padding has been found.  This is a countermeasure
+     against active attacks where the attacker has to distinguish
+     between bad padding and a MAC verification error. (CVE-2003-0078)
+
+     [Bodo Moeller; problem pointed out by Brice Canvel (EPFL),
+     Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and
+     Martin Vuagnoux (EPFL, Ilion)]
+
+ Changes between 0.9.6g and 0.9.6h  [5 Dec 2002]
+
+  *) New function OPENSSL_cleanse(), which is used to cleanse a section of
+     memory from it's contents.  This is done with a counter that will
+     place alternating values in each byte.  This can be used to solve
+     two issues: 1) the removal of calls to memset() by highly optimizing
+     compilers, and 2) cleansing with other values than 0, since those can
+     be read through on certain media, for example a swap space on disk.
+     [Geoff Thorpe]
+
+  *) Bugfix: client side session caching did not work with external caching,
+     because the session->cipher setting was not restored when reloading
+     from the external cache. This problem was masked, when
+     SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG (part of SSL_OP_ALL) was set.
+     (Found by Steve Haslam <steve@araqnid.ddts.net>.)
+     [Lutz Jaenicke]
+
+  *) Fix client_certificate (ssl/s2_clnt.c): The permissible total
+     length of the REQUEST-CERTIFICATE message is 18 .. 34, not 17 .. 33.
+     [Zeev Lieber <zeev-l@yahoo.com>]
+
+  *) Undo an undocumented change introduced in 0.9.6e which caused
+     repeated calls to OpenSSL_add_all_ciphers() and 
+     OpenSSL_add_all_digests() to be ignored, even after calling
+     EVP_cleanup().
+     [Richard Levitte]
+
+  *) Change the default configuration reader to deal with last line not
+     being properly terminated.
+     [Richard Levitte]
+
+  *) Change X509_NAME_cmp() so it applies the special rules on handling
+     DN values that are of type PrintableString, as well as RDNs of type
+     emailAddress where the value has the type ia5String.
+     [stefank@valicert.com via Richard Levitte]
+
+  *) Add a SSL_SESS_CACHE_NO_INTERNAL_STORE flag to take over half
+     the job SSL_SESS_CACHE_NO_INTERNAL_LOOKUP was inconsistently
+     doing, define a new flag (SSL_SESS_CACHE_NO_INTERNAL) to be
+     the bitwise-OR of the two for use by the majority of applications
+     wanting this behaviour, and update the docs. The documented
+     behaviour and actual behaviour were inconsistent and had been
+     changing anyway, so this is more a bug-fix than a behavioural
+     change.
+     [Geoff Thorpe, diagnosed by Nadav Har'El]
+
+  *) Don't impose a 16-byte length minimum on session IDs in ssl/s3_clnt.c
+     (the SSL 3.0 and TLS 1.0 specifications allow any length up to 32 bytes).
+     [Bodo Moeller]
+
+  *) Fix initialization code race conditions in
+        SSLv23_method(),  SSLv23_client_method(),   SSLv23_server_method(),
+        SSLv2_method(),   SSLv2_client_method(),    SSLv2_server_method(),
+        SSLv3_method(),   SSLv3_client_method(),    SSLv3_server_method(),
+        TLSv1_method(),   TLSv1_client_method(),    TLSv1_server_method(),
+        ssl2_get_cipher_by_char(),
+        ssl3_get_cipher_by_char().
+     [Patrick McCormick <patrick@tellme.com>, Bodo Moeller]
+
+  *) Reorder cleanup sequence in SSL_CTX_free(): only remove the ex_data after
+     the cached sessions are flushed, as the remove_cb() might use ex_data
+     contents. Bug found by Sam Varshavchik <mrsam@courier-mta.com>
+     (see [openssl.org #212]).
+     [Geoff Thorpe, Lutz Jaenicke]
+
+  *) Fix typo in OBJ_txt2obj which incorrectly passed the content
+     length, instead of the encoding length to d2i_ASN1_OBJECT.
+     [Steve Henson]
+
+ Changes between 0.9.6f and 0.9.6g  [9 Aug 2002]
+
+  *) [In 0.9.6g-engine release:]
+     Fix crypto/engine/vendor_defns/cswift.h for WIN32 (use '_stdcall').
+     [Lynn Gazis <lgazis@rainbow.com>]
+
+ Changes between 0.9.6e and 0.9.6f  [8 Aug 2002]
+
+  *) Fix ASN1 checks. Check for overflow by comparing with LONG_MAX
+     and get fix the header length calculation.
+     [Florian Weimer <Weimer@CERT.Uni-Stuttgart.DE>,
+	Alon Kantor <alonk@checkpoint.com> (and others),
+	Steve Henson]
+
+  *) Use proper error handling instead of 'assertions' in buffer
+     overflow checks added in 0.9.6e.  This prevents DoS (the
+     assertions could call abort()).
+     [Arne Ansper <arne@ats.cyber.ee>, Bodo Moeller]
+
+ Changes between 0.9.6d and 0.9.6e  [30 Jul 2002]
+
+  *) Add various sanity checks to asn1_get_length() to reject
+     the ASN1 length bytes if they exceed sizeof(long), will appear
+     negative or the content length exceeds the length of the
+     supplied buffer.
+     [Steve Henson, Adi Stav <stav@mercury.co.il>, James Yonan <jim@ntlp.com>]
+
+  *) Fix cipher selection routines: ciphers without encryption had no flags
+     for the cipher strength set and where therefore not handled correctly
+     by the selection routines (PR #130).
+     [Lutz Jaenicke]
+
+  *) Fix EVP_dsa_sha macro.
+     [Nils Larsch]
+
+  *) New option
+          SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
+     for disabling the SSL 3.0/TLS 1.0 CBC vulnerability countermeasure
+     that was added in OpenSSL 0.9.6d.
+
+     As the countermeasure turned out to be incompatible with some
+     broken SSL implementations, the new option is part of SSL_OP_ALL.
+     SSL_OP_ALL is usually employed when compatibility with weird SSL
+     implementations is desired (e.g. '-bugs' option to 's_client' and
+     's_server'), so the new option is automatically set in many
+     applications.
+     [Bodo Moeller]
+
+  *) Changes in security patch:
+
+     Changes marked "(CHATS)" were sponsored by the Defense Advanced
+     Research Projects Agency (DARPA) and Air Force Research Laboratory,
+     Air Force Materiel Command, USAF, under agreement number
+     F30602-01-2-0537.
+
+  *) Add various sanity checks to asn1_get_length() to reject
+     the ASN1 length bytes if they exceed sizeof(long), will appear
+     negative or the content length exceeds the length of the
+     supplied buffer. (CVE-2002-0659)
+     [Steve Henson, Adi Stav <stav@mercury.co.il>, James Yonan <jim@ntlp.com>]
+
+  *) Assertions for various potential buffer overflows, not known to
+     happen in practice.
+     [Ben Laurie (CHATS)]
+
+  *) Various temporary buffers to hold ASCII versions of integers were
+     too small for 64 bit platforms. (CVE-2002-0655)
+     [Matthew Byng-Maddick <mbm@aldigital.co.uk> and Ben Laurie (CHATS)>
+
+  *) Remote buffer overflow in SSL3 protocol - an attacker could
+     supply an oversized session ID to a client. (CVE-2002-0656)
+     [Ben Laurie (CHATS)]
+
+  *) Remote buffer overflow in SSL2 protocol - an attacker could
+     supply an oversized client master key. (CVE-2002-0656)
+     [Ben Laurie (CHATS)]
+
+ Changes between 0.9.6c and 0.9.6d  [9 May 2002]
+
+  *) Fix crypto/asn1/a_sign.c so that 'parameters' is omitted (not
+     encoded as NULL) with id-dsa-with-sha1.
+     [Nils Larsch <nla@trustcenter.de>; problem pointed out by Bodo Moeller]
+
+  *) Check various X509_...() return values in apps/req.c.
+     [Nils Larsch <nla@trustcenter.de>]
+
+  *) Fix BASE64 decode (EVP_DecodeUpdate) for data with CR/LF ended lines:
+     an end-of-file condition would erronously be flagged, when the CRLF
+     was just at the end of a processed block. The bug was discovered when
+     processing data through a buffering memory BIO handing the data to a
+     BASE64-decoding BIO. Bug fund and patch submitted by Pavel Tsekov
+     <ptsekov@syntrex.com> and Nedelcho Stanev.
+     [Lutz Jaenicke]
+
+  *) Implement a countermeasure against a vulnerability recently found
+     in CBC ciphersuites in SSL 3.0/TLS 1.0: Send an empty fragment
+     before application data chunks to avoid the use of known IVs
+     with data potentially chosen by the attacker.
+     [Bodo Moeller]
+
+  *) Fix length checks in ssl3_get_client_hello().
+     [Bodo Moeller]
+
+  *) TLS/SSL library bugfix: use s->s3->in_read_app_data differently
+     to prevent ssl3_read_internal() from incorrectly assuming that
+     ssl3_read_bytes() found application data while handshake
+     processing was enabled when in fact s->s3->in_read_app_data was
+     merely automatically cleared during the initial handshake.
+     [Bodo Moeller; problem pointed out by Arne Ansper <arne@ats.cyber.ee>]
+
+  *) Fix object definitions for Private and Enterprise: they were not
+     recognized in their shortname (=lowercase) representation. Extend
+     obj_dat.pl to issue an error when using undefined keywords instead
+     of silently ignoring the problem (Svenning Sorensen
+     <sss@sss.dnsalias.net>).
+     [Lutz Jaenicke]
+
+  *) Fix DH_generate_parameters() so that it works for 'non-standard'
+     generators, i.e. generators other than 2 and 5.  (Previously, the
+     code did not properly initialise the 'add' and 'rem' values to
+     BN_generate_prime().)
+
+     In the new general case, we do not insist that 'generator' is
+     actually a primitive root: This requirement is rather pointless;
+     a generator of the order-q subgroup is just as good, if not
+     better.
+     [Bodo Moeller]
+ 
+  *) Map new X509 verification errors to alerts. Discovered and submitted by
+     Tom Wu <tom@arcot.com>.
+     [Lutz Jaenicke]
+
+  *) Fix ssl3_pending() (ssl/s3_lib.c) to prevent SSL_pending() from
+     returning non-zero before the data has been completely received
+     when using non-blocking I/O.
+     [Bodo Moeller; problem pointed out by John Hughes]
+
+  *) Some of the ciphers missed the strength entry (SSL_LOW etc).
+     [Ben Laurie, Lutz Jaenicke]
+
+  *) Fix bug in SSL_clear(): bad sessions were not removed (found by
+     Yoram Zahavi <YoramZ@gilian.com>).
+     [Lutz Jaenicke]
+
+  *) Add information about CygWin 1.3 and on, and preserve proper
+     configuration for the versions before that.
+     [Corinna Vinschen <vinschen@redhat.com> and Richard Levitte]
+
+  *) Make removal from session cache (SSL_CTX_remove_session()) more robust:
+     check whether we deal with a copy of a session and do not delete from
+     the cache in this case. Problem reported by "Izhar Shoshani Levi"
+     <izhar@checkpoint.com>.
+     [Lutz Jaenicke]
+
+  *) Do not store session data into the internal session cache, if it
+     is never intended to be looked up (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
+     flag is set). Proposed by Aslam <aslam@funk.com>.
+     [Lutz Jaenicke]
+
+  *) Have ASN1_BIT_STRING_set_bit() really clear a bit when the requested
+     value is 0.
+     [Richard Levitte]
+
+  *) [In 0.9.6d-engine release:]
+     Fix a crashbug and a logic bug in hwcrhk_load_pubkey().
+     [Toomas Kiisk <vix@cyber.ee> via Richard Levitte]
+
+  *) Add the configuration target linux-s390x.
+     [Neale Ferguson <Neale.Ferguson@SoftwareAG-USA.com> via Richard Levitte]
+
+  *) The earlier bugfix for the SSL3_ST_SW_HELLO_REQ_C case of
+     ssl3_accept (ssl/s3_srvr.c) incorrectly used a local flag
+     variable as an indication that a ClientHello message has been
+     received.  As the flag value will be lost between multiple
+     invocations of ssl3_accept when using non-blocking I/O, the
+     function may not be aware that a handshake has actually taken
+     place, thus preventing a new session from being added to the
+     session cache.
+
+     To avoid this problem, we now set s->new_session to 2 instead of
+     using a local variable.
+     [Lutz Jaenicke, Bodo Moeller]
+
+  *) Bugfix: Return -1 from ssl3_get_server_done (ssl3/s3_clnt.c)
+     if the SSL_R_LENGTH_MISMATCH error is detected.
+     [Geoff Thorpe, Bodo Moeller]
+
+  *) New 'shared_ldflag' column in Configure platform table.
+     [Richard Levitte]
+
+  *) Fix EVP_CIPHER_mode macro.
+     ["Dan S. Camper" <dan@bti.net>]
+
+  *) Fix ssl3_read_bytes (ssl/s3_pkt.c): To ignore messages of unknown
+     type, we must throw them away by setting rr->length to 0.
+     [D P Chang <dpc@qualys.com>]
+
+ Changes between 0.9.6b and 0.9.6c  [21 dec 2001]
+
+  *) Fix BN_rand_range bug pointed out by Dominikus Scherkl
+     <Dominikus.Scherkl@biodata.com>.  (The previous implementation
+     worked incorrectly for those cases where  range = 10..._2  and
+     3*range  is two bits longer than  range.)
+     [Bodo Moeller]
+
+  *) Only add signing time to PKCS7 structures if it is not already
+     present.
+     [Steve Henson]
+
+  *) Fix crypto/objects/objects.h: "ld-ce" should be "id-ce",
+     OBJ_ld_ce should be OBJ_id_ce.
+     Also some ip-pda OIDs in crypto/objects/objects.txt were
+     incorrect (cf. RFC 3039).
+     [Matt Cooper, Frederic Giudicelli, Bodo Moeller]
+
+  *) Release CRYPTO_LOCK_DYNLOCK when CRYPTO_destroy_dynlockid()
+     returns early because it has nothing to do.
+     [Andy Schneider <andy.schneider@bjss.co.uk>]
+
+  *) [In 0.9.6c-engine release:]
+     Fix mutex callback return values in crypto/engine/hw_ncipher.c.
+     [Andy Schneider <andy.schneider@bjss.co.uk>]
+
+  *) [In 0.9.6c-engine release:]
+     Add support for Cryptographic Appliance's keyserver technology.
+     (Use engine 'keyclient')
+     [Cryptographic Appliances and Geoff Thorpe]
+
+  *) Add a configuration entry for OS/390 Unix.  The C compiler 'c89'
+     is called via tools/c89.sh because arguments have to be
+     rearranged (all '-L' options must appear before the first object
+     modules).
+     [Richard Shapiro <rshapiro@abinitio.com>]
+
+  *) [In 0.9.6c-engine release:]
+     Add support for Broadcom crypto accelerator cards, backported
+     from 0.9.7.
+     [Broadcom, Nalin Dahyabhai <nalin@redhat.com>, Mark Cox]
+
+  *) [In 0.9.6c-engine release:]
+     Add support for SureWare crypto accelerator cards from 
+     Baltimore Technologies.  (Use engine 'sureware')
+     [Baltimore Technologies and Mark Cox]
+
+  *) [In 0.9.6c-engine release:]
+     Add support for crypto accelerator cards from Accelerated
+     Encryption Processing, www.aep.ie.  (Use engine 'aep')
+     [AEP Inc. and Mark Cox]
+
+  *) Add a configuration entry for gcc on UnixWare.
+     [Gary Benson <gbenson@redhat.com>]
+
+  *) Change ssl/s2_clnt.c and ssl/s2_srvr.c so that received handshake
+     messages are stored in a single piece (fixed-length part and
+     variable-length part combined) and fix various bugs found on the way.
+     [Bodo Moeller]
+
+  *) Disable caching in BIO_gethostbyname(), directly use gethostbyname()
+     instead.  BIO_gethostbyname() does not know what timeouts are
+     appropriate, so entries would stay in cache even when they have
+     become invalid.
+     [Bodo Moeller; problem pointed out by Rich Salz <rsalz@zolera.com>
+
+  *) Change ssl23_get_client_hello (ssl/s23_srvr.c) behaviour when
+     faced with a pathologically small ClientHello fragment that does
+     not contain client_version: Instead of aborting with an error,
+     simply choose the highest available protocol version (i.e.,
+     TLS 1.0 unless it is disabled).  In practice, ClientHello
+     messages are never sent like this, but this change gives us
+     strictly correct behaviour at least for TLS.
+     [Bodo Moeller]
+
+  *) Fix SSL handshake functions and SSL_clear() such that SSL_clear()
+     never resets s->method to s->ctx->method when called from within
+     one of the SSL handshake functions.
+     [Bodo Moeller; problem pointed out by Niko Baric]
+
+  *) In ssl3_get_client_hello (ssl/s3_srvr.c), generate a fatal alert
+     (sent using the client's version number) if client_version is
+     smaller than the protocol version in use.  Also change
+     ssl23_get_client_hello (ssl/s23_srvr.c) to select TLS 1.0 if
+     the client demanded SSL 3.0 but only TLS 1.0 is enabled; then
+     the client will at least see that alert.
+     [Bodo Moeller]
+
+  *) Fix ssl3_get_message (ssl/s3_both.c) to handle message fragmentation
+     correctly.
+     [Bodo Moeller]
+
+  *) Avoid infinite loop in ssl3_get_message (ssl/s3_both.c) if a
+     client receives HelloRequest while in a handshake.
+     [Bodo Moeller; bug noticed by Andy Schneider <andy.schneider@bjss.co.uk>]
+
+  *) Bugfix in ssl3_accept (ssl/s3_srvr.c): Case SSL3_ST_SW_HELLO_REQ_C
+     should end in 'break', not 'goto end' which circuments various
+     cleanups done in state SSL_ST_OK.   But session related stuff
+     must be disabled for SSL_ST_OK in the case that we just sent a
+     HelloRequest.
+
+     Also avoid some overhead by not calling ssl_init_wbio_buffer()
+     before just sending a HelloRequest.
+     [Bodo Moeller, Eric Rescorla <ekr@rtfm.com>]
+
+  *) Fix ssl/s3_enc.c, ssl/t1_enc.c and ssl/s3_pkt.c so that we don't
+     reveal whether illegal block cipher padding was found or a MAC
+     verification error occured.  (Neither SSLerr() codes nor alerts
+     are directly visible to potential attackers, but the information
+     may leak via logfiles.)
+
+     Similar changes are not required for the SSL 2.0 implementation
+     because the number of padding bytes is sent in clear for SSL 2.0,
+     and the extra bytes are just ignored.  However ssl/s2_pkt.c
+     failed to verify that the purported number of padding bytes is in
+     the legal range.
+     [Bodo Moeller]
+
+  *) Add OpenUNIX-8 support including shared libraries
+     (Boyd Lynn Gerber <gerberb@zenez.com>).
+     [Lutz Jaenicke]
+
+  *) Improve RSA_padding_check_PKCS1_OAEP() check again to avoid
+     'wristwatch attack' using huge encoding parameters (cf.
+     James H. Manger's CRYPTO 2001 paper).  Note that the
+     RSA_PKCS1_OAEP_PADDING case of RSA_private_decrypt() does not use
+     encoding parameters and hence was not vulnerable.
+     [Bodo Moeller]
+
+  *) BN_sqr() bug fix.
+     [Ulf Möller, reported by Jim Ellis <jim.ellis@cavium.com>]
+
+  *) Rabin-Miller test analyses assume uniformly distributed witnesses,
+     so use BN_pseudo_rand_range() instead of using BN_pseudo_rand()
+     followed by modular reduction.
+     [Bodo Moeller; pointed out by Adam Young <AYoung1@NCSUS.JNJ.COM>]
+
+  *) Add BN_pseudo_rand_range() with obvious functionality: BN_rand_range()
+     equivalent based on BN_pseudo_rand() instead of BN_rand().
+     [Bodo Moeller]
+
+  *) s3_srvr.c: allow sending of large client certificate lists (> 16 kB).
+     This function was broken, as the check for a new client hello message
+     to handle SGC did not allow these large messages.
+     (Tracked down by "Douglas E. Engert" <deengert@anl.gov>.)
+     [Lutz Jaenicke]
+
+  *) Add alert descriptions for TLSv1 to SSL_alert_desc_string[_long]().
+     [Lutz Jaenicke]
+
+  *) Fix buggy behaviour of BIO_get_num_renegotiates() and BIO_ctrl()
+     for BIO_C_GET_WRITE_BUF_SIZE ("Stephen Hinton" <shinton@netopia.com>).
+     [Lutz Jaenicke]
+
+  *) Rework the configuration and shared library support for Tru64 Unix.
+     The configuration part makes use of modern compiler features and
+     still retains old compiler behavior for those that run older versions
+     of the OS.  The shared library support part includes a variant that
+     uses the RPATH feature, and is available through the special
+     configuration target "alpha-cc-rpath", which will never be selected
+     automatically.
+     [Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu> via Richard Levitte]
+
+  *) In ssl3_get_key_exchange (ssl/s3_clnt.c), call ssl3_get_message()
+     with the same message size as in ssl3_get_certificate_request().
+     Otherwise, if no ServerKeyExchange message occurs, CertificateRequest
+     messages might inadvertently be reject as too long.
+     [Petr Lampa <lampa@fee.vutbr.cz>]
+
+  *) Enhanced support for IA-64 Unix platforms (well, Linux and HP-UX).
+     [Andy Polyakov]
+
+  *) Modified SSL library such that the verify_callback that has been set
+     specificly for an SSL object with SSL_set_verify() is actually being
+     used. Before the change, a verify_callback set with this function was
+     ignored and the verify_callback() set in the SSL_CTX at the time of
+     the call was used. New function X509_STORE_CTX_set_verify_cb() introduced
+     to allow the necessary settings.
+     [Lutz Jaenicke]
+
+  *) Initialize static variable in crypto/dsa/dsa_lib.c and crypto/dh/dh_lib.c
+     explicitly to NULL, as at least on Solaris 8 this seems not always to be
+     done automatically (in contradiction to the requirements of the C
+     standard). This made problems when used from OpenSSH.
+     [Lutz Jaenicke]
+
+  *) In OpenSSL 0.9.6a and 0.9.6b, crypto/dh/dh_key.c ignored
+     dh->length and always used
+
+          BN_rand_range(priv_key, dh->p).
+
+     BN_rand_range() is not necessary for Diffie-Hellman, and this
+     specific range makes Diffie-Hellman unnecessarily inefficient if
+     dh->length (recommended exponent length) is much smaller than the
+     length of dh->p.  We could use BN_rand_range() if the order of
+     the subgroup was stored in the DH structure, but we only have
+     dh->length.
+
+     So switch back to
+
+          BN_rand(priv_key, l, ...)
+
+     where 'l' is dh->length if this is defined, or BN_num_bits(dh->p)-1
+     otherwise.
+     [Bodo Moeller]
+
+  *) In
+
+          RSA_eay_public_encrypt
+          RSA_eay_private_decrypt
+          RSA_eay_private_encrypt (signing)
+          RSA_eay_public_decrypt (signature verification)
+
+     (default implementations for RSA_public_encrypt,
+     RSA_private_decrypt, RSA_private_encrypt, RSA_public_decrypt),
+     always reject numbers >= n.
+     [Bodo Moeller]
+
+  *) In crypto/rand/md_rand.c, use a new short-time lock CRYPTO_LOCK_RAND2
+     to synchronize access to 'locking_thread'.  This is necessary on
+     systems where access to 'locking_thread' (an 'unsigned long'
+     variable) is not atomic.
+     [Bodo Moeller]
+
+  *) In crypto/rand/md_rand.c, set 'locking_thread' to current thread's ID
+     *before* setting the 'crypto_lock_rand' flag.  The previous code had
+     a race condition if 0 is a valid thread ID.
+     [Travis Vitek <vitek@roguewave.com>]
+
+  *) Add support for shared libraries under Irix.
+     [Albert Chin-A-Young <china@thewrittenword.com>]
+
+  *) Add configuration option to build on Linux on both big-endian and
+     little-endian MIPS.
+     [Ralf Baechle <ralf@uni-koblenz.de>]
+
+  *) Add the possibility to create shared libraries on HP-UX.
+     [Richard Levitte]
+
+ Changes between 0.9.6a and 0.9.6b  [9 Jul 2001]
+
+  *) Change ssleay_rand_bytes (crypto/rand/md_rand.c)
+     to avoid a SSLeay/OpenSSL PRNG weakness pointed out by
+     Markku-Juhani O. Saarinen <markku-juhani.saarinen@nokia.com>:
+     PRNG state recovery was possible based on the output of
+     one PRNG request appropriately sized to gain knowledge on
+     'md' followed by enough consecutive 1-byte PRNG requests
+     to traverse all of 'state'.
+
+     1. When updating 'md_local' (the current thread's copy of 'md')
+        during PRNG output generation, hash all of the previous
+        'md_local' value, not just the half used for PRNG output.
+
+     2. Make the number of bytes from 'state' included into the hash
+        independent from the number of PRNG bytes requested.
+
+     The first measure alone would be sufficient to avoid
+     Markku-Juhani's attack.  (Actually it had never occurred
+     to me that the half of 'md_local' used for chaining was the
+     half from which PRNG output bytes were taken -- I had always
+     assumed that the secret half would be used.)  The second
+     measure makes sure that additional data from 'state' is never
+     mixed into 'md_local' in small portions; this heuristically
+     further strengthens the PRNG.
+     [Bodo Moeller]
+
+  *) Fix crypto/bn/asm/mips3.s.
+     [Andy Polyakov]
+
+  *) When only the key is given to "enc", the IV is undefined. Print out
+     an error message in this case.
+     [Lutz Jaenicke]
+
+  *) Handle special case when X509_NAME is empty in X509 printing routines.
+     [Steve Henson]
+
+  *) In dsa_do_verify (crypto/dsa/dsa_ossl.c), verify that r and s are
+     positive and less than q.
+     [Bodo Moeller]
+
+  *) Don't change *pointer in CRYPTO_add_lock() is add_lock_callback is
+     used: it isn't thread safe and the add_lock_callback should handle
+     that itself.
+     [Paul Rose <Paul.Rose@bridge.com>]
+
+  *) Verify that incoming data obeys the block size in
+     ssl3_enc (ssl/s3_enc.c) and tls1_enc (ssl/t1_enc.c).
+     [Bodo Moeller]
+
+  *) Fix OAEP check.
+     [Ulf Möller, Bodo Möller]
+
+  *) The countermeasure against Bleichbacher's attack on PKCS #1 v1.5
+     RSA encryption was accidentally removed in s3_srvr.c in OpenSSL 0.9.5
+     when fixing the server behaviour for backwards-compatible 'client
+     hello' messages.  (Note that the attack is impractical against
+     SSL 3.0 and TLS 1.0 anyway because length and version checking
+     means that the probability of guessing a valid ciphertext is
+     around 2^-40; see section 5 in Bleichenbacher's CRYPTO '98
+     paper.)
+
+     Before 0.9.5, the countermeasure (hide the error by generating a
+     random 'decryption result') did not work properly because
+     ERR_clear_error() was missing, meaning that SSL_get_error() would
+     detect the supposedly ignored error.
+
+     Both problems are now fixed.
+     [Bodo Moeller]
+
+  *) In crypto/bio/bf_buff.c, increase DEFAULT_BUFFER_SIZE to 4096
+     (previously it was 1024).
+     [Bodo Moeller]
+
+  *) Fix for compatibility mode trust settings: ignore trust settings
+     unless some valid trust or reject settings are present.
+     [Steve Henson]
+
+  *) Fix for blowfish EVP: its a variable length cipher.
+     [Steve Henson]
+
+  *) Fix various bugs related to DSA S/MIME verification. Handle missing
+     parameters in DSA public key structures and return an error in the
+     DSA routines if parameters are absent.
+     [Steve Henson]
+
+  *) In versions up to 0.9.6, RAND_file_name() resorted to file ".rnd"
+     in the current directory if neither $RANDFILE nor $HOME was set.
+     RAND_file_name() in 0.9.6a returned NULL in this case.  This has
+     caused some confusion to Windows users who haven't defined $HOME.
+     Thus RAND_file_name() is changed again: e_os.h can define a
+     DEFAULT_HOME, which will be used if $HOME is not set.
+     For Windows, we use "C:"; on other platforms, we still require
+     environment variables.
+
+  *) Move 'if (!initialized) RAND_poll()' into regions protected by
+     CRYPTO_LOCK_RAND.  This is not strictly necessary, but avoids
+     having multiple threads call RAND_poll() concurrently.
+     [Bodo Moeller]
+
+  *) In crypto/rand/md_rand.c, replace 'add_do_not_lock' flag by a
+     combination of a flag and a thread ID variable.
+     Otherwise while one thread is in ssleay_rand_bytes (which sets the
+     flag), *other* threads can enter ssleay_add_bytes without obeying
+     the CRYPTO_LOCK_RAND lock (and may even illegally release the lock
+     that they do not hold after the first thread unsets add_do_not_lock).
+     [Bodo Moeller]
+
+  *) Change bctest again: '-x' expressions are not available in all
+     versions of 'test'.
+     [Bodo Moeller]
+
+ Changes between 0.9.6 and 0.9.6a  [5 Apr 2001]
+
+  *) Fix a couple of memory leaks in PKCS7_dataDecode()
+     [Steve Henson, reported by Heyun Zheng <hzheng@atdsprint.com>]
+
+  *) Change Configure and Makefiles to provide EXE_EXT, which will contain
+     the default extension for executables, if any.  Also, make the perl
+     scripts that use symlink() to test if it really exists and use "cp"
+     if it doesn't.  All this made OpenSSL compilable and installable in
+     CygWin.
+     [Richard Levitte]
+
+  *) Fix for asn1_GetSequence() for indefinite length constructed data.
+     If SEQUENCE is length is indefinite just set c->slen to the total
+     amount of data available.
+     [Steve Henson, reported by shige@FreeBSD.org]
+     [This change does not apply to 0.9.7.]
+
+  *) Change bctest to avoid here-documents inside command substitution
+     (workaround for FreeBSD /bin/sh bug).
+     For compatibility with Ultrix, avoid shell functions (introduced
+     in the bctest version that searches along $PATH).
+     [Bodo Moeller]
+
+  *) Rename 'des_encrypt' to 'des_encrypt1'.  This avoids the clashes
+     with des_encrypt() defined on some operating systems, like Solaris
+     and UnixWare.
+     [Richard Levitte]
+
+  *) Check the result of RSA-CRT (see D. Boneh, R. DeMillo, R. Lipton:
+     On the Importance of Eliminating Errors in Cryptographic
+     Computations, J. Cryptology 14 (2001) 2, 101-119,
+     http://theory.stanford.edu/~dabo/papers/faults.ps.gz).
+     [Ulf Moeller]
+  
+  *) MIPS assembler BIGNUM division bug fix. 
+     [Andy Polyakov]
+
+  *) Disabled incorrect Alpha assembler code.
+     [Richard Levitte]
+
+  *) Fix PKCS#7 decode routines so they correctly update the length
+     after reading an EOC for the EXPLICIT tag.
+     [Steve Henson]
+     [This change does not apply to 0.9.7.]
+
+  *) Fix bug in PKCS#12 key generation routines. This was triggered
+     if a 3DES key was generated with a 0 initial byte. Include
+     PKCS12_BROKEN_KEYGEN compilation option to retain the old
+     (but broken) behaviour.
+     [Steve Henson]
+
+  *) Enhance bctest to search for a working bc along $PATH and print
+     it when found.
+     [Tim Rice <tim@multitalents.net> via Richard Levitte]
+
+  *) Fix memory leaks in err.c: free err_data string if necessary;
+     don't write to the wrong index in ERR_set_error_data.
+     [Bodo Moeller]
+
+  *) Implement ssl23_peek (analogous to ssl23_read), which previously
+     did not exist.
+     [Bodo Moeller]
+
+  *) Replace rdtsc with _emit statements for VC++ version 5.
+     [Jeremy Cooper <jeremy@baymoo.org>]
+
+  *) Make it possible to reuse SSLv2 sessions.
+     [Richard Levitte]
+
+  *) In copy_email() check for >= 0 as a return value for
+     X509_NAME_get_index_by_NID() since 0 is a valid index.
+     [Steve Henson reported by Massimiliano Pala <madwolf@opensca.org>]
+
+  *) Avoid coredump with unsupported or invalid public keys by checking if
+     X509_get_pubkey() fails in PKCS7_verify(). Fix memory leak when
+     PKCS7_verify() fails with non detached data.
+     [Steve Henson]
+
+  *) Don't use getenv in library functions when run as setuid/setgid.
+     New function OPENSSL_issetugid().
+     [Ulf Moeller]
+
+  *) Avoid false positives in memory leak detection code (crypto/mem_dbg.c)
+     due to incorrect handling of multi-threading:
+
+     1. Fix timing glitch in the MemCheck_off() portion of CRYPTO_mem_ctrl().
+
+     2. Fix logical glitch in is_MemCheck_on() aka CRYPTO_is_mem_check_on().
+
+     3. Count how many times MemCheck_off() has been called so that
+        nested use can be treated correctly.  This also avoids 
+        inband-signalling in the previous code (which relied on the
+        assumption that thread ID 0 is impossible).
+     [Bodo Moeller]
+
+  *) Add "-rand" option also to s_client and s_server.
+     [Lutz Jaenicke]
+
+  *) Fix CPU detection on Irix 6.x.
+     [Kurt Hockenbury <khockenb@stevens-tech.edu> and
+      "Bruce W. Forsberg" <bruce.forsberg@baesystems.com>]
+
+  *) Fix X509_NAME bug which produced incorrect encoding if X509_NAME
+     was empty.
+     [Steve Henson]
+     [This change does not apply to 0.9.7.]
+
+  *) Use the cached encoding of an X509_NAME structure rather than
+     copying it. This is apparently the reason for the libsafe "errors"
+     but the code is actually correct.
+     [Steve Henson]
+
+  *) Add new function BN_rand_range(), and fix DSA_sign_setup() to prevent
+     Bleichenbacher's DSA attack.
+     Extend BN_[pseudo_]rand: As before, top=1 forces the highest two bits
+     to be set and top=0 forces the highest bit to be set; top=-1 is new
+     and leaves the highest bit random.
+     [Ulf Moeller, Bodo Moeller]
+
+  *) In the NCONF_...-based implementations for CONF_... queries
+     (crypto/conf/conf_lib.c), if the input LHASH is NULL, avoid using
+     a temporary CONF structure with the data component set to NULL
+     (which gives segmentation faults in lh_retrieve).
+     Instead, use NULL for the CONF pointer in CONF_get_string and
+     CONF_get_number (which may use environment variables) and directly
+     return NULL from CONF_get_section.
+     [Bodo Moeller]
+
+  *) Fix potential buffer overrun for EBCDIC.
+     [Ulf Moeller]
+
+  *) Tolerate nonRepudiation as being valid for S/MIME signing and certSign
+     keyUsage if basicConstraints absent for a CA.
+     [Steve Henson]
+
+  *) Make SMIME_write_PKCS7() write mail header values with a format that
+     is more generally accepted (no spaces before the semicolon), since
+     some programs can't parse those values properly otherwise.  Also make
+     sure BIO's that break lines after each write do not create invalid
+     headers.
+     [Richard Levitte]
+
+  *) Make the CRL encoding routines work with empty SEQUENCE OF. The
+     macros previously used would not encode an empty SEQUENCE OF
+     and break the signature.
+     [Steve Henson]
+     [This change does not apply to 0.9.7.]
+
+  *) Zero the premaster secret after deriving the master secret in
+     DH ciphersuites.
+     [Steve Henson]
+
+  *) Add some EVP_add_digest_alias registrations (as found in
+     OpenSSL_add_all_digests()) to SSL_library_init()
+     aka OpenSSL_add_ssl_algorithms().  This provides improved
+     compatibility with peers using X.509 certificates
+     with unconventional AlgorithmIdentifier OIDs.
+     [Bodo Moeller]
+
+  *) Fix for Irix with NO_ASM.
+     ["Bruce W. Forsberg" <bruce.forsberg@baesystems.com>]
+
+  *) ./config script fixes.
+     [Ulf Moeller, Richard Levitte]
+
+  *) Fix 'openssl passwd -1'.
+     [Bodo Moeller]
+
+  *) Change PKCS12_key_gen_asc() so it can cope with non null
+     terminated strings whose length is passed in the passlen
+     parameter, for example from PEM callbacks. This was done
+     by adding an extra length parameter to asc2uni().
+     [Steve Henson, reported by <oddissey@samsung.co.kr>]
+
+  *) Fix C code generated by 'openssl dsaparam -C': If a BN_bin2bn
+     call failed, free the DSA structure.
+     [Bodo Moeller]
+
+  *) Fix to uni2asc() to cope with zero length Unicode strings.
+     These are present in some PKCS#12 files.
+     [Steve Henson]
+
+  *) Increase s2->wbuf allocation by one byte in ssl2_new (ssl/s2_lib.c).
+     Otherwise do_ssl_write (ssl/s2_pkt.c) will write beyond buffer limits
+     when writing a 32767 byte record.
+     [Bodo Moeller; problem reported by Eric Day <eday@concentric.net>]
+
+  *) In RSA_eay_public_{en,ed}crypt and RSA_eay_mod_exp (rsa_eay.c),
+     obtain lock CRYPTO_LOCK_RSA before setting rsa->_method_mod_{n,p,q}.
+
+     (RSA objects have a reference count access to which is protected
+     by CRYPTO_LOCK_RSA [see rsa_lib.c, s3_srvr.c, ssl_cert.c, ssl_rsa.c],
+     so they are meant to be shared between threads.)
+     [Bodo Moeller, Geoff Thorpe; original patch submitted by
+     "Reddie, Steven" <Steven.Reddie@ca.com>]
+
+  *) Fix a deadlock in CRYPTO_mem_leaks().
+     [Bodo Moeller]
+
+  *) Use better test patterns in bntest.
+     [Ulf Möller]
+
+  *) rand_win.c fix for Borland C.
+     [Ulf Möller]
+ 
+  *) BN_rshift bugfix for n == 0.
+     [Bodo Moeller]
+
+  *) Add a 'bctest' script that checks for some known 'bc' bugs
+     so that 'make test' does not abort just because 'bc' is broken.
+     [Bodo Moeller]
+
+  *) Store verify_result within SSL_SESSION also for client side to
+     avoid potential security hole. (Re-used sessions on the client side
+     always resulted in verify_result==X509_V_OK, not using the original
+     result of the server certificate verification.)
+     [Lutz Jaenicke]
+
+  *) Fix ssl3_pending: If the record in s->s3->rrec is not of type
+     SSL3_RT_APPLICATION_DATA, return 0.
+     Similarly, change ssl2_pending to return 0 if SSL_in_init(s) is true.
+     [Bodo Moeller]
+
+  *) Fix SSL_peek:
+     Both ssl2_peek and ssl3_peek, which were totally broken in earlier
+     releases, have been re-implemented by renaming the previous
+     implementations of ssl2_read and ssl3_read to ssl2_read_internal
+     and ssl3_read_internal, respectively, and adding 'peek' parameters
+     to them.  The new ssl[23]_{read,peek} functions are calls to
+     ssl[23]_read_internal with the 'peek' flag set appropriately.
+     A 'peek' parameter has also been added to ssl3_read_bytes, which
+     does the actual work for ssl3_read_internal.
+     [Bodo Moeller]
+
+  *) Initialise "ex_data" member of RSA/DSA/DH structures prior to calling
+     the method-specific "init()" handler. Also clean up ex_data after
+     calling the method-specific "finish()" handler. Previously, this was
+     happening the other way round.
+     [Geoff Thorpe]
+
+  *) Increase BN_CTX_NUM (the number of BIGNUMs in a BN_CTX) to 16.
+     The previous value, 12, was not always sufficient for BN_mod_exp().
+     [Bodo Moeller]
+
+  *) Make sure that shared libraries get the internal name engine with
+     the full version number and not just 0.  This should mark the
+     shared libraries as not backward compatible.  Of course, this should
+     be changed again when we can guarantee backward binary compatibility.
+     [Richard Levitte]
+
+  *) Fix typo in get_cert_by_subject() in by_dir.c
+     [Jean-Marc Desperrier <jean-marc.desperrier@certplus.com>]
+
+  *) Rework the system to generate shared libraries:
+
+     - Make note of the expected extension for the shared libraries and
+       if there is a need for symbolic links from for example libcrypto.so.0
+       to libcrypto.so.0.9.7.  There is extended info in Configure for
+       that.
+
+     - Make as few rebuilds of the shared libraries as possible.
+
+     - Still avoid linking the OpenSSL programs with the shared libraries.
+
+     - When installing, install the shared libraries separately from the
+       static ones.
+     [Richard Levitte]
+
+  *) Fix SSL_CTX_set_read_ahead macro to actually use its argument.
+
+     Copy SSL_CTX's read_ahead flag to SSL object directly in SSL_new
+     and not in SSL_clear because the latter is also used by the
+     accept/connect functions; previously, the settings made by
+     SSL_set_read_ahead would be lost during the handshake.
+     [Bodo Moeller; problems reported by Anders Gertz <gertz@epact.se>]     
+
+  *) Correct util/mkdef.pl to be selective about disabled algorithms.
+     Previously, it would create entries for disableed algorithms no
+     matter what.
+     [Richard Levitte]
+
+  *) Added several new manual pages for SSL_* function.
+     [Lutz Jaenicke]
+
+ Changes between 0.9.5a and 0.9.6  [24 Sep 2000]
+
+  *) In ssl23_get_client_hello, generate an error message when faced
+     with an initial SSL 3.0/TLS record that is too small to contain the
+     first two bytes of the ClientHello message, i.e. client_version.
+     (Note that this is a pathologic case that probably has never happened
+     in real life.)  The previous approach was to use the version number
+     from the record header as a substitute; but our protocol choice
+     should not depend on that one because it is not authenticated
+     by the Finished messages.
+     [Bodo Moeller]
+
+  *) More robust randomness gathering functions for Windows.
+     [Jeffrey Altman <jaltman@columbia.edu>]
+
+  *) For compatibility reasons if the flag X509_V_FLAG_ISSUER_CHECK is
+     not set then we don't setup the error code for issuer check errors
+     to avoid possibly overwriting other errors which the callback does
+     handle. If an application does set the flag then we assume it knows
+     what it is doing and can handle the new informational codes
+     appropriately.
+     [Steve Henson]
+
+  *) Fix for a nasty bug in ASN1_TYPE handling. ASN1_TYPE is used for
+     a general "ANY" type, as such it should be able to decode anything
+     including tagged types. However it didn't check the class so it would
+     wrongly interpret tagged types in the same way as their universal
+     counterpart and unknown types were just rejected. Changed so that the
+     tagged and unknown types are handled in the same way as a SEQUENCE:
+     that is the encoding is stored intact. There is also a new type
+     "V_ASN1_OTHER" which is used when the class is not universal, in this
+     case we have no idea what the actual type is so we just lump them all
+     together.
+     [Steve Henson]
+
+  *) On VMS, stdout may very well lead to a file that is written to
+     in a record-oriented fashion.  That means that every write() will
+     write a separate record, which will be read separately by the
+     programs trying to read from it.  This can be very confusing.
+
+     The solution is to put a BIO filter in the way that will buffer
+     text until a linefeed is reached, and then write everything a
+     line at a time, so every record written will be an actual line,
+     not chunks of lines and not (usually doesn't happen, but I've
+     seen it once) several lines in one record.  BIO_f_linebuffer() is
+     the answer.
+
+     Currently, it's a VMS-only method, because that's where it has
+     been tested well enough.
+     [Richard Levitte]
+
+  *) Remove 'optimized' squaring variant in BN_mod_mul_montgomery,
+     it can return incorrect results.
+     (Note: The buggy variant was not enabled in OpenSSL 0.9.5a,
+     but it was in 0.9.6-beta[12].)
+     [Bodo Moeller]
+
+  *) Disable the check for content being present when verifying detached
+     signatures in pk7_smime.c. Some versions of Netscape (wrongly)
+     include zero length content when signing messages.
+     [Steve Henson]
+
+  *) New BIO_shutdown_wr macro, which invokes the BIO_C_SHUTDOWN_WR
+     BIO_ctrl (for BIO pairs).
+     [Bodo Möller]
+
+  *) Add DSO method for VMS.
+     [Richard Levitte]
+
+  *) Bug fix: Montgomery multiplication could produce results with the
+     wrong sign.
+     [Ulf Möller]
+
+  *) Add RPM specification openssl.spec and modify it to build three
+     packages.  The default package contains applications, application
+     documentation and run-time libraries.  The devel package contains
+     include files, static libraries and function documentation.  The
+     doc package contains the contents of the doc directory.  The original
+     openssl.spec was provided by Damien Miller <djm@mindrot.org>.
+     [Richard Levitte]
+     
+  *) Add a large number of documentation files for many SSL routines.
+     [Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE>]
+
+  *) Add a configuration entry for Sony News 4.
+     [NAKAJI Hiroyuki <nakaji@tutrp.tut.ac.jp>]
+
+  *) Don't set the two most significant bits to one when generating a
+     random number < q in the DSA library.
+     [Ulf Möller]
+
+  *) New SSL API mode 'SSL_MODE_AUTO_RETRY'.  This disables the default
+     behaviour that SSL_read may result in SSL_ERROR_WANT_READ (even if
+     the underlying transport is blocking) if a handshake took place.
+     (The default behaviour is needed by applications such as s_client
+     and s_server that use select() to determine when to use SSL_read;
+     but for applications that know in advance when to expect data, it
+     just makes things more complicated.)
+     [Bodo Moeller]
+
+  *) Add RAND_egd_bytes(), which gives control over the number of bytes read
+     from EGD.
+     [Ben Laurie]
+
+  *) Add a few more EBCDIC conditionals that make `req' and `x509'
+     work better on such systems.
+     [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>]
+
+  *) Add two demo programs for PKCS12_parse() and PKCS12_create().
+     Update PKCS12_parse() so it copies the friendlyName and the
+     keyid to the certificates aux info.
+     [Steve Henson]
+
+  *) Fix bug in PKCS7_verify() which caused an infinite loop
+     if there was more than one signature.
+     [Sven Uszpelkat <su@celocom.de>]
+
+  *) Major change in util/mkdef.pl to include extra information
+     about each symbol, as well as presentig variables as well
+     as functions.  This change means that there's n more need
+     to rebuild the .num files when some algorithms are excluded.
+     [Richard Levitte]
+
+  *) Allow the verify time to be set by an application,
+     rather than always using the current time.
+     [Steve Henson]
+  
+  *) Phase 2 verify code reorganisation. The certificate
+     verify code now looks up an issuer certificate by a
+     number of criteria: subject name, authority key id
+     and key usage. It also verifies self signed certificates
+     by the same criteria. The main comparison function is
+     X509_check_issued() which performs these checks.
+ 
+     Lot of changes were necessary in order to support this
+     without completely rewriting the lookup code.
+ 
+     Authority and subject key identifier are now cached.
+ 
+     The LHASH 'certs' is X509_STORE has now been replaced
+     by a STACK_OF(X509_OBJECT). This is mainly because an
+     LHASH can't store or retrieve multiple objects with
+     the same hash value.
+
+     As a result various functions (which were all internal
+     use only) have changed to handle the new X509_STORE
+     structure. This will break anything that messed round
+     with X509_STORE internally.
+ 
+     The functions X509_STORE_add_cert() now checks for an
+     exact match, rather than just subject name.
+ 
+     The X509_STORE API doesn't directly support the retrieval
+     of multiple certificates matching a given criteria, however
+     this can be worked round by performing a lookup first
+     (which will fill the cache with candidate certificates)
+     and then examining the cache for matches. This is probably
+     the best we can do without throwing out X509_LOOKUP
+     entirely (maybe later...).
+ 
+     The X509_VERIFY_CTX structure has been enhanced considerably.
+ 
+     All certificate lookup operations now go via a get_issuer()
+     callback. Although this currently uses an X509_STORE it
+     can be replaced by custom lookups. This is a simple way
+     to bypass the X509_STORE hackery necessary to make this
+     work and makes it possible to use more efficient techniques
+     in future. A very simple version which uses a simple
+     STACK for its trusted certificate store is also provided
+     using X509_STORE_CTX_trusted_stack().
+ 
+     The verify_cb() and verify() callbacks now have equivalents
+     in the X509_STORE_CTX structure.
+ 
+     X509_STORE_CTX also has a 'flags' field which can be used
+     to customise the verify behaviour.
+     [Steve Henson]
+ 
+  *) Add new PKCS#7 signing option PKCS7_NOSMIMECAP which 
+     excludes S/MIME capabilities.
+     [Steve Henson]
+
+  *) When a certificate request is read in keep a copy of the
+     original encoding of the signed data and use it when outputing
+     again. Signatures then use the original encoding rather than
+     a decoded, encoded version which may cause problems if the
+     request is improperly encoded.
+     [Steve Henson]
+
+  *) For consistency with other BIO_puts implementations, call
+     buffer_write(b, ...) directly in buffer_puts instead of calling
+     BIO_write(b, ...).
+
+     In BIO_puts, increment b->num_write as in BIO_write.
+     [Peter.Sylvester@EdelWeb.fr]
+
+  *) Fix BN_mul_word for the case where the word is 0. (We have to use
+     BN_zero, we may not return a BIGNUM with an array consisting of
+     words set to zero.)
+     [Bodo Moeller]
+
+  *) Avoid calling abort() from within the library when problems are
+     detected, except if preprocessor symbols have been defined
+     (such as REF_CHECK, BN_DEBUG etc.).
+     [Bodo Moeller]
+
+  *) New openssl application 'rsautl'. This utility can be
+     used for low level RSA operations. DER public key
+     BIO/fp routines also added.
+     [Steve Henson]
+
+  *) New Configure entry and patches for compiling on QNX 4.
+     [Andreas Schneider <andreas@ds3.etech.fh-hamburg.de>]
+
+  *) A demo state-machine implementation was sponsored by
+     Nuron (http://www.nuron.com/) and is now available in
+     demos/state_machine.
+     [Ben Laurie]
+
+  *) New options added to the 'dgst' utility for signature
+     generation and verification.
+     [Steve Henson]
+
+  *) Unrecognized PKCS#7 content types are now handled via a
+     catch all ASN1_TYPE structure. This allows unsupported
+     types to be stored as a "blob" and an application can
+     encode and decode it manually.
+     [Steve Henson]
+
+  *) Fix various signed/unsigned issues to make a_strex.c
+     compile under VC++.
+     [Oscar Jacobsson <oscar.jacobsson@celocom.com>]
+
+  *) ASN1 fixes. i2d_ASN1_OBJECT was not returning the correct
+     length if passed a buffer. ASN1_INTEGER_to_BN failed
+     if passed a NULL BN and its argument was negative.
+     [Steve Henson, pointed out by Sven Heiberg <sven@tartu.cyber.ee>]
+
+  *) Modification to PKCS#7 encoding routines to output definite
+     length encoding. Since currently the whole structures are in
+     memory there's not real point in using indefinite length 
+     constructed encoding. However if OpenSSL is compiled with
+     the flag PKCS7_INDEFINITE_ENCODING the old form is used.
+     [Steve Henson]
+
+  *) Added BIO_vprintf() and BIO_vsnprintf().
+     [Richard Levitte]
+
+  *) Added more prefixes to parse for in the the strings written
+     through a logging bio, to cover all the levels that are available
+     through syslog.  The prefixes are now:
+
+	PANIC, EMERG, EMR	=>	LOG_EMERG
+	ALERT, ALR		=>	LOG_ALERT
+	CRIT, CRI		=>	LOG_CRIT
+	ERROR, ERR		=>	LOG_ERR
+	WARNING, WARN, WAR	=>	LOG_WARNING
+	NOTICE, NOTE, NOT	=>	LOG_NOTICE
+	INFO, INF		=>	LOG_INFO
+	DEBUG, DBG		=>	LOG_DEBUG
+
+     and as before, if none of those prefixes are present at the
+     beginning of the string, LOG_ERR is chosen.
+
+     On Win32, the LOG_* levels are mapped according to this:
+
+	LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR	=> EVENTLOG_ERROR_TYPE
+	LOG_WARNING				=> EVENTLOG_WARNING_TYPE
+	LOG_NOTICE, LOG_INFO, LOG_DEBUG		=> EVENTLOG_INFORMATION_TYPE
+
+     [Richard Levitte]
+
+  *) Made it possible to reconfigure with just the configuration
+     argument "reconf" or "reconfigure".  The command line arguments
+     are stored in Makefile.ssl in the variable CONFIGURE_ARGS,
+     and are retrieved from there when reconfiguring.
+     [Richard Levitte]
+
+  *) MD4 implemented.
+     [Assar Westerlund <assar@sics.se>, Richard Levitte]
+
+  *) Add the arguments -CAfile and -CApath to the pkcs12 utility.
+     [Richard Levitte]
+
+  *) The obj_dat.pl script was messing up the sorting of object
+     names. The reason was that it compared the quoted version
+     of strings as a result "OCSP" > "OCSP Signing" because
+     " > SPACE. Changed script to store unquoted versions of
+     names and add quotes on output. It was also omitting some
+     names from the lookup table if they were given a default
+     value (that is if SN is missing it is given the same
+     value as LN and vice versa), these are now added on the
+     grounds that if an object has a name we should be able to
+     look it up. Finally added warning output when duplicate
+     short or long names are found.
+     [Steve Henson]
+
+  *) Changes needed for Tandem NSK.
+     [Scott Uroff <scott@xypro.com>]
+
+  *) Fix SSL 2.0 rollback checking: Due to an off-by-one error in
+     RSA_padding_check_SSLv23(), special padding was never detected
+     and thus the SSL 3.0/TLS 1.0 countermeasure against protocol
+     version rollback attacks was not effective.
+
+     In s23_clnt.c, don't use special rollback-attack detection padding
+     (RSA_SSLV23_PADDING) if SSL 2.0 is the only protocol enabled in the
+     client; similarly, in s23_srvr.c, don't do the rollback check if
+     SSL 2.0 is the only protocol enabled in the server.
+     [Bodo Moeller]
+
+  *) Make it possible to get hexdumps of unprintable data with 'openssl
+     asn1parse'.  By implication, the functions ASN1_parse_dump() and
+     BIO_dump_indent() are added.
+     [Richard Levitte]
+
+  *) New functions ASN1_STRING_print_ex() and X509_NAME_print_ex()
+     these print out strings and name structures based on various
+     flags including RFC2253 support and proper handling of
+     multibyte characters. Added options to the 'x509' utility 
+     to allow the various flags to be set.
+     [Steve Henson]
+
+  *) Various fixes to use ASN1_TIME instead of ASN1_UTCTIME.
+     Also change the functions X509_cmp_current_time() and
+     X509_gmtime_adj() work with an ASN1_TIME structure,
+     this will enable certificates using GeneralizedTime in validity
+     dates to be checked.
+     [Steve Henson]
+
+  *) Make the NEG_PUBKEY_BUG code (which tolerates invalid
+     negative public key encodings) on by default,
+     NO_NEG_PUBKEY_BUG can be set to disable it.
+     [Steve Henson]
+
+  *) New function c2i_ASN1_OBJECT() which acts on ASN1_OBJECT
+     content octets. An i2c_ASN1_OBJECT is unnecessary because
+     the encoding can be trivially obtained from the structure.
+     [Steve Henson]
+
+  *) crypto/err.c locking bugfix: Use write locks (CRYPTO_w_[un]lock),
+     not read locks (CRYPTO_r_[un]lock).
+     [Bodo Moeller]
+
+  *) A first attempt at creating official support for shared
+     libraries through configuration.  I've kept it so the
+     default is static libraries only, and the OpenSSL programs
+     are always statically linked for now, but there are
+     preparations for dynamic linking in place.
+     This has been tested on Linux and Tru64.
+     [Richard Levitte]
+
+  *) Randomness polling function for Win9x, as described in:
+     Peter Gutmann, Software Generation of Practically Strong
+     Random Numbers.
+     [Ulf Möller]
+
+  *) Fix so PRNG is seeded in req if using an already existing
+     DSA key.
+     [Steve Henson]
+
+  *) New options to smime application. -inform and -outform
+     allow alternative formats for the S/MIME message including
+     PEM and DER. The -content option allows the content to be
+     specified separately. This should allow things like Netscape
+     form signing output easier to verify.
+     [Steve Henson]
+
+  *) Fix the ASN1 encoding of tags using the 'long form'.
+     [Steve Henson]
+
+  *) New ASN1 functions, i2c_* and c2i_* for INTEGER and BIT
+     STRING types. These convert content octets to and from the
+     underlying type. The actual tag and length octets are
+     already assumed to have been read in and checked. These
+     are needed because all other string types have virtually
+     identical handling apart from the tag. By having versions
+     of the ASN1 functions that just operate on content octets
+     IMPLICIT tagging can be handled properly. It also allows
+     the ASN1_ENUMERATED code to be cut down because ASN1_ENUMERATED
+     and ASN1_INTEGER are identical apart from the tag.
+     [Steve Henson]
+
+  *) Change the handling of OID objects as follows:
+
+     - New object identifiers are inserted in objects.txt, following
+       the syntax given in objects.README.
+     - objects.pl is used to process obj_mac.num and create a new
+       obj_mac.h.
+     - obj_dat.pl is used to create a new obj_dat.h, using the data in
+       obj_mac.h.
+
+     This is currently kind of a hack, and the perl code in objects.pl
+     isn't very elegant, but it works as I intended.  The simplest way
+     to check that it worked correctly is to look in obj_dat.h and
+     check the array nid_objs and make sure the objects haven't moved
+     around (this is important!).  Additions are OK, as well as
+     consistent name changes. 
+     [Richard Levitte]
+
+  *) Add BSD-style MD5-based passwords to 'openssl passwd' (option '-1').
+     [Bodo Moeller]
+
+  *) Addition of the command line parameter '-rand file' to 'openssl req'.
+     The given file adds to whatever has already been seeded into the
+     random pool through the RANDFILE configuration file option or
+     environment variable, or the default random state file.
+     [Richard Levitte]
+
+  *) mkstack.pl now sorts each macro group into lexical order.
+     Previously the output order depended on the order the files
+     appeared in the directory, resulting in needless rewriting
+     of safestack.h .
+     [Steve Henson]
+
+  *) Patches to make OpenSSL compile under Win32 again. Mostly
+     work arounds for the VC++ problem that it treats func() as
+     func(void). Also stripped out the parts of mkdef.pl that
+     added extra typesafe functions: these no longer exist.
+     [Steve Henson]
+
+  *) Reorganisation of the stack code. The macros are now all 
+     collected in safestack.h . Each macro is defined in terms of
+     a "stack macro" of the form SKM_<name>(type, a, b). The 
+     DEBUG_SAFESTACK is now handled in terms of function casts,
+     this has the advantage of retaining type safety without the
+     use of additional functions. If DEBUG_SAFESTACK is not defined
+     then the non typesafe macros are used instead. Also modified the
+     mkstack.pl script to handle the new form. Needs testing to see
+     if which (if any) compilers it chokes and maybe make DEBUG_SAFESTACK
+     the default if no major problems. Similar behaviour for ASN1_SET_OF
+     and PKCS12_STACK_OF.
+     [Steve Henson]
+
+  *) When some versions of IIS use the 'NET' form of private key the
+     key derivation algorithm is different. Normally MD5(password) is
+     used as a 128 bit RC4 key. In the modified case
+     MD5(MD5(password) + "SGCKEYSALT")  is used insted. Added some
+     new functions i2d_RSA_NET(), d2i_RSA_NET() etc which are the same
+     as the old Netscape_RSA functions except they have an additional
+     'sgckey' parameter which uses the modified algorithm. Also added
+     an -sgckey command line option to the rsa utility. Thanks to 
+     Adrian Peck <bertie@ncipher.com> for posting details of the modified
+     algorithm to openssl-dev.
+     [Steve Henson]
+
+  *) The evp_local.h macros were using 'c.##kname' which resulted in
+     invalid expansion on some systems (SCO 5.0.5 for example).
+     Corrected to 'c.kname'.
+     [Phillip Porch <root@theporch.com>]
+
+  *) New X509_get1_email() and X509_REQ_get1_email() functions that return
+     a STACK of email addresses from a certificate or request, these look
+     in the subject name and the subject alternative name extensions and 
+     omit any duplicate addresses.
+     [Steve Henson]
+
+  *) Re-implement BN_mod_exp2_mont using independent (and larger) windows.
+     This makes DSA verification about 2 % faster.
+     [Bodo Moeller]
+
+  *) Increase maximum window size in BN_mod_exp_... to 6 bits instead of 5
+     (meaning that now 2^5 values will be precomputed, which is only 4 KB
+     plus overhead for 1024 bit moduli).
+     This makes exponentiations about 0.5 % faster for 1024 bit
+     exponents (as measured by "openssl speed rsa2048").
+     [Bodo Moeller]
+
+  *) Rename memory handling macros to avoid conflicts with other
+     software:
+          Malloc         =>  OPENSSL_malloc
+          Malloc_locked  =>  OPENSSL_malloc_locked
+          Realloc        =>  OPENSSL_realloc
+          Free           =>  OPENSSL_free
+     [Richard Levitte]
+
+  *) New function BN_mod_exp_mont_word for small bases (roughly 15%
+     faster than BN_mod_exp_mont, i.e. 7% for a full DH exchange).
+     [Bodo Moeller]
+
+  *) CygWin32 support.
+     [John Jarvie <jjarvie@newsguy.com>]
+
+  *) The type-safe stack code has been rejigged. It is now only compiled
+     in when OpenSSL is configured with the DEBUG_SAFESTACK option and
+     by default all type-specific stack functions are "#define"d back to
+     standard stack functions. This results in more streamlined output
+     but retains the type-safety checking possibilities of the original
+     approach.
+     [Geoff Thorpe]
+
+  *) The STACK code has been cleaned up, and certain type declarations
+     that didn't make a lot of sense have been brought in line. This has
+     also involved a cleanup of sorts in safestack.h to more correctly
+     map type-safe stack functions onto their plain stack counterparts.
+     This work has also resulted in a variety of "const"ifications of
+     lots of the code, especially "_cmp" operations which should normally
+     be prototyped with "const" parameters anyway.
+     [Geoff Thorpe]
+
+  *) When generating bytes for the first time in md_rand.c, 'stir the pool'
+     by seeding with STATE_SIZE dummy bytes (with zero entropy count).
+     (The PRNG state consists of two parts, the large pool 'state' and 'md',
+     where all of 'md' is used each time the PRNG is used, but 'state'
+     is used only indexed by a cyclic counter. As entropy may not be
+     well distributed from the beginning, 'md' is important as a
+     chaining variable. However, the output function chains only half
+     of 'md', i.e. 80 bits.  ssleay_rand_add, on the other hand, chains
+     all of 'md', and seeding with STATE_SIZE dummy bytes will result
+     in all of 'state' being rewritten, with the new values depending
+     on virtually all of 'md'.  This overcomes the 80 bit limitation.)
+     [Bodo Moeller]
+
+  *) In ssl/s2_clnt.c and ssl/s3_clnt.c, call ERR_clear_error() when
+     the handshake is continued after ssl_verify_cert_chain();
+     otherwise, if SSL_VERIFY_NONE is set, remaining error codes
+     can lead to 'unexplainable' connection aborts later.
+     [Bodo Moeller; problem tracked down by Lutz Jaenicke]
+
+  *) Major EVP API cipher revision.
+     Add hooks for extra EVP features. This allows various cipher
+     parameters to be set in the EVP interface. Support added for variable
+     key length ciphers via the EVP_CIPHER_CTX_set_key_length() function and
+     setting of RC2 and RC5 parameters.
+
+     Modify EVP_OpenInit() and EVP_SealInit() to cope with variable key length
+     ciphers.
+
+     Remove lots of duplicated code from the EVP library. For example *every*
+     cipher init() function handles the 'iv' in the same way according to the
+     cipher mode. They also all do nothing if the 'key' parameter is NULL and
+     for CFB and OFB modes they zero ctx->num.
+
+     New functionality allows removal of S/MIME code RC2 hack.
+
+     Most of the routines have the same form and so can be declared in terms
+     of macros.
+
+     By shifting this to the top level EVP_CipherInit() it can be removed from
+     all individual ciphers. If the cipher wants to handle IVs or keys
+     differently it can set the EVP_CIPH_CUSTOM_IV or EVP_CIPH_ALWAYS_CALL_INIT
+     flags.
+
+     Change lots of functions like EVP_EncryptUpdate() to now return a
+     value: although software versions of the algorithms cannot fail
+     any installed hardware versions can.
+     [Steve Henson]
+
+  *) Implement SSL_OP_TLS_ROLLBACK_BUG: In ssl3_get_client_key_exchange, if
+     this option is set, tolerate broken clients that send the negotiated
+     protocol version number instead of the requested protocol version
+     number.
+     [Bodo Moeller]
+
+  *) Call dh_tmp_cb (set by ..._TMP_DH_CB) with correct 'is_export' flag;
+     i.e. non-zero for export ciphersuites, zero otherwise.
+     Previous versions had this flag inverted, inconsistent with
+     rsa_tmp_cb (..._TMP_RSA_CB).
+     [Bodo Moeller; problem reported by Amit Chopra]
+
+  *) Add missing DSA library text string. Work around for some IIS
+     key files with invalid SEQUENCE encoding.
+     [Steve Henson]
+
+  *) Add a document (doc/standards.txt) that list all kinds of standards
+     and so on that are implemented in OpenSSL.
+     [Richard Levitte]
+
+  *) Enhance c_rehash script. Old version would mishandle certificates
+     with the same subject name hash and wouldn't handle CRLs at all.
+     Added -fingerprint option to crl utility, to support new c_rehash
+     features.
+     [Steve Henson]
+
+  *) Eliminate non-ANSI declarations in crypto.h and stack.h.
+     [Ulf Möller]
+
+  *) Fix for SSL server purpose checking. Server checking was
+     rejecting certificates which had extended key usage present
+     but no ssl client purpose.
+     [Steve Henson, reported by Rene Grosser <grosser@hisolutions.com>]
+
+  *) Make PKCS#12 code work with no password. The PKCS#12 spec
+     is a little unclear about how a blank password is handled.
+     Since the password in encoded as a BMPString with terminating
+     double NULL a zero length password would end up as just the
+     double NULL. However no password at all is different and is
+     handled differently in the PKCS#12 key generation code. NS
+     treats a blank password as zero length. MSIE treats it as no
+     password on export: but it will try both on import. We now do
+     the same: PKCS12_parse() tries zero length and no password if
+     the password is set to "" or NULL (NULL is now a valid password:
+     it wasn't before) as does the pkcs12 application.
+     [Steve Henson]
+
+  *) Bugfixes in apps/x509.c: Avoid a memory leak; and don't use
+     perror when PEM_read_bio_X509_REQ fails, the error message must
+     be obtained from the error queue.
+     [Bodo Moeller]
+
+  *) Avoid 'thread_hash' memory leak in crypto/err/err.c by freeing
+     it in ERR_remove_state if appropriate, and change ERR_get_state
+     accordingly to avoid race conditions (this is necessary because
+     thread_hash is no longer constant once set).
+     [Bodo Moeller]
+
+  *) Bugfix for linux-elf makefile.one.
+     [Ulf Möller]
+
+  *) RSA_get_default_method() will now cause a default
+     RSA_METHOD to be chosen if one doesn't exist already.
+     Previously this was only set during a call to RSA_new()
+     or RSA_new_method(NULL) meaning it was possible for
+     RSA_get_default_method() to return NULL.
+     [Geoff Thorpe]
+
+  *) Added native name translation to the existing DSO code
+     that will convert (if the flag to do so is set) filenames
+     that are sufficiently small and have no path information
+     into a canonical native form. Eg. "blah" converted to
+     "libblah.so" or "blah.dll" etc.
+     [Geoff Thorpe]
+
+  *) New function ERR_error_string_n(e, buf, len) which is like
+     ERR_error_string(e, buf), but writes at most 'len' bytes
+     including the 0 terminator.  For ERR_error_string_n, 'buf'
+     may not be NULL.
+     [Damien Miller <djm@mindrot.org>, Bodo Moeller]
+
+  *) CONF library reworked to become more general.  A new CONF
+     configuration file reader "class" is implemented as well as a
+     new functions (NCONF_*, for "New CONF") to handle it.  The now
+     old CONF_* functions are still there, but are reimplemented to
+     work in terms of the new functions.  Also, a set of functions
+     to handle the internal storage of the configuration data is
+     provided to make it easier to write new configuration file
+     reader "classes" (I can definitely see something reading a
+     configuration file in XML format, for example), called _CONF_*,
+     or "the configuration storage API"...
+
+     The new configuration file reading functions are:
+
+        NCONF_new, NCONF_free, NCONF_load, NCONF_load_fp, NCONF_load_bio,
+        NCONF_get_section, NCONF_get_string, NCONF_get_numbre
+
+        NCONF_default, NCONF_WIN32
+
+        NCONF_dump_fp, NCONF_dump_bio
+
+     NCONF_default and NCONF_WIN32 are method (or "class") choosers,
+     NCONF_new creates a new CONF object.  This works in the same way
+     as other interfaces in OpenSSL, like the BIO interface.
+     NCONF_dump_* dump the internal storage of the configuration file,
+     which is useful for debugging.  All other functions take the same
+     arguments as the old CONF_* functions wth the exception of the
+     first that must be a `CONF *' instead of a `LHASH *'.
+
+     To make it easer to use the new classes with the old CONF_* functions,
+     the function CONF_set_default_method is provided.
+     [Richard Levitte]
+
+  *) Add '-tls1' option to 'openssl ciphers', which was already
+     mentioned in the documentation but had not been implemented.
+     (This option is not yet really useful because even the additional
+     experimental TLS 1.0 ciphers are currently treated as SSL 3.0 ciphers.)
+     [Bodo Moeller]
+
+  *) Initial DSO code added into libcrypto for letting OpenSSL (and
+     OpenSSL-based applications) load shared libraries and bind to
+     them in a portable way.
+     [Geoff Thorpe, with contributions from Richard Levitte]
+
+ Changes between 0.9.5 and 0.9.5a  [1 Apr 2000]
+
+  *) Make sure _lrotl and _lrotr are only used with MSVC.
+
+  *) Use lock CRYPTO_LOCK_RAND correctly in ssleay_rand_status
+     (the default implementation of RAND_status).
+
+  *) Rename openssl x509 option '-crlext', which was added in 0.9.5,
+     to '-clrext' (= clear extensions), as intended and documented.
+     [Bodo Moeller; inconsistency pointed out by Michael Attili
+     <attili@amaxo.com>]
+
+  *) Fix for HMAC. It wasn't zeroing the rest of the block if the key length
+     was larger than the MD block size.      
+     [Steve Henson, pointed out by Yost William <YostW@tce.com>]
+
+  *) Modernise PKCS12_parse() so it uses STACK_OF(X509) for its ca argument
+     fix a leak when the ca argument was passed as NULL. Stop X509_PUBKEY_set()
+     using the passed key: if the passed key was a private key the result
+     of X509_print(), for example, would be to print out all the private key
+     components.
+     [Steve Henson]
+
+  *) des_quad_cksum() byte order bug fix.
+     [Ulf Möller, using the problem description in krb4-0.9.7, where
+      the solution is attributed to Derrick J Brashear <shadow@DEMENTIA.ORG>]
+
+  *) Fix so V_ASN1_APP_CHOOSE works again: however its use is strongly
+     discouraged.
+     [Steve Henson, pointed out by Brian Korver <briank@cs.stanford.edu>]
+
+  *) For easily testing in shell scripts whether some command
+     'openssl XXX' exists, the new pseudo-command 'openssl no-XXX'
+     returns with exit code 0 iff no command of the given name is available.
+     'no-XXX' is printed in this case, 'XXX' otherwise.  In both cases,
+     the output goes to stdout and nothing is printed to stderr.
+     Additional arguments are always ignored.
+
+     Since for each cipher there is a command of the same name,
+     the 'no-cipher' compilation switches can be tested this way.
+
+     ('openssl no-XXX' is not able to detect pseudo-commands such
+     as 'quit', 'list-XXX-commands', or 'no-XXX' itself.)
+     [Bodo Moeller]
+
+  *) Update test suite so that 'make test' succeeds in 'no-rsa' configuration.
+     [Bodo Moeller]
+
+  *) For SSL_[CTX_]set_tmp_dh, don't create a DH key if SSL_OP_SINGLE_DH_USE
+     is set; it will be thrown away anyway because each handshake creates
+     its own key.
+     ssl_cert_dup, which is used by SSL_new, now copies DH keys in addition
+     to parameters -- in previous versions (since OpenSSL 0.9.3) the
+     'default key' from SSL_CTX_set_tmp_dh would always be lost, meanining
+     you effectivly got SSL_OP_SINGLE_DH_USE when using this macro.
+     [Bodo Moeller]
+
+  *) New s_client option -ign_eof: EOF at stdin is ignored, and
+     'Q' and 'R' lose their special meanings (quit/renegotiate).
+     This is part of what -quiet does; unlike -quiet, -ign_eof
+     does not suppress any output.
+     [Richard Levitte]
+
+  *) Add compatibility options to the purpose and trust code. The
+     purpose X509_PURPOSE_ANY is "any purpose" which automatically
+     accepts a certificate or CA, this was the previous behaviour,
+     with all the associated security issues.
+
+     X509_TRUST_COMPAT is the old trust behaviour: only and
+     automatically trust self signed roots in certificate store. A
+     new trust setting X509_TRUST_DEFAULT is used to specify that
+     a purpose has no associated trust setting and it should instead
+     use the value in the default purpose.
+     [Steve Henson]
+
+  *) Fix the PKCS#8 DSA private key code so it decodes keys again
+     and fix a memory leak.
+     [Steve Henson]
+
+  *) In util/mkerr.pl (which implements 'make errors'), preserve
+     reason strings from the previous version of the .c file, as
+     the default to have only downcase letters (and digits) in
+     automatically generated reasons codes is not always appropriate.
+     [Bodo Moeller]
+
+  *) In ERR_load_ERR_strings(), build an ERR_LIB_SYS error reason table
+     using strerror.  Previously, ERR_reason_error_string() returned
+     library names as reason strings for SYSerr; but SYSerr is a special
+     case where small numbers are errno values, not library numbers.
+     [Bodo Moeller]
+
+  *) Add '-dsaparam' option to 'openssl dhparam' application.  This
+     converts DSA parameters into DH parameters. (When creating parameters,
+     DSA_generate_parameters is used.)
+     [Bodo Moeller]
+
+  *) Include 'length' (recommended exponent length) in C code generated
+     by 'openssl dhparam -C'.
+     [Bodo Moeller]
+
+  *) The second argument to set_label in perlasm was already being used
+     so couldn't be used as a "file scope" flag. Moved to third argument
+     which was free.
+     [Steve Henson]
+
+  *) In PEM_ASN1_write_bio and some other functions, use RAND_pseudo_bytes
+     instead of RAND_bytes for encryption IVs and salts.
+     [Bodo Moeller]
+
+  *) Include RAND_status() into RAND_METHOD instead of implementing
+     it only for md_rand.c  Otherwise replacing the PRNG by calling
+     RAND_set_rand_method would be impossible.
+     [Bodo Moeller]
+
+  *) Don't let DSA_generate_key() enter an infinite loop if the random
+     number generation fails.
+     [Bodo Moeller]
+
+  *) New 'rand' application for creating pseudo-random output.
+     [Bodo Moeller]
+
+  *) Added configuration support for Linux/IA64
+     [Rolf Haberrecker <rolf@suse.de>]
+
+  *) Assembler module support for Mingw32.
+     [Ulf Möller]
+
+  *) Shared library support for HPUX (in shlib/).
+     [Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE> and Anonymous]
+
+  *) Shared library support for Solaris gcc.
+     [Lutz Behnke <behnke@trustcenter.de>]
+
+ Changes between 0.9.4 and 0.9.5  [28 Feb 2000]
+
+  *) PKCS7_encrypt() was adding text MIME headers twice because they
+     were added manually and by SMIME_crlf_copy().
+     [Steve Henson]
+
+  *) In bntest.c don't call BN_rand with zero bits argument.
+     [Steve Henson, pointed out by Andrew W. Gray <agray@iconsinc.com>]
+
+  *) BN_mul bugfix: In bn_mul_part_recursion() only the a>a[n] && b>b[n]
+     case was implemented. This caused BN_div_recp() to fail occasionally.
+     [Ulf Möller]
+
+  *) Add an optional second argument to the set_label() in the perl
+     assembly language builder. If this argument exists and is set
+     to 1 it signals that the assembler should use a symbol whose 
+     scope is the entire file, not just the current function. This
+     is needed with MASM which uses the format label:: for this scope.
+     [Steve Henson, pointed out by Peter Runestig <peter@runestig.com>]
+
+  *) Change the ASN1 types so they are typedefs by default. Before
+     almost all types were #define'd to ASN1_STRING which was causing
+     STACK_OF() problems: you couldn't declare STACK_OF(ASN1_UTF8STRING)
+     for example.
+     [Steve Henson]
+
+  *) Change names of new functions to the new get1/get0 naming
+     convention: After 'get1', the caller owns a reference count
+     and has to call ..._free; 'get0' returns a pointer to some
+     data structure without incrementing reference counters.
+     (Some of the existing 'get' functions increment a reference
+     counter, some don't.)
+     Similarly, 'set1' and 'add1' functions increase reference
+     counters or duplicate objects.
+     [Steve Henson]
+
+  *) Allow for the possibility of temp RSA key generation failure:
+     the code used to assume it always worked and crashed on failure.
+     [Steve Henson]
+
+  *) Fix potential buffer overrun problem in BIO_printf().
+     [Ulf Möller, using public domain code by Patrick Powell; problem
+      pointed out by David Sacerdote <das33@cornell.edu>]
+
+  *) Support EGD <http://www.lothar.com/tech/crypto/>.  New functions
+     RAND_egd() and RAND_status().  In the command line application,
+     the EGD socket can be specified like a seed file using RANDFILE
+     or -rand.
+     [Ulf Möller]
+
+  *) Allow the string CERTIFICATE to be tolerated in PKCS#7 structures.
+     Some CAs (e.g. Verisign) distribute certificates in this form.
+     [Steve Henson]
+
+  *) Remove the SSL_ALLOW_ADH compile option and set the default cipher
+     list to exclude them. This means that no special compilation option
+     is needed to use anonymous DH: it just needs to be included in the
+     cipher list.
+     [Steve Henson]
+
+  *) Change the EVP_MD_CTX_type macro so its meaning consistent with
+     EVP_MD_type. The old functionality is available in a new macro called
+     EVP_MD_md(). Change code that uses it and update docs.
+     [Steve Henson]
+
+  *) ..._ctrl functions now have corresponding ..._callback_ctrl functions
+     where the 'void *' argument is replaced by a function pointer argument.
+     Previously 'void *' was abused to point to functions, which works on
+     many platforms, but is not correct.  As these functions are usually
+     called by macros defined in OpenSSL header files, most source code
+     should work without changes.
+     [Richard Levitte]
+
+  *) <openssl/opensslconf.h> (which is created by Configure) now contains
+     sections with information on -D... compiler switches used for
+     compiling the library so that applications can see them.  To enable
+     one of these sections, a pre-processor symbol OPENSSL_..._DEFINES
+     must be defined.  E.g.,
+        #define OPENSSL_ALGORITHM_DEFINES
+        #include <openssl/opensslconf.h>
+     defines all pertinent NO_<algo> symbols, such as NO_IDEA, NO_RSA, etc.
+     [Richard Levitte, Ulf and Bodo Möller]
+
+  *) Bugfix: Tolerate fragmentation and interleaving in the SSL 3/TLS
+     record layer.
+     [Bodo Moeller]
+
+  *) Change the 'other' type in certificate aux info to a STACK_OF
+     X509_ALGOR. Although not an AlgorithmIdentifier as such it has
+     the required ASN1 format: arbitrary types determined by an OID.
+     [Steve Henson]
+
+  *) Add some PEM_write_X509_REQ_NEW() functions and a command line
+     argument to 'req'. This is not because the function is newer or
+     better than others it just uses the work 'NEW' in the certificate
+     request header lines. Some software needs this.
+     [Steve Henson]
+
+  *) Reorganise password command line arguments: now passwords can be
+     obtained from various sources. Delete the PEM_cb function and make
+     it the default behaviour: i.e. if the callback is NULL and the
+     usrdata argument is not NULL interpret it as a null terminated pass
+     phrase. If usrdata and the callback are NULL then the pass phrase
+     is prompted for as usual.
+     [Steve Henson]
+
+  *) Add support for the Compaq Atalla crypto accelerator. If it is installed,
+     the support is automatically enabled. The resulting binaries will
+     autodetect the card and use it if present.
+     [Ben Laurie and Compaq Inc.]
+
+  *) Work around for Netscape hang bug. This sends certificate request
+     and server done in one record. Since this is perfectly legal in the
+     SSL/TLS protocol it isn't a "bug" option and is on by default. See
+     the bugs/SSLv3 entry for more info.
+     [Steve Henson]
+
+  *) HP-UX tune-up: new unified configs, HP C compiler bug workaround.
+     [Andy Polyakov]
+
+  *) Add -rand argument to smime and pkcs12 applications and read/write
+     of seed file.
+     [Steve Henson]
+
+  *) New 'passwd' tool for crypt(3) and apr1 password hashes.
+     [Bodo Moeller]
+
+  *) Add command line password options to the remaining applications.
+     [Steve Henson]
+
+  *) Bug fix for BN_div_recp() for numerators with an even number of
+     bits.
+     [Ulf Möller]
+
+  *) More tests in bntest.c, and changed test_bn output.
+     [Ulf Möller]
+
+  *) ./config recognizes MacOS X now.
+     [Andy Polyakov]
+
+  *) Bug fix for BN_div() when the first words of num and divsor are
+     equal (it gave wrong results if (rem=(n1-q*d0)&BN_MASK2) < d0).
+     [Ulf Möller]
+
+  *) Add support for various broken PKCS#8 formats, and command line
+     options to produce them.
+     [Steve Henson]
+
+  *) New functions BN_CTX_start(), BN_CTX_get() and BT_CTX_end() to
+     get temporary BIGNUMs from a BN_CTX.
+     [Ulf Möller]
+
+  *) Correct return values in BN_mod_exp_mont() and BN_mod_exp2_mont()
+     for p == 0.
+     [Ulf Möller]
+
+  *) Change the SSLeay_add_all_*() functions to OpenSSL_add_all_*() and
+     include a #define from the old name to the new. The original intent
+     was that statically linked binaries could for example just call
+     SSLeay_add_all_ciphers() to just add ciphers to the table and not
+     link with digests. This never worked becayse SSLeay_add_all_digests()
+     and SSLeay_add_all_ciphers() were in the same source file so calling
+     one would link with the other. They are now in separate source files.
+     [Steve Henson]
+
+  *) Add a new -notext option to 'ca' and a -pubkey option to 'spkac'.
+     [Steve Henson]
+
+  *) Use a less unusual form of the Miller-Rabin primality test (it used
+     a binary algorithm for exponentiation integrated into the Miller-Rabin
+     loop, our standard modexp algorithms are faster).
+     [Bodo Moeller]
+
+  *) Support for the EBCDIC character set completed.
+     [Martin Kraemer <Martin.Kraemer@Mch.SNI.De>]
+
+  *) Source code cleanups: use const where appropriate, eliminate casts,
+     use void * instead of char * in lhash.
+     [Ulf Möller] 
+
+  *) Bugfix: ssl3_send_server_key_exchange was not restartable
+     (the state was not changed to SSL3_ST_SW_KEY_EXCH_B, and because of
+     this the server could overwrite ephemeral keys that the client
+     has already seen).
+     [Bodo Moeller]
+
+  *) Turn DSA_is_prime into a macro that calls BN_is_prime,
+     using 50 iterations of the Rabin-Miller test.
+
+     DSA_generate_parameters now uses BN_is_prime_fasttest (with 50
+     iterations of the Rabin-Miller test as required by the appendix
+     to FIPS PUB 186[-1]) instead of DSA_is_prime.
+     As BN_is_prime_fasttest includes trial division, DSA parameter
+     generation becomes much faster.
+
+     This implies a change for the callback functions in DSA_is_prime
+     and DSA_generate_parameters: The callback function is called once
+     for each positive witness in the Rabin-Miller test, not just
+     occasionally in the inner loop; and the parameters to the
+     callback function now provide an iteration count for the outer
+     loop rather than for the current invocation of the inner loop.
+     DSA_generate_parameters additionally can call the callback
+     function with an 'iteration count' of -1, meaning that a
+     candidate has passed the trial division test (when q is generated 
+     from an application-provided seed, trial division is skipped).
+     [Bodo Moeller]
+
+  *) New function BN_is_prime_fasttest that optionally does trial
+     division before starting the Rabin-Miller test and has
+     an additional BN_CTX * argument (whereas BN_is_prime always
+     has to allocate at least one BN_CTX).
+     'callback(1, -1, cb_arg)' is called when a number has passed the
+     trial division stage.
+     [Bodo Moeller]
+
+  *) Fix for bug in CRL encoding. The validity dates weren't being handled
+     as ASN1_TIME.
+     [Steve Henson]
+
+  *) New -pkcs12 option to CA.pl script to write out a PKCS#12 file.
+     [Steve Henson]
+
+  *) New function BN_pseudo_rand().
+     [Ulf Möller]
+
+  *) Clean up BN_mod_mul_montgomery(): replace the broken (and unreadable)
+     bignum version of BN_from_montgomery() with the working code from
+     SSLeay 0.9.0 (the word based version is faster anyway), and clean up
+     the comments.
+     [Ulf Möller]
+
+  *) Avoid a race condition in s2_clnt.c (function get_server_hello) that
+     made it impossible to use the same SSL_SESSION data structure in
+     SSL2 clients in multiple threads.
+     [Bodo Moeller]
+
+  *) The return value of RAND_load_file() no longer counts bytes obtained
+     by stat().  RAND_load_file(..., -1) is new and uses the complete file
+     to seed the PRNG (previously an explicit byte count was required).
+     [Ulf Möller, Bodo Möller]
+
+  *) Clean up CRYPTO_EX_DATA functions, some of these didn't have prototypes
+     used (char *) instead of (void *) and had casts all over the place.
+     [Steve Henson]
+
+  *) Make BN_generate_prime() return NULL on error if ret!=NULL.
+     [Ulf Möller]
+
+  *) Retain source code compatibility for BN_prime_checks macro:
+     BN_is_prime(..., BN_prime_checks, ...) now uses
+     BN_prime_checks_for_size to determine the appropriate number of
+     Rabin-Miller iterations.
+     [Ulf Möller]
+
+  *) Diffie-Hellman uses "safe" primes: DH_check() return code renamed to
+     DH_CHECK_P_NOT_SAFE_PRIME.
+     (Check if this is true? OpenPGP calls them "strong".)
+     [Ulf Möller]
+
+  *) Merge the functionality of "dh" and "gendh" programs into a new program
+     "dhparam". The old programs are retained for now but will handle DH keys
+     (instead of parameters) in future.
+     [Steve Henson]
+
+  *) Make the ciphers, s_server and s_client programs check the return values
+     when a new cipher list is set.
+     [Steve Henson]
+
+  *) Enhance the SSL/TLS cipher mechanism to correctly handle the TLS 56bit
+     ciphers. Before when the 56bit ciphers were enabled the sorting was
+     wrong.
+
+     The syntax for the cipher sorting has been extended to support sorting by
+     cipher-strength (using the strength_bits hard coded in the tables).
+     The new command is "@STRENGTH" (see also doc/apps/ciphers.pod).
+
+     Fix a bug in the cipher-command parser: when supplying a cipher command
+     string with an "undefined" symbol (neither command nor alphanumeric
+     [A-Za-z0-9], ssl_set_cipher_list used to hang in an endless loop. Now
+     an error is flagged.
+
+     Due to the strength-sorting extension, the code of the
+     ssl_create_cipher_list() function was completely rearranged. I hope that
+     the readability was also increased :-)
+     [Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE>]
+
+  *) Minor change to 'x509' utility. The -CAcreateserial option now uses 1
+     for the first serial number and places 2 in the serial number file. This
+     avoids problems when the root CA is created with serial number zero and
+     the first user certificate has the same issuer name and serial number
+     as the root CA.
+     [Steve Henson]
+
+  *) Fixes to X509_ATTRIBUTE utilities, change the 'req' program so it uses
+     the new code. Add documentation for this stuff.
+     [Steve Henson]
+
+  *) Changes to X509_ATTRIBUTE utilities. These have been renamed from
+     X509_*() to X509at_*() on the grounds that they don't handle X509
+     structures and behave in an analagous way to the X509v3 functions:
+     they shouldn't be called directly but wrapper functions should be used
+     instead.
+
+     So we also now have some wrapper functions that call the X509at functions
+     when passed certificate requests. (TO DO: similar things can be done with
+     PKCS#7 signed and unsigned attributes, PKCS#12 attributes and a few other
+     things. Some of these need some d2i or i2d and print functionality
+     because they handle more complex structures.)
+     [Steve Henson]
+
+  *) Add missing #ifndefs that caused missing symbols when building libssl
+     as a shared library without RSA.  Use #ifndef NO_SSL2 instead of
+     NO_RSA in ssl/s2*.c. 
+     [Kris Kennaway <kris@hub.freebsd.org>, modified by Ulf Möller]
+
+  *) Precautions against using the PRNG uninitialized: RAND_bytes() now
+     has a return value which indicates the quality of the random data
+     (1 = ok, 0 = not seeded).  Also an error is recorded on the thread's
+     error queue. New function RAND_pseudo_bytes() generates output that is
+     guaranteed to be unique but not unpredictable. RAND_add is like
+     RAND_seed, but takes an extra argument for an entropy estimate
+     (RAND_seed always assumes full entropy).
+     [Ulf Möller]
+
+  *) Do more iterations of Rabin-Miller probable prime test (specifically,
+     3 for 1024-bit primes, 6 for 512-bit primes, 12 for 256-bit primes
+     instead of only 2 for all lengths; see BN_prime_checks_for_size definition
+     in crypto/bn/bn_prime.c for the complete table).  This guarantees a
+     false-positive rate of at most 2^-80 for random input.
+     [Bodo Moeller]
+
+  *) Rewrite ssl3_read_n (ssl/s3_pkt.c) avoiding a couple of bugs.
+     [Bodo Moeller]
+
+  *) New function X509_CTX_rget_chain() (renamed to X509_CTX_get1_chain
+     in the 0.9.5 release), this returns the chain
+     from an X509_CTX structure with a dup of the stack and all
+     the X509 reference counts upped: so the stack will exist
+     after X509_CTX_cleanup() has been called. Modify pkcs12.c
+     to use this.
+
+     Also make SSL_SESSION_print() print out the verify return
+     code.
+     [Steve Henson]
+
+  *) Add manpage for the pkcs12 command. Also change the default
+     behaviour so MAC iteration counts are used unless the new
+     -nomaciter option is used. This improves file security and
+     only older versions of MSIE (4.0 for example) need it.
+     [Steve Henson]
+
+  *) Honor the no-xxx Configure options when creating .DEF files.
+     [Ulf Möller]
+
+  *) Add PKCS#10 attributes to field table: challengePassword, 
+     unstructuredName and unstructuredAddress. These are taken from
+     draft PKCS#9 v2.0 but are compatible with v1.2 provided no 
+     international characters are used.
+
+     More changes to X509_ATTRIBUTE code: allow the setting of types
+     based on strings. Remove the 'loc' parameter when adding
+     attributes because these will be a SET OF encoding which is sorted
+     in ASN1 order.
+     [Steve Henson]
+
+  *) Initial changes to the 'req' utility to allow request generation
+     automation. This will allow an application to just generate a template
+     file containing all the field values and have req construct the
+     request.
+
+     Initial support for X509_ATTRIBUTE handling. Stacks of these are
+     used all over the place including certificate requests and PKCS#7
+     structures. They are currently handled manually where necessary with
+     some primitive wrappers for PKCS#7. The new functions behave in a
+     manner analogous to the X509 extension functions: they allow
+     attributes to be looked up by NID and added.
+
+     Later something similar to the X509V3 code would be desirable to
+     automatically handle the encoding, decoding and printing of the
+     more complex types. The string types like challengePassword can
+     be handled by the string table functions.
+
+     Also modified the multi byte string table handling. Now there is
+     a 'global mask' which masks out certain types. The table itself
+     can use the flag STABLE_NO_MASK to ignore the mask setting: this
+     is useful when for example there is only one permissible type
+     (as in countryName) and using the mask might result in no valid
+     types at all.
+     [Steve Henson]
+
+  *) Clean up 'Finished' handling, and add functions SSL_get_finished and
+     SSL_get_peer_finished to allow applications to obtain the latest
+     Finished messages sent to the peer or expected from the peer,
+     respectively.  (SSL_get_peer_finished is usually the Finished message
+     actually received from the peer, otherwise the protocol will be aborted.)
+
+     As the Finished message are message digests of the complete handshake
+     (with a total of 192 bits for TLS 1.0 and more for SSL 3.0), they can
+     be used for external authentication procedures when the authentication
+     provided by SSL/TLS is not desired or is not enough.
+     [Bodo Moeller]
+
+  *) Enhanced support for Alpha Linux is added. Now ./config checks if
+     the host supports BWX extension and if Compaq C is present on the
+     $PATH. Just exploiting of the BWX extension results in 20-30%
+     performance kick for some algorithms, e.g. DES and RC4 to mention
+     a couple. Compaq C in turn generates ~20% faster code for MD5 and
+     SHA1.
+     [Andy Polyakov]
+
+  *) Add support for MS "fast SGC". This is arguably a violation of the
+     SSL3/TLS protocol. Netscape SGC does two handshakes: the first with
+     weak crypto and after checking the certificate is SGC a second one
+     with strong crypto. MS SGC stops the first handshake after receiving
+     the server certificate message and sends a second client hello. Since
+     a server will typically do all the time consuming operations before
+     expecting any further messages from the client (server key exchange
+     is the most expensive) there is little difference between the two.
+
+     To get OpenSSL to support MS SGC we have to permit a second client
+     hello message after we have sent server done. In addition we have to
+     reset the MAC if we do get this second client hello.
+     [Steve Henson]
+
+  *) Add a function 'd2i_AutoPrivateKey()' this will automatically decide
+     if a DER encoded private key is RSA or DSA traditional format. Changed
+     d2i_PrivateKey_bio() to use it. This is only needed for the "traditional"
+     format DER encoded private key. Newer code should use PKCS#8 format which
+     has the key type encoded in the ASN1 structure. Added DER private key
+     support to pkcs8 application.
+     [Steve Henson]
+
+  *) SSL 3/TLS 1 servers now don't request certificates when an anonymous
+     ciphersuites has been selected (as required by the SSL 3/TLS 1
+     specifications).  Exception: When SSL_VERIFY_FAIL_IF_NO_PEER_CERT
+     is set, we interpret this as a request to violate the specification
+     (the worst that can happen is a handshake failure, and 'correct'
+     behaviour would result in a handshake failure anyway).
+     [Bodo Moeller]
+
+  *) In SSL_CTX_add_session, take into account that there might be multiple
+     SSL_SESSION structures with the same session ID (e.g. when two threads
+     concurrently obtain them from an external cache).
+     The internal cache can handle only one SSL_SESSION with a given ID,
+     so if there's a conflict, we now throw out the old one to achieve
+     consistency.
+     [Bodo Moeller]
+
+  *) Add OIDs for idea and blowfish in CBC mode. This will allow both
+     to be used in PKCS#5 v2.0 and S/MIME.  Also add checking to
+     some routines that use cipher OIDs: some ciphers do not have OIDs
+     defined and so they cannot be used for S/MIME and PKCS#5 v2.0 for
+     example.
+     [Steve Henson]
+
+  *) Simplify the trust setting structure and code. Now we just have
+     two sequences of OIDs for trusted and rejected settings. These will
+     typically have values the same as the extended key usage extension
+     and any application specific purposes.
+
+     The trust checking code now has a default behaviour: it will just
+     check for an object with the same NID as the passed id. Functions can
+     be provided to override either the default behaviour or the behaviour
+     for a given id. SSL client, server and email already have functions
+     in place for compatibility: they check the NID and also return "trusted"
+     if the certificate is self signed.
+     [Steve Henson]
+
+  *) Add d2i,i2d bio/fp functions for PrivateKey: these convert the
+     traditional format into an EVP_PKEY structure.
+     [Steve Henson]
+
+  *) Add a password callback function PEM_cb() which either prompts for
+     a password if usr_data is NULL or otherwise assumes it is a null
+     terminated password. Allow passwords to be passed on command line
+     environment or config files in a few more utilities.
+     [Steve Henson]
+
+  *) Add a bunch of DER and PEM functions to handle PKCS#8 format private
+     keys. Add some short names for PKCS#8 PBE algorithms and allow them
+     to be specified on the command line for the pkcs8 and pkcs12 utilities.
+     Update documentation.
+     [Steve Henson]
+
+  *) Support for ASN1 "NULL" type. This could be handled before by using
+     ASN1_TYPE but there wasn't any function that would try to read a NULL
+     and produce an error if it couldn't. For compatibility we also have
+     ASN1_NULL_new() and ASN1_NULL_free() functions but these are faked and
+     don't allocate anything because they don't need to.
+     [Steve Henson]
+
+  *) Initial support for MacOS is now provided. Examine INSTALL.MacOS
+     for details.
+     [Andy Polyakov, Roy Woods <roy@centicsystems.ca>]
+
+  *) Rebuild of the memory allocation routines used by OpenSSL code and
+     possibly others as well.  The purpose is to make an interface that
+     provide hooks so anyone can build a separate set of allocation and
+     deallocation routines to be used by OpenSSL, for example memory
+     pool implementations, or something else, which was previously hard
+     since Malloc(), Realloc() and Free() were defined as macros having
+     the values malloc, realloc and free, respectively (except for Win32
+     compilations).  The same is provided for memory debugging code.
+     OpenSSL already comes with functionality to find memory leaks, but
+     this gives people a chance to debug other memory problems.
+
+     With these changes, a new set of functions and macros have appeared:
+
+       CRYPTO_set_mem_debug_functions()	        [F]
+       CRYPTO_get_mem_debug_functions()         [F]
+       CRYPTO_dbg_set_options()	                [F]
+       CRYPTO_dbg_get_options()                 [F]
+       CRYPTO_malloc_debug_init()               [M]
+
+     The memory debug functions are NULL by default, unless the library
+     is compiled with CRYPTO_MDEBUG or friends is defined.  If someone
+     wants to debug memory anyway, CRYPTO_malloc_debug_init() (which
+     gives the standard debugging functions that come with OpenSSL) or
+     CRYPTO_set_mem_debug_functions() (tells OpenSSL to use functions
+     provided by the library user) must be used.  When the standard
+     debugging functions are used, CRYPTO_dbg_set_options can be used to
+     request additional information:
+     CRYPTO_dbg_set_options(V_CYRPTO_MDEBUG_xxx) corresponds to setting
+     the CRYPTO_MDEBUG_xxx macro when compiling the library.   
+
+     Also, things like CRYPTO_set_mem_functions will always give the
+     expected result (the new set of functions is used for allocation
+     and deallocation) at all times, regardless of platform and compiler
+     options.
+
+     To finish it up, some functions that were never use in any other
+     way than through macros have a new API and new semantic:
+
+       CRYPTO_dbg_malloc()
+       CRYPTO_dbg_realloc()
+       CRYPTO_dbg_free()
+
+     All macros of value have retained their old syntax.
+     [Richard Levitte and Bodo Moeller]
+
+  *) Some S/MIME fixes. The OID for SMIMECapabilities was wrong, the
+     ordering of SMIMECapabilities wasn't in "strength order" and there
+     was a missing NULL in the AlgorithmIdentifier for the SHA1 signature
+     algorithm.
+     [Steve Henson]
+
+  *) Some ASN1 types with illegal zero length encoding (INTEGER,
+     ENUMERATED and OBJECT IDENTIFIER) choked the ASN1 routines.
+     [Frans Heymans <fheymans@isaserver.be>, modified by Steve Henson]
+
+  *) Merge in my S/MIME library for OpenSSL. This provides a simple
+     S/MIME API on top of the PKCS#7 code, a MIME parser (with enough
+     functionality to handle multipart/signed properly) and a utility
+     called 'smime' to call all this stuff. This is based on code I
+     originally wrote for Celo who have kindly allowed it to be
+     included in OpenSSL.
+     [Steve Henson]
+
+  *) Add variants des_set_key_checked and des_set_key_unchecked of
+     des_set_key (aka des_key_sched).  Global variable des_check_key
+     decides which of these is called by des_set_key; this way
+     des_check_key behaves as it always did, but applications and
+     the library itself, which was buggy for des_check_key == 1,
+     have a cleaner way to pick the version they need.
+     [Bodo Moeller]
+
+  *) New function PKCS12_newpass() which changes the password of a
+     PKCS12 structure.
+     [Steve Henson]
+
+  *) Modify X509_TRUST and X509_PURPOSE so it also uses a static and
+     dynamic mix. In both cases the ids can be used as an index into the
+     table. Also modified the X509_TRUST_add() and X509_PURPOSE_add()
+     functions so they accept a list of the field values and the
+     application doesn't need to directly manipulate the X509_TRUST
+     structure.
+     [Steve Henson]
+
+  *) Modify the ASN1_STRING_TABLE stuff so it also uses bsearch and doesn't
+     need initialising.
+     [Steve Henson]
+
+  *) Modify the way the V3 extension code looks up extensions. This now
+     works in a similar way to the object code: we have some "standard"
+     extensions in a static table which is searched with OBJ_bsearch()
+     and the application can add dynamic ones if needed. The file
+     crypto/x509v3/ext_dat.h now has the info: this file needs to be
+     updated whenever a new extension is added to the core code and kept
+     in ext_nid order. There is a simple program 'tabtest.c' which checks
+     this. New extensions are not added too often so this file can readily
+     be maintained manually.
+
+     There are two big advantages in doing things this way. The extensions
+     can be looked up immediately and no longer need to be "added" using
+     X509V3_add_standard_extensions(): this function now does nothing.
+     [Side note: I get *lots* of email saying the extension code doesn't
+      work because people forget to call this function]
+     Also no dynamic allocation is done unless new extensions are added:
+     so if we don't add custom extensions there is no need to call
+     X509V3_EXT_cleanup().
+     [Steve Henson]
+
+  *) Modify enc utility's salting as follows: make salting the default. Add a
+     magic header, so unsalted files fail gracefully instead of just decrypting
+     to garbage. This is because not salting is a big security hole, so people
+     should be discouraged from doing it.
+     [Ben Laurie]
+
+  *) Fixes and enhancements to the 'x509' utility. It allowed a message
+     digest to be passed on the command line but it only used this
+     parameter when signing a certificate. Modified so all relevant
+     operations are affected by the digest parameter including the
+     -fingerprint and -x509toreq options. Also -x509toreq choked if a
+     DSA key was used because it didn't fix the digest.
+     [Steve Henson]
+
+  *) Initial certificate chain verify code. Currently tests the untrusted
+     certificates for consistency with the verify purpose (which is set
+     when the X509_STORE_CTX structure is set up) and checks the pathlength.
+
+     There is a NO_CHAIN_VERIFY compilation option to keep the old behaviour:
+     this is because it will reject chains with invalid extensions whereas
+     every previous version of OpenSSL and SSLeay made no checks at all.
+
+     Trust code: checks the root CA for the relevant trust settings. Trust
+     settings have an initial value consistent with the verify purpose: e.g.
+     if the verify purpose is for SSL client use it expects the CA to be
+     trusted for SSL client use. However the default value can be changed to
+     permit custom trust settings: one example of this would be to only trust
+     certificates from a specific "secure" set of CAs.
+
+     Also added X509_STORE_CTX_new() and X509_STORE_CTX_free() functions
+     which should be used for version portability: especially since the
+     verify structure is likely to change more often now.
+
+     SSL integration. Add purpose and trust to SSL_CTX and SSL and functions
+     to set them. If not set then assume SSL clients will verify SSL servers
+     and vice versa.
+
+     Two new options to the verify program: -untrusted allows a set of
+     untrusted certificates to be passed in and -purpose which sets the
+     intended purpose of the certificate. If a purpose is set then the
+     new chain verify code is used to check extension consistency.
+     [Steve Henson]
+
+  *) Support for the authority information access extension.
+     [Steve Henson]
+
+  *) Modify RSA and DSA PEM read routines to transparently handle
+     PKCS#8 format private keys. New *_PUBKEY_* functions that handle
+     public keys in a format compatible with certificate
+     SubjectPublicKeyInfo structures. Unfortunately there were already
+     functions called *_PublicKey_* which used various odd formats so
+     these are retained for compatibility: however the DSA variants were
+     never in a public release so they have been deleted. Changed dsa/rsa
+     utilities to handle the new format: note no releases ever handled public
+     keys so we should be OK.
+
+     The primary motivation for this change is to avoid the same fiasco
+     that dogs private keys: there are several incompatible private key
+     formats some of which are standard and some OpenSSL specific and
+     require various evil hacks to allow partial transparent handling and
+     even then it doesn't work with DER formats. Given the option anything
+     other than PKCS#8 should be dumped: but the other formats have to
+     stay in the name of compatibility.
+
+     With public keys and the benefit of hindsight one standard format 
+     is used which works with EVP_PKEY, RSA or DSA structures: though
+     it clearly returns an error if you try to read the wrong kind of key.
+
+     Added a -pubkey option to the 'x509' utility to output the public key.
+     Also rename the EVP_PKEY_get_*() to EVP_PKEY_rget_*()
+     (renamed to EVP_PKEY_get1_*() in the OpenSSL 0.9.5 release) and add
+     EVP_PKEY_rset_*() functions (renamed to EVP_PKEY_set1_*())
+     that do the same as the EVP_PKEY_assign_*() except they up the
+     reference count of the added key (they don't "swallow" the
+     supplied key).
+     [Steve Henson]
+
+  *) Fixes to crypto/x509/by_file.c the code to read in certificates and
+     CRLs would fail if the file contained no certificates or no CRLs:
+     added a new function to read in both types and return the number
+     read: this means that if none are read it will be an error. The
+     DER versions of the certificate and CRL reader would always fail
+     because it isn't possible to mix certificates and CRLs in DER format
+     without choking one or the other routine. Changed this to just read
+     a certificate: this is the best we can do. Also modified the code
+     in apps/verify.c to take notice of return codes: it was previously
+     attempting to read in certificates from NULL pointers and ignoring
+     any errors: this is one reason why the cert and CRL reader seemed
+     to work. It doesn't check return codes from the default certificate
+     routines: these may well fail if the certificates aren't installed.
+     [Steve Henson]
+
+  *) Code to support otherName option in GeneralName.
+     [Steve Henson]
+
+  *) First update to verify code. Change the verify utility
+     so it warns if it is passed a self signed certificate:
+     for consistency with the normal behaviour. X509_verify
+     has been modified to it will now verify a self signed
+     certificate if *exactly* the same certificate appears
+     in the store: it was previously impossible to trust a
+     single self signed certificate. This means that:
+     openssl verify ss.pem
+     now gives a warning about a self signed certificate but
+     openssl verify -CAfile ss.pem ss.pem
+     is OK.
+     [Steve Henson]
+
+  *) For servers, store verify_result in SSL_SESSION data structure
+     (and add it to external session representation).
+     This is needed when client certificate verifications fails,
+     but an application-provided verification callback (set by
+     SSL_CTX_set_cert_verify_callback) allows accepting the session
+     anyway (i.e. leaves x509_store_ctx->error != X509_V_OK
+     but returns 1): When the session is reused, we have to set
+     ssl->verify_result to the appropriate error code to avoid
+     security holes.
+     [Bodo Moeller, problem pointed out by Lutz Jaenicke]
+
+  *) Fix a bug in the new PKCS#7 code: it didn't consider the
+     case in PKCS7_dataInit() where the signed PKCS7 structure
+     didn't contain any existing data because it was being created.
+     [Po-Cheng Chen <pocheng@nst.com.tw>, slightly modified by Steve Henson]
+
+  *) Add a salt to the key derivation routines in enc.c. This
+     forms the first 8 bytes of the encrypted file. Also add a
+     -S option to allow a salt to be input on the command line.
+     [Steve Henson]
+
+  *) New function X509_cmp(). Oddly enough there wasn't a function
+     to compare two certificates. We do this by working out the SHA1
+     hash and comparing that. X509_cmp() will be needed by the trust
+     code.
+     [Steve Henson]
+
+  *) SSL_get1_session() is like SSL_get_session(), but increments
+     the reference count in the SSL_SESSION returned.
+     [Geoff Thorpe <geoff@eu.c2.net>]
+
+  *) Fix for 'req': it was adding a null to request attributes.
+     Also change the X509_LOOKUP and X509_INFO code to handle
+     certificate auxiliary information.
+     [Steve Henson]
+
+  *) Add support for 40 and 64 bit RC2 and RC4 algorithms: document
+     the 'enc' command.
+     [Steve Henson]
+
+  *) Add the possibility to add extra information to the memory leak
+     detecting output, to form tracebacks, showing from where each
+     allocation was originated: CRYPTO_push_info("constant string") adds
+     the string plus current file name and line number to a per-thread
+     stack, CRYPTO_pop_info() does the obvious, CRYPTO_remove_all_info()
+     is like calling CYRPTO_pop_info() until the stack is empty.
+     Also updated memory leak detection code to be multi-thread-safe.
+     [Richard Levitte]
+
+  *) Add options -text and -noout to pkcs7 utility and delete the
+     encryption options which never did anything. Update docs.
+     [Steve Henson]
+
+  *) Add options to some of the utilities to allow the pass phrase
+     to be included on either the command line (not recommended on
+     OSes like Unix) or read from the environment. Update the
+     manpages and fix a few bugs.
+     [Steve Henson]
+
+  *) Add a few manpages for some of the openssl commands.
+     [Steve Henson]
+
+  *) Fix the -revoke option in ca. It was freeing up memory twice,
+     leaking and not finding already revoked certificates.
+     [Steve Henson]
+
+  *) Extensive changes to support certificate auxiliary information.
+     This involves the use of X509_CERT_AUX structure and X509_AUX
+     functions. An X509_AUX function such as PEM_read_X509_AUX()
+     can still read in a certificate file in the usual way but it
+     will also read in any additional "auxiliary information". By
+     doing things this way a fair degree of compatibility can be
+     retained: existing certificates can have this information added
+     using the new 'x509' options. 
+
+     Current auxiliary information includes an "alias" and some trust
+     settings. The trust settings will ultimately be used in enhanced
+     certificate chain verification routines: currently a certificate
+     can only be trusted if it is self signed and then it is trusted
+     for all purposes.
+     [Steve Henson]
+
+  *) Fix assembler for Alpha (tested only on DEC OSF not Linux or *BSD).
+     The problem was that one of the replacement routines had not been working
+     since SSLeay releases.  For now the offending routine has been replaced
+     with non-optimised assembler.  Even so, this now gives around 95%
+     performance improvement for 1024 bit RSA signs.
+     [Mark Cox]
+
+  *) Hack to fix PKCS#7 decryption when used with some unorthodox RC2 
+     handling. Most clients have the effective key size in bits equal to
+     the key length in bits: so a 40 bit RC2 key uses a 40 bit (5 byte) key.
+     A few however don't do this and instead use the size of the decrypted key
+     to determine the RC2 key length and the AlgorithmIdentifier to determine
+     the effective key length. In this case the effective key length can still
+     be 40 bits but the key length can be 168 bits for example. This is fixed
+     by manually forcing an RC2 key into the EVP_PKEY structure because the
+     EVP code can't currently handle unusual RC2 key sizes: it always assumes
+     the key length and effective key length are equal.
+     [Steve Henson]
+
+  *) Add a bunch of functions that should simplify the creation of 
+     X509_NAME structures. Now you should be able to do:
+     X509_NAME_add_entry_by_txt(nm, "CN", MBSTRING_ASC, "Steve", -1, -1, 0);
+     and have it automatically work out the correct field type and fill in
+     the structures. The more adventurous can try:
+     X509_NAME_add_entry_by_txt(nm, field, MBSTRING_UTF8, str, -1, -1, 0);
+     and it will (hopefully) work out the correct multibyte encoding.
+     [Steve Henson]
+
+  *) Change the 'req' utility to use the new field handling and multibyte
+     copy routines. Before the DN field creation was handled in an ad hoc
+     way in req, ca, and x509 which was rather broken and didn't support
+     BMPStrings or UTF8Strings. Since some software doesn't implement
+     BMPStrings or UTF8Strings yet, they can be enabled using the config file
+     using the dirstring_type option. See the new comment in the default
+     openssl.cnf for more info.
+     [Steve Henson]
+
+  *) Make crypto/rand/md_rand.c more robust:
+     - Assure unique random numbers after fork().
+     - Make sure that concurrent threads access the global counter and
+       md serializably so that we never lose entropy in them
+       or use exactly the same state in multiple threads.
+       Access to the large state is not always serializable because
+       the additional locking could be a performance killer, and
+       md should be large enough anyway.
+     [Bodo Moeller]
+
+  *) New file apps/app_rand.c with commonly needed functionality
+     for handling the random seed file.
+
+     Use the random seed file in some applications that previously did not:
+          ca,
+          dsaparam -genkey (which also ignored its '-rand' option), 
+          s_client,
+          s_server,
+          x509 (when signing).
+     Except on systems with /dev/urandom, it is crucial to have a random
+     seed file at least for key creation, DSA signing, and for DH exchanges;
+     for RSA signatures we could do without one.
+
+     gendh and gendsa (unlike genrsa) used to read only the first byte
+     of each file listed in the '-rand' option.  The function as previously
+     found in genrsa is now in app_rand.c and is used by all programs
+     that support '-rand'.
+     [Bodo Moeller]
+
+  *) In RAND_write_file, use mode 0600 for creating files;
+     don't just chmod when it may be too late.
+     [Bodo Moeller]
+
+  *) Report an error from X509_STORE_load_locations
+     when X509_LOOKUP_load_file or X509_LOOKUP_add_dir failed.
+     [Bill Perry]
+
+  *) New function ASN1_mbstring_copy() this copies a string in either
+     ASCII, Unicode, Universal (4 bytes per character) or UTF8 format
+     into an ASN1_STRING type. A mask of permissible types is passed
+     and it chooses the "minimal" type to use or an error if not type
+     is suitable.
+     [Steve Henson]
+
+  *) Add function equivalents to the various macros in asn1.h. The old
+     macros are retained with an M_ prefix. Code inside the library can
+     use the M_ macros. External code (including the openssl utility)
+     should *NOT* in order to be "shared library friendly".
+     [Steve Henson]
+
+  *) Add various functions that can check a certificate's extensions
+     to see if it usable for various purposes such as SSL client,
+     server or S/MIME and CAs of these types. This is currently 
+     VERY EXPERIMENTAL but will ultimately be used for certificate chain
+     verification. Also added a -purpose flag to x509 utility to
+     print out all the purposes.
+     [Steve Henson]
+
+  *) Add a CRYPTO_EX_DATA to X509 certificate structure and associated
+     functions.
+     [Steve Henson]
+
+  *) New X509V3_{X509,CRL,REVOKED}_get_d2i() functions. These will search
+     for, obtain and decode and extension and obtain its critical flag.
+     This allows all the necessary extension code to be handled in a
+     single function call.
+     [Steve Henson]
+
+  *) RC4 tune-up featuring 30-40% performance improvement on most RISC
+     platforms. See crypto/rc4/rc4_enc.c for further details.
+     [Andy Polyakov]
+
+  *) New -noout option to asn1parse. This causes no output to be produced
+     its main use is when combined with -strparse and -out to extract data
+     from a file (which may not be in ASN.1 format).
+     [Steve Henson]
+
+  *) Fix for pkcs12 program. It was hashing an invalid certificate pointer
+     when producing the local key id.
+     [Richard Levitte <levitte@stacken.kth.se>]
+
+  *) New option -dhparam in s_server. This allows a DH parameter file to be
+     stated explicitly. If it is not stated then it tries the first server
+     certificate file. The previous behaviour hard coded the filename
+     "server.pem".
+     [Steve Henson]
+
+  *) Add -pubin and -pubout options to the rsa and dsa commands. These allow
+     a public key to be input or output. For example:
+     openssl rsa -in key.pem -pubout -out pubkey.pem
+     Also added necessary DSA public key functions to handle this.
+     [Steve Henson]
+
+  *) Fix so PKCS7_dataVerify() doesn't crash if no certificates are contained
+     in the message. This was handled by allowing
+     X509_find_by_issuer_and_serial() to tolerate a NULL passed to it.
+     [Steve Henson, reported by Sampo Kellomaki <sampo@mail.neuronio.pt>]
+
+  *) Fix for bug in d2i_ASN1_bytes(): other ASN1 functions add an extra null
+     to the end of the strings whereas this didn't. This would cause problems
+     if strings read with d2i_ASN1_bytes() were later modified.
+     [Steve Henson, reported by Arne Ansper <arne@ats.cyber.ee>]
+
+  *) Fix for base64 decode bug. When a base64 bio reads only one line of
+     data and it contains EOF it will end up returning an error. This is
+     caused by input 46 bytes long. The cause is due to the way base64
+     BIOs find the start of base64 encoded data. They do this by trying a
+     trial decode on each line until they find one that works. When they
+     do a flag is set and it starts again knowing it can pass all the
+     data directly through the decoder. Unfortunately it doesn't reset
+     the context it uses. This means that if EOF is reached an attempt
+     is made to pass two EOFs through the context and this causes the
+     resulting error. This can also cause other problems as well. As is
+     usual with these problems it takes *ages* to find and the fix is
+     trivial: move one line.
+     [Steve Henson, reported by ian@uns.ns.ac.yu (Ivan Nejgebauer) ]
+
+  *) Ugly workaround to get s_client and s_server working under Windows. The
+     old code wouldn't work because it needed to select() on sockets and the
+     tty (for keypresses and to see if data could be written). Win32 only
+     supports select() on sockets so we select() with a 1s timeout on the
+     sockets and then see if any characters are waiting to be read, if none
+     are present then we retry, we also assume we can always write data to
+     the tty. This isn't nice because the code then blocks until we've
+     received a complete line of data and it is effectively polling the
+     keyboard at 1s intervals: however it's quite a bit better than not
+     working at all :-) A dedicated Windows application might handle this
+     with an event loop for example.
+     [Steve Henson]
+
+  *) Enhance RSA_METHOD structure. Now there are two extra methods, rsa_sign
+     and rsa_verify. When the RSA_FLAGS_SIGN_VER option is set these functions
+     will be called when RSA_sign() and RSA_verify() are used. This is useful
+     if rsa_pub_dec() and rsa_priv_enc() equivalents are not available.
+     For this to work properly RSA_public_decrypt() and RSA_private_encrypt()
+     should *not* be used: RSA_sign() and RSA_verify() must be used instead.
+     This necessitated the support of an extra signature type NID_md5_sha1
+     for SSL signatures and modifications to the SSL library to use it instead
+     of calling RSA_public_decrypt() and RSA_private_encrypt().
+     [Steve Henson]
+
+  *) Add new -verify -CAfile and -CApath options to the crl program, these
+     will lookup a CRL issuers certificate and verify the signature in a
+     similar way to the verify program. Tidy up the crl program so it
+     no longer accesses structures directly. Make the ASN1 CRL parsing a bit
+     less strict. It will now permit CRL extensions even if it is not
+     a V2 CRL: this will allow it to tolerate some broken CRLs.
+     [Steve Henson]
+
+  *) Initialize all non-automatic variables each time one of the openssl
+     sub-programs is started (this is necessary as they may be started
+     multiple times from the "OpenSSL>" prompt).
+     [Lennart Bang, Bodo Moeller]
+
+  *) Preliminary compilation option RSA_NULL which disables RSA crypto without
+     removing all other RSA functionality (this is what NO_RSA does). This
+     is so (for example) those in the US can disable those operations covered
+     by the RSA patent while allowing storage and parsing of RSA keys and RSA
+     key generation.
+     [Steve Henson]
+
+  *) Non-copying interface to BIO pairs.
+     (still largely untested)
+     [Bodo Moeller]
+
+  *) New function ANS1_tag2str() to convert an ASN1 tag to a descriptive
+     ASCII string. This was handled independently in various places before.
+     [Steve Henson]
+
+  *) New functions UTF8_getc() and UTF8_putc() that parse and generate
+     UTF8 strings a character at a time.
+     [Steve Henson]
+
+  *) Use client_version from client hello to select the protocol
+     (s23_srvr.c) and for RSA client key exchange verification
+     (s3_srvr.c), as required by the SSL 3.0/TLS 1.0 specifications.
+     [Bodo Moeller]
+
+  *) Add various utility functions to handle SPKACs, these were previously
+     handled by poking round in the structure internals. Added new function
+     NETSCAPE_SPKI_print() to print out SPKAC and a new utility 'spkac' to
+     print, verify and generate SPKACs. Based on an original idea from
+     Massimiliano Pala <madwolf@comune.modena.it> but extensively modified.
+     [Steve Henson]
+
+  *) RIPEMD160 is operational on all platforms and is back in 'make test'.
+     [Andy Polyakov]
+
+  *) Allow the config file extension section to be overwritten on the
+     command line. Based on an original idea from Massimiliano Pala
+     <madwolf@comune.modena.it>. The new option is called -extensions
+     and can be applied to ca, req and x509. Also -reqexts to override
+     the request extensions in req and -crlexts to override the crl extensions
+     in ca.
+     [Steve Henson]
+
+  *) Add new feature to the SPKAC handling in ca.  Now you can include
+     the same field multiple times by preceding it by "XXXX." for example:
+     1.OU="Unit name 1"
+     2.OU="Unit name 2"
+     this is the same syntax as used in the req config file.
+     [Steve Henson]
+
+  *) Allow certificate extensions to be added to certificate requests. These
+     are specified in a 'req_extensions' option of the req section of the
+     config file. They can be printed out with the -text option to req but
+     are otherwise ignored at present.
+     [Steve Henson]
+
+  *) Fix a horrible bug in enc_read() in crypto/evp/bio_enc.c: if the first
+     data read consists of only the final block it would not decrypted because
+     EVP_CipherUpdate() would correctly report zero bytes had been decrypted.
+     A misplaced 'break' also meant the decrypted final block might not be
+     copied until the next read.
+     [Steve Henson]
+
+  *) Initial support for DH_METHOD. Again based on RSA_METHOD. Also added
+     a few extra parameters to the DH structure: these will be useful if
+     for example we want the value of 'q' or implement X9.42 DH.
+     [Steve Henson]
+
+  *) Initial support for DSA_METHOD. This is based on the RSA_METHOD and
+     provides hooks that allow the default DSA functions or functions on a
+     "per key" basis to be replaced. This allows hardware acceleration and
+     hardware key storage to be handled without major modification to the
+     library. Also added low level modexp hooks and CRYPTO_EX structure and 
+     associated functions.
+     [Steve Henson]
+
+  *) Add a new flag to memory BIOs, BIO_FLAG_MEM_RDONLY. This marks the BIO
+     as "read only": it can't be written to and the buffer it points to will
+     not be freed. Reading from a read only BIO is much more efficient than
+     a normal memory BIO. This was added because there are several times when
+     an area of memory needs to be read from a BIO. The previous method was
+     to create a memory BIO and write the data to it, this results in two
+     copies of the data and an O(n^2) reading algorithm. There is a new
+     function BIO_new_mem_buf() which creates a read only memory BIO from
+     an area of memory. Also modified the PKCS#7 routines to use read only
+     memory BIOs.
+     [Steve Henson]
+
+  *) Bugfix: ssl23_get_client_hello did not work properly when called in
+     state SSL23_ST_SR_CLNT_HELLO_B, i.e. when the first 7 bytes of
+     a SSLv2-compatible client hello for SSLv3 or TLSv1 could be read,
+     but a retry condition occured while trying to read the rest.
+     [Bodo Moeller]
+
+  *) The PKCS7_ENC_CONTENT_new() function was setting the content type as
+     NID_pkcs7_encrypted by default: this was wrong since this should almost
+     always be NID_pkcs7_data. Also modified the PKCS7_set_type() to handle
+     the encrypted data type: this is a more sensible place to put it and it
+     allows the PKCS#12 code to be tidied up that duplicated this
+     functionality.
+     [Steve Henson]
+
+  *) Changed obj_dat.pl script so it takes its input and output files on
+     the command line. This should avoid shell escape redirection problems
+     under Win32.
+     [Steve Henson]
+
+  *) Initial support for certificate extension requests, these are included
+     in things like Xenroll certificate requests. Included functions to allow
+     extensions to be obtained and added.
+     [Steve Henson]
+
+  *) -crlf option to s_client and s_server for sending newlines as
+     CRLF (as required by many protocols).
+     [Bodo Moeller]
+
+ Changes between 0.9.3a and 0.9.4  [09 Aug 1999]
+  
+  *) Install libRSAglue.a when OpenSSL is built with RSAref.
+     [Ralf S. Engelschall]
+
+  *) A few more ``#ifndef NO_FP_API / #endif'' pairs for consistency.
+     [Andrija Antonijevic <TheAntony2@bigfoot.com>]
+
+  *) Fix -startdate and -enddate (which was missing) arguments to 'ca'
+     program.
+     [Steve Henson]
+
+  *) New function DSA_dup_DH, which duplicates DSA parameters/keys as
+     DH parameters/keys (q is lost during that conversion, but the resulting
+     DH parameters contain its length).
+
+     For 1024-bit p, DSA_generate_parameters followed by DSA_dup_DH is
+     much faster than DH_generate_parameters (which creates parameters
+     where p = 2*q + 1), and also the smaller q makes DH computations
+     much more efficient (160-bit exponentiation instead of 1024-bit
+     exponentiation); so this provides a convenient way to support DHE
+     ciphersuites in SSL/TLS servers (see ssl/ssltest.c).  It is of
+     utter importance to use
+         SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
+     or
+         SSL_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
+     when such DH parameters are used, because otherwise small subgroup
+     attacks may become possible!
+     [Bodo Moeller]
+
+  *) Avoid memory leak in i2d_DHparams.
+     [Bodo Moeller]
+
+  *) Allow the -k option to be used more than once in the enc program:
+     this allows the same encrypted message to be read by multiple recipients.
+     [Steve Henson]
+
+  *) New function OBJ_obj2txt(buf, buf_len, a, no_name), this converts
+     an ASN1_OBJECT to a text string. If the "no_name" parameter is set then
+     it will always use the numerical form of the OID, even if it has a short
+     or long name.
+     [Steve Henson]
+
+  *) Added an extra RSA flag: RSA_FLAG_EXT_PKEY. Previously the rsa_mod_exp
+     method only got called if p,q,dmp1,dmq1,iqmp components were present,
+     otherwise bn_mod_exp was called. In the case of hardware keys for example
+     no private key components need be present and it might store extra data
+     in the RSA structure, which cannot be accessed from bn_mod_exp.
+     By setting RSA_FLAG_EXT_PKEY rsa_mod_exp will always be called for
+     private key operations.
+     [Steve Henson]
+
+  *) Added support for SPARC Linux.
+     [Andy Polyakov]
+
+  *) pem_password_cb function type incompatibly changed from
+          typedef int pem_password_cb(char *buf, int size, int rwflag);
+     to
+          ....(char *buf, int size, int rwflag, void *userdata);
+     so that applications can pass data to their callbacks:
+     The PEM[_ASN1]_{read,write}... functions and macros now take an
+     additional void * argument, which is just handed through whenever
+     the password callback is called.
+     [Damien Miller <dmiller@ilogic.com.au>; tiny changes by Bodo Moeller]
+
+     New function SSL_CTX_set_default_passwd_cb_userdata.
+
+     Compatibility note: As many C implementations push function arguments
+     onto the stack in reverse order, the new library version is likely to
+     interoperate with programs that have been compiled with the old
+     pem_password_cb definition (PEM_whatever takes some data that
+     happens to be on the stack as its last argument, and the callback
+     just ignores this garbage); but there is no guarantee whatsoever that
+     this will work.
+
+  *) The -DPLATFORM="\"$(PLATFORM)\"" definition and the similar -DCFLAGS=...
+     (both in crypto/Makefile.ssl for use by crypto/cversion.c) caused
+     problems not only on Windows, but also on some Unix platforms.
+     To avoid problematic command lines, these definitions are now in an
+     auto-generated file crypto/buildinf.h (created by crypto/Makefile.ssl
+     for standard "make" builds, by util/mk1mf.pl for "mk1mf" builds).
+     [Bodo Moeller]
+
+  *) MIPS III/IV assembler module is reimplemented.
+     [Andy Polyakov]
+
+  *) More DES library cleanups: remove references to srand/rand and
+     delete an unused file.
+     [Ulf Möller]
+
+  *) Add support for the the free Netwide assembler (NASM) under Win32,
+     since not many people have MASM (ml) and it can be hard to obtain.
+     This is currently experimental but it seems to work OK and pass all
+     the tests. Check out INSTALL.W32 for info.
+     [Steve Henson]
+
+  *) Fix memory leaks in s3_clnt.c: All non-anonymous SSL3/TLS1 connections
+     without temporary keys kept an extra copy of the server key,
+     and connections with temporary keys did not free everything in case
+     of an error.
+     [Bodo Moeller]
+
+  *) New function RSA_check_key and new openssl rsa option -check
+     for verifying the consistency of RSA keys.
+     [Ulf Moeller, Bodo Moeller]
+
+  *) Various changes to make Win32 compile work: 
+     1. Casts to avoid "loss of data" warnings in p5_crpt2.c
+     2. Change unsigned int to int in b_dump.c to avoid "signed/unsigned
+        comparison" warnings.
+     3. Add sk_<TYPE>_sort to DEF file generator and do make update.
+     [Steve Henson]
+
+  *) Add a debugging option to PKCS#5 v2 key generation function: when
+     you #define DEBUG_PKCS5V2 passwords, salts, iteration counts and
+     derived keys are printed to stderr.
+     [Steve Henson]
+
+  *) Copy the flags in ASN1_STRING_dup().
+     [Roman E. Pavlov <pre@mo.msk.ru>]
+
+  *) The x509 application mishandled signing requests containing DSA
+     keys when the signing key was also DSA and the parameters didn't match.
+
+     It was supposed to omit the parameters when they matched the signing key:
+     the verifying software was then supposed to automatically use the CA's
+     parameters if they were absent from the end user certificate.
+
+     Omitting parameters is no longer recommended. The test was also
+     the wrong way round! This was probably due to unusual behaviour in
+     EVP_cmp_parameters() which returns 1 if the parameters match. 
+     This meant that parameters were omitted when they *didn't* match and
+     the certificate was useless. Certificates signed with 'ca' didn't have
+     this bug.
+     [Steve Henson, reported by Doug Erickson <Doug.Erickson@Part.NET>]
+
+  *) Memory leak checking (-DCRYPTO_MDEBUG) had some problems.
+     The interface is as follows:
+     Applications can use
+         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) aka MemCheck_start(),
+         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) aka MemCheck_stop();
+     "off" is now the default.
+     The library internally uses
+         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE) aka MemCheck_off(),
+         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE) aka MemCheck_on()
+     to disable memory-checking temporarily.
+
+     Some inconsistent states that previously were possible (and were
+     even the default) are now avoided.
+
+     -DCRYPTO_MDEBUG_TIME is new and additionally stores the current time
+     with each memory chunk allocated; this is occasionally more helpful
+     than just having a counter.
+
+     -DCRYPTO_MDEBUG_THREAD is also new and adds the thread ID.
+
+     -DCRYPTO_MDEBUG_ALL enables all of the above, plus any future
+     extensions.
+     [Bodo Moeller]
+
+  *) Introduce "mode" for SSL structures (with defaults in SSL_CTX),
+     which largely parallels "options", but is for changing API behaviour,
+     whereas "options" are about protocol behaviour.
+     Initial "mode" flags are:
+
+     SSL_MODE_ENABLE_PARTIAL_WRITE   Allow SSL_write to report success when
+                                     a single record has been written.
+     SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER  Don't insist that SSL_write
+                                     retries use the same buffer location.
+                                     (But all of the contents must be
+                                     copied!)
+     [Bodo Moeller]
+
+  *) Bugfix: SSL_set_options ignored its parameter, only SSL_CTX_set_options
+     worked.
+
+  *) Fix problems with no-hmac etc.
+     [Ulf Möller, pointed out by Brian Wellington <bwelling@tislabs.com>]
+
+  *) New functions RSA_get_default_method(), RSA_set_method() and
+     RSA_get_method(). These allows replacement of RSA_METHODs without having
+     to mess around with the internals of an RSA structure.
+     [Steve Henson]
+
+  *) Fix memory leaks in DSA_do_sign and DSA_is_prime.
+     Also really enable memory leak checks in openssl.c and in some
+     test programs.
+     [Chad C. Mulligan, Bodo Moeller]
+
+  *) Fix a bug in d2i_ASN1_INTEGER() and i2d_ASN1_INTEGER() which can mess
+     up the length of negative integers. This has now been simplified to just
+     store the length when it is first determined and use it later, rather
+     than trying to keep track of where data is copied and updating it to
+     point to the end.
+     [Steve Henson, reported by Brien Wheeler
+      <bwheeler@authentica-security.com>]
+
+  *) Add a new function PKCS7_signatureVerify. This allows the verification
+     of a PKCS#7 signature but with the signing certificate passed to the
+     function itself. This contrasts with PKCS7_dataVerify which assumes the
+     certificate is present in the PKCS#7 structure. This isn't always the
+     case: certificates can be omitted from a PKCS#7 structure and be
+     distributed by "out of band" means (such as a certificate database).
+     [Steve Henson]
+
+  *) Complete the PEM_* macros with DECLARE_PEM versions to replace the
+     function prototypes in pem.h, also change util/mkdef.pl to add the
+     necessary function names. 
+     [Steve Henson]
+
+  *) mk1mf.pl (used by Windows builds) did not properly read the
+     options set by Configure in the top level Makefile, and Configure
+     was not even able to write more than one option correctly.
+     Fixed, now "no-idea no-rc5 -DCRYPTO_MDEBUG" etc. works as intended.
+     [Bodo Moeller]
+
+  *) New functions CONF_load_bio() and CONF_load_fp() to allow a config
+     file to be loaded from a BIO or FILE pointer. The BIO version will
+     for example allow memory BIOs to contain config info.
+     [Steve Henson]
+
+  *) New function "CRYPTO_num_locks" that returns CRYPTO_NUM_LOCKS.
+     Whoever hopes to achieve shared-library compatibility across versions
+     must use this, not the compile-time macro.
+     (Exercise 0.9.4: Which is the minimum library version required by
+     such programs?)
+     Note: All this applies only to multi-threaded programs, others don't
+     need locks.
+     [Bodo Moeller]
+
+  *) Add missing case to s3_clnt.c state machine -- one of the new SSL tests
+     through a BIO pair triggered the default case, i.e.
+     SSLerr(...,SSL_R_UNKNOWN_STATE).
+     [Bodo Moeller]
+
+  *) New "BIO pair" concept (crypto/bio/bss_bio.c) so that applications
+     can use the SSL library even if none of the specific BIOs is
+     appropriate.
+     [Bodo Moeller]
+
+  *) Fix a bug in i2d_DSAPublicKey() which meant it returned the wrong value
+     for the encoded length.
+     [Jeon KyoungHo <khjeon@sds.samsung.co.kr>]
+
+  *) Add initial documentation of the X509V3 functions.
+     [Steve Henson]
+
+  *) Add a new pair of functions PEM_write_PKCS8PrivateKey() and 
+     PEM_write_bio_PKCS8PrivateKey() that are equivalent to
+     PEM_write_PrivateKey() and PEM_write_bio_PrivateKey() but use the more
+     secure PKCS#8 private key format with a high iteration count.
+     [Steve Henson]
+
+  *) Fix determination of Perl interpreter: A perl or perl5
+     _directory_ in $PATH was also accepted as the interpreter.
+     [Ralf S. Engelschall]
+
+  *) Fix demos/sign/sign.c: well there wasn't anything strictly speaking
+     wrong with it but it was very old and did things like calling
+     PEM_ASN1_read() directly and used MD5 for the hash not to mention some
+     unusual formatting.
+     [Steve Henson]
+
+  *) Fix demos/selfsign.c: it used obsolete and deleted functions, changed
+     to use the new extension code.
+     [Steve Henson]
+
+  *) Implement the PEM_read/PEM_write functions in crypto/pem/pem_all.c
+     with macros. This should make it easier to change their form, add extra
+     arguments etc. Fix a few PEM prototypes which didn't have cipher as a
+     constant.
+     [Steve Henson]
+
+  *) Add to configuration table a new entry that can specify an alternative
+     name for unistd.h (for pre-POSIX systems); we need this for NeXTstep,
+     according to Mark Crispin <MRC@Panda.COM>.
+     [Bodo Moeller]
+
+#if 0
+  *) DES CBC did not update the IV. Weird.
+     [Ben Laurie]
+#else
+     des_cbc_encrypt does not update the IV, but des_ncbc_encrypt does.
+     Changing the behaviour of the former might break existing programs --
+     where IV updating is needed, des_ncbc_encrypt can be used.
+#endif
+
+  *) When bntest is run from "make test" it drives bc to check its
+     calculations, as well as internally checking them. If an internal check
+     fails, it needs to cause bc to give a non-zero result or make test carries
+     on without noticing the failure. Fixed.
+     [Ben Laurie]
+
+  *) DES library cleanups.
+     [Ulf Möller]
+
+  *) Add support for PKCS#5 v2.0 PBE algorithms. This will permit PKCS#8 to be
+     used with any cipher unlike PKCS#5 v1.5 which can at most handle 64 bit
+     ciphers. NOTE: although the key derivation function has been verified
+     against some published test vectors it has not been extensively tested
+     yet. Added a -v2 "cipher" option to pkcs8 application to allow the use
+     of v2.0.
+     [Steve Henson]
+
+  *) Instead of "mkdir -p", which is not fully portable, use new
+     Perl script "util/mkdir-p.pl".
+     [Bodo Moeller]
+
+  *) Rewrite the way password based encryption (PBE) is handled. It used to
+     assume that the ASN1 AlgorithmIdentifier parameter was a PBEParameter
+     structure. This was true for the PKCS#5 v1.5 and PKCS#12 PBE algorithms
+     but doesn't apply to PKCS#5 v2.0 where it can be something else. Now
+     the 'parameter' field of the AlgorithmIdentifier is passed to the
+     underlying key generation function so it must do its own ASN1 parsing.
+     This has also changed the EVP_PBE_CipherInit() function which now has a
+     'parameter' argument instead of literal salt and iteration count values
+     and the function EVP_PBE_ALGOR_CipherInit() has been deleted.
+     [Steve Henson]
+
+  *) Support for PKCS#5 v1.5 compatible password based encryption algorithms
+     and PKCS#8 functionality. New 'pkcs8' application linked to openssl.
+     Needed to change the PEM_STRING_EVP_PKEY value which was just "PRIVATE
+     KEY" because this clashed with PKCS#8 unencrypted string. Since this
+     value was just used as a "magic string" and not used directly its
+     value doesn't matter.
+     [Steve Henson]
+
+  *) Introduce some semblance of const correctness to BN. Shame C doesn't
+     support mutable.
+     [Ben Laurie]
+
+  *) "linux-sparc64" configuration (ultrapenguin).
+     [Ray Miller <ray.miller@oucs.ox.ac.uk>]
+     "linux-sparc" configuration.
+     [Christian Forster <fo@hawo.stw.uni-erlangen.de>]
+
+  *) config now generates no-xxx options for missing ciphers.
+     [Ulf Möller]
+
+  *) Support the EBCDIC character set (work in progress).
+     File ebcdic.c not yet included because it has a different license.
+     [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>]
+
+  *) Support BS2000/OSD-POSIX.
+     [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>]
+
+  *) Make callbacks for key generation use void * instead of char *.
+     [Ben Laurie]
+
+  *) Make S/MIME samples compile (not yet tested).
+     [Ben Laurie]
+
+  *) Additional typesafe stacks.
+     [Ben Laurie]
+
+  *) New configuration variants "bsdi-elf-gcc" (BSD/OS 4.x).
+     [Bodo Moeller]
+
+
+ Changes between 0.9.3 and 0.9.3a  [29 May 1999]
+
+  *) New configuration variant "sco5-gcc".
+
+  *) Updated some demos.
+     [Sean O Riordain, Wade Scholine]
+
+  *) Add missing BIO_free at exit of pkcs12 application.
+     [Wu Zhigang]
+
+  *) Fix memory leak in conf.c.
+     [Steve Henson]
+
+  *) Updates for Win32 to assembler version of MD5.
+     [Steve Henson]
+
+  *) Set #! path to perl in apps/der_chop to where we found it
+     instead of using a fixed path.
+     [Bodo Moeller]
+
+  *) SHA library changes for irix64-mips4-cc.
+     [Andy Polyakov]
+
+  *) Improvements for VMS support.
+     [Richard Levitte]
+
+
+ Changes between 0.9.2b and 0.9.3  [24 May 1999]
+
+  *) Bignum library bug fix. IRIX 6 passes "make test" now!
+     This also avoids the problems with SC4.2 and unpatched SC5.  
+     [Andy Polyakov <appro@fy.chalmers.se>]
+
+  *) New functions sk_num, sk_value and sk_set to replace the previous macros.
+     These are required because of the typesafe stack would otherwise break 
+     existing code. If old code used a structure member which used to be STACK
+     and is now STACK_OF (for example cert in a PKCS7_SIGNED structure) with
+     sk_num or sk_value it would produce an error because the num, data members
+     are not present in STACK_OF. Now it just produces a warning. sk_set
+     replaces the old method of assigning a value to sk_value
+     (e.g. sk_value(x, i) = y) which the library used in a few cases. Any code
+     that does this will no longer work (and should use sk_set instead) but
+     this could be regarded as a "questionable" behaviour anyway.
+     [Steve Henson]
+
+  *) Fix most of the other PKCS#7 bugs. The "experimental" code can now
+     correctly handle encrypted S/MIME data.
+     [Steve Henson]
+
+  *) Change type of various DES function arguments from des_cblock
+     (which means, in function argument declarations, pointer to char)
+     to des_cblock * (meaning pointer to array with 8 char elements),
+     which allows the compiler to do more typechecking; it was like
+     that back in SSLeay, but with lots of ugly casts.
+
+     Introduce new type const_des_cblock.
+     [Bodo Moeller]
+
+  *) Reorganise the PKCS#7 library and get rid of some of the more obvious
+     problems: find RecipientInfo structure that matches recipient certificate
+     and initialise the ASN1 structures properly based on passed cipher.
+     [Steve Henson]
+
+  *) Belatedly make the BN tests actually check the results.
+     [Ben Laurie]
+
+  *) Fix the encoding and decoding of negative ASN1 INTEGERS and conversion
+     to and from BNs: it was completely broken. New compilation option
+     NEG_PUBKEY_BUG to allow for some broken certificates that encode public
+     key elements as negative integers.
+     [Steve Henson]
+
+  *) Reorganize and speed up MD5.
+     [Andy Polyakov <appro@fy.chalmers.se>]
+
+  *) VMS support.
+     [Richard Levitte <richard@levitte.org>]
+
+  *) New option -out to asn1parse to allow the parsed structure to be
+     output to a file. This is most useful when combined with the -strparse
+     option to examine the output of things like OCTET STRINGS.
+     [Steve Henson]
+
+  *) Make SSL library a little more fool-proof by not requiring any longer
+     that SSL_set_{accept,connect}_state be called before
+     SSL_{accept,connect} may be used (SSL_set_..._state is omitted
+     in many applications because usually everything *appeared* to work as
+     intended anyway -- now it really works as intended).
+     [Bodo Moeller]
+
+  *) Move openssl.cnf out of lib/.
+     [Ulf Möller]
+
+  *) Fix various things to let OpenSSL even pass ``egcc -pipe -O2 -Wall
+     -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes
+     -Wmissing-declarations -Wnested-externs -Winline'' with EGCS 1.1.2+ 
+     [Ralf S. Engelschall]
+
+  *) Various fixes to the EVP and PKCS#7 code. It may now be able to
+     handle PKCS#7 enveloped data properly.
+     [Sebastian Akerman <sak@parallelconsulting.com>, modified by Steve]
+
+  *) Create a duplicate of the SSL_CTX's CERT in SSL_new instead of
+     copying pointers.  The cert_st handling is changed by this in
+     various ways (and thus what used to be known as ctx->default_cert
+     is now called ctx->cert, since we don't resort to s->ctx->[default_]cert
+     any longer when s->cert does not give us what we need).
+     ssl_cert_instantiate becomes obsolete by this change.
+     As soon as we've got the new code right (possibly it already is?),
+     we have solved a couple of bugs of the earlier code where s->cert
+     was used as if it could not have been shared with other SSL structures.
+
+     Note that using the SSL API in certain dirty ways now will result
+     in different behaviour than observed with earlier library versions:
+     Changing settings for an SSL_CTX *ctx after having done s = SSL_new(ctx)
+     does not influence s as it used to.
+     
+     In order to clean up things more thoroughly, inside SSL_SESSION
+     we don't use CERT any longer, but a new structure SESS_CERT
+     that holds per-session data (if available); currently, this is
+     the peer's certificate chain and, for clients, the server's certificate
+     and temporary key.  CERT holds only those values that can have
+     meaningful defaults in an SSL_CTX.
+     [Bodo Moeller]
+
+  *) New function X509V3_EXT_i2d() to create an X509_EXTENSION structure
+     from the internal representation. Various PKCS#7 fixes: remove some
+     evil casts and set the enc_dig_alg field properly based on the signing
+     key type.
+     [Steve Henson]
+
+  *) Allow PKCS#12 password to be set from the command line or the
+     environment. Let 'ca' get its config file name from the environment
+     variables "OPENSSL_CONF" or "SSLEAY_CONF" (for consistency with 'req'
+     and 'x509').
+     [Steve Henson]
+
+  *) Allow certificate policies extension to use an IA5STRING for the
+     organization field. This is contrary to the PKIX definition but
+     VeriSign uses it and IE5 only recognises this form. Document 'x509'
+     extension option.
+     [Steve Henson]
+
+  *) Add PEDANTIC compiler flag to allow compilation with gcc -pedantic,
+     without disallowing inline assembler and the like for non-pedantic builds.
+     [Ben Laurie]
+
+  *) Support Borland C++ builder.
+     [Janez Jere <jj@void.si>, modified by Ulf Möller]
+
+  *) Support Mingw32.
+     [Ulf Möller]
+
+  *) SHA-1 cleanups and performance enhancements.
+     [Andy Polyakov <appro@fy.chalmers.se>]
+
+  *) Sparc v8plus assembler for the bignum library.
+     [Andy Polyakov <appro@fy.chalmers.se>]
+
+  *) Accept any -xxx and +xxx compiler options in Configure.
+     [Ulf Möller]
+
+  *) Update HPUX configuration.
+     [Anonymous]
+  
+  *) Add missing sk_<type>_unshift() function to safestack.h
+     [Ralf S. Engelschall]
+
+  *) New function SSL_CTX_use_certificate_chain_file that sets the
+     "extra_cert"s in addition to the certificate.  (This makes sense
+     only for "PEM" format files, as chains as a whole are not
+     DER-encoded.)
+     [Bodo Moeller]
+
+  *) Support verify_depth from the SSL API.
+     x509_vfy.c had what can be considered an off-by-one-error:
+     Its depth (which was not part of the external interface)
+     was actually counting the number of certificates in a chain;
+     now it really counts the depth.
+     [Bodo Moeller]
+
+  *) Bugfix in crypto/x509/x509_cmp.c: The SSLerr macro was used
+     instead of X509err, which often resulted in confusing error
+     messages since the error codes are not globally unique
+     (e.g. an alleged error in ssl3_accept when a certificate
+     didn't match the private key).
+
+  *) New function SSL_CTX_set_session_id_context that allows to set a default
+     value (so that you don't need SSL_set_session_id_context for each
+     connection using the SSL_CTX).
+     [Bodo Moeller]
+
+  *) OAEP decoding bug fix.
+     [Ulf Möller]
+
+  *) Support INSTALL_PREFIX for package builders, as proposed by
+     David Harris.
+     [Bodo Moeller]
+
+  *) New Configure options "threads" and "no-threads".  For systems
+     where the proper compiler options are known (currently Solaris
+     and Linux), "threads" is the default.
+     [Bodo Moeller]
+
+  *) New script util/mklink.pl as a faster substitute for util/mklink.sh.
+     [Bodo Moeller]
+
+  *) Install various scripts to $(OPENSSLDIR)/misc, not to
+     $(INSTALLTOP)/bin -- they shouldn't clutter directories
+     such as /usr/local/bin.
+     [Bodo Moeller]
+
+  *) "make linux-shared" to build shared libraries.
+     [Niels Poppe <niels@netbox.org>]
+
+  *) New Configure option no-<cipher> (rsa, idea, rc5, ...).
+     [Ulf Möller]
+
+  *) Add the PKCS#12 API documentation to openssl.txt. Preliminary support for
+     extension adding in x509 utility.
+     [Steve Henson]
+
+  *) Remove NOPROTO sections and error code comments.
+     [Ulf Möller]
+
+  *) Partial rewrite of the DEF file generator to now parse the ANSI
+     prototypes.
+     [Steve Henson]
+
+  *) New Configure options --prefix=DIR and --openssldir=DIR.
+     [Ulf Möller]
+
+  *) Complete rewrite of the error code script(s). It is all now handled
+     by one script at the top level which handles error code gathering,
+     header rewriting and C source file generation. It should be much better
+     than the old method: it now uses a modified version of Ulf's parser to
+     read the ANSI prototypes in all header files (thus the old K&R definitions
+     aren't needed for error creation any more) and do a better job of
+     translating function codes into names. The old 'ASN1 error code imbedded
+     in a comment' is no longer necessary and it doesn't use .err files which
+     have now been deleted. Also the error code call doesn't have to appear all
+     on one line (which resulted in some large lines...).
+     [Steve Henson]
+
+  *) Change #include filenames from <foo.h> to <openssl/foo.h>.
+     [Bodo Moeller]
+
+  *) Change behaviour of ssl2_read when facing length-0 packets: Don't return
+     0 (which usually indicates a closed connection), but continue reading.
+     [Bodo Moeller]
+
+  *) Fix some race conditions.
+     [Bodo Moeller]
+
+  *) Add support for CRL distribution points extension. Add Certificate
+     Policies and CRL distribution points documentation.
+     [Steve Henson]
+
+  *) Move the autogenerated header file parts to crypto/opensslconf.h.
+     [Ulf Möller]
+
+  *) Fix new 56-bit DES export ciphersuites: they were using 7 bytes instead of
+     8 of keying material. Merlin has also confirmed interop with this fix
+     between OpenSSL and Baltimore C/SSL 2.0 and J/SSL 2.0.
+     [Merlin Hughes <merlin@baltimore.ie>]
+
+  *) Fix lots of warnings.
+     [Richard Levitte <levitte@stacken.kth.se>]
+ 
+  *) In add_cert_dir() in crypto/x509/by_dir.c, break out of the loop if
+     the directory spec didn't end with a LIST_SEPARATOR_CHAR.
+     [Richard Levitte <levitte@stacken.kth.se>]
+ 
+  *) Fix problems with sizeof(long) == 8.
+     [Andy Polyakov <appro@fy.chalmers.se>]
+
+  *) Change functions to ANSI C.
+     [Ulf Möller]
+
+  *) Fix typos in error codes.
+     [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>, Ulf Möller]
+
+  *) Remove defunct assembler files from Configure.
+     [Ulf Möller]
+
+  *) SPARC v8 assembler BIGNUM implementation.
+     [Andy Polyakov <appro@fy.chalmers.se>]
+
+  *) Support for Certificate Policies extension: both print and set.
+     Various additions to support the r2i method this uses.
+     [Steve Henson]
+
+  *) A lot of constification, and fix a bug in X509_NAME_oneline() that could
+     return a const string when you are expecting an allocated buffer.
+     [Ben Laurie]
+
+  *) Add support for ASN1 types UTF8String and VISIBLESTRING, also the CHOICE
+     types DirectoryString and DisplayText.
+     [Steve Henson]
+
+  *) Add code to allow r2i extensions to access the configuration database,
+     add an LHASH database driver and add several ctx helper functions.
+     [Steve Henson]
+
+  *) Fix an evil bug in bn_expand2() which caused various BN functions to
+     fail when they extended the size of a BIGNUM.
+     [Steve Henson]
+
+  *) Various utility functions to handle SXNet extension. Modify mkdef.pl to
+     support typesafe stack.
+     [Steve Henson]
+
+  *) Fix typo in SSL_[gs]et_options().
+     [Nils Frostberg <nils@medcom.se>]
+
+  *) Delete various functions and files that belonged to the (now obsolete)
+     old X509V3 handling code.
+     [Steve Henson]
+
+  *) New Configure option "rsaref".
+     [Ulf Möller]
+
+  *) Don't auto-generate pem.h.
+     [Bodo Moeller]
+
+  *) Introduce type-safe ASN.1 SETs.
+     [Ben Laurie]
+
+  *) Convert various additional casted stacks to type-safe STACK_OF() variants.
+     [Ben Laurie, Ralf S. Engelschall, Steve Henson]
+
+  *) Introduce type-safe STACKs. This will almost certainly break lots of code
+     that links with OpenSSL (well at least cause lots of warnings), but fear
+     not: the conversion is trivial, and it eliminates loads of evil casts. A
+     few STACKed things have been converted already. Feel free to convert more.
+     In the fullness of time, I'll do away with the STACK type altogether.
+     [Ben Laurie]
+
+  *) Add `openssl ca -revoke <certfile>' facility which revokes a certificate
+     specified in <certfile> by updating the entry in the index.txt file.
+     This way one no longer has to edit the index.txt file manually for
+     revoking a certificate. The -revoke option does the gory details now.
+     [Massimiliano Pala <madwolf@openca.org>, Ralf S. Engelschall]
+
+  *) Fix `openssl crl -noout -text' combination where `-noout' killed the
+     `-text' option at all and this way the `-noout -text' combination was
+     inconsistent in `openssl crl' with the friends in `openssl x509|rsa|dsa'.
+     [Ralf S. Engelschall]
+
+  *) Make sure a corresponding plain text error message exists for the
+     X509_V_ERR_CERT_REVOKED/23 error number which can occur when a
+     verify callback function determined that a certificate was revoked.
+     [Ralf S. Engelschall]
+
+  *) Bugfix: In test/testenc, don't test "openssl <cipher>" for
+     ciphers that were excluded, e.g. by -DNO_IDEA.  Also, test
+     all available cipers including rc5, which was forgotten until now.
+     In order to let the testing shell script know which algorithms
+     are available, a new (up to now undocumented) command
+     "openssl list-cipher-commands" is used.
+     [Bodo Moeller]
+
+  *) Bugfix: s_client occasionally would sleep in select() when
+     it should have checked SSL_pending() first.
+     [Bodo Moeller]
+
+  *) New functions DSA_do_sign and DSA_do_verify to provide access to
+     the raw DSA values prior to ASN.1 encoding.
+     [Ulf Möller]
+
+  *) Tweaks to Configure
+     [Niels Poppe <niels@netbox.org>]
+
+  *) Add support for PKCS#5 v2.0 ASN1 PBES2 structures. No other support,
+     yet...
+     [Steve Henson]
+
+  *) New variables $(RANLIB) and $(PERL) in the Makefiles.
+     [Ulf Möller]
+
+  *) New config option to avoid instructions that are illegal on the 80386.
+     The default code is faster, but requires at least a 486.
+     [Ulf Möller]
+  
+  *) Got rid of old SSL2_CLIENT_VERSION (inconsistently used) and
+     SSL2_SERVER_VERSION (not used at all) macros, which are now the
+     same as SSL2_VERSION anyway.
+     [Bodo Moeller]
+
+  *) New "-showcerts" option for s_client.
+     [Bodo Moeller]
+
+  *) Still more PKCS#12 integration. Add pkcs12 application to openssl
+     application. Various cleanups and fixes.
+     [Steve Henson]
+
+  *) More PKCS#12 integration. Add new pkcs12 directory with Makefile.ssl and
+     modify error routines to work internally. Add error codes and PBE init
+     to library startup routines.
+     [Steve Henson]
+
+  *) Further PKCS#12 integration. Added password based encryption, PKCS#8 and
+     packing functions to asn1 and evp. Changed function names and error
+     codes along the way.
+     [Steve Henson]
+
+  *) PKCS12 integration: and so it begins... First of several patches to
+     slowly integrate PKCS#12 functionality into OpenSSL. Add PKCS#12
+     objects to objects.h
+     [Steve Henson]
+
+  *) Add a new 'indent' option to some X509V3 extension code. Initial ASN1
+     and display support for Thawte strong extranet extension.
+     [Steve Henson]
+
+  *) Add LinuxPPC support.
+     [Jeff Dubrule <igor@pobox.org>]
+
+  *) Get rid of redundant BN file bn_mulw.c, and rename bn_div64 to
+     bn_div_words in alpha.s.
+     [Hannes Reinecke <H.Reinecke@hw.ac.uk> and Ben Laurie]
+
+  *) Make sure the RSA OAEP test is skipped under -DRSAref because
+     OAEP isn't supported when OpenSSL is built with RSAref.
+     [Ulf Moeller <ulf@fitug.de>]
+
+  *) Move definitions of IS_SET/IS_SEQUENCE inside crypto/asn1/asn1.h 
+     so they no longer are missing under -DNOPROTO. 
+     [Soren S. Jorvang <soren@t.dk>]
+
+
+ Changes between 0.9.1c and 0.9.2b  [22 Mar 1999]
+
+  *) Make SSL_get_peer_cert_chain() work in servers. Unfortunately, it still
+     doesn't work when the session is reused. Coming soon!
+     [Ben Laurie]
+
+  *) Fix a security hole, that allows sessions to be reused in the wrong
+     context thus bypassing client cert protection! All software that uses
+     client certs and session caches in multiple contexts NEEDS PATCHING to
+     allow session reuse! A fuller solution is in the works.
+     [Ben Laurie, problem pointed out by Holger Reif, Bodo Moeller (and ???)]
+
+  *) Some more source tree cleanups (removed obsolete files
+     crypto/bf/asm/bf586.pl, test/test.txt and crypto/sha/asm/f.s; changed
+     permission on "config" script to be executable) and a fix for the INSTALL
+     document.
+     [Ulf Moeller <ulf@fitug.de>]
+
+  *) Remove some legacy and erroneous uses of malloc, free instead of
+     Malloc, Free.
+     [Lennart Bang <lob@netstream.se>, with minor changes by Steve]
+
+  *) Make rsa_oaep_test return non-zero on error.
+     [Ulf Moeller <ulf@fitug.de>]
+
+  *) Add support for native Solaris shared libraries. Configure
+     solaris-sparc-sc4-pic, make, then run shlib/solaris-sc4.sh. It'd be nice
+     if someone would make that last step automatic.
+     [Matthias Loepfe <Matthias.Loepfe@AdNovum.CH>]
+
+  *) ctx_size was not built with the right compiler during "make links". Fixed.
+     [Ben Laurie]
+
+  *) Change the meaning of 'ALL' in the cipher list. It now means "everything
+     except NULL ciphers". This means the default cipher list will no longer
+     enable NULL ciphers. They need to be specifically enabled e.g. with
+     the string "DEFAULT:eNULL".
+     [Steve Henson]
+
+  *) Fix to RSA private encryption routines: if p < q then it would
+     occasionally produce an invalid result. This will only happen with
+     externally generated keys because OpenSSL (and SSLeay) ensure p > q.
+     [Steve Henson]
+
+  *) Be less restrictive and allow also `perl util/perlpath.pl
+     /path/to/bin/perl' in addition to `perl util/perlpath.pl /path/to/bin',
+     because this way one can also use an interpreter named `perl5' (which is
+     usually the name of Perl 5.xxx on platforms where an Perl 4.x is still
+     installed as `perl').
+     [Matthias Loepfe <Matthias.Loepfe@adnovum.ch>]
+
+  *) Let util/clean-depend.pl work also with older Perl 5.00x versions.
+     [Matthias Loepfe <Matthias.Loepfe@adnovum.ch>]
+
+  *) Fix Makefile.org so CC,CFLAG etc are passed to 'make links' add
+     advapi32.lib to Win32 build and change the pem test comparision
+     to fc.exe (thanks to Ulrich Kroener <kroneru@yahoo.com> for the
+     suggestion). Fix misplaced ASNI prototypes and declarations in evp.h
+     and crypto/des/ede_cbcm_enc.c.
+     [Steve Henson]
+
+  *) DES quad checksum was broken on big-endian architectures. Fixed.
+     [Ben Laurie]
+
+  *) Comment out two functions in bio.h that aren't implemented. Fix up the
+     Win32 test batch file so it (might) work again. The Win32 test batch file
+     is horrible: I feel ill....
+     [Steve Henson]
+
+  *) Move various #ifdefs around so NO_SYSLOG, NO_DIRENT etc are now selected
+     in e_os.h. Audit of header files to check ANSI and non ANSI
+     sections: 10 functions were absent from non ANSI section and not exported
+     from Windows DLLs. Fixed up libeay.num for new functions.
+     [Steve Henson]
+
+  *) Make `openssl version' output lines consistent.
+     [Ralf S. Engelschall]
+
+  *) Fix Win32 symbol export lists for BIO functions: Added
+     BIO_get_ex_new_index, BIO_get_ex_num, BIO_get_ex_data and BIO_set_ex_data
+     to ms/libeay{16,32}.def.
+     [Ralf S. Engelschall]
+
+  *) Second round of fixing the OpenSSL perl/ stuff. It now at least compiled
+     fine under Unix and passes some trivial tests I've now added. But the
+     whole stuff is horribly incomplete, so a README.1ST with a disclaimer was
+     added to make sure no one expects that this stuff really works in the
+     OpenSSL 0.9.2 release.  Additionally I've started to clean the XS sources
+     up and fixed a few little bugs and inconsistencies in OpenSSL.{pm,xs} and
+     openssl_bio.xs.
+     [Ralf S. Engelschall]
+
+  *) Fix the generation of two part addresses in perl.
+     [Kenji Miyake <kenji@miyake.org>, integrated by Ben Laurie]
+
+  *) Add config entry for Linux on MIPS.
+     [John Tobey <jtobey@channel1.com>]
+
+  *) Make links whenever Configure is run, unless we are on Windoze.
+     [Ben Laurie]
+
+  *) Permit extensions to be added to CRLs using crl_section in openssl.cnf.
+     Currently only issuerAltName and AuthorityKeyIdentifier make any sense
+     in CRLs.
+     [Steve Henson]
+
+  *) Add a useful kludge to allow package maintainers to specify compiler and
+     other platforms details on the command line without having to patch the
+     Configure script everytime: One now can use ``perl Configure
+     <id>:<details>'', i.e. platform ids are allowed to have details appended
+     to them (seperated by colons). This is treated as there would be a static
+     pre-configured entry in Configure's %table under key <id> with value
+     <details> and ``perl Configure <id>'' is called.  So, when you want to
+     perform a quick test-compile under FreeBSD 3.1 with pgcc and without
+     assembler stuff you can use ``perl Configure "FreeBSD-elf:pgcc:-O6:::"''
+     now, which overrides the FreeBSD-elf entry on-the-fly.
+     [Ralf S. Engelschall]
+
+  *) Disable new TLS1 ciphersuites by default: they aren't official yet.
+     [Ben Laurie]
+
+  *) Allow DSO flags like -fpic, -fPIC, -KPIC etc. to be specified
+     on the `perl Configure ...' command line. This way one can compile
+     OpenSSL libraries with Position Independent Code (PIC) which is needed
+     for linking it into DSOs.
+     [Ralf S. Engelschall]
+
+  *) Remarkably, export ciphers were totally broken and no-one had noticed!
+     Fixed.
+     [Ben Laurie]
+
+  *) Cleaned up the LICENSE document: The official contact for any license
+     questions now is the OpenSSL core team under openssl-core@openssl.org.
+     And add a paragraph about the dual-license situation to make sure people
+     recognize that _BOTH_ the OpenSSL license _AND_ the SSLeay license apply
+     to the OpenSSL toolkit.
+     [Ralf S. Engelschall]
+
+  *) General source tree makefile cleanups: Made `making xxx in yyy...'
+     display consistent in the source tree and replaced `/bin/rm' by `rm'.
+     Additonally cleaned up the `make links' target: Remove unnecessary
+     semicolons, subsequent redundant removes, inline point.sh into mklink.sh
+     to speed processing and no longer clutter the display with confusing
+     stuff. Instead only the actually done links are displayed.
+     [Ralf S. Engelschall]
+
+  *) Permit null encryption ciphersuites, used for authentication only. It used
+     to be necessary to set the preprocessor define SSL_ALLOW_ENULL to do this.
+     It is now necessary to set SSL_FORBID_ENULL to prevent the use of null
+     encryption.
+     [Ben Laurie]
+
+  *) Add a bunch of fixes to the PKCS#7 stuff. It used to sometimes reorder
+     signed attributes when verifying signatures (this would break them), 
+     the detached data encoding was wrong and public keys obtained using
+     X509_get_pubkey() weren't freed.
+     [Steve Henson]
+
+  *) Add text documentation for the BUFFER functions. Also added a work around
+     to a Win95 console bug. This was triggered by the password read stuff: the
+     last character typed gets carried over to the next fread(). If you were 
+     generating a new cert request using 'req' for example then the last
+     character of the passphrase would be CR which would then enter the first
+     field as blank.
+     [Steve Henson]
+
+  *) Added the new `Includes OpenSSL Cryptography Software' button as
+     doc/openssl_button.{gif,html} which is similar in style to the old SSLeay
+     button and can be used by applications based on OpenSSL to show the
+     relationship to the OpenSSL project.  
+     [Ralf S. Engelschall]
+
+  *) Remove confusing variables in function signatures in files
+     ssl/ssl_lib.c and ssl/ssl.h.
+     [Lennart Bong <lob@kulthea.stacken.kth.se>]
+
+  *) Don't install bss_file.c under PREFIX/include/
+     [Lennart Bong <lob@kulthea.stacken.kth.se>]
+
+  *) Get the Win32 compile working again. Modify mkdef.pl so it can handle
+     functions that return function pointers and has support for NT specific
+     stuff. Fix mk1mf.pl and VC-32.pl to support NT differences also. Various
+     #ifdef WIN32 and WINNTs sprinkled about the place and some changes from
+     unsigned to signed types: this was killing the Win32 compile.
+     [Steve Henson]
+
+  *) Add new certificate file to stack functions,
+     SSL_add_dir_cert_subjects_to_stack() and
+     SSL_add_file_cert_subjects_to_stack().  These largely supplant
+     SSL_load_client_CA_file(), and can be used to add multiple certs easily
+     to a stack (usually this is then handed to SSL_CTX_set_client_CA_list()).
+     This means that Apache-SSL and similar packages don't have to mess around
+     to add as many CAs as they want to the preferred list.
+     [Ben Laurie]
+
+  *) Experiment with doxygen documentation. Currently only partially applied to
+     ssl/ssl_lib.c.
+     See http://www.stack.nl/~dimitri/doxygen/index.html, and run doxygen with
+     openssl.doxy as the configuration file.
+     [Ben Laurie]
+  
+  *) Get rid of remaining C++-style comments which strict C compilers hate.
+     [Ralf S. Engelschall, pointed out by Carlos Amengual]
+
+  *) Changed BN_RECURSION in bn_mont.c to BN_RECURSION_MONT so it is not
+     compiled in by default: it has problems with large keys.
+     [Steve Henson]
+
+  *) Add a bunch of SSL_xxx() functions for configuring the temporary RSA and
+     DH private keys and/or callback functions which directly correspond to
+     their SSL_CTX_xxx() counterparts but work on a per-connection basis. This
+     is needed for applications which have to configure certificates on a
+     per-connection basis (e.g. Apache+mod_ssl) instead of a per-context basis
+     (e.g. s_server). 
+        For the RSA certificate situation is makes no difference, but
+     for the DSA certificate situation this fixes the "no shared cipher"
+     problem where the OpenSSL cipher selection procedure failed because the
+     temporary keys were not overtaken from the context and the API provided
+     no way to reconfigure them. 
+        The new functions now let applications reconfigure the stuff and they
+     are in detail: SSL_need_tmp_RSA, SSL_set_tmp_rsa, SSL_set_tmp_dh,
+     SSL_set_tmp_rsa_callback and SSL_set_tmp_dh_callback.  Additionally a new
+     non-public-API function ssl_cert_instantiate() is used as a helper
+     function and also to reduce code redundancy inside ssl_rsa.c.
+     [Ralf S. Engelschall]
+
+  *) Move s_server -dcert and -dkey options out of the undocumented feature
+     area because they are useful for the DSA situation and should be
+     recognized by the users.
+     [Ralf S. Engelschall]
+
+  *) Fix the cipher decision scheme for export ciphers: the export bits are
+     *not* within SSL_MKEY_MASK or SSL_AUTH_MASK, they are within
+     SSL_EXP_MASK.  So, the original variable has to be used instead of the
+     already masked variable.
+     [Richard Levitte <levitte@stacken.kth.se>]
+
+  *) Fix 'port' variable from `int' to `unsigned int' in crypto/bio/b_sock.c
+     [Richard Levitte <levitte@stacken.kth.se>]
+
+  *) Change type of another md_len variable in pk7_doit.c:PKCS7_dataFinal()
+     from `int' to `unsigned int' because it's a length and initialized by
+     EVP_DigestFinal() which expects an `unsigned int *'.
+     [Richard Levitte <levitte@stacken.kth.se>]
+
+  *) Don't hard-code path to Perl interpreter on shebang line of Configure
+     script. Instead use the usual Shell->Perl transition trick.
+     [Ralf S. Engelschall]
+
+  *) Make `openssl x509 -noout -modulus' functional also for DSA certificates
+     (in addition to RSA certificates) to match the behaviour of `openssl dsa
+     -noout -modulus' as it's already the case for `openssl rsa -noout
+     -modulus'.  For RSA the -modulus is the real "modulus" while for DSA
+     currently the public key is printed (a decision which was already done by
+     `openssl dsa -modulus' in the past) which serves a similar purpose.
+     Additionally the NO_RSA no longer completely removes the whole -modulus
+     option; it now only avoids using the RSA stuff. Same applies to NO_DSA
+     now, too.
+     [Ralf S.  Engelschall]
+
+  *) Add Arne Ansper's reliable BIO - this is an encrypted, block-digested
+     BIO. See the source (crypto/evp/bio_ok.c) for more info.
+     [Arne Ansper <arne@ats.cyber.ee>]
+
+  *) Dump the old yucky req code that tried (and failed) to allow raw OIDs
+     to be added. Now both 'req' and 'ca' can use new objects defined in the
+     config file.
+     [Steve Henson]
+
+  *) Add cool BIO that does syslog (or event log on NT).
+     [Arne Ansper <arne@ats.cyber.ee>, integrated by Ben Laurie]
+
+  *) Add support for new TLS ciphersuites, TLS_RSA_EXPORT56_WITH_RC4_56_MD5,
+     TLS_RSA_EXPORT56_WITH_RC2_CBC_56_MD5 and
+     TLS_RSA_EXPORT56_WITH_DES_CBC_SHA, as specified in "56-bit Export Cipher
+     Suites For TLS", draft-ietf-tls-56-bit-ciphersuites-00.txt.
+     [Ben Laurie]
+
+  *) Add preliminary config info for new extension code.
+     [Steve Henson]
+
+  *) Make RSA_NO_PADDING really use no padding.
+     [Ulf Moeller <ulf@fitug.de>]
+
+  *) Generate errors when private/public key check is done.
+     [Ben Laurie]
+
+  *) Overhaul for 'crl' utility. New function X509_CRL_print. Partial support
+     for some CRL extensions and new objects added.
+     [Steve Henson]
+
+  *) Really fix the ASN1 IMPLICIT bug this time... Partial support for private
+     key usage extension and fuller support for authority key id.
+     [Steve Henson]
+
+  *) Add OAEP encryption for the OpenSSL crypto library. OAEP is the improved
+     padding method for RSA, which is recommended for new applications in PKCS
+     #1 v2.0 (RFC 2437, October 1998).
+     OAEP (Optimal Asymmetric Encryption Padding) has better theoretical
+     foundations than the ad-hoc padding used in PKCS #1 v1.5. It is secure
+     against Bleichbacher's attack on RSA.
+     [Ulf Moeller <ulf@fitug.de>, reformatted, corrected and integrated by
+      Ben Laurie]
+
+  *) Updates to the new SSL compression code
+     [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
+
+  *) Fix so that the version number in the master secret, when passed
+     via RSA, checks that if TLS was proposed, but we roll back to SSLv3
+     (because the server will not accept higher), that the version number
+     is 0x03,0x01, not 0x03,0x00
+     [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
+
+  *) Run extensive memory leak checks on SSL apps. Fixed *lots* of memory
+     leaks in ssl/ relating to new X509_get_pubkey() behaviour. Also fixes
+     in apps/ and an unrelated leak in crypto/dsa/dsa_vrf.c
+     [Steve Henson]
+
+  *) Support for RAW extensions where an arbitrary extension can be
+     created by including its DER encoding. See apps/openssl.cnf for
+     an example.
+     [Steve Henson]
+
+  *) Make sure latest Perl versions don't interpret some generated C array
+     code as Perl array code in the crypto/err/err_genc.pl script.
+     [Lars Weber <3weber@informatik.uni-hamburg.de>]
+
+  *) Modify ms/do_ms.bat to not generate assembly language makefiles since
+     not many people have the assembler. Various Win32 compilation fixes and
+     update to the INSTALL.W32 file with (hopefully) more accurate Win32
+     build instructions.
+     [Steve Henson]
+
+  *) Modify configure script 'Configure' to automatically create crypto/date.h
+     file under Win32 and also build pem.h from pem.org. New script
+     util/mkfiles.pl to create the MINFO file on environments that can't do a
+     'make files': perl util/mkfiles.pl >MINFO should work.
+     [Steve Henson]
+
+  *) Major rework of DES function declarations, in the pursuit of correctness
+     and purity. As a result, many evil casts evaporated, and some weirdness,
+     too. You may find this causes warnings in your code. Zapping your evil
+     casts will probably fix them. Mostly.
+     [Ben Laurie]
+
+  *) Fix for a typo in asn1.h. Bug fix to object creation script
+     obj_dat.pl. It considered a zero in an object definition to mean
+     "end of object": none of the objects in objects.h have any zeros
+     so it wasn't spotted.
+     [Steve Henson, reported by Erwann ABALEA <eabalea@certplus.com>]
+
+  *) Add support for Triple DES Cipher Block Chaining with Output Feedback
+     Masking (CBCM). In the absence of test vectors, the best I have been able
+     to do is check that the decrypt undoes the encrypt, so far. Send me test
+     vectors if you have them.
+     [Ben Laurie]
+
+  *) Correct calculation of key length for export ciphers (too much space was
+     allocated for null ciphers). This has not been tested!
+     [Ben Laurie]
+
+  *) Modifications to the mkdef.pl for Win32 DEF file creation. The usage
+     message is now correct (it understands "crypto" and "ssl" on its
+     command line). There is also now an "update" option. This will update
+     the util/ssleay.num and util/libeay.num files with any new functions.
+     If you do a: 
+     perl util/mkdef.pl crypto ssl update
+     it will update them.
+     [Steve Henson]
+
+  *) Overhauled the Perl interface (perl/*):
+     - ported BN stuff to OpenSSL's different BN library
+     - made the perl/ source tree CVS-aware
+     - renamed the package from SSLeay to OpenSSL (the files still contain
+       their history because I've copied them in the repository)
+     - removed obsolete files (the test scripts will be replaced
+       by better Test::Harness variants in the future)
+     [Ralf S. Engelschall]
+
+  *) First cut for a very conservative source tree cleanup:
+     1. merge various obsolete readme texts into doc/ssleay.txt
+     where we collect the old documents and readme texts.
+     2. remove the first part of files where I'm already sure that we no
+     longer need them because of three reasons: either they are just temporary
+     files which were left by Eric or they are preserved original files where
+     I've verified that the diff is also available in the CVS via "cvs diff
+     -rSSLeay_0_8_1b" or they were renamed (as it was definitely the case for
+     the crypto/md/ stuff).
+     [Ralf S. Engelschall]
+
+  *) More extension code. Incomplete support for subject and issuer alt
+     name, issuer and authority key id. Change the i2v function parameters
+     and add an extra 'crl' parameter in the X509V3_CTX structure: guess
+     what that's for :-) Fix to ASN1 macro which messed up
+     IMPLICIT tag and add f_enum.c which adds a2i, i2a for ENUMERATED.
+     [Steve Henson]
+
+  *) Preliminary support for ENUMERATED type. This is largely copied from the
+     INTEGER code.
+     [Steve Henson]
+
+  *) Add new function, EVP_MD_CTX_copy() to replace frequent use of memcpy.
+     [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
+
+  *) Make sure `make rehash' target really finds the `openssl' program.
+     [Ralf S. Engelschall, Matthias Loepfe <Matthias.Loepfe@adnovum.ch>]
+
+  *) Squeeze another 7% of speed out of MD5 assembler, at least on a P2. I'd
+     like to hear about it if this slows down other processors.
+     [Ben Laurie]
+
+  *) Add CygWin32 platform information to Configure script.
+     [Alan Batie <batie@aahz.jf.intel.com>]
+
+  *) Fixed ms/32all.bat script: `no_asm' -> `no-asm'
+     [Rainer W. Gerling <gerling@mpg-gv.mpg.de>]
+  
+  *) New program nseq to manipulate netscape certificate sequences
+     [Steve Henson]
+
+  *) Modify crl2pkcs7 so it supports multiple -certfile arguments. Fix a
+     few typos.
+     [Steve Henson]
+
+  *) Fixes to BN code.  Previously the default was to define BN_RECURSION
+     but the BN code had some problems that would cause failures when
+     doing certificate verification and some other functions.
+     [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
+
+  *) Add ASN1 and PEM code to support netscape certificate sequences.
+     [Steve Henson]
+
+  *) Add ASN1 and PEM code to support netscape certificate sequences.
+     [Steve Henson]
+
+  *) Add several PKIX and private extended key usage OIDs.
+     [Steve Henson]
+
+  *) Modify the 'ca' program to handle the new extension code. Modify
+     openssl.cnf for new extension format, add comments.
+     [Steve Henson]
+
+  *) More X509 V3 changes. Fix typo in v3_bitstr.c. Add support to 'req'
+     and add a sample to openssl.cnf so req -x509 now adds appropriate
+     CA extensions.
+     [Steve Henson]
+
+  *) Continued X509 V3 changes. Add to other makefiles, integrate with the
+     error code, add initial support to X509_print() and x509 application.
+     [Steve Henson]
+
+  *) Takes a deep breath and start addding X509 V3 extension support code. Add
+     files in crypto/x509v3. Move original stuff to crypto/x509v3/old. All this
+     stuff is currently isolated and isn't even compiled yet.
+     [Steve Henson]
+
+  *) Continuing patches for GeneralizedTime. Fix up certificate and CRL
+     ASN1 to use ASN1_TIME and modify print routines to use ASN1_TIME_print.
+     Removed the versions check from X509 routines when loading extensions:
+     this allows certain broken certificates that don't set the version
+     properly to be processed.
+     [Steve Henson]
+
+  *) Deal with irritating shit to do with dependencies, in YAAHW (Yet Another
+     Ad Hoc Way) - Makefile.ssls now all contain local dependencies, which
+     can still be regenerated with "make depend".
+     [Ben Laurie]
+
+  *) Spelling mistake in C version of CAST-128.
+     [Ben Laurie, reported by Jeremy Hylton <jeremy@cnri.reston.va.us>]
+
+  *) Changes to the error generation code. The perl script err-code.pl 
+     now reads in the old error codes and retains the old numbers, only
+     adding new ones if necessary. It also only changes the .err files if new
+     codes are added. The makefiles have been modified to only insert errors
+     when needed (to avoid needlessly modifying header files). This is done
+     by only inserting errors if the .err file is newer than the auto generated
+     C file. To rebuild all the error codes from scratch (the old behaviour)
+     either modify crypto/Makefile.ssl to pass the -regen flag to err_code.pl
+     or delete all the .err files.
+     [Steve Henson]
+
+  *) CAST-128 was incorrectly implemented for short keys. The C version has
+     been fixed, but is untested. The assembler versions are also fixed, but
+     new assembler HAS NOT BEEN GENERATED FOR WIN32 - the Makefile needs fixing
+     to regenerate it if needed.
+     [Ben Laurie, reported (with fix for C version) by Jun-ichiro itojun
+      Hagino <itojun@kame.net>]
+
+  *) File was opened incorrectly in randfile.c.
+     [Ulf Möller <ulf@fitug.de>]
+
+  *) Beginning of support for GeneralizedTime. d2i, i2d, check and print
+     functions. Also ASN1_TIME suite which is a CHOICE of UTCTime or
+     GeneralizedTime. ASN1_TIME is the proper type used in certificates et
+     al: it's just almost always a UTCTime. Note this patch adds new error
+     codes so do a "make errors" if there are problems.
+     [Steve Henson]
+
+  *) Correct Linux 1 recognition in config.
+     [Ulf Möller <ulf@fitug.de>]
+
+  *) Remove pointless MD5 hash when using DSA keys in ca.
+     [Anonymous <nobody@replay.com>]
+
+  *) Generate an error if given an empty string as a cert directory. Also
+     generate an error if handed NULL (previously returned 0 to indicate an
+     error, but didn't set one).
+     [Ben Laurie, reported by Anonymous <nobody@replay.com>]
+
+  *) Add prototypes to SSL methods. Make SSL_write's buffer const, at last.
+     [Ben Laurie]
+
+  *) Fix the dummy function BN_ref_mod_exp() in rsaref.c to have the correct
+     parameters. This was causing a warning which killed off the Win32 compile.
+     [Steve Henson]
+
+  *) Remove C++ style comments from crypto/bn/bn_local.h.
+     [Neil Costigan <neil.costigan@celocom.com>]
+
+  *) The function OBJ_txt2nid was broken. It was supposed to return a nid
+     based on a text string, looking up short and long names and finally
+     "dot" format. The "dot" format stuff didn't work. Added new function
+     OBJ_txt2obj to do the same but return an ASN1_OBJECT and rewrote 
+     OBJ_txt2nid to use it. OBJ_txt2obj can also return objects even if the
+     OID is not part of the table.
+     [Steve Henson]
+
+  *) Add prototypes to X509 lookup/verify methods, fixing a bug in
+     X509_LOOKUP_by_alias().
+     [Ben Laurie]
+
+  *) Sort openssl functions by name.
+     [Ben Laurie]
+
+  *) Get the gendsa program working (hopefully) and add it to app list. Remove
+     encryption from sample DSA keys (in case anyone is interested the password
+     was "1234").
+     [Steve Henson]
+
+  *) Make _all_ *_free functions accept a NULL pointer.
+     [Frans Heymans <fheymans@isaserver.be>]
+
+  *) If a DH key is generated in s3_srvr.c, don't blow it by trying to use
+     NULL pointers.
+     [Anonymous <nobody@replay.com>]
+
+  *) s_server should send the CAfile as acceptable CAs, not its own cert.
+     [Bodo Moeller <3moeller@informatik.uni-hamburg.de>]
+
+  *) Don't blow it for numeric -newkey arguments to apps/req.
+     [Bodo Moeller <3moeller@informatik.uni-hamburg.de>]
+
+  *) Temp key "for export" tests were wrong in s3_srvr.c.
+     [Anonymous <nobody@replay.com>]
+
+  *) Add prototype for temp key callback functions
+     SSL_CTX_set_tmp_{rsa,dh}_callback().
+     [Ben Laurie]
+
+  *) Make DH_free() tolerate being passed a NULL pointer (like RSA_free() and
+     DSA_free()). Make X509_PUBKEY_set() check for errors in d2i_PublicKey().
+     [Steve Henson]
+
+  *) X509_name_add_entry() freed the wrong thing after an error.
+     [Arne Ansper <arne@ats.cyber.ee>]
+
+  *) rsa_eay.c would attempt to free a NULL context.
+     [Arne Ansper <arne@ats.cyber.ee>]
+
+  *) BIO_s_socket() had a broken should_retry() on Windoze.
+     [Arne Ansper <arne@ats.cyber.ee>]
+
+  *) BIO_f_buffer() didn't pass on BIO_CTRL_FLUSH.
+     [Arne Ansper <arne@ats.cyber.ee>]
+
+  *) Make sure the already existing X509_STORE->depth variable is initialized
+     in X509_STORE_new(), but document the fact that this variable is still
+     unused in the certificate verification process.
+     [Ralf S. Engelschall]
+
+  *) Fix the various library and apps files to free up pkeys obtained from
+     X509_PUBKEY_get() et al. Also allow x509.c to handle netscape extensions.
+     [Steve Henson]
+
+  *) Fix reference counting in X509_PUBKEY_get(). This makes
+     demos/maurice/example2.c work, amongst others, probably.
+     [Steve Henson and Ben Laurie]
+
+  *) First cut of a cleanup for apps/. First the `ssleay' program is now named
+     `openssl' and second, the shortcut symlinks for the `openssl <command>'
+     are no longer created. This way we have a single and consistent command
+     line interface `openssl <command>', similar to `cvs <command>'.
+     [Ralf S. Engelschall, Paul Sutton and Ben Laurie]
+
+  *) ca.c: move test for DSA keys inside #ifndef NO_DSA. Make pubkey
+     BIT STRING wrapper always have zero unused bits.
+     [Steve Henson]
+
+  *) Add CA.pl, perl version of CA.sh, add extended key usage OID.
+     [Steve Henson]
+
+  *) Make the top-level INSTALL documentation easier to understand.
+     [Paul Sutton]
+
+  *) Makefiles updated to exit if an error occurs in a sub-directory
+     make (including if user presses ^C) [Paul Sutton]
+
+  *) Make Montgomery context stuff explicit in RSA data structure.
+     [Ben Laurie]
+
+  *) Fix build order of pem and err to allow for generated pem.h.
+     [Ben Laurie]
+
+  *) Fix renumbering bug in X509_NAME_delete_entry().
+     [Ben Laurie]
+
+  *) Enhanced the err-ins.pl script so it makes the error library number 
+     global and can add a library name. This is needed for external ASN1 and
+     other error libraries.
+     [Steve Henson]
+
+  *) Fixed sk_insert which never worked properly.
+     [Steve Henson]
+
+  *) Fix ASN1 macros so they can handle indefinite length construted 
+     EXPLICIT tags. Some non standard certificates use these: they can now
+     be read in.
+     [Steve Henson]
+
+  *) Merged the various old/obsolete SSLeay documentation files (doc/xxx.doc)
+     into a single doc/ssleay.txt bundle. This way the information is still
+     preserved but no longer messes up this directory. Now it's new room for
+     the new set of documenation files.
+     [Ralf S. Engelschall]
+
+  *) SETs were incorrectly DER encoded. This was a major pain, because they
+     shared code with SEQUENCEs, which aren't coded the same. This means that
+     almost everything to do with SETs or SEQUENCEs has either changed name or
+     number of arguments.
+     [Ben Laurie, based on a partial fix by GP Jayan <gp@nsj.co.jp>]
+
+  *) Fix test data to work with the above.
+     [Ben Laurie]
+
+  *) Fix the RSA header declarations that hid a bug I fixed in 0.9.0b but
+     was already fixed by Eric for 0.9.1 it seems.
+     [Ben Laurie - pointed out by Ulf Möller <ulf@fitug.de>]
+
+  *) Autodetect FreeBSD3.
+     [Ben Laurie]
+
+  *) Fix various bugs in Configure. This affects the following platforms:
+     nextstep
+     ncr-scde
+     unixware-2.0
+     unixware-2.0-pentium
+     sco5-cc.
+     [Ben Laurie]
+
+  *) Eliminate generated files from CVS. Reorder tests to regenerate files
+     before they are needed.
+     [Ben Laurie]
+
+  *) Generate Makefile.ssl from Makefile.org (to keep CVS happy).
+     [Ben Laurie]
+
+
+ Changes between 0.9.1b and 0.9.1c  [23-Dec-1998]
+
+  *) Added OPENSSL_VERSION_NUMBER to crypto/crypto.h and 
+     changed SSLeay to OpenSSL in version strings.
+     [Ralf S. Engelschall]
+  
+  *) Some fixups to the top-level documents.
+     [Paul Sutton]
+
+  *) Fixed the nasty bug where rsaref.h was not found under compile-time
+     because the symlink to include/ was missing.
+     [Ralf S. Engelschall]
+
+  *) Incorporated the popular no-RSA/DSA-only patches 
+     which allow to compile a RSA-free SSLeay.
+     [Andrew Cooke / Interrader Ldt., Ralf S. Engelschall]
+
+  *) Fixed nasty rehash problem under `make -f Makefile.ssl links'
+     when "ssleay" is still not found.
+     [Ralf S. Engelschall]
+
+  *) Added more platforms to Configure: Cray T3E, HPUX 11, 
+     [Ralf S. Engelschall, Beckmann <beckman@acl.lanl.gov>]
+
+  *) Updated the README file.
+     [Ralf S. Engelschall]
+
+  *) Added various .cvsignore files in the CVS repository subdirs
+     to make a "cvs update" really silent.
+     [Ralf S. Engelschall]
+
+  *) Recompiled the error-definition header files and added
+     missing symbols to the Win32 linker tables.
+     [Ralf S. Engelschall]
+
+  *) Cleaned up the top-level documents;
+     o new files: CHANGES and LICENSE
+     o merged VERSION, HISTORY* and README* files a CHANGES.SSLeay 
+     o merged COPYRIGHT into LICENSE
+     o removed obsolete TODO file
+     o renamed MICROSOFT to INSTALL.W32
+     [Ralf S. Engelschall]
+
+  *) Removed dummy files from the 0.9.1b source tree: 
+     crypto/asn1/x crypto/bio/cd crypto/bio/fg crypto/bio/grep crypto/bio/vi
+     crypto/bn/asm/......add.c crypto/bn/asm/a.out crypto/dsa/f crypto/md5/f
+     crypto/pem/gmon.out crypto/perlasm/f crypto/pkcs7/build crypto/rsa/f
+     crypto/sha/asm/f crypto/threads/f ms/zzz ssl/f ssl/f.mak test/f
+     util/f.mak util/pl/f util/pl/f.mak crypto/bf/bf_locl.old apps/f
+     [Ralf S. Engelschall]
+
+  *) Added various platform portability fixes.
+     [Mark J. Cox]
+
+  *) The Genesis of the OpenSSL rpject:
+     We start with the latest (unreleased) SSLeay version 0.9.1b which Eric A.
+     Young and Tim J. Hudson created while they were working for C2Net until
+     summer 1998.
+     [The OpenSSL Project]
+ 
+
+ Changes between 0.9.0b and 0.9.1b  [not released]
+
+  *) Updated a few CA certificates under certs/
+     [Eric A. Young]
+
+  *) Changed some BIGNUM api stuff.
+     [Eric A. Young]
+
+  *) Various platform ports: OpenBSD, Ultrix, IRIX 64bit, NetBSD, 
+     DGUX x86, Linux Alpha, etc.
+     [Eric A. Young]
+
+  *) New COMP library [crypto/comp/] for SSL Record Layer Compression: 
+     RLE (dummy implemented) and ZLIB (really implemented when ZLIB is
+     available).
+     [Eric A. Young]
+
+  *) Add -strparse option to asn1pars program which parses nested 
+     binary structures 
+     [Dr Stephen Henson <shenson@bigfoot.com>]
+
+  *) Added "oid_file" to ssleay.cnf for "ca" and "req" programs.
+     [Eric A. Young]
+
+  *) DSA fix for "ca" program.
+     [Eric A. Young]
+
+  *) Added "-genkey" option to "dsaparam" program.
+     [Eric A. Young]
+
+  *) Added RIPE MD160 (rmd160) message digest.
+     [Eric A. Young]
+
+  *) Added -a (all) option to "ssleay version" command.
+     [Eric A. Young]
+
+  *) Added PLATFORM define which is the id given to Configure.
+     [Eric A. Young]
+
+  *) Added MemCheck_XXXX functions to crypto/mem.c for memory checking.
+     [Eric A. Young]
+
+  *) Extended the ASN.1 parser routines.
+     [Eric A. Young]
+
+  *) Extended BIO routines to support REUSEADDR, seek, tell, etc.
+     [Eric A. Young]
+
+  *) Added a BN_CTX to the BN library.
+     [Eric A. Young]
+
+  *) Fixed the weak key values in DES library
+     [Eric A. Young]
+
+  *) Changed API in EVP library for cipher aliases.
+     [Eric A. Young]
+
+  *) Added support for RC2/64bit cipher.
+     [Eric A. Young]
+
+  *) Converted the lhash library to the crypto/mem.c functions.
+     [Eric A. Young]
+
+  *) Added more recognized ASN.1 object ids.
+     [Eric A. Young]
+
+  *) Added more RSA padding checks for SSL/TLS.
+     [Eric A. Young]
+
+  *) Added BIO proxy/filter functionality.
+     [Eric A. Young]
+
+  *) Added extra_certs to SSL_CTX which can be used
+     send extra CA certificates to the client in the CA cert chain sending
+     process. It can be configured with SSL_CTX_add_extra_chain_cert().
+     [Eric A. Young]
+
+  *) Now Fortezza is denied in the authentication phase because
+     this is key exchange mechanism is not supported by SSLeay at all.
+     [Eric A. Young]
+
+  *) Additional PKCS1 checks.
+     [Eric A. Young]
+
+  *) Support the string "TLSv1" for all TLS v1 ciphers.
+     [Eric A. Young]
+
+  *) Added function SSL_get_ex_data_X509_STORE_CTX_idx() which gives the
+     ex_data index of the SSL context in the X509_STORE_CTX ex_data.
+     [Eric A. Young]
+
+  *) Fixed a few memory leaks.
+     [Eric A. Young]
+
+  *) Fixed various code and comment typos.
+     [Eric A. Young]
+
+  *) A minor bug in ssl/s3_clnt.c where there would always be 4 0 
+     bytes sent in the client random.
+     [Edward Bishop <ebishop@spyglass.com>]
+
diff --git a/openssl/CHANGES.SSLeay b/openssl/CHANGES.SSLeay
new file mode 100644
index 0000000..ca5cd72
--- /dev/null
+++ b/openssl/CHANGES.SSLeay
@@ -0,0 +1,968 @@
+This file contains the changes for the SSLeay library up to version
+0.9.0b. For later changes, see the file "CHANGES".
+
+  SSLeay CHANGES
+  ______________
+
+Changes between 0.8.x and 0.9.0b
+
+10-Apr-1998
+
+I said the next version would go out at easter, and so it shall.
+I expect a 0.9.1 will follow with portability fixes in the next few weeks.
+
+This is a quick, meet the deadline.  Look to ssl-users for comments on what
+is new etc.
+
+eric (about to go bushwalking for the 4 day easter break :-)
+
+16-Mar-98
+    - Patch for Cray T90 from Wayne Schroeder <schroede@SDSC.EDU>
+    - Lots and lots of changes
+
+29-Jan-98
+    - ASN1_BIT_STRING_set_bit()/ASN1_BIT_STRING_get_bit() from
+      Goetz Babin-Ebell <babinebell@trustcenter.de>.
+    - SSL_version() now returns SSL2_VERSION, SSL3_VERSION or
+      TLS1_VERSION.
+
+7-Jan-98
+    - Finally reworked the cipher string to ciphers again, so it
+      works correctly
+    - All the app_data stuff is now ex_data with funcion calls to access.
+      The index is supplied by a function and 'methods' can be setup
+      for the types that are called on XXX_new/XXX_free.  This lets
+      applications get notified on creation and destruction.  Some of
+      the RSA methods could be implemented this way and I may do so.
+    - Oh yes, SSL under perl5 is working at the basic level.
+
+15-Dec-97
+    - Warning - the gethostbyname cache is not fully thread safe,
+      but it should work well enough.
+    - Major internal reworking of the app_data stuff.  More functions
+      but if you were accessing ->app_data directly, things will
+      stop working.
+    - The perlv5 stuff is working.  Currently on message digests,
+      ciphers and the bignum library.
+
+9-Dec-97
+    - Modified re-negotiation so that server initated re-neg
+      will cause a SSL_read() to return -1 should retry.
+      The danger otherwise was that the server and the
+      client could end up both trying to read when using non-blocking
+      sockets.
+
+4-Dec-97
+    - Lots of small changes
+    - Fix for binaray mode in Windows for the FILE BIO, thanks to
+      Bob Denny <rdenny@dc3.com>
+
+17-Nov-97
+    - Quite a few internal cleanups, (removal of errno, and using macros
+      defined in e_os.h).
+    - A bug in ca.c, pointed out by yasuyuki-ito@d-cruise.co.jp, where
+      the automactic naming out output files was being stuffed up.
+
+29-Oct-97
+    - The Cast5 cipher has been added.  MD5 and SHA-1 are now in assember
+      for x86.
+
+21-Oct-97
+    - Fixed a bug in the BIO_gethostbyname() cache.
+
+15-Oct-97
+    - cbc mode for blowfish/des/3des is now in assember.  Blowfish asm
+      has also been improved.  At this point in time, on the pentium,
+      md5 is %80 faster, the unoptimesed sha-1 is %79 faster,
+      des-cbc is %28 faster, des-ede3-cbc is %9 faster and blowfish-cbc
+      is %62 faster.
+
+12-Oct-97
+    - MEM_BUF_grow() has been fixed so that it always sets the buf->length
+      to the value we are 'growing' to.  Think of MEM_BUF_grow() as the
+      way to set the length value correctly.
+
+10-Oct-97
+    - I now hash for certificate lookup on the raw DER encoded RDN (md5).
+      This breaks things again :-(.  This is efficent since I cache
+      the DER encoding of the RDN.
+    - The text DN now puts in the numeric OID instead of UNKNOWN.
+    - req can now process arbitary OIDs in the config file.
+    - I've been implementing md5 in x86 asm, much faster :-).
+    - Started sha1 in x86 asm, needs more work.
+    - Quite a few speedups in the BN stuff.  RSA public operation
+      has been made faster by caching the BN_MONT_CTX structure.
+      The calulating of the Ai where A*Ai === 1 mod m was rather
+      expensive.  Basically a 40-50% speedup on public operations.
+      The RSA speedup is now 15% on pentiums and %20 on pentium
+      pro.
+
+30-Sep-97
+    - After doing some profiling, I added x86 adm for bn_add_words(),
+      which just adds 2 arrays of longs together.  A %10 speedup
+      for 512 and 1024 bit RSA on the pentium pro.
+
+29-Sep-97
+    - Converted the x86 bignum assembler to us the perl scripts
+      for generation.
+
+23-Sep-97
+    - If SSL_set_session() is passed a NULL session, it now clears the
+      current session-id.
+
+22-Sep-97
+    - Added a '-ss_cert file' to apps/ca.c.  This will sign selfsigned
+      certificates.
+    - Bug in crypto/evp/encode.c where by decoding of 65 base64
+      encoded lines, one line at a time (via a memory BIO) would report
+      EOF after the first line was decoded.
+    - Fix in X509_find_by_issuer_and_serial() from
+      Dr Stephen Henson <shenson@bigfoot.com>
+
+19-Sep-97
+    - NO_FP_API and NO_STDIO added.
+    - Put in sh config command.  It auto runs Configure with the correct
+      parameters.
+
+18-Sep-97
+    - Fix x509.c so if a DSA cert has different parameters to its parent,
+      they are left in place.  Not tested yet.
+
+16-Sep-97
+    - ssl_create_cipher_list() had some bugs, fixes from
+      Patrick Eisenacher <eisenach@stud.uni-frankfurt.de>
+    - Fixed a bug in the Base64 BIO, where it would return 1 instead
+      of -1 when end of input was encountered but should retry.
+      Basically a Base64/Memory BIO interaction problem.
+    - Added a HMAC set of functions in preporarion for TLS work.
+
+15-Sep-97
+    - Top level makefile tweak - Cameron Simpson <cs@zip.com.au>
+    - Prime generation spead up %25 (512 bit prime, pentium pro linux)
+      by using montgomery multiplication in the prime number test.
+
+11-Sep-97
+    - Ugly bug in ssl3_write_bytes().  Basically if application land
+      does a SSL_write(ssl,buf,len) where len > 16k, the SSLv3 write code
+      did not check the size and tried to copy the entire buffer.
+      This would tend to cause memory overwrites since SSLv3 has
+      a maximum packet size of 16k.  If your program uses
+      buffers <= 16k, you would probably never see this problem.
+    - Fixed a few errors that were cause by malloc() not returning
+      0 initialised memory..
+    - SSL_OP_NETSCAPE_CA_DN_BUG was being switched on when using
+      SSL_CTX_set_options(ssl_ctx,SSL_OP_ALL); which was a bad thing
+      since this flags stops SSLeay being able to handle client
+      cert requests correctly.
+
+08-Sep-97
+    - SSL_SESS_CACHE_NO_INTERNAL_LOOKUP option added.  When switched
+      on, the SSL server routines will not use a SSL_SESSION that is
+      held in it's cache.  This in intended to be used with the session-id
+      callbacks so that while the session-ids are still stored in the
+      cache, the decision to use them and how to look them up can be
+      done by the callbacks.  The are the 'new', 'get' and 'remove'
+      callbacks.  This can be used to determine the session-id
+      to use depending on information like which port/host the connection
+      is coming from.  Since the are also SSL_SESSION_set_app_data() and
+      SSL_SESSION_get_app_data() functions, the application can hold
+      information against the session-id as well.
+
+03-Sep-97
+    - Added lookup of CRLs to the by_dir method,
+      X509_load_crl_file() also added.  Basically it means you can
+      lookup CRLs via the same system used to lookup certificates.
+    - Changed things so that the X509_NAME structure can contain
+      ASN.1 BIT_STRINGS which is required for the unique
+      identifier OID.
+    - Fixed some problems with the auto flushing of the session-id
+      cache.  It was not occuring on the server side.
+
+02-Sep-97
+    - Added SSL_CTX_sess_cache_size(SSL_CTX *ctx,unsigned long size)
+      which is the maximum number of entries allowed in the
+      session-id cache.  This is enforced with a simple FIFO list.
+      The default size is 20*1024 entries which is rather large :-).
+      The Timeout code is still always operating.
+
+01-Sep-97
+    - Added an argument to all the 'generate private key/prime`
+      callbacks.  It is the last parameter so this should not
+      break existing code but it is needed for C++.
+    - Added the BIO_FLAGS_BASE64_NO_NL flag for the BIO_f_base64()
+      BIO.  This lets the BIO read and write base64 encoded data
+      without inserting or looking for '\n' characters.  The '-A'
+      flag turns this on when using apps/enc.c.
+    - RSA_NO_PADDING added to help BSAFE functionality.  This is a
+      very dangerous thing to use, since RSA private key
+      operations without random padding bytes (as PKCS#1 adds) can
+      be attacked such that the private key can be revealed.
+    - ASN.1 bug and rc2-40-cbc and rc4-40 added by
+      Dr Stephen Henson <shenson@bigfoot.com>
+
+31-Aug-97 (stuff added while I was away)    
+    - Linux pthreads by Tim Hudson (tjh@cryptsoft.com).
+    - RSA_flags() added allowing bypass of pub/priv match check
+      in ssl/ssl_rsa.c - Tim Hudson.
+    - A few minor bugs.
+
+SSLeay 0.8.1 released.
+
+19-Jul-97
+    - Server side initated dynamic renegotiation is broken.  I will fix
+      it when I get back from holidays.
+
+15-Jul-97
+    - Quite a few small changes.
+    - INVALID_SOCKET usage cleanups from Alex Kiernan <alex@hisoft.co.uk>
+
+09-Jul-97
+    - Added 2 new values to the SSL info callback.
+      SSL_CB_START which is passed when the SSL protocol is started
+      and SSL_CB_DONE when it has finished sucsessfully.
+
+08-Jul-97
+    - Fixed a few bugs problems in apps/req.c and crypto/asn1/x_pkey.c
+      that related to DSA public/private keys.
+    - Added all the relevent PEM and normal IO functions to support
+      reading and writing RSAPublic keys.
+    - Changed makefiles to use ${AR} instead of 'ar r'
+
+07-Jul-97
+    - Error in ERR_remove_state() that would leave a dangling reference
+      to a free()ed location - thanks to Alex Kiernan <alex@hisoft.co.uk>
+    - s_client now prints the X509_NAMEs passed from the server
+      when requesting a client cert.
+    - Added a ssl->type, which is one of SSL_ST_CONNECT or
+      SSL_ST_ACCEPT.  I had to add it so I could tell if I was
+      a connect or an accept after the handshake had finished.
+    - SSL_get_client_CA_list(SSL *s) now returns the CA names
+      passed by the server if called by a client side SSL.
+
+05-Jul-97
+    - Bug in X509_NAME_get_text_by_OBJ(), looking starting at index
+      0, not -1 :-(  Fix from Tim Hudson (tjh@cryptsoft.com).
+
+04-Jul-97
+    - Fixed some things in X509_NAME_add_entry(), thanks to
+      Matthew Donald <matthew@world.net>.
+    - I had a look at the cipher section and though that it was a
+      bit confused, so I've changed it.
+    - I was not setting up the RC4-64-MD5 cipher correctly.  It is
+      a MS special that appears in exported MS Money.
+    - Error in all my DH ciphers.  Section 7.6.7.3 of the SSLv3
+      spec.  I was missing the two byte length header for the
+      ClientDiffieHellmanPublic value.  This is a packet sent from
+      the client to the server.  The SSL_OP_SSLEAY_080_CLIENT_DH_BUG
+      option will enable SSLeay server side SSLv3 accept either
+      the correct or my 080 packet format.
+    - Fixed a few typos in crypto/pem.org.
+
+02-Jul-97
+    - Alias mapping for EVP_get_(digest|cipher)byname is now
+      performed before a lookup for actual cipher.  This means
+      that an alias can be used to 're-direct' a cipher or a
+      digest.
+    - ASN1_read_bio() had a bug that only showed up when using a
+      memory BIO.  When EOF is reached in the memory BIO, it is
+      reported as a -1 with BIO_should_retry() set to true.
+
+01-Jul-97
+    - Fixed an error in X509_verify_cert() caused by my
+      miss-understanding how 'do { contine } while(0);' works.
+      Thanks to Emil Sit <sit@mit.edu> for educating me :-)
+
+30-Jun-97
+    - Base64 decoding error.  If the last data line did not end with
+      a '=', sometimes extra data would be returned.
+    - Another 'cut and paste' bug in x509.c related to setting up the
+      STDout BIO.
+
+27-Jun-97
+    - apps/ciphers.c was not printing due to an editing error.
+    - Alex Kiernan <alex@hisoft.co.uk> send in a nice fix for
+      a library build error in util/mk1mf.pl
+
+26-Jun-97
+    - Still did not have the auto 'experimental' code removal
+      script correct.
+    - A few header tweaks for Watcom 11.0 under Win32 from
+      Rolf Lindemann <Lindemann@maz-hh.de>
+    - 0 length OCTET_STRING bug in asn1_parse
+    - A minor fix with an non-existent function in the MS .def files.
+    - A few changes to the PKCS7 stuff.
+
+25-Jun-97
+    SSLeay 0.8.0 finally it gets released.
+
+24-Jun-97
+    Added a SSL_OP_EPHEMERAL_RSA option which causes all SSLv3 RSA keys to
+    use a temporary RSA key.  This is experimental and needs some more work.
+    Fixed a few Win16 build problems.
+
+23-Jun-97
+    SSLv3 bug. I was not doing the 'lookup' of the CERT structure
+    correctly. I was taking the SSL->ctx->default_cert when I should
+    have been using SSL->cert. The bug was in ssl/s3_srvr.c
+
+20-Jun-97
+    X509_ATTRIBUTES were being encoded wrongly by apps/reg.c and the
+    rest of the library. Even though I had the code required to do
+    it correctly, apps/req.c was doing the wrong thing.  I have fixed
+    and tested everything.
+
+    Missing a few #ifdef FIONBIO sections in crypto/bio/bss_acpt.c.
+
+19-Jun-97
+    Fixed a bug in the SSLv2 server side first packet handling. When
+    using the non-blocking test BIO, the ssl->s2->first_packet flag
+    was being reset when a would-block failure occurred when reading
+    the first 5 bytes of the first packet. This caused the checking
+    logic to run at the wrong time and cause an error.
+
+    Fixed a problem with specifying cipher. If RC4-MD5 were used,
+    only the SSLv3 version would be picked up.  Now this will pick
+    up both SSLv2 and SSLv3 versions. This required changing the
+    SSL_CIPHER->mask values so that they only mask the ciphers,
+    digests, authentication, export type and key-exchange algorithms.
+
+    I found that when a SSLv23 session is established, a reused
+    session, of type SSLv3 was attempting to write the SSLv2 
+    ciphers, which were invalid. The SSL_METHOD->put_cipher_by_char 
+    method has been modified so it will only write out cipher which
+    that method knows about.  
+
+
+ Changes between 0.8.0 and 0.8.1
+
+  *) Mostly bug fixes. 
+     There is an Ephemeral DH cipher problem which is fixed.
+
+ SSLeay 0.8.0
+
+This version of SSLeay has quite a lot of things different from the
+previous version.
+
+Basically check all callback parameters, I will be producing documentation
+about how to use things in th future.  Currently I'm just getting 080 out
+the door.  Please not that there are several ways to do everything, and
+most of the applications in the apps directory are hybrids, some using old
+methods and some using new methods.
+
+Have a look in demos/bio for some very simple programs and
+apps/s_client.c and apps/s_server.c for some more advanced versions.
+Notes are definitly needed but they are a week or so away.
+
+Anyway, some quick nots from Tim Hudson (tjh@cryptsoft.com)
+---
+Quick porting notes for moving from SSLeay-0.6.x to SSLeay-0.8.x to
+get those people that want to move to using the new code base off to
+a quick start.
+
+Note that Eric has tidied up a lot of the areas of the API that were
+less than desirable and renamed quite a few things (as he had to break
+the API in lots of places anyrate). There are a whole pile of additional
+functions for making dealing with (and creating) certificates a lot
+cleaner.
+
+01-Jul-97
+Tim Hudson
+tjh@cryptsoft.com
+
+---8<---
+
+To maintain code that uses both SSLeay-0.6.x and SSLeay-0.8.x you could
+use something like the following (assuming you #include "crypto.h" which
+is something that you really should be doing).
+
+#if SSLEAY_VERSION_NUMBER >= 0x0800
+#define SSLEAY8
+#endif
+
+buffer.h -> splits into buffer.h and bio.h so you need to include bio.h
+            too if you are working with BIO internal stuff (as distinct
+        from simply using the interface in an opaque manner)
+
+#include "bio.h"    - required along with "buffer.h" if you write
+              your own BIO routines as the buffer and bio
+              stuff that was intermixed has been separated
+              out 
+            
+envelope.h -> evp.h  (which should have been done ages ago)
+
+Initialisation ... don't forget these or you end up with code that
+is missing the bits required to do useful things (like ciphers):
+
+SSLeay_add_ssl_algorithms()
+(probably also want SSL_load_error_strings() too but you should have
+ already had that call in place)
+
+SSL_CTX_new()   - requires an extra method parameter
+              SSL_CTX_new(SSLv23_method()) 
+              SSL_CTX_new(SSLv2_method()) 
+              SSL_CTX_new(SSLv3_method()) 
+
+          OR to only have the server or the client code
+              SSL_CTX_new(SSLv23_server_method()) 
+              SSL_CTX_new(SSLv2_server_method()) 
+              SSL_CTX_new(SSLv3_server_method()) 
+          or  
+              SSL_CTX_new(SSLv23_client_method()) 
+              SSL_CTX_new(SSLv2_client_method()) 
+              SSL_CTX_new(SSLv3_client_method()) 
+
+SSL_set_default_verify_paths() ... renamed to the more appropriate
+SSL_CTX_set_default_verify_paths()
+
+If you want to use client certificates then you have to add in a bit
+of extra stuff in that a SSLv3 server sends a list of those CAs that
+it will accept certificates from ... so you have to provide a list to
+SSLeay otherwise certain browsers will not send client certs.
+
+SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(s_cert_file));
+
+
+X509_NAME_oneline(X)    -> X509_NAME_oneline(X,NULL,0)  
+               or provide a buffer and size to copy the
+               result into
+
+X509_add_cert ->  X509_STORE_add_cert (and you might want to read the
+          notes on X509_NAME structure changes too)
+
+
+VERIFICATION CODE
+=================
+
+The codes have all be renamed from VERIFY_ERR_* to X509_V_ERR_* to
+more accurately reflect things.
+
+The verification callback args are now packaged differently so that
+extra fields for verification can be added easily in future without
+having to break things by adding extra parameters each release :-)
+
+X509_cert_verify_error_string -> X509_verify_cert_error_string
+
+
+BIO INTERNALS
+=============
+
+Eric has fixed things so that extra flags can be introduced in
+the BIO layer in future without having to play with all the BIO
+modules by adding in some macros.
+
+The ugly stuff using 
+    b->flags ~= (BIO_FLAGS_RW|BIO_FLAGS_SHOULD_RETRY)
+becomes
+    BIO_clear_retry_flags(b)
+
+    b->flags |= (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)
+becomes
+    BIO_set_retry_read(b)
+
+Also ... BIO_get_retry_flags(b), BIO_set_flags(b)
+
+
+
+OTHER THINGS
+============
+
+X509_NAME has been altered so that it isn't just a STACK ... the STACK
+is now in the "entries" field ... and there are a pile of nice functions
+for getting at the details in a much cleaner manner.
+
+SSL_CTX has been altered ... "cert" is no longer a direct member of this
+structure ... things are now down under "cert_store" (see x509_vfy.h) and
+things are no longer in a CERTIFICATE_CTX but instead in a X509_STORE.
+If your code "knows" about this level of detail then it will need some 
+surgery.
+
+If you depending on the incorrect spelling of a number of the error codes
+then you will have to change your code as these have been fixed.
+
+ENV_CIPHER "type" got renamed to "nid" and as that is what it actually
+has been all along so this makes things clearer.
+ify_cert_error_string(ctx->error));
+
+SSL_R_NO_CIPHER_WE_TRUST -> SSL_R_NO_CIPHER_LIST
+            and SSL_R_REUSE_CIPHER_LIST_NOT_ZERO
+
+
+
+ Changes between 0.7.x and 0.8.0
+  
+  *) There have been lots of changes, mostly the addition of SSLv3.
+     There have been many additions from people and amongst
+     others, C2Net has assisted greatly.
+ 
+ Changes between 0.7.x and 0.7.x
+
+  *) Internal development version only
+
+SSLeay 0.6.6 13-Jan-1997
+
+The main additions are
+
+- assember for x86 DES improvments.
+  From 191,000 per second on a pentium 100, I now get 281,000.  The inner
+  loop and the IP/FP modifications are from
+  Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>.  Many thanks for his
+  contribution.
+- The 'DES macros' introduced in 0.6.5 now have 3 types.
+  DES_PTR1, DES_PTR2 and 'normal'.  As per before, des_opts reports which
+  is best and there is a summery of mine in crypto/des/options.txt
+- A few bug fixes.
+- Added blowfish.  It is not used by SSL but all the other stuff that
+  deals with ciphers can use it in either ecb, cbc, cfb64 or ofb64 modes.
+  There are 3 options for optimising Blowfish.  BF_PTR, BF_PTR2 and 'normal'.
+  BF_PTR2 is pentium/x86 specific.  The correct option is setup in
+  the 'Configure' script.
+- There is now a 'get client certificate' callback which can be
+  'non-blocking'.  If more details are required, let me know.  It will
+  documented more in SSLv3 when I finish it.
+- Bug fixes from 0.6.5 including the infamous 'ca' bug.  The 'make test'
+  now tests the ca program.
+- Lots of little things modified and tweaked.
+
+ SSLeay 0.6.5
+
+After quite some time (3 months), the new release.  I have been very busy
+for the last few months and so this is mostly bug fixes and improvments.
+
+The main additions are
+
+- assember for x86 DES.  For all those gcc based systems, this is a big
+  improvement.  From 117,000 DES operation a second on a pentium 100,
+  I now get 191,000.  I have also reworked the C version so it
+  now gives 148,000 DESs per second.  
+- As mentioned above, the inner DES macros now have some more variant that
+  sometimes help, sometimes hinder performance.  There are now 3 options
+  DES_PTR (ptr vs array lookup), DES_UNROLL (full vs partial loop unrolling)
+  and DES_RISC (a more register intensive version of the inner macro).
+  The crypto/des/des_opts.c program, when compiled and run, will give
+  an indication of the correct options to use.
+- The BIO stuff has been improved.  Read doc/bio.doc.  There are now
+  modules for encryption and base64 encoding and a BIO_printf() function.
+- The CA program will accept simple one line X509v3 extensions in the
+  ssleay.cnf file.  Have a look at the example.  Currently this just
+  puts the text into the certificate as an OCTET_STRING so currently
+  the more advanced X509v3 data types are not handled but this is enough
+  for the netscape extensions.
+- There is the start of a nicer higher level interface to the X509
+  strucutre.
+- Quite a lot of bug fixes.
+- CRYPTO_malloc_init()  (or CRYPTO_set_mem_functions()) can be used
+  to define the malloc(), free() and realloc() routines to use
+  (look in crypto/crypto.h).  This is mostly needed for Windows NT/95 when
+  using DLLs and mixing CRT libraries.
+
+In general, read the 'VERSION' file for changes and be aware that some of
+the new stuff may not have been tested quite enough yet, so don't just plonk
+in SSLeay 0.6.5 when 0.6.4 used to work and expect nothing to break.
+
+SSLeay 0.6.4 30/08/96 eay
+
+I've just finished some test builds on Windows NT, Windows 3.1, Solaris 2.3,
+Solaris 2.5, Linux, IRIX, HPUX 10 and everthing seems to work :-).
+
+The main changes in this release
+
+- Thread safe.  have a read of doc/threads.doc and play in the mt directory.
+  For anyone using 0.6.3 with threads, I found 2 major errors so consider
+  moving to 0.6.4.  I have a test program that builds under NT and
+  solaris.
+- The get session-id callback has changed.  Have a read of doc/callback.doc.
+- The X509_cert_verify callback (the SSL_verify callback) now
+  has another argument.  Have a read of doc/callback.doc
+- 'ca -preserve', sign without re-ordering the DN.  Not tested much.
+- VMS support.
+- Compile time memory leak detection can now be built into SSLeay.
+  Read doc/memory.doc
+- CONF routines now understand '\', '\n', '\r' etc.  What this means is that
+  the  SPKAC object mentioned in doc/ns-ca.doc can be on multiple lines.
+- 'ssleay ciphers' added, lists the default cipher list for SSLeay.
+- RC2 key setup is now compatable with Netscape.
+- Modifed server side of SSL implementation, big performance difference when
+      using session-id reuse.
+
+0.6.3
+
+Bug fixes and the addition of some nice stuff to the 'ca' program.
+Have a read of doc/ns-ca.doc for how hit has been modified so
+it can be driven from a CGI script.  The CGI script is not provided,
+but that is just being left as an excersize for the reader :-).
+
+0.6.2
+
+This is most bug fixes and functionality improvements.
+
+Additions are
+- More thread debugging patches, the thread stuff is still being
+  tested, but for those keep to play with stuff, have a look in
+  crypto/cryptlib.c.  The application needs to define 1 (or optionaly
+  a second) callback that is used to implement locking.  Compiling
+  with LOCK_DEBUG spits out lots of locking crud :-).
+  This is what I'm currently working on.
+- SSL_CTX_set_default_passwd_cb() can be used to define the callback
+  function used in the SSL*_file() functions used to load keys.  I was
+  always of the opinion that people should call
+  PEM_read_RSAPrivateKey() and pass the callback they want to use, but
+  it appears they just want to use the SSL_*_file() function() :-(.
+- 'enc' now has a -kfile so a key can be read from a file.  This is
+  mostly used so that the passwd does not appear when using 'ps',
+  which appears imposible to stop under solaris.
+- X509v3 certificates now work correctly.  I even have more examples
+  in my tests :-).  There is now a X509_EXTENSION type that is used in
+  X509v3 certificates and CRLv2.
+- Fixed that signature type error :-(
+- Fixed quite a few potential memory leaks and problems when reusing
+  X509, CRL and REQ structures.
+- EVP_set_pw_prompt() now sets the library wide default password
+  prompt.
+- The 'pkcs7' command will now, given the -print_certs flag, output in
+  pem format, all certificates and CRL contained within.  This is more
+  of a pre-emtive thing for the new verisign distribution method.  I
+  should also note, that this also gives and example in code, of how
+  to do this :-), or for that matter, what is involved in going the
+  other way (list of certs and crl -> pkcs7).
+- Added RSA's DESX to the DES library.  It is also available via the
+  EVP_desx_cbc() method and via 'enc desx'. 
+
+SSLeay 0.6.1
+
+The main functional changes since 0.6.0 are as follows
+- Bad news, the Microsoft 060 DLL's are not compatable, but the good news is
+  that from now on, I'll keep the .def numbers the same so they will be.
+- RSA private key operations are about 2 times faster that 0.6.0
+- The SSL_CTX now has more fields so default values can be put against
+  it.  When an SSL structure is created, these default values are used
+  but can be overwritten.  There are defaults for cipher, certificate,
+  private key, verify mode and callback.  This means SSL session
+  creation can now be
+  ssl=SSL_new()
+  SSL_set_fd(ssl,sock);
+  SSL_accept(ssl)
+  ....
+  All the other uglyness with having to keep a global copy of the
+  private key and certificate/verify mode in the server is now gone.
+- ssl/ssltest.c - one process talking SSL to its self for testing.
+- Storage of Session-id's can be controled via a session_cache_mode
+  flag.  There is also now an automatic default flushing of 
+  old session-id's.
+- The X509_cert_verify() function now has another parameter, this
+  should not effect most people but it now means that the reason for
+  the failure to verify is now available via SSL_get_verify_result(ssl).
+  You don't have to use a global variable.
+- SSL_get_app_data() and SSL_set_app_data() can be used to keep some
+  application data against the SSL structure.  It is upto the application
+  to free the data.  I don't use it, but it is available.
+- SSL_CTX_set_cert_verify_callback() can be used to specify a
+  verify callback function that completly replaces my certificate
+  verification code.  Xcert should be able to use this :-).
+  The callback is of the form int app_verify_callback(arg,ssl,cert).
+  This needs to be documented more.
+- I have started playing with shared library builds, have a look in
+  the shlib directory.  It is very simple.  If you need a numbered
+  list of functions, have a look at misc/crypto.num and misc/ssl.num.
+- There is some stuff to do locking to make the library thread safe.
+  I have only started this stuff and have not finished.  If anyone is
+  keen to do so, please send me the patches when finished.
+
+So I have finally made most of the additions to the SSL interface that
+I thought were needed.
+
+There will probably be a pause before I make any non-bug/documentation
+related changes to SSLeay since I'm feeling like a bit of a break.
+
+eric - 12 Jul 1996
+I saw recently a comment by some-one that we now seem to be entering
+the age of perpetual Beta software.
+Pioneered by packages like linux but refined to an art form by
+netscape.
+
+I too wish to join this trend with the anouncement of SSLeay 0.6.0 :-).
+
+There are quite a large number of sections that are 'works in
+progress' in this package.  I will also list the major changes and
+what files you should read.
+
+BIO - this is the new IO structure being used everywhere in SSLeay.  I
+started out developing this because of microsoft, I wanted a mechanism
+to callback to the application for all IO, so Windows 3.1 DLL
+perversion could be hidden from me and the 15 different ways to write
+to a file under NT would also not be dictated by me at library build
+time.  What the 'package' is is an API for a data structure containing
+functions.  IO interfaces can be written to conform to the
+specification.  This in not intended to hide the underlying data type
+from the application, but to hide it from SSLeay :-).
+I have only really finished testing the FILE * and socket/fd modules.
+There are also 'filter' BIO's.  Currently I have only implemented
+message digests, and it is in use in the dgst application.  This
+functionality will allow base64/encrypto/buffering modules to be
+'push' into a BIO without it affecting the semantics.  I'm also
+working on an SSL BIO which will hide the SSL_accept()/SLL_connet()
+from an event loop which uses the interface.
+It is also possible to 'attach' callbacks to a BIO so they get called
+before and after each operation, alowing extensive debug output
+to be generated (try running dgst with -d).
+
+Unfortunaly in the conversion from 0.5.x to 0.6.0, quite a few
+functions that used to take FILE *, now take BIO *.
+The wrappers are easy to write
+
+function_fp(fp,x)
+FILE *fp;
+    {
+    BIO *b;
+    int ret;
+
+    if ((b=BIO_new(BIO_s_file())) == NULL) error.....
+    BIO_set_fp(b,fp,BIO_NOCLOSE);
+    ret=function_bio(b,x);
+    BIO_free(b);
+    return(ret);
+    }
+Remember, there are no functions that take FILE * in SSLeay when
+compiled for Windows 3.1 DLL's.
+
+--
+I have added a general EVP_PKEY type that can hold a public/private
+key.  This is now what is used by the EVP_ functions and is passed
+around internally.  I still have not done the PKCS#8 stuff, but
+X509_PKEY is defined and waiting :-)
+
+--
+For a full function name listings, have a look at ms/crypt32.def and
+ms/ssl32.def.  These are auto-generated but are complete.
+Things like ASN1_INTEGER_get() have been added and are in here if you
+look.  I have renamed a few things, again, have a look through the
+function list and you will probably find what you are after.  I intend
+to at least put a one line descrition for each one.....
+
+--
+Microsoft - thats what this release is about, read the MICROSOFT file.
+
+--
+Multi-threading support.  I have started hunting through the code and
+flaging where things need to be done.  In a state of work but high on
+the list.
+
+--
+For random numbers, edit e_os.h and set DEVRANDOM (it's near the top)
+be be you random data device, otherwise 'RFILE' in e_os.h
+will be used, in your home directory.  It will be updated
+periodically.  The environment variable RANDFILE will override this
+choice and read/write to that file instead.  DEVRANDOM is used in
+conjunction to the RFILE/RANDFILE.  If you wish to 'seed' the random
+number generator, pick on one of these files.
+
+--
+
+The list of things to read and do
+
+dgst -d
+s_client -state (this uses a callback placed in the SSL state loop and
+        will be used else-where to help debug/monitor what
+        is happening.)
+
+doc/why.doc
+doc/bio.doc <- hmmm, needs lots of work.
+doc/bss_file.doc <- one that is working :-)
+doc/session.doc <- it has changed
+doc/speed.doc
+ also play with ssleay version -a.  I have now added a SSLeay()
+ function that returns a version number, eg 0600 for this release
+ which is primarily to be used to check DLL version against the
+ application.
+util/*  Quite a few will not interest people, but some may, like
+ mk1mf.pl, mkdef.pl,
+util/do_ms.sh
+
+try
+cc -Iinclude -Icrypto -c crypto/crypto.c
+cc -Iinclude -Issl -c ssl/ssl.c
+You have just built the SSLeay libraries as 2 object files :-)
+
+Have a general rummage around in the bin stall directory and look at
+what is in there, like CA.sh and c_rehash
+
+There are lots more things but it is 12:30am on a Friday night and I'm
+heading home :-).
+
+eric 22-Jun-1996
+This version has quite a few major bug fixes and improvements.  It DOES NOT
+do SSLv3 yet.
+
+The main things changed
+- A Few days ago I added the s_mult application to ssleay which is
+  a demo of an SSL server running in an event loop type thing.
+  It supports non-blocking IO, I have finally gotten it right, SSL_accept()
+  can operate in non-blocking IO mode, look at the code to see how :-).
+  Have a read of doc/s_mult as well.  This program leaks memory and
+  file descriptors everywhere but I have not cleaned it up yet.
+  This is a demo of how to do non-blocking IO.
+- The SSL session management has been 'worked over' and there is now
+  quite an expansive set of functions to manipulate them.  Have a read of
+  doc/session.doc for some-things I quickly whipped up about how it now works.
+  This assume you know the SSLv2 protocol :-)
+- I can now read/write the netscape certificate format, use the
+  -inform/-outform  'net' options to the x509 command.  I have not put support
+  for this type in the other demo programs, but it would be easy to add.
+- asn1parse and 'enc' have been modified so that when reading base64
+  encoded files (pem format), they do not require '-----BEGIN' header lines.
+  The 'enc' program had a buffering bug fixed, it can be used as a general
+  base64 -> binary -> base64 filter by doing 'enc -a -e' and 'enc -a -d'
+  respecivly.  Leaving out the '-a' flag in this case makes the 'enc' command
+  into a form of 'cat'.
+- The 'x509' and 'req' programs have been fixed and modified a little so
+  that they generate self-signed certificates correctly.  The test
+  script actually generates a 'CA' certificate and then 'signs' a
+  'user' certificate.  Have a look at this shell script (test/sstest)
+  to see how things work, it tests most possible combinations of what can
+  be done.
+- The 'SSL_set_pref_cipher()' function has been 'fixed' and the prefered name
+  of SSL_set_cipher_list() is now the correct API (stops confusion :-).
+  If this function is used in the client, only the specified ciphers can
+  be used, with preference given to the order the ciphers were listed.
+  For the server, if this is used, only the specified ciphers will be used
+  to accept connections.  If this 'option' is not used, a default set of
+  ciphers will be used.  The SSL_CTX_set_cipher_list(SSL_CTX *ctx) sets this
+  list for all ciphers started against the SSL_CTX.  So the order is
+  SSL cipher_list, if not present, SSL_CTX cipher list, if not
+  present, then the library default.
+  What this means is that normally ciphers like
+  NULL-MD5 will never be used.  The only way this cipher can be used
+  for both ends to specify to use it.
+  To enable or disable ciphers in the library at build time, modify the
+  first field for the cipher in the ssl_ciphers array in ssl/ssl_lib.c.
+  This file also contains the 'pref_cipher' list which is the default
+  cipher preference order.
+- I'm not currently sure if the 'rsa -inform net' and the 'rsa -outform net'
+  options work.  They should, and they enable loading and writing the
+  netscape rsa private key format.  I will be re-working this section of
+  SSLeay for the next version.  What is currently in place is a quick and
+  dirty hack.
+- I've re-written parts of the bignum library.  This gives speedups
+  for all platforms.  I now provide assembler for use under Windows NT.
+  I have not tested the Windows 3.1 assembler but it is quite simple code.
+  This gives RSAprivate_key operation encryption times of 0.047s (512bit key)
+  and 0.230s (1024bit key) on a pentium 100 which I consider reasonable.
+  Basically the times available under linux/solaris x86 can be achieve under
+  Windows NT.  I still don't know how these times compare to RSA's BSAFE
+  library but I have been emailing with people and with their help, I should
+  be able to get my library's quite a bit faster still (more algorithm changes).
+  The object file crypto/bn/asm/x86-32.obj should be used when linking
+  under NT.
+- 'make makefile.one' in the top directory will generate a single makefile
+  called 'makefile.one'  This makefile contains no perl references and
+  will build the SSLeay library into the 'tmp' and 'out' directories.
+  util/mk1mf.pl >makefile.one is how this makefile is
+  generated.  The mk1mf.pl command take several option to generate the
+  makefile for use with cc, gcc, Visual C++ and Borland C++.  This is
+  still under development.  I have only build .lib's for NT and MSDOS
+  I will be working on this more.  I still need to play with the
+  correct compiler setups for these compilers and add some more stuff but
+  basically if you just want to compile the library
+  on a 'non-unix' platform, this is a very very good file to start with :-).
+  Have a look in the 'microsoft' directory for my current makefiles.
+  I have not yet modified things to link with sockets under Windows NT.
+  You guys should be able to do this since this is actually outside of the
+  SSLeay scope :-).  I will be doing it for myself soon.
+  util/mk1mf.pl takes quite a few options including no-rc, rsaref  and no-sock
+  to build without RC2/RC4, to require RSAref for linking, and to
+  build with no socket code.
+
+- Oh yes, the cipher that was reported to be compatible with RSA's RC2 cipher
+  that was posted to sci.crypt has been added to the library and SSL.
+  I take the view that if RC2 is going to be included in a standard,
+  I'll include the cipher to make my package complete.
+  There are NO_RC2, NO_RC4 and NO_IDEA macros to remove these ciphers
+  at compile time.  I have not tested this recently but it should all work
+  and if you are in the USA and don't want RSA threatening to sue you,
+  you could probably remove the RC4/RC2 code inside these sections.
+  I may in the future include a perl script that does this code
+  removal automatically for those in the USA :-).
+- I have removed all references to sed in the makefiles.  So basically,
+  the development environment requires perl and sh.  The build environment
+  does not (use the makefile.one makefile).
+  The Configure script still requires perl, this will probably stay that way
+  since I have perl for Windows NT :-).
+
+eric (03-May-1996)
+
+PS Have a look in the VERSION file for more details on the changes and
+   bug fixes.
+I have fixed a few bugs, added alpha and x86 assembler and generally cleaned
+things up.  This version will be quite stable, mostly because I'm on
+holidays until 10-March-1996.  For any problems in the interum, send email
+to Tim Hudson <tjh@mincom.oz.au>.
+
+SSLeay 0.5.0
+
+12-12-95
+This is going out before it should really be released.
+
+I leave for 11 weeks holidays on the 22-12-95 and so I either sit on
+this for 11 weeks or get things out.  It is still going to change a
+lot in the next week so if you do grab this version, please test and
+give me feed back ASAP, inculuding questions on how to do things with
+the library.  This will prompt me to write documentation so I don't
+have to answer the same question again :-).
+
+This 'pre' release version is for people who are interested in the
+library.  The applications will have to be changed to use
+the new version of the SSL interface.  I intend to finish more
+documentation before I leave but until then, look at the programs in
+the apps directory.  As far as code goes, it is much much nicer than
+the old version.
+
+The current library works, has no memory leaks (as far as I can tell)
+and is far more bug free that 0.4.5d.  There are no global variable of
+consequence (I believe) and I will produce some documentation that
+tell where to look for those people that do want to do multi-threaded
+stuff.
+
+There should be more documentation.  Have a look in the
+doc directory.  I'll be adding more before I leave, it is a start
+by mostly documents the crypto library.  Tim Hudson will update
+the web page ASAP.  The spelling and grammar are crap but
+it is better than nothing :-)
+
+Reasons to start playing with version 0.5.0
+- All the programs in the apps directory build into one ssleay binary.
+- There is a new version of the 'req' program that generates certificate
+  requests, there is even documentation for this one :-)
+- There is a demo certification authorithy program.  Currently it will
+  look at the simple database and update it.  It will generate CRL from
+  the data base.  You need to edit the database by hand to revoke a
+  certificate, it is my aim to use perl5/Tk but I don't have time to do
+  this right now.  It will generate the certificates but the management
+  scripts still need to be written.  This is not a hard task.
+- Things have been cleaned up alot.
+- Have a look at the enc and dgst programs in the apps directory.
+- It supports v3 of x509 certiticates.
+
+
+Major things missing.
+- I have been working on (and thinging about) the distributed x509
+  hierachy problem.  I have not had time to put my solution in place.
+  It will have to wait until I come back.
+- I have not put in CRL checking in the certificate verification but
+  it would not be hard to do.  I was waiting until I could generate my
+  own CRL (which has only been in the last week) and I don't have time
+  to put it in correctly.
+- Montgomery multiplication need to be implemented.  I know the
+  algorithm, just ran out of time.
+- PKCS#7.  I can load and write the DER version.  I need to re-work
+  things to support BER (if that means nothing, read the ASN1 spec :-).
+- Testing of the higher level digital envelope routines.  I have not
+  played with the *_seal() and *_open() type functions.  They are
+  written but need testing.  The *_sign() and *_verify() functions are
+  rock solid. 
+- PEM.  Doing this and PKCS#7 have been dependant on the distributed
+  x509 heirachy problem.  I started implementing my ideas, got
+  distracted writing a CA program and then ran out of time.  I provide
+  the functionality of RSAref at least.
+- Re work the asm. code for the x86.  I've changed by low level bignum
+  interface again, so I really need to tweak the x86 stuff.  gcc is
+  good enough for the other boxes.
+
diff --git a/openssl/Configure b/openssl/Configure
new file mode 100755
index 0000000..7941c93
--- /dev/null
+++ b/openssl/Configure
@@ -0,0 +1,2057 @@
+:
+eval 'exec perl -S $0 ${1+"$@"}'
+    if $running_under_some_shell;
+##
+##  Configure -- OpenSSL source tree configuration script
+##
+
+require 5.000;
+use strict;
+
+# see INSTALL for instructions.
+
+my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
+
+# Options:
+#
+# --openssldir  install OpenSSL in OPENSSLDIR (Default: DIR/ssl if the
+#               --prefix option is given; /usr/local/ssl otherwise)
+# --prefix      prefix for the OpenSSL include, lib and bin directories
+#               (Default: the OPENSSLDIR directory)
+#
+# --install_prefix  Additional prefix for package builders (empty by
+#               default).  This needn't be set in advance, you can
+#               just as well use "make INSTALL_PREFIX=/whatever install".
+#
+# --with-krb5-dir  Declare where Kerberos 5 lives.  The libraries are expected
+#		to live in the subdirectory lib/ and the header files in
+#		include/.  A value is required.
+# --with-krb5-lib  Declare where the Kerberos 5 libraries live.  A value is
+#		required.
+#		(Default: KRB5_DIR/lib)
+# --with-krb5-include  Declare where the Kerberos 5 header files live.  A
+#		value is required.
+#		(Default: KRB5_DIR/include)
+# --with-krb5-flavor  Declare what flavor of Kerberos 5 is used.  Currently
+#		supported values are "MIT" and "Heimdal".  A value is required.
+#
+# --test-sanity Make a number of sanity checks on the data in this file.
+#               This is a debugging tool for OpenSSL developers.
+#
+# --cross-compile-prefix Add specified prefix to binutils components.
+#
+# no-hw-xxx     do not compile support for specific crypto hardware.
+#               Generic OpenSSL-style methods relating to this support
+#               are always compiled but return NULL if the hardware
+#               support isn't compiled.
+# no-hw         do not compile support for any crypto hardware.
+# [no-]threads  [don't] try to create a library that is suitable for
+#               multithreaded applications (default is "threads" if we
+#               know how to do it)
+# [no-]shared	[don't] try to create shared libraries when supported.
+# no-asm        do not use assembler
+# no-dso        do not compile in any native shared-library methods. This
+#               will ensure that all methods just return NULL.
+# no-krb5       do not compile in any KRB5 library or code.
+# [no-]zlib     [don't] compile support for zlib compression.
+# zlib-dynamic	Like "zlib", but the zlib library is expected to be a shared
+#		library and will be loaded in run-time by the OpenSSL library.
+# 386           generate 80386 code
+# no-sse2	disables IA-32 SSE2 code, above option implies no-sse2
+# no-<cipher>   build without specified algorithm (rsa, idea, rc5, ...)
+# -<xxx> +<xxx> compiler options are passed through 
+#
+# DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
+#		provided to stack calls. Generates unique stack functions for
+#		each possible stack type.
+# DES_PTR	use pointer lookup vs arrays in the DES in crypto/des/des_locl.h
+# DES_RISC1	use different DES_ENCRYPT macro that helps reduce register
+#		dependancies but needs to more registers, good for RISC CPU's
+# DES_RISC2	A different RISC variant.
+# DES_UNROLL	unroll the inner DES loop, sometimes helps, somtimes hinders.
+# DES_INT	use 'int' instead of 'long' for DES_LONG in crypto/des/des.h
+#		This is used on the DEC Alpha where long is 8 bytes
+#		and int is 4
+# BN_LLONG	use the type 'long long' in crypto/bn/bn.h
+# MD2_CHAR	use 'char' instead of 'int' for MD2_INT in crypto/md2/md2.h
+# MD2_LONG	use 'long' instead of 'int' for MD2_INT in crypto/md2/md2.h
+# IDEA_SHORT	use 'short' instead of 'int' for IDEA_INT in crypto/idea/idea.h
+# IDEA_LONG	use 'long' instead of 'int' for IDEA_INT in crypto/idea/idea.h
+# RC2_SHORT	use 'short' instead of 'int' for RC2_INT in crypto/rc2/rc2.h
+# RC2_LONG	use 'long' instead of 'int' for RC2_INT in crypto/rc2/rc2.h
+# RC4_CHAR	use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
+# RC4_LONG	use 'long' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
+# RC4_INDEX	define RC4_INDEX in crypto/rc4/rc4_locl.h.  This turns on
+#		array lookups instead of pointer use.
+# RC4_CHUNK	enables code that handles data aligned at long (natural CPU
+#		word) boundary.
+# RC4_CHUNK_LL	enables code that handles data aligned at long long boundary
+#		(intended for 64-bit CPUs running 32-bit OS).
+# BF_PTR	use 'pointer arithmatic' for Blowfish (unsafe on Alpha).
+# BF_PTR2	intel specific version (generic version is more efficient).
+#
+# Following are set automatically by this script
+#
+# MD5_ASM	use some extra md5 assember,
+# SHA1_ASM	use some extra sha1 assember, must define L_ENDIAN for x86
+# RMD160_ASM	use some extra ripemd160 assember,
+# SHA256_ASM	sha256_block is implemented in assembler
+# SHA512_ASM	sha512_block is implemented in assembler
+# AES_ASM	ASE_[en|de]crypt is implemented in assembler
+
+# Minimum warning options... any contributions to OpenSSL should at least get
+# past these. 
+
+my $gcc_devteam_warn = "-Wall -pedantic -DPEDANTIC -Wno-long-long -Wsign-compare -Wmissing-prototypes -Wshadow -Wformat -Werror -DCRYPTO_MDEBUG_ALL -DCRYPTO_MDEBUG_ABORT -DREF_CHECK -DOPENSSL_NO_DEPRECATED";
+
+my $strict_warnings = 0;
+
+my $x86_gcc_des="DES_PTR DES_RISC1 DES_UNROLL";
+
+# MD2_CHAR slags pentium pros
+my $x86_gcc_opts="RC4_INDEX MD2_INT";
+
+# MODIFY THESE PARAMETERS IF YOU ARE GOING TO USE THE 'util/speed.sh SCRIPT
+# Don't worry about these normally
+
+my $tcc="cc";
+my $tflags="-fast -Xa";
+my $tbn_mul="";
+my $tlib="-lnsl -lsocket";
+#$bits1="SIXTEEN_BIT ";
+#$bits2="THIRTY_TWO_BIT ";
+my $bits1="THIRTY_TWO_BIT ";
+my $bits2="SIXTY_FOUR_BIT ";
+
+my $x86_asm="x86cpuid.o:bn-586.o co-586.o x86-mont.o:des-586.o crypt586.o:aes-586.o:bf-586.o:md5-586.o:sha1-586.o sha256-586.o sha512-586.o:cast-586.o:rc4-586.o:rmd-586.o:rc5-586.o:wp_block.o wp-mmx.o:cmll-x86.o";
+
+my $x86_elf_asm="$x86_asm:elf";
+
+my $x86_64_asm="x86_64cpuid.o:x86_64-gcc.o x86_64-mont.o::aes-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o::rc4-x86_64.o:::wp-x86_64.o:cmll-x86_64.o cmll_misc.o";
+my $ia64_asm="ia64cpuid.o:bn-ia64.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o::rc4-ia64.o rc4_skey.o:::::void";
+my $sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o sparcv9a-mont.o:des_enc-sparc.o fcrypt_b.o:aes_core.o aes_cbc.o aes-sparcv9.o:::sha1-sparcv9.o sha256-sparcv9.o sha512-sparcv9.o:::::::void";
+my $sparcv8_asm=":sparcv8.o:des_enc-sparc.o fcrypt_b.o:::::::::::void";
+my $alpha_asm="alphacpuid.o:bn_asm.o alpha-mont.o::::::::::::void";
+my $mips3_asm=":bn-mips3.o::::::::::::void";
+my $s390x_asm="s390xcap.o s390xcpuid.o:bn-s390x.o s390x-mont.o::aes-s390x.o:::sha1-s390x.o sha256-s390x.o sha512-s390x.o::rc4-s390x.o:::::void";
+my $armv4_asm=":bn_asm.o armv4-mont.o::aes_cbc.o aes-armv4.o:::sha1-armv4-large.o sha256-armv4.o sha512-armv4.o:::::::void";
+my $ppc32_asm="ppccpuid.o:bn-ppc.o::aes_core.o aes_cbc.o aes-ppc.o:::sha1-ppc.o sha256-ppc.o::::::";
+my $ppc64_asm="ppccpuid.o:bn-ppc.o ppc-mont.o::aes_core.o aes_cbc.o aes-ppc.o:::sha1-ppc.o sha256-ppc.o sha512-ppc.o::::::";
+my $no_asm=":::::::::::::void";
+
+# As for $BSDthreads. Idea is to maintain "collective" set of flags,
+# which would cover all BSD flavors. -pthread applies to them all, 
+# but is treated differently. OpenBSD expands is as -D_POSIX_THREAD
+# -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r,
+# which has to be accompanied by explicit -D_THREAD_SAFE and
+# sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which
+# seems to be sufficient?
+my $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
+
+#config-string	$cc : $cflags : $unistd : $thread_cflag : $sys_id : $lflags : $bn_ops : $cpuid_obj : $bn_obj : $des_obj : $aes_obj : $bf_obj : $md5_obj : $sha1_obj : $cast_obj : $rc4_obj : $rmd160_obj : $rc5_obj : $wp_obj : $cmll_obj : $dso_scheme : $shared_target : $shared_cflag : $shared_ldflag : $shared_extension : $ranlib : $arflags : $multilib
+
+my %table=(
+# File 'TABLE' (created by 'make TABLE') contains the data from this list,
+# formatted for better readability.
+
+
+#"b",		"${tcc}:${tflags}::${tlib}:${bits1}:${tbn_mul}::",
+#"bl-4c-2c",	"${tcc}:${tflags}::${tlib}:${bits1}BN_LLONG RC4_CHAR MD2_CHAR:${tbn_mul}::",
+#"bl-4c-ri",	"${tcc}:${tflags}::${tlib}:${bits1}BN_LLONG RC4_CHAR RC4_INDEX:${tbn_mul}::",
+#"b2-is-ri-dp",	"${tcc}:${tflags}::${tlib}:${bits2}IDEA_SHORT RC4_INDEX DES_PTR:${tbn_mul}::",
+
+# Our development configs
+"purify",	"purify gcc:-g -DPURIFY -Wall::(unknown)::-lsocket -lnsl::::",
+"debug",	"gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -ggdb -g2 -Wformat -Wshadow -Wmissing-prototypes -Wmissing-declarations -Werror::(unknown)::-lefence::::",
+"debug-ben",	"gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DDEBUG_UNUSED -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown):::::bn86-elf.o co86-elf.o",
+"debug-ben-openbsd","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DOPENSSL_OPENBSD_DEV_CRYPTO -DOPENSSL_NO_ASM -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown)::::",
+"debug-ben-openbsd-debug","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DOPENSSL_OPENBSD_DEV_CRYPTO -DOPENSSL_NO_ASM -g3 -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown)::::",
+"debug-ben-debug",	"gcc44:$gcc_devteam_warn -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O2 -pipe::(unknown)::::::",
+"debug-ben-no-opt",	"gcc: -Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -DDEBUG_SAFESTACK -DCRYPTO_MDEBUG -Werror -DL_ENDIAN -DTERMIOS -Wall -g3::(unknown)::::::",
+"debug-ben-strict",	"gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DCONST_STRICT -O2 -Wall -Wshadow -Werror -Wpointer-arith -Wcast-qual -Wwrite-strings -pipe::(unknown)::::::",
+"debug-rse","cc:-DTERMIOS -DL_ENDIAN -pipe -O -g -ggdb3 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}",
+"debug-bodo",	"gcc:-DL_ENDIAN -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBIO_PAIR_DEBUG -DPEDANTIC -g -march=i486 -pedantic -Wshadow -Wall -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion::-D_REENTRANT:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}",
+"debug-ulf", "gcc:-DTERMIOS -DL_ENDIAN -march=i486 -Wall -DBN_DEBUG -DBN_DEBUG_RAND -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -g -Wformat -Wshadow -Wmissing-prototypes -Wmissing-declarations:::CYGWIN32:::${no_asm}:win32:cygwin-shared:::.dll",
+"debug-steve64", "gcc:$gcc_devteam_warn -m64 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -DDEBUG_SAFESTACK -g -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-steve32", "gcc:$gcc_devteam_warn -m32 -DL_ENDIAN -DCONF_DEBUG -DDEBUG_SAFESTACK -g -pipe::-D_REENTRANT::-rdynamic -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC:-m32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-steve-opt", "gcc:$gcc_devteam_warn -m64 -O3 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -DDEBUG_SAFESTACK -g -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-levitte-linux-elf","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DL_ENDIAN -DTERMIO -D_POSIX_SOURCE -DPEDANTIC -ggdb -g3 -mcpu=i486 -pedantic -ansi -Wall -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-levitte-linux-noasm","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DOPENSSL_NO_ASM -DL_ENDIAN -DTERMIO -D_POSIX_SOURCE -DPEDANTIC -ggdb -g3 -mcpu=i486 -pedantic -ansi -Wall -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-levitte-linux-elf-extreme","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DL_ENDIAN -DTERMIO -D_POSIX_SOURCE -DPEDANTIC -ggdb -g3 -mcpu=i486 -pedantic -ansi -Wall -W -Wundef -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-levitte-linux-noasm-extreme","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DOPENSSL_NO_ASM -DL_ENDIAN -DTERMIO -D_POSIX_SOURCE -DPEDANTIC -ggdb -g3 -mcpu=i486 -pedantic -ansi -Wall -W -Wundef -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-geoff32","gcc:-DBN_DEBUG -DBN_DEBUG_RAND -DBN_STRICT -DPURIFY -DOPENSSL_NO_DEPRECATED -DOPENSSL_NO_ASM -DOPENSSL_NO_INLINE_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -DMD32_REG_T=int -O1 -ggdb2 -Wall -Werror -Wundef -pedantic -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare -Wmissing-prototypes -Wmissing-declarations -Wno-long-long::-D_REENTRANT::-ldl:BN_LLONG:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-geoff64","gcc:-DBN_DEBUG -DBN_DEBUG_RAND -DBN_STRICT -DPURIFY -DOPENSSL_NO_DEPRECATED -DOPENSSL_NO_ASM -DOPENSSL_NO_INLINE_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -DMD32_REG_T=int -O1 -ggdb2 -Wall -Werror -Wundef -pedantic -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare -Wmissing-prototypes -Wmissing-declarations -Wno-long-long::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-linux-pentium","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -mcpu=pentium -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn",
+"debug-linux-ppro","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -mcpu=pentiumpro -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn",
+"debug-linux-elf","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -march=i486 -Wall::-D_REENTRANT::-lefence -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-linux-elf-noefence","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -march=i486 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-linux-ia32-aes", "gcc:-DAES_EXPERIMENTAL -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:x86cpuid.o:bn-586.o co-586.o x86-mont.o:des-586.o crypt586.o:aes_x86core.o aes_cbc.o:bf-586.o:md5-586.o:sha1-586.o sha256-586.o sha512-586.o:cast-586.o:rc4-586.o:rmd-586.o:rc5-586.o:wp_block.o wp-mmx.o::elf:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-linux-generic32","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DTERMIO -g -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-linux-generic64","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DTERMIO -g -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-linux-x86_64",	"gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -m64 -DL_ENDIAN -DTERMIO -g -Wall -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
+"dist",		"cc:-O::(unknown)::::::",
+
+# Basic configs that should work on any (32 and less bit) box
+"gcc",		"gcc:-O3::(unknown):::BN_LLONG:::",
+"cc",		"cc:-O::(unknown)::::::",
+
+####VOS Configurations
+"vos-gcc","gcc:-O3 -Wall -DOPENSSL_SYSNAME_VOS -D_POSIX_C_SOURCE=200112L -D_BSD -D_VOS_EXTENDED_NAMES -DB_ENDIAN::(unknown):VOS:-Wl,-map:BN_LLONG:${no_asm}:::::.so:",
+"debug-vos-gcc","gcc:-O0 -g -Wall -DOPENSSL_SYSNAME_VOS -D_POSIX_C_SOURCE=200112L -D_BSD -D_VOS_EXTENDED_NAMES -DB_ENDIAN -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG::(unknown):VOS:-Wl,-map:BN_LLONG:${no_asm}:::::.so:",
+
+#### Solaris x86 with GNU C setups
+# -DOPENSSL_NO_INLINE_ASM switches off inline assembler. We have to do it
+# here because whenever GNU C instantiates an assembler template it
+# surrounds it with #APP #NO_APP comment pair which (at least Solaris
+# 7_x86) /usr/ccs/bin/as fails to assemble with "Illegal mnemonic"
+# error message.
+"solaris-x86-gcc","gcc:-O3 -fomit-frame-pointer -march=pentium -Wall -DL_ENDIAN -DOPENSSL_NO_INLINE_ASM::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+# -shared -static-libgcc might appear controversial, but modules taken
+# from static libgcc do not have relocations and linking them into our
+# shared objects doesn't have any negative side-effects. On the contrary,
+# doing so makes it possible to use gcc shared build with Sun C. Given
+# that gcc generates faster code [thanks to inline assembler], I would
+# actually recommend to consider using gcc shared build even with vendor
+# compiler:-)
+#						<appro@fy.chalmers.se>
+"solaris64-x86_64-gcc","gcc:-m64 -O3 -Wall -DL_ENDIAN -DMD32_REG_T=int::-D_REENTRANT::-lsocket -lnsl -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:solaris-shared:-fPIC:-m64 -shared -static-libgcc:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/64",
+ 
+#### Solaris x86 with Sun C setups
+"solaris-x86-cc","cc:-fast -O -Xa::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_UNROLL BF_PTR:${no_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"solaris64-x86_64-cc","cc:-fast -xarch=amd64 -xstrconst -Xa -DL_ENDIAN::-D_REENTRANT::-lsocket -lnsl -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:solaris-shared:-KPIC:-xarch=amd64 -G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/64",
+
+#### SPARC Solaris with GNU C setups
+"solaris-sparcv7-gcc","gcc:-O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"solaris-sparcv8-gcc","gcc:-mv8 -O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+# -m32 should be safe to add as long as driver recognizes -mcpu=ultrasparc
+"solaris-sparcv9-gcc","gcc:-m32 -mcpu=ultrasparc -O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"solaris64-sparcv9-gcc","gcc:-m64 -mcpu=ultrasparc -O3 -Wall -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-fPIC:-m64 -shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/64",
+####
+"debug-solaris-sparcv8-gcc","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -O -g -mv8 -Wall -DB_ENDIAN::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-solaris-sparcv9-gcc","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -DPEDANTIC -O -g -mcpu=ultrasparc -pedantic -ansi -Wall -Wshadow -Wno-long-long -D__EXTENSIONS__ -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+
+#### SPARC Solaris with Sun C setups
+# SC4.0 doesn't pass 'make test', upgrade to SC5.0 or SC4.2.
+# SC4.2 is ok, better than gcc even on bn as long as you tell it -xarch=v8
+# SC5.0 note: Compiler common patch 107357-01 or later is required!
+"solaris-sparcv7-cc","cc:-xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${no_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"solaris-sparcv8-cc","cc:-xarch=v8 -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"solaris-sparcv9-cc","cc:-xtarget=ultra -xarch=v8plus -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK_LL DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"solaris64-sparcv9-cc","cc:-xtarget=ultra -xarch=v9 -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-xarch=v9 -G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):/usr/ccs/bin/ar rs::/64",
+####
+"debug-solaris-sparcv8-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -xarch=v8 -g -O -xstrconst -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-solaris-sparcv9-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -xtarget=ultra -xarch=v8plus -g -O -xstrconst -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK_LL DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", 
+
+#### SunOS configs, assuming sparc for the gcc one.
+#"sunos-cc", "cc:-O4 -DNOPROTO -DNOCONST::(unknown):SUNOS::DES_UNROLL:${no_asm}::",
+"sunos-gcc","gcc:-O3 -mv8 -Dssize_t=int::(unknown):SUNOS::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL DES_PTR DES_RISC1:${no_asm}::",
+
+#### IRIX 5.x configs
+# -mips2 flag is added by ./config when appropriate.
+"irix-gcc","gcc:-O3 -DTERMIOS -DB_ENDIAN::(unknown):::BN_LLONG MD2_CHAR RC4_INDEX RC4_CHAR RC4_CHUNK DES_UNROLL DES_RISC2 DES_PTR BF_PTR:${no_asm}:dlfcn:irix-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"irix-cc", "cc:-O2 -use_readonly_const -DTERMIOS -DB_ENDIAN::(unknown):::BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC2 DES_UNROLL BF_PTR:${no_asm}:dlfcn:irix-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+#### IRIX 6.x configs
+# Only N32 and N64 ABIs are supported. If you need O32 ABI build, invoke
+# './Configure irix-cc -o32' manually.
+"irix-mips3-gcc","gcc:-mabi=n32 -O3 -DTERMIOS -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::MD2_CHAR RC4_INDEX RC4_CHAR RC4_CHUNK_LL DES_UNROLL DES_RISC2 DES_PTR BF_PTR SIXTY_FOUR_BIT:${mips3_asm}:dlfcn:irix-shared::-mabi=n32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::32",
+"irix-mips3-cc", "cc:-n32 -mips3 -O2 -use_readonly_const -G0 -rdata_shared -DTERMIOS -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::DES_PTR RC4_CHAR RC4_CHUNK_LL DES_RISC2 DES_UNROLL BF_PTR SIXTY_FOUR_BIT:${mips3_asm}:dlfcn:irix-shared::-n32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::32",
+# N64 ABI builds.
+"irix64-mips4-gcc","gcc:-mabi=64 -mips4 -O3 -DTERMIOS -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::RC4_CHAR RC4_CHUNK DES_RISC2 DES_UNROLL SIXTY_FOUR_BIT_LONG:${mips3_asm}:dlfcn:irix-shared::-mabi=64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
+"irix64-mips4-cc", "cc:-64 -mips4 -O2 -use_readonly_const -G0 -rdata_shared -DTERMIOS -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::RC4_CHAR RC4_CHUNK DES_RISC2 DES_UNROLL SIXTY_FOUR_BIT_LONG:${mips3_asm}:dlfcn:irix-shared::-64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
+
+#### Unified HP-UX ANSI C configs.
+# Special notes:
+# - Originally we were optimizing at +O4 level. It should be noted
+#   that the only difference between +O3 and +O4 is global inter-
+#   procedural analysis. As it has to be performed during the link
+#   stage the compiler leaves behind certain pseudo-code in lib*.a
+#   which might be release or even patch level specific. Generating
+#   the machine code for and analyzing the *whole* program appears
+#   to be *extremely* memory demanding while the performance gain is
+#   actually questionable. The situation is intensified by the default
+#   HP-UX data set size limit (infamous 'maxdsiz' tunable) of 64MB
+#   which is way too low for +O4. In other words, doesn't +O3 make
+#   more sense?
+# - Keep in mind that the HP compiler by default generates code
+#   suitable for execution on the host you're currently compiling at.
+#   If the toolkit is ment to be used on various PA-RISC processors
+#   consider './config +DAportable'.
+# - +DD64 is chosen in favour of +DA2.0W because it's meant to be
+#   compatible with *future* releases.
+# - If you run ./Configure hpux-parisc-[g]cc manually don't forget to
+#   pass -D_REENTRANT on HP-UX 10 and later.
+# - -DMD32_XARRAY triggers workaround for compiler bug we ran into in
+#   32-bit message digests. (For the moment of this writing) HP C
+#   doesn't seem to "digest" too many local variables (they make "him"
+#   chew forever:-). For more details look-up MD32_XARRAY comment in
+#   crypto/sha/sha_lcl.h.
+#					<appro@fy.chalmers.se>
+#
+# Since there is mention of this in shlib/hpux10-cc.sh
+"hpux-parisc-cc-o4","cc:-Ae +O4 +ESlit -z -DB_ENDIAN -DBN_DIV2W -DMD32_XARRAY::-D_REENTRANT::-ldld:BN_LLONG DES_PTR DES_UNROLL DES_RISC1:${no_asm}:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"hpux-parisc-gcc","gcc:-O3 -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-Wl,+s -ldld:BN_LLONG DES_PTR DES_UNROLL DES_RISC1:${no_asm}:dl:hpux-shared:-fPIC:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"hpux-parisc2-gcc","gcc:-march=2.0 -O3 -DB_ENDIAN -D_REENTRANT::::-Wl,+s -ldld:SIXTY_FOUR_BIT RC4_CHAR RC4_CHUNK DES_PTR DES_UNROLL DES_RISC1::pa-risc2.o::::::::::::void:dl:hpux-shared:-fPIC:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"hpux64-parisc2-gcc","gcc:-O3 -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT_LONG MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT::pa-risc2W.o::::::::::::void:dlfcn:hpux-shared:-fpic:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa20_64",
+
+# More attempts at unified 10.X and 11.X targets for HP C compiler.
+#
+# Chris Ruemmler <ruemmler@cup.hp.com>
+# Kevin Steves <ks@hp.se>
+"hpux-parisc-cc","cc:+O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DBN_DIV2W -DMD32_XARRAY::-D_REENTRANT::-Wl,+s -ldld:MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT:${no_asm}:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"hpux-parisc1_0-cc","cc:+DAportable +O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY::-D_REENTRANT::-Wl,+s -ldld:MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT:${no_asm}:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"hpux-parisc2-cc","cc:+DA2.0 +DS2.0 +O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY -D_REENTRANT::::-Wl,+s -ldld:SIXTY_FOUR_BIT MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT::pa-risc2.o::::::::::::void:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"hpux64-parisc2-cc","cc:+DD64 +O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT_LONG MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT::pa-risc2W.o::::::::::::void:dlfcn:hpux-shared:+Z:+DD64 -b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa20_64",
+
+# HP/UX IA-64 targets
+"hpux-ia64-cc","cc:-Ae +DD32 +O2 +Olit=all -z -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT MD2_CHAR RC4_INDEX DES_UNROLL DES_RISC1 DES_INT:${ia64_asm}:dlfcn:hpux-shared:+Z:+DD32 -b:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/hpux32",
+# Frank Geurts <frank.geurts@nl.abnamro.com> has patiently assisted with
+# with debugging of the following config.
+"hpux64-ia64-cc","cc:-Ae +DD64 +O3 +Olit=all -z -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT_LONG MD2_CHAR RC4_INDEX DES_UNROLL DES_RISC1 DES_INT:${ia64_asm}:dlfcn:hpux-shared:+Z:+DD64 -b:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/hpux64",
+# GCC builds...
+"hpux-ia64-gcc","gcc:-O3 -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT MD2_CHAR RC4_INDEX DES_UNROLL DES_RISC1 DES_INT:${ia64_asm}:dlfcn:hpux-shared:-fpic:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/hpux32",
+"hpux64-ia64-gcc","gcc:-mlp64 -O3 -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT_LONG MD2_CHAR RC4_INDEX DES_UNROLL DES_RISC1 DES_INT:${ia64_asm}:dlfcn:hpux-shared:-fpic:-mlp64 -shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/hpux64", 
+
+# Legacy HPUX 9.X configs...
+"hpux-cc",	"cc:-DB_ENDIAN -DBN_DIV2W -DMD32_XARRAY -Ae +ESlit +O2 -z::(unknown)::-Wl,+s -ldld:DES_PTR DES_UNROLL DES_RISC1:${no_asm}:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"hpux-gcc",	"gcc:-DB_ENDIAN -DBN_DIV2W -O3::(unknown)::-Wl,+s -ldld:DES_PTR DES_UNROLL DES_RISC1:${no_asm}:dl:hpux-shared:-fPIC:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+
+#### HP MPE/iX http://jazz.external.hp.com/src/openssl/
+"MPE/iX-gcc",	"gcc:-D_ENDIAN -DBN_DIV2W -O3 -D_POSIX_SOURCE -D_SOCKET_SOURCE -I/SYSLOG/PUB::(unknown):MPE:-L/SYSLOG/PUB -lsyslog -lsocket -lcurses:BN_LLONG DES_PTR DES_UNROLL DES_RISC1:::",
+
+# DEC Alpha OSF/1/Tru64 targets.
+#
+#	"What's in a name? That which we call a rose
+#	 By any other word would smell as sweet."
+#
+# - William Shakespeare, "Romeo & Juliet", Act II, scene II.
+#
+# For gcc, the following gave a %50 speedup on a 164 over the 'DES_INT' version
+#
+"osf1-alpha-gcc", "gcc:-O3::(unknown):::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_UNROLL DES_RISC1:${alpha_asm}:dlfcn:alpha-osf1-shared:::.so",
+"osf1-alpha-cc",  "cc:-std1 -tune host -O4 -readonly_strings::(unknown):::SIXTY_FOUR_BIT_LONG RC4_CHUNK:${alpha_asm}:dlfcn:alpha-osf1-shared:::.so",
+"tru64-alpha-cc", "cc:-std1 -tune host -fast -readonly_strings::-pthread:::SIXTY_FOUR_BIT_LONG RC4_CHUNK:${alpha_asm}:dlfcn:alpha-osf1-shared::-msym:.so",
+
+####
+#### Variety of LINUX:-)
+####
+# *-generic* is endian-neutral target, but ./config is free to
+# throw in -D[BL]_ENDIAN, whichever appropriate...
+"linux-generic32","gcc:-DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"linux-ppc",	"gcc:-DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${ppc32_asm}:linux32:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+# It's believed that majority of ARM toolchains predefine appropriate -march.
+# If you compiler does not, do complement config command line with one!
+"linux-armv4",	"gcc:-DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+#### IA-32 targets...
+"linux-ia32-icc",	"icc:-DL_ENDIAN -DTERMIO -O2 -no_cpprt::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-KPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"linux-elf",	"gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"linux-aout",	"gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -march=i486 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_asm}:a.out",
+####
+"linux-generic64","gcc:-DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"linux-ppc64",	"gcc:-m64 -DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${ppc64_asm}:linux64:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
+"linux-ia64",	"gcc:-DL_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_UNROLL DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"linux-ia64-ecc","ecc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"linux-ia64-icc","icc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"linux-x86_64",	"gcc:-m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
+"linux-s390x",	"gcc:-m64 -DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:${s390x_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
+#### SPARC Linux setups
+# Ray Miller <ray.miller@computing-services.oxford.ac.uk> has patiently
+# assisted with debugging of following two configs.
+"linux-sparcv8","gcc:-mv8 -DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall -DBN_DIV2W::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+# it's a real mess with -mcpu=ultrasparc option under Linux, but
+# -Wa,-Av8plus should do the trick no matter what.
+"linux-sparcv9","gcc:-m32 -mcpu=ultrasparc -DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall -Wa,-Av8plus -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:linux-shared:-fPIC:-m32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+# GCC 3.1 is a requirement
+"linux64-sparcv9","gcc:-m64 -mcpu=ultrasparc -DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT:ULTRASPARC:-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
+#### Alpha Linux with GNU C and Compaq C setups
+# Special notes:
+# - linux-alpha+bwx-gcc is ment to be used from ./config only. If you
+#   ought to run './Configure linux-alpha+bwx-gcc' manually, do
+#   complement the command line with -mcpu=ev56, -mcpu=ev6 or whatever
+#   which is appropriate.
+# - If you use ccc keep in mind that -fast implies -arch host and the
+#   compiler is free to issue instructions which gonna make elder CPU
+#   choke. If you wish to build "blended" toolkit, add -arch generic
+#   *after* -fast and invoke './Configure linux-alpha-ccc' manually.
+#
+#					<appro@fy.chalmers.se>
+#
+"linux-alpha-gcc","gcc:-O3 -DL_ENDIAN -DTERMIO::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_UNROLL:${alpha_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"linux-alpha+bwx-gcc","gcc:-O3 -DL_ENDIAN -DTERMIO::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${alpha_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"linux-alpha-ccc","ccc:-fast -readonly_strings -DL_ENDIAN -DTERMIO::-D_REENTRANT:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL:${alpha_asm}",
+"linux-alpha+bwx-ccc","ccc:-fast -readonly_strings -DL_ENDIAN -DTERMIO::-D_REENTRANT:::SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL:${alpha_asm}",
+
+#### *BSD [do see comment about ${BSDthreads} above!]
+"BSD-generic32","gcc:-DTERMIOS -O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_INDEX DES_INT DES_UNROLL:${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"BSD-x86",	"gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_asm}:a.out:dlfcn:bsd-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"BSD-x86-elf",	"gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"debug-BSD-x86-elf",	"gcc:-DL_ENDIAN -DTERMIOS -O3 -Wall -g::${BSDthreads}:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"BSD-sparcv8",	"gcc:-DB_ENDIAN -DTERMIOS -O3 -mv8 -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_INDEX DES_INT DES_UNROLL:${sparcv8_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+
+"BSD-generic64","gcc:-DTERMIOS -O3 -Wall::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+# -DMD32_REG_T=int doesn't actually belong in sparc64 target, it
+# simply *happens* to work around a compiler bug in gcc 3.3.3,
+# triggered by RIPEMD160 code.
+"BSD-sparc64",	"gcc:-DB_ENDIAN -DTERMIOS -O3 -DMD32_REG_T=int -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC2 BF_PTR:${sparcv9_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"BSD-ia64",	"gcc:-DL_ENDIAN -DTERMIOS -O3 -Wall::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_UNROLL DES_INT:${ia64_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"BSD-x86_64",	"gcc:-DL_ENDIAN -DTERMIOS -O3 -DMD32_REG_T=int -Wall::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+
+"bsdi-elf-gcc",     "gcc:-DPERL5 -DL_ENDIAN -fomit-frame-pointer -O3 -march=i486 -Wall::(unknown)::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+
+"nextstep",	"cc:-O -Wall:<libc.h>:(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:::",
+"nextstep3.3",	"cc:-O3 -Wall:<libc.h>:(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:::",
+
+# NCR MP-RAS UNIX ver 02.03.01
+"ncr-scde","cc:-O6 -Xa -Hoff=BEHAVED -686 -Hwide -Hiw::(unknown)::-lsocket -lnsl -lc89:${x86_gcc_des} ${x86_gcc_opts}:::",
+
+# QNX
+"qnx4",	"cc:-DL_ENDIAN -DTERMIO::(unknown):::${x86_gcc_des} ${x86_gcc_opts}:",
+"QNX6",       "gcc:-DTERMIOS::::-lsocket::${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"QNX6-i386",  "gcc:-DL_ENDIAN -DTERMIOS -O2 -Wall::::-lsocket:${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+
+# BeOS
+"beos-x86-r5",   "gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -mcpu=pentium -Wall::-D_REENTRANT:BEOS:-lbe -lnet:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:beos:beos-shared:-fPIC -DPIC:-shared:.so",
+"beos-x86-bone", "gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -mcpu=pentium -Wall::-D_REENTRANT:BEOS:-lbe -lbind -lsocket:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:beos:beos-shared:-fPIC:-shared:.so",
+
+#### SCO/Caldera targets.
+#
+# Originally we had like unixware-*, unixware-*-pentium, unixware-*-p6, etc.
+# Now we only have blended unixware-* as it's the only one used by ./config.
+# If you want to optimize for particular microarchitecture, bypass ./config
+# and './Configure unixware-7 -Kpentium_pro' or whatever appropriate.
+# Note that not all targets include assembler support. Mostly because of
+# lack of motivation to support out-of-date platforms with out-of-date
+# compiler drivers and assemblers. Tim Rice <tim@multitalents.net> has
+# patiently assisted to debug most of it.
+#
+# UnixWare 2.0x fails destest with -O.
+"unixware-2.0","cc:-DFILIO_H -DNO_STRINGS_H::-Kthread::-lsocket -lnsl -lresolv -lx:${x86_gcc_des} ${x86_gcc_opts}:::",
+"unixware-2.1","cc:-O -DFILIO_H::-Kthread::-lsocket -lnsl -lresolv -lx:${x86_gcc_des} ${x86_gcc_opts}:::",
+"unixware-7","cc:-O -DFILIO_H -Kalloca::-Kthread::-lsocket -lnsl:BN_LLONG MD2_CHAR RC4_INDEX ${x86_gcc_des}:${x86_elf_asm}:dlfcn:svr5-shared:-Kpic::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"unixware-7-gcc","gcc:-DL_ENDIAN -DFILIO_H -O3 -fomit-frame-pointer -march=pentium -Wall::-D_REENTRANT::-lsocket -lnsl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:gnu-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+# SCO 5 - Ben Laurie <ben@algroup.co.uk> says the -O breaks the SCO cc.
+"sco5-cc",  "cc:-belf::(unknown)::-lsocket -lnsl:${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:svr3-shared:-Kpic::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"sco5-gcc",  "gcc:-O3 -fomit-frame-pointer::(unknown)::-lsocket -lnsl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:svr3-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+
+#### IBM's AIX.
+"aix3-cc",  "cc:-O -DB_ENDIAN -qmaxmem=16384::(unknown):AIX::BN_LLONG RC4_CHAR:::",
+"aix-gcc",  "gcc:-O -DB_ENDIAN::-pthread:AIX::BN_LLONG RC4_CHAR:${ppc32_asm}:aix32:dlfcn:aix-shared::-shared -Wl,-G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X32",
+"aix64-gcc","gcc:-maix64 -O -DB_ENDIAN::-pthread:AIX::SIXTY_FOUR_BIT_LONG RC4_CHAR:${ppc64_asm}:aix64:dlfcn:aix-shared::-maix64 -shared -Wl,-G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X64",
+# Below targets assume AIX 5. Idea is to effectively disregard $OBJECT_MODE
+# at build time. $OBJECT_MODE is respected at ./config stage!
+"aix-cc",   "cc:-q32 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded:AIX::BN_LLONG RC4_CHAR:${ppc32_asm}:aix32:dlfcn:aix-shared::-q32 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 32",
+"aix64-cc", "cc:-q64 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded:AIX::SIXTY_FOUR_BIT_LONG RC4_CHAR:${ppc64_asm}:aix64:dlfcn:aix-shared::-q64 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 64",
+
+#
+# Cray T90 and similar (SDSC)
+# It's Big-endian, but the algorithms work properly when B_ENDIAN is NOT
+# defined.  The T90 ints and longs are 8 bytes long, and apparently the
+# B_ENDIAN code assumes 4 byte ints.  Fortunately, the non-B_ENDIAN and
+# non L_ENDIAN code aligns the bytes in each word correctly.
+#
+# The BIT_FIELD_LIMITS define is to avoid two fatal compiler errors:
+#'Taking the address of a bit field is not allowed. '
+#'An expression with bit field exists as the operand of "sizeof" '
+# (written by Wayne Schroeder <schroede@SDSC.EDU>)
+#
+# j90 is considered the base machine type for unicos machines,
+# so this configuration is now called "cray-j90" ...
+"cray-j90", "cc: -DBIT_FIELD_LIMITS -DTERMIOS::(unknown):CRAY::SIXTY_FOUR_BIT_LONG DES_INT:::",
+
+#
+# Cray T3E (Research Center Juelich, beckman@acl.lanl.gov)
+#
+# The BIT_FIELD_LIMITS define was written for the C90 (it seems).  I added
+# another use.  Basically, the problem is that the T3E uses some bit fields
+# for some st_addr stuff, and then sizeof and address-of fails
+# I could not use the ams/alpha.o option because the Cray assembler, 'cam'
+# did not like it.
+"cray-t3e", "cc: -DBIT_FIELD_LIMITS -DTERMIOS::(unknown):CRAY::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT:::",
+
+# DGUX, 88100.
+"dgux-R3-gcc",	"gcc:-O3 -fomit-frame-pointer::(unknown):::RC4_INDEX DES_UNROLL:::",
+"dgux-R4-gcc",	"gcc:-O3 -fomit-frame-pointer::(unknown)::-lnsl -lsocket:RC4_INDEX DES_UNROLL:::",
+"dgux-R4-x86-gcc",	"gcc:-O3 -fomit-frame-pointer -DL_ENDIAN::(unknown)::-lnsl -lsocket:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}",
+
+# Sinix/ReliantUNIX RM400
+# NOTE: The CDS++ Compiler up to V2.0Bsomething has the IRIX_CC_BUG optimizer problem. Better use -g  */
+"ReliantUNIX","cc:-KPIC -g -DTERMIOS -DB_ENDIAN::-Kthread:SNI:-lsocket -lnsl -lc -L/usr/ucblib -lucb:BN_LLONG DES_PTR DES_RISC2 DES_UNROLL BF_PTR:${no_asm}:dlfcn:reliantunix-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"SINIX","cc:-O::(unknown):SNI:-lsocket -lnsl -lc -L/usr/ucblib -lucb:RC4_INDEX RC4_CHAR:::",
+"SINIX-N","/usr/ucb/cc:-O2 -misaligned::(unknown)::-lucb:RC4_INDEX RC4_CHAR:::",
+
+# SIEMENS BS2000/OSD: an EBCDIC-based mainframe
+"BS2000-OSD","c89:-O -XLLML -XLLMK -XL -DB_ENDIAN -DTERMIOS -DCHARSET_EBCDIC::(unknown)::-lsocket -lnsl:THIRTY_TWO_BIT DES_PTR DES_UNROLL MD2_CHAR RC4_INDEX RC4_CHAR BF_PTR:::",
+
+# OS/390 Unix an EBCDIC-based Unix system on IBM mainframe
+# You need to compile using the c89.sh wrapper in the tools directory, because the
+# IBM compiler does not like the -L switch after any object modules.
+#
+"OS390-Unix","c89.sh:-O -DB_ENDIAN -DCHARSET_EBCDIC -DNO_SYS_PARAM_H  -D_ALL_SOURCE::(unknown):::THIRTY_TWO_BIT DES_PTR DES_UNROLL MD2_CHAR RC4_INDEX RC4_CHAR BF_PTR:::",
+
+# Visual C targets
+#
+# Win64 targets, WIN64I denotes IA-64 and WIN64A - AMD64
+"VC-WIN64I","cl:-W3 -Gs0 -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64I::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:ia64cpuid.o:ia64.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o:::::::ias:win32",
+"VC-WIN64A","cl:-W3 -Gs0 -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64A::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:x86_64cpuid.o:bn_asm.o x86_64-mont.o::aes-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o::rc4-x86_64.o:::wp-x86_64.o:cmll-x86_64.o cmll_misc.o:auto:win32",
+"debug-VC-WIN64I","cl:-W3 -Gs0 -Gy -Zi -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64I::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:ia64cpuid.o:ia64.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o:::::::ias:win32",
+"debug-VC-WIN64A","cl:-W3 -Gs0 -Gy -Zi -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64A::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:x86_64cpuid.o:bn_asm.o x86_64-mont.o::aes-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o::rc4-x86_64.o:::wp-x86_64.o:cmll-x86_64.o cmll_misc.o:auto:win32",
+# x86 Win32 target defaults to ANSI API, if you want UNICODE, complement
+# 'perl Configure VC-WIN32' with '-DUNICODE -D_UNICODE'
+"VC-WIN32","cl:-W3 -WX -Gs0 -GF -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE:::WIN32::BN_LLONG RC4_INDEX EXPORT_VAR_AS_FN ${x86_gcc_opts}:${x86_asm}:win32n:win32",
+# Unified CE target
+"debug-VC-WIN32","cl:-W3 -WX -Gs0 -GF -Gy -Zi -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE:::WIN32::BN_LLONG RC4_INDEX EXPORT_VAR_AS_FN ${x86_gcc_opts}:${x86_asm}:win32n:win32",
+"VC-CE","cl::::WINCE::BN_LLONG RC4_INDEX EXPORT_VAR_AS_FN ${x86_gcc_opts}:${no_asm}:win32",
+
+# Borland C++ 4.5
+"BC-32","bcc32::::WIN32::BN_LLONG DES_PTR RC4_INDEX EXPORT_VAR_AS_FN:${no_asm}:win32",
+
+# MinGW
+"mingw", "gcc:-mno-cygwin -DL_ENDIAN -DWIN32_LEAN_AND_MEAN -fomit-frame-pointer -O3 -march=i486 -Wall::-D_MT:MINGW32:-lws2_32 -lgdi32 -lcrypt32:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts} EXPORT_VAR_AS_FN:${x86_asm}:coff:win32:cygwin-shared:-D_WINDLL -DOPENSSL_USE_APPLINK:-mno-cygwin:.dll.a",
+# As for OPENSSL_USE_APPLINK. Applink makes it possible to use .dll
+# compiled with one compiler with application compiled with another
+# compiler. It's possible to engage Applink support in mingw64 build,
+# but it's not done, because till mingw64 supports structured exception
+# handling, one can't seriously consider its binaries for using with
+# non-mingw64 run-time environment. And as mingw64 is always consistent
+# with itself, Applink is never engaged and can as well be omitted.
+"mingw64", "gcc:-mno-cygwin -DL_ENDIAN -O3 -Wall -DWIN32_LEAN_AND_MEAN -DUNICODE -D_UNICODE::-D_MT:MINGW64:-lws2_32 -lgdi32 -lcrypt32:SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:${x86_64_asm}:mingw64:win32:cygwin-shared:-D_WINDLL:-mno-cygwin:.dll.a",
+
+# UWIN 
+"UWIN", "cc:-DTERMIOS -DL_ENDIAN -O -Wall:::UWIN::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:win32",
+
+# Cygwin
+"Cygwin-pre1.3", "gcc:-DTERMIOS -DL_ENDIAN -fomit-frame-pointer -O3 -m486 -Wall::(unknown):CYGWIN32::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:win32",
+"Cygwin", "gcc:-DTERMIOS -DL_ENDIAN -fomit-frame-pointer -O3 -march=i486 -Wall:::CYGWIN32::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_asm}:coff:dlfcn:cygwin-shared:-D_WINDLL:-shared:.dll.a",
+"debug-Cygwin", "gcc:-DTERMIOS -DL_ENDIAN -march=i486 -Wall -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -g -Wformat -Wshadow -Wmissing-prototypes -Wmissing-declarations -Werror:::CYGWIN32:::${no_asm}:dlfcn:cygwin-shared:-D_WINDLL:-shared:.dll.a",
+
+# NetWare from David Ward (dsward@novell.com)
+# requires either MetroWerks NLM development tools, or gcc / nlmconv
+# NetWare defaults socket bio to WinSock sockets. However,
+# the builds can be configured to use BSD sockets instead.
+# netware-clib => legacy CLib c-runtime support
+"netware-clib", "mwccnlm::::::${x86_gcc_opts}::",
+"netware-clib-bsdsock", "mwccnlm::::::${x86_gcc_opts}::",
+"netware-clib-gcc", "i586-netware-gcc:-nostdinc -I/ndk/nwsdk/include/nlm -I/ndk/ws295sdk/include -DL_ENDIAN -DNETWARE_CLIB -DOPENSSL_SYSNAME_NETWARE -O2 -Wall:::::${x86_gcc_opts}::",
+"netware-clib-bsdsock-gcc", "i586-netware-gcc:-nostdinc -I/ndk/nwsdk/include/nlm -DNETWARE_BSDSOCK -DNETDB_USE_INTERNET -DL_ENDIAN -DNETWARE_CLIB -DOPENSSL_SYSNAME_NETWARE -O2 -Wall:::::${x86_gcc_opts}::",
+# netware-libc => LibC/NKS support
+"netware-libc", "mwccnlm::::::BN_LLONG ${x86_gcc_opts}::",
+"netware-libc-bsdsock", "mwccnlm::::::BN_LLONG ${x86_gcc_opts}::",
+"netware-libc-gcc", "i586-netware-gcc:-nostdinc -I/ndk/libc/include -I/ndk/libc/include/winsock -DL_ENDIAN -DNETWARE_LIBC -DOPENSSL_SYSNAME_NETWARE -DTERMIO -O2 -Wall:::::BN_LLONG ${x86_gcc_opts}::",
+"netware-libc-bsdsock-gcc", "i586-netware-gcc:-nostdinc -I/ndk/libc/include -DNETWARE_BSDSOCK -DL_ENDIAN -DNETWARE_LIBC -DOPENSSL_SYSNAME_NETWARE -DTERMIO -O2 -Wall:::::BN_LLONG ${x86_gcc_opts}::",
+
+# DJGPP
+"DJGPP", "gcc:-I/dev/env/WATT_ROOT/inc -DTERMIOS -DL_ENDIAN -fomit-frame-pointer -O2 -Wall:::MSDOS:-L/dev/env/WATT_ROOT/lib -lwatt:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_asm}:a.out:",
+
+# Ultrix from Bernhard Simon <simon@zid.tuwien.ac.at>
+"ultrix-cc","cc:-std1 -O -Olimit 2500 -DL_ENDIAN::(unknown):::::::",
+"ultrix-gcc","gcc:-O3 -DL_ENDIAN::(unknown):::BN_LLONG::::",
+# K&R C is no longer supported; you need gcc on old Ultrix installations
+##"ultrix","cc:-O2 -DNOPROTO -DNOCONST -DL_ENDIAN::(unknown):::::::",
+
+##### MacOS X (a.k.a. Rhapsody or Darwin) setup
+"rhapsody-ppc-cc","cc:-O3 -DB_ENDIAN::(unknown):MACOSX_RHAPSODY::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}::",
+"darwin-ppc-cc","cc:-arch ppc -O3 -DB_ENDIAN -Wa,-force_cpusubtype_ALL::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc32_asm}:osx32:dlfcn:darwin-shared:-fPIC -fno-common:-arch ppc -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
+"darwin64-ppc-cc","cc:-arch ppc64 -O3 -DB_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc64_asm}:osx64:dlfcn:darwin-shared:-fPIC -fno-common:-arch ppc64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
+"darwin-i386-cc","cc:-arch i386 -O3 -fomit-frame-pointer -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:${x86_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
+"debug-darwin-i386-cc","cc:-arch i386 -g3 -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:${x86_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
+"darwin64-x86_64-cc","cc:-arch x86_64 -O3 -DL_ENDIAN -DMD32_REG_T=int -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$x86_64_asm;$asm=~s/rc4\-[^:]+//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
+"debug-darwin-ppc-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DB_ENDIAN -g -Wall -O::-D_REENTRANT:MACOSX::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc32_asm}:osx32:dlfcn:darwin-shared:-fPIC:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
+
+##### A/UX
+"aux3-gcc","gcc:-O2 -DTERMIO::(unknown):AUX:-lbsd:RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:::",
+
+##### Sony NEWS-OS 4.x
+"newsos4-gcc","gcc:-O -DB_ENDIAN::(unknown):NEWS4:-lmld -liberty:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC1 DES_UNROLL BF_PTR::::",
+
+##### GNU Hurd
+"hurd-x86",  "gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -march=i486 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC",
+
+##### OS/2 EMX
+"OS2-EMX", "gcc::::::::",
+
+##### VxWorks for various targets
+"vxworks-ppc405","ccppc:-g -msoft-float -mlongcall -DCPU=PPC405 -I\$(WIND_BASE)/target/h:::VXWORKS:-r:::::",
+"vxworks-ppc750","ccppc:-ansi -nostdinc -DPPC750 -D_REENTRANT -fvolatile -fno-builtin -fno-for-scope -fsigned-char -Wall -msoft-float -mlongcall -DCPU=PPC604 -I\$(WIND_BASE)/target/h \$(DEBUG_FLAG):::VXWORKS:-r:::::",
+"vxworks-ppc750-debug","ccppc:-ansi -nostdinc -DPPC750 -D_REENTRANT -fvolatile -fno-builtin -fno-for-scope -fsigned-char -Wall -msoft-float -mlongcall -DCPU=PPC604 -I\$(WIND_BASE)/target/h -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DDEBUG -g:::VXWORKS:-r:::::",
+"vxworks-ppc860","ccppc:-nostdinc -msoft-float -DCPU=PPC860 -DNO_STRINGS_H -I\$(WIND_BASE)/target/h:::VXWORKS:-r:::::",
+"vxworks-mipsle","ccmips:-B\$(WIND_BASE)/host/\$(WIND_HOST_TYPE)/lib/gcc-lib/ -DL_ENDIAN -EL -Wl,-EL -mips2 -mno-branch-likely -G 0 -fno-builtin -msoft-float -DCPU=MIPS32 -DMIPSEL -DNO_STRINGS_H -I\$(WIND_BASE)/target/h:::VXWORKS:-r::${no_asm}::::::ranlibmips:",
+
+##### Compaq Non-Stop Kernel (Tandem)
+"tandem-c89","c89:-Ww -D__TANDEM -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1 -D_TANDEM_SOURCE -DB_ENDIAN::(unknown):::THIRTY_TWO_BIT:::",
+
+# uClinux
+"uClinux-dist","$ENV{'CC'}:\$(CFLAGS)::-D_REENTRANT::\$(LDFLAGS) \$(LDLIBS):BN_LLONG:::::::::::::::$ENV{'LIBSSL_dlfcn'}:linux-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):$ENV{'RANLIB'}::",
+"uClinux-dist64","$ENV{'CC'}:\$(CFLAGS)::-D_REENTRANT::\$(LDFLAGS) \$(LDLIBS):SIXTY_FOUR_BIT_LONG:::::::::::::::$ENV{'LIBSSL_dlfcn'}:linux-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):$ENV{'RANLIB'}::",
+
+);
+
+my @MK1MF_Builds=qw(VC-WIN64I VC-WIN64A
+		    debug-VC-WIN64I debug-VC-WIN64A
+		    VC-NT VC-CE VC-WIN32 debug-VC-WIN32
+		    BC-32 
+		    netware-clib netware-clib-bsdsock
+		    netware-libc netware-libc-bsdsock);
+
+my $idx = 0;
+my $idx_cc = $idx++;
+my $idx_cflags = $idx++;
+my $idx_unistd = $idx++;
+my $idx_thread_cflag = $idx++;
+my $idx_sys_id = $idx++;
+my $idx_lflags = $idx++;
+my $idx_bn_ops = $idx++;
+my $idx_cpuid_obj = $idx++;
+my $idx_bn_obj = $idx++;
+my $idx_des_obj = $idx++;
+my $idx_aes_obj = $idx++;
+my $idx_bf_obj = $idx++;
+my $idx_md5_obj = $idx++;
+my $idx_sha1_obj = $idx++;
+my $idx_cast_obj = $idx++;
+my $idx_rc4_obj = $idx++;
+my $idx_rmd160_obj = $idx++;
+my $idx_rc5_obj = $idx++;
+my $idx_wp_obj = $idx++;
+my $idx_cmll_obj = $idx++;
+my $idx_perlasm_scheme = $idx++;
+my $idx_dso_scheme = $idx++;
+my $idx_shared_target = $idx++;
+my $idx_shared_cflag = $idx++;
+my $idx_shared_ldflag = $idx++;
+my $idx_shared_extension = $idx++;
+my $idx_ranlib = $idx++;
+my $idx_arflags = $idx++;
+my $idx_multilib = $idx++;
+
+my $prefix="";
+my $libdir="";
+my $openssldir="";
+my $exe_ext="";
+my $install_prefix= "$ENV{'INSTALL_PREFIX'}";
+my $cross_compile_prefix="";
+my $no_threads=0;
+my $threads=0;
+my $no_shared=0; # but "no-shared" is default
+my $zlib=1;      # but "no-zlib" is default
+my $no_krb5=0;   # but "no-krb5" is implied unless "--with-krb5-..." is used
+my $no_rfc3779=1; # but "no-rfc3779" is default
+my $no_asm=0;
+my $no_dso=0;
+my $no_gmp=0;
+my @skip=();
+my $Makefile="Makefile";
+my $des_locl="crypto/des/des_locl.h";
+my $des	="crypto/des/des.h";
+my $bn	="crypto/bn/bn.h";
+my $md2	="crypto/md2/md2.h";
+my $rc4	="crypto/rc4/rc4.h";
+my $rc4_locl="crypto/rc4/rc4_locl.h";
+my $idea	="crypto/idea/idea.h";
+my $rc2	="crypto/rc2/rc2.h";
+my $bf	="crypto/bf/bf_locl.h";
+my $bn_asm	="bn_asm.o";
+my $des_enc="des_enc.o fcrypt_b.o";
+my $aes_enc="aes_core.o aes_cbc.o";
+my $bf_enc	="bf_enc.o";
+my $cast_enc="c_enc.o";
+my $rc4_enc="rc4_enc.o rc4_skey.o";
+my $rc5_enc="rc5_enc.o";
+my $md5_obj="";
+my $sha1_obj="";
+my $rmd160_obj="";
+my $cmll_enc="camellia.o cmll_misc.o cmll_cbc.o";
+my $processor="";
+my $default_ranlib;
+my $perl;
+
+
+# All of the following is disabled by default (RC5 was enabled before 0.9.8):
+
+my %disabled = ( # "what"         => "comment" [or special keyword "experimental"]
+		 "gmp"		  => "default",
+                 "jpake"          => "experimental",
+                 "md2"            => "default",
+                 "rc5"            => "default",
+		 "rfc3779"	  => "default",
+                 "shared"         => "default",
+		 "store"	  => "experimental",
+                 "zlib"           => "default",
+                 "zlib-dynamic"   => "default"
+               );
+my @experimental = ();
+
+# This is what $depflags will look like with the above defaults
+# (we need this to see if we should advise the user to run "make depend"):
+my $default_depflags = " -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_STORE";
+
+# Explicit "no-..." options will be collected in %disabled along with the defaults.
+# To remove something from %disabled, use "enable-foo" (unless it's experimental).
+# For symmetry, "disable-foo" is a synonym for "no-foo".
+
+# For features called "experimental" here, a more explicit "experimental-foo" is needed to enable.
+# We will collect such requests in @experimental.
+# To avoid accidental use of experimental features, applications will have to use -DOPENSSL_EXPERIMENTAL_FOO.
+
+
+my $no_sse2=0;
+
+&usage if ($#ARGV < 0);
+
+my $flags;
+my $depflags;
+my $openssl_experimental_defines;
+my $openssl_algorithm_defines;
+my $openssl_thread_defines;
+my $openssl_sys_defines="";
+my $openssl_other_defines;
+my $libs;
+my $libkrb5="";
+my $target;
+my $options;
+my $symlink;
+my $make_depend=0;
+my %withargs=();
+
+my @argvcopy=@ARGV;
+my $argvstring="";
+my $argv_unprocessed=1;
+
+while($argv_unprocessed)
+	{
+	$flags="";
+	$depflags="";
+	$openssl_experimental_defines="";
+	$openssl_algorithm_defines="";
+	$openssl_thread_defines="";
+	$openssl_sys_defines="";
+	$openssl_other_defines="";
+	$libs="";
+	$target="";
+	$options="";
+	$symlink=1;
+
+	$argv_unprocessed=0;
+	$argvstring=join(' ',@argvcopy);
+
+PROCESS_ARGS:
+	foreach (@argvcopy)
+		{
+		s /^-no-/no-/; # some people just can't read the instructions
+
+		# rewrite some options in "enable-..." form
+		s /^-?-?shared$/enable-shared/;
+		s /^threads$/enable-threads/;
+		s /^zlib$/enable-zlib/;
+		s /^zlib-dynamic$/enable-zlib-dynamic/;
+
+		if (/^no-(.+)$/ || /^disable-(.+)$/)
+			{
+			if (!($disabled{$1} eq "experimental"))
+				{
+				if ($1 eq "ssl")
+					{
+					$disabled{"ssl2"} = "option(ssl)";
+					$disabled{"ssl3"} = "option(ssl)";
+					}
+				elsif ($1 eq "tls")
+					{
+					$disabled{"tls1"} = "option(tls)"
+					}
+				else
+					{
+					$disabled{$1} = "option";
+					}
+				}			
+			}
+		elsif (/^enable-(.+)$/ || /^experimental-(.+)$/)
+			{
+			my $algo = $1;
+			if ($disabled{$algo} eq "experimental")
+				{
+				die "You are requesting an experimental feature; please say 'experimental-$algo' if you are sure\n"
+					unless (/^experimental-/);
+				push @experimental, $algo;
+				}
+			delete $disabled{$algo};
+
+			$threads = 1 if ($algo eq "threads");
+			}
+		elsif (/^--test-sanity$/)
+			{
+			exit(&test_sanity());
+			}
+		elsif (/^--strict-warnings/)
+			{
+			$strict_warnings = 1;
+			}
+		elsif (/^reconfigure/ || /^reconf/)
+			{
+			if (open(IN,"<$Makefile"))
+				{
+				while (<IN>)
+					{
+					chomp;
+					if (/^CONFIGURE_ARGS=(.*)/)
+						{
+						$argvstring=$1;
+						@argvcopy=split(' ',$argvstring);
+						die "Incorrect data to reconfigure, please do a normal configuration\n"
+							if (grep(/^reconf/,@argvcopy));
+						print "Reconfiguring with: $argvstring\n";
+						$argv_unprocessed=1;
+						close(IN);
+						last PROCESS_ARGS;
+						}
+					}
+				close(IN);
+				}
+			die "Insufficient data to reconfigure, please do a normal configuration\n";
+			}
+		elsif (/^386$/)
+			{ $processor=386; }
+		elsif (/^rsaref$/)
+			{
+			# No RSAref support any more since it's not needed.
+			# The check for the option is there so scripts aren't
+			# broken
+			}
+		elsif (/^[-+]/)
+			{
+			if (/^-[lL](.*)$/ or /^-Wl,/)
+				{
+				$libs.=$_." ";
+				}
+			elsif (/^-[^-]/ or /^\+/)
+				{
+				$flags.=$_." ";
+				}
+			elsif (/^--prefix=(.*)$/)
+				{
+				$prefix=$1;
+				}
+			elsif (/^--libdir=(.*)$/)
+				{
+				$libdir=$1;
+				}
+			elsif (/^--openssldir=(.*)$/)
+				{
+				$openssldir=$1;
+				}
+			elsif (/^--install.prefix=(.*)$/)
+				{
+				$install_prefix=$1;
+				}
+			elsif (/^--with-krb5-(dir|lib|include|flavor)=(.*)$/)
+				{
+				$withargs{"krb5-".$1}=$2;
+				}
+			elsif (/^--with-zlib-lib=(.*)$/)
+				{
+				$withargs{"zlib-lib"}=$1;
+				}
+			elsif (/^--with-zlib-include=(.*)$/)
+				{
+				$withargs{"zlib-include"}="-I$1";
+				}
+			elsif (/^--cross-compile-prefix=(.*)$/)
+				{
+				$cross_compile_prefix=$1;
+				}
+			else
+				{
+				print STDERR $usage;
+				exit(1);
+				}
+			}
+		elsif ($_ =~ /^([^:]+):(.+)$/)
+			{
+			eval "\$table{\$1} = \"$2\""; # allow $xxx constructs in the string
+			$target=$1;
+			}
+		else
+			{
+			die "target already defined - $target (offending arg: $_)\n" if ($target ne "");
+			$target=$_;
+			}
+
+		unless ($_ eq $target || /^no-/ || /^disable-/)
+			{
+			# "no-..." follows later after implied disactivations
+			# have been derived.  (Don't take this too seroiusly,
+			# we really only write OPTIONS to the Makefile out of
+			# nostalgia.)
+
+			if ($options eq "")
+				{ $options = $_; }
+			else
+				{ $options .= " ".$_; }
+			}
+		}
+	}
+
+
+
+if ($processor eq "386")
+	{
+	$disabled{"sse2"} = "forced";
+	}
+
+if (!defined($withargs{"krb5-flavor"}) || $withargs{"krb5-flavor"} eq "")
+	{
+	$disabled{"krb5"} = "krb5-flavor not specified";
+	}
+
+if (!defined($disabled{"zlib-dynamic"}))
+	{
+	# "zlib-dynamic" was specifically enabled, so enable "zlib"
+	delete $disabled{"zlib"};
+	}
+
+if (defined($disabled{"rijndael"}))
+	{
+	$disabled{"aes"} = "forced";
+	}
+if (defined($disabled{"des"}))
+	{
+	$disabled{"mdc2"} = "forced";
+	}
+if (defined($disabled{"ec"}))
+	{
+	$disabled{"ecdsa"} = "forced";
+	$disabled{"ecdh"} = "forced";
+	}
+
+# SSL 2.0 requires MD5 and RSA
+if (defined($disabled{"md5"}) || defined($disabled{"rsa"}))
+	{
+	$disabled{"ssl2"} = "forced";
+	}
+
+# SSL 3.0 and TLS requires MD5 and SHA and either RSA or DSA+DH
+if (defined($disabled{"md5"}) || defined($disabled{"sha"})
+    || (defined($disabled{"rsa"})
+        && (defined($disabled{"dsa"}) || defined($disabled{"dh"}))))
+	{
+	$disabled{"ssl3"} = "forced";
+	$disabled{"tls1"} = "forced";
+	}
+
+if (defined($disabled{"tls1"}))
+	{
+	$disabled{"tlsext"} = "forced";
+	}
+
+if (defined($disabled{"ec"}) || defined($disabled{"dsa"})
+    || defined($disabled{"dh"}))
+	{
+	$disabled{"gost"} = "forced";
+	}
+
+if ($target eq "TABLE") {
+	foreach $target (sort keys %table) {
+		print_table_entry($target);
+	}
+	exit 0;
+}
+
+if ($target eq "LIST") {
+	foreach (sort keys %table) {
+		print;
+		print "\n";
+	}
+	exit 0;
+}
+
+if ($target =~ m/^CygWin32(-.*)$/) {
+	$target = "Cygwin".$1;
+}
+
+print "Configuring for $target\n";
+
+&usage if (!defined($table{$target}));
+
+
+foreach (sort (keys %disabled))
+	{
+	$options .= " no-$_";
+
+	printf "    no-%-12s %-10s", $_, "[$disabled{$_}]";
+
+	if (/^dso$/)
+		{ $no_dso = 1; }
+	elsif (/^threads$/)
+		{ $no_threads = 1; }
+	elsif (/^shared$/)
+		{ $no_shared = 1; }
+	elsif (/^zlib$/)
+		{ $zlib = 0; }
+	elsif (/^static-engine$/)
+		{ }
+	elsif (/^zlib-dynamic$/)
+		{ }
+	elsif (/^symlinks$/)
+		{ $symlink = 0; }
+	elsif (/^sse2$/)
+		{ $no_sse2 = 1; }
+	else
+		{
+		my ($ALGO, $algo);
+		($ALGO = $algo = $_) =~ tr/[a-z]/[A-Z]/;
+
+		if (/^asm$/ || /^err$/ || /^hw$/ || /^hw-/)
+			{
+			$openssl_other_defines .= "#define OPENSSL_NO_$ALGO\n";
+			print " OPENSSL_NO_$ALGO";
+		
+			if (/^err$/)	{ $flags .= "-DOPENSSL_NO_ERR "; }
+			elsif (/^asm$/)	{ $no_asm = 1; }
+			}
+		else
+			{
+			$openssl_algorithm_defines .= "#define OPENSSL_NO_$ALGO\n";
+			print " OPENSSL_NO_$ALGO";
+
+			if (/^krb5$/)
+				{ $no_krb5 = 1; }
+			else
+				{
+				push @skip, $algo;
+				print " (skip dir)";
+
+				$depflags .= " -DOPENSSL_NO_$ALGO";
+				}
+			}
+		}
+
+	print "\n";
+	}
+
+my $exp_cflags = "";
+foreach (sort @experimental)
+	{
+	my $ALGO;
+	($ALGO = $_) =~ tr/[a-z]/[A-Z]/;
+
+	# opensslconf.h will set OPENSSL_NO_... unless OPENSSL_EXPERIMENTAL_... is defined
+	$openssl_experimental_defines .= "#define OPENSSL_NO_$ALGO\n";
+	$exp_cflags .= " -DOPENSSL_EXPERIMENTAL_$ALGO";
+	}
+
+my $IsMK1MF=scalar grep /^$target$/,@MK1MF_Builds;
+
+$exe_ext=".exe" if ($target eq "Cygwin" || $target eq "DJGPP" || $target =~ /^mingw/);
+$exe_ext=".nlm" if ($target =~ /netware/);
+$exe_ext=".pm"  if ($target =~ /vos/);
+$openssldir="/usr/local/ssl" if ($openssldir eq "" and $prefix eq "");
+$prefix=$openssldir if $prefix eq "";
+
+$default_ranlib= &which("ranlib") or $default_ranlib="true";
+$perl=$ENV{'PERL'} or $perl=&which("perl5") or $perl=&which("perl")
+  or $perl="perl";
+my $make = $ENV{'MAKE'} || "make";
+
+$cross_compile_prefix=$ENV{'CROSS_COMPILE'} if $cross_compile_prefix eq "";
+
+chop $openssldir if $openssldir =~ /\/$/;
+chop $prefix if $prefix =~ /.\/$/;
+
+$openssldir=$prefix . "/ssl" if $openssldir eq "";
+$openssldir=$prefix . "/" . $openssldir if $openssldir !~ /(^\/|^[a-zA-Z]:[\\\/])/;
+
+
+print "IsMK1MF=$IsMK1MF\n";
+
+my @fields = split(/\s*:\s*/,$table{$target} . ":" x 30 , -1);
+my $cc = $fields[$idx_cc];
+# Allow environment CC to override compiler...
+if($ENV{CC}) {
+    $cc = $ENV{CC};
+}
+my $cflags = $fields[$idx_cflags];
+my $unistd = $fields[$idx_unistd];
+my $thread_cflag = $fields[$idx_thread_cflag];
+my $sys_id = $fields[$idx_sys_id];
+my $lflags = $fields[$idx_lflags];
+my $bn_ops = $fields[$idx_bn_ops];
+my $cpuid_obj = $fields[$idx_cpuid_obj];
+my $bn_obj = $fields[$idx_bn_obj];
+my $des_obj = $fields[$idx_des_obj];
+my $aes_obj = $fields[$idx_aes_obj];
+my $bf_obj = $fields[$idx_bf_obj];
+my $md5_obj = $fields[$idx_md5_obj];
+my $sha1_obj = $fields[$idx_sha1_obj];
+my $cast_obj = $fields[$idx_cast_obj];
+my $rc4_obj = $fields[$idx_rc4_obj];
+my $rmd160_obj = $fields[$idx_rmd160_obj];
+my $rc5_obj = $fields[$idx_rc5_obj];
+my $wp_obj = $fields[$idx_wp_obj];
+my $cmll_obj = $fields[$idx_cmll_obj];
+my $perlasm_scheme = $fields[$idx_perlasm_scheme];
+my $dso_scheme = $fields[$idx_dso_scheme];
+my $shared_target = $fields[$idx_shared_target];
+my $shared_cflag = $fields[$idx_shared_cflag];
+my $shared_ldflag = $fields[$idx_shared_ldflag];
+my $shared_extension = $fields[$idx_shared_extension];
+my $ranlib = $ENV{'RANLIB'} || $fields[$idx_ranlib];
+my $ar = $ENV{'AR'} || "ar";
+my $arflags = $fields[$idx_arflags];
+my $multilib = $fields[$idx_multilib];
+
+# if $prefix/lib$multilib is not an existing directory, then
+# assume that it's not searched by linker automatically, in
+# which case adding $multilib suffix causes more grief than
+# we're ready to tolerate, so don't...
+$multilib="" if !-d "$prefix/lib$multilib";
+
+$libdir="lib$multilib" if $libdir eq "";
+
+$cflags = "$cflags$exp_cflags";
+
+# '%' in $lflags is used to split flags to "pre-" and post-flags
+my ($prelflags,$postlflags)=split('%',$lflags);
+if (defined($postlflags))	{ $lflags=$postlflags;	}
+else				{ $lflags=$prelflags; undef $prelflags;	}
+
+if ($target =~ /^mingw/ && `$cc --target-help 2>&1` !~ m/\-mno\-cygwin/m)
+	{
+	$cflags =~ s/\-mno\-cygwin\s*//;
+	$shared_ldflag =~ s/\-mno\-cygwin\s*//;
+	}
+
+my $no_shared_warn=0;
+my $no_user_cflags=0;
+
+if ($flags ne "")	{ $cflags="$flags$cflags"; }
+else			{ $no_user_cflags=1;       }
+
+# Kerberos settings.  The flavor must be provided from outside, either through
+# the script "config" or manually.
+if (!$no_krb5)
+	{
+	my ($lresolv, $lpath, $lext);
+	if ($withargs{"krb5-flavor"} =~ /^[Hh]eimdal$/)
+		{
+		die "Sorry, Heimdal is currently not supported\n";
+		}
+	##### HACK to force use of Heimdal.
+	##### WARNING: Since we don't really have adequate support for Heimdal,
+	#####          using this will break the build.  You'll have to make
+	#####          changes to the source, and if you do, please send
+	#####          patches to openssl-dev@openssl.org
+	if ($withargs{"krb5-flavor"} =~ /^force-[Hh]eimdal$/)
+		{
+		warn "Heimdal isn't really supported.  Your build WILL break\n";
+		warn "If you fix the problems, please send a patch to openssl-dev\@openssl.org\n";
+		$withargs{"krb5-dir"} = "/usr/heimdal"
+			if $withargs{"krb5-dir"} eq "";
+		$withargs{"krb5-lib"} = "-L".$withargs{"krb5-dir"}.
+			"/lib -lgssapi -lkrb5 -lcom_err"
+			if $withargs{"krb5-lib"} eq "" && !$IsMK1MF;
+		$cflags="-DKRB5_HEIMDAL $cflags";
+		}
+	if ($withargs{"krb5-flavor"} =~ /^[Mm][Ii][Tt]/)
+		{
+		$withargs{"krb5-dir"} = "/usr/kerberos"
+			if $withargs{"krb5-dir"} eq "";
+		$withargs{"krb5-lib"} = "-L".$withargs{"krb5-dir"}.
+			"/lib -lgssapi_krb5 -lkrb5 -lcom_err -lk5crypto"
+			if $withargs{"krb5-lib"} eq "" && !$IsMK1MF;
+		$cflags="-DKRB5_MIT $cflags";
+		$withargs{"krb5-flavor"} =~ s/^[Mm][Ii][Tt][._-]*//;
+		if ($withargs{"krb5-flavor"} =~ /^1[._-]*[01]/)
+			{
+			$cflags="-DKRB5_MIT_OLD11 $cflags";
+			}
+		}
+	LRESOLV:
+	foreach $lpath ("/lib", "/usr/lib")
+		{
+		foreach $lext ("a", "so")
+			{
+			$lresolv = "$lpath/libresolv.$lext";
+			last LRESOLV	if (-r "$lresolv");
+			$lresolv = "";
+			}
+		}
+	$withargs{"krb5-lib"} .= " -lresolv"
+		if ("$lresolv" ne "");
+	$withargs{"krb5-include"} = "-I".$withargs{"krb5-dir"}."/include"
+		if $withargs{"krb5-include"} eq "" &&
+		   $withargs{"krb5-dir"} ne "";
+	}
+
+# The DSO code currently always implements all functions so that no
+# applications will have to worry about that from a compilation point
+# of view. However, the "method"s may return zero unless that platform
+# has support compiled in for them. Currently each method is enabled
+# by a define "DSO_<name>" ... we translate the "dso_scheme" config
+# string entry into using the following logic;
+my $dso_cflags;
+if (!$no_dso && $dso_scheme ne "")
+	{
+	$dso_scheme =~ tr/[a-z]/[A-Z]/;
+	if ($dso_scheme eq "DLFCN")
+		{
+		$dso_cflags = "-DDSO_DLFCN -DHAVE_DLFCN_H";
+		}
+	elsif ($dso_scheme eq "DLFCN_NO_H")
+		{
+		$dso_cflags = "-DDSO_DLFCN";
+		}
+	else
+		{
+		$dso_cflags = "-DDSO_$dso_scheme";
+		}
+	$cflags = "$dso_cflags $cflags";
+	}
+
+my $thread_cflags;
+my $thread_defines;
+if ($thread_cflag ne "(unknown)" && !$no_threads)
+	{
+	# If we know how to do it, support threads by default.
+	$threads = 1;
+	}
+if ($thread_cflag eq "(unknown)" && $threads)
+	{
+	# If the user asked for "threads", [s]he is also expected to
+	# provide any system-dependent compiler options that are
+	# necessary.
+	if ($no_user_cflags)
+		{
+		print "You asked for multi-threading support, but didn't\n";
+		print "provide any system-specific compiler options\n";
+		exit(1);
+		}
+	$thread_cflags="-DOPENSSL_THREADS $cflags" ;
+	$thread_defines .= "#define OPENSSL_THREADS\n";
+	}
+else
+	{
+	$thread_cflags="-DOPENSSL_THREADS $thread_cflag $cflags";
+	$thread_defines .= "#define OPENSSL_THREADS\n";
+#	my $def;
+#	foreach $def (split ' ',$thread_cflag)
+#		{
+#		if ($def =~ s/^-D// && $def !~ /^_/)
+#			{
+#			$thread_defines .= "#define $def\n";
+#			}
+#		}
+	}	
+
+$lflags="$libs$lflags" if ($libs ne "");
+
+if ($no_asm)
+	{
+	$cpuid_obj=$bn_obj=
+	$des_obj=$aes_obj=$bf_obj=$cast_obj=$rc4_obj=$rc5_obj=$cmll_obj=
+	$sha1_obj=$md5_obj=$rmd160_obj=$wp_obj="";
+	}
+
+if (!$no_shared)
+	{
+	$cast_obj="";	# CAST assembler is not PIC
+	}
+
+if ($threads)
+	{
+	$cflags=$thread_cflags;
+	$openssl_thread_defines .= $thread_defines;
+	}
+
+if ($zlib)
+	{
+	$cflags = "-DZLIB $cflags";
+	if (defined($disabled{"zlib-dynamic"}))
+		{
+		if (defined($withargs{"zlib-lib"}))
+			{
+			$lflags = "$lflags -L" . $withargs{"zlib-lib"} . " -lz";
+			}
+		else
+			{
+			$lflags = "$lflags -lz";
+			}
+		}
+	else
+		{
+		$cflags = "-DZLIB_SHARED $cflags";
+		}
+	}
+
+# You will find shlib_mark1 and shlib_mark2 explained in Makefile.org
+my $shared_mark = "";
+if ($shared_target eq "")
+	{
+	$no_shared_warn = 1 if !$no_shared;
+	$no_shared = 1;
+	}
+if (!$no_shared)
+	{
+	if ($shared_cflag ne "")
+		{
+		$cflags = "$shared_cflag -DOPENSSL_PIC $cflags";
+		}
+	}
+
+if (!$IsMK1MF)
+	{
+	# add {no-}static-engine to options to allow mkdef.pl to work without extra arguments
+	if ($no_shared)
+		{
+		$openssl_other_defines.="#define OPENSSL_NO_DYNAMIC_ENGINE\n";
+		$options.=" static-engine";
+		}
+	else
+		{
+		$openssl_other_defines.="#define OPENSSL_NO_STATIC_ENGINE\n";
+		$options.=" no-static-engine";
+		}
+	}
+
+$cpuid_obj.=" uplink.o uplink-cof.o" if ($cflags =~ /\-DOPENSSL_USE_APPLINK/);
+
+#
+# Platform fix-ups
+#
+if ($target =~ /\-icc$/)	# Intel C compiler
+	{
+	my $iccver=0;
+	if (open(FD,"$cc -V 2>&1 |"))
+		{
+		while(<FD>) { $iccver=$1 if (/Version ([0-9]+)\./); }
+		close(FD);
+		}
+	if ($iccver>=8)
+		{
+		# Eliminate unnecessary dependency from libirc.a. This is
+		# essential for shared library support, as otherwise
+		# apps/openssl can end up in endless loop upon startup...
+		$cflags.=" -Dmemcpy=__builtin_memcpy -Dmemset=__builtin_memset";
+		}
+	if ($iccver>=9)
+		{
+		$cflags.=" -i-static";
+		$cflags=~s/\-no_cpprt/-no-cpprt/;
+		}
+	if ($iccver>=10)
+		{
+		$cflags=~s/\-i\-static/-static-intel/;
+		}
+	}
+
+# Unlike other OSes (like Solaris, Linux, Tru64, IRIX) BSD run-time
+# linkers (tested OpenBSD, NetBSD and FreeBSD) "demand" RPATH set on
+# .so objects. Apparently application RPATH is not global and does
+# not apply to .so linked with other .so. Problem manifests itself
+# when libssl.so fails to load libcrypto.so. One can argue that we
+# should engrave this into Makefile.shared rules or into BSD-* config
+# lines above. Meanwhile let's try to be cautious and pass -rpath to
+# linker only when --prefix is not /usr.
+if ($target =~ /^BSD\-/)
+	{
+	$shared_ldflag.=" -Wl,-rpath,\$(LIBRPATH)" if ($prefix !~ m|^/usr[/]*$|);
+	}
+
+if ($sys_id ne "")
+	{
+	#$cflags="-DOPENSSL_SYSNAME_$sys_id $cflags";
+	$openssl_sys_defines="#define OPENSSL_SYSNAME_$sys_id\n";
+	}
+
+if ($ranlib eq "")
+	{
+	$ranlib = $default_ranlib;
+	}
+
+#my ($bn1)=split(/\s+/,$bn_obj);
+#$bn1 = "" unless defined $bn1;
+#$bn1=$bn_asm unless ($bn1 =~ /\.o$/);
+#$bn_obj="$bn1";
+
+$cpuid_obj="" if ($processor eq "386");
+
+$bn_obj = $bn_asm unless $bn_obj ne "";
+# bn-586 is the only one implementing bn_*_part_words
+$cflags.=" -DOPENSSL_BN_ASM_PART_WORDS" if ($bn_obj =~ /bn-586/);
+$cflags.=" -DOPENSSL_IA32_SSE2" if (!$no_sse2 && $bn_obj =~ /86/);
+
+$cflags.=" -DOPENSSL_BN_ASM_MONT" if ($bn_obj =~ /-mont/);
+
+$cpuid_obj="mem_clr.o"	unless ($cpuid_obj =~ /\.o$/);
+$des_obj=$des_enc	unless ($des_obj =~ /\.o$/);
+$bf_obj=$bf_enc		unless ($bf_obj =~ /\.o$/);
+$cast_obj=$cast_enc	unless ($cast_obj =~ /\.o$/);
+$rc4_obj=$rc4_enc	unless ($rc4_obj =~ /\.o$/);
+$rc5_obj=$rc5_enc	unless ($rc5_obj =~ /\.o$/);
+if ($sha1_obj =~ /\.o$/)
+	{
+#	$sha1_obj=$sha1_enc;
+	$cflags.=" -DSHA1_ASM"   if ($sha1_obj =~ /sx86/ || $sha1_obj =~ /sha1/);
+	$cflags.=" -DSHA256_ASM" if ($sha1_obj =~ /sha256/);
+	$cflags.=" -DSHA512_ASM" if ($sha1_obj =~ /sha512/);
+	if ($sha1_obj =~ /sse2/)
+	    {	if ($no_sse2)
+		{   $sha1_obj =~ s/\S*sse2\S+//;        }
+		elsif ($cflags !~ /OPENSSL_IA32_SSE2/)
+		{   $cflags.=" -DOPENSSL_IA32_SSE2";    }
+	    }
+	}
+if ($md5_obj =~ /\.o$/)
+	{
+#	$md5_obj=$md5_enc;
+	$cflags.=" -DMD5_ASM";
+	}
+if ($rmd160_obj =~ /\.o$/)
+	{
+#	$rmd160_obj=$rmd160_enc;
+	$cflags.=" -DRMD160_ASM";
+	}
+if ($aes_obj =~ /\.o$/)
+	{
+	$cflags.=" -DAES_ASM";
+	}
+else	{
+	$aes_obj=$aes_enc;
+	}
+$wp_obj="" if ($wp_obj =~ /mmx/ && $processor eq "386");
+if ($wp_obj =~ /\.o$/)
+	{
+	$cflags.=" -DWHIRLPOOL_ASM";
+	}
+else	{
+	$wp_obj="wp_block.o";
+	}
+$cmll_obj=$cmll_enc	unless ($cmll_obj =~ /.o$/);
+
+# "Stringify" the C flags string.  This permits it to be made part of a string
+# and works as well on command lines.
+$cflags =~ s/([\\\"])/\\\1/g;
+
+my $version = "unknown";
+my $version_num = "unknown";
+my $major = "unknown";
+my $minor = "unknown";
+my $shlib_version_number = "unknown";
+my $shlib_version_history = "unknown";
+my $shlib_major = "unknown";
+my $shlib_minor = "unknown";
+
+open(IN,'<crypto/opensslv.h') || die "unable to read opensslv.h:$!\n";
+while (<IN>)
+	{
+	$version=$1 if /OPENSSL.VERSION.TEXT.*OpenSSL (\S+) /;
+	$version_num=$1 if /OPENSSL.VERSION.NUMBER.*0x(\S+)/;
+	$shlib_version_number=$1 if /SHLIB_VERSION_NUMBER *"([^"]+)"/;
+	$shlib_version_history=$1 if /SHLIB_VERSION_HISTORY *"([^"]*)"/;
+	}
+close(IN);
+if ($shlib_version_history ne "") { $shlib_version_history .= ":"; }
+
+if ($version =~ /(^[0-9]*)\.([0-9\.]*)/)
+	{
+	$major=$1;
+	$minor=$2;
+	}
+
+if ($shlib_version_number =~ /(^[0-9]*)\.([0-9\.]*)/)
+	{
+	$shlib_major=$1;
+	$shlib_minor=$2;
+	}
+
+if ($strict_warnings)
+	{
+	my $wopt;
+	die "ERROR --strict-warnings requires gcc" unless ($cc =~ /gcc$/);
+	foreach $wopt (split /\s+/, $gcc_devteam_warn)
+		{
+		$cflags .= " $wopt" unless ($cflags =~ /$wopt/)
+		}
+	}
+
+open(IN,'<Makefile.org') || die "unable to read Makefile.org:$!\n";
+unlink("$Makefile.new") || die "unable to remove old $Makefile.new:$!\n" if -e "$Makefile.new";
+open(OUT,">$Makefile.new") || die "unable to create $Makefile.new:$!\n";
+print OUT "### Generated automatically from Makefile.org by Configure.\n\n";
+my $sdirs=0;
+while (<IN>)
+	{
+	chomp;
+	$sdirs = 1 if /^SDIRS=/;
+	if ($sdirs) {
+		my $dir;
+		foreach $dir (@skip) {
+			s/(\s)$dir /$1/;
+			s/\s$dir$//;
+			}
+		}
+	$sdirs = 0 unless /\\$/;
+        s/engines // if (/^DIRS=/ && $disabled{"engine"});
+	s/ccgost// if (/^ENGDIRS=/ && $disabled{"gost"});
+	s/^VERSION=.*/VERSION=$version/;
+	s/^MAJOR=.*/MAJOR=$major/;
+	s/^MINOR=.*/MINOR=$minor/;
+	s/^SHLIB_VERSION_NUMBER=.*/SHLIB_VERSION_NUMBER=$shlib_version_number/;
+	s/^SHLIB_VERSION_HISTORY=.*/SHLIB_VERSION_HISTORY=$shlib_version_history/;
+	s/^SHLIB_MAJOR=.*/SHLIB_MAJOR=$shlib_major/;
+	s/^SHLIB_MINOR=.*/SHLIB_MINOR=$shlib_minor/;
+	s/^SHLIB_EXT=.*/SHLIB_EXT=$shared_extension/;
+	s/^INSTALLTOP=.*$/INSTALLTOP=$prefix/;
+	s/^MULTILIB=.*$/MULTILIB=$multilib/;
+	s/^OPENSSLDIR=.*$/OPENSSLDIR=$openssldir/;
+	s/^LIBDIR=.*$/LIBDIR=$libdir/;
+	s/^INSTALL_PREFIX=.*$/INSTALL_PREFIX=$install_prefix/;
+	s/^PLATFORM=.*$/PLATFORM=$target/;
+	s/^OPTIONS=.*$/OPTIONS=$options/;
+	s/^CONFIGURE_ARGS=.*$/CONFIGURE_ARGS=$argvstring/;
+	if ($cross_compile_prefix)
+		{
+		s/^CC=.*$/CROSS_COMPILE= $cross_compile_prefix\nCC= \$\(CROSS_COMPILE\)$cc/;
+		s/^AR=\s*/AR= \$\(CROSS_COMPILE\)/;
+		s/^NM=\s*/NM= \$\(CROSS_COMPILE\)/;
+		s/^RANLIB=\s*/RANLIB= \$\(CROSS_COMPILE\)/;
+		s/^MAKEDEPPROG=.*$/MAKEDEPPROG= \$\(CROSS_COMPILE\)$cc/ if $cc eq "gcc";
+		}
+	else	{
+		s/^CC=.*$/CC= $cc/;
+		s/^AR=\s*ar/AR= $ar/;
+		s/^RANLIB=.*/RANLIB= $ranlib/;
+		s/^MAKEDEPPROG=.*$/MAKEDEPPROG= $cc/ if $cc eq "gcc";
+		}
+	s/^CFLAG=.*$/CFLAG= $cflags/;
+	s/^DEPFLAG=.*$/DEPFLAG=$depflags/;
+	s/^PEX_LIBS=.*$/PEX_LIBS= $prelflags/;
+	s/^EX_LIBS=.*$/EX_LIBS= $lflags/;
+	s/^EXE_EXT=.*$/EXE_EXT= $exe_ext/;
+	s/^CPUID_OBJ=.*$/CPUID_OBJ= $cpuid_obj/;
+	s/^BN_ASM=.*$/BN_ASM= $bn_obj/;
+	s/^DES_ENC=.*$/DES_ENC= $des_obj/;
+	s/^AES_ENC=.*$/AES_ENC= $aes_obj/;
+	s/^BF_ENC=.*$/BF_ENC= $bf_obj/;
+	s/^CAST_ENC=.*$/CAST_ENC= $cast_obj/;
+	s/^RC4_ENC=.*$/RC4_ENC= $rc4_obj/;
+	s/^RC5_ENC=.*$/RC5_ENC= $rc5_obj/;
+	s/^MD5_ASM_OBJ=.*$/MD5_ASM_OBJ= $md5_obj/;
+	s/^SHA1_ASM_OBJ=.*$/SHA1_ASM_OBJ= $sha1_obj/;
+	s/^RMD160_ASM_OBJ=.*$/RMD160_ASM_OBJ= $rmd160_obj/;
+	s/^WP_ASM_OBJ=.*$/WP_ASM_OBJ= $wp_obj/;
+	s/^CMLL_ENC=.*$/CMLL_ENC= $cmll_obj/;
+	s/^PERLASM_SCHEME=.*$/PERLASM_SCHEME= $perlasm_scheme/;
+	s/^PROCESSOR=.*/PROCESSOR= $processor/;
+	s/^ARFLAGS=.*/ARFLAGS= $arflags/;
+	s/^PERL=.*/PERL= $perl/;
+	s/^KRB5_INCLUDES=.*/KRB5_INCLUDES=$withargs{"krb5-include"}/;
+	s/^LIBKRB5=.*/LIBKRB5=$withargs{"krb5-lib"}/;
+	s/^LIBZLIB=.*/LIBZLIB=$withargs{"zlib-lib"}/;
+	s/^ZLIB_INCLUDE=.*/ZLIB_INCLUDE=$withargs{"zlib-include"}/;
+	s/^SHLIB_TARGET=.*/SHLIB_TARGET=$shared_target/;
+	s/^SHLIB_MARK=.*/SHLIB_MARK=$shared_mark/;
+	s/^SHARED_LIBS=.*/SHARED_LIBS=\$(SHARED_CRYPTO) \$(SHARED_SSL)/ if (!$no_shared);
+	if ($shared_extension ne "" && $shared_extension =~ /^\.s([ol])\.[^\.]*$/)
+		{
+		my $sotmp = $1;
+		s/^SHARED_LIBS_LINK_EXTS=.*/SHARED_LIBS_LINK_EXTS=.s$sotmp/;
+		}
+	elsif ($shared_extension ne "" && $shared_extension =~ /^\.[^\.]*\.dylib$/)
+		{
+		s/^SHARED_LIBS_LINK_EXTS=.*/SHARED_LIBS_LINK_EXTS=.dylib/;
+		}
+	elsif ($shared_extension ne "" && $shared_extension =~ /^\.s([ol])\.[^\.]*\.[^\.]*$/)
+		{
+		my $sotmp = $1;
+		s/^SHARED_LIBS_LINK_EXTS=.*/SHARED_LIBS_LINK_EXTS=.s$sotmp.\$(SHLIB_MAJOR) .s$sotmp/;
+		}
+	elsif ($shared_extension ne "" && $shared_extension =~ /^\.[^\.]*\.[^\.]*\.dylib$/)
+		{
+		s/^SHARED_LIBS_LINK_EXTS=.*/SHARED_LIBS_LINK_EXTS=.\$(SHLIB_MAJOR).dylib .dylib/;
+		}
+	s/^SHARED_LDFLAGS=.*/SHARED_LDFLAGS=$shared_ldflag/;
+	print OUT $_."\n";
+	}
+close(IN);
+close(OUT);
+rename($Makefile,"$Makefile.bak") || die "unable to rename $Makefile\n" if -e $Makefile;
+rename("$Makefile.new",$Makefile) || die "unable to rename $Makefile.new\n";
+
+print "CC            =$cc\n";
+print "CFLAG         =$cflags\n";
+print "EX_LIBS       =$lflags\n";
+print "CPUID_OBJ     =$cpuid_obj\n";
+print "BN_ASM        =$bn_obj\n";
+print "DES_ENC       =$des_obj\n";
+print "AES_ENC       =$aes_obj\n";
+print "BF_ENC        =$bf_obj\n";
+print "CAST_ENC      =$cast_obj\n";
+print "RC4_ENC       =$rc4_obj\n";
+print "RC5_ENC       =$rc5_obj\n";
+print "MD5_OBJ_ASM   =$md5_obj\n";
+print "SHA1_OBJ_ASM  =$sha1_obj\n";
+print "RMD160_OBJ_ASM=$rmd160_obj\n";
+print "CMLL_ENC=     =$cmll_obj\n";
+print "PROCESSOR     =$processor\n";
+print "RANLIB        =$ranlib\n";
+print "ARFLAGS       =$arflags\n";
+print "PERL          =$perl\n";
+print "KRB5_INCLUDES =",$withargs{"krb5-include"},"\n"
+	if $withargs{"krb5-include"} ne "";
+
+my $des_ptr=0;
+my $des_risc1=0;
+my $des_risc2=0;
+my $des_unroll=0;
+my $bn_ll=0;
+my $def_int=2;
+my $rc4_int=$def_int;
+my $md2_int=$def_int;
+my $idea_int=$def_int;
+my $rc2_int=$def_int;
+my $rc4_idx=0;
+my $rc4_chunk=0;
+my $bf_ptr=0;
+my @type=("char","short","int","long");
+my ($b64l,$b64,$b32,$b16,$b8)=(0,0,1,0,0);
+my $export_var_as_fn=0;
+
+my $des_int;
+
+foreach (sort split(/\s+/,$bn_ops))
+	{
+	$des_ptr=1 if /DES_PTR/;
+	$des_risc1=1 if /DES_RISC1/;
+	$des_risc2=1 if /DES_RISC2/;
+	$des_unroll=1 if /DES_UNROLL/;
+	$des_int=1 if /DES_INT/;
+	$bn_ll=1 if /BN_LLONG/;
+	$rc4_int=0 if /RC4_CHAR/;
+	$rc4_int=3 if /RC4_LONG/;
+	$rc4_idx=1 if /RC4_INDEX/;
+	$rc4_chunk=1 if /RC4_CHUNK/;
+	$rc4_chunk=2 if /RC4_CHUNK_LL/;
+	$md2_int=0 if /MD2_CHAR/;
+	$md2_int=3 if /MD2_LONG/;
+	$idea_int=1 if /IDEA_SHORT/;
+	$idea_int=3 if /IDEA_LONG/;
+	$rc2_int=1 if /RC2_SHORT/;
+	$rc2_int=3 if /RC2_LONG/;
+	$bf_ptr=1 if $_ eq "BF_PTR";
+	$bf_ptr=2 if $_ eq "BF_PTR2";
+	($b64l,$b64,$b32,$b16,$b8)=(0,1,0,0,0) if /SIXTY_FOUR_BIT/;
+	($b64l,$b64,$b32,$b16,$b8)=(1,0,0,0,0) if /SIXTY_FOUR_BIT_LONG/;
+	($b64l,$b64,$b32,$b16,$b8)=(0,0,1,0,0) if /THIRTY_TWO_BIT/;
+	($b64l,$b64,$b32,$b16,$b8)=(0,0,0,1,0) if /SIXTEEN_BIT/;
+	($b64l,$b64,$b32,$b16,$b8)=(0,0,0,0,1) if /EIGHT_BIT/;
+	$export_var_as_fn=1 if /EXPORT_VAR_AS_FN/;
+	}
+
+open(IN,'<crypto/opensslconf.h.in') || die "unable to read crypto/opensslconf.h.in:$!\n";
+unlink("crypto/opensslconf.h.new") || die "unable to remove old crypto/opensslconf.h.new:$!\n" if -e "crypto/opensslconf.h.new";
+open(OUT,'>crypto/opensslconf.h.new') || die "unable to create crypto/opensslconf.h.new:$!\n";
+print OUT "/* opensslconf.h */\n";
+print OUT "/* WARNING: Generated automatically from opensslconf.h.in by Configure. */\n\n";
+
+print OUT "/* OpenSSL was configured with the following options: */\n";
+my $openssl_algorithm_defines_trans = $openssl_algorithm_defines;
+$openssl_experimental_defines =~ s/^\s*#\s*define\s+OPENSSL_NO_(.*)/#ifndef OPENSSL_EXPERIMENTAL_$1\n# ifndef OPENSSL_NO_$1\n#  define OPENSSL_NO_$1\n# endif\n#endif/mg;
+$openssl_algorithm_defines_trans =~ s/^\s*#\s*define\s+OPENSSL_(.*)/# if defined(OPENSSL_$1) \&\& !defined($1)\n#  define $1\n# endif/mg;
+$openssl_algorithm_defines =~ s/^\s*#\s*define\s+(.*)/#ifndef $1\n# define $1\n#endif/mg;
+$openssl_algorithm_defines = "   /* no ciphers excluded */\n" if $openssl_algorithm_defines eq "";
+$openssl_thread_defines =~ s/^\s*#\s*define\s+(.*)/#ifndef $1\n# define $1\n#endif/mg;
+$openssl_sys_defines =~ s/^\s*#\s*define\s+(.*)/#ifndef $1\n# define $1\n#endif/mg;
+$openssl_other_defines =~ s/^\s*#\s*define\s+(.*)/#ifndef $1\n# define $1\n#endif/mg;
+print OUT $openssl_sys_defines;
+print OUT "#ifndef OPENSSL_DOING_MAKEDEPEND\n\n";
+print OUT $openssl_experimental_defines;
+print OUT "\n";
+print OUT $openssl_algorithm_defines;
+print OUT "\n#endif /* OPENSSL_DOING_MAKEDEPEND */\n\n";
+print OUT $openssl_thread_defines;
+print OUT $openssl_other_defines,"\n";
+
+print OUT "/* The OPENSSL_NO_* macros are also defined as NO_* if the application\n";
+print OUT "   asks for it.  This is a transient feature that is provided for those\n";
+print OUT "   who haven't had the time to do the appropriate changes in their\n";
+print OUT "   applications.  */\n";
+print OUT "#ifdef OPENSSL_ALGORITHM_DEFINES\n";
+print OUT $openssl_algorithm_defines_trans;
+print OUT "#endif\n\n";
+
+print OUT "#define OPENSSL_CPUID_OBJ\n\n" if ($cpuid_obj ne "mem_clr.o");
+
+while (<IN>)
+	{
+	if	(/^#define\s+OPENSSLDIR/)
+		{
+		my $foo = $openssldir;
+		$foo =~ s/\\/\\\\/g;
+		print OUT "#define OPENSSLDIR \"$foo\"\n";
+		}
+	elsif	(/^#define\s+ENGINESDIR/)
+		{
+		my $foo = "$prefix/$libdir/engines";
+		$foo =~ s/\\/\\\\/g;
+		print OUT "#define ENGINESDIR \"$foo\"\n";
+		}
+	elsif	(/^#((define)|(undef))\s+OPENSSL_EXPORT_VAR_AS_FUNCTION/)
+		{ printf OUT "#undef OPENSSL_EXPORT_VAR_AS_FUNCTION\n"
+			if $export_var_as_fn;
+		  printf OUT "#%s OPENSSL_EXPORT_VAR_AS_FUNCTION\n",
+			($export_var_as_fn)?"define":"undef"; }
+	elsif	(/^#define\s+OPENSSL_UNISTD/)
+		{
+		$unistd = "<unistd.h>" if $unistd eq "";
+		print OUT "#define OPENSSL_UNISTD $unistd\n";
+		}
+	elsif	(/^#((define)|(undef))\s+SIXTY_FOUR_BIT_LONG/)
+		{ printf OUT "#%s SIXTY_FOUR_BIT_LONG\n",($b64l)?"define":"undef"; }
+	elsif	(/^#((define)|(undef))\s+SIXTY_FOUR_BIT/)
+		{ printf OUT "#%s SIXTY_FOUR_BIT\n",($b64)?"define":"undef"; }
+	elsif	(/^#((define)|(undef))\s+THIRTY_TWO_BIT/)
+		{ printf OUT "#%s THIRTY_TWO_BIT\n",($b32)?"define":"undef"; }
+	elsif	(/^#((define)|(undef))\s+SIXTEEN_BIT/)
+		{ printf OUT "#%s SIXTEEN_BIT\n",($b16)?"define":"undef"; }
+	elsif	(/^#((define)|(undef))\s+EIGHT_BIT/)
+		{ printf OUT "#%s EIGHT_BIT\n",($b8)?"define":"undef"; }
+	elsif	(/^#((define)|(undef))\s+BN_LLONG\s*$/)
+		{ printf OUT "#%s BN_LLONG\n",($bn_ll)?"define":"undef"; }
+	elsif	(/^\#define\s+DES_LONG\s+.*/)
+		{ printf OUT "#define DES_LONG unsigned %s\n",
+			($des_int)?'int':'long'; }
+	elsif	(/^\#(define|undef)\s+DES_PTR/)
+		{ printf OUT "#%s DES_PTR\n",($des_ptr)?'define':'undef'; }
+	elsif	(/^\#(define|undef)\s+DES_RISC1/)
+		{ printf OUT "#%s DES_RISC1\n",($des_risc1)?'define':'undef'; }
+	elsif	(/^\#(define|undef)\s+DES_RISC2/)
+		{ printf OUT "#%s DES_RISC2\n",($des_risc2)?'define':'undef'; }
+	elsif	(/^\#(define|undef)\s+DES_UNROLL/)
+		{ printf OUT "#%s DES_UNROLL\n",($des_unroll)?'define':'undef'; }
+	elsif	(/^#define\s+RC4_INT\s/)
+		{ printf OUT "#define RC4_INT unsigned %s\n",$type[$rc4_int]; }
+	elsif	(/^#undef\s+RC4_CHUNK/)
+		{
+		printf OUT "#undef RC4_CHUNK\n" if $rc4_chunk==0;
+		printf OUT "#define RC4_CHUNK unsigned long\n" if $rc4_chunk==1;
+		printf OUT "#define RC4_CHUNK unsigned long long\n" if $rc4_chunk==2;
+		}
+	elsif	(/^#((define)|(undef))\s+RC4_INDEX/)
+		{ printf OUT "#%s RC4_INDEX\n",($rc4_idx)?"define":"undef"; }
+	elsif (/^#(define|undef)\s+I386_ONLY/)
+		{ printf OUT "#%s I386_ONLY\n", ($processor eq "386")?
+			"define":"undef"; }
+	elsif	(/^#define\s+MD2_INT\s/)
+		{ printf OUT "#define MD2_INT unsigned %s\n",$type[$md2_int]; }
+	elsif	(/^#define\s+IDEA_INT\s/)
+		{printf OUT "#define IDEA_INT unsigned %s\n",$type[$idea_int];}
+	elsif	(/^#define\s+RC2_INT\s/)
+		{printf OUT "#define RC2_INT unsigned %s\n",$type[$rc2_int];}
+	elsif (/^#(define|undef)\s+BF_PTR/)
+		{
+		printf OUT "#undef BF_PTR\n" if $bf_ptr == 0;
+		printf OUT "#define BF_PTR\n" if $bf_ptr == 1;
+		printf OUT "#define BF_PTR2\n" if $bf_ptr == 2;
+	        }
+	else
+		{ print OUT $_; }
+	}
+close(IN);
+close(OUT);
+rename("crypto/opensslconf.h","crypto/opensslconf.h.bak") || die "unable to rename crypto/opensslconf.h\n" if -e "crypto/opensslconf.h";
+rename("crypto/opensslconf.h.new","crypto/opensslconf.h") || die "unable to rename crypto/opensslconf.h.new\n";
+
+
+# Fix the date
+
+print "SIXTY_FOUR_BIT_LONG mode\n" if $b64l;
+print "SIXTY_FOUR_BIT mode\n" if $b64;
+print "THIRTY_TWO_BIT mode\n" if $b32;
+print "SIXTEEN_BIT mode\n" if $b16;
+print "EIGHT_BIT mode\n" if $b8;
+print "DES_PTR used\n" if $des_ptr;
+print "DES_RISC1 used\n" if $des_risc1;
+print "DES_RISC2 used\n" if $des_risc2;
+print "DES_UNROLL used\n" if $des_unroll;
+print "DES_INT used\n" if $des_int;
+print "BN_LLONG mode\n" if $bn_ll;
+print "RC4 uses u$type[$rc4_int]\n" if $rc4_int != $def_int;
+print "RC4_INDEX mode\n" if $rc4_idx;
+print "RC4_CHUNK is undefined\n" if $rc4_chunk==0;
+print "RC4_CHUNK is unsigned long\n" if $rc4_chunk==1;
+print "RC4_CHUNK is unsigned long long\n" if $rc4_chunk==2;
+print "MD2 uses u$type[$md2_int]\n" if $md2_int != $def_int;
+print "IDEA uses u$type[$idea_int]\n" if $idea_int != $def_int;
+print "RC2 uses u$type[$rc2_int]\n" if $rc2_int != $def_int;
+print "BF_PTR used\n" if $bf_ptr == 1; 
+print "BF_PTR2 used\n" if $bf_ptr == 2; 
+
+if($IsMK1MF) {
+	open (OUT,">crypto/buildinf.h") || die "Can't open buildinf.h";
+	printf OUT <<EOF;
+#ifndef MK1MF_BUILD
+  /* auto-generated by Configure for crypto/cversion.c:
+   * for Unix builds, crypto/Makefile.ssl generates functional definitions;
+   * Windows builds (and other mk1mf builds) compile cversion.c with
+   * -DMK1MF_BUILD and use definitions added to this file by util/mk1mf.pl. */
+  #error "Windows builds (PLATFORM=$target) use mk1mf.pl-created Makefiles"
+#endif
+EOF
+	close(OUT);
+} else {
+	my $make_command = "$make PERL=\'$perl\'";
+	my $make_targets = "";
+	$make_targets .= " links" if $symlink;
+	$make_targets .= " depend" if $depflags ne $default_depflags && $make_depend;
+	$make_targets .= " gentests" if $symlink;
+	(system $make_command.$make_targets) == 0 or exit $?
+		if $make_targets ne "";
+	if ( $perl =~ m@^/@) {
+	    &dofile("tools/c_rehash",$perl,'^#!/', '#!%s','^my \$dir;$', 'my $dir = "' . $openssldir . '";', '^my \$prefix;$', 'my $prefix = "' . $prefix . '";');
+	    &dofile("apps/CA.pl",$perl,'^#!/', '#!%s');
+	} else {
+	    # No path for Perl known ...
+	    &dofile("tools/c_rehash",'/usr/local/bin/perl','^#!/', '#!%s','^my \$dir;$', 'my $dir = "' . $openssldir . '";',  '^my \$prefix;$', 'my $prefix = "' . $prefix . '";');
+	    &dofile("apps/CA.pl",'/usr/local/bin/perl','^#!/', '#!%s');
+	}
+	if ($depflags ne $default_depflags && !$make_depend) {
+		print <<EOF;
+
+Since you've disabled or enabled at least one algorithm, you need to do
+the following before building:
+
+	make depend
+EOF
+	}
+}
+
+# create the ms/version32.rc file if needed
+if ($IsMK1MF && ($target !~ /^netware/)) {
+	my ($v1, $v2, $v3, $v4);
+	if ($version_num =~ /(^[0-9a-f]{1})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/i) {
+		$v1=hex $1;
+		$v2=hex $2;
+		$v3=hex $3;
+		$v4=hex $4;
+	}
+	open (OUT,">ms/version32.rc") || die "Can't open ms/version32.rc";
+	print OUT <<EOF;
+#include <winver.h>
+
+LANGUAGE 0x09,0x01
+
+1 VERSIONINFO
+  FILEVERSION $v1,$v2,$v3,$v4
+  PRODUCTVERSION $v1,$v2,$v3,$v4
+  FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+  FILEFLAGS 0x01L
+#else
+  FILEFLAGS 0x00L
+#endif
+  FILEOS VOS__WINDOWS32
+  FILETYPE VFT_DLL
+  FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+	BLOCK "040904b0"
+	BEGIN
+	    // Required:	    
+	    VALUE "CompanyName", "The OpenSSL Project, http://www.openssl.org/\\0"
+	    VALUE "FileDescription", "OpenSSL Shared Library\\0"
+	    VALUE "FileVersion", "$version\\0"
+#if defined(CRYPTO)
+	    VALUE "InternalName", "libeay32\\0"
+	    VALUE "OriginalFilename", "libeay32.dll\\0"
+#elif defined(SSL)
+	    VALUE "InternalName", "ssleay32\\0"
+	    VALUE "OriginalFilename", "ssleay32.dll\\0"
+#endif
+	    VALUE "ProductName", "The OpenSSL Toolkit\\0"
+	    VALUE "ProductVersion", "$version\\0"
+	    // Optional:
+	    //VALUE "Comments", "\\0"
+	    VALUE "LegalCopyright", "Copyright © 1998-2005 The OpenSSL Project. Copyright © 1995-1998 Eric A. Young, Tim J. Hudson. All rights reserved.\\0"
+	    //VALUE "LegalTrademarks", "\\0"
+	    //VALUE "PrivateBuild", "\\0"
+	    //VALUE "SpecialBuild", "\\0"
+	END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 0x4b0
+    END
+END
+EOF
+	close(OUT);
+  }
+  
+print <<EOF;
+
+Configured for $target.
+EOF
+
+print <<\EOF if (!$no_threads && !$threads);
+
+The library could not be configured for supporting multi-threaded
+applications as the compiler options required on this system are not known.
+See file INSTALL for details if you need multi-threading.
+EOF
+
+print <<\EOF if ($no_shared_warn);
+
+You gave the option 'shared'.  Normally, that would give you shared libraries.
+Unfortunately, the OpenSSL configuration doesn't include shared library support
+for this platform yet, so it will pretend you gave the option 'no-shared'.  If
+you can inform the developpers (openssl-dev\@openssl.org) how to support shared
+libraries on this platform, they will at least look at it and try their best
+(but please first make sure you have tried with a current version of OpenSSL).
+EOF
+
+exit(0);
+
+sub usage
+	{
+	print STDERR $usage;
+	print STDERR "\npick os/compiler from:\n";
+	my $j=0;
+	my $i;
+        my $k=0;
+	foreach $i (sort keys %table)
+		{
+		next if $i =~ /^debug/;
+		$k += length($i) + 1;
+		if ($k > 78)
+			{
+			print STDERR "\n";
+			$k=length($i);
+			}
+		print STDERR $i . " ";
+		}
+	foreach $i (sort keys %table)
+		{
+		next if $i !~ /^debug/;
+		$k += length($i) + 1;
+		if ($k > 78)
+			{
+			print STDERR "\n";
+			$k=length($i);
+			}
+		print STDERR $i . " ";
+		}
+	print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
+	exit(1);
+	}
+
+sub which
+	{
+	my($name)=@_;
+	my $path;
+	foreach $path (split /:/, $ENV{PATH})
+		{
+		if (-f "$path/$name$exe_ext" and -x _)
+			{
+			return "$path/$name$exe_ext" unless ($name eq "perl" and
+			 system("$path/$name$exe_ext -e " . '\'exit($]<5.0);\''));
+			}
+		}
+	}
+
+sub dofile
+	{
+	my $f; my $p; my %m; my @a; my $k; my $ff;
+	($f,$p,%m)=@_;
+
+	open(IN,"<$f.in") || open(IN,"<$f") || die "unable to open $f:$!\n";
+	@a=<IN>;
+	close(IN);
+	foreach $k (keys %m)
+		{
+		grep(/$k/ && ($_=sprintf($m{$k}."\n",$p)),@a);
+		}
+	open(OUT,">$f.new") || die "unable to open $f.new:$!\n";
+	print OUT @a;
+	close(OUT);
+	rename($f,"$f.bak") || die "unable to rename $f\n" if -e $f;
+	rename("$f.new",$f) || die "unable to rename $f.new\n";
+	}
+
+sub print_table_entry
+	{
+	my $target = shift;
+
+	(my $cc,my $cflags,my $unistd,my $thread_cflag,my $sys_id,my $lflags,
+	my $bn_ops,my $cpuid_obj,my $bn_obj,my $des_obj,my $aes_obj, my $bf_obj,
+	my $md5_obj,my $sha1_obj,my $cast_obj,my $rc4_obj,my $rmd160_obj,
+	my $rc5_obj,my $wp_obj,my $cmll_obj,my $perlasm_scheme,my $dso_scheme,my $shared_target,my $shared_cflag,
+	my $shared_ldflag,my $shared_extension,my $ranlib,my $arflags,my $multilib)=
+	split(/\s*:\s*/,$table{$target} . ":" x 30 , -1);
+			
+	print <<EOF
+
+*** $target
+\$cc           = $cc
+\$cflags       = $cflags
+\$unistd       = $unistd
+\$thread_cflag = $thread_cflag
+\$sys_id       = $sys_id
+\$lflags       = $lflags
+\$bn_ops       = $bn_ops
+\$cpuid_obj    = $cpuid_obj
+\$bn_obj       = $bn_obj
+\$des_obj      = $des_obj
+\$aes_obj      = $aes_obj
+\$bf_obj       = $bf_obj
+\$md5_obj      = $md5_obj
+\$sha1_obj     = $sha1_obj
+\$cast_obj     = $cast_obj
+\$rc4_obj      = $rc4_obj
+\$rmd160_obj   = $rmd160_obj
+\$rc5_obj      = $rc5_obj
+\$wp_obj       = $wp_obj
+\$cmll_obj     = $cmll_obj
+\$perlasm_scheme = $perlasm_scheme
+\$dso_scheme   = $dso_scheme
+\$shared_target= $shared_target
+\$shared_cflag = $shared_cflag
+\$shared_ldflag = $shared_ldflag
+\$shared_extension = $shared_extension
+\$ranlib       = $ranlib
+\$arflags      = $arflags
+\$multilib     = $multilib
+EOF
+	}
+
+sub test_sanity
+	{
+	my $errorcnt = 0;
+
+	print STDERR "=" x 70, "\n";
+	print STDERR "=== SANITY TESTING!\n";
+	print STDERR "=== No configuration will be done, all other arguments will be ignored!\n";
+	print STDERR "=" x 70, "\n";
+
+	foreach $target (sort keys %table)
+		{
+		@fields = split(/\s*:\s*/,$table{$target} . ":" x 30 , -1);
+
+		if ($fields[$idx_dso_scheme-1] =~ /^(beos|dl|dlfcn|win32|vms)$/)
+			{
+			$errorcnt++;
+			print STDERR "SANITY ERROR: '$target' has the dso_scheme [$idx_dso_scheme] values\n";
+			print STDERR "              in the previous field\n";
+			}
+		elsif ($fields[$idx_dso_scheme+1] =~ /^(beos|dl|dlfcn|win32|vms)$/)
+			{
+			$errorcnt++;
+			print STDERR "SANITY ERROR: '$target' has the dso_scheme [$idx_dso_scheme] values\n";
+			print STDERR "              in the following field\n";
+			}
+		elsif ($fields[$idx_dso_scheme] !~ /^(beos|dl|dlfcn|win32|vms|)$/)
+			{
+			$errorcnt++;
+			print STDERR "SANITY ERROR: '$target' has the dso_scheme [$idx_dso_scheme] field = ",$fields[$idx_dso_scheme],"\n";
+			print STDERR "              valid values are 'beos', 'dl', 'dlfcn', 'win32' and 'vms'\n";
+			}
+		}
+	print STDERR "No sanity errors detected!\n" if $errorcnt == 0;
+	return $errorcnt;
+	}
diff --git a/openssl/FAQ b/openssl/FAQ
new file mode 100644
index 0000000..3b07cd3
--- /dev/null
+++ b/openssl/FAQ
@@ -0,0 +1,1025 @@
+OpenSSL  -  Frequently Asked Questions
+--------------------------------------
+
+[MISC] Miscellaneous questions
+
+* Which is the current version of OpenSSL?
+* Where is the documentation?
+* How can I contact the OpenSSL developers?
+* Where can I get a compiled version of OpenSSL?
+* Why aren't tools like 'autoconf' and 'libtool' used?
+* What is an 'engine' version?
+* How do I check the authenticity of the OpenSSL distribution?
+
+[LEGAL] Legal questions
+
+* Do I need patent licenses to use OpenSSL?
+* Can I use OpenSSL with GPL software? 
+
+[USER] Questions on using the OpenSSL applications
+
+* Why do I get a "PRNG not seeded" error message?
+* Why do I get an "unable to write 'random state'" error message?
+* How do I create certificates or certificate requests?
+* Why can't I create certificate requests?
+* Why does <SSL program> fail with a certificate verify error?
+* Why can I only use weak ciphers when I connect to a server using OpenSSL?
+* How can I create DSA certificates?
+* Why can't I make an SSL connection using a DSA certificate?
+* How can I remove the passphrase on a private key?
+* Why can't I use OpenSSL certificates with SSL client authentication?
+* Why does my browser give a warning about a mismatched hostname?
+* How do I install a CA certificate into a browser?
+* Why is OpenSSL x509 DN output not conformant to RFC2253?
+* What is a "128 bit certificate"? Can I create one with OpenSSL?
+* Why does OpenSSL set the authority key identifier extension incorrectly?
+* How can I set up a bundle of commercial root CA certificates?
+
+[BUILD] Questions about building and testing OpenSSL
+
+* Why does the linker complain about undefined symbols?
+* Why does the OpenSSL test fail with "bc: command not found"?
+* Why does the OpenSSL test fail with "bc: 1 no implemented"?
+* Why does the OpenSSL test fail with "bc: stack empty"?
+* Why does the OpenSSL compilation fail on Alpha Tru64 Unix?
+* Why does the OpenSSL compilation fail with "ar: command not found"?
+* Why does the OpenSSL compilation fail on Win32 with VC++?
+* What is special about OpenSSL on Redhat?
+* Why does the OpenSSL compilation fail on MacOS X?
+* Why does the OpenSSL test suite fail on MacOS X?
+* Why does the OpenSSL test suite fail in BN_sqr test [on a 64-bit platform]?
+* Why does OpenBSD-i386 build fail on des-586.s with "Unimplemented segment type"?
+* Why does the OpenSSL test suite fail in sha512t on x86 CPU?
+* Why does compiler fail to compile sha512.c?
+* Test suite still fails, what to do?
+* I think I've found a bug, what should I do?
+* I'm SURE I've found a bug, how do I report it?
+* I've found a security issue, how do I report it?
+
+[PROG] Questions about programming with OpenSSL
+
+* Is OpenSSL thread-safe?
+* I've compiled a program under Windows and it crashes: why?
+* How do I read or write a DER encoded buffer using the ASN1 functions?
+* OpenSSL uses DER but I need BER format: does OpenSSL support BER?
+* I've tried using <M_some_evil_pkcs12_macro> and I get errors why?
+* I've called <some function> and it fails, why?
+* I just get a load of numbers for the error output, what do they mean?
+* Why do I get errors about unknown algorithms?
+* Why can't the OpenSSH configure script detect OpenSSL?
+* Can I use OpenSSL's SSL library with non-blocking I/O?
+* Why doesn't my server application receive a client certificate?
+* Why does compilation fail due to an undefined symbol NID_uniqueIdentifier?
+* I think I've detected a memory leak, is this a bug?
+* Why does Valgrind complain about the use of uninitialized data?
+* Why doesn't a memory BIO work when a file does?
+* Where are the declarations and implementations of d2i_X509() etc?
+
+===============================================================================
+
+[MISC] ========================================================================
+
+* Which is the current version of OpenSSL?
+
+The current version is available from <URL: http://www.openssl.org>.
+OpenSSL 1.0.0f was released on Jan 4th, 2012.
+
+In addition to the current stable release, you can also access daily
+snapshots of the OpenSSL development version at <URL:
+ftp://ftp.openssl.org/snapshot/>, or get it by anonymous CVS access.
+
+
+* Where is the documentation?
+
+OpenSSL is a library that provides cryptographic functionality to
+applications such as secure web servers.  Be sure to read the
+documentation of the application you want to use.  The INSTALL file
+explains how to install this library.
+
+OpenSSL includes a command line utility that can be used to perform a
+variety of cryptographic functions.  It is described in the openssl(1)
+manpage.  Documentation for developers is currently being written. Many
+manual pages are available; overviews over libcrypto and
+libssl are given in the crypto(3) and ssl(3) manpages.
+
+The OpenSSL manpages are installed in /usr/local/ssl/man/ (or a
+different directory if you specified one as described in INSTALL).
+In addition, you can read the most current versions at
+<URL: http://www.openssl.org/docs/>. Note that the online documents refer
+to the very latest development versions of OpenSSL and may include features
+not present in released versions. If in doubt refer to the documentation
+that came with the version of OpenSSL you are using.
+
+For information on parts of libcrypto that are not yet documented, you
+might want to read Ariel Glenn's documentation on SSLeay 0.9, OpenSSL's
+predecessor, at <URL: http://www.columbia.edu/~ariel/ssleay/>.  Much
+of this still applies to OpenSSL.
+
+There is some documentation about certificate extensions and PKCS#12
+in doc/openssl.txt
+
+The original SSLeay documentation is included in OpenSSL as
+doc/ssleay.txt.  It may be useful when none of the other resources
+help, but please note that it reflects the obsolete version SSLeay
+0.6.6.
+
+
+* How can I contact the OpenSSL developers?
+
+The README file describes how to submit bug reports and patches to
+OpenSSL.  Information on the OpenSSL mailing lists is available from
+<URL: http://www.openssl.org>.
+
+
+* Where can I get a compiled version of OpenSSL?
+
+You can finder pointers to binary distributions in
+<URL: http://www.openssl.org/related/binaries.html> .
+
+Some applications that use OpenSSL are distributed in binary form.
+When using such an application, you don't need to install OpenSSL
+yourself; the application will include the required parts (e.g. DLLs).
+
+If you want to build OpenSSL on a Windows system and you don't have
+a C compiler, read the "Mingw32" section of INSTALL.W32 for information
+on how to obtain and install the free GNU C compiler.
+
+A number of Linux and *BSD distributions include OpenSSL.
+
+
+* Why aren't tools like 'autoconf' and 'libtool' used?
+
+autoconf will probably be used in future OpenSSL versions. If it was
+less Unix-centric, it might have been used much earlier.
+
+* What is an 'engine' version?
+
+With version 0.9.6 OpenSSL was extended to interface to external crypto
+hardware. This was realized in a special release '0.9.6-engine'. With
+version 0.9.7 the changes were merged into the main development line,
+so that the special release is no longer necessary.
+
+* How do I check the authenticity of the OpenSSL distribution?
+
+We provide MD5 digests and ASC signatures of each tarball.
+Use MD5 to check that a tarball from a mirror site is identical:
+
+   md5sum TARBALL | awk '{print $1;}' | cmp - TARBALL.md5
+
+You can check authenticity using pgp or gpg. You need the OpenSSL team
+member public key used to sign it (download it from a key server, see a
+list of keys at <URL: http://www.openssl.org/about/>). Then
+just do:
+
+   pgp TARBALL.asc
+
+[LEGAL] =======================================================================
+
+* Do I need patent licenses to use OpenSSL?
+
+The patents section of the README file lists patents that may apply to
+you if you want to use OpenSSL.  For information on intellectual
+property rights, please consult a lawyer.  The OpenSSL team does not
+offer legal advice.
+
+You can configure OpenSSL so as not to use IDEA, MDC2 and RC5 by using
+ ./config no-idea no-mdc2 no-rc5
+
+
+* Can I use OpenSSL with GPL software?
+
+On many systems including the major Linux and BSD distributions, yes (the
+GPL does not place restrictions on using libraries that are part of the
+normal operating system distribution).
+
+On other systems, the situation is less clear. Some GPL software copyright
+holders claim that you infringe on their rights if you use OpenSSL with
+their software on operating systems that don't normally include OpenSSL.
+
+If you develop open source software that uses OpenSSL, you may find it
+useful to choose an other license than the GPL, or state explicitly that
+"This program is released under the GPL with the additional exemption that
+compiling, linking, and/or using OpenSSL is allowed."  If you are using
+GPL software developed by others, you may want to ask the copyright holder
+for permission to use their software with OpenSSL.
+
+
+[USER] ========================================================================
+
+* Why do I get a "PRNG not seeded" error message?
+
+Cryptographic software needs a source of unpredictable data to work
+correctly.  Many open source operating systems provide a "randomness
+device" (/dev/urandom or /dev/random) that serves this purpose.
+All OpenSSL versions try to use /dev/urandom by default; starting with
+version 0.9.7, OpenSSL also tries /dev/random if /dev/urandom is not
+available.
+
+On other systems, applications have to call the RAND_add() or
+RAND_seed() function with appropriate data before generating keys or
+performing public key encryption. (These functions initialize the
+pseudo-random number generator, PRNG.)  Some broken applications do
+not do this.  As of version 0.9.5, the OpenSSL functions that need
+randomness report an error if the random number generator has not been
+seeded with at least 128 bits of randomness.  If this error occurs and
+is not discussed in the documentation of the application you are
+using, please contact the author of that application; it is likely
+that it never worked correctly.  OpenSSL 0.9.5 and later make the
+error visible by refusing to perform potentially insecure encryption.
+
+If you are using Solaris 8, you can add /dev/urandom and /dev/random
+devices by installing patch 112438 (Sparc) or 112439 (x86), which are
+available via the Patchfinder at <URL: http://sunsolve.sun.com>
+(Solaris 9 includes these devices by default). For /dev/random support
+for earlier Solaris versions, see Sun's statement at
+<URL: http://sunsolve.sun.com/pub-cgi/retrieve.pl?doc=fsrdb/27606&zone_32=SUNWski>
+(the SUNWski package is available in patch 105710).
+
+On systems without /dev/urandom and /dev/random, it is a good idea to
+use the Entropy Gathering Demon (EGD); see the RAND_egd() manpage for
+details.  Starting with version 0.9.7, OpenSSL will automatically look
+for an EGD socket at /var/run/egd-pool, /dev/egd-pool, /etc/egd-pool and
+/etc/entropy.
+
+Most components of the openssl command line utility automatically try
+to seed the random number generator from a file.  The name of the
+default seeding file is determined as follows: If environment variable
+RANDFILE is set, then it names the seeding file.  Otherwise if
+environment variable HOME is set, then the seeding file is $HOME/.rnd.
+If neither RANDFILE nor HOME is set, versions up to OpenSSL 0.9.6 will
+use file .rnd in the current directory while OpenSSL 0.9.6a uses no
+default seeding file at all.  OpenSSL 0.9.6b and later will behave
+similarly to 0.9.6a, but will use a default of "C:\" for HOME on
+Windows systems if the environment variable has not been set.
+
+If the default seeding file does not exist or is too short, the "PRNG
+not seeded" error message may occur.
+
+The openssl command line utility will write back a new state to the
+default seeding file (and create this file if necessary) unless
+there was no sufficient seeding.
+
+Pointing $RANDFILE to an Entropy Gathering Daemon socket does not work.
+Use the "-rand" option of the OpenSSL command line tools instead.
+The $RANDFILE environment variable and $HOME/.rnd are only used by the
+OpenSSL command line tools. Applications using the OpenSSL library
+provide their own configuration options to specify the entropy source,
+please check out the documentation coming the with application.
+
+
+* Why do I get an "unable to write 'random state'" error message?
+
+
+Sometimes the openssl command line utility does not abort with
+a "PRNG not seeded" error message, but complains that it is
+"unable to write 'random state'".  This message refers to the
+default seeding file (see previous answer).  A possible reason
+is that no default filename is known because neither RANDFILE
+nor HOME is set.  (Versions up to 0.9.6 used file ".rnd" in the
+current directory in this case, but this has changed with 0.9.6a.)
+
+
+* How do I create certificates or certificate requests?
+
+Check out the CA.pl(1) manual page. This provides a simple wrapper round
+the 'req', 'verify', 'ca' and 'pkcs12' utilities. For finer control check
+out the manual pages for the individual utilities and the certificate
+extensions documentation (currently in doc/openssl.txt).
+
+
+* Why can't I create certificate requests?
+
+You typically get the error:
+
+	unable to find 'distinguished_name' in config
+	problems making Certificate Request
+
+This is because it can't find the configuration file. Check out the
+DIAGNOSTICS section of req(1) for more information.
+
+
+* Why does <SSL program> fail with a certificate verify error?
+
+This problem is usually indicated by log messages saying something like
+"unable to get local issuer certificate" or "self signed certificate".
+When a certificate is verified its root CA must be "trusted" by OpenSSL
+this typically means that the CA certificate must be placed in a directory
+or file and the relevant program configured to read it. The OpenSSL program
+'verify' behaves in a similar way and issues similar error messages: check
+the verify(1) program manual page for more information.
+
+
+* Why can I only use weak ciphers when I connect to a server using OpenSSL?
+
+This is almost certainly because you are using an old "export grade" browser
+which only supports weak encryption. Upgrade your browser to support 128 bit
+ciphers.
+
+
+* How can I create DSA certificates?
+
+Check the CA.pl(1) manual page for a DSA certificate example.
+
+
+* Why can't I make an SSL connection to a server using a DSA certificate?
+
+Typically you'll see a message saying there are no shared ciphers when
+the same setup works fine with an RSA certificate. There are two possible
+causes. The client may not support connections to DSA servers most web
+browsers (including Netscape and MSIE) only support connections to servers
+supporting RSA cipher suites. The other cause is that a set of DH parameters
+has not been supplied to the server. DH parameters can be created with the
+dhparam(1) command and loaded using the SSL_CTX_set_tmp_dh() for example:
+check the source to s_server in apps/s_server.c for an example.
+
+
+* How can I remove the passphrase on a private key?
+
+Firstly you should be really *really* sure you want to do this. Leaving
+a private key unencrypted is a major security risk. If you decide that
+you do have to do this check the EXAMPLES sections of the rsa(1) and
+dsa(1) manual pages.
+
+
+* Why can't I use OpenSSL certificates with SSL client authentication?
+
+What will typically happen is that when a server requests authentication
+it will either not include your certificate or tell you that you have
+no client certificates (Netscape) or present you with an empty list box
+(MSIE). The reason for this is that when a server requests a client
+certificate it includes a list of CAs names which it will accept. Browsers
+will only let you select certificates from the list on the grounds that
+there is little point presenting a certificate which the server will
+reject.
+
+The solution is to add the relevant CA certificate to your servers "trusted
+CA list". How you do this depends on the server software in uses. You can
+print out the servers list of acceptable CAs using the OpenSSL s_client tool:
+
+openssl s_client -connect www.some.host:443 -prexit
+
+If your server only requests certificates on certain URLs then you may need
+to manually issue an HTTP GET command to get the list when s_client connects:
+
+GET /some/page/needing/a/certificate.html
+
+If your CA does not appear in the list then this confirms the problem.
+
+
+* Why does my browser give a warning about a mismatched hostname?
+
+Browsers expect the server's hostname to match the value in the commonName
+(CN) field of the certificate. If it does not then you get a warning.
+
+
+* How do I install a CA certificate into a browser?
+
+The usual way is to send the DER encoded certificate to the browser as
+MIME type application/x-x509-ca-cert, for example by clicking on an appropriate
+link. On MSIE certain extensions such as .der or .cacert may also work, or you
+can import the certificate using the certificate import wizard.
+
+You can convert a certificate to DER form using the command:
+
+openssl x509 -in ca.pem -outform DER -out ca.der
+
+Occasionally someone suggests using a command such as:
+
+openssl pkcs12 -export -out cacert.p12 -in cacert.pem -inkey cakey.pem
+
+DO NOT DO THIS! This command will give away your CAs private key and
+reduces its security to zero: allowing anyone to forge certificates in
+whatever name they choose.
+
+* Why is OpenSSL x509 DN output not conformant to RFC2253?
+
+The ways to print out the oneline format of the DN (Distinguished Name) have
+been extended in version 0.9.7 of OpenSSL. Using the new X509_NAME_print_ex()
+interface, the "-nameopt" option could be introduded. See the manual
+page of the "openssl x509" commandline tool for details. The old behaviour
+has however been left as default for the sake of compatibility.
+
+* What is a "128 bit certificate"? Can I create one with OpenSSL?
+
+The term "128 bit certificate" is a highly misleading marketing term. It does
+*not* refer to the size of the public key in the certificate! A certificate
+containing a 128 bit RSA key would have negligible security.
+
+There were various other names such as "magic certificates", "SGC
+certificates", "step up certificates" etc.
+
+You can't generally create such a certificate using OpenSSL but there is no
+need to any more. Nowadays web browsers using unrestricted strong encryption
+are generally available.
+
+When there were tight restrictions on the export of strong encryption
+software from the US only weak encryption algorithms could be freely exported
+(initially 40 bit and then 56 bit). It was widely recognised that this was
+inadequate. A relaxation of the rules allowed the use of strong encryption but
+only to an authorised server.
+
+Two slighly different techniques were developed to support this, one used by
+Netscape was called "step up", the other used by MSIE was called "Server Gated
+Cryptography" (SGC). When a browser initially connected to a server it would
+check to see if the certificate contained certain extensions and was issued by
+an authorised authority. If these test succeeded it would reconnect using
+strong encryption.
+
+Only certain (initially one) certificate authorities could issue the
+certificates and they generally cost more than ordinary certificates.
+
+Although OpenSSL can create certificates containing the appropriate extensions
+the certificate would not come from a permitted authority and so would not
+be recognized.
+
+The export laws were later changed to allow almost unrestricted use of strong
+encryption so these certificates are now obsolete.
+
+
+* Why does OpenSSL set the authority key identifier (AKID) extension incorrectly?
+
+It doesn't: this extension is often the cause of confusion.
+
+Consider a certificate chain A->B->C so that A signs B and B signs C. Suppose
+certificate C contains AKID.
+
+The purpose of this extension is to identify the authority certificate B. This
+can be done either by including the subject key identifier of B or its issuer
+name and serial number.
+
+In this latter case because it is identifying certifcate B it must contain the
+issuer name and serial number of B.
+
+It is often wrongly assumed that it should contain the subject name of B. If it
+did this would be redundant information because it would duplicate the issuer
+name of C.
+
+
+* How can I set up a bundle of commercial root CA certificates?
+
+The OpenSSL software is shipped without any root CA certificate as the
+OpenSSL project does not have any policy on including or excluding
+any specific CA and does not intend to set up such a policy. Deciding
+about which CAs to support is up to application developers or
+administrators.
+
+Other projects do have other policies so you can for example extract the CA
+bundle used by Mozilla and/or modssl as described in this article:
+
+  <URL: http://www.mail-archive.com/modssl-users@modssl.org/msg16980.html>
+
+
+[BUILD] =======================================================================
+
+* Why does the linker complain about undefined symbols?
+
+Maybe the compilation was interrupted, and make doesn't notice that
+something is missing.  Run "make clean; make".
+
+If you used ./Configure instead of ./config, make sure that you
+selected the right target.  File formats may differ slightly between
+OS versions (for example sparcv8/sparcv9, or a.out/elf).
+
+In case you get errors about the following symbols, use the config
+option "no-asm", as described in INSTALL:
+
+ BF_cbc_encrypt, BF_decrypt, BF_encrypt, CAST_cbc_encrypt,
+ CAST_decrypt, CAST_encrypt, RC4, RC5_32_cbc_encrypt, RC5_32_decrypt,
+ RC5_32_encrypt, bn_add_words, bn_div_words, bn_mul_add_words,
+ bn_mul_comba4, bn_mul_comba8, bn_mul_words, bn_sqr_comba4,
+ bn_sqr_comba8, bn_sqr_words, bn_sub_words, des_decrypt3,
+ des_ede3_cbc_encrypt, des_encrypt, des_encrypt2, des_encrypt3,
+ des_ncbc_encrypt, md5_block_asm_host_order, sha1_block_asm_data_order
+
+If none of these helps, you may want to try using the current snapshot.
+If the problem persists, please submit a bug report.
+
+
+* Why does the OpenSSL test fail with "bc: command not found"?
+
+You didn't install "bc", the Unix calculator.  If you want to run the
+tests, get GNU bc from ftp://ftp.gnu.org or from your OS distributor.
+
+
+* Why does the OpenSSL test fail with "bc: 1 no implemented"?
+
+On some SCO installations or versions, bc has a bug that gets triggered
+when you run the test suite (using "make test").  The message returned is
+"bc: 1 not implemented".
+
+The best way to deal with this is to find another implementation of bc
+and compile/install it.  GNU bc (see <URL: http://www.gnu.org/software/software.html>
+for download instructions) can be safely used, for example.
+
+
+* Why does the OpenSSL test fail with "bc: stack empty"?
+
+On some DG/ux versions, bc seems to have a too small stack for calculations
+that the OpenSSL bntest throws at it.  This gets triggered when you run the
+test suite (using "make test").  The message returned is "bc: stack empty".
+
+The best way to deal with this is to find another implementation of bc
+and compile/install it.  GNU bc (see <URL: http://www.gnu.org/software/software.html>
+for download instructions) can be safely used, for example.
+
+
+* Why does the OpenSSL compilation fail on Alpha Tru64 Unix?
+
+On some Alpha installations running Tru64 Unix and Compaq C, the compilation
+of crypto/sha/sha_dgst.c fails with the message 'Fatal:  Insufficient virtual
+memory to continue compilation.'  As far as the tests have shown, this may be
+a compiler bug.  What happens is that it eats up a lot of resident memory
+to build something, probably a table.  The problem is clearly in the
+optimization code, because if one eliminates optimization completely (-O0),
+the compilation goes through (and the compiler consumes about 2MB of resident
+memory instead of 240MB or whatever one's limit is currently).
+
+There are three options to solve this problem:
+
+1. set your current data segment size soft limit higher.  Experience shows
+that about 241000 kbytes seems to be enough on an AlphaServer DS10.  You do
+this with the command 'ulimit -Sd nnnnnn', where 'nnnnnn' is the number of
+kbytes to set the limit to.
+
+2. If you have a hard limit that is lower than what you need and you can't
+get it changed, you can compile all of OpenSSL with -O0 as optimization
+level.  This is however not a very nice thing to do for those who expect to
+get the best result from OpenSSL.  A bit more complicated solution is the
+following:
+
+----- snip:start -----
+  make DIRS=crypto SDIRS=sha "`grep '^CFLAG=' Makefile.ssl | \
+       sed -e 's/ -O[0-9] / -O0 /'`"
+  rm `ls crypto/*.o crypto/sha/*.o | grep -v 'sha_dgst\.o'`
+  make
+----- snip:end -----
+
+This will only compile sha_dgst.c with -O0, the rest with the optimization
+level chosen by the configuration process.  When the above is done, do the
+test and installation and you're set.
+
+3. Reconfigure the toolkit with no-sha0 option to leave out SHA0. It 
+should not be used and is not used in SSL/TLS nor any other recognized
+protocol in either case.
+
+
+* Why does the OpenSSL compilation fail with "ar: command not found"?
+
+Getting this message is quite usual on Solaris 2, because Sun has hidden
+away 'ar' and other development commands in directories that aren't in
+$PATH by default.  One of those directories is '/usr/ccs/bin'.  The
+quickest way to fix this is to do the following (it assumes you use sh
+or any sh-compatible shell):
+
+----- snip:start -----
+  PATH=${PATH}:/usr/ccs/bin; export PATH
+----- snip:end -----
+
+and then redo the compilation.  What you should really do is make sure
+'/usr/ccs/bin' is permanently in your $PATH, for example through your
+'.profile' (again, assuming you use a sh-compatible shell).
+
+
+* Why does the OpenSSL compilation fail on Win32 with VC++?
+
+Sometimes, you may get reports from VC++ command line (cl) that it
+can't find standard include files like stdio.h and other weirdnesses.
+One possible cause is that the environment isn't correctly set up.
+To solve that problem for VC++ versions up to 6, one should run
+VCVARS32.BAT which is found in the 'bin' subdirectory of the VC++
+installation directory (somewhere under 'Program Files').  For VC++
+version 7 (and up?), which is also called VS.NET, the file is called
+VSVARS32.BAT instead.
+This needs to be done prior to running NMAKE, and the changes are only
+valid for the current DOS session.
+
+
+* What is special about OpenSSL on Redhat?
+
+Red Hat Linux (release 7.0 and later) include a preinstalled limited
+version of OpenSSL. For patent reasons, support for IDEA, RC5 and MDC2
+is disabled in this version. The same may apply to other Linux distributions.
+Users may therefore wish to install more or all of the features left out.
+
+To do this you MUST ensure that you do not overwrite the openssl that is in
+/usr/bin on your Red Hat machine. Several packages depend on this file,
+including sendmail and ssh. /usr/local/bin is a good alternative choice. The
+libraries that come with Red Hat 7.0 onwards have different names and so are
+not affected. (eg For Red Hat 7.2 they are /lib/libssl.so.0.9.6b and
+/lib/libcrypto.so.0.9.6b with symlinks /lib/libssl.so.2 and
+/lib/libcrypto.so.2 respectively).
+
+Please note that we have been advised by Red Hat attempting to recompile the
+openssl rpm with all the cryptography enabled will not work. All other
+packages depend on the original Red Hat supplied openssl package. It is also
+worth noting that due to the way Red Hat supplies its packages, updates to
+openssl on each distribution never change the package version, only the
+build number. For example, on Red Hat 7.1, the latest openssl package has
+version number 0.9.6 and build number 9 even though it contains all the
+relevant updates in packages up to and including 0.9.6b.
+
+A possible way around this is to persuade Red Hat to produce a non-US
+version of Red Hat Linux.
+
+FYI: Patent numbers and expiry dates of US patents:
+MDC-2: 4,908,861 13/03/2007
+IDEA:  5,214,703 25/05/2010
+RC5:   5,724,428 03/03/2015
+
+
+* Why does the OpenSSL compilation fail on MacOS X?
+
+If the failure happens when trying to build the "openssl" binary, with
+a large number of undefined symbols, it's very probable that you have
+OpenSSL 0.9.6b delivered with the operating system (you can find out by
+running '/usr/bin/openssl version') and that you were trying to build
+OpenSSL 0.9.7 or newer.  The problem is that the loader ('ld') in
+MacOS X has a misfeature that's quite difficult to go around.
+Look in the file PROBLEMS for a more detailed explanation and for possible
+solutions.
+
+
+* Why does the OpenSSL test suite fail on MacOS X?
+
+If the failure happens when running 'make test' and the RC4 test fails,
+it's very probable that you have OpenSSL 0.9.6b delivered with the
+operating system (you can find out by running '/usr/bin/openssl version')
+and that you were trying to build OpenSSL 0.9.6d.  The problem is that
+the loader ('ld') in MacOS X has a misfeature that's quite difficult to
+go around and has linked the programs "openssl" and the test programs
+with /usr/lib/libcrypto.dylib and /usr/lib/libssl.dylib instead of the
+libraries you just built.
+Look in the file PROBLEMS for a more detailed explanation and for possible
+solutions.
+
+* Why does the OpenSSL test suite fail in BN_sqr test [on a 64-bit platform]?
+
+Failure in BN_sqr test is most likely caused by a failure to configure the
+toolkit for current platform or lack of support for the platform in question.
+Run './config -t' and './apps/openssl version -p'. Do these platform
+identifiers match? If they don't, then you most likely failed to run
+./config and you're hereby advised to do so before filing a bug report.
+If ./config itself fails to run, then it's most likely problem with your
+local environment and you should turn to your system administrator (or
+similar). If identifiers match (and/or no alternative identifier is
+suggested by ./config script), then the platform is unsupported. There might
+or might not be a workaround. Most notably on SPARC64 platforms with GNU
+C compiler you should be able to produce a working build by running
+'./config -m32'. I understand that -m32 might not be what you want/need,
+but the build should be operational. For further details turn to
+<openssl-dev@openssl.org>.
+
+* Why does OpenBSD-i386 build fail on des-586.s with "Unimplemented segment type"?
+
+As of 0.9.7 assembler routines were overhauled for position independence
+of the machine code, which is essential for shared library support. For
+some reason OpenBSD is equipped with an out-of-date GNU assembler which
+finds the new code offensive. To work around the problem, configure with
+no-asm (and sacrifice a great deal of performance) or patch your assembler
+according to <URL: http://www.openssl.org/~appro/gas-1.92.3.OpenBSD.patch>.
+For your convenience a pre-compiled replacement binary is provided at
+<URL: http://www.openssl.org/~appro/gas-1.92.3.static.aout.bin>.
+Reportedly elder *BSD a.out platforms also suffer from this problem and
+remedy should be same. Provided binary is statically linked and should be
+working across wider range of *BSD branches, not just OpenBSD.
+
+* Why does the OpenSSL test suite fail in sha512t on x86 CPU?
+
+If the test program in question fails withs SIGILL, Illegal Instruction
+exception, then you more than likely to run SSE2-capable CPU, such as
+Intel P4, under control of kernel which does not support SSE2
+instruction extentions. See accompanying INSTALL file and
+OPENSSL_ia32cap(3) documentation page for further information.
+
+* Why does compiler fail to compile sha512.c?
+
+OpenSSL SHA-512 implementation depends on compiler support for 64-bit
+integer type. Few elder compilers [ULTRIX cc, SCO compiler to mention a
+couple] lack support for this and therefore are incapable of compiling
+the module in question. The recommendation is to disable SHA-512 by
+adding no-sha512 to ./config [or ./Configure] command line. Another
+possible alternative might be to switch to GCC.
+
+* Test suite still fails, what to do?
+
+Another common reason for failure to complete some particular test is
+simply bad code generated by a buggy component in toolchain or deficiency
+in run-time environment. There are few cases documented in PROBLEMS file,
+consult it for possible workaround before you beat the drum. Even if you
+don't find solution or even mention there, do reserve for possibility of
+a compiler bug. Compiler bugs might appear in rather bizarre ways, they
+never make sense, and tend to emerge when you least expect them. In order
+to identify one, drop optimization level, e.g. by editing CFLAG line in
+top-level Makefile, recompile and re-run the test.
+
+* I think I've found a bug, what should I do?
+
+If you are a new user then it is quite likely you haven't found a bug and
+something is happening you aren't familiar with. Check this FAQ, the associated
+documentation and the mailing lists for similar queries. If you are still
+unsure whether it is a bug or not submit a query to the openssl-users mailing
+list.
+
+
+* I'm SURE I've found a bug, how do I report it?
+
+Bug reports with no security implications should be sent to the request
+tracker. This can be done by mailing the report to <rt@openssl.org> (or its
+alias <openssl-bugs@openssl.org>), please note that messages sent to the
+request tracker also appear in the public openssl-dev mailing list.
+
+The report should be in plain text. Any patches should be sent as
+plain text attachments because some mailers corrupt patches sent inline.
+If your issue affects multiple versions of OpenSSL check any patches apply
+cleanly and, if possible include patches to each affected version.
+
+The report should be given a meaningful subject line briefly summarising the
+issue. Just "bug in OpenSSL" or "bug in OpenSSL 0.9.8n" is not very helpful.
+
+By sending reports to the request tracker the bug can then be given a priority
+and assigned to the appropriate maintainer. The history of discussions can be
+accessed and if the issue has been addressed or a reason why not. If patches
+are only sent to openssl-dev they can be mislaid if a team member has to
+wade through months of old messages to review the discussion.
+
+See also <URL: http://www.openssl.org/support/rt.html>
+
+
+* I've found a security issue, how do I report it?
+
+If you think your bug has security implications then please send it to
+openssl-security@openssl.org if you don't get a prompt reply at least 
+acknowledging receipt then resend or mail it directly to one of the
+more active team members (e.g. Steve).
+
+[PROG] ========================================================================
+
+* Is OpenSSL thread-safe?
+
+Yes (with limitations: an SSL connection may not concurrently be used
+by multiple threads).  On Windows and many Unix systems, OpenSSL
+automatically uses the multi-threaded versions of the standard
+libraries.  If your platform is not one of these, consult the INSTALL
+file.
+
+Multi-threaded applications must provide two callback functions to
+OpenSSL by calling CRYPTO_set_locking_callback() and
+CRYPTO_set_id_callback(), for all versions of OpenSSL up to and
+including 0.9.8[abc...]. As of version 1.0.0, CRYPTO_set_id_callback()
+and associated APIs are deprecated by CRYPTO_THREADID_set_callback()
+and friends. This is described in the threads(3) manpage.
+
+* I've compiled a program under Windows and it crashes: why?
+
+This is usually because you've missed the comment in INSTALL.W32.
+Your application must link against the same version of the Win32
+C-Runtime against which your openssl libraries were linked.  The
+default version for OpenSSL is /MD - "Multithreaded DLL".
+
+If you are using Microsoft Visual C++'s IDE (Visual Studio), in
+many cases, your new project most likely defaulted to "Debug
+Singlethreaded" - /ML.  This is NOT interchangeable with /MD and your
+program will crash, typically on the first BIO related read or write
+operation.
+
+For each of the six possible link stage configurations within Win32,
+your application must link  against the same by which OpenSSL was
+built.  If you are using MS Visual C++ (Studio) this can be changed
+by:
+
+ 1. Select Settings... from the Project Menu.
+ 2. Select the C/C++ Tab.
+ 3. Select "Code Generation from the "Category" drop down list box
+ 4. Select the Appropriate library (see table below) from the "Use
+    run-time library" drop down list box.  Perform this step for both
+    your debug and release versions of your application (look at the
+    top left of the settings panel to change between the two)
+
+    Single Threaded           /ML        -  MS VC++ often defaults to
+                                            this for the release
+                                            version of a new project.
+    Debug Single Threaded     /MLd       -  MS VC++ often defaults to
+                                            this for the debug version
+                                            of a new project.
+    Multithreaded             /MT
+    Debug Multithreaded       /MTd
+    Multithreaded DLL         /MD        -  OpenSSL defaults to this.
+    Debug Multithreaded DLL   /MDd
+
+Note that debug and release libraries are NOT interchangeable.  If you
+built OpenSSL with /MD your application must use /MD and cannot use /MDd.
+
+As per 0.9.8 the above limitation is eliminated for .DLLs. OpenSSL
+.DLLs compiled with some specific run-time option [we insist on the
+default /MD] can be deployed with application compiled with different
+option or even different compiler. But there is a catch! Instead of
+re-compiling OpenSSL toolkit, as you would have to with prior versions,
+you have to compile small C snippet with compiler and/or options of
+your choice. The snippet gets installed as
+<install-root>/include/openssl/applink.c and should be either added to
+your application project or simply #include-d in one [and only one]
+of your application source files. Failure to link this shim module
+into your application manifests itself as fatal "no OPENSSL_Applink"
+run-time error. An explicit reminder is due that in this situation
+[mixing compiler options] it is as important to add CRYPTO_malloc_init
+prior first call to OpenSSL.
+
+* How do I read or write a DER encoded buffer using the ASN1 functions?
+
+You have two options. You can either use a memory BIO in conjunction
+with the i2d_*_bio() or d2i_*_bio() functions or you can use the
+i2d_*(), d2i_*() functions directly. Since these are often the
+cause of grief here are some code fragments using PKCS7 as an example:
+
+ unsigned char *buf, *p;
+ int len;
+
+ len = i2d_PKCS7(p7, NULL);
+ buf = OPENSSL_malloc(len); /* or Malloc, error checking omitted */
+ p = buf;
+ i2d_PKCS7(p7, &p);
+
+At this point buf contains the len bytes of the DER encoding of
+p7.
+
+The opposite assumes we already have len bytes in buf:
+
+ unsigned char *p;
+ p = buf;
+ p7 = d2i_PKCS7(NULL, &p, len);
+
+At this point p7 contains a valid PKCS7 structure of NULL if an error
+occurred. If an error occurred ERR_print_errors(bio) should give more
+information.
+
+The reason for the temporary variable 'p' is that the ASN1 functions
+increment the passed pointer so it is ready to read or write the next
+structure. This is often a cause of problems: without the temporary
+variable the buffer pointer is changed to point just after the data
+that has been read or written. This may well be uninitialized data
+and attempts to free the buffer will have unpredictable results
+because it no longer points to the same address.
+
+
+* OpenSSL uses DER but I need BER format: does OpenSSL support BER?
+
+The short answer is yes, because DER is a special case of BER and OpenSSL
+ASN1 decoders can process BER.
+
+The longer answer is that ASN1 structures can be encoded in a number of
+different ways. One set of ways is the Basic Encoding Rules (BER) with various
+permissible encodings. A restriction of BER is the Distinguished Encoding
+Rules (DER): these uniquely specify how a given structure is encoded.
+
+Therefore, because DER is a special case of BER, DER is an acceptable encoding
+for BER.
+
+
+* I've tried using <M_some_evil_pkcs12_macro> and I get errors why?
+
+This usually happens when you try compiling something using the PKCS#12
+macros with a C++ compiler. There is hardly ever any need to use the
+PKCS#12 macros in a program, it is much easier to parse and create
+PKCS#12 files using the PKCS12_parse() and PKCS12_create() functions
+documented in doc/openssl.txt and with examples in demos/pkcs12. The
+'pkcs12' application has to use the macros because it prints out 
+debugging information.
+
+
+* I've called <some function> and it fails, why?
+
+Before submitting a report or asking in one of the mailing lists, you
+should try to determine the cause. In particular, you should call
+ERR_print_errors() or ERR_print_errors_fp() after the failed call
+and see if the message helps. Note that the problem may occur earlier
+than you think -- you should check for errors after every call where
+it is possible, otherwise the actual problem may be hidden because
+some OpenSSL functions clear the error state.
+
+
+* I just get a load of numbers for the error output, what do they mean?
+
+The actual format is described in the ERR_print_errors() manual page.
+You should call the function ERR_load_crypto_strings() before hand and
+the message will be output in text form. If you can't do this (for example
+it is a pre-compiled binary) you can use the errstr utility on the error
+code itself (the hex digits after the second colon).
+
+
+* Why do I get errors about unknown algorithms?
+
+The cause is forgetting to load OpenSSL's table of algorithms with
+OpenSSL_add_all_algorithms(). See the manual page for more information. This
+can cause several problems such as being unable to read in an encrypted
+PEM file, unable to decrypt a PKCS#12 file or signature failure when
+verifying certificates.
+
+* Why can't the OpenSSH configure script detect OpenSSL?
+
+Several reasons for problems with the automatic detection exist.
+OpenSSH requires at least version 0.9.5a of the OpenSSL libraries.
+Sometimes the distribution has installed an older version in the system
+locations that is detected instead of a new one installed. The OpenSSL
+library might have been compiled for another CPU or another mode (32/64 bits).
+Permissions might be wrong.
+
+The general answer is to check the config.log file generated when running
+the OpenSSH configure script. It should contain the detailed information
+on why the OpenSSL library was not detected or considered incompatible.
+
+
+* Can I use OpenSSL's SSL library with non-blocking I/O?
+
+Yes; make sure to read the SSL_get_error(3) manual page!
+
+A pitfall to avoid: Don't assume that SSL_read() will just read from
+the underlying transport or that SSL_write() will just write to it --
+it is also possible that SSL_write() cannot do any useful work until
+there is data to read, or that SSL_read() cannot do anything until it
+is possible to send data.  One reason for this is that the peer may
+request a new TLS/SSL handshake at any time during the protocol,
+requiring a bi-directional message exchange; both SSL_read() and
+SSL_write() will try to continue any pending handshake.
+
+
+* Why doesn't my server application receive a client certificate?
+
+Due to the TLS protocol definition, a client will only send a certificate,
+if explicitly asked by the server. Use the SSL_VERIFY_PEER flag of the
+SSL_CTX_set_verify() function to enable the use of client certificates.
+
+
+* Why does compilation fail due to an undefined symbol NID_uniqueIdentifier?
+
+For OpenSSL 0.9.7 the OID table was extended and corrected. In earlier
+versions, uniqueIdentifier was incorrectly used for X.509 certificates.
+The correct name according to RFC2256 (LDAP) is x500UniqueIdentifier.
+Change your code to use the new name when compiling against OpenSSL 0.9.7.
+
+
+* I think I've detected a memory leak, is this a bug?
+
+In most cases the cause of an apparent memory leak is an OpenSSL internal table
+that is allocated when an application starts up. Since such tables do not grow
+in size over time they are harmless.
+
+These internal tables can be freed up when an application closes using various
+functions.  Currently these include following:
+
+Thread-local cleanup functions:
+
+  ERR_remove_state()
+
+Application-global cleanup functions that are aware of usage (and therefore
+thread-safe):
+
+  ENGINE_cleanup() and CONF_modules_unload()
+
+"Brutal" (thread-unsafe) Application-global cleanup functions:
+
+  ERR_free_strings(), EVP_cleanup() and CRYPTO_cleanup_all_ex_data().
+
+
+* Why does Valgrind complain about the use of uninitialized data?
+
+When OpenSSL's PRNG routines are called to generate random numbers the supplied
+buffer contents are mixed into the entropy pool: so it technically does not
+matter whether the buffer is initialized at this point or not.  Valgrind (and
+other test tools) will complain about this. When using Valgrind, make sure the
+OpenSSL library has been compiled with the PURIFY macro defined (-DPURIFY)
+to get rid of these warnings.
+
+
+* Why doesn't a memory BIO work when a file does?
+
+This can occur in several cases for example reading an S/MIME email message.
+The reason is that a memory BIO can do one of two things when all the data
+has been read from it.
+
+The default behaviour is to indicate that no more data is available and that
+the call should be retried, this is to allow the application to fill up the BIO
+again if necessary.
+
+Alternatively it can indicate that no more data is available and that EOF has
+been reached.
+
+If a memory BIO is to behave in the same way as a file this second behaviour
+is needed. This must be done by calling:
+
+   BIO_set_mem_eof_return(bio, 0);
+
+See the manual pages for more details.
+
+
+* Where are the declarations and implementations of d2i_X509() etc?
+
+These are defined and implemented by macros of the form:
+
+
+ DECLARE_ASN1_FUNCTIONS(X509) and IMPLEMENT_ASN1_FUNCTIONS(X509)
+
+The implementation passes an ASN1 "template" defining the structure into an
+ASN1 interpreter using generalised functions such as ASN1_item_d2i().
+
+
+===============================================================================
diff --git a/openssl/INSTALL b/openssl/INSTALL
new file mode 100644
index 0000000..1325079
--- /dev/null
+++ b/openssl/INSTALL
@@ -0,0 +1,360 @@
+
+ INSTALLATION ON THE UNIX PLATFORM
+ ---------------------------------
+
+ [Installation on DOS (with djgpp), Windows, OpenVMS, MacOS (before MacOS X)
+  and NetWare is described in INSTALL.DJGPP, INSTALL.W32, INSTALL.VMS,
+  INSTALL.MacOS and INSTALL.NW.
+  
+  This document describes installation on operating systems in the Unix
+  family.]
+
+ To install OpenSSL, you will need:
+
+  * make
+  * Perl 5
+  * an ANSI C compiler
+  * a development environment in form of development libraries and C
+    header files
+  * a supported Unix operating system
+
+ Quick Start
+ -----------
+
+ If you want to just get on with it, do:
+
+  $ ./config
+  $ make
+  $ make test
+  $ make install
+
+ [If any of these steps fails, see section Installation in Detail below.]
+
+ This will build and install OpenSSL in the default location, which is (for
+ historical reasons) /usr/local/ssl. If you want to install it anywhere else,
+ run config like this:
+
+  $ ./config --prefix=/usr/local --openssldir=/usr/local/openssl
+
+
+ Configuration Options
+ ---------------------
+
+ There are several options to ./config (or ./Configure) to customize
+ the build:
+
+  --prefix=DIR  Install in DIR/bin, DIR/lib, DIR/include/openssl.
+	        Configuration files used by OpenSSL will be in DIR/ssl
+                or the directory specified by --openssldir.
+
+  --openssldir=DIR Directory for OpenSSL files. If no prefix is specified,
+                the library files and binaries are also installed there.
+
+  no-threads    Don't try to build with support for multi-threaded
+                applications.
+
+  threads       Build with support for multi-threaded applications.
+                This will usually require additional system-dependent options!
+                See "Note on multi-threading" below.
+
+  no-zlib       Don't try to build with support for zlib compression and
+                decompression.
+
+  zlib          Build with support for zlib compression/decompression.
+
+  zlib-dynamic  Like "zlib", but has OpenSSL load the zlib library dynamically
+                when needed.  This is only supported on systems where loading
+                of shared libraries is supported.  This is the default choice.
+
+  no-shared     Don't try to create shared libraries.
+
+  shared        In addition to the usual static libraries, create shared
+                libraries on platforms where it's supported.  See "Note on
+                shared libraries" below.
+
+  no-asm        Do not use assembler code.
+
+  386           Use the 80386 instruction set only (the default x86 code is
+                more efficient, but requires at least a 486). Note: Use
+                compiler flags for any other CPU specific configuration,
+                e.g. "-m32" to build x86 code on an x64 system.
+
+  no-sse2	Exclude SSE2 code pathes. Normally SSE2 extention is
+		detected at run-time, but the decision whether or not the
+		machine code will be executed is taken solely on CPU
+		capability vector. This means that if you happen to run OS
+		kernel which does not support SSE2 extension on Intel P4
+		processor, then your application might be exposed to
+		"illegal instruction" exception. There might be a way
+		to enable support in kernel, e.g. FreeBSD kernel can be
+		compiled with CPU_ENABLE_SSE, and there is a way to
+		disengage SSE2 code pathes upon application start-up,
+		but if you aim for wider "audience" running such kernel,
+		consider no-sse2. Both 386 and no-asm options above imply
+		no-sse2.
+
+  no-<cipher>   Build without the specified cipher (bf, cast, des, dh, dsa,
+                hmac, md2, md5, mdc2, rc2, rc4, rc5, rsa, sha).
+                The crypto/<cipher> directory can be removed after running
+                "make depend".
+
+  -Dxxx, -lxxx, -Lxxx, -fxxx, -mXXX, -Kxxx These system specific options will
+                be passed through to the compiler to allow you to
+                define preprocessor symbols, specify additional libraries,
+                library directories or other compiler options.
+
+  -DHAVE_CRYPTODEV Enable the BSD cryptodev engine even if we are not using
+		BSD. Useful if you are running ocf-linux or something
+		similar. Once enabled you can also enable the use of
+		cryptodev digests, which is usually slower unless you have
+		large amounts data. Use -DUSE_CRYPTODEV_DIGESTS to force
+		it.
+
+ Installation in Detail
+ ----------------------
+
+ 1a. Configure OpenSSL for your operation system automatically:
+
+       $ ./config [options]
+
+     This guesses at your operating system (and compiler, if necessary) and
+     configures OpenSSL based on this guess. Run ./config -t to see
+     if it guessed correctly. If you want to use a different compiler, you
+     are cross-compiling for another platform, or the ./config guess was
+     wrong for other reasons, go to step 1b. Otherwise go to step 2.
+
+     On some systems, you can include debugging information as follows:
+
+       $ ./config -d [options]
+
+ 1b. Configure OpenSSL for your operating system manually
+
+     OpenSSL knows about a range of different operating system, hardware and
+     compiler combinations. To see the ones it knows about, run
+
+       $ ./Configure
+
+     Pick a suitable name from the list that matches your system. For most
+     operating systems there is a choice between using "cc" or "gcc".  When
+     you have identified your system (and if necessary compiler) use this name
+     as the argument to ./Configure. For example, a "linux-elf" user would
+     run:
+
+       $ ./Configure linux-elf [options]
+
+     If your system is not available, you will have to edit the Configure
+     program and add the correct configuration for your system. The
+     generic configurations "cc" or "gcc" should usually work on 32 bit
+     systems.
+
+     Configure creates the file Makefile.ssl from Makefile.org and
+     defines various macros in crypto/opensslconf.h (generated from
+     crypto/opensslconf.h.in).
+
+  2. Build OpenSSL by running:
+
+       $ make
+
+     This will build the OpenSSL libraries (libcrypto.a and libssl.a) and the
+     OpenSSL binary ("openssl"). The libraries will be built in the top-level
+     directory, and the binary will be in the "apps" directory.
+
+     If "make" fails, look at the output.  There may be reasons for
+     the failure that aren't problems in OpenSSL itself (like missing
+     standard headers).  If it is a problem with OpenSSL itself, please
+     report the problem to <openssl-bugs@openssl.org> (note that your
+     message will be recorded in the request tracker publicly readable
+     via http://www.openssl.org/support/rt.html and will be forwarded to a
+     public mailing list). Include the output of "make report" in your message.
+     Please check out the request tracker. Maybe the bug was already
+     reported or has already been fixed.
+
+     [If you encounter assembler error messages, try the "no-asm"
+     configuration option as an immediate fix.]
+
+     Compiling parts of OpenSSL with gcc and others with the system
+     compiler will result in unresolved symbols on some systems.
+
+  3. After a successful build, the libraries should be tested. Run:
+
+       $ make test
+
+     If a test fails, look at the output.  There may be reasons for
+     the failure that isn't a problem in OpenSSL itself (like a missing
+     or malfunctioning bc).  If it is a problem with OpenSSL itself,
+     try removing any compiler optimization flags from the CFLAG line
+     in Makefile.ssl and run "make clean; make". Please send a bug
+     report to <openssl-bugs@openssl.org>, including the output of
+     "make report" in order to be added to the request tracker at
+     http://www.openssl.org/support/rt.html.
+
+  4. If everything tests ok, install OpenSSL with
+
+       $ make install
+
+     This will create the installation directory (if it does not exist) and
+     then the following subdirectories:
+
+       certs           Initially empty, this is the default location
+                       for certificate files.
+       man/man1        Manual pages for the 'openssl' command line tool
+       man/man3        Manual pages for the libraries (very incomplete)
+       misc            Various scripts.
+       private         Initially empty, this is the default location
+                       for private key files.
+
+     If you didn't choose a different installation prefix, the
+     following additional subdirectories will be created:
+
+       bin             Contains the openssl binary and a few other 
+                       utility programs. 
+       include/openssl Contains the header files needed if you want to
+                       compile programs with libcrypto or libssl.
+       lib             Contains the OpenSSL library files themselves.
+
+     Use "make install_sw" to install the software without documentation,
+     and "install_docs_html" to install HTML renditions of the manual
+     pages.
+
+     Package builders who want to configure the library for standard
+     locations, but have the package installed somewhere else so that
+     it can easily be packaged, can use
+
+       $ make INSTALL_PREFIX=/tmp/package-root install
+
+     (or specify "--install_prefix=/tmp/package-root" as a configure
+     option).  The specified prefix will be prepended to all
+     installation target filenames.
+
+
+  NOTE: The header files used to reside directly in the include
+  directory, but have now been moved to include/openssl so that
+  OpenSSL can co-exist with other libraries which use some of the
+  same filenames.  This means that applications that use OpenSSL
+  should now use C preprocessor directives of the form
+
+       #include <openssl/ssl.h>
+
+  instead of "#include <ssl.h>", which was used with library versions
+  up to OpenSSL 0.9.2b.
+
+  If you install a new version of OpenSSL over an old library version,
+  you should delete the old header files in the include directory.
+
+  Compatibility issues:
+
+  *  COMPILING existing applications
+
+     To compile an application that uses old filenames -- e.g.
+     "#include <ssl.h>" --, it will usually be enough to find
+     the CFLAGS definition in the application's Makefile and
+     add a C option such as
+
+          -I/usr/local/ssl/include/openssl
+
+     to it.
+
+     But don't delete the existing -I option that points to
+     the ..../include directory!  Otherwise, OpenSSL header files
+     could not #include each other.
+
+  *  WRITING applications
+
+     To write an application that is able to handle both the new
+     and the old directory layout, so that it can still be compiled
+     with library versions up to OpenSSL 0.9.2b without bothering
+     the user, you can proceed as follows:
+
+     -  Always use the new filename of OpenSSL header files,
+        e.g. #include <openssl/ssl.h>.
+
+     -  Create a directory "incl" that contains only a symbolic
+        link named "openssl", which points to the "include" directory
+        of OpenSSL.
+        For example, your application's Makefile might contain the
+        following rule, if OPENSSLDIR is a pathname (absolute or
+        relative) of the directory where OpenSSL resides:
+
+        incl/openssl:
+        	-mkdir incl
+        	cd $(OPENSSLDIR) # Check whether the directory really exists
+        	-ln -s `cd $(OPENSSLDIR); pwd`/include incl/openssl
+
+        You will have to add "incl/openssl" to the dependencies
+        of those C files that include some OpenSSL header file.
+
+     -  Add "-Iincl" to your CFLAGS.
+
+     With these additions, the OpenSSL header files will be available
+     under both name variants if an old library version is used:
+     Your application can reach them under names like <openssl/foo.h>,
+     while the header files still are able to #include each other
+     with names of the form <foo.h>.
+
+
+ Note on multi-threading
+ -----------------------
+
+ For some systems, the OpenSSL Configure script knows what compiler options
+ are needed to generate a library that is suitable for multi-threaded
+ applications.  On these systems, support for multi-threading is enabled
+ by default; use the "no-threads" option to disable (this should never be
+ necessary).
+
+ On other systems, to enable support for multi-threading, you will have
+ to specify at least two options: "threads", and a system-dependent option.
+ (The latter is "-D_REENTRANT" on various systems.)  The default in this
+ case, obviously, is not to include support for multi-threading (but
+ you can still use "no-threads" to suppress an annoying warning message
+ from the Configure script.)
+
+
+ Note on shared libraries
+ ------------------------
+
+ Shared libraries have certain caveats.  Binary backward compatibility
+ can't be guaranteed before OpenSSL version 1.0.  The only reason to
+ use them would be to conserve memory on systems where several programs
+ are using OpenSSL.
+
+ For some systems, the OpenSSL Configure script knows what is needed to
+ build shared libraries for libcrypto and libssl.  On these systems,
+ the shared libraries are currently not created by default, but giving
+ the option "shared" will get them created.  This method supports Makefile
+ targets for shared library creation, like linux-shared.  Those targets
+ can currently be used on their own just as well, but this is expected
+ to change in future versions of OpenSSL.
+
+ Note on random number generation
+ --------------------------------
+
+ Availability of cryptographically secure random numbers is required for
+ secret key generation. OpenSSL provides several options to seed the
+ internal PRNG. If not properly seeded, the internal PRNG will refuse
+ to deliver random bytes and a "PRNG not seeded error" will occur.
+ On systems without /dev/urandom (or similar) device, it may be necessary
+ to install additional support software to obtain random seed.
+ Please check out the manual pages for RAND_add(), RAND_bytes(), RAND_egd(),
+ and the FAQ for more information.
+
+ Note on support for multiple builds
+ -----------------------------------
+
+ OpenSSL is usually built in its source tree.  Unfortunately, this doesn't
+ support building for multiple platforms from the same source tree very well.
+ It is however possible to build in a separate tree through the use of lots
+ of symbolic links, which should be prepared like this:
+
+	mkdir -p objtree/"`uname -s`-`uname -r`-`uname -m`"
+	cd objtree/"`uname -s`-`uname -r`-`uname -m`"
+	(cd $OPENSSL_SOURCE; find . -type f) | while read F; do
+		mkdir -p `dirname $F`
+		rm -f $F; ln -s $OPENSSL_SOURCE/$F $F
+		echo $F '->' $OPENSSL_SOURCE/$F
+	done
+	make -f Makefile.org clean
+
+ OPENSSL_SOURCE is an environment variable that contains the absolute (this
+ is important!) path to the OpenSSL source tree.
+
+ Also, operations like 'make update' should still be made in the source tree.
diff --git a/openssl/INSTALL.DJGPP b/openssl/INSTALL.DJGPP
new file mode 100644
index 0000000..1047ec9
--- /dev/null
+++ b/openssl/INSTALL.DJGPP
@@ -0,0 +1,47 @@
+
+ 
+ INSTALLATION ON THE DOS PLATFORM WITH DJGPP
+ -------------------------------------------
+
+ OpenSSL has been ported to DJGPP, a Unix look-alike 32-bit run-time
+ environment for 16-bit DOS, but only with long filename support.
+ If you wish to compile on native DOS with 8+3 filenames, you will
+ have to tweak the installation yourself, including renaming files
+ with illegal or duplicate names.
+
+ You should have a full DJGPP environment installed, including the
+ latest versions of DJGPP, GCC, BINUTILS, BASH, etc. This package
+ requires that PERL and BC also be installed.
+
+ All of these can be obtained from the usual DJGPP mirror sites or
+ directly at "http://www.delorie.com/pub/djgpp". For help on which
+ files to download, see the DJGPP "ZIP PICKER" page at
+ "http://www.delorie.com/djgpp/zip-picker.html". You also need to have
+ the WATT-32 networking package installed before you try to compile
+ OpenSSL. This can be obtained from "http://www.bgnett.no/~giva/".
+ The Makefile assumes that the WATT-32 code is in the directory
+ specified by the environment variable WATT_ROOT. If you have watt-32
+ in directory "watt32" under your main DJGPP directory, specify
+ WATT_ROOT="/dev/env/DJDIR/watt32".
+
+ To compile OpenSSL, start your BASH shell, then configure for DJGPP by
+ running "./Configure" with appropriate arguments:
+
+	./Configure no-threads --prefix=/dev/env/DJDIR DJGPP
+ 
+ And finally fire up "make". You may run out of DPMI selectors when
+ running in a DOS box under Windows. If so, just close the BASH
+ shell, go back to Windows, and restart BASH. Then run "make" again.
+
+ RUN-TIME CAVEAT LECTOR
+ --------------
+
+ Quoting FAQ:
+
+  "Cryptographic software needs a source of unpredictable data to work
+   correctly.  Many open source operating systems provide a "randomness
+   device" (/dev/urandom or /dev/random) that serves this purpose."
+
+ As of version 0.9.7f DJGPP port checks upon /dev/urandom$ for a 3rd
+ party "randomness" DOS driver. One such driver, NOISE.SYS, can be
+ obtained from "http://www.rahul.net/dkaufman/index.html".
diff --git a/openssl/INSTALL.MacOS b/openssl/INSTALL.MacOS
new file mode 100644
index 0000000..01c60d8
--- /dev/null
+++ b/openssl/INSTALL.MacOS
@@ -0,0 +1,72 @@
+OpenSSL - Port To The Macintosh OS 9 or Earlier
+===============================================
+
+Thanks to Roy Wood <roy@centricsystems.ca> initial support for Mac OS (pre
+X) is now provided. "Initial" means that unlike other platforms where you
+get an SDK and a "swiss army" openssl application, on Macintosh you only
+get one sample application which fetches a page over HTTPS(*) and dumps it
+in a window. We don't even build the test applications so that we can't
+guarantee that all algorithms are operational.
+
+Required software:
+
+- StuffIt Expander 5.5 or later, alternatively MacGzip and SUNtar;
+- Scriptable Finder;
+- CodeWarrior Pro 5;
+
+Installation procedure:
+
+- fetch the source at ftp://ftp.openssl.org/ (well, you probably already
+  did, huh?)
+- unpack the .tar.gz file:
+	- if you have StuffIt Expander then just drag it over it;
+	- otherwise uncompress it with MacGzip and then unpack with SUNtar;
+- locate MacOS folder in OpenSSL source tree and open it;
+- unbinhex mklinks.as.hqx and OpenSSL.mcp.hqx if present (**), do it
+  "in-place", i.e. unpacked files should end-up in the very same folder;
+- execute mklinks.as;
+- open OpenSSL.mcp(***) and build 'GetHTTPS PPC' target(****);
+- that's it for now;
+
+(*)	URL is hardcoded into ./MacOS/GetHTTPS.src/GetHTTPS.cpp, lines 40
+        to 42, change appropriately.
+(**)	If you use SUNtar, then it might have already unbinhexed the files
+	in question.
+(***)	The project file was saved with CW Pro 5.3. If you have an earlier
+	version and it refuses to open it, then download
+	http://www.openssl.org/~appro/OpenSSL.mcp.xml and import it
+	overwriting the original OpenSSL.mcp.
+(****)	Other targets are works in progress. If you feel like giving 'em a
+	shot, then you should know that OpenSSL* and Lib* targets are
+	supposed to be built with the GUSI, MacOS library which mimics
+	BSD sockets and some other POSIX APIs. The GUSI distribution is
+	expected to be found in the same directory as the openssl source tree,
+	i.e., in the parent directory to the one where this very file,
+	namely INSTALL.MacOS, resides. For more information about GUSI, see
+	http://www.iis.ee.ethz.ch/~neeri/macintosh/gusi-qa.html
+
+Finally some essential comments from our generous contributor:-)
+
+"I've gotten OpenSSL working on the Macintosh. It's probably a bit of a
+hack, but it works for what I'm doing. If you don't like the way I've done
+it, then feel free to change what I've done. I freely admit that I've done
+some less-than-ideal things in my port, and if you don't like the way I've
+done something, then feel free to change it-- I won't be offended!
+
+... I've tweaked "bss_sock.c" a little to call routines in a "MacSocket"
+library I wrote. My MacSocket library is a wrapper around OpenTransport,
+handling stuff like endpoint creation, reading, writing, etc. It is not
+designed as a high-performance package such as you'd use in a webserver,
+but is fine for lots of other applications. MacSocket also uses some other
+code libraries I've written to deal with string manipulations and error
+handling. Feel free to use these things in your own code, but give me
+credit and/or send me free stuff in appreciation! :-)
+
+...
+
+If you have any questions, feel free to email me as the following:
+
+roy@centricsystems.ca
+
+-Roy Wood"
+
diff --git a/openssl/INSTALL.NW b/openssl/INSTALL.NW
new file mode 100644
index 0000000..609a730
--- /dev/null
+++ b/openssl/INSTALL.NW
@@ -0,0 +1,454 @@
+
+INSTALLATION ON THE NETWARE PLATFORM
+------------------------------------
+
+Notes about building OpenSSL for NetWare.
+
+
+BUILD PLATFORM:
+---------------
+The build scripts (batch files, perl scripts, etc) have been developed and
+tested on W2K.  The scripts should run fine on other Windows platforms
+(NT, Win9x, WinXP) but they have not been tested.  They may require some
+modifications.
+
+
+Supported NetWare Platforms - NetWare 5.x, NetWare 6.x:
+-------------------------------------------------------
+OpenSSL can either use the WinSock interfaces introduced in NetWare 5,
+or the BSD socket interface.  Previous versions of NetWare, 4.x and 3.x,
+are only supported if OpenSSL is build for CLIB and BSD sockets;
+WinSock builds only support NetWare 5 and up.
+
+On NetWare there are two c-runtime libraries.  There is the legacy CLIB 
+interfaces and the newer LIBC interfaces.  Being ANSI-C libraries, the 
+functionality in CLIB and LIBC is similar but the LIBC interfaces are built 
+using Novell Kernal Services (NKS) which is designed to leverage 
+multi-processor environments.
+
+The NetWare port of OpenSSL can be configured to build using CLIB or LIBC.
+The CLIB build was developed and tested using NetWare 5.0 sp6.0a.  The LIBC 
+build was developed and tested using the NetWare 6.0 FCS.  
+
+The necessary LIBC functionality ships with NetWare 6.  However, earlier 
+NetWare 5.x versions will require updates in order to run the OpenSSL LIBC
+build (NetWare 5.1 SP8 is known to work).
+
+As of June 2005, the LIBC build can be configured to use BSD sockets instead
+of WinSock sockets. Call Configure (usually through netware\build.bat) using
+a target of "netware-libc-bsdsock" instead of "netware-libc".
+
+As of June 2007, support for CLIB and BSD sockets is also now available
+using a target of "netware-clib-bsdsock" instead of "netware-clib";
+also gcc builds are now supported on both Linux and Win32 (post 0.9.8e).
+
+REQUIRED TOOLS:
+---------------
+Based upon the configuration and build options used, some or all of the
+following tools may be required:
+
+* Perl for Win32 - required (http://www.activestate.com/ActivePerl)
+   Used to run the various perl scripts on the build platform.
+
+* Perl 5.8.0 for NetWare v3.20 (or later) - required 
+   (http://developer.novell.com) Used to run the test script on NetWare 
+   after building.
+
+* Compiler / Linker - required:
+   Metrowerks CodeWarrior PDK 2.1 (or later) for NetWare (commercial):
+      Provides command line tools used for building.
+      Tools:
+      mwccnlm.exe  - C/C++ Compiler for NetWare
+      mwldnlm.exe  - Linker for NetWare
+      mwasmnlm.exe - x86 assembler for NetWare (if using assembly option)
+
+   gcc / nlmconv Cross-Compiler, available from Novell Forge (free):
+         http://forge.novell.com/modules/xfmod/project/?aunixnw
+
+* Assemblers - optional:
+   If you intend to build using the assembly options you will need an
+   assembler.  Work has been completed to support two assemblers, Metrowerks
+   and NASM.  However, during development, a bug was found in the Metrowerks
+   assembler which generates incorrect code.  Until this problem is fixed,
+   the Metrowerks assembler cannot be used.
+
+   mwasmnlm.exe - Metrowerks x86 assembler - part of CodeWarrior tools.
+         (version 2.2 Built Aug 23, 1999 - not useable due to code
+          generation bug)
+
+   nasmw.exe - Netwide Assembler NASM
+         version 0.98 was used in development and testing
+
+* Make Tool - required:
+   In order to build you will need a make tool.  Two make tools are
+   supported, GNU make (gmake.exe) or Microsoft nmake.exe.
+
+   make.exe - GNU make for Windows (version 3.75 used for development)
+         http://gnuwin32.sourceforge.net/packages/make.htm
+
+   nmake.exe - Microsoft make (Version 6.00.8168.0 used for development)
+         http://support.microsoft.com/kb/132084/EN-US/
+
+* Novell Developer Kit (NDK) - required: (http://developer.novell.com)
+
+   CLIB - BUILDS:
+
+      WinSock2 Developer Components for NetWare:
+         For initial development, the October 27, 2000 version was used.
+         However, future versions should also work.
+
+         NOTE:  The WinSock2 components include headers & import files for
+         NetWare, but you will also need the winsock2.h and supporting
+         headers (pshpack4.h, poppack.h, qos.h) delivered in the
+         Microsoft SDK.  Note: The winsock2.h support headers may change
+         with various versions of winsock2.h.  Check the dependencies
+         section on the NDK WinSock2 download page for the latest
+         information on dependencies. These components are unsupported by
+         Novell. They are provided as a courtesy, but it is strongly
+         suggested that all development be done using LIBC, not CLIB.
+
+         As of June 2005, the WinSock2 components are available at:
+         http://forgeftp.novell.com//ws2comp/
+
+
+      NLM and NetWare libraries for C (including CLIB and XPlat):
+         If you are going to build a CLIB version of OpenSSL, you will
+         need the CLIB headers and imports.  The March, 2001 NDK release or 
+         later is recommended.
+
+         Earlier versions should work but haven't been tested.  In recent
+         versions the import files have been consolidated and function
+         names moved.  This means you may run into link problems
+         (undefined symbols) when using earlier versions.   The functions
+         are available in earlier versions, but you will have to modifiy
+         the make files to include additional import files (see
+         openssl\util\pl\netware.pl).
+
+
+   LIBC - BUILDS:
+   
+      Libraries for C (LIBC) - LIBC headers and import files
+         If you are going to build a LIBC version of OpenSSL, you will
+         need the LIBC headers and imports.  The March 14, 2002 NDK release or
+         later is required.  
+         
+         NOTE: The LIBC SDK includes the necessary WinSock2 support.
+         It is not necessary to download the WinSock2 NDK when building for
+         LIBC. The LIBC SDK also includes the appropriate BSD socket support
+         if configuring to use BSD sockets.
+
+
+BUILDING:
+---------
+Before building, you will need to set a few environment variables.  You can
+set them manually or you can modify the "netware\set_env.bat" file.
+
+The set_env.bat file is a template you can use to set up the path
+and environment variables you will need to build.  Modify the
+various lines to point to YOUR tools and run set_env.bat.
+
+   netware\set_env.bat <target> [compiler]
+
+      target        - "netware-clib" - CLIB NetWare build
+                    - "netware-libc" - LIBC NetWare build
+
+      compiler      - "gnuc"         - GNU GCC Compiler
+                    - "codewarrior"  - MetroWerks CodeWarrior (default)
+
+If you don't use set_env.bat, you will need to set up the following
+environment variables:
+
+   PATH - Set PATH to point to the tools you will use.
+
+   INCLUDE - The location of the NDK include files.
+         
+            CLIB ex: set INCLUDE=c:\ndk\nwsdk\include\nlm
+            LIBC ex: set INCLUDE=c:\ndk\libc\include
+
+   PRELUDE - The absolute path of the prelude object to link with.  For
+            a CLIB build it is recommended you use the "clibpre.o" files shipped
+            with the Metrowerks PDK for NetWare.  For a LIBC build you should 
+            use the "libcpre.o" file delivered with the LIBC NDK components.
+
+            CLIB ex: set PRELUDE=c:\ndk\nwsdk\imports\clibpre.o
+            LIBC ex: set PRELUDE=c:\ndk\libc\imports\libcpre.o
+
+   IMPORTS - The locaton of the NDK import files.
+
+            CLIB ex: set IMPORTS=c:\ndk\nwsdk\imports
+            LIBC ex: set IMPORTS=c:\ndk\libc\imports
+
+
+In order to build, you need to run the Perl scripts to configure the build
+process and generate a make file.  There is a batch file,
+"netware\build.bat", to automate the process.
+
+Build.bat runs the build configuration scripts and generates a make file.
+If an assembly option is specified, it also runs the scripts to generate 
+the assembly code.  Always run build.bat from the "openssl" directory.
+
+   netware\build [target] [debug opts] [assembly opts] [configure opts]
+
+      target        - "netware-clib" - CLIB NetWare build (WinSock Sockets)
+                    - "netware-clib-bsdsock" - CLIB NetWare build (BSD Sockets)
+                    - "netware-libc" - LIBC NetWare build (WinSock Sockets)
+                    - "netware-libc-bsdsock" - LIBC NetWare build (BSD Sockets)
+ 
+      debug opts    - "debug"  - build debug
+
+      assembly opts - "nw-mwasm" - use Metrowerks assembler
+                      "nw-nasm"  - use NASM assembler
+                      "no-asm"   - don't use assembly
+
+      configure opts- all unrecognized arguments are passed to the
+                      perl 'configure' script. See that script for
+                      internal documentation regarding options that
+                      are available.
+
+   examples:
+
+      CLIB build, debug, without assembly:
+         netware\build.bat netware-clib debug no-asm
+
+      LIBC build, non-debug, using NASM assembly, add mdc2 support:
+         netware\build.bat netware-libc nw-nasm enable-mdc2
+
+      LIBC build, BSD sockets, non-debug, without assembly:
+         netware\build.bat netware-libc-bsdsock no-asm
+
+Running build.bat generates a make file to be processed by your make 
+tool (gmake or nmake):
+
+   CLIB ex: gmake -f netware\nlm_clib_dbg.mak 
+   LIBC ex: gmake -f netware\nlm_libc.mak 
+   LIBC ex: gmake -f netware\nlm_libc_bsdsock.mak 
+
+
+You can also run the build scripts manually if you do not want to use the
+build.bat file.  Run the following scripts in the "\openssl"
+subdirectory (in the order listed below):
+
+   perl configure no-asm [other config opts] [netware-clib|netware-libc|netware-libc-bsdsock]
+      configures no assembly build for specified netware environment
+      (CLIB or LIBC).
+
+   perl util\mkfiles.pl >MINFO
+      generates a listing of source files (used by mk1mf)
+
+   perl util\mk1mf.pl no-asm [other config opts] [netware-clib|netware-libc|netware-libc-bsdsock >netware\nlm.mak
+      generates the makefile for NetWare
+
+   gmake -f netware\nlm.mak
+      build with the make tool (nmake.exe also works)
+
+NOTE:  If you are building using the assembly option, you must also run the
+various Perl scripts to generate the assembly files.  See build.bat
+for an example of running the various assembly scripts.  You must use the
+"no-asm" option to build without assembly.  The configure and mk1mf scripts
+also have various other options.  See the scripts for more information.
+
+
+The output from the build is placed in the following directories:
+
+   CLIB Debug build:
+      out_nw_clib.dbg     - static libs & test nlm(s)
+      tmp_nw_clib.dbg     - temporary build files
+      outinc_nw_clib      - necessary include files
+
+   CLIB Non-debug build:
+      out_nw_clib         - static libs & test nlm(s)
+      tmp_nw_clib         - temporary build files
+      outinc_nw_clib      - necesary include files
+
+   LIBC Debug build:
+      out_nw_libc.dbg     - static libs & test nlm(s)
+      tmp_nw_libc.dbg     - temporary build files
+      outinc_nw_libc      - necessary include files
+
+   LIBC Non-debug build:
+      out_nw_libc         - static libs & test nlm(s)
+      tmp_nw_libc         - temporary build files
+      outinc_nw_libc      - necesary include files
+
+
+TESTING:
+--------
+The build process creates the OpenSSL static libs ( crypto.lib, ssl.lib,
+rsaglue.lib ) and several test programs.  You should copy the test programs
+to your NetWare server and run the tests.
+
+The batch file "netware\cpy_tests.bat" will copy all the necessary files
+to your server for testing.  In order to run the batch file, you need a
+drive mapped to your target server.  It will create an "OpenSSL" directory
+on the drive and copy the test files to it.  CAUTION: If a directory with the
+name of "OpenSSL" already exists, it will be deleted.
+
+To run cpy_tests.bat:
+
+   netware\cpy_tests [output directory] [NetWare drive]
+
+      output directory - "out_nw_clib.dbg", "out_nw_libc", etc.
+      NetWare drive    - drive letter of mapped drive
+
+      CLIB ex: netware\cpy_tests out_nw_clib m:
+      LIBC ex: netware\cpy_tests out_nw_libc m:
+
+
+The Perl script, "do_tests.pl", in the "OpenSSL" directory on the server
+should be used to execute the tests.  Before running the script, make sure
+your SEARCH PATH includes the "OpenSSL" directory.  For example, if you
+copied the files to the "sys:" volume you use the command:
+
+   SEARCH ADD SYS:\OPENSSL
+
+
+To run do_tests.pl type (at the console prompt):
+
+   perl \openssl\do_tests.pl [options]
+
+      options:
+         -p    - pause after executing each test
+
+The do_tests.pl script generates a log file "\openssl\test_out\tests.log"
+which should be reviewed for errors.  Any errors will be denoted by the word
+"ERROR" in the log.
+
+DEVELOPING WITH THE OPENSSL SDK:
+--------------------------------
+Now that everything is built and tested, you are ready to use the OpenSSL
+libraries in your development.
+
+There is no real installation procedure, just copy the static libs and
+headers to your build location.  The libs (crypto.lib & ssl.lib) are
+located in the appropriate "out_nw_XXXX" directory 
+(out_nw_clib, out_nw_libc, etc).  
+
+The headers are located in the appropriate "outinc_nw_XXX" directory 
+(outinc_nw_clib, outinc_nw_libc).  
+
+One suggestion is to create the following directory 
+structure for the OpenSSL SDK:
+
+   \openssl
+      |- bin
+      |   |- openssl.nlm
+      |   |- (other tests you want)
+      |
+      |- lib
+      |   | - crypto.lib
+      |   | - ssl.lib
+      |
+      |- include
+      |   | - openssl
+      |   |    | - (all the headers in "outinc_nw\openssl")
+
+
+The program "openssl.nlm" can be very useful.  It has dozens of
+options and you may want to keep it handy for debugging, testing, etc.
+
+When building your apps using OpenSSL, define "NETWARE".  It is needed by
+some of the OpenSSL headers.  One way to do this is with a compile option,
+for example "-DNETWARE".
+
+
+
+NOTES:
+------
+
+Resource leaks in Tests
+------------------------
+Some OpenSSL tests do not clean up resources and NetWare reports
+the resource leaks when the tests unload.  If this really bugs you,
+you can stop the messages by setting the developer option off at the console
+prompt (set developer option = off).  Or better yet, fix the tests to
+clean up the resources!
+
+
+Multi-threaded Development
+---------------------------
+The NetWare version of OpenSSL is thread-safe, however multi-threaded
+applications must provide the necessary locking function callbacks.  This
+is described in doc\threads.doc.  The file "openssl-x.x.x\crypto\threads\mttest.c"
+is a multi-threaded test program and demonstrates the locking functions.
+
+
+What is openssl2.nlm?
+---------------------
+The openssl program has numerous options and can be used for many different
+things.  Many of the options operate in an interactive mode requiring the
+user to enter data.  Because of this, a default screen is created for the
+program.  However, when running the test script it is not desirable to
+have a seperate screen.  Therefore, the build also creates openssl2.nlm.
+Openssl2.nlm is functionally identical but uses the console screen.
+Openssl2 can be used when a non-interactive mode is desired.
+
+NOTE:  There are may other possibilities (command line options, etc)
+which could have been used to address the screen issue.  The openssl2.nlm
+option was chosen because it impacted only the build not the code.
+
+
+Why only static libraries?
+--------------------------
+Globals, globals, and more globals.  The OpenSSL code uses many global
+variables that are allocated and initialized when used for the first time.
+
+On NetWare, most applications (at least historically) run in the kernel.
+When running in the kernel, there is one instance of global variables.
+For regular application type NLM(s) this isn't a problem because they are
+the only ones using the globals.  However, for a library NLM (an NLM which
+exposes functions and has no threads of execution), the globals cause
+problems.  Applications could inadvertently step on each other if they
+change some globals.  Even worse, the first application that triggers a
+global to be allocated and initialized has the allocated memory charged to
+itself.  Now when that application unloads, NetWare will clean up all the
+applicaton's memory.  The global pointer variables inside OpenSSL now
+point to freed memory.  An abend waiting to happen!
+
+To work correctly in the kernel, library NLM(s) that use globals need to
+provide a set of globals (instance data) for each application.  Another
+option is to require the library only be loaded in a protected address
+space along with the application using it.
+
+Modifying the OpenSSL code to provide a set of globals (instance data) for
+each application isn't technically difficult, but due to the large number
+globals it would require substantial code changes and it wasn't done.  Hence,
+the build currently only builds static libraries which are then linked
+into each application.
+
+NOTE:  If you are building a library NLM that uses the OpenSSL static
+libraries, you will still have to deal with the global variable issue.
+This is because when you link in the OpenSSL code you bring in all the
+globals.  One possible solution for the global pointer variables is to
+register memory functions with OpenSSL which allocate memory and charge it
+to your library NLM (see the function CRYPTO_set_mem_functions).  However,
+be aware that now all memory allocated by OpenSSL is charged to your NLM.
+
+
+CodeWarrior Tools and W2K
+---------------------------
+There have been problems reported with the CodeWarrior Linker
+(mwldnlm.exe) in the PDK 2.1 for NetWare when running on Windows 2000.  The
+problems cause the link step to fail.  The only work around is to obtain an
+updated linker from Metrowerks.  It is expected Metrowerks will release
+PDK 3.0 (in beta testing at this time - May, 2001) in the near future which
+will fix these problems.
+
+
+Makefile "vclean"
+------------------
+The generated makefile has a "vclean" target which cleans up the build
+directories.  If you have been building successfully and suddenly
+experience problems, use "vclean" (gmake -f netware\nlm_xxxx.mak vclean) and retry.
+
+
+"Undefined Symbol" Linker errors
+--------------------------------
+There have been linker errors reported when doing a CLIB build.  The problems
+occur because some versions of the CLIB SDK import files inadvertently 
+left out some symbols.  One symbol in particular is "_lrotl".  The missing
+functions are actually delivered in the binaries, but they were left out of
+the import files.  The issues should be fixed in the September 2001 release 
+of the NDK.  If you experience the problems you can temporarily
+work around it by manually adding the missing symbols to your version of 
+"clib.imp".
+
diff --git a/openssl/INSTALL.OS2 b/openssl/INSTALL.OS2
new file mode 100644
index 0000000..530316d
--- /dev/null
+++ b/openssl/INSTALL.OS2
@@ -0,0 +1,31 @@
+ 
+ Installation on OS/2
+ --------------------
+
+ You need to have the following tools installed:
+
+  * EMX GCC
+  * PERL
+  * GNU make
+
+
+ To build the makefile, run
+
+ > os2\os2-emx
+
+ This will configure OpenSSL and create OS2-EMX.mak which you then use to 
+ build the OpenSSL libraries & programs by running
+
+ > make -f os2-emx.mak
+
+ If that finishes successfully you will find the libraries and programs in the
+ "out" directory.
+
+ Alternatively, you can make a dynamic build that puts the library code into
+ crypto.dll and ssl.dll by running
+
+ > make -f os2-emx-dll.mak
+
+ This will build the above mentioned dlls and a matching pair of import
+ libraries in the "out_dll" directory along with the set of test programs
+ and the openssl application.
diff --git a/openssl/INSTALL.VMS b/openssl/INSTALL.VMS
new file mode 100644
index 0000000..e5d43a5
--- /dev/null
+++ b/openssl/INSTALL.VMS
@@ -0,0 +1,293 @@
+			VMS Installation instructions
+			written by Richard Levitte
+			<richard@levitte.org>
+
+
+Intro:
+======
+
+This file is divided in the following parts:
+
+  Requirements			- Mandatory reading.
+  Checking the distribution	- Mandatory reading.
+  Compilation			- Mandatory reading.
+  Logical names			- Mandatory reading.
+  Test				- Mandatory reading.
+  Installation			- Mandatory reading.
+  Backward portability		- Read if it's an issue.
+  Possible bugs or quirks	- A few warnings on things that
+				  may go wrong or may surprise you.
+  TODO				- Things that are to come.
+
+
+Requirements:
+=============
+
+To build and install OpenSSL, you will need:
+
+ * DEC C or some other ANSI C compiler.  VAX C is *not* supported.
+   [Note: OpenSSL has only been tested with DEC C.  Compiling with 
+    a different ANSI C compiler may require some work]
+
+Checking the distribution:
+==========================
+
+There have been reports of places where the distribution didn't quite get
+through, for example if you've copied the tree from a NFS-mounted Unix
+mount point.
+
+The easiest way to check if everything got through as it should is to check
+for one of the following files:
+
+	[.CRYPTO]OPENSSLCONF.H_IN
+	[.CRYPTO]OPENSSLCONF_H.IN
+
+They should never exist both at once, but one of them should (preferably
+the first variant).  If you can't find any of those two, something went
+wrong.
+
+The best way to get a correct distribution is to download the gzipped tar
+file from ftp://ftp.openssl.org/source/, use GUNZIP to uncompress it and
+use VMSTAR to unpack the resulting tar file.
+
+GUNZIP is available in many places on the net.  One of the distribution
+points is the WKU software archive, ftp://ftp.wku.edu/vms/fileserv/ .
+
+VMSTAR is also available in many places on the net.  The recommended place
+to find information about it is http://www.free.lp.se/vmstar/ .
+
+
+Compilation:
+============
+
+I've used the very good command procedures written by Robert Byer
+<byer@mail.all-net.net>, and just slightly modified them, making
+them slightly more general and easier to maintain.
+
+You can actually compile in almost any directory separately.  Look
+for a command procedure name xxx-LIB.COM (in the library directories)
+or MAKExxx.COM (in the program directories) and read the comments at
+the top to understand how to use them.  However, if you want to
+compile all you can get, the simplest is to use MAKEVMS.COM in the top
+directory.  The syntax is the following:
+
+  @MAKEVMS <option> <bits> <debug-p> [<compiler>]
+
+<option> must be one of the following:
+
+      ALL       Just build "everything".
+      CONFIG    Just build the "[.CRYPTO]OPENSSLCONF.H" file.
+      BUILDINF  Just build the "[.INCLUDE]BUILDINF.H" file.
+      SOFTLINKS Just copies some files, to simulate Unix soft links.
+      BUILDALL  Same as ALL, except CONFIG, BUILDINF and SOFTLINKS aren't done.
+      RSAREF    Just build the "[.xxx.EXE.RSAREF]LIBRSAGLUE.OLB" library.
+      CRYPTO    Just build the "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" library.
+      SSL       Just build the "[.xxx.EXE.SSL]LIBSSL.OLB" library.
+      SSL_TASK  Just build the "[.xxx.EXE.SSL]SSL_TASK.EXE" program.
+      TEST      Just build the "[.xxx.EXE.TEST]" test programs for OpenSSL.
+      APPS      Just build the "[.xxx.EXE.APPS]" application programs for OpenSSL.
+
+<bits> must be one of the following:
+
+      ""        compile using default pointer size
+      32        compile using 32 bit pointer size
+      64        compile using 64 bit pointer size
+
+<debug-p> must be one of the following:
+
+      DEBUG     compile with debugging info (will not optimize)
+      NODEBUG   compile without debugging info (will optimize)
+
+<compiler> must be one of the following:
+
+      DECC      For DEC C.
+      GNUC      For GNU C.
+
+
+You will find the crypto library in [.xxx.EXE.CRYPTO] (where xxx is VAX,
+ALPHA or IA64), called SSL_LIBCRYPTO32.OLB or SSL_LIBCRYPTO.OLB depending
+on how it was built.  You will find the SSL library in [.xxx.EXE.SSL],
+named SSL_LIBSSL32.OLB or SSL_LIBSSL.OLB, and you will find a bunch of
+useful programs in [.xxx.EXE.APPS].  However, these shouldn't be used
+right off unless it's just to test them.  For production use, make sure
+you install first, see Installation below.
+
+Note 1: Some programs in this package require a TCP/IP library.
+
+Note 2: if you want to compile the crypto library only, please make sure
+        you have at least done a @MAKEVMS CONFIG, a @MAKEVMS BUILDINF and
+        a @MAKEVMS SOFTLINKS.  A lot of things will break if you don't.
+
+
+Logical names:
+==============
+
+There are a few things that can't currently be given through the command
+line.  Instead, logical names are used.
+
+Currently, the logical names supported are:
+
+      OPENSSL_NO_ASM    with value YES, the assembler parts of OpenSSL will
+                        not be used.  Instead, plain C implementations are
+                        used.  This is good to try if something doesn't work.
+      OPENSSL_NO_'alg'  with value YES, the corresponding crypto algorithm
+                        will not be implemented.  Supported algorithms to
+                        do this with are: RSA, DSA, DH, MD2, MD4, MD5, RIPEMD,
+                        SHA, DES, MDC2, CR2, RC4, RC5, IDEA, BF, CAST, HMAC,
+                        SSL2.  So, for example, having the logical name
+                        OPENSSL_NO_RSA with the value YES means that the
+                        LIBCRYPTO.OLB library will not contain an RSA
+                        implementation.
+
+
+Test:
+=====
+
+Testing is very simple, just do the following:
+
+  @[.TEST]TESTS
+
+If a test fails, try with defining the logical name OPENSSL_NO_ASM (yes,
+it's an ugly hack!) and rebuild. Please send a bug report to
+<openssl-bugs@openssl.org>, including the output of "openssl version -a"
+and of the failed test.
+
+
+Installation:
+=============
+
+Installation is easy, just do the following:
+
+  @INSTALL <root> <bits>
+
+<root> is the directory in which everything will be installed,
+subdirectories, libraries, header files, programs and startup command
+procedures.
+
+<bits> works the same way as for MAKEVMS.COM
+
+N.B.: INSTALL.COM builds a new directory structure, different from
+the directory tree where you have now build OpenSSL.
+
+In the [.VMS] subdirectory of the installation, you will find the
+following command procedures:
+
+  OPENSSL_STARTUP.COM
+
+        defines all needed logical names.  Takes one argument that
+        tells it in what logical name table to insert the logical
+        names.  If you insert if it SYS$MANAGER:SYSTARTUP_VMS.COM, the
+        call should look like this: 
+
+          @openssldev:[openssldir.VMS]OPENSSL_STARTUP "/SYSTEM"
+
+  OPENSSL_UTILS.COM
+
+        sets up the symbols to the applications.  Should be called
+        from for example SYS$MANAGER:SYLOGIN.COM 
+
+  OPENSSL_UNDO.COM
+
+	deassigns the logical names created with OPENSSL_STARTUP.COM.
+
+The logical names that are set up are the following:
+
+  SSLROOT       a dotted concealed logical name pointing at the
+                root directory.
+
+  SSLCERTS      Initially an empty directory, this is the default
+		location for certificate files.
+  SSLPRIVATE	Initially an empty directory, this is the default
+		location for private key files.
+
+  SSLEXE        Contains the openssl binary and a few other utility
+		programs.
+  SSLINCLUDE    Contains the header files needed if you want to
+		compile programs with libcrypto or libssl.
+  SSLLIB        Contains the OpenSSL library files themselves:
+  		- SSL_LIBCRYPTO32.OLB and SSL_LIBSSL32.OLB or
+		- SSL_LIBCRYPTO.OLB and SSL_LIBSSL.OLB
+
+  OPENSSL	Same as SSLINCLUDE.  This is because the standard
+		way to include OpenSSL header files from version
+		0.9.3 and on is:
+
+			#include <openssl/header.h>
+
+		For more info on this issue, see the INSTALL. file
+		(the NOTE in section 4 of "Installation in Detail").
+		You don't need to "deleting old header files"!!!
+
+
+Backward portability:
+=====================
+
+One great problem when you build a library is making sure it will work
+on as many versions of VMS as possible.  Especially, code compiled on
+OpenVMS version 7.x and above tend to be unusable in version 6.x or
+lower, because some C library routines have changed names internally
+(the C programmer won't usually see it, because the old name is
+maintained through C macros).  One obvious solution is to make sure
+you have a development machine with an old enough version of OpenVMS.
+However, if you are stuck with a bunch of Alphas running OpenVMS version
+7.1, you seem to be out of luck.  Fortunately, the DEC C header files
+are cluttered with conditionals that make some declarations and definitions
+dependent on the OpenVMS version or the C library version, *and* you
+can use those macros to simulate older OpenVMS or C library versions,
+by defining the macros _VMS_V6_SOURCE, __VMS_VER and __CTRL_VER with
+correct values.  In the compilation scripts, I've provided the possibility
+for the user to influence the creation of such macros, through a bunch of
+symbols, all having names starting with USER_.  Here's the list of them:
+
+  USER_CCFLAGS		 - Used to give additional qualifiers to the
+			   compiler.  It can't be used to define macros
+			   since the scripts will do such things as well.
+			   To do such things, use USER_CCDEFS.
+  USER_CCDEFS		 - Used to define macros on the command line.  The
+			   value of this symbol will be inserted inside a
+			   /DEFINE=(...).
+  USER_CCDISABLEWARNINGS - Used to disable some warnings.  The value is
+			   inserted inside a /DISABLE=WARNING=(...).
+
+So, to maintain backward compatibility with older VMS versions, do the
+following before you start compiling:
+
+  $ USER_CCDEFS := _VMS_V6_SOURCE=1,__VMS_VER=60000000,__CRTL_VER=60000000
+  $ USER_CCDISABLEWARNINGS := PREOPTW
+
+The USER_CCDISABLEWARNINGS is there because otherwise, DEC C will complain
+that those macros have been changed.
+
+Note: Currently, this is only useful for library compilation.  The
+      programs will still be linked with the current version of the
+      C library shareable image, and will thus complain if they are
+      faced with an older version of the same C library shareable image.
+      This will probably be fixed in a future revision of OpenSSL.
+
+
+Possible bugs or quirks:
+========================
+
+I'm not perfectly sure all the programs will use the SSLCERTS:
+directory by default, it may very well be that you have to give them
+extra arguments.  Please experiment.
+
+
+TODO:
+=====
+
+There are a few things that need to be worked out in the VMS version of
+OpenSSL, still:
+
+- Description files. ("Makefile's" :-))
+- Script code to link an already compiled build tree.
+- A VMSINSTALlable version (way in the future, unless someone else hacks).
+- shareable images (DLL for you Windows folks).
+
+There may be other things that I have missed and that may be desirable.
+Please send mail to <openssl-users@openssl.org> or to me directly if you
+have any ideas.
+
+--
+Richard Levitte <richard@levitte.org>
+2000-02-27, 2011-03-18
diff --git a/openssl/INSTALL.W32 b/openssl/INSTALL.W32
new file mode 100644
index 0000000..d23c4ba
--- /dev/null
+++ b/openssl/INSTALL.W32
@@ -0,0 +1,325 @@
+ 
+ INSTALLATION ON THE WIN32 PLATFORM
+ ----------------------------------
+
+ [Instructions for building for Windows CE can be found in INSTALL.WCE]
+ [Instructions for building for Win64 can be found in INSTALL.W64]
+
+ Here are a few comments about building OpenSSL for Win32 environments,
+ such as Windows NT and Windows 9x. It should be noted though that
+ Windows 9x are not ordinarily tested. Its mention merely means that we
+ attempt to maintain certain programming discipline and pay attention
+ to backward compatibility issues, in other words it's kind of expected
+ to work on Windows 9x, but no regression tests are actually performed.
+
+ On additional note newer OpenSSL versions are compiled and linked with
+ Winsock 2. This means that minimum OS requirement was elevated to NT 4
+ and Windows 98 [there is Winsock 2 update for Windows 95 though].
+
+ - you need Perl for Win32.  Unless you will build on Cygwin, you will need
+   ActiveState Perl, available from http://www.activestate.com/ActivePerl.
+
+ - one of the following C compilers:
+
+  * Visual C++
+  * Borland C
+  * GNU C (Cygwin or MinGW)
+
+- Netwide Assembler, a.k.a. NASM, available from http://nasm.sourceforge.net/
+  is required if you intend to utilize assembler modules. Note that NASM
+  is now the only supported assembler.
+
+ If you are compiling from a tarball or a CVS snapshot then the Win32 files
+ may well be not up to date. This may mean that some "tweaking" is required to
+ get it all to work. See the trouble shooting section later on for if (when?)
+ it goes wrong.
+
+ Visual C++
+ ----------
+
+ If you want to compile in the assembly language routines with Visual
+ C++, then you will need already mentioned Netwide Assembler binary,
+ nasmw.exe or nasm.exe, to be available on your %PATH%.
+
+ Firstly you should run Configure with platform VC-WIN32:
+
+ > perl Configure VC-WIN32 --prefix=c:\some\openssl\dir
+
+ Where the prefix argument specifies where OpenSSL will be installed to.
+
+ Next you need to build the Makefiles and optionally the assembly
+ language files:
+
+ - If you are using NASM then run:
+
+   > ms\do_nasm
+
+ - If you don't want to use the assembly language files at all then run:
+
+   > perl Configure VC-WIN32 no-asm --prefix=c:/some/openssl/dir
+   > ms\do_ms
+
+ If you get errors about things not having numbers assigned then check the
+ troubleshooting section: you probably won't be able to compile it as it
+ stands.
+
+ Then from the VC++ environment at a prompt do:
+
+ > nmake -f ms\ntdll.mak
+
+ If all is well it should compile and you will have some DLLs and
+ executables in out32dll. If you want to try the tests then do:
+ 
+ > nmake -f ms\ntdll.mak test
+
+
+ To install OpenSSL to the specified location do:
+
+ > nmake -f ms\ntdll.mak install
+
+ Tweaks:
+
+ There are various changes you can make to the Win32 compile
+ environment. By default the library is not compiled with debugging
+ symbols. If you use the platform debug-VC-WIN32 instead of VC-WIN32
+ then debugging symbols will be compiled in.
+
+ By default in 1.0.0 OpenSSL will compile builtin ENGINES into the
+ separate shared librariesy. If you specify the "enable-static-engine"
+ option on the command line to Configure the shared library build
+ (ms\ntdll.mak) will compile the engines into libeay32.dll instead.
+
+ The default Win32 environment is to leave out any Windows NT specific
+ features.
+
+ If you want to enable the NT specific features of OpenSSL (currently
+ only the logging BIO) follow the instructions above but call the batch
+ file do_nt.bat instead of do_ms.bat.
+
+ You can also build a static version of the library using the Makefile
+ ms\nt.mak
+
+
+ Borland C++ builder 5
+ ---------------------
+
+ * Configure for building with Borland Builder:
+   > perl Configure BC-32
+
+ * Create the appropriate makefile
+   > ms\do_nasm
+
+ * Build
+   > make -f ms\bcb.mak
+
+ Borland C++ builder 3 and 4
+ ---------------------------
+
+ * Setup PATH. First must be GNU make then bcb4/bin 
+
+ * Run ms\bcb4.bat
+
+ * Run make:
+   > make -f bcb.mak
+
+ GNU C (Cygwin)
+ --------------
+
+ Cygwin implements a Posix/Unix runtime system (cygwin1.dll) on top of
+ Win32 subsystem and provides a bash shell and GNU tools environment.
+ Consequently, a make of OpenSSL with Cygwin is virtually identical to
+ Unix procedure. It is also possible to create Win32 binaries that only
+ use the Microsoft C runtime system (msvcrt.dll or crtdll.dll) using
+ MinGW. MinGW can be used in the Cygwin development environment or in a
+ standalone setup as described in the following section.
+
+ To build OpenSSL using Cygwin:
+
+ * Install Cygwin (see http://cygwin.com/)
+
+ * Install Perl and ensure it is in the path. Both Cygwin perl
+   (5.6.1-2 or newer) and ActivePerl work.
+
+ * Run the Cygwin bash shell
+
+ * $ tar zxvf openssl-x.x.x.tar.gz
+   $ cd openssl-x.x.x
+
+   To build the Cygwin version of OpenSSL:
+
+   $ ./config
+   [...]
+   $ make
+   [...]
+   $ make test
+   $ make install
+
+   This will create a default install in /usr/local/ssl.
+
+   To build the MinGW version (native Windows) in Cygwin:
+
+   $ ./Configure mingw
+   [...]
+   $ make
+   [...]
+   $ make test
+   $ make install
+
+ Cygwin Notes:
+
+ "make test" and normal file operations may fail in directories
+ mounted as text (i.e. mount -t c:\somewhere /home) due to Cygwin
+ stripping of carriage returns. To avoid this ensure that a binary
+ mount is used, e.g. mount -b c:\somewhere /home.
+
+ "bc" is not provided in older Cygwin distribution.  This causes a
+ non-fatal error in "make test" but is otherwise harmless.  If
+ desired and needed, GNU bc can be built with Cygwin without change.
+
+ GNU C (MinGW/MSYS)
+ -------------
+
+ * Compiler and shell environment installation:
+
+   MinGW and MSYS are available from http://www.mingw.org/, both are
+   required. Run the installers and do whatever magic they say it takes
+   to start MSYS bash shell with GNU tools on its PATH.
+
+   N.B. Since source tar-ball can contain symbolic links, it's essential
+   that you use accompanying MSYS tar to unpack the source. It will
+   either handle them in one way or another or fail to extract them,
+   which does the trick too. Latter means that you may safely ignore all
+   "cannot create symlink" messages, as they will be "re-created" at
+   configure stage by copying corresponding files. Alternative programs
+   were observed to create empty files instead, which results in build
+   failure.
+
+ * Compile OpenSSL:
+
+   $ ./config
+   [...]
+   $ make
+   [...]
+   $ make test
+
+   This will create the library and binaries in root source directory
+   and openssl.exe application in apps directory.
+
+   It is also possible to cross-compile it on Linux by configuring
+   with './Configure --cross-compile-prefix=i386-mingw32- mingw ...'.
+   'make test' is naturally not applicable then.
+
+   libcrypto.a and libssl.a are the static libraries. To use the DLLs,
+   link with libeay32.a and libssl32.a instead.
+
+   See troubleshooting if you get error messages about functions not
+   having a number assigned.
+
+ Installation
+ ------------
+
+ If you used the Cygwin procedure above, you have already installed and
+ can skip this section.  For all other procedures, there's currently no real
+ installation procedure for Win32.  There are, however, some suggestions:
+
+    - do nothing.  The include files are found in the inc32/ subdirectory,
+      all binaries are found in out32dll/ or out32/ depending if you built
+      dynamic or static libraries.
+
+    - do as is written in INSTALL.Win32 that comes with modssl:
+
+	$ md c:\openssl 
+	$ md c:\openssl\bin
+	$ md c:\openssl\lib
+	$ md c:\openssl\include
+	$ md c:\openssl\include\openssl
+	$ copy /b inc32\openssl\*       c:\openssl\include\openssl
+	$ copy /b out32dll\ssleay32.lib c:\openssl\lib
+	$ copy /b out32dll\libeay32.lib c:\openssl\lib
+	$ copy /b out32dll\ssleay32.dll c:\openssl\bin
+	$ copy /b out32dll\libeay32.dll c:\openssl\bin
+	$ copy /b out32dll\openssl.exe  c:\openssl\bin
+
+      Of course, you can choose another device than c:.  C: is used here
+      because that's usually the first (and often only) harddisk device.
+      Note: in the modssl INSTALL.Win32, p: is used rather than c:.
+
+
+ Troubleshooting
+ ---------------
+
+ Since the Win32 build is only occasionally tested it may not always compile
+ cleanly.  If you get an error about functions not having numbers assigned
+ when you run ms\do_ms then this means the Win32 ordinal files are not up to
+ date. You can do:
+
+ > perl util\mkdef.pl crypto ssl update
+
+ then ms\do_XXX should not give a warning any more. However the numbers that
+ get assigned by this technique may not match those that eventually get
+ assigned in the CVS tree: so anything linked against this version of the
+ library may need to be recompiled.
+
+ If you get errors about unresolved symbols there are several possible
+ causes.
+
+ If this happens when the DLL is being linked and you have disabled some
+ ciphers then it is possible the DEF file generator hasn't removed all
+ the disabled symbols: the easiest solution is to edit the DEF files manually
+ to delete them. The DEF files are ms\libeay32.def ms\ssleay32.def.
+
+ Another cause is if you missed or ignored the errors about missing numbers
+ mentioned above.
+
+ If you get warnings in the code then the compilation will halt.
+
+ The default Makefile for Win32 halts whenever any warnings occur. Since VC++
+ has its own ideas about warnings which don't always match up to other
+ environments this can happen. The best fix is to edit the file with the
+ warning in and fix it. Alternatively you can turn off the halt on warnings by
+ editing the CFLAG line in the Makefile and deleting the /WX option.
+
+ You might get compilation errors. Again you will have to fix these or report
+ them.
+
+ One final comment about compiling applications linked to the OpenSSL library.
+ If you don't use the multithreaded DLL runtime library (/MD option) your
+ program will almost certainly crash because malloc gets confused -- the
+ OpenSSL DLLs are statically linked to one version, the application must
+ not use a different one.  You might be able to work around such problems
+ by adding CRYPTO_malloc_init() to your program before any calls to the
+ OpenSSL libraries: This tells the OpenSSL libraries to use the same
+ malloc(), free() and realloc() as the application.  However there are many
+ standard library functions used by OpenSSL that call malloc() internally
+ (e.g. fopen()), and OpenSSL cannot change these; so in general you cannot
+ rely on CRYPTO_malloc_init() solving your problem, and you should
+ consistently use the multithreaded library.
+
+ Linking your application
+ ------------------------
+
+ If you link with static OpenSSL libraries [those built with ms/nt.mak],
+ then you're expected to additionally link your application with
+ WS2_32.LIB, ADVAPI32.LIB, GDI32.LIB and USER32.LIB. Those developing
+ non-interactive service applications might feel concerned about linking
+ with the latter two, as they are justly associated with interactive
+ desktop, which is not available to service processes. The toolkit is
+ designed to detect in which context it's currently executed, GUI,
+ console app or service, and act accordingly, namely whether or not to
+ actually make GUI calls. Additionally those who wish to
+ /DELAYLOAD:GDI32.DLL and /DELAYLOAD:USER32.DLL and actually keep them
+ off service process should consider implementing and exporting from
+ .exe image in question own _OPENSSL_isservice not relying on USER32.DLL.
+ E.g., on Windows Vista and later you could:
+
+	__declspec(dllexport) __cdecl BOOL _OPENSSL_isservice(void)
+	{   DWORD sess;
+	    if (ProcessIdToSessionId(GetCurrentProcessId(),&sess))
+	        return sess==0;
+	    return FALSE;
+	}
+
+ If you link with OpenSSL .DLLs, then you're expected to include into
+ your application code small "shim" snippet, which provides glue between
+ OpenSSL BIO layer and your compiler run-time. Look up OPENSSL_Applink
+ reference page for further details.
diff --git a/openssl/INSTALL.W64 b/openssl/INSTALL.W64
new file mode 100644
index 0000000..9fa7a19
--- /dev/null
+++ b/openssl/INSTALL.W64
@@ -0,0 +1,66 @@
+
+ INSTALLATION ON THE WIN64 PLATFORM
+ ----------------------------------
+
+ Caveat lector
+ -------------
+
+ As of moment of this writing Win64 support is classified "initial"
+ for the following reasons.
+
+ - No assembler modules are engaged upon initial 0.9.8 release.
+ - API might change within 0.9.8 life-span, *but* in a manner which
+   doesn't break backward binary compatibility. Or in other words,
+   application programs compiled with initial 0.9.8 headers will
+   be expected to work with future minor release .DLL without need
+   to re-compile, even if future minor release features modified API.
+ - Above mentioned API modifications have everything to do with
+   elimination of a number of limitations, which are normally
+   considered inherent to 32-bit platforms. Which in turn is why they
+   are treated as limitations on 64-bit platform such as Win64:-)
+   The current list comprises [but not necessarily limited to]:
+
+   - null-terminated strings may not be longer than 2G-1 bytes,
+     longer strings are treated as zero-length;
+   - dynamically and *internally* allocated chunks can't be larger
+     than 2G-1 bytes;
+   - inability to encrypt/decrypt chunks of data larger than 4GB
+     [it's possibly to *hash* chunks of arbitrary size through];
+
+   Neither of these is actually big deal and hardly encountered
+   in real-life applications.
+
+ Compiling procedure
+ -------------------
+
+ You will need Perl. You can run under Cygwin or you can download
+ ActiveState Perl from http://www.activestate.com/ActivePerl.
+
+ You will need Microsoft Platform SDK, available for download at
+ http://www.microsoft.com/msdownload/platformsdk/sdkupdate/. As per
+ April 2005 Platform SDK is equipped with Win64 compilers, as well
+ as assemblers, but it might change in the future.
+
+ To build for Win64/x64:
+
+ > perl Configure VC-WIN64A
+ > ms\do_win64a
+ > nmake -f ms\ntdll.mak
+ > cd out32dll
+ > ..\ms\test
+
+ To build for Win64/IA64:
+
+ > perl Configure VC-WIN64I
+ > ms\do_win64i
+ > nmake -f ms\ntdll.mak
+ > cd out32dll
+ > ..\ms\test
+
+ Naturally test-suite itself has to be executed on the target platform.
+
+ Installation
+ ------------
+
+ TBD, for now see INSTALL.W32.
+
diff --git a/openssl/INSTALL.WCE b/openssl/INSTALL.WCE
new file mode 100644
index 0000000..d78c61a
--- /dev/null
+++ b/openssl/INSTALL.WCE
@@ -0,0 +1,95 @@
+ 
+ INSTALLATION FOR THE WINDOWS CE PLATFORM
+ ----------------------------------------
+
+ Building OpenSSL for Windows CE requires the following external tools:
+
+  * Microsoft eMbedded Visual C++ 3.0 or later
+  * Appropriate SDK might be required
+  * Perl for Win32 [commonly recommended ActiveState Perl is available
+    from http://www.activestate.com/Products/ActivePerl/]
+
+  * wcecompat compatibility library available at
+    http://www.essemer.com.au/windowsce/
+  * Optionally ceutils for running automated tests (same location)
+
+  _or_
+
+  * PocketConsole driver and PortSDK available at
+    http://www.symbolictools.de/public/pocketconsole/
+  * CMD command interpreter (same location)
+
+ As Windows CE support in OpenSSL relies on 3rd party compatibility
+ library, it's appropriate to check corresponding URL for updates. For
+ example if you choose wcecompat, note that as for the moment of this
+ writing version 1.2 is available and actually required for WCE 4.2
+ and newer platforms. All wcecompat issues should be directed to
+ www.essemer.com.au.
+
+ Why compatibility library at all? The C Runtime Library implementation
+ for Windows CE that is included with Microsoft eMbedded Visual C++ is
+ incomplete and in some places incorrect.  Compatibility library plugs
+ the holes and tries to bring the Windows CE CRT to [more] usable level.
+ Most gaping hole in CRT is support for stdin/stdout/stderr IO, which
+ proposed compatibility libraries solve in two different ways: wcecompat
+ redirects IO to active sync link, while PortSDK - to NT-like console
+ driver on the handheld itself.
+
+ Building
+ --------
+
+ Setup the eMbedded Visual C++ environment.  There are batch files for doing
+ this installed with eVC++.  For an ARM processor, for example, execute:
+
+ > "C:\Program Files\Microsoft eMbedded Tools\EVC\WCE300\BIN\WCEARM.BAT"
+
+ Next pick compatibility library according to your preferences.
+
+ 1. To choose wcecompat set up WCECOMPAT environment variable pointing
+    at the location of wcecompat tree "root":
+
+    > set WCECOMPAT=C:\wcecompat
+    > set PORTSDK_LIBPATH=
+
+ 2. To choose PortSDK set up PORTSDK_LIBPATH to point at hardware-
+    specific location where your portlib.lib is installed:
+
+    > set PORTSDK_LIBPATH=C:\PortSDK\lib\ARM
+    > set WCECOMPAT=
+
+ Note that you may not set both variables.
+
+ Next you should run Configure:
+
+ > perl Configure VC-CE
+
+ Next you need to build the Makefiles:
+
+ > ms\do_ms
+
+ If you get errors about things not having numbers assigned then check the
+ troubleshooting section in INSTALL.W32: you probably won't be able to compile
+ it as it stands.
+
+ Then from the VC++ environment at a prompt do:
+
+   > nmake -f ms\cedll.mak
+
+ [note that static builds are not supported under CE]
+
+ If all is well it should compile and you will have some DLLs and executables
+ in out32dll*. 
+
+ <<< everyting below needs revision in respect to wcecompat vs. PortSDK >>>
+
+ If you want
+ to try the tests then make sure the ceutils are in the path and do:
+ 
+ > cd out32
+ > ..\ms\testce
+
+ This will copy each of the test programs to the Windows CE device and execute
+ them, displaying the output of the tests on this computer.  The output should
+ look similar to the output produced by running the tests for a regular Windows
+ build.
+
diff --git a/openssl/LICENSE b/openssl/LICENSE
new file mode 100644
index 0000000..e47d101
--- /dev/null
+++ b/openssl/LICENSE
@@ -0,0 +1,127 @@
+
+  LICENSE ISSUES
+  ==============
+
+  The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
+  the OpenSSL License and the original SSLeay license apply to the toolkit.
+  See below for the actual license texts. Actually both licenses are BSD-style
+  Open Source licenses. In case of any license issues related to OpenSSL
+  please contact openssl-core@openssl.org.
+
+  OpenSSL License
+  ---------------
+
+/* ====================================================================
+ * Copyright (c) 1998-2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+ Original SSLeay License
+ -----------------------
+
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
diff --git a/openssl/MacOS/GUSI_Init.cpp b/openssl/MacOS/GUSI_Init.cpp
new file mode 100644
index 0000000..d8223db
--- /dev/null
+++ b/openssl/MacOS/GUSI_Init.cpp
@@ -0,0 +1,62 @@
+/**************** BEGIN GUSI CONFIGURATION ****************************
+ *
+ * GUSI Configuration section generated by GUSI Configurator
+ * last modified: Wed Jan  5 20:33:51 2000
+ *
+ * This section will be overwritten by the next run of Configurator.
+ */
+
+#define GUSI_SOURCE
+#include <GUSIConfig.h>
+#include <sys/cdefs.h>
+
+/* Declarations of Socket Factories */
+
+__BEGIN_DECLS
+void GUSIwithInetSockets();
+void GUSIwithLocalSockets();
+void GUSIwithMTInetSockets();
+void GUSIwithMTTcpSockets();
+void GUSIwithMTUdpSockets();
+void GUSIwithOTInetSockets();
+void GUSIwithOTTcpSockets();
+void GUSIwithOTUdpSockets();
+void GUSIwithPPCSockets();
+void GUSISetupFactories();
+__END_DECLS
+
+/* Configure Socket Factories */
+
+void GUSISetupFactories()
+{
+#ifdef GUSISetupFactories_BeginHook
+	GUSISetupFactories_BeginHook
+#endif
+	GUSIwithInetSockets();
+#ifdef GUSISetupFactories_EndHook
+	GUSISetupFactories_EndHook
+#endif
+}
+
+/* Declarations of File Devices */
+
+__BEGIN_DECLS
+void GUSIwithDConSockets();
+void GUSIwithNullSockets();
+void GUSISetupDevices();
+__END_DECLS
+
+/* Configure File Devices */
+
+void GUSISetupDevices()
+{
+#ifdef GUSISetupDevices_BeginHook
+	GUSISetupDevices_BeginHook
+#endif
+	GUSIwithNullSockets();
+#ifdef GUSISetupDevices_EndHook
+	GUSISetupDevices_EndHook
+#endif
+}
+
+/**************** END GUSI CONFIGURATION *************************/
diff --git a/openssl/MacOS/GetHTTPS.src/CPStringUtils.cpp b/openssl/MacOS/GetHTTPS.src/CPStringUtils.cpp
new file mode 100644
index 0000000..617aae2
--- /dev/null
+++ b/openssl/MacOS/GetHTTPS.src/CPStringUtils.cpp
@@ -0,0 +1,2753 @@
+/* ====================================================================
+ * Copyright (c) 1998-1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+ 
+ 
+ 
+ #include "CPStringUtils.hpp"
+#include "ErrorHandling.hpp"
+
+
+
+#define kNumberFormatString			"\p########0.00#######;-########0.00#######"
+
+
+
+//	Useful utility functions which could be optimized a whole lot
+
+
+void CopyPStrToCStr(const unsigned char *thePStr,char *theCStr,const int maxCStrLength)
+{
+int		i,numPChars;
+
+
+	if (thePStr != nil && theCStr != nil && maxCStrLength > 0)
+	{
+		numPChars = thePStr[0];
+		
+		for (i = 0;;i++)
+		{
+			if (i >= numPChars || i >= maxCStrLength - 1)
+			{
+				theCStr[i] = 0;
+				
+				break;
+			}
+			
+			else
+			{
+				theCStr[i] = thePStr[i + 1];
+			}
+		}
+	}
+}
+
+
+void CopyPStrToPStr(const unsigned char *theSrcPStr,unsigned char *theDstPStr,const int maxDstStrLength)
+{
+int		theMaxDstStrLength;
+
+	
+	theMaxDstStrLength = maxDstStrLength;
+	
+	
+	if (theDstPStr != nil && theSrcPStr != nil && theMaxDstStrLength > 0)
+	{
+		if (theMaxDstStrLength > 255)
+		{
+			theMaxDstStrLength = 255;
+		}
+		
+		
+		if (theMaxDstStrLength - 1 < theSrcPStr[0])
+		{
+			BlockMove(theSrcPStr + 1,theDstPStr + 1,theMaxDstStrLength - 1);
+			
+			theDstPStr[0] = theMaxDstStrLength - 1;
+		}
+		
+		else
+		{
+			BlockMove(theSrcPStr,theDstPStr,theSrcPStr[0] + 1);
+		}
+	}
+}
+
+
+void CopyCStrToCStr(const char *theSrcCStr,char *theDstCStr,const int maxDstStrLength)
+{
+int		i;
+
+
+	if (theDstCStr != nil && theSrcCStr != nil && maxDstStrLength > 0)
+	{
+		for (i = 0;;i++)
+		{
+			if (theSrcCStr[i] == 0 || i >= maxDstStrLength - 1)
+			{
+				theDstCStr[i] = 0;
+				
+				break;
+			}
+			
+			else
+			{
+				theDstCStr[i] = theSrcCStr[i];
+			}
+		}
+	}
+}
+
+
+
+void CopyCSubstrToCStr(const char *theSrcCStr,const int maxCharsToCopy,char *theDstCStr,const int maxDstStrLength)
+{
+int		i;
+
+
+	if (theDstCStr != nil && theSrcCStr != nil && maxDstStrLength > 0)
+	{
+		for (i = 0;;i++)
+		{
+			if (theSrcCStr[i] == 0 || i >= maxDstStrLength - 1 || i >= maxCharsToCopy)
+			{
+				theDstCStr[i] = 0;
+				
+				break;
+			}
+			
+			else
+			{
+				theDstCStr[i] = theSrcCStr[i];
+			}
+		}
+	}
+}
+
+
+
+void CopyCSubstrToPStr(const char *theSrcCStr,const int maxCharsToCopy,unsigned char *theDstPStr,const int maxDstStrLength)
+{
+int		i;
+int		theMaxDstStrLength;
+
+	
+	theMaxDstStrLength = maxDstStrLength;
+
+	if (theDstPStr != nil && theSrcCStr != nil && theMaxDstStrLength > 0)
+	{
+		if (theMaxDstStrLength > 255)
+		{
+			theMaxDstStrLength = 255;
+		}
+		
+		
+		for (i = 0;;i++)
+		{
+			if (theSrcCStr[i] == 0 || i >= theMaxDstStrLength - 1 || i >= maxCharsToCopy)
+			{
+				theDstPStr[0] = i;
+				
+				break;
+			}
+			
+			else
+			{
+				theDstPStr[i + 1] = theSrcCStr[i];
+			}
+		}
+	}
+}
+
+
+
+void CopyCStrToPStr(const char *theSrcCStr,unsigned char *theDstPStr,const int maxDstStrLength)
+{
+int		i;
+int		theMaxDstStrLength;
+
+	
+	theMaxDstStrLength = maxDstStrLength;
+
+	if (theDstPStr != nil && theSrcCStr != nil && theMaxDstStrLength > 0)
+	{
+		if (theMaxDstStrLength > 255)
+		{
+			theMaxDstStrLength = 255;
+		}
+		
+		
+		for (i = 0;;i++)
+		{
+			if (i >= theMaxDstStrLength - 1 || theSrcCStr[i] == 0)
+			{
+				theDstPStr[0] = i;
+				
+				break;
+			}
+			
+			else
+			{
+				theDstPStr[i + 1] = theSrcCStr[i];
+			}
+		}
+	}
+}
+
+
+void ConcatPStrToCStr(const unsigned char *thePStr,char *theCStr,const int maxCStrLength)
+{
+int		i,numPChars,cStrLength;
+
+
+	if (thePStr != nil && theCStr != nil && maxCStrLength > 0)
+	{
+		for (cStrLength = 0;theCStr[cStrLength] != 0;cStrLength++)
+		{
+		
+		}
+		
+
+		numPChars = thePStr[0];
+		
+		
+		for (i = 0;;i++)
+		{
+			if (i >= numPChars || cStrLength >= maxCStrLength - 1)
+			{
+				theCStr[cStrLength++] = 0;
+				
+				break;
+			}
+			
+			else
+			{
+				theCStr[cStrLength++] = thePStr[i + 1];
+			}
+		}
+	}
+}
+
+
+
+void ConcatPStrToPStr(const unsigned char *theSrcPStr,unsigned char *theDstPStr,const int maxDstStrLength)
+{
+int		theMaxDstStrLength;
+
+	
+	theMaxDstStrLength = maxDstStrLength;
+	
+	if (theSrcPStr != nil && theDstPStr != nil && theMaxDstStrLength > 0)
+	{
+		if (theMaxDstStrLength > 255)
+		{
+			theMaxDstStrLength = 255;
+		}
+		
+		
+		if (theMaxDstStrLength - theDstPStr[0] - 1 < theSrcPStr[0])
+		{
+			BlockMove(theSrcPStr + 1,theDstPStr + theDstPStr[0] + 1,theMaxDstStrLength - 1 - theDstPStr[0]);
+			
+			theDstPStr[0] = theMaxDstStrLength - 1;
+		}
+		
+		else
+		{
+			BlockMove(theSrcPStr + 1,theDstPStr + theDstPStr[0] + 1,theSrcPStr[0]);
+			
+			theDstPStr[0] += theSrcPStr[0];
+		}
+	}
+}
+
+
+
+void ConcatCStrToPStr(const char *theSrcCStr,unsigned char *theDstPStr,const int maxDstStrLength)
+{
+int		i,thePStrLength;
+int		theMaxDstStrLength;
+
+	
+	theMaxDstStrLength = maxDstStrLength;
+
+	if (theSrcCStr != nil && theDstPStr != nil && theMaxDstStrLength > 0)
+	{
+		if (theMaxDstStrLength > 255)
+		{
+			theMaxDstStrLength = 255;
+		}
+		
+		
+		thePStrLength = theDstPStr[0];
+		
+		for (i = 0;;i++)
+		{
+			if (theSrcCStr[i] == 0 || thePStrLength >= theMaxDstStrLength - 1)
+			{
+				theDstPStr[0] = thePStrLength;
+				
+				break;
+			}
+			
+			else
+			{
+				theDstPStr[thePStrLength + 1] = theSrcCStr[i];
+				
+				thePStrLength++;
+			}
+		}
+	}
+}
+
+
+
+void ConcatCStrToCStr(const char *theSrcCStr,char *theDstCStr,const int maxCStrLength)
+{
+int		cStrLength;
+
+
+	if (theSrcCStr != nil && theDstCStr != nil && maxCStrLength > 0)
+	{
+		for (cStrLength = 0;theDstCStr[cStrLength] != 0;cStrLength++)
+		{
+		
+		}
+		
+
+		for (;;)
+		{
+			if (*theSrcCStr == 0 || cStrLength >= maxCStrLength - 1)
+			{
+				theDstCStr[cStrLength++] = 0;
+				
+				break;
+			}
+			
+			else
+			{
+				theDstCStr[cStrLength++] = *theSrcCStr++;
+			}
+		}
+	}
+}
+
+
+
+void ConcatCharToCStr(const char theChar,char *theDstCStr,const int maxCStrLength)
+{
+int		cStrLength;
+
+
+	if (theDstCStr != nil && maxCStrLength > 0)
+	{
+		cStrLength = CStrLength(theDstCStr);
+		
+		if (cStrLength < maxCStrLength - 1)
+		{
+			theDstCStr[cStrLength++] = theChar;
+			theDstCStr[cStrLength++] = '\0';
+		}
+	}
+}
+
+
+
+void ConcatCharToPStr(const char theChar,unsigned char *theDstPStr,const int maxPStrLength)
+{
+int		pStrLength;
+
+
+	if (theDstPStr != nil && maxPStrLength > 0)
+	{
+		pStrLength = PStrLength(theDstPStr);
+		
+		if (pStrLength < maxPStrLength - 1 && pStrLength < 255)
+		{
+			theDstPStr[pStrLength + 1] = theChar;
+			theDstPStr[0] += 1;
+		}
+	}
+}
+
+
+
+
+int CompareCStrs(const char *theFirstCStr,const char *theSecondCStr,const Boolean ignoreCase)
+{
+int		returnValue;
+char	firstChar,secondChar;
+
+	
+	returnValue = 0;
+	
+	
+	if (theFirstCStr != nil && theSecondCStr != nil)
+	{
+		for (;;)
+		{
+			firstChar = *theFirstCStr;
+			secondChar = *theSecondCStr;
+			
+			if (ignoreCase == true)
+			{
+				if (firstChar >= 'A' && firstChar <= 'Z')
+				{
+					firstChar = 'a' + (firstChar - 'A');
+				}
+				
+				if (secondChar >= 'A' && secondChar <= 'Z')
+				{
+					secondChar = 'a' + (secondChar - 'A');
+				}
+			}
+			
+			
+			if (firstChar == 0 && secondChar != 0)
+			{
+				returnValue = -1;
+				
+				break;
+			}
+			
+			else if (firstChar != 0 && secondChar == 0)
+			{
+				returnValue = 1;
+				
+				break;
+			}
+			
+			else if (firstChar == 0 && secondChar == 0)
+			{
+				returnValue = 0;
+				
+				break;
+			}
+			
+			else if (firstChar < secondChar)
+			{
+				returnValue = -1;
+				
+				break;
+			}
+			
+			else if (firstChar > secondChar)
+			{
+				returnValue = 1;
+				
+				break;
+			}
+			
+			theFirstCStr++;
+			theSecondCStr++;
+		}
+	}
+	
+	
+	return(returnValue);
+}
+
+
+
+Boolean CStrsAreEqual(const char *theFirstCStr,const char *theSecondCStr,const Boolean ignoreCase)
+{
+	if (CompareCStrs(theFirstCStr,theSecondCStr,ignoreCase) == 0)
+	{
+		return true;
+	}
+	
+	else
+	{
+		return false;
+	}
+}
+
+
+Boolean PStrsAreEqual(const unsigned char *theFirstPStr,const unsigned char *theSecondPStr,const Boolean ignoreCase)
+{
+	if (ComparePStrs(theFirstPStr,theSecondPStr,ignoreCase) == 0)
+	{
+		return true;
+	}
+	
+	else
+	{
+		return false;
+	}
+}
+
+
+
+int ComparePStrs(const unsigned char *theFirstPStr,const unsigned char *theSecondPStr,const Boolean ignoreCase)
+{
+int		i,returnValue;
+char	firstChar,secondChar;
+
+	
+	returnValue = 0;
+	
+	
+	if (theFirstPStr != nil && theSecondPStr != nil)
+	{
+		for (i = 1;;i++)
+		{
+			firstChar = theFirstPStr[i];
+			secondChar = theSecondPStr[i];
+
+			if (ignoreCase == true)
+			{
+				if (firstChar >= 'A' && firstChar <= 'Z')
+				{
+					firstChar = 'a' + (firstChar - 'A');
+				}
+				
+				if (secondChar >= 'A' && secondChar <= 'Z')
+				{
+					secondChar = 'a' + (secondChar - 'A');
+				}
+			}
+
+
+			if (theFirstPStr[0] < i && theSecondPStr[0] >= i)
+			{
+				returnValue = -1;
+				
+				break;
+			}
+			
+			else if (theFirstPStr[0] >= i && theSecondPStr[0] < i)
+			{
+				returnValue = 1;
+				
+				break;
+			}
+			
+			else if (theFirstPStr[0] < i && theSecondPStr[0] < i)
+			{
+				returnValue = 0;
+				
+				break;
+			}
+			
+			else if (firstChar < secondChar)
+			{
+				returnValue = -1;
+				
+				break;
+			}
+			
+			else if (firstChar > secondChar)
+			{
+				returnValue = 1;
+				
+				break;
+			}
+		}
+	}
+	
+	
+	return(returnValue);
+}
+
+
+
+int CompareCStrToPStr(const char *theCStr,const unsigned char *thePStr,const Boolean ignoreCase)
+{
+int		returnValue;
+char	tempString[256];
+
+	
+	returnValue = 0;
+	
+	if (theCStr != nil && thePStr != nil)
+	{
+		CopyPStrToCStr(thePStr,tempString,sizeof(tempString));
+		
+		returnValue = CompareCStrs(theCStr,tempString,ignoreCase);
+	}
+	
+	
+	return(returnValue);
+}
+
+
+
+void ConcatLongIntToCStr(const long theNum,char *theCStr,const int maxCStrLength,const int numDigits)
+{
+Str255 		theStr255;
+
+
+	NumToString(theNum,theStr255);
+
+
+	if (numDigits > 0)
+	{
+	int 	charsToInsert;
+	
+		
+		charsToInsert = numDigits - PStrLength(theStr255);
+		
+		if (charsToInsert > 0)
+		{
+		char	tempString[256];
+			
+			CopyCStrToCStr("",tempString,sizeof(tempString));
+			
+			for (;charsToInsert > 0;charsToInsert--)
+			{
+				ConcatCStrToCStr("0",tempString,sizeof(tempString));
+			}
+			
+			ConcatPStrToCStr(theStr255,tempString,sizeof(tempString));
+			
+			CopyCStrToPStr(tempString,theStr255,sizeof(theStr255));
+		}
+	}
+
+
+	ConcatPStrToCStr(theStr255,theCStr,maxCStrLength);
+}
+
+
+
+
+void ConcatLongIntToPStr(const long theNum,unsigned char *thePStr,const int maxPStrLength,const int numDigits)
+{
+Str255 		theStr255;
+
+
+	NumToString(theNum,theStr255);
+
+
+	if (numDigits > 0)
+	{
+	int 	charsToInsert;
+	
+		
+		charsToInsert = numDigits - PStrLength(theStr255);
+		
+		if (charsToInsert > 0)
+		{
+		char	tempString[256];
+			
+			CopyCStrToCStr("",tempString,sizeof(tempString));
+			
+			for (;charsToInsert > 0;charsToInsert--)
+			{
+				ConcatCStrToCStr("0",tempString,sizeof(tempString));
+			}
+			
+			ConcatPStrToCStr(theStr255,tempString,sizeof(tempString));
+			
+			CopyCStrToPStr(tempString,theStr255,sizeof(theStr255));
+		}
+	}
+
+
+	ConcatPStrToPStr(theStr255,thePStr,maxPStrLength);
+}
+
+
+
+void CopyCStrAndConcatLongIntToCStr(const char *theSrcCStr,const long theNum,char *theDstCStr,const int maxDstStrLength)
+{
+	CopyCStrToCStr(theSrcCStr,theDstCStr,maxDstStrLength);
+	
+	ConcatLongIntToCStr(theNum,theDstCStr,maxDstStrLength);
+}
+
+
+
+void CopyLongIntToCStr(const long theNum,char *theCStr,const int maxCStrLength,const int numDigits)
+{
+Str255 		theStr255;
+
+
+	NumToString(theNum,theStr255);
+
+
+	if (numDigits > 0)
+	{
+	int 	charsToInsert;
+	
+		
+		charsToInsert = numDigits - PStrLength(theStr255);
+		
+		if (charsToInsert > 0)
+		{
+		char	tempString[256];
+			
+			CopyCStrToCStr("",tempString,sizeof(tempString));
+			
+			for (;charsToInsert > 0;charsToInsert--)
+			{
+				ConcatCStrToCStr("0",tempString,sizeof(tempString));
+			}
+			
+			ConcatPStrToCStr(theStr255,tempString,sizeof(tempString));
+			
+			CopyCStrToPStr(tempString,theStr255,sizeof(theStr255));
+		}
+	}
+
+
+	CopyPStrToCStr(theStr255,theCStr,maxCStrLength);
+}
+
+
+
+
+
+void CopyUnsignedLongIntToCStr(const unsigned long theNum,char *theCStr,const int maxCStrLength)
+{
+char			tempString[256];
+int				srcCharIndex,dstCharIndex;
+unsigned long	tempNum,quotient,remainder;
+
+	
+	if (theNum == 0)
+	{
+		CopyCStrToCStr("0",theCStr,maxCStrLength);
+	}
+	
+	else
+	{
+		srcCharIndex = 0;
+		
+		tempNum = theNum;
+		
+		for (;;)
+		{
+			if (srcCharIndex >= sizeof(tempString) - 1 || tempNum == 0)
+			{
+				for (dstCharIndex = 0;;)
+				{
+					if (dstCharIndex >= maxCStrLength - 1 || srcCharIndex <= 0)
+					{
+						theCStr[dstCharIndex] = 0;
+						
+						break;
+					}
+					
+					theCStr[dstCharIndex++] = tempString[--srcCharIndex];
+				}
+				
+				break;
+			}
+			
+
+			quotient = tempNum / 10;
+			
+			remainder = tempNum - (quotient * 10);
+			
+			tempString[srcCharIndex] = '0' + remainder;
+			
+			srcCharIndex++;
+			
+			tempNum = quotient;
+		}
+	}
+}
+
+
+
+
+void CopyLongIntToPStr(const long theNum,unsigned char *thePStr,const int maxPStrLength,const int numDigits)
+{
+char	tempString[256];
+
+
+	CopyLongIntToCStr(theNum,tempString,sizeof(tempString),numDigits);
+	
+	CopyCStrToPStr(tempString,thePStr,maxPStrLength);
+}
+
+
+
+OSErr CopyLongIntToNewHandle(const long inTheLongInt,Handle *theHandle)
+{
+OSErr		errCode = noErr;
+char		tempString[32];
+	
+	
+	CopyLongIntToCStr(inTheLongInt,tempString,sizeof(tempString));
+	
+	errCode = CopyCStrToNewHandle(tempString,theHandle);
+
+	return(errCode);
+}
+
+
+OSErr CopyLongIntToExistingHandle(const long inTheLongInt,Handle theHandle)
+{
+OSErr		errCode = noErr;
+char		tempString[32];
+	
+	
+	CopyLongIntToCStr(inTheLongInt,tempString,sizeof(tempString));
+	
+	errCode = CopyCStrToExistingHandle(tempString,theHandle);
+
+	return(errCode);
+}
+
+
+
+
+OSErr CopyCStrToExistingHandle(const char *theCString,Handle theHandle)
+{
+OSErr	errCode = noErr;
+long	stringLength;
+
+	
+	if (theCString == nil)
+	{
+		SetErrorMessageAndBail(("CopyCStrToExistingHandle: Bad parameter, theCString == nil"));
+	}
+
+	if (theHandle == nil)
+	{
+		SetErrorMessageAndBail(("CopyCStrToExistingHandle: Bad parameter, theHandle == nil"));
+	}
+
+	if (*theHandle == nil)
+	{
+		SetErrorMessageAndBail(("CopyCStrToExistingHandle: Bad parameter, *theHandle == nil"));
+	}
+
+
+
+	stringLength = CStrLength(theCString) + 1;
+	
+	SetHandleSize(theHandle,stringLength);
+	
+	if (GetHandleSize(theHandle) < stringLength)
+	{
+		SetErrorMessageAndLongIntAndBail("CopyCStrToExistingHandle: Can't set Handle size, MemError() = ",MemError());
+	}
+	
+	
+	::BlockMove(theCString,*theHandle,stringLength);
+	
+
+EXITPOINT:
+	
+	return(errCode);
+}
+
+
+
+
+
+OSErr CopyCStrToNewHandle(const char *theCString,Handle *theHandle)
+{
+OSErr	errCode = noErr;
+long	stringLength;
+
+	
+	if (theCString == nil)
+	{
+		SetErrorMessageAndBail(("CopyCStrToNewHandle: Bad parameter, theCString == nil"));
+	}
+
+	if (theHandle == nil)
+	{
+		SetErrorMessageAndBail(("CopyCStrToNewHandle: Bad parameter, theHandle == nil"));
+	}
+
+
+
+	stringLength = CStrLength(theCString) + 1;
+	
+	*theHandle = NewHandle(stringLength);
+	
+	if (*theHandle == nil)
+	{
+		SetErrorMessageAndLongIntAndBail("CopyCStrToNewHandle: Can't allocate Handle, MemError() = ",MemError());
+	}
+	
+	
+	::BlockMove(theCString,**theHandle,stringLength);
+	
+
+EXITPOINT:
+	
+	return(errCode);
+}
+
+
+
+OSErr CopyPStrToNewHandle(const unsigned char *thePString,Handle *theHandle)
+{
+OSErr	errCode = noErr;
+long	stringLength;
+
+	
+	if (thePString == nil)
+	{
+		SetErrorMessageAndBail(("CopyPStrToNewHandle: Bad parameter, thePString == nil"));
+	}
+
+	if (theHandle == nil)
+	{
+		SetErrorMessageAndBail(("CopyPStrToNewHandle: Bad parameter, theHandle == nil"));
+	}
+
+
+
+	stringLength = PStrLength(thePString) + 1;
+	
+	*theHandle = NewHandle(stringLength);
+	
+	if (*theHandle == nil)
+	{
+		SetErrorMessageAndLongIntAndBail("CopyPStrToNewHandle: Can't allocate Handle, MemError() = ",MemError());
+	}
+	
+	
+	if (stringLength > 1)
+	{
+		BlockMove(thePString + 1,**theHandle,stringLength - 1);
+	}
+	
+	(**theHandle)[stringLength - 1] = 0;
+	
+
+EXITPOINT:
+	
+	return(errCode);
+}
+
+
+OSErr AppendPStrToHandle(const unsigned char *thePString,Handle theHandle,long *currentLength)
+{
+OSErr		errCode = noErr;
+char		tempString[256];
+
+	
+	CopyPStrToCStr(thePString,tempString,sizeof(tempString));
+	
+	errCode = AppendCStrToHandle(tempString,theHandle,currentLength);
+	
+
+EXITPOINT:
+	
+	return(errCode);
+}
+
+
+
+OSErr AppendCStrToHandle(const char *theCString,Handle theHandle,long *currentLength,long *maxLength)
+{
+OSErr		errCode = noErr;
+long		handleMaxLength,handleCurrentLength,stringLength,byteCount;
+
+
+	if (theCString == nil)
+	{
+		SetErrorMessageAndBail(("AppendCStrToHandle: Bad parameter, theCString == nil"));
+	}
+
+	if (theHandle == nil)
+	{
+		SetErrorMessageAndBail(("AppendCStrToHandle: Bad parameter, theHandle == nil"));
+	}
+	
+	
+	if (maxLength != nil)
+	{
+		handleMaxLength = *maxLength;
+	}
+	
+	else
+	{
+		handleMaxLength = GetHandleSize(theHandle);
+	}
+	
+	
+	if (currentLength != nil && *currentLength >= 0)
+	{
+		handleCurrentLength = *currentLength;
+	}
+	
+	else
+	{
+		handleCurrentLength = CStrLength(*theHandle);
+	}
+	
+	
+	stringLength = CStrLength(theCString);
+	
+	byteCount = handleCurrentLength + stringLength + 1;
+	
+	if (byteCount > handleMaxLength)
+	{
+		SetHandleSize(theHandle,handleCurrentLength + stringLength + 1);
+		
+		if (maxLength != nil)
+		{
+			*maxLength = GetHandleSize(theHandle);
+			
+			handleMaxLength = *maxLength;
+		}
+		
+		else
+		{
+			handleMaxLength = GetHandleSize(theHandle);
+		}
+
+		if (byteCount > handleMaxLength)
+		{
+			SetErrorMessageAndLongIntAndBail("AppendCStrToHandle: Can't increase Handle allocation, MemError() = ",MemError());
+		}
+	}
+	
+	
+	BlockMove(theCString,*theHandle + handleCurrentLength,stringLength + 1);
+	
+	
+	if (currentLength != nil)
+	{
+		*currentLength += stringLength;
+	}
+
+
+	errCode = noErr;
+	
+	
+EXITPOINT:
+
+	return(errCode);
+}
+
+
+
+OSErr AppendCharsToHandle(const char *theChars,const int numChars,Handle theHandle,long *currentLength,long *maxLength)
+{
+OSErr		errCode = noErr;
+long		handleMaxLength,handleCurrentLength,byteCount;
+
+
+	if (theChars == nil)
+	{
+		SetErrorMessageAndBail(("AppendCharsToHandle: Bad parameter, theChars == nil"));
+	}
+
+	if (theHandle == nil)
+	{
+		SetErrorMessageAndBail(("AppendCharsToHandle: Bad parameter, theHandle == nil"));
+	}
+	
+	
+	if (maxLength != nil)
+	{
+		handleMaxLength = *maxLength;
+	}
+	
+	else
+	{
+		handleMaxLength = GetHandleSize(theHandle);
+	}
+	
+	
+	if (currentLength != nil && *currentLength >= 0)
+	{
+		handleCurrentLength = *currentLength;
+	}
+	
+	else
+	{
+		handleCurrentLength = CStrLength(*theHandle);
+	}
+	
+	
+	byteCount = handleCurrentLength + numChars + 1;
+	
+	if (byteCount > handleMaxLength)
+	{
+		SetHandleSize(theHandle,handleCurrentLength + numChars + 1);
+		
+		if (maxLength != nil)
+		{
+			*maxLength = GetHandleSize(theHandle);
+			
+			handleMaxLength = *maxLength;
+		}
+		
+		else
+		{
+			handleMaxLength = GetHandleSize(theHandle);
+		}
+
+		if (byteCount > handleMaxLength)
+		{
+			SetErrorMessageAndLongIntAndBail("AppendCharsToHandle: Can't increase Handle allocation, MemError() = ",MemError());
+		}
+	}
+	
+	
+	BlockMove(theChars,*theHandle + handleCurrentLength,numChars);
+	
+	(*theHandle)[handleCurrentLength + numChars] = '\0';
+	
+	if (currentLength != nil)
+	{
+		*currentLength += numChars;
+	}
+
+
+	errCode = noErr;
+	
+	
+EXITPOINT:
+
+	return(errCode);
+}
+
+
+
+OSErr AppendLongIntToHandle(const long inTheLongInt,Handle theHandle,long *currentLength)
+{
+OSErr		errCode = noErr;
+char		tempString[32];
+	
+	
+	CopyLongIntToCStr(inTheLongInt,tempString,sizeof(tempString));
+	
+	errCode = AppendCStrToHandle(tempString,theHandle,currentLength);
+
+	return(errCode);
+}
+
+
+
+
+long CStrLength(const char *theCString)
+{
+long	cStrLength = 0;
+
+	
+	if (theCString != nil)
+	{
+		for (cStrLength = 0;theCString[cStrLength] != 0;cStrLength++)
+		{
+		
+		}
+	}
+	
+	
+	return(cStrLength);
+}
+
+
+
+long PStrLength(const unsigned char *thePString)
+{
+long	pStrLength = 0;
+
+	
+	if (thePString != nil)
+	{
+		pStrLength = thePString[0];
+	}
+	
+	
+	return(pStrLength);
+}
+
+
+
+
+
+void ZeroMem(void *theMemPtr,const unsigned long numBytes)
+{
+unsigned char	*theBytePtr;
+unsigned long	*theLongPtr;
+unsigned long	numSingleBytes;
+unsigned long	theNumBytes;
+
+	
+	theNumBytes = numBytes;
+	
+	if (theMemPtr != nil && theNumBytes > 0)
+	{
+		theBytePtr = (unsigned char	*) theMemPtr;
+		
+		numSingleBytes = (unsigned long) theBytePtr & 0x0003;
+		
+		while (numSingleBytes > 0)
+		{
+			*theBytePtr++ = 0;
+			
+			theNumBytes--;
+			numSingleBytes--;
+		}
+		
+
+		theLongPtr = (unsigned long	*) theBytePtr;
+		
+		while (theNumBytes >= 4)
+		{
+			*theLongPtr++ = 0;
+			
+			theNumBytes -= 4;
+		}
+		
+		
+		theBytePtr = (unsigned char	*) theLongPtr;
+		
+		while (theNumBytes > 0)
+		{
+			*theBytePtr++ = 0;
+			
+			theNumBytes--;
+		}
+	}
+}
+
+
+
+
+char *FindCharInCStr(const char theChar,const char *theCString)
+{
+char	*theStringSearchPtr;
+
+	
+	theStringSearchPtr = (char	*) theCString;
+	
+	if (theStringSearchPtr != nil)
+	{
+		while (*theStringSearchPtr != '\0' && *theStringSearchPtr != theChar)
+		{
+			theStringSearchPtr++;
+		}
+		
+		if (*theStringSearchPtr == '\0')
+		{
+			theStringSearchPtr = nil;
+		}
+	}
+	
+	return(theStringSearchPtr);
+}
+
+
+
+long FindCharOffsetInCStr(const char theChar,const char *theCString,const Boolean inIgnoreCase)
+{
+long	theOffset = -1;
+
+
+	if (theCString != nil)
+	{
+		theOffset = 0;
+		
+
+		if (inIgnoreCase)
+		{
+		char	searchChar = theChar;
+		
+			if (searchChar >= 'a' && searchChar <= 'z')
+			{
+				searchChar = searchChar - 'a' + 'A';
+			}
+			
+			
+			while (*theCString != 0)
+			{
+			char	currentChar = *theCString;
+			
+				if (currentChar >= 'a' && currentChar <= 'z')
+				{
+					currentChar = currentChar - 'a' + 'A';
+				}
+			
+				if (currentChar == searchChar)
+				{
+					break;
+				}
+				
+				theCString++;
+				theOffset++;
+			}
+		}
+		
+		else
+		{
+			while (*theCString != 0 && *theCString != theChar)
+			{
+				theCString++;
+				theOffset++;
+			}
+		}
+		
+		if (*theCString == 0)
+		{
+			theOffset = -1;
+		}
+	}
+	
+	return(theOffset);
+}
+
+
+long FindCStrOffsetInCStr(const char *theCSubstring,const char *theCString,const Boolean inIgnoreCase)
+{
+long	theOffset = -1;
+
+
+	if (theCSubstring != nil && theCString != nil)
+	{
+		for (theOffset = 0;;theOffset++)
+		{
+			if (theCString[theOffset] == 0)
+			{
+				theOffset = -1;
+				
+				goto EXITPOINT;
+			}
+			
+			
+			for (const char	*tempSubstringPtr = theCSubstring,*tempCStringPtr = theCString + theOffset;;tempSubstringPtr++,tempCStringPtr++)
+			{
+				if (*tempSubstringPtr == 0)
+				{
+					goto EXITPOINT;
+				}
+				
+				else if (*tempCStringPtr == 0)
+				{
+					break;
+				}
+			
+			char	searchChar = *tempSubstringPtr;
+			char	currentChar = *tempCStringPtr;
+			
+				if (inIgnoreCase && searchChar >= 'a' && searchChar <= 'z')
+				{
+					searchChar = searchChar - 'a' + 'A';
+				}
+				
+				if (inIgnoreCase && currentChar >= 'a' && currentChar <= 'z')
+				{
+					currentChar = currentChar - 'a' + 'A';
+				}
+				
+				if (currentChar != searchChar)
+				{
+					break;
+				}
+			}
+		}
+		
+		theOffset = -1;
+	}
+
+
+EXITPOINT:
+	
+	return(theOffset);
+}
+
+
+
+void InsertCStrIntoCStr(const char *theSrcCStr,const int theInsertionOffset,char *theDstCStr,const int maxDstStrLength)
+{
+int		currentLength;
+int		insertLength;
+int		numCharsToInsert;
+int		numCharsToShift;
+
+	
+	if (theDstCStr != nil && theSrcCStr != nil && maxDstStrLength > 0 && theInsertionOffset < maxDstStrLength - 1)
+	{
+		currentLength = CStrLength(theDstCStr);
+		
+		insertLength = CStrLength(theSrcCStr);
+		
+
+		if (theInsertionOffset + insertLength < maxDstStrLength - 1)
+		{
+			numCharsToInsert = insertLength;
+		}
+		
+		else
+		{
+			numCharsToInsert = maxDstStrLength - 1 - theInsertionOffset;
+		}
+		
+
+		if (numCharsToInsert + currentLength < maxDstStrLength - 1)
+		{
+			numCharsToShift = currentLength - theInsertionOffset;
+		}
+		
+		else
+		{
+			numCharsToShift = maxDstStrLength - 1 - theInsertionOffset - numCharsToInsert;
+		}
+
+		
+		if (numCharsToShift > 0)
+		{
+			BlockMove(theDstCStr + theInsertionOffset,theDstCStr + theInsertionOffset + numCharsToInsert,numCharsToShift);
+		}
+		
+		if (numCharsToInsert > 0)
+		{
+			BlockMove(theSrcCStr,theDstCStr + theInsertionOffset,numCharsToInsert);
+		}
+		
+		theDstCStr[theInsertionOffset + numCharsToInsert + numCharsToShift] = 0;
+	}
+}
+
+
+
+void InsertPStrIntoCStr(const unsigned char *theSrcPStr,const int theInsertionOffset,char *theDstCStr,const int maxDstStrLength)
+{
+int		currentLength;
+int		insertLength;
+int		numCharsToInsert;
+int		numCharsToShift;
+
+	
+	if (theDstCStr != nil && theSrcPStr != nil && maxDstStrLength > 0 && theInsertionOffset < maxDstStrLength - 1)
+	{
+		currentLength = CStrLength(theDstCStr);
+		
+		insertLength = PStrLength(theSrcPStr);
+		
+
+		if (theInsertionOffset + insertLength < maxDstStrLength - 1)
+		{
+			numCharsToInsert = insertLength;
+		}
+		
+		else
+		{
+			numCharsToInsert = maxDstStrLength - 1 - theInsertionOffset;
+		}
+		
+
+		if (numCharsToInsert + currentLength < maxDstStrLength - 1)
+		{
+			numCharsToShift = currentLength - theInsertionOffset;
+		}
+		
+		else
+		{
+			numCharsToShift = maxDstStrLength - 1 - theInsertionOffset - numCharsToInsert;
+		}
+
+		
+		if (numCharsToShift > 0)
+		{
+			BlockMove(theDstCStr + theInsertionOffset,theDstCStr + theInsertionOffset + numCharsToInsert,numCharsToShift);
+		}
+		
+		if (numCharsToInsert > 0)
+		{
+			BlockMove(theSrcPStr + 1,theDstCStr + theInsertionOffset,numCharsToInsert);
+		}
+		
+		theDstCStr[theInsertionOffset + numCharsToInsert + numCharsToShift] = 0;
+	}
+}
+
+
+
+OSErr InsertCStrIntoHandle(const char *theCString,Handle theHandle,const long inInsertOffset)
+{
+OSErr	errCode;
+int		currentLength;
+int		insertLength;
+
+	
+	SetErrorMessageAndBailIfNil(theCString,"InsertCStrIntoHandle: Bad parameter, theCString == nil");
+
+	SetErrorMessageAndBailIfNil(theHandle,"InsertCStrIntoHandle: Bad parameter, theHandle == nil");
+	
+	currentLength = CStrLength(*theHandle);
+	
+	if (currentLength + 1 > ::GetHandleSize(theHandle))
+	{
+		SetErrorMessageAndBail("InsertCStrIntoHandle: Handle has been overflowed");
+	}
+	
+	if (inInsertOffset > currentLength)
+	{
+		SetErrorMessageAndBail("InsertCStrIntoHandle: Insertion offset is greater than string length");
+	}
+	
+	insertLength = CStrLength(theCString);
+	
+	::SetHandleSize(theHandle,currentLength + 1 + insertLength);
+	
+	if (::GetHandleSize(theHandle) < currentLength + 1 + insertLength)
+	{
+		SetErrorMessageAndLongIntAndBail("InsertCStrIntoHandle: Can't expand storage for Handle, MemError() = ",MemError());
+	}
+	
+	::BlockMove(*theHandle + inInsertOffset,*theHandle + inInsertOffset + insertLength,currentLength - inInsertOffset + 1);
+	
+	::BlockMove(theCString,*theHandle + inInsertOffset,insertLength);
+
+
+	errCode = noErr;
+	
+	
+EXITPOINT:
+
+	return(errCode);
+}
+
+
+
+
+void CopyCStrAndInsert1LongIntIntoCStr(const char *theSrcCStr,const long theNum,char *theDstCStr,const int maxDstStrLength)
+{
+	CopyCStrAndInsertCStrLongIntIntoCStr(theSrcCStr,nil,theNum,theDstCStr,maxDstStrLength);
+}
+
+
+void CopyCStrAndInsert2LongIntsIntoCStr(const char *theSrcCStr,const long long1,const long long2,char *theDstCStr,const int maxDstStrLength)
+{
+const long	theLongInts[] = { long1,long2 };
+
+	CopyCStrAndInsertCStrsLongIntsIntoCStr(theSrcCStr,nil,theLongInts,theDstCStr,maxDstStrLength);
+}
+
+
+void CopyCStrAndInsert3LongIntsIntoCStr(const char *theSrcCStr,const long long1,const long long2,const long long3,char *theDstCStr,const int maxDstStrLength)
+{
+const long	theLongInts[] = { long1,long2,long3 };
+
+	CopyCStrAndInsertCStrsLongIntsIntoCStr(theSrcCStr,nil,theLongInts,theDstCStr,maxDstStrLength);
+}
+
+
+void CopyCStrAndInsertCStrIntoCStr(const char *theSrcCStr,const char *theInsertCStr,char *theDstCStr,const int maxDstStrLength)
+{
+const char	*theCStrs[2] = { theInsertCStr,nil };
+
+	CopyCStrAndInsertCStrsLongIntsIntoCStr(theSrcCStr,theCStrs,nil,theDstCStr,maxDstStrLength);
+}
+
+
+
+void CopyCStrAndInsertCStrLongIntIntoCStr(const char *theSrcCStr,const char *theInsertCStr,const long theNum,char *theDstCStr,const int maxDstStrLength)
+{
+const char	*theCStrs[2] = { theInsertCStr,nil };
+const long	theLongInts[1] = { theNum };
+
+	CopyCStrAndInsertCStrsLongIntsIntoCStr(theSrcCStr,theCStrs,theLongInts,theDstCStr,maxDstStrLength);
+}
+
+
+
+void CopyCStrAndInsertCStrsLongIntsIntoCStr(const char *theSrcCStr,const char **theInsertCStrs,const long *theLongInts,char *theDstCStr,const int maxDstStrLength)
+{
+int			dstCharIndex,srcCharIndex,theMaxDstStrLength;
+int			theCStrIndex = 0;
+int			theLongIntIndex = 0;
+
+	
+	theMaxDstStrLength = maxDstStrLength;
+	
+	if (theDstCStr != nil && theSrcCStr != nil && theMaxDstStrLength > 0)
+	{
+		dstCharIndex = 0;
+		
+		srcCharIndex = 0;
+		
+		
+		//	Allow room for NULL at end of string
+		
+		theMaxDstStrLength--;
+		
+		
+		for (;;)
+		{
+			//	Hit end of buffer?
+			
+			if (dstCharIndex >= theMaxDstStrLength)
+			{
+				theDstCStr[dstCharIndex++] = 0;
+				
+				goto EXITPOINT;
+			}
+			
+			//	End of source string?
+			
+			else if (theSrcCStr[srcCharIndex] == 0)
+			{
+				theDstCStr[dstCharIndex++] = 0;
+				
+				goto EXITPOINT;
+			}
+			
+			//	Did we find a '%s'?
+			
+			else if (theInsertCStrs != nil && theInsertCStrs[theCStrIndex] != nil && theSrcCStr[srcCharIndex] == '%' && theSrcCStr[srcCharIndex + 1] == 's')
+			{
+				//	Skip over the '%s'
+				
+				srcCharIndex += 2;
+				
+				
+				//	Terminate the dest string and then concat the string
+				
+				theDstCStr[dstCharIndex] = 0;
+				
+				ConcatCStrToCStr(theInsertCStrs[theCStrIndex],theDstCStr,theMaxDstStrLength);
+				
+				dstCharIndex = CStrLength(theDstCStr);
+				
+				theCStrIndex++;
+			}
+			
+			//	Did we find a '%ld'?
+			
+			else if (theLongInts != nil && theSrcCStr[srcCharIndex] == '%' && theSrcCStr[srcCharIndex + 1] == 'l' && theSrcCStr[srcCharIndex + 2] == 'd')
+			{
+				//	Skip over the '%ld'
+				
+				srcCharIndex += 3;
+				
+				
+				//	Terminate the dest string and then concat the number
+				
+				theDstCStr[dstCharIndex] = 0;
+				
+				ConcatLongIntToCStr(theLongInts[theLongIntIndex],theDstCStr,theMaxDstStrLength);
+				
+				theLongIntIndex++;
+				
+				dstCharIndex = CStrLength(theDstCStr);
+			}
+			
+			else
+			{
+				theDstCStr[dstCharIndex++] = theSrcCStr[srcCharIndex++];
+			}
+		}
+	}
+
+
+
+EXITPOINT:
+
+	return;
+}
+
+
+
+
+
+OSErr CopyCStrAndInsertCStrLongIntIntoHandle(const char *theSrcCStr,const char *theInsertCStr,const long theNum,Handle *theHandle)
+{
+OSErr	errCode;
+long	byteCount;
+
+	
+	if (theHandle != nil)
+	{
+		byteCount = CStrLength(theSrcCStr) + CStrLength(theInsertCStr) + 32;
+		
+		*theHandle = NewHandle(byteCount);
+		
+		if (*theHandle == nil)
+		{
+			SetErrorMessageAndLongIntAndBail("CopyCStrAndInsertCStrLongIntIntoHandle: Can't allocate Handle, MemError() = ",MemError());
+		}
+		
+		
+		HLock(*theHandle);
+		
+		CopyCStrAndInsertCStrLongIntIntoCStr(theSrcCStr,theInsertCStr,theNum,**theHandle,byteCount);
+		
+		HUnlock(*theHandle);
+	}
+	
+	errCode = noErr;
+	
+	
+EXITPOINT:
+
+	return(errCode);
+}
+
+
+
+
+
+OSErr CopyIndexedWordToCStr(char *theSrcCStr,int whichWord,char *theDstCStr,int maxDstCStrLength)
+{
+OSErr		errCode;
+char		*srcCharPtr,*dstCharPtr;
+int			wordCount;
+int			byteCount;
+
+
+	if (theSrcCStr == nil)
+	{
+		SetErrorMessageAndBail(("CopyIndexedWordToCStr: Bad parameter, theSrcCStr == nil"));
+	}
+	
+	if (theDstCStr == nil)
+	{
+		SetErrorMessageAndBail(("CopyIndexedWordToCStr: Bad parameter, theDstCStr == nil"));
+	}
+	
+	if (whichWord < 0)
+	{
+		SetErrorMessageAndBail(("CopyIndexedWordToCStr: Bad parameter, whichWord < 0"));
+	}
+	
+	if (maxDstCStrLength <= 0)
+	{
+		SetErrorMessageAndBail(("CopyIndexedWordToCStr: Bad parameter, maxDstCStrLength <= 0"));
+	}
+
+	
+	*theDstCStr = '\0';
+	
+	srcCharPtr = theSrcCStr;
+
+	while (*srcCharPtr == ' ' || *srcCharPtr == '\t')
+	{
+		srcCharPtr++;
+	}
+	
+
+	for (wordCount = 0;wordCount < whichWord;wordCount++)
+	{
+		while (*srcCharPtr != ' ' && *srcCharPtr != '\t' && *srcCharPtr != '\r' && *srcCharPtr != '\n' && *srcCharPtr != '\0')
+		{
+			srcCharPtr++;
+		}
+		
+		if (*srcCharPtr == '\r' || *srcCharPtr == '\n' || *srcCharPtr == '\0')
+		{
+			errCode = noErr;
+			
+			goto EXITPOINT;
+		}
+
+		while (*srcCharPtr == ' ' || *srcCharPtr == '\t')
+		{
+			srcCharPtr++;
+		}
+		
+		if (*srcCharPtr == '\r' || *srcCharPtr == '\n' || *srcCharPtr == '\0')
+		{
+			errCode = noErr;
+			
+			goto EXITPOINT;
+		}
+	}
+
+
+	dstCharPtr = theDstCStr;
+	byteCount = 0;
+	
+	
+	for(;;)
+	{
+		if (byteCount >= maxDstCStrLength - 1 || *srcCharPtr == '\0' || *srcCharPtr == ' ' || *srcCharPtr == '\t' || *srcCharPtr == '\r' || *srcCharPtr == '\n')
+		{
+			*dstCharPtr = '\0';
+			break;
+		}
+		
+		*dstCharPtr++ = *srcCharPtr++;
+		
+		byteCount++;
+	}
+
+
+	errCode = noErr;
+
+
+EXITPOINT:
+
+	return(errCode);
+}
+
+
+
+
+
+OSErr CopyIndexedWordToNewHandle(char *theSrcCStr,int whichWord,Handle *outTheHandle)
+{
+OSErr		errCode;
+char		*srcCharPtr;
+int			wordCount;
+int			byteCount;
+
+
+	if (theSrcCStr == nil)
+	{
+		SetErrorMessageAndBail(("CopyIndexedWordToNewHandle: Bad parameter, theSrcCStr == nil"));
+	}
+	
+	if (outTheHandle == nil)
+	{
+		SetErrorMessageAndBail(("CopyIndexedWordToNewHandle: Bad parameter, outTheHandle == nil"));
+	}
+	
+	if (whichWord < 0)
+	{
+		SetErrorMessageAndBail(("CopyIndexedWordToNewHandle: Bad parameter, whichWord < 0"));
+	}
+
+	
+	*outTheHandle = nil;
+	
+
+	srcCharPtr = theSrcCStr;
+
+	while (*srcCharPtr == ' ' || *srcCharPtr == '\t')
+	{
+		srcCharPtr++;
+	}
+	
+
+	for (wordCount = 0;wordCount < whichWord;wordCount++)
+	{
+		while (*srcCharPtr != ' ' && *srcCharPtr != '\t' && *srcCharPtr != '\r' && *srcCharPtr != '\n' && *srcCharPtr != '\0')
+		{
+			srcCharPtr++;
+		}
+		
+		if (*srcCharPtr == '\r' || *srcCharPtr == '\n' || *srcCharPtr == '\0')
+		{
+			break;
+		}
+
+		while (*srcCharPtr == ' ' || *srcCharPtr == '\t')
+		{
+			srcCharPtr++;
+		}
+		
+		if (*srcCharPtr == '\r' || *srcCharPtr == '\n' || *srcCharPtr == '\0')
+		{
+			break;
+		}
+	}
+
+
+	for (byteCount = 0;;byteCount++)
+	{
+		if (srcCharPtr[byteCount] == ' ' || srcCharPtr[byteCount] == '\t' || srcCharPtr[byteCount] == '\r' || srcCharPtr[byteCount] == '\n' || srcCharPtr[byteCount] == '\0')
+		{
+			break;
+		}
+	}
+
+	
+	*outTheHandle = NewHandle(byteCount + 1);
+	
+	if (*outTheHandle == nil)
+	{
+		SetErrorMessageAndLongIntAndBail("CopyIndexedWordToNewHandle: Can't allocate Handle, MemError() = ",MemError());
+	}
+	
+	
+	::BlockMove(srcCharPtr,**outTheHandle,byteCount);
+	
+	(**outTheHandle)[byteCount] = '\0';
+
+	errCode = noErr;
+
+
+EXITPOINT:
+
+	return(errCode);
+}
+
+
+
+OSErr CopyIndexedLineToCStr(const char *theSrcCStr,int inWhichLine,int *lineEndIndex,Boolean *gotLastLine,char *theDstCStr,const int maxDstCStrLength)
+{
+OSErr		errCode;
+int			theCurrentLine;
+int			theCurrentLineOffset;
+int			theEOSOffset;
+
+
+	if (theSrcCStr == nil)
+	{
+		SetErrorMessageAndBail(("CopyIndexedLineToCStr: Bad parameter, theSrcCStr == nil"));
+	}
+	
+	if (theDstCStr == nil)
+	{
+		SetErrorMessageAndBail(("CopyIndexedLineToCStr: Bad parameter, theDstCStr == nil"));
+	}
+	
+	if (inWhichLine < 0)
+	{
+		SetErrorMessageAndBail(("CopyIndexedLineToCStr: Bad parameter, inWhichLine < 0"));
+	}
+	
+	if (maxDstCStrLength <= 0)
+	{
+		SetErrorMessageAndBail(("CopyIndexedLineToCStr: Bad parameter, maxDstCStrLength <= 0"));
+	}
+	
+	
+	if (gotLastLine != nil)
+	{
+		*gotLastLine = false;
+	}
+
+	
+	*theDstCStr = 0;
+	
+	theCurrentLineOffset = 0;
+	
+	theCurrentLine = 0;
+	
+	
+	while (theCurrentLine < inWhichLine)
+	{
+		while (theSrcCStr[theCurrentLineOffset] != '\r' && theSrcCStr[theCurrentLineOffset] != 0)
+		{
+			theCurrentLineOffset++;
+		}
+		
+		if (theSrcCStr[theCurrentLineOffset] == 0)
+		{
+			break;
+		}
+		
+		theCurrentLineOffset++;
+		theCurrentLine++;
+	}
+		
+	if (theSrcCStr[theCurrentLineOffset] == 0)
+	{
+		SetErrorMessageAndLongIntAndBail("CopyIndexedLineToCStr: Too few lines in source text, can't get line ",inWhichLine);
+	}
+
+
+	theEOSOffset = FindCharOffsetInCStr('\r',theSrcCStr + theCurrentLineOffset);
+	
+	if (theEOSOffset >= 0)
+	{
+		CopyCSubstrToCStr(theSrcCStr + theCurrentLineOffset,theEOSOffset,theDstCStr,maxDstCStrLength);
+		
+		if (gotLastLine != nil)
+		{
+			*gotLastLine = false;
+		}
+	
+		if (lineEndIndex != nil)
+		{
+			*lineEndIndex = theEOSOffset;
+		}
+	}
+	
+	else
+	{
+		theEOSOffset = CStrLength(theSrcCStr + theCurrentLineOffset);
+
+		CopyCSubstrToCStr(theSrcCStr + theCurrentLineOffset,theEOSOffset,theDstCStr,maxDstCStrLength);
+		
+		if (gotLastLine != nil)
+		{
+			*gotLastLine = true;
+		}
+	
+		if (lineEndIndex != nil)
+		{
+			*lineEndIndex = theEOSOffset;
+		}
+	}
+	
+
+	errCode = noErr;
+
+
+EXITPOINT:
+
+	return(errCode);
+}
+
+
+
+OSErr CopyIndexedLineToNewHandle(const char *theSrcCStr,int inWhichLine,Handle *outNewHandle)
+{
+OSErr		errCode;
+int			theCurrentLine;
+int			theCurrentLineOffset;
+int			byteCount;
+
+
+	SetErrorMessageAndBailIfNil(theSrcCStr,"CopyIndexedLineToNewHandle: Bad parameter, theSrcCStr == nil");
+	SetErrorMessageAndBailIfNil(outNewHandle,"CopyIndexedLineToNewHandle: Bad parameter, outNewHandle == nil");
+	
+	if (inWhichLine < 0)
+	{
+		SetErrorMessageAndBail(("CopyIndexedLineToNewHandle: Bad parameter, inWhichLine < 0"));
+	}
+	
+
+	theCurrentLineOffset = 0;
+	
+	theCurrentLine = 0;
+	
+	
+	while (theCurrentLine < inWhichLine)
+	{
+		while (theSrcCStr[theCurrentLineOffset] != '\r' && theSrcCStr[theCurrentLineOffset] != '\0')
+		{
+			theCurrentLineOffset++;
+		}
+		
+		if (theSrcCStr[theCurrentLineOffset] == '\0')
+		{
+			break;
+		}
+		
+		theCurrentLineOffset++;
+		theCurrentLine++;
+	}
+		
+	if (theSrcCStr[theCurrentLineOffset] == '\0')
+	{
+		SetErrorMessageAndLongIntAndBail("CopyIndexedLineToNewHandle: Too few lines in source text, can't get line #",inWhichLine);
+	}
+
+	
+	byteCount = 0;
+	
+	while (theSrcCStr[theCurrentLineOffset + byteCount] != '\r' && theSrcCStr[theCurrentLineOffset + byteCount] != '\0')
+	{
+		byteCount++;
+	}
+		
+	
+	*outNewHandle = NewHandle(byteCount + 1);
+	
+	if (*outNewHandle == nil)
+	{
+		SetErrorMessageAndLongIntAndBail("CopyIndexedLineToNewHandle: Can't allocate Handle, MemError() = ",MemError());
+	}
+	
+	::BlockMove(theSrcCStr + theCurrentLineOffset,**outNewHandle,byteCount);
+	
+	(**outNewHandle)[byteCount] = '\0';
+
+	errCode = noErr;
+
+
+EXITPOINT:
+
+	return(errCode);
+}
+
+
+
+
+OSErr CountDigits(const char *inCStr,int *outNumIntegerDigits,int *outNumFractDigits)
+{
+OSErr	errCode = noErr;
+int		numIntDigits = 0;
+int		numFractDigits = 0;
+int 	digitIndex = 0;
+
+	
+	SetErrorMessageAndBailIfNil(inCStr,"CountDigits: Bad parameter, theSrcCStr == nil");
+	SetErrorMessageAndBailIfNil(outNumIntegerDigits,"CountDigits: Bad parameter, outNumIntegerDigits == nil");
+	SetErrorMessageAndBailIfNil(outNumFractDigits,"CountDigits: Bad parameter, outNumFractDigits == nil");
+	
+	digitIndex = 0;
+	
+	while (inCStr[digitIndex] >= '0' && inCStr[digitIndex] <= '9')
+	{
+		digitIndex++;
+		numIntDigits++;
+	}
+	
+	if (inCStr[digitIndex] == '.')
+	{
+		digitIndex++;
+		
+		while (inCStr[digitIndex] >= '0' && inCStr[digitIndex] <= '9')
+		{
+			digitIndex++;
+			numFractDigits++;
+		}
+	}
+	
+	*outNumIntegerDigits = numIntDigits;
+	
+	*outNumFractDigits = numFractDigits;
+	
+	errCode = noErr;
+	
+EXITPOINT:
+
+	return(errCode);
+}
+
+
+
+OSErr ExtractIntFromCStr(const char *theSrcCStr,int *outInt,Boolean skipLeadingSpaces)
+{
+OSErr		errCode;
+int			theCharIndex;
+
+
+	if (theSrcCStr == nil)
+	{
+		SetErrorMessageAndBail(("ExtractIntFromCStr: Bad parameter, theSrcCStr == nil"));
+	}
+	
+	if (outInt == nil)
+	{
+		SetErrorMessageAndBail(("ExtractIntFromCStr: Bad parameter, outInt == nil"));
+	}	
+
+	
+	*outInt = 0;
+	
+	theCharIndex = 0;
+	
+	if (skipLeadingSpaces == true)
+	{
+		while (theSrcCStr[theCharIndex] == ' ')
+		{
+			theCharIndex++;
+		}
+	}
+	
+	if (theSrcCStr[theCharIndex] < '0' || theSrcCStr[theCharIndex] > '9')
+	{
+		SetErrorMessageAndBail(("ExtractIntFromCStr: Bad parameter, theSrcCStr contains a bogus numeric representation"));
+	}
+
+
+	while (theSrcCStr[theCharIndex] >= '0' && theSrcCStr[theCharIndex] <= '9')
+	{
+		*outInt = (*outInt * 10) + (theSrcCStr[theCharIndex] - '0');
+		
+		theCharIndex++;
+	}
+	
+
+	errCode = noErr;
+
+
+EXITPOINT:
+
+	return(errCode);
+}
+
+
+
+OSErr ExtractIntFromPStr(const unsigned char *theSrcPStr,int *outInt,Boolean skipLeadingSpaces)
+{
+OSErr		errCode;
+char		theCStr[256];
+
+
+	if (theSrcPStr == nil)
+	{
+		SetErrorMessageAndBail(("ExtractIntFromPStr: Bad parameter, theSrcPStr == nil"));
+	}
+	
+	if (outInt == nil)
+	{
+		SetErrorMessageAndBail(("ExtractIntFromPStr: Bad parameter, outInt == nil"));
+	}
+	
+	
+	CopyPStrToCStr(theSrcPStr,theCStr,sizeof(theCStr));
+	
+	
+	errCode = ExtractIntFromCStr(theCStr,outInt,skipLeadingSpaces);
+
+
+EXITPOINT:
+
+	return(errCode);
+}
+
+
+
+int CountOccurencesOfCharInCStr(const char inChar,const char *inSrcCStr)
+{
+int		theSrcCharIndex;
+int		numOccurrences = -1;
+
+
+	if (inSrcCStr != nil && inChar != '\0')
+	{
+		numOccurrences = 0;
+		
+		for (theSrcCharIndex = 0;inSrcCStr[theSrcCharIndex] != '\0';theSrcCharIndex++)
+		{
+			if (inSrcCStr[theSrcCharIndex] == inChar)
+			{
+				numOccurrences++;
+			}
+		}
+	}
+	
+	return(numOccurrences);
+}
+
+
+int CountWordsInCStr(const char *inSrcCStr)
+{
+int		numWords = -1;
+
+
+	if (inSrcCStr != nil)
+	{
+		numWords = 0;
+		
+		//	Skip lead spaces
+		
+		while (*inSrcCStr == ' ')
+		{
+			inSrcCStr++;
+		}
+
+		while (*inSrcCStr != '\0')
+		{
+			numWords++;
+
+			while (*inSrcCStr != ' ' && *inSrcCStr != '\0')
+			{
+				inSrcCStr++;
+			}
+			
+			while (*inSrcCStr == ' ')
+			{
+				inSrcCStr++;
+			}
+		}
+	}
+	
+	return(numWords);
+}
+
+
+
+
+void ConvertCStrToUpperCase(char *theSrcCStr)
+{
+char		*theCharPtr;
+
+
+	if (theSrcCStr != nil)
+	{
+		theCharPtr = theSrcCStr;
+		
+		while (*theCharPtr != 0)
+		{
+			if (*theCharPtr >= 'a' && *theCharPtr <= 'z')
+			{
+				*theCharPtr = *theCharPtr - 'a' + 'A';
+			}
+			
+			theCharPtr++;
+		}
+	}
+}
+
+
+
+
+
+
+
+void ExtractCStrItemFromCStr(const char *inSrcCStr,const char inItemDelimiter,const int inItemNumber,Boolean *foundItem,char *outDstCharPtr,const int inDstCharPtrMaxLength,const Boolean inTreatMultipleDelimsAsSingleDelim)
+{
+int		theItem;
+int		theSrcCharIndex;
+int		theDstCharIndex;
+
+
+	if (foundItem != nil)
+	{
+		*foundItem = false;
+	}
+	
+	
+	if (outDstCharPtr != nil && inDstCharPtrMaxLength > 0 && inItemNumber >= 0 && inItemDelimiter != 0)
+	{
+		*outDstCharPtr = 0;
+		
+
+		theSrcCharIndex = 0;
+		
+		for (theItem = 0;theItem < inItemNumber;theItem++)
+		{
+			while (inSrcCStr[theSrcCharIndex] != inItemDelimiter && inSrcCStr[theSrcCharIndex] != '\0')
+			{
+				theSrcCharIndex++;
+			}
+			
+			if (inSrcCStr[theSrcCharIndex] == inItemDelimiter)
+			{
+				theSrcCharIndex++;
+				
+				if (inTreatMultipleDelimsAsSingleDelim)
+				{
+					while (inSrcCStr[theSrcCharIndex] == inItemDelimiter)
+					{
+						theSrcCharIndex++;
+					}
+				}
+			}
+			
+			
+			if (inSrcCStr[theSrcCharIndex] == '\0')
+			{
+				goto EXITPOINT;
+			}
+		}
+		
+
+		if (foundItem != nil)
+		{
+			*foundItem = true;
+		}
+		
+		
+		theDstCharIndex = 0;
+		
+		for (;;)
+		{
+			if (inSrcCStr[theSrcCharIndex] == 0 || inSrcCStr[theSrcCharIndex] == inItemDelimiter || theDstCharIndex >= inDstCharPtrMaxLength - 1)
+			{
+				outDstCharPtr[theDstCharIndex] = 0;
+				
+				break;
+			}
+			
+			outDstCharPtr[theDstCharIndex++] = inSrcCStr[theSrcCharIndex++];
+		}
+	}
+	
+	
+EXITPOINT:
+
+	return;
+}
+
+
+
+OSErr ExtractCStrItemFromCStrIntoNewHandle(const char *inSrcCStr,const char inItemDelimiter,const int inItemNumber,Boolean *foundItem,Handle *outNewHandle,const Boolean inTreatMultipleDelimsAsSingleDelim)
+{
+OSErr	errCode;
+int		theItem;
+int		theSrcCharIndex;
+int		theItemLength;
+
+
+	if (inSrcCStr == nil)
+	{
+		SetErrorMessage("ExtractCStrItemFromCStrIntoNewHandle: Bad parameter, inSrcCStr == nil");
+		errCode = kGenericError;
+		goto EXITPOINT;
+	}
+	
+	if (outNewHandle == nil)
+	{
+		SetErrorMessage("ExtractCStrItemFromCStrIntoNewHandle: Bad parameter, outNewHandle == nil");
+		errCode = kGenericError;
+		goto EXITPOINT;
+	}
+	
+	if (foundItem == nil)
+	{
+		SetErrorMessage("ExtractCStrItemFromCStrIntoNewHandle: Bad parameter, foundItem == nil");
+		errCode = kGenericError;
+		goto EXITPOINT;
+	}
+	
+	if (inItemNumber < 0)
+	{
+		SetErrorMessage("ExtractCStrItemFromCStrIntoNewHandle: Bad parameter, inItemNumber < 0");
+		errCode = kGenericError;
+		goto EXITPOINT;
+	}
+	
+	if (inItemDelimiter == 0)
+	{
+		SetErrorMessage("ExtractCStrItemFromCStrIntoNewHandle: Bad parameter, inItemDelimiter == 0");
+		errCode = kGenericError;
+		goto EXITPOINT;
+	}
+
+
+	*foundItem = false;
+	
+	theSrcCharIndex = 0;
+	
+	for (theItem = 0;theItem < inItemNumber;theItem++)
+	{
+		while (inSrcCStr[theSrcCharIndex] != inItemDelimiter && inSrcCStr[theSrcCharIndex] != '\0')
+		{
+			theSrcCharIndex++;
+		}
+		
+		if (inSrcCStr[theSrcCharIndex] == inItemDelimiter)
+		{
+			theSrcCharIndex++;
+			
+			if (inTreatMultipleDelimsAsSingleDelim)
+			{
+				while (inSrcCStr[theSrcCharIndex] == inItemDelimiter)
+				{
+					theSrcCharIndex++;
+				}
+			}
+		}
+		
+		
+		if (inSrcCStr[theSrcCharIndex] == '\0')
+		{
+			errCode = noErr;
+			
+			goto EXITPOINT;
+		}
+	}
+	
+
+	*foundItem = true;
+	
+	
+	for (theItemLength = 0;;theItemLength++)
+	{
+		if (inSrcCStr[theSrcCharIndex + theItemLength] == 0 || inSrcCStr[theSrcCharIndex + theItemLength] == inItemDelimiter)
+		{
+			break;
+		}
+	}
+	
+
+	*outNewHandle = NewHandle(theItemLength + 1);
+	
+	if (*outNewHandle == nil)
+	{
+		SetErrorMessageAndLongIntAndBail("ExtractCStrItemFromCStrIntoNewHandle: Can't allocate Handle, MemError() = ",MemError());
+	}
+	
+	
+	BlockMove(inSrcCStr + theSrcCharIndex,**outNewHandle,theItemLength);
+	
+	(**outNewHandle)[theItemLength] = 0;
+	
+	errCode = noErr;
+	
+	
+EXITPOINT:
+
+	return(errCode);
+}
+
+
+
+
+
+
+OSErr ExtractFloatFromCStr(const char *inCString,extended80 *outFloat)
+{
+OSErr				errCode;
+Str255				theStr255;
+Handle				theNumberPartsTableHandle = nil;
+long				theNumberPartsOffset,theNumberPartsLength;
+FormatResultType	theFormatResultType;
+NumberParts			theNumberPartsTable;
+NumFormatStringRec	theNumFormatStringRec;
+
+
+	if (inCString == nil)
+	{
+		SetErrorMessage("ExtractFloatFromCStr: Bad parameter, inCString == nil");
+		errCode = kGenericError;
+		goto EXITPOINT;
+	}
+
+	if (outFloat == nil)
+	{
+		SetErrorMessage("ExtractFloatFromCStr: Bad parameter, outFloat == nil");
+		errCode = kGenericError;
+		goto EXITPOINT;
+	}
+	
+	
+//	GetIntlResourceTable(smRoman,smNumberPartsTable,&theNumberPartsTableHandle,&theNumberPartsOffset,&theNumberPartsLength);
+
+	GetIntlResourceTable(GetScriptManagerVariable(smSysScript),smNumberPartsTable,&theNumberPartsTableHandle,&theNumberPartsOffset,&theNumberPartsLength);	
+	
+	if (theNumberPartsTableHandle == nil)
+	{
+		SetErrorMessage("ExtractFloatFromCStr: Can't get number parts table for converting string representations to/from numeric representations");
+		errCode = kGenericError;
+		goto EXITPOINT;
+	}
+	
+	if (theNumberPartsLength > sizeof(theNumberPartsTable))
+	{
+		SetErrorMessage("ExtractFloatFromCStr: Number parts table has bad length");
+		errCode = kGenericError;
+		goto EXITPOINT;
+	}
+	
+
+	BlockMove(*theNumberPartsTableHandle + theNumberPartsOffset,&theNumberPartsTable,theNumberPartsLength);
+	
+	
+	theFormatResultType = (FormatResultType) StringToFormatRec(kNumberFormatString,&theNumberPartsTable,&theNumFormatStringRec);
+	
+	if (theFormatResultType != fFormatOK)
+	{
+		SetErrorMessage("ExtractFloatFromCStr: StringToFormatRec() != fFormatOK");
+		errCode = kGenericError;
+		goto EXITPOINT;
+	}
+
+	
+	CopyCStrToPStr(inCString,theStr255,sizeof(theStr255));
+
+
+	theFormatResultType = (FormatResultType) StringToExtended(theStr255,&theNumFormatStringRec,&theNumberPartsTable,outFloat);
+	
+	if (theFormatResultType != fFormatOK && theFormatResultType != fBestGuess)
+	{
+		SetErrorMessageAndLongIntAndBail("ExtractFloatFromCStr: StringToExtended() = ",theFormatResultType);
+	}
+
+	
+	errCode = noErr;
+	
+
+EXITPOINT:
+	
+	return(errCode);
+}
+
+
+
+OSErr CopyFloatToCStr(const extended80 *theFloat,char *theCStr,const int maxCStrLength,const int inMaxNumIntDigits,const int inMaxNumFractDigits)
+{
+OSErr				errCode;
+Str255				theStr255;
+Handle				theNumberPartsTableHandle = nil;
+long				theNumberPartsOffset,theNumberPartsLength;
+FormatResultType	theFormatResultType;
+NumberParts			theNumberPartsTable;
+NumFormatStringRec	theNumFormatStringRec;
+
+
+	if (theCStr == nil)
+	{
+		SetErrorMessage("CopyFloatToCStr: Bad parameter, theCStr == nil");
+		errCode = kGenericError;
+		goto EXITPOINT;
+	}
+
+	if (theFloat == nil)
+	{
+		SetErrorMessage("CopyFloatToCStr: Bad parameter, theFloat == nil");
+		errCode = kGenericError;
+		goto EXITPOINT;
+	}
+	
+
+//	GetIntlResourceTable(smRoman,smNumberPartsTable,&theNumberPartsTableHandle,&theNumberPartsOffset,&theNumberPartsLength);
+
+	GetIntlResourceTable(GetScriptManagerVariable(smSysScript),smNumberPartsTable,&theNumberPartsTableHandle,&theNumberPartsOffset,&theNumberPartsLength);	
+	
+	if (theNumberPartsTableHandle == nil)
+	{
+		SetErrorMessage("CopyFloatToCStr: Can't get number parts table for converting string representations to/from numeric representations");
+		errCode = kGenericError;
+		goto EXITPOINT;
+	}
+	
+	if (theNumberPartsLength > sizeof(theNumberPartsTable))
+	{
+		SetErrorMessage("CopyFloatToCStr: Number parts table has bad length");
+		errCode = kGenericError;
+		goto EXITPOINT;
+	}
+	
+	
+	BlockMove(*theNumberPartsTableHandle + theNumberPartsOffset,&theNumberPartsTable,theNumberPartsLength);
+	
+	
+	if (inMaxNumIntDigits >= 0 || inMaxNumFractDigits >= 0)
+	{
+	char	numberFormat[64];
+	int		numberFormatLength = 0;
+	
+		for (int i = 0;i < inMaxNumIntDigits && numberFormatLength < sizeof(numberFormat) - 1;i++)
+		{
+			numberFormat[numberFormatLength++] = '0';
+		}
+		
+		if (inMaxNumFractDigits > 0 && numberFormatLength < sizeof(numberFormat) - 1)
+		{
+			numberFormat[numberFormatLength++] = '.';
+			
+			for (int i = 0;i < inMaxNumFractDigits && numberFormatLength < sizeof(numberFormat) - 1;i++)
+			{
+				numberFormat[numberFormatLength++] = '0';
+			}
+		}
+
+		
+		if (numberFormatLength < sizeof(numberFormat) - 1)
+		{
+			numberFormat[numberFormatLength++] = ';';
+		}
+		
+		if (numberFormatLength < sizeof(numberFormat) - 1)
+		{
+			numberFormat[numberFormatLength++] = '-';
+		}
+		
+
+		for (int i = 0;i < inMaxNumIntDigits && numberFormatLength < sizeof(numberFormat) - 1;i++)
+		{
+			numberFormat[numberFormatLength++] = '0';
+		}
+		
+		if (inMaxNumFractDigits > 0 && numberFormatLength < sizeof(numberFormat) - 1)
+		{
+			numberFormat[numberFormatLength++] = '.';
+			
+			for (int i = 0;i < inMaxNumFractDigits && numberFormatLength < sizeof(numberFormat) - 1;i++)
+			{
+				numberFormat[numberFormatLength++] = '0';
+			}
+		}
+		
+		numberFormat[numberFormatLength] = '\0';
+
+
+	Str255	tempStr255;
+	
+		CopyCStrToPStr(numberFormat,tempStr255,sizeof(tempStr255));
+		
+		theFormatResultType = (FormatResultType) StringToFormatRec(tempStr255,&theNumberPartsTable,&theNumFormatStringRec);
+	}
+	
+	else
+	{
+		theFormatResultType = (FormatResultType) StringToFormatRec(kNumberFormatString,&theNumberPartsTable,&theNumFormatStringRec);
+	}
+	
+	if (theFormatResultType != fFormatOK)
+	{
+		SetErrorMessage("CopyFloatToCStr: StringToFormatRec() != fFormatOK");
+		errCode = kGenericError;
+		goto EXITPOINT;
+	}
+
+
+	theFormatResultType = (FormatResultType) ExtendedToString(theFloat,&theNumFormatStringRec,&theNumberPartsTable,theStr255);
+	
+	if (theFormatResultType != fFormatOK)
+	{
+		SetErrorMessage("CopyFloatToCStr: ExtendedToString() != fFormatOK");
+		errCode = kGenericError;
+		goto EXITPOINT;
+	}
+
+	
+	CopyPStrToCStr(theStr255,theCStr,maxCStrLength);
+	
+	errCode = noErr;
+	
+
+EXITPOINT:
+	
+	return(errCode);
+}
+
+
+
+
+
+void SkipWhiteSpace(char **ioSrcCharPtr,const Boolean inStopAtEOL)
+{
+	if (ioSrcCharPtr != nil && *ioSrcCharPtr != nil)
+	{
+		if (inStopAtEOL)
+		{
+			while ((**ioSrcCharPtr == ' ' || **ioSrcCharPtr == '\t') && **ioSrcCharPtr != '\r' && **ioSrcCharPtr != '\n')
+			{
+				*ioSrcCharPtr++;
+			}
+		}
+		
+		else
+		{
+			while (**ioSrcCharPtr == ' ' || **ioSrcCharPtr == '\t')
+			{
+				*ioSrcCharPtr++;
+			}
+		}
+	}
+}
diff --git a/openssl/MacOS/GetHTTPS.src/CPStringUtils.hpp b/openssl/MacOS/GetHTTPS.src/CPStringUtils.hpp
new file mode 100644
index 0000000..5045c41
--- /dev/null
+++ b/openssl/MacOS/GetHTTPS.src/CPStringUtils.hpp
@@ -0,0 +1,104 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void CopyPStrToCStr(const unsigned char *thePStr,char *theCStr,const int maxCStrLength);
+void CopyPStrToPStr(const unsigned char *theSrcPStr,unsigned char *theDstPStr,const int maxDstStrLength);
+void CopyCStrToCStr(const char *theSrcCStr,char *theDstCStr,const int maxDstStrLength);
+void CopyCStrToPStr(const char *theSrcCStr,unsigned char *theDstPStr,const int maxDstStrLength);
+void ConcatPStrToCStr(const unsigned char *thePStr,char *theCStr,const int maxCStrLength);
+void ConcatPStrToPStr(const unsigned char *theSrcPStr,unsigned char *theDstPStr,const int maxDstStrLength);
+void ConcatCStrToPStr(const char *theSrcCStr,unsigned char *theDstPStr,const int maxDstStrLength);
+void ConcatCStrToCStr(const char *theSrcCStr,char *theDstCStr,const int maxCStrLength);
+
+void ConcatCharToCStr(const char theChar,char *theDstCStr,const int maxCStrLength);
+void ConcatCharToPStr(const char theChar,unsigned char *theDstPStr,const int maxPStrLength);
+
+int ComparePStrs(const unsigned char *theFirstPStr,const unsigned char *theSecondPStr,const Boolean ignoreCase = true);
+int CompareCStrs(const char *theFirstCStr,const char *theSecondCStr,const Boolean ignoreCase = true);
+int CompareCStrToPStr(const char *theCStr,const unsigned char *thePStr,const Boolean ignoreCase = true);
+
+Boolean CStrsAreEqual(const char *theFirstCStr,const char *theSecondCStr,const Boolean ignoreCase = true);
+Boolean PStrsAreEqual(const unsigned char *theFirstCStr,const unsigned char *theSecondCStr,const Boolean ignoreCase = true);
+
+void CopyLongIntToCStr(const long theNum,char *theCStr,const int maxCStrLength,const int numDigits = -1);
+void CopyUnsignedLongIntToCStr(const unsigned long theNum,char *theCStr,const int maxCStrLength);
+void ConcatLongIntToCStr(const long theNum,char *theCStr,const int maxCStrLength,const int numDigits = -1);
+void CopyCStrAndConcatLongIntToCStr(const char *theSrcCStr,const long theNum,char *theDstCStr,const int maxDstStrLength);
+
+void CopyLongIntToPStr(const long theNum,unsigned char *thePStr,const int maxPStrLength,const int numDigits = -1);
+void ConcatLongIntToPStr(const long theNum,unsigned char *thePStr,const int maxPStrLength,const int numDigits = -1);
+
+long CStrLength(const char *theCString);
+long PStrLength(const unsigned char *thePString);
+
+OSErr CopyCStrToExistingHandle(const char *theCString,Handle theHandle);
+OSErr CopyLongIntToExistingHandle(const long inTheLongInt,Handle theHandle);
+
+OSErr CopyCStrToNewHandle(const char *theCString,Handle *theHandle);
+OSErr CopyPStrToNewHandle(const unsigned char *thePString,Handle *theHandle);
+OSErr CopyLongIntToNewHandle(const long inTheLongInt,Handle *theHandle);
+
+OSErr AppendCStrToHandle(const char *theCString,Handle theHandle,long *currentLength = nil,long *maxLength = nil);
+OSErr AppendCharsToHandle(const char *theChars,const int numChars,Handle theHandle,long *currentLength = nil,long *maxLength = nil);
+OSErr AppendPStrToHandle(const unsigned char *thePString,Handle theHandle,long *currentLength = nil);
+OSErr AppendLongIntToHandle(const long inTheLongInt,Handle theHandle,long *currentLength = nil);
+
+void ZeroMem(void *theMemPtr,const unsigned long numBytes);
+
+char *FindCharInCStr(const char theChar,const char *theCString);
+long FindCharOffsetInCStr(const char theChar,const char *theCString,const Boolean inIgnoreCase = false);
+long FindCStrOffsetInCStr(const char *theCSubstring,const char *theCString,const Boolean inIgnoreCase = false);
+
+void CopyCSubstrToCStr(const char *theSrcCStr,const int maxCharsToCopy,char *theDstCStr,const int maxDstStrLength);
+void CopyCSubstrToPStr(const char *theSrcCStr,const int maxCharsToCopy,unsigned char *theDstPStr,const int maxDstStrLength);
+
+void InsertCStrIntoCStr(const char *theSrcCStr,const int theInsertionOffset,char *theDstCStr,const int maxDstStrLength);
+void InsertPStrIntoCStr(const unsigned char *theSrcPStr,const int theInsertionOffset,char *theDstCStr,const int maxDstStrLength);
+OSErr InsertCStrIntoHandle(const char *theCString,Handle theHandle,const long inInsertOffset);
+
+void CopyCStrAndInsertCStrIntoCStr(const char *theSrcCStr,const char *theInsertCStr,char *theDstCStr,const int maxDstStrLength);
+
+void CopyCStrAndInsertCStrsLongIntsIntoCStr(const char *theSrcCStr,const char **theInsertCStrs,const long *theLongInts,char *theDstCStr,const int maxDstStrLength);
+
+void CopyCStrAndInsert1LongIntIntoCStr(const char *theSrcCStr,const long theNum,char *theDstCStr,const int maxDstStrLength);
+void CopyCStrAndInsert2LongIntsIntoCStr(const char *theSrcCStr,const long long1,const long long2,char *theDstCStr,const int maxDstStrLength);
+void CopyCStrAndInsert3LongIntsIntoCStr(const char *theSrcCStr,const long long1,const long long2,const long long3,char *theDstCStr,const int maxDstStrLength);
+
+void CopyCStrAndInsertCStrLongIntIntoCStr(const char *theSrcCStr,const char *theInsertCStr,const long theNum,char *theDstCStr,const int maxDstStrLength);
+OSErr CopyCStrAndInsertCStrLongIntIntoHandle(const char *theSrcCStr,const char *theInsertCStr,const long theNum,Handle *theHandle);
+
+
+OSErr CopyIndexedWordToCStr(char *theSrcCStr,int whichWord,char *theDstCStr,int maxDstCStrLength);
+OSErr CopyIndexedWordToNewHandle(char *theSrcCStr,int whichWord,Handle *outTheHandle);
+
+OSErr CopyIndexedLineToCStr(const char *theSrcCStr,int inWhichLine,int *lineEndIndex,Boolean *gotLastLine,char *theDstCStr,const int maxDstCStrLength);
+OSErr CopyIndexedLineToNewHandle(const char *theSrcCStr,int inWhichLine,Handle *outNewHandle);
+
+OSErr ExtractIntFromCStr(const char *theSrcCStr,int *outInt,Boolean skipLeadingSpaces = true);
+OSErr ExtractIntFromPStr(const unsigned char *theSrcPStr,int *outInt,Boolean skipLeadingSpaces = true);
+
+
+void ConvertCStrToUpperCase(char *theSrcCStr);
+
+
+int CountOccurencesOfCharInCStr(const char inChar,const char *inSrcCStr);
+int CountWordsInCStr(const char *inSrcCStr);
+
+OSErr CountDigits(const char *inCStr,int *outNumIntegerDigits,int *outNumFractDigits);
+
+void ExtractCStrItemFromCStr(const char *inSrcCStr,const char inItemDelimiter,const int inItemNumber,Boolean *foundItem,char *outDstCharPtr,const int inDstCharPtrMaxLength,const Boolean inTreatMultipleDelimsAsSingleDelim = false);
+OSErr ExtractCStrItemFromCStrIntoNewHandle(const char *inSrcCStr,const char inItemDelimiter,const int inItemNumber,Boolean *foundItem,Handle *outNewHandle,const Boolean inTreatMultipleDelimsAsSingleDelim = false);
+
+
+OSErr ExtractFloatFromCStr(const char *inCString,extended80 *outFloat);
+OSErr CopyFloatToCStr(const extended80 *theFloat,char *theCStr,const int maxCStrLength,const int inMaxNumIntDigits = -1,const int inMaxNumFractDigits = -1);
+
+void SkipWhiteSpace(char **ioSrcCharPtr,const Boolean inStopAtEOL = false);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/openssl/MacOS/GetHTTPS.src/ErrorHandling.cpp b/openssl/MacOS/GetHTTPS.src/ErrorHandling.cpp
new file mode 100644
index 0000000..80b6a67
--- /dev/null
+++ b/openssl/MacOS/GetHTTPS.src/ErrorHandling.cpp
@@ -0,0 +1,170 @@
+/* ====================================================================
+ * Copyright (c) 1998-1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+ 
+ 
+ 
+ #include "ErrorHandling.hpp"
+#include "CPStringUtils.hpp"
+
+#ifdef __EXCEPTIONS_ENABLED__
+	#include "CMyException.hpp"
+#endif
+
+
+static char					gErrorMessageBuffer[512];
+
+char 						*gErrorMessage = gErrorMessageBuffer;
+int							gErrorMessageMaxLength = sizeof(gErrorMessageBuffer);
+
+
+
+void SetErrorMessage(const char *theErrorMessage)
+{
+	if (theErrorMessage != nil)
+	{
+		CopyCStrToCStr(theErrorMessage,gErrorMessage,gErrorMessageMaxLength);
+	}
+}
+
+
+void SetErrorMessageAndAppendLongInt(const char *theErrorMessage,const long theLongInt)
+{
+	if (theErrorMessage != nil)
+	{
+		CopyCStrAndConcatLongIntToCStr(theErrorMessage,theLongInt,gErrorMessage,gErrorMessageMaxLength);
+	}
+}
+
+void SetErrorMessageAndCStrAndLongInt(const char *theErrorMessage,const char * theCStr,const long theLongInt)
+{
+	if (theErrorMessage != nil)
+	{
+		CopyCStrAndInsertCStrLongIntIntoCStr(theErrorMessage,theCStr,theLongInt,gErrorMessage,gErrorMessageMaxLength);
+	}
+
+}
+
+void SetErrorMessageAndCStr(const char *theErrorMessage,const char * theCStr)
+{
+	if (theErrorMessage != nil)
+	{
+		CopyCStrAndInsertCStrLongIntIntoCStr(theErrorMessage,theCStr,-1,gErrorMessage,gErrorMessageMaxLength);
+	}
+}
+
+
+void AppendCStrToErrorMessage(const char *theErrorMessage)
+{
+	if (theErrorMessage != nil)
+	{
+		ConcatCStrToCStr(theErrorMessage,gErrorMessage,gErrorMessageMaxLength);
+	}
+}
+
+
+void AppendLongIntToErrorMessage(const long theLongInt)
+{
+	ConcatLongIntToCStr(theLongInt,gErrorMessage,gErrorMessageMaxLength);
+}
+
+
+
+char *GetErrorMessage(void)
+{
+	return gErrorMessage;
+}
+
+
+OSErr GetErrorMessageInNewHandle(Handle *inoutHandle)
+{
+OSErr		errCode;
+
+
+	errCode = CopyCStrToNewHandle(gErrorMessage,inoutHandle);
+	
+	return(errCode);
+}
+
+
+OSErr GetErrorMessageInExistingHandle(Handle inoutHandle)
+{
+OSErr		errCode;
+
+
+	errCode = CopyCStrToExistingHandle(gErrorMessage,inoutHandle);
+	
+	return(errCode);
+}
+
+
+
+OSErr AppendErrorMessageToHandle(Handle inoutHandle)
+{
+OSErr		errCode;
+
+
+	errCode = AppendCStrToHandle(gErrorMessage,inoutHandle,nil);
+	
+	return(errCode);
+}
+
+
+#ifdef __EXCEPTIONS_ENABLED__
+
+void ThrowErrorMessageException(void)
+{
+	ThrowDescriptiveException(gErrorMessage);
+}
+
+#endif
diff --git a/openssl/MacOS/GetHTTPS.src/ErrorHandling.hpp b/openssl/MacOS/GetHTTPS.src/ErrorHandling.hpp
new file mode 100644
index 0000000..fbfbe78
--- /dev/null
+++ b/openssl/MacOS/GetHTTPS.src/ErrorHandling.hpp
@@ -0,0 +1,147 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef kGenericError
+	#define kGenericError		-1
+#endif
+
+extern char	*gErrorMessage;
+
+
+void SetErrorMessage(const char *theErrorMessage);
+void SetErrorMessageAndAppendLongInt(const char *theErrorMessage,const long theLongInt);
+void SetErrorMessageAndCStrAndLongInt(const char *theErrorMessage,const char * theCStr,const long theLongInt);
+void SetErrorMessageAndCStr(const char *theErrorMessage,const char * theCStr);
+void AppendCStrToErrorMessage(const char *theErrorMessage);
+void AppendLongIntToErrorMessage(const long theLongInt);
+
+
+char *GetErrorMessage(void);
+OSErr GetErrorMessageInNewHandle(Handle *inoutHandle);
+OSErr GetErrorMessageInExistingHandle(Handle inoutHandle);
+OSErr AppendErrorMessageToHandle(Handle inoutHandle);
+
+
+#ifdef __EXCEPTIONS_ENABLED__
+	void ThrowErrorMessageException(void);
+#endif
+
+
+
+//	A bunch of evil macros that would be unnecessary if I were always using C++ !
+
+#define SetErrorMessageAndBailIfNil(theArg,theMessage)								\
+{																					\
+	if (theArg == nil)																\
+	{																				\
+		SetErrorMessage(theMessage);												\
+		errCode = kGenericError;													\
+		goto EXITPOINT;																\
+	}																				\
+}
+
+
+#define SetErrorMessageAndBail(theMessage)											\
+{																					\
+		SetErrorMessage(theMessage);												\
+		errCode = kGenericError;													\
+		goto EXITPOINT;																\
+}
+
+
+#define SetErrorMessageAndLongIntAndBail(theMessage,theLongInt)						\
+{																					\
+		SetErrorMessageAndAppendLongInt(theMessage,theLongInt);						\
+		errCode = kGenericError;													\
+		goto EXITPOINT;																\
+}
+
+
+#define SetErrorMessageAndLongIntAndBailIfError(theErrCode,theMessage,theLongInt)	\
+{																					\
+	if (theErrCode != noErr)														\
+	{																				\
+		SetErrorMessageAndAppendLongInt(theMessage,theLongInt);						\
+		errCode = theErrCode;														\
+		goto EXITPOINT;																\
+	}																				\
+}
+
+
+#define SetErrorMessageCStrLongIntAndBailIfError(theErrCode,theMessage,theCStr,theLongInt)	\
+{																					\
+	if (theErrCode != noErr)														\
+	{																				\
+		SetErrorMessageAndCStrAndLongInt(theMessage,theCStr,theLongInt);			\
+		errCode = theErrCode;														\
+		goto EXITPOINT;																\
+	}																				\
+}
+
+
+#define SetErrorMessageAndCStrAndBail(theMessage,theCStr)							\
+{																					\
+	SetErrorMessageAndCStr(theMessage,theCStr);										\
+	errCode = kGenericError;														\
+	goto EXITPOINT;																	\
+}
+
+
+#define SetErrorMessageAndBailIfError(theErrCode,theMessage)						\
+{																					\
+	if (theErrCode != noErr)														\
+	{																				\
+		SetErrorMessage(theMessage);												\
+		errCode = theErrCode;														\
+		goto EXITPOINT;																\
+	}																				\
+}
+
+
+#define SetErrorMessageAndLongIntAndBailIfNil(theArg,theMessage,theLongInt)			\
+{																					\
+	if (theArg == nil)																\
+	{																				\
+		SetErrorMessageAndAppendLongInt(theMessage,theLongInt);						\
+		errCode = kGenericError;													\
+		goto EXITPOINT;																\
+	}																				\
+}
+
+
+#define BailIfError(theErrCode)														\
+{																					\
+	if ((theErrCode) != noErr)														\
+	{																				\
+		goto EXITPOINT;																\
+	}																				\
+}
+
+
+#define SetErrCodeAndBail(theErrCode)												\
+{																					\
+	errCode = theErrCode;															\
+																					\
+	goto EXITPOINT;																	\
+}
+
+
+#define SetErrorCodeAndMessageAndBail(theErrCode,theMessage)						\
+{																					\
+	SetErrorMessage(theMessage);													\
+	errCode = theErrCode;															\
+	goto EXITPOINT;																	\
+}
+
+
+#define BailNow()																	\
+{																					\
+	errCode = kGenericError;														\
+	goto EXITPOINT;																	\
+}
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/openssl/MacOS/GetHTTPS.src/GetHTTPS.cpp b/openssl/MacOS/GetHTTPS.src/GetHTTPS.cpp
new file mode 100644
index 0000000..3a5e3f0
--- /dev/null
+++ b/openssl/MacOS/GetHTTPS.src/GetHTTPS.cpp
@@ -0,0 +1,209 @@
+/*
+ *	An demo illustrating how to retrieve a URI from a secure HTTP server.
+ *
+ *	Author: 	Roy Wood
+ *	Date:		September 7, 1999
+ *	Comments:	This relies heavily on my MacSockets library.
+ *				This project is also set up so that it expects the OpenSSL source folder (0.9.4 as I write this)
+ *				to live in a folder called "OpenSSL-0.9.4" in this project's parent folder.  For example:
+ *
+ *					Macintosh HD:
+ *						Development:
+ *							OpenSSL-0.9.4:
+ *								(OpenSSL sources here)
+ *							OpenSSL Example:
+ *								(OpenSSL example junk here)
+ *
+ *
+ *				Also-- before attempting to compile this, make sure the aliases in "OpenSSL-0.9.4:include:openssl" 
+ *				are installed!  Use the AppleScript applet in the "openssl-0.9.4" folder to do this!
+ */
+/* modified to seed the PRNG */
+/* modified to use CRandomizer for seeding */
+
+
+//	Include some funky libs I've developed over time
+
+#include "CPStringUtils.hpp"
+#include "ErrorHandling.hpp"
+#include "MacSocket.h"
+#include "Randomizer.h"
+
+//	We use the OpenSSL implementation of SSL....
+//	This was a lot of work to finally get going, though you wouldn't know it by the results!
+
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+#include <timer.h>
+
+//	Let's try grabbing some data from here:
+
+#define kHTTPS_DNS		"www.apache-ssl.org"
+#define kHTTPS_Port		443
+#define kHTTPS_URI		"/"
+
+
+//	Forward-declare this
+
+OSErr MyMacSocket_IdleWaitCallback(void *inUserRefPtr);
+
+//	My idle-wait callback.  Doesn't do much, does it?  Silly cooperative multitasking.
+
+OSErr MyMacSocket_IdleWaitCallback(void *inUserRefPtr)
+{
+#pragma unused(inUserRefPtr)
+
+EventRecord		theEvent;
+	::EventAvail(everyEvent,&theEvent);
+	
+	CRandomizer *randomizer = (CRandomizer*)inUserRefPtr;
+	if (randomizer)
+		randomizer->PeriodicAction();
+
+	return(noErr);
+}
+
+
+//	Finally!
+
+void main(void)
+{
+	OSErr				errCode;
+	int					theSocket = -1;
+	int					theTimeout = 30;
+
+	SSL_CTX				*ssl_ctx = nil;
+	SSL					*ssl = nil;
+
+	char				tempString[256];
+	UnsignedWide		microTickCount;
+
+
+	CRandomizer randomizer;
+	
+	printf("OpenSSL Demo by Roy Wood, roy@centricsystems.ca\n\n");
+	
+	BailIfError(errCode = MacSocket_Startup());
+
+
+
+	//	Create a socket-like object
+	
+	BailIfError(errCode = MacSocket_socket(&theSocket,false,theTimeout * 60,MyMacSocket_IdleWaitCallback,&randomizer));
+
+	
+	//	Set up the connect string and try to connect
+	
+	CopyCStrAndInsertCStrLongIntIntoCStr("%s:%ld",kHTTPS_DNS,kHTTPS_Port,tempString,sizeof(tempString));
+	
+	printf("Connecting to %s....\n",tempString);
+
+	BailIfError(errCode = MacSocket_connect(theSocket,tempString));
+	
+	
+	//	Init SSL stuff
+	
+	SSL_load_error_strings();
+	
+	SSLeay_add_ssl_algorithms();
+	
+	
+	//	Pick the SSL method
+	
+//	ssl_ctx = SSL_CTX_new(SSLv2_client_method());
+	ssl_ctx = SSL_CTX_new(SSLv23_client_method());
+//	ssl_ctx = SSL_CTX_new(SSLv3_client_method());
+			
+
+	//	Create an SSL thingey and try to negotiate the connection
+	
+	ssl = SSL_new(ssl_ctx);
+	
+	SSL_set_fd(ssl,theSocket);
+	
+	errCode = SSL_connect(ssl);
+	
+	if (errCode < 0)
+	{
+		SetErrorMessageAndLongIntAndBail("OpenSSL: Can't initiate SSL connection, SSL_connect() = ",errCode);
+	}
+	
+	//	Request the URI from the host
+	
+	CopyCStrToCStr("GET ",tempString,sizeof(tempString));
+	ConcatCStrToCStr(kHTTPS_URI,tempString,sizeof(tempString));
+	ConcatCStrToCStr(" HTTP/1.0\r\n\r\n",tempString,sizeof(tempString));
+
+	
+	errCode = SSL_write(ssl,tempString,CStrLength(tempString));
+	
+	if (errCode < 0)
+	{
+		SetErrorMessageAndLongIntAndBail("OpenSSL: Error writing data via ssl, SSL_write() = ",errCode);
+	}
+	
+
+	for (;;)
+	{
+	char	tempString[256];
+	int		bytesRead;
+		
+
+		//	Read some bytes and dump them to the console
+		
+		bytesRead = SSL_read(ssl,tempString,sizeof(tempString) - 1);
+		
+		if (bytesRead == 0 && MacSocket_RemoteEndIsClosing(theSocket))
+		{
+			break;
+		}
+		
+		else if (bytesRead < 0)
+		{
+			SetErrorMessageAndLongIntAndBail("OpenSSL: Error reading data via ssl, SSL_read() = ",bytesRead);
+		}
+		
+		
+		tempString[bytesRead] = '\0';
+		
+		printf("%s", tempString);
+	}
+	
+	printf("\n\n\n");
+	
+	//	All done!
+	
+	errCode = noErr;
+	
+	
+EXITPOINT:
+
+	//	Clean up and go home
+	
+	if (theSocket >= 0)
+	{
+		MacSocket_close(theSocket);
+	}
+	
+	if (ssl != nil)
+	{
+		SSL_free(ssl);
+	}
+	
+	if (ssl_ctx != nil)
+	{
+		SSL_CTX_free(ssl_ctx);
+	}
+	
+	
+	if (errCode != noErr)
+	{
+		printf("An error occurred:\n");
+		
+		printf("%s",GetErrorMessage());
+	}
+	
+	
+	MacSocket_Shutdown();
+}
diff --git a/openssl/MacOS/GetHTTPS.src/MacSocket.cpp b/openssl/MacOS/GetHTTPS.src/MacSocket.cpp
new file mode 100644
index 0000000..c95d804
--- /dev/null
+++ b/openssl/MacOS/GetHTTPS.src/MacSocket.cpp
@@ -0,0 +1,1607 @@
+/*
+ *	A simple socket-like package.  
+ *	This could undoubtedly be improved, since it does polling and busy-waiting.  
+ *	At least it uses asynch I/O and implements timeouts!
+ *
+ *	Other funkiness includes the use of my own (possibly brain-damaged) error-handling infrastructure.
+ *
+ *	-Roy Wood (roy@centricsystems.ca)
+ *
+ */
+
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+ 
+
+
+
+
+#include "MacSocket.h"
+
+#include <Threads.h>
+
+#include <OpenTransport.h>
+#include <OpenTpTInternet.h>
+#include <OpenTptClient.h>
+
+
+
+#include "CPStringUtils.hpp"
+#include "ErrorHandling.hpp"
+
+
+//	#define MACSOCKET_DEBUG		1
+
+#ifdef MACSOCKET_DEBUG
+	#include <stdio.h>
+#endif
+
+
+
+extern int errno;
+
+
+#define kMaxNumSockets			4
+
+
+struct SocketStruct
+{
+	Boolean						mIsInUse;
+
+	Boolean						mEndpointIsBound;
+
+	Boolean						mLocalEndIsConnected;
+	Boolean						mRemoteEndIsConnected;
+
+	Boolean						mReceivedTOpenComplete;
+	Boolean						mReceivedTBindComplete;
+	Boolean						mReceivedTConnect;
+	Boolean						mReceivedTListen;
+	Boolean						mReceivedTPassCon;
+	Boolean						mReceivedTDisconnect;
+	Boolean						mReceivedTOrdRel;
+	Boolean						mReceivedTDisconnectComplete;
+	
+	long						mTimeoutTicks;
+	long						mOperationStartTicks;
+	
+	MacSocket_IdleWaitCallback	mIdleWaitCallback;
+	void						*mUserRefPtr;
+	
+	OTEventCode					mExpectedCode;
+	OTResult					mAsyncOperationResult;
+	
+	EndpointRef		 			mEndPointRef;
+	TBind						*mBindRequestedAddrInfo;
+	TBind						*mAssignedAddrInfo;
+	TCall						*mRemoteAddrInfo;
+	
+	Boolean						mReadyToReadData;
+	Boolean						mReadyToWriteData;
+	
+	Ptr							mReadBuffer;
+	Ptr							mWriteBuffer;
+	
+	int							mLastError;
+	char						mErrMessage[256];
+};
+
+typedef struct SocketStruct	SocketStruct;
+
+
+static SocketStruct			sSockets[kMaxNumSockets];
+static Boolean				sSocketsSetup = false;
+
+
+
+
+static OSErr MyBusyWait(SocketStruct *ioSocket,Boolean returnImmediatelyOnError,OTResult *outOTResult,Boolean *inAsyncOperationCompleteFlag);
+
+static pascal void OTNonYieldingNotifier(void *contextPtr,OTEventCode code,OTResult result,void *cookie);
+
+static Boolean	SocketIndexIsValid(const int inSocketNum);
+
+static void InitSocket(SocketStruct *ioSocket);
+
+static void PrepareForAsyncOperation(SocketStruct *ioSocket,const OTEventCode inExpectedCode);
+
+static Boolean TimeoutElapsed(const SocketStruct *inSocket);
+
+static OSStatus NegotiateIPReuseAddrOption(EndpointRef inEndpoint,const Boolean inEnableReuseIP);
+
+
+
+void MacSocket_GetSocketErrorInfo(const int inSocketNum,int *outSocketErrCode,char *outSocketErrString,const int inSocketErrStringMaxLength)
+{
+	if (outSocketErrCode != nil)
+	{
+		*outSocketErrCode = -1;
+	}
+	
+	if (outSocketErrString != nil)
+	{
+		CopyCStrToCStr("",outSocketErrString,inSocketErrStringMaxLength);
+	}
+	
+	
+	if (SocketIndexIsValid(inSocketNum))
+	{
+	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
+	
+		
+		if (outSocketErrCode != nil)
+		{
+			*outSocketErrCode = theSocketStruct->mLastError;
+		}
+
+		if (outSocketErrString != nil)
+		{
+			CopyCStrToCStr(theSocketStruct->mErrMessage,outSocketErrString,inSocketErrStringMaxLength);
+		}
+	}
+}
+
+
+void MacSocket_SetUserRefPtr(const int inSocketNum,void *inNewRefPtr)
+{
+	if (SocketIndexIsValid(inSocketNum))
+	{
+	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
+
+		theSocketStruct->mUserRefPtr = inNewRefPtr;
+	}
+}
+
+
+
+void MacSocket_GetLocalIPAndPort(const int inSocketNum,char *outIPAndPort,const int inIPAndPortLength)
+{
+	if (outIPAndPort != nil && SocketIndexIsValid(inSocketNum))
+	{
+	char			tempString[256];
+	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
+	
+		
+		CopyCStrToCStr("",tempString,sizeof(tempString));
+
+		if (theSocketStruct->mAssignedAddrInfo != nil)
+		{
+		InetAddress		*theInetAddress = (InetAddress *) theSocketStruct->mAssignedAddrInfo->addr.buf;
+		InetHost		theInetHost = theInetAddress->fHost;
+			
+			if (theInetHost == 0)
+			{
+			InetInterfaceInfo	theInetInterfaceInfo;
+				
+				if (::OTInetGetInterfaceInfo(&theInetInterfaceInfo,kDefaultInetInterface) == noErr)
+				{
+					theInetHost = theInetInterfaceInfo.fAddress;
+				}
+			}
+		
+			::OTInetHostToString(theInetHost,tempString);
+			
+			ConcatCStrToCStr(":",tempString,sizeof(tempString));
+			ConcatLongIntToCStr(theInetAddress->fPort,tempString,sizeof(tempString));
+		}
+		
+		CopyCStrToCStr(tempString,outIPAndPort,inIPAndPortLength);
+	}
+}
+
+
+
+void MacSocket_GetRemoteIPAndPort(const int inSocketNum,char *outIPAndPort,const int inIPAndPortLength)
+{
+	if (outIPAndPort != nil && SocketIndexIsValid(inSocketNum))
+	{
+	char			tempString[256];
+	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
+	
+		
+		CopyCStrToCStr("",tempString,sizeof(tempString));
+
+		if (theSocketStruct->mRemoteAddrInfo != nil)
+		{
+		InetAddress		*theInetAddress = (InetAddress *) theSocketStruct->mRemoteAddrInfo->addr.buf;
+		InetHost		theInetHost = theInetAddress->fHost;
+			
+			if (theInetHost == 0)
+			{
+			InetInterfaceInfo	theInetInterfaceInfo;
+				
+				if (::OTInetGetInterfaceInfo(&theInetInterfaceInfo,kDefaultInetInterface) == noErr)
+				{
+					theInetHost = theInetInterfaceInfo.fAddress;
+				}
+			}
+		
+			::OTInetHostToString(theInetHost,tempString);
+			
+			ConcatCStrToCStr(":",tempString,sizeof(tempString));
+			ConcatLongIntToCStr(theInetAddress->fPort,tempString,sizeof(tempString));
+		}
+		
+		CopyCStrToCStr(tempString,outIPAndPort,inIPAndPortLength);
+	}
+}
+
+
+
+Boolean MacSocket_RemoteEndIsClosing(const int inSocketNum)
+{
+Boolean		theResult = false;
+
+	if (SocketIndexIsValid(inSocketNum))
+	{
+	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
+
+		theResult = theSocketStruct->mReceivedTOrdRel;
+	}
+
+	return(theResult);
+}
+
+
+
+Boolean MacSocket_ListenCompleted(const int inSocketNum)
+{
+Boolean		theResult = false;
+
+	if (SocketIndexIsValid(inSocketNum))
+	{
+	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
+
+		theResult = theSocketStruct->mReceivedTPassCon;
+	}
+
+	return(theResult);
+}
+
+
+
+Boolean MacSocket_RemoteEndIsOpen(const int inSocketNum)
+{
+	if (SocketIndexIsValid(inSocketNum))
+	{
+	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
+	
+		return(theSocketStruct->mRemoteEndIsConnected);
+	}
+	
+	else
+	{
+		return(false);
+	}
+}
+
+
+
+Boolean MacSocket_LocalEndIsOpen(const int inSocketNum)
+{
+	if (SocketIndexIsValid(inSocketNum))
+	{
+	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
+	
+		return(theSocketStruct->mLocalEndIsConnected);
+	}
+	
+	else
+	{
+		return(false);
+	}
+}
+
+
+
+static Boolean TimeoutElapsed(const SocketStruct *inSocket)
+{
+Boolean		timeIsUp = false;
+
+	if (inSocket != nil && inSocket->mTimeoutTicks > 0 && ::TickCount() > inSocket->mOperationStartTicks + inSocket->mTimeoutTicks)
+	{
+		timeIsUp = true;
+	}
+	
+	
+	return(timeIsUp);
+}
+
+
+
+static Boolean SocketIndexIsValid(const int inSocketNum)
+{
+	if (inSocketNum >= 0 && inSocketNum < kMaxNumSockets && sSockets[inSocketNum].mEndPointRef != kOTInvalidEndpointRef)
+	{
+		return(true);
+	}
+	
+	else
+	{
+		return(false);
+	}
+}
+
+
+
+static void InitSocket(SocketStruct *ioSocket)
+{
+	ioSocket->mIsInUse = false;
+	
+	ioSocket->mEndpointIsBound = false;
+	
+	ioSocket->mLocalEndIsConnected = false;
+	ioSocket->mRemoteEndIsConnected = false;
+	
+	ioSocket->mReceivedTOpenComplete = false;
+	ioSocket->mReceivedTBindComplete = false;
+	ioSocket->mReceivedTConnect = false;
+	ioSocket->mReceivedTListen = false;
+	ioSocket->mReceivedTPassCon = false;
+	ioSocket->mReceivedTDisconnect = false;
+	ioSocket->mReceivedTOrdRel = false;
+	ioSocket->mReceivedTDisconnectComplete = false;
+	
+	ioSocket->mTimeoutTicks = 30 * 60;
+	ioSocket->mOperationStartTicks = -1;
+	
+	ioSocket->mIdleWaitCallback = nil;
+	ioSocket->mUserRefPtr = nil;
+	
+	ioSocket->mExpectedCode = 0;
+	ioSocket->mAsyncOperationResult = noErr;
+	
+	ioSocket->mEndPointRef = kOTInvalidEndpointRef;
+	
+	ioSocket->mBindRequestedAddrInfo = nil;
+	ioSocket->mAssignedAddrInfo = nil;
+	ioSocket->mRemoteAddrInfo = nil;
+	
+	ioSocket->mReadyToReadData = false;
+	ioSocket->mReadyToWriteData = true;
+	
+	ioSocket->mReadBuffer = nil;
+	ioSocket->mWriteBuffer = nil;
+
+	ioSocket->mLastError = noErr;
+	CopyCStrToCStr("",ioSocket->mErrMessage,sizeof(ioSocket->mErrMessage));
+}
+
+
+
+static void PrepareForAsyncOperation(SocketStruct *ioSocket,const OTEventCode inExpectedCode)
+{
+	ioSocket->mOperationStartTicks = ::TickCount();
+	
+	ioSocket->mAsyncOperationResult = noErr;
+	
+	ioSocket->mExpectedCode = inExpectedCode;
+}
+
+
+//	The wait function....
+
+static OSErr MyBusyWait(SocketStruct *ioSocket,Boolean returnImmediatelyOnError,OTResult *outOTResult,Boolean *inAsyncOperationCompleteFlag)
+{
+OSErr 		errCode = noErr;
+OTResult	theOTResult = noErr;
+
+	
+	SetErrorMessageAndBailIfNil(ioSocket,"MyBusyWait: Bad parameter, ioSocket = nil");
+	SetErrorMessageAndBailIfNil(inAsyncOperationCompleteFlag,"MyBusyWait: Bad parameter, inAsyncOperationCompleteFlag = nil");
+	
+	for (;;) 
+	{
+		if (*inAsyncOperationCompleteFlag)
+		{
+			theOTResult = ioSocket->mAsyncOperationResult;
+			
+			break;
+		}
+		
+		if (ioSocket->mIdleWaitCallback != nil)
+		{
+			theOTResult = (*(ioSocket->mIdleWaitCallback))(ioSocket->mUserRefPtr);
+			
+			if (theOTResult != noErr && returnImmediatelyOnError)
+			{
+				break;
+			}
+		}
+		
+		if (TimeoutElapsed(ioSocket))
+		{
+			theOTResult = kMacSocket_TimeoutErr;
+			
+			break;
+		}
+	}
+
+
+EXITPOINT:
+	
+	if (outOTResult != nil)
+	{
+		*outOTResult = theOTResult;
+	}
+	
+	return(errCode);
+}
+
+
+
+//	I used to do thread switching, but stopped.  It could easily be rolled back in though....
+
+static pascal void OTNonYieldingNotifier(void *contextPtr,OTEventCode code,OTResult result,void *cookie)
+{
+SocketStruct *theSocketStruct = (SocketStruct *) contextPtr;
+	
+	if (theSocketStruct != nil)
+	{
+		if (theSocketStruct->mExpectedCode != 0 && code == theSocketStruct->mExpectedCode)
+		{
+			theSocketStruct->mAsyncOperationResult = result;
+			
+			theSocketStruct->mExpectedCode = 0;
+		}
+		
+		
+		switch (code) 
+		{
+			case T_OPENCOMPLETE:
+			{
+				theSocketStruct->mReceivedTOpenComplete = true;
+				
+				theSocketStruct->mEndPointRef = (EndpointRef) cookie;
+				
+				break;
+			}
+
+			
+			case T_BINDCOMPLETE:
+			{
+				theSocketStruct->mReceivedTBindComplete = true;
+				
+				break;
+			}
+			
+
+			case T_CONNECT:
+			{
+				theSocketStruct->mReceivedTConnect = true;
+
+				theSocketStruct->mLocalEndIsConnected = true;
+				
+				theSocketStruct->mRemoteEndIsConnected = true;
+
+				break;
+			}
+			
+
+			case T_LISTEN:
+			{
+				theSocketStruct->mReceivedTListen = true;
+				
+				break;
+			}
+			
+
+			case T_PASSCON:
+			{
+				theSocketStruct->mReceivedTPassCon = true;
+				
+				theSocketStruct->mLocalEndIsConnected = true;
+				
+				theSocketStruct->mRemoteEndIsConnected = true;
+
+				break;
+			}
+
+
+			case T_DATA:
+			{
+				theSocketStruct->mReadyToReadData = true;
+				
+				break;
+			}
+			
+			case T_GODATA:
+			{
+				theSocketStruct->mReadyToWriteData = true;
+				
+				break;
+			}
+			
+			case T_DISCONNECT:
+			{
+				theSocketStruct->mReceivedTDisconnect = true;
+				
+				theSocketStruct->mRemoteEndIsConnected = false;
+				
+				theSocketStruct->mLocalEndIsConnected = false;
+				
+				::OTRcvDisconnect(theSocketStruct->mEndPointRef,nil);
+				
+				break;
+			}
+
+			case T_ORDREL:
+			{
+				theSocketStruct->mReceivedTOrdRel = true;
+				
+				//	We can still write data, so don't clear mRemoteEndIsConnected
+				
+				::OTRcvOrderlyDisconnect(theSocketStruct->mEndPointRef);
+				
+				break;
+			}
+			
+			case T_DISCONNECTCOMPLETE:
+			{
+				theSocketStruct->mReceivedTDisconnectComplete = true;
+				
+				theSocketStruct->mRemoteEndIsConnected = false;
+				
+				theSocketStruct->mLocalEndIsConnected = false;
+				
+				break;
+			}
+		}
+	}
+/*
+T_LISTEN OTListen
+T_CONNECT OTRcvConnect
+T_DATA OTRcv, OTRcvUData
+T_DISCONNECT OTRcvDisconnect
+T_ORDREL OTRcvOrderlyDisconnect
+T_GODATA OTSnd, OTSndUData, OTLook
+T_PASSCON none
+
+T_EXDATA OTRcv
+T_GOEXDATA OTSnd, OTLook
+T_UDERR OTRcvUDErr
+*/
+}
+
+
+
+//	Initialize the main socket data structure
+
+OSErr MacSocket_Startup(void)
+{
+	if (!sSocketsSetup)
+	{
+		for (int i = 0;i < kMaxNumSockets;i++)
+		{
+			InitSocket(&(sSockets[i]));
+		}
+
+		::InitOpenTransport();
+		
+		sSocketsSetup = true;
+	}
+	
+	
+	return(noErr);
+}
+
+
+
+//	Cleanup before exiting
+
+OSErr MacSocket_Shutdown(void)
+{
+	if (sSocketsSetup)
+	{
+		for (int i = 0;i < kMaxNumSockets;i++)
+		{
+		SocketStruct *theSocketStruct = &(sSockets[i]);
+		
+			if (theSocketStruct->mIsInUse)
+			{
+				if (theSocketStruct->mEndPointRef != kOTInvalidEndpointRef)
+				{
+				OTResult	theOTResult;
+				
+				
+					//	Since we're killing the endpoint, I don't bother to send the disconnect (sorry!)
+
+/*
+					if (theSocketStruct->mLocalEndIsConnected)
+					{
+						//	This is an abortive action, so we do a hard disconnect instead of an OTSndOrderlyDisconnect
+						
+						theOTResult = ::OTSndDisconnect(theSocketStruct->mEndPointRef, nil);
+						
+						//	Now we have to watch for T_DISCONNECTCOMPLETE event
+						
+						theSocketStruct->mLocalEndIsConnected = false;
+					}
+*/					
+					
+					theOTResult = ::OTCloseProvider(theSocketStruct->mEndPointRef);
+					
+					
+					theSocketStruct->mEndPointRef = kOTInvalidEndpointRef;
+				}
+				
+				if (theSocketStruct->mBindRequestedAddrInfo != nil)
+				{
+					::OTFree((void *) theSocketStruct->mBindRequestedAddrInfo,T_BIND);
+					
+					theSocketStruct->mBindRequestedAddrInfo = nil;
+				}
+				
+				if (theSocketStruct->mAssignedAddrInfo != nil)
+				{
+					::OTFree((void *) theSocketStruct->mAssignedAddrInfo,T_BIND);
+					
+					theSocketStruct->mAssignedAddrInfo = nil;
+				}
+				
+				if (theSocketStruct->mRemoteAddrInfo != nil)
+				{
+					::OTFree((void *) theSocketStruct->mRemoteAddrInfo,T_CALL);
+					
+					theSocketStruct->mRemoteAddrInfo = nil;
+				}
+				
+				
+			}
+		}
+		
+		::CloseOpenTransport();
+
+		sSocketsSetup = false;
+	}
+	
+	return(noErr);
+}
+
+
+
+
+
+
+//	Allocate a socket
+
+OSErr MacSocket_socket(int *outSocketNum,const Boolean inDoThreadSwitching,const long inTimeoutTicks,MacSocket_IdleWaitCallback inIdleWaitCallback,void *inUserRefPtr)
+{
+//	Gotta roll support back in for threads eventually.....
+
+#pragma unused(inDoThreadSwitching)
+
+
+OSErr	errCode = noErr;
+
+	
+	SetErrorMessageAndBailIfNil(outSocketNum,"MacSocket_socket: Bad parameter, outSocketNum == nil");
+	
+	*outSocketNum = -1;
+	
+	
+	//	Find an unused socket
+	
+	for (int i = 0;i < kMaxNumSockets;i++)
+	{
+		if (sSockets[i].mIsInUse == false)
+		{
+		OTResult		theOTResult;
+		SocketStruct	*theSocketStruct = &(sSockets[i]);
+		
+			
+			InitSocket(theSocketStruct);
+			
+			theSocketStruct->mIdleWaitCallback = inIdleWaitCallback;
+			theSocketStruct->mUserRefPtr = inUserRefPtr;
+			
+			theSocketStruct->mTimeoutTicks = inTimeoutTicks;
+			
+
+			//	Set up OT endpoint
+			
+			PrepareForAsyncOperation(theSocketStruct,T_OPENCOMPLETE);
+			
+			theOTResult = ::OTAsyncOpenEndpoint(OTCreateConfiguration(kTCPName),0,nil,OTNonYieldingNotifier,(void *) theSocketStruct);
+			
+			SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_socket: Can't create OT endpoint, OTAsyncOpenEndpoint() = ",theOTResult);
+			
+			BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTOpenComplete)));
+																						
+			SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_socket: Can't create OT endpoint, OTAsyncOpenEndpoint() = ",theOTResult);
+			
+			
+			*outSocketNum = i;
+			
+			errCode = noErr;
+			
+			theSocketStruct->mIsInUse = true;
+			
+			break;
+		}
+		
+		else if (i == kMaxNumSockets - 1)
+		{
+			SetErrorMessageAndBail("MacSocket_socket: No sockets available");
+		}
+	}
+
+
+EXITPOINT:
+	
+	errno = errCode;
+	
+	return(errCode);
+}
+
+
+
+
+OSErr MacSocket_listen(const int inSocketNum,const int inPortNum)
+{
+OSErr			errCode = noErr;
+SocketStruct	*theSocketStruct = nil;
+
+
+	if (!SocketIndexIsValid(inSocketNum))
+	{
+		SetErrorMessageAndBail("MacSocket_listen: Invalid socket number specified");
+	}
+
+
+	theSocketStruct = &(sSockets[inSocketNum]);
+
+
+OTResult		theOTResult;
+	
+	
+	if (theSocketStruct->mBindRequestedAddrInfo == nil)
+	{
+		theSocketStruct->mBindRequestedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
+																					
+		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
+		SetErrorMessageAndBailIfNil(theSocketStruct->mBindRequestedAddrInfo,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
+	}
+	
+	if (theSocketStruct->mAssignedAddrInfo == nil)
+	{
+		theSocketStruct->mAssignedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
+																					
+		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
+		SetErrorMessageAndBailIfNil(theSocketStruct->mAssignedAddrInfo,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
+	}
+	
+	if (theSocketStruct->mRemoteAddrInfo == nil)
+	{
+		theSocketStruct->mRemoteAddrInfo = (TCall *) ::OTAlloc(theSocketStruct->mEndPointRef,T_CALL,T_ADDR,&theOTResult);
+																					
+		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't allocate OT T_CALL structure, OTAlloc() = ",theOTResult);
+		SetErrorMessageAndBailIfNil(theSocketStruct->mRemoteAddrInfo,"MacSocket_listen: Can't allocate OT T_CALL structure, OTAlloc() returned nil");
+	}
+	
+
+	if (!theSocketStruct->mEndpointIsBound)
+	{
+	InetInterfaceInfo	theInetInterfaceInfo;
+		
+		theOTResult = ::OTInetGetInterfaceInfo(&theInetInterfaceInfo,kDefaultInetInterface);
+																					
+		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't determine OT interface info, OTInetGetInterfaceInfo() = ",theOTResult);
+
+
+	InetAddress	*theInetAddress = (InetAddress *) theSocketStruct->mBindRequestedAddrInfo->addr.buf;
+		
+//		theInetAddress->fAddressType = AF_INET;
+//		theInetAddress->fPort = inPortNum;
+//		theInetAddress->fHost = theInetInterfaceInfo.fAddress;
+		
+		::OTInitInetAddress(theInetAddress,inPortNum,theInetInterfaceInfo.fAddress);
+
+		theSocketStruct->mBindRequestedAddrInfo->addr.len = sizeof(InetAddress);
+		
+		theSocketStruct->mBindRequestedAddrInfo->qlen = 1;
+		
+		
+		theOTResult = ::OTSetSynchronous(theSocketStruct->mEndPointRef);
+																					
+		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't set OT endpoint mode, OTSetSynchronous() = ",theOTResult);
+		
+		theOTResult = NegotiateIPReuseAddrOption(theSocketStruct->mEndPointRef,true);
+																					
+		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't set OT IP address reuse flag, NegotiateIPReuseAddrOption() = ",theOTResult);
+		
+		theOTResult = ::OTSetAsynchronous(theSocketStruct->mEndPointRef);
+																					
+		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't set OT endpoint mode, OTSetAsynchronous() = ",theOTResult);
+
+		
+		PrepareForAsyncOperation(theSocketStruct,T_BINDCOMPLETE);
+				
+		theOTResult = ::OTBind(theSocketStruct->mEndPointRef,theSocketStruct->mBindRequestedAddrInfo,theSocketStruct->mAssignedAddrInfo);
+																					
+		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't bind OT endpoint, OTBind() = ",theOTResult);
+		
+		BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTBindComplete)));
+																					
+		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't bind OT endpoint, OTBind() = ",theOTResult);
+		
+		
+		theSocketStruct->mEndpointIsBound = true;
+	}
+
+
+	PrepareForAsyncOperation(theSocketStruct,T_LISTEN);
+
+	theOTResult = ::OTListen(theSocketStruct->mEndPointRef,theSocketStruct->mRemoteAddrInfo);
+	
+	if (theOTResult == noErr)
+	{
+		PrepareForAsyncOperation(theSocketStruct,T_PASSCON);
+		
+		theOTResult = ::OTAccept(theSocketStruct->mEndPointRef,theSocketStruct->mEndPointRef,theSocketStruct->mRemoteAddrInfo);
+		
+		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't begin OT accept, OTAccept() = ",theOTResult);
+		
+		BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTPassCon)));
+																					
+		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't accept OT connection, OTAccept() = ",theOTResult);
+	}
+	
+	else if (theOTResult == kOTNoDataErr)
+	{
+		theOTResult = noErr;
+	}
+	
+	else
+	{
+		SetErrorMessageAndLongIntAndBail("MacSocket_listen: Can't begin OT listen, OTListen() = ",theOTResult);
+	}
+
+
+	errCode = noErr;
+
+
+EXITPOINT:
+	
+	if (theSocketStruct != nil)
+	{
+		theSocketStruct->mLastError = noErr;
+		
+		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
+
+		if (errCode != noErr)
+		{
+			theSocketStruct->mLastError = errCode;
+			
+			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
+		}
+	}
+	
+	errno = errCode;
+	
+	return(errCode);
+}
+
+
+
+
+OSErr MacSocket_connect(const int inSocketNum,char *inTargetAddressAndPort)
+{
+OSErr			errCode = noErr;
+SocketStruct	*theSocketStruct = nil;
+
+
+	if (!SocketIndexIsValid(inSocketNum))
+	{
+		SetErrorMessageAndBail("MacSocket_connect: Invalid socket number specified");
+	}
+
+	theSocketStruct = &(sSockets[inSocketNum]);
+
+	if (theSocketStruct->mEndpointIsBound)
+	{
+		SetErrorMessageAndBail("MacSocket_connect: Socket previously bound");
+	}
+
+	
+OTResult		theOTResult;
+
+	theSocketStruct->mBindRequestedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
+																				
+	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
+	SetErrorMessageAndBailIfNil(theSocketStruct->mBindRequestedAddrInfo,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
+	
+
+	theSocketStruct->mAssignedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
+																				
+	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
+	SetErrorMessageAndBailIfNil(theSocketStruct->mAssignedAddrInfo,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
+
+
+	theSocketStruct->mRemoteAddrInfo = (TCall *) ::OTAlloc(theSocketStruct->mEndPointRef,T_CALL,T_ADDR,&theOTResult);
+																				
+	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't allocate OT T_CALL structure, OTAlloc() = ",theOTResult);
+	SetErrorMessageAndBailIfNil(theSocketStruct->mRemoteAddrInfo,"MacSocket_connect: Can't allocate OT T_CALL structure, OTAlloc() returned nil");
+
+	
+	PrepareForAsyncOperation(theSocketStruct,T_BINDCOMPLETE);
+
+	theOTResult = ::OTBind(theSocketStruct->mEndPointRef,nil,theSocketStruct->mAssignedAddrInfo);
+																				
+	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't bind OT endpoint, OTBind() = ",theOTResult);
+	
+	BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTBindComplete)));
+																				
+	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't bind OT endpoint, OTBind() = ",theOTResult);
+	
+	theSocketStruct->mEndpointIsBound = true;
+	
+
+TCall		sndCall;
+DNSAddress 	hostDNSAddress;
+	
+	//	Set up target address
+	
+	sndCall.addr.buf = (UInt8 *) &hostDNSAddress;
+	sndCall.addr.len = ::OTInitDNSAddress(&hostDNSAddress,inTargetAddressAndPort);
+	sndCall.opt.buf = nil;
+	sndCall.opt.len = 0;
+	sndCall.udata.buf = nil;
+	sndCall.udata.len = 0;
+	sndCall.sequence = 0;
+		
+	//	Connect!
+	
+	PrepareForAsyncOperation(theSocketStruct,T_CONNECT);
+
+	theOTResult = ::OTConnect(theSocketStruct->mEndPointRef,&sndCall,nil);
+	
+	if (theOTResult == kOTNoDataErr)
+	{
+		theOTResult = noErr;
+	}
+												
+	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't connect OT endpoint, OTConnect() = ",theOTResult);
+	
+	BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTConnect)));
+	
+	if (theOTResult == kMacSocket_TimeoutErr)
+	{
+		SetErrorMessageAndBail("MacSocket_connect: Can't connect OT endpoint, OTConnect() = kMacSocket_TimeoutErr");
+	}
+	
+	else
+	{
+		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't connect OT endpoint, OTConnect() = ",theOTResult);
+	}
+
+	theOTResult = ::OTRcvConnect(theSocketStruct->mEndPointRef,nil);
+												
+	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't complete connect on OT endpoint, OTRcvConnect() = ",theOTResult);
+
+
+	errCode = noErr;
+
+
+#ifdef MACSOCKET_DEBUG
+	printf("MacSocket_connect: connect completed\n");
+#endif
+
+EXITPOINT:
+	
+	if (theSocketStruct != nil)
+	{
+		theSocketStruct->mLastError = noErr;
+		
+		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
+
+		if (errCode != noErr)
+		{
+			theSocketStruct->mLastError = errCode;
+			
+			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
+		}
+	}
+	
+	errno = errCode;
+	
+	return(errCode);
+}
+
+
+
+
+//	Close a connection
+
+OSErr MacSocket_close(const int inSocketNum)
+{
+OSErr			errCode = noErr;
+SocketStruct	*theSocketStruct = nil;
+
+
+	if (!SocketIndexIsValid(inSocketNum))
+	{
+		SetErrorMessageAndBail("MacSocket_close: Invalid socket number specified");
+	}
+
+
+	theSocketStruct = &(sSockets[inSocketNum]);
+	
+	if (theSocketStruct->mEndPointRef != kOTInvalidEndpointRef)
+	{
+	OTResult		theOTResult = noErr;
+	
+		//	Try to play nice
+		
+		if (theSocketStruct->mReceivedTOrdRel)
+		{
+			//	Already did an OTRcvOrderlyDisconnect() in the notifier
+		
+			if (theSocketStruct->mLocalEndIsConnected)
+			{
+				theOTResult = ::OTSndOrderlyDisconnect(theSocketStruct->mEndPointRef);
+				
+				theSocketStruct->mLocalEndIsConnected = false;
+			}
+		}
+		
+		else if (theSocketStruct->mLocalEndIsConnected)
+		{
+			theOTResult = ::OTSndOrderlyDisconnect(theSocketStruct->mEndPointRef);
+			
+			theSocketStruct->mLocalEndIsConnected = false;
+			
+			//	Wait for other end to hang up too!
+			
+//			PrepareForAsyncOperation(theSocketStruct,T_ORDREL);
+//
+//			errCode = MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTOrdRel));
+		}
+		
+		
+		if (theOTResult != noErr)
+		{
+			::OTCloseProvider(theSocketStruct->mEndPointRef);
+		}
+		
+		else
+		{
+			theOTResult = ::OTCloseProvider(theSocketStruct->mEndPointRef);
+		}
+
+		theSocketStruct->mEndPointRef = kOTInvalidEndpointRef;
+		
+		errCode = theOTResult;
+	}
+
+
+	theSocketStruct->mIsInUse = false;
+
+	
+EXITPOINT:
+	
+	if (theSocketStruct != nil)
+	{
+		theSocketStruct->mLastError = noErr;
+		
+		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
+
+		if (errCode != noErr)
+		{
+			theSocketStruct->mLastError = errCode;
+			
+			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
+		}
+	}
+
+	errno = errCode;
+		
+	return(errCode);
+}
+
+
+
+
+//	Receive some bytes
+
+int MacSocket_recv(const int inSocketNum,void *outBuff,int outBuffLength,const Boolean inBlock)
+{
+OSErr			errCode = noErr;
+int				totalBytesRead = 0;
+SocketStruct	*theSocketStruct = nil;
+
+	
+	SetErrorMessageAndBailIfNil(outBuff,"MacSocket_recv: Bad parameter, outBuff = nil");
+	
+	if (outBuffLength <= 0)
+	{
+		SetErrorMessageAndBail("MacSocket_recv: Bad parameter, outBuffLength <= 0");
+	}
+	
+	if (!SocketIndexIsValid(inSocketNum))
+	{
+		SetErrorMessageAndBail("MacSocket_recv: Invalid socket number specified");
+	}
+
+	theSocketStruct = &(sSockets[inSocketNum]);
+
+	if (!theSocketStruct->mLocalEndIsConnected)
+	{
+		SetErrorMessageAndBail("MacSocket_recv: Socket not connected");
+	}
+
+	if (theSocketStruct->mReceivedTOrdRel)
+	{
+		totalBytesRead = 0;
+		
+		goto EXITPOINT;
+	}
+
+	
+	PrepareForAsyncOperation(theSocketStruct,0);
+	
+	for (;;)
+	{
+	int			bytesRead;
+	OTResult	theOTResult;
+	
+	
+		theOTResult = ::OTRcv(theSocketStruct->mEndPointRef,(void *) ((unsigned long) outBuff + (unsigned long) totalBytesRead),outBuffLength - totalBytesRead,nil);
+		
+		if (theOTResult >= 0)
+		{
+			bytesRead = theOTResult;
+			
+#ifdef MACSOCKET_DEBUG
+	printf("MacSocket_recv: read %d bytes in part\n",bytesRead);
+#endif
+		}
+		
+		else if (theOTResult == kOTNoDataErr)
+		{
+			bytesRead = 0;
+		}
+		
+		else
+		{
+			SetErrorMessageAndLongIntAndBail("MacSocket_recv: Can't receive OT data, OTRcv() = ",theOTResult);
+		}
+		
+		
+		totalBytesRead += bytesRead;
+		
+		
+		if (totalBytesRead <= 0)
+		{
+			if (theSocketStruct->mReceivedTOrdRel)
+			{
+				break;
+			}
+			
+			//	This seems pretty stupid to me now.  Maybe I'll delete this blocking garbage.
+			
+			if (inBlock)
+			{
+				if (TimeoutElapsed(theSocketStruct))
+				{
+					SetErrorCodeAndMessageAndBail(kMacSocket_TimeoutErr,"MacSocket_recv: Receive operation timed-out");
+				}
+				
+				if (theSocketStruct->mIdleWaitCallback != nil)
+				{
+					theOTResult = (*(theSocketStruct->mIdleWaitCallback))(theSocketStruct->mUserRefPtr);
+					
+					SetErrorMessageAndBailIfError(theOTResult,"MacSocket_recv: User cancelled operation");
+				}
+				
+				continue;
+			}
+		}
+		
+		
+		break;
+	}
+	
+	errCode = noErr;
+
+
+#ifdef MACSOCKET_DEBUG
+	printf("MacSocket_recv: read %d bytes in total\n",totalBytesRead);
+#endif
+	
+	
+EXITPOINT:
+	
+	if (theSocketStruct != nil)
+	{
+		theSocketStruct->mLastError = noErr;
+		
+		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
+
+		if (errCode != noErr)
+		{
+			theSocketStruct->mLastError = errCode;
+			
+			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
+		}
+	}
+
+	errno = errCode;
+	
+	return(totalBytesRead);
+}
+
+
+
+//	Send some bytes
+
+int MacSocket_send(const int inSocketNum,const void *inBuff,int inBuffLength)
+{
+OSErr			errCode = noErr;
+int				bytesSent = 0;
+SocketStruct	*theSocketStruct = nil;
+
+
+	SetErrorMessageAndBailIfNil(inBuff,"MacSocket_send: Bad parameter, inBuff = nil");
+	
+	if (inBuffLength <= 0)
+	{
+		SetErrorMessageAndBail("MacSocket_send: Bad parameter, inBuffLength <= 0");
+	}
+
+	if (!SocketIndexIsValid(inSocketNum))
+	{
+		SetErrorMessageAndBail("MacSocket_send: Invalid socket number specified");
+	}
+	
+
+	theSocketStruct = &(sSockets[inSocketNum]);
+	
+	if (!theSocketStruct->mLocalEndIsConnected)
+	{
+		SetErrorMessageAndBail("MacSocket_send: Socket not connected");
+	}
+
+
+OTResult		theOTResult;
+	
+
+	PrepareForAsyncOperation(theSocketStruct,0);
+
+	while (bytesSent < inBuffLength)
+	{
+		if (theSocketStruct->mIdleWaitCallback != nil)
+		{
+			theOTResult = (*(theSocketStruct->mIdleWaitCallback))(theSocketStruct->mUserRefPtr);
+			
+			SetErrorMessageAndBailIfError(theOTResult,"MacSocket_send: User cancelled");
+		}
+
+
+		theOTResult = ::OTSnd(theSocketStruct->mEndPointRef,(void *) ((unsigned long) inBuff + bytesSent),inBuffLength - bytesSent,0);
+		
+		if (theOTResult >= 0)
+		{
+			bytesSent += theOTResult;
+			
+			theOTResult = noErr;
+			
+			//	Reset timer....
+			
+			PrepareForAsyncOperation(theSocketStruct,0);
+		}
+		
+		if (theOTResult == kOTFlowErr)
+		{
+			if (TimeoutElapsed(theSocketStruct))
+			{
+				SetErrorCodeAndMessageAndBail(kMacSocket_TimeoutErr,"MacSocket_send: Send timed-out")
+			}
+
+			theOTResult = noErr;
+		}
+													
+		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_send: Can't send OT data, OTSnd() = ",theOTResult);
+	}
+
+	
+	errCode = noErr;
+
+#ifdef MACSOCKET_DEBUG
+	printf("MacSocket_send: sent %d bytes\n",bytesSent);
+#endif
+	
+	
+EXITPOINT:
+	
+	if (theSocketStruct != nil)
+	{
+		theSocketStruct->mLastError = noErr;
+		
+		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
+
+		if (errCode != noErr)
+		{
+			theSocketStruct->mLastError = errCode;
+			
+			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
+		}
+	}
+	
+	if (errCode != noErr)
+	{
+		::SysBeep(1);
+	}
+	
+	errno = errCode;
+	
+	return(bytesSent);
+}
+
+
+
+
+
+static OSStatus NegotiateIPReuseAddrOption(EndpointRef inEndpoint,const Boolean inEnableReuseIP)
+{
+OSStatus	errCode;
+UInt8		buf[kOTFourByteOptionSize];
+TOption*	theOTOption;
+TOptMgmt	theOTRequest;
+TOptMgmt	theOTResult;
+	
+
+	if (!OTIsSynchronous(inEndpoint))
+	{
+		SetErrorMessageAndBail("NegotiateIPReuseAddrOption: Open Transport endpoint is not synchronous");
+	}
+	
+	theOTRequest.opt.buf = buf;
+	theOTRequest.opt.len = sizeof(buf);
+	theOTRequest.flags = T_NEGOTIATE;
+
+	theOTResult.opt.buf = buf;
+	theOTResult.opt.maxlen = kOTFourByteOptionSize;
+
+
+	theOTOption = (TOption *) buf;
+	
+	theOTOption->level = INET_IP;
+	theOTOption->name = IP_REUSEADDR;
+	theOTOption->len = kOTFourByteOptionSize;
+	theOTOption->status = 0;
+	*((UInt32 *) (theOTOption->value)) = inEnableReuseIP;
+
+	errCode = ::OTOptionManagement(inEndpoint,&theOTRequest,&theOTResult);
+	
+	if (errCode == kOTNoError)
+	{
+		if (theOTOption->status != T_SUCCESS)
+		{
+			errCode = theOTOption->status;
+		}
+		
+		else
+		{
+			errCode = kOTNoError;
+		}
+	}
+				
+
+EXITPOINT:
+	
+	errno = errCode;
+	
+	return(errCode);
+}
+
+
+
+
+
+//	Some rough notes....
+
+
+
+//	OTAckSends(ep);
+//	OTAckSends(ep) // enable AckSend option
+//	......
+//	buf = OTAllocMem( nbytes); // Allocate nbytes of memory from OT
+//	OTSnd(ep, buf, nbytes, 0); // send a packet
+//	......
+//	NotifyProc( .... void* theParam) // Notifier Proc
+//	case T_MEMORYRELEASED: // process event
+//	OTFreeMem( theParam); // free up memory
+//	break;
+
+
+
+/*
+struct InetInterfaceInfo
+{
+	InetHost		fAddress;
+	InetHost		fNetmask;
+	InetHost		fBroadcastAddr;
+	InetHost		fDefaultGatewayAddr;
+	InetHost		fDNSAddr;
+	UInt16			fVersion;
+	UInt16			fHWAddrLen;
+	UInt8*			fHWAddr;
+	UInt32			fIfMTU;
+	UInt8*			fReservedPtrs[2];
+	InetDomainName	fDomainName;
+	UInt32			fIPSecondaryCount;
+	UInt8			fReserved[252];			
+};
+typedef struct InetInterfaceInfo InetInterfaceInfo;
+
+
+
+((InetAddress *) addr.buf)->fHost
+
+struct TBind
+{
+	TNetbuf	addr;
+	OTQLen	qlen;
+};
+
+typedef struct TBind	TBind;
+
+struct TNetbuf
+{
+	size_t	maxlen;
+	size_t	len;
+	UInt8*	buf;
+};
+
+typedef struct TNetbuf	TNetbuf;
+
+	
+	struct InetAddress
+{
+		OTAddressType	fAddressType;	// always AF_INET
+		InetPort		fPort;			// Port number 
+		InetHost		fHost;			// Host address in net byte order
+		UInt8			fUnused[8];		// Traditional unused bytes
+};
+typedef struct InetAddress InetAddress;
+*/
+
+
+
+/*
+static pascal void Notifier(void* context, OTEventCode event, OTResult result, void* cookie)
+{
+EPInfo* epi = (EPInfo*) context;
+
+	switch (event)
+	{
+		case T_LISTEN:
+		{
+			DoListenAccept();
+			return;
+		}
+		
+		case T_ACCEPTCOMPLETE:
+		{
+			if (result != kOTNoError)
+				DBAlert1("Notifier: T_ACCEPTCOMPLETE - result %d",result);
+			return;
+		}
+		
+		case T_PASSCON:
+		{
+			if (result != kOTNoError)
+			{
+				DBAlert1("Notifier: T_PASSCON result %d", result);
+				return;
+			}
+
+			OTAtomicAdd32(1, &gCntrConnections);
+			OTAtomicAdd32(1, &gCntrTotalConnections);
+			OTAtomicAdd32(1, &gCntrIntervalConnects);
+			
+			if ( OTAtomicSetBit(&epi->stateFlags, kPassconBit) != 0 )
+			{
+				ReadData(epi);
+			}
+			
+			return;
+		}
+		
+		case T_DATA:
+		{
+			if ( OTAtomicSetBit(&epi->stateFlags, kPassconBit) != 0 )
+			{
+				ReadData(epi);
+			}
+			
+			return;
+		}
+		
+		case T_GODATA:
+		{
+			SendData(epi);
+			return;
+		}
+		
+		case T_DISCONNECT:
+		{
+			DoRcvDisconnect(epi);
+			return;
+		}
+		
+		case T_DISCONNECTCOMPLETE:
+		{
+			if (result != kOTNoError)
+				DBAlert1("Notifier: T_DISCONNECT_COMPLETE result %d",result);
+				
+			return;
+		}
+		
+		case T_MEMORYRELEASED:
+		{
+			OTAtomicAdd32(-1, &epi->outstandingSends);
+			return;
+		}
+		
+		default:
+		{
+			DBAlert1("Notifier: unknown event <%x>", event);
+			return;
+		}
+	}
+}
+*/
diff --git a/openssl/MacOS/GetHTTPS.src/MacSocket.h b/openssl/MacOS/GetHTTPS.src/MacSocket.h
new file mode 100644
index 0000000..ad59dc9
--- /dev/null
+++ b/openssl/MacOS/GetHTTPS.src/MacSocket.h
@@ -0,0 +1,103 @@
+#pragma once
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+enum
+{
+	kMacSocket_TimeoutErr = -2
+};
+
+
+//	Since MacSocket does busy waiting, I do a callback while waiting
+
+typedef OSErr (*MacSocket_IdleWaitCallback)(void *);
+
+
+//	Call this before anything else!
+
+OSErr MacSocket_Startup(void);
+
+
+//	Call this to cleanup before quitting
+
+OSErr MacSocket_Shutdown(void);
+
+
+//	Call this to allocate a "socket" (reference number is returned in outSocketNum)
+//	Note that inDoThreadSwitching is pretty much irrelevant right now, since I ignore it
+//	The inTimeoutTicks parameter is applied during reads/writes of data
+//	The inIdleWaitCallback parameter specifies a callback which is called during busy-waiting periods
+//	The inUserRefPtr parameter is passed back to the idle-wait callback
+
+OSErr MacSocket_socket(int *outSocketNum,const Boolean inDoThreadSwitching,const long inTimeoutTicks,MacSocket_IdleWaitCallback inIdleWaitCallback,void *inUserRefPtr);
+
+
+//	Call this to connect to an IP/DNS address
+//	Note that inTargetAddressAndPort is in "IP:port" format-- e.g. 10.1.1.1:123
+
+OSErr MacSocket_connect(const int inSocketNum,char *inTargetAddressAndPort);
+
+
+//	Call this to listen on a port
+//	Since this a low-performance implementation, I allow a maximum of 1 (one!) incoming request when I listen
+
+OSErr MacSocket_listen(const int inSocketNum,const int inPortNum);
+
+
+//	Call this to close a socket
+
+OSErr MacSocket_close(const int inSocketNum);
+
+
+//	Call this to receive data on a socket
+//	Most parameters' purpose are obvious-- except maybe "inBlock" which controls whether I wait for data or return immediately
+
+int MacSocket_recv(const int inSocketNum,void *outBuff,int outBuffLength,const Boolean inBlock);
+
+
+//	Call this to send data on a socket
+
+int MacSocket_send(const int inSocketNum,const void *inBuff,int inBuffLength);
+
+
+//	If zero bytes were read in a call to MacSocket_recv(), it may be that the remote end has done a half-close
+//	This function will let you check whether that's true or not
+
+Boolean MacSocket_RemoteEndIsClosing(const int inSocketNum);
+
+
+//	Call this to see if the listen has completed after a call to MacSocket_listen()
+
+Boolean MacSocket_ListenCompleted(const int inSocketNum);
+
+
+//	These really aren't very useful anymore
+
+Boolean MacSocket_LocalEndIsOpen(const int inSocketNum);
+Boolean MacSocket_RemoteEndIsOpen(const int inSocketNum);
+
+
+//	You may wish to change the userRefPtr for a socket callback-- use this to do it
+
+void MacSocket_SetUserRefPtr(const int inSocketNum,void *inNewRefPtr);
+
+
+//	Call these to get the socket's IP:port descriptor
+
+void MacSocket_GetLocalIPAndPort(const int inSocketNum,char *outIPAndPort,const int inIPAndPortLength);
+void MacSocket_GetRemoteIPAndPort(const int inSocketNum,char *outIPAndPort,const int inIPAndPortLength);
+
+
+//	Call this to get error info from a socket
+
+void MacSocket_GetSocketErrorInfo(const int inSocketNum,int *outSocketErrCode,char *outSocketErrString,const int inSocketErrStringMaxLength);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/openssl/MacOS/OpenSSL.mcp.hqx b/openssl/MacOS/OpenSSL.mcp.hqx
new file mode 100644
index 0000000..c357ea5
--- /dev/null
+++ b/openssl/MacOS/OpenSSL.mcp.hqx
@@ -0,0 +1,4940 @@
+(This file must be converted with BinHex 4.0)
+
+:#dp`C@j68d`ZE@0`!%e08(*$9dP&!!!!!jeU!!!!!0U2Bfp[E!!!!!-!!!%S!!1
+%3J!$K@S!!"J!!!!"!!%#!3!!!!!!!!!!!%0[C'9ABA*bD@pb)&"bEfTPBh3!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"(CA4)9&4
+38b"38%-k4'9LG@GRCA)J8R9ZG'PYC3"(CA4)9&438b"38%-k8fpeFQ0P)&4bC@9
+c!%GPG%K89&"6)&"33cT$GA0dEfdJ5f9jGfpbC(-!4f9d5&488&-J8&"$1N&MBf9
+cFb"3BA4SF`"(CA4)9&438b"38%-k9'&bCf9d)&0PG(4TEQGc!%GPG%K89&"6)&"
+33cT'D@aP)%eKF("TEQGc!%GPG%K89&"6)&"33cT#G@PXC#"&H(4bBA-!4f9d5&4
+88&-J8&"$1N4PBR9RCf9b)&4KFQGPG!"(CA4)9&438b"38%-k0MK,)%0[C'9(C@i
+!4f9d5&488&-J8&"$1MBi5b"%DA0KFh0PE@*XCA)!4f9d5&488&-J8&"$1MBi5b"
+(E'pLB@`J6h"dD@eTHQ9b!%GPG%K89&"6)&"33cSf1%XJ6'PZDf9b!%GPG%K89&"
+6)&"33cSf1%XJ8(*[DQ9MG!"(CA4)9&438b"38%-k3bp$+bXJ3fpYF'PXCA)!4f9
+d5&488&-J8&"$1N-[3bXV)&GKFQjTEQGc!%GPG%K89&"6)&"33cT$4Ndf1%X!4f9
+d5&488&-J8&"$1NeKBdp6)%ePFQGP)&"KEQ9X!%GPG%K89&"6)&"33cT38%-J3fp
+NC8GPEJ"(CA4)9&438b"38%-k8&"$)%4TFf&cFf9YBQaPFJ"(CA4)9&438b"38%-
+k8&"$)%GXEf*KE#"2F(4TE@PkCA)!4f9d5&488&-J8&"$1P"33b"-D@jVCA)!4f9
+d5&488&-J8&"$1P"33b"348B!4f9d5&488&-J8&"$1P"33b"3FQpUC@0d!%GPG%K
+89&"6)&"33cT38%0"FfdJ8'&ZC@`!4f9d5&488&-J8&"$1P*PHL"$Efe`D@aPFJ"
+2F'9Z8e0-)&"33cT%C@*eCfGPFL"5G@jdD@eP!%p`C@j68d`J8&"$1P0[GA*MC5"
+8FQ9PF`"2F'9Z8e0-)&"33cT$GA0dEfdJ5f9jGfpbC(-!6h"PEP066#"38%-k3@0
+MCA0c)&"KG'Kc!%p`C@j68d`J8&"$1P4KFQGPG#"6CA4dD@jRF`"2F'9Z8e0-)&"
+33cT'D@aP)%eKF("TEQGc!%p`C@j68d`J8&"$1N*eD@aN)%9iG(*KF`"2F'9Z8e0
+-)&"33cT%C@*eCfGPFL"8BA*RCA3!6h"PEP066#"38%-k0MK,)%0[C'9(C@i!6h"
+PEP066#"38%-k0MK,)%4TFf&cFf9YBQaPFJ"2F'9Z8e0-)&"33cSf1%XJ4fa[BQ&
+X)%p`G'PYDATPFJ"2F'9Z8e0-)&"33cSf1%XJ6'PZDf9b!%p`C@j68d`J8&"$1MB
+i5b"3FQpUC@0d!%p`C@j68d`J8&"$1N-[3bXV)%0[EA"TE'9b!%p`C@j68d`J8&"
+$1N-[3bXV)&GKFQjTEQGc!%p`C@j68d`J8&"$1N0'66Bi5`"2F'9Z8e0-)&"33cT
+0B@028b"0CA*RC5"3B@jPE!"2F'9Z8e0-)&"33cT38%-J3fpNC8GPEJ"2F'9Z8e0
+-)&"33cT38%-J4'PcBA0cC@eLE'9b!%p`C@j68d`J8&"$1P"33b"(E'pLB@`J6h"
+dD@eTHQ9b!%p`C@j68d`J8&"$1P"33b"-D@jVCA)!6h"PEP066#"38%-k8&"$)&"
+&4J"2F'9Z8e0-)&"33cT38%-J8(*[DQ9MG!"2F'9Z8e0-)&"33cT38%0"FfdJ8'&
+ZC@`!6h"PEP066#"38%-k8Q9k)%0[EA"TE'9b!%GPG%K89&"6)$Bi5cT%C@*eCfG
+PFL"5G@jdD@eP!%GPG%K89&"6)$Bi5cT6Eh9bBf8J9(*PCA-!4f9d5&488&-J0MK
+,1N0eFh4[E5",CAPhEh*NF`"(CA4)9&438b!f1%Xk3@0MCA0c)&"KG'Kc!%GPG%K
+89&"6)$Bi5cT8BA*RCA3J8f9dG'PZCh-!4f9d5&488&-J0MK,1NCTE'8J6@&`F'P
+ZCh-!4f9d5&488&-J0MK,1N*eD@aN)%9iG(*KF`"(CA4)9&438b!f1%Xk4'9LG@G
+RCA)J9'&bCf9d!%GPG%K89&"6)$Bi5cSf1%XJ3fpNC8GPEJ"(CA4)9&438b!f1%X
+k0MK,)%4TFf&cFf9YBQaPFJ"(CA4)9&438b!f1%Xk0MK,)%GXEf*KE#"2F(4TE@P
+kCA)!4f9d5&488&-J0MK,1MBi5b"-D@jVCA)!4f9d5&488&-J0MK,1MBi5b"3FQp
+UC@0d!%GPG%K89&"6)$Bi5cT$,d-V+b"$Efe`D@aPFJ"(CA4)9&438b!f1%Xk3bp
+$+bXJ9f&bEQPZCh-!4f9d5&488&-J0MK,1N0'66Bi5`"(CA4)9&438b!f1%Xk6@&
+M6e-J6@9bCf8J8'&ZC@`!4f9d5&488&-J0MK,1P"33b"$Ef4P4f9Z!%GPG%K89&"
+6)$Bi5cT38%-J4'PcBA0cC@eLE'9b!%GPG%K89&"6)$Bi5cT38%-J4fa[BQ&X)%p
+`G'PYDATPFJ"(CA4)9&438b!f1%Xk8&"$)%aTEQYPFJ"(CA4)9&438b!f1%Xk8&"
+$)&"&4J"(CA4)9&438b!f1%Xk8&"$)&"bEfTPBh3!4f9d5&488&-J0MK,1P"33d&
+cE5"3B@jPE!"(CA4)9&438b!f1%Xk8Q9k)%0[EA"TE'9b!%aTBP066#!f1%Xk4'9
+LG@GRCA)J8R9ZG'PYC3"-D@*68d`J0MK,1P0[GA*MC5"8FQ9PF`"-D@*68d`J0MK
+,1N0eFh4[E5",CAPhEh*NF`"-D@*68d`J0MK,1N&MBf9cFb"3BA4SF`"-D@*68d`
+J0MK,1P4KFQGPG#"6CA4dD@jRF`"-D@*68d`J0MK,1NCTE'8J6@&`F'PZCh-!6'P
+L8e0-)$Bi5cT#G@PXC#"&H(4bBA-!6'PL8e0-)$Bi5cT%C@*eCfGPFL"8BA*RCA3
+!6'PL8e0-)$Bi5cSf1%XJ3fpNC8GPEJ"-D@*68d`J0MK,1MBi5b"%DA0KFh0PE@*
+XCA)!6'PL8e0-)$Bi5cSf1%XJ4fa[BQ&X)%p`G'PYDATPFJ"-D@*68d`J0MK,1MB
+i5b"-D@jVCA)!6'PL8e0-)$Bi5cSf1%XJ8(*[DQ9MG!"-D@*68d`J0MK,1N-[3bX
+V)%0[EA"TE'9b!%aTBP066#!f1%Xk3bp$+bXJ9f&bEQPZCh-!6'PL8e0-)$Bi5cT
+$4Ndf1%X!6'PL8e0-)$Bi5cT0B@028b"0CA*RC5"3B@jPE!"-D@*68d`J0MK,1P"
+33b"$Ef4P4f9Z!%aTBP066#!f1%Xk8&"$)%4TFf&cFf9YBQaPFJ"-D@*68d`J0MK
+,1P"33b"(E'pLB@`J6h"dD@eTHQ9b!%aTBP066#!f1%Xk8&"$)%aTEQYPFJ"-D@*
+68d`J0MK,1P"33b"348B!6'PL8e0-)$Bi5cT38%-J8(*[DQ9MG!"-D@*68d`J0MK
+,1P"33d&cE5"3B@jPE!"-D@*68d`J0MK,1P*PHL"$Efe`D@aPFJ"2F'9Z8e0-)$B
+iDcT%C@*eCfGPFL"5G@jdD@eP!%p`C@j68d`J0MKV1P0[GA*MC5"8FQ9PF`"2F'9
+Z8e0-)$BiDcT$GA0dEfdJ5f9jGfpbC(-!6h"PEP066#!f1'Xk3@0MCA0c)&"KG'K
+c!%p`C@j68d`J0MKV1P4KFQGPG#"6CA4dD@jRF`"2F'9Z8e0-)$BiDcT'D@aP)%e
+KF("TEQGc!%p`C@j68d`J0MKV1N*eD@aN)%9iG(*KF`"2F'9Z8e0-)$BiDcT%C@*
+eCfGPFL"8BA*RCA3!6h"PEP066#!f1'Xk0MK,)%0[C'9(C@i!6h"PEP066#!f1'X
+k0MK,)%4TFf&cFf9YBQaPFJ"2F'9Z8e0-)$BiDcSf1%XJ4fa[BQ&X)%p`G'PYDAT
+PFJ"2F'9Z8e0-)$BiDcSf1%XJ6'PZDf9b!%p`C@j68d`J0MKV1MBi5b"3FQpUC@0
+d!%p`C@j68d`J0MKV1N-[3bXV)%0[EA"TE'9b!%p`C@j68d`J0MKV1N-[3bXV)&G
+KFQjTEQGc!%p`C@j68d`J0MKV1N0'66Bi5`"2F'9Z8e0-)$BiDcT0B@028b"0CA*
+RC5"3B@jPE!"2F'9Z8e0-)$BiDcT38%-J3fpNC8GPEJ"2F'9Z8e0-)$BiDcT38%-
+J4'PcBA0cC@eLE'9b!%p`C@j68d`J0MKV1P"33b"(E'pLB@`J6h"dD@eTHQ9b!%p
+`C@j68d`J0MKV1P"33b"-D@jVCA)!6h"PEP066#!f1'Xk8&"$)&"&4J"2F'9Z8e0
+-)$BiDcT38%-J8(*[DQ9MG!"2F'9Z8e0-)$BiDcT38%0"FfdJ8'&ZC@`!6h"PEP0
+66#!f1'Xk8Q9k)%0[EA"TE'9b!%aTBP066#"38%-k4'9LG@GRCA)J8R9ZG'PYC3"
+-D@*68d`J8&"$1P0[GA*MC5"8FQ9PF`"-D@*68d`J8&"$1N0eFh4[E5",CAPhEh*
+NF`"-D@*68d`J8&"$1N&MBf9cFb"3BA4SF`"-D@*68d`J8&"$1P4KFQGPG#"6CA4
+dD@jRF`"-D@*68d`J8&"$1NCTE'8J6@&`F'PZCh-!6'PL8e0-)&"33cT#G@PXC#"
+&H(4bBA-!6'PL8e0-)&"33cT%C@*eCfGPFL"8BA*RCA3!6'PL8e0-)&"33cSf1%X
+J3fpNC8GPEJ"-D@*68d`J8&"$1MBi5b"%DA0KFh0PE@*XCA)!6'PL8e0-)&"33cS
+f1%XJ4fa[BQ&X)%p`G'PYDATPFJ"-D@*68d`J8&"$1MBi5b"-D@jVCA)!6'PL8e0
+-)&"33cSf1%XJ8(*[DQ9MG!"-D@*68d`J8&"$1N-[3bXV)%0[EA"TE'9b!%aTBP0
+66#"38%-k3bp$+bXJ9f&bEQPZCh-!6'PL8e0-)&"33cT$4Ndf1%X!6'PL8e0-)&"
+33cT0B@028b"0CA*RC5"3B@jPE!"-D@*68d`J8&"$1P"33b"$Ef4P4f9Z!%aTBP0
+66#"38%-k8&"$)%4TFf&cFf9YBQaPFJ"-D@*68d`J8&"$1P"33b"(E'pLB@`J6h"
+dD@eTHQ9b!%aTBP066#"38%-k8&"$)%aTEQYPFJ"-D@*68d`J8&"$1P"33b"348B
+!6'PL8e0-)&"33cT38%-J8(*[DQ9MG!"-D@*68d`J8&"$1P"33d&cE5"3B@jPE!"
+-D@*68d`J8&"$1P*PHL"$Efe`D@aPFJ"-D@*$FRP`G'mJ8&"$1N4PBR9RCf9b)&*
+eER4TE@8!6'PL3h*jF(4[)&"33cT6Eh9bBf8J9(*PCA-!6'PL3h*jF(4[)&"33cT
+$GA0dEfdJ5f9jGfpbC(-!6'PL3h*jF(4[)&"33cT"Bf0PFh-J8'&dD(-!6'PL3h*
+jF(4[)&"33cT8BA*RCA3J8f9dG'PZCh-!6'PL3h*jF(4[)&"33cT'D@aP)%eKF("
+TEQGc!%aTBN0bHA"dEb"38%-k3R9TE'3J4AKdFQ&c!%aTBN0bHA"dEb"38%-k4'9
+LG@GRCA)J9'&bCf9d!%aTBN0bHA"dEb"38%-k0MK,)%0[C'9(C@i!6'PL3h*jF(4
+[)&"33cSf1%XJ4'PcBA0cC@eLE'9b!%aTBN0bHA"dEb"38%-k0MK,)%GXEf*KE#"
+2F(4TE@PkCA)!6'PL3h*jF(4[)&"33cSf1%XJ6'PZDf9b!%aTBN0bHA"dEb"38%-
+k0MK,)&"bEfTPBh3!6'PL3h*jF(4[)&"33cT$,d-V+b"$Efe`D@aPFJ"-D@*$FRP
+`G'mJ8&"$1N-[3bXV)&GKFQjTEQGc!%aTBN0bHA"dEb"38%-k3dC00MK,!%aTBN0
+bHA"dEb"38%-k6@&M6e-J6@9bCf8J8'&ZC@`!6'PL3h*jF(4[)&"33cT38%-J3fp
+NC8GPEJ"-D@*$FRP`G'mJ8&"$1P"33b"%DA0KFh0PE@*XCA)!6'PL3h*jF(4[)&"
+33cT38%-J4fa[BQ&X)%p`G'PYDATPFJ"-D@*$FRP`G'mJ8&"$1P"33b"-D@jVCA)
+!6'PL3h*jF(4[)&"33cT38%-J8%9'!%aTBN0bHA"dEb"38%-k8&"$)&"bEfTPBh3
+!6'PL3h*jF(4[)&"33cT38%0"FfdJ8'&ZC@`!6'PL3h*jF(4[)&"33cT5CASJ3fp
+YF'PXCA)!6'PL3h*jF(4[)$Bi5cT%C@*eCfGPFL"5G@jdD@eP!%aTBN0bHA"dEb!
+f1%Xk8fpeFQ0P)&4bC@9c!%aTBN0bHA"dEb!f1%Xk3h9cG'pY)%YPHAG[FQ4c!%a
+TBN0bHA"dEb!f1%Xk3@0MCA0c)&"KG'Kc!%aTBN0bHA"dEb!f1%Xk9'&bCf9d)&0
+PG(4TEQGc!%aTBN0bHA"dEb!f1%Xk4QPXC5"0BA"`D@jRF`"-D@*$FRP`G'mJ0MK
+,1N*eD@aN)%9iG(*KF`"-D@*$FRP`G'mJ0MK,1N4PBR9RCf9b)&4KFQGPG!"-D@*
+$FRP`G'mJ0MK,1MBi5b"$Ef4P4f9Z!%aTBN0bHA"dEb!f1%Xk0MK,)%4TFf&cFf9
+YBQaPFJ"-D@*$FRP`G'mJ0MK,1MBi5b"(E'pLB@`J6h"dD@eTHQ9b!%aTBN0bHA"
+dEb!f1%Xk0MK,)%aTEQYPFJ"-D@*$FRP`G'mJ0MK,1MBi5b"3FQpUC@0d!%aTBN0
+bHA"dEb!f1%Xk3bp$+bXJ3fpYF'PXCA)!6'PL3h*jF(4[)$Bi5cT$,d-V+b"ABA*
+ZD@jRF`"-D@*$FRP`G'mJ0MK,1N0'66Bi5`"-D@*$FRP`G'mJ0MK,1NeKBdp6)%e
+PFQGP)&"KEQ9X!%aTBN0bHA"dEb!f1%Xk8&"$)%0[C'9(C@i!6'PL3h*jF(4[)$B
+i5cT38%-J4'PcBA0cC@eLE'9b!%aTBN0bHA"dEb!f1%Xk8&"$)%GXEf*KE#"2F(4
+TE@PkCA)!6'PL3h*jF(4[)$Bi5cT38%-J6'PZDf9b!%aTBN0bHA"dEb!f1%Xk8&"
+$)&"&4J"-D@*$FRP`G'mJ0MK,1P"33b"3FQpUC@0d!%aTBN0bHA"dEb!f1%Xk8&"
+$3A0Y)&"KEQ9X!%aTBN0bHA"dEb!f1%Xk8Q9k)%0[EA"TE'9b!&"bEfTPBh3J4QP
+XC5"-DA0d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!3!!!!!!!!!H!!!!!J!!!!!!!!!i!!!!!`!!!!!!!!"9!!!!"!!!!!!!!!"[!!!
+!"3!!!!!!!!#-!!!!"J!!!!!!!!#R!!!!"`!!!!!!!!$"!!!!#!!!!!!!!!$H!!!
+!#3!!!!!!!!$h!!!!#J!!!!!!!!%9!!!!#`!!!!!!!!%h!!!!$!!!!!!!!!&2!!!
+!$3!!!!!!!!&S!!!!$J!!!!!!!!'%!!!!$`!!!!!!!!'J!!!!%!!!!!!!!!'d!!!
+!%3!!!!!!!!(6!!!!%J!!!!!!!!(X!!!!%`!!!!!!!!)+!!!!&!!!!!!!!!)X!!!
+!&3!!!!!!!!*%!!!!&J!!!!!!!!*C!!!!&`!!!!!!!!*b!!!!'!!!!!!!!!+-!!!
+!'3!!!!!!!!+Q!!!!'J!!!!!!!!,$!!!!'`!!!!!!!!,F!!!!(!!!!!!!!!,i!!!
+!(3!!!!!!!!-4!!!!(J!!!!!!!!-Y!!!!(`!!!!!!!!0(!!!!)!!!!!!!!!0J!!!
+!)3!!!!!!!!0m!!!!)J!!!!!!!!18!!!!)`!!!!!!!!1a!!!!*!!!!!!!!!25!!!
+!*3!!!!!!!!2T!!!!*J!!!!!!!!3"!!!!*`!!!!!!!!3F!!!!+!!!!!!!!!3h!!!
+!+3!!!!!!!!4+!!!!+J!!!!!!!!4S!!!!+`!!!!!!!!5!!!!!,!!!!!!!!!5G!!!
+!,3!!!!!!!!5q!!!!,J!!!!!!!!69!!!!,`!!!!!!!!6T!!!!-!!!!!!!!!8"!!!
+!-3!!!!!!!!8D!!!!-J!!!!!!!!8c!!!!-`!!!!!!!!94!!!!0!!!!!!!!!9V!!!
+!03!!!!!!!!@)!!!!0J!!!!!!!!@L!!!!0`!!!!!!!!@r!!!!1!!!!!!!!!AD!!!
+!13!!!!!!!!Ad!!!!1J!!!!!!!!B4!!!!1`!!!!!!!!BU!!!!2!!!!!!!!!C)!!!
+!23!!!!!!!!CU!!!!2J!!!!!!!!D#!!!!2`!!!!!!!!DE!!!!3!!!!!!!!!Dh!!!
+!33!!!!!!!!E6!!!!3J!!!!!!!!ER!!!!3`!!!!!!!!F'!!!!4!!!!!!!!!FI!!!
+!43!!!!!!!!Fp!!!!4J!!!!!!!!GI!!!!4`!!!!!!!!Gh!!!!5!!!!!!!!!H-!!!
+!53!!!!!!!!HP!!!!5J!!!!!!!!Hr!!!!5`!!!!!!!!IC!!!!6!!!!!!!!!Ie!!!
+!63!!!!!!!!J0!!!!6J!!!!!!!!JS!!!!6`!!!!!!!!K!!!!!8!!!!!!!!!KE!!!
+!83!!!!!!!!Kd!!!!8J!!!!!!!!L-!!!!8`!!!!!!!!LR!!!!9!!!!!!!!!Lq!!!
+!93!!!!!!!!MD!!!!9J!!!!!!!!Mk!!!!9`!!!!!!!!N3!!!!@!!!!!!!!!NR!!!
+!@3!!!!!!!!P"!!!!@J!!!!!!!!PE!!!!@`!!!!!!!!PY!!!!A!!!!!!!!!Q+!!!
+!A3!!!!!!!!QK!!!!AJ!!!!!!!!Qp!!!!A`!!!!!!!!RG!!!!B!!!!!!!!!Rc!!!
+!B3!!!!!!!!S'!!!!BJ!!!!!!!!SG!!!!B`!!!!!!!!Se!!!!C!!!!!!!!!T0!!!
+!C3!!!!!!!!TU!!!!CJ!!!!!!!!U$!!!!C`!!!!!!!!UI!!!!D!!!!!!!!!Ui!!!
+!D3!!!!!!!!V8!!!!DJ!!!!!!!!VZ!!!!D`!!!!!!!!X(!!!!E!!!!!!!!!XM!!!
+!E3!!!!!!!!Xl!!!!EJ!!!!!!!!YB!!!!E`!!!!!!!!Yj!!!!F!!!!!!!!!Z3!!!
+!!(%!!!!!!!!,U!!!!()!!!!!!!!,``!!!(-!!!!!!!!,hJ!!!(3!!!!!!!!,m3!
+!!(8!!!!!!!!-$`!!!(B!!!!!!!!-*`!!!(F!!!!!!!!-4!!!!(J!!!!!!!!-C3!
+!!(N!!!!!!!!-I!!!!(S!!!!!!!!-N!!!!!"l!!!!!!!!$+J!!!"m!!!!!!!!$-%
+!!!"p!!!!!!!!$0S!!!"q!!!!!!!!$2B!!!"r!!!!!!!!$3i!!!#!!!!!!!!!$5N
+!!!#"!!!!!!!!$8%!!!##!!!!!!!!$9`!!!#$!!!!!!!!$A8!!!#%!!!!!!!!$Bd
+!!!#&!!!!!!!!$DJ!!!#'!!!!!!!!$Em!!!#(!!!!!!!!$GX!!!#)!!!!!!!!$IX
+!!!#*!!!!!!!!$K%!!!#+!!!!!!!!$LJ!!!#,!!!!!!!!$N)!!!#-!!!!!!!!$P`
+!!!#0!!!!!!!!$Qi!!!#1!!!!!!!!$SX!!!#2!!!!!!!!$U)!!!#3!!!!!!!!!!k
+q!!!!N3!!!!!!!!lH!!!!NJ!!!!!!!!ld!!!!N`!!!!!!!!m(!!!!P!!!!!!!!!m
+H!!!!P3!!!!!!!!mf!!!!PJ!!!!!!!!p1!!!!P`!!!!!!!!pY!!!!Q!!!!!!!!!q
+)!!!!Q3!!!!!!!!qQ!!!!QJ!!!!!!!!r"!!!!Q`!!!!!!!!rI!!!!R!!!!!!!!!r
+l!!!!R3!!!!!!!"!@!!!!RJ!!!!!!!"!d!!!!R`!!!!!!!""1!!!!S!!!!!!!!""
+Y!!!!S3!!!!!!!"#3!!!!!+)!!!!!!!!3U3!!!+-!!!!!!!!3``!!!+3!!!!!!!!
+3i!!!!+8!!!!!!!!3r3!!!+B!!!!!!!!4%J!!!+F!!!!!!!!4-J!!!+J!!!!!!!!
+46!!!!+N!!!!!!!!4D`!!!+S!!!!!!!!4MJ!!!+X!!!!!!!!4T`!!!+`!!!!!!!!
+4[3!!!+d!!!!!!!!4e`!!!+i!!!!!!!!4mJ!!!+m!!!!!!!!5$3!!!,!!!!!!!!!
+5,!!!!,%!!!!!!!!54`!!!,)!!!!!!!!5C3!!!,-!!!!!!!!5J!!!!,3!!!!!!!!
+5RJ!!!,8!!!!!!!!5ZJ!!!,B!!!!!!!!5e3!!!,F!!!!!!!!5m`!!!,J!!!!!!!!
+6$3!!!,N!!!!!!!!6,!!!!,S!!!!!!!!66`!!!,X!!!!!!!!6D!!!!,`!!!!!!!!
+6JJ!!!,d!!!!!!!!6R`!!!,i!!!!!!!!6[!!!!,m!!!!!!!!6d3!!!-!!!!!!!!!
+6m3!!!-%!!!!!!!!8#`!!!-)!!!!!!!!8+J!!!--!!!!!!!!863!!!-3!!!!!!!!
+8CJ!!!-8!!!!!!!!8I!!!!-B!!!!!!!!8PJ!!!-F!!!!!!!!8X3!!!-J!!!!!!!!
+8c!!!!-N!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!1J!!!$X!!!!m!!!!23!!!$i!!!!e!!!!1!!!!$m!!!"!!!!!33!!!$3!!!!b!!!
+!13!!!$F!!!"#!!!!3`!!!%3!!!"&!!!!4J!!!%F!!!")!!!!53!!!%S!!!!c!!!
+!0J!!!!J!!!!*!!!!#J!!!!X!!!!-!!!!!`!!!!B!!!!0!!!!$J!!!!m!!!!#!!!
+!!!!!!!F!!!!&!!!!%!!!!"%!!!!5!!!!%`!!!"3!!!!9!!!!&J!!!"F!!!!B!!!
+!!3!!!!3!!!#h!!!!Z!!!!,N!!!#k!!!!Z`!!!,)!!!#e!!!![!!!!,d!!!#q!!!
+!X3!!!+m!!!#f!!!!Y!!!!,m!!!$!!!!!`3!!!-)!!!$$!!!!a!!!!-8!!!$'!!!
+!a`!!!,!!!!#c!!!!RJ!!!*m!!!#J!!!!S3!!!+)!!!#C!!!!R!!!!+-!!!#N!!!
+!T3!!!*J!!!#@!!!!R3!!!*X!!!#Q!!!!T`!!!+J!!!#T!!!!UJ!!!+X!!!#X!!!
+!V3!!!+i!!!#A!!!!QJ!!!&-!!!"8!!!!93!!!&B!!!"A!!!!6J!!!&%!!!"B!!!
+!@3!!!&S!!!"0!!!!5`!!!&)!!!"3!!!!@`!!!&`!!!"G!!!!AJ!!!&m!!!"J!!!
+!B3!!!')!!!"M!!!!6!!!!%m!!!#&!!!!KJ!!!)F!!!#)!!!!L3!!!)!!!!#$!!!
+!LJ!!!)X!!!#-!!!!I`!!!(d!!!#%!!!!JJ!!!)d!!!#1!!!!M`!!!*!!!!!!N3!
+!!*)!!!#6!!!!P!!!!*8!!!"q!!!!J3!!!'`!!!"Y!!!!EJ!!!'m!!!"`!!!!C`!
+!!'S!!!"a!!!!FJ!!!(-!!!"Q!!!!C!!!!'X!!!"T!!!!G!!!!(8!!!"f!!!!G`!
+!!(J!!!"j!!!!HJ!!!(X!!!"m!!!!C3!!!'J!!!!K!!!!)J!!!#-!!!!N!!!!*3!
+!!"`!!!!I!!!!*J!!!#F!!!!S!!!!'`!!!"N!!!!J!!!!(J!!!#N!!!!U!!!!+`!
+!!#`!!!!Y!!!!,J!!!#m!!!!`!!!!-3!!!"S!!!!G!!!!b!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!690-)%-Z8&"$,NaTBJ"*ER4
+PFQCKBf9-D@)!6@&dD%aTBJ"08d`J8R9ZG'PYC9"33bj-D@)!6h"PEP4`G%PZCA4
+38%-ZE`"2F'9Z9("d5@jdCA*ZCA4-D@)!6h"PEP4bB@jcF'pbG%9iG'j38%-ZE`"
+2F'9Z9(*KER0`Eh*d6'PL!&4SFQ9KC(0-D@)!BQP[Ah0cE#jM!(-b-epME'jd,Q-
+!Fc)cAfaTBLjM!(-b-epYCA4S,Q-!Fc)cAh"VG#jM!(-b-epcFRCb,Q-!Fc*IBfa
+ZG#jM!(-bAf9ZBbjM!(-bAfaTBLjM!(-bAfePG'JZB`"c-Pp`Dh3ZB`"c-PpcFRC
+b,Q-!Fc0IBQpdD#jM!(-cAf0XER3ZB`"c-epPEQ-ZB`"c-epXD@)ZB`"c-epYCA4
+S,Q-!Fc0IF'Yd,Q-!Fc0IFh*fFLjM!(0cE&pKE'Gc,Q-!Fh0XAf&cEM%ZB`"cFfa
+IBf9bG#jM!(0cE&pMDA"S,Q-!Fh0XAf9bFLjM!(0cE&pPFR)b,Q-!Fh0XAfaTBLj
+M!(0cE&pbFf%ZB`"cFfaIFf9cFbjM!(0cE&pcG'&d,Q-!Fh0XAh4iG#jM!(3aAf0
+XER3ZB`"d-9pPEQ-ZB`"d-9pXD@)ZB`"d-9pYCA4S,Q-!G$&IFh*fFLjM!'&cEM&
+ICA*b,Q-!BA0Z-9pXD@)ZB`"KFfiaAh"KFLjM!'&cEPp`B@0V,Q-!B9pLDA4cG()
+ZB`"KAf*YF#jM!'&IBQp[E#jM!'&IBRPdCA-ZB`"KAf3bD9pQF#jM!'&IC'PRCA0
+d,Q-!B9pNGA!ZB`"KAf9ZG@dZB`"KAfGPER4Y,Q-!B9pSC()ZB`"KAfNbC&pQF#j
+M!'&ID@jd,Q-!B9pYCA4S,Q-!B9p[BQTPBh3ZB`"KAfpMG'9d,Q-!B9p`FQPZG#j
+M!'&IFf9d,Q-!B9pcD@GZ,Q-!B9pdD@eP,Q-!B9pdHA"P,Q-!B9peG'0dE5jM!'&
+IGA4Q1#jM!'&IGQ9bD@Cj,Q-!B9pfDA-ZB`"N-QPIC'K`,Q-!C$*TAf4cBA!ZB`"
+N-QPIF()ZB`"N-QPIF(8ZB`"N-QPIFPp`FLjM!'3bD9pbAh"e,Q-!C$*TAh0IF()
+ZB`"N-QPIFep`G5jM!'9fF&pKFfia,Q-!CPpPER9Y,Q-!CPpTER3ZB`"QAh0dFQP
+ZCbjM!'NbC&pND(!ZB`"T-Q4IC(0KF#jM!'NbC&p`FLjM!'NbC&p`G5jM!'NbC&p
+bAh"b,Q-!D6*NAh*IF(8ZB`"T-Q4IFep`FLjM!'NbC&pcAh"e,Q-!ER0cCA%ZB`"
+ZAh"VCANZB`"`09p`BQ8ZB`"`09p`BQ9f-LjM!(!hAf4RFh3ZB`"`0epPEQ-ZB`"
+`0epPEQ0IBbjM!(!hAf9fF#jM!(!hAfPIFbjM!(!hAfaTBLjM!(!hAh*PBfP`,Q-
+!F$GIFfPREQ3ZB`"`0epcD@GZD5jM!(!hAh0IC5jM!(!iAh"VCANZB`"dAf0bE#j
+M!(4IF'YPH5jM!(4IFQ9a,Q-!G&pi06!j,Q-!H&pKE'G[FLjM!(KIBA4dFQPL,Q-
+!H&pMD@jQ,Q-!H&pMFQ`ZB`"iAf9iG'9Z,Q-!H&pTEQC[,Q-!H&pZB@eP,Q-!H&p
+`Df9j,Q-!H&p`G@*VCANZB`"iAh*PF5jM!(KIFfPR,Q-!H&pcF'YT,Q-!H&pfB@`
+ZB`"iAhJe-$NZB`"LCPpMCQ)f0#jM!'*QAf9MBLjM!'*QAf9ZBbjM!'*QAfpQBMB
+d,Q-!BQCIFfYPH5jM!'*TEepPFR)ZB`"LD@pIE'PL,Q-!BR0cAh0[BfXZB`"LEPp
+KC'3ZB`"LEPpKFfdZB`"LEPpLE'PZC#jM!'*ZAf4TGLjM!'*ZAf9bFLjM!'*ZAf9
+iF#jM!'*ZAf9iF$)ZB`"LEPpRBf3ZB`"LEPpXD@)ZB`"LEPpYEfjd,Q-!BQjIEA"
+T,Q-!BQjIEA9X,Q-!BQjIF(*TE@8ZB`"LEPp`FQPZG#jM!'*ZAh*KEQ3ZB`"LEPp
+bC@0`,Q-!BQjIFfKTCR3ZB`"LEPpcFA)ZB`"LEPphEh*N,Q-!BR9QCQ9b,Q-!BR9
+QAf9bFLjM!'0IBfCL0M3ZB`"MAf9MBLjM!'0IC@jM,Q-!Bep[CQ)f0#jM!'0IFfY
+PH5jM!'0[EA"IE'PL,Q-!BepbE'8ZB`"MAhTXD@)ZB`"MEfjQ,Q-!BfpZCPpPFR)
+ZB`"MBQ0IBfYcE5jM!'0LBepPEQ-ZB`"MCQ)f0'9NC5jM!'0QBMBdC@jM,Q-!BfC
+LAf9ZBbjM!'4PFepPEQ-ZB`"PBf)cAf9ZBbjM!'9MBPpPEQ-ZB`"PC'9IBf*ME9p
+PEQ-ZB`"PEQ0IFQ9KC#jM!'CMFRP`G#jM!'CMFRP`G&pL,Q-!EfCL0M4PC'8ZB`"
+[CQ)f0'9ZBbjM!'pQBPpPEQ-ZB`"`Bf*MAf9ZBbjM!(&eC&pMDh0Y,Q-!FQ&ZC&p
+VCANZB`"bC@&N-R"hC#jM!(*PB@4IF(GN,Q-!FR"MAf9ZBbjM!(0PG&pVCANZB`"
+cG()bDf9j,Q-!Fh9`F#jM!(KMBQ0IC@jM,Q-!C'KIBfKPBfXZB`"ND&pPFR)ZB`"
+ND&pRC@iZB`"ND&pVCANZB`"ND&pXD@)ZB`"NFf&IBA0Z-5jM!'4cB9pPFR)ZB`"
+NFf&ICf9Z,Q-!C(0KAfYPH5jM!'4cB9pXD@)ZB`"NFf&IFfPRELjM!'4cB9pfFQB
+ZB`"PFR)ZB`"PFR*IB@aX,Q-!CA*bAh"bELjM!'*TEepL0M3ZB`"LD@pIC@jM,Q-
+!BQP[AfeN,Q-!BQP[AfpV,Q-!BepKE'`ZB`"ND@GPFh3ZB`"PEQ0[C'8ZB`"PGR"
+IC@jM,Q-!CAC`Af9bFLjM!'9fF&pVCANZB`"PGR"IE'PL,Q-!CAC`Ah"LC5jM!'9
+fF&p`Df9j,Q-!C9pMBQ0I-f3ZB`"PAf0LBepLCLjM!'9IBf*MAf-ZB`"PAf0LBep
+N,Q-!C9pMBQ0ID5jM!'9IBf*MAh)b,Q-!C9pMBQ0IFM8ZB`"PAf0QBPmcC#jM!'9
+IBfCLAf*Q,Q-!C9pMCQ*IBbjM!'9IBfCLAf3ZB`"PAf0QBPpT,Q-!C9pMCQ*IFM)
+ZB`"PAf0QBPpb05jM!'9IC@0LAc0N,Q-!C9pPBf*IBQBZB`"PAf9MBPpM,Q-!C9p
+PBf*IC#jM!'9IC@0LAfNZB`"PAf9MBPpb-LjM!'9IC@0LAh)e,Q-!C9pZG@aX,Q-
+!C9p[CQ*I-f3ZB`"PAfpQBPpLCLjM!'9IEfCLAf-ZB`"PAfpQBPpN,Q-!C9p[CQ*
+ID5jM!'9IEfCLAh)b,Q-!C9p[CQ*IFM8ZB`"PAh*M0#jM!'9IH'0LBepN,Q-!E9p
+NFh-ZB`"YAf4cFc%ZB`"YAfeN-LjM!'eIE@3e,Q-!E9pYC'-b,Q-!E9pZG@aX,Q-
+!E9pbDA"PE@3ZB`"YAh0SB5jM!'eIFfKK-5jM!'jKE@9c,Q-!F&pNC@-ZB`"`Af9
+ZBbjM!("IE'PL,Q-!F&p[F'9Z,Q-!F&pcC@&X,Q-!F&pcD@GZ,Q-!F&pfCA*TCRN
+ZB`"SE@&M,Q-!D9pMBQ-ZB`"TAf0QBMBd,Q-!D9pPBf)ZB`"TAfpQBMBd,Q-!D9p
+cDf9j,Q-!E'KKFfJZB`"XD&pcG'&dFbjM!'eN-PpNCh0d,Q-!E@3bAfpZC5jM!'e
+N09pNCh0d,Q-!E@3eAfpZC5jM!'eNBc*NCh0d,Q-!E@4M-Pp[EQ8ZB`"[BQTIC'&
+d,Q-!Ef*UAf9bFLjM!'pLDPpXD@)ZB`"[AfjKE@9c,Q-!F'9YAf&XE#jM!("PE9p
+PFR)ZB`"`C@eID@jQEbjM!("PE9pXD@)ZB`"`C@eIFf9KE#jM!("PE9pcD@GZ,Q-
+!F$%bAf&NC#jM!(!a-PpKG(4b,Q-!F$%bAf*KCh-ZB`"`-6*IBh*`G#jM!(!a-Pp
+MFR3ZB`"`-6*IC'9MFLjM!(!a-PpTEQPd,Q-!F$%bAfYPH5jM!(!a-PpVDA0c,Q-
+!F$%bAfaTBLjM!(!a-PpYB@-ZB`"`-6*IEA9dE#jM!(!a-PpcBQ&R,Q-!F$%bAh9
+dE#jM!("V-6*PFR)ZB`"`DcGIC'pTG#jM!("V0epXD@)ZB`"`Df0c0f9bFLjM!'e
+NAh*KEQ3ZB`"bB@jNCQPXC5jM!(*KEQ4IE'PL,Q-!FQ-bBfCL0M3ZB`"bBc*[CQ)
+f0#jM!(*M-PpMBQ-ZB`"bBc*IC@0L,Q-!FQ-bAh0VCANZB`"bBc4IC@jM,Q-!FQ-
+dAh0VCANZB`"bBc9MCQ)f0#jM!(*M0@pQBMBd,Q-!FQ-eAf9MBLjM!(*M09pPEQ-
+ZB`"bBc9IFfYPH5jM!(*YC&pNCh0d,Q-!FQeNAfpZC5jM!(*cB9pPBANZB`"bFf&
+ICA*b,Q-!FR0KAfGPELjM!(*cB9pXD@)ZB`"bFf&IEQpZC5jM!(*cB9p[B@9`,Q-
+!FR0KAh"V-5jM!(*cB9pcB@pc,Q-!FR0KAh0TCfiZB`"bFf&IFh0X,Q-!FfKK-@4
+RFh3ZB`"cD'%aAfpZC5jM!(0SB9pNCh0d,Q-!FfKKAfpZC5jM!(0dB@0V,Q-!G(K
+dAf4L,Q-!BRPIC'Pb,Q-!BRPICQPXC5jM!(Je-$PZB@eP,Q-!H$8`1A*cCA3ZB`"
+i06!jG(P`C5jM!(Je-$PIBfe`,Q-!H$8`19pN-LjM!(Je-$PIC'9Q,Q-!H$8`19p
+PFR)ZB`"i06!jAf9iG#jM!(Je-$PIE(8ZB`"i06!jAfpLDLjM!(Je-$PIFM*i,Q-
+!H$8`19pbCA%ZB`"i06!jAh0PG#jM!(Je-$PIG(Kd,Q-!H$8`19pf-bjM!(Je-$P
+IGQCj,Q-!H&pKE'`ZB`"f-f9bFLjM!(BcAf&VCANZB`"f-epKE(3ZB`"f-epLBfp
+ZFbjM!(BcAf*TG(0d,Q-!GM0IBfpZCLjM!(BcAf0`Efac,Q-!GM0IBh*XC#jM!(B
+cAf9ZG@dZB`"f-epPH(4VG5jM!(BcAfGPEQiZB`"f-epTB68ZB`"f-epTER3ZB`"
+f-epXD@)ZB`"f-ep`Dh8ZB`"f-ep`FQiZB`"f-epcDf9j,Q-!GM0IFhKZCA3ZB`"
+f-epeG'`ZB`"MF(4ICA*b,Q-!Bh*jF(4XD@)ZB`"PH&pNBA4K,Q-!E@9Y,Q-!690
+-)&0*6e9B,P"33bj-D@)!BQCIBR9QCLjM!(KIH$8`1@%ZB`"NFf&IEh0cE#jM!(J
+e-$PcF'YT,Q-!H$8`19pdFR-ZB`"f-ep`GA*`,Q-!GM0ID@jQEbjM!'*IF(*TER3
+ZB`"KAfeLFh4b,Q-!G&pcF'YT,Q-!G&pi06!jB5jM!(4IBQPdFh3ZB`"KAh0dFQj
+TC#jM!'*TEepMBLjM!'*cFepYC@dZB`"LFh0ICQ3ZB`"LFh0ICQPXC5jM!'*cFep
+ZG@aX,Q-!BQCIER9XE#jM!'*QAfjLD@mZB`"LFh0IBQP[,Q-!BPpNG@e`,Q-!C@j
+MAhGbDA3ZB`"`09pMFR"d,Q-!F$9IBh*`G$)ZB`"`-6*IER"KFbjM!("V0epKG(4
+b,Q-!F'XhAfeTE@8ZB`"`DcGIFfeTE@8ZB`"bFf&IBfKV,Q-!FR0KAfjeE'`ZB`"
+MGQ9bFfP[ELjM!%038h4bD@jR9A4TE(-ZBh"`!%9bFQpb5'&ZC'aTEQFZBh"`!%G
+PG%K89&"6,Q0`F!"0B@06Ef0VCA3ZBh"`!'ePE9pNBQFZB`"36&0dFQPZCdCeEQ0
+c8&"$,QaTBJ"LEPpMG(JZB`"bB@jNAf9bFLjM!&*KEQ4[E@PkCA)ZBh"`!(J!BA"
+`FbjM!'&`F&pbB@jN,Q-!BA0Z-A"KFR-ZB`"MB5jM!'0TF'KPFR-ZB`"MFQ`ZB`"
+MFQ`bF$FZB`"NCh0d,Q-!C'JZB`"NFf%ZB`"NFf&`BA*KE5jM!'9ZBbjM!'9bFR0
+dFLjM!'GPEQ4S,Q-!Cf9ZC(0K,Q-!Cf9ZFR0K,Q-!ER0PF5jM!'p`C@jcFf`ZB`"
+`Df0c-6)ZB`"`Df0c0bjM!("VBh-i,Q-!FQ9a,Q-!FR0K,Q-!Ff9cFepTC#jM!(0
+YD@eP,Q-!Fh"PC@3ZB`"cF'YKBbjM!(0IBf)ZB`"cAf0XD@9ZG#jM!(0IFf9bGQ9
+b,Q-!FepcEf0VCA3ZB`"fCA*TCRNZB`"fCA*cD@pZ,Q-!H$8`15jM!(0IG'PYC5j
+M!%G98dPI5@jTG#jMF(!!4e9659p$Eh*P,P"33bj-D@)!4e9659p08d`Z8&"$,Na
+TBJ"(990*Ae0*6e9B,P"33bj-D@)!1NaTBP066#j38%-Z6'PL!$T-D@*$FRP`G'm
+Z8&"$,NaTBJ"0B@028bjXD@)!690-)&*eER4TE@8f1%XZ6'PL!%p`C@j8F(4*EQ9
+d,Qm!6h"PEP4bB@jcF'pbG#j[!%p`C@j8FQ&ZFh"[FR4"F(!ZE`"08d`J8dP299J
+Z0MK,,NaTBJ"08d`J3bif1%XJ4Q%S0'PI1'3T,NaTBJ"0BA4S6'PL0MK,)%CK+$4
+TAcKN+5j-D@)!4QPbFh3J8f9RE@9ZG!"(990*Ad0[FQ8Z0MK,,NaTBJ"(990*Ade
+66#if1%XZ6'PL!%G98dPI8dP299JZ0MK,,NaTBJ!k6'PL3h*jF(4[,MBiDb"'B5J
+dD9miC#NZ6'PL!%aTBP066#if1%XJ4Q%S0'PI1'3T,NaTBJ"(CA4)9&438b"38%-
+!6h"PEP066#"38%-!4f9d5&488&-J0MK,!%aTBP066#!f1%X!6h"PEP066#!f1'X
+!6'PL8e0-)&"33`"-D@*$FRP`G'mJ8&"$!%aTBN0bHA"dEb!f1%X!1NGPG%K89&"
+6+&"33bN!6'PL)%PYF'pbG#"38%-!3Q&XE'p[EL")C@a`!%eA)%-[3bXV)&"33`"
+(B@eP3fpNC5"$EfjfCA*dCA)!4QaPH#"3FQ9`FQpMCA0cEh)!69FJ8'&cBf&X)&"
+33`"5CAS!8&"$3A0Y!%*TFfpZ)&"bCA"bEf0PFh0[FJ"B3dp'4L"*EA"[FR3J8&"
+$!&"&4L"*EA"[FR3J8&"$!$T2F'9Z8e0-!$T(CA4)9&438bJf1%XT!%aTBL"*EA"
+[FR3J0MK,!%e39b"*EA"[FR3J0MK,!%eA)%-[3bXV)$Bi5`"09b"3BA0MB@`J0MK
+,!&"&4L"*EA"[FR3J0MK,!$T-D@*68d`Z0MK,)%CK+$4TAcKN+5j-D@)!1Np`C@j
+68d`S0MKV+3"0B@028b"38%-J6'PZDf9b!%eKBdp6)$Bi5b"-D@jVCA)!8fpeFQ0
+P)&4bC@9c!%0eFh4[E5",CAPhEh*NF`""Bf0PFh-J8'&dD(-!9'&bCf9d)&0PG(4
+TEQGc!%CTE'8J6@&`F'PZCh-!3R9TE'3J4AKdFQ&c!%4PBR9RCf9b)&*eER4TE@8
+!4'9LG@GRCA)J9'&bCf9d!%-[3bXV)%0[EA"TE'9b!%-[3bXV)&GKFQjTEQGc!&"
+33b"$Ef4P4f9Z!&"33b"%DA0KFh0PE@*XCA)!8&"$)%GXEf*KE#"2F(4TE@PkCA)
+!8&"$)%aTEQYPFJ"38%-J8%9'!&"33b"3FQpUC@0d!&"33d&cE5"3B@jPE!"5CAS
+J3fpYF'PXCA)!0MK,)%0[C'9(C@i!0MK,)%4TFf&cFf9YBQaPFJ!f1%XJ4fa[BQ&
+X)%p`G'PYDATPFJ!f1%XJ6'PZDf9b!$Bi5b"3FQpUC@0d!%0'66Bi5`!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!!!!!!!!$J!
+!!!)!!!!!!!!!'`!!!!-!!!!!!!!!)`!!!!3!!!!!!!!!0J!!!!8!!!!!!!!!4`!
+!!!B!!!!!!!!!@J!!!!F!!!!!!!!!F3!!!!J!!!!!!!!!JJ!!!!N!!!!!!!!!M3!
+!!!S!!!!!!!!!P`!!!!X!!!!!!!!!SJ!!!!`!!!!!!!!!V!!!!!d!!!!!!!!!Y`!
+!!!i!!!!!!!!!`3!!!!m!!!!!!!!!c!!!!"!!!!!!!!!!eJ!!!"%!!!!!!!!!h`!
+!!")!!!!!!!!!k!!!!"-!!!!!!!!!mJ!!!"3!!!!!!!!!q`!!!"8!!!!!!!!""3!
+!!"B!!!!!!!!"$`!!!"F!!!!!!!!"'3!!!"J!!!!!!!!")J!!!"N!!!!!!!!"+`!
+!!"S!!!!!!!!"03!!!"X!!!!!!!!"2J!!!"`!!!!!!!!"5!!!!"d!!!!!!!!"8`!
+!!"i!!!!!!!!"AJ!!!"m!!!!!!!!"D3!!!#!!!!!!!!!"G!!!!#%!!!!!!!!"IJ!
+!!#)!!!!!!!!"L3!!!#-!!!!!!!!"N`!!!#3!!!!!!!!"R3!!!#8!!!!!!!!"U!!
+!!#B!!!!!!!!"X`!!!#F!!!!!!!!"[3!!!#J!!!!!!!!"a`!!!#N!!!!!!!!"d!!
+!!#S!!!!!!!!"f3!!!#X!!!!!!!!"i`!!!#`!!!!!!!!"l3!!!#d!!!!!!!!"q!!
+!!#i!!!!!!!!#!`!!!#m!!!!!!!!#$J!!!$!!!!!!!!!#'3!!!$%!!!!!!!!#*!!
+!!$)!!!!!!!!#,!!!!$-!!!!!!!!#03!!!$3!!!!!!!!#2`!!!$8!!!!!!!!#5J!
+!!$B!!!!!!!!#93!!!$F!!!!!!!!#A3!!!$J!!!!!!!!#CJ!!!$N!!!!!!!!#F!!
+!!$S!!!!!!!!#H!!!!$X!!!!!!!!#J`!!!$`!!!!!!!!#L`!!!$d!!!!!!!!#P!!
+!!$i!!!!!!!!#R`!!!$m!!!!!!!!#U3!!!%!!!!!!!!!#X`!!!%%!!!!!!!!#Z`!
+!!%)!!!!!!!!#a!!!!%-!!!!!!!!#c3!!!%3!!!!!!!!#eJ!!!%8!!!!!!!!#i!!
+!!%B!!!!!!!!#k3!!!%F!!!!!!!!#p!!!!%J!!!!!!!!#r!!!!%N!!!!!!!!$"J!
+!!%S!!!!!!!!$%3!!!%X!!!!!!!!$'J!!!%`!!!!!!!!$)`!!!%d!!!!!!!!$,J!
+!!%i!!!!!!!!$13!!!%m!!!!!!!!$4!!!!&!!!!!!!!!$6`!!!&%!!!!!!!!$@J!
+!!&)!!!!!!!!$B`!!!&-!!!!!!!!$D`!!!&3!!!!!!!!$GJ!!!&8!!!!!!!!$J!!
+!!&B!!!!!!!!$L`!!!&F!!!!!!!!$P!!!!&J!!!!!!!!$R3!!!&N!!!!!!!!$U!!
+!!&S!!!!!!!!$X`!!!&X!!!!!!!!$[J!!!&`!!!!!!!!$b3!!!&d!!!!!!!!$d3!
+!!&i!!!!!!!!$fJ!!!&m!!!!!!!!$i`!!!'!!!!!!!!!$lJ!!!'%!!!!!!!!$q!!
+!!')!!!!!!!!%!3!!!'-!!!!!!!!%$!!!!'3!!!!!!!!%&3!!!'8!!!!!!!!%(J!
+!!'B!!!!!!!!%*`!!!'F!!!!!!!!%-J!!!'J!!!!!!!!%23!!!'N!!!!!!!!%5!!
+!!'S!!!!!!!!%83!!!'X!!!!!!!!%@`!!!'`!!!!!!!!%B`!!!'d!!!!!!!!%E!!
+!!'i!!!!!!!!%G!!!!'m!!!!!!!!%I3!!!(!!!!!!!!!%K`!!!(%!!!!!!!!%NJ!
+!!()!!!!!!!!%Q`!!!(-!!!!!!!!%S`!!!(3!!!!!!!!%V3!!!(8!!!!!!!!%YJ!
+!!(B!!!!!!!!%[`!!!(F!!!!!!!!%b!!!!(J!!!!!!!!%d`!!!(N!!!!!!!!%f`!
+!!(S!!!!!!!!%i`!!!(X!!!!!!!!%l!!!!(`!!!!!!!!%p!!!!(d!!!!!!!!%r3!
+!!(i!!!!!!!!&#!!!!(m!!!!!!!!&%3!!!)!!!!!!!!!&'J!!!)%!!!!!!!!&*3!
+!!))!!!!!!!!&,`!!!)-!!!!!!!!&13!!!)3!!!!!!!!&3`!!!)8!!!!!!!!&6J!
+!!)B!!!!!!!!&9`!!!)F!!!!!!!!&B!!!!)J!!!!!!!!&D`!!!)N!!!!!!!!&G!!
+!!)S!!!!!!!!&I3!!!)X!!!!!!!!&KJ!!!)`!!!!!!!!&N!!!!!#0!!!!!!!!"CN
+!!!#1!!!!!!!!"D)!!!#2!!!!!!!!"D`!!!#3!!!!!!!!!!@e!!!!N3!!!!!!!!@
+q!!!!NJ!!!!!!!!A*!!!!N`!!!!!!!!A8!!!!P!!!!!!!!!AH!!!!P3!!!!!!!!A
+S!!!!PJ!!!!!!!!Ac!!!!P`!!!!!!!!Am!!!!Q!!!!!!!!!B'!!!!Q3!!!!!!!!B
+2!!!!QJ!!!!!!!!BC!!!!Q`!!!!!!!!BM!!!!R!!!!!!!!!BV!!!!R3!!!!!!!!B
+c!!!!RJ!!!!!!!!Bp!!!!R`!!!!!!!!C'!!!!S!!!!!!!!!C4!!!!S3!!!!!!!!C
+C!!!!SJ!!!!!!!!CL!!!!S`!!!!!!!!CT!!!!T!!!!!!!!!Cd!!!!T3!!!!!!!!C
+r!!!!TJ!!!!!!!!D*!!!!T`!!!!!!!!D8!!!!U!!!!!!!!!DI!!!!U3!!!!!!!!D
+T!!!!UJ!!!!!!!!Dc!!!!U`!!!!!!!!Dq!!!!V!!!!!!!!!E)!!!!V3!!!!!!!!E
+A!!!!VJ!!!!!!!!EL!!!!V`!!!!!!!!EV!!!!X!!!!!!!!!Ef!!!!X3!!!!!!!!F
+"!!!!XJ!!!!!!!!F-!!!!X`!!!!!!!!F@!!!!Y!!!!!!!!!FK!!!!Y3!!!!!!!!F
+X!!!!YJ!!!!!!!!Fh!!!!Y`!!!!!!!!G#!!!!Z!!!!!!!!!G0!!!!Z3!!!!!!!!G
+A!!!!ZJ!!!!!!!!GK!!!!Z`!!!!!!!!GV!!!![!!!!!!!!!Gb!!!![3!!!!!!!!G
+p!!!![J!!!!!!!!H)!!!![`!!!!!!!!H4!!!!`!!!!!!!!!HD!!!!`3!!!!!!!!H
+M!!!!`J!!!!!!!!HX!!!!``!!!!!!!!Hh!!!!a!!!!!!!!!I"!!!!a3!!!!!!!!I
+,!!!!aJ!!!!!!!!I9!!!!a`!!!!!!!!II!!!!b!!!!!!!!!IU!!!!b3!!!!!!!!I
+d!!!!bJ!!!!!!!!Ik!!!!b`!!!!!!!!J%!!!!c!!!!!!!!!J1!!!!c3!!!!!!!!J
+B!!!!cJ!!!!!!!!JL!!!!c`!!!!!!!!JV!!!!d!!!!!!!!!Jd!!!!d3!!!!!!!!J
+m!!!!dJ!!!!!!!!K&!!!!d`!!!!!!!!K1!!!!e!!!!!!!!!KB!!!!e3!!!!!!!!K
+L!!!!eJ!!!!!!!!KX!!!!e`!!!!!!!!Kf!!!!f!!!!!!!!!L!!!!!f3!!!!!!!!L
+,!!!!fJ!!!!!!!!L@!!!!f`!!!!!!!!LK!!!!h!!!!!!!!!LV!!!!h3!!!!!!!!L
+e!!!!hJ!!!!!!!!Lr!!!!h`!!!!!!!!M+!!!!i!!!!!!!!!M9!!!!i3!!!!!!!!M
+J!!!!iJ!!!!!!!!MV!!!!i`!!!!!!!!Me!!!!j!!!!!!!!!Mr!!!!j3!!!!!!!!N
+*!!!!jJ!!!!!!!!N8!!!!j`!!!!!!!!NI!!!!k!!!!!!!!!NU!!!!k3!!!!!!!!N
+e!!!!kJ!!!!!!!!Nr!!!!k`!!!!!!!!P*!!!!l!!!!!!!!!P6!!!!l3!!!!!!!!P
+H!!!!lJ!!!!!!!!PT!!!!l`!!!!!!!!Pb!!!!m!!!!!!!!!Pp!!!!m3!!!!!!!!Q
+)!!!!mJ!!!!!!!!Q5!!!!m`!!!!!!!!QF!!!!p!!!!!!!!!QQ!!!!p3!!!!!!!!Q
+a!!!!pJ!!!!!!!!Qm!!!!p`!!!!!!!!R%!!!!q!!!!!!!!!R2!!!!q3!!!!!!!!R
+A!!!!qJ!!!!!!!!RJ!!!!q`!!!!!!!!RS!!!!r!!!!!!!!!R`!!!!r3!!!!!!!!R
+j!!!!rJ!!!!!!!!S#!!!!r`!!!!!!!!S0!!!"!!!!!!!!!!S9!!!"!3!!!!!!!!S
+H!!!"!J!!!!!!!!SQ!!!"!`!!!!!!!!SZ!!!""!!!!!!!!!Sf!!!""3!!!!!!!!S
+q!!!""J!!!!!!!!T(!!!""`!!!!!!!!T3!!!"#!!!!!!!!!TC!!!"#3!!!!!!!!T
+N!!!"#J!!!!!!!!TV!!!"#`!!!!!!!!Tc!!!"$!!!!!!!!!Tp!!!"$3!!!!!!!!U
+&!!!"$J!!!!!!!!U2!!!"$`!!!!!!!!UB!!!"%!!!!!!!!!UJ!!!"%3!!!!!!!!U
+V!!!"%J!!!!!!!!Uf!!!"%`!!!!!!!!V!!!!"&!!!!!!!!!V,!!!"&3!!!!!!!!V
+9!!!"&J!!!!!!!!VJ!!!"&`!!!!!!!!VV!!!"'!!!!!!!!!Ve!!!"'3!!!!!!!!V
+r!!!"'J!!!!!!!!X*!!!"'`!!!!!!!!X6!!!"(!!!!!!!!!XG!!!"(3!!!!!!!!X
+R!!!"(J!!!!!!!!Xb!!!"(`!!!!!!!!Xm!!!")!!!!!!!!!Y(!!!")3!!!!!!!!Y
+5!!!")J!!!!!!!!YF!!!")`!!!!!!!!YR!!!"*!!!!!!!!!Yb!!!"*3!!!!!!!!Y
+p!!!"*J!!!!!!!!Z(!!!"*`!!!!!!!!Z5!!!"+!!!!!!!!!ZG!!!"+3!!!!!!!!Z
+R!!!"+J!!!!!!!!Zb!!!"+`!!!!!!!!Zm!!!",!!!!!!!!!['!!!",3!!!!!!!![
+4!!!",J!!!!!!!![F!!!",`!!!!!!!![Q!!!"-!!!!!!!!![`!!!"-3!!!!!!!![
+l!!!"-J!!!!!!!!`&!!!"-`!!!!!!!!`3!!!"0!!!!!!!!!`D!!!"03!!!!!!!!`
+P!!!"0J!!!!!!!!``!!!"0`!!!!!!!!`l!!!"1!!!!!!!!!a'!!!"13!!!!!!!!a
+3!!!"1J!!!!!!!!aD!!!"1`!!!!!!!!aP!!!"2!!!!!!!!!a[!!!"23!!!!!!!!a
+k!!!"2J!!!!!!!!b&!!!"2`!!!!!!!!b3!!!!!8!!!!!!!!!-QJ!!!8%!!!!!!!!
+-T!!!!8)!!!!!!!!-V`!!!8-!!!!!!!!-ZJ!!!83!!!!!!!!-a!!!!88!!!!!!!!
+-cJ!!!8B!!!!!!!!-f!!!!8F!!!!!!!!-iJ!!!8J!!!!!!!!-l!!!!8N!!!!!!!!
+-p`!!!8S!!!!!!!!0!J!!!8X!!!!!!!!0$!!!!8`!!!!!!!!0&`!!!8d!!!!!!!!
+0)J!!!8i!!!!!!!!0,!!!!8m!!!!!!!!00`!!!9!!!!!!!!!03J!!!9%!!!!!!!!
+063!!!9)!!!!!!!!09`!!!9-!!!!!!!!0A`!!!93!!!!!!!!0D!!!!98!!!!!!!!
+0F3!!!9B!!!!!!!!0H`!!!9F!!!!!!!!0KJ!!!9J!!!!!!!!0N3!!!9N!!!!!!!!
+0R!!!!9S!!!!!!!!0T`!!!9X!!!!!!!!0X3!!!9`!!!!!!!!0[!!!!9d!!!!!!!!
+0a`!!!9i!!!!!!!!0dJ!!!9m!!!!!!!!0h!!!!@!!!!!!!!!0j`!!!@%!!!!!!!!
+0mJ!!!@)!!!!!!!!0r3!!!@-!!!!!!!!1#!!!!@3!!!!!!!!1%`!!!@8!!!!!!!!
+1(3!!!@B!!!!!!!!1+!!!!@F!!!!!!!!1-!!!!@J!!!!!!!!11!!!!@N!!!!!!!!
+13J!!!@S!!!!!!!!15`!!!@X!!!!!!!!19J!!!@`!!!!!!!!1B3!!!@d!!!!!!!!
+1D`!!!@i!!!!!!!!1GJ!!!@m!!!!!!!!1J!!!!A!!!!!!!!!1LJ!!!A%!!!!!!!!
+1P3!!!A)!!!!!!!!1R`!!!A-!!!!!!!!1U!!!!A3!!!!!!!!1X3!!!A8!!!!!!!!
+1ZJ!!!AB!!!!!!!!1``!!!AF!!!!!!!!1c!!!!AJ!!!!!!!!1eJ!!!AN!!!!!!!!
+1i3!!!AS!!!!!!!!1kJ!!!AX!!!!!!!!1p!!!!A`!!!!!!!!1r`!!!Ad!!!!!!!!
+2#3!!!Ai!!!!!!!!2$`!!!Am!!!!!!!!2)3!!!B!!!!!!!!!2+`!!!B%!!!!!!!!
+203!!!B)!!!!!!!!23!!!!B-!!!!!!!!25`!!!B3!!!!!!!!29J!!!B8!!!!!!!!
+2B!!!!BB!!!!!!!!2DJ!!!BF!!!!!!!!2G!!!!BJ!!!!!!!!2IJ!!!BN!!!!!!!!
+2K`!!!BS!!!!!!!!2N3!!!BX!!!!!!!!2Q`!!!B`!!!!!!!!2TJ!!!Bd!!!!!!!!
+2V`!!!Bi!!!!!!!!2Z3!!!Bm!!!!!!!!2`J!!!C!!!!!!!!!!$md!!!'4!!!!!!!
+!$pJ!!!'5!!!!!!!!$q)!!!'6!!!!!!!!$q`!!!'8!!!!!!!!$rB!!!'9!!!!!!!
+!$rm!!!'@!!!!!!!!%!S!!!'A!!!!!!!!%"3!!!'B!!!!!!!!%"m!!!'C!!!!!!!
+!%#S!!!'D!!!!!!!!%$8!!!'E!!!!!!!!%%!!!!'F!!!!!!!!%%`!!!'G!!!!!!!
+!%&B!!!'H!!!!!!!!%'%!!!'I!!!!!!!!%'`!!!'J!!!!!!!!%(i!!!'K!!!!!!!
+!%*!!!!!"SJ!!!!!!!"#G!!!"S`!!!!!!!"#V!!!"T!!!!!!!!"#e!!!"T3!!!!!
+!!"$+!!!"TJ!!!!!!!"$6!!!"T`!!!!!!!"$H!!!"U!!!!!!!!"$Y!!!"U3!!!!!
+!!"$[!!!"UJ!!!!!!!"$f!!!"U`!!!!!!!"%"!!!"V!!!!!!!!"%-!!!"V3!!!!!
+!!"%4!!!"VJ!!!!!!!"%E!!!"V`!!!!!!!"%K!!!"X!!!!!!!!"%U!!!"X3!!!!!
+!!"%a!!!"XJ!!!!!!!"%f!!!"X`!!!!!!!"%m!!!"Y!!!!!!!!"&(!!!"Y3!!!!!
+!!"&0!!!"YJ!!!!!!!"&@!!!"Y`!!!!!!!"&H!!!"Z!!!!!!!!"&R!!!"Z3!!!!!
+!!"&`!!!"ZJ!!!!!!!"&h!!!"Z`!!!!!!!"'"!!!"[!!!!!!!!"'+!!!"[3!!!!!
+!!"'5!!!"[J!!!!!!!"'D!!!"[`!!!!!!!"'J!!!"`!!!!!!!!"'Q!!!"`3!!!!!
+!!"'`!!!"`J!!!!!!!"'i!!!"``!!!!!!!"(!!!!"a!!!!!!!!"()!!!"a3!!!!!
+!!"(2!!!"aJ!!!!!!!"(D!!!"a`!!!!!!!"(P!!!"b!!!!!!!!"(`!!!"b3!!!!!
+!!"(j!!!"bJ!!!!!!!")$!!!"b`!!!!!!!")+!!!"c!!!!!!!!")6!!!"c3!!!!!
+!!")K!!!"cJ!!!!!!!")c!!!"c`!!!!!!!"*%!!!"d!!!!!!!!"*A!!!"d3!!!!!
+!!"*R!!!"dJ!!!!!!!"*k!!!"d`!!!!!!!"+%!!!"e!!!!!!!!"+A!!!"e3!!!!!
+!!"+P!!!"eJ!!!!!!!"+e!!!"e`!!!!!!!",)!!!"f!!!!!!!!",D!!!"f3!!!!!
+!!",b!!!"fJ!!!!!!!"-,!!!"f`!!!!!!!"-C!!!"h!!!!!!!!"-V!!!"h3!!!!!
+!!"-m!!!"hJ!!!!!!!"02!!!"h`!!!!!!!"0X!!!"i!!!!!!!!"1&!!!"i3!!!!!
+!!"15!!!"iJ!!!!!!!"1H!!!"i`!!!!!!!"1V!!!"j!!!!!!!!"1f!!!"j3!!!!!
+!!"2#!!!"jJ!!!!!!!"20!!!"j`!!!!!!!"2E!!!"k!!!!!!!!"2T!!!"k3!!!!!
+!!"2i!!!"kJ!!!!!!!"3(!!!"k`!!!!!!!"38!!!"l!!!!!!!!"3K!!!"l3!!!!!
+!!"3d!!!"lJ!!!!!!!"4'!!!"l`!!!!!!!"48!!!"m!!!!!!!!"4B!!!"m3!!!!!
+!!"4I!!!"mJ!!!!!!!"4b!!!"m`!!!!!!!"5$!!!"p!!!!!!!!"55!!!"p3!!!!!
+!!"5E!!!"pJ!!!!!!!"5U!!!"p`!!!!!!!"5j!!!"q!!!!!!!!"6)!!!"q3!!!!!
+!!"69!!!"qJ!!!!!!!"6M!!!"q`!!!!!!!"6b!!!"r!!!!!!!!"8-!!!"r3!!!!!
+!!"8D!!!"rJ!!!!!!!"8V!!!"r`!!!!!!!"8m!!!#!!!!!!!!!"9*!!!#!3!!!!!
+!!"9C!!!#!J!!!!!!!"9Q!!!#!`!!!!!!!"9f!!!#"!!!!!!!!"@%!!!#"3!!!!!
+!!"@4!!!#"J!!!!!!!"@L!!!#"`!!!!!!!"@b!!!##!!!!!!!!"A"!!!##3!!!!!
+!!"A3!!!##J!!!!!!!"AF!!!##`!!!!!!!"AY!!!#$!!!!!!!!"B#!!!#$3!!!!!
+!!"B0!!!#$J!!!!!!!"B9!!!#$`!!!!!!!"BK!!!#%!!!!!!!!"BZ!!!#%3!!!!!
+!!"Bl!!!#%J!!!!!!!"C(!!!#%`!!!!!!!"CB!!!#&!!!!!!!!"CY!!!#&3!!!!!
+!!"Ci!!!#&J!!!!!!!"D%!!!#&`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$!!!!$!!!!!-
+!!!!-Y0ifDrrrqUS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!#&`!!!L!!!"D,!!!B!!!!!KF!!!!!!!!!!!!!!!!
+!!!!!9%9B9!!!!!)!!!(q!!!"r`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#`MlJ!!!!!!!!!3!
+#`NI`!!)!!!!!!!!!!!!!!X)fJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!)!!!%!!!!!"3!!Irm!!!!!Irm!!!!!Irm!!!!!Irm!!!!-!!%!!J!%!!!
+!"8!!!!B!!3!"1J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!%!!!$rrrrr!!!!!`!"!!%k1J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!3!!!2rrrrm!!!!%!!%!!6SkD@jME(9NC6S!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!rrrrrd!!!!)!!3!"1J!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$rrrrr3!!!!`!#!!%k6@&M6e-
+J8h9`F'pbG$S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!2rrrrp!!!!%!!)
+!!6T08d`k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!rrr
+rrd!!!!8!#J!!6@&M6e-J8&"$)%aTEQYPFJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!4f9d5&488&-J8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!%k!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!&0B@028b"38%-J6'PZDf9b!!!
+!!!!!!!!!!!!!!!!!!!!H39"36!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!3A"`E!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!"J!!!!68e-3J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!6'PL)%PYF'pbG#"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69"-4J!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6'PL)%PYF'pbG#"38%-!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!69G$4!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!8P053`!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!"J!!!!9%9B9#jLD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!3Q&XE'p[EL")C@a`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jM!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!9%9B9#jM+bX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jMB`!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!9%9B9#jMF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jMF(!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!9%9B9#jPH(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jRB`!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4f&YC80[C'8J3fpZGQ9bG'9b!!!
+!!!!!!!!!!!!!!!"!!!!!9%9B9#jS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!!9%9B9#jX!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4QaPH#"3FQ9`FQpMCA0cEh)!!!!
+!!!!!!!!!!!!!!!#!!!!!9%9B9#j`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!69FJ8'&cBf&X)&"33`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j`BA-
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)&"33`!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!9%9B9#j`BfJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`BfJ
+V+`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!
+!!!!!!!!!!!!!!!#!!!!!9%9B9#j`F(8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!69FJ8'&cBf&X)&"33`!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#jb!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8Q9k!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!9%9B9#jc!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!8&"$3A0Y!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jj!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3QPcEfiJ8(*PF(*[Bf9cFfpb!!!
+!!!!!!!!!!!!!!!#!!!!!@%024J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!@%024NBJ5@e`Eh*d)&"33`!!!!!!!!!!!!!!!!!!!!!!!!!!C'pMG3!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!"J!!!!FR0bB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!FfKXBJ!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%9')%PYF'pbG#"38%-!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!Fh4eBJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!8%9')%PYF'pbG#"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#jNEf-
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!"3!!!!!!8"!3!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!!"!!!
+!!!8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!"!3!!E@&TEJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!3!"!!!!!3%"!3%!!3%!!!!!!!%"!!!
+"!3!"!!!"!!%!!!!!!!!!!!!)!3!"!3!"!3!!!!%!!!N!!"G0B@028b"8EfpXBQp
+i)%4&3P9()$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!r2cmr39"36!!!!B"B`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$mr2cm!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!0!!%!!!!!!""I69G&8NY6Ah"bC@CTH#jS!!!!!!!!!!!!!!!!!!!!!!!
+"!!!"!!!!!!!"!!!!!!!!!!!!!!8"!3%!!!%"!!%!!!!!"!!!!!!!!!!!!!!!!!!
+!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"IAh0dBA*d!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!3!!#8ePFQGP)%peG!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$m
+r2cp"8&"-!!%"!!!%)#!J)!1ARe!$GYpi!`@Z%!!&!J%!!3%!!3%"!!!"!!!!!!!
+!!!%"!3%!!3%!!3!""!!!!!!!!!!!!!!(!3%!!3!!!3!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+IAh0dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8!!!e(CA4)9&438bK38%-T!!!!!!!
+!!!!!!!!!!!!!!!!!2cmr2d&38%`!!!3!!!!%!!!!!%!!!&M!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%r2cmr!!!!!!!
+!!!)!!!!#!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+#!&!!!3!"!!%!!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8*d024%8R)#G%394"*b!R8%P$9#F
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!3!
+!!!%#!3!!!!!!!3!"!`!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!!)!!!!#!J%!!!!
+!!!%!!3-!!!!!!!!!!!!!!!!%!!!!!!!!!!!"!!!$!!!!!`)"!!!!!!!"!!%$!!!
+!!!!!!!!!!!!!"!!!!!!!!!!!!3!!"!!!!!3#!3!!!!!!!3!"!`!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!%!!!8!!!!&!J%!!!!!!!%!!3-!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!!'!!!!"J)"!!!!!!!"!!%$!!!!!!!!!!!!!!!!"3!!!!!!!!!!!3!!"`!
+!!!F#!3!!!!!!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!!J!!!!)!J%!!!!
+!!!%!!3-!!!!!!!!!!!!!!!!&!!!!!!!!!!!"!!!*!!!!#3)"!!!!!!!"!!%$!!!
+!!!!!!!!!!!!!"3!!!!!!!!!!!3!!#J!!!!S#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!!X!!!!,!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!!-!!!!$!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!$3!
+!!!d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!!i!!!!1!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!2!!!!$`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!%!!!!"!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!"%!!!!4!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!!5!!!!%J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!%`!
+!!"-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!"3!!!!8!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!9!!!!&3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!&J!!!"B#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!"F!!!!A!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!!B!!!!'!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!'3!
+!!"N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!"S!!!!D!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!E!!!!'`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!(!!!!"`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!"d!!!!G!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!!H!!!!(J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!(`!
+!!"m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!#!!!!!J!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!K!!!!)3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!)J!!!#)#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!#-!!!!M!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!!N!!!!*!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!*3!
+!!#8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!#B!!!!Q!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!R!!!!*`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!+!!!!#J#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!#N!!!!T!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!!U!!!!+J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!+`!
+!!#X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!#`!!!!X!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!Y!!!!,3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!,J!!!#i#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!#m!!!![!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!!`!!!!-!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!-3!
+!!$%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!$)!!!!b!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!c!!!!-`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!0!!!!$3#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!$8!!!!e!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!!f!!!!0J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!0`!
+!!$F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!$J!!!!i!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!j!!!!13)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!1J!!!$S#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!$X!!!!l!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!!m!!!!2!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!23!
+!!$d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!$i!!!!q!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!r!!!!2`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!3!!!!%!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!%%!!!""!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!"#!!!!3J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!3`!
+!!%-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!%3!!!"%!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"&!!!!43)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!4J!!!%B#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!%F!!!"(!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!")!!!!5!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!53!
+!!%N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!%S!!!"+!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!",!!!!5`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!6!!!!%`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!%d!!!"0!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!"1!!!!6J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!6`!
+!!%m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!&!!!!"3!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"4!!!!83)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!8J!!!&)#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!&-!!!"6!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!"8!!!!9!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!93!
+!!&8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!&B!!!"@!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"A!!!!9`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!@!!!!&J#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!&N!!!"C!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!"D!!!!@J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!@`!
+!!&X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!&`!!!"F!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"G!!!!A3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!AJ!!!&i#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!&m!!!"I!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!"J!!!!B!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!B3!
+!!'%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!')!!!"L!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"M!!!!B`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!C!!!!'3#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!'8!!!"P!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!"Q!!!!CJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!C`!
+!!'F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!'J!!!"S!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"T!!!!D3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!DJ!!!'S#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!'X!!!"V!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!"X!!!!E!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!E3!
+!!'d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!'i!!!"Z!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"[!!!!E`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!F!!!!(!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!(%!!!"a!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!"b!!!!FJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!F`!
+!!(-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!(3!!!"d!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"e!!!!G3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!GJ!!!(B#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!(F!!!"h!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!"i!!!!H!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!H3!
+!!(N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!(S!!!"k!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"l!!!!H`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!I!!!!(`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!(d!!!"p!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!"q!!!!IJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!I`!
+!!(m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!)!!!!#!!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#"!!!!J3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!JJ!!!))#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!)-!!!#$!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!#%!!!!K!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!K3!
+!!)8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!)B!!!#'!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#(!!!!K`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!L!!!!)J#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!)N!!!#*!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!#+!!!!LJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!L`!
+!!)X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!)`!!!#-!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#0!!!!M3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!3!!MJ!!!)i#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!%!!)m!!!#2!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!"!!#3!!!!!*!!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#
+4!!!!N3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!NJ!!!*)#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!*-!!!#6!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#8!!!!P!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!!P3!!!*8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!*B!!!#@!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#
+A!!!!P`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!Q!!!!*J#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!*N!!!#C!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#D!!!!QJ)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!!Q`!!!*X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!*`!!!#F!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#
+G!!!!R3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!RJ!!!*i#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!*m!!!#I!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#J!!!!S!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!!S3!!!+%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!+)!!!#L!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#
+M!!!!S`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!T!!!!+3#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!+8!!!#P!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#Q!!!!TJ)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!!T`!!!+F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!+J!!!#S!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#
+T!!!!U3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!UJ!!!+S#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!+X!!!#V!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#X!!!!V!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!!V3!!!+d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!+i!!!#Z!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#
+[!!!!V`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!X!!!!,!#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!,%!!!#a!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#b!!!!XJ)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!!X`!!!,-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!,3!!!#d!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#
+e!!!!Y3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!YJ!!!,B#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!,F!!!#h!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#i!!!!Z!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!!Z3!!!,N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!,S!!!#k!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#
+l!!!!Z`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!![!!!!,`#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!,d!!!#p!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#q!!!![J)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!![`!!!,m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!-!!!!$!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
+"!!!!`3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!`J!!!-)#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!--!!!$$!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$%!!!!a!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!!a3!!!-8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!-B!!!$'!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
+(!!!!a`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!b!!!!-J#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!-N!!!$*!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$+!!!!bJ)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!!b`!!!-X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!-`!!!$-!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
+0!!!!c3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!cJ!!!-i#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!-m!!!$2!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$3!!!!d!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!!d3!!!0%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!0)!!!$5!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
+6!!!!d`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!e!!!!03#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!08!!!$9!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$@!!!!eJ)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!!e`!!!0F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!0J!!!$B!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
+C!!!!f3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!fJ!!!0S#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!0X!!!$E!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$F!!!!h!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!!h3!!!0d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!0i!!!$H!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
+I!!!!h`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!i!!!!1!#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!1%!!!$K!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$L!!!!iJ)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!!i`!!!1-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!13!!!$N!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
+P!!!!j3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!jJ!!!1B#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!1F!!!$R!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$S!!!!k!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!!k3!!!1N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!1S!!!$U!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
+V!!!!k`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!l!!!!1`#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!1d!!!$Y!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$Z!!!!lJ)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!!l`!!!1m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!2!!!!$`!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
+a!!!!m3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!mJ!!!2)#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!2-!!!$c!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$d!!!!p!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!!p3!!!28#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!2B!!!$f!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
+h!!!!p`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!q!!!!2J#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!2N!!!$j!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$k!!!!qJ)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!!q`!!!2X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!2`!!!$m!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
+p!!!!r3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!rJ!!!2i#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!2m!!!$r!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%!!!!"!!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"!3!!!3%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!3)!!!%#!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
+$!!!"!`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!""!!!!33#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!38!!!%&!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%'!!!""J)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!""`!!!3F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!3J!!!%)!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
+*!!!"#3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"#J!!!3S#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!3X!!!%,!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%-!!!"$!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"$3!!!3d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!3i!!!%1!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
+2!!!"$`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"%!!!!4!#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!4%!!!%4!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%5!!!"%J)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"%`!!!4-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!43!!!%8!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
+9!!!"&3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"&J!!!4B#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!4F!!!%A!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%B!!!"'!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"'3!!!4N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!4S!!!%D!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
+E!!!"'`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"(!!!!4`#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!4d!!!%G!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%H!!!"(J)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"(`!!!4m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!5!!!!%J!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
+K!!!")3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!")J!!!5)#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!5-!!!%M!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%N!!!"*!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"*3!!!58#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!5B!!!%Q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
+R!!!"*`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"+!!!!5J#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!5N!!!%T!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%U!!!"+J)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"+`!!!5X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!5`!!!%X!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
+Y!!!",3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!",J!!!5i#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!5m!!!%[!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%`!!!"-!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"-3!!!6%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!6)!!!%b!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
+c!!!"-`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"0!!!!63#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!68!!!%e!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%f!!!"0J)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"0`!!!6F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!6J!!!%i!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
+j!!!"13)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"1J!!!6S#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!6X!!!%l!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%m!!!"2!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"23!!!6d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!6i!!!%q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
+r!!!"2`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"3!!!!8!#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!8%!!!&"!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&#!!!"3J)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"3`!!!8-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!83!!!&%!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
+&!!!"43)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"4J!!!8B#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!8F!!!&(!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&)!!!"5!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"53!!!8N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!8S!!!&+!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
+,!!!"5`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"6!!!!8`#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!8d!!!&0!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&1!!!"6J)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"6`!!!8m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!9!!!!&3!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
+4!!!"83)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"8J!!!9)#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!9-!!!&6!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&8!!!"9!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"93!!!98#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!9B!!!&@!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
+A!!!"9`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"@!!!!9J#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!9N!!!&C!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&D!!!"@J)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"@`!!!9X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!9`!!!&F!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
+G!!!"A3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"AJ!!!9i#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!9m!!!&I!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&J!!!"B!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"B3!!!@%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!@)!!!&L!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
+M!!!"B`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"C!!!!@3#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!@8!!!&P!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&Q!!!"CJ)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"C`!!!@F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!@J!!!&S!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
+T!!!"D3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"DJ!!!@S#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!@X!!!&V!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&X!!!"E!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"E3!!!@d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!@i!!!&Z!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
+[!!!"E`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"F!!!!A!#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!A%!!!&a!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&b!!!"FJ)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"F`!!!A-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!A3!!!&d!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
+e!!!"G3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"GJ!!!AB#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!AF!!!&h!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&i!!!"H!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"H3!!!AN#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!AS!!!&k!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
+l!!!"H`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"I!!!!A`#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!Ad!!!&p!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&q!!!"IJ)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"I`!!!Am#!3!!!!!!!3!"!`!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!B!!!!'!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'
+"!!!"J3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"JJ!!!B)#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!B-!!!'$!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'%!!!"K!)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"K3!!!B8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!BB!!!''!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'
+(!!!"K`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"L!!!!BJ#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!BN!!!'*!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'+!!!"LJ)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!3!"L`!!!BX#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!B`!!!'-!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'
+0!!!"M3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"MJ!!!Bi#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!Bm!!!'2!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'3!!!!!C!!!J%!!!!!!!%!!3%!!!!!!!!
+!!!!!!!!"!!!!!!!!!!!"!!'4!!!"N3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!
+!!!!!!!!!!3!"NJ!!!C)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%
+!!C-!!!'6!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'8!!!"P!)
+"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"P3!!!C8#!3!!!!!!!3!
+"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!CB!!!'@!J%!!!!!!!%!!3%!!!!!!!!
+!!!!!!!!"!!!!!!!!!!!"!!'A!!!"P`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!
+!!!!!!!!!!3!"Q!!!!CJ#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%
+!!CN!!!'C!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'D!!!"QJ)
+"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"Q`!!!CX#!3!!!!!!!3!
+"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!C`!!!'F!J%!!!!!!!%!!3%!!!!!!!!
+!!!!!!!!"!!!!!!!!!!!"!!'G!!!"R3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!
+!!!!!!!!!!3!"RJ!!!Ci#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%
+!!Cm!!!'I!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'J!!!"S!)
+"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"S3!!!D%#!3!!!!!!!3!
+"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!D)!!!'L!J%!!!!!!!%!!3%!!!!!!!!
+!!!!!!!!"!!!!!!!!!!!"!!'M!!!"S`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!
+!!!!!!!!!!3!"T!!!!D3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%
+!!D8!!!'P!J%!!!!!!!%!!3-!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'Q!!!"TJ)
+"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"T`!!!DF#!3!!!!!!!3!
+"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!DJ!!!'S!J%!!!!!!!%!!3%!!!!!!!!
+!!!!!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!!)!!!!$!!!!"!!!!!8!!!!'!!!!"`!
+!!!J!!!!*!!!!#J!!!!X!!!!-!!!!$3!!!!i!!!!2!!!!%!!!!"%!!!!5!!!!%`!
+!!"3!!!!9!!!!&J!!!"F!!!!B!!!!'3!!!"S!!!!E!!!!(!!!!"d!!!!H!!!!(`!
+!!#!!!!!K!!!!)J!!!#-!!!!N!!!!*3!!!#B!!!!R!!!!+!!!!#N!!!!U!!!!+`!
+!!#`!!!!Y!!!!,J!!!#m!!!!`!!!!-3!!!$)!!!!c!!!!0!!!!$8!!!!f!!!!0`!
+!!$J!!!!j!!!!1J!!!$X!!!!m!!!!23!!!$i!!!!r!!!!3!!!!%%!!!"#!!!!3`!
+!!%3!!!"&!!!!4J!!!%F!!!")!!!!53!!!%S!!!",!!!!6!!!!%d!!!"1!!!!6`!
+!!&!!!!"4!!!!8J!!!&-!!!"8!!!!93!!!&B!!!"A!!!!@!!!!&N!!!"D!!!!@`!
+!!&`!!!"G!!!!AJ!!!&m!!!"J!!!!B3!!!')!!!"M!!!!C!!!!'8!!!"Q!!!!C`!
+!!'J!!!"T!!!!DJ!!!'X!!!"X!!!!E3!!!'i!!!"[!!!!F!!!!(%!!!"b!!!!F`!
+!!(3!!!"e!!!!GJ!!!(F!!!"i!!!!H3!!!(S!!!"l!!!!I!!!!(d!!!"q!!!!I`!
+!!)!!!!#"!!!!JJ!!!)-!!!#%!!!!K3!!!)B!!!#(!!!!L!!!!)N!!!#+!!!!L`!
+!!)`!!!#0!!!!MJ!!!)m!!!#3!!!!!*%!!!#5!!!!N`!!!*3!!!#9!!!!PJ!!!*F
+!!!#B!!!!Q3!!!*S!!!#E!!!!R!!!!*d!!!#H!!!!R`!!!+!!!!#K!!!!SJ!!!+-
+!!!#N!!!!T3!!!+B!!!#R!!!!U!!!!+N!!!#U!!!!U`!!!+`!!!#Y!!!!VJ!!!+m
+!!!#`!!!!X3!!!,)!!!#c!!!!Y!!!!,8!!!#f!!!!Y`!!!,J!!!#j!!!!ZJ!!!,X
+!!!#m!!!![3!!!,i!!!#r!!!!`!!!!-%!!!$#!!!!``!!!-3!!!$&!!!!aJ!!!-F
+!!!$)!!!!b3!!!-S!!!$,!!!!c!!!!-d!!!$1!!!!c`!!!0!!!!$4!!!!dJ!!!0-
+!!!$8!!!!e3!!!0B!!!$A!!!!f!!!!0N!!!$D!!!!f`!!!0`!!!$G!!!!hJ!!!0m
+!!!$J!!!!i3!!!1)!!!$M!!!!j!!!!18!!!$Q!!!!j`!!!1J!!!$T!!!!kJ!!!1X
+!!!$X!!!!l3!!!1i!!!$[!!!!m!!!!2%!!!$b!!!!m`!!!23!!!$e!!!!pJ!!!2F
+!!!$i!!!!q3!!!2S!!!$l!!!!r!!!!2d!!!$q!!!!r`!!!3!!!!%"!!!"!J!!!3-
+!!!%%!!!""3!!!3B!!!%(!!!"#!!!!3N!!!%+!!!"#`!!!3`!!!%0!!!"$J!!!3m
+!!!%3!!!"%3!!!4)!!!%6!!!"&!!!!48!!!%@!!!"&`!!!4J!!!%C!!!"'J!!!4X
+!!!%F!!!"(3!!!4i!!!%I!!!")!!!!5%!!!%L!!!")`!!!53!!!%P!!!"*J!!!5F
+!!!%S!!!"+3!!!5S!!!%V!!!",!!!!5d!!!%Z!!!",`!!!6!!!!%a!!!"-J!!!6-
+!!!%d!!!"03!!!6B!!!%h!!!"1!!!!6N!!!%k!!!"1`!!!6`!!!%p!!!"2J!!!6m
+!!!&!!!!"33!!!8)!!!&$!!!"4!!!!88!!!&'!!!"4`!!!8J!!!&*!!!"5J!!!8X
+!!!&-!!!"63!!!8i!!!&2!!!"8!!!!9%!!!&5!!!"8`!!!93!!!&9!!!"9J!!!9F
+!!!&B!!!"@3!!!9S!!!&E!!!"A!!!!9d!!!&H!!!"A`!!!@!!!!&K!!!"BJ!!!@-
+!!!&N!!!"C3!!!@B!!!&R!!!"D!!!!@N!!!&U!!!"D`!!!@`!!!&Y!!!"EJ!!!@m
+!!!&`!!!"F3!!!A)!!!&c!!!"G!!!!A8!!!&f!!!"G`!!!AJ!!!&j!!!"HJ!!!AX
+!!!&m!!!"I3!!!Ai!!!&r!!!"J!!!!B%!!!'#!!!"J`!!!B3!!!'&!!!"KJ!!!BF
+!!!')!!!"L3!!!BS!!!',!!!"M!!!!Bd!!!'1!!!"M`!!!C!!!!!"N3!!!C)!!!'
+6!!!"P!!!!C8!!!'@!!!"P`!!!CJ!!!'C!!!"QJ!!!CX!!!'F!!!"R3!!!Ci!!!'
+I!!!"S!!!!D%!!!'L!!!"S`!!!D3!!!'P!!!"TJ!!!DF!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'S!!!"`!%!!!!"!!'
+S!3!"SJ%!!D-"!!'S!3!"S3%!!D!"!!!,!3!!$!%!!!S"!!!0!3!!$J%!!!m"!!!
+3!3!!%3%!!")"!!!6!3!!&!%!!"8"!!!@!3!!&`%!!"J"!!!C!3!!'J%!!"X"!!!
+F!3!!(3%!!"i"!!!I!3!!)!%!!#%"!!!L!3!!)`%!!#3"!!!P!3!!*J%!!#F"!!!
+S!3!!+3%!!#S"!!!V!3!!,!%!!#d"!!!Z!3!!,`%!!$!"!!!a!3!!-J%!!$-"!!!
+d!3!!03%!!$B"!!!h!3!!1!%!!$N"!!!k!3!!1`%!!$`"!!!p!3!!2J%!!$m"!!"
+!!3!!33%!!%)"!!"$!3!!4!%!!%8"!!"'!3!!4`%!!%J"!!"*!3!!5J%!!%X"!!"
+-!3!!63%!!%i"!!"2!3!!8!%!!&%"!!"5!3!!8`%!!&3"!!"9!3!!9J%!!&F"!!"
+B!3!!@3%!!&S"!!"E!3!!A!%!!&d"!!"H!3!!A`%!!'!"!!"K!3!!BJ%!!'-"!!"
+N!3!!C3%!!'B"!!"R!3!!D!%!!'N"!!"U!3!!D`%!!'`"!!"Y!3!!EJ%!!'m"!!"
+`!3!!F3%!!()"!!"c!3!!G!%!!(8"!!"f!3!!G`%!!(J"!!"j!3!!HJ%!!(X"!!"
+m!3!!I3%!!(i"!!"r!3!!J!%!!)%"!!##!3!!J`%!!)3"!!#&!3!!KJ%!!)F"!!#
+)!3!!L3%!!)S"!!#,!3!!M!%!!)d"!!#1!3!!M`%!!*!!!3!"TJ%!!*%"!!#5!3!
+!N`%!!*3"!!#9!3!!PJ%!!*F"!!#B!3!!Q3%!!*S"!!#E!3!!R!%!!*d"!!#H!3!
+!R`%!!+!"!!#K!3!!SJ%!!+-"!!#N!3!!T3%!!+B"!!#R!3!!U!%!!+N"!!#U!3!
+!U`%!!+`"!!#Y!3!!VJ%!!+m"!!#`!3!!X3%!!,)"!!#c!3!!Y!%!!,8"!!#f!3!
+!Y`%!!,J"!!#j!3!!ZJ%!!,X"!!#m!3!![3%!!,i"!!#r!3!!`!%!!-%"!!$#!3!
+!``%!!-3"!!$&!3!!aJ%!!-F"!!$)!3!!b3%!!-S"!!$,!3!!c!%!!-d"!!$1!3!
+!c`%!!0!"!!$4!3!!dJ%!!0-"!!$8!3!!e3%!!0B"!!$A!3!!f!%!!0N"!!$D!3!
+!f`%!!0`"!!$G!3!!hJ%!!0m"!!$J!3!!i3%!!1)"!!$M!3!!j!%!!18"!!$Q!3!
+!j`%!!1J"!!$T!3!!kJ%!!1X"!!$X!3!!l3%!!1i"!!$[!3!!m!%!!2%"!!$b!3!
+!m`%!!23"!!$e!3!!pJ%!!2F"!!$i!3!!q3%!!2S"!!$l!3!!r!%!!2d"!!$q!3!
+!r`%!!3!"!!%"!3!"!J%!!3-"!!%%!3!""3%!!3B"!!%(!3!"#!%!!3N"!!%+!3!
+"#`%!!3`"!!%0!3!"$J%!!3m"!!%3!3!"%3%!!4)"!!%6!3!"&!%!!48"!!%@!3!
+"&`%!!4J"!!%C!3!"'J%!!4X"!!%F!3!"(3%!!4i"!!%I!3!")!%!!5%"!!%L!3!
+")`%!!53"!!%P!3!"*J%!!5F"!!%S!3!"+3%!!5S"!!%V!3!",!%!!5d"!!%Z!3!
+",`%!!6!"!!%a!3!"-J%!!6-"!!%d!3!"03%!!6B"!!'R!3!"0`%!!6J"!!%j!3!
+"1J%!!6X"!!%m!3!"23%!!6i"!!%r!3!"3!%!!8%"!!&#!3!"3`%!!83"!!&&!3!
+"4J%!!8F"!!&)!3!"53%!!8S"!!&,!3!"6!%!!8d"!!&1!3!"6`%!!9!"!!&4!3!
+"8J%!!9-"!!&8!3!"93%!!9B"!!&A!3!"@!%!!9N"!!&D!3!"@`%!!9`"!!&G!3!
+"AJ%!!9m"!!&J!3!"B3%!!@)"!!&M!3!"C!%!!@8"!!&Q!3!"C`%!!@J"!!&T!3!
+"DJ%!!@X"!!&X!3!"E3%!!@i"!!&[!3!"F!%!!A%"!!&b!3!"F`%!!A3"!!&e!3!
+"GJ%!!AF"!!&i!3!"H3%!!AS"!!&l!3!"I!%!!Ad"!!&q!3!"J!%!!B%"!!'#!3!
+"J`%!!B3"!!'&!3!"KJ%!!BF"!!')!3!"L3%!!BS"!!',!3!"M!%!!Bd"!!'1!3!
+"M`%!!C!!!3!"N3%!!C)"!!'6!3!"P!%!!C8"!!'@!3!"P`%!!CJ"!!'C!3!"QJ%
+!!CX"!!'F!3!"R3%!!Ci"!!'I!3!"T!%!!Am"!!!"!3!!"!%!!!-"!!!#!3!!#3%
+!!!8"!!!'!3!!"`%!!!J"!!'P!!!"U3!"!#J!!!!JrrrjT!!""!!!!!!!!!!!!!!
+!!!!!!J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!"1NKjF'9
+b3f&bC!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!,#2Z!!!!!!!!!"!!,
+#4r!!!J!!!!!!!!!!!!!#`MD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!J!!!3!!!!!&!!"rr`!!!!"rr`!!!!"rr`!!!!"rr`!!!!`!!3!#!!B!!!!
+&3!!!#!!"!!%k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!3!!!2rrrrm!!!!$!!%!!6Sk!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!"!!!!rrrrr`!!!!3!!3!"1MTTEQ0XG@4P1J!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!$rrrrr3!!!!J!"!!%k!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2rrrrp!!!!$!!%!!6Sk1NG98dN
+kD@jME(9NC6S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!rrrrrd!!!!3!!3!
+"1MSk4e9656TXD@)k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$rrrr
+r3!!!"3!#!!%k6@&M6e-J8h9`F'pbG$S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!3!!!2rrrrp!!!!'!!)!!6T08d`k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!"!!!!rrrrrd!!!!F!#J!!6@&M6e-J8&"$)%aTEQYPFJ!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6h"PEP066#"38%-!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!%k!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!&0B@0
+28b"38%-J6'PZDf9b!!!!!!!!!!!!!!!!!!!!!!!H39"36!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!"J!!!!3A"`E!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!68e-3J!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!6'PL)%PYF'pbG#"38%-!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!69"-4J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6'PL)%P
+YF'pbG#"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69G$4!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!"J!!!!8P053`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!9%9B9#jLD!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!3Q&XE'p[EL")C@a`!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!9%9B9#jM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp
+$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jM+bX!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!9%9B9#jMB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp
+$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jMF!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!9%9B9#jMF(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp
+$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jPH(!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!9%9B9#jRB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4f&YC80
+[C'8J3fpZGQ9bG'9b!!!!!!!!!!!!!!!!!!"!!!!!9%9B9#jS!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!
+!!!!3!!!!9%9B9#jX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4QaPH#"
+3FQ9`FQpMCA0cEh)!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)&"33`!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!9%9B9#j`BA-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ8'&
+cBf&X)&"33`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j`BfJ!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!
+!!!#!!!!!9%9B9#j`BfJV+`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp
+$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`F(8!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)&"33`!!!!!!!!!!!!!!!!!!!!!
+!!!#!!!!!9%9B9#jb!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8Q9k!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jc!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!8&"$3A0Y!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!9%9B9#jj!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3QPcEfi
+J8(*PF(*[Bf9cFfpb!!!!!!!!!!!!!!!!!!#!!!!!@%024J!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!@%024NBJ5@e`Eh*d)&"33`!!!!!!!!!!!!!!!!!
+!!!!!!!!!C'pMG3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!FR0bB`!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!"J!!!!FfKXBJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%9')%P
+YF'pbG#"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Fh4eBJ!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!8%9')%PYF'pbG#"38%-!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!#jNEf-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"3!!!!!!8"!3!"!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!"J!!!!!"!!!!!!8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!"!3!!E@&TEJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!3!"!!!!!3%
+"!3%!!3%!!!!!!!%"!!!"!3!"!!!"!!%!!!!!!!!!!!!)!3!"!3!"!3!!!!%!!!N
+!!"G0B@028b"8EfpXBQpi)%4&3P9()$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!r2cmr39"36!!!!B"B`!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!$mr2cm!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!0!!%!!!!!!"9I69G&8NY6AdG98dPIF(*PCQP
+i,QJ!!!!!!!!!!!!!!!!"!!!"!!!!!!!"!!!!!!!!!!!!!!8"!3%!!!%"!!%!!!!
+!"!!!!!!!!!!!!!!!!!!!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!"IAh0dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!3!!#8e
+PFQGP)%peG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!$mr2cp"8&"-!!%"!!!%)#!J)!1ARe!$GYpi!`@Z%!!&!J%
+!!3%!!3%"!!!"!!!!!!!!!!%"!3%!!3%!!3!""!!!!!!!!!!!!!!(!3%!!3!!!3!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!"IAh0dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8!!!G2F'9
+Z8e0-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2cmr2d&38%`!!!3!!!!%!!!!!%!
+!!&M!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!%r2cmr!!!!!!!!!!)!!!!#!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!#!&!!!3!"!!%!!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8*d024%8
+R)#G%394"*b!R8%P$9#F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!J!!!3!!!!%#!3!!!!!!!3!"!`!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!)!!!)!!!!#!J%!!!!!!!%!!3-!!!!!!!!!!!!!!!!%!!!!!!!!!!!#!!!$!!!
+!!`)"!!!!!!!"!!%$!!!!!!!!!!!!!!!!"!!!!!!!!!!!!J!!"!!!!!3#!3!!!!!
+!!3!"!`!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!!!8!!!!&!J%!!!!!!!%!!3-!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!#!!!'!!!!"J)"!!!!!!!"!!%$!!!!!!!!!!!!!!!
+!"3!!!!!!!!!!!J!!"`!!!!F#!3!!!!!!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!)!!!J!!!!)!J%!!!!!!!%!!3-!!!!!!!!!!!!!!!!&!!!!!!!!!!!#!!!*!!!
+!#3)"!!!!!!!"!!%$!!!!!!!!!!!!!!!!"3!!!!!!!!!!!J!!#J!!!Am#!3!!!!!
+!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!)!!!X!!!'U!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!#!!!-!!!"U`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!!J!!$3!!!D`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!)!!!i!!!'Y!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!#!!!2!!!
+"VJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!J!!%!!!!Dm#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!)!!"%!!!'`!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!#!!!5!!!"X3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!!J!!%`!!!E)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!)!!"3!!!'c!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!#!!!9!!!
+"Y!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!J!!&J!!!E8#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!)!!"F!!!'f!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!#!!!B!!!"Y`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!!J!!'3!!!EJ#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!)!!"S!!!'j!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!#!!!E!!!
+"ZJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!J!!(!!!!EX#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!)!!"d!!!'m!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!#!!!H!!!"[3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!!J!!(`!!!Ei#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!)!!#!!!!'r!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!#!!!K!!!
+"`!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!J!!)J!!!F%#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!)!!#-!!!(#!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!#!!!N!!!"``)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!!J!!*3!!!F3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!)!!#B!!!(&!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!#!!!R!!!
+"aJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!J!!+!!!!FF#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!)!!#N!!!()!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!#!!!U!!!"b3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!!J!!+`!!!FS#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!)!!#`!!!(,!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!#!!!Y!!!
+"c!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!J!!,J!!!D8#!3!!!!!
+!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!)!!#m!!!(0!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!#!!!`!!!"cJ)"!!!!!!!"!!%$!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!!J!!-3!!!Fm#!3!!!!!!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!)!!$)!!!(3!J%!!!!!!!%!!3-!!!!!!!!!!!!!!!!"!!!!!!!!!!!#!!!c!!!
+"d33"!!!!!!!!!!%$!!!!!!!!!!!!!!!!J3!!!!!!!!!!!J!!0!!!!G)%!3!!!!!
+!!!!"!`!!!!!!!!!!!!!!!)%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!!J!!!!-!!!!%!!!
+!"3!!!!B!!!!(!!!!#!!!!!N!!!!Y!!!!#J!!!!X!!!!-!!!!$3!!!!i!!!!2!!!
+!%!!!!"%!!!!5!!!!%`!!!"3!!!!9!!!!&J!!!"F!!!!B!!!!'3!!!"S!!!!E!!!
+!(!!!!"d!!!!H!!!!(`!!!#!!!!!K!!!!)J!!!#-!!!!N!!!!*3!!!#B!!!!R!!!
+!+!!!!#N!!!!U!!!!+`!!!#`!!!!Z!!!!,`!!!$!!!!!a!!!!-J!!!$-!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!d!!!
+!3!)!!!!#!!!d!J!!(!)!!"d#!!!H!J!!(`)!!#!#!!!K!J!!)J)!!#-#!!!N!J!
+!*3)!!#B#!!!R!J!!+!)!!#N#!!!U!J!!+`)!!#`#!!!Y!J!!#`)!!!`#!!!0!J!
+!$J)!!!m#!!!3!J!!%3)!!")#!!!6!J!!&!)!!"8#!!!@!J!!&`)!!"J#!!!C!J!
+!'J)!!"X#!!!c!J!!0!)!!#m#!!!`!J!!-J)!!$%#!!!+!J!!!3)!!!3#!!!$!J!
+!!J)!!!N#!!!&!J!!"J)!!!F#!!!)!J!!,J!!!DN!!3!S!J!!%`)!!"3#!!!9!J!
+!&J)!!"F#!!!B!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#`MlJ!!!
+!!!!!!3!#`NI`!!)!!!!!!!!!!!!!!X)fJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!)!!!%!!!!!"3!!Irm!!!!!Irm!!!!!Irm!!!!!Irm!!!!-!!%
+!!J!%!!!!"8!!!!B!!3!"1J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!%!!!$rrrrr!!!!!`!"!!%k1J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!3!!!2rrrrm!!!!%!!%!!6SkD@jME(9NC6S!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!rrrrrd!!!!)!!3!"1J!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$rrrrr3!!!!`!#!!%
+k6@&M6e-J8h9`F'pbG$S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!2rrrrp
+!!!!%!!)!!6T08d`k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+"!!!!rrrrrd!!!!8!#J!!6@&M6e-J0MK,)%aTEQYPFJ!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!4f9d5&488&-J0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!%k!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!&0B@028b!f1%XJ6'P
+ZDf9b!!!!!!!!!!!!!!!!!!!!!!!J39"36!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!3A"
+`E!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"J!!!!68e-3J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!6'PL)%PYF'pbG#!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69"
+-4J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6'PL)%PYF'pbG#!f1%X
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69G$4!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!6d*
++)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69"A)%PYF'pbG#!f1%X
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%a[BJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!8P0
+53`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"J!!!!9%9B9#jLD!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!3Q&XE'p[EL")C@a`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
+B9#jM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jM+bX!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
+B9#jMB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jMF!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
+B9#jMF(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jPH(!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
+B9#jRB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4f&YC80[C'8J3fpZGQ9
+bG'9b!!!!!!!!!!!!!!!!!!"!!!!!9%9B9#jS!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!!9%9
+B9#jX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4QaPH#"3FQ9`FQpMCA0
+cEh)!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!69FJ8'&cBf&X)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
+B9#j`BA-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)$Bi5`!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j`BfJ!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9
+B9#j`BfJV+`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!
+!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`F(8!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!69FJ8'&cBf&X)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9
+B9#jb!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8Q9k!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jcC@F!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
+B9#jj!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3QPcEfiJ8(*PF(*[Bf9
+cFfpb!!!!!!!!!!!!!!!!!!#!!!!!C'pMG3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!FR0
+bB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"J!!!!FfKXBJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!8%9')%PYF'pbG#!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Fh4
+eBJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%9')%PYF'pbG#!f1%X
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#jNEf-!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"3!!!!!!!
+!!#jbFh*M!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"J!!!!!!8"!3!"!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!
+!!!!"!!!!!!8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!"!3!!E@&TEJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!3%"!!!!!3%"!!!"!3%!!!!
+!!!%"!!!"!3!"!!!""!!!!!!!!!!!!!!)!3!"!3!"!3!!!!%!!!N!!!e(CA4)9&4
+38bJf1%XT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!r2cmr39"36!!!!J"B`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$mr2cm!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!0!!%!!!!!!""I69G&8NY6Ah"bC@CTH#jS!!!!!!!!!!!!!!!
+!!!!!!!!"!!!!!!!!!!!"!!!!!!!!!!!!!!8"!3%!!!%"!!%!!!!!"!!!!!!!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"IAh0
+dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!3!!#8ePFQGP)%peG!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!$mr2cp"8&"-!!%"!!!%)#!J)!1ARe!$GYpi!`@Z%!!&!J%!!3%!!3%"!!!
+"!!!!!!!!!!%"!3%!!3%!!3!""!!!!!!!!!!!!!!(!3%!!3!!!3!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!"IAh0dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8!!!K(CA4)9&438`!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!2cmr2d&38%`!!!3!!!!%!!!!!%!!!&M!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%r2cm
+r!!!!!!!!!!)!!!!#!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!#!&!!!3!"!!%!!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8*d024%8R)#G%394"*b!
+R8%P$9#F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!`!!!3!!!!S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!!)!!!!
+,!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!$!!!!$!)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!"!!!!!d#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!!8!!!!1!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!!'!!!!$`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!"`!!!"!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!!J!!!!
+4!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!*!!!!%J)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!#J!!!"-#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!!X!!!!8!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!!-!!!!&3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!$3!!!"B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!!i!!!!
+A!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!2!!!!'!)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!%!!!!"N#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!"%!!!!D!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!!5!!!!'`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!%`!!!"`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!"3!!!!
+G!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!9!!!!(J)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!&J!!!"m#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!"F!!!!J!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!!B!!!!)3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!'3!!!#)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!"S!!!!
+M!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!E!!!!*!)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!(!!!!#8#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!"d!!!!Q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!!H!!!!*`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!(`!!!#J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!#!!!!!
+T!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!K!!!!+J)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!)J!!!#X#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!#-!!!!X!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!!N!!!!,3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!*3!!!#i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!#B!!!!
+[!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!R!!!!-!)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!+!!!!$%#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!#N!!!!b!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!!U!!!!-`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!+`!!!$3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!#`!!!!
+e!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!Y!!!!0J)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!,J!!!$F#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!#m!!!!i!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!!`!!!!13)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!-3!!!$S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!$)!!!!
+l!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!c!!!!2!)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!0!!!!$d#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!$8!!!!q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!!f!!!!2`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!0`!!!%!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!$J!!!"
+"!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!j!!!!3J)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!1J!!!%-#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!$X!!!"%!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!!m!!!!43)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!23!!!%B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!$i!!!"
+(!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!r!!!!5!)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!3!!!!%N#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!%%!!!"+!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!"#!!!!5`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!3`!!!%`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!%3!!!"
+0!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"&!!!!6J)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!4J!!!%m#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!%F!!!"3!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!")!!!!83)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!53!!!&)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!%S!!!"
+6!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!",!!!!9!)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!6!!!!&8#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!%d!!!"@!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!"1!!!!9`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!6`!!!&J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!&!!!!"
+C!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"4!!!!@J)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!8J!!!&X#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!&-!!!"F!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!"8!!!!A3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!93!!!&i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!&B!!!"
+I!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"A!!!!B!)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!@!!!!'%#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!&N!!!"L!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!"D!!!!B`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!@`!!!'3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!&`!!!"
+P!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"G!!!!CJ)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!AJ!!!'F#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!&m!!!"S!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!"J!!!!D3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!B3!!!'S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!')!!!"
+V!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"M!!!!E!)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!C!!!!'d#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!'8!!!"Z!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!"Q!!!!E`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!C`!!!(!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!'J!!!"
+a!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"T!!!!FJ)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!DJ!!!(-#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!'X!!!"d!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!"X!!!!G3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!E3!!!(B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!'i!!!"
+h!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"[!!!!H!)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!F!!!!(N#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!(%!!!"k!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!"b!!!!H`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!F`!!!(`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!(3!!!"
+p!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"e!!!!IJ)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!GJ!!!(m#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!(F!!!#!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!"i!!!!J3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!H3!!!))#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!(S!!!#
+$!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"l!!!!K!)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!I!!!!)8#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!(d!!!#'!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!"q!!!!K`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!I`!!!)J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!)!!!!#
+*!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#"!!!!LJ)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!JJ!!!)X#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!-!!)-!!!#-!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!$!!#%!!!!M3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!!`!!K3!!!)i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!)B!!!#
+2!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#(!!!!N!!#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!)J!!!#4!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!$!!#*!!!!NJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!!`!!LJ!!!*-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!-!!)X!!!#8!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#-!!!
+!P3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!M3!!!*B#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!)i!!!#A!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!$!!#2!!!!Q!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!!`!!N!!!!!#C!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!#4!!!!QJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!NJ!
+!!*X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!*-!!!#F!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#8!!!!R3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!!P3!!!*i#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!*B!!!#I!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!#A!!!!S!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!Q!!
+!!+%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!*N!!!#L!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#D!!!!S`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!!Q`!!!+3#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!*`!!!#P!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!#G!!!!TJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!RJ!
+!!+F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!*m!!!#S!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#J!!!!U3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!!S3!!!+S#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!+)!!!#V!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!#M!!!!V!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!T!!
+!!+d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!+8!!!#Z!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#Q!!!!V`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!!T`!!!,!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!+J!!!#a!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!#T!!!!XJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!UJ!
+!!,-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!+X!!!#d!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#X!!!!Y3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!!V3!!!,B#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!+i!!!#h!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!#[!!!!Z!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!X!!
+!!,N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!,%!!!#k!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#b!!!!Z`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!!X`!!!,`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!,3!!!#p!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!#e!!!![J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!YJ!
+!!,m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!,F!!!$!!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#i!!!!`3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!!Z3!!!-)#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!,S!!!$$!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!#l!!!!a!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!![!!
+!!-8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!,d!!!$'!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#q!!!!a`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!![`!!!-J#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!-!!!!$*!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!$"!!!!bJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!`J!
+!!-X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!--!!!$-!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$%!!!!c3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!!a3!!!-i#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!-B!!!$2!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!$(!!!!d!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!b!!
+!!0%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!-N!!!$5!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$+!!!!d`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!!b`!!!03#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!-`!!!$9!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!$0!!!!eJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!cJ!
+!!0F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!-m!!!$B!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$3!!!!f3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!!d3!!!0S#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!0)!!!$E!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!$6!!!!h!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!e!!
+!!0d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!08!!!$H!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$@!!!!h`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!!e`!!!1!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!0J!!!$K!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!$C!!!!iJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!fJ!
+!!1-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!0X!!!$N!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$F!!!!j3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!!h3!!!1B#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!0i!!!$R!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!$I!!!!k!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!i!!
+!!1N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!1%!!!$U!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$L!!!!k`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!!i`!!!1`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!13!!!$Y!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!$P!!!!lJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!jJ!
+!!1m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!1F!!!$`!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$S!!!!m3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!!k3!!!2)#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!1S!!!$c!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!$V!!!!p!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!l!!
+!!28#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!1d!!!$f!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$Z!!!!p`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!!l`!!!2J#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!2!!!!$j!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!$a!!!!qJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!mJ!
+!!2X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!2-!!!$m!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$d!!!!r3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!!p3!!!2i#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!2B!!!$r!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!$h!!!"!!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!q!!
+!!3%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!2N!!!%#!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$k!!!"!`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!!q`!!!33#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!2`!!!%&!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!$p!!!""J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!rJ!
+!!3F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!2m!!!%)!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%!!!!"#3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"!3!!!3S#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!3)!!!%,!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!%$!!!"$!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!""!!
+!!3d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!38!!!%1!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%'!!!"$`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!""`!!!4!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!3J!!!%4!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!%*!!!"%J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"#J!
+!!4-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!3X!!!%8!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%-!!!"&3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"$3!!!4B#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!3i!!!%A!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!%2!!!"'!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"%!!
+!!4N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!4%!!!%D!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%5!!!"'`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"%`!!!4`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!43!!!%G!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!%9!!!"(J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"&J!
+!!4m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!4F!!!%J!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%B!!!")3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"'3!!!5)#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!4S!!!%M!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!%E!!!"*!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"(!!
+!!58#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!4d!!!%Q!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%H!!!"*`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"(`!!!5J#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!5!!!!%T!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!%K!!!"+J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!")J!
+!!5X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!5-!!!%X!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%N!!!",3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"*3!!!5i#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!5B!!!%[!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!%R!!!"-!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"+!!
+!!6%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!5N!!!%b!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%U!!!"-`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"+`!!!63#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!5`!!!%e!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!%Y!!!"0J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!",J!
+!!6F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!5m!!!%i!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%`!!!"13)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"-3!!!6S#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!6)!!!%l!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!%c!!!"2!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"0!!
+!!6d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!68!!!%q!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%f!!!"2`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"0`!!!8!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!6J!!!&"!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!%j!!!"3J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"1J!
+!!8-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!6X!!!&%!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%m!!!"43)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"23!!!8B#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!6i!!!&(!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!%r!!!"5!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"3!!
+!!8N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!8%!!!&+!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&#!!!"5`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"3`!!!8`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!83!!!&0!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!&&!!!"6J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"4J!
+!!8m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!8F!!!&3!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&)!!!"83)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"53!!!9)#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!8S!!!&6!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!&,!!!"9!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"6!!
+!!98#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!8d!!!&@!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&1!!!"9`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"6`!!!9J#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!9!!!!&C!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!&4!!!"@J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"8J!
+!!9X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!9-!!!&F!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&8!!!"A3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"93!!!9i#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!9B!!!&I!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!&A!!!"B!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"@!!
+!!@%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!9N!!!&L!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&D!!!"B`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"@`!!!@3#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!9`!!!&P!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!&G!!!"CJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"AJ!
+!!@F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!9m!!!&S!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&J!!!"D3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"B3!!!@S#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!@)!!!&V!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!&M!!!"E!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"C!!
+!!@d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!@8!!!&Z!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&Q!!!"E`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"C`!!!A!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!@J!!!&a!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!&T!!!"FJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"DJ!
+!!A-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!@X!!!&d!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&X!!!"G3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"E3!!!AB#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!@i!!!&h!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!&[!!!"H!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"F!!
+!!AN#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!A%!!!&k!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&b!!!"H`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"F`!!!A`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!A3!!!&p!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!&e!!!"IJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"GJ!
+!!B!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!AF!!!'"!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&i!!!"JJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"H3!!!B-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!AS!!!'%!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!&l!!!"K3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"I!!
+!!BB#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!Ad!!!'(!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&q!!!"L!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"I`!!!BN#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!B!!!!'+!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!$!!'"!!!"L`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"JJ!
+!!B`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!B-!!!'0!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'%!!!"MJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!!`!"K3!!!Bm#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!-!!BB!!!'3!!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
+!!!!!!`!"K`!!!C%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!BJ
+!!!'5!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'*!!!"N`)"!!!
+!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"LJ!!!C3#!3!!!!!!!3!"!3!
+!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!BX!!!'9!J%!!!!!!!%!!3%!!!!!!!!!!!!
+!!!!"!!!!!!!!!!!$!!'-!!!"PJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
+!!!!!!`!"M3!!!CF#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!Bi
+!!!'B!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'2!!!"Q3)"!!!
+!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"N!!!!!'D!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'4!!!"Q`)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!`!"NJ!!!C`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!-!!C-!!!'G!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'
+8!!!"RJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"P3!!!Cm#!3!
+!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!CB!!!'J!J%!!!!!!!%!!3%
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'A!!!"S3)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!`!"Q!!!!D)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!-!!CN!!!'M!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'
+D!!!"d`)"!!!!!!!"!!%$!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"Q`!!!G3#!3!
+!!!!!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!C`!!!(9!J%!!!!!!!%!!3-
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'G!!!"eJ)"!!!!!!!"!!%$!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!`!"RJ!!!D3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!-!!Cm!!!(A!J%!!!!!!!%!!3-!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'
+J!!!"f!)"!!!!!!!"!!%$!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"S3!!!GN#!3!
+!!!!!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!D)!!!(D!J%!!!!!!!%!!3-
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'M!!!"TJ)"!!!!!!!"!!%"!!!!!!!!!!!
+!!!!!!3!!!!!!!!!!!`!"T!!!!DF#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!-!!D8!!!'S!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!!)!!!!$!!!!"!!!!!8!!!!
+'!!!!"`!!!!J!!!!*!!!!#J!!!!X!!!!-!!!!$3!!!!i!!!!2!!!!%!!!!"%!!!!
+5!!!!%`!!!"3!!!!9!!!!&J!!!"F!!!!B!!!!'3!!!"S!!!!E!!!!(!!!!"d!!!!
+H!!!!(`!!!#!!!!!K!!!!)J!!!#-!!!!N!!!!*3!!!#B!!!!R!!!!+!!!!#N!!!!
+U!!!!+`!!!#`!!!!Y!!!!,J!!!#m!!!!`!!!!-3!!!$)!!!!c!!!!0!!!!$8!!!!
+f!!!!0`!!!$J!!!!j!!!!1J!!!$X!!!!m!!!!23!!!$i!!!!r!!!!3!!!!%%!!!"
+#!!!!3`!!!%3!!!"&!!!!4J!!!%F!!!")!!!!53!!!%S!!!",!!!!6!!!!%d!!!"
+1!!!!6`!!!&!!!!"4!!!!8J!!!&-!!!"8!!!!93!!!&B!!!"A!!!!@!!!!&N!!!"
+D!!!!@`!!!&`!!!"G!!!!AJ!!!&m!!!"J!!!!B3!!!')!!!"M!!!!C!!!!'8!!!"
+Q!!!!C`!!!'J!!!"T!!!!DJ!!!'X!!!"X!!!!E3!!!'i!!!"[!!!!F!!!!(%!!!"
+b!!!!F`!!!(3!!!"e!!!!GJ!!!(F!!!"i!!!!H3!!!(S!!!"l!!!!I!!!!(d!!!"
+q!!!!I`!!!)!!!!#"!!!!JJ!!!)-!!!#%!!!!K3!!!)B!!!#(!!!!L!!!!)N!!!#
++!!!!L`!!!)`!!!#0!!!!MJ!!!)m!!!#3!!!!!*%!!!#5!!!!N`!!!*3!!!#9!!!
+!PJ!!!*F!!!#B!!!!Q3!!!*S!!!#E!!!!R!!!!*d!!!#H!!!!R`!!!+!!!!#K!!!
+!SJ!!!+-!!!#N!!!!T3!!!+B!!!#R!!!!U!!!!+N!!!#U!!!!U`!!!+`!!!#Y!!!
+!VJ!!!+m!!!#`!!!!X3!!!,)!!!#c!!!!Y!!!!,8!!!#f!!!!Y`!!!,J!!!#j!!!
+!ZJ!!!,X!!!#m!!!![3!!!,i!!!#r!!!!`!!!!-%!!!$#!!!!``!!!-3!!!$&!!!
+!aJ!!!-F!!!$)!!!!b3!!!-S!!!$,!!!!c!!!!-d!!!$1!!!!c`!!!0!!!!$4!!!
+!dJ!!!0-!!!$8!!!!e3!!!0B!!!$A!!!!f!!!!0N!!!$D!!!!f`!!!0`!!!$G!!!
+!hJ!!!0m!!!$J!!!!i3!!!1)!!!$M!!!!j!!!!18!!!$Q!!!!j`!!!1J!!!$T!!!
+!kJ!!!1X!!!$X!!!!l3!!!1i!!!$[!!!!m!!!!2%!!!$b!!!!m`!!!23!!!$e!!!
+!pJ!!!2F!!!$i!!!!q3!!!2S!!!$l!!!!r!!!!2d!!!$q!!!!r`!!!3!!!!%"!!!
+"!J!!!3-!!!%%!!!""3!!!3B!!!%(!!!"#!!!!3N!!!%+!!!"#`!!!3`!!!%0!!!
+"$J!!!3m!!!%3!!!"%3!!!4)!!!%6!!!"&!!!!48!!!%@!!!"&`!!!4J!!!%C!!!
+"'J!!!4X!!!%F!!!"(3!!!4i!!!%I!!!")!!!!5%!!!%L!!!")`!!!53!!!%P!!!
+"*J!!!5F!!!%S!!!"+3!!!5S!!!%V!!!",!!!!5d!!!%Z!!!",`!!!6!!!!%a!!!
+"-J!!!6-!!!%d!!!"03!!!6B!!!%h!!!"1!!!!6N!!!%k!!!"1`!!!6`!!!%p!!!
+"2J!!!6m!!!&!!!!"33!!!8)!!!&$!!!"4!!!!88!!!&'!!!"4`!!!8J!!!&*!!!
+"5J!!!8X!!!&-!!!"63!!!8i!!!&2!!!"8!!!!9%!!!&5!!!"8`!!!93!!!&9!!!
+"9J!!!9F!!!&B!!!"@3!!!9S!!!&E!!!"A!!!!9d!!!&H!!!"A`!!!@!!!!&K!!!
+"BJ!!!@-!!!&N!!!"C3!!!@B!!!&R!!!"D!!!!@N!!!&U!!!"D`!!!@`!!!&Y!!!
+"EJ!!!@m!!!&`!!!"F3!!!A)!!!&c!!!"G!!!!A8!!!&f!!!"G`!!!AJ!!!&j!!!
+"HJ!!!AX!!!&m!!!"I3!!!Ai!!!&r!!!"J!!!!B%!!!'#!!!"J`!!!B3!!!'&!!!
+"KJ!!!BF!!!')!!!"L3!!!BS!!!',!!!"M!!!!Bd!!!'1!!!"M`!!!C!!!!!"N3!
+!!C)!!!'6!!!"P!!!!C8!!!'@!!!"P`!!!CJ!!!'G!!!"SJ!!!D-!!!'N!!!"Q3!
+!!CS!!!'E!!!"R!!!!Ci!!!'I!!!"S!!!!D%!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'P!!!"`!-
+!!!!$!!'P!!!"f`!"!"`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$!!'B!`!"Q3-
+!!D8$!!'A!`!"PJ-!!!)$!!!$!`!!!3-!!!3$!!!&!`!!"J-!!!F$!!!)!`!!#3-
+!!!S$!!!,!`!!$!-!!!d$!!!1!`!!$`-!!"!$!!!4!`!!%J-!!"-$!!!8!`!!&3-
+!!"B$!!!A!`!!'!-!!"N$!!!D!`!!'`-!!"`$!!!G!`!!(J-!!"m$!!!J!`!!)3-
+!!#)$!!!M!`!!*!-!!#8$!!!Q!`!!*`-!!#J$!!!T!`!!+J-!!#X$!!!X!`!!,3-
+!!#i$!!![!`!!-!-!!$%$!!!b!`!!-`-!!$3$!!!e!`!!0J-!!$F$!!!i!`!!13-
+!!$S$!!!l!`!!2!-!!$d$!!!q!`!!2`-!!%!$!!""!`!!3J-!!%-$!!"%!`!!43-
+!!%B$!!"(!`!!5!-!!%N$!!"+!`!!5`-!!%`$!!"0!`!!6J-!!%m$!!"3!`!!83-
+!!&)$!!"6!`!!9!-!!&8$!!"@!`!!9`-!!&J$!!"C!`!!@J-!!&X$!!"F!`!!A3-
+!!&i$!!"I!`!!B!-!!'%$!!"L!`!!B`-!!'3$!!"P!`!!CJ-!!'F$!!"S!`!!D3-
+!!'S$!!"V!`!!E!-!!'d$!!"Z!`!!E`-!!(!$!!"a!`!!FJ-!!(-$!!"d!`!!G3-
+!!(B$!!"h!`!!H!-!!(N$!!"k!`!!H`-!!(`$!!"p!`!!IJ-!!(m$!!#!!`!!J3-
+!!))$!!#$!`!!K!-!!)8$!!'M!`!!KJ-!!)F$!!#)!`!!L3-!!)S$!!#,!`!!M!-
+!!)d$!!#1!`!!M`-!!*!!!`!!N3-!!*)$!!#6!`!!P!-!!*8$!!#@!`!!P`-!!*J
+$!!#C!`!!QJ-!!*X$!!#F!`!!R3-!!*i$!!#I!`!!S!-!!+%$!!#L!`!!S`-!!+3
+$!!#P!`!!TJ-!!+F$!!#S!`!!U3-!!+S$!!#V!`!!V!-!!+d$!!#Z!`!!V`-!!,!
+$!!#a!`!!XJ-!!,-$!!#d!`!!Y3-!!,B$!!#h!`!!Z!-!!,N$!!#k!`!!Z`-!!,`
+$!!#p!`!![J-!!,m$!!$!!`!!`3-!!-)$!!$$!`!!a!-!!-8$!!$'!`!!a`-!!-J
+$!!$*!`!!bJ-!!-X$!!$-!`!!c3-!!-i$!!$2!`!!d!-!!0%$!!$5!`!!d`-!!03
+$!!$9!`!!eJ-!!0F$!!$B!`!!f3-!!0S$!!$E!`!!h!-!!0d$!!$H!`!!h`-!!1!
+$!!$K!`!!iJ-!!1-$!!$N!`!!j3-!!1B$!!$R!`!!k!-!!1N$!!$U!`!!k`-!!1`
+$!!$Y!`!!lJ-!!1m$!!$`!`!!m3-!!2)$!!$c!`!!p!-!!28$!!$f!`!!p`-!!2J
+$!!$j!`!!qJ-!!2X$!!$m!`!!r3-!!2i$!!$r!`!"!!-!!3%$!!%#!`!"!`-!!33
+$!!%&!`!""J-!!3F$!!%)!`!"#3-!!3S$!!%,!`!"$!-!!3d$!!%1!`!"$`-!!4!
+$!!%4!`!"%J-!!4-$!!%8!`!"&3-!!4B$!!%A!`!"'!-!!4N$!!%D!`!"'`-!!4`
+$!!%G!`!"(J-!!4m$!!%J!`!")3-!!5)$!!%M!`!"*!-!!58$!!%Q!`!"*`-!!5J
+$!!%T!`!"+J-!!5X$!!%X!`!",3-!!D3$!!%Z!`!",`-!!6!$!!%a!`!"-J-!!6-
+$!!%d!`!"03-!!6B$!!%h!`!"1!-!!6N$!!%k!`!"1`-!!6`$!!%p!`!"2J-!!6m
+$!!&!!`!"33-!!8)$!!&$!`!"4!-!!88$!!&'!`!"4`-!!8J$!!&*!`!"5J-!!8X
+$!!&-!`!"63-!!8i$!!&2!`!"8!-!!9%$!!&5!`!"8`-!!93$!!&9!`!"9J-!!9F
+$!!&B!`!"@3-!!9S$!!&E!`!"A!-!!9d$!!&H!`!"A`-!!@!$!!&K!`!"BJ-!!@-
+$!!&N!`!"C3-!!@B$!!&R!`!"D!-!!@N$!!&U!`!"D`-!!@`$!!&Y!`!"EJ-!!@m
+$!!&`!`!"F3-!!A)$!!&c!`!"G!-!!A8$!!&f!`!"G`-!!AJ$!!&j!`!"HJ-!!AX
+$!!&m!`!"I3-!!Ai$!!&r!`!"J!-!!B%$!!'#!`!"J`-!!B3$!!'&!`!"KJ-!!BF
+$!!')!`!"L3-!!BS$!!',!`!"M!-!!Bd$!!'1!`!"M`-!!C!!!`!"N3-!!C)$!!'
+6!`!"P!-!!C8$!!'H!`!"S!-!!D%$!!'E!`!"SJ-!!CS$!!'F!`!"R3-!!Cm!!J!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!,#2Z!!!!!!!!!"!!,#4r!!!J!
+!!!!!!!!!!!!#`MD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!J!
+!!3!!!!!&!!"rr`!!!!"rr`!!!!"rr`!!!!"rr`!!!!`!!3!#!!B!!!!&3!!!#!!
+"!!%k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!2r
+rrrm!!!!$!!%!!6Sk!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!"!!!!rrrrr`!!!!3!!3!"1MTTEQ0XG@4P1J!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!$rrrrr3!!!!J!"!!%k!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2rrrrp!!!!$!!%!!6Sk1NG98dNkD@jME(9
+NC6S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!rrrrrd!!!!3!!3!"1MSk4e9
+656TXD@)k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$rrrrr3!!!"3!
+#!!%k6@&M6e-J8h9`F'pbG$S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!2r
+rrrp!!!!'!!)!!6T08d`k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!"!!!!rrrrrd!!!!F!#J!!6@&M6e-J0MK,)%aTEQYPFJ!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!6'PL8e0-)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!%k!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!&0B@028b!f1%X
+J6'PZDf9b!!!!!!!!!!!!!!!!!!!!!!!J39"36!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!
+!3A"`E!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!68e-3J!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!6'PL)%PYF'pbG#!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!69"-4J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6'PL)%PYF'pbG#!
+f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69G$4!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!
+!6d*+)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69"A)%PYF'pbG#!
+f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%a[BJ!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!
+!8P053`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!9%9B9#jLD!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!3Q&XE'p[EL")C@a`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!9%9B9#jM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK
+,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jM+bX!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!9%9B9#jMB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK
+,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jMF!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!9%9B9#jMF(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK
+,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jPH(!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!9%9B9#jRB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4f&YC80[C'8J3fp
+ZGQ9bG'9b!!!!!!!!!!!!!!!!!!"!!!!!9%9B9#jS!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!
+!9%9B9#jX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4QaPH#"3FQ9`FQp
+MCA0cEh)!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!9%9B9#j`BA-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)$B
+i5`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j`BfJ!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!
+!9%9B9#j`BfJV+`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK
+,!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`F(8!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!#!!!!
+!9%9B9#jb!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8Q9k!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jcC@F!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!9%9B9#jj!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3QPcEfiJ8(*PF(*
+[Bf9cFfpb!!!!!!!!!!!!!!!!!!#!!!!!C'pMG3!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!
+!FR0bB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!FfKXBJ!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!8%9')%PYF'pbG#!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!Fh4eBJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%9')%PYF'pbG#!
+f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#jNEf-!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"3!!!
+!!!!!!#jbFh*M!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!!!8"!3!"!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!"J!!!!!"!!!!!!8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!"!3!!E@&TEJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!3%"!!!!!3%"!!!"!3%
+!!!!!!!%"!!!"!3!"!!!""!!!!!!!!!!!!!!)!3!"!3!"!3!!!!%!!!N!!aK-D@*
+68d`Z0MK,)%CK+$4TAcKN+5j-D@)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!r2cmr2cmr2`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$mr2cm
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!0!!%!!!!!!"9I69G&8NY6AdG98dPIF(*PCQPi,QJ!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!"!!!!!!!!!!!!!!8"!3%!!!%"!!%!!!!!"!!!!!!
+!!!!!!!!!!!!!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+IAh0dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!3!!#8ePFQGP)%p
+eG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!$mr2cp"8&"-!!%"!!!%)#!J)!1ARe!$GYpi!`@Z%!!&!J%!!3%!!3%
+"!!!"!!!!!!!!!!%"!3%!!3%!!3!""!!!!!!!!!!!!!!(!3%!!3!!!3!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!"IAh0dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8!!!K(CA4)9&438`!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2cmr2d&38%`!!!3!!!!%!!!!!%!!!&M!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%
+r2cmr!!!!!!!!!!)!!!!#!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!#!&!!!3!"!!%!!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8*d024%8R)#G%394
+"*b!R8%P$9#F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!"!!!!3!!!!S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!!)
+!!!!,!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!%!!!$!!!!$!)"!!!
+!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"!!!"!!!!!d#!3!!!!!!!3!"!3!
+!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!!8!!!!1!J%!!!!!!!%!!3%!!!!!!!!!!!!
+!!!!"!!!!!!!!!!!%!!!'!!!!$`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
+!!!!!"!!!"`!!!"!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!!J
+!!!!4!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!%!!!*!!!!%J)"!!!
+!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"!!!#J!!!"-#!3!!!!!!!3!"!3!
+!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!!X!!!!8!J%!!!!!!!%!!3%!!!!!!!!!!!!
+!!!!"!!!!!!!!!!!%!!!-!!!!&3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
+!!!!!"!!!$3!!!"B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!!i
+!!!!A!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!%!!!2!!!!'!)"!!!
+!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"!!!%!!!!"N#!3!!!!!!!3!"!3!
+!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!"%!!!!D!J%!!!!!!!%!!3%!!!!!!!!!!!!
+!!!!"!!!!!!!!!!!%!!!5!!!!'`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
+!!!!!"!!!%`!!!"`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!"3
+!!!!G!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!%!!!9!!!!(J)"!!!
+!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"!!!&J!!!"m#!3!!!!!!!3!"!3!
+!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!"F!!!!J!J%!!!!!!!%!!3%!!!!!!!!!!!!
+!!!!"!!!!!!!!!!!%!!!B!!!!)3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
+!!!!!"!!!'3!!!#)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!"S
+!!!!M!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!%!!!E!!!!*!)"!!!
+!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"!!!(!!!!#8#!3!!!!!!!3!"!3!
+!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!"d!!!!Q!J%!!!!!!!%!!3%!!!!!!!!!!!!
+!!!!"!!!!!!!!!!!%!!!H!!!!*`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
+!!!!!"!!!(`!!!#J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!#!
+!!!!T!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!%!!!K!!!!+J)"!!!
+!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"!!!)J!!!#X#!3!!!!!!!3!"!3!
+!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!#-!!!!X!J%!!!!!!!%!!3%!!!!!!!!!!!!
+!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!!J!!!!-!!!!%!!!!"3!!!!B
+!!!!(!!!!#!!!!!N!!!!+!!!!#`!!!!`!!!!0!!!!$J!!!!m!!!!3!!!!%3!!!")
+!!!!6!!!!&!!!!"8!!!!@!!!!&`!!!"J!!!!C!!!!'J!!!"X!!!!F!!!!(3!!!"i
+!!!!I!!!!)!!!!#%!!!!L!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!M!!!!3!3!!!!
+%!!!M!!!"f`!"!"`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!!&"!!!"!3!!!-
+%!!!#"!!!"J3!!!X%!!!+"!!!#33!!!J%!!!("!!!$!3!!")%!!!4"!!!%!3!!!m
+%!!!0"!!!$J3!!"-%!!!L"!!!)33!!#!%!!!I"!!!)`3!!!%%!!!8"!!!&33!!"B
+%!!!A"!!!'!3!!"N%!!!D"!!!'`3!!"`%!!!G"!!!(J!#!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!X)qi!!!!!!!!!%!!X*(m!!#!!!!!!!!!!!!!!,#0S!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!"!!!!!!8!!(rr!!!
+!!(rr!!!!!(rr!!!!!(rr!!!!$!!"!!)!"J!!!!9!!!!)!!%!!6S!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!rrrrr`!!!!-!!3!"1MS
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!!$rrrrr!!!
+!"!!"!!%k1QPZBfaeC'8k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!2rrrrp!!!!#!!%!!6S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!rrrrrd!!!!-!!3!"1MSk4e9656TTEQ0XG@4P1J!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!$rrrrr3!!!"!!"!!%k1MT(990*1QaTBMS!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2rrrrp!!!!&!!)!!6T0B@028b"6GA"
+`Eh*d1J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!rrrrrd!!!!B!!J!"1Ne
+66$S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!!$rrrrr3!!
+!"`!+!!"0B@028b!f1%XJ6'PZDf9b!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!"2F'9Z8e0-)$BiD`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!6S!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!!8eKBdp6)$Bi5b"-D@jVCA)!!!!!!!!
+!!!!!!!!!!!!!!#""8&"-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!""F("X!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!'!!!!"068a#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+-D@)J5@e`Eh*d)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!!!!"08%a'!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"-D@)J5@e`Eh*d)$Bi5`!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!"09d0%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!"23NSJ!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"08&FJ5@e`Eh*d)$Bi5`!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!"36'pL!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!"58e*$!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!'!!!!"849K8,Q*S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+#B@aXEfpZ)%KPE(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,Q-!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-V+b!f1%X!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!"849K8,Q-V+`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+09b"$,d-V+b!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,Q0M!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-V+b!f1%X!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!"849K8,Q0`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+09b"$,d-V+b!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,Q0`F!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-V+b!f1%X!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!"849K8,Q9iF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,QGM!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"(B@eP3fpNC5"$EfjfCA*dCA)!!!!!!!!
+!!!!!!!!!!%!!!!"849K8,QJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+09b"$,d-V+b!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!"849K8,Q`!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"'E'9i)&"bCA"bEf0PFh0[FJ!!!!!!!!!
+!!!!!!!!!!)!!!!"849K8,R!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+09b"3BA0MB@`J0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,R"KF`!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"3BA0MB@`J0MK,!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!"849K8,R"MD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+09b"$,d-V+b!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!)!!!!"849K8,R"MD#XV!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-V+b!f1%X!!!!!!!!!!!!!!!!
+!!!!!!!!!!)!!!!"849K8,R"`G3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+09b"3BA0MB@`J0MK,!!!!!!!!!!!!!!!!!!!!!!!!!)!!!!"849K8,R)!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"5CAS!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!"849K8,R0PC`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,RN!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"#DA0[EL"3FQ9`FQpMCA0cEh)!!!!!!!!
+!!!!!!!!!!)!!!!"NEf0e!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!"bFh*M!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!'!!!!"cD'aL!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+348BJ5@e`Eh*d)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!!!!"cG(9L!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"348BJ5@e`Eh*d)$Bi5`!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!,Q4[B`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&!!!!!!!!!!,R*cFQ-!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!'!!!!!!"3%"!!%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!!!%!!!!!"3!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%
+"!!"YB@PZ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!J"!!%!!!!"!3%!!!%"!3!!!!!!!3%!!!%"!!%
+!!!%%!!!!!!!!!!!!!!J"!!%"!!%"!!!!!3!!#3!!$%p`C@j68d`S0MKV+3!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$m
+r2cp"8&"-!!!#!&M!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2cmr2`!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!d!!3!!!!!!&9p09d955e0I4e9659p`FQ9QDAJZD!!!!!!!!!!!!!!!!!%!!!!
+!!!!!!!%!!!!!!!!!!!!!"3%"!3!!!3%!!3!!!!!%!!!!!!!!!!!!!!!!!!!!!!%
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&pIFh4KFR3!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!"!!!*6@9bCf8J6h9d!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2cmr2d&
+38%`!!3%!!!3J)#!J!jHI8!0fhhJ$"Di3!!8#!3!"!3!"!3%!!!%!!!!!!!!!!3%
+"!3!"!3!"!!%%!!!!!!!!!!!!!!F"!3!"!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&pIFh4
+KFR3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"3!!"dp`C@j68d`!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!r2cmr39"36!!!"!!!!!3!!!!!3!!!@-!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6mr2cm!!!!!!!!!!J!
+!!!)!!J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!8!!
+"!!%!!3!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"3R3dp%45FJ*d4"9%%R)#G35808*`!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&!!!"!!!"Z`)
+"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"3!!!J!!!E`#!3!!!!!!!3!
+"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!8!!!-!!!'p!J%!!!!!!!%!!3%!!!!!!!!
+!!!!!!!!"!!!!!!!!!!!&!!!%!!!"[J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!
+!!!!!!!!!"3!!"3!!!Em#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!8
+!!!B!!!(!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!&!!!(!!!"`3)
+"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"3!!#!!!!F)#!3!!!!!!!3!
+"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!8!!!N!!!($!J%!!!!!!!%!!3%!!!!!!!!
+!!!!!!!!"!!!!!!!!!!!&!!!+!!!"a!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!
+!!!!!!!!!"3!!#`!!!F8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!8
+!!!`!!!('!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!&!!!0!!!"a`)
+"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"3!!$J!!!FJ#!3!!!!!!!3!
+"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!8!!!m!!!(*!J%!!!!!!!%!!3%!!!!!!!!
+!!!!!!!!"!!!!!!!!!!!&!!!3!!!"bJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!
+!!!!!!!!!"3!!%3!!!FX#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!8
+!!")!!!(-!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!&!!!6!!!"c3)
+"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"3!!&!!!!G`#!3!!!!!!!3!
+"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!8!!"8!!!(G!J%!!!!!!!%!!3-!!!!!!!!
+!!!!!!!!"!!!!!!!!!!!&!!!@!!!"hJ)"!!!!!!!"!!%$!!!!!!!!!!!!!!!!!3!
+!!!!!!!!!"3!!&`!!!G-#!3!!!!!!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!8
+!!"J!!!(D!J%!!!!!!!%!!3-!!!!!!!!!!!!!!!!"!!!!!!!!!!!&!!!C!!!"e3)
+"!!!!!!!"!!%$!!!!!!!!!!!!!!!!!3!!!!!!!!!!"3!!'J!!!GB#!3!!!!!!!3!
+"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!8!!"X!!!(A!J%!!!!!!!%!!3-!!!!!!!!
+!!!!!!!!"!!!!!!!!!!!&!!!F!!!"e!)"!!!!!!!"!!%$!!!!!!!!!!!!!!!!!3!
+!!!!!!!!!"3!!(3!!!GJ#!3!!!!!!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!8
+!!"i!!!(C!J%!!!!!!!%!!3-!!!!!!!!!!!!!!!!"!!!!!!!!!!!&!!!I!!!"h`3
+"!!!!!!!!!!%$!!!!!!!!!!!!!!!!J3!!!!!!!!!!"3!!)!!!!H!#!3!!!!!!!3!
+"!`!!!!!!!!!!!!!!!)%!!!!!!!!!!!!!!!!!!!!"!!!!!J!!!!-!!!!%!!!!"3!
+!!!B!!!!(!!!!#!!!!!N!!!!+!!!!#`!!!!`!!!!0!!!!$J!!!!m!!!!3!!!!%3!
+!!")!!!!@!!!!'`!!!"J!!!!C!!!!'J!!!"`!!!!G!!!!&`!!!"-!!!!8!!!!&3!
+!!"i!!!!I!!!!)!!!!#!&!!!!"3!!)!!!!GX!!3!F!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!"3!!!38!!!)&!!!$"3!!"!8!!!8&!!!'"3!!"`8!!!J&!!!*"3!!#J8
+!!!X&!!!-"3!!$38!!!i&!!!2"3!!%!8!!"%&!!!5"3!!)!8!!"m&!!!6"3!!&!8
+!!"8&!!!@"3!!(38!!"i&!!!F"3!!'!8!!"F&!!!C"3!!'J8!!"X!!J!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!,#2Z!!!!!!!!!"!!,#4r!!!J!!!!!!!!!
+!!!!#`MD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!J!!!3!!!!!
+&!!"rr`!!!!"rr`!!!!"rr`!!!!"rr`!!!!`!!3!#!!B!!!!&3!!!#!!"!!%k!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!2rrrrm!!!!
+$!!%!!6Sk!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!
+!rrrrr`!!!!3!!3!"1MTTEQ0XG@4P1J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!$rrrrr3!!!!J!"!!%k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!2rrrrp!!!!$!!%!!6Sk1NG98dNkD@jME(9NC6S!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!rrrrrd!!!!3!!3!"1MSk4e9656TXD@)
+k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$rrrrr3!!!"3!#!!%k6@&
+M6e-J8h9`F'pbG$S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!2rrrrp!!!!
+'!!)!!6T08d`k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!
+!rrrrrd!!!!F!#J!!6@&M6e-J8&"$)%aTEQYPFJ!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!6'PL8e0-)&"33`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!%k!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!&0B@028b"38%-J6'PZDf9
+b!!!!!!!!!!!!!!!!!!!!!!!H39"36!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!3A"`E!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!"J!!!!68e-3J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!6'PL)%PYF'pbG#"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69"-4J!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6'PL)%PYF'pbG#"38%-!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!69G$4!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!8P053`!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!"J!!!!9%9B9#jLD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!3Q&XE'p[EL")C@a`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j
+M!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jM+bX!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j
+MB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jMF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j
+MF(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jPH(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j
+RB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4f&YC80[C'8J3fpZGQ9bG'9
+b!!!!!!!!!!!!!!!!!!"!!!!!9%9B9#jS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!!9%9B9#j
+X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4QaPH#"3FQ9`FQpMCA0cEh)
+!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!69FJ8'&cBf&X)&"33`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j
+`BA-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)&"33`!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j`BfJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j
+`BfJV+`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!
+!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`F(8!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!69FJ8'&cBf&X)&"33`!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j
+b!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8Q9k!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jc!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!8&"$3A0Y!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j
+j!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3QPcEfiJ8(*PF(*[Bf9cFfp
+b!!!!!!!!!!!!!!!!!!#!!!!!@%024J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!@%024NBJ5@e`Eh*d)&"33`!!!!!!!!!!!!!!!!!!!!!!!!!!C'pMG3!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!"J!!!!FR0bB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!FfKXBJ!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%9')%PYF'pbG#"38%-!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!Fh4eBJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!8%9')%PYF'pbG#"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#j
+NEf-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!"3!!!!!!8"!3!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!!
+"!!!!!!8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!"!3!!E@&TEJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!3%"!!!!!3%"!!!"!3%!!!!!!!%
+"!!!"!3!"!!!""!!!!!!!!!!!!!!)!3!"!3!"!3!!!!%!!!N!!aK-D@*68d`Z0MK
+,)%CK+$KTAc4N+5j-D@)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!r2cmr2cmr2`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$mr2cm!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!0!!%!!!!!!"9I69G&8NY6AdG98dPIF(*PCQPi,QJ!!!!!!!!!!!!
+!!!!"!!!"!!!!!!!"!!!!!!!!!!!!!!8"!3%!!!%"!!%!!!!!"!!!!!!!!!!!!!!
+!!!!!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"IAh0dBA*
+d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!3!!#8ePFQGP)%peG!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!$mr2cp"8&"-!!%"!!!%)#!J)!1ARe!$GYpi!`@Z%!!&!J%!!3%!!3%"!!!"!!!
+!!!!!!!%"!3%!!3%!!3!""!!!!!!!!!!!!!!(!3%!!3!!!3!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!"IAh0dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8!!`j-D@*68d`Z8&"$,NaTBJ!
+!!!!!!!!!!!!!!!!!!!!!2cmr2cmr2cm!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%r2cmr!!!
+!!!!!!!)!!!!#!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!#!&!!!3!"!!%!!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8*d024%8R)#G%394"*b!R8%P
+$9#F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!
+!!3!!!!S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!B!!!)!!!!,!J%
+!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!'!!!$!!!!$!)"!!!!!!!"!!%
+"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!!"!!!!!d#!3!!!!!!!3!"!3!!!!!!!!!
+!!!!!!!%!!!!!!!!!!!B!!!8!!!!1!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!
+!!!!!!!!'!!!'!!!!$`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!
+!"`!!!"!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!B!!!J!!!!4!J%
+!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!'!!!*!!!!%J)"!!!!!!!"!!%
+"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!!#J!!!"-#!3!!!!!!!3!"!3!!!!!!!!!
+!!!!!!!%!!!!!!!!!!!B!!!X!!!!8!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!
+!!!!!!!!'!!!-!!!!&3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!
+!$3!!!"B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!B!!!i!!!!A!J%
+!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!'!!!2!!!!'!)"!!!!!!!"!!%
+"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!!%!!!!"N#!3!!!!!!!3!"!3!!!!!!!!!
+!!!!!!!%!!!!!!!!!!!B!!"%!!!!D!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!
+!!!!!!!!'!!!5!!!!'`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!
+!%`!!!"`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!B!!"3!!!!G!J%
+!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!'!!!9!!!!(J)"!!!!!!!"!!%
+"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!!&J!!!"m#!3!!!!!!!3!"!3!!!!!!!!!
+!!!!!!!%!!!!!!!!!!!B!!"F!!!!J!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!
+!!!!!!!!'!!!B!!!!)3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!
+!'3!!!#)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!B!!"S!!!!M!J%
+!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!'!!!E!!!!*!)"!!!!!!!"!!%
+"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!!(!!!!#8#!3!!!!!!!3!"!3!!!!!!!!!
+!!!!!!!%!!!!!!!!!!!B!!"d!!!!Q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!
+!!!!!!!!'!!!H!!!!*`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!
+!(`!!!#J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!B!!#!!!!!T!J%
+!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!'!!!K!!!!+J)"!!!!!!!"!!%
+"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!!)J!!!#X#!3!!!!!!!3!"!3!!!!!!!!!
+!!!!!!!%!!!!!!!!!!!B!!#-!!!!X!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!!J!!!!-!!!!%!!!!"3!!!!B!!!!(!!!
+!#!!!!!N!!!!+!!!!#`!!!!`!!!!0!!!!$J!!!!m!!!!3!!!!%3!!!")!!!!6!!!
+!&!!!!"8!!!!@!!!!&`!!!"J!!!!C!!!!'J!!!"X!!!!F!!!!(3!!!"i!!!!I!!!
+!)!!!!#%!!!!L!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!M!!!!3!B!!!!'!!!M"J!
+!"3B!!!3'!!!$"J!!!JB!!!B'!!!,"J!!#JB!!!N'!!!)"J!!"`B!!!`'!!!5"J!
+!%3B!!"!'!!!2"J!!$3B!!!i'!!!6"J!!)JB!!#%'!!!J"J!!(`B!!#-'!!!""J!
+!&!B!!"8'!!!@"J!!&`B!!"J'!!!C"J!!'JB!!"X'!!!F"J!!(3B!!"i!!!'T!!%
+!+!!!!!!$Pj@!!!!!!!!!Irm!!!%!!!"j`!!#!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!X)qi!!!!!!!!!%!!X*(m!!#!!!!!!!!!!!!!!,#0S!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!"!!!!!!8!!(rr!!!!!(rr!!!
+!!(rr!!!!!(rr!!!!$!!"!!)!"J!!!!9!!!!)!!%!!6S!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!rrrrr`!!!!-!!3!"1MS!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!!$rrrrr!!!!"!!"!!%
+k1QPZBfaeC'8k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2rrrrp
+!!!!#!!%!!6S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!rrrrrd!!!!-!!3!"1MSk4e9656TTEQ0XG@4P1J!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!$rrrrr3!!!"!!"!!%k1MT(990*1QaTBMS!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!2rrrrp!!!!&!!)!!6T0B@028b"6GA"`Eh*d1J!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!rrrrrd!!!!B!!J!"1Ne66$S!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!!$rrrrr3!!!"`!+!!"
+0B@028b"38%-J6'PZDf9b!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+-D@*$FRP`G'mJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!%!!6S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!)!!8eKBdp6)&"33b"-D@jVCA)!!!!!!!!!!!!!!!!
+!!!!!!"j"8&"-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!""F("X!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!'!!!!"068a#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"-D@)J5@e
+`Eh*d)&"33`!!!!!!!!!!!!!!!!!!!!!!!!!!!!"08%a'!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"-D@)J5@e`Eh*d)&"33`!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!"09d0%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!"58e*$!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!'!!!!"849K8,Q*S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"#B@aXEfp
+Z)%KPE(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,Q-!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-V+b"38%-!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!"849K8,Q-V+`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-
+V+b"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,Q0M!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-V+b"38%-!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!"849K8,Q0`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-
+V+b"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,Q0`F!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-V+b"38%-!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!"849K8,Q9iF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,QGM!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"(B@eP3fpNC5"$EfjfCA*dCA)!!!!!!!!!!!!!!!!
+!!%!!!!"849K8,QJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-
+V+b"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!"849K8,Q`!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"'E'9i)&"bCA"bEf0PFh0[FJ!!!!!!!!!!!!!!!!!
+!!)!!!!"849K8,R!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"3BA0
+MB@`J8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,R"KF`!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"09b"3BA0MB@`J8&"$!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!"849K8,R"MD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-
+V+b"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!)!!!!"849K8,R"MD#XV!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-V+b"38%-!!!!!!!!!!!!!!!!!!!!!!!!
+!!)!!!!"849K8,R"`G3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"3BA0
+MB@`J8&"$!!!!!!!!!!!!!!!!!!!!!!!!!)!!!!"849K8,R)!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"5CAS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!"849K8,R-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"38%0"Ffd
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,RN!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"#DA0[EL"3FQ9`FQpMCA0cEh)!!!!!!!!!!!!!!!!
+!!)!!!!"B3dp'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"B3dp'4L"
+*EA"[FR3J8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!"NEf0e!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!'!!!!"bFh*M!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!"cD'aL!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"348BJ5@e`Eh*d)&"33`!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!"cG(9L!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"348BJ5@e
+`Eh*d)&"33`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!,Q4[B`!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!&!!!!!!"3%"!!%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!!!%!!!!!"3!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%"!!"YB@P
+Z!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!J"!!%!!!!"!3%"!3!"!3!!!!!!!3%!!!%"!!%!!!%!!3!
+!!!!!!!!!!!J"!!%"!!%"!!!!!3!!#3!!&deKBdp6)&4[EfaLEhJJ4%9#98FJ0MK
+,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$mr2cp"8&"
+-!!!"J&M!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2cmr2`!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!d!!3!
+!!!!!&9p09d955e0I4e9659p`FQ9QDAJZD!!!!!!!!!!!!!!!!!%!!!%!!!!!!!%
+!!!!!!!!!!!!!"3%"!3!!!3%!!3!!!!!%!!!!!!!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&pIFh4KFR3!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!3!"!!!*6@9bCf8J6h9d!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2cmr2d&38%`!!3%
+!!!3J)#!J!jHI8!0fhhJ$"Di3!!8#!3!"!3!"!3%!!!%!!!!!!!!!!3%"!3!"!3!
+"!!%%!!!!!!!!!!!!!!F"!3!"!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&pIFh4KFR3!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!"3!$%8aTBN0bHA"dEbj38%-Z6'PL!!!!!!!!!!!!!!!
+!!!!r2cmr2cmr2`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6mr2cm!!!!!!!!!!J!!!!)!!J!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!8!!"!!%!!3!
+"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!"3R3dp%45FJ*d4"9%%R)#G35808*`!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!(!!!"!!!!,3)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!!J!!!#i#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!F!!!-!!!![!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!(!!!%!!!!-!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!"`!!"3!!!$%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!!B!!!!
+b!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!(!!!!-`)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!#!!!!$3#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!F!!!N!!!!e!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!(!!!+!!!!0J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!"`!!#`!!!$F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!!`!!!!
+i!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!0!!!!13)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!$J!!!$S#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!F!!!m!!!!l!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!(!!!3!!!!2!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!"`!!%3!!!$d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!")!!!!
+q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!6!!!!2`)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!&!!!!%!#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!F!!"8!!!""!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!(!!!@!!!!3J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!"`!!&`!!!%-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!"J!!!"
+%!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!C!!!!43)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!'J!!!%B#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!F!!"X!!!"(!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!(!!!F!!!!5!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!"`!!(3!!!%N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!"i!!!"
++!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!I!!!!5`)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!)!!!!%`#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!F!!#%!!!"0!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!(!!!L!!!!6J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!"`!!)`!!!%m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!#3!!!"
+3!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!P!!!!83)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!*J!!!&)#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!F!!#F!!!"6!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!(!!!S!!!!9!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!"`!!+3!!!&8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!#S!!!"
+@!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!V!!!!9`)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!,!!!!&J#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!F!!#d!!!"C!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!(!!!Z!!!!@J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!"`!!,`!!!&X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!$!!!!"
+F!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!a!!!!A3)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!-J!!!&i#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!F!!$-!!!"I!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!(!!!d!!!!B!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!"`!!03!!!'%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!$B!!!"
+L!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!h!!!!B`)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!1!!!!'3#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!F!!$N!!!"P!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!(!!!k!!!!CJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!"`!!1`!!!'F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!$`!!!"
+S!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!p!!!!D3)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!2J!!!'S#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!F!!$m!!!"V!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!(!!"!!!!!E!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!"`!!33!!!'d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!%)!!!"
+Z!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"$!!!!E`)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!4!!!!(!#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!F!!%8!!!"a!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!(!!"'!!!!FJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!"`!!4`!!!(-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!%J!!!"
+d!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"*!!!!G3)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!5J!!!(B#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!F!!%X!!!"h!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!(!!"-!!!!H!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!"`!!63!!!(N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!%i!!!"
+k!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"2!!!!H`)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!8!!!!(`#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!F!!&%!!!"p!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!(!!"5!!!!IJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!"`!!8`!!!(m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!&3!!!#
+!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"9!!!!J3)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!9J!!!))#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!F!!&F!!!#$!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!(!!"B!!!!K!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!"`!!@3!!!)8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!&S!!!#
+'!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"E!!!!K`)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!A!!!!)J#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!F!!&d!!!#*!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!(!!"H!!!!LJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!"`!!A`!!!)X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!'!!!!#
+-!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"K!!!!M3)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!BJ!!!)i#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!F!!'-!!!#2!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!(!!"N!!!!N!!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!F!!'8!!!#4!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"Q!!!
+!NJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!C`!!!*-#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!'J!!!#8!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!(!!"T!!!!P3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!"`!!DJ!!!*B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!F!!'X!!!#A!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"X!!!
+!Q!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!E3!!!*N#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!'i!!!#D!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!(!!"[!!!!Q`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!"`!!F!!!!*`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!F!!(%!!!#G!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"b!!!
+!RJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!F`!!!*m#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!(3!!!#J!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!(!!"e!!!!S3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!"`!!GJ!!!+)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!F!!(F!!!#M!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"i!!!
+!T!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!H3!!!+8#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!(S!!!#Q!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!(!!"l!!!!T`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!"`!!I!!!!+J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!F!!(d!!!#T!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"q!!!
+!UJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!I`!!!+X#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!)!!!!#X!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!(!!#"!!!!V3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!"`!!JJ!!!+i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!F!!)-!!!#[!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#%!!!
+!X!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!K3!!!,%#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!)B!!!#b!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!(!!#(!!!!X`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!"`!!L!!!!,3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!F!!)N!!!#e!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#+!!!
+!YJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!L`!!!,F#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!)`!!!#i!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!(!!#0!!!!Z3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!"`!!MJ!!!,S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!F!!)m!!!#l!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#3!!!
+!!,`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!*%!!!#p!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#5!!!![J)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!N`!!!,m#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!*3!!!$!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!#9!!!!`3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!PJ!
+!!-)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!*F!!!$$!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#B!!!!a!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!Q3!!!-8#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!*S!!!$'!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!#E!!!!a`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!R!!
+!!-J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!*d!!!$*!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#H!!!!bJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!R`!!!-X#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!+!!!!$-!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!#K!!!!c3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!SJ!
+!!-i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!+-!!!$2!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#N!!!!d!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!T3!!!0%#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!+B!!!$5!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!#R!!!!d`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!U!!
+!!03#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!+N!!!$9!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#U!!!!eJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!U`!!!0F#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!+`!!!$B!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!#Y!!!!f3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!VJ!
+!!0S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!+m!!!$E!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#`!!!!h!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!X3!!!0d#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!,)!!!$H!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!#c!!!!h`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!Y!!
+!!1!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!,8!!!$K!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#f!!!!iJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!Y`!!!1-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!,J!!!$N!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!#j!!!!j3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!ZJ!
+!!1B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!,X!!!$R!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#m!!!!k!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!![3!!!1N#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!,i!!!$U!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!#r!!!!k`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!`!!
+!!1`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!-%!!!$Y!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$#!!!!lJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!``!!!1m#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!-3!!!$`!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!$&!!!!m3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!aJ!
+!!2)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!-F!!!$c!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$)!!!!p!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!b3!!!28#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!-S!!!$f!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!$,!!!!p`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!c!!
+!!2J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!-d!!!$j!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$1!!!!qJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!c`!!!2X#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!0!!!!$m!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!$4!!!!r3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!dJ!
+!!2i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!0-!!!$r!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$8!!!"!!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!e3!!!3%#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!0B!!!%#!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!$A!!!"!`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!f!!
+!!33#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!0N!!!%&!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$D!!!""J)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!f`!!!3F#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!0`!!!%)!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!$G!!!"#3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!hJ!
+!!3S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!0m!!!%,!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$J!!!"$!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!i3!!!3d#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!1)!!!%1!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!$M!!!"$`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!j!!
+!!4!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!18!!!%4!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$Q!!!"%J)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!j`!!!4-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!1J!!!%8!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!$T!!!"&3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!kJ!
+!!4B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!1X!!!%A!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$X!!!"'!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!l3!!!4N#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!1i!!!%D!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!$[!!!"'`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!m!!
+!!4`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!2%!!!%G!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$b!!!"(J)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!m`!!!4m#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!23!!!%J!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!$e!!!")3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!pJ!
+!!5)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!2F!!!%M!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$i!!!"*!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!q3!!!58#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!2S!!!%Q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!$l!!!"*`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!r!!
+!!5J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!2d!!!%T!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$q!!!"+J)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!!r`!!!5X#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!3!!!!%X!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!%"!!!",3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"!J!
+!!5i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!3-!!!%[!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%%!!!"-!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!""3!!!6%#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!3B!!!%b!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!%(!!!"-`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"#!!
+!!63#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!3N!!!%e!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%+!!!"0J)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!"#`!!!6F#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!3`!!!%i!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!%0!!!"13)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"$J!
+!!6S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!3m!!!%l!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%3!!!"2!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!"%3!!!6d#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!4)!!!%q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!%6!!!"2`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"&!!
+!!8!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!48!!!&"!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%@!!!"3J)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!"&`!!!8-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!4J!!!&%!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!%C!!!"43)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"'J!
+!!8B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!4X!!!&(!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%F!!!"5!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!"(3!!!8N#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!4i!!!&+!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!%I!!!"5`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!")!!
+!!8`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!5%!!!&0!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%L!!!"6J)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!")`!!!8m#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!53!!!&3!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!%P!!!"83)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"*J!
+!!9)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!5F!!!&6!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%S!!!"9!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!"+3!!!98#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!5S!!!&@!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!%V!!!"9`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!",!!
+!!9J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!5d!!!&C!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%Z!!!"@J)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!",`!!!9X#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!6!!!!&F!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!%a!!!"A3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"-J!
+!!9i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!6-!!!&I!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%d!!!"B!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!"03!!!@%#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!6B!!!&L!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!%h!!!"B`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"1!!
+!!@3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!6N!!!&P!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%k!!!"CJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!"1`!!!@F#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!6`!!!&S!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!%p!!!"D3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"2J!
+!!@S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!6m!!!&V!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&!!!!"E!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!"33!!!@d#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!8)!!!&Z!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!&$!!!"E`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"4!!
+!!A!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!88!!!&a!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&'!!!"FJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!"4`!!!A-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!8J!!!&d!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!&*!!!"G3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"5J!
+!!AB#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!8X!!!&h!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&-!!!"H!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!"63!!!AN#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!8i!!!&k!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!&2!!!"H`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"8!!
+!!A`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!9%!!!&p!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&5!!!"IJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!"8`!!!B!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!93!!!'"!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!&9!!!"JJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"9J!
+!!B-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!9F!!!'%!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&B!!!"K3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!"@3!!!BB#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!9S!!!'(!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!&E!!!"L!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"A!!
+!!BN#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!9d!!!'+!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&H!!!"L`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!"`!"A`!!!B`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!F!!@!!!!'0!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!(!!&K!!!"MJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"BJ!
+!!Bm#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!@-!!!'3!!)"!!!
+!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"C!!!!C%#!3!!!!!!!3!"!3!
+!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!@8!!!'5!J%!!!!!!!%!!3%!!!!!!!!!!!!
+!!!!"!!!!!!!!!!!(!!&Q!!!"N`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
+!!!!!"`!"C`!!!C3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!@J
+!!!'9!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&T!!!"PJ)"!!!
+!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"DJ!!!CF#!3!!!!!!!3!"!3!
+!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!@X!!!'B!J%!!!!!!!%!!3%!!!!!!!!!!!!
+!!!!"!!!!!!!!!!!(!!&X!!!"Q3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
+!!!!!"`!"E3!!!CS#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!@i
+!!!'E!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&[!!!"R!)"!!!
+!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"F!!!!Cd#!3!!!!!!!3!"!3!
+!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!A%!!!'H!J%!!!!!!!%!!3%!!!!!!!!!!!!
+!!!!"!!!!!!!!!!!(!!&b!!!"R`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
+!!!!!"`!"F`!!!D3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!A3
+!!!'Q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&e!!!"T`)"!!!
+!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!!)
+!!!!$!!!!"!!!!!8!!!!'!!!!"`!!!!J!!!!*!!!!#J!!!!X!!!!-!!!!$3!!!!i
+!!!!2!!!!%!!!!"%!!!!5!!!!%`!!!"3!!!!9!!!!&J!!!"F!!!!B!!!!'3!!!"S
+!!!!E!!!!(!!!!"d!!!!H!!!!(`!!!#!!!!!K!!!!)J!!!#-!!!!N!!!!*3!!!#B
+!!!!R!!!!+!!!!#N!!!!U!!!!+`!!!#`!!!!Y!!!!,J!!!#m!!!!`!!!!-3!!!$)
+!!!!c!!!!0!!!!$8!!!!f!!!!0`!!!$J!!!!j!!!!1J!!!$X!!!!m!!!!23!!!$i
+!!!!r!!!!3!!!!%%!!!"#!!!!3`!!!%3!!!"&!!!!4J!!!%F!!!")!!!!53!!!%S
+!!!",!!!!6!!!!%d!!!"1!!!!6`!!!&!!!!"4!!!!8J!!!&-!!!"8!!!!93!!!&B
+!!!"A!!!!@!!!!&N!!!"D!!!!@`!!!&`!!!"G!!!!AJ!!!&m!!!"J!!!!B3!!!')
+!!!"M!!!!C!!!!'8!!!"Q!!!!C`!!!'J!!!"T!!!!DJ!!!'X!!!"X!!!!E3!!!'i
+!!!"[!!!!F!!!!(%!!!"b!!!!F`!!!(3!!!"e!!!!GJ!!!(F!!!"i!!!!H3!!!(S
+!!!"l!!!!I!!!!(d!!!"q!!!!I`!!!)!!!!#"!!!!JJ!!!)-!!!#%!!!!K3!!!)B
+!!!#(!!!!L!!!!)N!!!#+!!!!L`!!!)`!!!#0!!!!MJ!!!)m!!!#3!!!!!*%!!!#
+5!!!!N`!!!*3!!!#9!!!!PJ!!!*F!!!#B!!!!Q3!!!*S!!!#E!!!!R!!!!*d!!!#
+H!!!!R`!!!+!!!!#K!!!!SJ!!!+-!!!#N!!!!T3!!!+B!!!#R!!!!U!!!!+N!!!#
+U!!!!U`!!!+`!!!#Y!!!!VJ!!!+m!!!#`!!!!X3!!!,)!!!#c!!!!Y!!!!,8!!!#
+f!!!!Y`!!!,J!!!#j!!!!ZJ!!!,X!!!#m!!!![3!!!,i!!!#r!!!!`!!!!-%!!!$
+#!!!!``!!!-3!!!$&!!!!aJ!!!-F!!!$)!!!!b3!!!-S!!!$,!!!!c!!!!-d!!!$
+1!!!!c`!!!0!!!!$4!!!!dJ!!!0-!!!$8!!!!e3!!!0B!!!$A!!!!f!!!!0N!!!$
+D!!!!f`!!!0`!!!$G!!!!hJ!!!0m!!!$J!!!!i3!!!1)!!!$M!!!!j!!!!18!!!$
+Q!!!!j`!!!1J!!!$T!!!!kJ!!!1X!!!$X!!!!l3!!!1i!!!$[!!!!m!!!!2%!!!$
+b!!!!m`!!!23!!!$e!!!!pJ!!!2F!!!$i!!!!q3!!!2S!!!$l!!!!r!!!!2d!!!$
+q!!!!r`!!!3!!!!%"!!!"!J!!!3-!!!%%!!!""3!!!3B!!!%(!!!"#!!!!3N!!!%
++!!!"#`!!!3`!!!%0!!!"$J!!!3m!!!%3!!!"%3!!!4)!!!%6!!!"&!!!!48!!!%
+@!!!"&`!!!4J!!!%C!!!"'J!!!4X!!!%F!!!"(3!!!4i!!!%I!!!")!!!!5%!!!%
+L!!!")`!!!53!!!%P!!!"*J!!!5F!!!%S!!!"+3!!!5S!!!%V!!!",!!!!5d!!!%
+Z!!!",`!!!6!!!!%a!!!"-J!!!6-!!!%d!!!"03!!!6B!!!%h!!!"1!!!!6N!!!%
+k!!!"1`!!!6`!!!%p!!!"2J!!!6m!!!&!!!!"33!!!8)!!!&$!!!"4!!!!88!!!&
+'!!!"4`!!!8J!!!&*!!!"5J!!!8X!!!&-!!!"63!!!8i!!!&2!!!"8!!!!9%!!!&
+5!!!"8`!!!93!!!&9!!!"9J!!!9F!!!&B!!!"@3!!!9S!!!&E!!!"A!!!!9d!!!&
+H!!!"A`!!!@!!!!&K!!!"BJ!!!@-!!!&N!!!"C3!!!@B!!!&R!!!"D!!!!@N!!!&
+U!!!"D`!!!@`!!!&Y!!!"EJ!!!@m!!!&`!!!"F3!!!A)!!!&c!!!"G!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"G3!!!B!(!!!
+!"`!"G3F!!!%(!!!#"`!!!`F!!!3(!!!&"`!!"JF!!!F(!!!)"`!!#3F!!!S(!!!
+,"`!!$!F!!!d(!!!1"`!!$`F!!"!(!!!4"`!!%JF!!"-(!!!8"`!!&3F!!"B(!!!
+A"`!!'!F!!"N(!!!D"`!!'`F!!"`(!!!G"`!!(JF!!"m(!!!J"`!!)3F!!#)(!!!
+M"`!!*!F!!#8(!!!Q"`!!*`F!!#J(!!!T"`!!+JF!!#X(!!!X"`!!,3F!!#i(!!!
+["`!!-!F!!$%(!!!b"`!!-`F!!$3(!!!e"`!!0JF!!$F(!!!i"`!!13F!!$S(!!!
+l"`!!2!F!!$d(!!!q"`!!2`F!!%!(!!"""`!!3JF!!%-(!!"%"`!!43F!!%B(!!"
+("`!!5!F!!%N(!!"+"`!!5`F!!%`(!!"0"`!!6JF!!%m(!!"3"`!!83F!!&)(!!"
+6"`!!9!F!!&8(!!"@"`!!9`F!!&J(!!"C"`!!@JF!!&X(!!"F"`!!A3F!!&i(!!"
+I"`!!B!F!!'%(!!"L"`!"G!F!!'-(!!"N"`!!C3F!!'B(!!"R"`!!D!F!!'N(!!"
+U"`!!D`F!!'`(!!"Y"`!!EJF!!'m(!!"`"`!!F3F!!()(!!"c"`!!G!F!!(8(!!"
+f"`!!G`F!!(J(!!"j"`!!HJF!!(X(!!"m"`!!I3F!!(i(!!"r"`!!J!F!!)%(!!#
+#"`!!J`F!!)3(!!#&"`!!KJF!!)F(!!#)"`!!L3F!!)S(!!#,"`!!M!F!!)d(!!#
+1"`!!M`F!!*!!"`!!N3F!!*)(!!#6"`!!P!F!!*8(!!#@"`!!P`F!!*J(!!#C"`!
+!QJF!!*X(!!#F"`!!R3F!!*i(!!#I"`!!S!F!!+%(!!#L"`!!S`F!!+3(!!#P"`!
+!TJF!!+F(!!#S"`!!U3F!!+S(!!#V"`!!V!F!!+d(!!#Z"`!!V`F!!,!(!!#a"`!
+!XJF!!,-(!!#d"`!!Y3F!!,B(!!#h"`!!Z!F!!,N(!!#k"`!!Z`F!!,`(!!#p"`!
+![JF!!,m(!!$!"`!!`3F!!-)(!!$$"`!!a!F!!-8(!!$'"`!!a`F!!-J(!!$*"`!
+!bJF!!-X(!!$-"`!!c3F!!-i(!!$2"`!!d!F!!0%(!!$5"`!!d`F!!03(!!$9"`!
+!eJF!!0F(!!$B"`!!f3F!!0S(!!$E"`!!h!F!!0d(!!$H"`!!h`F!!1!(!!$K"`!
+!iJF!!1-(!!$N"`!!j3F!!1B(!!$R"`!!k!F!!1N(!!$U"`!!k`F!!1`(!!$Y"`!
+!lJF!!1m(!!$`"`!!m3F!!2)(!!$c"`!!p!F!!28(!!$f"`!!p`F!!2J(!!$j"`!
+!qJF!!2X(!!$m"`!!r3F!!2i(!!$r"`!"!!F!!3%(!!%#"`!"!`F!!33(!!%&"`!
+""JF!!3F(!!%)"`!"#3F!!3S(!!&e"`!"#`F!!3`(!!%0"`!"$JF!!3m(!!%3"`!
+"%3F!!4)(!!%6"`!"&!F!!48(!!%@"`!"&`F!!4J(!!%C"`!"'JF!!4X(!!%F"`!
+"(3F!!4i(!!%I"`!")!F!!5%(!!%L"`!")`F!!53(!!%P"`!"*JF!!5F(!!%S"`!
+"+3F!!5S(!!%V"`!",!F!!5d(!!%Z"`!",`F!!6!(!!%a"`!"-JF!!6-(!!%d"`!
+"03F!!6B(!!%h"`!"1!F!!6N(!!%k"`!"1`F!!6`(!!%p"`!"2JF!!6m(!!&!"`!
+"33F!!8)(!!&$"`!"4!F!!88(!!&'"`!"4`F!!8J(!!&*"`!"5JF!!8X(!!&-"`!
+"63F!!8i(!!&2"`!"8!F!!9%(!!&5"`!"8`F!!93(!!&9"`!"9JF!!9F(!!&B"`!
+"@3F!!9S(!!&E"`!"A!F!!9d(!!&H"`!"A`F!!@!(!!&K"`!"BJF!!@-(!!&N"`!
+"C3F!!@B(!!&R"`!"D!F!!@N(!!&U"`!"D`F!!@`(!!&Y"`!"EJF!!@m(!!&`"`!
+"F3F!!A)(!!&c!!!"U3!"!#J!!!!!!jH9J!!!!!!!!(rr!!!"!!!!HF!!!J!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!,#2Z!!!!!!!!!"!!,#4r!!!J!!!!!
+!!!!!!!!#`MD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!J!!!3!
+!!!!&!!"rr`!!!!"rr`!!!!"rr`!!!!"rr`!!!!`!!3!#!!B!!!!&3!!!#!!"!!%
+k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!2rrrrm
+!!!!$!!%!!6Sk!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+"!!!!rrrrr`!!!!3!!3!"1MTTEQ0XG@4P1J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!$rrrrr3!!!!J!"!!%k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!2rrrrp!!!!$!!%!!6Sk1NG98dNkD@jME(9NC6S
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!rrrrrd!!!!3!!3!"1MSk4e9656T
+XD@)k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$rrrrr3!!!"3!#!!%
+k6@&M6e-J8h9`F'pbG$S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!2rrrrp
+!!!!'!!)!!6T08d`k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+"!!!!rrrrrd!!!!F!#J!!6@&M6e-J0MK,)%aTEQYPFJ!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!6'PL3h*jF(4[)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!%k!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!&0B@028b!f1%XJ6'P
+ZDf9b!!!!!!!!!!!!!!!!!!!!!!!J39"36!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!3A"
+`E!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"J!!!!68e-3J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!6'PL)%PYF'pbG#!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69"
+-4J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6'PL)%PYF'pbG#!f1%X
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69G$4!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!6d*
++)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69"A)%PYF'pbG#!f1%X
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%a[BJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!8P0
+53`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"J!!!!9%9B9#jLD!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!3Q&XE'p[EL")C@a`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
+B9#jM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jM+bX!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
+B9#jMB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jMF!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
+B9#jMF(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jPH(!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
+B9#jRB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4f&YC80[C'8J3fpZGQ9
+bG'9b!!!!!!!!!!!!!!!!!!"!!!!!9%9B9#jS!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!!9%9
+B9#jX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4QaPH#"3FQ9`FQpMCA0
+cEh)!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!69FJ8'&cBf&X)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
+B9#j`BA-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)$Bi5`!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j`BfJ!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9
+B9#j`BfJV+`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!
+!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`F(8!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!69FJ8'&cBf&X)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9
+B9#jb!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8Q9k!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jcC@F!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
+B9#jj!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3QPcEfiJ8(*PF(*[Bf9
+cFfpb!!!!!!!!!!!!!!!!!!#!!!!!C'pMG3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!FR0
+bB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"J!!!!FfKXBJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!8%9')%PYF'pbG#!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Fh4
+eBJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%9')%PYF'pbG#!f1%X
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#jNEf-!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"3!!!!!!!
+!!#jbFh*M!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!"J!!!!!!8"!3!"!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!
+!!!!"!!!!!!8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!"!3!!E@&TEJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!3!"!!!!!3%"!!!"!3%!!!!
+!!!%"!!!"!3!"!!!""!!!!!!!!!!!!!!)!3!"!3!"!3!!!!%!!!N!!aY-D@*$FRP
+`G'mZ0MKV)%CK+$4TAcKN+5j-D@)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!r2cmr2cmr2`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$mr2cm!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!0!!%!!!!!!"9I69G&8NY6AdG98dPIF(*PCQPi,QJ!!!!!!!!
+!!!!!!!!"!!!!!!!!!!!"!!!!!!!!!!!!!!8"!3%!!!%"!!%!!!!!"!!!!!!!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"IAh0
+dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!3!!#8ePFQGP)%peG!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!$mr2cp"8&"-!!%"!!!%)#!J)!1ARe!$GYpi!`@Z%!!&!J%!!3%!!3%"!!!
+"!!!!!!!!!!%"!3%!!3%!!3!""!!!!!!!!!!!!!!(!3%!!3!!!3!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!"IAh0dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8!!!G2F'9Z8e0-!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!2cmr2d&38%`!!!3!!!!%!!!!!%!!!&M!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%r2cm
+r!!!!!!!!!!)!!!!#!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!#!&!!!3!"!!%!!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8*d024%8R)#G%394"*b!
+R8%P$9#F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!#!!!!3!!!#d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!!)!!!!
+Z!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!$!!!!,`)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!"!!!!$!#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!J!!!8!!!!a!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!)!!!'!!!!-J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!#!!!"`!!!$-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!!J!!!!
+d!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!*!!!!03)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!#J!!!$B#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!J!!!X!!!!h!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!)!!!-!!!!1!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!#!!!$3!!!$N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!!i!!!!
+k!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!2!!!!1`)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!%!!!!$`#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!J!!"%!!!!p!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!)!!!5!!!!2J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!#!!!%`!!!$m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!"3!!!"
+!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!9!!!!33)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!&J!!!%)#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!J!!"F!!!"$!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!)!!!B!!!!4!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!#!!!'3!!!%8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!"S!!!"
+'!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!E!!!!4`)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!(!!!!%J#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!J!!"d!!!"*!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!)!!!H!!!!5J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!#!!!(`!!!%X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!#!!!!"
+-!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!K!!!!63)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!)J!!!%i#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!J!!#-!!!"2!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!)!!!N!!!!8!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!#!!!*3!!!&%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!#B!!!"
+5!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!R!!!!8`)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!+!!!!&3#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!J!!#N!!!"9!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!)!!!U!!!!9J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!#!!!+`!!!&F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!#`!!!"
+B!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!Y!!!!@3)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!,J!!!&S#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!J!!#m!!!"E!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!)!!!`!!!!A!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!#!!!-3!!!&d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!$)!!!"
+H!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!c!!!!A`)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!0!!!!'!#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!J!!$8!!!"K!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!)!!!f!!!!BJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!#!!!0`!!!'-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!$J!!!"
+N!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!j!!!!C3)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!1J!!!'B#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!J!!$X!!!"R!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!)!!!m!!!!D!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!#!!!23!!!'N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!$i!!!"
+U!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!r!!!!D`)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!3!!!!'`#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!J!!%%!!!"Y!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!)!!"#!!!!EJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!#!!!3`!!!'m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!%3!!!"
+`!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"&!!!!F3)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!4J!!!()#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!J!!%F!!!"c!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!)!!")!!!!G!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!#!!!53!!!(8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!%S!!!"
+f!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!",!!!!G`)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!6!!!!(J#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!J!!%d!!!"j!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!)!!"1!!!!HJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!#!!!6`!!!(X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!&!!!!"
+m!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"4!!!!I3)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!8J!!!(i#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!J!!&-!!!"r!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!)!!"8!!!!J!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!#!!!93!!!)%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!&B!!!#
+#!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"A!!!!J`)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!@!!!!)3#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!J!!&N!!!#&!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!)!!"D!!!!KJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!#!!!@`!!!)F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!&`!!!#
+)!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"G!!!!L3)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!AJ!!!)S#!3!!!!!!!3!"!3!!!!!
+!!!!!!!!!!!%!!!!!!!!!!!J!!&m!!!#,!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
+"!!!!!!!!!!!)!!"J!!!!M!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
+!#!!!B3!!!)d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!')!!!#
+1!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"M!!!!M`)"!!!!!!!
+"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!C!!!!*!!!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!)!!"P!!!!N3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!#!!!CJ!!!*)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!J!!'F!!!#6!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"S!!!
+!P!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!D3!!!*8#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!'S!!!#@!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!)!!"V!!!!P`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!#!!!E!!!!*J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!J!!'d!!!#C!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"Z!!!
+!QJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!E`!!!*X#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!(!!!!#F!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!)!!"a!!!!R3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!#!!!FJ!!!*i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!J!!(-!!!#I!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"d!!!
+!S!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!G3!!!+%#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!(B!!!#L!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!)!!"h!!!!S`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!#!!!H!!!!+3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!J!!(N!!!#P!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"k!!!
+!TJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!H`!!!+F#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!(`!!!#S!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!)!!"p!!!!U3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!#!!!IJ!!!+S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!J!!(m!!!#V!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#!!!!
+!V!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!J3!!!+d#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!))!!!#Z!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!)!!#$!!!!V`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!#!!!K!!!!,!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!J!!)8!!!#a!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#'!!!
+!XJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!K`!!!,-#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!)J!!!#d!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!)!!#*!!!!Y3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!#!!!LJ!!!,B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
+!!!J!!)X!!!#h!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#-!!!
+!Z!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!M3!!!,N#!3!!!!!
+!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!)i!!!#k!J%!!!!!!!%!!3%!!!!
+!!!!!!!!!!!!"!!!!!!!!!!!)!!#2!!!!Z`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
+!!3!!!!!!!!!!#!!!N!!!!!#m!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!#4!!!![3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!NJ!
+!!,i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!*-!!!#r!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#8!!!!`!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!!P3!!!-%#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!*B!!!$#!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!#A!!!!``)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!Q!!
+!!-3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!*N!!!$&!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#D!!!!aJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!!Q`!!!-F#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!*`!!!$)!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!#G!!!!b3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!RJ!
+!!-S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!*m!!!$,!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#J!!!!c!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!!S3!!!-d#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!+)!!!$1!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!#M!!!!c`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!T!!
+!!0!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!+8!!!$4!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#Q!!!!dJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!!T`!!!0-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!+J!!!$8!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!#T!!!!e3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!UJ!
+!!0B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!+X!!!$A!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#X!!!!f!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!!V3!!!0N#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!+i!!!$D!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!#[!!!!f`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!X!!
+!!0`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!,%!!!$G!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#b!!!!hJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!!X`!!!0m#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!,3!!!$J!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!#e!!!!i3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!YJ!
+!!1)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!,F!!!$M!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#i!!!!j!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!!Z3!!!18#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!,S!!!$Q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!#l!!!!j`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!![!!
+!!1J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!,d!!!$T!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#q!!!!kJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!![`!!!1X#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!-!!!!$X!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!$"!!!!l3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!`J!
+!!1i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!--!!!$[!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$%!!!!m!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!!a3!!!2%#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!-B!!!$b!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!$(!!!!m`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!b!!
+!!23#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!-N!!!$e!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$+!!!!pJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!!b`!!!2F#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!-`!!!$i!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!$0!!!!q3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!cJ!
+!!2S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!-m!!!$l!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$3!!!!r!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!!d3!!!2d#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!0)!!!$q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!$6!!!!r`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!e!!
+!!3!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!08!!!%"!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$@!!!"!J)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!!e`!!!3-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!0J!!!%%!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!$C!!!""3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!fJ!
+!!3B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!0X!!!%(!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$F!!!"#!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!!h3!!!3N#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!0i!!!%+!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!$I!!!"#`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!i!!
+!!3`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!1%!!!%0!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$L!!!"$J)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!!i`!!!3m#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!13!!!%3!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!$P!!!"%3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!jJ!
+!!4)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!1F!!!%6!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$S!!!"&!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!!k3!!!48#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!1S!!!%@!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!$V!!!"&`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!l!!
+!!4J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!1d!!!%C!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$Z!!!"'J)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!!l`!!!4X#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!2!!!!%F!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!$a!!!"(3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!mJ!
+!!4i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!2-!!!%I!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$d!!!")!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!!p3!!!5%#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!2B!!!%L!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!$h!!!")`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!q!!
+!!53#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!2N!!!%P!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$k!!!"*J)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!!q`!!!5F#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!2`!!!%S!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!$p!!!"+3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!rJ!
+!!5S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!2m!!!%V!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%!!!!",!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!"!3!!!5d#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!3)!!!%Z!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!%$!!!",`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!""!!
+!!6!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!38!!!%a!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%'!!!"-J)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!""`!!!6-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!3J!!!%d!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!%*!!!"03)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"#J!
+!!6B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!3X!!!%h!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%-!!!"1!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!"$3!!!6N#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!3i!!!%k!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!%2!!!"1`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"%!!
+!!6`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!4%!!!%p!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%5!!!"2J)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!"%`!!!6m#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!43!!!&!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!%9!!!"33)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"&J!
+!!8)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!4F!!!&$!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%B!!!"4!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!"'3!!!88#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!4S!!!&'!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!%E!!!"4`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"(!!
+!!8J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!4d!!!&*!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%H!!!"5J)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!"(`!!!8X#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!5!!!!&-!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!%K!!!"63)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!")J!
+!!8i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!5-!!!&2!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%N!!!"8!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!"*3!!!9%#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!5B!!!&5!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!%R!!!"8`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"+!!
+!!93#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!5N!!!&9!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%U!!!"9J)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!"+`!!!9F#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!5`!!!&B!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!%Y!!!"@3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!",J!
+!!9S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!5m!!!&E!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%`!!!"A!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!"-3!!!9d#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!6)!!!&H!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!%c!!!"A`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"0!!
+!!@!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!68!!!&K!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%f!!!"BJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!"0`!!!@-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!6J!!!&N!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!%j!!!"C3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"1J!
+!!@B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!6X!!!&R!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%m!!!"D!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!"23!!!@N#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!6i!!!&U!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!%r!!!"D`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"3!!
+!!@`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!8%!!!&Y!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&#!!!"EJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!"3`!!!@m#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!83!!!&`!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!&&!!!"F3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"4J!
+!!A)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!8F!!!&c!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&)!!!"G!)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!"53!!!A8#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!8S!!!&f!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!&,!!!"G`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"6!!
+!!AJ#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!8d!!!&j!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&1!!!"HJ)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!"6`!!!AX#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!9!!!!&m!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!&4!!!"I3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"8J!
+!!Ai#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!9-!!!'!!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&8!!!"J3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!"93!!!B)#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!9B!!!'$!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!&A!!!"K!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"@!!
+!!B8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!9N!!!''!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&D!!!"K`)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!"@`!!!BJ#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!9`!!!'*!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!&G!!!"LJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"AJ!
+!!BX#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!9m!!!'-!J%!!!!
+!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&J!!!"M3)"!!!!!!!"!!%"!!!
+!!!!!!!!!!!!!!3!!!!!!!!!!#!!"B3!!!Bi#!3!!!!!!!3!"!3!!!!!!!!!!!!!
+!!!%!!!!!!!!!!!J!!@)!!!'2!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
+!!!!)!!&M!!!"N!!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!@3
+!!!'4!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&P!!!"NJ)"!!!
+!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"CJ!!!C-#!3!!!!!!!3!"!3!
+!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!@F!!!'8!J%!!!!!!!%!!3%!!!!!!!!!!!!
+!!!!"!!!!!!!!!!!)!!&S!!!"P3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
+!!!!!#!!"D3!!!CB#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!@S
+!!!'A!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&V!!!"Q!)"!!!
+!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"E!!!!CN#!3!!!!!!!3!"!3!
+!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!@d!!!'D!J%!!!!!!!%!!3%!!!!!!!!!!!!
+!!!!"!!!!!!!!!!!)!!&Z!!!"Q`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
+!!!!!#!!"E`!!!C`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!A!
+!!!'G!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&a!!!"RJ)"!!!
+!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"FJ!!!Cm#!3!!!!!!!3!"!3!
+!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!A-!!!'N!J%!!!!!!!%!!3%!!!!!!!!!!!!
+!!!!"!!!!!!!!!!!)!!&d!!!"TJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
+!!!!!#!!"G3!!!DF#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!%!!!!#!!!!!`!!!!3!!!!&!!!!"J!!!!F!!!!)!!!!#3!!!!S
+!!!!,!!!!$!!!!!d!!!!1!!!!$`!!!"!!!!!4!!!!%J!!!"-!!!!8!!!!&3!!!"B
+!!!!A!!!!'!!!!"N!!!!D!!!!'`!!!"`!!!!G!!!!(J!!!"m!!!!J!!!!)3!!!#)
+!!!!M!!!!*!!!!#8!!!!Q!!!!*`!!!#J!!!!T!!!!+J!!!#X!!!!X!!!!,3!!!#i
+!!!![!!!!-!!!!$%!!!!b!!!!-`!!!$3!!!!e!!!!0J!!!$F!!!!i!!!!13!!!$S
+!!!!l!!!!2!!!!$d!!!!q!!!!2`!!!%!!!!""!!!!3J!!!%-!!!"%!!!!43!!!%B
+!!!"(!!!!5!!!!%N!!!"+!!!!5`!!!%`!!!"0!!!!6J!!!%m!!!"3!!!!83!!!&)
+!!!"6!!!!9!!!!&8!!!"@!!!!9`!!!&J!!!"C!!!!@J!!!&X!!!"F!!!!A3!!!&i
+!!!"I!!!!B!!!!'%!!!"L!!!!B`!!!'3!!!"P!!!!CJ!!!'F!!!"S!!!!D3!!!'S
+!!!"V!!!!E!!!!'d!!!"Z!!!!E`!!!(!!!!"a!!!!FJ!!!(-!!!"d!!!!G3!!!(B
+!!!"h!!!!H!!!!(N!!!"k!!!!H`!!!(`!!!"p!!!!IJ!!!(m!!!#!!!!!J3!!!))
+!!!#$!!!!K!!!!)8!!!#'!!!!K`!!!)J!!!#*!!!!LJ!!!)X!!!#-!!!!M3!!!)i
+!!!#2!!!!N!!!!!#4!!!!NJ!!!*-!!!#8!!!!P3!!!*B!!!#A!!!!Q!!!!*N!!!#
+D!!!!Q`!!!*`!!!#G!!!!RJ!!!*m!!!#J!!!!S3!!!+)!!!#M!!!!T!!!!+8!!!#
+Q!!!!T`!!!+J!!!#T!!!!UJ!!!+X!!!#X!!!!V3!!!+i!!!#[!!!!X!!!!,%!!!#
+b!!!!X`!!!,3!!!#e!!!!YJ!!!,F!!!#i!!!!Z3!!!,S!!!#l!!!![!!!!,d!!!#
+q!!!![`!!!-!!!!$"!!!!`J!!!--!!!$%!!!!a3!!!-B!!!$(!!!!b!!!!-N!!!$
++!!!!b`!!!-`!!!$0!!!!cJ!!!-m!!!$3!!!!d3!!!0)!!!$6!!!!e!!!!08!!!$
+@!!!!e`!!!0J!!!$C!!!!fJ!!!0X!!!$F!!!!h3!!!0i!!!$I!!!!i!!!!1%!!!$
+L!!!!i`!!!13!!!$P!!!!jJ!!!1F!!!$S!!!!k3!!!1S!!!$V!!!!l!!!!1d!!!$
+Z!!!!l`!!!2!!!!$a!!!!mJ!!!2-!!!$d!!!!p3!!!2B!!!$h!!!!q!!!!2N!!!$
+k!!!!q`!!!2`!!!$p!!!!rJ!!!2m!!!%!!!!"!3!!!3)!!!%$!!!""!!!!38!!!%
+'!!!""`!!!3J!!!%*!!!"#J!!!3X!!!%-!!!"$3!!!3i!!!%2!!!"%!!!!4%!!!%
+5!!!"%`!!!43!!!%9!!!"&J!!!4F!!!%B!!!"'3!!!4S!!!%E!!!"(!!!!4d!!!%
+H!!!"(`!!!5!!!!%K!!!")J!!!5-!!!%N!!!"*3!!!5B!!!%R!!!"+!!!!5N!!!%
+U!!!"+`!!!5`!!!%Y!!!",J!!!5m!!!%`!!!"-3!!!6)!!!%c!!!"0!!!!68!!!%
+f!!!"0`!!!6J!!!%j!!!"1J!!!6X!!!%m!!!"23!!!6i!!!%r!!!"3!!!!8%!!!&
+#!!!"3`!!!83!!!&&!!!"4J!!!8F!!!&)!!!"53!!!8S!!!&,!!!"6!!!!8d!!!&
+1!!!"6`!!!9!!!!&4!!!"8J!!!9-!!!&8!!!"93!!!9B!!!&A!!!"@!!!!9N!!!&
+D!!!"@`!!!9`!!!&G!!!"AJ!!!9m!!!&J!!!"B3!!!@)!!!&M!!!"C!!!!@8!!!&
+Q!!!"C`!!!@J!!!&T!!!"DJ!!!@X!!!&X!!!"E3!!!@i!!!&[!!!"F!!!!A%!!!&
+b!!!"F`!!!A3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!A8!!!'!#!!!!!J!!A8!!!(E!!%!(!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!J!!!%)!!!##!!!!`J!!!3)!!!&#!!!"JJ!!!F)!!!)#!!!#3J!!!S)!!!
+,#!!!$!J!!!d)!!!1#!!!$`J!!"!)!!!4#!!!%JJ!!"-)!!!8#!!!&3J!!"B)!!!
+A#!!!'!J!!"N)!!!D#!!!'`J!!"`)!!!G#!!!(JJ!!"m)!!!J#!!!)3J!!#))!!!
+M#!!!*!J!!#8)!!!Q#!!!*`J!!#J)!!!T#!!!+JJ!!#X)!!!X#!!!,3J!!#i)!!!
+[#!!!-!J!!$%)!!!b#!!!-`J!!$3)!!!e#!!!0JJ!!$F)!!!i#!!!13J!!$S)!!!
+l#!!!2!J!!$d)!!!q#!!!2`J!!%!)!!""#!!!3JJ!!%-)!!"%#!!!43J!!%B)!!"
+(#!!!5!J!!%N)!!"+#!!!5`J!!%`)!!"0#!!!6JJ!!%m)!!"3#!!!83J!!&))!!"
+6#!!!9!J!!&8)!!"@#!!!9`J!!&J)!!"C#!!!@JJ!!&X)!!"F#!!!A3J!!&i)!!"
+I#!!!B!J!!'%)!!"L#!!"G!J!!'-)!!"N#!!!C3J!!'B)!!"R#!!!D!J!!'N)!!"
+U#!!!D`J!!'`)!!"Y#!!!EJJ!!'m)!!"`#!!!F3J!!())!!"c#!!!G!J!!(8)!!"
+f#!!!G`J!!(J)!!"j#!!!HJJ!!(X)!!"m#!!!I3J!!(i)!!"r#!!!J!J!!)%)!!#
+##!!!J`J!!)3)!!#&#!!!KJJ!!)F)!!#)#!!!L3J!!)S)!!#,#!!!M!J!!)d)!!#
+1#!!!M`J!!*!!#!!!N3J!!*))!!#6#!!!P!J!!*8)!!#@#!!!P`J!!*J)!!#C#!!
+!QJJ!!*X)!!#F#!!!R3J!!*i)!!#I#!!!S!J!!+%)!!#L#!!!S`J!!+3)!!#P#!!
+!TJJ!!+F)!!#S#!!!U3J!!+S)!!#V#!!!V!J!!+d)!!#Z#!!!V`J!!,!)!!#a#!!
+!XJJ!!,-)!!#d#!!!Y3J!!,B)!!#h#!!!Z!J!!,N)!!#k#!!!Z`J!!,`)!!#p#!!
+![JJ!!,m)!!$!#!!!`3J!!-))!!$$#!!!a!J!!-8)!!$'#!!!a`J!!-J)!!$*#!!
+!bJJ!!-X)!!$-#!!!c3J!!-i)!!$2#!!!d!J!!0%)!!$5#!!!d`J!!03)!!$9#!!
+!eJJ!!0F)!!$B#!!!f3J!!0S)!!$E#!!!h!J!!0d)!!$H#!!!h`J!!1!)!!$K#!!
+!iJJ!!1-)!!$N#!!!j3J!!1B)!!$R#!!!k!J!!1N)!!$U#!!!k`J!!1`)!!$Y#!!
+!lJJ!!1m)!!$`#!!!m3J!!2))!!$c#!!!p!J!!28)!!$f#!!!p`J!!2J)!!$j#!!
+!qJJ!!2X)!!$m#!!!r3J!!2i)!!$r#!!"!!J!!3%)!!%##!!"!`J!!33)!!%&#!!
+""JJ!!3F)!!%)#!!"#3J!!3S)!!&e#!!"#`J!!3`)!!%0#!!"$JJ!!3m)!!%3#!!
+"%3J!!4))!!%6#!!"&!J!!48)!!%@#!!"&`J!!4J)!!%C#!!"'JJ!!4X)!!%F#!!
+"(3J!!4i)!!%I#!!")!J!!5%)!!%L#!!")`J!!53)!!%P#!!"*JJ!!5F)!!%S#!!
+"+3J!!5S)!!%V#!!",!J!!5d)!!%Z#!!",`J!!6!)!!%a#!!"-JJ!!6-)!!%d#!!
+"03J!!6B)!!%h#!!"1!J!!6N)!!%k#!!"1`J!!6`)!!%p#!!"2JJ!!6m)!!&!#!!
+"33J!!8))!!&$#!!"4!J!!88)!!&'#!!"4`J!!8J)!!&*#!!"5JJ!!8X)!!&-#!!
+"63J!!8i)!!&2#!!"8!J!!9%)!!&5#!!"8`J!!93)!!&9#!!"9JJ!!9F)!!&B#!!
+"@3J!!9S)!!&E#!!"A!J!!9d)!!&H#!!"A`J!!@!)!!&K#!!"BJJ!!@-)!!&N#!!
+"C3J!!@B)!!&R#!!"D!J!!@N)!!&U#!!"D`J!!@`)!!&Y#!!"EJJ!!@m)!!&`#!!
+"F3J!!A))!!&c!!!!#!!!!H%"!!!"!!!!!!!!!!!!"!!"!!!"kE6H0L[rrmA@!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"iJ)!!!%!!!!!!!!!!!!%!!%!!!(eY0i
+f,!!!IZ)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!(M!`!!!3!!!!!!!!!!!!3
+!!3!!!IDdhMBX!!!f%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!H3%!!!"!!!
+!!!!!!!!!"!!"!!!"r,6H0L`!!&C*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+"j38!!!%!!!!!!!!!!!!%!!%!!!(pY0if,2rrp2N!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!(Q"J!!!3!!!!!!!!!!!!3!!3!!!G'dhMBX!!!Si3!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!HF(!!!"!!!!!!!!!!!!"!!"!!!"dV6H0L`!!!ca!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"k!J!!!%!!!!!!!!!!!!%!!%!!!(IY0i
+f,2rr[fi!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!!!!!H%!!!!"i`!!!!(
+L!!!!!H8!!!!"jJ!!!!(N!!!!!HF!!!!"k!!"!!!!!&*26e3!!!!!!!!!!!!!!!!
+'4e*98!!!!!!!!!!!$P*[H5Gc)%GPG%K89&"6!!!!"8C*6%8"!!'L4NP-43%!!D0
+'58a&!3!"U%C*6%8"!!'K4NP-43%!!D"(8P93!!!!!!!!!!!66h"PEP066#""F("
+XD@0KG'P[EJ!!!#0'58a&!J!!(%C*6%8#!!!U4NP-43)!!!e'58a&!J!!)%C*6%8
+#!!!54NP-43)!!"0'58a&!J!!&NC*6%8#!!!B4NP-43)!!"G'58a&!J!!$NC*6%8
+#!!!H4NP-43)!!"&'58a&!J!!%%C*6%8#!!!K4NP-43)!!"4'58a&!J!!&8C*6%8
+#!!!X4NP-43)!!"T'58a&!J!!'8C*6%8#!!!S4NP-43)!!#G'58a&!J!!*%C*6%8
+#!!!Y4NP-43)!!!Y'58a&!J!!*NC*6%8#!!!T4NP-43)!!!a'58a&!J!!+dC*6%8
+#!!!L4NP-43)!!!p'58a&!J!!'dC*6%8#!!!G4NP-43)!!"p'58a&!J!!*8C*6%8
+#!!!M4e*98!!!!!!!!!!!%8p`C@j68d`J6'PLFQ&bD@9c!!!!"%G599!!!!!!!!!
+!!!038%-!!!!#4NP-43)!!$0'58a&!J!!0%G599!!!!!!!!!!!!-f1'X!!!!#4NP
+-438!!#"'58a&"3!!(dG599!!!!!!!!!!!!CMFRP`G'm!!!!S4NP-43%!!Aa'58a
+&!3!"INC*6%8"!!'N4NP-43%!!Cp'58a&!3!"I8C*6%8"!!&l4e*98!!!!!!!!!!
+!"'&cEM%!!!"A4NP-43%!!$j'58a&!3!!-8C*6%8"!!"&4NP-43%!!$P'58a&!3!
+!3dC*6%8"!!!m4NP-43%!!$p'58a&!3!!3%C*6%8"!!"%4NP-43%!!%&'58a&!3!
+!0dC*6%8"!!!e4NP-43%!!$Y'58a&!3!!-NC*6%8"!!!i4NP-43%!!%K'58a&!3!
+!4NC*6%8"!!"#4NP-43%!!$C'58a&!3!!4dC*6%8"!!')4NP-43%!!("'58a&!3!
+!I%C*6%8"!!"i4NP-43%!!(T'58a&!3!!H8C*6%8"!!"a4NP-43%!!(C'58a&!3!
+!FNC*6%8"!!"p4NP-43%!!B&'58a&!3!!FdC*6%8"!!"e4NP-43%!!(Y'58a&!3!
+!A8C*6%8"!!"04NP-43%!!&P'58a&!3!!6NC*6%8"!!"D4NP-43%!!%p'58a&!3!
+!@dC*6%8"!!"34NP-43%!!&a'58a&!3!!5dC*6%8"!!"A4NP-43%!!%a'58a&!3!
+!@%C*6%8"!!"Z4NP-43%!!'p'58a&!3!"LNC*6%8"!!"X4NP-43%!!'e'58a&!3!
+"L8C*6%8"!!',4NP-43%!!'9'58a&!3!!D8C*6%8"!!"S4NP-43%!!'G'58a&!3!
+!BdC*6%8"!!"N4NP-43%!!'&'58a&!3!!DNC*6%8"!!"L4NP-43%!!'C'58a&!3!
+!8dC*6%8"!!"84NP-43%!!&9'58a&!3!!9NC*6%8"!!"*4NP-43%!!%T'58a&!3!
+!ANC*6%8"!!"54NP-43%!!$T'58a&!3!!GdC*6%8"!!!c4NP-43%!!(4'58a&!3!
+!,dC*6%8"!!!Z4NP-43%!!#e'58a&!3!!28C*6%8"!!!d4NP-43%!!Ba'58a&!3!
+!88C*6%8"!!!`4NP-43%!!&p'58a&!3!!B%C*6%8"!!"V4e*98!!!!!!!!!!!!Q*
+Q!!!!"8C*6%8"!!##4NP-43%!!(p'58a&!3!!J%C*6%8"!!"q4NP-43%!!)&(8P9
+3!!!!!!!!!!!$BQP[!!!!$NC*6%8"!!#%4NP-43%!!Be'58a&!3!!JdC*6%8"!!'
+14NP-43%!!C&'58a&!3!"MdC*6%8"!!'3!%C*6%8"!!#&4NP-43%!!C*'58a&!3!
+"J%C*6%8"!!'(4NP-43%!!C9'58a&!3!"NdC*6%8"!!'84e*98!!!!!!!!!!!!Q*
+Z!!!!&%C*6%8"!!#'4NP-43%!!)P'58a&!3!!LdC*6%8"!!#14NP-43%!!DC'58a
+&!3!!N8C*6%8"!!#64NP-43%!!*4'58a&!3!!PNC*6%8"!!#B4NP-43%!!)K'58a
+&!3!!M8C*6%8"!!#54NP-43%!!)T'58a&!3!!PdC*6%8"!!#(4NP-43%!!*9'58a
+&!3!!MdC*6%8"!!#3!%C*6%8"!!#-4e*98!!!!!!!!!!!"Q*eCQCPFJ!!!!*'58a
+&!3!!Q8C*6%8"!!#D4e*98!!!!!!!!!!!"'0KFh3!!!!&4NP-43%!!*p'58a&!3!
+!R%C*6%8"!!#G4NP-43%!!*Y'58a&!3!!RNG599!!!!!!!!!!!!4MEfe`!!!!!dC
+*6%8"!!#J4NP-43%!!+&'58a&!3!!SNG599!!!!!!!!!!!!4MEfjQ!!!!!NC*6%8
+"!!#M4NP-43%!!+4(8P93!!!!!!!!!!!$C'9c!!!!'NC*6%8"!!#P4NP-43%!!+C
+'58a&!3!!U%C*6%8"!!#T4NP-43%!!+Y'58a&!3!!V%C*6%8"!!#Z4NP-43%!!CC
+'58a&!3!!VdC*6%8"!!#b4NP-43%!!,0'58a&!3!!Y%C*6%8"!!#e4NP-43%!!,C
+'58a&!3!!Z%C*6%8"!!#j4NP-43%!!,T'58a&!3!!UNC*6%8"!!#`4NP-43%!!,G
+'58a&!3!![8C*6%8"!!#l4NP-43%!!+G'58a&!3!!X8C*6%8"!!#m4NP-43%!!+e
+(8P93!!!!!!!!!!!#C'J!!!!&4NP-43%!!-"'58a&!3!!`8C*6%8"!!$#4NP-43%
+!!,j'58a&!3!![dG599!!!!!!!!!!!!0NFf%!!!!)4NP-43%!!-9'58a&!3!!aNC
+*6%8"!!$(4NP-43%!!-0'58a&!3!!b8C*6%8"!!$)4NP-43%!!-4'58a&!3!"JNG
+599!!!!!!!!!!!!0PFR)!!!!$4NP-43%!!-T'58a&!3!!bdC*6%8"!!$-4e*98!!
+!!!!!!!!!!f9fF!!!!$p'58a&!3!!ddC*6%8"!!$54NP-43%!!04'58a&!3!!eNC
+*6%8"!!$V4NP-43%!!0e'58a&!3!!j%C*6%8"!!$c4NP-43%!!1a'58a&!3!!hNC
+*6%8"!!$P4NP-43%!!24'58a&!3!!k%C*6%8"!!$D4NP-43%!!2G'58a&!3!"!NC
+*6%8"!!$K4NP-43%!!2"'58a&!3!!q%C*6%8"!!$Y4NP-43%!!0p'58a&!3!!jNC
+*6%8"!!$e4NP-43%!!1P'58a&!3!!fdC*6%8"!!$L4NP-43%!!2&'58a&!3!!kNC
+*6%8"!!$F4NP-43%!!10'58a&!3!!mNC*6%8"!!$Z4NP-43%!!1"'58a&!3!!jdC
+*6%8"!!$f4NP-43%!!2j'58a&!3!!qdC*6%8"!!$m4NP-43%!!3"'58a&!3!"!8C
+*6%8"!!$j4NP-43%!!2T'58a&!3!!r8C*6%8"!!$r4NP-43%!!3C'58a&!3!""dC
+*6%8"!!%)4NP-43%!!3P'58a&!3!""8C*6%8"!!%%4NP-43%!!30'58a&!3!!cdC
+*6%8"!!$04NP-43%!!-j'58a&!3!!e8C*6%8"!!$[4NP-43%!!0&'58a&!3!!edC
+*6%8"!!$34NP-43%!!0P'58a&!3!!f%C*6%8"!!'A4NP-43%!!CK(8P93!!!!!!!
+!!!!%D'eKB`!!!!&'58a&!3!"#NG599!!!!!!!!!!!!4TC'9K!!!!"8C*6%8"!!%
+,4NP-43%!!3a'58a&!3!"$NC*6%8"!!%04NP-43%!!3p(8P93!!!!!!!!!!!&E'K
+KFfJ!!!!#4NP-43%!!4"'58a&!3!"%8G599!!!!!!!!!!!!0YC$)!!!!#4NP-43%
+!!4*'58a&!3!"%dG599!!!!!!!!!!!!0YC$8!!!!#4NP-43%!!44'58a&!3!"&8G
+599!!!!!!!!!!!!4YC'-b!!!!!NC*6%8"!!%@4NP-43%!!4G(8P93!!!!!!!!!!!
+(Ef*UC@0dF`!!!!4'58a&!3!"'dC*6%8"!!%B4NP-43%!!4T'58a&!3!"'8G599!
+!!!!!!!!!!!0`C@d!!!!'4NP-43%!!5&'58a&!3!")%C*6%8"!!%H4NP-43%!!4p
+'58a&!3!"(%C*6%8"!!%G4e*98!!!!!!!!!!!"R"VBh-a-J!!!""'58a&!3!")NC
+*6%8"!!%M4NP-43%!!54'58a&!3!"*8C*6%8"!!%Q4NP-43%!!5G'58a&!3!"+%C
+*6%8"!!%T4NP-43%!!5T'58a&!3!"+dC*6%8"!!%X4NP-43%!!5e'58a&!3!",NC
+*6%8"!!%[4NP-43%!!CP'58a&!3!"-%G599!!!!!!!!!!!!9`Df0c0`!!!!C'58a
+&!3!"-NC*6%8"!!%c4NP-43%!!6&'58a&!3!"R%C*6%8"!!'D4NP-43%!!CY(8P9
+3!!!!!!!!!!!%FQ&ZC!!!!!4'58a&!3!"0%C*6%8"!!%e4NP-43%!!6C'58a&!3!
+"TdG599!!!!!!!!!!!!0bBc)!!!!&4NP-43%!!6T'58a&!3!"1dC*6%8"!!%j4NP
+-43%!!6G'58a&!3!"1%G599!!!!!!!!!!!!0bBc3!!!!#4NP-43%!!6e'58a&!3!
+"2%G599!!!!!!!!!!!!0bBc8!!!!&4NP-43%!!8*'58a&!3!"3%C*6%8"!!&"4NP
+-43%!!6j'58a&!3!"2dG599!!!!!!!!!!!!CbDA"PE@3!!!!#4NP-43%!!80'58a
+&!3!"4%G599!!!!!!!!!!!!0bFf%!!!!-4NP-43%!!89'58a&!3!"4dC*6%8"!!&
+)4NP-43%!!8e'58a&!3!"6%C*6%8"!!&'4NP-43%!!8Y'58a&!3!"6NC*6%8"!!&
+*4NP-43%!!8T'58a&!3!"R8C*6%8"!!'H4e*98!!!!!!!!!!!!h0SB3!!!!4'58a
+&!3!"88C*6%8"!!&24NP-43%!!9*'58a&!3!"8%G599!!!!!!!!!!!!9cG'&MD`!
+!!!&'58a&!3!"8dG599!!!!!!!!!!!!CdH(4IC')!!!!"4NP-43%!!94(8P93!!!
+!!!!!!!!%H$8`13!!!"9'58a&!3!"A%C*6%8"!!&E4NP-43%!!@&'58a&!3!"@NC
+*6%8"!!&J4NP-43%!!@*'58a&!3!"JdC*6%8"!!&Q4NP-43%!!@0'58a&!3!"@%C
+*6%8"!!&G4NP-43%!!9G'58a&!3!"C8C*6%8"!!&H4NP-43%!!9P'58a&!3!"AdC
+*6%8"!!&R4NP-43%!!@4'58a&!3!"K%C*6%8"!!&94NP-43%!!9C(8P93!!!!!!!
+!!!!'H$8`1ABc!!!!&8C*6%8"!!&V4NP-43%!!@a'58a&!3!"E8C*6%8"!!&a4NP
+-43%!!A0'58a&!3!"G8C*6%8"!!&h4NP-43%!!AT'58a&!3!"D%C*6%8"!!&b4NP
+-43%!!@T'58a&!3!"H%C*6%8"!!&T4NP-43%!!AC'58a&!3!"G%C*6%8"!!&`4NP
+-43%!!AP'58a&!3!"ENC*6%8"!!&[4NP-43%!!B9'58a&!3!"KNG599!!!!!!!!!
+!!!0cFf`!!!!M4NP-43%!!"0'58a&!3!!&8C*6%8"!!!34NP-43%!!"*'58a&!3!
+!%8C*6%8"!!!84NP-43%!!"T'58a&!3!!(%C*6%8"!!!A4NP-43%!!"P'58a&!3!
+!'%C*6%8"!!!E4NP-43%!!"C'58a&!3!!$8C*6%8"!!!24NP-43%!!!Y'58a&!3!
+!$%C*6%8"!!!14NP-43%!!#Y'58a&!3!!,%C*6%8"!!!S4NP-43%!!#T'58a&!3!
+!+8C*6%8"!!!M4NP-43%!!#*'58a&!3!!(dC*6%8"!!!P4NP-43%!!#"'58a&!3!
+!*NC*6%8"!!!N4NP-43%!!"j'58a&!3!!*dC*6%8"!!!G4NP-43%!!!T'58a&!3!
+!)8G599!!!!!!!!!!!!j(990*)%aTBR*KFQPPF`!!!!0'58a&!J!!,dG599!!!!!
+!!!!!!!038%-!!!!$4NP-43)!!$"'58a&!J!!-8C*6%8#!!!b4e*98!!!!!!!!!!
+!!cBiD`!!!!0'58a&"3!!&%C*6%8&!!!94NP-438!!"C(8P93!!!!!!!!!!!138j
+655"-D@*bBA*TCA-!!!!#4e*98!!!!!!!!!!!!e"33`!!!!*'58a&!3!!!8C*6%8
+"!!&r4e*98!!!!!!!!!!!!cBiD`!!!!*'58a&!`!"S%C*6%8$!!'K4e*98!!!!!!
+!!!!!$8eKBb"-D@*bBA*TCA-!!!!#4e*98!!!!!!!!!!!!e"33`!!!!P'58a&!3!
+!"%C*6%8"!!!#4NP-43%!!!0'58a&!3!!#8C*6%8"!!!)4NP-43%!!!G'58a&!3!
+!"NC*6%8"!!!&4NP-43%!!D9(8P93!!!!!!!!!!!$0MKV!!!!"NC*6%8$!!'D4NP
+-43-!!D*'58a&!`!"R%C*6%8$!!'G4NP-43-!!Cp'58a&!`!"Q`!!!"J!!!)!!!)
+!!!!!!J%!"3!!!!!#!J!-!!!!!!)$!!S!!!!!!J3!!J!!!!!#"3!&!!!!!!)'!!)
+!!!!!!JF!"J!!!!!##!!0!!!!!!)*!!8!!!!!!JS!"3!!!!!##`!"!!!!!!)-!!%
+!!!!!!Jd!"`!!!!!#$J!)!!!!!!)2!!8!!!!!!K!!!J!!!!!#%3!#!!!!!!)5!!J
+!!!!!!K-!!3!!!!!#&!!"!!!!!!)9!!J!!!!!!KB!#3!!!!!#&`!%!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!#"J%#!!!c"`%#!!!d!!!!!J3""3!!)!J""3!
+!(`!!!HJ!!!)!!!!6k3!!&!!!!!(S!&j1G!!-6PB!!#m+,`-NEJ!35Ui!!!$*!!!
+!i!!!&0i!!"J!!!!!b3!-,bi!##"U!-JJD!"i6T!!-"mf!!!!!K%!!!)5!!!#%`!
+!!K3!!!)9!!!"p3!!!HJ!!!(H!!!"d3!!!IX!!!(3!!!"p!!!!I`!!!)"!!!"U3!
+!!DS!!!'V!!!!,!!!!#d!!!!Z!!!!,`!!!$!!!!!a!!!!-J!!!$-!!!!d!!!!03!
+!!$B!!!!h!!!!1!!!!$N!!!!k!!!!1`!!!BF!!!!m!!!!23!!!$i!!!!r!!!!3!!
+!!%%!!!',!!!!3J!!!%-!!!"%!!!!43!!!%B!!!"(!!!"kJ!!!Am!!!"p!!!!IJ!
+!!(m!!!'5!!!"N3!!!)!!!!#"!!!!c!!!!B`!!!$0!!!!JJ!!!)-!!!$1!!!!c`!
+!!!N!!!(a!!!!K3!!!)B!!!#(!!!"T3!!!)J!!!#*!!!!LJ!!!)X!!!#-!!!!M3!
+!!)i!!!#2!!!!N!!!!!#4!!!!NJ!!!*-!!!#8!!!!P3!!!*B!!!#A!!!"N`!!!Bi
+!!!'2!!!"M3!!!C!!!!!!K!!!!*J!!!#C!!!#"!!!!93!!!&9!!!"P!!!!BB!!!)
+(!!!##!!!!D`!!!#N!!!!T3!!!+B!!!#R!!!!U!!!!KB!!!'Y!!!!R`!!!+)!!!#
+M!!!"R`!!!AS!!!'Z!!!"V`!!!AX!!!)!!!!"RJ!!!0!!!!#D!!!!Q`!!!*`!!!#
+G!!!!S!!!!*i!!!#K!!!!5!!!!%N!!!"+!!!!5`!!!%`!!!"0!!!!6J!!!%m!!!)
+&!!!#"J!!!+N!!!'`!!!"X3!!!,d!!!#q!!!![`!!!-!!!!$"!!!!d3!!!E)!!!'
+c!!!!`J!!!--!!!$%!!!!a3!!!-B!!!'"!!!!a`!!!-J!!!#U!!!!U`!!!+`!!!'
+d!!!!dJ!!!+d!!!'9!!!!b3!!!D!!!!'e!!!!bJ!!!-X!!!"3!!!!d`!!!03!!!$
+9!!!!eJ!!!0F!!!$B!!!"I!!!!0N!!!$D!!!!f`!!!0`!!!$G!!!!hJ!!!0m!!!$
+J!!!!i3!!!1)!!!$M!!!!j!!!!18!!!$Q!!!!j`!!!1J!!!$T!!!!kJ!!!1X!!!$
+X!!!!l3!!!1i!!!$[!!!!m!!!!2%!!!$b!!!!m`!!!23!!!$e!!!!pJ!!!2F!!!#
+Z!!!!V`!!!J-!!!(D!!!"l3!!!&%!!!"5!!!!8`!!!H`!!!'f!!!"Y`!!!EJ!!!(
+L!!!"i!!!!D%!!!(E!!!"c3!!!F`!!!(F!!!"cJ!!!Gd!!!(2!!!"#3!!!&3!!!"
+9!!!!9J!!!&F!!!"B!!!!@3!!!&S!!!"E!!!!!3!!!3S!!!%,!!!"$!!!!3d!!!%
+1!!!"$`!!!4!!!!(f!!!"k3!!!HF!!!(Q!!!"i`!!!H8!!!(I!!!"rJ!!!Id!!!(
+5!!!"SJ!!!!)!!!(C!!!"%3!!!4)!!!%6!!!"&!!!!48!!!%@!!!"-`!!!Ad!!!'
+M!!!"p`!!!GJ!!!!!!!!"d`!!!!-!!!(A!!!"IJ!!!IJ!!!(V!!!"q3!!!Hi!!!$
+i!!!!q3!!!2S!!!$l!!!!r!!!!2d!!!$q!!!!r`!!!3!!!!%"!!!"Z3!!!&`!!!"
+G!!!"&`!!!4J!!!%C!!!!X!!!!,%!!!#b!!!"j!!!!H%!!!'k!!!"e!!!!!3!!!!
+&!!!"e3!!!GB!!!!'!!!!"`!!!4S!!!%K!!!")J!!!5-!!!%N!!!"*3!!!5B!!!%
+R!!!"+!!!!5N!!!%U!!!"+`!!!5`!!!'B!!!",3!!!5i!!!'@!!!"P`!!!&i!!!"
+I!!!!B!!!!'%!!!"L!!!!B`!!!'3!!!"P!!!!CJ!!!'F!!!"S!!!!D3!!!'S!!!#
+c!!!"qJ!!!I-!!!%E!!!"(!!!!4d!!!%H!!!"(`!!!5!!!!%[!!!"Q3!!!6!!!!%
+a!!!"QJ!!!CX!!!'l!!!"[!!!!6)!!!'p!!!"T!!!!JN!!!)+!!!##`!!!J`!!!)
+0!!!#$J!!!I!!!!)2!!!"!J!!!3-!!!%%!!!""3!!!3B!!!%(!!!"#!!!!,3!!!%
+d!!!"T`!!!DB!!!#e!!!"03!!!6B!!!%h!!!"1!!!!6N!!!%k!!!"1`!!!6`!!!%
+p!!!"2J!!!6m!!!&!!!!"33!!!,B!!!#h!!!"[J!!!Hm!!!)3!!!"3J!!!8-!!!#
+i!!!"[`!!!C`!!!&%!!!"43!!!8B!!!&(!!!"5!!!!Cd!!!&*!!!"5J!!!8X!!!&
+-!!!"63!!!!S!!!!,!!!!$!!!!!d!!!!1!!!!$`!!!"!!!!!4!!!!%J!!!"-!!!!
+8!!!!&3!!!"B!!!!A!!!!'!!!!"N!!!!D!!!!'`!!!F!!!!#j!!!"6J!!!8m!!!&
+3!!!"83!!!F%!!!(r!!!"`J!!!F-!!!!F!!!!(3!!!"i!!!!I!!!!)!!!!#%!!!!
+L!!!!)`!!!#3!!!!P!!!!*J!!!9)!!!#k!!!!Z`!!!F3!!!(&!!!"aJ!!!FF!!!(
+,!!!!*`!!!#J!!!!T!!!!+J!!!#X!!!)#!!!!#!!!!9-!!!'+!!!!D`!!!'`!!!"
+Y!!!"L!!!!'i!!!'*!!!"C`!!!@J!!!&T!!!"DJ!!!@X!!!&X!!!"E3!!!@i!!!&
+[!!!"F!!!!A%!!!&b!!!"K3!!!A-!!!&d!!!"G3!!!AB!!!'%!!!"G`!!!AJ!!!&
+j!!!"b!!!!FN!!!'S!!!"bJ!!!9B!!!&A!!!"JJ!!!9J!!!&C!!!"@J!!!9X!!!&
+F!!!"A3!!!9i!!!&I!!!"B!!!!@%!!!&L!!!"J`!!!@-!!!&N!!!"C3!!!,`!!!(
+b!!!!E`!!!@B!!!"`!!!!F3!!!()!!!"c!!!!G!!!!(8!!!"f!!!!G`!!!(J!!!"
+j!!!!HJ!!!(X!!!"m!!!"J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!"!!!!-P*26e3!!!!!!!!!!!!!!!!'4e*98!!!!!!!!!!"$P*[H5Gc)%G
+PG%K89&"6!!!!"8C*6%8"!!'L4NP-43%!!D0'58a&!3!"U%C*6%8"!!'K4NP-43%
+!!D"(8P93!!!!!!!!!!)66h"PEP066#""F("XD@0KG'P[EJ!!!#0'58a&!J!!(%C
+*6%8#!!!U4NP-43)!!!e'58a&!J!!)%C*6%8#!!!54NP-43)!!"0'58a&!J!!&NC
+*6%8#!!!B4NP-43)!!"G'58a&!J!!$NC*6%8#!!!H4NP-43)!!"&'58a&!J!!%%C
+*6%8#!!!K4NP-43)!!"4'58a&!J!!&8C*6%8#!!!X4NP-43)!!"T'58a&!J!!'8C
+*6%8#!!!S4NP-43)!!#G'58a&!J!!*%C*6%8#!!!Y4NP-43)!!!Y'58a&!J!!*NC
+*6%8#!!!T4NP-43)!!!a'58a&!J!!+dC*6%8#!!!L4NP-43)!!!p'58a&!J!!'dC
+*6%8#!!!G4NP-43)!!"p'58a&!J!!*8C*6%8#!!!M4e*98!!!!!!!!!!$%8p`C@j
+68d`J6'PLFQ&bD@9c!!!!"%G599!!!!!!!!!!"!038%-!!!!#4NP-43)!!$0'58a
+&!J!!0%G599!!!!!!!!!!"3-f1'X!!!!#4NP-438!!#"'58a&"3!!(dG599!!!!!
+!!!!!"JCMFRP`G'm!!!!S4NP-43%!!Aa'58a&!3!"INC*6%8"!!'N4NP-43%!!Cp
+'58a&!3!"I8C*6%8"!!&l4e*98!!!!!!!!!!("'&cEM%!!!"A4NP-43%!!$j'58a
+&!3!!-8C*6%8"!!"&4NP-43%!!$P'58a&!3!!3dC*6%8"!!!m4NP-43%!!$p'58a
+&!3!!3%C*6%8"!!"%4NP-43%!!%&'58a&!3!!0dC*6%8"!!!e4NP-43%!!$Y'58a
+&!3!!-NC*6%8"!!!i4NP-43%!!%K'58a&!3!!4NC*6%8"!!"#4NP-43%!!$C'58a
+&!3!!4dC*6%8"!!')4NP-43%!!("'58a&!3!!I%C*6%8"!!"i4NP-43%!!(T'58a
+&!3!!H8C*6%8"!!"a4NP-43%!!(C'58a&!3!!FNC*6%8"!!"p4NP-43%!!B&'58a
+&!3!!FdC*6%8"!!"e4NP-43%!!(Y'58a&!3!!A8C*6%8"!!"04NP-43%!!&P'58a
+&!3!!6NC*6%8"!!"D4NP-43%!!%p'58a&!3!!@dC*6%8"!!"34NP-43%!!&a'58a
+&!3!!5dC*6%8"!!"A4NP-43%!!%a'58a&!3!!@%C*6%8"!!"Z4NP-43%!!'p'58a
+&!3!"LNC*6%8"!!"X4NP-43%!!'e'58a&!3!"L8C*6%8"!!',4NP-43%!!'9'58a
+&!3!!D8C*6%8"!!"S4NP-43%!!'G'58a&!3!!BdC*6%8"!!"N4NP-43%!!'&'58a
+&!3!!DNC*6%8"!!"L4NP-43%!!'C'58a&!3!!8dC*6%8"!!"84NP-43%!!&9'58a
+&!3!!9NC*6%8"!!"*4NP-43%!!%T'58a&!3!!ANC*6%8"!!"54NP-43%!!$T'58a
+&!3!!GdC*6%8"!!!c4NP-43%!!(4'58a&!3!!,dC*6%8"!!!Z4NP-43%!!#e'58a
+&!3!!28C*6%8"!!!d4NP-43%!!Ba'58a&!3!!88C*6%8"!!!`4NP-43%!!&p'58a
+&!3!!B%C*6%8"!!"V4e*98!!!!!!!!!!)!Q*Q!!!!"8C*6%8"!!##4NP-43%!!(p
+'58a&!3!!J%C*6%8"!!"q4NP-43%!!)&(8P93!!!!!!!!!!N$BQP[!!!!$NC*6%8
+"!!#%4NP-43%!!Be'58a&!3!!JdC*6%8"!!'14NP-43%!!C&'58a&!3!"MdC*6%8
+"!!'3!%C*6%8"!!#&4NP-43%!!C*'58a&!3!"J%C*6%8"!!'(4NP-43%!!C9'58a
+&!3!"NdC*6%8"!!'84e*98!!!!!!!!!!+!Q*Z!!!!&%C*6%8"!!#'4NP-43%!!)P
+'58a&!3!!LdC*6%8"!!#14NP-43%!!DC'58a&!3!!N8C*6%8"!!#64NP-43%!!*4
+'58a&!3!!PNC*6%8"!!#B4NP-43%!!)K'58a&!3!!M8C*6%8"!!#54NP-43%!!)T
+'58a&!3!!PdC*6%8"!!#(4NP-43%!!*9'58a&!3!!MdC*6%8"!!#3!%C*6%8"!!#
+-4e*98!!!!!!!!!!,"Q*eCQCPFJ!!!!*'58a&!3!!Q8C*6%8"!!#D4e*98!!!!!!
+!!!!-"'0KFh3!!!!&4NP-43%!!*p'58a&!3!!R%C*6%8"!!#G4NP-43%!!*Y'58a
+&!3!!RNG599!!!!!!!!!!$34MEfe`!!!!!dC*6%8"!!#J4NP-43%!!+&'58a&!3!
+!SNG599!!!!!!!!!!$J4MEfjQ!!!!!NC*6%8"!!#M4NP-43%!!+4(8P93!!!!!!!
+!!!m$C'9c!!!!'NC*6%8"!!#P4NP-43%!!+C'58a&!3!!U%C*6%8"!!#T4NP-43%
+!!+Y'58a&!3!!V%C*6%8"!!#Z4NP-43%!!CC'58a&!3!!VdC*6%8"!!#b4NP-43%
+!!,0'58a&!3!!Y%C*6%8"!!#e4NP-43%!!,C'58a&!3!!Z%C*6%8"!!#j4NP-43%
+!!,T'58a&!3!!UNC*6%8"!!#`4NP-43%!!,G'58a&!3!![8C*6%8"!!#l4NP-43%
+!!+G'58a&!3!!X8C*6%8"!!#m4NP-43%!!+e(8P93!!!!!!!!!"!#C'J!!!!&4NP
+-43%!!-"'58a&!3!!`8C*6%8"!!$#4NP-43%!!,j'58a&!3!![dG599!!!!!!!!!
+!%30NFf%!!!!)4NP-43%!!-9'58a&!3!!aNC*6%8"!!$(4NP-43%!!-0'58a&!3!
+!b8C*6%8"!!$)4NP-43%!!-4'58a&!3!"JNG599!!!!!!!!!!%J0PFR)!!!!$4NP
+-43%!!-T'58a&!3!!bdC*6%8"!!$-4e*98!!!!!!!!!!6!f9fF!!!!$p'58a&!3!
+!ddC*6%8"!!$54NP-43%!!04'58a&!3!!eNC*6%8"!!$V4NP-43%!!0e'58a&!3!
+!j%C*6%8"!!$c4NP-43%!!1a'58a&!3!!hNC*6%8"!!$P4NP-43%!!24'58a&!3!
+!k%C*6%8"!!$D4NP-43%!!2G'58a&!3!"!NC*6%8"!!$K4NP-43%!!2"'58a&!3!
+!q%C*6%8"!!$Y4NP-43%!!0p'58a&!3!!jNC*6%8"!!$e4NP-43%!!1P'58a&!3!
+!fdC*6%8"!!$L4NP-43%!!2&'58a&!3!!kNC*6%8"!!$F4NP-43%!!10'58a&!3!
+!mNC*6%8"!!$Z4NP-43%!!1"'58a&!3!!jdC*6%8"!!$f4NP-43%!!2j'58a&!3!
+!qdC*6%8"!!$m4NP-43%!!3"'58a&!3!"!8C*6%8"!!$j4NP-43%!!2T'58a&!3!
+!r8C*6%8"!!$r4NP-43%!!3C'58a&!3!""dC*6%8"!!%)4NP-43%!!3P'58a&!3!
+""8C*6%8"!!%%4NP-43%!!30'58a&!3!!cdC*6%8"!!$04NP-43%!!-j'58a&!3!
+!e8C*6%8"!!$[4NP-43%!!0&'58a&!3!!edC*6%8"!!$34NP-43%!!0P'58a&!3!
+!f%C*6%8"!!'A4NP-43%!!CK(8P93!!!!!!!!!"3%D'eKB`!!!!&'58a&!3!"#NG
+599!!!!!!!!!!&34TC'9K!!!!"8C*6%8"!!%,4NP-43%!!3a'58a&!3!"$NC*6%8
+"!!%04NP-43%!!3p(8P93!!!!!!!!!"B&E'KKFfJ!!!!#4NP-43%!!4"'58a&!3!
+"%8G599!!!!!!!!!!&`0YC$)!!!!#4NP-43%!!4*'58a&!3!"%dG599!!!!!!!!!
+!'!0YC$8!!!!#4NP-43%!!44'58a&!3!"&8G599!!!!!!!!!!'34YC'-b!!!!!NC
+*6%8"!!%@4NP-43%!!4G(8P93!!!!!!!!!"S(Ef*UC@0dF`!!!!4'58a&!3!"'dC
+*6%8"!!%B4NP-43%!!4T'58a&!3!"'8G599!!!!!!!!!!'`0`C@d!!!!'4NP-43%
+!!5&'58a&!3!")%C*6%8"!!%H4NP-43%!!4p'58a&!3!"(%C*6%8"!!%G4e*98!!
+!!!!!!!!F"R"VBh-a-J!!!""'58a&!3!")NC*6%8"!!%M4NP-43%!!54'58a&!3!
+"*8C*6%8"!!%Q4NP-43%!!5G'58a&!3!"+%C*6%8"!!%T4NP-43%!!5T'58a&!3!
+"+dC*6%8"!!%X4NP-43%!!5e'58a&!3!",NC*6%8"!!%[4NP-43%!!CP'58a&!3!
+"-%G599!!!!!!!!!!(39`Df0c0`!!!!C'58a&!3!"-NC*6%8"!!%c4NP-43%!!6&
+'58a&!3!"R%C*6%8"!!'D4NP-43%!!CY(8P93!!!!!!!!!"i%FQ&ZC!!!!!4'58a
+&!3!"0%C*6%8"!!%e4NP-43%!!6C'58a&!3!"TdG599!!!!!!!!!!(`0bBc)!!!!
+&4NP-43%!!6T'58a&!3!"1dC*6%8"!!%j4NP-43%!!6G'58a&!3!"1%G599!!!!!
+!!!!!)!0bBc3!!!!#4NP-43%!!6e'58a&!3!"2%G599!!!!!!!!!!)30bBc8!!!!
+&4NP-43%!!8*'58a&!3!"3%C*6%8"!!&"4NP-43%!!6j'58a&!3!"2dG599!!!!!
+!!!!!)JCbDA"PE@3!!!!#4NP-43%!!80'58a&!3!"4%G599!!!!!!!!!!)`0bFf%
+!!!!-4NP-43%!!89'58a&!3!"4dC*6%8"!!&)4NP-43%!!8e'58a&!3!"6%C*6%8
+"!!&'4NP-43%!!8Y'58a&!3!"6NC*6%8"!!&*4NP-43%!!8T'58a&!3!"R8C*6%8
+"!!'H4e*98!!!!!!!!!!N!h0SB3!!!!4'58a&!3!"88C*6%8"!!&24NP-43%!!9*
+'58a&!3!"8%G599!!!!!!!!!!*39cG'&MD`!!!!&'58a&!3!"8dG599!!!!!!!!!
+!*JCdH(4IC')!!!!"4NP-43%!!94(8P93!!!!!!!!!#F%H$8`13!!!"9'58a&!3!
+"A%C*6%8"!!&E4NP-43%!!@&'58a&!3!"@NC*6%8"!!&J4NP-43%!!@*'58a&!3!
+"JdC*6%8"!!&Q4NP-43%!!@0'58a&!3!"@%C*6%8"!!&G4NP-43%!!9G'58a&!3!
+"C8C*6%8"!!&H4NP-43%!!9P'58a&!3!"AdC*6%8"!!&R4NP-43%!!@4'58a&!3!
+"K%C*6%8"!!&94NP-43%!!9C(8P93!!!!!!!!!#J'H$8`1ABc!!!!&8C*6%8"!!&
+V4NP-43%!!@a'58a&!3!"E8C*6%8"!!&a4NP-43%!!A0'58a&!3!"G8C*6%8"!!&
+h4NP-43%!!AT'58a&!3!"D%C*6%8"!!&b4NP-43%!!@T'58a&!3!"H%C*6%8"!!&
+T4NP-43%!!AC'58a&!3!"G%C*6%8"!!&`4NP-43%!!AP'58a&!3!"ENC*6%8"!!&
+[4NP-43%!!B9'58a&!3!"KNG599!!!!!!!!!!+30cFf`!!!!M4NP-43%!!"0'58a
+&!3!!&8C*6%8"!!!34NP-43%!!"*'58a&!3!!%8C*6%8"!!!84NP-43%!!"T'58a
+&!3!!(%C*6%8"!!!A4NP-43%!!"P'58a&!3!!'%C*6%8"!!!E4NP-43%!!"C'58a
+&!3!!$8C*6%8"!!!24NP-43%!!!Y'58a&!3!!$%C*6%8"!!!14NP-43%!!#Y'58a
+&!3!!,%C*6%8"!!!S4NP-43%!!#T'58a&!3!!+8C*6%8"!!!M4NP-43%!!#*'58a
+&!3!!(dC*6%8"!!!P4NP-43%!!#"'58a&!3!!*NC*6%8"!!!N4NP-43%!!"j'58a
+&!3!!*dC*6%8"!!!G4NP-43%!!!T'58a&!3!!)8G599!!!!!!!!!!+Jj(990*)%a
+TBR*KFQPPF`!!!!0'58a&!J!!,dG599!!!!!!!!!!+`038%-!!!!$4NP-43)!!$"
+'58a&!J!!-8C*6%8#!!!b4e*98!!!!!!!!!!X!cBiD`!!!!0'58a&"3!!&%C*6%8
+&!!!94NP-438!!"C(8P93!!!!!!!!!#d138j655"-D@*bBA*TCA-!!!!#4e*98!!
+!!!!!!!!Z!e"33`!!!!*'58a&!3!!!8C*6%8"!!&r4e*98!!!!!!!!!![!cBiD`!
+!!!*'58a&!`!"S%C*6%8$!!'K4e*98!!!!!!!!!!`$8eKBb"-D@*bBA*TCA-!!!!
+#4e*98!!!!!!!!!!a!e"33`!!!!P'58a&!3!!"%C*6%8"!!!#4NP-43%!!!0'58a
+&!3!!#8C*6%8"!!!)4NP-43%!!!G'58a&!3!!"NC*6%8"!!!&4NP-43%!!D9(8P9
+3!!!!!!!!!$)$0MKV!!!!"NC*6%8$!!'D4NP-43-!!D*'58a&!`!"R%C*6%8$!!'
+G4NP-43-!!Cp'58a&!`!"Q`!!!4#V3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!"+!!!'!"YFh4b!!!!!!!!!!!!!!!!!!!C+!!!#S"YFh4X!!!!!!!
+!!!!!!!!!!!!MU!!!!i"YFh4Z!!!!!!!!!!!!!!!!!!!R+!!!'!"YFh4b!!!$k!!
+!!!!!!!!!!!!r+!!!'B"YFh4X!!!$k!!!!!!!!!!!!!0TDJ!!#)"YFh4Z!!!$k!!
+!!!!!!!!!!!"E+!!!"4"`FQ9Q!!P'eJ!!!!%!!!!!!!"J1!!!!!K`FQ9Q!!L`,3!
+!!!)!!!!!!!"J3!!!!"T`FQ9Q!!PX2!!!!!-!!!!!!!"J@J!!$+"`FQ9Q!!MrS3!
+!!!3!!!!!!!"XqJ!!"K4`FQ9Q!!L+i3!!!!8!!!!!!!"c$J!!#*C`FQ9Q!!P5m!!
+!!!B!!!!!!!"lT!!!!3G`FQ9Q!!Le63!!!!F!!!!!!!"mU`!!!b"`FQ9Q!!N!,`!
+!!!J!!!!!!!"rb`!!!"4`FQ9Q!!NR4!!!!!N!!!!!!!"rh`!!!!T`FQ9Q!!M`UJ!
+!!!S!!!!!!!"rk3!!!!a`FQ9Q!!L"hJ!!!!X!!!!!!!"rp3!!!!j`FQ9Q!!M0!!!
+!!!`!!!!!!!#!!`!!!3C`FQ9Q!!Kpf3!!!!d!!!!!!!#"#3!!!$j`FQ9Q!!N#K!!
+!!!i!!!!!!!#"4`!!!!j`FQ9Q!!PRC3!!!!m!!!!!!!#"93!!!GT`FQ9Q!!MG@`!
+!!"!!!!!!!!#$,`!!!'*`FQ9Q!!M*!3!!!"%!!!!!!!#$N3!!!"4`FQ9Q!!MP"`!
+!!")!!!!!!!#$T3!!!!T`FQ9Q!!LpV!!!!"-!!!!!!!#$V`!!!!a`FQ9Q!!PJK`!
+!!"3!!!!!!!#$Z`!!!-T`FQ9Q!!L(e!!!!"8!!!!!!!#%K3!!!4K`FQ9Q!!LAh3!
+!!"B!!!!!!!#&R3!!!+K`FQ9Q!!LpP!!!!"F!!!!!!!#'43!!!#j`FQ9Q!!PBJJ!
+!!"J!!!!!!!#'F`!!!Ja`FQ9Q!!N()3!!!"N!!!!!!!#)I`!!4J"YG("X!!!!!3!
+!!!!!!!!!!!$1I`!!"`"YG("c!!!!!3!!!!!!!!!!!!$9I`!!!""YG("T!!!!!3!
+!!!!!!!!!!!$9M`!!"U"YG'a[!!!!!3!!!!!!!!!!!!$F,`!!!#"YG(0X!!!!!3!
+!!!!!!!!!!!$F6`!!"4"`FQ9Q!!NN23!!!"S!!!!!!!$KA`!!!!K`FQ9Q!!M6`J!
+!!"X!!!!!!!$KC`!!!"T`FQ9Q!!KkI3!!!"`!!!!!!!$KJ3!!%0"`FQ9Q!!LKD`!
+!!"d!!!!!!!$b83!!"K4`FQ9Q!!PS2J!!!"i!!!!!!!$iC3!!#*C`FQ9Q!!M14`!
+!!"m!!!!!!!%!q`!!!3G`FQ9Q!!P,IJ!!!#!!!!!!!!%#!J!!!b"`FQ9Q!!Mle3!
+!!#%!!!!!!!%&)J!!!"4`FQ9Q!!NP93!!!#)!!!!!!!%&0J!!!!T`FQ9Q!!LIJJ!
+!!#-!!!!!!!%&3!!!!!a`FQ9Q!!L8Z!!!!#3!!!!!!!%&6!!!!!j`FQ9Q!!P54!!
+!!#8!!!!!!!%&@J!!!3C`FQ9Q!!P'2`!!!#B!!!!!!!%'B!!!!$j`FQ9Q!!N63!!
+!!#F!!!!!!!%'RJ!!!!j`FQ9Q!!MZ(3!!!#J!!!!!!!%'V!!!!GT`FQ9Q!!Lmf!!
+!!#N!!!!!!!%)KJ!!!'*`FQ9Q!!LrK!!!!#S!!!!!!!%)k!!!!"4`FQ9Q!!NchJ!
+!!#X!!!!!!!%)r!!!!!T`FQ9Q!!M,S!!!!#`!!!!!!!%*"J!!!!a`FQ9Q!!N%'3!
+!!#d!!!!!!!%*%J!!!-T`FQ9Q!!NJ2!!!!#i!!!!!!!%*h!!!!4K`FQ9Q!!PIl3!
+!!#m!!!!!!!%+p!!!!+K`FQ9Q!!Lq%J!!!$!!!!!!!!%,R!!!!#j`FQ9Q!!LM0`!
+!!$%!!!!!!!%,bJ!!!Ja`FQ9Q!!NG#`!!!$)!!!!!!!%0eJ!!#J"YG("X!!!!!J!
+!!!!!!!!!!!%AeJ!!!3"YG("c!!!!!J!!!!!!!!!!!!%BeJ!!!""YG("T!!!!!J!
+!!!!!!!!!!!%BjJ!!!0"YG'a[!!!!!J!!!!!!!!!!!!%CYJ!!!#"YG(0X!!!!!J!
+!!!!!!!!!!!%CeJ!!"4"`FQ9Q!!PDj!!!!$-!!!!!!!%HjJ!!!!K`FQ9Q!!NN$!!
+!!$3!!!!!!!%HlJ!!!"T`FQ9Q!!MT*`!!!$8!!!!!!!%I#!!!$+"`FQ9Q!!P`ZJ!
+!!$B!!!!!!!%VU!!!"K4`FQ9Q!!N$-3!!!$F!!!!!!!%a[!!!#5C`FQ9Q!!L9f`!
+!!$J!!!!!!!%kiJ!!!3G`FQ9Q!!LI%`!!!$N!!!!!!!%lk3!!!b"`FQ9Q!!Lj$!!
+!!$S!!!!!!!%r#3!!!"4`FQ9Q!!MhR`!!!$X!!!!!!!%r(3!!!!T`FQ9Q!!M-hJ!
+!!$`!!!!!!!%r*`!!!!a`FQ9Q!!N&m!!!!$d!!!!!!!%r-`!!!!j`FQ9Q!!P[``!
+!!$i!!!!!!!%r33!!!3C`FQ9Q!!MmQ!!!!$m!!!!!!!&!4`!!!$j`FQ9Q!!MK!J!
+!!%!!!!!!!!&!K3!!!!j`FQ9Q!!LfY`!!!%%!!!!!!!&!N`!!!GT`FQ9Q!!MPM!!
+!!%)!!!!!!!&#E3!!!'*`FQ9Q!!PS+!!!!%-!!!!!!!&#c`!!!"4`FQ9Q!!MH03!
+!!%3!!!!!!!&#i`!!!!T`FQ9Q!!PH+3!!!%8!!!!!!!&#l3!!!!a`FQ9Q!!L*a3!
+!!%B!!!!!!!&#q3!!!-T`FQ9Q!!L*,!!!!%F!!!!!!!&$``!!!4K`FQ9Q!!MZ"!!
+!!%J!!!!!!!&%f`!!!+K`FQ9Q!!L@Q`!!!%N!!!!!!!&&J`!!!#j`FQ9Q!!M8&3!
+!!%S!!!!!!!&&X3!!!Ja`FQ9Q!!Lj"J!!!%X!!!!!!!&([3!!4J"YG("X!!!!!`!
+!!!!!!!!!!!'0[3!!"`"YG("c!!!!!`!!!!!!!!!!!!'8[3!!!""YG("T!!!!!`!
+!!!!!!!!!!!'8c3!!!#"YG(0X!!!!!`!!!!!!!!!!!!'8l3!!"T4YG'a[!!!!!`!
+!!!!!!!!!!!'EJ3!!"4"`FQ9Q!!N*[!!!!%`!!!!!!!'JN3!!!!K`FQ9Q!!Kq93!
+!!%d!!!!!!!'JQ3!!!"T`FQ9Q!!M+H`!!!%i!!!!!!!'JX`!!%0"`FQ9Q!!N6p!!
+!!%m!!!!!!!'aJ`!!"K4`FQ9Q!!M$+3!!!&!!!!!!!!'hP`!!#5C`FQ9Q!!L!9`!
+!!&%!!!!!!!(![3!!!3G`FQ9Q!!N`BJ!!!&)!!!!!!!("a!!!!b"`FQ9Q!!M3)3!
+!!&-!!!!!!!(%j!!!!"4`FQ9Q!!L4H3!!!&3!!!!!!!(%q!!!!!T`FQ9Q!!NR0J!
+!!&8!!!!!!!(&!J!!!!a`FQ9Q!!L'$3!!!&B!!!!!!!(&$J!!!!j`FQ9Q!!MR53!
+!!&F!!!!!!!(&(!!!!3C`FQ9Q!!PEH!!!!&J!!!!!!!(')J!!!$j`FQ9Q!!MfA3!
+!!&N!!!!!!!('B!!!!!j`FQ9Q!!N&53!!!&S!!!!!!!('EJ!!!GT`FQ9Q!!LB-`!
+!!&X!!!!!!!()5!!!!'*`FQ9Q!!L6[3!!!&`!!!!!!!()UJ!!!"4`FQ9Q!!LeT`!
+!!&d!!!!!!!()[J!!!!T`FQ9Q!!N,D`!!!&i!!!!!!!()b!!!!!a`FQ9Q!!LcY`!
+!!&m!!!!!!!()e!!!!-T`FQ9Q!!LFj`!!!'!!!!!!!!(*RJ!!!4K`FQ9Q!!N!V3!
+!!'%!!!!!!!(+YJ!!!+K`FQ9Q!!N(2!!!!')!!!!!!!(,AJ!!!#j`FQ9Q!!LQY!!
+!!'-!!!!!!!(,M!!!!Ja`FQ9Q!!M053!!!'3!!!!!!!(0Q!!!#J"YG("X!!!!"!!
+!!!!!!!!!!!(AQ!!!!3"YG("c!!!!"!!!!!!!!!!!!!(BQ!!!!""YG("T!!!!"!!
+!!!!!!!!!!!(BU!!!!#"YG(0X!!!!"!!!!!!!!!!!!!(Bb!!!!)aYG'a[!!!!"!!
+!!!!!!!!!!!(C9!!!"4"`FQ9Q!!MM#`!!!'8!!!!!!!(HC!!!!!K`FQ9Q!!M"$!!
+!!'B!!!!!!!(HE!!!!"T`FQ9Q!!MYHJ!!!'F!!!!!!!(HKJ!!%0"`FQ9Q!!MKm`!
+!!'J!!!!!!!([9J!!"K4`FQ9Q!!Nre3!!!'N!!!!!!!(eDJ!!#5C`FQ9Q!!LZ3J!
+!!'S!!!!!!!(qN!!!!!%(F(*PCJ!)KRi!!!"V!!!!!!!"rjF!!!-JF(*PCJ!)PD8
+!!!"X!!!!!!!#!VF!!!!8F(*PCJ!*0m)!!!"Y!!!!!!!#!XX!!!!+F(*PCJ!*AZd
+!!!"Z!!!!!!!#!Y8!!!!-F(*PCJ!)Vii!!!"[!!!!!!!#!Z%!!!!1F(*PCJ!*,[d
+!!!"`!!!!!!!#!Zm!!!%'F(*PCJ!*'EB!!!"a!!!!!!!#!r8!!!!qF(*PCJ!*0P8
+!!!"b!!!!!!!#"$-!!!!1F(*PCJ!*-D%!!!"c!!!!!!!#"%%!!!(DF(*PCJ!*0"i
+!!!"d!!!!!!!#"KX!!!"LF(*PCJ!)GH!!!!"e!!!!!!!#"Rd!!!!8F(*PCJ!)Q)S
+!!!"f!!!!!!!#"T%!!!!+F(*PCJ!*!Pd!!!"h!!!!!!!#"TX!!!!-F(*PCJ!)PR-
+!!!"i!!!!!!!#"UF!!!$+F(*PCJ!)TC!!!!!!H3!!!!!!!JGa!!!"'("bC@B!#-A
+9!!!!HJ!!!!!!!JL*!!!!U("bC@B!#86U!!!!H`!!!!!!!JNa!!!!,R"bC@B!#@@
+8!!!!I!!!!!!!!JPI!!!#$("bC@B!#(ep!!!!I3!!!!!!!JYV!!!&!'edF'`!!!!
+&!!!!!!!!!!!!!K"V!!!!J'edF(-!!!!&!!!!!!!!!!!!!K$V!!!!%'edF'N!!!!
+&!!!!!!!!!!!!!K$l!!!!)'edFf`!!!!&!!!!!!!!!!!!!K%E!!!!J'edE'm!!!!
+&!!!!!!!!!!!!!K'E!!!&%("bC@B!#8UQ!!!!IJ!!!!!!!KDV!!!!#("bC@B!#22
+(!!!!I`!!!!!!!KDc!!!!'R"bC@B!#3#p!!!!J!!!!!!!!KE0!!!3d("bC@B!#2`
+[!!!!J3!!!!!!!LHG!!!'&("bC@B!#1[4!!!!JJ!!!!!!!Lfa!!!)PR"bC@B!#(,
+9!!!!J`!!!!!!!MC(!!!""h"bC@B!#@rk!!!!K!!!!!!!!MG1!!!$)("bC@B!#1G
+'!!!!K3!!!!!!!MTZ!!!!&("bC@B!#128!!!!KJ!!!!!!!MU#!!!!#R"bC@B!#,1
+q!!!!K`!!!!!!!MU-!!!!$("bC@B!#)c'!!!!L!!!!!!!!MUB!!!!$R"bC@B!#4S
+,!!!!L3!!!!!!!MUQ!!!""R"bC@B!#-iX!!!!LJ!!!!!!!MZX!!!!2R"bC@B!#(C
+#!!!!L`!!!!!!!M[U!!!!$R"bC@B!#@+F!!!!M!!!!!!!!M[i!!!"fR"bC@B!#8(
+h!!!!M3!!!!!!!Mh5!!!!BR"bC@B!#2!L!!!!MJ!!!!!!!Mid!!!!&("bC@B!#(d
+@!!!!M`!!!!!!!Mj)!!!!#R"bC@B!#2iC!!!!N!!!!!!!!!)q8J!!!!a`FQ9Q!!M
+YZ!!!!*%!!!!!!!)qAJ!!!-T`FQ9Q!!Pb83!!!*)!!!!!!!)r+!!!!4K`FQ9Q!!L
+a"3!!!*-!!!!!!!*!3!!!!+K`FQ9Q!!NZf`!!!*3!!!!!!!*!k!!!!#j`FQ9Q!!K
+j[`!!!*8!!!!!!!*"&J!!!Ja`FQ9Q!!Mi,3!!!*B!!!!!!!*$)J!!#J"YG("X!!!
+!"J!!!!!!!!!!!!*0)J!!!3"YG("c!!!!"J!!!!!!!!!!!!*1)J!!!""YG("T!!!
+!"J!!!!!!!!!!!!*1-J!!!)aYG'a[!!!!"J!!!!!!!!!!!!*1[J!!!#"YG(0X!!!
+!"J!!!!!!!!!!!!*1hJ!!"4"`FQ9Q!!Kf)J!!!*F!!!!!!!*6lJ!!!!K`FQ9Q!!N
+bh`!!!*J!!!!!!!*6pJ!!!"T`FQ9Q!!MZB3!!!*N!!!!!!!*8%!!!%0"`FQ9Q!!M
+[m`!!!*S!!!!!!!*Ni!!!"K4`FQ9Q!!NVZ`!!!*X!!!!!!!*Up!!!#*C`FQ9Q!!M
+b!J!!!*`!!!!!!!*cLJ!!!3G`FQ9Q!!P083!!!*d!!!!!!!*dN3!!!b"`FQ9Q!!M
+a13!!!*i!!!!!!!*hX3!!!"4`FQ9Q!!P9h3!!!*m!!!!!!!*ha3!!!!T`FQ9Q!!M
++,3!!!+!!!!!!!!*hc`!!!!a`FQ9Q!!L6T`!!!+%!!!!!!!*hf`!!!!j`FQ9Q!!M
+jB3!!!+)!!!!!!!*hk3!!!3C`FQ9Q!!L0Z`!!!+-!!!!!!!*il`!!!$j`FQ9Q!!M
+P3J!!!+3!!!!!!!*j,3!!!!j`FQ9Q!!N6hJ!!!+8!!!!!!!*j1`!!!GT`FQ9Q!!N
+kJ`!!!+B!!!!!!!*l&3!!!'*`FQ9Q!!N&H!!!!+F!!!!!!!*lG`!!!"4`FQ9Q!!L
+,iJ!!!+J!!!!!!!*lL`!!!!T`FQ9Q!!MDI3!!!+N!!!!!!!*lP3!!!!a`FQ9Q!!K
+l33!!!+S!!!!!!!*lS3!!!-T`FQ9Q!!MlG3!!!+X!!!!!!!*mD`!!!4K`FQ9Q!!L
+e&!!!!+`!!!!!!!*pJ`!!!+K`FQ9Q!!MK1`!!!+d!!!!!!!*q+`!!!#j`FQ9Q!!L
+Y#!!!!+i!!!!!!!*q@3!!!Ja`FQ9Q!!L42`!!!+m!!!!!!!+!C3!!2!"YG("X!!!
+!"`!!!!!!!!!!!!+mC3!!"J"YG("c!!!!"`!!!!!!!!!!!!,#C3!!!""YG("T!!!
+!"`!!!!!!!!!!!!,#G3!!"G4YG'a[!!!!"`!!!!!!!!!!!!,)53!!!#"YG(0X!!!
+!"`!!!!!!!!!!!!,)D3!!"4"`FQ9Q!!NXL3!!!,!!!!!!!!,0H3!!!!K`FQ9Q!!P
+%U3!!!,%!!!!!!!,0J3!!!"T`FQ9Q!!LT(!!!!,)!!!!!!!,0Q`!!%0"`FQ9Q!!N
+(M3!!!,-!!!!!!!,HD`!!"K4`FQ9Q!!PH[`!!!,3!!!!!!!,NI`!!#5C`FQ9Q!!M
+Hh!!!!,8!!!!!!!,YT3!!!3G`FQ9Q!!M`h!!!!,B!!!!!!!,ZV!!!!b"`FQ9Q!!L
+N03!!!,F!!!!!!!,ac!!!!"4`FQ9Q!!Mb6J!!!,J!!!!!!!,ai!!!!!T`FQ9Q!!N
+a@!!!!,N!!!!!!!,akJ!!!!a`FQ9Q!!LH1J!!!,S!!!!!!!,apJ!!!!j`FQ9Q!!N
+"f3!!!,X!!!!!!!,b"!!!!3C`FQ9Q!!P`p!!!!,`!!!!!!!,c#J!!!$j`FQ9Q!!P
+Qf!!!!,d!!!!!!!,c5!!!!!j`FQ9Q!!PYDJ!!!,i!!!!!!!,c9J!!!GT`FQ9Q!!N
+#-!!!!,m!!!!!!!,e-!!!!'*`FQ9Q!!ME@!!!!-!!!!!!!!,eNJ!!!"4`FQ9Q!!L
+j4`!!!-%!!!!!!!,eTJ!!!!T`FQ9Q!!Mf$3!!!-)!!!!!!!,eX!!!!!a`FQ9Q!!M
+eDJ!!!--!!!!!!!,e[!!!!-T`FQ9Q!!MfF3!!!-3!!!!!!!,fKJ!!!4K`FQ9Q!!N
+`R`!!!-8!!!!!!!,hRJ!!!+K`FQ9Q!!LqH3!!!-B!!!!!!!,i4J!!!#j`FQ9Q!!L
+3!*S!!!$(!!!!!!!#q(3!!!)-F(*PCJ!)d'B!!!$)!!!!!!!#qS!!!$`!EA4`E!!
+!!!J!!!!!!!!!!!!$0S!!!!B!EA4`F`!!!!J!!!!!!!!!!!!$2)!!!!!3EA4`D3!
+!!!J!!!!!!!!!!!!$2*!!!!!!)'edFf`!!!!)!!!!!!!!!!!!!cb`!!!&e'edE'm
+!!!!)!!!!!!!!!!!!!d+%!!!3a'edCf`!!!2S!!!!!!!!!!!!!e0)!!!!,'e[G'N
+!!!!!!!!!!!!!!!!!!h(U!!!6J&"-Fh3!#,"V!!!!b3!!!!!!!&LS!!!#,'e`FfN
+!!!2S!!!!!!!!!!!!!fMk!!!!%'ecG(!!!!!#!!!!!!!!!!!!!fN+!!!!%'ecG(!
+!!!!&!!!!!!!!!!!!!&V8!!!!+'ecG'N!!!2S!!!!!!!!!!!!!fP#!!!!+'ecG'N
+!!!!!!!!!!!!!!!!!!&Vm!!!!$'eKE'`!!!!!!!!!!!!!!!!!!fE1!!!!a'eKF'`
+!!!!!!!!!!!!!!!$B03!!:
diff --git a/openssl/MacOS/Randomizer.cpp b/openssl/MacOS/Randomizer.cpp
new file mode 100644
index 0000000..cceb6bd
--- /dev/null
+++ b/openssl/MacOS/Randomizer.cpp
@@ -0,0 +1,476 @@
+/* 
+------- Strong random data generation on a Macintosh (pre - OS X) ------
+		
+--	GENERAL: We aim to generate unpredictable bits without explicit
+	user interaction. A general review of the problem may be found
+	in RFC 1750, "Randomness Recommendations for Security", and some
+	more discussion, of general and Mac-specific issues has appeared
+	in "Using and Creating Cryptographic- Quality Random Numbers" by
+	Jon Callas (www.merrymeet.com/jon/usingrandom.html).
+
+	The data and entropy estimates provided below are based on my
+	limited experimentation and estimates, rather than by any
+	rigorous study, and the entropy estimates tend to be optimistic.
+	They should not be considered absolute.
+
+	Some of the information being collected may be correlated in
+	subtle ways. That includes mouse positions, timings, and disk
+	size measurements. Some obvious correlations will be eliminated
+	by the programmer, but other, weaker ones may remain. The
+	reliability of the code depends on such correlations being
+	poorly understood, both by us and by potential interceptors.
+
+	This package has been planned to be used with OpenSSL, v. 0.9.5.
+	It requires the OpenSSL function RAND_add. 
+
+--	OTHER WORK: Some source code and other details have been
+	published elsewhere, but I haven't found any to be satisfactory
+	for the Mac per se:
+
+	* The Linux random number generator (by Theodore Ts'o, in
+	  drivers/char/random.c), is a carefully designed open-source
+	  crypto random number package. It collects data from a variety
+	  of sources, including mouse, keyboard and other interrupts.
+	  One nice feature is that it explicitly estimates the entropy
+	  of the data it collects. Some of its features (e.g. interrupt
+	  timing) cannot be reliably exported to the Mac without using
+	  undocumented APIs.
+
+	* Truerand by Don P. Mitchell and Matt Blaze uses variations
+	  between different timing mechanisms on the same system. This
+	  has not been tested on the Mac, but requires preemptive
+	  multitasking, and is hardware-dependent, and can't be relied
+	  on to work well if only one oscillator is present.
+
+	* Cryptlib's RNG for the Mac (RNDMAC.C by Peter Gutmann),
+	  gathers a lot of information about the machine and system
+	  environment. Unfortunately, much of it is constant from one
+	  startup to the next. In other words, the random seed could be
+	  the same from one day to the next. Some of the APIs are
+	  hardware-dependent, and not all are compatible with Carbon (OS
+	  X). Incidentally, the EGD library is based on the UNIX entropy
+	  gathering methods in cryptlib, and isn't suitable for MacOS
+	  either.
+
+	* Mozilla (and perhaps earlier versions of Netscape) uses the
+	  time of day (in seconds) and an uninitialized local variable
+	  to seed the random number generator. The time of day is known
+	  to an outside interceptor (to within the accuracy of the
+	  system clock). The uninitialized variable could easily be
+	  identical between subsequent launches of an application, if it
+	  is reached through the same path.
+
+	* OpenSSL provides the function RAND_screen(), by G. van
+	  Oosten, which hashes the contents of the screen to generate a
+	  seed. This is not useful for an extension or for an
+	  application which launches at startup time, since the screen
+	  is likely to look identical from one launch to the next. This
+	  method is also rather slow.
+
+	* Using variations in disk drive seek times has been proposed
+	  (Davis, Ihaka and Fenstermacher, world.std.com/~dtd/;
+	  Jakobsson, Shriver, Hillyer and Juels,
+	  www.bell-labs.com/user/shriver/random.html). These variations
+	  appear to be due to air turbulence inside the disk drive
+	  mechanism, and are very strongly unpredictable. Unfortunately
+	  this technique is slow, and some implementations of it may be
+	  patented (see Shriver's page above.) It of course cannot be
+	  used with a RAM disk.
+
+--	TIMING: On the 601 PowerPC the time base register is guaranteed
+	to change at least once every 10 addi instructions, i.e. 10
+	cycles. On a 60 MHz machine (slowest PowerPC) this translates to
+	a resolution of 1/6 usec. Newer machines seem to be using a 10
+	cycle resolution as well.
+	
+	For 68K Macs, the Microseconds() call may be used. See Develop
+	issue 29 on the Apple developer site
+	(developer.apple.com/dev/techsupport/develop/issue29/minow.html)
+	for information on its accuracy and resolution. The code below
+	has been tested only on PowerPC based machines.
+
+	The time from machine startup to the launch of an application in
+	the startup folder has a variance of about 1.6 msec on a new G4
+	machine with a defragmented and optimized disk, most extensions
+	off and no icons on the desktop. This can be reasonably taken as
+	a lower bound on the variance. Most of this variation is likely
+	due to disk seek time variability. The distribution of startup
+	times is probably not entirely even or uncorrelated. This needs
+	to be investigated, but I am guessing that it not a majpor
+	problem. Entropy = log2 (1600/0.166) ~= 13 bits on a 60 MHz
+	machine, ~16 bits for a 450 MHz machine.
+
+	User-launched application startup times will have a variance of
+	a second or more relative to machine startup time. Entropy >~22
+	bits.
+
+	Machine startup time is available with a 1-second resolution. It
+	is predictable to no better a minute or two, in the case of
+	people who show up punctually to work at the same time and
+	immediately start their computer. Using the scheduled startup
+	feature (when available) will cause the machine to start up at
+	the same time every day, making the value predictable. Entropy
+	>~7 bits, or 0 bits with scheduled startup.
+
+	The time of day is of course known to an outsider and thus has 0
+	entropy if the system clock is regularly calibrated.
+
+--	KEY TIMING: A  very fast typist (120 wpm) will have a typical
+	inter-key timing interval of 100 msec. We can assume a variance
+	of no less than 2 msec -- maybe. Do good typists have a constant
+	rhythm, like drummers? Since what we measure is not the
+	key-generated interrupt but the time at which the key event was
+	taken off the event queue, our resolution is roughly the time
+	between process switches, at best 1 tick (17 msec). I  therefore
+	consider this technique questionable and not very useful for
+	obtaining high entropy data on the Mac.
+
+--	MOUSE POSITION AND TIMING: The high bits of the mouse position
+	are far from arbitrary, since the mouse tends to stay in a few
+	limited areas of the screen. I am guessing that the position of
+	the mouse is arbitrary within a 6 pixel square. Since the mouse
+	stays still for long periods of time, it should be sampled only
+	after it was moved, to avoid correlated data. This gives an
+	entropy of log2(6*6) ~= 5 bits per measurement.
+
+	The time during which the mouse stays still can vary from zero
+	to, say, 5 seconds (occasionally longer). If the still time is
+	measured by sampling the mouse during null events, and null
+	events are received once per tick, its resolution is 1/60th of a
+	second, giving an entropy of log2 (60*5) ~= 8 bits per
+	measurement. Since the distribution of still times is uneven,
+	this estimate is on the high side.
+
+	For simplicity and compatibility across system versions, the
+	mouse is to be sampled explicitly (e.g. in the event loop),
+	rather than in a time manager task.
+
+--	STARTUP DISK TOTAL FILE SIZE: Varies typically by at least 20k
+	from one startup to the next, with 'minimal' computer use. Won't
+	vary at all if machine is started again immediately after
+	startup (unless virtual memory is on), but any application which
+	uses the web and caches information to disk is likely to cause
+	this much variation or more. The variation is probably not
+	random, but I don't know in what way. File sizes tend to be
+	divisible by 4 bytes since file format fields are often
+	long-aligned. Entropy > log2 (20000/4) ~= 12 bits.
+	
+--	STARTUP DISK FIRST AVAILABLE ALLOCATION BLOCK: As the volume
+	gets fragmented this could be anywhere in principle. In a
+	perfectly unfragmented volume this will be strongly correlated
+	with the total file size on the disk. With more fragmentation
+	comes less certainty. I took the variation in this value to be
+	1/8 of the total file size on the volume.
+
+--	SYSTEM REQUIREMENTS: The code here requires System 7.0 and above
+	(for Gestalt and Microseconds calls). All the calls used are
+	Carbon-compatible.
+*/
+
+/*------------------------------ Includes ----------------------------*/
+
+#include "Randomizer.h"
+
+// Mac OS API
+#include <Files.h>
+#include <Folders.h>
+#include <Events.h>
+#include <Processes.h>
+#include <Gestalt.h>
+#include <Resources.h>
+#include <LowMem.h>
+
+// Standard C library
+#include <stdlib.h>
+#include <math.h>
+
+/*---------------------- Function declarations -----------------------*/
+
+// declared in OpenSSL/crypto/rand/rand.h
+extern "C" void RAND_add (const void *buf, int num, double entropy);
+
+unsigned long GetPPCTimer (bool is601);	// Make it global if needed
+					// elsewhere
+
+/*---------------------------- Constants -----------------------------*/
+
+#define kMouseResolution 6		// Mouse position has to differ
+					// from the last one by this
+					// much to be entered
+#define kMousePositionEntropy 5.16	// log2 (kMouseResolution**2)
+#define kTypicalMouseIdleTicks 300.0	// I am guessing that a typical
+					// amount of time between mouse
+					// moves is 5 seconds
+#define kVolumeBytesEntropy 12.0	// about log2 (20000/4),
+					// assuming a variation of 20K
+					// in total file size and
+					// long-aligned file formats.
+#define kApplicationUpTimeEntropy 6.0	// Variance > 1 second, uptime
+					// in ticks  
+#define kSysStartupEntropy 7.0		// Entropy for machine startup
+					// time
+
+
+/*------------------------ Function definitions ----------------------*/
+
+CRandomizer::CRandomizer (void)
+{
+	long	result;
+	
+	mSupportsLargeVolumes =
+		(Gestalt(gestaltFSAttr, &result) == noErr) &&
+		((result & (1L << gestaltFSSupports2TBVols)) != 0);
+	
+	if (Gestalt (gestaltNativeCPUtype, &result) != noErr)
+	{
+		mIsPowerPC = false;
+		mIs601 = false;
+	}
+	else
+	{
+		mIs601 = (result == gestaltCPU601);
+		mIsPowerPC = (result >= gestaltCPU601);
+	}
+	mLastMouse.h = mLastMouse.v = -10;	// First mouse will
+						// always be recorded
+	mLastPeriodicTicks = TickCount();
+	GetTimeBaseResolution ();
+	
+	// Add initial entropy
+	AddTimeSinceMachineStartup ();
+	AddAbsoluteSystemStartupTime ();
+	AddStartupVolumeInfo ();
+	AddFiller ();
+}
+
+void CRandomizer::PeriodicAction (void)
+{
+	AddCurrentMouse ();
+	AddNow (0.0);	// Should have a better entropy estimate here
+	mLastPeriodicTicks = TickCount();
+}
+
+/*------------------------- Private Methods --------------------------*/
+
+void CRandomizer::AddCurrentMouse (void)
+{
+	Point mouseLoc;
+	unsigned long lastCheck;	// Ticks since mouse was last
+					// sampled
+
+#if TARGET_API_MAC_CARBON
+	GetGlobalMouse (&mouseLoc);
+#else
+	mouseLoc = LMGetMouseLocation();
+#endif
+	
+	if (labs (mLastMouse.h - mouseLoc.h) > kMouseResolution/2 &&
+	    labs (mLastMouse.v - mouseLoc.v) > kMouseResolution/2)
+		AddBytes (&mouseLoc, sizeof (mouseLoc),
+				kMousePositionEntropy);
+	
+	if (mLastMouse.h == mouseLoc.h && mLastMouse.v == mouseLoc.v)
+		mMouseStill ++;
+	else
+	{
+		double entropy;
+		
+		// Mouse has moved. Add the number of measurements for
+		// which it's been still. If the resolution is too
+		// coarse, assume the entropy is 0.
+
+		lastCheck = TickCount() - mLastPeriodicTicks;
+		if (lastCheck <= 0)
+			lastCheck = 1;
+		entropy = log2l
+			(kTypicalMouseIdleTicks/(double)lastCheck);
+		if (entropy < 0.0)
+			entropy = 0.0;
+		AddBytes (&mMouseStill, sizeof (mMouseStill), entropy);
+		mMouseStill = 0;
+	}
+	mLastMouse = mouseLoc;
+}
+
+void CRandomizer::AddAbsoluteSystemStartupTime (void)
+{
+	unsigned long	now;		// Time in seconds since
+					// 1/1/1904
+	GetDateTime (&now);
+	now -= TickCount() / 60;	// Time in ticks since machine
+					// startup
+	AddBytes (&now, sizeof (now), kSysStartupEntropy);
+}
+
+void CRandomizer::AddTimeSinceMachineStartup (void)
+{
+	AddNow (1.5);			// Uncertainty in app startup
+					// time is > 1.5 msec (for
+					// automated app startup).
+}
+
+void CRandomizer::AddAppRunningTime (void)
+{
+	ProcessSerialNumber PSN;
+	ProcessInfoRec		ProcessInfo;
+	
+	ProcessInfo.processInfoLength = sizeof (ProcessInfoRec);
+	ProcessInfo.processName = nil;
+	ProcessInfo.processAppSpec = nil;
+	
+	GetCurrentProcess (&PSN);
+	GetProcessInformation (&PSN, &ProcessInfo);
+
+	// Now add the amount of time in ticks that the current process
+	// has been active
+
+	AddBytes (&ProcessInfo, sizeof (ProcessInfoRec),
+			kApplicationUpTimeEntropy);
+}
+
+void CRandomizer::AddStartupVolumeInfo (void)
+{
+	short			vRefNum;
+	long			dirID;
+	XVolumeParam	pb;
+	OSErr			err;
+	
+	if (!mSupportsLargeVolumes)
+		return;
+		
+	FindFolder (kOnSystemDisk, kSystemFolderType, kDontCreateFolder,
+			&vRefNum, &dirID);
+	pb.ioVRefNum = vRefNum;
+	pb.ioCompletion = 0;
+	pb.ioNamePtr = 0;
+	pb.ioVolIndex = 0;
+	err = PBXGetVolInfoSync (&pb);
+	if (err != noErr)
+		return;
+		
+	// Base the entropy on the amount of space used on the disk and
+	// on the next available allocation block. A lot else might be
+	// unpredictable, so might as well toss the whole block in. See
+	// comments for entropy estimate justifications.
+
+	AddBytes (&pb, sizeof (pb),
+		kVolumeBytesEntropy +
+		log2l (((pb.ioVTotalBytes.hi - pb.ioVFreeBytes.hi)
+				* 4294967296.0D +
+			(pb.ioVTotalBytes.lo - pb.ioVFreeBytes.lo))
+				/ pb.ioVAlBlkSiz - 3.0));
+}
+
+/*
+	On a typical startup CRandomizer will come up with about 60
+	bits of good, unpredictable data. Assuming no more input will
+	be available, we'll need some more lower-quality data to give
+	OpenSSL the 128 bits of entropy it desires. AddFiller adds some
+	relatively predictable data into the soup.
+*/
+
+void CRandomizer::AddFiller (void)
+{
+	struct
+	{
+		ProcessSerialNumber psn;	// Front process serial
+						// number
+		RGBColor	hiliteRGBValue;	// User-selected
+						// highlight color
+		long		processCount;	// Number of active
+						// processes
+		long		cpuSpeed;	// Processor speed
+		long		totalMemory;	// Total logical memory
+						// (incl. virtual one)
+		long		systemVersion;	// OS version
+		short		resFile;	// Current resource file
+	} data;
+	
+	GetNextProcess ((ProcessSerialNumber*) kNoProcess);
+	while (GetNextProcess (&data.psn) == noErr)
+		data.processCount++;
+	GetFrontProcess (&data.psn);
+	LMGetHiliteRGB (&data.hiliteRGBValue);
+	Gestalt (gestaltProcClkSpeed, &data.cpuSpeed);
+	Gestalt (gestaltLogicalRAMSize, &data.totalMemory);
+	Gestalt (gestaltSystemVersion, &data.systemVersion);
+	data.resFile = CurResFile ();
+	
+	// Here we pretend to feed the PRNG completely random data. This
+	// is of course false, as much of the above data is predictable
+	// by an outsider. At this point we don't have any more
+	// randomness to add, but with OpenSSL we must have a 128 bit
+	// seed before we can start. We just add what we can, without a
+	// real entropy estimate, and hope for the best.
+
+	AddBytes (&data, sizeof(data), 8.0 * sizeof(data));
+	AddCurrentMouse ();
+	AddNow (1.0);
+}
+
+//-------------------  LOW LEVEL ---------------------
+
+void CRandomizer::AddBytes (void *data, long size, double entropy)
+{
+	RAND_add (data, size, entropy * 0.125);	// Convert entropy bits
+						// to bytes
+}
+
+void CRandomizer::AddNow (double millisecondUncertainty)
+{
+	long time = SysTimer();
+	AddBytes (&time, sizeof (time), log2l (millisecondUncertainty *
+			mTimebaseTicksPerMillisec));
+}
+
+//----------------- TIMING SUPPORT ------------------
+
+void CRandomizer::GetTimeBaseResolution (void)
+{	
+#ifdef __powerc
+	long speed;
+	
+	// gestaltProcClkSpeed available on System 7.5.2 and above
+	if (Gestalt (gestaltProcClkSpeed, &speed) != noErr)
+		// Only PowerPCs running pre-7.5.2 are 60-80 MHz
+		// machines.
+		mTimebaseTicksPerMillisec =  6000.0D;
+	// Assume 10 cycles per clock update, as in 601 spec. Seems true
+	// for later chips as well.
+	mTimebaseTicksPerMillisec = speed / 1.0e4D;
+#else
+	// 68K VIA-based machines (see Develop Magazine no. 29)
+	mTimebaseTicksPerMillisec = 783.360D;
+#endif
+}
+
+unsigned long CRandomizer::SysTimer (void)	// returns the lower 32
+						// bit of the chip timer
+{
+#ifdef __powerc
+	return GetPPCTimer (mIs601);
+#else
+	UnsignedWide usec;
+	Microseconds (&usec);
+	return usec.lo;
+#endif
+}
+
+#ifdef __powerc
+// The timebase is available through mfspr on 601, mftb on later chips.
+// Motorola recommends that an 601 implementation map mftb to mfspr
+// through an exception, but I haven't tested to see if MacOS actually
+// does this. We only sample the lower 32 bits of the timer (i.e. a
+// few minutes of resolution)
+
+asm unsigned long GetPPCTimer (register bool is601)
+{
+	cmplwi	is601, 0	// Check if 601
+	bne	_601		// if non-zero goto _601
+	mftb  	r3		// Available on 603 and later.
+	blr			// return with result in r3
+_601:
+	mfspr r3, spr5  	// Available on 601 only.
+				// blr inserted automatically
+}
+#endif
diff --git a/openssl/MacOS/Randomizer.h b/openssl/MacOS/Randomizer.h
new file mode 100644
index 0000000..565537b
--- /dev/null
+++ b/openssl/MacOS/Randomizer.h
@@ -0,0 +1,43 @@
+
+//	Gathers unpredictable system data to be used for generating
+//	random bits
+
+#include <MacTypes.h>
+
+class CRandomizer
+{
+public:
+	CRandomizer (void);
+	void PeriodicAction (void);
+	
+private:
+
+	// Private calls
+
+	void		AddTimeSinceMachineStartup (void);
+	void		AddAbsoluteSystemStartupTime (void);
+	void		AddAppRunningTime (void);
+	void		AddStartupVolumeInfo (void);
+	void		AddFiller (void);
+
+	void		AddCurrentMouse (void);
+	void		AddNow (double millisecondUncertainty);
+	void		AddBytes (void *data, long size, double entropy);
+	
+	void		GetTimeBaseResolution (void);
+	unsigned long	SysTimer (void);
+
+	// System Info	
+	bool		mSupportsLargeVolumes;
+	bool		mIsPowerPC;
+	bool		mIs601;
+	
+	// Time info
+	double		mTimebaseTicksPerMillisec;
+	unsigned long	mLastPeriodicTicks;
+	
+	// Mouse info
+	long		mSamplePeriod;
+	Point		mLastMouse;
+	long		mMouseStill;
+};
diff --git a/openssl/MacOS/TODO b/openssl/MacOS/TODO
new file mode 100644
index 0000000..903eb13
--- /dev/null
+++ b/openssl/MacOS/TODO
@@ -0,0 +1,18 @@
+-------------------------------------------------------------------
+Verify server certificate
+-------------------------------------------------------------------
+Currently omitted from the project:
+
+	crypto/tmdiff.c
+	crypto/bio/bss_conn.c
+	crypto/bio/b_sock.c
+	crypto/bio/bss_acpt.c
+	crypto/bio/bss_log.h
+
+-------------------------------------------------------------------
+Build libraries to link with...
+-------------------------------------------------------------------
+Port openssl application.
+-------------------------------------------------------------------
+BN optimizations (currently PPC version is compiled with BN_LLONG)
+-------------------------------------------------------------------
diff --git a/openssl/MacOS/_MWERKS_GUSI_prefix.h b/openssl/MacOS/_MWERKS_GUSI_prefix.h
new file mode 100644
index 0000000..fe6b538
--- /dev/null
+++ b/openssl/MacOS/_MWERKS_GUSI_prefix.h
@@ -0,0 +1,9 @@
+#include <MacHeaders.h>
+#define B_ENDIAN
+#ifdef __POWERPC__
+#pragma longlong on
+#endif
+#if 1
+#define MAC_OS_GUSI_SOURCE
+#endif
+#define MONOLITH
diff --git a/openssl/MacOS/_MWERKS_prefix.h b/openssl/MacOS/_MWERKS_prefix.h
new file mode 100644
index 0000000..2189da7
--- /dev/null
+++ b/openssl/MacOS/_MWERKS_prefix.h
@@ -0,0 +1,9 @@
+#include <MacHeaders.h>
+#define B_ENDIAN
+#ifdef __POWERPC__
+#pragma longlong on
+#endif
+#if 0
+#define MAC_OS_GUSI_SOURCE
+#endif
+#define MONOLITH
diff --git a/openssl/MacOS/buildinf.h b/openssl/MacOS/buildinf.h
new file mode 100644
index 0000000..90875b6
--- /dev/null
+++ b/openssl/MacOS/buildinf.h
@@ -0,0 +1,5 @@
+#ifndef MK1MF_BUILD
+#  define CFLAGS	"-DB_ENDIAN"
+#  define PLATFORM	"macos"
+#  define DATE		"Sun Feb 27 19:44:16 MET 2000"
+#endif
diff --git a/openssl/MacOS/mklinks.as.hqx b/openssl/MacOS/mklinks.as.hqx
new file mode 100644
index 0000000..fe3e7d5
--- /dev/null
+++ b/openssl/MacOS/mklinks.as.hqx
@@ -0,0 +1,820 @@
+(This file must be converted with BinHex 4.0)
+
+:#QeVE'PZDh-ZBA-!39"36'&`E(3J!!!!!!!!!*LiI6m!!!!!!3!!!*G#!!#@3J!
+!!AChFQPd!!!!K3)"!3m(Fh9`F'pbG!!!!)B#!3%$"(0eFQ8!!!#(!J-%"!3("3C
+cGfPdBfJ!!!#)!J%"#39cH@jMD!!!!)N#"J%$!`-&"3-'FhPcG'9Y!!!!LJ)&"3)
+%!J8("!-#!`4dB@*X!!!!L`))!3-$!`-$!`-$"(4PE'`!!!#-!J)"#38$G'KP!!!
+!M3))(J)@!Ki#!J))!K)#!`)B!Kd%G'KPE3!!!)i#!J%&#`4dD'9j!!!!M`)#!J)
+#$3TdD(*[G@GSEh9d!!!!N!!#!3%&"(4TCQB!!!#4!J%"!`4dD@eP!!!!NJ)"!JS
+#!h4T!!!!'N!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!H!!!!!!!#!!!!!!
+!!!!!!!!!!!!!rrrrr`!!!$3!!!!N!!!!!#"[!!5JAb"[!!5K++!M6R9$9'mJFR9
+Z)(4SDA-JFf0bDA"d)'&`F'aTBf&dD@pZ,#"jEh8JEA9cG#"QDA*cG#"TER0dB@a
+X)%&`F'aP8f0bDA"d,J!!!)C8D'Pc)(0MFQP`G#"MFQ9KG'9c)#iZ,fPZBfaeC'8
+[Eh"PER0cE#"KEQ3JCQPXE(-JDA3JGfPdD#"ZC@0PFh0KFRNJB@aTBA0PFbi0$8P
+d)'eTCfKd)(4KDf8JB5"hD'PXC5"dEb"MEfe`E'9dC5"cEb"`E'9KFf8JBQ8JF'&
+dD@9ZG$SY+3!!!#S!!J!!!!!!$3!+!"!!!!!-!!!!!!!!!!!!63!0!!S!%!%!!!`
+!!!!!!!!!!!!B!!!!+!!!!!!!!!!)!!!!)!#N2c`!!DR`!!!!l!!!!!&19[ri,`0
+f!#m$-$bKVDG'*KmY52ri,`-`2+LITdBQ(b!ZrrLa`'FJ,`-J2'0`ER4"l[rm)NL
+KV5+)*Kp+3'B)5Ulrr'F#GJ%3!bBZrr41ANje6PB!!#m-@Bm[2%j29%Nr2!#!U"m
+SAb!-CJK`!cm!UFKJ+#m-UC)J9#!)d+J!'#&!!"JJ9#!)d+J!(#&!!"a9Mbm8)&q
+JAMk!9%mSE[rm6Pj1G8j@!!![$%kkre4+!'FU@Bm[2'&`E(3[2(0MF(4`)DJU+&m
+J$'F5@Bm[$#mm!!!!!A!!U#UTp&K26VVrG#KZrra1ANje!!!!('&`E(3!!!!"4P*
+&4J!!!!!!J%P$6L-!!!!!!*B!!!!"!!!!!!G"8&"-!!!!!!!"!!!"!!!!!S!!!!4
+!!!"i)!!!K"!!!3))!!)#"!!%"!)!#!J"!"!8!)!J)J"!3%%!)2#!J"#*!%!)KJ!
+J")3!)!*!!"!")!!3!K!!%!3)!"!)"!!J%!)!3#!"!)"!!S%!J!5#!3!)4!)!#%J
+%!!KB#!!%C"!!!m)J!!!"3!!!!)!!!!%!!!!$J!!!"m!!!(rJ!!$rm!!"rrJ!!rr
+m!!IrrJ!2rrm!(rrrJ$rrrm"rrrrJrrrrm2rrrrMrrrrmrrrrrRrrrrmrrrrq(rr
+rr!rrrrJ(rrr`!rrri!(rrm!$rrq!"rrr!!rrrJ!2rr`!$rri!!IRm!!$`q!!!!(
+!!!!!J!!!!!)!!!!!!!!!!!m!!!!!!!!!!!!!!!!!!!$`m!!!!!!!!!!!!!!!!!!
+2!!m!!!!!!!!!!!!!!!rrm!!!m!!!!!!!!!!!!!$`c0m!!!m!!!!!!!!!!!!2!!c
+-m!!!m!!!!!!!!!!!m!$-cI!!!!m!!!!!!!!!$`!-c0m!!!!!m!!!!!!!!2!!c-h
+`!!!!!!m!!!!!!!m!$-cIh`!!!!!!m!!!!!$`!-c0rGh`!!!!!!m!!!!2!!c-hph
+-h`!!!!!!m!!!rrr-cIhF`-h`!!!!!!m!!2lFr0rGc!`-h`!!!!!!m!$pc-rph-$
+!`-h`!!!!!!m!r-`2cF`-$!!-r3!!!!!!m!m!`-c!`-!!$0m!!!!!$-m!m!`-$!`
+!!-cI!!!!!-c`!!m!`-$!!!`-h`!!!!c2!!!!m!`-!!$!c0m!!!$-m!!!!!m!`!!
+-$-hm!!!-c`!!!!!!m!!!`-cIc!!!c2!!!!!!!!m!$!c0r-`!$-m!!!!!!!$pm-$
+-hmc!!-c`!!!!!!!2hI`-cIc-!!c2!!!!!!!!rGc2c0r-`!$-m!!!!!!!!2h-cmh
+mc!!-c`!!!!!!!!$mc!rIr-!!c2!!!!!!!!!!$m$2m!r-$-m!!!!!!!!!!!$rr`!
+!r-c`!!!!!!!!!!!!!!!!!!r2!!!!!!!!!!!!!!!!!!!!m!!!!!!!!!!!!!"!!B!
+13"%J)4"##18%Q)+3!%&!)5!L%%3BL#83*L!G3!#!!B!2`"rJ2r"rq2rmrrlrrhr
+r2riIr"ri2r!ri"h!!)!!!!#!!!!!$r!!!!!!!2r`$`!!!!!2$!m!m!!!!2$!c`!
+2!!!2$!c`!!$`!2r`cpm!!!m!rGrpc2!!!2$p$p`-c`!!$`m!`-$0m!$2!2!-$-h
+`$2!!$`$-hm$2!!!2m-hm$2!!!2h2hm$2!!!!r-rm$2!!!!!2r`r2!!!!!!!!!2!
+!!!!!!!#D8f0bDA"d)%&`F'aTBf&dD@pZ$3e8D'Pc)(0MFQP`G#"MFQ9KG'9c)#i
+Z,fPZBfaeC'8[Eh"PER0cE#"KEQ3JCQPXE(-JDA3JGfPdD#"ZC@0PFh0KFRNJB@a
+TBA0PFbi0$8Pd)'eTCfKd)(4KDf8JB5"hD'PXC5"dEb"MEfe`E'9dC5"cEb"`E'9
+KFf8JBQ8JF'&dD@9ZG$SY+3!!!")!!J!!!!!!!!!!!!%!"J!'%iN!!!!+@1!!!b!
+!!!-J!!!!!"3!+`!(!Cm#@!!V!!F"f!*B!!!!!3!!M`C'BA0N98&6)$%Z-6!a,M%
+`$J!!!!32rrm!!3!#!!-"rrm!!!d!!3!"D`!!!!!!!!!%!J!%!!)!"3!'$3!&!!*
+X!!)!!!U`!!IrrJd!"`!#6`!!!!!+X!!)!!N0!!J!!@X!!!!%#Um!#J)!#J!#!!X
+!$!d!#`!#E!!#!!3!"2rprr`"rrd!!!(rr!!!!J!-!!)!$3!1$3!0!!*X!!%!"!!
+%rrX!$`(rq`!!$!!2!&N!8b"(CA3JF'&dD#"dEb"dD'Pc)%&`F'aP8f0bDA"d)'&
+`F'aPG$XJGA0P)'Pd)(4[)'C[FQdJG'KP)("KG'JJG'mJG'KP)'PZBfaeC'8JCQp
+XC'9b!!)!!!)!$J!#!"!!%3d!%!!#E!!"!!3!"2rk!")"rrS!!!`!%J!Q!#!JB@j
+N)(4SC5"[G'KPFL"bC@aPGQ&ZG#"QEfaNCA*c,J!#!!!#!"%!!J!6!"30!"-!!R-
+!!!!%!"%!&3!@$3!9!!*M!!!!"!!1!"F!'!d!&`!#E!!&!!3!$!!CrrN0!"N!!Qi
+!!!!%!!`!'J!E$3!D!!)d!!!!"3!-rrJ!(!Vrq!!%#Q0[BQS0!"`!!Q`!"3!'!!X
+!(Irh$3!G!!0*!!)!"J!,rrB!([re#[rf!"JZC@&bFfCQC(*KE'Pc!!!!!!!!)!"
+KCQ4b$3!H!!"Q!!!!"J!(![re!!!"rrF!!!d!'`!"E3!!!!3!"3!I$`!I!6J)ER9
+XE!!!!!!!!Gq!rrm!!!!A"NCTEQ4PFJ!!(`*[Me!!ASfm!Qq,i!"HA[!!I&M!!!!
+!!!!!'mi!!JN#!Qq-1!!!Kb%#Ei`J!!!!!%C14&*038e"3e-!!"%!B@aTF`!!!!!
+!fJ!#!!!-6@&MD@jdEh0S)%K%!!!!!!!!!!!!!!!!!!!!XSA5h%*%!!!!!!!A"NC
+TEQ4PFJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!3rLc#@a!4Nj%8Ne"3e2rrrrr!!!!!!!!!!!!!!!!!!!
+!!!!!!!e6HA0dC@dJ4QpXC'9b!!!"!!3!!!!A!!)!)8eKBfPZG'pcD#")4$T6HA0
+dC@dJ4QpXC'9b1NCTEQ4PFJ$rr`!!!Irj!!!0!"J!!@d!!!!-!!hrp!Vrp!!%#Q0
+dH(30!"B!!@m!!!!!!!$rm`[rm`!5-!!(G'KPF'&dD!!(G'KP8'&dD!)!&!!#!#!
+!)3d!)!!#E!!#!")!%[rbrr%"rr)!!!(rm3!!!J!K!!)!)J!M$3!L!!*b!!!!%J!
+A!#3!*3d!*!!#EJ!$!")!&3!Q!#F0!#B!!6%!!!!6!"Arm!Vrm!!%#R4iC'`0!#F
+!!6%!!!!5!"2rl`Vrl`!%#Q&cBh)0!#8!!@m!!!!!!!$rlJ[rlJ!F-!!-G'KPEfa
+NC'9XD@ec!!adD'92E'4%C@aTEA-#!#-!!J!S!#N0!#J!!R)!!!!B!"d!+J!V$3!
+U!!&Y!!!!'!!C!#`-!#`!"`!"1J!#!!!0!#X!!Qi!!`!!!!!!,3!Z$3!Y!!%a!!!
+!'J!Frqd+rqd!"!TdH'4X$3!Z!!%a!!!!'3!Drq`+rq`!"!TKFf0b!J!T!!)!,`!
+`$3![!!*X!!)!(J!Hrq[rkJ(rk`!!!IrU!!!#!$!!!J!a!$)0!$%!!R)!!!!H!#X
+!-`!d$3!c!!*X!!8!(J!T!$Ark3d!03!#EJ!!!"i!+3!f!$F0!$B!!cF"!!!I!#R
+rk!!i!$N+rqJ!"!TMDA4Y$3!i!!&Y!!!!)`!PrqF$rqF!!3d!13!"E3!!!#B!+2r
+Q!rrQrrd0!$F!!@m!!!!H!"rrj3[rj3!5-!!(G'KPF'&dD!!(G'KP8'&dD!(rk3!
+!$3!d!!&[!!!!!!!!rq3,rq3!)$!!$R4SCA"bEfTPBh4`BA4S!!jdD'93FQpUC@0
+d8'&dD!)!-J!#!$S!1`d!1J!#FJ!!!#`!1`!m!$d0!$`!!Q-!!!!X!$N!2J!r$3!
+q!!*X!!8!,!!h!%$ri`d!3!!#EJ!!!#`!0`""!%)0!%%!!cF"!!!Y!$IriJ"$!%3
++rq)!"!TMDA4Y$3"$!!&Y!!!!-3!crq%$rq%!!3d!4!!"E3!!!$3!0[rJ!rrJrri
+0!%)!!@m!!!!X!#hrh`[rh`!5-!!(G'KPF'&dD!!(G'KP8'&dD!(ri`!!$3!r!!&
+Y!!!!0`!irpi+rpi!"!T849K8$3!p!!&[!!!!!!!!rpd,rpd!&M!!#A4SC@ePF'&
+dD!!*G'KP6@93BA4S!J!l!!)!43"'$3"&!!*X!!)!2!!mrpcrf`(rh!!!!IrE!!!
+#!%B!!J"(!%J0!%F!!R)!!!!m!%8!53"+$3"*!!*M!!!!2!""!%X!6!d!5`!#BJ!
+!!$`!2`"0!%i0!%d!!@m!!!!m!$hrfJ[rfJ!J-!!1G'KPF(*[DQ9MG("KG'J!$R4
+SC9"bEfTPBh43BA4S$3"1!!&Y!!!!23!q!%m-!%m!$3!(D@jME(9NC3!#!!!0!%`
+!!@d!!!!r!%$rf3Vrf3!%#P4&@&30!%S!!@m!!!!!!!$rf![rf!!Q-!!4D@jME(9
+NC@C[E'4PFR"KG'J!%@PZBfaeC'9'EfaNCA*3BA4S!J")!!)!8!"4$3"3!!*b!!!
+!4J"9!&)!8`d!8J!#B`!!!%B!83"8!&80!&3!!Q)!!!"'!%m!9J"A$3"@!!*L!!!
+!4J",!&J!@3d!@!!"E`!!!%B!4rrA#rrA!#!`!!jdD'9`FQpUC@0dF'&dD!!1G'K
+P8(*[DQ9MG&"KG'J0!&N!!@d!!!"(!%S!@J`!@J!0!!GTEQ0XG@4P!!)!!!d!9`!
+"E3!!!%X!6J"E$!"E!!d!"fp`C@jcFf`!!J!!$3"9!!&Y!!!!6`"3rpB+rpB!"!T
+849K8$3"6!!&[!!!!!!!!rp8,rp8!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&
+dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S!J"4!!)!A!"G$3"F!!*b!!!!9J"
+K!&i!A`d!AJ!#B`!!!&B!A3"J!'%0!'!!!Q)!!!"@!&X!BJ"M$3"L!!&[!!!!9J"
+Arp3,rp3!)$!!$R4SCA"bEfTPBh4`BA4S!!jdD'93FQpUC@0d8'&dD!d!B`!"E3!
+!!&F!@J"N$!"N!!`!"Q0bHA"dE`!#!!!0!'%!!@d!!!"E!&crd`Vrd`!%#P4&@&3
+0!&m!!@m!!!!!!!$rdJ[rdJ!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4Qp
+XC'9b8'&dD!)!A3!#!'8!CJd!C3!#FJ!!!')!E3"R!'J0!'F!!Q-!!!"L!'N!D3"
+U$3"T!!*L!!!!BJ"R!'X!E!d!D`!"E`!!!')!Brr4#rr4!#!`!!jdD'9`FQpUC@0
+dF'&dD!!1G'KP8(*[DQ9MG&"KG'J0!'`!!@d!!!"M!'B!E3`!E3!*!!0cFf`!!J!
+!$3"U!!&Y!!!!C`"Srp!+rp!!"!T849K8$3"S!!&[!!!!!!!!rmm,rmm!(M!!$A0
+cE'C[E'4PFR"KG'J!$A0cE%C[E'4PFP"KG'J#!'B!!J"Z!'m0!'i!!R)!!!"Z!(8
+!F!"a$3"`!!*M!!!!EJ"a!()!F`d!FJ!"E`!!!'i!Err1#rr1!#!`!!jdD'9`FQp
+UC@0dF'&dD!!1G'KP8(*[DQ9MG&"KG'J0!(-!!@d!!!"[!($rc3Vrc3!%#P4&@&3
+0!(%!!@m!!!!!!!$rc![rc!!Q-!!4Eh"PER0cE'C[E'4PFR"KG'J!%@p`C@jcFfa
+'EfaNCA*3BA4S!J"[!!)!G!"e$3"d!!*X!!)!GJ"frm[rbJ(rb`!!!Ir+!!!#!(8
+!!J"f!(F0!(B!!R)!!!"f!(X!H!"j$3"i!!&[!!!!GJ"hrmN,rmN!($!!$(4SC@p
+XC'4PE'PYF`!-G'KP6faN4'9XD@ec$3"j!!*Z!!-!!!!!!(S!H`d!HJ!"-3!!!(J
+!H[r)#[r)!!3+G(KNE!d!H`!"-3!!!(F!H2r(#[r(!!3+BA0MFJ)!G`!#!(`!I3d
+!I!!#E!!#!(`!I2r'rm8"rmB!!!(ra3!!!J"p!!)!IJ"r$3"q!!*X!!%!I!"mrm3
+!J!(ra!!!$!#!!%!!1L"NC@aPG'8JEfaN)'PZBfaeC'8kEh"PER0cE#"QEfaNCA)
+JB@jN)(*PBh*PBA4P)'Pd)'0XC@&ZE(N!!J!!!J"r!!)!J3##$3#"!!*X!!)!I!"
+mrm2r`J(r``!!!Ir#!!!#!))!!J#$!)30!)-!!e%!!!"m!+8!K3#'!)F0!)8!!@X
+!!!"r!*`!L!)!L!!#!)N!LJd!L3!$53!#!(m!N[r"!)[r`!Vr`3!B,QeTFf0cE'0
+d+LSU+J!!!!!!!*!!!#SU+LS0!)X!!Qi!!!"r!)i!M!#0$3#-!!)d!!!!K`#1rlm
+!MJVr[`!%#Q0QEf`0!)i!!@d!!!#+!)d!M``!M`!0!!G[F'9ZFh0X!!)!!!d!M3!
+#0!!!!(m!Krqq!*!!#[qq!!3+BfC[E!d!N!!!!@m!!!#$!)Er[3[r[3!Q-!!4D@j
+ME(9NC@C[E'4PFR"KG'J!%@PZBfaeC'9'EfaNCA*3BA4S![r!!!!#!)S!!J#4rl`
+0!*%!!dN!!J#6!*crZ`#5rlS+rlX!'#jMEh*PC'9XEbSU+LS!!!!!!!#3!!!U+LS
+U$3#5!!%a!!!!N`#BrlN+rlN!"!TcC@aP![qk!!!#rl`!!!d!KJ!$8J!!!!!!!2q
+irlIrYJVrZ!!B,Q&cBh*PFR)J+LSU+J!!!!!!!*!!!#SU+LS"rlF!!!,rYJ!!$3#
+(!!*X!!%!T!#Nrl8!N`(rY3!!$!#6!"-!$5"TCfj[FQ8JCA*bEh)!!J!!!J#%!!)
+!P!#9$3#8!!*X!!)!TJ#Qrl6rX`(rY!!!!Iqc!!!#!*8!!J#@!*F0!*B!!dN!!J#
+Q!,lrX[qa!*J+rl)!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@aX!Iqa!!!'!*J
+!!rq`!*N!QJVrX!!%#QY[Bf`0!*N!!@d!!!#U!+hrV`VrV`!%#Q0QEf`'!*S!!rq
+Z!*[rV3VrVJ!%#QPZFfJ0!*X!!M3!!!#`!,MrV!#F#[qX!!3+BfC[E!d!R!!"E`!
+!!,3!YrqV#rqV!#B`!"&TEQ0XG@4PCQpXC'9bF'&dD!!4D@jME(9NC8C[E'4PFP"
+KG'J'rkd!!!)!P`!#!*d!RJd!R3!#FJ!!!,m!aJ#I!+!0!*m!!Q`"!!#r!-)!SIq
+U$3#K!!%a!!!![`$#rkN+rkN!"!TbFfad!IqU!!!0!+!!!@m!!!!!!!$rU![rU!!
+Z-!!9G'KPEQ9hCQpXC'9bFQ9QCA*PEQ0P!"9dD'91CAG'EfaNCA*5C@CPFQ9ZBf8
+#!*i!!J#L!+-0!+)!!dN!!J$(!-lrT`#NrkB+rkF!'#jYDA0MFfaMG#SU+LS!!!!
+!!!#3!!!U+LSU$3#N!!&[!!!!a`$+rk8,rk8!,M!!&A4SC@jPGfC[E'4PFR*PCQ9
+bC@jMC3!9G'KP6Q9h4QpXC'9b8Q9QCA*PEQ0P![qQ!!!#!+-!!J#P!+B0!+8!!R)
+!!!$2!0`!T`#S$3#R!!&Y!!!!c`$5!+N-!+N!$3!(Eh"PER0cE!!#!!!0!+J!!Qi
+!!!!!!!!!UJ#V$3#U!!%a!!!!e`$Erk3+rk3!"!T`EQ&Y$3#V!!%a!!!!dJ$Ark-
++rk-!"!TcC@aP!J#Q!!)!V!#Y$3#X!!*X!!)!h3$Grk,rS3(rSJ!!!IqK!!!#!+d
+!!J#Z!+m0!+i!!Q`!!3$G!0hrS!#`!IqJ!!!-!,!!(`!C)&0dBA*d)'eKDfPZCb"
+dD'8JB@aTBA0PF`!#!!!#!+m!!J#a!,)0!,%!!dN!!J$G!3ArRrqH!,-+rjm!'#j
+MEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@aX!IqH!!!'!,-!!rqG!,3!Y3VrR3!%#QY
+[Bf`0!,3!!@d!!!$K!16rR!VrR!!%#Q&XD@%'!,8!!rqE!,B!Y`VrQ`!%#QPZFfJ
+0!,B!!M3!!!$R!1rrQJ#i#[qD!!3+BfC[E!d!Z!!"E`!!!1X!l[qC#rqC!$3`!"K
+[F'9ZFh0XD@jME(9NC@C[E'4PFR"KG'J!''p`C@j68da*EQ0XG@4P4QpXC'9b8'&
+dD!B!Y`!$rjJ!ZIqA#[qB!!3+G'mJ)!d!Z3!#EJ!!!2)!r`#k!,X0!,S!!M3!!!$
+i!2rrPJ#m#[q@!!3+CQPXC3d![!!"E3!!!2X!rJ#p$!#p!"-!$@p`C@jcFfaMEfj
+Q,QJ!!J!!$3#l!!)d!!!!mJ$irj8![JVrP3!%#Q0QEf`0!,i!!@m!!!$f!2IrP![
+rP!!@-!!*G'KPE@9`BA4S!!PdD'90C9"KG'J'rjF!!!)!XJ!#!,m!`!d![`!#E!!
+#!3B""[q6rj)"rj-!!!(rNJ!!!J$!!!)!`3$#$3$"!!*b!!!""J%4!--!a!d!``!
+#BJ!!!3B"$3$&!-B0!-8!!@m!!!%'!3RrN3[rN3!N-!!3Bh*jF(4[CQpXC'9bF'&
+dD!!3Bh*jF(4[4QpXC'9b8'&dD!d!aJ!"E3!!!3N"$!$($!$(!!X!"6TKFfia!!)
+!!!d!a!!"E`!!!!!!!2q3!![rN!!!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!)!`J!
+#!-J!b3d!b!!$53!#!4)"22q2rii!bJVrM`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!
+!!'jeE'`"rii!!!B!bJ!$rid!b`$-#[q0!!3+DfpME!d!b`!"E3!!!4B"'Iq-#[q
+-!!3+B@aTB3B!c!!$riX!c3$1#[q,!!3+D@jcD!d!c3!#0!!!!4`"*2q+!-m+riS
+!"!TMCQpX$3$2!!&[!!!")!%MriN,riN!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9
+bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J$1!!2rL!$3riF+riJ!"!T
+dEb!J$3$3!!*Z!!!"*`%f!0%!dJd!d3!#0!!!!5m"0[q'!0-+riB!"!TQD@aP$3$
+6!!&Y!!!"-J%e!03-!03!$!!'BA0Z-5jS!!)!!!d!dJ!#0!!!!5F",rq&!08+ri8
+!"!TMCQpX$3$9!!&[!!!"+`%Zri3,ri3!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!E
+rK`!!!J$*!!)!eJ$A$3$@!!0*!!)"23&Rri2rJJ$B#[q$!"JZBfpbC@0bC@`U+LS
+U!!!!!!!!N!!!ER9XE!(rJJ!!"J$B!!2rJ3$C!0S+ri%!"!TVEf0X$3$C!!&Y!!!
+"33&%ri!+ri!!"!TKE'PK"J$D!!2rI`$E!0`+rhm!"!TTER0S$3$E!!)d!!!"4`&
+2rhi!h3VrIJ!%#Q0QEf`0!0d!!@m!!!&,!8lrI3[rI3!d-!!BEh"PER0cE'PZBfa
+eC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'!0`!!rpm!0l
+rH`VrI!!%#R4[)#!0!0i!!Qi!!!&5!@%!h`$J$3$I!!)d!!!"@J&KrhS!i3VrHJ!
+%#QCTE'80!1%!!@d!!!&G!@!!iJ`!iJ!3!!TKFfiaAfeKBbjS!!)!!!d!i!!#0!!
+!!9)"@[pj!1-+rhN!"!TMCQpX$3$M!!&[!!!"9J&CrhJ,rhJ!&$!!#(4PEA"`BA4
+S!!KdC@e`8'&dD!ErH`!!!J$A!!)!j!$P$3$N!!*X!!)"D!&SrhIrGJ(rG`!!!Ip
+f!!!#!18!!J$Q!1F0!1B!!R)!!!&S!A-!k!$T$3$S!!*L!!!"D!&[!1S!k`d!kJ!
+"E`!!!@J"Drpe#rpe!#3`!""MFRP`G'pQEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*
+3BA4S$3$V!!&Y!!!"D`&Z!1`-!1`!#J!%1Q*TE`!#!!!0!1N!!@m!!!!!!!$rG![
+rG!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S!J$R!!)!l3$Z$3$Y!!0*!!)"G!'Hrh2
+rFJ$[#[pc!"JZBfpbC@0bC@`U+LSU!!!!!!!!N!!!ER9XE!(rFJ!!"J$[!!2rF3$
+`!2%+rh%!"!TVEf0X$3$`!!&Y!!!"H!&lrh!+rh!!"!TKE'PK"J$a!!2rE`$b!2-
++rfm!"!TTER0S$3$b!!)d!!!"IJ''rfi!p!VrEJ!%#Q0QEf`0!23!!@m!!!'#!BA
+rE3[rE3!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9
+NC8C[E'4PFP"KG'J'!2-!!rpX!2ArD`VrE!!%#R4[)#!0!28!!Qi!!!'*!CJ!pJ$
+h$3$f!!)d!!!"N3'BrfS!q!VrDJ!%#QCTE'80!2J!!@d!!!'8!CF!q3`!q3!,!!9
+LD@mZD!!#!!!0!2F!!M3!!!'*!C(rD3$k#[pT!!3+BfC[E!d!qJ!"E`!!!Bd"N!$
+rD![rD!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S"[pV!!!#!1i!!J$l!2`0!2X!!Q`
+!!J'I!CrrCrpQ!IpR!!!"rfB!!!)!r!!#!2d!rJd!r3!#FJ!!!Cm"UJ$r!3!0!2m
+!!Q)!!!'I!DB"!3%#$3%"!!&[!!!"R`'Lrf8,rf8!*$!!%'0bHA"dEfC[E'4PFR"
+KG'J!%'0bHA"dEdC[E'4PFP"KG'J0!3)!!@d!!!'L!D8"!``"!`!*!!-kBQB!!J!
+!$3%!!!&[!!!!!!!!rf3,rf3!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!)!rJ!#!33
+""3d""!!$53!#!DX"eIpMrf)""JVrB`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'j
+eE'`"rf)!!!B""J!$rf%""`%)#[pK!!3+DfpME!d""`!"E3!!!Dm"X[pJ#[pJ!!3
++B@aTB3B"#!!$rem"#3%+#[pI!!3+D@jcD!d"#3!#0!!!!E8"[IpH!3X+rei!"!T
+MCQpX$3%,!!&[!!!"Z3'mred,red!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&
+dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J%+!!2rA!%-reX+re`!"!TdEb!
+J$3%-!!*Z!!!"`!(2!3d"$Jd"$3!#0!!!!FJ"crpD!3m+reS!"!TQD@aP$3%2!!&
+Y!!!"b`(1!4!-!4!!%!!+BQa[GfCTFfJZD!!#!!!0!3i!!M3!!!(!!FMr@3%4#[p
+C!!3+BfC[E!d"%3!"E`!!!F3"arpB#rpB!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J
+'reX!!!)""3!#!4)"%`d"%J!#E!!#!GB"e[pAreB"reF!!!(r9J!!!J%6!!)"&!%
+9$3%8!!*b!!!"eJ(K!4B"&`d"&J!#BJ!!!GB"h3%B!4N0!4J!!@m!!!(@!GRr93[
+r93!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD!d"'3!"E3!
+!!GN"h!%D$!%D!!N!!cTLEJ!#!!!0!4F!!@m!!!!!!!$r9![r9!!8-!!)G'9YF("
+KG'J!#(4PEA"3BA4S!J%9!!)"'`%F$3%E!!0*!!)"iJ)-re2r8J%G#[p6!"JZBfp
+bC@0bC@`U+LSU!!!!!!!!N!!!ER9XE!(r8J!!"J%G!!2r83%H!4m+re%!"!TVEf0
+X$3%H!!&Y!!!"jJ(Tre!+re!!"!TKE'PK"J%I!!2r6`%J!5%+rdm!"!TTER0S$3%
+J!!)d!!!"l!(drdi")JVr6J!%#Q0QEf`0!5)!!@m!!!(`!I2r63[r63!d-!!BEh"
+PER0cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J
+'!5%!!rp-!52r5`Vr6!!%#R4[)#!0!5-!!Qi!!!(h!JB"*!%P$3%N!!)d!!!"r`)
+'rdS"*JVr5J!%#QCTE'80!5B!!@d!!!)#!J8"*``"*`!+!!4LELjS!!)!!!d"*3!
+#0!!!!IF"rrp*!5J+rdN!"!TMCQpX$3%S!!&[!!!"q`(qrdJ,rdJ!&$!!#(4PEA"
+`BA4S!!KdC@e`8'&dD!Er5`!!!J%F!!)"+3%U$3%T!!*X!!)#$3)0rdIr4J(r4`!
+!!Ip'!!!#!5S!!J%V!5`0!5X!!R)!!!)0!KJ",3%Z$3%Y!!*L!!!#$3)8!5m"-!d
+",`!"E`!!!Jd#%2p&#rp&!#3`!""MFRP`G'pQEfaNCA*`BA4S!""MFRP`G'p'Efa
+NCA*3BA4S$3%`!!&Y!!!#%!)6!6%-!6%!$3!(1Q*eCQCPFJ!#!!!0!5i!!@m!!!!
+!!!$r4![r4!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S!J%X!!)"-J%c$3%b!!0*!!)
+#'3*$rd2r3J%d#[p$!"JZBfpbC@0bC@`U+LSU!!!!!!!!N!!!ER9XE!(r3J!!"J%
+d!!2r33%e!6B+rd%!"!TVEf0X$3%e!!&Y!!!#(3)Jrd!+rd!!"!TKE'PK"J%f!!2
+r2`%h!6J+rcm!"!TTER0S$3%h!!)d!!!#)`)Vrci"13Vr2J!%#Q0QEf`0!6N!!@m
+!!!)R!LVr23[r23!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0
+-5@jME(9NC8C[E'4PFP"KG'J'!6J!!rmm!6Vr1`Vr2!!%#R4[)#!0!6S!!Qi!!!)
+Z!Md"1`%m$3%l!!)d!!!#0J)prcS"23Vr1J!%#QCTE'80!6d!!@d!!!)j!M`"2J`
+"2J!1!!KLG@CQCA)ZD!!#!!!0!6`!!M3!!!)Z!MEr13%r#[mj!!3+BfC[E!d"2`!
+"E`!!!M)#0Imi#rmi!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J'rcX!!!)"-`!#!8!
+"33d"3!!#E!!#!N3#42mhrcB"rcF!!!(r0J!!!J&"!!)"3J&$$3&#!!*b!!!#4!*
+2!83"43d"4!!#BJ!!!N3#5`&'!8F0!8B!!@m!!!*%!NIr03[r03!N-!!3Bh*jF(4
+[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD!d"4`!"E3!!!NF#5J&)$!&)!!X
+!"6TMBA0d!!)!!!d"43!"E`!!!!!!!2md#rmd!"3`!!KdC@e`F'&dD!!)G'9YF&"
+KG'J#!8-!!J&*!8S0!8N!!dN!!J*3!RVr-rmb!8X+rc-!'#jMEh*PBh*PE#SU+LS
+!!!!!!!#3!!"ZG@aX!Imb!!!'!8X!!rma!8`"63Vr-3!%#QY[Bf`0!8`!!@d!!!*
+8!PIr-!Vr-!!%#Q&XD@%'!8d!!rm[!8i"6`Vr,`!%#QPZFfJ0!8i!!M3!!!*D!Q,
+r,J&3#[mZ!!3+BfC[E!d"8!!"E`!!!Pi#BImY#rmY!$3`!"K[F'9ZFh0XD@jME(9
+NC@C[E'4PFR"KG'J!''p`C@j68da*EQ0XG@4P4QpXC'9b8'&dD!B"6`!$rb`"8Im
+V#[mX!!3+G'mJ)!d"83!#EJ!!!Q8#G!&5!9-0!9)!!M3!!!*Y!R6r+J&8#[mU!!3
++CQPXC3d"9!!"E3!!!R!#F`&9$!&9!!`!"Q0KFh3ZD!!#!!!0!9-!!M3!!!*P!Qh
+r+3&@#[mT!!3+BfC[E!d"9J!"E`!!!QN#E2mS#rmS!"3`!!KdC@e`F'&dD!!)G'9
+YF&"KG'J'rbX!!!)"5J!#!9F"@!d"9`!#E!!#!RX#HrmRrbB"rbF!!!(r*J!!!J&
+B!!)"@3&D$3&C!!*b!!!#H`+'!9X"A!d"@`!#BJ!!!RX#JJ&G!9i0!9d!!@m!!!*
+l!Rlr*3[r*3!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD!d
+"AJ!"E3!!!Ri#J3&I$!&I!!X!"6TMEfe`!!)!!!d"A!!"E`!!!!!!!2mN#rmN!"3
+`!!KdC@e`F'&dD!!)G'9YF&"KG'J#!9S!!J&J!@%0!@!!!dN!!J+(!V(r)rmL!@)
++rb-!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@aX!ImL!!!'!@)!!rmK!@-"C!V
+r)3!%#QY[Bf`0!@-!!@d!!!+,!Slr)!Vr)!!%#Q&XD@%'!@3!!rmI!@8"CJVr(`!
+%#QPZFfJ0!@8!!M3!!!+4!TRr(J&R#[mH!!3+BfC[E!d"C`!"E`!!!T8#Q2mG#rm
+G!$3`!"K[F'9ZFh0XD@jME(9NC@C[E'4PFR"KG'J!''p`C@j68da*EQ0XG@4P4Qp
+XC'9b8'&dD!B"CJ!$ra`"D2mE#[mF!!3+G'mJ)!d"D!!#EJ!!!T`#U`&T!@S0!@N
+!!M3!!!+N!U[r'J&V#[mD!!3+CQPXC3d"D`!"E3!!!UF#UJ&X$!&X!!`!"Q0[EA!
+ZD!!#!!!0!@S!!M3!!!+F!U6r'3&Y#[mC!!3+BfC[E!d"E3!"E`!!!U!#SrmB#rm
+B!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J'raX!!!)"B3!#!@i"E`d"EJ!#E!!#!V)
+#X[mAraB"raF!!!(r&J!!!J&[!!)"F!&a$3&`!!*b!!!#XJ+p!A)"F`d"FJ!#BJ!
+!!V)#Z3&d!A80!A3!!@m!!!+b!VAr&3[r&3!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!
+3Bh*jF(4[4QpXC'9b8'&dD!d"G3!"E3!!!V8#Z!&f$!&f!!X!"6TMEfjQ!!)!!!d
+"F`!"E`!!!!!!!2m8#rm8!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J#!A%!!J&h!AJ
+0!AF!!dN!!J+q!ZMr%rm5!AN+ra-!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@a
+X!Im5!!!'!AN!!rm4!AS"H`Vr%3!%#QY[Bf`0!AS!!@d!!!,#!XAr%!Vr%!!%#Q&
+XD@%'!AX!!rm2!A`"I3Vr$`!%#QPZFfJ0!A`!!M3!!!,)!Y$r$J&q#[m1!!3+BfC
+[E!d"IJ!"E`!!!X`#crm0#rm0!$3`!"K[F'9ZFh0XD@jME(9NC@C[E'4PFR"KG'J
+!''p`C@j68da*EQ0XG@4P4QpXC'9b8'&dD!B"I3!$r``"Irm,#[m-!!3+G'mJ)!d
+"I`!#EJ!!!Y-#iJ'!!B%0!B!!!M3!!!,E!Z,r#J'##[m+!!3+CQPXC3d"JJ!"E3!
+!!Yi#i3'$$!'$!!`!"Q0[EQBZD!!#!!!0!B%!!M3!!!,6!Y[r#3'%#[m*!!3+BfC
+[E!d"K!!"E`!!!YF#f[m)#rm)!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J'r`X!!!)
+"H!!#!B8"KJd"K3!#E!!#!ZN#kIm(r`B"r`F!!!(r"J!!!J''!!)"K`')$3'(!!*
+b!!!#k3,d!BN"LJd"L3!#BJ!!!ZN#m!',!B`0!BX!!@m!!!,T!Zcr"3[r"3!N-!!
+3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD!d"M!!"E3!!!Z`#l`'
+0$!'0!!S!"$TNCA-!!J!!$3'+!!&[!!!!!!!!r`3,r`3!&$!!#(4PEA"`BA4S!!K
+dC@e`8'&dD!)"L!!#!Bi"M`d"MJ!$53!#![8$(rm$r`)"N!!+r`-!'#jMEh*PBh*
+PE#SU+LS!!!!!!!#3!!"ZG@aX!Im#!!!'!C!!!!2r!3'4!C)+r`%!"!TVEf0X$3'
+4!!&Y!!!#q3,mr`!+r`!!"!TKE'PK"J'5!!2qr`'6!C3+r[m!"!TTER0S$3'6!!)
+d!!!#r`-(r[i"P3VqrJ!%#Q0QEf`0!C8!!@m!!!-$!`Eqr3[qr3!d-!!BEh"PER0
+cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'!C3
+!!rlm!CEqq`Vqr!!%#R4[)#!0!CB!!Qi!!!-+!aN"P`'B$3'A!!)d!!!$%J-Cr[S
+"Q3VqqJ!%#QCTE'80!CN!!@d!!!-9!aJ"QJ`"QJ!,!!9NCA-ZD!!#!!!0!CJ!!M3
+!!!-+!a,qq3'E#[lj!!3+BfC[E!d"Q`!"E`!!!`i$%Ili#rli!"3`!!KdC@e`F'&
+dD!!)G'9YF&"KG'J'r[X!!!)"M`!#!C`"R3d"R!!#E!!#!b!$)2lhr[B"r[F!!!(
+qpJ!!!J'G!!)"RJ'I$3'H!!*b!!!$)!-V!D!"S3d"S!!#BJ!!!b!$*`'L!D-0!D)
+!!@m!!!-J!b2qp3[qp3!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9
+b8'&dD!d"S`!"E3!!!b-$*J'N$!'N!!N!!cTND!!#!!!0!D%!!@m!!!!!!!$qp![
+qp!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S!J'I!!)"T3'Q$3'P!!0*!!)$,!0@r[2
+qmJ'R#[lc!"JZBfpbC@0bC@`U+LSU!!!!!!!!N!!!ER9XE!(qmJ!!"J'R!!2qm3'
+S!DN+r[%!"!TVEf0X$3'S!!&Y!!!$-!-cr[!+r[!!"!TKE'PK"J'T!!2ql`'U!DX
++rZm!"!TTER0S$3'U!!)d!!!$0J-qrZi"V!VqlJ!%#Q0QEf`0!D`!!@m!!!-k!ch
+ql3[ql3!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9
+NC8C[E'4PFP"KG'J'!DX!!rlX!Dhqk`Vql!!%#R4[)#!0!Dd!!Qi!!!0"!e!"VJ'
+[$3'Z!!)d!!!$5303rZS"X!VqkJ!%#QCTE'80!E!!!@d!!!0-!dm"X3`"X3!+!!4
+ND#jS!!)!!!d"V`!#0!!!!d%$5IlT!E)+rZN!"!TMCQpX$3'b!!&[!!!$430)rZJ
+,rZJ!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!Eqk`!!!J'Q!!)"X`'d$3'c!!*X!!)
+$9`0ArZIqjJ(qj`!!!IlQ!!!#!E3!!J'e!EB0!E8!!R)!!!0A!f)"Y`'i$3'h!!*
+L!!!$9`0H!EN"ZJd"Z3!"E`!!!eF$@[lP#rlP!#3`!""MFRP`G'pQEfaNCA*`BA4
+S!""MFRP`G'p'EfaNCA*3BA4S$3'k!!&Y!!!$@J0G!EX-!EX!#J!%1Q4cB3!#!!!
+0!EJ!!@m!!!!!!!$qj![qj!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S!J'f!!)"[!'
+p$3'm!!0*!!)$B`10rZ2qiJ'q#[lM!"JZBfpbC@0bC@`U+LSU!!!!!!!!N!!!ER9
+XE!(qiJ!!"J'q!!2qi3'r!F!+rZ%!"!TVEf0X$3'r!!&Y!!!$C`0UrZ!+rZ!!"!T
+KE'PK"J(!!!2qh`("!F)+rYm!"!TTER0S$3("!!)d!!!$E30erYi"``VqhJ!%#Q0
+QEf`0!F-!!@m!!!0a!h6qh3[qh3!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4
+S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'!F)!!rlF!F6qf`Vqh!!%#R4[)#!
+0!F3!!Qi!!!0i!iF"a3('$3(&!!)d!!!$J!1(rYS"a`VqfJ!%#QCTE'80!FF!!@d
+!!!1$!iB"b!`"b!!,!!9NFf%ZD!!#!!!0!FB!!M3!!!0i!i$qf3(*#[lC!!3+BfC
+[E!d"b3!"E`!!!h`$IrlB#rlB!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J'rYX!!!)
+"[3!#!FS"b`d"bJ!#E!!#!ii$M[lArYB"rYF!!!(qeJ!!!J(,!!)"c!(0$3(-!!*
+b!!!$MJ1C!Fi"c`d"cJ!#BJ!!!ii$P3(3!G%0!G!!!@m!!!11!j(qe3[qe3!N-!!
+3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD!d"d3!"E3!!!j%$P!(
+5$!(5!!S!"$TPFR)!!J!!$3(2!!&[!!!!!!!!rY3,rY3!&$!!#(4PEA"`BA4S!!K
+dC@e`8'&dD!)"c3!#!G-"e!d"d`!$53!#!jS$a2l6rY)"e3Vqd`!B,Q0[FQ9MFQ9
+X+LSU+J!!!!!!!*!!!'jeE'`"rY)!!!B"e3!$rY%"eJ(A#[l4!!3+DfpME!d"eJ!
+"E3!!!ji$SIl3#[l3!!3+B@aTB3B"e`!$rXm"f!(C#[l2!!3+D@jcD!d"f!!#0!!
+!!k3$V2l1!GS+rXi!"!TMCQpX$3(D!!&[!!!$U!1VrXd,rXd!0$!!''p`C@jcFfa
+TEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J(C!!2
+qc!(ErXX+rX`!"!TdEb!J$3(E!!*Z!!!$V`1q!G`"h3d"h!!#0!!!!lF$[[l+!Gi
++rXS!"!TQD@aP$3(H!!&Y!!!$ZJ1p!Gm-!Gm!#`!&CA*b,QJ!!J!!$3(G!!)d!!!
+$V`1hrXN"i!Vqb3!%#Q0QEf`0!H!!!@m!!!1c!lEqb![qb!!8-!!)G'9YF("KG'J
+!#(4PEA"3BA4S"[l,!!!#!G3!!J(K!H)0!H%!!Q`!!J2&!mAqarl'!Il(!!!"rXB
+!!!)"iJ!#!H-"j!d"i`!#FJ!!!m8$d!(P!HB0!H8!!Q)!!!2&!m`"j`(S$3(R!!&
+[!!!$a32)rX8,rX8!*$!!%'0bHA"dEfC[E'4PFR"KG'J!%'0bHA"dEdC[E'4PFP"
+KG'J0!HJ!!@d!!!2)!mX"k3`"k3!+!!3kCAC`!!)!!!d"jJ!"E`!!!!!!!2l%#rl
+%!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J#!H3!!J(U!HX0!HS!!dN!!J24!r[q`rl
+#!H`+rX-!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@aX!Il#!!!'!H`!!rl"!Hd
+"lJVq`3!%#QY[Bf`0!Hd!!@d!!!29!pMq`!Vq`!!%#Q&XD@%'!Hi!!rkr!Hm"m!V
+q[`!%#QPZFfJ0!Hm!!M3!!!2E!q2q[J(a#[kq!!3+BfC[E!d"m3!"E`!!!pm$i[k
+p#rkp!$3`!"K[F'9ZFh0XD@jME(9NC@C[E'4PFR"KG'J!''p`C@j68da*EQ0XG@4
+P4QpXC'9b8'&dD!B"m!!$rV`"m[kl#[km!!3+G'mJ)!d"mJ!#EJ!!!qB$p3(c!I3
+0!I-!!M3!!!2Z!rAqZJ(e#[kk!!3+CQPXC3d"p3!"E3!!!r%$p!(f$!(f!!X!"@9
+fF#jS!!)!!!d"p!!#0!!!!qB$l[kj!IF+rVN!"!TMCQpX$3(h!!&[!!!$kJ2YrVJ
+,rVJ!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!EqZ`!!!J(V!!)"q!(j$3(i!!*X!!)
+$r!2mrVIqYJ(qY`!!!Ikf!!!#!IN!!J(k!IX0!IS!!R)!!!2m"!F"r!(p$3(m!!*
+L!!!$r!3$!Ii"r`d"rJ!"E`!!!r`$rrke#rke!#3`!""MFRP`G'pQEfaNCA*`BA4
+S!""MFRP`G'p'EfaNCA*3BA4S$3(r!!&Y!!!$r`3#!J!-!J!!#`!&1QKYB@-!!J!
+!$3(p!!&[!!!!!!!!rV3,rV3!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!)"q`!#!J%
+#!Jd#!3!$53!#"!J%-[kcrV)#!`VqX`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'j
+eE'`"rV)!!!B#!`!$rV%#"!)&#[ka!!3+DfpME!d#"!!"E3!!"!`%$rk`#[k`!!3
++B@aTB3B#"3!$rUm#"J)(#[k[!!3+D@jcD!d#"J!#0!!!"")%'[kZ!JJ+rUi!"!T
+MCQpX$3))!!&[!!!%&J3CrUd,rUd!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&
+dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J)(!!2qV!)*rUX+rU`!"!TdEb!
+J$3)*!!*Z!!!%(33X!JS##`d##J!#0!!!"#8%,2kU!J`+rUS!"!TQD@aP$3)-!!&
+Y!!!%+!3V!Jd-!Jd!$!!'D'eKBbjS!!)!!!d##`!#0!!!""d%*IkT!Ji+rUN!"!T
+MCQpX$3)1!!&[!!!%)33NrUJ,rUJ!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!EqU`!
+!!J)#!!)#$`)3$3)2!!*X!!)%-`3crUIqTJ(qT`!!!IkQ!!!#!K!!!J)4!K)0!K%
+!!R)!!!3c"$i#%`)8$3)6!!*L!!!%-`3k!K8#&Jd#&3!"E`!!"$-%0[kP#rkP!#3
+`!""MFRP`G'pQEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S$3)@!!&Y!!!%0J3
+j!KF-!KF!#`!&1QPNC@%!!J!!$3)8!!&[!!!!!!!!rU3,rU3!&$!!#(4PEA"`BA4
+S!!KdC@e`8'&dD!)#%J!#!KJ#'3d#'!!$53!#"$m%DIkMrU)#'JVqS`!B,Q0[FQ9
+MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"rU)!!!B#'J!$rU%#'`)F#[kK!!3+DfpME!d
+#'`!"E3!!"%-%4[kJ#[kJ!!3+B@aTB3B#(!!$rTm#(3)H#[kI!!3+D@jcD!d#(3!
+#0!!!"%N%8IkH!Km+rTi!"!TMCQpX$3)I!!&[!!!%6343rTd,rTd!0$!!''p`C@j
+cFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J)
+H!!2qR!)JrTX+rT`!"!TdEb!J$3)J!!*Z!!!%9!4M!L%#)Jd#)3!#0!!!"&`%Brk
+D!L-+rTS!"!TQD@aP$3)M!!&Y!!!%A`4L!L3-!L3!$!!'D@4PB5jS!!)!!!d#)J!
+#0!!!"&3%A2kC!L8+rTN!"!TMCQpX$3)P!!&[!!!%@!4ErTJ,rTJ!&$!!#(4PEA"
+`BA4S!!KdC@e`8'&dD!EqQ`!!!J)C!!)#*J)R$3)Q!!*X!!)%DJ4UrTIqPJ(qP`!
+!!Ik@!!!#!LF!!J)S!LN0!LJ!!R)!!!4U"(8#+J)V$3)U!!*L!!!%DJ4a!L`#,3d
+#,!!"E`!!"'S%EIk9#rk9!#3`!""MFRP`G'pQEfaNCA*`BA4S!""MFRP`G'p'Efa
+NCA*3BA4S$3)Y!!&Y!!!%E34`!Li-!Li!$!!'1QaSBA0S!!)!!!d#+`!"E`!!!!!
+!!2k8#rk8!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J#!LN!!J)[!M!0!Lm!!dN!!J4
+f"+$qNrk5!M%+rT-!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@aX!Ik5!!!'!M%
+!!rk4!M)#-`VqN3!%#QY[Bf`0!M)!!@d!!!4k"(hqN!!+rT!!!!3+B@aTB3B#-`!
+$rSm#0!)e#[k2!!3+D@jcD!d#0!!#0!!!")!%L2k1!MB+rSi!"!TMCQpX$3)f!!&
+[!!!%K!5(rSd,rSd!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP0
+66%PZBfaeC'9'EfaNCA*3BA4S"J)e!!2qM!)hrSX+rS`!"!TdEb!J$3)h!!*Z!!!
+%L`5D!MJ#13d#1!!#0!!!"*-%Q[k+!MS+rSS!"!TQD@aP$3)k!!&Y!!!%PJ5C!MX
+-!MX!$3!(E'KKFfJZD!!#!!!0!MN!!M3!!!5,"*2qL3)m#[k*!!3+BfC[E!d#2!!
+"E`!!")m%N[k)#rk)!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J'rSX!!!)#-!!#!Md
+#2Jd#23!#E!!#"+%%SIk(rSB"rSF!!!(qKJ!!!J)q!!)#2`*!$3)r!!*b!!!%S35
+X!N%#3Jd#33!#BJ!!"+%%U!*$!N30!N-!!@m!!!5K"+6qK3[qK3!N-!!3Bh*jF(4
+[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD!d#4!!"E3!!"+3%T`*&$!*&!!S
+!"$TYC$)!!J!!$3*#!!&[!!!!!!!!rS3,rS3!&$!!#(4PEA"`BA4S!!KdC@e`8'&
+dD!)#3!!#!NB#4`d#4J!$53!#"+d%erk$rS)#5!VqJ`!B,Q0[FQ9MFQ9X+LSU+J!
+!!!!!!*!!!'jeE'`"rS)!!!B#5!!$rS%#53*+#[k"!!3+DfpME!d#53!"E3!!",%
+%Y2k!#[k!!!3+B@aTB3B#5J!$rRm#5`*-#[jr!!3+D@jcD!d#5`!#0!!!",F%[rj
+q!Nd+rRi!"!TMCQpX$3*0!!&[!!!%Z`5qrRd,rRd!0$!!''p`C@jcFfaTEQ0XG@4
+PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J*-!!2qI!*1rRX
++rR`!"!TdEb!J$3*1!!*Z!!!%`J64!Nm#8!d#6`!#0!!!"-S%dIjk!P%+rRS!"!T
+QD@aP$3*4!!&Y!!!%c363!P)-!P)!#`!&E@3b,QJ!!J!!$3*3!!)d!!!%`J6+rRN
+#8`VqH3!%#Q0QEf`0!P-!!@m!!!6'"-RqH![qH!!8-!!)G'9YF("KG'J!#(4PEA"
+3BA4S"[jl!!!#!NF!!J*8!P80!P3!!Q`!!J6B"0MqGrjf!Ijh!!!"rRB!!!)#93!
+#!PB#9`d#9J!#FJ!!"0J%i`*B!PN0!PJ!!Q)!!!6B"0m#@J*E$3*D!!&[!!!%f!6
+ErR8,rR8!*$!!%'0bHA"dEfC[E'4PFR"KG'J!%'0bHA"dEdC[E'4PFP"KG'J0!PX
+!!@d!!!6E"0i#A!`#A!!+!!3kE@3e!!)!!!d#@3!"E`!!!!!!!2jd#rjd!"3`!!K
+dC@e`F'&dD!!)G'9YF&"KG'J#!PF!!J*G!Pi0!Pd!!dN!!J6N"3lqFrjb!Pm+rR-
+!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@aX!Ijb!!!'!Pm!!rja!Q!#B3VqF3!
+%#QY[Bf`0!Q!!!@d!!!6S"1[qF!VqF!!%#Q&XD@%'!Q%!!rj[!Q)#B`VqE`!%#QP
+ZFfJ0!Q)!!M3!!!6Z"2EqEJ*N#[jZ!!3+BfC[E!d#C!!"E`!!"2)%pIjY#rjY!$3
+`!"K[F'9ZFh0XD@jME(9NC@C[E'4PFR"KG'J!''p`C@j68da*EQ0XG@4P4QpXC'9
+b8'&dD!B#B`!$rQ`#CIjV#[jX!!3+G'mJ)!d#C3!#EJ!!"2N&#!*Q!QF0!QB!!M3
+!!!8""3MqDJ*S#[jU!!3+CQPXC3d#D!!"E3!!"33&"`*T$!*T!!X!"@eN05jS!!)
+!!!d#C`!#0!!!"2N&!IjT!QS+rQN!"!TMCQpX$3*U!!&[!!!%r38!rQJ,rQJ!&$!
+!#(4PEA"`BA4S!!KdC@e`8'&dD!EqD`!!!J*H!!)#D`*X$3*V!!*X!!)&$`82rQI
+qCJ(qC`!!!IjQ!!!#!Q`!!J*Y!Qi0!Qd!!R)!!!82"4S#E`*`$3*[!!*L!!!&$`8
+@!R%#FJd#F3!"E`!!"3m&%[jP#rjP!#3`!""MFRP`G'pQEfaNCA*`BA4S!""MFRP
+`G'p'EfaNCA*3BA4S$3*b!!&Y!!!&%J89!R--!R-!#`!&1QeNBc)!!J!!$3*`!!&
+[!!!!!!!!rQ3,rQ3!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!)#EJ!#!R3#G3d#G!!
+$53!#"4X&4IjMrQ)#GJVqB`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"rQ)
+!!!B#GJ!$rQ%#G`*i#[jK!!3+DfpME!d#G`!"E3!!"4m&)[jJ#[jJ!!3+B@aTB3B
+#H!!$rPm#H3*k#[jI!!3+D@jcD!d#H3!#0!!!"58&,IjH!RX+rPi!"!TMCQpX$3*
+l!!&[!!!&+38XrPd,rPd!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"
+PEP066%PZBfaeC'9'EfaNCA*3BA4S"J*k!!2qA!*mrPX+rP`!"!TdEb!J$3*m!!*
+Z!!!&-!8r!Rd#IJd#I3!#0!!!"6J&2rjD!Rm+rPS!"!TQD@aP$3*r!!&Y!!!&1`8
+q!S!-!S!!$!!'E@4M-LjS!!)!!!d#IJ!#0!!!"6!&12jC!S%+rPN!"!TMCQpX$3+
+"!!&[!!!&0!8hrPJ,rPJ!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!Eq@`!!!J*e!!)
+#JJ+$$3+#!!*X!!)&4J9'rPIq9J(q9`!!!Ij@!!!#!S-!!J+%!S80!S3!!R)!!!9
+'"9%#KJ+($3+'!!*L!!!&4J90!SJ#L3d#L!!"E`!!"8B&5Ij9#rj9!#3`!""MFRP
+`G'pQEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S$3+*!!&Y!!!&539-!SS-!SS
+!$J!)1QpLDQ9MG(-!!J!!$3+(!!&[!!!!!!!!rP3,rP3!&$!!#(4PEA"`BA4S!!K
+dC@e`8'&dD!)#K3!#!SX#M!d#L`!$53!#"9)&I2j6rP)#M3Vq8`!B,Q0[FQ9MFQ9
+X+LSU+J!!!!!!!*!!!'jeE'`"rP)!!!B#M3!$rP%#MJ+2#[j4!!3+DfpME!d#MJ!
+"E3!!"9B&@Ij3#[j3!!3+B@aTB3B#M`!$rNm#N!!#N3Vq6`!%#QPZFfJ0!T!!!!)
+d!!!&A!9NrNi#NJVq6J!%#Q0QEf`0!T)!!@m!!!9J"@2q63[q63!d-!!BEh"PER0
+cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'!T%
+!!rj-!T2q5`Vq6!!%#R4[)#!0!T-!!Qi!!!9R"AB#P!+9$3+8!!)d!!!&E`9frNS
+#PJVq5J!%#QCTE'80!TB!!@d!!!9b"A8#P``#P`!2!!P[BQTPBh4c,QJ!!J!!$3+
+9!!)d!!!&C`9[rNN#Q!Vq53!%#Q0QEf`0!TJ!!@m!!!9V"@lq5![q5!!8-!!)G'9
+YF("KG'J!#(4PEA"3BA4S"[j,!!!#!S`!!J+C!TS0!TN!!Q`!!J9p"Ahq4rj'!Ij
+(!!!"rNB!!!)#QJ!#!TX#R!d#Q`!#FJ!!"Ad&L!+G!Ti0!Td!!Q)!!!9p"B3#R`+
+J$3+I!!&[!!!&I3@!rN8,rN8!*$!!%'0bHA"dEfC[E'4PFR"KG'J!%'0bHA"dEdC
+[E'4PFP"KG'J0!U!!!@d!!!@!"B-#S3`#S3!+!!3kF'9Y!!)!!!d#RJ!"E`!!!!!
+!!2j%#rj%!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J#!T`!!J+L!U-0!U)!!dN!!J@
+*"E2q3rj#!U3+rN-!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@aX!Ij#!!!'!U3
+!!rj"!U8#TJVq33!%#QY[Bf`0!U8!!@d!!!@0"C!!rN!+rN!!"!TKE'PK"J+Q!!2
+q2`+R!UJ+rMm!"!TTER0S$3+R!!)d!!!&N`@ErMi#U3Vq2J!%#Q0QEf`0!UN!!@m
+!!!@A"CVq23[q23!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0
+-5@jME(9NC8C[E'4PFP"KG'J'!UJ!!rim!UVq1`Vq2!!%#R4[)#!0!US!!Qi!!!@
+H"Dd#U`+X$3+V!!)d!!!&TJ@YrMS#V3Vq1J!%#QCTE'80!Ud!!@d!!!@T"D`#VJ`
+#VJ!,!!9`C@dZD!!#!!!0!U`!!M3!!!@H"DEq13+[#[ij!!3+BfC[E!d#V`!"E`!
+!"D)&TIii#rii!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J'rMX!!!)#S`!#!V!#X3d
+#X!!$53!#"E3&h[ihrMB#XJVq0`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`
+"rMB!!!B#XJ!$rM8#X`+d#[ie!!3+DfpME!d#X`!"E3!!"EJ&Zrid#[id!!3+B@a
+TB3B#Y!!$rM-#Y3+f#[ic!!3+D@jcD!d#Y3!#0!!!"Ei&a[ib!VF+rM)!"!TMCQp
+X$3+h!!&[!!!&`JA&rM%,rM%!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!
+BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J+f!!2q-!+irLm+rM!!"!TdEb!J$3+
+i!!*Z!!!&b3AB!VN#ZJd#Z3!#0!!!"G%&f2iZ!VX+rLi!"!TQD@aP$3+l!!&Y!!!
+&e!AA!V`-!V`!$!!'F'9Y-LjS!!)!!!d#ZJ!#0!!!"FN&dIiY!Vd+rLd!"!TMCQp
+X$3+p!!&[!!!&c3A3rL`,rL`!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!Eq,`!!!J+
+a!!)#[J+r$3+q!!*X!!)&h`AIrL[q+J(q+`!!!IiU!!!#!Vm!!J,!!X%0!X!!!R)
+!!!AI"HS#`J,$$3,#!!*L!!!&h`AQ!X3#a3d#a!!"E`!!"Gm&i[iT#riT!#3`!""
+MFRP`G'pQEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S$3,&!!&Y!!!&iJAP!XB
+-!XB!$3!(1R"VBh-a-J!#!!!0!X-!!@m!!!!!!!$q+![q+!!8-!!)G'9YF("KG'J
+!#(4PEA"3BA4S!J,"!!)#a`,)$3,(!!0*!!)&k`B9rLIq*J,*#[iR!"JZBfpbC@0
+bC@`U+LSU!!!!!!!!N!!!ER9XE!(q*J!!"J,*!!2q*3,+!XX+rL8!"!TVEf0X$3,
++!!&Y!!!&l`AbrL3+rL3!"!TKE'PK"J,,!!2q)`,-!Xd+rL-!"!TTER0S$3,-!!)
+d!!!&p3AprL)#cJVq)J!%#Q0QEf`0!Xi!!@m!!!Aj"Icq)3[q)3!d-!!BEh"PER0
+cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'!Xd
+!!riJ!Xrq(`Vq)!!%#R4[)#!0!Xm!!Qi!!!B!"Jm#d!,4$3,3!!)d!!!'#!B2rKi
+#dJVq(J!%#QCTE'80!Y)!!@d!!!B,"Ji#d``#d`!1!!K`Df0c-6)ZD!!#!!!0!Y%
+!!M3!!!B!"JMq(3,8#[iG!!3+BfC[E!d#e!!"E`!!"J3'"riF#riF!"3`!!KdC@e
+`F'&dD!!)G'9YF&"KG'J'rKm!!!)#b!!#!Y8#eJd#e3!#E!!#"KB'&[iErKS"rKX
+!!!(q'J!!!J,@!!)#e`,B$3,A!!*b!!!'&JBK!YN#fJd#f3!#BJ!!"KB'(3,E!Y`
+0!YX!!@m!!!B@"KRq'3[q'3!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4Qp
+XC'9b8'&dD!d#h!!"E3!!"KN'(!,G$!,G!!`!"MT`Df0c0`!#!!!0!YS!!@m!!!!
+!!!$q'![q'!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S!J,B!!)#hJ,I$3,H!!0*!!)
+')JC-rKIq&J,J#[iA!"JZBfpbC@0bC@`U+LSU!!!!!!!!N!!!ER9XE!(q&J!!"J,
+J!!2q&3,K!Z)+rK8!"!TVEf0X$3,K!!&Y!!!'*JBTrK3+rK3!"!TKE'PK"J,L!!2
+q%`,M!Z3+rK-!"!TTER0S$3,M!!)d!!!',!BdrK)#j3Vq%J!%#Q0QEf`0!Z8!!@m
+!!!B`"M2q%3[q%3!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0
+-5@jME(9NC8C[E'4PFP"KG'J'!Z3!!ri3!ZEq$`Vq%!!%#R4[)#!0!ZB!!Qi!!!B
+h"NB#j`,S$3,R!!)d!!!'2`C'rJi#k3Vq$J!%#QCTE'80!ZN!!@d!!!C#"N8#kJ`
+#kJ!0!!G`Df0c0bjS!!)!!!d#k!!#0!!!"MF'2ri0!ZX+rJd!"!TMCQpX$3,V!!&
+[!!!'1`BqrJ`,rJ`!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!Eq$`!!!J,I!!)#l!,
+Y$3,X!!*X!!)'63C0rJ[q#J(q#`!!!Ii+!!!#!Zd!!J,Z!Zm0!Zi!!R)!!!C0"PJ
+#m!,a$3,`!!*L!!!'63C8![)#m`d#mJ!"E`!!"Nd'82i*#ri*!#3`!""MFRP`G'p
+QEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S$3,c!!&Y!!!'8!C6![3-![3!#`!
+&1R*KEQ3!!J!!$3,a!!&[!!!!!!!!rJJ,rJJ!&$!!#(4PEA"`BA4S!!KdC@e`8'&
+dD!)#l`!#![8#pJd#p3!$53!#"PN'Jri(rJB#p`Vq"`!B,Q0[FQ9MFQ9X+LSU+J!
+!!!!!!*!!!'jeE'`"rJB!!!B#p`!$rJ8#q!,j#[i&!!3+DfpME!d#q!!"E3!!"Pd
+'B2i%#[i%!!3+B@aTB3B#q3!$rJ-#qJ,l#[i$!!3+D@jcD!d#qJ!#0!!!"Q-'Dri
+#![`+rJ)!"!TMCQpX$3,m!!&[!!!'C`CUrJ%,rJ%!0$!!''p`C@jcFfaTEQ0XG@4
+PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J,l!!2q!!,prIm
++rJ!!"!TdEb!J$3,p!!*Z!!!'EJCp![i#r`d#rJ!#0!!!"RB'IIhq!`!+rIi!"!T
+QD@aP$3-!!!&Y!!!'H3Cm!`%-!`%!$!!'FQ&ZC#jS!!)!!!d#r`!#0!!!"Qi'G[h
+p!`)+rId!"!TMCQpX$3-#!!&[!!!'FJCerI`,rI`!&$!!#(4PEA"`BA4S!!KdC@e
+`8'&dD!Epr`!!!J,f!!)$!`-%$3-$!!*X!!)'K!D%rI[pqJ(pq`!!!Ihk!!!#!`3
+!!J-&!`B0!`8!!R)!!!D%"Sm$"`-)$3-(!!*L!!!'K!D,!`N$#Jd$#3!"E`!!"S3
+'Krhj#rhj!#3`!""MFRP`G'pQEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S$3-
++!!&Y!!!'K`D+!`X-!`X!#J!%1R*M-J!#!!!0!`J!!@m!!!!!!!$pq![pq!!8-!!
+)G'9YF("KG'J!#(4PEA"3BA4S!J-'!!)$$!-0$3--!!0*!!)'N!!'Z[hhrIB$$JV
+pp`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"rIB!!!B$$J!$rI8$$`-3#[h
+e!!3+DfpME!d$$`!"E3!!"T3'Prhd#[hd!!3+B@aTB3B$%!!$rI-$%3-5#[hc!!3
++D@jcD!d$%3!#0!!!"TS'S[hb!a-+rI)!"!TMCQpX$3-6!!&[!!!'RJDKrI%,rI%
+!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'Efa
+NCA*3BA4S"J-5!!2pm!-8rHm+rI!!"!TdEb!J$3-8!!*Z!!!'T3Dd!a8$&Jd$&3!
+#0!!!"Ud'Y2hZ!aF+rHi!"!TQD@aP$3-A!!&Y!!!'X!Dc!aJ-!aJ!#`!&FQ-b,QJ
+!!J!!$3-@!!)d!!!'T3DYrHd$'3Vpl3!%#Q0QEf`0!aN!!@m!!!DT"Ucpl![pl!!
+8-!!)G'9YF("KG'J!#(4PEA"3BA4S"[h[!!!#!`d!!J-D!aX0!aS!!Q`!!JDl"V[
+pkrhU!IhV!!!"rHS!!!)$'`!#!a`$(3d$(!!#FJ!!"VX'aJ-H!am0!ai!!Q)!!!D
+l"X)$)!-K$3-J!!&[!!!'Z`DqrHN,rHN!*$!!%'0bHA"dEfC[E'4PFR"KG'J!%'0
+bHA"dEdC[E'4PFP"KG'J0!b%!!@d!!!Dq"X%$)J`$)J!+!!3kFQ-d!!)!!!d$(`!
+"E`!!!!!!!2hS#rhS!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J#!ad!!J-M!b30!b-
+!!dN!!JE("[(pjrhQ!b8+rHF!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@aX!Ih
+Q!!!'!b8!!rhP!bB$*`Vpj3!%#QY[Bf`0!bB!!@d!!!E,"Xlpj!Vpj!!%#Q&XD@%
+'!bF!!rhM!bJ$+3Vpi`!%#QPZFfJ0!bJ!!M3!!!E4"YRpiJ-U#[hL!!3+BfC[E!d
+$+J!"E`!!"Y8'f2hK#rhK!$3`!"K[F'9ZFh0XD@jME(9NC@C[E'4PFR"KG'J!''p
+`C@j68da*EQ0XG@4P4QpXC'9b8'&dD!B$+3!$rH!$+rhI#[hJ!!3+G'mJ)!d$+`!
+#EJ!!"Y`'k`-X!bd0!b`!!M3!!!EN"Z[phJ-Z#[hH!!3+CQPXC3d$,J!"E3!!"ZF
+'kJ-[$!-[!!X!"A*M0#jS!!)!!!d$,3!#0!!!"Y`'j2hG!c!+rGd!"!TMCQpX$3-
+`!!&[!!!'i!EMrG`,rG`!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!Eph`!!!J-N!!)
+$-3-b$3-a!!*X!!)'mJEbrG[pfJ(pf`!!!IhD!!!#!c)!!J-c!c30!c-!!R)!!!E
+b"[d$03-f$3-e!!*L!!!'mJEj!cF$1!d$0`!"E`!!"[)'pIhC#rhC!#3`!""MFRP
+`G'pQEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S$3-i!!&Y!!!'p3Ei!cN-!cN
+!#J!%1R*M03!#!!!0!cB!!@m!!!!!!!$pf![pf!!8-!!)G'9YF("KG'J!#(4PEA"
+3BA4S!J-d!!)$1J-l$3-k!!0*!!)'rJFSrGIpeJ-m#[hA!"JZBfpbC@0bC@`U+LS
+U!!!!!!!!N!!!ER9XE!(peJ!!"J-m!!2pe3-p!ci+rG8!"!TVEf0X$3-p!!&Y!!!
+(!JF&rG3+rG3!"!TKE'PK"J-q!!2pd`-r!d!+rG-!"!TTER0S$3-r!!)d!!!(#!F
+3rG)$33VpdJ!%#Q0QEf`0!d%!!@m!!!F-"`rpd3[pd3!d-!!BEh"PER0cE'PZBfa
+eC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'!d!!!rh3!d,
+pc`Vpd!!%#R4[)#!0!d)!!Qi!!!F6"b)$3`0%$30$!!)d!!!('`FLrFi$43VpcJ!
+%#QCTE'80!d8!!@d!!!FH"b%$4J`$4J!,!!9bBc8ZD!!#!!!0!d3!!M3!!!F6"a[
+pc30(#[h0!!3+BfC[E!d$4`!"E`!!"aF('[h-#rh-!"3`!!KdC@e`F'&dD!!)G'9
+YF&"KG'J'rFm!!!)$1`!#!dJ$53d$5!!#E!!#"bN(+Ih,rFS"rFX!!!(pbJ!!!J0
+*!!)$5J0,$30+!!*b!!!(+3Fd!d`$63d$6!!#BJ!!"bN(-!01!dm0!di!!@m!!!F
+T"bcpb3[pb3!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD!d
+$6`!"E3!!"b`(,`03$!03!!d!"cTbDA"PE@3!!J!!$300!!&[!!!!!!!!rFJ,rFJ
+!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!)$5`!#!e%$8Jd$83!$53!#"c8(Arh(rFB
+$8`Vpa`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"rFB!!!B$8`!$rF8$9!0
+9#[h&!!3+DfpME!d$9!!"E3!!"cN(22h%#[h%!!3+B@aTB3B$93!$rF-$9J0A#[h
+$!!3+D@jcD!d$9J!#0!!!"cm(4rh#!eJ+rF)!"!TMCQpX$30B!!&[!!!(3`G'rF%
+,rF%!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9
+'EfaNCA*3BA4S"J0A!!2p`!0CrEm+rF!!"!TdEb!J$30C!!*Z!!!(5JGC!eS$@`d
+$@J!#0!!!"e)(@Ifq!e`+rEi!"!TQD@aP$30F!!&Y!!!(93GB!ed-!ed!$J!)FQP
+`C@eN,QJ!!J!!$30E!!)d!!!(5JG5rEd$AJVp[3!%#Q0QEf`0!ei!!@m!!!G1"e(
+p[![p[!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S"[fr!!!#!e)!!J0I!f!0!em!!Q`
+!!JGJ"f$pZrfk!Ifl!!!"rES!!!)$B!!#!f%$BJd$B3!#FJ!!"f!(D`0M!f30!f-
+!!Q)!!!GJ"fF$C30Q$30P!!&[!!!(B!GMrEN,rEN!*$!!%'0bHA"dEfC[E'4PFR"
+KG'J!%'0bHA"dEdC[E'4PFP"KG'J0!fB!!@d!!!GM"fB$C``$C`!+!!3kFR0K!!)
+!!!d$C!!"E`!!!!!!!2fi#rfi!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J#!f)!!J0
+S!fN0!fJ!!dN!!JGX"jEpYrff!fS+rEF!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"
+ZG@aX!Iff!!!'!fS!!rfe!fX$E!VpY3!%#QY[Bf`0!fX!!@d!!!G`"h2pY!VpY!!
+%#Q&XD@%'!f`!!rfc!fd$EJVpX`!%#QPZFfJ0!fd!!M3!!!Gf"hlpXJ0[#[fb!!3
++BfC[E!d$E`!"E`!!"hS(IIfa#rfa!$3`!"K[F'9ZFh0XD@jME(9NC@C[E'4PFR"
+KG'J!''p`C@j68da*EQ0XG@4P4QpXC'9b8'&dD!B$EJ!$rE!$F2f[#[f`!!3+G'm
+J)!d$F!!#EJ!!"i%(N!!$F30b$30a!!)d!!!(L3H3!2fZ!h-+rDi!"!TQD@aP$30
+c!!&Y!!!(M!H2!h3-!h3!#`!&FR0K,QJ!!J!!$30b!!)d!!!(J3H*rDd$G3VpV3!
+%#Q0QEf`0!h8!!@m!!!H&"iMpV![pV!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S"[f
+[!!!#!fN!!J0f!hF0!hB!!Q`!!JHA"jIpUrfU!IfV!!!"rDS!!!)$G`!#!hJ$H3d
+$H!!#FJ!!"jF(SJ0k!hX0!hS!!Q)!!!HA"ji$I!0p$30m!!&[!!!(P`HDrDN,rDN
+!*$!!%'0bHA"dEfC[E'4PFR"KG'J!%'0bHA"dEdC[E'4PFP"KG'J0!hd!!@d!!!H
+D"jd$IJ`$IJ!-!!BkFh4KBfX!!J!!$30l!!&[!!!!!!!!rDJ,rDJ!&$!!#(4PEA"
+`BA4S!!KdC@e`8'&dD!)$H3!#!hm$J!d$I`!$53!#"k-(cIfRrDB$J3VpT`!B,Q0
+[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"rDB!!!B$J3!$rD8$JJ1$#[fP!!3+Dfp
+ME!d$JJ!"E3!!"kF(U[fN#[fN!!3+B@aTB3B$J`!$rD-$K!1&#[fM!!3+D@jcD!d
+$K!!#0!!!"kd(YIfL!iB+rD)!"!TMCQpX$31'!!&[!!!(X3HdrD%,rD%!0$!!''p
+`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4
+S"J1&!!2pS!1(rCm+rD!!"!TdEb!J$31(!!*Z!!!(Z!I(!iJ$L3d$L!!#0!!!"m!
+(arfH!iS+rCi!"!TQD@aP$31+!!&Y!!!(``I'!iX-!iX!$3!(Fh4KBfXZD!!#!!!
+0!iN!!M3!!!Hi"m$pR31-#[fG!!3+BfC[E!d$M!!"E`!!"l`([rfF#rfF!"3`!!K
+dC@e`F'&dD!!)G'9YF&"KG'J'rCm!!!)$J!!#!id$MJd$M3!$53!#"mi(q2fErCS
+$M`VpQ`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"rCS!!!B$M`!$rCN$N!!
+$N3VpQ3!%#QY[Bf`0!j!!!!&Y!!!(dJI9rCJ+rCJ!"!TKE'PK"J14!!2pP`15!j-
++rCF!"!TTER0S$315!!)d!!!(f!IJrCB$P!VpPJ!%#Q0QEf`0!j3!!@m!!!IF"pr
+pP3[pP3!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9
+NC8C[E'4PFP"KG'J'!j-!!rf8!jApN`VpP!!%#R4[)#!0!j8!!Qi!!!IM"r)$PJ1
+A$31@!!)d!!!(k`IbrC)$Q!VpNJ!%#QCTE'80!jJ!!@d!!!IZ"r%$Q3`$Q3!4!!Y
+cB@CPFh4KBfXZD!!#!!!0!jF!!M3!!!IM"q[pN31D#[f4!!3+BfC[E!d$QJ!"E`!
+!"qF(k[f3!![pN!!!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!EpN`!!!J11!!)$Q`1
+F$31E!!*X!!)(q3IjrBrpMJ(pM`!!!If1!!!#!j`!!J1G!ji0!jd!!R)!!!Ij#!3
+$R`1J$31I!!*L!!!(q3J!!k%$SJd$S3!"E`!!"rN(r2f0#rf0!#3`!""MFRP`G'p
+QEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S$31L!!&Y!!!(r!Ir!k--!k-!#J!
+%1R0SB3!#!!!0!k!!!@m!!!!!!!$pM![pM!!8-!!)G'9YF("KG'J!#(4PEA"3BA4
+S!J1H!!)$T!1P$31N!!0*!!))"3J[rB[pLJ1Q#[f,!"JZBfpbC@0bC@`U+LSU!!!
+!!!!!N!!!ER9XE!(pLJ!!"J1Q!!2pL31R!kJ+rBN!"!TVEf0X$31R!!&Y!!!)#3J
+-rBJ+rBJ!"!TKE'PK"J1S!!2pK`1T!kS+rBF!"!TTER0S$31T!!)d!!!)$`JArBB
+$U`VpKJ!%#Q0QEf`0!kX!!@m!!!J6#"EpK3[pK3!d-!!BEh"PER0cE'PZBfaeC'9
+QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'!kS!!rf%!kcpJ`V
+pK!!%#R4[)#!0!k`!!Qi!!!JD##N$V31Z$31Y!!)d!!!))JJTrB)$V`VpJJ!%#QC
+TE'80!km!!@d!!!JP##J$X!`$X!!,!!9cD'%ZD!!#!!!0!ki!!M3!!!JD##,pJ31
+a#[f"!!3+BfC[E!d$X3!"E`!!#"i))If!#rf!!"3`!!KdC@e`F'&dD!!)G'9YF&"
+KG'J'rB-!!!)$T3!#!l)$X`d$XJ!#E!!##$!)-2errAi"rAm!!!(pIJ!!!J1c!!)
+$Y!1e$31d!!*b!!!)-!Jl!lB$Y`d$YJ!#BJ!!#$!)0`1i!lN0!lJ!!@m!!!J`#$2
+pI3[pI3!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD!d$Z3!
+"E3!!#$-)0J1k$!1k!!d!"cTdH(4IC')!!J!!$31h!!&[!!!!!!!!rA`,rA`!&$!
+!#(4PEA"`BA4S!!KdC@e`8'&dD!)$Y3!#!lX$[!d$Z`!$53!##$`)C[elrAS$[3V
+pH`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"rAS!!!B$[3!$rAN$[J1r#[e
+j!!3+DfpME!d$[J!"E3!!#%!)3rei#[ei!!3+B@aTB3B$[`!$rAF$`!2"#[eh!!3
++D@jcD!d$`!!#0!!!#%B)6[ef!m)+rAB!"!TMCQpX$32#!!&[!!!)5JK0rA8,rA8
+!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'Efa
+NCA*3BA4S"J2"!!2pG!2$rA-+rA3!"!TdEb!J$32$!!*Z!!!)83KJ!m3$a3d$a!!
+#0!!!#&N)B2eb!mB+rA)!"!TQD@aP$32'!!&Y!!!)A!KI!mF-!mF!$J!)G(KdAf4
+L,QJ!!J!!$32&!!)d!!!)83KCrA%$b!VpF3!%#Q0QEf`0!mJ!!@m!!!K9#&MpF![
+pF!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S"[ec!!!#!l`!!J2*!mS0!mN!!Q`!!JK
+R#'IpEreZ!Ie[!!!"r@i!!!)$bJ!#!mX$c!d$b`!#FJ!!#'F)FJ20!mi0!md!!Q)
+!!!KR#'i$c`23$322!!&[!!!)C`KUr@d,r@d!*$!!%'0bHA"dEfC[E'4PFR"KG'J
+!%'0bHA"dEdC[E'4PFP"KG'J0!p!!!@d!!!KU#'d$d3`$d3!,!!8kH$8`13!#!!!
+0!mi!!@m!!!!!!!$pE![pE!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S!J2-!!)$dJ2
+6$325!!0*!!))F`LGr@[pDJ28#[eV!"JZBfpbC@0bC@`U+LSU!!!!!!!!N!!!ER9
+XE!(pDJ!!"J28!!2pD329!pB+r@N!"!TVEf0X$329!!&Y!!!)G`Kkr@J+r@J!"!T
+KE'PK"J2@!!2pC`2A!pJ+r@F!"!TTER0S$32A!!)d!!!)I3L&r@B$f3VpCJ!%#Q0
+QEf`0!pN!!@m!!!L"#)6pC3[pC3!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4
+S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'!pJ!!reN!pVpB`VpC!!%#R4[)#!
+0!pS!!Qi!!!L)#*F$f`2F$32E!!)d!!!)N!!)PreL!pd+r@)!"!TQD@aP$32G!!&
+Y!!!)N`L@!pi-!pi!$!!'H$8`15jS!!)!!!d$h!!#0!!!#)J)N!$pB32I#[eK!!3
++BfC[E!d$h`!"E`!!#)`)MreJ#reJ!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J'r@-
+!!!)$d`!#!q!$i3d$i!!$53!##*i)b2eIr9i$iJVpA`!B,Q0[FQ9MFQ9X+LSU+J!
+!!!!!!*!!!'jeE'`"r9i!!!B$iJ!$r9d$i`2N#[eG!!3+DfpME!d$i`!"E3!!#+)
+)TIeF#[eF!!3+B@aTB3B$j!!$r9X$j32Q#[eE!!3+D@jcD!d$j3!#0!!!#+J)X2e
+D!qF+r9S!"!TMCQpX$32R!!&[!!!)V!L[r9N,r9N!0$!!''p`C@jcFfaTEQ0XG@4
+PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J2Q!!2p@!2Sr9F
++r9J!"!TdEb!J$32S!!*Z!!!)X`M#!qN$kJd$k3!#0!!!#,X)`[e@!qX+r9B!"!T
+QD@aP$32V!!&Y!!!)[JM"!q`-!q`!%!!+H$8`19pfCRNZD!!#!!!0!qS!!M3!!!L
+c#,[p932Y#[e9!!3+BfC[E!d$l3!"E`!!#,F)Z[e8#re8!"3`!!KdC@e`F'&dD!!
+)G'9YF&"KG'J'r9F!!!)$i3!#!qi$l`d$lJ!#E!!##-N)bIe6r9)"r9-!!!(p8J!
+!!J2[!!)$m!2a$32`!!*b!!!)b3M8!r)$m`d$mJ!#BJ!!#-N)d!2d!r80!r3!!@m
+!!!M*#-cp83[p83!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&
+dD!d$p3!"E3!!#-`)c`2f$!2f!!d!"cTi06!jGM-!!J!!$32c!!&[!!!!!!!!r9!
+,r9!!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!)$m3!#!rF$q!d$p`!$53!##08)rre
+2r8i$q3Vp6`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"r8i!!!B$q3!$r8d
+$qJ2l#[e0!!3+DfpME!d$qJ!"E3!!#0N)h2e-#[e-!!3+B@aTB3B$q`!$r8X$r!2
+p#[e,!!3+D@jcD!d$r!!#0!!!#0m)jre+!ri+r8S!"!TMCQpX$32q!!&[!!!)i`M
+Qr8N,r8N!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfa
+eC'9'EfaNCA*3BA4S"J2p!!2p5!2rr8F+r8J!"!TdEb!J$32r!!*Z!!!)kJMj"!!
+%!3d%!!!#0!!!#2))qIe'"!)+r8B!"!TQD@aP$33#!!&Y!!!)p3Mi"!--"!-!$J!
+)H$8`1ABc,QJ!!J!!$33"!!)d!!!)kJMbr88%"!Vp43!%#Q0QEf`0"!3!!@m!!!M
+Z#2(p4![p4!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S"[e(!!!#!rJ!!J3&"!B0"!8
+!!Q`!!JN!#3$p3re#!Ie$!!!"r8)!!!)%"J!#"!F%#!d%"`!$53!##3!*+[e"r8!
+%#3Vp33!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"r8!!!!B%#3!$r6m%#J3
+,#[dr!!3+DfpME!d%#J!"E3!!#33*"rdq#[dq!!3+B@aTB3B%#`!$r6d%$!30#[d
+p!!3+D@jcD!d%$!!#0!!!#3S*%[dm"!i+r6`!"!TMCQpX$331!!&[!!!*$JN4r6X
+,r6X!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9
+'EfaNCA*3BA4S"J30!!2p1J32r6N+r6S!"!TdEb!J$332!!*Z!!!*&3NN""!%%3d
+%%!!#0!!!#4d**2di"")+r6J!"!TQD@aP$335!!&Y!!!*)!NM""--""-!#`!&Fh0
+X,QJ!!J!!$334!!)d!!!*&3NGr6F%&!Vp0`!%#Q0QEf`0""3!!@m!!!NC#4cp0J[
+p0J!H-!!0Fh0XCQpXC'9bF'&dD!!0Fh0X4QpXC'9b8'&dD!Ep13!!!J3)!!)%&33
+@$339!!0*!!)*+`P9r6Ap0!3A#[de!"JZBfpbC@0bC@`U+LSU!!!!!!!!N!!!ER9
+XE!(p0!!!"J3A!!2p-`3B""N+r6-!"!TVEf0X$33B!!&Y!!!*,`Nbr6)+r6)!"!T
+KE'PK"J3C!!2p-33D""X+r6%!"!TTER0S$33D!!)d!!!*03Npr6!%(!Vp-!!%#Q0
+QEf`0""`!!@m!!!Nj#6cp,`[p,`!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4
+S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'""X!!rdZ""hp,3Vp,J!%#R4[)#!
+0""d!!Qi!!!P!#8m%(J3I$33H!!)d!!!*5!P2r5`%)!Vp,!!%#QCTE'80"#!!!@d
+!!!P,#8i%)3`%)3!-!!CcFf`b,QJ!!J!!$33I!!)d!!!*3!P)r5X%)JVp+`!%#Q0
+QEf`0"#)!!@m!!!P%#8Ip+J[p+J!H-!!0Fh0XCQpXC'9bF'&dD!!0Fh0X4QpXC'9
+b8'&dD!Ep,3!!!J3@!!)%)`3N$33M!!0*!!)*9JQ!r5Rp+!3P#[dT!"JZBfpbC@0
+bC@`U+LSU!!!!!!!!N!!!ER9XE!(p+!!!"J3P!!2p*`3Q"#F+r5F!"!TVEf0X$33
+Q!!&Y!!!*@JPGr5B+r5B!"!TKE'PK"J3R!!2p*33S"#N+r58!"!TTER0S$33S!!)
+d!!!*B!PSr53%+JVp*!!%#Q0QEf`0"#S!!@m!!!PN#@Ip)`[p)`!d-!!BEh"PER0
+cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'"#N
+!!rdL"#[p)3Vp)J!%#R4[)#!0"#X!!Qi!!!PV#AS%,!3Y$33X!!)d!!!*F`Pkr5!
+%,JVp)!!%#QCTE'80"#i!!@d!!!Pf#AN%,``%,`!0!!GcFf`b-bjS!!)!!!d%,3!
+#0!!!#@X*FrdI"$!+r4m!"!TMCQpX$33`!!&[!!!*E`Pbr4i,r4i!(M!!$A0cE'C
+[E'4PFR"KG'J!$A0cE%C[E'4PFP"KG'J'r5%!!!)%*!!#"$%%-Jd%-3!$53!##B%
+*UrdGr4`%-`Vp(3!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"r4`!!!B%-`!
+$r4X%0!3e#[dE!!3+DfpME!d%0!!"E3!!#B8*L2dD#[dD!!3+B@aTB3B%03!$r4N
+%0J3h#[dC!!3+D@jcD!d%0J!#0!!!#BX*NrdB"$J+r4J!"!TMCQpX$33i!!&[!!!
+*M`Q5r4F,r4F!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%P
+ZBfaeC'9'EfaNCA*3BA4S"J3h!!2p&J3jr48+r4B!"!TdEb!J$33j!!*Z!!!*PJQ
+P"$S%1`d%1J!#0!!!#Ci*TId8"$`+r43!"!TQD@aP$33m!!&Y!!!*S3QN"$d-"$d
+!$!!'Fh0X-bjS!!)!!!d%1`!#0!!!#CB*R[d6"$i+r4-!"!TMCQpX$33q!!&[!!!
+*QJQGr4),r4)!(M!!$A0cE'C[E'4PFR"KG'J!$A0cE%C[E'4PFP"KG'J'r48!!!)
+%-J!#"$m%3!d%2`!$53!##D`*e[d4r4!%33Vp%3!B,Q0[FQ9MFQ9X+LSU+J!!!!!
+!!*!!!'jeE'`"r4!!!!B%33!$r3m%3J4$#[d2!!3+DfpME!d%3J!"E3!!#E!*Xrd
+1#[d1!!3+B@aTB3B%3`!$r3d%4!4&#[d0!!3+D@jcD!d%4!!#0!!!#EB*[[d-"%B
++r3`!"!TMCQpX$34'!!&[!!!*ZJQpr3X,r3X!0$!!''p`C@jcFfaTEQ0XG@4PCQp
+XC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J4&!!2p#J4(r3N+r3S
+!"!TdEb!J$34(!!*Z!!!*`3R3"%J%53d%5!!#0!!!#FN*d2d)"%S+r3J!"!TQD@a
+P$34+!!&Y!!!*c!R2"%X-"%X!$!!'G'ac-5jS!!)!!!d%53!#0!!!#F%*bId("%`
++r3F!"!TMCQpX$34-!!&[!!!*a3R)r3B,r3B!(M!!$A0cE'C[E'4PFR"KG'J!$A0
+cE%C[E'4PFP"KG'J'r3N!!!)%3!!#"%d%6Jd%63!#E!!##GF*erd&r33"r38!!!(
+p"!!!!J41!!)%6`43$342!!0*!!)*e`S"r32p!J44#[d$!"JZBfpbC@0bC@`U+LS
+U!!!!!!!!N!!!ER9XE!(p!J!!"J44!!2p!345"&-+r3%!"!TVEf0X$345!!&Y!!!
+*f`RHr3!+r3!!"!TKE'PK"J46!!2mr`48"&8+r2m!"!TTER0S$348!!)d!!!*i3R
+Tr2i%9JVmrJ!%#Q0QEf`0"&B!!@m!!!RP#HMmr3[mr3!d-!!BEh"PER0cE'PZBfa
+eC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'"&8!!rcm"&I
+mq`Vmr!!%#R4[)#!0"&F!!Qi!!!RX#IX%@!4C$34B!!)d!!!*p!Rlr2S%@JVmqJ!
+%#QCTE'80"&S!!@d!!!Rh#IS%@``%@`!1!!KMFRP`G'mZD!!#!!!0"&N!!M3!!!R
+X#I6mq34F#[cj!!3+BfC[E!d%A!!"E`!!#I!*mrci#rci!#3`!""MFRP`G'pQEfa
+NCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S"[cl!!!#"&!!!J4G"&i0"&d!!Q`!!JS
+##J,mprcf!Ich!!!"r2B!!!)%AJ!#"&m%B!d%A`!$53!##J)+,2cer23%B3Vmp3!
+B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"r23!!!B%B3!$r2-%BJ4M#[cc!!3
++DfpME!d%BJ!"E3!!#JB+#Icb#[cb!!3+B@aTB3B%B`!$r2%%C!4P#[ca!!3+D@j
+cD!d%C!!#0!!!#J`+&2c`"'B+r2!!"!TMCQpX$34Q!!&[!!!+%!S6r1m,r1m!0$!
+!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*
+3BA4S"J4P!!2mlJ4Rr1d+r1i!"!TdEb!J$34R!!*Z!!!+&`SQ"'J%D3d%D!!#0!!
+!#Km+*[cX"'S+r1`!"!TQD@aP$34U!!&Y!!!+)JSP"'X-"'X!%!!+Eh"PER0cE(B
+ZD!!#!!!0"'N!!M3!!!SA#Krmk`4X#[cV!!3+BfC[E!d%E!!"E`!!#KX+([cU#rc
+U!#3`!""MFRP`G'pQEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S"[cY!!!#"'!
+!!J4Y"'i0"'d!!dN!!JSY#PImkIcS"'m+r1N!'#jMEh*PBh*PE#SU+LS!!!!!!!#
+3!!"ZG@aX!IcS!!!'"'m!!rcR"(!%F3Vmj`!%#QY[Bf`0"(!!!@d!!!Sa#M6mjJV
+mjJ!%#Q&XD@%'"(%!!rcP"()%F`Vmj3!%#QPZFfJ0"()!!M3!!!Sh#Mrmj!4d#[c
+N!!3+BfC[E!d%G!!"E`!!#MX+2[cM#rcM!$3`!"K[F'9ZFh0XD@jME(9NC@C[E'4
+PFR"KG'J!''p`C@j68da*EQ0XG@4P4QpXC'9b8'&dD!B%F`!$r1)%GIcK#[cL!!3
++G'mJ)!d%G3!#EJ!!#N)+834f"(F0"(B!!M3!!!T+#P(mi!4i#[cJ!!3+CQPXC3d
+%H!!"E3!!#Nd+8!4j$!4j!!i!#(4YC'PQCLjS!!)!!!d%G`!#0!!!#N)+5[cI"(S
++r0m!"!TMCQpX$34k!!&[!!!+4JT*r0i,r0i!*$!!%'0bHA"dEfC[E'4PFR"KG'J
+!%'0bHA"dEdC[E'4PFP"KG'J'r1%!!!)%EJ!#"(X%I!d%H`!#E!!##PJ+@2cGr0`
+"r0d!!!(mh!!!!J4m!!)%I34q$34p!!*X!!)+@!TBr0[mfJ(mf`!!!IcD!!!#"(i
+!!J4r")!0"(m!!dN!!JTB#S,mfIcB")%+r0N!'#jMEh*PBh*PE#SU+LS!!!!!!!#
+3!!"ZG@aX!IcB!!!'")%!!rcA"))%J`Vme`!%#QY[Bf`0"))!!@d!!!TF#PrmeJV
+meJ!%#Q&XD@%'")-!!rc9")3%K3Vme3!%#QPZFfJ0")3!!M3!!!TL#QVme!5'#[c
+8!!3+BfC[E!d%KJ!"E`!!#QB+DIc6#rc6!$3`!"K[F'9ZFh0XD@jME(9NC@C[E'4
+PFR"KG'J!''p`C@j68da*EQ0XG@4P4QpXC'9b8'&dD!B%K3!$r0)%Krc4#[c5!!3
++G'mJ)!d%K`!#EJ!!#Qd+I!5)")N0")J!!M3!!!Te#Rcmd!5+#[c3!!3+CQPXC3d
+%LJ!"E3!!#RJ+H`5,$!5,!!`!"Q9IEh-ZD!!#!!!0")N!!M3!!!TY#RAmc`5-#[c
+2!!3+BfC[E!d%M!!"E`!!#R%+G2c1#rc1!#B`!"&[F'9ZFh0XCQpXC'9bF'&dD!!
+4Eh"PER0cE%C[E'4PFP"KG'J'r0%!!!)%J!!#")d%MJd%M3!$53!##S-+VIc0r-`
+%M`Vmc3!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"r-`!!!B%M`!$r-X%N!!
+%N3Vmb`!%#QY[Bf`0"*!!!!&Y!!!+K`U+r-S+r-S!"!TKE'PK"J54!!2mb355"*-
++r-N!"!TTER0S$355!!)d!!!+M3U9r-J%P!Vmb!!%#Q0QEf`0"*3!!@m!!!U4#T6
+ma`[ma`!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9
+NC8C[E'4PFP"KG'J'"*-!!rc'"*Ama3VmaJ!%#R4[)#!0"*8!!Qi!!!UB#UF%PJ5
+A$35@!!)d!!!+S!URr-3%Q!Vma!!%#QCTE'80"*J!!@d!!!UM#UB%Q3`%Q3!0!!G
+PAfpc-LjS!!)!!!d%P`!#0!!!#TJ+S2c$"*S+r--!"!TMCQpX$35D!!&[!!!+R!U
+Ir-),r-)!*M!!%@p`C@jcFfaQEfaNCA*`BA4S!"&[F'9ZFh0X4QpXC'9b8'&dD!E
+ma3!!!J51!!)%Qrc"$35E!!*X!!)+VJUZr-$m[`(m`!!!!Ibr!!!#r-%!!!d!#3!
+"E3!!!!!!!3!I!Irq!!!#!!B!!J5F"*d0"*`!!Q`!!J!!!!$m[[bp!Ibq!!!"r,d
+!!!)%R3!#"*i%R`d%RJ!#E!!##V%+b!5Jr,`0"+!!!dN!!JUa#XMmZ`5K"+)+r,X
+!'#jcHA0[C'a[Cf&cDh)!!!!!!!!!!&4&@&30"+%!!@d!!!Ua#V3%S``%S`!'!!!
+!!J!!"J5L!!2mZJ5N"+8+r,S!"!TLG'jc$35N!!&+!!!+Y`Um"+B#"+B!!J5Rr,N
+0"+F!!@d!!!Uh#VS%U!`%U!!+!!4%EfjP!!)!!!,mZ3!!"J5P!!2mZ!5Tr,F+r,J
+!"!TRDACe$35T!!&Y!!!+[`V#r,B$r,B!"3EmY`!!!Ibm!!!#"*m!!J5Ur,80"+S
+!!Q`!!J!!!!$mY2bc!Ibd!!!"r,-!!!,mY3!!$J!#!!!2%!!$!",mXJ5V"+`%V35
+Z"+m%X!5a",)%X`5d",8%YJ5hr,(mX2b[r+i"r,)!!"!%U`!3r+hmV2bVr+VmUIb
+Sr+ImT[bPr+6mSrbLr+(mS2bIr*i+r+d!'#jKCACdEf&`F'jeE'`!!)!!!!#3!!!
+U+LSU#rbX!")`!!GdD'9`BA4S!!GdD'93BA4S#rbV!"``!!adD'9[E'4NC@aTEA-
+!$(4SC8pXC%4PE'PYF`[mUJ!J-!!1G'KPF(*[DQ9MG("KG'J!$R4SC9"bEfTPBh4
+3BA4S#rbT!"B`!!PdD'9YCA"KG'J!#A4SC8eP8'&dD![mU!!Q-!!4D@jME(9NC@C
+[E'4PFR"KG'J!%@PZBfaeC'9'EfaNCA*3BA4S#rbR!$3`!"K[F'9ZFh0XD@jME(9
+NC@C[E'4PFR"KG'J!''p`C@j68da*EQ0XG@4P4QpXC'9b8'&dD![mTJ!N-!!3Bh*
+jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD![mT3!H-!!0Fh0XCQpXC'9
+bF'&dD!!0Fh0X4QpXC'9b8'&dD![mT!!Q-!!4Eh"PER0cE'C[E'4PFR"KG'J!%@p
+`C@jcFfa'EfaNCA*3BA4S#rbM!#i`!"9dD'9ZCAGQEfaNCA*bC@CPFQ9ZBf8!&A4
+SC8jPGdC[E'4PFP*PCQ9bC@jMC3[mSJ!8-!!)G'9YF("KG'J!#(4PEA"3BA4S!Ib
+K!!!"r+!!!!(mR`!!!IbH!!!1"+`!"a$mR35ir*cmQ`5j",VmQJVmR3!B,Q&PGR4
+[BA"`ER9XE!!!J!!!!*!!!#SU+LS0",J!!@X!!!!!#XJ%Z`)%Z`!#!!8%[!)%[!!
+#"*lmQ3,mQ3!!!IbF!!!#r*X!!"!%Z3!!%!5k!)B!(rbBr*ImP[b9r*6mNrb5!#c
+mNIb3!2b2r)lmMIb-!%rmL`"D!&[mLJ"Nr)N!EIb)r)ImKJ#2r)AmK2b$r),mJIb
+!r(rmI[apr(cmH`#Tr(VmHIair(F![Iaf!-ImG3$8!1)!l!$j!3-"%!%D!5F"-3%
+q!8J"93&I!@`"GJ'$!Bd"QJ'N!E%"Z`()!G)"h`(T!IB#!!)0!KF#*!)Z!MX#43*
+5!P`#D3*c!S!#LJ+A!U%#VJ+m!XB#d`,G!ZS#p!-"!`X$'!-L!bm$130'!e!$A30
+R!h3$IJ1,!jN$S`1`!lS$a`24!pi$l!2f"!-%%`3K"#m%234,"&X%D`4j")X%Q35
+Mr(3%U2acr(,mF3VmQ!!%#Q0[BQS+r*F!'#jPBA*cCQCNFQ&XDA-!!!!!!!!J!'&
+QC()+r*B!"!TMG(Kd#rb9!")`!!GdD'9`BA4S!!GdD'93BA4S#[b8!!3+BA0MFJV
+mN`!%#R4iC'`,r*)!($!!$(4SC@pXC'4PE'PYF`!-G'KP6faN4'9XD@ec#[b4!!3
++BfPdE32mN!$rr3[mM`!J-!!1G'KPF(*[DQ9MG("KG'J!$R4SC9"bEfTPBh43BA4
+S!rb1rri+r)d!"!T849K8#rb-!"B`!!PdD'9YCA"KG'J!#A4SC8eP8'&dD![mL`!
+Q-!!4D@jME(9NC@C[E'4PFR"KG'J!%@PZBfaeC'9'EfaNCA*3BA4S#rb+!$3`!"K
+[F'9ZFh0XD@jME(9NC@C[E'4PFR"KG'J!''p`C@j68da*EQ0XG@4P4QpXC'9b8'&
+dD![mL3!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD![mL!!
+H-!!0Fh0XCQpXC'9bF'&dD!!0Fh0X4QpXC'9b8'&dD![mK`!Q-!!4Eh"PER0cE'C
+[E'4PFR"KG'J!%@p`C@jcFfa'EfaNCA*3BA4S#[b'!!3+BfC[E!VmK3!B,QeTFf0
+cE'0d+LSU+J!!!!!!!*!!!#SU+LS+r)3!"!TcC@aP#[b$!"JZBfpbC@4PE'mU+LS
+U!!!!!!!!N!!!+LSU+J(mJJ!!![b"!!!+r)!!"!TVEf0X#[ar!!3+D@jcD!2mIJ!
+%#[ap!"JZBfpbC@0bC@`U+LSU!!!!!!!!N!!!ER9XE!VmI!!%#R*cE(3,r(X!,M!
+!&A4SC@jPGfC[E'4PFR*PCQ9bC@jMC3!9G'KP6Q9h4QpXC'9b8Q9QCA*PEQ0P#[a
+k!!3+F'jKE3VmH3!%#Q&XD@%+r(J!"!TdEb!J#[ah!!3+CQPXC32mGJ!'#rae!"3
+`!!KdC@e`F'&dD!!)G'9YF&"KG'J+r(3!"!TLG'jc#[ac!!3+CfPfG32mFJ!&#[a
+a!"JZFhPcEf4XEfGKFfYb!!!!!!!!!!"849K8%IbD#XRJ%JUYi1%TDJ`!!LrM*N9
+4e%r&jLa&edrSaHBX4Nr%@qPF@eTVA&VU-NAE6m4Ek9aE@QYF@Z`bl5C&hNr,lbA
+Y*N9J!""2bf%!%59K!")Pl5C&B!!66mYK!"3Pl5C&B!!96mYK!"BPl5C&B!!A6m[
+Y*N9J!"K2amAQ,%C2&!!L+Q%!'9m!%#pK!"PK!"S[DJ`!'dmUB3!F,'S-!"eA!!K
+B!"i!(fK2+Q%!)'%!'@%!)5TK!"PI!"![B3!L$!!M6em!*%9J!#92A`!PDJ`!'dp
+K!#BUB3!F,'%!*ba'6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"R1,f%!+Q%!+bp
+K!#`-!#02A`!9B3!Y*89J!#j2+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!,Lp
+K!#TK!#m[B3!X$!!M6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"PI!#i[B3!UB3!
+`,f%!,!`!)dpI!"9K!$%P4@!!,NmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!
+Z,f%!+Q%!-LpK!#`-!#02A`!9B3!c*89J!#j2+Q%!)'%!+'%!)5TK!"PI!"-[B3!
+T+Q%!'9m!,LpK!#TK!$3[B3!X$!!M6em!&@%!059&B!!Z6bTK!#"K!#KK!#%UB3!
+CA`!6,f%!+5TK!"PI!#i[B3!UB3!f,f%!,!`!)dpI!"9K!$FP4@!!,NmUB3!JB3!
+SB3!K+Q%!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%!1#pK!#`-!#02A`!9B3!j*89J!#j
+2+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!,LpK!#TK!$S[B3!X$!!M6em!&@%
+!1b9&B!!Z6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"PI!#i[B3!UB3!m,f%!,!`
+!)dpI!"9K!$dP4@!!,NmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%
+!2LpK!#`-!#02A`!9B3!r*89J!#j2+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m
+!,LpK!#TK!%![B3!X$!!M6em!&@%!359&B!!Z6bTK!#"K!#KK!#%UB3!CA`!6,f%
+!+5TK!"PI!#i[B3!UB3"#,f%!,!`!)dpI!"9K!%-P4@!!,NmUB3!JB3!SB3!K+Q%
+!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%!4#pK!#`-!#02A`!9B3"&*89J!#j2+Q%!)'%
+!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!,LpK!#TK!%B[B3!X$!!M6em!&@%!4b9&B!!
+Z6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"PI!#i[B3!UB3"),f%!,!`!)dpI!"9
+K!%NP4@!!,NmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%!5LpK!#`
+-!#02A`!9B3",*89J!#j2+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!,LpK!#T
+K!%`[B3!X$!!M6em!&@%!659&B!!Z6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"P
+I!#i[B3!UB3"1,f%!,!`!)dpI!"9K!%mP4@!!,NmUB3!JB3!SB3!K+Q%!'9m!%bp
+K!#NUB3!CA`!Z,f%!+Q%!8#pK!#`-!#02A`!9B3"4*89J!#j2+Q%!)'%!+'%!)5T
+K!"PI!"-[B3!T+Q%!'9m!,LpK!#TK!&)[B3!X$!!M6em!&@%!8b9&B!!Z6bTK!#"
+K!#KK!#%UB3!CA`!6,f%!+5TK!"PI!#i[B3!UB3"8,f%!,!`!)dpI!"9K!&8P4@!
+!,NmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%!9LpK!#`-!#02A`!
+9B3"A*89J!#j2+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!,LpK!#TK!&J[B3!
+X$!!M6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"PI!#i[B3!UB3"C,f%!,!`!)dp
+I!"9K!&SP4@!!,NmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%!@bp
+K!#`-!#02A`!9B3"F*89J!#j2+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!,Lp
+K!#TK!&d[B3!X$!!M6em!&@%!AL9&B!!Z6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5T
+K!"PI!#i[B3!UB3"I,f%!,!`!)dpI!"9K!'!P4@!!,NmUB3!JB3!SB3!K+Q%!'9m
+!%bpK!#NUB3!CA`!Z,f%!+Q%!B5pK!#`-!#02A`!9B3"L*89J!#j2+Q%!)'%!+'%
+!)5TK!"PI!"-[B3!T+Q%!'9m!,LpK!#TK!'-[B3!X$!!M6em!&@%!C#9&B!!Z6bT
+K!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"PI!#i[B3!UB3"P,f%!,!`!)dpI!"9K!'B
+P4@!!,NmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%!CbpK!#`-!#0
+2A`!9B3"S*89J!#j2+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!,LpK!#TK!'N
+[B3!X$!!M6em!&@%!DL9&B!!Z6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"PI!#i
+[B3!UB3"V,f%!,!`!)dmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%
+!E#pK!#`-!#02A`!9B3"Y*89J!#j2+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m
+!,LpK!#TK!'i[B3!X$!!M6em!&@%!Eb9&B!!Z6bTK!#"K!#KK!#%UB3!CA`!6,f%
+!+5TK!"PI!#i[B3!UB3"`,f%!,!`!)dpI!"9K!(%P4@!!,NmUB3!JB3!SB3!K+Q%
+!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%!FLpK!#`-!#02+Q%!)'%!+'%!)5TK!"PI!"-
+[B3!T+Q%!'9m!,LpK!#TK!(-[B3!X$!!M6em!&@%!G#9&B!!Z6bTK!#"K!#KK!#%
+UB3!CA`!6,f%!+5TK!"PI!#i[B3!UB3"e,f%!,!`!)dmUB3!JB3!SB3!K+Q%!'9m
+!%bpK!#NUB3!CA`!A,f%!+Q%!GLpK!#`-!#02+Q%!)'%!+'%!)5TK!"PI!"-[B3!
+T+Q%!'9m!&bpK!#TK!(F[B3!X$!!M6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"P
+I!"F[B3!UB3"i,f%!,!`!)dmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!A,f%
+!+Q%!H5pK!#`-!#02+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!&bpK!#TK!(S
+[B3!X$!!M6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"PI!"8[B3!UB3"l,f%!,!`
+!)dmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!9,f%!+Q%!I#pK!#`-!#02+Q%
+!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!&5pK!#TK!(d[B3!X$!!M6bTK!#"K!#K
+K!#%UB3!CA`!6,f%!+5TK!"PI!"J[B3!UB3"q,f%!,!`!)dmUB3!JB3!SB3!K+Q%
+!'9m!%bpK!#NUB3!CA`!B,f%!+Q%!IbpK!#`-!#028&92B3#!B3#"B3##DhCK!)0
+K!)4K!#)-!)82$!5Y!&%!5deKBfPZG'pcD#")4$T%CA0VG'p`)%C[E'4PFMT*EQ0
+[E@PZCcT[F'9ZFh0X,90139!Y-6Nj16%b-6%k6@&M6e-kE@YXD@jVFbjKF`!#!!!
+1"+i!!J6mF!5p!ra`!!%1",d!!3!%[J`%[J!'!!!!!J!!$J5[!!)%r'm%[`2mE`!
+%$J5r!!3!"-!%`36#"---"-!!%J!-6@&MD@jdEh0S)%K%!!)!!!`%`3!8!!j%CA0
+VG'p`)%C[E'4PFJ!#!!!-"-)!$J!)5@jMEfeTEQF!!J!!$!6$!"X!&@p`C@jcFf`
+Y8dj"8#da16Nj-6)a-3!#!!!-",!!4J"!6@&MD@jdEh0S)%K%1N4PFfYdEh!J4Qp
+XC'9b1NPZBfpYD@jR1Qp`C@jcFf`Y8dj"8#da16Nj-6)a-6T0B@028`!#!!!-",%
+!5!"#6@&MD@jdEh0S)%K%1N4PFfYdEh!J4QpXC'9b1NPZBfpYD@jR1Qp`C@jcFf`
+Y8dj"8#da16Nj-6)a-6TTEQ0XG@4P!!)!!!`%XJ"3!%T0B@0TER4[FfJJ5%3k4'9
+cDh4[F#"'EfaNCA)k5@jMEfeTEQFkEh"PER0cE#e66N&3,6%j16Na-M%a1QPZBfa
+eC'8kEh"PER0cE!!#!!!-",-!4`""6@&MD@jdEh0S)%K%1N4PFfYdEh!J4QpXC'9
+b1NPZBfpYD@jR1Qp`C@jcFf`Y8dj"8#da16Nj-6)a-6TMFRP`G'm!!J!!$!5d!%3
+!2NeKBfPZG'pcD#")4$T%CA0VG'p`)%C[E'4PFMT*EQ0[E@PZCcT[F'9ZFh0X,90
+139!Y-6Nj16%b-6%kFh0X!!)!!!`%Y3"!!$T0B@0TER4[FfJJ5%3k4'9cDh4[F#"
+'EfaNCA)k5@jMEfeTEQFkEh"PER0cE#e66N&3,6%j16Na-M%a!!)!!!i%YJ!"&!6
+%$J6%!!-B"-AmEJ6'$J6&!!-B"-ImE36)$J6(!!-B"-RmE!6+$J6*!!-B!"rmD`6
+,#[aV!!3+BfC[E!`%b`!1!!K*EQ0[E@PZC`!#!!!+r'`!"!TMCQpX$!6+!"X!&@p
+`C@jcFf`Y8dj"8#da16Nj-6)a-3!#!!!+r'd!"!TMCQpX$!6)!!d!"fPZBfaeC'8
+!!J!!#[aZ!!3+BfC[E!`%aJ!9!!peER4TG'aPC#"QEfaNCA)!!J!!$!5h!%i!5%e
+KBfPZG'pcD#")4$T%CA0VG'p`)%C[E'4PFMT*EQ0[E@PZCcT[F'9ZFh0X,90139!
+Y-6Nj16%b-6%kBh*jF(4[1RJe-$Pf-`!#!!!"r,%!!!(mX!!!!Ib[!!!"r+i!!'&
+cBh)!!3!-qYlHV3!!!3!!!*G#!!#@3J!!!AB!!$-8-0J!!!!F!AB!$h0MFhS!!!#
+#6Np853!!!)jcBh"d!!!!QP4&@&3!!3#QFh4jE!!!!,j$6d4&!!%!bN*14%`!!!$
+LBA"XG!!!!1j'8N9'!!!!qNP$6L-!!!%'D@0X0!!!!4*TBh-M!!!"(QPMFc3!!!%
+UD'CNFJ!!!6C659T&!!!"3PG3Eh-!!!&1!!$rr`!!!!!!!!!!!)$rre!!!"i!!!!
+!!)$rr`!!"cJ#DH#m"'Mrr`!!!*S!!!!!%iRrr`!!"Pi!!!!!"'Mrr`!!!53!!!!
+!!!$rrb!!!9)!!!!!!!(rra3!!@i#DG`%!)$rr`!!!Pi#DH"X!!$rr`!!!Ri!!!!
+!!)$rr`!!!S-#DH"d!*Err`!!!Si!!!!!!*Err`!!!j)!!!!!!*Err`!!"CB#DH%
+i!*Err`!!"GS#DH%dkF$rr`!!"[`!!!!!rrrrr`!!"a)!!!!!!)$rr`!!"b!!!!!
+!*4S:
diff --git a/openssl/MacOS/opensslconf.h b/openssl/MacOS/opensslconf.h
new file mode 100644
index 0000000..ad557cc
--- /dev/null
+++ b/openssl/MacOS/opensslconf.h
@@ -0,0 +1,116 @@
+/* MacOS/opensslconf.h */
+
+#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
+#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
+#define OPENSSLDIR "/usr/local/ssl"
+#endif
+#endif
+
+#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
+#define IDEA_INT unsigned int
+#endif
+
+#if defined(HEADER_MD2_H) && !defined(MD2_INT)
+#define MD2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC2_H) && !defined(RC2_INT)
+/* I need to put in a mod for the alpha - eay */
+#define RC2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC4_H)
+#if !defined(RC4_INT)
+/* using int types make the structure larger but make the code faster
+ * on most boxes I have tested - up to %20 faster. */
+/*
+ * I don't know what does "most" mean, but declaring "int" is a must on:
+ * - Intel P6 because partial register stalls are very expensive;
+ * - elder Alpha because it lacks byte load/store instructions;
+ */
+#define RC4_INT unsigned char
+#endif
+#if !defined(RC4_CHUNK)
+/*
+ * This enables code handling data aligned at natural CPU word
+ * boundary. See crypto/rc4/rc4_enc.c for further details.
+ */
+#define RC4_CHUNK unsigned long
+#endif
+#endif
+
+#if defined(HEADER_DES_H) && !defined(DES_LONG)
+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+#ifndef DES_LONG
+#define DES_LONG unsigned long
+#endif
+#endif
+
+#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
+#define CONFIG_HEADER_BN_H
+#if __option(longlong)
+#  define BN_LLONG
+#else
+#  undef BN_LLONG
+#endif
+
+/* Should we define BN_DIV2W here? */
+
+/* Only one for the following should be defined */
+/* The prime number generation stuff may not work when
+ * EIGHT_BIT but I don't care since I've only used this mode
+ * for debuging the bignum libraries */
+#undef SIXTY_FOUR_BIT_LONG
+#undef SIXTY_FOUR_BIT
+#define THIRTY_TWO_BIT
+#undef SIXTEEN_BIT
+#undef EIGHT_BIT
+#endif
+
+#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
+#define CONFIG_HEADER_RC4_LOCL_H
+/* if this is defined data[i] is used instead of *data, this is a %20
+ * speedup on x86 */
+#undef RC4_INDEX
+#endif
+
+#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
+#define CONFIG_HEADER_BF_LOCL_H
+#define BF_PTR
+#endif /* HEADER_BF_LOCL_H */
+
+#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
+#define CONFIG_HEADER_DES_LOCL_H
+/* the following is tweaked from a config script, that is why it is a
+ * protected undef/define */
+#ifndef DES_PTR
+#define DES_PTR
+#endif
+
+/* This helps C compiler generate the correct code for multiple functional
+ * units.  It reduces register dependancies at the expense of 2 more
+ * registers */
+#ifndef DES_RISC1
+#define DES_RISC1
+#endif
+
+#ifndef DES_RISC2
+#undef DES_RISC2
+#endif
+
+#if defined(DES_RISC1) && defined(DES_RISC2)
+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
+#endif
+
+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
+ * Very mucy CPU dependant */
+#ifndef DES_UNROLL
+#define DES_UNROLL
+#endif
+
+#endif /* HEADER_DES_LOCL_H */
+
+#ifndef __POWERPC__
+#define MD32_XARRAY
+#endif
diff --git a/openssl/Makefile b/openssl/Makefile
new file mode 100644
index 0000000..8fe8885
--- /dev/null
+++ b/openssl/Makefile
@@ -0,0 +1,640 @@
+### Generated automatically from Makefile.org by Configure.
+
+##
+## Makefile for OpenSSL
+##
+
+VERSION=1.0.0f
+MAJOR=1
+MINOR=0.0
+SHLIB_VERSION_NUMBER=1.0.0
+SHLIB_VERSION_HISTORY=
+SHLIB_MAJOR=1
+SHLIB_MINOR=0.0
+SHLIB_EXT=
+PLATFORM=dist
+OPTIONS= no-gmp no-jpake no-krb5 no-md2 no-rc5 no-rfc3779 no-shared no-store no-zlib no-zlib-dynamic static-engine
+CONFIGURE_ARGS=dist
+SHLIB_TARGET=
+
+# HERE indicates where this Makefile lives.  This can be used to indicate
+# where sub-Makefiles are expected to be.  Currently has very limited usage,
+# and should probably not be bothered with at all.
+HERE=.
+
+# INSTALL_PREFIX is for package builders so that they can configure
+# for, say, /usr/ and yet have everything installed to /tmp/somedir/usr/.
+# Normally it is left empty.
+INSTALL_PREFIX=
+INSTALLTOP=/usr/local/ssl
+
+# Do not edit this manually. Use Configure --openssldir=DIR do change this!
+OPENSSLDIR=/usr/local/ssl
+
+# NO_IDEA - Define to build without the IDEA algorithm
+# NO_RC4  - Define to build without the RC4 algorithm
+# NO_RC2  - Define to build without the RC2 algorithm
+# THREADS - Define when building with threads, you will probably also need any
+#           system defines as well, i.e. _REENTERANT for Solaris 2.[34]
+# TERMIO  - Define the termio terminal subsystem, needed if sgtty is missing.
+# TERMIOS - Define the termios terminal subsystem, Silicon Graphics.
+# LONGCRYPT - Define to use HPUX 10.x's long password modification to crypt(3).
+# DEVRANDOM - Give this the value of the 'random device' if your OS supports
+#           one.  32 bytes will be read from this when the random
+#           number generator is initalised.
+# SSL_FORBID_ENULL - define if you want the server to be not able to use the
+#           NULL encryption ciphers.
+#
+# LOCK_DEBUG - turns on lots of lock debug output :-)
+# REF_CHECK - turn on some xyz_free() assertions.
+# REF_PRINT - prints some stuff on structure free.
+# CRYPTO_MDEBUG - turns on my 'memory leak' detecting stuff
+# MFUNC - Make all Malloc/Free/Realloc calls call
+#       CRYPTO_malloc/CRYPTO_free/CRYPTO_realloc which can be setup to
+#       call application defined callbacks via CRYPTO_set_mem_functions()
+# MD5_ASM needs to be defined to use the x86 assembler for MD5
+# SHA1_ASM needs to be defined to use the x86 assembler for SHA1
+# RMD160_ASM needs to be defined to use the x86 assembler for RIPEMD160
+# Do not define B_ENDIAN or L_ENDIAN if 'unsigned long' == 8.  It must
+# equal 4.
+# PKCS1_CHECK - pkcs1 tests.
+
+CC= cc
+CFLAG= -O
+DEPFLAG= -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_STORE
+PEX_LIBS= 
+EX_LIBS= 
+EXE_EXT= 
+ARFLAGS= 
+AR= ar $(ARFLAGS) r
+RANLIB= /usr/bin/ranlib
+NM= nm
+PERL= /usr/bin/perl
+TAR= tar
+TARFLAGS= --no-recursion
+MAKEDEPPROG=makedepend
+LIBDIR=lib
+
+# We let the C compiler driver to take care of .s files. This is done in
+# order to be excused from maintaining a separate set of architecture
+# dependent assembler flags. E.g. if you throw -mcpu=ultrasparc at SPARC
+# gcc, then the driver will automatically translate it to -xarch=v8plus
+# and pass it down to assembler.
+AS=$(CC) -c
+ASFLAG=$(CFLAG)
+
+# For x86 assembler: Set PROCESSOR to 386 if you want to support
+# the 80386.
+PROCESSOR= 
+
+# CPUID module collects small commonly used assembler snippets
+CPUID_OBJ= mem_clr.o
+BN_ASM= bn_asm.o
+DES_ENC= des_enc.o fcrypt_b.o
+AES_ENC= aes_core.o aes_cbc.o
+BF_ENC= bf_enc.o
+CAST_ENC= c_enc.o
+RC4_ENC= rc4_enc.o rc4_skey.o
+RC5_ENC= rc5_enc.o
+MD5_ASM_OBJ= 
+SHA1_ASM_OBJ= 
+RMD160_ASM_OBJ= 
+WP_ASM_OBJ= wp_block.o
+CMLL_ENC= camellia.o cmll_misc.o cmll_cbc.o
+PERLASM_SCHEME= 
+
+# KRB5 stuff
+KRB5_INCLUDES=
+LIBKRB5=
+
+# Zlib stuff
+ZLIB_INCLUDE=
+LIBZLIB=
+
+DIRS=   crypto ssl engines apps test tools
+ENGDIRS= ccgost
+SHLIBDIRS= crypto ssl
+
+# dirs in crypto to build
+SDIRS=  \
+	objects \
+	md4 md5 sha mdc2 hmac ripemd whrlpool \
+	des aes rc2 rc4 idea bf cast camellia seed modes \
+	bn ec rsa dsa ecdsa dh ecdh dso engine \
+	buffer bio stack lhash rand err \
+	evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \
+	cms pqueue ts
+# keep in mind that the above list is adjusted by ./Configure
+# according to no-xxx arguments...
+
+# tests to perform.  "alltests" is a special word indicating that all tests
+# should be performed.
+TESTS = alltests
+
+MAKEFILE= Makefile
+
+MANDIR=$(OPENSSLDIR)/man
+MAN1=1
+MAN3=3
+MANSUFFIX=
+HTMLSUFFIX=html
+HTMLDIR=$(OPENSSLDIR)/html
+SHELL=/bin/sh
+
+TOP=    .
+ONEDIRS=out tmp
+EDIRS=  times doc bugs util include certs ms shlib mt demos perl sf dep VMS
+WDIRS=  windows
+LIBS=   libcrypto.a libssl.a
+SHARED_CRYPTO=libcrypto$(SHLIB_EXT)
+SHARED_SSL=libssl$(SHLIB_EXT)
+SHARED_LIBS=
+SHARED_LIBS_LINK_EXTS=
+SHARED_LDFLAGS=
+
+GENERAL=        Makefile
+BASENAME=       openssl
+NAME=           $(BASENAME)-$(VERSION)
+TARFILE=        $(NAME).tar
+WTARFILE=       $(NAME)-win.tar
+EXHEADER=       e_os2.h
+HEADER=         e_os.h
+
+all: Makefile build_all openssl.pc libssl.pc libcrypto.pc
+
+# as we stick to -e, CLEARENV ensures that local variables in lower
+# Makefiles remain local and variable. $${VAR+VAR} is tribute to Korn
+# shell, which [annoyingly enough] terminates unset with error if VAR
+# is not present:-( TOP= && unset TOP is tribute to HP-UX /bin/sh,
+# which terminates unset with error if no variable was present:-(
+CLEARENV=	TOP= && unset TOP $${LIB+LIB} $${LIBS+LIBS}	\
+		$${INCLUDE+INCLUDE} $${INCLUDES+INCLUDES}	\
+		$${DIR+DIR} $${DIRS+DIRS} $${SRC+SRC}		\
+		$${LIBSRC+LIBSRC} $${LIBOBJ+LIBOBJ} $${ALL+ALL}	\
+		$${EXHEADER+EXHEADER} $${HEADER+HEADER}		\
+		$${GENERAL+GENERAL} $${CFLAGS+CFLAGS}		\
+		$${ASFLAGS+ASFLAGS} $${AFLAGS+AFLAGS}		\
+		$${LDCMD+LDCMD} $${LDFLAGS+LDFLAGS}		\
+		$${SHAREDCMD+SHAREDCMD} $${SHAREDFLAGS+SHAREDFLAGS}	\
+		$${SHARED_LIB+SHARED_LIB} $${LIBEXTRAS+LIBEXTRAS}
+
+BUILDENV=	PLATFORM='$(PLATFORM)' PROCESSOR='$(PROCESSOR)' \
+		CC='$(CC)' CFLAG='$(CFLAG)' 			\
+		AS='$(CC)' ASFLAG='$(CFLAG) -c'			\
+		AR='$(AR)' NM='$(NM)' RANLIB='$(RANLIB)'	\
+		CROSS_COMPILE='$(CROSS_COMPILE)'	\
+		PERL='$(PERL)' ENGDIRS='$(ENGDIRS)'		\
+		SDIRS='$(SDIRS)' LIBRPATH='$(INSTALLTOP)/$(LIBDIR)'	\
+		INSTALL_PREFIX='$(INSTALL_PREFIX)'		\
+		INSTALLTOP='$(INSTALLTOP)' OPENSSLDIR='$(OPENSSLDIR)'	\
+		LIBDIR='$(LIBDIR)'				\
+		MAKEDEPEND='$$$${TOP}/util/domd $$$${TOP} -MD $(MAKEDEPPROG)' \
+		DEPFLAG='-DOPENSSL_NO_DEPRECATED $(DEPFLAG)'	\
+		MAKEDEPPROG='$(MAKEDEPPROG)'			\
+		SHARED_LDFLAGS='$(SHARED_LDFLAGS)'		\
+		KRB5_INCLUDES='$(KRB5_INCLUDES)' LIBKRB5='$(LIBKRB5)'	\
+		ZLIB_INCLUDE='$(ZLIB_INCLUDE)' LIBZLIB='$(LIBZLIB)'	\
+		EXE_EXT='$(EXE_EXT)' SHARED_LIBS='$(SHARED_LIBS)'	\
+		SHLIB_EXT='$(SHLIB_EXT)' SHLIB_TARGET='$(SHLIB_TARGET)'	\
+		PEX_LIBS='$(PEX_LIBS)' EX_LIBS='$(EX_LIBS)'	\
+		CPUID_OBJ='$(CPUID_OBJ)'			\
+		BN_ASM='$(BN_ASM)' DES_ENC='$(DES_ENC)' 	\
+		AES_ENC='$(AES_ENC)' CMLL_ENC='$(CMLL_ENC)'	\
+		BF_ENC='$(BF_ENC)' CAST_ENC='$(CAST_ENC)'	\
+		RC4_ENC='$(RC4_ENC)' RC5_ENC='$(RC5_ENC)'	\
+		SHA1_ASM_OBJ='$(SHA1_ASM_OBJ)'			\
+		MD5_ASM_OBJ='$(MD5_ASM_OBJ)'			\
+		RMD160_ASM_OBJ='$(RMD160_ASM_OBJ)'		\
+		WP_ASM_OBJ='$(WP_ASM_OBJ)'			\
+		PERLASM_SCHEME='$(PERLASM_SCHEME)'		\
+		THIS=$${THIS:-$@} MAKEFILE=Makefile MAKEOVERRIDES=
+# MAKEOVERRIDES= effectively "equalizes" GNU-ish and SysV-ish make flavors,
+# which in turn eliminates ambiguities in variable treatment with -e.
+
+# BUILD_CMD is a generic macro to build a given target in a given
+# subdirectory.  The target must be given through the shell variable
+# `target' and the subdirectory to build in must be given through `dir'.
+# This macro shouldn't be used directly, use RECURSIVE_BUILD_CMD or
+# BUILD_ONE_CMD instead.
+#
+# BUILD_ONE_CMD is a macro to build a given target in a given
+# subdirectory if that subdirectory is part of $(DIRS).  It requires
+# exactly the same shell variables as BUILD_CMD.
+#
+# RECURSIVE_BUILD_CMD is a macro to build a given target in all
+# subdirectories defined in $(DIRS).  It requires that the target
+# is given through the shell variable `target'.
+BUILD_CMD=  if [ -d "$$dir" ]; then \
+	    (	cd $$dir && echo "making $$target in $$dir..." && \
+		$(CLEARENV) && $(MAKE) -e $(BUILDENV) TOP=.. DIR=$$dir $$target \
+	    ) || exit 1; \
+	    fi
+RECURSIVE_BUILD_CMD=for dir in $(DIRS); do $(BUILD_CMD); done
+BUILD_ONE_CMD=\
+	if expr " $(DIRS) " : ".* $$dir " >/dev/null 2>&1; then \
+		$(BUILD_CMD); \
+	fi
+
+reflect:
+	@[ -n "$(THIS)" ] && $(CLEARENV) && $(MAKE) $(THIS) -e $(BUILDENV)
+
+sub_all: build_all
+build_all: build_libs build_apps build_tests build_tools
+
+build_libs: build_crypto build_ssl build_engines
+
+build_crypto:
+	@dir=crypto; target=all; $(BUILD_ONE_CMD)
+build_ssl:
+	@dir=ssl; target=all; $(BUILD_ONE_CMD)
+build_engines:
+	@dir=engines; target=all; $(BUILD_ONE_CMD)
+build_apps:
+	@dir=apps; target=all; $(BUILD_ONE_CMD)
+build_tests:
+	@dir=test; target=all; $(BUILD_ONE_CMD)
+build_tools:
+	@dir=tools; target=all; $(BUILD_ONE_CMD)
+
+all_testapps: build_libs build_testapps
+build_testapps:
+	@dir=crypto; target=testapps; $(BUILD_ONE_CMD)
+
+libcrypto$(SHLIB_EXT): libcrypto.a
+	@if [ "$(SHLIB_TARGET)" != "" ]; then \
+		$(MAKE) SHLIBDIRS=crypto build-shared; \
+	else \
+		echo "There's no support for shared libraries on this platform" >&2; \
+		exit 1; \
+	fi
+
+libssl$(SHLIB_EXT): libcrypto$(SHLIB_EXT) libssl.a
+	@if [ "$(SHLIB_TARGET)" != "" ]; then \
+		$(MAKE) SHLIBDIRS=ssl SHLIBDEPS='-lcrypto' build-shared; \
+	else \
+		echo "There's no support for shared libraries on this platform" >&2; \
+		exit 1; \
+	fi
+
+clean-shared:
+	@set -e; for i in $(SHLIBDIRS); do \
+		if [ -n "$(SHARED_LIBS_LINK_EXTS)" ]; then \
+			tmp="$(SHARED_LIBS_LINK_EXTS)"; \
+			for j in $${tmp:-x}; do \
+				( set -x; rm -f lib$$i$$j ); \
+			done; \
+		fi; \
+		( set -x; rm -f lib$$i$(SHLIB_EXT) ); \
+		if [ "$(PLATFORM)" = "Cygwin" ]; then \
+			( set -x; rm -f cyg$$i$(SHLIB_EXT) lib$$i$(SHLIB_EXT).a ); \
+		fi; \
+	done
+
+link-shared:
+	@ set -e; for i in $(SHLIBDIRS); do \
+		$(MAKE) -f $(HERE)/Makefile.shared -e $(BUILDENV) \
+			LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \
+			LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \
+			symlink.$(SHLIB_TARGET); \
+		libs="$$libs -l$$i"; \
+	done
+
+build-shared: do_$(SHLIB_TARGET) link-shared
+
+do_$(SHLIB_TARGET):
+	@ set -e; libs='-L. $(SHLIBDEPS)'; for i in $(SHLIBDIRS); do \
+		if [ "$$i" = "ssl" -a -n "$(LIBKRB5)" ]; then \
+			libs="$(LIBKRB5) $$libs"; \
+		fi; \
+		$(CLEARENV) && $(MAKE) -f Makefile.shared -e $(BUILDENV) \
+			LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \
+			LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \
+			LIBDEPS="$$libs $(EX_LIBS)" \
+			link_a.$(SHLIB_TARGET); \
+		libs="-l$$i $$libs"; \
+	done
+
+libcrypto.pc: Makefile
+	@ ( echo 'prefix=$(INSTALLTOP)'; \
+	    echo 'exec_prefix=$${prefix}'; \
+	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
+	    echo 'includedir=$${prefix}/include'; \
+	    echo ''; \
+	    echo 'Name: OpenSSL-libcrypto'; \
+	    echo 'Description: OpenSSL cryptography library'; \
+	    echo 'Version: '$(VERSION); \
+	    echo 'Requires: '; \
+	    echo 'Libs: -L$${libdir} -lcrypto $(EX_LIBS)'; \
+	    echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libcrypto.pc
+
+libssl.pc: Makefile
+	@ ( echo 'prefix=$(INSTALLTOP)'; \
+	    echo 'exec_prefix=$${prefix}'; \
+	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
+	    echo 'includedir=$${prefix}/include'; \
+	    echo ''; \
+	    echo 'Name: OpenSSL'; \
+	    echo 'Description: Secure Sockets Layer and cryptography libraries'; \
+	    echo 'Version: '$(VERSION); \
+	    echo 'Requires: '; \
+	    echo 'Libs: -L$${libdir} -lssl -lcrypto $(EX_LIBS)'; \
+	    echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libssl.pc
+
+openssl.pc: Makefile
+	@ ( echo 'prefix=$(INSTALLTOP)'; \
+	    echo 'exec_prefix=$${prefix}'; \
+	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
+	    echo 'includedir=$${prefix}/include'; \
+	    echo ''; \
+	    echo 'Name: OpenSSL'; \
+	    echo 'Description: Secure Sockets Layer and cryptography libraries and tools'; \
+	    echo 'Version: '$(VERSION); \
+	    echo 'Requires: '; \
+	    echo 'Libs: -L$${libdir} -lssl -lcrypto $(EX_LIBS)'; \
+	    echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > openssl.pc
+
+Makefile: Makefile.org Configure config
+	@echo "Makefile is older than Makefile.org, Configure or config."
+	@echo "Reconfigure the source tree (via './config' or 'perl Configure'), please."
+	@false
+
+libclean:
+	rm -f *.map *.so *.so.* *.dll engines/*.so engines/*.dll *.a engines/*.a */lib */*/lib
+
+clean:	libclean
+	rm -f shlib/*.o *.o core a.out fluff rehash.time testlog make.log cctest cctest.c
+	@set -e; target=clean; $(RECURSIVE_BUILD_CMD)
+	rm -f $(LIBS)
+	rm -f openssl.pc libssl.pc libcrypto.pc
+	rm -f speed.* .pure
+	rm -f $(TARFILE)
+	@set -e; for i in $(ONEDIRS) ;\
+	do \
+	rm -fr $$i/*; \
+	done
+
+makefile.one: files
+	$(PERL) util/mk1mf.pl >makefile.one; \
+	sh util/do_ms.sh
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile > $(TOP)/MINFO
+	@set -e; target=files; $(RECURSIVE_BUILD_CMD)
+
+links:
+	@$(PERL) $(TOP)/util/mkdir-p.pl include/openssl
+	@$(PERL) $(TOP)/util/mklink.pl include/openssl $(EXHEADER)
+	@set -e; target=links; $(RECURSIVE_BUILD_CMD)
+
+gentests:
+	@(cd test && echo "generating dummy tests (if needed)..." && \
+	$(CLEARENV) && $(MAKE) -e $(BUILDENV) TESTS='$(TESTS)' OPENSSL_DEBUG_MEMORY=on generate );
+
+dclean:
+	rm -rf *.bak include/openssl certs/.0
+	@set -e; target=dclean; $(RECURSIVE_BUILD_CMD)
+
+rehash: rehash.time
+rehash.time: certs apps
+	@if [ -z "$(CROSS_COMPILE)" ]; then \
+		(OPENSSL="`pwd`/util/opensslwrap.sh"; \
+		[ -x "apps/openssl.exe" ] && OPENSSL="apps/openssl.exe" || :; \
+		OPENSSL_DEBUG_MEMORY=on; \
+		export OPENSSL OPENSSL_DEBUG_MEMORY; \
+		$(PERL) tools/c_rehash certs) && \
+		touch rehash.time; \
+	else :; fi
+
+test:   tests
+
+tests: rehash
+	@(cd test && echo "testing..." && \
+	$(CLEARENV) && $(MAKE) -e $(BUILDENV) TOP=.. TESTS='$(TESTS)' OPENSSL_DEBUG_MEMORY=on OPENSSL_CONF=../apps/openssl.cnf tests );
+	OPENSSL_CONF=apps/openssl.cnf util/opensslwrap.sh version -a
+
+report:
+	@$(PERL) util/selftest.pl
+
+depend:
+	@set -e; target=depend; $(RECURSIVE_BUILD_CMD)
+
+lint:
+	@set -e; target=lint; $(RECURSIVE_BUILD_CMD)
+
+tags:
+	rm -f TAGS
+	find . -name '[^.]*.[ch]' | xargs etags -a
+
+errors:
+	$(PERL) util/mkerr.pl -recurse -write
+	(cd engines; $(MAKE) PERL=$(PERL) errors)
+	$(PERL) util/ck_errf.pl */*.c */*/*.c
+
+stacks:
+	$(PERL) util/mkstack.pl -write
+
+util/libeay.num::
+	$(PERL) util/mkdef.pl crypto update
+
+util/ssleay.num::
+	$(PERL) util/mkdef.pl ssl update
+
+crypto/objects/obj_dat.h: crypto/objects/obj_dat.pl crypto/objects/obj_mac.h
+	$(PERL) crypto/objects/obj_dat.pl crypto/objects/obj_mac.h crypto/objects/obj_dat.h
+crypto/objects/obj_mac.h: crypto/objects/objects.pl crypto/objects/objects.txt crypto/objects/obj_mac.num
+	$(PERL) crypto/objects/objects.pl crypto/objects/objects.txt crypto/objects/obj_mac.num crypto/objects/obj_mac.h
+crypto/objects/obj_xref.h: crypto/objects/objxref.pl crypto/objects/obj_xref.txt crypto/objects/obj_mac.num
+	$(PERL) crypto/objects/objxref.pl crypto/objects/obj_mac.num crypto/objects/obj_xref.txt >crypto/objects/obj_xref.h
+
+apps/openssl-vms.cnf: apps/openssl.cnf
+	$(PERL) VMS/VMSify-conf.pl < apps/openssl.cnf > apps/openssl-vms.cnf
+
+crypto/bn/bn_prime.h: crypto/bn/bn_prime.pl
+	$(PERL) crypto/bn/bn_prime.pl >crypto/bn/bn_prime.h
+
+
+TABLE: Configure
+	(echo 'Output of `Configure TABLE'"':"; \
+	$(PERL) Configure TABLE) > TABLE
+
+update: errors stacks util/libeay.num util/ssleay.num crypto/objects/obj_dat.h crypto/objects/obj_xref.h apps/openssl-vms.cnf crypto/bn/bn_prime.h TABLE depend
+
+# Build distribution tar-file. As the list of files returned by "find" is
+# pretty long, on several platforms a "too many arguments" error or similar
+# would occur. Therefore the list of files is temporarily stored into a file
+# and read directly, requiring GNU-Tar. Call "make TAR=gtar dist" if the normal
+# tar does not support the --files-from option.
+tar:
+	find . -type d -print | xargs chmod 755
+	find . -type f -print | xargs chmod a+r
+	find . -type f -perm -0100 -print | xargs chmod a+x
+	find * \! -path CVS/\* \! -path \*/CVS/\* \! -name CVS \! -name .cvsignore \! -name STATUS \! -name TABLE | sort > ../$(TARFILE).list; \
+	$(TAR) $(TARFLAGS) --files-from ../$(TARFILE).list -cvf - | \
+	tardy --user_number=0  --user_name=openssl \
+	      --group_number=0 --group_name=openssl \
+	      --prefix=openssl-$(VERSION) - |\
+	gzip --best >../$(TARFILE).gz; \
+	rm -f ../$(TARFILE).list; \
+	ls -l ../$(TARFILE).gz
+
+tar-snap:
+	@$(TAR) $(TARFLAGS) -cvf - \
+		`find * \! -path CVS/\* \! -path \*/CVS/\* \! -name CVS \! -name .cvsignore \! -name STATUS \! -name TABLE \! -name '*.o' \! -name '*.a' \! -name '*.so' \! -name '*.so.*'  \! -name 'openssl' \! -name '*test' \! -name '.#*' \! -name '*~' | sort` |\
+	tardy --user_number=0  --user_name=openssl \
+	      --group_number=0 --group_name=openssl \
+	      --prefix=openssl-$(VERSION) - > ../$(TARFILE);\
+	ls -l ../$(TARFILE)
+
+dist:   
+	$(PERL) Configure dist
+	@$(MAKE) dist_pem_h
+	@$(MAKE) SDIRS='$(SDIRS)' clean
+	@$(MAKE) TAR='$(TAR)' TARFLAGS='$(TARFLAGS)' tar
+
+dist_pem_h:
+	(cd crypto/pem; $(MAKE) -e $(BUILDENV) pem.h; $(MAKE) clean)
+
+install: all install_docs install_sw
+
+install_sw:
+	@$(PERL) $(TOP)/util/mkdir-p.pl $(INSTALL_PREFIX)$(INSTALLTOP)/bin \
+		$(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR) \
+		$(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines \
+		$(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig \
+		$(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl \
+		$(INSTALL_PREFIX)$(OPENSSLDIR)/misc \
+		$(INSTALL_PREFIX)$(OPENSSLDIR)/certs \
+		$(INSTALL_PREFIX)$(OPENSSLDIR)/private
+	@set -e; headerlist="$(EXHEADER)"; for i in $$headerlist;\
+	do \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+	@set -e; target=install; $(RECURSIVE_BUILD_CMD)
+	@set -e; for i in $(LIBS) ;\
+	do \
+		if [ -f "$$i" ]; then \
+		(       echo installing $$i; \
+			cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+			$(RANLIB) $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+			chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+			mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i ); \
+		fi; \
+	done;
+	@set -e; if [ -n "$(SHARED_LIBS)" ]; then \
+		tmp="$(SHARED_LIBS)"; \
+		for i in $${tmp:-x}; \
+		do \
+			if [ -f "$$i" -o -f "$$i.a" ]; then \
+			(       echo installing $$i; \
+				if [ "$(PLATFORM)" != "Cygwin" ]; then \
+					cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+					chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+					mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i; \
+				else \
+					c=`echo $$i | sed 's/^lib\(.*\)\.dll\.a/cyg\1-$(SHLIB_VERSION_NUMBER).dll/'`; \
+					cp $$c $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \
+					chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \
+					mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c; \
+					cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+					chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+					mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i; \
+				fi ); \
+				if expr $(PLATFORM) : 'mingw' > /dev/null; then \
+				(	case $$i in \
+						*crypto*) i=libeay32.dll;; \
+						*ssl*)    i=ssleay32.dll;; \
+					esac; \
+					echo installing $$i; \
+	 				cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
+	 				chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
+	 				mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i ); \
+				fi; \
+			fi; \
+		done; \
+		(	here="`pwd`"; \
+			cd $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR); \
+			$(MAKE) -f $$here/Makefile HERE="$$here" link-shared ); \
+		if [ "$(INSTALLTOP)" != "/usr" ]; then \
+			echo 'OpenSSL shared libraries have been installed in:'; \
+			echo '  $(INSTALLTOP)'; \
+			echo ''; \
+			sed -e '1,/^$$/d' doc/openssl-shared.txt; \
+		fi; \
+	fi
+	cp libcrypto.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libcrypto.pc
+	cp libssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libssl.pc
+	cp openssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/openssl.pc
+
+install_html_docs:
+	here="`pwd`"; \
+	for subdir in apps crypto ssl; do \
+		mkdir -p $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir; \
+		for i in doc/$$subdir/*.pod; do \
+			fn=`basename $$i .pod`; \
+			echo "installing html/$$fn.$(HTMLSUFFIX)"; \
+			cat $$i \
+			| sed -r 's/L<([^)]*)(\([0-9]\))?\|([^)]*)(\([0-9]\))?>/L<\1|\3>/g' \
+			| pod2html --podroot=doc --htmlroot=.. --podpath=apps:crypto:ssl \
+			| sed -r 's/<!DOCTYPE.*//g' \
+			> $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir/$$fn.$(HTMLSUFFIX); \
+			$(PERL) util/extract-names.pl < $$i | \
+				grep -v $$filecase "^$$fn\$$" | \
+				(cd $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir; \
+				 while read n; do \
+					PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$(HTMLSUFFIX) "$$n".$(HTMLSUFFIX); \
+				 done); \
+		done; \
+	done
+
+install_docs:
+	@$(PERL) $(TOP)/util/mkdir-p.pl \
+		$(INSTALL_PREFIX)$(MANDIR)/man1 \
+		$(INSTALL_PREFIX)$(MANDIR)/man3 \
+		$(INSTALL_PREFIX)$(MANDIR)/man5 \
+		$(INSTALL_PREFIX)$(MANDIR)/man7
+	@pod2man="`cd ./util; ./pod2mantest $(PERL)`"; \
+	here="`pwd`"; \
+	filecase=; \
+	if [ "$(PLATFORM)" = "DJGPP" -o "$(PLATFORM)" = "Cygwin" -o "$(PLATFORM)" = "mingw" ]; then \
+		filecase=-i; \
+	fi; \
+	set -e; for i in doc/apps/*.pod; do \
+		fn=`basename $$i .pod`; \
+		sec=`$(PERL) util/extract-section.pl 1 < $$i`; \
+		echo "installing man$$sec/$$fn.$${sec}$(MANSUFFIX)"; \
+		(cd `$(PERL) util/dirname.pl $$i`; \
+		sh -c "$$pod2man \
+			--section=$$sec --center=OpenSSL \
+			--release=$(VERSION) `basename $$i`") \
+			>  $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$fn.$${sec}$(MANSUFFIX); \
+		$(PERL) util/extract-names.pl < $$i | \
+			(grep -v $$filecase "^$$fn\$$"; true) | \
+			(grep -v "[	]"; true) | \
+			(cd $(INSTALL_PREFIX)$(MANDIR)/man$$sec/; \
+			 while read n; do \
+				PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$${sec}$(MANSUFFIX) "$$n".$${sec}$(MANSUFFIX); \
+			 done); \
+	done; \
+	set -e; for i in doc/crypto/*.pod doc/ssl/*.pod; do \
+		fn=`basename $$i .pod`; \
+		sec=`$(PERL) util/extract-section.pl 3 < $$i`; \
+		echo "installing man$$sec/$$fn.$${sec}$(MANSUFFIX)"; \
+		(cd `$(PERL) util/dirname.pl $$i`; \
+		sh -c "$$pod2man \
+			--section=$$sec --center=OpenSSL \
+			--release=$(VERSION) `basename $$i`") \
+			>  $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$fn.$${sec}$(MANSUFFIX); \
+		$(PERL) util/extract-names.pl < $$i | \
+			(grep -v $$filecase "^$$fn\$$"; true) | \
+			(grep -v "[	]"; true) | \
+			(cd $(INSTALL_PREFIX)$(MANDIR)/man$$sec/; \
+			 while read n; do \
+				PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$${sec}$(MANSUFFIX) "$$n".$${sec}$(MANSUFFIX); \
+			 done); \
+	done
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
diff --git a/openssl/Makefile.org b/openssl/Makefile.org
new file mode 100644
index 0000000..fb0af7e
--- /dev/null
+++ b/openssl/Makefile.org
@@ -0,0 +1,638 @@
+##
+## Makefile for OpenSSL
+##
+
+VERSION=
+MAJOR=
+MINOR=
+SHLIB_VERSION_NUMBER=
+SHLIB_VERSION_HISTORY=
+SHLIB_MAJOR=
+SHLIB_MINOR=
+SHLIB_EXT=
+PLATFORM=dist
+OPTIONS=
+CONFIGURE_ARGS=
+SHLIB_TARGET=
+
+# HERE indicates where this Makefile lives.  This can be used to indicate
+# where sub-Makefiles are expected to be.  Currently has very limited usage,
+# and should probably not be bothered with at all.
+HERE=.
+
+# INSTALL_PREFIX is for package builders so that they can configure
+# for, say, /usr/ and yet have everything installed to /tmp/somedir/usr/.
+# Normally it is left empty.
+INSTALL_PREFIX=
+INSTALLTOP=/usr/local/ssl
+
+# Do not edit this manually. Use Configure --openssldir=DIR do change this!
+OPENSSLDIR=/usr/local/ssl
+
+# NO_IDEA - Define to build without the IDEA algorithm
+# NO_RC4  - Define to build without the RC4 algorithm
+# NO_RC2  - Define to build without the RC2 algorithm
+# THREADS - Define when building with threads, you will probably also need any
+#           system defines as well, i.e. _REENTERANT for Solaris 2.[34]
+# TERMIO  - Define the termio terminal subsystem, needed if sgtty is missing.
+# TERMIOS - Define the termios terminal subsystem, Silicon Graphics.
+# LONGCRYPT - Define to use HPUX 10.x's long password modification to crypt(3).
+# DEVRANDOM - Give this the value of the 'random device' if your OS supports
+#           one.  32 bytes will be read from this when the random
+#           number generator is initalised.
+# SSL_FORBID_ENULL - define if you want the server to be not able to use the
+#           NULL encryption ciphers.
+#
+# LOCK_DEBUG - turns on lots of lock debug output :-)
+# REF_CHECK - turn on some xyz_free() assertions.
+# REF_PRINT - prints some stuff on structure free.
+# CRYPTO_MDEBUG - turns on my 'memory leak' detecting stuff
+# MFUNC - Make all Malloc/Free/Realloc calls call
+#       CRYPTO_malloc/CRYPTO_free/CRYPTO_realloc which can be setup to
+#       call application defined callbacks via CRYPTO_set_mem_functions()
+# MD5_ASM needs to be defined to use the x86 assembler for MD5
+# SHA1_ASM needs to be defined to use the x86 assembler for SHA1
+# RMD160_ASM needs to be defined to use the x86 assembler for RIPEMD160
+# Do not define B_ENDIAN or L_ENDIAN if 'unsigned long' == 8.  It must
+# equal 4.
+# PKCS1_CHECK - pkcs1 tests.
+
+CC= cc
+CFLAG= -O
+DEPFLAG= 
+PEX_LIBS= 
+EX_LIBS= 
+EXE_EXT= 
+ARFLAGS=
+AR=ar $(ARFLAGS) r
+RANLIB= ranlib
+NM= nm
+PERL= perl
+TAR= tar
+TARFLAGS= --no-recursion
+MAKEDEPPROG=makedepend
+LIBDIR=lib
+
+# We let the C compiler driver to take care of .s files. This is done in
+# order to be excused from maintaining a separate set of architecture
+# dependent assembler flags. E.g. if you throw -mcpu=ultrasparc at SPARC
+# gcc, then the driver will automatically translate it to -xarch=v8plus
+# and pass it down to assembler.
+AS=$(CC) -c
+ASFLAG=$(CFLAG)
+
+# For x86 assembler: Set PROCESSOR to 386 if you want to support
+# the 80386.
+PROCESSOR=
+
+# CPUID module collects small commonly used assembler snippets
+CPUID_OBJ= 
+BN_ASM= bn_asm.o
+DES_ENC= des_enc.o fcrypt_b.o
+AES_ENC= aes_core.o aes_cbc.o
+BF_ENC= bf_enc.o
+CAST_ENC= c_enc.o
+RC4_ENC= rc4_enc.o
+RC5_ENC= rc5_enc.o
+MD5_ASM_OBJ= 
+SHA1_ASM_OBJ= 
+RMD160_ASM_OBJ= 
+WP_ASM_OBJ=
+CMLL_ENC=
+PERLASM_SCHEME=
+
+# KRB5 stuff
+KRB5_INCLUDES=
+LIBKRB5=
+
+# Zlib stuff
+ZLIB_INCLUDE=
+LIBZLIB=
+
+DIRS=   crypto ssl engines apps test tools
+ENGDIRS= ccgost
+SHLIBDIRS= crypto ssl
+
+# dirs in crypto to build
+SDIRS=  \
+	objects \
+	md2 md4 md5 sha mdc2 hmac ripemd whrlpool \
+	des aes rc2 rc4 rc5 idea bf cast camellia seed modes \
+	bn ec rsa dsa ecdsa dh ecdh dso engine \
+	buffer bio stack lhash rand err \
+	evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \
+	cms pqueue ts jpake store
+# keep in mind that the above list is adjusted by ./Configure
+# according to no-xxx arguments...
+
+# tests to perform.  "alltests" is a special word indicating that all tests
+# should be performed.
+TESTS = alltests
+
+MAKEFILE= Makefile
+
+MANDIR=$(OPENSSLDIR)/man
+MAN1=1
+MAN3=3
+MANSUFFIX=
+HTMLSUFFIX=html
+HTMLDIR=$(OPENSSLDIR)/html
+SHELL=/bin/sh
+
+TOP=    .
+ONEDIRS=out tmp
+EDIRS=  times doc bugs util include certs ms shlib mt demos perl sf dep VMS
+WDIRS=  windows
+LIBS=   libcrypto.a libssl.a
+SHARED_CRYPTO=libcrypto$(SHLIB_EXT)
+SHARED_SSL=libssl$(SHLIB_EXT)
+SHARED_LIBS=
+SHARED_LIBS_LINK_EXTS=
+SHARED_LDFLAGS=
+
+GENERAL=        Makefile
+BASENAME=       openssl
+NAME=           $(BASENAME)-$(VERSION)
+TARFILE=        $(NAME).tar
+WTARFILE=       $(NAME)-win.tar
+EXHEADER=       e_os2.h
+HEADER=         e_os.h
+
+all: Makefile build_all openssl.pc libssl.pc libcrypto.pc
+
+# as we stick to -e, CLEARENV ensures that local variables in lower
+# Makefiles remain local and variable. $${VAR+VAR} is tribute to Korn
+# shell, which [annoyingly enough] terminates unset with error if VAR
+# is not present:-( TOP= && unset TOP is tribute to HP-UX /bin/sh,
+# which terminates unset with error if no variable was present:-(
+CLEARENV=	TOP= && unset TOP $${LIB+LIB} $${LIBS+LIBS}	\
+		$${INCLUDE+INCLUDE} $${INCLUDES+INCLUDES}	\
+		$${DIR+DIR} $${DIRS+DIRS} $${SRC+SRC}		\
+		$${LIBSRC+LIBSRC} $${LIBOBJ+LIBOBJ} $${ALL+ALL}	\
+		$${EXHEADER+EXHEADER} $${HEADER+HEADER}		\
+		$${GENERAL+GENERAL} $${CFLAGS+CFLAGS}		\
+		$${ASFLAGS+ASFLAGS} $${AFLAGS+AFLAGS}		\
+		$${LDCMD+LDCMD} $${LDFLAGS+LDFLAGS}		\
+		$${SHAREDCMD+SHAREDCMD} $${SHAREDFLAGS+SHAREDFLAGS}	\
+		$${SHARED_LIB+SHARED_LIB} $${LIBEXTRAS+LIBEXTRAS}
+
+BUILDENV=	PLATFORM='$(PLATFORM)' PROCESSOR='$(PROCESSOR)' \
+		CC='$(CC)' CFLAG='$(CFLAG)' 			\
+		AS='$(CC)' ASFLAG='$(CFLAG) -c'			\
+		AR='$(AR)' NM='$(NM)' RANLIB='$(RANLIB)'	\
+		CROSS_COMPILE='$(CROSS_COMPILE)'	\
+		PERL='$(PERL)' ENGDIRS='$(ENGDIRS)'		\
+		SDIRS='$(SDIRS)' LIBRPATH='$(INSTALLTOP)/$(LIBDIR)'	\
+		INSTALL_PREFIX='$(INSTALL_PREFIX)'		\
+		INSTALLTOP='$(INSTALLTOP)' OPENSSLDIR='$(OPENSSLDIR)'	\
+		LIBDIR='$(LIBDIR)'				\
+		MAKEDEPEND='$$$${TOP}/util/domd $$$${TOP} -MD $(MAKEDEPPROG)' \
+		DEPFLAG='-DOPENSSL_NO_DEPRECATED $(DEPFLAG)'	\
+		MAKEDEPPROG='$(MAKEDEPPROG)'			\
+		SHARED_LDFLAGS='$(SHARED_LDFLAGS)'		\
+		KRB5_INCLUDES='$(KRB5_INCLUDES)' LIBKRB5='$(LIBKRB5)'	\
+		ZLIB_INCLUDE='$(ZLIB_INCLUDE)' LIBZLIB='$(LIBZLIB)'	\
+		EXE_EXT='$(EXE_EXT)' SHARED_LIBS='$(SHARED_LIBS)'	\
+		SHLIB_EXT='$(SHLIB_EXT)' SHLIB_TARGET='$(SHLIB_TARGET)'	\
+		PEX_LIBS='$(PEX_LIBS)' EX_LIBS='$(EX_LIBS)'	\
+		CPUID_OBJ='$(CPUID_OBJ)'			\
+		BN_ASM='$(BN_ASM)' DES_ENC='$(DES_ENC)' 	\
+		AES_ENC='$(AES_ENC)' CMLL_ENC='$(CMLL_ENC)'	\
+		BF_ENC='$(BF_ENC)' CAST_ENC='$(CAST_ENC)'	\
+		RC4_ENC='$(RC4_ENC)' RC5_ENC='$(RC5_ENC)'	\
+		SHA1_ASM_OBJ='$(SHA1_ASM_OBJ)'			\
+		MD5_ASM_OBJ='$(MD5_ASM_OBJ)'			\
+		RMD160_ASM_OBJ='$(RMD160_ASM_OBJ)'		\
+		WP_ASM_OBJ='$(WP_ASM_OBJ)'			\
+		PERLASM_SCHEME='$(PERLASM_SCHEME)'		\
+		THIS=$${THIS:-$@} MAKEFILE=Makefile MAKEOVERRIDES=
+# MAKEOVERRIDES= effectively "equalizes" GNU-ish and SysV-ish make flavors,
+# which in turn eliminates ambiguities in variable treatment with -e.
+
+# BUILD_CMD is a generic macro to build a given target in a given
+# subdirectory.  The target must be given through the shell variable
+# `target' and the subdirectory to build in must be given through `dir'.
+# This macro shouldn't be used directly, use RECURSIVE_BUILD_CMD or
+# BUILD_ONE_CMD instead.
+#
+# BUILD_ONE_CMD is a macro to build a given target in a given
+# subdirectory if that subdirectory is part of $(DIRS).  It requires
+# exactly the same shell variables as BUILD_CMD.
+#
+# RECURSIVE_BUILD_CMD is a macro to build a given target in all
+# subdirectories defined in $(DIRS).  It requires that the target
+# is given through the shell variable `target'.
+BUILD_CMD=  if [ -d "$$dir" ]; then \
+	    (	cd $$dir && echo "making $$target in $$dir..." && \
+		$(CLEARENV) && $(MAKE) -e $(BUILDENV) TOP=.. DIR=$$dir $$target \
+	    ) || exit 1; \
+	    fi
+RECURSIVE_BUILD_CMD=for dir in $(DIRS); do $(BUILD_CMD); done
+BUILD_ONE_CMD=\
+	if expr " $(DIRS) " : ".* $$dir " >/dev/null 2>&1; then \
+		$(BUILD_CMD); \
+	fi
+
+reflect:
+	@[ -n "$(THIS)" ] && $(CLEARENV) && $(MAKE) $(THIS) -e $(BUILDENV)
+
+sub_all: build_all
+build_all: build_libs build_apps build_tests build_tools
+
+build_libs: build_crypto build_ssl build_engines
+
+build_crypto:
+	@dir=crypto; target=all; $(BUILD_ONE_CMD)
+build_ssl:
+	@dir=ssl; target=all; $(BUILD_ONE_CMD)
+build_engines:
+	@dir=engines; target=all; $(BUILD_ONE_CMD)
+build_apps:
+	@dir=apps; target=all; $(BUILD_ONE_CMD)
+build_tests:
+	@dir=test; target=all; $(BUILD_ONE_CMD)
+build_tools:
+	@dir=tools; target=all; $(BUILD_ONE_CMD)
+
+all_testapps: build_libs build_testapps
+build_testapps:
+	@dir=crypto; target=testapps; $(BUILD_ONE_CMD)
+
+libcrypto$(SHLIB_EXT): libcrypto.a
+	@if [ "$(SHLIB_TARGET)" != "" ]; then \
+		$(MAKE) SHLIBDIRS=crypto build-shared; \
+	else \
+		echo "There's no support for shared libraries on this platform" >&2; \
+		exit 1; \
+	fi
+
+libssl$(SHLIB_EXT): libcrypto$(SHLIB_EXT) libssl.a
+	@if [ "$(SHLIB_TARGET)" != "" ]; then \
+		$(MAKE) SHLIBDIRS=ssl SHLIBDEPS='-lcrypto' build-shared; \
+	else \
+		echo "There's no support for shared libraries on this platform" >&2; \
+		exit 1; \
+	fi
+
+clean-shared:
+	@set -e; for i in $(SHLIBDIRS); do \
+		if [ -n "$(SHARED_LIBS_LINK_EXTS)" ]; then \
+			tmp="$(SHARED_LIBS_LINK_EXTS)"; \
+			for j in $${tmp:-x}; do \
+				( set -x; rm -f lib$$i$$j ); \
+			done; \
+		fi; \
+		( set -x; rm -f lib$$i$(SHLIB_EXT) ); \
+		if [ "$(PLATFORM)" = "Cygwin" ]; then \
+			( set -x; rm -f cyg$$i$(SHLIB_EXT) lib$$i$(SHLIB_EXT).a ); \
+		fi; \
+	done
+
+link-shared:
+	@ set -e; for i in $(SHLIBDIRS); do \
+		$(MAKE) -f $(HERE)/Makefile.shared -e $(BUILDENV) \
+			LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \
+			LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \
+			symlink.$(SHLIB_TARGET); \
+		libs="$$libs -l$$i"; \
+	done
+
+build-shared: do_$(SHLIB_TARGET) link-shared
+
+do_$(SHLIB_TARGET):
+	@ set -e; libs='-L. $(SHLIBDEPS)'; for i in $(SHLIBDIRS); do \
+		if [ "$$i" = "ssl" -a -n "$(LIBKRB5)" ]; then \
+			libs="$(LIBKRB5) $$libs"; \
+		fi; \
+		$(CLEARENV) && $(MAKE) -f Makefile.shared -e $(BUILDENV) \
+			LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \
+			LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \
+			LIBDEPS="$$libs $(EX_LIBS)" \
+			link_a.$(SHLIB_TARGET); \
+		libs="-l$$i $$libs"; \
+	done
+
+libcrypto.pc: Makefile
+	@ ( echo 'prefix=$(INSTALLTOP)'; \
+	    echo 'exec_prefix=$${prefix}'; \
+	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
+	    echo 'includedir=$${prefix}/include'; \
+	    echo ''; \
+	    echo 'Name: OpenSSL-libcrypto'; \
+	    echo 'Description: OpenSSL cryptography library'; \
+	    echo 'Version: '$(VERSION); \
+	    echo 'Requires: '; \
+	    echo 'Libs: -L$${libdir} -lcrypto $(EX_LIBS)'; \
+	    echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libcrypto.pc
+
+libssl.pc: Makefile
+	@ ( echo 'prefix=$(INSTALLTOP)'; \
+	    echo 'exec_prefix=$${prefix}'; \
+	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
+	    echo 'includedir=$${prefix}/include'; \
+	    echo ''; \
+	    echo 'Name: OpenSSL'; \
+	    echo 'Description: Secure Sockets Layer and cryptography libraries'; \
+	    echo 'Version: '$(VERSION); \
+	    echo 'Requires: '; \
+	    echo 'Libs: -L$${libdir} -lssl -lcrypto $(EX_LIBS)'; \
+	    echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libssl.pc
+
+openssl.pc: Makefile
+	@ ( echo 'prefix=$(INSTALLTOP)'; \
+	    echo 'exec_prefix=$${prefix}'; \
+	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
+	    echo 'includedir=$${prefix}/include'; \
+	    echo ''; \
+	    echo 'Name: OpenSSL'; \
+	    echo 'Description: Secure Sockets Layer and cryptography libraries and tools'; \
+	    echo 'Version: '$(VERSION); \
+	    echo 'Requires: '; \
+	    echo 'Libs: -L$${libdir} -lssl -lcrypto $(EX_LIBS)'; \
+	    echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > openssl.pc
+
+Makefile: Makefile.org Configure config
+	@echo "Makefile is older than Makefile.org, Configure or config."
+	@echo "Reconfigure the source tree (via './config' or 'perl Configure'), please."
+	@false
+
+libclean:
+	rm -f *.map *.so *.so.* *.dll engines/*.so engines/*.dll *.a engines/*.a */lib */*/lib
+
+clean:	libclean
+	rm -f shlib/*.o *.o core a.out fluff rehash.time testlog make.log cctest cctest.c
+	@set -e; target=clean; $(RECURSIVE_BUILD_CMD)
+	rm -f $(LIBS)
+	rm -f openssl.pc libssl.pc libcrypto.pc
+	rm -f speed.* .pure
+	rm -f $(TARFILE)
+	@set -e; for i in $(ONEDIRS) ;\
+	do \
+	rm -fr $$i/*; \
+	done
+
+makefile.one: files
+	$(PERL) util/mk1mf.pl >makefile.one; \
+	sh util/do_ms.sh
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile > $(TOP)/MINFO
+	@set -e; target=files; $(RECURSIVE_BUILD_CMD)
+
+links:
+	@$(PERL) $(TOP)/util/mkdir-p.pl include/openssl
+	@$(PERL) $(TOP)/util/mklink.pl include/openssl $(EXHEADER)
+	@set -e; target=links; $(RECURSIVE_BUILD_CMD)
+
+gentests:
+	@(cd test && echo "generating dummy tests (if needed)..." && \
+	$(CLEARENV) && $(MAKE) -e $(BUILDENV) TESTS='$(TESTS)' OPENSSL_DEBUG_MEMORY=on generate );
+
+dclean:
+	rm -rf *.bak include/openssl certs/.0
+	@set -e; target=dclean; $(RECURSIVE_BUILD_CMD)
+
+rehash: rehash.time
+rehash.time: certs apps
+	@if [ -z "$(CROSS_COMPILE)" ]; then \
+		(OPENSSL="`pwd`/util/opensslwrap.sh"; \
+		[ -x "apps/openssl.exe" ] && OPENSSL="apps/openssl.exe" || :; \
+		OPENSSL_DEBUG_MEMORY=on; \
+		export OPENSSL OPENSSL_DEBUG_MEMORY; \
+		$(PERL) tools/c_rehash certs) && \
+		touch rehash.time; \
+	else :; fi
+
+test:   tests
+
+tests: rehash
+	@(cd test && echo "testing..." && \
+	$(CLEARENV) && $(MAKE) -e $(BUILDENV) TOP=.. TESTS='$(TESTS)' OPENSSL_DEBUG_MEMORY=on OPENSSL_CONF=../apps/openssl.cnf tests );
+	OPENSSL_CONF=apps/openssl.cnf util/opensslwrap.sh version -a
+
+report:
+	@$(PERL) util/selftest.pl
+
+depend:
+	@set -e; target=depend; $(RECURSIVE_BUILD_CMD)
+
+lint:
+	@set -e; target=lint; $(RECURSIVE_BUILD_CMD)
+
+tags:
+	rm -f TAGS
+	find . -name '[^.]*.[ch]' | xargs etags -a
+
+errors:
+	$(PERL) util/mkerr.pl -recurse -write
+	(cd engines; $(MAKE) PERL=$(PERL) errors)
+	$(PERL) util/ck_errf.pl */*.c */*/*.c
+
+stacks:
+	$(PERL) util/mkstack.pl -write
+
+util/libeay.num::
+	$(PERL) util/mkdef.pl crypto update
+
+util/ssleay.num::
+	$(PERL) util/mkdef.pl ssl update
+
+crypto/objects/obj_dat.h: crypto/objects/obj_dat.pl crypto/objects/obj_mac.h
+	$(PERL) crypto/objects/obj_dat.pl crypto/objects/obj_mac.h crypto/objects/obj_dat.h
+crypto/objects/obj_mac.h: crypto/objects/objects.pl crypto/objects/objects.txt crypto/objects/obj_mac.num
+	$(PERL) crypto/objects/objects.pl crypto/objects/objects.txt crypto/objects/obj_mac.num crypto/objects/obj_mac.h
+crypto/objects/obj_xref.h: crypto/objects/objxref.pl crypto/objects/obj_xref.txt crypto/objects/obj_mac.num
+	$(PERL) crypto/objects/objxref.pl crypto/objects/obj_mac.num crypto/objects/obj_xref.txt >crypto/objects/obj_xref.h
+
+apps/openssl-vms.cnf: apps/openssl.cnf
+	$(PERL) VMS/VMSify-conf.pl < apps/openssl.cnf > apps/openssl-vms.cnf
+
+crypto/bn/bn_prime.h: crypto/bn/bn_prime.pl
+	$(PERL) crypto/bn/bn_prime.pl >crypto/bn/bn_prime.h
+
+
+TABLE: Configure
+	(echo 'Output of `Configure TABLE'"':"; \
+	$(PERL) Configure TABLE) > TABLE
+
+update: errors stacks util/libeay.num util/ssleay.num crypto/objects/obj_dat.h crypto/objects/obj_xref.h apps/openssl-vms.cnf crypto/bn/bn_prime.h TABLE depend
+
+# Build distribution tar-file. As the list of files returned by "find" is
+# pretty long, on several platforms a "too many arguments" error or similar
+# would occur. Therefore the list of files is temporarily stored into a file
+# and read directly, requiring GNU-Tar. Call "make TAR=gtar dist" if the normal
+# tar does not support the --files-from option.
+tar:
+	find . -type d -print | xargs chmod 755
+	find . -type f -print | xargs chmod a+r
+	find . -type f -perm -0100 -print | xargs chmod a+x
+	find * \! -path CVS/\* \! -path \*/CVS/\* \! -name CVS \! -name .cvsignore \! -name STATUS \! -name TABLE | sort > ../$(TARFILE).list; \
+	$(TAR) $(TARFLAGS) --files-from ../$(TARFILE).list -cvf - | \
+	tardy --user_number=0  --user_name=openssl \
+	      --group_number=0 --group_name=openssl \
+	      --prefix=openssl-$(VERSION) - |\
+	gzip --best >../$(TARFILE).gz; \
+	rm -f ../$(TARFILE).list; \
+	ls -l ../$(TARFILE).gz
+
+tar-snap:
+	@$(TAR) $(TARFLAGS) -cvf - \
+		`find * \! -path CVS/\* \! -path \*/CVS/\* \! -name CVS \! -name .cvsignore \! -name STATUS \! -name TABLE \! -name '*.o' \! -name '*.a' \! -name '*.so' \! -name '*.so.*'  \! -name 'openssl' \! -name '*test' \! -name '.#*' \! -name '*~' | sort` |\
+	tardy --user_number=0  --user_name=openssl \
+	      --group_number=0 --group_name=openssl \
+	      --prefix=openssl-$(VERSION) - > ../$(TARFILE);\
+	ls -l ../$(TARFILE)
+
+dist:   
+	$(PERL) Configure dist
+	@$(MAKE) dist_pem_h
+	@$(MAKE) SDIRS='$(SDIRS)' clean
+	@$(MAKE) TAR='$(TAR)' TARFLAGS='$(TARFLAGS)' tar
+
+dist_pem_h:
+	(cd crypto/pem; $(MAKE) -e $(BUILDENV) pem.h; $(MAKE) clean)
+
+install: all install_docs install_sw
+
+install_sw:
+	@$(PERL) $(TOP)/util/mkdir-p.pl $(INSTALL_PREFIX)$(INSTALLTOP)/bin \
+		$(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR) \
+		$(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines \
+		$(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig \
+		$(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl \
+		$(INSTALL_PREFIX)$(OPENSSLDIR)/misc \
+		$(INSTALL_PREFIX)$(OPENSSLDIR)/certs \
+		$(INSTALL_PREFIX)$(OPENSSLDIR)/private
+	@set -e; headerlist="$(EXHEADER)"; for i in $$headerlist;\
+	do \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+	@set -e; target=install; $(RECURSIVE_BUILD_CMD)
+	@set -e; for i in $(LIBS) ;\
+	do \
+		if [ -f "$$i" ]; then \
+		(       echo installing $$i; \
+			cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+			$(RANLIB) $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+			chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+			mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i ); \
+		fi; \
+	done;
+	@set -e; if [ -n "$(SHARED_LIBS)" ]; then \
+		tmp="$(SHARED_LIBS)"; \
+		for i in $${tmp:-x}; \
+		do \
+			if [ -f "$$i" -o -f "$$i.a" ]; then \
+			(       echo installing $$i; \
+				if [ "$(PLATFORM)" != "Cygwin" ]; then \
+					cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+					chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+					mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i; \
+				else \
+					c=`echo $$i | sed 's/^lib\(.*\)\.dll\.a/cyg\1-$(SHLIB_VERSION_NUMBER).dll/'`; \
+					cp $$c $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \
+					chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \
+					mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c; \
+					cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+					chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
+					mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i; \
+				fi ); \
+				if expr $(PLATFORM) : 'mingw' > /dev/null; then \
+				(	case $$i in \
+						*crypto*) i=libeay32.dll;; \
+						*ssl*)    i=ssleay32.dll;; \
+					esac; \
+					echo installing $$i; \
+	 				cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
+	 				chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
+	 				mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i ); \
+				fi; \
+			fi; \
+		done; \
+		(	here="`pwd`"; \
+			cd $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR); \
+			$(MAKE) -f $$here/Makefile HERE="$$here" link-shared ); \
+		if [ "$(INSTALLTOP)" != "/usr" ]; then \
+			echo 'OpenSSL shared libraries have been installed in:'; \
+			echo '  $(INSTALLTOP)'; \
+			echo ''; \
+			sed -e '1,/^$$/d' doc/openssl-shared.txt; \
+		fi; \
+	fi
+	cp libcrypto.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libcrypto.pc
+	cp libssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libssl.pc
+	cp openssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/openssl.pc
+
+install_html_docs:
+	here="`pwd`"; \
+	for subdir in apps crypto ssl; do \
+		mkdir -p $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir; \
+		for i in doc/$$subdir/*.pod; do \
+			fn=`basename $$i .pod`; \
+			echo "installing html/$$fn.$(HTMLSUFFIX)"; \
+			cat $$i \
+			| sed -r 's/L<([^)]*)(\([0-9]\))?\|([^)]*)(\([0-9]\))?>/L<\1|\3>/g' \
+			| pod2html --podroot=doc --htmlroot=.. --podpath=apps:crypto:ssl \
+			| sed -r 's/<!DOCTYPE.*//g' \
+			> $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir/$$fn.$(HTMLSUFFIX); \
+			$(PERL) util/extract-names.pl < $$i | \
+				grep -v $$filecase "^$$fn\$$" | \
+				(cd $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir; \
+				 while read n; do \
+					PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$(HTMLSUFFIX) "$$n".$(HTMLSUFFIX); \
+				 done); \
+		done; \
+	done
+
+install_docs:
+	@$(PERL) $(TOP)/util/mkdir-p.pl \
+		$(INSTALL_PREFIX)$(MANDIR)/man1 \
+		$(INSTALL_PREFIX)$(MANDIR)/man3 \
+		$(INSTALL_PREFIX)$(MANDIR)/man5 \
+		$(INSTALL_PREFIX)$(MANDIR)/man7
+	@pod2man="`cd ./util; ./pod2mantest $(PERL)`"; \
+	here="`pwd`"; \
+	filecase=; \
+	if [ "$(PLATFORM)" = "DJGPP" -o "$(PLATFORM)" = "Cygwin" -o "$(PLATFORM)" = "mingw" ]; then \
+		filecase=-i; \
+	fi; \
+	set -e; for i in doc/apps/*.pod; do \
+		fn=`basename $$i .pod`; \
+		sec=`$(PERL) util/extract-section.pl 1 < $$i`; \
+		echo "installing man$$sec/$$fn.$${sec}$(MANSUFFIX)"; \
+		(cd `$(PERL) util/dirname.pl $$i`; \
+		sh -c "$$pod2man \
+			--section=$$sec --center=OpenSSL \
+			--release=$(VERSION) `basename $$i`") \
+			>  $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$fn.$${sec}$(MANSUFFIX); \
+		$(PERL) util/extract-names.pl < $$i | \
+			(grep -v $$filecase "^$$fn\$$"; true) | \
+			(grep -v "[	]"; true) | \
+			(cd $(INSTALL_PREFIX)$(MANDIR)/man$$sec/; \
+			 while read n; do \
+				PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$${sec}$(MANSUFFIX) "$$n".$${sec}$(MANSUFFIX); \
+			 done); \
+	done; \
+	set -e; for i in doc/crypto/*.pod doc/ssl/*.pod; do \
+		fn=`basename $$i .pod`; \
+		sec=`$(PERL) util/extract-section.pl 3 < $$i`; \
+		echo "installing man$$sec/$$fn.$${sec}$(MANSUFFIX)"; \
+		(cd `$(PERL) util/dirname.pl $$i`; \
+		sh -c "$$pod2man \
+			--section=$$sec --center=OpenSSL \
+			--release=$(VERSION) `basename $$i`") \
+			>  $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$fn.$${sec}$(MANSUFFIX); \
+		$(PERL) util/extract-names.pl < $$i | \
+			(grep -v $$filecase "^$$fn\$$"; true) | \
+			(grep -v "[	]"; true) | \
+			(cd $(INSTALL_PREFIX)$(MANDIR)/man$$sec/; \
+			 while read n; do \
+				PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$${sec}$(MANSUFFIX) "$$n".$${sec}$(MANSUFFIX); \
+			 done); \
+	done
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
diff --git a/openssl/Makefile.shared b/openssl/Makefile.shared
new file mode 100644
index 0000000..e753f44
--- /dev/null
+++ b/openssl/Makefile.shared
@@ -0,0 +1,655 @@
+#
+# Helper makefile to link shared libraries in a portable way.
+# This is much simpler than libtool, and hopefully not too error-prone.
+#
+# The following variables need to be set on the command line to build
+# properly
+
+# CC contains the current compiler.  This one MUST be defined
+CC=cc
+CFLAGS=$(CFLAG)
+# LDFLAGS contains flags to be used when temporary object files (when building
+# shared libraries) are created, or when an application is linked.
+# SHARED_LDFLAGS contains flags to be used when the shared library is created.
+LDFLAGS=
+SHARED_LDFLAGS=
+
+NM=nm
+
+# LIBNAME contains just the name of the library, without prefix ("lib"
+# on Unix, "cyg" for certain forms under Cygwin...) or suffix (.a, .so,
+# .dll, ...).  This one MUST have a value when using this makefile to
+# build shared libraries.
+# For example, to build libfoo.so, you need to do the following:
+#LIBNAME=foo
+LIBNAME=
+
+# APPNAME contains just the name of the application, without suffix (""
+# on Unix, ".exe" on Windows, ...).  This one MUST have a value when using
+# this makefile to build applications.
+# For example, to build foo, you need to do the following:
+#APPNAME=foo
+APPNAME=
+
+# OBJECTS contains all the object files to link together into the application.
+# This must contain at least one object file.
+#OBJECTS=foo.o
+OBJECTS=
+
+# LIBEXTRAS contains extra modules to link together with the library.
+# For example, if a second library, say libbar.a needs to be linked into
+# libfoo.so, you need to do the following:
+#LIBEXTRAS=libbar.a
+# Note that this MUST be used when using the link_o targets, to hold the
+# names of all object files that go into the target library.
+LIBEXTRAS=
+
+# LIBVERSION contains the current version of the library.
+# For example, to build libfoo.so.1.2, you need to do the following:
+#LIBVERSION=1.2
+LIBVERSION=
+
+# LIBCOMPATVERSIONS contains the compatibility versions (a list) of
+# the library.  They MUST be in decreasing order.
+# For example, if libfoo.so.1.2.1 is backward compatible with libfoo.so.1.2
+# and libfoo.so.1, you need to do the following:
+#LIBCOMPATVERSIONS=1.2 1
+# Note that on systems that use sonames, the last number will appear as
+# part of it.
+# It's also possible, for systems that support it (Tru64, for example),
+# to add extra compatibility info with more precision, by adding a second
+# list of versions, separated from the first with a semicolon, like this:
+#LIBCOMPATVERSIONS=1.2 1;1.2.0 1.1.2 1.1.1 1.1.0 1.0.0
+LIBCOMPATVERSIONS=
+
+# LIBDEPS contains all the flags necessary to cover all necessary
+# dependencies to other libraries.
+LIBDEPS=
+
+#------------------------------------------------------------------------------
+# The rest is private to this makefile.
+
+SET_X=:
+#SET_X=set -x
+
+top:
+	echo "Trying to use this makefile interactively?  Don't."
+
+CALC_VERSIONS=	\
+	SHLIB_COMPAT=; SHLIB_SOVER=; \
+	if [ -n "$(LIBVERSION)$(LIBCOMPATVERSIONS)" ]; then \
+		prev=""; \
+		for v in `echo "$(LIBVERSION) $(LIBCOMPATVERSIONS)" | cut -d';' -f1`; do \
+			SHLIB_SOVER_NODOT=$$v; \
+			SHLIB_SOVER=.$$v; \
+			if [ -n "$$prev" ]; then \
+				SHLIB_COMPAT="$$SHLIB_COMPAT .$$prev"; \
+			fi; \
+			prev=$$v; \
+		done; \
+	fi
+
+LINK_APP=	\
+  ( $(SET_X);   \
+    LIBDEPS="$${LIBDEPS:-$(LIBDEPS)}"; \
+    LDCMD="$${LDCMD:-$(CC)}"; LDFLAGS="$${LDFLAGS:-$(CFLAGS)}"; \
+    LIBPATH=`for x in $$LIBDEPS; do echo $$x; done | sed -e 's/^ *-L//;t' -e d | uniq`; \
+    LIBPATH=`echo $$LIBPATH | sed -e 's/ /:/g'`; \
+    LD_LIBRARY_PATH=$$LIBPATH:$$LD_LIBRARY_PATH \
+    $${LDCMD} $${LDFLAGS} -o $${APPNAME:=$(APPNAME)} $(OBJECTS) $${LIBDEPS} )
+
+LINK_SO=	\
+  ( $(SET_X);   \
+    LIBDEPS="$${LIBDEPS:-$(LIBDEPS)}"; \
+    SHAREDCMD="$${SHAREDCMD:-$(CC)}"; \
+    SHAREDFLAGS="$${SHAREDFLAGS:-$(CFLAGS) $(SHARED_LDFLAGS)}"; \
+    LIBPATH=`for x in $$LIBDEPS; do echo $$x; done | sed -e 's/^ *-L//;t' -e d | uniq`; \
+    LIBPATH=`echo $$LIBPATH | sed -e 's/ /:/g'`; \
+    LD_LIBRARY_PATH=$$LIBPATH:$$LD_LIBRARY_PATH \
+    $${SHAREDCMD} $${SHAREDFLAGS} \
+	-o $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX \
+	$$ALLSYMSFLAGS $$SHOBJECTS $$NOALLSYMSFLAGS $$LIBDEPS \
+  ) && $(SYMLINK_SO)
+
+SYMLINK_SO=	\
+	if [ -n "$$INHIBIT_SYMLINKS" ]; then :; else \
+		prev=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX; \
+		if [ -n "$$SHLIB_COMPAT" ]; then \
+			for x in $$SHLIB_COMPAT; do \
+				( $(SET_X); rm -f $$SHLIB$$x$$SHLIB_SUFFIX; \
+				  ln -s $$prev $$SHLIB$$x$$SHLIB_SUFFIX ); \
+				prev=$$SHLIB$$x$$SHLIB_SUFFIX; \
+			done; \
+		fi; \
+		if [ -n "$$SHLIB_SOVER" ]; then \
+			( $(SET_X); rm -f $$SHLIB$$SHLIB_SUFFIX; \
+			  ln -s $$prev $$SHLIB$$SHLIB_SUFFIX ); \
+		fi; \
+	fi
+
+LINK_SO_A=	SHOBJECTS="lib$(LIBNAME).a $(LIBEXTRAS)"; $(LINK_SO)
+LINK_SO_O=	SHOBJECTS="$(LIBEXTRAS)"; $(LINK_SO)
+
+LINK_SO_A_VIA_O=	\
+  SHOBJECTS=lib$(LIBNAME).o; \
+  ALL=$$ALLSYMSFLAGS; ALLSYMSFLAGS=; NOALLSYMSFLAGS=; \
+  ( $(SET_X); \
+    ld $(LDFLAGS) -r -o lib$(LIBNAME).o $$ALL lib$(LIBNAME).a $(LIBEXTRAS) ); \
+  $(LINK_SO) && rm -f lib$(LIBNAME).o
+
+LINK_SO_A_UNPACKED=	\
+  UNPACKDIR=link_tmp.$$$$; rm -rf $$UNPACKDIR; mkdir $$UNPACKDIR; \
+  (cd $$UNPACKDIR; ar x ../lib$(LIBNAME).a) && \
+  ([ -z "$(LIBEXTRAS)" ] || cp $(LIBEXTRAS) $$UNPACKDIR) && \
+  SHOBJECTS=$$UNPACKDIR/*.o; \
+  $(LINK_SO) && rm -rf $$UNPACKDIR
+
+DETECT_GNU_LD=($(CC) -Wl,-V /dev/null 2>&1 | grep '^GNU ld' )>/dev/null
+
+DO_GNU_SO=$(CALC_VERSIONS); \
+	SHLIB=lib$(LIBNAME).so; \
+	SHLIB_SUFFIX=; \
+	ALLSYMSFLAGS='-Wl,--whole-archive'; \
+	NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \
+	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-Bsymbolic -Wl,-soname=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX"
+
+DO_GNU_APP=LDFLAGS="$(CFLAGS) -Wl,-rpath,$(LIBRPATH)"
+
+#This is rather special.  It's a special target with which one can link
+#applications without bothering with any features that have anything to
+#do with shared libraries, for example when linking against static
+#libraries.  It's mostly here to avoid a lot of conditionals everywhere
+#else...
+link_app.:
+	$(LINK_APP)
+
+link_o.gnu:
+	@ $(DO_GNU_SO); $(LINK_SO_O)
+link_a.gnu:
+	@ $(DO_GNU_SO); $(LINK_SO_A)
+link_app.gnu:
+	@ $(DO_GNU_APP); $(LINK_APP)
+
+DO_BEOS_SO=	SHLIB=lib$(LIBNAME).so; \
+	SHLIB_SUFFIX=; \
+	ALLSYMSFLAGS='-Wl,--whole-archive'; \
+	NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \
+	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-Bsymbolic -Wl,-soname=$$SHLIB$$SHLIB_SUFFIX"
+
+link_o.beos:
+	@ $(DO_BEOS_SO); $(LINK_SO_O)
+link_a.beos:
+	@ $(DO_BEOS_SO); $(LINK_SO_A)
+
+link_o.bsd:
+	@if $(DETECT_GNU_LD); then $(DO_GNU_SO); else \
+	$(CALC_VERSIONS); \
+	SHLIB=lib$(LIBNAME).so; \
+	SHLIB_SUFFIX=; \
+	LIBDEPS=" "; \
+	ALLSYMSFLAGS="-Wl,-Bforcearchive"; \
+	NOALLSYMSFLAGS=; \
+	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -nostdlib"; \
+	fi; $(LINK_SO_O)
+link_a.bsd:
+	@if $(DETECT_GNU_LD); then $(DO_GNU_SO); else \
+	$(CALC_VERSIONS); \
+	SHLIB=lib$(LIBNAME).so; \
+	SHLIB_SUFFIX=; \
+	LIBDEPS=" "; \
+	ALLSYMSFLAGS="-Wl,-Bforcearchive"; \
+	NOALLSYMSFLAGS=; \
+	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -nostdlib"; \
+	fi; $(LINK_SO_A)
+link_app.bsd:
+	@if $(DETECT_GNU_LD); then $(DO_GNU_APP); else \
+	LDFLAGS="$(CFLAGS) -Wl,-rpath,$(LIBPATH)"; \
+	fi; $(LINK_APP)
+
+# For Darwin AKA Mac OS/X (dyld)
+# Originally link_o.darwin produced .so, because it was hard-coded
+# in dso_dlfcn module. At later point dso_dlfcn switched to .dylib
+# extension in order to allow for run-time linking with vendor-
+# supplied shared libraries such as libz, so that link_o.darwin had
+# to be harmonized with it. This caused minor controversy, because
+# it was believed that dlopen can't be used to dynamically load
+# .dylib-s, only so called bundle modules (ones linked with -bundle
+# flag). The belief seems to be originating from pre-10.4 release,
+# where dlfcn functionality was emulated by dlcompat add-on. In
+# 10.4 dlopen was rewritten as native part of dyld and is documented
+# to be capable of loading both dynamic libraries and bundles. In
+# order to provide compatibility with pre-10.4 dlopen, modules are
+# linked with -bundle flag, which makes .dylib extension misleading.
+# It works, because dlopen is [and always was] extension-agnostic.
+# Alternative to this heuristic approach is to develop specific
+# MacOS X dso module relying on whichever "native" dyld interface.
+link_o.darwin:
+	@ $(CALC_VERSIONS); \
+	SHLIB=lib$(LIBNAME); \
+	SHLIB_SUFFIX=.dylib; \
+	ALLSYMSFLAGS='-all_load'; \
+	NOALLSYMSFLAGS=''; \
+	SHAREDFLAGS="$(CFLAGS) `echo $(SHARED_LDFLAGS) | sed s/dynamiclib/bundle/`"; \
+	if [ -n "$(LIBVERSION)" ]; then \
+		SHAREDFLAGS="$$SHAREDFLAGS -current_version $(LIBVERSION)"; \
+	fi; \
+	if [ -n "$$SHLIB_SOVER_NODOT" ]; then \
+		SHAREDFLAGS="$$SHAREDFLAGS -compatibility_version $$SHLIB_SOVER_NODOT"; \
+	fi; \
+	$(LINK_SO_O)
+link_a.darwin:
+	@ $(CALC_VERSIONS); \
+	SHLIB=lib$(LIBNAME); \
+	SHLIB_SUFFIX=.dylib; \
+	ALLSYMSFLAGS='-all_load'; \
+	NOALLSYMSFLAGS=''; \
+	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS)"; \
+	if [ -n "$(LIBVERSION)" ]; then \
+		SHAREDFLAGS="$$SHAREDFLAGS -current_version $(LIBVERSION)"; \
+	fi; \
+	if [ -n "$$SHLIB_SOVER_NODOT" ]; then \
+		SHAREDFLAGS="$$SHAREDFLAGS -compatibility_version $$SHLIB_SOVER_NODOT"; \
+	fi; \
+	SHAREDFLAGS="$$SHAREDFLAGS -install_name $(INSTALLTOP)/$(LIBDIR)/$$SHLIB$(SHLIB_EXT)"; \
+	$(LINK_SO_A)
+link_app.darwin:	# is there run-path on darwin?
+	$(LINK_APP)
+
+link_o.cygwin:
+	@ $(CALC_VERSIONS); \
+	INHIBIT_SYMLINKS=yes; \
+	SHLIB=cyg$(LIBNAME); \
+	base=-Wl,--enable-auto-image-base; \
+	deffile=; \
+	if expr $(PLATFORM) : 'mingw' > /dev/null; then \
+		SHLIB=$(LIBNAME)eay32; base=; \
+		if test -f $(LIBNAME)eay32.def; then \
+			deffile=$(LIBNAME)eay32.def; \
+		fi; \
+	fi; \
+	SHLIB_SUFFIX=.dll; \
+	LIBVERSION="$(LIBVERSION)"; \
+	SHLIB_SOVER=${LIBVERSION:+"-$(LIBVERSION)"}; \
+	ALLSYMSFLAGS='-Wl,--whole-archive'; \
+	NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \
+	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared $$base $$deffile -Wl,-s,-Bsymbolic"; \
+	$(LINK_SO_O)
+#for mingw target if def-file is in use dll-name should match library-name
+link_a.cygwin:
+	@ $(CALC_VERSIONS); \
+	INHIBIT_SYMLINKS=yes; \
+	SHLIB=cyg$(LIBNAME); SHLIB_SOVER=-$(LIBVERSION); SHLIB_SUFFIX=.dll; \
+	dll_name=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX; extras=; \
+	base=-Wl,--enable-auto-image-base; \
+	if expr $(PLATFORM) : 'mingw' > /dev/null; then \
+		case $(LIBNAME) in \
+			crypto) SHLIB=libeay;; \
+			ssl) SHLIB=ssleay;; \
+		esac; \
+		SHLIB_SOVER=32; \
+		extras="$(LIBNAME).def"; \
+		$(PERL) util/mkdef.pl 32 $$SHLIB > $$extras; \
+		base=; [ $(LIBNAME) = "crypto" ] && base=-Wl,--image-base,0x63000000; \
+	fi; \
+	dll_name=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX; \
+	$(PERL) util/mkrc.pl $$dll_name | \
+		$(CROSS_COMPILE)windres -o rc.o; \
+	extras="$$extras rc.o"; \
+	ALLSYMSFLAGS='-Wl,--whole-archive'; \
+	NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \
+	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared $$base -Wl,-s,-Bsymbolic -Wl,--out-implib,lib$(LIBNAME).dll.a $$extras"; \
+	[ -f apps/$$dll_name ] && rm apps/$$dll_name; \
+	[ -f test/$$dll_name ] && rm test/$$dll_name; \
+	$(LINK_SO_A) || exit 1; \
+	rm $$extras; \
+	cp -p $$dll_name apps/; \
+	cp -p $$dll_name test/
+link_app.cygwin:
+	@if expr "$(CFLAGS)" : '.*OPENSSL_USE_APPLINK' > /dev/null; then \
+		LIBDEPS="$(TOP)/crypto/applink.o $${LIBDEPS:-$(LIBDEPS)}"; \
+		export LIBDEPS; \
+	fi; \
+	$(LINK_APP)
+
+link_o.alpha-osf1:
+	@ if $(DETECT_GNU_LD); then \
+		$(DO_GNU_SO); \
+	else \
+		SHLIB=lib$(LIBNAME).so; \
+		SHLIB_SUFFIX=; \
+		SHLIB_HIST=`echo "$(LIBCOMPATVERSIONS)" | cut -d';' -f2 | sed -e 's/ */:/'`; \
+		if [ -n "$$SHLIB_HIST" ]; then \
+			SHLIB_HIST="$${SHLIB_HIST}:$(LIBVERSION)"; \
+		else \
+			SHLIB_HIST="$(LIBVERSION)"; \
+		fi; \
+		SHLIB_SOVER=; \
+		ALLSYMSFLAGS='-all'; \
+		NOALLSYMSFLAGS='-none'; \
+		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-B,symbolic"; \
+		if [ -n "$$SHLIB_HIST" ]; then \
+			SHAREDFLAGS="$$SHAREDFLAGS -set_version $$SHLIB_HIST"; \
+		fi; \
+	fi; \
+	$(LINK_SO_O)
+link_a.alpha-osf1:
+	@ if $(DETECT_GNU_LD); then \
+		$(DO_GNU_SO); \
+	else \
+		SHLIB=lib$(LIBNAME).so; \
+		SHLIB_SUFFIX=; \
+		SHLIB_HIST=`echo "$(LIBCOMPATVERSIONS)" | cut -d';' -f2 | sed -e 's/ */:/'`; \
+		if [ -n "$$SHLIB_HIST" ]; then \
+			SHLIB_HIST="$${SHLIB_HIST}:$(LIBVERSION)"; \
+		else \
+			SHLIB_HIST="$(LIBVERSION)"; \
+		fi; \
+		SHLIB_SOVER=; \
+		ALLSYMSFLAGS='-all'; \
+		NOALLSYMSFLAGS='-none'; \
+		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-B,symbolic"; \
+		if [ -n "$$SHLIB_HIST" ]; then \
+			SHAREDFLAGS="$$SHAREDFLAGS -set_version $$SHLIB_HIST"; \
+		fi; \
+	fi; \
+	$(LINK_SO_A)
+link_app.alpha-osf1:
+	@if $(DETECT_GNU_LD); then \
+		$(DO_GNU_APP); \
+	else \
+		LDFLAGS="$(CFLAGS) -rpath $(LIBRPATH)"; \
+	fi; \
+	$(LINK_APP)
+
+link_o.solaris:
+	@ if $(DETECT_GNU_LD); then \
+		$(DO_GNU_SO); \
+	else \
+		$(CALC_VERSIONS); \
+		MINUSZ='-z '; \
+		($(CC) -v 2>&1 | grep gcc) > /dev/null && MINUSZ='-Wl,-z,'; \
+		SHLIB=lib$(LIBNAME).so; \
+		SHLIB_SUFFIX=; \
+		ALLSYMSFLAGS="$${MINUSZ}allextract"; \
+		NOALLSYMSFLAGS="$${MINUSZ}defaultextract"; \
+		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX -Wl,-Bsymbolic"; \
+	fi; \
+	$(LINK_SO_O)
+link_a.solaris:
+	@ if $(DETECT_GNU_LD); then \
+		$(DO_GNU_SO); \
+	else \
+		$(CALC_VERSIONS); \
+		MINUSZ='-z '; \
+		($(CC) -v 2>&1 | grep gcc) > /dev/null && MINUSZ='-Wl,-z,'; \
+		SHLIB=lib$(LIBNAME).so; \
+		SHLIB_SUFFIX=;\
+		ALLSYMSFLAGS="$${MINUSZ}allextract"; \
+		NOALLSYMSFLAGS="$${MINUSZ}defaultextract"; \
+		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX -Wl,-Bsymbolic"; \
+	fi; \
+	$(LINK_SO_A)
+link_app.solaris:
+	@ if $(DETECT_GNU_LD); then \
+		$(DO_GNU_APP); \
+	else \
+		LDFLAGS="$(CFLAGS) -R $(LIBRPATH)"; \
+	fi; \
+	$(LINK_APP)
+
+# OpenServer 5 native compilers used
+link_o.svr3:
+	@ if $(DETECT_GNU_LD); then \
+		$(DO_GNU_SO); \
+	else \
+		$(CALC_VERSIONS); \
+		SHLIB=lib$(LIBNAME).so; \
+		SHLIB_SUFFIX=; \
+		ALLSYMSFLAGS=''; \
+		NOALLSYMSFLAGS=''; \
+		SHAREDFLAGS="$(CFLAGS) -G -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX"; \
+	fi; \
+	$(LINK_SO_O)
+link_a.svr3:
+	@ if $(DETECT_GNU_LD); then \
+		$(DO_GNU_SO); \
+	else \
+		$(CALC_VERSIONS); \
+		SHLIB=lib$(LIBNAME).so; \
+		SHLIB_SUFFIX=; \
+		ALLSYMSFLAGS=''; \
+		NOALLSYMSFLAGS=''; \
+		SHAREDFLAGS="$(CFLAGS) -G -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX"; \
+	fi; \
+	$(LINK_SO_A_UNPACKED)
+link_app.svr3:
+	@$(DETECT_GNU_LD) && $(DO_GNU_APP); \
+	$(LINK_APP)
+
+# UnixWare 7 and OpenUNIX 8 native compilers used
+link_o.svr5:
+	@ if $(DETECT_GNU_LD); then \
+		$(DO_GNU_SO); \
+	else \
+		$(CALC_VERSIONS); \
+		SHARE_FLAG='-G'; \
+		($(CC) -v 2>&1 | grep gcc) > /dev/null && SHARE_FLAG='-shared'; \
+		SHLIB=lib$(LIBNAME).so; \
+		SHLIB_SUFFIX=; \
+		ALLSYMSFLAGS=''; \
+		NOALLSYMSFLAGS=''; \
+		SHAREDFLAGS="$(CFLAGS) $${SHARE_FLAG} -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX"; \
+	fi; \
+	$(LINK_SO_O)
+link_a.svr5:
+	@ if $(DETECT_GNU_LD); then \
+		$(DO_GNU_SO); \
+	else \
+		$(CALC_VERSIONS); \
+		SHARE_FLAG='-G'; \
+		($(CC) -v 2>&1 | grep gcc) > /dev/null && SHARE_FLAG='-shared'; \
+		SHLIB=lib$(LIBNAME).so; \
+		SHLIB_SUFFIX=; \
+		ALLSYMSFLAGS=''; \
+		NOALLSYMSFLAGS=''; \
+		SHAREDFLAGS="$(CFLAGS) $${SHARE_FLAG} -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX"; \
+	fi; \
+	$(LINK_SO_A_UNPACKED)
+link_app.svr5:
+	@$(DETECT_GNU_LD) && $(DO_GNU_APP); \
+	$(LINK_APP)
+
+link_o.irix:
+	@ if $(DETECT_GNU_LD); then \
+		$(DO_GNU_SO); \
+	else \
+		$(CALC_VERSIONS); \
+		SHLIB=lib$(LIBNAME).so; \
+		SHLIB_SUFFIX=; \
+		MINUSWL=""; \
+		($(CC) -v 2>&1 | grep gcc) > /dev/null && MINUSWL="-Wl,"; \
+		ALLSYMSFLAGS="$${MINUSWL}-all"; \
+		NOALLSYMSFLAGS="$${MINUSWL}-none"; \
+		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-soname,$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX,-B,symbolic"; \
+	fi; \
+	$(LINK_SO_O)
+link_a.irix:
+	@ if $(DETECT_GNU_LD); then \
+		$(DO_GNU_SO); \
+	else \
+		$(CALC_VERSIONS); \
+		SHLIB=lib$(LIBNAME).so; \
+		SHLIB_SUFFIX=; \
+		MINUSWL=""; \
+		($(CC) -v 2>&1 | grep gcc) > /dev/null && MINUSWL="-Wl,"; \
+		ALLSYMSFLAGS="$${MINUSWL}-all"; \
+		NOALLSYMSFLAGS="$${MINUSWL}-none"; \
+		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-soname,$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX,-B,symbolic"; \
+	fi; \
+	$(LINK_SO_A)
+link_app.irix:
+	@LDFLAGS="$(CFLAGS) -Wl,-rpath,$(LIBRPATH)"; \
+	$(LINK_APP)
+
+# 32-bit PA-RISC HP-UX embeds the -L pathname of libs we link with, so
+# we compensate for it with +cdp ../: and +cdp ./:. Yes, these rewrite
+# rules imply that we can only link one level down in catalog structure,
+# but that's what takes place for the moment of this writing. +cdp option
+# was introduced in HP-UX 11.x and applies in 32-bit PA-RISC link
+# editor context only [it's simply ignored in other cases, which are all
+# ELFs by the way].
+#
+link_o.hpux:
+	@if $(DETECT_GNU_LD); then $(DO_GNU_SO); else \
+	$(CALC_VERSIONS); \
+	SHLIB=lib$(LIBNAME).sl; \
+	expr "$(CFLAGS)" : '.*DSO_DLFCN' > /dev/null && SHLIB=lib$(LIBNAME).so; \
+	SHLIB_SUFFIX=; \
+	ALLSYMSFLAGS='-Wl,-Fl'; \
+	NOALLSYMSFLAGS=''; \
+	expr $(PLATFORM) : 'hpux64' > /dev/null && ALLSYMSFLAGS='-Wl,+forceload'; \
+	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -Wl,-B,symbolic,+vnocompatwarnings,-z,+s,+h,$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX,+cdp,../:,+cdp,./:"; \
+	fi; \
+	rm -f $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX || :; \
+	$(LINK_SO_O) && chmod a=rx $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX
+link_a.hpux:
+	@if $(DETECT_GNU_LD); then $(DO_GNU_SO); else \
+	$(CALC_VERSIONS); \
+	SHLIB=lib$(LIBNAME).sl; \
+	expr $(PLATFORM) : '.*ia64' > /dev/null && SHLIB=lib$(LIBNAME).so; \
+	SHLIB_SUFFIX=; \
+	ALLSYMSFLAGS='-Wl,-Fl'; \
+	NOALLSYMSFLAGS=''; \
+	expr $(PLATFORM) : 'hpux64' > /dev/null && ALLSYMSFLAGS='-Wl,+forceload'; \
+	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -Wl,-B,symbolic,+vnocompatwarnings,-z,+s,+h,$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX,+cdp,../:,+cdp,./:"; \
+	fi; \
+	rm -f $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX || :; \
+	$(LINK_SO_A) && chmod a=rx $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX
+link_app.hpux:
+	@if $(DETECT_GNU_LD); then $(DO_GNU_APP); else \
+	LDFLAGS="$(CFLAGS) -Wl,+s,+cdp,../:,+cdp,./:,+b,$(LIBRPATH)"; \
+	fi; \
+	$(LINK_APP)
+
+link_o.aix:
+	@ $(CALC_VERSIONS); \
+	OBJECT_MODE=`expr "x$(SHARED_LDFLAGS)" : 'x\-[a-z]*\(64\)'` || :; \
+	OBJECT_MODE=$${OBJECT_MODE:-32}; export OBJECT_MODE; \
+	SHLIB=lib$(LIBNAME).so; \
+	SHLIB_SUFFIX=; \
+	ALLSYMSFLAGS=''; \
+	NOALLSYMSFLAGS=''; \
+	SHAREDFLAGS='$(CFLAGS) $(SHARED_LDFLAGS) -Wl,-bexpall,-bnolibpath,-bM:SRE'; \
+	$(LINK_SO_O);
+link_a.aix:
+	@ $(CALC_VERSIONS); \
+	OBJECT_MODE=`expr "x$(SHARED_LDFLAGS)" : 'x\-[a-z]*\(64\)'` || : ; \
+	OBJECT_MODE=$${OBJECT_MODE:-32}; export OBJECT_MODE; \
+	SHLIB=lib$(LIBNAME).so; \
+	SHLIB_SUFFIX=; \
+	ALLSYMSFLAGS='-bnogc'; \
+	NOALLSYMSFLAGS=''; \
+	SHAREDFLAGS='$(CFLAGS) $(SHARED_LDFLAGS) -Wl,-bexpall,-bnolibpath,-bM:SRE'; \
+	$(LINK_SO_A_VIA_O)
+link_app.aix:
+	LDFLAGS="$(CFLAGS) -Wl,-brtl,-blibpath:$(LIBRPATH):$${LIBPATH:-/usr/lib:/lib}"; \
+	$(LINK_APP)
+
+link_o.reliantunix:
+	@ $(CALC_VERSIONS); \
+	SHLIB=lib$(LIBNAME).so; \
+	SHLIB_SUFFIX=; \
+	ALLSYMSFLAGS=; \
+	NOALLSYMSFLAGS=''; \
+	SHAREDFLAGS='$(CFLAGS) -G'; \
+	$(LINK_SO_O)
+link_a.reliantunix:
+	@ $(CALC_VERSIONS); \
+	SHLIB=lib$(LIBNAME).so; \
+	SHLIB_SUFFIX=; \
+	ALLSYMSFLAGS=; \
+	NOALLSYMSFLAGS=''; \
+	SHAREDFLAGS='$(CFLAGS) -G'; \
+	$(LINK_SO_A_UNPACKED)
+link_app.reliantunix:
+	$(LINK_APP)
+
+# Targets to build symbolic links when needed
+symlink.gnu symlink.solaris symlink.svr3 symlink.svr5 symlink.irix \
+symlink.aix symlink.reliantunix:
+	@ $(CALC_VERSIONS); \
+	SHLIB=lib$(LIBNAME).so; \
+	$(SYMLINK_SO)
+symlink.darwin:
+	@ $(CALC_VERSIONS); \
+	SHLIB=lib$(LIBNAME); \
+	SHLIB_SUFFIX=.dylib; \
+	$(SYMLINK_SO)
+symlink.hpux:
+	@ $(CALC_VERSIONS); \
+	SHLIB=lib$(LIBNAME).sl; \
+	expr $(PLATFORM) : '.*ia64' > /dev/null && SHLIB=lib$(LIBNAME).so; \
+	$(SYMLINK_SO)
+# The following lines means those specific architectures do no symlinks
+symlink.cygwin symlink.alpha-osf1 symlink.tru64 symlink.tru64-rpath symlink.beos:
+
+# Compatibility targets
+link_o.bsd-gcc-shared link_o.linux-shared link_o.gnu-shared: link_o.gnu
+link_a.bsd-gcc-shared link_a.linux-shared link_a.gnu-shared: link_a.gnu
+link_app.bsd-gcc-shared link_app.linux-shared link_app.gnu-shared: link_app.gnu
+symlink.bsd-gcc-shared symlink.bsd-shared symlink.linux-shared symlink.gnu-shared: symlink.gnu
+link_o.bsd-shared: link_o.bsd
+link_a.bsd-shared: link_a.bsd
+link_app.bsd-shared: link_app.bsd
+link_o.darwin-shared: link_o.darwin
+link_a.darwin-shared: link_a.darwin
+link_app.darwin-shared: link_app.darwin
+symlink.darwin-shared: symlink.darwin
+link_o.cygwin-shared: link_o.cygwin
+link_a.cygwin-shared: link_a.cygwin
+link_app.cygwin-shared: link_app.cygwin
+symlink.cygwin-shared: symlink.cygwin
+link_o.alpha-osf1-shared: link_o.alpha-osf1
+link_a.alpha-osf1-shared: link_a.alpha-osf1
+link_app.alpha-osf1-shared: link_app.alpha-osf1
+symlink.alpha-osf1-shared: symlink.alpha-osf1
+link_o.tru64-shared: link_o.tru64
+link_a.tru64-shared: link_a.tru64
+link_app.tru64-shared: link_app.tru64
+symlink.tru64-shared: symlink.tru64
+link_o.tru64-shared-rpath: link_o.tru64-rpath
+link_a.tru64-shared-rpath: link_a.tru64-rpath
+link_app.tru64-shared-rpath: link_app.tru64-rpath
+symlink.tru64-shared-rpath: symlink.tru64-rpath
+link_o.solaris-shared: link_o.solaris
+link_a.solaris-shared: link_a.solaris
+link_app.solaris-shared: link_app.solaris
+symlink.solaris-shared: symlink.solaris
+link_o.svr3-shared: link_o.svr3
+link_a.svr3-shared: link_a.svr3
+link_app.svr3-shared: link_app.svr3
+symlink.svr3-shared: symlink.svr3
+link_o.svr5-shared: link_o.svr5
+link_a.svr5-shared: link_a.svr5
+link_app.svr5-shared: link_app.svr5
+symlink.svr5-shared: symlink.svr5
+link_o.irix-shared: link_o.irix
+link_a.irix-shared: link_a.irix
+link_app.irix-shared: link_app.irix
+symlink.irix-shared: symlink.irix
+link_o.hpux-shared: link_o.hpux
+link_a.hpux-shared: link_a.hpux
+link_app.hpux-shared: link_app.hpux
+symlink.hpux-shared: symlink.hpux
+link_o.aix-shared: link_o.aix
+link_a.aix-shared: link_a.aix
+link_app.aix-shared: link_app.aix
+symlink.aix-shared: symlink.aix
+link_o.reliantunix-shared: link_o.reliantunix
+link_a.reliantunix-shared: link_a.reliantunix
+link_app.reliantunix-shared: link_app.reliantunix
+symlink.reliantunix-shared: symlink.reliantunix
+link_o.beos-shared: link_o.beos
+link_a.beos-shared: link_a.beos
+link_app.beos-shared: link_app.gnu
+symlink.beos-shared: symlink.beos
diff --git a/openssl/NEWS b/openssl/NEWS
new file mode 100644
index 0000000..1fb25c6
--- /dev/null
+++ b/openssl/NEWS
@@ -0,0 +1,604 @@
+
+  NEWS
+  ====
+
+  This file gives a brief overview of the major changes between each OpenSSL
+  release. For more details please read the CHANGES file.
+
+  Major changes between OpenSSL 1.0.0e and OpenSSL 1.0.0f:
+
+      o Fix for DTLS plaintext recovery attack CVE-2011-4108
+      o Clear block padding bytes of SSL 3.0 records CVE-2011-4576
+      o Only allow one SGC handshake restart for SSL/TLS CVE-2011-4619
+      o Check parameters are not NULL in GOST ENGINE CVE-2012-0027
+      o Check for malformed RFC3779 data CVE-2011-4577
+
+  Major changes between OpenSSL 1.0.0d and OpenSSL 1.0.0e:
+
+      o Fix for CRL vulnerability issue CVE-2011-3207
+      o Fix for ECDH crashes CVE-2011-3210
+      o Protection against EC timing attacks.
+      o Support ECDH ciphersuites for certificates using SHA2 algorithms.
+      o Various DTLS fixes.
+
+  Major changes between OpenSSL 1.0.0c and OpenSSL 1.0.0d:
+
+      o Fix for security issue CVE-2011-0014
+
+  Major changes between OpenSSL 1.0.0b and OpenSSL 1.0.0c:
+
+      o Fix for security issue CVE-2010-4180
+      o Fix for CVE-2010-4252
+      o Fix mishandling of absent EC point format extension.
+      o Fix various platform compilation issues.
+      o Corrected fix for security issue CVE-2010-3864.
+
+  Major changes between OpenSSL 1.0.0a and OpenSSL 1.0.0b:
+
+      o Fix for security issue CVE-2010-3864.
+      o Fix for CVE-2010-2939
+      o Fix WIN32 build system for GOST ENGINE.
+
+  Major changes between OpenSSL 1.0.0 and OpenSSL 1.0.0a:
+
+      o Fix for security issue CVE-2010-1633.
+      o GOST MAC and CFB fixes.
+
+  Major changes between OpenSSL 0.9.8n and OpenSSL 1.0.0:
+
+      o RFC3280 path validation: sufficient to process PKITS tests.
+      o Integrated support for PVK files and keyblobs.
+      o Change default private key format to PKCS#8.
+      o CMS support: able to process all examples in RFC4134
+      o Streaming ASN1 encode support for PKCS#7 and CMS.
+      o Multiple signer and signer add support for PKCS#7 and CMS.
+      o ASN1 printing support.
+      o Whirlpool hash algorithm added.
+      o RFC3161 time stamp support.
+      o New generalised public key API supporting ENGINE based algorithms.
+      o New generalised public key API utilities.
+      o New ENGINE supporting GOST algorithms.
+      o SSL/TLS GOST ciphersuite support.
+      o PKCS#7 and CMS GOST support.
+      o RFC4279 PSK ciphersuite support.
+      o Supported points format extension for ECC ciphersuites.
+      o ecdsa-with-SHA224/256/384/512 signature types.
+      o dsa-with-SHA224 and dsa-with-SHA256 signature types.
+      o Opaque PRF Input TLS extension support.
+      o Updated time routines to avoid OS limitations.
+
+  Major changes between OpenSSL 0.9.8q and OpenSSL 0.9.8r:
+
+      o Fix for security issue CVE-2011-0014
+
+  Major changes between OpenSSL 0.9.8p and OpenSSL 0.9.8q:
+
+      o Fix for security issue CVE-2010-4180
+      o Fix for CVE-2010-4252
+
+  Major changes between OpenSSL 0.9.8o and OpenSSL 0.9.8p:
+
+      o Fix for security issue CVE-2010-3864.
+
+  Major changes between OpenSSL 0.9.8n and OpenSSL 0.9.8o:
+
+      o Fix for security issue CVE-2010-0742.
+      o Various DTLS fixes.
+      o Recognise SHA2 certificates if only SSL algorithms added.
+      o Fix for no-rc4 compilation.
+      o Chil ENGINE unload workaround.
+
+  Major changes between OpenSSL 0.9.8m and OpenSSL 0.9.8n:
+
+      o CFB cipher definition fixes.
+      o Fix security issues CVE-2010-0740 and CVE-2010-0433.
+
+  Major changes between OpenSSL 0.9.8l and OpenSSL 0.9.8m:
+
+      o Cipher definition fixes.
+      o Workaround for slow RAND_poll() on some WIN32 versions.
+      o Remove MD2 from algorithm tables.
+      o SPKAC handling fixes.
+      o Support for RFC5746 TLS renegotiation extension.
+      o Compression memory leak fixed.
+      o Compression session resumption fixed.
+      o Ticket and SNI coexistence fixes.
+      o Many fixes to DTLS handling. 
+
+  Major changes between OpenSSL 0.9.8k and OpenSSL 0.9.8l:
+
+      o Temporary work around for CVE-2009-3555: disable renegotiation.
+
+  Major changes between OpenSSL 0.9.8j and OpenSSL 0.9.8k:
+
+      o Fix various build issues.
+      o Fix security issues (CVE-2009-0590, CVE-2009-0591, CVE-2009-0789)
+
+  Major changes between OpenSSL 0.9.8i and OpenSSL 0.9.8j:
+
+      o Fix security issue (CVE-2008-5077)
+      o Merge FIPS 140-2 branch code.
+
+  Major changes between OpenSSL 0.9.8g and OpenSSL 0.9.8h:
+
+      o CryptoAPI ENGINE support.
+      o Various precautionary measures.
+      o Fix for bugs affecting certificate request creation.
+      o Support for local machine keyset attribute in PKCS#12 files.
+
+  Major changes between OpenSSL 0.9.8f and OpenSSL 0.9.8g:
+
+      o Backport of CMS functionality to 0.9.8.
+      o Fixes for bugs introduced with 0.9.8f.
+
+  Major changes between OpenSSL 0.9.8e and OpenSSL 0.9.8f:
+
+      o Add gcc 4.2 support.
+      o Add support for AES and SSE2 assembly lanugauge optimization
+        for VC++ build.
+      o Support for RFC4507bis and server name extensions if explicitly 
+        selected at compile time.
+      o DTLS improvements.
+      o RFC4507bis support.
+      o TLS Extensions support.
+
+  Major changes between OpenSSL 0.9.8d and OpenSSL 0.9.8e:
+
+      o Various ciphersuite selection fixes.
+      o RFC3779 support.
+
+  Major changes between OpenSSL 0.9.8c and OpenSSL 0.9.8d:
+
+      o Introduce limits to prevent malicious key DoS  (CVE-2006-2940)
+      o Fix security issues (CVE-2006-2937, CVE-2006-3737, CVE-2006-4343)
+      o Changes to ciphersuite selection algorithm
+
+  Major changes between OpenSSL 0.9.8b and OpenSSL 0.9.8c:
+
+      o Fix Daniel Bleichenbacher forged signature attack, CVE-2006-4339
+      o New cipher Camellia
+
+  Major changes between OpenSSL 0.9.8a and OpenSSL 0.9.8b:
+
+      o Cipher string fixes.
+      o Fixes for VC++ 2005.
+      o Updated ECC cipher suite support.
+      o New functions EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free().
+      o Zlib compression usage fixes.
+      o Built in dynamic engine compilation support on Win32.
+      o Fixes auto dynamic engine loading in Win32.
+
+  Major changes between OpenSSL 0.9.8 and OpenSSL 0.9.8a:
+
+      o Fix potential SSL 2.0 rollback, CVE-2005-2969
+      o Extended Windows CE support
+
+  Major changes between OpenSSL 0.9.7g and OpenSSL 0.9.8:
+
+      o Major work on the BIGNUM library for higher efficiency and to
+        make operations more streamlined and less contradictory.  This
+        is the result of a major audit of the BIGNUM library.
+      o Addition of BIGNUM functions for fields GF(2^m) and NIST
+        curves, to support the Elliptic Crypto functions.
+      o Major work on Elliptic Crypto; ECDH and ECDSA added, including
+        the use through EVP, X509 and ENGINE.
+      o New ASN.1 mini-compiler that's usable through the OpenSSL
+        configuration file.
+      o Added support for ASN.1 indefinite length constructed encoding.
+      o New PKCS#12 'medium level' API to manipulate PKCS#12 files.
+      o Complete rework of shared library construction and linking
+        programs with shared or static libraries, through a separate
+        Makefile.shared.
+      o Rework of the passing of parameters from one Makefile to another.
+      o Changed ENGINE framework to load dynamic engine modules
+        automatically from specifically given directories.
+      o New structure and ASN.1 functions for CertificatePair.
+      o Changed the ZLIB compression method to be stateful.
+      o Changed the key-generation and primality testing "progress"
+        mechanism to take a structure that contains the ticker
+        function and an argument.
+      o New engine module: GMP (performs private key exponentiation).
+      o New engine module: VIA PadLOck ACE extension in VIA C3
+        Nehemiah processors.
+      o Added support for IPv6 addresses in certificate extensions.
+        See RFC 1884, section 2.2.
+      o Added support for certificate policy mappings, policy
+        constraints and name constraints.
+      o Added support for multi-valued AVAs in the OpenSSL
+        configuration file.
+      o Added support for multiple certificates with the same subject
+        in the 'openssl ca' index file.
+      o Make it possible to create self-signed certificates using
+        'openssl ca -selfsign'.
+      o Make it possible to generate a serial number file with
+        'openssl ca -create_serial'.
+      o New binary search functions with extended functionality.
+      o New BUF functions.
+      o New STORE structure and library to provide an interface to all
+        sorts of data repositories.  Supports storage of public and
+        private keys, certificates, CRLs, numbers and arbitrary blobs.
+	This library is unfortunately unfinished and unused withing
+	OpenSSL.
+      o New control functions for the error stack.
+      o Changed the PKCS#7 library to support one-pass S/MIME
+        processing.
+      o Added the possibility to compile without old deprecated
+        functionality with the OPENSSL_NO_DEPRECATED macro or the
+        'no-deprecated' argument to the config and Configure scripts.
+      o Constification of all ASN.1 conversion functions, and other
+        affected functions.
+      o Improved platform support for PowerPC.
+      o New FIPS 180-2 algorithms (SHA-224, -256, -384 and -512).
+      o New X509_VERIFY_PARAM structure to support parametrisation
+        of X.509 path validation.
+      o Major overhaul of RC4 performance on Intel P4, IA-64 and
+        AMD64.
+      o Changed the Configure script to have some algorithms disabled
+        by default.  Those can be explicitely enabled with the new
+        argument form 'enable-xxx'.
+      o Change the default digest in 'openssl' commands from MD5 to
+        SHA-1.
+      o Added support for DTLS.
+      o New BIGNUM blinding.
+      o Added support for the RSA-PSS encryption scheme
+      o Added support for the RSA X.931 padding.
+      o Added support for BSD sockets on NetWare.
+      o Added support for files larger than 2GB.
+      o Added initial support for Win64.
+      o Added alternate pkg-config files.
+
+  Major changes between OpenSSL 0.9.7l and OpenSSL 0.9.7m:
+
+      o FIPS 1.1.1 module linking.
+      o Various ciphersuite selection fixes.
+
+  Major changes between OpenSSL 0.9.7k and OpenSSL 0.9.7l:
+
+      o Introduce limits to prevent malicious key DoS  (CVE-2006-2940)
+      o Fix security issues (CVE-2006-2937, CVE-2006-3737, CVE-2006-4343)
+
+  Major changes between OpenSSL 0.9.7j and OpenSSL 0.9.7k:
+
+      o Fix Daniel Bleichenbacher forged signature attack, CVE-2006-4339
+
+  Major changes between OpenSSL 0.9.7i and OpenSSL 0.9.7j:
+
+      o Visual C++ 2005 fixes.
+      o Update Windows build system for FIPS.
+
+  Major changes between OpenSSL 0.9.7h and OpenSSL 0.9.7i:
+
+      o Give EVP_MAX_MD_SIZE it's old value, except for a FIPS build.
+
+  Major changes between OpenSSL 0.9.7g and OpenSSL 0.9.7h:
+
+      o Fix SSL 2.0 Rollback, CVE-2005-2969
+      o Allow use of fixed-length exponent on DSA signing
+      o Default fixed-window RSA, DSA, DH private-key operations
+
+  Major changes between OpenSSL 0.9.7f and OpenSSL 0.9.7g:
+
+      o More compilation issues fixed.
+      o Adaptation to more modern Kerberos API.
+      o Enhanced or corrected configuration for Solaris64, Mingw and Cygwin.
+      o Enhanced x86_64 assembler BIGNUM module.
+      o More constification.
+      o Added processing of proxy certificates (RFC 3820).
+
+  Major changes between OpenSSL 0.9.7e and OpenSSL 0.9.7f:
+
+      o Several compilation issues fixed.
+      o Many memory allocation failure checks added.
+      o Improved comparison of X509 Name type.
+      o Mandatory basic checks on certificates.
+      o Performance improvements.
+
+  Major changes between OpenSSL 0.9.7d and OpenSSL 0.9.7e:
+
+      o Fix race condition in CRL checking code.
+      o Fixes to PKCS#7 (S/MIME) code.
+
+  Major changes between OpenSSL 0.9.7c and OpenSSL 0.9.7d:
+
+      o Security: Fix Kerberos ciphersuite SSL/TLS handshaking bug
+      o Security: Fix null-pointer assignment in do_change_cipher_spec()
+      o Allow multiple active certificates with same subject in CA index
+      o Multiple X509 verification fixes
+      o Speed up HMAC and other operations
+
+  Major changes between OpenSSL 0.9.7b and OpenSSL 0.9.7c:
+
+      o Security: fix various ASN1 parsing bugs.
+      o New -ignore_err option to OCSP utility.
+      o Various interop and bug fixes in S/MIME code.
+      o SSL/TLS protocol fix for unrequested client certificates.
+
+  Major changes between OpenSSL 0.9.7a and OpenSSL 0.9.7b:
+
+      o Security: counter the Klima-Pokorny-Rosa extension of
+        Bleichbacher's attack 
+      o Security: make RSA blinding default.
+      o Configuration: Irix fixes, AIX fixes, better mingw support.
+      o Support for new platforms: linux-ia64-ecc.
+      o Build: shared library support fixes.
+      o ASN.1: treat domainComponent correctly.
+      o Documentation: fixes and additions.
+
+  Major changes between OpenSSL 0.9.7 and OpenSSL 0.9.7a:
+
+      o Security: Important security related bugfixes.
+      o Enhanced compatibility with MIT Kerberos.
+      o Can be built without the ENGINE framework.
+      o IA32 assembler enhancements.
+      o Support for new platforms: FreeBSD/IA64 and FreeBSD/Sparc64.
+      o Configuration: the no-err option now works properly.
+      o SSL/TLS: now handles manual certificate chain building.
+      o SSL/TLS: certain session ID malfunctions corrected.
+
+  Major changes between OpenSSL 0.9.6 and OpenSSL 0.9.7:
+
+      o New library section OCSP.
+      o Complete rewrite of ASN1 code.
+      o CRL checking in verify code and openssl utility.
+      o Extension copying in 'ca' utility.
+      o Flexible display options in 'ca' utility.
+      o Provisional support for international characters with UTF8.
+      o Support for external crypto devices ('engine') is no longer
+        a separate distribution.
+      o New elliptic curve library section.
+      o New AES (Rijndael) library section.
+      o Support for new platforms: Windows CE, Tandem OSS, A/UX, AIX 64-bit,
+        Linux x86_64, Linux 64-bit on Sparc v9
+      o Extended support for some platforms: VxWorks
+      o Enhanced support for shared libraries.
+      o Now only builds PIC code when shared library support is requested.
+      o Support for pkg-config.
+      o Lots of new manuals.
+      o Makes symbolic links to or copies of manuals to cover all described
+        functions.
+      o Change DES API to clean up the namespace (some applications link also
+        against libdes providing similar functions having the same name).
+        Provide macros for backward compatibility (will be removed in the
+        future).
+      o Unify handling of cryptographic algorithms (software and engine)
+        to be available via EVP routines for asymmetric and symmetric ciphers.
+      o NCONF: new configuration handling routines.
+      o Change API to use more 'const' modifiers to improve error checking
+        and help optimizers.
+      o Finally remove references to RSAref.
+      o Reworked parts of the BIGNUM code.
+      o Support for new engines: Broadcom ubsec, Accelerated Encryption
+        Processing, IBM 4758.
+      o A few new engines added in the demos area.
+      o Extended and corrected OID (object identifier) table.
+      o PRNG: query at more locations for a random device, automatic query for
+        EGD style random sources at several locations.
+      o SSL/TLS: allow optional cipher choice according to server's preference.
+      o SSL/TLS: allow server to explicitly set new session ids.
+      o SSL/TLS: support Kerberos cipher suites (RFC2712).
+	Only supports MIT Kerberos for now.
+      o SSL/TLS: allow more precise control of renegotiations and sessions.
+      o SSL/TLS: add callback to retrieve SSL/TLS messages.
+      o SSL/TLS: support AES cipher suites (RFC3268).
+
+  Major changes between OpenSSL 0.9.6j and OpenSSL 0.9.6k:
+
+      o Security: fix various ASN1 parsing bugs.
+      o SSL/TLS protocol fix for unrequested client certificates.
+
+  Major changes between OpenSSL 0.9.6i and OpenSSL 0.9.6j:
+
+      o Security: counter the Klima-Pokorny-Rosa extension of
+        Bleichbacher's attack 
+      o Security: make RSA blinding default.
+      o Build: shared library support fixes.
+
+  Major changes between OpenSSL 0.9.6h and OpenSSL 0.9.6i:
+
+      o Important security related bugfixes.
+
+  Major changes between OpenSSL 0.9.6g and OpenSSL 0.9.6h:
+
+      o New configuration targets for Tandem OSS and A/UX.
+      o New OIDs for Microsoft attributes.
+      o Better handling of SSL session caching.
+      o Better comparison of distinguished names.
+      o Better handling of shared libraries in a mixed GNU/non-GNU environment.
+      o Support assembler code with Borland C.
+      o Fixes for length problems.
+      o Fixes for uninitialised variables.
+      o Fixes for memory leaks, some unusual crashes and some race conditions.
+      o Fixes for smaller building problems.
+      o Updates of manuals, FAQ and other instructive documents.
+
+  Major changes between OpenSSL 0.9.6f and OpenSSL 0.9.6g:
+
+      o Important building fixes on Unix.
+
+  Major changes between OpenSSL 0.9.6e and OpenSSL 0.9.6f:
+
+      o Various important bugfixes.
+
+  Major changes between OpenSSL 0.9.6d and OpenSSL 0.9.6e:
+
+      o Important security related bugfixes.
+      o Various SSL/TLS library bugfixes.
+
+  Major changes between OpenSSL 0.9.6c and OpenSSL 0.9.6d:
+
+      o Various SSL/TLS library bugfixes.
+      o Fix DH parameter generation for 'non-standard' generators.
+
+  Major changes between OpenSSL 0.9.6b and OpenSSL 0.9.6c:
+
+      o Various SSL/TLS library bugfixes.
+      o BIGNUM library fixes.
+      o RSA OAEP and random number generation fixes.
+      o Object identifiers corrected and added.
+      o Add assembler BN routines for IA64.
+      o Add support for OS/390 Unix, UnixWare with gcc, OpenUNIX 8,
+        MIPS Linux; shared library support for Irix, HP-UX.
+      o Add crypto accelerator support for AEP, Baltimore SureWare,
+        Broadcom and Cryptographic Appliance's keyserver
+        [in 0.9.6c-engine release].
+
+  Major changes between OpenSSL 0.9.6a and OpenSSL 0.9.6b:
+
+      o Security fix: PRNG improvements.
+      o Security fix: RSA OAEP check.
+      o Security fix: Reinsert and fix countermeasure to Bleichbacher's
+        attack.
+      o MIPS bug fix in BIGNUM.
+      o Bug fix in "openssl enc".
+      o Bug fix in X.509 printing routine.
+      o Bug fix in DSA verification routine and DSA S/MIME verification.
+      o Bug fix to make PRNG thread-safe.
+      o Bug fix in RAND_file_name().
+      o Bug fix in compatibility mode trust settings.
+      o Bug fix in blowfish EVP.
+      o Increase default size for BIO buffering filter.
+      o Compatibility fixes in some scripts.
+
+  Major changes between OpenSSL 0.9.6 and OpenSSL 0.9.6a:
+
+      o Security fix: change behavior of OpenSSL to avoid using
+        environment variables when running as root.
+      o Security fix: check the result of RSA-CRT to reduce the
+        possibility of deducing the private key from an incorrectly
+        calculated signature.
+      o Security fix: prevent Bleichenbacher's DSA attack.
+      o Security fix: Zero the premaster secret after deriving the
+        master secret in DH ciphersuites.
+      o Reimplement SSL_peek(), which had various problems.
+      o Compatibility fix: the function des_encrypt() renamed to
+        des_encrypt1() to avoid clashes with some Unixen libc.
+      o Bug fixes for Win32, HP/UX and Irix.
+      o Bug fixes in BIGNUM, SSL, PKCS#7, PKCS#12, X.509, CONF and
+        memory checking routines.
+      o Bug fixes for RSA operations in threaded environments.
+      o Bug fixes in misc. openssl applications.
+      o Remove a few potential memory leaks.
+      o Add tighter checks of BIGNUM routines.
+      o Shared library support has been reworked for generality.
+      o More documentation.
+      o New function BN_rand_range().
+      o Add "-rand" option to openssl s_client and s_server.
+
+  Major changes between OpenSSL 0.9.5a and OpenSSL 0.9.6:
+
+      o Some documentation for BIO and SSL libraries.
+      o Enhanced chain verification using key identifiers.
+      o New sign and verify options to 'dgst' application.
+      o Support for DER and PEM encoded messages in 'smime' application.
+      o New 'rsautl' application, low level RSA utility.
+      o MD4 now included.
+      o Bugfix for SSL rollback padding check.
+      o Support for external crypto devices [1].
+      o Enhanced EVP interface.
+
+    [1] The support for external crypto devices is currently a separate
+        distribution.  See the file README.ENGINE.
+
+  Major changes between OpenSSL 0.9.5 and OpenSSL 0.9.5a:
+
+      o Bug fixes for Win32, SuSE Linux, NeXTSTEP and FreeBSD 2.2.8 
+      o Shared library support for HPUX and Solaris-gcc
+      o Support of Linux/IA64
+      o Assembler support for Mingw32
+      o New 'rand' application
+      o New way to check for existence of algorithms from scripts
+
+  Major changes between OpenSSL 0.9.4 and OpenSSL 0.9.5:
+
+      o S/MIME support in new 'smime' command
+      o Documentation for the OpenSSL command line application
+      o Automation of 'req' application
+      o Fixes to make s_client, s_server work under Windows
+      o Support for multiple fieldnames in SPKACs
+      o New SPKAC command line utilty and associated library functions
+      o Options to allow passwords to be obtained from various sources
+      o New public key PEM format and options to handle it
+      o Many other fixes and enhancements to command line utilities
+      o Usable certificate chain verification
+      o Certificate purpose checking
+      o Certificate trust settings
+      o Support of authority information access extension
+      o Extensions in certificate requests
+      o Simplified X509 name and attribute routines
+      o Initial (incomplete) support for international character sets
+      o New DH_METHOD, DSA_METHOD and enhanced RSA_METHOD
+      o Read only memory BIOs and simplified creation function
+      o TLS/SSL protocol bugfixes: Accept TLS 'client hello' in SSL 3.0
+        record; allow fragmentation and interleaving of handshake and other
+        data
+      o TLS/SSL code now "tolerates" MS SGC
+      o Work around for Netscape client certificate hang bug
+      o RSA_NULL option that removes RSA patent code but keeps other
+        RSA functionality
+      o Memory leak detection now allows applications to add extra information
+        via a per-thread stack
+      o PRNG robustness improved
+      o EGD support
+      o BIGNUM library bug fixes
+      o Faster DSA parameter generation
+      o Enhanced support for Alpha Linux
+      o Experimental MacOS support
+
+  Major changes between OpenSSL 0.9.3 and OpenSSL 0.9.4:
+
+      o Transparent support for PKCS#8 format private keys: these are used
+        by several software packages and are more secure than the standard
+        form
+      o PKCS#5 v2.0 implementation
+      o Password callbacks have a new void * argument for application data
+      o Avoid various memory leaks
+      o New pipe-like BIO that allows using the SSL library when actual I/O
+        must be handled by the application (BIO pair)
+
+  Major changes between OpenSSL 0.9.2b and OpenSSL 0.9.3:
+      o Lots of enhancements and cleanups to the Configuration mechanism
+      o RSA OEAP related fixes
+      o Added `openssl ca -revoke' option for revoking a certificate
+      o Source cleanups: const correctness, type-safe stacks and ASN.1 SETs
+      o Source tree cleanups: removed lots of obsolete files
+      o Thawte SXNet, certificate policies and CRL distribution points
+        extension support
+      o Preliminary (experimental) S/MIME support
+      o Support for ASN.1 UTF8String and VisibleString
+      o Full integration of PKCS#12 code
+      o Sparc assembler bignum implementation, optimized hash functions
+      o Option to disable selected ciphers
+
+  Major changes between OpenSSL 0.9.1c and OpenSSL 0.9.2b:
+      o Fixed a security hole related to session resumption
+      o Fixed RSA encryption routines for the p < q case
+      o "ALL" in cipher lists now means "everything except NULL ciphers"
+      o Support for Triple-DES CBCM cipher
+      o Support of Optimal Asymmetric Encryption Padding (OAEP) for RSA
+      o First support for new TLSv1 ciphers
+      o Added a few new BIOs (syslog BIO, reliable BIO)
+      o Extended support for DSA certificate/keys.
+      o Extended support for Certificate Signing Requests (CSR)
+      o Initial support for X.509v3 extensions
+      o Extended support for compression inside the SSL record layer
+      o Overhauled Win32 builds
+      o Cleanups and fixes to the Big Number (BN) library
+      o Support for ASN.1 GeneralizedTime
+      o Splitted ASN.1 SETs from SEQUENCEs
+      o ASN1 and PEM support for Netscape Certificate Sequences
+      o Overhauled Perl interface
+      o Lots of source tree cleanups.
+      o Lots of memory leak fixes.
+      o Lots of bug fixes.
+
+  Major changes between SSLeay 0.9.0b and OpenSSL 0.9.1c:
+      o Integration of the popular NO_RSA/NO_DSA patches
+      o Initial support for compression inside the SSL record layer
+      o Added BIO proxy and filtering functionality
+      o Extended Big Number (BN) library
+      o Added RIPE MD160 message digest
+      o Addeed support for RC2/64bit cipher
+      o Extended ASN.1 parser routines
+      o Adjustations of the source tree for CVS
+      o Support for various new platforms
+
diff --git a/openssl/Netware/build.bat b/openssl/Netware/build.bat
new file mode 100644
index 0000000..3125c2a
--- /dev/null
+++ b/openssl/Netware/build.bat
@@ -0,0 +1,235 @@
+@echo off
+
+rem ========================================================================
+rem   Batch file to automate building OpenSSL for NetWare.
+rem
+rem   usage:
+rem      build [target] [debug opts] [assembly opts] [configure opts]
+rem
+rem      target        - "netware-clib" - CLib NetWare build (WinSock Sockets)
+rem                    - "netware-clib-bsdsock" - CLib NetWare build (BSD Sockets)
+rem                    - "netware-libc" - LibC NetWare build (WinSock Sockets)
+rem                    - "netware-libc-bsdsock" - LibC NetWare build (BSD Sockets)
+rem 
+rem      debug opts    - "debug"  - build debug
+rem
+rem      assembly opts - "nw-mwasm" - use Metrowerks assembler
+rem                    - "nw-nasm"  - use NASM assembler
+rem                    - "no-asm"   - don't use assembly
+rem
+rem      configure opts- all unrecognized arguments are passed to the
+rem                       perl configure script
+rem
+rem   If no arguments are specified the default is to build non-debug with
+rem   no assembly.  NOTE: there is no default BLD_TARGET.
+rem
+
+
+
+rem   No assembly is the default - Uncomment section below to change
+rem   the assembler default
+set ASM_MODE=
+set ASSEMBLER=
+set NO_ASM=no-asm
+
+rem   Uncomment to default to the Metrowerks assembler
+rem set ASM_MODE=nw-mwasm
+rem set ASSEMBLER=Metrowerks
+rem set NO_ASM=
+
+rem   Uncomment to default to the NASM assembler
+rem set ASM_MODE=nw-nasm
+rem set ASSEMBLER=NASM
+rem set NO_ASM=
+
+rem   No default Bld target
+set BLD_TARGET=no_target
+rem set BLD_TARGET=netware-clib
+rem set BLD_TARGET=netware-libc
+
+
+rem   Default to build non-debug
+set DEBUG=
+                                    
+rem   Uncomment to default to debug build
+rem set DEBUG=debug
+
+
+set CONFIG_OPTS=
+set ARG_PROCESSED=NO
+
+
+rem   Process command line args
+:opts
+if "a%1" == "a" goto endopt
+if "%1" == "no-asm"   set NO_ASM=no-asm
+if "%1" == "no-asm"   set ARG_PROCESSED=YES
+if "%1" == "debug"    set DEBUG=debug
+if "%1" == "debug"    set ARG_PROCESSED=YES
+if "%1" == "nw-nasm"  set ASM_MODE=nw-nasm
+if "%1" == "nw-nasm"  set ASSEMBLER=NASM
+if "%1" == "nw-nasm"  set NO_ASM=
+if "%1" == "nw-nasm"  set ARG_PROCESSED=YES
+if "%1" == "nw-mwasm" set ASM_MODE=nw-mwasm
+if "%1" == "nw-mwasm" set ASSEMBLER=Metrowerks
+if "%1" == "nw-mwasm" set NO_ASM=
+if "%1" == "nw-mwasm" set ARG_PROCESSED=YES
+if "%1" == "netware-clib" set BLD_TARGET=netware-clib
+if "%1" == "netware-clib" set ARG_PROCESSED=YES
+if "%1" == "netware-clib-bsdsock" set BLD_TARGET=netware-clib-bsdsock
+if "%1" == "netware-clib-bsdsock" set ARG_PROCESSED=YES
+if "%1" == "netware-libc" set BLD_TARGET=netware-libc
+if "%1" == "netware-libc" set ARG_PROCESSED=YES
+if "%1" == "netware-libc-bsdsock" set BLD_TARGET=netware-libc-bsdsock
+if "%1" == "netware-libc-bsdsock" set ARG_PROCESSED=YES
+
+rem   If we didn't recognize the argument, consider it an option for config
+if "%ARG_PROCESSED%" == "NO" set CONFIG_OPTS=%CONFIG_OPTS% %1
+if "%ARG_PROCESSED%" == "YES" set ARG_PROCESSED=NO
+
+shift
+goto opts
+:endopt
+
+rem make sure a valid BLD_TARGET was specified
+if "%BLD_TARGET%" == "no_target" goto no_target
+
+rem build the nlm make file name which includes target and debug info
+set NLM_MAKE=
+if "%BLD_TARGET%" == "netware-clib" set NLM_MAKE=netware\nlm_clib
+if "%BLD_TARGET%" == "netware-clib-bsdsock" set NLM_MAKE=netware\nlm_clib_bsdsock
+if "%BLD_TARGET%" == "netware-libc" set NLM_MAKE=netware\nlm_libc
+if "%BLD_TARGET%" == "netware-libc-bsdsock" set NLM_MAKE=netware\nlm_libc_bsdsock
+if "%DEBUG%" == "" set NLM_MAKE=%NLM_MAKE%.mak
+if "%DEBUG%" == "debug" set NLM_MAKE=%NLM_MAKE%_dbg.mak
+
+if "%NO_ASM%" == "no-asm" set ASM_MODE=
+if "%NO_ASM%" == "no-asm" set ASSEMBLER=
+if "%NO_ASM%" == "no-asm" set CONFIG_OPTS=%CONFIG_OPTS% no-asm
+if "%NO_ASM%" == "no-asm" goto do_config
+
+
+rem ==================================================
+echo Generating x86 for %ASSEMBLER% assembler
+
+echo Bignum
+cd crypto\bn\asm
+rem perl x86.pl %ASM_MODE% > bn-nw.asm
+perl bn-586.pl %ASM_MODE% > bn-nw.asm
+perl co-586.pl %ASM_MODE% > co-nw.asm
+cd ..\..\..
+
+echo AES
+cd crypto\aes\asm
+perl aes-586.pl %ASM_MODE% > a-nw.asm
+cd ..\..\..
+
+echo DES
+cd crypto\des\asm
+perl des-586.pl %ASM_MODE% > d-nw.asm
+cd ..\..\..
+
+echo "crypt(3)"
+
+cd crypto\des\asm
+perl crypt586.pl %ASM_MODE% > y-nw.asm
+cd ..\..\..
+
+echo Blowfish
+
+cd crypto\bf\asm
+perl bf-586.pl %ASM_MODE% > b-nw.asm
+cd ..\..\..
+
+echo CAST5
+cd crypto\cast\asm
+perl cast-586.pl %ASM_MODE% > c-nw.asm
+cd ..\..\..
+
+echo RC4
+cd crypto\rc4\asm
+perl rc4-586.pl %ASM_MODE% > r4-nw.asm
+cd ..\..\..
+
+echo MD5
+cd crypto\md5\asm
+perl md5-586.pl %ASM_MODE% > m5-nw.asm
+cd ..\..\..
+
+echo SHA1
+cd crypto\sha\asm
+perl sha1-586.pl %ASM_MODE% > s1-nw.asm
+perl sha256-586.pl %ASM_MODE% > sha256-nw.asm
+perl sha512-586.pl %ASM_MODE% > sha512-nw.asm
+cd ..\..\..
+
+echo RIPEMD160
+cd crypto\ripemd\asm
+perl rmd-586.pl %ASM_MODE% > rm-nw.asm
+cd ..\..\..
+
+echo RC5\32
+cd crypto\rc5\asm
+perl rc5-586.pl %ASM_MODE% > r5-nw.asm
+cd ..\..\..
+
+echo WHIRLPOOL
+cd crypto\whrlpool\asm
+perl wp-mmx.pl %ASM_MODE% > wp-nw.asm
+cd ..\..\..
+
+echo CPUID
+cd crypto
+perl x86cpuid.pl %ASM_MODE% > x86cpuid-nw.asm
+cd ..\
+
+rem ===============================================================
+rem
+:do_config
+
+echo .
+echo configure options: %CONFIG_OPTS% %BLD_TARGET%
+echo .
+perl configure %CONFIG_OPTS% %BLD_TARGET%
+
+perl util\mkfiles.pl >MINFO
+
+echo .
+echo mk1mf.pl options: %DEBUG% %ASM_MODE% %CONFIG_OPTS% %BLD_TARGET%
+echo .
+perl util\mk1mf.pl %DEBUG% %ASM_MODE% %CONFIG_OPTS% %BLD_TARGET% >%NLM_MAKE%
+
+make -f %NLM_MAKE% vclean
+echo .
+echo The makefile "%NLM_MAKE%" has been created use your maketool to
+echo build (ex: make -f %NLM_MAKE%)
+goto end
+
+rem ===============================================================
+rem
+:no_target
+echo .
+echo .  No build target specified!!!
+echo .
+echo .  usage: build [target] [debug opts] [assembly opts] [configure opts]
+echo .
+echo .     target        - "netware-clib" - CLib NetWare build (WinSock Sockets)
+echo .                   - "netware-clib-bsdsock" - CLib NetWare build (BSD Sockets)
+echo .                   - "netware-libc" - LibC NetWare build (WinSock Sockets)
+echo .                   - "netware-libc-bsdsock" - LibC NetWare build (BSD Sockets)
+echo .
+echo .     debug opts    - "debug"  - build debug
+echo .
+echo .     assembly opts - "nw-mwasm" - use Metrowerks assembler
+echo .                     "nw-nasm"  - use NASM assembler
+echo .                     "no-asm"   - don't use assembly
+echo .
+echo .     configure opts- all unrecognized arguments are passed to the
+echo .                      perl configure script
+echo .
+echo .  If no debug or assembly opts are specified the default is to build
+echo .  non-debug without assembly
+echo .
+
+        
+:end        
diff --git a/openssl/Netware/cpy_tests.bat b/openssl/Netware/cpy_tests.bat
new file mode 100644
index 0000000..1583f28
--- /dev/null
+++ b/openssl/Netware/cpy_tests.bat
@@ -0,0 +1,113 @@
+@echo off
+
+rem   Batch file to copy OpenSSL stuff to a NetWare server for testing
+
+rem   This batch file will create an "opensssl" directory at the root of the
+rem   specified NetWare drive and copy the required files to run the tests.
+rem   It should be run from inside the "openssl\netware" subdirectory.
+
+rem   Usage:
+rem      cpy_tests.bat <test subdirectory> <NetWare drive>
+rem          <test subdirectory> - out_nw.dbg | out_nw
+rem          <NetWare drive> - any mapped drive letter
+rem
+rem      example ( copy from debug build to m: dirve ):
+rem              cpy_tests.bat out_nw.dbg m:
+rem
+rem      CAUTION:  If a directory named OpenSSL exists on the target drive
+rem                it will be deleted first.
+
+
+if "%1" == "" goto usage
+if "%2" == "" goto usage
+
+rem   Assume running in \openssl directory unless cpy_tests.bat exists then
+rem   it must be the \openssl\netware directory
+set loc=.
+if exist cpy_tests.bat set loc=..
+
+rem   make sure the local build subdirectory specified is valid
+if not exist %loc%\%1\NUL goto invalid_dir
+
+rem   make sure target drive is valid
+if not exist %2\NUL goto invalid_drive
+
+rem   If an OpenSSL directory exists on the target drive, remove it
+if exist %2\openssl\NUL goto remove_openssl
+goto do_copy
+
+:remove_openssl
+echo .
+echo OpenSSL directory exists on %2 - it will be removed!
+pause
+rmdir %2\openssl /s /q
+
+:do_copy
+rem   make an "openssl" directory and others at the root of the NetWare drive
+mkdir %2\openssl
+mkdir %2\openssl\test_out
+mkdir %2\openssl\apps
+mkdir %2\openssl\certs
+mkdir %2\openssl\test
+
+
+rem   copy the test nlms
+copy %loc%\%1\*.nlm %2\openssl\
+
+rem   copy the test perl script
+copy %loc%\netware\do_tests.pl %2\openssl\
+
+rem   copy the certs directory stuff
+xcopy %loc%\certs\*.*         %2\openssl\certs\ /s
+
+rem   copy the test directory stuff
+copy %loc%\test\CAss.cnf      %2\openssl\test\
+copy %loc%\test\Uss.cnf       %2\openssl\test\
+copy %loc%\test\pkcs7.pem     %2\openssl\test\
+copy %loc%\test\pkcs7-1.pem   %2\openssl\test\
+copy %loc%\test\testcrl.pem   %2\openssl\test\
+copy %loc%\test\testp7.pem    %2\openssl\test\
+copy %loc%\test\testreq2.pem  %2\openssl\test\
+copy %loc%\test\testrsa.pem   %2\openssl\test\
+copy %loc%\test\testsid.pem   %2\openssl\test\
+copy %loc%\test\testx509.pem  %2\openssl\test\
+copy %loc%\test\v3-cert1.pem  %2\openssl\test\
+copy %loc%\test\v3-cert2.pem  %2\openssl\test\
+copy %loc%\crypto\evp\evptests.txt %2\openssl\test\
+
+rem   copy the apps directory stuff
+copy %loc%\apps\client.pem    %2\openssl\apps\
+copy %loc%\apps\server.pem    %2\openssl\apps\
+copy %loc%\apps\openssl.cnf   %2\openssl\apps\
+
+echo .
+echo Tests copied
+echo Run the test script at the console by typing:
+echo     "Perl \openssl\do_tests.pl"
+echo .
+echo Make sure the Search path includes the OpenSSL subdirectory
+
+goto end
+
+:invalid_dir
+echo.
+echo Invalid build directory specified: %1
+echo.
+goto usage
+
+:invalid_drive
+echo.
+echo Invalid drive: %2
+echo.
+goto usage
+
+:usage
+echo.
+echo usage: cpy_tests.bat [test subdirectory] [NetWare drive]
+echo     [test subdirectory] - out_nw_clib.dbg, out_nw_libc.dbg, etc. 
+echo     [NetWare drive]     - any mapped drive letter
+echo.
+echo example: cpy_test out_nw_clib.dbg M:
+echo  (copy from clib debug build area to M: drive)
+
+:end
diff --git a/openssl/Netware/do_tests.pl b/openssl/Netware/do_tests.pl
new file mode 100644
index 0000000..ac482db
--- /dev/null
+++ b/openssl/Netware/do_tests.pl
@@ -0,0 +1,624 @@
+# perl script to run OpenSSL tests
+
+
+my $base_path      = "\\openssl";
+
+my $output_path    = "$base_path\\test_out";
+my $cert_path      = "$base_path\\certs";
+my $test_path      = "$base_path\\test";
+my $app_path       = "$base_path\\apps";
+
+my $tmp_cert       = "$output_path\\cert.tmp";
+my $OpenSSL_config = "$app_path\\openssl.cnf";
+my $log_file       = "$output_path\\tests.log";
+
+my $pause = 0;
+
+
+#  process the command line args to see if they wanted us to pause
+#  between executing each command
+foreach $i (@ARGV)
+{
+   if ($i =~ /^-p$/)
+   { $pause=1; }
+}
+
+
+
+main();
+
+
+############################################################################
+sub main()
+{
+   # delete all the output files in the output directory
+   unlink <$output_path\\*.*>;
+
+   # open the main log file
+   open(OUT, ">$log_file") || die "unable to open $log_file\n";
+
+   print( OUT "========================================================\n");
+   my $outFile = "$output_path\\version.out";
+   system("openssl2 version (CLIB_OPT)/>$outFile");
+   log_output("CHECKING FOR OPENSSL VERSION:", $outFile);
+
+   algorithm_tests();
+   encryption_tests();
+   evp_tests();
+   pem_tests();
+   verify_tests();
+   ca_tests();
+   ssl_tests();
+
+   close(OUT);
+
+   print("\nCompleted running tests.\n\n");
+   print("Check log file for errors: $log_file\n");
+}
+
+############################################################################
+sub algorithm_tests
+{
+   my $i;
+   my $outFile;
+   my @tests = ( rsa_test, destest, ideatest, bftest, bntest, shatest, sha1test,
+                 sha256t, sha512t, dsatest, md2test, md4test, md5test, mdc2test,
+                 rc2test, rc4test, rc5test, randtest, rmdtest, dhtest, ecdhtest,
+                 ecdsatest, ectest, exptest, casttest, hmactest );
+
+   print( "\nRUNNING CRYPTO ALGORITHM TESTS:\n\n");
+
+   print( OUT "\n========================================================\n");
+   print( OUT "CRYPTO ALGORITHM TESTS:\n\n");
+
+   foreach $i (@tests)
+   {
+      if (-e "$base_path\\$i.nlm")
+      {
+         $outFile = "$output_path\\$i.out";
+         system("$i (CLIB_OPT)/>$outFile");
+         log_desc("Test: $i\.nlm:");
+         log_output("", $outFile );
+      }
+      else
+      {
+         log_desc("Test: $i\.nlm: file not found");
+      }
+   }
+}
+
+############################################################################
+sub encryption_tests
+{
+   my $i;
+   my $outFile;
+   my @enc_tests = ( "enc", "rc4", "des-cfb", "des-ede-cfb", "des-ede3-cfb",
+                     "des-ofb", "des-ede-ofb", "des-ede3-ofb",
+                     "des-ecb", "des-ede", "des-ede3", "des-cbc",
+                     "des-ede-cbc", "des-ede3-cbc", "idea-ecb", "idea-cfb",
+                     "idea-ofb", "idea-cbc", "rc2-ecb", "rc2-cfb",
+                     "rc2-ofb", "rc2-cbc", "bf-ecb", "bf-cfb",
+                     "bf-ofb", "bf-cbc" );
+
+   my $input = "$base_path\\do_tests.pl";
+   my $cipher = "$output_path\\cipher.out";
+   my $clear = "$output_path\\clear.out";
+
+   print( "\nRUNNING ENCRYPTION & DECRYPTION TESTS:\n\n");
+
+   print( OUT "\n========================================================\n");
+   print( OUT "FILE ENCRYPTION & DECRYPTION TESTS:\n\n");
+
+   foreach $i (@enc_tests)
+   {
+      log_desc("Testing: $i");
+
+      # do encryption
+      $outFile = "$output_path\\enc.out";
+      system("openssl2 $i -e -bufsize 113 -k test -in $input -out $cipher (CLIB_OPT)/>$outFile" );
+      log_output("Encrypting: $input --> $cipher", $outFile);
+
+      # do decryption
+      $outFile = "$output_path\\dec.out";
+      system("openssl2 $i -d -bufsize 157 -k test -in $cipher -out $clear (CLIB_OPT)/>$outFile");
+      log_output("Decrypting: $cipher --> $clear", $outFile);
+
+      # compare files
+      $x = compare_files( $input, $clear, 1);
+      if ( $x == 0 )
+      {
+         print( "\rSUCCESS - files match: $input, $clear\n");
+         print( OUT "SUCCESS - files match: $input, $clear\n");
+      }
+      else
+      {
+         print( "\rERROR: files don't match\n");
+         print( OUT "ERROR: files don't match\n");
+      }
+
+      do_wait();
+
+      # Now do the same encryption but use Base64
+
+      # do encryption B64
+      $outFile = "$output_path\\B64enc.out";
+      system("openssl2 $i -a -e -bufsize 113 -k test -in $input -out $cipher (CLIB_OPT)/>$outFile");
+      log_output("Encrypting(B64): $cipher --> $clear", $outFile);
+
+      # do decryption B64
+      $outFile = "$output_path\\B64dec.out";
+      system("openssl2 $i -a -d -bufsize 157 -k test -in $cipher -out $clear (CLIB_OPT)/>$outFile");
+      log_output("Decrypting(B64): $cipher --> $clear", $outFile);
+
+      # compare files
+      $x = compare_files( $input, $clear, 1);
+      if ( $x == 0 )
+      {
+         print( "\rSUCCESS - files match: $input, $clear\n");
+         print( OUT "SUCCESS - files match: $input, $clear\n");
+      }
+      else
+      {
+         print( "\rERROR: files don't match\n");
+         print( OUT "ERROR: files don't match\n");
+      }
+
+      do_wait();
+
+   } # end foreach
+
+   # delete the temporary files
+   unlink($cipher);
+   unlink($clear);
+}
+
+
+############################################################################
+sub pem_tests
+{
+   my $i;
+   my $tmp_out;
+   my $outFile = "$output_path\\pem.out";
+
+   my %pem_tests = (
+         "crl"      => "testcrl.pem",
+          "pkcs7"   => "testp7.pem",
+          "req"     => "testreq2.pem",
+          "rsa"     => "testrsa.pem",
+          "x509"    => "testx509.pem",
+          "x509"    => "v3-cert1.pem",
+          "sess_id" => "testsid.pem"  );
+
+
+   print( "\nRUNNING PEM TESTS:\n\n");
+
+   print( OUT "\n========================================================\n");
+   print( OUT "PEM TESTS:\n\n");
+
+   foreach $i (keys(%pem_tests))
+   {
+      log_desc( "Testing: $i");
+
+      my $input = "$test_path\\$pem_tests{$i}";
+
+      $tmp_out = "$output_path\\$pem_tests{$i}";
+
+      if ($i ne "req" )
+      {
+         system("openssl2 $i -in $input -out $tmp_out (CLIB_OPT)/>$outFile");
+         log_output( "openssl2 $i -in $input -out $tmp_out", $outFile);
+      }
+      else
+      {
+         system("openssl2 $i -in $input -out $tmp_out -config $OpenSSL_config (CLIB_OPT)/>$outFile");
+         log_output( "openssl2 $i -in $input -out $tmp_out -config $OpenSSL_config", $outFile );
+      }
+
+      $x = compare_files( $input, $tmp_out);
+      if ( $x == 0 )
+      {
+         print( "\rSUCCESS - files match: $input, $tmp_out\n");
+         print( OUT "SUCCESS - files match: $input, $tmp_out\n");
+      }
+      else
+      {
+         print( "\rERROR: files don't match\n");
+         print( OUT "ERROR: files don't match\n");
+      }
+      do_wait();
+
+   } # end foreach
+}
+
+
+############################################################################
+sub verify_tests
+{
+   my $i;
+   my $outFile = "$output_path\\verify.out";
+
+   $cert_path =~ s/\\/\//g;
+   my @cert_files = <$cert_path/*.pem>;
+
+   print( "\nRUNNING VERIFY TESTS:\n\n");
+
+   print( OUT "\n========================================================\n");
+   print( OUT "VERIFY TESTS:\n\n");
+
+   make_tmp_cert_file();
+
+   foreach $i (@cert_files)
+   {
+      system("openssl2 verify -CAfile $tmp_cert $i (CLIB_OPT)/>$outFile");
+      log_desc("Verifying cert: $i");
+      log_output("openssl2 verify -CAfile $tmp_cert $i", $outFile);
+   }
+}
+
+
+############################################################################
+sub ssl_tests
+{
+   my $outFile = "$output_path\\ssl_tst.out";
+   my($CAcert) = "$output_path\\certCA.ss";
+   my($Ukey)   = "$output_path\\keyU.ss";
+   my($Ucert)  = "$output_path\\certU.ss";
+   my($ssltest)= "ssltest -key $Ukey -cert $Ucert -c_key $Ukey -c_cert $Ucert -CAfile $CAcert";
+
+   print( "\nRUNNING SSL TESTS:\n\n");
+
+   print( OUT "\n========================================================\n");
+   print( OUT "SSL TESTS:\n\n");
+
+   system("ssltest -ssl2 (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv2:");
+   log_output("ssltest -ssl2", $outFile);
+
+   system("$ssltest -ssl2 -server_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv2 with server authentication:");
+   log_output("$ssltest -ssl2 -server_auth", $outFile);
+
+   system("$ssltest -ssl2 -client_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv2 with client authentication:");
+   log_output("$ssltest -ssl2 -client_auth", $outFile);
+
+   system("$ssltest -ssl2 -server_auth -client_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv2 with both client and server authentication:");
+   log_output("$ssltest -ssl2 -server_auth -client_auth", $outFile);
+
+   system("ssltest -ssl3 (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv3:");
+   log_output("ssltest -ssl3", $outFile);
+
+   system("$ssltest -ssl3 -server_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv3 with server authentication:");
+   log_output("$ssltest -ssl3 -server_auth", $outFile);
+
+   system("$ssltest -ssl3 -client_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv3 with client authentication:");
+   log_output("$ssltest -ssl3 -client_auth", $outFile);
+
+   system("$ssltest -ssl3 -server_auth -client_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv3 with both client and server authentication:");
+   log_output("$ssltest -ssl3 -server_auth -client_auth", $outFile);
+
+   system("ssltest (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv2/sslv3:");
+   log_output("ssltest", $outFile);
+
+   system("$ssltest -server_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv2/sslv3 with server authentication:");
+   log_output("$ssltest -server_auth", $outFile);
+
+   system("$ssltest -client_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv2/sslv3 with client authentication:");
+   log_output("$ssltest -client_auth ", $outFile);
+
+   system("$ssltest -server_auth -client_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv2/sslv3 with both client and server authentication:");
+   log_output("$ssltest -server_auth -client_auth", $outFile);
+
+   system("ssltest -bio_pair -ssl2 (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv2 via BIO pair:");
+   log_output("ssltest -bio_pair -ssl2", $outFile);
+
+   system("ssltest -bio_pair -dhe1024dsa -v (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv2/sslv3 with 1024 bit DHE via BIO pair:");
+   log_output("ssltest -bio_pair -dhe1024dsa -v", $outFile);
+
+   system("$ssltest -bio_pair -ssl2 -server_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv2 with server authentication via BIO pair:");
+   log_output("$ssltest -bio_pair -ssl2 -server_auth", $outFile);
+
+   system("$ssltest -bio_pair -ssl2 -client_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv2 with client authentication via BIO pair:");
+   log_output("$ssltest -bio_pair -ssl2 -client_auth", $outFile);
+
+   system("$ssltest -bio_pair -ssl2 -server_auth -client_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv2 with both client and server authentication via BIO pair:");
+   log_output("$ssltest -bio_pair -ssl2 -server_auth -client_auth", $outFile);
+
+   system("ssltest -bio_pair -ssl3 (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv3 via BIO pair:");
+   log_output("ssltest -bio_pair -ssl3", $outFile);
+
+   system("$ssltest -bio_pair -ssl3 -server_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv3 with server authentication via BIO pair:");
+   log_output("$ssltest -bio_pair -ssl3 -server_auth", $outFile);
+
+   system("$ssltest -bio_pair -ssl3 -client_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv3 with client authentication  via BIO pair:");
+   log_output("$ssltest -bio_pair -ssl3 -client_auth", $outFile);
+
+   system("$ssltest -bio_pair -ssl3 -server_auth -client_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv3 with both client and server authentication via BIO pair:");
+   log_output("$ssltest -bio_pair -ssl3 -server_auth -client_auth", $outFile);
+
+   system("ssltest -bio_pair (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv2/sslv3 via BIO pair:");
+   log_output("ssltest -bio_pair", $outFile);
+
+   system("$ssltest -bio_pair -server_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv2/sslv3 with server authentication via BIO pair:");
+   log_output("$ssltest -bio_pair -server_auth", $outFile);
+
+   system("$ssltest -bio_pair -client_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv2/sslv3 with client authentication via BIO pair:");
+   log_output("$ssltest -bio_pair -client_auth", $outFile);
+
+   system("$ssltest -bio_pair -server_auth -client_auth (CLIB_OPT)/>$outFile");
+   log_desc("Testing sslv2/sslv3 with both client and server authentication via BIO pair:");
+   log_output("$ssltest -bio_pair -server_auth -client_auth", $outFile);
+}
+
+
+############################################################################
+sub ca_tests
+{
+   my $outFile = "$output_path\\ca_tst.out";
+
+   my($CAkey)     = "$output_path\\keyCA.ss";
+   my($CAcert)    = "$output_path\\certCA.ss";
+   my($CAserial)  = "$output_path\\certCA.srl";
+   my($CAreq)     = "$output_path\\reqCA.ss";
+   my($CAreq2)    = "$output_path\\req2CA.ss";
+
+   my($CAconf)    = "$test_path\\CAss.cnf";
+
+   my($Uconf)     = "$test_path\\Uss.cnf";
+
+   my($Ukey)      = "$output_path\\keyU.ss";
+   my($Ureq)      = "$output_path\\reqU.ss";
+   my($Ucert)     = "$output_path\\certU.ss";
+
+   print( "\nRUNNING CA TESTS:\n\n");
+
+   print( OUT "\n========================================================\n");
+   print( OUT "CA TESTS:\n");
+
+   system("openssl2 req -config $CAconf -out $CAreq -keyout $CAkey -new (CLIB_OPT)/>$outFile");
+   log_desc("Make a certificate request using req:");
+   log_output("openssl2 req -config $CAconf -out $CAreq -keyout $CAkey -new", $outFile);
+
+   system("openssl2 x509 -CAcreateserial -in $CAreq -days 30 -req -out $CAcert -signkey $CAkey (CLIB_OPT)/>$outFile");
+   log_desc("Convert the certificate request into a self signed certificate using x509:");
+   log_output("openssl2 x509 -CAcreateserial -in $CAreq -days 30 -req -out $CAcert -signkey $CAkey", $outFile);
+
+   system("openssl2 x509 -in $CAcert -x509toreq -signkey $CAkey -out $CAreq2 (CLIB_OPT)/>$outFile");
+   log_desc("Convert a certificate into a certificate request using 'x509':");
+   log_output("openssl2 x509 -in $CAcert -x509toreq -signkey $CAkey -out $CAreq2", $outFile);
+
+   system("openssl2 req -config $OpenSSL_config -verify -in $CAreq -noout (CLIB_OPT)/>$outFile");
+   log_output("openssl2 req -config $OpenSSL_config -verify -in $CAreq -noout", $outFile);
+
+   system("openssl2 req -config $OpenSSL_config -verify -in $CAreq2 -noout (CLIB_OPT)/>$outFile");
+   log_output( "openssl2 req -config $OpenSSL_config -verify -in $CAreq2 -noout", $outFile);
+
+   system("openssl2 verify -CAfile $CAcert $CAcert (CLIB_OPT)/>$outFile");
+   log_output("openssl2 verify -CAfile $CAcert $CAcert", $outFile);
+
+   system("openssl2 req -config $Uconf -out $Ureq -keyout $Ukey -new (CLIB_OPT)/>$outFile");
+   log_desc("Make another certificate request using req:");
+   log_output("openssl2 req -config $Uconf -out $Ureq -keyout $Ukey -new", $outFile);
+
+   system("openssl2 x509 -CAcreateserial -in $Ureq -days 30 -req -out $Ucert -CA $CAcert -CAkey $CAkey -CAserial $CAserial (CLIB_OPT)/>$outFile");
+   log_desc("Sign certificate request with the just created CA via x509:");
+   log_output("openssl2 x509 -CAcreateserial -in $Ureq -days 30 -req -out $Ucert -CA $CAcert -CAkey $CAkey -CAserial $CAserial", $outFile);
+
+   system("openssl2 verify -CAfile $CAcert $Ucert (CLIB_OPT)/>$outFile");
+   log_output("openssl2 verify -CAfile $CAcert $Ucert", $outFile);
+
+   system("openssl2 x509 -subject -issuer -startdate -enddate -noout -in $Ucert (CLIB_OPT)/>$outFile");
+   log_desc("Certificate details");
+   log_output("openssl2 x509 -subject -issuer -startdate -enddate -noout -in $Ucert", $outFile);
+
+   print(OUT "--\n");
+   print(OUT "The generated CA certificate is $CAcert\n");
+   print(OUT "The generated CA private key is $CAkey\n");
+   print(OUT "The current CA signing serial number is in $CAserial\n");
+
+   print(OUT "The generated user certificate is $Ucert\n");
+   print(OUT "The generated user private key is $Ukey\n");
+   print(OUT "--\n");
+}
+
+############################################################################
+sub evp_tests
+{
+   my $i = 'evp_test';
+
+   print( "\nRUNNING EVP TESTS:\n\n");
+
+   print( OUT "\n========================================================\n");
+   print( OUT "EVP TESTS:\n\n");
+
+   if (-e "$base_path\\$i.nlm")
+   {
+       my $outFile = "$output_path\\$i.out";
+       system("$i $test_path\\evptests.txt (CLIB_OPT)/>$outFile");
+       log_desc("Test: $i\.nlm:");
+       log_output("", $outFile );
+   }
+   else
+   {
+       log_desc("Test: $i\.nlm: file not found");
+   }
+}
+
+############################################################################
+sub log_output( $ $ )
+{
+   my( $desc, $file ) = @_;
+   my($error) = 0;
+   my($key);
+   my($msg);
+
+   if ($desc)
+   {
+      print("\r$desc\n");
+      print(OUT "$desc\n");
+   }
+
+      # loop waiting for test program to complete
+   while ( stat($file) == 0)
+      { print(". "); sleep(1); }
+
+
+      # copy test output to log file
+   open(IN, "<$file");
+   while (<IN>)
+   {
+      print(OUT $_);
+      if ( $_ =~ /ERROR/ )
+      {
+         $error = 1;
+      }
+   }
+      # close and delete the temporary test output file
+   close(IN);
+   unlink($file);
+
+   if ( $error == 0 )
+   {
+      $msg = "Test Succeeded";
+   }
+   else
+   {
+      $msg = "Test Failed";
+   }
+
+   print(OUT "$msg\n");
+
+   if ($pause)
+   {
+      print("$msg - press ENTER to continue...");
+      $key = getc;
+      print("\n");
+   }
+
+      # Several of the testing scripts run a loop loading the
+      # same NLM with different options.
+      # On slow NetWare machines there appears to be some delay in the
+      # OS actually unloading the test nlms and the OS complains about.
+      # the NLM already being loaded.  This additional pause is to
+      # to help provide a little more time for unloading before trying to
+      # load again.
+   sleep(1);
+}
+
+
+############################################################################
+sub log_desc( $ )
+{
+   my( $desc ) = @_;
+
+   print("\n");
+   print("$desc\n");
+
+   print(OUT "\n");
+   print(OUT "$desc\n");
+   print(OUT "======================================\n");
+}
+
+############################################################################
+sub compare_files( $ $ $ )
+{
+   my( $file1, $file2, $binary ) = @_;
+   my( $n1, $n2, $b1, $b2 );
+   my($ret) = 1;
+
+   open(IN0, $file1) || die "\nunable to open $file1\n";
+   open(IN1, $file2) || die "\nunable to open $file2\n";
+
+  if ($binary)
+  {
+      binmode IN0;
+      binmode IN1;
+  }
+
+   for (;;)
+   {
+      $n1 = read(IN0, $b1, 512);
+      $n2 = read(IN1, $b2, 512);
+
+      if ($n1 != $n2) {last;}
+      if ($b1 != $b2) {last;}
+
+      if ($n1 == 0)
+      {
+         $ret = 0;
+         last;
+      }
+   }
+   close(IN0);
+   close(IN1);
+   return($ret);
+}
+
+############################################################################
+sub do_wait()
+{
+   my($key);
+
+   if ($pause)
+   {
+      print("Press ENTER to continue...");
+      $key = getc;
+      print("\n");
+   }
+}
+
+
+############################################################################
+sub make_tmp_cert_file()
+{
+   my @cert_files = <$cert_path/*.pem>;
+
+      # delete the file if it already exists
+   unlink($tmp_cert);
+
+   open( TMP_CERT, ">$tmp_cert") || die "\nunable to open $tmp_cert\n";
+
+   print("building temporary cert file\n");
+
+   # create a temporary cert file that contains all the certs
+   foreach $i (@cert_files)
+   {
+      open( IN_CERT, $i ) || die "\nunable to open $i\n";
+
+      for(;;)
+      {
+         $n = sysread(IN_CERT, $data, 1024);
+
+         if ($n == 0)
+         {
+            close(IN_CERT);
+            last;
+         };
+
+         syswrite(TMP_CERT, $data, $n);
+      }
+   }
+
+   close( TMP_CERT );
+}
diff --git a/openssl/Netware/globals.txt b/openssl/Netware/globals.txt
new file mode 100644
index 0000000..fe05d39
--- /dev/null
+++ b/openssl/Netware/globals.txt
@@ -0,0 +1,254 @@
+An initial review of the OpenSSL code was done to determine how many 
+global variables where present.  The idea was to determine the amount of 
+work required to pull the globals into an instance data structure in 
+order to build a Library NLM for NetWare.  This file contains the results 
+of the review.  Each file is listed along with the globals in the file.  
+The initial review was done very quickly so this list is probably
+not a comprehensive list.
+
+
+cryptlib.c
+===========================================
+
+static STACK *app_locks=NULL;
+
+static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL;
+
+static void (MS_FAR *locking_callback)(int mode,int type,
+   const char *file,int line)=NULL;
+static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
+   int type,const char *file,int line)=NULL;
+static unsigned long (MS_FAR *id_callback)(void)=NULL;
+static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
+   (const char *file,int line)=NULL;
+static void (MS_FAR *dynlock_lock_callback)(int mode,
+   struct CRYPTO_dynlock_value *l, const char *file,int line)=NULL;
+static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
+   const char *file,int line)=NULL;
+
+
+mem.c
+===========================================
+static int allow_customize = 1;      /* we provide flexible functions for */
+static int allow_customize_debug = 1;/* exchanging memory-related functions at
+
+/* may be changed as long as `allow_customize' is set */
+static void *(*malloc_locked_func)(size_t)  = malloc;
+static void (*free_locked_func)(void *)     = free;
+static void *(*malloc_func)(size_t)         = malloc;
+static void *(*realloc_func)(void *, size_t)= realloc;
+static void (*free_func)(void *)            = free;
+
+/* use default functions from mem_dbg.c */
+static void (*malloc_debug_func)(void *,int,const char *,int,int)
+   = CRYPTO_dbg_malloc;
+static void (*realloc_debug_func)(void *,void *,int,const char *,int,int)
+   = CRYPTO_dbg_realloc;
+static void (*free_debug_func)(void *,int) = CRYPTO_dbg_free;
+static void (*set_debug_options_func)(long) = CRYPTO_dbg_set_options;
+static long (*get_debug_options_func)(void) = CRYPTO_dbg_get_options;
+
+
+mem_dbg.c
+===========================================
+static int mh_mode=CRYPTO_MEM_CHECK_OFF;
+static unsigned long order = 0; /* number of memory requests */
+static LHASH *mh=NULL; /* hash-table of memory requests (address as key) */
+
+static LHASH *amih=NULL; /* hash-table with those app_mem_info_st's */
+static long options =             /* extra information to be recorded */
+static unsigned long disabling_thread = 0;
+
+
+err.c
+===========================================
+static LHASH *error_hash=NULL;
+static LHASH *thread_hash=NULL;
+
+several files have routines with static "init" to track if error strings
+   have been loaded ( may not want seperate error strings for each process )
+   The "init" variable can't be left "global" because the error has is a ptr
+   that is malloc'ed.  The malloc'ed error has is dependant on the "init"
+   vars.
+
+   files:
+      pem_err.c
+      cpt_err.c
+      pk12err.c
+      asn1_err.c
+      bio_err.c
+      bn_err.c
+      buf_err.c
+      comp_err.c
+      conf_err.c
+      cpt_err.c
+      dh_err.c
+      dsa_err.c
+      dso_err.c
+      evp_err.c
+      obj_err.c
+      pkcs7err.c
+      rand_err.c
+      rsa_err.c
+      rsar_err.c
+      ssl_err.c
+      x509_err.c
+      v3err.c
+		err.c
+
+These file have similar "init" globals but they are for other stuff not
+error strings:
+
+		bn_lib.c
+		ecc_enc.c
+		s23_clnt.c
+		s23_meth.c
+		s23_srvr.c
+		s2_clnt.c
+		s2_lib.c
+		s2_meth.c
+		s2_srvr.c
+		s3_clnt.c
+		s3_lib.c
+		s3_srvr.c
+		t1_clnt.c
+		t1_meth.c
+		t1_srvr.c
+
+rand_lib.c
+===========================================
+static RAND_METHOD *rand_meth= &rand_ssleay_meth;
+
+md_rand.c
+===========================================
+static int state_num=0,state_index=0;
+static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH];
+static unsigned char md[MD_DIGEST_LENGTH];
+static long md_count[2]={0,0};
+static double entropy=0;
+static int initialized=0;
+
+/* This should be set to 1 only when ssleay_rand_add() is called inside
+   an already locked state, so it doesn't try to lock and thereby cause
+   a hang.  And it should always be reset back to 0 before unlocking. */
+static int add_do_not_lock=0;
+
+obj_dat.c
+============================================
+static int new_nid=NUM_NID;
+static LHASH *added=NULL;
+
+b_sock.c
+===========================================
+static unsigned long BIO_ghbn_hits=0L;
+static unsigned long BIO_ghbn_miss=0L;
+static struct ghbn_cache_st
+   {
+   char name[129];
+   struct hostent *ent;
+   unsigned long order;
+   } ghbn_cache[GHBN_NUM];
+
+static int wsa_init_done=0;
+
+
+bio_lib.c
+===========================================
+static STACK_OF(CRYPTO_EX_DATA_FUNCS) *bio_meth=NULL;
+static int bio_meth_num=0;
+
+
+bn_lib.c
+========================================
+static int bn_limit_bits=0;
+static int bn_limit_num=8;        /* (1<<bn_limit_bits) */
+static int bn_limit_bits_low=0;
+static int bn_limit_num_low=8;    /* (1<<bn_limit_bits_low) */
+static int bn_limit_bits_high=0;
+static int bn_limit_num_high=8;   /* (1<<bn_limit_bits_high) */
+static int bn_limit_bits_mont=0;
+static int bn_limit_num_mont=8;   /* (1<<bn_limit_bits_mont) */
+
+conf_lib.c
+========================================
+static CONF_METHOD *default_CONF_method=NULL;
+
+dh_lib.c
+========================================
+static DH_METHOD *default_DH_method;
+static int dh_meth_num = 0;
+static STACK_OF(CRYPTO_EX_DATA_FUNCS) *dh_meth = NULL;
+
+dsa_lib.c
+========================================
+static DSA_METHOD *default_DSA_method;
+static int dsa_meth_num = 0;
+static STACK_OF(CRYPTO_EX_DATA_FUNCS) *dsa_meth = NULL;
+
+dso_lib.c
+========================================
+static DSO_METHOD *default_DSO_meth = NULL;
+
+rsa_lib.c
+========================================
+static RSA_METHOD *default_RSA_meth=NULL;
+static int rsa_meth_num=0;
+static STACK_OF(CRYPTO_EX_DATA_FUNCS) *rsa_meth=NULL;
+
+x509_trs.c
+=======================================
+static int (*default_trust)(int id, X509 *x, int flags) = obj_trust;
+static STACK_OF(X509_TRUST) *trtable = NULL;
+
+x509_req.c
+=======================================
+static int *ext_nids = ext_nid_list;
+
+o_names.c
+======================================
+static LHASH *names_lh=NULL;
+static STACK_OF(NAME_FUNCS) *name_funcs_stack;
+static int free_type;
+static int names_type_num=OBJ_NAME_TYPE_NUM;
+
+
+th-lock.c - NEED to add support for locking for NetWare
+==============================================
+static long *lock_count;
+(other platform specific globals)
+
+x_x509.c
+==============================================
+static int x509_meth_num = 0;
+static STACK_OF(CRYPTO_EX_DATA_FUNCS) *x509_meth = NULL;
+
+
+evp_pbe.c
+============================================
+static STACK *pbe_algs;
+
+evp_key.c
+============================================
+static char prompt_string[80];
+
+ssl_ciph.c
+============================================
+static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL;
+
+ssl_lib.c
+=============================================
+static STACK_OF(CRYPTO_EX_DATA_FUNCS) *ssl_meth=NULL;
+static STACK_OF(CRYPTO_EX_DATA_FUNCS) *ssl_ctx_meth=NULL;
+static int ssl_meth_num=0;
+static int ssl_ctx_meth_num=0;
+
+ssl_sess.c
+=============================================
+static int ssl_session_num=0;
+static STACK_OF(CRYPTO_EX_DATA_FUNCS) *ssl_session_meth=NULL;
+
+x509_vfy.c
+============================================
+static STACK_OF(CRYPTO_EX_DATA_FUNCS) *x509_store_ctx_method=NULL;
+static int x509_store_ctx_num=0;
+
diff --git a/openssl/Netware/readme.txt b/openssl/Netware/readme.txt
new file mode 100644
index 0000000..a5b5faa
--- /dev/null
+++ b/openssl/Netware/readme.txt
@@ -0,0 +1,19 @@
+
+Contents of the openssl\netware directory
+==========================================
+
+Regular files:
+
+readme.txt     - this file
+do_tests.pl    - perl script used to run the OpenSSL tests on NetWare
+cpy_tests.bat  - batch to to copy test stuff to NetWare server
+build.bat      - batch file to help with builds
+set_env.bat    - batch file to help setup build environments
+globals.txt    - results of initial code review to identify OpenSSL global variables
+
+
+The following files are generated by the various scripts.  They are
+recreated each time and it is okay to delete them.
+
+*.def - command files used by Metrowerks linker
+*.mak - make files generated by mk1mf.pl
diff --git a/openssl/Netware/set_env.bat b/openssl/Netware/set_env.bat
new file mode 100644
index 0000000..ace024e
--- /dev/null
+++ b/openssl/Netware/set_env.bat
@@ -0,0 +1,112 @@
+@echo off
+
+rem ========================================================================
+rem   Batch file to assist in setting up the necessary enviroment for
+rem   building OpenSSL for NetWare.
+rem
+rem   usage:
+rem      set_env [target]
+rem
+rem      target      - "netware-clib" - Clib build
+rem                  - "netware-libc" - LibC build
+rem
+rem
+
+if "a%1" == "a" goto usage
+               
+set LIBC_BUILD=
+set CLIB_BUILD=
+set GNUC=
+
+if "%1" == "netware-clib" set CLIB_BUILD=Y
+if "%1" == "netware-clib" set LIBC_BUILD=
+
+if "%1" == "netware-libc" set LIBC_BUILD=Y
+if "%1" == "netware-libc" set CLIB_BUILD=
+
+if "%2" == "gnuc" set GNUC=Y
+if "%2" == "codewarrior" set GNUC=
+
+rem   Location of tools (compiler, linker, etc)
+if "%NDKBASE%" == "" set NDKBASE=c:\Novell
+
+rem   If Perl for Win32 is not already in your path, add it here
+set PERL_PATH=
+
+rem   Define path to the Metrowerks command line tools
+rem   or GNU Crosscompiler gcc / nlmconv
+rem   ( compiler, assembler, linker)
+if "%GNUC%" == "Y" set COMPILER_PATH=c:\usr\i586-netware\bin;c:\usr\bin
+if "%GNUC%" == "" set COMPILER_PATH=c:\prg\cwcmdl40
+
+rem   If using gnu make define path to utility
+rem set GNU_MAKE_PATH=%NDKBASE%\gnu
+set GNU_MAKE_PATH=c:\prg\tools
+
+rem   If using ms nmake define path to nmake
+rem set MS_NMAKE_PATH=%NDKBASE%\msvc\600\bin
+
+rem   If using NASM assembler define path
+rem set NASM_PATH=%NDKBASE%\nasm
+set NASM_PATH=c:\prg\tools
+
+rem   Update path to include tool paths
+set path=%path%;%COMPILER_PATH%
+if not "%GNU_MAKE_PATH%" == "" set path=%path%;%GNU_MAKE_PATH%
+if not "%MS_NMAKE_PATH%" == "" set path=%path%;%MS_NMAKE_PATH%
+if not "%NASM_PATH%"     == "" set path=%path%;%NASM_PATH%
+if not "%PERL_PATH%"     == "" set path=%path%;%PERL_PATH%
+
+rem   Set INCLUDES to location of Novell NDK includes
+if "%LIBC_BUILD%" == "Y" set INCLUDE=%NDKBASE%\ndk\libc\include;%NDKBASE%\ndk\libc\include\winsock
+if "%CLIB_BUILD%" == "Y" set INCLUDE=%NDKBASE%\ndk\nwsdk\include\nlm;%NDKBASE%\ws295sdk\include
+
+rem   Set Imports to location of Novell NDK import files
+if "%LIBC_BUILD%" == "Y" set IMPORTS=%NDKBASE%\ndk\libc\imports
+if "%CLIB_BUILD%" == "Y" set IMPORTS=%NDKBASE%\ndk\nwsdk\imports
+
+rem   Set PRELUDE to the absolute path of the prelude object to link with in
+rem   the Metrowerks NetWare PDK - NOTE: for Clib builds "clibpre.o" is 
+rem   recommended, for LibC NKS builds libcpre.o must be used
+if "%GNUC%" == "Y" goto gnuc
+if "%LIBC_BUILD%" == "Y" set PRELUDE=%IMPORTS%\libcpre.o
+rem if "%CLIB_BUILD%" == "Y" set PRELUDE=%IMPORTS%\clibpre.o
+if "%CLIB_BUILD%" == "Y" set PRELUDE=%IMPORTS%\prelude.o
+echo using MetroWerks CodeWarrior 
+goto info
+
+:gnuc
+if "%LIBC_BUILD%" == "Y" set PRELUDE=%IMPORTS%\libcpre.gcc.o
+rem if "%CLIB_BUILD%" == "Y" set PRELUDE=%IMPORTS%\clibpre.gcc.o
+if "%CLIB_BUILD%" == "Y" set PRELUDE=%IMPORTS%\prelude.gcc.o
+echo using GNU GCC Compiler 
+
+:info
+echo.
+
+if "%LIBC_BUILD%" == "Y" echo Enviroment configured for LibC build
+if "%LIBC_BUILD%" == "Y" echo use "netware\build.bat netware-libc ..." 
+
+if "%CLIB_BUILD%" == "Y" echo Enviroment configured for CLib build
+if "%CLIB_BUILD%" == "Y" echo use "netware\build.bat netware-clib ..." 
+
+goto end
+
+:usage
+rem ===============================================================
+echo.
+echo No target build specified!
+echo.
+echo usage: set_env [target] [compiler]
+echo.
+echo target      - "netware-clib" - Clib build
+echo             - "netware-libc" - LibC build
+echo.
+echo compiler    - "gnuc"         - GNU GCC Compiler
+echo             - "codewarrior"  - MetroWerks CodeWarrior (default)
+echo.
+
+:end
+echo.
+
+
diff --git a/openssl/PROBLEMS b/openssl/PROBLEMS
new file mode 100644
index 0000000..d247470
--- /dev/null
+++ b/openssl/PROBLEMS
@@ -0,0 +1,199 @@
+* System libcrypto.dylib and libssl.dylib are used by system ld on MacOS X.
+
+
+    NOTE: The problem described here only applies when OpenSSL isn't built
+    with shared library support (i.e. without the "shared" configuration
+    option).  If you build with shared library support, you will have no
+    problems as long as you set up DYLD_LIBRARY_PATH properly at all times.
+
+
+This is really a misfeature in ld, which seems to look for .dylib libraries
+along the whole library path before it bothers looking for .a libraries.  This
+means that -L switches won't matter unless OpenSSL is built with shared
+library support.
+
+The workaround may be to change the following lines in apps/Makefile and
+test/Makefile:
+
+  LIBCRYPTO=-L.. -lcrypto
+  LIBSSL=-L.. -lssl
+
+to:
+
+  LIBCRYPTO=../libcrypto.a
+  LIBSSL=../libssl.a
+
+It's possible that something similar is needed for shared library support
+as well.  That hasn't been well tested yet.
+
+
+Another solution that many seem to recommend is to move the libraries
+/usr/lib/libcrypto.0.9.dylib, /usr/lib/libssl.0.9.dylib to a different
+directory, build and install OpenSSL and anything that depends on your
+build, then move libcrypto.0.9.dylib and libssl.0.9.dylib back to their
+original places.  Note that the version numbers on those two libraries
+may differ on your machine.
+
+
+As long as Apple doesn't fix the problem with ld, this problem building
+OpenSSL will remain as is. Well, the problem was addressed in 0.9.8f by
+passing -Wl,-search_paths_first, but it's unknown if the flag was
+supported from the initial MacOS X release.
+
+
+* Parallell make leads to errors
+
+While running tests, running a parallell make is a bad idea.  Many test
+scripts use the same name for output and input files, which means different
+will interfere with each other and lead to test failure.
+
+The solution is simple for now: don't run parallell make when testing.
+
+
+* Bugs in gcc triggered
+
+- According to a problem report, there are bugs in gcc 3.0 that are
+  triggered by some of the code in OpenSSL, more specifically in
+  PEM_get_EVP_CIPHER_INFO().  The triggering code is the following:
+
+	header+=11;
+	if (*header != '4') return(0); header++;
+	if (*header != ',') return(0); header++;
+
+  What happens is that gcc might optimize a little too agressively, and
+  you end up with an extra incrementation when *header != '4'.
+
+  We recommend that you upgrade gcc to as high a 3.x version as you can.
+
+- According to multiple problem reports, some of our message digest
+  implementations trigger bug[s] in code optimizer in gcc 3.3 for sparc64
+  and gcc 2.96 for ppc. Former fails to complete RIPEMD160 test, while
+  latter - SHA one.
+
+  The recomendation is to upgrade your compiler. This naturally applies to
+  other similar cases.
+
+- There is a subtle Solaris x86-specific gcc run-time environment bug, which
+  "falls between" OpenSSL [0.9.8 and later], Solaris ld and GCC. The bug
+  manifests itself as Segmentation Fault upon early application start-up.
+  The problem can be worked around by patching the environment according to
+  http://www.openssl.org/~appro/values.c.
+
+* solaris64-sparcv9-cc SHA-1 performance with WorkShop 6 compiler.
+
+As subject suggests SHA-1 might perform poorly (4 times slower)
+if compiled with WorkShop 6 compiler and -xarch=v9. The cause for
+this seems to be the fact that compiler emits multiplication to
+perform shift operations:-( To work the problem around configure
+with './Configure solaris64-sparcv9-cc -DMD32_REG_T=int'.
+
+* Problems with hp-parisc2-cc target when used with "no-asm" flag
+
+When using the hp-parisc2-cc target, wrong bignum code is generated.
+This is due to the SIXTY_FOUR_BIT build being compiled with the +O3
+aggressive optimization.
+The problem manifests itself by the BN_kronecker test hanging in an
+endless loop. Reason: the BN_kronecker test calls BN_generate_prime()
+which itself hangs. The reason could be tracked down to the bn_mul_comba8()
+function in bn_asm.c. At some occasions the higher 32bit value of r[7]
+is off by 1 (meaning: calculated=shouldbe+1). Further analysis failed,
+as no debugger support possible at +O3 and additional fprintf()'s
+introduced fixed the bug, therefore it is most likely a bug in the
+optimizer.
+The bug was found in the BN_kronecker test but may also lead to
+failures in other parts of the code.
+(See Ticket #426.)
+
+Workaround: modify the target to +O2 when building with no-asm.
+
+* Problems building shared libraries on SCO OpenServer Release 5.0.6
+  with gcc 2.95.3
+
+The symptoms appear when running the test suite, more specifically
+test/ectest, with the following result:
+
+OSSL_LIBPATH="`cd ..; pwd`"; LD_LIBRARY_PATH="$OSSL_LIBPATH:$LD_LIBRARY_PATH"; DYLD_LIBRARY_PATH="$OSSL_LIBPATH:$DYLD_LIBRARY_PATH"; SHLIB_PATH="$OSSL_LIBPATH:$SHLIB_PATH"; LIBPATH="$OSSL_LIBPATH:$LIBPATH"; if [ "debug-sco5-gcc" = "Cygwin" ]; then PATH="${LIBPATH}:$PATH"; fi; export LD_LIBRARY_PATH DYLD_LIBRARY_PATH SHLIB_PATH LIBPATH PATH; ./ectest
+ectest.c:186: ABORT
+
+The cause of the problem seems to be that isxdigit(), called from
+BN_hex2bn(), returns 0 on a perfectly legitimate hex digit.  Further
+investigation shows that any of the isxxx() macros return 0 on any
+input.  A direct look in the information array that the isxxx() use,
+called __ctype, shows that it contains all zeroes...
+
+Taking a look at the newly created libcrypto.so with nm, one can see
+that the variable __ctype is defined in libcrypto's .bss (which
+explains why it is filled with zeroes):
+
+$ nm -Pg libcrypto.so | grep __ctype
+__ctype B 0011659c
+__ctype2 U         
+
+Curiously, __ctype2 is undefined, in spite of being declared in
+/usr/include/ctype.h in exactly the same way as __ctype.
+
+Any information helping to solve this issue would be deeply
+appreciated.
+
+NOTE: building non-shared doesn't come with this problem.
+
+* ULTRIX build fails with shell errors, such as "bad substitution"
+  and "test: argument expected"
+
+The problem is caused by ULTRIX /bin/sh supporting only original
+Bourne shell syntax/semantics, and the trouble is that the vast
+majority is so accustomed to more modern syntax, that very few
+people [if any] would recognize the ancient syntax even as valid.
+This inevitably results in non-trivial scripts breaking on ULTRIX,
+and OpenSSL isn't an exclusion. Fortunately there is workaround,
+hire /bin/ksh to do the job /bin/sh fails to do.
+
+1. Trick make(1) to use /bin/ksh by setting up following environ-
+   ment variables *prior* you execute ./Configure and make:
+
+	PROG_ENV=POSIX
+	MAKESHELL=/bin/ksh
+	export PROG_ENV MAKESHELL
+
+   or if your shell is csh-compatible:
+
+	setenv PROG_ENV POSIX
+	setenv MAKESHELL /bin/ksh
+
+2. Trick /bin/sh to use alternative expression evaluator. Create
+   following 'test' script for example in /tmp:
+
+	#!/bin/ksh
+	${0##*/} "$@"
+
+   Then 'chmod a+x /tmp/test; ln /tmp/test /tmp/[' and *prepend*
+   your $PATH with chosen location, e.g. PATH=/tmp:$PATH. Alter-
+   natively just replace system /bin/test and /bin/[ with the
+   above script.
+
+* hpux64-ia64-cc fails blowfish test.
+
+Compiler bug, presumably at particular patch level. It should be noted
+that same compiler generates correct 32-bit code, a.k.a. hpux-ia64-cc
+target. Drop optimization level to +O2 when compiling 64-bit bf_skey.o.
+
+* no-engines generates errors.
+
+Unfortunately, the 'no-engines' configuration option currently doesn't
+work properly.  Use 'no-hw' and you'll will at least get no hardware
+support.  We'll see how we fix that on OpenSSL versions past 0.9.8.
+
+* 'make test' fails in BN_sqr [commonly with "error 139" denoting SIGSEGV]
+  if elder GNU binutils were deployed to link shared libcrypto.so.
+
+As subject suggests the failure is caused by a bug in elder binutils,
+either as or ld, and was observed on FreeBSD and Linux. There are two
+options. First is naturally to upgrade binutils, the second one - to
+reconfigure with additional no-sse2 [or 386] option passed to ./config.
+
+* If configured with ./config no-dso, toolkit still gets linked with -ldl,
+  which most notably poses a problem when linking with dietlibc.
+
+We don't have framework to associate -ldl with no-dso, therefore the only
+way is to edit Makefile right after ./config no-dso and remove -ldl from
+EX_LIBS line.
diff --git a/openssl/README b/openssl/README
new file mode 100644
index 0000000..50d54d5
--- /dev/null
+++ b/openssl/README
@@ -0,0 +1,218 @@
+
+ OpenSSL 1.0.0f 4 Jan 2012
+
+ Copyright (c) 1998-2011 The OpenSSL Project
+ Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
+ All rights reserved.
+
+ DESCRIPTION
+ -----------
+
+ The OpenSSL Project is a collaborative effort to develop a robust,
+ commercial-grade, fully featured, and Open Source toolkit implementing the
+ Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1)
+ protocols as well as a full-strength general purpose cryptography library.
+ The project is managed by a worldwide community of volunteers that use the
+ Internet to communicate, plan, and develop the OpenSSL toolkit and its
+ related documentation.
+
+ OpenSSL is based on the excellent SSLeay library developed from Eric A. Young
+ and Tim J. Hudson.  The OpenSSL toolkit is licensed under a dual-license (the
+ OpenSSL license plus the SSLeay license) situation, which basically means
+ that you are free to get and use it for commercial and non-commercial
+ purposes as long as you fulfill the conditions of both licenses.
+
+ OVERVIEW
+ --------
+
+ The OpenSSL toolkit includes:
+
+ libssl.a:
+     Implementation of SSLv2, SSLv3, TLSv1 and the required code to support
+     both SSLv2, SSLv3 and TLSv1 in the one server and client.
+
+ libcrypto.a:
+     General encryption and X.509 v1/v3 stuff needed by SSL/TLS but not
+     actually logically part of it. It includes routines for the following:
+
+     Ciphers
+        libdes - EAY's libdes DES encryption package which was floating
+                 around the net for a few years, and was then relicensed by
+                 him as part of SSLeay.  It includes 15 'modes/variations'
+                 of DES (1, 2 and 3 key versions of ecb, cbc, cfb and ofb;
+                 pcbc and a more general form of cfb and ofb) including desx
+                 in cbc mode, a fast crypt(3), and routines to read
+                 passwords from the keyboard.
+        RC4 encryption,
+        RC2 encryption      - 4 different modes, ecb, cbc, cfb and ofb.
+        Blowfish encryption - 4 different modes, ecb, cbc, cfb and ofb.
+        IDEA encryption     - 4 different modes, ecb, cbc, cfb and ofb.
+
+     Digests
+        MD5 and MD2 message digest algorithms, fast implementations,
+        SHA (SHA-0) and SHA-1 message digest algorithms,
+        MDC2 message digest. A DES based hash that is popular on smart cards.
+
+     Public Key
+        RSA encryption/decryption/generation.
+            There is no limit on the number of bits.
+        DSA encryption/decryption/generation.
+            There is no limit on the number of bits.
+        Diffie-Hellman key-exchange/key generation.
+            There is no limit on the number of bits.
+
+     X.509v3 certificates
+        X509 encoding/decoding into/from binary ASN1 and a PEM
+             based ASCII-binary encoding which supports encryption with a
+             private key.  Program to generate RSA and DSA certificate
+             requests and to generate RSA and DSA certificates.
+
+     Systems
+        The normal digital envelope routines and base64 encoding.  Higher
+        level access to ciphers and digests by name.  New ciphers can be
+        loaded at run time.  The BIO io system which is a simple non-blocking
+        IO abstraction.  Current methods supported are file descriptors,
+        sockets, socket accept, socket connect, memory buffer, buffering, SSL
+        client/server, file pointer, encryption, digest, non-blocking testing
+        and null.
+
+     Data structures
+        A dynamically growing hashing system
+        A simple stack.
+        A Configuration loader that uses a format similar to MS .ini files.
+
+ openssl:
+     A command line tool that can be used for:
+        Creation of RSA, DH and DSA key parameters
+        Creation of X.509 certificates, CSRs and CRLs
+        Calculation of Message Digests
+        Encryption and Decryption with Ciphers
+        SSL/TLS Client and Server Tests
+        Handling of S/MIME signed or encrypted mail
+
+
+ PATENTS
+ -------
+
+ Various companies hold various patents for various algorithms in various
+ locations around the world. _YOU_ are responsible for ensuring that your use
+ of any algorithms is legal by checking if there are any patents in your
+ country.  The file contains some of the patents that we know about or are
+ rumored to exist. This is not a definitive list.
+
+ RSA Security holds software patents on the RC5 algorithm.  If you
+ intend to use this cipher, you must contact RSA Security for
+ licensing conditions. Their web page is http://www.rsasecurity.com/.
+
+ RC4 is a trademark of RSA Security, so use of this label should perhaps
+ only be used with RSA Security's permission.
+
+ The IDEA algorithm is patented by Ascom in Austria, France, Germany, Italy,
+ Japan, the Netherlands, Spain, Sweden, Switzerland, UK and the USA.  They
+ should be contacted if that algorithm is to be used; their web page is
+ http://www.ascom.ch/.
+
+ NTT and Mitsubishi have patents and pending patents on the Camellia
+ algorithm, but allow use at no charge without requiring an explicit
+ licensing agreement: http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
+
+ INSTALLATION
+ ------------
+
+ To install this package under a Unix derivative, read the INSTALL file.  For
+ a Win32 platform, read the INSTALL.W32 file.  For OpenVMS systems, read
+ INSTALL.VMS.
+
+ Read the documentation in the doc/ directory.  It is quite rough, but it
+ lists the functions; you will probably have to look at the code to work out
+ how to use them. Look at the example programs.
+
+ PROBLEMS
+ --------
+
+ For some platforms, there are some known problems that may affect the user
+ or application author.  We try to collect those in doc/PROBLEMS, with current
+ thoughts on how they should be solved in a future of OpenSSL.
+
+ SUPPORT
+ -------
+
+ See the OpenSSL website www.openssl.org for details of how to obtain
+ commercial technical support.
+
+ If you have any problems with OpenSSL then please take the following steps
+ first:
+
+    - Download the current snapshot from ftp://ftp.openssl.org/snapshot/
+      to see if the problem has already been addressed
+    - Remove ASM versions of libraries
+    - Remove compiler optimisation flags
+
+ If you wish to report a bug then please include the following information in
+ any bug report:
+
+    - On Unix systems:
+        Self-test report generated by 'make report'
+    - On other systems:
+        OpenSSL version: output of 'openssl version -a'
+        OS Name, Version, Hardware platform
+        Compiler Details (name, version)
+    - Application Details (name, version)
+    - Problem Description (steps that will reproduce the problem, if known)
+    - Stack Traceback (if the application dumps core)
+
+ Report the bug to the OpenSSL project via the Request Tracker
+ (http://www.openssl.org/support/rt.html) by mail to:
+
+    openssl-bugs@openssl.org
+
+ Note that the request tracker should NOT be used for general assistance
+ or support queries. Just because something doesn't work the way you expect
+ does not mean it is necessarily a bug in OpenSSL.
+
+ Note that mail to openssl-bugs@openssl.org is recorded in the publicly
+ readable request tracker database and is forwarded to a public
+ mailing list. Confidential mail may be sent to openssl-security@openssl.org
+ (PGP key available from the key servers).
+
+ HOW TO CONTRIBUTE TO OpenSSL
+ ----------------------------
+
+ Development is coordinated on the openssl-dev mailing list (see
+ http://www.openssl.org for information on subscribing). If you
+ would like to submit a patch, send it to openssl-bugs@openssl.org with
+ the string "[PATCH]" in the subject. Please be sure to include a
+ textual explanation of what your patch does.
+
+ If you are unsure as to whether a feature will be useful for the general
+ OpenSSL community please discuss it on the openssl-dev mailing list first.
+ Someone may be already working on the same thing or there may be a good
+ reason as to why that feature isn't implemented.
+
+ Patches should be as up to date as possible, preferably relative to the
+ current CVS or the last snapshot. They should follow the coding style of
+ OpenSSL and compile without warnings. Some of the core team developer targets
+ can be used for testing purposes, (debug-steve64, debug-geoff etc). OpenSSL
+ compiles on many varied platforms: try to ensure you only use portable
+ features.
+
+ Note: For legal reasons, contributions from the US can be accepted only
+ if a TSU notification and a copy of the patch are sent to crypt@bis.doc.gov
+ (formerly BXA) with a copy to the ENC Encryption Request Coordinator;
+ please take some time to look at
+    http://www.bis.doc.gov/Encryption/PubAvailEncSourceCodeNofify.html [sic]
+ and
+    http://w3.access.gpo.gov/bis/ear/pdf/740.pdf (EAR Section 740.13(e))
+ for the details. If "your encryption source code is too large to serve as
+ an email attachment", they are glad to receive it by fax instead; hope you
+ have a cheap long-distance plan.
+
+ Our preferred format for changes is "diff -u" output. You might
+ generate it like this:
+
+ # cd openssl-work
+ # [your changes]
+ # ./Configure dist; make clean
+ # cd ..
+ # diff -ur openssl-orig openssl-work > mydiffs.patch
+
diff --git a/openssl/README.ASN1 b/openssl/README.ASN1
new file mode 100644
index 0000000..11bcfaf
--- /dev/null
+++ b/openssl/README.ASN1
@@ -0,0 +1,187 @@
+
+OpenSSL ASN1 Revision
+=====================
+
+This document describes some of the issues relating to the new ASN1 code.
+
+Previous OpenSSL ASN1 problems
+=============================
+
+OK why did the OpenSSL ASN1 code need revising in the first place? Well
+there are lots of reasons some of which are included below...
+
+1. The code is difficult to read and write. For every single ASN1 structure
+(e.g. SEQUENCE) four functions need to be written for new, free, encode and
+decode operations. This is a very painful and error prone operation. Very few
+people have ever written any OpenSSL ASN1 and those that have usually wish
+they hadn't.
+
+2. Partly because of 1. the code is bloated and takes up a disproportionate
+amount of space. The SEQUENCE encoder is particularly bad: it essentially
+contains two copies of the same operation, one to compute the SEQUENCE length
+and the other to encode it.
+
+3. The code is memory based: that is it expects to be able to read the whole
+structure from memory. This is fine for small structures but if you have a
+(say) 1Gb PKCS#7 signedData structure it isn't such a good idea...
+
+4. The code for the ASN1 IMPLICIT tag is evil. It is handled by temporarily
+changing the tag to the expected one, attempting to read it, then changing it
+back again. This means that decode buffers have to be writable even though they
+are ultimately unchanged. This gets in the way of constification.
+
+5. The handling of EXPLICIT isn't much better. It adds a chunk of code into 
+the decoder and encoder for every EXPLICIT tag.
+
+6. APPLICATION and PRIVATE tags aren't even supported at all.
+
+7. Even IMPLICIT isn't complete: there is no support for implicitly tagged
+types that are not OPTIONAL.
+
+8. Much of the code assumes that a tag will fit in a single octet. This is
+only true if the tag is 30 or less (mercifully tags over 30 are rare).
+
+9. The ASN1 CHOICE type has to be largely handled manually, there aren't any
+macros that properly support it.
+
+10. Encoders have no concept of OPTIONAL and have no error checking. If the
+passed structure contains a NULL in a mandatory field it will not be encoded,
+resulting in an invalid structure.
+
+11. It is tricky to add ASN1 encoders and decoders to external applications.
+
+Template model
+==============
+
+One of the major problems with revision is the sheer volume of the ASN1 code.
+Attempts to change (for example) the IMPLICIT behaviour would result in a
+modification of *every* single decode function. 
+
+I decided to adopt a template based approach. I'm using the term 'template'
+in a manner similar to SNACC templates: it has nothing to do with C++
+templates.
+
+A template is a description of an ASN1 module as several constant C structures.
+It describes in a machine readable way exactly how the ASN1 structure should
+behave. If this template contains enough detail then it is possible to write
+versions of new, free, encode, decode (and possibly others operations) that
+operate on templates.
+
+Instead of having to write code to handle each operation only a single
+template needs to be written. If new operations are needed (such as a 'print'
+operation) only a single new template based function needs to be written 
+which will then automatically handle all existing templates.
+
+Plans for revision
+==================
+
+The revision will consist of the following steps. Other than the first two
+these can be handled in any order.
+ 
+o Design and write template new, free, encode and decode operations, initially
+memory based. *DONE*
+
+o Convert existing ASN1 code to template form. *IN PROGRESS*
+
+o Convert an existing ASN1 compiler (probably SNACC) to output templates
+in OpenSSL form.
+
+o Add support for BIO based ASN1 encoders and decoders to handle large
+structures, initially blocking I/O.
+
+o Add support for non blocking I/O: this is quite a bit harder than blocking
+I/O.
+
+o Add new ASN1 structures, such as OCSP, CRMF, S/MIME v3 (CMS), attribute
+certificates etc etc.
+
+Description of major changes
+============================
+
+The BOOLEAN type now takes three values. 0xff is TRUE, 0 is FALSE and -1 is
+absent. The meaning of absent depends on the context. If for example the
+boolean type is DEFAULT FALSE (as in the case of the critical flag for
+certificate extensions) then -1 is FALSE, if DEFAULT TRUE then -1 is TRUE.
+Usually the value will only ever be read via an API which will hide this from
+an application.
+
+There is an evil bug in the old ASN1 code that mishandles OPTIONAL with
+SEQUENCE OF or SET OF. These are both implemented as a STACK structure. The
+old code would omit the structure if the STACK was NULL (which is fine) or if
+it had zero elements (which is NOT OK). This causes problems because an empty
+SEQUENCE OF or SET OF will result in an empty STACK when it is decoded but when
+it is encoded it will be omitted resulting in different encodings. The new code
+only omits the encoding if the STACK is NULL, if it contains zero elements it
+is encoded and empty. There is an additional problem though: because an empty
+STACK was omitted, sometimes the corresponding *_new() function would
+initialize the STACK to empty so an application could immediately use it, if
+this is done with the new code (i.e. a NULL) it wont work. Therefore a new
+STACK should be allocated first. One instance of this is the X509_CRL list of
+revoked certificates: a helper function X509_CRL_add0_revoked() has been added
+for this purpose.
+
+The X509_ATTRIBUTE structure used to have an element called 'set' which took
+the value 1 if the attribute value was a SET OF or 0 if it was a single. Due
+to the behaviour of CHOICE in the new code this has been changed to a field
+called 'single' which is 0 for a SET OF and 1 for single. The old field has
+been deleted to deliberately break source compatibility. Since this structure
+is normally accessed via higher level functions this shouldn't break too much.
+
+The X509_REQ_INFO certificate request info structure no longer has a field
+called 'req_kludge'. This used to be set to 1 if the attributes field was
+(incorrectly) omitted. You can check to see if the field is omitted now by
+checking if the attributes field is NULL. Similarly if you need to omit
+the field then free attributes and set it to NULL.
+
+The top level 'detached' field in the PKCS7 structure is no longer set when
+a PKCS#7 structure is read in. PKCS7_is_detached() should be called instead.
+The behaviour of PKCS7_get_detached() is unaffected.
+
+The values of 'type' in the GENERAL_NAME structure have changed. This is
+because the old code use the ASN1 initial octet as the selector. The new
+code uses the index in the ASN1_CHOICE template.
+
+The DIST_POINT_NAME structure has changed to be a true CHOICE type.
+
+typedef struct DIST_POINT_NAME_st {
+int type;
+union {
+	STACK_OF(GENERAL_NAME) *fullname;
+	STACK_OF(X509_NAME_ENTRY) *relativename;
+} name;
+} DIST_POINT_NAME;
+
+This means that name.fullname or name.relativename should be set
+and type reflects the option. That is if name.fullname is set then
+type is 0 and if name.relativename is set type is 1.
+
+With the old code using the i2d functions would typically involve:
+
+unsigned char *buf, *p;
+int len;
+/* Find length of encoding */
+len = i2d_SOMETHING(x, NULL);
+/* Allocate buffer */
+buf = OPENSSL_malloc(len);
+if(buf == NULL) {
+	/* Malloc error */
+}
+/* Use temp variable because &p gets updated to point to end of
+ * encoding.
+ */
+p = buf;
+i2d_SOMETHING(x, &p);
+
+
+Using the new i2d you can also do:
+
+unsigned char *buf = NULL;
+int len;
+len = i2d_SOMETHING(x, &buf);
+if(len < 0) {
+	/* Malloc error */
+}
+
+and it will automatically allocate and populate a buffer with the
+encoding. After this call 'buf' will point to the start of the
+encoding which is len bytes long.
diff --git a/openssl/README.ENGINE b/openssl/README.ENGINE
new file mode 100644
index 0000000..0ff8333
--- /dev/null
+++ b/openssl/README.ENGINE
@@ -0,0 +1,289 @@
+  ENGINE
+  ======
+
+  With OpenSSL 0.9.6, a new component was added to support alternative
+  cryptography implementations, most commonly for interfacing with external
+  crypto devices (eg. accelerator cards). This component is called ENGINE,
+  and its presence in OpenSSL 0.9.6 (and subsequent bug-fix releases)
+  caused a little confusion as 0.9.6** releases were rolled in two
+  versions, a "standard" and an "engine" version. In development for 0.9.7,
+  the ENGINE code has been merged into the main branch and will be present
+  in the standard releases from 0.9.7 forwards.
+
+  There are currently built-in ENGINE implementations for the following
+  crypto devices:
+
+      o CryptoSwift
+      o Compaq Atalla
+      o nCipher CHIL
+      o Nuron
+      o Broadcom uBSec
+
+  In addition, dynamic binding to external ENGINE implementations is now
+  provided by a special ENGINE called "dynamic". See the "DYNAMIC ENGINE"
+  section below for details.
+
+  At this stage, a number of things are still needed and are being worked on:
+
+      1 Integration of EVP support.
+      2 Configuration support.
+      3 Documentation!
+
+1 With respect to EVP, this relates to support for ciphers and digests in
+  the ENGINE model so that alternative implementations of existing
+  algorithms/modes (or previously unimplemented ones) can be provided by
+  ENGINE implementations.
+
+2 Configuration support currently exists in the ENGINE API itself, in the
+  form of "control commands". These allow an application to expose to the
+  user/admin the set of commands and parameter types a given ENGINE
+  implementation supports, and for an application to directly feed string
+  based input to those ENGINEs, in the form of name-value pairs. This is an
+  extensible way for ENGINEs to define their own "configuration" mechanisms
+  that are specific to a given ENGINE (eg. for a particular hardware
+  device) but that should be consistent across *all* OpenSSL-based
+  applications when they use that ENGINE. Work is in progress (or at least
+  in planning) for supporting these control commands from the CONF (or
+  NCONF) code so that applications using OpenSSL's existing configuration
+  file format can have ENGINE settings specified in much the same way.
+  Presently however, applications must use the ENGINE API itself to provide
+  such functionality. To see first hand the types of commands available
+  with the various compiled-in ENGINEs (see further down for dynamic
+  ENGINEs), use the "engine" openssl utility with full verbosity, ie;
+       openssl engine -vvvv
+
+3 Documentation? Volunteers welcome! The source code is reasonably well
+  self-documenting, but some summaries and usage instructions are needed -
+  moreover, they are needed in the same POD format the existing OpenSSL
+  documentation is provided in. Any complete or incomplete contributions
+  would help make this happen.
+
+  STABILITY & BUG-REPORTS
+  =======================
+
+  What already exists is fairly stable as far as it has been tested, but
+  the test base has been a bit small most of the time. For the most part,
+  the vendors of the devices these ENGINEs support have contributed to the
+  development and/or testing of the implementations, and *usually* (with no
+  guarantees) have experience in using the ENGINE support to drive their
+  devices from common OpenSSL-based applications. Bugs and/or inexplicable
+  behaviour in using a specific ENGINE implementation should be sent to the
+  author of that implementation (if it is mentioned in the corresponding C
+  file), and in the case of implementations for commercial hardware
+  devices, also through whatever vendor support channels are available.  If
+  none of this is possible, or the problem seems to be something about the
+  ENGINE API itself (ie. not necessarily specific to a particular ENGINE
+  implementation) then you should mail complete details to the relevant
+  OpenSSL mailing list. For a definition of "complete details", refer to
+  the OpenSSL "README" file. As for which list to send it to;
+
+     openssl-users: if you are *using* the ENGINE abstraction, either in an
+          pre-compiled application or in your own application code.
+
+     openssl-dev: if you are discussing problems with OpenSSL source code.
+
+  USAGE
+  =====
+
+  The default "openssl" ENGINE is always chosen when performing crypto
+  operations unless you specify otherwise. You must actively tell the
+  openssl utility commands to use anything else through a new command line
+  switch called "-engine". Also, if you want to use the ENGINE support in
+  your own code to do something similar, you must likewise explicitly
+  select the ENGINE implementation you want.
+
+  Depending on the type of hardware, system, and configuration, "settings"
+  may need to be applied to an ENGINE for it to function as expected/hoped.
+  The recommended way of doing this is for the application to support
+  ENGINE "control commands" so that each ENGINE implementation can provide
+  whatever configuration primitives it might require and the application
+  can allow the user/admin (and thus the hardware vendor's support desk
+  also) to provide any such input directly to the ENGINE implementation.
+  This way, applications do not need to know anything specific to any
+  device, they only need to provide the means to carry such user/admin
+  input through to the ENGINE in question. Ie. this connects *you* (and
+  your helpdesk) to the specific ENGINE implementation (and device), and
+  allows application authors to not get buried in hassle supporting
+  arbitrary devices they know (and care) nothing about.
+
+  A new "openssl" utility, "openssl engine", has been added in that allows
+  for testing and examination of ENGINE implementations. Basic usage
+  instructions are available by specifying the "-?" command line switch.
+
+  DYNAMIC ENGINES
+  ===============
+
+  The new "dynamic" ENGINE provides a low-overhead way to support ENGINE
+  implementations that aren't pre-compiled and linked into OpenSSL-based
+  applications. This could be because existing compiled-in implementations
+  have known problems and you wish to use a newer version with an existing
+  application. It could equally be because the application (or OpenSSL
+  library) you are using simply doesn't have support for the ENGINE you
+  wish to use, and the ENGINE provider (eg. hardware vendor) is providing
+  you with a self-contained implementation in the form of a shared-library.
+  The other use-case for "dynamic" is with applications that wish to
+  maintain the smallest foot-print possible and so do not link in various
+  ENGINE implementations from OpenSSL, but instead leaves you to provide
+  them, if you want them, in the form of "dynamic"-loadable
+  shared-libraries. It should be possible for hardware vendors to provide
+  their own shared-libraries to support arbitrary hardware to work with
+  applications based on OpenSSL 0.9.7 or later. If you're using an
+  application based on 0.9.7 (or later) and the support you desire is only
+  announced for versions later than the one you need, ask the vendor to
+  backport their ENGINE to the version you need.
+
+  How does "dynamic" work?
+  ------------------------
+    The dynamic ENGINE has a special flag in its implementation such that
+    every time application code asks for the 'dynamic' ENGINE, it in fact
+    gets its own copy of it. As such, multi-threaded code (or code that
+    multiplexes multiple uses of 'dynamic' in a single application in any
+    way at all) does not get confused by 'dynamic' being used to do many
+    independent things. Other ENGINEs typically don't do this so there is
+    only ever 1 ENGINE structure of its type (and reference counts are used
+    to keep order). The dynamic ENGINE itself provides absolutely no
+    cryptographic functionality, and any attempt to "initialise" the ENGINE
+    automatically fails. All it does provide are a few "control commands"
+    that can be used to control how it will load an external ENGINE
+    implementation from a shared-library. To see these control commands,
+    use the command-line;
+
+       openssl engine -vvvv dynamic
+
+    The "SO_PATH" control command should be used to identify the
+    shared-library that contains the ENGINE implementation, and "NO_VCHECK"
+    might possibly be useful if there is a minor version conflict and you
+    (or a vendor helpdesk) is convinced you can safely ignore it.
+    "ID" is probably only needed if a shared-library implements
+    multiple ENGINEs, but if you know the engine id you expect to be using,
+    it doesn't hurt to specify it (and this provides a sanity check if
+    nothing else). "LIST_ADD" is only required if you actually wish the
+    loaded ENGINE to be discoverable by application code later on using the
+    ENGINE's "id". For most applications, this isn't necessary - but some
+    application authors may have nifty reasons for using it. The "LOAD"
+    command is the only one that takes no parameters and is the command
+    that uses the settings from any previous commands to actually *load*
+    the shared-library ENGINE implementation. If this command succeeds, the
+    (copy of the) 'dynamic' ENGINE will magically morph into the ENGINE
+    that has been loaded from the shared-library. As such, any control
+    commands supported by the loaded ENGINE could then be executed as per
+    normal. Eg. if ENGINE "foo" is implemented in the shared-library
+    "libfoo.so" and it supports some special control command "CMD_FOO", the
+    following code would load and use it (NB: obviously this code has no
+    error checking);
+
+       ENGINE *e = ENGINE_by_id("dynamic");
+       ENGINE_ctrl_cmd_string(e, "SO_PATH", "/lib/libfoo.so", 0);
+       ENGINE_ctrl_cmd_string(e, "ID", "foo", 0);
+       ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0);
+       ENGINE_ctrl_cmd_string(e, "CMD_FOO", "some input data", 0);
+
+    For testing, the "openssl engine" utility can be useful for this sort
+    of thing. For example the above code excerpt would achieve much the
+    same result as;
+
+       openssl engine dynamic \
+                 -pre SO_PATH:/lib/libfoo.so \
+                 -pre ID:foo \
+                 -pre LOAD \
+                 -pre "CMD_FOO:some input data"
+
+    Or to simply see the list of commands supported by the "foo" ENGINE;
+
+       openssl engine -vvvv dynamic \
+                 -pre SO_PATH:/lib/libfoo.so \
+                 -pre ID:foo \
+                 -pre LOAD
+
+    Applications that support the ENGINE API and more specifically, the
+    "control commands" mechanism, will provide some way for you to pass
+    such commands through to ENGINEs. As such, you would select "dynamic"
+    as the ENGINE to use, and the parameters/commands you pass would
+    control the *actual* ENGINE used. Each command is actually a name-value
+    pair and the value can sometimes be omitted (eg. the "LOAD" command).
+    Whilst the syntax demonstrated in "openssl engine" uses a colon to
+    separate the command name from the value, applications may provide
+    their own syntax for making that separation (eg. a win32 registry
+    key-value pair may be used by some applications). The reason for the
+    "-pre" syntax in the "openssl engine" utility is that some commands
+    might be issued to an ENGINE *after* it has been initialised for use.
+    Eg. if an ENGINE implementation requires a smart-card to be inserted
+    during initialisation (or a PIN to be typed, or whatever), there may be
+    a control command you can issue afterwards to "forget" the smart-card
+    so that additional initialisation is no longer possible. In
+    applications such as web-servers, where potentially volatile code may
+    run on the same host system, this may provide some arguable security
+    value. In such a case, the command would be passed to the ENGINE after
+    it has been initialised for use, and so the "-post" switch would be
+    used instead. Applications may provide a different syntax for
+    supporting this distinction, and some may simply not provide it at all
+    ("-pre" is almost always what you're after, in reality).
+
+  How do I build a "dynamic" ENGINE?
+  ----------------------------------
+    This question is trickier - currently OpenSSL bundles various ENGINE
+    implementations that are statically built in, and any application that
+    calls the "ENGINE_load_builtin_engines()" function will automatically
+    have all such ENGINEs available (and occupying memory). Applications
+    that don't call that function have no ENGINEs available like that and
+    would have to use "dynamic" to load any such ENGINE - but on the other
+    hand such applications would only have the memory footprint of any
+    ENGINEs explicitly loaded using user/admin provided control commands.
+    The main advantage of not statically linking ENGINEs and only using
+    "dynamic" for hardware support is that any installation using no
+    "external" ENGINE suffers no unnecessary memory footprint from unused
+    ENGINEs. Likewise, installations that do require an ENGINE incur the
+    overheads from only *that* ENGINE once it has been loaded.
+
+    Sounds good? Maybe, but currently building an ENGINE implementation as
+    a shared-library that can be loaded by "dynamic" isn't automated in
+    OpenSSL's build process. It can be done manually quite easily however.
+    Such a shared-library can either be built with any OpenSSL code it
+    needs statically linked in, or it can link dynamically against OpenSSL
+    if OpenSSL itself is built as a shared library. The instructions are
+    the same in each case, but in the former (statically linked any
+    dependencies on OpenSSL) you must ensure OpenSSL is built with
+    position-independent code ("PIC"). The default OpenSSL compilation may
+    already specify the relevant flags to do this, but you should consult
+    with your compiler documentation if you are in any doubt.
+
+    This example will show building the "atalla" ENGINE in the
+    crypto/engine/ directory as a shared-library for use via the "dynamic"
+    ENGINE.
+    1) "cd" to the crypto/engine/ directory of a pre-compiled OpenSSL
+       source tree.
+    2) Recompile at least one source file so you can see all the compiler
+       flags (and syntax) being used to build normally. Eg;
+           touch hw_atalla.c ; make
+       will rebuild "hw_atalla.o" using all such flags.
+    3) Manually enter the same compilation line to compile the
+       "hw_atalla.c" file but with the following two changes;
+         (a) add "-DENGINE_DYNAMIC_SUPPORT" to the command line switches,
+	 (b) change the output file from "hw_atalla.o" to something new,
+             eg. "tmp_atalla.o"
+    4) Link "tmp_atalla.o" into a shared-library using the top-level
+       OpenSSL libraries to resolve any dependencies. The syntax for doing
+       this depends heavily on your system/compiler and is a nightmare
+       known well to anyone who has worked with shared-library portability
+       before. 'gcc' on Linux, for example, would use the following syntax;
+          gcc -shared -o dyn_atalla.so tmp_atalla.o -L../.. -lcrypto
+    5) Test your shared library using "openssl engine" as explained in the
+       previous section. Eg. from the top-level directory, you might try;
+          apps/openssl engine -vvvv dynamic \
+              -pre SO_PATH:./crypto/engine/dyn_atalla.so -pre LOAD
+       If the shared-library loads successfully, you will see both "-pre"
+       commands marked as "SUCCESS" and the list of control commands
+       displayed (because of "-vvvv") will be the control commands for the
+       *atalla* ENGINE (ie. *not* the 'dynamic' ENGINE). You can also add
+       the "-t" switch to the utility if you want it to try and initialise
+       the atalla ENGINE for use to test any possible hardware/driver
+       issues.
+
+  PROBLEMS
+  ========
+
+  It seems like the ENGINE part doesn't work too well with CryptoSwift on Win32.
+  A quick test done right before the release showed that trying "openssl speed
+  -engine cswift" generated errors. If the DSO gets enabled, an attempt is made
+  to write at memory address 0x00000002.
+
diff --git a/openssl/VMS/TODO b/openssl/VMS/TODO
new file mode 100644
index 0000000..359e069
--- /dev/null
+++ b/openssl/VMS/TODO
@@ -0,0 +1,18 @@
+TODO:
+=====
+
+There are a few things that need to be worked out in the VMS version of
+OpenSSL, still:
+
+- Description files. ("Makefile's" :-))
+- Script code to link an already compiled build tree.
+- A VMSINSTALlable version (way in the future, unless someone else hacks).
+- shareable images (DLL for you Windows folks).
+
+There may be other things that I have missed and that may be desirable.
+Please send mail to <openssl-users@openssl.org> or to me directly if you
+have any ideas.
+
+--
+Richard Levitte <richard@levitte.org>
+1999-05-24
diff --git a/openssl/VMS/VMSify-conf.pl b/openssl/VMS/VMSify-conf.pl
new file mode 100644
index 0000000..d3be6a2
--- /dev/null
+++ b/openssl/VMS/VMSify-conf.pl
@@ -0,0 +1,34 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+
+my @directory_vars = ( "dir", "certs", "crl_dir", "new_certs_dir" );
+my @file_vars = ( "database", "certificate", "serial", "crlnumber",
+		  "crl", "private_key", "RANDFILE" );
+while(<STDIN>) {
+    chomp;
+    foreach my $d (@directory_vars) {
+	if (/^(\s*\#?\s*${d}\s*=\s*)\.\/([^\s\#]*)([\s\#].*)$/) {
+	    $_ = "$1sys\\\$disk:\[.$2$3";
+	} elsif (/^(\s*\#?\s*${d}\s*=\s*)(\w[^\s\#]*)([\s\#].*)$/) {
+	    $_ = "$1sys\\\$disk:\[.$2$3";
+	}
+	s/^(\s*\#?\s*${d}\s*=\s*\$\w+)\/([^\s\#]*)([\s\#].*)$/$1.$2\]$3/;
+	while(/^(\s*\#?\s*${d}\s*=\s*(\$\w+\.|sys\\\$disk:\[\.)[\w\.]+)\/([^\]]*)\](.*)$/) {
+	    $_ = "$1.$3]$4";
+	}
+    }
+    foreach my $f (@file_vars) {
+	s/^(\s*\#?\s*${f}\s*=\s*)\.\/(.*)$/$1sys\\\$disk:\[\/$2/;
+	while(/^(\s*\#?\s*${f}\s*=\s*(\$\w+|sys\\\$disk:\[)[^\/]*)\/(\w+\/[^\s\#]*)([\s\#].*)$/) {
+	    $_ = "$1.$3$4";
+	}
+	if (/^(\s*\#?\s*${f}\s*=\s*(\$\w+|sys\\\$disk:\[)[^\/]*)\/(\w+)([\s\#].*)$/) {
+	    $_ = "$1]$3.$4";
+	} elsif  (/^(\s*\#?\s*${f}\s*=\s*(\$\w+|sys\\\$disk:\[)[^\/]*)\/([^\s\#]*)([\s\#].*)$/) {
+	    $_ = "$1]$3$4";
+	}
+   }
+    print $_,"\n";
+}
diff --git a/openssl/VMS/WISHLIST.TXT b/openssl/VMS/WISHLIST.TXT
new file mode 100644
index 0000000..c151fc8
--- /dev/null
+++ b/openssl/VMS/WISHLIST.TXT
@@ -0,0 +1,4 @@
+* Have the building procedure contain a LINK-only possibility.
+  Wished by Mark Daniel <mark.daniel@dsto.defence.gov.au>
+
+  One way to enable that is also to go over to DESCRIP.MMS files.
diff --git a/openssl/VMS/install-vms.com b/openssl/VMS/install-vms.com
new file mode 100644
index 0000000..7da8b21
--- /dev/null
+++ b/openssl/VMS/install-vms.com
@@ -0,0 +1,67 @@
+$! install-vms.com -- Installs the files in a given directory tree
+$!
+$! Author: Richard Levitte <richard@levitte.org>
+$! Time of creation: 23-MAY-1998 19:22
+$!
+$! P1	root of the directory tree
+$!
+$!
+$! Announce/identify.
+$!
+$ proc = f$environment( "procedure")
+$ write sys$output "@@@ "+ -
+   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
+$!
+$ on error then goto tidy
+$ on control_c then goto tidy
+$!
+$ if p1 .eqs. ""
+$ then
+$   write sys$output "First argument missing."
+$   write sys$output -
+     "Should be the directory where you want things installed."
+$   exit
+$ endif
+$
+$ if (f$getsyi( "cpu") .lt. 128)
+$ then
+$   arch = "VAX"
+$ else
+$   arch = f$edit( f$getsyi( "arch_name"), "upcase")
+$   if (arch .eqs. "") then arch = "UNK"
+$ endif
+$
+$ root = f$parse( P1, "[]A.;0", , , "SYNTAX_ONLY, NO_CONCEAL")- "A.;0"
+$ root_dev = f$parse( root, , , "device", "syntax_only")
+$ root_dir = f$parse( root, , , "directory", "syntax_only") - -
+   "[000000." - "][" - "[" - "]"
+$ root = root_dev + "[" + root_dir
+$
+$ define /nolog wrk_sslroot 'root'.] /translation_attributes = concealed
+$ define /nolog wrk_sslinclude wrk_sslroot:[include]
+$
+$ if f$parse( "wrk_sslroot:[000000]") .eqs. "" then -
+   create /directory /log wrk_sslroot:[000000]
+$ if f$parse( "wrk_sslinclude:") .eqs. "" then -
+   create /directory /log wrk_sslinclude:
+$ if f$parse( "wrk_sslroot:[vms]") .eqs. "" then -
+   create /directory /log wrk_sslroot:[vms]
+$!
+$ copy /log /protection = world:re openssl_startup.com wrk_sslroot:[vms]
+$ copy /log /protection = world:re openssl_undo.com wrk_sslroot:[vms]
+$ copy /log /protection = world:re openssl_utils.com wrk_sslroot:[vms]
+$!
+$ tidy:
+$!
+$ call deass wrk_sslroot
+$ call deass wrk_sslinclude
+$!
+$ exit
+$!
+$ deass: subroutine
+$ if (f$trnlnm( p1, "LNM$PROCESS") .nes. "")
+$ then
+$   deassign /process 'p1'
+$ endif
+$ endsubroutine
+$!
diff --git a/openssl/VMS/mkshared.com b/openssl/VMS/mkshared.com
new file mode 100644
index 0000000..b0d1fda
--- /dev/null
+++ b/openssl/VMS/mkshared.com
@@ -0,0 +1,476 @@
+$! MKSHARED.COM -- Create shareable images.
+$!
+$! P1: "64" for 64-bit pointers.
+$!
+$! P2: Zlib object library path (optional).
+$!
+$! Input:	[.UTIL]LIBEAY.NUM,[.xxx.EXE.CRYPTO]SSL_LIBCRYPTO[32].OLB
+$!		[.UTIL]SSLEAY.NUM,[.xxx.EXE.SSL]SSL_LIBSSL[32].OLB
+$!		[.CRYPTO.xxx]OPENSSLCONF.H
+$! Output:	[.xxx.EXE.CRYPTO]SSL_LIBCRYPTO_SHR[32].OPT,.MAP,.EXE
+$!		[.xxx.EXE.SSL]SSL_LIBSSL_SRH[32].OPT,.MAP,.EXE
+$!
+$! So far, tests have only been made on VMS for Alpha.  VAX will come in time.
+$! ===========================================================================
+$!
+$! Announce/identify.
+$!
+$ proc = f$environment( "procedure")
+$ write sys$output "@@@ "+ -
+   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
+$!
+$! Save the original default device:[directory].
+$!
+$ def_orig = f$environment( "default")
+$ on error then goto tidy
+$ on control_c then goto tidy
+$!
+$! SET DEFAULT to the main kit directory.
+$!
+$ proc = f$environment("procedure")
+$ proc = f$parse( "A.;", proc)- "A.;"
+$ set default 'proc'
+$ set default [-]
+$!
+$! ----- Prepare info for processing: version number and file info
+$ gosub read_version_info
+$ if libver .eqs. ""
+$ then
+$   write sys$error "ERROR: Couldn't find any library version info..."
+$   go to tidy:
+$ endif
+$
+$ if (f$getsyi("cpu") .lt. 128)
+$ then
+$   arch_vax = 1
+$   arch = "VAX"
+$ else
+$   arch_vax = 0
+$   arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$   if (arch .eqs. "") then arch = "UNK"
+$ endif
+$!
+$ archd = arch
+$ lib32 = "32"
+$ shr = "SHR32"
+$!
+$ if (p1 .nes. "")
+$ then
+$   if (p1 .eqs. "64")
+$   then
+$     archd = arch+ "_64"
+$     lib32 = ""
+$     shr = "SHR"
+$   else
+$     if (p1 .nes. "32")
+$     then
+$       write sys$output "Second argument invalid."
+$       write sys$output "It should be "32", "64", or nothing."
+$       exit
+$     endif
+$   endif
+$ endif
+$!
+$! ----- Prepare info for processing: disabled algorithms info
+$ gosub read_disabled_algorithms_info
+$!
+$ ZLIB = p2
+$ zlib_lib = ""
+$ if (ZLIB .nes. "")
+$ then
+$   file2 = f$parse( ZLIB, "libz.olb", , , "syntax_only")
+$   if (f$search( file2) .eqs. "")
+$   then
+$     write sys$output ""
+$     write sys$output "The Option ", ZLIB, " Is Invalid."
+$     write sys$output "    Can't find library: ''file2'"
+$     write sys$output ""
+$     goto tidy
+$   endif
+$   zlib_lib = ", ''file2' /library"
+$ endif
+$!
+$ if (arch_vax)
+$ then
+$   libtit = "CRYPTO_TRANSFER_VECTOR"
+$   libid  = "Crypto"
+$   libnum = "[.UTIL]LIBEAY.NUM"
+$   libdir = "[.''ARCHD'.EXE.CRYPTO]"
+$   libmar = "''libdir'SSL_LIBCRYPTO_''shr'.MAR"
+$   libolb = "''libdir'SSL_LIBCRYPTO''lib32'.OLB"
+$   libopt = "''libdir'SSL_LIBCRYPTO_''shr'.OPT"
+$   libobj = "''libdir'SSL_LIBCRYPTO_''shr'.OBJ"
+$   libmap = "''libdir'SSL_LIBCRYPTO_''shr'.MAP"
+$   libgoal= "''libdir'SSL_LIBCRYPTO_''shr'.EXE"
+$   libref = ""
+$   libvec = "LIBCRYPTO"
+$   if f$search( libolb) .nes. "" then gosub create_vax_shr
+$   libtit = "SSL_TRANSFER_VECTOR"
+$   libid  = "SSL"
+$   libnum = "[.UTIL]SSLEAY.NUM"
+$   libdir = "[.''ARCHD'.EXE.SSL]"
+$   libmar = "''libdir'SSL_LIBSSL_''shr'.MAR"
+$   libolb = "''libdir'SSL_LIBSSL''lib32'.OLB"
+$   libopt = "''libdir'SSL_LIBSSL_''shr'.OPT"
+$   libobj = "''libdir'SSL_LIBSSL_''shr'.OBJ"
+$   libmap = "''libdir'SSL_LIBSSL_''shr'.MAP"
+$   libgoal= "''libdir'SSL_LIBSSL_''shr'.EXE"
+$   libref = "[.''ARCHD'.EXE.CRYPTO]SSL_LIBCRYPTO_''shr'.EXE"
+$   libvec = "LIBSSL"
+$   if f$search( libolb) .nes. "" then gosub create_vax_shr
+$ else
+$   libid  = "Crypto"
+$   libnum = "[.UTIL]LIBEAY.NUM"
+$   libdir = "[.''ARCHD'.EXE.CRYPTO]"
+$   libolb = "''libdir'SSL_LIBCRYPTO''lib32'.OLB"
+$   libopt = "''libdir'SSL_LIBCRYPTO_''shr'.OPT"
+$   libmap = "''libdir'SSL_LIBCRYPTO_''shr'.MAP"
+$   libgoal= "''libdir'SSL_LIBCRYPTO_''shr'.EXE"
+$   libref = ""
+$   if f$search( libolb) .nes. "" then gosub create_nonvax_shr
+$   libid  = "SSL"
+$   libnum = "[.UTIL]SSLEAY.NUM"
+$   libdir = "[.''ARCHD'.EXE.SSL]"
+$   libolb = "''libdir'SSL_LIBSSL''lib32'.OLB"
+$   libopt = "''libdir'SSL_LIBSSL_''shr'.OPT"
+$   libmap = "''libdir'SSL_LIBSSL_''shr'.MAP"
+$   libgoal= "''libdir'SSL_LIBSSL_''shr'.EXE"
+$   libref = "[.''ARCHD'.EXE.CRYPTO]SSL_LIBCRYPTO_''shr'.EXE"
+$   if f$search( libolb) .nes. "" then gosub create_nonvax_shr
+$ endif
+$!
+$ tidy:
+$!
+$! Close any open files.
+$!
+$ if (f$trnlnm( "libnum", "LNM$PROCESS", 0, "SUPERVISOR") .nes. "") then -
+   close libnum
+$!
+$ if (f$trnlnm( "mar", "LNM$PROCESS", 0, "SUPERVISOR") .nes. "") then -
+   close mar
+$!
+$ if (f$trnlnm( "opt", "LNM$PROCESS", 0, "SUPERVISOR") .nes. "") then -
+   close opt
+$!
+$ if (f$trnlnm( "vf", "LNM$PROCESS", 0, "SUPERVISOR") .nes. "") then -
+   close vf
+$!
+$! Restore the original default device:[directory].
+$!
+$ set default 'def_orig'
+$ exit
+$
+$! ----- Subroutines to build the shareable libraries
+$! For each supported architecture, there's a main shareable library
+$! creator, which is called from the main code above.
+$! The creator will define a number of variables to tell the next levels of
+$! subroutines what routines to use to write to the option files, call the
+$! main processor, read_func_num, and when that is done, it will write version
+$! data at the end of the .opt file, close it, and link the library.
+$!
+$! read_func_num reads through a .num file and calls the writer routine for
+$! each line.  It's also responsible for checking that order is properly kept
+$! in the .num file, check that each line applies to VMS and the architecture,
+$! and to fill in "holes" with dummy entries.
+$!
+$! The creator routines depend on the following variables:
+$! libnum	The name of the .num file to use as input
+$! libolb	The name of the object library to build from
+$! libid	The identification string of the shareable library
+$! libopt	The name of the .opt file to write
+$! libtit	The title of the assembler transfer vector file (VAX only)
+$! libmar	The name of the assembler transfer vector file (VAX only)
+$! libmap	The name of the map file to write
+$! libgoal	The name of the shareable library to write
+$! libref	The name of a shareable library to link in
+$!
+$! read_func_num depends on the following variables from the creator:
+$! libwriter	The name of the writer routine to call for each .num file line
+$! -----
+$
+$! ----- Subroutines for non-VAX
+$! -----
+$! The creator routine
+$ create_nonvax_shr:
+$   open /write opt 'libopt'
+$   write opt "identification=""",libid," ",libverstr,""""
+$   write opt libolb, " /library"
+$   if libref .nes. "" then write opt libref,"/SHARE"
+$   write opt "SYMBOL_VECTOR=(-"
+$   libfirstentry := true
+$   libwrch   := opt
+$   libwriter := write_nonvax_transfer_entry
+$   textcount = 0
+$   gosub read_func_num
+$   write opt ")"
+$   write opt "GSMATCH=",libvmatch,",",libver
+$   close opt
+$   link /map = 'libmap' /full /share = 'libgoal' 'libopt' /options -
+     'zlib_lib'
+$   return
+$
+$! The record writer routine
+$ write_nonvax_transfer_entry:
+$   if libentry .eqs. ".dummy" then return
+$   if info_kind .eqs. "VARIABLE"
+$   then
+$     pr:=DATA
+$   else
+$     pr:=PROCEDURE
+$   endif
+$   textcount_this = f$length(pr) + f$length(libentry) + 5
+$   if textcount + textcount_this .gt. 1024
+$   then
+$     write opt ")"
+$     write opt "SYMBOL_VECTOR=(-"
+$     textcount = 16
+$     libfirstentry := true
+$   endif
+$   if libfirstentry
+$   then
+$     write 'libwrch' "    ",libentry,"=",pr," -"
+$   else
+$     write 'libwrch' "    ,",libentry,"=",pr," -"
+$   endif
+$   libfirstentry := false
+$   textcount = textcount + textcount_this
+$   return
+$
+$! ----- Subroutines for VAX
+$! -----
+$! The creator routine
+$ create_vax_shr:
+$   open /write mar 'libmar'
+$   type sys$input:/out=mar:
+;
+; Transfer vector for VAX shareable image
+;
+$   write mar "	.TITLE ",libtit
+$   write mar "	.IDENT /",libid,"/"
+$   type sys$input:/out=mar:
+;
+; Define macro to assist in building transfer vector entries.  Each entry
+; should take no more than 8 bytes.
+;
+	.MACRO FTRANSFER_ENTRY routine
+	.ALIGN QUAD
+	.TRANSFER routine
+	.MASK	routine
+	JMP	routine+2
+	.ENDM FTRANSFER_ENTRY
+;
+; Place entries in own program section.
+;
+$   write mar "	.PSECT $$",libvec,",QUAD,PIC,USR,CON,REL,LCL,SHR,EXE,RD,NOWRT"
+$   write mar libvec,"_xfer:"
+$   libwrch   := mar
+$   libwriter := write_vax_ftransfer_entry
+$   gosub read_func_num
+$   type sys$input:/out=mar:
+;
+; Allocate extra storage at end of vector to allow for expansion.
+;
+$   write mar "	.BLKB 32768-<.-",libvec,"_xfer>	; 64 pages total."
+$!   libwriter := write_vax_vtransfer_entry
+$!   gosub read_func_num
+$   write mar "	.END"
+$   close mar
+$   open /write opt 'libopt'
+$   write opt "identification=""",libid," ",libverstr,""""
+$   write opt libobj
+$   write opt libolb, " /library"
+$   if libref .nes. "" then write opt libref,"/SHARE"
+$   type sys$input:/out=opt:
+!
+! Ensure transfer vector is at beginning of image
+!
+CLUSTER=FIRST
+$   write opt "COLLECT=FIRST,$$",libvec
+$   write opt "GSMATCH=",libvmatch,",",libver
+$   type sys$input:/out=opt:
+!
+! make psects nonshareable so image can be installed.
+!
+PSECT_ATTR=$CHAR_STRING_CONSTANTS,NOWRT
+$   libwrch   := opt
+$   libwriter := write_vax_psect_attr
+$   gosub read_func_num
+$   close opt
+$   macro/obj='libobj' 'libmar'
+$   link /map = 'libmap' /full /share = 'libgoal' 'libopt' /options -
+     'zlib_lib'
+$   return
+$
+$! The record writer routine for VAX functions
+$ write_vax_ftransfer_entry:
+$   if info_kind .nes. "FUNCTION" then return
+$   if libentry .eqs ".dummy"
+$   then
+$     write 'libwrch' "	.BLKB 8" ! Dummy is zeroes...
+$   else
+$     write 'libwrch' "	FTRANSFER_ENTRY ",libentry
+$   endif
+$   return
+$! The record writer routine for VAX variables (should never happen!)
+$ write_vax_psect_attr:
+$   if info_kind .nes. "VARIABLE" then return
+$   if libentry .eqs ".dummy" then return
+$   write 'libwrch' "PSECT_ATTR=",libentry,",NOSHR"
+$   return
+$
+$! ----- Common subroutines
+$! -----
+$! The .num file reader.  This one has great responsibility.
+$ read_func_num:
+$   open /read libnum 'libnum'
+$   goto read_nums
+$
+$ read_nums:
+$   libentrynum=0
+$   liblastentry:=false
+$   entrycount=0
+$   loop:
+$     read /end=loop_end /err=loop_end libnum line
+$     lin = f$edit( line, "COMPRESS,TRIM")
+$!    Skip a "#" comment line.
+$     if (f$extract( 0, 1, lin) .eqs. "#") then goto loop
+$     entrynum = f$int(f$element( 1, " ", lin))
+$     entryinfo = f$element( 2, " ", lin)
+$     curentry = f$element( 0, " ", lin)
+$     info_exist = f$element( 0, ":", entryinfo)
+$     info_platforms = ","+ f$element(1, ":", entryinfo)+ ","
+$     info_kind = f$element( 2, ":", entryinfo)
+$     info_algorithms = ","+ f$element( 3, ":", entryinfo)+ ","
+$     if info_exist .eqs. "NOEXIST" then goto loop
+$     truesum = 0
+$     falsesum = 0
+$     negatives = 1
+$     plat_i = 0
+$     loop1:
+$       plat_entry = f$element( plat_i, ",", info_platforms)
+$       plat_i = plat_i + 1
+$       if plat_entry .eqs. "" then goto loop1
+$       if plat_entry .nes. ","
+$       then
+$         if f$extract(0,1,plat_entry) .nes. "!" then negatives = 0
+$         if (arch_vax)
+$         then
+$           if plat_entry .eqs. "EXPORT_VAR_AS_FUNCTION" then -
+$             truesum = truesum + 1
+$           if plat_entry .eqs. "!EXPORT_VAR_AS_FUNCTION" then -
+$             falsesum = falsesum + 1
+$         endif
+$!
+$         if ((plat_entry .eqs. "VMS") .or. -
+            ((plat_entry .eqs. "ZLIB") .and. (ZLIB .nes. "")) .or. -
+            (arch_vax .and. (plat_entry .eqs. "VMSVAX"))) then -
+            truesum = truesum + 1
+$!
+$         if ((plat_entry .eqs. "!VMS") .or. -
+            (arch_vax .and. (plat_entry .eqs. "!VMSVAX"))) then -
+            falsesum = falsesum + 1
+$!
+$	  goto loop1
+$       endif
+$     endloop1:
+$!DEBUG!$     if info_platforms - "EXPORT_VAR_AS_FUNCTION" .nes. info_platforms
+$!DEBUG!$     then
+$!DEBUG!$       write sys$output line
+$!DEBUG!$       write sys$output "        truesum = ",truesum,-
+$!DEBUG!		", negatives = ",negatives,", falsesum = ",falsesum
+$!DEBUG!$     endif
+$     if falsesum .ne. 0 then goto loop
+$     if truesum+negatives .eq. 0 then goto loop
+$     alg_i = 0
+$     loop2:
+$       alg_entry = f$element(alg_i,",",info_algorithms)
+$	alg_i = alg_i + 1
+$       if alg_entry .eqs. "" then goto loop2
+$       if alg_entry .nes. ","
+$       then
+$	  if disabled_algorithms - ("," + alg_entry + ",") .nes disabled_algorithms then goto loop
+$         if f$trnlnm("OPENSSL_NO_"+alg_entry) .nes. "" then goto loop
+$	  goto loop2
+$       endif
+$     endloop2:
+$     if info_platforms - "EXPORT_VAR_AS_FUNCTION" .nes. info_platforms
+$     then
+$!DEBUG!$     write sys$output curentry," ; ",entrynum," ; ",entryinfo
+$     endif
+$   redo:
+$     next:=loop
+$     tolibentry=curentry
+$     if libentrynum .ne. entrynum
+$     then
+$       entrycount=entrycount+1
+$       if entrycount .lt. entrynum
+$       then
+$!DEBUG!$         write sys$output "Info: entrycount: ''entrycount', entrynum: ''entrynum' => 0"
+$         tolibentry=".dummy"
+$         next:=redo
+$       endif
+$       if entrycount .gt. entrynum
+$       then
+$         write sys$error "Decreasing library entry numbers!  Can't continue"
+$         write sys$error """",line,""""
+$         close libnum
+$         return
+$       endif
+$       libentry=tolibentry
+$!DEBUG!$       write sys$output entrycount," ",libentry," ",entryinfo
+$       if libentry .nes. "" .and. libwriter .nes. "" then gosub 'libwriter'
+$     else
+$       write sys$error "Info: ""''curentry'"" is an alias for ""''libentry'"".  Overriding..."
+$     endif
+$     libentrynum=entrycount
+$     goto 'next'
+$   loop_end:
+$   close libnum
+$   return
+$
+$! The version number reader
+$ read_version_info:
+$   libver = ""
+$   open /read vf [.CRYPTO]OPENSSLV.H
+$   loop_rvi:
+$     read/err=endloop_rvi/end=endloop_rvi vf rvi_line
+$     if rvi_line - "SHLIB_VERSION_NUMBER """ .eqs. rvi_line then -
+	goto loop_rvi
+$     libverstr = f$element(1,"""",rvi_line)
+$     libvmajor = f$element(0,".",libverstr)
+$     libvminor = f$element(1,".",libverstr)
+$     libvedit = f$element(2,".",libverstr)
+$     libvpatch = f$cvui(0,8,f$extract(1,1,libvedit)+"@")-f$cvui(0,8,"@")
+$     libvedit = f$extract(0,1,libvedit)
+$     libver = f$string(f$int(libvmajor)*100)+","+-
+	f$string(f$int(libvminor)*100+f$int(libvedit)*10+f$int(libvpatch))
+$     if libvmajor .eqs. "0"
+$     then
+$       libvmatch = "EQUAL"
+$     else
+$       ! Starting with the 1.0 release, backward compatibility should be
+$       ! kept, so switch over to the following
+$       libvmatch = "LEQUAL"
+$     endif
+$   endloop_rvi:
+$   close vf
+$   return
+$
+$! The disabled algorithms reader
+$ read_disabled_algorithms_info:
+$   disabled_algorithms = ","
+$   open /read cf [.CRYPTO.'ARCH']OPENSSLCONF.H
+$   loop_rci:
+$     read/err=endloop_rci/end=endloop_rci cf rci_line
+$     rci_line = f$edit(rci_line,"TRIM,COMPRESS")
+$     rci_ei = 0
+$     if f$extract(0,9,rci_line) .eqs. "# define " then rci_ei = 2
+$     if f$extract(0,8,rci_line) .eqs. "#define " then rci_ei = 1
+$     if rci_ei .eq. 0 then goto loop_rci
+$     rci_e = f$element(rci_ei," ",rci_line)
+$     if f$extract(0,11,rci_e) .nes. "OPENSSL_NO_" then goto loop_rci
+$     disabled_algorithms = disabled_algorithms + f$extract(11,999,rci_e) + ","
+$     goto loop_rci
+$   endloop_rci:
+$   close cf
+$   return
diff --git a/openssl/VMS/multinet_shr.opt b/openssl/VMS/multinet_shr.opt
new file mode 100644
index 0000000..610f42d
--- /dev/null
+++ b/openssl/VMS/multinet_shr.opt
@@ -0,0 +1 @@
+multinet:multinet_socket_library.exe/share
diff --git a/openssl/VMS/openssl_startup.com b/openssl/VMS/openssl_startup.com
new file mode 100644
index 0000000..04bbbde
--- /dev/null
+++ b/openssl/VMS/openssl_startup.com
@@ -0,0 +1,108 @@
+$!
+$! Startup file for OpenSSL 1.x.
+$!
+$! 2011-03-05 SMS.
+$!
+$! This procedure must reside in the OpenSSL installation directory.
+$! It will fail if it is copied to a different location.
+$!
+$! P1  qualifier(s) for DEFINE.  For example, "/SYSTEM" to get the
+$!     logical names defined in the system logical name table.
+$!
+$! P2  "64", to use executables which were built with 64-bit pointers.
+$!
+$! Good (default) and bad status values.
+$!
+$ status =    %x00010001 ! RMS$_NORMAL, normal successful completion.
+$ rms_e_fnf = %x00018292 ! RMS$_FNF, file not found.
+$!
+$! Prepare for problems.
+$!
+$ orig_dev_dir = f$environment( "DEFAULT")
+$ on control_y then goto clean_up
+$ on error then goto clean_up
+$!
+$! Determine hardware architecture.
+$!
+$ if (f$getsyi( "cpu") .lt. 128)
+$ then
+$   arch_name = "VAX"
+$ else
+$   arch_name = f$edit( f$getsyi( "arch_name"), "upcase")
+$   if (arch_name .eqs. "") then arch_name = "UNK"
+$ endif
+$!
+$ if (p2 .eqs. "64")
+$ then
+$   arch_name_exe = arch_name+ "_64"
+$ else
+$   arch_name_exe = arch_name
+$ endif
+$!
+$! Derive the OpenSSL installation device:[directory] from the location
+$! of this command procedure.
+$!
+$ proc = f$environment( "procedure")
+$ proc_dev_dir = f$parse( "A.;", proc, , , "no_conceal") - "A.;"
+$ proc_dev = f$parse( proc_dev_dir, , , "device", "syntax_only")
+$ proc_dir = f$parse( proc_dev_dir, , , "directory", "syntax_only") - -
+   ".][000000"- "[000000."- "]["- "["- "]"
+$ proc_dev_dir = proc_dev+ "["+ proc_dir+ "]"
+$ set default 'proc_dev_dir'
+$ set default [-]
+$ ossl_dev_dir = f$environment( "default")
+$!
+$! Check existence of expected directories (to see if this procedure has
+$! been moved away from its proper place).
+$!
+$ if ((f$search( "certs.dir;1") .eqs. "") .or. -
+   (f$search( "include.dir;1") .eqs. "") .or. -
+   (f$search( "private.dir;1") .eqs. "") .or. -
+   (f$search( "vms.dir;1") .eqs. ""))
+$ then
+$    write sys$output -
+      "   Can't find expected common OpenSSL directories in:"
+$    write sys$output "   ''ossl_dev_dir'"
+$    status = rms_e_fnf
+$    goto clean_up
+$ endif
+$!
+$ if ((f$search( "''arch_name_exe'_exe.dir;1") .eqs. "") .or. -
+   (f$search( "''arch_name'_lib.dir;1") .eqs. ""))
+$ then
+$    write sys$output -
+      "   Can't find expected architecture-specific OpenSSL directories in:"
+$    write sys$output "   ''ossl_dev_dir'"
+$    status = rms_e_fnf
+$    goto clean_up
+$ endif
+$!
+$! All seems well (enough).  Define the OpenSSL logical names.
+$!
+$ ossl_root = ossl_dev_dir- "]"+ ".]"
+$ define /translation_attributes = concealed /nolog'p1 SSLROOT 'ossl_root'
+$ define /nolog 'p1' SSLCERTS     sslroot:[certs]
+$ define /nolog 'p1' SSLINCLUDE   sslroot:[include]
+$ define /nolog 'p1' SSLPRIVATE   sslroot:[private]
+$ define /nolog 'p1' SSLEXE       sslroot:['arch_name_exe'_exe]
+$ define /nolog 'p1' SSLLIB       sslroot:['arch_name'_lib]
+$!
+$! Defining OPENSSL lets a C program use "#include <openssl/{foo}.h>":
+$ define /nolog 'p1' OPENSSL      SSLINCLUDE:
+$!
+$! Run a site-specific procedure, if it exists.
+$!
+$ if f$search( "sslroot:[vms]openssl_systartup.com") .nes."" then -
+   @ sslroot:[vms]openssl_systartup.com
+$!
+$! Restore the original default dev:[dir] (if known).
+$!
+$ clean_up:
+$!
+$ if (f$type( orig_dev_dir) .nes. "")
+$ then
+$    set default 'orig_dev_dir'
+$ endif
+$!
+$ EXIT 'status'
+$!
diff --git a/openssl/VMS/openssl_undo.com b/openssl/VMS/openssl_undo.com
new file mode 100644
index 0000000..d1623a3
--- /dev/null
+++ b/openssl/VMS/openssl_undo.com
@@ -0,0 +1,20 @@
+$!
+$! Deassign OpenSSL logical names.
+$!
+$ call deass "OPENSSL" "''p1'"
+$ call deass "SSLCERTS" "''p1'"
+$ call deass "SSLEXE" "''p1'"
+$ call deass "SSLINCLUDE" "''p1'"
+$ call deass "SSLLIB" "''p1'"
+$ call deass "SSLPRIVATE" "''p1'"
+$ call deass "SSLROOT" "''p1'"
+$!
+$ exit
+$!
+$deass: subroutine
+$ if (f$trnlnm( p1) .nes. "")
+$ then
+$    deassign 'p2' 'p1'
+$ endif
+$ endsubroutine
+$!
diff --git a/openssl/VMS/openssl_utils.com b/openssl/VMS/openssl_utils.com
new file mode 100644
index 0000000..64f4915
--- /dev/null
+++ b/openssl/VMS/openssl_utils.com
@@ -0,0 +1,46 @@
+$!
+$!  APPS.COM
+$!  Written By:  Robert Byer
+$!               Vice-President
+$!               A-Com Computing, Inc.
+$!               byer@mail.all-net.net
+$!
+$!
+$! Slightly modified by Richard Levitte <richard@levitte.org>
+$!
+$!
+$! Always define OPENSSL.  Others are optional (non-null P1).
+$!
+$ OPENSSL  :== $SSLEXE:OPENSSL
+$
+$ IF (P1 .NES. "")
+$ THEN
+$     VERIFY   :== $SSLEXE:OPENSSL VERIFY
+$     ASN1PARSE:== $SSLEXE:OPENSSL ASN1PARS
+$! REQ could conflict with REQUEST.
+$     OREQ     :== $SSLEXE:OPENSSL REQ
+$     DGST     :== $SSLEXE:OPENSSL DGST
+$     DH       :== $SSLEXE:OPENSSL DH
+$     ENC      :== $SSLEXE:OPENSSL ENC
+$     GENDH    :== $SSLEXE:OPENSSL GENDH
+$     ERRSTR   :== $SSLEXE:OPENSSL ERRSTR
+$     CA       :== $SSLEXE:OPENSSL CA
+$     CRL      :== $SSLEXE:OPENSSL CRL
+$     RSA      :== $SSLEXE:OPENSSL RSA
+$     DSA      :== $SSLEXE:OPENSSL DSA
+$     DSAPARAM :== $SSLEXE:OPENSSL DSAPARAM
+$     X509     :== $SSLEXE:OPENSSL X509
+$     GENRSA   :== $SSLEXE:OPENSSL GENRSA
+$     GENDSA   :== $SSLEXE:OPENSSL GENDSA
+$     S_SERVER :== $SSLEXE:OPENSSL S_SERVER
+$     S_CLIENT :== $SSLEXE:OPENSSL S_CLIENT
+$     SPEED    :== $SSLEXE:OPENSSL SPEED
+$     S_TIME   :== $SSLEXE:OPENSSL S_TIME
+$     VERSION  :== $SSLEXE:OPENSSL VERSION
+$     PKCS7    :== $SSLEXE:OPENSSL PKCS7
+$     CRL2PKCS7:== $SSLEXE:OPENSSL CRL2P7
+$     SESS_ID  :== $SSLEXE:OPENSSL SESS_ID
+$     CIPHERS  :== $SSLEXE:OPENSSL CIPHERS
+$     NSEQ     :== $SSLEXE:OPENSSL NSEQ
+$     PKCS12   :== $SSLEXE:OPENSSL PKCS12
+$ ENDIF
diff --git a/openssl/VMS/socketshr_shr.opt b/openssl/VMS/socketshr_shr.opt
new file mode 100644
index 0000000..f6e3131
--- /dev/null
+++ b/openssl/VMS/socketshr_shr.opt
@@ -0,0 +1 @@
+socketshr/share
diff --git a/openssl/VMS/tcpip_shr_decc.opt b/openssl/VMS/tcpip_shr_decc.opt
new file mode 100644
index 0000000..33b159e
--- /dev/null
+++ b/openssl/VMS/tcpip_shr_decc.opt
@@ -0,0 +1 @@
+sys$share:tcpip$ipc_shr.exe/share
diff --git a/openssl/VMS/test-includes.com b/openssl/VMS/test-includes.com
new file mode 100644
index 0000000..c1d7ccd
--- /dev/null
+++ b/openssl/VMS/test-includes.com
@@ -0,0 +1,28 @@
+$! Quick script to check how well including individual header files works
+$! on VMS, even when the VMS macro isn't defined.
+$
+$	sav_def = f$env("DEFAULT")
+$	here = f$parse("A.;0",f$ENV("PROCEDURE")) - "A.;0"
+$	set default 'here'
+$	set default [-.include.openssl]
+$	define openssl 'f$env("DEFAULT")'
+$	set default [--]
+$
+$ loop:
+$	f = f$search("openssl:*.h")
+$	if f .eqs. "" then goto loop_end
+$	write sys$output "Checking ",f
+$	open/write foo foo.c
+$	write foo "#undef VMS"
+$	write foo "#include <stdio.h>"
+$	write foo "#include <openssl/",f$parse(f,,,"NAME"),".h>"
+$	write foo "main()"
+$	write foo "{printf(""foo\n"");}"
+$	close foo
+$	cc/STANDARD=ANSI89/NOLIST/PREFIX=ALL foo.c
+$	delete foo.c;
+$	goto loop
+$ loop_end:
+$	set default 'save_def'
+$	exit
+
diff --git a/openssl/VMS/ucx_shr_decc.opt b/openssl/VMS/ucx_shr_decc.opt
new file mode 100644
index 0000000..28d84f4
--- /dev/null
+++ b/openssl/VMS/ucx_shr_decc.opt
@@ -0,0 +1 @@
+sys$share:ucx$ipc_shr.exe/share
diff --git a/openssl/VMS/ucx_shr_decc_log.opt b/openssl/VMS/ucx_shr_decc_log.opt
new file mode 100644
index 0000000..c9d9a96
--- /dev/null
+++ b/openssl/VMS/ucx_shr_decc_log.opt
@@ -0,0 +1 @@
+ucx$ipc_shr/share
diff --git a/openssl/VMS/ucx_shr_vaxc.opt b/openssl/VMS/ucx_shr_vaxc.opt
new file mode 100644
index 0000000..86bfaf0
--- /dev/null
+++ b/openssl/VMS/ucx_shr_vaxc.opt
@@ -0,0 +1 @@
+sys$library:ucx$ipc.olb/library
diff --git a/openssl/apps/CA.com b/openssl/apps/CA.com
new file mode 100644
index 0000000..2c0d465
--- /dev/null
+++ b/openssl/apps/CA.com
@@ -0,0 +1,236 @@
+$! CA - wrapper around ca to make it easier to use ... basically ca requires
+$!      some setup stuff to be done before you can use it and this makes
+$!      things easier between now and when Eric is convinced to fix it :-)
+$!
+$! CA -newca ... will setup the right stuff
+$! CA -newreq ... will generate a certificate request 
+$! CA -sign ... will sign the generated request and output 
+$!
+$! At the end of that grab newreq.pem and newcert.pem (one has the key 
+$! and the other the certificate) and cat them together and that is what
+$! you want/need ... I'll make even this a little cleaner later.
+$!
+$!
+$! 12-Jan-96 tjh    Added more things ... including CA -signcert which
+$!                  converts a certificate to a request and then signs it.
+$! 10-Jan-96 eay    Fixed a few more bugs and added the SSLEAY_CONFIG
+$!                 environment variable so this can be driven from
+$!                 a script.
+$! 25-Jul-96 eay    Cleaned up filenames some more.
+$! 11-Jun-96 eay    Fixed a few filename missmatches.
+$! 03-May-96 eay    Modified to use 'openssl cmd' instead of 'cmd'.
+$! 18-Apr-96 tjh    Original hacking
+$!
+$! Tim Hudson
+$! tjh@cryptsoft.com
+$!
+$!
+$! default ssleay.cnf file has setup as per the following
+$! demoCA ... where everything is stored
+$
+$ IF F$TYPE(SSLEAY_CONFIG) .EQS. "" THEN SSLEAY_CONFIG := SSLLIB:SSLEAY.CNF
+$
+$ DAYS   = "-days 365"
+$ REQ    = openssl + " req " + SSLEAY_CONFIG
+$ CA     = openssl + " ca " + SSLEAY_CONFIG
+$ VERIFY = openssl + " verify"
+$ X509   = openssl + " x509"
+$ PKCS12 = openssl + " pkcs12"
+$ echo   = "write sys$Output"
+$ RET = 1
+$!
+$! 2010-12-20 SMS.
+$! Use a concealed logical name to reduce command line lengths, to
+$! avoid DCL errors on VAX:
+$!     %DCL-W-TKNOVF, command element is too long - shorten
+$! (Path segments like "openssl-1_0_1-stable-SNAP-20101217" accumulate
+$! quickly.)
+$!
+$ CATOP = F$PARSE( F$ENVIRONMENT( "DEFAULT"), "[]")- "].;"+ ".demoCA.]"
+$ define /translation_attributes = concealed CATOP 'CATOP'
+$!
+$ on error then goto clean_up
+$ on control_y then goto clean_up
+$!
+$ CAKEY  = "CATOP:[private]cakey.pem"
+$ CACERT = "CATOP:[000000]cacert.pem"
+$
+$ __INPUT := SYS$COMMAND
+$!
+$ i = 1
+$opt_loop:
+$ if i .gt. 8 then goto opt_loop_end
+$
+$ prog_opt = F$EDIT(P'i',"lowercase")
+$
+$ IF (prog_opt .EQS. "?" .OR. prog_opt .EQS. "-h" .OR. prog_opt .EQS. "-help") 
+$ THEN
+$   echo "usage: CA -newcert|-newreq|-newca|-sign|-verify" 
+$   goto clean_up
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-input")
+$ THEN
+$   ! Get input from somewhere other than SYS$COMMAND
+$   i = i + 1
+$   __INPUT = P'i'
+$   GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-newcert")
+$ THEN
+$   ! Create a certificate.
+$   DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$   REQ -new -x509 -keyout newreq.pem -out newreq.pem 'DAYS'
+$   RET=$STATUS
+$   echo "Certificate (and private key) is in newreq.pem"
+$   GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-newreq")
+$ THEN
+$   ! Create a certificate request
+$   DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$   REQ -new -keyout newreq.pem -out newreq.pem 'DAYS'
+$   RET=$STATUS
+$   echo "Request (and private key) is in newreq.pem"
+$   GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-newca")
+$ THEN
+$   ! If explicitly asked for or it doesn't exist then setup the directory
+$   ! structure that Eric likes to manage things.
+$   IF F$SEARCH( "CATOP:[000000]serial.") .EQS. ""
+$   THEN
+$     CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[000000]
+$     CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[certs]
+$     CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[crl]
+$     CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[newcerts]
+$     CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[private]
+$
+$     OPEN /WRITE ser_file CATOP:[000000]serial. 
+$     WRITE ser_file "01"
+$     CLOSE ser_file
+$     APPEND /NEW_VERSION NL: CATOP:[000000]index.txt
+$
+$     ! The following is to make sure access() doesn't get confused.  It
+$     ! really needs one file in the directory to give correct answers...
+$     COPY NLA0: CATOP:[certs].;
+$     COPY NLA0: CATOP:[crl].;
+$     COPY NLA0: CATOP:[newcerts].;
+$     COPY NLA0: CATOP:[private].;
+$   ENDIF
+$!
+$   IF F$SEARCH( CAKEY) .EQS. ""
+$   THEN
+$     READ '__INPUT' FILE -
+       /PROMPT="CA certificate filename (or enter to create): "
+$     IF (FILE .NES. "") .AND. (F$SEARCH(FILE) .NES. "")
+$     THEN
+$       COPY 'FILE' 'CAKEY'
+$       RET=$STATUS
+$     ELSE
+$       echo "Making CA certificate ..."
+$       DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$       REQ -new -x509 -keyout 'CAKEY' -out 'CACERT' 'DAYS'
+$       RET=$STATUS
+$     ENDIF
+$   ENDIF
+$   GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-pkcs12")
+$ THEN
+$   i = i + 1
+$   cname = P'i'
+$   IF cname .EQS. "" THEN cname = "My certificate"
+$   PKCS12 -in newcert.pem -inkey newreq.pem -certfile 'CACERT' -
+     -out newcert.p12 -export -name "''cname'"
+$   RET=$STATUS
+$   goto clean_up
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-xsign")
+$ THEN
+$!
+$   DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$   CA -policy policy_anything -infiles newreq.pem
+$   RET=$STATUS
+$   GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF ((prog_opt .EQS. "-sign") .OR. (prog_opt .EQS. "-signreq"))
+$ THEN
+$!   
+$   DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$   CA -policy policy_anything -out newcert.pem -infiles newreq.pem
+$   RET=$STATUS
+$   type newcert.pem
+$   echo "Signed certificate is in newcert.pem"
+$   GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-signcert")
+$  THEN
+$!   
+$   echo "Cert passphrase will be requested twice - bug?"
+$   DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$   X509 -x509toreq -in newreq.pem -signkey newreq.pem -out tmp.pem
+$   DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$   CA -policy policy_anything -out newcert.pem -infiles tmp.pem
+y
+y
+$   type newcert.pem
+$   echo "Signed certificate is in newcert.pem"
+$   GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-verify")
+$ THEN
+$!   
+$   i = i + 1
+$   IF (p'i' .EQS. "")
+$   THEN
+$     DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$     VERIFY "-CAfile" 'CACERT' newcert.pem
+$   ELSE
+$     j = i
+$    verify_opt_loop:
+$     IF j .GT. 8 THEN GOTO verify_opt_loop_end
+$     IF p'j' .NES. ""
+$     THEN 
+$       DEFINE /USER_MODE SYS$INPUT '__INPUT'
+$       __tmp = p'j'
+$       VERIFY "-CAfile" 'CACERT' '__tmp'
+$       tmp=$STATUS
+$       IF tmp .NE. 0 THEN RET=tmp
+$     ENDIF
+$     j = j + 1
+$     GOTO verify_opt_loop
+$    verify_opt_loop_end:
+$   ENDIF
+$   
+$   GOTO opt_loop_end
+$ ENDIF
+$!
+$ IF (prog_opt .NES. "")
+$ THEN
+$!   
+$   echo "Unknown argument ''prog_opt'"
+$   RET = 3
+$   goto clean_up
+$ ENDIF
+$
+$opt_loop_continue:
+$ i = i + 1
+$ GOTO opt_loop
+$
+$opt_loop_end:
+$!
+$clean_up:
+$!
+$ if f$trnlnm( "CATOP", "LNM$PROCESS") .nes. "" then -
+   deassign /process CATOP
+$!
+$ EXIT 'RET'
diff --git a/openssl/apps/CA.pl b/openssl/apps/CA.pl
new file mode 100644
index 0000000..a3965ec
--- /dev/null
+++ b/openssl/apps/CA.pl
@@ -0,0 +1,189 @@
+#!/usr/bin/perl
+#
+# CA - wrapper around ca to make it easier to use ... basically ca requires
+#      some setup stuff to be done before you can use it and this makes
+#      things easier between now and when Eric is convinced to fix it :-)
+#
+# CA -newca ... will setup the right stuff
+# CA -newreq[-nodes] ... will generate a certificate request 
+# CA -sign ... will sign the generated request and output 
+#
+# At the end of that grab newreq.pem and newcert.pem (one has the key 
+# and the other the certificate) and cat them together and that is what
+# you want/need ... I'll make even this a little cleaner later.
+#
+#
+# 12-Jan-96 tjh    Added more things ... including CA -signcert which
+#                  converts a certificate to a request and then signs it.
+# 10-Jan-96 eay    Fixed a few more bugs and added the SSLEAY_CONFIG
+#		   environment variable so this can be driven from
+#		   a script.
+# 25-Jul-96 eay    Cleaned up filenames some more.
+# 11-Jun-96 eay    Fixed a few filename missmatches.
+# 03-May-96 eay    Modified to use 'ssleay cmd' instead of 'cmd'.
+# 18-Apr-96 tjh    Original hacking
+#
+# Tim Hudson
+# tjh@cryptsoft.com
+#
+
+# 27-Apr-98 snh    Translation into perl, fix existing CA bug.
+#
+#
+# Steve Henson
+# shenson@bigfoot.com
+
+# default openssl.cnf file has setup as per the following
+# demoCA ... where everything is stored
+
+my $openssl;
+if(defined $ENV{OPENSSL}) {
+	$openssl = $ENV{OPENSSL};
+} else {
+	$openssl = "openssl";
+	$ENV{OPENSSL} = $openssl;
+}
+
+$SSLEAY_CONFIG=$ENV{"SSLEAY_CONFIG"};
+$DAYS="-days 365";	# 1 year
+$CADAYS="-days 1095";	# 3 years
+$REQ="$openssl req $SSLEAY_CONFIG";
+$CA="$openssl ca $SSLEAY_CONFIG";
+$VERIFY="$openssl verify";
+$X509="$openssl x509";
+$PKCS12="$openssl pkcs12";
+
+$CATOP="./demoCA";
+$CAKEY="cakey.pem";
+$CAREQ="careq.pem";
+$CACERT="cacert.pem";
+
+$DIRMODE = 0777;
+
+$RET = 0;
+
+foreach (@ARGV) {
+	if ( /^(-\?|-h|-help)$/ ) {
+	    print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n";
+	    exit 0;
+	} elsif (/^-newcert$/) {
+	    # create a certificate
+	    system ("$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS");
+	    $RET=$?;
+	    print "Certificate is in newcert.pem, private key is in newkey.pem\n"
+	} elsif (/^-newreq$/) {
+	    # create a certificate request
+	    system ("$REQ -new -keyout newkey.pem -out newreq.pem $DAYS");
+	    $RET=$?;
+	    print "Request is in newreq.pem, private key is in newkey.pem\n";
+	} elsif (/^-newreq-nodes$/) {
+	    # create a certificate request
+	    system ("$REQ -new -nodes -keyout newkey.pem -out newreq.pem $DAYS");
+	    $RET=$?;
+	    print "Request is in newreq.pem, private key is in newkey.pem\n";
+	} elsif (/^-newca$/) {
+		# if explicitly asked for or it doesn't exist then setup the
+		# directory structure that Eric likes to manage things 
+	    $NEW="1";
+	    if ( "$NEW" || ! -f "${CATOP}/serial" ) {
+		# create the directory hierarchy
+		mkdir $CATOP, $DIRMODE;
+		mkdir "${CATOP}/certs", $DIRMODE;
+		mkdir "${CATOP}/crl", $DIRMODE ;
+		mkdir "${CATOP}/newcerts", $DIRMODE;
+		mkdir "${CATOP}/private", $DIRMODE;
+		open OUT, ">${CATOP}/index.txt";
+		close OUT;
+		open OUT, ">${CATOP}/crlnumber";
+		print OUT "01\n";
+		close OUT;
+	    }
+	    if ( ! -f "${CATOP}/private/$CAKEY" ) {
+		print "CA certificate filename (or enter to create)\n";
+		$FILE = <STDIN>;
+
+		chop $FILE;
+
+		# ask user for existing CA certificate
+		if ($FILE) {
+		    cp_pem($FILE,"${CATOP}/private/$CAKEY", "PRIVATE");
+		    cp_pem($FILE,"${CATOP}/$CACERT", "CERTIFICATE");
+		    $RET=$?;
+		} else {
+		    print "Making CA certificate ...\n";
+		    system ("$REQ -new -keyout " .
+			"${CATOP}/private/$CAKEY -out ${CATOP}/$CAREQ");
+		    system ("$CA -create_serial " .
+			"-out ${CATOP}/$CACERT $CADAYS -batch " . 
+			"-keyfile ${CATOP}/private/$CAKEY -selfsign " .
+			"-extensions v3_ca " .
+			"-infiles ${CATOP}/$CAREQ ");
+		    $RET=$?;
+		}
+	    }
+	} elsif (/^-pkcs12$/) {
+	    my $cname = $ARGV[1];
+	    $cname = "My Certificate" unless defined $cname;
+	    system ("$PKCS12 -in newcert.pem -inkey newkey.pem " .
+			"-certfile ${CATOP}/$CACERT -out newcert.p12 " .
+			"-export -name \"$cname\"");
+	    $RET=$?;
+	    print "PKCS #12 file is in newcert.p12\n";
+	    exit $RET;
+	} elsif (/^-xsign$/) {
+	    system ("$CA -policy policy_anything -infiles newreq.pem");
+	    $RET=$?;
+	} elsif (/^(-sign|-signreq)$/) {
+	    system ("$CA -policy policy_anything -out newcert.pem " .
+							"-infiles newreq.pem");
+	    $RET=$?;
+	    print "Signed certificate is in newcert.pem\n";
+	} elsif (/^(-signCA)$/) {
+	    system ("$CA -policy policy_anything -out newcert.pem " .
+					"-extensions v3_ca -infiles newreq.pem");
+	    $RET=$?;
+	    print "Signed CA certificate is in newcert.pem\n";
+	} elsif (/^-signcert$/) {
+	    system ("$X509 -x509toreq -in newreq.pem -signkey newreq.pem " .
+								"-out tmp.pem");
+	    system ("$CA -policy policy_anything -out newcert.pem " .
+							"-infiles tmp.pem");
+	    $RET = $?;
+	    print "Signed certificate is in newcert.pem\n";
+	} elsif (/^-verify$/) {
+	    if (shift) {
+		foreach $j (@ARGV) {
+		    system ("$VERIFY -CAfile $CATOP/$CACERT $j");
+		    $RET=$? if ($? != 0);
+		}
+		exit $RET;
+	    } else {
+		    system ("$VERIFY -CAfile $CATOP/$CACERT newcert.pem");
+		    $RET=$?;
+	    	    exit 0;
+	    }
+	} else {
+	    print STDERR "Unknown arg $_\n";
+	    print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n";
+	    exit 1;
+	}
+}
+
+exit $RET;
+
+sub cp_pem {
+my ($infile, $outfile, $bound) = @_;
+open IN, $infile;
+open OUT, ">$outfile";
+my $flag = 0;
+while (<IN>) {
+	$flag = 1 if (/^-----BEGIN.*$bound/) ;
+	print OUT $_ if ($flag);
+	if (/^-----END.*$bound/) {
+		close IN;
+		close OUT;
+		return;
+	}
+}
+}
+
diff --git a/openssl/apps/CA.pl.in b/openssl/apps/CA.pl.in
new file mode 100644
index 0000000..c783a6e
--- /dev/null
+++ b/openssl/apps/CA.pl.in
@@ -0,0 +1,189 @@
+#!/usr/local/bin/perl
+#
+# CA - wrapper around ca to make it easier to use ... basically ca requires
+#      some setup stuff to be done before you can use it and this makes
+#      things easier between now and when Eric is convinced to fix it :-)
+#
+# CA -newca ... will setup the right stuff
+# CA -newreq[-nodes] ... will generate a certificate request 
+# CA -sign ... will sign the generated request and output 
+#
+# At the end of that grab newreq.pem and newcert.pem (one has the key 
+# and the other the certificate) and cat them together and that is what
+# you want/need ... I'll make even this a little cleaner later.
+#
+#
+# 12-Jan-96 tjh    Added more things ... including CA -signcert which
+#                  converts a certificate to a request and then signs it.
+# 10-Jan-96 eay    Fixed a few more bugs and added the SSLEAY_CONFIG
+#		   environment variable so this can be driven from
+#		   a script.
+# 25-Jul-96 eay    Cleaned up filenames some more.
+# 11-Jun-96 eay    Fixed a few filename missmatches.
+# 03-May-96 eay    Modified to use 'ssleay cmd' instead of 'cmd'.
+# 18-Apr-96 tjh    Original hacking
+#
+# Tim Hudson
+# tjh@cryptsoft.com
+#
+
+# 27-Apr-98 snh    Translation into perl, fix existing CA bug.
+#
+#
+# Steve Henson
+# shenson@bigfoot.com
+
+# default openssl.cnf file has setup as per the following
+# demoCA ... where everything is stored
+
+my $openssl;
+if(defined $ENV{OPENSSL}) {
+	$openssl = $ENV{OPENSSL};
+} else {
+	$openssl = "openssl";
+	$ENV{OPENSSL} = $openssl;
+}
+
+$SSLEAY_CONFIG=$ENV{"SSLEAY_CONFIG"};
+$DAYS="-days 365";	# 1 year
+$CADAYS="-days 1095";	# 3 years
+$REQ="$openssl req $SSLEAY_CONFIG";
+$CA="$openssl ca $SSLEAY_CONFIG";
+$VERIFY="$openssl verify";
+$X509="$openssl x509";
+$PKCS12="$openssl pkcs12";
+
+$CATOP="./demoCA";
+$CAKEY="cakey.pem";
+$CAREQ="careq.pem";
+$CACERT="cacert.pem";
+
+$DIRMODE = 0777;
+
+$RET = 0;
+
+foreach (@ARGV) {
+	if ( /^(-\?|-h|-help)$/ ) {
+	    print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n";
+	    exit 0;
+	} elsif (/^-newcert$/) {
+	    # create a certificate
+	    system ("$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS");
+	    $RET=$?;
+	    print "Certificate is in newcert.pem, private key is in newkey.pem\n"
+	} elsif (/^-newreq$/) {
+	    # create a certificate request
+	    system ("$REQ -new -keyout newkey.pem -out newreq.pem $DAYS");
+	    $RET=$?;
+	    print "Request is in newreq.pem, private key is in newkey.pem\n";
+	} elsif (/^-newreq-nodes$/) {
+	    # create a certificate request
+	    system ("$REQ -new -nodes -keyout newkey.pem -out newreq.pem $DAYS");
+	    $RET=$?;
+	    print "Request is in newreq.pem, private key is in newkey.pem\n";
+	} elsif (/^-newca$/) {
+		# if explicitly asked for or it doesn't exist then setup the
+		# directory structure that Eric likes to manage things 
+	    $NEW="1";
+	    if ( "$NEW" || ! -f "${CATOP}/serial" ) {
+		# create the directory hierarchy
+		mkdir $CATOP, $DIRMODE;
+		mkdir "${CATOP}/certs", $DIRMODE;
+		mkdir "${CATOP}/crl", $DIRMODE ;
+		mkdir "${CATOP}/newcerts", $DIRMODE;
+		mkdir "${CATOP}/private", $DIRMODE;
+		open OUT, ">${CATOP}/index.txt";
+		close OUT;
+		open OUT, ">${CATOP}/crlnumber";
+		print OUT "01\n";
+		close OUT;
+	    }
+	    if ( ! -f "${CATOP}/private/$CAKEY" ) {
+		print "CA certificate filename (or enter to create)\n";
+		$FILE = <STDIN>;
+
+		chop $FILE;
+
+		# ask user for existing CA certificate
+		if ($FILE) {
+		    cp_pem($FILE,"${CATOP}/private/$CAKEY", "PRIVATE");
+		    cp_pem($FILE,"${CATOP}/$CACERT", "CERTIFICATE");
+		    $RET=$?;
+		} else {
+		    print "Making CA certificate ...\n";
+		    system ("$REQ -new -keyout " .
+			"${CATOP}/private/$CAKEY -out ${CATOP}/$CAREQ");
+		    system ("$CA -create_serial " .
+			"-out ${CATOP}/$CACERT $CADAYS -batch " . 
+			"-keyfile ${CATOP}/private/$CAKEY -selfsign " .
+			"-extensions v3_ca " .
+			"-infiles ${CATOP}/$CAREQ ");
+		    $RET=$?;
+		}
+	    }
+	} elsif (/^-pkcs12$/) {
+	    my $cname = $ARGV[1];
+	    $cname = "My Certificate" unless defined $cname;
+	    system ("$PKCS12 -in newcert.pem -inkey newkey.pem " .
+			"-certfile ${CATOP}/$CACERT -out newcert.p12 " .
+			"-export -name \"$cname\"");
+	    $RET=$?;
+	    print "PKCS #12 file is in newcert.p12\n";
+	    exit $RET;
+	} elsif (/^-xsign$/) {
+	    system ("$CA -policy policy_anything -infiles newreq.pem");
+	    $RET=$?;
+	} elsif (/^(-sign|-signreq)$/) {
+	    system ("$CA -policy policy_anything -out newcert.pem " .
+							"-infiles newreq.pem");
+	    $RET=$?;
+	    print "Signed certificate is in newcert.pem\n";
+	} elsif (/^(-signCA)$/) {
+	    system ("$CA -policy policy_anything -out newcert.pem " .
+					"-extensions v3_ca -infiles newreq.pem");
+	    $RET=$?;
+	    print "Signed CA certificate is in newcert.pem\n";
+	} elsif (/^-signcert$/) {
+	    system ("$X509 -x509toreq -in newreq.pem -signkey newreq.pem " .
+								"-out tmp.pem");
+	    system ("$CA -policy policy_anything -out newcert.pem " .
+							"-infiles tmp.pem");
+	    $RET = $?;
+	    print "Signed certificate is in newcert.pem\n";
+	} elsif (/^-verify$/) {
+	    if (shift) {
+		foreach $j (@ARGV) {
+		    system ("$VERIFY -CAfile $CATOP/$CACERT $j");
+		    $RET=$? if ($? != 0);
+		}
+		exit $RET;
+	    } else {
+		    system ("$VERIFY -CAfile $CATOP/$CACERT newcert.pem");
+		    $RET=$?;
+	    	    exit 0;
+	    }
+	} else {
+	    print STDERR "Unknown arg $_\n";
+	    print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n";
+	    exit 1;
+	}
+}
+
+exit $RET;
+
+sub cp_pem {
+my ($infile, $outfile, $bound) = @_;
+open IN, $infile;
+open OUT, ">$outfile";
+my $flag = 0;
+while (<IN>) {
+	$flag = 1 if (/^-----BEGIN.*$bound/) ;
+	print OUT $_ if ($flag);
+	if (/^-----END.*$bound/) {
+		close IN;
+		close OUT;
+		return;
+	}
+}
+}
+
diff --git a/openssl/apps/CA.sh b/openssl/apps/CA.sh
new file mode 100644
index 0000000..7ad6b8c
--- /dev/null
+++ b/openssl/apps/CA.sh
@@ -0,0 +1,198 @@
+#!/bin/sh
+#
+# CA - wrapper around ca to make it easier to use ... basically ca requires
+#      some setup stuff to be done before you can use it and this makes
+#      things easier between now and when Eric is convinced to fix it :-)
+#
+# CA -newca ... will setup the right stuff
+# CA -newreq ... will generate a certificate request
+# CA -sign ... will sign the generated request and output
+#
+# At the end of that grab newreq.pem and newcert.pem (one has the key
+# and the other the certificate) and cat them together and that is what
+# you want/need ... I'll make even this a little cleaner later.
+#
+#
+# 12-Jan-96 tjh    Added more things ... including CA -signcert which
+#                  converts a certificate to a request and then signs it.
+# 10-Jan-96 eay    Fixed a few more bugs and added the SSLEAY_CONFIG
+#                  environment variable so this can be driven from
+#                  a script.
+# 25-Jul-96 eay    Cleaned up filenames some more.
+# 11-Jun-96 eay    Fixed a few filename missmatches.
+# 03-May-96 eay    Modified to use 'ssleay cmd' instead of 'cmd'.
+# 18-Apr-96 tjh    Original hacking
+#
+# Tim Hudson
+# tjh@cryptsoft.com
+#
+
+# default openssl.cnf file has setup as per the following
+# demoCA ... where everything is stored
+cp_pem() {
+    infile=$1
+    outfile=$2
+    bound=$3
+    flag=0
+    exec <$infile;
+    while read line; do
+	if [ $flag -eq 1 ]; then
+		echo $line|grep "^-----END.*$bound"  2>/dev/null 1>/dev/null
+		if [ $? -eq 0 ] ; then
+			echo $line >>$outfile
+			break
+		else
+			echo $line >>$outfile
+		fi
+	fi
+
+	echo $line|grep "^-----BEGIN.*$bound"  2>/dev/null 1>/dev/null
+	if [ $? -eq 0 ]; then
+		echo $line >$outfile
+		flag=1
+	fi
+    done
+}
+
+usage() {
+ echo "usage: $0 -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify" >&2
+}
+
+if [ -z "$OPENSSL" ]; then OPENSSL=openssl; fi
+
+if [ -z "$DAYS" ] ; then DAYS="-days 365" ; fi	# 1 year
+CADAYS="-days 1095"	# 3 years
+REQ="$OPENSSL req $SSLEAY_CONFIG"
+CA="$OPENSSL ca $SSLEAY_CONFIG"
+VERIFY="$OPENSSL verify"
+X509="$OPENSSL x509"
+PKCS12="openssl pkcs12"
+
+if [ -z "$CATOP" ] ; then CATOP=./demoCA ; fi
+CAKEY=./cakey.pem
+CAREQ=./careq.pem
+CACERT=./cacert.pem
+
+RET=0
+
+while [ "$1" != "" ] ; do
+case $1 in
+-\?|-h|-help)
+    usage
+    exit 0
+    ;;
+-newcert)
+    # create a certificate
+    $REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS
+    RET=$?
+    echo "Certificate is in newcert.pem, private key is in newkey.pem"
+    ;;
+-newreq)
+    # create a certificate request
+    $REQ -new -keyout newkey.pem -out newreq.pem $DAYS
+    RET=$?
+    echo "Request is in newreq.pem, private key is in newkey.pem"
+    ;;
+-newreq-nodes) 
+    # create a certificate request
+    $REQ -new -nodes -keyout newreq.pem -out newreq.pem $DAYS
+    RET=$?
+    echo "Request (and private key) is in newreq.pem"
+    ;;
+-newca)
+    # if explicitly asked for or it doesn't exist then setup the directory
+    # structure that Eric likes to manage things
+    NEW="1"
+    if [ "$NEW" -o ! -f ${CATOP}/serial ]; then
+	# create the directory hierarchy
+	mkdir -p ${CATOP}
+	mkdir -p ${CATOP}/certs
+	mkdir -p ${CATOP}/crl
+	mkdir -p ${CATOP}/newcerts
+	mkdir -p ${CATOP}/private
+	touch ${CATOP}/index.txt
+    fi
+    if [ ! -f ${CATOP}/private/$CAKEY ]; then
+	echo "CA certificate filename (or enter to create)"
+	read FILE
+
+	# ask user for existing CA certificate
+	if [ "$FILE" ]; then
+	    cp_pem $FILE ${CATOP}/private/$CAKEY PRIVATE
+	    cp_pem $FILE ${CATOP}/$CACERT CERTIFICATE
+	    RET=$?
+	    if [ ! -f "${CATOP}/serial" ]; then
+		$X509 -in ${CATOP}/$CACERT -noout -next_serial \
+		      -out ${CATOP}/serial
+	    fi
+	else
+	    echo "Making CA certificate ..."
+	    $REQ -new -keyout ${CATOP}/private/$CAKEY \
+			   -out ${CATOP}/$CAREQ
+	    $CA -create_serial -out ${CATOP}/$CACERT $CADAYS -batch \
+			   -keyfile ${CATOP}/private/$CAKEY -selfsign \
+			   -extensions v3_ca \
+			   -infiles ${CATOP}/$CAREQ
+	    RET=$?
+	fi
+    fi
+    ;;
+-xsign)
+    $CA -policy policy_anything -infiles newreq.pem
+    RET=$?
+    ;;
+-pkcs12)
+    if [ -z "$2" ] ; then
+	CNAME="My Certificate"
+    else
+	CNAME="$2"
+    fi
+    $PKCS12 -in newcert.pem -inkey newreq.pem -certfile ${CATOP}/$CACERT \
+	    -out newcert.p12 -export -name "$CNAME"
+    RET=$?
+    exit $RET
+    ;;
+-sign|-signreq)
+    $CA -policy policy_anything -out newcert.pem -infiles newreq.pem
+    RET=$?
+    cat newcert.pem
+    echo "Signed certificate is in newcert.pem"
+    ;;
+-signCA)
+    $CA -policy policy_anything -out newcert.pem -extensions v3_ca -infiles newreq.pem
+    RET=$?
+    echo "Signed CA certificate is in newcert.pem"
+    ;;
+-signcert)
+    echo "Cert passphrase will be requested twice - bug?"
+    $X509 -x509toreq -in newreq.pem -signkey newreq.pem -out tmp.pem
+    $CA -policy policy_anything -out newcert.pem -infiles tmp.pem
+    RET=$?
+    cat newcert.pem
+    echo "Signed certificate is in newcert.pem"
+    ;;
+-verify)
+    shift
+    if [ -z "$1" ]; then
+	    $VERIFY -CAfile $CATOP/$CACERT newcert.pem
+	    RET=$?
+    else
+	for j
+	do
+	    $VERIFY -CAfile $CATOP/$CACERT $j
+	    if [ $? != 0 ]; then
+		    RET=$?
+	    fi
+	done
+    fi
+    exit $RET
+    ;;
+*)
+    echo "Unknown arg $i" >&2
+    usage
+    exit 1
+    ;;
+esac
+shift
+done
+exit $RET
diff --git a/openssl/apps/Makefile b/openssl/apps/Makefile
new file mode 100644
index 0000000..fa32d2d
--- /dev/null
+++ b/openssl/apps/Makefile
@@ -0,0 +1,1035 @@
+#
+#  apps/Makefile
+#
+
+DIR=		apps
+TOP=		..
+CC=		cc
+INCLUDES=	-I$(TOP) -I../include $(KRB5_INCLUDES)
+CFLAG=		-g -static
+MAKEFILE=	Makefile
+PERL=		perl
+RM=		rm -f
+# KRB5 stuff
+KRB5_INCLUDES=
+LIBKRB5=
+
+PEX_LIBS=
+EX_LIBS= 
+EXE_EXT= 
+
+SHLIB_TARGET=
+
+CFLAGS= -DMONOLITH $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile makeapps.com install.com
+
+DLIBCRYPTO=../libcrypto.a
+DLIBSSL=../libssl.a
+LIBCRYPTO=-L.. -lcrypto
+LIBSSL=-L.. -lssl
+
+PROGRAM= openssl
+
+SCRIPTS=CA.sh CA.pl tsget
+
+EXE= $(PROGRAM)$(EXE_EXT)
+
+E_EXE=	verify asn1pars req dgst dh dhparam enc passwd gendh errstr \
+	ca crl rsa rsautl dsa dsaparam ec ecparam \
+	x509 genrsa gendsa genpkey s_server s_client speed \
+	s_time version pkcs7 cms crl2pkcs7 sess_id ciphers nseq pkcs12 \
+	pkcs8 pkey pkeyparam pkeyutl spkac smime rand engine ocsp prime ts
+
+PROGS= $(PROGRAM).c
+
+A_OBJ=apps.o
+A_SRC=apps.c
+S_OBJ=	s_cb.o s_socket.o
+S_SRC=	s_cb.c s_socket.c
+RAND_OBJ=app_rand.o
+RAND_SRC=app_rand.c
+
+E_OBJ=	verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o errstr.o \
+	ca.o pkcs7.o crl2p7.o crl.o \
+	rsa.o rsautl.o dsa.o dsaparam.o ec.o ecparam.o \
+	x509.o genrsa.o gendsa.o genpkey.o s_server.o s_client.o speed.o \
+	s_time.o $(A_OBJ) $(S_OBJ) $(RAND_OBJ) version.o sess_id.o \
+	ciphers.o nseq.o pkcs12.o pkcs8.o pkey.o pkeyparam.o pkeyutl.o \
+	spkac.o smime.o cms.o rand.o engine.o ocsp.o prime.o ts.o
+
+E_SRC=	verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca.c \
+	pkcs7.c crl2p7.c crl.c \
+	rsa.c rsautl.c dsa.c dsaparam.c ec.c ecparam.c \
+	x509.c genrsa.c gendsa.c genpkey.c s_server.c s_client.c speed.c \
+	s_time.c $(A_SRC) $(S_SRC) $(RAND_SRC) version.c sess_id.c \
+	ciphers.c nseq.c pkcs12.c pkcs8.c pkey.c pkeyparam.c pkeyutl.c \
+	spkac.c smime.c cms.c rand.c engine.c ocsp.c prime.c ts.c
+
+SRC=$(E_SRC)
+
+EXHEADER=
+HEADER=	apps.h progs.h s_apps.h \
+	testdsa.h testrsa.h \
+	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	@(cd ..; $(MAKE) DIRS=$(DIR) all)
+
+all:	exe
+
+exe:	$(EXE)
+
+req: sreq.o $(A_OBJ) $(DLIBCRYPTO)
+	shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \
+		shlib_target="$(SHLIB_TARGET)"; \
+	fi; \
+	$(MAKE) -f $(TOP)/Makefile.shared -e \
+		APPNAME=req OBJECTS="sreq.o $(A_OBJ) $(RAND_OBJ)" \
+		LIBDEPS="$(PEX_LIBS) $(LIBCRYPTO) $(EX_LIBS)" \
+		link_app.$${shlib_target}
+
+sreq.o: req.c 
+	$(CC) -c $(INCLUDES) $(CFLAG) -o sreq.o req.c
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@set -e; for i in $(EXE); \
+	do  \
+	(echo installing $$i; \
+	 cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
+	 chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
+	 mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i ); \
+	 done;
+	@set -e; for i in $(SCRIPTS); \
+	do  \
+	(echo installing $$i; \
+	 cp $$i $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
+	 chmod 755 $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
+	 mv -f $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i ); \
+	 done
+	@cp openssl.cnf $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new; \
+	chmod 644 $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new; \
+	mv -f  $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+links:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@if [ -z "$(THIS)" ]; then \
+	    $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
+	else \
+	    $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(SRC); \
+	fi
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+	rm -f CA.pl
+
+clean:
+	rm -f *.o *.obj *.dll lib tags core .pure .nfs* *.old *.bak fluff $(EXE)
+	rm -f req
+
+$(DLIBSSL):
+	(cd ..; $(MAKE) DIRS=ssl all)
+
+$(DLIBCRYPTO):
+	(cd ..; $(MAKE) DIRS=crypto all)
+
+$(EXE): progs.h $(E_OBJ) $(PROGRAM).o $(DLIBCRYPTO) $(DLIBSSL)
+	$(RM) $(EXE)
+	shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \
+		shlib_target="$(SHLIB_TARGET)"; \
+	fi; \
+	LIBRARIES="$(LIBSSL) $(LIBKRB5) $(LIBCRYPTO)" ; \
+	$(MAKE) -f $(TOP)/Makefile.shared -e \
+		APPNAME=$(EXE) OBJECTS="$(PROGRAM).o $(E_OBJ)" \
+		LIBDEPS="$(PEX_LIBS) $$LIBRARIES $(EX_LIBS)" \
+		link_app.$${shlib_target}
+	@(cd ..; $(MAKE) rehash)
+
+progs.h: progs.pl
+	$(PERL) progs.pl $(E_EXE) >progs.h
+	$(RM) $(PROGRAM).o
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+app_rand.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+app_rand.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+app_rand.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+app_rand.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+app_rand.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+app_rand.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+app_rand.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+app_rand.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+app_rand.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+app_rand.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+app_rand.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+app_rand.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+app_rand.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+app_rand.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h
+app_rand.o: app_rand.c apps.h
+apps.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+apps.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+apps.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+apps.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+apps.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+apps.o: ../include/openssl/engine.h ../include/openssl/err.h
+apps.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+apps.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+apps.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+apps.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+apps.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+apps.o: ../include/openssl/pkcs12.h ../include/openssl/pkcs7.h
+apps.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+apps.o: ../include/openssl/sha.h ../include/openssl/stack.h
+apps.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+apps.o: ../include/openssl/ui.h ../include/openssl/x509.h
+apps.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.c apps.h
+asn1pars.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+asn1pars.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+asn1pars.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+asn1pars.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+asn1pars.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+asn1pars.o: ../include/openssl/err.h ../include/openssl/evp.h
+asn1pars.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+asn1pars.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+asn1pars.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+asn1pars.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+asn1pars.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+asn1pars.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+asn1pars.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+asn1pars.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+asn1pars.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+asn1pars.o: asn1pars.c
+ca.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ca.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+ca.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+ca.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ca.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+ca.o: ../include/openssl/engine.h ../include/openssl/err.h
+ca.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+ca.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ca.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+ca.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ca.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+ca.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+ca.o: ../include/openssl/sha.h ../include/openssl/stack.h
+ca.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+ca.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+ca.o: ../include/openssl/x509v3.h apps.h ca.c
+ciphers.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ciphers.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ciphers.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+ciphers.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ciphers.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ciphers.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+ciphers.o: ../include/openssl/err.h ../include/openssl/evp.h
+ciphers.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+ciphers.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ciphers.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+ciphers.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ciphers.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ciphers.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ciphers.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
+ciphers.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+ciphers.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ciphers.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ciphers.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ciphers.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+ciphers.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+ciphers.o: ciphers.c
+cms.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+cms.o: ../include/openssl/buffer.h ../include/openssl/cms.h
+cms.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+cms.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+cms.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+cms.o: ../include/openssl/engine.h ../include/openssl/err.h
+cms.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+cms.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+cms.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+cms.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+cms.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+cms.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+cms.o: ../include/openssl/sha.h ../include/openssl/stack.h
+cms.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+cms.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+cms.o: ../include/openssl/x509v3.h apps.h cms.c
+crl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+crl.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+crl.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+crl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+crl.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+crl.o: ../include/openssl/err.h ../include/openssl/evp.h
+crl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+crl.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+crl.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+crl.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+crl.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+crl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+crl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+crl.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+crl.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h crl.c
+crl2p7.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+crl2p7.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+crl2p7.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+crl2p7.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+crl2p7.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+crl2p7.o: ../include/openssl/err.h ../include/openssl/evp.h
+crl2p7.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+crl2p7.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+crl2p7.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+crl2p7.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+crl2p7.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+crl2p7.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+crl2p7.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+crl2p7.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+crl2p7.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+crl2p7.o: crl2p7.c
+dgst.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+dgst.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+dgst.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+dgst.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+dgst.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+dgst.o: ../include/openssl/err.h ../include/openssl/evp.h
+dgst.o: ../include/openssl/hmac.h ../include/openssl/lhash.h
+dgst.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+dgst.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+dgst.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+dgst.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+dgst.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+dgst.o: ../include/openssl/sha.h ../include/openssl/stack.h
+dgst.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+dgst.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+dgst.o: ../include/openssl/x509v3.h apps.h dgst.c
+dh.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+dh.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+dh.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+dh.o: ../include/openssl/dh.h ../include/openssl/e_os2.h
+dh.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+dh.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+dh.o: ../include/openssl/err.h ../include/openssl/evp.h
+dh.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+dh.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+dh.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+dh.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+dh.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+dh.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+dh.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+dh.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+dh.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h dh.c
+dsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+dsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+dsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+dsa.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
+dsa.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+dsa.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+dsa.o: ../include/openssl/err.h ../include/openssl/evp.h
+dsa.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+dsa.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+dsa.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+dsa.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+dsa.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+dsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+dsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+dsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+dsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h dsa.c
+dsaparam.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+dsaparam.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+dsaparam.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+dsaparam.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+dsaparam.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+dsaparam.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+dsaparam.o: ../include/openssl/engine.h ../include/openssl/err.h
+dsaparam.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+dsaparam.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+dsaparam.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+dsaparam.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+dsaparam.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+dsaparam.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+dsaparam.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+dsaparam.o: ../include/openssl/sha.h ../include/openssl/stack.h
+dsaparam.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+dsaparam.o: ../include/openssl/ui.h ../include/openssl/x509.h
+dsaparam.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+dsaparam.o: dsaparam.c
+ec.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ec.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+ec.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+ec.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ec.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+ec.o: ../include/openssl/err.h ../include/openssl/evp.h
+ec.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ec.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+ec.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ec.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ec.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ec.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ec.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ec.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+ec.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h ec.c
+ecparam.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ecparam.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+ecparam.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+ecparam.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ecparam.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+ecparam.o: ../include/openssl/engine.h ../include/openssl/err.h
+ecparam.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+ecparam.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ecparam.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+ecparam.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ecparam.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+ecparam.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+ecparam.o: ../include/openssl/sha.h ../include/openssl/stack.h
+ecparam.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+ecparam.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+ecparam.o: ../include/openssl/x509v3.h apps.h ecparam.c
+enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+enc.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+enc.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+enc.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+enc.o: ../include/openssl/engine.h ../include/openssl/err.h
+enc.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+enc.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+enc.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+enc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+enc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+enc.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+enc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+enc.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+enc.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h enc.c
+engine.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+engine.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+engine.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+engine.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+engine.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+engine.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+engine.o: ../include/openssl/err.h ../include/openssl/evp.h
+engine.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+engine.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+engine.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+engine.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+engine.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+engine.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+engine.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
+engine.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+engine.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+engine.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+engine.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+engine.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+engine.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+engine.o: engine.c
+errstr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+errstr.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+errstr.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+errstr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+errstr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+errstr.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+errstr.o: ../include/openssl/err.h ../include/openssl/evp.h
+errstr.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+errstr.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+errstr.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+errstr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+errstr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+errstr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+errstr.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
+errstr.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+errstr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+errstr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+errstr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+errstr.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+errstr.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+errstr.o: errstr.c
+gendh.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+gendh.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+gendh.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+gendh.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+gendh.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+gendh.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+gendh.o: ../include/openssl/engine.h ../include/openssl/err.h
+gendh.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+gendh.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+gendh.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+gendh.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+gendh.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+gendh.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+gendh.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+gendh.o: ../include/openssl/sha.h ../include/openssl/stack.h
+gendh.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+gendh.o: ../include/openssl/ui.h ../include/openssl/x509.h
+gendh.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+gendh.o: gendh.c
+gendsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+gendsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+gendsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+gendsa.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
+gendsa.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+gendsa.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+gendsa.o: ../include/openssl/err.h ../include/openssl/evp.h
+gendsa.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+gendsa.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+gendsa.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+gendsa.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+gendsa.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+gendsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+gendsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+gendsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+gendsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+gendsa.o: gendsa.c
+genpkey.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+genpkey.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+genpkey.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+genpkey.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+genpkey.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+genpkey.o: ../include/openssl/err.h ../include/openssl/evp.h
+genpkey.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+genpkey.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+genpkey.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+genpkey.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+genpkey.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+genpkey.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+genpkey.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+genpkey.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+genpkey.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+genpkey.o: genpkey.c
+genrsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+genrsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+genrsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+genrsa.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+genrsa.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+genrsa.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+genrsa.o: ../include/openssl/engine.h ../include/openssl/err.h
+genrsa.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+genrsa.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+genrsa.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+genrsa.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+genrsa.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+genrsa.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+genrsa.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+genrsa.o: ../include/openssl/sha.h ../include/openssl/stack.h
+genrsa.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+genrsa.o: ../include/openssl/ui.h ../include/openssl/x509.h
+genrsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+genrsa.o: genrsa.c
+nseq.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+nseq.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+nseq.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+nseq.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+nseq.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+nseq.o: ../include/openssl/err.h ../include/openssl/evp.h
+nseq.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+nseq.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+nseq.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+nseq.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+nseq.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+nseq.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+nseq.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+nseq.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+nseq.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h nseq.c
+ocsp.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ocsp.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+ocsp.o: ../include/openssl/comp.h ../include/openssl/conf.h
+ocsp.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
+ocsp.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ocsp.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+ocsp.o: ../include/openssl/engine.h ../include/openssl/err.h
+ocsp.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+ocsp.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+ocsp.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ocsp.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+ocsp.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ocsp.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+ocsp.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+ocsp.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ocsp.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ocsp.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ocsp.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ocsp.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
+ocsp.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+ocsp.o: ../include/openssl/x509v3.h apps.h ocsp.c
+openssl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+openssl.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+openssl.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+openssl.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+openssl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+openssl.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+openssl.o: ../include/openssl/err.h ../include/openssl/evp.h
+openssl.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+openssl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+openssl.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+openssl.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+openssl.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+openssl.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+openssl.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
+openssl.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+openssl.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+openssl.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+openssl.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+openssl.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+openssl.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+openssl.o: openssl.c progs.h s_apps.h
+passwd.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+passwd.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+passwd.o: ../include/openssl/crypto.h ../include/openssl/des.h
+passwd.o: ../include/openssl/des_old.h ../include/openssl/e_os2.h
+passwd.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+passwd.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+passwd.o: ../include/openssl/err.h ../include/openssl/evp.h
+passwd.o: ../include/openssl/lhash.h ../include/openssl/md5.h
+passwd.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+passwd.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+passwd.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+passwd.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+passwd.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+passwd.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+passwd.o: ../include/openssl/txt_db.h ../include/openssl/ui.h
+passwd.o: ../include/openssl/ui_compat.h ../include/openssl/x509.h
+passwd.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+passwd.o: passwd.c
+pkcs12.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+pkcs12.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+pkcs12.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+pkcs12.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+pkcs12.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+pkcs12.o: ../include/openssl/err.h ../include/openssl/evp.h
+pkcs12.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+pkcs12.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+pkcs12.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+pkcs12.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+pkcs12.o: ../include/openssl/pem2.h ../include/openssl/pkcs12.h
+pkcs12.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+pkcs12.o: ../include/openssl/sha.h ../include/openssl/stack.h
+pkcs12.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+pkcs12.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+pkcs12.o: ../include/openssl/x509v3.h apps.h pkcs12.c
+pkcs7.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+pkcs7.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+pkcs7.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+pkcs7.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+pkcs7.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+pkcs7.o: ../include/openssl/err.h ../include/openssl/evp.h
+pkcs7.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+pkcs7.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+pkcs7.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+pkcs7.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+pkcs7.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+pkcs7.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+pkcs7.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+pkcs7.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+pkcs7.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+pkcs7.o: pkcs7.c
+pkcs8.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+pkcs8.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+pkcs8.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+pkcs8.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+pkcs8.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+pkcs8.o: ../include/openssl/err.h ../include/openssl/evp.h
+pkcs8.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+pkcs8.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+pkcs8.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+pkcs8.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+pkcs8.o: ../include/openssl/pem2.h ../include/openssl/pkcs12.h
+pkcs8.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+pkcs8.o: ../include/openssl/sha.h ../include/openssl/stack.h
+pkcs8.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+pkcs8.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+pkcs8.o: ../include/openssl/x509v3.h apps.h pkcs8.c
+pkey.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+pkey.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+pkey.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+pkey.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+pkey.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+pkey.o: ../include/openssl/err.h ../include/openssl/evp.h
+pkey.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+pkey.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+pkey.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+pkey.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+pkey.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+pkey.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+pkey.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+pkey.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+pkey.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h pkey.c
+pkeyparam.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+pkeyparam.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+pkeyparam.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+pkeyparam.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+pkeyparam.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+pkeyparam.o: ../include/openssl/err.h ../include/openssl/evp.h
+pkeyparam.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+pkeyparam.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+pkeyparam.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+pkeyparam.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+pkeyparam.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+pkeyparam.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+pkeyparam.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+pkeyparam.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+pkeyparam.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+pkeyparam.o: pkeyparam.c
+pkeyutl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+pkeyutl.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+pkeyutl.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+pkeyutl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+pkeyutl.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+pkeyutl.o: ../include/openssl/err.h ../include/openssl/evp.h
+pkeyutl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+pkeyutl.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+pkeyutl.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+pkeyutl.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+pkeyutl.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+pkeyutl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+pkeyutl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+pkeyutl.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+pkeyutl.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+pkeyutl.o: pkeyutl.c
+prime.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+prime.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+prime.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+prime.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+prime.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+prime.o: ../include/openssl/engine.h ../include/openssl/evp.h
+prime.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+prime.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+prime.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+prime.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+prime.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+prime.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+prime.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+prime.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+prime.o: prime.c
+rand.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+rand.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+rand.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+rand.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+rand.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+rand.o: ../include/openssl/err.h ../include/openssl/evp.h
+rand.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+rand.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+rand.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+rand.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+rand.o: ../include/openssl/rand.h ../include/openssl/safestack.h
+rand.o: ../include/openssl/sha.h ../include/openssl/stack.h
+rand.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+rand.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+rand.o: ../include/openssl/x509v3.h apps.h rand.c
+req.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+req.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+req.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+req.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+req.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+req.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+req.o: ../include/openssl/engine.h ../include/openssl/err.h
+req.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+req.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+req.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+req.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+req.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+req.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+req.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+req.o: ../include/openssl/sha.h ../include/openssl/stack.h
+req.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+req.o: ../include/openssl/ui.h ../include/openssl/x509.h
+req.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h req.c
+rsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+rsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+rsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+rsa.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+rsa.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+rsa.o: ../include/openssl/engine.h ../include/openssl/err.h
+rsa.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+rsa.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+rsa.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+rsa.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+rsa.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+rsa.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h
+rsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+rsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+rsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+rsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h rsa.c
+rsautl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+rsautl.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+rsautl.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+rsautl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+rsautl.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+rsautl.o: ../include/openssl/err.h ../include/openssl/evp.h
+rsautl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+rsautl.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+rsautl.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+rsautl.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+rsautl.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+rsautl.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+rsautl.o: ../include/openssl/sha.h ../include/openssl/stack.h
+rsautl.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+rsautl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+rsautl.o: ../include/openssl/x509v3.h apps.h rsautl.c
+s_cb.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s_cb.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s_cb.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+s_cb.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s_cb.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s_cb.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+s_cb.o: ../include/openssl/err.h ../include/openssl/evp.h
+s_cb.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+s_cb.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+s_cb.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+s_cb.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s_cb.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s_cb.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s_cb.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s_cb.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s_cb.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s_cb.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s_cb.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s_cb.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
+s_cb.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+s_cb.o: ../include/openssl/x509v3.h apps.h s_apps.h s_cb.c
+s_client.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s_client.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+s_client.o: ../include/openssl/comp.h ../include/openssl/conf.h
+s_client.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
+s_client.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+s_client.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+s_client.o: ../include/openssl/engine.h ../include/openssl/err.h
+s_client.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s_client.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s_client.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s_client.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+s_client.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+s_client.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+s_client.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+s_client.o: ../include/openssl/rand.h ../include/openssl/safestack.h
+s_client.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s_client.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s_client.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s_client.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s_client.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+s_client.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+s_client.o: s_apps.h s_client.c timeouts.h
+s_server.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s_server.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+s_server.o: ../include/openssl/comp.h ../include/openssl/conf.h
+s_server.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+s_server.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
+s_server.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+s_server.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+s_server.o: ../include/openssl/engine.h ../include/openssl/err.h
+s_server.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s_server.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s_server.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s_server.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+s_server.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+s_server.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+s_server.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+s_server.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+s_server.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s_server.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s_server.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s_server.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s_server.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
+s_server.o: ../include/openssl/ui.h ../include/openssl/x509.h
+s_server.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+s_server.o: s_apps.h s_server.c timeouts.h
+s_socket.o: ../e_os.h ../e_os2.h ../include/openssl/asn1.h
+s_socket.o: ../include/openssl/bio.h ../include/openssl/buffer.h
+s_socket.o: ../include/openssl/comp.h ../include/openssl/conf.h
+s_socket.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
+s_socket.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+s_socket.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+s_socket.o: ../include/openssl/engine.h ../include/openssl/evp.h
+s_socket.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+s_socket.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+s_socket.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+s_socket.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s_socket.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s_socket.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s_socket.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
+s_socket.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s_socket.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s_socket.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s_socket.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s_socket.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+s_socket.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+s_socket.o: s_apps.h s_socket.c
+s_time.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s_time.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s_time.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+s_time.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s_time.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s_time.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+s_time.o: ../include/openssl/err.h ../include/openssl/evp.h
+s_time.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+s_time.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+s_time.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+s_time.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s_time.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s_time.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s_time.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
+s_time.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s_time.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s_time.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s_time.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s_time.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+s_time.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+s_time.o: s_apps.h s_time.c
+sess_id.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+sess_id.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+sess_id.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+sess_id.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+sess_id.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+sess_id.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+sess_id.o: ../include/openssl/err.h ../include/openssl/evp.h
+sess_id.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+sess_id.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+sess_id.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+sess_id.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+sess_id.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+sess_id.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+sess_id.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
+sess_id.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+sess_id.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+sess_id.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+sess_id.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+sess_id.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+sess_id.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+sess_id.o: sess_id.c
+smime.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+smime.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+smime.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+smime.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+smime.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+smime.o: ../include/openssl/err.h ../include/openssl/evp.h
+smime.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+smime.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+smime.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+smime.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+smime.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+smime.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+smime.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+smime.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+smime.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+smime.o: smime.c
+speed.o: ../e_os.h ../include/openssl/aes.h ../include/openssl/asn1.h
+speed.o: ../include/openssl/bio.h ../include/openssl/blowfish.h
+speed.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+speed.o: ../include/openssl/camellia.h ../include/openssl/cast.h
+speed.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+speed.o: ../include/openssl/des.h ../include/openssl/des_old.h
+speed.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
+speed.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+speed.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+speed.o: ../include/openssl/err.h ../include/openssl/evp.h
+speed.o: ../include/openssl/hmac.h ../include/openssl/idea.h
+speed.o: ../include/openssl/lhash.h ../include/openssl/md4.h
+speed.o: ../include/openssl/md5.h ../include/openssl/mdc2.h
+speed.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+speed.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+speed.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+speed.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+speed.o: ../include/openssl/rc2.h ../include/openssl/rc4.h
+speed.o: ../include/openssl/ripemd.h ../include/openssl/rsa.h
+speed.o: ../include/openssl/safestack.h ../include/openssl/seed.h
+speed.o: ../include/openssl/sha.h ../include/openssl/stack.h
+speed.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+speed.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h
+speed.o: ../include/openssl/whrlpool.h ../include/openssl/x509.h
+speed.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+speed.o: speed.c testdsa.h testrsa.h
+spkac.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+spkac.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+spkac.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+spkac.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+spkac.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+spkac.o: ../include/openssl/err.h ../include/openssl/evp.h
+spkac.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+spkac.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+spkac.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+spkac.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+spkac.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+spkac.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+spkac.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+spkac.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+spkac.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+spkac.o: spkac.c
+ts.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ts.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+ts.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+ts.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+ts.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ts.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+ts.o: ../include/openssl/engine.h ../include/openssl/err.h
+ts.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+ts.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ts.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+ts.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ts.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+ts.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+ts.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+ts.o: ../include/openssl/sha.h ../include/openssl/stack.h
+ts.o: ../include/openssl/symhacks.h ../include/openssl/ts.h
+ts.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+ts.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h ts.c
+verify.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+verify.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+verify.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+verify.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+verify.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+verify.o: ../include/openssl/err.h ../include/openssl/evp.h
+verify.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+verify.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+verify.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+verify.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+verify.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+verify.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+verify.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+verify.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+verify.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+verify.o: verify.c
+version.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+version.o: ../include/openssl/blowfish.h ../include/openssl/bn.h
+version.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+version.o: ../include/openssl/crypto.h ../include/openssl/des.h
+version.o: ../include/openssl/des_old.h ../include/openssl/e_os2.h
+version.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+version.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+version.o: ../include/openssl/evp.h ../include/openssl/idea.h
+version.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+version.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+version.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+version.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+version.o: ../include/openssl/rc4.h ../include/openssl/safestack.h
+version.o: ../include/openssl/sha.h ../include/openssl/stack.h
+version.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+version.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h
+version.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+version.o: ../include/openssl/x509v3.h apps.h version.c
+x509.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+x509.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+x509.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+x509.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
+x509.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+x509.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+x509.o: ../include/openssl/err.h ../include/openssl/evp.h
+x509.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+x509.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+x509.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+x509.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+x509.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+x509.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+x509.o: ../include/openssl/sha.h ../include/openssl/stack.h
+x509.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+x509.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+x509.o: ../include/openssl/x509v3.h apps.h x509.c
diff --git a/openssl/apps/app_rand.c b/openssl/apps/app_rand.c
new file mode 100644
index 0000000..b7b6128
--- /dev/null
+++ b/openssl/apps/app_rand.c
@@ -0,0 +1,218 @@
+/* apps/app_rand.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#define NON_MAIN
+#include "apps.h"
+#undef NON_MAIN
+#include <openssl/bio.h>
+#include <openssl/rand.h>
+
+
+static int seeded = 0;
+static int egdsocket = 0;
+
+int app_RAND_load_file(const char *file, BIO *bio_e, int dont_warn)
+	{
+	int consider_randfile = (file == NULL);
+	char buffer[200];
+	
+#ifdef OPENSSL_SYS_WINDOWS
+	BIO_printf(bio_e,"Loading 'screen' into random state -");
+	BIO_flush(bio_e);
+	RAND_screen();
+	BIO_printf(bio_e," done\n");
+#endif
+
+	if (file == NULL)
+		file = RAND_file_name(buffer, sizeof buffer);
+	else if (RAND_egd(file) > 0)
+		{
+		/* we try if the given filename is an EGD socket.
+		   if it is, we don't write anything back to the file. */
+		egdsocket = 1;
+		return 1;
+		}
+	if (file == NULL || !RAND_load_file(file, -1))
+		{
+		if (RAND_status() == 0)
+			{
+			if (!dont_warn)
+				{
+				BIO_printf(bio_e,"unable to load 'random state'\n");
+				BIO_printf(bio_e,"This means that the random number generator has not been seeded\n");
+				BIO_printf(bio_e,"with much random data.\n");
+				if (consider_randfile) /* explanation does not apply when a file is explicitly named */
+					{
+					BIO_printf(bio_e,"Consider setting the RANDFILE environment variable to point at a file that\n");
+					BIO_printf(bio_e,"'random' data can be kept in (the file will be overwritten).\n");
+					}
+				}
+			return 0;
+			}
+		}
+	seeded = 1;
+	return 1;
+	}
+
+long app_RAND_load_files(char *name)
+	{
+	char *p,*n;
+	int last;
+	long tot=0;
+	int egd;
+	
+	for (;;)
+		{
+		last=0;
+		for (p=name; ((*p != '\0') && (*p != LIST_SEPARATOR_CHAR)); p++);
+		if (*p == '\0') last=1;
+		*p='\0';
+		n=name;
+		name=p+1;
+		if (*n == '\0') break;
+
+		egd=RAND_egd(n);
+		if (egd > 0)
+			tot+=egd;
+		else
+			tot+=RAND_load_file(n,-1);
+		if (last) break;
+		}
+	if (tot > 512)
+		app_RAND_allow_write_file();
+	return(tot);
+	}
+
+int app_RAND_write_file(const char *file, BIO *bio_e)
+	{
+	char buffer[200];
+	
+	if (egdsocket || !seeded)
+		/* If we did not manage to read the seed file,
+		 * we should not write a low-entropy seed file back --
+		 * it would suppress a crucial warning the next time
+		 * we want to use it. */
+		return 0;
+
+	if (file == NULL)
+		file = RAND_file_name(buffer, sizeof buffer);
+	if (file == NULL || !RAND_write_file(file))
+		{
+		BIO_printf(bio_e,"unable to write 'random state'\n");
+		return 0;
+		}
+	return 1;
+	}
+
+void app_RAND_allow_write_file(void)
+	{
+	seeded = 1;
+	}
diff --git a/openssl/apps/apps.c b/openssl/apps/apps.c
new file mode 100644
index 0000000..38e6197
--- /dev/null
+++ b/openssl/apps/apps.c
@@ -0,0 +1,3063 @@
+/* apps/apps.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 2	/* On VMS, you need to define this to get
+				   the declaration of fileno().  The value
+				   2 is to make sure no function defined
+				   in POSIX-2 is left undefined. */
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if !defined(OPENSSL_SYSNAME_WIN32) && !defined(NETWARE_CLIB)
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#include <ctype.h>
+#include <errno.h>
+#include <assert.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/pem.h>
+#include <openssl/pkcs12.h>
+#include <openssl/ui.h>
+#include <openssl/safestack.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_JPAKE
+#include <openssl/jpake.h>
+#endif
+
+#define NON_MAIN
+#include "apps.h"
+#undef NON_MAIN
+
+#ifdef _WIN32
+static int WIN32_rename(const char *from, const char *to);
+#define rename(from,to) WIN32_rename((from),(to))
+#endif
+
+typedef struct {
+	const char *name;
+	unsigned long flag;
+	unsigned long mask;
+} NAME_EX_TBL;
+
+static UI_METHOD *ui_method = NULL;
+
+static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl);
+static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl);
+
+#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
+/* Looks like this stuff is worth moving into separate function */
+static EVP_PKEY *
+load_netscape_key(BIO *err, BIO *key, const char *file,
+		const char *key_descrip, int format);
+#endif
+
+int app_init(long mesgwin);
+#ifdef undef /* never finished - probably never will be :-) */
+int args_from_file(char *file, int *argc, char **argv[])
+	{
+	FILE *fp;
+	int num,i;
+	unsigned int len;
+	static char *buf=NULL;
+	static char **arg=NULL;
+	char *p;
+
+	fp=fopen(file,"r");
+	if (fp == NULL)
+		return(0);
+
+	if (fseek(fp,0,SEEK_END)==0)
+		len=ftell(fp), rewind(fp);
+	else	len=-1;
+	if (len<=0)
+		{
+		fclose(fp);
+		return(0);
+		}
+
+	*argc=0;
+	*argv=NULL;
+
+	if (buf != NULL) OPENSSL_free(buf);
+	buf=(char *)OPENSSL_malloc(len+1);
+	if (buf == NULL) return(0);
+
+	len=fread(buf,1,len,fp);
+	if (len <= 1) return(0);
+	buf[len]='\0';
+
+	i=0;
+	for (p=buf; *p; p++)
+		if (*p == '\n') i++;
+	if (arg != NULL) OPENSSL_free(arg);
+	arg=(char **)OPENSSL_malloc(sizeof(char *)*(i*2));
+
+	*argv=arg;
+	num=0;
+	p=buf;
+	for (;;)
+		{
+		if (!*p) break;
+		if (*p == '#') /* comment line */
+			{
+			while (*p && (*p != '\n')) p++;
+			continue;
+			}
+		/* else we have a line */
+		*(arg++)=p;
+		num++;
+		while (*p && ((*p != ' ') && (*p != '\t') && (*p != '\n')))
+			p++;
+		if (!*p) break;
+		if (*p == '\n')
+			{
+			*(p++)='\0';
+			continue;
+			}
+		/* else it is a tab or space */
+		p++;
+		while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
+			p++;
+		if (!*p) break;
+		if (*p == '\n')
+			{
+			p++;
+			continue;
+			}
+		*(arg++)=p++;
+		num++;
+		while (*p && (*p != '\n')) p++;
+		if (!*p) break;
+		/* else *p == '\n' */
+		*(p++)='\0';
+		}
+	*argc=num;
+	return(1);
+	}
+#endif
+
+int str2fmt(char *s)
+	{
+	if (s == NULL)
+		return FORMAT_UNDEF;
+	if 	((*s == 'D') || (*s == 'd'))
+		return(FORMAT_ASN1);
+	else if ((*s == 'T') || (*s == 't'))
+		return(FORMAT_TEXT);
+  	else if ((*s == 'N') || (*s == 'n'))
+  		return(FORMAT_NETSCAPE);
+  	else if ((*s == 'S') || (*s == 's'))
+  		return(FORMAT_SMIME);
+ 	else if ((*s == 'M') || (*s == 'm'))
+ 		return(FORMAT_MSBLOB);
+	else if ((*s == '1')
+		|| (strcmp(s,"PKCS12") == 0) || (strcmp(s,"pkcs12") == 0)
+		|| (strcmp(s,"P12") == 0) || (strcmp(s,"p12") == 0))
+		return(FORMAT_PKCS12);
+	else if ((*s == 'E') || (*s == 'e'))
+		return(FORMAT_ENGINE);
+	else if ((*s == 'P') || (*s == 'p'))
+ 		{
+ 		if (s[1] == 'V' || s[1] == 'v')
+ 			return FORMAT_PVK;
+ 		else
+  			return(FORMAT_PEM);
+ 		}
+	else
+		return(FORMAT_UNDEF);
+	}
+
+#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_NETWARE)
+void program_name(char *in, char *out, int size)
+	{
+	int i,n;
+	char *p=NULL;
+
+	n=strlen(in);
+	/* find the last '/', '\' or ':' */
+	for (i=n-1; i>0; i--)
+		{
+		if ((in[i] == '/') || (in[i] == '\\') || (in[i] == ':'))
+			{
+			p= &(in[i+1]);
+			break;
+			}
+		}
+	if (p == NULL)
+		p=in;
+	n=strlen(p);
+
+#if defined(OPENSSL_SYS_NETWARE)
+   /* strip off trailing .nlm if present. */
+   if ((n > 4) && (p[n-4] == '.') &&
+      ((p[n-3] == 'n') || (p[n-3] == 'N')) &&
+      ((p[n-2] == 'l') || (p[n-2] == 'L')) &&
+      ((p[n-1] == 'm') || (p[n-1] == 'M')))
+      n-=4;
+#else
+	/* strip off trailing .exe if present. */
+	if ((n > 4) && (p[n-4] == '.') &&
+		((p[n-3] == 'e') || (p[n-3] == 'E')) &&
+		((p[n-2] == 'x') || (p[n-2] == 'X')) &&
+		((p[n-1] == 'e') || (p[n-1] == 'E')))
+		n-=4;
+#endif
+
+	if (n > size-1)
+		n=size-1;
+
+	for (i=0; i<n; i++)
+		{
+		if ((p[i] >= 'A') && (p[i] <= 'Z'))
+			out[i]=p[i]-'A'+'a';
+		else
+			out[i]=p[i];
+		}
+	out[n]='\0';
+	}
+#else
+#ifdef OPENSSL_SYS_VMS
+void program_name(char *in, char *out, int size)
+	{
+	char *p=in, *q;
+	char *chars=":]>";
+
+	while(*chars != '\0')
+		{
+		q=strrchr(p,*chars);
+		if (q > p)
+			p = q + 1;
+		chars++;
+		}
+
+	q=strrchr(p,'.');
+	if (q == NULL)
+		q = p + strlen(p);
+	strncpy(out,p,size-1);
+	if (q-p >= size)
+		{
+		out[size-1]='\0';
+		}
+	else
+		{
+		out[q-p]='\0';
+		}
+	}
+#else
+void program_name(char *in, char *out, int size)
+	{
+	char *p;
+
+	p=strrchr(in,'/');
+	if (p != NULL)
+		p++;
+	else
+		p=in;
+	BUF_strlcpy(out,p,size);
+	}
+#endif
+#endif
+
+int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[])
+	{
+	int num,i;
+	char *p;
+
+	*argc=0;
+	*argv=NULL;
+
+	i=0;
+	if (arg->count == 0)
+		{
+		arg->count=20;
+		arg->data=(char **)OPENSSL_malloc(sizeof(char *)*arg->count);
+		}
+	for (i=0; i<arg->count; i++)
+		arg->data[i]=NULL;
+
+	num=0;
+	p=buf;
+	for (;;)
+		{
+		/* first scan over white space */
+		if (!*p) break;
+		while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
+			p++;
+		if (!*p) break;
+
+		/* The start of something good :-) */
+		if (num >= arg->count)
+			{
+			char **tmp_p;
+			int tlen = arg->count + 20;
+			tmp_p = (char **)OPENSSL_realloc(arg->data,
+				sizeof(char *)*tlen);
+			if (tmp_p == NULL)
+				return 0;
+			arg->data  = tmp_p;
+			arg->count = tlen;
+			/* initialize newly allocated data */
+			for (i = num; i < arg->count; i++)
+				arg->data[i] = NULL;
+			}
+		arg->data[num++]=p;
+
+		/* now look for the end of this */
+		if ((*p == '\'') || (*p == '\"')) /* scan for closing quote */
+			{
+			i= *(p++);
+			arg->data[num-1]++; /* jump over quote */
+			while (*p && (*p != i))
+				p++;
+			*p='\0';
+			}
+		else
+			{
+			while (*p && ((*p != ' ') &&
+				(*p != '\t') && (*p != '\n')))
+				p++;
+
+			if (*p == '\0')
+				p--;
+			else
+				*p='\0';
+			}
+		p++;
+		}
+	*argc=num;
+	*argv=arg->data;
+	return(1);
+	}
+
+#ifndef APP_INIT
+int app_init(long mesgwin)
+	{
+	return(1);
+	}
+#endif
+
+
+int dump_cert_text (BIO *out, X509 *x)
+{
+	char *p;
+
+	p=X509_NAME_oneline(X509_get_subject_name(x),NULL,0);
+	BIO_puts(out,"subject=");
+	BIO_puts(out,p);
+	OPENSSL_free(p);
+
+	p=X509_NAME_oneline(X509_get_issuer_name(x),NULL,0);
+	BIO_puts(out,"\nissuer=");
+	BIO_puts(out,p);
+	BIO_puts(out,"\n");
+	OPENSSL_free(p);
+
+	return 0;
+}
+
+static int ui_open(UI *ui)
+	{
+	return UI_method_get_opener(UI_OpenSSL())(ui);
+	}
+static int ui_read(UI *ui, UI_STRING *uis)
+	{
+	if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
+		&& UI_get0_user_data(ui))
+		{
+		switch(UI_get_string_type(uis))
+			{
+		case UIT_PROMPT:
+		case UIT_VERIFY:
+			{
+			const char *password =
+				((PW_CB_DATA *)UI_get0_user_data(ui))->password;
+			if (password && password[0] != '\0')
+				{
+				UI_set_result(ui, uis, password);
+				return 1;
+				}
+			}
+		default:
+			break;
+			}
+		}
+	return UI_method_get_reader(UI_OpenSSL())(ui, uis);
+	}
+static int ui_write(UI *ui, UI_STRING *uis)
+	{
+	if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
+		&& UI_get0_user_data(ui))
+		{
+		switch(UI_get_string_type(uis))
+			{
+		case UIT_PROMPT:
+		case UIT_VERIFY:
+			{
+			const char *password =
+				((PW_CB_DATA *)UI_get0_user_data(ui))->password;
+			if (password && password[0] != '\0')
+				return 1;
+			}
+		default:
+			break;
+			}
+		}
+	return UI_method_get_writer(UI_OpenSSL())(ui, uis);
+	}
+static int ui_close(UI *ui)
+	{
+	return UI_method_get_closer(UI_OpenSSL())(ui);
+	}
+int setup_ui_method(void)
+	{
+	ui_method = UI_create_method("OpenSSL application user interface");
+	UI_method_set_opener(ui_method, ui_open);
+	UI_method_set_reader(ui_method, ui_read);
+	UI_method_set_writer(ui_method, ui_write);
+	UI_method_set_closer(ui_method, ui_close);
+	return 0;
+	}
+void destroy_ui_method(void)
+	{
+	if(ui_method)
+		{
+		UI_destroy_method(ui_method);
+		ui_method = NULL;
+		}
+	}
+int password_callback(char *buf, int bufsiz, int verify,
+	PW_CB_DATA *cb_tmp)
+	{
+	UI *ui = NULL;
+	int res = 0;
+	const char *prompt_info = NULL;
+	const char *password = NULL;
+	PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp;
+
+	if (cb_data)
+		{
+		if (cb_data->password)
+			password = cb_data->password;
+		if (cb_data->prompt_info)
+			prompt_info = cb_data->prompt_info;
+		}
+
+	if (password)
+		{
+		res = strlen(password);
+		if (res > bufsiz)
+			res = bufsiz;
+		memcpy(buf, password, res);
+		return res;
+		}
+
+	ui = UI_new_method(ui_method);
+	if (ui)
+		{
+		int ok = 0;
+		char *buff = NULL;
+		int ui_flags = 0;
+		char *prompt = NULL;
+
+		prompt = UI_construct_prompt(ui, "pass phrase",
+			prompt_info);
+
+		ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
+		UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
+
+		if (ok >= 0)
+			ok = UI_add_input_string(ui,prompt,ui_flags,buf,
+				PW_MIN_LENGTH,BUFSIZ-1);
+		if (ok >= 0 && verify)
+			{
+			buff = (char *)OPENSSL_malloc(bufsiz);
+			ok = UI_add_verify_string(ui,prompt,ui_flags,buff,
+				PW_MIN_LENGTH,BUFSIZ-1, buf);
+			}
+		if (ok >= 0)
+			do
+				{
+				ok = UI_process(ui);
+				}
+			while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
+
+		if (buff)
+			{
+			OPENSSL_cleanse(buff,(unsigned int)bufsiz);
+			OPENSSL_free(buff);
+			}
+
+		if (ok >= 0)
+			res = strlen(buf);
+		if (ok == -1)
+			{
+			BIO_printf(bio_err, "User interface error\n");
+			ERR_print_errors(bio_err);
+			OPENSSL_cleanse(buf,(unsigned int)bufsiz);
+			res = 0;
+			}
+		if (ok == -2)
+			{
+			BIO_printf(bio_err,"aborted!\n");
+			OPENSSL_cleanse(buf,(unsigned int)bufsiz);
+			res = 0;
+			}
+		UI_free(ui);
+		OPENSSL_free(prompt);
+		}
+	return res;
+	}
+
+static char *app_get_pass(BIO *err, char *arg, int keepbio);
+
+int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2)
+{
+	int same;
+	if(!arg2 || !arg1 || strcmp(arg1, arg2)) same = 0;
+	else same = 1;
+	if(arg1) {
+		*pass1 = app_get_pass(err, arg1, same);
+		if(!*pass1) return 0;
+	} else if(pass1) *pass1 = NULL;
+	if(arg2) {
+		*pass2 = app_get_pass(err, arg2, same ? 2 : 0);
+		if(!*pass2) return 0;
+	} else if(pass2) *pass2 = NULL;
+	return 1;
+}
+
+static char *app_get_pass(BIO *err, char *arg, int keepbio)
+{
+	char *tmp, tpass[APP_PASS_LEN];
+	static BIO *pwdbio = NULL;
+	int i;
+	if(!strncmp(arg, "pass:", 5)) return BUF_strdup(arg + 5);
+	if(!strncmp(arg, "env:", 4)) {
+		tmp = getenv(arg + 4);
+		if(!tmp) {
+			BIO_printf(err, "Can't read environment variable %s\n", arg + 4);
+			return NULL;
+		}
+		return BUF_strdup(tmp);
+	}
+	if(!keepbio || !pwdbio) {
+		if(!strncmp(arg, "file:", 5)) {
+			pwdbio = BIO_new_file(arg + 5, "r");
+			if(!pwdbio) {
+				BIO_printf(err, "Can't open file %s\n", arg + 5);
+				return NULL;
+			}
+#if !defined(_WIN32)
+		/*
+		 * Under _WIN32, which covers even Win64 and CE, file
+		 * descriptors referenced by BIO_s_fd are not inherited
+		 * by child process and therefore below is not an option.
+		 * It could have been an option if bss_fd.c was operating
+		 * on real Windows descriptors, such as those obtained
+		 * with CreateFile.
+		 */
+		} else if(!strncmp(arg, "fd:", 3)) {
+			BIO *btmp;
+			i = atoi(arg + 3);
+			if(i >= 0) pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
+			if((i < 0) || !pwdbio) {
+				BIO_printf(err, "Can't access file descriptor %s\n", arg + 3);
+				return NULL;
+			}
+			/* Can't do BIO_gets on an fd BIO so add a buffering BIO */
+			btmp = BIO_new(BIO_f_buffer());
+			pwdbio = BIO_push(btmp, pwdbio);
+#endif
+		} else if(!strcmp(arg, "stdin")) {
+			pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE);
+			if(!pwdbio) {
+				BIO_printf(err, "Can't open BIO for stdin\n");
+				return NULL;
+			}
+		} else {
+			BIO_printf(err, "Invalid password argument \"%s\"\n", arg);
+			return NULL;
+		}
+	}
+	i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
+	if(keepbio != 1) {
+		BIO_free_all(pwdbio);
+		pwdbio = NULL;
+	}
+	if(i <= 0) {
+		BIO_printf(err, "Error reading password from BIO\n");
+		return NULL;
+	}
+	tmp = strchr(tpass, '\n');
+	if(tmp) *tmp = 0;
+	return BUF_strdup(tpass);
+}
+
+int add_oid_section(BIO *err, CONF *conf)
+{	
+	char *p;
+	STACK_OF(CONF_VALUE) *sktmp;
+	CONF_VALUE *cnf;
+	int i;
+	if(!(p=NCONF_get_string(conf,NULL,"oid_section")))
+		{
+		ERR_clear_error();
+		return 1;
+		}
+	if(!(sktmp = NCONF_get_section(conf, p))) {
+		BIO_printf(err, "problem loading oid section %s\n", p);
+		return 0;
+	}
+	for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
+		cnf = sk_CONF_VALUE_value(sktmp, i);
+		if(OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
+			BIO_printf(err, "problem creating object %s=%s\n",
+							 cnf->name, cnf->value);
+			return 0;
+		}
+	}
+	return 1;
+}
+
+static int load_pkcs12(BIO *err, BIO *in, const char *desc,
+		pem_password_cb *pem_cb,  void *cb_data,
+		EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
+	{
+ 	const char *pass;
+	char tpass[PEM_BUFSIZE];
+	int len, ret = 0;
+	PKCS12 *p12;
+	p12 = d2i_PKCS12_bio(in, NULL);
+	if (p12 == NULL)
+		{
+		BIO_printf(err, "Error loading PKCS12 file for %s\n", desc);	
+		goto die;
+		}
+	/* See if an empty password will do */
+	if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0))
+		pass = "";
+	else
+		{
+		if (!pem_cb)
+			pem_cb = (pem_password_cb *)password_callback;
+		len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data);
+		if (len < 0) 
+			{
+			BIO_printf(err, "Passpharse callback error for %s\n",
+					desc);
+			goto die;
+			}
+		if (len < PEM_BUFSIZE)
+			tpass[len] = 0;
+		if (!PKCS12_verify_mac(p12, tpass, len))
+			{
+			BIO_printf(err,
+	"Mac verify error (wrong password?) in PKCS12 file for %s\n", desc);	
+			goto die;
+			}
+		pass = tpass;
+		}
+	ret = PKCS12_parse(p12, pass, pkey, cert, ca);
+	die:
+	if (p12)
+		PKCS12_free(p12);
+	return ret;
+	}
+
+X509 *load_cert(BIO *err, const char *file, int format,
+	const char *pass, ENGINE *e, const char *cert_descrip)
+	{
+	X509 *x=NULL;
+	BIO *cert;
+
+	if ((cert=BIO_new(BIO_s_file())) == NULL)
+		{
+		ERR_print_errors(err);
+		goto end;
+		}
+
+	if (file == NULL)
+		{
+#ifdef _IONBF
+# ifndef OPENSSL_NO_SETVBUF_IONBF
+		setvbuf(stdin, NULL, _IONBF, 0);
+# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
+#endif
+		BIO_set_fp(cert,stdin,BIO_NOCLOSE);
+		}
+	else
+		{
+		if (BIO_read_filename(cert,file) <= 0)
+			{
+			BIO_printf(err, "Error opening %s %s\n",
+				cert_descrip, file);
+			ERR_print_errors(err);
+			goto end;
+			}
+		}
+
+	if 	(format == FORMAT_ASN1)
+		x=d2i_X509_bio(cert,NULL);
+	else if (format == FORMAT_NETSCAPE)
+		{
+		NETSCAPE_X509 *nx;
+		nx=ASN1_item_d2i_bio(ASN1_ITEM_rptr(NETSCAPE_X509),cert,NULL);
+		if (nx == NULL)
+				goto end;
+
+		if ((strncmp(NETSCAPE_CERT_HDR,(char *)nx->header->data,
+			nx->header->length) != 0))
+			{
+			NETSCAPE_X509_free(nx);
+			BIO_printf(err,"Error reading header on certificate\n");
+			goto end;
+			}
+		x=nx->cert;
+		nx->cert = NULL;
+		NETSCAPE_X509_free(nx);
+		}
+	else if (format == FORMAT_PEM)
+		x=PEM_read_bio_X509_AUX(cert,NULL,
+			(pem_password_cb *)password_callback, NULL);
+	else if (format == FORMAT_PKCS12)
+		{
+		if (!load_pkcs12(err, cert,cert_descrip, NULL, NULL,
+					NULL, &x, NULL))
+			goto end;
+		}
+	else	{
+		BIO_printf(err,"bad input format specified for %s\n",
+			cert_descrip);
+		goto end;
+		}
+end:
+	if (x == NULL)
+		{
+		BIO_printf(err,"unable to load certificate\n");
+		ERR_print_errors(err);
+		}
+	if (cert != NULL) BIO_free(cert);
+	return(x);
+	}
+
+EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
+	const char *pass, ENGINE *e, const char *key_descrip)
+	{
+	BIO *key=NULL;
+	EVP_PKEY *pkey=NULL;
+	PW_CB_DATA cb_data;
+
+	cb_data.password = pass;
+	cb_data.prompt_info = file;
+
+	if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE))
+		{
+		BIO_printf(err,"no keyfile specified\n");
+		goto end;
+		}
+#ifndef OPENSSL_NO_ENGINE
+	if (format == FORMAT_ENGINE)
+		{
+		if (!e)
+			BIO_printf(err,"no engine specified\n");
+		else
+			{
+			pkey = ENGINE_load_private_key(e, file,
+				ui_method, &cb_data);
+			if (!pkey) 
+				{
+				BIO_printf(err,"cannot load %s from engine\n",key_descrip);
+				ERR_print_errors(err);
+				}	
+			}
+		goto end;
+		}
+#endif
+	key=BIO_new(BIO_s_file());
+	if (key == NULL)
+		{
+		ERR_print_errors(err);
+		goto end;
+		}
+	if (file == NULL && maybe_stdin)
+		{
+#ifdef _IONBF
+# ifndef OPENSSL_NO_SETVBUF_IONBF
+		setvbuf(stdin, NULL, _IONBF, 0);
+# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
+#endif
+		BIO_set_fp(key,stdin,BIO_NOCLOSE);
+		}
+	else
+		if (BIO_read_filename(key,file) <= 0)
+			{
+			BIO_printf(err, "Error opening %s %s\n",
+				key_descrip, file);
+			ERR_print_errors(err);
+			goto end;
+			}
+	if (format == FORMAT_ASN1)
+		{
+		pkey=d2i_PrivateKey_bio(key, NULL);
+		}
+	else if (format == FORMAT_PEM)
+		{
+		pkey=PEM_read_bio_PrivateKey(key,NULL,
+			(pem_password_cb *)password_callback, &cb_data);
+		}
+#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
+	else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
+		pkey = load_netscape_key(err, key, file, key_descrip, format);
+#endif
+	else if (format == FORMAT_PKCS12)
+		{
+		if (!load_pkcs12(err, key, key_descrip,
+				(pem_password_cb *)password_callback, &cb_data,
+				&pkey, NULL, NULL))
+			goto end;
+		}
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4)
+	else if (format == FORMAT_MSBLOB)
+		pkey = b2i_PrivateKey_bio(key);
+	else if (format == FORMAT_PVK)
+		pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback,
+								&cb_data);
+#endif
+	else
+		{
+		BIO_printf(err,"bad input format specified for key file\n");
+		goto end;
+		}
+ end:
+	if (key != NULL) BIO_free(key);
+	if (pkey == NULL) 
+		{
+		BIO_printf(err,"unable to load %s\n", key_descrip);
+		ERR_print_errors(err);
+		}	
+	return(pkey);
+	}
+
+EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
+	const char *pass, ENGINE *e, const char *key_descrip)
+	{
+	BIO *key=NULL;
+	EVP_PKEY *pkey=NULL;
+	PW_CB_DATA cb_data;
+
+	cb_data.password = pass;
+	cb_data.prompt_info = file;
+
+	if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE))
+		{
+		BIO_printf(err,"no keyfile specified\n");
+		goto end;
+		}
+#ifndef OPENSSL_NO_ENGINE
+	if (format == FORMAT_ENGINE)
+		{
+		if (!e)
+			BIO_printf(bio_err,"no engine specified\n");
+		else
+			pkey = ENGINE_load_public_key(e, file,
+				ui_method, &cb_data);
+		goto end;
+		}
+#endif
+	key=BIO_new(BIO_s_file());
+	if (key == NULL)
+		{
+		ERR_print_errors(err);
+		goto end;
+		}
+	if (file == NULL && maybe_stdin)
+		{
+#ifdef _IONBF
+# ifndef OPENSSL_NO_SETVBUF_IONBF
+		setvbuf(stdin, NULL, _IONBF, 0);
+# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
+#endif
+		BIO_set_fp(key,stdin,BIO_NOCLOSE);
+		}
+	else
+		if (BIO_read_filename(key,file) <= 0)
+			{
+			BIO_printf(err, "Error opening %s %s\n",
+				key_descrip, file);
+			ERR_print_errors(err);
+			goto end;
+		}
+	if (format == FORMAT_ASN1)
+		{
+		pkey=d2i_PUBKEY_bio(key, NULL);
+		}
+#ifndef OPENSSL_NO_RSA
+	else if (format == FORMAT_ASN1RSA)
+		{
+		RSA *rsa;
+		rsa = d2i_RSAPublicKey_bio(key, NULL);
+		if (rsa)
+			{
+			pkey = EVP_PKEY_new();
+			if (pkey)
+				EVP_PKEY_set1_RSA(pkey, rsa);
+			RSA_free(rsa);
+			}
+		else
+			pkey = NULL;
+		}
+	else if (format == FORMAT_PEMRSA)
+		{
+		RSA *rsa;
+		rsa = PEM_read_bio_RSAPublicKey(key, NULL, 
+			(pem_password_cb *)password_callback, &cb_data);
+		if (rsa)
+			{
+			pkey = EVP_PKEY_new();
+			if (pkey)
+				EVP_PKEY_set1_RSA(pkey, rsa);
+			RSA_free(rsa);
+			}
+		else
+			pkey = NULL;
+		}
+#endif
+	else if (format == FORMAT_PEM)
+		{
+		pkey=PEM_read_bio_PUBKEY(key,NULL,
+			(pem_password_cb *)password_callback, &cb_data);
+		}
+#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
+	else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
+		pkey = load_netscape_key(err, key, file, key_descrip, format);
+#endif
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
+	else if (format == FORMAT_MSBLOB)
+		pkey = b2i_PublicKey_bio(key);
+#endif
+	else
+		{
+		BIO_printf(err,"bad input format specified for key file\n");
+		goto end;
+		}
+ end:
+	if (key != NULL) BIO_free(key);
+	if (pkey == NULL)
+		BIO_printf(err,"unable to load %s\n", key_descrip);
+	return(pkey);
+	}
+
+#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
+static EVP_PKEY *
+load_netscape_key(BIO *err, BIO *key, const char *file,
+		const char *key_descrip, int format)
+	{
+	EVP_PKEY *pkey;
+	BUF_MEM *buf;
+	RSA	*rsa;
+	const unsigned char *p;
+	int size, i;
+
+	buf=BUF_MEM_new();
+	pkey = EVP_PKEY_new();
+	size = 0;
+	if (buf == NULL || pkey == NULL)
+		goto error;
+	for (;;)
+		{
+		if (!BUF_MEM_grow_clean(buf,size+1024*10))
+			goto error;
+		i = BIO_read(key, &(buf->data[size]), 1024*10);
+		size += i;
+		if (i == 0)
+			break;
+		if (i < 0)
+			{
+				BIO_printf(err, "Error reading %s %s",
+					key_descrip, file);
+				goto error;
+			}
+		}
+	p=(unsigned char *)buf->data;
+	rsa = d2i_RSA_NET(NULL,&p,(long)size,NULL,
+		(format == FORMAT_IISSGC ? 1 : 0));
+	if (rsa == NULL)
+		goto error;
+	BUF_MEM_free(buf);
+	EVP_PKEY_set1_RSA(pkey, rsa);
+	return pkey;
+error:
+	BUF_MEM_free(buf);
+	EVP_PKEY_free(pkey);
+	return NULL;
+	}
+#endif /* ndef OPENSSL_NO_RC4 */
+
+static int load_certs_crls(BIO *err, const char *file, int format,
+	const char *pass, ENGINE *e, const char *desc,
+	STACK_OF(X509) **pcerts, STACK_OF(X509_CRL) **pcrls)
+	{
+	int i;
+	BIO *bio;
+	STACK_OF(X509_INFO) *xis = NULL;
+	X509_INFO *xi;
+	PW_CB_DATA cb_data;
+	int rv = 0;
+
+	cb_data.password = pass;
+	cb_data.prompt_info = file;
+
+	if (format != FORMAT_PEM)
+		{
+		BIO_printf(err,"bad input format specified for %s\n", desc);
+		return 0;
+		}
+
+	if (file == NULL)
+		bio = BIO_new_fp(stdin,BIO_NOCLOSE);
+	else
+		bio = BIO_new_file(file, "r");
+
+	if (bio == NULL)
+		{
+		BIO_printf(err, "Error opening %s %s\n",
+				desc, file ? file : "stdin");
+		ERR_print_errors(err);
+		return 0;
+		}
+
+	xis = PEM_X509_INFO_read_bio(bio, NULL,
+				(pem_password_cb *)password_callback, &cb_data);
+
+	BIO_free(bio);
+
+	if (pcerts)
+		{
+		*pcerts = sk_X509_new_null();
+		if (!*pcerts)
+			goto end;
+		}
+
+	if (pcrls)
+		{
+		*pcrls = sk_X509_CRL_new_null();
+		if (!*pcrls)
+			goto end;
+		}
+
+	for(i = 0; i < sk_X509_INFO_num(xis); i++)
+		{
+		xi = sk_X509_INFO_value (xis, i);
+		if (xi->x509 && pcerts)
+			{
+			if (!sk_X509_push(*pcerts, xi->x509))
+				goto end;
+			xi->x509 = NULL;
+			}
+		if (xi->crl && pcrls)
+			{
+			if (!sk_X509_CRL_push(*pcrls, xi->crl))
+				goto end;
+			xi->crl = NULL;
+			}
+		}
+
+	if (pcerts && sk_X509_num(*pcerts) > 0)
+		rv = 1;
+
+	if (pcrls && sk_X509_CRL_num(*pcrls) > 0)
+		rv = 1;
+
+	end:
+
+	if (xis)
+		sk_X509_INFO_pop_free(xis, X509_INFO_free);
+
+	if (rv == 0)
+		{
+		if (pcerts)
+			{
+			sk_X509_pop_free(*pcerts, X509_free);
+			*pcerts = NULL;
+			}
+		if (pcrls)
+			{
+			sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
+			*pcrls = NULL;
+			}
+		BIO_printf(err,"unable to load %s\n",
+				pcerts ? "certificates" : "CRLs");
+		ERR_print_errors(err);
+		}
+	return rv;
+	}
+
+STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
+	const char *pass, ENGINE *e, const char *desc)
+	{
+	STACK_OF(X509) *certs;
+	load_certs_crls(err, file, format, pass, e, desc, &certs, NULL);
+	return certs;
+	}	
+
+STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
+	const char *pass, ENGINE *e, const char *desc)
+	{
+	STACK_OF(X509_CRL) *crls;
+	load_certs_crls(err, file, format, pass, e, desc, NULL, &crls);
+	return crls;
+	}	
+
+#define X509V3_EXT_UNKNOWN_MASK		(0xfL << 16)
+/* Return error for unknown extensions */
+#define X509V3_EXT_DEFAULT		0
+/* Print error for unknown extensions */
+#define X509V3_EXT_ERROR_UNKNOWN	(1L << 16)
+/* ASN1 parse unknown extensions */
+#define X509V3_EXT_PARSE_UNKNOWN	(2L << 16)
+/* BIO_dump unknown extensions */
+#define X509V3_EXT_DUMP_UNKNOWN		(3L << 16)
+
+#define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \
+			 X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
+
+int set_cert_ex(unsigned long *flags, const char *arg)
+{
+	static const NAME_EX_TBL cert_tbl[] = {
+		{ "compatible", X509_FLAG_COMPAT, 0xffffffffl},
+		{ "ca_default", X509_FLAG_CA, 0xffffffffl},
+		{ "no_header", X509_FLAG_NO_HEADER, 0},
+		{ "no_version", X509_FLAG_NO_VERSION, 0},
+		{ "no_serial", X509_FLAG_NO_SERIAL, 0},
+		{ "no_signame", X509_FLAG_NO_SIGNAME, 0},
+		{ "no_validity", X509_FLAG_NO_VALIDITY, 0},
+		{ "no_subject", X509_FLAG_NO_SUBJECT, 0},
+		{ "no_issuer", X509_FLAG_NO_ISSUER, 0},
+		{ "no_pubkey", X509_FLAG_NO_PUBKEY, 0},
+		{ "no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
+		{ "no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
+		{ "no_aux", X509_FLAG_NO_AUX, 0},
+		{ "no_attributes", X509_FLAG_NO_ATTRIBUTES, 0},
+		{ "ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
+		{ "ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
+		{ "ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
+		{ "ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
+		{ NULL, 0, 0}
+	};
+	return set_multi_opts(flags, arg, cert_tbl);
+}
+
+int set_name_ex(unsigned long *flags, const char *arg)
+{
+	static const NAME_EX_TBL ex_tbl[] = {
+		{ "esc_2253", ASN1_STRFLGS_ESC_2253, 0},
+		{ "esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
+		{ "esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
+		{ "use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
+		{ "utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
+		{ "ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
+		{ "show_type", ASN1_STRFLGS_SHOW_TYPE, 0},
+		{ "dump_all", ASN1_STRFLGS_DUMP_ALL, 0},
+		{ "dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0},
+		{ "dump_der", ASN1_STRFLGS_DUMP_DER, 0},
+		{ "compat", XN_FLAG_COMPAT, 0xffffffffL},
+		{ "sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK},
+		{ "sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK},
+		{ "sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK},
+		{ "sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK},
+		{ "dn_rev", XN_FLAG_DN_REV, 0},
+		{ "nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK},
+		{ "sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK},
+		{ "lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK},
+		{ "align", XN_FLAG_FN_ALIGN, 0},
+		{ "oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK},
+		{ "space_eq", XN_FLAG_SPC_EQ, 0},
+		{ "dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0},
+		{ "RFC2253", XN_FLAG_RFC2253, 0xffffffffL},
+		{ "oneline", XN_FLAG_ONELINE, 0xffffffffL},
+		{ "multiline", XN_FLAG_MULTILINE, 0xffffffffL},
+		{ "ca_default", XN_FLAG_MULTILINE, 0xffffffffL},
+		{ NULL, 0, 0}
+	};
+	return set_multi_opts(flags, arg, ex_tbl);
+}
+
+int set_ext_copy(int *copy_type, const char *arg)
+{
+	if (!strcasecmp(arg, "none"))
+		*copy_type = EXT_COPY_NONE;
+	else if (!strcasecmp(arg, "copy"))
+		*copy_type = EXT_COPY_ADD;
+	else if (!strcasecmp(arg, "copyall"))
+		*copy_type = EXT_COPY_ALL;
+	else
+		return 0;
+	return 1;
+}
+
+int copy_extensions(X509 *x, X509_REQ *req, int copy_type)
+{
+	STACK_OF(X509_EXTENSION) *exts = NULL;
+	X509_EXTENSION *ext, *tmpext;
+	ASN1_OBJECT *obj;
+	int i, idx, ret = 0;
+	if (!x || !req || (copy_type == EXT_COPY_NONE))
+		return 1;
+	exts = X509_REQ_get_extensions(req);
+
+	for(i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+		ext = sk_X509_EXTENSION_value(exts, i);
+		obj = X509_EXTENSION_get_object(ext);
+		idx = X509_get_ext_by_OBJ(x, obj, -1);
+		/* Does extension exist? */
+		if (idx != -1) {
+			/* If normal copy don't override existing extension */
+			if (copy_type == EXT_COPY_ADD)
+				continue;
+			/* Delete all extensions of same type */
+			do {
+				tmpext = X509_get_ext(x, idx);
+				X509_delete_ext(x, idx);
+				X509_EXTENSION_free(tmpext);
+				idx = X509_get_ext_by_OBJ(x, obj, -1);
+			} while (idx != -1);
+		}
+		if (!X509_add_ext(x, ext, -1))
+			goto end;
+	}
+
+	ret = 1;
+
+	end:
+
+	sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+
+	return ret;
+}
+		
+		
+			
+
+static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl)
+{
+	STACK_OF(CONF_VALUE) *vals;
+	CONF_VALUE *val;
+	int i, ret = 1;
+	if(!arg) return 0;
+	vals = X509V3_parse_list(arg);
+	for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
+		val = sk_CONF_VALUE_value(vals, i);
+		if (!set_table_opts(flags, val->name, in_tbl))
+			ret = 0;
+	}
+	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+	return ret;
+}
+
+static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl)
+{
+	char c;
+	const NAME_EX_TBL *ptbl;
+	c = arg[0];
+
+	if(c == '-') {
+		c = 0;
+		arg++;
+	} else if (c == '+') {
+		c = 1;
+		arg++;
+	} else c = 1;
+
+	for(ptbl = in_tbl; ptbl->name; ptbl++) {
+		if(!strcasecmp(arg, ptbl->name)) {
+			*flags &= ~ptbl->mask;
+			if(c) *flags |= ptbl->flag;
+			else *flags &= ~ptbl->flag;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+void print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags)
+{
+	char *buf;
+	char mline = 0;
+	int indent = 0;
+
+	if(title) BIO_puts(out, title);
+	if((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+		mline = 1;
+		indent = 4;
+	}
+	if(lflags == XN_FLAG_COMPAT) {
+		buf = X509_NAME_oneline(nm, 0, 0);
+		BIO_puts(out, buf);
+		BIO_puts(out, "\n");
+		OPENSSL_free(buf);
+	} else {
+		if(mline) BIO_puts(out, "\n");
+		X509_NAME_print_ex(out, nm, indent, lflags);
+		BIO_puts(out, "\n");
+	}
+}
+
+X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath)
+{
+	X509_STORE *store;
+	X509_LOOKUP *lookup;
+	if(!(store = X509_STORE_new())) goto end;
+	lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file());
+	if (lookup == NULL) goto end;
+	if (CAfile) {
+		if(!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM)) {
+			BIO_printf(bp, "Error loading file %s\n", CAfile);
+			goto end;
+		}
+	} else X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
+		
+	lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir());
+	if (lookup == NULL) goto end;
+	if (CApath) {
+		if(!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM)) {
+			BIO_printf(bp, "Error loading directory %s\n", CApath);
+			goto end;
+		}
+	} else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
+
+	ERR_clear_error();
+	return store;
+	end:
+	X509_STORE_free(store);
+	return NULL;
+}
+
+#ifndef OPENSSL_NO_ENGINE
+/* Try to load an engine in a shareable library */
+static ENGINE *try_load_engine(BIO *err, const char *engine, int debug)
+	{
+	ENGINE *e = ENGINE_by_id("dynamic");
+	if (e)
+		{
+		if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0)
+			|| !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
+			{
+			ENGINE_free(e);
+			e = NULL;
+			}
+		}
+	return e;
+	}
+
+ENGINE *setup_engine(BIO *err, const char *engine, int debug)
+        {
+        ENGINE *e = NULL;
+
+        if (engine)
+                {
+		if(strcmp(engine, "auto") == 0)
+			{
+			BIO_printf(err,"enabling auto ENGINE support\n");
+			ENGINE_register_all_complete();
+			return NULL;
+			}
+		if((e = ENGINE_by_id(engine)) == NULL
+			&& (e = try_load_engine(err, engine, debug)) == NULL)
+			{
+			BIO_printf(err,"invalid engine \"%s\"\n", engine);
+			ERR_print_errors(err);
+			return NULL;
+			}
+		if (debug)
+			{
+			ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM,
+				0, err, 0);
+			}
+                ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1);
+		if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
+			{
+			BIO_printf(err,"can't use that engine\n");
+			ERR_print_errors(err);
+			ENGINE_free(e);
+			return NULL;
+			}
+
+		BIO_printf(err,"engine \"%s\" set.\n", ENGINE_get_id(e));
+
+		/* Free our "structural" reference. */
+		ENGINE_free(e);
+		}
+        return e;
+        }
+#endif
+
+int load_config(BIO *err, CONF *cnf)
+	{
+	static int load_config_called = 0;
+	if (load_config_called)
+		return 1;
+	load_config_called = 1;
+	if (!cnf)
+		cnf = config;
+	if (!cnf)
+		return 1;
+
+	OPENSSL_load_builtin_modules();
+
+	if (CONF_modules_load(cnf, NULL, 0) <= 0)
+		{
+		BIO_printf(err, "Error configuring OpenSSL\n");
+		ERR_print_errors(err);
+		return 0;
+		}
+	return 1;
+	}
+
+char *make_config_name()
+	{
+	const char *t=X509_get_default_cert_area();
+	size_t len;
+	char *p;
+
+	len=strlen(t)+strlen(OPENSSL_CONF)+2;
+	p=OPENSSL_malloc(len);
+	BUF_strlcpy(p,t,len);
+#ifndef OPENSSL_SYS_VMS
+	BUF_strlcat(p,"/",len);
+#endif
+	BUF_strlcat(p,OPENSSL_CONF,len);
+
+	return p;
+	}
+
+static unsigned long index_serial_hash(const OPENSSL_CSTRING *a)
+	{
+	const char *n;
+
+	n=a[DB_serial];
+	while (*n == '0') n++;
+	return(lh_strhash(n));
+	}
+
+static int index_serial_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
+	{
+	const char *aa,*bb;
+
+	for (aa=a[DB_serial]; *aa == '0'; aa++);
+	for (bb=b[DB_serial]; *bb == '0'; bb++);
+	return(strcmp(aa,bb));
+	}
+
+static int index_name_qual(char **a)
+	{ return(a[0][0] == 'V'); }
+
+static unsigned long index_name_hash(const OPENSSL_CSTRING *a)
+	{ return(lh_strhash(a[DB_name])); }
+
+int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
+	{ return(strcmp(a[DB_name], b[DB_name])); }
+
+static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
+static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
+static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
+static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
+
+#undef BSIZE
+#define BSIZE 256
+
+BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai)
+	{
+	BIO *in=NULL;
+	BIGNUM *ret=NULL;
+	MS_STATIC char buf[1024];
+	ASN1_INTEGER *ai=NULL;
+
+	ai=ASN1_INTEGER_new();
+	if (ai == NULL) goto err;
+
+	if ((in=BIO_new(BIO_s_file())) == NULL)
+		{
+		ERR_print_errors(bio_err);
+		goto err;
+		}
+
+	if (BIO_read_filename(in,serialfile) <= 0)
+		{
+		if (!create)
+			{
+			perror(serialfile);
+			goto err;
+			}
+		else
+			{
+			ret=BN_new();
+			if (ret == NULL || !rand_serial(ret, ai))
+				BIO_printf(bio_err, "Out of memory\n");
+			}
+		}
+	else
+		{
+		if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
+			{
+			BIO_printf(bio_err,"unable to load number from %s\n",
+				serialfile);
+			goto err;
+			}
+		ret=ASN1_INTEGER_to_BN(ai,NULL);
+		if (ret == NULL)
+			{
+			BIO_printf(bio_err,"error converting number from bin to BIGNUM\n");
+			goto err;
+			}
+		}
+
+	if (ret && retai)
+		{
+		*retai = ai;
+		ai = NULL;
+		}
+ err:
+	if (in != NULL) BIO_free(in);
+	if (ai != NULL) ASN1_INTEGER_free(ai);
+	return(ret);
+	}
+
+int save_serial(char *serialfile, char *suffix, BIGNUM *serial, ASN1_INTEGER **retai)
+	{
+	char buf[1][BSIZE];
+	BIO *out = NULL;
+	int ret=0;
+	ASN1_INTEGER *ai=NULL;
+	int j;
+
+	if (suffix == NULL)
+		j = strlen(serialfile);
+	else
+		j = strlen(serialfile) + strlen(suffix) + 1;
+	if (j >= BSIZE)
+		{
+		BIO_printf(bio_err,"file name too long\n");
+		goto err;
+		}
+
+	if (suffix == NULL)
+		BUF_strlcpy(buf[0], serialfile, BSIZE);
+	else
+		{
+#ifndef OPENSSL_SYS_VMS
+		j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix);
+#else
+		j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, suffix);
+#endif
+		}
+#ifdef RL_DEBUG
+	BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
+#endif
+	out=BIO_new(BIO_s_file());
+	if (out == NULL)
+		{
+		ERR_print_errors(bio_err);
+		goto err;
+		}
+	if (BIO_write_filename(out,buf[0]) <= 0)
+		{
+		perror(serialfile);
+		goto err;
+		}
+
+	if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
+		{
+		BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
+		goto err;
+		}
+	i2a_ASN1_INTEGER(out,ai);
+	BIO_puts(out,"\n");
+	ret=1;
+	if (retai)
+		{
+		*retai = ai;
+		ai = NULL;
+		}
+err:
+	if (out != NULL) BIO_free_all(out);
+	if (ai != NULL) ASN1_INTEGER_free(ai);
+	return(ret);
+	}
+
+int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix)
+	{
+	char buf[5][BSIZE];
+	int i,j;
+
+	i = strlen(serialfile) + strlen(old_suffix);
+	j = strlen(serialfile) + strlen(new_suffix);
+	if (i > j) j = i;
+	if (j + 1 >= BSIZE)
+		{
+		BIO_printf(bio_err,"file name too long\n");
+		goto err;
+		}
+
+#ifndef OPENSSL_SYS_VMS
+	j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s",
+		serialfile, new_suffix);
+#else
+	j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s",
+		serialfile, new_suffix);
+#endif
+#ifndef OPENSSL_SYS_VMS
+	j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s",
+		serialfile, old_suffix);
+#else
+	j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s",
+		serialfile, old_suffix);
+#endif
+#ifdef RL_DEBUG
+	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+		serialfile, buf[1]);
+#endif
+	if (rename(serialfile,buf[1]) < 0 && errno != ENOENT
+#ifdef ENOTDIR
+			&& errno != ENOTDIR
+#endif
+	   )		{
+			BIO_printf(bio_err,
+				"unable to rename %s to %s\n",
+				serialfile, buf[1]);
+			perror("reason");
+			goto err;
+			}
+#ifdef RL_DEBUG
+	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+		buf[0],serialfile);
+#endif
+	if (rename(buf[0],serialfile) < 0)
+		{
+		BIO_printf(bio_err,
+			"unable to rename %s to %s\n",
+			buf[0],serialfile);
+		perror("reason");
+		rename(buf[1],serialfile);
+		goto err;
+		}
+	return 1;
+ err:
+	return 0;
+	}
+
+int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
+	{
+	BIGNUM *btmp;
+	int ret = 0;
+	if (b)
+		btmp = b;
+	else
+		btmp = BN_new();
+
+	if (!btmp)
+		return 0;
+
+	if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
+		goto error;
+	if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
+		goto error;
+
+	ret = 1;
+	
+	error:
+
+	if (!b)
+		BN_free(btmp);
+	
+	return ret;
+	}
+
+CA_DB *load_index(char *dbfile, DB_ATTR *db_attr)
+	{
+	CA_DB *retdb = NULL;
+	TXT_DB *tmpdb = NULL;
+	BIO *in = BIO_new(BIO_s_file());
+	CONF *dbattr_conf = NULL;
+	char buf[1][BSIZE];
+	long errorline= -1;
+
+	if (in == NULL)
+		{
+		ERR_print_errors(bio_err);
+		goto err;
+		}
+	if (BIO_read_filename(in,dbfile) <= 0)
+		{
+		perror(dbfile);
+		BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
+		goto err;
+		}
+	if ((tmpdb = TXT_DB_read(in,DB_NUMBER)) == NULL)
+		goto err;
+
+#ifndef OPENSSL_SYS_VMS
+	BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile);
+#else
+	BIO_snprintf(buf[0], sizeof buf[0], "%s-attr", dbfile);
+#endif
+	dbattr_conf = NCONF_new(NULL);
+	if (NCONF_load(dbattr_conf,buf[0],&errorline) <= 0)
+		{
+		if (errorline > 0)
+			{
+			BIO_printf(bio_err,
+				"error on line %ld of db attribute file '%s'\n"
+				,errorline,buf[0]);
+			goto err;
+			}
+		else
+			{
+			NCONF_free(dbattr_conf);
+			dbattr_conf = NULL;
+			}
+		}
+
+	if ((retdb = OPENSSL_malloc(sizeof(CA_DB))) == NULL)
+		{
+		fprintf(stderr, "Out of memory\n");
+		goto err;
+		}
+
+	retdb->db = tmpdb;
+	tmpdb = NULL;
+	if (db_attr)
+		retdb->attributes = *db_attr;
+	else
+		{
+		retdb->attributes.unique_subject = 1;
+		}
+
+	if (dbattr_conf)
+		{
+		char *p = NCONF_get_string(dbattr_conf,NULL,"unique_subject");
+		if (p)
+			{
+#ifdef RL_DEBUG
+			BIO_printf(bio_err, "DEBUG[load_index]: unique_subject = \"%s\"\n", p);
+#endif
+			retdb->attributes.unique_subject = parse_yesno(p,1);
+			}
+		}
+
+ err:
+	if (dbattr_conf) NCONF_free(dbattr_conf);
+	if (tmpdb) TXT_DB_free(tmpdb);
+	if (in) BIO_free_all(in);
+	return retdb;
+	}
+
+int index_index(CA_DB *db)
+	{
+	if (!TXT_DB_create_index(db->db, DB_serial, NULL,
+				LHASH_HASH_FN(index_serial),
+				LHASH_COMP_FN(index_serial)))
+		{
+		BIO_printf(bio_err,
+		  "error creating serial number index:(%ld,%ld,%ld)\n",
+		  			db->db->error,db->db->arg1,db->db->arg2);
+			return 0;
+		}
+
+	if (db->attributes.unique_subject
+		&& !TXT_DB_create_index(db->db, DB_name, index_name_qual,
+			LHASH_HASH_FN(index_name),
+			LHASH_COMP_FN(index_name)))
+		{
+		BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
+			db->db->error,db->db->arg1,db->db->arg2);
+		return 0;
+		}
+	return 1;
+	}
+
+int save_index(const char *dbfile, const char *suffix, CA_DB *db)
+	{
+	char buf[3][BSIZE];
+	BIO *out = BIO_new(BIO_s_file());
+	int j;
+
+	if (out == NULL)
+		{
+		ERR_print_errors(bio_err);
+		goto err;
+		}
+
+	j = strlen(dbfile) + strlen(suffix);
+	if (j + 6 >= BSIZE)
+		{
+		BIO_printf(bio_err,"file name too long\n");
+		goto err;
+		}
+
+#ifndef OPENSSL_SYS_VMS
+	j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile);
+#else
+	j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr", dbfile);
+#endif
+#ifndef OPENSSL_SYS_VMS
+	j = BIO_snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix);
+#else
+	j = BIO_snprintf(buf[1], sizeof buf[1], "%s-attr-%s", dbfile, suffix);
+#endif
+#ifndef OPENSSL_SYS_VMS
+	j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix);
+#else
+	j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, suffix);
+#endif
+#ifdef RL_DEBUG
+	BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
+#endif
+	if (BIO_write_filename(out,buf[0]) <= 0)
+		{
+		perror(dbfile);
+		BIO_printf(bio_err,"unable to open '%s'\n", dbfile);
+		goto err;
+		}
+	j=TXT_DB_write(out,db->db);
+	if (j <= 0) goto err;
+			
+	BIO_free(out);
+
+	out = BIO_new(BIO_s_file());
+#ifdef RL_DEBUG
+	BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[1]);
+#endif
+	if (BIO_write_filename(out,buf[1]) <= 0)
+		{
+		perror(buf[2]);
+		BIO_printf(bio_err,"unable to open '%s'\n", buf[2]);
+		goto err;
+		}
+	BIO_printf(out,"unique_subject = %s\n",
+		db->attributes.unique_subject ? "yes" : "no");
+	BIO_free(out);
+
+	return 1;
+ err:
+	return 0;
+	}
+
+int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix)
+	{
+	char buf[5][BSIZE];
+	int i,j;
+
+	i = strlen(dbfile) + strlen(old_suffix);
+	j = strlen(dbfile) + strlen(new_suffix);
+	if (i > j) j = i;
+	if (j + 6 >= BSIZE)
+		{
+		BIO_printf(bio_err,"file name too long\n");
+		goto err;
+		}
+
+#ifndef OPENSSL_SYS_VMS
+	j = BIO_snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile);
+#else
+	j = BIO_snprintf(buf[4], sizeof buf[4], "%s-attr", dbfile);
+#endif
+#ifndef OPENSSL_SYS_VMS
+	j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr.%s",
+		dbfile, new_suffix);
+#else
+	j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr-%s",
+		dbfile, new_suffix);
+#endif
+#ifndef OPENSSL_SYS_VMS
+	j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s",
+		dbfile, new_suffix);
+#else
+	j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s",
+		dbfile, new_suffix);
+#endif
+#ifndef OPENSSL_SYS_VMS
+	j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s",
+		dbfile, old_suffix);
+#else
+	j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s",
+		dbfile, old_suffix);
+#endif
+#ifndef OPENSSL_SYS_VMS
+	j = BIO_snprintf(buf[3], sizeof buf[3], "%s.attr.%s",
+		dbfile, old_suffix);
+#else
+	j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s",
+		dbfile, old_suffix);
+#endif
+#ifdef RL_DEBUG
+	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+		dbfile, buf[1]);
+#endif
+	if (rename(dbfile,buf[1]) < 0 && errno != ENOENT
+#ifdef ENOTDIR
+		&& errno != ENOTDIR
+#endif
+	   )		{
+			BIO_printf(bio_err,
+				"unable to rename %s to %s\n",
+				dbfile, buf[1]);
+			perror("reason");
+			goto err;
+			}
+#ifdef RL_DEBUG
+	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+		buf[0],dbfile);
+#endif
+	if (rename(buf[0],dbfile) < 0)
+		{
+		BIO_printf(bio_err,
+			"unable to rename %s to %s\n",
+			buf[0],dbfile);
+		perror("reason");
+		rename(buf[1],dbfile);
+		goto err;
+		}
+#ifdef RL_DEBUG
+	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+		buf[4],buf[3]);
+#endif
+	if (rename(buf[4],buf[3]) < 0 && errno != ENOENT
+#ifdef ENOTDIR
+		&& errno != ENOTDIR
+#endif
+	   )		{
+			BIO_printf(bio_err,
+				"unable to rename %s to %s\n",
+				buf[4], buf[3]);
+			perror("reason");
+			rename(dbfile,buf[0]);
+			rename(buf[1],dbfile);
+			goto err;
+			}
+#ifdef RL_DEBUG
+	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+		buf[2],buf[4]);
+#endif
+	if (rename(buf[2],buf[4]) < 0)
+		{
+		BIO_printf(bio_err,
+			"unable to rename %s to %s\n",
+			buf[2],buf[4]);
+		perror("reason");
+		rename(buf[3],buf[4]);
+		rename(dbfile,buf[0]);
+		rename(buf[1],dbfile);
+		goto err;
+		}
+	return 1;
+ err:
+	return 0;
+	}
+
+void free_index(CA_DB *db)
+	{
+	if (db)
+		{
+		if (db->db) TXT_DB_free(db->db);
+		OPENSSL_free(db);
+		}
+	}
+
+int parse_yesno(const char *str, int def)
+	{
+	int ret = def;
+	if (str)
+		{
+		switch (*str)
+			{
+		case 'f': /* false */
+		case 'F': /* FALSE */
+		case 'n': /* no */
+		case 'N': /* NO */
+		case '0': /* 0 */
+			ret = 0;
+			break;
+		case 't': /* true */
+		case 'T': /* TRUE */
+		case 'y': /* yes */
+		case 'Y': /* YES */
+		case '1': /* 1 */
+			ret = 1;
+			break;
+		default:
+			ret = def;
+			break;
+			}
+		}
+	return ret;
+	}
+
+/*
+ * subject is expected to be in the format /type0=value0/type1=value1/type2=...
+ * where characters may be escaped by \
+ */
+X509_NAME *parse_name(char *subject, long chtype, int multirdn)
+	{
+	size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
+	char *buf = OPENSSL_malloc(buflen);
+	size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
+	char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
+	char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
+	int *mval = OPENSSL_malloc (max_ne * sizeof (int));
+
+	char *sp = subject, *bp = buf;
+	int i, ne_num = 0;
+
+	X509_NAME *n = NULL;
+	int nid;
+
+	if (!buf || !ne_types || !ne_values)
+		{
+		BIO_printf(bio_err, "malloc error\n");
+		goto error;
+		}	
+
+	if (*subject != '/')
+		{
+		BIO_printf(bio_err, "Subject does not start with '/'.\n");
+		goto error;
+		}
+	sp++; /* skip leading / */
+
+	/* no multivalued RDN by default */
+	mval[ne_num] = 0;
+
+	while (*sp)
+		{
+		/* collect type */
+		ne_types[ne_num] = bp;
+		while (*sp)
+			{
+			if (*sp == '\\') /* is there anything to escape in the type...? */
+				{
+				if (*++sp)
+					*bp++ = *sp++;
+				else	
+					{
+					BIO_printf(bio_err, "escape character at end of string\n");
+					goto error;
+					}
+				}	
+			else if (*sp == '=')
+				{
+				sp++;
+				*bp++ = '\0';
+				break;
+				}
+			else
+				*bp++ = *sp++;
+			}
+		if (!*sp)
+			{
+			BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
+			goto error;
+			}
+		ne_values[ne_num] = bp;
+		while (*sp)
+			{
+			if (*sp == '\\')
+				{
+				if (*++sp)
+					*bp++ = *sp++;
+				else
+					{
+					BIO_printf(bio_err, "escape character at end of string\n");
+					goto error;
+					}
+				}
+			else if (*sp == '/')
+				{
+				sp++;
+				/* no multivalued RDN by default */
+				mval[ne_num+1] = 0;
+				break;
+				}
+			else if (*sp == '+' && multirdn)
+				{
+				/* a not escaped + signals a mutlivalued RDN */
+				sp++;
+				mval[ne_num+1] = -1;
+				break;
+				}
+			else
+				*bp++ = *sp++;
+			}
+		*bp++ = '\0';
+		ne_num++;
+		}	
+
+	if (!(n = X509_NAME_new()))
+		goto error;
+
+	for (i = 0; i < ne_num; i++)
+		{
+		if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
+			{
+			BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
+			continue;
+			}
+
+		if (!*ne_values[i])
+			{
+			BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
+			continue;
+			}
+
+		if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,mval[i]))
+			goto error;
+		}
+
+	OPENSSL_free(ne_values);
+	OPENSSL_free(ne_types);
+	OPENSSL_free(buf);
+	return n;
+
+error:
+	X509_NAME_free(n);
+	if (ne_values)
+		OPENSSL_free(ne_values);
+	if (ne_types)
+		OPENSSL_free(ne_types);
+	if (buf)
+		OPENSSL_free(buf);
+	return NULL;
+}
+
+int args_verify(char ***pargs, int *pargc,
+			int *badarg, BIO *err, X509_VERIFY_PARAM **pm)
+	{
+	ASN1_OBJECT *otmp = NULL;
+	unsigned long flags = 0;
+	int i;
+	int purpose = 0, depth = -1;
+	char **oldargs = *pargs;
+	char *arg = **pargs, *argn = (*pargs)[1];
+	if (!strcmp(arg, "-policy"))
+		{
+		if (!argn)
+			*badarg = 1;
+		else
+			{
+			otmp = OBJ_txt2obj(argn, 0);
+			if (!otmp)
+				{
+				BIO_printf(err, "Invalid Policy \"%s\"\n",
+									argn);
+				*badarg = 1;
+				}
+			}
+		(*pargs)++;
+		}
+	else if (strcmp(arg,"-purpose") == 0)
+		{
+		X509_PURPOSE *xptmp;
+		if (!argn)
+			*badarg = 1;
+		else
+			{
+			i = X509_PURPOSE_get_by_sname(argn);
+			if(i < 0)
+				{
+				BIO_printf(err, "unrecognized purpose\n");
+				*badarg = 1;
+				}
+			else
+				{
+				xptmp = X509_PURPOSE_get0(i);
+				purpose = X509_PURPOSE_get_id(xptmp);
+				}
+			}
+		(*pargs)++;
+		}
+	else if (strcmp(arg,"-verify_depth") == 0)
+		{
+		if (!argn)
+			*badarg = 1;
+		else
+			{
+			depth = atoi(argn);
+			if(depth < 0)
+				{
+				BIO_printf(err, "invalid depth\n");
+				*badarg = 1;
+				}
+			}
+		(*pargs)++;
+		}
+	else if (!strcmp(arg, "-ignore_critical"))
+		flags |= X509_V_FLAG_IGNORE_CRITICAL;
+	else if (!strcmp(arg, "-issuer_checks"))
+		flags |= X509_V_FLAG_CB_ISSUER_CHECK;
+	else if (!strcmp(arg, "-crl_check"))
+		flags |=  X509_V_FLAG_CRL_CHECK;
+	else if (!strcmp(arg, "-crl_check_all"))
+		flags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
+	else if (!strcmp(arg, "-policy_check"))
+		flags |= X509_V_FLAG_POLICY_CHECK;
+	else if (!strcmp(arg, "-explicit_policy"))
+		flags |= X509_V_FLAG_EXPLICIT_POLICY;
+	else if (!strcmp(arg, "-inhibit_any"))
+		flags |= X509_V_FLAG_INHIBIT_ANY;
+	else if (!strcmp(arg, "-inhibit_map"))
+		flags |= X509_V_FLAG_INHIBIT_MAP;
+	else if (!strcmp(arg, "-x509_strict"))
+		flags |= X509_V_FLAG_X509_STRICT;
+	else if (!strcmp(arg, "-extended_crl"))
+		flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT;
+	else if (!strcmp(arg, "-use_deltas"))
+		flags |= X509_V_FLAG_USE_DELTAS;
+	else if (!strcmp(arg, "-policy_print"))
+		flags |= X509_V_FLAG_NOTIFY_POLICY;
+	else if (!strcmp(arg, "-check_ss_sig"))
+		flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
+	else
+		return 0;
+
+	if (*badarg)
+		{
+		if (*pm)
+			X509_VERIFY_PARAM_free(*pm);
+		*pm = NULL;
+		goto end;
+		}
+
+	if (!*pm && !(*pm = X509_VERIFY_PARAM_new()))
+		{
+		*badarg = 1;
+		goto end;
+		}
+
+	if (otmp)
+		X509_VERIFY_PARAM_add0_policy(*pm, otmp);
+	if (flags)
+		X509_VERIFY_PARAM_set_flags(*pm, flags);
+
+	if (purpose)
+		X509_VERIFY_PARAM_set_purpose(*pm, purpose);
+
+	if (depth >= 0)
+		X509_VERIFY_PARAM_set_depth(*pm, depth);
+
+	end:
+
+	(*pargs)++;
+
+	if (pargc)
+		*pargc -= *pargs - oldargs;
+
+	return 1;
+
+	}
+
+/* Read whole contents of a BIO into an allocated memory buffer and
+ * return it.
+ */
+
+int bio_to_mem(unsigned char **out, int maxlen, BIO *in)
+	{
+	BIO *mem;
+	int len, ret;
+	unsigned char tbuf[1024];
+	mem = BIO_new(BIO_s_mem());
+	if (!mem)
+		return -1;
+	for(;;)
+		{
+		if ((maxlen != -1) && maxlen < 1024)
+			len = maxlen;
+		else
+			len = 1024;
+		len = BIO_read(in, tbuf, len);
+		if (len <= 0)
+			break;
+		if (BIO_write(mem, tbuf, len) != len)
+			{
+			BIO_free(mem);
+			return -1;
+			}
+		maxlen -= len;
+
+		if (maxlen == 0)
+			break;
+		}
+	ret = BIO_get_mem_data(mem, (char **)out);
+	BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY);
+	BIO_free(mem);
+	return ret;
+	}
+
+int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value)
+	{
+	int rv;
+	char *stmp, *vtmp = NULL;
+	stmp = BUF_strdup(value);
+	if (!stmp)
+		return -1;
+	vtmp = strchr(stmp, ':');
+	if (vtmp)
+		{
+		*vtmp = 0;
+		vtmp++;
+		}
+	rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
+	OPENSSL_free(stmp);
+	return rv;
+	}
+
+static void nodes_print(BIO *out, const char *name,
+	STACK_OF(X509_POLICY_NODE) *nodes)
+	{
+	X509_POLICY_NODE *node;
+	int i;
+	BIO_printf(out, "%s Policies:", name);
+	if (nodes)
+		{
+		BIO_puts(out, "\n");
+		for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++)
+			{
+			node = sk_X509_POLICY_NODE_value(nodes, i);
+			X509_POLICY_NODE_print(out, node, 2);
+			}
+		}
+	else
+		BIO_puts(out, " <empty>\n");
+	}
+
+void policies_print(BIO *out, X509_STORE_CTX *ctx)
+	{
+	X509_POLICY_TREE *tree;
+	int explicit_policy;
+	int free_out = 0;
+	if (out == NULL)
+		{
+		out = BIO_new_fp(stderr, BIO_NOCLOSE);
+		free_out = 1;
+		}
+	tree = X509_STORE_CTX_get0_policy_tree(ctx);
+	explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx);
+
+	BIO_printf(out, "Require explicit Policy: %s\n",
+				explicit_policy ? "True" : "False");
+
+	nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree));
+	nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree));
+	if (free_out)
+		BIO_free(out);
+	}
+
+#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
+
+static JPAKE_CTX *jpake_init(const char *us, const char *them,
+							 const char *secret)
+	{
+	BIGNUM *p = NULL;
+	BIGNUM *g = NULL;
+	BIGNUM *q = NULL;
+	BIGNUM *bnsecret = BN_new();
+	JPAKE_CTX *ctx;
+
+	/* Use a safe prime for p (that we found earlier) */
+	BN_hex2bn(&p, "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F");
+	g = BN_new();
+	BN_set_word(g, 2);
+	q = BN_new();
+	BN_rshift1(q, p);
+
+	BN_bin2bn((const unsigned char *)secret, strlen(secret), bnsecret);
+
+	ctx = JPAKE_CTX_new(us, them, p, g, q, bnsecret);
+	BN_free(bnsecret);
+	BN_free(q);
+	BN_free(g);
+	BN_free(p);
+
+	return ctx;
+	}
+
+static void jpake_send_part(BIO *conn, const JPAKE_STEP_PART *p)
+	{
+	BN_print(conn, p->gx);
+	BIO_puts(conn, "\n");
+	BN_print(conn, p->zkpx.gr);
+	BIO_puts(conn, "\n");
+	BN_print(conn, p->zkpx.b);
+	BIO_puts(conn, "\n");
+	}
+
+static void jpake_send_step1(BIO *bconn, JPAKE_CTX *ctx)
+	{
+	JPAKE_STEP1 s1;
+
+	JPAKE_STEP1_init(&s1);
+	JPAKE_STEP1_generate(&s1, ctx);
+	jpake_send_part(bconn, &s1.p1);
+	jpake_send_part(bconn, &s1.p2);
+	(void)BIO_flush(bconn);
+	JPAKE_STEP1_release(&s1);
+	}
+
+static void jpake_send_step2(BIO *bconn, JPAKE_CTX *ctx)
+	{
+	JPAKE_STEP2 s2;
+
+	JPAKE_STEP2_init(&s2);
+	JPAKE_STEP2_generate(&s2, ctx);
+	jpake_send_part(bconn, &s2);
+	(void)BIO_flush(bconn);
+	JPAKE_STEP2_release(&s2);
+	}
+
+static void jpake_send_step3a(BIO *bconn, JPAKE_CTX *ctx)
+	{
+	JPAKE_STEP3A s3a;
+
+	JPAKE_STEP3A_init(&s3a);
+	JPAKE_STEP3A_generate(&s3a, ctx);
+	BIO_write(bconn, s3a.hhk, sizeof s3a.hhk);
+	(void)BIO_flush(bconn);
+	JPAKE_STEP3A_release(&s3a);
+	}
+
+static void jpake_send_step3b(BIO *bconn, JPAKE_CTX *ctx)
+	{
+	JPAKE_STEP3B s3b;
+
+	JPAKE_STEP3B_init(&s3b);
+	JPAKE_STEP3B_generate(&s3b, ctx);
+	BIO_write(bconn, s3b.hk, sizeof s3b.hk);
+	(void)BIO_flush(bconn);
+	JPAKE_STEP3B_release(&s3b);
+	}
+
+static void readbn(BIGNUM **bn, BIO *bconn)
+	{
+	char buf[10240];
+	int l;
+
+	l = BIO_gets(bconn, buf, sizeof buf);
+	assert(l > 0);
+	assert(buf[l-1] == '\n');
+	buf[l-1] = '\0';
+	BN_hex2bn(bn, buf);
+	}
+
+static void jpake_receive_part(JPAKE_STEP_PART *p, BIO *bconn)
+	{
+	readbn(&p->gx, bconn);
+	readbn(&p->zkpx.gr, bconn);
+	readbn(&p->zkpx.b, bconn);
+	}
+
+static void jpake_receive_step1(JPAKE_CTX *ctx, BIO *bconn)
+	{
+	JPAKE_STEP1 s1;
+
+	JPAKE_STEP1_init(&s1);
+	jpake_receive_part(&s1.p1, bconn);
+	jpake_receive_part(&s1.p2, bconn);
+	if(!JPAKE_STEP1_process(ctx, &s1))
+		{
+		ERR_print_errors(bio_err);
+		exit(1);
+		}
+	JPAKE_STEP1_release(&s1);
+	}
+
+static void jpake_receive_step2(JPAKE_CTX *ctx, BIO *bconn)
+	{
+	JPAKE_STEP2 s2;
+
+	JPAKE_STEP2_init(&s2);
+	jpake_receive_part(&s2, bconn);
+	if(!JPAKE_STEP2_process(ctx, &s2))
+		{
+		ERR_print_errors(bio_err);
+		exit(1);
+		}
+	JPAKE_STEP2_release(&s2);
+	}
+
+static void jpake_receive_step3a(JPAKE_CTX *ctx, BIO *bconn)
+	{
+	JPAKE_STEP3A s3a;
+	int l;
+
+	JPAKE_STEP3A_init(&s3a);
+	l = BIO_read(bconn, s3a.hhk, sizeof s3a.hhk);
+	assert(l == sizeof s3a.hhk);
+	if(!JPAKE_STEP3A_process(ctx, &s3a))
+		{
+		ERR_print_errors(bio_err);
+		exit(1);
+		}
+	JPAKE_STEP3A_release(&s3a);
+	}
+
+static void jpake_receive_step3b(JPAKE_CTX *ctx, BIO *bconn)
+	{
+	JPAKE_STEP3B s3b;
+	int l;
+
+	JPAKE_STEP3B_init(&s3b);
+	l = BIO_read(bconn, s3b.hk, sizeof s3b.hk);
+	assert(l == sizeof s3b.hk);
+	if(!JPAKE_STEP3B_process(ctx, &s3b))
+		{
+		ERR_print_errors(bio_err);
+		exit(1);
+		}
+	JPAKE_STEP3B_release(&s3b);
+	}
+
+void jpake_client_auth(BIO *out, BIO *conn, const char *secret)
+	{
+	JPAKE_CTX *ctx;
+	BIO *bconn;
+
+	BIO_puts(out, "Authenticating with JPAKE\n");
+
+	ctx = jpake_init("client", "server", secret);
+
+	bconn = BIO_new(BIO_f_buffer());
+	BIO_push(bconn, conn);
+
+	jpake_send_step1(bconn, ctx);
+	jpake_receive_step1(ctx, bconn);
+	jpake_send_step2(bconn, ctx);
+	jpake_receive_step2(ctx, bconn);
+	jpake_send_step3a(bconn, ctx);
+	jpake_receive_step3b(ctx, bconn);
+
+	BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n");
+
+	psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx));
+
+	BIO_pop(bconn);
+	BIO_free(bconn);
+
+	JPAKE_CTX_free(ctx);
+	}
+
+void jpake_server_auth(BIO *out, BIO *conn, const char *secret)
+	{
+	JPAKE_CTX *ctx;
+	BIO *bconn;
+
+	BIO_puts(out, "Authenticating with JPAKE\n");
+
+	ctx = jpake_init("server", "client", secret);
+
+	bconn = BIO_new(BIO_f_buffer());
+	BIO_push(bconn, conn);
+
+	jpake_receive_step1(ctx, bconn);
+	jpake_send_step1(bconn, ctx);
+	jpake_receive_step2(ctx, bconn);
+	jpake_send_step2(bconn, ctx);
+	jpake_receive_step3a(ctx, bconn);
+	jpake_send_step3b(bconn, ctx);
+
+	BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n");
+
+	psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx));
+
+	BIO_pop(bconn);
+	BIO_free(bconn);
+
+	JPAKE_CTX_free(ctx);
+	}
+
+#endif
+
+/*
+ * Platform-specific sections
+ */
+#if defined(_WIN32)
+# ifdef fileno
+#  undef fileno
+#  define fileno(a) (int)_fileno(a)
+# endif
+
+# include <windows.h>
+# include <tchar.h>
+
+static int WIN32_rename(const char *from, const char *to)
+	{
+	TCHAR  *tfrom=NULL,*tto;
+	DWORD	err;
+	int	ret=0;
+
+	if (sizeof(TCHAR) == 1)
+		{
+		tfrom = (TCHAR *)from;
+		tto   = (TCHAR *)to;
+		}
+	else	/* UNICODE path */
+		{
+		size_t i,flen=strlen(from)+1,tlen=strlen(to)+1;
+		tfrom = (TCHAR *)malloc(sizeof(TCHAR)*(flen+tlen));
+		if (tfrom==NULL) goto err;
+		tto=tfrom+flen;
+#if !defined(_WIN32_WCE) || _WIN32_WCE>=101
+		if (!MultiByteToWideChar(CP_ACP,0,from,flen,(WCHAR *)tfrom,flen))
+#endif
+			for (i=0;i<flen;i++)	tfrom[i]=(TCHAR)from[i];
+#if !defined(_WIN32_WCE) || _WIN32_WCE>=101
+		if (!MultiByteToWideChar(CP_ACP,0,to,  tlen,(WCHAR *)tto,  tlen))
+#endif
+			for (i=0;i<tlen;i++)	tto[i]  =(TCHAR)to[i];
+		}
+
+	if (MoveFile(tfrom,tto))	goto ok;
+	err=GetLastError();
+	if (err==ERROR_ALREADY_EXISTS || err==ERROR_FILE_EXISTS)
+		{
+		if (DeleteFile(tto) && MoveFile(tfrom,tto))
+			goto ok;
+		err=GetLastError();
+		}
+	if (err==ERROR_FILE_NOT_FOUND || err==ERROR_PATH_NOT_FOUND)
+		errno = ENOENT;
+	else if (err==ERROR_ACCESS_DENIED)
+		errno = EACCES;
+	else
+		errno = EINVAL;	/* we could map more codes... */
+err:
+	ret=-1;
+ok:
+	if (tfrom!=NULL && tfrom!=(TCHAR *)from)	free(tfrom);
+	return ret;
+	}
+#endif
+
+/* app_tminterval section */
+#if defined(_WIN32)
+double app_tminterval(int stop,int usertime)
+	{
+	FILETIME		now;
+	double			ret=0;
+	static ULARGE_INTEGER	tmstart;
+	static int		warning=1;
+#ifdef _WIN32_WINNT
+	static HANDLE		proc=NULL;
+
+	if (proc==NULL)
+		{
+		if (GetVersion() < 0x80000000)
+			proc = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,
+						GetCurrentProcessId());
+		if (proc==NULL) proc = (HANDLE)-1;
+		}
+
+	if (usertime && proc!=(HANDLE)-1)
+		{
+		FILETIME junk;
+		GetProcessTimes(proc,&junk,&junk,&junk,&now);
+		}
+	else
+#endif
+		{
+		SYSTEMTIME systime;
+
+		if (usertime && warning)
+			{
+			BIO_printf(bio_err,"To get meaningful results, run "
+					   "this program on idle system.\n");
+			warning=0;
+			}
+		GetSystemTime(&systime);
+		SystemTimeToFileTime(&systime,&now);
+		}
+
+	if (stop==TM_START)
+		{
+		tmstart.u.LowPart  = now.dwLowDateTime;
+		tmstart.u.HighPart = now.dwHighDateTime;
+		}
+	else	{
+		ULARGE_INTEGER tmstop;
+
+		tmstop.u.LowPart   = now.dwLowDateTime;
+		tmstop.u.HighPart  = now.dwHighDateTime;
+
+		ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart)*1e-7;
+		}
+
+	return (ret);
+	}
+
+#elif defined(OPENSSL_SYS_NETWARE)
+#include <time.h>
+
+double app_tminterval(int stop,int usertime)
+	{
+	double		ret=0;
+	static clock_t	tmstart;
+	static int	warning=1;
+
+	if (usertime && warning)
+		{
+		BIO_printf(bio_err,"To get meaningful results, run "
+				   "this program on idle system.\n");
+		warning=0;
+		}
+
+	if (stop==TM_START)	tmstart = clock();
+	else			ret     = (clock()-tmstart)/(double)CLOCKS_PER_SEC;
+
+	return (ret);
+	}
+
+#elif defined(OPENSSL_SYSTEM_VXWORKS)
+#include <time.h>
+
+double app_tminterval(int stop,int usertime)
+	{
+	double ret=0;
+#ifdef CLOCK_REALTIME
+	static struct timespec	tmstart;
+	struct timespec		now;
+#else
+	static unsigned long	tmstart;
+	unsigned long		now;
+#endif
+	static int warning=1;
+
+	if (usertime && warning)
+		{
+		BIO_printf(bio_err,"To get meaningful results, run "
+				   "this program on idle system.\n");
+		warning=0;
+		}
+
+#ifdef CLOCK_REALTIME
+	clock_gettime(CLOCK_REALTIME,&now);
+	if (stop==TM_START)	tmstart = now;
+	else	ret = ( (now.tv_sec+now.tv_nsec*1e-9)
+			- (tmstart.tv_sec+tmstart.tv_nsec*1e-9) );
+#else
+	now = tickGet();
+	if (stop==TM_START)	tmstart = now;
+	else			ret = (now - tmstart)/(double)sysClkRateGet();
+#endif
+	return (ret);
+	}
+
+#elif defined(OPENSSL_SYSTEM_VMS)
+#include <time.h>
+#include <times.h>
+
+double app_tminterval(int stop,int usertime)
+	{
+	static clock_t	tmstart;
+	double		ret = 0;
+	clock_t		now;
+#ifdef __TMS
+	struct tms	rus;
+
+	now = times(&rus);
+	if (usertime)	now = rus.tms_utime;
+#else
+	if (usertime)
+		now = clock(); /* sum of user and kernel times */
+	else	{
+		struct timeval tv;
+		gettimeofday(&tv,NULL);
+		now = (clock_t)(
+			(unsigned long long)tv.tv_sec*CLK_TCK +
+			(unsigned long long)tv.tv_usec*(1000000/CLK_TCK)
+			);
+		}
+#endif
+	if (stop==TM_START)	tmstart = now;
+	else			ret = (now - tmstart)/(double)(CLK_TCK);
+
+	return (ret);
+	}
+
+#elif defined(_SC_CLK_TCK)	/* by means of unistd.h */
+#include <sys/times.h>
+
+double app_tminterval(int stop,int usertime)
+	{
+	double		ret = 0;
+	struct tms	rus;
+	clock_t		now = times(&rus);
+	static clock_t	tmstart;
+
+	if (usertime)		now = rus.tms_utime;
+
+	if (stop==TM_START)	tmstart = now;
+	else
+		{
+		long int tck = sysconf(_SC_CLK_TCK);
+		ret = (now - tmstart)/(double)tck;
+		}
+
+	return (ret);
+	}
+
+#else
+#include <sys/time.h>
+#include <sys/resource.h>
+
+double app_tminterval(int stop,int usertime)
+	{
+	double		ret = 0;
+	struct rusage	rus;
+	struct timeval	now;
+	static struct timeval tmstart;
+
+	if (usertime)		getrusage(RUSAGE_SELF,&rus), now = rus.ru_utime;
+	else			gettimeofday(&now,NULL);
+
+	if (stop==TM_START)	tmstart = now;
+	else			ret = ( (now.tv_sec+now.tv_usec*1e-6)
+					- (tmstart.tv_sec+tmstart.tv_usec*1e-6) );
+
+	return ret;
+	}
+#endif
+
+/* app_isdir section */
+#ifdef _WIN32
+int app_isdir(const char *name)
+	{
+	HANDLE		hList;
+	WIN32_FIND_DATA	FileData;
+#if defined(UNICODE) || defined(_UNICODE)
+	size_t i, len_0 = strlen(name)+1;
+
+	if (len_0 > sizeof(FileData.cFileName)/sizeof(FileData.cFileName[0]))
+		return -1;
+
+#if !defined(_WIN32_WCE) || _WIN32_WCE>=101
+	if (!MultiByteToWideChar(CP_ACP,0,name,len_0,FileData.cFileName,len_0))
+#endif
+		for (i=0;i<len_0;i++)
+			FileData.cFileName[i] = (WCHAR)name[i];
+
+	hList = FindFirstFile(FileData.cFileName,&FileData);
+#else
+	hList = FindFirstFile(name,&FileData);
+#endif
+	if (hList == INVALID_HANDLE_VALUE)	return -1;
+	FindClose(hList);
+	return ((FileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0);
+	}
+#else
+#include <sys/stat.h>
+#ifndef S_ISDIR
+# if defined(_S_IFMT) && defined(_S_IFDIR)
+#  define S_ISDIR(a)   (((a) & _S_IFMT) == _S_IFDIR)
+# else 
+#  define S_ISDIR(a)   (((a) & S_IFMT) == S_IFDIR)
+# endif 
+#endif 
+
+int app_isdir(const char *name)
+	{
+#if defined(S_ISDIR)
+	struct stat st;
+
+	if (stat(name,&st)==0)	return S_ISDIR(st.st_mode);
+	else			return -1;
+#else
+	return -1;
+#endif
+	}
+#endif
+
+/* raw_read|write section */
+#if defined(_WIN32) && defined(STD_INPUT_HANDLE)
+int raw_read_stdin(void *buf,int siz)
+	{
+	DWORD n;
+	if (ReadFile(GetStdHandle(STD_INPUT_HANDLE),buf,siz,&n,NULL))
+		return (n);
+	else	return (-1);
+	}
+#else
+int raw_read_stdin(void *buf,int siz)
+	{	return read(fileno(stdin),buf,siz);	}
+#endif
+
+#if defined(_WIN32) && defined(STD_OUTPUT_HANDLE)
+int raw_write_stdout(const void *buf,int siz)
+	{
+	DWORD n;
+	if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),buf,siz,&n,NULL))
+		return (n);
+	else	return (-1);
+	}
+#else
+int raw_write_stdout(const void *buf,int siz)
+	{	return write(fileno(stdout),buf,siz);	}
+#endif
+
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+/* next_protos_parse parses a comma separated list of strings into a string
+ * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
+ *   outlen: (output) set to the length of the resulting buffer on success.
+ *   in: a NUL termianted string like "abc,def,ghi"
+ *
+ *   returns: a malloced buffer or NULL on failure.
+ */
+unsigned char *next_protos_parse(unsigned short *outlen, const char *in)
+	{
+	size_t len;
+	unsigned char *out;
+	size_t i, start = 0;
+
+	len = strlen(in);
+	if (len >= 65535)
+		return NULL;
+
+	out = OPENSSL_malloc(strlen(in) + 1);
+	if (!out)
+		return NULL;
+
+	for (i = 0; i <= len; ++i)
+		{
+		if (i == len || in[i] == ',')
+			{
+			if (i - start > 255)
+				{
+				OPENSSL_free(out);
+				return NULL;
+				}
+			out[start] = i - start;
+			start = i + 1;
+			}
+		else
+			out[i+1] = in[i];
+		}
+
+	*outlen = len + 1;
+	return out;
+	}
+#endif  /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
diff --git a/openssl/apps/apps.h b/openssl/apps/apps.h
new file mode 100644
index 0000000..42072ec
--- /dev/null
+++ b/openssl/apps/apps.h
@@ -0,0 +1,364 @@
+/* apps/apps.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_APPS_H
+#define HEADER_APPS_H
+
+#include "e_os.h"
+
+#include <openssl/bio.h>
+#include <openssl/x509.h>
+#include <openssl/lhash.h>
+#include <openssl/conf.h>
+#include <openssl/txt_db.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#ifndef OPENSSL_NO_OCSP
+#include <openssl/ocsp.h>
+#endif
+#include <openssl/ossl_typ.h>
+
+int app_RAND_load_file(const char *file, BIO *bio_e, int dont_warn);
+int app_RAND_write_file(const char *file, BIO *bio_e);
+/* When `file' is NULL, use defaults.
+ * `bio_e' is for error messages. */
+void app_RAND_allow_write_file(void);
+long app_RAND_load_files(char *file); /* `file' is a list of files to read,
+                                       * separated by LIST_SEPARATOR_CHAR
+                                       * (see e_os.h).  The string is
+                                       * destroyed! */
+
+#ifndef MONOLITH
+
+#define MAIN(a,v)	main(a,v)
+
+#ifndef NON_MAIN
+CONF *config=NULL;
+BIO *bio_err=NULL;
+#else
+extern CONF *config;
+extern BIO *bio_err;
+#endif
+
+#else
+
+#define MAIN(a,v)	PROG(a,v)
+extern CONF *config;
+extern char *default_config_file;
+extern BIO *bio_err;
+
+#endif
+
+#ifndef OPENSSL_SYS_NETWARE
+#include <signal.h>
+#endif
+
+#ifdef SIGPIPE
+#define do_pipe_sig()	signal(SIGPIPE,SIG_IGN)
+#else
+#define do_pipe_sig()
+#endif
+
+#ifdef OPENSSL_NO_COMP
+#define zlib_cleanup() 
+#else
+#define zlib_cleanup() COMP_zlib_cleanup()
+#endif
+
+#if defined(MONOLITH) && !defined(OPENSSL_C)
+#  define apps_startup() \
+		do_pipe_sig()
+#  define apps_shutdown()
+#else
+#  ifndef OPENSSL_NO_ENGINE
+#    define apps_startup() \
+			do { do_pipe_sig(); CRYPTO_malloc_init(); \
+			ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); \
+			ENGINE_load_builtin_engines(); setup_ui_method(); } while(0)
+#    define apps_shutdown() \
+			do { CONF_modules_unload(1); destroy_ui_method(); \
+			OBJ_cleanup(); EVP_cleanup(); ENGINE_cleanup(); \
+			CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \
+			ERR_free_strings(); zlib_cleanup();} while(0)
+#  else
+#    define apps_startup() \
+			do { do_pipe_sig(); CRYPTO_malloc_init(); \
+			ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); \
+			setup_ui_method(); } while(0)
+#    define apps_shutdown() \
+			do { CONF_modules_unload(1); destroy_ui_method(); \
+			OBJ_cleanup(); EVP_cleanup(); \
+			CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \
+			ERR_free_strings(); zlib_cleanup(); } while(0)
+#  endif
+#endif
+
+#ifdef OPENSSL_SYSNAME_WIN32
+#  define openssl_fdset(a,b) FD_SET((unsigned int)a, b)
+#else
+#  define openssl_fdset(a,b) FD_SET(a, b)
+#endif
+
+
+typedef struct args_st
+	{
+	char **data;
+	int count;
+	} ARGS;
+
+#define PW_MIN_LENGTH 4
+typedef struct pw_cb_data
+	{
+	const void *password;
+	const char *prompt_info;
+	} PW_CB_DATA;
+
+int password_callback(char *buf, int bufsiz, int verify,
+	PW_CB_DATA *cb_data);
+
+int setup_ui_method(void);
+void destroy_ui_method(void);
+
+int should_retry(int i);
+int args_from_file(char *file, int *argc, char **argv[]);
+int str2fmt(char *s);
+void program_name(char *in,char *out,int size);
+int chopup_args(ARGS *arg,char *buf, int *argc, char **argv[]);
+#ifdef HEADER_X509_H
+int dump_cert_text(BIO *out, X509 *x);
+void print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags);
+#endif
+int set_cert_ex(unsigned long *flags, const char *arg);
+int set_name_ex(unsigned long *flags, const char *arg);
+int set_ext_copy(int *copy_type, const char *arg);
+int copy_extensions(X509 *x, X509_REQ *req, int copy_type);
+int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2);
+int add_oid_section(BIO *err, CONF *conf);
+X509 *load_cert(BIO *err, const char *file, int format,
+	const char *pass, ENGINE *e, const char *cert_descrip);
+EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
+	const char *pass, ENGINE *e, const char *key_descrip);
+EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
+	const char *pass, ENGINE *e, const char *key_descrip);
+STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
+	const char *pass, ENGINE *e, const char *cert_descrip);
+STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
+	const char *pass, ENGINE *e, const char *cert_descrip);
+X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath);
+#ifndef OPENSSL_NO_ENGINE
+ENGINE *setup_engine(BIO *err, const char *engine, int debug);
+#endif
+
+#ifndef OPENSSL_NO_OCSP
+OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
+			char *host, char *path, char *port, int use_ssl,
+			STACK_OF(CONF_VALUE) *headers,
+			int req_timeout);
+#endif
+
+int load_config(BIO *err, CONF *cnf);
+char *make_config_name(void);
+
+/* Functions defined in ca.c and also used in ocsp.c */
+int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
+			ASN1_GENERALIZEDTIME **pinvtm, const char *str);
+
+#define DB_type         0
+#define DB_exp_date     1
+#define DB_rev_date     2
+#define DB_serial       3       /* index - unique */
+#define DB_file         4       
+#define DB_name         5       /* index - unique when active and not disabled */
+#define DB_NUMBER       6
+
+#define DB_TYPE_REV	'R'
+#define DB_TYPE_EXP	'E'
+#define DB_TYPE_VAL	'V'
+
+typedef struct db_attr_st
+	{
+	int unique_subject;
+	} DB_ATTR;
+typedef struct ca_db_st
+	{
+	DB_ATTR attributes;
+	TXT_DB *db;
+	} CA_DB;
+
+BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai);
+int save_serial(char *serialfile, char *suffix, BIGNUM *serial, ASN1_INTEGER **retai);
+int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix);
+int rand_serial(BIGNUM *b, ASN1_INTEGER *ai);
+CA_DB *load_index(char *dbfile, DB_ATTR *dbattr);
+int index_index(CA_DB *db);
+int save_index(const char *dbfile, const char *suffix, CA_DB *db);
+int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix);
+void free_index(CA_DB *db);
+#define index_name_cmp_noconst(a, b) \
+	index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \
+	(const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b))
+int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b);
+int parse_yesno(const char *str, int def);
+
+X509_NAME *parse_name(char *str, long chtype, int multirdn);
+int args_verify(char ***pargs, int *pargc,
+			int *badarg, BIO *err, X509_VERIFY_PARAM **pm);
+void policies_print(BIO *out, X509_STORE_CTX *ctx);
+int bio_to_mem(unsigned char **out, int maxlen, BIO *in);
+int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value);
+int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
+			const char *algname, ENGINE *e, int do_param);
+#ifndef OPENSSL_NO_PSK
+extern char *psk_key;
+#endif
+#ifndef OPENSSL_NO_JPAKE
+void jpake_client_auth(BIO *out, BIO *conn, const char *secret);
+void jpake_server_auth(BIO *out, BIO *conn, const char *secret);
+#endif
+
+#define FORMAT_UNDEF    0
+#define FORMAT_ASN1     1
+#define FORMAT_TEXT     2
+#define FORMAT_PEM      3
+#define FORMAT_NETSCAPE 4
+#define FORMAT_PKCS12   5
+#define FORMAT_SMIME    6
+#define FORMAT_ENGINE   7
+#define FORMAT_IISSGC	8	/* XXX this stupid macro helps us to avoid
+				 * adding yet another param to load_*key() */
+#define FORMAT_PEMRSA	9	/* PEM RSAPubicKey format */
+#define FORMAT_ASN1RSA	10	/* DER RSAPubicKey format */
+#define FORMAT_MSBLOB	11	/* MS Key blob format */
+#define FORMAT_PVK	12	/* MS PVK file format */
+
+#define EXT_COPY_NONE	0
+#define EXT_COPY_ADD	1
+#define EXT_COPY_ALL	2
+
+#define NETSCAPE_CERT_HDR	"certificate"
+
+#define APP_PASS_LEN	1024
+
+#define SERIAL_RAND_BITS	64
+
+int app_isdir(const char *);
+int raw_read_stdin(void *,int);
+int raw_write_stdout(const void *,int);
+
+#define TM_START	0
+#define TM_STOP		1
+double app_tminterval (int stop,int usertime);
+#endif
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+unsigned char *next_protos_parse(unsigned short *outlen, const char *in);
+#endif
diff --git a/openssl/apps/asn1pars.c b/openssl/apps/asn1pars.c
new file mode 100644
index 0000000..0d66070
--- /dev/null
+++ b/openssl/apps/asn1pars.c
@@ -0,0 +1,445 @@
+/* apps/asn1pars.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* A nice addition from Dr Stephen Henson <steve@openssl.org> to 
+ * add the -strparse option which parses nested binary structures
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+/* -inform arg	- input format - default PEM (DER or PEM)
+ * -in arg	- input file - default stdin
+ * -i		- indent the details by depth
+ * -offset	- where in the file to start
+ * -length	- how many bytes to use
+ * -oid file	- extra oid description file
+ */
+
+#undef PROG
+#define PROG	asn1parse_main
+
+int MAIN(int, char **);
+
+static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf);
+
+int MAIN(int argc, char **argv)
+	{
+	int i,badops=0,offset=0,ret=1,j;
+	unsigned int length=0;
+	long num,tmplen;
+	BIO *in=NULL,*out=NULL,*b64=NULL, *derout = NULL;
+	int informat,indent=0, noout = 0, dump = 0;
+	char *infile=NULL,*str=NULL,*prog,*oidfile=NULL, *derfile=NULL;
+	char *genstr=NULL, *genconf=NULL;
+	unsigned char *tmpbuf;
+	const unsigned char *ctmpbuf;
+	BUF_MEM *buf=NULL;
+	STACK_OF(OPENSSL_STRING) *osk=NULL;
+	ASN1_TYPE *at=NULL;
+
+	informat=FORMAT_PEM;
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	prog=argv[0];
+	argc--;
+	argv++;
+	if ((osk=sk_OPENSSL_STRING_new_null()) == NULL)
+		{
+		BIO_printf(bio_err,"Memory allocation failure\n");
+		goto end;
+		}
+	while (argc >= 1)
+		{
+		if 	(strcmp(*argv,"-inform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			informat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			derfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-i") == 0)
+			{
+			indent=1;
+			}
+		else if (strcmp(*argv,"-noout") == 0) noout = 1;
+		else if (strcmp(*argv,"-oid") == 0)
+			{
+			if (--argc < 1) goto bad;
+			oidfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-offset") == 0)
+			{
+			if (--argc < 1) goto bad;
+			offset= atoi(*(++argv));
+			}
+		else if (strcmp(*argv,"-length") == 0)
+			{
+			if (--argc < 1) goto bad;
+			length= atoi(*(++argv));
+			if (length == 0) goto bad;
+			}
+		else if (strcmp(*argv,"-dump") == 0)
+			{
+			dump= -1;
+			}
+		else if (strcmp(*argv,"-dlimit") == 0)
+			{
+			if (--argc < 1) goto bad;
+			dump= atoi(*(++argv));
+			if (dump <= 0) goto bad;
+			}
+		else if (strcmp(*argv,"-strparse") == 0)
+			{
+			if (--argc < 1) goto bad;
+			sk_OPENSSL_STRING_push(osk,*(++argv));
+			}
+		else if (strcmp(*argv,"-genstr") == 0)
+			{
+			if (--argc < 1) goto bad;
+			genstr= *(++argv);
+			}
+		else if (strcmp(*argv,"-genconf") == 0)
+			{
+			if (--argc < 1) goto bad;
+			genconf= *(++argv);
+			}
+		else
+			{
+			BIO_printf(bio_err,"unknown option %s\n",*argv);
+			badops=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (badops)
+		{
+bad:
+		BIO_printf(bio_err,"%s [options] <infile\n",prog);
+		BIO_printf(bio_err,"where options are\n");
+		BIO_printf(bio_err," -inform arg   input format - one of DER PEM\n");
+		BIO_printf(bio_err," -in arg       input file\n");
+		BIO_printf(bio_err," -out arg      output file (output format is always DER\n");
+		BIO_printf(bio_err," -noout arg    don't produce any output\n");
+		BIO_printf(bio_err," -offset arg   offset into file\n");
+		BIO_printf(bio_err," -length arg   length of section in file\n");
+		BIO_printf(bio_err," -i            indent entries\n");
+		BIO_printf(bio_err," -dump         dump unknown data in hex form\n");
+		BIO_printf(bio_err," -dlimit arg   dump the first arg bytes of unknown data in hex form\n");
+		BIO_printf(bio_err," -oid file     file of extra oid definitions\n");
+		BIO_printf(bio_err," -strparse offset\n");
+		BIO_printf(bio_err,"               a series of these can be used to 'dig' into multiple\n");
+		BIO_printf(bio_err,"               ASN1 blob wrappings\n");
+		BIO_printf(bio_err," -genstr str   string to generate ASN1 structure from\n");
+		BIO_printf(bio_err," -genconf file file to generate ASN1 structure from\n");
+		goto end;
+		}
+
+	ERR_load_crypto_strings();
+
+	in=BIO_new(BIO_s_file());
+	out=BIO_new(BIO_s_file());
+	if ((in == NULL) || (out == NULL))
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+	BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
+#ifdef OPENSSL_SYS_VMS
+	{
+	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+	out = BIO_push(tmpbio, out);
+	}
+#endif
+
+	if (oidfile != NULL)
+		{
+		if (BIO_read_filename(in,oidfile) <= 0)
+			{
+			BIO_printf(bio_err,"problems opening %s\n",oidfile);
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		OBJ_create_objects(in);
+		}
+
+	if (infile == NULL)
+		BIO_set_fp(in,stdin,BIO_NOCLOSE);
+	else
+		{
+		if (BIO_read_filename(in,infile) <= 0)
+			{
+			perror(infile);
+			goto end;
+			}
+		}
+
+	if (derfile) {
+		if(!(derout = BIO_new_file(derfile, "wb"))) {
+			BIO_printf(bio_err,"problems opening %s\n",derfile);
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+	}
+
+	if ((buf=BUF_MEM_new()) == NULL) goto end;
+	if (!BUF_MEM_grow(buf,BUFSIZ*8)) goto end; /* Pre-allocate :-) */
+
+	if (genstr || genconf)
+		{
+		num = do_generate(bio_err, genstr, genconf, buf);
+		if (num < 0)
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+
+	else
+		{
+
+		if (informat == FORMAT_PEM)
+			{
+			BIO *tmp;
+
+			if ((b64=BIO_new(BIO_f_base64())) == NULL)
+				goto end;
+			BIO_push(b64,in);
+			tmp=in;
+			in=b64;
+			b64=tmp;
+			}
+
+		num=0;
+		for (;;)
+			{
+			if (!BUF_MEM_grow(buf,(int)num+BUFSIZ)) goto end;
+			i=BIO_read(in,&(buf->data[num]),BUFSIZ);
+			if (i <= 0) break;
+			num+=i;
+			}
+		}
+	str=buf->data;
+
+	/* If any structs to parse go through in sequence */
+
+	if (sk_OPENSSL_STRING_num(osk))
+		{
+		tmpbuf=(unsigned char *)str;
+		tmplen=num;
+		for (i=0; i<sk_OPENSSL_STRING_num(osk); i++)
+			{
+			ASN1_TYPE *atmp;
+			int typ;
+			j=atoi(sk_OPENSSL_STRING_value(osk,i));
+			if (j == 0)
+				{
+				BIO_printf(bio_err,"'%s' is an invalid number\n",sk_OPENSSL_STRING_value(osk,i));
+				continue;
+				}
+			tmpbuf+=j;
+			tmplen-=j;
+			atmp = at;
+			ctmpbuf = tmpbuf;
+			at = d2i_ASN1_TYPE(NULL,&ctmpbuf,tmplen);
+			ASN1_TYPE_free(atmp);
+			if(!at)
+				{
+				BIO_printf(bio_err,"Error parsing structure\n");
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+			typ = ASN1_TYPE_get(at);
+			if ((typ == V_ASN1_OBJECT)
+				|| (typ == V_ASN1_NULL))
+				{
+				BIO_printf(bio_err, "Can't parse %s type\n",
+					typ == V_ASN1_NULL ? "NULL" : "OBJECT");
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+			/* hmm... this is a little evil but it works */
+			tmpbuf=at->value.asn1_string->data;
+			tmplen=at->value.asn1_string->length;
+			}
+		str=(char *)tmpbuf;
+		num=tmplen;
+		}
+
+	if (offset >= num)
+		{
+		BIO_printf(bio_err, "Error: offset too large\n");
+		goto end;
+		}
+
+	num -= offset;
+
+	if ((length == 0) || ((long)length > num)) length=(unsigned int)num;
+	if(derout) {
+		if(BIO_write(derout, str + offset, length) != (int)length) {
+			BIO_printf(bio_err, "Error writing output\n");
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+	}
+	if (!noout &&
+	    !ASN1_parse_dump(out,(unsigned char *)&(str[offset]),length,
+		    indent,dump))
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+	ret=0;
+end:
+	BIO_free(derout);
+	if (in != NULL) BIO_free(in);
+	if (out != NULL) BIO_free_all(out);
+	if (b64 != NULL) BIO_free(b64);
+	if (ret != 0)
+		ERR_print_errors(bio_err);
+	if (buf != NULL) BUF_MEM_free(buf);
+	if (at != NULL) ASN1_TYPE_free(at);
+	if (osk != NULL) sk_OPENSSL_STRING_free(osk);
+	OBJ_cleanup();
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
+static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf)
+	{
+	CONF *cnf = NULL;
+	int len;
+	long errline;
+	unsigned char *p;
+	ASN1_TYPE *atyp = NULL;
+
+	if (genconf)
+		{
+		cnf = NCONF_new(NULL);
+		if (!NCONF_load(cnf, genconf, &errline))
+			goto conferr;
+		if (!genstr)
+			genstr = NCONF_get_string(cnf, "default", "asn1");
+		if (!genstr)
+			{
+			BIO_printf(bio, "Can't find 'asn1' in '%s'\n", genconf);
+			goto err;
+			}
+		}
+
+	atyp = ASN1_generate_nconf(genstr, cnf);
+	NCONF_free(cnf);
+	cnf = NULL;
+
+	if (!atyp)
+		return -1;
+
+	len = i2d_ASN1_TYPE(atyp, NULL);
+
+	if (len <= 0)
+		goto err;
+
+	if (!BUF_MEM_grow(buf,len))
+		goto err;
+
+	p=(unsigned char *)buf->data;
+
+	i2d_ASN1_TYPE(atyp, &p);
+
+	ASN1_TYPE_free(atyp);
+	return len;
+
+	conferr:
+
+	if (errline > 0)
+		BIO_printf(bio, "Error on line %ld of config file '%s'\n",
+							errline, genconf);
+	else
+		BIO_printf(bio, "Error loading config file '%s'\n", genconf);
+
+	err:
+	NCONF_free(cnf);
+	ASN1_TYPE_free(atyp);
+
+	return -1;
+
+	}
diff --git a/openssl/apps/ca-cert.srl b/openssl/apps/ca-cert.srl
new file mode 100644
index 0000000..2c7456e
--- /dev/null
+++ b/openssl/apps/ca-cert.srl
@@ -0,0 +1 @@
+07
diff --git a/openssl/apps/ca-key.pem b/openssl/apps/ca-key.pem
new file mode 100644
index 0000000..3a520b2
--- /dev/null
+++ b/openssl/apps/ca-key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQCju6PLddelT+nIMm07GQwmYa/eZ2JWbsmt2gotSCqM7asFp425
+gxSK4jqhhT62UPpqDBEwvQ+fYkVv3RV0r9ReuZGv12NoS4fXsQgqO17lHA7Od0Kd
+2yNwJjKh44MxPKDt2o8iQMyZE0zlHnEFNpsP4COLTDNC6ljEEu5bk8uPsQIDAQAB
+AoGAVZmpFZsDZfr0l2S9tLLwpjRWNOlKATQkno6q2WesT0eGLQufTciY+c8ypfU6
+hyio8r5iUl/VhhdjhAtKx1mRpiotftHo/eYf8rtsrnprOnWG0bWjLjtIoMbcxGn2
+J3bN6LJmbJMjDs0eJ3KnTu646F3nDUw2oGAwmpzKXA1KAP0CQQDRvQhxk2D3Pehs
+HvG665u2pB5ipYQngEFlZO7RHJZzJOZEWSLuuMqaF/7pTfA5jiBvWqCgJeCRRInL
+21ru4dlPAkEAx9jj7BgKn5TYnMoBSSe0afjsV9oApVpN1Nacb1YDtCwy+scp3++s
+nFxlv98wxIlSdpwMUn+AUWfjiWR7Tu/G/wJBAJ/KjwZIrFVxewP0x2ILYsTRYLzz
+MS4PDsO7FB+I0i7DbBOifXS2oNSpd3I0CNMwrxFnUHzynpbOStVfN3ZL5w0CQQCa
+pwFahxBRhkJKsxhjoFJBX9yl75JoY4Wvm5Tbo9ih6UJaRx3kqfkN14L2BKYcsZgb
+KY9vmDOYy6iNfjDeWTfJAkBkfPUb8oTJ/nSP5zN6sqGxSY4krc4xLxpRmxoJ8HL2
+XfhqXkTzbU13RX9JJ/NZ8vQN9Vm2NhxRGJocQkmcdVtJ
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/apps/ca-req.pem b/openssl/apps/ca-req.pem
new file mode 100644
index 0000000..77bf7ec
--- /dev/null
+++ b/openssl/apps/ca-req.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBmTCCAQICAQAwWzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQx
+GjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYDVQQDExJUZXN0IENBICgx
+MDI0IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKO7o8t116VP6cgy
+bTsZDCZhr95nYlZuya3aCi1IKoztqwWnjbmDFIriOqGFPrZQ+moMETC9D59iRW/d
+FXSv1F65ka/XY2hLh9exCCo7XuUcDs53Qp3bI3AmMqHjgzE8oO3ajyJAzJkTTOUe
+cQU2mw/gI4tMM0LqWMQS7luTy4+xAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAKlk7
+cxu9gCJN3/iQFyJXQ6YphaiQAT5VBXTx9ftRrQIjA3vxlDzPWGDy+V5Tqa7h8PtR
+5Bn00JShII2zf0hjyjKils6x/UkWmjEiwSiFp4hR70iE8XwSNEHY2P6j6nQEIpgW
+kbfgmmUqk7dl2V+ossTJ80B8SBpEhrn81V/cHxA=
+-----END CERTIFICATE REQUEST-----
diff --git a/openssl/apps/ca.c b/openssl/apps/ca.c
new file mode 100644
index 0000000..6b8b0ef
--- /dev/null
+++ b/openssl/apps/ca.c
@@ -0,0 +1,2985 @@
+/* apps/ca.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* The PPKI stuff has been donated by Jeff Barber <jeffb@issl.atl.hp.com> */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <openssl/conf.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/txt_db.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/objects.h>
+#include <openssl/ocsp.h>
+#include <openssl/pem.h>
+
+#ifndef W_OK
+#  ifdef OPENSSL_SYS_VMS
+#    if defined(__DECC)
+#      include <unistd.h>
+#    else
+#      include <unixlib.h>
+#    endif
+#  elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_NETWARE)
+#    include <sys/file.h>
+#  endif
+#endif
+
+#include "apps.h"
+
+#ifndef W_OK
+#  define F_OK 0
+#  define X_OK 1
+#  define W_OK 2
+#  define R_OK 4
+#endif
+
+#undef PROG
+#define PROG ca_main
+
+#define BASE_SECTION	"ca"
+#define CONFIG_FILE "openssl.cnf"
+
+#define ENV_DEFAULT_CA		"default_ca"
+
+#define STRING_MASK	"string_mask"
+#define UTF8_IN			"utf8"
+
+#define ENV_DIR			"dir"
+#define ENV_CERTS		"certs"
+#define ENV_CRL_DIR		"crl_dir"
+#define ENV_CA_DB		"CA_DB"
+#define ENV_NEW_CERTS_DIR	"new_certs_dir"
+#define ENV_CERTIFICATE 	"certificate"
+#define ENV_SERIAL		"serial"
+#define ENV_CRLNUMBER		"crlnumber"
+#define ENV_CRL			"crl"
+#define ENV_PRIVATE_KEY		"private_key"
+#define ENV_RANDFILE		"RANDFILE"
+#define ENV_DEFAULT_DAYS 	"default_days"
+#define ENV_DEFAULT_STARTDATE 	"default_startdate"
+#define ENV_DEFAULT_ENDDATE 	"default_enddate"
+#define ENV_DEFAULT_CRL_DAYS 	"default_crl_days"
+#define ENV_DEFAULT_CRL_HOURS 	"default_crl_hours"
+#define ENV_DEFAULT_MD		"default_md"
+#define ENV_DEFAULT_EMAIL_DN	"email_in_dn"
+#define ENV_PRESERVE		"preserve"
+#define ENV_POLICY      	"policy"
+#define ENV_EXTENSIONS      	"x509_extensions"
+#define ENV_CRLEXT      	"crl_extensions"
+#define ENV_MSIE_HACK		"msie_hack"
+#define ENV_NAMEOPT		"name_opt"
+#define ENV_CERTOPT		"cert_opt"
+#define ENV_EXTCOPY		"copy_extensions"
+#define ENV_UNIQUE_SUBJECT	"unique_subject"
+
+#define ENV_DATABASE		"database"
+
+/* Additional revocation information types */
+
+#define REV_NONE		0	/* No addditional information */
+#define REV_CRL_REASON		1	/* Value is CRL reason code */
+#define REV_HOLD		2	/* Value is hold instruction */
+#define REV_KEY_COMPROMISE	3	/* Value is cert key compromise time */
+#define REV_CA_COMPROMISE	4	/* Value is CA key compromise time */
+
+static const char *ca_usage[]={
+"usage: ca args\n",
+"\n",
+" -verbose        - Talk alot while doing things\n",
+" -config file    - A config file\n",
+" -name arg       - The particular CA definition to use\n",
+" -gencrl         - Generate a new CRL\n",
+" -crldays days   - Days is when the next CRL is due\n",
+" -crlhours hours - Hours is when the next CRL is due\n",
+" -startdate YYMMDDHHMMSSZ  - certificate validity notBefore\n",
+" -enddate YYMMDDHHMMSSZ    - certificate validity notAfter (overrides -days)\n",
+" -days arg       - number of days to certify the certificate for\n",
+" -md arg         - md to use, one of md2, md5, sha or sha1\n",
+" -policy arg     - The CA 'policy' to support\n",
+" -keyfile arg    - private key file\n",
+" -keyform arg    - private key file format (PEM or ENGINE)\n",
+" -key arg        - key to decode the private key if it is encrypted\n",
+" -cert file      - The CA certificate\n",
+" -selfsign       - sign a certificate with the key associated with it\n",
+" -in file        - The input PEM encoded certificate request(s)\n",
+" -out file       - Where to put the output file(s)\n",
+" -outdir dir     - Where to put output certificates\n",
+" -infiles ....   - The last argument, requests to process\n",
+" -spkac file     - File contains DN and signed public key and challenge\n",
+" -ss_cert file   - File contains a self signed cert to sign\n",
+" -preserveDN     - Don't re-order the DN\n",
+" -noemailDN      - Don't add the EMAIL field into certificate' subject\n",
+" -batch          - Don't ask questions\n",
+" -msie_hack      - msie modifications to handle all those universal strings\n",
+" -revoke file    - Revoke a certificate (given in file)\n",
+" -subj arg       - Use arg instead of request's subject\n",
+" -utf8           - input characters are UTF8 (default ASCII)\n",
+" -multivalue-rdn - enable support for multivalued RDNs\n",
+" -extensions ..  - Extension section (override value in config file)\n",
+" -extfile file   - Configuration file with X509v3 extentions to add\n",
+" -crlexts ..     - CRL extension section (override value in config file)\n",
+#ifndef OPENSSL_NO_ENGINE
+" -engine e       - use engine e, possibly a hardware device.\n",
+#endif
+" -status serial  - Shows certificate status given the serial number\n",
+" -updatedb       - Updates db for expired certificates\n",
+NULL
+};
+
+#ifdef EFENCE
+extern int EF_PROTECT_FREE;
+extern int EF_PROTECT_BELOW;
+extern int EF_ALIGNMENT;
+#endif
+
+static void lookup_fail(const char *name, const char *tag);
+static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
+		   const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,CA_DB *db,
+		   BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate,
+		   char *enddate, long days, int batch, char *ext_sect, CONF *conf,
+		   int verbose, unsigned long certopt, unsigned long nameopt,
+		   int default_op, int ext_copy, int selfsign);
+static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
+			const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
+			CA_DB *db, BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn,
+			char *startdate, char *enddate, long days, int batch,
+			char *ext_sect, CONF *conf,int verbose, unsigned long certopt,
+			unsigned long nameopt, int default_op, int ext_copy,
+			ENGINE *e);
+static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
+			 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
+			 CA_DB *db, BIGNUM *serial,char *subj,unsigned long chtype, int multirdn, int email_dn,
+			 char *startdate, char *enddate, long days, char *ext_sect,
+			 CONF *conf, int verbose, unsigned long certopt, 
+			 unsigned long nameopt, int default_op, int ext_copy);
+static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
+static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
+	STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,char *subj,unsigned long chtype, int multirdn,
+	int email_dn, char *startdate, char *enddate, long days, int batch,
+       	int verbose, X509_REQ *req, char *ext_sect, CONF *conf,
+	unsigned long certopt, unsigned long nameopt, int default_op,
+	int ext_copy, int selfsign);
+static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval);
+static int get_certificate_status(const char *ser_status, CA_DB *db);
+static int do_updatedb(CA_DB *db);
+static int check_time_format(const char *str);
+char *make_revocation_str(int rev_type, char *rev_arg);
+int make_revoked(X509_REVOKED *rev, const char *str);
+int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
+static CONF *conf=NULL;
+static CONF *extconf=NULL;
+static char *section=NULL;
+
+static int preserve=0;
+static int msie_hack=0;
+
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	ENGINE *e = NULL;
+	char *key=NULL,*passargin=NULL;
+	int create_ser = 0;
+	int free_key = 0;
+	int total=0;
+	int total_done=0;
+	int badops=0;
+	int ret=1;
+	int email_dn=1;
+	int req=0;
+	int verbose=0;
+	int gencrl=0;
+	int dorevoke=0;
+	int doupdatedb=0;
+	long crldays=0;
+	long crlhours=0;
+	long crlsec=0;
+	long errorline= -1;
+	char *configfile=NULL;
+	char *md=NULL;
+	char *policy=NULL;
+	char *keyfile=NULL;
+	char *certfile=NULL;
+	int keyform=FORMAT_PEM;
+	char *infile=NULL;
+	char *spkac_file=NULL;
+	char *ss_cert_file=NULL;
+	char *ser_status=NULL;
+	EVP_PKEY *pkey=NULL;
+	int output_der = 0;
+	char *outfile=NULL;
+	char *outdir=NULL;
+	char *serialfile=NULL;
+	char *crlnumberfile=NULL;
+	char *extensions=NULL;
+	char *extfile=NULL;
+	char *subj=NULL;
+	unsigned long chtype = MBSTRING_ASC;
+	int multirdn = 0;
+	char *tmp_email_dn=NULL;
+	char *crl_ext=NULL;
+	int rev_type = REV_NONE;
+	char *rev_arg = NULL;
+	BIGNUM *serial=NULL;
+	BIGNUM *crlnumber=NULL;
+	char *startdate=NULL;
+	char *enddate=NULL;
+	long days=0;
+	int batch=0;
+	int notext=0;
+	unsigned long nameopt = 0, certopt = 0;
+	int default_op = 1;
+	int ext_copy = EXT_COPY_NONE;
+	int selfsign = 0;
+	X509 *x509=NULL, *x509p = NULL;
+	X509 *x=NULL;
+	BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
+	char *dbfile=NULL;
+	CA_DB *db=NULL;
+	X509_CRL *crl=NULL;
+	X509_REVOKED *r=NULL;
+	ASN1_TIME *tmptm;
+	ASN1_INTEGER *tmpser;
+	char *f;
+	const char *p;
+	char * const *pp;
+	int i,j;
+	const EVP_MD *dgst=NULL;
+	STACK_OF(CONF_VALUE) *attribs=NULL;
+	STACK_OF(X509) *cert_sk=NULL;
+#undef BSIZE
+#define BSIZE 256
+	MS_STATIC char buf[3][BSIZE];
+	char *randfile=NULL;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine = NULL;
+#endif
+	char *tofree=NULL;
+	DB_ATTR db_attr;
+
+#ifdef EFENCE
+EF_PROTECT_FREE=1;
+EF_PROTECT_BELOW=1;
+EF_ALIGNMENT=0;
+#endif
+
+	apps_startup();
+
+	conf = NULL;
+	key = NULL;
+	section = NULL;
+
+	preserve=0;
+	msie_hack=0;
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if	(strcmp(*argv,"-verbose") == 0)
+			verbose=1;
+		else if	(strcmp(*argv,"-config") == 0)
+			{
+			if (--argc < 1) goto bad;
+			configfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-name") == 0)
+			{
+			if (--argc < 1) goto bad;
+			section= *(++argv);
+			}
+		else if (strcmp(*argv,"-subj") == 0)
+			{
+			if (--argc < 1) goto bad;
+			subj= *(++argv);
+			/* preserve=1; */
+			}
+		else if (strcmp(*argv,"-utf8") == 0)
+			chtype = MBSTRING_UTF8;
+		else if (strcmp(*argv,"-create_serial") == 0)
+			create_ser = 1;
+		else if (strcmp(*argv,"-multivalue-rdn") == 0)
+			multirdn=1;
+		else if (strcmp(*argv,"-startdate") == 0)
+			{
+			if (--argc < 1) goto bad;
+			startdate= *(++argv);
+			}
+		else if (strcmp(*argv,"-enddate") == 0)
+			{
+			if (--argc < 1) goto bad;
+			enddate= *(++argv);
+			}
+		else if (strcmp(*argv,"-days") == 0)
+			{
+			if (--argc < 1) goto bad;
+			days=atoi(*(++argv));
+			}
+		else if (strcmp(*argv,"-md") == 0)
+			{
+			if (--argc < 1) goto bad;
+			md= *(++argv);
+			}
+		else if (strcmp(*argv,"-policy") == 0)
+			{
+			if (--argc < 1) goto bad;
+			policy= *(++argv);
+			}
+		else if (strcmp(*argv,"-keyfile") == 0)
+			{
+			if (--argc < 1) goto bad;
+			keyfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-keyform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			keyform=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-passin") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passargin= *(++argv);
+			}
+		else if (strcmp(*argv,"-key") == 0)
+			{
+			if (--argc < 1) goto bad;
+			key= *(++argv);
+			}
+		else if (strcmp(*argv,"-cert") == 0)
+			{
+			if (--argc < 1) goto bad;
+			certfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-selfsign") == 0)
+			selfsign=1;
+		else if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			req=1;
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-outdir") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outdir= *(++argv);
+			}
+		else if (strcmp(*argv,"-notext") == 0)
+			notext=1;
+		else if (strcmp(*argv,"-batch") == 0)
+			batch=1;
+		else if (strcmp(*argv,"-preserveDN") == 0)
+			preserve=1;
+		else if (strcmp(*argv,"-noemailDN") == 0)
+			email_dn=0;
+		else if (strcmp(*argv,"-gencrl") == 0)
+			gencrl=1;
+		else if (strcmp(*argv,"-msie_hack") == 0)
+			msie_hack=1;
+		else if (strcmp(*argv,"-crldays") == 0)
+			{
+			if (--argc < 1) goto bad;
+			crldays= atol(*(++argv));
+			}
+		else if (strcmp(*argv,"-crlhours") == 0)
+			{
+			if (--argc < 1) goto bad;
+			crlhours= atol(*(++argv));
+			}
+		else if (strcmp(*argv,"-crlsec") == 0)
+			{
+			if (--argc < 1) goto bad;
+			crlsec = atol(*(++argv));
+			}
+		else if (strcmp(*argv,"-infiles") == 0)
+			{
+			argc--;
+			argv++;
+			req=1;
+			break;
+			}
+		else if (strcmp(*argv, "-ss_cert") == 0)
+			{
+			if (--argc < 1) goto bad;
+			ss_cert_file = *(++argv);
+			req=1;
+			}
+		else if (strcmp(*argv, "-spkac") == 0)
+			{
+			if (--argc < 1) goto bad;
+			spkac_file = *(++argv);
+			req=1;
+			}
+		else if (strcmp(*argv,"-revoke") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			dorevoke=1;
+			}
+		else if (strcmp(*argv,"-extensions") == 0)
+			{
+			if (--argc < 1) goto bad;
+			extensions= *(++argv);
+			}
+		else if (strcmp(*argv,"-extfile") == 0)
+			{
+			if (--argc < 1) goto bad;
+			extfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-status") == 0)
+			{
+			if (--argc < 1) goto bad;
+			ser_status= *(++argv);
+			}
+		else if (strcmp(*argv,"-updatedb") == 0)
+			{
+			doupdatedb=1;
+			}
+		else if (strcmp(*argv,"-crlexts") == 0)
+			{
+			if (--argc < 1) goto bad;
+			crl_ext= *(++argv);
+			}
+		else if (strcmp(*argv,"-crl_reason") == 0)
+			{
+			if (--argc < 1) goto bad;
+			rev_arg = *(++argv);
+			rev_type = REV_CRL_REASON;
+			}
+		else if (strcmp(*argv,"-crl_hold") == 0)
+			{
+			if (--argc < 1) goto bad;
+			rev_arg = *(++argv);
+			rev_type = REV_HOLD;
+			}
+		else if (strcmp(*argv,"-crl_compromise") == 0)
+			{
+			if (--argc < 1) goto bad;
+			rev_arg = *(++argv);
+			rev_type = REV_KEY_COMPROMISE;
+			}
+		else if (strcmp(*argv,"-crl_CA_compromise") == 0)
+			{
+			if (--argc < 1) goto bad;
+			rev_arg = *(++argv);
+			rev_type = REV_CA_COMPROMISE;
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*argv,"-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine= *(++argv);
+			}
+#endif
+		else
+			{
+bad:
+			BIO_printf(bio_err,"unknown option %s\n",*argv);
+			badops=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (badops)
+		{
+		const char **pp2;
+
+		for (pp2=ca_usage; (*pp2 != NULL); pp2++)
+			BIO_printf(bio_err,"%s",*pp2);
+		goto err;
+		}
+
+	ERR_load_crypto_strings();
+
+	/*****************************************************************/
+	tofree=NULL;
+	if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
+	if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
+	if (configfile == NULL)
+		{
+		const char *s=X509_get_default_cert_area();
+		size_t len;
+
+#ifdef OPENSSL_SYS_VMS
+		len = strlen(s)+sizeof(CONFIG_FILE);
+		tofree=OPENSSL_malloc(len);
+		strcpy(tofree,s);
+#else
+		len = strlen(s)+sizeof(CONFIG_FILE)+1;
+		tofree=OPENSSL_malloc(len);
+		BUF_strlcpy(tofree,s,len);
+		BUF_strlcat(tofree,"/",len);
+#endif
+		BUF_strlcat(tofree,CONFIG_FILE,len);
+		configfile=tofree;
+		}
+
+	BIO_printf(bio_err,"Using configuration from %s\n",configfile);
+	conf = NCONF_new(NULL);
+	if (NCONF_load(conf,configfile,&errorline) <= 0)
+		{
+		if (errorline <= 0)
+			BIO_printf(bio_err,"error loading the config file '%s'\n",
+				configfile);
+		else
+			BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
+				,errorline,configfile);
+		goto err;
+		}
+	if(tofree)
+		{
+		OPENSSL_free(tofree);
+		tofree = NULL;
+		}
+
+	if (!load_config(bio_err, conf))
+		goto err;
+
+#ifndef OPENSSL_NO_ENGINE
+	e = setup_engine(bio_err, engine, 0);
+#endif
+
+	/* Lets get the config section we are using */
+	if (section == NULL)
+		{
+		section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
+		if (section == NULL)
+			{
+			lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
+			goto err;
+			}
+		}
+
+	if (conf != NULL)
+		{
+		p=NCONF_get_string(conf,NULL,"oid_file");
+		if (p == NULL)
+			ERR_clear_error();
+		if (p != NULL)
+			{
+			BIO *oid_bio;
+
+			oid_bio=BIO_new_file(p,"r");
+			if (oid_bio == NULL) 
+				{
+				/*
+				BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
+				ERR_print_errors(bio_err);
+				*/
+				ERR_clear_error();
+				}
+			else
+				{
+				OBJ_create_objects(oid_bio);
+				BIO_free(oid_bio);
+				}
+			}
+		if (!add_oid_section(bio_err,conf)) 
+			{
+			ERR_print_errors(bio_err);
+			goto err;
+			}
+		}
+
+	randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
+	if (randfile == NULL)
+		ERR_clear_error();
+	app_RAND_load_file(randfile, bio_err, 0);
+
+	f = NCONF_get_string(conf, section, STRING_MASK);
+	if (!f)
+		ERR_clear_error();
+
+	if(f && !ASN1_STRING_set_default_mask_asc(f)) {
+		BIO_printf(bio_err, "Invalid global string mask setting %s\n", f);
+		goto err;
+	}
+
+	if (chtype != MBSTRING_UTF8){
+		f = NCONF_get_string(conf, section, UTF8_IN);
+		if (!f)
+			ERR_clear_error();
+		else if (!strcmp(f, "yes"))
+			chtype = MBSTRING_UTF8;
+	}
+
+	db_attr.unique_subject = 1;
+	p = NCONF_get_string(conf, section, ENV_UNIQUE_SUBJECT);
+	if (p)
+		{
+#ifdef RL_DEBUG
+		BIO_printf(bio_err, "DEBUG: unique_subject = \"%s\"\n", p);
+#endif
+		db_attr.unique_subject = parse_yesno(p,1);
+		}
+	else
+		ERR_clear_error();
+#ifdef RL_DEBUG
+	if (!p)
+		BIO_printf(bio_err, "DEBUG: unique_subject undefined\n", p);
+#endif
+#ifdef RL_DEBUG
+	BIO_printf(bio_err, "DEBUG: configured unique_subject is %d\n",
+		db_attr.unique_subject);
+#endif
+	
+	in=BIO_new(BIO_s_file());
+	out=BIO_new(BIO_s_file());
+	Sout=BIO_new(BIO_s_file());
+	Cout=BIO_new(BIO_s_file());
+	if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
+		{
+		ERR_print_errors(bio_err);
+		goto err;
+		}
+
+	/*****************************************************************/
+	/* report status of cert with serial number given on command line */
+	if (ser_status)
+	{
+		if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
+			{
+			lookup_fail(section,ENV_DATABASE);
+			goto err;
+			}
+		db = load_index(dbfile,&db_attr);
+		if (db == NULL) goto err;
+
+		if (!index_index(db)) goto err;
+
+		if (get_certificate_status(ser_status,db) != 1)
+			BIO_printf(bio_err,"Error verifying serial %s!\n",
+				 ser_status);
+		goto err;
+	}
+
+	/*****************************************************************/
+	/* we definitely need a private key, so let's get it */
+
+	if ((keyfile == NULL) && ((keyfile=NCONF_get_string(conf,
+		section,ENV_PRIVATE_KEY)) == NULL))
+		{
+		lookup_fail(section,ENV_PRIVATE_KEY);
+		goto err;
+		}
+	if (!key)
+		{
+		free_key = 1;
+		if (!app_passwd(bio_err, passargin, NULL, &key, NULL))
+			{
+			BIO_printf(bio_err,"Error getting password\n");
+			goto err;
+			}
+		}
+	pkey = load_key(bio_err, keyfile, keyform, 0, key, e, 
+		"CA private key");
+	if (key) OPENSSL_cleanse(key,strlen(key));
+	if (pkey == NULL)
+		{
+		/* load_key() has already printed an appropriate message */
+		goto err;
+		}
+
+	/*****************************************************************/
+	/* we need a certificate */
+	if (!selfsign || spkac_file || ss_cert_file || gencrl)
+		{
+		if ((certfile == NULL)
+			&& ((certfile=NCONF_get_string(conf,
+				     section,ENV_CERTIFICATE)) == NULL))
+			{
+			lookup_fail(section,ENV_CERTIFICATE);
+			goto err;
+			}
+		x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e,
+			"CA certificate");
+		if (x509 == NULL)
+			goto err;
+
+		if (!X509_check_private_key(x509,pkey))
+			{
+			BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
+			goto err;
+			}
+		}
+	if (!selfsign) x509p = x509;
+
+	f=NCONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
+	if (f == NULL)
+		ERR_clear_error();
+	if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
+		preserve=1;
+	f=NCONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
+	if (f == NULL)
+		ERR_clear_error();
+	if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
+		msie_hack=1;
+
+	f=NCONF_get_string(conf,section,ENV_NAMEOPT);
+
+	if (f)
+		{
+		if (!set_name_ex(&nameopt, f))
+			{
+			BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
+			goto err;
+			}
+		default_op = 0;
+		}
+	else
+		ERR_clear_error();
+
+	f=NCONF_get_string(conf,section,ENV_CERTOPT);
+
+	if (f)
+		{
+		if (!set_cert_ex(&certopt, f))
+			{
+			BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
+			goto err;
+			}
+		default_op = 0;
+		}
+	else
+		ERR_clear_error();
+
+	f=NCONF_get_string(conf,section,ENV_EXTCOPY);
+
+	if (f)
+		{
+		if (!set_ext_copy(&ext_copy, f))
+			{
+			BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
+			goto err;
+			}
+		}
+	else
+		ERR_clear_error();
+
+	/*****************************************************************/
+	/* lookup where to write new certificates */
+	if ((outdir == NULL) && (req))
+		{
+
+		if ((outdir=NCONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
+			== NULL)
+			{
+			BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
+			goto err;
+			}
+#ifndef OPENSSL_SYS_VMS
+	    /* outdir is a directory spec, but access() for VMS demands a
+	       filename.  In any case, stat(), below, will catch the problem
+	       if outdir is not a directory spec, and the fopen() or open()
+	       will catch an error if there is no write access.
+
+	       Presumably, this problem could also be solved by using the DEC
+	       C routines to convert the directory syntax to Unixly, and give
+	       that to access().  However, time's too short to do that just
+	       now.
+	    */
+#ifndef _WIN32
+		if (access(outdir,R_OK|W_OK|X_OK) != 0)
+#else
+		if (_access(outdir,R_OK|W_OK|X_OK) != 0)
+#endif
+			{
+			BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
+			perror(outdir);
+			goto err;
+			}
+
+		if (app_isdir(outdir)<=0)
+			{
+			BIO_printf(bio_err,"%s need to be a directory\n",outdir);
+			perror(outdir);
+			goto err;
+			}
+#endif
+		}
+
+	/*****************************************************************/
+	/* we need to load the database file */
+	if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
+		{
+		lookup_fail(section,ENV_DATABASE);
+		goto err;
+		}
+	db = load_index(dbfile, &db_attr);
+	if (db == NULL) goto err;
+
+	/* Lets check some fields */
+	for (i=0; i<sk_OPENSSL_PSTRING_num(db->db->data); i++)
+		{
+		pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
+		if ((pp[DB_type][0] != DB_TYPE_REV) &&
+			(pp[DB_rev_date][0] != '\0'))
+			{
+			BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
+			goto err;
+			}
+		if ((pp[DB_type][0] == DB_TYPE_REV) &&
+			!make_revoked(NULL, pp[DB_rev_date]))
+			{
+			BIO_printf(bio_err," in entry %d\n", i+1);
+			goto err;
+			}
+		if (!check_time_format((char *)pp[DB_exp_date]))
+			{
+			BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
+			goto err;
+			}
+		p=pp[DB_serial];
+		j=strlen(p);
+		if (*p == '-')
+			{
+			p++;
+			j--;
+			}
+		if ((j&1) || (j < 2))
+			{
+			BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
+			goto err;
+			}
+		while (*p)
+			{
+			if (!(	((*p >= '0') && (*p <= '9')) ||
+				((*p >= 'A') && (*p <= 'F')) ||
+				((*p >= 'a') && (*p <= 'f')))  )
+				{
+				BIO_printf(bio_err,"entry %d: bad serial number characters, char pos %ld, char is '%c'\n",i+1,(long)(p-pp[DB_serial]),*p);
+				goto err;
+				}
+			p++;
+			}
+		}
+	if (verbose)
+		{
+		BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+		TXT_DB_write(out,db->db);
+		BIO_printf(bio_err,"%d entries loaded from the database\n",
+			   sk_OPENSSL_PSTRING_num(db->db->data));
+		BIO_printf(bio_err,"generating index\n");
+		}
+	
+	if (!index_index(db)) goto err;
+
+	/*****************************************************************/
+	/* Update the db file for expired certificates */
+	if (doupdatedb)
+		{
+		if (verbose)
+			BIO_printf(bio_err, "Updating %s ...\n",
+							dbfile);
+
+		i = do_updatedb(db);
+		if (i == -1)
+			{
+			BIO_printf(bio_err,"Malloc failure\n");
+			goto err;
+			}
+		else if (i == 0)
+			{
+			if (verbose) BIO_printf(bio_err,
+					"No entries found to mark expired\n"); 
+			}
+	    	else
+			{
+			if (!save_index(dbfile,"new",db)) goto err;
+				
+			if (!rotate_index(dbfile,"new","old")) goto err;
+				
+			if (verbose) BIO_printf(bio_err,
+				"Done. %d entries marked as expired\n",i); 
+	      		}
+	  	}
+
+ 	/*****************************************************************/
+	/* Read extentions config file                                   */
+	if (extfile)
+		{
+		extconf = NCONF_new(NULL);
+		if (NCONF_load(extconf,extfile,&errorline) <= 0)
+			{
+			if (errorline <= 0)
+				BIO_printf(bio_err, "ERROR: loading the config file '%s'\n",
+					extfile);
+			else
+				BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n",
+					errorline,extfile);
+			ret = 1;
+			goto err;
+			}
+
+		if (verbose)
+			BIO_printf(bio_err, "Successfully loaded extensions file %s\n", extfile);
+
+		/* We can have sections in the ext file */
+		if (!extensions && !(extensions = NCONF_get_string(extconf, "default", "extensions")))
+			extensions = "default";
+		}
+
+	/*****************************************************************/
+	if (req || gencrl)
+		{
+		if (outfile != NULL)
+			{
+			if (BIO_write_filename(Sout,outfile) <= 0)
+				{
+				perror(outfile);
+				goto err;
+				}
+			}
+		else
+			{
+			BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
+#ifdef OPENSSL_SYS_VMS
+			{
+			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+			Sout = BIO_push(tmpbio, Sout);
+			}
+#endif
+			}
+		}
+
+	if ((md == NULL) && ((md=NCONF_get_string(conf,
+		section,ENV_DEFAULT_MD)) == NULL))
+		{
+		lookup_fail(section,ENV_DEFAULT_MD);
+		goto err;
+		}
+
+	if (!strcmp(md, "default"))
+		{
+		int def_nid;
+		if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
+			{
+			BIO_puts(bio_err,"no default digest\n");
+			goto err;
+			}
+		md = (char *)OBJ_nid2sn(def_nid);
+		}
+
+	if ((dgst=EVP_get_digestbyname(md)) == NULL)
+		{
+		BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
+		goto err;
+		}
+
+	if (req)
+		{
+		if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf,
+			section,ENV_DEFAULT_EMAIL_DN)) != NULL ))
+			{
+			if(strcmp(tmp_email_dn,"no") == 0)
+				email_dn=0;
+			}
+		if (verbose)
+			BIO_printf(bio_err,"message digest is %s\n",
+				OBJ_nid2ln(dgst->type));
+		if ((policy == NULL) && ((policy=NCONF_get_string(conf,
+			section,ENV_POLICY)) == NULL))
+			{
+			lookup_fail(section,ENV_POLICY);
+			goto err;
+			}
+		if (verbose)
+			BIO_printf(bio_err,"policy is %s\n",policy);
+
+		if ((serialfile=NCONF_get_string(conf,section,ENV_SERIAL))
+			== NULL)
+			{
+			lookup_fail(section,ENV_SERIAL);
+			goto err;
+			}
+
+		if (!extconf)
+			{
+			/* no '-extfile' option, so we look for extensions
+			 * in the main configuration file */
+			if (!extensions)
+				{
+				extensions=NCONF_get_string(conf,section,
+								ENV_EXTENSIONS);
+				if (!extensions)
+					ERR_clear_error();
+				}
+			if (extensions)
+				{
+				/* Check syntax of file */
+				X509V3_CTX ctx;
+				X509V3_set_ctx_test(&ctx);
+				X509V3_set_nconf(&ctx, conf);
+				if (!X509V3_EXT_add_nconf(conf, &ctx, extensions,
+								NULL))
+					{
+					BIO_printf(bio_err,
+				 	"Error Loading extension section %s\n",
+								 extensions);
+					ret = 1;
+					goto err;
+					}
+				}
+			}
+
+		if (startdate == NULL)
+			{
+			startdate=NCONF_get_string(conf,section,
+				ENV_DEFAULT_STARTDATE);
+			if (startdate == NULL)
+				ERR_clear_error();
+			}
+		if (startdate && !ASN1_TIME_set_string(NULL, startdate))
+			{
+			BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
+			goto err;
+			}
+		if (startdate == NULL) startdate="today";
+
+		if (enddate == NULL)
+			{
+			enddate=NCONF_get_string(conf,section,
+				ENV_DEFAULT_ENDDATE);
+			if (enddate == NULL)
+				ERR_clear_error();
+			}
+		if (enddate && !ASN1_TIME_set_string(NULL, enddate))
+			{
+			BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
+			goto err;
+			}
+
+		if (days == 0)
+			{
+			if(!NCONF_get_number(conf,section, ENV_DEFAULT_DAYS, &days))
+				days = 0;
+			}
+		if (!enddate && (days == 0))
+			{
+			BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
+			goto err;
+			}
+
+		if ((serial=load_serial(serialfile, create_ser, NULL)) == NULL)
+			{
+			BIO_printf(bio_err,"error while loading serial number\n");
+			goto err;
+			}
+		if (verbose)
+			{
+			if (BN_is_zero(serial))
+				BIO_printf(bio_err,"next serial number is 00\n");
+			else
+				{
+				if ((f=BN_bn2hex(serial)) == NULL) goto err;
+				BIO_printf(bio_err,"next serial number is %s\n",f);
+				OPENSSL_free(f);
+				}
+			}
+
+		if ((attribs=NCONF_get_section(conf,policy)) == NULL)
+			{
+			BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
+			goto err;
+			}
+
+		if ((cert_sk=sk_X509_new_null()) == NULL)
+			{
+			BIO_printf(bio_err,"Memory allocation failure\n");
+			goto err;
+			}
+		if (spkac_file != NULL)
+			{
+			total++;
+			j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
+				serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,extensions,
+				conf,verbose,certopt,nameopt,default_op,ext_copy);
+			if (j < 0) goto err;
+			if (j > 0)
+				{
+				total_done++;
+				BIO_printf(bio_err,"\n");
+				if (!BN_add_word(serial,1)) goto err;
+				if (!sk_X509_push(cert_sk,x))
+					{
+					BIO_printf(bio_err,"Memory allocation failure\n");
+					goto err;
+					}
+				if (outfile)
+					{
+					output_der = 1;
+					batch = 1;
+					}
+				}
+			}
+		if (ss_cert_file != NULL)
+			{
+			total++;
+			j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
+				db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
+				extensions,conf,verbose, certopt, nameopt,
+				default_op, ext_copy, e);
+			if (j < 0) goto err;
+			if (j > 0)
+				{
+				total_done++;
+				BIO_printf(bio_err,"\n");
+				if (!BN_add_word(serial,1)) goto err;
+				if (!sk_X509_push(cert_sk,x))
+					{
+					BIO_printf(bio_err,"Memory allocation failure\n");
+					goto err;
+					}
+				}
+			}
+		if (infile != NULL)
+			{
+			total++;
+			j=certify(&x,infile,pkey,x509p,dgst,attribs,db,
+				serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
+				extensions,conf,verbose, certopt, nameopt,
+				default_op, ext_copy, selfsign);
+			if (j < 0) goto err;
+			if (j > 0)
+				{
+				total_done++;
+				BIO_printf(bio_err,"\n");
+				if (!BN_add_word(serial,1)) goto err;
+				if (!sk_X509_push(cert_sk,x))
+					{
+					BIO_printf(bio_err,"Memory allocation failure\n");
+					goto err;
+					}
+				}
+			}
+		for (i=0; i<argc; i++)
+			{
+			total++;
+			j=certify(&x,argv[i],pkey,x509p,dgst,attribs,db,
+				serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
+				extensions,conf,verbose, certopt, nameopt,
+				default_op, ext_copy, selfsign);
+			if (j < 0) goto err;
+			if (j > 0)
+				{
+				total_done++;
+				BIO_printf(bio_err,"\n");
+				if (!BN_add_word(serial,1)) goto err;
+				if (!sk_X509_push(cert_sk,x))
+					{
+					BIO_printf(bio_err,"Memory allocation failure\n");
+					goto err;
+					}
+				}
+			}	
+		/* we have a stack of newly certified certificates
+		 * and a data base and serial number that need
+		 * updating */
+
+		if (sk_X509_num(cert_sk) > 0)
+			{
+			if (!batch)
+				{
+				BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
+				(void)BIO_flush(bio_err);
+				buf[0][0]='\0';
+				if (!fgets(buf[0],10,stdin))
+					{
+					BIO_printf(bio_err,"CERTIFICATION CANCELED: I/O error\n"); 
+					ret=0;
+					goto err;
+					}
+				if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
+					{
+					BIO_printf(bio_err,"CERTIFICATION CANCELED\n"); 
+					ret=0;
+					goto err;
+					}
+				}
+
+			BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
+
+			if (!save_serial(serialfile,"new",serial,NULL)) goto err;
+
+			if (!save_index(dbfile, "new", db)) goto err;
+			}
+	
+		if (verbose)
+			BIO_printf(bio_err,"writing new certificates\n");
+		for (i=0; i<sk_X509_num(cert_sk); i++)
+			{
+			int k;
+			char *n;
+
+			x=sk_X509_value(cert_sk,i);
+
+			j=x->cert_info->serialNumber->length;
+			p=(const char *)x->cert_info->serialNumber->data;
+			
+			if(strlen(outdir) >= (size_t)(j ? BSIZE-j*2-6 : BSIZE-8))
+				{
+				BIO_printf(bio_err,"certificate file name too long\n");
+				goto err;
+				}
+
+			strcpy(buf[2],outdir);
+
+#ifndef OPENSSL_SYS_VMS
+			BUF_strlcat(buf[2],"/",sizeof(buf[2]));
+#endif
+
+			n=(char *)&(buf[2][strlen(buf[2])]);
+			if (j > 0)
+				{
+				for (k=0; k<j; k++)
+					{
+					if (n >= &(buf[2][sizeof(buf[2])]))
+						break;
+					BIO_snprintf(n,
+						     &buf[2][0] + sizeof(buf[2]) - n,
+						     "%02X",(unsigned char)*(p++));
+					n+=2;
+					}
+				}
+			else
+				{
+				*(n++)='0';
+				*(n++)='0';
+				}
+			*(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
+			*n='\0';
+			if (verbose)
+				BIO_printf(bio_err,"writing %s\n",buf[2]);
+
+			if (BIO_write_filename(Cout,buf[2]) <= 0)
+				{
+				perror(buf[2]);
+				goto err;
+				}
+			write_new_certificate(Cout,x, 0, notext);
+			write_new_certificate(Sout,x, output_der, notext);
+			}
+
+		if (sk_X509_num(cert_sk))
+			{
+			/* Rename the database and the serial file */
+			if (!rotate_serial(serialfile,"new","old")) goto err;
+
+			if (!rotate_index(dbfile,"new","old")) goto err;
+
+			BIO_printf(bio_err,"Data Base Updated\n");
+			}
+		}
+	
+	/*****************************************************************/
+	if (gencrl)
+		{
+		int crl_v2 = 0;
+		if (!crl_ext)
+			{
+			crl_ext=NCONF_get_string(conf,section,ENV_CRLEXT);
+			if (!crl_ext)
+				ERR_clear_error();
+			}
+		if (crl_ext)
+			{
+			/* Check syntax of file */
+			X509V3_CTX ctx;
+			X509V3_set_ctx_test(&ctx);
+			X509V3_set_nconf(&ctx, conf);
+			if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL))
+				{
+				BIO_printf(bio_err,
+				 "Error Loading CRL extension section %s\n",
+								 crl_ext);
+				ret = 1;
+				goto err;
+				}
+			}
+
+		if ((crlnumberfile=NCONF_get_string(conf,section,ENV_CRLNUMBER))
+			!= NULL)
+			if ((crlnumber=load_serial(crlnumberfile,0,NULL)) == NULL)
+				{
+				BIO_printf(bio_err,"error while loading CRL number\n");
+				goto err;
+				}
+
+		if (!crldays && !crlhours && !crlsec)
+			{
+			if (!NCONF_get_number(conf,section,
+				ENV_DEFAULT_CRL_DAYS, &crldays))
+				crldays = 0;
+			if (!NCONF_get_number(conf,section,
+				ENV_DEFAULT_CRL_HOURS, &crlhours))
+				crlhours = 0;
+			}
+		if ((crldays == 0) && (crlhours == 0) && (crlsec == 0))
+			{
+			BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n");
+			goto err;
+			}
+
+		if (verbose) BIO_printf(bio_err,"making CRL\n");
+		if ((crl=X509_CRL_new()) == NULL) goto err;
+		if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err;
+
+		tmptm = ASN1_TIME_new();
+		if (!tmptm) goto err;
+		X509_gmtime_adj(tmptm,0);
+		X509_CRL_set_lastUpdate(crl, tmptm);	
+		if (!X509_time_adj_ex(tmptm, crldays, crlhours*60*60 + crlsec,
+			NULL))
+			{
+			BIO_puts(bio_err, "error setting CRL nextUpdate\n");
+			goto err;
+			}
+		X509_CRL_set_nextUpdate(crl, tmptm);	
+
+		ASN1_TIME_free(tmptm);
+
+		for (i=0; i<sk_OPENSSL_PSTRING_num(db->db->data); i++)
+			{
+			pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
+			if (pp[DB_type][0] == DB_TYPE_REV)
+				{
+				if ((r=X509_REVOKED_new()) == NULL) goto err;
+				j = make_revoked(r, pp[DB_rev_date]);
+				if (!j) goto err;
+				if (j == 2) crl_v2 = 1;
+				if (!BN_hex2bn(&serial, pp[DB_serial]))
+					goto err;
+				tmpser = BN_to_ASN1_INTEGER(serial, NULL);
+				BN_free(serial);
+				serial = NULL;
+				if (!tmpser)
+					goto err;
+				X509_REVOKED_set_serialNumber(r, tmpser);
+				ASN1_INTEGER_free(tmpser);
+				X509_CRL_add0_revoked(crl,r);
+				}
+			}
+
+		/* sort the data so it will be written in serial
+		 * number order */
+		X509_CRL_sort(crl);
+
+		/* we now have a CRL */
+		if (verbose) BIO_printf(bio_err,"signing CRL\n");
+
+		/* Add any extensions asked for */
+
+		if (crl_ext || crlnumberfile != NULL)
+			{
+			X509V3_CTX crlctx;
+			X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
+			X509V3_set_nconf(&crlctx, conf);
+
+			if (crl_ext)
+				if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
+					crl_ext, crl)) goto err;
+			if (crlnumberfile != NULL)
+				{
+				tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL);
+				if (!tmpser) goto err;
+				X509_CRL_add1_ext_i2d(crl,NID_crl_number,tmpser,0,0);
+				ASN1_INTEGER_free(tmpser);
+				crl_v2 = 1;
+				if (!BN_add_word(crlnumber,1)) goto err;
+				}
+			}
+		if (crl_ext || crl_v2)
+			{
+			if (!X509_CRL_set_version(crl, 1))
+				goto err; /* version 2 CRL */
+			}
+
+		
+		if (crlnumberfile != NULL)	/* we have a CRL number that need updating */
+			if (!save_serial(crlnumberfile,"new",crlnumber,NULL)) goto err;
+
+		if (crlnumber)
+			{
+			BN_free(crlnumber);
+			crlnumber = NULL;
+			}
+
+		if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
+
+		PEM_write_bio_X509_CRL(Sout,crl);
+
+		if (crlnumberfile != NULL)	/* Rename the crlnumber file */
+			if (!rotate_serial(crlnumberfile,"new","old")) goto err;
+
+		}
+	/*****************************************************************/
+	if (dorevoke)
+		{
+		if (infile == NULL) 
+			{
+			BIO_printf(bio_err,"no input files\n");
+			goto err;
+			}
+		else
+			{
+			X509 *revcert;
+			revcert=load_cert(bio_err, infile, FORMAT_PEM,
+				NULL, e, infile);
+			if (revcert == NULL)
+				goto err;
+			j=do_revoke(revcert,db, rev_type, rev_arg);
+			if (j <= 0) goto err;
+			X509_free(revcert);
+
+			if (!save_index(dbfile, "new", db)) goto err;
+
+			if (!rotate_index(dbfile, "new", "old")) goto err;
+
+			BIO_printf(bio_err,"Data Base Updated\n"); 
+			}
+		}
+	/*****************************************************************/
+	ret=0;
+err:
+	if(tofree)
+		OPENSSL_free(tofree);
+	BIO_free_all(Cout);
+	BIO_free_all(Sout);
+	BIO_free_all(out);
+	BIO_free_all(in);
+
+	if (cert_sk)
+		sk_X509_pop_free(cert_sk,X509_free);
+
+	if (ret) ERR_print_errors(bio_err);
+	app_RAND_write_file(randfile, bio_err);
+	if (free_key && key)
+		OPENSSL_free(key);
+	BN_free(serial);
+	BN_free(crlnumber);
+	free_index(db);
+	EVP_PKEY_free(pkey);
+	if (x509) X509_free(x509);
+	X509_CRL_free(crl);
+	NCONF_free(conf);
+	NCONF_free(extconf);
+	OBJ_cleanup();
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
+static void lookup_fail(const char *name, const char *tag)
+	{
+	BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
+	}
+
+static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
+	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
+	     BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
+	     long days, int batch, char *ext_sect, CONF *lconf, int verbose,
+	     unsigned long certopt, unsigned long nameopt, int default_op,
+	     int ext_copy, int selfsign)
+	{
+	X509_REQ *req=NULL;
+	BIO *in=NULL;
+	EVP_PKEY *pktmp=NULL;
+	int ok= -1,i;
+
+	in=BIO_new(BIO_s_file());
+
+	if (BIO_read_filename(in,infile) <= 0)
+		{
+		perror(infile);
+		goto err;
+		}
+	if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
+		{
+		BIO_printf(bio_err,"Error reading certificate request in %s\n",
+			infile);
+		goto err;
+		}
+	if (verbose)
+		X509_REQ_print(bio_err,req);
+
+	BIO_printf(bio_err,"Check that the request matches the signature\n");
+
+	if (selfsign && !X509_REQ_check_private_key(req,pkey))
+		{
+		BIO_printf(bio_err,"Certificate request and CA private key do not match\n");
+		ok=0;
+		goto err;
+		}
+	if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
+		{
+		BIO_printf(bio_err,"error unpacking public key\n");
+		goto err;
+		}
+	i=X509_REQ_verify(req,pktmp);
+	EVP_PKEY_free(pktmp);
+	if (i < 0)
+		{
+		ok=0;
+		BIO_printf(bio_err,"Signature verification problems....\n");
+		goto err;
+		}
+	if (i == 0)
+		{
+		ok=0;
+		BIO_printf(bio_err,"Signature did not match the certificate request\n");
+		goto err;
+		}
+	else
+		BIO_printf(bio_err,"Signature ok\n");
+
+	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn, email_dn,
+		startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
+		certopt, nameopt, default_op, ext_copy, selfsign);
+
+err:
+	if (req != NULL) X509_REQ_free(req);
+	if (in != NULL) BIO_free(in);
+	return(ok);
+	}
+
+static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
+	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
+	     BIGNUM *serial, char *subj, unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
+	     long days, int batch, char *ext_sect, CONF *lconf, int verbose,
+	     unsigned long certopt, unsigned long nameopt, int default_op,
+	     int ext_copy, ENGINE *e)
+	{
+	X509 *req=NULL;
+	X509_REQ *rreq=NULL;
+	EVP_PKEY *pktmp=NULL;
+	int ok= -1,i;
+
+	if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
+		goto err;
+	if (verbose)
+		X509_print(bio_err,req);
+
+	BIO_printf(bio_err,"Check that the request matches the signature\n");
+
+	if ((pktmp=X509_get_pubkey(req)) == NULL)
+		{
+		BIO_printf(bio_err,"error unpacking public key\n");
+		goto err;
+		}
+	i=X509_verify(req,pktmp);
+	EVP_PKEY_free(pktmp);
+	if (i < 0)
+		{
+		ok=0;
+		BIO_printf(bio_err,"Signature verification problems....\n");
+		goto err;
+		}
+	if (i == 0)
+		{
+		ok=0;
+		BIO_printf(bio_err,"Signature did not match the certificate\n");
+		goto err;
+		}
+	else
+		BIO_printf(bio_err,"Signature ok\n");
+
+	if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
+		goto err;
+
+	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,
+		days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
+		ext_copy, 0);
+
+err:
+	if (rreq != NULL) X509_REQ_free(rreq);
+	if (req != NULL) X509_free(req);
+	return(ok);
+	}
+
+static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
+	     STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
+	     unsigned long chtype, int multirdn,
+	     int email_dn, char *startdate, char *enddate, long days, int batch,
+	     int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
+	     unsigned long certopt, unsigned long nameopt, int default_op,
+	     int ext_copy, int selfsign)
+	{
+	X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
+	ASN1_UTCTIME *tm,*tmptm;
+	ASN1_STRING *str,*str2;
+	ASN1_OBJECT *obj;
+	X509 *ret=NULL;
+	X509_CINF *ci;
+	X509_NAME_ENTRY *ne;
+	X509_NAME_ENTRY *tne,*push;
+	EVP_PKEY *pktmp;
+	int ok= -1,i,j,last,nid;
+	const char *p;
+	CONF_VALUE *cv;
+	OPENSSL_STRING row[DB_NUMBER];
+	OPENSSL_STRING *irow=NULL;
+	OPENSSL_STRING *rrow=NULL;
+	char buf[25];
+
+	tmptm=ASN1_UTCTIME_new();
+	if (tmptm == NULL)
+		{
+		BIO_printf(bio_err,"malloc error\n");
+		return(0);
+		}
+
+	for (i=0; i<DB_NUMBER; i++)
+		row[i]=NULL;
+
+	if (subj)
+		{
+		X509_NAME *n = parse_name(subj, chtype, multirdn);
+
+		if (!n)
+			{
+			ERR_print_errors(bio_err);
+			goto err;
+			}
+		X509_REQ_set_subject_name(req,n);
+		req->req_info->enc.modified = 1;
+		X509_NAME_free(n);
+		}
+
+	if (default_op)
+		BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
+
+	name=X509_REQ_get_subject_name(req);
+	for (i=0; i<X509_NAME_entry_count(name); i++)
+		{
+		ne= X509_NAME_get_entry(name,i);
+		str=X509_NAME_ENTRY_get_data(ne);
+		obj=X509_NAME_ENTRY_get_object(ne);
+
+		if (msie_hack)
+			{
+			/* assume all type should be strings */
+			nid=OBJ_obj2nid(ne->object);
+
+			if (str->type == V_ASN1_UNIVERSALSTRING)
+				ASN1_UNIVERSALSTRING_to_string(str);
+
+			if ((str->type == V_ASN1_IA5STRING) &&
+				(nid != NID_pkcs9_emailAddress))
+				str->type=V_ASN1_T61STRING;
+
+			if ((nid == NID_pkcs9_emailAddress) &&
+				(str->type == V_ASN1_PRINTABLESTRING))
+				str->type=V_ASN1_IA5STRING;
+			}
+
+		/* If no EMAIL is wanted in the subject */
+		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
+			continue;
+
+		/* check some things */
+		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
+			(str->type != V_ASN1_IA5STRING))
+			{
+			BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
+			goto err;
+			}
+		if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
+			{
+			j=ASN1_PRINTABLE_type(str->data,str->length);
+			if (	((j == V_ASN1_T61STRING) &&
+				 (str->type != V_ASN1_T61STRING)) ||
+				((j == V_ASN1_IA5STRING) &&
+				 (str->type == V_ASN1_PRINTABLESTRING)))
+				{
+				BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
+				goto err;
+				}
+			}
+
+		if (default_op)
+			old_entry_print(bio_err, obj, str);
+		}
+
+	/* Ok, now we check the 'policy' stuff. */
+	if ((subject=X509_NAME_new()) == NULL)
+		{
+		BIO_printf(bio_err,"Memory allocation failure\n");
+		goto err;
+		}
+
+	/* take a copy of the issuer name before we mess with it. */
+	if (selfsign)
+		CAname=X509_NAME_dup(name);
+	else
+		CAname=X509_NAME_dup(x509->cert_info->subject);
+	if (CAname == NULL) goto err;
+	str=str2=NULL;
+
+	for (i=0; i<sk_CONF_VALUE_num(policy); i++)
+		{
+		cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
+		if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
+			{
+			BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
+			goto err;
+			}
+		obj=OBJ_nid2obj(j);
+
+		last= -1;
+		for (;;)
+			{
+			/* lookup the object in the supplied name list */
+			j=X509_NAME_get_index_by_OBJ(name,obj,last);
+			if (j < 0)
+				{
+				if (last != -1) break;
+				tne=NULL;
+				}
+			else
+				{
+				tne=X509_NAME_get_entry(name,j);
+				}
+			last=j;
+
+			/* depending on the 'policy', decide what to do. */
+			push=NULL;
+			if (strcmp(cv->value,"optional") == 0)
+				{
+				if (tne != NULL)
+					push=tne;
+				}
+			else if (strcmp(cv->value,"supplied") == 0)
+				{
+				if (tne == NULL)
+					{
+					BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
+					goto err;
+					}
+				else
+					push=tne;
+				}
+			else if (strcmp(cv->value,"match") == 0)
+				{
+				int last2;
+
+				if (tne == NULL)
+					{
+					BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
+					goto err;
+					}
+
+				last2= -1;
+
+again2:
+				j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
+				if ((j < 0) && (last2 == -1))
+					{
+					BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
+					goto err;
+					}
+				if (j >= 0)
+					{
+					push=X509_NAME_get_entry(CAname,j);
+					str=X509_NAME_ENTRY_get_data(tne);
+					str2=X509_NAME_ENTRY_get_data(push);
+					last2=j;
+					if (ASN1_STRING_cmp(str,str2) != 0)
+						goto again2;
+					}
+				if (j < 0)
+					{
+					BIO_printf(bio_err,"The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n",cv->name,((str2 == NULL)?"NULL":(char *)str2->data),((str == NULL)?"NULL":(char *)str->data));
+					goto err;
+					}
+				}
+			else
+				{
+				BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
+				goto err;
+				}
+
+			if (push != NULL)
+				{
+				if (!X509_NAME_add_entry(subject,push, -1, 0))
+					{
+					if (push != NULL)
+						X509_NAME_ENTRY_free(push);
+					BIO_printf(bio_err,"Memory allocation failure\n");
+					goto err;
+					}
+				}
+			if (j < 0) break;
+			}
+		}
+
+	if (preserve)
+		{
+		X509_NAME_free(subject);
+		/* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
+		subject=X509_NAME_dup(name);
+		if (subject == NULL) goto err;
+		}
+
+	if (verbose)
+		BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
+
+	/* Build the correct Subject if no e-mail is wanted in the subject */
+	/* and add it later on because of the method extensions are added (altName) */
+	 
+	if (email_dn)
+		dn_subject = subject;
+	else
+		{
+		X509_NAME_ENTRY *tmpne;
+		/* Its best to dup the subject DN and then delete any email
+		 * addresses because this retains its structure.
+		 */
+		if (!(dn_subject = X509_NAME_dup(subject)))
+			{
+			BIO_printf(bio_err,"Memory allocation failure\n");
+			goto err;
+			}
+		while((i = X509_NAME_get_index_by_NID(dn_subject,
+					NID_pkcs9_emailAddress, -1)) >= 0)
+			{
+			tmpne = X509_NAME_get_entry(dn_subject, i);
+			X509_NAME_delete_entry(dn_subject, i);
+			X509_NAME_ENTRY_free(tmpne);
+			}
+		}
+
+	if (BN_is_zero(serial))
+		row[DB_serial]=BUF_strdup("00");
+	else
+		row[DB_serial]=BN_bn2hex(serial);
+	if (row[DB_serial] == NULL)
+		{
+		BIO_printf(bio_err,"Memory allocation failure\n");
+		goto err;
+		}
+
+	if (db->attributes.unique_subject)
+		{
+		OPENSSL_STRING *crow=row;
+
+		rrow=TXT_DB_get_by_index(db->db,DB_name,crow);
+		if (rrow != NULL)
+			{
+			BIO_printf(bio_err,
+				"ERROR:There is already a certificate for %s\n",
+				row[DB_name]);
+			}
+		}
+	if (rrow == NULL)
+		{
+		rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
+		if (rrow != NULL)
+			{
+			BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
+				row[DB_serial]);
+			BIO_printf(bio_err,"      check the database/serial_file for corruption\n");
+			}
+		}
+
+	if (rrow != NULL)
+		{
+		BIO_printf(bio_err,
+			"The matching entry has the following details\n");
+		if (rrow[DB_type][0] == 'E')
+			p="Expired";
+		else if (rrow[DB_type][0] == 'R')
+			p="Revoked";
+		else if (rrow[DB_type][0] == 'V')
+			p="Valid";
+		else
+			p="\ninvalid type, Data base error\n";
+		BIO_printf(bio_err,"Type	  :%s\n",p);;
+		if (rrow[DB_type][0] == 'R')
+			{
+			p=rrow[DB_exp_date]; if (p == NULL) p="undef";
+			BIO_printf(bio_err,"Was revoked on:%s\n",p);
+			}
+		p=rrow[DB_exp_date]; if (p == NULL) p="undef";
+		BIO_printf(bio_err,"Expires on    :%s\n",p);
+		p=rrow[DB_serial]; if (p == NULL) p="undef";
+		BIO_printf(bio_err,"Serial Number :%s\n",p);
+		p=rrow[DB_file]; if (p == NULL) p="undef";
+		BIO_printf(bio_err,"File name     :%s\n",p);
+		p=rrow[DB_name]; if (p == NULL) p="undef";
+		BIO_printf(bio_err,"Subject Name  :%s\n",p);
+		ok= -1; /* This is now a 'bad' error. */
+		goto err;
+		}
+
+	/* We are now totally happy, lets make and sign the certificate */
+	if (verbose)
+		BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
+
+	if ((ret=X509_new()) == NULL) goto err;
+	ci=ret->cert_info;
+
+#ifdef X509_V3
+	/* Make it an X509 v3 certificate. */
+	if (!X509_set_version(ret,2)) goto err;
+#endif
+
+	if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
+		goto err;
+	if (selfsign)
+		{
+		if (!X509_set_issuer_name(ret,subject))
+			goto err;
+		}
+	else
+		{
+		if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
+			goto err;
+		}
+
+	if (strcmp(startdate,"today") == 0)
+		X509_gmtime_adj(X509_get_notBefore(ret),0);
+	else ASN1_TIME_set_string(X509_get_notBefore(ret),startdate);
+
+	if (enddate == NULL)
+		X509_time_adj_ex(X509_get_notAfter(ret),days, 0, NULL);
+	else ASN1_TIME_set_string(X509_get_notAfter(ret),enddate);
+
+	if (!X509_set_subject_name(ret,subject)) goto err;
+
+	pktmp=X509_REQ_get_pubkey(req);
+	i = X509_set_pubkey(ret,pktmp);
+	EVP_PKEY_free(pktmp);
+	if (!i) goto err;
+
+	/* Lets add the extensions, if there are any */
+	if (ext_sect)
+		{
+		X509V3_CTX ctx;
+		if (ci->version == NULL)
+			if ((ci->version=ASN1_INTEGER_new()) == NULL)
+				goto err;
+		ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
+
+		/* Free the current entries if any, there should not
+		 * be any I believe */
+		if (ci->extensions != NULL)
+			sk_X509_EXTENSION_pop_free(ci->extensions,
+						   X509_EXTENSION_free);
+
+		ci->extensions = NULL;
+
+		/* Initialize the context structure */
+		if (selfsign)
+			X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
+		else
+			X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
+
+		if (extconf)
+			{
+			if (verbose)
+				BIO_printf(bio_err, "Extra configuration file found\n");
+ 
+			/* Use the extconf configuration db LHASH */
+			X509V3_set_nconf(&ctx, extconf);
+ 
+			/* Test the structure (needed?) */
+			/* X509V3_set_ctx_test(&ctx); */
+
+			/* Adds exts contained in the configuration file */
+			if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
+				{
+				BIO_printf(bio_err,
+				    "ERROR: adding extensions in section %s\n",
+								ext_sect);
+				ERR_print_errors(bio_err);
+				goto err;
+				}
+			if (verbose)
+				BIO_printf(bio_err, "Successfully added extensions from file.\n");
+			}
+		else if (ext_sect)
+			{
+			/* We found extensions to be set from config file */
+			X509V3_set_nconf(&ctx, lconf);
+
+			if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
+				{
+				BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
+				ERR_print_errors(bio_err);
+				goto err;
+				}
+
+			if (verbose) 
+				BIO_printf(bio_err, "Successfully added extensions from config\n");
+			}
+		}
+
+	/* Copy extensions from request (if any) */
+
+	if (!copy_extensions(ret, req, ext_copy))
+		{
+		BIO_printf(bio_err, "ERROR: adding extensions from request\n");
+		ERR_print_errors(bio_err);
+		goto err;
+		}
+
+	/* Set the right value for the noemailDN option */
+	if( email_dn == 0 )
+		{
+		if (!X509_set_subject_name(ret,dn_subject)) goto err;
+		}
+
+	if (!default_op)
+		{
+		BIO_printf(bio_err, "Certificate Details:\n");
+		/* Never print signature details because signature not present */
+		certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
+		X509_print_ex(bio_err, ret, nameopt, certopt); 
+		}
+
+	BIO_printf(bio_err,"Certificate is to be certified until ");
+	ASN1_TIME_print(bio_err,X509_get_notAfter(ret));
+	if (days) BIO_printf(bio_err," (%ld days)",days);
+	BIO_printf(bio_err, "\n");
+
+	if (!batch)
+		{
+
+		BIO_printf(bio_err,"Sign the certificate? [y/n]:");
+		(void)BIO_flush(bio_err);
+		buf[0]='\0';
+		if (!fgets(buf,sizeof(buf)-1,stdin))
+			{
+			BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n");
+			ok=0;
+			goto err;
+			}
+		if (!((buf[0] == 'y') || (buf[0] == 'Y')))
+			{
+			BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
+			ok=0;
+			goto err;
+			}
+		}
+
+	pktmp=X509_get_pubkey(ret);
+	if (EVP_PKEY_missing_parameters(pktmp) &&
+		!EVP_PKEY_missing_parameters(pkey))
+		EVP_PKEY_copy_parameters(pktmp,pkey);
+	EVP_PKEY_free(pktmp);
+
+	if (!X509_sign(ret,pkey,dgst))
+		goto err;
+
+	/* We now just add it to the database */
+	row[DB_type]=(char *)OPENSSL_malloc(2);
+
+	tm=X509_get_notAfter(ret);
+	row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
+	memcpy(row[DB_exp_date],tm->data,tm->length);
+	row[DB_exp_date][tm->length]='\0';
+
+	row[DB_rev_date]=NULL;
+
+	/* row[DB_serial] done already */
+	row[DB_file]=(char *)OPENSSL_malloc(8);
+	row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
+
+	if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
+		(row[DB_file] == NULL) || (row[DB_name] == NULL))
+		{
+		BIO_printf(bio_err,"Memory allocation failure\n");
+		goto err;
+		}
+	BUF_strlcpy(row[DB_file],"unknown",8);
+	row[DB_type][0]='V';
+	row[DB_type][1]='\0';
+
+	if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
+		{
+		BIO_printf(bio_err,"Memory allocation failure\n");
+		goto err;
+		}
+
+	for (i=0; i<DB_NUMBER; i++)
+		{
+		irow[i]=row[i];
+		row[i]=NULL;
+		}
+	irow[DB_NUMBER]=NULL;
+
+	if (!TXT_DB_insert(db->db,irow))
+		{
+		BIO_printf(bio_err,"failed to update database\n");
+		BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
+		goto err;
+		}
+	ok=1;
+err:
+	for (i=0; i<DB_NUMBER; i++)
+		if (row[i] != NULL) OPENSSL_free(row[i]);
+
+	if (CAname != NULL)
+		X509_NAME_free(CAname);
+	if (subject != NULL)
+		X509_NAME_free(subject);
+	if ((dn_subject != NULL) && !email_dn)
+		X509_NAME_free(dn_subject);
+	if (tmptm != NULL)
+		ASN1_UTCTIME_free(tmptm);
+	if (ok <= 0)
+		{
+		if (ret != NULL) X509_free(ret);
+		ret=NULL;
+		}
+	else
+		*xret=ret;
+	return(ok);
+	}
+
+static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
+	{
+
+	if (output_der)
+		{
+		(void)i2d_X509_bio(bp,x);
+		return;
+		}
+#if 0
+	/* ??? Not needed since X509_print prints all this stuff anyway */
+	f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
+	BIO_printf(bp,"issuer :%s\n",f);
+
+	f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
+	BIO_printf(bp,"subject:%s\n",f);
+
+	BIO_puts(bp,"serial :");
+	i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
+	BIO_puts(bp,"\n\n");
+#endif
+	if (!notext)X509_print(bp,x);
+	PEM_write_bio_X509(bp,x);
+	}
+
+static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
+	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
+	     BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
+	     long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
+	     unsigned long nameopt, int default_op, int ext_copy)
+	{
+	STACK_OF(CONF_VALUE) *sk=NULL;
+	LHASH_OF(CONF_VALUE) *parms=NULL;
+	X509_REQ *req=NULL;
+	CONF_VALUE *cv=NULL;
+	NETSCAPE_SPKI *spki = NULL;
+	X509_REQ_INFO *ri;
+	char *type,*buf;
+	EVP_PKEY *pktmp=NULL;
+	X509_NAME *n=NULL;
+	X509_NAME_ENTRY *ne=NULL;
+	int ok= -1,i,j;
+	long errline;
+	int nid;
+
+	/*
+	 * Load input file into a hash table.  (This is just an easy
+	 * way to read and parse the file, then put it into a convenient
+	 * STACK format).
+	 */
+	parms=CONF_load(NULL,infile,&errline);
+	if (parms == NULL)
+		{
+		BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
+		ERR_print_errors(bio_err);
+		goto err;
+		}
+
+	sk=CONF_get_section(parms, "default");
+	if (sk_CONF_VALUE_num(sk) == 0)
+		{
+		BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
+		CONF_free(parms);
+		goto err;
+		}
+
+	/*
+	 * Now create a dummy X509 request structure.  We don't actually
+	 * have an X509 request, but we have many of the components
+	 * (a public key, various DN components).  The idea is that we
+	 * put these components into the right X509 request structure
+	 * and we can use the same code as if you had a real X509 request.
+	 */
+	req=X509_REQ_new();
+	if (req == NULL)
+		{
+		ERR_print_errors(bio_err);
+		goto err;
+		}
+
+	/*
+	 * Build up the subject name set.
+	 */
+	ri=req->req_info;
+	n = ri->subject;
+
+	for (i = 0; ; i++)
+		{
+		if (sk_CONF_VALUE_num(sk) <= i) break;
+
+		cv=sk_CONF_VALUE_value(sk,i);
+		type=cv->name;
+		/* Skip past any leading X. X: X, etc to allow for
+		 * multiple instances
+		 */
+		for (buf = cv->name; *buf ; buf++)
+			if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
+				{
+				buf++;
+				if (*buf) type = buf;
+				break;
+				}
+
+		buf=cv->value;
+		if ((nid=OBJ_txt2nid(type)) == NID_undef)
+			{
+			if (strcmp(type, "SPKAC") == 0)
+				{
+				spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
+				if (spki == NULL)
+					{
+					BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
+					ERR_print_errors(bio_err);
+					goto err;
+					}
+				}
+			continue;
+			}
+
+		if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
+				(unsigned char *)buf, -1, -1, 0))
+			goto err;
+		}
+	if (spki == NULL)
+		{
+		BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
+			infile);
+		goto err;
+		}
+
+	/*
+	 * Now extract the key from the SPKI structure.
+	 */
+
+	BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
+
+	if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
+		{
+		BIO_printf(bio_err,"error unpacking SPKAC public key\n");
+		goto err;
+		}
+
+	j = NETSCAPE_SPKI_verify(spki, pktmp);
+	if (j <= 0)
+		{
+		BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
+		goto err;
+		}
+	BIO_printf(bio_err,"Signature ok\n");
+
+	X509_REQ_set_pubkey(req,pktmp);
+	EVP_PKEY_free(pktmp);
+	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,
+		   days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
+			ext_copy, 0);
+err:
+	if (req != NULL) X509_REQ_free(req);
+	if (parms != NULL) CONF_free(parms);
+	if (spki != NULL) NETSCAPE_SPKI_free(spki);
+	if (ne != NULL) X509_NAME_ENTRY_free(ne);
+
+	return(ok);
+	}
+
+static int check_time_format(const char *str)
+	{
+	return ASN1_TIME_set_string(NULL, str);
+	}
+
+static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
+	{
+	ASN1_UTCTIME *tm=NULL;
+	char *row[DB_NUMBER],**rrow,**irow;
+	char *rev_str = NULL;
+	BIGNUM *bn = NULL;
+	int ok=-1,i;
+
+	for (i=0; i<DB_NUMBER; i++)
+		row[i]=NULL;
+	row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
+	bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
+	if (!bn)
+		goto err;
+	if (BN_is_zero(bn))
+		row[DB_serial]=BUF_strdup("00");
+	else
+		row[DB_serial]=BN_bn2hex(bn);
+	BN_free(bn);
+	if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
+		{
+		BIO_printf(bio_err,"Memory allocation failure\n");
+		goto err;
+		}
+	/* We have to lookup by serial number because name lookup
+	 * skips revoked certs
+ 	 */
+	rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
+	if (rrow == NULL)
+		{
+		BIO_printf(bio_err,"Adding Entry with serial number %s to DB for %s\n", row[DB_serial], row[DB_name]);
+
+		/* We now just add it to the database */
+		row[DB_type]=(char *)OPENSSL_malloc(2);
+
+		tm=X509_get_notAfter(x509);
+		row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
+		memcpy(row[DB_exp_date],tm->data,tm->length);
+		row[DB_exp_date][tm->length]='\0';
+
+		row[DB_rev_date]=NULL;
+
+		/* row[DB_serial] done already */
+		row[DB_file]=(char *)OPENSSL_malloc(8);
+
+		/* row[DB_name] done already */
+
+		if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
+			(row[DB_file] == NULL))
+			{
+			BIO_printf(bio_err,"Memory allocation failure\n");
+			goto err;
+			}
+		BUF_strlcpy(row[DB_file],"unknown",8);
+		row[DB_type][0]='V';
+		row[DB_type][1]='\0';
+
+		if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
+			{
+			BIO_printf(bio_err,"Memory allocation failure\n");
+			goto err;
+			}
+
+		for (i=0; i<DB_NUMBER; i++)
+			{
+			irow[i]=row[i];
+			row[i]=NULL;
+			}
+		irow[DB_NUMBER]=NULL;
+
+		if (!TXT_DB_insert(db->db,irow))
+			{
+			BIO_printf(bio_err,"failed to update database\n");
+			BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
+			goto err;
+			}
+
+		/* Revoke Certificate */
+		ok = do_revoke(x509,db, type, value);
+
+		goto err;
+
+		}
+	else if (index_name_cmp_noconst(row, rrow))
+		{
+		BIO_printf(bio_err,"ERROR:name does not match %s\n",
+			   row[DB_name]);
+		goto err;
+		}
+	else if (rrow[DB_type][0]=='R')
+		{
+		BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
+			   row[DB_serial]);
+		goto err;
+		}
+	else
+		{
+		BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
+		rev_str = make_revocation_str(type, value);
+		if (!rev_str)
+			{
+			BIO_printf(bio_err, "Error in revocation arguments\n");
+			goto err;
+			}
+		rrow[DB_type][0]='R';
+		rrow[DB_type][1]='\0';
+		rrow[DB_rev_date] = rev_str;
+		}
+	ok=1;
+err:
+	for (i=0; i<DB_NUMBER; i++)
+		{
+		if (row[i] != NULL) 
+			OPENSSL_free(row[i]);
+		}
+	return(ok);
+	}
+
+static int get_certificate_status(const char *serial, CA_DB *db)
+	{
+	char *row[DB_NUMBER],**rrow;
+	int ok=-1,i;
+
+	/* Free Resources */
+	for (i=0; i<DB_NUMBER; i++)
+		row[i]=NULL;
+
+	/* Malloc needed char spaces */
+	row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
+	if (row[DB_serial] == NULL)
+		{
+		BIO_printf(bio_err,"Malloc failure\n");
+		goto err;
+		}
+
+	if (strlen(serial) % 2)
+		{
+		/* Set the first char to 0 */;
+		row[DB_serial][0]='0';
+
+		/* Copy String from serial to row[DB_serial] */
+		memcpy(row[DB_serial]+1, serial, strlen(serial));
+		row[DB_serial][strlen(serial)+1]='\0';
+		}
+	else
+		{
+		/* Copy String from serial to row[DB_serial] */
+		memcpy(row[DB_serial], serial, strlen(serial));
+		row[DB_serial][strlen(serial)]='\0';
+		}
+			
+	/* Make it Upper Case */
+	for (i=0; row[DB_serial][i] != '\0'; i++)
+		row[DB_serial][i] = toupper(row[DB_serial][i]);
+	
+
+	ok=1;
+
+	/* Search for the certificate */
+	rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
+	if (rrow == NULL)
+		{
+		BIO_printf(bio_err,"Serial %s not present in db.\n",
+				 row[DB_serial]);
+		ok=-1;
+		goto err;
+		}
+	else if (rrow[DB_type][0]=='V')
+		{
+		BIO_printf(bio_err,"%s=Valid (%c)\n",
+			row[DB_serial], rrow[DB_type][0]);
+		goto err;
+		}
+	else if (rrow[DB_type][0]=='R')
+		{
+		BIO_printf(bio_err,"%s=Revoked (%c)\n",
+			row[DB_serial], rrow[DB_type][0]);
+		goto err;
+		}
+	else if (rrow[DB_type][0]=='E')
+		{
+		BIO_printf(bio_err,"%s=Expired (%c)\n",
+			row[DB_serial], rrow[DB_type][0]);
+		goto err;
+		}
+	else if (rrow[DB_type][0]=='S')
+		{
+		BIO_printf(bio_err,"%s=Suspended (%c)\n",
+			row[DB_serial], rrow[DB_type][0]);
+		goto err;
+		}
+	else
+		{
+		BIO_printf(bio_err,"%s=Unknown (%c).\n",
+			row[DB_serial], rrow[DB_type][0]);
+		ok=-1;
+		}
+err:
+	for (i=0; i<DB_NUMBER; i++)
+		{
+		if (row[i] != NULL)
+			OPENSSL_free(row[i]);
+		}
+	return(ok);
+	}
+
+static int do_updatedb (CA_DB *db)
+	{
+	ASN1_UTCTIME	*a_tm = NULL;
+	int i, cnt = 0;
+	int db_y2k, a_y2k;  /* flags = 1 if y >= 2000 */ 
+	char **rrow, *a_tm_s;
+
+	a_tm = ASN1_UTCTIME_new();
+
+	/* get actual time and make a string */
+	a_tm = X509_gmtime_adj(a_tm, 0);
+	a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
+	if (a_tm_s == NULL)
+		{
+		cnt = -1;
+		goto err;
+		}
+
+	memcpy(a_tm_s, a_tm->data, a_tm->length);
+	a_tm_s[a_tm->length] = '\0';
+
+	if (strncmp(a_tm_s, "49", 2) <= 0)
+		a_y2k = 1;
+	else
+		a_y2k = 0;
+
+	for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
+		{
+		rrow = sk_OPENSSL_PSTRING_value(db->db->data, i);
+
+		if (rrow[DB_type][0] == 'V')
+		 	{
+			/* ignore entries that are not valid */
+			if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
+				db_y2k = 1;
+			else
+				db_y2k = 0;
+
+			if (db_y2k == a_y2k)
+				{
+				/* all on the same y2k side */
+				if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
+				       	{
+				       	rrow[DB_type][0]  = 'E';
+				       	rrow[DB_type][1]  = '\0';
+	  				cnt++;
+
+					BIO_printf(bio_err, "%s=Expired\n",
+							rrow[DB_serial]);
+					}
+				}
+			else if (db_y2k < a_y2k)
+				{
+		  		rrow[DB_type][0]  = 'E';
+		  		rrow[DB_type][1]  = '\0';
+	  			cnt++;
+
+				BIO_printf(bio_err, "%s=Expired\n",
+							rrow[DB_serial]);
+				}
+
+			}
+    		}
+
+err:
+
+	ASN1_UTCTIME_free(a_tm);
+	OPENSSL_free(a_tm_s);
+
+	return (cnt);
+	}
+
+static const char *crl_reasons[] = {
+	/* CRL reason strings */
+	"unspecified",
+	"keyCompromise",
+	"CACompromise",
+	"affiliationChanged",
+	"superseded", 
+	"cessationOfOperation",
+	"certificateHold",
+	"removeFromCRL",
+	/* Additional pseudo reasons */
+	"holdInstruction",
+	"keyTime",
+	"CAkeyTime"
+};
+
+#define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
+
+/* Given revocation information convert to a DB string.
+ * The format of the string is:
+ * revtime[,reason,extra]. Where 'revtime' is the
+ * revocation time (the current time). 'reason' is the
+ * optional CRL reason and 'extra' is any additional
+ * argument
+ */
+
+char *make_revocation_str(int rev_type, char *rev_arg)
+	{
+	char *other = NULL, *str;
+	const char *reason = NULL;
+	ASN1_OBJECT *otmp;
+	ASN1_UTCTIME *revtm = NULL;
+	int i;
+	switch (rev_type)
+		{
+	case REV_NONE:
+		break;
+
+	case REV_CRL_REASON:
+		for (i = 0; i < 8; i++)
+			{
+			if (!strcasecmp(rev_arg, crl_reasons[i]))
+				{
+				reason = crl_reasons[i];
+				break;
+				}
+			}
+		if (reason == NULL)
+			{
+			BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
+			return NULL;
+			}
+		break;
+
+	case REV_HOLD:
+		/* Argument is an OID */
+
+		otmp = OBJ_txt2obj(rev_arg, 0);
+		ASN1_OBJECT_free(otmp);
+
+		if (otmp == NULL)
+			{
+			BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
+			return NULL;
+			}
+
+		reason = "holdInstruction";
+		other = rev_arg;
+		break;
+		
+	case REV_KEY_COMPROMISE:
+	case REV_CA_COMPROMISE:
+
+		/* Argument is the key compromise time  */
+		if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
+			{	
+			BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
+			return NULL;
+			}
+		other = rev_arg;
+		if (rev_type == REV_KEY_COMPROMISE)
+			reason = "keyTime";
+		else 
+			reason = "CAkeyTime";
+
+		break;
+
+		}
+
+	revtm = X509_gmtime_adj(NULL, 0);
+
+	i = revtm->length + 1;
+
+	if (reason) i += strlen(reason) + 1;
+	if (other) i += strlen(other) + 1;
+
+	str = OPENSSL_malloc(i);
+
+	if (!str) return NULL;
+
+	BUF_strlcpy(str, (char *)revtm->data, i);
+	if (reason)
+		{
+		BUF_strlcat(str, ",", i);
+		BUF_strlcat(str, reason, i);
+		}
+	if (other)
+		{
+		BUF_strlcat(str, ",", i);
+		BUF_strlcat(str, other, i);
+		}
+	ASN1_UTCTIME_free(revtm);
+	return str;
+	}
+
+/* Convert revocation field to X509_REVOKED entry 
+ * return code:
+ * 0 error
+ * 1 OK
+ * 2 OK and some extensions added (i.e. V2 CRL)
+ */
+
+
+int make_revoked(X509_REVOKED *rev, const char *str)
+	{
+	char *tmp = NULL;
+	int reason_code = -1;
+	int i, ret = 0;
+	ASN1_OBJECT *hold = NULL;
+	ASN1_GENERALIZEDTIME *comp_time = NULL;
+	ASN1_ENUMERATED *rtmp = NULL;
+
+	ASN1_TIME *revDate = NULL;
+
+	i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
+
+	if (i == 0)
+		goto err;
+
+	if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
+		goto err;
+
+	if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
+		{
+		rtmp = ASN1_ENUMERATED_new();
+		if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
+			goto err;
+		if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
+			goto err;
+		}
+
+	if (rev && comp_time)
+		{
+		if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
+			goto err;
+		}
+	if (rev && hold)
+		{
+		if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
+			goto err;
+		}
+
+	if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
+		ret = 2;
+	else ret = 1;
+
+	err:
+
+	if (tmp) OPENSSL_free(tmp);
+	ASN1_OBJECT_free(hold);
+	ASN1_GENERALIZEDTIME_free(comp_time);
+	ASN1_ENUMERATED_free(rtmp);
+	ASN1_TIME_free(revDate);
+
+	return ret;
+	}
+
+int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
+	{
+	char buf[25],*pbuf, *p;
+	int j;
+	j=i2a_ASN1_OBJECT(bp,obj);
+	pbuf=buf;
+	for (j=22-j; j>0; j--)
+		*(pbuf++)=' ';
+	*(pbuf++)=':';
+	*(pbuf++)='\0';
+	BIO_puts(bp,buf);
+
+	if (str->type == V_ASN1_PRINTABLESTRING)
+		BIO_printf(bp,"PRINTABLE:'");
+	else if (str->type == V_ASN1_T61STRING)
+		BIO_printf(bp,"T61STRING:'");
+	else if (str->type == V_ASN1_IA5STRING)
+		BIO_printf(bp,"IA5STRING:'");
+	else if (str->type == V_ASN1_UNIVERSALSTRING)
+		BIO_printf(bp,"UNIVERSALSTRING:'");
+	else
+		BIO_printf(bp,"ASN.1 %2d:'",str->type);
+			
+	p=(char *)str->data;
+	for (j=str->length; j>0; j--)
+		{
+		if ((*p >= ' ') && (*p <= '~'))
+			BIO_printf(bp,"%c",*p);
+		else if (*p & 0x80)
+			BIO_printf(bp,"\\0x%02X",*p);
+		else if ((unsigned char)*p == 0xf7)
+			BIO_printf(bp,"^?");
+		else	BIO_printf(bp,"^%c",*p+'@');
+		p++;
+		}
+	BIO_printf(bp,"'\n");
+	return 1;
+	}
+
+int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, const char *str)
+	{
+	char *tmp = NULL;
+	char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
+	int reason_code = -1;
+	int ret = 0;
+	unsigned int i;
+	ASN1_OBJECT *hold = NULL;
+	ASN1_GENERALIZEDTIME *comp_time = NULL;
+	tmp = BUF_strdup(str);
+
+	p = strchr(tmp, ',');
+
+	rtime_str = tmp;
+
+	if (p)
+		{
+		*p = '\0';
+		p++;
+		reason_str = p;
+		p = strchr(p, ',');
+		if (p)
+			{
+			*p = '\0';
+			arg_str = p + 1;
+			}
+		}
+
+	if (prevtm)
+		{
+		*prevtm = ASN1_UTCTIME_new();
+		if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
+			{
+			BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
+			goto err;
+			}
+		}
+	if (reason_str)
+		{
+		for (i = 0; i < NUM_REASONS; i++)
+			{
+			if(!strcasecmp(reason_str, crl_reasons[i]))
+				{
+				reason_code = i;
+				break;
+				}
+			}
+		if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
+			{
+			BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
+			goto err;
+			}
+
+		if (reason_code == 7)
+			reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
+		else if (reason_code == 8)		/* Hold instruction */
+			{
+			if (!arg_str)
+				{	
+				BIO_printf(bio_err, "missing hold instruction\n");
+				goto err;
+				}
+			reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
+			hold = OBJ_txt2obj(arg_str, 0);
+
+			if (!hold)
+				{
+				BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
+				goto err;
+				}
+			if (phold) *phold = hold;
+			}
+		else if ((reason_code == 9) || (reason_code == 10))
+			{
+			if (!arg_str)
+				{	
+				BIO_printf(bio_err, "missing compromised time\n");
+				goto err;
+				}
+			comp_time = ASN1_GENERALIZEDTIME_new();
+			if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
+				{	
+				BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
+				goto err;
+				}
+			if (reason_code == 9)
+				reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
+			else
+				reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
+			}
+		}
+
+	if (preason) *preason = reason_code;
+	if (pinvtm) *pinvtm = comp_time;
+	else ASN1_GENERALIZEDTIME_free(comp_time);
+
+	ret = 1;
+
+	err:
+
+	if (tmp) OPENSSL_free(tmp);
+	if (!phold) ASN1_OBJECT_free(hold);
+	if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
+
+	return ret;
+	}
diff --git a/openssl/apps/cert.pem b/openssl/apps/cert.pem
new file mode 100644
index 0000000..de4a77a
--- /dev/null
+++ b/openssl/apps/cert.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBoDCCAUoCAQAwDQYJKoZIhvcNAQEEBQAwYzELMAkGA1UEBhMCQVUxEzARBgNV
+BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYD
+VQQDExpTZXJ2ZXIgdGVzdCBjZXJ0ICg1MTIgYml0KTAeFw05NzA5MDkwMzQxMjZa
+Fw05NzEwMDkwMzQxMjZaMF4xCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0
+YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFzAVBgNVBAMT
+DkVyaWMgdGhlIFlvdW5nMFEwCQYFKw4DAgwFAANEAAJBALVEqPODnpI4rShlY8S7
+tB713JNvabvn6Gned7zylwLLiXQAo/PAT6mfdWPTyCX9RlId/Aroh1ou893BA32Q
+sggwDQYJKoZIhvcNAQEEBQADQQCU5SSgapJSdRXJoX+CpCvFy+JVh9HpSjCpSNKO
+19raHv98hKAUJuP9HyM+SUsffO6mAIgitUaqW8/wDMePhEC3
+-----END CERTIFICATE-----
diff --git a/openssl/apps/ciphers.c b/openssl/apps/ciphers.c
new file mode 100644
index 0000000..3d4c60d
--- /dev/null
+++ b/openssl/apps/ciphers.c
@@ -0,0 +1,231 @@
+/* apps/ciphers.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef OPENSSL_NO_STDIO
+#define APPS_WIN16
+#endif
+#include "apps.h"
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+#undef PROG
+#define PROG	ciphers_main
+
+static const char *ciphers_usage[]={
+"usage: ciphers args\n",
+" -v          - verbose mode, a textual listing of the SSL/TLS ciphers in OpenSSL\n",
+" -V          - even more verbose\n",
+" -ssl2       - SSL2 mode\n",
+" -ssl3       - SSL3 mode\n",
+" -tls1       - TLS1 mode\n",
+NULL
+};
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	int ret=1,i;
+	int verbose=0,Verbose=0;
+	const char **pp;
+	const char *p;
+	int badops=0;
+	SSL_CTX *ctx=NULL;
+	SSL *ssl=NULL;
+	char *ciphers=NULL;
+	const SSL_METHOD *meth=NULL;
+	STACK_OF(SSL_CIPHER) *sk;
+	char buf[512];
+	BIO *STDout=NULL;
+
+#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
+	meth=SSLv23_server_method();
+#elif !defined(OPENSSL_NO_SSL3)
+	meth=SSLv3_server_method();
+#elif !defined(OPENSSL_NO_SSL2)
+	meth=SSLv2_server_method();
+#endif
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+	STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+	{
+	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+	STDout = BIO_push(tmpbio, STDout);
+	}
+#endif
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if (strcmp(*argv,"-v") == 0)
+			verbose=1;
+		else if (strcmp(*argv,"-V") == 0)
+			verbose=Verbose=1;
+#ifndef OPENSSL_NO_SSL2
+		else if (strcmp(*argv,"-ssl2") == 0)
+			meth=SSLv2_client_method();
+#endif
+#ifndef OPENSSL_NO_SSL3
+		else if (strcmp(*argv,"-ssl3") == 0)
+			meth=SSLv3_client_method();
+#endif
+#ifndef OPENSSL_NO_TLS1
+		else if (strcmp(*argv,"-tls1") == 0)
+			meth=TLSv1_client_method();
+#endif
+		else if ((strncmp(*argv,"-h",2) == 0) ||
+			 (strcmp(*argv,"-?") == 0))
+			{
+			badops=1;
+			break;
+			}
+		else
+			{
+			ciphers= *argv;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (badops)
+		{
+		for (pp=ciphers_usage; (*pp != NULL); pp++)
+			BIO_printf(bio_err,"%s",*pp);
+		goto end;
+		}
+
+	OpenSSL_add_ssl_algorithms();
+
+	ctx=SSL_CTX_new(meth);
+	if (ctx == NULL) goto err;
+	if (ciphers != NULL) {
+		if(!SSL_CTX_set_cipher_list(ctx,ciphers)) {
+			BIO_printf(bio_err, "Error in cipher list\n");
+			goto err;
+		}
+	}
+	ssl=SSL_new(ctx);
+	if (ssl == NULL) goto err;
+
+
+	if (!verbose)
+		{
+		for (i=0; ; i++)
+			{
+			p=SSL_get_cipher_list(ssl,i);
+			if (p == NULL) break;
+			if (i != 0) BIO_printf(STDout,":");
+			BIO_printf(STDout,"%s",p);
+			}
+		BIO_printf(STDout,"\n");
+		}
+	else /* verbose */
+		{
+		sk=SSL_get_ciphers(ssl);
+
+		for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
+			{
+			SSL_CIPHER *c;
+
+			c = sk_SSL_CIPHER_value(sk,i);
+			
+			if (Verbose)
+				{
+				unsigned long id = c->id;
+				int id0 = (int)(id >> 24);
+				int id1 = (int)((id >> 16) & 0xffL);
+				int id2 = (int)((id >> 8) & 0xffL);
+				int id3 = (int)(id & 0xffL);
+				
+				if ((id & 0xff000000L) == 0x02000000L)
+					BIO_printf(STDout, "     0x%02X,0x%02X,0x%02X - ", id1, id2, id3); /* SSL2 cipher */
+				else if ((id & 0xff000000L) == 0x03000000L)
+					BIO_printf(STDout, "          0x%02X,0x%02X - ", id2, id3); /* SSL3 cipher */
+				else
+					BIO_printf(STDout, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */
+				}
+
+			BIO_puts(STDout,SSL_CIPHER_description(c,buf,sizeof buf));
+			}
+		}
+
+	ret=0;
+	if (0)
+		{
+err:
+		SSL_load_error_strings();
+		ERR_print_errors(bio_err);
+		}
+end:
+	if (ctx != NULL) SSL_CTX_free(ctx);
+	if (ssl != NULL) SSL_free(ssl);
+	if (STDout != NULL) BIO_free_all(STDout);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
diff --git a/openssl/apps/client.pem b/openssl/apps/client.pem
new file mode 100644
index 0000000..307910e
--- /dev/null
+++ b/openssl/apps/client.pem
@@ -0,0 +1,24 @@
+issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit)
+subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Client test cert (512 bit)
+-----BEGIN CERTIFICATE-----
+MIIB6TCCAVICAQIwDQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCQVUxEzARBgNV
+BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYD
+VQQDExJUZXN0IENBICgxMDI0IGJpdCkwHhcNOTcwNjA5MTM1NzU2WhcNOTgwNjA5
+MTM1NzU2WjBjMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEaMBgG
+A1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxIzAhBgNVBAMTGkNsaWVudCB0ZXN0IGNl
+cnQgKDUxMiBiaXQpMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALtv55QyzG6i2Plw
+Z1pah7++Gv8L5j6Hnyr/uTZE1NLG0ABDDexmq/R4KedLjFEIYjocDui+IXs62NNt
+XrT8odkCAwEAATANBgkqhkiG9w0BAQQFAAOBgQBwtMmI7oGUG8nKmftQssATViH5
+NRRtoEw07DxJp/LfatHdrhqQB73eGdL5WILZJXk46Xz2e9WMSUjVCSYhdKxtflU3
+UR2Ajv1Oo0sTNdfz0wDqJNirLNtzyhhsaq8qMTrLwXrCP31VxBiigFSQSUFnZyTE
+9TKwhS4GlwbtCfxSKQ==
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOwIBAAJBALtv55QyzG6i2PlwZ1pah7++Gv8L5j6Hnyr/uTZE1NLG0ABDDexm
+q/R4KedLjFEIYjocDui+IXs62NNtXrT8odkCAwEAAQJAbwXq0vJ/+uyEvsNgxLko
+/V86mGXQ/KrSkeKlL0r4ENxjcyeMAGoKu6J9yMY7+X9+Zm4nxShNfTsf/+Freoe1
+HQIhAPOSm5Q1YI+KIsII2GeVJx1U69+wnd71OasIPakS1L1XAiEAxQAW+J3/JWE0
+ftEYakbhUOKL8tD1OaFZS71/5GdG7E8CIQCefUMmySSvwd6kC0VlATSWbW+d+jp/
+nWmM1KvqnAo5uQIhALqEADu5U1Wvt8UN8UDGBRPQulHWNycuNV45d3nnskWPAiAw
+ueTyr6WsZ5+SD8g/Hy3xuvF3nPmJRH+rwvVihlcFOg==
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/apps/cms.c b/openssl/apps/cms.c
new file mode 100644
index 0000000..3f5ee1b
--- /dev/null
+++ b/openssl/apps/cms.c
@@ -0,0 +1,1362 @@
+/* apps/cms.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+/* CMS utility function */
+
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+
+#ifndef OPENSSL_NO_CMS
+
+#include <openssl/crypto.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/x509_vfy.h>
+#include <openssl/x509v3.h>
+#include <openssl/cms.h>
+
+#undef PROG
+#define PROG cms_main
+static int save_certs(char *signerfile, STACK_OF(X509) *signers);
+static int cms_cb(int ok, X509_STORE_CTX *ctx);
+static void receipt_request_print(BIO *out, CMS_ContentInfo *cms);
+static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to,
+						int rr_allorfirst,
+					STACK_OF(OPENSSL_STRING) *rr_from);
+
+#define SMIME_OP	0x10
+#define SMIME_IP	0x20
+#define SMIME_SIGNERS	0x40
+#define SMIME_ENCRYPT		(1 | SMIME_OP)
+#define SMIME_DECRYPT		(2 | SMIME_IP)
+#define SMIME_SIGN		(3 | SMIME_OP | SMIME_SIGNERS)
+#define SMIME_VERIFY		(4 | SMIME_IP)
+#define SMIME_CMSOUT		(5 | SMIME_IP | SMIME_OP)
+#define SMIME_RESIGN		(6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
+#define SMIME_DATAOUT		(7 | SMIME_IP)
+#define SMIME_DATA_CREATE	(8 | SMIME_OP)
+#define SMIME_DIGEST_VERIFY	(9 | SMIME_IP)
+#define SMIME_DIGEST_CREATE	(10 | SMIME_OP)
+#define SMIME_UNCOMPRESS	(11 | SMIME_IP)
+#define SMIME_COMPRESS		(12 | SMIME_OP)
+#define SMIME_ENCRYPTED_DECRYPT	(13 | SMIME_IP)
+#define SMIME_ENCRYPTED_ENCRYPT	(14 | SMIME_OP)
+#define SMIME_SIGN_RECEIPT	(15 | SMIME_IP | SMIME_OP)
+#define SMIME_VERIFY_RECEIPT	(16 | SMIME_IP)
+
+int verify_err = 0;
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	ENGINE *e = NULL;
+	int operation = 0;
+	int ret = 0;
+	char **args;
+	const char *inmode = "r", *outmode = "w";
+	char *infile = NULL, *outfile = NULL, *rctfile = NULL;
+	char *signerfile = NULL, *recipfile = NULL;
+	STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL;
+	char *certfile = NULL, *keyfile = NULL, *contfile=NULL;
+	char *certsoutfile = NULL;
+	const EVP_CIPHER *cipher = NULL;
+	CMS_ContentInfo *cms = NULL, *rcms = NULL;
+	X509_STORE *store = NULL;
+	X509 *cert = NULL, *recip = NULL, *signer = NULL;
+	EVP_PKEY *key = NULL;
+	STACK_OF(X509) *encerts = NULL, *other = NULL;
+	BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
+	int badarg = 0;
+	int flags = CMS_DETACHED, noout = 0, print = 0;
+	int verify_retcode = 0;
+	int rr_print = 0, rr_allorfirst = -1;
+	STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL;
+	CMS_ReceiptRequest *rr = NULL;
+	char *to = NULL, *from = NULL, *subject = NULL;
+	char *CAfile = NULL, *CApath = NULL;
+	char *passargin = NULL, *passin = NULL;
+	char *inrand = NULL;
+	int need_rand = 0;
+	const EVP_MD *sign_md = NULL;
+	int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
+        int rctformat = FORMAT_SMIME, keyform = FORMAT_PEM;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+	unsigned char *secret_key = NULL, *secret_keyid = NULL;
+	size_t secret_keylen = 0, secret_keyidlen = 0;
+
+	ASN1_OBJECT *econtent_type = NULL;
+
+	X509_VERIFY_PARAM *vpm = NULL;
+
+	args = argv + 1;
+	ret = 1;
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		{
+		if ((bio_err = BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
+		}
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	while (!badarg && *args && *args[0] == '-')
+		{
+		if (!strcmp (*args, "-encrypt"))
+			operation = SMIME_ENCRYPT;
+		else if (!strcmp (*args, "-decrypt"))
+			operation = SMIME_DECRYPT;
+		else if (!strcmp (*args, "-sign"))
+			operation = SMIME_SIGN;
+		else if (!strcmp (*args, "-sign_receipt"))
+			operation = SMIME_SIGN_RECEIPT;
+		else if (!strcmp (*args, "-resign"))
+			operation = SMIME_RESIGN;
+		else if (!strcmp (*args, "-verify"))
+			operation = SMIME_VERIFY;
+		else if (!strcmp (*args, "-verify_retcode"))
+			verify_retcode = 1;
+		else if (!strcmp(*args,"-verify_receipt"))
+			{
+			operation = SMIME_VERIFY_RECEIPT;
+			if (!args[1])
+				goto argerr;
+			args++;
+			rctfile = *args;
+			}
+		else if (!strcmp (*args, "-cmsout"))
+			operation = SMIME_CMSOUT;
+		else if (!strcmp (*args, "-data_out"))
+			operation = SMIME_DATAOUT;
+		else if (!strcmp (*args, "-data_create"))
+			operation = SMIME_DATA_CREATE;
+		else if (!strcmp (*args, "-digest_verify"))
+			operation = SMIME_DIGEST_VERIFY;
+		else if (!strcmp (*args, "-digest_create"))
+			operation = SMIME_DIGEST_CREATE;
+		else if (!strcmp (*args, "-compress"))
+			operation = SMIME_COMPRESS;
+		else if (!strcmp (*args, "-uncompress"))
+			operation = SMIME_UNCOMPRESS;
+		else if (!strcmp (*args, "-EncryptedData_decrypt"))
+			operation = SMIME_ENCRYPTED_DECRYPT;
+		else if (!strcmp (*args, "-EncryptedData_encrypt"))
+			operation = SMIME_ENCRYPTED_ENCRYPT;
+#ifndef OPENSSL_NO_DES
+		else if (!strcmp (*args, "-des3")) 
+				cipher = EVP_des_ede3_cbc();
+		else if (!strcmp (*args, "-des")) 
+				cipher = EVP_des_cbc();
+#endif
+#ifndef OPENSSL_NO_SEED
+		else if (!strcmp (*args, "-seed")) 
+				cipher = EVP_seed_cbc();
+#endif
+#ifndef OPENSSL_NO_RC2
+		else if (!strcmp (*args, "-rc2-40")) 
+				cipher = EVP_rc2_40_cbc();
+		else if (!strcmp (*args, "-rc2-128")) 
+				cipher = EVP_rc2_cbc();
+		else if (!strcmp (*args, "-rc2-64")) 
+				cipher = EVP_rc2_64_cbc();
+#endif
+#ifndef OPENSSL_NO_AES
+		else if (!strcmp(*args,"-aes128"))
+				cipher = EVP_aes_128_cbc();
+		else if (!strcmp(*args,"-aes192"))
+				cipher = EVP_aes_192_cbc();
+		else if (!strcmp(*args,"-aes256"))
+				cipher = EVP_aes_256_cbc();
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+		else if (!strcmp(*args,"-camellia128"))
+				cipher = EVP_camellia_128_cbc();
+		else if (!strcmp(*args,"-camellia192"))
+				cipher = EVP_camellia_192_cbc();
+		else if (!strcmp(*args,"-camellia256"))
+				cipher = EVP_camellia_256_cbc();
+#endif
+		else if (!strcmp (*args, "-text")) 
+				flags |= CMS_TEXT;
+		else if (!strcmp (*args, "-nointern")) 
+				flags |= CMS_NOINTERN;
+		else if (!strcmp (*args, "-noverify") 
+			|| !strcmp (*args, "-no_signer_cert_verify")) 
+				flags |= CMS_NO_SIGNER_CERT_VERIFY;
+		else if (!strcmp (*args, "-nocerts")) 
+				flags |= CMS_NOCERTS;
+		else if (!strcmp (*args, "-noattr")) 
+				flags |= CMS_NOATTR;
+		else if (!strcmp (*args, "-nodetach")) 
+				flags &= ~CMS_DETACHED;
+		else if (!strcmp (*args, "-nosmimecap"))
+				flags |= CMS_NOSMIMECAP;
+		else if (!strcmp (*args, "-binary"))
+				flags |= CMS_BINARY;
+		else if (!strcmp (*args, "-keyid"))
+				flags |= CMS_USE_KEYID;
+		else if (!strcmp (*args, "-nosigs"))
+				flags |= CMS_NOSIGS;
+		else if (!strcmp (*args, "-no_content_verify"))
+				flags |= CMS_NO_CONTENT_VERIFY;
+		else if (!strcmp (*args, "-no_attr_verify"))
+				flags |= CMS_NO_ATTR_VERIFY;
+		else if (!strcmp (*args, "-stream"))
+				flags |= CMS_STREAM;
+		else if (!strcmp (*args, "-indef"))
+				flags |= CMS_STREAM;
+		else if (!strcmp (*args, "-noindef"))
+				flags &= ~CMS_STREAM;
+		else if (!strcmp (*args, "-nooldmime"))
+				flags |= CMS_NOOLDMIMETYPE;
+		else if (!strcmp (*args, "-crlfeol"))
+				flags |= CMS_CRLFEOL;
+		else if (!strcmp (*args, "-noout"))
+				noout = 1;
+		else if (!strcmp (*args, "-receipt_request_print"))
+				rr_print = 1;
+		else if (!strcmp (*args, "-receipt_request_all"))
+				rr_allorfirst = 0;
+		else if (!strcmp (*args, "-receipt_request_first"))
+				rr_allorfirst = 1;
+		else if (!strcmp(*args,"-receipt_request_from"))
+			{
+			if (!args[1])
+				goto argerr;
+			args++;
+			if (!rr_from)
+				rr_from = sk_OPENSSL_STRING_new_null();
+			sk_OPENSSL_STRING_push(rr_from, *args);
+			}
+		else if (!strcmp(*args,"-receipt_request_to"))
+			{
+			if (!args[1])
+				goto argerr;
+			args++;
+			if (!rr_to)
+				rr_to = sk_OPENSSL_STRING_new_null();
+			sk_OPENSSL_STRING_push(rr_to, *args);
+			}
+		else if (!strcmp (*args, "-print"))
+				{
+				noout = 1;
+				print = 1;
+				}
+		else if (!strcmp(*args,"-secretkey"))
+			{
+			long ltmp;
+			if (!args[1])
+				goto argerr;
+			args++;
+			secret_key = string_to_hex(*args, &ltmp);
+			if (!secret_key)
+				{
+				BIO_printf(bio_err, "Invalid key %s\n", *args);
+				goto argerr;
+				}
+			secret_keylen = (size_t)ltmp;
+			}
+		else if (!strcmp(*args,"-secretkeyid"))
+			{
+			long ltmp;
+			if (!args[1])
+				goto argerr;
+			args++;
+			secret_keyid = string_to_hex(*args, &ltmp);
+			if (!secret_keyid)
+				{
+				BIO_printf(bio_err, "Invalid id %s\n", *args);
+				goto argerr;
+				}
+			secret_keyidlen = (size_t)ltmp;
+			}
+		else if (!strcmp(*args,"-econtent_type"))
+			{
+			if (!args[1])
+				goto argerr;
+			args++;
+			econtent_type = OBJ_txt2obj(*args, 0);
+			if (!econtent_type)
+				{
+				BIO_printf(bio_err, "Invalid OID %s\n", *args);
+				goto argerr;
+				}
+			}
+		else if (!strcmp(*args,"-rand"))
+			{
+			if (!args[1])
+				goto argerr;
+			args++;
+			inrand = *args;
+			need_rand = 1;
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (!strcmp(*args,"-engine"))
+			{
+			if (!args[1])
+				goto argerr;
+			engine = *++args;
+			}
+#endif
+		else if (!strcmp(*args,"-passin"))
+			{
+			if (!args[1])
+				goto argerr;
+			passargin = *++args;
+			}
+		else if (!strcmp (*args, "-to"))
+			{
+			if (!args[1])
+				goto argerr;
+			to = *++args;
+			}
+		else if (!strcmp (*args, "-from"))
+			{
+			if (!args[1])
+				goto argerr;
+			from = *++args;
+			}
+		else if (!strcmp (*args, "-subject"))
+			{
+			if (!args[1])
+				goto argerr;
+			subject = *++args;
+			}
+		else if (!strcmp (*args, "-signer"))
+			{
+			if (!args[1])
+				goto argerr;
+			/* If previous -signer argument add signer to list */
+
+			if (signerfile)
+				{
+				if (!sksigners)
+					sksigners = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(sksigners, signerfile);
+				if (!keyfile)
+					keyfile = signerfile;
+				if (!skkeys)
+					skkeys = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(skkeys, keyfile);
+				keyfile = NULL;
+				}
+			signerfile = *++args;
+			}
+		else if (!strcmp (*args, "-recip"))
+			{
+			if (!args[1])
+				goto argerr;
+			recipfile = *++args;
+			}
+		else if (!strcmp (*args, "-certsout"))
+			{
+			if (!args[1])
+				goto argerr;
+			certsoutfile = *++args;
+			}
+		else if (!strcmp (*args, "-md"))
+			{
+			if (!args[1])
+				goto argerr;
+			sign_md = EVP_get_digestbyname(*++args);
+			if (sign_md == NULL)
+				{
+				BIO_printf(bio_err, "Unknown digest %s\n",
+							*args);
+				goto argerr;
+				}
+			}
+		else if (!strcmp (*args, "-inkey"))
+			{
+			if (!args[1])	
+				goto argerr;
+			/* If previous -inkey arument add signer to list */
+			if (keyfile)
+				{
+				if (!signerfile)
+					{
+					BIO_puts(bio_err, "Illegal -inkey without -signer\n");
+					goto argerr;
+					}
+				if (!sksigners)
+					sksigners = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(sksigners, signerfile);
+				signerfile = NULL;
+				if (!skkeys)
+					skkeys = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(skkeys, keyfile);
+				}
+			keyfile = *++args;
+			}
+		else if (!strcmp (*args, "-keyform"))
+			{
+			if (!args[1])
+				goto argerr;
+			keyform = str2fmt(*++args);
+			}
+		else if (!strcmp (*args, "-rctform"))
+			{
+			if (!args[1])
+				goto argerr;
+			rctformat = str2fmt(*++args);
+			}
+		else if (!strcmp (*args, "-certfile"))
+			{
+			if (!args[1])
+				goto argerr;
+			certfile = *++args;
+			}
+		else if (!strcmp (*args, "-CAfile"))
+			{
+			if (!args[1])
+				goto argerr;
+			CAfile = *++args;
+			}
+		else if (!strcmp (*args, "-CApath"))
+			{
+			if (!args[1])
+				goto argerr;
+			CApath = *++args;
+			}
+		else if (!strcmp (*args, "-in"))
+			{
+			if (!args[1])
+				goto argerr;
+			infile = *++args;
+			}
+		else if (!strcmp (*args, "-inform"))
+			{
+			if (!args[1])
+				goto argerr;
+			informat = str2fmt(*++args);
+			}
+		else if (!strcmp (*args, "-outform"))
+			{
+			if (!args[1])
+				goto argerr;
+			outformat = str2fmt(*++args);
+			}
+		else if (!strcmp (*args, "-out"))
+			{
+			if (!args[1])
+				goto argerr;
+			outfile = *++args;
+			}
+		else if (!strcmp (*args, "-content"))
+			{
+			if (!args[1])
+				goto argerr;
+			contfile = *++args;
+			}
+		else if (args_verify(&args, NULL, &badarg, bio_err, &vpm))
+			continue;
+		else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL)
+			badarg = 1;
+		args++;
+		}
+
+	if (((rr_allorfirst != -1) || rr_from) && !rr_to)
+		{
+		BIO_puts(bio_err, "No Signed Receipts Recipients\n");
+		goto argerr;
+		}
+
+	if (!(operation & SMIME_SIGNERS)  && (rr_to || rr_from))
+		{
+		BIO_puts(bio_err, "Signed receipts only allowed with -sign\n");
+		goto argerr;
+		}
+	if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners))
+		{
+		BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
+		goto argerr;
+		}
+
+	if (operation & SMIME_SIGNERS)
+		{
+		if (keyfile && !signerfile)
+			{
+			BIO_puts(bio_err, "Illegal -inkey without -signer\n");
+			goto argerr;
+			}
+		/* Check to see if any final signer needs to be appended */
+		if (signerfile)
+			{
+			if (!sksigners)
+				sksigners = sk_OPENSSL_STRING_new_null();
+			sk_OPENSSL_STRING_push(sksigners, signerfile);
+			if (!skkeys)
+				skkeys = sk_OPENSSL_STRING_new_null();
+			if (!keyfile)
+				keyfile = signerfile;
+			sk_OPENSSL_STRING_push(skkeys, keyfile);
+			}
+		if (!sksigners)
+			{
+			BIO_printf(bio_err, "No signer certificate specified\n");
+			badarg = 1;
+			}
+		signerfile = NULL;
+		keyfile = NULL;
+		need_rand = 1;
+		}
+
+	else if (operation == SMIME_DECRYPT)
+		{
+		if (!recipfile && !keyfile && !secret_key)
+			{
+			BIO_printf(bio_err, "No recipient certificate or key specified\n");
+			badarg = 1;
+			}
+		}
+	else if (operation == SMIME_ENCRYPT)
+		{
+		if (!*args && !secret_key)
+			{
+			BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
+			badarg = 1;
+			}
+		need_rand = 1;
+		}
+	else if (!operation)
+		badarg = 1;
+
+	if (badarg)
+		{
+		argerr:
+		BIO_printf (bio_err, "Usage cms [options] cert.pem ...\n");
+		BIO_printf (bio_err, "where options are\n");
+		BIO_printf (bio_err, "-encrypt       encrypt message\n");
+		BIO_printf (bio_err, "-decrypt       decrypt encrypted message\n");
+		BIO_printf (bio_err, "-sign          sign message\n");
+		BIO_printf (bio_err, "-verify        verify signed message\n");
+		BIO_printf (bio_err, "-cmsout        output CMS structure\n");
+#ifndef OPENSSL_NO_DES
+		BIO_printf (bio_err, "-des3          encrypt with triple DES\n");
+		BIO_printf (bio_err, "-des           encrypt with DES\n");
+#endif
+#ifndef OPENSSL_NO_SEED
+		BIO_printf (bio_err, "-seed          encrypt with SEED\n");
+#endif
+#ifndef OPENSSL_NO_RC2
+		BIO_printf (bio_err, "-rc2-40        encrypt with RC2-40 (default)\n");
+		BIO_printf (bio_err, "-rc2-64        encrypt with RC2-64\n");
+		BIO_printf (bio_err, "-rc2-128       encrypt with RC2-128\n");
+#endif
+#ifndef OPENSSL_NO_AES
+		BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
+		BIO_printf (bio_err, "               encrypt PEM output with cbc aes\n");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+		BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n");
+		BIO_printf (bio_err, "               encrypt PEM output with cbc camellia\n");
+#endif
+		BIO_printf (bio_err, "-nointern      don't search certificates in message for signer\n");
+		BIO_printf (bio_err, "-nosigs        don't verify message signature\n");
+		BIO_printf (bio_err, "-noverify      don't verify signers certificate\n");
+		BIO_printf (bio_err, "-nocerts       don't include signers certificate when signing\n");
+		BIO_printf (bio_err, "-nodetach      use opaque signing\n");
+		BIO_printf (bio_err, "-noattr        don't include any signed attributes\n");
+		BIO_printf (bio_err, "-binary        don't translate message to text\n");
+		BIO_printf (bio_err, "-certfile file other certificates file\n");
+		BIO_printf (bio_err, "-certsout file certificate output file\n");
+		BIO_printf (bio_err, "-signer file   signer certificate file\n");
+		BIO_printf (bio_err, "-recip  file   recipient certificate file for decryption\n");
+		BIO_printf (bio_err, "-keyid        use subject key identifier\n");
+		BIO_printf (bio_err, "-in file       input file\n");
+		BIO_printf (bio_err, "-inform arg    input format SMIME (default), PEM or DER\n");
+		BIO_printf (bio_err, "-inkey file    input private key (if not signer or recipient)\n");
+		BIO_printf (bio_err, "-keyform arg   input private key format (PEM or ENGINE)\n");
+		BIO_printf (bio_err, "-out file      output file\n");
+		BIO_printf (bio_err, "-outform arg   output format SMIME (default), PEM or DER\n");
+		BIO_printf (bio_err, "-content file  supply or override content for detached signature\n");
+		BIO_printf (bio_err, "-to addr       to address\n");
+		BIO_printf (bio_err, "-from ad       from address\n");
+		BIO_printf (bio_err, "-subject s     subject\n");
+		BIO_printf (bio_err, "-text          include or delete text MIME headers\n");
+		BIO_printf (bio_err, "-CApath dir    trusted certificates directory\n");
+		BIO_printf (bio_err, "-CAfile file   trusted certificates file\n");
+		BIO_printf (bio_err, "-crl_check     check revocation status of signer's certificate using CRLs\n");
+		BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf (bio_err, "-engine e      use engine e, possibly a hardware device.\n");
+#endif
+		BIO_printf (bio_err, "-passin arg    input file pass phrase source\n");
+		BIO_printf(bio_err,  "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+		BIO_printf(bio_err,  "               load the file (or the files in the directory) into\n");
+		BIO_printf(bio_err,  "               the random number generator\n");
+		BIO_printf (bio_err, "cert.pem       recipient certificate(s) for encryption\n");
+		goto end;
+		}
+
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine, 0);
+#endif
+
+	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL))
+		{
+		BIO_printf(bio_err, "Error getting password\n");
+		goto end;
+		}
+
+	if (need_rand)
+		{
+		app_RAND_load_file(NULL, bio_err, (inrand != NULL));
+		if (inrand != NULL)
+			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+				app_RAND_load_files(inrand));
+		}
+
+	ret = 2;
+
+	if (!(operation & SMIME_SIGNERS))
+		flags &= ~CMS_DETACHED;
+
+	if (operation & SMIME_OP)
+		{
+		if (outformat == FORMAT_ASN1)
+			outmode = "wb";
+		}
+	else
+		{
+		if (flags & CMS_BINARY)
+			outmode = "wb";
+		}
+
+	if (operation & SMIME_IP)
+		{
+		if (informat == FORMAT_ASN1)
+			inmode = "rb";
+		}
+	else
+		{
+		if (flags & CMS_BINARY)
+			inmode = "rb";
+		}
+
+	if (operation == SMIME_ENCRYPT)
+		{
+		if (!cipher)
+			{
+#ifndef OPENSSL_NO_DES			
+			cipher = EVP_des_ede3_cbc();
+#else
+			BIO_printf(bio_err, "No cipher selected\n");
+			goto end;
+#endif
+			}
+
+		if (secret_key && !secret_keyid)
+			{
+			BIO_printf(bio_err, "No secret key id\n");
+			goto end;
+			}
+
+		if (*args)
+			encerts = sk_X509_new_null();
+		while (*args)
+			{
+			if (!(cert = load_cert(bio_err,*args,FORMAT_PEM,
+				NULL, e, "recipient certificate file")))
+				goto end;
+			sk_X509_push(encerts, cert);
+			cert = NULL;
+			args++;
+			}
+		}
+
+	if (certfile)
+		{
+		if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL,
+			e, "certificate file")))
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+
+	if (recipfile && (operation == SMIME_DECRYPT))
+		{
+		if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL,
+			e, "recipient certificate file")))
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+
+	if (operation == SMIME_SIGN_RECEIPT)
+		{
+		if (!(signer = load_cert(bio_err,signerfile,FORMAT_PEM,NULL,
+			e, "receipt signer certificate file")))
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+
+	if (operation == SMIME_DECRYPT)
+		{
+		if (!keyfile)
+			keyfile = recipfile;
+		}
+	else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT))
+		{
+		if (!keyfile)
+			keyfile = signerfile;
+		}
+	else keyfile = NULL;
+
+	if (keyfile)
+		{
+		key = load_key(bio_err, keyfile, keyform, 0, passin, e,
+			       "signing key file");
+		if (!key)
+			goto end;
+		}
+
+	if (infile)
+		{
+		if (!(in = BIO_new_file(infile, inmode)))
+			{
+			BIO_printf (bio_err,
+				 "Can't open input file %s\n", infile);
+			goto end;
+			}
+		}
+	else
+		in = BIO_new_fp(stdin, BIO_NOCLOSE);
+
+	if (operation & SMIME_IP)
+		{
+		if (informat == FORMAT_SMIME) 
+			cms = SMIME_read_CMS(in, &indata);
+		else if (informat == FORMAT_PEM) 
+			cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
+		else if (informat == FORMAT_ASN1) 
+			cms = d2i_CMS_bio(in, NULL);
+		else
+			{
+			BIO_printf(bio_err, "Bad input format for CMS file\n");
+			goto end;
+			}
+
+		if (!cms)
+			{
+			BIO_printf(bio_err, "Error reading S/MIME message\n");
+			goto end;
+			}
+		if (contfile)
+			{
+			BIO_free(indata);
+			if (!(indata = BIO_new_file(contfile, "rb")))
+				{
+				BIO_printf(bio_err, "Can't read content file %s\n", contfile);
+				goto end;
+				}
+			}
+		if (certsoutfile)
+			{
+			STACK_OF(X509) *allcerts;
+			allcerts = CMS_get1_certs(cms);
+			if (!save_certs(certsoutfile, allcerts))
+				{
+				BIO_printf(bio_err,
+						"Error writing certs to %s\n",
+								certsoutfile);
+				ret = 5;
+				goto end;
+				}
+			sk_X509_pop_free(allcerts, X509_free);
+			}
+		}
+
+	if (rctfile)
+		{
+		char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r";
+		if (!(rctin = BIO_new_file(rctfile, rctmode)))
+			{
+			BIO_printf (bio_err,
+				 "Can't open receipt file %s\n", rctfile);
+			goto end;
+			}
+		
+		if (rctformat == FORMAT_SMIME) 
+			rcms = SMIME_read_CMS(rctin, NULL);
+		else if (rctformat == FORMAT_PEM) 
+			rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
+		else if (rctformat == FORMAT_ASN1) 
+			rcms = d2i_CMS_bio(rctin, NULL);
+		else
+			{
+			BIO_printf(bio_err, "Bad input format for receipt\n");
+			goto end;
+			}
+
+		if (!rcms)
+			{
+			BIO_printf(bio_err, "Error reading receipt\n");
+			goto end;
+			}
+		}
+
+	if (outfile)
+		{
+		if (!(out = BIO_new_file(outfile, outmode)))
+			{
+			BIO_printf (bio_err,
+				 "Can't open output file %s\n", outfile);
+			goto end;
+			}
+		}
+	else
+		{
+		out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		    out = BIO_push(tmpbio, out);
+		}
+#endif
+		}
+
+	if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT))
+		{
+		if (!(store = setup_verify(bio_err, CAfile, CApath)))
+			goto end;
+		X509_STORE_set_verify_cb(store, cms_cb);
+		if (vpm)
+			X509_STORE_set1_param(store, vpm);
+		}
+
+
+	ret = 3;
+
+	if (operation == SMIME_DATA_CREATE)
+		{
+		cms = CMS_data_create(in, flags);
+		}
+	else if (operation == SMIME_DIGEST_CREATE)
+		{
+		cms = CMS_digest_create(in, sign_md, flags);
+		}
+	else if (operation == SMIME_COMPRESS)
+		{
+		cms = CMS_compress(in, -1, flags);
+		}
+	else if (operation == SMIME_ENCRYPT)
+		{
+		flags |= CMS_PARTIAL;
+		cms = CMS_encrypt(encerts, in, cipher, flags);
+		if (!cms)
+			goto end;
+		if (secret_key)
+			{
+			if (!CMS_add0_recipient_key(cms, NID_undef, 
+						secret_key, secret_keylen,
+						secret_keyid, secret_keyidlen,
+						NULL, NULL, NULL))
+				goto end;
+			/* NULL these because call absorbs them */
+			secret_key = NULL;
+			secret_keyid = NULL;
+			}
+		if (!(flags & CMS_STREAM))
+			{
+			if (!CMS_final(cms, in, NULL, flags))
+				goto end;
+			}
+		}
+	else if (operation == SMIME_ENCRYPTED_ENCRYPT)
+		{
+		cms = CMS_EncryptedData_encrypt(in, cipher,
+						secret_key, secret_keylen,
+						flags);
+
+		}
+	else if (operation == SMIME_SIGN_RECEIPT)
+		{
+		CMS_ContentInfo *srcms = NULL;
+		STACK_OF(CMS_SignerInfo) *sis;
+		CMS_SignerInfo *si;
+		sis = CMS_get0_SignerInfos(cms);
+		if (!sis)
+			goto end;
+		si = sk_CMS_SignerInfo_value(sis, 0);
+		srcms = CMS_sign_receipt(si, signer, key, other, flags);
+		if (!srcms)
+			goto end;
+		CMS_ContentInfo_free(cms);
+		cms = srcms;
+		}
+	else if (operation & SMIME_SIGNERS)
+		{
+		int i;
+		/* If detached data content we enable streaming if
+		 * S/MIME output format.
+		 */
+		if (operation == SMIME_SIGN)
+			{
+				
+			if (flags & CMS_DETACHED)
+				{
+				if (outformat == FORMAT_SMIME)
+					flags |= CMS_STREAM;
+				}
+			flags |= CMS_PARTIAL;
+			cms = CMS_sign(NULL, NULL, other, in, flags);
+			if (!cms)
+				goto end;
+			if (econtent_type)
+				CMS_set1_eContentType(cms, econtent_type);
+
+			if (rr_to)
+				{
+				rr = make_receipt_request(rr_to, rr_allorfirst,
+								rr_from);
+				if (!rr)
+					{
+					BIO_puts(bio_err,
+				"Signed Receipt Request Creation Error\n");
+					goto end;
+					}
+				}
+			}
+		else
+			flags |= CMS_REUSE_DIGEST;
+		for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++)
+			{
+			CMS_SignerInfo *si;
+			signerfile = sk_OPENSSL_STRING_value(sksigners, i);
+			keyfile = sk_OPENSSL_STRING_value(skkeys, i);
+			signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL,
+					e, "signer certificate");
+			if (!signer)
+				goto end;
+			key = load_key(bio_err, keyfile, keyform, 0, passin, e,
+			       "signing key file");
+			if (!key)
+				goto end;
+			si = CMS_add1_signer(cms, signer, key, sign_md, flags);
+			if (!si)
+				goto end;
+			if (rr && !CMS_add1_ReceiptRequest(si, rr))
+				goto end;
+			X509_free(signer);
+			signer = NULL;
+			EVP_PKEY_free(key);
+			key = NULL;
+			}
+		/* If not streaming or resigning finalize structure */
+		if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM))
+			{
+			if (!CMS_final(cms, in, NULL, flags))
+				goto end;
+			}
+		}
+
+	if (!cms)
+		{
+		BIO_printf(bio_err, "Error creating CMS structure\n");
+		goto end;
+		}
+
+	ret = 4;
+	if (operation == SMIME_DECRYPT)
+		{
+
+		if (secret_key)
+			{
+			if (!CMS_decrypt_set1_key(cms,
+						secret_key, secret_keylen,
+						secret_keyid, secret_keyidlen))
+				{
+				BIO_puts(bio_err,
+					"Error decrypting CMS using secret key\n");
+				goto end;
+				}
+			}
+
+		if (key)
+			{
+			if (!CMS_decrypt_set1_pkey(cms, key, recip))
+				{
+				BIO_puts(bio_err,
+					"Error decrypting CMS using private key\n");
+				goto end;
+				}
+			}
+
+		if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags))
+			{
+			BIO_printf(bio_err, "Error decrypting CMS structure\n");
+			goto end;
+			}
+		}
+	else if (operation == SMIME_DATAOUT)
+		{
+		if (!CMS_data(cms, out, flags))
+			goto end;
+		}
+	else if (operation == SMIME_UNCOMPRESS)
+		{
+		if (!CMS_uncompress(cms, indata, out, flags))
+			goto end;
+		}
+	else if (operation == SMIME_DIGEST_VERIFY)
+		{
+		if (CMS_digest_verify(cms, indata, out, flags) > 0)
+			BIO_printf(bio_err, "Verification successful\n");
+		else
+			{
+			BIO_printf(bio_err, "Verification failure\n");
+			goto end;
+			}
+		}
+	else if (operation == SMIME_ENCRYPTED_DECRYPT)
+		{
+		if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen,
+						indata, out, flags))
+			goto end;
+		}
+	else if (operation == SMIME_VERIFY)
+		{
+		if (CMS_verify(cms, other, store, indata, out, flags) > 0)
+			BIO_printf(bio_err, "Verification successful\n");
+		else
+			{
+			BIO_printf(bio_err, "Verification failure\n");
+			if (verify_retcode)
+				ret = verify_err + 32;
+			goto end;
+			}
+		if (signerfile)
+			{
+			STACK_OF(X509) *signers;
+			signers = CMS_get0_signers(cms);
+			if (!save_certs(signerfile, signers))
+				{
+				BIO_printf(bio_err,
+						"Error writing signers to %s\n",
+								signerfile);
+				ret = 5;
+				goto end;
+				}
+			sk_X509_free(signers);
+			}
+		if (rr_print)
+			receipt_request_print(bio_err, cms);
+					
+		}
+	else if (operation == SMIME_VERIFY_RECEIPT)
+		{
+		if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0)
+			BIO_printf(bio_err, "Verification successful\n");
+		else
+			{
+			BIO_printf(bio_err, "Verification failure\n");
+			goto end;
+			}
+		}
+	else
+		{
+		if (noout)
+			{
+			if (print)
+				CMS_ContentInfo_print_ctx(out, cms, 0, NULL);
+			}
+		else if (outformat == FORMAT_SMIME)
+			{
+			if (to)
+				BIO_printf(out, "To: %s\n", to);
+			if (from)
+				BIO_printf(out, "From: %s\n", from);
+			if (subject)
+				BIO_printf(out, "Subject: %s\n", subject);
+			if (operation == SMIME_RESIGN)
+				ret = SMIME_write_CMS(out, cms, indata, flags);
+			else
+				ret = SMIME_write_CMS(out, cms, in, flags);
+			}
+		else if (outformat == FORMAT_PEM) 
+			ret = PEM_write_bio_CMS_stream(out, cms, in, flags);
+		else if (outformat == FORMAT_ASN1) 
+			ret = i2d_CMS_bio_stream(out,cms, in, flags);
+		else
+			{
+			BIO_printf(bio_err, "Bad output format for CMS file\n");
+			goto end;
+			}
+		if (ret <= 0)
+			{
+			ret = 6;
+			goto end;
+			}
+		}
+	ret = 0;
+end:
+	if (ret)
+		ERR_print_errors(bio_err);
+	if (need_rand)
+		app_RAND_write_file(NULL, bio_err);
+	sk_X509_pop_free(encerts, X509_free);
+	sk_X509_pop_free(other, X509_free);
+	if (vpm)
+		X509_VERIFY_PARAM_free(vpm);
+	if (sksigners)
+		sk_OPENSSL_STRING_free(sksigners);
+	if (skkeys)
+		sk_OPENSSL_STRING_free(skkeys);
+	if (secret_key)
+		OPENSSL_free(secret_key);
+	if (secret_keyid)
+		OPENSSL_free(secret_keyid);
+	if (econtent_type)
+		ASN1_OBJECT_free(econtent_type);
+	if (rr)
+		CMS_ReceiptRequest_free(rr);
+	if (rr_to)
+		sk_OPENSSL_STRING_free(rr_to);
+	if (rr_from)
+		sk_OPENSSL_STRING_free(rr_from);
+	X509_STORE_free(store);
+	X509_free(cert);
+	X509_free(recip);
+	X509_free(signer);
+	EVP_PKEY_free(key);
+	CMS_ContentInfo_free(cms);
+	CMS_ContentInfo_free(rcms);
+	BIO_free(rctin);
+	BIO_free(in);
+	BIO_free(indata);
+	BIO_free_all(out);
+	if (passin) OPENSSL_free(passin);
+	return (ret);
+}
+
+static int save_certs(char *signerfile, STACK_OF(X509) *signers)
+	{
+	int i;
+	BIO *tmp;
+	if (!signerfile)
+		return 1;
+	tmp = BIO_new_file(signerfile, "w");
+	if (!tmp) return 0;
+	for(i = 0; i < sk_X509_num(signers); i++)
+		PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
+	BIO_free(tmp);
+	return 1;
+	}
+	
+
+/* Minimal callback just to output policy info (if any) */
+
+static int cms_cb(int ok, X509_STORE_CTX *ctx)
+	{
+	int error;
+
+	error = X509_STORE_CTX_get_error(ctx);
+
+	verify_err = error;
+
+	if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
+		&& ((error != X509_V_OK) || (ok != 2)))
+		return ok;
+
+	policies_print(NULL, ctx);
+
+	return ok;
+
+	}
+
+static void gnames_stack_print(BIO *out, STACK_OF(GENERAL_NAMES) *gns)
+	{
+	STACK_OF(GENERAL_NAME) *gens;
+	GENERAL_NAME *gen;
+	int i, j;
+	for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++)
+		{
+		gens = sk_GENERAL_NAMES_value(gns, i);
+		for (j = 0; j < sk_GENERAL_NAME_num(gens); j++)
+			{
+			gen = sk_GENERAL_NAME_value(gens, j);
+			BIO_puts(out, "    ");
+			GENERAL_NAME_print(out, gen);
+			BIO_puts(out, "\n");
+			}
+		}
+	return;
+	}
+
+static void receipt_request_print(BIO *out, CMS_ContentInfo *cms)
+	{
+	STACK_OF(CMS_SignerInfo) *sis;
+	CMS_SignerInfo *si;
+	CMS_ReceiptRequest *rr;
+	int allorfirst;
+	STACK_OF(GENERAL_NAMES) *rto, *rlist;
+	ASN1_STRING *scid;
+	int i, rv;
+	sis = CMS_get0_SignerInfos(cms);
+	for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++)
+		{
+		si = sk_CMS_SignerInfo_value(sis, i);
+		rv = CMS_get1_ReceiptRequest(si, &rr);
+		BIO_printf(bio_err, "Signer %d:\n", i + 1);
+		if (rv == 0)
+			BIO_puts(bio_err, "  No Receipt Request\n");
+		else if (rv < 0)
+			{
+			BIO_puts(bio_err, "  Receipt Request Parse Error\n");
+			ERR_print_errors(bio_err);
+			}
+		else
+			{
+			char *id;
+			int idlen;
+			CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst,
+							&rlist, &rto);
+			BIO_puts(out, "  Signed Content ID:\n");
+			idlen = ASN1_STRING_length(scid);
+			id = (char *)ASN1_STRING_data(scid);
+			BIO_dump_indent(out, id, idlen, 4);
+			BIO_puts(out, "  Receipts From");
+			if (rlist)
+				{
+				BIO_puts(out, " List:\n");
+				gnames_stack_print(out, rlist);
+				}
+			else if (allorfirst == 1)
+				BIO_puts(out, ": First Tier\n");
+			else if (allorfirst == 0)
+				BIO_puts(out, ": All\n");
+			else
+				BIO_printf(out, " Unknown (%d)\n", allorfirst);
+			BIO_puts(out, "  Receipts To:\n");
+			gnames_stack_print(out, rto);
+			}
+		if (rr)
+			CMS_ReceiptRequest_free(rr);
+		}
+	}
+
+static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns)
+	{
+	int i;
+	STACK_OF(GENERAL_NAMES) *ret;
+	GENERAL_NAMES *gens = NULL;
+	GENERAL_NAME *gen = NULL;
+	ret = sk_GENERAL_NAMES_new_null();
+	if (!ret)
+		goto err;
+	for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++)
+		{
+		char *str = sk_OPENSSL_STRING_value(ns, i);
+		gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0);
+		if (!gen)
+			goto err;
+		gens = GENERAL_NAMES_new();
+		if (!gens)
+			goto err;
+		if (!sk_GENERAL_NAME_push(gens, gen))
+			goto err;
+		gen = NULL;
+		if (!sk_GENERAL_NAMES_push(ret, gens))
+			goto err;
+		gens = NULL;
+		}
+
+	return ret;
+
+	err:
+	if (ret)
+		sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free);
+	if (gens)
+		GENERAL_NAMES_free(gens);
+	if (gen)
+		GENERAL_NAME_free(gen);
+	return NULL;
+	}
+
+
+static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to,
+						int rr_allorfirst,
+						STACK_OF(OPENSSL_STRING) *rr_from)
+	{
+	STACK_OF(GENERAL_NAMES) *rct_to, *rct_from;
+	CMS_ReceiptRequest *rr;
+	rct_to = make_names_stack(rr_to);
+	if (!rct_to)
+		goto err;
+	if (rr_from)
+		{
+		rct_from = make_names_stack(rr_from);
+		if (!rct_from)
+			goto err;
+		}
+	else
+		rct_from = NULL;
+	rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from,
+						rct_to);
+	return rr;
+	err:
+	return NULL;
+	}
+
+#endif
diff --git a/openssl/apps/crl.c b/openssl/apps/crl.c
new file mode 100644
index 0000000..c395b2a
--- /dev/null
+++ b/openssl/apps/crl.c
@@ -0,0 +1,446 @@
+/* apps/crl.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/pem.h>
+
+#undef PROG
+#define PROG	crl_main
+
+#undef POSTFIX
+#define	POSTFIX	".rvk"
+
+static const char *crl_usage[]={
+"usage: crl args\n",
+"\n",
+" -inform arg     - input format - default PEM (DER or PEM)\n",
+" -outform arg    - output format - default PEM\n",
+" -text           - print out a text format version\n",
+" -in arg         - input file - default stdin\n",
+" -out arg        - output file - default stdout\n",
+" -hash           - print hash value\n",
+" -fingerprint    - print the crl fingerprint\n",
+" -issuer         - print issuer DN\n",
+" -lastupdate     - lastUpdate field\n",
+" -nextupdate     - nextUpdate field\n",
+" -crlnumber      - print CRL number\n",
+" -noout          - no CRL output\n",
+" -CAfile  name   - verify CRL using certificates in file \"name\"\n",
+" -CApath  dir    - verify CRL using certificates in \"dir\"\n",
+" -nameopt arg    - various certificate name options\n",
+NULL
+};
+
+static X509_CRL *load_crl(char *file, int format);
+static BIO *bio_out=NULL;
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	unsigned long nmflag = 0;
+	X509_CRL *x=NULL;
+	char *CAfile = NULL, *CApath = NULL;
+	int ret=1,i,num,badops=0;
+	BIO *out=NULL;
+	int informat,outformat;
+	char *infile=NULL,*outfile=NULL;
+	int hash=0,issuer=0,lastupdate=0,nextupdate=0,noout=0,text=0;
+	int fingerprint = 0, crlnumber = 0;
+	const char **pp;
+	X509_STORE *store = NULL;
+	X509_STORE_CTX ctx;
+	X509_LOOKUP *lookup = NULL;
+	X509_OBJECT xobj;
+	EVP_PKEY *pkey;
+	int do_ver = 0;
+	const EVP_MD *md_alg,*digest=EVP_sha1();
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	if (bio_out == NULL)
+		if ((bio_out=BIO_new(BIO_s_file())) != NULL)
+			{
+			BIO_set_fp(bio_out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+			{
+			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+			bio_out = BIO_push(tmpbio, bio_out);
+			}
+#endif
+			}
+
+	informat=FORMAT_PEM;
+	outformat=FORMAT_PEM;
+
+	argc--;
+	argv++;
+	num=0;
+	while (argc >= 1)
+		{
+#ifdef undef
+		if	(strcmp(*argv,"-p") == 0)
+			{
+			if (--argc < 1) goto bad;
+			if (!args_from_file(++argv,Nargc,Nargv)) { goto end; }*/
+			}
+#endif
+		if 	(strcmp(*argv,"-inform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			informat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-outform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outformat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-CApath") == 0)
+			{
+			if (--argc < 1) goto bad;
+			CApath = *(++argv);
+			do_ver = 1;
+			}
+		else if (strcmp(*argv,"-CAfile") == 0)
+			{
+			if (--argc < 1) goto bad;
+			CAfile = *(++argv);
+			do_ver = 1;
+			}
+		else if (strcmp(*argv,"-verify") == 0)
+			do_ver = 1;
+		else if (strcmp(*argv,"-text") == 0)
+			text = 1;
+		else if (strcmp(*argv,"-hash") == 0)
+			hash= ++num;
+		else if (strcmp(*argv,"-nameopt") == 0)
+			{
+			if (--argc < 1) goto bad;
+			if (!set_name_ex(&nmflag, *(++argv))) goto bad;
+			}
+		else if (strcmp(*argv,"-issuer") == 0)
+			issuer= ++num;
+		else if (strcmp(*argv,"-lastupdate") == 0)
+			lastupdate= ++num;
+		else if (strcmp(*argv,"-nextupdate") == 0)
+			nextupdate= ++num;
+		else if (strcmp(*argv,"-noout") == 0)
+			noout= ++num;
+		else if (strcmp(*argv,"-fingerprint") == 0)
+			fingerprint= ++num;
+		else if (strcmp(*argv,"-crlnumber") == 0)
+			crlnumber= ++num;
+		else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
+			{
+			/* ok */
+			digest=md_alg;
+			}
+		else
+			{
+			BIO_printf(bio_err,"unknown option %s\n",*argv);
+			badops=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (badops)
+		{
+bad:
+		for (pp=crl_usage; (*pp != NULL); pp++)
+			BIO_printf(bio_err,"%s",*pp);
+		goto end;
+		}
+
+	ERR_load_crypto_strings();
+	x=load_crl(infile,informat);
+	if (x == NULL) { goto end; }
+
+	if(do_ver) {
+		store = X509_STORE_new();
+		lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file());
+		if (lookup == NULL) goto end;
+		if (!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM))
+			X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
+			
+		lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir());
+		if (lookup == NULL) goto end;
+		if (!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM))
+			X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
+		ERR_clear_error();
+
+		if(!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) {
+			BIO_printf(bio_err,
+				"Error initialising X509 store\n");
+			goto end;
+		}
+
+		i = X509_STORE_get_by_subject(&ctx, X509_LU_X509, 
+					X509_CRL_get_issuer(x), &xobj);
+		if(i <= 0) {
+			BIO_printf(bio_err,
+				"Error getting CRL issuer certificate\n");
+			goto end;
+		}
+		pkey = X509_get_pubkey(xobj.data.x509);
+		X509_OBJECT_free_contents(&xobj);
+		if(!pkey) {
+			BIO_printf(bio_err,
+				"Error getting CRL issuer public key\n");
+			goto end;
+		}
+		i = X509_CRL_verify(x, pkey);
+		EVP_PKEY_free(pkey);
+		if(i < 0) goto end;
+		if(i == 0) BIO_printf(bio_err, "verify failure\n");
+		else BIO_printf(bio_err, "verify OK\n");
+	}
+
+	if (num)
+		{
+		for (i=1; i<=num; i++)
+			{
+			if (issuer == i)
+				{
+				print_name(bio_out, "issuer=", X509_CRL_get_issuer(x), nmflag);
+				}
+			if (crlnumber == i)
+				{
+				ASN1_INTEGER *crlnum;
+				crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number,
+							      NULL, NULL);
+				BIO_printf(bio_out,"crlNumber=");
+				if (crlnum)
+					{
+					i2a_ASN1_INTEGER(bio_out, crlnum);
+					ASN1_INTEGER_free(crlnum);
+					}
+				else
+					BIO_puts(bio_out, "<NONE>");
+				BIO_printf(bio_out,"\n");
+				}
+			if (hash == i)
+				{
+				BIO_printf(bio_out,"%08lx\n",
+					X509_NAME_hash(X509_CRL_get_issuer(x)));
+				}
+			if (lastupdate == i)
+				{
+				BIO_printf(bio_out,"lastUpdate=");
+				ASN1_TIME_print(bio_out,
+						X509_CRL_get_lastUpdate(x));
+				BIO_printf(bio_out,"\n");
+				}
+			if (nextupdate == i)
+				{
+				BIO_printf(bio_out,"nextUpdate=");
+				if (X509_CRL_get_nextUpdate(x)) 
+					ASN1_TIME_print(bio_out,
+						X509_CRL_get_nextUpdate(x));
+				else
+					BIO_printf(bio_out,"NONE");
+				BIO_printf(bio_out,"\n");
+				}
+			if (fingerprint == i)
+				{
+				int j;
+				unsigned int n;
+				unsigned char md[EVP_MAX_MD_SIZE];
+
+				if (!X509_CRL_digest(x,digest,md,&n))
+					{
+					BIO_printf(bio_err,"out of memory\n");
+					goto end;
+					}
+				BIO_printf(bio_out,"%s Fingerprint=",
+						OBJ_nid2sn(EVP_MD_type(digest)));
+				for (j=0; j<(int)n; j++)
+					{
+					BIO_printf(bio_out,"%02X%c",md[j],
+						(j+1 == (int)n)
+						?'\n':':');
+					}
+				}
+			}
+		}
+
+	out=BIO_new(BIO_s_file());
+	if (out == NULL)
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (outfile == NULL)
+		{
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+		}
+	else
+		{
+		if (BIO_write_filename(out,outfile) <= 0)
+			{
+			perror(outfile);
+			goto end;
+			}
+		}
+
+	if (text) X509_CRL_print(out, x);
+
+	if (noout) 
+		{
+		ret = 0;
+		goto end;
+		}
+
+	if 	(outformat == FORMAT_ASN1)
+		i=(int)i2d_X509_CRL_bio(out,x);
+	else if (outformat == FORMAT_PEM)
+		i=PEM_write_bio_X509_CRL(out,x);
+	else	
+		{
+		BIO_printf(bio_err,"bad output format specified for outfile\n");
+		goto end;
+		}
+	if (!i) { BIO_printf(bio_err,"unable to write CRL\n"); goto end; }
+	ret=0;
+end:
+	BIO_free_all(out);
+	BIO_free_all(bio_out);
+	bio_out=NULL;
+	X509_CRL_free(x);
+	if(store) {
+		X509_STORE_CTX_cleanup(&ctx);
+		X509_STORE_free(store);
+	}
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
+static X509_CRL *load_crl(char *infile, int format)
+	{
+	X509_CRL *x=NULL;
+	BIO *in=NULL;
+
+	in=BIO_new(BIO_s_file());
+	if (in == NULL)
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (infile == NULL)
+		BIO_set_fp(in,stdin,BIO_NOCLOSE);
+	else
+		{
+		if (BIO_read_filename(in,infile) <= 0)
+			{
+			perror(infile);
+			goto end;
+			}
+		}
+	if 	(format == FORMAT_ASN1)
+		x=d2i_X509_CRL_bio(in,NULL);
+	else if (format == FORMAT_PEM)
+		x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
+	else	{
+		BIO_printf(bio_err,"bad input format specified for input crl\n");
+		goto end;
+		}
+	if (x == NULL)
+		{
+		BIO_printf(bio_err,"unable to load CRL\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+	
+end:
+	BIO_free(in);
+	return(x);
+	}
+
diff --git a/openssl/apps/crl2p7.c b/openssl/apps/crl2p7.c
new file mode 100644
index 0000000..bbc8377
--- /dev/null
+++ b/openssl/apps/crl2p7.c
@@ -0,0 +1,337 @@
+/* apps/crl2p7.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* This was written by Gordon Chaffee <chaffee@plateau.cs.berkeley.edu>
+ * and donated 'to the cause' along with lots and lots of other fixes to
+ * the library. */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include "apps.h"
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pem.h>
+#include <openssl/objects.h>
+
+static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile);
+#undef PROG
+#define PROG	crl2pkcs7_main
+
+/* -inform arg	- input format - default PEM (DER or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg	- input file - default stdin
+ * -out arg	- output file - default stdout
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	int i,badops=0;
+	BIO *in=NULL,*out=NULL;
+	int informat,outformat;
+	char *infile,*outfile,*prog,*certfile;
+	PKCS7 *p7 = NULL;
+	PKCS7_SIGNED *p7s = NULL;
+	X509_CRL *crl=NULL;
+	STACK_OF(OPENSSL_STRING) *certflst=NULL;
+	STACK_OF(X509_CRL) *crl_stack=NULL;
+	STACK_OF(X509) *cert_stack=NULL;
+	int ret=1,nocrl=0;
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	infile=NULL;
+	outfile=NULL;
+	informat=FORMAT_PEM;
+	outformat=FORMAT_PEM;
+
+	prog=argv[0];
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if 	(strcmp(*argv,"-inform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			informat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-outform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outformat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			}
+		else if (strcmp(*argv,"-nocrl") == 0)
+			{
+			nocrl=1;
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-certfile") == 0)
+			{
+			if (--argc < 1) goto bad;
+			if(!certflst) certflst = sk_OPENSSL_STRING_new_null();
+			sk_OPENSSL_STRING_push(certflst,*(++argv));
+			}
+		else
+			{
+			BIO_printf(bio_err,"unknown option %s\n",*argv);
+			badops=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (badops)
+		{
+bad:
+		BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
+		BIO_printf(bio_err,"where options are\n");
+		BIO_printf(bio_err," -inform arg    input format - DER or PEM\n");
+		BIO_printf(bio_err," -outform arg   output format - DER or PEM\n");
+		BIO_printf(bio_err," -in arg        input file\n");
+		BIO_printf(bio_err," -out arg       output file\n");
+		BIO_printf(bio_err," -certfile arg  certificates file of chain to a trusted CA\n");
+		BIO_printf(bio_err,"                (can be used more than once)\n");
+		BIO_printf(bio_err," -nocrl         no crl to load, just certs from '-certfile'\n");
+		ret = 1;
+		goto end;
+		}
+
+	ERR_load_crypto_strings();
+
+	in=BIO_new(BIO_s_file());
+	out=BIO_new(BIO_s_file());
+	if ((in == NULL) || (out == NULL))
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (!nocrl)
+		{
+		if (infile == NULL)
+			BIO_set_fp(in,stdin,BIO_NOCLOSE);
+		else
+			{
+			if (BIO_read_filename(in,infile) <= 0)
+				{
+				perror(infile);
+				goto end;
+				}
+			}
+
+		if 	(informat == FORMAT_ASN1)
+			crl=d2i_X509_CRL_bio(in,NULL);
+		else if (informat == FORMAT_PEM)
+			crl=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
+		else	{
+			BIO_printf(bio_err,"bad input format specified for input crl\n");
+			goto end;
+			}
+		if (crl == NULL)
+			{
+			BIO_printf(bio_err,"unable to load CRL\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+	
+	if ((p7=PKCS7_new()) == NULL) goto end;
+	if ((p7s=PKCS7_SIGNED_new()) == NULL) goto end;
+	p7->type=OBJ_nid2obj(NID_pkcs7_signed);
+	p7->d.sign=p7s;
+	p7s->contents->type=OBJ_nid2obj(NID_pkcs7_data);
+
+	if (!ASN1_INTEGER_set(p7s->version,1)) goto end;
+	if ((crl_stack=sk_X509_CRL_new_null()) == NULL) goto end;
+	p7s->crl=crl_stack;
+	if (crl != NULL)
+		{
+		sk_X509_CRL_push(crl_stack,crl);
+		crl=NULL; /* now part of p7 for OPENSSL_freeing */
+		}
+
+	if ((cert_stack=sk_X509_new_null()) == NULL) goto end;
+	p7s->cert=cert_stack;
+
+	if(certflst) for(i = 0; i < sk_OPENSSL_STRING_num(certflst); i++) {
+		certfile = sk_OPENSSL_STRING_value(certflst, i);
+		if (add_certs_from_file(cert_stack,certfile) < 0)
+			{
+			BIO_printf(bio_err, "error loading certificates\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+	}
+
+	sk_OPENSSL_STRING_free(certflst);
+
+	if (outfile == NULL)
+		{
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+		}
+	else
+		{
+		if (BIO_write_filename(out,outfile) <= 0)
+			{
+			perror(outfile);
+			goto end;
+			}
+		}
+
+	if 	(outformat == FORMAT_ASN1)
+		i=i2d_PKCS7_bio(out,p7);
+	else if (outformat == FORMAT_PEM)
+		i=PEM_write_bio_PKCS7(out,p7);
+	else	{
+		BIO_printf(bio_err,"bad output format specified for outfile\n");
+		goto end;
+		}
+	if (!i)
+		{
+		BIO_printf(bio_err,"unable to write pkcs7 object\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+	ret=0;
+end:
+	if (in != NULL) BIO_free(in);
+	if (out != NULL) BIO_free_all(out);
+	if (p7 != NULL) PKCS7_free(p7);
+	if (crl != NULL) X509_CRL_free(crl);
+
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
+/*
+ *----------------------------------------------------------------------
+ * int add_certs_from_file
+ *
+ *	Read a list of certificates to be checked from a file.
+ *
+ * Results:
+ *	number of certs added if successful, -1 if not.
+ *----------------------------------------------------------------------
+ */
+static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile)
+	{
+	BIO *in=NULL;
+	int count=0;
+	int ret= -1;
+	STACK_OF(X509_INFO) *sk=NULL;
+	X509_INFO *xi;
+
+	in=BIO_new(BIO_s_file());
+	if ((in == NULL) || (BIO_read_filename(in,certfile) <= 0))
+		{
+		BIO_printf(bio_err,"error opening the file, %s\n",certfile);
+		goto end;
+		}
+
+	/* This loads from a file, a stack of x509/crl/pkey sets */
+	sk=PEM_X509_INFO_read_bio(in,NULL,NULL,NULL);
+	if (sk == NULL) {
+		BIO_printf(bio_err,"error reading the file, %s\n",certfile);
+		goto end;
+	}
+
+	/* scan over it and pull out the CRL's */
+	while (sk_X509_INFO_num(sk))
+		{
+		xi=sk_X509_INFO_shift(sk);
+		if (xi->x509 != NULL)
+			{
+			sk_X509_push(stack,xi->x509);
+			xi->x509=NULL;
+			count++;
+			}
+		X509_INFO_free(xi);
+		}
+
+	ret=count;
+end:
+ 	/* never need to OPENSSL_free x */
+	if (in != NULL) BIO_free(in);
+	if (sk != NULL) sk_X509_INFO_free(sk);
+	return(ret);
+	}
+
diff --git a/openssl/apps/demoCA/cacert.pem b/openssl/apps/demoCA/cacert.pem
new file mode 100644
index 0000000..affbce3
--- /dev/null
+++ b/openssl/apps/demoCA/cacert.pem
@@ -0,0 +1,14 @@
+subject=/C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
+issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
+-----BEGIN X509 CERTIFICATE-----
+
+MIIBgjCCASwCAQQwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV
+BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MTAwOTIz
+MzIwNVoXDTk4MDcwNTIzMzIwNVowYDELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM
+RDEZMBcGA1UEChMQTWluY29tIFB0eS4gTHRkLjELMAkGA1UECxMCQ1MxGzAZBgNV
+BAMTElNTTGVheSBkZW1vIHNlcnZlcjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3
+LCXcScWua0PFLkHBLm2VejqpA1F4RQ8q0VjRiPafjx/Z/aWH3ipdMVvuJGa/wFXb
+/nDFLDlfWp+oCPwhBtVPAgMBAAEwDQYJKoZIhvcNAQEEBQADQQArNFsihWIjBzb0
+DCsU0BvL2bvSwJrPEqFlkDq3F4M6EGutL9axEcANWgbbEdAvNJD1dmEmoWny27Pn
+IMs6ZOZB
+-----END X509 CERTIFICATE-----
diff --git a/openssl/apps/demoCA/index.txt b/openssl/apps/demoCA/index.txt
new file mode 100644
index 0000000..2cdd252
--- /dev/null
+++ b/openssl/apps/demoCA/index.txt
@@ -0,0 +1,39 @@
+R	980705233205Z	951009233205Z	01	certs/00000001	/CN=Eric Young
+E	951009233205Z		02	certs/00000002	/CN=Duncan Young
+R	980705233205Z	951201010000Z	03	certs/00000003	/CN=Tim Hudson
+V	980705233205Z		04	certs/00000004	/CN=Eric Young4
+V	980705233205Z		05	certs/00000004	/CN=Eric Young5
+V	980705233205Z		06	certs/00000004	/CN=Eric Young6
+V	980705233205Z		07	certs/00000004	/CN=Eric Young7
+V	980705233205Z		08	certs/00000004	/CN=Eric Young8
+V	980705233205Z		09	certs/00000004	/CN=Eric Young9
+V	980705233205Z		0A	certs/00000004	/CN=Eric YoungA
+V	980705233205Z		0B	certs/00000004	/CN=Eric YoungB
+V	980705233205Z		0C	certs/00000004	/CN=Eric YoungC
+V	980705233205Z		0D	certs/00000004	/CN=Eric YoungD
+V	980705233205Z		0E	certs/00000004	/CN=Eric YoungE
+V	980705233205Z		0F	certs/00000004	/CN=Eric YoungF
+V	980705233205Z		10	certs/00000004	/CN=Eric Young10
+V	980705233205Z		11	certs/00000004	/CN=Eric Young11
+V	980705233205Z		12	certs/00000004	/CN=Eric Young12
+V	980705233205Z		13	certs/00000004	/CN=Eric Young13
+V	980705233205Z		14	certs/00000004	/CN=Eric Young14
+V	980705233205Z		15	certs/00000004	/CN=Eric Young15
+V	980705233205Z		16	certs/00000004	/CN=Eric Young16
+V	980705233205Z		17	certs/00000004	/CN=Eric Young17
+V	961206150305Z		010C	unknown	/C=AU/SP=QLD/O=Mincom Pty. Ltd./OU=MTR/CN=Eric Young/Email=eay@mincom.oz.au
+V	961206153245Z		010D	unknown	/C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=Eric Young/Email=eay@mincom.oz.au
+V	970322074816Z		010E	unknown	/CN=Eric Young/Email=eay@mincom.oz.au
+V	970322075152Z		010F	unknown	/CN=Eric Young
+V	970322075906Z		0110	unknown	/CN=Eric Youngg
+V	970324092238Z		0111	unknown	/C=AU/SP=Queensland/CN=Eric Young
+V	970324221931Z		0112	unknown	/CN=Fred
+V	970324224934Z		0113	unknown	/C=AU/CN=eay
+V	971001005237Z		0114	unknown	/C=AU/SP=QLD/O=Mincom Pty Ltd/OU=MTR/CN=x509v3 test
+V	971001010331Z		0115	unknown	/C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=test again - x509v3
+V	971001013945Z		0117	unknown	/C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=x509v3 test
+V	971014225415Z		0118	unknown	/C=AU/SP=Queensland/CN=test
+V	971015004448Z		0119	unknown	/C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=test2
+V	971016035001Z		011A	unknown	/C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=test64
+V	971016080129Z		011B	unknown	/C=FR/O=ALCATEL/OU=Alcatel Mobile Phones/CN=bourque/Email=bourque@art.alcatel.fr
+V	971016224000Z		011D	unknown	/L=Bedford/O=Cranfield University/OU=Computer Centre/CN=Peter R Lister/Email=P.Lister@cranfield.ac.uk
diff --git a/openssl/apps/demoCA/private/cakey.pem b/openssl/apps/demoCA/private/cakey.pem
new file mode 100644
index 0000000..48fb18c
--- /dev/null
+++ b/openssl/apps/demoCA/private/cakey.pem
@@ -0,0 +1,24 @@
+issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
+subject=/C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
+-----BEGIN X509 CERTIFICATE-----
+
+MIIBgjCCASwCAQQwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV
+BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MTAwOTIz
+MzIwNVoXDTk4MDcwNTIzMzIwNVowYDELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM
+RDEZMBcGA1UEChMQTWluY29tIFB0eS4gTHRkLjELMAkGA1UECxMCQ1MxGzAZBgNV
+BAMTElNTTGVheSBkZW1vIHNlcnZlcjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3
+LCXcScWua0PFLkHBLm2VejqpA1F4RQ8q0VjRiPafjx/Z/aWH3ipdMVvuJGa/wFXb
+/nDFLDlfWp+oCPwhBtVPAgMBAAEwDQYJKoZIhvcNAQEEBQADQQArNFsihWIjBzb0
+DCsU0BvL2bvSwJrPEqFlkDq3F4M6EGutL9axEcANWgbbEdAvNJD1dmEmoWny27Pn
+IMs6ZOZB
+-----END X509 CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+
+MIIBPAIBAAJBALcsJdxJxa5rQ8UuQcEubZV6OqkDUXhFDyrRWNGI9p+PH9n9pYfe
+Kl0xW+4kZr/AVdv+cMUsOV9an6gI/CEG1U8CAwEAAQJAXJMBZ34ZXHd1vtgL/3hZ
+hexKbVTx/djZO4imXO/dxPGRzG2ylYZpHmG32/T1kaHpZlCHoEPgHoSzmxYXfxjG
+sQIhAPmZ/bQOjmRUHM/VM2X5zrjjM6z18R1P6l3ObFwt9FGdAiEAu943Yh9SqMRw
+tL0xHGxKmM/YJueUw1gB6sLkETN71NsCIQCeT3RhoqXfrpXDoEcEU+gwzjI1bpxq
+agiNTOLfqGoA5QIhAIQFYjgzONxex7FLrsKBm16N2SFl5pXsN9SpRqqL2n63AiEA
+g9VNIQ3xwpw7og3IbONifeku+J9qGMGQJMKwSTwrFtI=
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/apps/demoCA/serial b/openssl/apps/demoCA/serial
new file mode 100644
index 0000000..69fa0ff
--- /dev/null
+++ b/openssl/apps/demoCA/serial
@@ -0,0 +1 @@
+011E
diff --git a/openssl/apps/dgst.c b/openssl/apps/dgst.c
new file mode 100644
index 0000000..9bf38ce
--- /dev/null
+++ b/openssl/apps/dgst.c
@@ -0,0 +1,632 @@
+/* apps/dgst.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/hmac.h>
+
+#undef BUFSIZE
+#define BUFSIZE	1024*8
+
+#undef PROG
+#define PROG	dgst_main
+
+int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
+	  EVP_PKEY *key, unsigned char *sigin, int siglen,
+	  const char *sig_name, const char *md_name,
+	  const char *file,BIO *bmd);
+
+static void list_md_fn(const EVP_MD *m,
+			const char *from, const char *to, void *arg)
+	{
+	const char *mname;
+	/* Skip aliases */
+	if (!m)
+		return;
+	mname = OBJ_nid2ln(EVP_MD_type(m));
+	/* Skip shortnames */
+	if (strcmp(from, mname))
+		return;
+	/* Skip clones */
+	if (EVP_MD_flags(m) & EVP_MD_FLAG_PKEY_DIGEST)
+		return;
+	if (strchr(mname, ' '))
+		mname= EVP_MD_name(m);
+	BIO_printf(arg, "-%-14s to use the %s message digest algorithm\n",
+			mname, mname);
+	}
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	ENGINE *e = NULL;
+	unsigned char *buf=NULL;
+	int i,err=1;
+	const EVP_MD *md=NULL,*m;
+	BIO *in=NULL,*inp;
+	BIO *bmd=NULL;
+	BIO *out = NULL;
+#define PROG_NAME_SIZE  39
+	char pname[PROG_NAME_SIZE+1];
+	int separator=0;
+	int debug=0;
+	int keyform=FORMAT_PEM;
+	const char *outfile = NULL, *keyfile = NULL;
+	const char *sigfile = NULL, *randfile = NULL;
+	int out_bin = -1, want_pub = 0, do_verify = 0;
+	EVP_PKEY *sigkey = NULL;
+	unsigned char *sigbuf = NULL;
+	int siglen = 0;
+	char *passargin = NULL, *passin = NULL;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+	char *hmac_key=NULL;
+	char *mac_name=NULL;
+	STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL;
+
+	apps_startup();
+
+	if ((buf=(unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL)
+		{
+		BIO_printf(bio_err,"out of memory\n");
+		goto end;
+		}
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	/* first check the program name */
+	program_name(argv[0],pname,sizeof pname);
+
+	md=EVP_get_digestbyname(pname);
+
+	argc--;
+	argv++;
+	while (argc > 0)
+		{
+		if ((*argv)[0] != '-') break;
+		if (strcmp(*argv,"-c") == 0)
+			separator=1;
+		else if (strcmp(*argv,"-r") == 0)
+			separator=2;
+		else if (strcmp(*argv,"-rand") == 0)
+			{
+			if (--argc < 1) break;
+			randfile=*(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) break;
+			outfile=*(++argv);
+			}
+		else if (strcmp(*argv,"-sign") == 0)
+			{
+			if (--argc < 1) break;
+			keyfile=*(++argv);
+			}
+		else if (!strcmp(*argv,"-passin"))
+			{
+			if (--argc < 1)
+				break;
+			passargin=*++argv;
+			}
+		else if (strcmp(*argv,"-verify") == 0)
+			{
+			if (--argc < 1) break;
+			keyfile=*(++argv);
+			want_pub = 1;
+			do_verify = 1;
+			}
+		else if (strcmp(*argv,"-prverify") == 0)
+			{
+			if (--argc < 1) break;
+			keyfile=*(++argv);
+			do_verify = 1;
+			}
+		else if (strcmp(*argv,"-signature") == 0)
+			{
+			if (--argc < 1) break;
+			sigfile=*(++argv);
+			}
+		else if (strcmp(*argv,"-keyform") == 0)
+			{
+			if (--argc < 1) break;
+			keyform=str2fmt(*(++argv));
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*argv,"-engine") == 0)
+			{
+			if (--argc < 1) break;
+			engine= *(++argv);
+        		e = setup_engine(bio_err, engine, 0);
+			}
+#endif
+		else if (strcmp(*argv,"-hex") == 0)
+			out_bin = 0;
+		else if (strcmp(*argv,"-binary") == 0)
+			out_bin = 1;
+		else if (strcmp(*argv,"-d") == 0)
+			debug=1;
+		else if (!strcmp(*argv,"-hmac"))
+			{
+			if (--argc < 1)
+				break;
+			hmac_key=*++argv;
+			}
+		else if (!strcmp(*argv,"-mac"))
+			{
+			if (--argc < 1)
+				break;
+			mac_name=*++argv;
+			}
+		else if (strcmp(*argv,"-sigopt") == 0)
+			{
+			if (--argc < 1)
+				break;
+			if (!sigopts)
+				sigopts = sk_OPENSSL_STRING_new_null();
+			if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
+				break;
+			}
+		else if (strcmp(*argv,"-macopt") == 0)
+			{
+			if (--argc < 1)
+				break;
+			if (!macopts)
+				macopts = sk_OPENSSL_STRING_new_null();
+			if (!macopts || !sk_OPENSSL_STRING_push(macopts, *(++argv)))
+				break;
+			}
+		else if ((m=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
+			md=m;
+		else
+			break;
+		argc--;
+		argv++;
+		}
+
+
+	if(do_verify && !sigfile) {
+		BIO_printf(bio_err, "No signature to verify: use the -signature option\n");
+		goto end;
+	}
+
+	if ((argc > 0) && (argv[0][0] == '-')) /* bad option */
+		{
+		BIO_printf(bio_err,"unknown option '%s'\n",*argv);
+		BIO_printf(bio_err,"options are\n");
+		BIO_printf(bio_err,"-c              to output the digest with separating colons\n");
+		BIO_printf(bio_err,"-r              to output the digest in coreutils format\n");
+		BIO_printf(bio_err,"-d              to output debug info\n");
+		BIO_printf(bio_err,"-hex            output as hex dump\n");
+		BIO_printf(bio_err,"-binary         output in binary form\n");
+		BIO_printf(bio_err,"-sign   file    sign digest using private key in file\n");
+		BIO_printf(bio_err,"-verify file    verify a signature using public key in file\n");
+		BIO_printf(bio_err,"-prverify file  verify a signature using private key in file\n");
+		BIO_printf(bio_err,"-keyform arg    key file format (PEM or ENGINE)\n");
+		BIO_printf(bio_err,"-out filename   output to filename rather than stdout\n");
+		BIO_printf(bio_err,"-signature file signature to verify\n");
+		BIO_printf(bio_err,"-sigopt nm:v    signature parameter\n");
+		BIO_printf(bio_err,"-hmac key       create hashed MAC with key\n");
+		BIO_printf(bio_err,"-mac algorithm  create MAC (not neccessarily HMAC)\n"); 
+		BIO_printf(bio_err,"-macopt nm:v    MAC algorithm parameters or key\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err,"-engine e       use engine e, possibly a hardware device.\n");
+#endif
+
+		EVP_MD_do_all_sorted(list_md_fn, bio_err);
+		goto end;
+		}
+
+	in=BIO_new(BIO_s_file());
+	bmd=BIO_new(BIO_f_md());
+	if (debug)
+		{
+		BIO_set_callback(in,BIO_debug_callback);
+		/* needed for windows 3.1 */
+		BIO_set_callback_arg(in,(char *)bio_err);
+		}
+
+	if(!app_passwd(bio_err, passargin, NULL, &passin, NULL))
+		{
+		BIO_printf(bio_err, "Error getting password\n");
+		goto end;
+		}
+
+	if ((in == NULL) || (bmd == NULL))
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if(out_bin == -1) {
+		if(keyfile)
+			out_bin = 1;
+		else
+			out_bin = 0;
+	}
+
+	if(randfile)
+		app_RAND_load_file(randfile, bio_err, 0);
+
+	if(outfile) {
+		if(out_bin)
+			out = BIO_new_file(outfile, "wb");
+		else    out = BIO_new_file(outfile, "w");
+	} else {
+		out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+	}
+
+	if(!out) {
+		BIO_printf(bio_err, "Error opening output file %s\n", 
+					outfile ? outfile : "(stdout)");
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+	if ((!!mac_name + !!keyfile + !!hmac_key) > 1)
+		{
+		BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n");
+		goto end;
+		}
+
+	if(keyfile)
+		{
+		if (want_pub)
+			sigkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL,
+				e, "key file");
+		else
+			sigkey = load_key(bio_err, keyfile, keyform, 0, passin,
+				e, "key file");
+		if (!sigkey)
+			{
+			/* load_[pub]key() has already printed an appropriate
+			   message */
+			goto end;
+			}
+		}
+
+	if (mac_name)
+		{
+		EVP_PKEY_CTX *mac_ctx = NULL;
+		int r = 0;
+		if (!init_gen_str(bio_err, &mac_ctx, mac_name,e, 0))
+			goto mac_end;
+		if (macopts)
+			{
+			char *macopt;
+			for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++)
+				{
+				macopt = sk_OPENSSL_STRING_value(macopts, i);
+				if (pkey_ctrl_string(mac_ctx, macopt) <= 0)
+					{
+					BIO_printf(bio_err,
+						"MAC parameter error \"%s\"\n",
+						macopt);
+					ERR_print_errors(bio_err);
+					goto mac_end;
+					}
+				}
+			}
+		if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0)
+			{
+			BIO_puts(bio_err, "Error generating key\n");
+			ERR_print_errors(bio_err);
+			goto mac_end;
+			}
+		r = 1;
+		mac_end:
+		if (mac_ctx)
+			EVP_PKEY_CTX_free(mac_ctx);
+		if (r == 0)
+			goto end;
+		}
+
+	if (hmac_key)
+		{
+		sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, e,
+					(unsigned char *)hmac_key, -1);
+		if (!sigkey)
+			goto end;
+		}
+
+	if (sigkey)
+		{
+		EVP_MD_CTX *mctx = NULL;
+		EVP_PKEY_CTX *pctx = NULL;
+		int r;
+		if (!BIO_get_md_ctx(bmd, &mctx))
+			{
+			BIO_printf(bio_err, "Error getting context\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		if (do_verify)
+			r = EVP_DigestVerifyInit(mctx, &pctx, md, e, sigkey);
+		else
+			r = EVP_DigestSignInit(mctx, &pctx, md, e, sigkey);
+		if (!r)
+			{
+			BIO_printf(bio_err, "Error setting context\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		if (sigopts)
+			{
+			char *sigopt;
+			for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++)
+				{
+				sigopt = sk_OPENSSL_STRING_value(sigopts, i);
+				if (pkey_ctrl_string(pctx, sigopt) <= 0)
+					{
+					BIO_printf(bio_err,
+						"parameter error \"%s\"\n",
+						sigopt);
+					ERR_print_errors(bio_err);
+					goto end;
+					}
+				}
+			}
+		}
+	/* we use md as a filter, reading from 'in' */
+	else
+		{
+		if (md == NULL)
+			md = EVP_md5(); 
+		if (!BIO_set_md(bmd,md))
+			{
+			BIO_printf(bio_err, "Error setting digest %s\n", pname);
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+
+	if(sigfile && sigkey) {
+		BIO *sigbio;
+		sigbio = BIO_new_file(sigfile, "rb");
+		siglen = EVP_PKEY_size(sigkey);
+		sigbuf = OPENSSL_malloc(siglen);
+		if(!sigbio) {
+			BIO_printf(bio_err, "Error opening signature file %s\n",
+								sigfile);
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+		siglen = BIO_read(sigbio, sigbuf, siglen);
+		BIO_free(sigbio);
+		if(siglen <= 0) {
+			BIO_printf(bio_err, "Error reading signature file %s\n",
+								sigfile);
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+	}
+	inp=BIO_push(bmd,in);
+
+	if (md == NULL)
+		{
+		EVP_MD_CTX *tctx;
+		BIO_get_md_ctx(bmd, &tctx);
+		md = EVP_MD_CTX_md(tctx);
+		}
+
+	if (argc == 0)
+		{
+		BIO_set_fp(in,stdin,BIO_NOCLOSE);
+		err=do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf,
+			  siglen,NULL,NULL,"stdin",bmd);
+		}
+	else
+		{
+		const char *md_name = NULL, *sig_name = NULL;
+		if(!out_bin)
+			{
+			if (sigkey)
+				{
+				const EVP_PKEY_ASN1_METHOD *ameth;
+				ameth = EVP_PKEY_get0_asn1(sigkey);
+				if (ameth)
+					EVP_PKEY_asn1_get0_info(NULL, NULL,
+						NULL, NULL, &sig_name, ameth);
+				}
+			md_name = EVP_MD_name(md);
+			}
+		err = 0;
+		for (i=0; i<argc; i++)
+			{
+			int r;
+			if (BIO_read_filename(in,argv[i]) <= 0)
+				{
+				perror(argv[i]);
+				err++;
+				continue;
+				}
+			else
+			r=do_fp(out,buf,inp,separator,out_bin,sigkey,sigbuf,
+				siglen,sig_name,md_name, argv[i],bmd);
+			if(r)
+			    err=r;
+			(void)BIO_reset(bmd);
+			}
+		}
+end:
+	if (buf != NULL)
+		{
+		OPENSSL_cleanse(buf,BUFSIZE);
+		OPENSSL_free(buf);
+		}
+	if (in != NULL) BIO_free(in);
+	if (passin)
+		OPENSSL_free(passin);
+	BIO_free_all(out);
+	EVP_PKEY_free(sigkey);
+	if (sigopts)
+		sk_OPENSSL_STRING_free(sigopts);
+	if (macopts)
+		sk_OPENSSL_STRING_free(macopts);
+	if(sigbuf) OPENSSL_free(sigbuf);
+	if (bmd != NULL) BIO_free(bmd);
+	apps_shutdown();
+	OPENSSL_EXIT(err);
+	}
+
+int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
+	  EVP_PKEY *key, unsigned char *sigin, int siglen,
+	  const char *sig_name, const char *md_name,
+	  const char *file,BIO *bmd)
+	{
+	size_t len;
+	int i;
+
+	for (;;)
+		{
+		i=BIO_read(bp,(char *)buf,BUFSIZE);
+		if(i < 0)
+			{
+			BIO_printf(bio_err, "Read Error in %s\n",file);
+			ERR_print_errors(bio_err);
+			return 1;
+			}
+		if (i == 0) break;
+		}
+	if(sigin)
+		{
+		EVP_MD_CTX *ctx;
+		BIO_get_md_ctx(bp, &ctx);
+		i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int)siglen); 
+		if(i > 0)
+			BIO_printf(out, "Verified OK\n");
+		else if(i == 0)
+			{
+			BIO_printf(out, "Verification Failure\n");
+			return 1;
+			}
+		else
+			{
+			BIO_printf(bio_err, "Error Verifying Data\n");
+			ERR_print_errors(bio_err);
+			return 1;
+			}
+		return 0;
+		}
+	if(key)
+		{
+		EVP_MD_CTX *ctx;
+		BIO_get_md_ctx(bp, &ctx);
+		len = BUFSIZE;
+		if(!EVP_DigestSignFinal(ctx, buf, &len)) 
+			{
+			BIO_printf(bio_err, "Error Signing Data\n");
+			ERR_print_errors(bio_err);
+			return 1;
+			}
+		}
+	else
+		{
+		len=BIO_gets(bp,(char *)buf,BUFSIZE);
+		if ((int)len <0)
+			{
+			ERR_print_errors(bio_err);
+			return 1;
+			}
+		}
+
+	if(binout) BIO_write(out, buf, len);
+	else if (sep == 2)
+		{
+		for (i=0; i<(int)len; i++)
+			BIO_printf(out, "%02x",buf[i]);
+		BIO_printf(out, " *%s\n", file);
+		}
+	else 
+		{
+		if (sig_name)
+			BIO_printf(out, "%s-%s(%s)= ", sig_name, md_name, file);
+		else if (md_name)
+			BIO_printf(out, "%s(%s)= ", md_name, file);
+		else
+			BIO_printf(out, "(%s)= ", file);
+		for (i=0; i<(int)len; i++)
+			{
+			if (sep && (i != 0))
+				BIO_printf(out, ":");
+			BIO_printf(out, "%02x",buf[i]);
+			}
+		BIO_printf(out, "\n");
+		}
+	return 0;
+	}
+
diff --git a/openssl/apps/dh.c b/openssl/apps/dh.c
new file mode 100644
index 0000000..dee9c01
--- /dev/null
+++ b/openssl/apps/dh.c
@@ -0,0 +1,355 @@
+/* apps/dh.c */
+/* obsoleted by dhparam.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/opensslconf.h>	/* for OPENSSL_NO_DH */
+#ifndef OPENSSL_NO_DH
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+#undef PROG
+#define PROG	dh_main
+
+/* -inform arg	- input format - default PEM (DER or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg	- input file - default stdin
+ * -out arg	- output file - default stdout
+ * -check	- check the parameters are ok
+ * -noout
+ * -text
+ * -C
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	DH *dh=NULL;
+	int i,badops=0,text=0;
+	BIO *in=NULL,*out=NULL;
+	int informat,outformat,check=0,noout=0,C=0,ret=1;
+	char *infile,*outfile,*prog;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine;
+#endif
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+#ifndef OPENSSL_NO_ENGINE
+	engine=NULL;
+#endif
+	infile=NULL;
+	outfile=NULL;
+	informat=FORMAT_PEM;
+	outformat=FORMAT_PEM;
+
+	prog=argv[0];
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if 	(strcmp(*argv,"-inform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			informat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-outform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outformat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*argv,"-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine= *(++argv);
+			}
+#endif
+		else if (strcmp(*argv,"-check") == 0)
+			check=1;
+		else if (strcmp(*argv,"-text") == 0)
+			text=1;
+		else if (strcmp(*argv,"-C") == 0)
+			C=1;
+		else if (strcmp(*argv,"-noout") == 0)
+			noout=1;
+		else
+			{
+			BIO_printf(bio_err,"unknown option %s\n",*argv);
+			badops=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (badops)
+		{
+bad:
+		BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
+		BIO_printf(bio_err,"where options are\n");
+		BIO_printf(bio_err," -inform arg   input format - one of DER PEM\n");
+		BIO_printf(bio_err," -outform arg  output format - one of DER PEM\n");
+		BIO_printf(bio_err," -in arg       input file\n");
+		BIO_printf(bio_err," -out arg      output file\n");
+		BIO_printf(bio_err," -check        check the DH parameters\n");
+		BIO_printf(bio_err," -text         print a text form of the DH parameters\n");
+		BIO_printf(bio_err," -C            Output C code\n");
+		BIO_printf(bio_err," -noout        no output\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err," -engine e     use engine e, possibly a hardware device.\n");
+#endif
+		goto end;
+		}
+
+	ERR_load_crypto_strings();
+
+#ifndef OPENSSL_NO_ENGINE
+        setup_engine(bio_err, engine, 0);
+#endif
+
+	in=BIO_new(BIO_s_file());
+	out=BIO_new(BIO_s_file());
+	if ((in == NULL) || (out == NULL))
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (infile == NULL)
+		BIO_set_fp(in,stdin,BIO_NOCLOSE);
+	else
+		{
+		if (BIO_read_filename(in,infile) <= 0)
+			{
+			perror(infile);
+			goto end;
+			}
+		}
+	if (outfile == NULL)
+		{
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+		}
+	else
+		{
+		if (BIO_write_filename(out,outfile) <= 0)
+			{
+			perror(outfile);
+			goto end;
+			}
+		}
+
+	if	(informat == FORMAT_ASN1)
+		dh=d2i_DHparams_bio(in,NULL);
+	else if (informat == FORMAT_PEM)
+		dh=PEM_read_bio_DHparams(in,NULL,NULL,NULL);
+	else
+		{
+		BIO_printf(bio_err,"bad input format specified\n");
+		goto end;
+		}
+	if (dh == NULL)
+		{
+		BIO_printf(bio_err,"unable to load DH parameters\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	
+
+	if (text)
+		{
+		DHparams_print(out,dh);
+#ifdef undef
+		printf("p=");
+		BN_print(stdout,dh->p);
+		printf("\ng=");
+		BN_print(stdout,dh->g);
+		printf("\n");
+		if (dh->length != 0)
+			printf("recommended private length=%ld\n",dh->length);
+#endif
+		}
+	
+	if (check)
+		{
+		if (!DH_check(dh,&i))
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		if (i & DH_CHECK_P_NOT_PRIME)
+			printf("p value is not prime\n");
+		if (i & DH_CHECK_P_NOT_SAFE_PRIME)
+			printf("p value is not a safe prime\n");
+		if (i & DH_UNABLE_TO_CHECK_GENERATOR)
+			printf("unable to check the generator value\n");
+		if (i & DH_NOT_SUITABLE_GENERATOR)
+			printf("the g value is not a generator\n");
+		if (i == 0)
+			printf("DH parameters appear to be ok.\n");
+		}
+	if (C)
+		{
+		unsigned char *data;
+		int len,l,bits;
+
+		len=BN_num_bytes(dh->p);
+		bits=BN_num_bits(dh->p);
+		data=(unsigned char *)OPENSSL_malloc(len);
+		if (data == NULL)
+			{
+			perror("OPENSSL_malloc");
+			goto end;
+			}
+		l=BN_bn2bin(dh->p,data);
+		printf("static unsigned char dh%d_p[]={",bits);
+		for (i=0; i<l; i++)
+			{
+			if ((i%12) == 0) printf("\n\t");
+			printf("0x%02X,",data[i]);
+			}
+		printf("\n\t};\n");
+
+		l=BN_bn2bin(dh->g,data);
+		printf("static unsigned char dh%d_g[]={",bits);
+		for (i=0; i<l; i++)
+			{
+			if ((i%12) == 0) printf("\n\t");
+			printf("0x%02X,",data[i]);
+			}
+		printf("\n\t};\n\n");
+
+		printf("DH *get_dh%d()\n\t{\n",bits);
+		printf("\tDH *dh;\n\n");
+		printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n");
+		printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n",
+			bits,bits);
+		printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n",
+			bits,bits);
+		printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n");
+		printf("\t\treturn(NULL);\n");
+		printf("\treturn(dh);\n\t}\n");
+		OPENSSL_free(data);
+		}
+
+
+	if (!noout)
+		{
+		if 	(outformat == FORMAT_ASN1)
+			i=i2d_DHparams_bio(out,dh);
+		else if (outformat == FORMAT_PEM)
+			i=PEM_write_bio_DHparams(out,dh);
+		else	{
+			BIO_printf(bio_err,"bad output format specified for outfile\n");
+			goto end;
+			}
+		if (!i)
+			{
+			BIO_printf(bio_err,"unable to write DH parameters\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+	ret=0;
+end:
+	if (in != NULL) BIO_free(in);
+	if (out != NULL) BIO_free_all(out);
+	if (dh != NULL) DH_free(dh);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+#else /* !OPENSSL_NO_DH */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/apps/dh1024.pem b/openssl/apps/dh1024.pem
new file mode 100644
index 0000000..6eaeca9
--- /dev/null
+++ b/openssl/apps/dh1024.pem
@@ -0,0 +1,10 @@
+-----BEGIN DH PARAMETERS-----
+MIGHAoGBAPSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsY
+jY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6
+ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpL3jHAgEC
+-----END DH PARAMETERS-----
+
+These are the 1024 bit DH parameters from "Assigned Number for SKIP Protocols"
+(http://www.skip-vpn.org/spec/numbers.html).
+See there for how they were generated.
+Note that g is not a generator, but this is not a problem since p is a safe prime.
diff --git a/openssl/apps/dh2048.pem b/openssl/apps/dh2048.pem
new file mode 100644
index 0000000..dcd0b8d
--- /dev/null
+++ b/openssl/apps/dh2048.pem
@@ -0,0 +1,12 @@
+-----BEGIN DH PARAMETERS-----
+MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV
+89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50
+T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb
+zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX
+Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT
+CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg==
+-----END DH PARAMETERS-----
+
+These are the 2048 bit DH parameters from "Assigned Number for SKIP Protocols"
+(http://www.skip-vpn.org/spec/numbers.html).
+See there for how they were generated.
diff --git a/openssl/apps/dh4096.pem b/openssl/apps/dh4096.pem
new file mode 100644
index 0000000..1b35ad8
--- /dev/null
+++ b/openssl/apps/dh4096.pem
@@ -0,0 +1,18 @@
+-----BEGIN DH PARAMETERS-----
+MIICCAKCAgEA+hRyUsFN4VpJ1O8JLcCo/VWr19k3BCgJ4uk+d+KhehjdRqNDNyOQ
+l/MOyQNQfWXPeGKmOmIig6Ev/nm6Nf9Z2B1h3R4hExf+zTiHnvVPeRBhjdQi81rt
+Xeoh6TNrSBIKIHfUJWBh3va0TxxjQIs6IZOLeVNRLMqzeylWqMf49HsIXqbcokUS
+Vt1BkvLdW48j8PPv5DsKRN3tloTxqDJGo9tKvj1Fuk74A+Xda1kNhB7KFlqMyN98
+VETEJ6c7KpfOo30mnK30wqw3S8OtaIR/maYX72tGOno2ehFDkq3pnPtEbD2CScxc
+alJC+EL7RPk5c/tgeTvCngvc1KZn92Y//EI7G9tPZtylj2b56sHtMftIoYJ9+ODM
+sccD5Piz/rejE3Ome8EOOceUSCYAhXn8b3qvxVI1ddd1pED6FHRhFvLrZxFvBEM9
+ERRMp5QqOaHJkM+Dxv8Cj6MqrCbfC4u+ZErxodzuusgDgvZiLF22uxMZbobFWyte
+OvOzKGtwcTqO/1wV5gKkzu1ZVswVUQd5Gg8lJicwqRWyyNRczDDoG9jVDxmogKTH
+AaqLulO7R8Ifa1SwF2DteSGVtgWEN8gDpN3RBmmPTDngyF2DHb5qmpnznwtFKdTL
+KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=
+-----END DH PARAMETERS-----
+
+These are the 4096 bit DH parameters from "Assigned Number for SKIP Protocols"
+(http://www.skip-vpn.org/spec/numbers.html).
+See there for how they were generated.
+Note that g is not a generator, but this is not a problem since p is a safe prime.
diff --git a/openssl/apps/dh512.pem b/openssl/apps/dh512.pem
new file mode 100644
index 0000000..200d16c
--- /dev/null
+++ b/openssl/apps/dh512.pem
@@ -0,0 +1,9 @@
+-----BEGIN DH PARAMETERS-----
+MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak
+XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC
+-----END DH PARAMETERS-----
+
+These are the 512 bit DH parameters from "Assigned Number for SKIP Protocols"
+(http://www.skip-vpn.org/spec/numbers.html).
+See there for how they were generated.
+Note that g is not a generator, but this is not a problem since p is a safe prime.
diff --git a/openssl/apps/dhparam.c b/openssl/apps/dhparam.c
new file mode 100644
index 0000000..b47097c
--- /dev/null
+++ b/openssl/apps/dhparam.c
@@ -0,0 +1,560 @@
+/* apps/dhparam.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/opensslconf.h>	/* for OPENSSL_NO_DH */
+#ifndef OPENSSL_NO_DH
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+
+#undef PROG
+#define PROG	dhparam_main
+
+#define DEFBITS	512
+
+/* -inform arg	- input format - default PEM (DER or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg	- input file - default stdin
+ * -out arg	- output file - default stdout
+ * -dsaparam  - read or generate DSA parameters, convert to DH
+ * -check	- check the parameters are ok
+ * -noout
+ * -text
+ * -C
+ */
+
+static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb);
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	DH *dh=NULL;
+	int i,badops=0,text=0;
+#ifndef OPENSSL_NO_DSA
+	int dsaparam=0;
+#endif
+	BIO *in=NULL,*out=NULL;
+	int informat,outformat,check=0,noout=0,C=0,ret=1;
+	char *infile,*outfile,*prog;
+	char *inrand=NULL;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+	int num = 0, g = 0;
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	infile=NULL;
+	outfile=NULL;
+	informat=FORMAT_PEM;
+	outformat=FORMAT_PEM;
+
+	prog=argv[0];
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if 	(strcmp(*argv,"-inform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			informat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-outform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outformat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*argv,"-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine= *(++argv);
+			}
+#endif
+		else if (strcmp(*argv,"-check") == 0)
+			check=1;
+		else if (strcmp(*argv,"-text") == 0)
+			text=1;
+#ifndef OPENSSL_NO_DSA
+		else if (strcmp(*argv,"-dsaparam") == 0)
+			dsaparam=1;
+#endif
+		else if (strcmp(*argv,"-C") == 0)
+			C=1;
+		else if (strcmp(*argv,"-noout") == 0)
+			noout=1;
+		else if (strcmp(*argv,"-2") == 0)
+			g=2;
+		else if (strcmp(*argv,"-5") == 0)
+			g=5;
+		else if (strcmp(*argv,"-rand") == 0)
+			{
+			if (--argc < 1) goto bad;
+			inrand= *(++argv);
+			}
+		else if (((sscanf(*argv,"%d",&num) == 0) || (num <= 0)))
+			goto bad;
+		argv++;
+		argc--;
+		}
+
+	if (badops)
+		{
+bad:
+		BIO_printf(bio_err,"%s [options] [numbits]\n",prog);
+		BIO_printf(bio_err,"where options are\n");
+		BIO_printf(bio_err," -inform arg   input format - one of DER PEM\n");
+		BIO_printf(bio_err," -outform arg  output format - one of DER PEM\n");
+		BIO_printf(bio_err," -in arg       input file\n");
+		BIO_printf(bio_err," -out arg      output file\n");
+#ifndef OPENSSL_NO_DSA
+		BIO_printf(bio_err," -dsaparam     read or generate DSA parameters, convert to DH\n");
+#endif
+		BIO_printf(bio_err," -check        check the DH parameters\n");
+		BIO_printf(bio_err," -text         print a text form of the DH parameters\n");
+		BIO_printf(bio_err," -C            Output C code\n");
+		BIO_printf(bio_err," -2            generate parameters using  2 as the generator value\n");
+		BIO_printf(bio_err," -5            generate parameters using  5 as the generator value\n");
+		BIO_printf(bio_err," numbits       number of bits in to generate (default 512)\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err," -engine e     use engine e, possibly a hardware device.\n");
+#endif
+		BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+		BIO_printf(bio_err,"               - load the file (or the files in the directory) into\n");
+		BIO_printf(bio_err,"               the random number generator\n");
+		BIO_printf(bio_err," -noout        no output\n");
+		goto end;
+		}
+
+	ERR_load_crypto_strings();
+
+#ifndef OPENSSL_NO_ENGINE
+        setup_engine(bio_err, engine, 0);
+#endif
+
+	if (g && !num)
+		num = DEFBITS;
+
+#ifndef OPENSSL_NO_DSA
+	if (dsaparam)
+		{
+		if (g)
+			{
+			BIO_printf(bio_err, "generator may not be chosen for DSA parameters\n");
+			goto end;
+			}
+		}
+	else
+#endif
+		{
+		/* DH parameters */
+		if (num && !g)
+			g = 2;
+		}
+
+	if(num) {
+
+		BN_GENCB cb;
+		BN_GENCB_set(&cb, dh_cb, bio_err);
+		if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL)
+			{
+			BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
+			}
+		if (inrand != NULL)
+			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+				app_RAND_load_files(inrand));
+
+#ifndef OPENSSL_NO_DSA
+		if (dsaparam)
+			{
+			DSA *dsa = DSA_new();
+			
+			BIO_printf(bio_err,"Generating DSA parameters, %d bit long prime\n",num);
+			if(!dsa || !DSA_generate_parameters_ex(dsa, num,
+						NULL, 0, NULL, NULL, &cb))
+				{
+				if(dsa) DSA_free(dsa);
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+
+			dh = DSA_dup_DH(dsa);
+			DSA_free(dsa);
+			if (dh == NULL)
+				{
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+			}
+		else
+#endif
+			{
+			dh = DH_new();
+			BIO_printf(bio_err,"Generating DH parameters, %d bit long safe prime, generator %d\n",num,g);
+			BIO_printf(bio_err,"This is going to take a long time\n");
+			if(!dh || !DH_generate_parameters_ex(dh, num, g, &cb))
+				{
+				if(dh) DH_free(dh);
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+			}
+
+		app_RAND_write_file(NULL, bio_err);
+	} else {
+
+		in=BIO_new(BIO_s_file());
+		if (in == NULL)
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		if (infile == NULL)
+			BIO_set_fp(in,stdin,BIO_NOCLOSE);
+		else
+			{
+			if (BIO_read_filename(in,infile) <= 0)
+				{
+				perror(infile);
+				goto end;
+				}
+			}
+
+		if	(informat != FORMAT_ASN1 && informat != FORMAT_PEM)
+			{
+			BIO_printf(bio_err,"bad input format specified\n");
+			goto end;
+			}
+
+#ifndef OPENSSL_NO_DSA
+		if (dsaparam)
+			{
+			DSA *dsa;
+			
+			if (informat == FORMAT_ASN1)
+				dsa=d2i_DSAparams_bio(in,NULL);
+			else /* informat == FORMAT_PEM */
+				dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL);
+			
+			if (dsa == NULL)
+				{
+				BIO_printf(bio_err,"unable to load DSA parameters\n");
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+			
+			dh = DSA_dup_DH(dsa);
+			DSA_free(dsa);
+			if (dh == NULL)
+				{
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+			}
+		else
+#endif
+			{
+			if (informat == FORMAT_ASN1)
+				dh=d2i_DHparams_bio(in,NULL);
+			else /* informat == FORMAT_PEM */
+				dh=PEM_read_bio_DHparams(in,NULL,NULL,NULL);
+			
+			if (dh == NULL)
+				{
+				BIO_printf(bio_err,"unable to load DH parameters\n");
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+			}
+		
+		/* dh != NULL */
+	}
+	
+	out=BIO_new(BIO_s_file());
+	if (out == NULL)
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+	if (outfile == NULL)
+		{
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+		}
+	else
+		{
+		if (BIO_write_filename(out,outfile) <= 0)
+			{
+			perror(outfile);
+			goto end;
+			}
+		}
+
+
+	if (text)
+		{
+		DHparams_print(out,dh);
+		}
+	
+	if (check)
+		{
+		if (!DH_check(dh,&i))
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		if (i & DH_CHECK_P_NOT_PRIME)
+			printf("p value is not prime\n");
+		if (i & DH_CHECK_P_NOT_SAFE_PRIME)
+			printf("p value is not a safe prime\n");
+		if (i & DH_UNABLE_TO_CHECK_GENERATOR)
+			printf("unable to check the generator value\n");
+		if (i & DH_NOT_SUITABLE_GENERATOR)
+			printf("the g value is not a generator\n");
+		if (i == 0)
+			printf("DH parameters appear to be ok.\n");
+		}
+	if (C)
+		{
+		unsigned char *data;
+		int len,l,bits;
+
+		len=BN_num_bytes(dh->p);
+		bits=BN_num_bits(dh->p);
+		data=(unsigned char *)OPENSSL_malloc(len);
+		if (data == NULL)
+			{
+			perror("OPENSSL_malloc");
+			goto end;
+			}
+		printf("#ifndef HEADER_DH_H\n"
+		       "#include <openssl/dh.h>\n"
+		       "#endif\n");
+		printf("DH *get_dh%d()\n\t{\n",bits);
+
+		l=BN_bn2bin(dh->p,data);
+		printf("\tstatic unsigned char dh%d_p[]={",bits);
+		for (i=0; i<l; i++)
+			{
+			if ((i%12) == 0) printf("\n\t\t");
+			printf("0x%02X,",data[i]);
+			}
+		printf("\n\t\t};\n");
+
+		l=BN_bn2bin(dh->g,data);
+		printf("\tstatic unsigned char dh%d_g[]={",bits);
+		for (i=0; i<l; i++)
+			{
+			if ((i%12) == 0) printf("\n\t\t");
+			printf("0x%02X,",data[i]);
+			}
+		printf("\n\t\t};\n");
+
+		printf("\tDH *dh;\n\n");
+		printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n");
+		printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n",
+			bits,bits);
+		printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n",
+			bits,bits);
+		printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n");
+		printf("\t\t{ DH_free(dh); return(NULL); }\n");
+		if (dh->length)
+			printf("\tdh->length = %ld;\n", dh->length);
+		printf("\treturn(dh);\n\t}\n");
+		OPENSSL_free(data);
+		}
+
+
+	if (!noout)
+		{
+		if 	(outformat == FORMAT_ASN1)
+			i=i2d_DHparams_bio(out,dh);
+		else if (outformat == FORMAT_PEM)
+			i=PEM_write_bio_DHparams(out,dh);
+		else	{
+			BIO_printf(bio_err,"bad output format specified for outfile\n");
+			goto end;
+			}
+		if (!i)
+			{
+			BIO_printf(bio_err,"unable to write DH parameters\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+	ret=0;
+end:
+	if (in != NULL) BIO_free(in);
+	if (out != NULL) BIO_free_all(out);
+	if (dh != NULL) DH_free(dh);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
+/* dh_cb is identical to dsa_cb in apps/dsaparam.c */
+static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb)
+	{
+	char c='*';
+
+	if (p == 0) c='.';
+	if (p == 1) c='+';
+	if (p == 2) c='*';
+	if (p == 3) c='\n';
+	BIO_write(cb->arg,&c,1);
+	(void)BIO_flush(cb->arg);
+#ifdef LINT
+	p=n;
+#endif
+	return 1;
+	}
+
+#else /* !OPENSSL_NO_DH */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/apps/dsa-ca.pem b/openssl/apps/dsa-ca.pem
new file mode 100644
index 0000000..cccc142
--- /dev/null
+++ b/openssl/apps/dsa-ca.pem
@@ -0,0 +1,40 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBugIBAAKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2GlrMV4FMuj+BZgnOQ
+PnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7OZq5riDb77Cjcwtel
+u+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR5HCVW1DNSQIVAPcH
+Me36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnlaG8w42nh5bNdmLso
+hkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6kQmdtvFNnFQPWAbu
+SXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15AlsQReVkusBtXOlan7Y
+Mu0OArgCgYAapll6iqz9XrZFlk2GCVcB+KihxWnH7IuHvSLw9YUrJahcBHmbpvt4
+94lF4gC5w3WPM+vXJofbusk4GoQEEsQNMDaah4m49uUqAylOVFJJJXuirVJ+o+0T
+tOFDITEAl+YZZariXOD7tdOSOl9RLMPC6+daHKS9e68u3enxhqnDGQIUB78dhW77
+J6zsFbSEHaQGUmfSeoM=
+-----END DSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE REQUEST-----
+MIICUjCCAhECAQAwUjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
+ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDELMAkGA1UEAxMCQ0Ew
+ggG0MIIBKQYFKw4DAgwwggEeAoGBAKc/boW/QWopffCfRxkwkJoJHdpqMx7FPYaW
+sxXgUy6P4FmCc5A+dTGZR3pS+4Xk2aZ7OJtoioSbh8YetX6GS1NbWc9xZRmIbs5m
+rmuINvvsKNzC16W75Sw5JkvamnAYlTeVEFYj9hXtugRe3jlP/bdDH7WkZW/NgBHk
+cJVbUM1JAhUA9wcx7fpsBgPVhYocrJxl51BmZW8CgYBN30wDppGK9RlvUEYlmeVo
+bzDjaeHls12YuyiGSPzemQQ/X4gMnHMkDSBduSqaPxiWJ+Rih8F7dGJT/GEnqHqR
+CZ228U2cVA9YBu5JdAfOVX4jzhb2ytxaYQF+yXG1TfbcNCmHaPZeIJOz2/XkCWxB
+F5WS6wG1c6Vqftgy7Q4CuAOBhAACgYAapll6iqz9XrZFlk2GCVcB+KihxWnH7IuH
+vSLw9YUrJahcBHmbpvt494lF4gC5w3WPM+vXJofbusk4GoQEEsQNMDaah4m49uUq
+AylOVFJJJXuirVJ+o+0TtOFDITEAl+YZZariXOD7tdOSOl9RLMPC6+daHKS9e68u
+3enxhqnDGaAAMAkGBSsOAwIbBQADMAAwLQIVAJGVuFsG/0DBuSZ0jF7ypdU0/G0v
+AhQfeF5BoMMDbX/kidUVpQ6gadPlZA==
+-----END CERTIFICATE REQUEST-----
+-----BEGIN CERTIFICATE-----
+MIIBrjCCAWwCAQswCQYFKw4DAhsFADBTMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
+U29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQww
+CgYDVQQDEwNQQ0EwHhcNOTcwNjE1MDIxNDI5WhcNOTcwNzE1MDIxNDI5WjBSMQsw
+CQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJu
+ZXQgV2lkZ2l0cyBQdHkgTHRkMQswCQYDVQQDEwJDQTCBkjAJBgUrDgMCDAUAA4GE
+AAKBgBqmWXqKrP1etkWWTYYJVwH4qKHFacfsi4e9IvD1hSslqFwEeZum+3j3iUXi
+ALnDdY8z69cmh9u6yTgahAQSxA0wNpqHibj25SoDKU5UUkkle6KtUn6j7RO04UMh
+MQCX5hllquJc4Pu105I6X1Esw8Lr51ocpL17ry7d6fGGqcMZMAkGBSsOAwIbBQAD
+MQAwLgIVAJ4wtQsANPxHo7Q4IQZYsL12SKdbAhUAjJ9n38zxT+iai2164xS+LIfa
+C1Q=
+-----END CERTIFICATE-----
+
diff --git a/openssl/apps/dsa-pca.pem b/openssl/apps/dsa-pca.pem
new file mode 100644
index 0000000..d23774e
--- /dev/null
+++ b/openssl/apps/dsa-pca.pem
@@ -0,0 +1,46 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2GlrMV4FMuj+BZgnOQ
+PnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7OZq5riDb77Cjcwtel
+u+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR5HCVW1DNSQIVAPcH
+Me36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnlaG8w42nh5bNdmLso
+hkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6kQmdtvFNnFQPWAbu
+SXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15AlsQReVkusBtXOlan7Y
+Mu0OArgCgYEApu25HkB1b4gKMIV7aLGNSIknMzYgrB7o1kQxeDf34dDVRM9OZ8tk
+umz6tl+iUcNe5EoxdsYV1IXSddjOi08LOLsZq7AQlNnKvbtlmMDULpqkZJD0bO7A
+29nisJfKy1URqABLw5DgfcPh1ZLXtmDfUgJvmjgTmvTPT2j9TPjq7RUCFQDNvrBz
+6TicfImU7UFRn9h00j0lJQ==
+-----END DSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE REQUEST-----
+MIICVTCCAhMCAQAwUzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
+ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEMMAoGA1UEAxMDUENB
+MIIBtTCCASkGBSsOAwIMMIIBHgKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2G
+lrMV4FMuj+BZgnOQPnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7O
+Zq5riDb77Cjcwtelu+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR
+5HCVW1DNSQIVAPcHMe36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnl
+aG8w42nh5bNdmLsohkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6
+kQmdtvFNnFQPWAbuSXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15Als
+QReVkusBtXOlan7YMu0OArgDgYUAAoGBAKbtuR5AdW+ICjCFe2ixjUiJJzM2IKwe
+6NZEMXg39+HQ1UTPTmfLZLps+rZfolHDXuRKMXbGFdSF0nXYzotPCzi7GauwEJTZ
+yr27ZZjA1C6apGSQ9GzuwNvZ4rCXystVEagAS8OQ4H3D4dWS17Zg31ICb5o4E5r0
+z09o/Uz46u0VoAAwCQYFKw4DAhsFAAMxADAuAhUArRubTxsbIXy3AhtjQ943AbNB
+nSICFQCu+g1iW3jwF+gOcbroD4S/ZcvB3w==
+-----END CERTIFICATE REQUEST-----
+-----BEGIN CERTIFICATE-----
+MIIC0zCCApECAQAwCQYFKw4DAhsFADBTMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
+U29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQww
+CgYDVQQDEwNQQ0EwHhcNOTcwNjE0MjI1NDQ1WhcNOTcwNzE0MjI1NDQ1WjBTMQsw
+CQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJu
+ZXQgV2lkZ2l0cyBQdHkgTHRkMQwwCgYDVQQDEwNQQ0EwggG1MIIBKQYFKw4DAgww
+ggEeAoGBAKc/boW/QWopffCfRxkwkJoJHdpqMx7FPYaWsxXgUy6P4FmCc5A+dTGZ
+R3pS+4Xk2aZ7OJtoioSbh8YetX6GS1NbWc9xZRmIbs5mrmuINvvsKNzC16W75Sw5
+JkvamnAYlTeVEFYj9hXtugRe3jlP/bdDH7WkZW/NgBHkcJVbUM1JAhUA9wcx7fps
+BgPVhYocrJxl51BmZW8CgYBN30wDppGK9RlvUEYlmeVobzDjaeHls12YuyiGSPze
+mQQ/X4gMnHMkDSBduSqaPxiWJ+Rih8F7dGJT/GEnqHqRCZ228U2cVA9YBu5JdAfO
+VX4jzhb2ytxaYQF+yXG1TfbcNCmHaPZeIJOz2/XkCWxBF5WS6wG1c6Vqftgy7Q4C
+uAOBhQACgYEApu25HkB1b4gKMIV7aLGNSIknMzYgrB7o1kQxeDf34dDVRM9OZ8tk
+umz6tl+iUcNe5EoxdsYV1IXSddjOi08LOLsZq7AQlNnKvbtlmMDULpqkZJD0bO7A
+29nisJfKy1URqABLw5DgfcPh1ZLXtmDfUgJvmjgTmvTPT2j9TPjq7RUwCQYFKw4D
+AhsFAAMxADAuAhUAvtv6AkMolix1Jvy3UnVEIUqdCUICFQC+jq8P49mwrY9oJ24n
+5rKUjNBhSg==
+-----END CERTIFICATE-----
+
diff --git a/openssl/apps/dsa.c b/openssl/apps/dsa.c
new file mode 100644
index 0000000..5222487
--- /dev/null
+++ b/openssl/apps/dsa.c
@@ -0,0 +1,376 @@
+/* apps/dsa.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/opensslconf.h>	/* for OPENSSL_NO_DSA */
+#ifndef OPENSSL_NO_DSA
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/dsa.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/bn.h>
+
+#undef PROG
+#define PROG	dsa_main
+
+/* -inform arg	- input format - default PEM (one of DER, NET or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg	- input file - default stdin
+ * -out arg	- output file - default stdout
+ * -des		- encrypt output if PEM format with DES in cbc mode
+ * -des3	- encrypt output if PEM format
+ * -idea	- encrypt output if PEM format
+ * -aes128	- encrypt output if PEM format
+ * -aes192	- encrypt output if PEM format
+ * -aes256	- encrypt output if PEM format
+ * -camellia128 - encrypt output if PEM format
+ * -camellia192 - encrypt output if PEM format
+ * -camellia256 - encrypt output if PEM format
+ * -seed        - encrypt output if PEM format
+ * -text	- print a text version
+ * -modulus	- print the DSA public key
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	ENGINE *e = NULL;
+	int ret=1;
+	DSA *dsa=NULL;
+	int i,badops=0;
+	const EVP_CIPHER *enc=NULL;
+	BIO *in=NULL,*out=NULL;
+	int informat,outformat,text=0,noout=0;
+	int pubin = 0, pubout = 0;
+	char *infile,*outfile,*prog;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine;
+#endif
+	char *passargin = NULL, *passargout = NULL;
+	char *passin = NULL, *passout = NULL;
+	int modulus=0;
+
+	int pvk_encr = 2;
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+#ifndef OPENSSL_NO_ENGINE
+	engine=NULL;
+#endif
+	infile=NULL;
+	outfile=NULL;
+	informat=FORMAT_PEM;
+	outformat=FORMAT_PEM;
+
+	prog=argv[0];
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if 	(strcmp(*argv,"-inform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			informat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-outform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outformat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-passin") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passargin= *(++argv);
+			}
+		else if (strcmp(*argv,"-passout") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passargout= *(++argv);
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*argv,"-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine= *(++argv);
+			}
+#endif
+		else if (strcmp(*argv,"-pvk-strong") == 0)
+			pvk_encr=2;
+		else if (strcmp(*argv,"-pvk-weak") == 0)
+			pvk_encr=1;
+		else if (strcmp(*argv,"-pvk-none") == 0)
+			pvk_encr=0;
+		else if (strcmp(*argv,"-noout") == 0)
+			noout=1;
+		else if (strcmp(*argv,"-text") == 0)
+			text=1;
+		else if (strcmp(*argv,"-modulus") == 0)
+			modulus=1;
+		else if (strcmp(*argv,"-pubin") == 0)
+			pubin=1;
+		else if (strcmp(*argv,"-pubout") == 0)
+			pubout=1;
+		else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL)
+			{
+			BIO_printf(bio_err,"unknown option %s\n",*argv);
+			badops=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (badops)
+		{
+bad:
+		BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
+		BIO_printf(bio_err,"where options are\n");
+		BIO_printf(bio_err," -inform arg     input format - DER or PEM\n");
+		BIO_printf(bio_err," -outform arg    output format - DER or PEM\n");
+		BIO_printf(bio_err," -in arg         input file\n");
+		BIO_printf(bio_err," -passin arg     input file pass phrase source\n");
+		BIO_printf(bio_err," -out arg        output file\n");
+		BIO_printf(bio_err," -passout arg    output file pass phrase source\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err," -engine e       use engine e, possibly a hardware device.\n");
+#endif
+		BIO_printf(bio_err," -des            encrypt PEM output with cbc des\n");
+		BIO_printf(bio_err," -des3           encrypt PEM output with ede cbc des using 168 bit key\n");
+#ifndef OPENSSL_NO_IDEA
+		BIO_printf(bio_err," -idea           encrypt PEM output with cbc idea\n");
+#endif
+#ifndef OPENSSL_NO_AES
+		BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
+		BIO_printf(bio_err,"                 encrypt PEM output with cbc aes\n");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+		BIO_printf(bio_err," -camellia128, -camellia192, -camellia256\n");
+		BIO_printf(bio_err,"                 encrypt PEM output with cbc camellia\n");
+#endif
+#ifndef OPENSSL_NO_SEED
+		BIO_printf(bio_err," -seed           encrypt PEM output with cbc seed\n");
+#endif
+		BIO_printf(bio_err," -text           print the key in text\n");
+		BIO_printf(bio_err," -noout          don't print key out\n");
+		BIO_printf(bio_err," -modulus        print the DSA public value\n");
+		goto end;
+		}
+
+	ERR_load_crypto_strings();
+
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine, 0);
+#endif
+
+	if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
+		BIO_printf(bio_err, "Error getting passwords\n");
+		goto end;
+	}
+
+	in=BIO_new(BIO_s_file());
+	out=BIO_new(BIO_s_file());
+	if ((in == NULL) || (out == NULL))
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (infile == NULL)
+		BIO_set_fp(in,stdin,BIO_NOCLOSE);
+	else
+		{
+		if (BIO_read_filename(in,infile) <= 0)
+			{
+			perror(infile);
+			goto end;
+			}
+		}
+
+	BIO_printf(bio_err,"read DSA key\n");
+
+		{
+		EVP_PKEY	*pkey;
+
+		if (pubin)
+			pkey = load_pubkey(bio_err, infile, informat, 1,
+				passin, e, "Public Key");
+		else
+			pkey = load_key(bio_err, infile, informat, 1,
+				passin, e, "Private Key");
+
+		if (pkey)
+			{
+			dsa = EVP_PKEY_get1_DSA(pkey);
+			EVP_PKEY_free(pkey);
+			}
+		}
+	if (dsa == NULL)
+		{
+		BIO_printf(bio_err,"unable to load Key\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (outfile == NULL)
+		{
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+		}
+	else
+		{
+		if (BIO_write_filename(out,outfile) <= 0)
+			{
+			perror(outfile);
+			goto end;
+			}
+		}
+
+	if (text) 
+		if (!DSA_print(out,dsa,0))
+			{
+			perror(outfile);
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+
+	if (modulus)
+		{
+		fprintf(stdout,"Public Key=");
+		BN_print(out,dsa->pub_key);
+		fprintf(stdout,"\n");
+		}
+
+	if (noout) goto end;
+	BIO_printf(bio_err,"writing DSA key\n");
+	if 	(outformat == FORMAT_ASN1) {
+		if(pubin || pubout) i=i2d_DSA_PUBKEY_bio(out,dsa);
+		else i=i2d_DSAPrivateKey_bio(out,dsa);
+	} else if (outformat == FORMAT_PEM) {
+		if(pubin || pubout)
+			i=PEM_write_bio_DSA_PUBKEY(out,dsa);
+		else i=PEM_write_bio_DSAPrivateKey(out,dsa,enc,
+							NULL,0,NULL, passout);
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_RC4)
+	} else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) {
+		EVP_PKEY *pk;
+		pk = EVP_PKEY_new();
+		EVP_PKEY_set1_DSA(pk, dsa);
+		if (outformat == FORMAT_PVK)
+			i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout);
+		else if (pubin || pubout)
+			i = i2b_PublicKey_bio(out, pk);
+		else
+			i = i2b_PrivateKey_bio(out, pk);
+		EVP_PKEY_free(pk);
+#endif
+	} else {
+		BIO_printf(bio_err,"bad output format specified for outfile\n");
+		goto end;
+		}
+	if (i <= 0)
+		{
+		BIO_printf(bio_err,"unable to write private key\n");
+		ERR_print_errors(bio_err);
+		}
+	else
+		ret=0;
+end:
+	if(in != NULL) BIO_free(in);
+	if(out != NULL) BIO_free_all(out);
+	if(dsa != NULL) DSA_free(dsa);
+	if(passin) OPENSSL_free(passin);
+	if(passout) OPENSSL_free(passout);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+#else /* !OPENSSL_NO_DSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/apps/dsa1024.pem b/openssl/apps/dsa1024.pem
new file mode 100644
index 0000000..082dec3
--- /dev/null
+++ b/openssl/apps/dsa1024.pem
@@ -0,0 +1,9 @@
+-----BEGIN DSA PARAMETERS-----
+MIIBHgKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2GlrMV4FMuj+BZgnOQPnUx
+mUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7OZq5riDb77Cjcwtelu+Us
+OSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR5HCVW1DNSQIVAPcHMe36
+bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnlaG8w42nh5bNdmLsohkj8
+3pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6kQmdtvFNnFQPWAbuSXQH
+zlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15AlsQReVkusBtXOlan7YMu0O
+Arg=
+-----END DSA PARAMETERS-----
diff --git a/openssl/apps/dsa512.pem b/openssl/apps/dsa512.pem
new file mode 100644
index 0000000..5f86d1a
--- /dev/null
+++ b/openssl/apps/dsa512.pem
@@ -0,0 +1,6 @@
+-----BEGIN DSA PARAMETERS-----
+MIGdAkEAnRtpjibb8isRcBmG9hnI+BnyGFOURgbQYlAzSwI8UjADizv5X9EkBk97
+TLqqQJv9luQ3M7stWtdaEUBmonZ9MQIVAPtT71C0QJIxVoZTeuiLIppJ+3GPAkEA
+gz6I5cWJc847bAFJv7PHnwrqRJHlMKrZvltftxDXibeOdPvPKR7rqCxUUbgQ3qDO
+L8wka5B33qJoplISogOdIA==
+-----END DSA PARAMETERS-----
diff --git a/openssl/apps/dsap.pem b/openssl/apps/dsap.pem
new file mode 100644
index 0000000..d4dfdb3
--- /dev/null
+++ b/openssl/apps/dsap.pem
@@ -0,0 +1,6 @@
+-----BEGIN DSA PARAMETERS-----
+MIGcAkEA+ZiKEvZmc9MtnaFZh4NiZ3oZS4J1PHvPrm9MXj5ntVheDPkdmBDTncya
+GAJcMjwsyB/GvLDGd6yGCw/8eF+09wIVAK3VagOxGd/Q4Af5NbxR5FB7CXEjAkA2
+t/q7HgVLi0KeKvcDG8BRl3wuy7bCvpjgtWiJc/tpvcuzeuAayH89UofjAGueKjXD
+ADiRffvSdhrNw5dkqdql
+-----END DSA PARAMETERS-----
diff --git a/openssl/apps/dsaparam.c b/openssl/apps/dsaparam.c
new file mode 100644
index 0000000..fe72c1d
--- /dev/null
+++ b/openssl/apps/dsaparam.c
@@ -0,0 +1,479 @@
+/* apps/dsaparam.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/opensslconf.h>	/* for OPENSSL_NO_DSA */
+/* Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code */
+#ifdef OPENSSL_NO_DEPRECATED
+#undef OPENSSL_NO_DEPRECATED
+#endif
+
+#ifndef OPENSSL_NO_DSA
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+#undef PROG
+#define PROG	dsaparam_main
+
+/* -inform arg	- input format - default PEM (DER or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg	- input file - default stdin
+ * -out arg	- output file - default stdout
+ * -noout
+ * -text
+ * -C
+ * -noout
+ * -genkey
+ *  #ifdef GENCB_TEST
+ * -timebomb n  - interrupt keygen after <n> seconds
+ *  #endif
+ */
+
+#ifdef GENCB_TEST
+
+static int stop_keygen_flag = 0;
+
+static void timebomb_sigalarm(int foo)
+	{
+	stop_keygen_flag = 1;
+	}
+
+#endif
+
+static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb);
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	DSA *dsa=NULL;
+	int i,badops=0,text=0;
+	BIO *in=NULL,*out=NULL;
+	int informat,outformat,noout=0,C=0,ret=1;
+	char *infile,*outfile,*prog,*inrand=NULL;
+	int numbits= -1,num,genkey=0;
+	int need_rand=0;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+#ifdef GENCB_TEST
+	int timebomb=0;
+#endif
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	infile=NULL;
+	outfile=NULL;
+	informat=FORMAT_PEM;
+	outformat=FORMAT_PEM;
+
+	prog=argv[0];
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if 	(strcmp(*argv,"-inform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			informat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-outform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outformat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if(strcmp(*argv, "-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine = *(++argv);
+			}
+#endif
+#ifdef GENCB_TEST
+		else if(strcmp(*argv, "-timebomb") == 0)
+			{
+			if (--argc < 1) goto bad;
+			timebomb = atoi(*(++argv));
+			}
+#endif
+		else if (strcmp(*argv,"-text") == 0)
+			text=1;
+		else if (strcmp(*argv,"-C") == 0)
+			C=1;
+		else if (strcmp(*argv,"-genkey") == 0)
+			{
+			genkey=1;
+			need_rand=1;
+			}
+		else if (strcmp(*argv,"-rand") == 0)
+			{
+			if (--argc < 1) goto bad;
+			inrand= *(++argv);
+			need_rand=1;
+			}
+		else if (strcmp(*argv,"-noout") == 0)
+			noout=1;
+		else if (sscanf(*argv,"%d",&num) == 1)
+			{
+			/* generate a key */
+			numbits=num;
+			need_rand=1;
+			}
+		else
+			{
+			BIO_printf(bio_err,"unknown option %s\n",*argv);
+			badops=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (badops)
+		{
+bad:
+		BIO_printf(bio_err,"%s [options] [bits] <infile >outfile\n",prog);
+		BIO_printf(bio_err,"where options are\n");
+		BIO_printf(bio_err," -inform arg   input format - DER or PEM\n");
+		BIO_printf(bio_err," -outform arg  output format - DER or PEM\n");
+		BIO_printf(bio_err," -in arg       input file\n");
+		BIO_printf(bio_err," -out arg      output file\n");
+		BIO_printf(bio_err," -text         print as text\n");
+		BIO_printf(bio_err," -C            Output C code\n");
+		BIO_printf(bio_err," -noout        no output\n");
+		BIO_printf(bio_err," -genkey       generate a DSA key\n");
+		BIO_printf(bio_err," -rand         files to use for random number input\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err," -engine e     use engine e, possibly a hardware device.\n");
+#endif
+#ifdef GENCB_TEST
+		BIO_printf(bio_err," -timebomb n   interrupt keygen after <n> seconds\n");
+#endif
+		BIO_printf(bio_err," number        number of bits to use for generating private key\n");
+		goto end;
+		}
+
+	ERR_load_crypto_strings();
+
+	in=BIO_new(BIO_s_file());
+	out=BIO_new(BIO_s_file());
+	if ((in == NULL) || (out == NULL))
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (infile == NULL)
+		BIO_set_fp(in,stdin,BIO_NOCLOSE);
+	else
+		{
+		if (BIO_read_filename(in,infile) <= 0)
+			{
+			perror(infile);
+			goto end;
+			}
+		}
+	if (outfile == NULL)
+		{
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+		}
+	else
+		{
+		if (BIO_write_filename(out,outfile) <= 0)
+			{
+			perror(outfile);
+			goto end;
+			}
+		}
+
+#ifndef OPENSSL_NO_ENGINE
+        setup_engine(bio_err, engine, 0);
+#endif
+
+	if (need_rand)
+		{
+		app_RAND_load_file(NULL, bio_err, (inrand != NULL));
+		if (inrand != NULL)
+			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+				app_RAND_load_files(inrand));
+		}
+
+	if (numbits > 0)
+		{
+		BN_GENCB cb;
+		BN_GENCB_set(&cb, dsa_cb, bio_err);
+		assert(need_rand);
+		dsa = DSA_new();
+		if(!dsa)
+			{
+			BIO_printf(bio_err,"Error allocating DSA object\n");
+			goto end;
+			}
+		BIO_printf(bio_err,"Generating DSA parameters, %d bit long prime\n",num);
+	        BIO_printf(bio_err,"This could take some time\n");
+#ifdef GENCB_TEST
+		if(timebomb > 0)
+	{
+		struct sigaction act;
+		act.sa_handler = timebomb_sigalarm;
+		act.sa_flags = 0;
+		BIO_printf(bio_err,"(though I'll stop it if not done within %d secs)\n",
+				timebomb);
+		if(sigaction(SIGALRM, &act, NULL) != 0)
+			{
+			BIO_printf(bio_err,"Error, couldn't set SIGALRM handler\n");
+			goto end;
+			}
+		alarm(timebomb);
+	}
+#endif
+	        if(!DSA_generate_parameters_ex(dsa,num,NULL,0,NULL,NULL, &cb))
+			{
+#ifdef GENCB_TEST
+			if(stop_keygen_flag)
+				{
+				BIO_printf(bio_err,"DSA key generation time-stopped\n");
+				/* This is an asked-for behaviour! */
+				ret = 0;
+				goto end;
+				}
+#endif
+			BIO_printf(bio_err,"Error, DSA key generation failed\n");
+			goto end;
+			}
+		}
+	else if	(informat == FORMAT_ASN1)
+		dsa=d2i_DSAparams_bio(in,NULL);
+	else if (informat == FORMAT_PEM)
+		dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL);
+	else
+		{
+		BIO_printf(bio_err,"bad input format specified\n");
+		goto end;
+		}
+	if (dsa == NULL)
+		{
+		BIO_printf(bio_err,"unable to load DSA parameters\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (text)
+		{
+		DSAparams_print(out,dsa);
+		}
+	
+	if (C)
+		{
+		unsigned char *data;
+		int l,len,bits_p;
+
+		len=BN_num_bytes(dsa->p);
+		bits_p=BN_num_bits(dsa->p);
+		data=(unsigned char *)OPENSSL_malloc(len+20);
+		if (data == NULL)
+			{
+			perror("OPENSSL_malloc");
+			goto end;
+			}
+		l=BN_bn2bin(dsa->p,data);
+		printf("static unsigned char dsa%d_p[]={",bits_p);
+		for (i=0; i<l; i++)
+			{
+			if ((i%12) == 0) printf("\n\t");
+			printf("0x%02X,",data[i]);
+			}
+		printf("\n\t};\n");
+
+		l=BN_bn2bin(dsa->q,data);
+		printf("static unsigned char dsa%d_q[]={",bits_p);
+		for (i=0; i<l; i++)
+			{
+			if ((i%12) == 0) printf("\n\t");
+			printf("0x%02X,",data[i]);
+			}
+		printf("\n\t};\n");
+
+		l=BN_bn2bin(dsa->g,data);
+		printf("static unsigned char dsa%d_g[]={",bits_p);
+		for (i=0; i<l; i++)
+			{
+			if ((i%12) == 0) printf("\n\t");
+			printf("0x%02X,",data[i]);
+			}
+		printf("\n\t};\n\n");
+
+		printf("DSA *get_dsa%d()\n\t{\n",bits_p);
+		printf("\tDSA *dsa;\n\n");
+		printf("\tif ((dsa=DSA_new()) == NULL) return(NULL);\n");
+		printf("\tdsa->p=BN_bin2bn(dsa%d_p,sizeof(dsa%d_p),NULL);\n",
+			bits_p,bits_p);
+		printf("\tdsa->q=BN_bin2bn(dsa%d_q,sizeof(dsa%d_q),NULL);\n",
+			bits_p,bits_p);
+		printf("\tdsa->g=BN_bin2bn(dsa%d_g,sizeof(dsa%d_g),NULL);\n",
+			bits_p,bits_p);
+		printf("\tif ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))\n");
+		printf("\t\t{ DSA_free(dsa); return(NULL); }\n");
+		printf("\treturn(dsa);\n\t}\n");
+		}
+
+
+	if (!noout)
+		{
+		if 	(outformat == FORMAT_ASN1)
+			i=i2d_DSAparams_bio(out,dsa);
+		else if (outformat == FORMAT_PEM)
+			i=PEM_write_bio_DSAparams(out,dsa);
+		else	{
+			BIO_printf(bio_err,"bad output format specified for outfile\n");
+			goto end;
+			}
+		if (!i)
+			{
+			BIO_printf(bio_err,"unable to write DSA parameters\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+	if (genkey)
+		{
+		DSA *dsakey;
+
+		assert(need_rand);
+		if ((dsakey=DSAparams_dup(dsa)) == NULL) goto end;
+		if (!DSA_generate_key(dsakey)) goto end;
+		if 	(outformat == FORMAT_ASN1)
+			i=i2d_DSAPrivateKey_bio(out,dsakey);
+		else if (outformat == FORMAT_PEM)
+			i=PEM_write_bio_DSAPrivateKey(out,dsakey,NULL,NULL,0,NULL,NULL);
+		else	{
+			BIO_printf(bio_err,"bad output format specified for outfile\n");
+			goto end;
+			}
+		DSA_free(dsakey);
+		}
+	if (need_rand)
+		app_RAND_write_file(NULL, bio_err);
+	ret=0;
+end:
+	if (in != NULL) BIO_free(in);
+	if (out != NULL) BIO_free_all(out);
+	if (dsa != NULL) DSA_free(dsa);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
+static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb)
+	{
+	char c='*';
+
+	if (p == 0) c='.';
+	if (p == 1) c='+';
+	if (p == 2) c='*';
+	if (p == 3) c='\n';
+	BIO_write(cb->arg,&c,1);
+	(void)BIO_flush(cb->arg);
+#ifdef LINT
+	p=n;
+#endif
+#ifdef GENCB_TEST
+	if(stop_keygen_flag)
+		return 0;
+#endif
+	return 1;
+	}
+#else /* !OPENSSL_NO_DSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/apps/ec.c b/openssl/apps/ec.c
new file mode 100644
index 0000000..896eabc
--- /dev/null
+++ b/openssl/apps/ec.c
@@ -0,0 +1,406 @@
+/* apps/ec.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_EC
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+
+#undef PROG
+#define PROG	ec_main
+
+/* -inform arg    - input format - default PEM (one of DER, NET or PEM)
+ * -outform arg   - output format - default PEM
+ * -in arg        - input file - default stdin
+ * -out arg       - output file - default stdout
+ * -des           - encrypt output if PEM format with DES in cbc mode
+ * -text          - print a text version
+ * -param_out     - print the elliptic curve parameters
+ * -conv_form arg - specifies the point encoding form
+ * -param_enc arg - specifies the parameter encoding
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+{
+	int 	ret = 1;
+	EC_KEY 	*eckey = NULL;
+	const EC_GROUP *group;
+	int 	i, badops = 0;
+	const EVP_CIPHER *enc = NULL;
+	BIO 	*in = NULL, *out = NULL;
+	int 	informat, outformat, text=0, noout=0;
+	int  	pubin = 0, pubout = 0, param_out = 0;
+	char 	*infile, *outfile, *prog, *engine;
+	char 	*passargin = NULL, *passargout = NULL;
+	char 	*passin = NULL, *passout = NULL;
+	point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
+	int	new_form = 0;
+	int	asn1_flag = OPENSSL_EC_NAMED_CURVE;
+	int 	new_asn1_flag = 0;
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	engine = NULL;
+	infile = NULL;
+	outfile = NULL;
+	informat = FORMAT_PEM;
+	outformat = FORMAT_PEM;
+
+	prog = argv[0];
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if (strcmp(*argv,"-inform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			informat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-outform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outformat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-passin") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passargin= *(++argv);
+			}
+		else if (strcmp(*argv,"-passout") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passargout= *(++argv);
+			}
+		else if (strcmp(*argv, "-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine= *(++argv);
+			}
+		else if (strcmp(*argv, "-noout") == 0)
+			noout = 1;
+		else if (strcmp(*argv, "-text") == 0)
+			text = 1;
+		else if (strcmp(*argv, "-conv_form") == 0)
+			{
+			if (--argc < 1)
+				goto bad;
+			++argv;
+			new_form = 1;
+			if (strcmp(*argv, "compressed") == 0)
+				form = POINT_CONVERSION_COMPRESSED;
+			else if (strcmp(*argv, "uncompressed") == 0)
+				form = POINT_CONVERSION_UNCOMPRESSED;
+			else if (strcmp(*argv, "hybrid") == 0)
+				form = POINT_CONVERSION_HYBRID;
+			else
+				goto bad;
+			}
+		else if (strcmp(*argv, "-param_enc") == 0)
+			{
+			if (--argc < 1)
+				goto bad;
+			++argv;
+			new_asn1_flag = 1;
+			if (strcmp(*argv, "named_curve") == 0)
+				asn1_flag = OPENSSL_EC_NAMED_CURVE;
+			else if (strcmp(*argv, "explicit") == 0)
+				asn1_flag = 0;
+			else
+				goto bad;
+			}
+		else if (strcmp(*argv, "-param_out") == 0)
+			param_out = 1;
+		else if (strcmp(*argv, "-pubin") == 0)
+			pubin=1;
+		else if (strcmp(*argv, "-pubout") == 0)
+			pubout=1;
+		else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL)
+			{
+			BIO_printf(bio_err, "unknown option %s\n", *argv);
+			badops=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (badops)
+		{
+bad:
+		BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
+		BIO_printf(bio_err, "where options are\n");
+		BIO_printf(bio_err, " -inform arg     input format - "
+				"DER or PEM\n");
+		BIO_printf(bio_err, " -outform arg    output format - "
+				"DER or PEM\n");
+		BIO_printf(bio_err, " -in arg         input file\n");
+		BIO_printf(bio_err, " -passin arg     input file pass "
+				"phrase source\n");
+		BIO_printf(bio_err, " -out arg        output file\n");
+		BIO_printf(bio_err, " -passout arg    output file pass "
+				"phrase source\n");
+		BIO_printf(bio_err, " -engine e       use engine e, "
+				"possibly a hardware device.\n");
+		BIO_printf(bio_err, " -des            encrypt PEM output, "
+				"instead of 'des' every other \n"
+				"                 cipher "
+				"supported by OpenSSL can be used\n");
+		BIO_printf(bio_err, " -text           print the key\n");
+		BIO_printf(bio_err, " -noout          don't print key out\n");
+		BIO_printf(bio_err, " -param_out      print the elliptic "
+				"curve parameters\n");
+		BIO_printf(bio_err, " -conv_form arg  specifies the "
+				"point conversion form \n");
+		BIO_printf(bio_err, "                 possible values:"
+				" compressed\n");
+		BIO_printf(bio_err, "                                 "
+				" uncompressed (default)\n");
+		BIO_printf(bio_err, "                                  "
+				" hybrid\n");
+		BIO_printf(bio_err, " -param_enc arg  specifies the way"
+				" the ec parameters are encoded\n");
+		BIO_printf(bio_err, "                 in the asn1 der "
+				"encoding\n");
+		BIO_printf(bio_err, "                 possible values:"
+				" named_curve (default)\n");
+		BIO_printf(bio_err,"                                  "
+				"explicit\n");
+		goto end;
+		}
+
+	ERR_load_crypto_strings();
+
+#ifndef OPENSSL_NO_ENGINE
+        setup_engine(bio_err, engine, 0);
+#endif
+
+	if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) 
+		{
+		BIO_printf(bio_err, "Error getting passwords\n");
+		goto end;
+		}
+
+	in = BIO_new(BIO_s_file());
+	out = BIO_new(BIO_s_file());
+	if ((in == NULL) || (out == NULL))
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (infile == NULL)
+		BIO_set_fp(in, stdin, BIO_NOCLOSE);
+	else
+		{
+		if (BIO_read_filename(in, infile) <= 0)
+			{
+			perror(infile);
+			goto end;
+			}
+		}
+
+	BIO_printf(bio_err, "read EC key\n");
+	if (informat == FORMAT_ASN1) 
+		{
+		if (pubin) 
+			eckey = d2i_EC_PUBKEY_bio(in, NULL);
+		else 
+			eckey = d2i_ECPrivateKey_bio(in, NULL);
+		} 
+	else if (informat == FORMAT_PEM) 
+		{
+		if (pubin) 
+			eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, 
+				NULL);
+		else 
+			eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL,
+				passin);
+		} 
+	else
+		{
+		BIO_printf(bio_err, "bad input format specified for key\n");
+		goto end;
+		}
+	if (eckey == NULL)
+		{
+		BIO_printf(bio_err,"unable to load Key\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (outfile == NULL)
+		{
+		BIO_set_fp(out, stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+			{
+			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+			out = BIO_push(tmpbio, out);
+			}
+#endif
+		}
+	else
+		{
+		if (BIO_write_filename(out, outfile) <= 0)
+			{
+			perror(outfile);
+			goto end;
+			}
+		}
+
+	group = EC_KEY_get0_group(eckey);
+
+	if (new_form)
+		EC_KEY_set_conv_form(eckey, form);
+
+	if (new_asn1_flag)
+		EC_KEY_set_asn1_flag(eckey, asn1_flag);
+
+	if (text) 
+		if (!EC_KEY_print(out, eckey, 0))
+			{
+			perror(outfile);
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+
+	if (noout) 
+		{
+		ret = 0;
+		goto end;
+		}
+
+	BIO_printf(bio_err, "writing EC key\n");
+	if (outformat == FORMAT_ASN1) 
+		{
+		if (param_out)
+			i = i2d_ECPKParameters_bio(out, group);
+		else if (pubin || pubout) 
+			i = i2d_EC_PUBKEY_bio(out, eckey);
+		else 
+			i = i2d_ECPrivateKey_bio(out, eckey);
+		} 
+	else if (outformat == FORMAT_PEM) 
+		{
+		if (param_out)
+			i = PEM_write_bio_ECPKParameters(out, group);
+		else if (pubin || pubout)
+			i = PEM_write_bio_EC_PUBKEY(out, eckey);
+		else 
+			i = PEM_write_bio_ECPrivateKey(out, eckey, enc,
+						NULL, 0, NULL, passout);
+		} 
+	else 
+		{
+		BIO_printf(bio_err, "bad output format specified for "
+			"outfile\n");
+		goto end;
+		}
+
+	if (!i)
+		{
+		BIO_printf(bio_err, "unable to write private key\n");
+		ERR_print_errors(bio_err);
+		}
+	else
+		ret=0;
+end:
+	if (in)
+		BIO_free(in);
+	if (out)
+		BIO_free_all(out);
+	if (eckey)
+		EC_KEY_free(eckey);
+	if (passin)
+		OPENSSL_free(passin);
+	if (passout)
+		OPENSSL_free(passout);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+}
+#else /* !OPENSSL_NO_EC */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/apps/ecparam.c b/openssl/apps/ecparam.c
new file mode 100644
index 0000000..465480b
--- /dev/null
+++ b/openssl/apps/ecparam.c
@@ -0,0 +1,731 @@
+/* apps/ecparam.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by 
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_EC
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+#undef PROG
+#define PROG	ecparam_main
+
+/* -inform arg      - input format - default PEM (DER or PEM)
+ * -outform arg     - output format - default PEM
+ * -in  arg         - input file  - default stdin
+ * -out arg         - output file - default stdout
+ * -noout           - do not print the ec parameter
+ * -text            - print the ec parameters in text form
+ * -check           - validate the ec parameters
+ * -C               - print a 'C' function creating the parameters
+ * -name arg        - use the ec parameters with 'short name' name
+ * -list_curves     - prints a list of all currently available curve 'short names'
+ * -conv_form arg   - specifies the point conversion form 
+ *                  - possible values: compressed
+ *                                     uncompressed (default)
+ *                                     hybrid
+ * -param_enc arg   - specifies the way the ec parameters are encoded
+ *                    in the asn1 der encoding
+ *                    possible values: named_curve (default)
+ *                                     explicit
+ * -no_seed         - if 'explicit' parameters are choosen do not use the seed
+ * -genkey          - generate ec key
+ * -rand file       - files to use for random number input
+ * -engine e        - use engine e, possibly a hardware device
+ */
+
+
+static int ecparam_print_var(BIO *,BIGNUM *,const char *,int,unsigned char *);
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	EC_GROUP *group = NULL;
+	point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED; 
+	int 	new_form = 0;
+	int 	asn1_flag = OPENSSL_EC_NAMED_CURVE;
+	int 	new_asn1_flag = 0;
+	char 	*curve_name = NULL, *inrand = NULL;
+	int	list_curves = 0, no_seed = 0, check = 0,
+		badops = 0, text = 0, i, need_rand = 0, genkey = 0;
+	char	*infile = NULL, *outfile = NULL, *prog;
+	BIO 	*in = NULL, *out = NULL;
+	int 	informat, outformat, noout = 0, C = 0, ret = 1;
+	char	*engine = NULL;
+
+	BIGNUM	*ec_p = NULL, *ec_a = NULL, *ec_b = NULL,
+		*ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL;
+	unsigned char *buffer = NULL;
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	informat=FORMAT_PEM;
+	outformat=FORMAT_PEM;
+
+	prog=argv[0];
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if 	(strcmp(*argv,"-inform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			informat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-outform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outformat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-text") == 0)
+			text = 1;
+		else if (strcmp(*argv,"-C") == 0)
+			C = 1;
+		else if (strcmp(*argv,"-check") == 0)
+			check = 1;
+		else if (strcmp (*argv, "-name") == 0)
+			{
+			if (--argc < 1)
+				goto bad;
+			curve_name = *(++argv);
+			}
+		else if (strcmp(*argv, "-list_curves") == 0)
+			list_curves = 1;
+		else if (strcmp(*argv, "-conv_form") == 0)
+			{
+			if (--argc < 1)
+				goto bad;
+			++argv;
+			new_form = 1;
+			if (strcmp(*argv, "compressed") == 0)
+				form = POINT_CONVERSION_COMPRESSED;
+			else if (strcmp(*argv, "uncompressed") == 0)
+				form = POINT_CONVERSION_UNCOMPRESSED;
+			else if (strcmp(*argv, "hybrid") == 0)
+				form = POINT_CONVERSION_HYBRID;
+			else
+				goto bad;
+			}
+		else if (strcmp(*argv, "-param_enc") == 0)
+			{
+			if (--argc < 1)
+				goto bad;
+			++argv;
+			new_asn1_flag = 1;
+			if (strcmp(*argv, "named_curve") == 0)
+				asn1_flag = OPENSSL_EC_NAMED_CURVE;
+			else if (strcmp(*argv, "explicit") == 0)
+				asn1_flag = 0;
+			else
+				goto bad;
+			}
+		else if (strcmp(*argv, "-no_seed") == 0)
+			no_seed = 1;
+		else if (strcmp(*argv, "-noout") == 0)
+			noout=1;
+		else if (strcmp(*argv,"-genkey") == 0)
+			{
+			genkey=1;
+			need_rand=1;
+			}
+		else if (strcmp(*argv, "-rand") == 0)
+			{
+			if (--argc < 1) goto bad;
+			inrand= *(++argv);
+			need_rand=1;
+			}
+		else if(strcmp(*argv, "-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine = *(++argv);
+			}	
+		else
+			{
+			BIO_printf(bio_err,"unknown option %s\n",*argv);
+			badops=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (badops)
+		{
+bad:
+		BIO_printf(bio_err, "%s [options] <infile >outfile\n",prog);
+		BIO_printf(bio_err, "where options are\n");
+		BIO_printf(bio_err, " -inform arg       input format - "
+				"default PEM (DER or PEM)\n");
+		BIO_printf(bio_err, " -outform arg      output format - "
+				"default PEM\n");
+		BIO_printf(bio_err, " -in  arg          input file  - "
+				"default stdin\n");
+		BIO_printf(bio_err, " -out arg          output file - "
+				"default stdout\n");
+		BIO_printf(bio_err, " -noout            do not print the "
+				"ec parameter\n");
+		BIO_printf(bio_err, " -text             print the ec "
+				"parameters in text form\n");
+		BIO_printf(bio_err, " -check            validate the ec "
+				"parameters\n");
+		BIO_printf(bio_err, " -C                print a 'C' "
+				"function creating the parameters\n");
+		BIO_printf(bio_err, " -name arg         use the "
+				"ec parameters with 'short name' name\n");
+		BIO_printf(bio_err, " -list_curves      prints a list of "
+				"all currently available curve 'short names'\n");
+		BIO_printf(bio_err, " -conv_form arg    specifies the "
+				"point conversion form \n");
+		BIO_printf(bio_err, "                   possible values:"
+				" compressed\n");
+		BIO_printf(bio_err, "                                   "
+				" uncompressed (default)\n");
+		BIO_printf(bio_err, "                                   "
+				" hybrid\n");
+		BIO_printf(bio_err, " -param_enc arg    specifies the way"
+				" the ec parameters are encoded\n");
+		BIO_printf(bio_err, "                   in the asn1 der "
+				"encoding\n");
+		BIO_printf(bio_err, "                   possible values:"
+				" named_curve (default)\n");
+		BIO_printf(bio_err, "                                   "
+				" explicit\n");
+		BIO_printf(bio_err, " -no_seed          if 'explicit'"
+				" parameters are choosen do not"
+				" use the seed\n");
+		BIO_printf(bio_err, " -genkey           generate ec"
+				" key\n");
+		BIO_printf(bio_err, " -rand file        files to use for"
+				" random number input\n");
+		BIO_printf(bio_err, " -engine e         use engine e, "
+				"possibly a hardware device\n");
+		goto end;
+		}
+
+	ERR_load_crypto_strings();
+
+	in=BIO_new(BIO_s_file());
+	out=BIO_new(BIO_s_file());
+	if ((in == NULL) || (out == NULL))
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (infile == NULL)
+		BIO_set_fp(in,stdin,BIO_NOCLOSE);
+	else
+		{
+		if (BIO_read_filename(in,infile) <= 0)
+			{
+			perror(infile);
+			goto end;
+			}
+		}
+	if (outfile == NULL)
+		{
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+		}
+	else
+		{
+		if (BIO_write_filename(out,outfile) <= 0)
+			{
+			perror(outfile);
+			goto end;
+			}
+		}
+
+#ifndef OPENSSL_NO_ENGINE
+	setup_engine(bio_err, engine, 0);
+#endif
+
+	if (list_curves)
+		{
+		EC_builtin_curve *curves = NULL;
+		size_t crv_len = 0;
+		size_t n = 0;
+
+		crv_len = EC_get_builtin_curves(NULL, 0);
+
+		curves = OPENSSL_malloc((int)(sizeof(EC_builtin_curve) * crv_len));
+
+		if (curves == NULL)
+			goto end;
+
+		if (!EC_get_builtin_curves(curves, crv_len))
+			{
+			OPENSSL_free(curves);
+			goto end;
+			}
+
+		
+		for (n = 0; n < crv_len; n++)
+			{
+			const char *comment;
+			const char *sname;
+			comment = curves[n].comment;
+			sname   = OBJ_nid2sn(curves[n].nid);
+			if (comment == NULL)
+				comment = "CURVE DESCRIPTION NOT AVAILABLE";
+			if (sname == NULL)
+				sname = "";
+
+			BIO_printf(out, "  %-10s: ", sname);
+			BIO_printf(out, "%s\n", comment);
+			} 
+
+		OPENSSL_free(curves);
+		ret = 0;
+		goto end;
+		}
+
+	if (curve_name != NULL)
+		{
+		int nid;
+
+		/* workaround for the SECG curve names secp192r1
+		 * and secp256r1 (which are the same as the curves
+		 * prime192v1 and prime256v1 defined in X9.62)
+		 */
+		if (!strcmp(curve_name, "secp192r1"))
+			{
+			BIO_printf(bio_err, "using curve name prime192v1 "
+				"instead of secp192r1\n");
+			nid = NID_X9_62_prime192v1;
+			}
+		else if (!strcmp(curve_name, "secp256r1"))
+			{
+			BIO_printf(bio_err, "using curve name prime256v1 "
+				"instead of secp256r1\n");
+			nid = NID_X9_62_prime256v1;
+			}
+		else
+			nid = OBJ_sn2nid(curve_name);
+	
+		if (nid == 0)
+			{
+			BIO_printf(bio_err, "unknown curve name (%s)\n", 
+				curve_name);
+			goto end;
+			}
+
+		group = EC_GROUP_new_by_curve_name(nid);
+		if (group == NULL)
+			{
+			BIO_printf(bio_err, "unable to create curve (%s)\n", 
+				curve_name);
+			goto end;
+			}
+		EC_GROUP_set_asn1_flag(group, asn1_flag);
+		EC_GROUP_set_point_conversion_form(group, form);
+		}
+	else if (informat == FORMAT_ASN1)
+		{
+		group = d2i_ECPKParameters_bio(in, NULL);
+		}
+	else if (informat == FORMAT_PEM)
+		{
+		group = PEM_read_bio_ECPKParameters(in,NULL,NULL,NULL);
+		}
+	else
+		{
+		BIO_printf(bio_err, "bad input format specified\n");
+		goto end;
+		}
+
+	if (group == NULL)
+		{
+		BIO_printf(bio_err, 
+			"unable to load elliptic curve parameters\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (new_form)
+		EC_GROUP_set_point_conversion_form(group, form);
+
+	if (new_asn1_flag)
+		EC_GROUP_set_asn1_flag(group, asn1_flag);
+
+	if (no_seed)
+		{
+		EC_GROUP_set_seed(group, NULL, 0);
+		}
+
+	if (text)
+		{
+		if (!ECPKParameters_print(out, group, 0))
+			goto end;
+		}
+
+	if (check)
+		{
+		if (group == NULL)
+			BIO_printf(bio_err, "no elliptic curve parameters\n");
+		BIO_printf(bio_err, "checking elliptic curve parameters: ");
+		if (!EC_GROUP_check(group, NULL))
+			{
+			BIO_printf(bio_err, "failed\n");
+			ERR_print_errors(bio_err);
+			}
+		else
+			BIO_printf(bio_err, "ok\n");
+			
+		}
+
+	if (C)
+		{
+		size_t	buf_len = 0, tmp_len = 0;
+		const EC_POINT *point;
+		int	is_prime, len = 0;
+		const EC_METHOD *meth = EC_GROUP_method_of(group);
+
+		if ((ec_p = BN_new()) == NULL || (ec_a = BN_new()) == NULL ||
+		    (ec_b = BN_new()) == NULL || (ec_gen = BN_new()) == NULL ||
+		    (ec_order = BN_new()) == NULL || 
+		    (ec_cofactor = BN_new()) == NULL )
+			{
+			perror("OPENSSL_malloc");
+			goto end;
+			}
+
+		is_prime = (EC_METHOD_get_field_type(meth) == 
+			NID_X9_62_prime_field);
+
+		if (is_prime)
+			{
+			if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a,
+				ec_b, NULL))
+				goto end;
+			}
+		else
+			{
+			/* TODO */
+			goto end;
+			}
+
+		if ((point = EC_GROUP_get0_generator(group)) == NULL)
+			goto end;
+		if (!EC_POINT_point2bn(group, point, 
+			EC_GROUP_get_point_conversion_form(group), ec_gen, 
+			NULL))
+			goto end;
+		if (!EC_GROUP_get_order(group, ec_order, NULL))
+			goto end;
+		if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL))
+			goto end;
+
+		if (!ec_p || !ec_a || !ec_b || !ec_gen || 
+			!ec_order || !ec_cofactor)
+			goto end;
+
+		len = BN_num_bits(ec_order);
+
+		if ((tmp_len = (size_t)BN_num_bytes(ec_p)) > buf_len)
+			buf_len = tmp_len;
+		if ((tmp_len = (size_t)BN_num_bytes(ec_a)) > buf_len)
+			buf_len = tmp_len;
+		if ((tmp_len = (size_t)BN_num_bytes(ec_b)) > buf_len)
+			buf_len = tmp_len;
+		if ((tmp_len = (size_t)BN_num_bytes(ec_gen)) > buf_len)
+			buf_len = tmp_len;
+		if ((tmp_len = (size_t)BN_num_bytes(ec_order)) > buf_len)
+			buf_len = tmp_len;
+		if ((tmp_len = (size_t)BN_num_bytes(ec_cofactor)) > buf_len)
+			buf_len = tmp_len;
+
+		buffer = (unsigned char *)OPENSSL_malloc(buf_len);
+
+		if (buffer == NULL)
+			{
+			perror("OPENSSL_malloc");
+			goto end;
+			}
+
+		ecparam_print_var(out, ec_p, "ec_p", len, buffer);
+		ecparam_print_var(out, ec_a, "ec_a", len, buffer);
+		ecparam_print_var(out, ec_b, "ec_b", len, buffer);
+		ecparam_print_var(out, ec_gen, "ec_gen", len, buffer);
+		ecparam_print_var(out, ec_order, "ec_order", len, buffer);
+		ecparam_print_var(out, ec_cofactor, "ec_cofactor", len, 
+			buffer);
+
+		BIO_printf(out, "\n\n");
+
+		BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n\t{\n", len);
+		BIO_printf(out, "\tint ok=0;\n");
+		BIO_printf(out, "\tEC_GROUP *group = NULL;\n");
+		BIO_printf(out, "\tEC_POINT *point = NULL;\n");
+		BIO_printf(out, "\tBIGNUM   *tmp_1 = NULL, *tmp_2 = NULL, "
+				"*tmp_3 = NULL;\n\n");
+		BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_p_%d, "
+				"sizeof(ec_p_%d), NULL)) == NULL)\n\t\t"
+				"goto err;\n", len, len);
+		BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_a_%d, "
+				"sizeof(ec_a_%d), NULL)) == NULL)\n\t\t"
+				"goto err;\n", len, len);
+		BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_b_%d, "
+				"sizeof(ec_b_%d), NULL)) == NULL)\n\t\t"
+				"goto err;\n", len, len);
+		if (is_prime)
+			{
+			BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_"
+				"GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)"
+				"\n\t\tgoto err;\n\n");
+			}
+		else
+			{
+			/* TODO */
+			goto end;
+			}
+		BIO_printf(out, "\t/* build generator */\n");
+		BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_gen_%d, "
+				"sizeof(ec_gen_%d), tmp_1)) == NULL)"
+				"\n\t\tgoto err;\n", len, len);
+		BIO_printf(out, "\tpoint = EC_POINT_bn2point(group, tmp_1, "
+				"NULL, NULL);\n");
+		BIO_printf(out, "\tif (point == NULL)\n\t\tgoto err;\n");
+		BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_order_%d, "
+				"sizeof(ec_order_%d), tmp_2)) == NULL)"
+				"\n\t\tgoto err;\n", len, len);
+		BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_cofactor_%d, "
+				"sizeof(ec_cofactor_%d), tmp_3)) == NULL)"
+				"\n\t\tgoto err;\n", len, len);
+		BIO_printf(out, "\tif (!EC_GROUP_set_generator(group, point,"
+				" tmp_2, tmp_3))\n\t\tgoto err;\n");
+		BIO_printf(out, "\n\tok=1;\n");
+		BIO_printf(out, "err:\n");
+		BIO_printf(out, "\tif (tmp_1)\n\t\tBN_free(tmp_1);\n");
+		BIO_printf(out, "\tif (tmp_2)\n\t\tBN_free(tmp_2);\n");
+		BIO_printf(out, "\tif (tmp_3)\n\t\tBN_free(tmp_3);\n");
+		BIO_printf(out, "\tif (point)\n\t\tEC_POINT_free(point);\n");
+		BIO_printf(out, "\tif (!ok)\n");
+		BIO_printf(out, "\t\t{\n");
+		BIO_printf(out, "\t\tEC_GROUP_free(group);\n");
+		BIO_printf(out, "\t\tgroup = NULL;\n");
+		BIO_printf(out, "\t\t}\n");
+		BIO_printf(out, "\treturn(group);\n\t}\n");
+	}
+
+	if (!noout)
+		{
+		if (outformat == FORMAT_ASN1)
+			i = i2d_ECPKParameters_bio(out, group);
+		else if (outformat == FORMAT_PEM)
+			i = PEM_write_bio_ECPKParameters(out, group);
+		else	
+			{
+			BIO_printf(bio_err,"bad output format specified for"
+				" outfile\n");
+			goto end;
+			}
+		if (!i)
+			{
+			BIO_printf(bio_err, "unable to write elliptic "
+				"curve parameters\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+	
+	if (need_rand)
+		{
+		app_RAND_load_file(NULL, bio_err, (inrand != NULL));
+		if (inrand != NULL)
+			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+				app_RAND_load_files(inrand));
+		}
+
+	if (genkey)
+		{
+		EC_KEY *eckey = EC_KEY_new();
+
+		if (eckey == NULL)
+			goto end;
+
+		assert(need_rand);
+
+		if (EC_KEY_set_group(eckey, group) == 0)
+			goto end;
+		
+		if (!EC_KEY_generate_key(eckey))
+			{
+			EC_KEY_free(eckey);
+			goto end;
+			}
+		if (outformat == FORMAT_ASN1)
+			i = i2d_ECPrivateKey_bio(out, eckey);
+		else if (outformat == FORMAT_PEM)
+			i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
+				NULL, 0, NULL, NULL);
+		else	
+			{
+			BIO_printf(bio_err, "bad output format specified "
+				"for outfile\n");
+			EC_KEY_free(eckey);
+			goto end;
+			}
+		EC_KEY_free(eckey);
+		}
+
+	if (need_rand)
+		app_RAND_write_file(NULL, bio_err);
+
+	ret=0;
+end:
+	if (ec_p)
+		BN_free(ec_p);
+	if (ec_a)
+		BN_free(ec_a);
+	if (ec_b)
+		BN_free(ec_b);
+	if (ec_gen)
+		BN_free(ec_gen);
+	if (ec_order)
+		BN_free(ec_order);
+	if (ec_cofactor)
+		BN_free(ec_cofactor);
+	if (buffer)
+		OPENSSL_free(buffer);
+	if (in != NULL)
+		BIO_free(in);
+	if (out != NULL)
+		BIO_free_all(out);
+	if (group != NULL)
+		EC_GROUP_free(group);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+}
+
+static int ecparam_print_var(BIO *out, BIGNUM *in, const char *var,
+	int len, unsigned char *buffer)
+	{
+	BIO_printf(out, "static unsigned char %s_%d[] = {", var, len);
+	if (BN_is_zero(in))
+		BIO_printf(out, "\n\t0x00");
+	else 
+		{
+		int i, l;
+
+		l = BN_bn2bin(in, buffer);
+		for (i=0; i<l-1; i++)
+			{
+			if ((i%12) == 0) 
+				BIO_printf(out, "\n\t");
+			BIO_printf(out, "0x%02X,", buffer[i]);
+			}
+		if ((i%12) == 0) 
+			BIO_printf(out, "\n\t");
+		BIO_printf(out, "0x%02X", buffer[i]);
+		}
+	BIO_printf(out, "\n\t};\n\n");
+	return 1;
+	}
+#else /* !OPENSSL_NO_EC */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/apps/enc.c b/openssl/apps/enc.c
new file mode 100644
index 0000000..076225c
--- /dev/null
+++ b/openssl/apps/enc.c
@@ -0,0 +1,724 @@
+/* apps/enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/rand.h>
+#include <openssl/pem.h>
+#include <openssl/comp.h>
+#include <ctype.h>
+
+int set_hex(char *in,unsigned char *out,int size);
+#undef SIZE
+#undef BSIZE
+#undef PROG
+
+#define SIZE	(512)
+#define BSIZE	(8*1024)
+#define	PROG	enc_main
+
+static void show_ciphers(const OBJ_NAME *name,void *bio_)
+	{
+	BIO *bio=bio_;
+	static int n;
+
+	if(!islower((unsigned char)*name->name))
+		return;
+
+	BIO_printf(bio,"-%-25s",name->name);
+	if(++n == 3)
+		{
+		BIO_printf(bio,"\n");
+		n=0;
+		}
+	else
+		BIO_printf(bio," ");
+	}
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	static const char magic[]="Salted__";
+	char mbuf[sizeof magic-1];
+	char *strbuf=NULL;
+	unsigned char *buff=NULL,*bufsize=NULL;
+	int bsize=BSIZE,verbose=0;
+	int ret=1,inl;
+	int nopad = 0;
+	unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
+	unsigned char salt[PKCS5_SALT_LEN];
+	char *str=NULL, *passarg = NULL, *pass = NULL;
+	char *hkey=NULL,*hiv=NULL,*hsalt = NULL;
+	char *md=NULL;
+	int enc=1,printkey=0,i,base64=0;
+#ifdef ZLIB
+	int do_zlib=0;
+	BIO *bzl = NULL;
+#endif
+	int debug=0,olb64=0,nosalt=0;
+	const EVP_CIPHER *cipher=NULL,*c;
+	EVP_CIPHER_CTX *ctx = NULL;
+	char *inf=NULL,*outf=NULL;
+	BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL;
+#define PROG_NAME_SIZE  39
+	char pname[PROG_NAME_SIZE+1];
+#ifndef OPENSSL_NO_ENGINE
+	char *engine = NULL;
+#endif
+	const EVP_MD *dgst=NULL;
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	/* first check the program name */
+	program_name(argv[0],pname,sizeof pname);
+	if (strcmp(pname,"base64") == 0)
+		base64=1;
+#ifdef ZLIB
+	if (strcmp(pname,"zlib") == 0)
+		do_zlib=1;
+#endif
+
+	cipher=EVP_get_cipherbyname(pname);
+#ifdef ZLIB
+	if (!do_zlib && !base64 && (cipher == NULL)
+				&& (strcmp(pname,"enc") != 0))
+#else
+	if (!base64 && (cipher == NULL) && (strcmp(pname,"enc") != 0))
+#endif
+		{
+		BIO_printf(bio_err,"%s is an unknown cipher\n",pname);
+		goto bad;
+		}
+
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if	(strcmp(*argv,"-e") == 0)
+			enc=1;
+		else if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			inf= *(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outf= *(++argv);
+			}
+		else if (strcmp(*argv,"-pass") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passarg= *(++argv);
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*argv,"-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine= *(++argv);
+			}
+#endif
+		else if	(strcmp(*argv,"-d") == 0)
+			enc=0;
+		else if	(strcmp(*argv,"-p") == 0)
+			printkey=1;
+		else if	(strcmp(*argv,"-v") == 0)
+			verbose=1;
+		else if	(strcmp(*argv,"-nopad") == 0)
+			nopad=1;
+		else if	(strcmp(*argv,"-salt") == 0)
+			nosalt=0;
+		else if	(strcmp(*argv,"-nosalt") == 0)
+			nosalt=1;
+		else if	(strcmp(*argv,"-debug") == 0)
+			debug=1;
+		else if	(strcmp(*argv,"-P") == 0)
+			printkey=2;
+		else if	(strcmp(*argv,"-A") == 0)
+			olb64=1;
+		else if	(strcmp(*argv,"-a") == 0)
+			base64=1;
+		else if	(strcmp(*argv,"-base64") == 0)
+			base64=1;
+#ifdef ZLIB
+		else if	(strcmp(*argv,"-z") == 0)
+			do_zlib=1;
+#endif
+		else if (strcmp(*argv,"-bufsize") == 0)
+			{
+			if (--argc < 1) goto bad;
+			bufsize=(unsigned char *)*(++argv);
+			}
+		else if (strcmp(*argv,"-k") == 0)
+			{
+			if (--argc < 1) goto bad;
+			str= *(++argv);
+			}
+		else if (strcmp(*argv,"-kfile") == 0)
+			{
+			static char buf[128];
+			FILE *infile;
+			char *file;
+
+			if (--argc < 1) goto bad;
+			file= *(++argv);
+			infile=fopen(file,"r");
+			if (infile == NULL)
+				{
+				BIO_printf(bio_err,"unable to read key from '%s'\n",
+					file);
+				goto bad;
+				}
+			buf[0]='\0';
+			if (!fgets(buf,sizeof buf,infile))
+				{
+				BIO_printf(bio_err,"unable to read key from '%s'\n",
+					file);
+				goto bad;
+				}
+			fclose(infile);
+			i=strlen(buf);
+			if ((i > 0) &&
+				((buf[i-1] == '\n') || (buf[i-1] == '\r')))
+				buf[--i]='\0';
+			if ((i > 0) &&
+				((buf[i-1] == '\n') || (buf[i-1] == '\r')))
+				buf[--i]='\0';
+			if (i < 1)
+				{
+				BIO_printf(bio_err,"zero length password\n");
+				goto bad;
+				}
+			str=buf;
+			}
+		else if (strcmp(*argv,"-K") == 0)
+			{
+			if (--argc < 1) goto bad;
+			hkey= *(++argv);
+			}
+		else if (strcmp(*argv,"-S") == 0)
+			{
+			if (--argc < 1) goto bad;
+			hsalt= *(++argv);
+			}
+		else if (strcmp(*argv,"-iv") == 0)
+			{
+			if (--argc < 1) goto bad;
+			hiv= *(++argv);
+			}
+		else if (strcmp(*argv,"-md") == 0)
+			{
+			if (--argc < 1) goto bad;
+			md= *(++argv);
+			}
+		else if	((argv[0][0] == '-') &&
+			((c=EVP_get_cipherbyname(&(argv[0][1]))) != NULL))
+			{
+			cipher=c;
+			}
+		else if (strcmp(*argv,"-none") == 0)
+			cipher=NULL;
+		else
+			{
+			BIO_printf(bio_err,"unknown option '%s'\n",*argv);
+bad:
+			BIO_printf(bio_err,"options are\n");
+			BIO_printf(bio_err,"%-14s input file\n","-in <file>");
+			BIO_printf(bio_err,"%-14s output file\n","-out <file>");
+			BIO_printf(bio_err,"%-14s pass phrase source\n","-pass <arg>");
+			BIO_printf(bio_err,"%-14s encrypt\n","-e");
+			BIO_printf(bio_err,"%-14s decrypt\n","-d");
+			BIO_printf(bio_err,"%-14s base64 encode/decode, depending on encryption flag\n","-a/-base64");
+			BIO_printf(bio_err,"%-14s passphrase is the next argument\n","-k");
+			BIO_printf(bio_err,"%-14s passphrase is the first line of the file argument\n","-kfile");
+			BIO_printf(bio_err,"%-14s the next argument is the md to use to create a key\n","-md");
+			BIO_printf(bio_err,"%-14s   from a passphrase.  One of md2, md5, sha or sha1\n","");
+			BIO_printf(bio_err,"%-14s salt in hex is the next argument\n","-S");
+			BIO_printf(bio_err,"%-14s key/iv in hex is the next argument\n","-K/-iv");
+			BIO_printf(bio_err,"%-14s print the iv/key (then exit if -P)\n","-[pP]");
+			BIO_printf(bio_err,"%-14s buffer size\n","-bufsize <n>");
+			BIO_printf(bio_err,"%-14s disable standard block padding\n","-nopad");
+#ifndef OPENSSL_NO_ENGINE
+			BIO_printf(bio_err,"%-14s use engine e, possibly a hardware device.\n","-engine e");
+#endif
+
+			BIO_printf(bio_err,"Cipher Types\n");
+			OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
+					       show_ciphers,
+					       bio_err);
+			BIO_printf(bio_err,"\n");
+
+			goto end;
+			}
+		argc--;
+		argv++;
+		}
+
+#ifndef OPENSSL_NO_ENGINE
+        setup_engine(bio_err, engine, 0);
+#endif
+
+	if (md && (dgst=EVP_get_digestbyname(md)) == NULL)
+		{
+		BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
+		goto end;
+		}
+
+	if (dgst == NULL)
+		{
+		dgst = EVP_md5();
+		}
+
+	if (bufsize != NULL)
+		{
+		unsigned long n;
+
+		for (n=0; *bufsize; bufsize++)
+			{
+			i= *bufsize;
+			if ((i <= '9') && (i >= '0'))
+				n=n*10+i-'0';
+			else if (i == 'k')
+				{
+				n*=1024;
+				bufsize++;
+				break;
+				}
+			}
+		if (*bufsize != '\0')
+			{
+			BIO_printf(bio_err,"invalid 'bufsize' specified.\n");
+			goto end;
+			}
+
+		/* It must be large enough for a base64 encoded line */
+		if (base64 && n < 80) n=80;
+
+		bsize=(int)n;
+		if (verbose) BIO_printf(bio_err,"bufsize=%d\n",bsize);
+		}
+
+	strbuf=OPENSSL_malloc(SIZE);
+	buff=(unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize));
+	if ((buff == NULL) || (strbuf == NULL))
+		{
+		BIO_printf(bio_err,"OPENSSL_malloc failure %ld\n",(long)EVP_ENCODE_LENGTH(bsize));
+		goto end;
+		}
+
+	in=BIO_new(BIO_s_file());
+	out=BIO_new(BIO_s_file());
+	if ((in == NULL) || (out == NULL))
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+	if (debug)
+		{
+		BIO_set_callback(in,BIO_debug_callback);
+		BIO_set_callback(out,BIO_debug_callback);
+		BIO_set_callback_arg(in,(char *)bio_err);
+		BIO_set_callback_arg(out,(char *)bio_err);
+		}
+
+	if (inf == NULL)
+	        {
+#ifndef OPENSSL_NO_SETVBUF_IONBF
+		if (bufsize != NULL)
+			setvbuf(stdin, (char *)NULL, _IONBF, 0);
+#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
+		BIO_set_fp(in,stdin,BIO_NOCLOSE);
+	        }
+	else
+		{
+		if (BIO_read_filename(in,inf) <= 0)
+			{
+			perror(inf);
+			goto end;
+			}
+		}
+
+	if(!str && passarg) {
+		if(!app_passwd(bio_err, passarg, NULL, &pass, NULL)) {
+			BIO_printf(bio_err, "Error getting password\n");
+			goto end;
+		}
+		str = pass;
+	}
+
+	if ((str == NULL) && (cipher != NULL) && (hkey == NULL))
+		{
+		for (;;)
+			{
+			char buf[200];
+
+			BIO_snprintf(buf,sizeof buf,"enter %s %s password:",
+				     OBJ_nid2ln(EVP_CIPHER_nid(cipher)),
+				     (enc)?"encryption":"decryption");
+			strbuf[0]='\0';
+			i=EVP_read_pw_string((char *)strbuf,SIZE,buf,enc);
+			if (i == 0)
+				{
+				if (strbuf[0] == '\0')
+					{
+					ret=1;
+					goto end;
+					}
+				str=strbuf;
+				break;
+				}
+			if (i < 0)
+				{
+				BIO_printf(bio_err,"bad password read\n");
+				goto end;
+				}
+			}
+		}
+
+
+	if (outf == NULL)
+		{
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifndef OPENSSL_NO_SETVBUF_IONBF
+		if (bufsize != NULL)
+			setvbuf(stdout, (char *)NULL, _IONBF, 0);
+#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+		}
+	else
+		{
+		if (BIO_write_filename(out,outf) <= 0)
+			{
+			perror(outf);
+			goto end;
+			}
+		}
+
+	rbio=in;
+	wbio=out;
+
+#ifdef ZLIB
+
+	if (do_zlib)
+		{
+		if ((bzl=BIO_new(BIO_f_zlib())) == NULL)
+			goto end;
+		if (enc)
+			wbio=BIO_push(bzl,wbio);
+		else
+			rbio=BIO_push(bzl,rbio);
+		}
+#endif
+
+	if (base64)
+		{
+		if ((b64=BIO_new(BIO_f_base64())) == NULL)
+			goto end;
+		if (debug)
+			{
+			BIO_set_callback(b64,BIO_debug_callback);
+			BIO_set_callback_arg(b64,(char *)bio_err);
+			}
+		if (olb64)
+			BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
+		if (enc)
+			wbio=BIO_push(b64,wbio);
+		else
+			rbio=BIO_push(b64,rbio);
+		}
+
+	if (cipher != NULL)
+		{
+		/* Note that str is NULL if a key was passed on the command
+		 * line, so we get no salt in that case. Is this a bug?
+		 */
+		if (str != NULL)
+			{
+			/* Salt handling: if encrypting generate a salt and
+			 * write to output BIO. If decrypting read salt from
+			 * input BIO.
+			 */
+			unsigned char *sptr;
+			if(nosalt) sptr = NULL;
+			else {
+				if(enc) {
+					if(hsalt) {
+						if(!set_hex(hsalt,salt,sizeof salt)) {
+							BIO_printf(bio_err,
+								"invalid hex salt value\n");
+							goto end;
+						}
+					} else if (RAND_pseudo_bytes(salt, sizeof salt) < 0)
+						goto end;
+					/* If -P option then don't bother writing */
+					if((printkey != 2)
+					   && (BIO_write(wbio,magic,
+							 sizeof magic-1) != sizeof magic-1
+					       || BIO_write(wbio,
+							    (char *)salt,
+							    sizeof salt) != sizeof salt)) {
+						BIO_printf(bio_err,"error writing output file\n");
+						goto end;
+					}
+				} else if(BIO_read(rbio,mbuf,sizeof mbuf) != sizeof mbuf
+					  || BIO_read(rbio,
+						      (unsigned char *)salt,
+				    sizeof salt) != sizeof salt) {
+					BIO_printf(bio_err,"error reading input file\n");
+					goto end;
+				} else if(memcmp(mbuf,magic,sizeof magic-1)) {
+				    BIO_printf(bio_err,"bad magic number\n");
+				    goto end;
+				}
+
+				sptr = salt;
+			}
+
+			EVP_BytesToKey(cipher,dgst,sptr,
+				(unsigned char *)str,
+				strlen(str),1,key,iv);
+			/* zero the complete buffer or the string
+			 * passed from the command line
+			 * bug picked up by
+			 * Larry J. Hughes Jr. <hughes@indiana.edu> */
+			if (str == strbuf)
+				OPENSSL_cleanse(str,SIZE);
+			else
+				OPENSSL_cleanse(str,strlen(str));
+			}
+		if ((hiv != NULL) && !set_hex(hiv,iv,sizeof iv))
+			{
+			BIO_printf(bio_err,"invalid hex iv value\n");
+			goto end;
+			}
+		if ((hiv == NULL) && (str == NULL)
+		    && EVP_CIPHER_iv_length(cipher) != 0)
+			{
+			/* No IV was explicitly set and no IV was generated
+			 * during EVP_BytesToKey. Hence the IV is undefined,
+			 * making correct decryption impossible. */
+			BIO_printf(bio_err, "iv undefined\n");
+			goto end;
+			}
+		if ((hkey != NULL) && !set_hex(hkey,key,sizeof key))
+			{
+			BIO_printf(bio_err,"invalid hex key value\n");
+			goto end;
+			}
+
+		if ((benc=BIO_new(BIO_f_cipher())) == NULL)
+			goto end;
+
+		/* Since we may be changing parameters work on the encryption
+		 * context rather than calling BIO_set_cipher().
+		 */
+
+		BIO_get_cipher_ctx(benc, &ctx);
+		if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc))
+			{
+			BIO_printf(bio_err, "Error setting cipher %s\n",
+				EVP_CIPHER_name(cipher));
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+
+		if (nopad)
+			EVP_CIPHER_CTX_set_padding(ctx, 0);
+
+		if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc))
+			{
+			BIO_printf(bio_err, "Error setting cipher %s\n",
+				EVP_CIPHER_name(cipher));
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+
+		if (debug)
+			{
+			BIO_set_callback(benc,BIO_debug_callback);
+			BIO_set_callback_arg(benc,(char *)bio_err);
+			}
+
+		if (printkey)
+			{
+			if (!nosalt)
+				{
+				printf("salt=");
+				for (i=0; i<(int)sizeof(salt); i++)
+					printf("%02X",salt[i]);
+				printf("\n");
+				}
+			if (cipher->key_len > 0)
+				{
+				printf("key=");
+				for (i=0; i<cipher->key_len; i++)
+					printf("%02X",key[i]);
+				printf("\n");
+				}
+			if (cipher->iv_len > 0)
+				{
+				printf("iv =");
+				for (i=0; i<cipher->iv_len; i++)
+					printf("%02X",iv[i]);
+				printf("\n");
+				}
+			if (printkey == 2)
+				{
+				ret=0;
+				goto end;
+				}
+			}
+		}
+
+	/* Only encrypt/decrypt as we write the file */
+	if (benc != NULL)
+		wbio=BIO_push(benc,wbio);
+
+	for (;;)
+		{
+		inl=BIO_read(rbio,(char *)buff,bsize);
+		if (inl <= 0) break;
+		if (BIO_write(wbio,(char *)buff,inl) != inl)
+			{
+			BIO_printf(bio_err,"error writing output file\n");
+			goto end;
+			}
+		}
+	if (!BIO_flush(wbio))
+		{
+		BIO_printf(bio_err,"bad decrypt\n");
+		goto end;
+		}
+
+	ret=0;
+	if (verbose)
+		{
+		BIO_printf(bio_err,"bytes read   :%8ld\n",BIO_number_read(in));
+		BIO_printf(bio_err,"bytes written:%8ld\n",BIO_number_written(out));
+		}
+end:
+	ERR_print_errors(bio_err);
+	if (strbuf != NULL) OPENSSL_free(strbuf);
+	if (buff != NULL) OPENSSL_free(buff);
+	if (in != NULL) BIO_free(in);
+	if (out != NULL) BIO_free_all(out);
+	if (benc != NULL) BIO_free(benc);
+	if (b64 != NULL) BIO_free(b64);
+#ifdef ZLIB
+	if (bzl != NULL) BIO_free(bzl);
+#endif
+	if(pass) OPENSSL_free(pass);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
+int set_hex(char *in, unsigned char *out, int size)
+	{
+	int i,n;
+	unsigned char j;
+
+	n=strlen(in);
+	if (n > (size*2))
+		{
+		BIO_printf(bio_err,"hex string is too long\n");
+		return(0);
+		}
+	memset(out,0,size);
+	for (i=0; i<n; i++)
+		{
+		j=(unsigned char)*in;
+		*(in++)='\0';
+		if (j == 0) break;
+		if ((j >= '0') && (j <= '9'))
+			j-='0';
+		else if ((j >= 'A') && (j <= 'F'))
+			j=j-'A'+10;
+		else if ((j >= 'a') && (j <= 'f'))
+			j=j-'a'+10;
+		else
+			{
+			BIO_printf(bio_err,"non-hex digit\n");
+			return(0);
+			}
+		if (i&1)
+			out[i/2]|=j;
+		else
+			out[i/2]=(j<<4);
+		}
+	return(1);
+	}
diff --git a/openssl/apps/engine.c b/openssl/apps/engine.c
new file mode 100644
index 0000000..9a02943
--- /dev/null
+++ b/openssl/apps/engine.c
@@ -0,0 +1,549 @@
+/* apps/engine.c -*- mode: C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte <richard@levitte.org> for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef OPENSSL_NO_STDIO
+#define APPS_WIN16
+#endif
+#include "apps.h"
+#include <openssl/err.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#include <openssl/ssl.h>
+
+#undef PROG
+#define PROG	engine_main
+
+static const char *engine_usage[]={
+"usage: engine opts [engine ...]\n",
+" -v[v[v[v]]] - verbose mode, for each engine, list its 'control commands'\n",
+"               -vv will additionally display each command's description\n",
+"               -vvv will also add the input flags for each command\n",
+"               -vvvv will also show internal input flags\n",
+" -c          - for each engine, also list the capabilities\n",
+" -t[t]       - for each engine, check that they are really available\n",
+"               -tt will display error trace for unavailable engines\n",
+" -pre <cmd>  - runs command 'cmd' against the ENGINE before any attempts\n",
+"               to load it (if -t is used)\n",
+" -post <cmd> - runs command 'cmd' against the ENGINE after loading it\n",
+"               (only used if -t is also provided)\n",
+" NB: -pre and -post will be applied to all ENGINEs supplied on the command\n",
+" line, or all supported ENGINEs if none are specified.\n",
+" Eg. '-pre \"SO_PATH:/lib/libdriver.so\"' calls command \"SO_PATH\" with\n",
+" argument \"/lib/libdriver.so\".\n",
+NULL
+};
+
+static void identity(char *ptr)
+	{
+	return;
+	}
+
+static int append_buf(char **buf, const char *s, int *size, int step)
+	{
+	int l = strlen(s);
+
+	if (*buf == NULL)
+		{
+		*size = step;
+		*buf = OPENSSL_malloc(*size);
+		if (*buf == NULL)
+			return 0;
+		**buf = '\0';
+		}
+
+	if (**buf != '\0')
+		l += 2;		/* ", " */
+
+	if (strlen(*buf) + strlen(s) >= (unsigned int)*size)
+		{
+		*size += step;
+		*buf = OPENSSL_realloc(*buf, *size);
+		}
+
+	if (*buf == NULL)
+		return 0;
+
+	if (**buf != '\0')
+		BUF_strlcat(*buf, ", ", *size);
+	BUF_strlcat(*buf, s, *size);
+
+	return 1;
+	}
+
+static int util_flags(BIO *bio_out, unsigned int flags, const char *indent)
+	{
+	int started = 0, err = 0;
+	/* Indent before displaying input flags */
+	BIO_printf(bio_out, "%s%s(input flags): ", indent, indent);
+	if(flags == 0)
+		{
+		BIO_printf(bio_out, "<no flags>\n");
+		return 1;
+		}
+        /* If the object is internal, mark it in a way that shows instead of
+         * having it part of all the other flags, even if it really is. */
+	if(flags & ENGINE_CMD_FLAG_INTERNAL)
+		{
+		BIO_printf(bio_out, "[Internal] ");
+		}
+
+	if(flags & ENGINE_CMD_FLAG_NUMERIC)
+		{
+		BIO_printf(bio_out, "NUMERIC");
+		started = 1;
+		}
+	/* Now we check that no combinations of the mutually exclusive NUMERIC,
+	 * STRING, and NO_INPUT flags have been used. Future flags that can be
+	 * OR'd together with these would need to added after these to preserve
+	 * the testing logic. */
+	if(flags & ENGINE_CMD_FLAG_STRING)
+		{
+		if(started)
+			{
+			BIO_printf(bio_out, "|");
+			err = 1;
+			}
+		BIO_printf(bio_out, "STRING");
+		started = 1;
+		}
+	if(flags & ENGINE_CMD_FLAG_NO_INPUT)
+		{
+		if(started)
+			{
+			BIO_printf(bio_out, "|");
+			err = 1;
+			}
+		BIO_printf(bio_out, "NO_INPUT");
+		started = 1;
+		}
+	/* Check for unknown flags */
+	flags = flags & ~ENGINE_CMD_FLAG_NUMERIC &
+			~ENGINE_CMD_FLAG_STRING &
+			~ENGINE_CMD_FLAG_NO_INPUT &
+			~ENGINE_CMD_FLAG_INTERNAL;
+	if(flags)
+		{
+		if(started) BIO_printf(bio_out, "|");
+		BIO_printf(bio_out, "<0x%04X>", flags);
+		}
+	if(err)
+		BIO_printf(bio_out, "  <illegal flags!>");
+	BIO_printf(bio_out, "\n");
+	return 1;
+	}
+
+static int util_verbose(ENGINE *e, int verbose, BIO *bio_out, const char *indent)
+	{
+	static const int line_wrap = 78;
+	int num;
+	int ret = 0;
+	char *name = NULL;
+	char *desc = NULL;
+	int flags;
+	int xpos = 0;
+	STACK_OF(OPENSSL_STRING) *cmds = NULL;
+	if(!ENGINE_ctrl(e, ENGINE_CTRL_HAS_CTRL_FUNCTION, 0, NULL, NULL) ||
+			((num = ENGINE_ctrl(e, ENGINE_CTRL_GET_FIRST_CMD_TYPE,
+					0, NULL, NULL)) <= 0))
+		{
+#if 0
+		BIO_printf(bio_out, "%s<no control commands>\n", indent);
+#endif
+		return 1;
+		}
+
+	cmds = sk_OPENSSL_STRING_new_null();
+
+	if(!cmds)
+		goto err;
+	do {
+		int len;
+		/* Get the command input flags */
+		if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num,
+					NULL, NULL)) < 0)
+			goto err;
+                if (!(flags & ENGINE_CMD_FLAG_INTERNAL) || verbose >= 4)
+                        {
+                        /* Get the command name */
+                        if((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_LEN_FROM_CMD, num,
+                                NULL, NULL)) <= 0)
+                                goto err;
+                        if((name = OPENSSL_malloc(len + 1)) == NULL)
+                                goto err;
+                        if(ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_FROM_CMD, num, name,
+                                NULL) <= 0)
+                                goto err;
+                        /* Get the command description */
+                        if((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_LEN_FROM_CMD, num,
+                                NULL, NULL)) < 0)
+                                goto err;
+                        if(len > 0)
+                                {
+                                if((desc = OPENSSL_malloc(len + 1)) == NULL)
+                                        goto err;
+                                if(ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_FROM_CMD, num, desc,
+                                        NULL) <= 0)
+                                        goto err;
+                                }
+                        /* Now decide on the output */
+                        if(xpos == 0)
+                                /* Do an indent */
+                                xpos = BIO_puts(bio_out, indent);
+                        else
+                                /* Otherwise prepend a ", " */
+                                xpos += BIO_printf(bio_out, ", ");
+                        if(verbose == 1)
+                                {
+                                /* We're just listing names, comma-delimited */
+                                if((xpos > (int)strlen(indent)) &&
+					(xpos + (int)strlen(name) > line_wrap))
+                                        {
+                                        BIO_printf(bio_out, "\n");
+                                        xpos = BIO_puts(bio_out, indent);
+                                        }
+                                xpos += BIO_printf(bio_out, "%s", name);
+                                }
+                        else
+                                {
+                                /* We're listing names plus descriptions */
+                                BIO_printf(bio_out, "%s: %s\n", name,
+                                        (desc == NULL) ? "<no description>" : desc);
+                                /* ... and sometimes input flags */
+                                if((verbose >= 3) && !util_flags(bio_out, flags,
+                                        indent))
+                                        goto err;
+                                xpos = 0;
+                                }
+                        }
+		OPENSSL_free(name); name = NULL;
+		if(desc) { OPENSSL_free(desc); desc = NULL; }
+		/* Move to the next command */
+		num = ENGINE_ctrl(e, ENGINE_CTRL_GET_NEXT_CMD_TYPE,
+					num, NULL, NULL);
+		} while(num > 0);
+	if(xpos > 0)
+		BIO_printf(bio_out, "\n");
+	ret = 1;
+err:
+	if(cmds) sk_OPENSSL_STRING_pop_free(cmds, identity);
+	if(name) OPENSSL_free(name);
+	if(desc) OPENSSL_free(desc);
+	return ret;
+	}
+
+static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds,
+			BIO *bio_out, const char *indent)
+	{
+	int loop, res, num = sk_OPENSSL_STRING_num(cmds);
+
+	if(num < 0)
+		{
+		BIO_printf(bio_out, "[Error]: internal stack error\n");
+		return;
+		}
+	for(loop = 0; loop < num; loop++)
+		{
+		char buf[256];
+		const char *cmd, *arg;
+		cmd = sk_OPENSSL_STRING_value(cmds, loop);
+		res = 1; /* assume success */
+		/* Check if this command has no ":arg" */
+		if((arg = strstr(cmd, ":")) == NULL)
+			{
+			if(!ENGINE_ctrl_cmd_string(e, cmd, NULL, 0))
+				res = 0;
+			}
+		else
+			{
+			if((int)(arg - cmd) > 254)
+				{
+				BIO_printf(bio_out,"[Error]: command name too long\n");
+				return;
+				}
+			memcpy(buf, cmd, (int)(arg - cmd));
+			buf[arg-cmd] = '\0';
+			arg++; /* Move past the ":" */
+			/* Call the command with the argument */
+			if(!ENGINE_ctrl_cmd_string(e, buf, arg, 0))
+				res = 0;
+			}
+		if(res)
+			BIO_printf(bio_out, "[Success]: %s\n", cmd);
+		else
+			{
+			BIO_printf(bio_out, "[Failure]: %s\n", cmd);
+			ERR_print_errors(bio_out);
+			}
+		}
+	}
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	int ret=1,i;
+	const char **pp;
+	int verbose=0, list_cap=0, test_avail=0, test_avail_noise = 0;
+	ENGINE *e;
+	STACK_OF(OPENSSL_STRING) *engines = sk_OPENSSL_STRING_new_null();
+	STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null();
+	STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null();
+	int badops=1;
+	BIO *bio_out=NULL;
+	const char *indent = "     ";
+
+	apps_startup();
+	SSL_load_error_strings();
+
+	if (bio_err == NULL)
+		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+	bio_out=BIO_new_fp(stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+	{
+	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+	bio_out = BIO_push(tmpbio, bio_out);
+	}
+#endif
+
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if (strncmp(*argv,"-v",2) == 0)
+			{
+			if(strspn(*argv + 1, "v") < strlen(*argv + 1))
+				goto skip_arg_loop;
+			if((verbose=strlen(*argv + 1)) > 4)
+				goto skip_arg_loop;
+			}
+		else if (strcmp(*argv,"-c") == 0)
+			list_cap=1;
+		else if (strncmp(*argv,"-t",2) == 0)
+			{
+			test_avail=1;
+			if(strspn(*argv + 1, "t") < strlen(*argv + 1))
+				goto skip_arg_loop;
+			if((test_avail_noise = strlen(*argv + 1) - 1) > 1)
+				goto skip_arg_loop;
+			}
+		else if (strcmp(*argv,"-pre") == 0)
+			{
+			argc--; argv++;
+			if (argc == 0)
+				goto skip_arg_loop;
+			sk_OPENSSL_STRING_push(pre_cmds,*argv);
+			}
+		else if (strcmp(*argv,"-post") == 0)
+			{
+			argc--; argv++;
+			if (argc == 0)
+				goto skip_arg_loop;
+			sk_OPENSSL_STRING_push(post_cmds,*argv);
+			}
+		else if ((strncmp(*argv,"-h",2) == 0) ||
+				(strcmp(*argv,"-?") == 0))
+			goto skip_arg_loop;
+		else
+			sk_OPENSSL_STRING_push(engines,*argv);
+		argc--;
+		argv++;
+		}
+	/* Looks like everything went OK */
+	badops = 0;
+skip_arg_loop:
+
+	if (badops)
+		{
+		for (pp=engine_usage; (*pp != NULL); pp++)
+			BIO_printf(bio_err,"%s",*pp);
+		goto end;
+		}
+
+	if (sk_OPENSSL_STRING_num(engines) == 0)
+		{
+		for(e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e))
+			{
+			sk_OPENSSL_STRING_push(engines,(char *)ENGINE_get_id(e));
+			}
+		}
+
+	for (i=0; i<sk_OPENSSL_STRING_num(engines); i++)
+		{
+		const char *id = sk_OPENSSL_STRING_value(engines,i);
+		if ((e = ENGINE_by_id(id)) != NULL)
+			{
+			const char *name = ENGINE_get_name(e);
+			/* Do "id" first, then "name". Easier to auto-parse. */
+			BIO_printf(bio_out, "(%s) %s\n", id, name);
+			util_do_cmds(e, pre_cmds, bio_out, indent);
+			if (strcmp(ENGINE_get_id(e), id) != 0)
+				{
+				BIO_printf(bio_out, "Loaded: (%s) %s\n",
+					ENGINE_get_id(e), ENGINE_get_name(e));
+				}
+			if (list_cap)
+				{
+				int cap_size = 256;
+				char *cap_buf = NULL;
+				int k,n;
+				const int *nids;
+				ENGINE_CIPHERS_PTR fn_c;
+				ENGINE_DIGESTS_PTR fn_d;
+				ENGINE_PKEY_METHS_PTR fn_pk;
+
+				if (ENGINE_get_RSA(e) != NULL
+					&& !append_buf(&cap_buf, "RSA",
+						&cap_size, 256))
+					goto end;
+				if (ENGINE_get_DSA(e) != NULL
+					&& !append_buf(&cap_buf, "DSA",
+						&cap_size, 256))
+					goto end;
+				if (ENGINE_get_DH(e) != NULL
+					&& !append_buf(&cap_buf, "DH",
+						&cap_size, 256))
+					goto end;
+				if (ENGINE_get_RAND(e) != NULL
+					&& !append_buf(&cap_buf, "RAND",
+						&cap_size, 256))
+					goto end;
+
+				fn_c = ENGINE_get_ciphers(e);
+				if(!fn_c) goto skip_ciphers;
+				n = fn_c(e, NULL, &nids, 0);
+				for(k=0 ; k < n ; ++k)
+					if(!append_buf(&cap_buf,
+						       OBJ_nid2sn(nids[k]),
+						       &cap_size, 256))
+						goto end;
+
+skip_ciphers:
+				fn_d = ENGINE_get_digests(e);
+				if(!fn_d) goto skip_digests;
+				n = fn_d(e, NULL, &nids, 0);
+				for(k=0 ; k < n ; ++k)
+					if(!append_buf(&cap_buf,
+						       OBJ_nid2sn(nids[k]),
+						       &cap_size, 256))
+						goto end;
+
+skip_digests:
+				fn_pk = ENGINE_get_pkey_meths(e);
+				if(!fn_pk) goto skip_pmeths;
+				n = fn_pk(e, NULL, &nids, 0);
+				for(k=0 ; k < n ; ++k)
+					if(!append_buf(&cap_buf,
+						       OBJ_nid2sn(nids[k]),
+						       &cap_size, 256))
+						goto end;
+skip_pmeths:
+				if (cap_buf && (*cap_buf != '\0'))
+					BIO_printf(bio_out, " [%s]\n", cap_buf);
+
+				OPENSSL_free(cap_buf);
+				}
+			if(test_avail)
+				{
+				BIO_printf(bio_out, "%s", indent);
+				if (ENGINE_init(e))
+					{
+					BIO_printf(bio_out, "[ available ]\n");
+					util_do_cmds(e, post_cmds, bio_out, indent);
+					ENGINE_finish(e);
+					}
+				else
+					{
+					BIO_printf(bio_out, "[ unavailable ]\n");
+					if(test_avail_noise)
+						ERR_print_errors_fp(stdout);
+					ERR_clear_error();
+					}
+				}
+			if((verbose > 0) && !util_verbose(e, verbose, bio_out, indent))
+				goto end;
+			ENGINE_free(e);
+			}
+		else
+			ERR_print_errors(bio_err);
+		}
+
+	ret=0;
+end:
+
+	ERR_print_errors(bio_err);
+	sk_OPENSSL_STRING_pop_free(engines, identity);
+	sk_OPENSSL_STRING_pop_free(pre_cmds, identity);
+	sk_OPENSSL_STRING_pop_free(post_cmds, identity);
+	if (bio_out != NULL) BIO_free_all(bio_out);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+#else
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/apps/errstr.c b/openssl/apps/errstr.c
new file mode 100644
index 0000000..fe3b980
--- /dev/null
+++ b/openssl/apps/errstr.c
@@ -0,0 +1,128 @@
+/* apps/errstr.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/lhash.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+#undef PROG
+#define PROG	errstr_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	int i,ret=0;
+	char buf[256];
+	unsigned long l;
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	SSL_load_error_strings();
+
+	if ((argc > 1) && (strcmp(argv[1],"-stats") == 0))
+		{
+		BIO *out=NULL;
+
+		out=BIO_new(BIO_s_file());
+		if ((out != NULL) && BIO_set_fp(out,stdout,BIO_NOCLOSE))
+			{
+#ifdef OPENSSL_SYS_VMS
+			{
+			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+			out = BIO_push(tmpbio, out);
+			}
+#endif
+			lh_ERR_STRING_DATA_node_stats_bio(
+						  ERR_get_string_table(), out);
+			lh_ERR_STRING_DATA_stats_bio(ERR_get_string_table(),
+						     out);
+			lh_ERR_STRING_DATA_node_usage_stats_bio(
+						    ERR_get_string_table(),out);
+			}
+		if (out != NULL) BIO_free_all(out);
+		argc--;
+		argv++;
+		}
+
+	for (i=1; i<argc; i++)
+		{
+		if (sscanf(argv[i],"%lx",&l))
+			{
+			ERR_error_string_n(l, buf, sizeof buf);
+			printf("%s\n",buf);
+			}
+		else
+			{
+			printf("%s: bad error code\n",argv[i]);
+			printf("usage: errstr [-stats] <errno> ...\n");
+			ret++;
+			}
+		}
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
diff --git a/openssl/apps/gendh.c b/openssl/apps/gendh.c
new file mode 100644
index 0000000..4ec776b
--- /dev/null
+++ b/openssl/apps/gendh.c
@@ -0,0 +1,241 @@
+/* apps/gendh.c */
+/* obsoleted by dhparam.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/opensslconf.h>
+/* Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code */
+#ifdef OPENSSL_NO_DEPRECATED
+#undef OPENSSL_NO_DEPRECATED
+#endif
+
+#ifndef OPENSSL_NO_DH
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+#define DEFBITS	512
+#undef PROG
+#define PROG gendh_main
+
+static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb);
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	BN_GENCB cb;
+	DH *dh=NULL;
+	int ret=1,num=DEFBITS;
+	int g=2;
+	char *outfile=NULL;
+	char *inrand=NULL;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+	BIO *out=NULL;
+
+	apps_startup();
+
+	BN_GENCB_set(&cb, dh_cb, bio_err);
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	argv++;
+	argc--;
+	for (;;)
+		{
+		if (argc <= 0) break;
+		if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-2") == 0)
+			g=2;
+	/*	else if (strcmp(*argv,"-3") == 0)
+			g=3; */
+		else if (strcmp(*argv,"-5") == 0)
+			g=5;
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*argv,"-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine= *(++argv);
+			}
+#endif
+		else if (strcmp(*argv,"-rand") == 0)
+			{
+			if (--argc < 1) goto bad;
+			inrand= *(++argv);
+			}
+		else
+			break;
+		argv++;
+		argc--;
+		}
+	if ((argc >= 1) && ((sscanf(*argv,"%d",&num) == 0) || (num < 0)))
+		{
+bad:
+		BIO_printf(bio_err,"usage: gendh [args] [numbits]\n");
+		BIO_printf(bio_err," -out file - output the key to 'file\n");
+		BIO_printf(bio_err," -2        - use 2 as the generator value\n");
+	/*	BIO_printf(bio_err," -3        - use 3 as the generator value\n"); */
+		BIO_printf(bio_err," -5        - use 5 as the generator value\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err," -engine e - use engine e, possibly a hardware device.\n");
+#endif
+		BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+		BIO_printf(bio_err,"           - load the file (or the files in the directory) into\n");
+		BIO_printf(bio_err,"             the random number generator\n");
+		goto end;
+		}
+		
+#ifndef OPENSSL_NO_ENGINE
+        setup_engine(bio_err, engine, 0);
+#endif
+
+	out=BIO_new(BIO_s_file());
+	if (out == NULL)
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (outfile == NULL)
+		{
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+		}
+	else
+		{
+		if (BIO_write_filename(out,outfile) <= 0)
+			{
+			perror(outfile);
+			goto end;
+			}
+		}
+
+	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL)
+		{
+		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
+		}
+	if (inrand != NULL)
+		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+			app_RAND_load_files(inrand));
+
+	BIO_printf(bio_err,"Generating DH parameters, %d bit long safe prime, generator %d\n",num,g);
+	BIO_printf(bio_err,"This is going to take a long time\n");
+
+	if(((dh = DH_new()) == NULL) || !DH_generate_parameters_ex(dh, num, g, &cb))
+		goto end;
+		
+	app_RAND_write_file(NULL, bio_err);
+
+	if (!PEM_write_bio_DHparams(out,dh))
+		goto end;
+	ret=0;
+end:
+	if (ret != 0)
+		ERR_print_errors(bio_err);
+	if (out != NULL) BIO_free_all(out);
+	if (dh != NULL) DH_free(dh);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
+static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb)
+	{
+	char c='*';
+
+	if (p == 0) c='.';
+	if (p == 1) c='+';
+	if (p == 2) c='*';
+	if (p == 3) c='\n';
+	BIO_write(cb->arg,&c,1);
+	(void)BIO_flush(cb->arg);
+#ifdef LINT
+	p=n;
+#endif
+	return 1;
+	}
+#else /* !OPENSSL_NO_DH */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/apps/gendsa.c b/openssl/apps/gendsa.c
new file mode 100644
index 0000000..62ea977
--- /dev/null
+++ b/openssl/apps/gendsa.c
@@ -0,0 +1,285 @@
+/* apps/gendsa.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/opensslconf.h>	/* for OPENSSL_NO_DSA */
+#ifndef OPENSSL_NO_DSA
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+#define DEFBITS	512
+#undef PROG
+#define PROG gendsa_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	DSA *dsa=NULL;
+	int ret=1;
+	char *outfile=NULL;
+	char *inrand=NULL,*dsaparams=NULL;
+	char *passargout = NULL, *passout = NULL;
+	BIO *out=NULL,*in=NULL;
+	const EVP_CIPHER *enc=NULL;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	argv++;
+	argc--;
+	for (;;)
+		{
+		if (argc <= 0) break;
+		if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-passout") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passargout= *(++argv);
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*argv,"-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine= *(++argv);
+			}
+#endif
+		else if (strcmp(*argv,"-rand") == 0)
+			{
+			if (--argc < 1) goto bad;
+			inrand= *(++argv);
+			}
+		else if (strcmp(*argv,"-") == 0)
+			goto bad;
+#ifndef OPENSSL_NO_DES
+		else if (strcmp(*argv,"-des") == 0)
+			enc=EVP_des_cbc();
+		else if (strcmp(*argv,"-des3") == 0)
+			enc=EVP_des_ede3_cbc();
+#endif
+#ifndef OPENSSL_NO_IDEA
+		else if (strcmp(*argv,"-idea") == 0)
+			enc=EVP_idea_cbc();
+#endif
+#ifndef OPENSSL_NO_SEED
+		else if (strcmp(*argv,"-seed") == 0)
+			enc=EVP_seed_cbc();
+#endif
+#ifndef OPENSSL_NO_AES
+		else if (strcmp(*argv,"-aes128") == 0)
+			enc=EVP_aes_128_cbc();
+		else if (strcmp(*argv,"-aes192") == 0)
+			enc=EVP_aes_192_cbc();
+		else if (strcmp(*argv,"-aes256") == 0)
+			enc=EVP_aes_256_cbc();
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+		else if (strcmp(*argv,"-camellia128") == 0)
+			enc=EVP_camellia_128_cbc();
+		else if (strcmp(*argv,"-camellia192") == 0)
+			enc=EVP_camellia_192_cbc();
+		else if (strcmp(*argv,"-camellia256") == 0)
+			enc=EVP_camellia_256_cbc();
+#endif
+		else if (**argv != '-' && dsaparams == NULL)
+			{
+			dsaparams = *argv;
+			}
+		else
+			goto bad;
+		argv++;
+		argc--;
+		}
+
+	if (dsaparams == NULL)
+		{
+bad:
+		BIO_printf(bio_err,"usage: gendsa [args] dsaparam-file\n");
+		BIO_printf(bio_err," -out file - output the key to 'file'\n");
+#ifndef OPENSSL_NO_DES
+		BIO_printf(bio_err," -des      - encrypt the generated key with DES in cbc mode\n");
+		BIO_printf(bio_err," -des3     - encrypt the generated key with DES in ede cbc mode (168 bit key)\n");
+#endif
+#ifndef OPENSSL_NO_IDEA
+		BIO_printf(bio_err," -idea     - encrypt the generated key with IDEA in cbc mode\n");
+#endif
+#ifndef OPENSSL_NO_SEED
+		BIO_printf(bio_err," -seed\n");
+		BIO_printf(bio_err,"                 encrypt PEM output with cbc seed\n");
+#endif
+#ifndef OPENSSL_NO_AES
+		BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
+		BIO_printf(bio_err,"                 encrypt PEM output with cbc aes\n");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+		BIO_printf(bio_err," -camellia128, -camellia192, -camellia256\n");
+		BIO_printf(bio_err,"                 encrypt PEM output with cbc camellia\n");
+#endif
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err," -engine e - use engine e, possibly a hardware device.\n");
+#endif
+		BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+		BIO_printf(bio_err,"           - load the file (or the files in the directory) into\n");
+		BIO_printf(bio_err,"             the random number generator\n");
+		BIO_printf(bio_err," dsaparam-file\n");
+		BIO_printf(bio_err,"           - a DSA parameter file as generated by the dsaparam command\n");
+		goto end;
+		}
+
+#ifndef OPENSSL_NO_ENGINE
+        setup_engine(bio_err, engine, 0);
+#endif
+
+	if(!app_passwd(bio_err, NULL, passargout, NULL, &passout)) {
+		BIO_printf(bio_err, "Error getting password\n");
+		goto end;
+	}
+
+
+	in=BIO_new(BIO_s_file());
+	if (!(BIO_read_filename(in,dsaparams)))
+		{
+		perror(dsaparams);
+		goto end;
+		}
+
+	if ((dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL)) == NULL)
+		{
+		BIO_printf(bio_err,"unable to load DSA parameter file\n");
+		goto end;
+		}
+	BIO_free(in);
+	in = NULL;
+		
+	out=BIO_new(BIO_s_file());
+	if (out == NULL) goto end;
+
+	if (outfile == NULL)
+		{
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+		}
+	else
+		{
+		if (BIO_write_filename(out,outfile) <= 0)
+			{
+			perror(outfile);
+			goto end;
+			}
+		}
+
+	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL)
+		{
+		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
+		}
+	if (inrand != NULL)
+		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+			app_RAND_load_files(inrand));
+
+	BIO_printf(bio_err,"Generating DSA key, %d bits\n",
+							BN_num_bits(dsa->p));
+	if (!DSA_generate_key(dsa)) goto end;
+
+	app_RAND_write_file(NULL, bio_err);
+
+	if (!PEM_write_bio_DSAPrivateKey(out,dsa,enc,NULL,0,NULL, passout))
+		goto end;
+	ret=0;
+end:
+	if (ret != 0)
+		ERR_print_errors(bio_err);
+	if (in != NULL) BIO_free(in);
+	if (out != NULL) BIO_free_all(out);
+	if (dsa != NULL) DSA_free(dsa);
+	if(passout) OPENSSL_free(passout);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+#else /* !OPENSSL_NO_DSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/apps/genpkey.c b/openssl/apps/genpkey.c
new file mode 100644
index 0000000..6dfda08
--- /dev/null
+++ b/openssl/apps/genpkey.c
@@ -0,0 +1,440 @@
+/* apps/genpkey.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx,
+				const char *file, ENGINE *e);
+static int genpkey_cb(EVP_PKEY_CTX *ctx);
+
+#define PROG genpkey_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	ENGINE *e = NULL;
+	char **args, *outfile = NULL;
+	char *passarg = NULL;
+	BIO *in = NULL, *out = NULL;
+	const EVP_CIPHER *cipher = NULL;
+	int outformat;
+	int text = 0;
+	EVP_PKEY *pkey=NULL;
+	EVP_PKEY_CTX *ctx = NULL;
+	char *pass = NULL;
+	int badarg = 0;
+	int ret = 1, rv;
+
+	int do_param = 0;
+
+	if (bio_err == NULL)
+		bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	outformat=FORMAT_PEM;
+
+	ERR_load_crypto_strings();
+	OpenSSL_add_all_algorithms();
+	args = argv + 1;
+	while (!badarg && *args && *args[0] == '-')
+		{
+		if (!strcmp(*args,"-outform"))
+			{
+			if (args[1])
+				{
+				args++;
+				outformat=str2fmt(*args);
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args,"-pass"))
+			{
+			if (!args[1]) goto bad;
+			passarg= *(++args);
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*args,"-engine") == 0)
+			{
+			if (!args[1])
+				goto bad;
+        		e = setup_engine(bio_err, *(++args), 0);
+			}
+#endif
+		else if (!strcmp (*args, "-paramfile"))
+			{
+			if (!args[1])
+				goto bad;
+			args++;
+			if (do_param == 1)
+				goto bad;
+			if (!init_keygen_file(bio_err, &ctx, *args, e))
+				goto end;
+			}
+		else if (!strcmp (*args, "-out"))
+			{
+			if (args[1])
+				{
+				args++;
+				outfile = *args;
+				}
+			else badarg = 1;
+			}
+		else if (strcmp(*args,"-algorithm") == 0)
+			{
+			if (!args[1])
+				goto bad;
+			if (!init_gen_str(bio_err, &ctx, *(++args),e, do_param))
+				goto end;
+			}
+		else if (strcmp(*args,"-pkeyopt") == 0)
+			{
+			if (!args[1])
+				goto bad;
+			if (!ctx)
+				{
+				BIO_puts(bio_err, "No keytype specified\n");
+				goto bad;
+				}
+			else if (pkey_ctrl_string(ctx, *(++args)) <= 0)
+				{
+				BIO_puts(bio_err, "parameter setting error\n");
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+			}
+		else if (strcmp(*args,"-genparam") == 0)
+			{
+			if (ctx)
+				goto bad;
+			do_param = 1;
+			}
+		else if (strcmp(*args,"-text") == 0)
+			text=1;
+		else
+			{
+			cipher = EVP_get_cipherbyname(*args + 1);
+			if (!cipher)
+				{
+				BIO_printf(bio_err, "Unknown cipher %s\n",
+								*args + 1);
+				badarg = 1;
+				}
+			if (do_param == 1)
+				badarg = 1;
+			}
+		args++;
+		}
+
+	if (!ctx)
+		badarg = 1;
+
+	if (badarg)
+		{
+		bad:
+		BIO_printf(bio_err, "Usage: genpkey [options]\n");
+		BIO_printf(bio_err, "where options may be\n");
+		BIO_printf(bio_err, "-out file          output file\n");
+		BIO_printf(bio_err, "-outform X         output format (DER or PEM)\n");
+		BIO_printf(bio_err, "-pass arg          output file pass phrase source\n");
+		BIO_printf(bio_err, "-<cipher>          use cipher <cipher> to encrypt the key\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err, "-engine e          use engine e, possibly a hardware device.\n");
+#endif
+		BIO_printf(bio_err, "-paramfile file    parameters file\n");
+		BIO_printf(bio_err, "-algorithm alg     the public key algorithm\n");
+		BIO_printf(bio_err, "-pkeyopt opt:value set the public key algorithm option <opt>\n"
+				            "                   to value <value>\n");
+		BIO_printf(bio_err, "-genparam          generate parameters, not key\n");
+		BIO_printf(bio_err, "-text              print the in text\n");
+		BIO_printf(bio_err, "NB: options order may be important!  See the manual page.\n");
+		goto end;
+		}
+
+	if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
+		{
+		BIO_puts(bio_err, "Error getting password\n");
+		goto end;
+		}
+
+	if (outfile)
+		{
+		if (!(out = BIO_new_file (outfile, "wb")))
+			{
+			BIO_printf(bio_err,
+				 "Can't open output file %s\n", outfile);
+			goto end;
+			}
+		}
+	else
+		{
+		out = BIO_new_fp (stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+			{
+			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+			out = BIO_push(tmpbio, out);
+			}
+#endif
+		}
+
+	EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
+	EVP_PKEY_CTX_set_app_data(ctx, bio_err);
+
+	if (do_param)
+		{
+		if (EVP_PKEY_paramgen(ctx, &pkey) <= 0)
+			{
+			BIO_puts(bio_err, "Error generating parameters\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+	else
+		{
+		if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
+			{
+			BIO_puts(bio_err, "Error generating key\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+
+	if (do_param)
+		rv = PEM_write_bio_Parameters(out, pkey);
+	else if (outformat == FORMAT_PEM) 
+		rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0,
+								NULL, pass);
+	else if (outformat == FORMAT_ASN1)
+		rv = i2d_PrivateKey_bio(out, pkey);
+	else
+		{
+		BIO_printf(bio_err, "Bad format specified for key\n");
+		goto end;
+		}
+
+	if (rv <= 0)
+		{
+		BIO_puts(bio_err, "Error writing key\n");
+		ERR_print_errors(bio_err);
+		}
+
+	if (text)
+		{
+		if (do_param)
+			rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
+		else
+			rv = EVP_PKEY_print_private(out, pkey, 0, NULL);
+
+		if (rv <= 0)
+			{
+			BIO_puts(bio_err, "Error printing key\n");
+			ERR_print_errors(bio_err);
+			}
+		}
+
+	ret = 0;
+
+	end:
+	if (pkey)
+		EVP_PKEY_free(pkey);
+	if (ctx)
+		EVP_PKEY_CTX_free(ctx);
+	if (out)
+		BIO_free_all(out);
+	BIO_free(in);
+	if (pass)
+		OPENSSL_free(pass);
+
+	return ret;
+	}
+
+static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx,
+				const char *file, ENGINE *e)
+	{
+	BIO *pbio;
+	EVP_PKEY *pkey = NULL;
+	EVP_PKEY_CTX *ctx = NULL;
+	if (*pctx)
+		{
+		BIO_puts(err, "Parameters already set!\n");
+		return 0;
+		}
+
+	pbio = BIO_new_file(file, "r");
+	if (!pbio)
+		{
+		BIO_printf(err, "Can't open parameter file %s\n", file);
+		return 0;
+		}
+
+	pkey = PEM_read_bio_Parameters(pbio, NULL);
+	BIO_free(pbio);
+
+	if (!pkey)
+		{
+		BIO_printf(bio_err, "Error reading parameter file %s\n", file);
+		return 0;
+		}
+
+	ctx = EVP_PKEY_CTX_new(pkey, e);
+	if (!ctx)
+		goto err;
+	if (EVP_PKEY_keygen_init(ctx) <= 0)
+		goto err;
+	EVP_PKEY_free(pkey);
+	*pctx = ctx;
+	return 1;
+
+	err:
+	BIO_puts(err, "Error initializing context\n");
+	ERR_print_errors(err);
+	if (ctx)
+		EVP_PKEY_CTX_free(ctx);
+	if (pkey)
+		EVP_PKEY_free(pkey);
+	return 0;
+
+	}
+
+int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
+			const char *algname, ENGINE *e, int do_param)
+	{
+	EVP_PKEY_CTX *ctx = NULL;
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	ENGINE *tmpeng = NULL;
+	int pkey_id;
+
+	if (*pctx)
+		{
+		BIO_puts(err, "Algorithm already set!\n");
+		return 0;
+		}
+
+	ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1);
+
+#ifndef OPENSSL_NO_ENGINE
+	if (!ameth && e)
+		ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1);
+#endif
+
+	if (!ameth)
+		{
+		BIO_printf(bio_err, "Algorithm %s not found\n", algname);
+		return 0;
+		}
+
+	ERR_clear_error();
+
+	EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
+#ifndef OPENSSL_NO_ENGINE
+	if (tmpeng)
+		ENGINE_finish(tmpeng);
+#endif
+	ctx = EVP_PKEY_CTX_new_id(pkey_id, e);
+
+	if (!ctx)
+		goto err;
+	if (do_param)
+		{
+		if (EVP_PKEY_paramgen_init(ctx) <= 0)
+			goto err;
+		}
+	else
+		{
+		if (EVP_PKEY_keygen_init(ctx) <= 0)
+			goto err;
+		}
+
+	*pctx = ctx;
+	return 1;
+
+	err:
+	BIO_printf(err, "Error initializing %s context\n", algname);
+	ERR_print_errors(err);
+	if (ctx)
+		EVP_PKEY_CTX_free(ctx);
+	return 0;
+
+	}
+
+static int genpkey_cb(EVP_PKEY_CTX *ctx)
+	{
+	char c='*';
+	BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
+	int p;
+	p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
+	if (p == 0) c='.';
+	if (p == 1) c='+';
+	if (p == 2) c='*';
+	if (p == 3) c='\n';
+	BIO_write(b,&c,1);
+	(void)BIO_flush(b);
+#ifdef LINT
+	p=n;
+#endif
+	return 1;
+	}
diff --git a/openssl/apps/genrsa.c b/openssl/apps/genrsa.c
new file mode 100644
index 0000000..37e9310
--- /dev/null
+++ b/openssl/apps/genrsa.c
@@ -0,0 +1,335 @@
+/* apps/genrsa.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/opensslconf.h>
+/* Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code */
+#ifdef OPENSSL_NO_DEPRECATED
+#undef OPENSSL_NO_DEPRECATED
+#endif
+
+#ifndef OPENSSL_NO_RSA
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+
+#define DEFBITS	512
+#undef PROG
+#define PROG genrsa_main
+
+static int MS_CALLBACK genrsa_cb(int p, int n, BN_GENCB *cb);
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	BN_GENCB cb;
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE *e = NULL;
+#endif
+	int ret=1;
+	int i,num=DEFBITS;
+	long l;
+	const EVP_CIPHER *enc=NULL;
+	unsigned long f4=RSA_F4;
+	char *outfile=NULL;
+	char *passargout = NULL, *passout = NULL;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+	char *inrand=NULL;
+	BIO *out=NULL;
+	BIGNUM *bn = BN_new();
+	RSA *rsa = NULL;
+
+	if(!bn) goto err;
+
+	apps_startup();
+	BN_GENCB_set(&cb, genrsa_cb, bio_err);
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto err;
+	if ((out=BIO_new(BIO_s_file())) == NULL)
+		{
+		BIO_printf(bio_err,"unable to create BIO for output\n");
+		goto err;
+		}
+
+	argv++;
+	argc--;
+	for (;;)
+		{
+		if (argc <= 0) break;
+		if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-3") == 0)
+			f4=3;
+		else if (strcmp(*argv,"-F4") == 0 || strcmp(*argv,"-f4") == 0)
+			f4=RSA_F4;
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*argv,"-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine= *(++argv);
+			}
+#endif
+		else if (strcmp(*argv,"-rand") == 0)
+			{
+			if (--argc < 1) goto bad;
+			inrand= *(++argv);
+			}
+#ifndef OPENSSL_NO_DES
+		else if (strcmp(*argv,"-des") == 0)
+			enc=EVP_des_cbc();
+		else if (strcmp(*argv,"-des3") == 0)
+			enc=EVP_des_ede3_cbc();
+#endif
+#ifndef OPENSSL_NO_IDEA
+		else if (strcmp(*argv,"-idea") == 0)
+			enc=EVP_idea_cbc();
+#endif
+#ifndef OPENSSL_NO_SEED
+		else if (strcmp(*argv,"-seed") == 0)
+			enc=EVP_seed_cbc();
+#endif
+#ifndef OPENSSL_NO_AES
+		else if (strcmp(*argv,"-aes128") == 0)
+			enc=EVP_aes_128_cbc();
+		else if (strcmp(*argv,"-aes192") == 0)
+			enc=EVP_aes_192_cbc();
+		else if (strcmp(*argv,"-aes256") == 0)
+			enc=EVP_aes_256_cbc();
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+		else if (strcmp(*argv,"-camellia128") == 0)
+			enc=EVP_camellia_128_cbc();
+		else if (strcmp(*argv,"-camellia192") == 0)
+			enc=EVP_camellia_192_cbc();
+		else if (strcmp(*argv,"-camellia256") == 0)
+			enc=EVP_camellia_256_cbc();
+#endif
+		else if (strcmp(*argv,"-passout") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passargout= *(++argv);
+			}
+		else
+			break;
+		argv++;
+		argc--;
+		}
+	if ((argc >= 1) && ((sscanf(*argv,"%d",&num) == 0) || (num < 0)))
+		{
+bad:
+		BIO_printf(bio_err,"usage: genrsa [args] [numbits]\n");
+		BIO_printf(bio_err," -des            encrypt the generated key with DES in cbc mode\n");
+		BIO_printf(bio_err," -des3           encrypt the generated key with DES in ede cbc mode (168 bit key)\n");
+#ifndef OPENSSL_NO_IDEA
+		BIO_printf(bio_err," -idea           encrypt the generated key with IDEA in cbc mode\n");
+#endif
+#ifndef OPENSSL_NO_SEED
+		BIO_printf(bio_err," -seed\n");
+		BIO_printf(bio_err,"                 encrypt PEM output with cbc seed\n");
+#endif
+#ifndef OPENSSL_NO_AES
+		BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
+		BIO_printf(bio_err,"                 encrypt PEM output with cbc aes\n");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+		BIO_printf(bio_err," -camellia128, -camellia192, -camellia256\n");
+		BIO_printf(bio_err,"                 encrypt PEM output with cbc camellia\n");
+#endif
+		BIO_printf(bio_err," -out file       output the key to 'file\n");
+		BIO_printf(bio_err," -passout arg    output file pass phrase source\n");
+		BIO_printf(bio_err," -f4             use F4 (0x10001) for the E value\n");
+		BIO_printf(bio_err," -3              use 3 for the E value\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err," -engine e       use engine e, possibly a hardware device.\n");
+#endif
+		BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+		BIO_printf(bio_err,"                 load the file (or the files in the directory) into\n");
+		BIO_printf(bio_err,"                 the random number generator\n");
+		goto err;
+		}
+		
+	ERR_load_crypto_strings();
+
+	if(!app_passwd(bio_err, NULL, passargout, NULL, &passout)) {
+		BIO_printf(bio_err, "Error getting password\n");
+		goto err;
+	}
+
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine, 0);
+#endif
+
+	if (outfile == NULL)
+		{
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+		}
+	else
+		{
+		if (BIO_write_filename(out,outfile) <= 0)
+			{
+			perror(outfile);
+			goto err;
+			}
+		}
+
+	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
+		&& !RAND_status())
+		{
+		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
+		}
+	if (inrand != NULL)
+		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+			app_RAND_load_files(inrand));
+
+	BIO_printf(bio_err,"Generating RSA private key, %d bit long modulus\n",
+		num);
+#ifdef OPENSSL_NO_ENGINE
+	rsa = RSA_new();
+#else
+	rsa = RSA_new_method(e);
+#endif
+	if (!rsa)
+		goto err;
+
+	if(!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, &cb))
+		goto err;
+		
+	app_RAND_write_file(NULL, bio_err);
+
+	/* We need to do the following for when the base number size is <
+	 * long, esp windows 3.1 :-(. */
+	l=0L;
+	for (i=0; i<rsa->e->top; i++)
+		{
+#ifndef SIXTY_FOUR_BIT
+		l<<=BN_BITS4;
+		l<<=BN_BITS4;
+#endif
+		l+=rsa->e->d[i];
+		}
+	BIO_printf(bio_err,"e is %ld (0x%lX)\n",l,l);
+	{
+	PW_CB_DATA cb_data;
+	cb_data.password = passout;
+	cb_data.prompt_info = outfile;
+	if (!PEM_write_bio_RSAPrivateKey(out,rsa,enc,NULL,0,
+		(pem_password_cb *)password_callback,&cb_data))
+		goto err;
+	}
+
+	ret=0;
+err:
+	if (bn) BN_free(bn);
+	if (rsa) RSA_free(rsa);
+	if (out) BIO_free_all(out);
+	if(passout) OPENSSL_free(passout);
+	if (ret != 0)
+		ERR_print_errors(bio_err);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
+static int MS_CALLBACK genrsa_cb(int p, int n, BN_GENCB *cb)
+	{
+	char c='*';
+
+	if (p == 0) c='.';
+	if (p == 1) c='+';
+	if (p == 2) c='*';
+	if (p == 3) c='\n';
+	BIO_write(cb->arg,&c,1);
+	(void)BIO_flush(cb->arg);
+#ifdef LINT
+	p=n;
+#endif
+	return 1;
+	}
+#else /* !OPENSSL_NO_RSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/apps/install-apps.com b/openssl/apps/install-apps.com
new file mode 100644
index 0000000..7a553aa
--- /dev/null
+++ b/openssl/apps/install-apps.com
@@ -0,0 +1,107 @@
+$! INSTALL.COM -- Installs the files in a given directory tree
+$!
+$! Author: Richard Levitte <richard@levitte.org>
+$! Time of creation: 22-MAY-1998 10:13
+$!
+$! P1  root of the directory tree
+$! P2  "64" for 64-bit pointers.
+$!
+$!
+$! Announce/identify.
+$!
+$ proc = f$environment( "procedure")
+$ write sys$output "@@@ "+ -
+   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
+$!
+$ on error then goto tidy
+$ on control_c then goto tidy
+$!
+$ if (p1 .eqs. "")
+$ then
+$   write sys$output "First argument missing."
+$   write sys$output -
+     "It should be the directory where you want things installed."
+$   exit
+$ endif
+$!
+$ if (f$getsyi("cpu") .lt. 128)
+$ then
+$   arch = "VAX"
+$ else
+$   arch = f$edit( f$getsyi( "arch_name"), "upcase")
+$   if (arch .eqs. "") then arch = "UNK"
+$ endif
+$!
+$ archd = arch
+$!
+$ if (p2 .nes. "")
+$ then
+$   if (p2 .eqs. "64")
+$   then
+$     archd = arch+ "_64"
+$   else
+$     if (p2 .nes. "32")
+$     then
+$       write sys$output "Second argument invalid."
+$       write sys$output "It should be "32", "64", or nothing."
+$       exit
+$     endif
+$   endif
+$ endif
+$!
+$ root = f$parse( p1, "[]A.;0", , , "syntax_only, no_conceal") - "A.;0"
+$ root_dev = f$parse(root,,,"device","syntax_only")
+$ root_dir = f$parse(root,,,"directory","syntax_only") - -
+   "[000000." - "][" - "[" - "]"
+$ root = root_dev + "[" + root_dir
+$!
+$ define /nolog wrk_sslroot 'root'.] /trans=conc
+$ define /nolog wrk_sslxexe wrk_sslroot:['archd'_exe]
+$!
+$ if f$parse("wrk_sslroot:[000000]") .eqs. "" then -
+   create /directory /log wrk_sslroot:[000000]
+$ if f$parse("wrk_sslxexe:") .eqs. "" then -
+   create /directory /log wrk_sslxexe:
+$!
+$ exe := openssl
+$!
+$ exe_dir := [-.'archd'.exe.apps]
+$!
+$! Executables.
+$!
+$ i = 0
+$ loop_exe:
+$   e = f$edit(f$element( i, ",", exe), "trim")
+$   i = i + 1
+$   if e .eqs. "," then goto loop_exe_end
+$   set noon
+$   file = exe_dir+ e+ ".exe"
+$   if f$search( file) .nes. ""
+$   then
+$     copy /protection = w:re 'file' wrk_sslxexe: /log
+$   endif
+$   set on
+$ goto loop_exe
+$ loop_exe_end:
+$!
+$! Miscellaneous.
+$!
+$ set noon
+$ copy /protection = w:re ca.com wrk_sslxexe:ca.com /log
+$ copy /protection = w:re openssl-vms.cnf wrk_sslroot:[000000]openssl.cnf /log
+$ set on
+$!
+$ tidy:
+$!
+$ call deass wrk_sslroot
+$ call deass wrk_sslxexe
+$!
+$ exit
+$!
+$ deass: subroutine
+$ if (f$trnlnm( p1, "LNM$PROCESS") .nes. "")
+$ then
+$   deassign /process 'p1'
+$ endif
+$ endsubroutine
+$!
diff --git a/openssl/apps/makeapps.com b/openssl/apps/makeapps.com
new file mode 100644
index 0000000..71417a8
--- /dev/null
+++ b/openssl/apps/makeapps.com
@@ -0,0 +1,1169 @@
+$!
+$!  MAKEAPPS.COM
+$!  Written By:  Robert Byer
+$!               Vice-President
+$!               A-Com Computing, Inc.
+$!               byer@mail.all-net.net
+$!
+$!  Changes by Richard Levitte <richard@levitte.org>
+$!             Zoltan Arpadffy <zoli@polarhome.com>   
+$!
+$!  This command files compiles and creates all the various different
+$!  "application" programs for the different types of encryption for OpenSSL.
+$!  The EXE's are placed in the directory [.xxx.EXE.APPS] where "xxx" denotes
+$!  ALPHA, IA64 or VAX, depending on your machine architecture.
+$!
+$!  It was written so it would try to determine what "C" compiler to
+$!  use or you can specify which "C" compiler to use.
+$!
+$!  Specify DEBUG or NODEBUG as P1 to compile with or without debugger
+$!  information.
+$!
+$!  Specify which compiler at P2 to try to compile under.
+$!
+$!	   VAXC	 For VAX C.
+$!	   DECC	 For DEC C.
+$!	   GNUC	 For GNU C.
+$!
+$!  If you don't specify a compiler, it will try to determine which
+$!  "C" compiler to use.
+$!
+$!  P3, if defined, sets a TCP/IP library to use, through one of the following
+$!  keywords:
+$!
+$!	UCX		for UCX
+$!	SOCKETSHR	for SOCKETSHR+NETLIB
+$!	TCPIP		for TCPIP (post UCX)
+$!
+$!  P4, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
+$!
+$!  P5, if defined, sets a choice of programs to compile.
+$!
+$!  P6, if defined, specifies the C pointer size.  Ignored on VAX.
+$!      ("64=ARGV" gives more efficient code with HP C V7.3 or newer.)
+$!      Supported values are:
+$!
+$!      ""       Compile with default (/NOPOINTER_SIZE)
+$!      32       Compile with /POINTER_SIZE=32 (SHORT)
+$!      64       Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV])
+$!               (Automatically select ARGV if compiler supports it.)
+$!      64=      Compile with /POINTER_SIZE=64 (LONG).
+$!      64=ARGV  Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV).
+$!
+$!  P7, if defined, specifies a directory where ZLIB files (zlib.h,
+$!  libz.olb) may be found.  Optionally, a non-default object library
+$!  name may be included ("dev:[dir]libz_64.olb", for example).
+$!
+$!
+$! Announce/identify.
+$!
+$ proc = f$environment( "procedure")
+$ write sys$output "@@@ "+ -
+   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
+$!
+$ on control_c then goto exit
+$!
+$! Define A TCP/IP Library That We Will Need To Link To.
+$! (That Is, If We Need To Link To One.)
+$!
+$ TCPIP_LIB = ""
+$ ZLIB_LIB = ""
+$!
+$! Check What Architecture We Are Using.
+$!
+$ IF (F$GETSYI("CPU").LT.128)
+$ THEN
+$!
+$!  The Architecture Is VAX.
+$!
+$   ARCH = "VAX"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  The Architecture Is Alpha, IA64 or whatever comes in the future.
+$!
+$   ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
+$   IF (ARCH .EQS. "") THEN ARCH = "UNK"
+$!
+$! End The Architecture Check.
+$!
+$ ENDIF
+$!
+$ ARCHD = ARCH
+$ LIB32 = "32"
+$ OPT_FILE = ""
+$ POINTER_SIZE = ""
+$!
+$! Define what programs should be compiled
+$!
+$ PROGRAMS := OPENSSL
+$!
+$! Check To Make Sure We Have Valid Command Line Parameters.
+$!
+$ GOSUB CHECK_OPTIONS
+$!
+$! Define The CRYPTO Library.
+$!
+$ CRYPTO_LIB := SYS$DISK:[-.'ARCHD'.EXE.CRYPTO]SSL_LIBCRYPTO'LIB32'.OLB
+$!
+$! Define The SSL Library.
+$!
+$ SSL_LIB := SYS$DISK:[-.'ARCHD'.EXE.SSL]SSL_LIBSSL'LIB32'.OLB
+$!
+$! Define The OBJ and EXE Directories.
+$!
+$ OBJ_DIR := SYS$DISK:[-.'ARCHD'.OBJ.APPS]
+$ EXE_DIR := SYS$DISK:[-.'ARCHD'.EXE.APPS]
+$!
+$! Specify the destination directory in any /MAP option.
+$!
+$ if (LINKMAP .eqs. "MAP")
+$ then
+$   LINKMAP = LINKMAP+ "=''EXE_DIR'"
+$ endif
+$!
+$! Add the location prefix to the linker options file name.
+$!
+$ if (OPT_FILE .nes. "")
+$ then
+$   OPT_FILE = EXE_DIR+ OPT_FILE
+$ endif
+$!
+$! Initialise logical names and such
+$!
+$ GOSUB INITIALISE
+$!
+$! Tell The User What Kind of Machine We Run On.
+$!
+$ WRITE SYS$OUTPUT "Host system architecture: ''ARCHD'"
+$!
+$! Check To See If The OBJ Directory Exists.
+$!
+$ IF (F$PARSE(OBJ_DIR).EQS."")
+$ THEN
+$!
+$!  It Dosen't Exist, So Create It.
+$!
+$   CREATE/DIRECTORY 'OBJ_DIR'
+$!
+$! End The OBJ Directory Check.
+$!
+$ ENDIF
+$!
+$! Check To See If The EXE Directory Exists.
+$!
+$ IF (F$PARSE(EXE_DIR).EQS."")
+$ THEN
+$!
+$!  It Dosen't Exist, So Create It.
+$!
+$   CREATE/DIRECTORY 'EXE_DIR'
+$!
+$! End The EXE Directory Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have The Proper Libraries.
+$!
+$ GOSUB LIB_CHECK
+$!
+$! Check To See If We Have A Linker Option File.
+$!
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Define The Application Files.
+$! NOTE: Some might think this list ugly.  However, it's made this way to
+$! reflect the E_OBJ variable in Makefile as closely as possible, thereby
+$! making it fairly easy to verify that the lists are the same.
+$!
+$ LIB_OPENSSL = "VERIFY,ASN1PARS,REQ,DGST,DH,DHPARAM,ENC,PASSWD,GENDH,ERRSTR,"+-
+	     	"CA,PKCS7,CRL2P7,CRL,"+-
+	      	"RSA,RSAUTL,DSA,DSAPARAM,EC,ECPARAM,"+-
+	      	"X509,GENRSA,GENDSA,GENPKEY,S_SERVER,S_CLIENT,SPEED,"+-
+	      	"S_TIME,APPS,S_CB,S_SOCKET,APP_RAND,VERSION,SESS_ID,"+-
+	      	"CIPHERS,NSEQ,PKCS12,PKCS8,PKEY,PKEYPARAM,PKEYUTL,"+ -
+	      	"SPKAC,SMIME,CMS,RAND,ENGINE,OCSP,PRIME,TS"
+$!
+$ LIB_OPENSSL = LIB_OPENSSL+ ",VMS_DECC_INIT"
+$!
+$ TCPIP_PROGRAMS = ",,"
+$ IF COMPILER .EQS. "VAXC" THEN -
+     TCPIP_PROGRAMS = ",OPENSSL,"
+$!
+$! Setup exceptional compilations
+$!
+$ COMPILEWITH_CC2 = ",S_SOCKET,S_SERVER,S_CLIENT,"
+$!
+$ PHASE := LIB
+$!
+$ RESTART: 
+$!
+$!  Define An App Counter And Set It To "0".
+$!
+$ APP_COUNTER = 0
+$!
+$!  Top Of The App Loop.
+$!
+$ NEXT_APP:
+$!
+$!  Make The Application File Name
+$!
+$ CURRENT_APP = F$EDIT(F$ELEMENT(APP_COUNTER,",",PROGRAMS),"TRIM")
+$!
+$!  Create The Executable File Name.
+$!
+$   EXE_FILE = EXE_DIR + CURRENT_APP + ".EXE"
+$!
+$!  Check To See If We Are At The End Of The File List.
+$!
+$ IF (CURRENT_APP.EQS.",")
+$ THEN
+$   IF (PHASE.EQS."LIB")
+$   THEN
+$     PHASE := APP
+$     GOTO RESTART
+$   ELSE
+$     GOTO APP_DONE
+$   ENDIF
+$ ENDIF
+$!
+$!  Increment The Counter.
+$!
+$ APP_COUNTER = APP_COUNTER + 1
+$!
+$!  Decide if we're building the object files or not.
+$!
+$ IF (PHASE.EQS."LIB")
+$ THEN
+$!
+$!  Define A Library File Counter And Set It To "-1".
+$!  -1 Means The Application File Name Is To Be Used.
+$!
+$   LIB_COUNTER = -1
+$!
+$!  Create a .OPT file for the object files
+$!
+$   OPEN /WRITE OBJECTS 'EXE_DIR''CURRENT_APP'.OPT
+$!
+$!  Top Of The File Loop.
+$!
+$  NEXT_LIB:
+$!
+$!  O.K, Extract The File Name From The File List.
+$!
+$   IF LIB_COUNTER .GE. 0
+$   THEN
+$     FILE_NAME = F$EDIT(F$ELEMENT(LIB_COUNTER,",",LIB_'CURRENT_APP'),"TRIM")
+$   ELSE
+$     FILE_NAME = CURRENT_APP
+$   ENDIF
+$!
+$!  Check To See If We Are At The End Of The File List.
+$!
+$   IF (FILE_NAME.EQS.",")
+$   THEN
+$     CLOSE OBJECTS
+$     GOTO NEXT_APP
+$   ENDIF
+$!
+$!  Increment The Counter.
+$!
+$   LIB_COUNTER = LIB_COUNTER + 1
+$!
+$!  Create The Source File Name.
+$!
+$   SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME + ".C"
+$!
+$!  Create The Object File Name.
+$!
+$   OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ"
+$   ON WARNING THEN GOTO NEXT_LIB
+$!
+$!  Check To See If The File We Want To Compile Actually Exists.
+$!
+$   IF (F$SEARCH(SOURCE_FILE).EQS."")
+$   THEN
+$!
+$!    Tell The User That The File Dosen't Exist.
+$!
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
+$     WRITE SYS$OUTPUT ""
+$!
+$!    Exit The Build.
+$!
+$     GOTO EXIT
+$!
+$!  End The File Exist Check.
+$!
+$   ENDIF
+$!
+$!  Tell The User What We Are Building.
+$!
+$   IF (PHASE.EQS."LIB")
+$   THEN
+$     WRITE SYS$OUTPUT "Compiling The ",FILE_NAME,".C File."
+$   ELSE
+$     WRITE SYS$OUTPUT "Building The ",FILE_NAME," Application Program."
+$   ENDIF
+$!
+$!  Compile The File.
+$!
+$   ON ERROR THEN GOTO NEXT_LIB
+$   IF COMPILEWITH_CC2 - FILE_NAME .NES. COMPILEWITH_CC2
+$   THEN
+$     CC2/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$   ELSE
+$     CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$   ENDIF
+$   WRITE OBJECTS OBJECT_FILE
+$!
+$   GOTO NEXT_LIB
+$ ENDIF
+$!
+$!  Check if this program works well without a TCPIP library
+$!
+$ IF TCPIP_LIB .EQS. "" .AND. TCPIP_PROGRAMS - CURRENT_APP .NES. TCPIP_PROGRAMS
+$ THEN
+$   WRITE SYS$OUTPUT CURRENT_APP," needs a TCP/IP library.  Can't link.  Skipping..."
+$   GOTO NEXT_APP
+$ ENDIF
+$!
+$! Link The Program.
+$!
+$ ON WARNING THEN GOTO NEXT_APP
+$!
+$! Don't Link With The RSAREF Routines And TCP/IP Library.
+$!
+$ LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' /EXE='EXE_FILE' -
+  'EXE_DIR''CURRENT_APP'.OPT /OPTIONS, -
+  'SSL_LIB' /LIBRARY, -
+  'CRYPTO_LIB' /LIBRARY -
+  'TCPIP_LIB' -
+  'ZLIB_LIB' -
+  ,'OPT_FILE' /OPTIONS
+$!
+$! Go Back And Do It Again.
+$!
+$ GOTO NEXT_APP
+$!
+$! All Done With This File.
+$!
+$ APP_DONE:
+$ EXIT:
+$!
+$! All Done, Time To Clean Up And Exit.
+$!
+$ GOSUB CLEANUP
+$ EXIT
+$!
+$! Check For The Link Option FIle.
+$!
+$ CHECK_OPT_FILE:
+$!
+$! Check To See If We Need To Make A VAX C Option File.
+$!
+$ IF (COMPILER.EQS."VAXC")
+$ THEN
+$!
+$!  Check To See If We Already Have A VAX C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    We Need A VAX C Linker Option File.
+$!
+$     CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against 
+! The Sharable VAX C Runtime Library.
+!
+SYS$SHARE:VAXCRTL.EXE/SHARE
+$EOD
+$!
+$!  End The Option File Check.
+$!
+$   ENDIF
+$!
+$! End The VAXC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A GNU C Option File.
+$!
+$ IF (COMPILER.EQS."GNUC")
+$ THEN
+$!
+$!  Check To See If We Already Have A GNU C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    We Need A GNU C Linker Option File.
+$!
+$     CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against 
+! The Sharable C Runtime Library.
+!
+GNU_CC:[000000]GCCLIB/LIBRARY
+SYS$SHARE:VAXCRTL/SHARE
+$EOD
+$!
+$!  End The Option File Check.
+$!
+$   ENDIF
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A DEC C Option File.
+$!
+$ IF (COMPILER.EQS."DECC")
+$ THEN
+$!
+$!  Check To See If We Already Have A DEC C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    Figure Out If We Need An AXP Or A VAX Linker Option File.
+$!
+$     IF ARCH.EQS."VAX"
+$     THEN
+$!
+$!      We Need A DEC C Linker Option File For VAX.
+$!
+$       CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against 
+! The Sharable DEC C Runtime Library.
+!
+SYS$SHARE:DECC$SHR.EXE/SHARE
+$EOD
+$!
+$!    Else...
+$!
+$     ELSE
+$!
+$!      Create The non-VAX Linker Option File.
+$!
+$       CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File For non-VAX To Link Against 
+! The Sharable C Runtime Library.
+!
+SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
+SYS$SHARE:CMA$OPEN_RTL/SHARE
+$EOD
+$!
+$!    End The DEC C Option File Check.
+$!
+$     ENDIF
+$!
+$!  End The Option File Search.
+$!
+$   ENDIF
+$!
+$! End The DEC C Check.
+$!
+$ ENDIF
+$!
+$!  Tell The User What Linker Option File We Are Using.
+$!
+$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."	
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$!
+$! Check To See If We Have The Appropiate Libraries.
+$!
+$ LIB_CHECK:
+$!
+$! Look For The Library LIBCRYPTO.OLB.
+$!
+$ IF (F$SEARCH(CRYPTO_LIB).EQS."")
+$ THEN
+$!
+$!  Tell The User We Can't Find The LIBCRYPTO.OLB Library.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"."
+$   WRITE SYS$OUTPUT "We Can't Link Without It."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Since We Can't Link Without It, Exit.
+$!
+$   EXIT
+$!
+$! End The Crypto Library Check.
+$!
+$ ENDIF
+$!
+$! Look For The Library LIBSSL.OLB.
+$!
+$ IF (F$SEARCH(SSL_LIB).EQS."")
+$ THEN
+$!
+$!  Tell The User We Can't Find The LIBSSL.OLB Library.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"."
+$   WRITE SYS$OUTPUT "Some Of The Test Programs Need To Link To It."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Since We Can't Link Without It, Exit.
+$!
+$   EXIT
+$!
+$! End The SSL Library Check.
+$!
+$ ENDIF
+$!
+$! Time To Return.
+$!
+$ RETURN
+$!
+$! Check The User's Options.
+$!
+$ CHECK_OPTIONS:
+$!
+$! Check To See If P1 Is Blank.
+$!
+$ IF (P1.EQS."NODEBUG")
+$ THEN
+$!
+$!  P1 Is NODEBUG, So Compile Without Debugger Information.
+$!
+$   DEBUGGER  = "NODEBUG"
+$   LINKMAP = "NOMAP"
+$   TRACEBACK = "NOTRACEBACK" 
+$   GCC_OPTIMIZE = "OPTIMIZE"
+$   CC_OPTIMIZE = "OPTIMIZE"
+$   WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
+$   WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  Check To See If We Are To Compile With Debugger Information.
+$!
+$   IF (P1.EQS."DEBUG")
+$   THEN
+$!
+$!    Compile With Debugger Information.
+$!
+$     DEBUGGER  = "DEBUG"
+$     LINKMAP = "MAP"
+$     TRACEBACK = "TRACEBACK"
+$     GCC_OPTIMIZE = "NOOPTIMIZE"
+$     CC_OPTIMIZE = "NOOPTIMIZE"
+$     WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
+$     WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
+$   ELSE
+$!
+$!    Tell The User Entered An Invalid Option.
+$!
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ",P1," Is Invalid.  The Valid Options Are:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "    DEBUG    :  Compile With The Debugger Information."
+$     WRITE SYS$OUTPUT "    NODEBUG  :  Compile Without The Debugger Information."
+$     WRITE SYS$OUTPUT ""
+$!
+$!    Time To EXIT.
+$!
+$     EXIT
+$!
+$!  End The Valid Argument Check.
+$!
+$   ENDIF
+$!
+$! End The P1 Check.
+$!
+$ ENDIF
+$!
+$! Check P6 (POINTER_SIZE).
+$!
+$ IF (P6 .NES. "") .AND. (ARCH .NES. "VAX")
+$ THEN
+$!
+$   IF (P6 .EQS. "32")
+$   THEN
+$     POINTER_SIZE = " /POINTER_SIZE=32"
+$   ELSE
+$     POINTER_SIZE = F$EDIT( P6, "COLLAPSE, UPCASE")
+$     IF ((POINTER_SIZE .EQS. "64") .OR. -
+       (POINTER_SIZE .EQS. "64=") .OR. -
+       (POINTER_SIZE .EQS. "64=ARGV"))
+$     THEN
+$       ARCHD = ARCH+ "_64"
+$       LIB32 = ""
+$       IF (F$EXTRACT( 2, 1, POINTER_SIZE) .EQS. "=")
+$       THEN
+$!        Explicit user choice: "64" or "64=ARGV".
+$         IF (POINTER_SIZE .EQS. "64=") THEN POINTER_SIZE = "64"
+$       ELSE
+$         SET NOON
+$         DEFINE /USER_MODE SYS$OUTPUT NL:
+$         DEFINE /USER_MODE SYS$ERROR NL:
+$         CC /NOLIST /NOOBJECT /POINTER_SIZE=64=ARGV NL:
+$         IF ($STATUS .AND. %X0FFF0000) .EQ. %X00030000
+$         THEN
+$           ! If we got here, it means DCL complained like this:
+$           ! %DCL-W-NOVALU, value not allowed - remove value specification
+$           !  \64=\
+$           !
+$           ! If the compiler was run, logicals defined in /USER would
+$           ! have been deassigned automatically.  However, when DCL
+$           ! complains, they aren't, so we do it here (it might be
+$           ! unnecessary, but just in case there will be another error
+$           ! message further on that we don't want to miss)
+$           DEASSIGN /USER_MODE SYS$ERROR
+$           DEASSIGN /USER_MODE SYS$OUTPUT
+$         ELSE
+$           POINTER_SIZE = POINTER_SIZE + "=ARGV"
+$         ENDIF
+$         SET ON
+$       ENDIF
+$       POINTER_SIZE = " /POINTER_SIZE=''POINTER_SIZE'"
+$!
+$     ELSE
+$!
+$!      Tell The User Entered An Invalid Option.
+$!
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT "The Option ", P6, -
+         " Is Invalid.  The Valid Options Are:"
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT -
+         "    """"  :  Compile with default (short) pointers."
+$       WRITE SYS$OUTPUT -
+         "    32  :  Compile with 32-bit (short) pointers."
+$       WRITE SYS$OUTPUT -
+         "    64       :  Compile with 64-bit (long) pointers (auto ARGV)."
+$       WRITE SYS$OUTPUT -
+         "    64=      :  Compile with 64-bit (long) pointers (no ARGV)."
+$       WRITE SYS$OUTPUT -
+         "    64=ARGV  :  Compile with 64-bit (long) pointers (ARGV)."
+$       WRITE SYS$OUTPUT ""
+$! 
+$!      Time To EXIT.
+$!
+$       EXIT
+$!
+$     ENDIF
+$!
+$   ENDIF
+$!
+$! End The P6 (POINTER_SIZE) Check.
+$!
+$ ENDIF
+$!
+$! Set basic C compiler /INCLUDE directories.
+$!
+$ CC_INCLUDES = "SYS$DISK:[-],SYS$DISK:[-.CRYPTO]"
+$!
+$! Check To See If P2 Is Blank.
+$!
+$ IF (P2.EQS."")
+$ THEN
+$!
+$!  O.K., The User Didn't Specify A Compiler, Let's Try To
+$!  Find Out Which One To Use.
+$!
+$!  Check To See If We Have GNU C.
+$!
+$   IF (F$TRNLNM("GNU_CC").NES."")
+$   THEN
+$!
+$!    Looks Like GNUC, Set To Use GNUC.
+$!
+$     P2 = "GNUC"
+$!
+$!  Else...
+$!
+$   ELSE
+$!
+$!  Check To See If We Have VAXC Or DECC.
+$!
+$     IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
+$     THEN 
+$!
+$!      Looks Like DECC, Set To Use DECC.
+$!
+$       P2 = "DECC"
+$!
+$!    Else...
+$!
+$     ELSE
+$!
+$!      Looks Like VAXC, Set To Use VAXC.
+$!
+$       P2 = "VAXC"
+$!
+$!    End The VAXC Compiler Check.
+$!
+$     ENDIF
+$!
+$!  End The DECC & VAXC Compiler Check.
+$!
+$   ENDIF
+$!
+$!  End The Compiler Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have A Option For P3.
+$!
+$ IF (P3.EQS."")
+$ THEN
+$!
+$!  Find out what socket library we have available
+$!
+$   IF F$PARSE("SOCKETSHR:") .NES. ""
+$   THEN
+$!
+$!    We have SOCKETSHR, and it is my opinion that it's the best to use.
+$!
+$     P3 = "SOCKETSHR"
+$!
+$!    Tell the user
+$!
+$     WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
+$!
+$!    Else, let's look for something else
+$!
+$   ELSE
+$!
+$!    Like UCX (the reason to do this before Multinet is that the UCX
+$!    emulation is easier to use...)
+$!
+$     IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
+	 .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
+	 .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
+$     THEN
+$!
+$!	Last resort: a UCX or UCX-compatible library
+$!
+$	P3 = "UCX"
+$!
+$!      Tell the user
+$!
+$       WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
+$!
+$!	That was all...
+$!
+$     ENDIF
+$   ENDIF
+$ ENDIF
+$!
+$! Set Up Initial CC Definitions, Possibly With User Ones
+$!
+$ CCDEFS = "MONOLITH"
+$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
+$ CCEXTRAFLAGS = ""
+$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
+$ CCDISABLEWARNINGS = "" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
+$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
+	CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
+$!
+$! Check To See If We Have A ZLIB Option.
+$!
+$ ZLIB = P7
+$ IF (ZLIB .NES. "")
+$ THEN
+$!
+$!  Check for expected ZLIB files.
+$!
+$   err = 0
+$   file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY")
+$   if (f$search( file1) .eqs. "")
+$   then
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
+$     WRITE SYS$OUTPUT "    Can't find header: ''file1'"
+$     err = 1
+$   endif
+$   file1 = f$parse( "A.;", ZLIB)- "A.;"
+$!
+$   file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY")
+$   if (f$search( file2) .eqs. "")
+$   then
+$     if (err .eq. 0)
+$     then
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
+$     endif
+$     WRITE SYS$OUTPUT "    Can't find library: ''file2'"
+$     WRITE SYS$OUTPUT ""
+$     err = err+ 2
+$   endif
+$   if (err .eq. 1)
+$   then
+$     WRITE SYS$OUTPUT ""
+$   endif
+$!
+$   if (err .ne. 0)
+$   then
+$     EXIT
+$   endif
+$!
+$   CCDEFS = """ZLIB=1"", "+ CCDEFS
+$   CC_INCLUDES = CC_INCLUDES+ ", "+ file1
+$   ZLIB_LIB = ", ''file2' /library"
+$!
+$!  Print info
+$!
+$   WRITE SYS$OUTPUT "ZLIB library spec: ", file2
+$!
+$! End The ZLIB Check.
+$!
+$ ENDIF
+$!
+$!  Check To See If The User Entered A Valid Parameter.
+$!
+$ IF (P2.EQS."VAXC").OR.(P2.EQS."DECC").OR.(P2.EQS."GNUC")
+$ THEN
+$!
+$!  Check To See If The User Wanted DECC.
+$!
+$   IF (P2.EQS."DECC")
+$   THEN
+$!
+$!    Looks Like DECC, Set To Use DECC.
+$!
+$     COMPILER = "DECC"
+$!
+$!    Tell The User We Are Using DECC.
+$!
+$     WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$!    Use DECC...
+$!
+$     CC = "CC"
+$     IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
+	 THEN CC = "CC/DECC"
+$     CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ -
+       "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + -
+       " /INCLUDE=(''CC_INCLUDES') " + CCEXTRAFLAGS
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "VAX_DECC_OPTIONS.OPT"
+$!
+$!  End DECC Check.
+$!
+$   ENDIF
+$!
+$!  Check To See If We Are To Use VAXC.
+$!
+$   IF (P2.EQS."VAXC")
+$   THEN
+$!
+$!    Looks Like VAXC, Set To Use VAXC.
+$!
+$     COMPILER = "VAXC"
+$!
+$!    Tell The User We Are Using VAX C.
+$     WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$!    Compile Using VAXC.
+$!
+$     CC = "CC"
+$     IF ARCH.NES."VAX"
+$     THEN
+$	WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
+$	EXIT
+$     ENDIF
+$     IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
+$     CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+	   "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
+$     CCDEFS = CCDEFS + ",""VAXC"""
+$!
+$!    Define <sys> As SYS$COMMON:[SYSLIB]
+$!
+$     DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "VAX_VAXC_OPTIONS.OPT"
+$!
+$!  End VAXC Check
+$!
+$   ENDIF
+$!
+$!  Check To See If We Are To Use GNU C.
+$!
+$   IF (P2.EQS."GNUC")
+$   THEN
+$!
+$!    Looks Like GNUC, Set To Use GNUC.
+$!
+$     COMPILER = "GNUC"
+$!
+$!    Tell The User We Are Using GNUC.
+$!
+$     WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$!    Use GNU C...
+$!
+$     IF F$TYPE(GCC) .EQS. "" THEN GCC := GCC
+$     CC = GCC+"/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+	   "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "VAX_GNUC_OPTIONS.OPT"
+$!
+$!  End The GNU C Check.
+$!
+$   ENDIF
+$!
+$!  Set up default defines
+$!
+$   CCDEFS = """FLAT_INC=1""," + CCDEFS
+$!
+$!  Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$!  Tell The User We Don't Know What They Want.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The Option ",P2," Is Invalid.  The Valid Options Are:"
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "    VAXC  :  To Compile With VAX C."
+$   WRITE SYS$OUTPUT "    DECC  :  To Compile With DEC C."
+$   WRITE SYS$OUTPUT "    GNUC  :  To Compile With GNU C."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Time To EXIT.
+$!
+$   EXIT
+$ ENDIF
+$!
+$! Time to check the contents, and to make sure we get the correct library.
+$!
+$ IF P3.EQS."SOCKETSHR" .OR. P3.EQS."MULTINET" .OR. P3.EQS."UCX" -
+     .OR. P3.EQS."TCPIP" .OR. P3.EQS."NONE"
+$ THEN
+$!
+$!  Check to see if SOCKETSHR was chosen
+$!
+$   IF P3.EQS."SOCKETSHR"
+$   THEN
+$!
+$!    Set the library to use SOCKETSHR
+$!
+$     TCPIP_LIB = ",SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
+$!
+$!    Done with SOCKETSHR
+$!
+$   ENDIF
+$!
+$!  Check to see if MULTINET was chosen
+$!
+$   IF P3.EQS."MULTINET"
+$   THEN
+$!
+$!    Set the library to use UCX emulation.
+$!
+$     P3 = "UCX"
+$!
+$!    Done with MULTINET
+$!
+$   ENDIF
+$!
+$!  Check to see if UCX was chosen
+$!
+$   IF P3.EQS."UCX"
+$   THEN
+$!
+$!    Set the library to use UCX.
+$!
+$     TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
+$     IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
+$     THEN
+$       TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS"
+$     ELSE
+$       IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
+	  TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS"
+$     ENDIF
+$!
+$!    Done with UCX
+$!
+$   ENDIF
+$!
+$!  Check to see if TCPIP (post UCX) was chosen
+$!
+$   IF P3.EQS."TCPIP"
+$   THEN
+$!
+$!    Set the library to use TCPIP.
+$!
+$     TCPIP_LIB = ",SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
+$!
+$!    Done with TCPIP
+$!
+$   ENDIF
+$!
+$!  Check to see if NONE was chosen
+$!
+$   IF P3.EQS."NONE"
+$   THEN
+$!
+$!    Do not use TCPIP.
+$!
+$     TCPIP_LIB = ""
+$!
+$!    Done with TCPIP
+$!
+$   ENDIF
+$!
+$!  Add TCP/IP type to CC definitions.
+$!
+$   CCDEFS = CCDEFS + ",TCPIP_TYPE_''P3'"
+$!
+$!  Print info
+$!
+$   WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB- ","
+$!
+$!  Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$!  Tell The User We Don't Know What They Want.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The Option ",P3," Is Invalid.  The Valid Options Are:"
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "    SOCKETSHR  :  To link with SOCKETSHR TCP/IP library."
+$   WRITE SYS$OUTPUT "    UCX        :  To link with UCX TCP/IP library."
+$   WRITE SYS$OUTPUT "    TCPIP      :  To link with TCPIP (post UCX) TCP/IP library."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Time To EXIT.
+$!
+$   EXIT
+$!
+$!  Done with TCP/IP libraries
+$!
+$ ENDIF
+$!
+$! Finish up the definition of CC.
+$!
+$ IF COMPILER .EQS. "DECC"
+$ THEN
+$   IF CCDISABLEWARNINGS .NES. ""
+$   THEN
+$     CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
+$   ENDIF
+$ ELSE
+$   CCDISABLEWARNINGS = ""
+$ ENDIF
+$ CC2 = CC + " /DEFINE=(" + CCDEFS + ",_POSIX_C_SOURCE)" + CCDISABLEWARNINGS
+$ CC = CC + " /DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
+$!
+$! Show user the result
+$!
+$ WRITE/SYMBOL SYS$OUTPUT "Main Compiling Command: ",CC
+$!
+$! Special Threads For OpenVMS v7.1 Or Later
+$!
+$! Written By:  Richard Levitte
+$!              richard@levitte.org
+$!
+$!
+$! Check To See If We Have A Option For P4.
+$!
+$ IF (P4.EQS."")
+$ THEN
+$!
+$!  Get The Version Of VMS We Are Using.
+$!
+$   ISSEVEN :=
+$   TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
+$   TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
+$!
+$!  Check To See If The VMS Version Is v7.1 Or Later.
+$!
+$   IF (TMP.GE.71)
+$   THEN
+$!
+$!    We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
+$!
+$     ISSEVEN := ,PTHREAD_USE_D4
+$!
+$!  End The VMS Version Check.
+$!
+$   ENDIF
+$!
+$! End The P4 Check.
+$!
+$ ENDIF
+$!
+$! Check if the user wanted to compile just a subset of all the programs.
+$!
+$ IF P5 .NES. ""
+$ THEN
+$   PROGRAMS = P5
+$ ENDIF
+$!
+$!  Time To RETURN...
+$!
+$ RETURN
+$!
+$ INITIALISE:
+$!
+$! Save old value of the logical name OPENSSL
+$!
+$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
+$!
+$! Save directory information
+$!
+$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
+$ __HERE = F$EDIT(__HERE,"UPCASE")
+$ __TOP = __HERE - "APPS]"
+$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
+$!
+$! Set up the logical name OPENSSL to point at the include directory
+$!
+$ DEFINE OPENSSL /NOLOG '__INCLUDE'
+$!
+$! Done
+$!
+$ RETURN
+$!
+$ CLEANUP:
+$!
+$! Restore the saved logical name OPENSSL, if it had a value.
+$!
+$ if (f$type( __SAVE_OPENSSL) .nes. "")
+$ then
+$   IF __SAVE_OPENSSL .EQS. ""
+$   THEN
+$     DEASSIGN OPENSSL
+$   ELSE
+$     DEFINE /NOLOG OPENSSL '__SAVE_OPENSSL'
+$   ENDIF
+$ endif
+$!
+$! Close any open files.
+$!
+$ if (f$trnlnm( "objects", "LNM$PROCESS", 0, "SUPERVISOR") .nes. "") then -
+   close objects
+$!
+$! Done
+$!
+$ RETURN
+$!
diff --git a/openssl/apps/md4.c b/openssl/apps/md4.c
new file mode 120000
index 0000000..7f457b2
--- /dev/null
+++ b/openssl/apps/md4.c
@@ -0,0 +1 @@
+../crypto/md4/md4.c
\ No newline at end of file
diff --git a/openssl/apps/nseq.c b/openssl/apps/nseq.c
new file mode 100644
index 0000000..e3c4dba
--- /dev/null
+++ b/openssl/apps/nseq.c
@@ -0,0 +1,167 @@
+/* nseq.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+
+#undef PROG
+#define PROG nseq_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+{
+	char **args, *infile = NULL, *outfile = NULL;
+	BIO *in = NULL, *out = NULL;
+	int toseq = 0;
+	X509 *x509 = NULL;
+	NETSCAPE_CERT_SEQUENCE *seq = NULL;
+	int i, ret = 1;
+	int badarg = 0;
+	if (bio_err == NULL) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
+	ERR_load_crypto_strings();
+	args = argv + 1;
+	while (!badarg && *args && *args[0] == '-') {
+		if (!strcmp (*args, "-toseq")) toseq = 1;
+		else if (!strcmp (*args, "-in")) {
+			if (args[1]) {
+				args++;
+				infile = *args;
+			} else badarg = 1;
+		} else if (!strcmp (*args, "-out")) {
+			if (args[1]) {
+				args++;
+				outfile = *args;
+			} else badarg = 1;
+		} else badarg = 1;
+		args++;
+	}
+
+	if (badarg) {
+		BIO_printf (bio_err, "Netscape certificate sequence utility\n");
+		BIO_printf (bio_err, "Usage nseq [options]\n");
+		BIO_printf (bio_err, "where options are\n");
+		BIO_printf (bio_err, "-in file  input file\n");
+		BIO_printf (bio_err, "-out file output file\n");
+		BIO_printf (bio_err, "-toseq    output NS Sequence file\n");
+		OPENSSL_EXIT(1);
+	}
+
+	if (infile) {
+		if (!(in = BIO_new_file (infile, "r"))) {
+			BIO_printf (bio_err,
+				 "Can't open input file %s\n", infile);
+			goto end;
+		}
+	} else in = BIO_new_fp(stdin, BIO_NOCLOSE);
+
+	if (outfile) {
+		if (!(out = BIO_new_file (outfile, "w"))) {
+			BIO_printf (bio_err,
+				 "Can't open output file %s\n", outfile);
+			goto end;
+		}
+	} else {
+		out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+	}
+	if (toseq) {
+		seq = NETSCAPE_CERT_SEQUENCE_new();
+		seq->certs = sk_X509_new_null();
+		while((x509 = PEM_read_bio_X509(in, NULL, NULL, NULL))) 
+		    sk_X509_push(seq->certs,x509);
+
+		if(!sk_X509_num(seq->certs))
+		{
+			BIO_printf (bio_err, "Error reading certs file %s\n", infile);
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+		PEM_write_bio_NETSCAPE_CERT_SEQUENCE(out, seq);
+		ret = 0;
+		goto end;
+	}
+
+	if (!(seq = PEM_read_bio_NETSCAPE_CERT_SEQUENCE(in, NULL, NULL, NULL))) {
+		BIO_printf (bio_err, "Error reading sequence file %s\n", infile);
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+
+	for(i = 0; i < sk_X509_num(seq->certs); i++) {
+		x509 = sk_X509_value(seq->certs, i);
+		dump_cert_text(out, x509);
+		PEM_write_bio_X509(out, x509);
+	}
+	ret = 0;
+end:
+	BIO_free(in);
+	BIO_free_all(out);
+	NETSCAPE_CERT_SEQUENCE_free(seq);
+
+	OPENSSL_EXIT(ret);
+}
+
diff --git a/openssl/apps/ocsp.c b/openssl/apps/ocsp.c
new file mode 100644
index 0000000..01847df
--- /dev/null
+++ b/openssl/apps/ocsp.c
@@ -0,0 +1,1421 @@
+/* ocsp.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef OPENSSL_NO_OCSP
+
+#ifdef OPENSSL_SYS_VMS
+#define _XOPEN_SOURCE_EXTENDED	/* So fd_set and friends get properly defined
+				   on OpenVMS */
+#endif
+
+#define USE_SOCKETS
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "apps.h" /* needs to be included before the openssl headers! */
+#include <openssl/e_os2.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/x509v3.h>
+
+#if defined(NETWARE_CLIB)
+#  ifdef NETWARE_BSDSOCK
+#    include <sys/socket.h>
+#    include <sys/bsdskt.h>
+#  else
+#    include <novsock2.h>
+#  endif
+#elif defined(NETWARE_LIBC)
+#  ifdef NETWARE_BSDSOCK
+#    include <sys/select.h>
+#  else
+#    include <novsock2.h>
+#  endif
+#endif
+  
+/* Maximum leeway in validity period: default 5 minutes */
+#define MAX_VALIDITY_PERIOD	(5 * 60)
+
+static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md, X509 *issuer,
+				STACK_OF(OCSP_CERTID) *ids);
+static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, const EVP_MD * cert_id_md, X509 *issuer,
+				STACK_OF(OCSP_CERTID) *ids);
+static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
+			      STACK_OF(OPENSSL_STRING) *names,
+			      STACK_OF(OCSP_CERTID) *ids, long nsec,
+			      long maxage);
+
+static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
+			X509 *ca, X509 *rcert, EVP_PKEY *rkey,
+			STACK_OF(X509) *rother, unsigned long flags,
+			int nmin, int ndays);
+
+static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser);
+static BIO *init_responder(char *port);
+static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port);
+static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
+static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
+				STACK_OF(CONF_VALUE) *headers,
+				OCSP_REQUEST *req, int req_timeout);
+
+#undef PROG
+#define PROG ocsp_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	ENGINE *e = NULL;
+	char **args;
+	char *host = NULL, *port = NULL, *path = "/";
+	char *reqin = NULL, *respin = NULL;
+	char *reqout = NULL, *respout = NULL;
+	char *signfile = NULL, *keyfile = NULL;
+	char *rsignfile = NULL, *rkeyfile = NULL;
+	char *outfile = NULL;
+	int add_nonce = 1, noverify = 0, use_ssl = -1;
+	STACK_OF(CONF_VALUE) *headers = NULL;
+	OCSP_REQUEST *req = NULL;
+	OCSP_RESPONSE *resp = NULL;
+	OCSP_BASICRESP *bs = NULL;
+	X509 *issuer = NULL, *cert = NULL;
+	X509 *signer = NULL, *rsigner = NULL;
+	EVP_PKEY *key = NULL, *rkey = NULL;
+	BIO *acbio = NULL, *cbio = NULL;
+	BIO *derbio = NULL;
+	BIO *out = NULL;
+	int req_timeout = -1;
+	int req_text = 0, resp_text = 0;
+	long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
+	char *CAfile = NULL, *CApath = NULL;
+	X509_STORE *store = NULL;
+	STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
+	char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
+	unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
+	int ret = 1;
+	int accept_count = -1;
+	int badarg = 0;
+	int i;
+	int ignore_err = 0;
+	STACK_OF(OPENSSL_STRING) *reqnames = NULL;
+	STACK_OF(OCSP_CERTID) *ids = NULL;
+
+	X509 *rca_cert = NULL;
+	char *ridx_filename = NULL;
+	char *rca_filename = NULL;
+	CA_DB *rdb = NULL;
+	int nmin = 0, ndays = -1;
+	const EVP_MD *cert_id_md = NULL;
+
+	if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+	SSL_load_error_strings();
+	OpenSSL_add_ssl_algorithms();
+	args = argv + 1;
+	reqnames = sk_OPENSSL_STRING_new_null();
+	ids = sk_OCSP_CERTID_new_null();
+	while (!badarg && *args && *args[0] == '-')
+		{
+		if (!strcmp(*args, "-out"))
+			{
+			if (args[1])
+				{
+				args++;
+				outfile = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-timeout"))
+			{
+			if (args[1])
+				{
+				args++;
+				req_timeout = atol(*args);
+				if (req_timeout < 0)
+					{
+					BIO_printf(bio_err,
+						"Illegal timeout value %s\n",
+						*args);
+					badarg = 1;
+					}
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-url"))
+			{
+			if (args[1])
+				{
+				args++;
+				if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl))
+					{
+					BIO_printf(bio_err, "Error parsing URL\n");
+					badarg = 1;
+					}
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-host"))
+			{
+			if (args[1])
+				{
+				args++;
+				host = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-port"))
+			{
+			if (args[1])
+				{
+				args++;
+				port = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-header"))
+			{
+			if (args[1] && args[2])
+				{
+				if (!X509V3_add_value(args[1], args[2], &headers))
+					goto end;
+				args += 2;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-ignore_err"))
+			ignore_err = 1;
+		else if (!strcmp(*args, "-noverify"))
+			noverify = 1;
+		else if (!strcmp(*args, "-nonce"))
+			add_nonce = 2;
+		else if (!strcmp(*args, "-no_nonce"))
+			add_nonce = 0;
+		else if (!strcmp(*args, "-resp_no_certs"))
+			rflags |= OCSP_NOCERTS;
+		else if (!strcmp(*args, "-resp_key_id"))
+			rflags |= OCSP_RESPID_KEY;
+		else if (!strcmp(*args, "-no_certs"))
+			sign_flags |= OCSP_NOCERTS;
+		else if (!strcmp(*args, "-no_signature_verify"))
+			verify_flags |= OCSP_NOSIGS;
+		else if (!strcmp(*args, "-no_cert_verify"))
+			verify_flags |= OCSP_NOVERIFY;
+		else if (!strcmp(*args, "-no_chain"))
+			verify_flags |= OCSP_NOCHAIN;
+		else if (!strcmp(*args, "-no_cert_checks"))
+			verify_flags |= OCSP_NOCHECKS;
+		else if (!strcmp(*args, "-no_explicit"))
+			verify_flags |= OCSP_NOEXPLICIT;
+		else if (!strcmp(*args, "-trust_other"))
+			verify_flags |= OCSP_TRUSTOTHER;
+		else if (!strcmp(*args, "-no_intern"))
+			verify_flags |= OCSP_NOINTERN;
+		else if (!strcmp(*args, "-text"))
+			{
+			req_text = 1;
+			resp_text = 1;
+			}
+		else if (!strcmp(*args, "-req_text"))
+			req_text = 1;
+		else if (!strcmp(*args, "-resp_text"))
+			resp_text = 1;
+		else if (!strcmp(*args, "-reqin"))
+			{
+			if (args[1])
+				{
+				args++;
+				reqin = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-respin"))
+			{
+			if (args[1])
+				{
+				args++;
+				respin = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-signer"))
+			{
+			if (args[1])
+				{
+				args++;
+				signfile = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp (*args, "-VAfile"))
+			{
+			if (args[1])
+				{
+				args++;
+				verify_certfile = *args;
+				verify_flags |= OCSP_TRUSTOTHER;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-sign_other"))
+			{
+			if (args[1])
+				{
+				args++;
+				sign_certfile = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-verify_other"))
+			{
+			if (args[1])
+				{
+				args++;
+				verify_certfile = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp (*args, "-CAfile"))
+			{
+			if (args[1])
+				{
+				args++;
+				CAfile = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp (*args, "-CApath"))
+			{
+			if (args[1])
+				{
+				args++;
+				CApath = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp (*args, "-validity_period"))
+			{
+			if (args[1])
+				{
+				args++;
+				nsec = atol(*args);
+				if (nsec < 0)
+					{
+					BIO_printf(bio_err,
+						"Illegal validity period %s\n",
+						*args);
+					badarg = 1;
+					}
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp (*args, "-status_age"))
+			{
+			if (args[1])
+				{
+				args++;
+				maxage = atol(*args);
+				if (maxage < 0)
+					{
+					BIO_printf(bio_err,
+						"Illegal validity age %s\n",
+						*args);
+					badarg = 1;
+					}
+				}
+			else badarg = 1;
+			}
+		 else if (!strcmp(*args, "-signkey"))
+			{
+			if (args[1])
+				{
+				args++;
+				keyfile = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-reqout"))
+			{
+			if (args[1])
+				{
+				args++;
+				reqout = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-respout"))
+			{
+			if (args[1])
+				{
+				args++;
+				respout = *args;
+				}
+			else badarg = 1;
+			}
+		 else if (!strcmp(*args, "-path"))
+			{
+			if (args[1])
+				{
+				args++;
+				path = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-issuer"))
+			{
+			if (args[1])
+				{
+				args++;
+				X509_free(issuer);
+				issuer = load_cert(bio_err, *args, FORMAT_PEM,
+					NULL, e, "issuer certificate");
+				if(!issuer) goto end;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp (*args, "-cert"))
+			{
+			if (args[1])
+				{
+				args++;
+				X509_free(cert);
+				cert = load_cert(bio_err, *args, FORMAT_PEM,
+					NULL, e, "certificate");
+				if(!cert) goto end;
+				if (!cert_id_md) cert_id_md = EVP_sha1();
+				if(!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids))
+					goto end;
+				if(!sk_OPENSSL_STRING_push(reqnames, *args))
+					goto end;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-serial"))
+			{
+			if (args[1])
+				{
+				args++;
+				if (!cert_id_md) cert_id_md = EVP_sha1();
+				if(!add_ocsp_serial(&req, *args, cert_id_md, issuer, ids))
+					goto end;
+				if(!sk_OPENSSL_STRING_push(reqnames, *args))
+					goto end;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-index"))
+			{
+			if (args[1])
+				{
+				args++;
+				ridx_filename = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-CA"))
+			{
+			if (args[1])
+				{
+				args++;
+				rca_filename = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp (*args, "-nmin"))
+			{
+			if (args[1])
+				{
+				args++;
+				nmin = atol(*args);
+				if (nmin < 0)
+					{
+					BIO_printf(bio_err,
+						"Illegal update period %s\n",
+						*args);
+					badarg = 1;
+					}
+				}
+				if (ndays == -1)
+					ndays = 0;
+			else badarg = 1;
+			}
+		else if (!strcmp (*args, "-nrequest"))
+			{
+			if (args[1])
+				{
+				args++;
+				accept_count = atol(*args);
+				if (accept_count < 0)
+					{
+					BIO_printf(bio_err,
+						"Illegal accept count %s\n",
+						*args);
+					badarg = 1;
+					}
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp (*args, "-ndays"))
+			{
+			if (args[1])
+				{
+				args++;
+				ndays = atol(*args);
+				if (ndays < 0)
+					{
+					BIO_printf(bio_err,
+						"Illegal update period %s\n",
+						*args);
+					badarg = 1;
+					}
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-rsigner"))
+			{
+			if (args[1])
+				{
+				args++;
+				rsignfile = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-rkey"))
+			{
+			if (args[1])
+				{
+				args++;
+				rkeyfile = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args, "-rother"))
+			{
+			if (args[1])
+				{
+				args++;
+				rcertfile = *args;
+				}
+			else badarg = 1;
+			}
+		else if ((cert_id_md = EVP_get_digestbyname((*args)+1))==NULL)
+			{
+			badarg = 1;
+			}
+		args++;
+		}
+
+	/* Have we anything to do? */
+	if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1;
+
+	if (badarg)
+		{
+		BIO_printf (bio_err, "OCSP utility\n");
+		BIO_printf (bio_err, "Usage ocsp [options]\n");
+		BIO_printf (bio_err, "where options are\n");
+		BIO_printf (bio_err, "-out file          output filename\n");
+		BIO_printf (bio_err, "-issuer file       issuer certificate\n");
+		BIO_printf (bio_err, "-cert file         certificate to check\n");
+		BIO_printf (bio_err, "-serial n          serial number to check\n");
+		BIO_printf (bio_err, "-signer file       certificate to sign OCSP request with\n");
+		BIO_printf (bio_err, "-signkey file      private key to sign OCSP request with\n");
+		BIO_printf (bio_err, "-sign_other file   additional certificates to include in signed request\n");
+		BIO_printf (bio_err, "-no_certs          don't include any certificates in signed request\n");
+		BIO_printf (bio_err, "-req_text          print text form of request\n");
+		BIO_printf (bio_err, "-resp_text         print text form of response\n");
+		BIO_printf (bio_err, "-text              print text form of request and response\n");
+		BIO_printf (bio_err, "-reqout file       write DER encoded OCSP request to \"file\"\n");
+		BIO_printf (bio_err, "-respout file      write DER encoded OCSP reponse to \"file\"\n");
+		BIO_printf (bio_err, "-reqin file        read DER encoded OCSP request from \"file\"\n");
+		BIO_printf (bio_err, "-respin file       read DER encoded OCSP reponse from \"file\"\n");
+		BIO_printf (bio_err, "-nonce             add OCSP nonce to request\n");
+		BIO_printf (bio_err, "-no_nonce          don't add OCSP nonce to request\n");
+		BIO_printf (bio_err, "-url URL           OCSP responder URL\n");
+		BIO_printf (bio_err, "-host host:n       send OCSP request to host on port n\n");
+		BIO_printf (bio_err, "-path              path to use in OCSP request\n");
+		BIO_printf (bio_err, "-CApath dir        trusted certificates directory\n");
+		BIO_printf (bio_err, "-CAfile file       trusted certificates file\n");
+		BIO_printf (bio_err, "-VAfile file       validator certificates file\n");
+		BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
+		BIO_printf (bio_err, "-status_age n      maximum status age in seconds\n");
+		BIO_printf (bio_err, "-noverify          don't verify response at all\n");
+		BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n");
+		BIO_printf (bio_err, "-trust_other       don't verify additional certificates\n");
+		BIO_printf (bio_err, "-no_intern         don't search certificates contained in response for signer\n");
+		BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n");
+		BIO_printf (bio_err, "-no_cert_verify    don't check signing certificate\n");
+		BIO_printf (bio_err, "-no_chain          don't chain verify response\n");
+		BIO_printf (bio_err, "-no_cert_checks    don't do additional checks on signing certificate\n");
+		BIO_printf (bio_err, "-port num		 port to run responder on\n");
+		BIO_printf (bio_err, "-index file	 certificate status index file\n");
+		BIO_printf (bio_err, "-CA file		 CA certificate\n");
+		BIO_printf (bio_err, "-rsigner file	 responder certificate to sign responses with\n");
+		BIO_printf (bio_err, "-rkey file	 responder key to sign responses with\n");
+		BIO_printf (bio_err, "-rother file	 other certificates to include in response\n");
+		BIO_printf (bio_err, "-resp_no_certs     don't include any certificates in response\n");
+		BIO_printf (bio_err, "-nmin n	 	 number of minutes before next update\n");
+		BIO_printf (bio_err, "-ndays n	 	 number of days before next update\n");
+		BIO_printf (bio_err, "-resp_key_id       identify reponse by signing certificate key ID\n");
+		BIO_printf (bio_err, "-nrequest n        number of requests to accept (default unlimited)\n");
+		BIO_printf (bio_err, "-<dgst alg>     use specified digest in the request");
+		goto end;
+		}
+
+	if(outfile) out = BIO_new_file(outfile, "w");
+	else out = BIO_new_fp(stdout, BIO_NOCLOSE);
+
+	if(!out)
+		{
+		BIO_printf(bio_err, "Error opening output file\n");
+		goto end;
+		}
+
+	if (!req && (add_nonce != 2)) add_nonce = 0;
+
+	if (!req && reqin)
+		{
+		derbio = BIO_new_file(reqin, "rb");
+		if (!derbio)
+			{
+			BIO_printf(bio_err, "Error Opening OCSP request file\n");
+			goto end;
+			}
+		req = d2i_OCSP_REQUEST_bio(derbio, NULL);
+		BIO_free(derbio);
+		if(!req)
+			{
+			BIO_printf(bio_err, "Error reading OCSP request\n");
+			goto end;
+			}
+		}
+
+	if (!req && port)
+		{
+		acbio = init_responder(port);
+		if (!acbio)
+			goto end;
+		}
+
+	if (rsignfile && !rdb)
+		{
+		if (!rkeyfile) rkeyfile = rsignfile;
+		rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM,
+			NULL, e, "responder certificate");
+		if (!rsigner)
+			{
+			BIO_printf(bio_err, "Error loading responder certificate\n");
+			goto end;
+			}
+		rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM,
+			NULL, e, "CA certificate");
+		if (rcertfile)
+			{
+			rother = load_certs(bio_err, rcertfile, FORMAT_PEM,
+				NULL, e, "responder other certificates");
+			if (!rother) goto end;
+			}
+		rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL,
+			"responder private key");
+		if (!rkey)
+			goto end;
+		}
+	if(acbio)
+		BIO_printf(bio_err, "Waiting for OCSP client connections...\n");
+
+	redo_accept:
+
+	if (acbio)
+		{
+		if (!do_responder(&req, &cbio, acbio, port))
+			goto end;
+		if (!req)
+			{
+			resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
+			send_ocsp_response(cbio, resp);
+			goto done_resp;
+			}
+		}
+
+	if (!req && (signfile || reqout || host || add_nonce || ridx_filename))
+		{
+		BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
+		goto end;
+		}
+
+	if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1);
+
+	if (signfile)
+		{
+		if (!keyfile) keyfile = signfile;
+		signer = load_cert(bio_err, signfile, FORMAT_PEM,
+			NULL, e, "signer certificate");
+		if (!signer)
+			{
+			BIO_printf(bio_err, "Error loading signer certificate\n");
+			goto end;
+			}
+		if (sign_certfile)
+			{
+			sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM,
+				NULL, e, "signer certificates");
+			if (!sign_other) goto end;
+			}
+		key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL,
+			"signer private key");
+		if (!key)
+			goto end;
+
+		if (!OCSP_request_sign(req, signer, key, NULL, sign_other, sign_flags))
+			{
+			BIO_printf(bio_err, "Error signing OCSP request\n");
+			goto end;
+			}
+		}
+
+	if (req_text && req) OCSP_REQUEST_print(out, req, 0);
+
+	if (reqout)
+		{
+		derbio = BIO_new_file(reqout, "wb");
+		if(!derbio)
+			{
+			BIO_printf(bio_err, "Error opening file %s\n", reqout);
+			goto end;
+			}
+		i2d_OCSP_REQUEST_bio(derbio, req);
+		BIO_free(derbio);
+		}
+
+	if (ridx_filename && (!rkey || !rsigner || !rca_cert))
+		{
+		BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n");
+		goto end;
+		}
+
+	if (ridx_filename && !rdb)
+		{
+		rdb = load_index(ridx_filename, NULL);
+		if (!rdb) goto end;
+		if (!index_index(rdb)) goto end;
+		}
+
+	if (rdb)
+		{
+		i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays);
+		if (cbio)
+			send_ocsp_response(cbio, resp);
+		}
+	else if (host)
+		{
+#ifndef OPENSSL_NO_SOCK
+		resp = process_responder(bio_err, req, host, path,
+					port, use_ssl, headers, req_timeout);
+		if (!resp)
+			goto end;
+#else
+		BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n");
+		goto end;
+#endif
+		}
+	else if (respin)
+		{
+		derbio = BIO_new_file(respin, "rb");
+		if (!derbio)
+			{
+			BIO_printf(bio_err, "Error Opening OCSP response file\n");
+			goto end;
+			}
+		resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
+		BIO_free(derbio);
+		if(!resp)
+			{
+			BIO_printf(bio_err, "Error reading OCSP response\n");
+			goto end;
+			}
+	
+		}
+	else
+		{
+		ret = 0;
+		goto end;
+		}
+
+	done_resp:
+
+	if (respout)
+		{
+		derbio = BIO_new_file(respout, "wb");
+		if(!derbio)
+			{
+			BIO_printf(bio_err, "Error opening file %s\n", respout);
+			goto end;
+			}
+		i2d_OCSP_RESPONSE_bio(derbio, resp);
+		BIO_free(derbio);
+		}
+
+	i = OCSP_response_status(resp);
+
+	if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL)
+		{
+		BIO_printf(out, "Responder Error: %s (%d)\n",
+				OCSP_response_status_str(i), i);
+		if (ignore_err)
+			goto redo_accept;
+		ret = 0;
+		goto end;
+		}
+
+	if (resp_text) OCSP_RESPONSE_print(out, resp, 0);
+
+	/* If running as responder don't verify our own response */
+	if (cbio)
+		{
+		if (accept_count > 0)
+			accept_count--;
+		/* Redo if more connections needed */
+		if (accept_count)
+			{
+			BIO_free_all(cbio);
+			cbio = NULL;
+			OCSP_REQUEST_free(req);
+			req = NULL;
+			OCSP_RESPONSE_free(resp);
+			resp = NULL;
+			goto redo_accept;
+			}
+		goto end;
+		}
+
+	if (!store)
+		store = setup_verify(bio_err, CAfile, CApath);
+	if (!store)
+		goto end;
+	if (verify_certfile)
+		{
+		verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM,
+			NULL, e, "validator certificate");
+		if (!verify_other) goto end;
+		}
+
+	bs = OCSP_response_get1_basic(resp);
+
+	if (!bs)
+		{
+		BIO_printf(bio_err, "Error parsing response\n");
+		goto end;
+		}
+
+	if (!noverify)
+		{
+		if (req && ((i = OCSP_check_nonce(req, bs)) <= 0))
+			{
+			if (i == -1)
+				BIO_printf(bio_err, "WARNING: no nonce in response\n");
+			else
+				{
+				BIO_printf(bio_err, "Nonce Verify error\n");
+				goto end;
+				}
+			}
+
+		i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
+                if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0);
+
+		if(i <= 0)
+			{
+			BIO_printf(bio_err, "Response Verify Failure\n");
+			ERR_print_errors(bio_err);
+			}
+		else
+			BIO_printf(bio_err, "Response verify OK\n");
+
+		}
+
+	if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage))
+		goto end;
+
+	ret = 0;
+
+end:
+	ERR_print_errors(bio_err);
+	X509_free(signer);
+	X509_STORE_free(store);
+	EVP_PKEY_free(key);
+	EVP_PKEY_free(rkey);
+	X509_free(issuer);
+	X509_free(cert);
+	X509_free(rsigner);
+	X509_free(rca_cert);
+	free_index(rdb);
+	BIO_free_all(cbio);
+	BIO_free_all(acbio);
+	BIO_free(out);
+	OCSP_REQUEST_free(req);
+	OCSP_RESPONSE_free(resp);
+	OCSP_BASICRESP_free(bs);
+	sk_OPENSSL_STRING_free(reqnames);
+	sk_OCSP_CERTID_free(ids);
+	sk_X509_pop_free(sign_other, X509_free);
+	sk_X509_pop_free(verify_other, X509_free);
+	sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);
+
+	if (use_ssl != -1)
+		{
+		OPENSSL_free(host);
+		OPENSSL_free(port);
+		OPENSSL_free(path);
+		}
+
+	OPENSSL_EXIT(ret);
+}
+
+static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md,X509 *issuer,
+				STACK_OF(OCSP_CERTID) *ids)
+	{
+	OCSP_CERTID *id;
+	if(!issuer)
+		{
+		BIO_printf(bio_err, "No issuer certificate specified\n");
+		return 0;
+		}
+	if(!*req) *req = OCSP_REQUEST_new();
+	if(!*req) goto err;
+	id = OCSP_cert_to_id(cert_id_md, cert, issuer);
+	if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
+	if(!OCSP_request_add0_id(*req, id)) goto err;
+	return 1;
+
+	err:
+	BIO_printf(bio_err, "Error Creating OCSP request\n");
+	return 0;
+	}
+
+static int add_ocsp_serial(OCSP_REQUEST **req, char *serial,const EVP_MD *cert_id_md, X509 *issuer,
+				STACK_OF(OCSP_CERTID) *ids)
+	{
+	OCSP_CERTID *id;
+	X509_NAME *iname;
+	ASN1_BIT_STRING *ikey;
+	ASN1_INTEGER *sno;
+	if(!issuer)
+		{
+		BIO_printf(bio_err, "No issuer certificate specified\n");
+		return 0;
+		}
+	if(!*req) *req = OCSP_REQUEST_new();
+	if(!*req) goto err;
+	iname = X509_get_subject_name(issuer);
+	ikey = X509_get0_pubkey_bitstr(issuer);
+	sno = s2i_ASN1_INTEGER(NULL, serial);
+	if(!sno)
+		{
+		BIO_printf(bio_err, "Error converting serial number %s\n", serial);
+		return 0;
+		}
+	id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno);
+	ASN1_INTEGER_free(sno);
+	if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
+	if(!OCSP_request_add0_id(*req, id)) goto err;
+	return 1;
+
+	err:
+	BIO_printf(bio_err, "Error Creating OCSP request\n");
+	return 0;
+	}
+
+static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
+			      STACK_OF(OPENSSL_STRING) *names,
+			      STACK_OF(OCSP_CERTID) *ids, long nsec,
+			      long maxage)
+	{
+	OCSP_CERTID *id;
+	char *name;
+	int i;
+
+	int status, reason;
+
+	ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
+
+	if (!bs || !req || !sk_OPENSSL_STRING_num(names) || !sk_OCSP_CERTID_num(ids))
+		return 1;
+
+	for (i = 0; i < sk_OCSP_CERTID_num(ids); i++)
+		{
+		id = sk_OCSP_CERTID_value(ids, i);
+		name = sk_OPENSSL_STRING_value(names, i);
+		BIO_printf(out, "%s: ", name);
+
+		if(!OCSP_resp_find_status(bs, id, &status, &reason,
+					&rev, &thisupd, &nextupd))
+			{
+			BIO_puts(out, "ERROR: No Status found.\n");
+			continue;
+			}
+
+		/* Check validity: if invalid write to output BIO so we
+		 * know which response this refers to.
+		 */
+		if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage))
+			{
+			BIO_puts(out, "WARNING: Status times invalid.\n");
+			ERR_print_errors(out);
+			}
+		BIO_printf(out, "%s\n", OCSP_cert_status_str(status));
+
+		BIO_puts(out, "\tThis Update: ");
+		ASN1_GENERALIZEDTIME_print(out, thisupd);
+		BIO_puts(out, "\n");
+
+		if(nextupd)
+			{
+			BIO_puts(out, "\tNext Update: ");
+			ASN1_GENERALIZEDTIME_print(out, nextupd);
+			BIO_puts(out, "\n");
+			}
+
+		if (status != V_OCSP_CERTSTATUS_REVOKED)
+			continue;
+
+		if (reason != -1)
+			BIO_printf(out, "\tReason: %s\n",
+				OCSP_crl_reason_str(reason));
+
+		BIO_puts(out, "\tRevocation Time: ");
+		ASN1_GENERALIZEDTIME_print(out, rev);
+		BIO_puts(out, "\n");
+		}
+
+	return 1;
+	}
+
+
+static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
+			X509 *ca, X509 *rcert, EVP_PKEY *rkey,
+			STACK_OF(X509) *rother, unsigned long flags,
+			int nmin, int ndays)
+	{
+	ASN1_TIME *thisupd = NULL, *nextupd = NULL;
+	OCSP_CERTID *cid, *ca_id = NULL;
+	OCSP_BASICRESP *bs = NULL;
+	int i, id_count, ret = 1;
+
+	id_count = OCSP_request_onereq_count(req);
+
+	if (id_count <= 0)
+		{
+		*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
+		goto end;
+		}
+
+
+	bs = OCSP_BASICRESP_new();
+	thisupd = X509_gmtime_adj(NULL, 0);
+	if (ndays != -1)
+		nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24 );
+
+	/* Examine each certificate id in the request */
+	for (i = 0; i < id_count; i++)
+		{
+		OCSP_ONEREQ *one;
+		ASN1_INTEGER *serial;
+		char **inf;
+		ASN1_OBJECT *cert_id_md_oid;
+		const EVP_MD *cert_id_md;
+		one = OCSP_request_onereq_get0(req, i);
+		cid = OCSP_onereq_get0_id(one);
+
+		OCSP_id_get0_info(NULL,&cert_id_md_oid, NULL,NULL, cid);
+
+		cert_id_md = EVP_get_digestbyobj(cert_id_md_oid);	
+		if (! cert_id_md) 
+			{
+			*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR,
+				NULL);
+				goto end;
+			}	
+		if (ca_id) OCSP_CERTID_free(ca_id);
+		ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca);
+
+		/* Is this request about our CA? */
+		if (OCSP_id_issuer_cmp(ca_id, cid))
+			{
+			OCSP_basic_add1_status(bs, cid,
+						V_OCSP_CERTSTATUS_UNKNOWN,
+						0, NULL,
+						thisupd, nextupd);
+			continue;
+			}
+		OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid);
+		inf = lookup_serial(db, serial);
+		if (!inf)
+			OCSP_basic_add1_status(bs, cid,
+						V_OCSP_CERTSTATUS_UNKNOWN,
+						0, NULL,
+						thisupd, nextupd);
+		else if (inf[DB_type][0] == DB_TYPE_VAL)
+			OCSP_basic_add1_status(bs, cid,
+						V_OCSP_CERTSTATUS_GOOD,
+						0, NULL,
+						thisupd, nextupd);
+		else if (inf[DB_type][0] == DB_TYPE_REV)
+			{
+			ASN1_OBJECT *inst = NULL;
+			ASN1_TIME *revtm = NULL;
+			ASN1_GENERALIZEDTIME *invtm = NULL;
+			OCSP_SINGLERESP *single;
+			int reason = -1;
+			unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]);
+			single = OCSP_basic_add1_status(bs, cid,
+						V_OCSP_CERTSTATUS_REVOKED,
+						reason, revtm,
+						thisupd, nextupd);
+			if (invtm)
+				OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invtm, 0, 0);
+			else if (inst)
+				OCSP_SINGLERESP_add1_ext_i2d(single, NID_hold_instruction_code, inst, 0, 0);
+			ASN1_OBJECT_free(inst);
+			ASN1_TIME_free(revtm);
+			ASN1_GENERALIZEDTIME_free(invtm);
+			}
+		}
+
+	OCSP_copy_nonce(bs, req);
+	
+	OCSP_basic_sign(bs, rcert, rkey, NULL, rother, flags);
+
+	*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
+
+	end:
+	ASN1_TIME_free(thisupd);
+	ASN1_TIME_free(nextupd);
+	OCSP_CERTID_free(ca_id);
+	OCSP_BASICRESP_free(bs);
+	return ret;
+
+	}
+
+static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser)
+	{
+	int i;
+	BIGNUM *bn = NULL;
+	char *itmp, *row[DB_NUMBER],**rrow;
+	for (i = 0; i < DB_NUMBER; i++) row[i] = NULL;
+	bn = ASN1_INTEGER_to_BN(ser,NULL);
+	OPENSSL_assert(bn); /* FIXME: should report an error at this point and abort */
+	if (BN_is_zero(bn))
+		itmp = BUF_strdup("00");
+	else
+		itmp = BN_bn2hex(bn);
+	row[DB_serial] = itmp;
+	BN_free(bn);
+	rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
+	OPENSSL_free(itmp);
+	return rrow;
+	}
+
+/* Quick and dirty OCSP server: read in and parse input request */
+
+static BIO *init_responder(char *port)
+	{
+	BIO *acbio = NULL, *bufbio = NULL;
+	bufbio = BIO_new(BIO_f_buffer());
+	if (!bufbio) 
+		goto err;
+#ifndef OPENSSL_NO_SOCK
+	acbio = BIO_new_accept(port);
+#else
+	BIO_printf(bio_err, "Error setting up accept BIO - sockets not supported.\n");
+#endif
+	if (!acbio)
+		goto err;
+	BIO_set_accept_bios(acbio, bufbio);
+	bufbio = NULL;
+
+	if (BIO_do_accept(acbio) <= 0)
+		{
+			BIO_printf(bio_err, "Error setting up accept BIO\n");
+			ERR_print_errors(bio_err);
+			goto err;
+		}
+
+	return acbio;
+
+	err:
+	BIO_free_all(acbio);
+	BIO_free(bufbio);
+	return NULL;
+	}
+
+static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port)
+	{
+	int have_post = 0, len;
+	OCSP_REQUEST *req = NULL;
+	char inbuf[1024];
+	BIO *cbio = NULL;
+
+	if (BIO_do_accept(acbio) <= 0)
+		{
+			BIO_printf(bio_err, "Error accepting connection\n");
+			ERR_print_errors(bio_err);
+			return 0;
+		}
+
+	cbio = BIO_pop(acbio);
+	*pcbio = cbio;
+
+	for(;;)
+		{
+		len = BIO_gets(cbio, inbuf, sizeof inbuf);
+		if (len <= 0)
+			return 1;
+		/* Look for "POST" signalling start of query */
+		if (!have_post)
+			{
+			if(strncmp(inbuf, "POST", 4))
+				{
+				BIO_printf(bio_err, "Invalid request\n");
+				return 1;
+				}
+			have_post = 1;
+			}
+		/* Look for end of headers */
+		if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))
+			break;
+		}
+
+	/* Try to read OCSP request */
+
+	req = d2i_OCSP_REQUEST_bio(cbio, NULL);
+
+	if (!req)
+		{
+		BIO_printf(bio_err, "Error parsing OCSP request\n");
+		ERR_print_errors(bio_err);
+		}
+
+	*preq = req;
+
+	return 1;
+
+	}
+
+static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
+	{
+	char http_resp[] = 
+		"HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n"
+		"Content-Length: %d\r\n\r\n";
+	if (!cbio)
+		return 0;
+	BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL));
+	i2d_OCSP_RESPONSE_bio(cbio, resp);
+	(void)BIO_flush(cbio);
+	return 1;
+	}
+
+static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
+				STACK_OF(CONF_VALUE) *headers,
+				OCSP_REQUEST *req, int req_timeout)
+	{
+	int fd;
+	int rv;
+	int i;
+	OCSP_REQ_CTX *ctx = NULL;
+	OCSP_RESPONSE *rsp = NULL;
+	fd_set confds;
+	struct timeval tv;
+
+	if (req_timeout != -1)
+		BIO_set_nbio(cbio, 1);
+
+	rv = BIO_do_connect(cbio);
+
+	if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio)))
+		{
+		BIO_puts(err, "Error connecting BIO\n");
+		return NULL;
+		}
+
+	if (BIO_get_fd(cbio, &fd) <= 0)
+		{
+		BIO_puts(err, "Can't get connection fd\n");
+		goto err;
+		}
+
+	if (req_timeout != -1 && rv <= 0)
+		{
+		FD_ZERO(&confds);
+		openssl_fdset(fd, &confds);
+		tv.tv_usec = 0;
+		tv.tv_sec = req_timeout;
+		rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
+		if (rv == 0)
+			{
+			BIO_puts(err, "Timeout on connect\n");
+			return NULL;
+			}
+		}
+
+
+	ctx = OCSP_sendreq_new(cbio, path, NULL, -1);
+	if (!ctx)
+		return NULL;
+
+	for (i = 0; i < sk_CONF_VALUE_num(headers); i++)
+		{
+		CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i);
+		if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value))
+			goto err;
+		}
+
+	if (!OCSP_REQ_CTX_set1_req(ctx, req))
+		goto err;
+	
+	for (;;)
+		{
+		rv = OCSP_sendreq_nbio(&rsp, ctx);
+		if (rv != -1)
+			break;
+		if (req_timeout == -1)
+			continue;
+		FD_ZERO(&confds);
+		openssl_fdset(fd, &confds);
+		tv.tv_usec = 0;
+		tv.tv_sec = req_timeout;
+		if (BIO_should_read(cbio))
+			rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv);
+		else if (BIO_should_write(cbio))
+			rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
+		else
+			{
+			BIO_puts(err, "Unexpected retry condition\n");
+			goto err;
+			}
+		if (rv == 0)
+			{
+			BIO_puts(err, "Timeout on request\n");
+			break;
+			}
+		if (rv == -1)
+			{
+			BIO_puts(err, "Select error\n");
+			break;
+			}
+
+		}
+	err:
+	if (ctx)
+		OCSP_REQ_CTX_free(ctx);
+
+	return rsp;
+	}
+
+OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
+			char *host, char *path, char *port, int use_ssl,
+			STACK_OF(CONF_VALUE) *headers,
+			int req_timeout)
+	{
+	BIO *cbio = NULL;
+	SSL_CTX *ctx = NULL;
+	OCSP_RESPONSE *resp = NULL;
+	cbio = BIO_new_connect(host);
+	if (!cbio)
+		{
+		BIO_printf(err, "Error creating connect BIO\n");
+		goto end;
+		}
+	if (port) BIO_set_conn_port(cbio, port);
+	if (use_ssl == 1)
+		{
+		BIO *sbio;
+#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
+		ctx = SSL_CTX_new(SSLv23_client_method());
+#elif !defined(OPENSSL_NO_SSL3)
+		ctx = SSL_CTX_new(SSLv3_client_method());
+#elif !defined(OPENSSL_NO_SSL2)
+		ctx = SSL_CTX_new(SSLv2_client_method());
+#else
+		BIO_printf(err, "SSL is disabled\n");
+			goto end;
+#endif
+		if (ctx == NULL)
+			{
+			BIO_printf(err, "Error creating SSL context.\n");
+			goto end;
+			}
+		SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
+		sbio = BIO_new_ssl(ctx, 1);
+		cbio = BIO_push(sbio, cbio);
+		}
+	resp = query_responder(err, cbio, path, headers, req, req_timeout);
+	if (!resp)
+		BIO_printf(bio_err, "Error querying OCSP responsder\n");
+	end:
+	if (cbio)
+		BIO_free_all(cbio);
+	if (ctx)
+		SSL_CTX_free(ctx);
+	return resp;
+	}
+
+#endif
diff --git a/openssl/apps/oid.cnf b/openssl/apps/oid.cnf
new file mode 100644
index 0000000..faf425a
--- /dev/null
+++ b/openssl/apps/oid.cnf
@@ -0,0 +1,6 @@
+2.99999.1       SET.ex1         SET x509v3 extension 1
+2.99999.2       SET.ex2         SET x509v3 extension 2
+2.99999.3       SET.ex3         SET x509v3 extension 3
+2.99999.4       SET.ex4         SET x509v3 extension 4
+2.99999.5       SET.ex5         SET x509v3 extension 5
+2.99999.6       SET.ex6         SET x509v3 extension 6
diff --git a/openssl/apps/openssl-vms.cnf b/openssl/apps/openssl-vms.cnf
new file mode 100644
index 0000000..45e46a0
--- /dev/null
+++ b/openssl/apps/openssl-vms.cnf
@@ -0,0 +1,350 @@
+#
+# OpenSSL example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME			= .
+RANDFILE		= $ENV::HOME/.rnd
+
+# Extra OBJECT IDENTIFIER info:
+#oid_file		= $ENV::HOME/.oid
+oid_section		= new_oids
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions		= 
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+# Policies used by the TSA examples.
+tsa_policy1 = 1.2.3.4.1
+tsa_policy2 = 1.2.3.4.5.6
+tsa_policy3 = 1.2.3.4.5.7
+
+####################################################################
+[ ca ]
+default_ca	= CA_default		# The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir		= sys\$disk:[.demoCA		# Where everything is kept
+certs		= $dir.certs]		# Where the issued certs are kept
+crl_dir		= $dir.crl]		# Where the issued crl are kept
+database	= $dir]index.txt	# database index file.
+#unique_subject	= no			# Set to 'no' to allow creation of
+					# several ctificates with same subject.
+new_certs_dir	= $dir.newcerts]		# default place for new certs.
+
+certificate	= $dir]cacert.pem 	# The CA certificate
+serial		= $dir]serial. 		# The current serial number
+crlnumber	= $dir]crlnumber.	# the current crl number
+					# must be commented out to leave a V1 CRL
+crl		= $dir]crl.pem 		# The current CRL
+private_key	= $dir.private]cakey.pem# The private key
+RANDFILE	= $dir.private].rand	# private random number file
+
+x509_extensions	= usr_cert		# The extentions to add to the cert
+
+# Comment out the following two lines for the "traditional"
+# (and highly broken) format.
+name_opt 	= ca_default		# Subject Name options
+cert_opt 	= ca_default		# Certificate field options
+
+# Extension copying option: use with caution.
+# copy_extensions = copy
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crlnumber must also be commented out to leave a V1 CRL.
+# crl_extensions	= crl_ext
+
+default_days	= 365			# how long to certify for
+default_crl_days= 30			# how long before next CRL
+default_md	= default		# use public key default MD
+preserve	= no			# keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy		= policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName		= match
+stateOrProvinceName	= match
+organizationName	= match
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName		= optional
+stateOrProvinceName	= optional
+localityName		= optional
+organizationName	= optional
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+####################################################################
+[ req ]
+default_bits		= 1024
+default_keyfile 	= privkey.pem
+distinguished_name	= req_distinguished_name
+attributes		= req_attributes
+x509_extensions	= v3_ca	# The extentions to add to the self signed cert
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options. 
+# default: PrintableString, T61String, BMPString.
+# pkix	 : PrintableString, BMPString (PKIX recommendation before 2004)
+# utf8only: only UTF8Strings (PKIX recommendation after 2004).
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
+string_mask = utf8only
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= AU
+countryName_min			= 2
+countryName_max			= 2
+
+stateOrProvinceName		= State or Province Name (full name)
+stateOrProvinceName_default	= Some-State
+
+localityName			= Locality Name (eg, city)
+
+0.organizationName		= Organization Name (eg, company)
+0.organizationName_default	= Internet Widgits Pty Ltd
+
+# we can do this but it is not needed normally :-)
+#1.organizationName		= Second Organization Name (eg, company)
+#1.organizationName_default	= World Wide Web Pty Ltd
+
+organizationalUnitName		= Organizational Unit Name (eg, section)
+#organizationalUnitName_default	=
+
+commonName			= Common Name (e.g. server FQDN or YOUR name)
+commonName_max			= 64
+
+emailAddress			= Email Address
+emailAddress_max		= 64
+
+# SET-ex3			= SET extension number 3
+
+[ req_attributes ]
+challengePassword		= A challenge password
+challengePassword_min		= 4
+challengePassword_max		= 20
+
+unstructuredName		= An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This is required for TSA certificates.
+# extendedKeyUsage = critical,timeStamping
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+basicConstraints = CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
+
+####################################################################
+[ tsa ]
+
+default_tsa = tsa_config1	# the default TSA section
+
+[ tsa_config1 ]
+
+# These are used by the TSA reply generation only.
+dir		= sys\$disk:[.demoCA		# TSA root directory
+serial		= $dir]tsaserial.	# The current serial number (mandatory)
+crypto_device	= builtin		# OpenSSL engine to use for signing
+signer_cert	= $dir/tsacert.pem 	# The TSA signing certificate
+					# (optional)
+certs		= $dir.cacert.pem]	# Certificate chain to include in reply
+					# (optional)
+signer_key	= $dir/private/tsakey.pem # The TSA private key (optional)
+
+default_policy	= tsa_policy1		# Policy if request did not specify it
+					# (optional)
+other_policies	= tsa_policy2, tsa_policy3	# acceptable policies (optional)
+digests		= md5, sha1		# Acceptable message digests (mandatory)
+accuracy	= secs:1, millisecs:500, microsecs:100	# (optional)
+clock_precision_digits  = 0	# number of digits after dot. (optional)
+ordering		= yes	# Is ordering defined for timestamps?
+				# (optional, default: no)
+tsa_name		= yes	# Must the TSA name be included in the reply?
+				# (optional, default: no)
+ess_cert_id_chain	= no	# Must the ESS cert id chain be included?
+				# (optional, default: no)
diff --git a/openssl/apps/openssl.c b/openssl/apps/openssl.c
new file mode 100644
index 0000000..1068957
--- /dev/null
+++ b/openssl/apps/openssl.c
@@ -0,0 +1,714 @@
+/* apps/openssl.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#define OPENSSL_C /* tells apps.h to use complete apps_startup() */
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+#include <openssl/conf.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#define USE_SOCKETS /* needed for the _O_BINARY defs in the MS world */
+#include "progs.h"
+#include "s_apps.h"
+#include <openssl/err.h>
+
+/* The LHASH callbacks ("hash" & "cmp") have been replaced by functions with the
+ * base prototypes (we cast each variable inside the function to the required
+ * type of "FUNCTION*"). This removes the necessity for macro-generated wrapper
+ * functions. */
+
+static LHASH_OF(FUNCTION) *prog_init(void );
+static int do_cmd(LHASH_OF(FUNCTION) *prog,int argc,char *argv[]);
+static void list_pkey(BIO *out);
+static void list_cipher(BIO *out);
+static void list_md(BIO *out);
+char *default_config_file=NULL;
+
+/* Make sure there is only one when MONOLITH is defined */
+#ifdef MONOLITH
+CONF *config=NULL;
+BIO *bio_err=NULL;
+#endif
+
+
+static void lock_dbg_cb(int mode, int type, const char *file, int line)
+	{
+	static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */
+	const char *errstr = NULL;
+	int rw;
+	
+	rw = mode & (CRYPTO_READ|CRYPTO_WRITE);
+	if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE)))
+		{
+		errstr = "invalid mode";
+		goto err;
+		}
+
+	if (type < 0 || type >= CRYPTO_NUM_LOCKS)
+		{
+		errstr = "type out of bounds";
+		goto err;
+		}
+
+	if (mode & CRYPTO_LOCK)
+		{
+		if (modes[type])
+			{
+			errstr = "already locked";
+			/* must not happen in a single-threaded program
+			 * (would deadlock) */
+			goto err;
+			}
+
+		modes[type] = rw;
+		}
+	else if (mode & CRYPTO_UNLOCK)
+		{
+		if (!modes[type])
+			{
+			errstr = "not locked";
+			goto err;
+			}
+		
+		if (modes[type] != rw)
+			{
+			errstr = (rw == CRYPTO_READ) ?
+				"CRYPTO_r_unlock on write lock" :
+				"CRYPTO_w_unlock on read lock";
+			}
+
+		modes[type] = 0;
+		}
+	else
+		{
+		errstr = "invalid mode";
+		goto err;
+		}
+
+ err:
+	if (errstr)
+		{
+		/* we cannot use bio_err here */
+		fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n",
+			errstr, mode, type, file, line);
+		}
+	}
+
+#if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64)
+# define ARGV _Argv
+#else
+# define ARGV Argv
+#endif
+
+int main(int Argc, char *ARGV[])
+	{
+	ARGS arg;
+#define PROG_NAME_SIZE	39
+	char pname[PROG_NAME_SIZE+1];
+	FUNCTION f,*fp;
+	MS_STATIC const char *prompt;
+	MS_STATIC char buf[1024];
+	char *to_free=NULL;
+	int n,i,ret=0;
+	int argc;
+	char **argv,*p;
+	LHASH_OF(FUNCTION) *prog=NULL;
+	long errline;
+
+#if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64)
+	/* 2011-03-22 SMS.
+	 * If we have 32-bit pointers everywhere, then we're safe, and
+	 * we bypass this mess, as on non-VMS systems.  (See ARGV,
+	 * above.)
+	 * Problem 1: Compaq/HP C before V7.3 always used 32-bit
+	 * pointers for argv[].
+	 * Fix 1: For a 32-bit argv[], when we're using 64-bit pointers
+	 * everywhere else, we always allocate and use a 64-bit
+	 * duplicate of argv[].
+	 * Problem 2: Compaq/HP C V7.3 (Alpha, IA64) before ECO1 failed
+	 * to NULL-terminate a 64-bit argv[].  (As this was written, the
+	 * compiler ECO was available only on IA64.)
+	 * Fix 2: Unless advised not to (VMS_TRUST_ARGV), we test a
+	 * 64-bit argv[argc] for NULL, and, if necessary, use a
+	 * (properly) NULL-terminated (64-bit) duplicate of argv[].
+	 * The same code is used in either case to duplicate argv[].
+	 * Some of these decisions could be handled in preprocessing,
+	 * but the code tends to get even uglier, and the penalty for
+	 * deciding at compile- or run-time is tiny.
+	 */
+	char **Argv = NULL;
+	int free_Argv = 0;
+
+	if ((sizeof( _Argv) < 8)        /* 32-bit argv[]. */
+# if !defined( VMS_TRUST_ARGV)
+	 || (_Argv[ Argc] != NULL)      /* Untrusted argv[argc] not NULL. */
+# endif
+		)
+		{
+		int i;
+		Argv = OPENSSL_malloc( (Argc+ 1)* sizeof( char *));
+		if (Argv == NULL)
+			{ ret = -1; goto end; }
+		for(i = 0; i < Argc; i++)
+			Argv[i] = _Argv[i];
+		Argv[ Argc] = NULL;     /* Certain NULL termination. */
+		free_Argv = 1;
+		}
+	else
+		{
+		/* Use the known-good 32-bit argv[] (which needs the
+		 * type cast to satisfy the compiler), or the trusted or
+		 * tested-good 64-bit argv[] as-is. */
+		Argv = (char **)_Argv;
+		}
+#endif /* defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) */
+
+	arg.data=NULL;
+	arg.count=0;
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (getenv("OPENSSL_DEBUG_MEMORY") != NULL) /* if not defined, use compiled-in library defaults */
+		{
+		if (!(0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))
+			{
+			CRYPTO_malloc_debug_init();
+			CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+			}
+		else
+			{
+			/* OPENSSL_DEBUG_MEMORY=off */
+			CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
+			}
+		}
+	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+#if 0
+	if (getenv("OPENSSL_DEBUG_LOCKING") != NULL)
+#endif
+		{
+		CRYPTO_set_locking_callback(lock_dbg_cb);
+		}
+
+	apps_startup();
+
+	/* Lets load up our environment a little */
+	p=getenv("OPENSSL_CONF");
+	if (p == NULL)
+		p=getenv("SSLEAY_CONF");
+	if (p == NULL)
+		p=to_free=make_config_name();
+
+	default_config_file=p;
+
+	config=NCONF_new(NULL);
+	i=NCONF_load(config,p,&errline);
+	if (i == 0)
+		{
+		if (ERR_GET_REASON(ERR_peek_last_error())
+		    == CONF_R_NO_SUCH_FILE)
+			{
+#if 0 /* ANDROID */
+			BIO_printf(bio_err,
+				   "WARNING: can't open config file: %s\n",p);
+#endif
+			ERR_clear_error();
+			NCONF_free(config);
+			config = NULL;
+			}
+		else
+			{
+			ERR_print_errors(bio_err);
+			NCONF_free(config);
+			exit(1);
+			}
+		}
+
+	prog=prog_init();
+
+	/* first check the program name */
+	program_name(Argv[0],pname,sizeof pname);
+
+	f.name=pname;
+	fp=lh_FUNCTION_retrieve(prog,&f);
+	if (fp != NULL)
+		{
+		Argv[0]=pname;
+		ret=fp->func(Argc,Argv);
+		goto end;
+		}
+
+	/* ok, now check that there are not arguments, if there are,
+	 * run with them, shifting the ssleay off the front */
+	if (Argc != 1)
+		{
+		Argc--;
+		Argv++;
+		ret=do_cmd(prog,Argc,Argv);
+		if (ret < 0) ret=0;
+		goto end;
+		}
+
+	/* ok, lets enter the old 'OpenSSL>' mode */
+	
+	for (;;)
+		{
+		ret=0;
+		p=buf;
+		n=sizeof buf;
+		i=0;
+		for (;;)
+			{
+			p[0]='\0';
+			if (i++)
+				prompt=">";
+			else	prompt="OpenSSL> ";
+			fputs(prompt,stdout);
+			fflush(stdout);
+			if (!fgets(p,n,stdin))
+				goto end;
+			if (p[0] == '\0') goto end;
+			i=strlen(p);
+			if (i <= 1) break;
+			if (p[i-2] != '\\') break;
+			i-=2;
+			p+=i;
+			n-=i;
+			}
+		if (!chopup_args(&arg,buf,&argc,&argv)) break;
+
+		ret=do_cmd(prog,argc,argv);
+		if (ret < 0)
+			{
+			ret=0;
+			goto end;
+			}
+		if (ret != 0)
+			BIO_printf(bio_err,"error in %s\n",argv[0]);
+		(void)BIO_flush(bio_err);
+		}
+	BIO_printf(bio_err,"bad exit\n");
+	ret=1;
+end:
+	if (to_free)
+		OPENSSL_free(to_free);
+	if (config != NULL)
+		{
+		NCONF_free(config);
+		config=NULL;
+		}
+	if (prog != NULL) lh_FUNCTION_free(prog);
+	if (arg.data != NULL) OPENSSL_free(arg.data);
+
+	apps_shutdown();
+
+	CRYPTO_mem_leaks(bio_err);
+	if (bio_err != NULL)
+		{
+		BIO_free(bio_err);
+		bio_err=NULL;
+		}
+#if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64)
+	/* Free any duplicate Argv[] storage. */
+	if (free_Argv)
+		{
+		OPENSSL_free(Argv);
+		}
+#endif
+	OPENSSL_EXIT(ret);
+	}
+
+#define LIST_STANDARD_COMMANDS "list-standard-commands"
+#define LIST_MESSAGE_DIGEST_COMMANDS "list-message-digest-commands"
+#define LIST_MESSAGE_DIGEST_ALGORITHMS "list-message-digest-algorithms"
+#define LIST_CIPHER_COMMANDS "list-cipher-commands"
+#define LIST_CIPHER_ALGORITHMS "list-cipher-algorithms"
+#define LIST_PUBLIC_KEY_ALGORITHMS "list-public-key-algorithms"
+
+
+static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[])
+	{
+	FUNCTION f,*fp;
+	int i,ret=1,tp,nl;
+
+	if ((argc <= 0) || (argv[0] == NULL))
+		{ ret=0; goto end; }
+	f.name=argv[0];
+	fp=lh_FUNCTION_retrieve(prog,&f);
+	if (fp == NULL)
+		{
+		if (EVP_get_digestbyname(argv[0]))
+			{
+			f.type = FUNC_TYPE_MD;
+			f.func = dgst_main;
+			fp = &f;
+			}
+		else if (EVP_get_cipherbyname(argv[0]))
+			{
+			f.type = FUNC_TYPE_CIPHER;
+			f.func = enc_main;
+			fp = &f;
+			}
+		}
+	if (fp != NULL)
+		{
+		ret=fp->func(argc,argv);
+		}
+	else if ((strncmp(argv[0],"no-",3)) == 0)
+		{
+		BIO *bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		bio_stdout = BIO_push(tmpbio, bio_stdout);
+		}
+#endif
+		f.name=argv[0]+3;
+		ret = (lh_FUNCTION_retrieve(prog,&f) != NULL);
+		if (!ret)
+			BIO_printf(bio_stdout, "%s\n", argv[0]);
+		else
+			BIO_printf(bio_stdout, "%s\n", argv[0]+3);
+		BIO_free_all(bio_stdout);
+		goto end;
+		}
+	else if ((strcmp(argv[0],"quit") == 0) ||
+		(strcmp(argv[0],"q") == 0) ||
+		(strcmp(argv[0],"exit") == 0) ||
+		(strcmp(argv[0],"bye") == 0))
+		{
+		ret= -1;
+		goto end;
+		}
+	else if ((strcmp(argv[0],LIST_STANDARD_COMMANDS) == 0) ||
+		(strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0) ||
+		(strcmp(argv[0],LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) ||
+		(strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0) ||
+		(strcmp(argv[0],LIST_CIPHER_ALGORITHMS) == 0) ||
+		(strcmp(argv[0],LIST_PUBLIC_KEY_ALGORITHMS) == 0))
+		{
+		int list_type;
+		BIO *bio_stdout;
+
+		if (strcmp(argv[0],LIST_STANDARD_COMMANDS) == 0)
+			list_type = FUNC_TYPE_GENERAL;
+		else if (strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0)
+			list_type = FUNC_TYPE_MD;
+		else if (strcmp(argv[0],LIST_MESSAGE_DIGEST_ALGORITHMS) == 0)
+			list_type = FUNC_TYPE_MD_ALG;
+		else if (strcmp(argv[0],LIST_PUBLIC_KEY_ALGORITHMS) == 0)
+			list_type = FUNC_TYPE_PKEY;
+		else if (strcmp(argv[0],LIST_CIPHER_ALGORITHMS) == 0)
+			list_type = FUNC_TYPE_CIPHER_ALG;
+		else /* strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0 */
+			list_type = FUNC_TYPE_CIPHER;
+		bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		bio_stdout = BIO_push(tmpbio, bio_stdout);
+		}
+#endif
+
+		if (!load_config(bio_err, NULL))
+			goto end;
+
+		if (list_type == FUNC_TYPE_PKEY)
+			list_pkey(bio_stdout);	
+		if (list_type == FUNC_TYPE_MD_ALG)
+			list_md(bio_stdout);	
+		if (list_type == FUNC_TYPE_CIPHER_ALG)
+			list_cipher(bio_stdout);	
+		else
+			{
+			for (fp=functions; fp->name != NULL; fp++)
+				if (fp->type == list_type)
+					BIO_printf(bio_stdout, "%s\n",
+								fp->name);
+			}
+		BIO_free_all(bio_stdout);
+		ret=0;
+		goto end;
+		}
+	else
+		{
+		BIO_printf(bio_err,"openssl:Error: '%s' is an invalid command.\n",
+			argv[0]);
+		BIO_printf(bio_err, "\nStandard commands");
+		i=0;
+		tp=0;
+		for (fp=functions; fp->name != NULL; fp++)
+			{
+			nl=0;
+#ifdef OPENSSL_NO_CAMELLIA
+			if (((i++) % 5) == 0)
+#else
+			if (((i++) % 4) == 0)
+#endif
+				{
+				BIO_printf(bio_err,"\n");
+				nl=1;
+				}
+			if (fp->type != tp)
+				{
+				tp=fp->type;
+				if (!nl) BIO_printf(bio_err,"\n");
+				if (tp == FUNC_TYPE_MD)
+					{
+					i=1;
+					BIO_printf(bio_err,
+						"\nMessage Digest commands (see the `dgst' command for more details)\n");
+					}
+				else if (tp == FUNC_TYPE_CIPHER)
+					{
+					i=1;
+					BIO_printf(bio_err,"\nCipher commands (see the `enc' command for more details)\n");
+					}
+				}
+#ifdef OPENSSL_NO_CAMELLIA
+			BIO_printf(bio_err,"%-15s",fp->name);
+#else
+			BIO_printf(bio_err,"%-18s",fp->name);
+#endif
+			}
+		BIO_printf(bio_err,"\n\n");
+		ret=0;
+		}
+end:
+	return(ret);
+	}
+
+static int SortFnByName(const void *_f1,const void *_f2)
+    {
+    const FUNCTION *f1=_f1;
+    const FUNCTION *f2=_f2;
+
+    if(f1->type != f2->type)
+	return f1->type-f2->type;
+    return strcmp(f1->name,f2->name);
+    }
+
+static void list_pkey(BIO *out)
+	{
+	int i;
+	for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
+		{
+		const EVP_PKEY_ASN1_METHOD *ameth;
+		int pkey_id, pkey_base_id, pkey_flags;
+		const char *pinfo, *pem_str;
+		ameth = EVP_PKEY_asn1_get0(i);
+		EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags,
+						&pinfo, &pem_str, ameth);
+		if (pkey_flags & ASN1_PKEY_ALIAS)
+			{
+			BIO_printf(out, "Name: %s\n", 
+					OBJ_nid2ln(pkey_id));
+			BIO_printf(out, "\tType: Alias to %s\n",
+					OBJ_nid2ln(pkey_base_id));
+			}
+		else
+			{
+			BIO_printf(out, "Name: %s\n", pinfo);
+			BIO_printf(out, "\tType: %s Algorithm\n", 
+				pkey_flags & ASN1_PKEY_DYNAMIC ?
+					"External" : "Builtin");
+			BIO_printf(out, "\tOID: %s\n", OBJ_nid2ln(pkey_id));
+			if (pem_str == NULL)
+				pem_str = "(none)";
+			BIO_printf(out, "\tPEM string: %s\n", pem_str);
+			}
+					
+		}
+	}
+
+static void list_cipher_fn(const EVP_CIPHER *c,
+			const char *from, const char *to, void *arg)
+	{
+	if (c)
+		BIO_printf(arg, "%s\n", EVP_CIPHER_name(c));
+	else
+		{
+		if (!from)
+			from = "<undefined>";
+		if (!to)
+			to = "<undefined>";
+		BIO_printf(arg, "%s => %s\n", from, to);
+		}
+	}
+
+static void list_cipher(BIO *out)
+	{
+	EVP_CIPHER_do_all_sorted(list_cipher_fn, out);
+	}
+
+static void list_md_fn(const EVP_MD *m,
+			const char *from, const char *to, void *arg)
+	{
+	if (m)
+		BIO_printf(arg, "%s\n", EVP_MD_name(m));
+	else
+		{
+		if (!from)
+			from = "<undefined>";
+		if (!to)
+			to = "<undefined>";
+		BIO_printf(arg, "%s => %s\n", from, to);
+		}
+	}
+
+static void list_md(BIO *out)
+	{
+	EVP_MD_do_all_sorted(list_md_fn, out);
+	}
+
+static int MS_CALLBACK function_cmp(const FUNCTION *a, const FUNCTION *b)
+	{
+	return strncmp(a->name,b->name,8);
+	}
+static IMPLEMENT_LHASH_COMP_FN(function, FUNCTION)
+
+static unsigned long MS_CALLBACK function_hash(const FUNCTION *a)
+	{
+	return lh_strhash(a->name);
+	}	
+static IMPLEMENT_LHASH_HASH_FN(function, FUNCTION)
+
+static LHASH_OF(FUNCTION) *prog_init(void)
+	{
+	LHASH_OF(FUNCTION) *ret;
+	FUNCTION *f;
+	size_t i;
+
+	/* Purely so it looks nice when the user hits ? */
+	for(i=0,f=functions ; f->name != NULL ; ++f,++i)
+	    ;
+	qsort(functions,i,sizeof *functions,SortFnByName);
+
+	if ((ret=lh_FUNCTION_new()) == NULL)
+		return(NULL);
+
+	for (f=functions; f->name != NULL; f++)
+		(void)lh_FUNCTION_insert(ret,f);
+	return(ret);
+	}
+
diff --git a/openssl/apps/openssl.cnf b/openssl/apps/openssl.cnf
new file mode 100644
index 0000000..18760c6
--- /dev/null
+++ b/openssl/apps/openssl.cnf
@@ -0,0 +1,350 @@
+#
+# OpenSSL example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME			= .
+RANDFILE		= $ENV::HOME/.rnd
+
+# Extra OBJECT IDENTIFIER info:
+#oid_file		= $ENV::HOME/.oid
+oid_section		= new_oids
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions		= 
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+# Policies used by the TSA examples.
+tsa_policy1 = 1.2.3.4.1
+tsa_policy2 = 1.2.3.4.5.6
+tsa_policy3 = 1.2.3.4.5.7
+
+####################################################################
+[ ca ]
+default_ca	= CA_default		# The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir		= ./demoCA		# Where everything is kept
+certs		= $dir/certs		# Where the issued certs are kept
+crl_dir		= $dir/crl		# Where the issued crl are kept
+database	= $dir/index.txt	# database index file.
+#unique_subject	= no			# Set to 'no' to allow creation of
+					# several ctificates with same subject.
+new_certs_dir	= $dir/newcerts		# default place for new certs.
+
+certificate	= $dir/cacert.pem 	# The CA certificate
+serial		= $dir/serial 		# The current serial number
+crlnumber	= $dir/crlnumber	# the current crl number
+					# must be commented out to leave a V1 CRL
+crl		= $dir/crl.pem 		# The current CRL
+private_key	= $dir/private/cakey.pem# The private key
+RANDFILE	= $dir/private/.rand	# private random number file
+
+x509_extensions	= usr_cert		# The extentions to add to the cert
+
+# Comment out the following two lines for the "traditional"
+# (and highly broken) format.
+name_opt 	= ca_default		# Subject Name options
+cert_opt 	= ca_default		# Certificate field options
+
+# Extension copying option: use with caution.
+# copy_extensions = copy
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crlnumber must also be commented out to leave a V1 CRL.
+# crl_extensions	= crl_ext
+
+default_days	= 365			# how long to certify for
+default_crl_days= 30			# how long before next CRL
+default_md	= default		# use public key default MD
+preserve	= no			# keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy		= policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName		= match
+stateOrProvinceName	= match
+organizationName	= match
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName		= optional
+stateOrProvinceName	= optional
+localityName		= optional
+organizationName	= optional
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+####################################################################
+[ req ]
+default_bits		= 1024
+default_keyfile 	= privkey.pem
+distinguished_name	= req_distinguished_name
+attributes		= req_attributes
+x509_extensions	= v3_ca	# The extentions to add to the self signed cert
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options. 
+# default: PrintableString, T61String, BMPString.
+# pkix	 : PrintableString, BMPString (PKIX recommendation before 2004)
+# utf8only: only UTF8Strings (PKIX recommendation after 2004).
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
+string_mask = utf8only
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= AU
+countryName_min			= 2
+countryName_max			= 2
+
+stateOrProvinceName		= State or Province Name (full name)
+stateOrProvinceName_default	= Some-State
+
+localityName			= Locality Name (eg, city)
+
+0.organizationName		= Organization Name (eg, company)
+0.organizationName_default	= Internet Widgits Pty Ltd
+
+# we can do this but it is not needed normally :-)
+#1.organizationName		= Second Organization Name (eg, company)
+#1.organizationName_default	= World Wide Web Pty Ltd
+
+organizationalUnitName		= Organizational Unit Name (eg, section)
+#organizationalUnitName_default	=
+
+commonName			= Common Name (e.g. server FQDN or YOUR name)
+commonName_max			= 64
+
+emailAddress			= Email Address
+emailAddress_max		= 64
+
+# SET-ex3			= SET extension number 3
+
+[ req_attributes ]
+challengePassword		= A challenge password
+challengePassword_min		= 4
+challengePassword_max		= 20
+
+unstructuredName		= An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This is required for TSA certificates.
+# extendedKeyUsage = critical,timeStamping
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+basicConstraints = CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
+
+####################################################################
+[ tsa ]
+
+default_tsa = tsa_config1	# the default TSA section
+
+[ tsa_config1 ]
+
+# These are used by the TSA reply generation only.
+dir		= ./demoCA		# TSA root directory
+serial		= $dir/tsaserial	# The current serial number (mandatory)
+crypto_device	= builtin		# OpenSSL engine to use for signing
+signer_cert	= $dir/tsacert.pem 	# The TSA signing certificate
+					# (optional)
+certs		= $dir/cacert.pem	# Certificate chain to include in reply
+					# (optional)
+signer_key	= $dir/private/tsakey.pem # The TSA private key (optional)
+
+default_policy	= tsa_policy1		# Policy if request did not specify it
+					# (optional)
+other_policies	= tsa_policy2, tsa_policy3	# acceptable policies (optional)
+digests		= md5, sha1		# Acceptable message digests (mandatory)
+accuracy	= secs:1, millisecs:500, microsecs:100	# (optional)
+clock_precision_digits  = 0	# number of digits after dot. (optional)
+ordering		= yes	# Is ordering defined for timestamps?
+				# (optional, default: no)
+tsa_name		= yes	# Must the TSA name be included in the reply?
+				# (optional, default: no)
+ess_cert_id_chain	= no	# Must the ESS cert id chain be included?
+				# (optional, default: no)
diff --git a/openssl/apps/passwd.c b/openssl/apps/passwd.c
new file mode 100644
index 0000000..9ca25dd
--- /dev/null
+++ b/openssl/apps/passwd.c
@@ -0,0 +1,512 @@
+/* apps/passwd.c */
+
+#if defined OPENSSL_NO_MD5 || defined CHARSET_EBCDIC
+# define NO_MD5CRYPT_1
+#endif
+
+#if !defined(OPENSSL_NO_DES) || !defined(NO_MD5CRYPT_1)
+
+#include <assert.h>
+#include <string.h>
+
+#include "apps.h"
+
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_DES
+# include <openssl/des.h>
+#endif
+#ifndef NO_MD5CRYPT_1
+# include <openssl/md5.h>
+#endif
+
+
+#undef PROG
+#define PROG passwd_main
+
+
+static unsigned const char cov_2char[64]={
+	/* from crypto/des/fcrypt.c */
+	0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
+	0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
+	0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
+	0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
+	0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
+	0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
+	0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
+	0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
+};
+
+static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
+	char *passwd, BIO *out, int quiet, int table, int reverse,
+	size_t pw_maxlen, int usecrypt, int use1, int useapr1);
+
+/* -crypt        - standard Unix password algorithm (default)
+ * -1            - MD5-based password algorithm
+ * -apr1         - MD5-based password algorithm, Apache variant
+ * -salt string  - salt
+ * -in file      - read passwords from file
+ * -stdin        - read passwords from stdin
+ * -noverify     - never verify when reading password from terminal
+ * -quiet        - no warnings
+ * -table        - format output as table
+ * -reverse      - switch table columns
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	int ret = 1;
+	char *infile = NULL;
+	int in_stdin = 0;
+	int in_noverify = 0;
+	char *salt = NULL, *passwd = NULL, **passwds = NULL;
+	char *salt_malloc = NULL, *passwd_malloc = NULL;
+	size_t passwd_malloc_size = 0;
+	int pw_source_defined = 0;
+	BIO *in = NULL, *out = NULL;
+	int i, badopt, opt_done;
+	int passed_salt = 0, quiet = 0, table = 0, reverse = 0;
+	int usecrypt = 0, use1 = 0, useapr1 = 0;
+	size_t pw_maxlen = 0;
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto err;
+	out = BIO_new(BIO_s_file());
+	if (out == NULL)
+		goto err;
+	BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
+#ifdef OPENSSL_SYS_VMS
+	{
+	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+	out = BIO_push(tmpbio, out);
+	}
+#endif
+
+	badopt = 0, opt_done = 0;
+	i = 0;
+	while (!badopt && !opt_done && argv[++i] != NULL)
+		{
+		if (strcmp(argv[i], "-crypt") == 0)
+			usecrypt = 1;
+		else if (strcmp(argv[i], "-1") == 0)
+			use1 = 1;
+		else if (strcmp(argv[i], "-apr1") == 0)
+			useapr1 = 1;
+		else if (strcmp(argv[i], "-salt") == 0)
+			{
+			if ((argv[i+1] != NULL) && (salt == NULL))
+				{
+				passed_salt = 1;
+				salt = argv[++i];
+				}
+			else
+				badopt = 1;
+			}
+		else if (strcmp(argv[i], "-in") == 0)
+			{
+			if ((argv[i+1] != NULL) && !pw_source_defined)
+				{
+				pw_source_defined = 1;
+				infile = argv[++i];
+				}
+			else
+				badopt = 1;
+			}
+		else if (strcmp(argv[i], "-stdin") == 0)
+			{
+			if (!pw_source_defined)
+				{
+				pw_source_defined = 1;
+				in_stdin = 1;
+				}
+			else
+				badopt = 1;
+			}
+		else if (strcmp(argv[i], "-noverify") == 0)
+			in_noverify = 1;
+		else if (strcmp(argv[i], "-quiet") == 0)
+			quiet = 1;
+		else if (strcmp(argv[i], "-table") == 0)
+			table = 1;
+		else if (strcmp(argv[i], "-reverse") == 0)
+			reverse = 1;
+		else if (argv[i][0] == '-')
+			badopt = 1;
+		else if (!pw_source_defined)
+			/* non-option arguments, use as passwords */
+			{
+			pw_source_defined = 1;
+			passwds = &argv[i];
+			opt_done = 1;
+			}
+		else
+			badopt = 1;
+		}
+
+	if (!usecrypt && !use1 && !useapr1) /* use default */
+		usecrypt = 1;
+	if (usecrypt + use1 + useapr1 > 1) /* conflict */
+		badopt = 1;
+
+	/* reject unsupported algorithms */
+#ifdef OPENSSL_NO_DES
+	if (usecrypt) badopt = 1;
+#endif
+#ifdef NO_MD5CRYPT_1
+	if (use1 || useapr1) badopt = 1;
+#endif
+
+	if (badopt) 
+		{
+		BIO_printf(bio_err, "Usage: passwd [options] [passwords]\n");
+		BIO_printf(bio_err, "where options are\n");
+#ifndef OPENSSL_NO_DES
+		BIO_printf(bio_err, "-crypt             standard Unix password algorithm (default)\n");
+#endif
+#ifndef NO_MD5CRYPT_1
+		BIO_printf(bio_err, "-1                 MD5-based password algorithm\n");
+		BIO_printf(bio_err, "-apr1              MD5-based password algorithm, Apache variant\n");
+#endif
+		BIO_printf(bio_err, "-salt string       use provided salt\n");
+		BIO_printf(bio_err, "-in file           read passwords from file\n");
+		BIO_printf(bio_err, "-stdin             read passwords from stdin\n");
+		BIO_printf(bio_err, "-noverify          never verify when reading password from terminal\n");
+		BIO_printf(bio_err, "-quiet             no warnings\n");
+		BIO_printf(bio_err, "-table             format output as table\n");
+		BIO_printf(bio_err, "-reverse           switch table columns\n");
+		
+		goto err;
+		}
+
+	if ((infile != NULL) || in_stdin)
+		{
+		in = BIO_new(BIO_s_file());
+		if (in == NULL)
+			goto err;
+		if (infile != NULL)
+			{
+			assert(in_stdin == 0);
+			if (BIO_read_filename(in, infile) <= 0)
+				goto err;
+			}
+		else
+			{
+			assert(in_stdin);
+			BIO_set_fp(in, stdin, BIO_NOCLOSE);
+			}
+		}
+	
+	if (usecrypt)
+		pw_maxlen = 8;
+	else if (use1 || useapr1)
+		pw_maxlen = 256; /* arbitrary limit, should be enough for most passwords */
+
+	if (passwds == NULL)
+		{
+		/* no passwords on the command line */
+
+		passwd_malloc_size = pw_maxlen + 2;
+		/* longer than necessary so that we can warn about truncation */
+		passwd = passwd_malloc = OPENSSL_malloc(passwd_malloc_size);
+		if (passwd_malloc == NULL)
+			goto err;
+		}
+
+	if ((in == NULL) && (passwds == NULL))
+		{
+		/* build a null-terminated list */
+		static char *passwds_static[2] = {NULL, NULL};
+		
+		passwds = passwds_static;
+		if (in == NULL)
+			if (EVP_read_pw_string(passwd_malloc, passwd_malloc_size, "Password: ", !(passed_salt || in_noverify)) != 0)
+				goto err;
+		passwds[0] = passwd_malloc;
+		}
+
+	if (in == NULL)
+		{
+		assert(passwds != NULL);
+		assert(*passwds != NULL);
+		
+		do /* loop over list of passwords */
+			{
+			passwd = *passwds++;
+			if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, out,
+				quiet, table, reverse, pw_maxlen, usecrypt, use1, useapr1))
+				goto err;
+			}
+		while (*passwds != NULL);
+		}
+	else
+		/* in != NULL */
+		{
+		int done;
+
+		assert (passwd != NULL);
+		do
+			{
+			int r = BIO_gets(in, passwd, pw_maxlen + 1);
+			if (r > 0)
+				{
+				char *c = (strchr(passwd, '\n')) ;
+				if (c != NULL)
+					*c = 0; /* truncate at newline */
+				else
+					{
+					/* ignore rest of line */
+					char trash[BUFSIZ];
+					do
+						r = BIO_gets(in, trash, sizeof trash);
+					while ((r > 0) && (!strchr(trash, '\n')));
+					}
+				
+				if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, out,
+					quiet, table, reverse, pw_maxlen, usecrypt, use1, useapr1))
+					goto err;
+				}
+			done = (r <= 0);
+			}
+		while (!done);
+		}
+	ret = 0;
+
+err:
+	ERR_print_errors(bio_err);
+	if (salt_malloc)
+		OPENSSL_free(salt_malloc);
+	if (passwd_malloc)
+		OPENSSL_free(passwd_malloc);
+	if (in)
+		BIO_free(in);
+	if (out)
+		BIO_free_all(out);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
+
+#ifndef NO_MD5CRYPT_1
+/* MD5-based password algorithm (should probably be available as a library
+ * function; then the static buffer would not be acceptable).
+ * For magic string "1", this should be compatible to the MD5-based BSD
+ * password algorithm.
+ * For 'magic' string "apr1", this is compatible to the MD5-based Apache
+ * password algorithm.
+ * (Apparently, the Apache password algorithm is identical except that the
+ * 'magic' string was changed -- the laziest application of the NIH principle
+ * I've ever encountered.)
+ */
+static char *md5crypt(const char *passwd, const char *magic, const char *salt)
+	{
+	static char out_buf[6 + 9 + 24 + 2]; /* "$apr1$..salt..$.......md5hash..........\0" */
+	unsigned char buf[MD5_DIGEST_LENGTH];
+	char *salt_out;
+	int n;
+	unsigned int i;
+	EVP_MD_CTX md,md2;
+	size_t passwd_len, salt_len;
+
+	passwd_len = strlen(passwd);
+	out_buf[0] = '$';
+	out_buf[1] = 0;
+	assert(strlen(magic) <= 4); /* "1" or "apr1" */
+	strncat(out_buf, magic, 4);
+	strncat(out_buf, "$", 1);
+	strncat(out_buf, salt, 8);
+	assert(strlen(out_buf) <= 6 + 8); /* "$apr1$..salt.." */
+	salt_out = out_buf + 2 + strlen(magic);
+	salt_len = strlen(salt_out);
+	assert(salt_len <= 8);
+	
+	EVP_MD_CTX_init(&md);
+	EVP_DigestInit_ex(&md,EVP_md5(), NULL);
+	EVP_DigestUpdate(&md, passwd, passwd_len);
+	EVP_DigestUpdate(&md, "$", 1);
+	EVP_DigestUpdate(&md, magic, strlen(magic));
+	EVP_DigestUpdate(&md, "$", 1);
+	EVP_DigestUpdate(&md, salt_out, salt_len);
+	
+	EVP_MD_CTX_init(&md2);
+	EVP_DigestInit_ex(&md2,EVP_md5(), NULL);
+	EVP_DigestUpdate(&md2, passwd, passwd_len);
+	EVP_DigestUpdate(&md2, salt_out, salt_len);
+	EVP_DigestUpdate(&md2, passwd, passwd_len);
+	EVP_DigestFinal_ex(&md2, buf, NULL);
+
+	for (i = passwd_len; i > sizeof buf; i -= sizeof buf)
+		EVP_DigestUpdate(&md, buf, sizeof buf);
+	EVP_DigestUpdate(&md, buf, i);
+	
+	n = passwd_len;
+	while (n)
+		{
+		EVP_DigestUpdate(&md, (n & 1) ? "\0" : passwd, 1);
+		n >>= 1;
+		}
+	EVP_DigestFinal_ex(&md, buf, NULL);
+
+	for (i = 0; i < 1000; i++)
+		{
+		EVP_DigestInit_ex(&md2,EVP_md5(), NULL);
+		EVP_DigestUpdate(&md2, (i & 1) ? (unsigned const char *) passwd : buf,
+		                       (i & 1) ? passwd_len : sizeof buf);
+		if (i % 3)
+			EVP_DigestUpdate(&md2, salt_out, salt_len);
+		if (i % 7)
+			EVP_DigestUpdate(&md2, passwd, passwd_len);
+		EVP_DigestUpdate(&md2, (i & 1) ? buf : (unsigned const char *) passwd,
+		                       (i & 1) ? sizeof buf : passwd_len);
+		EVP_DigestFinal_ex(&md2, buf, NULL);
+		}
+	EVP_MD_CTX_cleanup(&md2);
+	
+	 {
+		/* transform buf into output string */
+	
+		unsigned char buf_perm[sizeof buf];
+		int dest, source;
+		char *output;
+
+		/* silly output permutation */
+		for (dest = 0, source = 0; dest < 14; dest++, source = (source + 6) % 17)
+			buf_perm[dest] = buf[source];
+		buf_perm[14] = buf[5];
+		buf_perm[15] = buf[11];
+#ifndef PEDANTIC /* Unfortunately, this generates a "no effect" warning */
+		assert(16 == sizeof buf_perm);
+#endif
+		
+		output = salt_out + salt_len;
+		assert(output == out_buf + strlen(out_buf));
+		
+		*output++ = '$';
+
+		for (i = 0; i < 15; i += 3)
+			{
+			*output++ = cov_2char[buf_perm[i+2] & 0x3f];
+			*output++ = cov_2char[((buf_perm[i+1] & 0xf) << 2) |
+				                  (buf_perm[i+2] >> 6)];
+			*output++ = cov_2char[((buf_perm[i] & 3) << 4) |
+				                  (buf_perm[i+1] >> 4)];
+			*output++ = cov_2char[buf_perm[i] >> 2];
+			}
+		assert(i == 15);
+		*output++ = cov_2char[buf_perm[i] & 0x3f];
+		*output++ = cov_2char[buf_perm[i] >> 6];
+		*output = 0;
+		assert(strlen(out_buf) < sizeof(out_buf));
+	 }
+	EVP_MD_CTX_cleanup(&md);
+
+	return out_buf;
+	}
+#endif
+
+
+static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
+	char *passwd, BIO *out,	int quiet, int table, int reverse,
+	size_t pw_maxlen, int usecrypt, int use1, int useapr1)
+	{
+	char *hash = NULL;
+
+	assert(salt_p != NULL);
+	assert(salt_malloc_p != NULL);
+
+	/* first make sure we have a salt */
+	if (!passed_salt)
+		{
+#ifndef OPENSSL_NO_DES
+		if (usecrypt)
+			{
+			if (*salt_malloc_p == NULL)
+				{
+				*salt_p = *salt_malloc_p = OPENSSL_malloc(3);
+				if (*salt_malloc_p == NULL)
+					goto err;
+				}
+			if (RAND_pseudo_bytes((unsigned char *)*salt_p, 2) < 0)
+				goto err;
+			(*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */
+			(*salt_p)[1] = cov_2char[(*salt_p)[1] & 0x3f]; /* 6 bits */
+			(*salt_p)[2] = 0;
+#ifdef CHARSET_EBCDIC
+			ascii2ebcdic(*salt_p, *salt_p, 2); /* des_crypt will convert
+			                                    * back to ASCII */
+#endif
+			}
+#endif /* !OPENSSL_NO_DES */
+
+#ifndef NO_MD5CRYPT_1
+		if (use1 || useapr1)
+			{
+			int i;
+			
+			if (*salt_malloc_p == NULL)
+				{
+				*salt_p = *salt_malloc_p = OPENSSL_malloc(9);
+				if (*salt_malloc_p == NULL)
+					goto err;
+				}
+			if (RAND_pseudo_bytes((unsigned char *)*salt_p, 8) < 0)
+				goto err;
+			
+			for (i = 0; i < 8; i++)
+				(*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */
+			(*salt_p)[8] = 0;
+			}
+#endif /* !NO_MD5CRYPT_1 */
+		}
+	
+	assert(*salt_p != NULL);
+	
+	/* truncate password if necessary */
+	if ((strlen(passwd) > pw_maxlen))
+		{
+		if (!quiet)
+			/* XXX: really we should know how to print a size_t, not cast it */
+			BIO_printf(bio_err, "Warning: truncating password to %u characters\n", (unsigned)pw_maxlen);
+		passwd[pw_maxlen] = 0;
+		}
+	assert(strlen(passwd) <= pw_maxlen);
+	
+	/* now compute password hash */
+#ifndef OPENSSL_NO_DES
+	if (usecrypt)
+		hash = DES_crypt(passwd, *salt_p);
+#endif
+#ifndef NO_MD5CRYPT_1
+	if (use1 || useapr1)
+		hash = md5crypt(passwd, (use1 ? "1" : "apr1"), *salt_p);
+#endif
+	assert(hash != NULL);
+
+	if (table && !reverse)
+		BIO_printf(out, "%s\t%s\n", passwd, hash);
+	else if (table && reverse)
+		BIO_printf(out, "%s\t%s\n", hash, passwd);
+	else
+		BIO_printf(out, "%s\n", hash);
+	return 1;
+	
+err:
+	return 0;
+	}
+#else
+
+int MAIN(int argc, char **argv)
+	{
+	fputs("Program not available.\n", stderr)
+	OPENSSL_EXIT(1);
+	}
+#endif
diff --git a/openssl/apps/pca-cert.srl b/openssl/apps/pca-cert.srl
new file mode 100644
index 0000000..2c7456e
--- /dev/null
+++ b/openssl/apps/pca-cert.srl
@@ -0,0 +1 @@
+07
diff --git a/openssl/apps/pca-key.pem b/openssl/apps/pca-key.pem
new file mode 100644
index 0000000..20029ab
--- /dev/null
+++ b/openssl/apps/pca-key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQCdoWk/3+WcMlfjIrkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPg
+wgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp22Jp85PmemiDzyUIStwk72qhp1imbANZ
+vlmlCFKiQrjUyuDfu4TABmn+kkt3vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQAB
+AoGAba4fTtuap5l7/8ZsbE7Z1O32KJY4ZcOZukLOLUUhXxXduT+FTgGWujc0/rgc
+z9qYCLlNZHOouMYTgtSfYvuMuLZ11VIt0GYH+nRioLShE59Yy+zCRyC+gPigS1kz
+xvo14AsOIPYV14Tk/SsHyq6E0eTk7VzaIE197giiINUERPECQQDSKmtPTh/lRKw7
+HSZSM0I1mFWn/1zqrAbontRQY5w98QWIOe5qmzYyFbPXYT3d9BzlsMyhgiRNoBbD
+yvohSHXJAkEAwAHx6ezAZeWWzD5yXD36nyjpkVCw7Tk7TSmOceLJMWt1QcrCfqlS
+xA5jjpQ6Z8suU5DdtWAryM2sAir1WisYzwJAd6Zcx56jvAQ3xcPXsE6scBTVFzrj
+7FqZ6E+cclPzfLQ+QQsyOBE7bpI6e/FJppY26XGZXo3YGzV8IGXrt40oOQJALETG
+h86EFXo3qGOFbmsDy4pdP5nBERCu8X1xUCSfintiD4c2DInxgS5oGclnJeMcjTvL
+QjQoJCX3UJCi/OUO1QJBAKgcDHWjMvt+l1pjJBsSEZ0HX9AAIIVx0RQmbFGS+F2Q
+hhu5l77WnnZOQ9vvhV5u7NPCUF9nhU3jh60qWWO8mkc=
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/apps/pca-req.pem b/openssl/apps/pca-req.pem
new file mode 100644
index 0000000..33f1553
--- /dev/null
+++ b/openssl/apps/pca-req.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBmjCCAQMCAQAwXDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQx
+GjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYDVQQDExNUZXN0IFBDQSAo
+MTAyNCBiaXQpMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdoWk/3+WcMlfj
+Irkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPgwgsabJ/wn8TxA1yy3eKJbFl3OiUX
+MRsp22Jp85PmemiDzyUIStwk72qhp1imbANZvlmlCFKiQrjUyuDfu4TABmn+kkt3
+vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAEzz
+IG8NnfpnPTQSCN5zJhOfy6p9AcDyQzuJirYv1HR/qoYWalPh/U2uiK0lAim7qMcv
+wOlK3I7A8B7/4dLqvIqgtUj9b1WT8zIrnwdvJI4osLI2BY+c1pVlp174DHLMol1L
+Cl1e3N5BTm7lCitTYjuUhsw6hiA8IcdNKDo6sktV
+-----END CERTIFICATE REQUEST-----
diff --git a/openssl/apps/pkcs12.c b/openssl/apps/pkcs12.c
new file mode 100644
index 0000000..b54c6f8
--- /dev/null
+++ b/openssl/apps/pkcs12.c
@@ -0,0 +1,977 @@
+/* pkcs12.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/pkcs12.h>
+
+#define PROG pkcs12_main
+
+const EVP_CIPHER *enc;
+
+
+#define NOKEYS		0x1
+#define NOCERTS 	0x2
+#define INFO		0x4
+#define CLCERTS		0x8
+#define CACERTS		0x10
+
+int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain);
+int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, int options, char *pempass);
+int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, char *pass,
+			  int passlen, int options, char *pempass);
+int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, int passlen, int options, char *pempass);
+int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name);
+void hex_prin(BIO *out, unsigned char *buf, int len);
+int alg_print(BIO *x, X509_ALGOR *alg);
+int cert_load(BIO *in, STACK_OF(X509) *sk);
+static int set_pbe(BIO *err, int *ppbe, const char *str);
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+{
+    ENGINE *e = NULL;
+    char *infile=NULL, *outfile=NULL, *keyname = NULL;	
+    char *certfile=NULL;
+    BIO *in=NULL, *out = NULL;
+    char **args;
+    char *name = NULL;
+    char *csp_name = NULL;
+    int add_lmk = 0;
+    PKCS12 *p12 = NULL;
+    char pass[50], macpass[50];
+    int export_cert = 0;
+    int options = 0;
+    int chain = 0;
+    int badarg = 0;
+    int iter = PKCS12_DEFAULT_ITER;
+    int maciter = PKCS12_DEFAULT_ITER;
+    int twopass = 0;
+    int keytype = 0;
+    int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
+    int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+    int ret = 1;
+    int macver = 1;
+    int noprompt = 0;
+    STACK_OF(OPENSSL_STRING) *canames = NULL;
+    char *cpass = NULL, *mpass = NULL;
+    char *passargin = NULL, *passargout = NULL, *passarg = NULL;
+    char *passin = NULL, *passout = NULL;
+    char *inrand = NULL;
+    char *macalg = NULL;
+    char *CApath = NULL, *CAfile = NULL;
+#ifndef OPENSSL_NO_ENGINE
+    char *engine=NULL;
+#endif
+
+    apps_startup();
+
+    enc = EVP_des_ede3_cbc();
+    if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+    args = argv + 1;
+
+
+    while (*args) {
+	if (*args[0] == '-') {
+		if (!strcmp (*args, "-nokeys")) options |= NOKEYS;
+		else if (!strcmp (*args, "-keyex")) keytype = KEY_EX;
+		else if (!strcmp (*args, "-keysig")) keytype = KEY_SIG;
+		else if (!strcmp (*args, "-nocerts")) options |= NOCERTS;
+		else if (!strcmp (*args, "-clcerts")) options |= CLCERTS;
+		else if (!strcmp (*args, "-cacerts")) options |= CACERTS;
+		else if (!strcmp (*args, "-noout")) options |= (NOKEYS|NOCERTS);
+		else if (!strcmp (*args, "-info")) options |= INFO;
+		else if (!strcmp (*args, "-chain")) chain = 1;
+		else if (!strcmp (*args, "-twopass")) twopass = 1;
+		else if (!strcmp (*args, "-nomacver")) macver = 0;
+		else if (!strcmp (*args, "-descert"))
+    			cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+		else if (!strcmp (*args, "-export")) export_cert = 1;
+		else if (!strcmp (*args, "-des")) enc=EVP_des_cbc();
+		else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc();
+#ifndef OPENSSL_NO_IDEA
+		else if (!strcmp (*args, "-idea")) enc=EVP_idea_cbc();
+#endif
+#ifndef OPENSSL_NO_SEED
+		else if (!strcmp(*args, "-seed")) enc=EVP_seed_cbc();
+#endif
+#ifndef OPENSSL_NO_AES
+		else if (!strcmp(*args,"-aes128")) enc=EVP_aes_128_cbc();
+		else if (!strcmp(*args,"-aes192")) enc=EVP_aes_192_cbc();
+		else if (!strcmp(*args,"-aes256")) enc=EVP_aes_256_cbc();
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+		else if (!strcmp(*args,"-camellia128")) enc=EVP_camellia_128_cbc();
+		else if (!strcmp(*args,"-camellia192")) enc=EVP_camellia_192_cbc();
+		else if (!strcmp(*args,"-camellia256")) enc=EVP_camellia_256_cbc();
+#endif
+		else if (!strcmp (*args, "-noiter")) iter = 1;
+		else if (!strcmp (*args, "-maciter"))
+					 maciter = PKCS12_DEFAULT_ITER;
+		else if (!strcmp (*args, "-nomaciter"))
+					 maciter = 1;
+		else if (!strcmp (*args, "-nomac"))
+					 maciter = -1;
+		else if (!strcmp (*args, "-macalg"))
+		    if (args[1]) {
+			args++;	
+			macalg = *args;
+		    } else badarg = 1;
+		else if (!strcmp (*args, "-nodes")) enc=NULL;
+		else if (!strcmp (*args, "-certpbe")) {
+			if (!set_pbe(bio_err, &cert_pbe, *++args))
+				badarg = 1;
+		} else if (!strcmp (*args, "-keypbe")) {
+			if (!set_pbe(bio_err, &key_pbe, *++args))
+				badarg = 1;
+		} else if (!strcmp (*args, "-rand")) {
+		    if (args[1]) {
+			args++;	
+			inrand = *args;
+		    } else badarg = 1;
+		} else if (!strcmp (*args, "-inkey")) {
+		    if (args[1]) {
+			args++;	
+			keyname = *args;
+		    } else badarg = 1;
+		} else if (!strcmp (*args, "-certfile")) {
+		    if (args[1]) {
+			args++;	
+			certfile = *args;
+		    } else badarg = 1;
+		} else if (!strcmp (*args, "-name")) {
+		    if (args[1]) {
+			args++;	
+			name = *args;
+		    } else badarg = 1;
+		} else if (!strcmp (*args, "-LMK"))
+			add_lmk = 1;
+		else if (!strcmp (*args, "-CSP")) {
+		    if (args[1]) {
+			args++;	
+			csp_name = *args;
+		    } else badarg = 1;
+		} else if (!strcmp (*args, "-caname")) {
+		    if (args[1]) {
+			args++;	
+			if (!canames) canames = sk_OPENSSL_STRING_new_null();
+			sk_OPENSSL_STRING_push(canames, *args);
+		    } else badarg = 1;
+		} else if (!strcmp (*args, "-in")) {
+		    if (args[1]) {
+			args++;	
+			infile = *args;
+		    } else badarg = 1;
+		} else if (!strcmp (*args, "-out")) {
+		    if (args[1]) {
+			args++;	
+			outfile = *args;
+		    } else badarg = 1;
+		} else if (!strcmp(*args,"-passin")) {
+		    if (args[1]) {
+			args++;	
+			passargin = *args;
+		    } else badarg = 1;
+		} else if (!strcmp(*args,"-passout")) {
+		    if (args[1]) {
+			args++;	
+			passargout = *args;
+		    } else badarg = 1;
+		} else if (!strcmp (*args, "-password")) {
+		    if (args[1]) {
+			args++;	
+			passarg = *args;
+		    	noprompt = 1;
+		    } else badarg = 1;
+		} else if (!strcmp(*args,"-CApath")) {
+		    if (args[1]) {
+			args++;	
+			CApath = *args;
+		    } else badarg = 1;
+		} else if (!strcmp(*args,"-CAfile")) {
+		    if (args[1]) {
+			args++;	
+			CAfile = *args;
+		    } else badarg = 1;
+#ifndef OPENSSL_NO_ENGINE
+		} else if (!strcmp(*args,"-engine")) {
+		    if (args[1]) {
+			args++;	
+			engine = *args;
+		    } else badarg = 1;
+#endif
+		} else badarg = 1;
+
+	} else badarg = 1;
+	args++;
+    }
+
+    if (badarg) {
+	BIO_printf (bio_err, "Usage: pkcs12 [options]\n");
+	BIO_printf (bio_err, "where options are\n");
+	BIO_printf (bio_err, "-export       output PKCS12 file\n");
+	BIO_printf (bio_err, "-chain        add certificate chain\n");
+	BIO_printf (bio_err, "-inkey file   private key if not infile\n");
+	BIO_printf (bio_err, "-certfile f   add all certs in f\n");
+	BIO_printf (bio_err, "-CApath arg   - PEM format directory of CA's\n");
+	BIO_printf (bio_err, "-CAfile arg   - PEM format file of CA's\n");
+	BIO_printf (bio_err, "-name \"name\"  use name as friendly name\n");
+	BIO_printf (bio_err, "-caname \"nm\"  use nm as CA friendly name (can be used more than once).\n");
+	BIO_printf (bio_err, "-in  infile   input filename\n");
+	BIO_printf (bio_err, "-out outfile  output filename\n");
+	BIO_printf (bio_err, "-noout        don't output anything, just verify.\n");
+	BIO_printf (bio_err, "-nomacver     don't verify MAC.\n");
+	BIO_printf (bio_err, "-nocerts      don't output certificates.\n");
+	BIO_printf (bio_err, "-clcerts      only output client certificates.\n");
+	BIO_printf (bio_err, "-cacerts      only output CA certificates.\n");
+	BIO_printf (bio_err, "-nokeys       don't output private keys.\n");
+	BIO_printf (bio_err, "-info         give info about PKCS#12 structure.\n");
+	BIO_printf (bio_err, "-des          encrypt private keys with DES\n");
+	BIO_printf (bio_err, "-des3         encrypt private keys with triple DES (default)\n");
+#ifndef OPENSSL_NO_IDEA
+	BIO_printf (bio_err, "-idea         encrypt private keys with idea\n");
+#endif
+#ifndef OPENSSL_NO_SEED
+	BIO_printf (bio_err, "-seed         encrypt private keys with seed\n");
+#endif
+#ifndef OPENSSL_NO_AES
+	BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
+	BIO_printf (bio_err, "              encrypt PEM output with cbc aes\n");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+	BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n");
+	BIO_printf (bio_err, "              encrypt PEM output with cbc camellia\n");
+#endif
+	BIO_printf (bio_err, "-nodes        don't encrypt private keys\n");
+	BIO_printf (bio_err, "-noiter       don't use encryption iteration\n");
+	BIO_printf (bio_err, "-nomaciter    don't use MAC iteration\n");
+	BIO_printf (bio_err, "-maciter      use MAC iteration\n");
+	BIO_printf (bio_err, "-nomac        don't generate MAC\n");
+	BIO_printf (bio_err, "-twopass      separate MAC, encryption passwords\n");
+	BIO_printf (bio_err, "-descert      encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
+	BIO_printf (bio_err, "-certpbe alg  specify certificate PBE algorithm (default RC2-40)\n");
+	BIO_printf (bio_err, "-keypbe alg   specify private key PBE algorithm (default 3DES)\n");
+	BIO_printf (bio_err, "-macalg alg   digest algorithm used in MAC (default SHA1)\n");
+	BIO_printf (bio_err, "-keyex        set MS key exchange type\n");
+	BIO_printf (bio_err, "-keysig       set MS key signature type\n");
+	BIO_printf (bio_err, "-password p   set import/export password source\n");
+	BIO_printf (bio_err, "-passin p     input file pass phrase source\n");
+	BIO_printf (bio_err, "-passout p    output file pass phrase source\n");
+#ifndef OPENSSL_NO_ENGINE
+	BIO_printf (bio_err, "-engine e     use engine e, possibly a hardware device.\n");
+#endif
+	BIO_printf(bio_err,  "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+	BIO_printf(bio_err,  "              load the file (or the files in the directory) into\n");
+	BIO_printf(bio_err,  "              the random number generator\n");
+	BIO_printf(bio_err,  "-CSP name     Microsoft CSP name\n");
+	BIO_printf(bio_err,  "-LMK          Add local machine keyset attribute to private key\n");
+    	goto end;
+    }
+
+#ifndef OPENSSL_NO_ENGINE
+    e = setup_engine(bio_err, engine, 0);
+#endif
+
+    if(passarg) {
+	if(export_cert) passargout = passarg;
+	else passargin = passarg;
+    }
+
+    if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
+	BIO_printf(bio_err, "Error getting passwords\n");
+	goto end;
+    }
+
+    if(!cpass) {
+    	if(export_cert) cpass = passout;
+    	else cpass = passin;
+    }
+
+    if(cpass) {
+	mpass = cpass;
+	noprompt = 1;
+    } else {
+	cpass = pass;
+	mpass = macpass;
+    }
+
+    if(export_cert || inrand) {
+    	app_RAND_load_file(NULL, bio_err, (inrand != NULL));
+        if (inrand != NULL)
+		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+			app_RAND_load_files(inrand));
+    }
+    ERR_load_crypto_strings();
+
+#ifdef CRYPTO_MDEBUG
+    CRYPTO_push_info("read files");
+#endif
+
+    if (!infile) in = BIO_new_fp(stdin, BIO_NOCLOSE);
+    else in = BIO_new_file(infile, "rb");
+    if (!in) {
+	    BIO_printf(bio_err, "Error opening input file %s\n",
+						infile ? infile : "<stdin>");
+	    perror (infile);
+	    goto end;
+   }
+
+#ifdef CRYPTO_MDEBUG
+    CRYPTO_pop_info();
+    CRYPTO_push_info("write files");
+#endif
+
+    if (!outfile) {
+	out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+	{
+	    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+	    out = BIO_push(tmpbio, out);
+	}
+#endif
+    } else out = BIO_new_file(outfile, "wb");
+    if (!out) {
+	BIO_printf(bio_err, "Error opening output file %s\n",
+						outfile ? outfile : "<stdout>");
+	perror (outfile);
+	goto end;
+    }
+    if (twopass) {
+#ifdef CRYPTO_MDEBUG
+    CRYPTO_push_info("read MAC password");
+#endif
+	if(EVP_read_pw_string (macpass, sizeof macpass, "Enter MAC Password:", export_cert))
+	{
+    	    BIO_printf (bio_err, "Can't read Password\n");
+    	    goto end;
+       	}
+#ifdef CRYPTO_MDEBUG
+    CRYPTO_pop_info();
+#endif
+    }
+
+    if (export_cert) {
+	EVP_PKEY *key = NULL;
+	X509 *ucert = NULL, *x = NULL;
+	STACK_OF(X509) *certs=NULL;
+	const EVP_MD *macmd = NULL;
+	unsigned char *catmp = NULL;
+	int i;
+
+	if ((options & (NOCERTS|NOKEYS)) == (NOCERTS|NOKEYS))
+		{	
+		BIO_printf(bio_err, "Nothing to do!\n");
+		goto export_end;
+		}
+
+	if (options & NOCERTS)
+		chain = 0;
+
+#ifdef CRYPTO_MDEBUG
+	CRYPTO_push_info("process -export_cert");
+	CRYPTO_push_info("reading private key");
+#endif
+	if (!(options & NOKEYS))
+		{
+		key = load_key(bio_err, keyname ? keyname : infile,
+				FORMAT_PEM, 1, passin, e, "private key");
+		if (!key)
+			goto export_end;
+		}
+
+#ifdef CRYPTO_MDEBUG
+	CRYPTO_pop_info();
+	CRYPTO_push_info("reading certs from input");
+#endif
+
+	/* Load in all certs in input file */
+	if(!(options & NOCERTS))
+		{
+		certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
+							"certificates");
+		if (!certs)
+			goto export_end;
+
+		if (key)
+			{
+			/* Look for matching private key */
+			for(i = 0; i < sk_X509_num(certs); i++)
+				{
+				x = sk_X509_value(certs, i);
+				if(X509_check_private_key(x, key))
+					{
+					ucert = x;
+					/* Zero keyid and alias */
+					X509_keyid_set1(ucert, NULL, 0);
+					X509_alias_set1(ucert, NULL, 0);
+					/* Remove from list */
+					(void)sk_X509_delete(certs, i);
+					break;
+					}
+				}
+			if (!ucert)
+				{
+				BIO_printf(bio_err, "No certificate matches private key\n");
+				goto export_end;
+				}
+			}
+
+		}
+
+#ifdef CRYPTO_MDEBUG
+	CRYPTO_pop_info();
+	CRYPTO_push_info("reading certs from input 2");
+#endif
+
+	/* Add any more certificates asked for */
+	if(certfile)
+		{
+		STACK_OF(X509) *morecerts=NULL;
+		if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
+					    NULL, e,
+					    "certificates from certfile")))
+			goto export_end;
+		while(sk_X509_num(morecerts) > 0)
+			sk_X509_push(certs, sk_X509_shift(morecerts));
+		sk_X509_free(morecerts);
+ 		}
+
+#ifdef CRYPTO_MDEBUG
+	CRYPTO_pop_info();
+	CRYPTO_push_info("reading certs from certfile");
+#endif
+
+#ifdef CRYPTO_MDEBUG
+	CRYPTO_pop_info();
+	CRYPTO_push_info("building chain");
+#endif
+
+	/* If chaining get chain from user cert */
+	if (chain) {
+        	int vret;
+		STACK_OF(X509) *chain2;
+		X509_STORE *store = X509_STORE_new();
+		if (!store)
+			{
+			BIO_printf (bio_err, "Memory allocation error\n");
+			goto export_end;
+			}
+		if (!X509_STORE_load_locations(store, CAfile, CApath))
+			X509_STORE_set_default_paths (store);
+
+		vret = get_cert_chain (ucert, store, &chain2);
+		X509_STORE_free(store);
+
+		if (!vret) {
+		    /* Exclude verified certificate */
+		    for (i = 1; i < sk_X509_num (chain2) ; i++) 
+			sk_X509_push(certs, sk_X509_value (chain2, i));
+		    /* Free first certificate */
+		    X509_free(sk_X509_value(chain2, 0));
+		    sk_X509_free(chain2);
+		} else {
+			if (vret >= 0)
+				BIO_printf (bio_err, "Error %s getting chain.\n",
+					X509_verify_cert_error_string(vret));
+			else
+				ERR_print_errors(bio_err);
+			goto export_end;
+		}			
+    	}
+
+	/* Add any CA names */
+
+	for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++)
+		{
+		catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i);
+		X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
+		}
+
+	if (csp_name && key)
+		EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
+				MBSTRING_ASC, (unsigned char *)csp_name, -1);
+
+	if (add_lmk && key)
+		EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);
+
+#ifdef CRYPTO_MDEBUG
+	CRYPTO_pop_info();
+	CRYPTO_push_info("reading password");
+#endif
+
+	if(!noprompt &&
+		EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", 1))
+		{
+	    	BIO_printf (bio_err, "Can't read Password\n");
+	    	goto export_end;
+        	}
+	if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
+
+#ifdef CRYPTO_MDEBUG
+	CRYPTO_pop_info();
+	CRYPTO_push_info("creating PKCS#12 structure");
+#endif
+
+	p12 = PKCS12_create(cpass, name, key, ucert, certs,
+				key_pbe, cert_pbe, iter, -1, keytype);
+
+	if (!p12)
+		{
+	    	ERR_print_errors (bio_err);
+		goto export_end;
+		}
+
+	if (macalg)
+		{
+		macmd = EVP_get_digestbyname(macalg);
+		if (!macmd)
+			{
+			BIO_printf(bio_err, "Unknown digest algorithm %s\n", 
+						macalg);
+			}
+		}
+
+	if (maciter != -1)
+		PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd);
+
+#ifdef CRYPTO_MDEBUG
+	CRYPTO_pop_info();
+	CRYPTO_push_info("writing pkcs12");
+#endif
+
+	i2d_PKCS12_bio(out, p12);
+
+	ret = 0;
+
+    export_end:
+#ifdef CRYPTO_MDEBUG
+	CRYPTO_pop_info();
+	CRYPTO_pop_info();
+	CRYPTO_push_info("process -export_cert: freeing");
+#endif
+
+	if (key) EVP_PKEY_free(key);
+	if (certs) sk_X509_pop_free(certs, X509_free);
+	if (ucert) X509_free(ucert);
+
+#ifdef CRYPTO_MDEBUG
+	CRYPTO_pop_info();
+#endif
+	goto end;
+	
+    }
+
+    if (!(p12 = d2i_PKCS12_bio (in, NULL))) {
+	ERR_print_errors(bio_err);
+	goto end;
+    }
+
+#ifdef CRYPTO_MDEBUG
+    CRYPTO_push_info("read import password");
+#endif
+    if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", 0)) {
+	BIO_printf (bio_err, "Can't read Password\n");
+	goto end;
+    }
+#ifdef CRYPTO_MDEBUG
+    CRYPTO_pop_info();
+#endif
+
+    if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
+
+    if ((options & INFO) && p12->mac) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1);
+    if(macver) {
+#ifdef CRYPTO_MDEBUG
+    CRYPTO_push_info("verify MAC");
+#endif
+	/* If we enter empty password try no password first */
+	if(!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
+		/* If mac and crypto pass the same set it to NULL too */
+		if(!twopass) cpass = NULL;
+	} else if (!PKCS12_verify_mac(p12, mpass, -1)) {
+	    BIO_printf (bio_err, "Mac verify error: invalid password?\n");
+	    ERR_print_errors (bio_err);
+	    goto end;
+	}
+	BIO_printf (bio_err, "MAC verified OK\n");
+#ifdef CRYPTO_MDEBUG
+    CRYPTO_pop_info();
+#endif
+    }
+
+#ifdef CRYPTO_MDEBUG
+    CRYPTO_push_info("output keys and certificates");
+#endif
+    if (!dump_certs_keys_p12 (out, p12, cpass, -1, options, passout)) {
+	BIO_printf(bio_err, "Error outputting keys and certificates\n");
+	ERR_print_errors (bio_err);
+	goto end;
+    }
+#ifdef CRYPTO_MDEBUG
+    CRYPTO_pop_info();
+#endif
+    ret = 0;
+ end:
+    if (p12) PKCS12_free(p12);
+    if(export_cert || inrand) app_RAND_write_file(NULL, bio_err);
+#ifdef CRYPTO_MDEBUG
+    CRYPTO_remove_all_info();
+#endif
+    BIO_free(in);
+    BIO_free_all(out);
+    if (canames) sk_OPENSSL_STRING_free(canames);
+    if(passin) OPENSSL_free(passin);
+    if(passout) OPENSSL_free(passout);
+    apps_shutdown();
+    OPENSSL_EXIT(ret);
+}
+
+int dump_certs_keys_p12 (BIO *out, PKCS12 *p12, char *pass,
+	     int passlen, int options, char *pempass)
+{
+	STACK_OF(PKCS7) *asafes = NULL;
+	STACK_OF(PKCS12_SAFEBAG) *bags;
+	int i, bagnid;
+	int ret = 0;
+	PKCS7 *p7;
+
+	if (!( asafes = PKCS12_unpack_authsafes(p12))) return 0;
+	for (i = 0; i < sk_PKCS7_num (asafes); i++) {
+		p7 = sk_PKCS7_value (asafes, i);
+		bagnid = OBJ_obj2nid (p7->type);
+		if (bagnid == NID_pkcs7_data) {
+			bags = PKCS12_unpack_p7data(p7);
+			if (options & INFO) BIO_printf (bio_err, "PKCS7 Data\n");
+		} else if (bagnid == NID_pkcs7_encrypted) {
+			if (options & INFO) {
+				BIO_printf(bio_err, "PKCS7 Encrypted data: ");
+				alg_print(bio_err, 
+					p7->d.encrypted->enc_data->algorithm);
+			}
+			bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
+		} else continue;
+		if (!bags) goto err;
+	    	if (!dump_certs_pkeys_bags (out, bags, pass, passlen, 
+						 options, pempass)) {
+			sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free);
+			goto err;
+		}
+		sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free);
+		bags = NULL;
+	}
+	ret = 1;
+
+	err:
+
+	if (asafes)
+		sk_PKCS7_pop_free (asafes, PKCS7_free);
+	return ret;
+}
+
+int dump_certs_pkeys_bags (BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags,
+			   char *pass, int passlen, int options, char *pempass)
+{
+	int i;
+	for (i = 0; i < sk_PKCS12_SAFEBAG_num (bags); i++) {
+		if (!dump_certs_pkeys_bag (out,
+					   sk_PKCS12_SAFEBAG_value (bags, i),
+					   pass, passlen,
+					   options, pempass))
+		    return 0;
+	}
+	return 1;
+}
+
+int dump_certs_pkeys_bag (BIO *out, PKCS12_SAFEBAG *bag, char *pass,
+	     int passlen, int options, char *pempass)
+{
+	EVP_PKEY *pkey;
+	PKCS8_PRIV_KEY_INFO *p8;
+	X509 *x509;
+	
+	switch (M_PKCS12_bag_type(bag))
+	{
+	case NID_keyBag:
+		if (options & INFO) BIO_printf (bio_err, "Key bag\n");
+		if (options & NOKEYS) return 1;
+		print_attribs (out, bag->attrib, "Bag Attributes");
+		p8 = bag->value.keybag;
+		if (!(pkey = EVP_PKCS82PKEY (p8))) return 0;
+		print_attribs (out, p8->attributes, "Key Attributes");
+		PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass);
+		EVP_PKEY_free(pkey);
+	break;
+
+	case NID_pkcs8ShroudedKeyBag:
+		if (options & INFO) {
+			BIO_printf (bio_err, "Shrouded Keybag: ");
+			alg_print (bio_err, bag->value.shkeybag->algor);
+		}
+		if (options & NOKEYS) return 1;
+		print_attribs (out, bag->attrib, "Bag Attributes");
+		if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
+				return 0;
+		if (!(pkey = EVP_PKCS82PKEY (p8))) {
+			PKCS8_PRIV_KEY_INFO_free(p8);
+			return 0;
+		}
+		print_attribs (out, p8->attributes, "Key Attributes");
+		PKCS8_PRIV_KEY_INFO_free(p8);
+		PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass);
+		EVP_PKEY_free(pkey);
+	break;
+
+	case NID_certBag:
+		if (options & INFO) BIO_printf (bio_err, "Certificate bag\n");
+		if (options & NOCERTS) return 1;
+                if (PKCS12_get_attr(bag, NID_localKeyID)) {
+			if (options & CACERTS) return 1;
+		} else if (options & CLCERTS) return 1;
+		print_attribs (out, bag->attrib, "Bag Attributes");
+		if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )
+								 return 1;
+		if (!(x509 = PKCS12_certbag2x509(bag))) return 0;
+		dump_cert_text (out, x509);
+		PEM_write_bio_X509 (out, x509);
+		X509_free(x509);
+	break;
+
+	case NID_safeContentsBag:
+		if (options & INFO) BIO_printf (bio_err, "Safe Contents bag\n");
+		print_attribs (out, bag->attrib, "Bag Attributes");
+		return dump_certs_pkeys_bags (out, bag->value.safes, pass,
+							    passlen, options, pempass);
+					
+	default:
+		BIO_printf (bio_err, "Warning unsupported bag type: ");
+		i2a_ASN1_OBJECT (bio_err, bag->type);
+		BIO_printf (bio_err, "\n");
+		return 1;
+	break;
+	}
+	return 1;
+}
+
+/* Given a single certificate return a verified chain or NULL if error */
+
+/* Hope this is OK .... */
+
+int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain)
+{
+	X509_STORE_CTX store_ctx;
+	STACK_OF(X509) *chn;
+	int i = 0;
+
+	/* FIXME: Should really check the return status of X509_STORE_CTX_init
+	 * for an error, but how that fits into the return value of this
+	 * function is less obvious. */
+	X509_STORE_CTX_init(&store_ctx, store, cert, NULL);
+	if (X509_verify_cert(&store_ctx) <= 0) {
+		i = X509_STORE_CTX_get_error (&store_ctx);
+		if (i == 0)
+			/* avoid returning 0 if X509_verify_cert() did not
+			 * set an appropriate error value in the context */
+			i = -1;
+		chn = NULL;
+		goto err;
+	} else
+		chn = X509_STORE_CTX_get1_chain(&store_ctx);
+err:
+	X509_STORE_CTX_cleanup(&store_ctx);
+	*chain = chn;
+	
+	return i;
+}	
+
+int alg_print (BIO *x, X509_ALGOR *alg)
+{
+	PBEPARAM *pbe;
+	const unsigned char *p;
+	p = alg->parameter->value.sequence->data;
+	pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length);
+	if (!pbe)
+		return 1;
+	BIO_printf (bio_err, "%s, Iteration %ld\n", 
+		OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)),
+		ASN1_INTEGER_get(pbe->iter));
+	PBEPARAM_free (pbe);
+	return 1;
+}
+
+/* Load all certificates from a given file */
+
+int cert_load(BIO *in, STACK_OF(X509) *sk)
+{
+	int ret;
+	X509 *cert;
+	ret = 0;
+#ifdef CRYPTO_MDEBUG
+	CRYPTO_push_info("cert_load(): reading one cert");
+#endif
+	while((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
+#ifdef CRYPTO_MDEBUG
+		CRYPTO_pop_info();
+#endif
+		ret = 1;
+		sk_X509_push(sk, cert);
+#ifdef CRYPTO_MDEBUG
+		CRYPTO_push_info("cert_load(): reading one cert");
+#endif
+	}
+#ifdef CRYPTO_MDEBUG
+	CRYPTO_pop_info();
+#endif
+	if(ret) ERR_clear_error();
+	return ret;
+}
+
+/* Generalised attribute print: handle PKCS#8 and bag attributes */
+
+int print_attribs (BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name)
+{
+	X509_ATTRIBUTE *attr;
+	ASN1_TYPE *av;
+	char *value;
+	int i, attr_nid;
+	if(!attrlst) {
+		BIO_printf(out, "%s: <No Attributes>\n", name);
+		return 1;
+	}
+	if(!sk_X509_ATTRIBUTE_num(attrlst)) {
+		BIO_printf(out, "%s: <Empty Attributes>\n", name);
+		return 1;
+	}
+	BIO_printf(out, "%s\n", name);
+	for(i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) {
+		attr = sk_X509_ATTRIBUTE_value(attrlst, i);
+		attr_nid = OBJ_obj2nid(attr->object);
+		BIO_printf(out, "    ");
+		if(attr_nid == NID_undef) {
+			i2a_ASN1_OBJECT (out, attr->object);
+			BIO_printf(out, ": ");
+		} else BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
+
+		if(sk_ASN1_TYPE_num(attr->value.set)) {
+			av = sk_ASN1_TYPE_value(attr->value.set, 0);
+			switch(av->type) {
+				case V_ASN1_BMPSTRING:
+        			value = OPENSSL_uni2asc(av->value.bmpstring->data,
+                                	       av->value.bmpstring->length);
+				BIO_printf(out, "%s\n", value);
+				OPENSSL_free(value);
+				break;
+
+				case V_ASN1_OCTET_STRING:
+				hex_prin(out, av->value.octet_string->data,
+					av->value.octet_string->length);
+				BIO_printf(out, "\n");	
+				break;
+
+				case V_ASN1_BIT_STRING:
+				hex_prin(out, av->value.bit_string->data,
+					av->value.bit_string->length);
+				BIO_printf(out, "\n");	
+				break;
+
+				default:
+					BIO_printf(out, "<Unsupported tag %d>\n", av->type);
+				break;
+			}
+		} else BIO_printf(out, "<No Values>\n");
+	}
+	return 1;
+}
+
+void hex_prin(BIO *out, unsigned char *buf, int len)
+{
+	int i;
+	for (i = 0; i < len; i++) BIO_printf (out, "%02X ", buf[i]);
+}
+
+static int set_pbe(BIO *err, int *ppbe, const char *str)
+	{
+	if (!str)
+		return 0;
+	if (!strcmp(str, "NONE"))
+		{
+		*ppbe = -1;
+		return 1;
+		}
+	*ppbe=OBJ_txt2nid(str);
+	if (*ppbe == NID_undef)
+		{
+		BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str);
+		return 0;
+		}
+	return 1;
+	}
+			
+#endif
diff --git a/openssl/apps/pkcs7.c b/openssl/apps/pkcs7.c
new file mode 100644
index 0000000..ae6cd33
--- /dev/null
+++ b/openssl/apps/pkcs7.c
@@ -0,0 +1,320 @@
+/* apps/pkcs7.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "apps.h"
+#include <openssl/err.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pem.h>
+
+#undef PROG
+#define PROG	pkcs7_main
+
+/* -inform arg	- input format - default PEM (DER or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg	- input file - default stdin
+ * -out arg	- output file - default stdout
+ * -print_certs
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	PKCS7 *p7=NULL;
+	int i,badops=0;
+	BIO *in=NULL,*out=NULL;
+	int informat,outformat;
+	char *infile,*outfile,*prog;
+	int print_certs=0,text=0,noout=0,p7_print=0;
+	int ret=1;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	infile=NULL;
+	outfile=NULL;
+	informat=FORMAT_PEM;
+	outformat=FORMAT_PEM;
+
+	prog=argv[0];
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if 	(strcmp(*argv,"-inform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			informat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-outform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outformat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-noout") == 0)
+			noout=1;
+		else if (strcmp(*argv,"-text") == 0)
+			text=1;
+		else if (strcmp(*argv,"-print") == 0)
+			p7_print=1;
+		else if (strcmp(*argv,"-print_certs") == 0)
+			print_certs=1;
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*argv,"-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine= *(++argv);
+			}
+#endif
+		else
+			{
+			BIO_printf(bio_err,"unknown option %s\n",*argv);
+			badops=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (badops)
+		{
+bad:
+		BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
+		BIO_printf(bio_err,"where options are\n");
+		BIO_printf(bio_err," -inform arg   input format - DER or PEM\n");
+		BIO_printf(bio_err," -outform arg  output format - DER or PEM\n");
+		BIO_printf(bio_err," -in arg       input file\n");
+		BIO_printf(bio_err," -out arg      output file\n");
+		BIO_printf(bio_err," -print_certs  print any certs or crl in the input\n");
+		BIO_printf(bio_err," -text         print full details of certificates\n");
+		BIO_printf(bio_err," -noout        don't output encoded data\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err," -engine e     use engine e, possibly a hardware device.\n");
+#endif
+		ret = 1;
+		goto end;
+		}
+
+	ERR_load_crypto_strings();
+
+#ifndef OPENSSL_NO_ENGINE
+        setup_engine(bio_err, engine, 0);
+#endif
+
+	in=BIO_new(BIO_s_file());
+	out=BIO_new(BIO_s_file());
+	if ((in == NULL) || (out == NULL))
+		{
+		ERR_print_errors(bio_err);
+                goto end;
+                }
+
+	if (infile == NULL)
+		BIO_set_fp(in,stdin,BIO_NOCLOSE);
+	else
+		{
+		if (BIO_read_filename(in,infile) <= 0)
+		if (in == NULL)
+			{
+			perror(infile);
+			goto end;
+			}
+		}
+
+	if	(informat == FORMAT_ASN1)
+		p7=d2i_PKCS7_bio(in,NULL);
+	else if (informat == FORMAT_PEM)
+		p7=PEM_read_bio_PKCS7(in,NULL,NULL,NULL);
+	else
+		{
+		BIO_printf(bio_err,"bad input format specified for pkcs7 object\n");
+		goto end;
+		}
+	if (p7 == NULL)
+		{
+		BIO_printf(bio_err,"unable to load PKCS7 object\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (outfile == NULL)
+		{
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+		}
+	else
+		{
+		if (BIO_write_filename(out,outfile) <= 0)
+			{
+			perror(outfile);
+			goto end;
+			}
+		}
+
+	if (p7_print)
+		PKCS7_print_ctx(out, p7, 0, NULL);
+
+	if (print_certs)
+		{
+		STACK_OF(X509) *certs=NULL;
+		STACK_OF(X509_CRL) *crls=NULL;
+
+		i=OBJ_obj2nid(p7->type);
+		switch (i)
+			{
+		case NID_pkcs7_signed:
+			certs=p7->d.sign->cert;
+			crls=p7->d.sign->crl;
+			break;
+		case NID_pkcs7_signedAndEnveloped:
+			certs=p7->d.signed_and_enveloped->cert;
+			crls=p7->d.signed_and_enveloped->crl;
+			break;
+		default:
+			break;
+			}
+
+		if (certs != NULL)
+			{
+			X509 *x;
+
+			for (i=0; i<sk_X509_num(certs); i++)
+				{
+				x=sk_X509_value(certs,i);
+				if(text) X509_print(out, x);
+				else dump_cert_text(out, x);
+
+				if(!noout) PEM_write_bio_X509(out,x);
+				BIO_puts(out,"\n");
+				}
+			}
+		if (crls != NULL)
+			{
+			X509_CRL *crl;
+
+			for (i=0; i<sk_X509_CRL_num(crls); i++)
+				{
+				crl=sk_X509_CRL_value(crls,i);
+
+				X509_CRL_print(out, crl);
+
+				if(!noout)PEM_write_bio_X509_CRL(out,crl);
+				BIO_puts(out,"\n");
+				}
+			}
+
+		ret=0;
+		goto end;
+		}
+
+	if(!noout) {
+		if 	(outformat == FORMAT_ASN1)
+			i=i2d_PKCS7_bio(out,p7);
+		else if (outformat == FORMAT_PEM)
+			i=PEM_write_bio_PKCS7(out,p7);
+		else	{
+			BIO_printf(bio_err,"bad output format specified for outfile\n");
+			goto end;
+			}
+
+		if (!i)
+			{
+			BIO_printf(bio_err,"unable to write pkcs7 object\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+	}
+	ret=0;
+end:
+	if (p7 != NULL) PKCS7_free(p7);
+	if (in != NULL) BIO_free(in);
+	if (out != NULL) BIO_free_all(out);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
diff --git a/openssl/apps/pkcs8.c b/openssl/apps/pkcs8.c
new file mode 100644
index 0000000..7edeb17
--- /dev/null
+++ b/openssl/apps/pkcs8.c
@@ -0,0 +1,439 @@
+/* pkcs8.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999-2004.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/pkcs12.h>
+
+#define PROG pkcs8_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	ENGINE *e = NULL;
+	char **args, *infile = NULL, *outfile = NULL;
+	char *passargin = NULL, *passargout = NULL;
+	BIO *in = NULL, *out = NULL;
+	int topk8 = 0;
+	int pbe_nid = -1;
+	const EVP_CIPHER *cipher = NULL;
+	int iter = PKCS12_DEFAULT_ITER;
+	int informat, outformat;
+	int p8_broken = PKCS8_OK;
+	int nocrypt = 0;
+	X509_SIG *p8 = NULL;
+	PKCS8_PRIV_KEY_INFO *p8inf = NULL;
+	EVP_PKEY *pkey=NULL;
+	char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL;
+	int badarg = 0;
+	int ret = 1;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+
+	if (bio_err == NULL) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	informat=FORMAT_PEM;
+	outformat=FORMAT_PEM;
+
+	ERR_load_crypto_strings();
+	OpenSSL_add_all_algorithms();
+	args = argv + 1;
+	while (!badarg && *args && *args[0] == '-')
+		{
+		if (!strcmp(*args,"-v2"))
+			{
+			if (args[1])
+				{
+				args++;
+				cipher=EVP_get_cipherbyname(*args);
+				if (!cipher)
+					{
+					BIO_printf(bio_err,
+						 "Unknown cipher %s\n", *args);
+					badarg = 1;
+					}
+				}
+			else
+				badarg = 1;
+			}
+		else if (!strcmp(*args,"-v1"))
+			{
+			if (args[1])
+				{
+				args++;
+				pbe_nid=OBJ_txt2nid(*args);
+				if (pbe_nid == NID_undef)
+					{
+					BIO_printf(bio_err,
+						 "Unknown PBE algorithm %s\n", *args);
+					badarg = 1;
+					}
+				}
+			else
+				badarg = 1;
+			}
+		else if (!strcmp(*args,"-inform"))
+			{
+			if (args[1])
+				{
+				args++;
+				informat=str2fmt(*args);
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args,"-outform"))
+			{
+			if (args[1])
+				{
+				args++;
+				outformat=str2fmt(*args);
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp (*args, "-topk8"))
+			topk8 = 1;
+		else if (!strcmp (*args, "-noiter"))
+			iter = 1;
+		else if (!strcmp (*args, "-nocrypt"))
+			nocrypt = 1;
+		else if (!strcmp (*args, "-nooct"))
+			p8_broken = PKCS8_NO_OCTET;
+		else if (!strcmp (*args, "-nsdb"))
+			p8_broken = PKCS8_NS_DB;
+		else if (!strcmp (*args, "-embed"))
+			p8_broken = PKCS8_EMBEDDED_PARAM;
+		else if (!strcmp(*args,"-passin"))
+			{
+			if (!args[1]) goto bad;
+			passargin= *(++args);
+			}
+		else if (!strcmp(*args,"-passout"))
+			{
+			if (!args[1]) goto bad;
+			passargout= *(++args);
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*args,"-engine") == 0)
+			{
+			if (!args[1]) goto bad;
+			engine= *(++args);
+			}
+#endif
+		else if (!strcmp (*args, "-in"))
+			{
+			if (args[1])
+				{
+				args++;
+				infile = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp (*args, "-out"))
+			{
+			if (args[1])
+				{
+				args++;
+				outfile = *args;
+				}
+			else badarg = 1;
+			}
+		else badarg = 1;
+		args++;
+		}
+
+	if (badarg)
+		{
+		bad:
+		BIO_printf(bio_err, "Usage pkcs8 [options]\n");
+		BIO_printf(bio_err, "where options are\n");
+		BIO_printf(bio_err, "-in file        input file\n");
+		BIO_printf(bio_err, "-inform X       input format (DER or PEM)\n");
+		BIO_printf(bio_err, "-passin arg     input file pass phrase source\n");
+		BIO_printf(bio_err, "-outform X      output format (DER or PEM)\n");
+		BIO_printf(bio_err, "-out file       output file\n");
+		BIO_printf(bio_err, "-passout arg    output file pass phrase source\n");
+		BIO_printf(bio_err, "-topk8          output PKCS8 file\n");
+		BIO_printf(bio_err, "-nooct          use (nonstandard) no octet format\n");
+		BIO_printf(bio_err, "-embed          use (nonstandard) embedded DSA parameters format\n");
+		BIO_printf(bio_err, "-nsdb           use (nonstandard) DSA Netscape DB format\n");
+		BIO_printf(bio_err, "-noiter         use 1 as iteration count\n");
+		BIO_printf(bio_err, "-nocrypt        use or expect unencrypted private key\n");
+		BIO_printf(bio_err, "-v2 alg         use PKCS#5 v2.0 and cipher \"alg\"\n");
+		BIO_printf(bio_err, "-v1 obj         use PKCS#5 v1.5 and cipher \"alg\"\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err," -engine e       use engine e, possibly a hardware device.\n");
+#endif
+		goto end;
+		}
+
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine, 0);
+#endif
+
+	if (!app_passwd(bio_err, passargin, passargout, &passin, &passout))
+		{
+		BIO_printf(bio_err, "Error getting passwords\n");
+		goto end;
+		}
+
+	if ((pbe_nid == -1) && !cipher)
+		pbe_nid = NID_pbeWithMD5AndDES_CBC;
+
+	if (infile)
+		{
+		if (!(in = BIO_new_file(infile, "rb")))
+			{
+			BIO_printf(bio_err,
+				 "Can't open input file %s\n", infile);
+			goto end;
+			}
+		}
+	else
+		in = BIO_new_fp (stdin, BIO_NOCLOSE);
+
+	if (outfile)
+		{
+		if (!(out = BIO_new_file (outfile, "wb")))
+			{
+			BIO_printf(bio_err,
+				 "Can't open output file %s\n", outfile);
+			goto end;
+			}
+		}
+	else
+		{
+		out = BIO_new_fp (stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+			{
+			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+			out = BIO_push(tmpbio, out);
+			}
+#endif
+		}
+	if (topk8)
+		{
+		pkey = load_key(bio_err, infile, informat, 1,
+			passin, e, "key");
+		if (!pkey)
+			goto end;
+		if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken)))
+			{
+			BIO_printf(bio_err, "Error converting key\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		if (nocrypt)
+			{
+			if (outformat == FORMAT_PEM) 
+				PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf);
+			else if (outformat == FORMAT_ASN1)
+				i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf);
+			else
+				{
+				BIO_printf(bio_err, "Bad format specified for key\n");
+				goto end;
+				}
+			}
+		else
+			{
+			if (passout)
+				p8pass = passout;
+			else
+				{
+				p8pass = pass;
+				if (EVP_read_pw_string(pass, sizeof pass, "Enter Encryption Password:", 1))
+					goto end;
+				}
+			app_RAND_load_file(NULL, bio_err, 0);
+			if (!(p8 = PKCS8_encrypt(pbe_nid, cipher,
+					p8pass, strlen(p8pass),
+					NULL, 0, iter, p8inf)))
+				{
+				BIO_printf(bio_err, "Error encrypting key\n");
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+			app_RAND_write_file(NULL, bio_err);
+			if (outformat == FORMAT_PEM) 
+				PEM_write_bio_PKCS8(out, p8);
+			else if (outformat == FORMAT_ASN1)
+				i2d_PKCS8_bio(out, p8);
+			else
+				{
+				BIO_printf(bio_err, "Bad format specified for key\n");
+				goto end;
+				}
+			}
+
+		ret = 0;
+		goto end;
+		}
+
+	if (nocrypt)
+		{
+		if (informat == FORMAT_PEM) 
+			p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in,NULL,NULL, NULL);
+		else if (informat == FORMAT_ASN1)
+			p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL);
+		else
+			{
+			BIO_printf(bio_err, "Bad format specified for key\n");
+			goto end;
+			}
+		}
+	else
+		{
+		if (informat == FORMAT_PEM) 
+			p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
+		else if (informat == FORMAT_ASN1)
+			p8 = d2i_PKCS8_bio(in, NULL);
+		else
+			{
+			BIO_printf(bio_err, "Bad format specified for key\n");
+			goto end;
+			}
+
+		if (!p8)
+			{
+			BIO_printf (bio_err, "Error reading key\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		if (passin)
+			p8pass = passin;
+		else
+			{
+			p8pass = pass;
+			EVP_read_pw_string(pass, sizeof pass, "Enter Password:", 0);
+			}
+		p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass));
+		}
+
+	if (!p8inf)
+		{
+		BIO_printf(bio_err, "Error decrypting key\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (!(pkey = EVP_PKCS82PKEY(p8inf)))
+		{
+		BIO_printf(bio_err, "Error converting key\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+	
+	if (p8inf->broken)
+		{
+		BIO_printf(bio_err, "Warning: broken key encoding: ");
+		switch (p8inf->broken)
+			{
+			case PKCS8_NO_OCTET:
+			BIO_printf(bio_err, "No Octet String in PrivateKey\n");
+			break;
+
+			case PKCS8_EMBEDDED_PARAM:
+			BIO_printf(bio_err, "DSA parameters included in PrivateKey\n");
+			break;
+
+			case PKCS8_NS_DB:
+			BIO_printf(bio_err, "DSA public key include in PrivateKey\n");
+			break;
+
+			case PKCS8_NEG_PRIVKEY:
+			BIO_printf(bio_err, "DSA private key value is negative\n");
+			break;
+
+			default:
+			BIO_printf(bio_err, "Unknown broken type\n");
+			break;
+		}
+	}
+	
+	if (outformat == FORMAT_PEM) 
+		PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout);
+	else if (outformat == FORMAT_ASN1)
+		i2d_PrivateKey_bio(out, pkey);
+	else
+		{
+		BIO_printf(bio_err, "Bad format specified for key\n");
+			goto end;
+		}
+	ret = 0;
+
+	end:
+	X509_SIG_free(p8);
+	PKCS8_PRIV_KEY_INFO_free(p8inf);
+	EVP_PKEY_free(pkey);
+	BIO_free_all(out);
+	BIO_free(in);
+	if (passin)
+		OPENSSL_free(passin);
+	if (passout)
+		OPENSSL_free(passout);
+
+	return ret;
+	}
diff --git a/openssl/apps/pkey.c b/openssl/apps/pkey.c
new file mode 100644
index 0000000..17e6702
--- /dev/null
+++ b/openssl/apps/pkey.c
@@ -0,0 +1,284 @@
+/* apps/pkey.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+#define PROG pkey_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	ENGINE *e = NULL;
+	char **args, *infile = NULL, *outfile = NULL;
+	char *passargin = NULL, *passargout = NULL;
+	BIO *in = NULL, *out = NULL;
+	const EVP_CIPHER *cipher = NULL;
+	int informat, outformat;
+	int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0;
+	EVP_PKEY *pkey=NULL;
+	char *passin = NULL, *passout = NULL;
+	int badarg = 0;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+	int ret = 1;
+
+	if (bio_err == NULL)
+		bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	informat=FORMAT_PEM;
+	outformat=FORMAT_PEM;
+
+	ERR_load_crypto_strings();
+	OpenSSL_add_all_algorithms();
+	args = argv + 1;
+	while (!badarg && *args && *args[0] == '-')
+		{
+		if (!strcmp(*args,"-inform"))
+			{
+			if (args[1])
+				{
+				args++;
+				informat=str2fmt(*args);
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args,"-outform"))
+			{
+			if (args[1])
+				{
+				args++;
+				outformat=str2fmt(*args);
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args,"-passin"))
+			{
+			if (!args[1]) goto bad;
+			passargin= *(++args);
+			}
+		else if (!strcmp(*args,"-passout"))
+			{
+			if (!args[1]) goto bad;
+			passargout= *(++args);
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*args,"-engine") == 0)
+			{
+			if (!args[1]) goto bad;
+			engine= *(++args);
+			}
+#endif
+		else if (!strcmp (*args, "-in"))
+			{
+			if (args[1])
+				{
+				args++;
+				infile = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp (*args, "-out"))
+			{
+			if (args[1])
+				{
+				args++;
+				outfile = *args;
+				}
+			else badarg = 1;
+			}
+		else if (strcmp(*args,"-pubin") == 0)
+			{
+			pubin=1;
+			pubout=1;
+			pubtext=1;
+			}
+		else if (strcmp(*args,"-pubout") == 0)
+			pubout=1;
+		else if (strcmp(*args,"-text_pub") == 0)
+			{
+			pubtext=1;
+			text=1;
+			}
+		else if (strcmp(*args,"-text") == 0)
+			text=1;
+		else if (strcmp(*args,"-noout") == 0)
+			noout=1;
+		else
+			{
+			cipher = EVP_get_cipherbyname(*args + 1);
+			if (!cipher)
+				{
+				BIO_printf(bio_err, "Unknown cipher %s\n",
+								*args + 1);
+				badarg = 1;
+				}
+			}
+		args++;
+		}
+
+	if (badarg)
+		{
+		bad:
+		BIO_printf(bio_err, "Usage pkey [options]\n");
+		BIO_printf(bio_err, "where options are\n");
+		BIO_printf(bio_err, "-in file        input file\n");
+		BIO_printf(bio_err, "-inform X       input format (DER or PEM)\n");
+		BIO_printf(bio_err, "-passin arg     input file pass phrase source\n");
+		BIO_printf(bio_err, "-outform X      output format (DER or PEM)\n");
+		BIO_printf(bio_err, "-out file       output file\n");
+		BIO_printf(bio_err, "-passout arg    output file pass phrase source\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
+#endif
+		return 1;
+		}
+
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine, 0);
+#endif
+
+	if (!app_passwd(bio_err, passargin, passargout, &passin, &passout))
+		{
+		BIO_printf(bio_err, "Error getting passwords\n");
+		goto end;
+		}
+
+	if (outfile)
+		{
+		if (!(out = BIO_new_file (outfile, "wb")))
+			{
+			BIO_printf(bio_err,
+				 "Can't open output file %s\n", outfile);
+			goto end;
+			}
+		}
+	else
+		{
+		out = BIO_new_fp (stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+			{
+			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+			out = BIO_push(tmpbio, out);
+			}
+#endif
+		}
+
+	if (pubin)
+		pkey = load_pubkey(bio_err, infile, informat, 1,
+			passin, e, "Public Key");
+	else
+		pkey = load_key(bio_err, infile, informat, 1,
+			passin, e, "key");
+	if (!pkey)
+		goto end;
+
+	if (!noout)
+		{
+		if (outformat == FORMAT_PEM) 
+			{
+			if (pubout)
+				PEM_write_bio_PUBKEY(out,pkey);
+			else
+				PEM_write_bio_PrivateKey(out, pkey, cipher,
+							NULL, 0, NULL, passout);
+			}
+		else if (outformat == FORMAT_ASN1)
+			{
+			if (pubout)
+				i2d_PUBKEY_bio(out, pkey);
+			else
+				i2d_PrivateKey_bio(out, pkey);
+			}
+		else
+			{
+			BIO_printf(bio_err, "Bad format specified for key\n");
+			goto end;
+			}
+
+		}
+
+	if (text)
+		{
+		if (pubtext)
+			EVP_PKEY_print_public(out, pkey, 0, NULL);
+		else
+			EVP_PKEY_print_private(out, pkey, 0, NULL);
+		}
+
+	ret = 0;
+
+	end:
+	EVP_PKEY_free(pkey);
+	BIO_free_all(out);
+	BIO_free(in);
+	if (passin)
+		OPENSSL_free(passin);
+	if (passout)
+		OPENSSL_free(passout);
+
+	return ret;
+	}
diff --git a/openssl/apps/pkeyparam.c b/openssl/apps/pkeyparam.c
new file mode 100644
index 0000000..6f7a357
--- /dev/null
+++ b/openssl/apps/pkeyparam.c
@@ -0,0 +1,200 @@
+/* apps/pkeyparam.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+#define PROG pkeyparam_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	char **args, *infile = NULL, *outfile = NULL;
+	BIO *in = NULL, *out = NULL;
+	int text = 0, noout = 0;
+	EVP_PKEY *pkey=NULL;
+	int badarg = 0;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+	int ret = 1;
+
+	if (bio_err == NULL)
+		bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	ERR_load_crypto_strings();
+	OpenSSL_add_all_algorithms();
+	args = argv + 1;
+	while (!badarg && *args && *args[0] == '-')
+		{
+		if (!strcmp (*args, "-in"))
+			{
+			if (args[1])
+				{
+				args++;
+				infile = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp (*args, "-out"))
+			{
+			if (args[1])
+				{
+				args++;
+				outfile = *args;
+				}
+			else badarg = 1;
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*args,"-engine") == 0)
+			{
+			if (!args[1]) goto bad;
+			engine= *(++args);
+			}
+#endif
+
+		else if (strcmp(*args,"-text") == 0)
+			text=1;
+		else if (strcmp(*args,"-noout") == 0)
+			noout=1;
+		args++;
+		}
+
+	if (badarg)
+		{
+#ifndef OPENSSL_NO_ENGINE
+		bad:
+#endif
+		BIO_printf(bio_err, "Usage pkeyparam [options]\n");
+		BIO_printf(bio_err, "where options are\n");
+		BIO_printf(bio_err, "-in file        input file\n");
+		BIO_printf(bio_err, "-out file       output file\n");
+		BIO_printf(bio_err, "-text           print parameters as text\n");
+		BIO_printf(bio_err, "-noout          don't output encoded parameters\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
+#endif
+		return 1;
+		}
+
+#ifndef OPENSSL_NO_ENGINE
+        setup_engine(bio_err, engine, 0);
+#endif
+
+	if (infile)
+		{
+		if (!(in = BIO_new_file (infile, "r")))
+			{
+			BIO_printf(bio_err,
+				 "Can't open input file %s\n", infile);
+			goto end;
+			}
+		}
+	else
+		in = BIO_new_fp (stdin, BIO_NOCLOSE);
+
+	if (outfile)
+		{
+		if (!(out = BIO_new_file (outfile, "w")))
+			{
+			BIO_printf(bio_err,
+				 "Can't open output file %s\n", outfile);
+			goto end;
+			}
+		}
+	else
+		{
+		out = BIO_new_fp (stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+			{
+			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+			out = BIO_push(tmpbio, out);
+			}
+#endif
+		}
+
+	pkey = PEM_read_bio_Parameters(in, NULL);
+	if (!pkey)
+		{
+		BIO_printf(bio_err, "Error reading parameters\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (!noout)
+		PEM_write_bio_Parameters(out,pkey);
+
+	if (text)
+		EVP_PKEY_print_params(out, pkey, 0, NULL);
+
+	ret = 0;
+
+	end:
+	EVP_PKEY_free(pkey);
+	BIO_free_all(out);
+	BIO_free(in);
+
+	return ret;
+	}
diff --git a/openssl/apps/pkeyutl.c b/openssl/apps/pkeyutl.c
new file mode 100644
index 0000000..7eb3f5c
--- /dev/null
+++ b/openssl/apps/pkeyutl.c
@@ -0,0 +1,570 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include "apps.h"
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+
+#define KEY_PRIVKEY	1
+#define KEY_PUBKEY	2
+#define KEY_CERT	3
+
+static void usage(void);
+
+#undef PROG
+
+#define PROG pkeyutl_main
+
+static EVP_PKEY_CTX *init_ctx(int *pkeysize,
+				char *keyfile, int keyform, int key_type,
+				char *passargin, int pkey_op, ENGINE *e);
+
+static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform,
+							const char *file);
+
+static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
+		unsigned char *out, size_t *poutlen,
+		unsigned char *in, size_t inlen);
+
+int MAIN(int argc, char **);
+
+int MAIN(int argc, char **argv)
+{
+	BIO *in = NULL, *out = NULL;
+	char *infile = NULL, *outfile = NULL, *sigfile = NULL;
+	ENGINE *e = NULL;
+	int pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY;
+	int keyform = FORMAT_PEM, peerform = FORMAT_PEM;
+	char badarg = 0, rev = 0;
+	char hexdump = 0, asn1parse = 0;
+	EVP_PKEY_CTX *ctx = NULL;
+	char *passargin = NULL;
+	int keysize = -1;
+
+	unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
+	size_t buf_outlen;
+	int buf_inlen = 0, siglen = -1;
+
+	int ret = 1, rv = -1;
+
+	argc--;
+	argv++;
+
+	if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+	ERR_load_crypto_strings();
+	OpenSSL_add_all_algorithms();
+	
+	while(argc >= 1)
+		{
+		if (!strcmp(*argv,"-in"))
+			{
+			if (--argc < 1) badarg = 1;
+                        else infile= *(++argv);
+			}
+		else if (!strcmp(*argv,"-out"))
+			{
+			if (--argc < 1) badarg = 1;
+			else outfile= *(++argv);
+			}
+		else if (!strcmp(*argv,"-sigfile"))
+			{
+			if (--argc < 1) badarg = 1;
+			else sigfile= *(++argv);
+			}
+		else if(!strcmp(*argv, "-inkey"))
+			{
+			if (--argc < 1)
+				badarg = 1;
+			else
+				{
+				ctx = init_ctx(&keysize,
+						*(++argv), keyform, key_type,
+						passargin, pkey_op, e);
+				if (!ctx)
+					{
+					BIO_puts(bio_err,
+						"Error initializing context\n");
+					ERR_print_errors(bio_err);
+					badarg = 1;
+					}
+				}
+			}
+		else if (!strcmp(*argv,"-peerkey"))
+			{
+			if (--argc < 1)
+				badarg = 1;
+			else if (!setup_peer(bio_err, ctx, peerform, *(++argv)))
+				badarg = 1;
+			}
+		else if (!strcmp(*argv,"-passin"))
+			{
+			if (--argc < 1) badarg = 1;
+			else passargin= *(++argv);
+			}
+		else if (strcmp(*argv,"-peerform") == 0)
+			{
+			if (--argc < 1) badarg = 1;
+			else peerform=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-keyform") == 0)
+			{
+			if (--argc < 1) badarg = 1;
+			else keyform=str2fmt(*(++argv));
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if(!strcmp(*argv, "-engine"))
+			{
+			if (--argc < 1)
+				badarg = 1;
+			else
+				e = setup_engine(bio_err, *(++argv), 0);
+			}
+#endif
+		else if(!strcmp(*argv, "-pubin"))
+			key_type = KEY_PUBKEY;
+		else if(!strcmp(*argv, "-certin"))
+			key_type = KEY_CERT;
+		else if(!strcmp(*argv, "-asn1parse"))
+			asn1parse = 1;
+		else if(!strcmp(*argv, "-hexdump"))
+			hexdump = 1;
+		else if(!strcmp(*argv, "-sign"))
+			pkey_op = EVP_PKEY_OP_SIGN;
+		else if(!strcmp(*argv, "-verify"))
+			pkey_op = EVP_PKEY_OP_VERIFY;
+		else if(!strcmp(*argv, "-verifyrecover"))
+			pkey_op = EVP_PKEY_OP_VERIFYRECOVER;
+		else if(!strcmp(*argv, "-rev"))
+			rev = 1;
+		else if(!strcmp(*argv, "-encrypt"))
+			pkey_op = EVP_PKEY_OP_ENCRYPT;
+		else if(!strcmp(*argv, "-decrypt"))
+			pkey_op = EVP_PKEY_OP_DECRYPT;
+		else if(!strcmp(*argv, "-derive"))
+			pkey_op = EVP_PKEY_OP_DERIVE;
+		else if (strcmp(*argv,"-pkeyopt") == 0)
+			{
+			if (--argc < 1)
+				badarg = 1;
+			else if (!ctx)
+				{
+				BIO_puts(bio_err,
+					"-pkeyopt command before -inkey\n");
+				badarg = 1;
+				}
+			else if (pkey_ctrl_string(ctx, *(++argv)) <= 0)
+				{
+				BIO_puts(bio_err, "parameter setting error\n");
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+			}
+		else badarg = 1;
+		if(badarg)
+			{
+			usage();
+			goto end;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (!ctx)
+		{
+		usage();
+		goto end;
+		}
+
+	if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY))
+		{
+		BIO_puts(bio_err, "Signature file specified for non verify\n");
+		goto end;
+		}
+
+	if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY))
+		{
+		BIO_puts(bio_err, "No signature file specified for verify\n");
+		goto end;
+		}
+
+/* FIXME: seed PRNG only if needed */
+	app_RAND_load_file(NULL, bio_err, 0);
+
+	if (pkey_op != EVP_PKEY_OP_DERIVE)
+		{
+		if(infile)
+			{
+			if(!(in = BIO_new_file(infile, "rb")))
+				{
+				BIO_puts(bio_err,
+					"Error Opening Input File\n");
+				ERR_print_errors(bio_err);	
+				goto end;
+				}
+			}
+		else
+			in = BIO_new_fp(stdin, BIO_NOCLOSE);
+		}
+
+	if(outfile)
+		{
+		if(!(out = BIO_new_file(outfile, "wb")))
+			{
+			BIO_printf(bio_err, "Error Creating Output File\n");
+			ERR_print_errors(bio_err);	
+			goto end;
+			}
+		}
+	else
+		{
+		out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		    out = BIO_push(tmpbio, out);
+		}
+#endif
+	}
+
+	if (sigfile)
+		{
+		BIO *sigbio = BIO_new_file(sigfile, "rb");
+		if (!sigbio)
+			{
+			BIO_printf(bio_err, "Can't open signature file %s\n",
+								sigfile);
+			goto end;
+			}
+		siglen = bio_to_mem(&sig, keysize * 10, sigbio);
+		BIO_free(sigbio);
+		if (siglen <= 0)
+			{
+			BIO_printf(bio_err, "Error reading signature data\n");
+			goto end;
+			}
+		}
+	
+	if (in)
+		{
+		/* Read the input data */
+		buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
+		if(buf_inlen <= 0)
+			{
+			BIO_printf(bio_err, "Error reading input Data\n");
+			exit(1);
+			}
+		if(rev)
+			{
+			size_t i;
+			unsigned char ctmp;
+			size_t l = (size_t)buf_inlen;
+			for(i = 0; i < l/2; i++)
+				{
+				ctmp = buf_in[i];
+				buf_in[i] = buf_in[l - 1 - i];
+				buf_in[l - 1 - i] = ctmp;
+				}
+			}
+		}
+
+	if(pkey_op == EVP_PKEY_OP_VERIFY)
+		{
+		rv  = EVP_PKEY_verify(ctx, sig, (size_t)siglen,
+				      buf_in, (size_t)buf_inlen);
+		if (rv == 0)
+			BIO_puts(out, "Signature Verification Failure\n");
+		else if (rv == 1)
+			BIO_puts(out, "Signature Verified Successfully\n");
+		if (rv >= 0)
+			goto end;
+		}
+	else
+		{	
+		rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen,
+			      buf_in, (size_t)buf_inlen);
+		if (rv > 0)
+			{
+			buf_out = OPENSSL_malloc(buf_outlen);
+			if (!buf_out)
+				rv = -1;
+			else
+				rv = do_keyop(ctx, pkey_op,
+						buf_out, (size_t *)&buf_outlen,
+						buf_in, (size_t)buf_inlen);
+			}
+		}
+
+	if(rv <= 0)
+		{
+		BIO_printf(bio_err, "Public Key operation error\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+	ret = 0;
+	if(asn1parse)
+		{
+		if(!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1))
+			ERR_print_errors(bio_err);
+		}
+	else if(hexdump)
+		BIO_dump(out, (char *)buf_out, buf_outlen);
+	else
+		BIO_write(out, buf_out, buf_outlen);
+
+	end:
+	if (ctx)
+		EVP_PKEY_CTX_free(ctx);
+	BIO_free(in);
+	BIO_free_all(out);
+	if (buf_in)
+		OPENSSL_free(buf_in);
+	if (buf_out)
+		OPENSSL_free(buf_out);
+	if (sig)
+		OPENSSL_free(sig);
+	return ret;
+}
+
+static void usage()
+{
+	BIO_printf(bio_err, "Usage: pkeyutl [options]\n");
+	BIO_printf(bio_err, "-in file        input file\n");
+	BIO_printf(bio_err, "-out file       output file\n");
+	BIO_printf(bio_err, "-sigfile file signature file (verify operation only)\n");
+	BIO_printf(bio_err, "-inkey file     input key\n");
+	BIO_printf(bio_err, "-keyform arg    private key format - default PEM\n");
+	BIO_printf(bio_err, "-pubin          input is a public key\n");
+	BIO_printf(bio_err, "-certin         input is a certificate carrying a public key\n");
+	BIO_printf(bio_err, "-pkeyopt X:Y    public key options\n");
+	BIO_printf(bio_err, "-sign           sign with private key\n");
+	BIO_printf(bio_err, "-verify         verify with public key\n");
+	BIO_printf(bio_err, "-verifyrecover  verify with public key, recover original data\n");
+	BIO_printf(bio_err, "-encrypt        encrypt with public key\n");
+	BIO_printf(bio_err, "-decrypt        decrypt with private key\n");
+	BIO_printf(bio_err, "-derive         derive shared secret\n");
+	BIO_printf(bio_err, "-hexdump        hex dump output\n");
+#ifndef OPENSSL_NO_ENGINE
+	BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
+#endif
+	BIO_printf(bio_err, "-passin arg     pass phrase source\n");
+
+}
+
+static EVP_PKEY_CTX *init_ctx(int *pkeysize,
+				char *keyfile, int keyform, int key_type,
+				char *passargin, int pkey_op, ENGINE *e)
+	{
+	EVP_PKEY *pkey = NULL;
+	EVP_PKEY_CTX *ctx = NULL;
+	char *passin = NULL;
+	int rv = -1;
+	X509 *x;
+	if(((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT) 
+		|| (pkey_op == EVP_PKEY_OP_DERIVE))
+		&& (key_type != KEY_PRIVKEY))
+		{
+		BIO_printf(bio_err, "A private key is needed for this operation\n");
+		goto end;
+		}
+	if(!app_passwd(bio_err, passargin, NULL, &passin, NULL))
+		{
+		BIO_printf(bio_err, "Error getting password\n");
+		goto end;
+		}
+	switch(key_type)
+		{
+		case KEY_PRIVKEY:
+		pkey = load_key(bio_err, keyfile, keyform, 0,
+			passin, e, "Private Key");
+		break;
+
+		case KEY_PUBKEY:
+		pkey = load_pubkey(bio_err, keyfile, keyform, 0,
+			NULL, e, "Public Key");
+		break;
+
+		case KEY_CERT:
+		x = load_cert(bio_err, keyfile, keyform,
+			NULL, e, "Certificate");
+		if(x)
+			{
+			pkey = X509_get_pubkey(x);
+			X509_free(x);
+			}
+		break;
+
+		}
+
+	*pkeysize = EVP_PKEY_size(pkey);
+
+	if (!pkey)
+		goto end;
+
+	ctx = EVP_PKEY_CTX_new(pkey, e);
+
+	EVP_PKEY_free(pkey);
+
+	if (!ctx)
+		goto end;
+
+	switch(pkey_op)
+		{
+		case EVP_PKEY_OP_SIGN:
+		rv = EVP_PKEY_sign_init(ctx);
+		break;
+
+		case EVP_PKEY_OP_VERIFY:
+		rv = EVP_PKEY_verify_init(ctx);
+		break;
+
+		case EVP_PKEY_OP_VERIFYRECOVER:
+		rv = EVP_PKEY_verify_recover_init(ctx);
+		break;
+
+		case EVP_PKEY_OP_ENCRYPT:
+		rv = EVP_PKEY_encrypt_init(ctx);
+		break;
+
+		case EVP_PKEY_OP_DECRYPT:
+		rv = EVP_PKEY_decrypt_init(ctx);
+		break;
+
+		case EVP_PKEY_OP_DERIVE:
+		rv = EVP_PKEY_derive_init(ctx);
+		break;
+		}
+
+	if (rv <= 0)
+		{
+		EVP_PKEY_CTX_free(ctx);
+		ctx = NULL;
+		}
+
+	end:
+
+	if (passin)
+		OPENSSL_free(passin);
+
+	return ctx;
+
+
+	}
+
+static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform,
+							const char *file)
+	{
+	EVP_PKEY *peer = NULL;
+	int ret;
+	if (!ctx)
+		{
+		BIO_puts(err, "-peerkey command before -inkey\n");
+		return 0;
+		}
+		
+	peer = load_pubkey(bio_err, file, peerform, 0, NULL, NULL, "Peer Key");
+
+	if (!peer)
+		{
+		BIO_printf(bio_err, "Error reading peer key %s\n", file);
+		ERR_print_errors(err);
+		return 0;
+		}
+
+	ret = EVP_PKEY_derive_set_peer(ctx, peer);
+
+	EVP_PKEY_free(peer);
+	if (ret <= 0)
+		ERR_print_errors(err);
+	return ret;
+	}
+
+static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
+		unsigned char *out, size_t *poutlen,
+		unsigned char *in, size_t inlen)
+	{
+	int rv = 0;
+	switch(pkey_op)
+		{
+		case EVP_PKEY_OP_VERIFYRECOVER:
+		rv  = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen);
+		break;
+
+		case EVP_PKEY_OP_SIGN:
+		rv  = EVP_PKEY_sign(ctx, out, poutlen, in, inlen);
+		break;
+
+		case EVP_PKEY_OP_ENCRYPT:
+		rv  = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen);
+		break;
+
+		case EVP_PKEY_OP_DECRYPT:
+		rv  = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen);
+		break; 
+
+		case EVP_PKEY_OP_DERIVE:
+		rv  = EVP_PKEY_derive(ctx, out, poutlen);
+		break;
+
+		}
+	return rv;
+	}
diff --git a/openssl/apps/prime.c b/openssl/apps/prime.c
new file mode 100644
index 0000000..f1aaef8
--- /dev/null
+++ b/openssl/apps/prime.c
@@ -0,0 +1,160 @@
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+
+#include "apps.h"
+#include <openssl/bn.h>
+
+
+#undef PROG
+#define PROG prime_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+    {
+    int hex=0;
+    int checks=20;
+    int generate=0;
+    int bits=0;
+    int safe=0;
+    BIGNUM *bn=NULL;
+    BIO *bio_out;
+
+    apps_startup();
+
+    if (bio_err == NULL)
+	if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+	    BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+    --argc;
+    ++argv;
+    while (argc >= 1 && **argv == '-')
+	{
+	if(!strcmp(*argv,"-hex"))
+	    hex=1;
+	else if(!strcmp(*argv,"-generate"))
+	    generate=1;
+	else if(!strcmp(*argv,"-bits"))
+	    if(--argc < 1)
+		goto bad;
+	    else
+		bits=atoi(*++argv);
+	else if(!strcmp(*argv,"-safe"))
+	    safe=1;
+	else if(!strcmp(*argv,"-checks"))
+	    if(--argc < 1)
+		goto bad;
+	    else
+		checks=atoi(*++argv);
+	else
+	    {
+	    BIO_printf(bio_err,"Unknown option '%s'\n",*argv);
+	    goto bad;
+	    }
+	--argc;
+	++argv;
+	}
+
+    if (argv[0] == NULL && !generate)
+	{
+	BIO_printf(bio_err,"No prime specified\n");
+	goto bad;
+	}
+
+    if ((bio_out=BIO_new(BIO_s_file())) != NULL)
+	{
+	BIO_set_fp(bio_out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+	    {
+	    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+	    bio_out = BIO_push(tmpbio, bio_out);
+	    }
+#endif
+	}
+
+    if(generate)
+	{
+	char *s;
+
+	if(!bits)
+	    {
+	    BIO_printf(bio_err,"Specifiy the number of bits.\n");
+	    return 1;
+	    }
+	bn=BN_new();
+	BN_generate_prime_ex(bn,bits,safe,NULL,NULL,NULL);
+	s=hex ? BN_bn2hex(bn) : BN_bn2dec(bn);
+	BIO_printf(bio_out,"%s\n",s);
+	OPENSSL_free(s);
+	}
+    else
+	{
+	if(hex)
+	    BN_hex2bn(&bn,argv[0]);
+	else
+	    BN_dec2bn(&bn,argv[0]);
+
+	BN_print(bio_out,bn);
+	BIO_printf(bio_out," is %sprime\n",
+		   BN_is_prime_ex(bn,checks,NULL,NULL) ? "" : "not ");
+	}
+
+    BN_free(bn);
+    BIO_free_all(bio_out);
+
+    return 0;
+
+    bad:
+    BIO_printf(bio_err,"options are\n");
+    BIO_printf(bio_err,"%-14s hex\n","-hex");
+    BIO_printf(bio_err,"%-14s number of checks\n","-checks <n>");
+    return 1;
+    }
diff --git a/openssl/apps/privkey.pem b/openssl/apps/privkey.pem
new file mode 100644
index 0000000..0af4647
--- /dev/null
+++ b/openssl/apps/privkey.pem
@@ -0,0 +1,18 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,BA26229A1653B7FF
+
+6nhWG8PKhTPO/s3ZvjUa6226NlKdvPDZFsNXOOoSUs9ejxpb/aj5huhs6qRYzsz9
+Year47uaAZYhGD0vAagnNiBnYmjWEpN9G/wQxG7pgZThK1ZxDi63qn8aQ8UjuGHo
+F6RpnnBQIAnWTWqr/Qsybtc5EoNkrj/Cpx0OfbSr6gZsFBCxwX1R1hT3/mhJ45f3
+XMofY32Vdfx9/vtw1O7HmlHXQnXaqnbd9/nn1EpvFJG9+UjPoW7gV4jCOLuR4deE
+jS8hm+cpkwXmFtk3VGjT9tQXPpMv3JpYfBqgGQoMAJ5Toq0DWcHi6Wg08PsD8lgy
+vmTioPsRg+JGkJkJ8GnusgLpQdlQJbjzd7wGE6ElUFLfOxLo8bLlRHoriHNdWYhh
+JjY0LyeTkovcmWxVjImc6ZyBz5Ly4t0BYf1gq3OkjsV91Q1taBxnhiavfizqMCAf
+PPB3sLQnlXG77TOXkNxpqbZfEYrVZW2Nsqqdn8s07Uj4IMONZyq2odYKWFPMJBiM
+POYwXjMAOcmFMTHYsVlhcUJuV6LOuipw/FEbTtPH/MYMxLe4zx65dYo1rb4iLKLS
+gMtB0o/Wl4Xno3ZXh1ucicYnV2J7NpVcjVq+3SFiCRu2SrSkZHZ23EPS13Ec6fcz
+8X/YGA2vTJ8MAOozAzQUwHQYvLk7bIoQVekqDq4p0AZQbhdspHpArCk0Ifqqzg/v
+Uyky/zZiQYanzDenTSRVI/8wac3olxpU8QvbySxYqmbkgq6bTpXJfYFQfnAttEsC
+dA4S5UFgyOPZluxCAM4yaJF3Ft6neutNwftuJQMbgCUi9vYg2tGdSw==
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/apps/progs.h b/openssl/apps/progs.h
new file mode 100644
index 0000000..728bb6d
--- /dev/null
+++ b/openssl/apps/progs.h
@@ -0,0 +1,364 @@
+/* apps/progs.h */
+/* automatically generated by progs.pl for openssl.c */
+
+extern int verify_main(int argc,char *argv[]);
+extern int asn1parse_main(int argc,char *argv[]);
+extern int req_main(int argc,char *argv[]);
+extern int dgst_main(int argc,char *argv[]);
+extern int dh_main(int argc,char *argv[]);
+extern int dhparam_main(int argc,char *argv[]);
+extern int enc_main(int argc,char *argv[]);
+extern int passwd_main(int argc,char *argv[]);
+extern int gendh_main(int argc,char *argv[]);
+extern int errstr_main(int argc,char *argv[]);
+extern int ca_main(int argc,char *argv[]);
+extern int crl_main(int argc,char *argv[]);
+extern int rsa_main(int argc,char *argv[]);
+extern int rsautl_main(int argc,char *argv[]);
+extern int dsa_main(int argc,char *argv[]);
+extern int dsaparam_main(int argc,char *argv[]);
+extern int ec_main(int argc,char *argv[]);
+extern int ecparam_main(int argc,char *argv[]);
+extern int x509_main(int argc,char *argv[]);
+extern int genrsa_main(int argc,char *argv[]);
+extern int gendsa_main(int argc,char *argv[]);
+extern int genpkey_main(int argc,char *argv[]);
+extern int s_server_main(int argc,char *argv[]);
+extern int s_client_main(int argc,char *argv[]);
+extern int speed_main(int argc,char *argv[]);
+extern int s_time_main(int argc,char *argv[]);
+extern int version_main(int argc,char *argv[]);
+extern int pkcs7_main(int argc,char *argv[]);
+extern int cms_main(int argc,char *argv[]);
+extern int crl2pkcs7_main(int argc,char *argv[]);
+extern int sess_id_main(int argc,char *argv[]);
+extern int ciphers_main(int argc,char *argv[]);
+extern int nseq_main(int argc,char *argv[]);
+extern int pkcs12_main(int argc,char *argv[]);
+extern int pkcs8_main(int argc,char *argv[]);
+extern int pkey_main(int argc,char *argv[]);
+extern int pkeyparam_main(int argc,char *argv[]);
+extern int pkeyutl_main(int argc,char *argv[]);
+extern int spkac_main(int argc,char *argv[]);
+extern int smime_main(int argc,char *argv[]);
+extern int rand_main(int argc,char *argv[]);
+extern int engine_main(int argc,char *argv[]);
+extern int ocsp_main(int argc,char *argv[]);
+extern int prime_main(int argc,char *argv[]);
+extern int ts_main(int argc,char *argv[]);
+
+#define FUNC_TYPE_GENERAL	1
+#define FUNC_TYPE_MD		2
+#define FUNC_TYPE_CIPHER	3
+#define FUNC_TYPE_PKEY		4
+#define FUNC_TYPE_MD_ALG	5
+#define FUNC_TYPE_CIPHER_ALG	6
+
+typedef struct {
+	int type;
+	const char *name;
+	int (*func)(int argc,char *argv[]);
+	} FUNCTION;
+DECLARE_LHASH_OF(FUNCTION);
+
+FUNCTION functions[] = {
+	{FUNC_TYPE_GENERAL,"verify",verify_main},
+	{FUNC_TYPE_GENERAL,"asn1parse",asn1parse_main},
+	{FUNC_TYPE_GENERAL,"req",req_main},
+	{FUNC_TYPE_GENERAL,"dgst",dgst_main},
+#ifndef OPENSSL_NO_DH
+	{FUNC_TYPE_GENERAL,"dh",dh_main},
+#endif
+#ifndef OPENSSL_NO_DH
+	{FUNC_TYPE_GENERAL,"dhparam",dhparam_main},
+#endif
+	{FUNC_TYPE_GENERAL,"enc",enc_main},
+	{FUNC_TYPE_GENERAL,"passwd",passwd_main},
+#ifndef OPENSSL_NO_DH
+	{FUNC_TYPE_GENERAL,"gendh",gendh_main},
+#endif
+	{FUNC_TYPE_GENERAL,"errstr",errstr_main},
+	{FUNC_TYPE_GENERAL,"ca",ca_main},
+	{FUNC_TYPE_GENERAL,"crl",crl_main},
+#ifndef OPENSSL_NO_RSA
+	{FUNC_TYPE_GENERAL,"rsa",rsa_main},
+#endif
+#ifndef OPENSSL_NO_RSA
+	{FUNC_TYPE_GENERAL,"rsautl",rsautl_main},
+#endif
+#ifndef OPENSSL_NO_DSA
+	{FUNC_TYPE_GENERAL,"dsa",dsa_main},
+#endif
+#ifndef OPENSSL_NO_DSA
+	{FUNC_TYPE_GENERAL,"dsaparam",dsaparam_main},
+#endif
+#ifndef OPENSSL_NO_EC
+	{FUNC_TYPE_GENERAL,"ec",ec_main},
+#endif
+#ifndef OPENSSL_NO_EC
+	{FUNC_TYPE_GENERAL,"ecparam",ecparam_main},
+#endif
+	{FUNC_TYPE_GENERAL,"x509",x509_main},
+#ifndef OPENSSL_NO_RSA
+	{FUNC_TYPE_GENERAL,"genrsa",genrsa_main},
+#endif
+#ifndef OPENSSL_NO_DSA
+	{FUNC_TYPE_GENERAL,"gendsa",gendsa_main},
+#endif
+	{FUNC_TYPE_GENERAL,"genpkey",genpkey_main},
+#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
+	{FUNC_TYPE_GENERAL,"s_server",s_server_main},
+#endif
+#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
+	{FUNC_TYPE_GENERAL,"s_client",s_client_main},
+#endif
+#ifndef OPENSSL_NO_SPEED
+	{FUNC_TYPE_GENERAL,"speed",speed_main},
+#endif
+#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
+	{FUNC_TYPE_GENERAL,"s_time",s_time_main},
+#endif
+	{FUNC_TYPE_GENERAL,"version",version_main},
+	{FUNC_TYPE_GENERAL,"pkcs7",pkcs7_main},
+#ifndef OPENSSL_NO_CMS
+	{FUNC_TYPE_GENERAL,"cms",cms_main},
+#endif
+	{FUNC_TYPE_GENERAL,"crl2pkcs7",crl2pkcs7_main},
+	{FUNC_TYPE_GENERAL,"sess_id",sess_id_main},
+#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
+	{FUNC_TYPE_GENERAL,"ciphers",ciphers_main},
+#endif
+	{FUNC_TYPE_GENERAL,"nseq",nseq_main},
+#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
+	{FUNC_TYPE_GENERAL,"pkcs12",pkcs12_main},
+#endif
+	{FUNC_TYPE_GENERAL,"pkcs8",pkcs8_main},
+	{FUNC_TYPE_GENERAL,"pkey",pkey_main},
+	{FUNC_TYPE_GENERAL,"pkeyparam",pkeyparam_main},
+	{FUNC_TYPE_GENERAL,"pkeyutl",pkeyutl_main},
+	{FUNC_TYPE_GENERAL,"spkac",spkac_main},
+	{FUNC_TYPE_GENERAL,"smime",smime_main},
+	{FUNC_TYPE_GENERAL,"rand",rand_main},
+#ifndef OPENSSL_NO_ENGINE
+	{FUNC_TYPE_GENERAL,"engine",engine_main},
+#endif
+#ifndef OPENSSL_NO_OCSP
+	{FUNC_TYPE_GENERAL,"ocsp",ocsp_main},
+#endif
+	{FUNC_TYPE_GENERAL,"prime",prime_main},
+#if 0 /* ANDROID */
+	{FUNC_TYPE_GENERAL,"ts",ts_main},
+#endif
+#ifndef OPENSSL_NO_MD2
+	{FUNC_TYPE_MD,"md2",dgst_main},
+#endif
+#ifndef OPENSSL_NO_MD4
+	{FUNC_TYPE_MD,"md4",dgst_main},
+#endif
+#ifndef OPENSSL_NO_MD5
+	{FUNC_TYPE_MD,"md5",dgst_main},
+#endif
+#ifndef OPENSSL_NO_SHA
+	{FUNC_TYPE_MD,"sha",dgst_main},
+#endif
+#ifndef OPENSSL_NO_SHA1
+	{FUNC_TYPE_MD,"sha1",dgst_main},
+#endif
+#ifndef OPENSSL_NO_MDC2
+	{FUNC_TYPE_MD,"mdc2",dgst_main},
+#endif
+#ifndef OPENSSL_NO_RMD160
+	{FUNC_TYPE_MD,"rmd160",dgst_main},
+#endif
+#ifndef OPENSSL_NO_AES
+	{FUNC_TYPE_CIPHER,"aes-128-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_AES
+	{FUNC_TYPE_CIPHER,"aes-128-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_AES
+	{FUNC_TYPE_CIPHER,"aes-192-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_AES
+	{FUNC_TYPE_CIPHER,"aes-192-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_AES
+	{FUNC_TYPE_CIPHER,"aes-256-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_AES
+	{FUNC_TYPE_CIPHER,"aes-256-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+	{FUNC_TYPE_CIPHER,"camellia-128-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+	{FUNC_TYPE_CIPHER,"camellia-128-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+	{FUNC_TYPE_CIPHER,"camellia-192-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+	{FUNC_TYPE_CIPHER,"camellia-192-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+	{FUNC_TYPE_CIPHER,"camellia-256-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+	{FUNC_TYPE_CIPHER,"camellia-256-ecb",enc_main},
+#endif
+	{FUNC_TYPE_CIPHER,"base64",enc_main},
+#ifdef ZLIB
+	{FUNC_TYPE_CIPHER,"zlib",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+	{FUNC_TYPE_CIPHER,"des",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+	{FUNC_TYPE_CIPHER,"des3",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+	{FUNC_TYPE_CIPHER,"desx",enc_main},
+#endif
+#ifndef OPENSSL_NO_IDEA
+	{FUNC_TYPE_CIPHER,"idea",enc_main},
+#endif
+#ifndef OPENSSL_NO_SEED
+	{FUNC_TYPE_CIPHER,"seed",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC4
+	{FUNC_TYPE_CIPHER,"rc4",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC4
+	{FUNC_TYPE_CIPHER,"rc4-40",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC2
+	{FUNC_TYPE_CIPHER,"rc2",enc_main},
+#endif
+#ifndef OPENSSL_NO_BF
+	{FUNC_TYPE_CIPHER,"bf",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAST
+	{FUNC_TYPE_CIPHER,"cast",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC5
+	{FUNC_TYPE_CIPHER,"rc5",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+	{FUNC_TYPE_CIPHER,"des-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+	{FUNC_TYPE_CIPHER,"des-ede",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+	{FUNC_TYPE_CIPHER,"des-ede3",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+	{FUNC_TYPE_CIPHER,"des-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+	{FUNC_TYPE_CIPHER,"des-ede-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+	{FUNC_TYPE_CIPHER,"des-ede3-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+	{FUNC_TYPE_CIPHER,"des-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+	{FUNC_TYPE_CIPHER,"des-ede-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+	{FUNC_TYPE_CIPHER,"des-ede3-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+	{FUNC_TYPE_CIPHER,"des-ofb",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+	{FUNC_TYPE_CIPHER,"des-ede-ofb",enc_main},
+#endif
+#ifndef OPENSSL_NO_DES
+	{FUNC_TYPE_CIPHER,"des-ede3-ofb",enc_main},
+#endif
+#ifndef OPENSSL_NO_IDEA
+	{FUNC_TYPE_CIPHER,"idea-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_IDEA
+	{FUNC_TYPE_CIPHER,"idea-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_IDEA
+	{FUNC_TYPE_CIPHER,"idea-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_IDEA
+	{FUNC_TYPE_CIPHER,"idea-ofb",enc_main},
+#endif
+#ifndef OPENSSL_NO_SEED
+	{FUNC_TYPE_CIPHER,"seed-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_SEED
+	{FUNC_TYPE_CIPHER,"seed-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_SEED
+	{FUNC_TYPE_CIPHER,"seed-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_SEED
+	{FUNC_TYPE_CIPHER,"seed-ofb",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC2
+	{FUNC_TYPE_CIPHER,"rc2-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC2
+	{FUNC_TYPE_CIPHER,"rc2-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC2
+	{FUNC_TYPE_CIPHER,"rc2-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC2
+	{FUNC_TYPE_CIPHER,"rc2-ofb",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC2
+	{FUNC_TYPE_CIPHER,"rc2-64-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC2
+	{FUNC_TYPE_CIPHER,"rc2-40-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_BF
+	{FUNC_TYPE_CIPHER,"bf-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_BF
+	{FUNC_TYPE_CIPHER,"bf-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_BF
+	{FUNC_TYPE_CIPHER,"bf-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_BF
+	{FUNC_TYPE_CIPHER,"bf-ofb",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAST
+	{FUNC_TYPE_CIPHER,"cast5-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAST
+	{FUNC_TYPE_CIPHER,"cast5-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAST
+	{FUNC_TYPE_CIPHER,"cast5-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAST
+	{FUNC_TYPE_CIPHER,"cast5-ofb",enc_main},
+#endif
+#ifndef OPENSSL_NO_CAST
+	{FUNC_TYPE_CIPHER,"cast-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC5
+	{FUNC_TYPE_CIPHER,"rc5-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC5
+	{FUNC_TYPE_CIPHER,"rc5-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC5
+	{FUNC_TYPE_CIPHER,"rc5-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_RC5
+	{FUNC_TYPE_CIPHER,"rc5-ofb",enc_main},
+#endif
+	{0,NULL,NULL}
+	};
diff --git a/openssl/apps/progs.pl b/openssl/apps/progs.pl
new file mode 100644
index 0000000..de6fdea
--- /dev/null
+++ b/openssl/apps/progs.pl
@@ -0,0 +1,102 @@
+#!/usr/local/bin/perl
+
+print "/* apps/progs.h */\n";
+print "/* automatically generated by progs.pl for openssl.c */\n\n";
+
+grep(s/^asn1pars$/asn1parse/,@ARGV);
+
+foreach (@ARGV)
+	{ printf "extern int %s_main(int argc,char *argv[]);\n",$_; }
+
+print <<'EOF';
+
+#define FUNC_TYPE_GENERAL	1
+#define FUNC_TYPE_MD		2
+#define FUNC_TYPE_CIPHER	3
+#define FUNC_TYPE_PKEY		4
+#define FUNC_TYPE_MD_ALG	5
+#define FUNC_TYPE_CIPHER_ALG	6
+
+typedef struct {
+	int type;
+	const char *name;
+	int (*func)(int argc,char *argv[]);
+	} FUNCTION;
+DECLARE_LHASH_OF(FUNCTION);
+
+FUNCTION functions[] = {
+EOF
+
+foreach (@ARGV)
+	{
+	push(@files,$_);
+	$str="\t{FUNC_TYPE_GENERAL,\"$_\",${_}_main},\n";
+	if (($_ =~ /^s_/) || ($_ =~ /^ciphers$/))
+		{ print "#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))\n${str}#endif\n"; } 
+	elsif ( ($_ =~ /^speed$/))
+		{ print "#ifndef OPENSSL_NO_SPEED\n${str}#endif\n"; }
+	elsif ( ($_ =~ /^engine$/))
+		{ print "#ifndef OPENSSL_NO_ENGINE\n${str}#endif\n"; }
+	elsif ( ($_ =~ /^rsa$/) || ($_ =~ /^genrsa$/) || ($_ =~ /^rsautl$/)) 
+		{ print "#ifndef OPENSSL_NO_RSA\n${str}#endif\n";  }
+	elsif ( ($_ =~ /^dsa$/) || ($_ =~ /^gendsa$/) || ($_ =~ /^dsaparam$/))
+		{ print "#ifndef OPENSSL_NO_DSA\n${str}#endif\n"; }
+	elsif ( ($_ =~ /^ec$/) || ($_ =~ /^ecparam$/))
+		{ print "#ifndef OPENSSL_NO_EC\n${str}#endif\n";}
+	elsif ( ($_ =~ /^dh$/) || ($_ =~ /^gendh$/) || ($_ =~ /^dhparam$/))
+		{ print "#ifndef OPENSSL_NO_DH\n${str}#endif\n"; }
+	elsif ( ($_ =~ /^pkcs12$/))
+		{ print "#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)\n${str}#endif\n"; }
+	elsif ( ($_ =~ /^cms$/))
+		{ print "#ifndef OPENSSL_NO_CMS\n${str}#endif\n"; }
+	elsif ( ($_ =~ /^ocsp$/))
+		{ print "#ifndef OPENSSL_NO_OCSP\n${str}#endif\n"; }
+	else
+		{ print $str; }
+	}
+
+foreach ("md2","md4","md5","sha","sha1","mdc2","rmd160")
+	{
+	push(@files,$_);
+	printf "#ifndef OPENSSL_NO_".uc($_)."\n\t{FUNC_TYPE_MD,\"".$_."\",dgst_main},\n#endif\n";
+	}
+
+foreach (
+	"aes-128-cbc", "aes-128-ecb",
+	"aes-192-cbc", "aes-192-ecb",
+	"aes-256-cbc", "aes-256-ecb",
+	"camellia-128-cbc", "camellia-128-ecb",
+	"camellia-192-cbc", "camellia-192-ecb",
+	"camellia-256-cbc", "camellia-256-ecb",
+	"base64", "zlib",
+	"des", "des3", "desx", "idea", "seed", "rc4", "rc4-40",
+	"rc2", "bf", "cast", "rc5",
+	"des-ecb", "des-ede",    "des-ede3",
+	"des-cbc", "des-ede-cbc","des-ede3-cbc",
+	"des-cfb", "des-ede-cfb","des-ede3-cfb",
+	"des-ofb", "des-ede-ofb","des-ede3-ofb",
+	"idea-cbc","idea-ecb",    "idea-cfb", "idea-ofb",
+	"seed-cbc","seed-ecb",    "seed-cfb", "seed-ofb",
+	"rc2-cbc", "rc2-ecb", "rc2-cfb","rc2-ofb", "rc2-64-cbc", "rc2-40-cbc",
+	"bf-cbc",  "bf-ecb",     "bf-cfb",   "bf-ofb",
+	"cast5-cbc","cast5-ecb", "cast5-cfb","cast5-ofb",
+	"cast-cbc", "rc5-cbc",   "rc5-ecb",  "rc5-cfb",  "rc5-ofb")
+	{
+	push(@files,$_);
+
+	$t=sprintf("\t{FUNC_TYPE_CIPHER,\"%s\",enc_main},\n",$_);
+	if    ($_ =~ /des/)  { $t="#ifndef OPENSSL_NO_DES\n${t}#endif\n"; }
+	elsif ($_ =~ /aes/)  { $t="#ifndef OPENSSL_NO_AES\n${t}#endif\n"; }
+	elsif ($_ =~ /camellia/)  { $t="#ifndef OPENSSL_NO_CAMELLIA\n${t}#endif\n"; }
+	elsif ($_ =~ /idea/) { $t="#ifndef OPENSSL_NO_IDEA\n${t}#endif\n"; }
+	elsif ($_ =~ /seed/) { $t="#ifndef OPENSSL_NO_SEED\n${t}#endif\n"; }
+	elsif ($_ =~ /rc4/)  { $t="#ifndef OPENSSL_NO_RC4\n${t}#endif\n"; }
+	elsif ($_ =~ /rc2/)  { $t="#ifndef OPENSSL_NO_RC2\n${t}#endif\n"; }
+	elsif ($_ =~ /bf/)   { $t="#ifndef OPENSSL_NO_BF\n${t}#endif\n"; }
+	elsif ($_ =~ /cast/) { $t="#ifndef OPENSSL_NO_CAST\n${t}#endif\n"; }
+	elsif ($_ =~ /rc5/)  { $t="#ifndef OPENSSL_NO_RC5\n${t}#endif\n"; }
+	elsif ($_ =~ /zlib/)  { $t="#ifdef ZLIB\n${t}#endif\n"; }
+	print $t;
+	}
+
+print "\t{0,NULL,NULL}\n\t};\n";
diff --git a/openssl/apps/rand.c b/openssl/apps/rand.c
new file mode 100644
index 0000000..790e795
--- /dev/null
+++ b/openssl/apps/rand.c
@@ -0,0 +1,245 @@
+/* apps/rand.c */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "apps.h"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+#undef PROG
+#define PROG rand_main
+
+/* -out file         - write to file
+ * -rand file:file   - PRNG seed files
+ * -base64           - base64 encode output
+ * -hex              - hex encode output
+ * num               - write 'num' bytes
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	int i, r, ret = 1;
+	int badopt;
+	char *outfile = NULL;
+	char *inrand = NULL;
+	int base64 = 0;
+	int hex = 0;
+	BIO *out = NULL;
+	int num = -1;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err = BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto err;
+
+	badopt = 0;
+	i = 0;
+	while (!badopt && argv[++i] != NULL)
+		{
+		if (strcmp(argv[i], "-out") == 0)
+			{
+			if ((argv[i+1] != NULL) && (outfile == NULL))
+				outfile = argv[++i];
+			else
+				badopt = 1;
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(argv[i], "-engine") == 0)
+			{
+			if ((argv[i+1] != NULL) && (engine == NULL))
+				engine = argv[++i];
+			else
+				badopt = 1;
+			}
+#endif
+		else if (strcmp(argv[i], "-rand") == 0)
+			{
+			if ((argv[i+1] != NULL) && (inrand == NULL))
+				inrand = argv[++i];
+			else
+				badopt = 1;
+			}
+		else if (strcmp(argv[i], "-base64") == 0)
+			{
+			if (!base64)
+				base64 = 1;
+			else
+				badopt = 1;
+			}
+		else if (strcmp(argv[i], "-hex") == 0)
+			{
+			if (!hex)
+				hex = 1;
+			else
+				badopt = 1;
+			}
+		else if (isdigit((unsigned char)argv[i][0]))
+			{
+			if (num < 0)
+				{
+				r = sscanf(argv[i], "%d", &num);
+				if (r == 0 || num < 0)
+					badopt = 1;
+				}
+			else
+				badopt = 1;
+			}
+		else
+			badopt = 1;
+		}
+
+	if (hex && base64)
+		badopt = 1;
+
+	if (num < 0)
+		badopt = 1;
+	
+	if (badopt) 
+		{
+		BIO_printf(bio_err, "Usage: rand [options] num\n");
+		BIO_printf(bio_err, "where options are\n");
+		BIO_printf(bio_err, "-out file             - write to file\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err, "-engine e             - use engine e, possibly a hardware device.\n");
+#endif
+		BIO_printf(bio_err, "-rand file%cfile%c... - seed PRNG from files\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+		BIO_printf(bio_err, "-base64               - base64 encode output\n");
+		BIO_printf(bio_err, "-hex                  - hex encode output\n");
+		goto err;
+		}
+
+#ifndef OPENSSL_NO_ENGINE
+        setup_engine(bio_err, engine, 0);
+#endif
+
+	app_RAND_load_file(NULL, bio_err, (inrand != NULL));
+	if (inrand != NULL)
+		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+			app_RAND_load_files(inrand));
+
+	out = BIO_new(BIO_s_file());
+	if (out == NULL)
+		goto err;
+	if (outfile != NULL)
+		r = BIO_write_filename(out, outfile);
+	else
+		{
+		r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+		}
+	if (r <= 0)
+		goto err;
+
+	if (base64)
+		{
+		BIO *b64 = BIO_new(BIO_f_base64());
+		if (b64 == NULL)
+			goto err;
+		out = BIO_push(b64, out);
+		}
+	
+	while (num > 0) 
+		{
+		unsigned char buf[4096];
+		int chunk;
+
+		chunk = num;
+		if (chunk > (int)sizeof(buf))
+			chunk = sizeof buf;
+		r = RAND_bytes(buf, chunk);
+		if (r <= 0)
+			goto err;
+		if (!hex) 
+			BIO_write(out, buf, chunk);
+		else
+			{
+			for (i = 0; i < chunk; i++)
+				BIO_printf(out, "%02x", buf[i]);
+			}
+		num -= chunk;
+		}
+	if (hex)
+		BIO_puts(out, "\n");
+	(void)BIO_flush(out);
+
+	app_RAND_write_file(NULL, bio_err);
+	ret = 0;
+	
+err:
+	ERR_print_errors(bio_err);
+	if (out)
+		BIO_free_all(out);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
diff --git a/openssl/apps/req.c b/openssl/apps/req.c
new file mode 100644
index 0000000..820cd18
--- /dev/null
+++ b/openssl/apps/req.c
@@ -0,0 +1,1758 @@
+/* apps/req.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code */
+#ifdef OPENSSL_NO_DEPRECATED
+#undef OPENSSL_NO_DEPRECATED
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#ifdef OPENSSL_NO_STDIO
+#define APPS_WIN16
+#endif
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/conf.h>
+#include <openssl/err.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+
+#define SECTION		"req"
+
+#define BITS		"default_bits"
+#define KEYFILE		"default_keyfile"
+#define PROMPT		"prompt"
+#define DISTINGUISHED_NAME	"distinguished_name"
+#define ATTRIBUTES	"attributes"
+#define V3_EXTENSIONS	"x509_extensions"
+#define REQ_EXTENSIONS	"req_extensions"
+#define STRING_MASK	"string_mask"
+#define UTF8_IN		"utf8"
+
+#define DEFAULT_KEY_LENGTH	512
+#define MIN_KEY_LENGTH		384
+
+#undef PROG
+#define PROG	req_main
+
+/* -inform arg	- input format - default PEM (DER or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg	- input file - default stdin
+ * -out arg	- output file - default stdout
+ * -verify	- check request signature
+ * -noout	- don't print stuff out.
+ * -text	- print out human readable text.
+ * -nodes	- no des encryption
+ * -config file	- Load configuration file.
+ * -key file	- make a request using key in file (or use it for verification).
+ * -keyform arg	- key file format.
+ * -rand file(s) - load the file(s) into the PRNG.
+ * -newkey	- make a key and a request.
+ * -modulus	- print RSA modulus.
+ * -pubkey	- output Public Key.
+ * -x509	- output a self signed X509 structure instead.
+ * -asn1-kludge	- output new certificate request in a format that some CA's
+ *		  require.  This format is wrong
+ */
+
+static int make_REQ(X509_REQ *req,EVP_PKEY *pkey,char *dn,int mutlirdn,
+		int attribs,unsigned long chtype);
+static int build_subject(X509_REQ *req, char *subj, unsigned long chtype,
+		int multirdn);
+static int prompt_info(X509_REQ *req,
+		STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
+		STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs,
+		unsigned long chtype);
+static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *sk,
+				STACK_OF(CONF_VALUE) *attr, int attribs,
+				unsigned long chtype);
+static int add_attribute_object(X509_REQ *req, char *text, const char *def,
+				char *value, int nid, int n_min,
+				int n_max, unsigned long chtype);
+static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value,
+	int nid,int n_min,int n_max, unsigned long chtype, int mval);
+static int genpkey_cb(EVP_PKEY_CTX *ctx);
+static int req_check_len(int len,int n_min,int n_max);
+static int check_end(const char *str, const char *end);
+static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, int *pkey_type,
+					long *pkeylen, char **palgnam,
+					ENGINE *keygen_engine);
+#ifndef MONOLITH
+static char *default_config_file=NULL;
+#endif
+static CONF *req_conf=NULL;
+static int batch=0;
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	ENGINE *e = NULL, *gen_eng = NULL;
+	unsigned long nmflag = 0, reqflag = 0;
+	int ex=1,x509=0,days=30;
+	X509 *x509ss=NULL;
+	X509_REQ *req=NULL;
+	EVP_PKEY_CTX *genctx = NULL;
+	const char *keyalg = NULL;
+	char *keyalgstr = NULL;
+	STACK_OF(OPENSSL_STRING) *pkeyopts = NULL;
+	EVP_PKEY *pkey=NULL;
+	int i=0,badops=0,newreq=0,verbose=0,pkey_type=-1;
+	long newkey = -1;
+	BIO *in=NULL,*out=NULL;
+	int informat,outformat,verify=0,noout=0,text=0,keyform=FORMAT_PEM;
+	int nodes=0,kludge=0,newhdr=0,subject=0,pubkey=0;
+	char *infile,*outfile,*prog,*keyfile=NULL,*template=NULL,*keyout=NULL;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+	char *extensions = NULL;
+	char *req_exts = NULL;
+	const EVP_CIPHER *cipher=NULL;
+	ASN1_INTEGER *serial = NULL;
+	int modulus=0;
+	char *inrand=NULL;
+	char *passargin = NULL, *passargout = NULL;
+	char *passin = NULL, *passout = NULL;
+	char *p;
+	char *subj = NULL;
+	int multirdn = 0;
+	const EVP_MD *md_alg=NULL,*digest=NULL;
+	unsigned long chtype = MBSTRING_ASC;
+#ifndef MONOLITH
+	char *to_free;
+	long errline;
+#endif
+
+	req_conf = NULL;
+#ifndef OPENSSL_NO_DES
+	cipher=EVP_des_ede3_cbc();
+#endif
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	infile=NULL;
+	outfile=NULL;
+	informat=FORMAT_PEM;
+	outformat=FORMAT_PEM;
+
+	prog=argv[0];
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if 	(strcmp(*argv,"-inform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			informat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-outform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outformat=str2fmt(*(++argv));
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*argv,"-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine= *(++argv);
+			}
+		else if (strcmp(*argv,"-keygen_engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			gen_eng = ENGINE_by_id(*(++argv));
+			if (gen_eng == NULL)
+				{
+				BIO_printf(bio_err, "Can't find keygen engine %s\n", *argv);
+				goto end;
+				}
+			}
+#endif
+		else if (strcmp(*argv,"-key") == 0)
+			{
+			if (--argc < 1) goto bad;
+			keyfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-pubkey") == 0)
+			{
+			pubkey=1;
+			}
+		else if (strcmp(*argv,"-new") == 0)
+			{
+			newreq=1;
+			}
+		else if (strcmp(*argv,"-config") == 0)
+			{	
+			if (--argc < 1) goto bad;
+			template= *(++argv);
+			}
+		else if (strcmp(*argv,"-keyform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			keyform=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-keyout") == 0)
+			{
+			if (--argc < 1) goto bad;
+			keyout= *(++argv);
+			}
+		else if (strcmp(*argv,"-passin") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passargin= *(++argv);
+			}
+		else if (strcmp(*argv,"-passout") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passargout= *(++argv);
+			}
+		else if (strcmp(*argv,"-rand") == 0)
+			{
+			if (--argc < 1) goto bad;
+			inrand= *(++argv);
+			}
+		else if (strcmp(*argv,"-newkey") == 0)
+			{
+			if (--argc < 1)
+				goto bad;
+			keyalg = *(++argv);
+			newreq=1;
+			}
+		else if (strcmp(*argv,"-pkeyopt") == 0)
+			{
+			if (--argc < 1)
+				goto bad;
+			if (!pkeyopts)
+				pkeyopts = sk_OPENSSL_STRING_new_null();
+			if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, *(++argv)))
+				goto bad;
+			}
+		else if (strcmp(*argv,"-batch") == 0)
+			batch=1;
+		else if (strcmp(*argv,"-newhdr") == 0)
+			newhdr=1;
+		else if (strcmp(*argv,"-modulus") == 0)
+			modulus=1;
+		else if (strcmp(*argv,"-verify") == 0)
+			verify=1;
+		else if (strcmp(*argv,"-nodes") == 0)
+			nodes=1;
+		else if (strcmp(*argv,"-noout") == 0)
+			noout=1;
+		else if (strcmp(*argv,"-verbose") == 0)
+			verbose=1;
+		else if (strcmp(*argv,"-utf8") == 0)
+			chtype = MBSTRING_UTF8;
+		else if (strcmp(*argv,"-nameopt") == 0)
+			{
+			if (--argc < 1) goto bad;
+			if (!set_name_ex(&nmflag, *(++argv))) goto bad;
+			}
+		else if (strcmp(*argv,"-reqopt") == 0)
+			{
+			if (--argc < 1) goto bad;
+			if (!set_cert_ex(&reqflag, *(++argv))) goto bad;
+			}
+		else if (strcmp(*argv,"-subject") == 0)
+			subject=1;
+		else if (strcmp(*argv,"-text") == 0)
+			text=1;
+		else if (strcmp(*argv,"-x509") == 0)
+			x509=1;
+		else if (strcmp(*argv,"-asn1-kludge") == 0)
+			kludge=1;
+		else if (strcmp(*argv,"-no-asn1-kludge") == 0)
+			kludge=0;
+		else if (strcmp(*argv,"-subj") == 0)
+			{
+			if (--argc < 1) goto bad;
+			subj= *(++argv);
+			}
+		else if (strcmp(*argv,"-multivalue-rdn") == 0)
+			multirdn=1;
+		else if (strcmp(*argv,"-days") == 0)
+			{
+			if (--argc < 1) goto bad;
+			days= atoi(*(++argv));
+			if (days == 0) days=30;
+			}
+		else if (strcmp(*argv,"-set_serial") == 0)
+			{
+			if (--argc < 1) goto bad;
+			serial = s2i_ASN1_INTEGER(NULL, *(++argv));
+			if (!serial) goto bad;
+			}
+		else if (strcmp(*argv,"-extensions") == 0)
+			{
+			if (--argc < 1) goto bad;
+			extensions = *(++argv);
+			}
+		else if (strcmp(*argv,"-reqexts") == 0)
+			{
+			if (--argc < 1) goto bad;
+			req_exts = *(++argv);
+			}
+		else if ((md_alg=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
+			{
+			/* ok */
+			digest=md_alg;
+			}
+		else
+			{
+			BIO_printf(bio_err,"unknown option %s\n",*argv);
+			badops=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (badops)
+		{
+bad:
+		BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
+		BIO_printf(bio_err,"where options  are\n");
+		BIO_printf(bio_err," -inform arg    input format - DER or PEM\n");
+		BIO_printf(bio_err," -outform arg   output format - DER or PEM\n");
+		BIO_printf(bio_err," -in arg        input file\n");
+		BIO_printf(bio_err," -out arg       output file\n");
+		BIO_printf(bio_err," -text          text form of request\n");
+		BIO_printf(bio_err," -pubkey        output public key\n");
+		BIO_printf(bio_err," -noout         do not output REQ\n");
+		BIO_printf(bio_err," -verify        verify signature on REQ\n");
+		BIO_printf(bio_err," -modulus       RSA modulus\n");
+		BIO_printf(bio_err," -nodes         don't encrypt the output key\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err," -engine e      use engine e, possibly a hardware device\n");
+#endif
+		BIO_printf(bio_err," -subject       output the request's subject\n");
+		BIO_printf(bio_err," -passin        private key password source\n");
+		BIO_printf(bio_err," -key file      use the private key contained in file\n");
+		BIO_printf(bio_err," -keyform arg   key file format\n");
+		BIO_printf(bio_err," -keyout arg    file to send the key to\n");
+		BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+		BIO_printf(bio_err,"                load the file (or the files in the directory) into\n");
+		BIO_printf(bio_err,"                the random number generator\n");
+		BIO_printf(bio_err," -newkey rsa:bits generate a new RSA key of 'bits' in size\n");
+		BIO_printf(bio_err," -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'\n");
+#ifndef OPENSSL_NO_ECDSA
+		BIO_printf(bio_err," -newkey ec:file generate a new EC key, parameters taken from CA in 'file'\n");
+#endif
+		BIO_printf(bio_err," -[digest]      Digest to sign with (md5, sha1, md2, mdc2, md4)\n");
+		BIO_printf(bio_err," -config file   request template file.\n");
+		BIO_printf(bio_err," -subj arg      set or modify request subject\n");
+		BIO_printf(bio_err," -multivalue-rdn enable support for multivalued RDNs\n");
+		BIO_printf(bio_err," -new           new request.\n");
+		BIO_printf(bio_err," -batch         do not ask anything during request generation\n");
+		BIO_printf(bio_err," -x509          output a x509 structure instead of a cert. req.\n");
+		BIO_printf(bio_err," -days          number of days a certificate generated by -x509 is valid for.\n");
+		BIO_printf(bio_err," -set_serial    serial number to use for a certificate generated by -x509.\n");
+		BIO_printf(bio_err," -newhdr        output \"NEW\" in the header lines\n");
+		BIO_printf(bio_err," -asn1-kludge   Output the 'request' in a format that is wrong but some CA's\n");
+		BIO_printf(bio_err,"                have been reported as requiring\n");
+		BIO_printf(bio_err," -extensions .. specify certificate extension section (override value in config file)\n");
+		BIO_printf(bio_err," -reqexts ..    specify request extension section (override value in config file)\n");
+		BIO_printf(bio_err," -utf8          input characters are UTF8 (default ASCII)\n");
+		BIO_printf(bio_err," -nameopt arg    - various certificate name options\n");
+		BIO_printf(bio_err," -reqopt arg    - various request text options\n\n");
+		goto end;
+		}
+
+	ERR_load_crypto_strings();
+	if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
+		BIO_printf(bio_err, "Error getting passwords\n");
+		goto end;
+	}
+
+#ifndef MONOLITH /* else this has happened in openssl.c (global `config') */
+	/* Lets load up our environment a little */
+	p=getenv("OPENSSL_CONF");
+	if (p == NULL)
+		p=getenv("SSLEAY_CONF");
+	if (p == NULL)
+		p=to_free=make_config_name();
+	default_config_file=p;
+	config=NCONF_new(NULL);
+	i=NCONF_load(config, p, &errline);
+#endif
+
+	if (template != NULL)
+		{
+		long errline = -1;
+
+		if( verbose )
+			BIO_printf(bio_err,"Using configuration from %s\n",template);
+		req_conf=NCONF_new(NULL);
+		i=NCONF_load(req_conf,template,&errline);
+		if (i == 0)
+			{
+			BIO_printf(bio_err,"error on line %ld of %s\n",errline,template);
+			goto end;
+			}
+		}
+	else
+		{
+		req_conf=config;
+
+		if (req_conf == NULL)
+			{
+			BIO_printf(bio_err,"Unable to load config info from %s\n", default_config_file);
+			if (newreq)
+				goto end;
+			}
+		else if( verbose )
+			BIO_printf(bio_err,"Using configuration from %s\n",
+			default_config_file);
+		}
+
+	if (req_conf != NULL)
+		{
+		if (!load_config(bio_err, req_conf))
+			goto end;
+		p=NCONF_get_string(req_conf,NULL,"oid_file");
+		if (p == NULL)
+			ERR_clear_error();
+		if (p != NULL)
+			{
+			BIO *oid_bio;
+
+			oid_bio=BIO_new_file(p,"r");
+			if (oid_bio == NULL) 
+				{
+				/*
+				BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
+				ERR_print_errors(bio_err);
+				*/
+				}
+			else
+				{
+				OBJ_create_objects(oid_bio);
+				BIO_free(oid_bio);
+				}
+			}
+		}
+	if(!add_oid_section(bio_err, req_conf)) goto end;
+
+	if (md_alg == NULL)
+		{
+		p=NCONF_get_string(req_conf,SECTION,"default_md");
+		if (p == NULL)
+			ERR_clear_error();
+		if (p != NULL)
+			{
+			if ((md_alg=EVP_get_digestbyname(p)) != NULL)
+				digest=md_alg;
+			}
+		}
+
+	if (!extensions)
+		{
+		extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS);
+		if (!extensions)
+			ERR_clear_error();
+		}
+	if (extensions) {
+		/* Check syntax of file */
+		X509V3_CTX ctx;
+		X509V3_set_ctx_test(&ctx);
+		X509V3_set_nconf(&ctx, req_conf);
+		if(!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) {
+			BIO_printf(bio_err,
+			 "Error Loading extension section %s\n", extensions);
+			goto end;
+		}
+	}
+
+	if(!passin)
+		{
+		passin = NCONF_get_string(req_conf, SECTION, "input_password");
+		if (!passin)
+			ERR_clear_error();
+		}
+	
+	if(!passout)
+		{
+		passout = NCONF_get_string(req_conf, SECTION, "output_password");
+		if (!passout)
+			ERR_clear_error();
+		}
+
+	p = NCONF_get_string(req_conf, SECTION, STRING_MASK);
+	if (!p)
+		ERR_clear_error();
+
+	if(p && !ASN1_STRING_set_default_mask_asc(p)) {
+		BIO_printf(bio_err, "Invalid global string mask setting %s\n", p);
+		goto end;
+	}
+
+	if (chtype != MBSTRING_UTF8)
+		{
+		p = NCONF_get_string(req_conf, SECTION, UTF8_IN);
+		if (!p)
+			ERR_clear_error();
+		else if (!strcmp(p, "yes"))
+			chtype = MBSTRING_UTF8;
+		}
+
+
+	if(!req_exts)
+		{
+		req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS);
+		if (!req_exts)
+			ERR_clear_error();
+		}
+	if(req_exts) {
+		/* Check syntax of file */
+		X509V3_CTX ctx;
+		X509V3_set_ctx_test(&ctx);
+		X509V3_set_nconf(&ctx, req_conf);
+		if(!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) {
+			BIO_printf(bio_err,
+			 "Error Loading request extension section %s\n",
+								req_exts);
+			goto end;
+		}
+	}
+
+	in=BIO_new(BIO_s_file());
+	out=BIO_new(BIO_s_file());
+	if ((in == NULL) || (out == NULL))
+		goto end;
+
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine, 0);
+#endif
+
+	if (keyfile != NULL)
+		{
+		pkey = load_key(bio_err, keyfile, keyform, 0, passin, e,
+			"Private Key");
+		if (!pkey)
+			{
+			/* load_key() has already printed an appropriate
+			   message */
+			goto end;
+			}
+		else
+			{
+			char *randfile = NCONF_get_string(req_conf,SECTION,"RANDFILE");
+			if (randfile == NULL)
+				ERR_clear_error();
+			app_RAND_load_file(randfile, bio_err, 0);
+			}
+		}
+
+	if (newreq && (pkey == NULL))
+		{
+		char *randfile = NCONF_get_string(req_conf,SECTION,"RANDFILE");
+		if (randfile == NULL)
+			ERR_clear_error();
+		app_RAND_load_file(randfile, bio_err, 0);
+		if (inrand)
+			app_RAND_load_files(inrand);
+
+		if (keyalg)
+			{
+			genctx = set_keygen_ctx(bio_err, keyalg, &pkey_type, &newkey,
+							&keyalgstr, gen_eng);
+			if (!genctx)
+				goto end;
+			}
+	
+		if (newkey <= 0)
+			{
+			if (!NCONF_get_number(req_conf,SECTION,BITS, &newkey))
+				newkey=DEFAULT_KEY_LENGTH;
+			}
+
+		if (newkey < MIN_KEY_LENGTH && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA))
+			{
+			BIO_printf(bio_err,"private key length is too short,\n");
+			BIO_printf(bio_err,"it needs to be at least %d bits, not %ld\n",MIN_KEY_LENGTH,newkey);
+			goto end;
+			}
+
+		if (!genctx)
+			{
+			genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &newkey,
+							&keyalgstr, gen_eng);
+			if (!genctx)
+				goto end;
+			}
+
+		if (pkeyopts)
+			{
+			char *genopt;
+			for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++)
+				{
+				genopt = sk_OPENSSL_STRING_value(pkeyopts, i);
+				if (pkey_ctrl_string(genctx, genopt) <= 0)
+					{
+					BIO_printf(bio_err,
+						"parameter error \"%s\"\n",
+						genopt);
+					ERR_print_errors(bio_err);
+					goto end;
+					}
+				}
+			}
+
+		BIO_printf(bio_err,"Generating a %ld bit %s private key\n",
+				newkey, keyalgstr);
+
+		EVP_PKEY_CTX_set_cb(genctx, genpkey_cb);
+		EVP_PKEY_CTX_set_app_data(genctx, bio_err);
+
+		if (EVP_PKEY_keygen(genctx, &pkey) <= 0)
+			{
+			BIO_puts(bio_err, "Error Generating Key\n");
+			goto end;
+			}
+
+		EVP_PKEY_CTX_free(genctx);
+		genctx = NULL;
+
+		app_RAND_write_file(randfile, bio_err);
+
+		if (keyout == NULL)
+			{
+			keyout=NCONF_get_string(req_conf,SECTION,KEYFILE);
+			if (keyout == NULL)
+				ERR_clear_error();
+			}
+		
+		if (keyout == NULL)
+			{
+			BIO_printf(bio_err,"writing new private key to stdout\n");
+			BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+			{
+			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+			out = BIO_push(tmpbio, out);
+			}
+#endif
+			}
+		else
+			{
+			BIO_printf(bio_err,"writing new private key to '%s'\n",keyout);
+			if (BIO_write_filename(out,keyout) <= 0)
+				{
+				perror(keyout);
+				goto end;
+				}
+			}
+
+		p=NCONF_get_string(req_conf,SECTION,"encrypt_rsa_key");
+		if (p == NULL)
+			{
+			ERR_clear_error();
+			p=NCONF_get_string(req_conf,SECTION,"encrypt_key");
+			if (p == NULL)
+				ERR_clear_error();
+			}
+		if ((p != NULL) && (strcmp(p,"no") == 0))
+			cipher=NULL;
+		if (nodes) cipher=NULL;
+		
+		i=0;
+loop:
+		if (!PEM_write_bio_PrivateKey(out,pkey,cipher,
+			NULL,0,NULL,passout))
+			{
+			if ((ERR_GET_REASON(ERR_peek_error()) ==
+				PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3))
+				{
+				ERR_clear_error();
+				i++;
+				goto loop;
+				}
+			goto end;
+			}
+		BIO_printf(bio_err,"-----\n");
+		}
+
+	if (!newreq)
+		{
+		/* Since we are using a pre-existing certificate
+		 * request, the kludge 'format' info should not be
+		 * changed. */
+		kludge= -1;
+		if (infile == NULL)
+			BIO_set_fp(in,stdin,BIO_NOCLOSE);
+		else
+			{
+			if (BIO_read_filename(in,infile) <= 0)
+				{
+				perror(infile);
+				goto end;
+				}
+			}
+
+		if	(informat == FORMAT_ASN1)
+			req=d2i_X509_REQ_bio(in,NULL);
+		else if (informat == FORMAT_PEM)
+			req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL);
+		else
+			{
+			BIO_printf(bio_err,"bad input format specified for X509 request\n");
+			goto end;
+			}
+		if (req == NULL)
+			{
+			BIO_printf(bio_err,"unable to load X509 request\n");
+			goto end;
+			}
+		}
+
+	if (newreq || x509)
+		{
+		if (pkey == NULL)
+			{
+			BIO_printf(bio_err,"you need to specify a private key\n");
+			goto end;
+			}
+
+		if (req == NULL)
+			{
+			req=X509_REQ_new();
+			if (req == NULL)
+				{
+				goto end;
+				}
+
+			i=make_REQ(req,pkey,subj,multirdn,!x509, chtype);
+			subj=NULL; /* done processing '-subj' option */
+			if ((kludge > 0) && !sk_X509_ATTRIBUTE_num(req->req_info->attributes))
+				{
+				sk_X509_ATTRIBUTE_free(req->req_info->attributes);
+				req->req_info->attributes = NULL;
+				}
+			if (!i)
+				{
+				BIO_printf(bio_err,"problems making Certificate Request\n");
+				goto end;
+				}
+			}
+		if (x509)
+			{
+			EVP_PKEY *tmppkey;
+			X509V3_CTX ext_ctx;
+			if ((x509ss=X509_new()) == NULL) goto end;
+
+			/* Set version to V3 */
+			if(extensions && !X509_set_version(x509ss, 2)) goto end;
+			if (serial)
+				{
+				if (!X509_set_serialNumber(x509ss, serial)) goto end;
+				}
+			else
+				{
+				if (!rand_serial(NULL,
+					X509_get_serialNumber(x509ss)))
+						goto end;
+				}
+
+			if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req))) goto end;
+			if (!X509_gmtime_adj(X509_get_notBefore(x509ss),0)) goto end;
+			if (!X509_time_adj_ex(X509_get_notAfter(x509ss), days, 0, NULL)) goto end;
+			if (!X509_set_subject_name(x509ss, X509_REQ_get_subject_name(req))) goto end;
+			tmppkey = X509_REQ_get_pubkey(req);
+			if (!tmppkey || !X509_set_pubkey(x509ss,tmppkey)) goto end;
+			EVP_PKEY_free(tmppkey);
+
+			/* Set up V3 context struct */
+
+			X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0);
+			X509V3_set_nconf(&ext_ctx, req_conf);
+
+			/* Add extensions */
+			if(extensions && !X509V3_EXT_add_nconf(req_conf, 
+				 	&ext_ctx, extensions, x509ss))
+				{
+				BIO_printf(bio_err,
+					"Error Loading extension section %s\n",
+					extensions);
+				goto end;
+				}
+			
+			if (!(i=X509_sign(x509ss,pkey,digest)))
+				{
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+			}
+		else
+			{
+			X509V3_CTX ext_ctx;
+
+			/* Set up V3 context struct */
+
+			X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0);
+			X509V3_set_nconf(&ext_ctx, req_conf);
+
+			/* Add extensions */
+			if(req_exts && !X509V3_EXT_REQ_add_nconf(req_conf, 
+				 	&ext_ctx, req_exts, req))
+				{
+				BIO_printf(bio_err,
+					"Error Loading extension section %s\n",
+					req_exts);
+				goto end;
+				}
+			if (!(i=X509_REQ_sign(req,pkey,digest)))
+				{
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+			}
+		}
+
+	if (subj && x509)
+		{
+		BIO_printf(bio_err, "Cannot modifiy certificate subject\n");
+		goto end;
+		}
+
+	if (subj && !x509)
+		{
+		if (verbose)
+			{
+			BIO_printf(bio_err, "Modifying Request's Subject\n");
+			print_name(bio_err, "old subject=", X509_REQ_get_subject_name(req), nmflag);
+			}
+
+		if (build_subject(req, subj, chtype, multirdn) == 0)
+			{
+			BIO_printf(bio_err, "ERROR: cannot modify subject\n");
+			ex=1;
+			goto end;
+			}
+
+		req->req_info->enc.modified = 1;
+
+		if (verbose)
+			{
+			print_name(bio_err, "new subject=", X509_REQ_get_subject_name(req), nmflag);
+			}
+		}
+
+	if (verify && !x509)
+		{
+		int tmp=0;
+
+		if (pkey == NULL)
+			{
+			pkey=X509_REQ_get_pubkey(req);
+			tmp=1;
+			if (pkey == NULL) goto end;
+			}
+
+		i=X509_REQ_verify(req,pkey);
+		if (tmp) {
+			EVP_PKEY_free(pkey);
+			pkey=NULL;
+		}
+
+		if (i < 0)
+			{
+			goto end;
+			}
+		else if (i == 0)
+			{
+			BIO_printf(bio_err,"verify failure\n");
+			ERR_print_errors(bio_err);
+			}
+		else /* if (i > 0) */
+			BIO_printf(bio_err,"verify OK\n");
+		}
+
+	if (noout && !text && !modulus && !subject && !pubkey)
+		{
+		ex=0;
+		goto end;
+		}
+
+	if (outfile == NULL)
+		{
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+		}
+	else
+		{
+		if ((keyout != NULL) && (strcmp(outfile,keyout) == 0))
+			i=(int)BIO_append_filename(out,outfile);
+		else
+			i=(int)BIO_write_filename(out,outfile);
+		if (!i)
+			{
+			perror(outfile);
+			goto end;
+			}
+		}
+
+	if (pubkey)
+		{
+		EVP_PKEY *tpubkey; 
+		tpubkey=X509_REQ_get_pubkey(req);
+		if (tpubkey == NULL)
+			{
+			BIO_printf(bio_err,"Error getting public key\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		PEM_write_bio_PUBKEY(out, tpubkey);
+		EVP_PKEY_free(tpubkey);
+		}
+
+	if (text)
+		{
+		if (x509)
+			X509_print_ex(out, x509ss, nmflag, reqflag);
+		else	
+			X509_REQ_print_ex(out, req, nmflag, reqflag);
+		}
+
+	if(subject) 
+		{
+		if(x509)
+			print_name(out, "subject=", X509_get_subject_name(x509ss), nmflag);
+		else
+			print_name(out, "subject=", X509_REQ_get_subject_name(req), nmflag);
+		}
+
+	if (modulus)
+		{
+		EVP_PKEY *tpubkey;
+
+		if (x509)
+			tpubkey=X509_get_pubkey(x509ss);
+		else
+			tpubkey=X509_REQ_get_pubkey(req);
+		if (tpubkey == NULL)
+			{
+			fprintf(stdout,"Modulus=unavailable\n");
+			goto end; 
+			}
+		fprintf(stdout,"Modulus=");
+#ifndef OPENSSL_NO_RSA
+		if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA)
+			BN_print(out,tpubkey->pkey.rsa->n);
+		else
+#endif
+			fprintf(stdout,"Wrong Algorithm type");
+		EVP_PKEY_free(tpubkey);
+		fprintf(stdout,"\n");
+		}
+
+	if (!noout && !x509)
+		{
+		if 	(outformat == FORMAT_ASN1)
+			i=i2d_X509_REQ_bio(out,req);
+		else if (outformat == FORMAT_PEM) {
+			if(newhdr) i=PEM_write_bio_X509_REQ_NEW(out,req);
+			else i=PEM_write_bio_X509_REQ(out,req);
+		} else {
+			BIO_printf(bio_err,"bad output format specified for outfile\n");
+			goto end;
+			}
+		if (!i)
+			{
+			BIO_printf(bio_err,"unable to write X509 request\n");
+			goto end;
+			}
+		}
+	if (!noout && x509 && (x509ss != NULL))
+		{
+		if 	(outformat == FORMAT_ASN1)
+			i=i2d_X509_bio(out,x509ss);
+		else if (outformat == FORMAT_PEM)
+			i=PEM_write_bio_X509(out,x509ss);
+		else	{
+			BIO_printf(bio_err,"bad output format specified for outfile\n");
+			goto end;
+			}
+		if (!i)
+			{
+			BIO_printf(bio_err,"unable to write X509 certificate\n");
+			goto end;
+			}
+		}
+	ex=0;
+end:
+#ifndef MONOLITH
+	if(to_free)
+		OPENSSL_free(to_free);
+#endif
+	if (ex)
+		{
+		ERR_print_errors(bio_err);
+		}
+	if ((req_conf != NULL) && (req_conf != config)) NCONF_free(req_conf);
+	BIO_free(in);
+	BIO_free_all(out);
+	EVP_PKEY_free(pkey);
+	if (genctx)
+		EVP_PKEY_CTX_free(genctx);
+	if (pkeyopts)
+		sk_OPENSSL_STRING_free(pkeyopts);
+#ifndef OPENSSL_NO_ENGINE
+	if (gen_eng)
+		ENGINE_free(gen_eng);
+#endif
+	if (keyalgstr)
+		OPENSSL_free(keyalgstr);
+	X509_REQ_free(req);
+	X509_free(x509ss);
+	ASN1_INTEGER_free(serial);
+	if(passargin && passin) OPENSSL_free(passin);
+	if(passargout && passout) OPENSSL_free(passout);
+	OBJ_cleanup();
+	apps_shutdown();
+	OPENSSL_EXIT(ex);
+	}
+
+static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn,
+			int attribs, unsigned long chtype)
+	{
+	int ret=0,i;
+	char no_prompt = 0;
+	STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL;
+	char *tmp, *dn_sect,*attr_sect;
+
+	tmp=NCONF_get_string(req_conf,SECTION,PROMPT);
+	if (tmp == NULL)
+		ERR_clear_error();
+	if((tmp != NULL) && !strcmp(tmp, "no")) no_prompt = 1;
+
+	dn_sect=NCONF_get_string(req_conf,SECTION,DISTINGUISHED_NAME);
+	if (dn_sect == NULL)
+		{
+		BIO_printf(bio_err,"unable to find '%s' in config\n",
+			DISTINGUISHED_NAME);
+		goto err;
+		}
+	dn_sk=NCONF_get_section(req_conf,dn_sect);
+	if (dn_sk == NULL)
+		{
+		BIO_printf(bio_err,"unable to get '%s' section\n",dn_sect);
+		goto err;
+		}
+
+	attr_sect=NCONF_get_string(req_conf,SECTION,ATTRIBUTES);
+	if (attr_sect == NULL)
+		{
+		ERR_clear_error();		
+		attr_sk=NULL;
+		}
+	else
+		{
+		attr_sk=NCONF_get_section(req_conf,attr_sect);
+		if (attr_sk == NULL)
+			{
+			BIO_printf(bio_err,"unable to get '%s' section\n",attr_sect);
+			goto err;
+			}
+		}
+
+	/* setup version number */
+	if (!X509_REQ_set_version(req,0L)) goto err; /* version 1 */
+
+	if (no_prompt) 
+		i = auto_info(req, dn_sk, attr_sk, attribs, chtype);
+	else 
+		{
+		if (subj)
+			i = build_subject(req, subj, chtype, multirdn);
+		else
+			i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, chtype);
+		}
+	if(!i) goto err;
+
+	if (!X509_REQ_set_pubkey(req,pkey)) goto err;
+
+	ret=1;
+err:
+	return(ret);
+	}
+
+/*
+ * subject is expected to be in the format /type0=value0/type1=value1/type2=...
+ * where characters may be escaped by \
+ */
+static int build_subject(X509_REQ *req, char *subject, unsigned long chtype, int multirdn)
+	{
+	X509_NAME *n;
+
+	if (!(n = parse_name(subject, chtype, multirdn)))
+		return 0;
+
+	if (!X509_REQ_set_subject_name(req, n))
+		{
+		X509_NAME_free(n);
+		return 0;
+		}
+	X509_NAME_free(n);
+	return 1;
+}
+
+
+static int prompt_info(X509_REQ *req,
+		STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
+		STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs,
+		unsigned long chtype)
+	{
+	int i;
+	char *p,*q;
+	char buf[100];
+	int nid, mval;
+	long n_min,n_max;
+	char *type, *value;
+	const char *def;
+	CONF_VALUE *v;
+	X509_NAME *subj;
+	subj = X509_REQ_get_subject_name(req);
+
+	if(!batch)
+		{
+		BIO_printf(bio_err,"You are about to be asked to enter information that will be incorporated\n");
+		BIO_printf(bio_err,"into your certificate request.\n");
+		BIO_printf(bio_err,"What you are about to enter is what is called a Distinguished Name or a DN.\n");
+		BIO_printf(bio_err,"There are quite a few fields but you can leave some blank\n");
+		BIO_printf(bio_err,"For some fields there will be a default value,\n");
+		BIO_printf(bio_err,"If you enter '.', the field will be left blank.\n");
+		BIO_printf(bio_err,"-----\n");
+		}
+
+
+	if (sk_CONF_VALUE_num(dn_sk))
+		{
+		i= -1;
+start:		for (;;)
+			{
+			i++;
+			if (sk_CONF_VALUE_num(dn_sk) <= i) break;
+
+			v=sk_CONF_VALUE_value(dn_sk,i);
+			p=q=NULL;
+			type=v->name;
+			if(!check_end(type,"_min") || !check_end(type,"_max") ||
+				!check_end(type,"_default") ||
+					 !check_end(type,"_value")) continue;
+			/* Skip past any leading X. X: X, etc to allow for
+			 * multiple instances 
+			 */
+			for(p = v->name; *p ; p++) 
+				if ((*p == ':') || (*p == ',') ||
+							 (*p == '.')) {
+					p++;
+					if(*p) type = p;
+					break;
+				}
+			if (*type == '+')
+				{
+				mval = -1;
+				type++;
+				}
+			else
+				mval = 0;
+			/* If OBJ not recognised ignore it */
+			if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start;
+			if (BIO_snprintf(buf,sizeof buf,"%s_default",v->name)
+				>= (int)sizeof(buf))
+			   {
+			   BIO_printf(bio_err,"Name '%s' too long\n",v->name);
+			   return 0;
+			   }
+
+			if ((def=NCONF_get_string(req_conf,dn_sect,buf)) == NULL)
+				{
+				ERR_clear_error();
+				def="";
+				}
+				
+			BIO_snprintf(buf,sizeof buf,"%s_value",v->name);
+			if ((value=NCONF_get_string(req_conf,dn_sect,buf)) == NULL)
+				{
+				ERR_clear_error();
+				value=NULL;
+				}
+
+			BIO_snprintf(buf,sizeof buf,"%s_min",v->name);
+			if (!NCONF_get_number(req_conf,dn_sect,buf, &n_min))
+				{
+				ERR_clear_error();
+				n_min = -1;
+				}
+
+			BIO_snprintf(buf,sizeof buf,"%s_max",v->name);
+			if (!NCONF_get_number(req_conf,dn_sect,buf, &n_max))
+				{
+				ERR_clear_error();
+				n_max = -1;
+				}
+
+			if (!add_DN_object(subj,v->value,def,value,nid,
+				n_min,n_max, chtype, mval))
+				return 0;
+			}
+		if (X509_NAME_entry_count(subj) == 0)
+			{
+			BIO_printf(bio_err,"error, no objects specified in config file\n");
+			return 0;
+			}
+
+		if (attribs)
+			{
+			if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) && (!batch))
+				{
+				BIO_printf(bio_err,"\nPlease enter the following 'extra' attributes\n");
+				BIO_printf(bio_err,"to be sent with your certificate request\n");
+				}
+
+			i= -1;
+start2:			for (;;)
+				{
+				i++;
+				if ((attr_sk == NULL) ||
+					    (sk_CONF_VALUE_num(attr_sk) <= i))
+					break;
+
+				v=sk_CONF_VALUE_value(attr_sk,i);
+				type=v->name;
+				if ((nid=OBJ_txt2nid(type)) == NID_undef)
+					goto start2;
+
+				if (BIO_snprintf(buf,sizeof buf,"%s_default",type)
+					>= (int)sizeof(buf))
+				   {
+				   BIO_printf(bio_err,"Name '%s' too long\n",v->name);
+				   return 0;
+				   }
+
+				if ((def=NCONF_get_string(req_conf,attr_sect,buf))
+					== NULL)
+					{
+					ERR_clear_error();
+					def="";
+					}
+				
+				
+				BIO_snprintf(buf,sizeof buf,"%s_value",type);
+				if ((value=NCONF_get_string(req_conf,attr_sect,buf))
+					== NULL)
+					{
+					ERR_clear_error();
+					value=NULL;
+					}
+
+				BIO_snprintf(buf,sizeof buf,"%s_min",type);
+				if (!NCONF_get_number(req_conf,attr_sect,buf, &n_min))
+					{
+					ERR_clear_error();
+					n_min = -1;
+					}
+
+				BIO_snprintf(buf,sizeof buf,"%s_max",type);
+				if (!NCONF_get_number(req_conf,attr_sect,buf, &n_max))
+					{
+					ERR_clear_error();
+					n_max = -1;
+					}
+
+				if (!add_attribute_object(req,
+					v->value,def,value,nid,n_min,n_max, chtype))
+					return 0;
+				}
+			}
+		}
+	else
+		{
+		BIO_printf(bio_err,"No template, please set one up.\n");
+		return 0;
+		}
+
+	return 1;
+
+	}
+
+static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk,
+			STACK_OF(CONF_VALUE) *attr_sk, int attribs, unsigned long chtype)
+	{
+	int i;
+	char *p,*q;
+	char *type;
+	CONF_VALUE *v;
+	X509_NAME *subj;
+
+	subj = X509_REQ_get_subject_name(req);
+
+	for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++)
+		{
+		int mval;
+		v=sk_CONF_VALUE_value(dn_sk,i);
+		p=q=NULL;
+		type=v->name;
+		/* Skip past any leading X. X: X, etc to allow for
+		 * multiple instances 
+		 */
+		for(p = v->name; *p ; p++) 
+#ifndef CHARSET_EBCDIC
+			if ((*p == ':') || (*p == ',') || (*p == '.')) {
+#else
+			if ((*p == os_toascii[':']) || (*p == os_toascii[',']) || (*p == os_toascii['.'])) {
+#endif
+				p++;
+				if(*p) type = p;
+				break;
+			}
+#ifndef CHARSET_EBCDIC
+		if (*p == '+')
+#else
+		if (*p == os_toascii['+'])
+#endif
+			{
+			p++;
+			mval = -1;
+			}
+		else
+			mval = 0;
+		if (!X509_NAME_add_entry_by_txt(subj,type, chtype,
+				(unsigned char *) v->value,-1,-1,mval)) return 0;
+
+		}
+
+		if (!X509_NAME_entry_count(subj))
+			{
+			BIO_printf(bio_err,"error, no objects specified in config file\n");
+			return 0;
+			}
+		if (attribs)
+			{
+			for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++)
+				{
+				v=sk_CONF_VALUE_value(attr_sk,i);
+				if(!X509_REQ_add1_attr_by_txt(req, v->name, chtype,
+					(unsigned char *)v->value, -1)) return 0;
+				}
+			}
+	return 1;
+	}
+
+
+static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value,
+	     int nid, int n_min, int n_max, unsigned long chtype, int mval)
+	{
+	int i,ret=0;
+	MS_STATIC char buf[1024];
+start:
+	if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def);
+	(void)BIO_flush(bio_err);
+	if(value != NULL)
+		{
+		BUF_strlcpy(buf,value,sizeof buf);
+		BUF_strlcat(buf,"\n",sizeof buf);
+		BIO_printf(bio_err,"%s\n",value);
+		}
+	else
+		{
+		buf[0]='\0';
+		if (!batch)
+			{
+			if (!fgets(buf,sizeof buf,stdin))
+				return 0;
+			}
+		else
+			{
+			buf[0] = '\n';
+			buf[1] = '\0';
+			}
+		}
+
+	if (buf[0] == '\0') return(0);
+	else if (buf[0] == '\n')
+		{
+		if ((def == NULL) || (def[0] == '\0'))
+			return(1);
+		BUF_strlcpy(buf,def,sizeof buf);
+		BUF_strlcat(buf,"\n",sizeof buf);
+		}
+	else if ((buf[0] == '.') && (buf[1] == '\n')) return(1);
+
+	i=strlen(buf);
+	if (buf[i-1] != '\n')
+		{
+		BIO_printf(bio_err,"weird input :-(\n");
+		return(0);
+		}
+	buf[--i]='\0';
+#ifdef CHARSET_EBCDIC
+	ebcdic2ascii(buf, buf, i);
+#endif
+	if(!req_check_len(i, n_min, n_max)) goto start;
+	if (!X509_NAME_add_entry_by_NID(n,nid, chtype,
+				(unsigned char *) buf, -1,-1,mval)) goto err;
+	ret=1;
+err:
+	return(ret);
+	}
+
+static int add_attribute_object(X509_REQ *req, char *text, const char *def,
+				char *value, int nid, int n_min,
+				int n_max, unsigned long chtype)
+	{
+	int i;
+	static char buf[1024];
+
+start:
+	if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def);
+	(void)BIO_flush(bio_err);
+	if (value != NULL)
+		{
+		BUF_strlcpy(buf,value,sizeof buf);
+		BUF_strlcat(buf,"\n",sizeof buf);
+		BIO_printf(bio_err,"%s\n",value);
+		}
+	else
+		{
+		buf[0]='\0';
+		if (!batch)
+			{
+			if (!fgets(buf,sizeof buf,stdin))
+				return 0;
+			}
+		else
+			{
+			buf[0] = '\n';
+			buf[1] = '\0';
+			}
+		}
+
+	if (buf[0] == '\0') return(0);
+	else if (buf[0] == '\n')
+		{
+		if ((def == NULL) || (def[0] == '\0'))
+			return(1);
+		BUF_strlcpy(buf,def,sizeof buf);
+		BUF_strlcat(buf,"\n",sizeof buf);
+		}
+	else if ((buf[0] == '.') && (buf[1] == '\n')) return(1);
+
+	i=strlen(buf);
+	if (buf[i-1] != '\n')
+		{
+		BIO_printf(bio_err,"weird input :-(\n");
+		return(0);
+		}
+	buf[--i]='\0';
+#ifdef CHARSET_EBCDIC
+	ebcdic2ascii(buf, buf, i);
+#endif
+	if(!req_check_len(i, n_min, n_max)) goto start;
+
+	if(!X509_REQ_add1_attr_by_NID(req, nid, chtype,
+					(unsigned char *)buf, -1)) {
+		BIO_printf(bio_err, "Error adding attribute\n");
+		ERR_print_errors(bio_err);
+		goto err;
+	}
+
+	return(1);
+err:
+	return(0);
+	}
+
+static int req_check_len(int len, int n_min, int n_max)
+	{
+	if ((n_min > 0) && (len < n_min))
+		{
+		BIO_printf(bio_err,"string is too short, it needs to be at least %d bytes long\n",n_min);
+		return(0);
+		}
+	if ((n_max >= 0) && (len > n_max))
+		{
+		BIO_printf(bio_err,"string is too long, it needs to be less than  %d bytes long\n",n_max);
+		return(0);
+		}
+	return(1);
+	}
+
+/* Check if the end of a string matches 'end' */
+static int check_end(const char *str, const char *end)
+{
+	int elen, slen;	
+	const char *tmp;
+	elen = strlen(end);
+	slen = strlen(str);
+	if(elen > slen) return 1;
+	tmp = str + slen - elen;
+	return strcmp(tmp, end);
+}
+
+static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, int *pkey_type,
+					long *pkeylen, char **palgnam,
+					ENGINE *keygen_engine)
+	{
+	EVP_PKEY_CTX *gctx = NULL;
+	EVP_PKEY *param = NULL;
+	long keylen = -1;
+	BIO *pbio = NULL;
+	const char *paramfile = NULL;
+
+	if (gstr == NULL)
+		{
+		*pkey_type = EVP_PKEY_RSA;
+		keylen = *pkeylen;
+		}
+	else if (gstr[0] >= '0' && gstr[0] <= '9')
+		{
+		*pkey_type = EVP_PKEY_RSA;
+		keylen = atol(gstr);
+		*pkeylen = keylen;
+		}
+	else if (!strncmp(gstr, "param:", 6))
+		paramfile = gstr + 6;
+	else
+		{
+		const char *p = strchr(gstr, ':');
+		int len;
+		ENGINE *tmpeng;
+		const EVP_PKEY_ASN1_METHOD *ameth;
+
+		if (p)
+			len = p - gstr;
+		else
+			len = strlen(gstr);
+		/* The lookup of a the string will cover all engines so
+		 * keep a note of the implementation.
+		 */
+
+		ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len);
+
+		if (!ameth)
+			{
+			BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr);
+			return NULL;
+			}
+
+		EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL,
+									ameth);
+#ifndef OPENSSL_NO_ENGINE
+		if (tmpeng)
+			ENGINE_finish(tmpeng);
+#endif
+		if (*pkey_type == EVP_PKEY_RSA)
+			{
+			if (p)
+				{
+				keylen = atol(p + 1);
+				*pkeylen = keylen;
+				}
+			}
+		else if (p)
+			paramfile = p + 1;
+		}
+
+	if (paramfile)
+		{
+		pbio = BIO_new_file(paramfile, "r");
+		if (!pbio)
+			{
+			BIO_printf(err, "Can't open parameter file %s\n",
+					paramfile);
+			return NULL;
+			}
+		param = PEM_read_bio_Parameters(pbio, NULL);
+
+		if (!param)
+			{
+			X509 *x;
+			(void)BIO_reset(pbio);
+			x = PEM_read_bio_X509(pbio, NULL, NULL, NULL);
+			if (x)
+				{
+				param = X509_get_pubkey(x);
+				X509_free(x);
+				}
+			}
+
+		BIO_free(pbio);
+
+		if (!param)
+			{
+			BIO_printf(err, "Error reading parameter file %s\n",
+					paramfile);
+			return NULL;
+			}
+		if (*pkey_type == -1)
+			*pkey_type = EVP_PKEY_id(param);
+		else if (*pkey_type != EVP_PKEY_base_id(param))
+			{
+			BIO_printf(err, "Key Type does not match parameters\n");
+			EVP_PKEY_free(param);
+			return NULL;
+			}
+		}
+
+	if (palgnam)
+		{
+		const EVP_PKEY_ASN1_METHOD *ameth;
+		ENGINE *tmpeng;
+		const char *anam;
+		ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type);
+		if (!ameth)
+			{
+			BIO_puts(err, "Internal error: can't find key algorithm\n");
+			return NULL;
+			}
+		EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth);
+		*palgnam = BUF_strdup(anam);
+#ifndef OPENSSL_NO_ENGINE
+		if (tmpeng)
+			ENGINE_finish(tmpeng);
+#endif
+		}
+
+	if (param)
+		{
+		gctx = EVP_PKEY_CTX_new(param, keygen_engine);
+		*pkeylen = EVP_PKEY_bits(param);
+		EVP_PKEY_free(param);
+		}
+	else
+		gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine);
+
+	if (!gctx)
+		{
+		BIO_puts(err, "Error allocating keygen context\n");
+		ERR_print_errors(err);
+		return NULL;
+		}
+
+	if (EVP_PKEY_keygen_init(gctx) <= 0)
+		{
+		BIO_puts(err, "Error initializing keygen context\n");
+		ERR_print_errors(err);
+		return NULL;
+		}
+#ifndef OPENSSL_NO_RSA
+	if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1))
+		{
+		if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0)
+			{
+			BIO_puts(err, "Error setting RSA keysize\n");
+			ERR_print_errors(err);
+			EVP_PKEY_CTX_free(gctx);
+			return NULL;
+			}
+		}
+#endif
+
+	return gctx;
+	}
+
+static int genpkey_cb(EVP_PKEY_CTX *ctx)
+	{
+	char c='*';
+	BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
+	int p;
+	p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
+	if (p == 0) c='.';
+	if (p == 1) c='+';
+	if (p == 2) c='*';
+	if (p == 3) c='\n';
+	BIO_write(b,&c,1);
+	(void)BIO_flush(b);
+#ifdef LINT
+	p=n;
+#endif
+	return 1;
+	}
diff --git a/openssl/apps/req.pem b/openssl/apps/req.pem
new file mode 100644
index 0000000..5537df6
--- /dev/null
+++ b/openssl/apps/req.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBlzCCAVcCAQAwXjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
+ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAxMORXJp
+YyB0aGUgWW91bmcwge8wgaYGBSsOAwIMMIGcAkEA+ZiKEvZmc9MtnaFZh4NiZ3oZ
+S4J1PHvPrm9MXj5ntVheDPkdmBDTncyaGAJcMjwsyB/GvLDGd6yGCw/8eF+09wIV
+AK3VagOxGd/Q4Af5NbxR5FB7CXEjAkA2t/q7HgVLi0KeKvcDG8BRl3wuy7bCvpjg
+tWiJc/tpvcuzeuAayH89UofjAGueKjXDADiRffvSdhrNw5dkqdqlA0QAAkEAtUSo
+84OekjitKGVjxLu0HvXck29pu+foad53vPKXAsuJdACj88BPqZ91Y9PIJf1GUh38
+CuiHWi7z3cEDfZCyCKAAMAkGBSsOAwIbBQADLwAwLAIUTg8amKVBE9oqC5B75dDQ
+Chy3LdQCFHKodGEj3LjuTzdm/RTe2KZL9Uzf
+-----END CERTIFICATE REQUEST-----
diff --git a/openssl/apps/rsa.c b/openssl/apps/rsa.c
new file mode 100644
index 0000000..a17708f
--- /dev/null
+++ b/openssl/apps/rsa.c
@@ -0,0 +1,450 @@
+/* apps/rsa.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_RSA
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/bn.h>
+
+#undef PROG
+#define PROG	rsa_main
+
+/* -inform arg	- input format - default PEM (one of DER, NET or PEM)
+ * -outform arg - output format - default PEM
+ * -in arg	- input file - default stdin
+ * -out arg	- output file - default stdout
+ * -des		- encrypt output if PEM format with DES in cbc mode
+ * -des3	- encrypt output if PEM format
+ * -idea	- encrypt output if PEM format
+ * -seed	- encrypt output if PEM format
+ * -aes128	- encrypt output if PEM format
+ * -aes192	- encrypt output if PEM format
+ * -aes256	- encrypt output if PEM format
+ * -camellia128 - encrypt output if PEM format
+ * -camellia192 - encrypt output if PEM format
+ * -camellia256 - encrypt output if PEM format
+ * -text	- print a text version
+ * -modulus	- print the RSA key modulus
+ * -check	- verify key consistency
+ * -pubin	- Expect a public key in input file.
+ * -pubout	- Output a public key.
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	ENGINE *e = NULL;
+	int ret=1;
+	RSA *rsa=NULL;
+	int i,badops=0, sgckey=0;
+	const EVP_CIPHER *enc=NULL;
+	BIO *out=NULL;
+	int informat,outformat,text=0,check=0,noout=0;
+	int pubin = 0, pubout = 0;
+	char *infile,*outfile,*prog;
+	char *passargin = NULL, *passargout = NULL;
+	char *passin = NULL, *passout = NULL;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+	int modulus=0;
+
+	int pvk_encr = 2;
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	infile=NULL;
+	outfile=NULL;
+	informat=FORMAT_PEM;
+	outformat=FORMAT_PEM;
+
+	prog=argv[0];
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if 	(strcmp(*argv,"-inform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			informat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-outform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outformat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-passin") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passargin= *(++argv);
+			}
+		else if (strcmp(*argv,"-passout") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passargout= *(++argv);
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*argv,"-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine= *(++argv);
+			}
+#endif
+		else if (strcmp(*argv,"-sgckey") == 0)
+			sgckey=1;
+		else if (strcmp(*argv,"-pubin") == 0)
+			pubin=1;
+		else if (strcmp(*argv,"-pubout") == 0)
+			pubout=1;
+		else if (strcmp(*argv,"-RSAPublicKey_in") == 0)
+			pubin = 2;
+		else if (strcmp(*argv,"-RSAPublicKey_out") == 0)
+			pubout = 2;
+		else if (strcmp(*argv,"-pvk-strong") == 0)
+			pvk_encr=2;
+		else if (strcmp(*argv,"-pvk-weak") == 0)
+			pvk_encr=1;
+		else if (strcmp(*argv,"-pvk-none") == 0)
+			pvk_encr=0;
+		else if (strcmp(*argv,"-noout") == 0)
+			noout=1;
+		else if (strcmp(*argv,"-text") == 0)
+			text=1;
+		else if (strcmp(*argv,"-modulus") == 0)
+			modulus=1;
+		else if (strcmp(*argv,"-check") == 0)
+			check=1;
+		else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL)
+			{
+			BIO_printf(bio_err,"unknown option %s\n",*argv);
+			badops=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (badops)
+		{
+bad:
+		BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
+		BIO_printf(bio_err,"where options are\n");
+		BIO_printf(bio_err," -inform arg     input format - one of DER NET PEM\n");
+		BIO_printf(bio_err," -outform arg    output format - one of DER NET PEM\n");
+		BIO_printf(bio_err," -in arg         input file\n");
+		BIO_printf(bio_err," -sgckey         Use IIS SGC key format\n");
+		BIO_printf(bio_err," -passin arg     input file pass phrase source\n");
+		BIO_printf(bio_err," -out arg        output file\n");
+		BIO_printf(bio_err," -passout arg    output file pass phrase source\n");
+		BIO_printf(bio_err," -des            encrypt PEM output with cbc des\n");
+		BIO_printf(bio_err," -des3           encrypt PEM output with ede cbc des using 168 bit key\n");
+#ifndef OPENSSL_NO_IDEA
+		BIO_printf(bio_err," -idea           encrypt PEM output with cbc idea\n");
+#endif
+#ifndef OPENSSL_NO_SEED
+		BIO_printf(bio_err," -seed           encrypt PEM output with cbc seed\n");
+#endif
+#ifndef OPENSSL_NO_AES
+		BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
+		BIO_printf(bio_err,"                 encrypt PEM output with cbc aes\n");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+		BIO_printf(bio_err," -camellia128, -camellia192, -camellia256\n");
+		BIO_printf(bio_err,"                 encrypt PEM output with cbc camellia\n");
+#endif
+		BIO_printf(bio_err," -text           print the key in text\n");
+		BIO_printf(bio_err," -noout          don't print key out\n");
+		BIO_printf(bio_err," -modulus        print the RSA key modulus\n");
+		BIO_printf(bio_err," -check          verify key consistency\n");
+		BIO_printf(bio_err," -pubin          expect a public key in input file\n");
+		BIO_printf(bio_err," -pubout         output a public key\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err," -engine e       use engine e, possibly a hardware device.\n");
+#endif
+		goto end;
+		}
+
+	ERR_load_crypto_strings();
+
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine, 0);
+#endif
+
+	if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
+		BIO_printf(bio_err, "Error getting passwords\n");
+		goto end;
+	}
+
+	if(check && pubin) {
+		BIO_printf(bio_err, "Only private keys can be checked\n");
+		goto end;
+	}
+
+	out=BIO_new(BIO_s_file());
+
+	{
+		EVP_PKEY	*pkey;
+
+		if (pubin)
+			{
+			int tmpformat=-1;
+			if (pubin == 2)
+				{
+				if (informat == FORMAT_PEM)
+					tmpformat = FORMAT_PEMRSA;
+				else if (informat == FORMAT_ASN1)
+					tmpformat = FORMAT_ASN1RSA;
+				}
+			else if (informat == FORMAT_NETSCAPE && sgckey)
+				tmpformat = FORMAT_IISSGC;
+			else
+				tmpformat = informat;
+					
+			pkey = load_pubkey(bio_err, infile, tmpformat, 1,
+				passin, e, "Public Key");
+			}
+		else
+			pkey = load_key(bio_err, infile,
+				(informat == FORMAT_NETSCAPE && sgckey ?
+					FORMAT_IISSGC : informat), 1,
+				passin, e, "Private Key");
+
+		if (pkey != NULL)
+			rsa = EVP_PKEY_get1_RSA(pkey);
+		EVP_PKEY_free(pkey);
+	}
+
+	if (rsa == NULL)
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (outfile == NULL)
+		{
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+		}
+#endif
+		}
+	else
+		{
+		if (BIO_write_filename(out,outfile) <= 0)
+			{
+			perror(outfile);
+			goto end;
+			}
+		}
+
+	if (text) 
+		if (!RSA_print(out,rsa,0))
+			{
+			perror(outfile);
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+
+	if (modulus)
+		{
+		BIO_printf(out,"Modulus=");
+		BN_print(out,rsa->n);
+		BIO_printf(out,"\n");
+		}
+
+	if (check)
+		{
+		int r = RSA_check_key(rsa);
+
+		if (r == 1)
+			BIO_printf(out,"RSA key ok\n");
+		else if (r == 0)
+			{
+			unsigned long err;
+
+			while ((err = ERR_peek_error()) != 0 &&
+				ERR_GET_LIB(err) == ERR_LIB_RSA &&
+				ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY &&
+				ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE)
+				{
+				BIO_printf(out, "RSA key error: %s\n", ERR_reason_error_string(err));
+				ERR_get_error(); /* remove e from error stack */
+				}
+			}
+		
+		if (r == -1 || ERR_peek_error() != 0) /* should happen only if r == -1 */
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+		
+	if (noout)
+		{
+		ret = 0;
+		goto end;
+		}
+	BIO_printf(bio_err,"writing RSA key\n");
+	if 	(outformat == FORMAT_ASN1) {
+		if(pubout || pubin) 
+			{
+			if (pubout == 2)
+				i=i2d_RSAPublicKey_bio(out,rsa);
+			else
+				i=i2d_RSA_PUBKEY_bio(out,rsa);
+			}
+		else i=i2d_RSAPrivateKey_bio(out,rsa);
+	}
+#ifndef OPENSSL_NO_RC4
+	else if (outformat == FORMAT_NETSCAPE)
+		{
+		unsigned char *p,*pp;
+		int size;
+
+		i=1;
+		size=i2d_RSA_NET(rsa,NULL,NULL, sgckey);
+		if ((p=(unsigned char *)OPENSSL_malloc(size)) == NULL)
+			{
+			BIO_printf(bio_err,"Memory allocation failure\n");
+			goto end;
+			}
+		pp=p;
+		i2d_RSA_NET(rsa,&p,NULL, sgckey);
+		BIO_write(out,(char *)pp,size);
+		OPENSSL_free(pp);
+		}
+#endif
+	else if (outformat == FORMAT_PEM) {
+		if(pubout || pubin)
+			{
+			if (pubout == 2)
+		    		i=PEM_write_bio_RSAPublicKey(out,rsa);
+			else
+		    		i=PEM_write_bio_RSA_PUBKEY(out,rsa);
+			}
+		else i=PEM_write_bio_RSAPrivateKey(out,rsa,
+						enc,NULL,0,NULL,passout);
+#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
+	} else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) {
+		EVP_PKEY *pk;
+		pk = EVP_PKEY_new();
+		EVP_PKEY_set1_RSA(pk, rsa);
+		if (outformat == FORMAT_PVK)
+			i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout);
+		else if (pubin || pubout)
+			i = i2b_PublicKey_bio(out, pk);
+		else
+			i = i2b_PrivateKey_bio(out, pk);
+		EVP_PKEY_free(pk);
+#endif
+	} else	{
+		BIO_printf(bio_err,"bad output format specified for outfile\n");
+		goto end;
+		}
+	if (i <= 0)
+		{
+		BIO_printf(bio_err,"unable to write key\n");
+		ERR_print_errors(bio_err);
+		}
+	else
+		ret=0;
+end:
+	if(out != NULL) BIO_free_all(out);
+	if(rsa != NULL) RSA_free(rsa);
+	if(passin) OPENSSL_free(passin);
+	if(passout) OPENSSL_free(passout);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+#else /* !OPENSSL_NO_RSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/apps/rsa8192.pem b/openssl/apps/rsa8192.pem
new file mode 100644
index 0000000..946a6e5
--- /dev/null
+++ b/openssl/apps/rsa8192.pem
@@ -0,0 +1,101 @@
+-----BEGIN RSA PRIVATE KEY-----
+
+MIISKAIBAAKCBAEAiQ2f1X6Bte1DKD0OoCBKEikzPW+5w3oXk3WwnE97Wxzy6wJZ
+ebbZC3CZKKBnJeBMrysPf+lK+9+fP6Vm8bp1wvbcSIA59BDrX6irFSuM/bdnkbuF
+MFlDjt+uVrxwoyqfPi2IPot1HQg3l5mdyBqcTWvbOnU2L9HZxJfPUCjfzdTMPrMY
+55/A20XL7tlV2opEfwhy3uVlveQBM0DnZ3MUQfrk+lRRNWv7yE4ScbOfER9fjvOm
+yJc3ZbOa3e+AMGGU9OqJ/fyOl0SGYyP2k23omy/idBV4uOs8QWdnAvq8UOzDdua3
+tuf5Tn17XBurPJ8juwyPBNispkwwn8BjxAZVPhwUIcxFBg339IxJ9cW0WdVy4nNA
+LWo/8Ahlf+kZNnFNGCPFytU9gGMLMhab9w/rLrwa9qNe4L8Fmu1JxONn1WfhMOKE
+aFmycf2olJsYLgUIGYZrjnYu0p/7P3yhTOv8JIhmK+SzmA/I0xiQoF84rpaQzH2d
+PvxICOA9oQSowou0gLuBSZWm6LiXirg1DZCziU46v33ErQlWM1dSyNaUSzihcV59
+mVD0nmzboXH75lGiyiZlp8cLbozzoCwvk9rYqpUGSBzbAy0ECCpabGpzO2Ug+oDi
+71e5z4WMpeoR4IS8MaOG/GsJnwaXhiB/gNYfK+8pRADVk5StEAZDE2alSuCbDs0z
+d9zYr4/em5T9VZsLetxRE7pm/Es9yELuViz8/Tm0/8MVdmNYc/xZU1t6qYYFdyQ2
+wlGDTiNPsjR8yXCkmBjKwqnuleu1X6LaZu3VPhEkXGcyFAquQUkSiMv0Yu74qAe0
+bQ2v+jjZzP6AM9LUo89cW4Kd8SGD96BdNlAVPNMXoBcIOsZBwsOtETBd4KAyvkXE
+Ob17u+PLl4UPnSxm9ypKZunUNFRPxtKUyjySYnvlGL+kTjAXrIrZwKJqIn0uhnfa
+Ck3o7bU6yVMK22ODxy2/Vi3E0P6k5JLwnrF0VIOBqGhts66qo6mWDP8l6MZHARFd
+pU+nofssVmr8tLKmMmjYGMM5GmKIXRNBs0ksTwFnKRs9AmpE5owC8tTSVdTAkGuS
+os7QwLvyvNzq7BGJiVr0Iy3Dhsl1vzR35acNOrCsDl3DcCQONKJ2sVXV4pD3dBah
+mG3sR/jHgjasffJJ35uiGoAua9dbT7HG/+D0z1SHYaVqH8zO4VZSOnGJh/P9rtxx
+cckFDbiag/JMWig2lbnCjebTtp/BcUsK3TNaDOb7vb0LvbAeRJadd1EFu6PSlH3K
+LykSUPm4UedvUU3cWjqkSY5lITFJkVaIYOv/EljYtK7p7kFZFTaEwMAWxgsXU3pQ
+tTzVmq1gZ4vXPwcUq0zK50Frq0F7SQc21ZsunwIDAQABAoIEADuQAkDEpBausJsS
+PgL1RXuzECPJJJCBxTE+2qx0FoY4hJICCWTORHGmU8nGPE3Ht0wBiNDsULw6KXl9
+psmzYW6D3qRbpdQebky6fu/KZ5H0XTyGpJGomaXELH5hkwo2gdKB805LSXB+m7p0
+9o96kSdMkpBLVGtf5iZ8W4rY2LsZmlI9f7taQHSLVt/M8HTz1mTnBRU92QO3zZW6
+xVa+OrWaFl18u3ZeIaSh2X40tBK68cqstXVD0r2OWuXNKobcQeJW8/XABzBShZ0c
+ihL0lzyqiN4uXrLu+Nbr22b+FU2OODy6dGk3U6/69NvI4piMCPlHsfhHOnFjd1ZW
+RIVywyUlCtLNdcn11CchuRro+0J3c2Ba+i9Cl9r3qzT11xFEGF8/XLyUBBCB+uGf
+1dR/xJQhCA7cXWWLXyI/semxcvTaGpImP6kiIl1MAjHjXZTSdvyw4JmfXyYGhSjI
+P0mw3Xn7FXxJ/os9gOfNKz2nZHjr0q4sgWRYO+4vllkeL0GteZrg4oVaVpmZb7LH
+77afhodLylhijlEtV5skfkPujbBLQk6E5Ez3U/huEt2NLg6guADmwxMxfBRliZO4
+4Ex/td4cuggpEj3FGJV74qRvdvj/MF/uF7IxC/3WapPIsFBFH4zrJsUYt6u3L68I
+/KC/bfioDeUR/8ANw1DNh+UsnPV3GJIwDkIJKdppi2uXPahJyJQQ8Inps53nn8Gg
+GifS+HnOXNgMoKOJnZ9IDGjXpfjIs8dJNrGfDHF0mH30N2WARq2v/a3cNUC+f8Bq
+HSKQ9YrZopktMunsut8u7ZYbTmjIqJpXCaM0CCrSlzSMTDHFSj2tzLk6+qnxeGxB
+ZwIdShbdeK+0ETG91lE1e9RPQs/uXQP9+uCHJV0YpqQcA6pkCLYJfYpoSMu/Bafy
+AgfVZz6l5tyEnV0wCcbopsQShc1k9xtTbYNF1h9AQHknj6zeDW4iZMvmVeh3RovT
+52OA2R8oLyauF+QaG6x2wUjEx13SJlaBarJZ4seZIOJ+a8+oNzKsbgokXc2cyC9p
+5FAZz1OsOb68o93qD1Xvl7bY97fq2q55L7G1XHPPLtZE5lGiLGDtnAuwY8UPrdpr
+7Mv2yIxB7xVGurXyHb5PvusR88XED6HMPfLBG/55ENHTal7G5mRix+IWSBAIkxA5
+KZ0j8r5Ng4+wELZhqFQai39799bIAyiV6CEz4kyDXlo0kSSexp8o4iz5sPq5vp6h
+cCb7rdRw7uRnbXrHmXahxoB+ibXaurgV/6B2yurrU/UFoxEp2sHp8LXZGfF6ztY1
+dMhSQAACK2vGy5yNagbkTHLgVaHicG5zavJBqzCE+lbPlCqhOUQPdOIwvjHNjdS/
+DL3WV/ECggIBAMbW65wPk/i43nSyeZeYwcHtR1SUJqDXavYfBPC0VRhKz+7DVMFw
+Nwnocn6gITABc445W1yl7U3uww+LGuDlSlFnd8WuiXpVYud9/jeNu6Mu4wvNsnWr
+f4f4ua8CcS03GmqmcbROD2Z6by1AblCZ2UL1kv9cUX1FLVjPP1ESAGKoePt3BmZQ
+J1uJfK8HilNT8dcUlj/5CBi2uHxttDhoG0sxXE/SVsG9OD/Pjme0mj7gdzc6Ztd+
+TALuvpNQR4pRzfo5XWDZBcEYntcEE3PxYJB1+vnZ8509ew5/yLHTbLjFxIcx71zY
+fhH0gM36Sz7mz37r0+E/QkRkc5bVIDC4LDnWmjpAde6QUx0d218ShNx6sJo4kt5c
+Dd7tEVx8nuX8AIZYgwsOb382anLyFRkkmEdK3gRvwQ6SWR36Ez5L7/mHWODpLAX5
+mVBKSG4/ccFbc633/g0xHw0Nwajir/klckdakuYPlwF0yAxJSKDLhmNctDhRmxjC
+YP+fISkl5oTvFRzJH6HEyNu8M3ybRvmpPIjM5J5JpnB2IYbohYBR+T6/97C1DKrd
+mzL5PjlrWm0c1/d7LlDoP65fOShDMmj2zCiBAHHOM0Alokx+v5LmMd8NJumZIwGJ
+Rt5OpeMOhowz6j1AjYxYgV7PmJL6Ovpfb775od/aLaUbbwHz2uWIvfF7AoICAQCw
+c7NaO7oJVLJClhYw6OCvjT6oqtgNVWaennnDiJgzY9lv5HEgV0MAG0eYuB3hvj+w
+Y1P9DJxP1D+R+cshYrAFg8yU/3kaYVNI0Bl3ygX0eW1b/0HZTdocs+8kM/9PZQDR
+WrKQoU5lHvqRt99dXlD4NWGI2YQtzdZ8iet9QLqnjwRZabgE96mF01qKisMnFcsh
+KjT7ieheU4J15TZj/mdZRNK126d7e3q/rNj73e5EJ9tkYLcolSr4gpknUMJULSEi
+JH1/Qx7C/mTAMRsN5SkOthnGq0djCNWfPv/3JV0H67Uf5krFlnwLebrgfTYoPPdo
+yO7iBUNJzv6Qh22malLp4P8gzACkD7DGlSTnoB5cLwcjmDGg+i9WrUBbOiVTeQfZ
+kOj1o+Tz35ndpq/DDUVlqliB9krcxva+QHeJPH53EGI+YVg1nD+s/vUDZ3mQMGX9
+DQou2L8uU6RnWNv/BihGcL8QvS4Ty6QyPOUPpD3zc70JQAEcQk9BxQNaELgJX0IN
+22cYn22tYvElew9G41OpDqzBRcfbdJmKXQ2HcroShutYJQRGUpAXHk24fy6JVkIU
+ojF5U6cwextMja1ZIIZgh9eugIRUeIE7319nQNDzuXWjRCcoBLA25P7wnpHWDRpz
+D9ovXCIvdja74lL5psqobV6L5+fbLPkSgXoImKR0LQKCAgAIC9Jk8kxumCyIVGCP
+PeM5Uby9M3GMuKrfYsn0Y5e97+kSJF1dpojTodBgR2KQar6eVrvXt+8uZCcIjfx8
+dUrYmHNEUJfHl4T1ESgkX1vkcpVFeQFruZDjk7EP3+1sgvpSroGTZkVBRFsTXbQZ
+FuCv0Pgt1TKG+zGmklxhj3TsiRy8MEjWAxBUp++ftZJnZNI4feDGnfEx7tLwVhAg
+6DWSiWDO6hgQpvOLwX5lu+0x9itc1MQsnDO/OqIDnBAJDN5k7cVVkfKlqbVjxgpz
+eqUJs3yAd81f44kDQTCB4ahYocgeIGsrOqd/WoGL1EEPPo/O9wQP7VtlIRt8UwuG
+bS18+a4sBUfAa56xYu/pnPo7YcubsgZfcSIujzFQqMpVTClJRnOnEuJ4J1+PXzRz
+XAO9fs4VJ+CMEmgAyonUz4Xadxulnknlw//sO9VKgM69oFHCDHL/XamAAbqAdwvf
+7R/+uy+Ol7romC0wMhb6SsIZazrvvH2mNtduAKZ638nAP1x/WbQp+6iVG7yJok7w
+82Q7tO7baOePTXh12Rrt4mNPor0HLYxhra4GFgfqkumJ2Mz0esuZAozxJXFOq8ly
+beo9CVtXP5zbT6qNpeNismX6PLICaev8t+1iOZSE56WSLtefuuj/cOVrTMNDz1Rr
+pUkEVV2zjUSjlcScM538A9iL2QKCAgBLbBk0r6T0ihRsK9UucMxhnYEz/Vq+UEu9
+70Vi1AciqEJv9nh4d3Q3HnH7EHANZxG4Jqzm1DYYVUQa9GfkTFeq88xFv/GW2hUM
+YY8RSfRDrIeXNEOETCe37x2AHw25dRXlZtw+wARPau91y9+Y/FCl18NqCHfcUEin
+ERjsf/eI2bPlODAlR2tZvZ7M60VBdqpN8cmV3zvI3e88z43xLfQlDyr1+v7a5Evy
+lEJnXlSTI2o+vKxtl103vjMSwA1gh63K90gBVsJWXQDZueOzi8mB9UqNRfcMmOEe
+4YHttTXPxeu0x+4cCRfam9zKShsVFgI28vRQ/ijl6qmbQ5gV8wqf18GV1j1L4z0P
+lP6iVynDA4MMrug/w9DqPsHsfK0pwekeETfSj4y0xVXyjWZBfHG2ZBrS6mDTf+RG
+LC4sJgR0hjdILLnUqIX7PzuhieBHRrjBcopwvcryVWRHnI7kslAS0+yHjiWc5oW3
+x5mtlum4HzelNYuD9cAE/95P6CeSMfp9CyIE/KSX4VvsRm6gQVkoQRKMxnQIFQ3w
+O5gl1l88vhjoo2HxYScgCp70BsDwiUNTqIR3NM+ZBHYFweVf3Gwz5LzHZT2rEZtD
+6VXRP75Q/2wOLnqCO4bK4BUs6sqxcQZmOldruPkPynrY0oPfHHExjxZDvQu4/r80
+Ls3n0L8yvQKCAgEAnYWS6EikwaQNpJEfiUnOlglgFz4EE1eVkrDbBY4J3oPU+doz
+DrqmsvgpSZIAfd2MUbkN4pOMsMTjbeIYWDnZDa1RoctKs3FhwFPHwAjQpznab4mn
+Bp81FMHM40qyb0NaNuFRwghdXvoQvBBX1p8oEnFzDRvTiuS/vTPTA8KDY8IeRp8R
+oGzKHpfziNwq/URpqj7pwi9odNjGZvR2IwYw9jCLPIqaEbMoSOdI0mg4MoYyqP4q
+nm7d4wqSDwrYxiXZ6f3nYpkhEY1lb0Wbksp1ig8sKSF4nDZRGK1RSfE+6gjBp94H
+X/Wog6Zb6NC9ZpusTiDLvuIUXcyUJvmHiWjSNqiTv8jurlwEsgSwhziEQfqLrtdV
+QI3PRMolBkD1iCk+HFE53r05LMf1bp3r4MS+naaQrLbIrl1kgDNGwVdgS+SCM7Bg
+TwEgE67iOb2iIoUpon/NyP4LesMzvdpsu2JFlfz13PmmQ34mFI7tWvOb3NA5DP3c
+46C6SaWI0TD9B11nJbHGTYN3Si9n0EBgoDJEXUKeh3km9O47dgvkSug4WzhYsvrE
+rMlMLtKfp2w8HlMZpsUlToNCx6CI+tJrohzcs3BAVAbjFAXRKWGijB1rxwyDdHPv
+I+/wJTNaRNPQ1M0SwtEL/zJd21y3KSPn4eL+GP3efhlDSjtlDvZqkdAUsU8=
+-----END RSA PRIVATE KEY-----
+
diff --git a/openssl/apps/rsautl.c b/openssl/apps/rsautl.c
new file mode 100644
index 0000000..b01f004
--- /dev/null
+++ b/openssl/apps/rsautl.c
@@ -0,0 +1,351 @@
+/* rsautl.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_RSA
+
+#include "apps.h"
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/rsa.h>
+
+#define RSA_SIGN 	1
+#define RSA_VERIFY 	2
+#define RSA_ENCRYPT 	3
+#define RSA_DECRYPT 	4
+
+#define KEY_PRIVKEY	1
+#define KEY_PUBKEY	2
+#define KEY_CERT	3
+
+static void usage(void);
+
+#undef PROG
+
+#define PROG rsautl_main
+
+int MAIN(int argc, char **);
+
+int MAIN(int argc, char **argv)
+{
+	ENGINE *e = NULL;
+	BIO *in = NULL, *out = NULL;
+	char *infile = NULL, *outfile = NULL;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine = NULL;
+#endif
+	char *keyfile = NULL;
+	char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY;
+	int keyform = FORMAT_PEM;
+	char need_priv = 0, badarg = 0, rev = 0;
+	char hexdump = 0, asn1parse = 0;
+	X509 *x;
+	EVP_PKEY *pkey = NULL;
+	RSA *rsa = NULL;
+	unsigned char *rsa_in = NULL, *rsa_out = NULL, pad;
+	char *passargin = NULL, *passin = NULL;
+	int rsa_inlen, rsa_outlen = 0;
+	int keysize;
+
+	int ret = 1;
+
+	argc--;
+	argv++;
+
+	if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+	ERR_load_crypto_strings();
+	OpenSSL_add_all_algorithms();
+	pad = RSA_PKCS1_PADDING;
+	
+	while(argc >= 1)
+	{
+		if (!strcmp(*argv,"-in")) {
+			if (--argc < 1)
+				badarg = 1;
+			else
+				infile= *(++argv);
+		} else if (!strcmp(*argv,"-out")) {
+			if (--argc < 1)
+				badarg = 1;
+			else
+				outfile= *(++argv);
+		} else if(!strcmp(*argv, "-inkey")) {
+			if (--argc < 1)
+				badarg = 1;
+			else
+				keyfile = *(++argv);
+		} else if (!strcmp(*argv,"-passin")) {
+			if (--argc < 1)
+				badarg = 1;
+			else
+				passargin= *(++argv);
+		} else if (strcmp(*argv,"-keyform") == 0) {
+			if (--argc < 1)
+				badarg = 1;
+			else
+				keyform=str2fmt(*(++argv));
+#ifndef OPENSSL_NO_ENGINE
+		} else if(!strcmp(*argv, "-engine")) {
+			if (--argc < 1)
+				badarg = 1;
+			else
+				engine = *(++argv);
+#endif
+		} else if(!strcmp(*argv, "-pubin")) {
+			key_type = KEY_PUBKEY;
+		} else if(!strcmp(*argv, "-certin")) {
+			key_type = KEY_CERT;
+		} 
+		else if(!strcmp(*argv, "-asn1parse")) asn1parse = 1;
+		else if(!strcmp(*argv, "-hexdump")) hexdump = 1;
+		else if(!strcmp(*argv, "-raw")) pad = RSA_NO_PADDING;
+		else if(!strcmp(*argv, "-oaep")) pad = RSA_PKCS1_OAEP_PADDING;
+		else if(!strcmp(*argv, "-ssl")) pad = RSA_SSLV23_PADDING;
+		else if(!strcmp(*argv, "-pkcs")) pad = RSA_PKCS1_PADDING;
+		else if(!strcmp(*argv, "-x931")) pad = RSA_X931_PADDING;
+		else if(!strcmp(*argv, "-sign")) {
+			rsa_mode = RSA_SIGN;
+			need_priv = 1;
+		} else if(!strcmp(*argv, "-verify")) rsa_mode = RSA_VERIFY;
+		else if(!strcmp(*argv, "-rev")) rev = 1;
+		else if(!strcmp(*argv, "-encrypt")) rsa_mode = RSA_ENCRYPT;
+		else if(!strcmp(*argv, "-decrypt")) {
+			rsa_mode = RSA_DECRYPT;
+			need_priv = 1;
+		} else badarg = 1;
+		if(badarg) {
+			usage();
+			goto end;
+		}
+		argc--;
+		argv++;
+	}
+
+	if(need_priv && (key_type != KEY_PRIVKEY)) {
+		BIO_printf(bio_err, "A private key is needed for this operation\n");
+		goto end;
+	}
+
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine, 0);
+#endif
+	if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
+		BIO_printf(bio_err, "Error getting password\n");
+		goto end;
+	}
+
+/* FIXME: seed PRNG only if needed */
+	app_RAND_load_file(NULL, bio_err, 0);
+	
+	switch(key_type) {
+		case KEY_PRIVKEY:
+		pkey = load_key(bio_err, keyfile, keyform, 0,
+			passin, e, "Private Key");
+		break;
+
+		case KEY_PUBKEY:
+		pkey = load_pubkey(bio_err, keyfile, keyform, 0,
+			NULL, e, "Public Key");
+		break;
+
+		case KEY_CERT:
+		x = load_cert(bio_err, keyfile, keyform,
+			NULL, e, "Certificate");
+		if(x) {
+			pkey = X509_get_pubkey(x);
+			X509_free(x);
+		}
+		break;
+	}
+
+	if(!pkey) {
+		return 1;
+	}
+
+	rsa = EVP_PKEY_get1_RSA(pkey);
+	EVP_PKEY_free(pkey);
+
+	if(!rsa) {
+		BIO_printf(bio_err, "Error getting RSA key\n");
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+
+
+	if(infile) {
+		if(!(in = BIO_new_file(infile, "rb"))) {
+			BIO_printf(bio_err, "Error Reading Input File\n");
+			ERR_print_errors(bio_err);	
+			goto end;
+		}
+	} else in = BIO_new_fp(stdin, BIO_NOCLOSE);
+
+	if(outfile) {
+		if(!(out = BIO_new_file(outfile, "wb"))) {
+			BIO_printf(bio_err, "Error Reading Output File\n");
+			ERR_print_errors(bio_err);	
+			goto end;
+		}
+	} else {
+		out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		    out = BIO_push(tmpbio, out);
+		}
+#endif
+	}
+
+	keysize = RSA_size(rsa);
+
+	rsa_in = OPENSSL_malloc(keysize * 2);
+	rsa_out = OPENSSL_malloc(keysize);
+
+	/* Read the input data */
+	rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
+	if(rsa_inlen <= 0) {
+		BIO_printf(bio_err, "Error reading input Data\n");
+		exit(1);
+	}
+	if(rev) {
+		int i;
+		unsigned char ctmp;
+		for(i = 0; i < rsa_inlen/2; i++) {
+			ctmp = rsa_in[i];
+			rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
+			rsa_in[rsa_inlen - 1 - i] = ctmp;
+		}
+	}
+	switch(rsa_mode) {
+
+		case RSA_VERIFY:
+			rsa_outlen  = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
+		break;
+
+		case RSA_SIGN:
+			rsa_outlen  = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
+		break;
+
+		case RSA_ENCRYPT:
+			rsa_outlen  = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
+		break;
+
+		case RSA_DECRYPT:
+			rsa_outlen  = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
+		break;
+
+	}
+
+	if(rsa_outlen <= 0) {
+		BIO_printf(bio_err, "RSA operation error\n");
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+	ret = 0;
+	if(asn1parse) {
+		if(!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
+			ERR_print_errors(bio_err);
+		}
+	} else if(hexdump) BIO_dump(out, (char *)rsa_out, rsa_outlen);
+	else BIO_write(out, rsa_out, rsa_outlen);
+	end:
+	RSA_free(rsa);
+	BIO_free(in);
+	BIO_free_all(out);
+	if(rsa_in) OPENSSL_free(rsa_in);
+	if(rsa_out) OPENSSL_free(rsa_out);
+	if(passin) OPENSSL_free(passin);
+	return ret;
+}
+
+static void usage()
+{
+	BIO_printf(bio_err, "Usage: rsautl [options]\n");
+	BIO_printf(bio_err, "-in file        input file\n");
+	BIO_printf(bio_err, "-out file       output file\n");
+	BIO_printf(bio_err, "-inkey file     input key\n");
+	BIO_printf(bio_err, "-keyform arg    private key format - default PEM\n");
+	BIO_printf(bio_err, "-pubin          input is an RSA public\n");
+	BIO_printf(bio_err, "-certin         input is a certificate carrying an RSA public key\n");
+	BIO_printf(bio_err, "-ssl            use SSL v2 padding\n");
+	BIO_printf(bio_err, "-raw            use no padding\n");
+	BIO_printf(bio_err, "-pkcs           use PKCS#1 v1.5 padding (default)\n");
+	BIO_printf(bio_err, "-oaep           use PKCS#1 OAEP\n");
+	BIO_printf(bio_err, "-sign           sign with private key\n");
+	BIO_printf(bio_err, "-verify         verify with public key\n");
+	BIO_printf(bio_err, "-encrypt        encrypt with public key\n");
+	BIO_printf(bio_err, "-decrypt        decrypt with private key\n");
+	BIO_printf(bio_err, "-hexdump        hex dump output\n");
+#ifndef OPENSSL_NO_ENGINE
+	BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
+	BIO_printf (bio_err, "-passin arg    pass phrase source\n");
+#endif
+
+}
+
+#else /* !OPENSSL_NO_RSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/apps/s1024key.pem b/openssl/apps/s1024key.pem
new file mode 100644
index 0000000..19e0403
--- /dev/null
+++ b/openssl/apps/s1024key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQCzEfU8E+ZGTGtHXV5XhvM2Lg32fXUIjydXb34BGVPX6oN7+aNV
+S9eWayvW/+9/vUb0aCqilJrpFesgItV2T8VhhjOE++XUz46uNpcMU7wHMEAXUufP
+pztpFm8ZEk2tFKvadkSSoN8lb11juvZVkSkPlB65pFhSe4QKSp6J4HrkYwIDAQAB
+AoGBAKy8jvb0Lzby8q11yNLf7+78wCVdYi7ugMHcYA1JVFK8+zb1WfSm44FLQo/0
+dSChAjgz36TTexeLODPYxleJndjVcOMVzsLJjSM8dLpXsTS4FCeMbhw2s2u+xqKY
+bbPWfk+HOTyJjfnkcC5Nbg44eOmruq0gSmBeUXVM5UntlTnxAkEA7TGCA3h7kx5E
+Bl4zl2pc3gPAGt+dyfk5Po9mGJUUXhF5p2zueGmYWW74TmOWB1kzt4QRdYMzFePq
+zfDNXEa1CwJBAMFErdY0xp0UJ13WwBbUTk8rujqQdHtjw0klhpbuKkjxu2hN0wwM
+6p0D9qxF7JHaghqVRI0fAW/EE0OzdHMR9QkCQQDNR26dMFXKsoPu+vItljj/UEGf
+QG7gERiQ4yxaFBPHgdpGo0kT31eh9x9hQGDkxTe0GNG/YSgCRvm8+C3TMcKXAkBD
+dhGn36wkUFCddMSAM4NSJ1VN8/Z0y5HzCmI8dM3VwGtGMUQlxKxwOl30LEQzdS5M
+0SWojNYXiT2gOBfBwtbhAkEAhafl5QEOIgUz+XazS/IlZ8goNKdDVfYgK3mHHjvv
+nY5G+AuGebdNkXJr4KSWxDcN+C2i47zuj4QXA16MAOandA==
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/apps/s1024req.pem b/openssl/apps/s1024req.pem
new file mode 100644
index 0000000..bb75e7e
--- /dev/null
+++ b/openssl/apps/s1024req.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBojCCAQsCAQAwZDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQx
+GjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSQwIgYDVQQDExtTZXJ2ZXIgdGVz
+dCBjZXJ0ICgxMDI0IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALMR
+9TwT5kZMa0ddXleG8zYuDfZ9dQiPJ1dvfgEZU9fqg3v5o1VL15ZrK9b/73+9RvRo
+KqKUmukV6yAi1XZPxWGGM4T75dTPjq42lwxTvAcwQBdS58+nO2kWbxkSTa0Uq9p2
+RJKg3yVvXWO69lWRKQ+UHrmkWFJ7hApKnongeuRjAgMBAAEwDQYJKoZIhvcNAQEE
+BQADgYEAStHlk4pBbwiNeQ2/PKTPPXzITYC8Gn0XMbrU94e/6JIKiO7aArq9Espq
+nrBSvC14dHcNl6NNvnkEKdQ7hAkcACfBbnOXA/oQvMBd4GD78cH3k0jVDoVUEjil
+frLfWlckW6WzpTktt0ZPDdAjJCmKVh0ABHimi7Bo9FC3wIGIe5M=
+-----END CERTIFICATE REQUEST-----
diff --git a/openssl/apps/s512-key.pem b/openssl/apps/s512-key.pem
new file mode 100644
index 0000000..0e3ff2d
--- /dev/null
+++ b/openssl/apps/s512-key.pem
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBPAIBAAJBAJ+zw4Qnlf8SMVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVD
+TGiXav6ooKXfX3j/7tdkuD8Ey2//Kv7+ue0CAwEAAQJAN6W31vDEP2DjdqhzCDDu
+OA4NACqoiFqyblo7yc2tM4h4xMbC3Yx5UKMN9ZkCtX0gzrz6DyF47bdKcWBzNWCj
+gQIhANEoojVt7hq+SQ6MCN6FTAysGgQf56Q3TYoJMoWvdiXVAiEAw3e3rc+VJpOz
+rHuDo6bgpjUAAXM+v3fcpsfZSNO6V7kCIQCtbVjanpUwvZkMI9by02oUk9taki3b
+PzPfAfNPYAbCJQIhAJXNQDWyqwn/lGmR11cqY2y9nZ1+5w3yHGatLrcDnQHxAiEA
+vnlEGo8K85u+KwIOimM48ZG8oTk7iFdkqLJR1utT3aU=
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/apps/s512-req.pem b/openssl/apps/s512-req.pem
new file mode 100644
index 0000000..ea314be
--- /dev/null
+++ b/openssl/apps/s512-req.pem
@@ -0,0 +1,8 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBGzCBxgIBADBjMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEa
+MBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxIzAhBgNVBAMTGlNlcnZlciB0ZXN0
+IGNlcnQgKDUxMiBiaXQpMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ+zw4Qnlf8S
+MVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVDTGiXav6ooKXfX3j/7tdkuD8E
+y2//Kv7+ue0CAwEAATANBgkqhkiG9w0BAQQFAANBAAB+uQi+qwn6qRSHB8EUTvsm
+5TNTHzYDeN39nyIbZNX2s0se3Srn2Bxft5YCwD3moFZ9QoyDHxE0h6qLX5yjD+8=
+-----END CERTIFICATE REQUEST-----
diff --git a/openssl/apps/s_apps.h b/openssl/apps/s_apps.h
new file mode 100644
index 0000000..820e5c5
--- /dev/null
+++ b/openssl/apps/s_apps.h
@@ -0,0 +1,176 @@
+/* apps/s_apps.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#if !defined(OPENSSL_SYS_NETWARE)  /* conflicts with winsock2 stuff on netware */
+#include <sys/types.h>
+#endif
+#include <openssl/opensslconf.h>
+
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
+#include <conio.h>
+#endif
+
+#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32)
+#define _kbhit kbhit
+#endif
+
+#if defined(OPENSSL_SYS_VMS) && !defined(FD_SET)
+/* VAX C does not defined fd_set and friends, but it's actually quite simple */
+/* These definitions are borrowed from SOCKETSHR.	/Richard Levitte */
+#define MAX_NOFILE	32
+#define	NBBY		 8		/* number of bits in a byte	*/
+
+#ifndef	FD_SETSIZE
+#define	FD_SETSIZE	MAX_NOFILE
+#endif	/* FD_SETSIZE */
+
+/* How many things we'll allow select to use. 0 if unlimited */
+#define MAXSELFD	MAX_NOFILE
+typedef int	fd_mask;	/* int here! VMS prototypes int, not long */
+#define NFDBITS	(sizeof(fd_mask) * NBBY)	/* bits per mask (power of 2!)*/
+#define NFDSHIFT 5				/* Shift based on above */
+
+typedef fd_mask fd_set;
+#define	FD_SET(n, p)	(*(p) |= (1 << ((n) % NFDBITS)))
+#define	FD_CLR(n, p)	(*(p) &= ~(1 << ((n) % NFDBITS)))
+#define	FD_ISSET(n, p)	(*(p) & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)	memset((char *)(p), 0, sizeof(*(p)))
+#endif
+
+#define PORT            4433
+#define PORT_STR        "4433"
+#define PROTOCOL        "tcp"
+
+int do_server(int port, int type, int *ret, int (*cb) (char *hostname, int s, unsigned char *context), unsigned char *context);
+#ifdef HEADER_X509_H
+int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
+#endif
+#ifdef HEADER_SSL_H
+int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
+int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key);
+#endif
+int init_client(int *sock, char *server, int port, int type);
+int should_retry(int i);
+int extract_port(char *str, short *port_ptr);
+int extract_host_port(char *str,char **host_ptr,unsigned char *ip,short *p);
+
+long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp,
+				   int argi, long argl, long ret);
+
+#ifdef HEADER_SSL_H
+void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret);
+void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg);
+void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type,
+					unsigned char *data, int len,
+					void *arg);
+#endif
+
+int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len);
+int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int cookie_len);
diff --git a/openssl/apps/s_cb.c b/openssl/apps/s_cb.c
new file mode 100644
index 0000000..c4f5512
--- /dev/null
+++ b/openssl/apps/s_cb.c
@@ -0,0 +1,862 @@
+/* apps/s_cb.c - callback functions used by s_client, s_server, and s_time */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#define USE_SOCKETS
+#define NON_MAIN
+#include "apps.h"
+#undef NON_MAIN
+#undef USE_SOCKETS
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include "s_apps.h"
+
+#define	COOKIE_SECRET_LENGTH	16
+
+int verify_depth=0;
+int verify_error=X509_V_OK;
+int verify_return_error=0;
+unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
+int cookie_initialized=0;
+
+int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
+	{
+	X509 *err_cert;
+	int err,depth;
+
+	err_cert=X509_STORE_CTX_get_current_cert(ctx);
+	err=	X509_STORE_CTX_get_error(ctx);
+	depth=	X509_STORE_CTX_get_error_depth(ctx);
+
+	BIO_printf(bio_err,"depth=%d ",depth);
+	if (err_cert)
+		{
+		X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert),
+					0, XN_FLAG_ONELINE);
+		BIO_puts(bio_err, "\n");
+		}
+	else
+		BIO_puts(bio_err, "<no cert>\n");
+	if (!ok)
+		{
+		BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
+			X509_verify_cert_error_string(err));
+		if (verify_depth >= depth)
+			{
+			if (!verify_return_error)
+				ok=1;
+			verify_error=X509_V_OK;
+			}
+		else
+			{
+			ok=0;
+			verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
+			}
+		}
+	switch (err)
+		{
+	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+		BIO_puts(bio_err,"issuer= ");
+		X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert),
+					0, XN_FLAG_ONELINE);
+		BIO_puts(bio_err, "\n");
+		break;
+	case X509_V_ERR_CERT_NOT_YET_VALID:
+	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+		BIO_printf(bio_err,"notBefore=");
+		ASN1_TIME_print(bio_err,X509_get_notBefore(err_cert));
+		BIO_printf(bio_err,"\n");
+		break;
+	case X509_V_ERR_CERT_HAS_EXPIRED:
+	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+		BIO_printf(bio_err,"notAfter=");
+		ASN1_TIME_print(bio_err,X509_get_notAfter(err_cert));
+		BIO_printf(bio_err,"\n");
+		break;
+	case X509_V_ERR_NO_EXPLICIT_POLICY:
+		policies_print(bio_err, ctx);
+		break;
+		}
+	if (err == X509_V_OK && ok == 2)
+		policies_print(bio_err, ctx);
+
+	BIO_printf(bio_err,"verify return:%d\n",ok);
+	return(ok);
+	}
+
+int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
+	{
+	if (cert_file != NULL)
+		{
+		/*
+		SSL *ssl;
+		X509 *x509;
+		*/
+
+		if (SSL_CTX_use_certificate_file(ctx,cert_file,
+			SSL_FILETYPE_PEM) <= 0)
+			{
+			BIO_printf(bio_err,"unable to get certificate from '%s'\n",cert_file);
+			ERR_print_errors(bio_err);
+			return(0);
+			}
+		if (key_file == NULL) key_file=cert_file;
+		if (SSL_CTX_use_PrivateKey_file(ctx,key_file,
+			SSL_FILETYPE_PEM) <= 0)
+			{
+			BIO_printf(bio_err,"unable to get private key from '%s'\n",key_file);
+			ERR_print_errors(bio_err);
+			return(0);
+			}
+
+		/*
+		In theory this is no longer needed 
+		ssl=SSL_new(ctx);
+		x509=SSL_get_certificate(ssl);
+
+		if (x509 != NULL) {
+			EVP_PKEY *pktmp;
+			pktmp = X509_get_pubkey(x509);
+			EVP_PKEY_copy_parameters(pktmp,
+						SSL_get_privatekey(ssl));
+			EVP_PKEY_free(pktmp);
+		}
+		SSL_free(ssl);
+		*/
+
+		/* If we are using DSA, we can copy the parameters from
+		 * the private key */
+		
+		
+		/* Now we know that a key and cert have been set against
+		 * the SSL context */
+		if (!SSL_CTX_check_private_key(ctx))
+			{
+			BIO_printf(bio_err,"Private key does not match the certificate public key\n");
+			return(0);
+			}
+		}
+	return(1);
+	}
+
+int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key)
+	{
+	if (cert ==  NULL)
+		return 1;
+	if (SSL_CTX_use_certificate(ctx,cert) <= 0)
+		{
+		BIO_printf(bio_err,"error setting certificate\n");
+		ERR_print_errors(bio_err);
+		return 0;
+		}
+	if (SSL_CTX_use_PrivateKey(ctx,key) <= 0)
+		{
+		BIO_printf(bio_err,"error setting private key\n");
+		ERR_print_errors(bio_err);
+		return 0;
+		}
+
+		
+		/* Now we know that a key and cert have been set against
+		 * the SSL context */
+	if (!SSL_CTX_check_private_key(ctx))
+		{
+		BIO_printf(bio_err,"Private key does not match the certificate public key\n");
+		return 0;
+		}
+	return 1;
+	}
+
+long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp,
+				   int argi, long argl, long ret)
+	{
+	BIO *out;
+
+	out=(BIO *)BIO_get_callback_arg(bio);
+	if (out == NULL) return(ret);
+
+	if (cmd == (BIO_CB_READ|BIO_CB_RETURN))
+		{
+		BIO_printf(out,"read from %p [%p] (%lu bytes => %ld (0x%lX))\n",
+ 			(void *)bio,argp,(unsigned long)argi,ret,ret);
+		BIO_dump(out,argp,(int)ret);
+		return(ret);
+		}
+	else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN))
+		{
+		BIO_printf(out,"write to %p [%p] (%lu bytes => %ld (0x%lX))\n",
+			(void *)bio,argp,(unsigned long)argi,ret,ret);
+		BIO_dump(out,argp,(int)ret);
+		}
+	return(ret);
+	}
+
+void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret)
+	{
+	const char *str;
+	int w;
+
+	w=where& ~SSL_ST_MASK;
+
+	if (w & SSL_ST_CONNECT) str="SSL_connect";
+	else if (w & SSL_ST_ACCEPT) str="SSL_accept";
+	else str="undefined";
+
+	if (where & SSL_CB_LOOP)
+		{
+		BIO_printf(bio_err,"%s:%s\n",str,SSL_state_string_long(s));
+		}
+	else if (where & SSL_CB_ALERT)
+		{
+		str=(where & SSL_CB_READ)?"read":"write";
+		BIO_printf(bio_err,"SSL3 alert %s:%s:%s\n",
+			str,
+			SSL_alert_type_string_long(ret),
+			SSL_alert_desc_string_long(ret));
+		}
+	else if (where & SSL_CB_EXIT)
+		{
+		if (ret == 0)
+			BIO_printf(bio_err,"%s:failed in %s\n",
+				str,SSL_state_string_long(s));
+		else if (ret < 0)
+			{
+			BIO_printf(bio_err,"%s:error in %s\n",
+				str,SSL_state_string_long(s));
+			}
+		}
+	}
+
+
+void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
+	{
+	BIO *bio = arg;
+	const char *str_write_p, *str_version, *str_content_type = "", *str_details1 = "", *str_details2= "";
+	
+	str_write_p = write_p ? ">>>" : "<<<";
+
+	switch (version)
+		{
+	case SSL2_VERSION:
+		str_version = "SSL 2.0";
+		break;
+	case SSL3_VERSION:
+		str_version = "SSL 3.0 ";
+		break;
+	case TLS1_VERSION:
+		str_version = "TLS 1.0 ";
+		break;
+	case DTLS1_VERSION:
+		str_version = "DTLS 1.0 ";
+		break;
+	case DTLS1_BAD_VER:
+		str_version = "DTLS 1.0 (bad) ";
+		break;
+	default:
+		str_version = "???";
+		}
+
+	if (version == SSL2_VERSION)
+		{
+		str_details1 = "???";
+
+		if (len > 0)
+			{
+			switch (((const unsigned char*)buf)[0])
+				{
+				case 0:
+					str_details1 = ", ERROR:";
+					str_details2 = " ???";
+					if (len >= 3)
+						{
+						unsigned err = (((const unsigned char*)buf)[1]<<8) + ((const unsigned char*)buf)[2];
+						
+						switch (err)
+							{
+						case 0x0001:
+							str_details2 = " NO-CIPHER-ERROR";
+							break;
+						case 0x0002:
+							str_details2 = " NO-CERTIFICATE-ERROR";
+							break;
+						case 0x0004:
+							str_details2 = " BAD-CERTIFICATE-ERROR";
+							break;
+						case 0x0006:
+							str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR";
+							break;
+							}
+						}
+
+					break;
+				case 1:
+					str_details1 = ", CLIENT-HELLO";
+					break;
+				case 2:
+					str_details1 = ", CLIENT-MASTER-KEY";
+					break;
+				case 3:
+					str_details1 = ", CLIENT-FINISHED";
+					break;
+				case 4:
+					str_details1 = ", SERVER-HELLO";
+					break;
+				case 5:
+					str_details1 = ", SERVER-VERIFY";
+					break;
+				case 6:
+					str_details1 = ", SERVER-FINISHED";
+					break;
+				case 7:
+					str_details1 = ", REQUEST-CERTIFICATE";
+					break;
+				case 8:
+					str_details1 = ", CLIENT-CERTIFICATE";
+					break;
+				}
+			}
+		}
+
+	if (version == SSL3_VERSION ||
+	    version == TLS1_VERSION ||
+	    version == DTLS1_VERSION ||
+	    version == DTLS1_BAD_VER)
+		{
+		switch (content_type)
+			{
+		case 20:
+			str_content_type = "ChangeCipherSpec";
+			break;
+		case 21:
+			str_content_type = "Alert";
+			break;
+		case 22:
+			str_content_type = "Handshake";
+			break;
+			}
+
+		if (content_type == 21) /* Alert */
+			{
+			str_details1 = ", ???";
+			
+			if (len == 2)
+				{
+				switch (((const unsigned char*)buf)[0])
+					{
+				case 1:
+					str_details1 = ", warning";
+					break;
+				case 2:
+					str_details1 = ", fatal";
+					break;
+					}
+
+				str_details2 = " ???";
+				switch (((const unsigned char*)buf)[1])
+					{
+				case 0:
+					str_details2 = " close_notify";
+					break;
+				case 10:
+					str_details2 = " unexpected_message";
+					break;
+				case 20:
+					str_details2 = " bad_record_mac";
+					break;
+				case 21:
+					str_details2 = " decryption_failed";
+					break;
+				case 22:
+					str_details2 = " record_overflow";
+					break;
+				case 30:
+					str_details2 = " decompression_failure";
+					break;
+				case 40:
+					str_details2 = " handshake_failure";
+					break;
+				case 42:
+					str_details2 = " bad_certificate";
+					break;
+				case 43:
+					str_details2 = " unsupported_certificate";
+					break;
+				case 44:
+					str_details2 = " certificate_revoked";
+					break;
+				case 45:
+					str_details2 = " certificate_expired";
+					break;
+				case 46:
+					str_details2 = " certificate_unknown";
+					break;
+				case 47:
+					str_details2 = " illegal_parameter";
+					break;
+				case 48:
+					str_details2 = " unknown_ca";
+					break;
+				case 49:
+					str_details2 = " access_denied";
+					break;
+				case 50:
+					str_details2 = " decode_error";
+					break;
+				case 51:
+					str_details2 = " decrypt_error";
+					break;
+				case 60:
+					str_details2 = " export_restriction";
+					break;
+				case 70:
+					str_details2 = " protocol_version";
+					break;
+				case 71:
+					str_details2 = " insufficient_security";
+					break;
+				case 80:
+					str_details2 = " internal_error";
+					break;
+				case 90:
+					str_details2 = " user_canceled";
+					break;
+				case 100:
+					str_details2 = " no_renegotiation";
+					break;
+				case 110:
+					str_details2 = " unsupported_extension";
+					break;
+				case 111:
+					str_details2 = " certificate_unobtainable";
+					break;
+				case 112:
+					str_details2 = " unrecognized_name";
+					break;
+				case 113:
+					str_details2 = " bad_certificate_status_response";
+					break;
+				case 114:
+					str_details2 = " bad_certificate_hash_value";
+					break;
+					}
+				}
+			}
+		
+		if (content_type == 22) /* Handshake */
+			{
+			str_details1 = "???";
+
+			if (len > 0)
+				{
+				switch (((const unsigned char*)buf)[0])
+					{
+				case 0:
+					str_details1 = ", HelloRequest";
+					break;
+				case 1:
+					str_details1 = ", ClientHello";
+					break;
+				case 2:
+					str_details1 = ", ServerHello";
+					break;
+				case 3:
+					str_details1 = ", HelloVerifyRequest";
+					break;
+				case 11:
+					str_details1 = ", Certificate";
+					break;
+				case 12:
+					str_details1 = ", ServerKeyExchange";
+					break;
+				case 13:
+					str_details1 = ", CertificateRequest";
+					break;
+				case 14:
+					str_details1 = ", ServerHelloDone";
+					break;
+				case 15:
+					str_details1 = ", CertificateVerify";
+					break;
+				case 16:
+					str_details1 = ", ClientKeyExchange";
+					break;
+				case 20:
+					str_details1 = ", Finished";
+					break;
+					}
+				}
+			}
+		}
+
+	BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p, str_version, str_content_type, (unsigned long)len, str_details1, str_details2);
+
+	if (len > 0)
+		{
+		size_t num, i;
+		
+		BIO_printf(bio, "   ");
+		num = len;
+#if 0
+		if (num > 16)
+			num = 16;
+#endif
+		for (i = 0; i < num; i++)
+			{
+			if (i % 16 == 0 && i > 0)
+				BIO_printf(bio, "\n   ");
+			BIO_printf(bio, " %02x", ((const unsigned char*)buf)[i]);
+			}
+		if (i < len)
+			BIO_printf(bio, " ...");
+		BIO_printf(bio, "\n");
+		}
+	(void)BIO_flush(bio);
+	}
+
+void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type,
+					unsigned char *data, int len,
+					void *arg)
+	{
+	BIO *bio = arg;
+	char *extname;
+
+	switch(type)
+		{
+		case TLSEXT_TYPE_server_name:
+		extname = "server name";
+		break;
+
+		case TLSEXT_TYPE_max_fragment_length:
+		extname = "max fragment length";
+		break;
+
+		case TLSEXT_TYPE_client_certificate_url:
+		extname = "client certificate URL";
+		break;
+
+		case TLSEXT_TYPE_trusted_ca_keys:
+		extname = "trusted CA keys";
+		break;
+
+		case TLSEXT_TYPE_truncated_hmac:
+		extname = "truncated HMAC";
+		break;
+
+		case TLSEXT_TYPE_status_request:
+		extname = "status request";
+		break;
+
+		case TLSEXT_TYPE_elliptic_curves:
+		extname = "elliptic curves";
+		break;
+
+		case TLSEXT_TYPE_ec_point_formats:
+		extname = "EC point formats";
+		break;
+
+		case TLSEXT_TYPE_session_ticket:
+		extname = "server ticket";
+		break;
+
+		case TLSEXT_TYPE_renegotiate:
+		extname = "renegotiate";
+		break;
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+		case TLSEXT_TYPE_opaque_prf_input:
+		extname = "opaque PRF input";
+		break;
+#endif
+
+		default:
+		extname = "unknown";
+		break;
+
+		}
+	
+	BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n",
+			client_server ? "server": "client",
+			extname, type, len);
+	BIO_dump(bio, (char *)data, len);
+	(void)BIO_flush(bio);
+	}
+
+int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
+	{
+	unsigned char *buffer, result[EVP_MAX_MD_SIZE];
+	unsigned int length, resultlength;
+	union {
+		struct sockaddr sa;
+		struct sockaddr_in s4;
+#if OPENSSL_USE_IPV6
+		struct sockaddr_in6 s6;
+#endif
+	} peer;
+
+	/* Initialize a random secret */
+	if (!cookie_initialized)
+		{
+		if (!RAND_bytes(cookie_secret, COOKIE_SECRET_LENGTH))
+			{
+			BIO_printf(bio_err,"error setting random cookie secret\n");
+			return 0;
+			}
+		cookie_initialized = 1;
+		}
+
+	/* Read peer information */
+	(void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
+
+	/* Create buffer with peer's address and port */
+	length = 0;
+	switch (peer.sa.sa_family)
+		{
+	case AF_INET:
+		length += sizeof(struct in_addr);
+		length += sizeof(peer.s4.sin_port);
+		break;
+#if OPENSSL_USE_IPV6
+	case AF_INET6:
+		length += sizeof(struct in6_addr);
+		length += sizeof(peer.s6.sin6_port);
+		break;
+#endif
+	default:
+		OPENSSL_assert(0);
+		break;
+		}
+	buffer = OPENSSL_malloc(length);
+
+	if (buffer == NULL)
+		{
+		BIO_printf(bio_err,"out of memory\n");
+		return 0;
+		}
+
+	switch (peer.sa.sa_family)
+		{
+	case AF_INET:
+		memcpy(buffer,
+		       &peer.s4.sin_port,
+		       sizeof(peer.s4.sin_port));
+		memcpy(buffer + sizeof(peer.s4.sin_port),
+		       &peer.s4.sin_addr,
+		       sizeof(struct in_addr));
+		break;
+#if OPENSSL_USE_IPV6
+	case AF_INET6:
+		memcpy(buffer,
+		       &peer.s6.sin6_port,
+		       sizeof(peer.s6.sin6_port));
+		memcpy(buffer + sizeof(peer.s6.sin6_port),
+		       &peer.s6.sin6_addr,
+		       sizeof(struct in6_addr));
+		break;
+#endif
+	default:
+		OPENSSL_assert(0);
+		break;
+		}
+
+	/* Calculate HMAC of buffer using the secret */
+	HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
+	     buffer, length, result, &resultlength);
+	OPENSSL_free(buffer);
+
+	memcpy(cookie, result, resultlength);
+	*cookie_len = resultlength;
+
+	return 1;
+	}
+
+int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int cookie_len)
+	{
+	unsigned char *buffer, result[EVP_MAX_MD_SIZE];
+	unsigned int length, resultlength;
+	union {
+		struct sockaddr sa;
+		struct sockaddr_in s4;
+#if OPENSSL_USE_IPV6
+		struct sockaddr_in6 s6;
+#endif
+	} peer;
+
+	/* If secret isn't initialized yet, the cookie can't be valid */
+	if (!cookie_initialized)
+		return 0;
+
+	/* Read peer information */
+	(void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
+
+	/* Create buffer with peer's address and port */
+	length = 0;
+	switch (peer.sa.sa_family)
+		{
+	case AF_INET:
+		length += sizeof(struct in_addr);
+		length += sizeof(peer.s4.sin_port);
+		break;
+#if OPENSSL_USE_IPV6
+	case AF_INET6:
+		length += sizeof(struct in6_addr);
+		length += sizeof(peer.s6.sin6_port);
+		break;
+#endif
+	default:
+		OPENSSL_assert(0);
+		break;
+		}
+	buffer = OPENSSL_malloc(length);
+	
+	if (buffer == NULL)
+		{
+		BIO_printf(bio_err,"out of memory\n");
+		return 0;
+		}
+
+	switch (peer.sa.sa_family)
+		{
+	case AF_INET:
+		memcpy(buffer,
+		       &peer.s4.sin_port,
+		       sizeof(peer.s4.sin_port));
+		memcpy(buffer + sizeof(peer.s4.sin_port),
+		       &peer.s4.sin_addr,
+		       sizeof(struct in_addr));
+		break;
+#if OPENSSL_USE_IPV6
+	case AF_INET6:
+		memcpy(buffer,
+		       &peer.s6.sin6_port,
+		       sizeof(peer.s6.sin6_port));
+		memcpy(buffer + sizeof(peer.s6.sin6_port),
+		       &peer.s6.sin6_addr,
+		       sizeof(struct in6_addr));
+		break;
+#endif
+	default:
+		OPENSSL_assert(0);
+		break;
+		}
+
+	/* Calculate HMAC of buffer using the secret */
+	HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
+	     buffer, length, result, &resultlength);
+	OPENSSL_free(buffer);
+
+	if (cookie_len == resultlength && memcmp(result, cookie, resultlength) == 0)
+		return 1;
+
+	return 0;
+	}
diff --git a/openssl/apps/s_client.c b/openssl/apps/s_client.c
new file mode 100644
index 0000000..b951513
--- /dev/null
+++ b/openssl/apps/s_client.c
@@ -0,0 +1,1873 @@
+/* apps/s_client.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/e_os2.h>
+#ifdef OPENSSL_NO_STDIO
+#define APPS_WIN16
+#endif
+
+/* With IPv6, it looks like Digital has mixed up the proper order of
+   recursive header file inclusion, resulting in the compiler complaining
+   that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
+   is needed to have fileno() declared correctly...  So let's define u_int */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
+#define __U_INT
+typedef unsigned int u_int;
+#endif
+
+#define USE_SOCKETS
+#include "apps.h"
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/ocsp.h>
+#include <openssl/bn.h>
+#include "s_apps.h"
+#include "timeouts.h"
+
+#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
+/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
+#undef FIONBIO
+#endif
+
+#if defined(OPENSSL_SYS_BEOS_R5)
+#include <fcntl.h>
+#endif
+
+#undef PROG
+#define PROG	s_client_main
+
+/*#define SSL_HOST_NAME	"www.netscape.com" */
+/*#define SSL_HOST_NAME	"193.118.187.102" */
+#define SSL_HOST_NAME	"localhost"
+
+/*#define TEST_CERT "client.pem" */ /* no default cert. */
+
+#undef BUFSIZZ
+#define BUFSIZZ 1024*8
+
+extern int verify_depth;
+extern int verify_error;
+extern int verify_return_error;
+
+#ifdef FIONBIO
+static int c_nbio=0;
+#endif
+static int c_Pause=0;
+static int c_debug=0;
+#ifndef OPENSSL_NO_TLSEXT
+static int c_tlsextdebug=0;
+static int c_status_req=0;
+#endif
+static int c_msg=0;
+static int c_showcerts=0;
+
+static void sc_usage(void);
+static void print_stuff(BIO *berr,SSL *con,int full);
+#ifndef OPENSSL_NO_TLSEXT
+static int ocsp_resp_cb(SSL *s, void *arg);
+#endif
+static BIO *bio_c_out=NULL;
+static int c_quiet=0;
+static int c_ign_eof=0;
+
+#ifndef OPENSSL_NO_PSK
+/* Default PSK identity and key */
+static char *psk_identity="Client_identity";
+/*char *psk_key=NULL;  by default PSK is not used */
+
+static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity,
+	unsigned int max_identity_len, unsigned char *psk,
+	unsigned int max_psk_len)
+	{
+	unsigned int psk_len = 0;
+	int ret;
+        BIGNUM *bn=NULL;
+
+	if (c_debug)
+		BIO_printf(bio_c_out, "psk_client_cb\n");
+	if (!hint)
+                {
+                /* no ServerKeyExchange message*/
+		if (c_debug)
+			BIO_printf(bio_c_out,"NULL received PSK identity hint, continuing anyway\n");
+                }
+        else if (c_debug)
+		BIO_printf(bio_c_out, "Received PSK identity hint '%s'\n", hint);
+
+	/* lookup PSK identity and PSK key based on the given identity hint here */
+	ret = BIO_snprintf(identity, max_identity_len, "%s", psk_identity);
+	if (ret < 0 || (unsigned int)ret > max_identity_len)
+		goto out_err;
+	if (c_debug)
+		BIO_printf(bio_c_out, "created identity '%s' len=%d\n", identity, ret);
+        ret=BN_hex2bn(&bn, psk_key);
+        if (!ret)
+                {
+                BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", psk_key);
+                if (bn)
+                        BN_free(bn);
+                return 0;
+                }
+
+        if ((unsigned int)BN_num_bytes(bn) > max_psk_len)
+                {
+                BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n",
+                        max_psk_len, BN_num_bytes(bn));
+                BN_free(bn);
+                return 0;
+                }
+
+        psk_len=BN_bn2bin(bn, psk);
+        BN_free(bn);
+        if (psk_len == 0)
+                goto out_err;
+
+	if (c_debug)
+		BIO_printf(bio_c_out, "created PSK len=%d\n", psk_len);
+
+        return psk_len;
+ out_err:
+	if (c_debug)
+		BIO_printf(bio_err, "Error in PSK client callback\n");
+        return 0;
+	}
+#endif
+
+static void sc_usage(void)
+	{
+	BIO_printf(bio_err,"usage: s_client args\n");
+	BIO_printf(bio_err,"\n");
+	BIO_printf(bio_err," -host host     - use -connect instead\n");
+	BIO_printf(bio_err," -port port     - use -connect instead\n");
+	BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR);
+
+	BIO_printf(bio_err," -verify arg   - turn on peer certificate verification\n");
+	BIO_printf(bio_err," -cert arg     - certificate file to use, PEM format assumed\n");
+	BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n");
+	BIO_printf(bio_err," -key arg      - Private key file to use, in cert file if\n");
+	BIO_printf(bio_err,"                 not specified but cert file is.\n");
+	BIO_printf(bio_err," -keyform arg  - key format (PEM or DER) PEM default\n");
+	BIO_printf(bio_err," -pass arg     - private key file pass phrase source\n");
+	BIO_printf(bio_err," -CApath arg   - PEM format directory of CA's\n");
+	BIO_printf(bio_err," -CAfile arg   - PEM format file of CA's\n");
+	BIO_printf(bio_err," -reconnect    - Drop and re-make the connection with the same Session-ID\n");
+	BIO_printf(bio_err," -pause        - sleep(1) after each read(2) and write(2) system call\n");
+	BIO_printf(bio_err," -showcerts    - show all certificates in the chain\n");
+	BIO_printf(bio_err," -debug        - extra output\n");
+#ifdef WATT32
+	BIO_printf(bio_err," -wdebug       - WATT-32 tcp debugging\n");
+#endif
+	BIO_printf(bio_err," -msg          - Show protocol messages\n");
+	BIO_printf(bio_err," -nbio_test    - more ssl protocol testing\n");
+	BIO_printf(bio_err," -state        - print the 'ssl' states\n");
+#ifdef FIONBIO
+	BIO_printf(bio_err," -nbio         - Run with non-blocking IO\n");
+#endif
+	BIO_printf(bio_err," -crlf         - convert LF from terminal into CRLF\n");
+	BIO_printf(bio_err," -quiet        - no s_client output\n");
+	BIO_printf(bio_err," -ign_eof      - ignore input eof (default when -quiet)\n");
+	BIO_printf(bio_err," -no_ign_eof   - don't ignore input eof\n");
+#ifndef OPENSSL_NO_PSK
+	BIO_printf(bio_err," -psk_identity arg - PSK identity\n");
+	BIO_printf(bio_err," -psk arg      - PSK in hex (without 0x)\n");
+# ifndef OPENSSL_NO_JPAKE
+	BIO_printf(bio_err," -jpake arg    - JPAKE secret to use\n");
+# endif
+#endif
+	BIO_printf(bio_err," -ssl2         - just use SSLv2\n");
+	BIO_printf(bio_err," -ssl3         - just use SSLv3\n");
+	BIO_printf(bio_err," -tls1         - just use TLSv1\n");
+	BIO_printf(bio_err," -dtls1        - just use DTLSv1\n");    
+	BIO_printf(bio_err," -mtu          - set the link layer MTU\n");
+	BIO_printf(bio_err," -no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
+	BIO_printf(bio_err," -bugs         - Switch on all SSL implementation bug workarounds\n");
+	BIO_printf(bio_err," -serverpref   - Use server's cipher preferences (only SSLv2)\n");
+	BIO_printf(bio_err," -cipher       - preferred cipher to use, use the 'openssl ciphers'\n");
+	BIO_printf(bio_err,"                 command to see what is available\n");
+	BIO_printf(bio_err," -starttls prot - use the STARTTLS command before starting TLS\n");
+	BIO_printf(bio_err,"                 for those protocols that support it, where\n");
+	BIO_printf(bio_err,"                 'prot' defines which one to assume.  Currently,\n");
+	BIO_printf(bio_err,"                 only \"smtp\", \"pop3\", \"imap\", \"ftp\" and \"xmpp\"\n");
+	BIO_printf(bio_err,"                 are supported.\n");
+#ifndef OPENSSL_NO_ENGINE
+	BIO_printf(bio_err," -engine id    - Initialise and use the specified engine\n");
+#endif
+	BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+	BIO_printf(bio_err," -sess_out arg - file to write SSL session to\n");
+	BIO_printf(bio_err," -sess_in arg  - file to read SSL session from\n");
+#ifndef OPENSSL_NO_TLSEXT
+	BIO_printf(bio_err," -servername host  - Set TLS extension servername in ClientHello\n");
+	BIO_printf(bio_err," -tlsextdebug      - hex dump of all TLS extensions received\n");
+	BIO_printf(bio_err," -status           - request certificate status from server\n");
+	BIO_printf(bio_err," -no_ticket        - disable use of RFC4507bis session tickets\n");
+# ifndef OPENSSL_NO_NEXTPROTONEG
+	BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
+# endif
+	BIO_printf(bio_err," -cutthrough       - enable 1-RTT full-handshake for strong ciphers\n");
+#endif
+	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
+	}
+
+#ifndef OPENSSL_NO_TLSEXT
+
+/* This is a context that we pass to callbacks */
+typedef struct tlsextctx_st {
+   BIO * biodebug;
+   int ack;
+} tlsextctx;
+
+
+static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
+	{
+	tlsextctx * p = (tlsextctx *) arg;
+	const char * hn= SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
+	if (SSL_get_servername_type(s) != -1) 
+ 	        p->ack = !SSL_session_reused(s) && hn != NULL;
+	else 
+		BIO_printf(bio_err,"Can't use SSL_get_servername\n");
+	
+	return SSL_TLSEXT_ERR_OK;
+	}
+
+# ifndef OPENSSL_NO_NEXTPROTONEG
+/* This the context that we pass to next_proto_cb */
+typedef struct tlsextnextprotoctx_st {
+	unsigned char *data;
+	unsigned short len;
+	int status;
+} tlsextnextprotoctx;
+
+static tlsextnextprotoctx next_proto;
+
+static int next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
+	{
+	tlsextnextprotoctx *ctx = arg;
+
+	if (!c_quiet)
+		{
+		/* We can assume that |in| is syntactically valid. */
+		unsigned i;
+		BIO_printf(bio_c_out, "Protocols advertised by server: ");
+		for (i = 0; i < inlen; )
+			{
+			if (i)
+				BIO_write(bio_c_out, ", ", 2);
+			BIO_write(bio_c_out, &in[i + 1], in[i]);
+			i += in[i] + 1;
+			}
+		BIO_write(bio_c_out, "\n", 1);
+		}
+
+	ctx->status = SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len);
+	return SSL_TLSEXT_ERR_OK;
+	}
+# endif  /* ndef OPENSSL_NO_NEXTPROTONEG */
+#endif
+
+enum
+{
+	PROTO_OFF	= 0,
+	PROTO_SMTP,
+	PROTO_POP3,
+	PROTO_IMAP,
+	PROTO_FTP,
+	PROTO_XMPP
+};
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	unsigned int off=0, clr=0;
+	SSL *con=NULL;
+	int s,k,width,state=0;
+	char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL;
+	int cbuf_len,cbuf_off;
+	int sbuf_len,sbuf_off;
+	fd_set readfds,writefds;
+	short port=PORT;
+	int full_log=1;
+	char *host=SSL_HOST_NAME;
+	char *cert_file=NULL,*key_file=NULL;
+	int cert_format = FORMAT_PEM, key_format = FORMAT_PEM;
+	char *passarg = NULL, *pass = NULL;
+	X509 *cert = NULL;
+	EVP_PKEY *key = NULL;
+	char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
+	int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
+	int cutthrough=0;
+	int crlf=0;
+	int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
+	SSL_CTX *ctx=NULL;
+	int ret=1,in_init=1,i,nbio_test=0;
+	int starttls_proto = PROTO_OFF;
+	int prexit = 0;
+	X509_VERIFY_PARAM *vpm = NULL;
+	int badarg = 0;
+	const SSL_METHOD *meth=NULL;
+	int socket_type=SOCK_STREAM;
+	BIO *sbio;
+	char *inrand=NULL;
+	int mbuf_len=0;
+	struct timeval timeout, *timeoutp;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine_id=NULL;
+	char *ssl_client_engine_id=NULL;
+	ENGINE *ssl_client_engine=NULL;
+#endif
+	ENGINE *e=NULL;
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
+	struct timeval tv;
+#if defined(OPENSSL_SYS_BEOS_R5)
+	int stdin_set = 0;
+#endif
+#endif
+#ifndef OPENSSL_NO_TLSEXT
+	char *servername = NULL; 
+        tlsextctx tlsextcbp = 
+        {NULL,0};
+# ifndef OPENSSL_NO_NEXTPROTONEG
+	const char *next_proto_neg_in = NULL;
+# endif
+#endif
+	char *sess_in = NULL;
+	char *sess_out = NULL;
+	struct sockaddr peer;
+	int peerlen = sizeof(peer);
+	int enable_timeouts = 0 ;
+	long socket_mtu = 0;
+#ifndef OPENSSL_NO_JPAKE
+	char *jpake_secret = NULL;
+#endif
+
+#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
+	meth=SSLv23_client_method();
+#elif !defined(OPENSSL_NO_SSL3)
+	meth=SSLv3_client_method();
+#elif !defined(OPENSSL_NO_SSL2)
+	meth=SSLv2_client_method();
+#endif
+
+	apps_startup();
+	c_Pause=0;
+	c_quiet=0;
+	c_ign_eof=0;
+	c_debug=0;
+	c_msg=0;
+	c_showcerts=0;
+
+	if (bio_err == NULL)
+		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	if (	((cbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
+		((sbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
+		((mbuf=OPENSSL_malloc(BUFSIZZ)) == NULL))
+		{
+		BIO_printf(bio_err,"out of memory\n");
+		goto end;
+		}
+
+	verify_depth=0;
+	verify_error=X509_V_OK;
+#ifdef FIONBIO
+	c_nbio=0;
+#endif
+
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if	(strcmp(*argv,"-host") == 0)
+			{
+			if (--argc < 1) goto bad;
+			host= *(++argv);
+			}
+		else if	(strcmp(*argv,"-port") == 0)
+			{
+			if (--argc < 1) goto bad;
+			port=atoi(*(++argv));
+			if (port == 0) goto bad;
+			}
+		else if (strcmp(*argv,"-connect") == 0)
+			{
+			if (--argc < 1) goto bad;
+			if (!extract_host_port(*(++argv),&host,NULL,&port))
+				goto bad;
+			}
+		else if	(strcmp(*argv,"-verify") == 0)
+			{
+			verify=SSL_VERIFY_PEER;
+			if (--argc < 1) goto bad;
+			verify_depth=atoi(*(++argv));
+			BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
+			}
+		else if	(strcmp(*argv,"-cert") == 0)
+			{
+			if (--argc < 1) goto bad;
+			cert_file= *(++argv);
+			}
+		else if	(strcmp(*argv,"-sess_out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			sess_out = *(++argv);
+			}
+		else if	(strcmp(*argv,"-sess_in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			sess_in = *(++argv);
+			}
+		else if	(strcmp(*argv,"-certform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			cert_format = str2fmt(*(++argv));
+			}
+		else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm))
+			{
+			if (badarg)
+				goto bad;
+			continue;
+			}
+		else if (strcmp(*argv,"-verify_return_error") == 0)
+			verify_return_error = 1;
+		else if	(strcmp(*argv,"-prexit") == 0)
+			prexit=1;
+		else if	(strcmp(*argv,"-crlf") == 0)
+			crlf=1;
+		else if	(strcmp(*argv,"-quiet") == 0)
+			{
+			c_quiet=1;
+			c_ign_eof=1;
+			}
+		else if	(strcmp(*argv,"-ign_eof") == 0)
+			c_ign_eof=1;
+		else if	(strcmp(*argv,"-no_ign_eof") == 0)
+			c_ign_eof=0;
+		else if	(strcmp(*argv,"-pause") == 0)
+			c_Pause=1;
+		else if	(strcmp(*argv,"-debug") == 0)
+			c_debug=1;
+#ifndef OPENSSL_NO_TLSEXT
+		else if	(strcmp(*argv,"-tlsextdebug") == 0)
+			c_tlsextdebug=1;
+		else if	(strcmp(*argv,"-status") == 0)
+			c_status_req=1;
+#endif
+#ifdef WATT32
+		else if (strcmp(*argv,"-wdebug") == 0)
+			dbug_init();
+#endif
+		else if	(strcmp(*argv,"-msg") == 0)
+			c_msg=1;
+		else if	(strcmp(*argv,"-showcerts") == 0)
+			c_showcerts=1;
+		else if	(strcmp(*argv,"-nbio_test") == 0)
+			nbio_test=1;
+		else if	(strcmp(*argv,"-state") == 0)
+			state=1;
+#ifndef OPENSSL_NO_PSK
+                else if (strcmp(*argv,"-psk_identity") == 0)
+			{
+			if (--argc < 1) goto bad;
+			psk_identity=*(++argv);
+			}
+                else if (strcmp(*argv,"-psk") == 0)
+			{
+                        size_t j;
+
+			if (--argc < 1) goto bad;
+			psk_key=*(++argv);
+			for (j = 0; j < strlen(psk_key); j++)
+                                {
+                                if (isxdigit((int)psk_key[j]))
+                                        continue;
+                                BIO_printf(bio_err,"Not a hex number '%s'\n",*argv);
+                                goto bad;
+                                }
+			}
+#endif
+#ifndef OPENSSL_NO_SSL2
+		else if	(strcmp(*argv,"-ssl2") == 0)
+			meth=SSLv2_client_method();
+#endif
+#ifndef OPENSSL_NO_SSL3
+		else if	(strcmp(*argv,"-ssl3") == 0)
+			meth=SSLv3_client_method();
+#endif
+#ifndef OPENSSL_NO_TLS1
+		else if	(strcmp(*argv,"-tls1") == 0)
+			meth=TLSv1_client_method();
+#endif
+#ifndef OPENSSL_NO_DTLS1
+		else if	(strcmp(*argv,"-dtls1") == 0)
+			{
+			meth=DTLSv1_client_method();
+			socket_type=SOCK_DGRAM;
+			}
+		else if (strcmp(*argv,"-timeout") == 0)
+			enable_timeouts=1;
+		else if (strcmp(*argv,"-mtu") == 0)
+			{
+			if (--argc < 1) goto bad;
+			socket_mtu = atol(*(++argv));
+			}
+#endif
+		else if (strcmp(*argv,"-bugs") == 0)
+			bugs=1;
+		else if	(strcmp(*argv,"-keyform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			key_format = str2fmt(*(++argv));
+			}
+		else if	(strcmp(*argv,"-pass") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passarg = *(++argv);
+			}
+		else if	(strcmp(*argv,"-key") == 0)
+			{
+			if (--argc < 1) goto bad;
+			key_file= *(++argv);
+			}
+		else if	(strcmp(*argv,"-reconnect") == 0)
+			{
+			reconnect=5;
+			}
+		else if	(strcmp(*argv,"-CApath") == 0)
+			{
+			if (--argc < 1) goto bad;
+			CApath= *(++argv);
+			}
+		else if	(strcmp(*argv,"-CAfile") == 0)
+			{
+			if (--argc < 1) goto bad;
+			CAfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-no_tls1") == 0)
+			off|=SSL_OP_NO_TLSv1;
+		else if (strcmp(*argv,"-no_ssl3") == 0)
+			off|=SSL_OP_NO_SSLv3;
+		else if (strcmp(*argv,"-no_ssl2") == 0)
+			off|=SSL_OP_NO_SSLv2;
+		else if	(strcmp(*argv,"-no_comp") == 0)
+			{ off|=SSL_OP_NO_COMPRESSION; }
+#ifndef OPENSSL_NO_TLSEXT
+		else if	(strcmp(*argv,"-no_ticket") == 0)
+			{ off|=SSL_OP_NO_TICKET; }
+# ifndef OPENSSL_NO_NEXTPROTONEG
+		else if (strcmp(*argv,"-nextprotoneg") == 0)
+			{
+			if (--argc < 1) goto bad;
+			next_proto_neg_in = *(++argv);
+			}
+# endif
+#endif
+		else if (strcmp(*argv,"-cutthrough") == 0)
+			cutthrough=1;
+		else if (strcmp(*argv,"-serverpref") == 0)
+			off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
+		else if (strcmp(*argv,"-legacy_renegotiation") == 0)
+			off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
+		else if	(strcmp(*argv,"-legacy_server_connect") == 0)
+			{ off|=SSL_OP_LEGACY_SERVER_CONNECT; }
+		else if	(strcmp(*argv,"-no_legacy_server_connect") == 0)
+			{ clr|=SSL_OP_LEGACY_SERVER_CONNECT; }
+		else if	(strcmp(*argv,"-cipher") == 0)
+			{
+			if (--argc < 1) goto bad;
+			cipher= *(++argv);
+			}
+#ifdef FIONBIO
+		else if (strcmp(*argv,"-nbio") == 0)
+			{ c_nbio=1; }
+#endif
+		else if	(strcmp(*argv,"-starttls") == 0)
+			{
+			if (--argc < 1) goto bad;
+			++argv;
+			if (strcmp(*argv,"smtp") == 0)
+				starttls_proto = PROTO_SMTP;
+			else if (strcmp(*argv,"pop3") == 0)
+				starttls_proto = PROTO_POP3;
+			else if (strcmp(*argv,"imap") == 0)
+				starttls_proto = PROTO_IMAP;
+			else if (strcmp(*argv,"ftp") == 0)
+				starttls_proto = PROTO_FTP;
+			else if (strcmp(*argv, "xmpp") == 0)
+				starttls_proto = PROTO_XMPP;
+			else
+				goto bad;
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if	(strcmp(*argv,"-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine_id = *(++argv);
+			}
+		else if	(strcmp(*argv,"-ssl_client_engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			ssl_client_engine_id = *(++argv);
+			}
+#endif
+		else if (strcmp(*argv,"-rand") == 0)
+			{
+			if (--argc < 1) goto bad;
+			inrand= *(++argv);
+			}
+#ifndef OPENSSL_NO_TLSEXT
+		else if (strcmp(*argv,"-servername") == 0)
+			{
+			if (--argc < 1) goto bad;
+			servername= *(++argv);
+			/* meth=TLSv1_client_method(); */
+			}
+#endif
+#ifndef OPENSSL_NO_JPAKE
+		else if (strcmp(*argv,"-jpake") == 0)
+			{
+			if (--argc < 1) goto bad;
+			jpake_secret = *++argv;
+			}
+#endif
+		else
+			{
+			BIO_printf(bio_err,"unknown option %s\n",*argv);
+			badop=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+	if (badop)
+		{
+bad:
+		sc_usage();
+		goto end;
+		}
+
+#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
+	if (jpake_secret)
+		{
+		if (psk_key)
+			{
+			BIO_printf(bio_err,
+				   "Can't use JPAKE and PSK together\n");
+			goto end;
+			}
+		psk_identity = "JPAKE";
+		}
+
+	if (cipher)
+		{
+		BIO_printf(bio_err, "JPAKE sets cipher to PSK\n");
+		goto end;
+		}
+	cipher = "PSK";
+#endif
+
+	OpenSSL_add_ssl_algorithms();
+	SSL_load_error_strings();
+
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+	next_proto.status = -1;
+	if (next_proto_neg_in)
+		{
+		next_proto.data = next_protos_parse(&next_proto.len, next_proto_neg_in);
+		if (next_proto.data == NULL)
+			{
+			BIO_printf(bio_err, "Error parsing -nextprotoneg argument\n");
+			goto end;
+			}
+		}
+	else
+		next_proto.data = NULL;
+#endif
+
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine_id, 1);
+	if (ssl_client_engine_id)
+		{
+		ssl_client_engine = ENGINE_by_id(ssl_client_engine_id);
+		if (!ssl_client_engine)
+			{
+			BIO_printf(bio_err,
+					"Error getting client auth engine\n");
+			goto end;
+			}
+		}
+
+#endif
+	if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
+		{
+		BIO_printf(bio_err, "Error getting password\n");
+		goto end;
+		}
+
+	if (key_file == NULL)
+		key_file = cert_file;
+
+
+	if (key_file)
+
+		{
+
+		key = load_key(bio_err, key_file, key_format, 0, pass, e,
+			       "client certificate private key file");
+		if (!key)
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+
+		}
+
+	if (cert_file)
+
+		{
+		cert = load_cert(bio_err,cert_file,cert_format,
+				NULL, e, "client certificate file");
+
+		if (!cert)
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+
+	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
+		&& !RAND_status())
+		{
+		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
+		}
+	if (inrand != NULL)
+		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+			app_RAND_load_files(inrand));
+
+	if (bio_c_out == NULL)
+		{
+		if (c_quiet && !c_debug && !c_msg)
+			{
+			bio_c_out=BIO_new(BIO_s_null());
+			}
+		else
+			{
+			if (bio_c_out == NULL)
+				bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE);
+			}
+		}
+
+	ctx=SSL_CTX_new(meth);
+	if (ctx == NULL)
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (vpm)
+		SSL_CTX_set1_param(ctx, vpm);
+
+#ifndef OPENSSL_NO_ENGINE
+	if (ssl_client_engine)
+		{
+		if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine))
+			{
+			BIO_puts(bio_err, "Error setting client auth engine\n");
+			ERR_print_errors(bio_err);
+			ENGINE_free(ssl_client_engine);
+			goto end;
+			}
+		ENGINE_free(ssl_client_engine);
+		}
+#endif
+
+#ifndef OPENSSL_NO_PSK
+#ifdef OPENSSL_NO_JPAKE
+	if (psk_key != NULL)
+#else
+	if (psk_key != NULL || jpake_secret)
+#endif
+		{
+		if (c_debug)
+			BIO_printf(bio_c_out, "PSK key given or JPAKE in use, setting client callback\n");
+		SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
+		}
+#endif
+	if (bugs)
+		SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
+	else
+		SSL_CTX_set_options(ctx,off);
+
+	if (clr)
+		SSL_CTX_clear_options(ctx, clr);
+	/* DTLS: partial reads end up discarding unread UDP bytes :-( 
+	 * Setting read ahead solves this problem.
+	 */
+	if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
+
+	/* Enable handshake cutthrough for client connections using
+	 * strong ciphers. */
+	if (cutthrough)
+		{
+		int ssl_mode = SSL_CTX_get_mode(ctx);
+		ssl_mode |= SSL_MODE_HANDSHAKE_CUTTHROUGH;
+		SSL_CTX_set_mode(ctx, ssl_mode);
+		}
+
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+	if (next_proto.data)
+		SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
+#endif
+
+	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
+	if (cipher != NULL)
+		if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
+		BIO_printf(bio_err,"error setting cipher list\n");
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+#if 0
+	else
+		SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER"));
+#endif
+
+	SSL_CTX_set_verify(ctx,verify,verify_callback);
+	if (!set_cert_key_stuff(ctx,cert,key))
+		goto end;
+
+	if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
+		(!SSL_CTX_set_default_verify_paths(ctx)))
+		{
+		/* BIO_printf(bio_err,"error setting default verify locations\n"); */
+		ERR_print_errors(bio_err);
+		/* goto end; */
+		}
+
+#ifndef OPENSSL_NO_TLSEXT
+	if (servername != NULL)
+		{
+		tlsextcbp.biodebug = bio_err;
+		SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
+		SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
+		}
+#endif
+
+	con=SSL_new(ctx);
+	if (sess_in)
+		{
+		SSL_SESSION *sess;
+		BIO *stmp = BIO_new_file(sess_in, "r");
+		if (!stmp)
+			{
+			BIO_printf(bio_err, "Can't open session file %s\n",
+						sess_in);
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
+		BIO_free(stmp);
+		if (!sess)
+			{
+			BIO_printf(bio_err, "Can't open session file %s\n",
+						sess_in);
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		SSL_set_session(con, sess);
+		SSL_SESSION_free(sess);
+		}
+#ifndef OPENSSL_NO_TLSEXT
+	if (servername != NULL)
+		{
+		if (!SSL_set_tlsext_host_name(con,servername))
+			{
+			BIO_printf(bio_err,"Unable to set TLS servername extension.\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+#endif
+#ifndef OPENSSL_NO_KRB5
+	if (con  &&  (con->kssl_ctx = kssl_ctx_new()) != NULL)
+                {
+                kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVER, host);
+		}
+#endif	/* OPENSSL_NO_KRB5  */
+/*	SSL_set_cipher_list(con,"RC4-MD5"); */
+#if 0
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	SSL_set_tlsext_opaque_prf_input(con, "Test client", 11);
+#endif
+#endif
+
+re_start:
+
+	if (init_client(&s,host,port,socket_type) == 0)
+		{
+		BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
+		SHUTDOWN(s);
+		goto end;
+		}
+	BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s);
+
+#ifdef FIONBIO
+	if (c_nbio)
+		{
+		unsigned long l=1;
+		BIO_printf(bio_c_out,"turning on non blocking io\n");
+		if (BIO_socket_ioctl(s,FIONBIO,&l) < 0)
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+#endif                                              
+	if (c_Pause & 0x01) con->debug=1;
+
+	if ( SSL_version(con) == DTLS1_VERSION)
+		{
+
+		sbio=BIO_new_dgram(s,BIO_NOCLOSE);
+		if (getsockname(s, &peer, (void *)&peerlen) < 0)
+			{
+			BIO_printf(bio_err, "getsockname:errno=%d\n",
+				get_last_socket_error());
+			SHUTDOWN(s);
+			goto end;
+			}
+
+		(void)BIO_ctrl_set_connected(sbio, 1, &peer);
+
+		if (enable_timeouts)
+			{
+			timeout.tv_sec = 0;
+			timeout.tv_usec = DGRAM_RCV_TIMEOUT;
+			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
+			
+			timeout.tv_sec = 0;
+			timeout.tv_usec = DGRAM_SND_TIMEOUT;
+			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
+			}
+
+		if (socket_mtu > 28)
+			{
+			SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
+			SSL_set_mtu(con, socket_mtu - 28);
+			}
+		else
+			/* want to do MTU discovery */
+			BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
+		}
+	else
+		sbio=BIO_new_socket(s,BIO_NOCLOSE);
+
+	if (nbio_test)
+		{
+		BIO *test;
+
+		test=BIO_new(BIO_f_nbio_test());
+		sbio=BIO_push(test,sbio);
+		}
+
+	if (c_debug)
+		{
+		con->debug=1;
+		BIO_set_callback(sbio,bio_dump_callback);
+		BIO_set_callback_arg(sbio,(char *)bio_c_out);
+		}
+	if (c_msg)
+		{
+		SSL_set_msg_callback(con, msg_cb);
+		SSL_set_msg_callback_arg(con, bio_c_out);
+		}
+#ifndef OPENSSL_NO_TLSEXT
+	if (c_tlsextdebug)
+		{
+		SSL_set_tlsext_debug_callback(con, tlsext_cb);
+		SSL_set_tlsext_debug_arg(con, bio_c_out);
+		}
+	if (c_status_req)
+		{
+		SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp);
+		SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb);
+		SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out);
+#if 0
+{
+STACK_OF(OCSP_RESPID) *ids = sk_OCSP_RESPID_new_null();
+OCSP_RESPID *id = OCSP_RESPID_new();
+id->value.byKey = ASN1_OCTET_STRING_new();
+id->type = V_OCSP_RESPID_KEY;
+ASN1_STRING_set(id->value.byKey, "Hello World", -1);
+sk_OCSP_RESPID_push(ids, id);
+SSL_set_tlsext_status_ids(con, ids);
+}
+#endif
+		}
+#endif
+#ifndef OPENSSL_NO_JPAKE
+	if (jpake_secret)
+		jpake_client_auth(bio_c_out, sbio, jpake_secret);
+#endif
+
+	SSL_set_bio(con,sbio,sbio);
+	SSL_set_connect_state(con);
+
+	/* ok, lets connect */
+	width=SSL_get_fd(con)+1;
+
+	read_tty=1;
+	write_tty=0;
+	tty_on=0;
+	read_ssl=1;
+	write_ssl=1;
+	
+	cbuf_len=0;
+	cbuf_off=0;
+	sbuf_len=0;
+	sbuf_off=0;
+
+	/* This is an ugly hack that does a lot of assumptions */
+	/* We do have to handle multi-line responses which may come
+ 	   in a single packet or not. We therefore have to use
+	   BIO_gets() which does need a buffering BIO. So during
+	   the initial chitchat we do push a buffering BIO into the
+	   chain that is removed again later on to not disturb the
+	   rest of the s_client operation. */
+	if (starttls_proto == PROTO_SMTP)
+		{
+		int foundit=0;
+		BIO *fbio = BIO_new(BIO_f_buffer());
+		BIO_push(fbio, sbio);
+		/* wait for multi-line response to end from SMTP */
+		do
+			{
+			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
+			}
+		while (mbuf_len>3 && mbuf[3]=='-');
+		/* STARTTLS command requires EHLO... */
+		BIO_printf(fbio,"EHLO openssl.client.net\r\n");
+		(void)BIO_flush(fbio);
+		/* wait for multi-line response to end EHLO SMTP response */
+		do
+			{
+			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
+			if (strstr(mbuf,"STARTTLS"))
+				foundit=1;
+			}
+		while (mbuf_len>3 && mbuf[3]=='-');
+		(void)BIO_flush(fbio);
+		BIO_pop(fbio);
+		BIO_free(fbio);
+		if (!foundit)
+			BIO_printf(bio_err,
+				   "didn't found starttls in server response,"
+				   " try anyway...\n");
+		BIO_printf(sbio,"STARTTLS\r\n");
+		BIO_read(sbio,sbuf,BUFSIZZ);
+		}
+	else if (starttls_proto == PROTO_POP3)
+		{
+		BIO_read(sbio,mbuf,BUFSIZZ);
+		BIO_printf(sbio,"STLS\r\n");
+		BIO_read(sbio,sbuf,BUFSIZZ);
+		}
+	else if (starttls_proto == PROTO_IMAP)
+		{
+		int foundit=0;
+		BIO *fbio = BIO_new(BIO_f_buffer());
+		BIO_push(fbio, sbio);
+		BIO_gets(fbio,mbuf,BUFSIZZ);
+		/* STARTTLS command requires CAPABILITY... */
+		BIO_printf(fbio,". CAPABILITY\r\n");
+		(void)BIO_flush(fbio);
+		/* wait for multi-line CAPABILITY response */
+		do
+			{
+			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
+			if (strstr(mbuf,"STARTTLS"))
+				foundit=1;
+			}
+		while (mbuf_len>3 && mbuf[0]!='.');
+		(void)BIO_flush(fbio);
+		BIO_pop(fbio);
+		BIO_free(fbio);
+		if (!foundit)
+			BIO_printf(bio_err,
+				   "didn't found STARTTLS in server response,"
+				   " try anyway...\n");
+		BIO_printf(sbio,". STARTTLS\r\n");
+		BIO_read(sbio,sbuf,BUFSIZZ);
+		}
+	else if (starttls_proto == PROTO_FTP)
+		{
+		BIO *fbio = BIO_new(BIO_f_buffer());
+		BIO_push(fbio, sbio);
+		/* wait for multi-line response to end from FTP */
+		do
+			{
+			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
+			}
+		while (mbuf_len>3 && mbuf[3]=='-');
+		(void)BIO_flush(fbio);
+		BIO_pop(fbio);
+		BIO_free(fbio);
+		BIO_printf(sbio,"AUTH TLS\r\n");
+		BIO_read(sbio,sbuf,BUFSIZZ);
+		}
+	if (starttls_proto == PROTO_XMPP)
+		{
+		int seen = 0;
+		BIO_printf(sbio,"<stream:stream "
+		    "xmlns:stream='http://etherx.jabber.org/streams' "
+		    "xmlns='jabber:client' to='%s' version='1.0'>", host);
+		seen = BIO_read(sbio,mbuf,BUFSIZZ);
+		mbuf[seen] = 0;
+		while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'"))
+			{
+			if (strstr(mbuf, "/stream:features>"))
+				goto shut;
+			seen = BIO_read(sbio,mbuf,BUFSIZZ);
+			mbuf[seen] = 0;
+			}
+		BIO_printf(sbio, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
+		seen = BIO_read(sbio,sbuf,BUFSIZZ);
+		sbuf[seen] = 0;
+		if (!strstr(sbuf, "<proceed"))
+			goto shut;
+		mbuf[0] = 0;
+		}
+
+	for (;;)
+		{
+		FD_ZERO(&readfds);
+		FD_ZERO(&writefds);
+
+		if ((SSL_version(con) == DTLS1_VERSION) &&
+			DTLSv1_get_timeout(con, &timeout))
+			timeoutp = &timeout;
+		else
+			timeoutp = NULL;
+
+		if (SSL_in_init(con) && !SSL_total_renegotiations(con))
+			{
+			in_init=1;
+			tty_on=0;
+			}
+		else
+			{
+			tty_on=1;
+			if (in_init)
+				{
+				in_init=0;
+#if 0 /* This test doesn't really work as intended (needs to be fixed) */
+#ifndef OPENSSL_NO_TLSEXT
+				if (servername != NULL && !SSL_session_reused(con))
+					{
+					BIO_printf(bio_c_out,"Server did %sacknowledge servername extension.\n",tlsextcbp.ack?"":"not ");
+					}
+#endif
+#endif
+				if (sess_out)
+					{
+					BIO *stmp = BIO_new_file(sess_out, "w");
+					if (stmp)
+						{
+						PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con));
+						BIO_free(stmp);
+						}
+					else 
+						BIO_printf(bio_err, "Error writing session file %s\n", sess_out);
+					}
+				print_stuff(bio_c_out,con,full_log);
+				if (full_log > 0) full_log--;
+
+				if (starttls_proto)
+					{
+					BIO_printf(bio_err,"%s",mbuf);
+					/* We don't need to know any more */
+					starttls_proto = PROTO_OFF;
+					}
+
+				if (reconnect)
+					{
+					reconnect--;
+					BIO_printf(bio_c_out,"drop connection and then reconnect\n");
+					SSL_shutdown(con);
+					SSL_set_connect_state(con);
+					SHUTDOWN(SSL_get_fd(con));
+					goto re_start;
+					}
+				}
+			}
+
+		ssl_pending = read_ssl && SSL_pending(con);
+
+		if (!ssl_pending)
+			{
+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined (OPENSSL_SYS_BEOS_R5)
+			if (tty_on)
+				{
+				if (read_tty)  openssl_fdset(fileno(stdin),&readfds);
+				if (write_tty) openssl_fdset(fileno(stdout),&writefds);
+				}
+			if (read_ssl)
+				openssl_fdset(SSL_get_fd(con),&readfds);
+			if (write_ssl)
+				openssl_fdset(SSL_get_fd(con),&writefds);
+#else
+			if(!tty_on || !write_tty) {
+				if (read_ssl)
+					openssl_fdset(SSL_get_fd(con),&readfds);
+				if (write_ssl)
+					openssl_fdset(SSL_get_fd(con),&writefds);
+			}
+#endif
+/*			printf("mode tty(%d %d%d) ssl(%d%d)\n",
+				tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
+
+			/* Note: under VMS with SOCKETSHR the second parameter
+			 * is currently of type (int *) whereas under other
+			 * systems it is (void *) if you don't have a cast it
+			 * will choke the compiler: if you do have a cast then
+			 * you can either go for (int *) or (void *).
+			 */
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
+                        /* Under Windows/DOS we make the assumption that we can
+			 * always write to the tty: therefore if we need to
+			 * write to the tty we just fall through. Otherwise
+			 * we timeout the select every second and see if there
+			 * are any keypresses. Note: this is a hack, in a proper
+			 * Windows application we wouldn't do this.
+			 */
+			i=0;
+			if(!write_tty) {
+				if(read_tty) {
+					tv.tv_sec = 1;
+					tv.tv_usec = 0;
+					i=select(width,(void *)&readfds,(void *)&writefds,
+						 NULL,&tv);
+#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
+					if(!i && (!_kbhit() || !read_tty) ) continue;
+#else
+					if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;
+#endif
+				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
+					 NULL,timeoutp);
+			}
+#elif defined(OPENSSL_SYS_NETWARE)
+			if(!write_tty) {
+				if(read_tty) {
+					tv.tv_sec = 1;
+					tv.tv_usec = 0;
+					i=select(width,(void *)&readfds,(void *)&writefds,
+						NULL,&tv);
+				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
+					NULL,timeoutp);
+			}
+#elif defined(OPENSSL_SYS_BEOS_R5)
+			/* Under BeOS-R5 the situation is similar to DOS */
+			i=0;
+			stdin_set = 0;
+			(void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
+			if(!write_tty) {
+				if(read_tty) {
+					tv.tv_sec = 1;
+					tv.tv_usec = 0;
+					i=select(width,(void *)&readfds,(void *)&writefds,
+						 NULL,&tv);
+					if (read(fileno(stdin), sbuf, 0) >= 0)
+						stdin_set = 1;
+					if (!i && (stdin_set != 1 || !read_tty))
+						continue;
+				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
+					 NULL,timeoutp);
+			}
+			(void)fcntl(fileno(stdin), F_SETFL, 0);
+#else
+			i=select(width,(void *)&readfds,(void *)&writefds,
+				 NULL,timeoutp);
+#endif
+			if ( i < 0)
+				{
+				BIO_printf(bio_err,"bad select %d\n",
+				get_last_socket_error());
+				goto shut;
+				/* goto end; */
+				}
+			}
+
+		if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0)
+			{
+			BIO_printf(bio_err,"TIMEOUT occured\n");
+			}
+
+		if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
+			{
+			k=SSL_write(con,&(cbuf[cbuf_off]),
+				(unsigned int)cbuf_len);
+			switch (SSL_get_error(con,k))
+				{
+			case SSL_ERROR_NONE:
+				cbuf_off+=k;
+				cbuf_len-=k;
+				if (k <= 0) goto end;
+				/* we have done a  write(con,NULL,0); */
+				if (cbuf_len <= 0)
+					{
+					read_tty=1;
+					write_ssl=0;
+					}
+				else /* if (cbuf_len > 0) */
+					{
+					read_tty=0;
+					write_ssl=1;
+					}
+				break;
+			case SSL_ERROR_WANT_WRITE:
+				BIO_printf(bio_c_out,"write W BLOCK\n");
+				write_ssl=1;
+				read_tty=0;
+				break;
+			case SSL_ERROR_WANT_READ:
+				BIO_printf(bio_c_out,"write R BLOCK\n");
+				write_tty=0;
+				read_ssl=1;
+				write_ssl=0;
+				break;
+			case SSL_ERROR_WANT_X509_LOOKUP:
+				BIO_printf(bio_c_out,"write X BLOCK\n");
+				break;
+			case SSL_ERROR_ZERO_RETURN:
+				if (cbuf_len != 0)
+					{
+					BIO_printf(bio_c_out,"shutdown\n");
+					ret = 0;
+					goto shut;
+					}
+				else
+					{
+					read_tty=1;
+					write_ssl=0;
+					break;
+					}
+				
+			case SSL_ERROR_SYSCALL:
+				if ((k != 0) || (cbuf_len != 0))
+					{
+					BIO_printf(bio_err,"write:errno=%d\n",
+						get_last_socket_error());
+					goto shut;
+					}
+				else
+					{
+					read_tty=1;
+					write_ssl=0;
+					}
+				break;
+			case SSL_ERROR_SSL:
+				ERR_print_errors(bio_err);
+				goto shut;
+				}
+			}
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
+		/* Assume Windows/DOS/BeOS can always write */
+		else if (!ssl_pending && write_tty)
+#else
+		else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds))
+#endif
+			{
+#ifdef CHARSET_EBCDIC
+			ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len);
+#endif
+			i=raw_write_stdout(&(sbuf[sbuf_off]),sbuf_len);
+
+			if (i <= 0)
+				{
+				BIO_printf(bio_c_out,"DONE\n");
+				ret = 0;
+				goto shut;
+				/* goto end; */
+				}
+
+			sbuf_len-=i;;
+			sbuf_off+=i;
+			if (sbuf_len <= 0)
+				{
+				read_ssl=1;
+				write_tty=0;
+				}
+			}
+		else if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds))
+			{
+#ifdef RENEG
+{ static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } }
+#endif
+#if 1
+			k=SSL_read(con,sbuf,1024 /* BUFSIZZ */ );
+#else
+/* Demo for pending and peek :-) */
+			k=SSL_read(con,sbuf,16);
+{ char zbuf[10240]; 
+printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240));
+}
+#endif
+
+			switch (SSL_get_error(con,k))
+				{
+			case SSL_ERROR_NONE:
+				if (k <= 0)
+					goto end;
+				sbuf_off=0;
+				sbuf_len=k;
+
+				read_ssl=0;
+				write_tty=1;
+				break;
+			case SSL_ERROR_WANT_WRITE:
+				BIO_printf(bio_c_out,"read W BLOCK\n");
+				write_ssl=1;
+				read_tty=0;
+				break;
+			case SSL_ERROR_WANT_READ:
+				BIO_printf(bio_c_out,"read R BLOCK\n");
+				write_tty=0;
+				read_ssl=1;
+				if ((read_tty == 0) && (write_ssl == 0))
+					write_ssl=1;
+				break;
+			case SSL_ERROR_WANT_X509_LOOKUP:
+				BIO_printf(bio_c_out,"read X BLOCK\n");
+				break;
+			case SSL_ERROR_SYSCALL:
+				ret=get_last_socket_error();
+				BIO_printf(bio_err,"read:errno=%d\n",ret);
+				goto shut;
+			case SSL_ERROR_ZERO_RETURN:
+				BIO_printf(bio_c_out,"closed\n");
+				ret=0;
+				goto shut;
+			case SSL_ERROR_SSL:
+				ERR_print_errors(bio_err);
+				goto shut;
+				/* break; */
+				}
+			}
+
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
+#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
+		else if (_kbhit())
+#else
+		else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
+#endif
+#elif defined (OPENSSL_SYS_NETWARE)
+		else if (_kbhit())
+#elif defined(OPENSSL_SYS_BEOS_R5)
+		else if (stdin_set)
+#else
+		else if (FD_ISSET(fileno(stdin),&readfds))
+#endif
+			{
+			if (crlf)
+				{
+				int j, lf_num;
+
+				i=raw_read_stdin(cbuf,BUFSIZZ/2);
+				lf_num = 0;
+				/* both loops are skipped when i <= 0 */
+				for (j = 0; j < i; j++)
+					if (cbuf[j] == '\n')
+						lf_num++;
+				for (j = i-1; j >= 0; j--)
+					{
+					cbuf[j+lf_num] = cbuf[j];
+					if (cbuf[j] == '\n')
+						{
+						lf_num--;
+						i++;
+						cbuf[j+lf_num] = '\r';
+						}
+					}
+				assert(lf_num == 0);
+				}
+			else
+				i=raw_read_stdin(cbuf,BUFSIZZ);
+
+			if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q')))
+				{
+				BIO_printf(bio_err,"DONE\n");
+				ret=0;
+				goto shut;
+				}
+
+			if ((!c_ign_eof) && (cbuf[0] == 'R'))
+				{
+				BIO_printf(bio_err,"RENEGOTIATING\n");
+				SSL_renegotiate(con);
+				cbuf_len=0;
+				}
+			else
+				{
+				cbuf_len=i;
+				cbuf_off=0;
+#ifdef CHARSET_EBCDIC
+				ebcdic2ascii(cbuf, cbuf, i);
+#endif
+				}
+
+			write_ssl=1;
+			read_tty=0;
+			}
+		}
+
+	ret=0;
+shut:
+	if (in_init)
+		print_stuff(bio_c_out,con,full_log);
+	SSL_shutdown(con);
+	SHUTDOWN(SSL_get_fd(con));
+end:
+	if (con != NULL)
+		{
+		if (prexit != 0)
+			print_stuff(bio_c_out,con,1);
+		SSL_free(con);
+		}
+	if (ctx != NULL) SSL_CTX_free(ctx);
+	if (cert)
+		X509_free(cert);
+	if (key)
+		EVP_PKEY_free(key);
+	if (pass)
+		OPENSSL_free(pass);
+	if (cbuf != NULL) { OPENSSL_cleanse(cbuf,BUFSIZZ); OPENSSL_free(cbuf); }
+	if (sbuf != NULL) { OPENSSL_cleanse(sbuf,BUFSIZZ); OPENSSL_free(sbuf); }
+	if (mbuf != NULL) { OPENSSL_cleanse(mbuf,BUFSIZZ); OPENSSL_free(mbuf); }
+	if (bio_c_out != NULL)
+		{
+		BIO_free(bio_c_out);
+		bio_c_out=NULL;
+		}
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
+
+static void print_stuff(BIO *bio, SSL *s, int full)
+	{
+	X509 *peer=NULL;
+	char *p;
+	static const char *space="                ";
+	char buf[BUFSIZ];
+	STACK_OF(X509) *sk;
+	STACK_OF(X509_NAME) *sk2;
+	const SSL_CIPHER *c;
+	X509_NAME *xn;
+	int j,i;
+#ifndef OPENSSL_NO_COMP
+	const COMP_METHOD *comp, *expansion;
+#endif
+
+	if (full)
+		{
+		int got_a_chain = 0;
+
+		sk=SSL_get_peer_cert_chain(s);
+		if (sk != NULL)
+			{
+			got_a_chain = 1; /* we don't have it for SSL2 (yet) */
+
+			BIO_printf(bio,"---\nCertificate chain\n");
+			for (i=0; i<sk_X509_num(sk); i++)
+				{
+				X509_NAME_oneline(X509_get_subject_name(
+					sk_X509_value(sk,i)),buf,sizeof buf);
+				BIO_printf(bio,"%2d s:%s\n",i,buf);
+				X509_NAME_oneline(X509_get_issuer_name(
+					sk_X509_value(sk,i)),buf,sizeof buf);
+				BIO_printf(bio,"   i:%s\n",buf);
+				if (c_showcerts)
+					PEM_write_bio_X509(bio,sk_X509_value(sk,i));
+				}
+			}
+
+		BIO_printf(bio,"---\n");
+		peer=SSL_get_peer_certificate(s);
+		if (peer != NULL)
+			{
+			BIO_printf(bio,"Server certificate\n");
+			if (!(c_showcerts && got_a_chain)) /* Redundant if we showed the whole chain */
+				PEM_write_bio_X509(bio,peer);
+			X509_NAME_oneline(X509_get_subject_name(peer),
+				buf,sizeof buf);
+			BIO_printf(bio,"subject=%s\n",buf);
+			X509_NAME_oneline(X509_get_issuer_name(peer),
+				buf,sizeof buf);
+			BIO_printf(bio,"issuer=%s\n",buf);
+			}
+		else
+			BIO_printf(bio,"no peer certificate available\n");
+
+		sk2=SSL_get_client_CA_list(s);
+		if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0))
+			{
+			BIO_printf(bio,"---\nAcceptable client certificate CA names\n");
+			for (i=0; i<sk_X509_NAME_num(sk2); i++)
+				{
+				xn=sk_X509_NAME_value(sk2,i);
+				X509_NAME_oneline(xn,buf,sizeof(buf));
+				BIO_write(bio,buf,strlen(buf));
+				BIO_write(bio,"\n",1);
+				}
+			}
+		else
+			{
+			BIO_printf(bio,"---\nNo client certificate CA names sent\n");
+			}
+		p=SSL_get_shared_ciphers(s,buf,sizeof buf);
+		if (p != NULL)
+			{
+			/* This works only for SSL 2.  In later protocol
+			 * versions, the client does not know what other
+			 * ciphers (in addition to the one to be used
+			 * in the current connection) the server supports. */
+
+			BIO_printf(bio,"---\nCiphers common between both SSL endpoints:\n");
+			j=i=0;
+			while (*p)
+				{
+				if (*p == ':')
+					{
+					BIO_write(bio,space,15-j%25);
+					i++;
+					j=0;
+					BIO_write(bio,((i%3)?" ":"\n"),1);
+					}
+				else
+					{
+					BIO_write(bio,p,1);
+					j++;
+					}
+				p++;
+				}
+			BIO_write(bio,"\n",1);
+			}
+
+		BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n",
+			BIO_number_read(SSL_get_rbio(s)),
+			BIO_number_written(SSL_get_wbio(s)));
+		}
+	BIO_printf(bio,((s->hit)?"---\nReused, ":"---\nNew, "));
+	c=SSL_get_current_cipher(s);
+	BIO_printf(bio,"%s, Cipher is %s\n",
+		SSL_CIPHER_get_version(c),
+		SSL_CIPHER_get_name(c));
+	if (peer != NULL) {
+		EVP_PKEY *pktmp;
+		pktmp = X509_get_pubkey(peer);
+		BIO_printf(bio,"Server public key is %d bit\n",
+							 EVP_PKEY_bits(pktmp));
+		EVP_PKEY_free(pktmp);
+	}
+	BIO_printf(bio, "Secure Renegotiation IS%s supported\n",
+			SSL_get_secure_renegotiation_support(s) ? "" : " NOT");
+#ifndef OPENSSL_NO_COMP
+	comp=SSL_get_current_compression(s);
+	expansion=SSL_get_current_expansion(s);
+	BIO_printf(bio,"Compression: %s\n",
+		comp ? SSL_COMP_get_name(comp) : "NONE");
+	BIO_printf(bio,"Expansion: %s\n",
+		expansion ? SSL_COMP_get_name(expansion) : "NONE");
+#endif
+
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+	if (next_proto.status != -1) {
+		const unsigned char *proto;
+		unsigned int proto_len;
+		SSL_get0_next_proto_negotiated(s, &proto, &proto_len);
+		BIO_printf(bio, "Next protocol: (%d) ", next_proto.status);
+		BIO_write(bio, proto, proto_len);
+		BIO_write(bio, "\n", 1);
+	}
+#endif
+
+	SSL_SESSION_print(bio,SSL_get_session(s));
+	BIO_printf(bio,"---\n");
+	if (peer != NULL)
+		X509_free(peer);
+	/* flush, or debugging output gets mixed with http response */
+	(void)BIO_flush(bio);
+	}
+
+#ifndef OPENSSL_NO_TLSEXT
+
+static int ocsp_resp_cb(SSL *s, void *arg)
+	{
+	const unsigned char *p;
+	int len;
+	OCSP_RESPONSE *rsp;
+	len = SSL_get_tlsext_status_ocsp_resp(s, &p);
+	BIO_puts(arg, "OCSP response: ");
+	if (!p)
+		{
+		BIO_puts(arg, "no response sent\n");
+		return 1;
+		}
+	rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
+	if (!rsp)
+		{
+		BIO_puts(arg, "response parse error\n");
+		BIO_dump_indent(arg, (char *)p, len, 4);
+		return 0;
+		}
+	BIO_puts(arg, "\n======================================\n");
+	OCSP_RESPONSE_print(arg, rsp, 0);
+	BIO_puts(arg, "======================================\n");
+	OCSP_RESPONSE_free(rsp);
+	return 1;
+	}
+
+#endif
diff --git a/openssl/apps/s_server.c b/openssl/apps/s_server.c
new file mode 100644
index 0000000..a8e057c
--- /dev/null
+++ b/openssl/apps/s_server.c
@@ -0,0 +1,2752 @@
+/* apps/s_server.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+/* Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code */
+#ifdef OPENSSL_NO_DEPRECATED
+#undef OPENSSL_NO_DEPRECATED
+#endif
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/e_os2.h>
+#ifdef OPENSSL_NO_STDIO
+#define APPS_WIN16
+#endif
+
+#if !defined(OPENSSL_SYS_NETWARE)  /* conflicts with winsock2 stuff on netware */
+#include <sys/types.h>
+#endif
+
+/* With IPv6, it looks like Digital has mixed up the proper order of
+   recursive header file inclusion, resulting in the compiler complaining
+   that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
+   is needed to have fileno() declared correctly...  So let's define u_int */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
+#define __U_INT
+typedef unsigned int u_int;
+#endif
+
+#include <openssl/lhash.h>
+#include <openssl/bn.h>
+#define USE_SOCKETS
+#include "apps.h"
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include <openssl/rand.h>
+#include <openssl/ocsp.h>
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#include "s_apps.h"
+#include "timeouts.h"
+
+#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
+/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
+#undef FIONBIO
+#endif
+
+#if defined(OPENSSL_SYS_BEOS_R5)
+#include <fcntl.h>
+#endif
+
+#ifndef OPENSSL_NO_RSA
+static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength);
+#endif
+static int sv_body(char *hostname, int s, unsigned char *context);
+static int www_body(char *hostname, int s, unsigned char *context);
+static void close_accept_socket(void );
+static void sv_usage(void);
+static int init_ssl_connection(SSL *s);
+static void print_stats(BIO *bp,SSL_CTX *ctx);
+static int generate_session_id(const SSL *ssl, unsigned char *id,
+				unsigned int *id_len);
+#ifndef OPENSSL_NO_DH
+static DH *load_dh_param(const char *dhfile);
+static DH *get_dh512(void);
+#endif
+
+#ifdef MONOLITH
+static void s_server_init(void);
+#endif
+
+#ifndef OPENSSL_NO_DH
+static unsigned char dh512_p[]={
+	0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
+	0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
+	0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
+	0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
+	0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
+	0x47,0x74,0xE8,0x33,
+	};
+static unsigned char dh512_g[]={
+	0x02,
+	};
+
+static DH *get_dh512(void)
+	{
+	DH *dh=NULL;
+
+	if ((dh=DH_new()) == NULL) return(NULL);
+	dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
+	dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
+	if ((dh->p == NULL) || (dh->g == NULL))
+		return(NULL);
+	return(dh);
+	}
+#endif
+
+
+/* static int load_CA(SSL_CTX *ctx, char *file);*/
+
+#undef BUFSIZZ
+#define BUFSIZZ	16*1024
+static int bufsize=BUFSIZZ;
+static int accept_socket= -1;
+
+#define TEST_CERT	"server.pem"
+#ifndef OPENSSL_NO_TLSEXT
+#define TEST_CERT2	"server2.pem"
+#endif
+#undef PROG
+#define PROG		s_server_main
+
+extern int verify_depth, verify_return_error;
+
+static char *cipher=NULL;
+static int s_server_verify=SSL_VERIFY_NONE;
+static int s_server_session_id_context = 1; /* anything will do */
+static const char *s_cert_file=TEST_CERT,*s_key_file=NULL;
+#ifndef OPENSSL_NO_TLSEXT
+static const char *s_cert_file2=TEST_CERT2,*s_key_file2=NULL;
+#endif
+static char *s_dcert_file=NULL,*s_dkey_file=NULL;
+#ifdef FIONBIO
+static int s_nbio=0;
+#endif
+static int s_nbio_test=0;
+int s_crlf=0;
+static SSL_CTX *ctx=NULL;
+#ifndef OPENSSL_NO_TLSEXT
+static SSL_CTX *ctx2=NULL;
+#endif
+static int www=0;
+
+static BIO *bio_s_out=NULL;
+static int s_debug=0;
+#ifndef OPENSSL_NO_TLSEXT
+static int s_tlsextdebug=0;
+static int s_tlsextstatus=0;
+static int cert_status_cb(SSL *s, void *arg);
+#endif
+static int s_msg=0;
+static int s_quiet=0;
+
+static int hack=0;
+#ifndef OPENSSL_NO_ENGINE
+static char *engine_id=NULL;
+#endif
+static const char *session_id_prefix=NULL;
+
+static int enable_timeouts = 0;
+static long socket_mtu;
+#ifndef OPENSSL_NO_DTLS1
+static int cert_chain = 0;
+#endif
+
+#ifndef OPENSSL_NO_PSK
+static char *psk_identity="Client_identity";
+char *psk_key=NULL; /* by default PSK is not used */
+
+static unsigned int psk_server_cb(SSL *ssl, const char *identity,
+	unsigned char *psk, unsigned int max_psk_len)
+	{
+	unsigned int psk_len = 0;
+	int ret;
+	BIGNUM *bn = NULL;
+
+	if (s_debug)
+		BIO_printf(bio_s_out,"psk_server_cb\n");
+	if (!identity)
+		{
+		BIO_printf(bio_err,"Error: client did not send PSK identity\n");
+		goto out_err;
+		}
+	if (s_debug)
+		BIO_printf(bio_s_out,"identity_len=%d identity=%s\n",
+			identity ? (int)strlen(identity) : 0, identity);
+
+	/* here we could lookup the given identity e.g. from a database */
+  	if (strcmp(identity, psk_identity) != 0)
+		{
+                BIO_printf(bio_s_out, "PSK error: client identity not found"
+			   " (got '%s' expected '%s')\n", identity,
+			   psk_identity);
+		goto out_err;
+                }
+	if (s_debug)
+		BIO_printf(bio_s_out, "PSK client identity found\n");
+
+	/* convert the PSK key to binary */
+	ret = BN_hex2bn(&bn, psk_key);
+	if (!ret)
+		{
+		BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", psk_key);
+		if (bn)
+			BN_free(bn);
+		return 0;
+		}
+	if (BN_num_bytes(bn) > (int)max_psk_len)
+		{
+		BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n",
+			max_psk_len, BN_num_bytes(bn));
+		BN_free(bn);
+		return 0;
+		}
+
+	ret = BN_bn2bin(bn, psk);
+	BN_free(bn);
+
+	if (ret < 0)
+		goto out_err;
+	psk_len = (unsigned int)ret;
+
+	if (s_debug)
+		BIO_printf(bio_s_out, "fetched PSK len=%d\n", psk_len);
+        return psk_len;
+ out_err:
+	if (s_debug)
+		BIO_printf(bio_err, "Error in PSK server callback\n");
+	return 0;
+        }
+#endif
+
+#ifdef MONOLITH
+static void s_server_init(void)
+	{
+	accept_socket=-1;
+	cipher=NULL;
+	s_server_verify=SSL_VERIFY_NONE;
+	s_dcert_file=NULL;
+	s_dkey_file=NULL;
+	s_cert_file=TEST_CERT;
+	s_key_file=NULL;
+#ifndef OPENSSL_NO_TLSEXT
+	s_cert_file2=TEST_CERT2;
+	s_key_file2=NULL;
+	ctx2=NULL;
+#endif
+#ifdef FIONBIO
+	s_nbio=0;
+#endif
+	s_nbio_test=0;
+	ctx=NULL;
+	www=0;
+
+	bio_s_out=NULL;
+	s_debug=0;
+	s_msg=0;
+	s_quiet=0;
+	hack=0;
+#ifndef OPENSSL_NO_ENGINE
+	engine_id=NULL;
+#endif
+	}
+#endif
+
+static void sv_usage(void)
+	{
+	BIO_printf(bio_err,"usage: s_server [args ...]\n");
+	BIO_printf(bio_err,"\n");
+	BIO_printf(bio_err," -accept arg   - port to accept on (default is %d)\n",PORT);
+	BIO_printf(bio_err," -context arg  - set session ID context\n");
+	BIO_printf(bio_err," -verify arg   - turn on peer certificate verification\n");
+	BIO_printf(bio_err," -Verify arg   - turn on peer certificate verification, must have a cert.\n");
+	BIO_printf(bio_err," -cert arg     - certificate file to use\n");
+	BIO_printf(bio_err,"                 (default is %s)\n",TEST_CERT);
+	BIO_printf(bio_err," -crl_check    - check the peer certificate has not been revoked by its CA.\n" \
+	                   "                 The CRL(s) are appended to the certificate file\n");
+	BIO_printf(bio_err," -crl_check_all - check the peer certificate has not been revoked by its CA\n" \
+	                   "                 or any other CRL in the CA chain. CRL(s) are appened to the\n" \
+	                   "                 the certificate file.\n");
+	BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n");
+	BIO_printf(bio_err," -key arg      - Private Key file to use, in cert file if\n");
+	BIO_printf(bio_err,"                 not specified (default is %s)\n",TEST_CERT);
+	BIO_printf(bio_err," -keyform arg  - key format (PEM, DER or ENGINE) PEM default\n");
+	BIO_printf(bio_err," -pass arg     - private key file pass phrase source\n");
+	BIO_printf(bio_err," -dcert arg    - second certificate file to use (usually for DSA)\n");
+	BIO_printf(bio_err," -dcertform x  - second certificate format (PEM or DER) PEM default\n");
+	BIO_printf(bio_err," -dkey arg     - second private key file to use (usually for DSA)\n");
+	BIO_printf(bio_err," -dkeyform arg - second key format (PEM, DER or ENGINE) PEM default\n");
+	BIO_printf(bio_err," -dpass arg    - second private key file pass phrase source\n");
+	BIO_printf(bio_err," -dhparam arg  - DH parameter file to use, in cert file if not specified\n");
+	BIO_printf(bio_err,"                 or a default set of parameters is used\n");
+#ifndef OPENSSL_NO_ECDH
+	BIO_printf(bio_err," -named_curve arg  - Elliptic curve name to use for ephemeral ECDH keys.\n" \
+	                   "                 Use \"openssl ecparam -list_curves\" for all names\n" \
+	                   "                 (default is nistp256).\n");
+#endif
+#ifdef FIONBIO
+	BIO_printf(bio_err," -nbio         - Run with non-blocking IO\n");
+#endif
+	BIO_printf(bio_err," -nbio_test    - test with the non-blocking test bio\n");
+	BIO_printf(bio_err," -crlf         - convert LF from terminal into CRLF\n");
+	BIO_printf(bio_err," -debug        - Print more output\n");
+	BIO_printf(bio_err," -msg          - Show protocol messages\n");
+	BIO_printf(bio_err," -state        - Print the SSL states\n");
+	BIO_printf(bio_err," -CApath arg   - PEM format directory of CA's\n");
+	BIO_printf(bio_err," -CAfile arg   - PEM format file of CA's\n");
+	BIO_printf(bio_err," -nocert       - Don't use any certificates (Anon-DH)\n");
+	BIO_printf(bio_err," -cipher arg   - play with 'openssl ciphers' to see what goes here\n");
+	BIO_printf(bio_err," -serverpref   - Use server's cipher preferences\n");
+	BIO_printf(bio_err," -quiet        - No server output\n");
+	BIO_printf(bio_err," -no_tmp_rsa   - Do not generate a tmp RSA key\n");
+#ifndef OPENSSL_NO_PSK
+	BIO_printf(bio_err," -psk_hint arg - PSK identity hint to use\n");
+	BIO_printf(bio_err," -psk arg      - PSK in hex (without 0x)\n");
+# ifndef OPENSSL_NO_JPAKE
+	BIO_printf(bio_err," -jpake arg    - JPAKE secret to use\n");
+# endif
+#endif
+	BIO_printf(bio_err," -ssl2         - Just talk SSLv2\n");
+	BIO_printf(bio_err," -ssl3         - Just talk SSLv3\n");
+	BIO_printf(bio_err," -tls1         - Just talk TLSv1\n");
+	BIO_printf(bio_err," -dtls1        - Just talk DTLSv1\n");
+	BIO_printf(bio_err," -timeout      - Enable timeouts\n");
+	BIO_printf(bio_err," -mtu          - Set link layer MTU\n");
+	BIO_printf(bio_err," -chain        - Read a certificate chain\n");
+	BIO_printf(bio_err," -no_ssl2      - Just disable SSLv2\n");
+	BIO_printf(bio_err," -no_ssl3      - Just disable SSLv3\n");
+	BIO_printf(bio_err," -no_tls1      - Just disable TLSv1\n");
+#ifndef OPENSSL_NO_DH
+	BIO_printf(bio_err," -no_dhe       - Disable ephemeral DH\n");
+#endif
+#ifndef OPENSSL_NO_ECDH
+	BIO_printf(bio_err," -no_ecdhe     - Disable ephemeral ECDH\n");
+#endif
+	BIO_printf(bio_err," -bugs         - Turn on SSL bug compatibility\n");
+	BIO_printf(bio_err," -www          - Respond to a 'GET /' with a status page\n");
+	BIO_printf(bio_err," -WWW          - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
+	BIO_printf(bio_err," -HTTP         - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
+        BIO_printf(bio_err,"                 with the assumption it contains a complete HTTP response.\n");
+#ifndef OPENSSL_NO_ENGINE
+	BIO_printf(bio_err," -engine id    - Initialise and use the specified engine\n");
+#endif
+	BIO_printf(bio_err," -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n");
+	BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+#ifndef OPENSSL_NO_TLSEXT
+	BIO_printf(bio_err," -servername host - servername for HostName TLS extension\n");
+	BIO_printf(bio_err," -servername_fatal - on mismatch send fatal alert (default warning alert)\n");
+	BIO_printf(bio_err," -cert2 arg    - certificate file to use for servername\n");
+	BIO_printf(bio_err,"                 (default is %s)\n",TEST_CERT2);
+	BIO_printf(bio_err," -key2 arg     - Private Key file to use for servername, in cert file if\n");
+	BIO_printf(bio_err,"                 not specified (default is %s)\n",TEST_CERT2);
+	BIO_printf(bio_err," -tlsextdebug  - hex dump of all TLS extensions received\n");
+	BIO_printf(bio_err," -no_ticket    - disable use of RFC4507bis session tickets\n");
+	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
+# ifndef OPENSSL_NO_NEXTPROTONEG
+	BIO_printf(bio_err," -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n");
+# endif
+#endif
+	}
+
+static int local_argc=0;
+static char **local_argv;
+
+#ifdef CHARSET_EBCDIC
+static int ebcdic_new(BIO *bi);
+static int ebcdic_free(BIO *a);
+static int ebcdic_read(BIO *b, char *out, int outl);
+static int ebcdic_write(BIO *b, const char *in, int inl);
+static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr);
+static int ebcdic_gets(BIO *bp, char *buf, int size);
+static int ebcdic_puts(BIO *bp, const char *str);
+
+#define BIO_TYPE_EBCDIC_FILTER	(18|0x0200)
+static BIO_METHOD methods_ebcdic=
+	{
+	BIO_TYPE_EBCDIC_FILTER,
+	"EBCDIC/ASCII filter",
+	ebcdic_write,
+	ebcdic_read,
+	ebcdic_puts,
+	ebcdic_gets,
+	ebcdic_ctrl,
+	ebcdic_new,
+	ebcdic_free,
+	};
+
+typedef struct
+{
+	size_t	alloced;
+	char	buff[1];
+} EBCDIC_OUTBUFF;
+
+BIO_METHOD *BIO_f_ebcdic_filter()
+{
+	return(&methods_ebcdic);
+}
+
+static int ebcdic_new(BIO *bi)
+{
+	EBCDIC_OUTBUFF *wbuf;
+
+	wbuf = (EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024);
+	wbuf->alloced = 1024;
+	wbuf->buff[0] = '\0';
+
+	bi->ptr=(char *)wbuf;
+	bi->init=1;
+	bi->flags=0;
+	return(1);
+}
+
+static int ebcdic_free(BIO *a)
+{
+	if (a == NULL) return(0);
+	if (a->ptr != NULL)
+		OPENSSL_free(a->ptr);
+	a->ptr=NULL;
+	a->init=0;
+	a->flags=0;
+	return(1);
+}
+	
+static int ebcdic_read(BIO *b, char *out, int outl)
+{
+	int ret=0;
+
+	if (out == NULL || outl == 0) return(0);
+	if (b->next_bio == NULL) return(0);
+
+	ret=BIO_read(b->next_bio,out,outl);
+	if (ret > 0)
+		ascii2ebcdic(out,out,ret);
+	return(ret);
+}
+
+static int ebcdic_write(BIO *b, const char *in, int inl)
+{
+	EBCDIC_OUTBUFF *wbuf;
+	int ret=0;
+	int num;
+	unsigned char n;
+
+	if ((in == NULL) || (inl <= 0)) return(0);
+	if (b->next_bio == NULL) return(0);
+
+	wbuf=(EBCDIC_OUTBUFF *)b->ptr;
+
+	if (inl > (num = wbuf->alloced))
+	{
+		num = num + num;  /* double the size */
+		if (num < inl)
+			num = inl;
+		OPENSSL_free(wbuf);
+		wbuf=(EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num);
+
+		wbuf->alloced = num;
+		wbuf->buff[0] = '\0';
+
+		b->ptr=(char *)wbuf;
+	}
+
+	ebcdic2ascii(wbuf->buff, in, inl);
+
+	ret=BIO_write(b->next_bio, wbuf->buff, inl);
+
+	return(ret);
+}
+
+static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	long ret;
+
+	if (b->next_bio == NULL) return(0);
+	switch (cmd)
+	{
+	case BIO_CTRL_DUP:
+		ret=0L;
+		break;
+	default:
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	}
+	return(ret);
+}
+
+static int ebcdic_gets(BIO *bp, char *buf, int size)
+{
+	int i, ret=0;
+	if (bp->next_bio == NULL) return(0);
+/*	return(BIO_gets(bp->next_bio,buf,size));*/
+	for (i=0; i<size-1; ++i)
+	{
+		ret = ebcdic_read(bp,&buf[i],1);
+		if (ret <= 0)
+			break;
+		else if (buf[i] == '\n')
+		{
+			++i;
+			break;
+		}
+	}
+	if (i < size)
+		buf[i] = '\0';
+	return (ret < 0 && i == 0) ? ret : i;
+}
+
+static int ebcdic_puts(BIO *bp, const char *str)
+{
+	if (bp->next_bio == NULL) return(0);
+	return ebcdic_write(bp, str, strlen(str));
+}
+#endif
+
+#ifndef OPENSSL_NO_TLSEXT
+
+/* This is a context that we pass to callbacks */
+typedef struct tlsextctx_st {
+   char * servername;
+   BIO * biodebug;
+   int extension_error;
+} tlsextctx;
+
+
+static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
+	{
+	tlsextctx * p = (tlsextctx *) arg;
+	const char * servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
+        if (servername && p->biodebug) 
+		BIO_printf(p->biodebug,"Hostname in TLS extension: \"%s\"\n",servername);
+        
+	if (!p->servername)
+		return SSL_TLSEXT_ERR_NOACK;
+	
+	if (servername)
+		{
+    		if (strcmp(servername,p->servername)) 
+			return p->extension_error;
+		if (ctx2)
+			{
+			BIO_printf(p->biodebug,"Switching server context.\n");
+			SSL_set_SSL_CTX(s,ctx2);
+			}     
+		}
+	return SSL_TLSEXT_ERR_OK;
+}
+
+/* Structure passed to cert status callback */
+
+typedef struct tlsextstatusctx_st {
+   /* Default responder to use */
+   char *host, *path, *port;
+   int use_ssl;
+   int timeout;
+   BIO *err;
+   int verbose;
+} tlsextstatusctx;
+
+static tlsextstatusctx tlscstatp = {NULL, NULL, NULL, 0, -1, NULL, 0};
+
+/* Certificate Status callback. This is called when a client includes a
+ * certificate status request extension.
+ *
+ * This is a simplified version. It examines certificates each time and
+ * makes one OCSP responder query for each request.
+ *
+ * A full version would store details such as the OCSP certificate IDs and
+ * minimise the number of OCSP responses by caching them until they were
+ * considered "expired".
+ */
+
+static int cert_status_cb(SSL *s, void *arg)
+	{
+	tlsextstatusctx *srctx = arg;
+	BIO *err = srctx->err;
+	char *host, *port, *path;
+	int use_ssl;
+	unsigned char *rspder = NULL;
+	int rspderlen;
+	STACK_OF(OPENSSL_STRING) *aia = NULL;
+	X509 *x = NULL;
+	X509_STORE_CTX inctx;
+	X509_OBJECT obj;
+	OCSP_REQUEST *req = NULL;
+	OCSP_RESPONSE *resp = NULL;
+	OCSP_CERTID *id = NULL;
+	STACK_OF(X509_EXTENSION) *exts;
+	int ret = SSL_TLSEXT_ERR_NOACK;
+	int i;
+#if 0
+STACK_OF(OCSP_RESPID) *ids;
+SSL_get_tlsext_status_ids(s, &ids);
+BIO_printf(err, "cert_status: received %d ids\n", sk_OCSP_RESPID_num(ids));
+#endif
+	if (srctx->verbose)
+		BIO_puts(err, "cert_status: callback called\n");
+	/* Build up OCSP query from server certificate */
+	x = SSL_get_certificate(s);
+	aia = X509_get1_ocsp(x);
+	if (aia)
+		{
+		if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
+			&host, &port, &path, &use_ssl))
+			{
+			BIO_puts(err, "cert_status: can't parse AIA URL\n");
+			goto err;
+			}
+		if (srctx->verbose)
+			BIO_printf(err, "cert_status: AIA URL: %s\n",
+					sk_OPENSSL_STRING_value(aia, 0));
+		}
+	else
+		{
+		if (!srctx->host)
+			{
+			BIO_puts(srctx->err, "cert_status: no AIA and no default responder URL\n");
+			goto done;
+			}
+		host = srctx->host;
+		path = srctx->path;
+		port = srctx->port;
+		use_ssl = srctx->use_ssl;
+		}
+		
+	if (!X509_STORE_CTX_init(&inctx,
+				SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)),
+				NULL, NULL))
+		goto err;
+	if (X509_STORE_get_by_subject(&inctx,X509_LU_X509,
+				X509_get_issuer_name(x),&obj) <= 0)
+		{
+		BIO_puts(err, "cert_status: Can't retrieve issuer certificate.\n");
+		X509_STORE_CTX_cleanup(&inctx);
+		goto done;
+		}
+	req = OCSP_REQUEST_new();
+	if (!req)
+		goto err;
+	id = OCSP_cert_to_id(NULL, x, obj.data.x509);
+	X509_free(obj.data.x509);
+	X509_STORE_CTX_cleanup(&inctx);
+	if (!id)
+		goto err;
+	if (!OCSP_request_add0_id(req, id))
+		goto err;
+	id = NULL;
+	/* Add any extensions to the request */
+	SSL_get_tlsext_status_exts(s, &exts);
+	for (i = 0; i < sk_X509_EXTENSION_num(exts); i++)
+		{
+		X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
+		if (!OCSP_REQUEST_add_ext(req, ext, -1))
+			goto err;
+		}
+	resp = process_responder(err, req, host, path, port, use_ssl, NULL,
+					srctx->timeout);
+	if (!resp)
+		{
+		BIO_puts(err, "cert_status: error querying responder\n");
+		goto done;
+		}
+	rspderlen = i2d_OCSP_RESPONSE(resp, &rspder);
+	if (rspderlen <= 0)
+		goto err;
+	SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen);
+	if (srctx->verbose)
+		{
+		BIO_puts(err, "cert_status: ocsp response sent:\n");
+		OCSP_RESPONSE_print(err, resp, 2);
+		}
+	ret = SSL_TLSEXT_ERR_OK;
+	done:
+	if (ret != SSL_TLSEXT_ERR_OK)
+		ERR_print_errors(err);
+	if (aia)
+		{
+		OPENSSL_free(host);
+		OPENSSL_free(path);
+		OPENSSL_free(port);
+		X509_email_free(aia);
+		}
+	if (id)
+		OCSP_CERTID_free(id);
+	if (req)
+		OCSP_REQUEST_free(req);
+	if (resp)
+		OCSP_RESPONSE_free(resp);
+	return ret;
+	err:
+	ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+	goto done;
+	}
+
+# ifndef OPENSSL_NO_NEXTPROTONEG
+/* This is the context that we pass to next_proto_cb */
+typedef struct tlsextnextprotoctx_st {
+	unsigned char *data;
+	unsigned int len;
+} tlsextnextprotoctx;
+
+static int next_proto_cb(SSL *s, const unsigned char **data, unsigned int *len, void *arg)
+	{
+	tlsextnextprotoctx *next_proto = arg;
+
+	*data = next_proto->data;
+	*len = next_proto->len;
+
+	return SSL_TLSEXT_ERR_OK;
+	}
+# endif  /* ndef OPENSSL_NO_NPN */
+#endif
+
+int MAIN(int, char **);
+
+#ifndef OPENSSL_NO_JPAKE
+static char *jpake_secret = NULL;
+#endif
+
+int MAIN(int argc, char *argv[])
+	{
+	X509_VERIFY_PARAM *vpm = NULL;
+	int badarg = 0;
+	short port=PORT;
+	char *CApath=NULL,*CAfile=NULL;
+	unsigned char *context = NULL;
+	char *dhfile = NULL;
+#ifndef OPENSSL_NO_ECDH
+	char *named_curve = NULL;
+#endif
+	int badop=0,bugs=0;
+	int ret=1;
+	int off=0;
+	int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;
+	int state=0;
+	const SSL_METHOD *meth=NULL;
+	int socket_type=SOCK_STREAM;
+	ENGINE *e=NULL;
+	char *inrand=NULL;
+	int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
+	char *passarg = NULL, *pass = NULL;
+	char *dpassarg = NULL, *dpass = NULL;
+	int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
+	X509 *s_cert = NULL, *s_dcert = NULL;
+	EVP_PKEY *s_key = NULL, *s_dkey = NULL;
+	int no_cache = 0;
+#ifndef OPENSSL_NO_TLSEXT
+	EVP_PKEY *s_key2 = NULL;
+	X509 *s_cert2 = NULL;
+#endif
+#ifndef OPENSSL_NO_TLSEXT
+        tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING};
+# ifndef OPENSSL_NO_NEXTPROTONEG
+	const char *next_proto_neg_in = NULL;
+	tlsextnextprotoctx next_proto;
+# endif
+#endif
+#ifndef OPENSSL_NO_PSK
+	/* by default do not send a PSK identity hint */
+	static char *psk_identity_hint=NULL;
+#endif
+#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
+	meth=SSLv23_server_method();
+#elif !defined(OPENSSL_NO_SSL3)
+	meth=SSLv3_server_method();
+#elif !defined(OPENSSL_NO_SSL2)
+	meth=SSLv2_server_method();
+#endif
+
+	local_argc=argc;
+	local_argv=argv;
+
+	apps_startup();
+#ifdef MONOLITH
+	s_server_init();
+#endif
+
+	if (bio_err == NULL)
+		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	verify_depth=0;
+#ifdef FIONBIO
+	s_nbio=0;
+#endif
+	s_nbio_test=0;
+
+	argc--;
+	argv++;
+
+	while (argc >= 1)
+		{
+		if	((strcmp(*argv,"-port") == 0) ||
+			 (strcmp(*argv,"-accept") == 0))
+			{
+			if (--argc < 1) goto bad;
+			if (!extract_port(*(++argv),&port))
+				goto bad;
+			}
+		else if	(strcmp(*argv,"-verify") == 0)
+			{
+			s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE;
+			if (--argc < 1) goto bad;
+			verify_depth=atoi(*(++argv));
+			BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
+			}
+		else if	(strcmp(*argv,"-Verify") == 0)
+			{
+			s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
+				SSL_VERIFY_CLIENT_ONCE;
+			if (--argc < 1) goto bad;
+			verify_depth=atoi(*(++argv));
+			BIO_printf(bio_err,"verify depth is %d, must return a certificate\n",verify_depth);
+			}
+		else if	(strcmp(*argv,"-context") == 0)
+			{
+			if (--argc < 1) goto bad;
+			context= (unsigned char *)*(++argv);
+			}
+		else if	(strcmp(*argv,"-cert") == 0)
+			{
+			if (--argc < 1) goto bad;
+			s_cert_file= *(++argv);
+			}
+		else if	(strcmp(*argv,"-certform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			s_cert_format = str2fmt(*(++argv));
+			}
+		else if	(strcmp(*argv,"-key") == 0)
+			{
+			if (--argc < 1) goto bad;
+			s_key_file= *(++argv);
+			}
+		else if	(strcmp(*argv,"-keyform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			s_key_format = str2fmt(*(++argv));
+			}
+		else if	(strcmp(*argv,"-pass") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passarg = *(++argv);
+			}
+		else if	(strcmp(*argv,"-dhparam") == 0)
+			{
+			if (--argc < 1) goto bad;
+			dhfile = *(++argv);
+			}
+#ifndef OPENSSL_NO_ECDH		
+		else if	(strcmp(*argv,"-named_curve") == 0)
+			{
+			if (--argc < 1) goto bad;
+			named_curve = *(++argv);
+			}
+#endif
+		else if	(strcmp(*argv,"-dcertform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			s_dcert_format = str2fmt(*(++argv));
+			}
+		else if	(strcmp(*argv,"-dcert") == 0)
+			{
+			if (--argc < 1) goto bad;
+			s_dcert_file= *(++argv);
+			}
+		else if	(strcmp(*argv,"-dkeyform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			s_dkey_format = str2fmt(*(++argv));
+			}
+		else if	(strcmp(*argv,"-dpass") == 0)
+			{
+			if (--argc < 1) goto bad;
+			dpassarg = *(++argv);
+			}
+		else if	(strcmp(*argv,"-dkey") == 0)
+			{
+			if (--argc < 1) goto bad;
+			s_dkey_file= *(++argv);
+			}
+		else if (strcmp(*argv,"-nocert") == 0)
+			{
+			nocert=1;
+			}
+		else if	(strcmp(*argv,"-CApath") == 0)
+			{
+			if (--argc < 1) goto bad;
+			CApath= *(++argv);
+			}
+		else if (strcmp(*argv,"-no_cache") == 0)
+			no_cache = 1;
+		else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm))
+			{
+			if (badarg)
+				goto bad;
+			continue;
+			}
+		else if (strcmp(*argv,"-verify_return_error") == 0)
+			verify_return_error = 1;
+		else if	(strcmp(*argv,"-serverpref") == 0)
+			{ off|=SSL_OP_CIPHER_SERVER_PREFERENCE; }
+		else if (strcmp(*argv,"-legacy_renegotiation") == 0)
+			off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
+		else if	(strcmp(*argv,"-cipher") == 0)
+			{
+			if (--argc < 1) goto bad;
+			cipher= *(++argv);
+			}
+		else if	(strcmp(*argv,"-CAfile") == 0)
+			{
+			if (--argc < 1) goto bad;
+			CAfile= *(++argv);
+			}
+#ifdef FIONBIO	
+		else if	(strcmp(*argv,"-nbio") == 0)
+			{ s_nbio=1; }
+#endif
+		else if	(strcmp(*argv,"-nbio_test") == 0)
+			{
+#ifdef FIONBIO	
+			s_nbio=1;
+#endif
+			s_nbio_test=1;
+			}
+		else if	(strcmp(*argv,"-debug") == 0)
+			{ s_debug=1; }
+#ifndef OPENSSL_NO_TLSEXT
+		else if	(strcmp(*argv,"-tlsextdebug") == 0)
+			s_tlsextdebug=1;
+		else if	(strcmp(*argv,"-status") == 0)
+			s_tlsextstatus=1;
+		else if	(strcmp(*argv,"-status_verbose") == 0)
+			{
+			s_tlsextstatus=1;
+			tlscstatp.verbose = 1;
+			}
+		else if (!strcmp(*argv, "-status_timeout"))
+			{
+			s_tlsextstatus=1;
+                        if (--argc < 1) goto bad;
+			tlscstatp.timeout = atoi(*(++argv));
+			}
+		else if (!strcmp(*argv, "-status_url"))
+			{
+			s_tlsextstatus=1;
+                        if (--argc < 1) goto bad;
+			if (!OCSP_parse_url(*(++argv),
+					&tlscstatp.host,
+					&tlscstatp.port,
+					&tlscstatp.path,
+					&tlscstatp.use_ssl))
+				{
+				BIO_printf(bio_err, "Error parsing URL\n");
+				goto bad;
+				}
+			}
+#endif
+		else if	(strcmp(*argv,"-msg") == 0)
+			{ s_msg=1; }
+		else if	(strcmp(*argv,"-hack") == 0)
+			{ hack=1; }
+		else if	(strcmp(*argv,"-state") == 0)
+			{ state=1; }
+		else if	(strcmp(*argv,"-crlf") == 0)
+			{ s_crlf=1; }
+		else if	(strcmp(*argv,"-quiet") == 0)
+			{ s_quiet=1; }
+		else if	(strcmp(*argv,"-bugs") == 0)
+			{ bugs=1; }
+		else if	(strcmp(*argv,"-no_tmp_rsa") == 0)
+			{ no_tmp_rsa=1; }
+		else if	(strcmp(*argv,"-no_dhe") == 0)
+			{ no_dhe=1; }
+		else if	(strcmp(*argv,"-no_ecdhe") == 0)
+			{ no_ecdhe=1; }
+#ifndef OPENSSL_NO_PSK
+                else if (strcmp(*argv,"-psk_hint") == 0)
+			{
+                        if (--argc < 1) goto bad;
+                        psk_identity_hint= *(++argv);
+                        }
+                else if (strcmp(*argv,"-psk") == 0)
+			{
+			size_t i;
+
+			if (--argc < 1) goto bad;
+			psk_key=*(++argv);
+			for (i=0; i<strlen(psk_key); i++)
+				{
+				if (isxdigit((int)psk_key[i]))
+					continue;
+				BIO_printf(bio_err,"Not a hex number '%s'\n",*argv);
+				goto bad;
+				}
+			}
+#endif
+		else if	(strcmp(*argv,"-www") == 0)
+			{ www=1; }
+		else if	(strcmp(*argv,"-WWW") == 0)
+			{ www=2; }
+		else if	(strcmp(*argv,"-HTTP") == 0)
+			{ www=3; }
+		else if	(strcmp(*argv,"-no_ssl2") == 0)
+			{ off|=SSL_OP_NO_SSLv2; }
+		else if	(strcmp(*argv,"-no_ssl3") == 0)
+			{ off|=SSL_OP_NO_SSLv3; }
+		else if	(strcmp(*argv,"-no_tls1") == 0)
+			{ off|=SSL_OP_NO_TLSv1; }
+		else if	(strcmp(*argv,"-no_comp") == 0)
+			{ off|=SSL_OP_NO_COMPRESSION; }
+#ifndef OPENSSL_NO_TLSEXT
+		else if	(strcmp(*argv,"-no_ticket") == 0)
+			{ off|=SSL_OP_NO_TICKET; }
+#endif
+#ifndef OPENSSL_NO_SSL2
+		else if	(strcmp(*argv,"-ssl2") == 0)
+			{ meth=SSLv2_server_method(); }
+#endif
+#ifndef OPENSSL_NO_SSL3
+		else if	(strcmp(*argv,"-ssl3") == 0)
+			{ meth=SSLv3_server_method(); }
+#endif
+#ifndef OPENSSL_NO_TLS1
+		else if	(strcmp(*argv,"-tls1") == 0)
+			{ meth=TLSv1_server_method(); }
+#endif
+#ifndef OPENSSL_NO_DTLS1
+		else if	(strcmp(*argv,"-dtls1") == 0)
+			{ 
+			meth=DTLSv1_server_method();
+			socket_type = SOCK_DGRAM;
+			}
+		else if (strcmp(*argv,"-timeout") == 0)
+			enable_timeouts = 1;
+		else if (strcmp(*argv,"-mtu") == 0)
+			{
+			if (--argc < 1) goto bad;
+			socket_mtu = atol(*(++argv));
+			}
+		else if (strcmp(*argv, "-chain") == 0)
+			cert_chain = 1;
+#endif
+		else if (strcmp(*argv, "-id_prefix") == 0)
+			{
+			if (--argc < 1) goto bad;
+			session_id_prefix = *(++argv);
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*argv,"-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine_id= *(++argv);
+			}
+#endif
+		else if (strcmp(*argv,"-rand") == 0)
+			{
+			if (--argc < 1) goto bad;
+			inrand= *(++argv);
+			}
+#ifndef OPENSSL_NO_TLSEXT
+		else if (strcmp(*argv,"-servername") == 0)
+			{
+			if (--argc < 1) goto bad;
+			tlsextcbp.servername= *(++argv);
+			}
+		else if (strcmp(*argv,"-servername_fatal") == 0)
+			{ tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL; }
+		else if	(strcmp(*argv,"-cert2") == 0)
+			{
+			if (--argc < 1) goto bad;
+			s_cert_file2= *(++argv);
+			}
+		else if	(strcmp(*argv,"-key2") == 0)
+			{
+			if (--argc < 1) goto bad;
+			s_key_file2= *(++argv);
+			}
+# ifndef OPENSSL_NO_NEXTPROTONEG
+		else if	(strcmp(*argv,"-nextprotoneg") == 0)
+			{
+			if (--argc < 1) goto bad;
+			next_proto_neg_in = *(++argv);
+			}
+# endif
+#endif
+#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
+		else if (strcmp(*argv,"-jpake") == 0)
+			{
+			if (--argc < 1) goto bad;
+			jpake_secret = *(++argv);
+			}
+#endif
+		else
+			{
+			BIO_printf(bio_err,"unknown option %s\n",*argv);
+			badop=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+	if (badop)
+		{
+bad:
+		sv_usage();
+		goto end;
+		}
+
+#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
+	if (jpake_secret)
+		{
+		if (psk_key)
+			{
+			BIO_printf(bio_err,
+				   "Can't use JPAKE and PSK together\n");
+			goto end;
+			}
+		psk_identity = "JPAKE";
+		if (cipher)
+			{
+			BIO_printf(bio_err, "JPAKE sets cipher to PSK\n");
+			goto end;
+			}
+		cipher = "PSK";
+		}
+
+#endif
+
+	SSL_load_error_strings();
+	OpenSSL_add_ssl_algorithms();
+
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine_id, 1);
+#endif
+
+	if (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass))
+		{
+		BIO_printf(bio_err, "Error getting password\n");
+		goto end;
+		}
+
+
+	if (s_key_file == NULL)
+		s_key_file = s_cert_file;
+#ifndef OPENSSL_NO_TLSEXT
+	if (s_key_file2 == NULL)
+		s_key_file2 = s_cert_file2;
+#endif
+
+	if (nocert == 0)
+		{
+		s_key = load_key(bio_err, s_key_file, s_key_format, 0, pass, e,
+		       "server certificate private key file");
+		if (!s_key)
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+
+		s_cert = load_cert(bio_err,s_cert_file,s_cert_format,
+			NULL, e, "server certificate file");
+
+		if (!s_cert)
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+
+#ifndef OPENSSL_NO_TLSEXT
+		if (tlsextcbp.servername) 
+			{
+			s_key2 = load_key(bio_err, s_key_file2, s_key_format, 0, pass, e,
+				"second server certificate private key file");
+			if (!s_key2)
+				{
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+			
+			s_cert2 = load_cert(bio_err,s_cert_file2,s_cert_format,
+				NULL, e, "second server certificate file");
+			
+			if (!s_cert2)
+				{
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+			}
+#endif
+		}
+
+
+	if (s_dcert_file)
+		{
+
+		if (s_dkey_file == NULL)
+			s_dkey_file = s_dcert_file;
+
+		s_dkey = load_key(bio_err, s_dkey_file, s_dkey_format,
+				0, dpass, e,
+			       "second certificate private key file");
+		if (!s_dkey)
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+
+		s_dcert = load_cert(bio_err,s_dcert_file,s_dcert_format,
+				NULL, e, "second server certificate file");
+
+		if (!s_dcert)
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+
+		}
+
+	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
+		&& !RAND_status())
+		{
+		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
+		}
+	if (inrand != NULL)
+		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+			app_RAND_load_files(inrand));
+
+	if (bio_s_out == NULL)
+		{
+		if (s_quiet && !s_debug && !s_msg)
+			{
+			bio_s_out=BIO_new(BIO_s_null());
+			}
+		else
+			{
+			if (bio_s_out == NULL)
+				bio_s_out=BIO_new_fp(stdout,BIO_NOCLOSE);
+			}
+		}
+
+#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
+	if (nocert)
+#endif
+		{
+		s_cert_file=NULL;
+		s_key_file=NULL;
+		s_dcert_file=NULL;
+		s_dkey_file=NULL;
+#ifndef OPENSSL_NO_TLSEXT
+		s_cert_file2=NULL;
+		s_key_file2=NULL;
+#endif
+		}
+
+	ctx=SSL_CTX_new(meth);
+	if (ctx == NULL)
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+	if (session_id_prefix)
+		{
+		if(strlen(session_id_prefix) >= 32)
+			BIO_printf(bio_err,
+"warning: id_prefix is too long, only one new session will be possible\n");
+		else if(strlen(session_id_prefix) >= 16)
+			BIO_printf(bio_err,
+"warning: id_prefix is too long if you use SSLv2\n");
+		if(!SSL_CTX_set_generate_session_id(ctx, generate_session_id))
+			{
+			BIO_printf(bio_err,"error setting 'id_prefix'\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix);
+		}
+	SSL_CTX_set_quiet_shutdown(ctx,1);
+	if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL);
+	if (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
+	SSL_CTX_set_options(ctx,off);
+	/* DTLS: partial reads end up discarding unread UDP bytes :-( 
+	 * Setting read ahead solves this problem.
+	 */
+	if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
+
+	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
+	if (no_cache)
+		SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
+	else
+		SSL_CTX_sess_set_cache_size(ctx,128);
+
+#if 0
+	if (cipher == NULL) cipher=getenv("SSL_CIPHER");
+#endif
+
+#if 0
+	if (s_cert_file == NULL)
+		{
+		BIO_printf(bio_err,"You must specify a certificate file for the server to use\n");
+		goto end;
+		}
+#endif
+
+	if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
+		(!SSL_CTX_set_default_verify_paths(ctx)))
+		{
+		/* BIO_printf(bio_err,"X509_load_verify_locations\n"); */
+		ERR_print_errors(bio_err);
+		/* goto end; */
+		}
+	if (vpm)
+		SSL_CTX_set1_param(ctx, vpm);
+
+#ifndef OPENSSL_NO_TLSEXT
+	if (s_cert2)
+		{
+		ctx2=SSL_CTX_new(meth);
+		if (ctx2 == NULL)
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+	
+	if (ctx2)
+		{
+		BIO_printf(bio_s_out,"Setting secondary ctx parameters\n");
+
+		if (session_id_prefix)
+			{
+			if(strlen(session_id_prefix) >= 32)
+				BIO_printf(bio_err,
+					"warning: id_prefix is too long, only one new session will be possible\n");
+			else if(strlen(session_id_prefix) >= 16)
+				BIO_printf(bio_err,
+					"warning: id_prefix is too long if you use SSLv2\n");
+			if(!SSL_CTX_set_generate_session_id(ctx2, generate_session_id))
+				{
+				BIO_printf(bio_err,"error setting 'id_prefix'\n");
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+			BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix);
+			}
+		SSL_CTX_set_quiet_shutdown(ctx2,1);
+		if (bugs) SSL_CTX_set_options(ctx2,SSL_OP_ALL);
+		if (hack) SSL_CTX_set_options(ctx2,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
+		SSL_CTX_set_options(ctx2,off);
+		/* DTLS: partial reads end up discarding unread UDP bytes :-( 
+		 * Setting read ahead solves this problem.
+		 */
+		if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx2, 1);
+
+		if (state) SSL_CTX_set_info_callback(ctx2,apps_ssl_info_callback);
+
+		if (no_cache)
+			SSL_CTX_set_session_cache_mode(ctx2,SSL_SESS_CACHE_OFF);
+		else
+			SSL_CTX_sess_set_cache_size(ctx2,128);
+
+		if ((!SSL_CTX_load_verify_locations(ctx2,CAfile,CApath)) ||
+			(!SSL_CTX_set_default_verify_paths(ctx2)))
+			{
+			ERR_print_errors(bio_err);
+			}
+		if (vpm)
+			SSL_CTX_set1_param(ctx2, vpm);
+		}
+
+# ifndef OPENSSL_NO_NEXTPROTONEG
+	if (next_proto.data)
+		SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, &next_proto);
+# endif
+#endif 
+
+#ifndef OPENSSL_NO_DH
+	if (!no_dhe)
+		{
+		DH *dh=NULL;
+
+		if (dhfile)
+			dh = load_dh_param(dhfile);
+		else if (s_cert_file)
+			dh = load_dh_param(s_cert_file);
+
+		if (dh != NULL)
+			{
+			BIO_printf(bio_s_out,"Setting temp DH parameters\n");
+			}
+		else
+			{
+			BIO_printf(bio_s_out,"Using default temp DH parameters\n");
+			dh=get_dh512();
+			}
+		(void)BIO_flush(bio_s_out);
+
+		SSL_CTX_set_tmp_dh(ctx,dh);
+#ifndef OPENSSL_NO_TLSEXT
+		if (ctx2)
+			{
+			if (!dhfile)
+				{ 
+				DH *dh2=load_dh_param(s_cert_file2);
+				if (dh2 != NULL)
+					{
+					BIO_printf(bio_s_out,"Setting temp DH parameters\n");
+					(void)BIO_flush(bio_s_out);
+
+					DH_free(dh);
+					dh = dh2;
+					}
+				}
+			SSL_CTX_set_tmp_dh(ctx2,dh);
+			}
+#endif
+		DH_free(dh);
+		}
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+	if (!no_ecdhe)
+		{
+		EC_KEY *ecdh=NULL;
+
+		if (named_curve)
+			{
+			int nid = OBJ_sn2nid(named_curve);
+
+			if (nid == 0)
+				{
+				BIO_printf(bio_err, "unknown curve name (%s)\n", 
+					named_curve);
+				goto end;
+				}
+			ecdh = EC_KEY_new_by_curve_name(nid);
+			if (ecdh == NULL)
+				{
+				BIO_printf(bio_err, "unable to create curve (%s)\n", 
+					named_curve);
+				goto end;
+				}
+			}
+
+		if (ecdh != NULL)
+			{
+			BIO_printf(bio_s_out,"Setting temp ECDH parameters\n");
+			}
+		else
+			{
+			BIO_printf(bio_s_out,"Using default temp ECDH parameters\n");
+			ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+			if (ecdh == NULL) 
+				{
+				BIO_printf(bio_err, "unable to create curve (nistp256)\n");
+				goto end;
+				}
+			}
+		(void)BIO_flush(bio_s_out);
+
+		SSL_CTX_set_tmp_ecdh(ctx,ecdh);
+#ifndef OPENSSL_NO_TLSEXT
+		if (ctx2) 
+			SSL_CTX_set_tmp_ecdh(ctx2,ecdh);
+#endif
+		EC_KEY_free(ecdh);
+		}
+#endif
+	
+	if (!set_cert_key_stuff(ctx,s_cert,s_key))
+		goto end;
+#ifndef OPENSSL_NO_TLSEXT
+	if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2))
+		goto end; 
+#endif
+	if (s_dcert != NULL)
+		{
+		if (!set_cert_key_stuff(ctx,s_dcert,s_dkey))
+			goto end;
+		}
+
+#ifndef OPENSSL_NO_RSA
+#if 1
+	if (!no_tmp_rsa)
+		{
+		SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb);
+#ifndef OPENSSL_NO_TLSEXT
+		if (ctx2) 
+			SSL_CTX_set_tmp_rsa_callback(ctx2,tmp_rsa_cb);
+#endif		
+		}
+#else
+	if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx))
+		{
+		RSA *rsa;
+
+		BIO_printf(bio_s_out,"Generating temp (512 bit) RSA key...");
+		BIO_flush(bio_s_out);
+
+		rsa=RSA_generate_key(512,RSA_F4,NULL);
+
+		if (!SSL_CTX_set_tmp_rsa(ctx,rsa))
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+#ifndef OPENSSL_NO_TLSEXT
+			if (ctx2)
+				{
+				if (!SSL_CTX_set_tmp_rsa(ctx2,rsa))
+					{
+					ERR_print_errors(bio_err);
+					goto end;
+					}
+				}
+# ifndef OPENSSL_NO_NEXTPROTONEG
+		if (next_proto_neg_in)
+			{
+			unsigned short len;
+			next_proto.data = next_protos_parse(&len,
+				next_proto_neg_in);
+			if (next_proto.data == NULL)
+				goto end;
+			next_proto.len = len;
+			}
+		else
+			{
+			next_proto.data = NULL;
+			}
+# endif
+#endif
+		RSA_free(rsa);
+		BIO_printf(bio_s_out,"\n");
+		}
+#endif
+#endif
+
+#ifndef OPENSSL_NO_PSK
+#ifdef OPENSSL_NO_JPAKE
+	if (psk_key != NULL)
+#else
+	if (psk_key != NULL || jpake_secret)
+#endif
+		{
+		if (s_debug)
+			BIO_printf(bio_s_out, "PSK key given or JPAKE in use, setting server callback\n");
+		SSL_CTX_set_psk_server_callback(ctx, psk_server_cb);
+		}
+
+	if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint))
+		{
+		BIO_printf(bio_err,"error setting PSK identity hint to context\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+#endif
+
+	if (cipher != NULL)
+		{
+		if(!SSL_CTX_set_cipher_list(ctx,cipher))
+			{
+			BIO_printf(bio_err,"error setting cipher list\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+#ifndef OPENSSL_NO_TLSEXT
+		if (ctx2 && !SSL_CTX_set_cipher_list(ctx2,cipher))
+			{
+			BIO_printf(bio_err,"error setting cipher list\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+#endif
+		}
+	SSL_CTX_set_verify(ctx,s_server_verify,verify_callback);
+	SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context,
+		sizeof s_server_session_id_context);
+
+	/* Set DTLS cookie generation and verification callbacks */
+	SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback);
+	SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback);
+
+#ifndef OPENSSL_NO_TLSEXT
+	if (ctx2)
+		{
+		SSL_CTX_set_verify(ctx2,s_server_verify,verify_callback);
+		SSL_CTX_set_session_id_context(ctx2,(void*)&s_server_session_id_context,
+			sizeof s_server_session_id_context);
+
+		tlsextcbp.biodebug = bio_s_out;
+		SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb);
+		SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp);
+		SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
+		SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
+		}
+#endif
+
+	if (CAfile != NULL)
+		{
+		SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
+#ifndef OPENSSL_NO_TLSEXT
+		if (ctx2) 
+			SSL_CTX_set_client_CA_list(ctx2,SSL_load_client_CA_file(CAfile));
+#endif
+		}
+
+	BIO_printf(bio_s_out,"ACCEPT\n");
+	(void)BIO_flush(bio_s_out);
+	if (www)
+		do_server(port,socket_type,&accept_socket,www_body, context);
+	else
+		do_server(port,socket_type,&accept_socket,sv_body, context);
+	print_stats(bio_s_out,ctx);
+	ret=0;
+end:
+	if (ctx != NULL) SSL_CTX_free(ctx);
+	if (s_cert)
+		X509_free(s_cert);
+	if (s_dcert)
+		X509_free(s_dcert);
+	if (s_key)
+		EVP_PKEY_free(s_key);
+	if (s_dkey)
+		EVP_PKEY_free(s_dkey);
+	if (pass)
+		OPENSSL_free(pass);
+	if (dpass)
+		OPENSSL_free(dpass);
+#ifndef OPENSSL_NO_TLSEXT
+	if (ctx2 != NULL) SSL_CTX_free(ctx2);
+	if (s_cert2)
+		X509_free(s_cert2);
+	if (s_key2)
+		EVP_PKEY_free(s_key2);
+#endif
+	if (bio_s_out != NULL)
+		{
+        BIO_free(bio_s_out);
+		bio_s_out=NULL;
+		}
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
+static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)
+	{
+	BIO_printf(bio,"%4ld items in the session cache\n",
+		SSL_CTX_sess_number(ssl_ctx));
+	BIO_printf(bio,"%4ld client connects (SSL_connect())\n",
+		SSL_CTX_sess_connect(ssl_ctx));
+	BIO_printf(bio,"%4ld client renegotiates (SSL_connect())\n",
+		SSL_CTX_sess_connect_renegotiate(ssl_ctx));
+	BIO_printf(bio,"%4ld client connects that finished\n",
+		SSL_CTX_sess_connect_good(ssl_ctx));
+	BIO_printf(bio,"%4ld server accepts (SSL_accept())\n",
+		SSL_CTX_sess_accept(ssl_ctx));
+	BIO_printf(bio,"%4ld server renegotiates (SSL_accept())\n",
+		SSL_CTX_sess_accept_renegotiate(ssl_ctx));
+	BIO_printf(bio,"%4ld server accepts that finished\n",
+		SSL_CTX_sess_accept_good(ssl_ctx));
+	BIO_printf(bio,"%4ld session cache hits\n",SSL_CTX_sess_hits(ssl_ctx));
+	BIO_printf(bio,"%4ld session cache misses\n",SSL_CTX_sess_misses(ssl_ctx));
+	BIO_printf(bio,"%4ld session cache timeouts\n",SSL_CTX_sess_timeouts(ssl_ctx));
+	BIO_printf(bio,"%4ld callback cache hits\n",SSL_CTX_sess_cb_hits(ssl_ctx));
+	BIO_printf(bio,"%4ld cache full overflows (%ld allowed)\n",
+		SSL_CTX_sess_cache_full(ssl_ctx),
+		SSL_CTX_sess_get_cache_size(ssl_ctx));
+	}
+
+static int sv_body(char *hostname, int s, unsigned char *context)
+	{
+	char *buf=NULL;
+	fd_set readfds;
+	int ret=1,width;
+	int k,i;
+	unsigned long l;
+	SSL *con=NULL;
+	BIO *sbio;
+	struct timeval timeout;
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
+	struct timeval tv;
+#else
+	struct timeval *timeoutp;
+#endif
+
+	if ((buf=OPENSSL_malloc(bufsize)) == NULL)
+		{
+		BIO_printf(bio_err,"out of memory\n");
+		goto err;
+		}
+#ifdef FIONBIO	
+	if (s_nbio)
+		{
+		unsigned long sl=1;
+
+		if (!s_quiet)
+			BIO_printf(bio_err,"turning on non blocking io\n");
+		if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0)
+			ERR_print_errors(bio_err);
+		}
+#endif
+
+	if (con == NULL) {
+		con=SSL_new(ctx);
+#ifndef OPENSSL_NO_TLSEXT
+	if (s_tlsextdebug)
+		{
+		SSL_set_tlsext_debug_callback(con, tlsext_cb);
+		SSL_set_tlsext_debug_arg(con, bio_s_out);
+		}
+	if (s_tlsextstatus)
+		{
+		SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb);
+		tlscstatp.err = bio_err;
+		SSL_CTX_set_tlsext_status_arg(ctx, &tlscstatp);
+		}
+#endif
+#ifndef OPENSSL_NO_KRB5
+		if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
+                        {
+                        kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE,
+								KRB5SVC);
+                        kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB,
+								KRB5KEYTAB);
+                        }
+#endif	/* OPENSSL_NO_KRB5 */
+		if(context)
+		      SSL_set_session_id_context(con, context,
+						 strlen((char *)context));
+	}
+	SSL_clear(con);
+#if 0
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	SSL_set_tlsext_opaque_prf_input(con, "Test server", 11);
+#endif
+#endif
+
+	if (SSL_version(con) == DTLS1_VERSION)
+		{
+
+		sbio=BIO_new_dgram(s,BIO_NOCLOSE);
+
+		if (enable_timeouts)
+			{
+			timeout.tv_sec = 0;
+			timeout.tv_usec = DGRAM_RCV_TIMEOUT;
+			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
+			
+			timeout.tv_sec = 0;
+			timeout.tv_usec = DGRAM_SND_TIMEOUT;
+			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
+			}
+
+		if (socket_mtu > 28)
+			{
+			SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
+			SSL_set_mtu(con, socket_mtu - 28);
+			}
+		else
+			/* want to do MTU discovery */
+			BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
+
+        /* turn on cookie exchange */
+        SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
+		}
+	else
+		sbio=BIO_new_socket(s,BIO_NOCLOSE);
+
+	if (s_nbio_test)
+		{
+		BIO *test;
+
+		test=BIO_new(BIO_f_nbio_test());
+		sbio=BIO_push(test,sbio);
+		}
+#ifndef OPENSSL_NO_JPAKE
+	if(jpake_secret)
+		jpake_server_auth(bio_s_out, sbio, jpake_secret);
+#endif
+
+	SSL_set_bio(con,sbio,sbio);
+	SSL_set_accept_state(con);
+	/* SSL_set_fd(con,s); */
+
+	if (s_debug)
+		{
+		con->debug=1;
+		BIO_set_callback(SSL_get_rbio(con),bio_dump_callback);
+		BIO_set_callback_arg(SSL_get_rbio(con),(char *)bio_s_out);
+		}
+	if (s_msg)
+		{
+		SSL_set_msg_callback(con, msg_cb);
+		SSL_set_msg_callback_arg(con, bio_s_out);
+		}
+#ifndef OPENSSL_NO_TLSEXT
+	if (s_tlsextdebug)
+		{
+		SSL_set_tlsext_debug_callback(con, tlsext_cb);
+		SSL_set_tlsext_debug_arg(con, bio_s_out);
+		}
+#endif
+
+	width=s+1;
+	for (;;)
+		{
+		int read_from_terminal;
+		int read_from_sslcon;
+
+		read_from_terminal = 0;
+		read_from_sslcon = SSL_pending(con);
+
+		if (!read_from_sslcon)
+			{
+			FD_ZERO(&readfds);
+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined(OPENSSL_SYS_BEOS_R5)
+			openssl_fdset(fileno(stdin),&readfds);
+#endif
+			openssl_fdset(s,&readfds);
+			/* Note: under VMS with SOCKETSHR the second parameter is
+			 * currently of type (int *) whereas under other systems
+			 * it is (void *) if you don't have a cast it will choke
+			 * the compiler: if you do have a cast then you can either
+			 * go for (int *) or (void *).
+			 */
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
+                        /* Under DOS (non-djgpp) and Windows we can't select on stdin: only
+			 * on sockets. As a workaround we timeout the select every
+			 * second and check for any keypress. In a proper Windows
+			 * application we wouldn't do this because it is inefficient.
+			 */
+			tv.tv_sec = 1;
+			tv.tv_usec = 0;
+			i=select(width,(void *)&readfds,NULL,NULL,&tv);
+			if((i < 0) || (!i && !_kbhit() ) )continue;
+			if(_kbhit())
+				read_from_terminal = 1;
+#elif defined(OPENSSL_SYS_BEOS_R5)
+			/* Under BeOS-R5 the situation is similar to DOS */
+			tv.tv_sec = 1;
+			tv.tv_usec = 0;
+			(void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
+			i=select(width,(void *)&readfds,NULL,NULL,&tv);
+			if ((i < 0) || (!i && read(fileno(stdin), buf, 0) < 0))
+				continue;
+			if (read(fileno(stdin), buf, 0) >= 0)
+				read_from_terminal = 1;
+			(void)fcntl(fileno(stdin), F_SETFL, 0);
+#else
+			if ((SSL_version(con) == DTLS1_VERSION) &&
+				DTLSv1_get_timeout(con, &timeout))
+				timeoutp = &timeout;
+			else
+				timeoutp = NULL;
+
+			i=select(width,(void *)&readfds,NULL,NULL,timeoutp);
+
+			if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0)
+				{
+				BIO_printf(bio_err,"TIMEOUT occured\n");
+				}
+
+			if (i <= 0) continue;
+			if (FD_ISSET(fileno(stdin),&readfds))
+				read_from_terminal = 1;
+#endif
+			if (FD_ISSET(s,&readfds))
+				read_from_sslcon = 1;
+			}
+		if (read_from_terminal)
+			{
+			if (s_crlf)
+				{
+				int j, lf_num;
+
+				i=raw_read_stdin(buf, bufsize/2);
+				lf_num = 0;
+				/* both loops are skipped when i <= 0 */
+				for (j = 0; j < i; j++)
+					if (buf[j] == '\n')
+						lf_num++;
+				for (j = i-1; j >= 0; j--)
+					{
+					buf[j+lf_num] = buf[j];
+					if (buf[j] == '\n')
+						{
+						lf_num--;
+						i++;
+						buf[j+lf_num] = '\r';
+						}
+					}
+				assert(lf_num == 0);
+				}
+			else
+				i=raw_read_stdin(buf,bufsize);
+			if (!s_quiet)
+				{
+				if ((i <= 0) || (buf[0] == 'Q'))
+					{
+					BIO_printf(bio_s_out,"DONE\n");
+					SHUTDOWN(s);
+					close_accept_socket();
+					ret= -11;
+					goto err;
+					}
+				if ((i <= 0) || (buf[0] == 'q'))
+					{
+					BIO_printf(bio_s_out,"DONE\n");
+					if (SSL_version(con) != DTLS1_VERSION)
+                        SHUTDOWN(s);
+	/*				close_accept_socket();
+					ret= -11;*/
+					goto err;
+					}
+
+				if ((buf[0] == 'r') && 
+					((buf[1] == '\n') || (buf[1] == '\r')))
+					{
+					SSL_renegotiate(con);
+					i=SSL_do_handshake(con);
+					printf("SSL_do_handshake -> %d\n",i);
+					i=0; /*13; */
+					continue;
+					/* strcpy(buf,"server side RE-NEGOTIATE\n"); */
+					}
+				if ((buf[0] == 'R') &&
+					((buf[1] == '\n') || (buf[1] == '\r')))
+					{
+					SSL_set_verify(con,
+						SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,NULL);
+					SSL_renegotiate(con);
+					i=SSL_do_handshake(con);
+					printf("SSL_do_handshake -> %d\n",i);
+					i=0; /* 13; */
+					continue;
+					/* strcpy(buf,"server side RE-NEGOTIATE asking for client cert\n"); */
+					}
+				if (buf[0] == 'P')
+					{
+					static const char *str="Lets print some clear text\n";
+					BIO_write(SSL_get_wbio(con),str,strlen(str));
+					}
+				if (buf[0] == 'S')
+					{
+					print_stats(bio_s_out,SSL_get_SSL_CTX(con));
+					}
+				}
+#ifdef CHARSET_EBCDIC
+			ebcdic2ascii(buf,buf,i);
+#endif
+			l=k=0;
+			for (;;)
+				{
+				/* should do a select for the write */
+#ifdef RENEG
+{ static count=0; if (++count == 100) { count=0; SSL_renegotiate(con); } }
+#endif
+				k=SSL_write(con,&(buf[l]),(unsigned int)i);
+				switch (SSL_get_error(con,k))
+					{
+				case SSL_ERROR_NONE:
+					break;
+				case SSL_ERROR_WANT_WRITE:
+				case SSL_ERROR_WANT_READ:
+				case SSL_ERROR_WANT_X509_LOOKUP:
+					BIO_printf(bio_s_out,"Write BLOCK\n");
+					break;
+				case SSL_ERROR_SYSCALL:
+				case SSL_ERROR_SSL:
+					BIO_printf(bio_s_out,"ERROR\n");
+					ERR_print_errors(bio_err);
+					ret=1;
+					goto err;
+					/* break; */
+				case SSL_ERROR_ZERO_RETURN:
+					BIO_printf(bio_s_out,"DONE\n");
+					ret=1;
+					goto err;
+					}
+				l+=k;
+				i-=k;
+				if (i <= 0) break;
+				}
+			}
+		if (read_from_sslcon)
+			{
+			if (!SSL_is_init_finished(con))
+				{
+				i=init_ssl_connection(con);
+				
+				if (i < 0)
+					{
+					ret=0;
+					goto err;
+					}
+				else if (i == 0)
+					{
+					ret=1;
+					goto err;
+					}
+				}
+			else
+				{
+again:	
+				i=SSL_read(con,(char *)buf,bufsize);
+				switch (SSL_get_error(con,i))
+					{
+				case SSL_ERROR_NONE:
+#ifdef CHARSET_EBCDIC
+					ascii2ebcdic(buf,buf,i);
+#endif
+					raw_write_stdout(buf,
+						(unsigned int)i);
+					if (SSL_pending(con)) goto again;
+					break;
+				case SSL_ERROR_WANT_WRITE:
+				case SSL_ERROR_WANT_READ:
+				case SSL_ERROR_WANT_X509_LOOKUP:
+					BIO_printf(bio_s_out,"Read BLOCK\n");
+					break;
+				case SSL_ERROR_SYSCALL:
+				case SSL_ERROR_SSL:
+					BIO_printf(bio_s_out,"ERROR\n");
+					ERR_print_errors(bio_err);
+					ret=1;
+					goto err;
+				case SSL_ERROR_ZERO_RETURN:
+					BIO_printf(bio_s_out,"DONE\n");
+					ret=1;
+					goto err;
+					}
+				}
+			}
+		}
+err:
+	if (con != NULL)
+		{
+		BIO_printf(bio_s_out,"shutting down SSL\n");
+#if 1
+		SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+#else
+		SSL_shutdown(con);
+#endif
+		SSL_free(con);
+		}
+	BIO_printf(bio_s_out,"CONNECTION CLOSED\n");
+	if (buf != NULL)
+		{
+		OPENSSL_cleanse(buf,bufsize);
+		OPENSSL_free(buf);
+		}
+	if (ret >= 0)
+		BIO_printf(bio_s_out,"ACCEPT\n");
+	return(ret);
+	}
+
+static void close_accept_socket(void)
+	{
+	BIO_printf(bio_err,"shutdown accept socket\n");
+	if (accept_socket >= 0)
+		{
+		SHUTDOWN2(accept_socket);
+		}
+	}
+
+static int init_ssl_connection(SSL *con)
+	{
+	int i;
+	const char *str;
+	X509 *peer;
+	long verify_error;
+	MS_STATIC char buf[BUFSIZ];
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+	const unsigned char *next_proto_neg;
+	unsigned next_proto_neg_len;
+#endif
+
+	if ((i=SSL_accept(con)) <= 0)
+		{
+		if (BIO_sock_should_retry(i))
+			{
+			BIO_printf(bio_s_out,"DELAY\n");
+			return(1);
+			}
+
+		BIO_printf(bio_err,"ERROR\n");
+		verify_error=SSL_get_verify_result(con);
+		if (verify_error != X509_V_OK)
+			{
+			BIO_printf(bio_err,"verify error:%s\n",
+				X509_verify_cert_error_string(verify_error));
+			}
+		else
+			ERR_print_errors(bio_err);
+		return(0);
+		}
+
+	PEM_write_bio_SSL_SESSION(bio_s_out,SSL_get_session(con));
+
+	peer=SSL_get_peer_certificate(con);
+	if (peer != NULL)
+		{
+		BIO_printf(bio_s_out,"Client certificate\n");
+		PEM_write_bio_X509(bio_s_out,peer);
+		X509_NAME_oneline(X509_get_subject_name(peer),buf,sizeof buf);
+		BIO_printf(bio_s_out,"subject=%s\n",buf);
+		X509_NAME_oneline(X509_get_issuer_name(peer),buf,sizeof buf);
+		BIO_printf(bio_s_out,"issuer=%s\n",buf);
+		X509_free(peer);
+		}
+
+	if (SSL_get_shared_ciphers(con,buf,sizeof buf) != NULL)
+		BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf);
+	str=SSL_CIPHER_get_name(SSL_get_current_cipher(con));
+	BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)");
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+	SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len);
+	if (next_proto_neg)
+		{
+		BIO_printf(bio_s_out,"NEXTPROTO is ");
+		BIO_write(bio_s_out, next_proto_neg, next_proto_neg_len);
+		BIO_printf(bio_s_out, "\n");
+		}
+#endif
+	if (con->hit) BIO_printf(bio_s_out,"Reused session-id\n");
+	if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) &
+		TLS1_FLAGS_TLS_PADDING_BUG)
+		BIO_printf(bio_s_out,"Peer has incorrect TLSv1 block padding\n");
+#ifndef OPENSSL_NO_KRB5
+	if (con->kssl_ctx->client_princ != NULL)
+		{
+		BIO_printf(bio_s_out,"Kerberos peer principal is %s\n",
+			con->kssl_ctx->client_princ);
+		}
+#endif /* OPENSSL_NO_KRB5 */
+	BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n",
+		      SSL_get_secure_renegotiation_support(con) ? "" : " NOT");
+	return(1);
+	}
+
+#ifndef OPENSSL_NO_DH
+static DH *load_dh_param(const char *dhfile)
+	{
+	DH *ret=NULL;
+	BIO *bio;
+
+	if ((bio=BIO_new_file(dhfile,"r")) == NULL)
+		goto err;
+	ret=PEM_read_bio_DHparams(bio,NULL,NULL,NULL);
+err:
+	if (bio != NULL) BIO_free(bio);
+	return(ret);
+	}
+#endif
+
+#if 0
+static int load_CA(SSL_CTX *ctx, char *file)
+	{
+	FILE *in;
+	X509 *x=NULL;
+
+	if ((in=fopen(file,"r")) == NULL)
+		return(0);
+
+	for (;;)
+		{
+		if (PEM_read_X509(in,&x,NULL) == NULL)
+			break;
+		SSL_CTX_add_client_CA(ctx,x);
+		}
+	if (x != NULL) X509_free(x);
+	fclose(in);
+	return(1);
+	}
+#endif
+
+static int www_body(char *hostname, int s, unsigned char *context)
+	{
+	char *buf=NULL;
+	int ret=1;
+	int i,j,k,dot;
+	SSL *con;
+	const SSL_CIPHER *c;
+	BIO *io,*ssl_bio,*sbio;
+
+	buf=OPENSSL_malloc(bufsize);
+	if (buf == NULL) return(0);
+	io=BIO_new(BIO_f_buffer());
+	ssl_bio=BIO_new(BIO_f_ssl());
+	if ((io == NULL) || (ssl_bio == NULL)) goto err;
+
+#ifdef FIONBIO	
+	if (s_nbio)
+		{
+		unsigned long sl=1;
+
+		if (!s_quiet)
+			BIO_printf(bio_err,"turning on non blocking io\n");
+		if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0)
+			ERR_print_errors(bio_err);
+		}
+#endif
+
+	/* lets make the output buffer a reasonable size */
+	if (!BIO_set_write_buffer_size(io,bufsize)) goto err;
+
+	if ((con=SSL_new(ctx)) == NULL) goto err;
+#ifndef OPENSSL_NO_TLSEXT
+		if (s_tlsextdebug)
+			{
+			SSL_set_tlsext_debug_callback(con, tlsext_cb);
+			SSL_set_tlsext_debug_arg(con, bio_s_out);
+			}
+#endif
+#ifndef OPENSSL_NO_KRB5
+	if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
+		{
+		kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE, KRB5SVC);
+		kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB, KRB5KEYTAB);
+		}
+#endif	/* OPENSSL_NO_KRB5 */
+	if(context) SSL_set_session_id_context(con, context,
+					       strlen((char *)context));
+
+	sbio=BIO_new_socket(s,BIO_NOCLOSE);
+	if (s_nbio_test)
+		{
+		BIO *test;
+
+		test=BIO_new(BIO_f_nbio_test());
+		sbio=BIO_push(test,sbio);
+		}
+	SSL_set_bio(con,sbio,sbio);
+	SSL_set_accept_state(con);
+
+	/* SSL_set_fd(con,s); */
+	BIO_set_ssl(ssl_bio,con,BIO_CLOSE);
+	BIO_push(io,ssl_bio);
+#ifdef CHARSET_EBCDIC
+	io = BIO_push(BIO_new(BIO_f_ebcdic_filter()),io);
+#endif
+
+	if (s_debug)
+		{
+		con->debug=1;
+		BIO_set_callback(SSL_get_rbio(con),bio_dump_callback);
+		BIO_set_callback_arg(SSL_get_rbio(con),(char *)bio_s_out);
+		}
+	if (s_msg)
+		{
+		SSL_set_msg_callback(con, msg_cb);
+		SSL_set_msg_callback_arg(con, bio_s_out);
+		}
+
+	for (;;)
+		{
+		if (hack)
+			{
+			i=SSL_accept(con);
+
+			switch (SSL_get_error(con,i))
+				{
+			case SSL_ERROR_NONE:
+				break;
+			case SSL_ERROR_WANT_WRITE:
+			case SSL_ERROR_WANT_READ:
+			case SSL_ERROR_WANT_X509_LOOKUP:
+				continue;
+			case SSL_ERROR_SYSCALL:
+			case SSL_ERROR_SSL:
+			case SSL_ERROR_ZERO_RETURN:
+				ret=1;
+				goto err;
+				/* break; */
+				}
+
+			SSL_renegotiate(con);
+			SSL_write(con,NULL,0);
+			}
+
+		i=BIO_gets(io,buf,bufsize-1);
+		if (i < 0) /* error */
+			{
+			if (!BIO_should_retry(io))
+				{
+				if (!s_quiet)
+					ERR_print_errors(bio_err);
+				goto err;
+				}
+			else
+				{
+				BIO_printf(bio_s_out,"read R BLOCK\n");
+#if defined(OPENSSL_SYS_NETWARE)
+            delay(1000);
+#elif !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__)
+				sleep(1);
+#endif
+				continue;
+				}
+			}
+		else if (i == 0) /* end of input */
+			{
+			ret=1;
+			goto end;
+			}
+
+		/* else we have data */
+		if (	((www == 1) && (strncmp("GET ",buf,4) == 0)) ||
+			((www == 2) && (strncmp("GET /stats ",buf,10) == 0)))
+			{
+			char *p;
+			X509 *peer;
+			STACK_OF(SSL_CIPHER) *sk;
+			static const char *space="                          ";
+
+			BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
+			BIO_puts(io,"<HTML><BODY BGCOLOR=\"#ffffff\">\n");
+			BIO_puts(io,"<pre>\n");
+/*			BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/
+			BIO_puts(io,"\n");
+			for (i=0; i<local_argc; i++)
+				{
+				BIO_puts(io,local_argv[i]);
+				BIO_write(io," ",1);
+				}
+			BIO_puts(io,"\n");
+
+			/* The following is evil and should not really
+			 * be done */
+			BIO_printf(io,"Ciphers supported in s_server binary\n");
+			sk=SSL_get_ciphers(con);
+			j=sk_SSL_CIPHER_num(sk);
+			for (i=0; i<j; i++)
+				{
+				c=sk_SSL_CIPHER_value(sk,i);
+				BIO_printf(io,"%-11s:%-25s",
+					SSL_CIPHER_get_version(c),
+					SSL_CIPHER_get_name(c));
+				if ((((i+1)%2) == 0) && (i+1 != j))
+					BIO_puts(io,"\n");
+				}
+			BIO_puts(io,"\n");
+			p=SSL_get_shared_ciphers(con,buf,bufsize);
+			if (p != NULL)
+				{
+				BIO_printf(io,"---\nCiphers common between both SSL end points:\n");
+				j=i=0;
+				while (*p)
+					{
+					if (*p == ':')
+						{
+						BIO_write(io,space,26-j);
+						i++;
+						j=0;
+						BIO_write(io,((i%3)?" ":"\n"),1);
+						}
+					else
+						{
+						BIO_write(io,p,1);
+						j++;
+						}
+					p++;
+					}
+				BIO_puts(io,"\n");
+				}
+			BIO_printf(io,((con->hit)
+				?"---\nReused, "
+				:"---\nNew, "));
+			c=SSL_get_current_cipher(con);
+			BIO_printf(io,"%s, Cipher is %s\n",
+				SSL_CIPHER_get_version(c),
+				SSL_CIPHER_get_name(c));
+			SSL_SESSION_print(io,SSL_get_session(con));
+			BIO_printf(io,"---\n");
+			print_stats(io,SSL_get_SSL_CTX(con));
+			BIO_printf(io,"---\n");
+			peer=SSL_get_peer_certificate(con);
+			if (peer != NULL)
+				{
+				BIO_printf(io,"Client certificate\n");
+				X509_print(io,peer);
+				PEM_write_bio_X509(io,peer);
+				}
+			else
+				BIO_puts(io,"no client certificate available\n");
+			BIO_puts(io,"</BODY></HTML>\r\n\r\n");
+			break;
+			}
+		else if ((www == 2 || www == 3)
+                         && (strncmp("GET /",buf,5) == 0))
+			{
+			BIO *file;
+			char *p,*e;
+			static const char *text="HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
+
+			/* skip the '/' */
+			p= &(buf[5]);
+
+			dot = 1;
+			for (e=p; *e != '\0'; e++)
+				{
+				if (e[0] == ' ')
+					break;
+
+				switch (dot)
+					{
+				case 1:
+					dot = (e[0] == '.') ? 2 : 0;
+					break;
+				case 2:
+					dot = (e[0] == '.') ? 3 : 0;
+					break;
+				case 3:
+					dot = (e[0] == '/') ? -1 : 0;
+					break;
+					}
+				if (dot == 0)
+					dot = (e[0] == '/') ? 1 : 0;
+				}
+			dot = (dot == 3) || (dot == -1); /* filename contains ".." component */
+
+			if (*e == '\0')
+				{
+				BIO_puts(io,text);
+				BIO_printf(io,"'%s' is an invalid file name\r\n",p);
+				break;
+				}
+			*e='\0';
+
+			if (dot)
+				{
+				BIO_puts(io,text);
+				BIO_printf(io,"'%s' contains '..' reference\r\n",p);
+				break;
+				}
+
+			if (*p == '/')
+				{
+				BIO_puts(io,text);
+				BIO_printf(io,"'%s' is an invalid path\r\n",p);
+				break;
+				}
+
+#if 0
+			/* append if a directory lookup */
+			if (e[-1] == '/')
+				strcat(p,"index.html");
+#endif
+
+			/* if a directory, do the index thang */
+			if (app_isdir(p)>0)
+				{
+#if 0 /* must check buffer size */
+				strcat(p,"/index.html");
+#else
+				BIO_puts(io,text);
+				BIO_printf(io,"'%s' is a directory\r\n",p);
+				break;
+#endif
+				}
+
+			if ((file=BIO_new_file(p,"r")) == NULL)
+				{
+				BIO_puts(io,text);
+				BIO_printf(io,"Error opening '%s'\r\n",p);
+				ERR_print_errors(io);
+				break;
+				}
+
+			if (!s_quiet)
+				BIO_printf(bio_err,"FILE:%s\n",p);
+
+                        if (www == 2)
+                                {
+                                i=strlen(p);
+                                if (	((i > 5) && (strcmp(&(p[i-5]),".html") == 0)) ||
+                                        ((i > 4) && (strcmp(&(p[i-4]),".php") == 0)) ||
+                                        ((i > 4) && (strcmp(&(p[i-4]),".htm") == 0)))
+                                        BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
+                                else
+                                        BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
+                                }
+			/* send the file */
+			for (;;)
+				{
+				i=BIO_read(file,buf,bufsize);
+				if (i <= 0) break;
+
+#ifdef RENEG
+				total_bytes+=i;
+				fprintf(stderr,"%d\n",i);
+				if (total_bytes > 3*1024)
+					{
+					total_bytes=0;
+					fprintf(stderr,"RENEGOTIATE\n");
+					SSL_renegotiate(con);
+					}
+#endif
+
+				for (j=0; j<i; )
+					{
+#ifdef RENEG
+{ static count=0; if (++count == 13) { SSL_renegotiate(con); } }
+#endif
+					k=BIO_write(io,&(buf[j]),i-j);
+					if (k <= 0)
+						{
+						if (!BIO_should_retry(io))
+							goto write_error;
+						else
+							{
+							BIO_printf(bio_s_out,"rwrite W BLOCK\n");
+							}
+						}
+					else
+						{
+						j+=k;
+						}
+					}
+				}
+write_error:
+			BIO_free(file);
+			break;
+			}
+		}
+
+	for (;;)
+		{
+		i=(int)BIO_flush(io);
+		if (i <= 0)
+			{
+			if (!BIO_should_retry(io))
+				break;
+			}
+		else
+			break;
+		}
+end:
+#if 1
+	/* make sure we re-use sessions */
+	SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+#else
+	/* This kills performance */
+/*	SSL_shutdown(con); A shutdown gets sent in the
+ *	BIO_free_all(io) procession */
+#endif
+
+err:
+
+	if (ret >= 0)
+		BIO_printf(bio_s_out,"ACCEPT\n");
+
+	if (buf != NULL) OPENSSL_free(buf);
+	if (io != NULL) BIO_free_all(io);
+/*	if (ssl_bio != NULL) BIO_free(ssl_bio);*/
+	return(ret);
+	}
+
+#ifndef OPENSSL_NO_RSA
+static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
+	{
+	BIGNUM *bn = NULL;
+	static RSA *rsa_tmp=NULL;
+
+	if (!rsa_tmp && ((bn = BN_new()) == NULL))
+		BIO_printf(bio_err,"Allocation error in generating RSA key\n");
+	if (!rsa_tmp && bn)
+		{
+		if (!s_quiet)
+			{
+			BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
+			(void)BIO_flush(bio_err);
+			}
+		if(!BN_set_word(bn, RSA_F4) || ((rsa_tmp = RSA_new()) == NULL) ||
+				!RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL))
+			{
+			if(rsa_tmp) RSA_free(rsa_tmp);
+			rsa_tmp = NULL;
+			}
+		if (!s_quiet)
+			{
+			BIO_printf(bio_err,"\n");
+			(void)BIO_flush(bio_err);
+			}
+		BN_free(bn);
+		}
+	return(rsa_tmp);
+	}
+#endif
+
+#define MAX_SESSION_ID_ATTEMPTS 10
+static int generate_session_id(const SSL *ssl, unsigned char *id,
+				unsigned int *id_len)
+	{
+	unsigned int count = 0;
+	do	{
+		RAND_pseudo_bytes(id, *id_len);
+		/* Prefix the session_id with the required prefix. NB: If our
+		 * prefix is too long, clip it - but there will be worse effects
+		 * anyway, eg. the server could only possibly create 1 session
+		 * ID (ie. the prefix!) so all future session negotiations will
+		 * fail due to conflicts. */
+		memcpy(id, session_id_prefix,
+			(strlen(session_id_prefix) < *id_len) ?
+			strlen(session_id_prefix) : *id_len);
+		}
+	while(SSL_has_matching_session_id(ssl, id, *id_len) &&
+		(++count < MAX_SESSION_ID_ATTEMPTS));
+	if(count >= MAX_SESSION_ID_ATTEMPTS)
+		return 0;
+	return 1;
+	}
diff --git a/openssl/apps/s_socket.c b/openssl/apps/s_socket.c
new file mode 100644
index 0000000..c08544a
--- /dev/null
+++ b/openssl/apps/s_socket.c
@@ -0,0 +1,620 @@
+/* apps/s_socket.c -  socket-related functions used by s_client and s_server */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+
+#ifdef FLAT_INC
+#include "e_os2.h"
+#else
+#include "../e_os2.h"
+#endif
+
+/* With IPv6, it looks like Digital has mixed up the proper order of
+   recursive header file inclusion, resulting in the compiler complaining
+   that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
+   is needed to have fileno() declared correctly...  So let's define u_int */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
+#define __U_INT
+typedef unsigned int u_int;
+#endif
+
+#define USE_SOCKETS
+#define NON_MAIN
+#include "apps.h"
+#undef USE_SOCKETS
+#undef NON_MAIN
+#include "s_apps.h"
+#include <openssl/ssl.h>
+
+#ifdef FLAT_INC
+#include "e_os.h"
+#else
+#include "../e_os.h"
+#endif
+
+#ifndef OPENSSL_NO_SOCK
+
+#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
+#include "netdb.h"
+#endif
+
+static struct hostent *GetHostByName(char *name);
+#if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
+static void ssl_sock_cleanup(void);
+#endif
+static int ssl_sock_init(void);
+static int init_client_ip(int *sock,unsigned char ip[4], int port, int type);
+static int init_server(int *sock, int port, int type);
+static int init_server_long(int *sock, int port,char *ip, int type);
+static int do_accept(int acc_sock, int *sock, char **host);
+static int host_ip(char *str, unsigned char ip[4]);
+
+#ifdef OPENSSL_SYS_WIN16
+#define SOCKET_PROTOCOL	0 /* more microsoft stupidity */
+#else
+#define SOCKET_PROTOCOL	IPPROTO_TCP
+#endif
+
+#if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
+static int wsa_init_done=0;
+#endif
+
+#ifdef OPENSSL_SYS_WINDOWS
+static struct WSAData wsa_state;
+static int wsa_init_done=0;
+
+#ifdef OPENSSL_SYS_WIN16
+static HWND topWnd=0;
+static FARPROC lpTopWndProc=NULL;
+static FARPROC lpTopHookProc=NULL;
+extern HINSTANCE _hInstance;  /* nice global CRT provides */
+
+static LONG FAR PASCAL topHookProc(HWND hwnd, UINT message, WPARAM wParam,
+	     LPARAM lParam)
+	{
+	if (hwnd == topWnd)
+		{
+		switch(message)
+			{
+		case WM_DESTROY:
+		case WM_CLOSE:
+			SetWindowLong(topWnd,GWL_WNDPROC,(LONG)lpTopWndProc);
+			ssl_sock_cleanup();
+			break;
+			}
+		}
+	return CallWindowProc(lpTopWndProc,hwnd,message,wParam,lParam);
+	}
+
+static BOOL CALLBACK enumproc(HWND hwnd,LPARAM lParam)
+	{
+	topWnd=hwnd;
+	return(FALSE);
+	}
+
+#endif /* OPENSSL_SYS_WIN32 */
+#endif /* OPENSSL_SYS_WINDOWS */
+
+#ifdef OPENSSL_SYS_WINDOWS
+static void ssl_sock_cleanup(void)
+	{
+	if (wsa_init_done)
+		{
+		wsa_init_done=0;
+#ifndef OPENSSL_SYS_WINCE
+		WSACancelBlockingCall();
+#endif
+		WSACleanup();
+		}
+	}
+#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
+static void sock_cleanup(void)
+    {
+    if (wsa_init_done)
+        {
+        wsa_init_done=0;
+		WSACleanup();
+		}
+	}
+#endif
+
+static int ssl_sock_init(void)
+	{
+#ifdef WATT32
+	extern int _watt_do_exit;
+	_watt_do_exit = 0;
+	if (sock_init())
+		return (0);
+#elif defined(OPENSSL_SYS_WINDOWS)
+	if (!wsa_init_done)
+		{
+		int err;
+	  
+#ifdef SIGINT
+		signal(SIGINT,(void (*)(int))ssl_sock_cleanup);
+#endif
+		wsa_init_done=1;
+		memset(&wsa_state,0,sizeof(wsa_state));
+		if (WSAStartup(0x0101,&wsa_state)!=0)
+			{
+			err=WSAGetLastError();
+			BIO_printf(bio_err,"unable to start WINSOCK, error code=%d\n",err);
+			return(0);
+			}
+
+#ifdef OPENSSL_SYS_WIN16
+		EnumTaskWindows(GetCurrentTask(),enumproc,0L);
+		lpTopWndProc=(FARPROC)GetWindowLong(topWnd,GWL_WNDPROC);
+		lpTopHookProc=MakeProcInstance((FARPROC)topHookProc,_hInstance);
+
+		SetWindowLong(topWnd,GWL_WNDPROC,(LONG)lpTopHookProc);
+#endif /* OPENSSL_SYS_WIN16 */
+		}
+#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
+   WORD wVerReq;
+   WSADATA wsaData;
+   int err;
+
+   if (!wsa_init_done)
+      {
+   
+# ifdef SIGINT
+      signal(SIGINT,(void (*)(int))sock_cleanup);
+# endif
+
+      wsa_init_done=1;
+      wVerReq = MAKEWORD( 2, 0 );
+      err = WSAStartup(wVerReq,&wsaData);
+      if (err != 0)
+         {
+         BIO_printf(bio_err,"unable to start WINSOCK2, error code=%d\n",err);
+         return(0);
+         }
+      }
+#endif /* OPENSSL_SYS_WINDOWS */
+	return(1);
+	}
+
+int init_client(int *sock, char *host, int port, int type)
+	{
+	unsigned char ip[4];
+
+	if (!host_ip(host,&(ip[0])))
+		{
+		return(0);
+		}
+	return(init_client_ip(sock,ip,port,type));
+	}
+
+static int init_client_ip(int *sock, unsigned char ip[4], int port, int type)
+	{
+	unsigned long addr;
+	struct sockaddr_in them;
+	int s,i;
+
+	if (!ssl_sock_init()) return(0);
+
+	memset((char *)&them,0,sizeof(them));
+	them.sin_family=AF_INET;
+	them.sin_port=htons((unsigned short)port);
+	addr=(unsigned long)
+		((unsigned long)ip[0]<<24L)|
+		((unsigned long)ip[1]<<16L)|
+		((unsigned long)ip[2]<< 8L)|
+		((unsigned long)ip[3]);
+	them.sin_addr.s_addr=htonl(addr);
+
+	if (type == SOCK_STREAM)
+		s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
+	else /* ( type == SOCK_DGRAM) */
+		s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
+			
+	if (s == INVALID_SOCKET) { perror("socket"); return(0); }
+
+#if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE)
+	if (type == SOCK_STREAM)
+		{
+		i=0;
+		i=setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
+		if (i < 0) { perror("keepalive"); return(0); }
+		}
+#endif
+
+	if (connect(s,(struct sockaddr *)&them,sizeof(them)) == -1)
+		{ closesocket(s); perror("connect"); return(0); }
+	*sock=s;
+	return(1);
+	}
+
+int do_server(int port, int type, int *ret, int (*cb)(char *hostname, int s, unsigned char *context), unsigned char *context)
+	{
+	int sock;
+	char *name = NULL;
+	int accept_socket = 0;
+	int i;
+
+	if (!init_server(&accept_socket,port,type)) return(0);
+
+	if (ret != NULL)
+		{
+		*ret=accept_socket;
+		/* return(1);*/
+		}
+  	for (;;)
+  		{
+		if (type==SOCK_STREAM)
+			{
+			if (do_accept(accept_socket,&sock,&name) == 0)
+				{
+				SHUTDOWN(accept_socket);
+				return(0);
+				}
+			}
+		else
+			sock = accept_socket;
+		i=(*cb)(name,sock, context);
+		if (name != NULL) OPENSSL_free(name);
+		if (type==SOCK_STREAM)
+			SHUTDOWN2(sock);
+		if (i < 0)
+			{
+			SHUTDOWN2(accept_socket);
+			return(i);
+			}
+		}
+	}
+
+static int init_server_long(int *sock, int port, char *ip, int type)
+	{
+	int ret=0;
+	struct sockaddr_in server;
+	int s= -1;
+
+	if (!ssl_sock_init()) return(0);
+
+	memset((char *)&server,0,sizeof(server));
+	server.sin_family=AF_INET;
+	server.sin_port=htons((unsigned short)port);
+	if (ip == NULL)
+		server.sin_addr.s_addr=INADDR_ANY;
+	else
+/* Added for T3E, address-of fails on bit field (beckman@acl.lanl.gov) */
+#ifndef BIT_FIELD_LIMITS
+		memcpy(&server.sin_addr.s_addr,ip,4);
+#else
+		memcpy(&server.sin_addr,ip,4);
+#endif
+	
+		if (type == SOCK_STREAM)
+			s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
+		else /* type == SOCK_DGRAM */
+			s=socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP);
+
+	if (s == INVALID_SOCKET) goto err;
+#if defined SOL_SOCKET && defined SO_REUSEADDR
+		{
+		int j = 1;
+		setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+			   (void *) &j, sizeof j);
+		}
+#endif
+	if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1)
+		{
+#ifndef OPENSSL_SYS_WINDOWS
+		perror("bind");
+#endif
+		goto err;
+		}
+	/* Make it 128 for linux */
+	if (type==SOCK_STREAM && listen(s,128) == -1) goto err;
+	*sock=s;
+	ret=1;
+err:
+	if ((ret == 0) && (s != -1))
+		{
+		SHUTDOWN(s);
+		}
+	return(ret);
+	}
+
+static int init_server(int *sock, int port, int type)
+	{
+	return(init_server_long(sock, port, NULL, type));
+	}
+
+static int do_accept(int acc_sock, int *sock, char **host)
+	{
+	int ret;
+	struct hostent *h1,*h2;
+	static struct sockaddr_in from;
+	int len;
+/*	struct linger ling; */
+
+	if (!ssl_sock_init()) return(0);
+
+#ifndef OPENSSL_SYS_WINDOWS
+redoit:
+#endif
+
+	memset((char *)&from,0,sizeof(from));
+	len=sizeof(from);
+	/* Note: under VMS with SOCKETSHR the fourth parameter is currently
+	 * of type (int *) whereas under other systems it is (void *) if
+	 * you don't have a cast it will choke the compiler: if you do
+	 * have a cast then you can either go for (int *) or (void *).
+	 */
+	ret=accept(acc_sock,(struct sockaddr *)&from,(void *)&len);
+	if (ret == INVALID_SOCKET)
+		{
+#if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
+		int i;
+		i=WSAGetLastError();
+		BIO_printf(bio_err,"accept error %d\n",i);
+#else
+		if (errno == EINTR)
+			{
+			/*check_timeout(); */
+			goto redoit;
+			}
+		fprintf(stderr,"errno=%d ",errno);
+		perror("accept");
+#endif
+		return(0);
+		}
+
+/*
+	ling.l_onoff=1;
+	ling.l_linger=0;
+	i=setsockopt(ret,SOL_SOCKET,SO_LINGER,(char *)&ling,sizeof(ling));
+	if (i < 0) { perror("linger"); return(0); }
+	i=0;
+	i=setsockopt(ret,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
+	if (i < 0) { perror("keepalive"); return(0); }
+*/
+
+	if (host == NULL) goto end;
+#ifndef BIT_FIELD_LIMITS
+	/* I should use WSAAsyncGetHostByName() under windows */
+	h1=gethostbyaddr((char *)&from.sin_addr.s_addr,
+		sizeof(from.sin_addr.s_addr),AF_INET);
+#else
+	h1=gethostbyaddr((char *)&from.sin_addr,
+		sizeof(struct in_addr),AF_INET);
+#endif
+	if (h1 == NULL)
+		{
+		BIO_printf(bio_err,"bad gethostbyaddr\n");
+		*host=NULL;
+		/* return(0); */
+		}
+	else
+		{
+		if ((*host=(char *)OPENSSL_malloc(strlen(h1->h_name)+1)) == NULL)
+			{
+			perror("OPENSSL_malloc");
+			return(0);
+			}
+		BUF_strlcpy(*host,h1->h_name,strlen(h1->h_name)+1);
+
+		h2=GetHostByName(*host);
+		if (h2 == NULL)
+			{
+			BIO_printf(bio_err,"gethostbyname failure\n");
+			return(0);
+			}
+		if (h2->h_addrtype != AF_INET)
+			{
+			BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n");
+			return(0);
+			}
+		}
+end:
+	*sock=ret;
+	return(1);
+	}
+
+int extract_host_port(char *str, char **host_ptr, unsigned char *ip,
+	     short *port_ptr)
+	{
+	char *h,*p;
+
+	h=str;
+	p=strchr(str,':');
+	if (p == NULL)
+		{
+		BIO_printf(bio_err,"no port defined\n");
+		return(0);
+		}
+	*(p++)='\0';
+
+	if ((ip != NULL) && !host_ip(str,ip))
+		goto err;
+	if (host_ptr != NULL) *host_ptr=h;
+
+	if (!extract_port(p,port_ptr))
+		goto err;
+	return(1);
+err:
+	return(0);
+	}
+
+static int host_ip(char *str, unsigned char ip[4])
+	{
+	unsigned int in[4]; 
+	int i;
+
+	if (sscanf(str,"%u.%u.%u.%u",&(in[0]),&(in[1]),&(in[2]),&(in[3])) == 4)
+		{
+		for (i=0; i<4; i++)
+			if (in[i] > 255)
+				{
+				BIO_printf(bio_err,"invalid IP address\n");
+				goto err;
+				}
+		ip[0]=in[0];
+		ip[1]=in[1];
+		ip[2]=in[2];
+		ip[3]=in[3];
+		}
+	else
+		{ /* do a gethostbyname */
+		struct hostent *he;
+
+		if (!ssl_sock_init()) return(0);
+
+		he=GetHostByName(str);
+		if (he == NULL)
+			{
+			BIO_printf(bio_err,"gethostbyname failure\n");
+			goto err;
+			}
+		/* cast to short because of win16 winsock definition */
+		if ((short)he->h_addrtype != AF_INET)
+			{
+			BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n");
+			return(0);
+			}
+		ip[0]=he->h_addr_list[0][0];
+		ip[1]=he->h_addr_list[0][1];
+		ip[2]=he->h_addr_list[0][2];
+		ip[3]=he->h_addr_list[0][3];
+		}
+	return(1);
+err:
+	return(0);
+	}
+
+int extract_port(char *str, short *port_ptr)
+	{
+	int i;
+	struct servent *s;
+
+	i=atoi(str);
+	if (i != 0)
+		*port_ptr=(unsigned short)i;
+	else
+		{
+		s=getservbyname(str,"tcp");
+		if (s == NULL)
+			{
+			BIO_printf(bio_err,"getservbyname failure for %s\n",str);
+			return(0);
+			}
+		*port_ptr=ntohs((unsigned short)s->s_port);
+		}
+	return(1);
+	}
+
+#define GHBN_NUM	4
+static struct ghbn_cache_st
+	{
+	char name[128];
+	struct hostent ent;
+	unsigned long order;
+	} ghbn_cache[GHBN_NUM];
+
+static unsigned long ghbn_hits=0L;
+static unsigned long ghbn_miss=0L;
+
+static struct hostent *GetHostByName(char *name)
+	{
+	struct hostent *ret;
+	int i,lowi=0;
+	unsigned long low= (unsigned long)-1;
+
+	for (i=0; i<GHBN_NUM; i++)
+		{
+		if (low > ghbn_cache[i].order)
+			{
+			low=ghbn_cache[i].order;
+			lowi=i;
+			}
+		if (ghbn_cache[i].order > 0)
+			{
+			if (strncmp(name,ghbn_cache[i].name,128) == 0)
+				break;
+			}
+		}
+	if (i == GHBN_NUM) /* no hit*/
+		{
+		ghbn_miss++;
+		ret=gethostbyname(name);
+		if (ret == NULL) return(NULL);
+		/* else add to cache */
+		if(strlen(name) < sizeof ghbn_cache[0].name)
+			{
+			strcpy(ghbn_cache[lowi].name,name);
+			memcpy((char *)&(ghbn_cache[lowi].ent),ret,sizeof(struct hostent));
+			ghbn_cache[lowi].order=ghbn_miss+ghbn_hits;
+			}
+		return(ret);
+		}
+	else
+		{
+		ghbn_hits++;
+		ret= &(ghbn_cache[i].ent);
+		ghbn_cache[i].order=ghbn_miss+ghbn_hits;
+		return(ret);
+		}
+	}
+
+#endif
diff --git a/openssl/apps/s_time.c b/openssl/apps/s_time.c
new file mode 100644
index 0000000..b823c33
--- /dev/null
+++ b/openssl/apps/s_time.c
@@ -0,0 +1,632 @@
+/* apps/s_time.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#define NO_SHUTDOWN
+
+/*-----------------------------------------
+   s_time - SSL client connection timer program
+   Written and donated by Larry Streepy <streepy@healthcare.com>
+  -----------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define USE_SOCKETS
+#include "apps.h"
+#ifdef OPENSSL_NO_STDIO
+#define APPS_WIN16
+#endif
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include <openssl/pem.h>
+#include "s_apps.h"
+#include <openssl/err.h>
+#ifdef WIN32_STUFF
+#include "winmain.h"
+#include "wintext.h"
+#endif
+#if !defined(OPENSSL_SYS_MSDOS)
+#include OPENSSL_UNISTD
+#endif
+
+#undef PROG
+#define PROG s_time_main
+
+#undef ioctl
+#define ioctl ioctlsocket
+
+#define SSL_CONNECT_NAME	"localhost:4433"
+
+/*#define TEST_CERT "client.pem" */ /* no default cert. */
+
+#undef BUFSIZZ
+#define BUFSIZZ 1024*10
+
+#define MYBUFSIZ 1024*8
+
+#undef min
+#undef max
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+
+#undef SECONDS
+#define SECONDS	30
+extern int verify_depth;
+extern int verify_error;
+
+static void s_time_usage(void);
+static int parseArgs( int argc, char **argv );
+static SSL *doConnection( SSL *scon );
+static void s_time_init(void);
+
+/***********************************************************************
+ * Static data declarations
+ */
+
+/* static char *port=PORT_STR;*/
+static char *host=SSL_CONNECT_NAME;
+static char *t_cert_file=NULL;
+static char *t_key_file=NULL;
+static char *CApath=NULL;
+static char *CAfile=NULL;
+static char *tm_cipher=NULL;
+static int tm_verify = SSL_VERIFY_NONE;
+static int maxTime = SECONDS;
+static SSL_CTX *tm_ctx=NULL;
+static const SSL_METHOD *s_time_meth=NULL;
+static char *s_www_path=NULL;
+static long bytes_read=0; 
+static int st_bugs=0;
+static int perform=0;
+#ifdef FIONBIO
+static int t_nbio=0;
+#endif
+#ifdef OPENSSL_SYS_WIN32
+static int exitNow = 0;		/* Set when it's time to exit main */
+#endif
+
+static void s_time_init(void)
+	{
+	host=SSL_CONNECT_NAME;
+	t_cert_file=NULL;
+	t_key_file=NULL;
+	CApath=NULL;
+	CAfile=NULL;
+	tm_cipher=NULL;
+	tm_verify = SSL_VERIFY_NONE;
+	maxTime = SECONDS;
+	tm_ctx=NULL;
+	s_time_meth=NULL;
+	s_www_path=NULL;
+	bytes_read=0; 
+	st_bugs=0;
+	perform=0;
+
+#ifdef FIONBIO
+	t_nbio=0;
+#endif
+#ifdef OPENSSL_SYS_WIN32
+	exitNow = 0;		/* Set when it's time to exit main */
+#endif
+	}
+
+/***********************************************************************
+ * usage - display usage message
+ */
+static void s_time_usage(void)
+{
+	static char umsg[] = "\
+-time arg     - max number of seconds to collect data, default %d\n\
+-verify arg   - turn on peer certificate verification, arg == depth\n\
+-cert arg     - certificate file to use, PEM format assumed\n\
+-key arg      - RSA file to use, PEM format assumed, key is in cert file\n\
+                file if not specified by this option\n\
+-CApath arg   - PEM format directory of CA's\n\
+-CAfile arg   - PEM format file of CA's\n\
+-cipher       - preferred cipher to use, play with 'openssl ciphers'\n\n";
+
+	printf( "usage: s_time <args>\n\n" );
+
+	printf("-connect host:port - host:port to connect to (default is %s)\n",SSL_CONNECT_NAME);
+#ifdef FIONBIO
+	printf("-nbio         - Run with non-blocking IO\n");
+	printf("-ssl2         - Just use SSLv2\n");
+	printf("-ssl3         - Just use SSLv3\n");
+	printf("-bugs         - Turn on SSL bug compatibility\n");
+	printf("-new          - Just time new connections\n");
+	printf("-reuse        - Just time connection reuse\n");
+	printf("-www page     - Retrieve 'page' from the site\n");
+#endif
+	printf( umsg,SECONDS );
+}
+
+/***********************************************************************
+ * parseArgs - Parse command line arguments and initialize data
+ *
+ * Returns 0 if ok, -1 on bad args
+ */
+static int parseArgs(int argc, char **argv)
+{
+    int badop = 0;
+
+    verify_depth=0;
+    verify_error=X509_V_OK;
+
+    argc--;
+    argv++;
+
+    while (argc >= 1) {
+	if (strcmp(*argv,"-connect") == 0)
+		{
+		if (--argc < 1) goto bad;
+		host= *(++argv);
+		}
+#if 0
+	else if( strcmp(*argv,"-host") == 0)
+		{
+		if (--argc < 1) goto bad;
+		host= *(++argv);
+		}
+	else if( strcmp(*argv,"-port") == 0)
+		{
+		if (--argc < 1) goto bad;
+		port= *(++argv);
+		}
+#endif
+	else if (strcmp(*argv,"-reuse") == 0)
+		perform=2;
+	else if (strcmp(*argv,"-new") == 0)
+		perform=1;
+	else if( strcmp(*argv,"-verify") == 0) {
+
+	    tm_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE;
+	    if (--argc < 1) goto bad;
+	    verify_depth=atoi(*(++argv));
+	    BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
+
+	} else if( strcmp(*argv,"-cert") == 0) {
+
+	    if (--argc < 1) goto bad;
+	    t_cert_file= *(++argv);
+
+	} else if( strcmp(*argv,"-key") == 0) {
+
+	    if (--argc < 1) goto bad;
+	    t_key_file= *(++argv);
+
+	} else if( strcmp(*argv,"-CApath") == 0) {
+
+	    if (--argc < 1) goto bad;
+	    CApath= *(++argv);
+
+	} else if( strcmp(*argv,"-CAfile") == 0) {
+
+	    if (--argc < 1) goto bad;
+	    CAfile= *(++argv);
+
+	} else if( strcmp(*argv,"-cipher") == 0) {
+
+	    if (--argc < 1) goto bad;
+	    tm_cipher= *(++argv);
+	}
+#ifdef FIONBIO
+	else if(strcmp(*argv,"-nbio") == 0) {
+	    t_nbio=1;
+	}
+#endif
+	else if(strcmp(*argv,"-www") == 0)
+		{
+		if (--argc < 1) goto bad;
+		s_www_path= *(++argv);
+		if(strlen(s_www_path) > MYBUFSIZ-100)
+			{
+			BIO_printf(bio_err,"-www option too long\n");
+			badop=1;
+			}
+		}
+	else if(strcmp(*argv,"-bugs") == 0)
+	    st_bugs=1;
+#ifndef OPENSSL_NO_SSL2
+	else if(strcmp(*argv,"-ssl2") == 0)
+	    s_time_meth=SSLv2_client_method();
+#endif
+#ifndef OPENSSL_NO_SSL3
+	else if(strcmp(*argv,"-ssl3") == 0)
+	    s_time_meth=SSLv3_client_method();
+#endif
+	else if( strcmp(*argv,"-time") == 0) {
+
+	    if (--argc < 1) goto bad;
+	    maxTime= atoi(*(++argv));
+	}
+	else {
+	    BIO_printf(bio_err,"unknown option %s\n",*argv);
+	    badop=1;
+	    break;
+	}
+
+	argc--;
+	argv++;
+    }
+
+    if (perform == 0) perform=3;
+
+    if(badop) {
+bad:
+		s_time_usage();
+		return -1;
+    }
+
+	return 0;			/* Valid args */
+}
+
+/***********************************************************************
+ * TIME - time functions
+ */
+#define START	0
+#define STOP	1
+
+static double tm_Time_F(int s)
+	{
+	return app_tminterval(s,1);
+	}
+
+/***********************************************************************
+ * MAIN - main processing area for client
+ *			real name depends on MONOLITH
+ */
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	double totalTime = 0.0;
+	int nConn = 0;
+	SSL *scon=NULL;
+	long finishtime=0;
+	int ret=1,i;
+	MS_STATIC char buf[1024*8];
+	int ver;
+
+	apps_startup();
+	s_time_init();
+
+	if (bio_err == NULL)
+		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+
+#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
+	s_time_meth=SSLv23_client_method();
+#elif !defined(OPENSSL_NO_SSL3)
+	s_time_meth=SSLv3_client_method();
+#elif !defined(OPENSSL_NO_SSL2)
+	s_time_meth=SSLv2_client_method();
+#endif
+
+	/* parse the command line arguments */
+	if( parseArgs( argc, argv ) < 0 )
+		goto end;
+
+	OpenSSL_add_ssl_algorithms();
+	if ((tm_ctx=SSL_CTX_new(s_time_meth)) == NULL) return(1);
+
+	SSL_CTX_set_quiet_shutdown(tm_ctx,1);
+
+	if (st_bugs) SSL_CTX_set_options(tm_ctx,SSL_OP_ALL);
+	SSL_CTX_set_cipher_list(tm_ctx,tm_cipher);
+	if(!set_cert_stuff(tm_ctx,t_cert_file,t_key_file)) 
+		goto end;
+
+	SSL_load_error_strings();
+
+	if ((!SSL_CTX_load_verify_locations(tm_ctx,CAfile,CApath)) ||
+		(!SSL_CTX_set_default_verify_paths(tm_ctx)))
+		{
+		/* BIO_printf(bio_err,"error setting default verify locations\n"); */
+		ERR_print_errors(bio_err);
+		/* goto end; */
+		}
+
+	if (tm_cipher == NULL)
+		tm_cipher = getenv("SSL_CIPHER");
+
+	if (tm_cipher == NULL ) {
+		fprintf( stderr, "No CIPHER specified\n" );
+	}
+
+	if (!(perform & 1)) goto next;
+	printf( "Collecting connection statistics for %d seconds\n", maxTime );
+
+	/* Loop and time how long it takes to make connections */
+
+	bytes_read=0;
+	finishtime=(long)time(NULL)+maxTime;
+	tm_Time_F(START);
+	for (;;)
+		{
+		if (finishtime < (long)time(NULL)) break;
+#ifdef WIN32_STUFF
+
+		if( flushWinMsgs(0) == -1 )
+			goto end;
+
+		if( waitingToDie || exitNow )		/* we're dead */
+			goto end;
+#endif
+
+		if( (scon = doConnection( NULL )) == NULL )
+			goto end;
+
+		if (s_www_path != NULL)
+			{
+			BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
+			SSL_write(scon,buf,strlen(buf));
+			while ((i=SSL_read(scon,buf,sizeof(buf))) > 0)
+				bytes_read+=i;
+			}
+
+#ifdef NO_SHUTDOWN
+		SSL_set_shutdown(scon,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+#else
+		SSL_shutdown(scon);
+#endif
+		SHUTDOWN2(SSL_get_fd(scon));
+
+		nConn += 1;
+		if (SSL_session_reused(scon))
+			ver='r';
+		else
+			{
+			ver=SSL_version(scon);
+			if (ver == TLS1_VERSION)
+				ver='t';
+			else if (ver == SSL3_VERSION)
+				ver='3';
+			else if (ver == SSL2_VERSION)
+				ver='2';
+			else
+				ver='*';
+			}
+		fputc(ver,stdout);
+		fflush(stdout);
+
+		SSL_free( scon );
+		scon=NULL;
+		}
+	totalTime += tm_Time_F(STOP); /* Add the time for this iteration */
+
+	i=(int)((long)time(NULL)-finishtime+maxTime);
+	printf( "\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double)nConn/totalTime),bytes_read);
+	printf( "%d connections in %ld real seconds, %ld bytes read per connection\n",nConn,(long)time(NULL)-finishtime+maxTime,bytes_read/nConn);
+
+	/* Now loop and time connections using the same session id over and over */
+
+next:
+	if (!(perform & 2)) goto end;
+	printf( "\n\nNow timing with session id reuse.\n" );
+
+	/* Get an SSL object so we can reuse the session id */
+	if( (scon = doConnection( NULL )) == NULL )
+		{
+		fprintf( stderr, "Unable to get connection\n" );
+		goto end;
+		}
+
+	if (s_www_path != NULL)
+		{
+		BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
+		SSL_write(scon,buf,strlen(buf));
+		while (SSL_read(scon,buf,sizeof(buf)) > 0)
+			;
+		}
+#ifdef NO_SHUTDOWN
+	SSL_set_shutdown(scon,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+#else
+	SSL_shutdown(scon);
+#endif
+	SHUTDOWN2(SSL_get_fd(scon));
+
+	nConn = 0;
+	totalTime = 0.0;
+
+	finishtime=(long)time(NULL)+maxTime;
+
+	printf( "starting\n" );
+	bytes_read=0;
+	tm_Time_F(START);
+		
+	for (;;)
+		{
+		if (finishtime < (long)time(NULL)) break;
+
+#ifdef WIN32_STUFF
+		if( flushWinMsgs(0) == -1 )
+			goto end;
+
+		if( waitingToDie || exitNow )	/* we're dead */
+			goto end;
+#endif
+
+	 	if( (doConnection( scon )) == NULL )
+			goto end;
+
+		if (s_www_path)
+			{
+			BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
+			SSL_write(scon,buf,strlen(buf));
+			while ((i=SSL_read(scon,buf,sizeof(buf))) > 0)
+				bytes_read+=i;
+			}
+
+#ifdef NO_SHUTDOWN
+		SSL_set_shutdown(scon,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+#else
+		SSL_shutdown(scon);
+#endif
+		SHUTDOWN2(SSL_get_fd(scon));
+	
+		nConn += 1;
+		if (SSL_session_reused(scon))
+			ver='r';
+		else
+			{
+			ver=SSL_version(scon);
+			if (ver == TLS1_VERSION)
+				ver='t';
+			else if (ver == SSL3_VERSION)
+				ver='3';
+			else if (ver == SSL2_VERSION)
+				ver='2';
+			else
+				ver='*';
+			}
+		fputc(ver,stdout);
+		fflush(stdout);
+		}
+	totalTime += tm_Time_F(STOP); /* Add the time for this iteration*/
+
+
+	printf( "\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double)nConn/totalTime),bytes_read);
+	printf( "%d connections in %ld real seconds, %ld bytes read per connection\n",nConn,(long)time(NULL)-finishtime+maxTime,bytes_read/nConn);
+
+	ret=0;
+end:
+	if (scon != NULL) SSL_free(scon);
+
+	if (tm_ctx != NULL)
+		{
+		SSL_CTX_free(tm_ctx);
+		tm_ctx=NULL;
+		}
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
+/***********************************************************************
+ * doConnection - make a connection
+ * Args:
+ *		scon	= earlier ssl connection for session id, or NULL
+ * Returns:
+ *		SSL *	= the connection pointer.
+ */
+static SSL *doConnection(SSL *scon)
+	{
+	BIO *conn;
+	SSL *serverCon;
+	int width, i;
+	fd_set readfds;
+
+	if ((conn=BIO_new(BIO_s_connect())) == NULL)
+		return(NULL);
+
+/*	BIO_set_conn_port(conn,port);*/
+	BIO_set_conn_hostname(conn,host);
+
+	if (scon == NULL)
+		serverCon=SSL_new(tm_ctx);
+	else
+		{
+		serverCon=scon;
+		SSL_set_connect_state(serverCon);
+		}
+
+	SSL_set_bio(serverCon,conn,conn);
+
+#if 0
+	if( scon != NULL )
+		SSL_set_session(serverCon,SSL_get_session(scon));
+#endif
+
+	/* ok, lets connect */
+	for(;;) {
+		i=SSL_connect(serverCon);
+		if (BIO_sock_should_retry(i))
+			{
+			BIO_printf(bio_err,"DELAY\n");
+
+			i=SSL_get_fd(serverCon);
+			width=i+1;
+			FD_ZERO(&readfds);
+			openssl_fdset(i,&readfds);
+			/* Note: under VMS with SOCKETSHR the 2nd parameter
+			 * is currently of type (int *) whereas under other
+			 * systems it is (void *) if you don't have a cast it
+			 * will choke the compiler: if you do have a cast then
+			 * you can either go for (int *) or (void *).
+			 */
+			select(width,(void *)&readfds,NULL,NULL,NULL);
+			continue;
+			}
+		break;
+		}
+	if(i <= 0)
+		{
+		BIO_printf(bio_err,"ERROR\n");
+		if (verify_error != X509_V_OK)
+			BIO_printf(bio_err,"verify error:%s\n",
+				X509_verify_cert_error_string(verify_error));
+		else
+			ERR_print_errors(bio_err);
+		if (scon == NULL)
+			SSL_free(serverCon);
+		return NULL;
+		}
+
+	return serverCon;
+	}
+
+
diff --git a/openssl/apps/server.pem b/openssl/apps/server.pem
new file mode 100644
index 0000000..56248e5
--- /dev/null
+++ b/openssl/apps/server.pem
@@ -0,0 +1,369 @@
+issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit)
+subject= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Server test cert (512 bit)
+-----BEGIN CERTIFICATE-----
+MIIB6TCCAVICAQYwDQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCQVUxEzARBgNV
+BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYD
+VQQDExJUZXN0IENBICgxMDI0IGJpdCkwHhcNMDAxMDE2MjIzMTAzWhcNMDMwMTE0
+MjIzMTAzWjBjMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEaMBgG
+A1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxIzAhBgNVBAMTGlNlcnZlciB0ZXN0IGNl
+cnQgKDUxMiBiaXQpMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ+zw4Qnlf8SMVIP
+Fe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVDTGiXav6ooKXfX3j/7tdkuD8Ey2//
+Kv7+ue0CAwEAATANBgkqhkiG9w0BAQQFAAOBgQCT0grFQeZaqYb5EYfk20XixZV4
+GmyAbXMftG1Eo7qGiMhYzRwGNWxEYojf5PZkYZXvSqZ/ZXHXa4g59jK/rJNnaVGM
+k+xIX8mxQvlV0n5O9PIha5BX5teZnkHKgL8aKKLKW1BK7YTngsfSzzaeame5iKfz
+itAE+OjGF+PFKbwX8Q==
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIBPAIBAAJBAJ+zw4Qnlf8SMVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVD
+TGiXav6ooKXfX3j/7tdkuD8Ey2//Kv7+ue0CAwEAAQJAN6W31vDEP2DjdqhzCDDu
+OA4NACqoiFqyblo7yc2tM4h4xMbC3Yx5UKMN9ZkCtX0gzrz6DyF47bdKcWBzNWCj
+gQIhANEoojVt7hq+SQ6MCN6FTAysGgQf56Q3TYoJMoWvdiXVAiEAw3e3rc+VJpOz
+rHuDo6bgpjUAAXM+v3fcpsfZSNO6V7kCIQCtbVjanpUwvZkMI9by02oUk9taki3b
+PzPfAfNPYAbCJQIhAJXNQDWyqwn/lGmR11cqY2y9nZ1+5w3yHGatLrcDnQHxAiEA
+vnlEGo8K85u+KwIOimM48ZG8oTk7iFdkqLJR1utT3aU=
+-----END RSA PRIVATE KEY-----
+subject=/C=US/O=AT&T Bell Laboratories/OU=Prototype Research CA
+issuer= /C=US/O=AT&T Bell Laboratories/OU=Prototype Research CA
+notBefore=950413210656Z
+notAfter =970412210656Z
+-----BEGIN X509 CERTIFICATE-----
+
+MIICCDCCAXECAQAwDQYJKoZIhvcNAQEEBQAwTjELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoUFkFUJlQgQmVsbCBMYWJvcmF0b3JpZXMxHjAcBgNVBAsUFVByb3RvdHlwZSBS
+ZXNlYXJjaCBDQTAeFw05NTA0MTMyMTA2NTZaFw05NzA0MTIyMTA2NTZaME4xCzAJ
+BgNVBAYTAlVTMR8wHQYDVQQKFBZBVCZUIEJlbGwgTGFib3JhdG9yaWVzMR4wHAYD
+VQQLFBVQcm90b3R5cGUgUmVzZWFyY2ggQ0EwgZwwDQYJKoZIhvcNAQEBBQADgYoA
+MIGGAoGAebOmgtSCl+wCYZc86UGYeTLY8cjmW2P0FN8ToT/u2pECCoFdrlycX0OR
+3wt0ZhpFXLVNeDnHwEE9veNUih7pCL2ZBFqoIoQkB1lZmXRiVtjGonz8BLm/qrFM
+YHb0lme/Ol+s118mwKVxnn6bSAeI/OXKhLaVdYZWk+aEaxEDkVkCAQ8wDQYJKoZI
+hvcNAQEEBQADgYEAAZMG14lZmZ8bahkaHaTV9dQf4p2FZiQTFwHP9ZyGsXPC+LT5
+dG5iTaRmyjNIJdPWohZDl97kAci79aBndvuEvRKOjLHs3WRGBIwERnAcnY9Mz8u/
+zIHK23PjYVxGGaZd669OJwD0CYyqH22HH9nFUGaoJdsv39ChW0NRdLE9+y8=
+-----END X509 CERTIFICATE-----
+issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test PCA (1024 bit)
+subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit)
+-----BEGIN CERTIFICATE-----
+MIICJjCCAY8CAQAwDQYJKoZIhvcNAQEEBQAwXDELMAkGA1UEBhMCQVUxEzARBgNV
+BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYD
+VQQDExNUZXN0IFBDQSAoMTAyNCBiaXQpMB4XDTk3MDYwOTEzNTc0M1oXDTAxMDYw
+OTEzNTc0M1owWzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxGjAY
+BgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYDVQQDExJUZXN0IENBICgxMDI0
+IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKO7o8t116VP6cgybTsZ
+DCZhr95nYlZuya3aCi1IKoztqwWnjbmDFIriOqGFPrZQ+moMETC9D59iRW/dFXSv
+1F65ka/XY2hLh9exCCo7XuUcDs53Qp3bI3AmMqHjgzE8oO3ajyJAzJkTTOUecQU2
+mw/gI4tMM0LqWMQS7luTy4+xAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAM7achv3v
+hLQJcv/65eGEpBXM40ZDVoFQFFJWaY5p883HTqLB1x4FdzsXHH0QKBTcKpWwqyu4
+YDm3fb8oDugw72bCzfyZK/zVZPR/hVlqI/fvU109Qoc+7oPvIXWky71HfcK6ZBCA
+q30KIqGM/uoM60INq97qjDmCJapagcNBGQs=
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQCju6PLddelT+nIMm07GQwmYa/eZ2JWbsmt2gotSCqM7asFp425
+gxSK4jqhhT62UPpqDBEwvQ+fYkVv3RV0r9ReuZGv12NoS4fXsQgqO17lHA7Od0Kd
+2yNwJjKh44MxPKDt2o8iQMyZE0zlHnEFNpsP4COLTDNC6ljEEu5bk8uPsQIDAQAB
+AoGAVZmpFZsDZfr0l2S9tLLwpjRWNOlKATQkno6q2WesT0eGLQufTciY+c8ypfU6
+hyio8r5iUl/VhhdjhAtKx1mRpiotftHo/eYf8rtsrnprOnWG0bWjLjtIoMbcxGn2
+J3bN6LJmbJMjDs0eJ3KnTu646F3nDUw2oGAwmpzKXA1KAP0CQQDRvQhxk2D3Pehs
+HvG665u2pB5ipYQngEFlZO7RHJZzJOZEWSLuuMqaF/7pTfA5jiBvWqCgJeCRRInL
+21ru4dlPAkEAx9jj7BgKn5TYnMoBSSe0afjsV9oApVpN1Nacb1YDtCwy+scp3++s
+nFxlv98wxIlSdpwMUn+AUWfjiWR7Tu/G/wJBAJ/KjwZIrFVxewP0x2ILYsTRYLzz
+MS4PDsO7FB+I0i7DbBOifXS2oNSpd3I0CNMwrxFnUHzynpbOStVfN3ZL5w0CQQCa
+pwFahxBRhkJKsxhjoFJBX9yl75JoY4Wvm5Tbo9ih6UJaRx3kqfkN14L2BKYcsZgb
+KY9vmDOYy6iNfjDeWTfJAkBkfPUb8oTJ/nSP5zN6sqGxSY4krc4xLxpRmxoJ8HL2
+XfhqXkTzbU13RX9JJ/NZ8vQN9Vm2NhxRGJocQkmcdVtJ
+-----END RSA PRIVATE KEY-----
+-----BEGIN X509 CERTIFICATE-----
+MIICYDCCAiACAgEoMAkGBSsOAwINBQAwfDELMAkGA1UEBhMCVVMxNjA0BgNVBAoT
+LU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEZ
+MBcGA1UECxMQVGVzdCBFbnZpcm9ubWVudDEaMBgGA1UECxMRRFNTLU5BU0EtUGls
+b3QtQ0EwHhcNOTYwMjI2MTYzMjQ1WhcNOTcwMjI1MTYzMjQ1WjB8MQswCQYDVQQG
+EwJVUzE2MDQGA1UEChMtTmF0aW9uYWwgQWVyb25hdXRpY3MgYW5kIFNwYWNlIEFk
+bWluaXN0cmF0aW9uMRkwFwYDVQQLExBUZXN0IEVudmlyb25tZW50MRowGAYDVQQL
+ExFEU1MtTkFTQS1QaWxvdC1DQTCB8jAJBgUrDgMCDAUAA4HkADCB4AJBAMA/ssKb
+hPNUG7ZlASfVwEJU21O5OyF/iyBzgHI1O8eOhJGUYO8cc8wDMjR508Mr9cp6Uhl/
+ZB7FV5GkLNEnRHYCQQDUEaSg45P2qrDwixTRhFhmWz5Nvc4lRFQ/42XPcchiJBLb
+bn3QK74T2IxY1yY+kCNq8XrIqf5fJJzIH0J/xUP3AhUAsg2wsQHfDGYk/BOSulX3
+fVd0geUCQQCzCFUQAh+ZkEmp5804cs6ZWBhrUAfnra8lJItYo9xPcXgdIfLfibcX
+R71UsyO77MRD7B0+Ag2tq794IleCVcEEMAkGBSsOAwINBQADLwAwLAIUUayDfreR
+Yh2WeU86/pHNdkUC1IgCFEfxe1f0oMpxJyrJ5XIxTi7vGdoK
+-----END X509 CERTIFICATE-----
+-----BEGIN X509 CERTIFICATE-----
+
+MIICGTCCAdgCAwCqTDAJBgUrDgMCDQUAMHwxCzAJBgNVBAYTAlVTMTYwNAYDVQQK
+Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x
+GTAXBgNVBAsTEFRlc3QgRW52aXJvbm1lbnQxGjAYBgNVBAsTEURTUy1OQVNBLVBp
+bG90LUNBMB4XDTk2MDUxNDE3MDE0MVoXDTk3MDUxNDE3MDE0MVowMzELMAkGA1UE
+BhMCQVUxDzANBgNVBAoTBk1pbmNvbTETMBEGA1UEAxMKRXJpYyBZb3VuZzCB8jAJ
+BgUrDgMCDAUAA4HkADCB4AJBAKbfHz6vE6pXXMTpswtGUec2tvnfLJUsoxE9qs4+
+ObZX7LmLvragNPUeiTJx7UOWZ5DfBj6bXLc8eYne0lP1g3ACQQDUEaSg45P2qrDw
+ixTRhFhmWz5Nvc4lRFQ/42XPcchiJBLbbn3QK74T2IxY1yY+kCNq8XrIqf5fJJzI
+H0J/xUP3AhUAsg2wsQHfDGYk/BOSulX3fVd0geUCQQCzCFUQAh+ZkEmp5804cs6Z
+WBhrUAfnra8lJItYo9xPcXgdIfLfibcXR71UsyO77MRD7B0+Ag2tq794IleCVcEE
+MAkGBSsOAwINBQADMAAwLQIUWsuuJRE3VT4ueWkWMAJMJaZjj1ECFQCYY0zX4bzM
+LC7obsrHD8XAHG+ZRG==
+-----END X509 CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICTTCCAbagAwIBAgIBADANBgkqhkiG9w0BAQQFADBMMQswCQYDVQQGEwJHQjEM
+MAoGA1UEChMDVUNMMRgwFgYDVQQLEw9JQ0UtVEVMIFByb2plY3QxFTATBgNVBAMT
+DFRydXN0RmFjdG9yeTAeFw05NzA0MjIxNDM5MTRaFw05ODA0MjIxNDM5MTRaMEwx
+CzAJBgNVBAYTAkdCMQwwCgYDVQQKEwNVQ0wxGDAWBgNVBAsTD0lDRS1URUwgUHJv
+amVjdDEVMBMGA1UEAxMMVHJ1c3RGYWN0b3J5MIGcMAoGBFUIAQECAgQAA4GNADCB
+iQKBgQCEieR8NcXkUW1f0G6aC6u0i8q/98JqS6RxK5YmHIGKCkuTWAUjzLfUa4dt
+U9igGCjTuxaDqlzEim+t/02pmiBZT9HaX++35MjQPUWmsChcYU5WyzGErXi+rQaw
+zlwS73zM8qiPj/97lXYycWhgL0VaiDSPxRXEUdWoaGruom4mNQIDAQABo0IwQDAd
+BgNVHQ4EFgQUHal1LZr7oVg5z6lYzrhTgZRCmcUwDgYDVR0PAQH/BAQDAgH2MA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAfaggfl6FZoioecjv0dq8
+/DXo/u11iMZvXn08gjX/zl2b4wtPbShOSY5FhkSm8GeySasz+/Nwb/uzfnIhokWi
+lfPZHtlCWtXbIy/TN51eJyq04ceDCQDWvLC2enVg9KB+GJ34b5c5VaPRzq8MBxsA
+S7ELuYGtmYgYm9NZOIr7yU0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIB6jCCAZQCAgEtMA0GCSqGSIb3DQEBBAUAMIGAMQswCQYDVQQGEwJVUzE2MDQG
+A1UEChMtTmF0aW9uYWwgQWVyb25hdXRpY3MgYW5kIFNwYWNlIEFkbWluaXN0cmF0
+aW9uMRkwFwYDVQQLExBUZXN0IEVudmlyb25tZW50MR4wHAYDVQQLExVNRDUtUlNB
+LU5BU0EtUGlsb3QtQ0EwHhcNOTYwNDMwMjIwNTAwWhcNOTcwNDMwMjIwNTAwWjCB
+gDELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu
+ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEZMBcGA1UECxMQVGVzdCBFbnZpcm9ubWVu
+dDEeMBwGA1UECxMVTUQ1LVJTQS1OQVNBLVBpbG90LUNBMFkwCgYEVQgBAQICAgAD
+SwAwSAJBALmmX5+GqAvcrWK13rfDrNX9UfeA7f+ijyBgeFQjYUoDpFqapw4nzQBL
+bAXug8pKkRwa2Zh8YODhXsRWu2F/UckCAwEAATANBgkqhkiG9w0BAQQFAANBAH9a
+OBA+QCsjxXgnSqHx04gcU8S49DVUb1f2XVoLnHlIb8RnX0k5O6mpHT5eti9bLkiW
+GJNMJ4L0AJ/ac+SmHZc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICajCCAdMCBDGA0QUwDQYJKoZIhvcNAQEEBQAwfTELMAkGA1UEBhMCQ2ExDzAN
+BgNVBAcTBk5lcGVhbjEeMBwGA1UECxMVTm8gTGlhYmlsaXR5IEFjY2VwdGVkMR8w
+HQYDVQQKExZGb3IgRGVtbyBQdXJwb3NlcyBPbmx5MRwwGgYDVQQDExNFbnRydXN0
+IERlbW8gV2ViIENBMB4XDTk2MDQyNjEzMzUwMVoXDTA2MDQyNjEzMzUwMVowfTEL
+MAkGA1UEBhMCQ2ExDzANBgNVBAcTBk5lcGVhbjEeMBwGA1UECxMVTm8gTGlhYmls
+aXR5IEFjY2VwdGVkMR8wHQYDVQQKExZGb3IgRGVtbyBQdXJwb3NlcyBPbmx5MRww
+GgYDVQQDExNFbnRydXN0IERlbW8gV2ViIENBMIGdMA0GCSqGSIb3DQEBAQUAA4GL
+ADCBhwKBgQCaroS7O1DA0hm4IefNYU1cx/nqOmzEnk291d1XqznDeF4wEgakbkCc
+zTKxK791yNpXG5RmngqH7cygDRTHZJ6mfCRn0wGC+AI00F2vYTGqPGRQL1N3lZT0
+YDKFC0SQeMMjFIZ1aeQigroFQnHo0VB3zWIMpNkka8PY9lxHZAmWwQIBAzANBgkq
+hkiG9w0BAQQFAAOBgQBAx0UMVA1s54lMQyXjMX5kj99FJN5itb8bK1Rk+cegPQPF
+cWO9SEWyEjjBjIkjjzAwBkaEszFsNGxemxtXvwjIm1xEUMTVlPEWTs2qnDvAUA9W
+YqhWbhH0toGT36236QAsqCZ76rbTRVSSX2BHyJwJMG2tCRv7kRJ//NIgxj3H4w==
+-----END CERTIFICATE-----
+
+issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test PCA (1024 bit)
+subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test PCA (1024 bit)
+-----BEGIN CERTIFICATE-----
+MIICJzCCAZACAQAwDQYJKoZIhvcNAQEEBQAwXDELMAkGA1UEBhMCQVUxEzARBgNV
+BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYD
+VQQDExNUZXN0IFBDQSAoMTAyNCBiaXQpMB4XDTk3MDYwOTEzNTczN1oXDTAxMDYw
+OTEzNTczN1owXDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxGjAY
+BgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYDVQQDExNUZXN0IFBDQSAoMTAy
+NCBiaXQpMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdoWk/3+WcMlfjIrkg
+40ketmnQaEogQe1LLcuOJV6rKfUSAsPgwgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp
+22Jp85PmemiDzyUIStwk72qhp1imbANZvlmlCFKiQrjUyuDfu4TABmn+kkt3vR1Y
+BEOGt+IFye1UBVSATVdRJ2UVhwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABNA1u/S
+Cg/LJZWb7GliiKJsvuhxlE4E5JxQF2zMub/CSNbF97//tYSyj96sxeFQxZXbcjm9
+xt6mr/xNLA4szNQMJ4P+L7b5e/jC5DSqlwS+CUYJgaFs/SP+qJoCSu1bR3IM9XWO
+cRBpDmcBbYLkSyB92WURvsZ1LtjEcn+cdQVI
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQCdoWk/3+WcMlfjIrkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPg
+wgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp22Jp85PmemiDzyUIStwk72qhp1imbANZ
+vlmlCFKiQrjUyuDfu4TABmn+kkt3vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQAB
+AoGAba4fTtuap5l7/8ZsbE7Z1O32KJY4ZcOZukLOLUUhXxXduT+FTgGWujc0/rgc
+z9qYCLlNZHOouMYTgtSfYvuMuLZ11VIt0GYH+nRioLShE59Yy+zCRyC+gPigS1kz
+xvo14AsOIPYV14Tk/SsHyq6E0eTk7VzaIE197giiINUERPECQQDSKmtPTh/lRKw7
+HSZSM0I1mFWn/1zqrAbontRQY5w98QWIOe5qmzYyFbPXYT3d9BzlsMyhgiRNoBbD
+yvohSHXJAkEAwAHx6ezAZeWWzD5yXD36nyjpkVCw7Tk7TSmOceLJMWt1QcrCfqlS
+xA5jjpQ6Z8suU5DdtWAryM2sAir1WisYzwJAd6Zcx56jvAQ3xcPXsE6scBTVFzrj
+7FqZ6E+cclPzfLQ+QQsyOBE7bpI6e/FJppY26XGZXo3YGzV8IGXrt40oOQJALETG
+h86EFXo3qGOFbmsDy4pdP5nBERCu8X1xUCSfintiD4c2DInxgS5oGclnJeMcjTvL
+QjQoJCX3UJCi/OUO1QJBAKgcDHWjMvt+l1pjJBsSEZ0HX9AAIIVx0RQmbFGS+F2Q
+hhu5l77WnnZOQ9vvhV5u7NPCUF9nhU3jh60qWWO8mkc=
+-----END RSA PRIVATE KEY-----
+subject=/C=US/O=RSA Data Security, Inc./OU=Commercial Certification Authority
+issuer= /C=US/O=RSA Data Security, Inc./OU=Commercial Certification Authority
+notBefore=941104185834Z
+notAfter =991103185834Z
+-----BEGIN X509 CERTIFICATE-----
+
+MIICIzCCAZACBQJBAAAWMA0GCSqGSIb3DQEBAgUAMFwxCzAJBgNVBAYTAlVTMSAw
+HgYDVQQKExdSU0EgRGF0YSBTZWN1cml0eSwgSW5jLjErMCkGA1UECxMiQ29tbWVy
+Y2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NDExMDQxODU4MzRaFw05
+OTExMDMxODU4MzRaMFwxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdSU0EgRGF0YSBT
+ZWN1cml0eSwgSW5jLjErMCkGA1UECxMiQ29tbWVyY2lhbCBDZXJ0aWZpY2F0aW9u
+IEF1dGhvcml0eTCBmzANBgkqhkiG9w0BAQEFAAOBiQAwgYUCfgCk+4Fie84QJ93o
+975sbsZwmdu41QUDaSiCnHJ/lj+O7Kwpkj+KFPhCdr69XQO5kNTQvAayUTNfxMK/
+touPmbZiImDd298ggrTKoi8tUO2UMt7gVY3UaOLgTNLNBRYulWZcYVI4HlGogqHE
+7yXpCuaLK44xZtn42f29O2nZ6wIDAQABMA0GCSqGSIb3DQEBAgUAA34AdrW2EP4j
+9/dZYkuwX5zBaLxJu7NJbyFHXSudVMQAKD+YufKKg5tgf+tQx6sFEC097TgCwaVI
+0v5loMC86qYjFmZsGySp8+x5NRhPJsjjr1BKx6cxa9B8GJ1Qv6km+iYrRpwUqbtb
+MJhCKLVLU7tDCZJAuqiqWqTGtotXTcU=
+-----END X509 CERTIFICATE-----
+subject=/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority
+issuer= /C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority
+notBefore=941109235417Z
+notAfter =991231235417Z
+-----BEGIN X509 CERTIFICATE-----
+
+MIICKTCCAZYCBQJBAAABMA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMSAw
+HgYDVQQKExdSU0EgRGF0YSBTZWN1cml0eSwgSW5jLjEuMCwGA1UECxMlU2VjdXJl
+IFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NDExMDkyMzU0MTda
+Fw05OTEyMzEyMzU0MTdaMF8xCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdSU0EgRGF0
+YSBTZWN1cml0eSwgSW5jLjEuMCwGA1UECxMlU2VjdXJlIFNlcnZlciBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eTCBmzANBgkqhkiG9w0BAQEFAAOBiQAwgYUCfgCSznrB
+roM+WqqJg1esJQF2DK2ujiw3zus1eGRUA+WEQFHJv48I4oqCCNIWhjdV6bEhAq12
+aIGaBaJLyUslZiJWbIgHj/eBWW2EB2VwE3F2Ppt3TONQiVaYSLkdpykaEy5KEVmc
+HhXVSVQsczppgrGXOZxtcGdI5d0t1sgeewIDAQABMA0GCSqGSIb3DQEBAgUAA34A
+iNHReSHO4ovo+MF9NFM/YYPZtgs4F7boviGNjwC4i1N+RGceIr2XJ+CchcxK9oU7
+suK+ktPlDemvXA4MRpX/oRxePug2WHpzpgr4IhFrwwk4fia7c+8AvQKk8xQNMD9h
+cHsg/jKjn7P0Z1LctO6EjJY2IN6BCINxIYoPnqk=
+-----END X509 CERTIFICATE-----
+subject=/C=ZA/SP=Western Cape/L=Cape Town/O=Thawte Consulting cc
+	/OU=Certification Services Division/CN=Thawte Server CA
+	/Email=server-certs@thawte.com
+issuer= /C=ZA/SP=Western Cape/L=Cape Town/O=Thawte Consulting cc
+	/OU=Certification Services Division/CN=Thawte Server CA
+	/Email=server-certs@thawte.com
+-----BEGIN CERTIFICATE-----
+MIIC+TCCAmICAQAwDQYJKoZIhvcNAQEEBQAwgcQxCzAJBgNVBAYTAlpBMRUwEwYD
+VQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU
+VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy
+dmljZXMgRGl2aXNpb24xGTAXBgNVBAMTEFRoYXd0ZSBTZXJ2ZXIgQ0ExJjAkBgkq
+hkiG9w0BCQEWF3NlcnZlci1jZXJ0c0B0aGF3dGUuY29tMB4XDTk2MDcyNzE4MDc1
+N1oXDTk4MDcyNzE4MDc1N1owgcQxCzAJBgNVBAYTAlpBMRUwEwYDVQQIEwxXZXN0
+ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMUVGhhd3RlIENv
+bnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2
+aXNpb24xGTAXBgNVBAMTEFRoYXd0ZSBTZXJ2ZXIgQ0ExJjAkBgkqhkiG9w0BCQEW
+F3NlcnZlci1jZXJ0c0B0aGF3dGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDTpFBuyP9Wa+bPXbbqDGh1R6KqwtqEJfyo9EdR2oW1IHSUhh4PdcnpCGH1
+Bm0wbhUZAulSwGLbTZme4moMRDjN/r7jZAlwxf6xaym2L0nIO9QnBCUQly/nkG3A
+KEKZ10xD3sP1IW1Un13DWOHA5NlbsLjctHvfNjrCtWYiEtaHDQIDAQABMA0GCSqG
+SIb3DQEBBAUAA4GBAIsvn7ifX3RUIrvYXtpI4DOfARkTogwm6o7OwVdl93yFhDcX
+7h5t0XZ11MUAMziKdde3rmTvzUYIUCYoY5b032IwGMTvdiclK+STN6NP2m5nvFAM
+qJT5gC5O+j/jBuZRQ4i0AMYQr5F4lT8oBJnhgafw6PL8aDY2vMHGSPl9+7uf
+-----END CERTIFICATE-----
+
+-----BEGIN CERTIFICATE-----
+MIIDDTCCAnYCAQAwDQYJKoZIhvcNAQEEBQAwgc4xCzAJBgNVBAYTAlpBMRUwEwYD
+VQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU
+VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy
+dmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBD
+QTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTAeFw05
+NjA3MjcxODA3MTRaFw05ODA3MjcxODA3MTRaMIHOMQswCQYDVQQGEwJaQTEVMBMG
+A1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xHTAbBgNVBAoT
+FFRoYXd0ZSBDb25zdWx0aW5nIGNjMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNl
+cnZpY2VzIERpdmlzaW9uMSEwHwYDVQQDExhUaGF3dGUgUHJlbWl1bSBTZXJ2ZXIg
+Q0ExKDAmBgkqhkiG9w0BCQEWGXByZW1pdW0tc2VydmVyQHRoYXd0ZS5jb20wgZ8w
+DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANI2NmqL18JbntqBQWKPOO5JBFXW0O8c
+G5UWR+8YSDU6UvQragaPOy/qVuOvho2eF/eetGV1Ak3vywmiIVHYm9Bn0LoNkgYU
+c9STy5cqAJxcTgy8+hVS/PJEbtoRSm4Iny8t4/mqOoZztkZTWMiJBb2DEbhzP6oH
+jfRCTedAnRw3AgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAutFIgTRZVYerIZfL9lvR
+w9Eifvvo5KTZ3h+Bj+VzNnyw4Qc/IyXkPOu6SIiH9LQ3sCmWBdxpe+qr4l77rLj2
+GYuMtESFfn1XVALzkYgC7JcPuTOjMfIiMByt+uFf8AV8x0IW/Qkuv+hEQcyM9vxK
+3VZdLbCVIhNoEsysrxCpxcI=
+-----END CERTIFICATE-----
+Tims test GCI CA
+
+-----BEGIN CERTIFICATE-----
+MIIB8DCCAZoCAQAwDQYJKoZIhvcNAQEEBQAwgYIxCzAJBgNVBAYTAkFVMRMwEQYD
+VQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5
+cHRTb2Z0IFB0eSBMdGQxFDASBgNVBAsTC2RldmVsb3BtZW50MRkwFwYDVQQDExBD
+cnlwdFNvZnQgRGV2IENBMB4XDTk3MDMyMjEzMzQwNFoXDTk4MDMyMjEzMzQwNFow
+gYIxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhC
+cmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxFDASBgNVBAsTC2Rl
+dmVsb3BtZW50MRkwFwYDVQQDExBDcnlwdFNvZnQgRGV2IENBMFwwDQYJKoZIhvcN
+AQEBBQADSwAwSAJBAOAOAqogG5QwAmLhzyO4CoRnx/wVy4NZP4dxJy83O1EnL0rw
+OdsamJKvPOLHgSXo3gDu9uVyvCf/QJmZAmC5ml8CAwEAATANBgkqhkiG9w0BAQQF
+AANBADRRS/GVdd7rAqRW6SdmgLJduOU2yq3avBu99kRqbp9A/dLu6r6jU+eP4oOA
+TfdbFZtAAD2Hx9jUtY3tfdrJOb8= 
+-----END CERTIFICATE-----
+
+-----BEGIN CERTIFICATE-----
+MIICVjCCAgACAQAwDQYJKoZIhvcNAQEEBQAwgbUxCzAJBgNVBAYTAkFVMRMwEQYD
+VQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5
+cHRTb2Z0IFB0eSBMdGQxLDAqBgNVBAsTI1dPUlRITEVTUyBDRVJUSUZJQ0FUSU9O
+IEFVVEhPUklUSUVTMTQwMgYDVQQDEytaRVJPIFZBTFVFIENBIC0gREVNT05TVFJB
+VElPTiBQVVJQT1NFUyBPTkxZMB4XDTk3MDQwMzEzMjI1NFoXDTk4MDQwMzEzMjI1
+NFowgbUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQH
+EwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxLDAqBgNVBAsT
+I1dPUlRITEVTUyBDRVJUSUZJQ0FUSU9OIEFVVEhPUklUSUVTMTQwMgYDVQQDEyta
+RVJPIFZBTFVFIENBIC0gREVNT05TVFJBVElPTiBQVVJQT1NFUyBPTkxZMFwwDQYJ
+KoZIhvcNAQEBBQADSwAwSAJBAOZ7T7yqP/tyspcko3yPY1y0Cm2EmwNvzW4QgVXR
+Fjs3HmJ4xtSpXdo6mwcGezL3Abt/aQXaxv9PU8xt+Jr0OFUCAwEAATANBgkqhkiG
+9w0BAQQFAANBAOQpYmGgyCqCy1OljgJhCqQOu627oVlHzK1L+t9vBaMfn40AVUR4
+WzQVWO31KTgi5vTK1U+3h46fgUWqQ0h+6rU=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIAwgKADAgECAgEAMA0GCSqGSIb3DQEBBAUAMGIxETAPBgNVBAcTCEludGVybmV0
+MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE0MDIGA1UECxMrVmVyaVNpZ24gQ2xh
+c3MgMSBDQSAtIEluZGl2aWR1YWwgU3Vic2NyaWJlcjAeFw05NjA0MDgxMDIwMjda
+Fw05NzA0MDgxMDIwMjdaMGIxETAPBgNVBAcTCEludGVybmV0MRcwFQYDVQQKEw5W
+ZXJpU2lnbiwgSW5jLjE0MDIGA1UECxMrVmVyaVNpZ24gQ2xhc3MgMSBDQSAtIElu
+ZGl2aWR1YWwgU3Vic2NyaWJlcjCAMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2
+FKbPTdAFDdjKI9BvqrQpkmOOLPhvltcunXZLEbE2jVfJw/0cxrr+Hgi6M8qV6r7j
+W80GqLd5HUQq7XPysVKDaBBwZJHXPmv5912dFEObbpdFmIFH0S3L3bty10w/cari
+QPJUObwW7s987LrbP2wqsxaxhhKdrpM01bjV0Pc+qQIDAQABAAAAADANBgkqhkiG
+9w0BAQQFAAOBgQA+1nJryNt8VBRjRr07ArDAV/3jAH7GjDc9jsrxZS68ost9v06C
+TvTNKGL+LISNmFLXl+JXhgGB0JZ9fvyYzNgHQ46HBUng1H6voalfJgS2KdEo50wW
+8EFZYMDkT1k4uynwJqkVN2QJK/2q4/A/VCov5h6SlM8Affg2W+1TLqvqkwAA
+-----END CERTIFICATE-----
+
+ subject=/L=Internet/O=VeriSign, Inc./OU=VeriSign Class 2 CA - Individual Subscriber
+ issuer= /L=Internet/O=VeriSign, Inc./OU=VeriSign Class 2 CA - Individual Subscriber
+
+-----BEGIN CERTIFICATE-----
+MIIEkzCCA/ygAwIBAgIRANDTUpSRL3nTFeMrMayFSPAwDQYJKoZIhvcNAQECBQAw
+YjERMA8GA1UEBxMISW50ZXJuZXQxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTQw
+MgYDVQQLEytWZXJpU2lnbiBDbGFzcyAyIENBIC0gSW5kaXZpZHVhbCBTdWJzY3Jp
+YmVyMB4XDTk2MDYwNDAwMDAwMFoXDTk4MDYwNDIzNTk1OVowYjERMA8GA1UEBxMI
+SW50ZXJuZXQxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTQwMgYDVQQLEytWZXJp
+U2lnbiBDbGFzcyAyIENBIC0gSW5kaXZpZHVhbCBTdWJzY3JpYmVyMIGfMA0GCSqG
+SIb3DQEBAQUAA4GNADCBiQKBgQC6A+2czKGRcYMfm8gdnk+0de99TDDzsqo0v5nb
+RsbUmMcdRQ7nsMbRWe0SAb/9QoLTZ/cJ0iOBqdrkz7UpqqKarVoTSdlSMVM92tWp
+3bJncZHQD1t4xd6lQVdI1/T6R+5J0T1ukOdsI9Jmf+F28S6g3R3L1SFwiHKeZKZv
+z+793wIDAQABo4ICRzCCAkMwggIpBgNVHQMBAf8EggIdMIICGTCCAhUwggIRBgtg
+hkgBhvhFAQcBATCCAgAWggGrVGhpcyBjZXJ0aWZpY2F0ZSBpbmNvcnBvcmF0ZXMg
+YnkgcmVmZXJlbmNlLCBhbmQgaXRzIHVzZSBpcyBzdHJpY3RseSBzdWJqZWN0IHRv
+LCB0aGUgVmVyaVNpZ24gQ2VydGlmaWNhdGlvbiBQcmFjdGljZSBTdGF0ZW1lbnQg
+KENQUyksIGF2YWlsYWJsZSBhdDogaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL0NQ
+Uy0xLjA7IGJ5IEUtbWFpbCBhdCBDUFMtcmVxdWVzdHNAdmVyaXNpZ24uY29tOyBv
+ciBieSBtYWlsIGF0IFZlcmlTaWduLCBJbmMuLCAyNTkzIENvYXN0IEF2ZS4sIE1v
+dW50YWluIFZpZXcsIENBIDk0MDQzIFVTQSBUZWwuICsxICg0MTUpIDk2MS04ODMw
+IENvcHlyaWdodCAoYykgMTk5NiBWZXJpU2lnbiwgSW5jLiAgQWxsIFJpZ2h0cyBS
+ZXNlcnZlZC4gQ0VSVEFJTiBXQVJSQU5USUVTIERJU0NMQUlNRUQgYW5kIExJQUJJ
+TElUWSBMSU1JVEVELqAOBgxghkgBhvhFAQcBAQGhDgYMYIZIAYb4RQEHAQECMC8w
+LRYraHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvQ1BTLTEuMDAU
+BglghkgBhvhCAQEBAf8EBAMCAgQwDQYJKoZIhvcNAQECBQADgYEApRJRkNBqLLgs
+53IR/d18ODdLOWMTZ+QOOxBrq460iBEdUwgF8vmPRX1ku7UiDeNzaLlurE6eFqHq
+2zPyK5j60zfTLVJMWKcQWwTJLjHtXrW8pxhNtFc6Fdvy5ZkHnC/9NIl7/t4U6WqB
+p4y+p7SdMIkEwIZfds0VbnQyX5MRUJY=
+-----END CERTIFICATE-----
+
+ subject=/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
+ issuer= /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
+-----BEGIN CERTIFICATE-----
+MIICMTCCAZoCBQKhAAABMA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMRcw
+FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMyBQdWJsaWMg
+UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NjAxMjkwMDAwMDBa
+Fw05OTEyMzEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2ln
+biwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyVxZ
+nvIbigEUtBDfBEDb41evakVAj4QMC9Ez2dkRz+4CWB8l9yqoRAWq7AMfeH+ek7ma
+AKojfdashaJjRcdyJ8z0TMZ1cdI5709C8HXfCpDGjiBvmA/4rCNfcCk2pMmG57Ga
+IMtTpYXnPb59mv4kRTPcdhXtD6JxZExlLoFoRacCAwEAATANBgkqhkiG9w0BAQIF
+AAOBgQB1Zmw+0c2B27X4LzZRtvdCvM1Cr9wO+hVs+GeTVzrrtpLotgHKjLeOQ7RJ
+Zfk+7r11Ri7J/CVdqMcvi5uPaM+0nJcYwE3vH9mvgrPmZLiEXIqaB1JDYft0nls6
+NvxMsvwaPxUupVs8G5DsiCnkWRb5zget7Ond2tIxik/W2O8XjQ==
+-----END CERTIFICATE-----
+ subject=/C=US/O=VeriSign, Inc./OU=Class 4 Public Primary Certification Authority
+ issuer= /C=US/O=VeriSign, Inc./OU=Class 4 Public Primary Certification Authority
+-----BEGIN CERTIFICATE-----
+MIICMTCCAZoCBQKmAAABMA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMRcw
+FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgNCBQdWJsaWMg
+UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NjAxMjkwMDAwMDBa
+Fw05OTEyMzEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2ln
+biwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0LJ1
+9njQrlpQ9OlQqZ+M1++RlHDo0iSQdomF1t+s5gEXMoDwnZNHvJplnR+Xrr/phnVj
+IIm9gFidBAydqMEk6QvlMXi9/C0MN2qeeIDpRnX57aP7E3vIwUzSo+/1PLBij0pd
+O92VZ48TucE81qcmm+zDO3rZTbxtm+gVAePwR6kCAwEAATANBgkqhkiG9w0BAQIF
+AAOBgQBT3dPwnCR+QKri/AAa19oM/DJhuBUNlvP6Vxt/M3yv6ZiaYch6s7f/sdyZ
+g9ysEvxwyR84Qu1E9oAuW2szaayc01znX1oYx7EteQSWQZGZQbE8DbqEOcY7l/Am
+yY7uvcxClf8exwI/VAx49byqYHwCaejcrOICdmHEPgPq0ook0Q==
+-----END CERTIFICATE-----
diff --git a/openssl/apps/server.srl b/openssl/apps/server.srl
new file mode 100644
index 0000000..8a0f05e
--- /dev/null
+++ b/openssl/apps/server.srl
@@ -0,0 +1 @@
+01
diff --git a/openssl/apps/server2.pem b/openssl/apps/server2.pem
new file mode 100644
index 0000000..8bb6641
--- /dev/null
+++ b/openssl/apps/server2.pem
@@ -0,0 +1,376 @@
+issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit)
+subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Server test cert (1024 bit)
+-----BEGIN CERTIFICATE-----
+MIICLjCCAZcCAQEwDQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCQVUxEzARBgNV
+BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYD
+VQQDExJUZXN0IENBICgxMDI0IGJpdCkwHhcNOTcwNjA5MTM1NzU0WhcNOTgwNjA5
+MTM1NzU0WjBkMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEaMBgG
+A1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxJDAiBgNVBAMTG1NlcnZlciB0ZXN0IGNl
+cnQgKDEwMjQgYml0KTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsxH1PBPm
+RkxrR11eV4bzNi4N9n11CI8nV29+ARlT1+qDe/mjVUvXlmsr1v/vf71G9GgqopSa
+6RXrICLVdk/FYYYzhPvl1M+OrjaXDFO8BzBAF1Lnz6c7aRZvGRJNrRSr2nZEkqDf
+JW9dY7r2VZEpD5QeuaRYUnuECkqeieB65GMCAwEAATANBgkqhkiG9w0BAQQFAAOB
+gQCWsOta6C0wiVzXz8wPmJKyTrurMlgUss2iSuW9366iwofZddsNg7FXniMzkIf6
+dp7jnmWZwKZ9cXsNUS2o4OL07qOk2HOywC0YsNZQsOBu1CBTYYkIefDiKFL1zQHh
+8lwwNd4NP+OE3NzUNkCfh4DnFfg9WHkXUlD5UpxNRJ4gJA==
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQCzEfU8E+ZGTGtHXV5XhvM2Lg32fXUIjydXb34BGVPX6oN7+aNV
+S9eWayvW/+9/vUb0aCqilJrpFesgItV2T8VhhjOE++XUz46uNpcMU7wHMEAXUufP
+pztpFm8ZEk2tFKvadkSSoN8lb11juvZVkSkPlB65pFhSe4QKSp6J4HrkYwIDAQAB
+AoGBAKy8jvb0Lzby8q11yNLf7+78wCVdYi7ugMHcYA1JVFK8+zb1WfSm44FLQo/0
+dSChAjgz36TTexeLODPYxleJndjVcOMVzsLJjSM8dLpXsTS4FCeMbhw2s2u+xqKY
+bbPWfk+HOTyJjfnkcC5Nbg44eOmruq0gSmBeUXVM5UntlTnxAkEA7TGCA3h7kx5E
+Bl4zl2pc3gPAGt+dyfk5Po9mGJUUXhF5p2zueGmYWW74TmOWB1kzt4QRdYMzFePq
+zfDNXEa1CwJBAMFErdY0xp0UJ13WwBbUTk8rujqQdHtjw0klhpbuKkjxu2hN0wwM
+6p0D9qxF7JHaghqVRI0fAW/EE0OzdHMR9QkCQQDNR26dMFXKsoPu+vItljj/UEGf
+QG7gERiQ4yxaFBPHgdpGo0kT31eh9x9hQGDkxTe0GNG/YSgCRvm8+C3TMcKXAkBD
+dhGn36wkUFCddMSAM4NSJ1VN8/Z0y5HzCmI8dM3VwGtGMUQlxKxwOl30LEQzdS5M
+0SWojNYXiT2gOBfBwtbhAkEAhafl5QEOIgUz+XazS/IlZ8goNKdDVfYgK3mHHjvv
+nY5G+AuGebdNkXJr4KSWxDcN+C2i47zuj4QXA16MAOandA==
+-----END RSA PRIVATE KEY-----
+subject=/C=US/O=AT&T Bell Laboratories/OU=Prototype Research CA
+issuer= /C=US/O=AT&T Bell Laboratories/OU=Prototype Research CA
+notBefore=950413210656Z
+notAfter =970412210656Z
+-----BEGIN X509 CERTIFICATE-----
+
+MIICCDCCAXECAQAwDQYJKoZIhvcNAQEEBQAwTjELMAkGA1UEBhMCVVMxHzAdBgNV
+BAoUFkFUJlQgQmVsbCBMYWJvcmF0b3JpZXMxHjAcBgNVBAsUFVByb3RvdHlwZSBS
+ZXNlYXJjaCBDQTAeFw05NTA0MTMyMTA2NTZaFw05NzA0MTIyMTA2NTZaME4xCzAJ
+BgNVBAYTAlVTMR8wHQYDVQQKFBZBVCZUIEJlbGwgTGFib3JhdG9yaWVzMR4wHAYD
+VQQLFBVQcm90b3R5cGUgUmVzZWFyY2ggQ0EwgZwwDQYJKoZIhvcNAQEBBQADgYoA
+MIGGAoGAebOmgtSCl+wCYZc86UGYeTLY8cjmW2P0FN8ToT/u2pECCoFdrlycX0OR
+3wt0ZhpFXLVNeDnHwEE9veNUih7pCL2ZBFqoIoQkB1lZmXRiVtjGonz8BLm/qrFM
+YHb0lme/Ol+s118mwKVxnn6bSAeI/OXKhLaVdYZWk+aEaxEDkVkCAQ8wDQYJKoZI
+hvcNAQEEBQADgYEAAZMG14lZmZ8bahkaHaTV9dQf4p2FZiQTFwHP9ZyGsXPC+LT5
+dG5iTaRmyjNIJdPWohZDl97kAci79aBndvuEvRKOjLHs3WRGBIwERnAcnY9Mz8u/
+zIHK23PjYVxGGaZd669OJwD0CYyqH22HH9nFUGaoJdsv39ChW0NRdLE9+y8=
+-----END X509 CERTIFICATE-----
+issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test PCA (1024 bit)
+subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit)
+-----BEGIN CERTIFICATE-----
+MIICJjCCAY8CAQAwDQYJKoZIhvcNAQEEBQAwXDELMAkGA1UEBhMCQVUxEzARBgNV
+BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYD
+VQQDExNUZXN0IFBDQSAoMTAyNCBiaXQpMB4XDTk3MDYwOTEzNTc0M1oXDTAxMDYw
+OTEzNTc0M1owWzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxGjAY
+BgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYDVQQDExJUZXN0IENBICgxMDI0
+IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKO7o8t116VP6cgybTsZ
+DCZhr95nYlZuya3aCi1IKoztqwWnjbmDFIriOqGFPrZQ+moMETC9D59iRW/dFXSv
+1F65ka/XY2hLh9exCCo7XuUcDs53Qp3bI3AmMqHjgzE8oO3ajyJAzJkTTOUecQU2
+mw/gI4tMM0LqWMQS7luTy4+xAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAM7achv3v
+hLQJcv/65eGEpBXM40ZDVoFQFFJWaY5p883HTqLB1x4FdzsXHH0QKBTcKpWwqyu4
+YDm3fb8oDugw72bCzfyZK/zVZPR/hVlqI/fvU109Qoc+7oPvIXWky71HfcK6ZBCA
+q30KIqGM/uoM60INq97qjDmCJapagcNBGQs=
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQCju6PLddelT+nIMm07GQwmYa/eZ2JWbsmt2gotSCqM7asFp425
+gxSK4jqhhT62UPpqDBEwvQ+fYkVv3RV0r9ReuZGv12NoS4fXsQgqO17lHA7Od0Kd
+2yNwJjKh44MxPKDt2o8iQMyZE0zlHnEFNpsP4COLTDNC6ljEEu5bk8uPsQIDAQAB
+AoGAVZmpFZsDZfr0l2S9tLLwpjRWNOlKATQkno6q2WesT0eGLQufTciY+c8ypfU6
+hyio8r5iUl/VhhdjhAtKx1mRpiotftHo/eYf8rtsrnprOnWG0bWjLjtIoMbcxGn2
+J3bN6LJmbJMjDs0eJ3KnTu646F3nDUw2oGAwmpzKXA1KAP0CQQDRvQhxk2D3Pehs
+HvG665u2pB5ipYQngEFlZO7RHJZzJOZEWSLuuMqaF/7pTfA5jiBvWqCgJeCRRInL
+21ru4dlPAkEAx9jj7BgKn5TYnMoBSSe0afjsV9oApVpN1Nacb1YDtCwy+scp3++s
+nFxlv98wxIlSdpwMUn+AUWfjiWR7Tu/G/wJBAJ/KjwZIrFVxewP0x2ILYsTRYLzz
+MS4PDsO7FB+I0i7DbBOifXS2oNSpd3I0CNMwrxFnUHzynpbOStVfN3ZL5w0CQQCa
+pwFahxBRhkJKsxhjoFJBX9yl75JoY4Wvm5Tbo9ih6UJaRx3kqfkN14L2BKYcsZgb
+KY9vmDOYy6iNfjDeWTfJAkBkfPUb8oTJ/nSP5zN6sqGxSY4krc4xLxpRmxoJ8HL2
+XfhqXkTzbU13RX9JJ/NZ8vQN9Vm2NhxRGJocQkmcdVtJ
+-----END RSA PRIVATE KEY-----
+-----BEGIN X509 CERTIFICATE-----
+MIICYDCCAiACAgEoMAkGBSsOAwINBQAwfDELMAkGA1UEBhMCVVMxNjA0BgNVBAoT
+LU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEZ
+MBcGA1UECxMQVGVzdCBFbnZpcm9ubWVudDEaMBgGA1UECxMRRFNTLU5BU0EtUGls
+b3QtQ0EwHhcNOTYwMjI2MTYzMjQ1WhcNOTcwMjI1MTYzMjQ1WjB8MQswCQYDVQQG
+EwJVUzE2MDQGA1UEChMtTmF0aW9uYWwgQWVyb25hdXRpY3MgYW5kIFNwYWNlIEFk
+bWluaXN0cmF0aW9uMRkwFwYDVQQLExBUZXN0IEVudmlyb25tZW50MRowGAYDVQQL
+ExFEU1MtTkFTQS1QaWxvdC1DQTCB8jAJBgUrDgMCDAUAA4HkADCB4AJBAMA/ssKb
+hPNUG7ZlASfVwEJU21O5OyF/iyBzgHI1O8eOhJGUYO8cc8wDMjR508Mr9cp6Uhl/
+ZB7FV5GkLNEnRHYCQQDUEaSg45P2qrDwixTRhFhmWz5Nvc4lRFQ/42XPcchiJBLb
+bn3QK74T2IxY1yY+kCNq8XrIqf5fJJzIH0J/xUP3AhUAsg2wsQHfDGYk/BOSulX3
+fVd0geUCQQCzCFUQAh+ZkEmp5804cs6ZWBhrUAfnra8lJItYo9xPcXgdIfLfibcX
+R71UsyO77MRD7B0+Ag2tq794IleCVcEEMAkGBSsOAwINBQADLwAwLAIUUayDfreR
+Yh2WeU86/pHNdkUC1IgCFEfxe1f0oMpxJyrJ5XIxTi7vGdoK
+-----END X509 CERTIFICATE-----
+-----BEGIN X509 CERTIFICATE-----
+
+MIICGTCCAdgCAwCqTDAJBgUrDgMCDQUAMHwxCzAJBgNVBAYTAlVTMTYwNAYDVQQK
+Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x
+GTAXBgNVBAsTEFRlc3QgRW52aXJvbm1lbnQxGjAYBgNVBAsTEURTUy1OQVNBLVBp
+bG90LUNBMB4XDTk2MDUxNDE3MDE0MVoXDTk3MDUxNDE3MDE0MVowMzELMAkGA1UE
+BhMCQVUxDzANBgNVBAoTBk1pbmNvbTETMBEGA1UEAxMKRXJpYyBZb3VuZzCB8jAJ
+BgUrDgMCDAUAA4HkADCB4AJBAKbfHz6vE6pXXMTpswtGUec2tvnfLJUsoxE9qs4+
+ObZX7LmLvragNPUeiTJx7UOWZ5DfBj6bXLc8eYne0lP1g3ACQQDUEaSg45P2qrDw
+ixTRhFhmWz5Nvc4lRFQ/42XPcchiJBLbbn3QK74T2IxY1yY+kCNq8XrIqf5fJJzI
+H0J/xUP3AhUAsg2wsQHfDGYk/BOSulX3fVd0geUCQQCzCFUQAh+ZkEmp5804cs6Z
+WBhrUAfnra8lJItYo9xPcXgdIfLfibcXR71UsyO77MRD7B0+Ag2tq794IleCVcEE
+MAkGBSsOAwINBQADMAAwLQIUWsuuJRE3VT4ueWkWMAJMJaZjj1ECFQCYY0zX4bzM
+LC7obsrHD8XAHG+ZRG==
+-----END X509 CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICTTCCAbagAwIBAgIBADANBgkqhkiG9w0BAQQFADBMMQswCQYDVQQGEwJHQjEM
+MAoGA1UEChMDVUNMMRgwFgYDVQQLEw9JQ0UtVEVMIFByb2plY3QxFTATBgNVBAMT
+DFRydXN0RmFjdG9yeTAeFw05NzA0MjIxNDM5MTRaFw05ODA0MjIxNDM5MTRaMEwx
+CzAJBgNVBAYTAkdCMQwwCgYDVQQKEwNVQ0wxGDAWBgNVBAsTD0lDRS1URUwgUHJv
+amVjdDEVMBMGA1UEAxMMVHJ1c3RGYWN0b3J5MIGcMAoGBFUIAQECAgQAA4GNADCB
+iQKBgQCEieR8NcXkUW1f0G6aC6u0i8q/98JqS6RxK5YmHIGKCkuTWAUjzLfUa4dt
+U9igGCjTuxaDqlzEim+t/02pmiBZT9HaX++35MjQPUWmsChcYU5WyzGErXi+rQaw
+zlwS73zM8qiPj/97lXYycWhgL0VaiDSPxRXEUdWoaGruom4mNQIDAQABo0IwQDAd
+BgNVHQ4EFgQUHal1LZr7oVg5z6lYzrhTgZRCmcUwDgYDVR0PAQH/BAQDAgH2MA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAfaggfl6FZoioecjv0dq8
+/DXo/u11iMZvXn08gjX/zl2b4wtPbShOSY5FhkSm8GeySasz+/Nwb/uzfnIhokWi
+lfPZHtlCWtXbIy/TN51eJyq04ceDCQDWvLC2enVg9KB+GJ34b5c5VaPRzq8MBxsA
+S7ELuYGtmYgYm9NZOIr7yU0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIB6jCCAZQCAgEtMA0GCSqGSIb3DQEBBAUAMIGAMQswCQYDVQQGEwJVUzE2MDQG
+A1UEChMtTmF0aW9uYWwgQWVyb25hdXRpY3MgYW5kIFNwYWNlIEFkbWluaXN0cmF0
+aW9uMRkwFwYDVQQLExBUZXN0IEVudmlyb25tZW50MR4wHAYDVQQLExVNRDUtUlNB
+LU5BU0EtUGlsb3QtQ0EwHhcNOTYwNDMwMjIwNTAwWhcNOTcwNDMwMjIwNTAwWjCB
+gDELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu
+ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEZMBcGA1UECxMQVGVzdCBFbnZpcm9ubWVu
+dDEeMBwGA1UECxMVTUQ1LVJTQS1OQVNBLVBpbG90LUNBMFkwCgYEVQgBAQICAgAD
+SwAwSAJBALmmX5+GqAvcrWK13rfDrNX9UfeA7f+ijyBgeFQjYUoDpFqapw4nzQBL
+bAXug8pKkRwa2Zh8YODhXsRWu2F/UckCAwEAATANBgkqhkiG9w0BAQQFAANBAH9a
+OBA+QCsjxXgnSqHx04gcU8S49DVUb1f2XVoLnHlIb8RnX0k5O6mpHT5eti9bLkiW
+GJNMJ4L0AJ/ac+SmHZc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICajCCAdMCBDGA0QUwDQYJKoZIhvcNAQEEBQAwfTELMAkGA1UEBhMCQ2ExDzAN
+BgNVBAcTBk5lcGVhbjEeMBwGA1UECxMVTm8gTGlhYmlsaXR5IEFjY2VwdGVkMR8w
+HQYDVQQKExZGb3IgRGVtbyBQdXJwb3NlcyBPbmx5MRwwGgYDVQQDExNFbnRydXN0
+IERlbW8gV2ViIENBMB4XDTk2MDQyNjEzMzUwMVoXDTA2MDQyNjEzMzUwMVowfTEL
+MAkGA1UEBhMCQ2ExDzANBgNVBAcTBk5lcGVhbjEeMBwGA1UECxMVTm8gTGlhYmls
+aXR5IEFjY2VwdGVkMR8wHQYDVQQKExZGb3IgRGVtbyBQdXJwb3NlcyBPbmx5MRww
+GgYDVQQDExNFbnRydXN0IERlbW8gV2ViIENBMIGdMA0GCSqGSIb3DQEBAQUAA4GL
+ADCBhwKBgQCaroS7O1DA0hm4IefNYU1cx/nqOmzEnk291d1XqznDeF4wEgakbkCc
+zTKxK791yNpXG5RmngqH7cygDRTHZJ6mfCRn0wGC+AI00F2vYTGqPGRQL1N3lZT0
+YDKFC0SQeMMjFIZ1aeQigroFQnHo0VB3zWIMpNkka8PY9lxHZAmWwQIBAzANBgkq
+hkiG9w0BAQQFAAOBgQBAx0UMVA1s54lMQyXjMX5kj99FJN5itb8bK1Rk+cegPQPF
+cWO9SEWyEjjBjIkjjzAwBkaEszFsNGxemxtXvwjIm1xEUMTVlPEWTs2qnDvAUA9W
+YqhWbhH0toGT36236QAsqCZ76rbTRVSSX2BHyJwJMG2tCRv7kRJ//NIgxj3H4w==
+-----END CERTIFICATE-----
+
+issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test PCA (1024 bit)
+subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test PCA (1024 bit)
+-----BEGIN CERTIFICATE-----
+MIICJzCCAZACAQAwDQYJKoZIhvcNAQEEBQAwXDELMAkGA1UEBhMCQVUxEzARBgNV
+BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYD
+VQQDExNUZXN0IFBDQSAoMTAyNCBiaXQpMB4XDTk3MDYwOTEzNTczN1oXDTAxMDYw
+OTEzNTczN1owXDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxGjAY
+BgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYDVQQDExNUZXN0IFBDQSAoMTAy
+NCBiaXQpMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdoWk/3+WcMlfjIrkg
+40ketmnQaEogQe1LLcuOJV6rKfUSAsPgwgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp
+22Jp85PmemiDzyUIStwk72qhp1imbANZvlmlCFKiQrjUyuDfu4TABmn+kkt3vR1Y
+BEOGt+IFye1UBVSATVdRJ2UVhwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABNA1u/S
+Cg/LJZWb7GliiKJsvuhxlE4E5JxQF2zMub/CSNbF97//tYSyj96sxeFQxZXbcjm9
+xt6mr/xNLA4szNQMJ4P+L7b5e/jC5DSqlwS+CUYJgaFs/SP+qJoCSu1bR3IM9XWO
+cRBpDmcBbYLkSyB92WURvsZ1LtjEcn+cdQVI
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQCdoWk/3+WcMlfjIrkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPg
+wgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp22Jp85PmemiDzyUIStwk72qhp1imbANZ
+vlmlCFKiQrjUyuDfu4TABmn+kkt3vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQAB
+AoGAba4fTtuap5l7/8ZsbE7Z1O32KJY4ZcOZukLOLUUhXxXduT+FTgGWujc0/rgc
+z9qYCLlNZHOouMYTgtSfYvuMuLZ11VIt0GYH+nRioLShE59Yy+zCRyC+gPigS1kz
+xvo14AsOIPYV14Tk/SsHyq6E0eTk7VzaIE197giiINUERPECQQDSKmtPTh/lRKw7
+HSZSM0I1mFWn/1zqrAbontRQY5w98QWIOe5qmzYyFbPXYT3d9BzlsMyhgiRNoBbD
+yvohSHXJAkEAwAHx6ezAZeWWzD5yXD36nyjpkVCw7Tk7TSmOceLJMWt1QcrCfqlS
+xA5jjpQ6Z8suU5DdtWAryM2sAir1WisYzwJAd6Zcx56jvAQ3xcPXsE6scBTVFzrj
+7FqZ6E+cclPzfLQ+QQsyOBE7bpI6e/FJppY26XGZXo3YGzV8IGXrt40oOQJALETG
+h86EFXo3qGOFbmsDy4pdP5nBERCu8X1xUCSfintiD4c2DInxgS5oGclnJeMcjTvL
+QjQoJCX3UJCi/OUO1QJBAKgcDHWjMvt+l1pjJBsSEZ0HX9AAIIVx0RQmbFGS+F2Q
+hhu5l77WnnZOQ9vvhV5u7NPCUF9nhU3jh60qWWO8mkc=
+-----END RSA PRIVATE KEY-----
+subject=/C=US/O=RSA Data Security, Inc./OU=Commercial Certification Authority
+issuer= /C=US/O=RSA Data Security, Inc./OU=Commercial Certification Authority
+notBefore=941104185834Z
+notAfter =991103185834Z
+-----BEGIN X509 CERTIFICATE-----
+
+MIICIzCCAZACBQJBAAAWMA0GCSqGSIb3DQEBAgUAMFwxCzAJBgNVBAYTAlVTMSAw
+HgYDVQQKExdSU0EgRGF0YSBTZWN1cml0eSwgSW5jLjErMCkGA1UECxMiQ29tbWVy
+Y2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NDExMDQxODU4MzRaFw05
+OTExMDMxODU4MzRaMFwxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdSU0EgRGF0YSBT
+ZWN1cml0eSwgSW5jLjErMCkGA1UECxMiQ29tbWVyY2lhbCBDZXJ0aWZpY2F0aW9u
+IEF1dGhvcml0eTCBmzANBgkqhkiG9w0BAQEFAAOBiQAwgYUCfgCk+4Fie84QJ93o
+975sbsZwmdu41QUDaSiCnHJ/lj+O7Kwpkj+KFPhCdr69XQO5kNTQvAayUTNfxMK/
+touPmbZiImDd298ggrTKoi8tUO2UMt7gVY3UaOLgTNLNBRYulWZcYVI4HlGogqHE
+7yXpCuaLK44xZtn42f29O2nZ6wIDAQABMA0GCSqGSIb3DQEBAgUAA34AdrW2EP4j
+9/dZYkuwX5zBaLxJu7NJbyFHXSudVMQAKD+YufKKg5tgf+tQx6sFEC097TgCwaVI
+0v5loMC86qYjFmZsGySp8+x5NRhPJsjjr1BKx6cxa9B8GJ1Qv6km+iYrRpwUqbtb
+MJhCKLVLU7tDCZJAuqiqWqTGtotXTcU=
+-----END X509 CERTIFICATE-----
+subject=/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority
+issuer= /C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority
+notBefore=941109235417Z
+notAfter =991231235417Z
+-----BEGIN X509 CERTIFICATE-----
+
+MIICKTCCAZYCBQJBAAABMA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMSAw
+HgYDVQQKExdSU0EgRGF0YSBTZWN1cml0eSwgSW5jLjEuMCwGA1UECxMlU2VjdXJl
+IFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NDExMDkyMzU0MTda
+Fw05OTEyMzEyMzU0MTdaMF8xCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdSU0EgRGF0
+YSBTZWN1cml0eSwgSW5jLjEuMCwGA1UECxMlU2VjdXJlIFNlcnZlciBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eTCBmzANBgkqhkiG9w0BAQEFAAOBiQAwgYUCfgCSznrB
+roM+WqqJg1esJQF2DK2ujiw3zus1eGRUA+WEQFHJv48I4oqCCNIWhjdV6bEhAq12
+aIGaBaJLyUslZiJWbIgHj/eBWW2EB2VwE3F2Ppt3TONQiVaYSLkdpykaEy5KEVmc
+HhXVSVQsczppgrGXOZxtcGdI5d0t1sgeewIDAQABMA0GCSqGSIb3DQEBAgUAA34A
+iNHReSHO4ovo+MF9NFM/YYPZtgs4F7boviGNjwC4i1N+RGceIr2XJ+CchcxK9oU7
+suK+ktPlDemvXA4MRpX/oRxePug2WHpzpgr4IhFrwwk4fia7c+8AvQKk8xQNMD9h
+cHsg/jKjn7P0Z1LctO6EjJY2IN6BCINxIYoPnqk=
+-----END X509 CERTIFICATE-----
+subject=/C=ZA/SP=Western Cape/L=Cape Town/O=Thawte Consulting cc
+	/OU=Certification Services Division/CN=Thawte Server CA
+	/Email=server-certs@thawte.com
+issuer= /C=ZA/SP=Western Cape/L=Cape Town/O=Thawte Consulting cc
+	/OU=Certification Services Division/CN=Thawte Server CA
+	/Email=server-certs@thawte.com
+-----BEGIN CERTIFICATE-----
+MIIC+TCCAmICAQAwDQYJKoZIhvcNAQEEBQAwgcQxCzAJBgNVBAYTAlpBMRUwEwYD
+VQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU
+VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy
+dmljZXMgRGl2aXNpb24xGTAXBgNVBAMTEFRoYXd0ZSBTZXJ2ZXIgQ0ExJjAkBgkq
+hkiG9w0BCQEWF3NlcnZlci1jZXJ0c0B0aGF3dGUuY29tMB4XDTk2MDcyNzE4MDc1
+N1oXDTk4MDcyNzE4MDc1N1owgcQxCzAJBgNVBAYTAlpBMRUwEwYDVQQIEwxXZXN0
+ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMUVGhhd3RlIENv
+bnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2
+aXNpb24xGTAXBgNVBAMTEFRoYXd0ZSBTZXJ2ZXIgQ0ExJjAkBgkqhkiG9w0BCQEW
+F3NlcnZlci1jZXJ0c0B0aGF3dGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDTpFBuyP9Wa+bPXbbqDGh1R6KqwtqEJfyo9EdR2oW1IHSUhh4PdcnpCGH1
+Bm0wbhUZAulSwGLbTZme4moMRDjN/r7jZAlwxf6xaym2L0nIO9QnBCUQly/nkG3A
+KEKZ10xD3sP1IW1Un13DWOHA5NlbsLjctHvfNjrCtWYiEtaHDQIDAQABMA0GCSqG
+SIb3DQEBBAUAA4GBAIsvn7ifX3RUIrvYXtpI4DOfARkTogwm6o7OwVdl93yFhDcX
+7h5t0XZ11MUAMziKdde3rmTvzUYIUCYoY5b032IwGMTvdiclK+STN6NP2m5nvFAM
+qJT5gC5O+j/jBuZRQ4i0AMYQr5F4lT8oBJnhgafw6PL8aDY2vMHGSPl9+7uf
+-----END CERTIFICATE-----
+
+-----BEGIN CERTIFICATE-----
+MIIDDTCCAnYCAQAwDQYJKoZIhvcNAQEEBQAwgc4xCzAJBgNVBAYTAlpBMRUwEwYD
+VQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU
+VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy
+dmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBD
+QTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTAeFw05
+NjA3MjcxODA3MTRaFw05ODA3MjcxODA3MTRaMIHOMQswCQYDVQQGEwJaQTEVMBMG
+A1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xHTAbBgNVBAoT
+FFRoYXd0ZSBDb25zdWx0aW5nIGNjMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNl
+cnZpY2VzIERpdmlzaW9uMSEwHwYDVQQDExhUaGF3dGUgUHJlbWl1bSBTZXJ2ZXIg
+Q0ExKDAmBgkqhkiG9w0BCQEWGXByZW1pdW0tc2VydmVyQHRoYXd0ZS5jb20wgZ8w
+DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANI2NmqL18JbntqBQWKPOO5JBFXW0O8c
+G5UWR+8YSDU6UvQragaPOy/qVuOvho2eF/eetGV1Ak3vywmiIVHYm9Bn0LoNkgYU
+c9STy5cqAJxcTgy8+hVS/PJEbtoRSm4Iny8t4/mqOoZztkZTWMiJBb2DEbhzP6oH
+jfRCTedAnRw3AgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAutFIgTRZVYerIZfL9lvR
+w9Eifvvo5KTZ3h+Bj+VzNnyw4Qc/IyXkPOu6SIiH9LQ3sCmWBdxpe+qr4l77rLj2
+GYuMtESFfn1XVALzkYgC7JcPuTOjMfIiMByt+uFf8AV8x0IW/Qkuv+hEQcyM9vxK
+3VZdLbCVIhNoEsysrxCpxcI=
+-----END CERTIFICATE-----
+Tims test GCI CA
+
+-----BEGIN CERTIFICATE-----
+MIIB8DCCAZoCAQAwDQYJKoZIhvcNAQEEBQAwgYIxCzAJBgNVBAYTAkFVMRMwEQYD
+VQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5
+cHRTb2Z0IFB0eSBMdGQxFDASBgNVBAsTC2RldmVsb3BtZW50MRkwFwYDVQQDExBD
+cnlwdFNvZnQgRGV2IENBMB4XDTk3MDMyMjEzMzQwNFoXDTk4MDMyMjEzMzQwNFow
+gYIxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhC
+cmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxFDASBgNVBAsTC2Rl
+dmVsb3BtZW50MRkwFwYDVQQDExBDcnlwdFNvZnQgRGV2IENBMFwwDQYJKoZIhvcN
+AQEBBQADSwAwSAJBAOAOAqogG5QwAmLhzyO4CoRnx/wVy4NZP4dxJy83O1EnL0rw
+OdsamJKvPOLHgSXo3gDu9uVyvCf/QJmZAmC5ml8CAwEAATANBgkqhkiG9w0BAQQF
+AANBADRRS/GVdd7rAqRW6SdmgLJduOU2yq3avBu99kRqbp9A/dLu6r6jU+eP4oOA
+TfdbFZtAAD2Hx9jUtY3tfdrJOb8= 
+-----END CERTIFICATE-----
+
+-----BEGIN CERTIFICATE-----
+MIICVjCCAgACAQAwDQYJKoZIhvcNAQEEBQAwgbUxCzAJBgNVBAYTAkFVMRMwEQYD
+VQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5
+cHRTb2Z0IFB0eSBMdGQxLDAqBgNVBAsTI1dPUlRITEVTUyBDRVJUSUZJQ0FUSU9O
+IEFVVEhPUklUSUVTMTQwMgYDVQQDEytaRVJPIFZBTFVFIENBIC0gREVNT05TVFJB
+VElPTiBQVVJQT1NFUyBPTkxZMB4XDTk3MDQwMzEzMjI1NFoXDTk4MDQwMzEzMjI1
+NFowgbUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQH
+EwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxLDAqBgNVBAsT
+I1dPUlRITEVTUyBDRVJUSUZJQ0FUSU9OIEFVVEhPUklUSUVTMTQwMgYDVQQDEyta
+RVJPIFZBTFVFIENBIC0gREVNT05TVFJBVElPTiBQVVJQT1NFUyBPTkxZMFwwDQYJ
+KoZIhvcNAQEBBQADSwAwSAJBAOZ7T7yqP/tyspcko3yPY1y0Cm2EmwNvzW4QgVXR
+Fjs3HmJ4xtSpXdo6mwcGezL3Abt/aQXaxv9PU8xt+Jr0OFUCAwEAATANBgkqhkiG
+9w0BAQQFAANBAOQpYmGgyCqCy1OljgJhCqQOu627oVlHzK1L+t9vBaMfn40AVUR4
+WzQVWO31KTgi5vTK1U+3h46fgUWqQ0h+6rU=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIAwgKADAgECAgEAMA0GCSqGSIb3DQEBBAUAMGIxETAPBgNVBAcTCEludGVybmV0
+MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE0MDIGA1UECxMrVmVyaVNpZ24gQ2xh
+c3MgMSBDQSAtIEluZGl2aWR1YWwgU3Vic2NyaWJlcjAeFw05NjA0MDgxMDIwMjda
+Fw05NzA0MDgxMDIwMjdaMGIxETAPBgNVBAcTCEludGVybmV0MRcwFQYDVQQKEw5W
+ZXJpU2lnbiwgSW5jLjE0MDIGA1UECxMrVmVyaVNpZ24gQ2xhc3MgMSBDQSAtIElu
+ZGl2aWR1YWwgU3Vic2NyaWJlcjCAMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2
+FKbPTdAFDdjKI9BvqrQpkmOOLPhvltcunXZLEbE2jVfJw/0cxrr+Hgi6M8qV6r7j
+W80GqLd5HUQq7XPysVKDaBBwZJHXPmv5912dFEObbpdFmIFH0S3L3bty10w/cari
+QPJUObwW7s987LrbP2wqsxaxhhKdrpM01bjV0Pc+qQIDAQABAAAAADANBgkqhkiG
+9w0BAQQFAAOBgQA+1nJryNt8VBRjRr07ArDAV/3jAH7GjDc9jsrxZS68ost9v06C
+TvTNKGL+LISNmFLXl+JXhgGB0JZ9fvyYzNgHQ46HBUng1H6voalfJgS2KdEo50wW
+8EFZYMDkT1k4uynwJqkVN2QJK/2q4/A/VCov5h6SlM8Affg2W+1TLqvqkwAA
+-----END CERTIFICATE-----
+
+ subject=/L=Internet/O=VeriSign, Inc./OU=VeriSign Class 2 CA - Individual Subscriber
+ issuer= /L=Internet/O=VeriSign, Inc./OU=VeriSign Class 2 CA - Individual Subscriber
+
+-----BEGIN CERTIFICATE-----
+MIIEkzCCA/ygAwIBAgIRANDTUpSRL3nTFeMrMayFSPAwDQYJKoZIhvcNAQECBQAw
+YjERMA8GA1UEBxMISW50ZXJuZXQxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTQw
+MgYDVQQLEytWZXJpU2lnbiBDbGFzcyAyIENBIC0gSW5kaXZpZHVhbCBTdWJzY3Jp
+YmVyMB4XDTk2MDYwNDAwMDAwMFoXDTk4MDYwNDIzNTk1OVowYjERMA8GA1UEBxMI
+SW50ZXJuZXQxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTQwMgYDVQQLEytWZXJp
+U2lnbiBDbGFzcyAyIENBIC0gSW5kaXZpZHVhbCBTdWJzY3JpYmVyMIGfMA0GCSqG
+SIb3DQEBAQUAA4GNADCBiQKBgQC6A+2czKGRcYMfm8gdnk+0de99TDDzsqo0v5nb
+RsbUmMcdRQ7nsMbRWe0SAb/9QoLTZ/cJ0iOBqdrkz7UpqqKarVoTSdlSMVM92tWp
+3bJncZHQD1t4xd6lQVdI1/T6R+5J0T1ukOdsI9Jmf+F28S6g3R3L1SFwiHKeZKZv
+z+793wIDAQABo4ICRzCCAkMwggIpBgNVHQMBAf8EggIdMIICGTCCAhUwggIRBgtg
+hkgBhvhFAQcBATCCAgAWggGrVGhpcyBjZXJ0aWZpY2F0ZSBpbmNvcnBvcmF0ZXMg
+YnkgcmVmZXJlbmNlLCBhbmQgaXRzIHVzZSBpcyBzdHJpY3RseSBzdWJqZWN0IHRv
+LCB0aGUgVmVyaVNpZ24gQ2VydGlmaWNhdGlvbiBQcmFjdGljZSBTdGF0ZW1lbnQg
+KENQUyksIGF2YWlsYWJsZSBhdDogaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL0NQ
+Uy0xLjA7IGJ5IEUtbWFpbCBhdCBDUFMtcmVxdWVzdHNAdmVyaXNpZ24uY29tOyBv
+ciBieSBtYWlsIGF0IFZlcmlTaWduLCBJbmMuLCAyNTkzIENvYXN0IEF2ZS4sIE1v
+dW50YWluIFZpZXcsIENBIDk0MDQzIFVTQSBUZWwuICsxICg0MTUpIDk2MS04ODMw
+IENvcHlyaWdodCAoYykgMTk5NiBWZXJpU2lnbiwgSW5jLiAgQWxsIFJpZ2h0cyBS
+ZXNlcnZlZC4gQ0VSVEFJTiBXQVJSQU5USUVTIERJU0NMQUlNRUQgYW5kIExJQUJJ
+TElUWSBMSU1JVEVELqAOBgxghkgBhvhFAQcBAQGhDgYMYIZIAYb4RQEHAQECMC8w
+LRYraHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvQ1BTLTEuMDAU
+BglghkgBhvhCAQEBAf8EBAMCAgQwDQYJKoZIhvcNAQECBQADgYEApRJRkNBqLLgs
+53IR/d18ODdLOWMTZ+QOOxBrq460iBEdUwgF8vmPRX1ku7UiDeNzaLlurE6eFqHq
+2zPyK5j60zfTLVJMWKcQWwTJLjHtXrW8pxhNtFc6Fdvy5ZkHnC/9NIl7/t4U6WqB
+p4y+p7SdMIkEwIZfds0VbnQyX5MRUJY=
+-----END CERTIFICATE-----
+
+ subject=/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
+ issuer= /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
+-----BEGIN CERTIFICATE-----
+MIICMTCCAZoCBQKhAAABMA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMRcw
+FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMyBQdWJsaWMg
+UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NjAxMjkwMDAwMDBa
+Fw05OTEyMzEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2ln
+biwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyVxZ
+nvIbigEUtBDfBEDb41evakVAj4QMC9Ez2dkRz+4CWB8l9yqoRAWq7AMfeH+ek7ma
+AKojfdashaJjRcdyJ8z0TMZ1cdI5709C8HXfCpDGjiBvmA/4rCNfcCk2pMmG57Ga
+IMtTpYXnPb59mv4kRTPcdhXtD6JxZExlLoFoRacCAwEAATANBgkqhkiG9w0BAQIF
+AAOBgQB1Zmw+0c2B27X4LzZRtvdCvM1Cr9wO+hVs+GeTVzrrtpLotgHKjLeOQ7RJ
+Zfk+7r11Ri7J/CVdqMcvi5uPaM+0nJcYwE3vH9mvgrPmZLiEXIqaB1JDYft0nls6
+NvxMsvwaPxUupVs8G5DsiCnkWRb5zget7Ond2tIxik/W2O8XjQ==
+-----END CERTIFICATE-----
+ subject=/C=US/O=VeriSign, Inc./OU=Class 4 Public Primary Certification Authority
+ issuer= /C=US/O=VeriSign, Inc./OU=Class 4 Public Primary Certification Authority
+-----BEGIN CERTIFICATE-----
+MIICMTCCAZoCBQKmAAABMA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMRcw
+FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgNCBQdWJsaWMg
+UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NjAxMjkwMDAwMDBa
+Fw05OTEyMzEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2ln
+biwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0LJ1
+9njQrlpQ9OlQqZ+M1++RlHDo0iSQdomF1t+s5gEXMoDwnZNHvJplnR+Xrr/phnVj
+IIm9gFidBAydqMEk6QvlMXi9/C0MN2qeeIDpRnX57aP7E3vIwUzSo+/1PLBij0pd
+O92VZ48TucE81qcmm+zDO3rZTbxtm+gVAePwR6kCAwEAATANBgkqhkiG9w0BAQIF
+AAOBgQBT3dPwnCR+QKri/AAa19oM/DJhuBUNlvP6Vxt/M3yv6ZiaYch6s7f/sdyZ
+g9ysEvxwyR84Qu1E9oAuW2szaayc01znX1oYx7EteQSWQZGZQbE8DbqEOcY7l/Am
+yY7uvcxClf8exwI/VAx49byqYHwCaejcrOICdmHEPgPq0ook0Q==
+-----END CERTIFICATE-----
diff --git a/openssl/apps/sess_id.c b/openssl/apps/sess_id.c
new file mode 100644
index 0000000..b99179f
--- /dev/null
+++ b/openssl/apps/sess_id.c
@@ -0,0 +1,320 @@
+/* apps/sess_id.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+
+#undef PROG
+#define PROG	sess_id_main
+
+static const char *sess_id_usage[]={
+"usage: sess_id args\n",
+"\n",
+" -inform arg     - input format - default PEM (DER or PEM)\n",
+" -outform arg    - output format - default PEM\n",
+" -in arg         - input file - default stdin\n",
+" -out arg        - output file - default stdout\n",
+" -text           - print ssl session id details\n",
+" -cert           - output certificate \n",
+" -noout          - no CRL output\n",
+" -context arg    - set the session ID context\n",
+NULL
+};
+
+static SSL_SESSION *load_sess_id(char *file, int format);
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	SSL_SESSION *x=NULL;
+	int ret=1,i,num,badops=0;
+	BIO *out=NULL;
+	int informat,outformat;
+	char *infile=NULL,*outfile=NULL,*context=NULL;
+	int cert=0,noout=0,text=0;
+	const char **pp;
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	informat=FORMAT_PEM;
+	outformat=FORMAT_PEM;
+
+	argc--;
+	argv++;
+	num=0;
+	while (argc >= 1)
+		{
+		if 	(strcmp(*argv,"-inform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			informat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-outform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outformat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-text") == 0)
+			text= ++num;
+		else if (strcmp(*argv,"-cert") == 0)
+			cert= ++num;
+		else if (strcmp(*argv,"-noout") == 0)
+			noout= ++num;
+		else if (strcmp(*argv,"-context") == 0)
+		    {
+		    if(--argc < 1) goto bad;
+		    context=*++argv;
+		    }
+		else
+			{
+			BIO_printf(bio_err,"unknown option %s\n",*argv);
+			badops=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (badops)
+		{
+bad:
+		for (pp=sess_id_usage; (*pp != NULL); pp++)
+			BIO_printf(bio_err,"%s",*pp);
+		goto end;
+		}
+
+	ERR_load_crypto_strings();
+	x=load_sess_id(infile,informat);
+	if (x == NULL) { goto end; }
+
+	if(context)
+	    {
+	    x->sid_ctx_length=strlen(context);
+	    if(x->sid_ctx_length > SSL_MAX_SID_CTX_LENGTH)
+		{
+		BIO_printf(bio_err,"Context too long\n");
+		goto end;
+		}
+	    memcpy(x->sid_ctx,context,x->sid_ctx_length);
+	    }
+
+#ifdef undef
+	/* just testing for memory leaks :-) */
+	{
+	SSL_SESSION *s;
+	char buf[1024*10],*p;
+	int i;
+
+	s=SSL_SESSION_new();
+
+	p= &buf;
+	i=i2d_SSL_SESSION(x,&p);
+	p= &buf;
+	d2i_SSL_SESSION(&s,&p,(long)i);
+	p= &buf;
+	d2i_SSL_SESSION(&s,&p,(long)i);
+	p= &buf;
+	d2i_SSL_SESSION(&s,&p,(long)i);
+	SSL_SESSION_free(s);
+	}
+#endif
+
+	if (!noout || text)
+		{
+		out=BIO_new(BIO_s_file());
+		if (out == NULL)
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+
+		if (outfile == NULL)
+			{
+			BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+			{
+			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+			out = BIO_push(tmpbio, out);
+			}
+#endif
+			}
+		else
+			{
+			if (BIO_write_filename(out,outfile) <= 0)
+				{
+				perror(outfile);
+				goto end;
+				}
+			}
+		}
+
+	if (text)
+		{
+		SSL_SESSION_print(out,x);
+
+		if (cert)
+			{
+			if (x->peer == NULL)
+				BIO_puts(out,"No certificate present\n");
+			else
+				X509_print(out,x->peer);
+			}
+		}
+
+	if (!noout && !cert)
+		{
+		if 	(outformat == FORMAT_ASN1)
+			i=i2d_SSL_SESSION_bio(out,x);
+		else if (outformat == FORMAT_PEM)
+			i=PEM_write_bio_SSL_SESSION(out,x);
+		else	{
+			BIO_printf(bio_err,"bad output format specified for outfile\n");
+			goto end;
+			}
+		if (!i) {
+			BIO_printf(bio_err,"unable to write SSL_SESSION\n");
+			goto end;
+			}
+		}
+	else if (!noout && (x->peer != NULL)) /* just print the certificate */
+		{
+		if 	(outformat == FORMAT_ASN1)
+			i=(int)i2d_X509_bio(out,x->peer);
+		else if (outformat == FORMAT_PEM)
+			i=PEM_write_bio_X509(out,x->peer);
+		else	{
+			BIO_printf(bio_err,"bad output format specified for outfile\n");
+			goto end;
+			}
+		if (!i) {
+			BIO_printf(bio_err,"unable to write X509\n");
+			goto end;
+			}
+		}
+	ret=0;
+end:
+	if (out != NULL) BIO_free_all(out);
+	if (x != NULL) SSL_SESSION_free(x);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
+static SSL_SESSION *load_sess_id(char *infile, int format)
+	{
+	SSL_SESSION *x=NULL;
+	BIO *in=NULL;
+
+	in=BIO_new(BIO_s_file());
+	if (in == NULL)
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (infile == NULL)
+		BIO_set_fp(in,stdin,BIO_NOCLOSE);
+	else
+		{
+		if (BIO_read_filename(in,infile) <= 0)
+			{
+			perror(infile);
+			goto end;
+			}
+		}
+	if 	(format == FORMAT_ASN1)
+		x=d2i_SSL_SESSION_bio(in,NULL);
+	else if (format == FORMAT_PEM)
+		x=PEM_read_bio_SSL_SESSION(in,NULL,NULL,NULL);
+	else	{
+		BIO_printf(bio_err,"bad input format specified for input crl\n");
+		goto end;
+		}
+	if (x == NULL)
+		{
+		BIO_printf(bio_err,"unable to load SSL_SESSION\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+	
+end:
+	if (in != NULL) BIO_free(in);
+	return(x);
+	}
+
diff --git a/openssl/apps/set/set-g-ca.pem b/openssl/apps/set/set-g-ca.pem
new file mode 100644
index 0000000..78499f0
--- /dev/null
+++ b/openssl/apps/set/set-g-ca.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDeDCCAuGgAwIBAgIgYCYUeg8NJ9kO1q3z6vGCkAmPRfu5+Nur0FyGF79MADMw
+DQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0JDQTEwMTcx
+MTA0MSAwHgYDVQQDExdCcmFuZCBOYW1lOlByb2R1Y3QgVHlwZTAeFw05NjEwMjIw
+MDAwMDBaFw05NjExMjEyMzU5NTlaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKEwtQ
+Q0ExMDIxMTgyODEgMB4GA1UEAxMXQnJhbmQgTmFtZTpQcm9kdWN0IFR5cGUwgZ8w
+DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJyi5V7l1HohY6hN/2N9x6mvWeMy8rD1
+6lfXjgmiuGmhpaszWYaalesMcS2OGuG8Lq3PkaSzpVzqASKfIOjxLMsdpYyYJRub
+vRPDWi3xd8wlp9xUwWHKqn+ki8mPo0yN4eONwZZ4rcZr6K+tWd+5EJZSjuENJoQ/
+SRRmGRzdcS7XAgMBAAGjggFXMIIBUzBUBgNVHSMETTBLoSekJTAjMQswCQYDVQQG
+EwJVUzEUMBIGA1UEChMLUkNBMTAxMTE4MjmCIGApUs14Ad7t9VTGq2PpV8DylPQ7
+aATM2mor7lc1fWvZMA4GA1UdDwEB/wQEAwIBBjAuBgNVHRABAf8EJDAigA8xOTk2
+MTAyMjAxMjIwMFqBDzE5OTYxMTIxMjM1OTU5WjAbBgNVHSABAf8EETAPMA0GC2CG
+SAGG+EUBBwEBMBIGA1UdEwEB/wQIMAYBAf8CAQAwDwYEho1vAwEB/wQEAwICBDB5
+BgSGjW8HAQH/BG4wbDAkAgEAMAkGBSsOAwIaBQAEFDJmNzRiMWFmNGZjYzA2MGY3
+Njc2Ew90ZXJzZSBzdGF0ZW1lbnSAF2h0dHA6Ly93d3cudmVyaXNpZ24uY29tgRpn
+ZXRzZXQtY2VudGVyQHZlcmlzaWduLmNvbTANBgkqhkiG9w0BAQUFAAOBgQBn19R2
+AgGvpJDmfXrHTDdCoYyMkaP2MPzw0hFRwh+wqnw0/pqUXa7MrLXMqtD3rUyOWaNR
+9fYpJZd0Bh/1OeIc2+U+VNfUovLLuZ8nNemdxyq2KMYnHtnh7UdO7atZ+PFLVu8x
+a+J2Mtj8MGy12CJNTJcjLSrJ/1f3AuVrwELjlQ==
+-----END CERTIFICATE-----
diff --git a/openssl/apps/set/set-m-ca.pem b/openssl/apps/set/set-m-ca.pem
new file mode 100644
index 0000000..0e74caf
--- /dev/null
+++ b/openssl/apps/set/set-m-ca.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDeDCCAuGgAwIBAgIgEGvcf5aUnufALdVMa/dmPdflq1CoORGeK5DUwbqhVYcw
+DQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0JDQTEwMTcx
+MTA0MSAwHgYDVQQDExdCcmFuZCBOYW1lOlByb2R1Y3QgVHlwZTAeFw05NjEwMjIw
+MDAwMDBaFw05NjExMjEyMzU5NTlaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKEwtN
+Q0ExMDIxMTgyNzEgMB4GA1UEAxMXQnJhbmQgTmFtZTpQcm9kdWN0IFR5cGUwgZ8w
+DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALuWwr63YrT1GIZpYKfIeiVFHESG/FZO
+7RAJKml/p12ZyZ7D5YPP4BBXVsa1H8e8arR1LKC4rdCArrtKKlBeBiMo9+NB+u35
+FnLnTmfzM4iZ2Syw35DXY8+Xn/LM7RJ1RG+vMNcTqpoUg7QPye7flq2Pt7vVROPn
+SZxPyVxmILe3AgMBAAGjggFXMIIBUzBUBgNVHSMETTBLoSekJTAjMQswCQYDVQQG
+EwJVUzEUMBIGA1UEChMLUkNBMTAxMTE4MjmCIGApUs14Ad7t9VTGq2PpV8DylPQ7
+aATM2mor7lc1fWvZMA4GA1UdDwEB/wQEAwIBBjAuBgNVHRABAf8EJDAigA8xOTk2
+MTAyMjAxMjEwMFqBDzE5OTYxMTIxMjM1OTU5WjAbBgNVHSABAf8EETAPMA0GC2CG
+SAGG+EUBBwEBMBIGA1UdEwEB/wQIMAYBAf8CAQAwDwYEho1vAwEB/wQEAwIDCDB5
+BgSGjW8HAQH/BG4wbDAkAgEAMAkGBSsOAwIaBQAEFDJmNzRiMWFmNGZjYzA2MGY3
+Njc2Ew90ZXJzZSBzdGF0ZW1lbnSAF2h0dHA6Ly93d3cudmVyaXNpZ24uY29tgRpn
+ZXRzZXQtY2VudGVyQHZlcmlzaWduLmNvbTANBgkqhkiG9w0BAQUFAAOBgQApaj0W
+GgyR47URZEZ7z83yivvnVErqtodub/nR1fMgJ4bDC0ofjA0SzXBP1/3eDq9VkPuS
+EKUw9BpM2XrSUKhJ6F1CbBjWpM0M7GC1nTSxMxmV+XL+Ab/Gn2SwozUApWtht29/
+x9VLB8qsi6wN2aOsVdQMl5iVCjGQYfEkyuoIgA==
+-----END CERTIFICATE-----
diff --git a/openssl/apps/set/set_b_ca.pem b/openssl/apps/set/set_b_ca.pem
new file mode 100644
index 0000000..eba7d5c
--- /dev/null
+++ b/openssl/apps/set/set_b_ca.pem
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID1zCCAr+gAwIBAgIgYClSzXgB3u31VMarY+lXwPKU9DtoBMzaaivuVzV9a9kw
+DQYJKoZIhvcNAQEFBQAwIzELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1JDQTEwMTEx
+ODI5MB4XDTk2MTAxNzAwMDAwMFoXDTk2MTExNjIzNTk1OVowRTELMAkGA1UEBhMC
+VVMxFDASBgNVBAoTC0JDQTEwMTcxMTA0MSAwHgYDVQQDExdCcmFuZCBOYW1lOlBy
+b2R1Y3QgVHlwZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEApPewvR0BwV02
+9E12ic48pMY/aMB6SkMEWPDx2hURr0DKYGJ6qMvzZn2pSfaVH1BqDtK6oK4Ye5Mj
+ItywwQIdXXO9Ut8+TLnvtzq9ByCJ0YThjZJBc7ZcpJxSV7QAoBON/lzxZuAVq3+L
+3uc39MgRwmBpRllZEpWrkojxs6166X0CAwEAAaOCAVcwggFTMFQGA1UdIwRNMEuh
+J6QlMCMxCzAJBgNVBAYTAlVTMRQwEgYDVQQKEwtSQ0ExMDExMTgyOYIgVqenwCYv
+mmxUIvi9gUMCa+uJGJ60mZecw9HrISXnLaYwDgYDVR0PAQH/BAQDAgEGMC4GA1Ud
+EAEB/wQkMCKADzE5OTYxMDE3MTc1NzAwWoEPMTk5NjExMTYyMzU5NTlaMBsGA1Ud
+IAEB/wQRMA8wDQYLYIZIAYb4RQEHAQEwEgYDVR0TAQH/BAgwBgEB/wIBATAPBgSG
+jW8DAQH/BAQDAgABMHkGBIaNbwcBAf8EbjBsMCQCAQAwCQYFKw4DAhoFAAQUMmY3
+NGIxYWY0ZmNjMDYwZjc2NzYTD3RlcnNlIHN0YXRlbWVudIAXaHR0cDovL3d3dy52
+ZXJpc2lnbi5jb22BGmdldHNldC1jZW50ZXJAdmVyaXNpZ24uY29tMA0GCSqGSIb3
+DQEBBQUAA4IBAQAWoMS8Aj2sO0LDxRoMcnWTKY8nd8Jw2vl2Mgsm+0qCvcndICM5
+43N0y9uHlP8WeCZULbFz95gTL8mfP/QTu4EctMUkQgRHJnx80f0XSF3HE/X6zBbI
+9rit/bF6yP1mhkdss/vGanReDpki7q8pLx+VIIcxWst/366HP3dW1Fb7ECW/WmVV
+VMN93f/xqk9I4sXchVZcVKQT3W4tzv+qQvugrEi1dSEkbAy1CITEAEGiaFhGUyCe
+WPox3guRXaEHoINNeajGrISe6d//alsz5EEroBoLnM2ryqWfLAtRsf4rjNzTgklw
+lbiz0fw7bNkXKp5ZVr0wlnOjQnoSM6dTI0AV
+-----END CERTIFICATE-----
diff --git a/openssl/apps/set/set_c_ca.pem b/openssl/apps/set/set_c_ca.pem
new file mode 100644
index 0000000..48b2cbd
--- /dev/null
+++ b/openssl/apps/set/set_c_ca.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDeDCCAuGgAwIBAgIgOnl8J6lAYNDdTWtIojWCGnloNf4ufHjOZ4Fkxwg5xOsw
+DQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0JDQTEwMTcx
+MTA0MSAwHgYDVQQDExdCcmFuZCBOYW1lOlByb2R1Y3QgVHlwZTAeFw05NjEwMjIw
+MDAwMDBaFw05NjExMjEyMzU5NTlaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKEwtD
+Q0ExMDIxMTYxNjEgMB4GA1UEAxMXQnJhbmQgTmFtZTpQcm9kdWN0IFR5cGUwgZ8w
+DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANA3a9+U8oXU3Dv1wJf8g0A7HjCRZAXc
+Y8E4OLOdye5aUssxifCE05qTPVqHMXo6cnCYcfroMdURhjQlswyTGtjQybgUnXjp
+pchw+V4D1DkN0ThErrMCh9ZFSykC0lUhQTRLESvbIb4Gal/HMAFAF5sj0GoOFi2H
+RRj7gpzBIU3xAgMBAAGjggFXMIIBUzBUBgNVHSMETTBLoSekJTAjMQswCQYDVQQG
+EwJVUzEUMBIGA1UEChMLUkNBMTAxMTE4MjmCIGApUs14Ad7t9VTGq2PpV8DylPQ7
+aATM2mor7lc1fWvZMA4GA1UdDwEB/wQEAwIBBjAuBgNVHRABAf8EJDAigA8xOTk2
+MTAyMjAxMTAwMFqBDzE5OTYxMTIxMjM1OTU5WjAbBgNVHSABAf8EETAPMA0GC2CG
+SAGG+EUBBwEBMBIGA1UdEwEB/wQIMAYBAf8CAQAwDwYEho1vAwEB/wQEAwIEEDB5
+BgSGjW8HAQH/BG4wbDAkAgEAMAkGBSsOAwIaBQAEFDJmNzRiMWFmNGZjYzA2MGY3
+Njc2Ew90ZXJzZSBzdGF0ZW1lbnSAF2h0dHA6Ly93d3cudmVyaXNpZ24uY29tgRpn
+ZXRzZXQtY2VudGVyQHZlcmlzaWduLmNvbTANBgkqhkiG9w0BAQUFAAOBgQBteLaZ
+u/TASC64UWPfhxYAUdys9DQ1pG/J1qPWNTkjOmpXFvW+7l/3nkxyRPgUoFNwx1e7
+XVVPr6zhy8LaaXppwfIZvVryzAUdbtijiUf/MO0hvV3w7e9NlCVProdU5H9EvCXr
++IV8rH8fdEkirIVyw0JGHkuWhkmtS1HEwai9vg==
+-----END CERTIFICATE-----
diff --git a/openssl/apps/set/set_d_ct.pem b/openssl/apps/set/set_d_ct.pem
new file mode 100644
index 0000000..9f8c7d8
--- /dev/null
+++ b/openssl/apps/set/set_d_ct.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDdjCCAt+gAwIBAgIgRU5t24v72xVDpZ4iHpyoOAQaQmfio1yhTZAOkBfT2uUw
+DQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0NDQTEwMjEx
+NjE2MSAwHgYDVQQDExdCcmFuZCBOYW1lOlByb2R1Y3QgVHlwZTAeFw05NjEwMjQw
+MDAwMDBaFw05NjExMjMyMzU5NTlaMG4xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdC
+cmFuZElEMSYwJAYDVQQLEx1Jc3N1aW5nIEZpbmFuY2lhbCBJbnN0aXR1dGlvbjEl
+MCMGA1UEAxMcR2lYb0t0VjViN1V0MHZKa2hkSG5RYmNzc2JrPTBcMA0GCSqGSIb3
+DQEBAQUAA0sAMEgCQQDIUxgpNB1aoSW585WErtN8WInCRWCqDj3RGT2mJye0F4SM
+/iT5ywdWMasmw18vpEpDlMypfZnRkUAdfyHcRABVAgMBAAGjggFwMIIBbDB2BgNV
+HSMEbzBtoUmkRzBFMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLQkNBMTAxNzExMDQx
+IDAeBgNVBAMTF0JyYW5kIE5hbWU6UHJvZHVjdCBUeXBlgiA6eXwnqUBg0N1Na0ii
+NYIaeWg1/i58eM5ngWTHCDnE6zAOBgNVHQ8BAf8EBAMCB4AwLgYDVR0QAQH/BCQw
+IoAPMTk5NjEwMjQwMTA0MDBagQ8xOTk2MTEyMzIzNTk1OVowGAYDVR0gBBEwDzAN
+BgtghkgBhvhFAQcBATAMBgNVHRMBAf8EAjAAMA8GBIaNbwMBAf8EBAMCB4AweQYE
+ho1vBwEB/wRuMGwwJAIBADAJBgUrDgMCGgUABBQzOTgyMzk4NzIzNzg5MTM0OTc4
+MhMPdGVyc2Ugc3RhdGVtZW50gBdodHRwOi8vd3d3LnZlcmlzaWduLmNvbYEaZ2V0
+c2V0LWNlbnRlckB2ZXJpc2lnbi5jb20wDQYJKoZIhvcNAQEFBQADgYEAVHCjhxeD
+mIFSkm3DpQAq7pGfcAFPWvSM9I9bK8qeFT1M5YQ+5fbPqaWlNcQlGKIe3cHd4+0P
+ndL5lb6UBhhA0kTzEYA38+HtBxPe/lokCv0bYfyWY9asUmvfbUrTYta0yjN7ixnV
+UqvxxHQHOAwhf6bcc7xNHapOxloWzGUU0RQ=
+-----END CERTIFICATE-----
diff --git a/openssl/apps/set/set_root.pem b/openssl/apps/set/set_root.pem
new file mode 100644
index 0000000..8dd104f
--- /dev/null
+++ b/openssl/apps/set/set_root.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDZzCCAk+gAwIBAgIgVqenwCYvmmxUIvi9gUMCa+uJGJ60mZecw9HrISXnLaYw
+DQYJKoZIhvcNAQEFBQAwIzELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1JDQTEwMTEx
+ODI5MB4XDTk2MTAxMjAwMDAwMFoXDTk2MTExMTIzNTk1OVowIzELMAkGA1UEBhMC
+VVMxFDASBgNVBAoTC1JDQTEwMTExODI5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAukca0PVUGFIYX7EyrShi+dVi9GTNzG0V2Wtdw6DqFzKfedba/KpE
+zqnRDV/wRZlBn3oXPS6kNCFiBPRV9mEFXI7y2W+q8/vPurjRDIXMsqQ+dAhKwf4q
+rofJBTiET4NUN0YTtpx6aYuoVubjiOgKdbqnUArxAWWP2Dkco17ipEYyUtd4sTAe
+/xKR02AHpbYGYPSHjMDS/nzUJ7uX4d51phs0rt7If48ExJSnDV/KoHMfm42mdmH2
+g23005qdHKY3UXeh10tZmb3QtGTSvF6OqpRZ+e9/ALklu7ZcIjqbb944ci4QWemb
+ZNWiDFrWWUoO1k942BI/iZ8Fh8pETYSDBQIDAQABo4GGMIGDMA4GA1UdDwEB/wQE
+AwIBBjAuBgNVHRABAf8EJDAigA8xOTk2MTAxMjAxMzQwMFqBDzE5OTYxMTExMjM1
+OTU5WjAbBgNVHSABAf8EETAPMA0GC2CGSAGG+EUBBwEBMBIGA1UdEwEB/wQIMAYB
+Af8CAQIwEAYEho1vAwEB/wQFAwMHAIAwDQYJKoZIhvcNAQEFBQADggEBAK4tntea
+y+ws7PdULwfqAS5osaoNvw73uBn5lROTpx91uhQbJyf0oZ3XG9GUuHZBpqG9qmr9
+vIL40RsvRpNMYgaNHKTxF716yx6rZmruAYZsrE3SpV63tQJCckKLPSge2E5uDhSQ
+O8UjusG+IRT9fKMXUHLv4OmZPOQVOSl1qTCN2XoJFqEPtC3Y9P4YR4xHL0P2jb1l
+DLdIbruuh+6omH+0XUZd5fKnQZTTi6gjl0iunj3wGnkcqGZtwr3j87ONiB/8tDwY
+vz8ceII4YYdX12PrNzn+fu3R5rChvPW4/ah/SaYQ2VQ0AupaIF4xrNJ/gLYYw0YO
+bxCrVJLd8tu9WgA=
+-----END CERTIFICATE-----
diff --git a/openssl/apps/smime.c b/openssl/apps/smime.c
new file mode 100644
index 0000000..c583f8a
--- /dev/null
+++ b/openssl/apps/smime.c
@@ -0,0 +1,857 @@
+/* smime.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* S/MIME utility function */
+
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/crypto.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/x509_vfy.h>
+#include <openssl/x509v3.h>
+
+#undef PROG
+#define PROG smime_main
+static int save_certs(char *signerfile, STACK_OF(X509) *signers);
+static int smime_cb(int ok, X509_STORE_CTX *ctx);
+
+#define SMIME_OP	0x10
+#define SMIME_IP	0x20
+#define SMIME_SIGNERS	0x40
+#define SMIME_ENCRYPT	(1 | SMIME_OP)
+#define SMIME_DECRYPT	(2 | SMIME_IP)
+#define SMIME_SIGN	(3 | SMIME_OP | SMIME_SIGNERS)
+#define SMIME_VERIFY	(4 | SMIME_IP)
+#define SMIME_PK7OUT	(5 | SMIME_IP | SMIME_OP)
+#define SMIME_RESIGN	(6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	ENGINE *e = NULL;
+	int operation = 0;
+	int ret = 0;
+	char **args;
+	const char *inmode = "r", *outmode = "w";
+	char *infile = NULL, *outfile = NULL;
+	char *signerfile = NULL, *recipfile = NULL;
+	STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL;
+	char *certfile = NULL, *keyfile = NULL, *contfile=NULL;
+	const EVP_CIPHER *cipher = NULL;
+	PKCS7 *p7 = NULL;
+	X509_STORE *store = NULL;
+	X509 *cert = NULL, *recip = NULL, *signer = NULL;
+	EVP_PKEY *key = NULL;
+	STACK_OF(X509) *encerts = NULL, *other = NULL;
+	BIO *in = NULL, *out = NULL, *indata = NULL;
+	int badarg = 0;
+	int flags = PKCS7_DETACHED;
+	char *to = NULL, *from = NULL, *subject = NULL;
+	char *CAfile = NULL, *CApath = NULL;
+	char *passargin = NULL, *passin = NULL;
+	char *inrand = NULL;
+	int need_rand = 0;
+	int indef = 0;
+	const EVP_MD *sign_md = NULL;
+	int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
+        int keyform = FORMAT_PEM;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+
+	X509_VERIFY_PARAM *vpm = NULL;
+
+	args = argv + 1;
+	ret = 1;
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		{
+		if ((bio_err = BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
+		}
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	while (!badarg && *args && *args[0] == '-')
+		{
+		if (!strcmp (*args, "-encrypt"))
+			operation = SMIME_ENCRYPT;
+		else if (!strcmp (*args, "-decrypt"))
+			operation = SMIME_DECRYPT;
+		else if (!strcmp (*args, "-sign"))
+			operation = SMIME_SIGN;
+		else if (!strcmp (*args, "-resign"))
+			operation = SMIME_RESIGN;
+		else if (!strcmp (*args, "-verify"))
+			operation = SMIME_VERIFY;
+		else if (!strcmp (*args, "-pk7out"))
+			operation = SMIME_PK7OUT;
+#ifndef OPENSSL_NO_DES
+		else if (!strcmp (*args, "-des3")) 
+				cipher = EVP_des_ede3_cbc();
+		else if (!strcmp (*args, "-des")) 
+				cipher = EVP_des_cbc();
+#endif
+#ifndef OPENSSL_NO_SEED
+		else if (!strcmp (*args, "-seed")) 
+				cipher = EVP_seed_cbc();
+#endif
+#ifndef OPENSSL_NO_RC2
+		else if (!strcmp (*args, "-rc2-40")) 
+				cipher = EVP_rc2_40_cbc();
+		else if (!strcmp (*args, "-rc2-128")) 
+				cipher = EVP_rc2_cbc();
+		else if (!strcmp (*args, "-rc2-64")) 
+				cipher = EVP_rc2_64_cbc();
+#endif
+#ifndef OPENSSL_NO_AES
+		else if (!strcmp(*args,"-aes128"))
+				cipher = EVP_aes_128_cbc();
+		else if (!strcmp(*args,"-aes192"))
+				cipher = EVP_aes_192_cbc();
+		else if (!strcmp(*args,"-aes256"))
+				cipher = EVP_aes_256_cbc();
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+		else if (!strcmp(*args,"-camellia128"))
+				cipher = EVP_camellia_128_cbc();
+		else if (!strcmp(*args,"-camellia192"))
+				cipher = EVP_camellia_192_cbc();
+		else if (!strcmp(*args,"-camellia256"))
+				cipher = EVP_camellia_256_cbc();
+#endif
+		else if (!strcmp (*args, "-text")) 
+				flags |= PKCS7_TEXT;
+		else if (!strcmp (*args, "-nointern")) 
+				flags |= PKCS7_NOINTERN;
+		else if (!strcmp (*args, "-noverify")) 
+				flags |= PKCS7_NOVERIFY;
+		else if (!strcmp (*args, "-nochain")) 
+				flags |= PKCS7_NOCHAIN;
+		else if (!strcmp (*args, "-nocerts")) 
+				flags |= PKCS7_NOCERTS;
+		else if (!strcmp (*args, "-noattr")) 
+				flags |= PKCS7_NOATTR;
+		else if (!strcmp (*args, "-nodetach")) 
+				flags &= ~PKCS7_DETACHED;
+		else if (!strcmp (*args, "-nosmimecap"))
+				flags |= PKCS7_NOSMIMECAP;
+		else if (!strcmp (*args, "-binary"))
+				flags |= PKCS7_BINARY;
+		else if (!strcmp (*args, "-nosigs"))
+				flags |= PKCS7_NOSIGS;
+		else if (!strcmp (*args, "-stream"))
+				indef = 1;
+		else if (!strcmp (*args, "-indef"))
+				indef = 1;
+		else if (!strcmp (*args, "-noindef"))
+				indef = 0;
+		else if (!strcmp (*args, "-nooldmime"))
+				flags |= PKCS7_NOOLDMIMETYPE;
+		else if (!strcmp (*args, "-crlfeol"))
+				flags |= PKCS7_CRLFEOL;
+		else if (!strcmp(*args,"-rand"))
+			{
+			if (!args[1])
+				goto argerr;
+			args++;
+			inrand = *args;
+			need_rand = 1;
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (!strcmp(*args,"-engine"))
+			{
+			if (!args[1])
+				goto argerr;
+			engine = *++args;
+			}
+#endif
+		else if (!strcmp(*args,"-passin"))
+			{
+			if (!args[1])
+				goto argerr;
+			passargin = *++args;
+			}
+		else if (!strcmp (*args, "-to"))
+			{
+			if (!args[1])
+				goto argerr;
+			to = *++args;
+			}
+		else if (!strcmp (*args, "-from"))
+			{
+			if (!args[1])
+				goto argerr;
+			from = *++args;
+			}
+		else if (!strcmp (*args, "-subject"))
+			{
+			if (!args[1])
+				goto argerr;
+			subject = *++args;
+			}
+		else if (!strcmp (*args, "-signer"))
+			{
+			if (!args[1])
+				goto argerr;
+			/* If previous -signer argument add signer to list */
+
+			if (signerfile)
+				{
+				if (!sksigners)
+					sksigners = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(sksigners, signerfile);
+				if (!keyfile)
+					keyfile = signerfile;
+				if (!skkeys)
+					skkeys = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(skkeys, keyfile);
+				keyfile = NULL;
+				}
+			signerfile = *++args;
+			}
+		else if (!strcmp (*args, "-recip"))
+			{
+			if (!args[1])
+				goto argerr;
+			recipfile = *++args;
+			}
+		else if (!strcmp (*args, "-md"))
+			{
+			if (!args[1])
+				goto argerr;
+			sign_md = EVP_get_digestbyname(*++args);
+			if (sign_md == NULL)
+				{
+				BIO_printf(bio_err, "Unknown digest %s\n",
+							*args);
+				goto argerr;
+				}
+			}
+		else if (!strcmp (*args, "-inkey"))
+			{
+			if (!args[1])	
+				goto argerr;
+			/* If previous -inkey arument add signer to list */
+			if (keyfile)
+				{
+				if (!signerfile)
+					{
+					BIO_puts(bio_err, "Illegal -inkey without -signer\n");
+					goto argerr;
+					}
+				if (!sksigners)
+					sksigners = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(sksigners, signerfile);
+				signerfile = NULL;
+				if (!skkeys)
+					skkeys = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(skkeys, keyfile);
+				}
+			keyfile = *++args;
+			}
+		else if (!strcmp (*args, "-keyform"))
+			{
+			if (!args[1])
+				goto argerr;
+			keyform = str2fmt(*++args);
+			}
+		else if (!strcmp (*args, "-certfile"))
+			{
+			if (!args[1])
+				goto argerr;
+			certfile = *++args;
+			}
+		else if (!strcmp (*args, "-CAfile"))
+			{
+			if (!args[1])
+				goto argerr;
+			CAfile = *++args;
+			}
+		else if (!strcmp (*args, "-CApath"))
+			{
+			if (!args[1])
+				goto argerr;
+			CApath = *++args;
+			}
+		else if (!strcmp (*args, "-in"))
+			{
+			if (!args[1])
+				goto argerr;
+			infile = *++args;
+			}
+		else if (!strcmp (*args, "-inform"))
+			{
+			if (!args[1])
+				goto argerr;
+			informat = str2fmt(*++args);
+			}
+		else if (!strcmp (*args, "-outform"))
+			{
+			if (!args[1])
+				goto argerr;
+			outformat = str2fmt(*++args);
+			}
+		else if (!strcmp (*args, "-out"))
+			{
+			if (!args[1])
+				goto argerr;
+			outfile = *++args;
+			}
+		else if (!strcmp (*args, "-content"))
+			{
+			if (!args[1])
+				goto argerr;
+			contfile = *++args;
+			}
+		else if (args_verify(&args, NULL, &badarg, bio_err, &vpm))
+			continue;
+		else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL)
+			badarg = 1;
+		args++;
+		}
+
+	if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners))
+		{
+		BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
+		goto argerr;
+		}
+
+	if (operation & SMIME_SIGNERS)
+		{
+		/* Check to see if any final signer needs to be appended */
+		if (keyfile && !signerfile)
+			{
+			BIO_puts(bio_err, "Illegal -inkey without -signer\n");
+			goto argerr;
+			}
+		if (signerfile)
+			{
+			if (!sksigners)
+				sksigners = sk_OPENSSL_STRING_new_null();
+			sk_OPENSSL_STRING_push(sksigners, signerfile);
+			if (!skkeys)
+				skkeys = sk_OPENSSL_STRING_new_null();
+			if (!keyfile)
+				keyfile = signerfile;
+			sk_OPENSSL_STRING_push(skkeys, keyfile);
+			}
+		if (!sksigners)
+			{
+			BIO_printf(bio_err, "No signer certificate specified\n");
+			badarg = 1;
+			}
+		signerfile = NULL;
+		keyfile = NULL;
+		need_rand = 1;
+		}
+	else if (operation == SMIME_DECRYPT)
+		{
+		if (!recipfile && !keyfile)
+			{
+			BIO_printf(bio_err, "No recipient certificate or key specified\n");
+			badarg = 1;
+			}
+		}
+	else if (operation == SMIME_ENCRYPT)
+		{
+		if (!*args)
+			{
+			BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
+			badarg = 1;
+			}
+		need_rand = 1;
+		}
+	else if (!operation)
+		badarg = 1;
+
+	if (badarg)
+		{
+		argerr:
+		BIO_printf (bio_err, "Usage smime [options] cert.pem ...\n");
+		BIO_printf (bio_err, "where options are\n");
+		BIO_printf (bio_err, "-encrypt       encrypt message\n");
+		BIO_printf (bio_err, "-decrypt       decrypt encrypted message\n");
+		BIO_printf (bio_err, "-sign          sign message\n");
+		BIO_printf (bio_err, "-verify        verify signed message\n");
+		BIO_printf (bio_err, "-pk7out        output PKCS#7 structure\n");
+#ifndef OPENSSL_NO_DES
+		BIO_printf (bio_err, "-des3          encrypt with triple DES\n");
+		BIO_printf (bio_err, "-des           encrypt with DES\n");
+#endif
+#ifndef OPENSSL_NO_SEED
+		BIO_printf (bio_err, "-seed          encrypt with SEED\n");
+#endif
+#ifndef OPENSSL_NO_RC2
+		BIO_printf (bio_err, "-rc2-40        encrypt with RC2-40 (default)\n");
+		BIO_printf (bio_err, "-rc2-64        encrypt with RC2-64\n");
+		BIO_printf (bio_err, "-rc2-128       encrypt with RC2-128\n");
+#endif
+#ifndef OPENSSL_NO_AES
+		BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
+		BIO_printf (bio_err, "               encrypt PEM output with cbc aes\n");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+		BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n");
+		BIO_printf (bio_err, "               encrypt PEM output with cbc camellia\n");
+#endif
+		BIO_printf (bio_err, "-nointern      don't search certificates in message for signer\n");
+		BIO_printf (bio_err, "-nosigs        don't verify message signature\n");
+		BIO_printf (bio_err, "-noverify      don't verify signers certificate\n");
+		BIO_printf (bio_err, "-nocerts       don't include signers certificate when signing\n");
+		BIO_printf (bio_err, "-nodetach      use opaque signing\n");
+		BIO_printf (bio_err, "-noattr        don't include any signed attributes\n");
+		BIO_printf (bio_err, "-binary        don't translate message to text\n");
+		BIO_printf (bio_err, "-certfile file other certificates file\n");
+		BIO_printf (bio_err, "-signer file   signer certificate file\n");
+		BIO_printf (bio_err, "-recip  file   recipient certificate file for decryption\n");
+		BIO_printf (bio_err, "-in file       input file\n");
+		BIO_printf (bio_err, "-inform arg    input format SMIME (default), PEM or DER\n");
+		BIO_printf (bio_err, "-inkey file    input private key (if not signer or recipient)\n");
+		BIO_printf (bio_err, "-keyform arg   input private key format (PEM or ENGINE)\n");
+		BIO_printf (bio_err, "-out file      output file\n");
+		BIO_printf (bio_err, "-outform arg   output format SMIME (default), PEM or DER\n");
+		BIO_printf (bio_err, "-content file  supply or override content for detached signature\n");
+		BIO_printf (bio_err, "-to addr       to address\n");
+		BIO_printf (bio_err, "-from ad       from address\n");
+		BIO_printf (bio_err, "-subject s     subject\n");
+		BIO_printf (bio_err, "-text          include or delete text MIME headers\n");
+		BIO_printf (bio_err, "-CApath dir    trusted certificates directory\n");
+		BIO_printf (bio_err, "-CAfile file   trusted certificates file\n");
+		BIO_printf (bio_err, "-crl_check     check revocation status of signer's certificate using CRLs\n");
+		BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf (bio_err, "-engine e      use engine e, possibly a hardware device.\n");
+#endif
+		BIO_printf (bio_err, "-passin arg    input file pass phrase source\n");
+		BIO_printf(bio_err,  "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+		BIO_printf(bio_err,  "               load the file (or the files in the directory) into\n");
+		BIO_printf(bio_err,  "               the random number generator\n");
+		BIO_printf (bio_err, "cert.pem       recipient certificate(s) for encryption\n");
+		goto end;
+		}
+
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine, 0);
+#endif
+
+	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL))
+		{
+		BIO_printf(bio_err, "Error getting password\n");
+		goto end;
+		}
+
+	if (need_rand)
+		{
+		app_RAND_load_file(NULL, bio_err, (inrand != NULL));
+		if (inrand != NULL)
+			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+				app_RAND_load_files(inrand));
+		}
+
+	ret = 2;
+
+	if (!(operation & SMIME_SIGNERS))
+		flags &= ~PKCS7_DETACHED;
+
+	if (operation & SMIME_OP)
+		{
+		if (outformat == FORMAT_ASN1)
+			outmode = "wb";
+		}
+	else
+		{
+		if (flags & PKCS7_BINARY)
+			outmode = "wb";
+		}
+
+	if (operation & SMIME_IP)
+		{
+		if (informat == FORMAT_ASN1)
+			inmode = "rb";
+		}
+	else
+		{
+		if (flags & PKCS7_BINARY)
+			inmode = "rb";
+		}
+
+	if (operation == SMIME_ENCRYPT)
+		{
+		if (!cipher)
+			{
+#ifndef OPENSSL_NO_RC2			
+			cipher = EVP_rc2_40_cbc();
+#else
+			BIO_printf(bio_err, "No cipher selected\n");
+			goto end;
+#endif
+			}
+		encerts = sk_X509_new_null();
+		while (*args)
+			{
+			if (!(cert = load_cert(bio_err,*args,FORMAT_PEM,
+				NULL, e, "recipient certificate file")))
+				{
+#if 0				/* An appropriate message is already printed */
+				BIO_printf(bio_err, "Can't read recipient certificate file %s\n", *args);
+#endif
+				goto end;
+				}
+			sk_X509_push(encerts, cert);
+			cert = NULL;
+			args++;
+			}
+		}
+
+	if (certfile)
+		{
+		if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL,
+			e, "certificate file")))
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+
+	if (recipfile && (operation == SMIME_DECRYPT))
+		{
+		if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL,
+			e, "recipient certificate file")))
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+
+	if (operation == SMIME_DECRYPT)
+		{
+		if (!keyfile)
+			keyfile = recipfile;
+		}
+	else if (operation == SMIME_SIGN)
+		{
+		if (!keyfile)
+			keyfile = signerfile;
+		}
+	else keyfile = NULL;
+
+	if (keyfile)
+		{
+		key = load_key(bio_err, keyfile, keyform, 0, passin, e,
+			       "signing key file");
+		if (!key)
+			goto end;
+		}
+
+	if (infile)
+		{
+		if (!(in = BIO_new_file(infile, inmode)))
+			{
+			BIO_printf (bio_err,
+				 "Can't open input file %s\n", infile);
+			goto end;
+			}
+		}
+	else
+		in = BIO_new_fp(stdin, BIO_NOCLOSE);
+
+	if (operation & SMIME_IP)
+		{
+		if (informat == FORMAT_SMIME) 
+			p7 = SMIME_read_PKCS7(in, &indata);
+		else if (informat == FORMAT_PEM) 
+			p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
+		else if (informat == FORMAT_ASN1) 
+			p7 = d2i_PKCS7_bio(in, NULL);
+		else
+			{
+			BIO_printf(bio_err, "Bad input format for PKCS#7 file\n");
+			goto end;
+			}
+
+		if (!p7)
+			{
+			BIO_printf(bio_err, "Error reading S/MIME message\n");
+			goto end;
+			}
+		if (contfile)
+			{
+			BIO_free(indata);
+			if (!(indata = BIO_new_file(contfile, "rb")))
+				{
+				BIO_printf(bio_err, "Can't read content file %s\n", contfile);
+				goto end;
+				}
+			}
+		}
+
+	if (outfile)
+		{
+		if (!(out = BIO_new_file(outfile, outmode)))
+			{
+			BIO_printf (bio_err,
+				 "Can't open output file %s\n", outfile);
+			goto end;
+			}
+		}
+	else
+		{
+		out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		    out = BIO_push(tmpbio, out);
+		}
+#endif
+		}
+
+	if (operation == SMIME_VERIFY)
+		{
+		if (!(store = setup_verify(bio_err, CAfile, CApath)))
+			goto end;
+		X509_STORE_set_verify_cb(store, smime_cb);
+		if (vpm)
+			X509_STORE_set1_param(store, vpm);
+		}
+
+
+	ret = 3;
+
+	if (operation == SMIME_ENCRYPT)
+		{
+		if (indef)
+			flags |= PKCS7_STREAM;
+		p7 = PKCS7_encrypt(encerts, in, cipher, flags);
+		}
+	else if (operation & SMIME_SIGNERS)
+		{
+		int i;
+		/* If detached data content we only enable streaming if
+		 * S/MIME output format.
+		 */
+		if (operation == SMIME_SIGN)
+			{
+			if (flags & PKCS7_DETACHED)
+				{
+				if (outformat == FORMAT_SMIME)
+					flags |= PKCS7_STREAM;
+				}
+			else if (indef)
+				flags |= PKCS7_STREAM;
+			flags |= PKCS7_PARTIAL;
+			p7 = PKCS7_sign(NULL, NULL, other, in, flags);
+			if (!p7)
+				goto end;
+			}
+		else
+			flags |= PKCS7_REUSE_DIGEST;
+		for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++)
+			{
+			signerfile = sk_OPENSSL_STRING_value(sksigners, i);
+			keyfile = sk_OPENSSL_STRING_value(skkeys, i);
+			signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL,
+					e, "signer certificate");
+			if (!signer)
+				goto end;
+			key = load_key(bio_err, keyfile, keyform, 0, passin, e,
+			       "signing key file");
+			if (!key)
+				goto end;
+			if (!PKCS7_sign_add_signer(p7, signer, key,
+						sign_md, flags))
+				goto end;
+			X509_free(signer);
+			signer = NULL;
+			EVP_PKEY_free(key);
+			key = NULL;
+			}
+		/* If not streaming or resigning finalize structure */
+		if ((operation == SMIME_SIGN) && !(flags & PKCS7_STREAM))
+			{
+			if (!PKCS7_final(p7, in, flags))
+				goto end;
+			}
+		}
+
+	if (!p7)
+		{
+		BIO_printf(bio_err, "Error creating PKCS#7 structure\n");
+		goto end;
+		}
+
+	ret = 4;
+	if (operation == SMIME_DECRYPT)
+		{
+		if (!PKCS7_decrypt(p7, key, recip, out, flags))
+			{
+			BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n");
+			goto end;
+			}
+		}
+	else if (operation == SMIME_VERIFY)
+		{
+		STACK_OF(X509) *signers;
+		if (PKCS7_verify(p7, other, store, indata, out, flags))
+			BIO_printf(bio_err, "Verification successful\n");
+		else
+			{
+			BIO_printf(bio_err, "Verification failure\n");
+			goto end;
+			}
+		signers = PKCS7_get0_signers(p7, other, flags);
+		if (!save_certs(signerfile, signers))
+			{
+			BIO_printf(bio_err, "Error writing signers to %s\n",
+								signerfile);
+			ret = 5;
+			goto end;
+			}
+		sk_X509_free(signers);
+		}
+	else if (operation == SMIME_PK7OUT)
+		PEM_write_bio_PKCS7(out, p7);
+	else
+		{
+		if (to)
+			BIO_printf(out, "To: %s\n", to);
+		if (from)
+			BIO_printf(out, "From: %s\n", from);
+		if (subject)
+			BIO_printf(out, "Subject: %s\n", subject);
+		if (outformat == FORMAT_SMIME) 
+			{
+			if (operation == SMIME_RESIGN)
+				SMIME_write_PKCS7(out, p7, indata, flags);
+			else
+				SMIME_write_PKCS7(out, p7, in, flags);
+			}
+		else if (outformat == FORMAT_PEM) 
+			PEM_write_bio_PKCS7_stream(out, p7, in, flags);
+		else if (outformat == FORMAT_ASN1) 
+			i2d_PKCS7_bio_stream(out,p7, in, flags);
+		else
+			{
+			BIO_printf(bio_err, "Bad output format for PKCS#7 file\n");
+			goto end;
+			}
+		}
+	ret = 0;
+end:
+	if (need_rand)
+		app_RAND_write_file(NULL, bio_err);
+	if (ret) ERR_print_errors(bio_err);
+	sk_X509_pop_free(encerts, X509_free);
+	sk_X509_pop_free(other, X509_free);
+	if (vpm)
+		X509_VERIFY_PARAM_free(vpm);
+	if (sksigners)
+		sk_OPENSSL_STRING_free(sksigners);
+	if (skkeys)
+		sk_OPENSSL_STRING_free(skkeys);
+	X509_STORE_free(store);
+	X509_free(cert);
+	X509_free(recip);
+	X509_free(signer);
+	EVP_PKEY_free(key);
+	PKCS7_free(p7);
+	BIO_free(in);
+	BIO_free(indata);
+	BIO_free_all(out);
+	if (passin) OPENSSL_free(passin);
+	return (ret);
+}
+
+static int save_certs(char *signerfile, STACK_OF(X509) *signers)
+	{
+	int i;
+	BIO *tmp;
+	if (!signerfile)
+		return 1;
+	tmp = BIO_new_file(signerfile, "w");
+	if (!tmp) return 0;
+	for(i = 0; i < sk_X509_num(signers); i++)
+		PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
+	BIO_free(tmp);
+	return 1;
+	}
+	
+
+/* Minimal callback just to output policy info (if any) */
+
+static int smime_cb(int ok, X509_STORE_CTX *ctx)
+	{
+	int error;
+
+	error = X509_STORE_CTX_get_error(ctx);
+
+	if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
+		&& ((error != X509_V_OK) || (ok != 2)))
+		return ok;
+
+	policies_print(NULL, ctx);
+
+	return ok;
+
+	}
diff --git a/openssl/apps/speed.c b/openssl/apps/speed.c
new file mode 100644
index 0000000..b3c5442
--- /dev/null
+++ b/openssl/apps/speed.c
@@ -0,0 +1,2787 @@
+/* apps/speed.c -*- mode:C; c-file-style: "eay" -*- */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The ECDH and ECDSA speed test software is originally written by 
+ * Sumit Gupta of Sun Microsystems Laboratories.
+ *
+ */
+
+/* most of this code has been pilfered from my libdes speed.c program */
+
+#ifndef OPENSSL_NO_SPEED
+
+#undef SECONDS
+#define SECONDS		3	
+#define RSA_SECONDS	10
+#define DSA_SECONDS	10
+#define ECDSA_SECONDS   10
+#define ECDH_SECONDS    10
+
+/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
+/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
+
+#undef PROG
+#define PROG speed_main
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <string.h>
+#include <math.h>
+#include "apps.h"
+#ifdef OPENSSL_NO_STDIO
+#define APPS_WIN16
+#endif
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#if !defined(OPENSSL_SYS_MSDOS)
+#include OPENSSL_UNISTD
+#endif
+
+#ifndef OPENSSL_SYS_NETWARE
+#include <signal.h>
+#endif
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_DES
+#include <openssl/des.h>
+#endif
+#ifndef OPENSSL_NO_AES
+#include <openssl/aes.h>
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+#include <openssl/camellia.h>
+#endif
+#ifndef OPENSSL_NO_MD2
+#include <openssl/md2.h>
+#endif
+#ifndef OPENSSL_NO_MDC2
+#include <openssl/mdc2.h>
+#endif
+#ifndef OPENSSL_NO_MD4
+#include <openssl/md4.h>
+#endif
+#ifndef OPENSSL_NO_MD5
+#include <openssl/md5.h>
+#endif
+#ifndef OPENSSL_NO_HMAC
+#include <openssl/hmac.h>
+#endif
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_SHA
+#include <openssl/sha.h>
+#endif
+#ifndef OPENSSL_NO_RIPEMD
+#include <openssl/ripemd.h>
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+#include <openssl/whrlpool.h>
+#endif
+#ifndef OPENSSL_NO_RC4
+#include <openssl/rc4.h>
+#endif
+#ifndef OPENSSL_NO_RC5
+#include <openssl/rc5.h>
+#endif
+#ifndef OPENSSL_NO_RC2
+#include <openssl/rc2.h>
+#endif
+#ifndef OPENSSL_NO_IDEA
+#include <openssl/idea.h>
+#endif
+#ifndef OPENSSL_NO_SEED
+#include <openssl/seed.h>
+#endif
+#ifndef OPENSSL_NO_BF
+#include <openssl/blowfish.h>
+#endif
+#ifndef OPENSSL_NO_CAST
+#include <openssl/cast.h>
+#endif
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#include "./testrsa.h"
+#endif
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#include "./testdsa.h"
+#endif
+#ifndef OPENSSL_NO_ECDSA
+#include <openssl/ecdsa.h>
+#endif
+#ifndef OPENSSL_NO_ECDH
+#include <openssl/ecdh.h>
+#endif
+
+#ifndef HAVE_FORK
+# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_NETWARE)
+#  define HAVE_FORK 0
+# else
+#  define HAVE_FORK 1
+# endif
+#endif
+
+#if HAVE_FORK
+#undef NO_FORK
+#else
+#define NO_FORK
+#endif
+
+#undef BUFSIZE
+#define BUFSIZE	((long)1024*8+1)
+int run=0;
+
+static int mr=0;
+static int usertime=1;
+
+static double Time_F(int s);
+static void print_message(const char *s,long num,int length);
+static void pkey_print_message(const char *str, const char *str2,
+	long num, int bits, int sec);
+static void print_result(int alg,int run_no,int count,double time_used);
+#ifndef NO_FORK
+static int do_multi(int multi);
+#endif
+
+#define ALGOR_NUM	29
+#define SIZE_NUM	5
+#define RSA_NUM		4
+#define DSA_NUM		3
+
+#define EC_NUM       16
+#define MAX_ECDH_SIZE 256
+
+static const char *names[ALGOR_NUM]={
+  "md2","mdc2","md4","md5","hmac(md5)","sha1","rmd160","rc4",
+  "des cbc","des ede3","idea cbc","seed cbc",
+  "rc2 cbc","rc5-32/12 cbc","blowfish cbc","cast cbc",
+  "aes-128 cbc","aes-192 cbc","aes-256 cbc",
+  "camellia-128 cbc","camellia-192 cbc","camellia-256 cbc",
+  "evp","sha256","sha512","whirlpool",
+  "aes-128 ige","aes-192 ige","aes-256 ige"};
+static double results[ALGOR_NUM][SIZE_NUM];
+static int lengths[SIZE_NUM]={16,64,256,1024,8*1024};
+#ifndef OPENSSL_NO_RSA
+static double rsa_results[RSA_NUM][2];
+#endif
+#ifndef OPENSSL_NO_DSA
+static double dsa_results[DSA_NUM][2];
+#endif
+#ifndef OPENSSL_NO_ECDSA
+static double ecdsa_results[EC_NUM][2];
+#endif
+#ifndef OPENSSL_NO_ECDH
+static double ecdh_results[EC_NUM][1];
+#endif
+
+#if defined(OPENSSL_NO_DSA) && !(defined(OPENSSL_NO_ECDSA) && defined(OPENSSL_NO_ECDH))
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+static int rnd_fake = 0;
+#endif
+
+#ifdef SIGALRM
+#if defined(__STDC__) || defined(sgi) || defined(_AIX)
+#define SIGRETTYPE void
+#else
+#define SIGRETTYPE int
+#endif 
+
+static SIGRETTYPE sig_done(int sig);
+static SIGRETTYPE sig_done(int sig)
+	{
+	signal(SIGALRM,sig_done);
+	run=0;
+#ifdef LINT
+	sig=sig;
+#endif
+	}
+#endif
+
+#define START	0
+#define STOP	1
+
+#if defined(_WIN32)
+
+#define SIGALRM
+static unsigned int lapse,schlock;
+static void alarm(unsigned int secs) { lapse = secs*1000; }
+
+static DWORD WINAPI sleepy(VOID *arg)
+	{
+	schlock = 1;
+	Sleep(lapse);
+	run = 0;
+	return 0;
+	}
+
+static double Time_F(int s)
+	{
+	if (s == START)
+		{
+		HANDLE	thr;
+		schlock = 0;
+		thr = CreateThread(NULL,4096,sleepy,NULL,0,NULL);
+		if (thr==NULL)
+			{
+			DWORD ret=GetLastError();
+			BIO_printf(bio_err,"unable to CreateThread (%d)",ret);
+			ExitProcess(ret);
+			}
+		CloseHandle(thr);		/* detach the thread	*/
+		while (!schlock) Sleep(0);	/* scheduler spinlock	*/
+		}
+
+	return app_tminterval(s,usertime);
+	}
+#else
+
+static double Time_F(int s)
+	{
+	return app_tminterval(s,usertime);
+	}
+#endif
+
+
+#ifndef OPENSSL_NO_ECDH
+static const int KDF1_SHA1_len = 20;
+static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen)
+	{
+#ifndef OPENSSL_NO_SHA
+	if (*outlen < SHA_DIGEST_LENGTH)
+		return NULL;
+	else
+		*outlen = SHA_DIGEST_LENGTH;
+	return SHA1(in, inlen, out);
+#else
+	return NULL;
+#endif	/* OPENSSL_NO_SHA */
+	}
+#endif	/* OPENSSL_NO_ECDH */
+
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	unsigned char *buf=NULL,*buf2=NULL;
+	int mret=1;
+	long count=0,save_count=0;
+	int i,j,k;
+#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA)
+	long rsa_count;
+#endif
+#ifndef OPENSSL_NO_RSA
+	unsigned rsa_num;
+#endif
+	unsigned char md[EVP_MAX_MD_SIZE];
+#ifndef OPENSSL_NO_MD2
+	unsigned char md2[MD2_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_MDC2
+	unsigned char mdc2[MDC2_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_MD4
+	unsigned char md4[MD4_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_MD5
+	unsigned char md5[MD5_DIGEST_LENGTH];
+	unsigned char hmac[MD5_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_SHA
+	unsigned char sha[SHA_DIGEST_LENGTH];
+#ifndef OPENSSL_NO_SHA256
+	unsigned char sha256[SHA256_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_SHA512
+	unsigned char sha512[SHA512_DIGEST_LENGTH];
+#endif
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+	unsigned char whirlpool[WHIRLPOOL_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_RIPEMD
+	unsigned char rmd160[RIPEMD160_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_RC4
+	RC4_KEY rc4_ks;
+#endif
+#ifndef OPENSSL_NO_RC5
+	RC5_32_KEY rc5_ks;
+#endif
+#ifndef OPENSSL_NO_RC2
+	RC2_KEY rc2_ks;
+#endif
+#ifndef OPENSSL_NO_IDEA
+	IDEA_KEY_SCHEDULE idea_ks;
+#endif
+#ifndef OPENSSL_NO_SEED
+	SEED_KEY_SCHEDULE seed_ks;
+#endif
+#ifndef OPENSSL_NO_BF
+	BF_KEY bf_ks;
+#endif
+#ifndef OPENSSL_NO_CAST
+	CAST_KEY cast_ks;
+#endif
+	static const unsigned char key16[16]=
+		{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+		 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
+#ifndef OPENSSL_NO_AES
+	static const unsigned char key24[24]=
+		{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+		 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,
+		 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
+	static const unsigned char key32[32]=
+		{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+		 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,
+		 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,
+		 0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,0x56};
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+	static const unsigned char ckey24[24]=
+		{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+		 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,
+		 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
+	static const unsigned char ckey32[32]=
+		{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+		 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,
+		 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,
+		 0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,0x56};
+#endif
+#ifndef OPENSSL_NO_AES
+#define MAX_BLOCK_SIZE 128
+#else
+#define MAX_BLOCK_SIZE 64
+#endif
+	unsigned char DES_iv[8];
+	unsigned char iv[2*MAX_BLOCK_SIZE/8];
+#ifndef OPENSSL_NO_DES
+	static DES_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
+	static DES_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
+	static DES_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
+	DES_key_schedule sch;
+	DES_key_schedule sch2;
+	DES_key_schedule sch3;
+#endif
+#ifndef OPENSSL_NO_AES
+	AES_KEY aes_ks1, aes_ks2, aes_ks3;
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+	CAMELLIA_KEY camellia_ks1, camellia_ks2, camellia_ks3;
+#endif
+#define	D_MD2		0
+#define	D_MDC2		1
+#define	D_MD4		2
+#define	D_MD5		3
+#define	D_HMAC		4
+#define	D_SHA1		5
+#define D_RMD160	6
+#define	D_RC4		7
+#define	D_CBC_DES	8
+#define	D_EDE3_DES	9
+#define	D_CBC_IDEA	10
+#define	D_CBC_SEED	11
+#define	D_CBC_RC2	12
+#define	D_CBC_RC5	13
+#define	D_CBC_BF	14
+#define	D_CBC_CAST	15
+#define D_CBC_128_AES	16
+#define D_CBC_192_AES	17
+#define D_CBC_256_AES	18
+#define D_CBC_128_CML   19 
+#define D_CBC_192_CML   20
+#define D_CBC_256_CML   21 
+#define D_EVP		22
+#define D_SHA256	23	
+#define D_SHA512	24
+#define D_WHIRLPOOL	25
+#define D_IGE_128_AES   26
+#define D_IGE_192_AES   27
+#define D_IGE_256_AES   28
+	double d=0.0;
+	long c[ALGOR_NUM][SIZE_NUM];
+#define	R_DSA_512	0
+#define	R_DSA_1024	1
+#define	R_DSA_2048	2
+#define	R_RSA_512	0
+#define	R_RSA_1024	1
+#define	R_RSA_2048	2
+#define	R_RSA_4096	3
+
+#define R_EC_P160    0
+#define R_EC_P192    1	
+#define R_EC_P224    2
+#define R_EC_P256    3
+#define R_EC_P384    4
+#define R_EC_P521    5
+#define R_EC_K163    6
+#define R_EC_K233    7
+#define R_EC_K283    8
+#define R_EC_K409    9
+#define R_EC_K571    10
+#define R_EC_B163    11
+#define R_EC_B233    12
+#define R_EC_B283    13
+#define R_EC_B409    14
+#define R_EC_B571    15
+
+#ifndef OPENSSL_NO_RSA
+	RSA *rsa_key[RSA_NUM];
+	long rsa_c[RSA_NUM][2];
+	static unsigned int rsa_bits[RSA_NUM]={512,1024,2048,4096};
+	static unsigned char *rsa_data[RSA_NUM]=
+		{test512,test1024,test2048,test4096};
+	static int rsa_data_length[RSA_NUM]={
+		sizeof(test512),sizeof(test1024),
+		sizeof(test2048),sizeof(test4096)};
+#endif
+#ifndef OPENSSL_NO_DSA
+	DSA *dsa_key[DSA_NUM];
+	long dsa_c[DSA_NUM][2];
+	static unsigned int dsa_bits[DSA_NUM]={512,1024,2048};
+#endif
+#ifndef OPENSSL_NO_EC
+	/* We only test over the following curves as they are representative, 
+	 * To add tests over more curves, simply add the curve NID
+	 * and curve name to the following arrays and increase the 
+	 * EC_NUM value accordingly. 
+	 */
+	static unsigned int test_curves[EC_NUM] = 
+	{	
+	/* Prime Curves */
+	NID_secp160r1,
+	NID_X9_62_prime192v1,
+	NID_secp224r1,
+	NID_X9_62_prime256v1,
+	NID_secp384r1,
+	NID_secp521r1,
+	/* Binary Curves */
+	NID_sect163k1,
+	NID_sect233k1,
+	NID_sect283k1,
+	NID_sect409k1,
+	NID_sect571k1,
+	NID_sect163r2,
+	NID_sect233r1,
+	NID_sect283r1,
+	NID_sect409r1,
+	NID_sect571r1
+	}; 
+	static const char * test_curves_names[EC_NUM] = 
+	{
+	/* Prime Curves */
+	"secp160r1",
+	"nistp192",
+	"nistp224",
+	"nistp256",
+	"nistp384",
+	"nistp521",
+	/* Binary Curves */
+	"nistk163",
+	"nistk233",
+	"nistk283",
+	"nistk409",
+	"nistk571",
+	"nistb163",
+	"nistb233",
+	"nistb283",
+	"nistb409",
+	"nistb571"
+	};
+	static int test_curves_bits[EC_NUM] =
+        {
+        160, 192, 224, 256, 384, 521,
+        163, 233, 283, 409, 571,
+        163, 233, 283, 409, 571
+        };
+
+#endif
+
+#ifndef OPENSSL_NO_ECDSA
+	unsigned char ecdsasig[256];
+	unsigned int ecdsasiglen;
+	EC_KEY *ecdsa[EC_NUM];
+	long ecdsa_c[EC_NUM][2];
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+	EC_KEY *ecdh_a[EC_NUM], *ecdh_b[EC_NUM];
+	unsigned char secret_a[MAX_ECDH_SIZE], secret_b[MAX_ECDH_SIZE];
+	int secret_size_a, secret_size_b;
+	int ecdh_checks = 0;
+	int secret_idx = 0;
+	long ecdh_c[EC_NUM][2];
+#endif
+
+	int rsa_doit[RSA_NUM];
+	int dsa_doit[DSA_NUM];
+#ifndef OPENSSL_NO_ECDSA
+	int ecdsa_doit[EC_NUM];
+#endif
+#ifndef OPENSSL_NO_ECDH
+        int ecdh_doit[EC_NUM];
+#endif
+	int doit[ALGOR_NUM];
+	int pr_header=0;
+	const EVP_CIPHER *evp_cipher=NULL;
+	const EVP_MD *evp_md=NULL;
+	int decrypt=0;
+#ifndef NO_FORK
+	int multi=0;
+#endif
+
+#ifndef TIMES
+	usertime=-1;
+#endif
+
+	apps_startup();
+	memset(results, 0, sizeof(results));
+#ifndef OPENSSL_NO_DSA
+	memset(dsa_key,0,sizeof(dsa_key));
+#endif
+#ifndef OPENSSL_NO_ECDSA
+	for (i=0; i<EC_NUM; i++) ecdsa[i] = NULL;
+#endif
+#ifndef OPENSSL_NO_ECDH
+	for (i=0; i<EC_NUM; i++)
+		{
+		ecdh_a[i] = NULL;
+		ecdh_b[i] = NULL;
+		}
+#endif
+
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+#ifndef OPENSSL_NO_RSA
+	memset(rsa_key,0,sizeof(rsa_key));
+	for (i=0; i<RSA_NUM; i++)
+		rsa_key[i]=NULL;
+#endif
+
+	if ((buf=(unsigned char *)OPENSSL_malloc((int)BUFSIZE)) == NULL)
+		{
+		BIO_printf(bio_err,"out of memory\n");
+		goto end;
+		}
+	if ((buf2=(unsigned char *)OPENSSL_malloc((int)BUFSIZE)) == NULL)
+		{
+		BIO_printf(bio_err,"out of memory\n");
+		goto end;
+		}
+
+	memset(c,0,sizeof(c));
+	memset(DES_iv,0,sizeof(DES_iv));
+	memset(iv,0,sizeof(iv));
+
+	for (i=0; i<ALGOR_NUM; i++)
+		doit[i]=0;
+	for (i=0; i<RSA_NUM; i++)
+		rsa_doit[i]=0;
+	for (i=0; i<DSA_NUM; i++)
+		dsa_doit[i]=0;
+#ifndef OPENSSL_NO_ECDSA
+	for (i=0; i<EC_NUM; i++)
+		ecdsa_doit[i]=0;
+#endif
+#ifndef OPENSSL_NO_ECDH
+	for (i=0; i<EC_NUM; i++)
+		ecdh_doit[i]=0;
+#endif
+
+	
+	j=0;
+	argc--;
+	argv++;
+	while (argc)
+		{
+		if	((argc > 0) && (strcmp(*argv,"-elapsed") == 0))
+			{
+			usertime = 0;
+			j--;	/* Otherwise, -elapsed gets confused with
+				   an algorithm. */
+			}
+		else if	((argc > 0) && (strcmp(*argv,"-evp") == 0))
+			{
+			argc--;
+			argv++;
+			if(argc == 0)
+				{
+				BIO_printf(bio_err,"no EVP given\n");
+				goto end;
+				}
+			evp_cipher=EVP_get_cipherbyname(*argv);
+			if(!evp_cipher)
+				{
+				evp_md=EVP_get_digestbyname(*argv);
+				}
+			if(!evp_cipher && !evp_md)
+				{
+				BIO_printf(bio_err,"%s is an unknown cipher or digest\n",*argv);
+				goto end;
+				}
+			doit[D_EVP]=1;
+			}
+		else if (argc > 0 && !strcmp(*argv,"-decrypt"))
+			{
+			decrypt=1;
+			j--;	/* Otherwise, -elapsed gets confused with
+				   an algorithm. */
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if	((argc > 0) && (strcmp(*argv,"-engine") == 0))
+			{
+			argc--;
+			argv++;
+			if(argc == 0)
+				{
+				BIO_printf(bio_err,"no engine given\n");
+				goto end;
+				}
+                        setup_engine(bio_err, *argv, 0);
+			/* j will be increased again further down.  We just
+			   don't want speed to confuse an engine with an
+			   algorithm, especially when none is given (which
+			   means all of them should be run) */
+			j--;
+			}
+#endif
+#ifndef NO_FORK
+		else if	((argc > 0) && (strcmp(*argv,"-multi") == 0))
+			{
+			argc--;
+			argv++;
+			if(argc == 0)
+				{
+				BIO_printf(bio_err,"no multi count given\n");
+				goto end;
+				}
+			multi=atoi(argv[0]);
+			if(multi <= 0)
+			    {
+				BIO_printf(bio_err,"bad multi count\n");
+				goto end;
+				}				
+			j--;	/* Otherwise, -mr gets confused with
+				   an algorithm. */
+			}
+#endif
+		else if (argc > 0 && !strcmp(*argv,"-mr"))
+			{
+			mr=1;
+			j--;	/* Otherwise, -mr gets confused with
+				   an algorithm. */
+			}
+		else
+#ifndef OPENSSL_NO_MD2
+		if	(strcmp(*argv,"md2") == 0) doit[D_MD2]=1;
+		else
+#endif
+#ifndef OPENSSL_NO_MDC2
+			if (strcmp(*argv,"mdc2") == 0) doit[D_MDC2]=1;
+		else
+#endif
+#ifndef OPENSSL_NO_MD4
+			if (strcmp(*argv,"md4") == 0) doit[D_MD4]=1;
+		else
+#endif
+#ifndef OPENSSL_NO_MD5
+			if (strcmp(*argv,"md5") == 0) doit[D_MD5]=1;
+		else
+#endif
+#ifndef OPENSSL_NO_MD5
+			if (strcmp(*argv,"hmac") == 0) doit[D_HMAC]=1;
+		else
+#endif
+#ifndef OPENSSL_NO_SHA
+			if (strcmp(*argv,"sha1") == 0) doit[D_SHA1]=1;
+		else
+			if (strcmp(*argv,"sha") == 0)	doit[D_SHA1]=1,
+							doit[D_SHA256]=1,
+							doit[D_SHA512]=1;
+		else
+#ifndef OPENSSL_NO_SHA256
+			if (strcmp(*argv,"sha256") == 0) doit[D_SHA256]=1;
+		else
+#endif
+#ifndef OPENSSL_NO_SHA512
+			if (strcmp(*argv,"sha512") == 0) doit[D_SHA512]=1;
+		else
+#endif
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+			if (strcmp(*argv,"whirlpool") == 0) doit[D_WHIRLPOOL]=1;
+		else
+#endif
+#ifndef OPENSSL_NO_RIPEMD
+			if (strcmp(*argv,"ripemd") == 0) doit[D_RMD160]=1;
+		else
+			if (strcmp(*argv,"rmd160") == 0) doit[D_RMD160]=1;
+		else
+			if (strcmp(*argv,"ripemd160") == 0) doit[D_RMD160]=1;
+		else
+#endif
+#ifndef OPENSSL_NO_RC4
+			if (strcmp(*argv,"rc4") == 0) doit[D_RC4]=1;
+		else 
+#endif
+#ifndef OPENSSL_NO_DES
+			if (strcmp(*argv,"des-cbc") == 0) doit[D_CBC_DES]=1;
+		else	if (strcmp(*argv,"des-ede3") == 0) doit[D_EDE3_DES]=1;
+		else
+#endif
+#ifndef OPENSSL_NO_AES
+			if (strcmp(*argv,"aes-128-cbc") == 0) doit[D_CBC_128_AES]=1;
+		else	if (strcmp(*argv,"aes-192-cbc") == 0) doit[D_CBC_192_AES]=1;
+		else	if (strcmp(*argv,"aes-256-cbc") == 0) doit[D_CBC_256_AES]=1;
+		else    if (strcmp(*argv,"aes-128-ige") == 0) doit[D_IGE_128_AES]=1;
+		else	if (strcmp(*argv,"aes-192-ige") == 0) doit[D_IGE_192_AES]=1;
+		else	if (strcmp(*argv,"aes-256-ige") == 0) doit[D_IGE_256_AES]=1;
+                else
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+			if (strcmp(*argv,"camellia-128-cbc") == 0) doit[D_CBC_128_CML]=1;
+		else    if (strcmp(*argv,"camellia-192-cbc") == 0) doit[D_CBC_192_CML]=1;
+		else    if (strcmp(*argv,"camellia-256-cbc") == 0) doit[D_CBC_256_CML]=1;
+		else
+#endif
+#ifndef OPENSSL_NO_RSA
+#if 0 /* was: #ifdef RSAref */
+			if (strcmp(*argv,"rsaref") == 0) 
+			{
+			RSA_set_default_openssl_method(RSA_PKCS1_RSAref());
+			j--;
+			}
+		else
+#endif
+#ifndef RSA_NULL
+			if (strcmp(*argv,"openssl") == 0) 
+			{
+			RSA_set_default_method(RSA_PKCS1_SSLeay());
+			j--;
+			}
+		else
+#endif
+#endif /* !OPENSSL_NO_RSA */
+		     if (strcmp(*argv,"dsa512") == 0) dsa_doit[R_DSA_512]=2;
+		else if (strcmp(*argv,"dsa1024") == 0) dsa_doit[R_DSA_1024]=2;
+		else if (strcmp(*argv,"dsa2048") == 0) dsa_doit[R_DSA_2048]=2;
+		else if (strcmp(*argv,"rsa512") == 0) rsa_doit[R_RSA_512]=2;
+		else if (strcmp(*argv,"rsa1024") == 0) rsa_doit[R_RSA_1024]=2;
+		else if (strcmp(*argv,"rsa2048") == 0) rsa_doit[R_RSA_2048]=2;
+		else if (strcmp(*argv,"rsa4096") == 0) rsa_doit[R_RSA_4096]=2;
+		else
+#ifndef OPENSSL_NO_RC2
+		     if (strcmp(*argv,"rc2-cbc") == 0) doit[D_CBC_RC2]=1;
+		else if (strcmp(*argv,"rc2") == 0) doit[D_CBC_RC2]=1;
+		else
+#endif
+#ifndef OPENSSL_NO_RC5
+		     if (strcmp(*argv,"rc5-cbc") == 0) doit[D_CBC_RC5]=1;
+		else if (strcmp(*argv,"rc5") == 0) doit[D_CBC_RC5]=1;
+		else
+#endif
+#ifndef OPENSSL_NO_IDEA
+		     if (strcmp(*argv,"idea-cbc") == 0) doit[D_CBC_IDEA]=1;
+		else if (strcmp(*argv,"idea") == 0) doit[D_CBC_IDEA]=1;
+		else
+#endif
+#ifndef OPENSSL_NO_SEED
+		     if (strcmp(*argv,"seed-cbc") == 0) doit[D_CBC_SEED]=1;
+		else if (strcmp(*argv,"seed") == 0) doit[D_CBC_SEED]=1;
+		else
+#endif
+#ifndef OPENSSL_NO_BF
+		     if (strcmp(*argv,"bf-cbc") == 0) doit[D_CBC_BF]=1;
+		else if (strcmp(*argv,"blowfish") == 0) doit[D_CBC_BF]=1;
+		else if (strcmp(*argv,"bf") == 0) doit[D_CBC_BF]=1;
+		else
+#endif
+#ifndef OPENSSL_NO_CAST
+		     if (strcmp(*argv,"cast-cbc") == 0) doit[D_CBC_CAST]=1;
+		else if (strcmp(*argv,"cast") == 0) doit[D_CBC_CAST]=1;
+		else if (strcmp(*argv,"cast5") == 0) doit[D_CBC_CAST]=1;
+		else
+#endif
+#ifndef OPENSSL_NO_DES
+			if (strcmp(*argv,"des") == 0)
+			{
+			doit[D_CBC_DES]=1;
+			doit[D_EDE3_DES]=1;
+			}
+		else
+#endif
+#ifndef OPENSSL_NO_AES
+			if (strcmp(*argv,"aes") == 0)
+			{
+			doit[D_CBC_128_AES]=1;
+			doit[D_CBC_192_AES]=1;
+			doit[D_CBC_256_AES]=1;
+			}
+		else
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+			if (strcmp(*argv,"camellia") == 0)
+			{
+			doit[D_CBC_128_CML]=1;
+			doit[D_CBC_192_CML]=1;
+			doit[D_CBC_256_CML]=1;
+			}
+		else
+#endif
+#ifndef OPENSSL_NO_RSA
+			if (strcmp(*argv,"rsa") == 0)
+			{
+			rsa_doit[R_RSA_512]=1;
+			rsa_doit[R_RSA_1024]=1;
+			rsa_doit[R_RSA_2048]=1;
+			rsa_doit[R_RSA_4096]=1;
+			}
+		else
+#endif
+#ifndef OPENSSL_NO_DSA
+			if (strcmp(*argv,"dsa") == 0)
+			{
+			dsa_doit[R_DSA_512]=1;
+			dsa_doit[R_DSA_1024]=1;
+			dsa_doit[R_DSA_2048]=1;
+			}
+		else
+#endif
+#ifndef OPENSSL_NO_ECDSA
+		     if (strcmp(*argv,"ecdsap160") == 0) ecdsa_doit[R_EC_P160]=2;
+		else if (strcmp(*argv,"ecdsap192") == 0) ecdsa_doit[R_EC_P192]=2;
+		else if (strcmp(*argv,"ecdsap224") == 0) ecdsa_doit[R_EC_P224]=2;
+		else if (strcmp(*argv,"ecdsap256") == 0) ecdsa_doit[R_EC_P256]=2;
+		else if (strcmp(*argv,"ecdsap384") == 0) ecdsa_doit[R_EC_P384]=2;
+		else if (strcmp(*argv,"ecdsap521") == 0) ecdsa_doit[R_EC_P521]=2;
+		else if (strcmp(*argv,"ecdsak163") == 0) ecdsa_doit[R_EC_K163]=2;
+		else if (strcmp(*argv,"ecdsak233") == 0) ecdsa_doit[R_EC_K233]=2;
+		else if (strcmp(*argv,"ecdsak283") == 0) ecdsa_doit[R_EC_K283]=2;
+		else if (strcmp(*argv,"ecdsak409") == 0) ecdsa_doit[R_EC_K409]=2;
+		else if (strcmp(*argv,"ecdsak571") == 0) ecdsa_doit[R_EC_K571]=2;
+		else if (strcmp(*argv,"ecdsab163") == 0) ecdsa_doit[R_EC_B163]=2;
+		else if (strcmp(*argv,"ecdsab233") == 0) ecdsa_doit[R_EC_B233]=2;
+		else if (strcmp(*argv,"ecdsab283") == 0) ecdsa_doit[R_EC_B283]=2;
+		else if (strcmp(*argv,"ecdsab409") == 0) ecdsa_doit[R_EC_B409]=2;
+		else if (strcmp(*argv,"ecdsab571") == 0) ecdsa_doit[R_EC_B571]=2;
+		else if (strcmp(*argv,"ecdsa") == 0)
+			{
+			for (i=0; i < EC_NUM; i++)
+				ecdsa_doit[i]=1;
+			}
+		else
+#endif
+#ifndef OPENSSL_NO_ECDH
+		     if (strcmp(*argv,"ecdhp160") == 0) ecdh_doit[R_EC_P160]=2;
+		else if (strcmp(*argv,"ecdhp192") == 0) ecdh_doit[R_EC_P192]=2;
+		else if (strcmp(*argv,"ecdhp224") == 0) ecdh_doit[R_EC_P224]=2;
+		else if (strcmp(*argv,"ecdhp256") == 0) ecdh_doit[R_EC_P256]=2;
+		else if (strcmp(*argv,"ecdhp384") == 0) ecdh_doit[R_EC_P384]=2;
+		else if (strcmp(*argv,"ecdhp521") == 0) ecdh_doit[R_EC_P521]=2;
+		else if (strcmp(*argv,"ecdhk163") == 0) ecdh_doit[R_EC_K163]=2;
+		else if (strcmp(*argv,"ecdhk233") == 0) ecdh_doit[R_EC_K233]=2;
+		else if (strcmp(*argv,"ecdhk283") == 0) ecdh_doit[R_EC_K283]=2;
+		else if (strcmp(*argv,"ecdhk409") == 0) ecdh_doit[R_EC_K409]=2;
+		else if (strcmp(*argv,"ecdhk571") == 0) ecdh_doit[R_EC_K571]=2;
+		else if (strcmp(*argv,"ecdhb163") == 0) ecdh_doit[R_EC_B163]=2;
+		else if (strcmp(*argv,"ecdhb233") == 0) ecdh_doit[R_EC_B233]=2;
+		else if (strcmp(*argv,"ecdhb283") == 0) ecdh_doit[R_EC_B283]=2;
+		else if (strcmp(*argv,"ecdhb409") == 0) ecdh_doit[R_EC_B409]=2;
+		else if (strcmp(*argv,"ecdhb571") == 0) ecdh_doit[R_EC_B571]=2;
+		else if (strcmp(*argv,"ecdh") == 0)
+			{
+			for (i=0; i < EC_NUM; i++)
+				ecdh_doit[i]=1;
+			}
+		else
+#endif
+			{
+			BIO_printf(bio_err,"Error: bad option or value\n");
+			BIO_printf(bio_err,"\n");
+			BIO_printf(bio_err,"Available values:\n");
+#ifndef OPENSSL_NO_MD2
+			BIO_printf(bio_err,"md2      ");
+#endif
+#ifndef OPENSSL_NO_MDC2
+			BIO_printf(bio_err,"mdc2     ");
+#endif
+#ifndef OPENSSL_NO_MD4
+			BIO_printf(bio_err,"md4      ");
+#endif
+#ifndef OPENSSL_NO_MD5
+			BIO_printf(bio_err,"md5      ");
+#ifndef OPENSSL_NO_HMAC
+			BIO_printf(bio_err,"hmac     ");
+#endif
+#endif
+#ifndef OPENSSL_NO_SHA1
+			BIO_printf(bio_err,"sha1     ");
+#endif
+#ifndef OPENSSL_NO_SHA256
+			BIO_printf(bio_err,"sha256   ");
+#endif
+#ifndef OPENSSL_NO_SHA512
+			BIO_printf(bio_err,"sha512   ");
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+			BIO_printf(bio_err,"whirlpool");
+#endif
+#ifndef OPENSSL_NO_RIPEMD160
+			BIO_printf(bio_err,"rmd160");
+#endif
+#if !defined(OPENSSL_NO_MD2) || !defined(OPENSSL_NO_MDC2) || \
+    !defined(OPENSSL_NO_MD4) || !defined(OPENSSL_NO_MD5) || \
+    !defined(OPENSSL_NO_SHA1) || !defined(OPENSSL_NO_RIPEMD160) || \
+    !defined(OPENSSL_NO_WHIRLPOOL)
+			BIO_printf(bio_err,"\n");
+#endif
+
+#ifndef OPENSSL_NO_IDEA
+			BIO_printf(bio_err,"idea-cbc ");
+#endif
+#ifndef OPENSSL_NO_SEED
+			BIO_printf(bio_err,"seed-cbc ");
+#endif
+#ifndef OPENSSL_NO_RC2
+			BIO_printf(bio_err,"rc2-cbc  ");
+#endif
+#ifndef OPENSSL_NO_RC5
+			BIO_printf(bio_err,"rc5-cbc  ");
+#endif
+#ifndef OPENSSL_NO_BF
+			BIO_printf(bio_err,"bf-cbc");
+#endif
+#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_SEED) || !defined(OPENSSL_NO_RC2) || \
+    !defined(OPENSSL_NO_BF) || !defined(OPENSSL_NO_RC5)
+			BIO_printf(bio_err,"\n");
+#endif
+#ifndef OPENSSL_NO_DES
+			BIO_printf(bio_err,"des-cbc  des-ede3 ");
+#endif
+#ifndef OPENSSL_NO_AES
+			BIO_printf(bio_err,"aes-128-cbc aes-192-cbc aes-256-cbc ");
+			BIO_printf(bio_err,"aes-128-ige aes-192-ige aes-256-ige ");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+			BIO_printf(bio_err,"\n");
+			BIO_printf(bio_err,"camellia-128-cbc camellia-192-cbc camellia-256-cbc ");
+#endif
+#ifndef OPENSSL_NO_RC4
+			BIO_printf(bio_err,"rc4");
+#endif
+			BIO_printf(bio_err,"\n");
+
+#ifndef OPENSSL_NO_RSA
+			BIO_printf(bio_err,"rsa512   rsa1024  rsa2048  rsa4096\n");
+#endif
+
+#ifndef OPENSSL_NO_DSA
+			BIO_printf(bio_err,"dsa512   dsa1024  dsa2048\n");
+#endif
+#ifndef OPENSSL_NO_ECDSA
+			BIO_printf(bio_err,"ecdsap160 ecdsap192 ecdsap224 ecdsap256 ecdsap384 ecdsap521\n");
+			BIO_printf(bio_err,"ecdsak163 ecdsak233 ecdsak283 ecdsak409 ecdsak571\n");
+			BIO_printf(bio_err,"ecdsab163 ecdsab233 ecdsab283 ecdsab409 ecdsab571\n");
+			BIO_printf(bio_err,"ecdsa\n");
+#endif
+#ifndef OPENSSL_NO_ECDH
+			BIO_printf(bio_err,"ecdhp160  ecdhp192  ecdhp224  ecdhp256  ecdhp384  ecdhp521\n");
+			BIO_printf(bio_err,"ecdhk163  ecdhk233  ecdhk283  ecdhk409  ecdhk571\n");
+			BIO_printf(bio_err,"ecdhb163  ecdhb233  ecdhb283  ecdhb409  ecdhb571\n");
+			BIO_printf(bio_err,"ecdh\n");
+#endif
+
+#ifndef OPENSSL_NO_IDEA
+			BIO_printf(bio_err,"idea     ");
+#endif
+#ifndef OPENSSL_NO_SEED
+			BIO_printf(bio_err,"seed     ");
+#endif
+#ifndef OPENSSL_NO_RC2
+			BIO_printf(bio_err,"rc2      ");
+#endif
+#ifndef OPENSSL_NO_DES
+			BIO_printf(bio_err,"des      ");
+#endif
+#ifndef OPENSSL_NO_AES
+			BIO_printf(bio_err,"aes      ");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+			BIO_printf(bio_err,"camellia ");
+#endif
+#ifndef OPENSSL_NO_RSA
+			BIO_printf(bio_err,"rsa      ");
+#endif
+#ifndef OPENSSL_NO_BF
+			BIO_printf(bio_err,"blowfish");
+#endif
+#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_SEED) || \
+    !defined(OPENSSL_NO_RC2) || !defined(OPENSSL_NO_DES) || \
+    !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_BF) || \
+    !defined(OPENSSL_NO_AES) || !defined(OPENSSL_NO_CAMELLIA)
+			BIO_printf(bio_err,"\n");
+#endif
+
+			BIO_printf(bio_err,"\n");
+			BIO_printf(bio_err,"Available options:\n");
+#if defined(TIMES) || defined(USE_TOD)
+			BIO_printf(bio_err,"-elapsed        measure time in real time instead of CPU user time.\n");
+#endif
+#ifndef OPENSSL_NO_ENGINE
+			BIO_printf(bio_err,"-engine e       use engine e, possibly a hardware device.\n");
+#endif
+			BIO_printf(bio_err,"-evp e          use EVP e.\n");
+			BIO_printf(bio_err,"-decrypt        time decryption instead of encryption (only EVP).\n");
+			BIO_printf(bio_err,"-mr             produce machine readable output.\n");
+#ifndef NO_FORK
+			BIO_printf(bio_err,"-multi n        run n benchmarks in parallel.\n");
+#endif
+			goto end;
+			}
+		argc--;
+		argv++;
+		j++;
+		}
+
+#ifndef NO_FORK
+	if(multi && do_multi(multi))
+		goto show_res;
+#endif
+
+	if (j == 0)
+		{
+		for (i=0; i<ALGOR_NUM; i++)
+			{
+			if (i != D_EVP)
+				doit[i]=1;
+			}
+		for (i=0; i<RSA_NUM; i++)
+			rsa_doit[i]=1;
+		for (i=0; i<DSA_NUM; i++)
+			dsa_doit[i]=1;
+#ifndef OPENSSL_NO_ECDSA
+		for (i=0; i<EC_NUM; i++)
+			ecdsa_doit[i]=1;
+#endif
+#ifndef OPENSSL_NO_ECDH
+		for (i=0; i<EC_NUM; i++)
+			ecdh_doit[i]=1;
+#endif
+		}
+	for (i=0; i<ALGOR_NUM; i++)
+		if (doit[i]) pr_header++;
+
+	if (usertime == 0 && !mr)
+		BIO_printf(bio_err,"You have chosen to measure elapsed time instead of user CPU time.\n");
+
+#ifndef OPENSSL_NO_RSA
+	for (i=0; i<RSA_NUM; i++)
+		{
+		const unsigned char *p;
+
+		p=rsa_data[i];
+		rsa_key[i]=d2i_RSAPrivateKey(NULL,&p,rsa_data_length[i]);
+		if (rsa_key[i] == NULL)
+			{
+			BIO_printf(bio_err,"internal error loading RSA key number %d\n",i);
+			goto end;
+			}
+#if 0
+		else
+			{
+			BIO_printf(bio_err,mr ? "+RK:%d:"
+				   : "Loaded RSA key, %d bit modulus and e= 0x",
+				   BN_num_bits(rsa_key[i]->n));
+			BN_print(bio_err,rsa_key[i]->e);
+			BIO_printf(bio_err,"\n");
+			}
+#endif
+		}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+	dsa_key[0]=get_dsa512();
+	dsa_key[1]=get_dsa1024();
+	dsa_key[2]=get_dsa2048();
+#endif
+
+#ifndef OPENSSL_NO_DES
+	DES_set_key_unchecked(&key,&sch);
+	DES_set_key_unchecked(&key2,&sch2);
+	DES_set_key_unchecked(&key3,&sch3);
+#endif
+#ifndef OPENSSL_NO_AES
+	AES_set_encrypt_key(key16,128,&aes_ks1);
+	AES_set_encrypt_key(key24,192,&aes_ks2);
+	AES_set_encrypt_key(key32,256,&aes_ks3);
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+	Camellia_set_key(key16,128,&camellia_ks1);
+	Camellia_set_key(ckey24,192,&camellia_ks2);
+	Camellia_set_key(ckey32,256,&camellia_ks3);
+#endif
+#ifndef OPENSSL_NO_IDEA
+	idea_set_encrypt_key(key16,&idea_ks);
+#endif
+#ifndef OPENSSL_NO_SEED
+	SEED_set_key(key16,&seed_ks);
+#endif
+#ifndef OPENSSL_NO_RC4
+	RC4_set_key(&rc4_ks,16,key16);
+#endif
+#ifndef OPENSSL_NO_RC2
+	RC2_set_key(&rc2_ks,16,key16,128);
+#endif
+#ifndef OPENSSL_NO_RC5
+	RC5_32_set_key(&rc5_ks,16,key16,12);
+#endif
+#ifndef OPENSSL_NO_BF
+	BF_set_key(&bf_ks,16,key16);
+#endif
+#ifndef OPENSSL_NO_CAST
+	CAST_set_key(&cast_ks,16,key16);
+#endif
+#ifndef OPENSSL_NO_RSA
+	memset(rsa_c,0,sizeof(rsa_c));
+#endif
+#ifndef SIGALRM
+#ifndef OPENSSL_NO_DES
+	BIO_printf(bio_err,"First we calculate the approximate speed ...\n");
+	count=10;
+	do	{
+		long it;
+		count*=2;
+		Time_F(START);
+		for (it=count; it; it--)
+			DES_ecb_encrypt((DES_cblock *)buf,
+				(DES_cblock *)buf,
+				&sch,DES_ENCRYPT);
+		d=Time_F(STOP);
+		} while (d <3);
+	save_count=count;
+	c[D_MD2][0]=count/10;
+	c[D_MDC2][0]=count/10;
+	c[D_MD4][0]=count;
+	c[D_MD5][0]=count;
+	c[D_HMAC][0]=count;
+	c[D_SHA1][0]=count;
+	c[D_RMD160][0]=count;
+	c[D_RC4][0]=count*5;
+	c[D_CBC_DES][0]=count;
+	c[D_EDE3_DES][0]=count/3;
+	c[D_CBC_IDEA][0]=count;
+	c[D_CBC_SEED][0]=count;
+	c[D_CBC_RC2][0]=count;
+	c[D_CBC_RC5][0]=count;
+	c[D_CBC_BF][0]=count;
+	c[D_CBC_CAST][0]=count;
+	c[D_CBC_128_AES][0]=count;
+	c[D_CBC_192_AES][0]=count;
+	c[D_CBC_256_AES][0]=count;
+	c[D_CBC_128_CML][0]=count;
+	c[D_CBC_192_CML][0]=count;
+	c[D_CBC_256_CML][0]=count;
+	c[D_SHA256][0]=count;
+	c[D_SHA512][0]=count;
+	c[D_WHIRLPOOL][0]=count;
+	c[D_IGE_128_AES][0]=count;
+	c[D_IGE_192_AES][0]=count;
+	c[D_IGE_256_AES][0]=count;
+
+	for (i=1; i<SIZE_NUM; i++)
+		{
+		c[D_MD2][i]=c[D_MD2][0]*4*lengths[0]/lengths[i];
+		c[D_MDC2][i]=c[D_MDC2][0]*4*lengths[0]/lengths[i];
+		c[D_MD4][i]=c[D_MD4][0]*4*lengths[0]/lengths[i];
+		c[D_MD5][i]=c[D_MD5][0]*4*lengths[0]/lengths[i];
+		c[D_HMAC][i]=c[D_HMAC][0]*4*lengths[0]/lengths[i];
+		c[D_SHA1][i]=c[D_SHA1][0]*4*lengths[0]/lengths[i];
+		c[D_RMD160][i]=c[D_RMD160][0]*4*lengths[0]/lengths[i];
+		c[D_SHA256][i]=c[D_SHA256][0]*4*lengths[0]/lengths[i];
+		c[D_SHA512][i]=c[D_SHA512][0]*4*lengths[0]/lengths[i];
+		c[D_WHIRLPOOL][i]=c[D_WHIRLPOOL][0]*4*lengths[0]/lengths[i];
+		}
+	for (i=1; i<SIZE_NUM; i++)
+		{
+		long l0,l1;
+
+		l0=(long)lengths[i-1];
+		l1=(long)lengths[i];
+		c[D_RC4][i]=c[D_RC4][i-1]*l0/l1;
+		c[D_CBC_DES][i]=c[D_CBC_DES][i-1]*l0/l1;
+		c[D_EDE3_DES][i]=c[D_EDE3_DES][i-1]*l0/l1;
+		c[D_CBC_IDEA][i]=c[D_CBC_IDEA][i-1]*l0/l1;
+		c[D_CBC_SEED][i]=c[D_CBC_SEED][i-1]*l0/l1;
+		c[D_CBC_RC2][i]=c[D_CBC_RC2][i-1]*l0/l1;
+		c[D_CBC_RC5][i]=c[D_CBC_RC5][i-1]*l0/l1;
+		c[D_CBC_BF][i]=c[D_CBC_BF][i-1]*l0/l1;
+		c[D_CBC_CAST][i]=c[D_CBC_CAST][i-1]*l0/l1;
+		c[D_CBC_128_AES][i]=c[D_CBC_128_AES][i-1]*l0/l1;
+		c[D_CBC_192_AES][i]=c[D_CBC_192_AES][i-1]*l0/l1;
+		c[D_CBC_256_AES][i]=c[D_CBC_256_AES][i-1]*l0/l1;
+ 		c[D_CBC_128_CML][i]=c[D_CBC_128_CML][i-1]*l0/l1;
+		c[D_CBC_192_CML][i]=c[D_CBC_192_CML][i-1]*l0/l1;
+		c[D_CBC_256_CML][i]=c[D_CBC_256_CML][i-1]*l0/l1;
+		c[D_IGE_128_AES][i]=c[D_IGE_128_AES][i-1]*l0/l1;
+		c[D_IGE_192_AES][i]=c[D_IGE_192_AES][i-1]*l0/l1;
+		c[D_IGE_256_AES][i]=c[D_IGE_256_AES][i-1]*l0/l1;
+		}
+#ifndef OPENSSL_NO_RSA
+	rsa_c[R_RSA_512][0]=count/2000;
+	rsa_c[R_RSA_512][1]=count/400;
+	for (i=1; i<RSA_NUM; i++)
+		{
+		rsa_c[i][0]=rsa_c[i-1][0]/8;
+		rsa_c[i][1]=rsa_c[i-1][1]/4;
+		if ((rsa_doit[i] <= 1) && (rsa_c[i][0] == 0))
+			rsa_doit[i]=0;
+		else
+			{
+			if (rsa_c[i][0] == 0)
+				{
+				rsa_c[i][0]=1;
+				rsa_c[i][1]=20;
+				}
+			}				
+		}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+	dsa_c[R_DSA_512][0]=count/1000;
+	dsa_c[R_DSA_512][1]=count/1000/2;
+	for (i=1; i<DSA_NUM; i++)
+		{
+		dsa_c[i][0]=dsa_c[i-1][0]/4;
+		dsa_c[i][1]=dsa_c[i-1][1]/4;
+		if ((dsa_doit[i] <= 1) && (dsa_c[i][0] == 0))
+			dsa_doit[i]=0;
+		else
+			{
+			if (dsa_c[i] == 0)
+				{
+				dsa_c[i][0]=1;
+				dsa_c[i][1]=1;
+				}
+			}				
+		}
+#endif
+
+#ifndef OPENSSL_NO_ECDSA
+	ecdsa_c[R_EC_P160][0]=count/1000;
+	ecdsa_c[R_EC_P160][1]=count/1000/2;
+	for (i=R_EC_P192; i<=R_EC_P521; i++)
+		{
+		ecdsa_c[i][0]=ecdsa_c[i-1][0]/2;
+		ecdsa_c[i][1]=ecdsa_c[i-1][1]/2;
+		if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0))
+			ecdsa_doit[i]=0;
+		else
+			{
+			if (ecdsa_c[i] == 0)
+				{
+				ecdsa_c[i][0]=1;
+				ecdsa_c[i][1]=1;
+				}
+			}
+		}
+	ecdsa_c[R_EC_K163][0]=count/1000;
+	ecdsa_c[R_EC_K163][1]=count/1000/2;
+	for (i=R_EC_K233; i<=R_EC_K571; i++)
+		{
+		ecdsa_c[i][0]=ecdsa_c[i-1][0]/2;
+		ecdsa_c[i][1]=ecdsa_c[i-1][1]/2;
+		if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0))
+			ecdsa_doit[i]=0;
+		else
+			{
+			if (ecdsa_c[i] == 0)
+				{
+				ecdsa_c[i][0]=1;
+				ecdsa_c[i][1]=1;
+				}
+			}
+		}
+	ecdsa_c[R_EC_B163][0]=count/1000;
+	ecdsa_c[R_EC_B163][1]=count/1000/2;
+	for (i=R_EC_B233; i<=R_EC_B571; i++)
+		{
+		ecdsa_c[i][0]=ecdsa_c[i-1][0]/2;
+		ecdsa_c[i][1]=ecdsa_c[i-1][1]/2;
+		if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0))
+			ecdsa_doit[i]=0;
+		else
+			{
+			if (ecdsa_c[i] == 0)
+				{
+				ecdsa_c[i][0]=1;
+				ecdsa_c[i][1]=1;
+				}
+			}
+		}
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+	ecdh_c[R_EC_P160][0]=count/1000;
+	ecdh_c[R_EC_P160][1]=count/1000;
+	for (i=R_EC_P192; i<=R_EC_P521; i++)
+		{
+		ecdh_c[i][0]=ecdh_c[i-1][0]/2;
+		ecdh_c[i][1]=ecdh_c[i-1][1]/2;
+		if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0))
+			ecdh_doit[i]=0;
+		else
+			{
+			if (ecdh_c[i] == 0)
+				{
+				ecdh_c[i][0]=1;
+				ecdh_c[i][1]=1;
+				}
+			}
+		}
+	ecdh_c[R_EC_K163][0]=count/1000;
+	ecdh_c[R_EC_K163][1]=count/1000;
+	for (i=R_EC_K233; i<=R_EC_K571; i++)
+		{
+		ecdh_c[i][0]=ecdh_c[i-1][0]/2;
+		ecdh_c[i][1]=ecdh_c[i-1][1]/2;
+		if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0))
+			ecdh_doit[i]=0;
+		else
+			{
+			if (ecdh_c[i] == 0)
+				{
+				ecdh_c[i][0]=1;
+				ecdh_c[i][1]=1;
+				}
+			}
+		}
+	ecdh_c[R_EC_B163][0]=count/1000;
+	ecdh_c[R_EC_B163][1]=count/1000;
+	for (i=R_EC_B233; i<=R_EC_B571; i++)
+		{
+		ecdh_c[i][0]=ecdh_c[i-1][0]/2;
+		ecdh_c[i][1]=ecdh_c[i-1][1]/2;
+		if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0))
+			ecdh_doit[i]=0;
+		else
+			{
+			if (ecdh_c[i] == 0)
+				{
+				ecdh_c[i][0]=1;
+				ecdh_c[i][1]=1;
+				}
+			}
+		}
+#endif
+
+#define COND(d)	(count < (d))
+#define COUNT(d) (d)
+#else
+/* not worth fixing */
+# error "You cannot disable DES on systems without SIGALRM."
+#endif /* OPENSSL_NO_DES */
+#else
+#define COND(c)	(run)
+#define COUNT(d) (count)
+#ifndef _WIN32
+	signal(SIGALRM,sig_done);
+#endif
+#endif /* SIGALRM */
+
+#ifndef OPENSSL_NO_MD2
+	if (doit[D_MD2])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_MD2],c[D_MD2][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_MD2][j]); count++)
+				EVP_Digest(buf,(unsigned long)lengths[j],&(md2[0]),NULL,EVP_md2(),NULL);
+			d=Time_F(STOP);
+			print_result(D_MD2,j,count,d);
+			}
+		}
+#endif
+#ifndef OPENSSL_NO_MDC2
+	if (doit[D_MDC2])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_MDC2],c[D_MDC2][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_MDC2][j]); count++)
+				EVP_Digest(buf,(unsigned long)lengths[j],&(mdc2[0]),NULL,EVP_mdc2(),NULL);
+			d=Time_F(STOP);
+			print_result(D_MDC2,j,count,d);
+			}
+		}
+#endif
+
+#ifndef OPENSSL_NO_MD4
+	if (doit[D_MD4])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_MD4],c[D_MD4][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_MD4][j]); count++)
+				EVP_Digest(&(buf[0]),(unsigned long)lengths[j],&(md4[0]),NULL,EVP_md4(),NULL);
+			d=Time_F(STOP);
+			print_result(D_MD4,j,count,d);
+			}
+		}
+#endif
+
+#ifndef OPENSSL_NO_MD5
+	if (doit[D_MD5])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_MD5],c[D_MD5][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_MD5][j]); count++)
+				EVP_Digest(&(buf[0]),(unsigned long)lengths[j],&(md5[0]),NULL,EVP_get_digestbyname("md5"),NULL);
+			d=Time_F(STOP);
+			print_result(D_MD5,j,count,d);
+			}
+		}
+#endif
+
+#if !defined(OPENSSL_NO_MD5) && !defined(OPENSSL_NO_HMAC)
+	if (doit[D_HMAC])
+		{
+		HMAC_CTX hctx;
+
+		HMAC_CTX_init(&hctx);
+		HMAC_Init_ex(&hctx,(unsigned char *)"This is a key...",
+			16,EVP_md5(), NULL);
+
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_HMAC],c[D_HMAC][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_HMAC][j]); count++)
+				{
+				HMAC_Init_ex(&hctx,NULL,0,NULL,NULL);
+				HMAC_Update(&hctx,buf,lengths[j]);
+				HMAC_Final(&hctx,&(hmac[0]),NULL);
+				}
+			d=Time_F(STOP);
+			print_result(D_HMAC,j,count,d);
+			}
+		HMAC_CTX_cleanup(&hctx);
+		}
+#endif
+#ifndef OPENSSL_NO_SHA
+	if (doit[D_SHA1])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_SHA1],c[D_SHA1][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_SHA1][j]); count++)
+				EVP_Digest(buf,(unsigned long)lengths[j],&(sha[0]),NULL,EVP_sha1(),NULL);
+			d=Time_F(STOP);
+			print_result(D_SHA1,j,count,d);
+			}
+		}
+
+#ifndef OPENSSL_NO_SHA256
+	if (doit[D_SHA256])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_SHA256],c[D_SHA256][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_SHA256][j]); count++)
+				SHA256(buf,lengths[j],sha256);
+			d=Time_F(STOP);
+			print_result(D_SHA256,j,count,d);
+			}
+		}
+#endif
+
+#ifndef OPENSSL_NO_SHA512
+	if (doit[D_SHA512])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_SHA512],c[D_SHA512][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_SHA512][j]); count++)
+				SHA512(buf,lengths[j],sha512);
+			d=Time_F(STOP);
+			print_result(D_SHA512,j,count,d);
+			}
+		}
+#endif
+#endif
+
+#ifndef OPENSSL_NO_WHIRLPOOL
+	if (doit[D_WHIRLPOOL])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_WHIRLPOOL],c[D_WHIRLPOOL][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_WHIRLPOOL][j]); count++)
+				WHIRLPOOL(buf,lengths[j],whirlpool);
+			d=Time_F(STOP);
+			print_result(D_WHIRLPOOL,j,count,d);
+			}
+		}
+#endif
+
+#ifndef OPENSSL_NO_RIPEMD
+	if (doit[D_RMD160])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_RMD160],c[D_RMD160][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_RMD160][j]); count++)
+				EVP_Digest(buf,(unsigned long)lengths[j],&(rmd160[0]),NULL,EVP_ripemd160(),NULL);
+			d=Time_F(STOP);
+			print_result(D_RMD160,j,count,d);
+			}
+		}
+#endif
+#ifndef OPENSSL_NO_RC4
+	if (doit[D_RC4])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_RC4],c[D_RC4][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_RC4][j]); count++)
+				RC4(&rc4_ks,(unsigned int)lengths[j],
+					buf,buf);
+			d=Time_F(STOP);
+			print_result(D_RC4,j,count,d);
+			}
+		}
+#endif
+#ifndef OPENSSL_NO_DES
+	if (doit[D_CBC_DES])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_CBC_DES],c[D_CBC_DES][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_CBC_DES][j]); count++)
+				DES_ncbc_encrypt(buf,buf,lengths[j],&sch,
+						 &DES_iv,DES_ENCRYPT);
+			d=Time_F(STOP);
+			print_result(D_CBC_DES,j,count,d);
+			}
+		}
+
+	if (doit[D_EDE3_DES])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_EDE3_DES],c[D_EDE3_DES][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_EDE3_DES][j]); count++)
+				DES_ede3_cbc_encrypt(buf,buf,lengths[j],
+						     &sch,&sch2,&sch3,
+						     &DES_iv,DES_ENCRYPT);
+			d=Time_F(STOP);
+			print_result(D_EDE3_DES,j,count,d);
+			}
+		}
+#endif
+#ifndef OPENSSL_NO_AES
+	if (doit[D_CBC_128_AES])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_CBC_128_AES],c[D_CBC_128_AES][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_CBC_128_AES][j]); count++)
+				AES_cbc_encrypt(buf,buf,
+					(unsigned long)lengths[j],&aes_ks1,
+					iv,AES_ENCRYPT);
+			d=Time_F(STOP);
+			print_result(D_CBC_128_AES,j,count,d);
+			}
+		}
+	if (doit[D_CBC_192_AES])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_CBC_192_AES],c[D_CBC_192_AES][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_CBC_192_AES][j]); count++)
+				AES_cbc_encrypt(buf,buf,
+					(unsigned long)lengths[j],&aes_ks2,
+					iv,AES_ENCRYPT);
+			d=Time_F(STOP);
+			print_result(D_CBC_192_AES,j,count,d);
+			}
+		}
+	if (doit[D_CBC_256_AES])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_CBC_256_AES],c[D_CBC_256_AES][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_CBC_256_AES][j]); count++)
+				AES_cbc_encrypt(buf,buf,
+					(unsigned long)lengths[j],&aes_ks3,
+					iv,AES_ENCRYPT);
+			d=Time_F(STOP);
+			print_result(D_CBC_256_AES,j,count,d);
+			}
+		}
+
+#if 0 /* ANDROID */
+	if (doit[D_IGE_128_AES])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_IGE_128_AES],c[D_IGE_128_AES][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_IGE_128_AES][j]); count++)
+				AES_ige_encrypt(buf,buf2,
+					(unsigned long)lengths[j],&aes_ks1,
+					iv,AES_ENCRYPT);
+			d=Time_F(STOP);
+			print_result(D_IGE_128_AES,j,count,d);
+			}
+		}
+	if (doit[D_IGE_192_AES])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_IGE_192_AES],c[D_IGE_192_AES][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_IGE_192_AES][j]); count++)
+				AES_ige_encrypt(buf,buf2,
+					(unsigned long)lengths[j],&aes_ks2,
+					iv,AES_ENCRYPT);
+			d=Time_F(STOP);
+			print_result(D_IGE_192_AES,j,count,d);
+			}
+		}
+	if (doit[D_IGE_256_AES])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_IGE_256_AES],c[D_IGE_256_AES][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_IGE_256_AES][j]); count++)
+				AES_ige_encrypt(buf,buf2,
+					(unsigned long)lengths[j],&aes_ks3,
+					iv,AES_ENCRYPT);
+			d=Time_F(STOP);
+			print_result(D_IGE_256_AES,j,count,d);
+			}
+		}
+
+
+#endif
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+	if (doit[D_CBC_128_CML])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_CBC_128_CML],c[D_CBC_128_CML][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_CBC_128_CML][j]); count++)
+				Camellia_cbc_encrypt(buf,buf,
+				        (unsigned long)lengths[j],&camellia_ks1,
+				        iv,CAMELLIA_ENCRYPT);
+			d=Time_F(STOP);
+			print_result(D_CBC_128_CML,j,count,d);
+			}
+		}
+	if (doit[D_CBC_192_CML])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_CBC_192_CML],c[D_CBC_192_CML][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_CBC_192_CML][j]); count++)
+				Camellia_cbc_encrypt(buf,buf,
+				        (unsigned long)lengths[j],&camellia_ks2,
+				        iv,CAMELLIA_ENCRYPT);
+			d=Time_F(STOP);
+			print_result(D_CBC_192_CML,j,count,d);
+			}
+		}
+	if (doit[D_CBC_256_CML])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_CBC_256_CML],c[D_CBC_256_CML][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_CBC_256_CML][j]); count++)
+				Camellia_cbc_encrypt(buf,buf,
+				        (unsigned long)lengths[j],&camellia_ks3,
+				        iv,CAMELLIA_ENCRYPT);
+			d=Time_F(STOP);
+			print_result(D_CBC_256_CML,j,count,d);
+			}
+		}
+
+#endif
+#ifndef OPENSSL_NO_IDEA
+	if (doit[D_CBC_IDEA])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_CBC_IDEA],c[D_CBC_IDEA][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_CBC_IDEA][j]); count++)
+				idea_cbc_encrypt(buf,buf,
+					(unsigned long)lengths[j],&idea_ks,
+					iv,IDEA_ENCRYPT);
+			d=Time_F(STOP);
+			print_result(D_CBC_IDEA,j,count,d);
+			}
+		}
+#endif
+#ifndef OPENSSL_NO_SEED
+	if (doit[D_CBC_SEED])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_CBC_SEED],c[D_CBC_SEED][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_CBC_SEED][j]); count++)
+				SEED_cbc_encrypt(buf,buf,
+					(unsigned long)lengths[j],&seed_ks,iv,1);
+			d=Time_F(STOP);
+			print_result(D_CBC_SEED,j,count,d);
+			}
+		}
+#endif
+#ifndef OPENSSL_NO_RC2
+	if (doit[D_CBC_RC2])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_CBC_RC2],c[D_CBC_RC2][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_CBC_RC2][j]); count++)
+				RC2_cbc_encrypt(buf,buf,
+					(unsigned long)lengths[j],&rc2_ks,
+					iv,RC2_ENCRYPT);
+			d=Time_F(STOP);
+			print_result(D_CBC_RC2,j,count,d);
+			}
+		}
+#endif
+#ifndef OPENSSL_NO_RC5
+	if (doit[D_CBC_RC5])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_CBC_RC5],c[D_CBC_RC5][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_CBC_RC5][j]); count++)
+				RC5_32_cbc_encrypt(buf,buf,
+					(unsigned long)lengths[j],&rc5_ks,
+					iv,RC5_ENCRYPT);
+			d=Time_F(STOP);
+			print_result(D_CBC_RC5,j,count,d);
+			}
+		}
+#endif
+#ifndef OPENSSL_NO_BF
+	if (doit[D_CBC_BF])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_CBC_BF],c[D_CBC_BF][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_CBC_BF][j]); count++)
+				BF_cbc_encrypt(buf,buf,
+					(unsigned long)lengths[j],&bf_ks,
+					iv,BF_ENCRYPT);
+			d=Time_F(STOP);
+			print_result(D_CBC_BF,j,count,d);
+			}
+		}
+#endif
+#ifndef OPENSSL_NO_CAST
+	if (doit[D_CBC_CAST])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_CBC_CAST],c[D_CBC_CAST][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_CBC_CAST][j]); count++)
+				CAST_cbc_encrypt(buf,buf,
+					(unsigned long)lengths[j],&cast_ks,
+					iv,CAST_ENCRYPT);
+			d=Time_F(STOP);
+			print_result(D_CBC_CAST,j,count,d);
+			}
+		}
+#endif
+
+	if (doit[D_EVP])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			if (evp_cipher)
+				{
+				EVP_CIPHER_CTX ctx;
+				int outl;
+
+				names[D_EVP]=OBJ_nid2ln(evp_cipher->nid);
+				/* -O3 -fschedule-insns messes up an
+				 * optimization here!  names[D_EVP]
+				 * somehow becomes NULL */
+				print_message(names[D_EVP],save_count,
+					lengths[j]);
+
+				EVP_CIPHER_CTX_init(&ctx);
+				if(decrypt)
+					EVP_DecryptInit_ex(&ctx,evp_cipher,NULL,key16,iv);
+				else
+					EVP_EncryptInit_ex(&ctx,evp_cipher,NULL,key16,iv);
+				EVP_CIPHER_CTX_set_padding(&ctx, 0);
+
+				Time_F(START);
+				if(decrypt)
+					for (count=0,run=1; COND(save_count*4*lengths[0]/lengths[j]); count++)
+						EVP_DecryptUpdate(&ctx,buf,&outl,buf,lengths[j]);
+				else
+					for (count=0,run=1; COND(save_count*4*lengths[0]/lengths[j]); count++)
+						EVP_EncryptUpdate(&ctx,buf,&outl,buf,lengths[j]);
+				if(decrypt)
+					EVP_DecryptFinal_ex(&ctx,buf,&outl);
+				else
+					EVP_EncryptFinal_ex(&ctx,buf,&outl);
+				d=Time_F(STOP);
+				EVP_CIPHER_CTX_cleanup(&ctx);
+				}
+			if (evp_md)
+				{
+				names[D_EVP]=OBJ_nid2ln(evp_md->type);
+				print_message(names[D_EVP],save_count,
+					lengths[j]);
+
+				Time_F(START);
+				for (count=0,run=1; COND(save_count*4*lengths[0]/lengths[j]); count++)
+					EVP_Digest(buf,lengths[j],&(md[0]),NULL,evp_md,NULL);
+
+				d=Time_F(STOP);
+				}
+			print_result(D_EVP,j,count,d);
+			}
+		}
+
+	RAND_pseudo_bytes(buf,36);
+#ifndef OPENSSL_NO_RSA
+	for (j=0; j<RSA_NUM; j++)
+		{
+		int ret;
+		if (!rsa_doit[j]) continue;
+		ret=RSA_sign(NID_md5_sha1, buf,36, buf2, &rsa_num, rsa_key[j]);
+		if (ret == 0)
+			{
+			BIO_printf(bio_err,"RSA sign failure.  No RSA sign will be done.\n");
+			ERR_print_errors(bio_err);
+			rsa_count=1;
+			}
+		else
+			{
+			pkey_print_message("private","rsa",
+				rsa_c[j][0],rsa_bits[j],
+				RSA_SECONDS);
+/*			RSA_blinding_on(rsa_key[j],NULL); */
+			Time_F(START);
+			for (count=0,run=1; COND(rsa_c[j][0]); count++)
+				{
+				ret=RSA_sign(NID_md5_sha1, buf,36, buf2,
+					&rsa_num, rsa_key[j]);
+				if (ret == 0)
+					{
+					BIO_printf(bio_err,
+						"RSA sign failure\n");
+					ERR_print_errors(bio_err);
+					count=1;
+					break;
+					}
+				}
+			d=Time_F(STOP);
+			BIO_printf(bio_err,mr ? "+R1:%ld:%d:%.2f\n"
+				   : "%ld %d bit private RSA's in %.2fs\n",
+				   count,rsa_bits[j],d);
+			rsa_results[j][0]=d/(double)count;
+			rsa_count=count;
+			}
+
+#if 1
+		ret=RSA_verify(NID_md5_sha1, buf,36, buf2, rsa_num, rsa_key[j]);
+		if (ret <= 0)
+			{
+			BIO_printf(bio_err,"RSA verify failure.  No RSA verify will be done.\n");
+			ERR_print_errors(bio_err);
+			rsa_doit[j] = 0;
+			}
+		else
+			{
+			pkey_print_message("public","rsa",
+				rsa_c[j][1],rsa_bits[j],
+				RSA_SECONDS);
+			Time_F(START);
+			for (count=0,run=1; COND(rsa_c[j][1]); count++)
+				{
+				ret=RSA_verify(NID_md5_sha1, buf,36, buf2,
+					rsa_num, rsa_key[j]);
+				if (ret <= 0)
+					{
+					BIO_printf(bio_err,
+						"RSA verify failure\n");
+					ERR_print_errors(bio_err);
+					count=1;
+					break;
+					}
+				}
+			d=Time_F(STOP);
+			BIO_printf(bio_err,mr ? "+R2:%ld:%d:%.2f\n"
+				   : "%ld %d bit public RSA's in %.2fs\n",
+				   count,rsa_bits[j],d);
+			rsa_results[j][1]=d/(double)count;
+			}
+#endif
+
+		if (rsa_count <= 1)
+			{
+			/* if longer than 10s, don't do any more */
+			for (j++; j<RSA_NUM; j++)
+				rsa_doit[j]=0;
+			}
+		}
+#endif
+
+	RAND_pseudo_bytes(buf,20);
+#ifndef OPENSSL_NO_DSA
+	if (RAND_status() != 1)
+		{
+		RAND_seed(rnd_seed, sizeof rnd_seed);
+		rnd_fake = 1;
+		}
+	for (j=0; j<DSA_NUM; j++)
+		{
+		unsigned int kk;
+		int ret;
+
+		if (!dsa_doit[j]) continue;
+/*		DSA_generate_key(dsa_key[j]); */
+/*		DSA_sign_setup(dsa_key[j],NULL); */
+		ret=DSA_sign(EVP_PKEY_DSA,buf,20,buf2,
+			&kk,dsa_key[j]);
+		if (ret == 0)
+			{
+			BIO_printf(bio_err,"DSA sign failure.  No DSA sign will be done.\n");
+			ERR_print_errors(bio_err);
+			rsa_count=1;
+			}
+		else
+			{
+			pkey_print_message("sign","dsa",
+				dsa_c[j][0],dsa_bits[j],
+				DSA_SECONDS);
+			Time_F(START);
+			for (count=0,run=1; COND(dsa_c[j][0]); count++)
+				{
+				ret=DSA_sign(EVP_PKEY_DSA,buf,20,buf2,
+					&kk,dsa_key[j]);
+				if (ret == 0)
+					{
+					BIO_printf(bio_err,
+						"DSA sign failure\n");
+					ERR_print_errors(bio_err);
+					count=1;
+					break;
+					}
+				}
+			d=Time_F(STOP);
+			BIO_printf(bio_err,mr ? "+R3:%ld:%d:%.2f\n"
+				   : "%ld %d bit DSA signs in %.2fs\n",
+				   count,dsa_bits[j],d);
+			dsa_results[j][0]=d/(double)count;
+			rsa_count=count;
+			}
+
+		ret=DSA_verify(EVP_PKEY_DSA,buf,20,buf2,
+			kk,dsa_key[j]);
+		if (ret <= 0)
+			{
+			BIO_printf(bio_err,"DSA verify failure.  No DSA verify will be done.\n");
+			ERR_print_errors(bio_err);
+			dsa_doit[j] = 0;
+			}
+		else
+			{
+			pkey_print_message("verify","dsa",
+				dsa_c[j][1],dsa_bits[j],
+				DSA_SECONDS);
+			Time_F(START);
+			for (count=0,run=1; COND(dsa_c[j][1]); count++)
+				{
+				ret=DSA_verify(EVP_PKEY_DSA,buf,20,buf2,
+					kk,dsa_key[j]);
+				if (ret <= 0)
+					{
+					BIO_printf(bio_err,
+						"DSA verify failure\n");
+					ERR_print_errors(bio_err);
+					count=1;
+					break;
+					}
+				}
+			d=Time_F(STOP);
+			BIO_printf(bio_err,mr ? "+R4:%ld:%d:%.2f\n"
+				   : "%ld %d bit DSA verify in %.2fs\n",
+				   count,dsa_bits[j],d);
+			dsa_results[j][1]=d/(double)count;
+			}
+
+		if (rsa_count <= 1)
+			{
+			/* if longer than 10s, don't do any more */
+			for (j++; j<DSA_NUM; j++)
+				dsa_doit[j]=0;
+			}
+		}
+	if (rnd_fake) RAND_cleanup();
+#endif
+
+#ifndef OPENSSL_NO_ECDSA
+	if (RAND_status() != 1) 
+		{
+		RAND_seed(rnd_seed, sizeof rnd_seed);
+		rnd_fake = 1;
+		}
+	for (j=0; j<EC_NUM; j++) 
+		{
+		int ret;
+
+		if (!ecdsa_doit[j]) continue; /* Ignore Curve */ 
+		ecdsa[j] = EC_KEY_new_by_curve_name(test_curves[j]);
+		if (ecdsa[j] == NULL) 
+			{
+			BIO_printf(bio_err,"ECDSA failure.\n");
+			ERR_print_errors(bio_err);
+			rsa_count=1;
+			} 
+		else 
+			{
+#if 1
+			EC_KEY_precompute_mult(ecdsa[j], NULL);
+#endif
+			/* Perform ECDSA signature test */
+			EC_KEY_generate_key(ecdsa[j]);
+			ret = ECDSA_sign(0, buf, 20, ecdsasig, 
+				&ecdsasiglen, ecdsa[j]);
+			if (ret == 0) 
+				{
+				BIO_printf(bio_err,"ECDSA sign failure.  No ECDSA sign will be done.\n");
+				ERR_print_errors(bio_err);
+				rsa_count=1;
+				} 
+			else 
+				{
+				pkey_print_message("sign","ecdsa",
+					ecdsa_c[j][0], 
+					test_curves_bits[j],
+					ECDSA_SECONDS);
+
+				Time_F(START);
+				for (count=0,run=1; COND(ecdsa_c[j][0]);
+					count++) 
+					{
+					ret=ECDSA_sign(0, buf, 20, 
+						ecdsasig, &ecdsasiglen,
+						ecdsa[j]);
+					if (ret == 0) 
+						{
+						BIO_printf(bio_err, "ECDSA sign failure\n");
+						ERR_print_errors(bio_err);
+						count=1;
+						break;
+						}
+					}
+				d=Time_F(STOP);
+
+				BIO_printf(bio_err, mr ? "+R5:%ld:%d:%.2f\n" :
+					"%ld %d bit ECDSA signs in %.2fs \n", 
+					count, test_curves_bits[j], d);
+				ecdsa_results[j][0]=d/(double)count;
+				rsa_count=count;
+				}
+
+			/* Perform ECDSA verification test */
+			ret=ECDSA_verify(0, buf, 20, ecdsasig, 
+				ecdsasiglen, ecdsa[j]);
+			if (ret != 1) 
+				{
+				BIO_printf(bio_err,"ECDSA verify failure.  No ECDSA verify will be done.\n");
+				ERR_print_errors(bio_err);
+				ecdsa_doit[j] = 0;
+				} 
+			else 
+				{
+				pkey_print_message("verify","ecdsa",
+				ecdsa_c[j][1],
+				test_curves_bits[j],
+				ECDSA_SECONDS);
+				Time_F(START);
+				for (count=0,run=1; COND(ecdsa_c[j][1]); count++) 
+					{
+					ret=ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen, ecdsa[j]);
+					if (ret != 1) 
+						{
+						BIO_printf(bio_err, "ECDSA verify failure\n");
+						ERR_print_errors(bio_err);
+						count=1;
+						break;
+						}
+					}
+				d=Time_F(STOP);
+				BIO_printf(bio_err, mr? "+R6:%ld:%d:%.2f\n"
+						: "%ld %d bit ECDSA verify in %.2fs\n",
+				count, test_curves_bits[j], d);
+				ecdsa_results[j][1]=d/(double)count;
+				}
+
+			if (rsa_count <= 1) 
+				{
+				/* if longer than 10s, don't do any more */
+				for (j++; j<EC_NUM; j++)
+				ecdsa_doit[j]=0;
+				}
+			}
+		}
+	if (rnd_fake) RAND_cleanup();
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+	if (RAND_status() != 1)
+		{
+		RAND_seed(rnd_seed, sizeof rnd_seed);
+		rnd_fake = 1;
+		}
+	for (j=0; j<EC_NUM; j++)
+		{
+		if (!ecdh_doit[j]) continue;
+		ecdh_a[j] = EC_KEY_new_by_curve_name(test_curves[j]);
+		ecdh_b[j] = EC_KEY_new_by_curve_name(test_curves[j]);
+		if ((ecdh_a[j] == NULL) || (ecdh_b[j] == NULL))
+			{
+			BIO_printf(bio_err,"ECDH failure.\n");
+			ERR_print_errors(bio_err);
+			rsa_count=1;
+			}
+		else
+			{
+			/* generate two ECDH key pairs */
+			if (!EC_KEY_generate_key(ecdh_a[j]) ||
+				!EC_KEY_generate_key(ecdh_b[j]))
+				{
+				BIO_printf(bio_err,"ECDH key generation failure.\n");
+				ERR_print_errors(bio_err);
+				rsa_count=1;		
+				}
+			else
+				{
+				/* If field size is not more than 24 octets, then use SHA-1 hash of result;
+				 * otherwise, use result (see section 4.8 of draft-ietf-tls-ecc-03.txt).
+				 */
+				int field_size, outlen;
+				void *(*kdf)(const void *in, size_t inlen, void *out, size_t *xoutlen);
+				field_size = EC_GROUP_get_degree(EC_KEY_get0_group(ecdh_a[j]));
+				if (field_size <= 24 * 8)
+					{
+					outlen = KDF1_SHA1_len;
+					kdf = KDF1_SHA1;
+					}
+				else
+					{
+					outlen = (field_size+7)/8;
+					kdf = NULL;
+					}
+				secret_size_a = ECDH_compute_key(secret_a, outlen,
+					EC_KEY_get0_public_key(ecdh_b[j]),
+					ecdh_a[j], kdf);
+				secret_size_b = ECDH_compute_key(secret_b, outlen,
+					EC_KEY_get0_public_key(ecdh_a[j]),
+					ecdh_b[j], kdf);
+				if (secret_size_a != secret_size_b) 
+					ecdh_checks = 0;
+				else
+					ecdh_checks = 1;
+
+				for (secret_idx = 0; 
+				    (secret_idx < secret_size_a)
+					&& (ecdh_checks == 1);
+				    secret_idx++)
+					{
+					if (secret_a[secret_idx] != secret_b[secret_idx])
+					ecdh_checks = 0;
+					}
+
+				if (ecdh_checks == 0)
+					{
+					BIO_printf(bio_err,"ECDH computations don't match.\n");
+					ERR_print_errors(bio_err);
+					rsa_count=1;		
+					}
+
+				pkey_print_message("","ecdh",
+				ecdh_c[j][0], 
+				test_curves_bits[j],
+				ECDH_SECONDS);
+				Time_F(START);
+				for (count=0,run=1; COND(ecdh_c[j][0]); count++)
+					{
+					ECDH_compute_key(secret_a, outlen,
+					EC_KEY_get0_public_key(ecdh_b[j]),
+					ecdh_a[j], kdf);
+					}
+				d=Time_F(STOP);
+				BIO_printf(bio_err, mr ? "+R7:%ld:%d:%.2f\n" :"%ld %d-bit ECDH ops in %.2fs\n",
+				count, test_curves_bits[j], d);
+				ecdh_results[j][0]=d/(double)count;
+				rsa_count=count;
+				}
+			}
+
+
+		if (rsa_count <= 1)
+			{
+			/* if longer than 10s, don't do any more */
+			for (j++; j<EC_NUM; j++)
+			ecdh_doit[j]=0;
+			}
+		}
+	if (rnd_fake) RAND_cleanup();
+#endif
+#ifndef NO_FORK
+show_res:
+#endif
+	if(!mr)
+		{
+		fprintf(stdout,"%s\n",SSLeay_version(SSLEAY_VERSION));
+        fprintf(stdout,"%s\n",SSLeay_version(SSLEAY_BUILT_ON));
+		printf("options:");
+		printf("%s ",BN_options());
+#ifndef OPENSSL_NO_MD2
+		printf("%s ",MD2_options());
+#endif
+#ifndef OPENSSL_NO_RC4
+		printf("%s ",RC4_options());
+#endif
+#ifndef OPENSSL_NO_DES
+		printf("%s ",DES_options());
+#endif
+#ifndef OPENSSL_NO_AES
+		printf("%s ",AES_options());
+#endif
+#ifndef OPENSSL_NO_IDEA
+		printf("%s ",idea_options());
+#endif
+#ifndef OPENSSL_NO_BF
+		printf("%s ",BF_options());
+#endif
+		fprintf(stdout,"\n%s\n",SSLeay_version(SSLEAY_CFLAGS));
+		}
+
+	if (pr_header)
+		{
+		if(mr)
+			fprintf(stdout,"+H");
+		else
+			{
+			fprintf(stdout,"The 'numbers' are in 1000s of bytes per second processed.\n"); 
+			fprintf(stdout,"type        ");
+			}
+		for (j=0;  j<SIZE_NUM; j++)
+			fprintf(stdout,mr ? ":%d" : "%7d bytes",lengths[j]);
+		fprintf(stdout,"\n");
+		}
+
+	for (k=0; k<ALGOR_NUM; k++)
+		{
+		if (!doit[k]) continue;
+		if(mr)
+			fprintf(stdout,"+F:%d:%s",k,names[k]);
+		else
+			fprintf(stdout,"%-13s",names[k]);
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			if (results[k][j] > 10000 && !mr)
+				fprintf(stdout," %11.2fk",results[k][j]/1e3);
+			else
+				fprintf(stdout,mr ? ":%.2f" : " %11.2f ",results[k][j]);
+			}
+		fprintf(stdout,"\n");
+		}
+#ifndef OPENSSL_NO_RSA
+	j=1;
+	for (k=0; k<RSA_NUM; k++)
+		{
+		if (!rsa_doit[k]) continue;
+		if (j && !mr)
+			{
+			printf("%18ssign    verify    sign/s verify/s\n"," ");
+			j=0;
+			}
+		if(mr)
+			fprintf(stdout,"+F2:%u:%u:%f:%f\n",
+				k,rsa_bits[k],rsa_results[k][0],
+				rsa_results[k][1]);
+		else
+			fprintf(stdout,"rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
+				rsa_bits[k],rsa_results[k][0],rsa_results[k][1],
+				1.0/rsa_results[k][0],1.0/rsa_results[k][1]);
+		}
+#endif
+#ifndef OPENSSL_NO_DSA
+	j=1;
+	for (k=0; k<DSA_NUM; k++)
+		{
+		if (!dsa_doit[k]) continue;
+		if (j && !mr)
+			{
+			printf("%18ssign    verify    sign/s verify/s\n"," ");
+			j=0;
+			}
+		if(mr)
+			fprintf(stdout,"+F3:%u:%u:%f:%f\n",
+				k,dsa_bits[k],dsa_results[k][0],dsa_results[k][1]);
+		else
+			fprintf(stdout,"dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
+				dsa_bits[k],dsa_results[k][0],dsa_results[k][1],
+				1.0/dsa_results[k][0],1.0/dsa_results[k][1]);
+		}
+#endif
+#ifndef OPENSSL_NO_ECDSA
+	j=1;
+	for (k=0; k<EC_NUM; k++)
+		{
+		if (!ecdsa_doit[k]) continue;
+		if (j && !mr)
+			{
+			printf("%30ssign    verify    sign/s verify/s\n"," ");
+			j=0;
+			}
+
+		if (mr)
+			fprintf(stdout,"+F4:%u:%u:%f:%f\n", 
+				k, test_curves_bits[k],
+				ecdsa_results[k][0],ecdsa_results[k][1]);
+		else
+			fprintf(stdout,
+				"%4u bit ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n", 
+				test_curves_bits[k],
+				test_curves_names[k],
+				ecdsa_results[k][0],ecdsa_results[k][1], 
+				1.0/ecdsa_results[k][0],1.0/ecdsa_results[k][1]);
+		}
+#endif
+
+
+#ifndef OPENSSL_NO_ECDH
+	j=1;
+	for (k=0; k<EC_NUM; k++)
+		{
+		if (!ecdh_doit[k]) continue;
+		if (j && !mr)
+			{
+			printf("%30sop      op/s\n"," ");
+			j=0;
+			}
+		if (mr)
+			fprintf(stdout,"+F5:%u:%u:%f:%f\n",
+				k, test_curves_bits[k],
+				ecdh_results[k][0], 1.0/ecdh_results[k][0]);
+
+		else
+			fprintf(stdout,"%4u bit ecdh (%s) %8.4fs %8.1f\n",
+				test_curves_bits[k],
+				test_curves_names[k],
+				ecdh_results[k][0], 1.0/ecdh_results[k][0]);
+		}
+#endif
+
+	mret=0;
+
+end:
+	ERR_print_errors(bio_err);
+	if (buf != NULL) OPENSSL_free(buf);
+	if (buf2 != NULL) OPENSSL_free(buf2);
+#ifndef OPENSSL_NO_RSA
+	for (i=0; i<RSA_NUM; i++)
+		if (rsa_key[i] != NULL)
+			RSA_free(rsa_key[i]);
+#endif
+#ifndef OPENSSL_NO_DSA
+	for (i=0; i<DSA_NUM; i++)
+		if (dsa_key[i] != NULL)
+			DSA_free(dsa_key[i]);
+#endif
+
+#ifndef OPENSSL_NO_ECDSA
+	for (i=0; i<EC_NUM; i++)
+		if (ecdsa[i] != NULL)
+			EC_KEY_free(ecdsa[i]);
+#endif
+#ifndef OPENSSL_NO_ECDH
+	for (i=0; i<EC_NUM; i++)
+	{
+		if (ecdh_a[i] != NULL)
+			EC_KEY_free(ecdh_a[i]);
+		if (ecdh_b[i] != NULL)
+			EC_KEY_free(ecdh_b[i]);
+	}
+#endif
+
+	apps_shutdown();
+	OPENSSL_EXIT(mret);
+	}
+
+static void print_message(const char *s, long num, int length)
+	{
+#ifdef SIGALRM
+	BIO_printf(bio_err,mr ? "+DT:%s:%d:%d\n"
+		   : "Doing %s for %ds on %d size blocks: ",s,SECONDS,length);
+	(void)BIO_flush(bio_err);
+	alarm(SECONDS);
+#else
+	BIO_printf(bio_err,mr ? "+DN:%s:%ld:%d\n"
+		   : "Doing %s %ld times on %d size blocks: ",s,num,length);
+	(void)BIO_flush(bio_err);
+#endif
+#ifdef LINT
+	num=num;
+#endif
+	}
+
+static void pkey_print_message(const char *str, const char *str2, long num,
+	int bits, int tm)
+	{
+#ifdef SIGALRM
+	BIO_printf(bio_err,mr ? "+DTP:%d:%s:%s:%d\n"
+			   : "Doing %d bit %s %s's for %ds: ",bits,str,str2,tm);
+	(void)BIO_flush(bio_err);
+	alarm(RSA_SECONDS);
+#else
+	BIO_printf(bio_err,mr ? "+DNP:%ld:%d:%s:%s\n"
+			   : "Doing %ld %d bit %s %s's: ",num,bits,str,str2);
+	(void)BIO_flush(bio_err);
+#endif
+#ifdef LINT
+	num=num;
+#endif
+	}
+
+static void print_result(int alg,int run_no,int count,double time_used)
+	{
+	BIO_printf(bio_err,mr ? "+R:%d:%s:%f\n"
+		   : "%d %s's in %.2fs\n",count,names[alg],time_used);
+	results[alg][run_no]=((double)count)/time_used*lengths[run_no];
+	}
+
+#ifndef NO_FORK
+static char *sstrsep(char **string, const char *delim)
+    {
+    char isdelim[256];
+    char *token = *string;
+
+    if (**string == 0)
+        return NULL;
+
+    memset(isdelim, 0, sizeof isdelim);
+    isdelim[0] = 1;
+
+    while (*delim)
+        {
+        isdelim[(unsigned char)(*delim)] = 1;
+        delim++;
+        }
+
+    while (!isdelim[(unsigned char)(**string)])
+        {
+        (*string)++;
+        }
+
+    if (**string)
+        {
+        **string = 0;
+        (*string)++;
+        }
+
+    return token;
+    }
+
+static int do_multi(int multi)
+	{
+	int n;
+	int fd[2];
+	int *fds;
+	static char sep[]=":";
+
+	fds=malloc(multi*sizeof *fds);
+	for(n=0 ; n < multi ; ++n)
+		{
+		pipe(fd);
+		fflush(stdout);
+		fflush(stderr);
+		if(fork())
+			{
+			close(fd[1]);
+			fds[n]=fd[0];
+			}
+		else
+			{
+			close(fd[0]);
+			close(1);
+			dup(fd[1]);
+			close(fd[1]);
+			mr=1;
+			usertime=0;
+			free(fds);
+			return 0;
+			}
+		printf("Forked child %d\n",n);
+		}
+
+	/* for now, assume the pipe is long enough to take all the output */
+	for(n=0 ; n < multi ; ++n)
+		{
+		FILE *f;
+		char buf[1024];
+		char *p;
+
+		f=fdopen(fds[n],"r");
+		while(fgets(buf,sizeof buf,f))
+			{
+			p=strchr(buf,'\n');
+			if(p)
+				*p='\0';
+			if(buf[0] != '+')
+				{
+				fprintf(stderr,"Don't understand line '%s' from child %d\n",
+						buf,n);
+				continue;
+				}
+			printf("Got: %s from %d\n",buf,n);
+			if(!strncmp(buf,"+F:",3))
+				{
+				int alg;
+				int j;
+
+				p=buf+3;
+				alg=atoi(sstrsep(&p,sep));
+				sstrsep(&p,sep);
+				for(j=0 ; j < SIZE_NUM ; ++j)
+					results[alg][j]+=atof(sstrsep(&p,sep));
+				}
+			else if(!strncmp(buf,"+F2:",4))
+				{
+				int k;
+				double d;
+				
+				p=buf+4;
+				k=atoi(sstrsep(&p,sep));
+				sstrsep(&p,sep);
+
+				d=atof(sstrsep(&p,sep));
+				if(n)
+					rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d);
+				else
+					rsa_results[k][0]=d;
+
+				d=atof(sstrsep(&p,sep));
+				if(n)
+					rsa_results[k][1]=1/(1/rsa_results[k][1]+1/d);
+				else
+					rsa_results[k][1]=d;
+				}
+			else if(!strncmp(buf,"+F2:",4))
+				{
+				int k;
+				double d;
+				
+				p=buf+4;
+				k=atoi(sstrsep(&p,sep));
+				sstrsep(&p,sep);
+
+				d=atof(sstrsep(&p,sep));
+				if(n)
+					rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d);
+				else
+					rsa_results[k][0]=d;
+
+				d=atof(sstrsep(&p,sep));
+				if(n)
+					rsa_results[k][1]=1/(1/rsa_results[k][1]+1/d);
+				else
+					rsa_results[k][1]=d;
+				}
+#ifndef OPENSSL_NO_DSA
+			else if(!strncmp(buf,"+F3:",4))
+				{
+				int k;
+				double d;
+				
+				p=buf+4;
+				k=atoi(sstrsep(&p,sep));
+				sstrsep(&p,sep);
+
+				d=atof(sstrsep(&p,sep));
+				if(n)
+					dsa_results[k][0]=1/(1/dsa_results[k][0]+1/d);
+				else
+					dsa_results[k][0]=d;
+
+				d=atof(sstrsep(&p,sep));
+				if(n)
+					dsa_results[k][1]=1/(1/dsa_results[k][1]+1/d);
+				else
+					dsa_results[k][1]=d;
+				}
+#endif
+#ifndef OPENSSL_NO_ECDSA
+			else if(!strncmp(buf,"+F4:",4))
+				{
+				int k;
+				double d;
+				
+				p=buf+4;
+				k=atoi(sstrsep(&p,sep));
+				sstrsep(&p,sep);
+
+				d=atof(sstrsep(&p,sep));
+				if(n)
+					ecdsa_results[k][0]=1/(1/ecdsa_results[k][0]+1/d);
+				else
+					ecdsa_results[k][0]=d;
+
+				d=atof(sstrsep(&p,sep));
+				if(n)
+					ecdsa_results[k][1]=1/(1/ecdsa_results[k][1]+1/d);
+				else
+					ecdsa_results[k][1]=d;
+				}
+#endif 
+
+#ifndef OPENSSL_NO_ECDH
+			else if(!strncmp(buf,"+F5:",4))
+				{
+				int k;
+				double d;
+				
+				p=buf+4;
+				k=atoi(sstrsep(&p,sep));
+				sstrsep(&p,sep);
+
+				d=atof(sstrsep(&p,sep));
+				if(n)
+					ecdh_results[k][0]=1/(1/ecdh_results[k][0]+1/d);
+				else
+					ecdh_results[k][0]=d;
+
+				}
+#endif
+
+			else if(!strncmp(buf,"+H:",3))
+				{
+				}
+			else
+				fprintf(stderr,"Unknown type '%s' from child %d\n",buf,n);
+			}
+
+		fclose(f);
+		}
+	free(fds);
+	return 1;
+	}
+#endif
+#endif
diff --git a/openssl/apps/spkac.c b/openssl/apps/spkac.c
new file mode 100644
index 0000000..0e01ea9
--- /dev/null
+++ b/openssl/apps/spkac.c
@@ -0,0 +1,308 @@
+/* apps/spkac.c */
+
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999. Based on an original idea by Massimiliano Pala
+ * (madwolf@openca.org).
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/conf.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/lhash.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+#undef PROG
+#define PROG	spkac_main
+
+/* -in arg	- input file - default stdin
+ * -out arg	- output file - default stdout
+ */
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	ENGINE *e = NULL;
+	int i,badops=0, ret = 1;
+	BIO *in = NULL,*out = NULL;
+	int verify=0,noout=0,pubkey=0;
+	char *infile = NULL,*outfile = NULL,*prog;
+	char *passargin = NULL, *passin = NULL;
+	const char *spkac = "SPKAC", *spksect = "default";
+	char *spkstr = NULL;
+	char *challenge = NULL, *keyfile = NULL;
+	CONF *conf = NULL;
+	NETSCAPE_SPKI *spki = NULL;
+	EVP_PKEY *pkey = NULL;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+
+	apps_startup();
+
+	if (!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	prog=argv[0];
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-passin") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passargin= *(++argv);
+			}
+		else if (strcmp(*argv,"-key") == 0)
+			{
+			if (--argc < 1) goto bad;
+			keyfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-challenge") == 0)
+			{
+			if (--argc < 1) goto bad;
+			challenge= *(++argv);
+			}
+		else if (strcmp(*argv,"-spkac") == 0)
+			{
+			if (--argc < 1) goto bad;
+			spkac= *(++argv);
+			}
+		else if (strcmp(*argv,"-spksect") == 0)
+			{
+			if (--argc < 1) goto bad;
+			spksect= *(++argv);
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*argv,"-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine= *(++argv);
+			}
+#endif
+		else if (strcmp(*argv,"-noout") == 0)
+			noout=1;
+		else if (strcmp(*argv,"-pubkey") == 0)
+			pubkey=1;
+		else if (strcmp(*argv,"-verify") == 0)
+			verify=1;
+		else badops = 1;
+		argc--;
+		argv++;
+		}
+
+	if (badops)
+		{
+bad:
+		BIO_printf(bio_err,"%s [options]\n",prog);
+		BIO_printf(bio_err,"where options are\n");
+		BIO_printf(bio_err," -in arg        input file\n");
+		BIO_printf(bio_err," -out arg       output file\n");
+		BIO_printf(bio_err," -key arg       create SPKAC using private key\n");
+		BIO_printf(bio_err," -passin arg    input file pass phrase source\n");
+		BIO_printf(bio_err," -challenge arg challenge string\n");
+		BIO_printf(bio_err," -spkac arg     alternative SPKAC name\n");
+		BIO_printf(bio_err," -noout         don't print SPKAC\n");
+		BIO_printf(bio_err," -pubkey        output public key\n");
+		BIO_printf(bio_err," -verify        verify SPKAC signature\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err," -engine e      use engine e, possibly a hardware device.\n");
+#endif
+		goto end;
+		}
+
+	ERR_load_crypto_strings();
+	if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
+		BIO_printf(bio_err, "Error getting password\n");
+		goto end;
+	}
+
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine, 0);
+#endif
+
+	if(keyfile) {
+		pkey = load_key(bio_err,
+				strcmp(keyfile, "-") ? keyfile : NULL,
+				FORMAT_PEM, 1, passin, e, "private key");
+		if(!pkey) {
+			goto end;
+		}
+		spki = NETSCAPE_SPKI_new();
+		if(challenge) ASN1_STRING_set(spki->spkac->challenge,
+						 challenge, (int)strlen(challenge));
+		NETSCAPE_SPKI_set_pubkey(spki, pkey);
+		NETSCAPE_SPKI_sign(spki, pkey, EVP_md5());
+		spkstr = NETSCAPE_SPKI_b64_encode(spki);
+
+		if (outfile) out = BIO_new_file(outfile, "w");
+		else {
+			out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+			{
+			    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+			    out = BIO_push(tmpbio, out);
+			}
+#endif
+		}
+
+		if(!out) {
+			BIO_printf(bio_err, "Error opening output file\n");
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+		BIO_printf(out, "SPKAC=%s\n", spkstr);
+		OPENSSL_free(spkstr);
+		ret = 0;
+		goto end;
+	}
+
+	
+
+	if (infile) in = BIO_new_file(infile, "r");
+	else in = BIO_new_fp(stdin, BIO_NOCLOSE);
+
+	if(!in) {
+		BIO_printf(bio_err, "Error opening input file\n");
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+
+	conf = NCONF_new(NULL);
+	i = NCONF_load_bio(conf, in, NULL);
+
+	if(!i) {
+		BIO_printf(bio_err, "Error parsing config file\n");
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+
+	spkstr = NCONF_get_string(conf, spksect, spkac);
+		
+	if(!spkstr) {
+		BIO_printf(bio_err, "Can't find SPKAC called \"%s\"\n", spkac);
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+
+	spki = NETSCAPE_SPKI_b64_decode(spkstr, -1);
+	
+	if(!spki) {
+		BIO_printf(bio_err, "Error loading SPKAC\n");
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+
+	if (outfile) out = BIO_new_file(outfile, "w");
+	else {
+		out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		    out = BIO_push(tmpbio, out);
+		}
+#endif
+	}
+
+	if(!out) {
+		BIO_printf(bio_err, "Error opening output file\n");
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+
+	if(!noout) NETSCAPE_SPKI_print(out, spki);
+	pkey = NETSCAPE_SPKI_get_pubkey(spki);
+	if(verify) {
+		i = NETSCAPE_SPKI_verify(spki, pkey);
+		if (i > 0) BIO_printf(bio_err, "Signature OK\n");
+		else {
+			BIO_printf(bio_err, "Signature Failure\n");
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+	}
+	if(pubkey) PEM_write_bio_PUBKEY(out, pkey);
+
+	ret = 0;
+
+end:
+	NCONF_free(conf);
+	NETSCAPE_SPKI_free(spki);
+	BIO_free(in);
+	BIO_free_all(out);
+	EVP_PKEY_free(pkey);
+	if(passin) OPENSSL_free(passin);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
diff --git a/openssl/apps/testCA.pem b/openssl/apps/testCA.pem
new file mode 100644
index 0000000..dcb710a
--- /dev/null
+++ b/openssl/apps/testCA.pem
@@ -0,0 +1,8 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBBzCBsgIBADBNMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEX
+MBUGA1UEChMOTWluY29tIFB0eSBMdGQxEDAOBgNVBAMTB1RFU1QgQ0EwXDANBgkq
+hkiG9w0BAQEFAANLADBIAkEAzW9brgA8efT2ODB+NrsflJZj3KKqKsm4OrXTRqfL
+VETj1ws/zCXl42XJAxdWQMCP0liKfc9Ut4xi1qCVI7N07wIDAQABoAAwDQYJKoZI
+hvcNAQEEBQADQQBjZZ42Det9Uw0AFwJy4ufUEy5Cv74pxBp5SZnljgHY+Az0Hs2S
+uNkIegr2ITX5azKi9nOkg9ZmsmGG13FIjiC/
+-----END CERTIFICATE REQUEST-----
diff --git a/openssl/apps/testdsa.h b/openssl/apps/testdsa.h
new file mode 100644
index 0000000..9e84e31
--- /dev/null
+++ b/openssl/apps/testdsa.h
@@ -0,0 +1,217 @@
+/* NOCW */
+/* used by apps/speed.c */
+DSA *get_dsa512(void );
+DSA *get_dsa1024(void );
+DSA *get_dsa2048(void );
+static unsigned char dsa512_priv[] = {
+	0x65,0xe5,0xc7,0x38,0x60,0x24,0xb5,0x89,0xd4,0x9c,0xeb,0x4c,
+	0x9c,0x1d,0x7a,0x22,0xbd,0xd1,0xc2,0xd2,
+	};
+static unsigned char dsa512_pub[] = {
+	0x00,0x95,0xa7,0x0d,0xec,0x93,0x68,0xba,0x5f,0xf7,0x5f,0x07,
+	0xf2,0x3b,0xad,0x6b,0x01,0xdc,0xbe,0xec,0xde,0x04,0x7a,0x3a,
+	0x27,0xb3,0xec,0x49,0xfd,0x08,0x43,0x3d,0x7e,0xa8,0x2c,0x5e,
+	0x7b,0xbb,0xfc,0xf4,0x6e,0xeb,0x6c,0xb0,0x6e,0xf8,0x02,0x12,
+	0x8c,0x38,0x5d,0x83,0x56,0x7d,0xee,0x53,0x05,0x3e,0x24,0x84,
+	0xbe,0xba,0x0a,0x6b,0xc8,
+	};
+static unsigned char dsa512_p[]={
+	0x9D,0x1B,0x69,0x8E,0x26,0xDB,0xF2,0x2B,0x11,0x70,0x19,0x86,
+	0xF6,0x19,0xC8,0xF8,0x19,0xF2,0x18,0x53,0x94,0x46,0x06,0xD0,
+	0x62,0x50,0x33,0x4B,0x02,0x3C,0x52,0x30,0x03,0x8B,0x3B,0xF9,
+	0x5F,0xD1,0x24,0x06,0x4F,0x7B,0x4C,0xBA,0xAA,0x40,0x9B,0xFD,
+	0x96,0xE4,0x37,0x33,0xBB,0x2D,0x5A,0xD7,0x5A,0x11,0x40,0x66,
+	0xA2,0x76,0x7D,0x31,
+	};
+static unsigned char dsa512_q[]={
+	0xFB,0x53,0xEF,0x50,0xB4,0x40,0x92,0x31,0x56,0x86,0x53,0x7A,
+	0xE8,0x8B,0x22,0x9A,0x49,0xFB,0x71,0x8F,
+	};
+static unsigned char dsa512_g[]={
+	0x83,0x3E,0x88,0xE5,0xC5,0x89,0x73,0xCE,0x3B,0x6C,0x01,0x49,
+	0xBF,0xB3,0xC7,0x9F,0x0A,0xEA,0x44,0x91,0xE5,0x30,0xAA,0xD9,
+	0xBE,0x5B,0x5F,0xB7,0x10,0xD7,0x89,0xB7,0x8E,0x74,0xFB,0xCF,
+	0x29,0x1E,0xEB,0xA8,0x2C,0x54,0x51,0xB8,0x10,0xDE,0xA0,0xCE,
+	0x2F,0xCC,0x24,0x6B,0x90,0x77,0xDE,0xA2,0x68,0xA6,0x52,0x12,
+	0xA2,0x03,0x9D,0x20,
+	};
+
+DSA *get_dsa512()
+	{
+	DSA *dsa;
+
+	if ((dsa=DSA_new()) == NULL) return(NULL);
+	dsa->priv_key=BN_bin2bn(dsa512_priv,sizeof(dsa512_priv),NULL);
+	dsa->pub_key=BN_bin2bn(dsa512_pub,sizeof(dsa512_pub),NULL);
+	dsa->p=BN_bin2bn(dsa512_p,sizeof(dsa512_p),NULL);
+	dsa->q=BN_bin2bn(dsa512_q,sizeof(dsa512_q),NULL);
+	dsa->g=BN_bin2bn(dsa512_g,sizeof(dsa512_g),NULL);
+	if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) || (dsa->p == NULL) ||
+				(dsa->q == NULL) || (dsa->g == NULL))
+		return(NULL);
+	return(dsa);
+	}
+
+static unsigned char dsa1024_priv[]={
+	0x7d,0x21,0xda,0xbb,0x62,0x15,0x47,0x36,0x07,0x67,0x12,0xe8,
+	0x8c,0xaa,0x1c,0xcd,0x38,0x12,0x61,0x18,
+	};
+static unsigned char dsa1024_pub[]={
+	0x3c,0x4e,0x9c,0x2a,0x7f,0x16,0xc1,0x25,0xeb,0xac,0x78,0x63,
+	0x90,0x14,0x8c,0x8b,0xf4,0x68,0x43,0x3c,0x2d,0xee,0x65,0x50,
+	0x7d,0x9c,0x8f,0x8c,0x8a,0x51,0xd6,0x11,0x2b,0x99,0xaf,0x1e,
+	0x90,0x97,0xb5,0xd3,0xa6,0x20,0x25,0xd6,0xfe,0x43,0x02,0xd5,
+	0x91,0x7d,0xa7,0x8c,0xdb,0xc9,0x85,0xa3,0x36,0x48,0xf7,0x68,
+	0xaa,0x60,0xb1,0xf7,0x05,0x68,0x3a,0xa3,0x3f,0xd3,0x19,0x82,
+	0xd8,0x82,0x7a,0x77,0xfb,0xef,0xf4,0x15,0x0a,0xeb,0x06,0x04,
+	0x7f,0x53,0x07,0x0c,0xbc,0xcb,0x2d,0x83,0xdb,0x3e,0xd1,0x28,
+	0xa5,0xa1,0x31,0xe0,0x67,0xfa,0x50,0xde,0x9b,0x07,0x83,0x7e,
+	0x2c,0x0b,0xc3,0x13,0x50,0x61,0xe5,0xad,0xbd,0x36,0xb8,0x97,
+	0x4e,0x40,0x7d,0xe8,0x83,0x0d,0xbc,0x4b
+	};
+static unsigned char dsa1024_p[]={
+	0xA7,0x3F,0x6E,0x85,0xBF,0x41,0x6A,0x29,0x7D,0xF0,0x9F,0x47,
+	0x19,0x30,0x90,0x9A,0x09,0x1D,0xDA,0x6A,0x33,0x1E,0xC5,0x3D,
+	0x86,0x96,0xB3,0x15,0xE0,0x53,0x2E,0x8F,0xE0,0x59,0x82,0x73,
+	0x90,0x3E,0x75,0x31,0x99,0x47,0x7A,0x52,0xFB,0x85,0xE4,0xD9,
+	0xA6,0x7B,0x38,0x9B,0x68,0x8A,0x84,0x9B,0x87,0xC6,0x1E,0xB5,
+	0x7E,0x86,0x4B,0x53,0x5B,0x59,0xCF,0x71,0x65,0x19,0x88,0x6E,
+	0xCE,0x66,0xAE,0x6B,0x88,0x36,0xFB,0xEC,0x28,0xDC,0xC2,0xD7,
+	0xA5,0xBB,0xE5,0x2C,0x39,0x26,0x4B,0xDA,0x9A,0x70,0x18,0x95,
+	0x37,0x95,0x10,0x56,0x23,0xF6,0x15,0xED,0xBA,0x04,0x5E,0xDE,
+	0x39,0x4F,0xFD,0xB7,0x43,0x1F,0xB5,0xA4,0x65,0x6F,0xCD,0x80,
+	0x11,0xE4,0x70,0x95,0x5B,0x50,0xCD,0x49,
+	};
+static unsigned char dsa1024_q[]={
+	0xF7,0x07,0x31,0xED,0xFA,0x6C,0x06,0x03,0xD5,0x85,0x8A,0x1C,
+	0xAC,0x9C,0x65,0xE7,0x50,0x66,0x65,0x6F,
+	};
+static unsigned char dsa1024_g[]={
+	0x4D,0xDF,0x4C,0x03,0xA6,0x91,0x8A,0xF5,0x19,0x6F,0x50,0x46,
+	0x25,0x99,0xE5,0x68,0x6F,0x30,0xE3,0x69,0xE1,0xE5,0xB3,0x5D,
+	0x98,0xBB,0x28,0x86,0x48,0xFC,0xDE,0x99,0x04,0x3F,0x5F,0x88,
+	0x0C,0x9C,0x73,0x24,0x0D,0x20,0x5D,0xB9,0x2A,0x9A,0x3F,0x18,
+	0x96,0x27,0xE4,0x62,0x87,0xC1,0x7B,0x74,0x62,0x53,0xFC,0x61,
+	0x27,0xA8,0x7A,0x91,0x09,0x9D,0xB6,0xF1,0x4D,0x9C,0x54,0x0F,
+	0x58,0x06,0xEE,0x49,0x74,0x07,0xCE,0x55,0x7E,0x23,0xCE,0x16,
+	0xF6,0xCA,0xDC,0x5A,0x61,0x01,0x7E,0xC9,0x71,0xB5,0x4D,0xF6,
+	0xDC,0x34,0x29,0x87,0x68,0xF6,0x5E,0x20,0x93,0xB3,0xDB,0xF5,
+	0xE4,0x09,0x6C,0x41,0x17,0x95,0x92,0xEB,0x01,0xB5,0x73,0xA5,
+	0x6A,0x7E,0xD8,0x32,0xED,0x0E,0x02,0xB8,
+	};
+
+DSA *get_dsa1024()
+	{
+	DSA *dsa;
+
+	if ((dsa=DSA_new()) == NULL) return(NULL);
+	dsa->priv_key=BN_bin2bn(dsa1024_priv,sizeof(dsa1024_priv),NULL);
+	dsa->pub_key=BN_bin2bn(dsa1024_pub,sizeof(dsa1024_pub),NULL);
+	dsa->p=BN_bin2bn(dsa1024_p,sizeof(dsa1024_p),NULL);
+	dsa->q=BN_bin2bn(dsa1024_q,sizeof(dsa1024_q),NULL);
+	dsa->g=BN_bin2bn(dsa1024_g,sizeof(dsa1024_g),NULL);
+	if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) || (dsa->p == NULL) ||
+				(dsa->q == NULL) || (dsa->g == NULL))
+		return(NULL);
+	return(dsa);
+	}
+
+static unsigned char dsa2048_priv[]={
+	0x32,0x67,0x92,0xf6,0xc4,0xe2,0xe2,0xe8,0xa0,0x8b,0x6b,0x45,
+	0x0c,0x8a,0x76,0xb0,0xee,0xcf,0x91,0xa7,
+	};
+static unsigned char dsa2048_pub[]={
+	0x17,0x8f,0xa8,0x11,0x84,0x92,0xec,0x83,0x47,0xc7,0x6a,0xb0,
+	0x92,0xaf,0x5a,0x20,0x37,0xa3,0x64,0x79,0xd2,0xd0,0x3d,0xcd,
+	0xe0,0x61,0x88,0x88,0x21,0xcc,0x74,0x5d,0xce,0x4c,0x51,0x47,
+	0xf0,0xc5,0x5c,0x4c,0x82,0x7a,0xaf,0x72,0xad,0xb9,0xe0,0x53,
+	0xf2,0x78,0xb7,0xf0,0xb5,0x48,0x7f,0x8a,0x3a,0x18,0xd1,0x9f,
+	0x8b,0x7d,0xa5,0x47,0xb7,0x95,0xab,0x98,0xf8,0x7b,0x74,0x50,
+	0x56,0x8e,0x57,0xf0,0xee,0xf5,0xb7,0xba,0xab,0x85,0x86,0xf9,
+	0x2b,0xef,0x41,0x56,0xa0,0xa4,0x9f,0xb7,0x38,0x00,0x46,0x0a,
+	0xa6,0xf1,0xfc,0x1f,0xd8,0x4e,0x85,0x44,0x92,0x43,0x21,0x5d,
+	0x6e,0xcc,0xc2,0xcb,0x26,0x31,0x0d,0x21,0xc4,0xbd,0x8d,0x24,
+	0xbc,0xd9,0x18,0x19,0xd7,0xdc,0xf1,0xe7,0x93,0x50,0x48,0x03,
+	0x2c,0xae,0x2e,0xe7,0x49,0x88,0x5f,0x93,0x57,0x27,0x99,0x36,
+	0xb4,0x20,0xab,0xfc,0xa7,0x2b,0xf2,0xd9,0x98,0xd7,0xd4,0x34,
+	0x9d,0x96,0x50,0x58,0x9a,0xea,0x54,0xf3,0xee,0xf5,0x63,0x14,
+	0xee,0x85,0x83,0x74,0x76,0xe1,0x52,0x95,0xc3,0xf7,0xeb,0x04,
+	0x04,0x7b,0xa7,0x28,0x1b,0xcc,0xea,0x4a,0x4e,0x84,0xda,0xd8,
+	0x9c,0x79,0xd8,0x9b,0x66,0x89,0x2f,0xcf,0xac,0xd7,0x79,0xf9,
+	0xa9,0xd8,0x45,0x13,0x78,0xb9,0x00,0x14,0xc9,0x7e,0x22,0x51,
+	0x86,0x67,0xb0,0x9f,0x26,0x11,0x23,0xc8,0x38,0xd7,0x70,0x1d,
+	0x15,0x8e,0x4d,0x4f,0x95,0x97,0x40,0xa1,0xc2,0x7e,0x01,0x18,
+	0x72,0xf4,0x10,0xe6,0x8d,0x52,0x16,0x7f,0xf2,0xc9,0xf8,0x33,
+	0x8b,0x33,0xb7,0xce,
+	};
+static unsigned char dsa2048_p[]={
+	0xA0,0x25,0xFA,0xAD,0xF4,0x8E,0xB9,0xE5,0x99,0xF3,0x5D,0x6F,
+	0x4F,0x83,0x34,0xE2,0x7E,0xCF,0x6F,0xBF,0x30,0xAF,0x6F,0x81,
+	0xEB,0xF8,0xC4,0x13,0xD9,0xA0,0x5D,0x8B,0x5C,0x8E,0xDC,0xC2,
+	0x1D,0x0B,0x41,0x32,0xB0,0x1F,0xFE,0xEF,0x0C,0xC2,0xA2,0x7E,
+	0x68,0x5C,0x28,0x21,0xE9,0xF5,0xB1,0x58,0x12,0x63,0x4C,0x19,
+	0x4E,0xFF,0x02,0x4B,0x92,0xED,0xD2,0x07,0x11,0x4D,0x8C,0x58,
+	0x16,0x5C,0x55,0x8E,0xAD,0xA3,0x67,0x7D,0xB9,0x86,0x6E,0x0B,
+	0xE6,0x54,0x6F,0x40,0xAE,0x0E,0x67,0x4C,0xF9,0x12,0x5B,0x3C,
+	0x08,0x7A,0xF7,0xFC,0x67,0x86,0x69,0xE7,0x0A,0x94,0x40,0xBF,
+	0x8B,0x76,0xFE,0x26,0xD1,0xF2,0xA1,0x1A,0x84,0xA1,0x43,0x56,
+	0x28,0xBC,0x9A,0x5F,0xD7,0x3B,0x69,0x89,0x8A,0x36,0x2C,0x51,
+	0xDF,0x12,0x77,0x2F,0x57,0x7B,0xA0,0xAA,0xDD,0x7F,0xA1,0x62,
+	0x3B,0x40,0x7B,0x68,0x1A,0x8F,0x0D,0x38,0xBB,0x21,0x5D,0x18,
+	0xFC,0x0F,0x46,0xF7,0xA3,0xB0,0x1D,0x23,0xC3,0xD2,0xC7,0x72,
+	0x51,0x18,0xDF,0x46,0x95,0x79,0xD9,0xBD,0xB5,0x19,0x02,0x2C,
+	0x87,0xDC,0xE7,0x57,0x82,0x7E,0xF1,0x8B,0x06,0x3D,0x00,0xA5,
+	0x7B,0x6B,0x26,0x27,0x91,0x0F,0x6A,0x77,0xE4,0xD5,0x04,0xE4,
+	0x12,0x2C,0x42,0xFF,0xD2,0x88,0xBB,0xD3,0x92,0xA0,0xF9,0xC8,
+	0x51,0x64,0x14,0x5C,0xD8,0xF9,0x6C,0x47,0x82,0xB4,0x1C,0x7F,
+	0x09,0xB8,0xF0,0x25,0x83,0x1D,0x3F,0x3F,0x05,0xB3,0x21,0x0A,
+	0x5D,0xA7,0xD8,0x54,0xC3,0x65,0x7D,0xC3,0xB0,0x1D,0xBF,0xAE,
+	0xF8,0x68,0xCF,0x9B,
+	};
+static unsigned char dsa2048_q[]={
+	0x97,0xE7,0x33,0x4D,0xD3,0x94,0x3E,0x0B,0xDB,0x62,0x74,0xC6,
+	0xA1,0x08,0xDD,0x19,0xA3,0x75,0x17,0x1B,
+	};
+static unsigned char dsa2048_g[]={
+	0x2C,0x78,0x16,0x59,0x34,0x63,0xF4,0xF3,0x92,0xFC,0xB5,0xA5,
+	0x4F,0x13,0xDE,0x2F,0x1C,0xA4,0x3C,0xAE,0xAD,0x38,0x3F,0x7E,
+	0x90,0xBF,0x96,0xA6,0xAE,0x25,0x90,0x72,0xF5,0x8E,0x80,0x0C,
+	0x39,0x1C,0xD9,0xEC,0xBA,0x90,0x5B,0x3A,0xE8,0x58,0x6C,0x9E,
+	0x30,0x42,0x37,0x02,0x31,0x82,0xBC,0x6A,0xDF,0x6A,0x09,0x29,
+	0xE3,0xC0,0x46,0xD1,0xCB,0x85,0xEC,0x0C,0x30,0x5E,0xEA,0xC8,
+	0x39,0x8E,0x22,0x9F,0x22,0x10,0xD2,0x34,0x61,0x68,0x37,0x3D,
+	0x2E,0x4A,0x5B,0x9A,0xF5,0xC1,0x48,0xC6,0xF6,0xDC,0x63,0x1A,
+	0xD3,0x96,0x64,0xBA,0x34,0xC9,0xD1,0xA0,0xD1,0xAE,0x6C,0x2F,
+	0x48,0x17,0x93,0x14,0x43,0xED,0xF0,0x21,0x30,0x19,0xC3,0x1B,
+	0x5F,0xDE,0xA3,0xF0,0x70,0x78,0x18,0xE1,0xA8,0xE4,0xEE,0x2E,
+	0x00,0xA5,0xE4,0xB3,0x17,0xC8,0x0C,0x7D,0x6E,0x42,0xDC,0xB7,
+	0x46,0x00,0x36,0x4D,0xD4,0x46,0xAA,0x3D,0x3C,0x46,0x89,0x40,
+	0xBF,0x1D,0x84,0x77,0x0A,0x75,0xF3,0x87,0x1D,0x08,0x4C,0xA6,
+	0xD1,0xA9,0x1C,0x1E,0x12,0x1E,0xE1,0xC7,0x30,0x28,0x76,0xA5,
+	0x7F,0x6C,0x85,0x96,0x2B,0x6F,0xDB,0x80,0x66,0x26,0xAE,0xF5,
+	0x93,0xC7,0x8E,0xAE,0x9A,0xED,0xE4,0xCA,0x04,0xEA,0x3B,0x72,
+	0xEF,0xDC,0x87,0xED,0x0D,0xA5,0x4C,0x4A,0xDD,0x71,0x22,0x64,
+	0x59,0x69,0x4E,0x8E,0xBF,0x43,0xDC,0xAB,0x8E,0x66,0xBB,0x01,
+	0xB6,0xF4,0xE7,0xFD,0xD2,0xAD,0x9F,0x36,0xC1,0xA0,0x29,0x99,
+	0xD1,0x96,0x70,0x59,0x06,0x78,0x35,0xBD,0x65,0x55,0x52,0x9E,
+	0xF8,0xB2,0xE5,0x38,
+	};
+ 
+DSA *get_dsa2048()
+	{
+	DSA *dsa;
+ 
+	if ((dsa=DSA_new()) == NULL) return(NULL);
+	dsa->priv_key=BN_bin2bn(dsa2048_priv,sizeof(dsa2048_priv),NULL);
+	dsa->pub_key=BN_bin2bn(dsa2048_pub,sizeof(dsa2048_pub),NULL);
+	dsa->p=BN_bin2bn(dsa2048_p,sizeof(dsa2048_p),NULL);
+	dsa->q=BN_bin2bn(dsa2048_q,sizeof(dsa2048_q),NULL);
+	dsa->g=BN_bin2bn(dsa2048_g,sizeof(dsa2048_g),NULL);
+	if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) || (dsa->p == NULL) ||
+				(dsa->q == NULL) || (dsa->g == NULL))
+		return(NULL);
+	return(dsa);
+	}
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+static int rnd_fake = 0;
diff --git a/openssl/apps/testrsa.h b/openssl/apps/testrsa.h
new file mode 100644
index 0000000..3007d79
--- /dev/null
+++ b/openssl/apps/testrsa.h
@@ -0,0 +1,518 @@
+/* apps/testrsa.h */
+/* used by apps/speed.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+static unsigned char test512[]={
+	0x30,0x82,0x01,0x3a,0x02,0x01,0x00,0x02,0x41,0x00,
+	0xd6,0x33,0xb9,0xc8,0xfb,0x4f,0x3c,0x7d,0xc0,0x01,
+	0x86,0xd0,0xe7,0xa0,0x55,0xf2,0x95,0x93,0xcc,0x4f,
+	0xb7,0x5b,0x67,0x5b,0x94,0x68,0xc9,0x34,0x15,0xde,
+	0xa5,0x2e,0x1c,0x33,0xc2,0x6e,0xfc,0x34,0x5e,0x71,
+	0x13,0xb7,0xd6,0xee,0xd8,0xa5,0x65,0x05,0x72,0x87,
+	0xa8,0xb0,0x77,0xfe,0x57,0xf5,0xfc,0x5f,0x55,0x83,
+	0x87,0xdd,0x57,0x49,0x02,0x03,0x01,0x00,0x01,0x02,
+	0x41,0x00,0xa7,0xf7,0x91,0xc5,0x0f,0x84,0x57,0xdc,
+	0x07,0xf7,0x6a,0x7f,0x60,0x52,0xb3,0x72,0xf1,0x66,
+	0x1f,0x7d,0x97,0x3b,0x9e,0xb6,0x0a,0x8f,0x8c,0xcf,
+	0x42,0x23,0x00,0x04,0xd4,0x28,0x0e,0x1c,0x90,0xc4,
+	0x11,0x25,0x25,0xa5,0x93,0xa5,0x2f,0x70,0x02,0xdf,
+	0x81,0x9c,0x49,0x03,0xa0,0xf8,0x6d,0x54,0x2e,0x26,
+	0xde,0xaa,0x85,0x59,0xa8,0x31,0x02,0x21,0x00,0xeb,
+	0x47,0xd7,0x3b,0xf6,0xc3,0xdd,0x5a,0x46,0xc5,0xb9,
+	0x2b,0x9a,0xa0,0x09,0x8f,0xa6,0xfb,0xf3,0x78,0x7a,
+	0x33,0x70,0x9d,0x0f,0x42,0x6b,0x13,0x68,0x24,0xd3,
+	0x15,0x02,0x21,0x00,0xe9,0x10,0xb0,0xb3,0x0d,0xe2,
+	0x82,0x68,0x77,0x8a,0x6e,0x7c,0xda,0xbc,0x3e,0x53,
+	0x83,0xfb,0xd6,0x22,0xe7,0xb5,0xae,0x6e,0x80,0xda,
+	0x00,0x55,0x97,0xc1,0xd0,0x65,0x02,0x20,0x4c,0xf8,
+	0x73,0xb1,0x6a,0x49,0x29,0x61,0x1f,0x46,0x10,0x0d,
+	0xf3,0xc7,0xe7,0x58,0xd7,0x88,0x15,0x5e,0x94,0x9b,
+	0xbf,0x7b,0xa2,0x42,0x58,0x45,0x41,0x0c,0xcb,0x01,
+	0x02,0x20,0x12,0x11,0xba,0x31,0x57,0x9d,0x3d,0x11,
+	0x0e,0x5b,0x8c,0x2f,0x5f,0xe2,0x02,0x4f,0x05,0x47,
+	0x8c,0x15,0x8e,0xb3,0x56,0x3f,0xb8,0xfb,0xad,0xd4,
+	0xf4,0xfc,0x10,0xc5,0x02,0x20,0x18,0xa1,0x29,0x99,
+	0x5b,0xd9,0xc8,0xd4,0xfc,0x49,0x7a,0x2a,0x21,0x2c,
+	0x49,0xe4,0x4f,0xeb,0xef,0x51,0xf1,0xab,0x6d,0xfb,
+	0x4b,0x14,0xe9,0x4b,0x52,0xb5,0x82,0x2c,
+	};
+
+static unsigned char test1024[]={
+	0x30,0x82,0x02,0x5c,0x02,0x01,0x00,0x02,0x81,0x81,
+	0x00,0xdc,0x98,0x43,0xe8,0x3d,0x43,0x5b,0xe4,0x05,
+	0xcd,0xd0,0xa9,0x3e,0xcb,0x83,0x75,0xf6,0xb5,0xa5,
+	0x9f,0x6b,0xe9,0x34,0x41,0x29,0x18,0xfa,0x6a,0x55,
+	0x4d,0x70,0xfc,0xec,0xae,0x87,0x38,0x0a,0x20,0xa9,
+	0xc0,0x45,0x77,0x6e,0x57,0x60,0x57,0xf4,0xed,0x96,
+	0x22,0xcb,0x8f,0xe1,0x33,0x3a,0x17,0x1f,0xed,0x37,
+	0xa5,0x6f,0xeb,0xa6,0xbc,0x12,0x80,0x1d,0x53,0xbd,
+	0x70,0xeb,0x21,0x76,0x3e,0xc9,0x2f,0x1a,0x45,0x24,
+	0x82,0xff,0xcd,0x59,0x32,0x06,0x2e,0x12,0x3b,0x23,
+	0x78,0xed,0x12,0x3d,0xe0,0x8d,0xf9,0x67,0x4f,0x37,
+	0x4e,0x47,0x02,0x4c,0x2d,0xc0,0x4f,0x1f,0xb3,0x94,
+	0xe1,0x41,0x2e,0x2d,0x90,0x10,0xfc,0x82,0x91,0x8b,
+	0x0f,0x22,0xd4,0xf2,0xfc,0x2c,0xab,0x53,0x55,0x02,
+	0x03,0x01,0x00,0x01,0x02,0x81,0x80,0x2b,0xcc,0x3f,
+	0x8f,0x58,0xba,0x8b,0x00,0x16,0xf6,0xea,0x3a,0xf0,
+	0x30,0xd0,0x05,0x17,0xda,0xb0,0xeb,0x9a,0x2d,0x4f,
+	0x26,0xb0,0xd6,0x38,0xc1,0xeb,0xf5,0xd8,0x3d,0x1f,
+	0x70,0xf7,0x7f,0xf4,0xe2,0xcf,0x51,0x51,0x79,0x88,
+	0xfa,0xe8,0x32,0x0e,0x7b,0x2d,0x97,0xf2,0xfa,0xba,
+	0x27,0xc5,0x9c,0xd9,0xc5,0xeb,0x8a,0x79,0x52,0x3c,
+	0x64,0x34,0x7d,0xc2,0xcf,0x28,0xc7,0x4e,0xd5,0x43,
+	0x0b,0xd1,0xa6,0xca,0x6d,0x03,0x2d,0x72,0x23,0xbc,
+	0x6d,0x05,0xfa,0x16,0x09,0x2f,0x2e,0x5c,0xb6,0xee,
+	0x74,0xdd,0xd2,0x48,0x8e,0x36,0x0c,0x06,0x3d,0x4d,
+	0xe5,0x10,0x82,0xeb,0x6a,0xf3,0x4b,0x9f,0xd6,0xed,
+	0x11,0xb1,0x6e,0xec,0xf4,0xfe,0x8e,0x75,0x94,0x20,
+	0x2f,0xcb,0xac,0x46,0xf1,0x02,0x41,0x00,0xf9,0x8c,
+	0xa3,0x85,0xb1,0xdd,0x29,0xaf,0x65,0xc1,0x33,0xf3,
+	0x95,0xc5,0x52,0x68,0x0b,0xd4,0xf1,0xe5,0x0e,0x02,
+	0x9f,0x4f,0xfa,0x77,0xdc,0x46,0x9e,0xc7,0xa6,0xe4,
+	0x16,0x29,0xda,0xb0,0x07,0xcf,0x5b,0xa9,0x12,0x8a,
+	0xdd,0x63,0x0a,0xde,0x2e,0x8c,0x66,0x8b,0x8c,0xdc,
+	0x19,0xa3,0x7e,0xf4,0x3b,0xd0,0x1a,0x8c,0xa4,0xc2,
+	0xe1,0xd3,0x02,0x41,0x00,0xe2,0x4c,0x05,0xf2,0x04,
+	0x86,0x4e,0x61,0x43,0xdb,0xb0,0xb9,0x96,0x86,0x52,
+	0x2c,0xca,0x8d,0x7b,0xab,0x0b,0x13,0x0d,0x7e,0x38,
+	0x5b,0xe2,0x2e,0x7b,0x0e,0xe7,0x19,0x99,0x38,0xe7,
+	0xf2,0x21,0xbd,0x85,0x85,0xe3,0xfd,0x28,0x77,0x20,
+	0x31,0x71,0x2c,0xd0,0xff,0xfb,0x2e,0xaf,0x85,0xb4,
+	0x86,0xca,0xf3,0xbb,0xca,0xaa,0x0f,0x95,0x37,0x02,
+	0x40,0x0e,0x41,0x9a,0x95,0xe8,0xb3,0x59,0xce,0x4b,
+	0x61,0xde,0x35,0xec,0x38,0x79,0x9c,0xb8,0x10,0x52,
+	0x41,0x63,0xab,0x82,0xae,0x6f,0x00,0xa9,0xf4,0xde,
+	0xdd,0x49,0x0b,0x7e,0xb8,0xa5,0x65,0xa9,0x0c,0x8f,
+	0x8f,0xf9,0x1f,0x35,0xc6,0x92,0xb8,0x5e,0xb0,0x66,
+	0xab,0x52,0x40,0xc0,0xb6,0x36,0x6a,0x7d,0x80,0x46,
+	0x04,0x02,0xe5,0x9f,0x41,0x02,0x41,0x00,0xc0,0xad,
+	0xcc,0x4e,0x21,0xee,0x1d,0x24,0x91,0xfb,0xa7,0x80,
+	0x8d,0x9a,0xb6,0xb3,0x2e,0x8f,0xc2,0xe1,0x82,0xdf,
+	0x69,0x18,0xb4,0x71,0xff,0xa6,0x65,0xde,0xed,0x84,
+	0x8d,0x42,0xb7,0xb3,0x21,0x69,0x56,0x1c,0x07,0x60,
+	0x51,0x29,0x04,0xff,0x34,0x06,0xdd,0xb9,0x67,0x2c,
+	0x7c,0x04,0x93,0x0e,0x46,0x15,0xbb,0x2a,0xb7,0x1b,
+	0xe7,0x87,0x02,0x40,0x78,0xda,0x5d,0x07,0x51,0x0c,
+	0x16,0x7a,0x9f,0x29,0x20,0x84,0x0d,0x42,0xfa,0xd7,
+	0x00,0xd8,0x77,0x7e,0xb0,0xb0,0x6b,0xd6,0x5b,0x53,
+	0xb8,0x9b,0x7a,0xcd,0xc7,0x2b,0xb8,0x6a,0x63,0xa9,
+	0xfb,0x6f,0xa4,0x72,0xbf,0x4c,0x5d,0x00,0x14,0xba,
+	0xfa,0x59,0x88,0xed,0xe4,0xe0,0x8c,0xa2,0xec,0x14,
+	0x7e,0x2d,0xe2,0xf0,0x46,0x49,0x95,0x45,
+	};
+
+static unsigned char test2048[]={
+	0x30,0x82,0x04,0xa3,0x02,0x01,0x00,0x02,0x82,0x01,
+	0x01,0x00,0xc0,0xc0,0xce,0x3e,0x3c,0x53,0x67,0x3f,
+	0x4f,0xc5,0x2f,0xa4,0xc2,0x5a,0x2f,0x58,0xfd,0x27,
+	0x52,0x6a,0xe8,0xcf,0x4a,0x73,0x47,0x8d,0x25,0x0f,
+	0x5f,0x03,0x26,0x78,0xef,0xf0,0x22,0x12,0xd3,0xde,
+	0x47,0xb2,0x1c,0x0b,0x38,0x63,0x1a,0x6c,0x85,0x7a,
+	0x80,0xc6,0x8f,0xa0,0x41,0xaf,0x62,0xc4,0x67,0x32,
+	0x88,0xf8,0xa6,0x9c,0xf5,0x23,0x1d,0xe4,0xac,0x3f,
+	0x29,0xf9,0xec,0xe1,0x8b,0x26,0x03,0x2c,0xb2,0xab,
+	0xf3,0x7d,0xb5,0xca,0x49,0xc0,0x8f,0x1c,0xdf,0x33,
+	0x3a,0x60,0xda,0x3c,0xb0,0x16,0xf8,0xa9,0x12,0x8f,
+	0x64,0xac,0x23,0x0c,0x69,0x64,0x97,0x5d,0x99,0xd4,
+	0x09,0x83,0x9b,0x61,0xd3,0xac,0xf0,0xde,0xdd,0x5e,
+	0x9f,0x44,0x94,0xdb,0x3a,0x4d,0x97,0xe8,0x52,0x29,
+	0xf7,0xdb,0x94,0x07,0x45,0x90,0x78,0x1e,0x31,0x0b,
+	0x80,0xf7,0x57,0xad,0x1c,0x79,0xc5,0xcb,0x32,0xb0,
+	0xce,0xcd,0x74,0xb3,0xe2,0x94,0xc5,0x78,0x2f,0x34,
+	0x1a,0x45,0xf7,0x8c,0x52,0xa5,0xbc,0x8d,0xec,0xd1,
+	0x2f,0x31,0x3b,0xf0,0x49,0x59,0x5e,0x88,0x9d,0x15,
+	0x92,0x35,0x32,0xc1,0xe7,0x61,0xec,0x50,0x48,0x7c,
+	0xba,0x05,0xf9,0xf8,0xf8,0xa7,0x8c,0x83,0xe8,0x66,
+	0x5b,0xeb,0xfe,0xd8,0x4f,0xdd,0x6d,0x36,0xc0,0xb2,
+	0x90,0x0f,0xb8,0x52,0xf9,0x04,0x9b,0x40,0x2c,0x27,
+	0xd6,0x36,0x8e,0xc2,0x1b,0x44,0xf3,0x92,0xd5,0x15,
+	0x9e,0x9a,0xbc,0xf3,0x7d,0x03,0xd7,0x02,0x14,0x20,
+	0xe9,0x10,0x92,0xfd,0xf9,0xfc,0x8f,0xe5,0x18,0xe1,
+	0x95,0xcc,0x9e,0x60,0xa6,0xfa,0x38,0x4d,0x02,0x03,
+	0x01,0x00,0x01,0x02,0x82,0x01,0x00,0x00,0xc3,0xc3,
+	0x0d,0xb4,0x27,0x90,0x8d,0x4b,0xbf,0xb8,0x84,0xaa,
+	0xd0,0xb8,0xc7,0x5d,0x99,0xbe,0x55,0xf6,0x3e,0x7c,
+	0x49,0x20,0xcb,0x8a,0x8e,0x19,0x0e,0x66,0x24,0xac,
+	0xaf,0x03,0x33,0x97,0xeb,0x95,0xd5,0x3b,0x0f,0x40,
+	0x56,0x04,0x50,0xd1,0xe6,0xbe,0x84,0x0b,0x25,0xd3,
+	0x9c,0xe2,0x83,0x6c,0xf5,0x62,0x5d,0xba,0x2b,0x7d,
+	0x3d,0x7a,0x6c,0xe1,0xd2,0x0e,0x54,0x93,0x80,0x01,
+	0x91,0x51,0x09,0xe8,0x5b,0x8e,0x47,0xbd,0x64,0xe4,
+	0x0e,0x03,0x83,0x55,0xcf,0x5a,0x37,0xf0,0x25,0xb5,
+	0x7d,0x21,0xd7,0x69,0xdf,0x6f,0xc2,0xcf,0x10,0xc9,
+	0x8a,0x40,0x9f,0x7a,0x70,0xc0,0xe8,0xe8,0xc0,0xe6,
+	0x9a,0x15,0x0a,0x8d,0x4e,0x46,0xcb,0x7a,0xdb,0xb3,
+	0xcb,0x83,0x02,0xc4,0xf0,0xab,0xeb,0x02,0x01,0x0e,
+	0x23,0xfc,0x1d,0xc4,0xbd,0xd4,0xaa,0x5d,0x31,0x46,
+	0x99,0xce,0x9e,0xf8,0x04,0x75,0x10,0x67,0xc4,0x53,
+	0x47,0x44,0xfa,0xc2,0x25,0x73,0x7e,0xd0,0x8e,0x59,
+	0xd1,0xb2,0x5a,0xf4,0xc7,0x18,0x92,0x2f,0x39,0xab,
+	0xcd,0xa3,0xb5,0xc2,0xb9,0xc7,0xb9,0x1b,0x9f,0x48,
+	0xfa,0x13,0xc6,0x98,0x4d,0xca,0x84,0x9c,0x06,0xca,
+	0xe7,0x89,0x01,0x04,0xc4,0x6c,0xfd,0x29,0x59,0x35,
+	0xe7,0xf3,0xdd,0xce,0x64,0x59,0xbf,0x21,0x13,0xa9,
+	0x9f,0x0e,0xc5,0xff,0xbd,0x33,0x00,0xec,0xac,0x6b,
+	0x11,0xef,0x51,0x5e,0xad,0x07,0x15,0xde,0xb8,0x5f,
+	0xc6,0xb9,0xa3,0x22,0x65,0x46,0x83,0x14,0xdf,0xd0,
+	0xf1,0x44,0x8a,0xe1,0x9c,0x23,0x33,0xb4,0x97,0x33,
+	0xe6,0x6b,0x81,0x02,0x81,0x81,0x00,0xec,0x12,0xa7,
+	0x59,0x74,0x6a,0xde,0x3e,0xad,0xd8,0x36,0x80,0x50,
+	0xa2,0xd5,0x21,0x81,0x07,0xf1,0xd0,0x91,0xf2,0x6c,
+	0x12,0x2f,0x9d,0x1a,0x26,0xf8,0x30,0x65,0xdf,0xe8,
+	0xc0,0x9b,0x6a,0x30,0x98,0x82,0x87,0xec,0xa2,0x56,
+	0x87,0x62,0x6f,0xe7,0x9f,0xf6,0x56,0xe6,0x71,0x8f,
+	0x49,0x86,0x93,0x5a,0x4d,0x34,0x58,0xfe,0xd9,0x04,
+	0x13,0xaf,0x79,0xb7,0xad,0x11,0xd1,0x30,0x9a,0x14,
+	0x06,0xa0,0xfa,0xb7,0x55,0xdc,0x6c,0x5a,0x4c,0x2c,
+	0x59,0x56,0xf6,0xe8,0x9d,0xaf,0x0a,0x78,0x99,0x06,
+	0x06,0x9e,0xe7,0x9c,0x51,0x55,0x43,0xfc,0x3b,0x6c,
+	0x0b,0xbf,0x2d,0x41,0xa7,0xaf,0xb7,0xe0,0xe8,0x28,
+	0x18,0xb4,0x13,0xd1,0xe6,0x97,0xd0,0x9f,0x6a,0x80,
+	0xca,0xdd,0x1a,0x7e,0x15,0x02,0x81,0x81,0x00,0xd1,
+	0x06,0x0c,0x1f,0xe3,0xd0,0xab,0xd6,0xca,0x7c,0xbc,
+	0x7d,0x13,0x35,0xce,0x27,0xcd,0xd8,0x49,0x51,0x63,
+	0x64,0x0f,0xca,0x06,0x12,0xfc,0x07,0x3e,0xaf,0x61,
+	0x6d,0xe2,0x53,0x39,0x27,0xae,0xc3,0x11,0x9e,0x94,
+	0x01,0x4f,0xe3,0xf3,0x67,0xf9,0x77,0xf9,0xe7,0x95,
+	0x3a,0x6f,0xe2,0x20,0x73,0x3e,0xa4,0x7a,0x28,0xd4,
+	0x61,0x97,0xf6,0x17,0xa0,0x23,0x10,0x2b,0xce,0x84,
+	0x57,0x7e,0x25,0x1f,0xf4,0xa8,0x54,0xd2,0x65,0x94,
+	0xcc,0x95,0x0a,0xab,0x30,0xc1,0x59,0x1f,0x61,0x8e,
+	0xb9,0x6b,0xd7,0x4e,0xb9,0x83,0x43,0x79,0x85,0x11,
+	0xbc,0x0f,0xae,0x25,0x20,0x05,0xbc,0xd2,0x48,0xa1,
+	0x68,0x09,0x84,0xf6,0x12,0x9a,0x66,0xb9,0x2b,0xbb,
+	0x76,0x03,0x17,0x46,0x4e,0x97,0x59,0x02,0x81,0x80,
+	0x09,0x4c,0xfa,0xd6,0xe5,0x65,0x48,0x78,0x43,0xb5,
+	0x1f,0x00,0x93,0x2c,0xb7,0x24,0xe8,0xc6,0x7d,0x5a,
+	0x70,0x45,0x92,0xc8,0x6c,0xa3,0xcd,0xe1,0xf7,0x29,
+	0x40,0xfa,0x3f,0x5b,0x47,0x44,0x39,0xc1,0xe8,0x72,
+	0x9e,0x7a,0x0e,0xda,0xaa,0xa0,0x2a,0x09,0xfd,0x54,
+	0x93,0x23,0xaa,0x37,0x85,0x5b,0xcc,0xd4,0xf9,0xd8,
+	0xff,0xc1,0x61,0x0d,0xbd,0x7e,0x18,0x24,0x73,0x6d,
+	0x40,0x72,0xf1,0x93,0x09,0x48,0x97,0x6c,0x84,0x90,
+	0xa8,0x46,0x14,0x01,0x39,0x11,0xe5,0x3c,0x41,0x27,
+	0x32,0x75,0x24,0xed,0xa1,0xd9,0x12,0x29,0x8a,0x28,
+	0x71,0x89,0x8d,0xca,0x30,0xb0,0x01,0xc4,0x2f,0x82,
+	0x19,0x14,0x4c,0x70,0x1c,0xb8,0x23,0x2e,0xe8,0x90,
+	0x49,0x97,0x92,0x97,0x6b,0x7a,0x9d,0xb9,0x02,0x81,
+	0x80,0x0f,0x0e,0xa1,0x76,0xf6,0xa1,0x44,0x8f,0xaf,
+	0x7c,0x76,0xd3,0x87,0xbb,0xbb,0x83,0x10,0x88,0x01,
+	0x18,0x14,0xd1,0xd3,0x75,0x59,0x24,0xaa,0xf5,0x16,
+	0xa5,0xe9,0x9d,0xd1,0xcc,0xee,0xf4,0x15,0xd9,0xc5,
+	0x7e,0x27,0xe9,0x44,0x49,0x06,0x72,0xb9,0xfc,0xd3,
+	0x8a,0xc4,0x2c,0x36,0x7d,0x12,0x9b,0x5a,0xaa,0xdc,
+	0x85,0xee,0x6e,0xad,0x54,0xb3,0xf4,0xfc,0x31,0xa1,
+	0x06,0x3a,0x70,0x57,0x0c,0xf3,0x95,0x5b,0x3e,0xe8,
+	0xfd,0x1a,0x4f,0xf6,0x78,0x93,0x46,0x6a,0xd7,0x31,
+	0xb4,0x84,0x64,0x85,0x09,0x38,0x89,0x92,0x94,0x1c,
+	0xbf,0xe2,0x3c,0x2a,0xe0,0xff,0x99,0xa3,0xf0,0x2b,
+	0x31,0xc2,0x36,0xcd,0x60,0xbf,0x9d,0x2d,0x74,0x32,
+	0xe8,0x9c,0x93,0x6e,0xbb,0x91,0x7b,0xfd,0xd9,0x02,
+	0x81,0x81,0x00,0xa2,0x71,0x25,0x38,0xeb,0x2a,0xe9,
+	0x37,0xcd,0xfe,0x44,0xce,0x90,0x3f,0x52,0x87,0x84,
+	0x52,0x1b,0xae,0x8d,0x22,0x94,0xce,0x38,0xe6,0x04,
+	0x88,0x76,0x85,0x9a,0xd3,0x14,0x09,0xe5,0x69,0x9a,
+	0xff,0x58,0x92,0x02,0x6a,0x7d,0x7c,0x1e,0x2c,0xfd,
+	0xa8,0xca,0x32,0x14,0x4f,0x0d,0x84,0x0d,0x37,0x43,
+	0xbf,0xe4,0x5d,0x12,0xc8,0x24,0x91,0x27,0x8d,0x46,
+	0xd9,0x54,0x53,0xe7,0x62,0x71,0xa8,0x2b,0x71,0x41,
+	0x8d,0x75,0xf8,0x3a,0xa0,0x61,0x29,0x46,0xa6,0xe5,
+	0x82,0xfa,0x3a,0xd9,0x08,0xfa,0xfc,0x63,0xfd,0x6b,
+	0x30,0xbc,0xf4,0x4e,0x9e,0x8c,0x25,0x0c,0xb6,0x55,
+	0xe7,0x3c,0xd4,0x4e,0x0b,0xfd,0x8b,0xc3,0x0e,0x1d,
+	0x9c,0x44,0x57,0x8f,0x1f,0x86,0xf7,0xd5,0x1b,0xe4,
+	0x95,
+	};
+
+static unsigned char test4096[]={
+	0x30,0x82,0x09,0x29,0x02,0x01,0x00,0x02,0x82,0x02,
+	0x01,0x00,0xc0,0x71,0xac,0x1a,0x13,0x88,0x82,0x43,
+	0x3b,0x51,0x57,0x71,0x8d,0xb6,0x2b,0x82,0x65,0x21,
+	0x53,0x5f,0x28,0x29,0x4f,0x8d,0x7c,0x8a,0xb9,0x44,
+	0xb3,0x28,0x41,0x4f,0xd3,0xfa,0x6a,0xf8,0xb9,0x28,
+	0x50,0x39,0x67,0x53,0x2c,0x3c,0xd7,0xcb,0x96,0x41,
+	0x40,0x32,0xbb,0xeb,0x70,0xae,0x1f,0xb0,0x65,0xf7,
+	0x3a,0xd9,0x22,0xfd,0x10,0xae,0xbd,0x02,0xe2,0xdd,
+	0xf3,0xc2,0x79,0x3c,0xc6,0xfc,0x75,0xbb,0xaf,0x4e,
+	0x3a,0x36,0xc2,0x4f,0xea,0x25,0xdf,0x13,0x16,0x4b,
+	0x20,0xfe,0x4b,0x69,0x16,0xc4,0x7f,0x1a,0x43,0xa6,
+	0x17,0x1b,0xb9,0x0a,0xf3,0x09,0x86,0x28,0x89,0xcf,
+	0x2c,0xd0,0xd4,0x81,0xaf,0xc6,0x6d,0xe6,0x21,0x8d,
+	0xee,0xef,0xea,0xdc,0xb7,0xc6,0x3b,0x63,0x9f,0x0e,
+	0xad,0x89,0x78,0x23,0x18,0xbf,0x70,0x7e,0x84,0xe0,
+	0x37,0xec,0xdb,0x8e,0x9c,0x3e,0x6a,0x19,0xcc,0x99,
+	0x72,0xe6,0xb5,0x7d,0x6d,0xfa,0xe5,0xd3,0xe4,0x90,
+	0xb5,0xb2,0xb2,0x12,0x70,0x4e,0xca,0xf8,0x10,0xf8,
+	0xa3,0x14,0xc2,0x48,0x19,0xeb,0x60,0x99,0xbb,0x2a,
+	0x1f,0xb1,0x7a,0xb1,0x3d,0x24,0xfb,0xa0,0x29,0xda,
+	0xbd,0x1b,0xd7,0xa4,0xbf,0xef,0x60,0x2d,0x22,0xca,
+	0x65,0x98,0xf1,0xc4,0xe1,0xc9,0x02,0x6b,0x16,0x28,
+	0x2f,0xa1,0xaa,0x79,0x00,0xda,0xdc,0x7c,0x43,0xf7,
+	0x42,0x3c,0xa0,0xef,0x68,0xf7,0xdf,0xb9,0x69,0xfb,
+	0x8e,0x01,0xed,0x01,0x42,0xb5,0x4e,0x57,0xa6,0x26,
+	0xb8,0xd0,0x7b,0x56,0x6d,0x03,0xc6,0x40,0x8c,0x8c,
+	0x2a,0x55,0xd7,0x9c,0x35,0x00,0x94,0x93,0xec,0x03,
+	0xeb,0x22,0xef,0x77,0xbb,0x79,0x13,0x3f,0x15,0xa1,
+	0x8f,0xca,0xdf,0xfd,0xd3,0xb8,0xe1,0xd4,0xcc,0x09,
+	0x3f,0x3c,0x2c,0xdb,0xd1,0x49,0x7f,0x38,0x07,0x83,
+	0x6d,0xeb,0x08,0x66,0xe9,0x06,0x44,0x12,0xac,0x95,
+	0x22,0x90,0x23,0x67,0xd4,0x08,0xcc,0xf4,0xb7,0xdc,
+	0xcc,0x87,0xd4,0xac,0x69,0x35,0x4c,0xb5,0x39,0x36,
+	0xcd,0xa4,0xd2,0x95,0xca,0x0d,0xc5,0xda,0xc2,0xc5,
+	0x22,0x32,0x28,0x08,0xe3,0xd2,0x8b,0x38,0x30,0xdc,
+	0x8c,0x75,0x4f,0x6a,0xec,0x7a,0xac,0x16,0x3e,0xa8,
+	0xd4,0x6a,0x45,0xe1,0xa8,0x4f,0x2e,0x80,0x34,0xaa,
+	0x54,0x1b,0x02,0x95,0x7d,0x8a,0x6d,0xcc,0x79,0xca,
+	0xf2,0xa4,0x2e,0x8d,0xfb,0xfe,0x15,0x51,0x10,0x0e,
+	0x4d,0x88,0xb1,0xc7,0xf4,0x79,0xdb,0xf0,0xb4,0x56,
+	0x44,0x37,0xca,0x5a,0xc1,0x8c,0x48,0xac,0xae,0x48,
+	0x80,0x83,0x01,0x3f,0xde,0xd9,0xd3,0x2c,0x51,0x46,
+	0xb1,0x41,0xb6,0xc6,0x91,0x72,0xf9,0x83,0x55,0x1b,
+	0x8c,0xba,0xf3,0x73,0xe5,0x2c,0x74,0x50,0x3a,0xbe,
+	0xc5,0x2f,0xa7,0xb2,0x6d,0x8c,0x9e,0x13,0x77,0xa3,
+	0x13,0xcd,0x6d,0x8c,0x45,0xe1,0xfc,0x0b,0xb7,0x69,
+	0xe9,0x27,0xbc,0x65,0xc3,0xfa,0x9b,0xd0,0xef,0xfe,
+	0xe8,0x1f,0xb3,0x5e,0x34,0xf4,0x8c,0xea,0xfc,0xd3,
+	0x81,0xbf,0x3d,0x30,0xb2,0xb4,0x01,0xe8,0x43,0x0f,
+	0xba,0x02,0x23,0x42,0x76,0x82,0x31,0x73,0x91,0xed,
+	0x07,0x46,0x61,0x0d,0x39,0x83,0x40,0xce,0x7a,0xd4,
+	0xdb,0x80,0x2c,0x1f,0x0d,0xd1,0x34,0xd4,0x92,0xe3,
+	0xd4,0xf1,0xc2,0x01,0x02,0x03,0x01,0x00,0x01,0x02,
+	0x82,0x02,0x01,0x00,0x97,0x6c,0xda,0x6e,0xea,0x4f,
+	0xcf,0xaf,0xf7,0x4c,0xd9,0xf1,0x90,0x00,0x77,0xdb,
+	0xf2,0x97,0x76,0x72,0xb9,0xb7,0x47,0xd1,0x9c,0xdd,
+	0xcb,0x4a,0x33,0x6e,0xc9,0x75,0x76,0xe6,0xe4,0xa5,
+	0x31,0x8c,0x77,0x13,0xb4,0x29,0xcd,0xf5,0x52,0x17,
+	0xef,0xf3,0x08,0x00,0xe3,0xbd,0x2e,0xbc,0xd4,0x52,
+	0x88,0xe9,0x30,0x75,0x0b,0x02,0xf5,0xcd,0x89,0x0c,
+	0x6c,0x57,0x19,0x27,0x3d,0x1e,0x85,0xb4,0xc1,0x2f,
+	0x1d,0x92,0x00,0x5c,0x76,0x29,0x4b,0xa4,0xe1,0x12,
+	0xb3,0xc8,0x09,0xfe,0x0e,0x78,0x72,0x61,0xcb,0x61,
+	0x6f,0x39,0x91,0x95,0x4e,0xd5,0x3e,0xc7,0x8f,0xb8,
+	0xf6,0x36,0xfe,0x9c,0x93,0x9a,0x38,0x25,0x7a,0xf4,
+	0x4a,0x12,0xd4,0xa0,0x13,0xbd,0xf9,0x1d,0x12,0x3e,
+	0x21,0x39,0xfb,0x72,0xe0,0x05,0x3d,0xc3,0xe5,0x50,
+	0xa8,0x5d,0x85,0xa3,0xea,0x5f,0x1c,0xb2,0x3f,0xea,
+	0x6d,0x03,0x91,0x55,0xd8,0x19,0x0a,0x21,0x12,0x16,
+	0xd9,0x12,0xc4,0xe6,0x07,0x18,0x5b,0x26,0xa4,0xae,
+	0xed,0x2b,0xb7,0xa6,0xed,0xf8,0xad,0xec,0x77,0xe6,
+	0x7f,0x4f,0x76,0x00,0xc0,0xfa,0x15,0x92,0xb4,0x2c,
+	0x22,0xc2,0xeb,0x6a,0xad,0x14,0x05,0xb2,0xe5,0x8a,
+	0x9e,0x85,0x83,0xcc,0x04,0xf1,0x56,0x78,0x44,0x5e,
+	0xde,0xe0,0x60,0x1a,0x65,0x79,0x31,0x23,0x05,0xbb,
+	0x01,0xff,0xdd,0x2e,0xb7,0xb3,0xaa,0x74,0xe0,0xa5,
+	0x94,0xaf,0x4b,0xde,0x58,0x0f,0x55,0xde,0x33,0xf6,
+	0xe3,0xd6,0x34,0x36,0x57,0xd6,0x79,0x91,0x2e,0xbe,
+	0x3b,0xd9,0x4e,0xb6,0x9d,0x21,0x5c,0xd3,0x48,0x14,
+	0x7f,0x4a,0xc4,0x60,0xa9,0x29,0xf8,0x53,0x7f,0x88,
+	0x11,0x2d,0xb5,0xc5,0x2d,0x6f,0xee,0x85,0x0b,0xf7,
+	0x8d,0x9a,0xbe,0xb0,0x42,0xf2,0x2e,0x71,0xaf,0x19,
+	0x31,0x6d,0xec,0xcd,0x6f,0x2b,0x23,0xdf,0xb4,0x40,
+	0xaf,0x2c,0x0a,0xc3,0x1b,0x7d,0x7d,0x03,0x1d,0x4b,
+	0xf3,0xb5,0xe0,0x85,0xd8,0xdf,0x91,0x6b,0x0a,0x69,
+	0xf7,0xf2,0x69,0x66,0x5b,0xf1,0xcf,0x46,0x7d,0xe9,
+	0x70,0xfa,0x6d,0x7e,0x75,0x4e,0xa9,0x77,0xe6,0x8c,
+	0x02,0xf7,0x14,0x4d,0xa5,0x41,0x8f,0x3f,0xc1,0x62,
+	0x1e,0x71,0x5e,0x38,0xb4,0xd6,0xe6,0xe1,0x4b,0xc2,
+	0x2c,0x30,0x83,0x81,0x6f,0x49,0x2e,0x96,0xe6,0xc9,
+	0x9a,0xf7,0x5d,0x09,0xa0,0x55,0x02,0xa5,0x3a,0x25,
+	0x23,0xd0,0x92,0xc3,0xa3,0xe3,0x0e,0x12,0x2f,0x4d,
+	0xef,0xf3,0x55,0x5a,0xbe,0xe6,0x19,0x86,0x31,0xab,
+	0x75,0x9a,0xd3,0xf0,0x2c,0xc5,0x41,0x92,0xd9,0x1f,
+	0x5f,0x11,0x8c,0x75,0x1c,0x63,0xd0,0x02,0x80,0x2c,
+	0x68,0xcb,0x93,0xfb,0x51,0x73,0x49,0xb4,0x60,0xda,
+	0xe2,0x26,0xaf,0xa9,0x46,0x12,0xb8,0xec,0x50,0xdd,
+	0x12,0x06,0x5f,0xce,0x59,0xe6,0xf6,0x1c,0xe0,0x54,
+	0x10,0xad,0xf6,0xcd,0x98,0xcc,0x0f,0xfb,0xcb,0x41,
+	0x14,0x9d,0xed,0xe4,0xb4,0x74,0x5f,0x09,0x60,0xc7,
+	0x12,0xf6,0x7b,0x3c,0x8f,0xa7,0x20,0xbc,0xe4,0xb1,
+	0xef,0xeb,0xa4,0x93,0xc5,0x06,0xca,0x9a,0x27,0x9d,
+	0x87,0xf3,0xde,0xca,0xe5,0xe7,0xf6,0x1c,0x01,0x65,
+	0x5b,0xfb,0x19,0x79,0x6e,0x08,0x26,0xc5,0xc8,0x28,
+	0x0e,0xb6,0x3b,0x07,0x08,0xc1,0x02,0x82,0x01,0x01,
+	0x00,0xe8,0x1c,0x73,0xa6,0xb8,0xe0,0x0e,0x6d,0x8d,
+	0x1b,0xb9,0x53,0xed,0x58,0x94,0xe6,0x1d,0x60,0x14,
+	0x5c,0x76,0x43,0xc4,0x58,0x19,0xc4,0x24,0xe8,0xbc,
+	0x1b,0x3b,0x0b,0x13,0x24,0x45,0x54,0x0e,0xcc,0x37,
+	0xf0,0xe0,0x63,0x7d,0xc3,0xf7,0xfb,0x81,0x74,0x81,
+	0xc4,0x0f,0x1a,0x21,0x48,0xaf,0xce,0xc1,0xc4,0x94,
+	0x18,0x06,0x44,0x8d,0xd3,0xd2,0x22,0x2d,0x2d,0x3e,
+	0x5a,0x31,0xdc,0x95,0x8e,0xf4,0x41,0xfc,0x58,0xc9,
+	0x40,0x92,0x17,0x5f,0xe3,0xda,0xac,0x9e,0x3f,0x1c,
+	0x2a,0x6b,0x58,0x5f,0x48,0x78,0x20,0xb1,0xaf,0x24,
+	0x9b,0x3c,0x20,0x8b,0x93,0x25,0x9e,0xe6,0x6b,0xbc,
+	0x13,0x42,0x14,0x6c,0x36,0x31,0xff,0x7a,0xd1,0xc1,
+	0x1a,0x26,0x14,0x7f,0xa9,0x76,0xa7,0x0c,0xf8,0xcc,
+	0xed,0x07,0x6a,0xd2,0xdf,0x62,0xee,0x0a,0x7c,0x84,
+	0xcb,0x49,0x90,0xb2,0x03,0x0d,0xa2,0x82,0x06,0x77,
+	0xf1,0xcd,0x67,0xf2,0x47,0x21,0x02,0x3f,0x43,0x21,
+	0xf0,0x46,0x30,0x62,0x51,0x72,0xb1,0xe7,0x48,0xc6,
+	0x67,0x12,0xcd,0x9e,0xd6,0x15,0xe5,0x21,0xed,0xfa,
+	0x8f,0x30,0xa6,0x41,0xfe,0xb6,0xfa,0x8f,0x34,0x14,
+	0x19,0xe8,0x11,0xf7,0xa5,0x77,0x3e,0xb7,0xf9,0x39,
+	0x07,0x8c,0x67,0x2a,0xab,0x7b,0x08,0xf8,0xb0,0x06,
+	0xa8,0xea,0x2f,0x8f,0xfa,0xcc,0xcc,0x40,0xce,0xf3,
+	0x70,0x4f,0x3f,0x7f,0xe2,0x0c,0xea,0x76,0x4a,0x35,
+	0x4e,0x47,0xad,0x2b,0xa7,0x97,0x5d,0x74,0x43,0x97,
+	0x90,0xd2,0xfb,0xd9,0xf9,0x96,0x01,0x33,0x05,0xed,
+	0x7b,0x03,0x05,0xad,0xf8,0x49,0x03,0x02,0x82,0x01,
+	0x01,0x00,0xd4,0x40,0x17,0x66,0x10,0x92,0x95,0xc8,
+	0xec,0x62,0xa9,0x7a,0xcb,0x93,0x8e,0xe6,0x53,0xd4,
+	0x80,0x48,0x27,0x4b,0x41,0xce,0x61,0xdf,0xbf,0x94,
+	0xa4,0x3d,0x71,0x03,0x0b,0xed,0x25,0x71,0x98,0xa4,
+	0xd6,0xd5,0x4a,0x57,0xf5,0x6c,0x1b,0xda,0x21,0x7d,
+	0x35,0x45,0xb3,0xf3,0x6a,0xd9,0xd3,0x43,0xe8,0x5c,
+	0x54,0x1c,0x83,0x1b,0xb4,0x5f,0xf2,0x97,0x24,0x2e,
+	0xdc,0x40,0xde,0x92,0x23,0x59,0x8e,0xbc,0xd2,0xa1,
+	0xf2,0xe0,0x4c,0xdd,0x0b,0xd1,0xe7,0xae,0x65,0xbc,
+	0xb5,0xf5,0x5b,0x98,0xe9,0xd7,0xc2,0xb7,0x0e,0x55,
+	0x71,0x0e,0x3c,0x0a,0x24,0x6b,0xa6,0xe6,0x14,0x61,
+	0x11,0xfd,0x33,0x42,0x99,0x2b,0x84,0x77,0x74,0x92,
+	0x91,0xf5,0x79,0x79,0xcf,0xad,0x8e,0x04,0xef,0x80,
+	0x1e,0x57,0xf4,0x14,0xf5,0x35,0x09,0x74,0xb2,0x13,
+	0x71,0x58,0x6b,0xea,0x32,0x5d,0xf3,0xd3,0x76,0x48,
+	0x39,0x10,0x23,0x84,0x9d,0xbe,0x92,0x77,0x4a,0xed,
+	0x70,0x3e,0x1a,0xa2,0x6c,0xb3,0x81,0x00,0xc3,0xc9,
+	0xe4,0x52,0xc8,0x24,0x88,0x0c,0x41,0xad,0x87,0x5a,
+	0xea,0xa3,0x7a,0x85,0x1c,0x5e,0x31,0x7f,0xc3,0x35,
+	0xc6,0xfa,0x10,0xc8,0x75,0x10,0xc4,0x96,0x99,0xe7,
+	0xfe,0x01,0xb4,0x74,0xdb,0xb4,0x11,0xc3,0xc8,0x8c,
+	0xf6,0xf7,0x3b,0x66,0x50,0xfc,0xdb,0xeb,0xca,0x47,
+	0x85,0x89,0xe1,0x65,0xd9,0x62,0x34,0x3c,0x70,0xd8,
+	0x2e,0xb4,0x2f,0x65,0x3c,0x4a,0xa6,0x2a,0xe7,0xc7,
+	0xd8,0x41,0x8f,0x8a,0x43,0xbf,0x42,0xf2,0x4d,0xbc,
+	0xfc,0x9e,0x27,0x95,0xfb,0x75,0xff,0xab,0x02,0x82,
+	0x01,0x00,0x41,0x2f,0x44,0x57,0x6d,0x12,0x17,0x5b,
+	0x32,0xc6,0xb7,0x6c,0x57,0x7a,0x8a,0x0e,0x79,0xef,
+	0x72,0xa8,0x68,0xda,0x2d,0x38,0xe4,0xbb,0x8d,0xf6,
+	0x02,0x65,0xcf,0x56,0x13,0xe1,0x1a,0xcb,0x39,0x80,
+	0xa6,0xb1,0x32,0x03,0x1e,0xdd,0xbb,0x35,0xd9,0xac,
+	0x43,0x89,0x31,0x08,0x90,0x92,0x5e,0x35,0x3d,0x7b,
+	0x9c,0x6f,0x86,0xcb,0x17,0xdd,0x85,0xe4,0xed,0x35,
+	0x08,0x8e,0xc1,0xf4,0x05,0xd8,0x68,0xc6,0x63,0x3c,
+	0xf7,0xff,0xf7,0x47,0x33,0x39,0xc5,0x3e,0xb7,0x0e,
+	0x58,0x35,0x9d,0x81,0xea,0xf8,0x6a,0x2c,0x1c,0x5a,
+	0x68,0x78,0x64,0x11,0x6b,0xc1,0x3e,0x4e,0x7a,0xbd,
+	0x84,0xcb,0x0f,0xc2,0xb6,0x85,0x1d,0xd3,0x76,0xc5,
+	0x93,0x6a,0x69,0x89,0x56,0x34,0xdc,0x4a,0x9b,0xbc,
+	0xff,0xa8,0x0d,0x6e,0x35,0x9c,0x60,0xa7,0x23,0x30,
+	0xc7,0x06,0x64,0x39,0x8b,0x94,0x89,0xee,0xba,0x7f,
+	0x60,0x8d,0xfa,0xb6,0x97,0x76,0xdc,0x51,0x4a,0x3c,
+	0xeb,0x3a,0x14,0x2c,0x20,0x60,0x69,0x4a,0x86,0xfe,
+	0x8c,0x21,0x84,0x49,0x54,0xb3,0x20,0xe1,0x01,0x7f,
+	0x58,0xdf,0x7f,0xb5,0x21,0x51,0x8c,0x47,0x9f,0x91,
+	0xeb,0x97,0x3e,0xf2,0x54,0xcf,0x16,0x46,0xf9,0xd9,
+	0xb6,0xe7,0x64,0xc9,0xd0,0x54,0xea,0x2f,0xa1,0xcf,
+	0xa5,0x7f,0x28,0x8d,0x84,0xec,0xd5,0x39,0x03,0x76,
+	0x5b,0x2d,0x8e,0x43,0xf2,0x01,0x24,0xc9,0x6f,0xc0,
+	0xf5,0x69,0x6f,0x7d,0xb5,0x85,0xd2,0x5f,0x7f,0x78,
+	0x40,0x07,0x7f,0x09,0x15,0xb5,0x1f,0x28,0x65,0x10,
+	0xe4,0x19,0xa8,0xc6,0x9e,0x8d,0xdc,0xcb,0x02,0x82,
+	0x01,0x00,0x13,0x01,0xee,0x56,0x80,0x93,0x70,0x00,
+	0x7f,0x52,0xd2,0x94,0xa1,0x98,0x84,0x4a,0x92,0x25,
+	0x4c,0x9b,0xa9,0x91,0x2e,0xc2,0x79,0xb7,0x5c,0xe3,
+	0xc5,0xd5,0x8e,0xc2,0x54,0x16,0x17,0xad,0x55,0x9b,
+	0x25,0x76,0x12,0x63,0x50,0x22,0x2f,0x58,0x58,0x79,
+	0x6b,0x04,0xe3,0xf9,0x9f,0x8f,0x04,0x41,0x67,0x94,
+	0xa5,0x1f,0xac,0x8a,0x15,0x9c,0x26,0x10,0x6c,0xf8,
+	0x19,0x57,0x61,0xd7,0x3a,0x7d,0x31,0xb0,0x2d,0x38,
+	0xbd,0x94,0x62,0xad,0xc4,0xfa,0x36,0x42,0x42,0xf0,
+	0x24,0x67,0x65,0x9d,0x8b,0x0b,0x7c,0x6f,0x82,0x44,
+	0x1a,0x8c,0xc8,0xc9,0xab,0xbb,0x4c,0x45,0xfc,0x7b,
+	0x38,0xee,0x30,0xe1,0xfc,0xef,0x8d,0xbc,0x58,0xdf,
+	0x2b,0x5d,0x0d,0x54,0xe0,0x49,0x4d,0x97,0x99,0x8f,
+	0x22,0xa8,0x83,0xbe,0x40,0xbb,0x50,0x2e,0x78,0x28,
+	0x0f,0x95,0x78,0x8c,0x8f,0x98,0x24,0x56,0xc2,0x97,
+	0xf3,0x2c,0x43,0xd2,0x03,0x82,0x66,0x81,0x72,0x5f,
+	0x53,0x16,0xec,0xb1,0xb1,0x04,0x5e,0x40,0x20,0x48,
+	0x7b,0x3f,0x02,0x97,0x6a,0xeb,0x96,0x12,0x21,0x35,
+	0xfe,0x1f,0x47,0xc0,0x95,0xea,0xc5,0x8a,0x08,0x84,
+	0x4f,0x5e,0x63,0x94,0x60,0x0f,0x71,0x5b,0x7f,0x4a,
+	0xec,0x4f,0x60,0xc6,0xba,0x4a,0x24,0xf1,0x20,0x8b,
+	0xa7,0x2e,0x3a,0xce,0x8d,0xe0,0x27,0x1d,0xb5,0x8e,
+	0xb4,0x21,0xc5,0xe2,0xa6,0x16,0x0a,0x51,0x83,0x55,
+	0x88,0xd1,0x30,0x11,0x63,0xd5,0xd7,0x8d,0xae,0x16,
+	0x12,0x82,0xc4,0x85,0x00,0x4e,0x27,0x83,0xa5,0x7c,
+	0x90,0x2e,0xe5,0xa2,0xa3,0xd3,0x4c,0x63,0x02,0x82,
+	0x01,0x01,0x00,0x86,0x08,0x98,0x98,0xa5,0x00,0x05,
+	0x39,0x77,0xd9,0x66,0xb3,0xcf,0xca,0xa0,0x71,0xb3,
+	0x50,0xce,0x3d,0xb1,0x93,0x95,0x35,0xc4,0xd4,0x2e,
+	0x90,0xdf,0x0f,0xfc,0x60,0xc1,0x94,0x68,0x61,0x43,
+	0xca,0x9a,0x23,0x4a,0x1e,0x45,0x72,0x99,0xb5,0x1e,
+	0x61,0x8d,0x77,0x0f,0xa0,0xbb,0xd7,0x77,0xb4,0x2a,
+	0x15,0x11,0x88,0x2d,0xb3,0x56,0x61,0x5e,0x6a,0xed,
+	0xa4,0x46,0x4a,0x3f,0x50,0x11,0xd6,0xba,0xb6,0xd7,
+	0x95,0x65,0x53,0xc3,0xa1,0x8f,0xe0,0xa3,0xf5,0x1c,
+	0xfd,0xaf,0x6e,0x43,0xd7,0x17,0xa7,0xd3,0x81,0x1b,
+	0xa4,0xdf,0xe0,0x97,0x8a,0x46,0x03,0xd3,0x46,0x0e,
+	0x83,0x48,0x4e,0xd2,0x02,0xcb,0xc0,0xad,0x79,0x95,
+	0x8c,0x96,0xba,0x40,0x34,0x11,0x71,0x5e,0xe9,0x11,
+	0xf9,0xc5,0x4a,0x5e,0x91,0x9d,0xf5,0x92,0x4f,0xeb,
+	0xc6,0x70,0x02,0x2d,0x3d,0x04,0xaa,0xe9,0x3a,0x8e,
+	0xd5,0xa8,0xad,0xf7,0xce,0x0d,0x16,0xb2,0xec,0x0a,
+	0x9c,0xf5,0x94,0x39,0xb9,0x8a,0xfc,0x1e,0xf9,0xcc,
+	0xf2,0x5f,0x21,0x31,0x74,0x72,0x6b,0x64,0xae,0x35,
+	0x61,0x8d,0x0d,0xcb,0xe7,0xda,0x39,0xca,0xf3,0x21,
+	0x66,0x0b,0x95,0xd7,0x0a,0x7c,0xca,0xa1,0xa9,0x5a,
+	0xe8,0xac,0xe0,0x71,0x54,0xaf,0x28,0xcf,0xd5,0x70,
+	0x89,0xe0,0xf3,0x9e,0x43,0x6c,0x8d,0x7b,0x99,0x01,
+	0x68,0x4d,0xa1,0x45,0x46,0x0c,0x43,0xbc,0xcc,0x2c,
+	0xdd,0xc5,0x46,0xc8,0x4e,0x0e,0xbe,0xed,0xb9,0x26,
+	0xab,0x2e,0xdb,0xeb,0x8f,0xff,0xdb,0xb0,0xc6,0x55,
+	0xaf,0xf8,0x2a,0x91,0x9d,0x50,0x44,0x21,0x17,
+	};
diff --git a/openssl/apps/timeouts.h b/openssl/apps/timeouts.h
new file mode 100644
index 0000000..89b5dc7
--- /dev/null
+++ b/openssl/apps/timeouts.h
@@ -0,0 +1,67 @@
+/* apps/timeouts.h */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef INCLUDED_TIMEOUTS_H
+#define INCLUDED_TIMEOUTS_H
+
+/* numbers in us */
+#define DGRAM_RCV_TIMEOUT         250000
+#define DGRAM_SND_TIMEOUT         250000
+
+#endif /* ! INCLUDED_TIMEOUTS_H */
diff --git a/openssl/apps/ts.c b/openssl/apps/ts.c
new file mode 100644
index 0000000..5fa9f7f
--- /dev/null
+++ b/openssl/apps/ts.c
@@ -0,0 +1,1147 @@
+/* apps/ts.c */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/ts.h>
+#include <openssl/bn.h>
+
+#undef PROG
+#define PROG	ts_main
+
+/* Length of the nonce of the request in bits (must be a multiple of 8). */
+#define	NONCE_LENGTH		64
+
+/* Macro definitions for the configuration file. */
+#define	ENV_OID_FILE		"oid_file"
+
+/* Local function declarations. */
+
+static ASN1_OBJECT *txt2obj(const char *oid);
+static CONF *load_config_file(const char *configfile);
+
+/* Query related functions. */
+static int query_command(const char *data, char *digest,
+			 const EVP_MD *md, const char *policy, int no_nonce, 
+			 int cert, const char *in, const char *out, int text);
+static BIO *BIO_open_with_default(const char *file, const char *mode, 
+				  FILE *default_fp);
+static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md,
+			    const char *policy, int no_nonce, int cert);
+static int create_digest(BIO *input, char *digest,
+			 const EVP_MD *md, unsigned char **md_value);
+static ASN1_INTEGER *create_nonce(int bits);
+
+/* Reply related functions. */
+static int reply_command(CONF *conf, char *section, char *engine, 
+			 char *queryfile, char *passin, char *inkey, 
+			 char *signer, char *chain, const char *policy, 
+			 char *in, int token_in, char *out, int token_out,
+			 int text);
+static TS_RESP *read_PKCS7(BIO *in_bio);
+static TS_RESP *create_response(CONF *conf, const char *section, char *engine,
+				char *queryfile, char *passin, char *inkey,
+				char *signer, char *chain, const char *policy);
+static ASN1_INTEGER * MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data);
+static ASN1_INTEGER *next_serial(const char *serialfile);
+static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial);
+
+/* Verify related functions. */
+static int verify_command(char *data, char *digest, char *queryfile,
+			  char *in, int token_in,
+			  char *ca_path, char *ca_file, char *untrusted);
+static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, 
+					char *queryfile, 
+					char *ca_path, char *ca_file,
+					char *untrusted);
+static X509_STORE *create_cert_store(char *ca_path, char *ca_file);
+static int MS_CALLBACK verify_cb(int ok, X509_STORE_CTX *ctx);
+
+/* Main function definition. */
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	int ret = 1;
+	char *configfile = NULL;
+	char *section = NULL;
+	CONF *conf = NULL;
+	enum mode {
+	CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY 
+	} mode = CMD_NONE;
+	char *data = NULL;
+	char *digest = NULL;
+	const EVP_MD *md = NULL;
+	char *rnd = NULL;
+	char *policy = NULL;
+	int no_nonce = 0;
+	int cert = 0;
+	char *in = NULL;
+	char *out = NULL;
+	int text = 0;
+	char *queryfile = NULL;
+	char *passin = NULL;	/* Password source. */
+	char *password =NULL;	/* Password itself. */
+	char *inkey = NULL;
+	char *signer = NULL;
+	char *chain = NULL;
+	char *ca_path = NULL;
+	char *ca_file = NULL;
+	char *untrusted = NULL;
+	char *engine = NULL;
+	/* Input is ContentInfo instead of TimeStampResp. */
+	int token_in = 0;	
+	/* Output is ContentInfo instead of TimeStampResp. */
+	int token_out = 0;
+	int free_bio_err = 0;
+
+	ERR_load_crypto_strings();
+	apps_startup();
+
+	if (bio_err == NULL && (bio_err = BIO_new(BIO_s_file())) != NULL)
+		{
+		free_bio_err = 1;
+		BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
+		}
+
+	if (!load_config(bio_err, NULL))
+		goto cleanup;
+
+	for (argc--, argv++; argc > 0; argc--, argv++)
+		{
+		if (strcmp(*argv, "-config") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			configfile = *++argv;
+			}
+		else if (strcmp(*argv, "-section") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			section = *++argv;
+			}
+		else if (strcmp(*argv, "-query") == 0)
+			{
+			if (mode != CMD_NONE) goto usage;
+			mode = CMD_QUERY;
+			}
+		else if (strcmp(*argv, "-data") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			data = *++argv;
+			}
+		else if (strcmp(*argv, "-digest") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			digest = *++argv;
+			}
+		else if (strcmp(*argv, "-rand") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			rnd = *++argv;
+			}
+		else if (strcmp(*argv, "-policy") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			policy = *++argv;
+			}
+		else if (strcmp(*argv, "-no_nonce") == 0)
+			{
+			no_nonce = 1;
+			}
+		else if (strcmp(*argv, "-cert") == 0)
+			{
+			cert = 1;
+			}
+		else if (strcmp(*argv, "-in") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			in = *++argv;
+			}
+		else if (strcmp(*argv, "-token_in") == 0)
+			{
+			token_in = 1;
+			}
+		else if (strcmp(*argv, "-out") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			out = *++argv;
+			}
+		else if (strcmp(*argv, "-token_out") == 0)
+			{
+			token_out = 1;
+			}
+		else if (strcmp(*argv, "-text") == 0)
+			{
+			text = 1;
+			}
+		else if (strcmp(*argv, "-reply") == 0)
+			{
+			if (mode != CMD_NONE) goto usage;
+			mode = CMD_REPLY;
+			}
+		else if (strcmp(*argv, "-queryfile") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			queryfile = *++argv;
+			}
+		else if (strcmp(*argv, "-passin") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			passin = *++argv;
+			}
+		else if (strcmp(*argv, "-inkey") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			inkey = *++argv;
+			}
+		else if (strcmp(*argv, "-signer") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			signer = *++argv;
+			}
+		else if (strcmp(*argv, "-chain") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			chain = *++argv;
+			}
+		else if (strcmp(*argv, "-verify") == 0)
+			{
+			if (mode != CMD_NONE) goto usage;
+			mode = CMD_VERIFY;
+			}
+		else if (strcmp(*argv, "-CApath") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			ca_path = *++argv;
+			}
+		else if (strcmp(*argv, "-CAfile") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			ca_file = *++argv;
+			}
+		else if (strcmp(*argv, "-untrusted") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			untrusted = *++argv;
+			}
+		else if (strcmp(*argv, "-engine") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			engine = *++argv;
+			}
+		else if ((md = EVP_get_digestbyname(*argv + 1)) != NULL)
+			{
+			/* empty. */
+			}
+		else
+			goto usage;
+		}
+	
+	/* Seed the random number generator if it is going to be used. */
+	if (mode == CMD_QUERY && !no_nonce)
+		{
+		if (!app_RAND_load_file(NULL, bio_err, 1) && rnd == NULL)
+			BIO_printf(bio_err, "warning, not much extra random "
+				   "data, consider using the -rand option\n");
+		if (rnd != NULL)
+			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+				   app_RAND_load_files(rnd));
+		}
+
+	/* Get the password if required. */
+	if(mode == CMD_REPLY && passin &&
+	   !app_passwd(bio_err, passin, NULL, &password, NULL))
+		{
+		BIO_printf(bio_err,"Error getting password.\n");
+		goto cleanup;
+		}
+
+	/* Check consistency of parameters and execute 
+	   the appropriate function. */
+	switch (mode)
+		{
+	case CMD_NONE:
+		goto usage;
+	case CMD_QUERY:
+		/* Data file and message imprint cannot be specified
+		   at the same time. */
+		ret = data != NULL && digest != NULL;
+		if (ret) goto usage;
+		/* Load the config file for possible policy OIDs. */
+		conf = load_config_file(configfile);
+		ret = !query_command(data, digest, md, policy, no_nonce, cert,
+				     in, out, text);
+		break;
+	case CMD_REPLY:
+		conf = load_config_file(configfile);
+		if (in == NULL)
+			{
+			ret = !(queryfile != NULL && conf != NULL && !token_in);
+			if (ret) goto usage;
+			}
+		else
+			{
+			/* 'in' and 'queryfile' are exclusive. */
+			ret = !(queryfile == NULL);
+			if (ret) goto usage;
+			}
+
+		ret = !reply_command(conf, section, engine, queryfile, 
+				     password, inkey, signer, chain, policy, 
+				     in, token_in, out, token_out, text);
+		break;
+	case CMD_VERIFY:
+		ret = !(((queryfile && !data && !digest)
+			 || (!queryfile && data && !digest)
+			 || (!queryfile && !data && digest))
+			&& in != NULL);
+		if (ret) goto usage;
+
+		ret = !verify_command(data, digest, queryfile, in, token_in,
+				      ca_path, ca_file, untrusted);
+		}
+
+	goto cleanup;
+
+ usage:
+	BIO_printf(bio_err, "usage:\n"
+		   "ts -query [-rand file%cfile%c...] [-config configfile] "
+		   "[-data file_to_hash] [-digest digest_bytes]"
+		   "[-md2|-md4|-md5|-sha|-sha1|-mdc2|-ripemd160] "
+		   "[-policy object_id] [-no_nonce] [-cert] "
+		   "[-in request.tsq] [-out request.tsq] [-text]\n",
+		   LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+	BIO_printf(bio_err, "or\n"
+		   "ts -reply [-config configfile] [-section tsa_section] "
+		   "[-queryfile request.tsq] [-passin password] "
+		   "[-signer tsa_cert.pem] [-inkey private_key.pem] "
+		   "[-chain certs_file.pem] [-policy object_id] "
+		   "[-in response.tsr] [-token_in] "
+		   "[-out response.tsr] [-token_out] [-text] [-engine id]\n");
+	BIO_printf(bio_err, "or\n"
+		   "ts -verify [-data file_to_hash] [-digest digest_bytes] "
+		   "[-queryfile request.tsq] "
+		   "-in response.tsr [-token_in] "
+		   "-CApath ca_path -CAfile ca_file.pem "
+		   "-untrusted cert_file.pem\n");
+ cleanup:
+	/* Clean up. */
+	app_RAND_write_file(NULL, bio_err);
+	NCONF_free(conf);
+	OPENSSL_free(password);
+	OBJ_cleanup();
+	if (free_bio_err)
+		{
+		BIO_free_all(bio_err);
+		bio_err = NULL;
+		}
+
+	OPENSSL_EXIT(ret);
+	}
+
+/*
+ * Configuration file-related function definitions.
+ */
+
+static ASN1_OBJECT *txt2obj(const char *oid)
+	{
+	ASN1_OBJECT *oid_obj = NULL;
+
+	if (!(oid_obj = OBJ_txt2obj(oid, 0)))
+		BIO_printf(bio_err, "cannot convert %s to OID\n", oid);
+
+	return oid_obj;
+	}
+
+static CONF *load_config_file(const char *configfile)
+	{
+	CONF *conf = NULL;
+	long errorline = -1;
+
+	if (!configfile) configfile = getenv("OPENSSL_CONF");
+	if (!configfile) configfile = getenv("SSLEAY_CONF");
+
+	if (configfile &&
+	    (!(conf = NCONF_new(NULL)) ||
+	     NCONF_load(conf, configfile, &errorline) <= 0))
+		{
+		if (errorline <= 0)
+			BIO_printf(bio_err, "error loading the config file "
+				   "'%s'\n", configfile);
+		else
+			BIO_printf(bio_err, "error on line %ld of config file "
+				   "'%s'\n", errorline, configfile);
+		}
+
+	if (conf != NULL)
+		{
+		const char *p;
+
+		BIO_printf(bio_err,"Using configuration from %s\n", configfile);
+		p = NCONF_get_string(conf, NULL, ENV_OID_FILE);
+		if (p != NULL)
+			{
+			BIO *oid_bio = BIO_new_file(p, "r");
+			if (!oid_bio) 
+				ERR_print_errors(bio_err);
+			else
+				{
+				OBJ_create_objects(oid_bio);
+				BIO_free_all(oid_bio);
+				}
+			}
+		else
+			ERR_clear_error();
+		if(!add_oid_section(bio_err, conf)) 
+			ERR_print_errors(bio_err);
+		}
+	return conf;
+	}
+
+/*
+ * Query-related method definitions.
+ */
+
+static int query_command(const char *data, char *digest, const EVP_MD *md,
+			 const char *policy, int no_nonce, 
+			 int cert, const char *in, const char *out, int text)
+	{
+	int ret = 0;
+	TS_REQ *query = NULL;
+	BIO *in_bio = NULL;
+	BIO *data_bio = NULL;
+	BIO *out_bio = NULL;
+
+	/* Build query object either from file or from scratch. */
+	if (in != NULL)
+		{
+		if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end;
+		query = d2i_TS_REQ_bio(in_bio, NULL);
+		}
+	else
+		{
+		/* Open the file if no explicit digest bytes were specified. */
+		if (!digest 
+		    && !(data_bio = BIO_open_with_default(data, "rb", stdin)))
+			goto end;
+		/* Creating the query object. */
+		query = create_query(data_bio, digest, md,
+				     policy, no_nonce, cert);
+		/* Saving the random number generator state. */
+		}
+	if (query == NULL) goto end;
+
+	/* Write query either in ASN.1 or in text format. */
+	if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL)
+		goto end;
+	if (text)
+		{
+		/* Text output. */
+		if (!TS_REQ_print_bio(out_bio, query))
+			goto end;
+		}
+	else
+		{
+		/* ASN.1 output. */
+		if (!i2d_TS_REQ_bio(out_bio, query))
+			goto end;
+		}
+
+	ret = 1;
+
+ end:
+	ERR_print_errors(bio_err);
+
+	/* Clean up. */
+	BIO_free_all(in_bio);
+	BIO_free_all(data_bio);
+	BIO_free_all(out_bio);
+	TS_REQ_free(query);
+
+	return ret;
+	}
+
+static BIO *BIO_open_with_default(const char *file, const char *mode, 
+				  FILE *default_fp)
+	{
+	return file == NULL ? 
+		BIO_new_fp(default_fp, BIO_NOCLOSE) 
+		: BIO_new_file(file, mode);
+	}
+
+static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md,
+			    const char *policy, int no_nonce, int cert)
+	{
+	int ret = 0;
+	TS_REQ *ts_req = NULL;
+	int len;
+	TS_MSG_IMPRINT *msg_imprint = NULL;
+	X509_ALGOR *algo = NULL;
+	unsigned char *data = NULL;
+	ASN1_OBJECT *policy_obj = NULL;
+	ASN1_INTEGER *nonce_asn1 = NULL;
+
+	/* Setting default message digest. */
+	if (!md && !(md = EVP_get_digestbyname("sha1"))) goto err;
+
+	/* Creating request object. */
+	if (!(ts_req = TS_REQ_new())) goto err;
+
+	/* Setting version. */
+	if (!TS_REQ_set_version(ts_req, 1)) goto err;
+
+	/* Creating and adding MSG_IMPRINT object. */
+	if (!(msg_imprint = TS_MSG_IMPRINT_new())) goto err;
+
+	/* Adding algorithm. */
+	if (!(algo = X509_ALGOR_new())) goto err;
+	if (!(algo->algorithm = OBJ_nid2obj(EVP_MD_type(md)))) goto err;
+	if (!(algo->parameter = ASN1_TYPE_new())) goto err;
+	algo->parameter->type = V_ASN1_NULL;
+	if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo)) goto err;
+
+	/* Adding message digest. */
+	if ((len = create_digest(data_bio, digest, md, &data)) == 0)
+		goto err;
+	if (!TS_MSG_IMPRINT_set_msg(msg_imprint, data, len)) goto err;
+
+	if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint)) goto err;
+	
+	/* Setting policy if requested. */
+	if (policy && !(policy_obj = txt2obj(policy))) goto err;
+	if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj)) goto err;
+
+	/* Setting nonce if requested. */
+	if (!no_nonce && !(nonce_asn1 = create_nonce(NONCE_LENGTH))) goto err;
+	if (nonce_asn1 && !TS_REQ_set_nonce(ts_req, nonce_asn1)) goto err;
+
+	/* Setting certificate request flag if requested. */
+	if (!TS_REQ_set_cert_req(ts_req, cert)) goto err;
+
+	ret = 1;
+ err:
+	if (!ret)
+		{
+		TS_REQ_free(ts_req);
+		ts_req = NULL;
+		BIO_printf(bio_err, "could not create query\n");
+		}
+	TS_MSG_IMPRINT_free(msg_imprint);
+	X509_ALGOR_free(algo);
+	OPENSSL_free(data);
+	ASN1_OBJECT_free(policy_obj);
+	ASN1_INTEGER_free(nonce_asn1);
+	return ts_req;
+	}
+
+static int create_digest(BIO *input, char *digest, const EVP_MD *md,
+			 unsigned char **md_value)
+	{
+	int md_value_len;
+
+	md_value_len = EVP_MD_size(md);
+	if (md_value_len < 0)
+	    goto err;
+	if (input)
+		{
+		/* Digest must be computed from an input file. */
+		EVP_MD_CTX md_ctx;
+		unsigned char buffer[4096];
+		int length;
+
+		*md_value = OPENSSL_malloc(md_value_len);
+		if (*md_value == 0) goto err;
+
+		EVP_DigestInit(&md_ctx, md);
+		while ((length = BIO_read(input, buffer, sizeof(buffer))) > 0)
+			{
+			EVP_DigestUpdate(&md_ctx, buffer, length);
+			}
+		EVP_DigestFinal(&md_ctx, *md_value, NULL);
+		}
+	else
+		{
+		/* Digest bytes are specified with digest. */
+		long digest_len;
+		*md_value = string_to_hex(digest, &digest_len);
+		if (!*md_value || md_value_len != digest_len)
+			{
+			OPENSSL_free(*md_value);
+			*md_value = NULL;
+			BIO_printf(bio_err, "bad digest, %d bytes "
+				   "must be specified\n", md_value_len);
+			goto err;
+			}
+		}
+
+	return md_value_len;
+ err:
+	return 0;
+	}
+
+static ASN1_INTEGER *create_nonce(int bits)
+	{
+	unsigned char buf[20];
+	ASN1_INTEGER *nonce = NULL;
+	int len = (bits - 1) / 8 + 1;
+	int i;
+
+	/* Generating random byte sequence. */
+	if (len > (int)sizeof(buf)) goto err;
+	if (RAND_bytes(buf, len) <= 0) goto err;
+
+	/* Find the first non-zero byte and creating ASN1_INTEGER object. */
+	for (i = 0; i < len && !buf[i]; ++i);
+	if (!(nonce = ASN1_INTEGER_new())) goto err;
+	OPENSSL_free(nonce->data);
+	/* Allocate at least one byte. */
+	nonce->length = len - i;
+	if (!(nonce->data = OPENSSL_malloc(nonce->length + 1))) goto err;
+	memcpy(nonce->data, buf + i, nonce->length);
+
+	return nonce;
+ err:
+	BIO_printf(bio_err, "could not create nonce\n");
+	ASN1_INTEGER_free(nonce);
+	return NULL;
+	}
+/*
+ * Reply-related method definitions.
+ */
+
+static int reply_command(CONF *conf, char *section, char *engine, 
+			 char *queryfile, char *passin, char *inkey,
+			 char *signer, char *chain, const char *policy, 
+			 char *in, int token_in,
+			 char *out, int token_out, int text)
+	{
+	int ret = 0;
+	TS_RESP *response = NULL;
+	BIO *in_bio = NULL;
+	BIO *query_bio = NULL;
+	BIO *inkey_bio = NULL;
+	BIO *signer_bio = NULL;
+	BIO *out_bio = NULL;
+
+	/* Build response object either from response or query. */
+	if (in != NULL)
+		{
+		if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end;
+		if (token_in)
+			{
+			/* We have a ContentInfo (PKCS7) object, add
+			   'granted' status info around it. */
+			response = read_PKCS7(in_bio);
+			}
+		else
+			{
+			/* We have a ready-made TS_RESP object. */
+			response = d2i_TS_RESP_bio(in_bio, NULL);
+			}
+		}
+	else
+		{
+		response = create_response(conf, section, engine, queryfile,
+					   passin, inkey, signer, chain,
+					   policy);
+		if (response)
+			BIO_printf(bio_err, "Response has been generated.\n");
+		else
+			BIO_printf(bio_err, "Response is not generated.\n");
+		}
+	if (response == NULL) goto end;
+
+	/* Write response either in ASN.1 or text format. */
+	if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL)
+		goto end;
+	if (text)
+		{
+		/* Text output. */
+		if (token_out)
+			{
+			TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response);
+			if (!TS_TST_INFO_print_bio(out_bio, tst_info)) goto end;
+			}
+		else
+			{
+			if (!TS_RESP_print_bio(out_bio, response)) goto end;
+			}
+		}
+	else
+		{
+		/* ASN.1 DER output. */
+		if (token_out)
+			{
+			PKCS7 *token = TS_RESP_get_token(response);
+			if (!i2d_PKCS7_bio(out_bio, token)) goto end;
+			}
+		else
+			{
+			if (!i2d_TS_RESP_bio(out_bio, response)) goto end;
+			}
+		}
+
+	ret = 1;
+
+ end:
+	ERR_print_errors(bio_err);
+
+	/* Clean up. */
+	BIO_free_all(in_bio);
+	BIO_free_all(query_bio);
+	BIO_free_all(inkey_bio);
+	BIO_free_all(signer_bio);
+	BIO_free_all(out_bio);
+	TS_RESP_free(response);
+
+	return ret;
+	}
+
+/* Reads a PKCS7 token and adds default 'granted' status info to it. */
+static TS_RESP *read_PKCS7(BIO *in_bio)
+	{
+	int ret = 0;
+	PKCS7 *token = NULL;
+	TS_TST_INFO *tst_info = NULL;
+	TS_RESP *resp = NULL;
+	TS_STATUS_INFO *si = NULL;
+
+	/* Read PKCS7 object and extract the signed time stamp info. */
+	if (!(token = d2i_PKCS7_bio(in_bio, NULL))) goto end;
+	if (!(tst_info = PKCS7_to_TS_TST_INFO(token))) goto end;
+
+	/* Creating response object. */
+	if (!(resp = TS_RESP_new())) goto end;
+
+	/* Create granted status info. */
+	if (!(si = TS_STATUS_INFO_new())) goto end;
+	if (!(ASN1_INTEGER_set(si->status, TS_STATUS_GRANTED))) goto end;
+	if (!TS_RESP_set_status_info(resp, si)) goto end;
+
+	/* Setting encapsulated token. */
+	TS_RESP_set_tst_info(resp, token, tst_info);
+	token = NULL;		/* Ownership is lost. */
+	tst_info = NULL;	/* Ownership is lost. */
+
+	ret = 1;
+ end:
+	PKCS7_free(token);
+	TS_TST_INFO_free(tst_info);
+	if (!ret)
+		{
+		TS_RESP_free(resp);
+		resp = NULL;
+		}
+	TS_STATUS_INFO_free(si);
+	return resp;
+	}
+
+static TS_RESP *create_response(CONF *conf, const char *section, char *engine, 
+				char *queryfile, char *passin, char *inkey,
+				char *signer, char *chain, const char *policy)
+	{
+	int ret = 0;
+	TS_RESP *response = NULL;
+	BIO *query_bio = NULL;
+	TS_RESP_CTX *resp_ctx = NULL;
+
+	if (!(query_bio = BIO_new_file(queryfile, "rb")))
+		goto end;
+
+	/* Getting TSA configuration section. */
+	if (!(section = TS_CONF_get_tsa_section(conf, section)))
+		goto end;
+
+	/* Setting up response generation context. */
+	if (!(resp_ctx = TS_RESP_CTX_new())) goto end;
+
+	/* Setting serial number provider callback. */
+	if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx)) goto end;
+#ifndef OPENSSL_NO_ENGINE
+	/* Setting default OpenSSL engine. */
+	if (!TS_CONF_set_crypto_device(conf, section, engine)) goto end;
+#endif
+
+	/* Setting TSA signer certificate. */
+	if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx)) goto end;
+
+	/* Setting TSA signer certificate chain. */
+	if (!TS_CONF_set_certs(conf, section, chain, resp_ctx)) goto end;
+
+	/* Setting TSA signer private key. */
+	if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx))
+		goto end;
+
+	/* Setting default policy OID. */
+	if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx)) goto end;
+
+	/* Setting acceptable policy OIDs. */
+	if (!TS_CONF_set_policies(conf, section, resp_ctx)) goto end;
+
+	/* Setting the acceptable one-way hash algorithms. */
+	if (!TS_CONF_set_digests(conf, section, resp_ctx)) goto end;
+
+	/* Setting guaranteed time stamp accuracy. */
+	if (!TS_CONF_set_accuracy(conf, section, resp_ctx)) goto end;
+
+	/* Setting the precision of the time. */
+	if (!TS_CONF_set_clock_precision_digits(conf, section, resp_ctx))
+		goto end;
+
+	/* Setting the ordering flaf if requested. */
+	if (!TS_CONF_set_ordering(conf, section, resp_ctx)) goto end;
+
+	/* Setting the TSA name required flag if requested. */
+	if (!TS_CONF_set_tsa_name(conf, section, resp_ctx)) goto end;
+
+	/* Setting the ESS cert id chain flag if requested. */
+	if (!TS_CONF_set_ess_cert_id_chain(conf, section, resp_ctx)) goto end;
+
+	/* Creating the response. */
+	if (!(response = TS_RESP_create_response(resp_ctx, query_bio)))
+		goto end;
+
+	ret = 1;
+ end:
+	if (!ret) 
+		{
+		TS_RESP_free(response);
+		response = NULL;
+		}
+	TS_RESP_CTX_free(resp_ctx);
+	BIO_free_all(query_bio);
+
+	return response;
+	}
+
+static ASN1_INTEGER * MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data)
+	{
+	const char *serial_file = (const char *) data;
+	ASN1_INTEGER *serial = next_serial(serial_file);
+
+	if (!serial)
+		{
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+					    "Error during serial number "
+					    "generation.");
+		TS_RESP_CTX_add_failure_info(ctx,
+					     TS_INFO_ADD_INFO_NOT_AVAILABLE);
+		}
+	else
+		save_ts_serial(serial_file, serial);
+
+	return serial;
+	}
+
+static ASN1_INTEGER *next_serial(const char *serialfile)
+	{
+	int ret = 0;
+	BIO *in = NULL;
+	ASN1_INTEGER *serial = NULL;
+	BIGNUM *bn = NULL;
+
+	if (!(serial = ASN1_INTEGER_new())) goto err;
+
+	if (!(in = BIO_new_file(serialfile, "r"))) 
+		{
+		ERR_clear_error();
+		BIO_printf(bio_err, "Warning: could not open file %s for "
+			   "reading, using serial number: 1\n", serialfile);
+		if (!ASN1_INTEGER_set(serial, 1)) goto err;
+		}
+	else
+		{
+		char buf[1024];
+		if (!a2i_ASN1_INTEGER(in, serial, buf, sizeof(buf)))
+			{
+			BIO_printf(bio_err, "unable to load number from %s\n",
+				   serialfile);
+			goto err;
+			}
+		if (!(bn = ASN1_INTEGER_to_BN(serial, NULL))) goto err;
+		ASN1_INTEGER_free(serial);
+		serial = NULL;
+		if (!BN_add_word(bn, 1)) goto err;
+		if (!(serial = BN_to_ASN1_INTEGER(bn, NULL))) goto err;
+		}
+	ret = 1;
+ err:
+	if (!ret)
+		{
+		ASN1_INTEGER_free(serial);
+		serial = NULL;
+		}
+	BIO_free_all(in);
+	BN_free(bn);
+	return serial;
+	}
+
+static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial)
+	{
+	int ret = 0;
+	BIO *out = NULL;
+
+	if (!(out = BIO_new_file(serialfile, "w"))) goto err;
+	if (i2a_ASN1_INTEGER(out, serial) <= 0) goto err;
+	if (BIO_puts(out, "\n") <= 0) goto err;
+	ret = 1;
+ err:
+	if (!ret)
+		BIO_printf(bio_err, "could not save serial number to %s\n",
+			   serialfile);
+	BIO_free_all(out);
+	return ret;
+	}
+
+/*
+ * Verify-related method definitions.
+ */
+
+static int verify_command(char *data, char *digest, char *queryfile,
+			  char *in, int token_in,
+			  char *ca_path, char *ca_file, char *untrusted)
+	{
+	BIO *in_bio = NULL;
+	PKCS7 *token = NULL;
+	TS_RESP *response = NULL;
+	TS_VERIFY_CTX *verify_ctx = NULL;
+	int ret = 0;
+
+	/* Decode the token (PKCS7) or response (TS_RESP) files. */
+	if (!(in_bio = BIO_new_file(in, "rb"))) goto end;
+	if (token_in)
+		{
+		if (!(token = d2i_PKCS7_bio(in_bio, NULL))) goto end;
+		}
+	else
+		{
+		if (!(response = d2i_TS_RESP_bio(in_bio, NULL))) goto end;
+		}
+
+	if (!(verify_ctx = create_verify_ctx(data, digest, queryfile, 
+					     ca_path, ca_file, untrusted)))
+		goto end;
+
+	/* Checking the token or response against the request. */
+	ret = token_in ?
+		TS_RESP_verify_token(verify_ctx, token) :
+		TS_RESP_verify_response(verify_ctx, response);
+
+ end:
+	printf("Verification: ");
+	if (ret)
+		printf("OK\n");
+	else
+		{
+		printf("FAILED\n");
+		/* Print errors, if there are any. */
+		ERR_print_errors(bio_err);
+		}
+	
+	/* Clean up. */
+	BIO_free_all(in_bio);
+	PKCS7_free(token);
+	TS_RESP_free(response);
+	TS_VERIFY_CTX_free(verify_ctx);
+	return ret;
+	}
+
+static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, 
+					char *queryfile, 
+					char *ca_path, char *ca_file,
+					char *untrusted)
+	{
+	TS_VERIFY_CTX *ctx = NULL;
+	BIO *input = NULL;
+	TS_REQ *request = NULL;
+	int ret = 0;
+
+	if (data != NULL || digest != NULL)
+		{
+		if (!(ctx = TS_VERIFY_CTX_new())) goto err;
+		ctx->flags = TS_VFY_VERSION | TS_VFY_SIGNER;
+		if (data != NULL)
+			{
+			ctx->flags |= TS_VFY_DATA;
+			if (!(ctx->data = BIO_new_file(data, "rb"))) goto err;
+			}
+		else if (digest != NULL)
+			{
+			long imprint_len;
+			ctx->flags |= TS_VFY_IMPRINT;
+			if (!(ctx->imprint = string_to_hex(digest,
+							   &imprint_len)))
+				{
+				BIO_printf(bio_err, "invalid digest string\n");
+				goto err;
+				}
+			ctx->imprint_len = imprint_len;
+			}
+		
+		}
+	else if (queryfile != NULL)
+		{
+		/* The request has just to be read, decoded and converted to
+		   a verify context object. */
+		if (!(input = BIO_new_file(queryfile, "rb"))) goto err;
+		if (!(request = d2i_TS_REQ_bio(input, NULL))) goto err;
+		if (!(ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL))) goto err;
+		}
+	else
+		return NULL;
+
+	/* Add the signature verification flag and arguments. */
+	ctx->flags |= TS_VFY_SIGNATURE;
+
+	/* Initialising the X509_STORE object. */
+	if (!(ctx->store = create_cert_store(ca_path, ca_file))) goto err;
+
+	/* Loading untrusted certificates. */
+	if (untrusted && !(ctx->certs = TS_CONF_load_certs(untrusted))) 
+		goto err;
+
+	ret = 1;
+ err:
+	if (!ret)
+		{
+		TS_VERIFY_CTX_free(ctx);
+		ctx = NULL;
+		}
+	BIO_free_all(input);
+	TS_REQ_free(request);
+	return ctx;
+	}
+
+static X509_STORE *create_cert_store(char *ca_path, char *ca_file)
+	{
+	X509_STORE *cert_ctx = NULL;
+	X509_LOOKUP *lookup = NULL;
+	int i;
+
+	/* Creating the X509_STORE object. */
+	cert_ctx = X509_STORE_new();
+
+	/* Setting the callback for certificate chain verification. */
+	X509_STORE_set_verify_cb(cert_ctx, verify_cb);
+
+	/* Adding a trusted certificate directory source. */
+	if (ca_path)
+		{
+		lookup = X509_STORE_add_lookup(cert_ctx,
+					       X509_LOOKUP_hash_dir());
+		if (lookup == NULL)
+			{
+			BIO_printf(bio_err, "memory allocation failure\n");
+			goto err;
+			}
+		i = X509_LOOKUP_add_dir(lookup, ca_path, X509_FILETYPE_PEM);
+		if (!i)
+			{
+			BIO_printf(bio_err, "Error loading directory %s\n",
+				   ca_path);
+			goto err;
+			}
+		}
+
+	/* Adding a trusted certificate file source. */
+	if (ca_file)
+		{
+		lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
+		if (lookup == NULL)
+			{
+			BIO_printf(bio_err, "memory allocation failure\n");
+			goto err;
+			}
+		i = X509_LOOKUP_load_file(lookup, ca_file, X509_FILETYPE_PEM);
+		if (!i)
+			{
+			BIO_printf(bio_err, "Error loading file %s\n", ca_file);
+			goto err;
+			}
+		}
+
+	return cert_ctx;
+ err:
+	X509_STORE_free(cert_ctx);
+	return NULL;
+	}
+
+static int MS_CALLBACK verify_cb(int ok, X509_STORE_CTX *ctx)
+	{
+	/*
+	char buf[256];
+
+	if (!ok)
+		{
+		X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),
+				  buf, sizeof(buf));
+		printf("%s\n", buf);
+		printf("error %d at %d depth lookup: %s\n",
+		       ctx->error, ctx->error_depth,
+			X509_verify_cert_error_string(ctx->error));
+		}
+	*/
+
+	return ok;
+	}
diff --git a/openssl/apps/tsget b/openssl/apps/tsget
new file mode 100644
index 0000000..0d54e9f
--- /dev/null
+++ b/openssl/apps/tsget
@@ -0,0 +1,196 @@
+#!/usr/bin/perl -w
+# Written by Zoltan Glozik <zglozik@stones.com>.
+# Copyright (c) 2002 The OpenTSA Project.  All rights reserved.
+$::version = '$Id: tsget,v 1.1.2.2 2009/09/07 17:57:02 steve Exp $';
+
+use strict;
+use IO::Handle;
+use Getopt::Std;
+use File::Basename;
+use WWW::Curl::Easy;
+
+use vars qw(%options);
+
+# Callback for reading the body.
+sub read_body {
+    my ($maxlength, $state) = @_;
+    my $return_data = "";
+    my $data_len = length ${$state->{data}};
+    if ($state->{bytes} < $data_len) {
+	$data_len = $data_len - $state->{bytes};
+	$data_len = $maxlength if $data_len > $maxlength;
+	$return_data = substr ${$state->{data}}, $state->{bytes}, $data_len;
+	$state->{bytes} += $data_len;
+    }
+    return $return_data;
+}
+
+# Callback for writing the body into a variable.
+sub write_body {
+    my ($data, $pointer) = @_;
+    ${$pointer} .= $data;
+    return length($data);
+}
+
+# Initialise a new Curl object.
+sub create_curl {
+    my $url = shift;
+
+    # Create Curl object.
+    my $curl = WWW::Curl::Easy::new();
+
+    # Error-handling related options.
+    $curl->setopt(CURLOPT_VERBOSE, 1) if $options{d};
+    $curl->setopt(CURLOPT_FAILONERROR, 1);
+    $curl->setopt(CURLOPT_USERAGENT, "OpenTSA tsget.pl/" . (split / /, $::version)[2]);
+
+    # Options for POST method.
+    $curl->setopt(CURLOPT_UPLOAD, 1);
+    $curl->setopt(CURLOPT_CUSTOMREQUEST, "POST");
+    $curl->setopt(CURLOPT_HTTPHEADER,
+		["Content-Type: application/timestamp-query",
+		"Accept: application/timestamp-reply,application/timestamp-response"]);
+    $curl->setopt(CURLOPT_READFUNCTION, \&read_body);
+    $curl->setopt(CURLOPT_HEADERFUNCTION, sub { return length($_[0]); });
+
+    # Options for getting the result.
+    $curl->setopt(CURLOPT_WRITEFUNCTION, \&write_body);
+
+    # SSL related options.
+    $curl->setopt(CURLOPT_SSLKEYTYPE, "PEM");
+    $curl->setopt(CURLOPT_SSL_VERIFYPEER, 1);	# Verify server's certificate.
+    $curl->setopt(CURLOPT_SSL_VERIFYHOST, 2);	# Check server's CN.
+    $curl->setopt(CURLOPT_SSLKEY, $options{k}) if defined($options{k});
+    $curl->setopt(CURLOPT_SSLKEYPASSWD, $options{p}) if defined($options{p});
+    $curl->setopt(CURLOPT_SSLCERT, $options{c}) if defined($options{c});
+    $curl->setopt(CURLOPT_CAINFO, $options{C}) if defined($options{C});
+    $curl->setopt(CURLOPT_CAPATH, $options{P}) if defined($options{P});
+    $curl->setopt(CURLOPT_RANDOM_FILE, $options{r}) if defined($options{r});
+    $curl->setopt(CURLOPT_EGDSOCKET, $options{g}) if defined($options{g});
+
+    # Setting destination.
+    $curl->setopt(CURLOPT_URL, $url);
+
+    return $curl;
+}
+
+# Send a request and returns the body back.
+sub get_timestamp {
+    my $curl = shift;
+    my $body = shift;
+    my $ts_body;
+    local $::error_buf;
+
+    # Error-handling related options.
+    $curl->setopt(CURLOPT_ERRORBUFFER, "::error_buf");
+
+    # Options for POST method.
+    $curl->setopt(CURLOPT_INFILE, {data => $body, bytes => 0});
+    $curl->setopt(CURLOPT_INFILESIZE, length(${$body}));
+
+    # Options for getting the result.
+    $curl->setopt(CURLOPT_FILE, \$ts_body);
+
+    # Send the request...
+    my $error_code = $curl->perform();
+    my $error_string;
+    if ($error_code != 0) {
+        my $http_code = $curl->getinfo(CURLINFO_HTTP_CODE);
+	$error_string = "could not get timestamp";
+	$error_string .= ", http code: $http_code" unless $http_code == 0;
+	$error_string .= ", curl code: $error_code";
+	$error_string .= " ($::error_buf)" if defined($::error_buf);
+    } else {
+        my $ct = $curl->getinfo(CURLINFO_CONTENT_TYPE);
+	if (lc($ct) ne "application/timestamp-reply"
+	    && lc($ct) ne "application/timestamp-response") {
+	    $error_string = "unexpected content type returned: $ct";
+        }
+    }
+    return ($ts_body, $error_string);
+
+}
+
+# Print usage information and exists.
+sub usage {
+
+    print STDERR "usage: $0 -h <server_url> [-e <extension>] [-o <output>] ";
+    print STDERR "[-v] [-d] [-k <private_key.pem>] [-p <key_password>] ";
+    print STDERR "[-c <client_cert.pem>] [-C <CA_certs.pem>] [-P <CA_path>] ";
+    print STDERR "[-r <file:file...>] [-g <EGD_socket>] [<request>]...\n";
+    exit 1;
+}
+
+# ----------------------------------------------------------------------
+#   Main program
+# ----------------------------------------------------------------------
+
+# Getting command-line options (default comes from TSGET environment variable).
+my $getopt_arg =  "h:e:o:vdk:p:c:C:P:r:g:";
+if (exists $ENV{TSGET}) {
+    my @old_argv = @ARGV;
+    @ARGV = split /\s+/, $ENV{TSGET};
+    getopts($getopt_arg, \%options) or usage;
+    @ARGV = @old_argv;
+}
+getopts($getopt_arg, \%options) or usage;
+
+# Checking argument consistency.
+if (!exists($options{h}) || (@ARGV == 0 && !exists($options{o}))
+    || (@ARGV > 1 && exists($options{o}))) {
+    print STDERR "Inconsistent command line options.\n";
+    usage;
+}
+# Setting defaults.
+@ARGV = ("-") unless @ARGV != 0;
+$options{e} = ".tsr" unless defined($options{e});
+
+# Processing requests.
+my $curl = create_curl $options{h};
+undef $/;   # For reading whole files.
+REQUEST: foreach (@ARGV) {
+    my $input = $_;
+    my ($base, $path) = fileparse($input, '\.[^.]*');
+    my $output_base = $base . $options{e};
+    my $output = defined($options{o}) ? $options{o} : $path . $output_base;
+
+    STDERR->printflush("$input: ") if $options{v};
+    # Read request.
+    my $body;
+    if ($input eq "-") {
+	# Read the request from STDIN;
+	$body = <STDIN>;
+    } else {
+	# Read the request from file.
+        open INPUT, "<" . $input
+	    or warn("$input: could not open input file: $!\n"), next REQUEST;
+        $body = <INPUT>;
+        close INPUT
+	    or warn("$input: could not close input file: $!\n"), next REQUEST;
+    }
+
+    # Send request.
+    STDERR->printflush("sending request") if $options{v};
+
+    my ($ts_body, $error) = get_timestamp $curl, \$body;
+    if (defined($error)) {
+	die "$input: fatal error: $error\n";
+    }
+    STDERR->printflush(", reply received") if $options{v};
+
+    # Write response.
+    if ($output eq "-") {
+	# Write to STDOUT.
+        print $ts_body;
+    } else {
+	# Write to file.
+        open OUTPUT, ">", $output
+	    or warn("$output: could not open output file: $!\n"), next REQUEST;
+        print OUTPUT $ts_body;
+        close OUTPUT
+	    or warn("$output: could not close output file: $!\n"), next REQUEST;
+    }
+    STDERR->printflush(", $output written.\n") if $options{v};
+}
+$curl->cleanup();
+WWW::Curl::Easy::global_cleanup();
diff --git a/openssl/apps/verify.c b/openssl/apps/verify.c
new file mode 100644
index 0000000..9163997
--- /dev/null
+++ b/openssl/apps/verify.c
@@ -0,0 +1,350 @@
+/* apps/verify.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/pem.h>
+
+#undef PROG
+#define PROG	verify_main
+
+static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx);
+static int check(X509_STORE *ctx, char *file,
+		STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
+		STACK_OF(X509_CRL) *crls, ENGINE *e);
+static int v_verbose=0, vflags = 0;
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	ENGINE *e = NULL;
+	int i,ret=1, badarg = 0;
+	char *CApath=NULL,*CAfile=NULL;
+	char *untfile = NULL, *trustfile = NULL, *crlfile = NULL;
+	STACK_OF(X509) *untrusted = NULL, *trusted = NULL;
+	STACK_OF(X509_CRL) *crls = NULL;
+	X509_STORE *cert_ctx=NULL;
+	X509_LOOKUP *lookup=NULL;
+	X509_VERIFY_PARAM *vpm = NULL;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+
+	cert_ctx=X509_STORE_new();
+	if (cert_ctx == NULL) goto end;
+	X509_STORE_set_verify_cb(cert_ctx,cb);
+
+	ERR_load_crypto_strings();
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	argc--;
+	argv++;
+	for (;;)
+		{
+		if (argc >= 1)
+			{
+			if (strcmp(*argv,"-CApath") == 0)
+				{
+				if (argc-- < 1) goto end;
+				CApath= *(++argv);
+				}
+			else if (strcmp(*argv,"-CAfile") == 0)
+				{
+				if (argc-- < 1) goto end;
+				CAfile= *(++argv);
+				}
+			else if (args_verify(&argv, &argc, &badarg, bio_err,
+									&vpm))
+				{
+				if (badarg)
+					goto end;
+				continue;
+				}
+			else if (strcmp(*argv,"-untrusted") == 0)
+				{
+				if (argc-- < 1) goto end;
+				untfile= *(++argv);
+				}
+			else if (strcmp(*argv,"-trusted") == 0)
+				{
+				if (argc-- < 1) goto end;
+				trustfile= *(++argv);
+				}
+			else if (strcmp(*argv,"-CRLfile") == 0)
+				{
+				if (argc-- < 1) goto end;
+				crlfile= *(++argv);
+				}
+#ifndef OPENSSL_NO_ENGINE
+			else if (strcmp(*argv,"-engine") == 0)
+				{
+				if (--argc < 1) goto end;
+				engine= *(++argv);
+				}
+#endif
+			else if (strcmp(*argv,"-help") == 0)
+				goto end;
+			else if (strcmp(*argv,"-verbose") == 0)
+				v_verbose=1;
+			else if (argv[0][0] == '-')
+				goto end;
+			else
+				break;
+			argc--;
+			argv++;
+			}
+		else
+			break;
+		}
+
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine, 0);
+#endif
+
+	if (vpm)
+		X509_STORE_set1_param(cert_ctx, vpm);
+
+	lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_file());
+	if (lookup == NULL) abort();
+	if (CAfile) {
+		i=X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM);
+		if(!i) {
+			BIO_printf(bio_err, "Error loading file %s\n", CAfile);
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+	} else X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
+		
+	lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_hash_dir());
+	if (lookup == NULL) abort();
+	if (CApath) {
+		i=X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM);
+		if(!i) {
+			BIO_printf(bio_err, "Error loading directory %s\n", CApath);
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+	} else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
+
+	ERR_clear_error();
+
+	if(untfile)
+		{
+		untrusted = load_certs(bio_err, untfile, FORMAT_PEM,
+					NULL, e, "untrusted certificates");
+		if(!untrusted)
+			goto end;
+		}
+
+	if(trustfile)
+		{
+		trusted = load_certs(bio_err, trustfile, FORMAT_PEM,
+					NULL, e, "trusted certificates");
+		if(!trusted)
+			goto end;
+		}
+
+	if(crlfile)
+		{
+		crls = load_crls(bio_err, crlfile, FORMAT_PEM,
+					NULL, e, "other CRLs");
+		if(!crls)
+			goto end;
+		}
+
+	if (argc < 1) check(cert_ctx, NULL, untrusted, trusted, crls, e);
+	else
+		for (i=0; i<argc; i++)
+			check(cert_ctx,argv[i], untrusted, trusted, crls, e);
+	ret=0;
+end:
+	if (ret == 1) {
+		BIO_printf(bio_err,"usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose purpose] [-crl_check]");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err," [-engine e]");
+#endif
+		BIO_printf(bio_err," cert1 cert2 ...\n");
+		BIO_printf(bio_err,"recognized usages:\n");
+		for(i = 0; i < X509_PURPOSE_get_count(); i++) {
+			X509_PURPOSE *ptmp;
+			ptmp = X509_PURPOSE_get0(i);
+			BIO_printf(bio_err, "\t%-10s\t%s\n", X509_PURPOSE_get0_sname(ptmp),
+								X509_PURPOSE_get0_name(ptmp));
+		}
+	}
+	if (vpm) X509_VERIFY_PARAM_free(vpm);
+	if (cert_ctx != NULL) X509_STORE_free(cert_ctx);
+	sk_X509_pop_free(untrusted, X509_free);
+	sk_X509_pop_free(trusted, X509_free);
+	sk_X509_CRL_pop_free(crls, X509_CRL_free);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
+static int check(X509_STORE *ctx, char *file,
+		STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
+		STACK_OF(X509_CRL) *crls, ENGINE *e)
+	{
+	X509 *x=NULL;
+	int i=0,ret=0;
+	X509_STORE_CTX *csc;
+
+	x = load_cert(bio_err, file, FORMAT_PEM, NULL, e, "certificate file");
+	if (x == NULL)
+		goto end;
+	fprintf(stdout,"%s: ",(file == NULL)?"stdin":file);
+
+	csc = X509_STORE_CTX_new();
+	if (csc == NULL)
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+	X509_STORE_set_flags(ctx, vflags);
+	if(!X509_STORE_CTX_init(csc,ctx,x,uchain))
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+	if(tchain) X509_STORE_CTX_trusted_stack(csc, tchain);
+	if (crls)
+		X509_STORE_CTX_set0_crls(csc, crls);
+	i=X509_verify_cert(csc);
+	X509_STORE_CTX_free(csc);
+
+	ret=0;
+end:
+	if (i > 0)
+		{
+		fprintf(stdout,"OK\n");
+		ret=1;
+		}
+	else
+		ERR_print_errors(bio_err);
+	if (x != NULL) X509_free(x);
+
+	return(ret);
+	}
+
+static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx)
+	{
+	int cert_error = X509_STORE_CTX_get_error(ctx);
+	X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
+
+	if (!ok)
+		{
+		if (current_cert)
+			{
+			X509_NAME_print_ex_fp(stdout,
+				X509_get_subject_name(current_cert),
+				0, XN_FLAG_ONELINE);
+			printf("\n");
+			}
+		printf("%serror %d at %d depth lookup:%s\n",
+			X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path]" : "",
+			cert_error,
+			X509_STORE_CTX_get_error_depth(ctx),
+			X509_verify_cert_error_string(cert_error));
+		switch(cert_error)
+			{
+			case X509_V_ERR_NO_EXPLICIT_POLICY:
+				policies_print(NULL, ctx);
+			case X509_V_ERR_CERT_HAS_EXPIRED:
+
+			/* since we are just checking the certificates, it is
+			 * ok if they are self signed. But we should still warn
+			 * the user.
+			 */
+
+			case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+			/* Continue after extension errors too */
+			case X509_V_ERR_INVALID_CA:
+			case X509_V_ERR_INVALID_NON_CA:
+			case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+			case X509_V_ERR_INVALID_PURPOSE:
+			case X509_V_ERR_CRL_HAS_EXPIRED:
+			case X509_V_ERR_CRL_NOT_YET_VALID:
+			case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
+			ok = 1;
+
+			}
+
+		return ok;
+
+		}
+	if (cert_error == X509_V_OK && ok == 2)
+		policies_print(NULL, ctx);
+	if (!v_verbose)
+		ERR_clear_error();
+	return(ok);
+	}
diff --git a/openssl/apps/version.c b/openssl/apps/version.c
new file mode 100644
index 0000000..e9555cb
--- /dev/null
+++ b/openssl/apps/version.c
@@ -0,0 +1,217 @@
+/* apps/version.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/evp.h>
+#include <openssl/crypto.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_MD2
+# include <openssl/md2.h>
+#endif
+#ifndef OPENSSL_NO_RC4
+# include <openssl/rc4.h>
+#endif
+#ifndef OPENSSL_NO_DES
+# include <openssl/des.h>
+#endif
+#ifndef OPENSSL_NO_IDEA
+# include <openssl/idea.h>
+#endif
+#ifndef OPENSSL_NO_BF
+# include <openssl/blowfish.h>
+#endif
+
+#undef PROG
+#define PROG	version_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	int i,ret=0;
+	int cflags=0,version=0,date=0,options=0,platform=0,dir=0;
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	if (argc == 1) version=1;
+	for (i=1; i<argc; i++)
+		{
+		if (strcmp(argv[i],"-v") == 0)
+			version=1;	
+		else if (strcmp(argv[i],"-b") == 0)
+			date=1;
+		else if (strcmp(argv[i],"-f") == 0)
+			cflags=1;
+		else if (strcmp(argv[i],"-o") == 0)
+			options=1;
+		else if (strcmp(argv[i],"-p") == 0)
+			platform=1;
+		else if (strcmp(argv[i],"-d") == 0)
+			dir=1;
+		else if (strcmp(argv[i],"-a") == 0)
+			date=version=cflags=options=platform=dir=1;
+		else
+			{
+			BIO_printf(bio_err,"usage:version -[avbofpd]\n");
+			ret=1;
+			goto end;
+			}
+		}
+
+	if (version)
+		{
+		if (SSLeay() == SSLEAY_VERSION_NUMBER)
+			{
+			printf("%s\n",SSLeay_version(SSLEAY_VERSION));
+			}
+		else
+			{
+			printf("%s (Library: %s)\n",
+				OPENSSL_VERSION_TEXT,
+				SSLeay_version(SSLEAY_VERSION));
+			}
+		}
+	if (date)    printf("%s\n",SSLeay_version(SSLEAY_BUILT_ON));
+	if (platform) printf("%s\n",SSLeay_version(SSLEAY_PLATFORM));
+	if (options) 
+		{
+		printf("options:  ");
+		printf("%s ",BN_options());
+#ifndef OPENSSL_NO_MD2
+		printf("%s ",MD2_options());
+#endif
+#ifndef OPENSSL_NO_RC4
+		printf("%s ",RC4_options());
+#endif
+#ifndef OPENSSL_NO_DES
+		printf("%s ",DES_options());
+#endif
+#ifndef OPENSSL_NO_IDEA
+		printf("%s ",idea_options());
+#endif
+#ifndef OPENSSL_NO_BF
+		printf("%s ",BF_options());
+#endif
+		printf("\n");
+		}
+	if (cflags)  printf("%s\n",SSLeay_version(SSLEAY_CFLAGS));
+	if (dir)  printf("%s\n",SSLeay_version(SSLEAY_DIR));
+end:
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
diff --git a/openssl/apps/vms_decc_init.c b/openssl/apps/vms_decc_init.c
new file mode 100644
index 0000000..f512c8f
--- /dev/null
+++ b/openssl/apps/vms_decc_init.c
@@ -0,0 +1,188 @@
+#if defined( __VMS) && !defined( OPENSSL_NO_DECC_INIT) && \
+ defined( __DECC) && !defined( __VAX) && (__CRTL_VER >= 70301000)
+# define USE_DECC_INIT 1
+#endif
+
+#ifdef USE_DECC_INIT
+
+/*
+ * 2010-04-26 SMS.
+ *
+ *----------------------------------------------------------------------
+ *
+ *       decc_init()
+ *
+ *    On non-VAX systems, uses LIB$INITIALIZE to set a collection of C
+ *    RTL features without using the DECC$* logical name method.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unixlib.h>
+
+
+/* Global storage. */
+
+/* Flag to sense if decc_init() was called. */
+
+int decc_init_done = -1;
+
+
+/* Structure to hold a DECC$* feature name and its desired value. */
+
+typedef struct
+{
+    char *name;
+    int value;
+} decc_feat_t;
+
+
+/* Array of DECC$* feature names and their desired values.
+ * Note: DECC$ARGV_PARSE_STYLE is the urgent one.
+ */
+
+decc_feat_t decc_feat_array[] =
+{
+ /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */
+ { "DECC$ARGV_PARSE_STYLE", 1 },
+
+ /* Preserve case for file names on ODS5 disks. */
+ { "DECC$EFS_CASE_PRESERVE", 1 },
+
+ /* Enable multiple dots (and most characters) in ODS5 file names,
+  * while preserving VMS-ness of ";version".
+  */
+ { "DECC$EFS_CHARSET", 1 },
+
+ /* List terminator. */
+ { (char *)NULL, 0 }
+};
+
+
+/* LIB$INITIALIZE initialization function. */
+
+static void decc_init( void)
+{
+    char *openssl_debug_decc_init;
+    int verbose = 0;
+    int feat_index;
+    int feat_value;
+    int feat_value_max;
+    int feat_value_min;
+    int i;
+    int sts;
+
+    /* Get debug option. */
+    openssl_debug_decc_init = getenv( "OPENSSL_DEBUG_DECC_INIT");
+    if (openssl_debug_decc_init != NULL)
+    {
+        verbose = strtol( openssl_debug_decc_init, NULL, 10);
+        if (verbose <= 0)
+        {
+            verbose = 1;
+        }
+    }
+
+    /* Set the global flag to indicate that LIB$INITIALIZE worked. */
+    decc_init_done = 1;
+
+    /* Loop through all items in the decc_feat_array[]. */
+
+    for (i = 0; decc_feat_array[ i].name != NULL; i++)
+    {
+        /* Get the feature index. */
+        feat_index = decc$feature_get_index( decc_feat_array[ i].name);
+        if (feat_index >= 0)
+        {
+            /* Valid item.  Collect its properties. */
+            feat_value = decc$feature_get_value( feat_index, 1);
+            feat_value_min = decc$feature_get_value( feat_index, 2);
+            feat_value_max = decc$feature_get_value( feat_index, 3);
+
+            /* Check the validity of our desired value. */
+            if ((decc_feat_array[ i].value >= feat_value_min) &&
+             (decc_feat_array[ i].value <= feat_value_max))
+            {
+                /* Valid value.  Set it if necessary. */
+                if (feat_value != decc_feat_array[ i].value)
+                {
+                    sts = decc$feature_set_value( feat_index,
+                     1,
+                     decc_feat_array[ i].value);
+
+                     if (verbose > 1)
+                     {
+                         fprintf( stderr, " %s = %d, sts = %d.\n",
+                          decc_feat_array[ i].name,
+                          decc_feat_array[ i].value,
+                          sts);
+                     }
+                }
+            }
+            else
+            {
+                /* Invalid DECC feature value. */
+                fprintf( stderr,
+                 " INVALID DECC$FEATURE VALUE, %d: %d <= %s <= %d.\n",
+                 feat_value,
+                 feat_value_min, decc_feat_array[ i].name, feat_value_max);
+            }
+        }
+        else
+        {
+            /* Invalid DECC feature name. */
+            fprintf( stderr,
+             " UNKNOWN DECC$FEATURE: %s.\n", decc_feat_array[ i].name);
+        }
+    }
+
+    if (verbose > 0)
+    {
+        fprintf( stderr, " DECC_INIT complete.\n");
+    }
+}
+
+/* Get "decc_init()" into a valid, loaded LIB$INITIALIZE PSECT. */
+
+#pragma nostandard
+
+/* Establish the LIB$INITIALIZE PSECTs, with proper alignment and
+ * other attributes.  Note that "nopic" is significant only on VAX.
+ */
+#pragma extern_model save
+
+#if __INITIAL_POINTER_SIZE == 64
+# define PSECT_ALIGN 3
+#else
+# define PSECT_ALIGN 2
+#endif
+
+#pragma extern_model strict_refdef "LIB$INITIALIZ" PSECT_ALIGN, nopic, nowrt
+const int spare[ 8] = { 0 };
+
+#pragma extern_model strict_refdef "LIB$INITIALIZE" PSECT_ALIGN, nopic, nowrt
+void (*const x_decc_init)() = decc_init;
+
+#pragma extern_model restore
+
+/* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */
+
+#pragma extern_model save
+
+int LIB$INITIALIZE( void);
+
+#pragma extern_model strict_refdef
+int dmy_lib$initialize = (int) LIB$INITIALIZE;
+
+#pragma extern_model restore
+
+#pragma standard
+
+#else /* def USE_DECC_INIT */
+
+/* Dummy code to avoid a %CC-W-EMPTYFILE complaint. */
+int decc_init_dummy( void);
+
+#endif /* def USE_DECC_INIT */
diff --git a/openssl/apps/winrand.c b/openssl/apps/winrand.c
new file mode 100644
index 0000000..59bede3
--- /dev/null
+++ b/openssl/apps/winrand.c
@@ -0,0 +1,148 @@
+/* apps/winrand.c */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Usage: winrand [filename]
+ *
+ * Collects entropy from mouse movements and other events and writes
+ * random data to filename or .rnd
+ */
+
+#include <windows.h>
+#include <openssl/opensslv.h>
+#include <openssl/rand.h>
+
+LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
+const char *filename;
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
+        PSTR cmdline, int iCmdShow)
+	{
+	static char appname[] = "OpenSSL";
+	HWND hwnd;
+	MSG msg;
+	WNDCLASSEX wndclass;
+        char buffer[200];
+
+        if (cmdline[0] == '\0')
+                filename = RAND_file_name(buffer, sizeof buffer);
+        else
+                filename = cmdline;
+
+        RAND_load_file(filename, -1);
+
+	wndclass.cbSize = sizeof(wndclass);
+	wndclass.style = CS_HREDRAW | CS_VREDRAW;
+	wndclass.lpfnWndProc = WndProc;
+	wndclass.cbClsExtra = 0;
+	wndclass.cbWndExtra = 0;
+	wndclass.hInstance = hInstance;
+	wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
+	wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
+	wndclass.lpszMenuName = NULL;
+        wndclass.lpszClassName = appname;
+	wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
+	RegisterClassEx(&wndclass);
+
+        hwnd = CreateWindow(appname, OPENSSL_VERSION_TEXT,
+		WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
+		CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
+
+	ShowWindow(hwnd, iCmdShow);
+	UpdateWindow(hwnd);
+
+
+	while (GetMessage(&msg, NULL, 0, 0))
+		{
+		TranslateMessage(&msg);
+		DispatchMessage(&msg);
+		}
+
+	return msg.wParam;
+	}
+
+LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
+	{
+        HDC hdc;
+	PAINTSTRUCT ps;
+        RECT rect;
+        static int seeded = 0;
+
+	switch (iMsg)
+		{
+	case WM_PAINT:
+		hdc = BeginPaint(hwnd, &ps);
+		GetClientRect(hwnd, &rect);
+                DrawText(hdc, "Seeding the PRNG. Please move the mouse!", -1,
+			&rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+		EndPaint(hwnd, &ps);
+		return 0;
+		
+        case WM_DESTROY:
+                PostQuitMessage(0);
+                return 0;
+                }
+
+        if (RAND_event(iMsg, wParam, lParam) == 1 && seeded == 0)
+                {
+                seeded = 1;
+                if (RAND_write_file(filename) <= 0)
+                        MessageBox(hwnd, "Couldn't write random file!",
+				"OpenSSL", MB_OK | MB_ICONERROR);
+                PostQuitMessage(0);
+                }
+
+	return DefWindowProc(hwnd, iMsg, wParam, lParam);
+	}
diff --git a/openssl/apps/x509.c b/openssl/apps/x509.c
new file mode 100644
index 0000000..9f5eaeb
--- /dev/null
+++ b/openssl/apps/x509.c
@@ -0,0 +1,1292 @@
+/* apps/x509.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef OPENSSL_NO_STDIO
+#define APPS_WIN16
+#endif
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+
+#undef PROG
+#define PROG x509_main
+
+#undef POSTFIX
+#define	POSTFIX	".srl"
+#define DEF_DAYS	30
+
+static const char *x509_usage[]={
+"usage: x509 args\n",
+" -inform arg     - input format - default PEM (one of DER, NET or PEM)\n",
+" -outform arg    - output format - default PEM (one of DER, NET or PEM)\n",
+" -keyform arg    - private key format - default PEM\n",
+" -CAform arg     - CA format - default PEM\n",
+" -CAkeyform arg  - CA key format - default PEM\n",
+" -in arg         - input file - default stdin\n",
+" -out arg        - output file - default stdout\n",
+" -passin arg     - private key password source\n",
+" -serial         - print serial number value\n",
+" -subject_hash   - print subject hash value\n",
+#ifndef OPENSSL_NO_MD5
+" -subject_hash_old   - print old-style (MD5) subject hash value\n",
+#endif
+" -issuer_hash    - print issuer hash value\n",
+#ifndef OPENSSL_NO_MD5
+" -issuer_hash_old    - print old-style (MD5) issuer hash value\n",
+#endif
+" -hash           - synonym for -subject_hash\n",
+" -subject        - print subject DN\n",
+" -issuer         - print issuer DN\n",
+" -email          - print email address(es)\n",
+" -startdate      - notBefore field\n",
+" -enddate        - notAfter field\n",
+" -purpose        - print out certificate purposes\n",
+" -dates          - both Before and After dates\n",
+" -modulus        - print the RSA key modulus\n",
+" -pubkey         - output the public key\n",
+" -fingerprint    - print the certificate fingerprint\n",
+" -alias          - output certificate alias\n",
+" -noout          - no certificate output\n",
+" -ocspid         - print OCSP hash values for the subject name and public key\n",
+" -ocsp_uri       - print OCSP Responder URL(s)\n",
+" -trustout       - output a \"trusted\" certificate\n",
+" -clrtrust       - clear all trusted purposes\n",
+" -clrreject      - clear all rejected purposes\n",
+" -addtrust arg   - trust certificate for a given purpose\n",
+" -addreject arg  - reject certificate for a given purpose\n",
+" -setalias arg   - set certificate alias\n",
+" -days arg       - How long till expiry of a signed certificate - def 30 days\n",
+" -checkend arg   - check whether the cert expires in the next arg seconds\n",
+"                   exit 1 if so, 0 if not\n",
+" -signkey arg    - self sign cert with arg\n",
+" -x509toreq      - output a certification request object\n",
+" -req            - input is a certificate request, sign and output.\n",
+" -CA arg         - set the CA certificate, must be PEM format.\n",
+" -CAkey arg      - set the CA key, must be PEM format\n",
+"                   missing, it is assumed to be in the CA file.\n",
+" -CAcreateserial - create serial number file if it does not exist\n",
+" -CAserial arg   - serial file\n",
+" -set_serial     - serial number to use\n",
+" -text           - print the certificate in text form\n",
+" -C              - print out C code forms\n",
+" -md2/-md5/-sha1/-mdc2 - digest to use\n",
+" -extfile        - configuration file with X509V3 extensions to add\n",
+" -extensions     - section from config file with X509V3 extensions to add\n",
+" -clrext         - delete extensions before signing and input certificate\n",
+" -nameopt arg    - various certificate name options\n",
+#ifndef OPENSSL_NO_ENGINE
+" -engine e       - use engine e, possibly a hardware device.\n",
+#endif
+" -certopt arg    - various certificate text options\n",
+NULL
+};
+
+static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx);
+static int sign (X509 *x, EVP_PKEY *pkey,int days,int clrext, const EVP_MD *digest,
+						CONF *conf, char *section);
+static int x509_certify (X509_STORE *ctx,char *CAfile,const EVP_MD *digest,
+			 X509 *x,X509 *xca,EVP_PKEY *pkey,char *serial,
+			 int create,int days, int clrext, CONF *conf, char *section,
+						ASN1_INTEGER *sno);
+static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
+static int reqfile=0;
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	ENGINE *e = NULL;
+	int ret=1;
+	X509_REQ *req=NULL;
+	X509 *x=NULL,*xca=NULL;
+	ASN1_OBJECT *objtmp;
+	EVP_PKEY *Upkey=NULL,*CApkey=NULL;
+	ASN1_INTEGER *sno = NULL;
+	int i,num,badops=0;
+	BIO *out=NULL;
+	BIO *STDout=NULL;
+	STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
+	int informat,outformat,keyformat,CAformat,CAkeyformat;
+	char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL;
+	char *CAkeyfile=NULL,*CAserial=NULL;
+	char *alias=NULL;
+	int text=0,serial=0,subject=0,issuer=0,startdate=0,enddate=0;
+	int next_serial=0;
+	int subject_hash=0,issuer_hash=0,ocspid=0;
+#ifndef OPENSSL_NO_MD5
+	int subject_hash_old=0,issuer_hash_old=0;
+#endif
+	int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0;
+	int ocsp_uri=0;
+	int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0;
+	int C=0;
+	int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0;
+	int pprint = 0;
+	const char **pp;
+	X509_STORE *ctx=NULL;
+	X509_REQ *rq=NULL;
+	int fingerprint=0;
+	char buf[256];
+	const EVP_MD *md_alg,*digest=NULL;
+	CONF *extconf = NULL;
+	char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL;
+	int need_rand = 0;
+	int checkend=0,checkoffset=0;
+	unsigned long nmflag = 0, certflag = 0;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+
+	reqfile=0;
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+	STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+	{
+	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+	STDout = BIO_push(tmpbio, STDout);
+	}
+#endif
+
+	informat=FORMAT_PEM;
+	outformat=FORMAT_PEM;
+	keyformat=FORMAT_PEM;
+	CAformat=FORMAT_PEM;
+	CAkeyformat=FORMAT_PEM;
+
+	ctx=X509_STORE_new();
+	if (ctx == NULL) goto end;
+	X509_STORE_set_verify_cb(ctx,callb);
+
+	argc--;
+	argv++;
+	num=0;
+	while (argc >= 1)
+		{
+		if 	(strcmp(*argv,"-inform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			informat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-outform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outformat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-keyform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			keyformat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-req") == 0)
+			{
+			reqfile=1;
+			need_rand = 1;
+			}
+		else if (strcmp(*argv,"-CAform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			CAformat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-CAkeyform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			CAkeyformat=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-days") == 0)
+			{
+			if (--argc < 1) goto bad;
+			days=atoi(*(++argv));
+			if (days == 0)
+				{
+				BIO_printf(STDout,"bad number of days\n");
+				goto bad;
+				}
+			}
+		else if (strcmp(*argv,"-passin") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passargin= *(++argv);
+			}
+		else if (strcmp(*argv,"-extfile") == 0)
+			{
+			if (--argc < 1) goto bad;
+			extfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-extensions") == 0)
+			{
+			if (--argc < 1) goto bad;
+			extsect= *(++argv);
+			}
+		else if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-signkey") == 0)
+			{
+			if (--argc < 1) goto bad;
+			keyfile= *(++argv);
+			sign_flag= ++num;
+			need_rand = 1;
+			}
+		else if (strcmp(*argv,"-CA") == 0)
+			{
+			if (--argc < 1) goto bad;
+			CAfile= *(++argv);
+			CA_flag= ++num;
+			need_rand = 1;
+			}
+		else if (strcmp(*argv,"-CAkey") == 0)
+			{
+			if (--argc < 1) goto bad;
+			CAkeyfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-CAserial") == 0)
+			{
+			if (--argc < 1) goto bad;
+			CAserial= *(++argv);
+			}
+		else if (strcmp(*argv,"-set_serial") == 0)
+			{
+			if (--argc < 1) goto bad;
+			if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv))))
+				goto bad;
+			}
+		else if (strcmp(*argv,"-addtrust") == 0)
+			{
+			if (--argc < 1) goto bad;
+			if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
+				{
+				BIO_printf(bio_err,
+					"Invalid trust object value %s\n", *argv);
+				goto bad;
+				}
+			if (!trust) trust = sk_ASN1_OBJECT_new_null();
+			sk_ASN1_OBJECT_push(trust, objtmp);
+			trustout = 1;
+			}
+		else if (strcmp(*argv,"-addreject") == 0)
+			{
+			if (--argc < 1) goto bad;
+			if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
+				{
+				BIO_printf(bio_err,
+					"Invalid reject object value %s\n", *argv);
+				goto bad;
+				}
+			if (!reject) reject = sk_ASN1_OBJECT_new_null();
+			sk_ASN1_OBJECT_push(reject, objtmp);
+			trustout = 1;
+			}
+		else if (strcmp(*argv,"-setalias") == 0)
+			{
+			if (--argc < 1) goto bad;
+			alias= *(++argv);
+			trustout = 1;
+			}
+		else if (strcmp(*argv,"-certopt") == 0)
+			{
+			if (--argc < 1) goto bad;
+			if (!set_cert_ex(&certflag, *(++argv))) goto bad;
+			}
+		else if (strcmp(*argv,"-nameopt") == 0)
+			{
+			if (--argc < 1) goto bad;
+			if (!set_name_ex(&nmflag, *(++argv))) goto bad;
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*argv,"-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine= *(++argv);
+			}
+#endif
+		else if (strcmp(*argv,"-C") == 0)
+			C= ++num;
+		else if (strcmp(*argv,"-email") == 0)
+			email= ++num;
+		else if (strcmp(*argv,"-ocsp_uri") == 0)
+			ocsp_uri= ++num;
+		else if (strcmp(*argv,"-serial") == 0)
+			serial= ++num;
+		else if (strcmp(*argv,"-next_serial") == 0)
+			next_serial= ++num;
+		else if (strcmp(*argv,"-modulus") == 0)
+			modulus= ++num;
+		else if (strcmp(*argv,"-pubkey") == 0)
+			pubkey= ++num;
+		else if (strcmp(*argv,"-x509toreq") == 0)
+			x509req= ++num;
+		else if (strcmp(*argv,"-text") == 0)
+			text= ++num;
+		else if (strcmp(*argv,"-hash") == 0
+			|| strcmp(*argv,"-subject_hash") == 0)
+			subject_hash= ++num;
+#ifndef OPENSSL_NO_MD5
+		else if (strcmp(*argv,"-subject_hash_old") == 0)
+			subject_hash_old= ++num;
+#endif
+		else if (strcmp(*argv,"-issuer_hash") == 0)
+			issuer_hash= ++num;
+#ifndef OPENSSL_NO_MD5
+		else if (strcmp(*argv,"-issuer_hash_old") == 0)
+			issuer_hash_old= ++num;
+#endif
+		else if (strcmp(*argv,"-subject") == 0)
+			subject= ++num;
+		else if (strcmp(*argv,"-issuer") == 0)
+			issuer= ++num;
+		else if (strcmp(*argv,"-fingerprint") == 0)
+			fingerprint= ++num;
+		else if (strcmp(*argv,"-dates") == 0)
+			{
+			startdate= ++num;
+			enddate= ++num;
+			}
+		else if (strcmp(*argv,"-purpose") == 0)
+			pprint= ++num;
+		else if (strcmp(*argv,"-startdate") == 0)
+			startdate= ++num;
+		else if (strcmp(*argv,"-enddate") == 0)
+			enddate= ++num;
+		else if (strcmp(*argv,"-checkend") == 0)
+			{
+			if (--argc < 1) goto bad;
+			checkoffset=atoi(*(++argv));
+			checkend=1;
+			}
+		else if (strcmp(*argv,"-noout") == 0)
+			noout= ++num;
+		else if (strcmp(*argv,"-trustout") == 0)
+			trustout= 1;
+		else if (strcmp(*argv,"-clrtrust") == 0)
+			clrtrust= ++num;
+		else if (strcmp(*argv,"-clrreject") == 0)
+			clrreject= ++num;
+		else if (strcmp(*argv,"-alias") == 0)
+			aliasout= ++num;
+		else if (strcmp(*argv,"-CAcreateserial") == 0)
+			CA_createserial= ++num;
+		else if (strcmp(*argv,"-clrext") == 0)
+			clrext = 1;
+#if 1 /* stay backwards-compatible with 0.9.5; this should go away soon */
+		else if (strcmp(*argv,"-crlext") == 0)
+			{
+			BIO_printf(bio_err,"use -clrext instead of -crlext\n");
+			clrext = 1;
+			}
+#endif
+		else if (strcmp(*argv,"-ocspid") == 0)
+			ocspid= ++num;
+		else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
+			{
+			/* ok */
+			digest=md_alg;
+			}
+		else
+			{
+			BIO_printf(bio_err,"unknown option %s\n",*argv);
+			badops=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (badops)
+		{
+bad:
+		for (pp=x509_usage; (*pp != NULL); pp++)
+			BIO_printf(bio_err,"%s",*pp);
+		goto end;
+		}
+
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine, 0);
+#endif
+
+	if (need_rand)
+		app_RAND_load_file(NULL, bio_err, 0);
+
+	ERR_load_crypto_strings();
+
+	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL))
+		{
+		BIO_printf(bio_err, "Error getting password\n");
+		goto end;
+		}
+
+	if (!X509_STORE_set_default_paths(ctx))
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM))
+		{ CAkeyfile=CAfile; }
+	else if ((CA_flag) && (CAkeyfile == NULL))
+		{
+		BIO_printf(bio_err,"need to specify a CAkey if using the CA command\n");
+		goto end;
+		}
+
+	if (extfile)
+		{
+		long errorline = -1;
+		X509V3_CTX ctx2;
+		extconf = NCONF_new(NULL);
+		if (!NCONF_load(extconf, extfile,&errorline))
+			{
+			if (errorline <= 0)
+				BIO_printf(bio_err,
+					"error loading the config file '%s'\n",
+								extfile);
+                	else
+                        	BIO_printf(bio_err,
+				       "error on line %ld of config file '%s'\n"
+							,errorline,extfile);
+			goto end;
+			}
+		if (!extsect)
+			{
+			extsect = NCONF_get_string(extconf, "default", "extensions");
+			if (!extsect)
+				{
+				ERR_clear_error();
+				extsect = "default";
+				}
+			}
+		X509V3_set_ctx_test(&ctx2);
+		X509V3_set_nconf(&ctx2, extconf);
+		if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL))
+			{
+			BIO_printf(bio_err,
+				"Error Loading extension section %s\n",
+								 extsect);
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+
+
+	if (reqfile)
+		{
+		EVP_PKEY *pkey;
+		BIO *in;
+
+		if (!sign_flag && !CA_flag)
+			{
+			BIO_printf(bio_err,"We need a private key to sign with\n");
+			goto end;
+			}
+		in=BIO_new(BIO_s_file());
+		if (in == NULL)
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+
+		if (infile == NULL)
+			BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT);
+		else
+			{
+			if (BIO_read_filename(in,infile) <= 0)
+				{
+				perror(infile);
+				BIO_free(in);
+				goto end;
+				}
+			}
+		req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL);
+		BIO_free(in);
+
+		if (req == NULL)
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+
+		if (	(req->req_info == NULL) ||
+			(req->req_info->pubkey == NULL) ||
+			(req->req_info->pubkey->public_key == NULL) ||
+			(req->req_info->pubkey->public_key->data == NULL))
+			{
+			BIO_printf(bio_err,"The certificate request appears to corrupted\n");
+			BIO_printf(bio_err,"It does not contain a public key\n");
+			goto end;
+			}
+		if ((pkey=X509_REQ_get_pubkey(req)) == NULL)
+	                {
+	                BIO_printf(bio_err,"error unpacking public key\n");
+	                goto end;
+	                }
+		i=X509_REQ_verify(req,pkey);
+		EVP_PKEY_free(pkey);
+		if (i < 0)
+			{
+			BIO_printf(bio_err,"Signature verification error\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+	        if (i == 0)
+			{
+			BIO_printf(bio_err,"Signature did not match the certificate request\n");
+			goto end;
+			}
+		else
+			BIO_printf(bio_err,"Signature ok\n");
+
+		print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag);
+
+		if ((x=X509_new()) == NULL) goto end;
+
+		if (sno == NULL)
+			{
+			sno = ASN1_INTEGER_new();
+			if (!sno || !rand_serial(NULL, sno))
+				goto end;
+			if (!X509_set_serialNumber(x, sno)) 
+				goto end;
+			ASN1_INTEGER_free(sno);
+			sno = NULL;
+			}
+		else if (!X509_set_serialNumber(x, sno)) 
+			goto end;
+
+		if (!X509_set_issuer_name(x,req->req_info->subject)) goto end;
+		if (!X509_set_subject_name(x,req->req_info->subject)) goto end;
+
+		X509_gmtime_adj(X509_get_notBefore(x),0);
+	        X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL);
+
+		pkey = X509_REQ_get_pubkey(req);
+		X509_set_pubkey(x,pkey);
+		EVP_PKEY_free(pkey);
+		}
+	else
+		x=load_cert(bio_err,infile,informat,NULL,e,"Certificate");
+
+	if (x == NULL) goto end;
+	if (CA_flag)
+		{
+		xca=load_cert(bio_err,CAfile,CAformat,NULL,e,"CA Certificate");
+		if (xca == NULL) goto end;
+		}
+
+	if (!noout || text || next_serial)
+		{
+		OBJ_create("2.99999.3",
+			"SET.ex3","SET x509v3 extension 3");
+
+		out=BIO_new(BIO_s_file());
+		if (out == NULL)
+			{
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		if (outfile == NULL)
+			{
+			BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+			{
+			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+			out = BIO_push(tmpbio, out);
+			}
+#endif
+			}
+		else
+			{
+			if (BIO_write_filename(out,outfile) <= 0)
+				{
+				perror(outfile);
+				goto end;
+				}
+			}
+		}
+
+	if (alias) X509_alias_set1(x, (unsigned char *)alias, -1);
+
+	if (clrtrust) X509_trust_clear(x);
+	if (clrreject) X509_reject_clear(x);
+
+	if (trust)
+		{
+		for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++)
+			{
+			objtmp = sk_ASN1_OBJECT_value(trust, i);
+			X509_add1_trust_object(x, objtmp);
+			}
+		}
+
+	if (reject)
+		{
+		for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++)
+			{
+			objtmp = sk_ASN1_OBJECT_value(reject, i);
+			X509_add1_reject_object(x, objtmp);
+			}
+		}
+
+	if (num)
+		{
+		for (i=1; i<=num; i++)
+			{
+			if (issuer == i)
+				{
+				print_name(STDout, "issuer= ",
+					X509_get_issuer_name(x), nmflag);
+				}
+			else if (subject == i) 
+				{
+				print_name(STDout, "subject= ",
+					X509_get_subject_name(x), nmflag);
+				}
+			else if (serial == i)
+				{
+				BIO_printf(STDout,"serial=");
+				i2a_ASN1_INTEGER(STDout,
+					X509_get_serialNumber(x));
+				BIO_printf(STDout,"\n");
+				}
+			else if (next_serial == i)
+				{
+				BIGNUM *bnser;
+				ASN1_INTEGER *ser;
+				ser = X509_get_serialNumber(x);
+				bnser = ASN1_INTEGER_to_BN(ser, NULL);
+				if (!bnser)
+					goto end;
+				if (!BN_add_word(bnser, 1))
+					goto end;
+				ser = BN_to_ASN1_INTEGER(bnser, NULL);
+				if (!ser)
+					goto end;
+				BN_free(bnser);
+				i2a_ASN1_INTEGER(out, ser);
+				ASN1_INTEGER_free(ser);
+				BIO_puts(out, "\n");
+				}
+			else if ((email == i) || (ocsp_uri == i))
+				{
+				int j;
+				STACK_OF(OPENSSL_STRING) *emlst;
+				if (email == i)
+					emlst = X509_get1_email(x);
+				else
+					emlst = X509_get1_ocsp(x);
+				for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
+					BIO_printf(STDout, "%s\n",
+						   sk_OPENSSL_STRING_value(emlst, j));
+				X509_email_free(emlst);
+				}
+			else if (aliasout == i)
+				{
+				unsigned char *alstr;
+				alstr = X509_alias_get0(x, NULL);
+				if (alstr) BIO_printf(STDout,"%s\n", alstr);
+				else BIO_puts(STDout,"<No Alias>\n");
+				}
+			else if (subject_hash == i)
+				{
+				BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x));
+				}
+#ifndef OPENSSL_NO_MD5
+			else if (subject_hash_old == i)
+				{
+				BIO_printf(STDout,"%08lx\n",X509_subject_name_hash_old(x));
+				}
+#endif
+			else if (issuer_hash == i)
+				{
+				BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash(x));
+				}
+#ifndef OPENSSL_NO_MD5
+			else if (issuer_hash_old == i)
+				{
+				BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash_old(x));
+				}
+#endif
+			else if (pprint == i)
+				{
+				X509_PURPOSE *ptmp;
+				int j;
+				BIO_printf(STDout, "Certificate purposes:\n");
+				for (j = 0; j < X509_PURPOSE_get_count(); j++)
+					{
+					ptmp = X509_PURPOSE_get0(j);
+					purpose_print(STDout, x, ptmp);
+					}
+				}
+			else
+				if (modulus == i)
+				{
+				EVP_PKEY *pkey;
+
+				pkey=X509_get_pubkey(x);
+				if (pkey == NULL)
+					{
+					BIO_printf(bio_err,"Modulus=unavailable\n");
+					ERR_print_errors(bio_err);
+					goto end;
+					}
+				BIO_printf(STDout,"Modulus=");
+#ifndef OPENSSL_NO_RSA
+				if (pkey->type == EVP_PKEY_RSA)
+					BN_print(STDout,pkey->pkey.rsa->n);
+				else
+#endif
+#ifndef OPENSSL_NO_DSA
+				if (pkey->type == EVP_PKEY_DSA)
+					BN_print(STDout,pkey->pkey.dsa->pub_key);
+				else
+#endif
+					BIO_printf(STDout,"Wrong Algorithm type");
+				BIO_printf(STDout,"\n");
+				EVP_PKEY_free(pkey);
+				}
+			else
+				if (pubkey == i)
+				{
+				EVP_PKEY *pkey;
+
+				pkey=X509_get_pubkey(x);
+				if (pkey == NULL)
+					{
+					BIO_printf(bio_err,"Error getting public key\n");
+					ERR_print_errors(bio_err);
+					goto end;
+					}
+				PEM_write_bio_PUBKEY(STDout, pkey);
+				EVP_PKEY_free(pkey);
+				}
+			else
+				if (C == i)
+				{
+				unsigned char *d;
+				char *m;
+				int y,z;
+
+				X509_NAME_oneline(X509_get_subject_name(x),
+					buf,sizeof buf);
+				BIO_printf(STDout,"/* subject:%s */\n",buf);
+				m=X509_NAME_oneline(
+					X509_get_issuer_name(x),buf,
+					sizeof buf);
+				BIO_printf(STDout,"/* issuer :%s */\n",buf);
+
+				z=i2d_X509(x,NULL);
+				m=OPENSSL_malloc(z);
+
+				d=(unsigned char *)m;
+				z=i2d_X509_NAME(X509_get_subject_name(x),&d);
+				BIO_printf(STDout,"unsigned char XXX_subject_name[%d]={\n",z);
+				d=(unsigned char *)m;
+				for (y=0; y<z; y++)
+					{
+					BIO_printf(STDout,"0x%02X,",d[y]);
+					if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n");
+					}
+				if (y%16 != 0) BIO_printf(STDout,"\n");
+				BIO_printf(STDout,"};\n");
+
+				z=i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x),&d);
+				BIO_printf(STDout,"unsigned char XXX_public_key[%d]={\n",z);
+				d=(unsigned char *)m;
+				for (y=0; y<z; y++)
+					{
+					BIO_printf(STDout,"0x%02X,",d[y]);
+					if ((y & 0x0f) == 0x0f)
+						BIO_printf(STDout,"\n");
+					}
+				if (y%16 != 0) BIO_printf(STDout,"\n");
+				BIO_printf(STDout,"};\n");
+
+				z=i2d_X509(x,&d);
+				BIO_printf(STDout,"unsigned char XXX_certificate[%d]={\n",z);
+				d=(unsigned char *)m;
+				for (y=0; y<z; y++)
+					{
+					BIO_printf(STDout,"0x%02X,",d[y]);
+					if ((y & 0x0f) == 0x0f)
+						BIO_printf(STDout,"\n");
+					}
+				if (y%16 != 0) BIO_printf(STDout,"\n");
+				BIO_printf(STDout,"};\n");
+
+				OPENSSL_free(m);
+				}
+			else if (text == i)
+				{
+				X509_print_ex(out,x,nmflag, certflag);
+				}
+			else if (startdate == i)
+				{
+				BIO_puts(STDout,"notBefore=");
+				ASN1_TIME_print(STDout,X509_get_notBefore(x));
+				BIO_puts(STDout,"\n");
+				}
+			else if (enddate == i)
+				{
+				BIO_puts(STDout,"notAfter=");
+				ASN1_TIME_print(STDout,X509_get_notAfter(x));
+				BIO_puts(STDout,"\n");
+				}
+			else if (fingerprint == i)
+				{
+				int j;
+				unsigned int n;
+				unsigned char md[EVP_MAX_MD_SIZE];
+				const EVP_MD *fdig = digest;
+
+				if (!fdig)
+					fdig = EVP_sha1();
+
+				if (!X509_digest(x,fdig,md,&n))
+					{
+					BIO_printf(bio_err,"out of memory\n");
+					goto end;
+					}
+				BIO_printf(STDout,"%s Fingerprint=",
+						OBJ_nid2sn(EVP_MD_type(fdig)));
+				for (j=0; j<(int)n; j++)
+					{
+					BIO_printf(STDout,"%02X%c",md[j],
+						(j+1 == (int)n)
+						?'\n':':');
+					}
+				}
+
+			/* should be in the library */
+			else if ((sign_flag == i) && (x509req == 0))
+				{
+				BIO_printf(bio_err,"Getting Private key\n");
+				if (Upkey == NULL)
+					{
+					Upkey=load_key(bio_err,
+						keyfile, keyformat, 0,
+						passin, e, "Private key");
+					if (Upkey == NULL) goto end;
+					}
+
+				assert(need_rand);
+				if (!sign(x,Upkey,days,clrext,digest,
+						 extconf, extsect)) goto end;
+				}
+			else if (CA_flag == i)
+				{
+				BIO_printf(bio_err,"Getting CA Private Key\n");
+				if (CAkeyfile != NULL)
+					{
+					CApkey=load_key(bio_err,
+						CAkeyfile, CAkeyformat,
+						0, passin, e,
+						"CA Private Key");
+					if (CApkey == NULL) goto end;
+					}
+				
+				assert(need_rand);
+				if (!x509_certify(ctx,CAfile,digest,x,xca,
+					CApkey, CAserial,CA_createserial,days, clrext,
+					extconf, extsect, sno))
+					goto end;
+				}
+			else if (x509req == i)
+				{
+				EVP_PKEY *pk;
+
+				BIO_printf(bio_err,"Getting request Private Key\n");
+				if (keyfile == NULL)
+					{
+					BIO_printf(bio_err,"no request key file specified\n");
+					goto end;
+					}
+				else
+					{
+					pk=load_key(bio_err,
+						keyfile, keyformat, 0,
+						passin, e, "request key");
+					if (pk == NULL) goto end;
+					}
+
+				BIO_printf(bio_err,"Generating certificate request\n");
+
+				rq=X509_to_X509_REQ(x,pk,digest);
+				EVP_PKEY_free(pk);
+				if (rq == NULL)
+					{
+					ERR_print_errors(bio_err);
+					goto end;
+					}
+				if (!noout)
+					{
+					X509_REQ_print(out,rq);
+					PEM_write_bio_X509_REQ(out,rq);
+					}
+				noout=1;
+				}
+			else if (ocspid == i)
+				{
+				X509_ocspid_print(out, x);
+				}
+			}
+		}
+
+	if (checkend)
+		{
+		time_t tcheck=time(NULL) + checkoffset;
+
+		if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0)
+			{
+			BIO_printf(out,"Certificate will expire\n");
+			ret=1;
+			}
+		else
+			{
+			BIO_printf(out,"Certificate will not expire\n");
+			ret=0;
+			}
+		goto end;
+		}
+
+	if (noout)
+		{
+		ret=0;
+		goto end;
+		}
+
+	if 	(outformat == FORMAT_ASN1)
+		i=i2d_X509_bio(out,x);
+	else if (outformat == FORMAT_PEM)
+		{
+		if (trustout) i=PEM_write_bio_X509_AUX(out,x);
+		else i=PEM_write_bio_X509(out,x);
+		}
+	else if (outformat == FORMAT_NETSCAPE)
+		{
+		NETSCAPE_X509 nx;
+		ASN1_OCTET_STRING hdr;
+
+		hdr.data=(unsigned char *)NETSCAPE_CERT_HDR;
+		hdr.length=strlen(NETSCAPE_CERT_HDR);
+		nx.header= &hdr;
+		nx.cert=x;
+
+		i=ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509),out,&nx);
+		}
+	else	{
+		BIO_printf(bio_err,"bad output format specified for outfile\n");
+		goto end;
+		}
+	if (!i)
+		{
+		BIO_printf(bio_err,"unable to write certificate\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+	ret=0;
+end:
+	if (need_rand)
+		app_RAND_write_file(NULL, bio_err);
+	OBJ_cleanup();
+	NCONF_free(extconf);
+	BIO_free_all(out);
+	BIO_free_all(STDout);
+	X509_STORE_free(ctx);
+	X509_REQ_free(req);
+	X509_free(x);
+	X509_free(xca);
+	EVP_PKEY_free(Upkey);
+	EVP_PKEY_free(CApkey);
+	X509_REQ_free(rq);
+	ASN1_INTEGER_free(sno);
+	sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
+	sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
+	if (passin) OPENSSL_free(passin);
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
+static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, int create)
+	{
+	char *buf = NULL, *p;
+	ASN1_INTEGER *bs = NULL;
+	BIGNUM *serial = NULL;
+	size_t len;
+
+	len = ((serialfile == NULL)
+		?(strlen(CAfile)+strlen(POSTFIX)+1)
+		:(strlen(serialfile)))+1;
+	buf=OPENSSL_malloc(len);
+	if (buf == NULL) { BIO_printf(bio_err,"out of mem\n"); goto end; }
+	if (serialfile == NULL)
+		{
+		BUF_strlcpy(buf,CAfile,len);
+		for (p=buf; *p; p++)
+			if (*p == '.')
+				{
+				*p='\0';
+				break;
+				}
+		BUF_strlcat(buf,POSTFIX,len);
+		}
+	else
+		BUF_strlcpy(buf,serialfile,len);
+
+	serial = load_serial(buf, create, NULL);
+	if (serial == NULL) goto end;
+
+	if (!BN_add_word(serial,1))
+		{ BIO_printf(bio_err,"add_word failure\n"); goto end; }
+
+	if (!save_serial(buf, NULL, serial, &bs)) goto end;
+
+ end:
+	if (buf) OPENSSL_free(buf);
+	BN_free(serial);
+	return bs;
+	}
+
+static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
+	     X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile, int create,
+	     int days, int clrext, CONF *conf, char *section, ASN1_INTEGER *sno)
+	{
+	int ret=0;
+	ASN1_INTEGER *bs=NULL;
+	X509_STORE_CTX xsc;
+	EVP_PKEY *upkey;
+
+	upkey = X509_get_pubkey(xca);
+	EVP_PKEY_copy_parameters(upkey,pkey);
+	EVP_PKEY_free(upkey);
+
+	if(!X509_STORE_CTX_init(&xsc,ctx,x,NULL))
+		{
+		BIO_printf(bio_err,"Error initialising X509 store\n");
+		goto end;
+		}
+	if (sno) bs = sno;
+	else if (!(bs = x509_load_serial(CAfile, serialfile, create)))
+		goto end;
+
+/*	if (!X509_STORE_add_cert(ctx,x)) goto end;*/
+
+	/* NOTE: this certificate can/should be self signed, unless it was
+	 * a certificate request in which case it is not. */
+	X509_STORE_CTX_set_cert(&xsc,x);
+	X509_STORE_CTX_set_flags(&xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);
+	if (!reqfile && X509_verify_cert(&xsc) <= 0)
+		goto end;
+
+	if (!X509_check_private_key(xca,pkey))
+		{
+		BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
+		goto end;
+		}
+
+	if (!X509_set_issuer_name(x,X509_get_subject_name(xca))) goto end;
+	if (!X509_set_serialNumber(x,bs)) goto end;
+
+	if (X509_gmtime_adj(X509_get_notBefore(x),0L) == NULL)
+		goto end;
+
+	/* hardwired expired */
+	if (X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL) == NULL)
+		goto end;
+
+	if (clrext)
+		{
+		while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0);
+		}
+
+	if (conf)
+		{
+		X509V3_CTX ctx2;
+		X509_set_version(x,2); /* version 3 certificate */
+                X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
+                X509V3_set_nconf(&ctx2, conf);
+                if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) goto end;
+		}
+
+	if (!X509_sign(x,pkey,digest)) goto end;
+	ret=1;
+end:
+	X509_STORE_CTX_cleanup(&xsc);
+	if (!ret)
+		ERR_print_errors(bio_err);
+	if (!sno) ASN1_INTEGER_free(bs);
+	return ret;
+	}
+
+static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx)
+	{
+	int err;
+	X509 *err_cert;
+
+	/* it is ok to use a self signed certificate
+	 * This case will catch both the initial ok == 0 and the
+	 * final ok == 1 calls to this function */
+	err=X509_STORE_CTX_get_error(ctx);
+	if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
+		return 1;
+
+	/* BAD we should have gotten an error.  Normally if everything
+	 * worked X509_STORE_CTX_get_error(ctx) will still be set to
+	 * DEPTH_ZERO_SELF_.... */
+	if (ok)
+		{
+		BIO_printf(bio_err,"error with certificate to be certified - should be self signed\n");
+		return 0;
+		}
+	else
+		{
+		err_cert=X509_STORE_CTX_get_current_cert(ctx);
+		print_name(bio_err, NULL, X509_get_subject_name(err_cert),0);
+		BIO_printf(bio_err,"error with certificate - error %d at depth %d\n%s\n",
+			err,X509_STORE_CTX_get_error_depth(ctx),
+			X509_verify_cert_error_string(err));
+		return 1;
+		}
+	}
+
+/* self sign */
+static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest, 
+						CONF *conf, char *section)
+	{
+
+	EVP_PKEY *pktmp;
+
+	pktmp = X509_get_pubkey(x);
+	EVP_PKEY_copy_parameters(pktmp,pkey);
+	EVP_PKEY_save_parameters(pktmp,1);
+	EVP_PKEY_free(pktmp);
+
+	if (!X509_set_issuer_name(x,X509_get_subject_name(x))) goto err;
+	if (X509_gmtime_adj(X509_get_notBefore(x),0) == NULL) goto err;
+
+	/* Lets just make it 12:00am GMT, Jan 1 1970 */
+	/* memcpy(x->cert_info->validity->notBefore,"700101120000Z",13); */
+	/* 28 days to be certified */
+
+	if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL)
+		goto err;
+
+	if (!X509_set_pubkey(x,pkey)) goto err;
+	if (clrext)
+		{
+		while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0);
+		}
+	if (conf)
+		{
+		X509V3_CTX ctx;
+		X509_set_version(x,2); /* version 3 certificate */
+                X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
+                X509V3_set_nconf(&ctx, conf);
+                if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) goto err;
+		}
+	if (!X509_sign(x,pkey,digest)) goto err;
+	return 1;
+err:
+	ERR_print_errors(bio_err);
+	return 0;
+	}
+
+static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt)
+{
+	int id, i, idret;
+	char *pname;
+	id = X509_PURPOSE_get_id(pt);
+	pname = X509_PURPOSE_get0_name(pt);
+	for (i = 0; i < 2; i++)
+		{
+		idret = X509_check_purpose(cert, id, i);
+		BIO_printf(bio, "%s%s : ", pname, i ? " CA" : ""); 
+		if (idret == 1) BIO_printf(bio, "Yes\n");
+		else if (idret == 0) BIO_printf(bio, "No\n");
+		else BIO_printf(bio, "Yes (WARNING code=%d)\n", idret);
+		}
+	return 1;
+}
diff --git a/openssl/bugs/MS b/openssl/bugs/MS
new file mode 100644
index 0000000..a1dcfb9
--- /dev/null
+++ b/openssl/bugs/MS
@@ -0,0 +1,7 @@
+If you use the function that does an fopen inside the DLL, it's malloc
+will be used and when the function is then written inside, more
+hassles
+....
+
+
+think about it.
diff --git a/openssl/bugs/SSLv3 b/openssl/bugs/SSLv3
new file mode 100644
index 0000000..a75a165
--- /dev/null
+++ b/openssl/bugs/SSLv3
@@ -0,0 +1,49 @@
+So far...
+
+ssl3.netscape.com:443 does not support client side dynamic
+session-renegotiation.
+
+ssl3.netscape.com:444 (asks for client cert) sends out all the CA RDN
+in an invalid format (the outer sequence is removed).
+
+Netscape-Commerce/1.12, when talking SSLv2, accepts a 32 byte
+challenge but then appears to only use 16 bytes when generating the
+encryption keys.  Using 16 bytes is ok but it should be ok to use 32.
+According to the SSLv3 spec, one should use 32 bytes for the challenge
+when opperating in SSLv2/v3 compatablity mode, but as mentioned above,
+this breaks this server so 16 bytes is the way to go.
+
+www.microsoft.com - when talking SSLv2, if session-id reuse is
+performed, the session-id passed back in the server-finished message
+is different from the one decided upon.
+
+ssl3.netscape.com:443, first a connection is established with RC4-MD5.
+If it is then resumed, we end up using DES-CBC3-SHA.  It should be
+RC4-MD5 according to 7.6.1.3, 'cipher_suite'.
+Netscape-Enterprise/2.01 (https://merchant.netscape.com) has this bug.
+It only really shows up when connecting via SSLv2/v3 then reconnecting
+via SSLv3. The cipher list changes....
+NEW INFORMATION.  Try connecting with a cipher list of just
+DES-CBC-SHA:RC4-MD5.  For some weird reason, each new connection uses
+RC4-MD5, but a re-connect tries to use DES-CBC-SHA.  So netscape, when
+doing a re-connect, always takes the first cipher in the cipher list.
+
+If we accept a netscape connection, demand a client cert, have a
+non-self-signed CA which does not have it's CA in netscape, and the
+browser has a cert, it will crash/hang.  Works for 3.x and 4.xbeta
+
+Netscape browsers do not really notice the server sending a
+close notify message.  I was sending one, and then some invalid data.
+netscape complained of an invalid mac. (a fork()ed child doing a
+SSL_shutdown() and still sharing the socket with its parent).
+
+Netscape, when using export ciphers, will accept a 1024 bit temporary
+RSA key.  It is supposed to only accept 512.
+
+If Netscape connects to a server which requests a client certificate
+it will frequently hang after the user has selected one and never
+complete the connection. Hitting "Stop" and reload fixes this and
+all subsequent connections work fine. This appears to be because 
+Netscape wont read any new records in when it is awaiting a server
+done message at this point. The fix is to send the certificate request
+and server done messages in one record.
diff --git a/openssl/bugs/alpha.c b/openssl/bugs/alpha.c
new file mode 100644
index 0000000..701d6a7
--- /dev/null
+++ b/openssl/bugs/alpha.c
@@ -0,0 +1,91 @@
+/* bugs/alpha.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* while not exactly a bug (ASN1 C leaves this undefined) it is
+ * something to watch out for.  This was fine on linux/NT/Solaris but not
+ * Alpha */
+
+/* it is basically an example of
+ * func(*(a++),*(a++))
+ * which parameter is evaluated first?  It is not defined in ASN1 C.
+ */
+
+#include <stdio.h>
+
+#define TYPE    unsigned int
+
+void func(a,b)
+TYPE *a;
+TYPE b;
+        {
+        printf("%ld -1 == %ld\n",a[0],b);
+        }
+
+main()
+        {
+        TYPE data[5]={1L,2L,3L,4L,5L};
+        TYPE *p;
+        int i;
+
+        p=data;
+
+        for (i=0; i<4; i++)
+                {
+                func(p,*(p++));
+                }
+        }
diff --git a/openssl/bugs/dggccbug.c b/openssl/bugs/dggccbug.c
new file mode 100644
index 0000000..30e07a6
--- /dev/null
+++ b/openssl/bugs/dggccbug.c
@@ -0,0 +1,45 @@
+/* NOCW */
+/* dggccbug.c */
+/* bug found by Eric Young (eay@cryptsoft.com) - May 1995 */
+
+#include <stdio.h>
+
+/* There is a bug in
+ * gcc version 2.5.8 (88open OCS/BCS, DG-2.5.8.3, Oct 14 1994)
+ * as shipped with DGUX 5.4R3.10 that can be bypassed by defining
+ * DG_GCC_BUG in my code.
+ * The bug manifests itself by the vaule of a pointer that is
+ * used only by reference, not having it's value change when it is used
+ * to check for exiting the loop.  Probably caused by there being 2
+ * copies of the valiable, one in a register and one being an address
+ * that is passed. */
+
+/* compare the out put from
+ * gcc dggccbug.c; ./a.out
+ * and
+ * gcc -O dggccbug.c; ./a.out
+ * compile with -DFIXBUG to remove the bug when optimising.
+ */
+
+void inc(a)
+int *a;
+	{
+	(*a)++;
+	}
+
+main()
+	{
+	int p=0;
+#ifdef FIXBUG
+	int dummy;
+#endif
+
+	while (p<3)
+		{
+		fprintf(stderr,"%08X\n",p);
+		inc(&p);
+#ifdef FIXBUG
+		dummy+=p;
+#endif
+		}
+	}
diff --git a/openssl/bugs/sgiccbug.c b/openssl/bugs/sgiccbug.c
new file mode 100644
index 0000000..178239d
--- /dev/null
+++ b/openssl/bugs/sgiccbug.c
@@ -0,0 +1,57 @@
+/* NOCW */
+/* sgibug.c */
+/* bug found by Eric Young (eay@mincom.oz.au) May 95 */
+
+#include <stdio.h>
+
+/* This compiler bug it present on IRIX 5.3, 5.1 and 4.0.5 (these are
+ * the only versions of IRIX I have access to.
+ * defining FIXBUG removes the bug.
+ * (bug is still present in IRIX 6.3 according to
+ * Gage <agage@forgetmenot.Mines.EDU>
+ */
+ 
+/* Compare the output from
+ * cc sgiccbug.c; ./a.out
+ * and
+ * cc -O sgiccbug.c; ./a.out
+ */
+
+static unsigned long a[4]={0x01234567,0x89ABCDEF,0xFEDCBA98,0x76543210};
+static unsigned long b[4]={0x89ABCDEF,0xFEDCBA98,0x76543210,0x01234567};
+static unsigned long c[4]={0x77777778,0x8ACF1357,0x88888888,0x7530ECA9};
+
+main()
+	{
+	unsigned long r[4];
+	sub(r,a,b);
+	fprintf(stderr,"input a= %08X %08X %08X %08X\n",a[3],a[2],a[1],a[0]);
+	fprintf(stderr,"input b= %08X %08X %08X %08X\n",b[3],b[2],b[1],b[0]);
+	fprintf(stderr,"output = %08X %08X %08X %08X\n",r[3],r[2],r[1],r[0]);
+	fprintf(stderr,"correct= %08X %08X %08X %08X\n",c[3],c[2],c[1],c[0]);
+	}
+
+int sub(r,a,b)
+unsigned long *r,*a,*b;
+	{
+	register unsigned long t1,t2,*ap,*bp,*rp;
+	int i,carry;
+#ifdef FIXBUG
+	unsigned long dummy;
+#endif
+
+	ap=a;
+	bp=b;
+	rp=r;
+	carry=0;
+	for (i=0; i<4; i++)
+		{
+		t1= *(ap++);
+		t2= *(bp++);
+		t1=(t1-t2);
+#ifdef FIXBUG
+		dummy=t1;
+#endif
+		*(rp++)=t1&0xffffffff;
+		}
+	}
diff --git a/openssl/bugs/sslref.dif b/openssl/bugs/sslref.dif
new file mode 100644
index 0000000..0aa92bf
--- /dev/null
+++ b/openssl/bugs/sslref.dif
@@ -0,0 +1,26 @@
+The February 9th, 1995 version of the SSL document differs from
+https://www.netscape.com in the following ways.
+=====
+The key material for generating a SSL_CK_DES_64_CBC_WITH_MD5 key is
+KEY-MATERIAL-0 = MD5[MASTER-KEY,"0",CHALLENGE,CONNECTION-ID]
+not
+KEY-MATERIAL-0 = MD5[MASTER-KEY,CHALLENGE,CONNECTION-ID]
+as specified in the documentation.
+=====
+From the section 2.6 Server Only Protocol Messages
+
+If the SESSION-ID-HIT flag is non-zero then the CERTIFICATE-TYPE,
+CERTIFICATE-LENGTH and CIPHER-SPECS-LENGTH fields will be zero. 
+
+This is not true for https://www.netscape.com.  The CERTIFICATE-TYPE
+is returned as 1.
+=====
+I have not tested the following but it is reported by holtzman@mit.edu.
+
+SSLref clients wait to recieve a server-verify before they send a
+client-finished.  Besides this not being evident from the examples in
+2.2.1, it makes more sense to always send all packets you can before
+reading.  SSLeay was waiting in the server to recieve a client-finish
+before sending the server-verify :-).  I have changed SSLeay to send a
+server-verify before trying to read the client-finished.
+
diff --git a/openssl/bugs/stream.c b/openssl/bugs/stream.c
new file mode 100644
index 0000000..c3b5e86
--- /dev/null
+++ b/openssl/bugs/stream.c
@@ -0,0 +1,131 @@
+/* bugs/stream.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/rc4.h>
+#ifdef OPENSSL_NO_DES
+#include <des.h>
+#else
+#include <openssl/des.h>
+#endif
+
+/* show how stream ciphers are not very good.  The mac has no affect
+ * on RC4 while it does for cfb DES
+ */
+
+main()
+	{
+	fprintf(stderr,"rc4\n");
+	rc4();
+	fprintf(stderr,"cfb des\n");
+	des();
+	}
+
+int des()
+	{
+	des_key_schedule ks;
+	des_cblock iv,key;
+	int num;
+	static char *keystr="01234567";
+	static char *in1="0123456789ABCEDFdata 12345";
+	static char *in2="9876543210abcdefdata 12345";
+	unsigned char out[100];
+	int i;
+
+	des_set_key((des_cblock *)keystr,ks);
+
+	num=0;
+	memset(iv,0,8);
+	des_cfb64_encrypt(in1,out,26,ks,(des_cblock *)iv,&num,1);
+	for (i=0; i<26; i++)
+		fprintf(stderr,"%02X ",out[i]);
+	fprintf(stderr,"\n");
+
+	num=0;
+	memset(iv,0,8);
+	des_cfb64_encrypt(in2,out,26,ks,(des_cblock *)iv,&num,1);
+	for (i=0; i<26; i++)
+		fprintf(stderr,"%02X ",out[i]);
+	fprintf(stderr,"\n");
+	}
+
+int rc4()
+	{
+	static char *keystr="0123456789abcdef";
+	RC4_KEY key;
+	unsigned char in[100],out[100];
+	int i;
+
+	RC4_set_key(&key,16,keystr);
+	in[0]='\0';
+	strcpy(in,"0123456789ABCEDFdata 12345");
+	RC4(key,26,in,out);
+
+	for (i=0; i<26; i++)
+		fprintf(stderr,"%02X ",out[i]);
+	fprintf(stderr,"\n");
+
+	RC4_set_key(&key,16,keystr);
+	in[0]='\0';
+	strcpy(in,"9876543210abcdefdata 12345");
+	RC4(key,26,in,out);
+
+	for (i=0; i<26; i++)
+		fprintf(stderr,"%02X ",out[i]);
+	fprintf(stderr,"\n");
+	}
diff --git a/openssl/bugs/ultrixcc.c b/openssl/bugs/ultrixcc.c
new file mode 100644
index 0000000..7ba75b1
--- /dev/null
+++ b/openssl/bugs/ultrixcc.c
@@ -0,0 +1,45 @@
+#include <stdio.h>
+
+/* This is a cc optimiser bug for ultrix 4.3, mips CPU.
+ * What happens is that the compiler, due to the (a)&7,
+ * does
+ * i=a&7;
+ * i--;
+ * i*=4;
+ * Then uses i as the offset into a jump table.
+ * The problem is that a value of 0 generates an offset of
+ * 0xfffffffc.
+ */
+
+main()
+	{
+	f(5);
+	f(0);
+	}
+
+int f(a)
+int a;
+	{
+	switch(a&7)
+		{
+	case 7:
+		printf("7\n");
+	case 6:
+		printf("6\n");
+	case 5:
+		printf("5\n");
+	case 4:
+		printf("4\n");
+	case 3:
+		printf("3\n");
+	case 2:
+		printf("2\n");
+	case 1:
+		printf("1\n");
+#ifdef FIX_BUG
+	case 0:
+		;
+#endif
+		}
+	}	
+
diff --git a/openssl/certs/README.RootCerts b/openssl/certs/README.RootCerts
new file mode 100644
index 0000000..c760b61
--- /dev/null
+++ b/openssl/certs/README.RootCerts
@@ -0,0 +1,4 @@
+The OpenSSL project does not (any longer) include root CA certificates.
+
+Please check out the FAQ:
+  * How can I set up a bundle of commercial root CA certificates?
diff --git a/openssl/certs/demo/ca-cert.pem b/openssl/certs/demo/ca-cert.pem
new file mode 100644
index 0000000..bcba68a
--- /dev/null
+++ b/openssl/certs/demo/ca-cert.pem
@@ -0,0 +1,33 @@
+-----BEGIN CERTIFICATE-----
+MIIC5TCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQQFADBcMQswCQYDVQQGEwJBVTET
+MBEGA1UECBMKUXVlZW5zbGFuZDEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQx
+HDAaBgNVBAMTE1Rlc3QgUENBICgxMDI0IGJpdCkwHhcNOTkxMjAyMjEzODUxWhcN
+MDUwNzEwMjEzODUxWjBbMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFu
+ZDEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxGzAZBgNVBAMTElRlc3QgQ0Eg
+KDEwMjQgYml0KTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAo7ujy3XXpU/p
+yDJtOxkMJmGv3mdiVm7JrdoKLUgqjO2rBaeNuYMUiuI6oYU+tlD6agwRML0Pn2JF
+b90VdK/UXrmRr9djaEuH17EIKjte5RwOzndCndsjcCYyoeODMTyg7dqPIkDMmRNM
+5R5xBTabD+Aji0wzQupYxBLuW5PLj7ECAwEAAaOBtzCBtDAdBgNVHQ4EFgQU1WWA
+U42mkhi3ecgey1dsJjU61+UwgYQGA1UdIwR9MHuAFE0RaEcrj18q1dw+G6nJbsTW
+R213oWCkXjBcMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEaMBgG
+A1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxHDAaBgNVBAMTE1Rlc3QgUENBICgxMDI0
+IGJpdCmCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBb39BRphHL
+6aRAQyymsvBvPSCiG9+kR0R1L23aTpNbhXp2BebyFjbEQYZc2kWGiKKcHkNECA35
+3d4LoqUlVey8DFyafOIJd9hxdZfg+rxlHMxnL7uCJRmx9+xB411Jtsol9/wg1uCK
+sleGpgB4j8cG2SVCz7V2MNZNK+d5QCnR7A==
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQCju6PLddelT+nIMm07GQwmYa/eZ2JWbsmt2gotSCqM7asFp425
+gxSK4jqhhT62UPpqDBEwvQ+fYkVv3RV0r9ReuZGv12NoS4fXsQgqO17lHA7Od0Kd
+2yNwJjKh44MxPKDt2o8iQMyZE0zlHnEFNpsP4COLTDNC6ljEEu5bk8uPsQIDAQAB
+AoGAVZmpFZsDZfr0l2S9tLLwpjRWNOlKATQkno6q2WesT0eGLQufTciY+c8ypfU6
+hyio8r5iUl/VhhdjhAtKx1mRpiotftHo/eYf8rtsrnprOnWG0bWjLjtIoMbcxGn2
+J3bN6LJmbJMjDs0eJ3KnTu646F3nDUw2oGAwmpzKXA1KAP0CQQDRvQhxk2D3Pehs
+HvG665u2pB5ipYQngEFlZO7RHJZzJOZEWSLuuMqaF/7pTfA5jiBvWqCgJeCRRInL
+21ru4dlPAkEAx9jj7BgKn5TYnMoBSSe0afjsV9oApVpN1Nacb1YDtCwy+scp3++s
+nFxlv98wxIlSdpwMUn+AUWfjiWR7Tu/G/wJBAJ/KjwZIrFVxewP0x2ILYsTRYLzz
+MS4PDsO7FB+I0i7DbBOifXS2oNSpd3I0CNMwrxFnUHzynpbOStVfN3ZL5w0CQQCa
+pwFahxBRhkJKsxhjoFJBX9yl75JoY4Wvm5Tbo9ih6UJaRx3kqfkN14L2BKYcsZgb
+KY9vmDOYy6iNfjDeWTfJAkBkfPUb8oTJ/nSP5zN6sqGxSY4krc4xLxpRmxoJ8HL2
+XfhqXkTzbU13RX9JJ/NZ8vQN9Vm2NhxRGJocQkmcdVtJ
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/certs/demo/dsa-ca.pem b/openssl/certs/demo/dsa-ca.pem
new file mode 100644
index 0000000..9eb08f3
--- /dev/null
+++ b/openssl/certs/demo/dsa-ca.pem
@@ -0,0 +1,43 @@
+-----BEGIN DSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,C5B6C7CC9E1FE2C0
+
+svCXBcBRhMuU22UXOfiKZA+thmz6KYXpt1Yg5Rd+TYQcQ1MdvNy0B0tkP1SxzDq0
+Xh1eMeTML9/9/0rKakgNXXXbpi5RB8t6BmwRSyej89F7nn1mtR3qzoyPRpp15SDl
+Tn67C+2v+HDF3MFk88hiNCYkNbcmi7TWvChsl8N1r7wdZwtIox56yXdgxw6ZIpa/
+par0oUCzN7fiavPgCWz1kfPNSaBQSdxwH7TZi5tMHAr0J3C7a7QRnZfE09R59Uqr
+zslrq+ndIw1BZAxoY0SlBu+iFOVaBVlwToC4AsHkv7j7l8ITtr7f42YbBa44D9TO
+uOhONmkk/v3Fso4RaOEzdKZC+hnmmzvHs6TiTWm6yzJgSFwyOUK0eGmKEeVxpcH5
+rUOlHOwzen+FFtocZDZAfdFnb7QY7L/boQvyA5A+ZbRG4DUpmBQeQsSaICHM5Rxx
+1QaLF413VNPXTLPbW0ilSc2H8x2iZTIVKfd33oSO6NhXPtSYQgfecEF4BvNHY5c4
+HovjT4mckbK95bcBzoCHu43vuSQkmZzdYo/ydSZt6zoPavbBLueTpgSbdXiDi827
+MVqOsYxGCb+kez0FoDSTgw==
+-----END DSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE REQUEST-----
+MIICUjCCAhECAQAwUjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
+ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDELMAkGA1UEAxMCQ0Ew
+ggG0MIIBKQYFKw4DAgwwggEeAoGBAKc/boW/QWopffCfRxkwkJoJHdpqMx7FPYaW
+sxXgUy6P4FmCc5A+dTGZR3pS+4Xk2aZ7OJtoioSbh8YetX6GS1NbWc9xZRmIbs5m
+rmuINvvsKNzC16W75Sw5JkvamnAYlTeVEFYj9hXtugRe3jlP/bdDH7WkZW/NgBHk
+cJVbUM1JAhUA9wcx7fpsBgPVhYocrJxl51BmZW8CgYBN30wDppGK9RlvUEYlmeVo
+bzDjaeHls12YuyiGSPzemQQ/X4gMnHMkDSBduSqaPxiWJ+Rih8F7dGJT/GEnqHqR
+CZ228U2cVA9YBu5JdAfOVX4jzhb2ytxaYQF+yXG1TfbcNCmHaPZeIJOz2/XkCWxB
+F5WS6wG1c6Vqftgy7Q4CuAOBhAACgYAapll6iqz9XrZFlk2GCVcB+KihxWnH7IuH
+vSLw9YUrJahcBHmbpvt494lF4gC5w3WPM+vXJofbusk4GoQEEsQNMDaah4m49uUq
+AylOVFJJJXuirVJ+o+0TtOFDITEAl+YZZariXOD7tdOSOl9RLMPC6+daHKS9e68u
+3enxhqnDGaAAMAkGBSsOAwIbBQADMAAwLQIVAJGVuFsG/0DBuSZ0jF7ypdU0/G0v
+AhQfeF5BoMMDbX/kidUVpQ6gadPlZA==
+-----END CERTIFICATE REQUEST-----
+-----BEGIN CERTIFICATE-----
+MIIBrjCCAWwCAQswCQYFKw4DAhsFADBTMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
+U29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQww
+CgYDVQQDEwNQQ0EwHhcNOTcwNjE1MDIxNDI5WhcNOTcwNzE1MDIxNDI5WjBSMQsw
+CQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJu
+ZXQgV2lkZ2l0cyBQdHkgTHRkMQswCQYDVQQDEwJDQTCBkjAJBgUrDgMCDAUAA4GE
+AAKBgBqmWXqKrP1etkWWTYYJVwH4qKHFacfsi4e9IvD1hSslqFwEeZum+3j3iUXi
+ALnDdY8z69cmh9u6yTgahAQSxA0wNpqHibj25SoDKU5UUkkle6KtUn6j7RO04UMh
+MQCX5hllquJc4Pu105I6X1Esw8Lr51ocpL17ry7d6fGGqcMZMAkGBSsOAwIbBQAD
+MQAwLgIVAJ4wtQsANPxHo7Q4IQZYsL12SKdbAhUAjJ9n38zxT+iai2164xS+LIfa
+C1Q=
+-----END CERTIFICATE-----
+
diff --git a/openssl/certs/demo/dsa-pca.pem b/openssl/certs/demo/dsa-pca.pem
new file mode 100644
index 0000000..e3641ad
--- /dev/null
+++ b/openssl/certs/demo/dsa-pca.pem
@@ -0,0 +1,49 @@
+-----BEGIN DSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,F80EEEBEEA7386C4
+
+GZ9zgFcHOlnhPoiSbVi/yXc9mGoj44A6IveD4UlpSEUt6Xbse3Fr0KHIUyQ3oGnS
+mClKoAp/eOTb5Frhto85SzdsxYtac+X1v5XwdzAMy2KowHVk1N8A5jmE2OlkNPNt
+of132MNlo2cyIRYaa35PPYBGNCmUm7YcYS8O90YtkrQZZTf4+2C4kllhMcdkQwkr
+FWSWC8YOQ7w0LHb4cX1FejHHom9Nd/0PN3vn3UyySvfOqoR7nbXkrpHXmPIr0hxX
+RcF0aXcV/CzZ1/nfXWQf4o3+oD0T22SDoVcZY60IzI0oIc3pNCbDV3uKNmgekrFd
+qOUJ+QW8oWp7oefRx62iBfIeC8DZunohMXaWAQCU0sLQOR4yEdeUCnzCSywe0bG1
+diD0KYaEe+Yub1BQH4aLsBgDjardgpJRTQLq0DUvw0/QGO1irKTJzegEDNVBKrVn
+V4AHOKT1CUKqvGNRP1UnccUDTF6miOAtaj/qpzra7sSk7dkGBvIEeFoAg84kfh9h
+hVvF1YyzC9bwZepruoqoUwke/WdNIR5ymOVZ/4Liw0JdIOcq+atbdRX08niqIRkf
+dsZrUj4leo3zdefYUQ7w4N2Ns37yDFq7
+-----END DSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE REQUEST-----
+MIICVTCCAhMCAQAwUzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
+ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEMMAoGA1UEAxMDUENB
+MIIBtTCCASkGBSsOAwIMMIIBHgKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2G
+lrMV4FMuj+BZgnOQPnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7O
+Zq5riDb77Cjcwtelu+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR
+5HCVW1DNSQIVAPcHMe36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnl
+aG8w42nh5bNdmLsohkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6
+kQmdtvFNnFQPWAbuSXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15Als
+QReVkusBtXOlan7YMu0OArgDgYUAAoGBAKbtuR5AdW+ICjCFe2ixjUiJJzM2IKwe
+6NZEMXg39+HQ1UTPTmfLZLps+rZfolHDXuRKMXbGFdSF0nXYzotPCzi7GauwEJTZ
+yr27ZZjA1C6apGSQ9GzuwNvZ4rCXystVEagAS8OQ4H3D4dWS17Zg31ICb5o4E5r0
+z09o/Uz46u0VoAAwCQYFKw4DAhsFAAMxADAuAhUArRubTxsbIXy3AhtjQ943AbNB
+nSICFQCu+g1iW3jwF+gOcbroD4S/ZcvB3w==
+-----END CERTIFICATE REQUEST-----
+-----BEGIN CERTIFICATE-----
+MIIC0zCCApECAQAwCQYFKw4DAhsFADBTMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
+U29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQww
+CgYDVQQDEwNQQ0EwHhcNOTcwNjE0MjI1NDQ1WhcNOTcwNzE0MjI1NDQ1WjBTMQsw
+CQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJu
+ZXQgV2lkZ2l0cyBQdHkgTHRkMQwwCgYDVQQDEwNQQ0EwggG1MIIBKQYFKw4DAgww
+ggEeAoGBAKc/boW/QWopffCfRxkwkJoJHdpqMx7FPYaWsxXgUy6P4FmCc5A+dTGZ
+R3pS+4Xk2aZ7OJtoioSbh8YetX6GS1NbWc9xZRmIbs5mrmuINvvsKNzC16W75Sw5
+JkvamnAYlTeVEFYj9hXtugRe3jlP/bdDH7WkZW/NgBHkcJVbUM1JAhUA9wcx7fps
+BgPVhYocrJxl51BmZW8CgYBN30wDppGK9RlvUEYlmeVobzDjaeHls12YuyiGSPze
+mQQ/X4gMnHMkDSBduSqaPxiWJ+Rih8F7dGJT/GEnqHqRCZ228U2cVA9YBu5JdAfO
+VX4jzhb2ytxaYQF+yXG1TfbcNCmHaPZeIJOz2/XkCWxBF5WS6wG1c6Vqftgy7Q4C
+uAOBhQACgYEApu25HkB1b4gKMIV7aLGNSIknMzYgrB7o1kQxeDf34dDVRM9OZ8tk
+umz6tl+iUcNe5EoxdsYV1IXSddjOi08LOLsZq7AQlNnKvbtlmMDULpqkZJD0bO7A
+29nisJfKy1URqABLw5DgfcPh1ZLXtmDfUgJvmjgTmvTPT2j9TPjq7RUwCQYFKw4D
+AhsFAAMxADAuAhUAvtv6AkMolix1Jvy3UnVEIUqdCUICFQC+jq8P49mwrY9oJ24n
+5rKUjNBhSg==
+-----END CERTIFICATE-----
+
diff --git a/openssl/certs/demo/pca-cert.pem b/openssl/certs/demo/pca-cert.pem
new file mode 100644
index 0000000..9d754d4
--- /dev/null
+++ b/openssl/certs/demo/pca-cert.pem
@@ -0,0 +1,33 @@
+-----BEGIN CERTIFICATE-----
+MIIC5jCCAk+gAwIBAgIBADANBgkqhkiG9w0BAQQFADBcMQswCQYDVQQGEwJBVTET
+MBEGA1UECBMKUXVlZW5zbGFuZDEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQx
+HDAaBgNVBAMTE1Rlc3QgUENBICgxMDI0IGJpdCkwHhcNOTkxMjAyMjEzNTQ4WhcN
+MDUwNzExMjEzNTQ4WjBcMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFu
+ZDEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxHDAaBgNVBAMTE1Rlc3QgUENB
+ICgxMDI0IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ2haT/f5Zwy
+V+MiuSDjSR62adBoSiBB7Usty44lXqsp9RICw+DCCxpsn/CfxPEDXLLd4olsWXc6
+JRcxGynbYmnzk+Z6aIPPJQhK3CTvaqGnWKZsA1m+WaUIUqJCuNTK4N+7hMAGaf6S
+S3e9HVgEQ4a34gXJ7VQFVIBNV1EnZRWHAgMBAAGjgbcwgbQwHQYDVR0OBBYEFE0R
+aEcrj18q1dw+G6nJbsTWR213MIGEBgNVHSMEfTB7gBRNEWhHK49fKtXcPhupyW7E
+1kdtd6FgpF4wXDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxGjAY
+BgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYDVQQDExNUZXN0IFBDQSAoMTAy
+NCBiaXQpggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAUa8B3pho
++Mvxeq9HsEzJxHIFQla05S5J/e/V+DQTYoKiRFchKPrDAdrzYSEvP3h4QJEtsNqQ
+JfOxg5M42uLFq7aPGWkF6ZZqZsYS+zA9IVT14g7gNA6Ne+5QtJqQtH9HA24st0T0
+Tga/lZ9M2ovImovaxSL/kRHbpCWcqWVxpOw=
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQCdoWk/3+WcMlfjIrkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPg
+wgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp22Jp85PmemiDzyUIStwk72qhp1imbANZ
+vlmlCFKiQrjUyuDfu4TABmn+kkt3vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQAB
+AoGAba4fTtuap5l7/8ZsbE7Z1O32KJY4ZcOZukLOLUUhXxXduT+FTgGWujc0/rgc
+z9qYCLlNZHOouMYTgtSfYvuMuLZ11VIt0GYH+nRioLShE59Yy+zCRyC+gPigS1kz
+xvo14AsOIPYV14Tk/SsHyq6E0eTk7VzaIE197giiINUERPECQQDSKmtPTh/lRKw7
+HSZSM0I1mFWn/1zqrAbontRQY5w98QWIOe5qmzYyFbPXYT3d9BzlsMyhgiRNoBbD
+yvohSHXJAkEAwAHx6ezAZeWWzD5yXD36nyjpkVCw7Tk7TSmOceLJMWt1QcrCfqlS
+xA5jjpQ6Z8suU5DdtWAryM2sAir1WisYzwJAd6Zcx56jvAQ3xcPXsE6scBTVFzrj
+7FqZ6E+cclPzfLQ+QQsyOBE7bpI6e/FJppY26XGZXo3YGzV8IGXrt40oOQJALETG
+h86EFXo3qGOFbmsDy4pdP5nBERCu8X1xUCSfintiD4c2DInxgS5oGclnJeMcjTvL
+QjQoJCX3UJCi/OUO1QJBAKgcDHWjMvt+l1pjJBsSEZ0HX9AAIIVx0RQmbFGS+F2Q
+hhu5l77WnnZOQ9vvhV5u7NPCUF9nhU3jh60qWWO8mkc=
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/certs/expired/ICE.crl b/openssl/certs/expired/ICE.crl
new file mode 100644
index 0000000..21939e8
--- /dev/null
+++ b/openssl/certs/expired/ICE.crl
@@ -0,0 +1,9 @@
+-----BEGIN X509 CRL-----
+MIIBNDCBnjANBgkqhkiG9w0BAQIFADBFMSEwHwYDVQQKExhFdXJvcGVhbiBJQ0Ut
+VEVMIFByb2plY3QxIDAeBgNVBAsTF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05
+NzA2MDkxNDQyNDNaFw05NzA3MDkxNDQyNDNaMCgwEgIBChcNOTcwMzAzMTQ0MjU0
+WjASAgEJFw05NjEwMDIxMjI5MjdaMA0GCSqGSIb3DQEBAgUAA4GBAH4vgWo2Tej/
+i7kbiw4Imd30If91iosjClNpBFwvwUDBclPEeMuYimHbLOk4H8Nofc0fw11+U/IO
+KSNouUDcqG7B64oY7c4SXKn+i1MWOb5OJiWeodX3TehHjBlyWzoNMWCnYA8XqFP1
+mOKp8Jla1BibEZf14+/HqCi2hnZUiEXh
+-----END X509 CRL-----
diff --git a/openssl/config b/openssl/config
new file mode 100755
index 0000000..cf64ec5
--- /dev/null
+++ b/openssl/config
@@ -0,0 +1,933 @@
+#!/bin/sh
+#
+# OpenSSL config: determine the operating system and run ./Configure
+#
+# "config -h" for usage information.
+#
+#          this is a merge of minarch and GuessOS from the Apache Group.
+#          Originally written by Tim Hudson <tjh@cryptsoft.com>.
+
+# Original Apache Group comments on GuessOS
+
+# Simple OS/Platform guesser. Similar to config.guess but
+# much, much smaller. Since it was developed for use with
+# Apache, it follows under Apache's regular licensing
+# with one specific addition: Any changes or additions
+# to this script should be Emailed to the Apache
+# group (apache@apache.org) in general and to
+# Jim Jagielski (jim@jaguNET.com) in specific.
+#
+# Be as similar to the output of config.guess/config.sub
+# as possible.
+
+PREFIX=""
+SUFFIX=""
+TEST="false"
+EXE=""
+
+# pick up any command line args to config
+for i
+do
+case "$i" in 
+-d*) PREFIX="debug-";;
+-t*) TEST="true";;
+-h*) TEST="true"; cat <<EOF
+Usage: config [options]
+ -d	Add a debug- prefix to machine choice.
+ -t	Test mode, do not run the Configure perl script.
+ -h	This help.
+
+Any other text will be passed to the Configure perl script.
+See INSTALL for instructions.
+
+EOF
+;;
+*) options=$options" $i" ;;
+esac
+done
+
+# First get uname entries that we use below
+
+[ "$MACHINE" ] || MACHINE=`(uname -m) 2>/dev/null` || MACHINE="unknown"
+[ "$RELEASE" ] || RELEASE=`(uname -r) 2>/dev/null` || RELEASE="unknown"
+[ "$SYSTEM" ] || SYSTEM=`(uname -s) 2>/dev/null`  || SYSTEM="unknown"
+[ "$BUILD" ] || VERSION=`(uname -v) 2>/dev/null` || VERSION="unknown"
+
+
+# Now test for ISC and SCO, since it is has a braindamaged uname.
+#
+# We need to work around FreeBSD 1.1.5.1 
+(
+XREL=`uname -X 2>/dev/null | grep "^Release" | awk '{print $3}'`
+if [ "x$XREL" != "x" ]; then
+    if [ -f /etc/kconfig ]; then
+	case "$XREL" in
+	    4.0|4.1)
+		    echo "${MACHINE}-whatever-isc4"; exit 0
+		;;
+	esac
+    else
+	case "$XREL" in
+	    3.2v4.2)
+		echo "whatever-whatever-sco3"; exit 0
+		;;
+	    3.2v5.0*)
+		echo "whatever-whatever-sco5"; exit 0
+		;;
+	    4.2MP)
+		case "x${VERSION}" in
+		    x2.0*) echo "whatever-whatever-unixware20"; exit 0 ;;
+		    x2.1*) echo "whatever-whatever-unixware21"; exit 0 ;;
+		    x2*)   echo "whatever-whatever-unixware2";  exit 0 ;;
+		esac
+		;;
+	    4.2)
+		echo "whatever-whatever-unixware1"; exit 0
+		;;
+	    5*)
+		case "x${VERSION}" in
+		    # We hardcode i586 in place of ${MACHINE} for the
+		    # following reason. The catch is that even though Pentium
+		    # is minimum requirement for platforms in question,
+		    # ${MACHINE} gets always assigned to i386. Now, problem
+		    # with i386 is that it makes ./config pass 386 to
+		    # ./Configure, which in turn makes make generate
+		    # inefficient SHA-1 (for this moment) code.
+		    x[678]*)  echo "i586-sco-unixware7"; exit 0 ;;
+		esac
+		;;
+	esac
+    fi
+fi
+# Now we simply scan though... In most cases, the SYSTEM info is enough
+#
+case "${SYSTEM}:${RELEASE}:${VERSION}:${MACHINE}" in
+    MPE/iX:*)
+	MACHINE=`echo "$MACHINE" | sed -e 's/-/_/g'`
+	echo "parisc-hp-MPE/iX"; exit 0
+	;;
+    A/UX:*)
+	echo "m68k-apple-aux3"; exit 0
+	;;
+
+    AIX:[3-9]:4:*)
+	echo "${MACHINE}-ibm-aix"; exit 0
+	;;
+
+    AIX:*:[5-9]:*)
+	echo "${MACHINE}-ibm-aix"; exit 0
+	;;
+
+    AIX:*)
+	echo "${MACHINE}-ibm-aix3"; exit 0
+	;;
+
+    BeOS:*:BePC)
+    if [ -e /boot/develop/headers/be/bone ]; then
+		echo "beos-x86-bone"; exit 0
+	else
+		echo "beos-x86-r5"; exit 0
+	fi
+	;;
+
+    dgux:*)
+	echo "${MACHINE}-dg-dgux"; exit 0
+	;;
+
+    HI-UX:*)
+	echo "${MACHINE}-hi-hiux"; exit 0
+	;;
+
+    HP-UX:*)
+	HPUXVER=`echo ${RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "$HPUXVER" in
+	    1[0-9].*)	# HPUX 10 and 11 targets are unified
+		echo "${MACHINE}-hp-hpux1x"; exit 0
+		;;
+	    *)
+		echo "${MACHINE}-hp-hpux"; exit 0
+		;;
+	esac
+	;;
+
+    IRIX:5.*)
+	echo "mips2-sgi-irix"; exit 0
+	;;
+
+    IRIX:6.*)
+	echo "mips3-sgi-irix"; exit 0
+	;;
+
+    IRIX64:*)
+	echo "mips4-sgi-irix64"; exit 0
+	;;
+
+    Linux:[2-9].*)
+	echo "${MACHINE}-whatever-linux2"; exit 0
+	;;
+
+    Linux:1.*)
+	echo "${MACHINE}-whatever-linux1"; exit 0
+	;;
+
+    GNU*)
+	echo "hurd-x86"; exit 0;
+	;;
+
+    LynxOS:*)
+	echo "${MACHINE}-lynx-lynxos"; exit 0
+	;;
+
+    BSD/OS:4.*)  # BSD/OS always says 386
+	echo "i486-whatever-bsdi4"; exit 0
+	;;
+
+    BSD/386:*:*:*486*|BSD/OS:*:*:*:*486*)
+        case `/sbin/sysctl -n hw.model` in
+	    Pentium*)
+                echo "i586-whatever-bsdi"; exit 0
+                ;;
+            *)
+                echo "i386-whatever-bsdi"; exit 0
+                ;;
+            esac;
+	;;
+
+    BSD/386:*|BSD/OS:*)
+	echo "${MACHINE}-whatever-bsdi"; exit 0
+	;;
+
+    FreeBSD:*:*:*386*)
+        VERS=`echo ${RELEASE} | sed -e 's/[-(].*//'`
+        MACH=`sysctl -n hw.model`
+        ARCH='whatever'
+        case ${MACH} in
+           *386*       ) MACH="i386"     ;;
+           *486*       ) MACH="i486"     ;;
+           Pentium\ II*) MACH="i686"     ;;
+           Pentium*    ) MACH="i586"     ;;
+           *           ) MACH="$MACHINE" ;;
+        esac
+        case ${MACH} in
+           i[0-9]86 ) ARCH="pc" ;;
+        esac
+        echo "${MACH}-${ARCH}-freebsd${VERS}"; exit 0
+        ;;
+
+    FreeBSD:*)
+	echo "${MACHINE}-whatever-freebsd"; exit 0
+	;;
+
+    NetBSD:*:*:*386*)
+        echo "`(/usr/sbin/sysctl -n hw.model || /sbin/sysctl -n hw.model) | sed 's,.*\(.\)86-class.*,i\186,'`-whatever-netbsd"; exit 0
+	;;
+
+    NetBSD:*)
+	echo "${MACHINE}-whatever-netbsd"; exit 0
+	;;
+
+    OpenBSD:*)
+	echo "${MACHINE}-whatever-openbsd"; exit 0
+	;;
+
+    OpenUNIX:*)
+	echo "${MACHINE}-unknown-OpenUNIX${VERSION}"; exit 0
+	;;
+
+    OSF1:*:*:*alpha*)
+	OSFMAJOR=`echo ${RELEASE}| sed -e 's/^V\([0-9]*\)\..*$/\1/'`
+	case "$OSFMAJOR" in
+	    4|5)
+		echo "${MACHINE}-dec-tru64"; exit 0
+		;;
+	    1|2|3)
+		echo "${MACHINE}-dec-osf"; exit 0
+		;;
+	    *)
+		echo "${MACHINE}-dec-osf"; exit 0
+		;;
+	esac
+	;;
+
+    QNX:*)
+	case "$RELEASE" in
+	    4*)
+		echo "${MACHINE}-whatever-qnx4"
+		;;
+	    6*)
+		echo "${MACHINE}-whatever-qnx6"
+		;;
+	    *)
+		echo "${MACHINE}-whatever-qnx"
+		;;
+	esac
+	exit 0
+	;;
+
+    Paragon*:*:*:*)
+	echo "i860-intel-osf1"; exit 0
+	;;
+
+    Rhapsody:*)
+	echo "ppc-apple-rhapsody"; exit 0
+	;;
+
+    Darwin:*)
+	case "$MACHINE" in
+	    Power*)
+		echo "ppc-apple-darwin${VERSION}"
+		;;
+	    *)
+		echo "i686-apple-darwin${VERSION}"
+		;;
+	esac
+	exit 0
+	;;
+
+    SunOS:5.*)
+	echo "${MACHINE}-whatever-solaris2"; exit 0
+	;;
+
+    SunOS:*)
+	echo "${MACHINE}-sun-sunos4"; exit 0
+	;;
+
+    UNIX_System_V:4.*:*)
+	echo "${MACHINE}-whatever-sysv4"; exit 0
+	;;
+
+    VOS:*:*:i786)
+     echo "i386-stratus-vos"; exit 0
+     ;;
+
+    VOS:*:*:*)
+     echo "hppa1.1-stratus-vos"; exit 0
+     ;;
+
+    *:4*:R4*:m88k)
+	echo "${MACHINE}-whatever-sysv4"; exit 0
+	;;
+
+    DYNIX/ptx:4*:*)
+	echo "${MACHINE}-whatever-sysv4"; exit 0
+	;;
+
+    *:4.0:3.0:3[34]?? | *:4.0:3.0:3[34]??,*)
+	echo "i486-ncr-sysv4"; exit 0
+	;;
+
+    ULTRIX:*)
+	echo "${MACHINE}-unknown-ultrix"; exit 0
+	;;
+
+    SINIX*|ReliantUNIX*)
+	echo "${MACHINE}-siemens-sysv4"; exit 0
+	;;
+
+    POSIX-BC*)
+	echo "${MACHINE}-siemens-sysv4"; exit 0   # Here, $MACHINE == "BS2000"
+	;;
+
+    machten:*)
+       echo "${MACHINE}-tenon-${SYSTEM}"; exit 0;
+       ;;
+
+    library:*)
+	echo "${MACHINE}-ncr-sysv4"; exit 0
+	;;
+
+    ConvexOS:*:11.0:*)
+	echo "${MACHINE}-v11-${SYSTEM}"; exit 0;
+	;;
+
+    NEWS-OS:4.*)
+	echo "mips-sony-newsos4"; exit 0;
+	;;
+
+    MINGW*)
+	echo "${MACHINE}-whatever-mingw"; exit 0;
+	;;
+    CYGWIN*)
+	case "$RELEASE" in
+	    [bB]*|1.0|1.[12].*)
+		echo "${MACHINE}-whatever-cygwin_pre1.3"
+		;;
+	    *)
+		echo "${MACHINE}-whatever-cygwin"
+		;;
+	esac
+	exit 0
+	;;
+
+    *"CRAY T3E")
+       echo "t3e-cray-unicosmk"; exit 0;
+       ;;
+
+    *CRAY*)
+       echo "j90-cray-unicos"; exit 0;
+       ;;
+
+    NONSTOP_KERNEL*)
+       echo "nsr-tandem-nsk"; exit 0;
+       ;;
+esac
+
+#
+# Ugg. These are all we can determine by what we know about
+# the output of uname. Be more creative:
+#
+
+# Do the Apollo stuff first. Here, we just simply assume
+# that the existance of the /usr/apollo directory is proof
+# enough
+if [ -d /usr/apollo ]; then
+    echo "whatever-apollo-whatever"
+    exit 0
+fi
+
+# Now NeXT
+ISNEXT=`hostinfo 2>/dev/null`
+case "$ISNEXT" in
+    *'NeXT Mach 3.3'*)
+	echo "whatever-next-nextstep3.3"; exit 0
+	;;
+    *NeXT*)
+	echo "whatever-next-nextstep"; exit 0
+	;;
+esac
+
+# At this point we gone through all the one's
+# we know of: Punt
+
+echo "${MACHINE}-whatever-${SYSTEM}" 
+exit 0
+) 2>/dev/null | (
+
+# ---------------------------------------------------------------------------
+# this is where the translation occurs into SSLeay terms
+# ---------------------------------------------------------------------------
+
+GCCVER=`(gcc -dumpversion) 2>/dev/null`
+if [ "$GCCVER" != "" ]; then
+  # then strip off whatever prefix egcs prepends the number with...
+  # Hopefully, this will work for any future prefixes as well.
+  GCCVER=`echo $GCCVER | LC_ALL=C sed 's/^[a-zA-Z]*\-//'`
+  # Since gcc 3.1 gcc --version behaviour has changed.  gcc -dumpversion
+  # does give us what we want though, so we use that.  We just just the
+  # major and minor version numbers.
+  # peak single digit before and after first dot, e.g. 2.95.1 gives 29
+  GCCVER=`echo $GCCVER | sed 's/\([0-9]\)\.\([0-9]\).*/\1\2/'`
+fi
+
+# Only set CC if not supplied already
+if [ -z "$CC" ]; then
+# figure out if gcc is available and if so we use it otherwise
+# we fallback to whatever cc does on the system
+  if [ "$GCCVER" != "" ]; then
+    CC=gcc
+  else
+    CC=cc
+  fi
+fi
+GCCVER=${GCCVER:-0}
+if [ "$SYSTEM" = "HP-UX" ];then
+  # By default gcc is a ILP32 compiler (with long long == 64).
+  GCC_BITS="32"
+  if [ $GCCVER -ge 30 ]; then
+    # PA64 support only came in with gcc 3.0.x.
+    # We check if the preprocessor symbol __LP64__ is defined...
+    if echo "__LP64__" | gcc -v -E -x c - 2>/dev/null | grep "^__LP64__" 2>&1 > /dev/null; then
+      : # __LP64__ has slipped through, it therefore is not defined
+    else
+      GCC_BITS="64"
+    fi
+  fi
+fi
+if [ "$SYSTEM" = "SunOS" ]; then
+  if [ $GCCVER -ge 30 ]; then
+    # 64-bit ABI isn't officially supported in gcc 3.0, but it appears
+    # to be working, at the very least 'make test' passes...
+    if gcc -v -E -x c /dev/null 2>&1 | grep __arch64__ > /dev/null; then
+      GCC_ARCH="-m64"
+    else
+      GCC_ARCH="-m32"
+    fi
+  fi
+  # check for WorkShop C, expected output is "cc: blah-blah C x.x"
+  CCVER=`(cc -V 2>&1) 2>/dev/null | \
+  	egrep -e '^cc: .* C [0-9]\.[0-9]' | \
+	sed 's/.* C \([0-9]\)\.\([0-9]\).*/\1\2/'`
+  CCVER=${CCVER:-0}
+  if [ $MACHINE != i86pc -a $CCVER -gt 40 ]; then
+    CC=cc	# overrides gcc!!!
+    if [ $CCVER -eq 50 ]; then
+      echo "WARNING! Detected WorkShop C 5.0. Do make sure you have"
+      echo "         patch #107357-01 or later applied."
+      sleep 5
+    fi
+  fi
+fi
+
+if [ "${SYSTEM}-${MACHINE}" = "Linux-alpha" ]; then
+  # check for Compaq C, expected output is "blah-blah C Vx.x"
+  CCCVER=`(ccc -V 2>&1) 2>/dev/null | \
+	egrep -e '.* C V[0-9]\.[0-9]' | \
+	sed 's/.* C V\([0-9]\)\.\([0-9]\).*/\1\2/'`
+  CCCVER=${CCCVER:-0}
+  if [ $CCCVER -gt 60 ]; then
+    CC=ccc	# overrides gcc!!! well, ccc outperforms inoticeably
+		# only on hash routines and des, otherwise gcc (2.95)
+		# keeps along rather tight...
+  fi
+fi
+
+if [ "${SYSTEM}" = "AIX" ]; then	# favor vendor cc over gcc
+    (cc) 2>&1 | grep -iv "not found" > /dev/null && CC=cc
+fi
+
+CCVER=${CCVER:-0}
+
+# read the output of the embedded GuessOS 
+read GUESSOS
+
+echo Operating system: $GUESSOS
+
+# now map the output into SSLeay terms ... really should hack into the
+# script above so we end up with values in vars but that would take
+# more time that I want to waste at the moment
+case "$GUESSOS" in
+  uClinux*64*)
+    OUT=uClinux-dist64
+	;;
+  uClinux*)
+    OUT=uClinux-dist
+	;;
+  mips2-sgi-irix)
+	CPU=`(hinv -t cpu) 2>/dev/null | head -1 | sed 's/^CPU:[^R]*R\([0-9]*\).*/\1/'`
+	CPU=${CPU:-0}
+	if [ $CPU -ge 4000 ]; then
+		options="$options -mips2"
+	fi
+	OUT="irix-$CC"
+	;;
+  mips3-sgi-irix)
+	#CPU=`(hinv -t cpu) 2>/dev/null | head -1 | sed 's/^CPU:[^R]*R\([0-9]*\).*/\1/'`
+	#CPU=${CPU:-0}
+	#if [ $CPU -ge 5000 ]; then
+	#	options="$options -mips4"
+	#else
+	#	options="$options -mips3"
+	#fi
+	OUT="irix-mips3-$CC"
+	;;
+  mips4-sgi-irix64)
+	echo "WARNING! If you wish to build 64-bit library, then you have to"
+	echo "         invoke './Configure irix64-mips4-$CC' *manually*."
+	if [ "$TEST" = "false" -a -t 1 ]; then
+	  echo "         You have about 5 seconds to press Ctrl-C to abort."
+	  (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
+	fi
+        #CPU=`(hinv -t cpu) 2>/dev/null | head -1 | sed 's/^CPU:[^R]*R\([0-9]*\).*/\1/'`
+        #CPU=${CPU:-0}
+        #if [ $CPU -ge 5000 ]; then
+        #        options="$options -mips4"
+        #else
+        #        options="$options -mips3"
+        #fi
+	OUT="irix-mips3-$CC"
+	;;
+  ppc-apple-rhapsody) OUT="rhapsody-ppc-cc" ;;
+  ppc-apple-darwin*)
+	ISA64=`(sysctl -n hw.optional.64bitops) 2>/dev/null`
+	if [ "$ISA64" = "1" ]; then
+	    echo "WARNING! If you wish to build 64-bit library, then you have to"
+	    echo "         invoke './Configure darwin64-ppc-cc' *manually*."
+	    if [ "$TEST" = "false" -a -t 1 ]; then
+	      echo "         You have about 5 seconds to press Ctrl-C to abort."
+	      (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
+	    fi
+	fi
+	OUT="darwin-ppc-cc" ;;
+  i?86-apple-darwin*)
+	ISA64=`(sysctl -n hw.optional.x86_64) 2>/dev/null`
+	if [ "$ISA64" = "1" ]; then
+	    echo "WARNING! If you wish to build 64-bit library, then you have to"
+	    echo "         invoke './Configure darwin64-x86_64-cc' *manually*."
+	    if [ "$TEST" = "false" -a -t 1 ]; then
+	      echo "         You have about 5 seconds to press Ctrl-C to abort."
+	      (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
+	    fi
+	fi
+	OUT="darwin-i386-cc" ;;
+  alpha-*-linux2)
+        ISA=`awk '/cpu model/{print$4;exit(0);}' /proc/cpuinfo`
+	case ${ISA:-generic} in
+	*[678])	OUT="linux-alpha+bwx-$CC" ;;
+	*)	OUT="linux-alpha-$CC" ;;
+	esac
+	if [ "$CC" = "gcc" ]; then
+	    case ${ISA:-generic} in
+	    EV5|EV45)		options="$options -mcpu=ev5";;
+	    EV56|PCA56)		options="$options -mcpu=ev56";;
+	    *)			options="$options -mcpu=ev6";;
+	    esac
+	fi
+	;;
+  ppc64-*-linux2)
+	echo "WARNING! If you wish to build 64-bit library, then you have to"
+	echo "         invoke './Configure linux-ppc64' *manually*."
+	if [ "$TEST" = "false" -a -t 1 ]; then
+	    echo "         You have about 5 seconds to press Ctrl-C to abort."
+	    (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
+	fi
+	OUT="linux-ppc"
+	;;
+  ppc-*-linux2) OUT="linux-ppc" ;;
+  ia64-*-linux?) OUT="linux-ia64" ;;
+  sparc64-*-linux2)
+	echo "WARNING! If you *know* that your GNU C supports 64-bit/V9 ABI"
+	echo "         and wish to build 64-bit library, then you have to"
+	echo "         invoke './Configure linux64-sparcv9' *manually*."
+	if [ "$TEST" = "false" -a -t 1 ]; then
+	  echo "          You have about 5 seconds to press Ctrl-C to abort."
+	  (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
+	fi
+	OUT="linux-sparcv9" ;;
+  sparc-*-linux2)
+	KARCH=`awk '/^type/{print$3;exit(0);}' /proc/cpuinfo`
+	case ${KARCH:-sun4} in
+	sun4u*)	OUT="linux-sparcv9" ;;
+	sun4m)	OUT="linux-sparcv8" ;;
+	sun4d)	OUT="linux-sparcv8" ;;
+	*)	OUT="linux-generic32"; options="$options -DB_ENDIAN" ;;
+	esac ;;
+  parisc*-*-linux2)
+	# 64-bit builds under parisc64 linux are not supported and
+	# compiler is expected to generate 32-bit objects...
+	CPUARCH=`awk '/cpu family/{print substr($5,1,3); exit(0);}' /proc/cpuinfo`
+	CPUSCHEDULE=`awk '/^cpu.[ 	]*: PA/{print substr($3,3); exit(0);}' /proc/cpuinfo`
+
+	# ??TODO ??  Model transformations
+	# 0. CPU Architecture for the 1.1 processor has letter suffixes. We strip that off
+	#    assuming no further arch. identification will ever be used by GCC.
+	# 1. I'm most concerned about whether is a 7300LC is closer to a 7100 versus a 7100LC.
+	# 2. The variant 64-bit processors cause concern should GCC support explicit schedulers
+	#    for these chips in the future.
+	#         PA7300LC -> 7100LC (1.1)
+	#         PA8200   -> 8000   (2.0)
+	#         PA8500   -> 8000   (2.0)
+	#         PA8600   -> 8000   (2.0)
+
+	CPUSCHEDULE=`echo $CPUSCHEDULE|sed -e 's/7300LC/7100LC/' -e 's/8.00/8000/'`
+	# Finish Model transformations
+
+	options="$options -DB_ENDIAN -mschedule=$CPUSCHEDULE -march=$CPUARCH"
+	OUT="linux-generic32" ;;
+  armv[1-3]*-*-linux2) OUT="linux-generic32" ;;
+  arm*-*-linux2) OUT="linux-armv4" ;;
+  sh*b-*-linux2) OUT="linux-generic32"; options="$options -DB_ENDIAN" ;;
+  sh*-*-linux2)  OUT="linux-generic32"; options="$options -DL_ENDIAN" ;;
+  m68k*-*-linux2) OUT="linux-generic32"; options="$options -DB_ENDIAN" ;;
+  s390-*-linux2) OUT="linux-generic32"; options="$options -DB_ENDIAN" ;;
+  s390x-*-linux2) OUT="linux-s390x" ;;
+  x86_64-*-linux?) OUT="linux-x86_64" ;;
+  *86-*-linux2) OUT="linux-elf"
+	if [ "$GCCVER" -gt 28 ]; then
+          if grep '^model.*Pentium' /proc/cpuinfo >/dev/null ; then
+	    options="$options -march=pentium"
+          fi
+          if grep '^model.*Pentium Pro' /proc/cpuinfo >/dev/null ; then
+	    options="$options -march=pentiumpro"
+          fi
+          if grep '^model.*K6' /proc/cpuinfo >/dev/null ; then
+	    options="$options -march=k6"
+          fi
+        fi ;;
+  *-*-linux1) OUT="linux-aout" ;;
+  *-*-linux2) OUT="linux-generic32" ;;
+  sun4[uv]*-*-solaris2)
+	OUT="solaris-sparcv9-$CC"
+	ISA64=`(isalist) 2>/dev/null | grep sparcv9`
+	if [ "$ISA64" != "" ]; then
+	    if [ "$CC" = "cc" -a $CCVER -ge 50 ]; then
+		echo "WARNING! If you wish to build 64-bit library, then you have to"
+		echo "         invoke './Configure solaris64-sparcv9-cc' *manually*."
+		if [ "$TEST" = "false" -a -t 1 ]; then
+		  echo "         You have about 5 seconds to press Ctrl-C to abort."
+		  (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
+		fi
+	    elif [ "$CC" = "gcc" -a "$GCC_ARCH" = "-m64" ]; then
+		# $GCC_ARCH denotes default ABI chosen by compiler driver
+		# (first one found on the $PATH). I assume that user
+		# expects certain consistency with the rest of his builds
+		# and therefore switch over to 64-bit. <appro>
+		OUT="solaris64-sparcv9-gcc"
+		echo "WARNING! If you wish to build 32-bit library, then you have to"
+		echo "         invoke './Configure solaris-sparcv9-gcc' *manually*."
+		if [ "$TEST" = "false" -a -t 1 ]; then
+		  echo "         You have about 5 seconds to press Ctrl-C to abort."
+		  (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
+		fi
+	    elif [ "$GCC_ARCH" = "-m32" ]; then
+		echo "NOTICE! If you *know* that your GNU C supports 64-bit/V9 ABI"
+		echo "        and wish to build 64-bit library, then you have to"
+		echo "        invoke './Configure solaris64-sparcv9-gcc' *manually*."
+		if [ "$TEST" = "false" -a -t 1 ]; then
+		  echo "         You have about 5 seconds to press Ctrl-C to abort."
+		  (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
+		fi
+	    fi
+	fi
+	;;
+  sun4m-*-solaris2)	OUT="solaris-sparcv8-$CC" ;;
+  sun4d-*-solaris2)	OUT="solaris-sparcv8-$CC" ;;
+  sun4*-*-solaris2)	OUT="solaris-sparcv7-$CC" ;;
+  *86*-*-solaris2)
+	ISA64=`(isalist) 2>/dev/null | grep amd64`
+	if [ "$ISA64" != "" ]; then
+	    OUT="solaris64-x86_64-$CC"
+	else
+	    OUT="solaris-x86-$CC"
+	    if [ `uname -r | sed -e 's/5\.//'` -lt 10 ]; then
+		options="$options no-sse2"
+	    fi
+	fi
+	;;
+  *-*-sunos4)		OUT="sunos-$CC" ;;
+
+  *86*-*-bsdi4)		OUT="BSD-x86-elf"; options="$options no-sse2 -ldl" ;;
+  alpha*-*-*bsd*)	OUT="BSD-generic64"; options="$options -DL_ENDIAN" ;;
+  powerpc64-*-*bsd*)	OUT="BSD-generic64"; options="$options -DB_ENDIAN" ;;
+  sparc64-*-*bsd*)	OUT="BSD-sparc64" ;;
+  ia64-*-*bsd*)		OUT="BSD-ia64" ;;
+  amd64-*-*bsd*)	OUT="BSD-x86_64" ;;
+  *86*-*-*bsd*)		# mimic ld behaviour when it's looking for libc...
+			if [ -L /usr/lib/libc.so ]; then	# [Free|Net]BSD
+			    libc=/usr/lib/libc.so
+			else					# OpenBSD
+			    # ld searches for highest libc.so.* and so do we
+			    libc=`(ls /usr/lib/libc.so.* | tail -1) 2>/dev/null`
+			fi
+			case "`(file -L $libc) 2>/dev/null`" in
+			*ELF*)	OUT="BSD-x86-elf" ;;
+			*)	OUT="BSD-x86"; options="$options no-sse2" ;;
+			esac ;;
+  *-*-*bsd*)		OUT="BSD-generic32" ;;
+
+  *-*-osf)		OUT="osf1-alpha-cc" ;;
+  *-*-tru64)		OUT="tru64-alpha-cc" ;;
+  *-*-[Uu]nix[Ww]are7)
+	if [ "$CC" = "gcc" ]; then
+	  OUT="unixware-7-gcc" ; options="$options no-sse2"
+	else    
+	  OUT="unixware-7" ; options="$options no-sse2 -D__i386__"
+	fi
+	;;
+  *-*-[Uu]nix[Ww]are20*) OUT="unixware-2.0"; options="$options no-sse2 no-sha512" ;;
+  *-*-[Uu]nix[Ww]are21*) OUT="unixware-2.1"; options="$options no-sse2 no-sha512" ;;
+  *-*-vos)
+	options="$options no-threads no-shared no-asm no-dso"
+	EXE=".pm"
+	OUT="vos-$CC" ;;
+  BS2000-siemens-sysv4) OUT="BS2000-OSD" ;;
+  RM*-siemens-sysv4) OUT="ReliantUNIX" ;;
+  *-siemens-sysv4) OUT="SINIX" ;;
+  *-hpux1*)
+	if [ $CC = "gcc" -a $GCC_BITS = "64" ]; then
+	    OUT="hpux64-parisc2-gcc"
+	fi
+	KERNEL_BITS=`(getconf KERNEL_BITS) 2>/dev/null`
+	KERNEL_BITS=${KERNEL_BITS:-32}
+	CPU_VERSION=`(getconf CPU_VERSION) 2>/dev/null`
+	CPU_VERSION=${CPU_VERSION:-0}
+	# See <sys/unistd.h> for further info on CPU_VERSION.
+	if   [ $CPU_VERSION -ge 768 ]; then	# IA-64 CPU
+	     echo "WARNING! 64-bit ABI is the default configured ABI on HP-UXi."
+	     echo "         If you wish to build 32-bit library, the you have to"
+	     echo "         invoke './Configure hpux-ia64-cc' *manually*."
+	     if [ "$TEST" = "false" -a -t 1 ]; then
+		echo "         You have about 5 seconds to press Ctrl-C to abort."
+		(trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
+	     fi
+	     OUT="hpux64-ia64-cc"
+	elif [ $CPU_VERSION -ge 532 ]; then	# PA-RISC 2.x CPU
+	     OUT=${OUT:-"hpux-parisc2-${CC}"}
+	     if [ $KERNEL_BITS -eq 64 -a "$CC" = "cc" ]; then
+		echo "WARNING! If you wish to build 64-bit library then you have to"
+		echo "         invoke './Configure hpux64-parisc2-cc' *manually*."
+		if [ "$TEST" = "false" -a -t 1 ]; then
+		  echo "         You have about 5 seconds to press Ctrl-C to abort."
+		  (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
+		fi
+	     fi
+	elif [ $CPU_VERSION -ge 528 ]; then	# PA-RISC 1.1+ CPU
+	     OUT="hpux-parisc-${CC}"
+	elif [ $CPU_VERSION -ge 523 ]; then	# PA-RISC 1.0 CPU
+	     OUT="hpux-parisc-${CC}"
+	else					# Motorola(?) CPU
+	     OUT="hpux-$CC"
+	fi
+	options="$options -D_REENTRANT" ;;
+  *-hpux)	OUT="hpux-parisc-$CC" ;;
+  *-aix)
+	KERNEL_BITS=`(getconf KERNEL_BITMODE) 2>/dev/null`
+	KERNEL_BITS=${KERNEL_BITS:-32}
+	OBJECT_MODE=${OBJECT_MODE:-32}
+	if [ "$CC" = "gcc" ]; then
+	    OUT="aix-gcc"
+          if [ $OBJECT_MODE -eq 64 ]; then
+            echo 'Your $OBJECT_MODE was found to be set to 64'
+            OUT="aix64-gcc"
+          fi
+	elif [ $OBJECT_MODE -eq 64 ]; then
+	    echo 'Your $OBJECT_MODE was found to be set to 64' 
+	    OUT="aix64-cc"
+	else
+	    OUT="aix-cc"
+	    if [ $KERNEL_BITS -eq 64 ]; then
+		echo "WARNING! If you wish to build 64-bit kit, then you have to"
+		echo "         invoke './Configure aix64-cc' *manually*."
+		if [ "$TEST" = "false" -a -t 1 ]; then
+		    echo "         You have ~5 seconds to press Ctrl-C to abort."
+		    (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
+		fi
+	    fi
+	fi
+	if (lsattr -E -O -l `lsdev -c processor|awk '{print$1;exit}'` | grep -i powerpc) >/dev/null 2>&1; then
+	    :	# this applies even to Power3 and later, as they return PowerPC_POWER[345]
+	else
+	    options="$options no-asm"
+	fi
+	;;
+  # these are all covered by the catchall below
+  # *-dgux) OUT="dgux" ;;
+  mips-sony-newsos4) OUT="newsos4-gcc" ;;
+  *-*-cygwin_pre1.3) OUT="Cygwin-pre1.3" ;;
+  *-*-cygwin) OUT="Cygwin" ;;
+  t3e-cray-unicosmk) OUT="cray-t3e" ;;
+  j90-cray-unicos) OUT="cray-j90" ;;
+  nsr-tandem-nsk) OUT="tandem-c89" ;;
+  beos-*) OUT="$GUESSOS" ;;
+  x86pc-*-qnx6) OUT="QNX6-i386" ;;
+  *-*-qnx6) OUT="QNX6" ;;
+  *) OUT=`echo $GUESSOS | awk -F- '{print $3}'`;;
+esac
+
+# NB: This atalla support has been superceded by the ENGINE support
+# That contains its own header and definitions anyway. Support can
+# be enabled or disabled on any supported platform without external
+# headers, eg. by adding the "hw-atalla" switch to ./config or
+# perl Configure
+#
+# See whether we can compile Atalla support
+#if [ -f /usr/include/atasi.h ]
+#then
+#  options="$options -DATALLA"
+#fi
+
+($CC -Wa,--help -c -o /dev/null -x assembler /dev/null 2>&1 | \
+ grep \\--noexecstack) 2>&1 > /dev/null && \
+  options="$options -Wa,--noexecstack"
+
+# gcc < 2.8 does not support -march=ultrasparc
+if [ "$OUT" = solaris-sparcv9-gcc -a $GCCVER -lt 28 ]
+then
+  echo "WARNING! Falling down to 'solaris-sparcv8-gcc'."
+  echo "         Upgrade to gcc-2.8 or later."
+  sleep 5
+  OUT=solaris-sparcv8-gcc
+fi
+if [ "$OUT" = "linux-sparcv9" -a $GCCVER -lt 28 ]
+then
+  echo "WARNING! Falling down to 'linux-sparcv8'."
+  echo "         Upgrade to gcc-2.8 or later."
+  sleep 5
+  OUT=linux-sparcv8
+fi
+
+case "$GUESSOS" in
+  i386-*) options="$options 386" ;;
+esac
+
+for i in aes bf camellia cast des dh dsa ec hmac idea md2 md5 mdc2 rc2 rc4 rc5 ripemd rsa seed sha
+do
+  if [ ! -d crypto/$i ]
+  then
+    options="$options no-$i"
+  fi
+done
+
+# Discover Kerberos 5 (since it's still a prototype, we don't
+# do any guesses yet, that's why this section is commented away.
+#if [ -d /usr/kerberos ]; then
+#    krb5_dir=/usr/kerberos
+#    if [ \( -f $krb5_dir/lib/libgssapi_krb5.a -o -f $krb5_dir/lib/libgssapi_krb5.so* \)\
+#	-a \( -f $krb5_dir/lib/libkrb5.a -o -f $krb5_dir/lib/libkrb5.so* \)\
+#	-a \( -f $krb5_dir/lib/libcom_err.a -o -f $krb5_dir/lib/libcom_err.so* \)\
+#	-a \( -f $krb5_dir/lib/libk5crypto.a -o -f $krb5_dir/lib/libk5crypto.so* \)\
+#	-a \( -f $krb5_dir/include/krb5.h \) ]; then
+#	options="$options --with-krb5-flavor=MIT"
+#    fi
+#elif [ -d /usr/heimdal ]; then
+#    krb5_dir=/usr/heimdal
+#    if [ \( -f $krb5_dir/lib/libgssapi.a -o -f $krb5_dir/lib/libgssapi.so* \)\
+#	-a \( -f $krb5_dir/lib/libkrb5.a -o -f $krb5_dir/lib/libkrb5.so* \)\
+#	-a \( -f $krb5_dir/lib/libcom_err.a -o -f $krb5_dir/lib/libcom_err.so* \)\
+#	-a \( -f $krb5_dir/include/krb5.h \) ]; then
+#	options="$options --with-krb5-flavor=Heimdal"
+#    fi
+#fi
+
+if [ -z "$OUT" ]; then
+  OUT="$CC"
+fi
+
+if [ ".$PERL" = . ] ; then
+	for i in . `echo $PATH | sed 's/:/ /g'`; do
+		if [ -f "$i/perl5$EXE" ] ; then
+			PERL="$i/perl5$EXE"
+			break;
+		fi;
+	done
+fi
+
+if [ ".$PERL" = . ] ; then
+	for i in . `echo $PATH | sed 's/:/ /g'`; do
+		if [ -f "$i/perl$EXE" ] ; then
+			if "$i/perl$EXE" -e 'exit($]<5.0)'; then
+				PERL="$i/perl$EXE"
+				break;
+			fi;
+		fi;
+	done
+fi
+
+if [ ".$PERL" = . ] ; then
+	echo "You need Perl 5."
+	exit 1
+fi
+
+# run Configure to check to see if we need to specify the 
+# compiler for the platform ... in which case we add it on
+# the end ... otherwise we leave it off
+
+$PERL ./Configure LIST | grep "$OUT-$CC" > /dev/null
+if [ $? = "0" ]; then
+  OUT="$OUT-$CC"
+fi
+
+OUT="$PREFIX$OUT"
+
+$PERL ./Configure LIST | grep "$OUT" > /dev/null
+if [ $? = "0" ]; then
+  echo Configuring for $OUT
+
+  if [ "$TEST" = "true" ]; then
+    echo $PERL ./Configure $OUT $options
+  else
+    $PERL ./Configure $OUT $options
+  fi
+else
+  echo "This system ($OUT) is not supported. See file INSTALL for details."
+fi
+)
diff --git a/openssl/crypto/LPdir_nyi.c b/openssl/crypto/LPdir_nyi.c
new file mode 100644
index 0000000..6c1a50e
--- /dev/null
+++ b/openssl/crypto/LPdir_nyi.c
@@ -0,0 +1,42 @@
+/* $LP: LPlib/source/LPdir_win.c,v 1.1 2004/06/14 10:07:56 _cvs_levitte Exp $ */
+/*
+ * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LPDIR_H
+#include "LPdir.h"
+#endif
+
+struct LP_dir_context_st { void *dummy; };
+const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
+	{
+	errno = EINVAL;
+	return 0;
+	}
+int LP_find_file_end(LP_DIR_CTX **ctx)
+	{
+	errno = EINVAL;
+	return 0;
+	}
diff --git a/openssl/crypto/LPdir_unix.c b/openssl/crypto/LPdir_unix.c
new file mode 100644
index 0000000..b004cd9
--- /dev/null
+++ b/openssl/crypto/LPdir_unix.c
@@ -0,0 +1,127 @@
+/* $LP: LPlib/source/LPdir_unix.c,v 1.11 2004/09/23 22:07:22 _cvs_levitte Exp $ */
+/*
+ * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#ifndef LPDIR_H
+#include "LPdir.h"
+#endif
+
+/* The POSIXly macro for the maximum number of characters in a file path
+   is NAME_MAX.  However, some operating systems use PATH_MAX instead.
+   Therefore, it seems natural to first check for PATH_MAX and use that,
+   and if it doesn't exist, use NAME_MAX. */
+#if defined(PATH_MAX)
+# define LP_ENTRY_SIZE PATH_MAX
+#elif defined(NAME_MAX)
+# define LP_ENTRY_SIZE NAME_MAX
+#endif
+
+/* Of course, there's the possibility that neither PATH_MAX nor NAME_MAX
+   exist.  It's also possible that NAME_MAX exists but is define to a
+   very small value (HP-UX offers 14), so we need to check if we got a
+   result, and if it meets a minimum standard, and create or change it
+   if not. */
+#if !defined(LP_ENTRY_SIZE) || LP_ENTRY_SIZE<255
+# undef LP_ENTRY_SIZE
+# define LP_ENTRY_SIZE 255
+#endif
+
+struct LP_dir_context_st
+{
+  DIR *dir;
+  char entry_name[LP_ENTRY_SIZE+1];
+};
+
+const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
+{
+  struct dirent *direntry = NULL;
+
+  if (ctx == NULL || directory == NULL)
+    {
+      errno = EINVAL;
+      return 0;
+    }
+
+  errno = 0;
+  if (*ctx == NULL)
+    {
+      *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
+      if (*ctx == NULL)
+	{
+	  errno = ENOMEM;
+	  return 0;
+	}
+      memset(*ctx, '\0', sizeof(LP_DIR_CTX));
+
+      (*ctx)->dir = opendir(directory);
+      if ((*ctx)->dir == NULL)
+	{
+	  int save_errno = errno; /* Probably not needed, but I'm paranoid */
+	  free(*ctx);
+	  *ctx = NULL;
+	  errno = save_errno;
+	  return 0;
+	}
+    }
+
+  direntry = readdir((*ctx)->dir);
+  if (direntry == NULL)
+    {
+      return 0;
+    }
+
+  strncpy((*ctx)->entry_name, direntry->d_name, sizeof((*ctx)->entry_name) - 1);
+  (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0';
+  return (*ctx)->entry_name;
+}
+
+int LP_find_file_end(LP_DIR_CTX **ctx)
+{
+  if (ctx != NULL && *ctx != NULL)
+    {
+      int ret = closedir((*ctx)->dir);
+
+      free(*ctx);
+      switch (ret)
+	{
+	case 0:
+	  return 1;
+	case -1:
+	  return 0;
+	default:
+	  break;
+	}
+    }
+  errno = EINVAL;
+  return 0;
+}
diff --git a/openssl/crypto/LPdir_vms.c b/openssl/crypto/LPdir_vms.c
new file mode 100644
index 0000000..7613bd2
--- /dev/null
+++ b/openssl/crypto/LPdir_vms.c
@@ -0,0 +1,206 @@
+/* $LP: LPlib/source/LPdir_vms.c,v 1.20 2004/08/26 13:36:05 _cvs_levitte Exp $ */
+/*
+ * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <descrip.h>
+#include <namdef.h>
+#include <rmsdef.h>
+#include <libfildef.h>
+#include <lib$routines.h>
+#include <strdef.h>
+#include <str$routines.h>
+#include <stsdef.h>
+#ifndef LPDIR_H
+#include "LPdir.h"
+#endif
+#include "vms_rms.h"
+
+/* Some compiler options hide EVMSERR. */
+#ifndef EVMSERR
+# define EVMSERR	65535  /* error for non-translatable VMS errors */
+#endif
+
+struct LP_dir_context_st
+{
+  unsigned long VMS_context;
+  char filespec[ NAMX_MAXRSS+ 1];
+  char result[ NAMX_MAXRSS+ 1];
+  struct dsc$descriptor_d filespec_dsc;
+  struct dsc$descriptor_d result_dsc;
+};
+
+const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
+{
+  int status;
+  char *p, *r;
+  size_t l;
+  unsigned long flags = 0;
+
+/* Arrange 32-bit pointer to (copied) string storage, if needed. */
+#if __INITIAL_POINTER_SIZE == 64
+# pragma pointer_size save
+# pragma pointer_size 32
+        char *ctx_filespec_32p;
+# pragma pointer_size restore
+        char ctx_filespec_32[ NAMX_MAXRSS+ 1];
+#endif /* __INITIAL_POINTER_SIZE == 64 */
+
+#ifdef NAML$C_MAXRSS
+  flags |= LIB$M_FIL_LONG_NAMES;
+#endif
+
+  if (ctx == NULL || directory == NULL)
+    {
+      errno = EINVAL;
+      return 0;
+    }
+
+  errno = 0;
+  if (*ctx == NULL)
+    {
+      size_t filespeclen = strlen(directory);
+      char *filespec = NULL;
+
+      /* MUST be a VMS directory specification!  Let's estimate if it is. */
+      if (directory[filespeclen-1] != ']'
+	  && directory[filespeclen-1] != '>'
+	  && directory[filespeclen-1] != ':')
+	{
+	  errno = EINVAL;
+	  return 0;
+	}
+
+      filespeclen += 4;		/* "*.*;" */
+
+      if (filespeclen > NAMX_MAXRSS)
+	{
+	  errno = ENAMETOOLONG;
+	  return 0;
+	}
+
+      *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
+      if (*ctx == NULL)
+	{
+	  errno = ENOMEM;
+	  return 0;
+	}
+      memset(*ctx, '\0', sizeof(LP_DIR_CTX));
+
+      strcpy((*ctx)->filespec,directory);
+      strcat((*ctx)->filespec,"*.*;");
+
+/* Arrange 32-bit pointer to (copied) string storage, if needed. */
+#if __INITIAL_POINTER_SIZE == 64
+# define CTX_FILESPEC ctx_filespec_32p
+        /* Copy the file name to storage with a 32-bit pointer. */
+        ctx_filespec_32p = ctx_filespec_32;
+        strcpy( ctx_filespec_32p, (*ctx)->filespec);
+#else /* __INITIAL_POINTER_SIZE == 64 */
+# define CTX_FILESPEC (*ctx)->filespec
+#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+      (*ctx)->filespec_dsc.dsc$w_length = filespeclen;
+      (*ctx)->filespec_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+      (*ctx)->filespec_dsc.dsc$b_class = DSC$K_CLASS_S;
+      (*ctx)->filespec_dsc.dsc$a_pointer = CTX_FILESPEC;
+    }
+
+  (*ctx)->result_dsc.dsc$w_length = 0;
+  (*ctx)->result_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+  (*ctx)->result_dsc.dsc$b_class = DSC$K_CLASS_D;
+  (*ctx)->result_dsc.dsc$a_pointer = 0;
+
+  status = lib$find_file(&(*ctx)->filespec_dsc, &(*ctx)->result_dsc,
+			 &(*ctx)->VMS_context, 0, 0, 0, &flags);
+
+  if (status == RMS$_NMF)
+    {
+      errno = 0;
+      vaxc$errno = status;
+      return NULL;
+    }
+
+  if(!$VMS_STATUS_SUCCESS(status))
+    {
+      errno = EVMSERR;
+      vaxc$errno = status;
+      return NULL;
+    }
+
+  /* Quick, cheap and dirty way to discard any device and directory,
+     since we only want file names */
+  l = (*ctx)->result_dsc.dsc$w_length;
+  p = (*ctx)->result_dsc.dsc$a_pointer;
+  r = p;
+  for (; *p; p++)
+    {
+      if (*p == '^' && p[1] != '\0') /* Take care of ODS-5 escapes */
+	{
+	  p++;
+	}
+      else if (*p == ':' || *p == '>' || *p == ']')
+	{
+	  l -= p + 1 - r;
+	  r = p + 1;
+	}
+      else if (*p == ';')
+	{
+	  l = p - r;
+	  break;
+	}
+    }
+
+  strncpy((*ctx)->result, r, l);
+  (*ctx)->result[l] = '\0';
+  str$free1_dx(&(*ctx)->result_dsc);
+
+  return (*ctx)->result;
+}
+
+int LP_find_file_end(LP_DIR_CTX **ctx)
+{
+  if (ctx != NULL && *ctx != NULL)
+    {
+      int status = lib$find_file_end(&(*ctx)->VMS_context);
+
+      free(*ctx);
+
+      if(!$VMS_STATUS_SUCCESS(status))
+	{
+	  errno = EVMSERR;
+	  vaxc$errno = status;
+	  return 0;
+	}
+      return 1;
+    }
+  errno = EINVAL;
+  return 0;
+}
+
diff --git a/openssl/crypto/LPdir_win.c b/openssl/crypto/LPdir_win.c
new file mode 100644
index 0000000..702dbc7
--- /dev/null
+++ b/openssl/crypto/LPdir_win.c
@@ -0,0 +1,153 @@
+/* $LP: LPlib/source/LPdir_win.c,v 1.10 2004/08/26 13:36:05 _cvs_levitte Exp $ */
+/*
+ * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <windows.h>
+#include <tchar.h>
+#ifndef LPDIR_H
+#include "LPdir.h"
+#endif
+
+/* We're most likely overcautious here, but let's reserve for
+    broken WinCE headers and explicitly opt for UNICODE call.
+    Keep in mind that our WinCE builds are compiled with -DUNICODE
+    [as well as -D_UNICODE]. */
+#if defined(LP_SYS_WINCE) && !defined(FindFirstFile)
+# define FindFirstFile FindFirstFileW
+#endif
+#if defined(LP_SYS_WINCE) && !defined(FindFirstFile)
+# define FindNextFile FindNextFileW
+#endif
+
+#ifndef NAME_MAX
+#define NAME_MAX 255
+#endif
+
+struct LP_dir_context_st
+{
+  WIN32_FIND_DATA ctx;
+  HANDLE handle;
+  char entry_name[NAME_MAX+1];
+};
+
+const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
+{
+  if (ctx == NULL || directory == NULL)
+    {
+      errno = EINVAL;
+      return 0;
+    }
+
+  errno = 0;
+  if (*ctx == NULL)
+    {
+      *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
+      if (*ctx == NULL)
+	{
+	  errno = ENOMEM;
+	  return 0;
+	}
+      memset(*ctx, '\0', sizeof(LP_DIR_CTX));
+
+      if (sizeof(TCHAR) != sizeof(char))
+	{
+	  TCHAR *wdir = NULL;
+	  /* len_0 denotes string length *with* trailing 0 */ 
+	  size_t index = 0,len_0 = strlen(directory) + 1;
+
+	  wdir = (TCHAR *)malloc(len_0 * sizeof(TCHAR));
+	  if (wdir == NULL)
+	    {
+	      free(*ctx);
+	      *ctx = NULL;
+	      errno = ENOMEM;
+	      return 0;
+	    }
+
+#ifdef LP_MULTIBYTE_AVAILABLE
+	  if (!MultiByteToWideChar(CP_ACP, 0, directory, len_0, (WCHAR *)wdir, len_0))
+#endif
+	    for (index = 0; index < len_0; index++)
+	      wdir[index] = (TCHAR)directory[index];
+
+	  (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
+
+	  free(wdir);
+	}
+      else
+	(*ctx)->handle = FindFirstFile((TCHAR *)directory, &(*ctx)->ctx);
+
+      if ((*ctx)->handle == INVALID_HANDLE_VALUE)
+	{
+	  free(*ctx);
+	  *ctx = NULL;
+	  errno = EINVAL;
+	  return 0;
+	}
+    }
+  else
+    {
+      if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE)
+	{
+	  return 0;
+	}
+    }
+
+  if (sizeof(TCHAR) != sizeof(char))
+    {
+      TCHAR *wdir = (*ctx)->ctx.cFileName;
+      size_t index, len_0 = 0;
+
+      while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1)) len_0++;
+      len_0++;
+
+#ifdef LP_MULTIBYTE_AVAILABLE
+      if (!WideCharToMultiByte(CP_ACP, 0, (WCHAR *)wdir, len_0, (*ctx)->entry_name,
+			       sizeof((*ctx)->entry_name), NULL, 0))
+#endif
+	for (index = 0; index < len_0; index++)
+	  (*ctx)->entry_name[index] = (char)wdir[index];
+    }
+  else
+    strncpy((*ctx)->entry_name, (const char *)(*ctx)->ctx.cFileName,
+	    sizeof((*ctx)->entry_name)-1);
+
+  (*ctx)->entry_name[sizeof((*ctx)->entry_name)-1] = '\0';
+
+  return (*ctx)->entry_name;
+}
+
+int LP_find_file_end(LP_DIR_CTX **ctx)
+{
+  if (ctx != NULL && *ctx != NULL)
+    {
+      FindClose((*ctx)->handle);
+      free(*ctx);
+      *ctx = NULL;
+      return 1;
+    }
+  errno = EINVAL;
+  return 0;
+}
diff --git a/openssl/crypto/LPdir_win32.c b/openssl/crypto/LPdir_win32.c
new file mode 100644
index 0000000..e39872d
--- /dev/null
+++ b/openssl/crypto/LPdir_win32.c
@@ -0,0 +1,30 @@
+/* $LP: LPlib/source/LPdir_win32.c,v 1.3 2004/08/26 13:36:05 _cvs_levitte Exp $ */
+/*
+ * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LP_SYS_WIN32
+#define LP_MULTIBYTE_AVAILABLE
+#include "LPdir_win.c"
diff --git a/openssl/crypto/LPdir_wince.c b/openssl/crypto/LPdir_wince.c
new file mode 100644
index 0000000..ab0e1e6
--- /dev/null
+++ b/openssl/crypto/LPdir_wince.c
@@ -0,0 +1,31 @@
+/* $LP: LPlib/source/LPdir_wince.c,v 1.3 2004/08/26 13:36:05 _cvs_levitte Exp $ */
+/*
+ * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LP_SYS_WINCE
+/* We might want to define LP_MULTIBYTE_AVAILABLE here.  It's currently
+   under investigation what the exact conditions would be */
+#include "LPdir_win.c"
diff --git a/openssl/crypto/Makefile b/openssl/crypto/Makefile
new file mode 100644
index 0000000..85d9f24
--- /dev/null
+++ b/openssl/crypto/Makefile
@@ -0,0 +1,201 @@
+#
+# OpenSSL/crypto/Makefile
+#
+
+DIR=		crypto
+TOP=		..
+CC=		cc
+INCLUDE=	-I. -I$(TOP) -I../include $(ZLIB_INCLUDE)
+# INCLUDES targets sudbirs!
+INCLUDES=	-I.. -I../.. -I../asn1 -I../evp -I../../include $(ZLIB_INCLUDE)
+CFLAG=		-g
+MAKEDEPPROG=	makedepend
+MAKEDEPEND=	$(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
+MAKEFILE=       Makefile
+RM=             rm -f
+AR=		ar r
+
+RECURSIVE_MAKE=	[ -n "$(SDIRS)" ] && for i in $(SDIRS) ; do \
+		    (cd $$i && echo "making $$target in $(DIR)/$$i..." && \
+		    $(MAKE) -e TOP=../.. DIR=$$i INCLUDES='$(INCLUDES)' $$target ) || exit 1; \
+		done;
+
+PEX_LIBS=
+EX_LIBS=
+ 
+CFLAGS= $(INCLUDE) $(CFLAG)
+ASFLAGS= $(INCLUDE) $(ASFLAG)
+AFLAGS=$(ASFLAGS)
+CPUID_OBJ=mem_clr.o
+
+LIBS=
+
+GENERAL=Makefile README crypto-lib.com install.com
+
+LIB= $(TOP)/libcrypto.a
+SHARED_LIB= libcrypto$(SHLIB_EXT)
+LIBSRC=	cryptlib.c mem.c mem_clr.c mem_dbg.c cversion.c ex_data.c cpt_err.c ebcdic.c uid.c o_time.c o_str.c o_dir.c
+LIBOBJ= cryptlib.o mem.o mem_dbg.o cversion.o ex_data.o cpt_err.o ebcdic.o uid.o o_time.o o_str.o o_dir.o $(CPUID_OBJ)
+
+SRC= $(LIBSRC)
+
+EXHEADER= crypto.h opensslv.h opensslconf.h ebcdic.h symhacks.h \
+	ossl_typ.h
+HEADER=	cryptlib.h buildinf.h md32_common.h o_time.h o_str.h o_dir.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	@(cd ..; $(MAKE) DIRS=$(DIR) all)
+
+all: shared
+
+buildinf.h: ../Makefile
+	( echo "#ifndef MK1MF_BUILD"; \
+	echo '  /* auto-generated by crypto/Makefile for crypto/cversion.c */'; \
+	echo '  #define CFLAGS "$(CC) $(CFLAG)"'; \
+	echo '  #define PLATFORM "$(PLATFORM)"'; \
+	echo "  #define DATE \"`LC_ALL=C LC_TIME=C date`\""; \
+	echo '#endif' ) >buildinf.h
+
+x86cpuid.s:	x86cpuid.pl perlasm/x86asm.pl
+	$(PERL) x86cpuid.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
+
+applink.o:	$(TOP)/ms/applink.c
+	$(CC) $(CFLAGS) -c -o $@ $(TOP)/ms/applink.c
+
+uplink.o:	$(TOP)/ms/uplink.c applink.o
+	$(CC) $(CFLAGS) -c -o $@ $(TOP)/ms/uplink.c
+
+uplink-cof.s:	$(TOP)/ms/uplink.pl
+	$(PERL) $(TOP)/ms/uplink.pl coff > $@
+
+x86_64cpuid.s: x86_64cpuid.pl
+	$(PERL) x86_64cpuid.pl $(PERLASM_SCHEME) > $@
+ia64cpuid.s: ia64cpuid.S
+	$(CC) $(CFLAGS) -E ia64cpuid.S > $@
+ppccpuid.s:	ppccpuid.pl;	$(PERL) ppccpuid.pl $(PERLASM_SCHEME) $@
+alphacpuid.s:	alphacpuid.pl
+	$(PERL) $< | $(CC) -E - | tee $@ > /dev/null
+
+testapps:
+	[ -z "$(THIS)" ] || (	if echo $(SDIRS) | fgrep ' des '; \
+				then cd des && $(MAKE) -e des; fi )
+	[ -z "$(THIS)" ] || ( cd pkcs7 && $(MAKE) -e testapps );
+	@if [ -z "$(THIS)" ]; then $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; fi
+
+subdirs:
+	@target=all; $(RECURSIVE_MAKE)
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+	@target=files; $(RECURSIVE_MAKE)
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../apps $(APPS)
+	@target=links; $(RECURSIVE_MAKE)
+
+# lib: $(LIB): are splitted to avoid end-less loop
+lib:	$(LIB)
+	@touch lib
+$(LIB):	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+
+shared: buildinf.h lib subdirs
+	if [ -n "$(SHARED_LIBS)" ]; then \
+		(cd ..; $(MAKE) $(SHARED_LIB)); \
+	fi
+
+libs:
+	@target=lib; $(RECURSIVE_MAKE)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ;\
+	do \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+	@target=install; $(RECURSIVE_MAKE)
+
+lint:
+	@target=lint; $(RECURSIVE_MAKE)
+
+depend:
+	@[ -z "$(THIS)" -o -f buildinf.h ] || touch buildinf.h # fake buildinf.h if it does not exist
+	@[ -z "$(THIS)" ] || $(MAKEDEPEND) -- $(CFLAG) $(INCLUDE) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+	@[ -z "$(THIS)" -o -s buildinf.h ] || rm buildinf.h
+	@[ -z "$(THIS)" ] || (set -e; target=depend; $(RECURSIVE_MAKE) )
+	@if [ -z "$(THIS)" ]; then $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; fi
+
+clean:
+	rm -f buildinf.h *.s *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+	@target=clean; $(RECURSIVE_MAKE)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+	rm -f opensslconf.h
+	@target=dclean; $(RECURSIVE_MAKE)
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+cpt_err.o: ../include/openssl/bio.h ../include/openssl/crypto.h
+cpt_err.o: ../include/openssl/e_os2.h ../include/openssl/err.h
+cpt_err.o: ../include/openssl/lhash.h ../include/openssl/opensslconf.h
+cpt_err.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+cpt_err.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+cpt_err.o: ../include/openssl/symhacks.h cpt_err.c
+cryptlib.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
+cryptlib.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+cryptlib.o: ../include/openssl/err.h ../include/openssl/lhash.h
+cryptlib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+cryptlib.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+cryptlib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.c
+cryptlib.o: cryptlib.h
+cversion.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
+cversion.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+cversion.o: ../include/openssl/err.h ../include/openssl/lhash.h
+cversion.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+cversion.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+cversion.o: ../include/openssl/stack.h ../include/openssl/symhacks.h buildinf.h
+cversion.o: cryptlib.h cversion.c
+ebcdic.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h ebcdic.c
+ex_data.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
+ex_data.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+ex_data.o: ../include/openssl/err.h ../include/openssl/lhash.h
+ex_data.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ex_data.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+ex_data.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
+ex_data.o: ex_data.c
+mem.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
+mem.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+mem.o: ../include/openssl/err.h ../include/openssl/lhash.h
+mem.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+mem.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+mem.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
+mem.o: mem.c
+mem_clr.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+mem_clr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+mem_clr.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+mem_clr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h mem_clr.c
+mem_dbg.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
+mem_dbg.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+mem_dbg.o: ../include/openssl/err.h ../include/openssl/lhash.h
+mem_dbg.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+mem_dbg.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+mem_dbg.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
+mem_dbg.o: mem_dbg.c
+o_dir.o: ../e_os.h ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
+o_dir.o: LPdir_unix.c o_dir.c o_dir.h
+o_str.o: ../e_os.h ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
+o_str.o: o_str.c o_str.h
+o_time.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h o_time.c
+o_time.o: o_time.h
+uid.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+uid.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+uid.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+uid.o: ../include/openssl/stack.h ../include/openssl/symhacks.h uid.c
diff --git a/openssl/crypto/aes/Makefile b/openssl/crypto/aes/Makefile
new file mode 100644
index 0000000..c501a43
--- /dev/null
+++ b/openssl/crypto/aes/Makefile
@@ -0,0 +1,132 @@
+#
+# crypto/aes/Makefile
+#
+
+DIR=	aes
+TOP=	../..
+CC=	cc
+CPP=	$(CC) -E
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+AES_ENC=aes_core.o aes_cbc.o
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+ASFLAGS= $(INCLUDES) $(ASFLAG)
+AFLAGS= $(ASFLAGS)
+
+GENERAL=Makefile
+#TEST=aestest.c
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=aes_core.c aes_misc.c aes_ecb.c aes_cbc.c aes_cfb.c aes_ofb.c \
+       aes_ctr.c aes_ige.c aes_wrap.c
+LIBOBJ=aes_misc.o aes_ecb.o aes_cfb.o aes_ofb.o aes_ctr.o aes_ige.o aes_wrap.o \
+       $(AES_ENC)
+
+SRC= $(LIBSRC)
+
+EXHEADER= aes.h
+HEADER= aes_locl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+aes-ia64.s: asm/aes-ia64.S
+	$(CC) $(CFLAGS) -E asm/aes-ia64.S > $@
+
+aes-586.s:	asm/aes-586.pl ../perlasm/x86asm.pl
+	$(PERL) asm/aes-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
+
+aes-x86_64.s: asm/aes-x86_64.pl
+	$(PERL) asm/aes-x86_64.pl $(PERLASM_SCHEME) > $@
+
+aes-sparcv9.s: asm/aes-sparcv9.pl
+	$(PERL) asm/aes-sparcv9.pl $(CFLAGS) > $@
+
+aes-ppc.s:	asm/aes-ppc.pl
+	$(PERL) asm/aes-ppc.pl $(PERLASM_SCHEME) $@
+
+# GNU make "catch all"
+aes-%.s:	asm/aes-%.pl;	$(PERL) $< $(CFLAGS) > $@
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+aes_cbc.o: ../../include/openssl/aes.h ../../include/openssl/modes.h
+aes_cbc.o: ../../include/openssl/opensslconf.h aes_cbc.c
+aes_cfb.o: ../../include/openssl/aes.h ../../include/openssl/modes.h
+aes_cfb.o: ../../include/openssl/opensslconf.h aes_cfb.c
+aes_core.o: ../../include/openssl/aes.h ../../include/openssl/e_os2.h
+aes_core.o: ../../include/openssl/opensslconf.h aes_core.c aes_locl.h
+aes_ctr.o: ../../include/openssl/aes.h ../../include/openssl/modes.h
+aes_ctr.o: ../../include/openssl/opensslconf.h aes_ctr.c
+aes_ecb.o: ../../include/openssl/aes.h ../../include/openssl/e_os2.h
+aes_ecb.o: ../../include/openssl/opensslconf.h aes_ecb.c aes_locl.h
+aes_ige.o: ../../e_os.h ../../include/openssl/aes.h ../../include/openssl/bio.h
+aes_ige.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+aes_ige.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+aes_ige.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+aes_ige.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+aes_ige.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+aes_ige.o: ../../include/openssl/symhacks.h ../cryptlib.h aes_ige.c aes_locl.h
+aes_misc.o: ../../include/openssl/aes.h ../../include/openssl/e_os2.h
+aes_misc.o: ../../include/openssl/opensslconf.h
+aes_misc.o: ../../include/openssl/opensslv.h aes_locl.h aes_misc.c
+aes_ofb.o: ../../include/openssl/aes.h ../../include/openssl/modes.h
+aes_ofb.o: ../../include/openssl/opensslconf.h aes_ofb.c
+aes_wrap.o: ../../e_os.h ../../include/openssl/aes.h
+aes_wrap.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+aes_wrap.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+aes_wrap.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+aes_wrap.o: ../../include/openssl/opensslconf.h
+aes_wrap.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+aes_wrap.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+aes_wrap.o: ../../include/openssl/symhacks.h ../cryptlib.h aes_wrap.c
diff --git a/openssl/crypto/aes/README b/openssl/crypto/aes/README
new file mode 100644
index 0000000..0f9620a
--- /dev/null
+++ b/openssl/crypto/aes/README
@@ -0,0 +1,3 @@
+This is an OpenSSL-compatible version of AES (also called Rijndael).
+aes_core.c is basically the same as rijndael-alg-fst.c but with an
+API that looks like the rest of the OpenSSL symmetric cipher suite.
diff --git a/openssl/crypto/aes/aes.h b/openssl/crypto/aes/aes.h
new file mode 100644
index 0000000..d2c9973
--- /dev/null
+++ b/openssl/crypto/aes/aes.h
@@ -0,0 +1,142 @@
+/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#ifndef HEADER_AES_H
+#define HEADER_AES_H
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_AES
+#error AES is disabled.
+#endif
+
+#include <stddef.h>
+
+#define AES_ENCRYPT	1
+#define AES_DECRYPT	0
+
+/* Because array size can't be a const in C, the following two are macros.
+   Both sizes are in bytes. */
+#define AES_MAXNR 14
+#define AES_BLOCK_SIZE 16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* This should be a hidden type, but EVP requires that the size be known */
+struct aes_key_st {
+#ifdef AES_LONG
+    unsigned long rd_key[4 *(AES_MAXNR + 1)];
+#else
+    unsigned int rd_key[4 *(AES_MAXNR + 1)];
+#endif
+    int rounds;
+};
+typedef struct aes_key_st AES_KEY;
+
+const char *AES_options(void);
+
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+	AES_KEY *key);
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+	AES_KEY *key);
+
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+	const AES_KEY *key);
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+	const AES_KEY *key);
+
+void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
+	const AES_KEY *key, const int enc);
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const AES_KEY *key,
+	unsigned char *ivec, const int enc);
+void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const AES_KEY *key,
+	unsigned char *ivec, int *num, const int enc);
+void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const AES_KEY *key,
+	unsigned char *ivec, int *num, const int enc);
+void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const AES_KEY *key,
+	unsigned char *ivec, int *num, const int enc);
+void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const AES_KEY *key,
+	unsigned char *ivec, int *num);
+void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const AES_KEY *key,
+	unsigned char ivec[AES_BLOCK_SIZE],
+	unsigned char ecount_buf[AES_BLOCK_SIZE],
+	unsigned int *num);
+/* NB: the IV is _two_ blocks long */
+void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
+		     size_t length, const AES_KEY *key,
+		     unsigned char *ivec, const int enc);
+/* NB: the IV is _four_ blocks long */
+void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
+			size_t length, const AES_KEY *key,
+			const AES_KEY *key2, const unsigned char *ivec,
+			const int enc);
+
+int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
+		unsigned char *out,
+		const unsigned char *in, unsigned int inlen);
+int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
+		unsigned char *out,
+		const unsigned char *in, unsigned int inlen);
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* !HEADER_AES_H */
diff --git a/openssl/crypto/aes/aes_cbc.c b/openssl/crypto/aes/aes_cbc.c
new file mode 100644
index 0000000..227f756
--- /dev/null
+++ b/openssl/crypto/aes/aes_cbc.c
@@ -0,0 +1,63 @@
+/* crypto/aes/aes_cbc.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/aes.h>
+#include <openssl/modes.h>
+
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+		     size_t len, const AES_KEY *key,
+		     unsigned char *ivec, const int enc) {
+
+	if (enc)
+		CRYPTO_cbc128_encrypt(in,out,len,key,ivec,(block128_f)AES_encrypt);
+	else
+		CRYPTO_cbc128_decrypt(in,out,len,key,ivec,(block128_f)AES_decrypt);
+}
diff --git a/openssl/crypto/aes/aes_cfb.c b/openssl/crypto/aes/aes_cfb.c
new file mode 100644
index 0000000..0c6d058
--- /dev/null
+++ b/openssl/crypto/aes/aes_cfb.c
@@ -0,0 +1,81 @@
+/* crypto/aes/aes_cfb.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 2002-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/aes.h>
+#include <openssl/modes.h>
+
+/* The input and output encrypted as though 128bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 128bit block we have used is contained in *num;
+ */
+
+void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const AES_KEY *key,
+	unsigned char *ivec, int *num, const int enc) {
+
+	CRYPTO_cfb128_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);
+}
+
+/* N.B. This expects the input to be packed, MS bit first */
+void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
+		      size_t length, const AES_KEY *key,
+		      unsigned char *ivec, int *num, const int enc)
+    {
+    CRYPTO_cfb128_1_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);
+    }
+
+void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+		      size_t length, const AES_KEY *key,
+		      unsigned char *ivec, int *num, const int enc)
+    {
+    CRYPTO_cfb128_8_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);
+    }
+
diff --git a/openssl/crypto/aes/aes_core.c b/openssl/crypto/aes/aes_core.c
new file mode 100644
index 0000000..a7ec54f
--- /dev/null
+++ b/openssl/crypto/aes/aes_core.c
@@ -0,0 +1,1358 @@
+/* crypto/aes/aes_core.c -*- mode:C; c-file-style: "eay" -*- */
+/**
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Note: rewritten a little bit to provide error control and an OpenSSL-
+   compatible API */
+
+#ifndef AES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+#include <stdlib.h>
+#include <openssl/aes.h>
+#include "aes_locl.h"
+
+#ifndef AES_ASM
+/*
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01];
+*/
+
+static const u32 Te0[256] = {
+    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+static const u32 Te1[256] = {
+    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+static const u32 Te2[256] = {
+    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+static const u32 Te3[256] = {
+    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+
+static const u32 Td0[256] = {
+    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+};
+static const u32 Td1[256] = {
+    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+};
+static const u32 Td2[256] = {
+    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+};
+static const u32 Td3[256] = {
+    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+};
+static const u8 Td4[256] = {
+    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
+    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
+    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
+    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
+    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
+    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
+    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
+    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
+    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
+    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
+    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
+    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
+    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
+    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
+    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
+    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
+    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
+    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
+    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
+    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
+    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
+    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
+    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
+    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
+    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
+    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
+    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
+    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
+    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
+    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
+    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
+    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
+};
+static const u32 rcon[] = {
+	0x01000000, 0x02000000, 0x04000000, 0x08000000,
+	0x10000000, 0x20000000, 0x40000000, 0x80000000,
+	0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ */
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+			AES_KEY *key) {
+
+	u32 *rk;
+   	int i = 0;
+	u32 temp;
+
+	if (!userKey || !key)
+		return -1;
+	if (bits != 128 && bits != 192 && bits != 256)
+		return -2;
+
+	rk = key->rd_key;
+
+	if (bits==128)
+		key->rounds = 10;
+	else if (bits==192)
+		key->rounds = 12;
+	else
+		key->rounds = 14;
+
+	rk[0] = GETU32(userKey     );
+	rk[1] = GETU32(userKey +  4);
+	rk[2] = GETU32(userKey +  8);
+	rk[3] = GETU32(userKey + 12);
+	if (bits == 128) {
+		while (1) {
+			temp  = rk[3];
+			rk[4] = rk[0] ^
+				(Te2[(temp >> 16) & 0xff] & 0xff000000) ^
+				(Te3[(temp >>  8) & 0xff] & 0x00ff0000) ^
+				(Te0[(temp      ) & 0xff] & 0x0000ff00) ^
+				(Te1[(temp >> 24)       ] & 0x000000ff) ^
+				rcon[i];
+			rk[5] = rk[1] ^ rk[4];
+			rk[6] = rk[2] ^ rk[5];
+			rk[7] = rk[3] ^ rk[6];
+			if (++i == 10) {
+				return 0;
+			}
+			rk += 4;
+		}
+	}
+	rk[4] = GETU32(userKey + 16);
+	rk[5] = GETU32(userKey + 20);
+	if (bits == 192) {
+		while (1) {
+			temp = rk[ 5];
+			rk[ 6] = rk[ 0] ^
+				(Te2[(temp >> 16) & 0xff] & 0xff000000) ^
+				(Te3[(temp >>  8) & 0xff] & 0x00ff0000) ^
+				(Te0[(temp      ) & 0xff] & 0x0000ff00) ^
+				(Te1[(temp >> 24)       ] & 0x000000ff) ^
+				rcon[i];
+			rk[ 7] = rk[ 1] ^ rk[ 6];
+			rk[ 8] = rk[ 2] ^ rk[ 7];
+			rk[ 9] = rk[ 3] ^ rk[ 8];
+			if (++i == 8) {
+				return 0;
+			}
+			rk[10] = rk[ 4] ^ rk[ 9];
+			rk[11] = rk[ 5] ^ rk[10];
+			rk += 6;
+		}
+	}
+	rk[6] = GETU32(userKey + 24);
+	rk[7] = GETU32(userKey + 28);
+	if (bits == 256) {
+		while (1) {
+			temp = rk[ 7];
+			rk[ 8] = rk[ 0] ^
+				(Te2[(temp >> 16) & 0xff] & 0xff000000) ^
+				(Te3[(temp >>  8) & 0xff] & 0x00ff0000) ^
+				(Te0[(temp      ) & 0xff] & 0x0000ff00) ^
+				(Te1[(temp >> 24)       ] & 0x000000ff) ^
+				rcon[i];
+			rk[ 9] = rk[ 1] ^ rk[ 8];
+			rk[10] = rk[ 2] ^ rk[ 9];
+			rk[11] = rk[ 3] ^ rk[10];
+			if (++i == 7) {
+				return 0;
+			}
+			temp = rk[11];
+			rk[12] = rk[ 4] ^
+				(Te2[(temp >> 24)       ] & 0xff000000) ^
+				(Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^
+				(Te0[(temp >>  8) & 0xff] & 0x0000ff00) ^
+				(Te1[(temp      ) & 0xff] & 0x000000ff);
+			rk[13] = rk[ 5] ^ rk[12];
+			rk[14] = rk[ 6] ^ rk[13];
+			rk[15] = rk[ 7] ^ rk[14];
+
+			rk += 8;
+        	}
+	}
+	return 0;
+}
+
+/**
+ * Expand the cipher key into the decryption key schedule.
+ */
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+			 AES_KEY *key) {
+
+        u32 *rk;
+	int i, j, status;
+	u32 temp;
+
+	/* first, start with an encryption schedule */
+	status = AES_set_encrypt_key(userKey, bits, key);
+	if (status < 0)
+		return status;
+
+	rk = key->rd_key;
+
+	/* invert the order of the round keys: */
+	for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
+		temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
+		temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+		temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+		temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+	}
+	/* apply the inverse MixColumn transform to all round keys but the first and the last: */
+	for (i = 1; i < (key->rounds); i++) {
+		rk += 4;
+		rk[0] =
+			Td0[Te1[(rk[0] >> 24)       ] & 0xff] ^
+			Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^
+			Td2[Te1[(rk[0] >>  8) & 0xff] & 0xff] ^
+			Td3[Te1[(rk[0]      ) & 0xff] & 0xff];
+		rk[1] =
+			Td0[Te1[(rk[1] >> 24)       ] & 0xff] ^
+			Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^
+			Td2[Te1[(rk[1] >>  8) & 0xff] & 0xff] ^
+			Td3[Te1[(rk[1]      ) & 0xff] & 0xff];
+		rk[2] =
+			Td0[Te1[(rk[2] >> 24)       ] & 0xff] ^
+			Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^
+			Td2[Te1[(rk[2] >>  8) & 0xff] & 0xff] ^
+			Td3[Te1[(rk[2]      ) & 0xff] & 0xff];
+		rk[3] =
+			Td0[Te1[(rk[3] >> 24)       ] & 0xff] ^
+			Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^
+			Td2[Te1[(rk[3] >>  8) & 0xff] & 0xff] ^
+			Td3[Te1[(rk[3]      ) & 0xff] & 0xff];
+	}
+	return 0;
+}
+
+/*
+ * Encrypt a single block
+ * in and out can overlap
+ */
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+		 const AES_KEY *key) {
+
+	const u32 *rk;
+	u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+	int r;
+#endif /* ?FULL_UNROLL */
+
+	assert(in && out && key);
+	rk = key->rd_key;
+
+	/*
+	 * map byte array block to cipher state
+	 * and add initial round key:
+	 */
+	s0 = GETU32(in     ) ^ rk[0];
+	s1 = GETU32(in +  4) ^ rk[1];
+	s2 = GETU32(in +  8) ^ rk[2];
+	s3 = GETU32(in + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+	/* round 1: */
+   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
+   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
+   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
+   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
+   	/* round 2: */
+   	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
+   	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
+   	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
+   	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
+	/* round 3: */
+   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
+   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
+   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
+   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
+   	/* round 4: */
+   	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
+   	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
+   	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
+   	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
+	/* round 5: */
+   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
+   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
+   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
+   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
+   	/* round 6: */
+   	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
+   	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
+   	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
+   	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
+	/* round 7: */
+   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
+   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
+   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
+   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
+   	/* round 8: */
+   	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
+   	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
+   	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
+   	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
+	/* round 9: */
+   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
+   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
+   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
+   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
+    if (key->rounds > 10) {
+        /* round 10: */
+        s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
+        s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
+        s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
+        s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
+        /* round 11: */
+        t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
+        t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
+        t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
+        t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
+        if (key->rounds > 12) {
+            /* round 12: */
+            s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
+            s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
+            s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
+            s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
+            /* round 13: */
+            t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
+            t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
+            t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
+            t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
+        }
+    }
+    rk += key->rounds << 2;
+#else  /* !FULL_UNROLL */
+    /*
+     * Nr - 1 full rounds:
+     */
+    r = key->rounds >> 1;
+    for (;;) {
+        t0 =
+            Te0[(s0 >> 24)       ] ^
+            Te1[(s1 >> 16) & 0xff] ^
+            Te2[(s2 >>  8) & 0xff] ^
+            Te3[(s3      ) & 0xff] ^
+            rk[4];
+        t1 =
+            Te0[(s1 >> 24)       ] ^
+            Te1[(s2 >> 16) & 0xff] ^
+            Te2[(s3 >>  8) & 0xff] ^
+            Te3[(s0      ) & 0xff] ^
+            rk[5];
+        t2 =
+            Te0[(s2 >> 24)       ] ^
+            Te1[(s3 >> 16) & 0xff] ^
+            Te2[(s0 >>  8) & 0xff] ^
+            Te3[(s1      ) & 0xff] ^
+            rk[6];
+        t3 =
+            Te0[(s3 >> 24)       ] ^
+            Te1[(s0 >> 16) & 0xff] ^
+            Te2[(s1 >>  8) & 0xff] ^
+            Te3[(s2      ) & 0xff] ^
+            rk[7];
+
+        rk += 8;
+        if (--r == 0) {
+            break;
+        }
+
+        s0 =
+            Te0[(t0 >> 24)       ] ^
+            Te1[(t1 >> 16) & 0xff] ^
+            Te2[(t2 >>  8) & 0xff] ^
+            Te3[(t3      ) & 0xff] ^
+            rk[0];
+        s1 =
+            Te0[(t1 >> 24)       ] ^
+            Te1[(t2 >> 16) & 0xff] ^
+            Te2[(t3 >>  8) & 0xff] ^
+            Te3[(t0      ) & 0xff] ^
+            rk[1];
+        s2 =
+            Te0[(t2 >> 24)       ] ^
+            Te1[(t3 >> 16) & 0xff] ^
+            Te2[(t0 >>  8) & 0xff] ^
+            Te3[(t1      ) & 0xff] ^
+            rk[2];
+        s3 =
+            Te0[(t3 >> 24)       ] ^
+            Te1[(t0 >> 16) & 0xff] ^
+            Te2[(t1 >>  8) & 0xff] ^
+            Te3[(t2      ) & 0xff] ^
+            rk[3];
+    }
+#endif /* ?FULL_UNROLL */
+    /*
+	 * apply last round and
+	 * map cipher state to byte array block:
+	 */
+	s0 =
+		(Te2[(t0 >> 24)       ] & 0xff000000) ^
+		(Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+		(Te0[(t2 >>  8) & 0xff] & 0x0000ff00) ^
+		(Te1[(t3      ) & 0xff] & 0x000000ff) ^
+		rk[0];
+	PUTU32(out     , s0);
+	s1 =
+		(Te2[(t1 >> 24)       ] & 0xff000000) ^
+		(Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+		(Te0[(t3 >>  8) & 0xff] & 0x0000ff00) ^
+		(Te1[(t0      ) & 0xff] & 0x000000ff) ^
+		rk[1];
+	PUTU32(out +  4, s1);
+	s2 =
+		(Te2[(t2 >> 24)       ] & 0xff000000) ^
+		(Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+		(Te0[(t0 >>  8) & 0xff] & 0x0000ff00) ^
+		(Te1[(t1      ) & 0xff] & 0x000000ff) ^
+		rk[2];
+	PUTU32(out +  8, s2);
+	s3 =
+		(Te2[(t3 >> 24)       ] & 0xff000000) ^
+		(Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+		(Te0[(t1 >>  8) & 0xff] & 0x0000ff00) ^
+		(Te1[(t2      ) & 0xff] & 0x000000ff) ^
+		rk[3];
+	PUTU32(out + 12, s3);
+}
+
+/*
+ * Decrypt a single block
+ * in and out can overlap
+ */
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+		 const AES_KEY *key) {
+
+	const u32 *rk;
+	u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+	int r;
+#endif /* ?FULL_UNROLL */
+
+	assert(in && out && key);
+	rk = key->rd_key;
+
+	/*
+	 * map byte array block to cipher state
+	 * and add initial round key:
+	 */
+    s0 = GETU32(in     ) ^ rk[0];
+    s1 = GETU32(in +  4) ^ rk[1];
+    s2 = GETU32(in +  8) ^ rk[2];
+    s3 = GETU32(in + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+    /* round 1: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
+    /* round 2: */
+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
+    /* round 3: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
+    /* round 4: */
+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
+    /* round 5: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
+    /* round 6: */
+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
+    /* round 7: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
+    /* round 8: */
+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
+    /* round 9: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
+    if (key->rounds > 10) {
+        /* round 10: */
+        s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
+        s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
+        s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
+        s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
+        /* round 11: */
+        t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
+        t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
+        t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
+        t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
+        if (key->rounds > 12) {
+            /* round 12: */
+            s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
+            s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
+            s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
+            s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
+            /* round 13: */
+            t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
+            t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
+            t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
+            t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
+        }
+    }
+	rk += key->rounds << 2;
+#else  /* !FULL_UNROLL */
+    /*
+     * Nr - 1 full rounds:
+     */
+    r = key->rounds >> 1;
+    for (;;) {
+        t0 =
+            Td0[(s0 >> 24)       ] ^
+            Td1[(s3 >> 16) & 0xff] ^
+            Td2[(s2 >>  8) & 0xff] ^
+            Td3[(s1      ) & 0xff] ^
+            rk[4];
+        t1 =
+            Td0[(s1 >> 24)       ] ^
+            Td1[(s0 >> 16) & 0xff] ^
+            Td2[(s3 >>  8) & 0xff] ^
+            Td3[(s2      ) & 0xff] ^
+            rk[5];
+        t2 =
+            Td0[(s2 >> 24)       ] ^
+            Td1[(s1 >> 16) & 0xff] ^
+            Td2[(s0 >>  8) & 0xff] ^
+            Td3[(s3      ) & 0xff] ^
+            rk[6];
+        t3 =
+            Td0[(s3 >> 24)       ] ^
+            Td1[(s2 >> 16) & 0xff] ^
+            Td2[(s1 >>  8) & 0xff] ^
+            Td3[(s0      ) & 0xff] ^
+            rk[7];
+
+        rk += 8;
+        if (--r == 0) {
+            break;
+        }
+
+        s0 =
+            Td0[(t0 >> 24)       ] ^
+            Td1[(t3 >> 16) & 0xff] ^
+            Td2[(t2 >>  8) & 0xff] ^
+            Td3[(t1      ) & 0xff] ^
+            rk[0];
+        s1 =
+            Td0[(t1 >> 24)       ] ^
+            Td1[(t0 >> 16) & 0xff] ^
+            Td2[(t3 >>  8) & 0xff] ^
+            Td3[(t2      ) & 0xff] ^
+            rk[1];
+        s2 =
+            Td0[(t2 >> 24)       ] ^
+            Td1[(t1 >> 16) & 0xff] ^
+            Td2[(t0 >>  8) & 0xff] ^
+            Td3[(t3      ) & 0xff] ^
+            rk[2];
+        s3 =
+            Td0[(t3 >> 24)       ] ^
+            Td1[(t2 >> 16) & 0xff] ^
+            Td2[(t1 >>  8) & 0xff] ^
+            Td3[(t0      ) & 0xff] ^
+            rk[3];
+    }
+#endif /* ?FULL_UNROLL */
+    /*
+	 * apply last round and
+	 * map cipher state to byte array block:
+	 */
+   	s0 =
+   		(Td4[(t0 >> 24)       ] << 24) ^
+   		(Td4[(t3 >> 16) & 0xff] << 16) ^
+   		(Td4[(t2 >>  8) & 0xff] <<  8) ^
+   		(Td4[(t1      ) & 0xff])       ^
+   		rk[0];
+	PUTU32(out     , s0);
+   	s1 =
+   		(Td4[(t1 >> 24)       ] << 24) ^
+   		(Td4[(t0 >> 16) & 0xff] << 16) ^
+   		(Td4[(t3 >>  8) & 0xff] <<  8) ^
+   		(Td4[(t2      ) & 0xff])       ^
+   		rk[1];
+	PUTU32(out +  4, s1);
+   	s2 =
+   		(Td4[(t2 >> 24)       ] << 24) ^
+   		(Td4[(t1 >> 16) & 0xff] << 16) ^
+   		(Td4[(t0 >>  8) & 0xff] <<  8) ^
+   		(Td4[(t3      ) & 0xff])       ^
+   		rk[2];
+	PUTU32(out +  8, s2);
+   	s3 =
+   		(Td4[(t3 >> 24)       ] << 24) ^
+   		(Td4[(t2 >> 16) & 0xff] << 16) ^
+   		(Td4[(t1 >>  8) & 0xff] <<  8) ^
+   		(Td4[(t0      ) & 0xff])       ^
+   		rk[3];
+	PUTU32(out + 12, s3);
+}
+
+#else /* AES_ASM */
+
+static const u8 Te4[256] = {
+    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
+    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
+    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
+    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
+    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
+    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
+    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
+    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
+    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
+    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
+    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
+    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
+    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
+    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
+    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
+    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
+    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
+    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
+    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
+    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
+    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
+    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
+    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
+    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
+    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
+    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
+    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
+    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
+    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
+    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
+    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
+    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
+};
+static const u32 rcon[] = {
+	0x01000000, 0x02000000, 0x04000000, 0x08000000,
+	0x10000000, 0x20000000, 0x40000000, 0x80000000,
+	0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ */
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+			AES_KEY *key) {
+	u32 *rk;
+   	int i = 0;
+	u32 temp;
+
+	if (!userKey || !key)
+		return -1;
+	if (bits != 128 && bits != 192 && bits != 256)
+		return -2;
+
+	rk = key->rd_key;
+
+	if (bits==128)
+		key->rounds = 10;
+	else if (bits==192)
+		key->rounds = 12;
+	else
+		key->rounds = 14;
+
+	rk[0] = GETU32(userKey     );
+	rk[1] = GETU32(userKey +  4);
+	rk[2] = GETU32(userKey +  8);
+	rk[3] = GETU32(userKey + 12);
+	if (bits == 128) {
+		while (1) {
+			temp  = rk[3];
+			rk[4] = rk[0] ^
+				(Te4[(temp >> 16) & 0xff] << 24) ^
+				(Te4[(temp >>  8) & 0xff] << 16) ^
+				(Te4[(temp      ) & 0xff] << 8) ^
+				(Te4[(temp >> 24)       ]) ^
+				rcon[i];
+			rk[5] = rk[1] ^ rk[4];
+			rk[6] = rk[2] ^ rk[5];
+			rk[7] = rk[3] ^ rk[6];
+			if (++i == 10) {
+				return 0;
+			}
+			rk += 4;
+		}
+	}
+	rk[4] = GETU32(userKey + 16);
+	rk[5] = GETU32(userKey + 20);
+	if (bits == 192) {
+		while (1) {
+			temp = rk[ 5];
+			rk[ 6] = rk[ 0] ^
+				(Te4[(temp >> 16) & 0xff] << 24) ^
+				(Te4[(temp >>  8) & 0xff] << 16) ^
+				(Te4[(temp      ) & 0xff] << 8) ^
+				(Te4[(temp >> 24)       ]) ^
+				rcon[i];
+			rk[ 7] = rk[ 1] ^ rk[ 6];
+			rk[ 8] = rk[ 2] ^ rk[ 7];
+			rk[ 9] = rk[ 3] ^ rk[ 8];
+			if (++i == 8) {
+				return 0;
+			}
+			rk[10] = rk[ 4] ^ rk[ 9];
+			rk[11] = rk[ 5] ^ rk[10];
+			rk += 6;
+		}
+	}
+	rk[6] = GETU32(userKey + 24);
+	rk[7] = GETU32(userKey + 28);
+	if (bits == 256) {
+		while (1) {
+			temp = rk[ 7];
+			rk[ 8] = rk[ 0] ^
+				(Te4[(temp >> 16) & 0xff] << 24) ^
+				(Te4[(temp >>  8) & 0xff] << 16) ^
+				(Te4[(temp      ) & 0xff] << 8) ^
+				(Te4[(temp >> 24)       ]) ^
+				rcon[i];
+			rk[ 9] = rk[ 1] ^ rk[ 8];
+			rk[10] = rk[ 2] ^ rk[ 9];
+			rk[11] = rk[ 3] ^ rk[10];
+			if (++i == 7) {
+				return 0;
+			}
+			temp = rk[11];
+			rk[12] = rk[ 4] ^
+				(Te4[(temp >> 24)       ] << 24) ^
+				(Te4[(temp >> 16) & 0xff] << 16) ^
+				(Te4[(temp >>  8) & 0xff] << 8) ^
+				(Te4[(temp      ) & 0xff]);
+			rk[13] = rk[ 5] ^ rk[12];
+			rk[14] = rk[ 6] ^ rk[13];
+			rk[15] = rk[ 7] ^ rk[14];
+
+			rk += 8;
+        	}
+	}
+	return 0;
+}
+
+/**
+ * Expand the cipher key into the decryption key schedule.
+ */
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+			 AES_KEY *key) {
+
+        u32 *rk;
+	int i, j, status;
+	u32 temp;
+
+	/* first, start with an encryption schedule */
+	status = AES_set_encrypt_key(userKey, bits, key);
+	if (status < 0)
+		return status;
+
+	rk = key->rd_key;
+
+	/* invert the order of the round keys: */
+	for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
+		temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
+		temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+		temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+		temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+	}
+	/* apply the inverse MixColumn transform to all round keys but the first and the last: */
+	for (i = 1; i < (key->rounds); i++) {
+		rk += 4;
+		for (j = 0; j < 4; j++) {
+			u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
+
+			tp1 = rk[j];
+			m = tp1 & 0x80808080;
+			tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp2 & 0x80808080;
+			tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp4 & 0x80808080;
+			tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			tp9 = tp8 ^ tp1;
+			tpb = tp9 ^ tp2;
+			tpd = tp9 ^ tp4;
+			tpe = tp8 ^ tp4 ^ tp2;
+#if defined(ROTATE)
+			rk[j] = tpe ^ ROTATE(tpd,16) ^
+				ROTATE(tp9,24) ^ ROTATE(tpb,8);
+#else
+			rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 
+				(tp9 >> 8) ^ (tp9 << 24) ^
+				(tpb >> 24) ^ (tpb << 8);
+#endif
+		}
+	}
+	return 0;
+}
+
+#endif /* AES_ASM */
diff --git a/openssl/crypto/aes/aes_ctr.c b/openssl/crypto/aes/aes_ctr.c
new file mode 100644
index 0000000..7c9d165
--- /dev/null
+++ b/openssl/crypto/aes/aes_ctr.c
@@ -0,0 +1,61 @@
+/* crypto/aes/aes_ctr.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/aes.h>
+#include <openssl/modes.h>
+
+void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t length, const AES_KEY *key,
+			unsigned char ivec[AES_BLOCK_SIZE],
+			unsigned char ecount_buf[AES_BLOCK_SIZE],
+			unsigned int *num) {
+	CRYPTO_ctr128_encrypt(in,out,length,key,ivec,ecount_buf,num,(block128_f)AES_encrypt);
+}
diff --git a/openssl/crypto/aes/aes_ecb.c b/openssl/crypto/aes/aes_ecb.c
new file mode 100644
index 0000000..28aa561
--- /dev/null
+++ b/openssl/crypto/aes/aes_ecb.c
@@ -0,0 +1,73 @@
+/* crypto/aes/aes_ecb.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#ifndef AES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+#include <openssl/aes.h>
+#include "aes_locl.h"
+
+void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
+		     const AES_KEY *key, const int enc) {
+
+        assert(in && out && key);
+	assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
+
+	if (AES_ENCRYPT == enc)
+		AES_encrypt(in, out, key);
+	else
+		AES_decrypt(in, out, key);
+}
+
diff --git a/openssl/crypto/aes/aes_ige.c b/openssl/crypto/aes/aes_ige.c
new file mode 100644
index 0000000..c161351
--- /dev/null
+++ b/openssl/crypto/aes/aes_ige.c
@@ -0,0 +1,323 @@
+/* crypto/aes/aes_ige.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include "cryptlib.h"
+
+#include <openssl/aes.h>
+#include "aes_locl.h"
+
+#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long))
+typedef struct {
+        unsigned long data[N_WORDS];
+} aes_block_t;
+
+/* XXX: probably some better way to do this */
+#if defined(__i386__) || defined(__x86_64__)
+#define UNALIGNED_MEMOPS_ARE_FAST 1
+#else
+#define UNALIGNED_MEMOPS_ARE_FAST 0
+#endif
+
+#if UNALIGNED_MEMOPS_ARE_FAST
+#define load_block(d, s)        (d) = *(const aes_block_t *)(s)
+#define store_block(d, s)       *(aes_block_t *)(d) = (s)
+#else
+#define load_block(d, s)        memcpy((d).data, (s), AES_BLOCK_SIZE)
+#define store_block(d, s)       memcpy((d), (s).data, AES_BLOCK_SIZE)
+#endif
+
+/* N.B. The IV for this mode is _twice_ the block size */
+
+void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
+					 size_t length, const AES_KEY *key,
+					 unsigned char *ivec, const int enc)
+	{
+	size_t n;
+	size_t len = length;
+
+	OPENSSL_assert(in && out && key && ivec);
+	OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
+	OPENSSL_assert((length%AES_BLOCK_SIZE) == 0);
+
+	len = length / AES_BLOCK_SIZE;
+
+	if (AES_ENCRYPT == enc)
+		{
+		if (in != out &&
+		    (UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0))
+			{
+			aes_block_t *ivp = (aes_block_t *)ivec;
+			aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE);
+
+			while (len)
+				{
+				aes_block_t *inp = (aes_block_t *)in;
+				aes_block_t *outp = (aes_block_t *)out;
+
+				for(n=0 ; n < N_WORDS; ++n)
+					outp->data[n] = inp->data[n] ^ ivp->data[n];
+				AES_encrypt((unsigned char *)outp->data, (unsigned char *)outp->data, key);
+				for(n=0 ; n < N_WORDS; ++n)
+					outp->data[n] ^= iv2p->data[n];
+				ivp = outp;
+				iv2p = inp;
+				--len;
+				in += AES_BLOCK_SIZE;
+				out += AES_BLOCK_SIZE;
+				}
+			memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
+			memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
+			}
+		else
+			{
+			aes_block_t tmp, tmp2;
+			aes_block_t iv;
+			aes_block_t iv2;
+
+			load_block(iv, ivec);
+			load_block(iv2, ivec + AES_BLOCK_SIZE);
+
+			while (len)
+				{
+				load_block(tmp, in);
+				for(n=0 ; n < N_WORDS; ++n)
+					tmp2.data[n] = tmp.data[n] ^ iv.data[n];
+				AES_encrypt((unsigned char *)tmp2.data, (unsigned char *)tmp2.data, key);
+				for(n=0 ; n < N_WORDS; ++n)
+					tmp2.data[n] ^= iv2.data[n];
+				store_block(out, tmp2);
+				iv = tmp2;
+				iv2 = tmp;
+				--len;
+				in += AES_BLOCK_SIZE;
+				out += AES_BLOCK_SIZE;
+				}
+			memcpy(ivec, iv.data, AES_BLOCK_SIZE);
+			memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
+			}
+		}
+	else
+		{
+		if (in != out &&
+		    (UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0))
+			{
+			aes_block_t *ivp = (aes_block_t *)ivec;
+			aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE);
+
+			while (len)
+				{
+				aes_block_t tmp;
+				aes_block_t *inp = (aes_block_t *)in;
+				aes_block_t *outp = (aes_block_t *)out;
+
+				for(n=0 ; n < N_WORDS; ++n)
+					tmp.data[n] = inp->data[n] ^ iv2p->data[n];
+				AES_decrypt((unsigned char *)tmp.data, (unsigned char *)outp->data, key);
+				for(n=0 ; n < N_WORDS; ++n)
+					outp->data[n] ^= ivp->data[n];
+				ivp = inp;
+				iv2p = outp;
+				--len;
+				in += AES_BLOCK_SIZE;
+				out += AES_BLOCK_SIZE;
+				}
+			memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
+			memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
+			}
+		else
+			{
+			aes_block_t tmp, tmp2;
+			aes_block_t iv;
+			aes_block_t iv2;
+
+			load_block(iv, ivec);
+			load_block(iv2, ivec + AES_BLOCK_SIZE);
+
+			while (len)
+				{
+				load_block(tmp, in);
+				tmp2 = tmp;
+				for(n=0 ; n < N_WORDS; ++n)
+					tmp.data[n] ^= iv2.data[n];
+				AES_decrypt((unsigned char *)tmp.data, (unsigned char *)tmp.data, key);
+				for(n=0 ; n < N_WORDS; ++n)
+					tmp.data[n] ^= iv.data[n];
+				store_block(out, tmp);
+				iv = tmp2;
+				iv2 = tmp;
+				--len;
+				in += AES_BLOCK_SIZE;
+				out += AES_BLOCK_SIZE;
+				}
+			memcpy(ivec, iv.data, AES_BLOCK_SIZE);
+			memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
+			}
+		}
+	}
+
+/*
+ * Note that its effectively impossible to do biIGE in anything other
+ * than a single pass, so no provision is made for chaining.
+ */
+
+/* N.B. The IV for this mode is _four times_ the block size */
+
+void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
+						size_t length, const AES_KEY *key,
+						const AES_KEY *key2, const unsigned char *ivec,
+						const int enc)
+	{
+	size_t n;
+	size_t len = length;
+	unsigned char tmp[AES_BLOCK_SIZE];
+	unsigned char tmp2[AES_BLOCK_SIZE];
+	unsigned char tmp3[AES_BLOCK_SIZE];
+	unsigned char prev[AES_BLOCK_SIZE];
+	const unsigned char *iv;
+	const unsigned char *iv2;
+
+	OPENSSL_assert(in && out && key && ivec);
+	OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
+	OPENSSL_assert((length%AES_BLOCK_SIZE) == 0);
+
+	if (AES_ENCRYPT == enc)
+		{
+		/* XXX: Do a separate case for when in != out (strictly should
+		   check for overlap, too) */
+
+		/* First the forward pass */ 
+		iv = ivec;
+		iv2 = ivec + AES_BLOCK_SIZE;
+		while (len >= AES_BLOCK_SIZE)
+			{
+			for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
+				out[n] = in[n] ^ iv[n];
+			AES_encrypt(out, out, key);
+			for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
+				out[n] ^= iv2[n];
+			iv = out;
+			memcpy(prev, in, AES_BLOCK_SIZE);
+			iv2 = prev;
+			len -= AES_BLOCK_SIZE;
+			in += AES_BLOCK_SIZE;
+			out += AES_BLOCK_SIZE;
+			}
+
+		/* And now backwards */
+		iv = ivec + AES_BLOCK_SIZE*2;
+		iv2 = ivec + AES_BLOCK_SIZE*3;
+		len = length;
+		while(len >= AES_BLOCK_SIZE)
+			{
+			out -= AES_BLOCK_SIZE;
+			/* XXX: reduce copies by alternating between buffers */
+			memcpy(tmp, out, AES_BLOCK_SIZE);
+			for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
+				out[n] ^= iv[n];
+			/*			hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE); */
+			AES_encrypt(out, out, key);
+			/*			hexdump(stdout,"enc", out, AES_BLOCK_SIZE); */
+			/*			hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); */
+			for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
+				out[n] ^= iv2[n];
+			/*			hexdump(stdout,"out", out, AES_BLOCK_SIZE); */
+			iv = out;
+			memcpy(prev, tmp, AES_BLOCK_SIZE);
+			iv2 = prev;
+			len -= AES_BLOCK_SIZE;
+			}
+		}
+	else
+		{
+		/* First backwards */
+		iv = ivec + AES_BLOCK_SIZE*2;
+		iv2 = ivec + AES_BLOCK_SIZE*3;
+		in += length;
+		out += length;
+		while (len >= AES_BLOCK_SIZE)
+			{
+			in -= AES_BLOCK_SIZE;
+			out -= AES_BLOCK_SIZE;
+			memcpy(tmp, in, AES_BLOCK_SIZE);
+			memcpy(tmp2, in, AES_BLOCK_SIZE);
+			for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
+				tmp[n] ^= iv2[n];
+			AES_decrypt(tmp, out, key);
+			for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
+				out[n] ^= iv[n];
+			memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
+			iv = tmp3;
+			iv2 = out;
+			len -= AES_BLOCK_SIZE;
+			}
+
+		/* And now forwards */
+		iv = ivec;
+		iv2 = ivec + AES_BLOCK_SIZE;
+		len = length;
+		while (len >= AES_BLOCK_SIZE)
+			{
+			memcpy(tmp, out, AES_BLOCK_SIZE);
+			memcpy(tmp2, out, AES_BLOCK_SIZE);
+			for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
+				tmp[n] ^= iv2[n];
+			AES_decrypt(tmp, out, key);
+			for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
+				out[n] ^= iv[n];
+			memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
+			iv = tmp3;
+			iv2 = out;
+			len -= AES_BLOCK_SIZE;
+			in += AES_BLOCK_SIZE;
+			out += AES_BLOCK_SIZE;
+			}
+		}
+	}
diff --git a/openssl/crypto/aes/aes_locl.h b/openssl/crypto/aes/aes_locl.h
new file mode 100644
index 0000000..054b442
--- /dev/null
+++ b/openssl/crypto/aes/aes_locl.h
@@ -0,0 +1,89 @@
+/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#ifndef HEADER_AES_LOCL_H
+#define HEADER_AES_LOCL_H
+
+#include <openssl/e_os2.h>
+
+#ifdef OPENSSL_NO_AES
+#error AES is disabled.
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
+# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+# define GETU32(p) SWAP(*((u32 *)(p)))
+# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
+#else
+# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
+# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >>  8); (ct)[3] = (u8)(st); }
+#endif
+
+#ifdef AES_LONG
+typedef unsigned long u32;
+#else
+typedef unsigned int u32;
+#endif
+typedef unsigned short u16;
+typedef unsigned char u8;
+
+#define MAXKC   (256/32)
+#define MAXKB   (256/8)
+#define MAXNR   14
+
+/* This controls loop-unrolling in aes_core.c */
+#undef FULL_UNROLL
+
+#endif /* !HEADER_AES_LOCL_H */
diff --git a/openssl/crypto/aes/aes_misc.c b/openssl/crypto/aes/aes_misc.c
new file mode 100644
index 0000000..4fead1b
--- /dev/null
+++ b/openssl/crypto/aes/aes_misc.c
@@ -0,0 +1,64 @@
+/* crypto/aes/aes_misc.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/opensslv.h>
+#include <openssl/aes.h>
+#include "aes_locl.h"
+
+const char AES_version[]="AES" OPENSSL_VERSION_PTEXT;
+
+const char *AES_options(void) {
+#ifdef FULL_UNROLL
+        return "aes(full)";
+#else   
+        return "aes(partial)";
+#endif
+}
diff --git a/openssl/crypto/aes/aes_ofb.c b/openssl/crypto/aes/aes_ofb.c
new file mode 100644
index 0000000..50bf0b8
--- /dev/null
+++ b/openssl/crypto/aes/aes_ofb.c
@@ -0,0 +1,60 @@
+/* crypto/aes/aes_ofb.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 2002-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/aes.h>
+#include <openssl/modes.h>
+
+void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const AES_KEY *key,
+	unsigned char *ivec, int *num)
+{
+	CRYPTO_ofb128_encrypt(in,out,length,key,ivec,num,(block128_f)AES_encrypt);
+}
diff --git a/openssl/crypto/aes/aes_wrap.c b/openssl/crypto/aes/aes_wrap.c
new file mode 100644
index 0000000..e2d73d3
--- /dev/null
+++ b/openssl/crypto/aes/aes_wrap.c
@@ -0,0 +1,259 @@
+/* crypto/aes/aes_wrap.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "cryptlib.h"
+#include <openssl/aes.h>
+#include <openssl/bio.h>
+
+static const unsigned char default_iv[] = {
+  0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
+};
+
+int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
+		unsigned char *out,
+		const unsigned char *in, unsigned int inlen)
+	{
+	unsigned char *A, B[16], *R;
+	unsigned int i, j, t;
+	if ((inlen & 0x7) || (inlen < 8))
+		return -1;
+	A = B;
+	t = 1;
+	memcpy(out + 8, in, inlen);
+	if (!iv)
+		iv = default_iv;
+
+	memcpy(A, iv, 8);
+
+	for (j = 0; j < 6; j++)
+		{
+		R = out + 8;
+		for (i = 0; i < inlen; i += 8, t++, R += 8)
+			{
+			memcpy(B + 8, R, 8);
+			AES_encrypt(B, B, key);
+			A[7] ^= (unsigned char)(t & 0xff);
+			if (t > 0xff)	
+				{
+				A[6] ^= (unsigned char)((t >> 8) & 0xff);
+				A[5] ^= (unsigned char)((t >> 16) & 0xff);
+				A[4] ^= (unsigned char)((t >> 24) & 0xff);
+				}
+			memcpy(R, B + 8, 8);
+			}
+		}
+	memcpy(out, A, 8);
+	return inlen + 8;
+	}
+
+int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
+		unsigned char *out,
+		const unsigned char *in, unsigned int inlen)
+	{
+	unsigned char *A, B[16], *R;
+	unsigned int i, j, t;
+	inlen -= 8;
+	if (inlen & 0x7)
+		return -1;
+	if (inlen < 8)
+		return -1;
+	A = B;
+	t =  6 * (inlen >> 3);
+	memcpy(A, in, 8);
+	memcpy(out, in + 8, inlen);
+	for (j = 0; j < 6; j++)
+		{
+		R = out + inlen - 8;
+		for (i = 0; i < inlen; i += 8, t--, R -= 8)
+			{
+			A[7] ^= (unsigned char)(t & 0xff);
+			if (t > 0xff)	
+				{
+				A[6] ^= (unsigned char)((t >> 8) & 0xff);
+				A[5] ^= (unsigned char)((t >> 16) & 0xff);
+				A[4] ^= (unsigned char)((t >> 24) & 0xff);
+				}
+			memcpy(B + 8, R, 8);
+			AES_decrypt(B, B, key);
+			memcpy(R, B + 8, 8);
+			}
+		}
+	if (!iv)
+		iv = default_iv;
+	if (memcmp(A, iv, 8))
+		{
+		OPENSSL_cleanse(out, inlen);
+		return 0;
+		}
+	return inlen;
+	}
+
+#ifdef AES_WRAP_TEST
+
+int AES_wrap_unwrap_test(const unsigned char *kek, int keybits,
+			 const unsigned char *iv,
+			 const unsigned char *eout,
+			 const unsigned char *key, int keylen)
+	{
+	unsigned char *otmp = NULL, *ptmp = NULL;
+	int r, ret = 0;
+	AES_KEY wctx;
+	otmp = OPENSSL_malloc(keylen + 8);
+	ptmp = OPENSSL_malloc(keylen);
+	if (!otmp || !ptmp)
+		return 0;
+	if (AES_set_encrypt_key(kek, keybits, &wctx))
+		goto err;
+	r = AES_wrap_key(&wctx, iv, otmp, key, keylen);
+	if (r <= 0)
+		goto err;
+
+	if (eout && memcmp(eout, otmp, keylen))
+		goto err;
+		
+	if (AES_set_decrypt_key(kek, keybits, &wctx))
+		goto err;
+	r = AES_unwrap_key(&wctx, iv, ptmp, otmp, r);
+
+	if (memcmp(key, ptmp, keylen))
+		goto err;
+
+	ret = 1;
+
+	err:
+	if (otmp)
+		OPENSSL_free(otmp);
+	if (ptmp)
+		OPENSSL_free(ptmp);
+
+	return ret;
+
+	}
+
+
+
+int main(int argc, char **argv)
+{
+
+static const unsigned char kek[] = {
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
+};
+
+static const unsigned char key[] = {
+  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+  0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
+};
+
+static const unsigned char e1[] = {
+  0x1f, 0xa6, 0x8b, 0x0a, 0x81, 0x12, 0xb4, 0x47,
+  0xae, 0xf3, 0x4b, 0xd8, 0xfb, 0x5a, 0x7b, 0x82,
+  0x9d, 0x3e, 0x86, 0x23, 0x71, 0xd2, 0xcf, 0xe5
+};
+
+static const unsigned char e2[] = {
+  0x96, 0x77, 0x8b, 0x25, 0xae, 0x6c, 0xa4, 0x35,
+  0xf9, 0x2b, 0x5b, 0x97, 0xc0, 0x50, 0xae, 0xd2,
+  0x46, 0x8a, 0xb8, 0xa1, 0x7a, 0xd8, 0x4e, 0x5d
+};
+
+static const unsigned char e3[] = {
+  0x64, 0xe8, 0xc3, 0xf9, 0xce, 0x0f, 0x5b, 0xa2,
+  0x63, 0xe9, 0x77, 0x79, 0x05, 0x81, 0x8a, 0x2a,
+  0x93, 0xc8, 0x19, 0x1e, 0x7d, 0x6e, 0x8a, 0xe7
+};
+
+static const unsigned char e4[] = {
+  0x03, 0x1d, 0x33, 0x26, 0x4e, 0x15, 0xd3, 0x32,
+  0x68, 0xf2, 0x4e, 0xc2, 0x60, 0x74, 0x3e, 0xdc,
+  0xe1, 0xc6, 0xc7, 0xdd, 0xee, 0x72, 0x5a, 0x93,
+  0x6b, 0xa8, 0x14, 0x91, 0x5c, 0x67, 0x62, 0xd2
+};
+
+static const unsigned char e5[] = {
+  0xa8, 0xf9, 0xbc, 0x16, 0x12, 0xc6, 0x8b, 0x3f,
+  0xf6, 0xe6, 0xf4, 0xfb, 0xe3, 0x0e, 0x71, 0xe4,
+  0x76, 0x9c, 0x8b, 0x80, 0xa3, 0x2c, 0xb8, 0x95,
+  0x8c, 0xd5, 0xd1, 0x7d, 0x6b, 0x25, 0x4d, 0xa1
+};
+
+static const unsigned char e6[] = {
+  0x28, 0xc9, 0xf4, 0x04, 0xc4, 0xb8, 0x10, 0xf4,
+  0xcb, 0xcc, 0xb3, 0x5c, 0xfb, 0x87, 0xf8, 0x26,
+  0x3f, 0x57, 0x86, 0xe2, 0xd8, 0x0e, 0xd3, 0x26,
+  0xcb, 0xc7, 0xf0, 0xe7, 0x1a, 0x99, 0xf4, 0x3b,
+  0xfb, 0x98, 0x8b, 0x9b, 0x7a, 0x02, 0xdd, 0x21
+};
+
+	AES_KEY wctx, xctx;
+	int ret;
+	ret = AES_wrap_unwrap_test(kek, 128, NULL, e1, key, 16);
+	fprintf(stderr, "Key test result %d\n", ret);
+	ret = AES_wrap_unwrap_test(kek, 192, NULL, e2, key, 16);
+	fprintf(stderr, "Key test result %d\n", ret);
+	ret = AES_wrap_unwrap_test(kek, 256, NULL, e3, key, 16);
+	fprintf(stderr, "Key test result %d\n", ret);
+	ret = AES_wrap_unwrap_test(kek, 192, NULL, e4, key, 24);
+	fprintf(stderr, "Key test result %d\n", ret);
+	ret = AES_wrap_unwrap_test(kek, 256, NULL, e5, key, 24);
+	fprintf(stderr, "Key test result %d\n", ret);
+	ret = AES_wrap_unwrap_test(kek, 256, NULL, e6, key, 32);
+	fprintf(stderr, "Key test result %d\n", ret);
+}
+	
+	
+#endif
diff --git a/openssl/crypto/aes/aes_x86core.c b/openssl/crypto/aes/aes_x86core.c
new file mode 100644
index 0000000..d323e26
--- /dev/null
+++ b/openssl/crypto/aes/aes_x86core.c
@@ -0,0 +1,1063 @@
+/* crypto/aes/aes_core.c -*- mode:C; c-file-style: "eay" -*- */
+/**
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This is experimental x86[_64] derivative. It assumes little-endian
+ * byte order and expects CPU to sustain unaligned memory references.
+ * It is used as playground for cache-time attack mitigations and
+ * serves as reference C implementation for x86[_64] assembler.
+ *
+ *					<appro@fy.chalmers.se>
+ */
+
+
+#ifndef AES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+#include <stdlib.h>
+#include <openssl/aes.h>
+#include "aes_locl.h"
+
+/*
+ * These two parameters control which table, 256-byte or 2KB, is
+ * referenced in outer and respectively inner rounds.
+ */
+#define AES_COMPACT_IN_OUTER_ROUNDS
+#ifdef  AES_COMPACT_IN_OUTER_ROUNDS
+/* AES_COMPACT_IN_OUTER_ROUNDS costs ~30% in performance, while
+ * adding AES_COMPACT_IN_INNER_ROUNDS reduces benchmark *further*
+ * by factor of ~2. */
+# undef  AES_COMPACT_IN_INNER_ROUNDS
+#endif
+
+#if 1
+static void prefetch256(const void *table)
+{
+	volatile unsigned long *t=(void *)table,ret;
+	unsigned long sum;
+	int i;
+
+	/* 32 is common least cache-line size */
+	for (sum=0,i=0;i<256/sizeof(t[0]);i+=32/sizeof(t[0]))	sum ^= t[i];
+
+	ret = sum;
+}
+#else
+# define prefetch256(t)
+#endif
+
+#undef GETU32
+#define GETU32(p) (*((u32*)(p)))
+
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
+typedef unsigned __int64 u64;
+#define U64(C)	C##UI64
+#elif defined(__arch64__)
+typedef unsigned long u64;
+#define U64(C)	C##UL
+#else
+typedef unsigned long long u64;
+#define U64(C)	C##ULL
+#endif
+
+#undef ROTATE
+#if defined(_MSC_VER) || defined(__ICC)
+# define ROTATE(a,n)	_lrotl(a,n)
+#elif defined(__GNUC__) && __GNUC__>=2
+# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+#   define ROTATE(a,n)	({ register unsigned int ret;	\
+				asm (			\
+				"roll %1,%0"		\
+				: "=r"(ret)		\
+				: "I"(n), "0"(a)	\
+				: "cc");		\
+			   ret;				\
+			})
+# endif
+#endif
+/*
+Te [x] = S [x].[02, 01, 01, 03, 02, 01, 01, 03];
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+*/
+#define Te0 (u32)((u64*)((u8*)Te+0))
+#define Te1 (u32)((u64*)((u8*)Te+3))
+#define Te2 (u32)((u64*)((u8*)Te+2))
+#define Te3 (u32)((u64*)((u8*)Te+1))
+/*
+Td [x] = Si[x].[0e, 09, 0d, 0b, 0e, 09, 0d, 0b];
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01];
+*/
+#define Td0 (u32)((u64*)((u8*)Td+0))
+#define Td1 (u32)((u64*)((u8*)Td+3))
+#define Td2 (u32)((u64*)((u8*)Td+2))
+#define Td3 (u32)((u64*)((u8*)Td+1))
+
+static const u64 Te[256] = {
+    U64(0xa56363c6a56363c6), U64(0x847c7cf8847c7cf8),
+    U64(0x997777ee997777ee), U64(0x8d7b7bf68d7b7bf6),
+    U64(0x0df2f2ff0df2f2ff), U64(0xbd6b6bd6bd6b6bd6),
+    U64(0xb16f6fdeb16f6fde), U64(0x54c5c59154c5c591),
+    U64(0x5030306050303060), U64(0x0301010203010102),
+    U64(0xa96767cea96767ce), U64(0x7d2b2b567d2b2b56),
+    U64(0x19fefee719fefee7), U64(0x62d7d7b562d7d7b5),
+    U64(0xe6abab4de6abab4d), U64(0x9a7676ec9a7676ec),
+    U64(0x45caca8f45caca8f), U64(0x9d82821f9d82821f),
+    U64(0x40c9c98940c9c989), U64(0x877d7dfa877d7dfa),
+    U64(0x15fafaef15fafaef), U64(0xeb5959b2eb5959b2),
+    U64(0xc947478ec947478e), U64(0x0bf0f0fb0bf0f0fb),
+    U64(0xecadad41ecadad41), U64(0x67d4d4b367d4d4b3),
+    U64(0xfda2a25ffda2a25f), U64(0xeaafaf45eaafaf45),
+    U64(0xbf9c9c23bf9c9c23), U64(0xf7a4a453f7a4a453),
+    U64(0x967272e4967272e4), U64(0x5bc0c09b5bc0c09b),
+    U64(0xc2b7b775c2b7b775), U64(0x1cfdfde11cfdfde1),
+    U64(0xae93933dae93933d), U64(0x6a26264c6a26264c),
+    U64(0x5a36366c5a36366c), U64(0x413f3f7e413f3f7e),
+    U64(0x02f7f7f502f7f7f5), U64(0x4fcccc834fcccc83),
+    U64(0x5c3434685c343468), U64(0xf4a5a551f4a5a551),
+    U64(0x34e5e5d134e5e5d1), U64(0x08f1f1f908f1f1f9),
+    U64(0x937171e2937171e2), U64(0x73d8d8ab73d8d8ab),
+    U64(0x5331316253313162), U64(0x3f15152a3f15152a),
+    U64(0x0c0404080c040408), U64(0x52c7c79552c7c795),
+    U64(0x6523234665232346), U64(0x5ec3c39d5ec3c39d),
+    U64(0x2818183028181830), U64(0xa1969637a1969637),
+    U64(0x0f05050a0f05050a), U64(0xb59a9a2fb59a9a2f),
+    U64(0x0907070e0907070e), U64(0x3612122436121224),
+    U64(0x9b80801b9b80801b), U64(0x3de2e2df3de2e2df),
+    U64(0x26ebebcd26ebebcd), U64(0x6927274e6927274e),
+    U64(0xcdb2b27fcdb2b27f), U64(0x9f7575ea9f7575ea),
+    U64(0x1b0909121b090912), U64(0x9e83831d9e83831d),
+    U64(0x742c2c58742c2c58), U64(0x2e1a1a342e1a1a34),
+    U64(0x2d1b1b362d1b1b36), U64(0xb26e6edcb26e6edc),
+    U64(0xee5a5ab4ee5a5ab4), U64(0xfba0a05bfba0a05b),
+    U64(0xf65252a4f65252a4), U64(0x4d3b3b764d3b3b76),
+    U64(0x61d6d6b761d6d6b7), U64(0xceb3b37dceb3b37d),
+    U64(0x7b2929527b292952), U64(0x3ee3e3dd3ee3e3dd),
+    U64(0x712f2f5e712f2f5e), U64(0x9784841397848413),
+    U64(0xf55353a6f55353a6), U64(0x68d1d1b968d1d1b9),
+    U64(0x0000000000000000), U64(0x2cededc12cededc1),
+    U64(0x6020204060202040), U64(0x1ffcfce31ffcfce3),
+    U64(0xc8b1b179c8b1b179), U64(0xed5b5bb6ed5b5bb6),
+    U64(0xbe6a6ad4be6a6ad4), U64(0x46cbcb8d46cbcb8d),
+    U64(0xd9bebe67d9bebe67), U64(0x4b3939724b393972),
+    U64(0xde4a4a94de4a4a94), U64(0xd44c4c98d44c4c98),
+    U64(0xe85858b0e85858b0), U64(0x4acfcf854acfcf85),
+    U64(0x6bd0d0bb6bd0d0bb), U64(0x2aefefc52aefefc5),
+    U64(0xe5aaaa4fe5aaaa4f), U64(0x16fbfbed16fbfbed),
+    U64(0xc5434386c5434386), U64(0xd74d4d9ad74d4d9a),
+    U64(0x5533336655333366), U64(0x9485851194858511),
+    U64(0xcf45458acf45458a), U64(0x10f9f9e910f9f9e9),
+    U64(0x0602020406020204), U64(0x817f7ffe817f7ffe),
+    U64(0xf05050a0f05050a0), U64(0x443c3c78443c3c78),
+    U64(0xba9f9f25ba9f9f25), U64(0xe3a8a84be3a8a84b),
+    U64(0xf35151a2f35151a2), U64(0xfea3a35dfea3a35d),
+    U64(0xc0404080c0404080), U64(0x8a8f8f058a8f8f05),
+    U64(0xad92923fad92923f), U64(0xbc9d9d21bc9d9d21),
+    U64(0x4838387048383870), U64(0x04f5f5f104f5f5f1),
+    U64(0xdfbcbc63dfbcbc63), U64(0xc1b6b677c1b6b677),
+    U64(0x75dadaaf75dadaaf), U64(0x6321214263212142),
+    U64(0x3010102030101020), U64(0x1affffe51affffe5),
+    U64(0x0ef3f3fd0ef3f3fd), U64(0x6dd2d2bf6dd2d2bf),
+    U64(0x4ccdcd814ccdcd81), U64(0x140c0c18140c0c18),
+    U64(0x3513132635131326), U64(0x2fececc32fececc3),
+    U64(0xe15f5fbee15f5fbe), U64(0xa2979735a2979735),
+    U64(0xcc444488cc444488), U64(0x3917172e3917172e),
+    U64(0x57c4c49357c4c493), U64(0xf2a7a755f2a7a755),
+    U64(0x827e7efc827e7efc), U64(0x473d3d7a473d3d7a),
+    U64(0xac6464c8ac6464c8), U64(0xe75d5dbae75d5dba),
+    U64(0x2b1919322b191932), U64(0x957373e6957373e6),
+    U64(0xa06060c0a06060c0), U64(0x9881811998818119),
+    U64(0xd14f4f9ed14f4f9e), U64(0x7fdcdca37fdcdca3),
+    U64(0x6622224466222244), U64(0x7e2a2a547e2a2a54),
+    U64(0xab90903bab90903b), U64(0x8388880b8388880b),
+    U64(0xca46468cca46468c), U64(0x29eeeec729eeeec7),
+    U64(0xd3b8b86bd3b8b86b), U64(0x3c1414283c141428),
+    U64(0x79dedea779dedea7), U64(0xe25e5ebce25e5ebc),
+    U64(0x1d0b0b161d0b0b16), U64(0x76dbdbad76dbdbad),
+    U64(0x3be0e0db3be0e0db), U64(0x5632326456323264),
+    U64(0x4e3a3a744e3a3a74), U64(0x1e0a0a141e0a0a14),
+    U64(0xdb494992db494992), U64(0x0a06060c0a06060c),
+    U64(0x6c2424486c242448), U64(0xe45c5cb8e45c5cb8),
+    U64(0x5dc2c29f5dc2c29f), U64(0x6ed3d3bd6ed3d3bd),
+    U64(0xefacac43efacac43), U64(0xa66262c4a66262c4),
+    U64(0xa8919139a8919139), U64(0xa4959531a4959531),
+    U64(0x37e4e4d337e4e4d3), U64(0x8b7979f28b7979f2),
+    U64(0x32e7e7d532e7e7d5), U64(0x43c8c88b43c8c88b),
+    U64(0x5937376e5937376e), U64(0xb76d6ddab76d6dda),
+    U64(0x8c8d8d018c8d8d01), U64(0x64d5d5b164d5d5b1),
+    U64(0xd24e4e9cd24e4e9c), U64(0xe0a9a949e0a9a949),
+    U64(0xb46c6cd8b46c6cd8), U64(0xfa5656acfa5656ac),
+    U64(0x07f4f4f307f4f4f3), U64(0x25eaeacf25eaeacf),
+    U64(0xaf6565caaf6565ca), U64(0x8e7a7af48e7a7af4),
+    U64(0xe9aeae47e9aeae47), U64(0x1808081018080810),
+    U64(0xd5baba6fd5baba6f), U64(0x887878f0887878f0),
+    U64(0x6f25254a6f25254a), U64(0x722e2e5c722e2e5c),
+    U64(0x241c1c38241c1c38), U64(0xf1a6a657f1a6a657),
+    U64(0xc7b4b473c7b4b473), U64(0x51c6c69751c6c697),
+    U64(0x23e8e8cb23e8e8cb), U64(0x7cdddda17cdddda1),
+    U64(0x9c7474e89c7474e8), U64(0x211f1f3e211f1f3e),
+    U64(0xdd4b4b96dd4b4b96), U64(0xdcbdbd61dcbdbd61),
+    U64(0x868b8b0d868b8b0d), U64(0x858a8a0f858a8a0f),
+    U64(0x907070e0907070e0), U64(0x423e3e7c423e3e7c),
+    U64(0xc4b5b571c4b5b571), U64(0xaa6666ccaa6666cc),
+    U64(0xd8484890d8484890), U64(0x0503030605030306),
+    U64(0x01f6f6f701f6f6f7), U64(0x120e0e1c120e0e1c),
+    U64(0xa36161c2a36161c2), U64(0x5f35356a5f35356a),
+    U64(0xf95757aef95757ae), U64(0xd0b9b969d0b9b969),
+    U64(0x9186861791868617), U64(0x58c1c19958c1c199),
+    U64(0x271d1d3a271d1d3a), U64(0xb99e9e27b99e9e27),
+    U64(0x38e1e1d938e1e1d9), U64(0x13f8f8eb13f8f8eb),
+    U64(0xb398982bb398982b), U64(0x3311112233111122),
+    U64(0xbb6969d2bb6969d2), U64(0x70d9d9a970d9d9a9),
+    U64(0x898e8e07898e8e07), U64(0xa7949433a7949433),
+    U64(0xb69b9b2db69b9b2d), U64(0x221e1e3c221e1e3c),
+    U64(0x9287871592878715), U64(0x20e9e9c920e9e9c9),
+    U64(0x49cece8749cece87), U64(0xff5555aaff5555aa),
+    U64(0x7828285078282850), U64(0x7adfdfa57adfdfa5),
+    U64(0x8f8c8c038f8c8c03), U64(0xf8a1a159f8a1a159),
+    U64(0x8089890980898909), U64(0x170d0d1a170d0d1a),
+    U64(0xdabfbf65dabfbf65), U64(0x31e6e6d731e6e6d7),
+    U64(0xc6424284c6424284), U64(0xb86868d0b86868d0),
+    U64(0xc3414182c3414182), U64(0xb0999929b0999929),
+    U64(0x772d2d5a772d2d5a), U64(0x110f0f1e110f0f1e),
+    U64(0xcbb0b07bcbb0b07b), U64(0xfc5454a8fc5454a8),
+    U64(0xd6bbbb6dd6bbbb6d), U64(0x3a16162c3a16162c)
+};
+
+static const u8 Te4[256] = {
+    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
+    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
+    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
+    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
+    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
+    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
+    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
+    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
+    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
+    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
+    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
+    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
+    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
+    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
+    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
+    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
+    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
+    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
+    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
+    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
+    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
+    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
+    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
+    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
+    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
+    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
+    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
+    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
+    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
+    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
+    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
+    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
+};
+
+static const u64 Td[256] = {
+    U64(0x50a7f45150a7f451), U64(0x5365417e5365417e),
+    U64(0xc3a4171ac3a4171a), U64(0x965e273a965e273a),
+    U64(0xcb6bab3bcb6bab3b), U64(0xf1459d1ff1459d1f),
+    U64(0xab58faacab58faac), U64(0x9303e34b9303e34b),
+    U64(0x55fa302055fa3020), U64(0xf66d76adf66d76ad),
+    U64(0x9176cc889176cc88), U64(0x254c02f5254c02f5),
+    U64(0xfcd7e54ffcd7e54f), U64(0xd7cb2ac5d7cb2ac5),
+    U64(0x8044352680443526), U64(0x8fa362b58fa362b5),
+    U64(0x495ab1de495ab1de), U64(0x671bba25671bba25),
+    U64(0x980eea45980eea45), U64(0xe1c0fe5de1c0fe5d),
+    U64(0x02752fc302752fc3), U64(0x12f04c8112f04c81),
+    U64(0xa397468da397468d), U64(0xc6f9d36bc6f9d36b),
+    U64(0xe75f8f03e75f8f03), U64(0x959c9215959c9215),
+    U64(0xeb7a6dbfeb7a6dbf), U64(0xda595295da595295),
+    U64(0x2d83bed42d83bed4), U64(0xd3217458d3217458),
+    U64(0x2969e0492969e049), U64(0x44c8c98e44c8c98e),
+    U64(0x6a89c2756a89c275), U64(0x78798ef478798ef4),
+    U64(0x6b3e58996b3e5899), U64(0xdd71b927dd71b927),
+    U64(0xb64fe1beb64fe1be), U64(0x17ad88f017ad88f0),
+    U64(0x66ac20c966ac20c9), U64(0xb43ace7db43ace7d),
+    U64(0x184adf63184adf63), U64(0x82311ae582311ae5),
+    U64(0x6033519760335197), U64(0x457f5362457f5362),
+    U64(0xe07764b1e07764b1), U64(0x84ae6bbb84ae6bbb),
+    U64(0x1ca081fe1ca081fe), U64(0x942b08f9942b08f9),
+    U64(0x5868487058684870), U64(0x19fd458f19fd458f),
+    U64(0x876cde94876cde94), U64(0xb7f87b52b7f87b52),
+    U64(0x23d373ab23d373ab), U64(0xe2024b72e2024b72),
+    U64(0x578f1fe3578f1fe3), U64(0x2aab55662aab5566),
+    U64(0x0728ebb20728ebb2), U64(0x03c2b52f03c2b52f),
+    U64(0x9a7bc5869a7bc586), U64(0xa50837d3a50837d3),
+    U64(0xf2872830f2872830), U64(0xb2a5bf23b2a5bf23),
+    U64(0xba6a0302ba6a0302), U64(0x5c8216ed5c8216ed),
+    U64(0x2b1ccf8a2b1ccf8a), U64(0x92b479a792b479a7),
+    U64(0xf0f207f3f0f207f3), U64(0xa1e2694ea1e2694e),
+    U64(0xcdf4da65cdf4da65), U64(0xd5be0506d5be0506),
+    U64(0x1f6234d11f6234d1), U64(0x8afea6c48afea6c4),
+    U64(0x9d532e349d532e34), U64(0xa055f3a2a055f3a2),
+    U64(0x32e18a0532e18a05), U64(0x75ebf6a475ebf6a4),
+    U64(0x39ec830b39ec830b), U64(0xaaef6040aaef6040),
+    U64(0x069f715e069f715e), U64(0x51106ebd51106ebd),
+    U64(0xf98a213ef98a213e), U64(0x3d06dd963d06dd96),
+    U64(0xae053eddae053edd), U64(0x46bde64d46bde64d),
+    U64(0xb58d5491b58d5491), U64(0x055dc471055dc471),
+    U64(0x6fd406046fd40604), U64(0xff155060ff155060),
+    U64(0x24fb981924fb9819), U64(0x97e9bdd697e9bdd6),
+    U64(0xcc434089cc434089), U64(0x779ed967779ed967),
+    U64(0xbd42e8b0bd42e8b0), U64(0x888b8907888b8907),
+    U64(0x385b19e7385b19e7), U64(0xdbeec879dbeec879),
+    U64(0x470a7ca1470a7ca1), U64(0xe90f427ce90f427c),
+    U64(0xc91e84f8c91e84f8), U64(0x0000000000000000),
+    U64(0x8386800983868009), U64(0x48ed2b3248ed2b32),
+    U64(0xac70111eac70111e), U64(0x4e725a6c4e725a6c),
+    U64(0xfbff0efdfbff0efd), U64(0x5638850f5638850f),
+    U64(0x1ed5ae3d1ed5ae3d), U64(0x27392d3627392d36),
+    U64(0x64d90f0a64d90f0a), U64(0x21a65c6821a65c68),
+    U64(0xd1545b9bd1545b9b), U64(0x3a2e36243a2e3624),
+    U64(0xb1670a0cb1670a0c), U64(0x0fe757930fe75793),
+    U64(0xd296eeb4d296eeb4), U64(0x9e919b1b9e919b1b),
+    U64(0x4fc5c0804fc5c080), U64(0xa220dc61a220dc61),
+    U64(0x694b775a694b775a), U64(0x161a121c161a121c),
+    U64(0x0aba93e20aba93e2), U64(0xe52aa0c0e52aa0c0),
+    U64(0x43e0223c43e0223c), U64(0x1d171b121d171b12),
+    U64(0x0b0d090e0b0d090e), U64(0xadc78bf2adc78bf2),
+    U64(0xb9a8b62db9a8b62d), U64(0xc8a91e14c8a91e14),
+    U64(0x8519f1578519f157), U64(0x4c0775af4c0775af),
+    U64(0xbbdd99eebbdd99ee), U64(0xfd607fa3fd607fa3),
+    U64(0x9f2601f79f2601f7), U64(0xbcf5725cbcf5725c),
+    U64(0xc53b6644c53b6644), U64(0x347efb5b347efb5b),
+    U64(0x7629438b7629438b), U64(0xdcc623cbdcc623cb),
+    U64(0x68fcedb668fcedb6), U64(0x63f1e4b863f1e4b8),
+    U64(0xcadc31d7cadc31d7), U64(0x1085634210856342),
+    U64(0x4022971340229713), U64(0x2011c6842011c684),
+    U64(0x7d244a857d244a85), U64(0xf83dbbd2f83dbbd2),
+    U64(0x1132f9ae1132f9ae), U64(0x6da129c76da129c7),
+    U64(0x4b2f9e1d4b2f9e1d), U64(0xf330b2dcf330b2dc),
+    U64(0xec52860dec52860d), U64(0xd0e3c177d0e3c177),
+    U64(0x6c16b32b6c16b32b), U64(0x99b970a999b970a9),
+    U64(0xfa489411fa489411), U64(0x2264e9472264e947),
+    U64(0xc48cfca8c48cfca8), U64(0x1a3ff0a01a3ff0a0),
+    U64(0xd82c7d56d82c7d56), U64(0xef903322ef903322),
+    U64(0xc74e4987c74e4987), U64(0xc1d138d9c1d138d9),
+    U64(0xfea2ca8cfea2ca8c), U64(0x360bd498360bd498),
+    U64(0xcf81f5a6cf81f5a6), U64(0x28de7aa528de7aa5),
+    U64(0x268eb7da268eb7da), U64(0xa4bfad3fa4bfad3f),
+    U64(0xe49d3a2ce49d3a2c), U64(0x0d9278500d927850),
+    U64(0x9bcc5f6a9bcc5f6a), U64(0x62467e5462467e54),
+    U64(0xc2138df6c2138df6), U64(0xe8b8d890e8b8d890),
+    U64(0x5ef7392e5ef7392e), U64(0xf5afc382f5afc382),
+    U64(0xbe805d9fbe805d9f), U64(0x7c93d0697c93d069),
+    U64(0xa92dd56fa92dd56f), U64(0xb31225cfb31225cf),
+    U64(0x3b99acc83b99acc8), U64(0xa77d1810a77d1810),
+    U64(0x6e639ce86e639ce8), U64(0x7bbb3bdb7bbb3bdb),
+    U64(0x097826cd097826cd), U64(0xf418596ef418596e),
+    U64(0x01b79aec01b79aec), U64(0xa89a4f83a89a4f83),
+    U64(0x656e95e6656e95e6), U64(0x7ee6ffaa7ee6ffaa),
+    U64(0x08cfbc2108cfbc21), U64(0xe6e815efe6e815ef),
+    U64(0xd99be7bad99be7ba), U64(0xce366f4ace366f4a),
+    U64(0xd4099fead4099fea), U64(0xd67cb029d67cb029),
+    U64(0xafb2a431afb2a431), U64(0x31233f2a31233f2a),
+    U64(0x3094a5c63094a5c6), U64(0xc066a235c066a235),
+    U64(0x37bc4e7437bc4e74), U64(0xa6ca82fca6ca82fc),
+    U64(0xb0d090e0b0d090e0), U64(0x15d8a73315d8a733),
+    U64(0x4a9804f14a9804f1), U64(0xf7daec41f7daec41),
+    U64(0x0e50cd7f0e50cd7f), U64(0x2ff691172ff69117),
+    U64(0x8dd64d768dd64d76), U64(0x4db0ef434db0ef43),
+    U64(0x544daacc544daacc), U64(0xdf0496e4df0496e4),
+    U64(0xe3b5d19ee3b5d19e), U64(0x1b886a4c1b886a4c),
+    U64(0xb81f2cc1b81f2cc1), U64(0x7f5165467f516546),
+    U64(0x04ea5e9d04ea5e9d), U64(0x5d358c015d358c01),
+    U64(0x737487fa737487fa), U64(0x2e410bfb2e410bfb),
+    U64(0x5a1d67b35a1d67b3), U64(0x52d2db9252d2db92),
+    U64(0x335610e9335610e9), U64(0x1347d66d1347d66d),
+    U64(0x8c61d79a8c61d79a), U64(0x7a0ca1377a0ca137),
+    U64(0x8e14f8598e14f859), U64(0x893c13eb893c13eb),
+    U64(0xee27a9ceee27a9ce), U64(0x35c961b735c961b7),
+    U64(0xede51ce1ede51ce1), U64(0x3cb1477a3cb1477a),
+    U64(0x59dfd29c59dfd29c), U64(0x3f73f2553f73f255),
+    U64(0x79ce141879ce1418), U64(0xbf37c773bf37c773),
+    U64(0xeacdf753eacdf753), U64(0x5baafd5f5baafd5f),
+    U64(0x146f3ddf146f3ddf), U64(0x86db447886db4478),
+    U64(0x81f3afca81f3afca), U64(0x3ec468b93ec468b9),
+    U64(0x2c3424382c342438), U64(0x5f40a3c25f40a3c2),
+    U64(0x72c31d1672c31d16), U64(0x0c25e2bc0c25e2bc),
+    U64(0x8b493c288b493c28), U64(0x41950dff41950dff),
+    U64(0x7101a8397101a839), U64(0xdeb30c08deb30c08),
+    U64(0x9ce4b4d89ce4b4d8), U64(0x90c1566490c15664),
+    U64(0x6184cb7b6184cb7b), U64(0x70b632d570b632d5),
+    U64(0x745c6c48745c6c48), U64(0x4257b8d04257b8d0)
+};
+static const u8 Td4[256] = {
+    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
+    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
+    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
+    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
+    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
+    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
+    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
+    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
+    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
+    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
+    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
+    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
+    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
+    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
+    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
+    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
+    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
+    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
+    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
+    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
+    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
+    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
+    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
+    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
+    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
+    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
+    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
+    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
+    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
+    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
+    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
+    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU
+};
+
+static const u32 rcon[] = {
+    0x00000001U, 0x00000002U, 0x00000004U, 0x00000008U,
+    0x00000010U, 0x00000020U, 0x00000040U, 0x00000080U,
+    0x0000001bU, 0x00000036U, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ */
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+			AES_KEY *key) {
+
+	u32 *rk;
+   	int i = 0;
+	u32 temp;
+
+	if (!userKey || !key)
+		return -1;
+	if (bits != 128 && bits != 192 && bits != 256)
+		return -2;
+
+	rk = key->rd_key;
+
+	if (bits==128)
+		key->rounds = 10;
+	else if (bits==192)
+		key->rounds = 12;
+	else
+		key->rounds = 14;
+
+	rk[0] = GETU32(userKey     );
+	rk[1] = GETU32(userKey +  4);
+	rk[2] = GETU32(userKey +  8);
+	rk[3] = GETU32(userKey + 12);
+	if (bits == 128) {
+		while (1) {
+			temp  = rk[3];
+			rk[4] = rk[0] ^
+				(Te4[(temp >>  8) & 0xff]      ) ^
+				(Te4[(temp >> 16) & 0xff] <<  8) ^
+				(Te4[(temp >> 24)       ] << 16) ^
+				(Te4[(temp      ) & 0xff] << 24) ^
+				rcon[i];
+			rk[5] = rk[1] ^ rk[4];
+			rk[6] = rk[2] ^ rk[5];
+			rk[7] = rk[3] ^ rk[6];
+			if (++i == 10) {
+				return 0;
+			}
+			rk += 4;
+		}
+	}
+	rk[4] = GETU32(userKey + 16);
+	rk[5] = GETU32(userKey + 20);
+	if (bits == 192) {
+		while (1) {
+			temp = rk[ 5];
+			rk[ 6] = rk[ 0] ^
+				(Te4[(temp >>  8) & 0xff]      ) ^
+				(Te4[(temp >> 16) & 0xff] <<  8) ^
+				(Te4[(temp >> 24)       ] << 16) ^
+				(Te4[(temp      ) & 0xff] << 24) ^
+				rcon[i];
+			rk[ 7] = rk[ 1] ^ rk[ 6];
+			rk[ 8] = rk[ 2] ^ rk[ 7];
+			rk[ 9] = rk[ 3] ^ rk[ 8];
+			if (++i == 8) {
+				return 0;
+			}
+			rk[10] = rk[ 4] ^ rk[ 9];
+			rk[11] = rk[ 5] ^ rk[10];
+			rk += 6;
+		}
+	}
+	rk[6] = GETU32(userKey + 24);
+	rk[7] = GETU32(userKey + 28);
+	if (bits == 256) {
+		while (1) {
+			temp = rk[ 7];
+			rk[ 8] = rk[ 0] ^
+				(Te4[(temp >>  8) & 0xff]      ) ^
+				(Te4[(temp >> 16) & 0xff] <<  8) ^
+				(Te4[(temp >> 24)       ] << 16) ^
+				(Te4[(temp      ) & 0xff] << 24) ^
+				rcon[i];
+			rk[ 9] = rk[ 1] ^ rk[ 8];
+			rk[10] = rk[ 2] ^ rk[ 9];
+			rk[11] = rk[ 3] ^ rk[10];
+			if (++i == 7) {
+				return 0;
+			}
+			temp = rk[11];
+			rk[12] = rk[ 4] ^
+				(Te4[(temp      ) & 0xff]      ) ^
+				(Te4[(temp >>  8) & 0xff] <<  8) ^
+				(Te4[(temp >> 16) & 0xff] << 16) ^
+				(Te4[(temp >> 24)       ] << 24);
+			rk[13] = rk[ 5] ^ rk[12];
+			rk[14] = rk[ 6] ^ rk[13];
+			rk[15] = rk[ 7] ^ rk[14];
+
+			rk += 8;
+        	}
+	}
+	return 0;
+}
+
+/**
+ * Expand the cipher key into the decryption key schedule.
+ */
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+			 AES_KEY *key) {
+
+        u32 *rk;
+	int i, j, status;
+	u32 temp;
+
+	/* first, start with an encryption schedule */
+	status = AES_set_encrypt_key(userKey, bits, key);
+	if (status < 0)
+		return status;
+
+	rk = key->rd_key;
+
+	/* invert the order of the round keys: */
+	for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
+		temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
+		temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+		temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+		temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+	}
+	/* apply the inverse MixColumn transform to all round keys but the first and the last: */
+	for (i = 1; i < (key->rounds); i++) {
+		rk += 4;
+#if 1
+		for (j = 0; j < 4; j++) {
+			u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
+
+			tp1 = rk[j];
+			m = tp1 & 0x80808080;
+			tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp2 & 0x80808080;
+			tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp4 & 0x80808080;
+			tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			tp9 = tp8 ^ tp1;
+			tpb = tp9 ^ tp2;
+			tpd = tp9 ^ tp4;
+			tpe = tp8 ^ tp4 ^ tp2;
+#if defined(ROTATE)
+			rk[j] = tpe ^ ROTATE(tpd,16) ^
+				ROTATE(tp9,8) ^ ROTATE(tpb,24);
+#else
+			rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 
+				(tp9 >> 24) ^ (tp9 << 8) ^
+				(tpb >> 8) ^ (tpb << 24);
+#endif
+		}
+#else
+		rk[0] =
+			Td0[Te2[(rk[0]      ) & 0xff] & 0xff] ^
+			Td1[Te2[(rk[0] >>  8) & 0xff] & 0xff] ^
+			Td2[Te2[(rk[0] >> 16) & 0xff] & 0xff] ^
+			Td3[Te2[(rk[0] >> 24)       ] & 0xff];
+		rk[1] =
+			Td0[Te2[(rk[1]      ) & 0xff] & 0xff] ^
+			Td1[Te2[(rk[1] >>  8) & 0xff] & 0xff] ^
+			Td2[Te2[(rk[1] >> 16) & 0xff] & 0xff] ^
+			Td3[Te2[(rk[1] >> 24)       ] & 0xff];
+		rk[2] =
+			Td0[Te2[(rk[2]      ) & 0xff] & 0xff] ^
+			Td1[Te2[(rk[2] >>  8) & 0xff] & 0xff] ^
+			Td2[Te2[(rk[2] >> 16) & 0xff] & 0xff] ^
+			Td3[Te2[(rk[2] >> 24)       ] & 0xff];
+		rk[3] =
+			Td0[Te2[(rk[3]      ) & 0xff] & 0xff] ^
+			Td1[Te2[(rk[3] >>  8) & 0xff] & 0xff] ^
+			Td2[Te2[(rk[3] >> 16) & 0xff] & 0xff] ^
+			Td3[Te2[(rk[3] >> 24)       ] & 0xff];
+#endif
+	}
+	return 0;
+}
+
+/*
+ * Encrypt a single block
+ * in and out can overlap
+ */
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+		 const AES_KEY *key) {
+
+	const u32 *rk;
+	u32 s0, s1, s2, s3, t[4];
+	int r;
+
+	assert(in && out && key);
+	rk = key->rd_key;
+
+	/*
+	 * map byte array block to cipher state
+	 * and add initial round key:
+	 */
+	s0 = GETU32(in     ) ^ rk[0];
+	s1 = GETU32(in +  4) ^ rk[1];
+	s2 = GETU32(in +  8) ^ rk[2];
+	s3 = GETU32(in + 12) ^ rk[3];
+
+#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
+	prefetch256(Te4);
+
+	t[0] =	Te4[(s0      ) & 0xff]       ^
+		Te4[(s1 >>  8) & 0xff] <<  8 ^
+		Te4[(s2 >> 16) & 0xff] << 16 ^
+		Te4[(s3 >> 24)       ] << 24;
+	t[1] =	Te4[(s1      ) & 0xff]       ^
+		Te4[(s2 >>  8) & 0xff] <<  8 ^
+		Te4[(s3 >> 16) & 0xff] << 16 ^
+		Te4[(s0 >> 24)       ] << 24;
+	t[2] =	Te4[(s2      ) & 0xff]       ^
+		Te4[(s3 >>  8) & 0xff] <<  8 ^
+		Te4[(s0 >> 16) & 0xff] << 16 ^
+		Te4[(s1 >> 24)       ] << 24;
+	t[3] =	Te4[(s3      ) & 0xff]       ^
+		Te4[(s0 >>  8) & 0xff] <<  8 ^
+		Te4[(s1 >> 16) & 0xff] << 16 ^
+		Te4[(s2 >> 24)       ] << 24;
+
+	/* now do the linear transform using words */
+	{	int i;
+		u32 r0, r1, r2;
+
+		for (i = 0; i < 4; i++) {
+			r0 = t[i];
+			r1 = r0 & 0x80808080;
+			r2 = ((r0 & 0x7f7f7f7f) << 1) ^
+				((r1 - (r1 >> 7)) & 0x1b1b1b1b);
+#if defined(ROTATE)
+			t[i] = r2 ^ ROTATE(r2,24) ^ ROTATE(r0,24) ^
+				ROTATE(r0,16) ^ ROTATE(r0,8);
+#else
+			t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^
+				(r0 << 16) ^ (r0 >> 16) ^
+				(r0 << 8) ^ (r0 >> 24);
+#endif
+			t[i] ^= rk[4+i];
+		}
+	}
+#else
+	t[0] =	Te0[(s0      ) & 0xff] ^
+		Te1[(s1 >>  8) & 0xff] ^
+		Te2[(s2 >> 16) & 0xff] ^
+		Te3[(s3 >> 24)       ] ^
+		rk[4];
+	t[1] =	Te0[(s1      ) & 0xff] ^
+		Te1[(s2 >>  8) & 0xff] ^
+		Te2[(s3 >> 16) & 0xff] ^
+		Te3[(s0 >> 24)       ] ^
+		rk[5];
+	t[2] =	Te0[(s2      ) & 0xff] ^
+		Te1[(s3 >>  8) & 0xff] ^
+		Te2[(s0 >> 16) & 0xff] ^
+		Te3[(s1 >> 24)       ] ^
+		rk[6];
+	t[3] =	Te0[(s3      ) & 0xff] ^
+		Te1[(s0 >>  8) & 0xff] ^
+		Te2[(s1 >> 16) & 0xff] ^
+		Te3[(s2 >> 24)       ] ^
+		rk[7];
+#endif
+	s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
+
+    /*
+     * Nr - 2 full rounds:
+     */
+    for (rk+=8,r=key->rounds-2; r>0; rk+=4,r--) {
+#if defined(AES_COMPACT_IN_INNER_ROUNDS)
+	t[0] =	Te4[(s0      ) & 0xff]       ^
+		Te4[(s1 >>  8) & 0xff] <<  8 ^
+		Te4[(s2 >> 16) & 0xff] << 16 ^
+		Te4[(s3 >> 24)       ] << 24;
+	t[1] =	Te4[(s1      ) & 0xff]       ^
+		Te4[(s2 >>  8) & 0xff] <<  8 ^
+		Te4[(s3 >> 16) & 0xff] << 16 ^
+		Te4[(s0 >> 24)       ] << 24;
+	t[2] =	Te4[(s2      ) & 0xff]       ^
+		Te4[(s3 >>  8) & 0xff] <<  8 ^
+		Te4[(s0 >> 16) & 0xff] << 16 ^
+		Te4[(s1 >> 24)       ] << 24;
+	t[3] =	Te4[(s3      ) & 0xff]       ^
+		Te4[(s0 >>  8) & 0xff] <<  8 ^
+		Te4[(s1 >> 16) & 0xff] << 16 ^
+		Te4[(s2 >> 24)       ] << 24;
+
+	/* now do the linear transform using words */
+	{	int i;
+		u32 r0, r1, r2;
+
+		for (i = 0; i < 4; i++) {
+			r0 = t[i];
+			r1 = r0 & 0x80808080;
+			r2 = ((r0 & 0x7f7f7f7f) << 1) ^
+				((r1 - (r1 >> 7)) & 0x1b1b1b1b);
+#if defined(ROTATE)
+			t[i] = r2 ^ ROTATE(r2,24) ^ ROTATE(r0,24) ^
+				ROTATE(r0,16) ^ ROTATE(r0,8);
+#else
+			t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^
+				(r0 << 16) ^ (r0 >> 16) ^
+				(r0 << 8) ^ (r0 >> 24);
+#endif
+			t[i] ^= rk[i];
+		}
+	}
+#else
+	t[0] =	Te0[(s0      ) & 0xff] ^
+		Te1[(s1 >>  8) & 0xff] ^
+		Te2[(s2 >> 16) & 0xff] ^
+		Te3[(s3 >> 24)       ] ^
+		rk[0];
+	t[1] =	Te0[(s1      ) & 0xff] ^
+		Te1[(s2 >>  8) & 0xff] ^
+		Te2[(s3 >> 16) & 0xff] ^
+		Te3[(s0 >> 24)       ] ^
+		rk[1];
+	t[2] =	Te0[(s2      ) & 0xff] ^
+		Te1[(s3 >>  8) & 0xff] ^
+		Te2[(s0 >> 16) & 0xff] ^
+		Te3[(s1 >> 24)       ] ^
+		rk[2];
+	t[3] =	Te0[(s3      ) & 0xff] ^
+		Te1[(s0 >>  8) & 0xff] ^
+		Te2[(s1 >> 16) & 0xff] ^
+		Te3[(s2 >> 24)       ] ^
+		rk[3];
+#endif
+	s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
+    }
+    /*
+	 * apply last round and
+	 * map cipher state to byte array block:
+	 */
+#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
+	prefetch256(Te4);
+
+	*(u32*)(out+0) =
+		Te4[(s0      ) & 0xff]       ^
+		Te4[(s1 >>  8) & 0xff] <<  8 ^
+		Te4[(s2 >> 16) & 0xff] << 16 ^
+		Te4[(s3 >> 24)       ] << 24 ^
+		rk[0];
+	*(u32*)(out+4) =
+		Te4[(s1      ) & 0xff]       ^
+		Te4[(s2 >>  8) & 0xff] <<  8 ^
+		Te4[(s3 >> 16) & 0xff] << 16 ^
+		Te4[(s0 >> 24)       ] << 24 ^
+		rk[1];
+	*(u32*)(out+8) =
+		Te4[(s2      ) & 0xff]       ^
+		Te4[(s3 >>  8) & 0xff] <<  8 ^
+		Te4[(s0 >> 16) & 0xff] << 16 ^
+		Te4[(s1 >> 24)       ] << 24 ^
+		rk[2];
+	*(u32*)(out+12) =
+		Te4[(s3      ) & 0xff]       ^
+		Te4[(s0 >>  8) & 0xff] <<  8 ^
+		Te4[(s1 >> 16) & 0xff] << 16 ^
+		Te4[(s2 >> 24)       ] << 24 ^
+		rk[3];
+#else
+	*(u32*)(out+0) =
+		(Te2[(s0      ) & 0xff] & 0x000000ffU) ^
+		(Te3[(s1 >>  8) & 0xff] & 0x0000ff00U) ^
+		(Te0[(s2 >> 16) & 0xff] & 0x00ff0000U) ^
+		(Te1[(s3 >> 24)       ] & 0xff000000U) ^
+		rk[0];
+	*(u32*)(out+4) =
+		(Te2[(s1      ) & 0xff] & 0x000000ffU) ^
+		(Te3[(s2 >>  8) & 0xff] & 0x0000ff00U) ^
+		(Te0[(s3 >> 16) & 0xff] & 0x00ff0000U) ^
+		(Te1[(s0 >> 24)       ] & 0xff000000U) ^
+		rk[1];
+	*(u32*)(out+8) =
+		(Te2[(s2      ) & 0xff] & 0x000000ffU) ^
+		(Te3[(s3 >>  8) & 0xff] & 0x0000ff00U) ^
+		(Te0[(s0 >> 16) & 0xff] & 0x00ff0000U) ^
+		(Te1[(s1 >> 24)       ] & 0xff000000U) ^
+		rk[2];
+	*(u32*)(out+12) =
+		(Te2[(s3      ) & 0xff] & 0x000000ffU) ^
+		(Te3[(s0 >>  8) & 0xff] & 0x0000ff00U) ^
+		(Te0[(s1 >> 16) & 0xff] & 0x00ff0000U) ^
+		(Te1[(s2 >> 24)       ] & 0xff000000U) ^
+		rk[3];
+#endif
+}
+
+/*
+ * Decrypt a single block
+ * in and out can overlap
+ */
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+		 const AES_KEY *key) {
+
+	const u32 *rk;
+	u32 s0, s1, s2, s3, t[4];
+	int r;
+
+	assert(in && out && key);
+	rk = key->rd_key;
+
+	/*
+	 * map byte array block to cipher state
+	 * and add initial round key:
+	 */
+	s0 = GETU32(in     ) ^ rk[0];
+	s1 = GETU32(in +  4) ^ rk[1];
+	s2 = GETU32(in +  8) ^ rk[2];
+	s3 = GETU32(in + 12) ^ rk[3];
+
+#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
+	prefetch256(Td4);
+
+        t[0] =	Td4[(s0      ) & 0xff]       ^
+		Td4[(s3 >>  8) & 0xff] <<  8 ^
+		Td4[(s2 >> 16) & 0xff] << 16 ^
+		Td4[(s1 >> 24)       ] << 24;
+        t[1] =	Td4[(s1      ) & 0xff]       ^
+		Td4[(s0 >>  8) & 0xff] <<  8 ^
+		Td4[(s3 >> 16) & 0xff] << 16 ^
+		Td4[(s2 >> 24)       ] << 24;
+        t[2] =	Td4[(s2      ) & 0xff]       ^
+		Td4[(s1 >>  8) & 0xff] <<  8 ^
+		Td4[(s0 >> 16) & 0xff] << 16 ^
+		Td4[(s3 >> 24)       ] << 24;
+        t[3] =	Td4[(s3      ) & 0xff]       ^
+		Td4[(s2 >>  8) & 0xff] <<  8 ^
+		Td4[(s1 >> 16) & 0xff] << 16 ^
+		Td4[(s0 >> 24)       ] << 24;
+
+	/* now do the linear transform using words */ 
+	{	int i;
+		u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
+
+		for (i = 0; i < 4; i++) {
+			tp1 = t[i];
+			m = tp1 & 0x80808080;
+			tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp2 & 0x80808080;
+			tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp4 & 0x80808080;
+			tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			tp9 = tp8 ^ tp1;
+			tpb = tp9 ^ tp2;
+			tpd = tp9 ^ tp4;
+			tpe = tp8 ^ tp4 ^ tp2;
+#if defined(ROTATE)
+			t[i] = tpe ^ ROTATE(tpd,16) ^
+				ROTATE(tp9,8) ^ ROTATE(tpb,24);
+#else
+			t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 
+				(tp9 >> 24) ^ (tp9 << 8) ^
+				(tpb >> 8) ^ (tpb << 24);
+#endif
+			t[i] ^= rk[4+i];
+		}
+	}
+#else
+	t[0] =	Td0[(s0      ) & 0xff] ^
+		Td1[(s3 >>  8) & 0xff] ^
+		Td2[(s2 >> 16) & 0xff] ^
+		Td3[(s1 >> 24)       ] ^
+		rk[4];
+	t[1] =	Td0[(s1      ) & 0xff] ^
+		Td1[(s0 >>  8) & 0xff] ^
+		Td2[(s3 >> 16) & 0xff] ^
+		Td3[(s2 >> 24)       ] ^
+		rk[5];
+	t[2] =	Td0[(s2      ) & 0xff] ^
+		Td1[(s1 >>  8) & 0xff] ^
+		Td2[(s0 >> 16) & 0xff] ^
+		Td3[(s3 >> 24)       ] ^
+		rk[6];
+	t[3] =	Td0[(s3      ) & 0xff] ^
+		Td1[(s2 >>  8) & 0xff] ^
+		Td2[(s1 >> 16) & 0xff] ^
+		Td3[(s0 >> 24)       ] ^
+		rk[7];
+#endif
+	s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
+
+    /*
+     * Nr - 2 full rounds:
+     */
+    for (rk+=8,r=key->rounds-2; r>0; rk+=4,r--) {
+#if defined(AES_COMPACT_IN_INNER_ROUNDS)
+        t[0] =	Td4[(s0      ) & 0xff]       ^
+		Td4[(s3 >>  8) & 0xff] <<  8 ^
+		Td4[(s2 >> 16) & 0xff] << 16 ^
+		Td4[(s1 >> 24)       ] << 24;
+        t[1] =	Td4[(s1      ) & 0xff]       ^
+		Td4[(s0 >>  8) & 0xff] <<  8 ^
+		Td4[(s3 >> 16) & 0xff] << 16 ^
+		Td4[(s2 >> 24)       ] << 24;
+        t[2] =	Td4[(s2      ) & 0xff]       ^
+		Td4[(s1 >>  8) & 0xff] <<  8 ^
+		Td4[(s0 >> 16) & 0xff] << 16 ^
+		Td4[(s3 >> 24)       ] << 24;
+        t[3] =	Td4[(s3      ) & 0xff]       ^
+		Td4[(s2 >>  8) & 0xff] <<  8 ^
+		Td4[(s1 >> 16) & 0xff] << 16 ^
+		Td4[(s0 >> 24)       ] << 24;
+
+	/* now do the linear transform using words */ 
+	{	int i;
+		u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
+
+		for (i = 0; i < 4; i++) {
+			tp1 = t[i];
+			m = tp1 & 0x80808080;
+			tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp2 & 0x80808080;
+			tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp4 & 0x80808080;
+			tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			tp9 = tp8 ^ tp1;
+			tpb = tp9 ^ tp2;
+			tpd = tp9 ^ tp4;
+			tpe = tp8 ^ tp4 ^ tp2;
+#if defined(ROTATE)
+			t[i] = tpe ^ ROTATE(tpd,16) ^
+				ROTATE(tp9,8) ^ ROTATE(tpb,24);
+#else
+			t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 
+				(tp9 >> 24) ^ (tp9 << 8) ^
+				(tpb >> 8) ^ (tpb << 24);
+#endif
+			t[i] ^= rk[i];
+		}
+	}
+#else
+	t[0] =	Td0[(s0      ) & 0xff] ^
+		Td1[(s3 >>  8) & 0xff] ^
+		Td2[(s2 >> 16) & 0xff] ^
+		Td3[(s1 >> 24)       ] ^
+		rk[0];
+	t[1] =	Td0[(s1      ) & 0xff] ^
+		Td1[(s0 >>  8) & 0xff] ^
+		Td2[(s3 >> 16) & 0xff] ^
+		Td3[(s2 >> 24)       ] ^
+		rk[1];
+	t[2] =	Td0[(s2      ) & 0xff] ^
+		Td1[(s1 >>  8) & 0xff] ^
+		Td2[(s0 >> 16) & 0xff] ^
+		Td3[(s3 >> 24)       ] ^
+		rk[2];
+	t[3] =	Td0[(s3      ) & 0xff] ^
+		Td1[(s2 >>  8) & 0xff] ^
+		Td2[(s1 >> 16) & 0xff] ^
+		Td3[(s0 >> 24)       ] ^
+		rk[3];
+#endif
+	s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
+    }
+    /*
+	 * apply last round and
+	 * map cipher state to byte array block:
+	 */
+	prefetch256(Td4);
+
+	*(u32*)(out+0) =
+		(Td4[(s0      ) & 0xff])	^
+		(Td4[(s3 >>  8) & 0xff] <<  8) ^
+		(Td4[(s2 >> 16) & 0xff] << 16) ^
+		(Td4[(s1 >> 24)       ] << 24) ^
+		rk[0];
+	*(u32*)(out+4) =
+		(Td4[(s1      ) & 0xff])	 ^
+		(Td4[(s0 >>  8) & 0xff] <<  8) ^
+		(Td4[(s3 >> 16) & 0xff] << 16) ^
+		(Td4[(s2 >> 24)       ] << 24) ^
+		rk[1];
+	*(u32*)(out+8) =
+		(Td4[(s2      ) & 0xff])	 ^
+		(Td4[(s1 >>  8) & 0xff] <<  8) ^
+		(Td4[(s0 >> 16) & 0xff] << 16) ^
+		(Td4[(s3 >> 24)       ] << 24) ^
+		rk[2];
+	*(u32*)(out+12) =
+		(Td4[(s3      ) & 0xff])	 ^
+		(Td4[(s2 >>  8) & 0xff] <<  8) ^
+		(Td4[(s1 >> 16) & 0xff] << 16) ^
+		(Td4[(s0 >> 24)       ] << 24) ^
+		rk[3];
+}
diff --git a/openssl/crypto/aes/asm/aes-586.pl b/openssl/crypto/aes/asm/aes-586.pl
new file mode 100755
index 0000000..aab40e6
--- /dev/null
+++ b/openssl/crypto/aes/asm/aes-586.pl
@@ -0,0 +1,2980 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# Version 4.3.
+#
+# You might fail to appreciate this module performance from the first
+# try. If compared to "vanilla" linux-ia32-icc target, i.e. considered
+# to be *the* best Intel C compiler without -KPIC, performance appears
+# to be virtually identical... But try to re-configure with shared
+# library support... Aha! Intel compiler "suddenly" lags behind by 30%
+# [on P4, more on others]:-) And if compared to position-independent
+# code generated by GNU C, this code performs *more* than *twice* as
+# fast! Yes, all this buzz about PIC means that unlike other hand-
+# coded implementations, this one was explicitly designed to be safe
+# to use even in shared library context... This also means that this
+# code isn't necessarily absolutely fastest "ever," because in order
+# to achieve position independence an extra register has to be
+# off-loaded to stack, which affects the benchmark result.
+#
+# Special note about instruction choice. Do you recall RC4_INT code
+# performing poorly on P4? It might be the time to figure out why.
+# RC4_INT code implies effective address calculations in base+offset*4
+# form. Trouble is that it seems that offset scaling turned to be
+# critical path... At least eliminating scaling resulted in 2.8x RC4
+# performance improvement [as you might recall]. As AES code is hungry
+# for scaling too, I [try to] avoid the latter by favoring off-by-2
+# shifts and masking the result with 0xFF<<2 instead of "boring" 0xFF.
+#
+# As was shown by Dean Gaudet <dean@arctic.org>, the above note turned
+# void. Performance improvement with off-by-2 shifts was observed on
+# intermediate implementation, which was spilling yet another register
+# to stack... Final offset*4 code below runs just a tad faster on P4,
+# but exhibits up to 10% improvement on other cores.
+#
+# Second version is "monolithic" replacement for aes_core.c, which in
+# addition to AES_[de|en]crypt implements AES_set_[de|en]cryption_key.
+# This made it possible to implement little-endian variant of the
+# algorithm without modifying the base C code. Motivating factor for
+# the undertaken effort was that it appeared that in tight IA-32
+# register window little-endian flavor could achieve slightly higher
+# Instruction Level Parallelism, and it indeed resulted in up to 15%
+# better performance on most recent µ-archs...
+#
+# Third version adds AES_cbc_encrypt implementation, which resulted in
+# up to 40% performance imrovement of CBC benchmark results. 40% was
+# observed on P4 core, where "overall" imrovement coefficient, i.e. if
+# compared to PIC generated by GCC and in CBC mode, was observed to be
+# as large as 4x:-) CBC performance is virtually identical to ECB now
+# and on some platforms even better, e.g. 17.6 "small" cycles/byte on
+# Opteron, because certain function prologues and epilogues are
+# effectively taken out of the loop...
+#
+# Version 3.2 implements compressed tables and prefetch of these tables
+# in CBC[!] mode. Former means that 3/4 of table references are now
+# misaligned, which unfortunately has negative impact on elder IA-32
+# implementations, Pentium suffered 30% penalty, PIII - 10%.
+#
+# Version 3.3 avoids L1 cache aliasing between stack frame and
+# S-boxes, and 3.4 - L1 cache aliasing even between key schedule. The
+# latter is achieved by copying the key schedule to controlled place in
+# stack. This unfortunately has rather strong impact on small block CBC
+# performance, ~2x deterioration on 16-byte block if compared to 3.3.
+#
+# Version 3.5 checks if there is L1 cache aliasing between user-supplied
+# key schedule and S-boxes and abstains from copying the former if
+# there is no. This allows end-user to consciously retain small block
+# performance by aligning key schedule in specific manner.
+#
+# Version 3.6 compresses Td4 to 256 bytes and prefetches it in ECB.
+#
+# Current ECB performance numbers for 128-bit key in CPU cycles per
+# processed byte [measure commonly used by AES benchmarkers] are:
+#
+#		small footprint		fully unrolled
+# P4		24			22
+# AMD K8	20			19
+# PIII		25			23
+# Pentium	81			78
+#
+# Version 3.7 reimplements outer rounds as "compact." Meaning that
+# first and last rounds reference compact 256 bytes S-box. This means
+# that first round consumes a lot more CPU cycles and that encrypt
+# and decrypt performance becomes asymmetric. Encrypt performance
+# drops by 10-12%, while decrypt - by 20-25%:-( 256 bytes S-box is
+# aggressively pre-fetched.
+#
+# Version 4.0 effectively rolls back to 3.6 and instead implements
+# additional set of functions, _[x86|sse]_AES_[en|de]crypt_compact,
+# which use exclusively 256 byte S-box. These functions are to be
+# called in modes not concealing plain text, such as ECB, or when
+# we're asked to process smaller amount of data [or unconditionally
+# on hyper-threading CPU]. Currently it's called unconditionally from
+# AES_[en|de]crypt, which affects all modes, but CBC. CBC routine
+# still needs to be modified to switch between slower and faster
+# mode when appropriate... But in either case benchmark landscape
+# changes dramatically and below numbers are CPU cycles per processed
+# byte for 128-bit key.
+#
+#		ECB encrypt	ECB decrypt	CBC large chunk
+# P4		56[60]		84[100]		23
+# AMD K8	48[44]		70[79]		18
+# PIII		41[50]		61[91]		24
+# Core 2	32[38]		45[70]		18.5
+# Pentium	120		160		77
+#
+# Version 4.1 switches to compact S-box even in key schedule setup.
+#
+# Version 4.2 prefetches compact S-box in every SSE round or in other
+# words every cache-line is *guaranteed* to be accessed within ~50
+# cycles window. Why just SSE? Because it's needed on hyper-threading
+# CPU! Which is also why it's prefetched with 64 byte stride. Best
+# part is that it has no negative effect on performance:-)  
+#
+# Version 4.3 implements switch between compact and non-compact block
+# functions in AES_cbc_encrypt depending on how much data was asked
+# to be processed in one stroke.
+#
+######################################################################
+# Timing attacks are classified in two classes: synchronous when
+# attacker consciously initiates cryptographic operation and collects
+# timing data of various character afterwards, and asynchronous when
+# malicious code is executed on same CPU simultaneously with AES,
+# instruments itself and performs statistical analysis of this data.
+#
+# As far as synchronous attacks go the root to the AES timing
+# vulnerability is twofold. Firstly, of 256 S-box elements at most 160
+# are referred to in single 128-bit block operation. Well, in C
+# implementation with 4 distinct tables it's actually as little as 40
+# references per 256 elements table, but anyway... Secondly, even
+# though S-box elements are clustered into smaller amount of cache-
+# lines, smaller than 160 and even 40, it turned out that for certain
+# plain-text pattern[s] or simply put chosen plain-text and given key
+# few cache-lines remain unaccessed during block operation. Now, if
+# attacker can figure out this access pattern, he can deduct the key
+# [or at least part of it]. The natural way to mitigate this kind of
+# attacks is to minimize the amount of cache-lines in S-box and/or
+# prefetch them to ensure that every one is accessed for more uniform
+# timing. But note that *if* plain-text was concealed in such way that
+# input to block function is distributed *uniformly*, then attack
+# wouldn't apply. Now note that some encryption modes, most notably
+# CBC, do mask the plain-text in this exact way [secure cipher output
+# is distributed uniformly]. Yes, one still might find input that
+# would reveal the information about given key, but if amount of
+# candidate inputs to be tried is larger than amount of possible key
+# combinations then attack becomes infeasible. This is why revised
+# AES_cbc_encrypt "dares" to switch to larger S-box when larger chunk
+# of data is to be processed in one stroke. The current size limit of
+# 512 bytes is chosen to provide same [diminishigly low] probability
+# for cache-line to remain untouched in large chunk operation with
+# large S-box as for single block operation with compact S-box and
+# surely needs more careful consideration...
+#
+# As for asynchronous attacks. There are two flavours: attacker code
+# being interleaved with AES on hyper-threading CPU at *instruction*
+# level, and two processes time sharing single core. As for latter.
+# Two vectors. 1. Given that attacker process has higher priority,
+# yield execution to process performing AES just before timer fires
+# off the scheduler, immediately regain control of CPU and analyze the
+# cache state. For this attack to be efficient attacker would have to
+# effectively slow down the operation by several *orders* of magnitute,
+# by ratio of time slice to duration of handful of AES rounds, which
+# unlikely to remain unnoticed. Not to mention that this also means
+# that he would spend correspondigly more time to collect enough
+# statistical data to mount the attack. It's probably appropriate to
+# say that if adeversary reckons that this attack is beneficial and
+# risks to be noticed, you probably have larger problems having him
+# mere opportunity. In other words suggested code design expects you
+# to preclude/mitigate this attack by overall system security design.
+# 2. Attacker manages to make his code interrupt driven. In order for
+# this kind of attack to be feasible, interrupt rate has to be high
+# enough, again comparable to duration of handful of AES rounds. But
+# is there interrupt source of such rate? Hardly, not even 1Gbps NIC
+# generates interrupts at such raging rate...
+#
+# And now back to the former, hyper-threading CPU or more specifically
+# Intel P4. Recall that asynchronous attack implies that malicious
+# code instruments itself. And naturally instrumentation granularity
+# has be noticeably lower than duration of codepath accessing S-box.
+# Given that all cache-lines are accessed during that time that is.
+# Current implementation accesses *all* cache-lines within ~50 cycles
+# window, which is actually *less* than RDTSC latency on Intel P4!
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"aes-586.pl",$x86only = $ARGV[$#ARGV] eq "386");
+&static_label("AES_Te");
+&static_label("AES_Td");
+
+$s0="eax";
+$s1="ebx";
+$s2="ecx";
+$s3="edx";
+$key="edi";
+$acc="esi";
+$tbl="ebp";
+
+# stack frame layout in _[x86|sse]_AES_* routines, frame is allocated
+# by caller
+$__ra=&DWP(0,"esp");	# return address
+$__s0=&DWP(4,"esp");	# s0 backing store
+$__s1=&DWP(8,"esp");	# s1 backing store
+$__s2=&DWP(12,"esp");	# s2 backing store
+$__s3=&DWP(16,"esp");	# s3 backing store
+$__key=&DWP(20,"esp");	# pointer to key schedule
+$__end=&DWP(24,"esp");	# pointer to end of key schedule
+$__tbl=&DWP(28,"esp");	# %ebp backing store
+
+# stack frame layout in AES_[en|crypt] routines, which differs from
+# above by 4 and overlaps by %ebp backing store
+$_tbl=&DWP(24,"esp");
+$_esp=&DWP(28,"esp");
+
+sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
+
+$speed_limit=512;	# chunks smaller than $speed_limit are
+			# processed with compact routine in CBC mode
+$small_footprint=1;	# $small_footprint=1 code is ~5% slower [on
+			# recent µ-archs], but ~5 times smaller!
+			# I favor compact code to minimize cache
+			# contention and in hope to "collect" 5% back
+			# in real-life applications...
+
+$vertical_spin=0;	# shift "verticaly" defaults to 0, because of
+			# its proof-of-concept status...
+# Note that there is no decvert(), as well as last encryption round is
+# performed with "horizontal" shifts. This is because this "vertical"
+# implementation [one which groups shifts on a given $s[i] to form a
+# "column," unlike "horizontal" one, which groups shifts on different
+# $s[i] to form a "row"] is work in progress. It was observed to run
+# few percents faster on Intel cores, but not AMD. On AMD K8 core it's
+# whole 12% slower:-( So we face a trade-off... Shall it be resolved
+# some day? Till then the code is considered experimental and by
+# default remains dormant...
+
+sub encvert()
+{ my ($te,@s) = @_;
+  my $v0 = $acc, $v1 = $key;
+
+	&mov	($v0,$s[3]);				# copy s3
+	&mov	(&DWP(4,"esp"),$s[2]);			# save s2
+	&mov	($v1,$s[0]);				# copy s0
+	&mov	(&DWP(8,"esp"),$s[1]);			# save s1
+
+	&movz	($s[2],&HB($s[0]));
+	&and	($s[0],0xFF);
+	&mov	($s[0],&DWP(0,$te,$s[0],8));		# s0>>0
+	&shr	($v1,16);
+	&mov	($s[3],&DWP(3,$te,$s[2],8));		# s0>>8
+	&movz	($s[1],&HB($v1));
+	&and	($v1,0xFF);
+	&mov	($s[2],&DWP(2,$te,$v1,8));		# s0>>16
+	 &mov	($v1,$v0);
+	&mov	($s[1],&DWP(1,$te,$s[1],8));		# s0>>24
+
+	&and	($v0,0xFF);
+	&xor	($s[3],&DWP(0,$te,$v0,8));		# s3>>0
+	&movz	($v0,&HB($v1));
+	&shr	($v1,16);
+	&xor	($s[2],&DWP(3,$te,$v0,8));		# s3>>8
+	&movz	($v0,&HB($v1));
+	&and	($v1,0xFF);
+	&xor	($s[1],&DWP(2,$te,$v1,8));		# s3>>16
+	 &mov	($v1,&DWP(4,"esp"));			# restore s2
+	&xor	($s[0],&DWP(1,$te,$v0,8));		# s3>>24
+
+	&mov	($v0,$v1);
+	&and	($v1,0xFF);
+	&xor	($s[2],&DWP(0,$te,$v1,8));		# s2>>0
+	&movz	($v1,&HB($v0));
+	&shr	($v0,16);
+	&xor	($s[1],&DWP(3,$te,$v1,8));		# s2>>8
+	&movz	($v1,&HB($v0));
+	&and	($v0,0xFF);
+	&xor	($s[0],&DWP(2,$te,$v0,8));		# s2>>16
+	 &mov	($v0,&DWP(8,"esp"));			# restore s1
+	&xor	($s[3],&DWP(1,$te,$v1,8));		# s2>>24
+
+	&mov	($v1,$v0);
+	&and	($v0,0xFF);
+	&xor	($s[1],&DWP(0,$te,$v0,8));		# s1>>0
+	&movz	($v0,&HB($v1));
+	&shr	($v1,16);
+	&xor	($s[0],&DWP(3,$te,$v0,8));		# s1>>8
+	&movz	($v0,&HB($v1));
+	&and	($v1,0xFF);
+	&xor	($s[3],&DWP(2,$te,$v1,8));		# s1>>16
+	 &mov	($key,$__key);				# reincarnate v1 as key
+	&xor	($s[2],&DWP(1,$te,$v0,8));		# s1>>24
+}
+
+# Another experimental routine, which features "horizontal spin," but
+# eliminates one reference to stack. Strangely enough runs slower...
+sub enchoriz()
+{ my $v0 = $key, $v1 = $acc;
+
+	&movz	($v0,&LB($s0));			#  3, 2, 1, 0*
+	&rotr	($s2,8);			#  8,11,10, 9
+	&mov	($v1,&DWP(0,$te,$v0,8));	#  0
+	&movz	($v0,&HB($s1));			#  7, 6, 5*, 4
+	&rotr	($s3,16);			# 13,12,15,14
+	&xor	($v1,&DWP(3,$te,$v0,8));	#  5
+	&movz	($v0,&HB($s2));			#  8,11,10*, 9
+	&rotr	($s0,16);			#  1, 0, 3, 2
+	&xor	($v1,&DWP(2,$te,$v0,8));	# 10
+	&movz	($v0,&HB($s3));			# 13,12,15*,14
+	&xor	($v1,&DWP(1,$te,$v0,8));	# 15, t[0] collected
+	&mov	($__s0,$v1);			# t[0] saved
+
+	&movz	($v0,&LB($s1));			#  7, 6, 5, 4*
+	&shr	($s1,16);			#  -, -, 7, 6
+	&mov	($v1,&DWP(0,$te,$v0,8));	#  4
+	&movz	($v0,&LB($s3));			# 13,12,15,14*
+	&xor	($v1,&DWP(2,$te,$v0,8));	# 14
+	&movz	($v0,&HB($s0));			#  1, 0, 3*, 2
+	&and	($s3,0xffff0000);		# 13,12, -, -
+	&xor	($v1,&DWP(1,$te,$v0,8));	#  3
+	&movz	($v0,&LB($s2));			#  8,11,10, 9*
+	&or	($s3,$s1);			# 13,12, 7, 6
+	&xor	($v1,&DWP(3,$te,$v0,8));	#  9, t[1] collected
+	&mov	($s1,$v1);			#  s[1]=t[1]
+
+	&movz	($v0,&LB($s0));			#  1, 0, 3, 2*
+	&shr	($s2,16);			#  -, -, 8,11
+	&mov	($v1,&DWP(2,$te,$v0,8));	#  2
+	&movz	($v0,&HB($s3));			# 13,12, 7*, 6
+	&xor	($v1,&DWP(1,$te,$v0,8));	#  7
+	&movz	($v0,&HB($s2));			#  -, -, 8*,11
+	&xor	($v1,&DWP(0,$te,$v0,8));	#  8
+	&mov	($v0,$s3);
+	&shr	($v0,24);			# 13
+	&xor	($v1,&DWP(3,$te,$v0,8));	# 13, t[2] collected
+
+	&movz	($v0,&LB($s2));			#  -, -, 8,11*
+	&shr	($s0,24);			#  1*
+	&mov	($s2,&DWP(1,$te,$v0,8));	# 11
+	&xor	($s2,&DWP(3,$te,$s0,8));	#  1
+	&mov	($s0,$__s0);			# s[0]=t[0]
+	&movz	($v0,&LB($s3));			# 13,12, 7, 6*
+	&shr	($s3,16);			#   ,  ,13,12
+	&xor	($s2,&DWP(2,$te,$v0,8));	#  6
+	&mov	($key,$__key);			# reincarnate v0 as key
+	&and	($s3,0xff);			#   ,  ,13,12*
+	&mov	($s3,&DWP(0,$te,$s3,8));	# 12
+	&xor	($s3,$s2);			# s[2]=t[3] collected
+	&mov	($s2,$v1);			# s[2]=t[2]
+}
+
+# More experimental code... SSE one... Even though this one eliminates
+# *all* references to stack, it's not faster...
+sub sse_encbody()
+{
+	&movz	($acc,&LB("eax"));		#  0
+	&mov	("ecx",&DWP(0,$tbl,$acc,8));	#  0
+	&pshufw	("mm2","mm0",0x0d);		#  7, 6, 3, 2
+	&movz	("edx",&HB("eax"));		#  1
+	&mov	("edx",&DWP(3,$tbl,"edx",8));	#  1
+	&shr	("eax",16);			#  5, 4
+
+	&movz	($acc,&LB("ebx"));		# 10
+	&xor	("ecx",&DWP(2,$tbl,$acc,8));	# 10
+	&pshufw	("mm6","mm4",0x08);		# 13,12, 9, 8
+	&movz	($acc,&HB("ebx"));		# 11
+	&xor	("edx",&DWP(1,$tbl,$acc,8));	# 11
+	&shr	("ebx",16);			# 15,14
+
+	&movz	($acc,&HB("eax"));		#  5
+	&xor	("ecx",&DWP(3,$tbl,$acc,8));	#  5
+	&movq	("mm3",QWP(16,$key));
+	&movz	($acc,&HB("ebx"));		# 15
+	&xor	("ecx",&DWP(1,$tbl,$acc,8));	# 15
+	&movd	("mm0","ecx");			# t[0] collected
+
+	&movz	($acc,&LB("eax"));		#  4
+	&mov	("ecx",&DWP(0,$tbl,$acc,8));	#  4
+	&movd	("eax","mm2");			#  7, 6, 3, 2
+	&movz	($acc,&LB("ebx"));		# 14
+	&xor	("ecx",&DWP(2,$tbl,$acc,8));	# 14
+	&movd	("ebx","mm6");			# 13,12, 9, 8
+
+	&movz	($acc,&HB("eax"));		#  3
+	&xor	("ecx",&DWP(1,$tbl,$acc,8));	#  3
+	&movz	($acc,&HB("ebx"));		#  9
+	&xor	("ecx",&DWP(3,$tbl,$acc,8));	#  9
+	&movd	("mm1","ecx");			# t[1] collected
+
+	&movz	($acc,&LB("eax"));		#  2
+	&mov	("ecx",&DWP(2,$tbl,$acc,8));	#  2
+	&shr	("eax",16);			#  7, 6
+	&punpckldq	("mm0","mm1");		# t[0,1] collected
+	&movz	($acc,&LB("ebx"));		#  8
+	&xor	("ecx",&DWP(0,$tbl,$acc,8));	#  8
+	&shr	("ebx",16);			# 13,12
+
+	&movz	($acc,&HB("eax"));		#  7
+	&xor	("ecx",&DWP(1,$tbl,$acc,8));	#  7
+	&pxor	("mm0","mm3");
+	&movz	("eax",&LB("eax"));		#  6
+	&xor	("edx",&DWP(2,$tbl,"eax",8));	#  6
+	&pshufw	("mm1","mm0",0x08);		#  5, 4, 1, 0
+	&movz	($acc,&HB("ebx"));		# 13
+	&xor	("ecx",&DWP(3,$tbl,$acc,8));	# 13
+	&xor	("ecx",&DWP(24,$key));		# t[2]
+	&movd	("mm4","ecx");			# t[2] collected
+	&movz	("ebx",&LB("ebx"));		# 12
+	&xor	("edx",&DWP(0,$tbl,"ebx",8));	# 12
+	&shr	("ecx",16);
+	&movd	("eax","mm1");			#  5, 4, 1, 0
+	&mov	("ebx",&DWP(28,$key));		# t[3]
+	&xor	("ebx","edx");
+	&movd	("mm5","ebx");			# t[3] collected
+	&and	("ebx",0xffff0000);
+	&or	("ebx","ecx");
+
+	&punpckldq	("mm4","mm5");		# t[2,3] collected
+}
+
+######################################################################
+# "Compact" block function
+######################################################################
+
+sub enccompact()
+{ my $Fn = mov;
+  while ($#_>5) { pop(@_); $Fn=sub{}; }
+  my ($i,$te,@s)=@_;
+  my $tmp = $key;
+  my $out = $i==3?$s[0]:$acc;
+
+	# $Fn is used in first compact round and its purpose is to
+	# void restoration of some values from stack, so that after
+	# 4xenccompact with extra argument $key value is left there...
+	if ($i==3)  {	&$Fn	($key,$__key);			}##%edx
+	else        {	&mov	($out,$s[0]);			}
+			&and	($out,0xFF);
+	if ($i==1)  {	&shr	($s[0],16);			}#%ebx[1]
+	if ($i==2)  {	&shr	($s[0],24);			}#%ecx[2]
+			&movz	($out,&BP(-128,$te,$out,1));
+
+	if ($i==3)  {	$tmp=$s[1];				}##%eax
+			&movz	($tmp,&HB($s[1]));
+			&movz	($tmp,&BP(-128,$te,$tmp,1));
+			&shl	($tmp,8);
+			&xor	($out,$tmp);
+
+	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$__s0);		}##%ebx
+	else        {	&mov	($tmp,$s[2]);
+			&shr	($tmp,16);			}
+	if ($i==2)  {	&and	($s[1],0xFF);			}#%edx[2]
+			&and	($tmp,0xFF);
+			&movz	($tmp,&BP(-128,$te,$tmp,1));
+			&shl	($tmp,16);
+			&xor	($out,$tmp);
+
+	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}##%ecx
+	elsif($i==2){	&movz	($tmp,&HB($s[3]));		}#%ebx[2]
+	else        {	&mov	($tmp,$s[3]);
+			&shr	($tmp,24);			}
+			&movz	($tmp,&BP(-128,$te,$tmp,1));
+			&shl	($tmp,24);
+			&xor	($out,$tmp);
+	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
+	if ($i==3)  {	&mov	($s[3],$acc);			}
+	&comment();
+}
+
+sub enctransform()
+{ my @s = ($s0,$s1,$s2,$s3);
+  my $i = shift;
+  my $tmp = $tbl;
+  my $r2  = $key ;
+
+	&mov	($acc,$s[$i]);
+	&and	($acc,0x80808080);
+	&mov	($tmp,$acc);
+	&shr	($tmp,7);
+	&lea	($r2,&DWP(0,$s[$i],$s[$i]));
+	&sub	($acc,$tmp);
+	&and	($r2,0xfefefefe);
+	&and	($acc,0x1b1b1b1b);
+	&mov	($tmp,$s[$i]);
+	&xor	($acc,$r2);	# r2
+
+	&xor	($s[$i],$acc);	# r0 ^ r2
+	&rotl	($s[$i],24);
+	&xor	($s[$i],$acc)	# ROTATE(r2^r0,24) ^ r2
+	&rotr	($tmp,16);
+	&xor	($s[$i],$tmp);
+	&rotr	($tmp,8);
+	&xor	($s[$i],$tmp);
+}
+
+&function_begin_B("_x86_AES_encrypt_compact");
+	# note that caller is expected to allocate stack frame for me!
+	&mov	($__key,$key);			# save key
+
+	&xor	($s0,&DWP(0,$key));		# xor with key
+	&xor	($s1,&DWP(4,$key));
+	&xor	($s2,&DWP(8,$key));
+	&xor	($s3,&DWP(12,$key));
+
+	&mov	($acc,&DWP(240,$key));		# load key->rounds
+	&lea	($acc,&DWP(-2,$acc,$acc));
+	&lea	($acc,&DWP(0,$key,$acc,8));
+	&mov	($__end,$acc);			# end of key schedule
+
+	# prefetch Te4
+	&mov	($key,&DWP(0-128,$tbl));
+	&mov	($acc,&DWP(32-128,$tbl));
+	&mov	($key,&DWP(64-128,$tbl));
+	&mov	($acc,&DWP(96-128,$tbl));
+	&mov	($key,&DWP(128-128,$tbl));
+	&mov	($acc,&DWP(160-128,$tbl));
+	&mov	($key,&DWP(192-128,$tbl));
+	&mov	($acc,&DWP(224-128,$tbl));
+
+	&set_label("loop",16);
+
+		&enccompact(0,$tbl,$s0,$s1,$s2,$s3,1);
+		&enccompact(1,$tbl,$s1,$s2,$s3,$s0,1);
+		&enccompact(2,$tbl,$s2,$s3,$s0,$s1,1);
+		&enccompact(3,$tbl,$s3,$s0,$s1,$s2,1);
+		&enctransform(2);
+		&enctransform(3);
+		&enctransform(0);
+		&enctransform(1);
+		&mov 	($key,$__key);
+		&mov	($tbl,$__tbl);
+		&add	($key,16);		# advance rd_key
+		&xor	($s0,&DWP(0,$key));
+		&xor	($s1,&DWP(4,$key));
+		&xor	($s2,&DWP(8,$key));
+		&xor	($s3,&DWP(12,$key));
+
+	&cmp	($key,$__end);
+	&mov	($__key,$key);
+	&jb	(&label("loop"));
+
+	&enccompact(0,$tbl,$s0,$s1,$s2,$s3);
+	&enccompact(1,$tbl,$s1,$s2,$s3,$s0);
+	&enccompact(2,$tbl,$s2,$s3,$s0,$s1);
+	&enccompact(3,$tbl,$s3,$s0,$s1,$s2);
+
+	&xor	($s0,&DWP(16,$key));
+	&xor	($s1,&DWP(20,$key));
+	&xor	($s2,&DWP(24,$key));
+	&xor	($s3,&DWP(28,$key));
+
+	&ret	();
+&function_end_B("_x86_AES_encrypt_compact");
+
+######################################################################
+# "Compact" SSE block function.
+######################################################################
+#
+# Performance is not actually extraordinary in comparison to pure
+# x86 code. In particular encrypt performance is virtually the same.
+# Decrypt performance on the other hand is 15-20% better on newer
+# µ-archs [but we're thankful for *any* improvement here], and ~50%
+# better on PIII:-) And additionally on the pros side this code
+# eliminates redundant references to stack and thus relieves/
+# minimizes the pressure on the memory bus.
+#
+# MMX register layout                           lsb
+# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+# |          mm4          |          mm0          |
+# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+# |     s3    |     s2    |     s1    |     s0    |    
+# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+# |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+#
+# Indexes translate as s[N/4]>>(8*(N%4)), e.g. 5 means s1>>8.
+# In this terms encryption and decryption "compact" permutation
+# matrices can be depicted as following:
+#
+# encryption              lsb	# decryption              lsb
+# +----++----+----+----+----+	# +----++----+----+----+----+
+# | t0 || 15 | 10 |  5 |  0 |	# | t0 ||  7 | 10 | 13 |  0 |
+# +----++----+----+----+----+	# +----++----+----+----+----+
+# | t1 ||  3 | 14 |  9 |  4 |	# | t1 || 11 | 14 |  1 |  4 |
+# +----++----+----+----+----+	# +----++----+----+----+----+
+# | t2 ||  7 |  2 | 13 |  8 |	# | t2 || 15 |  2 |  5 |  8 |
+# +----++----+----+----+----+	# +----++----+----+----+----+
+# | t3 || 11 |  6 |  1 | 12 |	# | t3 ||  3 |  6 |  9 | 12 |
+# +----++----+----+----+----+	# +----++----+----+----+----+
+#
+######################################################################
+# Why not xmm registers? Short answer. It was actually tested and
+# was not any faster, but *contrary*, most notably on Intel CPUs.
+# Longer answer. Main advantage of using mm registers is that movd
+# latency is lower, especially on Intel P4. While arithmetic
+# instructions are twice as many, they can be scheduled every cycle
+# and not every second one when they are operating on xmm register,
+# so that "arithmetic throughput" remains virtually the same. And
+# finally the code can be executed even on elder SSE-only CPUs:-)
+
+sub sse_enccompact()
+{
+	&pshufw	("mm1","mm0",0x08);		#  5, 4, 1, 0
+	&pshufw	("mm5","mm4",0x0d);		# 15,14,11,10
+	&movd	("eax","mm1");			#  5, 4, 1, 0
+	&movd	("ebx","mm5");			# 15,14,11,10
+
+	&movz	($acc,&LB("eax"));		#  0
+	&movz	("ecx",&BP(-128,$tbl,$acc,1));	#  0
+	&pshufw	("mm2","mm0",0x0d);		#  7, 6, 3, 2
+	&movz	("edx",&HB("eax"));		#  1
+	&movz	("edx",&BP(-128,$tbl,"edx",1));	#  1
+	&shl	("edx",8);			#  1
+	&shr	("eax",16);			#  5, 4
+
+	&movz	($acc,&LB("ebx"));		# 10
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 10
+	&shl	($acc,16);			# 10
+	&or	("ecx",$acc);			# 10
+	&pshufw	("mm6","mm4",0x08);		# 13,12, 9, 8
+	&movz	($acc,&HB("ebx"));		# 11
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 11
+	&shl	($acc,24);			# 11
+	&or	("edx",$acc);			# 11
+	&shr	("ebx",16);			# 15,14
+
+	&movz	($acc,&HB("eax"));		#  5
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  5
+	&shl	($acc,8);			#  5
+	&or	("ecx",$acc);			#  5
+	&movz	($acc,&HB("ebx"));		# 15
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 15
+	&shl	($acc,24);			# 15
+	&or	("ecx",$acc);			# 15
+	&movd	("mm0","ecx");			# t[0] collected
+
+	&movz	($acc,&LB("eax"));		#  4
+	&movz	("ecx",&BP(-128,$tbl,$acc,1));	#  4
+	&movd	("eax","mm2");			#  7, 6, 3, 2
+	&movz	($acc,&LB("ebx"));		# 14
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 14
+	&shl	($acc,16);			# 14
+	&or	("ecx",$acc);			# 14
+
+	&movd	("ebx","mm6");			# 13,12, 9, 8
+	&movz	($acc,&HB("eax"));		#  3
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  3
+	&shl	($acc,24);			#  3
+	&or	("ecx",$acc);			#  3
+	&movz	($acc,&HB("ebx"));		#  9
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  9
+	&shl	($acc,8);			#  9
+	&or	("ecx",$acc);			#  9
+	&movd	("mm1","ecx");			# t[1] collected
+
+	&movz	($acc,&LB("ebx"));		#  8
+	&movz	("ecx",&BP(-128,$tbl,$acc,1));	#  8
+	&shr	("ebx",16);			# 13,12
+	&movz	($acc,&LB("eax"));		#  2
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  2
+	&shl	($acc,16);			#  2
+	&or	("ecx",$acc);			#  2
+	&shr	("eax",16);			#  7, 6
+
+	&punpckldq	("mm0","mm1");		# t[0,1] collected
+
+	&movz	($acc,&HB("eax"));		#  7
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  7
+	&shl	($acc,24);			#  7
+	&or	("ecx",$acc);			#  7
+	&and	("eax",0xff);			#  6
+	&movz	("eax",&BP(-128,$tbl,"eax",1));	#  6
+	&shl	("eax",16);			#  6
+	&or	("edx","eax");			#  6
+	&movz	($acc,&HB("ebx"));		# 13
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 13
+	&shl	($acc,8);			# 13
+	&or	("ecx",$acc);			# 13
+	&movd	("mm4","ecx");			# t[2] collected
+	&and	("ebx",0xff);			# 12
+	&movz	("ebx",&BP(-128,$tbl,"ebx",1));	# 12
+	&or	("edx","ebx");			# 12
+	&movd	("mm5","edx");			# t[3] collected
+
+	&punpckldq	("mm4","mm5");		# t[2,3] collected
+}
+
+					if (!$x86only) {
+&function_begin_B("_sse_AES_encrypt_compact");
+	&pxor	("mm0",&QWP(0,$key));	#  7, 6, 5, 4, 3, 2, 1, 0
+	&pxor	("mm4",&QWP(8,$key));	# 15,14,13,12,11,10, 9, 8
+
+	# note that caller is expected to allocate stack frame for me!
+	&mov	($acc,&DWP(240,$key));		# load key->rounds
+	&lea	($acc,&DWP(-2,$acc,$acc));
+	&lea	($acc,&DWP(0,$key,$acc,8));
+	&mov	($__end,$acc);			# end of key schedule
+
+	&mov	($s0,0x1b1b1b1b);		# magic constant
+	&mov	(&DWP(8,"esp"),$s0);
+	&mov	(&DWP(12,"esp"),$s0);
+
+	# prefetch Te4
+	&mov	($s0,&DWP(0-128,$tbl));
+	&mov	($s1,&DWP(32-128,$tbl));
+	&mov	($s2,&DWP(64-128,$tbl));
+	&mov	($s3,&DWP(96-128,$tbl));
+	&mov	($s0,&DWP(128-128,$tbl));
+	&mov	($s1,&DWP(160-128,$tbl));
+	&mov	($s2,&DWP(192-128,$tbl));
+	&mov	($s3,&DWP(224-128,$tbl));
+
+	&set_label("loop",16);
+		&sse_enccompact();
+		&add	($key,16);
+		&cmp	($key,$__end);
+		&ja	(&label("out"));
+
+		&movq	("mm2",&QWP(8,"esp"));
+		&pxor	("mm3","mm3");		&pxor	("mm7","mm7");
+		&movq	("mm1","mm0");		&movq	("mm5","mm4");	# r0
+		&pcmpgtb("mm3","mm0");		&pcmpgtb("mm7","mm4");
+		&pand	("mm3","mm2");		&pand	("mm7","mm2");
+		&pshufw	("mm2","mm0",0xb1);	&pshufw	("mm6","mm4",0xb1);# ROTATE(r0,16)
+		&paddb	("mm0","mm0");		&paddb	("mm4","mm4");
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# = r2
+		&pshufw	("mm3","mm2",0xb1);	&pshufw	("mm7","mm6",0xb1);# r0
+		&pxor	("mm1","mm0");		&pxor	("mm5","mm4");	# r0^r2
+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= ROTATE(r0,16)
+
+		&movq	("mm2","mm3");		&movq	("mm6","mm7");
+		&pslld	("mm3",8);		&pslld	("mm7",8);
+		&psrld	("mm2",24);		&psrld	("mm6",24);
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= r0<<8
+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= r0>>24
+
+		&movq	("mm3","mm1");		&movq	("mm7","mm5");
+		&movq	("mm2",&QWP(0,$key));	&movq	("mm6",&QWP(8,$key));
+		&psrld	("mm1",8);		&psrld	("mm5",8);
+		&mov	($s0,&DWP(0-128,$tbl));
+		&pslld	("mm3",24);		&pslld	("mm7",24);
+		&mov	($s1,&DWP(64-128,$tbl));
+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= (r2^r0)<<8
+		&mov	($s2,&DWP(128-128,$tbl));
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= (r2^r0)>>24
+		&mov	($s3,&DWP(192-128,$tbl));
+
+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");
+	&jmp	(&label("loop"));
+
+	&set_label("out",16);
+	&pxor	("mm0",&QWP(0,$key));
+	&pxor	("mm4",&QWP(8,$key));
+
+	&ret	();
+&function_end_B("_sse_AES_encrypt_compact");
+					}
+
+######################################################################
+# Vanilla block function.
+######################################################################
+
+sub encstep()
+{ my ($i,$te,@s) = @_;
+  my $tmp = $key;
+  my $out = $i==3?$s[0]:$acc;
+
+	# lines marked with #%e?x[i] denote "reordered" instructions...
+	if ($i==3)  {	&mov	($key,$__key);			}##%edx
+	else        {	&mov	($out,$s[0]);
+			&and	($out,0xFF);			}
+	if ($i==1)  {	&shr	($s[0],16);			}#%ebx[1]
+	if ($i==2)  {	&shr	($s[0],24);			}#%ecx[2]
+			&mov	($out,&DWP(0,$te,$out,8));
+
+	if ($i==3)  {	$tmp=$s[1];				}##%eax
+			&movz	($tmp,&HB($s[1]));
+			&xor	($out,&DWP(3,$te,$tmp,8));
+
+	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$__s0);		}##%ebx
+	else        {	&mov	($tmp,$s[2]);
+			&shr	($tmp,16);			}
+	if ($i==2)  {	&and	($s[1],0xFF);			}#%edx[2]
+			&and	($tmp,0xFF);
+			&xor	($out,&DWP(2,$te,$tmp,8));
+
+	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}##%ecx
+	elsif($i==2){	&movz	($tmp,&HB($s[3]));		}#%ebx[2]
+	else        {	&mov	($tmp,$s[3]); 
+			&shr	($tmp,24)			}
+			&xor	($out,&DWP(1,$te,$tmp,8));
+	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
+	if ($i==3)  {	&mov	($s[3],$acc);			}
+			&comment();
+}
+
+sub enclast()
+{ my ($i,$te,@s)=@_;
+  my $tmp = $key;
+  my $out = $i==3?$s[0]:$acc;
+
+	if ($i==3)  {	&mov	($key,$__key);			}##%edx
+	else        {	&mov	($out,$s[0]);			}
+			&and	($out,0xFF);
+	if ($i==1)  {	&shr	($s[0],16);			}#%ebx[1]
+	if ($i==2)  {	&shr	($s[0],24);			}#%ecx[2]
+			&mov	($out,&DWP(2,$te,$out,8));
+			&and	($out,0x000000ff);
+
+	if ($i==3)  {	$tmp=$s[1];				}##%eax
+			&movz	($tmp,&HB($s[1]));
+			&mov	($tmp,&DWP(0,$te,$tmp,8));
+			&and	($tmp,0x0000ff00);
+			&xor	($out,$tmp);
+
+	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$__s0);		}##%ebx
+	else        {	&mov	($tmp,$s[2]);
+			&shr	($tmp,16);			}
+	if ($i==2)  {	&and	($s[1],0xFF);			}#%edx[2]
+			&and	($tmp,0xFF);
+			&mov	($tmp,&DWP(0,$te,$tmp,8));
+			&and	($tmp,0x00ff0000);
+			&xor	($out,$tmp);
+
+	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}##%ecx
+	elsif($i==2){	&movz	($tmp,&HB($s[3]));		}#%ebx[2]
+	else        {	&mov	($tmp,$s[3]);
+			&shr	($tmp,24);			}
+			&mov	($tmp,&DWP(2,$te,$tmp,8));
+			&and	($tmp,0xff000000);
+			&xor	($out,$tmp);
+	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
+	if ($i==3)  {	&mov	($s[3],$acc);			}
+}
+
+&function_begin_B("_x86_AES_encrypt");
+	if ($vertical_spin) {
+		# I need high parts of volatile registers to be accessible...
+		&exch	($s1="edi",$key="ebx");
+		&mov	($s2="esi",$acc="ecx");
+	}
+
+	# note that caller is expected to allocate stack frame for me!
+	&mov	($__key,$key);			# save key
+
+	&xor	($s0,&DWP(0,$key));		# xor with key
+	&xor	($s1,&DWP(4,$key));
+	&xor	($s2,&DWP(8,$key));
+	&xor	($s3,&DWP(12,$key));
+
+	&mov	($acc,&DWP(240,$key));		# load key->rounds
+
+	if ($small_footprint) {
+	    &lea	($acc,&DWP(-2,$acc,$acc));
+	    &lea	($acc,&DWP(0,$key,$acc,8));
+	    &mov	($__end,$acc);		# end of key schedule
+
+	    &set_label("loop",16);
+		if ($vertical_spin) {
+		    &encvert($tbl,$s0,$s1,$s2,$s3);
+		} else {
+		    &encstep(0,$tbl,$s0,$s1,$s2,$s3);
+		    &encstep(1,$tbl,$s1,$s2,$s3,$s0);
+		    &encstep(2,$tbl,$s2,$s3,$s0,$s1);
+		    &encstep(3,$tbl,$s3,$s0,$s1,$s2);
+		}
+		&add	($key,16);		# advance rd_key
+		&xor	($s0,&DWP(0,$key));
+		&xor	($s1,&DWP(4,$key));
+		&xor	($s2,&DWP(8,$key));
+		&xor	($s3,&DWP(12,$key));
+	    &cmp	($key,$__end);
+	    &mov	($__key,$key);
+	    &jb		(&label("loop"));
+	}
+	else {
+	    &cmp	($acc,10);
+	    &jle	(&label("10rounds"));
+	    &cmp	($acc,12);
+	    &jle	(&label("12rounds"));
+
+	&set_label("14rounds",4);
+	    for ($i=1;$i<3;$i++) {
+		if ($vertical_spin) {
+		    &encvert($tbl,$s0,$s1,$s2,$s3);
+		} else {
+		    &encstep(0,$tbl,$s0,$s1,$s2,$s3);
+		    &encstep(1,$tbl,$s1,$s2,$s3,$s0);
+		    &encstep(2,$tbl,$s2,$s3,$s0,$s1);
+		    &encstep(3,$tbl,$s3,$s0,$s1,$s2);
+		}
+		&xor	($s0,&DWP(16*$i+0,$key));
+		&xor	($s1,&DWP(16*$i+4,$key));
+		&xor	($s2,&DWP(16*$i+8,$key));
+		&xor	($s3,&DWP(16*$i+12,$key));
+	    }
+	    &add	($key,32);
+	    &mov	($__key,$key);		# advance rd_key
+	&set_label("12rounds",4);
+	    for ($i=1;$i<3;$i++) {
+		if ($vertical_spin) {
+		    &encvert($tbl,$s0,$s1,$s2,$s3);
+		} else {
+		    &encstep(0,$tbl,$s0,$s1,$s2,$s3);
+		    &encstep(1,$tbl,$s1,$s2,$s3,$s0);
+		    &encstep(2,$tbl,$s2,$s3,$s0,$s1);
+		    &encstep(3,$tbl,$s3,$s0,$s1,$s2);
+		}
+		&xor	($s0,&DWP(16*$i+0,$key));
+		&xor	($s1,&DWP(16*$i+4,$key));
+		&xor	($s2,&DWP(16*$i+8,$key));
+		&xor	($s3,&DWP(16*$i+12,$key));
+	    }
+	    &add	($key,32);
+	    &mov	($__key,$key);		# advance rd_key
+	&set_label("10rounds",4);
+	    for ($i=1;$i<10;$i++) {
+		if ($vertical_spin) {
+		    &encvert($tbl,$s0,$s1,$s2,$s3);
+		} else {
+		    &encstep(0,$tbl,$s0,$s1,$s2,$s3);
+		    &encstep(1,$tbl,$s1,$s2,$s3,$s0);
+		    &encstep(2,$tbl,$s2,$s3,$s0,$s1);
+		    &encstep(3,$tbl,$s3,$s0,$s1,$s2);
+		}
+		&xor	($s0,&DWP(16*$i+0,$key));
+		&xor	($s1,&DWP(16*$i+4,$key));
+		&xor	($s2,&DWP(16*$i+8,$key));
+		&xor	($s3,&DWP(16*$i+12,$key));
+	    }
+	}
+
+	if ($vertical_spin) {
+	    # "reincarnate" some registers for "horizontal" spin...
+	    &mov	($s1="ebx",$key="edi");
+	    &mov	($s2="ecx",$acc="esi");
+	}
+	&enclast(0,$tbl,$s0,$s1,$s2,$s3);
+	&enclast(1,$tbl,$s1,$s2,$s3,$s0);
+	&enclast(2,$tbl,$s2,$s3,$s0,$s1);
+	&enclast(3,$tbl,$s3,$s0,$s1,$s2);
+
+	&add	($key,$small_footprint?16:160);
+	&xor	($s0,&DWP(0,$key));
+	&xor	($s1,&DWP(4,$key));
+	&xor	($s2,&DWP(8,$key));
+	&xor	($s3,&DWP(12,$key));
+
+	&ret	();
+
+&set_label("AES_Te",64);	# Yes! I keep it in the code segment!
+	&_data_word(0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6);
+	&_data_word(0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591);
+	&_data_word(0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56);
+	&_data_word(0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec);
+	&_data_word(0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa);
+	&_data_word(0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb);
+	&_data_word(0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45);
+	&_data_word(0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b);
+	&_data_word(0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c);
+	&_data_word(0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83);
+	&_data_word(0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9);
+	&_data_word(0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a);
+	&_data_word(0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d);
+	&_data_word(0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f);
+	&_data_word(0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df);
+	&_data_word(0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea);
+	&_data_word(0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34);
+	&_data_word(0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b);
+	&_data_word(0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d);
+	&_data_word(0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413);
+	&_data_word(0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1);
+	&_data_word(0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6);
+	&_data_word(0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972);
+	&_data_word(0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85);
+	&_data_word(0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed);
+	&_data_word(0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511);
+	&_data_word(0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe);
+	&_data_word(0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b);
+	&_data_word(0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05);
+	&_data_word(0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1);
+	&_data_word(0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142);
+	&_data_word(0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf);
+	&_data_word(0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3);
+	&_data_word(0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e);
+	&_data_word(0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a);
+	&_data_word(0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6);
+	&_data_word(0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3);
+	&_data_word(0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b);
+	&_data_word(0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428);
+	&_data_word(0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad);
+	&_data_word(0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14);
+	&_data_word(0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8);
+	&_data_word(0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4);
+	&_data_word(0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2);
+	&_data_word(0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda);
+	&_data_word(0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949);
+	&_data_word(0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf);
+	&_data_word(0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810);
+	&_data_word(0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c);
+	&_data_word(0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697);
+	&_data_word(0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e);
+	&_data_word(0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f);
+	&_data_word(0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc);
+	&_data_word(0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c);
+	&_data_word(0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969);
+	&_data_word(0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27);
+	&_data_word(0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122);
+	&_data_word(0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433);
+	&_data_word(0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9);
+	&_data_word(0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5);
+	&_data_word(0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a);
+	&_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0);
+	&_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e);
+	&_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c);
+
+#Te4	# four copies of Te4 to choose from to avoid L1 aliasing
+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
+
+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
+
+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
+
+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
+#rcon:
+	&data_word(0x00000001, 0x00000002, 0x00000004, 0x00000008);
+	&data_word(0x00000010, 0x00000020, 0x00000040, 0x00000080);
+	&data_word(0x0000001b, 0x00000036, 0x00000000, 0x00000000);
+	&data_word(0x00000000, 0x00000000, 0x00000000, 0x00000000);
+&function_end_B("_x86_AES_encrypt");
+
+# void AES_encrypt (const void *inp,void *out,const AES_KEY *key);
+&function_begin("AES_encrypt");
+	&mov	($acc,&wparam(0));		# load inp
+	&mov	($key,&wparam(2));		# load key
+
+	&mov	($s0,"esp");
+	&sub	("esp",36);
+	&and	("esp",-64);			# align to cache-line
+
+	# place stack frame just "above" the key schedule
+	&lea	($s1,&DWP(-64-63,$key));
+	&sub	($s1,"esp");
+	&neg	($s1);
+	&and	($s1,0x3C0);	# modulo 1024, but aligned to cache-line
+	&sub	("esp",$s1);
+	&add	("esp",4);	# 4 is reserved for caller's return address
+	&mov	($_esp,$s0);			# save stack pointer
+
+	&call   (&label("pic_point"));          # make it PIC!
+	&set_label("pic_point");
+	&blindpop($tbl);
+	&picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if (!$x86only);
+	&lea    ($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
+
+	# pick Te4 copy which can't "overlap" with stack frame or key schedule
+	&lea	($s1,&DWP(768-4,"esp"));
+	&sub	($s1,$tbl);
+	&and	($s1,0x300);
+	&lea	($tbl,&DWP(2048+128,$tbl,$s1));
+
+					if (!$x86only) {
+	&bt	(&DWP(0,$s0),25);	# check for SSE bit
+	&jnc	(&label("x86"));
+
+	&movq	("mm0",&QWP(0,$acc));
+	&movq	("mm4",&QWP(8,$acc));
+	&call	("_sse_AES_encrypt_compact");
+	&mov	("esp",$_esp);			# restore stack pointer
+	&mov	($acc,&wparam(1));		# load out
+	&movq	(&QWP(0,$acc),"mm0");		# write output data
+	&movq	(&QWP(8,$acc),"mm4");
+	&emms	();
+	&function_end_A();
+					}
+	&set_label("x86",16);
+	&mov	($_tbl,$tbl);
+	&mov	($s0,&DWP(0,$acc));		# load input data
+	&mov	($s1,&DWP(4,$acc));
+	&mov	($s2,&DWP(8,$acc));
+	&mov	($s3,&DWP(12,$acc));
+	&call	("_x86_AES_encrypt_compact");
+	&mov	("esp",$_esp);			# restore stack pointer
+	&mov	($acc,&wparam(1));		# load out
+	&mov	(&DWP(0,$acc),$s0);		# write output data
+	&mov	(&DWP(4,$acc),$s1);
+	&mov	(&DWP(8,$acc),$s2);
+	&mov	(&DWP(12,$acc),$s3);
+&function_end("AES_encrypt");
+
+#--------------------------------------------------------------------#
+
+######################################################################
+# "Compact" block function
+######################################################################
+
+sub deccompact()
+{ my $Fn = mov;
+  while ($#_>5) { pop(@_); $Fn=sub{}; }
+  my ($i,$td,@s)=@_;
+  my $tmp = $key;
+  my $out = $i==3?$s[0]:$acc;
+
+	# $Fn is used in first compact round and its purpose is to
+	# void restoration of some values from stack, so that after
+	# 4xdeccompact with extra argument $key, $s0 and $s1 values
+	# are left there...
+	if($i==3)   {	&$Fn	($key,$__key);			}
+	else        {	&mov	($out,$s[0]);			}
+			&and	($out,0xFF);
+			&movz	($out,&BP(-128,$td,$out,1));
+
+	if ($i==3)  {	$tmp=$s[1];				}
+			&movz	($tmp,&HB($s[1]));
+			&movz	($tmp,&BP(-128,$td,$tmp,1));
+			&shl	($tmp,8);
+			&xor	($out,$tmp);
+
+	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$acc);		}
+	else        {	mov	($tmp,$s[2]);			}
+			&shr	($tmp,16);
+			&and	($tmp,0xFF);
+			&movz	($tmp,&BP(-128,$td,$tmp,1));
+			&shl	($tmp,16);
+			&xor	($out,$tmp);
+
+	if ($i==3)  {	$tmp=$s[3]; &$Fn ($s[2],$__s1);		}
+	else        {	&mov	($tmp,$s[3]);			}
+			&shr	($tmp,24);
+			&movz	($tmp,&BP(-128,$td,$tmp,1));
+			&shl	($tmp,24);
+			&xor	($out,$tmp);
+	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
+	if ($i==3)  {	&$Fn	($s[3],$__s0);			}
+}
+
+# must be called with 2,3,0,1 as argument sequence!!!
+sub dectransform()
+{ my @s = ($s0,$s1,$s2,$s3);
+  my $i = shift;
+  my $tmp = $key;
+  my $tp2 = @s[($i+2)%4]; $tp2 = @s[2] if ($i==1);
+  my $tp4 = @s[($i+3)%4]; $tp4 = @s[3] if ($i==1);
+  my $tp8 = $tbl;
+
+	&mov	($acc,$s[$i]);
+	&and	($acc,0x80808080);
+	&mov	($tmp,$acc);
+	&shr	($tmp,7);
+	&lea	($tp2,&DWP(0,$s[$i],$s[$i]));
+	&sub	($acc,$tmp);
+	&and	($tp2,0xfefefefe);
+	&and	($acc,0x1b1b1b1b);
+	&xor	($acc,$tp2);
+	&mov	($tp2,$acc);
+
+	&and	($acc,0x80808080);
+	&mov	($tmp,$acc);
+	&shr	($tmp,7);
+	&lea	($tp4,&DWP(0,$tp2,$tp2));
+	&sub	($acc,$tmp);
+	&and	($tp4,0xfefefefe);
+	&and	($acc,0x1b1b1b1b);
+	 &xor	($tp2,$s[$i]);	# tp2^tp1
+	&xor	($acc,$tp4);
+	&mov	($tp4,$acc);
+
+	&and	($acc,0x80808080);
+	&mov	($tmp,$acc);
+	&shr	($tmp,7);
+	&lea	($tp8,&DWP(0,$tp4,$tp4));
+	&sub	($acc,$tmp);
+	&and	($tp8,0xfefefefe);
+	&and	($acc,0x1b1b1b1b);
+	 &xor	($tp4,$s[$i]);	# tp4^tp1
+	 &rotl	($s[$i],8);	# = ROTATE(tp1,8)
+	&xor	($tp8,$acc);
+
+	&xor	($s[$i],$tp2);
+	&xor	($tp2,$tp8);
+	&rotl	($tp2,24);
+	&xor	($s[$i],$tp4);
+	&xor	($tp4,$tp8);
+	&rotl	($tp4,16);
+	&xor	($s[$i],$tp8);	# ^= tp8^(tp4^tp1)^(tp2^tp1)
+	&rotl	($tp8,8);
+	&xor	($s[$i],$tp2);	# ^= ROTATE(tp8^tp2^tp1,24)
+	&xor	($s[$i],$tp4);	# ^= ROTATE(tp8^tp4^tp1,16)
+	 &mov	($s[0],$__s0)			if($i==2); #prefetch $s0
+	 &mov	($s[1],$__s1)			if($i==3); #prefetch $s1
+	 &mov	($s[2],$__s2)			if($i==1);
+	&xor	($s[$i],$tp8);	# ^= ROTATE(tp8,8)
+
+	&mov	($s[3],$__s3)			if($i==1);
+	&mov	(&DWP(4+4*$i,"esp"),$s[$i])	if($i>=2);
+}
+
+&function_begin_B("_x86_AES_decrypt_compact");
+	# note that caller is expected to allocate stack frame for me!
+	&mov	($__key,$key);			# save key
+
+	&xor	($s0,&DWP(0,$key));		# xor with key
+	&xor	($s1,&DWP(4,$key));
+	&xor	($s2,&DWP(8,$key));
+	&xor	($s3,&DWP(12,$key));
+
+	&mov	($acc,&DWP(240,$key));		# load key->rounds
+
+	&lea	($acc,&DWP(-2,$acc,$acc));
+	&lea	($acc,&DWP(0,$key,$acc,8));
+	&mov	($__end,$acc);			# end of key schedule
+
+	# prefetch Td4
+	&mov	($key,&DWP(0-128,$tbl));
+	&mov	($acc,&DWP(32-128,$tbl));
+	&mov	($key,&DWP(64-128,$tbl));
+	&mov	($acc,&DWP(96-128,$tbl));
+	&mov	($key,&DWP(128-128,$tbl));
+	&mov	($acc,&DWP(160-128,$tbl));
+	&mov	($key,&DWP(192-128,$tbl));
+	&mov	($acc,&DWP(224-128,$tbl));
+
+	&set_label("loop",16);
+
+		&deccompact(0,$tbl,$s0,$s3,$s2,$s1,1);
+		&deccompact(1,$tbl,$s1,$s0,$s3,$s2,1);
+		&deccompact(2,$tbl,$s2,$s1,$s0,$s3,1);
+		&deccompact(3,$tbl,$s3,$s2,$s1,$s0,1);
+		&dectransform(2);
+		&dectransform(3);
+		&dectransform(0);
+		&dectransform(1);
+		&mov 	($key,$__key);
+		&mov	($tbl,$__tbl);
+		&add	($key,16);		# advance rd_key
+		&xor	($s0,&DWP(0,$key));
+		&xor	($s1,&DWP(4,$key));
+		&xor	($s2,&DWP(8,$key));
+		&xor	($s3,&DWP(12,$key));
+
+	&cmp	($key,$__end);
+	&mov	($__key,$key);
+	&jb	(&label("loop"));
+
+	&deccompact(0,$tbl,$s0,$s3,$s2,$s1);
+	&deccompact(1,$tbl,$s1,$s0,$s3,$s2);
+	&deccompact(2,$tbl,$s2,$s1,$s0,$s3);
+	&deccompact(3,$tbl,$s3,$s2,$s1,$s0);
+
+	&xor	($s0,&DWP(16,$key));
+	&xor	($s1,&DWP(20,$key));
+	&xor	($s2,&DWP(24,$key));
+	&xor	($s3,&DWP(28,$key));
+
+	&ret	();
+&function_end_B("_x86_AES_decrypt_compact");
+
+######################################################################
+# "Compact" SSE block function.
+######################################################################
+
+sub sse_deccompact()
+{
+	&pshufw	("mm1","mm0",0x0c);		#  7, 6, 1, 0
+	&movd	("eax","mm1");			#  7, 6, 1, 0
+
+	&pshufw	("mm5","mm4",0x09);		# 13,12,11,10
+	&movz	($acc,&LB("eax"));		#  0
+	&movz	("ecx",&BP(-128,$tbl,$acc,1));	#  0
+	&movd	("ebx","mm5");			# 13,12,11,10
+	&movz	("edx",&HB("eax"));		#  1
+	&movz	("edx",&BP(-128,$tbl,"edx",1));	#  1
+	&shl	("edx",8);			#  1
+
+	&pshufw	("mm2","mm0",0x06);		#  3, 2, 5, 4
+	&movz	($acc,&LB("ebx"));		# 10
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 10
+	&shl	($acc,16);			# 10
+	&or	("ecx",$acc);			# 10
+	&shr	("eax",16);			#  7, 6
+	&movz	($acc,&HB("ebx"));		# 11
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 11
+	&shl	($acc,24);			# 11
+	&or	("edx",$acc);			# 11
+	&shr	("ebx",16);			# 13,12
+
+	&pshufw	("mm6","mm4",0x03);		# 9, 8,15,14
+	&movz	($acc,&HB("eax"));		#  7
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  7
+	&shl	($acc,24);			#  7
+	&or	("ecx",$acc);			#  7
+	&movz	($acc,&HB("ebx"));		# 13
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 13
+	&shl	($acc,8);			# 13
+	&or	("ecx",$acc);			# 13
+	&movd	("mm0","ecx");			# t[0] collected
+
+	&movz	($acc,&LB("eax"));		#  6
+	&movd	("eax","mm2");			#  3, 2, 5, 4
+	&movz	("ecx",&BP(-128,$tbl,$acc,1));	#  6
+	&shl	("ecx",16);			#  6
+	&movz	($acc,&LB("ebx"));		# 12
+	&movd	("ebx","mm6");			#  9, 8,15,14
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 12
+	&or	("ecx",$acc);			# 12
+
+	&movz	($acc,&LB("eax"));		#  4
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  4
+	&or	("edx",$acc);			#  4
+	&movz	($acc,&LB("ebx"));		# 14
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 14
+	&shl	($acc,16);			# 14
+	&or	("edx",$acc);			# 14
+	&movd	("mm1","edx");			# t[1] collected
+
+	&movz	($acc,&HB("eax"));		#  5
+	&movz	("edx",&BP(-128,$tbl,$acc,1));	#  5
+	&shl	("edx",8);			#  5
+	&movz	($acc,&HB("ebx"));		# 15
+	&shr	("eax",16);			#  3, 2
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 15
+	&shl	($acc,24);			# 15
+	&or	("edx",$acc);			# 15
+	&shr	("ebx",16);			#  9, 8
+
+	&punpckldq	("mm0","mm1");		# t[0,1] collected
+
+	&movz	($acc,&HB("ebx"));		#  9
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  9
+	&shl	($acc,8);			#  9
+	&or	("ecx",$acc);			#  9
+	&and	("ebx",0xff);			#  8
+	&movz	("ebx",&BP(-128,$tbl,"ebx",1));	#  8
+	&or	("edx","ebx");			#  8
+	&movz	($acc,&LB("eax"));		#  2
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  2
+	&shl	($acc,16);			#  2
+	&or	("edx",$acc);			#  2
+	&movd	("mm4","edx");			# t[2] collected
+	&movz	("eax",&HB("eax"));		#  3
+	&movz	("eax",&BP(-128,$tbl,"eax",1));	#  3
+	&shl	("eax",24);			#  3
+	&or	("ecx","eax");			#  3
+	&movd	("mm5","ecx");			# t[3] collected
+
+	&punpckldq	("mm4","mm5");		# t[2,3] collected
+}
+
+					if (!$x86only) {
+&function_begin_B("_sse_AES_decrypt_compact");
+	&pxor	("mm0",&QWP(0,$key));	#  7, 6, 5, 4, 3, 2, 1, 0
+	&pxor	("mm4",&QWP(8,$key));	# 15,14,13,12,11,10, 9, 8
+
+	# note that caller is expected to allocate stack frame for me!
+	&mov	($acc,&DWP(240,$key));		# load key->rounds
+	&lea	($acc,&DWP(-2,$acc,$acc));
+	&lea	($acc,&DWP(0,$key,$acc,8));
+	&mov	($__end,$acc);			# end of key schedule
+
+	&mov	($s0,0x1b1b1b1b);		# magic constant
+	&mov	(&DWP(8,"esp"),$s0);
+	&mov	(&DWP(12,"esp"),$s0);
+
+	# prefetch Td4
+	&mov	($s0,&DWP(0-128,$tbl));
+	&mov	($s1,&DWP(32-128,$tbl));
+	&mov	($s2,&DWP(64-128,$tbl));
+	&mov	($s3,&DWP(96-128,$tbl));
+	&mov	($s0,&DWP(128-128,$tbl));
+	&mov	($s1,&DWP(160-128,$tbl));
+	&mov	($s2,&DWP(192-128,$tbl));
+	&mov	($s3,&DWP(224-128,$tbl));
+
+	&set_label("loop",16);
+		&sse_deccompact();
+		&add	($key,16);
+		&cmp	($key,$__end);
+		&ja	(&label("out"));
+
+		# ROTATE(x^y,N) == ROTATE(x,N)^ROTATE(y,N)
+		&movq	("mm3","mm0");		&movq	("mm7","mm4");
+		&movq	("mm2","mm0",1);	&movq	("mm6","mm4",1);
+		&movq	("mm1","mm0");		&movq	("mm5","mm4");
+		&pshufw	("mm0","mm0",0xb1);	&pshufw	("mm4","mm4",0xb1);# = ROTATE(tp0,16)
+		&pslld	("mm2",8);		&pslld	("mm6",8);
+		&psrld	("mm3",8);		&psrld	("mm7",8);
+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= tp0<<8
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp0>>8
+		&pslld	("mm2",16);		&pslld	("mm6",16);
+		&psrld	("mm3",16);		&psrld	("mm7",16);
+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= tp0<<24
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp0>>24
+
+		&movq	("mm3",&QWP(8,"esp"));
+		&pxor	("mm2","mm2");		&pxor	("mm6","mm6");
+		&pcmpgtb("mm2","mm1");		&pcmpgtb("mm6","mm5");
+		&pand	("mm2","mm3");		&pand	("mm6","mm3");
+		&paddb	("mm1","mm1");		&paddb	("mm5","mm5");
+		&pxor	("mm1","mm2");		&pxor	("mm5","mm6");	# tp2
+		&movq	("mm3","mm1");		&movq	("mm7","mm5");
+		&movq	("mm2","mm1");		&movq	("mm6","mm5");
+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp2
+		&pslld	("mm3",24);		&pslld	("mm7",24);
+		&psrld	("mm2",8);		&psrld	("mm6",8);
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp2<<24
+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= tp2>>8
+
+		&movq	("mm2",&QWP(8,"esp"));
+		&pxor	("mm3","mm3");		&pxor	("mm7","mm7");
+		&pcmpgtb("mm3","mm1");		&pcmpgtb("mm7","mm5");
+		&pand	("mm3","mm2");		&pand	("mm7","mm2");
+		&paddb	("mm1","mm1");		&paddb	("mm5","mm5");
+		&pxor	("mm1","mm3");		&pxor	("mm5","mm7");	# tp4
+		&pshufw	("mm3","mm1",0xb1);	&pshufw	("mm7","mm5",0xb1);
+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp4
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= ROTATE(tp4,16)	
+
+		&pxor	("mm3","mm3");		&pxor	("mm7","mm7");
+		&pcmpgtb("mm3","mm1");		&pcmpgtb("mm7","mm5");
+		&pand	("mm3","mm2");		&pand	("mm7","mm2");
+		&paddb	("mm1","mm1");		&paddb	("mm5","mm5");
+		&pxor	("mm1","mm3");		&pxor	("mm5","mm7");	# tp8
+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp8
+		&movq	("mm3","mm1");		&movq	("mm7","mm5");
+		&pshufw	("mm2","mm1",0xb1);	&pshufw	("mm6","mm5",0xb1);
+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= ROTATE(tp8,16)
+		&pslld	("mm1",8);		&pslld	("mm5",8);
+		&psrld	("mm3",8);		&psrld	("mm7",8);
+		&movq	("mm2",&QWP(0,$key));	&movq	("mm6",&QWP(8,$key));
+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp8<<8
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp8>>8
+		&mov	($s0,&DWP(0-128,$tbl));
+		&pslld	("mm1",16);		&pslld	("mm5",16);
+		&mov	($s1,&DWP(64-128,$tbl));
+		&psrld	("mm3",16);		&psrld	("mm7",16);
+		&mov	($s2,&DWP(128-128,$tbl));
+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp8<<24
+		&mov	($s3,&DWP(192-128,$tbl));
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp8>>24
+
+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");
+	&jmp	(&label("loop"));
+
+	&set_label("out",16);
+	&pxor	("mm0",&QWP(0,$key));
+	&pxor	("mm4",&QWP(8,$key));
+
+	&ret	();
+&function_end_B("_sse_AES_decrypt_compact");
+					}
+
+######################################################################
+# Vanilla block function.
+######################################################################
+
+sub decstep()
+{ my ($i,$td,@s) = @_;
+  my $tmp = $key;
+  my $out = $i==3?$s[0]:$acc;
+
+	# no instructions are reordered, as performance appears
+	# optimal... or rather that all attempts to reorder didn't
+	# result in better performance [which by the way is not a
+	# bit lower than ecryption].
+	if($i==3)   {	&mov	($key,$__key);			}
+	else        {	&mov	($out,$s[0]);			}
+			&and	($out,0xFF);
+			&mov	($out,&DWP(0,$td,$out,8));
+
+	if ($i==3)  {	$tmp=$s[1];				}
+			&movz	($tmp,&HB($s[1]));
+			&xor	($out,&DWP(3,$td,$tmp,8));
+
+	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$acc);		}
+	else        {	&mov	($tmp,$s[2]);			}
+			&shr	($tmp,16);
+			&and	($tmp,0xFF);
+			&xor	($out,&DWP(2,$td,$tmp,8));
+
+	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}
+	else        {	&mov	($tmp,$s[3]);			}
+			&shr	($tmp,24);
+			&xor	($out,&DWP(1,$td,$tmp,8));
+	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
+	if ($i==3)  {	&mov	($s[3],$__s0);			}
+			&comment();
+}
+
+sub declast()
+{ my ($i,$td,@s)=@_;
+  my $tmp = $key;
+  my $out = $i==3?$s[0]:$acc;
+
+	if($i==0)   {	&lea	($td,&DWP(2048+128,$td));
+			&mov	($tmp,&DWP(0-128,$td));
+			&mov	($acc,&DWP(32-128,$td));
+			&mov	($tmp,&DWP(64-128,$td));
+			&mov	($acc,&DWP(96-128,$td));
+			&mov	($tmp,&DWP(128-128,$td));
+			&mov	($acc,&DWP(160-128,$td));
+			&mov	($tmp,&DWP(192-128,$td));
+			&mov	($acc,&DWP(224-128,$td));
+			&lea	($td,&DWP(-128,$td));		}
+	if($i==3)   {	&mov	($key,$__key);			}
+	else        {	&mov	($out,$s[0]);			}
+			&and	($out,0xFF);
+			&movz	($out,&BP(0,$td,$out,1));
+
+	if ($i==3)  {	$tmp=$s[1];				}
+			&movz	($tmp,&HB($s[1]));
+			&movz	($tmp,&BP(0,$td,$tmp,1));
+			&shl	($tmp,8);
+			&xor	($out,$tmp);
+
+	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$acc);		}
+	else        {	mov	($tmp,$s[2]);			}
+			&shr	($tmp,16);
+			&and	($tmp,0xFF);
+			&movz	($tmp,&BP(0,$td,$tmp,1));
+			&shl	($tmp,16);
+			&xor	($out,$tmp);
+
+	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}
+	else        {	&mov	($tmp,$s[3]);			}
+			&shr	($tmp,24);
+			&movz	($tmp,&BP(0,$td,$tmp,1));
+			&shl	($tmp,24);
+			&xor	($out,$tmp);
+	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
+	if ($i==3)  {	&mov	($s[3],$__s0);
+			&lea	($td,&DWP(-2048,$td));		}
+}
+
+&function_begin_B("_x86_AES_decrypt");
+	# note that caller is expected to allocate stack frame for me!
+	&mov	($__key,$key);			# save key
+
+	&xor	($s0,&DWP(0,$key));		# xor with key
+	&xor	($s1,&DWP(4,$key));
+	&xor	($s2,&DWP(8,$key));
+	&xor	($s3,&DWP(12,$key));
+
+	&mov	($acc,&DWP(240,$key));		# load key->rounds
+
+	if ($small_footprint) {
+	    &lea	($acc,&DWP(-2,$acc,$acc));
+	    &lea	($acc,&DWP(0,$key,$acc,8));
+	    &mov	($__end,$acc);		# end of key schedule
+	    &set_label("loop",16);
+		&decstep(0,$tbl,$s0,$s3,$s2,$s1);
+		&decstep(1,$tbl,$s1,$s0,$s3,$s2);
+		&decstep(2,$tbl,$s2,$s1,$s0,$s3);
+		&decstep(3,$tbl,$s3,$s2,$s1,$s0);
+		&add	($key,16);		# advance rd_key
+		&xor	($s0,&DWP(0,$key));
+		&xor	($s1,&DWP(4,$key));
+		&xor	($s2,&DWP(8,$key));
+		&xor	($s3,&DWP(12,$key));
+	    &cmp	($key,$__end);
+	    &mov	($__key,$key);
+	    &jb		(&label("loop"));
+	}
+	else {
+	    &cmp	($acc,10);
+	    &jle	(&label("10rounds"));
+	    &cmp	($acc,12);
+	    &jle	(&label("12rounds"));
+
+	&set_label("14rounds",4);
+	    for ($i=1;$i<3;$i++) {
+		&decstep(0,$tbl,$s0,$s3,$s2,$s1);
+		&decstep(1,$tbl,$s1,$s0,$s3,$s2);
+		&decstep(2,$tbl,$s2,$s1,$s0,$s3);
+		&decstep(3,$tbl,$s3,$s2,$s1,$s0);
+		&xor	($s0,&DWP(16*$i+0,$key));
+		&xor	($s1,&DWP(16*$i+4,$key));
+		&xor	($s2,&DWP(16*$i+8,$key));
+		&xor	($s3,&DWP(16*$i+12,$key));
+	    }
+	    &add	($key,32);
+	    &mov	($__key,$key);		# advance rd_key
+	&set_label("12rounds",4);
+	    for ($i=1;$i<3;$i++) {
+		&decstep(0,$tbl,$s0,$s3,$s2,$s1);
+		&decstep(1,$tbl,$s1,$s0,$s3,$s2);
+		&decstep(2,$tbl,$s2,$s1,$s0,$s3);
+		&decstep(3,$tbl,$s3,$s2,$s1,$s0);
+		&xor	($s0,&DWP(16*$i+0,$key));
+		&xor	($s1,&DWP(16*$i+4,$key));
+		&xor	($s2,&DWP(16*$i+8,$key));
+		&xor	($s3,&DWP(16*$i+12,$key));
+	    }
+	    &add	($key,32);
+	    &mov	($__key,$key);		# advance rd_key
+	&set_label("10rounds",4);
+	    for ($i=1;$i<10;$i++) {
+		&decstep(0,$tbl,$s0,$s3,$s2,$s1);
+		&decstep(1,$tbl,$s1,$s0,$s3,$s2);
+		&decstep(2,$tbl,$s2,$s1,$s0,$s3);
+		&decstep(3,$tbl,$s3,$s2,$s1,$s0);
+		&xor	($s0,&DWP(16*$i+0,$key));
+		&xor	($s1,&DWP(16*$i+4,$key));
+		&xor	($s2,&DWP(16*$i+8,$key));
+		&xor	($s3,&DWP(16*$i+12,$key));
+	    }
+	}
+
+	&declast(0,$tbl,$s0,$s3,$s2,$s1);
+	&declast(1,$tbl,$s1,$s0,$s3,$s2);
+	&declast(2,$tbl,$s2,$s1,$s0,$s3);
+	&declast(3,$tbl,$s3,$s2,$s1,$s0);
+
+	&add	($key,$small_footprint?16:160);
+	&xor	($s0,&DWP(0,$key));
+	&xor	($s1,&DWP(4,$key));
+	&xor	($s2,&DWP(8,$key));
+	&xor	($s3,&DWP(12,$key));
+
+	&ret	();
+
+&set_label("AES_Td",64);	# Yes! I keep it in the code segment!
+	&_data_word(0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a);
+	&_data_word(0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b);
+	&_data_word(0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5);
+	&_data_word(0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5);
+	&_data_word(0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d);
+	&_data_word(0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b);
+	&_data_word(0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295);
+	&_data_word(0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e);
+	&_data_word(0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927);
+	&_data_word(0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d);
+	&_data_word(0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362);
+	&_data_word(0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9);
+	&_data_word(0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52);
+	&_data_word(0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566);
+	&_data_word(0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3);
+	&_data_word(0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed);
+	&_data_word(0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e);
+	&_data_word(0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4);
+	&_data_word(0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4);
+	&_data_word(0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd);
+	&_data_word(0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d);
+	&_data_word(0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060);
+	&_data_word(0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967);
+	&_data_word(0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879);
+	&_data_word(0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000);
+	&_data_word(0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c);
+	&_data_word(0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36);
+	&_data_word(0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624);
+	&_data_word(0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b);
+	&_data_word(0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c);
+	&_data_word(0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12);
+	&_data_word(0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14);
+	&_data_word(0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3);
+	&_data_word(0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b);
+	&_data_word(0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8);
+	&_data_word(0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684);
+	&_data_word(0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7);
+	&_data_word(0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177);
+	&_data_word(0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947);
+	&_data_word(0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322);
+	&_data_word(0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498);
+	&_data_word(0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f);
+	&_data_word(0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54);
+	&_data_word(0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382);
+	&_data_word(0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf);
+	&_data_word(0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb);
+	&_data_word(0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83);
+	&_data_word(0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef);
+	&_data_word(0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029);
+	&_data_word(0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235);
+	&_data_word(0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733);
+	&_data_word(0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117);
+	&_data_word(0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4);
+	&_data_word(0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546);
+	&_data_word(0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb);
+	&_data_word(0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d);
+	&_data_word(0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb);
+	&_data_word(0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a);
+	&_data_word(0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773);
+	&_data_word(0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478);
+	&_data_word(0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2);
+	&_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff);
+	&_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664);
+	&_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0);
+
+#Td4:	# four copies of Td4 to choose from to avoid L1 aliasing
+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
+
+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
+
+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
+
+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
+&function_end_B("_x86_AES_decrypt");
+
+# void AES_decrypt (const void *inp,void *out,const AES_KEY *key);
+&function_begin("AES_decrypt");
+	&mov	($acc,&wparam(0));		# load inp
+	&mov	($key,&wparam(2));		# load key
+
+	&mov	($s0,"esp");
+	&sub	("esp",36);
+	&and	("esp",-64);			# align to cache-line
+
+	# place stack frame just "above" the key schedule
+	&lea	($s1,&DWP(-64-63,$key));
+	&sub	($s1,"esp");
+	&neg	($s1);
+	&and	($s1,0x3C0);	# modulo 1024, but aligned to cache-line
+	&sub	("esp",$s1);
+	&add	("esp",4);	# 4 is reserved for caller's return address
+	&mov	($_esp,$s0);	# save stack pointer
+
+	&call   (&label("pic_point"));          # make it PIC!
+	&set_label("pic_point");
+	&blindpop($tbl);
+	&picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if(!$x86only);
+	&lea    ($tbl,&DWP(&label("AES_Td")."-".&label("pic_point"),$tbl));
+
+	# pick Td4 copy which can't "overlap" with stack frame or key schedule
+	&lea	($s1,&DWP(768-4,"esp"));
+	&sub	($s1,$tbl);
+	&and	($s1,0x300);
+	&lea	($tbl,&DWP(2048+128,$tbl,$s1));
+
+					if (!$x86only) {
+	&bt	(&DWP(0,$s0),25);	# check for SSE bit
+	&jnc	(&label("x86"));
+
+	&movq	("mm0",&QWP(0,$acc));
+	&movq	("mm4",&QWP(8,$acc));
+	&call	("_sse_AES_decrypt_compact");
+	&mov	("esp",$_esp);			# restore stack pointer
+	&mov	($acc,&wparam(1));		# load out
+	&movq	(&QWP(0,$acc),"mm0");		# write output data
+	&movq	(&QWP(8,$acc),"mm4");
+	&emms	();
+	&function_end_A();
+					}
+	&set_label("x86",16);
+	&mov	($_tbl,$tbl);
+	&mov	($s0,&DWP(0,$acc));		# load input data
+	&mov	($s1,&DWP(4,$acc));
+	&mov	($s2,&DWP(8,$acc));
+	&mov	($s3,&DWP(12,$acc));
+	&call	("_x86_AES_decrypt_compact");
+	&mov	("esp",$_esp);			# restore stack pointer
+	&mov	($acc,&wparam(1));		# load out
+	&mov	(&DWP(0,$acc),$s0);		# write output data
+	&mov	(&DWP(4,$acc),$s1);
+	&mov	(&DWP(8,$acc),$s2);
+	&mov	(&DWP(12,$acc),$s3);
+&function_end("AES_decrypt");
+
+# void AES_cbc_encrypt (const void char *inp, unsigned char *out,
+#			size_t length, const AES_KEY *key,
+#			unsigned char *ivp,const int enc);
+{
+# stack frame layout
+#             -4(%esp)		# return address	 0(%esp)
+#              0(%esp)		# s0 backing store	 4(%esp)	
+#              4(%esp)		# s1 backing store	 8(%esp)
+#              8(%esp)		# s2 backing store	12(%esp)
+#             12(%esp)		# s3 backing store	16(%esp)
+#             16(%esp)		# key backup		20(%esp)
+#             20(%esp)		# end of key schedule	24(%esp)
+#             24(%esp)		# %ebp backup		28(%esp)
+#             28(%esp)		# %esp backup
+my $_inp=&DWP(32,"esp");	# copy of wparam(0)
+my $_out=&DWP(36,"esp");	# copy of wparam(1)
+my $_len=&DWP(40,"esp");	# copy of wparam(2)
+my $_key=&DWP(44,"esp");	# copy of wparam(3)
+my $_ivp=&DWP(48,"esp");	# copy of wparam(4)
+my $_tmp=&DWP(52,"esp");	# volatile variable
+#
+my $ivec=&DWP(60,"esp");	# ivec[16]
+my $aes_key=&DWP(76,"esp");	# copy of aes_key
+my $mark=&DWP(76+240,"esp");	# copy of aes_key->rounds
+
+&function_begin("AES_cbc_encrypt");
+	&mov	($s2 eq "ecx"? $s2 : "",&wparam(2));	# load len
+	&cmp	($s2,0);
+	&je	(&label("drop_out"));
+
+	&call   (&label("pic_point"));		# make it PIC!
+	&set_label("pic_point");
+	&blindpop($tbl);
+	&picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if(!$x86only);
+
+	&cmp	(&wparam(5),0);
+	&lea    ($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
+	&jne	(&label("picked_te"));
+	&lea	($tbl,&DWP(&label("AES_Td")."-".&label("AES_Te"),$tbl));
+	&set_label("picked_te");
+
+	# one can argue if this is required
+	&pushf	();
+	&cld	();
+
+	&cmp	($s2,$speed_limit);
+	&jb	(&label("slow_way"));
+	&test	($s2,15);
+	&jnz	(&label("slow_way"));
+					if (!$x86only) {
+	&bt	(&DWP(0,$s0),28);	# check for hyper-threading bit
+	&jc	(&label("slow_way"));
+					}
+	# pre-allocate aligned stack frame...
+	&lea	($acc,&DWP(-80-244,"esp"));
+	&and	($acc,-64);
+
+	# ... and make sure it doesn't alias with $tbl modulo 4096
+	&mov	($s0,$tbl);
+	&lea	($s1,&DWP(2048+256,$tbl));
+	&mov	($s3,$acc);
+	&and	($s0,0xfff);		# s = %ebp&0xfff
+	&and	($s1,0xfff);		# e = (%ebp+2048+256)&0xfff
+	&and	($s3,0xfff);		# p = %esp&0xfff
+
+	&cmp	($s3,$s1);		# if (p>=e) %esp =- (p-e);
+	&jb	(&label("tbl_break_out"));
+	&sub	($s3,$s1);
+	&sub	($acc,$s3);
+	&jmp	(&label("tbl_ok"));
+	&set_label("tbl_break_out",4);	# else %esp -= (p-s)&0xfff + framesz;
+	&sub	($s3,$s0);
+	&and	($s3,0xfff);
+	&add	($s3,384);
+	&sub	($acc,$s3);
+	&set_label("tbl_ok",4);
+
+	&lea	($s3,&wparam(0));	# obtain pointer to parameter block
+	&exch	("esp",$acc);		# allocate stack frame
+	&add	("esp",4);		# reserve for return address!
+	&mov	($_tbl,$tbl);		# save %ebp
+	&mov	($_esp,$acc);		# save %esp
+
+	&mov	($s0,&DWP(0,$s3));	# load inp
+	&mov	($s1,&DWP(4,$s3));	# load out
+	#&mov	($s2,&DWP(8,$s3));	# load len
+	&mov	($key,&DWP(12,$s3));	# load key
+	&mov	($acc,&DWP(16,$s3));	# load ivp
+	&mov	($s3,&DWP(20,$s3));	# load enc flag
+
+	&mov	($_inp,$s0);		# save copy of inp
+	&mov	($_out,$s1);		# save copy of out
+	&mov	($_len,$s2);		# save copy of len
+	&mov	($_key,$key);		# save copy of key
+	&mov	($_ivp,$acc);		# save copy of ivp
+
+	&mov	($mark,0);		# copy of aes_key->rounds = 0;
+	# do we copy key schedule to stack?
+	&mov	($s1 eq "ebx" ? $s1 : "",$key);
+	&mov	($s2 eq "ecx" ? $s2 : "",244/4);
+	&sub	($s1,$tbl);
+	&mov	("esi",$key);
+	&and	($s1,0xfff);
+	&lea	("edi",$aes_key);
+	&cmp	($s1,2048+256);
+	&jb	(&label("do_copy"));
+	&cmp	($s1,4096-244);
+	&jb	(&label("skip_copy"));
+	&set_label("do_copy",4);
+		&mov	($_key,"edi");
+		&data_word(0xA5F3F689);	# rep movsd
+	&set_label("skip_copy");
+
+	&mov	($key,16);
+	&set_label("prefetch_tbl",4);
+		&mov	($s0,&DWP(0,$tbl));
+		&mov	($s1,&DWP(32,$tbl));
+		&mov	($s2,&DWP(64,$tbl));
+		&mov	($acc,&DWP(96,$tbl));
+		&lea	($tbl,&DWP(128,$tbl));
+		&sub	($key,1);
+	&jnz	(&label("prefetch_tbl"));
+	&sub	($tbl,2048);
+
+	&mov	($acc,$_inp);
+	&mov	($key,$_ivp);
+
+	&cmp	($s3,0);
+	&je	(&label("fast_decrypt"));
+
+#----------------------------- ENCRYPT -----------------------------#
+	&mov	($s0,&DWP(0,$key));		# load iv
+	&mov	($s1,&DWP(4,$key));
+
+	&set_label("fast_enc_loop",16);
+		&mov	($s2,&DWP(8,$key));
+		&mov	($s3,&DWP(12,$key));
+
+		&xor	($s0,&DWP(0,$acc));	# xor input data
+		&xor	($s1,&DWP(4,$acc));
+		&xor	($s2,&DWP(8,$acc));
+		&xor	($s3,&DWP(12,$acc));
+
+		&mov	($key,$_key);		# load key
+		&call	("_x86_AES_encrypt");
+
+		&mov	($acc,$_inp);		# load inp
+		&mov	($key,$_out);		# load out
+
+		&mov	(&DWP(0,$key),$s0);	# save output data
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&mov	(&DWP(12,$key),$s3);
+
+		&lea	($acc,&DWP(16,$acc));	# advance inp
+		&mov	($s2,$_len);		# load len
+		&mov	($_inp,$acc);		# save inp
+		&lea	($s3,&DWP(16,$key));	# advance out
+		&mov	($_out,$s3);		# save out
+		&sub	($s2,16);		# decrease len
+		&mov	($_len,$s2);		# save len
+	&jnz	(&label("fast_enc_loop"));
+	&mov	($acc,$_ivp);		# load ivp
+	&mov	($s2,&DWP(8,$key));	# restore last 2 dwords
+	&mov	($s3,&DWP(12,$key));
+	&mov	(&DWP(0,$acc),$s0);	# save ivec
+	&mov	(&DWP(4,$acc),$s1);
+	&mov	(&DWP(8,$acc),$s2);
+	&mov	(&DWP(12,$acc),$s3);
+
+	&cmp	($mark,0);		# was the key schedule copied?
+	&mov	("edi",$_key);
+	&je	(&label("skip_ezero"));
+	# zero copy of key schedule
+	&mov	("ecx",240/4);
+	&xor	("eax","eax");
+	&align	(4);
+	&data_word(0xABF3F689);	# rep stosd
+	&set_label("skip_ezero")
+	&mov	("esp",$_esp);
+	&popf	();
+    &set_label("drop_out");
+	&function_end_A();
+	&pushf	();			# kludge, never executed
+
+#----------------------------- DECRYPT -----------------------------#
+&set_label("fast_decrypt",16);
+
+	&cmp	($acc,$_out);
+	&je	(&label("fast_dec_in_place"));	# in-place processing...
+
+	&mov	($_tmp,$key);
+
+	&align	(4);
+	&set_label("fast_dec_loop",16);
+		&mov	($s0,&DWP(0,$acc));	# read input
+		&mov	($s1,&DWP(4,$acc));
+		&mov	($s2,&DWP(8,$acc));
+		&mov	($s3,&DWP(12,$acc));
+
+		&mov	($key,$_key);		# load key
+		&call	("_x86_AES_decrypt");
+
+		&mov	($key,$_tmp);		# load ivp
+		&mov	($acc,$_len);		# load len
+		&xor	($s0,&DWP(0,$key));	# xor iv
+		&xor	($s1,&DWP(4,$key));
+		&xor	($s2,&DWP(8,$key));
+		&xor	($s3,&DWP(12,$key));
+
+		&mov	($key,$_out);		# load out
+		&mov	($acc,$_inp);		# load inp
+
+		&mov	(&DWP(0,$key),$s0);	# write output
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&mov	(&DWP(12,$key),$s3);
+
+		&mov	($s2,$_len);		# load len
+		&mov	($_tmp,$acc);		# save ivp
+		&lea	($acc,&DWP(16,$acc));	# advance inp
+		&mov	($_inp,$acc);		# save inp
+		&lea	($key,&DWP(16,$key));	# advance out
+		&mov	($_out,$key);		# save out
+		&sub	($s2,16);		# decrease len
+		&mov	($_len,$s2);		# save len
+	&jnz	(&label("fast_dec_loop"));
+	&mov	($key,$_tmp);		# load temp ivp
+	&mov	($acc,$_ivp);		# load user ivp
+	&mov	($s0,&DWP(0,$key));	# load iv
+	&mov	($s1,&DWP(4,$key));
+	&mov	($s2,&DWP(8,$key));
+	&mov	($s3,&DWP(12,$key));
+	&mov	(&DWP(0,$acc),$s0);	# copy back to user
+	&mov	(&DWP(4,$acc),$s1);
+	&mov	(&DWP(8,$acc),$s2);
+	&mov	(&DWP(12,$acc),$s3);
+	&jmp	(&label("fast_dec_out"));
+
+    &set_label("fast_dec_in_place",16);
+	&set_label("fast_dec_in_place_loop");
+		&mov	($s0,&DWP(0,$acc));	# read input
+		&mov	($s1,&DWP(4,$acc));
+		&mov	($s2,&DWP(8,$acc));
+		&mov	($s3,&DWP(12,$acc));
+
+		&lea	($key,$ivec);
+		&mov	(&DWP(0,$key),$s0);	# copy to temp
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&mov	(&DWP(12,$key),$s3);
+
+		&mov	($key,$_key);		# load key
+		&call	("_x86_AES_decrypt");
+
+		&mov	($key,$_ivp);		# load ivp
+		&mov	($acc,$_out);		# load out
+		&xor	($s0,&DWP(0,$key));	# xor iv
+		&xor	($s1,&DWP(4,$key));
+		&xor	($s2,&DWP(8,$key));
+		&xor	($s3,&DWP(12,$key));
+
+		&mov	(&DWP(0,$acc),$s0);	# write output
+		&mov	(&DWP(4,$acc),$s1);
+		&mov	(&DWP(8,$acc),$s2);
+		&mov	(&DWP(12,$acc),$s3);
+
+		&lea	($acc,&DWP(16,$acc));	# advance out
+		&mov	($_out,$acc);		# save out
+
+		&lea	($acc,$ivec);
+		&mov	($s0,&DWP(0,$acc));	# read temp
+		&mov	($s1,&DWP(4,$acc));
+		&mov	($s2,&DWP(8,$acc));
+		&mov	($s3,&DWP(12,$acc));
+
+		&mov	(&DWP(0,$key),$s0);	# copy iv
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&mov	(&DWP(12,$key),$s3);
+
+		&mov	($acc,$_inp);		# load inp
+		&mov	($s2,$_len);		# load len
+		&lea	($acc,&DWP(16,$acc));	# advance inp
+		&mov	($_inp,$acc);		# save inp
+		&sub	($s2,16);		# decrease len
+		&mov	($_len,$s2);		# save len
+	&jnz	(&label("fast_dec_in_place_loop"));
+
+    &set_label("fast_dec_out",4);
+	&cmp	($mark,0);		# was the key schedule copied?
+	&mov	("edi",$_key);
+	&je	(&label("skip_dzero"));
+	# zero copy of key schedule
+	&mov	("ecx",240/4);
+	&xor	("eax","eax");
+	&align	(4);
+	&data_word(0xABF3F689);	# rep stosd
+	&set_label("skip_dzero")
+	&mov	("esp",$_esp);
+	&popf	();
+	&function_end_A();
+	&pushf	();			# kludge, never executed
+
+#--------------------------- SLOW ROUTINE ---------------------------#
+&set_label("slow_way",16);
+
+	&mov	($s0,&DWP(0,$s0)) if (!$x86only);# load OPENSSL_ia32cap
+	&mov	($key,&wparam(3));	# load key
+
+	# pre-allocate aligned stack frame...
+	&lea	($acc,&DWP(-80,"esp"));
+	&and	($acc,-64);
+
+	# ... and make sure it doesn't alias with $key modulo 1024
+	&lea	($s1,&DWP(-80-63,$key));
+	&sub	($s1,$acc);
+	&neg	($s1);
+	&and	($s1,0x3C0);	# modulo 1024, but aligned to cache-line
+	&sub	($acc,$s1);
+
+	# pick S-box copy which can't overlap with stack frame or $key
+	&lea	($s1,&DWP(768,$acc));
+	&sub	($s1,$tbl);
+	&and	($s1,0x300);
+	&lea	($tbl,&DWP(2048+128,$tbl,$s1));
+
+	&lea	($s3,&wparam(0));	# pointer to parameter block
+
+	&exch	("esp",$acc);
+	&add	("esp",4);		# reserve for return address!
+	&mov	($_tbl,$tbl);		# save %ebp
+	&mov	($_esp,$acc);		# save %esp
+	&mov	($_tmp,$s0);		# save OPENSSL_ia32cap
+
+	&mov	($s0,&DWP(0,$s3));	# load inp
+	&mov	($s1,&DWP(4,$s3));	# load out
+	#&mov	($s2,&DWP(8,$s3));	# load len
+	#&mov	($key,&DWP(12,$s3));	# load key
+	&mov	($acc,&DWP(16,$s3));	# load ivp
+	&mov	($s3,&DWP(20,$s3));	# load enc flag
+
+	&mov	($_inp,$s0);		# save copy of inp
+	&mov	($_out,$s1);		# save copy of out
+	&mov	($_len,$s2);		# save copy of len
+	&mov	($_key,$key);		# save copy of key
+	&mov	($_ivp,$acc);		# save copy of ivp
+
+	&mov	($key,$acc);
+	&mov	($acc,$s0);
+
+	&cmp	($s3,0);
+	&je	(&label("slow_decrypt"));
+
+#--------------------------- SLOW ENCRYPT ---------------------------#
+	&cmp	($s2,16);
+	&mov	($s3,$s1);
+	&jb	(&label("slow_enc_tail"));
+
+					if (!$x86only) {
+	&bt	($_tmp,25);		# check for SSE bit
+	&jnc	(&label("slow_enc_x86"));
+
+	&movq	("mm0",&QWP(0,$key));	# load iv
+	&movq	("mm4",&QWP(8,$key));
+
+	&set_label("slow_enc_loop_sse",16);
+		&pxor	("mm0",&QWP(0,$acc));	# xor input data
+		&pxor	("mm4",&QWP(8,$acc));
+
+		&mov	($key,$_key);
+		&call	("_sse_AES_encrypt_compact");
+
+		&mov	($acc,$_inp);		# load inp
+		&mov	($key,$_out);		# load out
+		&mov	($s2,$_len);		# load len
+
+		&movq	(&QWP(0,$key),"mm0");	# save output data
+		&movq	(&QWP(8,$key),"mm4");
+
+		&lea	($acc,&DWP(16,$acc));	# advance inp
+		&mov	($_inp,$acc);		# save inp
+		&lea	($s3,&DWP(16,$key));	# advance out
+		&mov	($_out,$s3);		# save out
+		&sub	($s2,16);		# decrease len
+		&cmp	($s2,16);
+		&mov	($_len,$s2);		# save len
+	&jae	(&label("slow_enc_loop_sse"));
+	&test	($s2,15);
+	&jnz	(&label("slow_enc_tail"));
+	&mov	($acc,$_ivp);		# load ivp
+	&movq	(&QWP(0,$acc),"mm0");	# save ivec
+	&movq	(&QWP(8,$acc),"mm4");
+	&emms	();
+	&mov	("esp",$_esp);
+	&popf	();
+	&function_end_A();
+	&pushf	();			# kludge, never executed
+					}
+    &set_label("slow_enc_x86",16);
+	&mov	($s0,&DWP(0,$key));	# load iv
+	&mov	($s1,&DWP(4,$key));
+
+	&set_label("slow_enc_loop_x86",4);
+		&mov	($s2,&DWP(8,$key));
+		&mov	($s3,&DWP(12,$key));
+
+		&xor	($s0,&DWP(0,$acc));	# xor input data
+		&xor	($s1,&DWP(4,$acc));
+		&xor	($s2,&DWP(8,$acc));
+		&xor	($s3,&DWP(12,$acc));
+
+		&mov	($key,$_key);		# load key
+		&call	("_x86_AES_encrypt_compact");
+
+		&mov	($acc,$_inp);		# load inp
+		&mov	($key,$_out);		# load out
+
+		&mov	(&DWP(0,$key),$s0);	# save output data
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&mov	(&DWP(12,$key),$s3);
+
+		&mov	($s2,$_len);		# load len
+		&lea	($acc,&DWP(16,$acc));	# advance inp
+		&mov	($_inp,$acc);		# save inp
+		&lea	($s3,&DWP(16,$key));	# advance out
+		&mov	($_out,$s3);		# save out
+		&sub	($s2,16);		# decrease len
+		&cmp	($s2,16);
+		&mov	($_len,$s2);		# save len
+	&jae	(&label("slow_enc_loop_x86"));
+	&test	($s2,15);
+	&jnz	(&label("slow_enc_tail"));
+	&mov	($acc,$_ivp);		# load ivp
+	&mov	($s2,&DWP(8,$key));	# restore last dwords
+	&mov	($s3,&DWP(12,$key));
+	&mov	(&DWP(0,$acc),$s0);	# save ivec
+	&mov	(&DWP(4,$acc),$s1);
+	&mov	(&DWP(8,$acc),$s2);
+	&mov	(&DWP(12,$acc),$s3);
+
+	&mov	("esp",$_esp);
+	&popf	();
+	&function_end_A();
+	&pushf	();			# kludge, never executed
+
+    &set_label("slow_enc_tail",16);
+	&emms	()	if (!$x86only);
+	&mov	($key eq "edi"? $key:"",$s3);	# load out to edi
+	&mov	($s1,16);
+	&sub	($s1,$s2);
+	&cmp	($key,$acc eq "esi"? $acc:"");	# compare with inp
+	&je	(&label("enc_in_place"));
+	&align	(4);
+	&data_word(0xA4F3F689);	# rep movsb	# copy input
+	&jmp	(&label("enc_skip_in_place"));
+    &set_label("enc_in_place");
+	&lea	($key,&DWP(0,$key,$s2));
+    &set_label("enc_skip_in_place");
+	&mov	($s2,$s1);
+	&xor	($s0,$s0);
+	&align	(4);
+	&data_word(0xAAF3F689);	# rep stosb	# zero tail
+
+	&mov	($key,$_ivp);			# restore ivp
+	&mov	($acc,$s3);			# output as input
+	&mov	($s0,&DWP(0,$key));
+	&mov	($s1,&DWP(4,$key));
+	&mov	($_len,16);			# len=16
+	&jmp	(&label("slow_enc_loop_x86"));	# one more spin...
+
+#--------------------------- SLOW DECRYPT ---------------------------#
+&set_label("slow_decrypt",16);
+					if (!$x86only) {
+	&bt	($_tmp,25);		# check for SSE bit
+	&jnc	(&label("slow_dec_loop_x86"));
+
+	&set_label("slow_dec_loop_sse",4);
+		&movq	("mm0",&QWP(0,$acc));	# read input
+		&movq	("mm4",&QWP(8,$acc));
+
+		&mov	($key,$_key);
+		&call	("_sse_AES_decrypt_compact");
+
+		&mov	($acc,$_inp);		# load inp
+		&lea	($s0,$ivec);
+		&mov	($s1,$_out);		# load out
+		&mov	($s2,$_len);		# load len
+		&mov	($key,$_ivp);		# load ivp
+
+		&movq	("mm1",&QWP(0,$acc));	# re-read input
+		&movq	("mm5",&QWP(8,$acc));
+
+		&pxor	("mm0",&QWP(0,$key));	# xor iv
+		&pxor	("mm4",&QWP(8,$key));
+
+		&movq	(&QWP(0,$key),"mm1");	# copy input to iv
+		&movq	(&QWP(8,$key),"mm5");
+
+		&sub	($s2,16);		# decrease len
+		&jc	(&label("slow_dec_partial_sse"));
+
+		&movq	(&QWP(0,$s1),"mm0");	# write output
+		&movq	(&QWP(8,$s1),"mm4");
+
+		&lea	($s1,&DWP(16,$s1));	# advance out
+		&mov	($_out,$s1);		# save out
+		&lea	($acc,&DWP(16,$acc));	# advance inp
+		&mov	($_inp,$acc);		# save inp
+		&mov	($_len,$s2);		# save len
+	&jnz	(&label("slow_dec_loop_sse"));
+	&emms	();
+	&mov	("esp",$_esp);
+	&popf	();
+	&function_end_A();
+	&pushf	();			# kludge, never executed
+
+    &set_label("slow_dec_partial_sse",16);
+	&movq	(&QWP(0,$s0),"mm0");	# save output to temp
+	&movq	(&QWP(8,$s0),"mm4");
+	&emms	();
+
+	&add	($s2 eq "ecx" ? "ecx":"",16);
+	&mov	("edi",$s1);		# out
+	&mov	("esi",$s0);		# temp
+	&align	(4);
+	&data_word(0xA4F3F689);		# rep movsb # copy partial output
+
+	&mov	("esp",$_esp);
+	&popf	();
+	&function_end_A();
+	&pushf	();			# kludge, never executed
+					}
+	&set_label("slow_dec_loop_x86",16);
+		&mov	($s0,&DWP(0,$acc));	# read input
+		&mov	($s1,&DWP(4,$acc));
+		&mov	($s2,&DWP(8,$acc));
+		&mov	($s3,&DWP(12,$acc));
+
+		&lea	($key,$ivec);
+		&mov	(&DWP(0,$key),$s0);	# copy to temp
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&mov	(&DWP(12,$key),$s3);
+
+		&mov	($key,$_key);		# load key
+		&call	("_x86_AES_decrypt_compact");
+
+		&mov	($key,$_ivp);		# load ivp
+		&mov	($acc,$_len);		# load len
+		&xor	($s0,&DWP(0,$key));	# xor iv
+		&xor	($s1,&DWP(4,$key));
+		&xor	($s2,&DWP(8,$key));
+		&xor	($s3,&DWP(12,$key));
+
+		&sub	($acc,16);
+		&jc	(&label("slow_dec_partial_x86"));
+
+		&mov	($_len,$acc);		# save len
+		&mov	($acc,$_out);		# load out
+
+		&mov	(&DWP(0,$acc),$s0);	# write output
+		&mov	(&DWP(4,$acc),$s1);
+		&mov	(&DWP(8,$acc),$s2);
+		&mov	(&DWP(12,$acc),$s3);
+
+		&lea	($acc,&DWP(16,$acc));	# advance out
+		&mov	($_out,$acc);		# save out
+
+		&lea	($acc,$ivec);
+		&mov	($s0,&DWP(0,$acc));	# read temp
+		&mov	($s1,&DWP(4,$acc));
+		&mov	($s2,&DWP(8,$acc));
+		&mov	($s3,&DWP(12,$acc));
+
+		&mov	(&DWP(0,$key),$s0);	# copy it to iv
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&mov	(&DWP(12,$key),$s3);
+
+		&mov	($acc,$_inp);		# load inp
+		&lea	($acc,&DWP(16,$acc));	# advance inp
+		&mov	($_inp,$acc);		# save inp
+	&jnz	(&label("slow_dec_loop_x86"));
+	&mov	("esp",$_esp);
+	&popf	();
+	&function_end_A();
+	&pushf	();			# kludge, never executed
+
+    &set_label("slow_dec_partial_x86",16);
+	&lea	($acc,$ivec);
+	&mov	(&DWP(0,$acc),$s0);	# save output to temp
+	&mov	(&DWP(4,$acc),$s1);
+	&mov	(&DWP(8,$acc),$s2);
+	&mov	(&DWP(12,$acc),$s3);
+
+	&mov	($acc,$_inp);
+	&mov	($s0,&DWP(0,$acc));	# re-read input
+	&mov	($s1,&DWP(4,$acc));
+	&mov	($s2,&DWP(8,$acc));
+	&mov	($s3,&DWP(12,$acc));
+
+	&mov	(&DWP(0,$key),$s0);	# copy it to iv
+	&mov	(&DWP(4,$key),$s1);
+	&mov	(&DWP(8,$key),$s2);
+	&mov	(&DWP(12,$key),$s3);
+
+	&mov	("ecx",$_len);
+	&mov	("edi",$_out);
+	&lea	("esi",$ivec);
+	&align	(4);
+	&data_word(0xA4F3F689);		# rep movsb # copy partial output
+
+	&mov	("esp",$_esp);
+	&popf	();
+&function_end("AES_cbc_encrypt");
+}
+
+#------------------------------------------------------------------#
+
+sub enckey()
+{
+	&movz	("esi",&LB("edx"));		# rk[i]>>0
+	&movz	("ebx",&BP(-128,$tbl,"esi",1));
+	&movz	("esi",&HB("edx"));		# rk[i]>>8
+	&shl	("ebx",24);
+	&xor	("eax","ebx");
+
+	&movz	("ebx",&BP(-128,$tbl,"esi",1));
+	&shr	("edx",16);
+	&movz	("esi",&LB("edx"));		# rk[i]>>16
+	&xor	("eax","ebx");
+
+	&movz	("ebx",&BP(-128,$tbl,"esi",1));
+	&movz	("esi",&HB("edx"));		# rk[i]>>24
+	&shl	("ebx",8);
+	&xor	("eax","ebx");
+
+	&movz	("ebx",&BP(-128,$tbl,"esi",1));
+	&shl	("ebx",16);
+	&xor	("eax","ebx");
+
+	&xor	("eax",&DWP(1024-128,$tbl,"ecx",4));	# rcon
+}
+
+&function_begin("_x86_AES_set_encrypt_key");
+	&mov	("esi",&wparam(1));		# user supplied key
+	&mov	("edi",&wparam(3));		# private key schedule
+
+	&test	("esi",-1);
+	&jz	(&label("badpointer"));
+	&test	("edi",-1);
+	&jz	(&label("badpointer"));
+
+	&call	(&label("pic_point"));
+	&set_label("pic_point");
+	&blindpop($tbl);
+	&lea	($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
+	&lea	($tbl,&DWP(2048+128,$tbl));
+
+	# prefetch Te4
+	&mov	("eax",&DWP(0-128,$tbl));
+	&mov	("ebx",&DWP(32-128,$tbl));
+	&mov	("ecx",&DWP(64-128,$tbl));
+	&mov	("edx",&DWP(96-128,$tbl));
+	&mov	("eax",&DWP(128-128,$tbl));
+	&mov	("ebx",&DWP(160-128,$tbl));
+	&mov	("ecx",&DWP(192-128,$tbl));
+	&mov	("edx",&DWP(224-128,$tbl));
+
+	&mov	("ecx",&wparam(2));		# number of bits in key
+	&cmp	("ecx",128);
+	&je	(&label("10rounds"));
+	&cmp	("ecx",192);
+	&je	(&label("12rounds"));
+	&cmp	("ecx",256);
+	&je	(&label("14rounds"));
+	&mov	("eax",-2);			# invalid number of bits
+	&jmp	(&label("exit"));
+
+    &set_label("10rounds");
+	&mov	("eax",&DWP(0,"esi"));		# copy first 4 dwords
+	&mov	("ebx",&DWP(4,"esi"));
+	&mov	("ecx",&DWP(8,"esi"));
+	&mov	("edx",&DWP(12,"esi"));
+	&mov	(&DWP(0,"edi"),"eax");
+	&mov	(&DWP(4,"edi"),"ebx");
+	&mov	(&DWP(8,"edi"),"ecx");
+	&mov	(&DWP(12,"edi"),"edx");
+
+	&xor	("ecx","ecx");
+	&jmp	(&label("10shortcut"));
+
+	&align	(4);
+	&set_label("10loop");
+		&mov	("eax",&DWP(0,"edi"));		# rk[0]
+		&mov	("edx",&DWP(12,"edi"));		# rk[3]
+	&set_label("10shortcut");
+		&enckey	();
+
+		&mov	(&DWP(16,"edi"),"eax");		# rk[4]
+		&xor	("eax",&DWP(4,"edi"));
+		&mov	(&DWP(20,"edi"),"eax");		# rk[5]
+		&xor	("eax",&DWP(8,"edi"));
+		&mov	(&DWP(24,"edi"),"eax");		# rk[6]
+		&xor	("eax",&DWP(12,"edi"));
+		&mov	(&DWP(28,"edi"),"eax");		# rk[7]
+		&inc	("ecx");
+		&add	("edi",16);
+		&cmp	("ecx",10);
+	&jl	(&label("10loop"));
+
+	&mov	(&DWP(80,"edi"),10);		# setup number of rounds
+	&xor	("eax","eax");
+	&jmp	(&label("exit"));
+		
+    &set_label("12rounds");
+	&mov	("eax",&DWP(0,"esi"));		# copy first 6 dwords
+	&mov	("ebx",&DWP(4,"esi"));
+	&mov	("ecx",&DWP(8,"esi"));
+	&mov	("edx",&DWP(12,"esi"));
+	&mov	(&DWP(0,"edi"),"eax");
+	&mov	(&DWP(4,"edi"),"ebx");
+	&mov	(&DWP(8,"edi"),"ecx");
+	&mov	(&DWP(12,"edi"),"edx");
+	&mov	("ecx",&DWP(16,"esi"));
+	&mov	("edx",&DWP(20,"esi"));
+	&mov	(&DWP(16,"edi"),"ecx");
+	&mov	(&DWP(20,"edi"),"edx");
+
+	&xor	("ecx","ecx");
+	&jmp	(&label("12shortcut"));
+
+	&align	(4);
+	&set_label("12loop");
+		&mov	("eax",&DWP(0,"edi"));		# rk[0]
+		&mov	("edx",&DWP(20,"edi"));		# rk[5]
+	&set_label("12shortcut");
+		&enckey	();
+
+		&mov	(&DWP(24,"edi"),"eax");		# rk[6]
+		&xor	("eax",&DWP(4,"edi"));
+		&mov	(&DWP(28,"edi"),"eax");		# rk[7]
+		&xor	("eax",&DWP(8,"edi"));
+		&mov	(&DWP(32,"edi"),"eax");		# rk[8]
+		&xor	("eax",&DWP(12,"edi"));
+		&mov	(&DWP(36,"edi"),"eax");		# rk[9]
+
+		&cmp	("ecx",7);
+		&je	(&label("12break"));
+		&inc	("ecx");
+
+		&xor	("eax",&DWP(16,"edi"));
+		&mov	(&DWP(40,"edi"),"eax");		# rk[10]
+		&xor	("eax",&DWP(20,"edi"));
+		&mov	(&DWP(44,"edi"),"eax");		# rk[11]
+
+		&add	("edi",24);
+	&jmp	(&label("12loop"));
+
+	&set_label("12break");
+	&mov	(&DWP(72,"edi"),12);		# setup number of rounds
+	&xor	("eax","eax");
+	&jmp	(&label("exit"));
+
+    &set_label("14rounds");
+	&mov	("eax",&DWP(0,"esi"));		# copy first 8 dwords
+	&mov	("ebx",&DWP(4,"esi"));
+	&mov	("ecx",&DWP(8,"esi"));
+	&mov	("edx",&DWP(12,"esi"));
+	&mov	(&DWP(0,"edi"),"eax");
+	&mov	(&DWP(4,"edi"),"ebx");
+	&mov	(&DWP(8,"edi"),"ecx");
+	&mov	(&DWP(12,"edi"),"edx");
+	&mov	("eax",&DWP(16,"esi"));
+	&mov	("ebx",&DWP(20,"esi"));
+	&mov	("ecx",&DWP(24,"esi"));
+	&mov	("edx",&DWP(28,"esi"));
+	&mov	(&DWP(16,"edi"),"eax");
+	&mov	(&DWP(20,"edi"),"ebx");
+	&mov	(&DWP(24,"edi"),"ecx");
+	&mov	(&DWP(28,"edi"),"edx");
+
+	&xor	("ecx","ecx");
+	&jmp	(&label("14shortcut"));
+
+	&align	(4);
+	&set_label("14loop");
+		&mov	("edx",&DWP(28,"edi"));		# rk[7]
+	&set_label("14shortcut");
+		&mov	("eax",&DWP(0,"edi"));		# rk[0]
+
+		&enckey	();
+
+		&mov	(&DWP(32,"edi"),"eax");		# rk[8]
+		&xor	("eax",&DWP(4,"edi"));
+		&mov	(&DWP(36,"edi"),"eax");		# rk[9]
+		&xor	("eax",&DWP(8,"edi"));
+		&mov	(&DWP(40,"edi"),"eax");		# rk[10]
+		&xor	("eax",&DWP(12,"edi"));
+		&mov	(&DWP(44,"edi"),"eax");		# rk[11]
+
+		&cmp	("ecx",6);
+		&je	(&label("14break"));
+		&inc	("ecx");
+
+		&mov	("edx","eax");
+		&mov	("eax",&DWP(16,"edi"));		# rk[4]
+		&movz	("esi",&LB("edx"));		# rk[11]>>0
+		&movz	("ebx",&BP(-128,$tbl,"esi",1));
+		&movz	("esi",&HB("edx"));		# rk[11]>>8
+		&xor	("eax","ebx");
+
+		&movz	("ebx",&BP(-128,$tbl,"esi",1));
+		&shr	("edx",16);
+		&shl	("ebx",8);
+		&movz	("esi",&LB("edx"));		# rk[11]>>16
+		&xor	("eax","ebx");
+
+		&movz	("ebx",&BP(-128,$tbl,"esi",1));
+		&movz	("esi",&HB("edx"));		# rk[11]>>24
+		&shl	("ebx",16);
+		&xor	("eax","ebx");
+
+		&movz	("ebx",&BP(-128,$tbl,"esi",1));
+		&shl	("ebx",24);
+		&xor	("eax","ebx");
+
+		&mov	(&DWP(48,"edi"),"eax");		# rk[12]
+		&xor	("eax",&DWP(20,"edi"));
+		&mov	(&DWP(52,"edi"),"eax");		# rk[13]
+		&xor	("eax",&DWP(24,"edi"));
+		&mov	(&DWP(56,"edi"),"eax");		# rk[14]
+		&xor	("eax",&DWP(28,"edi"));
+		&mov	(&DWP(60,"edi"),"eax");		# rk[15]
+
+		&add	("edi",32);
+	&jmp	(&label("14loop"));
+
+	&set_label("14break");
+	&mov	(&DWP(48,"edi"),14);		# setup number of rounds
+	&xor	("eax","eax");
+	&jmp	(&label("exit"));
+
+    &set_label("badpointer");
+	&mov	("eax",-1);
+    &set_label("exit");
+&function_end("_x86_AES_set_encrypt_key");
+
+# int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+#                        AES_KEY *key)
+&function_begin_B("AES_set_encrypt_key");
+	&call	("_x86_AES_set_encrypt_key");
+	&ret	();
+&function_end_B("AES_set_encrypt_key");
+
+sub deckey()
+{ my ($i,$key,$tp1,$tp2,$tp4,$tp8) = @_;
+  my $tmp = $tbl;
+
+	&mov	($acc,$tp1);
+	&and	($acc,0x80808080);
+	&mov	($tmp,$acc);
+	&shr	($tmp,7);
+	&lea	($tp2,&DWP(0,$tp1,$tp1));
+	&sub	($acc,$tmp);
+	&and	($tp2,0xfefefefe);
+	&and	($acc,0x1b1b1b1b);
+	&xor	($acc,$tp2);
+	&mov	($tp2,$acc);
+
+	&and	($acc,0x80808080);
+	&mov	($tmp,$acc);
+	&shr	($tmp,7);
+	&lea	($tp4,&DWP(0,$tp2,$tp2));
+	&sub	($acc,$tmp);
+	&and	($tp4,0xfefefefe);
+	&and	($acc,0x1b1b1b1b);
+	 &xor	($tp2,$tp1);	# tp2^tp1
+	&xor	($acc,$tp4);
+	&mov	($tp4,$acc);
+
+	&and	($acc,0x80808080);
+	&mov	($tmp,$acc);
+	&shr	($tmp,7);
+	&lea	($tp8,&DWP(0,$tp4,$tp4));
+	 &xor	($tp4,$tp1);	# tp4^tp1
+	&sub	($acc,$tmp);
+	&and	($tp8,0xfefefefe);
+	&and	($acc,0x1b1b1b1b);
+	 &rotl	($tp1,8);	# = ROTATE(tp1,8)
+	&xor	($tp8,$acc);
+
+	&mov	($tmp,&DWP(4*($i+1),$key));	# modulo-scheduled load
+
+	&xor	($tp1,$tp2);
+	&xor	($tp2,$tp8);
+	&xor	($tp1,$tp4);
+	&rotl	($tp2,24);
+	&xor	($tp4,$tp8);
+	&xor	($tp1,$tp8);	# ^= tp8^(tp4^tp1)^(tp2^tp1)
+	&rotl	($tp4,16);
+	&xor	($tp1,$tp2);	# ^= ROTATE(tp8^tp2^tp1,24)
+	&rotl	($tp8,8);
+	&xor	($tp1,$tp4);	# ^= ROTATE(tp8^tp4^tp1,16)
+	&mov	($tp2,$tmp);
+	&xor	($tp1,$tp8);	# ^= ROTATE(tp8,8)
+
+	&mov	(&DWP(4*$i,$key),$tp1);
+}
+
+# int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+#                        AES_KEY *key)
+&function_begin_B("AES_set_decrypt_key");
+	&call	("_x86_AES_set_encrypt_key");
+	&cmp	("eax",0);
+	&je	(&label("proceed"));
+	&ret	();
+
+    &set_label("proceed");
+	&push	("ebp");
+	&push	("ebx");
+	&push	("esi");
+	&push	("edi");
+
+	&mov	("esi",&wparam(2));
+	&mov	("ecx",&DWP(240,"esi"));	# pull number of rounds
+	&lea	("ecx",&DWP(0,"","ecx",4));
+	&lea	("edi",&DWP(0,"esi","ecx",4));	# pointer to last chunk
+
+	&set_label("invert",4);			# invert order of chunks
+		&mov	("eax",&DWP(0,"esi"));
+		&mov	("ebx",&DWP(4,"esi"));
+		&mov	("ecx",&DWP(0,"edi"));
+		&mov	("edx",&DWP(4,"edi"));
+		&mov	(&DWP(0,"edi"),"eax");
+		&mov	(&DWP(4,"edi"),"ebx");
+		&mov	(&DWP(0,"esi"),"ecx");
+		&mov	(&DWP(4,"esi"),"edx");
+		&mov	("eax",&DWP(8,"esi"));
+		&mov	("ebx",&DWP(12,"esi"));
+		&mov	("ecx",&DWP(8,"edi"));
+		&mov	("edx",&DWP(12,"edi"));
+		&mov	(&DWP(8,"edi"),"eax");
+		&mov	(&DWP(12,"edi"),"ebx");
+		&mov	(&DWP(8,"esi"),"ecx");
+		&mov	(&DWP(12,"esi"),"edx");
+		&add	("esi",16);
+		&sub	("edi",16);
+		&cmp	("esi","edi");
+	&jne	(&label("invert"));
+
+	&mov	($key,&wparam(2));
+	&mov	($acc,&DWP(240,$key));		# pull number of rounds
+	&lea	($acc,&DWP(-2,$acc,$acc));
+	&lea	($acc,&DWP(0,$key,$acc,8));
+	&mov	(&wparam(2),$acc);
+
+	&mov	($s0,&DWP(16,$key));		# modulo-scheduled load
+	&set_label("permute",4);		# permute the key schedule
+		&add	($key,16);
+		&deckey	(0,$key,$s0,$s1,$s2,$s3);
+		&deckey	(1,$key,$s1,$s2,$s3,$s0);
+		&deckey	(2,$key,$s2,$s3,$s0,$s1);
+		&deckey	(3,$key,$s3,$s0,$s1,$s2);
+		&cmp	($key,&wparam(2));
+	&jb	(&label("permute"));
+
+	&xor	("eax","eax");			# return success
+&function_end("AES_set_decrypt_key");
+&asciz("AES for x86, CRYPTOGAMS by <appro\@openssl.org>");
+
+&asm_finish();
diff --git a/openssl/crypto/aes/asm/aes-armv4.pl b/openssl/crypto/aes/asm/aes-armv4.pl
new file mode 100644
index 0000000..c51ee1f
--- /dev/null
+++ b/openssl/crypto/aes/asm/aes-armv4.pl
@@ -0,0 +1,1030 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# AES for ARMv4
+
+# January 2007.
+#
+# Code uses single 1K S-box and is >2 times faster than code generated
+# by gcc-3.4.1. This is thanks to unique feature of ARMv4 ISA, which
+# allows to merge logical or arithmetic operation with shift or rotate
+# in one instruction and emit combined result every cycle. The module
+# is endian-neutral. The performance is ~42 cycles/byte for 128-bit
+# key [on single-issue Xscale PXA250 core].
+
+# May 2007.
+#
+# AES_set_[en|de]crypt_key is added.
+
+# July 2010.
+#
+# Rescheduling for dual-issue pipeline resulted in 12% improvement on
+# Cortex A8 core and ~25 cycles per byte processed with 128-bit key.
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
+$s0="r0";
+$s1="r1";
+$s2="r2";
+$s3="r3";
+$t1="r4";
+$t2="r5";
+$t3="r6";
+$i1="r7";
+$i2="r8";
+$i3="r9";
+
+$tbl="r10";
+$key="r11";
+$rounds="r12";
+
+$code=<<___;
+.text
+.code	32
+
+.type	AES_Te,%object
+.align	5
+AES_Te:
+.word	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d
+.word	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554
+.word	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d
+.word	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a
+.word	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87
+.word	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b
+.word	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea
+.word	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b
+.word	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a
+.word	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f
+.word	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108
+.word	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f
+.word	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e
+.word	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5
+.word	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d
+.word	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f
+.word	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e
+.word	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb
+.word	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce
+.word	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497
+.word	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c
+.word	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed
+.word	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b
+.word	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a
+.word	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16
+.word	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594
+.word	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81
+.word	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3
+.word	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a
+.word	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504
+.word	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163
+.word	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d
+.word	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f
+.word	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739
+.word	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47
+.word	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395
+.word	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f
+.word	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883
+.word	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c
+.word	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76
+.word	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e
+.word	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4
+.word	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6
+.word	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b
+.word	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7
+.word	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0
+.word	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25
+.word	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818
+.word	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72
+.word	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651
+.word	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21
+.word	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85
+.word	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa
+.word	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12
+.word	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0
+.word	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9
+.word	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133
+.word	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7
+.word	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920
+.word	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a
+.word	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17
+.word	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8
+.word	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11
+.word	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
+@ Te4[256]
+.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
+.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
+.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
+.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
+.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
+.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
+.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
+.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
+.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
+.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
+.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
+.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
+.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
+.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
+.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
+.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+@ rcon[]
+.word	0x01000000, 0x02000000, 0x04000000, 0x08000000
+.word	0x10000000, 0x20000000, 0x40000000, 0x80000000
+.word	0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
+.size	AES_Te,.-AES_Te
+
+@ void AES_encrypt(const unsigned char *in, unsigned char *out,
+@ 		 const AES_KEY *key) {
+.global AES_encrypt
+.type   AES_encrypt,%function
+.align	5
+AES_encrypt:
+	sub	r3,pc,#8		@ AES_encrypt
+	stmdb   sp!,{r1,r4-r12,lr}
+	mov	$rounds,r0		@ inp
+	mov	$key,r2
+	sub	$tbl,r3,#AES_encrypt-AES_Te	@ Te
+
+	ldrb	$s0,[$rounds,#3]	@ load input data in endian-neutral
+	ldrb	$t1,[$rounds,#2]	@ manner...
+	ldrb	$t2,[$rounds,#1]
+	ldrb	$t3,[$rounds,#0]
+	orr	$s0,$s0,$t1,lsl#8
+	ldrb	$s1,[$rounds,#7]
+	orr	$s0,$s0,$t2,lsl#16
+	ldrb	$t1,[$rounds,#6]
+	orr	$s0,$s0,$t3,lsl#24
+	ldrb	$t2,[$rounds,#5]
+	ldrb	$t3,[$rounds,#4]
+	orr	$s1,$s1,$t1,lsl#8
+	ldrb	$s2,[$rounds,#11]
+	orr	$s1,$s1,$t2,lsl#16
+	ldrb	$t1,[$rounds,#10]
+	orr	$s1,$s1,$t3,lsl#24
+	ldrb	$t2,[$rounds,#9]
+	ldrb	$t3,[$rounds,#8]
+	orr	$s2,$s2,$t1,lsl#8
+	ldrb	$s3,[$rounds,#15]
+	orr	$s2,$s2,$t2,lsl#16
+	ldrb	$t1,[$rounds,#14]
+	orr	$s2,$s2,$t3,lsl#24
+	ldrb	$t2,[$rounds,#13]
+	ldrb	$t3,[$rounds,#12]
+	orr	$s3,$s3,$t1,lsl#8
+	orr	$s3,$s3,$t2,lsl#16
+	orr	$s3,$s3,$t3,lsl#24
+
+	bl	_armv4_AES_encrypt
+
+	ldr	$rounds,[sp],#4		@ pop out
+	mov	$t1,$s0,lsr#24		@ write output in endian-neutral
+	mov	$t2,$s0,lsr#16		@ manner...
+	mov	$t3,$s0,lsr#8
+	strb	$t1,[$rounds,#0]
+	strb	$t2,[$rounds,#1]
+	mov	$t1,$s1,lsr#24
+	strb	$t3,[$rounds,#2]
+	mov	$t2,$s1,lsr#16
+	strb	$s0,[$rounds,#3]
+	mov	$t3,$s1,lsr#8
+	strb	$t1,[$rounds,#4]
+	strb	$t2,[$rounds,#5]
+	mov	$t1,$s2,lsr#24
+	strb	$t3,[$rounds,#6]
+	mov	$t2,$s2,lsr#16
+	strb	$s1,[$rounds,#7]
+	mov	$t3,$s2,lsr#8
+	strb	$t1,[$rounds,#8]
+	strb	$t2,[$rounds,#9]
+	mov	$t1,$s3,lsr#24
+	strb	$t3,[$rounds,#10]
+	mov	$t2,$s3,lsr#16
+	strb	$s2,[$rounds,#11]
+	mov	$t3,$s3,lsr#8
+	strb	$t1,[$rounds,#12]
+	strb	$t2,[$rounds,#13]
+	strb	$t3,[$rounds,#14]
+	strb	$s3,[$rounds,#15]
+
+	ldmia   sp!,{r4-r12,lr}
+	tst	lr,#1
+	moveq	pc,lr			@ be binary compatible with V4, yet
+	bx	lr			@ interoperable with Thumb ISA:-)
+.size	AES_encrypt,.-AES_encrypt
+
+.type   _armv4_AES_encrypt,%function
+.align	2
+_armv4_AES_encrypt:
+	str	lr,[sp,#-4]!		@ push lr
+	ldmia	$key!,{$t1-$i1}
+	eor	$s0,$s0,$t1
+	ldr	$rounds,[$key,#240-16]
+	eor	$s1,$s1,$t2
+	eor	$s2,$s2,$t3
+	eor	$s3,$s3,$i1
+	sub	$rounds,$rounds,#1
+	mov	lr,#255
+
+	and	$i1,lr,$s0
+	and	$i2,lr,$s0,lsr#8
+	and	$i3,lr,$s0,lsr#16
+	mov	$s0,$s0,lsr#24
+.Lenc_loop:
+	ldr	$t1,[$tbl,$i1,lsl#2]	@ Te3[s0>>0]
+	and	$i1,lr,$s1,lsr#16	@ i0
+	ldr	$t2,[$tbl,$i2,lsl#2]	@ Te2[s0>>8]
+	and	$i2,lr,$s1
+	ldr	$t3,[$tbl,$i3,lsl#2]	@ Te1[s0>>16]
+	and	$i3,lr,$s1,lsr#8
+	ldr	$s0,[$tbl,$s0,lsl#2]	@ Te0[s0>>24]
+	mov	$s1,$s1,lsr#24
+
+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Te1[s1>>16]
+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Te3[s1>>0]
+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Te2[s1>>8]
+	eor	$s0,$s0,$i1,ror#8
+	ldr	$s1,[$tbl,$s1,lsl#2]	@ Te0[s1>>24]
+	and	$i1,lr,$s2,lsr#8	@ i0
+	eor	$t2,$t2,$i2,ror#8
+	and	$i2,lr,$s2,lsr#16	@ i1
+	eor	$t3,$t3,$i3,ror#8
+	and	$i3,lr,$s2
+	eor	$s1,$s1,$t1,ror#24
+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Te2[s2>>8]
+	mov	$s2,$s2,lsr#24
+
+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Te1[s2>>16]
+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Te3[s2>>0]
+	eor	$s0,$s0,$i1,ror#16
+	ldr	$s2,[$tbl,$s2,lsl#2]	@ Te0[s2>>24]
+	and	$i1,lr,$s3		@ i0
+	eor	$s1,$s1,$i2,ror#8
+	and	$i2,lr,$s3,lsr#8	@ i1
+	eor	$t3,$t3,$i3,ror#16
+	and	$i3,lr,$s3,lsr#16	@ i2
+	eor	$s2,$s2,$t2,ror#16
+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Te3[s3>>0]
+	mov	$s3,$s3,lsr#24
+
+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Te2[s3>>8]
+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Te1[s3>>16]
+	eor	$s0,$s0,$i1,ror#24
+	ldr	$s3,[$tbl,$s3,lsl#2]	@ Te0[s3>>24]
+	eor	$s1,$s1,$i2,ror#16
+	ldr	$i1,[$key],#16
+	eor	$s2,$s2,$i3,ror#8
+	ldr	$t1,[$key,#-12]
+	eor	$s3,$s3,$t3,ror#8
+
+	ldr	$t2,[$key,#-8]
+	eor	$s0,$s0,$i1
+	ldr	$t3,[$key,#-4]
+	and	$i1,lr,$s0
+	eor	$s1,$s1,$t1
+	and	$i2,lr,$s0,lsr#8
+	eor	$s2,$s2,$t2
+	and	$i3,lr,$s0,lsr#16
+	eor	$s3,$s3,$t3
+	mov	$s0,$s0,lsr#24
+
+	subs	$rounds,$rounds,#1
+	bne	.Lenc_loop
+
+	add	$tbl,$tbl,#2
+
+	ldrb	$t1,[$tbl,$i1,lsl#2]	@ Te4[s0>>0]
+	and	$i1,lr,$s1,lsr#16	@ i0
+	ldrb	$t2,[$tbl,$i2,lsl#2]	@ Te4[s0>>8]
+	and	$i2,lr,$s1
+	ldrb	$t3,[$tbl,$i3,lsl#2]	@ Te4[s0>>16]
+	and	$i3,lr,$s1,lsr#8
+	ldrb	$s0,[$tbl,$s0,lsl#2]	@ Te4[s0>>24]
+	mov	$s1,$s1,lsr#24
+
+	ldrb	$i1,[$tbl,$i1,lsl#2]	@ Te4[s1>>16]
+	ldrb	$i2,[$tbl,$i2,lsl#2]	@ Te4[s1>>0]
+	ldrb	$i3,[$tbl,$i3,lsl#2]	@ Te4[s1>>8]
+	eor	$s0,$i1,$s0,lsl#8
+	ldrb	$s1,[$tbl,$s1,lsl#2]	@ Te4[s1>>24]
+	and	$i1,lr,$s2,lsr#8	@ i0
+	eor	$t2,$i2,$t2,lsl#8
+	and	$i2,lr,$s2,lsr#16	@ i1
+	eor	$t3,$i3,$t3,lsl#8
+	and	$i3,lr,$s2
+	eor	$s1,$t1,$s1,lsl#24
+	ldrb	$i1,[$tbl,$i1,lsl#2]	@ Te4[s2>>8]
+	mov	$s2,$s2,lsr#24
+
+	ldrb	$i2,[$tbl,$i2,lsl#2]	@ Te4[s2>>16]
+	ldrb	$i3,[$tbl,$i3,lsl#2]	@ Te4[s2>>0]
+	eor	$s0,$i1,$s0,lsl#8
+	ldrb	$s2,[$tbl,$s2,lsl#2]	@ Te4[s2>>24]
+	and	$i1,lr,$s3		@ i0
+	eor	$s1,$s1,$i2,lsl#16
+	and	$i2,lr,$s3,lsr#8	@ i1
+	eor	$t3,$i3,$t3,lsl#8
+	and	$i3,lr,$s3,lsr#16	@ i2
+	eor	$s2,$t2,$s2,lsl#24
+	ldrb	$i1,[$tbl,$i1,lsl#2]	@ Te4[s3>>0]
+	mov	$s3,$s3,lsr#24
+
+	ldrb	$i2,[$tbl,$i2,lsl#2]	@ Te4[s3>>8]
+	ldrb	$i3,[$tbl,$i3,lsl#2]	@ Te4[s3>>16]
+	eor	$s0,$i1,$s0,lsl#8
+	ldrb	$s3,[$tbl,$s3,lsl#2]	@ Te4[s3>>24]
+	ldr	$i1,[$key,#0]
+	eor	$s1,$s1,$i2,lsl#8
+	ldr	$t1,[$key,#4]
+	eor	$s2,$s2,$i3,lsl#16
+	ldr	$t2,[$key,#8]
+	eor	$s3,$t3,$s3,lsl#24
+	ldr	$t3,[$key,#12]
+
+	eor	$s0,$s0,$i1
+	eor	$s1,$s1,$t1
+	eor	$s2,$s2,$t2
+	eor	$s3,$s3,$t3
+
+	sub	$tbl,$tbl,#2
+	ldr	pc,[sp],#4		@ pop and return
+.size	_armv4_AES_encrypt,.-_armv4_AES_encrypt
+
+.global AES_set_encrypt_key
+.type   AES_set_encrypt_key,%function
+.align	5
+AES_set_encrypt_key:
+	sub	r3,pc,#8		@ AES_set_encrypt_key
+	teq	r0,#0
+	moveq	r0,#-1
+	beq	.Labrt
+	teq	r2,#0
+	moveq	r0,#-1
+	beq	.Labrt
+
+	teq	r1,#128
+	beq	.Lok
+	teq	r1,#192
+	beq	.Lok
+	teq	r1,#256
+	movne	r0,#-1
+	bne	.Labrt
+
+.Lok:	stmdb   sp!,{r4-r12,lr}
+	sub	$tbl,r3,#AES_set_encrypt_key-AES_Te-1024	@ Te4
+
+	mov	$rounds,r0		@ inp
+	mov	lr,r1			@ bits
+	mov	$key,r2			@ key
+
+	ldrb	$s0,[$rounds,#3]	@ load input data in endian-neutral
+	ldrb	$t1,[$rounds,#2]	@ manner...
+	ldrb	$t2,[$rounds,#1]
+	ldrb	$t3,[$rounds,#0]
+	orr	$s0,$s0,$t1,lsl#8
+	ldrb	$s1,[$rounds,#7]
+	orr	$s0,$s0,$t2,lsl#16
+	ldrb	$t1,[$rounds,#6]
+	orr	$s0,$s0,$t3,lsl#24
+	ldrb	$t2,[$rounds,#5]
+	ldrb	$t3,[$rounds,#4]
+	orr	$s1,$s1,$t1,lsl#8
+	ldrb	$s2,[$rounds,#11]
+	orr	$s1,$s1,$t2,lsl#16
+	ldrb	$t1,[$rounds,#10]
+	orr	$s1,$s1,$t3,lsl#24
+	ldrb	$t2,[$rounds,#9]
+	ldrb	$t3,[$rounds,#8]
+	orr	$s2,$s2,$t1,lsl#8
+	ldrb	$s3,[$rounds,#15]
+	orr	$s2,$s2,$t2,lsl#16
+	ldrb	$t1,[$rounds,#14]
+	orr	$s2,$s2,$t3,lsl#24
+	ldrb	$t2,[$rounds,#13]
+	ldrb	$t3,[$rounds,#12]
+	orr	$s3,$s3,$t1,lsl#8
+	str	$s0,[$key],#16
+	orr	$s3,$s3,$t2,lsl#16
+	str	$s1,[$key,#-12]
+	orr	$s3,$s3,$t3,lsl#24
+	str	$s2,[$key,#-8]
+	str	$s3,[$key,#-4]
+
+	teq	lr,#128
+	bne	.Lnot128
+	mov	$rounds,#10
+	str	$rounds,[$key,#240-16]
+	add	$t3,$tbl,#256			@ rcon
+	mov	lr,#255
+
+.L128_loop:
+	and	$t2,lr,$s3,lsr#24
+	and	$i1,lr,$s3,lsr#16
+	ldrb	$t2,[$tbl,$t2]
+	and	$i2,lr,$s3,lsr#8
+	ldrb	$i1,[$tbl,$i1]
+	and	$i3,lr,$s3
+	ldrb	$i2,[$tbl,$i2]
+	orr	$t2,$t2,$i1,lsl#24
+	ldrb	$i3,[$tbl,$i3]
+	orr	$t2,$t2,$i2,lsl#16
+	ldr	$t1,[$t3],#4			@ rcon[i++]
+	orr	$t2,$t2,$i3,lsl#8
+	eor	$t2,$t2,$t1
+	eor	$s0,$s0,$t2			@ rk[4]=rk[0]^...
+	eor	$s1,$s1,$s0			@ rk[5]=rk[1]^rk[4]
+	str	$s0,[$key],#16
+	eor	$s2,$s2,$s1			@ rk[6]=rk[2]^rk[5]
+	str	$s1,[$key,#-12]
+	eor	$s3,$s3,$s2			@ rk[7]=rk[3]^rk[6]
+	str	$s2,[$key,#-8]
+	subs	$rounds,$rounds,#1
+	str	$s3,[$key,#-4]
+	bne	.L128_loop
+	sub	r2,$key,#176
+	b	.Ldone
+
+.Lnot128:
+	ldrb	$i2,[$rounds,#19]
+	ldrb	$t1,[$rounds,#18]
+	ldrb	$t2,[$rounds,#17]
+	ldrb	$t3,[$rounds,#16]
+	orr	$i2,$i2,$t1,lsl#8
+	ldrb	$i3,[$rounds,#23]
+	orr	$i2,$i2,$t2,lsl#16
+	ldrb	$t1,[$rounds,#22]
+	orr	$i2,$i2,$t3,lsl#24
+	ldrb	$t2,[$rounds,#21]
+	ldrb	$t3,[$rounds,#20]
+	orr	$i3,$i3,$t1,lsl#8
+	orr	$i3,$i3,$t2,lsl#16
+	str	$i2,[$key],#8
+	orr	$i3,$i3,$t3,lsl#24
+	str	$i3,[$key,#-4]
+
+	teq	lr,#192
+	bne	.Lnot192
+	mov	$rounds,#12
+	str	$rounds,[$key,#240-24]
+	add	$t3,$tbl,#256			@ rcon
+	mov	lr,#255
+	mov	$rounds,#8
+
+.L192_loop:
+	and	$t2,lr,$i3,lsr#24
+	and	$i1,lr,$i3,lsr#16
+	ldrb	$t2,[$tbl,$t2]
+	and	$i2,lr,$i3,lsr#8
+	ldrb	$i1,[$tbl,$i1]
+	and	$i3,lr,$i3
+	ldrb	$i2,[$tbl,$i2]
+	orr	$t2,$t2,$i1,lsl#24
+	ldrb	$i3,[$tbl,$i3]
+	orr	$t2,$t2,$i2,lsl#16
+	ldr	$t1,[$t3],#4			@ rcon[i++]
+	orr	$t2,$t2,$i3,lsl#8
+	eor	$i3,$t2,$t1
+	eor	$s0,$s0,$i3			@ rk[6]=rk[0]^...
+	eor	$s1,$s1,$s0			@ rk[7]=rk[1]^rk[6]
+	str	$s0,[$key],#24
+	eor	$s2,$s2,$s1			@ rk[8]=rk[2]^rk[7]
+	str	$s1,[$key,#-20]
+	eor	$s3,$s3,$s2			@ rk[9]=rk[3]^rk[8]
+	str	$s2,[$key,#-16]
+	subs	$rounds,$rounds,#1
+	str	$s3,[$key,#-12]
+	subeq	r2,$key,#216
+	beq	.Ldone
+
+	ldr	$i1,[$key,#-32]
+	ldr	$i2,[$key,#-28]
+	eor	$i1,$i1,$s3			@ rk[10]=rk[4]^rk[9]
+	eor	$i3,$i2,$i1			@ rk[11]=rk[5]^rk[10]
+	str	$i1,[$key,#-8]
+	str	$i3,[$key,#-4]
+	b	.L192_loop
+
+.Lnot192:
+	ldrb	$i2,[$rounds,#27]
+	ldrb	$t1,[$rounds,#26]
+	ldrb	$t2,[$rounds,#25]
+	ldrb	$t3,[$rounds,#24]
+	orr	$i2,$i2,$t1,lsl#8
+	ldrb	$i3,[$rounds,#31]
+	orr	$i2,$i2,$t2,lsl#16
+	ldrb	$t1,[$rounds,#30]
+	orr	$i2,$i2,$t3,lsl#24
+	ldrb	$t2,[$rounds,#29]
+	ldrb	$t3,[$rounds,#28]
+	orr	$i3,$i3,$t1,lsl#8
+	orr	$i3,$i3,$t2,lsl#16
+	str	$i2,[$key],#8
+	orr	$i3,$i3,$t3,lsl#24
+	str	$i3,[$key,#-4]
+
+	mov	$rounds,#14
+	str	$rounds,[$key,#240-32]
+	add	$t3,$tbl,#256			@ rcon
+	mov	lr,#255
+	mov	$rounds,#7
+
+.L256_loop:
+	and	$t2,lr,$i3,lsr#24
+	and	$i1,lr,$i3,lsr#16
+	ldrb	$t2,[$tbl,$t2]
+	and	$i2,lr,$i3,lsr#8
+	ldrb	$i1,[$tbl,$i1]
+	and	$i3,lr,$i3
+	ldrb	$i2,[$tbl,$i2]
+	orr	$t2,$t2,$i1,lsl#24
+	ldrb	$i3,[$tbl,$i3]
+	orr	$t2,$t2,$i2,lsl#16
+	ldr	$t1,[$t3],#4			@ rcon[i++]
+	orr	$t2,$t2,$i3,lsl#8
+	eor	$i3,$t2,$t1
+	eor	$s0,$s0,$i3			@ rk[8]=rk[0]^...
+	eor	$s1,$s1,$s0			@ rk[9]=rk[1]^rk[8]
+	str	$s0,[$key],#32
+	eor	$s2,$s2,$s1			@ rk[10]=rk[2]^rk[9]
+	str	$s1,[$key,#-28]
+	eor	$s3,$s3,$s2			@ rk[11]=rk[3]^rk[10]
+	str	$s2,[$key,#-24]
+	subs	$rounds,$rounds,#1
+	str	$s3,[$key,#-20]
+	subeq	r2,$key,#256
+	beq	.Ldone
+
+	and	$t2,lr,$s3
+	and	$i1,lr,$s3,lsr#8
+	ldrb	$t2,[$tbl,$t2]
+	and	$i2,lr,$s3,lsr#16
+	ldrb	$i1,[$tbl,$i1]
+	and	$i3,lr,$s3,lsr#24
+	ldrb	$i2,[$tbl,$i2]
+	orr	$t2,$t2,$i1,lsl#8
+	ldrb	$i3,[$tbl,$i3]
+	orr	$t2,$t2,$i2,lsl#16
+	ldr	$t1,[$key,#-48]
+	orr	$t2,$t2,$i3,lsl#24
+
+	ldr	$i1,[$key,#-44]
+	ldr	$i2,[$key,#-40]
+	eor	$t1,$t1,$t2			@ rk[12]=rk[4]^...
+	ldr	$i3,[$key,#-36]
+	eor	$i1,$i1,$t1			@ rk[13]=rk[5]^rk[12]
+	str	$t1,[$key,#-16]
+	eor	$i2,$i2,$i1			@ rk[14]=rk[6]^rk[13]
+	str	$i1,[$key,#-12]
+	eor	$i3,$i3,$i2			@ rk[15]=rk[7]^rk[14]
+	str	$i2,[$key,#-8]
+	str	$i3,[$key,#-4]
+	b	.L256_loop
+
+.Ldone:	mov	r0,#0
+	ldmia   sp!,{r4-r12,lr}
+.Labrt:	tst	lr,#1
+	moveq	pc,lr			@ be binary compatible with V4, yet
+	bx	lr			@ interoperable with Thumb ISA:-)
+.size	AES_set_encrypt_key,.-AES_set_encrypt_key
+
+.global AES_set_decrypt_key
+.type   AES_set_decrypt_key,%function
+.align	5
+AES_set_decrypt_key:
+	str	lr,[sp,#-4]!            @ push lr
+	bl	AES_set_encrypt_key
+	teq	r0,#0
+	ldrne	lr,[sp],#4              @ pop lr
+	bne	.Labrt
+
+	stmdb   sp!,{r4-r12}
+
+	ldr	$rounds,[r2,#240]	@ AES_set_encrypt_key preserves r2,
+	mov	$key,r2			@ which is AES_KEY *key
+	mov	$i1,r2
+	add	$i2,r2,$rounds,lsl#4
+
+.Linv:	ldr	$s0,[$i1]
+	ldr	$s1,[$i1,#4]
+	ldr	$s2,[$i1,#8]
+	ldr	$s3,[$i1,#12]
+	ldr	$t1,[$i2]
+	ldr	$t2,[$i2,#4]
+	ldr	$t3,[$i2,#8]
+	ldr	$i3,[$i2,#12]
+	str	$s0,[$i2],#-16
+	str	$s1,[$i2,#16+4]
+	str	$s2,[$i2,#16+8]
+	str	$s3,[$i2,#16+12]
+	str	$t1,[$i1],#16
+	str	$t2,[$i1,#-12]
+	str	$t3,[$i1,#-8]
+	str	$i3,[$i1,#-4]
+	teq	$i1,$i2
+	bne	.Linv
+___
+$mask80=$i1;
+$mask1b=$i2;
+$mask7f=$i3;
+$code.=<<___;
+	ldr	$s0,[$key,#16]!		@ prefetch tp1
+	mov	$mask80,#0x80
+	mov	$mask1b,#0x1b
+	orr	$mask80,$mask80,#0x8000
+	orr	$mask1b,$mask1b,#0x1b00
+	orr	$mask80,$mask80,$mask80,lsl#16
+	orr	$mask1b,$mask1b,$mask1b,lsl#16
+	sub	$rounds,$rounds,#1
+	mvn	$mask7f,$mask80
+	mov	$rounds,$rounds,lsl#2	@ (rounds-1)*4
+
+.Lmix:	and	$t1,$s0,$mask80
+	and	$s1,$s0,$mask7f
+	sub	$t1,$t1,$t1,lsr#7
+	and	$t1,$t1,$mask1b
+	eor	$s1,$t1,$s1,lsl#1	@ tp2
+
+	and	$t1,$s1,$mask80
+	and	$s2,$s1,$mask7f
+	sub	$t1,$t1,$t1,lsr#7
+	and	$t1,$t1,$mask1b
+	eor	$s2,$t1,$s2,lsl#1	@ tp4
+
+	and	$t1,$s2,$mask80
+	and	$s3,$s2,$mask7f
+	sub	$t1,$t1,$t1,lsr#7
+	and	$t1,$t1,$mask1b
+	eor	$s3,$t1,$s3,lsl#1	@ tp8
+
+	eor	$t1,$s1,$s2
+	eor	$t2,$s0,$s3		@ tp9
+	eor	$t1,$t1,$s3		@ tpe
+	eor	$t1,$t1,$s1,ror#24
+	eor	$t1,$t1,$t2,ror#24	@ ^= ROTATE(tpb=tp9^tp2,8)
+	eor	$t1,$t1,$s2,ror#16
+	eor	$t1,$t1,$t2,ror#16	@ ^= ROTATE(tpd=tp9^tp4,16)
+	eor	$t1,$t1,$t2,ror#8	@ ^= ROTATE(tp9,24)
+
+	ldr	$s0,[$key,#4]		@ prefetch tp1
+	str	$t1,[$key],#4
+	subs	$rounds,$rounds,#1
+	bne	.Lmix
+
+	mov	r0,#0
+	ldmia   sp!,{r4-r12,lr}
+	tst	lr,#1
+	moveq	pc,lr			@ be binary compatible with V4, yet
+	bx	lr			@ interoperable with Thumb ISA:-)
+.size	AES_set_decrypt_key,.-AES_set_decrypt_key
+
+.type	AES_Td,%object
+.align	5
+AES_Td:
+.word	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96
+.word	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393
+.word	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25
+.word	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f
+.word	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1
+.word	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6
+.word	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da
+.word	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844
+.word	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd
+.word	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4
+.word	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45
+.word	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94
+.word	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7
+.word	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a
+.word	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5
+.word	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c
+.word	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1
+.word	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a
+.word	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75
+.word	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051
+.word	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46
+.word	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff
+.word	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77
+.word	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb
+.word	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000
+.word	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e
+.word	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927
+.word	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a
+.word	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e
+.word	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16
+.word	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d
+.word	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8
+.word	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd
+.word	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34
+.word	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163
+.word	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120
+.word	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d
+.word	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0
+.word	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422
+.word	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef
+.word	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36
+.word	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4
+.word	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662
+.word	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5
+.word	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3
+.word	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b
+.word	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8
+.word	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6
+.word	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6
+.word	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0
+.word	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815
+.word	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f
+.word	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df
+.word	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f
+.word	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e
+.word	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713
+.word	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89
+.word	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c
+.word	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf
+.word	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86
+.word	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f
+.word	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541
+.word	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190
+.word	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
+@ Td4[256]
+.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
+.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
+.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
+.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
+.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
+.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
+.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
+.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
+.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
+.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
+.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
+.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
+.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
+.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
+.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
+.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
+.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+.size	AES_Td,.-AES_Td
+
+@ void AES_decrypt(const unsigned char *in, unsigned char *out,
+@ 		 const AES_KEY *key) {
+.global AES_decrypt
+.type   AES_decrypt,%function
+.align	5
+AES_decrypt:
+	sub	r3,pc,#8		@ AES_decrypt
+	stmdb   sp!,{r1,r4-r12,lr}
+	mov	$rounds,r0		@ inp
+	mov	$key,r2
+	sub	$tbl,r3,#AES_decrypt-AES_Td		@ Td
+
+	ldrb	$s0,[$rounds,#3]	@ load input data in endian-neutral
+	ldrb	$t1,[$rounds,#2]	@ manner...
+	ldrb	$t2,[$rounds,#1]
+	ldrb	$t3,[$rounds,#0]
+	orr	$s0,$s0,$t1,lsl#8
+	ldrb	$s1,[$rounds,#7]
+	orr	$s0,$s0,$t2,lsl#16
+	ldrb	$t1,[$rounds,#6]
+	orr	$s0,$s0,$t3,lsl#24
+	ldrb	$t2,[$rounds,#5]
+	ldrb	$t3,[$rounds,#4]
+	orr	$s1,$s1,$t1,lsl#8
+	ldrb	$s2,[$rounds,#11]
+	orr	$s1,$s1,$t2,lsl#16
+	ldrb	$t1,[$rounds,#10]
+	orr	$s1,$s1,$t3,lsl#24
+	ldrb	$t2,[$rounds,#9]
+	ldrb	$t3,[$rounds,#8]
+	orr	$s2,$s2,$t1,lsl#8
+	ldrb	$s3,[$rounds,#15]
+	orr	$s2,$s2,$t2,lsl#16
+	ldrb	$t1,[$rounds,#14]
+	orr	$s2,$s2,$t3,lsl#24
+	ldrb	$t2,[$rounds,#13]
+	ldrb	$t3,[$rounds,#12]
+	orr	$s3,$s3,$t1,lsl#8
+	orr	$s3,$s3,$t2,lsl#16
+	orr	$s3,$s3,$t3,lsl#24
+
+	bl	_armv4_AES_decrypt
+
+	ldr	$rounds,[sp],#4		@ pop out
+	mov	$t1,$s0,lsr#24		@ write output in endian-neutral
+	mov	$t2,$s0,lsr#16		@ manner...
+	mov	$t3,$s0,lsr#8
+	strb	$t1,[$rounds,#0]
+	strb	$t2,[$rounds,#1]
+	mov	$t1,$s1,lsr#24
+	strb	$t3,[$rounds,#2]
+	mov	$t2,$s1,lsr#16
+	strb	$s0,[$rounds,#3]
+	mov	$t3,$s1,lsr#8
+	strb	$t1,[$rounds,#4]
+	strb	$t2,[$rounds,#5]
+	mov	$t1,$s2,lsr#24
+	strb	$t3,[$rounds,#6]
+	mov	$t2,$s2,lsr#16
+	strb	$s1,[$rounds,#7]
+	mov	$t3,$s2,lsr#8
+	strb	$t1,[$rounds,#8]
+	strb	$t2,[$rounds,#9]
+	mov	$t1,$s3,lsr#24
+	strb	$t3,[$rounds,#10]
+	mov	$t2,$s3,lsr#16
+	strb	$s2,[$rounds,#11]
+	mov	$t3,$s3,lsr#8
+	strb	$t1,[$rounds,#12]
+	strb	$t2,[$rounds,#13]
+	strb	$t3,[$rounds,#14]
+	strb	$s3,[$rounds,#15]
+
+	ldmia   sp!,{r4-r12,lr}
+	tst	lr,#1
+	moveq	pc,lr			@ be binary compatible with V4, yet
+	bx	lr			@ interoperable with Thumb ISA:-)
+.size	AES_decrypt,.-AES_decrypt
+
+.type   _armv4_AES_decrypt,%function
+.align	2
+_armv4_AES_decrypt:
+	str	lr,[sp,#-4]!		@ push lr
+	ldmia	$key!,{$t1-$i1}
+	eor	$s0,$s0,$t1
+	ldr	$rounds,[$key,#240-16]
+	eor	$s1,$s1,$t2
+	eor	$s2,$s2,$t3
+	eor	$s3,$s3,$i1
+	sub	$rounds,$rounds,#1
+	mov	lr,#255
+
+	and	$i1,lr,$s0,lsr#16
+	and	$i2,lr,$s0,lsr#8
+	and	$i3,lr,$s0
+	mov	$s0,$s0,lsr#24
+.Ldec_loop:
+	ldr	$t1,[$tbl,$i1,lsl#2]	@ Td1[s0>>16]
+	and	$i1,lr,$s1		@ i0
+	ldr	$t2,[$tbl,$i2,lsl#2]	@ Td2[s0>>8]
+	and	$i2,lr,$s1,lsr#16
+	ldr	$t3,[$tbl,$i3,lsl#2]	@ Td3[s0>>0]
+	and	$i3,lr,$s1,lsr#8
+	ldr	$s0,[$tbl,$s0,lsl#2]	@ Td0[s0>>24]
+	mov	$s1,$s1,lsr#24
+
+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Td3[s1>>0]
+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Td1[s1>>16]
+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Td2[s1>>8]
+	eor	$s0,$s0,$i1,ror#24
+	ldr	$s1,[$tbl,$s1,lsl#2]	@ Td0[s1>>24]
+	and	$i1,lr,$s2,lsr#8	@ i0
+	eor	$t2,$i2,$t2,ror#8
+	and	$i2,lr,$s2		@ i1
+	eor	$t3,$i3,$t3,ror#8
+	and	$i3,lr,$s2,lsr#16
+	eor	$s1,$s1,$t1,ror#8
+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Td2[s2>>8]
+	mov	$s2,$s2,lsr#24
+
+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Td3[s2>>0]
+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Td1[s2>>16]
+	eor	$s0,$s0,$i1,ror#16
+	ldr	$s2,[$tbl,$s2,lsl#2]	@ Td0[s2>>24]
+	and	$i1,lr,$s3,lsr#16	@ i0
+	eor	$s1,$s1,$i2,ror#24
+	and	$i2,lr,$s3,lsr#8	@ i1
+	eor	$t3,$i3,$t3,ror#8
+	and	$i3,lr,$s3		@ i2
+	eor	$s2,$s2,$t2,ror#8
+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Td1[s3>>16]
+	mov	$s3,$s3,lsr#24
+
+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Td2[s3>>8]
+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Td3[s3>>0]
+	eor	$s0,$s0,$i1,ror#8
+	ldr	$s3,[$tbl,$s3,lsl#2]	@ Td0[s3>>24]
+	eor	$s1,$s1,$i2,ror#16
+	eor	$s2,$s2,$i3,ror#24
+	ldr	$i1,[$key],#16
+	eor	$s3,$s3,$t3,ror#8
+
+	ldr	$t1,[$key,#-12]
+	ldr	$t2,[$key,#-8]
+	eor	$s0,$s0,$i1
+	ldr	$t3,[$key,#-4]
+	and	$i1,lr,$s0,lsr#16
+	eor	$s1,$s1,$t1
+	and	$i2,lr,$s0,lsr#8
+	eor	$s2,$s2,$t2
+	and	$i3,lr,$s0
+	eor	$s3,$s3,$t3
+	mov	$s0,$s0,lsr#24
+
+	subs	$rounds,$rounds,#1
+	bne	.Ldec_loop
+
+	add	$tbl,$tbl,#1024
+
+	ldr	$t2,[$tbl,#0]		@ prefetch Td4
+	ldr	$t3,[$tbl,#32]
+	ldr	$t1,[$tbl,#64]
+	ldr	$t2,[$tbl,#96]
+	ldr	$t3,[$tbl,#128]
+	ldr	$t1,[$tbl,#160]
+	ldr	$t2,[$tbl,#192]
+	ldr	$t3,[$tbl,#224]
+
+	ldrb	$s0,[$tbl,$s0]		@ Td4[s0>>24]
+	ldrb	$t1,[$tbl,$i1]		@ Td4[s0>>16]
+	and	$i1,lr,$s1		@ i0
+	ldrb	$t2,[$tbl,$i2]		@ Td4[s0>>8]
+	and	$i2,lr,$s1,lsr#16
+	ldrb	$t3,[$tbl,$i3]		@ Td4[s0>>0]
+	and	$i3,lr,$s1,lsr#8
+
+	ldrb	$i1,[$tbl,$i1]		@ Td4[s1>>0]
+	ldrb	$s1,[$tbl,$s1,lsr#24]	@ Td4[s1>>24]
+	ldrb	$i2,[$tbl,$i2]		@ Td4[s1>>16]
+	eor	$s0,$i1,$s0,lsl#24
+	ldrb	$i3,[$tbl,$i3]		@ Td4[s1>>8]
+	eor	$s1,$t1,$s1,lsl#8
+	and	$i1,lr,$s2,lsr#8	@ i0
+	eor	$t2,$t2,$i2,lsl#8
+	and	$i2,lr,$s2		@ i1
+	eor	$t3,$t3,$i3,lsl#8
+	ldrb	$i1,[$tbl,$i1]		@ Td4[s2>>8]
+	and	$i3,lr,$s2,lsr#16
+
+	ldrb	$i2,[$tbl,$i2]		@ Td4[s2>>0]
+	ldrb	$s2,[$tbl,$s2,lsr#24]	@ Td4[s2>>24]
+	eor	$s0,$s0,$i1,lsl#8
+	ldrb	$i3,[$tbl,$i3]		@ Td4[s2>>16]
+	eor	$s1,$i2,$s1,lsl#16
+	and	$i1,lr,$s3,lsr#16	@ i0
+	eor	$s2,$t2,$s2,lsl#16
+	and	$i2,lr,$s3,lsr#8	@ i1
+	eor	$t3,$t3,$i3,lsl#16
+	ldrb	$i1,[$tbl,$i1]		@ Td4[s3>>16]
+	and	$i3,lr,$s3		@ i2
+
+	ldrb	$i2,[$tbl,$i2]		@ Td4[s3>>8]
+	ldrb	$i3,[$tbl,$i3]		@ Td4[s3>>0]
+	ldrb	$s3,[$tbl,$s3,lsr#24]	@ Td4[s3>>24]
+	eor	$s0,$s0,$i1,lsl#16
+	ldr	$i1,[$key,#0]
+	eor	$s1,$s1,$i2,lsl#8
+	ldr	$t1,[$key,#4]
+	eor	$s2,$i3,$s2,lsl#8
+	ldr	$t2,[$key,#8]
+	eor	$s3,$t3,$s3,lsl#24
+	ldr	$t3,[$key,#12]
+
+	eor	$s0,$s0,$i1
+	eor	$s1,$s1,$t1
+	eor	$s2,$s2,$t2
+	eor	$s3,$s3,$t3
+
+	sub	$tbl,$tbl,#1024
+	ldr	pc,[sp],#4		@ pop and return
+.size	_armv4_AES_decrypt,.-_armv4_AES_decrypt
+.asciz	"AES for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
+.align	2
+___
+
+$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
+print $code;
+close STDOUT;	# enforce flush
diff --git a/openssl/crypto/aes/asm/aes-ia64.S b/openssl/crypto/aes/asm/aes-ia64.S
new file mode 100644
index 0000000..7f6c4c3
--- /dev/null
+++ b/openssl/crypto/aes/asm/aes-ia64.S
@@ -0,0 +1,1123 @@
+// ====================================================================
+// Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+// project. Rights for redistribution and usage in source and binary
+// forms are granted according to the OpenSSL license.
+// ====================================================================
+//
+// What's wrong with compiler generated code? Compiler never uses
+// variable 'shr' which is pairable with 'extr'/'dep' instructions.
+// Then it uses 'zxt' which is an I-type, but can be replaced with
+// 'and' which in turn can be assigned to M-port [there're double as
+// much M-ports as there're I-ports on Itanium 2]. By sacrificing few
+// registers for small constants (255, 24 and 16) to be used with
+// 'shr' and 'and' instructions I can achieve better ILP, Intruction
+// Level Parallelism, and performance. This code outperforms GCC 3.3
+// generated code by over factor of 2 (two), GCC 3.4 - by 70% and
+// HP C - by 40%. Measured best-case scenario, i.e. aligned
+// big-endian input, ECB timing on Itanium 2 is (18 + 13*rounds)
+// ticks per block, or 9.25 CPU cycles per byte for 128 bit key.
+
+// Version 1.2 mitigates the hazard of cache-timing attacks by
+// a) compressing S-boxes from 8KB to 2KB+256B, b) scheduling
+// references to S-boxes for L2 cache latency, c) prefetching T[ed]4
+// prior last round. As result performance dropped to (26 + 15*rounds)
+// ticks per block or 11 cycles per byte processed with 128-bit key.
+// This is ~16% deterioration. For reference Itanium 2 L1 cache has
+// 64 bytes line size and L2 - 128 bytes...
+
+.ident	"aes-ia64.S, version 1.2"
+.ident	"IA-64 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
+.explicit
+.text
+
+rk0=r8;     rk1=r9;
+
+pfssave=r2;
+lcsave=r10;
+prsave=r3;
+maskff=r11;
+twenty4=r14;
+sixteen=r15;
+
+te00=r16;   te11=r17;   te22=r18;   te33=r19;
+te01=r20;   te12=r21;   te23=r22;   te30=r23;
+te02=r24;   te13=r25;   te20=r26;   te31=r27;
+te03=r28;   te10=r29;   te21=r30;   te32=r31;
+
+// these are rotating...
+t0=r32;     s0=r33;
+t1=r34;     s1=r35;
+t2=r36;     s2=r37;
+t3=r38;     s3=r39;
+
+te0=r40;    te1=r41;    te2=r42;    te3=r43;
+
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+# define ADDP	addp4
+#else
+# define ADDP	add
+#endif
+
+// Offsets from Te0
+#define TE0	0
+#define TE2	2
+#if defined(_HPUX_SOURCE) || defined(B_ENDIAN)
+#define TE1	3
+#define TE3	1
+#else
+#define TE1	1
+#define TE3	3
+#endif
+
+// This implies that AES_KEY comprises 32-bit key schedule elements
+// even on LP64 platforms.
+#ifndef	KSZ
+# define KSZ	4
+# define LDKEY	ld4
+#endif
+
+.proc	_ia64_AES_encrypt#
+// Input:	rk0-rk1
+//		te0
+//		te3	as AES_KEY->rounds!!!
+//		s0-s3
+//		maskff,twenty4,sixteen
+// Output:	r16,r20,r24,r28 as s0-s3
+// Clobber:	r16-r31,rk0-rk1,r32-r43
+.align	32
+_ia64_AES_encrypt:
+	.prologue
+	.altrp	b6
+	.body
+{ .mmi;	alloc	r16=ar.pfs,12,0,0,8
+	LDKEY	t0=[rk0],2*KSZ
+	mov	pr.rot=1<<16	}
+{ .mmi;	LDKEY	t1=[rk1],2*KSZ
+	add	te1=TE1,te0
+	add	te3=-3,te3	};;
+{ .mib;	LDKEY	t2=[rk0],2*KSZ
+	mov	ar.ec=2		}
+{ .mib;	LDKEY	t3=[rk1],2*KSZ
+	add	te2=TE2,te0
+	brp.loop.imp	.Le_top,.Le_end-16	};;
+
+{ .mmi;	xor	s0=s0,t0
+	xor	s1=s1,t1
+	mov	ar.lc=te3	}
+{ .mmi;	xor	s2=s2,t2
+	xor	s3=s3,t3
+	add	te3=TE3,te0	};;
+
+.align	32
+.Le_top:
+{ .mmi;	(p0)	LDKEY	t0=[rk0],2*KSZ		// 0/0:rk[0]
+	(p0)	and	te33=s3,maskff		// 0/0:s3&0xff
+	(p0)	extr.u	te22=s2,8,8	}	// 0/0:s2>>8&0xff
+{ .mmi; (p0)	LDKEY	t1=[rk1],2*KSZ		// 0/1:rk[1]
+	(p0)	and	te30=s0,maskff		// 0/1:s0&0xff
+	(p0)	shr.u	te00=s0,twenty4	};;	// 0/0:s0>>24
+{ .mmi;	(p0)	LDKEY	t2=[rk0],2*KSZ		// 1/2:rk[2]
+	(p0)	shladd	te33=te33,3,te3		// 1/0:te0+s0>>24
+	(p0)	extr.u	te23=s3,8,8	}	// 1/1:s3>>8&0xff
+{ .mmi;	(p0)	LDKEY	t3=[rk1],2*KSZ		// 1/3:rk[3]
+	(p0)	shladd	te30=te30,3,te3		// 1/1:te3+s0
+	(p0)	shr.u	te01=s1,twenty4	};;	// 1/1:s1>>24
+{ .mmi;	(p0)	ld4	te33=[te33]		// 2/0:te3[s3&0xff]
+	(p0)	shladd	te22=te22,3,te2		// 2/0:te2+s2>>8&0xff
+	(p0)	extr.u	te20=s0,8,8	}	// 2/2:s0>>8&0xff
+{ .mmi;	(p0)	ld4	te30=[te30]		// 2/1:te3[s0]
+	(p0)	shladd	te23=te23,3,te2		// 2/1:te2+s3>>8
+	(p0)	shr.u	te02=s2,twenty4	};;	// 2/2:s2>>24
+{ .mmi;	(p0)	ld4	te22=[te22]		// 3/0:te2[s2>>8]
+	(p0)	shladd	te20=te20,3,te2		// 3/2:te2+s0>>8
+	(p0)	extr.u	te21=s1,8,8	}	// 3/3:s1>>8&0xff
+{ .mmi;	(p0)	ld4	te23=[te23]		// 3/1:te2[s3>>8]
+	(p0)	shladd	te00=te00,3,te0		// 3/0:te0+s0>>24
+	(p0)	shr.u	te03=s3,twenty4	};;	// 3/3:s3>>24
+{ .mmi;	(p0)	ld4	te20=[te20]		// 4/2:te2[s0>>8]
+	(p0)	shladd	te21=te21,3,te2		// 4/3:te3+s2
+	(p0)	extr.u	te11=s1,16,8	}	// 4/0:s1>>16&0xff
+{ .mmi;	(p0)	ld4	te00=[te00]		// 4/0:te0[s0>>24]
+	(p0)	shladd	te01=te01,3,te0		// 4/1:te0+s1>>24
+	(p0)	shr.u	te13=s3,sixteen	};;	// 4/2:s3>>16
+{ .mmi;	(p0)	ld4	te21=[te21]		// 5/3:te2[s1>>8]
+	(p0)	shladd	te11=te11,3,te1		// 5/0:te1+s1>>16
+	(p0)	extr.u	te12=s2,16,8	}	// 5/1:s2>>16&0xff
+{ .mmi;	(p0)	ld4	te01=[te01]		// 5/1:te0[s1>>24]
+	(p0)	shladd	te02=te02,3,te0		// 5/2:te0+s2>>24
+	(p0)	and	te31=s1,maskff	};;	// 5/2:s1&0xff
+{ .mmi;	(p0)	ld4	te11=[te11]		// 6/0:te1[s1>>16]
+	(p0)	shladd	te12=te12,3,te1		// 6/1:te1+s2>>16
+	(p0)	extr.u	te10=s0,16,8	}	// 6/3:s0>>16&0xff
+{ .mmi;	(p0)	ld4	te02=[te02]		// 6/2:te0[s2>>24]
+	(p0)	shladd	te03=te03,3,te0		// 6/3:te1+s0>>16
+	(p0)	and	te32=s2,maskff	};;	// 6/3:s2&0xff
+
+{ .mmi;	(p0)	ld4	te12=[te12]		// 7/1:te1[s2>>16]
+	(p0)	shladd	te31=te31,3,te3		// 7/2:te3+s1&0xff
+	(p0)	and	te13=te13,maskff}	// 7/2:s3>>16&0xff
+{ .mmi;	(p0)	ld4	te03=[te03]		// 7/3:te0[s3>>24]
+	(p0)	shladd	te32=te32,3,te3		// 7/3:te3+s2
+	(p0)	xor	t0=t0,te33	};;	// 7/0:
+{ .mmi;	(p0)	ld4	te31=[te31]		// 8/2:te3[s1]
+	(p0)	shladd	te13=te13,3,te1		// 8/2:te1+s3>>16
+	(p0)	xor	t0=t0,te22	}	// 8/0:
+{ .mmi;	(p0)	ld4	te32=[te32]		// 8/3:te3[s2]
+	(p0)	shladd	te10=te10,3,te1		// 8/3:te1+s0>>16
+	(p0)	xor	t1=t1,te30	};;	// 8/1:
+{ .mmi;	(p0)	ld4	te13=[te13]		// 9/2:te1[s3>>16]
+	(p0)	ld4	te10=[te10]		// 9/3:te1[s0>>16]
+	(p0)	xor	t0=t0,te00	};;	// 9/0:		!L2 scheduling
+{ .mmi;	(p0)	xor	t1=t1,te23		// 10[9]/1:	
+	(p0)	xor	t2=t2,te20		// 10[9]/2:
+	(p0)	xor	t3=t3,te21	};;	// 10[9]/3:
+{ .mmi;	(p0)	xor	t0=t0,te11		// 11[10]/0:done!
+	(p0)	xor	t1=t1,te01		// 11[10]/1:
+	(p0)	xor	t2=t2,te02	};;	// 11[10]/2:	!L2 scheduling
+{ .mmi;	(p0)	xor	t3=t3,te03		// 12[10]/3:
+	(p16)	cmp.eq	p0,p17=r0,r0 	};;	// 12[10]/clear (p17)
+{ .mmi;	(p0)	xor	t1=t1,te12		// 13[11]/1:done!
+	(p0)	xor	t2=t2,te31		// 13[11]/2:
+	(p0)	xor	t3=t3,te32	}	// 13[11]/3:
+{ .mmi;	(p17)	add	te0=2048,te0		// 13[11]/
+	(p17)	add	te1=2048+64-TE1,te1};;	// 13[11]/
+{ .mib;	(p0)	xor	t2=t2,te13		// 14[12]/2:done!
+	(p17)	add	te2=2048+128-TE2,te2}	// 14[12]/
+{ .mib;	(p0)	xor	t3=t3,te10		// 14[12]/3:done!
+	(p17)	add	te3=2048+192-TE3,te3	// 14[12]/
+	br.ctop.sptk	.Le_top		};;
+.Le_end:
+
+
+{ .mmi;	ld8	te12=[te0]		// prefetch Te4
+	ld8	te31=[te1]	}
+{ .mmi;	ld8	te10=[te2]
+	ld8	te32=[te3]	}
+
+{ .mmi;	LDKEY	t0=[rk0],2*KSZ		// 0/0:rk[0]
+	and	te33=s3,maskff		// 0/0:s3&0xff
+	extr.u	te22=s2,8,8	}	// 0/0:s2>>8&0xff
+{ .mmi; LDKEY	t1=[rk1],2*KSZ		// 0/1:rk[1]
+	and	te30=s0,maskff		// 0/1:s0&0xff
+	shr.u	te00=s0,twenty4	};;	// 0/0:s0>>24
+{ .mmi;	LDKEY	t2=[rk0],2*KSZ		// 1/2:rk[2]
+	add	te33=te33,te0		// 1/0:te0+s0>>24
+	extr.u	te23=s3,8,8	}	// 1/1:s3>>8&0xff
+{ .mmi;	LDKEY	t3=[rk1],2*KSZ		// 1/3:rk[3]
+	add	te30=te30,te0		// 1/1:te0+s0
+	shr.u	te01=s1,twenty4	};;	// 1/1:s1>>24
+{ .mmi;	ld1	te33=[te33]		// 2/0:te0[s3&0xff]
+	add	te22=te22,te0		// 2/0:te0+s2>>8&0xff
+	extr.u	te20=s0,8,8	}	// 2/2:s0>>8&0xff
+{ .mmi;	ld1	te30=[te30]		// 2/1:te0[s0]
+	add	te23=te23,te0		// 2/1:te0+s3>>8
+	shr.u	te02=s2,twenty4	};;	// 2/2:s2>>24
+{ .mmi;	ld1	te22=[te22]		// 3/0:te0[s2>>8]
+	add	te20=te20,te0		// 3/2:te0+s0>>8
+	extr.u	te21=s1,8,8	}	// 3/3:s1>>8&0xff
+{ .mmi;	ld1	te23=[te23]		// 3/1:te0[s3>>8]
+	add	te00=te00,te0		// 3/0:te0+s0>>24
+	shr.u	te03=s3,twenty4	};;	// 3/3:s3>>24
+{ .mmi;	ld1	te20=[te20]		// 4/2:te0[s0>>8]
+	add	te21=te21,te0		// 4/3:te0+s2
+	extr.u	te11=s1,16,8	}	// 4/0:s1>>16&0xff
+{ .mmi;	ld1	te00=[te00]		// 4/0:te0[s0>>24]
+	add	te01=te01,te0		// 4/1:te0+s1>>24
+	shr.u	te13=s3,sixteen	};;	// 4/2:s3>>16
+{ .mmi;	ld1	te21=[te21]		// 5/3:te0[s1>>8]
+	add	te11=te11,te0		// 5/0:te0+s1>>16
+	extr.u	te12=s2,16,8	}	// 5/1:s2>>16&0xff
+{ .mmi;	ld1	te01=[te01]		// 5/1:te0[s1>>24]
+	add	te02=te02,te0		// 5/2:te0+s2>>24
+	and	te31=s1,maskff	};;	// 5/2:s1&0xff
+{ .mmi;	ld1	te11=[te11]		// 6/0:te0[s1>>16]
+	add	te12=te12,te0		// 6/1:te0+s2>>16
+	extr.u	te10=s0,16,8	}	// 6/3:s0>>16&0xff
+{ .mmi;	ld1	te02=[te02]		// 6/2:te0[s2>>24]
+	add	te03=te03,te0		// 6/3:te0+s0>>16
+	and	te32=s2,maskff	};;	// 6/3:s2&0xff
+
+{ .mmi;	ld1	te12=[te12]		// 7/1:te0[s2>>16]
+	add	te31=te31,te0		// 7/2:te0+s1&0xff
+	dep	te33=te22,te33,8,8}	// 7/0:
+{ .mmi;	ld1	te03=[te03]		// 7/3:te0[s3>>24]
+	add	te32=te32,te0		// 7/3:te0+s2
+	and	te13=te13,maskff};;	// 7/2:s3>>16&0xff
+{ .mmi;	ld1	te31=[te31]		// 8/2:te0[s1]
+	add	te13=te13,te0		// 8/2:te0+s3>>16
+	dep	te30=te23,te30,8,8}	// 8/1:
+{ .mmi;	ld1	te32=[te32]		// 8/3:te0[s2]
+	add	te10=te10,te0		// 8/3:te0+s0>>16
+	shl	te00=te00,twenty4};;	// 8/0:
+{ .mii;	ld1	te13=[te13]		// 9/2:te0[s3>>16]
+	dep	te33=te11,te33,16,8	// 9/0:
+	shl	te01=te01,twenty4};;	// 9/1:
+{ .mii;	ld1	te10=[te10]		// 10/3:te0[s0>>16]
+	dep	te31=te20,te31,8,8	// 10/2:
+	shl	te02=te02,twenty4};;	// 10/2:
+{ .mii;	xor	t0=t0,te33		// 11/0:
+	dep	te32=te21,te32,8,8	// 11/3:
+	shl	te12=te12,sixteen};;	// 11/1:
+{ .mii;	xor	r16=t0,te00		// 12/0:done!
+	dep	te31=te13,te31,16,8	// 12/2:
+	shl	te03=te03,twenty4};;	// 12/3:
+{ .mmi;	xor	t1=t1,te01		// 13/1:
+	xor	t2=t2,te02		// 13/2:
+	dep	te32=te10,te32,16,8};;	// 13/3:
+{ .mmi;	xor	t1=t1,te30		// 14/1:
+	xor	r24=t2,te31		// 14/2:done!
+	xor	t3=t3,te32	};;	// 14/3:
+{ .mib;	xor	r20=t1,te12		// 15/1:done!
+	xor	r28=t3,te03		// 15/3:done!
+	br.ret.sptk	b6	};;
+.endp	_ia64_AES_encrypt#
+
+// void AES_encrypt (const void *in,void *out,const AES_KEY *key);
+.global	AES_encrypt#
+.proc	AES_encrypt#
+.align	32
+AES_encrypt:
+	.prologue
+	.save	ar.pfs,pfssave
+{ .mmi;	alloc	pfssave=ar.pfs,3,1,12,0
+	and	out0=3,in0
+	mov	r3=ip			}
+{ .mmi;	ADDP	in0=0,in0
+	mov	loc0=psr.um
+	ADDP	out11=KSZ*60,in2	};;	// &AES_KEY->rounds
+
+{ .mmi;	ld4	out11=[out11]			// AES_KEY->rounds
+	add	out8=(AES_Te#-AES_encrypt#),r3	// Te0
+	.save	pr,prsave
+	mov	prsave=pr		}
+{ .mmi;	rum	1<<3				// clear um.ac
+	.save	ar.lc,lcsave
+	mov	lcsave=ar.lc		};;
+
+	.body
+#if defined(_HPUX_SOURCE)	// HPUX is big-endian, cut 15+15 cycles...
+{ .mib; cmp.ne	p6,p0=out0,r0
+	add	out0=4,in0
+(p6)	br.dpnt.many	.Le_i_unaligned	};;
+
+{ .mmi;	ld4	out1=[in0],8		// s0
+	and	out9=3,in1
+	mov	twenty4=24		}
+{ .mmi;	ld4	out3=[out0],8		// s1
+	ADDP	rk0=0,in2
+	mov	sixteen=16		};;
+{ .mmi;	ld4	out5=[in0]		// s2
+	cmp.ne	p6,p0=out9,r0
+	mov	maskff=0xff		}
+{ .mmb;	ld4	out7=[out0]		// s3
+	ADDP	rk1=KSZ,in2
+	br.call.sptk.many	b6=_ia64_AES_encrypt	};;
+
+{ .mib;	ADDP	in0=4,in1
+	ADDP	in1=0,in1
+(p6)	br.spnt	.Le_o_unaligned		};;
+
+{ .mii;	mov	psr.um=loc0
+	mov	ar.pfs=pfssave
+	mov	ar.lc=lcsave		};;
+{ .mmi;	st4	[in1]=r16,8		// s0
+	st4	[in0]=r20,8		// s1
+	mov	pr=prsave,0x1ffff	};;
+{ .mmb;	st4	[in1]=r24		// s2
+	st4	[in0]=r28		// s3
+	br.ret.sptk.many	b0	};;
+#endif
+
+.align	32
+.Le_i_unaligned:
+{ .mmi;	add	out0=1,in0
+	add	out2=2,in0
+	add	out4=3,in0	};;
+{ .mmi;	ld1	r16=[in0],4
+	ld1	r17=[out0],4	}//;;
+{ .mmi;	ld1	r18=[out2],4
+	ld1	out1=[out4],4	};;	// s0
+{ .mmi;	ld1	r20=[in0],4
+	ld1	r21=[out0],4	}//;;
+{ .mmi;	ld1	r22=[out2],4
+	ld1	out3=[out4],4	};;	// s1
+{ .mmi;	ld1	r24=[in0],4
+	ld1	r25=[out0],4	}//;;
+{ .mmi;	ld1	r26=[out2],4
+	ld1	out5=[out4],4	};;	// s2
+{ .mmi;	ld1	r28=[in0]
+	ld1	r29=[out0]	}//;;
+{ .mmi;	ld1	r30=[out2]
+	ld1	out7=[out4]	};;	// s3
+
+{ .mii;
+	dep	out1=r16,out1,24,8	//;;
+	dep	out3=r20,out3,24,8	}//;;
+{ .mii;	ADDP	rk0=0,in2
+	dep	out5=r24,out5,24,8	//;;
+	dep	out7=r28,out7,24,8	};;
+{ .mii;	ADDP	rk1=KSZ,in2
+	dep	out1=r17,out1,16,8	//;;
+	dep	out3=r21,out3,16,8	}//;;
+{ .mii;	mov	twenty4=24
+	dep	out5=r25,out5,16,8	//;;
+	dep	out7=r29,out7,16,8	};;
+{ .mii;	mov	sixteen=16
+	dep	out1=r18,out1,8,8	//;;
+	dep	out3=r22,out3,8,8	}//;;
+{ .mii;	mov	maskff=0xff
+	dep	out5=r26,out5,8,8	//;;
+	dep	out7=r30,out7,8,8	};;
+
+{ .mib;	br.call.sptk.many	b6=_ia64_AES_encrypt	};;
+
+.Le_o_unaligned:
+{ .mii;	ADDP	out0=0,in1
+	extr.u	r17=r16,8,8			// s0
+	shr.u	r19=r16,twenty4		}//;;
+{ .mii;	ADDP	out1=1,in1
+	extr.u	r18=r16,16,8
+	shr.u	r23=r20,twenty4		}//;;	// s1
+{ .mii;	ADDP	out2=2,in1
+	extr.u	r21=r20,8,8
+	shr.u	r22=r20,sixteen		}//;;
+{ .mii;	ADDP	out3=3,in1
+	extr.u	r25=r24,8,8			// s2
+	shr.u	r27=r24,twenty4		};;
+{ .mii;	st1	[out3]=r16,4
+	extr.u	r26=r24,16,8
+	shr.u	r31=r28,twenty4		}//;;	// s3
+{ .mii;	st1	[out2]=r17,4
+	extr.u	r29=r28,8,8
+	shr.u	r30=r28,sixteen		}//;;
+
+{ .mmi;	st1	[out1]=r18,4
+	st1	[out0]=r19,4		};;
+{ .mmi;	st1	[out3]=r20,4
+	st1	[out2]=r21,4		}//;;
+{ .mmi;	st1	[out1]=r22,4
+	st1	[out0]=r23,4		};;
+{ .mmi;	st1	[out3]=r24,4
+	st1	[out2]=r25,4
+	mov	pr=prsave,0x1ffff	}//;;
+{ .mmi;	st1	[out1]=r26,4
+	st1	[out0]=r27,4
+	mov	ar.pfs=pfssave		};;
+{ .mmi;	st1	[out3]=r28
+	st1	[out2]=r29
+	mov	ar.lc=lcsave		}//;;
+{ .mmi;	st1	[out1]=r30
+	st1	[out0]=r31		}
+{ .mfb;	mov	psr.um=loc0			// restore user mask
+	br.ret.sptk.many	b0	};;
+.endp	AES_encrypt#
+
+// *AES_decrypt are autogenerated by the following script:
+#if 0
+#!/usr/bin/env perl
+print "// *AES_decrypt are autogenerated by the following script:\n#if 0\n";
+open(PROG,'<'.$0); while(<PROG>) { print; } close(PROG);
+print "#endif\n";
+while(<>) {
+	$process=1	if (/\.proc\s+_ia64_AES_encrypt/);
+	next		if (!$process);
+
+	#s/te00=s0/td00=s0/;	s/te00/td00/g;
+	s/te11=s1/td13=s3/;	s/te11/td13/g;
+	#s/te22=s2/td22=s2/;	s/te22/td22/g;
+	s/te33=s3/td31=s1/;	s/te33/td31/g;
+
+	#s/te01=s1/td01=s1/;	s/te01/td01/g;
+	s/te12=s2/td10=s0/;	s/te12/td10/g;
+	#s/te23=s3/td23=s3/;	s/te23/td23/g;
+	s/te30=s0/td32=s2/;	s/te30/td32/g;
+
+	#s/te02=s2/td02=s2/;	s/te02/td02/g;
+	s/te13=s3/td11=s1/;	s/te13/td11/g;
+	#s/te20=s0/td20=s0/;	s/te20/td20/g;
+	s/te31=s1/td33=s3/;	s/te31/td33/g;
+
+	#s/te03=s3/td03=s3/;	s/te03/td03/g;
+	s/te10=s0/td12=s2/;	s/te10/td12/g;
+	#s/te21=s1/td21=s1/;	s/te21/td21/g;
+	s/te32=s2/td30=s0/;	s/te32/td30/g;
+
+	s/td/te/g;
+
+	s/AES_encrypt/AES_decrypt/g;
+	s/\.Le_/.Ld_/g;
+	s/AES_Te#/AES_Td#/g;
+
+	print;
+
+	exit		if (/\.endp\s+AES_decrypt/);
+}
+#endif
+.proc	_ia64_AES_decrypt#
+// Input:	rk0-rk1
+//		te0
+//		te3	as AES_KEY->rounds!!!
+//		s0-s3
+//		maskff,twenty4,sixteen
+// Output:	r16,r20,r24,r28 as s0-s3
+// Clobber:	r16-r31,rk0-rk1,r32-r43
+.align	32
+_ia64_AES_decrypt:
+	.prologue
+	.altrp	b6
+	.body
+{ .mmi;	alloc	r16=ar.pfs,12,0,0,8
+	LDKEY	t0=[rk0],2*KSZ
+	mov	pr.rot=1<<16	}
+{ .mmi;	LDKEY	t1=[rk1],2*KSZ
+	add	te1=TE1,te0
+	add	te3=-3,te3	};;
+{ .mib;	LDKEY	t2=[rk0],2*KSZ
+	mov	ar.ec=2		}
+{ .mib;	LDKEY	t3=[rk1],2*KSZ
+	add	te2=TE2,te0
+	brp.loop.imp	.Ld_top,.Ld_end-16	};;
+
+{ .mmi;	xor	s0=s0,t0
+	xor	s1=s1,t1
+	mov	ar.lc=te3	}
+{ .mmi;	xor	s2=s2,t2
+	xor	s3=s3,t3
+	add	te3=TE3,te0	};;
+
+.align	32
+.Ld_top:
+{ .mmi;	(p0)	LDKEY	t0=[rk0],2*KSZ		// 0/0:rk[0]
+	(p0)	and	te31=s1,maskff		// 0/0:s3&0xff
+	(p0)	extr.u	te22=s2,8,8	}	// 0/0:s2>>8&0xff
+{ .mmi; (p0)	LDKEY	t1=[rk1],2*KSZ		// 0/1:rk[1]
+	(p0)	and	te32=s2,maskff		// 0/1:s0&0xff
+	(p0)	shr.u	te00=s0,twenty4	};;	// 0/0:s0>>24
+{ .mmi;	(p0)	LDKEY	t2=[rk0],2*KSZ		// 1/2:rk[2]
+	(p0)	shladd	te31=te31,3,te3		// 1/0:te0+s0>>24
+	(p0)	extr.u	te23=s3,8,8	}	// 1/1:s3>>8&0xff
+{ .mmi;	(p0)	LDKEY	t3=[rk1],2*KSZ		// 1/3:rk[3]
+	(p0)	shladd	te32=te32,3,te3		// 1/1:te3+s0
+	(p0)	shr.u	te01=s1,twenty4	};;	// 1/1:s1>>24
+{ .mmi;	(p0)	ld4	te31=[te31]		// 2/0:te3[s3&0xff]
+	(p0)	shladd	te22=te22,3,te2		// 2/0:te2+s2>>8&0xff
+	(p0)	extr.u	te20=s0,8,8	}	// 2/2:s0>>8&0xff
+{ .mmi;	(p0)	ld4	te32=[te32]		// 2/1:te3[s0]
+	(p0)	shladd	te23=te23,3,te2		// 2/1:te2+s3>>8
+	(p0)	shr.u	te02=s2,twenty4	};;	// 2/2:s2>>24
+{ .mmi;	(p0)	ld4	te22=[te22]		// 3/0:te2[s2>>8]
+	(p0)	shladd	te20=te20,3,te2		// 3/2:te2+s0>>8
+	(p0)	extr.u	te21=s1,8,8	}	// 3/3:s1>>8&0xff
+{ .mmi;	(p0)	ld4	te23=[te23]		// 3/1:te2[s3>>8]
+	(p0)	shladd	te00=te00,3,te0		// 3/0:te0+s0>>24
+	(p0)	shr.u	te03=s3,twenty4	};;	// 3/3:s3>>24
+{ .mmi;	(p0)	ld4	te20=[te20]		// 4/2:te2[s0>>8]
+	(p0)	shladd	te21=te21,3,te2		// 4/3:te3+s2
+	(p0)	extr.u	te13=s3,16,8	}	// 4/0:s1>>16&0xff
+{ .mmi;	(p0)	ld4	te00=[te00]		// 4/0:te0[s0>>24]
+	(p0)	shladd	te01=te01,3,te0		// 4/1:te0+s1>>24
+	(p0)	shr.u	te11=s1,sixteen	};;	// 4/2:s3>>16
+{ .mmi;	(p0)	ld4	te21=[te21]		// 5/3:te2[s1>>8]
+	(p0)	shladd	te13=te13,3,te1		// 5/0:te1+s1>>16
+	(p0)	extr.u	te10=s0,16,8	}	// 5/1:s2>>16&0xff
+{ .mmi;	(p0)	ld4	te01=[te01]		// 5/1:te0[s1>>24]
+	(p0)	shladd	te02=te02,3,te0		// 5/2:te0+s2>>24
+	(p0)	and	te33=s3,maskff	};;	// 5/2:s1&0xff
+{ .mmi;	(p0)	ld4	te13=[te13]		// 6/0:te1[s1>>16]
+	(p0)	shladd	te10=te10,3,te1		// 6/1:te1+s2>>16
+	(p0)	extr.u	te12=s2,16,8	}	// 6/3:s0>>16&0xff
+{ .mmi;	(p0)	ld4	te02=[te02]		// 6/2:te0[s2>>24]
+	(p0)	shladd	te03=te03,3,te0		// 6/3:te1+s0>>16
+	(p0)	and	te30=s0,maskff	};;	// 6/3:s2&0xff
+
+{ .mmi;	(p0)	ld4	te10=[te10]		// 7/1:te1[s2>>16]
+	(p0)	shladd	te33=te33,3,te3		// 7/2:te3+s1&0xff
+	(p0)	and	te11=te11,maskff}	// 7/2:s3>>16&0xff
+{ .mmi;	(p0)	ld4	te03=[te03]		// 7/3:te0[s3>>24]
+	(p0)	shladd	te30=te30,3,te3		// 7/3:te3+s2
+	(p0)	xor	t0=t0,te31	};;	// 7/0:
+{ .mmi;	(p0)	ld4	te33=[te33]		// 8/2:te3[s1]
+	(p0)	shladd	te11=te11,3,te1		// 8/2:te1+s3>>16
+	(p0)	xor	t0=t0,te22	}	// 8/0:
+{ .mmi;	(p0)	ld4	te30=[te30]		// 8/3:te3[s2]
+	(p0)	shladd	te12=te12,3,te1		// 8/3:te1+s0>>16
+	(p0)	xor	t1=t1,te32	};;	// 8/1:
+{ .mmi;	(p0)	ld4	te11=[te11]		// 9/2:te1[s3>>16]
+	(p0)	ld4	te12=[te12]		// 9/3:te1[s0>>16]
+	(p0)	xor	t0=t0,te00	};;	// 9/0:		!L2 scheduling
+{ .mmi;	(p0)	xor	t1=t1,te23		// 10[9]/1:	
+	(p0)	xor	t2=t2,te20		// 10[9]/2:
+	(p0)	xor	t3=t3,te21	};;	// 10[9]/3:
+{ .mmi;	(p0)	xor	t0=t0,te13		// 11[10]/0:done!
+	(p0)	xor	t1=t1,te01		// 11[10]/1:
+	(p0)	xor	t2=t2,te02	};;	// 11[10]/2:	!L2 scheduling
+{ .mmi;	(p0)	xor	t3=t3,te03		// 12[10]/3:
+	(p16)	cmp.eq	p0,p17=r0,r0 	};;	// 12[10]/clear (p17)
+{ .mmi;	(p0)	xor	t1=t1,te10		// 13[11]/1:done!
+	(p0)	xor	t2=t2,te33		// 13[11]/2:
+	(p0)	xor	t3=t3,te30	}	// 13[11]/3:
+{ .mmi;	(p17)	add	te0=2048,te0		// 13[11]/
+	(p17)	add	te1=2048+64-TE1,te1};;	// 13[11]/
+{ .mib;	(p0)	xor	t2=t2,te11		// 14[12]/2:done!
+	(p17)	add	te2=2048+128-TE2,te2}	// 14[12]/
+{ .mib;	(p0)	xor	t3=t3,te12		// 14[12]/3:done!
+	(p17)	add	te3=2048+192-TE3,te3	// 14[12]/
+	br.ctop.sptk	.Ld_top		};;
+.Ld_end:
+
+
+{ .mmi;	ld8	te10=[te0]		// prefetch Td4
+	ld8	te33=[te1]	}
+{ .mmi;	ld8	te12=[te2]
+	ld8	te30=[te3]	}
+
+{ .mmi;	LDKEY	t0=[rk0],2*KSZ		// 0/0:rk[0]
+	and	te31=s1,maskff		// 0/0:s3&0xff
+	extr.u	te22=s2,8,8	}	// 0/0:s2>>8&0xff
+{ .mmi; LDKEY	t1=[rk1],2*KSZ		// 0/1:rk[1]
+	and	te32=s2,maskff		// 0/1:s0&0xff
+	shr.u	te00=s0,twenty4	};;	// 0/0:s0>>24
+{ .mmi;	LDKEY	t2=[rk0],2*KSZ		// 1/2:rk[2]
+	add	te31=te31,te0		// 1/0:te0+s0>>24
+	extr.u	te23=s3,8,8	}	// 1/1:s3>>8&0xff
+{ .mmi;	LDKEY	t3=[rk1],2*KSZ		// 1/3:rk[3]
+	add	te32=te32,te0		// 1/1:te0+s0
+	shr.u	te01=s1,twenty4	};;	// 1/1:s1>>24
+{ .mmi;	ld1	te31=[te31]		// 2/0:te0[s3&0xff]
+	add	te22=te22,te0		// 2/0:te0+s2>>8&0xff
+	extr.u	te20=s0,8,8	}	// 2/2:s0>>8&0xff
+{ .mmi;	ld1	te32=[te32]		// 2/1:te0[s0]
+	add	te23=te23,te0		// 2/1:te0+s3>>8
+	shr.u	te02=s2,twenty4	};;	// 2/2:s2>>24
+{ .mmi;	ld1	te22=[te22]		// 3/0:te0[s2>>8]
+	add	te20=te20,te0		// 3/2:te0+s0>>8
+	extr.u	te21=s1,8,8	}	// 3/3:s1>>8&0xff
+{ .mmi;	ld1	te23=[te23]		// 3/1:te0[s3>>8]
+	add	te00=te00,te0		// 3/0:te0+s0>>24
+	shr.u	te03=s3,twenty4	};;	// 3/3:s3>>24
+{ .mmi;	ld1	te20=[te20]		// 4/2:te0[s0>>8]
+	add	te21=te21,te0		// 4/3:te0+s2
+	extr.u	te13=s3,16,8	}	// 4/0:s1>>16&0xff
+{ .mmi;	ld1	te00=[te00]		// 4/0:te0[s0>>24]
+	add	te01=te01,te0		// 4/1:te0+s1>>24
+	shr.u	te11=s1,sixteen	};;	// 4/2:s3>>16
+{ .mmi;	ld1	te21=[te21]		// 5/3:te0[s1>>8]
+	add	te13=te13,te0		// 5/0:te0+s1>>16
+	extr.u	te10=s0,16,8	}	// 5/1:s2>>16&0xff
+{ .mmi;	ld1	te01=[te01]		// 5/1:te0[s1>>24]
+	add	te02=te02,te0		// 5/2:te0+s2>>24
+	and	te33=s3,maskff	};;	// 5/2:s1&0xff
+{ .mmi;	ld1	te13=[te13]		// 6/0:te0[s1>>16]
+	add	te10=te10,te0		// 6/1:te0+s2>>16
+	extr.u	te12=s2,16,8	}	// 6/3:s0>>16&0xff
+{ .mmi;	ld1	te02=[te02]		// 6/2:te0[s2>>24]
+	add	te03=te03,te0		// 6/3:te0+s0>>16
+	and	te30=s0,maskff	};;	// 6/3:s2&0xff
+
+{ .mmi;	ld1	te10=[te10]		// 7/1:te0[s2>>16]
+	add	te33=te33,te0		// 7/2:te0+s1&0xff
+	dep	te31=te22,te31,8,8}	// 7/0:
+{ .mmi;	ld1	te03=[te03]		// 7/3:te0[s3>>24]
+	add	te30=te30,te0		// 7/3:te0+s2
+	and	te11=te11,maskff};;	// 7/2:s3>>16&0xff
+{ .mmi;	ld1	te33=[te33]		// 8/2:te0[s1]
+	add	te11=te11,te0		// 8/2:te0+s3>>16
+	dep	te32=te23,te32,8,8}	// 8/1:
+{ .mmi;	ld1	te30=[te30]		// 8/3:te0[s2]
+	add	te12=te12,te0		// 8/3:te0+s0>>16
+	shl	te00=te00,twenty4};;	// 8/0:
+{ .mii;	ld1	te11=[te11]		// 9/2:te0[s3>>16]
+	dep	te31=te13,te31,16,8	// 9/0:
+	shl	te01=te01,twenty4};;	// 9/1:
+{ .mii;	ld1	te12=[te12]		// 10/3:te0[s0>>16]
+	dep	te33=te20,te33,8,8	// 10/2:
+	shl	te02=te02,twenty4};;	// 10/2:
+{ .mii;	xor	t0=t0,te31		// 11/0:
+	dep	te30=te21,te30,8,8	// 11/3:
+	shl	te10=te10,sixteen};;	// 11/1:
+{ .mii;	xor	r16=t0,te00		// 12/0:done!
+	dep	te33=te11,te33,16,8	// 12/2:
+	shl	te03=te03,twenty4};;	// 12/3:
+{ .mmi;	xor	t1=t1,te01		// 13/1:
+	xor	t2=t2,te02		// 13/2:
+	dep	te30=te12,te30,16,8};;	// 13/3:
+{ .mmi;	xor	t1=t1,te32		// 14/1:
+	xor	r24=t2,te33		// 14/2:done!
+	xor	t3=t3,te30	};;	// 14/3:
+{ .mib;	xor	r20=t1,te10		// 15/1:done!
+	xor	r28=t3,te03		// 15/3:done!
+	br.ret.sptk	b6	};;
+.endp	_ia64_AES_decrypt#
+
+// void AES_decrypt (const void *in,void *out,const AES_KEY *key);
+.global	AES_decrypt#
+.proc	AES_decrypt#
+.align	32
+AES_decrypt:
+	.prologue
+	.save	ar.pfs,pfssave
+{ .mmi;	alloc	pfssave=ar.pfs,3,1,12,0
+	and	out0=3,in0
+	mov	r3=ip			}
+{ .mmi;	ADDP	in0=0,in0
+	mov	loc0=psr.um
+	ADDP	out11=KSZ*60,in2	};;	// &AES_KEY->rounds
+
+{ .mmi;	ld4	out11=[out11]			// AES_KEY->rounds
+	add	out8=(AES_Td#-AES_decrypt#),r3	// Te0
+	.save	pr,prsave
+	mov	prsave=pr		}
+{ .mmi;	rum	1<<3				// clear um.ac
+	.save	ar.lc,lcsave
+	mov	lcsave=ar.lc		};;
+
+	.body
+#if defined(_HPUX_SOURCE)	// HPUX is big-endian, cut 15+15 cycles...
+{ .mib; cmp.ne	p6,p0=out0,r0
+	add	out0=4,in0
+(p6)	br.dpnt.many	.Ld_i_unaligned	};;
+
+{ .mmi;	ld4	out1=[in0],8		// s0
+	and	out9=3,in1
+	mov	twenty4=24		}
+{ .mmi;	ld4	out3=[out0],8		// s1
+	ADDP	rk0=0,in2
+	mov	sixteen=16		};;
+{ .mmi;	ld4	out5=[in0]		// s2
+	cmp.ne	p6,p0=out9,r0
+	mov	maskff=0xff		}
+{ .mmb;	ld4	out7=[out0]		// s3
+	ADDP	rk1=KSZ,in2
+	br.call.sptk.many	b6=_ia64_AES_decrypt	};;
+
+{ .mib;	ADDP	in0=4,in1
+	ADDP	in1=0,in1
+(p6)	br.spnt	.Ld_o_unaligned		};;
+
+{ .mii;	mov	psr.um=loc0
+	mov	ar.pfs=pfssave
+	mov	ar.lc=lcsave		};;
+{ .mmi;	st4	[in1]=r16,8		// s0
+	st4	[in0]=r20,8		// s1
+	mov	pr=prsave,0x1ffff	};;
+{ .mmb;	st4	[in1]=r24		// s2
+	st4	[in0]=r28		// s3
+	br.ret.sptk.many	b0	};;
+#endif
+
+.align	32
+.Ld_i_unaligned:
+{ .mmi;	add	out0=1,in0
+	add	out2=2,in0
+	add	out4=3,in0	};;
+{ .mmi;	ld1	r16=[in0],4
+	ld1	r17=[out0],4	}//;;
+{ .mmi;	ld1	r18=[out2],4
+	ld1	out1=[out4],4	};;	// s0
+{ .mmi;	ld1	r20=[in0],4
+	ld1	r21=[out0],4	}//;;
+{ .mmi;	ld1	r22=[out2],4
+	ld1	out3=[out4],4	};;	// s1
+{ .mmi;	ld1	r24=[in0],4
+	ld1	r25=[out0],4	}//;;
+{ .mmi;	ld1	r26=[out2],4
+	ld1	out5=[out4],4	};;	// s2
+{ .mmi;	ld1	r28=[in0]
+	ld1	r29=[out0]	}//;;
+{ .mmi;	ld1	r30=[out2]
+	ld1	out7=[out4]	};;	// s3
+
+{ .mii;
+	dep	out1=r16,out1,24,8	//;;
+	dep	out3=r20,out3,24,8	}//;;
+{ .mii;	ADDP	rk0=0,in2
+	dep	out5=r24,out5,24,8	//;;
+	dep	out7=r28,out7,24,8	};;
+{ .mii;	ADDP	rk1=KSZ,in2
+	dep	out1=r17,out1,16,8	//;;
+	dep	out3=r21,out3,16,8	}//;;
+{ .mii;	mov	twenty4=24
+	dep	out5=r25,out5,16,8	//;;
+	dep	out7=r29,out7,16,8	};;
+{ .mii;	mov	sixteen=16
+	dep	out1=r18,out1,8,8	//;;
+	dep	out3=r22,out3,8,8	}//;;
+{ .mii;	mov	maskff=0xff
+	dep	out5=r26,out5,8,8	//;;
+	dep	out7=r30,out7,8,8	};;
+
+{ .mib;	br.call.sptk.many	b6=_ia64_AES_decrypt	};;
+
+.Ld_o_unaligned:
+{ .mii;	ADDP	out0=0,in1
+	extr.u	r17=r16,8,8			// s0
+	shr.u	r19=r16,twenty4		}//;;
+{ .mii;	ADDP	out1=1,in1
+	extr.u	r18=r16,16,8
+	shr.u	r23=r20,twenty4		}//;;	// s1
+{ .mii;	ADDP	out2=2,in1
+	extr.u	r21=r20,8,8
+	shr.u	r22=r20,sixteen		}//;;
+{ .mii;	ADDP	out3=3,in1
+	extr.u	r25=r24,8,8			// s2
+	shr.u	r27=r24,twenty4		};;
+{ .mii;	st1	[out3]=r16,4
+	extr.u	r26=r24,16,8
+	shr.u	r31=r28,twenty4		}//;;	// s3
+{ .mii;	st1	[out2]=r17,4
+	extr.u	r29=r28,8,8
+	shr.u	r30=r28,sixteen		}//;;
+
+{ .mmi;	st1	[out1]=r18,4
+	st1	[out0]=r19,4		};;
+{ .mmi;	st1	[out3]=r20,4
+	st1	[out2]=r21,4		}//;;
+{ .mmi;	st1	[out1]=r22,4
+	st1	[out0]=r23,4		};;
+{ .mmi;	st1	[out3]=r24,4
+	st1	[out2]=r25,4
+	mov	pr=prsave,0x1ffff	}//;;
+{ .mmi;	st1	[out1]=r26,4
+	st1	[out0]=r27,4
+	mov	ar.pfs=pfssave		};;
+{ .mmi;	st1	[out3]=r28
+	st1	[out2]=r29
+	mov	ar.lc=lcsave		}//;;
+{ .mmi;	st1	[out1]=r30
+	st1	[out0]=r31		}
+{ .mfb;	mov	psr.um=loc0			// restore user mask
+	br.ret.sptk.many	b0	};;
+.endp	AES_decrypt#
+
+// leave it in .text segment...
+.align	64
+.global	AES_Te#
+.type	AES_Te#,@object
+AES_Te:	data4	0xc66363a5,0xc66363a5, 0xf87c7c84,0xf87c7c84
+	data4	0xee777799,0xee777799, 0xf67b7b8d,0xf67b7b8d
+	data4	0xfff2f20d,0xfff2f20d, 0xd66b6bbd,0xd66b6bbd
+	data4	0xde6f6fb1,0xde6f6fb1, 0x91c5c554,0x91c5c554
+	data4	0x60303050,0x60303050, 0x02010103,0x02010103
+	data4	0xce6767a9,0xce6767a9, 0x562b2b7d,0x562b2b7d
+	data4	0xe7fefe19,0xe7fefe19, 0xb5d7d762,0xb5d7d762
+	data4	0x4dababe6,0x4dababe6, 0xec76769a,0xec76769a
+	data4	0x8fcaca45,0x8fcaca45, 0x1f82829d,0x1f82829d
+	data4	0x89c9c940,0x89c9c940, 0xfa7d7d87,0xfa7d7d87
+	data4	0xeffafa15,0xeffafa15, 0xb25959eb,0xb25959eb
+	data4	0x8e4747c9,0x8e4747c9, 0xfbf0f00b,0xfbf0f00b
+	data4	0x41adadec,0x41adadec, 0xb3d4d467,0xb3d4d467
+	data4	0x5fa2a2fd,0x5fa2a2fd, 0x45afafea,0x45afafea
+	data4	0x239c9cbf,0x239c9cbf, 0x53a4a4f7,0x53a4a4f7
+	data4	0xe4727296,0xe4727296, 0x9bc0c05b,0x9bc0c05b
+	data4	0x75b7b7c2,0x75b7b7c2, 0xe1fdfd1c,0xe1fdfd1c
+	data4	0x3d9393ae,0x3d9393ae, 0x4c26266a,0x4c26266a
+	data4	0x6c36365a,0x6c36365a, 0x7e3f3f41,0x7e3f3f41
+	data4	0xf5f7f702,0xf5f7f702, 0x83cccc4f,0x83cccc4f
+	data4	0x6834345c,0x6834345c, 0x51a5a5f4,0x51a5a5f4
+	data4	0xd1e5e534,0xd1e5e534, 0xf9f1f108,0xf9f1f108
+	data4	0xe2717193,0xe2717193, 0xabd8d873,0xabd8d873
+	data4	0x62313153,0x62313153, 0x2a15153f,0x2a15153f
+	data4	0x0804040c,0x0804040c, 0x95c7c752,0x95c7c752
+	data4	0x46232365,0x46232365, 0x9dc3c35e,0x9dc3c35e
+	data4	0x30181828,0x30181828, 0x379696a1,0x379696a1
+	data4	0x0a05050f,0x0a05050f, 0x2f9a9ab5,0x2f9a9ab5
+	data4	0x0e070709,0x0e070709, 0x24121236,0x24121236
+	data4	0x1b80809b,0x1b80809b, 0xdfe2e23d,0xdfe2e23d
+	data4	0xcdebeb26,0xcdebeb26, 0x4e272769,0x4e272769
+	data4	0x7fb2b2cd,0x7fb2b2cd, 0xea75759f,0xea75759f
+	data4	0x1209091b,0x1209091b, 0x1d83839e,0x1d83839e
+	data4	0x582c2c74,0x582c2c74, 0x341a1a2e,0x341a1a2e
+	data4	0x361b1b2d,0x361b1b2d, 0xdc6e6eb2,0xdc6e6eb2
+	data4	0xb45a5aee,0xb45a5aee, 0x5ba0a0fb,0x5ba0a0fb
+	data4	0xa45252f6,0xa45252f6, 0x763b3b4d,0x763b3b4d
+	data4	0xb7d6d661,0xb7d6d661, 0x7db3b3ce,0x7db3b3ce
+	data4	0x5229297b,0x5229297b, 0xdde3e33e,0xdde3e33e
+	data4	0x5e2f2f71,0x5e2f2f71, 0x13848497,0x13848497
+	data4	0xa65353f5,0xa65353f5, 0xb9d1d168,0xb9d1d168
+	data4	0x00000000,0x00000000, 0xc1eded2c,0xc1eded2c
+	data4	0x40202060,0x40202060, 0xe3fcfc1f,0xe3fcfc1f
+	data4	0x79b1b1c8,0x79b1b1c8, 0xb65b5bed,0xb65b5bed
+	data4	0xd46a6abe,0xd46a6abe, 0x8dcbcb46,0x8dcbcb46
+	data4	0x67bebed9,0x67bebed9, 0x7239394b,0x7239394b
+	data4	0x944a4ade,0x944a4ade, 0x984c4cd4,0x984c4cd4
+	data4	0xb05858e8,0xb05858e8, 0x85cfcf4a,0x85cfcf4a
+	data4	0xbbd0d06b,0xbbd0d06b, 0xc5efef2a,0xc5efef2a
+	data4	0x4faaaae5,0x4faaaae5, 0xedfbfb16,0xedfbfb16
+	data4	0x864343c5,0x864343c5, 0x9a4d4dd7,0x9a4d4dd7
+	data4	0x66333355,0x66333355, 0x11858594,0x11858594
+	data4	0x8a4545cf,0x8a4545cf, 0xe9f9f910,0xe9f9f910
+	data4	0x04020206,0x04020206, 0xfe7f7f81,0xfe7f7f81
+	data4	0xa05050f0,0xa05050f0, 0x783c3c44,0x783c3c44
+	data4	0x259f9fba,0x259f9fba, 0x4ba8a8e3,0x4ba8a8e3
+	data4	0xa25151f3,0xa25151f3, 0x5da3a3fe,0x5da3a3fe
+	data4	0x804040c0,0x804040c0, 0x058f8f8a,0x058f8f8a
+	data4	0x3f9292ad,0x3f9292ad, 0x219d9dbc,0x219d9dbc
+	data4	0x70383848,0x70383848, 0xf1f5f504,0xf1f5f504
+	data4	0x63bcbcdf,0x63bcbcdf, 0x77b6b6c1,0x77b6b6c1
+	data4	0xafdada75,0xafdada75, 0x42212163,0x42212163
+	data4	0x20101030,0x20101030, 0xe5ffff1a,0xe5ffff1a
+	data4	0xfdf3f30e,0xfdf3f30e, 0xbfd2d26d,0xbfd2d26d
+	data4	0x81cdcd4c,0x81cdcd4c, 0x180c0c14,0x180c0c14
+	data4	0x26131335,0x26131335, 0xc3ecec2f,0xc3ecec2f
+	data4	0xbe5f5fe1,0xbe5f5fe1, 0x359797a2,0x359797a2
+	data4	0x884444cc,0x884444cc, 0x2e171739,0x2e171739
+	data4	0x93c4c457,0x93c4c457, 0x55a7a7f2,0x55a7a7f2
+	data4	0xfc7e7e82,0xfc7e7e82, 0x7a3d3d47,0x7a3d3d47
+	data4	0xc86464ac,0xc86464ac, 0xba5d5de7,0xba5d5de7
+	data4	0x3219192b,0x3219192b, 0xe6737395,0xe6737395
+	data4	0xc06060a0,0xc06060a0, 0x19818198,0x19818198
+	data4	0x9e4f4fd1,0x9e4f4fd1, 0xa3dcdc7f,0xa3dcdc7f
+	data4	0x44222266,0x44222266, 0x542a2a7e,0x542a2a7e
+	data4	0x3b9090ab,0x3b9090ab, 0x0b888883,0x0b888883
+	data4	0x8c4646ca,0x8c4646ca, 0xc7eeee29,0xc7eeee29
+	data4	0x6bb8b8d3,0x6bb8b8d3, 0x2814143c,0x2814143c
+	data4	0xa7dede79,0xa7dede79, 0xbc5e5ee2,0xbc5e5ee2
+	data4	0x160b0b1d,0x160b0b1d, 0xaddbdb76,0xaddbdb76
+	data4	0xdbe0e03b,0xdbe0e03b, 0x64323256,0x64323256
+	data4	0x743a3a4e,0x743a3a4e, 0x140a0a1e,0x140a0a1e
+	data4	0x924949db,0x924949db, 0x0c06060a,0x0c06060a
+	data4	0x4824246c,0x4824246c, 0xb85c5ce4,0xb85c5ce4
+	data4	0x9fc2c25d,0x9fc2c25d, 0xbdd3d36e,0xbdd3d36e
+	data4	0x43acacef,0x43acacef, 0xc46262a6,0xc46262a6
+	data4	0x399191a8,0x399191a8, 0x319595a4,0x319595a4
+	data4	0xd3e4e437,0xd3e4e437, 0xf279798b,0xf279798b
+	data4	0xd5e7e732,0xd5e7e732, 0x8bc8c843,0x8bc8c843
+	data4	0x6e373759,0x6e373759, 0xda6d6db7,0xda6d6db7
+	data4	0x018d8d8c,0x018d8d8c, 0xb1d5d564,0xb1d5d564
+	data4	0x9c4e4ed2,0x9c4e4ed2, 0x49a9a9e0,0x49a9a9e0
+	data4	0xd86c6cb4,0xd86c6cb4, 0xac5656fa,0xac5656fa
+	data4	0xf3f4f407,0xf3f4f407, 0xcfeaea25,0xcfeaea25
+	data4	0xca6565af,0xca6565af, 0xf47a7a8e,0xf47a7a8e
+	data4	0x47aeaee9,0x47aeaee9, 0x10080818,0x10080818
+	data4	0x6fbabad5,0x6fbabad5, 0xf0787888,0xf0787888
+	data4	0x4a25256f,0x4a25256f, 0x5c2e2e72,0x5c2e2e72
+	data4	0x381c1c24,0x381c1c24, 0x57a6a6f1,0x57a6a6f1
+	data4	0x73b4b4c7,0x73b4b4c7, 0x97c6c651,0x97c6c651
+	data4	0xcbe8e823,0xcbe8e823, 0xa1dddd7c,0xa1dddd7c
+	data4	0xe874749c,0xe874749c, 0x3e1f1f21,0x3e1f1f21
+	data4	0x964b4bdd,0x964b4bdd, 0x61bdbddc,0x61bdbddc
+	data4	0x0d8b8b86,0x0d8b8b86, 0x0f8a8a85,0x0f8a8a85
+	data4	0xe0707090,0xe0707090, 0x7c3e3e42,0x7c3e3e42
+	data4	0x71b5b5c4,0x71b5b5c4, 0xcc6666aa,0xcc6666aa
+	data4	0x904848d8,0x904848d8, 0x06030305,0x06030305
+	data4	0xf7f6f601,0xf7f6f601, 0x1c0e0e12,0x1c0e0e12
+	data4	0xc26161a3,0xc26161a3, 0x6a35355f,0x6a35355f
+	data4	0xae5757f9,0xae5757f9, 0x69b9b9d0,0x69b9b9d0
+	data4	0x17868691,0x17868691, 0x99c1c158,0x99c1c158
+	data4	0x3a1d1d27,0x3a1d1d27, 0x279e9eb9,0x279e9eb9
+	data4	0xd9e1e138,0xd9e1e138, 0xebf8f813,0xebf8f813
+	data4	0x2b9898b3,0x2b9898b3, 0x22111133,0x22111133
+	data4	0xd26969bb,0xd26969bb, 0xa9d9d970,0xa9d9d970
+	data4	0x078e8e89,0x078e8e89, 0x339494a7,0x339494a7
+	data4	0x2d9b9bb6,0x2d9b9bb6, 0x3c1e1e22,0x3c1e1e22
+	data4	0x15878792,0x15878792, 0xc9e9e920,0xc9e9e920
+	data4	0x87cece49,0x87cece49, 0xaa5555ff,0xaa5555ff
+	data4	0x50282878,0x50282878, 0xa5dfdf7a,0xa5dfdf7a
+	data4	0x038c8c8f,0x038c8c8f, 0x59a1a1f8,0x59a1a1f8
+	data4	0x09898980,0x09898980, 0x1a0d0d17,0x1a0d0d17
+	data4	0x65bfbfda,0x65bfbfda, 0xd7e6e631,0xd7e6e631
+	data4	0x844242c6,0x844242c6, 0xd06868b8,0xd06868b8
+	data4	0x824141c3,0x824141c3, 0x299999b0,0x299999b0
+	data4	0x5a2d2d77,0x5a2d2d77, 0x1e0f0f11,0x1e0f0f11
+	data4	0x7bb0b0cb,0x7bb0b0cb, 0xa85454fc,0xa85454fc
+	data4	0x6dbbbbd6,0x6dbbbbd6, 0x2c16163a,0x2c16163a
+// Te4:
+	data1	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
+	data1	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+	data1	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
+	data1	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+	data1	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
+	data1	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+	data1	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
+	data1	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+	data1	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
+	data1	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+	data1	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
+	data1	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+	data1	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
+	data1	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+	data1	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+	data1	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+	data1	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
+	data1	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+	data1	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
+	data1	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+	data1	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
+	data1	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+	data1	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
+	data1	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+	data1	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
+	data1	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+	data1	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
+	data1	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+	data1	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
+	data1	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+	data1	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
+	data1	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+.size	AES_Te#,2048+256	// HP-UX assembler fails to ".-AES_Te#"
+
+.align	64
+.global	AES_Td#
+.type	AES_Td#,@object
+AES_Td:	data4	0x51f4a750,0x51f4a750, 0x7e416553,0x7e416553
+	data4	0x1a17a4c3,0x1a17a4c3, 0x3a275e96,0x3a275e96
+	data4	0x3bab6bcb,0x3bab6bcb, 0x1f9d45f1,0x1f9d45f1
+	data4	0xacfa58ab,0xacfa58ab, 0x4be30393,0x4be30393
+	data4	0x2030fa55,0x2030fa55, 0xad766df6,0xad766df6
+	data4	0x88cc7691,0x88cc7691, 0xf5024c25,0xf5024c25
+	data4	0x4fe5d7fc,0x4fe5d7fc, 0xc52acbd7,0xc52acbd7
+	data4	0x26354480,0x26354480, 0xb562a38f,0xb562a38f
+	data4	0xdeb15a49,0xdeb15a49, 0x25ba1b67,0x25ba1b67
+	data4	0x45ea0e98,0x45ea0e98, 0x5dfec0e1,0x5dfec0e1
+	data4	0xc32f7502,0xc32f7502, 0x814cf012,0x814cf012
+	data4	0x8d4697a3,0x8d4697a3, 0x6bd3f9c6,0x6bd3f9c6
+	data4	0x038f5fe7,0x038f5fe7, 0x15929c95,0x15929c95
+	data4	0xbf6d7aeb,0xbf6d7aeb, 0x955259da,0x955259da
+	data4	0xd4be832d,0xd4be832d, 0x587421d3,0x587421d3
+	data4	0x49e06929,0x49e06929, 0x8ec9c844,0x8ec9c844
+	data4	0x75c2896a,0x75c2896a, 0xf48e7978,0xf48e7978
+	data4	0x99583e6b,0x99583e6b, 0x27b971dd,0x27b971dd
+	data4	0xbee14fb6,0xbee14fb6, 0xf088ad17,0xf088ad17
+	data4	0xc920ac66,0xc920ac66, 0x7dce3ab4,0x7dce3ab4
+	data4	0x63df4a18,0x63df4a18, 0xe51a3182,0xe51a3182
+	data4	0x97513360,0x97513360, 0x62537f45,0x62537f45
+	data4	0xb16477e0,0xb16477e0, 0xbb6bae84,0xbb6bae84
+	data4	0xfe81a01c,0xfe81a01c, 0xf9082b94,0xf9082b94
+	data4	0x70486858,0x70486858, 0x8f45fd19,0x8f45fd19
+	data4	0x94de6c87,0x94de6c87, 0x527bf8b7,0x527bf8b7
+	data4	0xab73d323,0xab73d323, 0x724b02e2,0x724b02e2
+	data4	0xe31f8f57,0xe31f8f57, 0x6655ab2a,0x6655ab2a
+	data4	0xb2eb2807,0xb2eb2807, 0x2fb5c203,0x2fb5c203
+	data4	0x86c57b9a,0x86c57b9a, 0xd33708a5,0xd33708a5
+	data4	0x302887f2,0x302887f2, 0x23bfa5b2,0x23bfa5b2
+	data4	0x02036aba,0x02036aba, 0xed16825c,0xed16825c
+	data4	0x8acf1c2b,0x8acf1c2b, 0xa779b492,0xa779b492
+	data4	0xf307f2f0,0xf307f2f0, 0x4e69e2a1,0x4e69e2a1
+	data4	0x65daf4cd,0x65daf4cd, 0x0605bed5,0x0605bed5
+	data4	0xd134621f,0xd134621f, 0xc4a6fe8a,0xc4a6fe8a
+	data4	0x342e539d,0x342e539d, 0xa2f355a0,0xa2f355a0
+	data4	0x058ae132,0x058ae132, 0xa4f6eb75,0xa4f6eb75
+	data4	0x0b83ec39,0x0b83ec39, 0x4060efaa,0x4060efaa
+	data4	0x5e719f06,0x5e719f06, 0xbd6e1051,0xbd6e1051
+	data4	0x3e218af9,0x3e218af9, 0x96dd063d,0x96dd063d
+	data4	0xdd3e05ae,0xdd3e05ae, 0x4de6bd46,0x4de6bd46
+	data4	0x91548db5,0x91548db5, 0x71c45d05,0x71c45d05
+	data4	0x0406d46f,0x0406d46f, 0x605015ff,0x605015ff
+	data4	0x1998fb24,0x1998fb24, 0xd6bde997,0xd6bde997
+	data4	0x894043cc,0x894043cc, 0x67d99e77,0x67d99e77
+	data4	0xb0e842bd,0xb0e842bd, 0x07898b88,0x07898b88
+	data4	0xe7195b38,0xe7195b38, 0x79c8eedb,0x79c8eedb
+	data4	0xa17c0a47,0xa17c0a47, 0x7c420fe9,0x7c420fe9
+	data4	0xf8841ec9,0xf8841ec9, 0x00000000,0x00000000
+	data4	0x09808683,0x09808683, 0x322bed48,0x322bed48
+	data4	0x1e1170ac,0x1e1170ac, 0x6c5a724e,0x6c5a724e
+	data4	0xfd0efffb,0xfd0efffb, 0x0f853856,0x0f853856
+	data4	0x3daed51e,0x3daed51e, 0x362d3927,0x362d3927
+	data4	0x0a0fd964,0x0a0fd964, 0x685ca621,0x685ca621
+	data4	0x9b5b54d1,0x9b5b54d1, 0x24362e3a,0x24362e3a
+	data4	0x0c0a67b1,0x0c0a67b1, 0x9357e70f,0x9357e70f
+	data4	0xb4ee96d2,0xb4ee96d2, 0x1b9b919e,0x1b9b919e
+	data4	0x80c0c54f,0x80c0c54f, 0x61dc20a2,0x61dc20a2
+	data4	0x5a774b69,0x5a774b69, 0x1c121a16,0x1c121a16
+	data4	0xe293ba0a,0xe293ba0a, 0xc0a02ae5,0xc0a02ae5
+	data4	0x3c22e043,0x3c22e043, 0x121b171d,0x121b171d
+	data4	0x0e090d0b,0x0e090d0b, 0xf28bc7ad,0xf28bc7ad
+	data4	0x2db6a8b9,0x2db6a8b9, 0x141ea9c8,0x141ea9c8
+	data4	0x57f11985,0x57f11985, 0xaf75074c,0xaf75074c
+	data4	0xee99ddbb,0xee99ddbb, 0xa37f60fd,0xa37f60fd
+	data4	0xf701269f,0xf701269f, 0x5c72f5bc,0x5c72f5bc
+	data4	0x44663bc5,0x44663bc5, 0x5bfb7e34,0x5bfb7e34
+	data4	0x8b432976,0x8b432976, 0xcb23c6dc,0xcb23c6dc
+	data4	0xb6edfc68,0xb6edfc68, 0xb8e4f163,0xb8e4f163
+	data4	0xd731dcca,0xd731dcca, 0x42638510,0x42638510
+	data4	0x13972240,0x13972240, 0x84c61120,0x84c61120
+	data4	0x854a247d,0x854a247d, 0xd2bb3df8,0xd2bb3df8
+	data4	0xaef93211,0xaef93211, 0xc729a16d,0xc729a16d
+	data4	0x1d9e2f4b,0x1d9e2f4b, 0xdcb230f3,0xdcb230f3
+	data4	0x0d8652ec,0x0d8652ec, 0x77c1e3d0,0x77c1e3d0
+	data4	0x2bb3166c,0x2bb3166c, 0xa970b999,0xa970b999
+	data4	0x119448fa,0x119448fa, 0x47e96422,0x47e96422
+	data4	0xa8fc8cc4,0xa8fc8cc4, 0xa0f03f1a,0xa0f03f1a
+	data4	0x567d2cd8,0x567d2cd8, 0x223390ef,0x223390ef
+	data4	0x87494ec7,0x87494ec7, 0xd938d1c1,0xd938d1c1
+	data4	0x8ccaa2fe,0x8ccaa2fe, 0x98d40b36,0x98d40b36
+	data4	0xa6f581cf,0xa6f581cf, 0xa57ade28,0xa57ade28
+	data4	0xdab78e26,0xdab78e26, 0x3fadbfa4,0x3fadbfa4
+	data4	0x2c3a9de4,0x2c3a9de4, 0x5078920d,0x5078920d
+	data4	0x6a5fcc9b,0x6a5fcc9b, 0x547e4662,0x547e4662
+	data4	0xf68d13c2,0xf68d13c2, 0x90d8b8e8,0x90d8b8e8
+	data4	0x2e39f75e,0x2e39f75e, 0x82c3aff5,0x82c3aff5
+	data4	0x9f5d80be,0x9f5d80be, 0x69d0937c,0x69d0937c
+	data4	0x6fd52da9,0x6fd52da9, 0xcf2512b3,0xcf2512b3
+	data4	0xc8ac993b,0xc8ac993b, 0x10187da7,0x10187da7
+	data4	0xe89c636e,0xe89c636e, 0xdb3bbb7b,0xdb3bbb7b
+	data4	0xcd267809,0xcd267809, 0x6e5918f4,0x6e5918f4
+	data4	0xec9ab701,0xec9ab701, 0x834f9aa8,0x834f9aa8
+	data4	0xe6956e65,0xe6956e65, 0xaaffe67e,0xaaffe67e
+	data4	0x21bccf08,0x21bccf08, 0xef15e8e6,0xef15e8e6
+	data4	0xbae79bd9,0xbae79bd9, 0x4a6f36ce,0x4a6f36ce
+	data4	0xea9f09d4,0xea9f09d4, 0x29b07cd6,0x29b07cd6
+	data4	0x31a4b2af,0x31a4b2af, 0x2a3f2331,0x2a3f2331
+	data4	0xc6a59430,0xc6a59430, 0x35a266c0,0x35a266c0
+	data4	0x744ebc37,0x744ebc37, 0xfc82caa6,0xfc82caa6
+	data4	0xe090d0b0,0xe090d0b0, 0x33a7d815,0x33a7d815
+	data4	0xf104984a,0xf104984a, 0x41ecdaf7,0x41ecdaf7
+	data4	0x7fcd500e,0x7fcd500e, 0x1791f62f,0x1791f62f
+	data4	0x764dd68d,0x764dd68d, 0x43efb04d,0x43efb04d
+	data4	0xccaa4d54,0xccaa4d54, 0xe49604df,0xe49604df
+	data4	0x9ed1b5e3,0x9ed1b5e3, 0x4c6a881b,0x4c6a881b
+	data4	0xc12c1fb8,0xc12c1fb8, 0x4665517f,0x4665517f
+	data4	0x9d5eea04,0x9d5eea04, 0x018c355d,0x018c355d
+	data4	0xfa877473,0xfa877473, 0xfb0b412e,0xfb0b412e
+	data4	0xb3671d5a,0xb3671d5a, 0x92dbd252,0x92dbd252
+	data4	0xe9105633,0xe9105633, 0x6dd64713,0x6dd64713
+	data4	0x9ad7618c,0x9ad7618c, 0x37a10c7a,0x37a10c7a
+	data4	0x59f8148e,0x59f8148e, 0xeb133c89,0xeb133c89
+	data4	0xcea927ee,0xcea927ee, 0xb761c935,0xb761c935
+	data4	0xe11ce5ed,0xe11ce5ed, 0x7a47b13c,0x7a47b13c
+	data4	0x9cd2df59,0x9cd2df59, 0x55f2733f,0x55f2733f
+	data4	0x1814ce79,0x1814ce79, 0x73c737bf,0x73c737bf
+	data4	0x53f7cdea,0x53f7cdea, 0x5ffdaa5b,0x5ffdaa5b
+	data4	0xdf3d6f14,0xdf3d6f14, 0x7844db86,0x7844db86
+	data4	0xcaaff381,0xcaaff381, 0xb968c43e,0xb968c43e
+	data4	0x3824342c,0x3824342c, 0xc2a3405f,0xc2a3405f
+	data4	0x161dc372,0x161dc372, 0xbce2250c,0xbce2250c
+	data4	0x283c498b,0x283c498b, 0xff0d9541,0xff0d9541
+	data4	0x39a80171,0x39a80171, 0x080cb3de,0x080cb3de
+	data4	0xd8b4e49c,0xd8b4e49c, 0x6456c190,0x6456c190
+	data4	0x7bcb8461,0x7bcb8461, 0xd532b670,0xd532b670
+	data4	0x486c5c74,0x486c5c74, 0xd0b85742,0xd0b85742
+// Td4:
+	data1	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
+	data1	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+	data1	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
+	data1	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+	data1	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
+	data1	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+	data1	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
+	data1	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+	data1	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
+	data1	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+	data1	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
+	data1	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+	data1	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
+	data1	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+	data1	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
+	data1	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+	data1	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
+	data1	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+	data1	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
+	data1	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+	data1	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
+	data1	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+	data1	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
+	data1	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+	data1	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
+	data1	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+	data1	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
+	data1	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+	data1	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
+	data1	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+	data1	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
+	data1	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+.size	AES_Td#,2048+256	// HP-UX assembler fails to ".-AES_Td#"
diff --git a/openssl/crypto/aes/asm/aes-ppc.pl b/openssl/crypto/aes/asm/aes-ppc.pl
new file mode 100644
index 0000000..f82c5e1
--- /dev/null
+++ b/openssl/crypto/aes/asm/aes-ppc.pl
@@ -0,0 +1,1189 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# Needs more work: key setup, page boundaries, CBC routine...
+#
+# ppc_AES_[en|de]crypt perform at 18 cycles per byte processed with
+# 128-bit key, which is ~40% better than 64-bit code generated by gcc
+# 4.0. But these are not the ones currently used! Their "compact"
+# counterparts are, for security reason. ppc_AES_encrypt_compact runs
+# at 1/2 of ppc_AES_encrypt speed, while ppc_AES_decrypt_compact -
+# at 1/3 of ppc_AES_decrypt.
+
+# February 2010
+#
+# Rescheduling instructions to favour Power6 pipeline gives 10%
+# performance improvement on the platfrom in question (and marginal
+# improvement even on others). It should be noted that Power6 fails
+# to process byte in 18 cycles, only in 23, because it fails to issue
+# 4 load instructions in two cycles, only in 3. As result non-compact
+# block subroutines are 25% slower than one would expect. Compact
+# functions scale better, because they have pure computational part,
+# which scales perfectly with clock frequency. To be specific
+# ppc_AES_encrypt_compact operates at 42 cycles per byte, while
+# ppc_AES_decrypt_compact - at 55 (in 64-bit build).
+
+$flavour = shift;
+
+if ($flavour =~ /64/) {
+	$SIZE_T	=8;
+	$STU	="stdu";
+	$POP	="ld";
+	$PUSH	="std";
+} elsif ($flavour =~ /32/) {
+	$SIZE_T	=4;
+	$STU	="stwu";
+	$POP	="lwz";
+	$PUSH	="stw";
+} else { die "nonsense $flavour"; }
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
+
+$FRAME=32*$SIZE_T;
+
+sub _data_word()
+{ my $i;
+    while(defined($i=shift)) { $code.=sprintf"\t.long\t0x%08x,0x%08x\n",$i,$i; }
+}
+
+$sp="r1";
+$toc="r2";
+$inp="r3";
+$out="r4";
+$key="r5";
+
+$Tbl0="r3";
+$Tbl1="r6";
+$Tbl2="r7";
+$Tbl3="r2";
+
+$s0="r8";
+$s1="r9";
+$s2="r10";
+$s3="r11";
+
+$t0="r12";
+$t1="r13";
+$t2="r14";
+$t3="r15";
+
+$acc00="r16";
+$acc01="r17";
+$acc02="r18";
+$acc03="r19";
+
+$acc04="r20";
+$acc05="r21";
+$acc06="r22";
+$acc07="r23";
+
+$acc08="r24";
+$acc09="r25";
+$acc10="r26";
+$acc11="r27";
+
+$acc12="r28";
+$acc13="r29";
+$acc14="r30";
+$acc15="r31";
+
+# stay away from TLS pointer
+if ($SIZE_T==8)	{ die if ($t1 ne "r13");  $t1="r0";		}
+else		{ die if ($Tbl3 ne "r2"); $Tbl3=$t0; $t0="r0";	}
+$mask80=$Tbl2;
+$mask1b=$Tbl3;
+
+$code.=<<___;
+.machine	"any"
+.text
+
+.align	7
+LAES_Te:
+	mflr	r0
+	bcl	20,31,\$+4
+	mflr	$Tbl0	;    vvvvv "distance" between . and 1st data entry
+	addi	$Tbl0,$Tbl0,`128-8`
+	mtlr	r0
+	blr
+	.space	`32-24`
+LAES_Td:
+	mflr	r0
+	bcl	20,31,\$+4
+	mflr	$Tbl0	;    vvvvvvvv "distance" between . and 1st data entry
+	addi	$Tbl0,$Tbl0,`128-8-32+2048+256`
+	mtlr	r0
+	blr
+	.space	`128-32-24`
+___
+&_data_word(
+	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
+	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
+	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
+	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
+	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
+	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
+	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
+	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
+	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
+	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
+	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
+	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
+	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
+	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
+	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
+	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
+	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
+	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
+	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
+	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
+	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
+	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
+	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
+	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
+	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
+	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
+	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
+	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
+	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
+	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
+	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
+	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
+	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
+	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
+	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
+	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
+	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
+	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
+	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
+	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
+	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
+	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
+	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
+	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
+	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
+	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
+	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
+	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
+	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
+	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
+	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
+	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
+	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
+	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
+	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
+	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
+	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
+	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
+	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
+	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
+	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
+	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
+	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
+	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
+$code.=<<___;
+.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
+.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
+.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
+.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
+.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
+.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
+.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
+.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
+.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
+.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
+.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
+.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
+.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
+.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
+.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
+.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+___
+&_data_word(
+	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
+	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
+	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
+	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
+	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
+	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
+	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
+	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
+	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
+	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
+	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
+	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
+	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
+	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
+	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
+	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
+	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
+	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
+	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
+	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
+	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
+	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
+	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
+	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
+	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
+	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
+	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
+	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
+	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
+	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
+	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
+	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
+	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
+	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
+	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
+	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
+	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
+	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
+	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
+	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
+	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
+	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
+	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
+	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
+	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
+	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
+	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
+	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
+	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
+	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
+	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
+	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
+	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
+	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
+	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
+	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
+	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
+	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
+	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
+	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
+	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
+	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
+	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
+	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
+$code.=<<___;
+.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
+.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
+.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
+.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
+.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
+.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
+.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
+.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
+.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
+.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
+.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
+.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
+.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
+.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
+.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
+.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
+.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+
+
+.globl	.AES_encrypt
+.align	7
+.AES_encrypt:
+	mflr	r0
+	$STU	$sp,-$FRAME($sp)
+
+	$PUSH	r0,`$FRAME-$SIZE_T*21`($sp)
+	$PUSH	$toc,`$FRAME-$SIZE_T*20`($sp)
+	$PUSH	r13,`$FRAME-$SIZE_T*19`($sp)
+	$PUSH	r14,`$FRAME-$SIZE_T*18`($sp)
+	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
+	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
+	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
+	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
+	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
+	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
+	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
+	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
+	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
+	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
+	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
+	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
+	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
+
+	lwz	$s0,0($inp)
+	lwz	$s1,4($inp)
+	lwz	$s2,8($inp)
+	lwz	$s3,12($inp)
+	bl	LAES_Te
+	bl	Lppc_AES_encrypt_compact
+	stw	$s0,0($out)
+	stw	$s1,4($out)
+	stw	$s2,8($out)
+	stw	$s3,12($out)
+
+	$POP	r0,`$FRAME-$SIZE_T*21`($sp)
+	$POP	$toc,`$FRAME-$SIZE_T*20`($sp)
+	$POP	r13,`$FRAME-$SIZE_T*19`($sp)
+	$POP	r14,`$FRAME-$SIZE_T*18`($sp)
+	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
+	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
+	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
+	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
+	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
+	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
+	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
+	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
+	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
+	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
+	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
+	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
+	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
+	mtlr	r0
+	addi	$sp,$sp,$FRAME
+	blr
+
+.align	5
+Lppc_AES_encrypt:
+	lwz	$acc00,240($key)
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	addi	$Tbl1,$Tbl0,3
+	addi	$Tbl2,$Tbl0,2
+	addi	$Tbl3,$Tbl0,1
+	addi	$acc00,$acc00,-1
+	addi	$key,$key,16
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	mtctr	$acc00
+.align	4
+Lenc_loop:
+	rlwinm	$acc00,$s0,`32-24+3`,21,28
+	rlwinm	$acc01,$s1,`32-24+3`,21,28
+	rlwinm	$acc02,$s2,`32-24+3`,21,28
+	rlwinm	$acc03,$s3,`32-24+3`,21,28
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	rlwinm	$acc04,$s1,`32-16+3`,21,28
+	rlwinm	$acc05,$s2,`32-16+3`,21,28
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	rlwinm	$acc06,$s3,`32-16+3`,21,28
+	rlwinm	$acc07,$s0,`32-16+3`,21,28
+	lwzx	$acc00,$Tbl0,$acc00
+	lwzx	$acc01,$Tbl0,$acc01
+	rlwinm	$acc08,$s2,`32-8+3`,21,28
+	rlwinm	$acc09,$s3,`32-8+3`,21,28
+	lwzx	$acc02,$Tbl0,$acc02
+	lwzx	$acc03,$Tbl0,$acc03
+	rlwinm	$acc10,$s0,`32-8+3`,21,28
+	rlwinm	$acc11,$s1,`32-8+3`,21,28
+	lwzx	$acc04,$Tbl1,$acc04
+	lwzx	$acc05,$Tbl1,$acc05
+	rlwinm	$acc12,$s3,`0+3`,21,28
+	rlwinm	$acc13,$s0,`0+3`,21,28
+	lwzx	$acc06,$Tbl1,$acc06
+	lwzx	$acc07,$Tbl1,$acc07
+	rlwinm	$acc14,$s1,`0+3`,21,28
+	rlwinm	$acc15,$s2,`0+3`,21,28
+	lwzx	$acc08,$Tbl2,$acc08
+	lwzx	$acc09,$Tbl2,$acc09
+	xor	$t0,$t0,$acc00
+	xor	$t1,$t1,$acc01
+	lwzx	$acc10,$Tbl2,$acc10
+	lwzx	$acc11,$Tbl2,$acc11
+	xor	$t2,$t2,$acc02
+	xor	$t3,$t3,$acc03
+	lwzx	$acc12,$Tbl3,$acc12
+	lwzx	$acc13,$Tbl3,$acc13
+	xor	$t0,$t0,$acc04
+	xor	$t1,$t1,$acc05
+	lwzx	$acc14,$Tbl3,$acc14
+	lwzx	$acc15,$Tbl3,$acc15
+	xor	$t2,$t2,$acc06
+	xor	$t3,$t3,$acc07
+	xor	$t0,$t0,$acc08
+	xor	$t1,$t1,$acc09
+	xor	$t2,$t2,$acc10
+	xor	$t3,$t3,$acc11
+	xor	$s0,$t0,$acc12
+	xor	$s1,$t1,$acc13
+	xor	$s2,$t2,$acc14
+	xor	$s3,$t3,$acc15
+	addi	$key,$key,16
+	bdnz-	Lenc_loop
+
+	addi	$Tbl2,$Tbl0,2048
+	nop
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	rlwinm	$acc00,$s0,`32-24`,24,31
+	rlwinm	$acc01,$s1,`32-24`,24,31
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	rlwinm	$acc02,$s2,`32-24`,24,31
+	rlwinm	$acc03,$s3,`32-24`,24,31
+	lwz	$acc08,`2048+0`($Tbl0)	! prefetch Te4
+	lwz	$acc09,`2048+32`($Tbl0)
+	rlwinm	$acc04,$s1,`32-16`,24,31
+	rlwinm	$acc05,$s2,`32-16`,24,31
+	lwz	$acc10,`2048+64`($Tbl0)
+	lwz	$acc11,`2048+96`($Tbl0)
+	rlwinm	$acc06,$s3,`32-16`,24,31
+	rlwinm	$acc07,$s0,`32-16`,24,31
+	lwz	$acc12,`2048+128`($Tbl0)
+	lwz	$acc13,`2048+160`($Tbl0)
+	rlwinm	$acc08,$s2,`32-8`,24,31
+	rlwinm	$acc09,$s3,`32-8`,24,31
+	lwz	$acc14,`2048+192`($Tbl0)
+	lwz	$acc15,`2048+224`($Tbl0)
+	rlwinm	$acc10,$s0,`32-8`,24,31
+	rlwinm	$acc11,$s1,`32-8`,24,31
+	lbzx	$acc00,$Tbl2,$acc00
+	lbzx	$acc01,$Tbl2,$acc01
+	rlwinm	$acc12,$s3,`0`,24,31
+	rlwinm	$acc13,$s0,`0`,24,31
+	lbzx	$acc02,$Tbl2,$acc02
+	lbzx	$acc03,$Tbl2,$acc03
+	rlwinm	$acc14,$s1,`0`,24,31
+	rlwinm	$acc15,$s2,`0`,24,31
+	lbzx	$acc04,$Tbl2,$acc04
+	lbzx	$acc05,$Tbl2,$acc05
+	rlwinm	$s0,$acc00,24,0,7
+	rlwinm	$s1,$acc01,24,0,7
+	lbzx	$acc06,$Tbl2,$acc06
+	lbzx	$acc07,$Tbl2,$acc07
+	rlwinm	$s2,$acc02,24,0,7
+	rlwinm	$s3,$acc03,24,0,7
+	lbzx	$acc08,$Tbl2,$acc08
+	lbzx	$acc09,$Tbl2,$acc09
+	rlwimi	$s0,$acc04,16,8,15
+	rlwimi	$s1,$acc05,16,8,15
+	lbzx	$acc10,$Tbl2,$acc10
+	lbzx	$acc11,$Tbl2,$acc11
+	rlwimi	$s2,$acc06,16,8,15
+	rlwimi	$s3,$acc07,16,8,15
+	lbzx	$acc12,$Tbl2,$acc12
+	lbzx	$acc13,$Tbl2,$acc13
+	rlwimi	$s0,$acc08,8,16,23
+	rlwimi	$s1,$acc09,8,16,23
+	lbzx	$acc14,$Tbl2,$acc14
+	lbzx	$acc15,$Tbl2,$acc15
+	rlwimi	$s2,$acc10,8,16,23
+	rlwimi	$s3,$acc11,8,16,23
+	or	$s0,$s0,$acc12
+	or	$s1,$s1,$acc13
+	or	$s2,$s2,$acc14
+	or	$s3,$s3,$acc15
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	blr
+
+.align	4
+Lppc_AES_encrypt_compact:
+	lwz	$acc00,240($key)
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	addi	$Tbl1,$Tbl0,2048
+	lis	$mask80,0x8080
+	lis	$mask1b,0x1b1b
+	addi	$key,$key,16
+	ori	$mask80,$mask80,0x8080
+	ori	$mask1b,$mask1b,0x1b1b
+	mtctr	$acc00
+.align	4
+Lenc_compact_loop:
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	rlwinm	$acc00,$s0,`32-24`,24,31
+	rlwinm	$acc01,$s1,`32-24`,24,31
+	rlwinm	$acc02,$s2,`32-24`,24,31
+	rlwinm	$acc03,$s3,`32-24`,24,31
+	rlwinm	$acc04,$s1,`32-16`,24,31
+	rlwinm	$acc05,$s2,`32-16`,24,31
+	rlwinm	$acc06,$s3,`32-16`,24,31
+	rlwinm	$acc07,$s0,`32-16`,24,31
+	lbzx	$acc00,$Tbl1,$acc00
+	lbzx	$acc01,$Tbl1,$acc01
+	rlwinm	$acc08,$s2,`32-8`,24,31
+	rlwinm	$acc09,$s3,`32-8`,24,31
+	lbzx	$acc02,$Tbl1,$acc02
+	lbzx	$acc03,$Tbl1,$acc03
+	rlwinm	$acc10,$s0,`32-8`,24,31
+	rlwinm	$acc11,$s1,`32-8`,24,31
+	lbzx	$acc04,$Tbl1,$acc04
+	lbzx	$acc05,$Tbl1,$acc05
+	rlwinm	$acc12,$s3,`0`,24,31
+	rlwinm	$acc13,$s0,`0`,24,31
+	lbzx	$acc06,$Tbl1,$acc06
+	lbzx	$acc07,$Tbl1,$acc07
+	rlwinm	$acc14,$s1,`0`,24,31
+	rlwinm	$acc15,$s2,`0`,24,31
+	lbzx	$acc08,$Tbl1,$acc08
+	lbzx	$acc09,$Tbl1,$acc09
+	rlwinm	$s0,$acc00,24,0,7
+	rlwinm	$s1,$acc01,24,0,7
+	lbzx	$acc10,$Tbl1,$acc10
+	lbzx	$acc11,$Tbl1,$acc11
+	rlwinm	$s2,$acc02,24,0,7
+	rlwinm	$s3,$acc03,24,0,7
+	lbzx	$acc12,$Tbl1,$acc12
+	lbzx	$acc13,$Tbl1,$acc13
+	rlwimi	$s0,$acc04,16,8,15
+	rlwimi	$s1,$acc05,16,8,15
+	lbzx	$acc14,$Tbl1,$acc14
+	lbzx	$acc15,$Tbl1,$acc15
+	rlwimi	$s2,$acc06,16,8,15
+	rlwimi	$s3,$acc07,16,8,15
+	rlwimi	$s0,$acc08,8,16,23
+	rlwimi	$s1,$acc09,8,16,23
+	rlwimi	$s2,$acc10,8,16,23
+	rlwimi	$s3,$acc11,8,16,23
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	or	$s0,$s0,$acc12
+	or	$s1,$s1,$acc13
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	or	$s2,$s2,$acc14
+	or	$s3,$s3,$acc15
+
+	addi	$key,$key,16
+	bdz	Lenc_compact_done
+
+	and	$acc00,$s0,$mask80	# r1=r0&0x80808080
+	and	$acc01,$s1,$mask80
+	and	$acc02,$s2,$mask80
+	and	$acc03,$s3,$mask80
+	srwi	$acc04,$acc00,7		# r1>>7
+	srwi	$acc05,$acc01,7
+	srwi	$acc06,$acc02,7
+	srwi	$acc07,$acc03,7
+	andc	$acc08,$s0,$mask80	# r0&0x7f7f7f7f
+	andc	$acc09,$s1,$mask80
+	andc	$acc10,$s2,$mask80
+	andc	$acc11,$s3,$mask80
+	sub	$acc00,$acc00,$acc04	# r1-(r1>>7)
+	sub	$acc01,$acc01,$acc05
+	sub	$acc02,$acc02,$acc06
+	sub	$acc03,$acc03,$acc07
+	add	$acc08,$acc08,$acc08	# (r0&0x7f7f7f7f)<<1
+	add	$acc09,$acc09,$acc09
+	add	$acc10,$acc10,$acc10
+	add	$acc11,$acc11,$acc11
+	and	$acc00,$acc00,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc01,$acc01,$mask1b
+	and	$acc02,$acc02,$mask1b
+	and	$acc03,$acc03,$mask1b
+	xor	$acc00,$acc00,$acc08	# r2
+	xor	$acc01,$acc01,$acc09
+	xor	$acc02,$acc02,$acc10
+	xor	$acc03,$acc03,$acc11
+
+	rotlwi	$acc12,$s0,16		# ROTATE(r0,16)
+	rotlwi	$acc13,$s1,16
+	rotlwi	$acc14,$s2,16
+	rotlwi	$acc15,$s3,16
+	xor	$s0,$s0,$acc00		# r0^r2
+	xor	$s1,$s1,$acc01
+	xor	$s2,$s2,$acc02
+	xor	$s3,$s3,$acc03
+	rotrwi	$s0,$s0,24		# ROTATE(r2^r0,24)
+	rotrwi	$s1,$s1,24
+	rotrwi	$s2,$s2,24
+	rotrwi	$s3,$s3,24
+	xor	$s0,$s0,$acc00		# ROTATE(r2^r0,24)^r2
+	xor	$s1,$s1,$acc01
+	xor	$s2,$s2,$acc02
+	xor	$s3,$s3,$acc03
+	rotlwi	$acc08,$acc12,8		# ROTATE(r0,24)
+	rotlwi	$acc09,$acc13,8
+	rotlwi	$acc10,$acc14,8
+	rotlwi	$acc11,$acc15,8
+	xor	$s0,$s0,$acc12		#
+	xor	$s1,$s1,$acc13
+	xor	$s2,$s2,$acc14
+	xor	$s3,$s3,$acc15
+	xor	$s0,$s0,$acc08		#
+	xor	$s1,$s1,$acc09
+	xor	$s2,$s2,$acc10
+	xor	$s3,$s3,$acc11
+
+	b	Lenc_compact_loop
+.align	4
+Lenc_compact_done:
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	blr
+
+.globl	.AES_decrypt
+.align	7
+.AES_decrypt:
+	mflr	r0
+	$STU	$sp,-$FRAME($sp)
+
+	$PUSH	r0,`$FRAME-$SIZE_T*21`($sp)
+	$PUSH	$toc,`$FRAME-$SIZE_T*20`($sp)
+	$PUSH	r13,`$FRAME-$SIZE_T*19`($sp)
+	$PUSH	r14,`$FRAME-$SIZE_T*18`($sp)
+	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
+	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
+	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
+	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
+	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
+	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
+	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
+	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
+	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
+	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
+	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
+	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
+	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
+
+	lwz	$s0,0($inp)
+	lwz	$s1,4($inp)
+	lwz	$s2,8($inp)
+	lwz	$s3,12($inp)
+	bl	LAES_Td
+	bl	Lppc_AES_decrypt_compact
+	stw	$s0,0($out)
+	stw	$s1,4($out)
+	stw	$s2,8($out)
+	stw	$s3,12($out)
+
+	$POP	r0,`$FRAME-$SIZE_T*21`($sp)
+	$POP	$toc,`$FRAME-$SIZE_T*20`($sp)
+	$POP	r13,`$FRAME-$SIZE_T*19`($sp)
+	$POP	r14,`$FRAME-$SIZE_T*18`($sp)
+	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
+	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
+	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
+	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
+	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
+	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
+	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
+	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
+	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
+	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
+	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
+	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
+	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
+	mtlr	r0
+	addi	$sp,$sp,$FRAME
+	blr
+
+.align	5
+Lppc_AES_decrypt:
+	lwz	$acc00,240($key)
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	addi	$Tbl1,$Tbl0,3
+	addi	$Tbl2,$Tbl0,2
+	addi	$Tbl3,$Tbl0,1
+	addi	$acc00,$acc00,-1
+	addi	$key,$key,16
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	mtctr	$acc00
+.align	4
+Ldec_loop:
+	rlwinm	$acc00,$s0,`32-24+3`,21,28
+	rlwinm	$acc01,$s1,`32-24+3`,21,28
+	rlwinm	$acc02,$s2,`32-24+3`,21,28
+	rlwinm	$acc03,$s3,`32-24+3`,21,28
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	rlwinm	$acc04,$s3,`32-16+3`,21,28
+	rlwinm	$acc05,$s0,`32-16+3`,21,28
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	rlwinm	$acc06,$s1,`32-16+3`,21,28
+	rlwinm	$acc07,$s2,`32-16+3`,21,28
+	lwzx	$acc00,$Tbl0,$acc00
+	lwzx	$acc01,$Tbl0,$acc01
+	rlwinm	$acc08,$s2,`32-8+3`,21,28
+	rlwinm	$acc09,$s3,`32-8+3`,21,28
+	lwzx	$acc02,$Tbl0,$acc02
+	lwzx	$acc03,$Tbl0,$acc03
+	rlwinm	$acc10,$s0,`32-8+3`,21,28
+	rlwinm	$acc11,$s1,`32-8+3`,21,28
+	lwzx	$acc04,$Tbl1,$acc04
+	lwzx	$acc05,$Tbl1,$acc05
+	rlwinm	$acc12,$s1,`0+3`,21,28
+	rlwinm	$acc13,$s2,`0+3`,21,28
+	lwzx	$acc06,$Tbl1,$acc06
+	lwzx	$acc07,$Tbl1,$acc07
+	rlwinm	$acc14,$s3,`0+3`,21,28
+	rlwinm	$acc15,$s0,`0+3`,21,28
+	lwzx	$acc08,$Tbl2,$acc08
+	lwzx	$acc09,$Tbl2,$acc09
+	xor	$t0,$t0,$acc00
+	xor	$t1,$t1,$acc01
+	lwzx	$acc10,$Tbl2,$acc10
+	lwzx	$acc11,$Tbl2,$acc11
+	xor	$t2,$t2,$acc02
+	xor	$t3,$t3,$acc03
+	lwzx	$acc12,$Tbl3,$acc12
+	lwzx	$acc13,$Tbl3,$acc13
+	xor	$t0,$t0,$acc04
+	xor	$t1,$t1,$acc05
+	lwzx	$acc14,$Tbl3,$acc14
+	lwzx	$acc15,$Tbl3,$acc15
+	xor	$t2,$t2,$acc06
+	xor	$t3,$t3,$acc07
+	xor	$t0,$t0,$acc08
+	xor	$t1,$t1,$acc09
+	xor	$t2,$t2,$acc10
+	xor	$t3,$t3,$acc11
+	xor	$s0,$t0,$acc12
+	xor	$s1,$t1,$acc13
+	xor	$s2,$t2,$acc14
+	xor	$s3,$t3,$acc15
+	addi	$key,$key,16
+	bdnz-	Ldec_loop
+
+	addi	$Tbl2,$Tbl0,2048
+	nop
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	rlwinm	$acc00,$s0,`32-24`,24,31
+	rlwinm	$acc01,$s1,`32-24`,24,31
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	rlwinm	$acc02,$s2,`32-24`,24,31
+	rlwinm	$acc03,$s3,`32-24`,24,31
+	lwz	$acc08,`2048+0`($Tbl0)	! prefetch Td4
+	lwz	$acc09,`2048+32`($Tbl0)
+	rlwinm	$acc04,$s3,`32-16`,24,31
+	rlwinm	$acc05,$s0,`32-16`,24,31
+	lwz	$acc10,`2048+64`($Tbl0)
+	lwz	$acc11,`2048+96`($Tbl0)
+	lbzx	$acc00,$Tbl2,$acc00
+	lbzx	$acc01,$Tbl2,$acc01
+	lwz	$acc12,`2048+128`($Tbl0)
+	lwz	$acc13,`2048+160`($Tbl0)
+	rlwinm	$acc06,$s1,`32-16`,24,31
+	rlwinm	$acc07,$s2,`32-16`,24,31
+	lwz	$acc14,`2048+192`($Tbl0)
+	lwz	$acc15,`2048+224`($Tbl0)
+	rlwinm	$acc08,$s2,`32-8`,24,31
+	rlwinm	$acc09,$s3,`32-8`,24,31
+	lbzx	$acc02,$Tbl2,$acc02
+	lbzx	$acc03,$Tbl2,$acc03
+	rlwinm	$acc10,$s0,`32-8`,24,31
+	rlwinm	$acc11,$s1,`32-8`,24,31
+	lbzx	$acc04,$Tbl2,$acc04
+	lbzx	$acc05,$Tbl2,$acc05
+	rlwinm	$acc12,$s1,`0`,24,31
+	rlwinm	$acc13,$s2,`0`,24,31
+	lbzx	$acc06,$Tbl2,$acc06
+	lbzx	$acc07,$Tbl2,$acc07
+	rlwinm	$acc14,$s3,`0`,24,31
+	rlwinm	$acc15,$s0,`0`,24,31
+	lbzx	$acc08,$Tbl2,$acc08
+	lbzx	$acc09,$Tbl2,$acc09
+	rlwinm	$s0,$acc00,24,0,7
+	rlwinm	$s1,$acc01,24,0,7
+	lbzx	$acc10,$Tbl2,$acc10
+	lbzx	$acc11,$Tbl2,$acc11
+	rlwinm	$s2,$acc02,24,0,7
+	rlwinm	$s3,$acc03,24,0,7
+	lbzx	$acc12,$Tbl2,$acc12
+	lbzx	$acc13,$Tbl2,$acc13
+	rlwimi	$s0,$acc04,16,8,15
+	rlwimi	$s1,$acc05,16,8,15
+	lbzx	$acc14,$Tbl2,$acc14
+	lbzx	$acc15,$Tbl2,$acc15
+	rlwimi	$s2,$acc06,16,8,15
+	rlwimi	$s3,$acc07,16,8,15
+	rlwimi	$s0,$acc08,8,16,23
+	rlwimi	$s1,$acc09,8,16,23
+	rlwimi	$s2,$acc10,8,16,23
+	rlwimi	$s3,$acc11,8,16,23
+	or	$s0,$s0,$acc12
+	or	$s1,$s1,$acc13
+	or	$s2,$s2,$acc14
+	or	$s3,$s3,$acc15
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	blr
+
+.align	4
+Lppc_AES_decrypt_compact:
+	lwz	$acc00,240($key)
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	addi	$Tbl1,$Tbl0,2048
+	lis	$mask80,0x8080
+	lis	$mask1b,0x1b1b
+	addi	$key,$key,16
+	ori	$mask80,$mask80,0x8080
+	ori	$mask1b,$mask1b,0x1b1b
+___
+$code.=<<___ if ($SIZE_T==8);
+	insrdi	$mask80,$mask80,32,0
+	insrdi	$mask1b,$mask1b,32,0
+___
+$code.=<<___;
+	mtctr	$acc00
+.align	4
+Ldec_compact_loop:
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	rlwinm	$acc00,$s0,`32-24`,24,31
+	rlwinm	$acc01,$s1,`32-24`,24,31
+	rlwinm	$acc02,$s2,`32-24`,24,31
+	rlwinm	$acc03,$s3,`32-24`,24,31
+	rlwinm	$acc04,$s3,`32-16`,24,31
+	rlwinm	$acc05,$s0,`32-16`,24,31
+	rlwinm	$acc06,$s1,`32-16`,24,31
+	rlwinm	$acc07,$s2,`32-16`,24,31
+	lbzx	$acc00,$Tbl1,$acc00
+	lbzx	$acc01,$Tbl1,$acc01
+	rlwinm	$acc08,$s2,`32-8`,24,31
+	rlwinm	$acc09,$s3,`32-8`,24,31
+	lbzx	$acc02,$Tbl1,$acc02
+	lbzx	$acc03,$Tbl1,$acc03
+	rlwinm	$acc10,$s0,`32-8`,24,31
+	rlwinm	$acc11,$s1,`32-8`,24,31
+	lbzx	$acc04,$Tbl1,$acc04
+	lbzx	$acc05,$Tbl1,$acc05
+	rlwinm	$acc12,$s1,`0`,24,31
+	rlwinm	$acc13,$s2,`0`,24,31
+	lbzx	$acc06,$Tbl1,$acc06
+	lbzx	$acc07,$Tbl1,$acc07
+	rlwinm	$acc14,$s3,`0`,24,31
+	rlwinm	$acc15,$s0,`0`,24,31
+	lbzx	$acc08,$Tbl1,$acc08
+	lbzx	$acc09,$Tbl1,$acc09
+	rlwinm	$s0,$acc00,24,0,7
+	rlwinm	$s1,$acc01,24,0,7
+	lbzx	$acc10,$Tbl1,$acc10
+	lbzx	$acc11,$Tbl1,$acc11
+	rlwinm	$s2,$acc02,24,0,7
+	rlwinm	$s3,$acc03,24,0,7
+	lbzx	$acc12,$Tbl1,$acc12
+	lbzx	$acc13,$Tbl1,$acc13
+	rlwimi	$s0,$acc04,16,8,15
+	rlwimi	$s1,$acc05,16,8,15
+	lbzx	$acc14,$Tbl1,$acc14
+	lbzx	$acc15,$Tbl1,$acc15
+	rlwimi	$s2,$acc06,16,8,15
+	rlwimi	$s3,$acc07,16,8,15
+	rlwimi	$s0,$acc08,8,16,23
+	rlwimi	$s1,$acc09,8,16,23
+	rlwimi	$s2,$acc10,8,16,23
+	rlwimi	$s3,$acc11,8,16,23
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	or	$s0,$s0,$acc12
+	or	$s1,$s1,$acc13
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	or	$s2,$s2,$acc14
+	or	$s3,$s3,$acc15
+
+	addi	$key,$key,16
+	bdz	Ldec_compact_done
+___
+$code.=<<___ if ($SIZE_T==8);
+	# vectorized permutation improves decrypt performance by 10%
+	insrdi	$s0,$s1,32,0
+	insrdi	$s2,$s3,32,0
+
+	and	$acc00,$s0,$mask80	# r1=r0&0x80808080
+	and	$acc02,$s2,$mask80
+	srdi	$acc04,$acc00,7		# r1>>7
+	srdi	$acc06,$acc02,7
+	andc	$acc08,$s0,$mask80	# r0&0x7f7f7f7f
+	andc	$acc10,$s2,$mask80
+	sub	$acc00,$acc00,$acc04	# r1-(r1>>7)
+	sub	$acc02,$acc02,$acc06
+	add	$acc08,$acc08,$acc08	# (r0&0x7f7f7f7f)<<1
+	add	$acc10,$acc10,$acc10
+	and	$acc00,$acc00,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc02,$acc02,$mask1b
+	xor	$acc00,$acc00,$acc08	# r2
+	xor	$acc02,$acc02,$acc10
+
+	and	$acc04,$acc00,$mask80	# r1=r2&0x80808080
+	and	$acc06,$acc02,$mask80
+	srdi	$acc08,$acc04,7		# r1>>7
+	srdi	$acc10,$acc06,7
+	andc	$acc12,$acc00,$mask80	# r2&0x7f7f7f7f
+	andc	$acc14,$acc02,$mask80
+	sub	$acc04,$acc04,$acc08	# r1-(r1>>7)
+	sub	$acc06,$acc06,$acc10
+	add	$acc12,$acc12,$acc12	# (r2&0x7f7f7f7f)<<1
+	add	$acc14,$acc14,$acc14
+	and	$acc04,$acc04,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc06,$acc06,$mask1b
+	xor	$acc04,$acc04,$acc12	# r4
+	xor	$acc06,$acc06,$acc14
+
+	and	$acc08,$acc04,$mask80	# r1=r4&0x80808080
+	and	$acc10,$acc06,$mask80
+	srdi	$acc12,$acc08,7		# r1>>7
+	srdi	$acc14,$acc10,7
+	sub	$acc08,$acc08,$acc12	# r1-(r1>>7)
+	sub	$acc10,$acc10,$acc14
+	andc	$acc12,$acc04,$mask80	# r4&0x7f7f7f7f
+	andc	$acc14,$acc06,$mask80
+	add	$acc12,$acc12,$acc12	# (r4&0x7f7f7f7f)<<1
+	add	$acc14,$acc14,$acc14
+	and	$acc08,$acc08,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc10,$acc10,$mask1b
+	xor	$acc08,$acc08,$acc12	# r8
+	xor	$acc10,$acc10,$acc14
+
+	xor	$acc00,$acc00,$s0	# r2^r0
+	xor	$acc02,$acc02,$s2
+	xor	$acc04,$acc04,$s0	# r4^r0
+	xor	$acc06,$acc06,$s2
+
+	extrdi	$acc01,$acc00,32,0
+	extrdi	$acc03,$acc02,32,0
+	extrdi	$acc05,$acc04,32,0
+	extrdi	$acc07,$acc06,32,0
+	extrdi	$acc09,$acc08,32,0
+	extrdi	$acc11,$acc10,32,0
+___
+$code.=<<___ if ($SIZE_T==4);
+	and	$acc00,$s0,$mask80	# r1=r0&0x80808080
+	and	$acc01,$s1,$mask80
+	and	$acc02,$s2,$mask80
+	and	$acc03,$s3,$mask80
+	srwi	$acc04,$acc00,7		# r1>>7
+	srwi	$acc05,$acc01,7
+	srwi	$acc06,$acc02,7
+	srwi	$acc07,$acc03,7
+	andc	$acc08,$s0,$mask80	# r0&0x7f7f7f7f
+	andc	$acc09,$s1,$mask80
+	andc	$acc10,$s2,$mask80
+	andc	$acc11,$s3,$mask80
+	sub	$acc00,$acc00,$acc04	# r1-(r1>>7)
+	sub	$acc01,$acc01,$acc05
+	sub	$acc02,$acc02,$acc06
+	sub	$acc03,$acc03,$acc07
+	add	$acc08,$acc08,$acc08	# (r0&0x7f7f7f7f)<<1
+	add	$acc09,$acc09,$acc09
+	add	$acc10,$acc10,$acc10
+	add	$acc11,$acc11,$acc11
+	and	$acc00,$acc00,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc01,$acc01,$mask1b
+	and	$acc02,$acc02,$mask1b
+	and	$acc03,$acc03,$mask1b
+	xor	$acc00,$acc00,$acc08	# r2
+	xor	$acc01,$acc01,$acc09
+	xor	$acc02,$acc02,$acc10
+	xor	$acc03,$acc03,$acc11
+
+	and	$acc04,$acc00,$mask80	# r1=r2&0x80808080
+	and	$acc05,$acc01,$mask80
+	and	$acc06,$acc02,$mask80
+	and	$acc07,$acc03,$mask80
+	srwi	$acc08,$acc04,7		# r1>>7
+	srwi	$acc09,$acc05,7
+	srwi	$acc10,$acc06,7
+	srwi	$acc11,$acc07,7
+	andc	$acc12,$acc00,$mask80	# r2&0x7f7f7f7f
+	andc	$acc13,$acc01,$mask80
+	andc	$acc14,$acc02,$mask80
+	andc	$acc15,$acc03,$mask80
+	sub	$acc04,$acc04,$acc08	# r1-(r1>>7)
+	sub	$acc05,$acc05,$acc09
+	sub	$acc06,$acc06,$acc10
+	sub	$acc07,$acc07,$acc11
+	add	$acc12,$acc12,$acc12	# (r2&0x7f7f7f7f)<<1
+	add	$acc13,$acc13,$acc13
+	add	$acc14,$acc14,$acc14
+	add	$acc15,$acc15,$acc15
+	and	$acc04,$acc04,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc05,$acc05,$mask1b
+	and	$acc06,$acc06,$mask1b
+	and	$acc07,$acc07,$mask1b
+	xor	$acc04,$acc04,$acc12	# r4
+	xor	$acc05,$acc05,$acc13
+	xor	$acc06,$acc06,$acc14
+	xor	$acc07,$acc07,$acc15
+
+	and	$acc08,$acc04,$mask80	# r1=r4&0x80808080
+	and	$acc09,$acc05,$mask80
+	and	$acc10,$acc06,$mask80
+	and	$acc11,$acc07,$mask80
+	srwi	$acc12,$acc08,7		# r1>>7
+	srwi	$acc13,$acc09,7
+	srwi	$acc14,$acc10,7
+	srwi	$acc15,$acc11,7
+	sub	$acc08,$acc08,$acc12	# r1-(r1>>7)
+	sub	$acc09,$acc09,$acc13
+	sub	$acc10,$acc10,$acc14
+	sub	$acc11,$acc11,$acc15
+	andc	$acc12,$acc04,$mask80	# r4&0x7f7f7f7f
+	andc	$acc13,$acc05,$mask80
+	andc	$acc14,$acc06,$mask80
+	andc	$acc15,$acc07,$mask80
+	add	$acc12,$acc12,$acc12	# (r4&0x7f7f7f7f)<<1
+	add	$acc13,$acc13,$acc13
+	add	$acc14,$acc14,$acc14
+	add	$acc15,$acc15,$acc15
+	and	$acc08,$acc08,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc09,$acc09,$mask1b
+	and	$acc10,$acc10,$mask1b
+	and	$acc11,$acc11,$mask1b
+	xor	$acc08,$acc08,$acc12	# r8
+	xor	$acc09,$acc09,$acc13
+	xor	$acc10,$acc10,$acc14
+	xor	$acc11,$acc11,$acc15
+
+	xor	$acc00,$acc00,$s0	# r2^r0
+	xor	$acc01,$acc01,$s1
+	xor	$acc02,$acc02,$s2
+	xor	$acc03,$acc03,$s3
+	xor	$acc04,$acc04,$s0	# r4^r0
+	xor	$acc05,$acc05,$s1
+	xor	$acc06,$acc06,$s2
+	xor	$acc07,$acc07,$s3
+___
+$code.=<<___;
+	rotrwi	$s0,$s0,8		# = ROTATE(r0,8)
+	rotrwi	$s1,$s1,8
+	rotrwi	$s2,$s2,8
+	rotrwi	$s3,$s3,8
+	xor	$s0,$s0,$acc00		# ^= r2^r0
+	xor	$s1,$s1,$acc01
+	xor	$s2,$s2,$acc02
+	xor	$s3,$s3,$acc03
+	xor	$acc00,$acc00,$acc08
+	xor	$acc01,$acc01,$acc09
+	xor	$acc02,$acc02,$acc10
+	xor	$acc03,$acc03,$acc11
+	xor	$s0,$s0,$acc04		# ^= r4^r0
+	xor	$s1,$s1,$acc05
+	xor	$s2,$s2,$acc06
+	xor	$s3,$s3,$acc07
+	rotrwi	$acc00,$acc00,24
+	rotrwi	$acc01,$acc01,24
+	rotrwi	$acc02,$acc02,24
+	rotrwi	$acc03,$acc03,24
+	xor	$acc04,$acc04,$acc08
+	xor	$acc05,$acc05,$acc09
+	xor	$acc06,$acc06,$acc10
+	xor	$acc07,$acc07,$acc11
+	xor	$s0,$s0,$acc08		# ^= r8 [^((r4^r0)^(r2^r0)=r4^r2)]
+	xor	$s1,$s1,$acc09
+	xor	$s2,$s2,$acc10
+	xor	$s3,$s3,$acc11
+	rotrwi	$acc04,$acc04,16
+	rotrwi	$acc05,$acc05,16
+	rotrwi	$acc06,$acc06,16
+	rotrwi	$acc07,$acc07,16
+	xor	$s0,$s0,$acc00		# ^= ROTATE(r8^r2^r0,24)
+	xor	$s1,$s1,$acc01
+	xor	$s2,$s2,$acc02
+	xor	$s3,$s3,$acc03
+	rotrwi	$acc08,$acc08,8
+	rotrwi	$acc09,$acc09,8
+	rotrwi	$acc10,$acc10,8
+	rotrwi	$acc11,$acc11,8
+	xor	$s0,$s0,$acc04		# ^= ROTATE(r8^r4^r0,16)
+	xor	$s1,$s1,$acc05
+	xor	$s2,$s2,$acc06
+	xor	$s3,$s3,$acc07
+	xor	$s0,$s0,$acc08		# ^= ROTATE(r8,8)	
+	xor	$s1,$s1,$acc09	
+	xor	$s2,$s2,$acc10	
+	xor	$s3,$s3,$acc11	
+
+	b	Ldec_compact_loop
+.align	4
+Ldec_compact_done:
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	blr
+.long	0
+.asciz	"AES for PPC, CRYPTOGAMS by <appro\@openssl.org>"
+.align	7
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/aes/asm/aes-s390x.pl b/openssl/crypto/aes/asm/aes-s390x.pl
new file mode 100644
index 0000000..7e01889
--- /dev/null
+++ b/openssl/crypto/aes/asm/aes-s390x.pl
@@ -0,0 +1,1339 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# AES for s390x.
+
+# April 2007.
+#
+# Software performance improvement over gcc-generated code is ~70% and
+# in absolute terms is ~73 cycles per byte processed with 128-bit key.
+# You're likely to exclaim "why so slow?" Keep in mind that z-CPUs are
+# *strictly* in-order execution and issued instruction [in this case
+# load value from memory is critical] has to complete before execution
+# flow proceeds. S-boxes are compressed to 2KB[+256B].
+#
+# As for hardware acceleration support. It's basically a "teaser," as
+# it can and should be improved in several ways. Most notably support
+# for CBC is not utilized, nor multiple blocks are ever processed.
+# Then software key schedule can be postponed till hardware support
+# detection... Performance improvement over assembler is reportedly
+# ~2.5x, but can reach >8x [naturally on larger chunks] if proper
+# support is implemented.
+
+# May 2007.
+#
+# Implement AES_set_[en|de]crypt_key. Key schedule setup is avoided
+# for 128-bit keys, if hardware support is detected.
+
+# Januray 2009.
+#
+# Add support for hardware AES192/256 and reschedule instructions to
+# minimize/avoid Address Generation Interlock hazard and to favour
+# dual-issue z10 pipeline. This gave ~25% improvement on z10 and
+# almost 50% on z9. The gain is smaller on z10, because being dual-
+# issue z10 makes it improssible to eliminate the interlock condition:
+# critial path is not long enough. Yet it spends ~24 cycles per byte
+# processed with 128-bit key.
+#
+# Unlike previous version hardware support detection takes place only
+# at the moment of key schedule setup, which is denoted in key->rounds.
+# This is done, because deferred key setup can't be made MT-safe, not
+# for key lengthes longer than 128 bits.
+#
+# Add AES_cbc_encrypt, which gives incredible performance improvement,
+# it was measured to be ~6.6x. It's less than previously mentioned 8x,
+# because software implementation was optimized.
+
+$softonly=0;	# allow hardware support
+
+$t0="%r0";	$mask="%r0";
+$t1="%r1";
+$t2="%r2";	$inp="%r2";
+$t3="%r3";	$out="%r3";	$bits="%r3";
+$key="%r4";
+$i1="%r5";
+$i2="%r6";
+$i3="%r7";
+$s0="%r8";
+$s1="%r9";
+$s2="%r10";
+$s3="%r11";
+$tbl="%r12";
+$rounds="%r13";
+$ra="%r14";
+$sp="%r15";
+
+sub _data_word()
+{ my $i;
+    while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; }
+}
+
+$code=<<___;
+.text
+
+.type	AES_Te,\@object
+.align	256
+AES_Te:
+___
+&_data_word(
+	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
+	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
+	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
+	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
+	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
+	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
+	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
+	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
+	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
+	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
+	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
+	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
+	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
+	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
+	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
+	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
+	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
+	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
+	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
+	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
+	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
+	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
+	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
+	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
+	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
+	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
+	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
+	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
+	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
+	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
+	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
+	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
+	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
+	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
+	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
+	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
+	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
+	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
+	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
+	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
+	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
+	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
+	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
+	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
+	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
+	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
+	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
+	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
+	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
+	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
+	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
+	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
+	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
+	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
+	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
+	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
+	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
+	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
+	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
+	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
+	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
+	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
+	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
+	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
+$code.=<<___;
+# Te4[256]
+.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
+.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
+.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
+.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
+.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
+.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
+.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
+.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
+.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
+.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
+.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
+.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
+.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
+.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
+.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
+.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+# rcon[]
+.long	0x01000000, 0x02000000, 0x04000000, 0x08000000
+.long	0x10000000, 0x20000000, 0x40000000, 0x80000000
+.long	0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
+.align	256
+.size	AES_Te,.-AES_Te
+
+# void AES_encrypt(const unsigned char *inp, unsigned char *out,
+# 		 const AES_KEY *key) {
+.globl	AES_encrypt
+.type	AES_encrypt,\@function
+AES_encrypt:
+___
+$code.=<<___ if (!$softonly);
+	l	%r0,240($key)
+	lhi	%r1,16
+	clr	%r0,%r1
+	jl	.Lesoft
+
+	la	%r1,0($key)
+	#la	%r2,0($inp)
+	la	%r4,0($out)
+	lghi	%r3,16		# single block length
+	.long	0xb92e0042	# km %r4,%r2
+	brc	1,.-4		# can this happen?
+	br	%r14
+.align	64
+.Lesoft:
+___
+$code.=<<___;
+	stmg	%r3,$ra,24($sp)
+
+	llgf	$s0,0($inp)
+	llgf	$s1,4($inp)
+	llgf	$s2,8($inp)
+	llgf	$s3,12($inp)
+
+	larl	$tbl,AES_Te
+	bras	$ra,_s390x_AES_encrypt
+
+	lg	$out,24($sp)
+	st	$s0,0($out)
+	st	$s1,4($out)
+	st	$s2,8($out)
+	st	$s3,12($out)
+
+	lmg	%r6,$ra,48($sp)
+	br	$ra
+.size	AES_encrypt,.-AES_encrypt
+
+.type   _s390x_AES_encrypt,\@function
+.align	16
+_s390x_AES_encrypt:
+	stg	$ra,152($sp)
+	x	$s0,0($key)
+	x	$s1,4($key)
+	x	$s2,8($key)
+	x	$s3,12($key)
+	l	$rounds,240($key)
+	llill	$mask,`0xff<<3`
+	aghi	$rounds,-1
+	j	.Lenc_loop
+.align	16
+.Lenc_loop:
+	sllg	$t1,$s0,`0+3`
+	srlg	$t2,$s0,`8-3`
+	srlg	$t3,$s0,`16-3`
+	srl	$s0,`24-3`
+	nr	$s0,$mask
+	ngr	$t1,$mask
+	nr	$t2,$mask
+	nr	$t3,$mask
+
+	srlg	$i1,$s1,`16-3`	# i0
+	sllg	$i2,$s1,`0+3`
+	srlg	$i3,$s1,`8-3`
+	srl	$s1,`24-3`
+	nr	$i1,$mask
+	nr	$s1,$mask
+	ngr	$i2,$mask
+	nr	$i3,$mask
+
+	l	$s0,0($s0,$tbl)	# Te0[s0>>24]
+	l	$t1,1($t1,$tbl)	# Te3[s0>>0]
+	l	$t2,2($t2,$tbl) # Te2[s0>>8]
+	l	$t3,3($t3,$tbl)	# Te1[s0>>16]
+
+	x	$s0,3($i1,$tbl)	# Te1[s1>>16]
+	l	$s1,0($s1,$tbl)	# Te0[s1>>24]
+	x	$t2,1($i2,$tbl)	# Te3[s1>>0]
+	x	$t3,2($i3,$tbl)	# Te2[s1>>8]
+
+	srlg	$i1,$s2,`8-3`	# i0
+	srlg	$i2,$s2,`16-3`	# i1
+	nr	$i1,$mask
+	nr	$i2,$mask
+	sllg	$i3,$s2,`0+3`
+	srl	$s2,`24-3`
+	nr	$s2,$mask
+	ngr	$i3,$mask
+
+	xr	$s1,$t1
+	srlg	$ra,$s3,`8-3`	# i1
+	sllg	$t1,$s3,`0+3`	# i0
+	nr	$ra,$mask
+	la	$key,16($key)
+	ngr	$t1,$mask
+
+	x	$s0,2($i1,$tbl)	# Te2[s2>>8]
+	x	$s1,3($i2,$tbl)	# Te1[s2>>16]
+	l	$s2,0($s2,$tbl)	# Te0[s2>>24]
+	x	$t3,1($i3,$tbl)	# Te3[s2>>0]
+
+	srlg	$i3,$s3,`16-3`	# i2
+	xr	$s2,$t2
+	srl	$s3,`24-3`
+	nr	$i3,$mask
+	nr	$s3,$mask
+
+	x	$s0,0($key)
+	x	$s1,4($key)
+	x	$s2,8($key)
+	x	$t3,12($key)
+
+	x	$s0,1($t1,$tbl)	# Te3[s3>>0]
+	x	$s1,2($ra,$tbl)	# Te2[s3>>8]
+	x	$s2,3($i3,$tbl)	# Te1[s3>>16]
+	l	$s3,0($s3,$tbl)	# Te0[s3>>24]
+	xr	$s3,$t3
+
+	brct	$rounds,.Lenc_loop
+	.align	16
+
+	sllg	$t1,$s0,`0+3`
+	srlg	$t2,$s0,`8-3`
+	ngr	$t1,$mask
+	srlg	$t3,$s0,`16-3`
+	srl	$s0,`24-3`
+	nr	$s0,$mask
+	nr	$t2,$mask
+	nr	$t3,$mask
+
+	srlg	$i1,$s1,`16-3`	# i0
+	sllg	$i2,$s1,`0+3`
+	ngr	$i2,$mask
+	srlg	$i3,$s1,`8-3`
+	srl	$s1,`24-3`
+	nr	$i1,$mask
+	nr	$s1,$mask
+	nr	$i3,$mask
+
+	llgc	$s0,2($s0,$tbl)	# Te4[s0>>24]
+	llgc	$t1,2($t1,$tbl)	# Te4[s0>>0]
+	sll	$s0,24
+	llgc	$t2,2($t2,$tbl)	# Te4[s0>>8]
+	llgc	$t3,2($t3,$tbl)	# Te4[s0>>16]
+	sll	$t2,8
+	sll	$t3,16
+
+	llgc	$i1,2($i1,$tbl)	# Te4[s1>>16]
+	llgc	$s1,2($s1,$tbl)	# Te4[s1>>24]
+	llgc	$i2,2($i2,$tbl)	# Te4[s1>>0]
+	llgc	$i3,2($i3,$tbl)	# Te4[s1>>8]
+	sll	$i1,16
+	sll	$s1,24
+	sll	$i3,8
+	or	$s0,$i1
+	or	$s1,$t1
+	or	$t2,$i2
+	or	$t3,$i3
+	
+	srlg	$i1,$s2,`8-3`	# i0
+	srlg	$i2,$s2,`16-3`	# i1
+	nr	$i1,$mask
+	nr	$i2,$mask
+	sllg	$i3,$s2,`0+3`
+	srl	$s2,`24-3`
+	ngr	$i3,$mask
+	nr	$s2,$mask
+
+	sllg	$t1,$s3,`0+3`	# i0
+	srlg	$ra,$s3,`8-3`	# i1
+	ngr	$t1,$mask
+
+	llgc	$i1,2($i1,$tbl)	# Te4[s2>>8]
+	llgc	$i2,2($i2,$tbl)	# Te4[s2>>16]
+	sll	$i1,8
+	llgc	$s2,2($s2,$tbl)	# Te4[s2>>24]
+	llgc	$i3,2($i3,$tbl)	# Te4[s2>>0]
+	sll	$i2,16
+	nr	$ra,$mask
+	sll	$s2,24
+	or	$s0,$i1
+	or	$s1,$i2
+	or	$s2,$t2
+	or	$t3,$i3
+
+	srlg	$i3,$s3,`16-3`	# i2
+	srl	$s3,`24-3`
+	nr	$i3,$mask
+	nr	$s3,$mask
+
+	l	$t0,16($key)
+	l	$t2,20($key)
+
+	llgc	$i1,2($t1,$tbl)	# Te4[s3>>0]
+	llgc	$i2,2($ra,$tbl)	# Te4[s3>>8]
+	llgc	$i3,2($i3,$tbl)	# Te4[s3>>16]
+	llgc	$s3,2($s3,$tbl)	# Te4[s3>>24]
+	sll	$i2,8
+	sll	$i3,16
+	sll	$s3,24
+	or	$s0,$i1
+	or	$s1,$i2
+	or	$s2,$i3
+	or	$s3,$t3
+
+	lg	$ra,152($sp)
+	xr	$s0,$t0
+	xr	$s1,$t2
+	x	$s2,24($key)
+	x	$s3,28($key)
+
+	br	$ra	
+.size	_s390x_AES_encrypt,.-_s390x_AES_encrypt
+___
+
+$code.=<<___;
+.type	AES_Td,\@object
+.align	256
+AES_Td:
+___
+&_data_word(
+	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
+	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
+	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
+	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
+	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
+	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
+	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
+	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
+	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
+	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
+	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
+	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
+	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
+	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
+	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
+	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
+	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
+	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
+	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
+	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
+	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
+	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
+	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
+	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
+	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
+	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
+	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
+	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
+	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
+	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
+	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
+	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
+	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
+	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
+	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
+	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
+	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
+	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
+	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
+	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
+	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
+	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
+	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
+	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
+	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
+	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
+	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
+	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
+	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
+	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
+	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
+	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
+	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
+	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
+	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
+	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
+	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
+	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
+	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
+	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
+	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
+	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
+	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
+	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
+$code.=<<___;
+# Td4[256]
+.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
+.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
+.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
+.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
+.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
+.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
+.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
+.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
+.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
+.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
+.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
+.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
+.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
+.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
+.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
+.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
+.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+.size	AES_Td,.-AES_Td
+
+# void AES_decrypt(const unsigned char *inp, unsigned char *out,
+# 		 const AES_KEY *key) {
+.globl	AES_decrypt
+.type	AES_decrypt,\@function
+AES_decrypt:
+___
+$code.=<<___ if (!$softonly);
+	l	%r0,240($key)
+	lhi	%r1,16
+	clr	%r0,%r1
+	jl	.Ldsoft
+
+	la	%r1,0($key)
+	#la	%r2,0($inp)
+	la	%r4,0($out)
+	lghi	%r3,16		# single block length
+	.long	0xb92e0042	# km %r4,%r2
+	brc	1,.-4		# can this happen?
+	br	%r14
+.align	64
+.Ldsoft:
+___
+$code.=<<___;
+	stmg	%r3,$ra,24($sp)
+
+	llgf	$s0,0($inp)
+	llgf	$s1,4($inp)
+	llgf	$s2,8($inp)
+	llgf	$s3,12($inp)
+
+	larl	$tbl,AES_Td
+	bras	$ra,_s390x_AES_decrypt
+
+	lg	$out,24($sp)
+	st	$s0,0($out)
+	st	$s1,4($out)
+	st	$s2,8($out)
+	st	$s3,12($out)
+
+	lmg	%r6,$ra,48($sp)
+	br	$ra
+.size	AES_decrypt,.-AES_decrypt
+
+.type   _s390x_AES_decrypt,\@function
+.align	16
+_s390x_AES_decrypt:
+	stg	$ra,152($sp)
+	x	$s0,0($key)
+	x	$s1,4($key)
+	x	$s2,8($key)
+	x	$s3,12($key)
+	l	$rounds,240($key)
+	llill	$mask,`0xff<<3`
+	aghi	$rounds,-1
+	j	.Ldec_loop
+.align	16
+.Ldec_loop:
+	srlg	$t1,$s0,`16-3`
+	srlg	$t2,$s0,`8-3`
+	sllg	$t3,$s0,`0+3`
+	srl	$s0,`24-3`
+	nr	$s0,$mask
+	nr	$t1,$mask
+	nr	$t2,$mask
+	ngr	$t3,$mask
+
+	sllg	$i1,$s1,`0+3`	# i0
+	srlg	$i2,$s1,`16-3`
+	srlg	$i3,$s1,`8-3`
+	srl	$s1,`24-3`
+	ngr	$i1,$mask
+	nr	$s1,$mask
+	nr	$i2,$mask
+	nr	$i3,$mask
+
+	l	$s0,0($s0,$tbl)	# Td0[s0>>24]
+	l	$t1,3($t1,$tbl)	# Td1[s0>>16]
+	l	$t2,2($t2,$tbl)	# Td2[s0>>8]
+	l	$t3,1($t3,$tbl)	# Td3[s0>>0]
+
+	x	$s0,1($i1,$tbl)	# Td3[s1>>0]
+	l	$s1,0($s1,$tbl)	# Td0[s1>>24]
+	x	$t2,3($i2,$tbl)	# Td1[s1>>16]
+	x	$t3,2($i3,$tbl)	# Td2[s1>>8]
+
+	srlg	$i1,$s2,`8-3`	# i0
+	sllg	$i2,$s2,`0+3`	# i1
+	srlg	$i3,$s2,`16-3`
+	srl	$s2,`24-3`
+	nr	$i1,$mask
+	ngr	$i2,$mask
+	nr	$s2,$mask
+	nr	$i3,$mask
+
+	xr	$s1,$t1
+	srlg	$ra,$s3,`8-3`	# i1
+	srlg	$t1,$s3,`16-3`	# i0
+	nr	$ra,$mask
+	la	$key,16($key)
+	nr	$t1,$mask
+
+	x	$s0,2($i1,$tbl)	# Td2[s2>>8]
+	x	$s1,1($i2,$tbl)	# Td3[s2>>0]
+	l	$s2,0($s2,$tbl)	# Td0[s2>>24]
+	x	$t3,3($i3,$tbl)	# Td1[s2>>16]
+
+	sllg	$i3,$s3,`0+3`	# i2
+	srl	$s3,`24-3`
+	ngr	$i3,$mask
+	nr	$s3,$mask
+
+	xr	$s2,$t2
+	x	$s0,0($key)
+	x	$s1,4($key)
+	x	$s2,8($key)
+	x	$t3,12($key)
+
+	x	$s0,3($t1,$tbl)	# Td1[s3>>16]
+	x	$s1,2($ra,$tbl)	# Td2[s3>>8]
+	x	$s2,1($i3,$tbl)	# Td3[s3>>0]
+	l	$s3,0($s3,$tbl)	# Td0[s3>>24]
+	xr	$s3,$t3
+
+	brct	$rounds,.Ldec_loop
+	.align	16
+
+	l	$t1,`2048+0`($tbl)	# prefetch Td4
+	l	$t2,`2048+64`($tbl)
+	l	$t3,`2048+128`($tbl)
+	l	$i1,`2048+192`($tbl)
+	llill	$mask,0xff
+
+	srlg	$i3,$s0,24	# i0
+	srlg	$t1,$s0,16
+	srlg	$t2,$s0,8
+	nr	$s0,$mask	# i3
+	nr	$t1,$mask
+
+	srlg	$i1,$s1,24
+	nr	$t2,$mask
+	srlg	$i2,$s1,16
+	srlg	$ra,$s1,8
+	nr	$s1,$mask	# i0
+	nr	$i2,$mask
+	nr	$ra,$mask
+
+	llgc	$i3,2048($i3,$tbl)	# Td4[s0>>24]
+	llgc	$t1,2048($t1,$tbl)	# Td4[s0>>16]
+	llgc	$t2,2048($t2,$tbl)	# Td4[s0>>8]
+	sll	$t1,16
+	llgc	$t3,2048($s0,$tbl)	# Td4[s0>>0]
+	sllg	$s0,$i3,24
+	sll	$t2,8
+
+	llgc	$s1,2048($s1,$tbl)	# Td4[s1>>0]
+	llgc	$i1,2048($i1,$tbl)	# Td4[s1>>24]
+	llgc	$i2,2048($i2,$tbl)	# Td4[s1>>16]
+	sll	$i1,24
+	llgc	$i3,2048($ra,$tbl)	# Td4[s1>>8]
+	sll	$i2,16
+	sll	$i3,8
+	or	$s0,$s1
+	or	$t1,$i1
+	or	$t2,$i2
+	or	$t3,$i3
+
+	srlg	$i1,$s2,8	# i0
+	srlg	$i2,$s2,24
+	srlg	$i3,$s2,16
+	nr	$s2,$mask	# i1
+	nr	$i1,$mask
+	nr	$i3,$mask
+	llgc	$i1,2048($i1,$tbl)	# Td4[s2>>8]
+	llgc	$s1,2048($s2,$tbl)	# Td4[s2>>0]
+	llgc	$i2,2048($i2,$tbl)	# Td4[s2>>24]
+	llgc	$i3,2048($i3,$tbl)	# Td4[s2>>16]
+	sll	$i1,8
+	sll	$i2,24
+	or	$s0,$i1
+	sll	$i3,16
+	or	$t2,$i2
+	or	$t3,$i3
+
+	srlg	$i1,$s3,16	# i0
+	srlg	$i2,$s3,8	# i1
+	srlg	$i3,$s3,24
+	nr	$s3,$mask	# i2
+	nr	$i1,$mask
+	nr	$i2,$mask
+
+	lg	$ra,152($sp)
+	or	$s1,$t1
+	l	$t0,16($key)
+	l	$t1,20($key)
+
+	llgc	$i1,2048($i1,$tbl)	# Td4[s3>>16]
+	llgc	$i2,2048($i2,$tbl)	# Td4[s3>>8]
+	sll	$i1,16
+	llgc	$s2,2048($s3,$tbl)	# Td4[s3>>0]
+	llgc	$s3,2048($i3,$tbl)	# Td4[s3>>24]
+	sll	$i2,8
+	sll	$s3,24
+	or	$s0,$i1
+	or	$s1,$i2
+	or	$s2,$t2
+	or	$s3,$t3
+
+	xr	$s0,$t0
+	xr	$s1,$t1
+	x	$s2,24($key)
+	x	$s3,28($key)
+
+	br	$ra	
+.size	_s390x_AES_decrypt,.-_s390x_AES_decrypt
+___
+
+$code.=<<___;
+# void AES_set_encrypt_key(const unsigned char *in, int bits,
+# 		 AES_KEY *key) {
+.globl	AES_set_encrypt_key
+.type	AES_set_encrypt_key,\@function
+.align	16
+AES_set_encrypt_key:
+	lghi	$t0,0
+	clgr	$inp,$t0
+	je	.Lminus1
+	clgr	$key,$t0
+	je	.Lminus1
+
+	lghi	$t0,128
+	clr	$bits,$t0
+	je	.Lproceed
+	lghi	$t0,192
+	clr	$bits,$t0
+	je	.Lproceed
+	lghi	$t0,256
+	clr	$bits,$t0
+	je	.Lproceed
+	lghi	%r2,-2
+	br	%r14
+
+.align	16
+.Lproceed:
+___
+$code.=<<___ if (!$softonly);
+	# convert bits to km code, [128,192,256]->[18,19,20]
+	lhi	%r5,-128
+	lhi	%r0,18
+	ar	%r5,$bits
+	srl	%r5,6
+	ar	%r5,%r0
+
+	larl	%r1,OPENSSL_s390xcap_P
+	lg	%r0,0(%r1)
+	tmhl	%r0,0x4000	# check for message-security assist
+	jz	.Lekey_internal
+
+	lghi	%r0,0		# query capability vector
+	la	%r1,16($sp)
+	.long	0xb92f0042	# kmc %r4,%r2
+
+	llihh	%r1,0x8000
+	srlg	%r1,%r1,0(%r5)
+	ng	%r1,16($sp)
+	jz	.Lekey_internal
+
+	lmg	%r0,%r1,0($inp)	# just copy 128 bits...
+	stmg	%r0,%r1,0($key)
+	lhi	%r0,192
+	cr	$bits,%r0
+	jl	1f
+	lg	%r1,16($inp)
+	stg	%r1,16($key)
+	je	1f
+	lg	%r1,24($inp)
+	stg	%r1,24($key)
+1:	st	$bits,236($key)	# save bits
+	st	%r5,240($key)	# save km code
+	lghi	%r2,0
+	br	%r14
+___
+$code.=<<___;
+.align	16
+.Lekey_internal:
+	stmg	%r6,%r13,48($sp)	# all non-volatile regs
+
+	larl	$tbl,AES_Te+2048
+
+	llgf	$s0,0($inp)
+	llgf	$s1,4($inp)
+	llgf	$s2,8($inp)
+	llgf	$s3,12($inp)
+	st	$s0,0($key)
+	st	$s1,4($key)
+	st	$s2,8($key)
+	st	$s3,12($key)
+	lghi	$t0,128
+	cr	$bits,$t0
+	jne	.Lnot128
+
+	llill	$mask,0xff
+	lghi	$t3,0			# i=0
+	lghi	$rounds,10
+	st	$rounds,240($key)
+
+	llgfr	$t2,$s3			# temp=rk[3]
+	srlg	$i1,$s3,8
+	srlg	$i2,$s3,16
+	srlg	$i3,$s3,24
+	nr	$t2,$mask
+	nr	$i1,$mask
+	nr	$i2,$mask
+
+.align	16
+.L128_loop:
+	la	$t2,0($t2,$tbl)
+	la	$i1,0($i1,$tbl)
+	la	$i2,0($i2,$tbl)
+	la	$i3,0($i3,$tbl)
+	icm	$t2,2,0($t2)		# Te4[rk[3]>>0]<<8
+	icm	$t2,4,0($i1)		# Te4[rk[3]>>8]<<16
+	icm	$t2,8,0($i2)		# Te4[rk[3]>>16]<<24
+	icm	$t2,1,0($i3)		# Te4[rk[3]>>24]
+	x	$t2,256($t3,$tbl)	# rcon[i]
+	xr	$s0,$t2			# rk[4]=rk[0]^...
+	xr	$s1,$s0			# rk[5]=rk[1]^rk[4]
+	xr	$s2,$s1			# rk[6]=rk[2]^rk[5]
+	xr	$s3,$s2			# rk[7]=rk[3]^rk[6]
+
+	llgfr	$t2,$s3			# temp=rk[3]
+	srlg	$i1,$s3,8
+	srlg	$i2,$s3,16
+	nr	$t2,$mask
+	nr	$i1,$mask
+	srlg	$i3,$s3,24
+	nr	$i2,$mask
+
+	st	$s0,16($key)
+	st	$s1,20($key)
+	st	$s2,24($key)
+	st	$s3,28($key)
+	la	$key,16($key)		# key+=4
+	la	$t3,4($t3)		# i++
+	brct	$rounds,.L128_loop
+	lghi	%r2,0
+	lmg	%r6,%r13,48($sp)
+	br	$ra
+
+.align	16
+.Lnot128:
+	llgf	$t0,16($inp)
+	llgf	$t1,20($inp)
+	st	$t0,16($key)
+	st	$t1,20($key)
+	lghi	$t0,192
+	cr	$bits,$t0
+	jne	.Lnot192
+
+	llill	$mask,0xff
+	lghi	$t3,0			# i=0
+	lghi	$rounds,12
+	st	$rounds,240($key)
+	lghi	$rounds,8
+
+	srlg	$i1,$t1,8
+	srlg	$i2,$t1,16
+	srlg	$i3,$t1,24
+	nr	$t1,$mask
+	nr	$i1,$mask
+	nr	$i2,$mask
+
+.align	16
+.L192_loop:
+	la	$t1,0($t1,$tbl)
+	la	$i1,0($i1,$tbl)
+	la	$i2,0($i2,$tbl)
+	la	$i3,0($i3,$tbl)
+	icm	$t1,2,0($t1)		# Te4[rk[5]>>0]<<8
+	icm	$t1,4,0($i1)		# Te4[rk[5]>>8]<<16
+	icm	$t1,8,0($i2)		# Te4[rk[5]>>16]<<24
+	icm	$t1,1,0($i3)		# Te4[rk[5]>>24]
+	x	$t1,256($t3,$tbl)	# rcon[i]
+	xr	$s0,$t1			# rk[6]=rk[0]^...
+	xr	$s1,$s0			# rk[7]=rk[1]^rk[6]
+	xr	$s2,$s1			# rk[8]=rk[2]^rk[7]
+	xr	$s3,$s2			# rk[9]=rk[3]^rk[8]
+
+	st	$s0,24($key)
+	st	$s1,28($key)
+	st	$s2,32($key)
+	st	$s3,36($key)
+	brct	$rounds,.L192_continue
+	lghi	%r2,0
+	lmg	%r6,%r13,48($sp)
+	br	$ra
+
+.align	16
+.L192_continue:
+	lgr	$t1,$s3
+	x	$t1,16($key)		# rk[10]=rk[4]^rk[9]
+	st	$t1,40($key)
+	x	$t1,20($key)		# rk[11]=rk[5]^rk[10]
+	st	$t1,44($key)
+
+	srlg	$i1,$t1,8
+	srlg	$i2,$t1,16
+	srlg	$i3,$t1,24
+	nr	$t1,$mask
+	nr	$i1,$mask
+	nr	$i2,$mask
+
+	la	$key,24($key)		# key+=6
+	la	$t3,4($t3)		# i++
+	j	.L192_loop
+
+.align	16
+.Lnot192:
+	llgf	$t0,24($inp)
+	llgf	$t1,28($inp)
+	st	$t0,24($key)
+	st	$t1,28($key)
+	llill	$mask,0xff
+	lghi	$t3,0			# i=0
+	lghi	$rounds,14
+	st	$rounds,240($key)
+	lghi	$rounds,7
+
+	srlg	$i1,$t1,8
+	srlg	$i2,$t1,16
+	srlg	$i3,$t1,24
+	nr	$t1,$mask
+	nr	$i1,$mask
+	nr	$i2,$mask
+
+.align	16
+.L256_loop:
+	la	$t1,0($t1,$tbl)
+	la	$i1,0($i1,$tbl)
+	la	$i2,0($i2,$tbl)
+	la	$i3,0($i3,$tbl)
+	icm	$t1,2,0($t1)		# Te4[rk[7]>>0]<<8
+	icm	$t1,4,0($i1)		# Te4[rk[7]>>8]<<16
+	icm	$t1,8,0($i2)		# Te4[rk[7]>>16]<<24
+	icm	$t1,1,0($i3)		# Te4[rk[7]>>24]
+	x	$t1,256($t3,$tbl)	# rcon[i]
+	xr	$s0,$t1			# rk[8]=rk[0]^...
+	xr	$s1,$s0			# rk[9]=rk[1]^rk[8]
+	xr	$s2,$s1			# rk[10]=rk[2]^rk[9]
+	xr	$s3,$s2			# rk[11]=rk[3]^rk[10]
+	st	$s0,32($key)
+	st	$s1,36($key)
+	st	$s2,40($key)
+	st	$s3,44($key)
+	brct	$rounds,.L256_continue
+	lghi	%r2,0
+	lmg	%r6,%r13,48($sp)
+	br	$ra
+
+.align	16
+.L256_continue:
+	lgr	$t1,$s3			# temp=rk[11]
+	srlg	$i1,$s3,8
+	srlg	$i2,$s3,16
+	srlg	$i3,$s3,24
+	nr	$t1,$mask
+	nr	$i1,$mask
+	nr	$i2,$mask
+	la	$t1,0($t1,$tbl)
+	la	$i1,0($i1,$tbl)
+	la	$i2,0($i2,$tbl)
+	la	$i3,0($i3,$tbl)
+	llgc	$t1,0($t1)		# Te4[rk[11]>>0]
+	icm	$t1,2,0($i1)		# Te4[rk[11]>>8]<<8
+	icm	$t1,4,0($i2)		# Te4[rk[11]>>16]<<16
+	icm	$t1,8,0($i3)		# Te4[rk[11]>>24]<<24
+	x	$t1,16($key)		# rk[12]=rk[4]^...
+	st	$t1,48($key)
+	x	$t1,20($key)		# rk[13]=rk[5]^rk[12]
+	st	$t1,52($key)
+	x	$t1,24($key)		# rk[14]=rk[6]^rk[13]
+	st	$t1,56($key)
+	x	$t1,28($key)		# rk[15]=rk[7]^rk[14]
+	st	$t1,60($key)
+
+	srlg	$i1,$t1,8
+	srlg	$i2,$t1,16
+	srlg	$i3,$t1,24
+	nr	$t1,$mask
+	nr	$i1,$mask
+	nr	$i2,$mask
+
+	la	$key,32($key)		# key+=8
+	la	$t3,4($t3)		# i++
+	j	.L256_loop
+
+.Lminus1:
+	lghi	%r2,-1
+	br	$ra
+.size	AES_set_encrypt_key,.-AES_set_encrypt_key
+
+# void AES_set_decrypt_key(const unsigned char *in, int bits,
+# 		 AES_KEY *key) {
+.globl	AES_set_decrypt_key
+.type	AES_set_decrypt_key,\@function
+.align	16
+AES_set_decrypt_key:
+	stg	$key,32($sp)		# I rely on AES_set_encrypt_key to
+	stg	$ra,112($sp)		# save non-volatile registers!
+	bras	$ra,AES_set_encrypt_key
+	lg	$key,32($sp)
+	lg	$ra,112($sp)
+	ltgr	%r2,%r2
+	bnzr	$ra
+___
+$code.=<<___ if (!$softonly);
+	l	$t0,240($key)
+	lhi	$t1,16
+	cr	$t0,$t1
+	jl	.Lgo
+	oill	$t0,0x80	# set "decrypt" bit
+	st	$t0,240($key)
+	br	$ra
+
+.align	16
+.Ldkey_internal:
+	stg	$key,32($sp)
+	stg	$ra,40($sp)
+	bras	$ra,.Lekey_internal
+	lg	$key,32($sp)
+	lg	$ra,40($sp)
+___
+$code.=<<___;
+
+.Lgo:	llgf	$rounds,240($key)
+	la	$i1,0($key)
+	sllg	$i2,$rounds,4
+	la	$i2,0($i2,$key)
+	srl	$rounds,1
+	lghi	$t1,-16
+
+.align	16
+.Linv:	lmg	$s0,$s1,0($i1)
+	lmg	$s2,$s3,0($i2)
+	stmg	$s0,$s1,0($i2)
+	stmg	$s2,$s3,0($i1)
+	la	$i1,16($i1)
+	la	$i2,0($t1,$i2)
+	brct	$rounds,.Linv
+___
+$mask80=$i1;
+$mask1b=$i2;
+$maskfe=$i3;
+$code.=<<___;
+	llgf	$rounds,240($key)
+	aghi	$rounds,-1
+	sll	$rounds,2	# (rounds-1)*4
+	llilh	$mask80,0x8080
+	llilh	$mask1b,0x1b1b
+	llilh	$maskfe,0xfefe
+	oill	$mask80,0x8080
+	oill	$mask1b,0x1b1b
+	oill	$maskfe,0xfefe
+
+.align	16
+.Lmix:	l	$s0,16($key)	# tp1
+	lr	$s1,$s0
+	ngr	$s1,$mask80
+	srlg	$t1,$s1,7
+	slr	$s1,$t1
+	nr	$s1,$mask1b
+	sllg	$t1,$s0,1
+	nr	$t1,$maskfe
+	xr	$s1,$t1		# tp2
+
+	lr	$s2,$s1
+	ngr	$s2,$mask80
+	srlg	$t1,$s2,7
+	slr	$s2,$t1
+	nr	$s2,$mask1b
+	sllg	$t1,$s1,1
+	nr	$t1,$maskfe
+	xr	$s2,$t1		# tp4
+
+	lr	$s3,$s2
+	ngr	$s3,$mask80
+	srlg	$t1,$s3,7
+	slr	$s3,$t1
+	nr	$s3,$mask1b
+	sllg	$t1,$s2,1
+	nr	$t1,$maskfe
+	xr	$s3,$t1		# tp8
+
+	xr	$s1,$s0		# tp2^tp1
+	xr	$s2,$s0		# tp4^tp1
+	rll	$s0,$s0,24	# = ROTATE(tp1,8)
+	xr	$s2,$s3		# ^=tp8
+	xr	$s0,$s1		# ^=tp2^tp1
+	xr	$s1,$s3		# tp2^tp1^tp8
+	xr	$s0,$s2		# ^=tp4^tp1^tp8
+	rll	$s1,$s1,8
+	rll	$s2,$s2,16
+	xr	$s0,$s1		# ^= ROTATE(tp8^tp2^tp1,24)
+	rll	$s3,$s3,24
+	xr	$s0,$s2    	# ^= ROTATE(tp8^tp4^tp1,16)
+	xr	$s0,$s3		# ^= ROTATE(tp8,8)
+
+	st	$s0,16($key)
+	la	$key,4($key)
+	brct	$rounds,.Lmix
+
+	lmg	%r6,%r13,48($sp)# as was saved by AES_set_encrypt_key!
+	lghi	%r2,0
+	br	$ra
+.size	AES_set_decrypt_key,.-AES_set_decrypt_key
+___
+
+#void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+#                     size_t length, const AES_KEY *key,
+#                     unsigned char *ivec, const int enc)
+{
+my $inp="%r2";
+my $out="%r4";	# length and out are swapped
+my $len="%r3";
+my $key="%r5";
+my $ivp="%r6";
+
+$code.=<<___;
+.globl	AES_cbc_encrypt
+.type	AES_cbc_encrypt,\@function
+.align	16
+AES_cbc_encrypt:
+	xgr	%r3,%r4		# flip %r3 and %r4, out and len
+	xgr	%r4,%r3
+	xgr	%r3,%r4
+___
+$code.=<<___ if (!$softonly);
+	lhi	%r0,16
+	cl	%r0,240($key)
+	jh	.Lcbc_software
+
+	lg	%r0,0($ivp)	# copy ivec
+	lg	%r1,8($ivp)
+	stmg	%r0,%r1,16($sp)
+	lmg	%r0,%r1,0($key)	# copy key, cover 256 bit
+	stmg	%r0,%r1,32($sp)
+	lmg	%r0,%r1,16($key)
+	stmg	%r0,%r1,48($sp)
+	l	%r0,240($key)	# load kmc code
+	lghi	$key,15		# res=len%16, len-=res;
+	ngr	$key,$len
+	slgr	$len,$key
+	la	%r1,16($sp)	# parameter block - ivec || key
+	jz	.Lkmc_truncated
+	.long	0xb92f0042	# kmc %r4,%r2
+	brc	1,.-4		# pay attention to "partial completion"
+	ltr	$key,$key
+	jnz	.Lkmc_truncated
+.Lkmc_done:
+	lmg	%r0,%r1,16($sp)	# copy ivec to caller
+	stg	%r0,0($ivp)
+	stg	%r1,8($ivp)
+	br	$ra
+.align	16
+.Lkmc_truncated:
+	ahi	$key,-1		# it's the way it's encoded in mvc
+	tmll	%r0,0x80
+	jnz	.Lkmc_truncated_dec
+	lghi	%r1,0
+	stg	%r1,128($sp)
+	stg	%r1,136($sp)
+	bras	%r1,1f
+	mvc	128(1,$sp),0($inp)
+1:	ex	$key,0(%r1)
+	la	%r1,16($sp)	# restore parameter block
+	la	$inp,128($sp)
+	lghi	$len,16
+	.long	0xb92f0042	# kmc %r4,%r2
+	j	.Lkmc_done
+.align	16
+.Lkmc_truncated_dec:
+	stg	$out,64($sp)
+	la	$out,128($sp)
+	lghi	$len,16
+	.long	0xb92f0042	# kmc %r4,%r2
+	lg	$out,64($sp)
+	bras	%r1,2f
+	mvc	0(1,$out),128($sp)
+2:	ex	$key,0(%r1)
+	j	.Lkmc_done
+.align	16
+.Lcbc_software:
+___
+$code.=<<___;
+	stmg	$key,$ra,40($sp)
+	lhi	%r0,0
+	cl	%r0,164($sp)
+	je	.Lcbc_decrypt
+
+	larl	$tbl,AES_Te
+
+	llgf	$s0,0($ivp)
+	llgf	$s1,4($ivp)
+	llgf	$s2,8($ivp)
+	llgf	$s3,12($ivp)
+
+	lghi	$t0,16
+	slgr	$len,$t0
+	brc	4,.Lcbc_enc_tail	# if borrow
+.Lcbc_enc_loop:
+	stmg	$inp,$out,16($sp)
+	x	$s0,0($inp)
+	x	$s1,4($inp)
+	x	$s2,8($inp)
+	x	$s3,12($inp)
+	lgr	%r4,$key
+
+	bras	$ra,_s390x_AES_encrypt
+
+	lmg	$inp,$key,16($sp)
+	st	$s0,0($out)
+	st	$s1,4($out)
+	st	$s2,8($out)
+	st	$s3,12($out)
+
+	la	$inp,16($inp)
+	la	$out,16($out)
+	lghi	$t0,16
+	ltgr	$len,$len
+	jz	.Lcbc_enc_done
+	slgr	$len,$t0
+	brc	4,.Lcbc_enc_tail	# if borrow
+	j	.Lcbc_enc_loop
+.align	16
+.Lcbc_enc_done:
+	lg	$ivp,48($sp)
+	st	$s0,0($ivp)
+	st	$s1,4($ivp)	
+	st	$s2,8($ivp)
+	st	$s3,12($ivp)
+
+	lmg	%r7,$ra,56($sp)
+	br	$ra
+
+.align	16
+.Lcbc_enc_tail:
+	aghi	$len,15
+	lghi	$t0,0
+	stg	$t0,128($sp)
+	stg	$t0,136($sp)
+	bras	$t1,3f
+	mvc	128(1,$sp),0($inp)
+3:	ex	$len,0($t1)
+	lghi	$len,0
+	la	$inp,128($sp)
+	j	.Lcbc_enc_loop
+
+.align	16
+.Lcbc_decrypt:
+	larl	$tbl,AES_Td
+
+	lg	$t0,0($ivp)
+	lg	$t1,8($ivp)
+	stmg	$t0,$t1,128($sp)
+
+.Lcbc_dec_loop:
+	stmg	$inp,$out,16($sp)
+	llgf	$s0,0($inp)
+	llgf	$s1,4($inp)
+	llgf	$s2,8($inp)
+	llgf	$s3,12($inp)
+	lgr	%r4,$key
+
+	bras	$ra,_s390x_AES_decrypt
+
+	lmg	$inp,$key,16($sp)
+	sllg	$s0,$s0,32
+	sllg	$s2,$s2,32
+	lr	$s0,$s1
+	lr	$s2,$s3
+
+	lg	$t0,0($inp)
+	lg	$t1,8($inp)
+	xg	$s0,128($sp)
+	xg	$s2,136($sp)
+	lghi	$s1,16
+	slgr	$len,$s1
+	brc	4,.Lcbc_dec_tail	# if borrow
+	brc	2,.Lcbc_dec_done	# if zero
+	stg	$s0,0($out)
+	stg	$s2,8($out)
+	stmg	$t0,$t1,128($sp)
+
+	la	$inp,16($inp)
+	la	$out,16($out)
+	j	.Lcbc_dec_loop
+
+.Lcbc_dec_done:
+	stg	$s0,0($out)
+	stg	$s2,8($out)
+.Lcbc_dec_exit:
+	lmg	$ivp,$ra,48($sp)
+	stmg	$t0,$t1,0($ivp)
+
+	br	$ra
+
+.align	16
+.Lcbc_dec_tail:
+	aghi	$len,15
+	stg	$s0,128($sp)
+	stg	$s2,136($sp)
+	bras	$s1,4f
+	mvc	0(1,$out),128($sp)
+4:	ex	$len,0($s1)
+	j	.Lcbc_dec_exit
+.size	AES_cbc_encrypt,.-AES_cbc_encrypt
+.comm  OPENSSL_s390xcap_P,8,8
+___
+}
+$code.=<<___;
+.string	"AES for s390x, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
diff --git a/openssl/crypto/aes/asm/aes-sparcv9.pl b/openssl/crypto/aes/asm/aes-sparcv9.pl
new file mode 100644
index 0000000..c57b3a2
--- /dev/null
+++ b/openssl/crypto/aes/asm/aes-sparcv9.pl
@@ -0,0 +1,1181 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. Rights for redistribution and usage in source and binary
+# forms are granted according to the OpenSSL license.
+# ====================================================================
+#
+# Version 1.1
+#
+# The major reason for undertaken effort was to mitigate the hazard of
+# cache-timing attack. This is [currently and initially!] addressed in
+# two ways. 1. S-boxes are compressed from 5KB to 2KB+256B size each.
+# 2. References to them are scheduled for L2 cache latency, meaning
+# that the tables don't have to reside in L1 cache. Once again, this
+# is an initial draft and one should expect more countermeasures to
+# be implemented...
+#
+# Version 1.1 prefetches T[ed]4 in order to mitigate attack on last
+# round.
+#
+# Even though performance was not the primary goal [on the contrary,
+# extra shifts "induced" by compressed S-box and longer loop epilogue
+# "induced" by scheduling for L2 have negative effect on performance],
+# the code turned out to run in ~23 cycles per processed byte en-/
+# decrypted with 128-bit key. This is pretty good result for code
+# with mentioned qualities and UltraSPARC core. Compared to Sun C
+# generated code my encrypt procedure runs just few percents faster,
+# while decrypt one - whole 50% faster [yes, Sun C failed to generate
+# optimal decrypt procedure]. Compared to GNU C generated code both
+# procedures are more than 60% faster:-)
+
+$bits=32;
+for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
+if ($bits==64)	{ $bias=2047; $frame=192; }
+else		{ $bias=0;    $frame=112; }
+$locals=16;
+
+$acc0="%l0";
+$acc1="%o0";
+$acc2="%o1";
+$acc3="%o2";
+
+$acc4="%l1";
+$acc5="%o3";
+$acc6="%o4";
+$acc7="%o5";
+
+$acc8="%l2";
+$acc9="%o7";
+$acc10="%g1";
+$acc11="%g2";
+
+$acc12="%l3";
+$acc13="%g3";
+$acc14="%g4";
+$acc15="%g5";
+
+$t0="%l4";
+$t1="%l5";
+$t2="%l6";
+$t3="%l7";
+
+$s0="%i0";
+$s1="%i1";
+$s2="%i2";
+$s3="%i3";
+$tbl="%i4";
+$key="%i5";
+$rounds="%i7";	# aliases with return address, which is off-loaded to stack
+
+sub _data_word()
+{ my $i;
+    while(defined($i=shift)) { $code.=sprintf"\t.long\t0x%08x,0x%08x\n",$i,$i; }
+}
+
+$code.=<<___ if ($bits==64);
+.register	%g2,#scratch
+.register	%g3,#scratch
+___
+$code.=<<___;
+.section	".text",#alloc,#execinstr
+
+.align	256
+AES_Te:
+___
+&_data_word(
+	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
+	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
+	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
+	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
+	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
+	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
+	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
+	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
+	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
+	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
+	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
+	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
+	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
+	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
+	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
+	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
+	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
+	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
+	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
+	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
+	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
+	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
+	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
+	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
+	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
+	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
+	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
+	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
+	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
+	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
+	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
+	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
+	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
+	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
+	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
+	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
+	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
+	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
+	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
+	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
+	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
+	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
+	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
+	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
+	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
+	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
+	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
+	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
+	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
+	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
+	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
+	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
+	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
+	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
+	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
+	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
+	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
+	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
+	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
+	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
+	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
+	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
+	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
+	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
+$code.=<<___;
+	.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
+	.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+	.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
+	.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+	.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
+	.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+	.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
+	.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+	.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
+	.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+	.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
+	.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+	.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
+	.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+	.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+	.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+	.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
+	.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+	.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
+	.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+	.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
+	.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+	.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
+	.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+	.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
+	.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+	.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
+	.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+	.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
+	.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+	.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
+	.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+.type	AES_Te,#object
+.size	AES_Te,(.-AES_Te)
+
+.align	64
+.skip	16
+_sparcv9_AES_encrypt:
+	save	%sp,-$frame-$locals,%sp
+	stx	%i7,[%sp+$bias+$frame+0]	! off-load return address
+	ld	[$key+240],$rounds
+	ld	[$key+0],$t0
+	ld	[$key+4],$t1			!
+	ld	[$key+8],$t2
+	srl	$rounds,1,$rounds
+	xor	$t0,$s0,$s0
+	ld	[$key+12],$t3
+	srl	$s0,21,$acc0
+	xor	$t1,$s1,$s1
+	ld	[$key+16],$t0
+	srl	$s1,13,$acc1			!
+	xor	$t2,$s2,$s2
+	ld	[$key+20],$t1
+	xor	$t3,$s3,$s3
+	ld	[$key+24],$t2
+	and	$acc0,2040,$acc0
+	ld	[$key+28],$t3
+	nop
+.Lenc_loop:
+	srl	$s2,5,$acc2			!
+	and	$acc1,2040,$acc1
+	ldx	[$tbl+$acc0],$acc0
+	sll	$s3,3,$acc3
+	and	$acc2,2040,$acc2
+	ldx	[$tbl+$acc1],$acc1
+	srl	$s1,21,$acc4
+	and	$acc3,2040,$acc3
+	ldx	[$tbl+$acc2],$acc2		!
+	srl	$s2,13,$acc5
+	and	$acc4,2040,$acc4
+	ldx	[$tbl+$acc3],$acc3
+	srl	$s3,5,$acc6
+	and	$acc5,2040,$acc5
+	ldx	[$tbl+$acc4],$acc4
+	fmovs	%f0,%f0
+	sll	$s0,3,$acc7			!
+	and	$acc6,2040,$acc6
+	ldx	[$tbl+$acc5],$acc5
+	srl	$s2,21,$acc8
+	and	$acc7,2040,$acc7
+	ldx	[$tbl+$acc6],$acc6
+	srl	$s3,13,$acc9
+	and	$acc8,2040,$acc8
+	ldx	[$tbl+$acc7],$acc7		!
+	srl	$s0,5,$acc10
+	and	$acc9,2040,$acc9
+	ldx	[$tbl+$acc8],$acc8
+	sll	$s1,3,$acc11
+	and	$acc10,2040,$acc10
+	ldx	[$tbl+$acc9],$acc9
+	fmovs	%f0,%f0
+	srl	$s3,21,$acc12			!
+	and	$acc11,2040,$acc11
+	ldx	[$tbl+$acc10],$acc10
+	srl	$s0,13,$acc13
+	and	$acc12,2040,$acc12
+	ldx	[$tbl+$acc11],$acc11
+	srl	$s1,5,$acc14
+	and	$acc13,2040,$acc13
+	ldx	[$tbl+$acc12],$acc12		!
+	sll	$s2,3,$acc15
+	and	$acc14,2040,$acc14
+	ldx	[$tbl+$acc13],$acc13
+	and	$acc15,2040,$acc15
+	add	$key,32,$key
+	ldx	[$tbl+$acc14],$acc14
+	fmovs	%f0,%f0
+	subcc	$rounds,1,$rounds		!
+	ldx	[$tbl+$acc15],$acc15
+	bz,a,pn	%icc,.Lenc_last
+	add	$tbl,2048,$rounds
+
+		srlx	$acc1,8,$acc1
+		xor	$acc0,$t0,$t0
+	ld	[$key+0],$s0
+	fmovs	%f0,%f0
+		srlx	$acc2,16,$acc2		!
+		xor	$acc1,$t0,$t0
+	ld	[$key+4],$s1
+		srlx	$acc3,24,$acc3
+		xor	$acc2,$t0,$t0
+	ld	[$key+8],$s2
+		srlx	$acc5,8,$acc5
+		xor	$acc3,$t0,$t0
+	ld	[$key+12],$s3			!
+		srlx	$acc6,16,$acc6
+		xor	$acc4,$t1,$t1
+	fmovs	%f0,%f0
+		srlx	$acc7,24,$acc7
+		xor	$acc5,$t1,$t1
+		srlx	$acc9,8,$acc9
+		xor	$acc6,$t1,$t1
+		srlx	$acc10,16,$acc10	!
+		xor	$acc7,$t1,$t1
+		srlx	$acc11,24,$acc11
+		xor	$acc8,$t2,$t2
+		srlx	$acc13,8,$acc13
+		xor	$acc9,$t2,$t2
+		srlx	$acc14,16,$acc14
+		xor	$acc10,$t2,$t2
+		srlx	$acc15,24,$acc15	!
+		xor	$acc11,$t2,$t2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$t3,$t3
+	srl	$t0,21,$acc0
+		xor	$acc14,$t3,$t3
+	srl	$t1,13,$acc1
+		xor	$acc15,$t3,$t3
+
+	and	$acc0,2040,$acc0		!
+	srl	$t2,5,$acc2
+	and	$acc1,2040,$acc1
+	ldx	[$tbl+$acc0],$acc0
+	sll	$t3,3,$acc3
+	and	$acc2,2040,$acc2
+	ldx	[$tbl+$acc1],$acc1
+	fmovs	%f0,%f0
+	srl	$t1,21,$acc4			!
+	and	$acc3,2040,$acc3
+	ldx	[$tbl+$acc2],$acc2
+	srl	$t2,13,$acc5
+	and	$acc4,2040,$acc4
+	ldx	[$tbl+$acc3],$acc3
+	srl	$t3,5,$acc6
+	and	$acc5,2040,$acc5
+	ldx	[$tbl+$acc4],$acc4		!
+	sll	$t0,3,$acc7
+	and	$acc6,2040,$acc6
+	ldx	[$tbl+$acc5],$acc5
+	srl	$t2,21,$acc8
+	and	$acc7,2040,$acc7
+	ldx	[$tbl+$acc6],$acc6
+	fmovs	%f0,%f0
+	srl	$t3,13,$acc9			!
+	and	$acc8,2040,$acc8
+	ldx	[$tbl+$acc7],$acc7
+	srl	$t0,5,$acc10
+	and	$acc9,2040,$acc9
+	ldx	[$tbl+$acc8],$acc8
+	sll	$t1,3,$acc11
+	and	$acc10,2040,$acc10
+	ldx	[$tbl+$acc9],$acc9		!
+	srl	$t3,21,$acc12
+	and	$acc11,2040,$acc11
+	ldx	[$tbl+$acc10],$acc10
+	srl	$t0,13,$acc13
+	and	$acc12,2040,$acc12
+	ldx	[$tbl+$acc11],$acc11
+	fmovs	%f0,%f0
+	srl	$t1,5,$acc14			!
+	and	$acc13,2040,$acc13
+	ldx	[$tbl+$acc12],$acc12
+	sll	$t2,3,$acc15
+	and	$acc14,2040,$acc14
+	ldx	[$tbl+$acc13],$acc13
+		srlx	$acc1,8,$acc1
+	and	$acc15,2040,$acc15
+	ldx	[$tbl+$acc14],$acc14		!
+
+		srlx	$acc2,16,$acc2
+		xor	$acc0,$s0,$s0
+	ldx	[$tbl+$acc15],$acc15
+		srlx	$acc3,24,$acc3
+		xor	$acc1,$s0,$s0
+	ld	[$key+16],$t0
+	fmovs	%f0,%f0
+		srlx	$acc5,8,$acc5		!
+		xor	$acc2,$s0,$s0
+	ld	[$key+20],$t1
+		srlx	$acc6,16,$acc6
+		xor	$acc3,$s0,$s0
+	ld	[$key+24],$t2
+		srlx	$acc7,24,$acc7
+		xor	$acc4,$s1,$s1
+	ld	[$key+28],$t3			!
+		srlx	$acc9,8,$acc9
+		xor	$acc5,$s1,$s1
+	ldx	[$tbl+2048+0],%g0		! prefetch te4
+		srlx	$acc10,16,$acc10
+		xor	$acc6,$s1,$s1
+	ldx	[$tbl+2048+32],%g0		! prefetch te4
+		srlx	$acc11,24,$acc11
+		xor	$acc7,$s1,$s1
+	ldx	[$tbl+2048+64],%g0		! prefetch te4
+		srlx	$acc13,8,$acc13
+		xor	$acc8,$s2,$s2
+	ldx	[$tbl+2048+96],%g0		! prefetch te4
+		srlx	$acc14,16,$acc14	!
+		xor	$acc9,$s2,$s2
+	ldx	[$tbl+2048+128],%g0		! prefetch te4
+		srlx	$acc15,24,$acc15
+		xor	$acc10,$s2,$s2
+	ldx	[$tbl+2048+160],%g0		! prefetch te4
+	srl	$s0,21,$acc0
+		xor	$acc11,$s2,$s2
+	ldx	[$tbl+2048+192],%g0		! prefetch te4
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$s3,$s3
+	ldx	[$tbl+2048+224],%g0		! prefetch te4
+	srl	$s1,13,$acc1			!
+		xor	$acc14,$s3,$s3
+		xor	$acc15,$s3,$s3
+	ba	.Lenc_loop
+	and	$acc0,2040,$acc0
+
+.align	32
+.Lenc_last:
+		srlx	$acc1,8,$acc1		!
+		xor	$acc0,$t0,$t0
+	ld	[$key+0],$s0
+		srlx	$acc2,16,$acc2
+		xor	$acc1,$t0,$t0
+	ld	[$key+4],$s1
+		srlx	$acc3,24,$acc3
+		xor	$acc2,$t0,$t0
+	ld	[$key+8],$s2			!
+		srlx	$acc5,8,$acc5
+		xor	$acc3,$t0,$t0
+	ld	[$key+12],$s3
+		srlx	$acc6,16,$acc6
+		xor	$acc4,$t1,$t1
+		srlx	$acc7,24,$acc7
+		xor	$acc5,$t1,$t1
+		srlx	$acc9,8,$acc9		!
+		xor	$acc6,$t1,$t1
+		srlx	$acc10,16,$acc10
+		xor	$acc7,$t1,$t1
+		srlx	$acc11,24,$acc11
+		xor	$acc8,$t2,$t2
+		srlx	$acc13,8,$acc13
+		xor	$acc9,$t2,$t2
+		srlx	$acc14,16,$acc14	!
+		xor	$acc10,$t2,$t2
+		srlx	$acc15,24,$acc15
+		xor	$acc11,$t2,$t2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$t3,$t3
+	srl	$t0,24,$acc0
+		xor	$acc14,$t3,$t3
+	srl	$t1,16,$acc1			!
+		xor	$acc15,$t3,$t3
+
+	srl	$t2,8,$acc2
+	and	$acc1,255,$acc1
+	ldub	[$rounds+$acc0],$acc0
+	srl	$t1,24,$acc4
+	and	$acc2,255,$acc2
+	ldub	[$rounds+$acc1],$acc1
+	srl	$t2,16,$acc5			!
+	and	$t3,255,$acc3
+	ldub	[$rounds+$acc2],$acc2
+	ldub	[$rounds+$acc3],$acc3
+	srl	$t3,8,$acc6
+	and	$acc5,255,$acc5
+	ldub	[$rounds+$acc4],$acc4
+	fmovs	%f0,%f0
+	srl	$t2,24,$acc8			!
+	and	$acc6,255,$acc6
+	ldub	[$rounds+$acc5],$acc5
+	srl	$t3,16,$acc9
+	and	$t0,255,$acc7
+	ldub	[$rounds+$acc6],$acc6
+	ldub	[$rounds+$acc7],$acc7
+	fmovs	%f0,%f0
+	srl	$t0,8,$acc10			!
+	and	$acc9,255,$acc9
+	ldub	[$rounds+$acc8],$acc8
+	srl	$t3,24,$acc12
+	and	$acc10,255,$acc10
+	ldub	[$rounds+$acc9],$acc9
+	srl	$t0,16,$acc13
+	and	$t1,255,$acc11
+	ldub	[$rounds+$acc10],$acc10		!
+	srl	$t1,8,$acc14
+	and	$acc13,255,$acc13
+	ldub	[$rounds+$acc11],$acc11
+	ldub	[$rounds+$acc12],$acc12
+	and	$acc14,255,$acc14
+	ldub	[$rounds+$acc13],$acc13
+	and	$t2,255,$acc15
+	ldub	[$rounds+$acc14],$acc14		!
+
+		sll	$acc0,24,$acc0
+		xor	$acc3,$s0,$s0
+	ldub	[$rounds+$acc15],$acc15
+		sll	$acc1,16,$acc1
+		xor	$acc0,$s0,$s0
+	ldx	[%sp+$bias+$frame+0],%i7	! restore return address
+	fmovs	%f0,%f0
+		sll	$acc2,8,$acc2		!
+		xor	$acc1,$s0,$s0
+		sll	$acc4,24,$acc4
+		xor	$acc2,$s0,$s0
+		sll	$acc5,16,$acc5
+		xor	$acc7,$s1,$s1
+		sll	$acc6,8,$acc6
+		xor	$acc4,$s1,$s1
+		sll	$acc8,24,$acc8		!
+		xor	$acc5,$s1,$s1
+		sll	$acc9,16,$acc9
+		xor	$acc11,$s2,$s2
+		sll	$acc10,8,$acc10
+		xor	$acc6,$s1,$s1
+		sll	$acc12,24,$acc12
+		xor	$acc8,$s2,$s2
+		sll	$acc13,16,$acc13	!
+		xor	$acc9,$s2,$s2
+		sll	$acc14,8,$acc14
+		xor	$acc10,$s2,$s2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$s3,$s3
+		xor	$acc14,$s3,$s3
+		xor	$acc15,$s3,$s3
+
+	ret
+	restore
+.type	_sparcv9_AES_encrypt,#function
+.size	_sparcv9_AES_encrypt,(.-_sparcv9_AES_encrypt)
+
+.align	32
+.globl	AES_encrypt
+AES_encrypt:
+	or	%o0,%o1,%g1
+	andcc	%g1,3,%g0
+	bnz,pn	%xcc,.Lunaligned_enc
+	save	%sp,-$frame,%sp
+
+	ld	[%i0+0],%o0
+	ld	[%i0+4],%o1
+	ld	[%i0+8],%o2
+	ld	[%i0+12],%o3
+
+1:	call	.+8
+	add	%o7,AES_Te-1b,%o4
+	call	_sparcv9_AES_encrypt
+	mov	%i2,%o5
+
+	st	%o0,[%i1+0]
+	st	%o1,[%i1+4]
+	st	%o2,[%i1+8]
+	st	%o3,[%i1+12]
+
+	ret
+	restore
+
+.align	32
+.Lunaligned_enc:
+	ldub	[%i0+0],%l0
+	ldub	[%i0+1],%l1
+	ldub	[%i0+2],%l2
+
+	sll	%l0,24,%l0
+	ldub	[%i0+3],%l3
+	sll	%l1,16,%l1
+	ldub	[%i0+4],%l4
+	sll	%l2,8,%l2
+	or	%l1,%l0,%l0
+	ldub	[%i0+5],%l5
+	sll	%l4,24,%l4
+	or	%l3,%l2,%l2
+	ldub	[%i0+6],%l6
+	sll	%l5,16,%l5
+	or	%l0,%l2,%o0
+	ldub	[%i0+7],%l7
+
+	sll	%l6,8,%l6
+	or	%l5,%l4,%l4
+	ldub	[%i0+8],%l0
+	or	%l7,%l6,%l6
+	ldub	[%i0+9],%l1
+	or	%l4,%l6,%o1
+	ldub	[%i0+10],%l2
+
+	sll	%l0,24,%l0
+	ldub	[%i0+11],%l3
+	sll	%l1,16,%l1
+	ldub	[%i0+12],%l4
+	sll	%l2,8,%l2
+	or	%l1,%l0,%l0
+	ldub	[%i0+13],%l5
+	sll	%l4,24,%l4
+	or	%l3,%l2,%l2
+	ldub	[%i0+14],%l6
+	sll	%l5,16,%l5
+	or	%l0,%l2,%o2
+	ldub	[%i0+15],%l7
+
+	sll	%l6,8,%l6
+	or	%l5,%l4,%l4
+	or	%l7,%l6,%l6
+	or	%l4,%l6,%o3
+
+1:	call	.+8
+	add	%o7,AES_Te-1b,%o4
+	call	_sparcv9_AES_encrypt
+	mov	%i2,%o5
+
+	srl	%o0,24,%l0
+	srl	%o0,16,%l1
+	stb	%l0,[%i1+0]
+	srl	%o0,8,%l2
+	stb	%l1,[%i1+1]
+	stb	%l2,[%i1+2]
+	srl	%o1,24,%l4
+	stb	%o0,[%i1+3]
+
+	srl	%o1,16,%l5
+	stb	%l4,[%i1+4]
+	srl	%o1,8,%l6
+	stb	%l5,[%i1+5]
+	stb	%l6,[%i1+6]
+	srl	%o2,24,%l0
+	stb	%o1,[%i1+7]
+
+	srl	%o2,16,%l1
+	stb	%l0,[%i1+8]
+	srl	%o2,8,%l2
+	stb	%l1,[%i1+9]
+	stb	%l2,[%i1+10]
+	srl	%o3,24,%l4
+	stb	%o2,[%i1+11]
+
+	srl	%o3,16,%l5
+	stb	%l4,[%i1+12]
+	srl	%o3,8,%l6
+	stb	%l5,[%i1+13]
+	stb	%l6,[%i1+14]
+	stb	%o3,[%i1+15]
+
+	ret
+	restore
+.type	AES_encrypt,#function
+.size	AES_encrypt,(.-AES_encrypt)
+
+___
+
+$code.=<<___;
+.align	256
+AES_Td:
+___
+&_data_word(
+	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
+	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
+	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
+	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
+	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
+	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
+	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
+	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
+	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
+	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
+	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
+	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
+	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
+	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
+	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
+	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
+	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
+	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
+	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
+	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
+	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
+	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
+	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
+	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
+	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
+	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
+	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
+	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
+	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
+	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
+	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
+	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
+	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
+	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
+	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
+	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
+	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
+	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
+	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
+	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
+	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
+	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
+	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
+	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
+	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
+	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
+	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
+	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
+	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
+	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
+	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
+	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
+	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
+	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
+	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
+	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
+	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
+	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
+	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
+	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
+	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
+	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
+	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
+	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
+$code.=<<___;
+	.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
+	.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+	.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
+	.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+	.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
+	.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+	.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
+	.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+	.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
+	.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+	.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
+	.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+	.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
+	.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+	.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
+	.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+	.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
+	.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+	.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
+	.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+	.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
+	.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+	.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
+	.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+	.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
+	.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+	.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
+	.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+	.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
+	.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+	.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
+	.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+.type	AES_Td,#object
+.size	AES_Td,(.-AES_Td)
+
+.align	64
+.skip	16
+_sparcv9_AES_decrypt:
+	save	%sp,-$frame-$locals,%sp
+	stx	%i7,[%sp+$bias+$frame+0]	! off-load return address
+	ld	[$key+240],$rounds
+	ld	[$key+0],$t0
+	ld	[$key+4],$t1			!
+	ld	[$key+8],$t2
+	ld	[$key+12],$t3
+	srl	$rounds,1,$rounds
+	xor	$t0,$s0,$s0
+	ld	[$key+16],$t0
+	xor	$t1,$s1,$s1
+	ld	[$key+20],$t1
+	srl	$s0,21,$acc0			!
+	xor	$t2,$s2,$s2
+	ld	[$key+24],$t2
+	xor	$t3,$s3,$s3
+	and	$acc0,2040,$acc0
+	ld	[$key+28],$t3
+	srl	$s3,13,$acc1
+	nop
+.Ldec_loop:
+	srl	$s2,5,$acc2			!
+	and	$acc1,2040,$acc1
+	ldx	[$tbl+$acc0],$acc0
+	sll	$s1,3,$acc3
+	and	$acc2,2040,$acc2
+	ldx	[$tbl+$acc1],$acc1
+	srl	$s1,21,$acc4
+	and	$acc3,2040,$acc3
+	ldx	[$tbl+$acc2],$acc2		!
+	srl	$s0,13,$acc5
+	and	$acc4,2040,$acc4
+	ldx	[$tbl+$acc3],$acc3
+	srl	$s3,5,$acc6
+	and	$acc5,2040,$acc5
+	ldx	[$tbl+$acc4],$acc4
+	fmovs	%f0,%f0
+	sll	$s2,3,$acc7			!
+	and	$acc6,2040,$acc6
+	ldx	[$tbl+$acc5],$acc5
+	srl	$s2,21,$acc8
+	and	$acc7,2040,$acc7
+	ldx	[$tbl+$acc6],$acc6
+	srl	$s1,13,$acc9
+	and	$acc8,2040,$acc8
+	ldx	[$tbl+$acc7],$acc7		!
+	srl	$s0,5,$acc10
+	and	$acc9,2040,$acc9
+	ldx	[$tbl+$acc8],$acc8
+	sll	$s3,3,$acc11
+	and	$acc10,2040,$acc10
+	ldx	[$tbl+$acc9],$acc9
+	fmovs	%f0,%f0
+	srl	$s3,21,$acc12			!
+	and	$acc11,2040,$acc11
+	ldx	[$tbl+$acc10],$acc10
+	srl	$s2,13,$acc13
+	and	$acc12,2040,$acc12
+	ldx	[$tbl+$acc11],$acc11
+	srl	$s1,5,$acc14
+	and	$acc13,2040,$acc13
+	ldx	[$tbl+$acc12],$acc12		!
+	sll	$s0,3,$acc15
+	and	$acc14,2040,$acc14
+	ldx	[$tbl+$acc13],$acc13
+	and	$acc15,2040,$acc15
+	add	$key,32,$key
+	ldx	[$tbl+$acc14],$acc14
+	fmovs	%f0,%f0
+	subcc	$rounds,1,$rounds		!
+	ldx	[$tbl+$acc15],$acc15
+	bz,a,pn	%icc,.Ldec_last
+	add	$tbl,2048,$rounds
+
+		srlx	$acc1,8,$acc1
+		xor	$acc0,$t0,$t0
+	ld	[$key+0],$s0
+	fmovs	%f0,%f0
+		srlx	$acc2,16,$acc2		!
+		xor	$acc1,$t0,$t0
+	ld	[$key+4],$s1
+		srlx	$acc3,24,$acc3
+		xor	$acc2,$t0,$t0
+	ld	[$key+8],$s2
+		srlx	$acc5,8,$acc5
+		xor	$acc3,$t0,$t0
+	ld	[$key+12],$s3			!
+		srlx	$acc6,16,$acc6
+		xor	$acc4,$t1,$t1
+	fmovs	%f0,%f0
+		srlx	$acc7,24,$acc7
+		xor	$acc5,$t1,$t1
+		srlx	$acc9,8,$acc9
+		xor	$acc6,$t1,$t1
+		srlx	$acc10,16,$acc10	!
+		xor	$acc7,$t1,$t1
+		srlx	$acc11,24,$acc11
+		xor	$acc8,$t2,$t2
+		srlx	$acc13,8,$acc13
+		xor	$acc9,$t2,$t2
+		srlx	$acc14,16,$acc14
+		xor	$acc10,$t2,$t2
+		srlx	$acc15,24,$acc15	!
+		xor	$acc11,$t2,$t2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$t3,$t3
+	srl	$t0,21,$acc0
+		xor	$acc14,$t3,$t3
+		xor	$acc15,$t3,$t3
+	srl	$t3,13,$acc1
+
+	and	$acc0,2040,$acc0		!
+	srl	$t2,5,$acc2
+	and	$acc1,2040,$acc1
+	ldx	[$tbl+$acc0],$acc0
+	sll	$t1,3,$acc3
+	and	$acc2,2040,$acc2
+	ldx	[$tbl+$acc1],$acc1
+	fmovs	%f0,%f0
+	srl	$t1,21,$acc4			!
+	and	$acc3,2040,$acc3
+	ldx	[$tbl+$acc2],$acc2
+	srl	$t0,13,$acc5
+	and	$acc4,2040,$acc4
+	ldx	[$tbl+$acc3],$acc3
+	srl	$t3,5,$acc6
+	and	$acc5,2040,$acc5
+	ldx	[$tbl+$acc4],$acc4		!
+	sll	$t2,3,$acc7
+	and	$acc6,2040,$acc6
+	ldx	[$tbl+$acc5],$acc5
+	srl	$t2,21,$acc8
+	and	$acc7,2040,$acc7
+	ldx	[$tbl+$acc6],$acc6
+	fmovs	%f0,%f0
+	srl	$t1,13,$acc9			!
+	and	$acc8,2040,$acc8
+	ldx	[$tbl+$acc7],$acc7
+	srl	$t0,5,$acc10
+	and	$acc9,2040,$acc9
+	ldx	[$tbl+$acc8],$acc8
+	sll	$t3,3,$acc11
+	and	$acc10,2040,$acc10
+	ldx	[$tbl+$acc9],$acc9		!
+	srl	$t3,21,$acc12
+	and	$acc11,2040,$acc11
+	ldx	[$tbl+$acc10],$acc10
+	srl	$t2,13,$acc13
+	and	$acc12,2040,$acc12
+	ldx	[$tbl+$acc11],$acc11
+	fmovs	%f0,%f0
+	srl	$t1,5,$acc14			!
+	and	$acc13,2040,$acc13
+	ldx	[$tbl+$acc12],$acc12
+	sll	$t0,3,$acc15
+	and	$acc14,2040,$acc14
+	ldx	[$tbl+$acc13],$acc13
+		srlx	$acc1,8,$acc1
+	and	$acc15,2040,$acc15
+	ldx	[$tbl+$acc14],$acc14		!
+
+		srlx	$acc2,16,$acc2
+		xor	$acc0,$s0,$s0
+	ldx	[$tbl+$acc15],$acc15
+		srlx	$acc3,24,$acc3
+		xor	$acc1,$s0,$s0
+	ld	[$key+16],$t0
+	fmovs	%f0,%f0
+		srlx	$acc5,8,$acc5		!
+		xor	$acc2,$s0,$s0
+	ld	[$key+20],$t1
+		srlx	$acc6,16,$acc6
+		xor	$acc3,$s0,$s0
+	ld	[$key+24],$t2
+		srlx	$acc7,24,$acc7
+		xor	$acc4,$s1,$s1
+	ld	[$key+28],$t3			!
+		srlx	$acc9,8,$acc9
+		xor	$acc5,$s1,$s1
+	ldx	[$tbl+2048+0],%g0		! prefetch td4
+		srlx	$acc10,16,$acc10
+		xor	$acc6,$s1,$s1
+	ldx	[$tbl+2048+32],%g0		! prefetch td4
+		srlx	$acc11,24,$acc11
+		xor	$acc7,$s1,$s1
+	ldx	[$tbl+2048+64],%g0		! prefetch td4
+		srlx	$acc13,8,$acc13
+		xor	$acc8,$s2,$s2
+	ldx	[$tbl+2048+96],%g0		! prefetch td4
+		srlx	$acc14,16,$acc14	!
+		xor	$acc9,$s2,$s2
+	ldx	[$tbl+2048+128],%g0		! prefetch td4
+		srlx	$acc15,24,$acc15
+		xor	$acc10,$s2,$s2
+	ldx	[$tbl+2048+160],%g0		! prefetch td4
+	srl	$s0,21,$acc0
+		xor	$acc11,$s2,$s2
+	ldx	[$tbl+2048+192],%g0		! prefetch td4
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$s3,$s3
+	ldx	[$tbl+2048+224],%g0		! prefetch td4
+	and	$acc0,2040,$acc0		!
+		xor	$acc14,$s3,$s3
+		xor	$acc15,$s3,$s3
+	ba	.Ldec_loop
+	srl	$s3,13,$acc1
+
+.align	32
+.Ldec_last:
+		srlx	$acc1,8,$acc1		!
+		xor	$acc0,$t0,$t0
+	ld	[$key+0],$s0
+		srlx	$acc2,16,$acc2
+		xor	$acc1,$t0,$t0
+	ld	[$key+4],$s1
+		srlx	$acc3,24,$acc3
+		xor	$acc2,$t0,$t0
+	ld	[$key+8],$s2			!
+		srlx	$acc5,8,$acc5
+		xor	$acc3,$t0,$t0
+	ld	[$key+12],$s3
+		srlx	$acc6,16,$acc6
+		xor	$acc4,$t1,$t1
+		srlx	$acc7,24,$acc7
+		xor	$acc5,$t1,$t1
+		srlx	$acc9,8,$acc9		!
+		xor	$acc6,$t1,$t1
+		srlx	$acc10,16,$acc10
+		xor	$acc7,$t1,$t1
+		srlx	$acc11,24,$acc11
+		xor	$acc8,$t2,$t2
+		srlx	$acc13,8,$acc13
+		xor	$acc9,$t2,$t2
+		srlx	$acc14,16,$acc14	!
+		xor	$acc10,$t2,$t2
+		srlx	$acc15,24,$acc15
+		xor	$acc11,$t2,$t2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$t3,$t3
+	srl	$t0,24,$acc0
+		xor	$acc14,$t3,$t3
+		xor	$acc15,$t3,$t3		!
+	srl	$t3,16,$acc1
+
+	srl	$t2,8,$acc2
+	and	$acc1,255,$acc1
+	ldub	[$rounds+$acc0],$acc0
+	srl	$t1,24,$acc4
+	and	$acc2,255,$acc2
+	ldub	[$rounds+$acc1],$acc1
+	srl	$t0,16,$acc5			!
+	and	$t1,255,$acc3
+	ldub	[$rounds+$acc2],$acc2
+	ldub	[$rounds+$acc3],$acc3
+	srl	$t3,8,$acc6
+	and	$acc5,255,$acc5
+	ldub	[$rounds+$acc4],$acc4
+	fmovs	%f0,%f0
+	srl	$t2,24,$acc8			!
+	and	$acc6,255,$acc6
+	ldub	[$rounds+$acc5],$acc5
+	srl	$t1,16,$acc9
+	and	$t2,255,$acc7
+	ldub	[$rounds+$acc6],$acc6
+	ldub	[$rounds+$acc7],$acc7
+	fmovs	%f0,%f0
+	srl	$t0,8,$acc10			!
+	and	$acc9,255,$acc9
+	ldub	[$rounds+$acc8],$acc8
+	srl	$t3,24,$acc12
+	and	$acc10,255,$acc10
+	ldub	[$rounds+$acc9],$acc9
+	srl	$t2,16,$acc13
+	and	$t3,255,$acc11
+	ldub	[$rounds+$acc10],$acc10		!
+	srl	$t1,8,$acc14
+	and	$acc13,255,$acc13
+	ldub	[$rounds+$acc11],$acc11
+	ldub	[$rounds+$acc12],$acc12
+	and	$acc14,255,$acc14
+	ldub	[$rounds+$acc13],$acc13
+	and	$t0,255,$acc15
+	ldub	[$rounds+$acc14],$acc14		!
+
+		sll	$acc0,24,$acc0
+		xor	$acc3,$s0,$s0
+	ldub	[$rounds+$acc15],$acc15
+		sll	$acc1,16,$acc1
+		xor	$acc0,$s0,$s0
+	ldx	[%sp+$bias+$frame+0],%i7	! restore return address
+	fmovs	%f0,%f0
+		sll	$acc2,8,$acc2		!
+		xor	$acc1,$s0,$s0
+		sll	$acc4,24,$acc4
+		xor	$acc2,$s0,$s0
+		sll	$acc5,16,$acc5
+		xor	$acc7,$s1,$s1
+		sll	$acc6,8,$acc6
+		xor	$acc4,$s1,$s1
+		sll	$acc8,24,$acc8		!
+		xor	$acc5,$s1,$s1
+		sll	$acc9,16,$acc9
+		xor	$acc11,$s2,$s2
+		sll	$acc10,8,$acc10
+		xor	$acc6,$s1,$s1
+		sll	$acc12,24,$acc12
+		xor	$acc8,$s2,$s2
+		sll	$acc13,16,$acc13	!
+		xor	$acc9,$s2,$s2
+		sll	$acc14,8,$acc14
+		xor	$acc10,$s2,$s2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$s3,$s3
+		xor	$acc14,$s3,$s3
+		xor	$acc15,$s3,$s3
+
+	ret
+	restore
+.type	_sparcv9_AES_decrypt,#function
+.size	_sparcv9_AES_decrypt,(.-_sparcv9_AES_decrypt)
+
+.align	32
+.globl	AES_decrypt
+AES_decrypt:
+	or	%o0,%o1,%g1
+	andcc	%g1,3,%g0
+	bnz,pn	%xcc,.Lunaligned_dec
+	save	%sp,-$frame,%sp
+
+	ld	[%i0+0],%o0
+	ld	[%i0+4],%o1
+	ld	[%i0+8],%o2
+	ld	[%i0+12],%o3
+
+1:	call	.+8
+	add	%o7,AES_Td-1b,%o4
+	call	_sparcv9_AES_decrypt
+	mov	%i2,%o5
+
+	st	%o0,[%i1+0]
+	st	%o1,[%i1+4]
+	st	%o2,[%i1+8]
+	st	%o3,[%i1+12]
+
+	ret
+	restore
+
+.align	32
+.Lunaligned_dec:
+	ldub	[%i0+0],%l0
+	ldub	[%i0+1],%l1
+	ldub	[%i0+2],%l2
+
+	sll	%l0,24,%l0
+	ldub	[%i0+3],%l3
+	sll	%l1,16,%l1
+	ldub	[%i0+4],%l4
+	sll	%l2,8,%l2
+	or	%l1,%l0,%l0
+	ldub	[%i0+5],%l5
+	sll	%l4,24,%l4
+	or	%l3,%l2,%l2
+	ldub	[%i0+6],%l6
+	sll	%l5,16,%l5
+	or	%l0,%l2,%o0
+	ldub	[%i0+7],%l7
+
+	sll	%l6,8,%l6
+	or	%l5,%l4,%l4
+	ldub	[%i0+8],%l0
+	or	%l7,%l6,%l6
+	ldub	[%i0+9],%l1
+	or	%l4,%l6,%o1
+	ldub	[%i0+10],%l2
+
+	sll	%l0,24,%l0
+	ldub	[%i0+11],%l3
+	sll	%l1,16,%l1
+	ldub	[%i0+12],%l4
+	sll	%l2,8,%l2
+	or	%l1,%l0,%l0
+	ldub	[%i0+13],%l5
+	sll	%l4,24,%l4
+	or	%l3,%l2,%l2
+	ldub	[%i0+14],%l6
+	sll	%l5,16,%l5
+	or	%l0,%l2,%o2
+	ldub	[%i0+15],%l7
+
+	sll	%l6,8,%l6
+	or	%l5,%l4,%l4
+	or	%l7,%l6,%l6
+	or	%l4,%l6,%o3
+
+1:	call	.+8
+	add	%o7,AES_Td-1b,%o4
+	call	_sparcv9_AES_decrypt
+	mov	%i2,%o5
+
+	srl	%o0,24,%l0
+	srl	%o0,16,%l1
+	stb	%l0,[%i1+0]
+	srl	%o0,8,%l2
+	stb	%l1,[%i1+1]
+	stb	%l2,[%i1+2]
+	srl	%o1,24,%l4
+	stb	%o0,[%i1+3]
+
+	srl	%o1,16,%l5
+	stb	%l4,[%i1+4]
+	srl	%o1,8,%l6
+	stb	%l5,[%i1+5]
+	stb	%l6,[%i1+6]
+	srl	%o2,24,%l0
+	stb	%o1,[%i1+7]
+
+	srl	%o2,16,%l1
+	stb	%l0,[%i1+8]
+	srl	%o2,8,%l2
+	stb	%l1,[%i1+9]
+	stb	%l2,[%i1+10]
+	srl	%o3,24,%l4
+	stb	%o2,[%i1+11]
+
+	srl	%o3,16,%l5
+	stb	%l4,[%i1+12]
+	srl	%o3,8,%l6
+	stb	%l5,[%i1+13]
+	stb	%l6,[%i1+14]
+	stb	%o3,[%i1+15]
+
+	ret
+	restore
+.type	AES_decrypt,#function
+.size	AES_decrypt,(.-AES_decrypt)
+___
+
+# fmovs instructions substituting for FP nops were originally added
+# to meet specific instruction alignment requirements to maximize ILP.
+# As UltraSPARC T1, a.k.a. Niagara, has shared FPU, FP nops can have
+# undesired effect, so just omit them and sacrifice some portion of
+# percent in performance...
+$code =~ s/fmovs.*$//gem;
+
+print $code;
diff --git a/openssl/crypto/aes/asm/aes-x86_64.pl b/openssl/crypto/aes/asm/aes-x86_64.pl
new file mode 100755
index 0000000..a545e89
--- /dev/null
+++ b/openssl/crypto/aes/asm/aes-x86_64.pl
@@ -0,0 +1,2809 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# Version 2.1.
+#
+# aes-*-cbc benchmarks are improved by >70% [compared to gcc 3.3.2 on
+# Opteron 240 CPU] plus all the bells-n-whistles from 32-bit version
+# [you'll notice a lot of resemblance], such as compressed S-boxes
+# in little-endian byte order, prefetch of these tables in CBC mode,
+# as well as avoiding L1 cache aliasing between stack frame and key
+# schedule and already mentioned tables, compressed Td4...
+#
+# Performance in number of cycles per processed byte for 128-bit key:
+#
+#		ECB encrypt	ECB decrypt	CBC large chunk
+# AMD64		33		41		13.0
+# EM64T		38		59		18.6(*)
+# Core 2	30		43		14.5(*)
+#
+# (*) with hyper-threading off
+
+$flavour = shift;
+$output  = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour $output";
+
+$verticalspin=1;	# unlike 32-bit version $verticalspin performs
+			# ~15% better on both AMD and Intel cores
+$speed_limit=512;	# see aes-586.pl for details
+
+$code=".text\n";
+
+$s0="%eax";
+$s1="%ebx";
+$s2="%ecx";
+$s3="%edx";
+$acc0="%esi";	$mask80="%rsi";
+$acc1="%edi";	$maskfe="%rdi";
+$acc2="%ebp";	$mask1b="%rbp";
+$inp="%r8";
+$out="%r9";
+$t0="%r10d";
+$t1="%r11d";
+$t2="%r12d";
+$rnds="%r13d";
+$sbox="%r14";
+$key="%r15";
+
+sub hi() { my $r=shift;	$r =~ s/%[er]([a-d])x/%\1h/;	$r; }
+sub lo() { my $r=shift;	$r =~ s/%[er]([a-d])x/%\1l/;
+			$r =~ s/%[er]([sd]i)/%\1l/;
+			$r =~ s/%(r[0-9]+)[d]?/%\1b/;	$r; }
+sub LO() { my $r=shift; $r =~ s/%r([a-z]+)/%e\1/;
+			$r =~ s/%r([0-9]+)/%r\1d/;	$r; }
+sub _data_word()
+{ my $i;
+    while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; }
+}
+sub data_word()
+{ my $i;
+  my $last=pop(@_);
+    $code.=".long\t";
+    while(defined($i=shift)) { $code.=sprintf"0x%08x,",$i; }
+    $code.=sprintf"0x%08x\n",$last;
+}
+
+sub data_byte()
+{ my $i;
+  my $last=pop(@_);
+    $code.=".byte\t";
+    while(defined($i=shift)) { $code.=sprintf"0x%02x,",$i&0xff; }
+    $code.=sprintf"0x%02x\n",$last&0xff;
+}
+
+sub encvert()
+{ my $t3="%r8d";	# zaps $inp!
+
+$code.=<<___;
+	# favor 3-way issue Opteron pipeline...
+	movzb	`&lo("$s0")`,$acc0
+	movzb	`&lo("$s1")`,$acc1
+	movzb	`&lo("$s2")`,$acc2
+	mov	0($sbox,$acc0,8),$t0
+	mov	0($sbox,$acc1,8),$t1
+	mov	0($sbox,$acc2,8),$t2
+
+	movzb	`&hi("$s1")`,$acc0
+	movzb	`&hi("$s2")`,$acc1
+	movzb	`&lo("$s3")`,$acc2
+	xor	3($sbox,$acc0,8),$t0
+	xor	3($sbox,$acc1,8),$t1
+	mov	0($sbox,$acc2,8),$t3
+
+	movzb	`&hi("$s3")`,$acc0
+	shr	\$16,$s2
+	movzb	`&hi("$s0")`,$acc2
+	xor	3($sbox,$acc0,8),$t2
+	shr	\$16,$s3
+	xor	3($sbox,$acc2,8),$t3
+
+	shr	\$16,$s1
+	lea	16($key),$key
+	shr	\$16,$s0
+
+	movzb	`&lo("$s2")`,$acc0
+	movzb	`&lo("$s3")`,$acc1
+	movzb	`&lo("$s0")`,$acc2
+	xor	2($sbox,$acc0,8),$t0
+	xor	2($sbox,$acc1,8),$t1
+	xor	2($sbox,$acc2,8),$t2
+
+	movzb	`&hi("$s3")`,$acc0
+	movzb	`&hi("$s0")`,$acc1
+	movzb	`&lo("$s1")`,$acc2
+	xor	1($sbox,$acc0,8),$t0
+	xor	1($sbox,$acc1,8),$t1
+	xor	2($sbox,$acc2,8),$t3
+
+	mov	12($key),$s3
+	movzb	`&hi("$s1")`,$acc1
+	movzb	`&hi("$s2")`,$acc2
+	mov	0($key),$s0
+	xor	1($sbox,$acc1,8),$t2
+	xor	1($sbox,$acc2,8),$t3
+
+	mov	4($key),$s1
+	mov	8($key),$s2
+	xor	$t0,$s0
+	xor	$t1,$s1
+	xor	$t2,$s2
+	xor	$t3,$s3
+___
+}
+
+sub enclastvert()
+{ my $t3="%r8d";	# zaps $inp!
+
+$code.=<<___;
+	movzb	`&lo("$s0")`,$acc0
+	movzb	`&lo("$s1")`,$acc1
+	movzb	`&lo("$s2")`,$acc2
+	movzb	2($sbox,$acc0,8),$t0
+	movzb	2($sbox,$acc1,8),$t1
+	movzb	2($sbox,$acc2,8),$t2
+
+	movzb	`&lo("$s3")`,$acc0
+	movzb	`&hi("$s1")`,$acc1
+	movzb	`&hi("$s2")`,$acc2
+	movzb	2($sbox,$acc0,8),$t3
+	mov	0($sbox,$acc1,8),$acc1	#$t0
+	mov	0($sbox,$acc2,8),$acc2	#$t1
+
+	and	\$0x0000ff00,$acc1
+	and	\$0x0000ff00,$acc2
+
+	xor	$acc1,$t0
+	xor	$acc2,$t1
+	shr	\$16,$s2
+
+	movzb	`&hi("$s3")`,$acc0
+	movzb	`&hi("$s0")`,$acc1
+	shr	\$16,$s3
+	mov	0($sbox,$acc0,8),$acc0	#$t2
+	mov	0($sbox,$acc1,8),$acc1	#$t3
+
+	and	\$0x0000ff00,$acc0
+	and	\$0x0000ff00,$acc1
+	shr	\$16,$s1
+	xor	$acc0,$t2
+	xor	$acc1,$t3
+	shr	\$16,$s0
+
+	movzb	`&lo("$s2")`,$acc0
+	movzb	`&lo("$s3")`,$acc1
+	movzb	`&lo("$s0")`,$acc2
+	mov	0($sbox,$acc0,8),$acc0	#$t0
+	mov	0($sbox,$acc1,8),$acc1	#$t1
+	mov	0($sbox,$acc2,8),$acc2	#$t2
+
+	and	\$0x00ff0000,$acc0
+	and	\$0x00ff0000,$acc1
+	and	\$0x00ff0000,$acc2
+
+	xor	$acc0,$t0
+	xor	$acc1,$t1
+	xor	$acc2,$t2
+
+	movzb	`&lo("$s1")`,$acc0
+	movzb	`&hi("$s3")`,$acc1
+	movzb	`&hi("$s0")`,$acc2
+	mov	0($sbox,$acc0,8),$acc0	#$t3
+	mov	2($sbox,$acc1,8),$acc1	#$t0
+	mov	2($sbox,$acc2,8),$acc2	#$t1
+
+	and	\$0x00ff0000,$acc0
+	and	\$0xff000000,$acc1
+	and	\$0xff000000,$acc2
+
+	xor	$acc0,$t3
+	xor	$acc1,$t0
+	xor	$acc2,$t1
+
+	movzb	`&hi("$s1")`,$acc0
+	movzb	`&hi("$s2")`,$acc1
+	mov	16+12($key),$s3
+	mov	2($sbox,$acc0,8),$acc0	#$t2
+	mov	2($sbox,$acc1,8),$acc1	#$t3
+	mov	16+0($key),$s0
+
+	and	\$0xff000000,$acc0
+	and	\$0xff000000,$acc1
+
+	xor	$acc0,$t2
+	xor	$acc1,$t3
+
+	mov	16+4($key),$s1
+	mov	16+8($key),$s2
+	xor	$t0,$s0
+	xor	$t1,$s1
+	xor	$t2,$s2
+	xor	$t3,$s3
+___
+}
+
+sub encstep()
+{ my ($i,@s) = @_;
+  my $tmp0=$acc0;
+  my $tmp1=$acc1;
+  my $tmp2=$acc2;
+  my $out=($t0,$t1,$t2,$s[0])[$i];
+
+	if ($i==3) {
+		$tmp0=$s[1];
+		$tmp1=$s[2];
+		$tmp2=$s[3];
+	}
+	$code.="	movzb	".&lo($s[0]).",$out\n";
+	$code.="	mov	$s[2],$tmp1\n"		if ($i!=3);
+	$code.="	lea	16($key),$key\n"	if ($i==0);
+
+	$code.="	movzb	".&hi($s[1]).",$tmp0\n";
+	$code.="	mov	0($sbox,$out,8),$out\n";
+
+	$code.="	shr	\$16,$tmp1\n";
+	$code.="	mov	$s[3],$tmp2\n"		if ($i!=3);
+	$code.="	xor	3($sbox,$tmp0,8),$out\n";
+
+	$code.="	movzb	".&lo($tmp1).",$tmp1\n";
+	$code.="	shr	\$24,$tmp2\n";
+	$code.="	xor	4*$i($key),$out\n";
+
+	$code.="	xor	2($sbox,$tmp1,8),$out\n";
+	$code.="	xor	1($sbox,$tmp2,8),$out\n";
+
+	$code.="	mov	$t0,$s[1]\n"		if ($i==3);
+	$code.="	mov	$t1,$s[2]\n"		if ($i==3);
+	$code.="	mov	$t2,$s[3]\n"		if ($i==3);
+	$code.="\n";
+}
+
+sub enclast()
+{ my ($i,@s)=@_;
+  my $tmp0=$acc0;
+  my $tmp1=$acc1;
+  my $tmp2=$acc2;
+  my $out=($t0,$t1,$t2,$s[0])[$i];
+
+	if ($i==3) {
+		$tmp0=$s[1];
+		$tmp1=$s[2];
+		$tmp2=$s[3];
+	}
+	$code.="	movzb	".&lo($s[0]).",$out\n";
+	$code.="	mov	$s[2],$tmp1\n"		if ($i!=3);
+
+	$code.="	mov	2($sbox,$out,8),$out\n";
+	$code.="	shr	\$16,$tmp1\n";
+	$code.="	mov	$s[3],$tmp2\n"		if ($i!=3);
+
+	$code.="	and	\$0x000000ff,$out\n";
+	$code.="	movzb	".&hi($s[1]).",$tmp0\n";
+	$code.="	movzb	".&lo($tmp1).",$tmp1\n";
+	$code.="	shr	\$24,$tmp2\n";
+
+	$code.="	mov	0($sbox,$tmp0,8),$tmp0\n";
+	$code.="	mov	0($sbox,$tmp1,8),$tmp1\n";
+	$code.="	mov	2($sbox,$tmp2,8),$tmp2\n";
+
+	$code.="	and	\$0x0000ff00,$tmp0\n";
+	$code.="	and	\$0x00ff0000,$tmp1\n";
+	$code.="	and	\$0xff000000,$tmp2\n";
+
+	$code.="	xor	$tmp0,$out\n";
+	$code.="	mov	$t0,$s[1]\n"		if ($i==3);
+	$code.="	xor	$tmp1,$out\n";
+	$code.="	mov	$t1,$s[2]\n"		if ($i==3);
+	$code.="	xor	$tmp2,$out\n";
+	$code.="	mov	$t2,$s[3]\n"		if ($i==3);
+	$code.="\n";
+}
+
+$code.=<<___;
+.type	_x86_64_AES_encrypt,\@abi-omnipotent
+.align	16
+_x86_64_AES_encrypt:
+	xor	0($key),$s0			# xor with key
+	xor	4($key),$s1
+	xor	8($key),$s2
+	xor	12($key),$s3
+
+	mov	240($key),$rnds			# load key->rounds
+	sub	\$1,$rnds
+	jmp	.Lenc_loop
+.align	16
+.Lenc_loop:
+___
+	if ($verticalspin) { &encvert(); }
+	else {	&encstep(0,$s0,$s1,$s2,$s3);
+		&encstep(1,$s1,$s2,$s3,$s0);
+		&encstep(2,$s2,$s3,$s0,$s1);
+		&encstep(3,$s3,$s0,$s1,$s2);
+	}
+$code.=<<___;
+	sub	\$1,$rnds
+	jnz	.Lenc_loop
+___
+	if ($verticalspin) { &enclastvert(); }
+	else {	&enclast(0,$s0,$s1,$s2,$s3);
+		&enclast(1,$s1,$s2,$s3,$s0);
+		&enclast(2,$s2,$s3,$s0,$s1);
+		&enclast(3,$s3,$s0,$s1,$s2);
+		$code.=<<___;
+		xor	16+0($key),$s0		# xor with key
+		xor	16+4($key),$s1
+		xor	16+8($key),$s2
+		xor	16+12($key),$s3
+___
+	}
+$code.=<<___;
+	.byte	0xf3,0xc3			# rep ret
+.size	_x86_64_AES_encrypt,.-_x86_64_AES_encrypt
+___
+
+# it's possible to implement this by shifting tN by 8, filling least
+# significant byte with byte load and finally bswap-ing at the end,
+# but such partial register load kills Core 2...
+sub enccompactvert()
+{ my ($t3,$t4,$t5)=("%r8d","%r9d","%r13d");
+
+$code.=<<___;
+	movzb	`&lo("$s0")`,$t0
+	movzb	`&lo("$s1")`,$t1
+	movzb	`&lo("$s2")`,$t2
+	movzb	($sbox,$t0,1),$t0
+	movzb	($sbox,$t1,1),$t1
+	movzb	($sbox,$t2,1),$t2
+
+	movzb	`&lo("$s3")`,$t3
+	movzb	`&hi("$s1")`,$acc0
+	movzb	`&hi("$s2")`,$acc1
+	movzb	($sbox,$t3,1),$t3
+	movzb	($sbox,$acc0,1),$t4	#$t0
+	movzb	($sbox,$acc1,1),$t5	#$t1
+
+	movzb	`&hi("$s3")`,$acc2
+	movzb	`&hi("$s0")`,$acc0
+	shr	\$16,$s2
+	movzb	($sbox,$acc2,1),$acc2	#$t2
+	movzb	($sbox,$acc0,1),$acc0	#$t3
+	shr	\$16,$s3
+
+	movzb	`&lo("$s2")`,$acc1
+	shl	\$8,$t4
+	shl	\$8,$t5
+	movzb	($sbox,$acc1,1),$acc1	#$t0
+	xor	$t4,$t0
+	xor	$t5,$t1
+
+	movzb	`&lo("$s3")`,$t4
+	shr	\$16,$s0
+	shr	\$16,$s1
+	movzb	`&lo("$s0")`,$t5
+	shl	\$8,$acc2
+	shl	\$8,$acc0
+	movzb	($sbox,$t4,1),$t4	#$t1
+	movzb	($sbox,$t5,1),$t5	#$t2
+	xor	$acc2,$t2
+	xor	$acc0,$t3
+
+	movzb	`&lo("$s1")`,$acc2
+	movzb	`&hi("$s3")`,$acc0
+	shl	\$16,$acc1
+	movzb	($sbox,$acc2,1),$acc2	#$t3
+	movzb	($sbox,$acc0,1),$acc0	#$t0
+	xor	$acc1,$t0
+
+	movzb	`&hi("$s0")`,$acc1
+	shr	\$8,$s2
+	shr	\$8,$s1
+	movzb	($sbox,$acc1,1),$acc1	#$t1
+	movzb	($sbox,$s2,1),$s3	#$t3
+	movzb	($sbox,$s1,1),$s2	#$t2
+	shl	\$16,$t4
+	shl	\$16,$t5
+	shl	\$16,$acc2
+	xor	$t4,$t1
+	xor	$t5,$t2
+	xor	$acc2,$t3
+
+	shl	\$24,$acc0
+	shl	\$24,$acc1
+	shl	\$24,$s3
+	xor	$acc0,$t0
+	shl	\$24,$s2
+	xor	$acc1,$t1
+	mov	$t0,$s0
+	mov	$t1,$s1
+	xor	$t2,$s2
+	xor	$t3,$s3
+___
+}
+
+sub enctransform_ref()
+{ my $sn = shift;
+  my ($acc,$r2,$tmp)=("%r8d","%r9d","%r13d");
+
+$code.=<<___;
+	mov	$sn,$acc
+	and	\$0x80808080,$acc
+	mov	$acc,$tmp
+	shr	\$7,$tmp
+	lea	($sn,$sn),$r2
+	sub	$tmp,$acc
+	and	\$0xfefefefe,$r2
+	and	\$0x1b1b1b1b,$acc
+	mov	$sn,$tmp
+	xor	$acc,$r2
+
+	xor	$r2,$sn
+	rol	\$24,$sn
+	xor	$r2,$sn
+	ror	\$16,$tmp
+	xor	$tmp,$sn
+	ror	\$8,$tmp
+	xor	$tmp,$sn
+___
+}
+
+# unlike decrypt case it does not pay off to parallelize enctransform
+sub enctransform()
+{ my ($t3,$r20,$r21)=($acc2,"%r8d","%r9d");
+
+$code.=<<___;
+	mov	$s0,$acc0
+	mov	$s1,$acc1
+	and	\$0x80808080,$acc0
+	and	\$0x80808080,$acc1
+	mov	$acc0,$t0
+	mov	$acc1,$t1
+	shr	\$7,$t0
+	lea	($s0,$s0),$r20
+	shr	\$7,$t1
+	lea	($s1,$s1),$r21
+	sub	$t0,$acc0
+	sub	$t1,$acc1
+	and	\$0xfefefefe,$r20
+	and	\$0xfefefefe,$r21
+	and	\$0x1b1b1b1b,$acc0
+	and	\$0x1b1b1b1b,$acc1
+	mov	$s0,$t0
+	mov	$s1,$t1
+	xor	$acc0,$r20
+	xor	$acc1,$r21
+
+	xor	$r20,$s0
+	xor	$r21,$s1
+	 mov	$s2,$acc0
+	 mov	$s3,$acc1
+	rol	\$24,$s0
+	rol	\$24,$s1
+	 and	\$0x80808080,$acc0
+	 and	\$0x80808080,$acc1
+	xor	$r20,$s0
+	xor	$r21,$s1
+	 mov	$acc0,$t2
+	 mov	$acc1,$t3
+	ror	\$16,$t0
+	ror	\$16,$t1
+	 shr	\$7,$t2
+	 lea	($s2,$s2),$r20
+	xor	$t0,$s0
+	xor	$t1,$s1
+	 shr	\$7,$t3
+	 lea	($s3,$s3),$r21
+	ror	\$8,$t0
+	ror	\$8,$t1
+	 sub	$t2,$acc0
+	 sub	$t3,$acc1
+	xor	$t0,$s0
+	xor	$t1,$s1
+
+	and	\$0xfefefefe,$r20
+	and	\$0xfefefefe,$r21
+	and	\$0x1b1b1b1b,$acc0
+	and	\$0x1b1b1b1b,$acc1
+	mov	$s2,$t2
+	mov	$s3,$t3
+	xor	$acc0,$r20
+	xor	$acc1,$r21
+
+	xor	$r20,$s2
+	xor	$r21,$s3
+	rol	\$24,$s2
+	rol	\$24,$s3
+	xor	$r20,$s2
+	xor	$r21,$s3
+	mov	0($sbox),$acc0			# prefetch Te4
+	ror	\$16,$t2
+	ror	\$16,$t3
+	mov	64($sbox),$acc1
+	xor	$t2,$s2
+	xor	$t3,$s3
+	mov	128($sbox),$r20
+	ror	\$8,$t2
+	ror	\$8,$t3
+	mov	192($sbox),$r21
+	xor	$t2,$s2
+	xor	$t3,$s3
+___
+}
+
+$code.=<<___;
+.type	_x86_64_AES_encrypt_compact,\@abi-omnipotent
+.align	16
+_x86_64_AES_encrypt_compact:
+	lea	128($sbox),$inp			# size optimization
+	mov	0-128($inp),$acc1		# prefetch Te4
+	mov	32-128($inp),$acc2
+	mov	64-128($inp),$t0
+	mov	96-128($inp),$t1
+	mov	128-128($inp),$acc1
+	mov	160-128($inp),$acc2
+	mov	192-128($inp),$t0
+	mov	224-128($inp),$t1
+	jmp	.Lenc_loop_compact
+.align	16
+.Lenc_loop_compact:
+		xor	0($key),$s0		# xor with key
+		xor	4($key),$s1
+		xor	8($key),$s2
+		xor	12($key),$s3
+		lea	16($key),$key
+___
+		&enccompactvert();
+$code.=<<___;
+		cmp	16(%rsp),$key
+		je	.Lenc_compact_done
+___
+		&enctransform();
+$code.=<<___;
+	jmp	.Lenc_loop_compact
+.align	16
+.Lenc_compact_done:
+	xor	0($key),$s0
+	xor	4($key),$s1
+	xor	8($key),$s2
+	xor	12($key),$s3
+	.byte	0xf3,0xc3			# rep ret
+.size	_x86_64_AES_encrypt_compact,.-_x86_64_AES_encrypt_compact
+___
+
+# void AES_encrypt (const void *inp,void *out,const AES_KEY *key);
+$code.=<<___;
+.globl	AES_encrypt
+.type	AES_encrypt,\@function,3
+.align	16
+AES_encrypt:
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+
+	# allocate frame "above" key schedule
+	mov	%rsp,%r10
+	lea	-63(%rdx),%rcx	# %rdx is key argument
+	and	\$-64,%rsp
+	sub	%rsp,%rcx
+	neg	%rcx
+	and	\$0x3c0,%rcx
+	sub	%rcx,%rsp
+	sub	\$32,%rsp
+
+	mov	%rsi,16(%rsp)	# save out
+	mov	%r10,24(%rsp)	# save real stack pointer
+.Lenc_prologue:
+
+	mov	%rdx,$key
+	mov	240($key),$rnds	# load rounds
+
+	mov	0(%rdi),$s0	# load input vector
+	mov	4(%rdi),$s1
+	mov	8(%rdi),$s2
+	mov	12(%rdi),$s3
+
+	shl	\$4,$rnds
+	lea	($key,$rnds),%rbp
+	mov	$key,(%rsp)	# key schedule
+	mov	%rbp,8(%rsp)	# end of key schedule
+
+	# pick Te4 copy which can't "overlap" with stack frame or key schedule
+	lea	.LAES_Te+2048(%rip),$sbox
+	lea	768(%rsp),%rbp
+	sub	$sbox,%rbp
+	and	\$0x300,%rbp
+	lea	($sbox,%rbp),$sbox
+
+	call	_x86_64_AES_encrypt_compact
+
+	mov	16(%rsp),$out	# restore out
+	mov	24(%rsp),%rsi	# restore saved stack pointer
+	mov	$s0,0($out)	# write output vector
+	mov	$s1,4($out)
+	mov	$s2,8($out)
+	mov	$s3,12($out)
+
+	mov	(%rsi),%r15
+	mov	8(%rsi),%r14
+	mov	16(%rsi),%r13
+	mov	24(%rsi),%r12
+	mov	32(%rsi),%rbp
+	mov	40(%rsi),%rbx
+	lea	48(%rsi),%rsp
+.Lenc_epilogue:
+	ret
+.size	AES_encrypt,.-AES_encrypt
+___
+
+#------------------------------------------------------------------#
+
+sub decvert()
+{ my $t3="%r8d";	# zaps $inp!
+
+$code.=<<___;
+	# favor 3-way issue Opteron pipeline...
+	movzb	`&lo("$s0")`,$acc0
+	movzb	`&lo("$s1")`,$acc1
+	movzb	`&lo("$s2")`,$acc2
+	mov	0($sbox,$acc0,8),$t0
+	mov	0($sbox,$acc1,8),$t1
+	mov	0($sbox,$acc2,8),$t2
+
+	movzb	`&hi("$s3")`,$acc0
+	movzb	`&hi("$s0")`,$acc1
+	movzb	`&lo("$s3")`,$acc2
+	xor	3($sbox,$acc0,8),$t0
+	xor	3($sbox,$acc1,8),$t1
+	mov	0($sbox,$acc2,8),$t3
+
+	movzb	`&hi("$s1")`,$acc0
+	shr	\$16,$s0
+	movzb	`&hi("$s2")`,$acc2
+	xor	3($sbox,$acc0,8),$t2
+	shr	\$16,$s3
+	xor	3($sbox,$acc2,8),$t3
+
+	shr	\$16,$s1
+	lea	16($key),$key
+	shr	\$16,$s2
+
+	movzb	`&lo("$s2")`,$acc0
+	movzb	`&lo("$s3")`,$acc1
+	movzb	`&lo("$s0")`,$acc2
+	xor	2($sbox,$acc0,8),$t0
+	xor	2($sbox,$acc1,8),$t1
+	xor	2($sbox,$acc2,8),$t2
+
+	movzb	`&hi("$s1")`,$acc0
+	movzb	`&hi("$s2")`,$acc1
+	movzb	`&lo("$s1")`,$acc2
+	xor	1($sbox,$acc0,8),$t0
+	xor	1($sbox,$acc1,8),$t1
+	xor	2($sbox,$acc2,8),$t3
+
+	movzb	`&hi("$s3")`,$acc0
+	mov	12($key),$s3
+	movzb	`&hi("$s0")`,$acc2
+	xor	1($sbox,$acc0,8),$t2
+	mov	0($key),$s0
+	xor	1($sbox,$acc2,8),$t3
+
+	xor	$t0,$s0
+	mov	4($key),$s1
+	mov	8($key),$s2
+	xor	$t2,$s2
+	xor	$t1,$s1
+	xor	$t3,$s3
+___
+}
+
+sub declastvert()
+{ my $t3="%r8d";	# zaps $inp!
+
+$code.=<<___;
+	lea	2048($sbox),$sbox	# size optimization
+	movzb	`&lo("$s0")`,$acc0
+	movzb	`&lo("$s1")`,$acc1
+	movzb	`&lo("$s2")`,$acc2
+	movzb	($sbox,$acc0,1),$t0
+	movzb	($sbox,$acc1,1),$t1
+	movzb	($sbox,$acc2,1),$t2
+
+	movzb	`&lo("$s3")`,$acc0
+	movzb	`&hi("$s3")`,$acc1
+	movzb	`&hi("$s0")`,$acc2
+	movzb	($sbox,$acc0,1),$t3
+	movzb	($sbox,$acc1,1),$acc1	#$t0
+	movzb	($sbox,$acc2,1),$acc2	#$t1
+
+	shl	\$8,$acc1
+	shl	\$8,$acc2
+
+	xor	$acc1,$t0
+	xor	$acc2,$t1
+	shr	\$16,$s3
+
+	movzb	`&hi("$s1")`,$acc0
+	movzb	`&hi("$s2")`,$acc1
+	shr	\$16,$s0
+	movzb	($sbox,$acc0,1),$acc0	#$t2
+	movzb	($sbox,$acc1,1),$acc1	#$t3
+
+	shl	\$8,$acc0
+	shl	\$8,$acc1
+	shr	\$16,$s1
+	xor	$acc0,$t2
+	xor	$acc1,$t3
+	shr	\$16,$s2
+
+	movzb	`&lo("$s2")`,$acc0
+	movzb	`&lo("$s3")`,$acc1
+	movzb	`&lo("$s0")`,$acc2
+	movzb	($sbox,$acc0,1),$acc0	#$t0
+	movzb	($sbox,$acc1,1),$acc1	#$t1
+	movzb	($sbox,$acc2,1),$acc2	#$t2
+
+	shl	\$16,$acc0
+	shl	\$16,$acc1
+	shl	\$16,$acc2
+
+	xor	$acc0,$t0
+	xor	$acc1,$t1
+	xor	$acc2,$t2
+
+	movzb	`&lo("$s1")`,$acc0
+	movzb	`&hi("$s1")`,$acc1
+	movzb	`&hi("$s2")`,$acc2
+	movzb	($sbox,$acc0,1),$acc0	#$t3
+	movzb	($sbox,$acc1,1),$acc1	#$t0
+	movzb	($sbox,$acc2,1),$acc2	#$t1
+
+	shl	\$16,$acc0
+	shl	\$24,$acc1
+	shl	\$24,$acc2
+
+	xor	$acc0,$t3
+	xor	$acc1,$t0
+	xor	$acc2,$t1
+
+	movzb	`&hi("$s3")`,$acc0
+	movzb	`&hi("$s0")`,$acc1
+	mov	16+12($key),$s3
+	movzb	($sbox,$acc0,1),$acc0	#$t2
+	movzb	($sbox,$acc1,1),$acc1	#$t3
+	mov	16+0($key),$s0
+
+	shl	\$24,$acc0
+	shl	\$24,$acc1
+
+	xor	$acc0,$t2
+	xor	$acc1,$t3
+
+	mov	16+4($key),$s1
+	mov	16+8($key),$s2
+	lea	-2048($sbox),$sbox
+	xor	$t0,$s0
+	xor	$t1,$s1
+	xor	$t2,$s2
+	xor	$t3,$s3
+___
+}
+
+sub decstep()
+{ my ($i,@s) = @_;
+  my $tmp0=$acc0;
+  my $tmp1=$acc1;
+  my $tmp2=$acc2;
+  my $out=($t0,$t1,$t2,$s[0])[$i];
+
+	$code.="	mov	$s[0],$out\n"		if ($i!=3);
+			$tmp1=$s[2]			if ($i==3);
+	$code.="	mov	$s[2],$tmp1\n"		if ($i!=3);
+	$code.="	and	\$0xFF,$out\n";
+
+	$code.="	mov	0($sbox,$out,8),$out\n";
+	$code.="	shr	\$16,$tmp1\n";
+			$tmp2=$s[3]			if ($i==3);
+	$code.="	mov	$s[3],$tmp2\n"		if ($i!=3);
+
+			$tmp0=$s[1]			if ($i==3);
+	$code.="	movzb	".&hi($s[1]).",$tmp0\n";
+	$code.="	and	\$0xFF,$tmp1\n";
+	$code.="	shr	\$24,$tmp2\n";
+
+	$code.="	xor	3($sbox,$tmp0,8),$out\n";
+	$code.="	xor	2($sbox,$tmp1,8),$out\n";
+	$code.="	xor	1($sbox,$tmp2,8),$out\n";
+
+	$code.="	mov	$t2,$s[1]\n"		if ($i==3);
+	$code.="	mov	$t1,$s[2]\n"		if ($i==3);
+	$code.="	mov	$t0,$s[3]\n"		if ($i==3);
+	$code.="\n";
+}
+
+sub declast()
+{ my ($i,@s)=@_;
+  my $tmp0=$acc0;
+  my $tmp1=$acc1;
+  my $tmp2=$acc2;
+  my $out=($t0,$t1,$t2,$s[0])[$i];
+
+	$code.="	mov	$s[0],$out\n"		if ($i!=3);
+			$tmp1=$s[2]			if ($i==3);
+	$code.="	mov	$s[2],$tmp1\n"		if ($i!=3);
+	$code.="	and	\$0xFF,$out\n";
+
+	$code.="	movzb	2048($sbox,$out,1),$out\n";
+	$code.="	shr	\$16,$tmp1\n";
+			$tmp2=$s[3]			if ($i==3);
+	$code.="	mov	$s[3],$tmp2\n"		if ($i!=3);
+
+			$tmp0=$s[1]			if ($i==3);
+	$code.="	movzb	".&hi($s[1]).",$tmp0\n";
+	$code.="	and	\$0xFF,$tmp1\n";
+	$code.="	shr	\$24,$tmp2\n";
+
+	$code.="	movzb	2048($sbox,$tmp0,1),$tmp0\n";
+	$code.="	movzb	2048($sbox,$tmp1,1),$tmp1\n";
+	$code.="	movzb	2048($sbox,$tmp2,1),$tmp2\n";
+
+	$code.="	shl	\$8,$tmp0\n";
+	$code.="	shl	\$16,$tmp1\n";
+	$code.="	shl	\$24,$tmp2\n";
+
+	$code.="	xor	$tmp0,$out\n";
+	$code.="	mov	$t2,$s[1]\n"		if ($i==3);
+	$code.="	xor	$tmp1,$out\n";
+	$code.="	mov	$t1,$s[2]\n"		if ($i==3);
+	$code.="	xor	$tmp2,$out\n";
+	$code.="	mov	$t0,$s[3]\n"		if ($i==3);
+	$code.="\n";
+}
+
+$code.=<<___;
+.type	_x86_64_AES_decrypt,\@abi-omnipotent
+.align	16
+_x86_64_AES_decrypt:
+	xor	0($key),$s0			# xor with key
+	xor	4($key),$s1
+	xor	8($key),$s2
+	xor	12($key),$s3
+
+	mov	240($key),$rnds			# load key->rounds
+	sub	\$1,$rnds
+	jmp	.Ldec_loop
+.align	16
+.Ldec_loop:
+___
+	if ($verticalspin) { &decvert(); }
+	else {	&decstep(0,$s0,$s3,$s2,$s1);
+		&decstep(1,$s1,$s0,$s3,$s2);
+		&decstep(2,$s2,$s1,$s0,$s3);
+		&decstep(3,$s3,$s2,$s1,$s0);
+		$code.=<<___;
+		lea	16($key),$key
+		xor	0($key),$s0			# xor with key
+		xor	4($key),$s1
+		xor	8($key),$s2
+		xor	12($key),$s3
+___
+	}
+$code.=<<___;
+	sub	\$1,$rnds
+	jnz	.Ldec_loop
+___
+	if ($verticalspin) { &declastvert(); }
+	else {	&declast(0,$s0,$s3,$s2,$s1);
+		&declast(1,$s1,$s0,$s3,$s2);
+		&declast(2,$s2,$s1,$s0,$s3);
+		&declast(3,$s3,$s2,$s1,$s0);
+		$code.=<<___;
+		xor	16+0($key),$s0			# xor with key
+		xor	16+4($key),$s1
+		xor	16+8($key),$s2
+		xor	16+12($key),$s3
+___
+	}
+$code.=<<___;
+	.byte	0xf3,0xc3			# rep ret
+.size	_x86_64_AES_decrypt,.-_x86_64_AES_decrypt
+___
+
+sub deccompactvert()
+{ my ($t3,$t4,$t5)=("%r8d","%r9d","%r13d");
+
+$code.=<<___;
+	movzb	`&lo("$s0")`,$t0
+	movzb	`&lo("$s1")`,$t1
+	movzb	`&lo("$s2")`,$t2
+	movzb	($sbox,$t0,1),$t0
+	movzb	($sbox,$t1,1),$t1
+	movzb	($sbox,$t2,1),$t2
+
+	movzb	`&lo("$s3")`,$t3
+	movzb	`&hi("$s3")`,$acc0
+	movzb	`&hi("$s0")`,$acc1
+	movzb	($sbox,$t3,1),$t3
+	movzb	($sbox,$acc0,1),$t4	#$t0
+	movzb	($sbox,$acc1,1),$t5	#$t1
+
+	movzb	`&hi("$s1")`,$acc2
+	movzb	`&hi("$s2")`,$acc0
+	shr	\$16,$s2
+	movzb	($sbox,$acc2,1),$acc2	#$t2
+	movzb	($sbox,$acc0,1),$acc0	#$t3
+	shr	\$16,$s3
+
+	movzb	`&lo("$s2")`,$acc1
+	shl	\$8,$t4
+	shl	\$8,$t5
+	movzb	($sbox,$acc1,1),$acc1	#$t0
+	xor	$t4,$t0
+	xor	$t5,$t1
+
+	movzb	`&lo("$s3")`,$t4
+	shr	\$16,$s0
+	shr	\$16,$s1
+	movzb	`&lo("$s0")`,$t5
+	shl	\$8,$acc2
+	shl	\$8,$acc0
+	movzb	($sbox,$t4,1),$t4	#$t1
+	movzb	($sbox,$t5,1),$t5	#$t2
+	xor	$acc2,$t2
+	xor	$acc0,$t3
+
+	movzb	`&lo("$s1")`,$acc2
+	movzb	`&hi("$s1")`,$acc0
+	shl	\$16,$acc1
+	movzb	($sbox,$acc2,1),$acc2	#$t3
+	movzb	($sbox,$acc0,1),$acc0	#$t0
+	xor	$acc1,$t0
+
+	movzb	`&hi("$s2")`,$acc1
+	shl	\$16,$t4
+	shl	\$16,$t5
+	movzb	($sbox,$acc1,1),$s1	#$t1
+	xor	$t4,$t1
+	xor	$t5,$t2
+
+	movzb	`&hi("$s3")`,$acc1
+	shr	\$8,$s0
+	shl	\$16,$acc2
+	movzb	($sbox,$acc1,1),$s2	#$t2
+	movzb	($sbox,$s0,1),$s3	#$t3
+	xor	$acc2,$t3
+
+	shl	\$24,$acc0
+	shl	\$24,$s1
+	shl	\$24,$s2
+	xor	$acc0,$t0
+	shl	\$24,$s3
+	xor	$t1,$s1
+	mov	$t0,$s0
+	xor	$t2,$s2
+	xor	$t3,$s3
+___
+}
+
+# parallelized version! input is pair of 64-bit values: %rax=s1.s0
+# and %rcx=s3.s2, output is four 32-bit values in %eax=s0, %ebx=s1,
+# %ecx=s2 and %edx=s3.
+sub dectransform()
+{ my ($tp10,$tp20,$tp40,$tp80,$acc0)=("%rax","%r8", "%r9", "%r10","%rbx");
+  my ($tp18,$tp28,$tp48,$tp88,$acc8)=("%rcx","%r11","%r12","%r13","%rdx");
+  my $prefetch = shift;
+
+$code.=<<___;
+	mov	$tp10,$acc0
+	mov	$tp18,$acc8
+	and	$mask80,$acc0
+	and	$mask80,$acc8
+	mov	$acc0,$tp40
+	mov	$acc8,$tp48
+	shr	\$7,$tp40
+	lea	($tp10,$tp10),$tp20
+	shr	\$7,$tp48
+	lea	($tp18,$tp18),$tp28
+	sub	$tp40,$acc0
+	sub	$tp48,$acc8
+	and	$maskfe,$tp20
+	and	$maskfe,$tp28
+	and	$mask1b,$acc0
+	and	$mask1b,$acc8
+	xor	$tp20,$acc0
+	xor	$tp28,$acc8
+	mov	$acc0,$tp20
+	mov	$acc8,$tp28
+
+	and	$mask80,$acc0
+	and	$mask80,$acc8
+	mov	$acc0,$tp80
+	mov	$acc8,$tp88
+	shr	\$7,$tp80
+	lea	($tp20,$tp20),$tp40
+	shr	\$7,$tp88
+	lea	($tp28,$tp28),$tp48
+	sub	$tp80,$acc0
+	sub	$tp88,$acc8
+	and	$maskfe,$tp40
+	and	$maskfe,$tp48
+	and	$mask1b,$acc0
+	and	$mask1b,$acc8
+	xor	$tp40,$acc0
+	xor	$tp48,$acc8
+	mov	$acc0,$tp40
+	mov	$acc8,$tp48
+
+	and	$mask80,$acc0
+	and	$mask80,$acc8
+	mov	$acc0,$tp80
+	mov	$acc8,$tp88
+	shr	\$7,$tp80
+	 xor	$tp10,$tp20		# tp2^=tp1
+	shr	\$7,$tp88
+	 xor	$tp18,$tp28		# tp2^=tp1
+	sub	$tp80,$acc0
+	sub	$tp88,$acc8
+	lea	($tp40,$tp40),$tp80
+	lea	($tp48,$tp48),$tp88
+	 xor	$tp10,$tp40		# tp4^=tp1
+	 xor	$tp18,$tp48		# tp4^=tp1
+	and	$maskfe,$tp80
+	and	$maskfe,$tp88
+	and	$mask1b,$acc0
+	and	$mask1b,$acc8
+	xor	$acc0,$tp80
+	xor	$acc8,$tp88
+
+	xor	$tp80,$tp10		# tp1^=tp8
+	xor	$tp88,$tp18		# tp1^=tp8
+	xor	$tp80,$tp20		# tp2^tp1^=tp8
+	xor	$tp88,$tp28		# tp2^tp1^=tp8
+	mov	$tp10,$acc0
+	mov	$tp18,$acc8
+	xor	$tp80,$tp40		# tp4^tp1^=tp8
+	xor	$tp88,$tp48		# tp4^tp1^=tp8
+	shr	\$32,$acc0
+	shr	\$32,$acc8
+	xor	$tp20,$tp80		# tp8^=tp8^tp2^tp1=tp2^tp1
+	xor	$tp28,$tp88		# tp8^=tp8^tp2^tp1=tp2^tp1
+	rol	\$8,`&LO("$tp10")`	# ROTATE(tp1^tp8,8)
+	rol	\$8,`&LO("$tp18")`	# ROTATE(tp1^tp8,8)
+	xor	$tp40,$tp80		# tp2^tp1^=tp8^tp4^tp1=tp8^tp4^tp2
+	xor	$tp48,$tp88		# tp2^tp1^=tp8^tp4^tp1=tp8^tp4^tp2
+
+	rol	\$8,`&LO("$acc0")`	# ROTATE(tp1^tp8,8)
+	rol	\$8,`&LO("$acc8")`	# ROTATE(tp1^tp8,8)
+	xor	`&LO("$tp80")`,`&LO("$tp10")`
+	xor	`&LO("$tp88")`,`&LO("$tp18")`
+	shr	\$32,$tp80
+	shr	\$32,$tp88
+	xor	`&LO("$tp80")`,`&LO("$acc0")`
+	xor	`&LO("$tp88")`,`&LO("$acc8")`
+
+	mov	$tp20,$tp80
+	mov	$tp28,$tp88
+	shr	\$32,$tp80
+	shr	\$32,$tp88
+	rol	\$24,`&LO("$tp20")`	# ROTATE(tp2^tp1^tp8,24)
+	rol	\$24,`&LO("$tp28")`	# ROTATE(tp2^tp1^tp8,24)
+	rol	\$24,`&LO("$tp80")`	# ROTATE(tp2^tp1^tp8,24)
+	rol	\$24,`&LO("$tp88")`	# ROTATE(tp2^tp1^tp8,24)
+	xor	`&LO("$tp20")`,`&LO("$tp10")`
+	xor	`&LO("$tp28")`,`&LO("$tp18")`
+	mov	$tp40,$tp20
+	mov	$tp48,$tp28
+	xor	`&LO("$tp80")`,`&LO("$acc0")`
+	xor	`&LO("$tp88")`,`&LO("$acc8")`
+
+	`"mov	0($sbox),$mask80"	if ($prefetch)`
+	shr	\$32,$tp20
+	shr	\$32,$tp28
+	`"mov	64($sbox),$maskfe"	if ($prefetch)`
+	rol	\$16,`&LO("$tp40")`	# ROTATE(tp4^tp1^tp8,16)
+	rol	\$16,`&LO("$tp48")`	# ROTATE(tp4^tp1^tp8,16)
+	`"mov	128($sbox),$mask1b"	if ($prefetch)`
+	rol	\$16,`&LO("$tp20")`	# ROTATE(tp4^tp1^tp8,16)
+	rol	\$16,`&LO("$tp28")`	# ROTATE(tp4^tp1^tp8,16)
+	`"mov	192($sbox),$tp80"	if ($prefetch)`
+	xor	`&LO("$tp40")`,`&LO("$tp10")`
+	xor	`&LO("$tp48")`,`&LO("$tp18")`
+	`"mov	256($sbox),$tp88"	if ($prefetch)`
+	xor	`&LO("$tp20")`,`&LO("$acc0")`
+	xor	`&LO("$tp28")`,`&LO("$acc8")`
+___
+}
+
+$code.=<<___;
+.type	_x86_64_AES_decrypt_compact,\@abi-omnipotent
+.align	16
+_x86_64_AES_decrypt_compact:
+	lea	128($sbox),$inp			# size optimization
+	mov	0-128($inp),$acc1		# prefetch Td4
+	mov	32-128($inp),$acc2
+	mov	64-128($inp),$t0
+	mov	96-128($inp),$t1
+	mov	128-128($inp),$acc1
+	mov	160-128($inp),$acc2
+	mov	192-128($inp),$t0
+	mov	224-128($inp),$t1
+	jmp	.Ldec_loop_compact
+
+.align	16
+.Ldec_loop_compact:
+		xor	0($key),$s0		# xor with key
+		xor	4($key),$s1
+		xor	8($key),$s2
+		xor	12($key),$s3
+		lea	16($key),$key
+___
+		&deccompactvert();
+$code.=<<___;
+		cmp	16(%rsp),$key
+		je	.Ldec_compact_done
+
+		mov	256+0($sbox),$mask80
+		shl	\$32,%rbx
+		shl	\$32,%rdx
+		mov	256+8($sbox),$maskfe
+		or	%rbx,%rax
+		or	%rdx,%rcx
+		mov	256+16($sbox),$mask1b
+___
+		&dectransform(1);
+$code.=<<___;
+	jmp	.Ldec_loop_compact
+.align	16
+.Ldec_compact_done:
+	xor	0($key),$s0
+	xor	4($key),$s1
+	xor	8($key),$s2
+	xor	12($key),$s3
+	.byte	0xf3,0xc3			# rep ret
+.size	_x86_64_AES_decrypt_compact,.-_x86_64_AES_decrypt_compact
+___
+
+# void AES_decrypt (const void *inp,void *out,const AES_KEY *key);
+$code.=<<___;
+.globl	AES_decrypt
+.type	AES_decrypt,\@function,3
+.align	16
+AES_decrypt:
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+
+	# allocate frame "above" key schedule
+	mov	%rsp,%r10
+	lea	-63(%rdx),%rcx	# %rdx is key argument
+	and	\$-64,%rsp
+	sub	%rsp,%rcx
+	neg	%rcx
+	and	\$0x3c0,%rcx
+	sub	%rcx,%rsp
+	sub	\$32,%rsp
+
+	mov	%rsi,16(%rsp)	# save out
+	mov	%r10,24(%rsp)	# save real stack pointer
+.Ldec_prologue:
+
+	mov	%rdx,$key
+	mov	240($key),$rnds	# load rounds
+
+	mov	0(%rdi),$s0	# load input vector
+	mov	4(%rdi),$s1
+	mov	8(%rdi),$s2
+	mov	12(%rdi),$s3
+
+	shl	\$4,$rnds
+	lea	($key,$rnds),%rbp
+	mov	$key,(%rsp)	# key schedule
+	mov	%rbp,8(%rsp)	# end of key schedule
+
+	# pick Td4 copy which can't "overlap" with stack frame or key schedule
+	lea	.LAES_Td+2048(%rip),$sbox
+	lea	768(%rsp),%rbp
+	sub	$sbox,%rbp
+	and	\$0x300,%rbp
+	lea	($sbox,%rbp),$sbox
+	shr	\$3,%rbp	# recall "magic" constants!
+	add	%rbp,$sbox
+
+	call	_x86_64_AES_decrypt_compact
+
+	mov	16(%rsp),$out	# restore out
+	mov	24(%rsp),%rsi	# restore saved stack pointer
+	mov	$s0,0($out)	# write output vector
+	mov	$s1,4($out)
+	mov	$s2,8($out)
+	mov	$s3,12($out)
+
+	mov	(%rsi),%r15
+	mov	8(%rsi),%r14
+	mov	16(%rsi),%r13
+	mov	24(%rsi),%r12
+	mov	32(%rsi),%rbp
+	mov	40(%rsi),%rbx
+	lea	48(%rsi),%rsp
+.Ldec_epilogue:
+	ret
+.size	AES_decrypt,.-AES_decrypt
+___
+#------------------------------------------------------------------#
+
+sub enckey()
+{
+$code.=<<___;
+	movz	%dl,%esi		# rk[i]>>0
+	movzb	-128(%rbp,%rsi),%ebx
+	movz	%dh,%esi		# rk[i]>>8
+	shl	\$24,%ebx
+	xor	%ebx,%eax
+
+	movzb	-128(%rbp,%rsi),%ebx
+	shr	\$16,%edx
+	movz	%dl,%esi		# rk[i]>>16
+	xor	%ebx,%eax
+
+	movzb	-128(%rbp,%rsi),%ebx
+	movz	%dh,%esi		# rk[i]>>24
+	shl	\$8,%ebx
+	xor	%ebx,%eax
+
+	movzb	-128(%rbp,%rsi),%ebx
+	shl	\$16,%ebx
+	xor	%ebx,%eax
+
+	xor	1024-128(%rbp,%rcx,4),%eax		# rcon
+___
+}
+
+# int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+#                        AES_KEY *key)
+$code.=<<___;
+.globl	AES_set_encrypt_key
+.type	AES_set_encrypt_key,\@function,3
+.align	16
+AES_set_encrypt_key:
+	push	%rbx
+	push	%rbp
+	push	%r12			# redundant, but allows to share 
+	push	%r13			# exception handler...
+	push	%r14
+	push	%r15
+	sub	\$8,%rsp
+.Lenc_key_prologue:
+
+	call	_x86_64_AES_set_encrypt_key
+
+	mov	8(%rsp),%r15
+	mov	16(%rsp),%r14
+	mov	24(%rsp),%r13
+	mov	32(%rsp),%r12
+	mov	40(%rsp),%rbp
+	mov	48(%rsp),%rbx
+	add	\$56,%rsp
+.Lenc_key_epilogue:
+	ret
+.size	AES_set_encrypt_key,.-AES_set_encrypt_key
+
+.type	_x86_64_AES_set_encrypt_key,\@abi-omnipotent
+.align	16
+_x86_64_AES_set_encrypt_key:
+	mov	%esi,%ecx			# %ecx=bits
+	mov	%rdi,%rsi			# %rsi=userKey
+	mov	%rdx,%rdi			# %rdi=key
+
+	test	\$-1,%rsi
+	jz	.Lbadpointer
+	test	\$-1,%rdi
+	jz	.Lbadpointer
+
+	lea	.LAES_Te(%rip),%rbp
+	lea	2048+128(%rbp),%rbp
+
+	# prefetch Te4
+	mov	0-128(%rbp),%eax
+	mov	32-128(%rbp),%ebx
+	mov	64-128(%rbp),%r8d
+	mov	96-128(%rbp),%edx
+	mov	128-128(%rbp),%eax
+	mov	160-128(%rbp),%ebx
+	mov	192-128(%rbp),%r8d
+	mov	224-128(%rbp),%edx
+
+	cmp	\$128,%ecx
+	je	.L10rounds
+	cmp	\$192,%ecx
+	je	.L12rounds
+	cmp	\$256,%ecx
+	je	.L14rounds
+	mov	\$-2,%rax			# invalid number of bits
+	jmp	.Lexit
+
+.L10rounds:
+	mov	0(%rsi),%rax			# copy first 4 dwords
+	mov	8(%rsi),%rdx
+	mov	%rax,0(%rdi)
+	mov	%rdx,8(%rdi)
+
+	shr	\$32,%rdx
+	xor	%ecx,%ecx
+	jmp	.L10shortcut
+.align	4
+.L10loop:
+		mov	0(%rdi),%eax			# rk[0]
+		mov	12(%rdi),%edx			# rk[3]
+.L10shortcut:
+___
+		&enckey	();
+$code.=<<___;
+		mov	%eax,16(%rdi)			# rk[4]
+		xor	4(%rdi),%eax
+		mov	%eax,20(%rdi)			# rk[5]
+		xor	8(%rdi),%eax
+		mov	%eax,24(%rdi)			# rk[6]
+		xor	12(%rdi),%eax
+		mov	%eax,28(%rdi)			# rk[7]
+		add	\$1,%ecx
+		lea	16(%rdi),%rdi
+		cmp	\$10,%ecx
+	jl	.L10loop
+
+	movl	\$10,80(%rdi)			# setup number of rounds
+	xor	%rax,%rax
+	jmp	.Lexit
+
+.L12rounds:
+	mov	0(%rsi),%rax			# copy first 6 dwords
+	mov	8(%rsi),%rbx
+	mov	16(%rsi),%rdx
+	mov	%rax,0(%rdi)
+	mov	%rbx,8(%rdi)
+	mov	%rdx,16(%rdi)
+
+	shr	\$32,%rdx
+	xor	%ecx,%ecx
+	jmp	.L12shortcut
+.align	4
+.L12loop:
+		mov	0(%rdi),%eax			# rk[0]
+		mov	20(%rdi),%edx			# rk[5]
+.L12shortcut:
+___
+		&enckey	();
+$code.=<<___;
+		mov	%eax,24(%rdi)			# rk[6]
+		xor	4(%rdi),%eax
+		mov	%eax,28(%rdi)			# rk[7]
+		xor	8(%rdi),%eax
+		mov	%eax,32(%rdi)			# rk[8]
+		xor	12(%rdi),%eax
+		mov	%eax,36(%rdi)			# rk[9]
+
+		cmp	\$7,%ecx
+		je	.L12break
+		add	\$1,%ecx
+
+		xor	16(%rdi),%eax
+		mov	%eax,40(%rdi)			# rk[10]
+		xor	20(%rdi),%eax
+		mov	%eax,44(%rdi)			# rk[11]
+
+		lea	24(%rdi),%rdi
+	jmp	.L12loop
+.L12break:
+	movl	\$12,72(%rdi)		# setup number of rounds
+	xor	%rax,%rax
+	jmp	.Lexit
+
+.L14rounds:		
+	mov	0(%rsi),%rax			# copy first 8 dwords
+	mov	8(%rsi),%rbx
+	mov	16(%rsi),%rcx
+	mov	24(%rsi),%rdx
+	mov	%rax,0(%rdi)
+	mov	%rbx,8(%rdi)
+	mov	%rcx,16(%rdi)
+	mov	%rdx,24(%rdi)
+
+	shr	\$32,%rdx
+	xor	%ecx,%ecx
+	jmp	.L14shortcut
+.align	4
+.L14loop:
+		mov	0(%rdi),%eax			# rk[0]
+		mov	28(%rdi),%edx			# rk[4]
+.L14shortcut:
+___
+		&enckey	();
+$code.=<<___;
+		mov	%eax,32(%rdi)			# rk[8]
+		xor	4(%rdi),%eax
+		mov	%eax,36(%rdi)			# rk[9]
+		xor	8(%rdi),%eax
+		mov	%eax,40(%rdi)			# rk[10]
+		xor	12(%rdi),%eax
+		mov	%eax,44(%rdi)			# rk[11]
+
+		cmp	\$6,%ecx
+		je	.L14break
+		add	\$1,%ecx
+
+		mov	%eax,%edx
+		mov	16(%rdi),%eax			# rk[4]
+		movz	%dl,%esi			# rk[11]>>0
+		movzb	-128(%rbp,%rsi),%ebx
+		movz	%dh,%esi			# rk[11]>>8
+		xor	%ebx,%eax
+
+		movzb	-128(%rbp,%rsi),%ebx
+		shr	\$16,%edx
+		shl	\$8,%ebx
+		movz	%dl,%esi			# rk[11]>>16
+		xor	%ebx,%eax
+
+		movzb	-128(%rbp,%rsi),%ebx
+		movz	%dh,%esi			# rk[11]>>24
+		shl	\$16,%ebx
+		xor	%ebx,%eax
+
+		movzb	-128(%rbp,%rsi),%ebx
+		shl	\$24,%ebx
+		xor	%ebx,%eax
+
+		mov	%eax,48(%rdi)			# rk[12]
+		xor	20(%rdi),%eax
+		mov	%eax,52(%rdi)			# rk[13]
+		xor	24(%rdi),%eax
+		mov	%eax,56(%rdi)			# rk[14]
+		xor	28(%rdi),%eax
+		mov	%eax,60(%rdi)			# rk[15]
+
+		lea	32(%rdi),%rdi
+	jmp	.L14loop
+.L14break:
+	movl	\$14,48(%rdi)		# setup number of rounds
+	xor	%rax,%rax
+	jmp	.Lexit
+
+.Lbadpointer:
+	mov	\$-1,%rax
+.Lexit:
+	.byte	0xf3,0xc3			# rep ret
+.size	_x86_64_AES_set_encrypt_key,.-_x86_64_AES_set_encrypt_key
+___
+
+sub deckey_ref()
+{ my ($i,$ptr,$te,$td) = @_;
+  my ($tp1,$tp2,$tp4,$tp8,$acc)=("%eax","%ebx","%edi","%edx","%r8d");
+$code.=<<___;
+	mov	$i($ptr),$tp1
+	mov	$tp1,$acc
+	and	\$0x80808080,$acc
+	mov	$acc,$tp4
+	shr	\$7,$tp4
+	lea	0($tp1,$tp1),$tp2
+	sub	$tp4,$acc
+	and	\$0xfefefefe,$tp2
+	and	\$0x1b1b1b1b,$acc
+	xor	$tp2,$acc
+	mov	$acc,$tp2
+
+	and	\$0x80808080,$acc
+	mov	$acc,$tp8
+	shr	\$7,$tp8
+	lea	0($tp2,$tp2),$tp4
+	sub	$tp8,$acc
+	and	\$0xfefefefe,$tp4
+	and	\$0x1b1b1b1b,$acc
+	 xor	$tp1,$tp2		# tp2^tp1
+	xor	$tp4,$acc
+	mov	$acc,$tp4
+
+	and	\$0x80808080,$acc
+	mov	$acc,$tp8
+	shr	\$7,$tp8
+	sub	$tp8,$acc
+	lea	0($tp4,$tp4),$tp8
+	 xor	$tp1,$tp4		# tp4^tp1
+	and	\$0xfefefefe,$tp8
+	and	\$0x1b1b1b1b,$acc
+	xor	$acc,$tp8
+
+	xor	$tp8,$tp1		# tp1^tp8
+	rol	\$8,$tp1		# ROTATE(tp1^tp8,8)
+	xor	$tp8,$tp2		# tp2^tp1^tp8
+	xor	$tp8,$tp4		# tp4^tp1^tp8
+	xor	$tp2,$tp8
+	xor	$tp4,$tp8		# tp8^(tp8^tp4^tp1)^(tp8^tp2^tp1)=tp8^tp4^tp2
+
+	xor	$tp8,$tp1
+	rol	\$24,$tp2		# ROTATE(tp2^tp1^tp8,24)
+	xor	$tp2,$tp1
+	rol	\$16,$tp4		# ROTATE(tp4^tp1^tp8,16)
+	xor	$tp4,$tp1
+
+	mov	$tp1,$i($ptr)
+___
+}
+
+# int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+#                        AES_KEY *key)
+$code.=<<___;
+.globl	AES_set_decrypt_key
+.type	AES_set_decrypt_key,\@function,3
+.align	16
+AES_set_decrypt_key:
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	push	%rdx			# save key schedule
+.Ldec_key_prologue:
+
+	call	_x86_64_AES_set_encrypt_key
+	mov	(%rsp),%r8		# restore key schedule
+	cmp	\$0,%eax
+	jne	.Labort
+
+	mov	240(%r8),%r14d		# pull number of rounds
+	xor	%rdi,%rdi
+	lea	(%rdi,%r14d,4),%rcx
+	mov	%r8,%rsi
+	lea	(%r8,%rcx,4),%rdi	# pointer to last chunk
+.align	4
+.Linvert:
+		mov	0(%rsi),%rax
+		mov	8(%rsi),%rbx
+		mov	0(%rdi),%rcx
+		mov	8(%rdi),%rdx
+		mov	%rax,0(%rdi)
+		mov	%rbx,8(%rdi)
+		mov	%rcx,0(%rsi)
+		mov	%rdx,8(%rsi)
+		lea	16(%rsi),%rsi
+		lea	-16(%rdi),%rdi
+		cmp	%rsi,%rdi
+	jne	.Linvert
+
+	lea	.LAES_Te+2048+1024(%rip),%rax	# rcon
+
+	mov	40(%rax),$mask80
+	mov	48(%rax),$maskfe
+	mov	56(%rax),$mask1b
+
+	mov	%r8,$key
+	sub	\$1,%r14d
+.align	4
+.Lpermute:
+		lea	16($key),$key
+		mov	0($key),%rax
+		mov	8($key),%rcx
+___
+		&dectransform ();
+$code.=<<___;
+		mov	%eax,0($key)
+		mov	%ebx,4($key)
+		mov	%ecx,8($key)
+		mov	%edx,12($key)
+		sub	\$1,%r14d
+	jnz	.Lpermute
+
+	xor	%rax,%rax
+.Labort:
+	mov	8(%rsp),%r15
+	mov	16(%rsp),%r14
+	mov	24(%rsp),%r13
+	mov	32(%rsp),%r12
+	mov	40(%rsp),%rbp
+	mov	48(%rsp),%rbx
+	add	\$56,%rsp
+.Ldec_key_epilogue:
+	ret
+.size	AES_set_decrypt_key,.-AES_set_decrypt_key
+___
+
+# void AES_cbc_encrypt (const void char *inp, unsigned char *out,
+#			size_t length, const AES_KEY *key,
+#			unsigned char *ivp,const int enc);
+{
+# stack frame layout
+# -8(%rsp)		return address
+my $keyp="0(%rsp)";		# one to pass as $key
+my $keyend="8(%rsp)";		# &(keyp->rd_key[4*keyp->rounds])
+my $_rsp="16(%rsp)";		# saved %rsp
+my $_inp="24(%rsp)";		# copy of 1st parameter, inp
+my $_out="32(%rsp)";		# copy of 2nd parameter, out
+my $_len="40(%rsp)";		# copy of 3rd parameter, length
+my $_key="48(%rsp)";		# copy of 4th parameter, key
+my $_ivp="56(%rsp)";		# copy of 5th parameter, ivp
+my $ivec="64(%rsp)";		# ivec[16]
+my $aes_key="80(%rsp)";		# copy of aes_key
+my $mark="80+240(%rsp)";	# copy of aes_key->rounds
+
+$code.=<<___;
+.globl	AES_cbc_encrypt
+.type	AES_cbc_encrypt,\@function,6
+.align	16
+.extern	OPENSSL_ia32cap_P
+AES_cbc_encrypt:
+	cmp	\$0,%rdx	# check length
+	je	.Lcbc_epilogue
+	pushfq
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+.Lcbc_prologue:
+
+	cld
+	mov	%r9d,%r9d	# clear upper half of enc
+
+	lea	.LAES_Te(%rip),$sbox
+	cmp	\$0,%r9
+	jne	.Lcbc_picked_te
+	lea	.LAES_Td(%rip),$sbox
+.Lcbc_picked_te:
+
+	mov	OPENSSL_ia32cap_P(%rip),%r10d
+	cmp	\$$speed_limit,%rdx
+	jb	.Lcbc_slow_prologue
+	test	\$15,%rdx
+	jnz	.Lcbc_slow_prologue
+	bt	\$28,%r10d
+	jc	.Lcbc_slow_prologue
+
+	# allocate aligned stack frame...
+	lea	-88-248(%rsp),$key
+	and	\$-64,$key
+
+	# ... and make sure it doesn't alias with AES_T[ed] modulo 4096
+	mov	$sbox,%r10
+	lea	2304($sbox),%r11
+	mov	$key,%r12
+	and	\$0xFFF,%r10	# s = $sbox&0xfff
+	and	\$0xFFF,%r11	# e = ($sbox+2048)&0xfff
+	and	\$0xFFF,%r12	# p = %rsp&0xfff
+
+	cmp	%r11,%r12	# if (p=>e) %rsp =- (p-e);
+	jb	.Lcbc_te_break_out
+	sub	%r11,%r12
+	sub	%r12,$key
+	jmp	.Lcbc_te_ok
+.Lcbc_te_break_out:		# else %rsp -= (p-s)&0xfff + framesz
+	sub	%r10,%r12
+	and	\$0xFFF,%r12
+	add	\$320,%r12
+	sub	%r12,$key
+.align	4
+.Lcbc_te_ok:
+
+	xchg	%rsp,$key
+	#add	\$8,%rsp	# reserve for return address!
+	mov	$key,$_rsp	# save %rsp
+.Lcbc_fast_body:
+	mov	%rdi,$_inp	# save copy of inp
+	mov	%rsi,$_out	# save copy of out
+	mov	%rdx,$_len	# save copy of len
+	mov	%rcx,$_key	# save copy of key
+	mov	%r8,$_ivp	# save copy of ivp
+	movl	\$0,$mark	# copy of aes_key->rounds = 0;
+	mov	%r8,%rbp	# rearrange input arguments
+	mov	%r9,%rbx
+	mov	%rsi,$out
+	mov	%rdi,$inp
+	mov	%rcx,$key
+
+	mov	240($key),%eax		# key->rounds
+	# do we copy key schedule to stack?
+	mov	$key,%r10
+	sub	$sbox,%r10
+	and	\$0xfff,%r10
+	cmp	\$2304,%r10
+	jb	.Lcbc_do_ecopy
+	cmp	\$4096-248,%r10
+	jb	.Lcbc_skip_ecopy
+.align	4
+.Lcbc_do_ecopy:
+		mov	$key,%rsi
+		lea	$aes_key,%rdi
+		lea	$aes_key,$key
+		mov	\$240/8,%ecx
+		.long	0x90A548F3	# rep movsq
+		mov	%eax,(%rdi)	# copy aes_key->rounds
+.Lcbc_skip_ecopy:
+	mov	$key,$keyp	# save key pointer
+
+	mov	\$18,%ecx
+.align	4
+.Lcbc_prefetch_te:
+		mov	0($sbox),%r10
+		mov	32($sbox),%r11
+		mov	64($sbox),%r12
+		mov	96($sbox),%r13
+		lea	128($sbox),$sbox
+		sub	\$1,%ecx
+	jnz	.Lcbc_prefetch_te
+	lea	-2304($sbox),$sbox
+
+	cmp	\$0,%rbx
+	je	.LFAST_DECRYPT
+
+#----------------------------- ENCRYPT -----------------------------#
+	mov	0(%rbp),$s0		# load iv
+	mov	4(%rbp),$s1
+	mov	8(%rbp),$s2
+	mov	12(%rbp),$s3
+
+.align	4
+.Lcbc_fast_enc_loop:
+		xor	0($inp),$s0
+		xor	4($inp),$s1
+		xor	8($inp),$s2
+		xor	12($inp),$s3
+		mov	$keyp,$key	# restore key
+		mov	$inp,$_inp	# if ($verticalspin) save inp
+
+		call	_x86_64_AES_encrypt
+
+		mov	$_inp,$inp	# if ($verticalspin) restore inp
+		mov	$_len,%r10
+		mov	$s0,0($out)
+		mov	$s1,4($out)
+		mov	$s2,8($out)
+		mov	$s3,12($out)
+
+		lea	16($inp),$inp
+		lea	16($out),$out
+		sub	\$16,%r10
+		test	\$-16,%r10
+		mov	%r10,$_len
+	jnz	.Lcbc_fast_enc_loop
+	mov	$_ivp,%rbp	# restore ivp
+	mov	$s0,0(%rbp)	# save ivec
+	mov	$s1,4(%rbp)
+	mov	$s2,8(%rbp)
+	mov	$s3,12(%rbp)
+
+	jmp	.Lcbc_fast_cleanup
+
+#----------------------------- DECRYPT -----------------------------#
+.align	16
+.LFAST_DECRYPT:
+	cmp	$inp,$out
+	je	.Lcbc_fast_dec_in_place
+
+	mov	%rbp,$ivec
+.align	4
+.Lcbc_fast_dec_loop:
+		mov	0($inp),$s0	# read input
+		mov	4($inp),$s1
+		mov	8($inp),$s2
+		mov	12($inp),$s3
+		mov	$keyp,$key	# restore key
+		mov	$inp,$_inp	# if ($verticalspin) save inp
+
+		call	_x86_64_AES_decrypt
+
+		mov	$ivec,%rbp	# load ivp
+		mov	$_inp,$inp	# if ($verticalspin) restore inp
+		mov	$_len,%r10	# load len
+		xor	0(%rbp),$s0	# xor iv
+		xor	4(%rbp),$s1
+		xor	8(%rbp),$s2
+		xor	12(%rbp),$s3
+		mov	$inp,%rbp	# current input, next iv
+
+		sub	\$16,%r10
+		mov	%r10,$_len	# update len
+		mov	%rbp,$ivec	# update ivp
+
+		mov	$s0,0($out)	# write output
+		mov	$s1,4($out)
+		mov	$s2,8($out)
+		mov	$s3,12($out)
+
+		lea	16($inp),$inp
+		lea	16($out),$out
+	jnz	.Lcbc_fast_dec_loop
+	mov	$_ivp,%r12		# load user ivp
+	mov	0(%rbp),%r10		# load iv
+	mov	8(%rbp),%r11
+	mov	%r10,0(%r12)		# copy back to user
+	mov	%r11,8(%r12)
+	jmp	.Lcbc_fast_cleanup
+
+.align	16
+.Lcbc_fast_dec_in_place:
+	mov	0(%rbp),%r10		# copy iv to stack
+	mov	8(%rbp),%r11
+	mov	%r10,0+$ivec
+	mov	%r11,8+$ivec
+.align	4
+.Lcbc_fast_dec_in_place_loop:
+		mov	0($inp),$s0	# load input
+		mov	4($inp),$s1
+		mov	8($inp),$s2
+		mov	12($inp),$s3
+		mov	$keyp,$key	# restore key
+		mov	$inp,$_inp	# if ($verticalspin) save inp
+
+		call	_x86_64_AES_decrypt
+
+		mov	$_inp,$inp	# if ($verticalspin) restore inp
+		mov	$_len,%r10
+		xor	0+$ivec,$s0
+		xor	4+$ivec,$s1
+		xor	8+$ivec,$s2
+		xor	12+$ivec,$s3
+
+		mov	0($inp),%r11	# load input
+		mov	8($inp),%r12
+		sub	\$16,%r10
+		jz	.Lcbc_fast_dec_in_place_done
+
+		mov	%r11,0+$ivec	# copy input to iv
+		mov	%r12,8+$ivec
+
+		mov	$s0,0($out)	# save output [zaps input]
+		mov	$s1,4($out)
+		mov	$s2,8($out)
+		mov	$s3,12($out)
+
+		lea	16($inp),$inp
+		lea	16($out),$out
+		mov	%r10,$_len
+	jmp	.Lcbc_fast_dec_in_place_loop
+.Lcbc_fast_dec_in_place_done:
+	mov	$_ivp,%rdi
+	mov	%r11,0(%rdi)	# copy iv back to user
+	mov	%r12,8(%rdi)
+
+	mov	$s0,0($out)	# save output [zaps input]
+	mov	$s1,4($out)
+	mov	$s2,8($out)
+	mov	$s3,12($out)
+
+.align	4
+.Lcbc_fast_cleanup:
+	cmpl	\$0,$mark	# was the key schedule copied?
+	lea	$aes_key,%rdi
+	je	.Lcbc_exit
+		mov	\$240/8,%ecx
+		xor	%rax,%rax
+		.long	0x90AB48F3	# rep stosq
+
+	jmp	.Lcbc_exit
+
+#--------------------------- SLOW ROUTINE ---------------------------#
+.align	16
+.Lcbc_slow_prologue:
+	# allocate aligned stack frame...
+	lea	-88(%rsp),%rbp
+	and	\$-64,%rbp
+	# ... just "above" key schedule
+	lea	-88-63(%rcx),%r10
+	sub	%rbp,%r10
+	neg	%r10
+	and	\$0x3c0,%r10
+	sub	%r10,%rbp
+
+	xchg	%rsp,%rbp
+	#add	\$8,%rsp	# reserve for return address!
+	mov	%rbp,$_rsp	# save %rsp
+.Lcbc_slow_body:
+	#mov	%rdi,$_inp	# save copy of inp
+	#mov	%rsi,$_out	# save copy of out
+	#mov	%rdx,$_len	# save copy of len
+	#mov	%rcx,$_key	# save copy of key
+	mov	%r8,$_ivp	# save copy of ivp
+	mov	%r8,%rbp	# rearrange input arguments
+	mov	%r9,%rbx
+	mov	%rsi,$out
+	mov	%rdi,$inp
+	mov	%rcx,$key
+	mov	%rdx,%r10
+
+	mov	240($key),%eax
+	mov	$key,$keyp	# save key pointer
+	shl	\$4,%eax
+	lea	($key,%rax),%rax
+	mov	%rax,$keyend
+
+	# pick Te4 copy which can't "overlap" with stack frame or key scdedule
+	lea	2048($sbox),$sbox
+	lea	768-8(%rsp),%rax
+	sub	$sbox,%rax
+	and	\$0x300,%rax
+	lea	($sbox,%rax),$sbox
+
+	cmp	\$0,%rbx
+	je	.LSLOW_DECRYPT
+
+#--------------------------- SLOW ENCRYPT ---------------------------#
+	test	\$-16,%r10		# check upon length
+	mov	0(%rbp),$s0		# load iv
+	mov	4(%rbp),$s1
+	mov	8(%rbp),$s2
+	mov	12(%rbp),$s3
+	jz	.Lcbc_slow_enc_tail	# short input...
+
+.align	4
+.Lcbc_slow_enc_loop:
+		xor	0($inp),$s0
+		xor	4($inp),$s1
+		xor	8($inp),$s2
+		xor	12($inp),$s3
+		mov	$keyp,$key	# restore key
+		mov	$inp,$_inp	# save inp
+		mov	$out,$_out	# save out
+		mov	%r10,$_len	# save len
+
+		call	_x86_64_AES_encrypt_compact
+
+		mov	$_inp,$inp	# restore inp
+		mov	$_out,$out	# restore out
+		mov	$_len,%r10	# restore len
+		mov	$s0,0($out)
+		mov	$s1,4($out)
+		mov	$s2,8($out)
+		mov	$s3,12($out)
+
+		lea	16($inp),$inp
+		lea	16($out),$out
+		sub	\$16,%r10
+		test	\$-16,%r10
+	jnz	.Lcbc_slow_enc_loop
+	test	\$15,%r10
+	jnz	.Lcbc_slow_enc_tail
+	mov	$_ivp,%rbp	# restore ivp
+	mov	$s0,0(%rbp)	# save ivec
+	mov	$s1,4(%rbp)
+	mov	$s2,8(%rbp)
+	mov	$s3,12(%rbp)
+
+	jmp	.Lcbc_exit
+
+.align	4
+.Lcbc_slow_enc_tail:
+	mov	%rax,%r11
+	mov	%rcx,%r12
+	mov	%r10,%rcx
+	mov	$inp,%rsi
+	mov	$out,%rdi
+	.long	0x9066A4F3		# rep movsb
+	mov	\$16,%rcx		# zero tail
+	sub	%r10,%rcx
+	xor	%rax,%rax
+	.long	0x9066AAF3		# rep stosb
+	mov	$out,$inp		# this is not a mistake!
+	mov	\$16,%r10		# len=16
+	mov	%r11,%rax
+	mov	%r12,%rcx
+	jmp	.Lcbc_slow_enc_loop	# one more spin...
+#--------------------------- SLOW DECRYPT ---------------------------#
+.align	16
+.LSLOW_DECRYPT:
+	shr	\$3,%rax
+	add	%rax,$sbox		# recall "magic" constants!
+
+	mov	0(%rbp),%r11		# copy iv to stack
+	mov	8(%rbp),%r12
+	mov	%r11,0+$ivec
+	mov	%r12,8+$ivec
+
+.align	4
+.Lcbc_slow_dec_loop:
+		mov	0($inp),$s0	# load input
+		mov	4($inp),$s1
+		mov	8($inp),$s2
+		mov	12($inp),$s3
+		mov	$keyp,$key	# restore key
+		mov	$inp,$_inp	# save inp
+		mov	$out,$_out	# save out
+		mov	%r10,$_len	# save len
+
+		call	_x86_64_AES_decrypt_compact
+
+		mov	$_inp,$inp	# restore inp
+		mov	$_out,$out	# restore out
+		mov	$_len,%r10
+		xor	0+$ivec,$s0
+		xor	4+$ivec,$s1
+		xor	8+$ivec,$s2
+		xor	12+$ivec,$s3
+
+		mov	0($inp),%r11	# load input
+		mov	8($inp),%r12
+		sub	\$16,%r10
+		jc	.Lcbc_slow_dec_partial
+		jz	.Lcbc_slow_dec_done
+
+		mov	%r11,0+$ivec	# copy input to iv
+		mov	%r12,8+$ivec
+
+		mov	$s0,0($out)	# save output [can zap input]
+		mov	$s1,4($out)
+		mov	$s2,8($out)
+		mov	$s3,12($out)
+
+		lea	16($inp),$inp
+		lea	16($out),$out
+	jmp	.Lcbc_slow_dec_loop
+.Lcbc_slow_dec_done:
+	mov	$_ivp,%rdi
+	mov	%r11,0(%rdi)		# copy iv back to user
+	mov	%r12,8(%rdi)
+
+	mov	$s0,0($out)		# save output [can zap input]
+	mov	$s1,4($out)
+	mov	$s2,8($out)
+	mov	$s3,12($out)
+
+	jmp	.Lcbc_exit
+
+.align	4
+.Lcbc_slow_dec_partial:
+	mov	$_ivp,%rdi
+	mov	%r11,0(%rdi)		# copy iv back to user
+	mov	%r12,8(%rdi)
+
+	mov	$s0,0+$ivec		# save output to stack
+	mov	$s1,4+$ivec
+	mov	$s2,8+$ivec
+	mov	$s3,12+$ivec
+
+	mov	$out,%rdi
+	lea	$ivec,%rsi
+	lea	16(%r10),%rcx
+	.long	0x9066A4F3	# rep movsb
+	jmp	.Lcbc_exit
+
+.align	16
+.Lcbc_exit:
+	mov	$_rsp,%rsi
+	mov	(%rsi),%r15
+	mov	8(%rsi),%r14
+	mov	16(%rsi),%r13
+	mov	24(%rsi),%r12
+	mov	32(%rsi),%rbp
+	mov	40(%rsi),%rbx
+	lea	48(%rsi),%rsp
+.Lcbc_popfq:
+	popfq
+.Lcbc_epilogue:
+	ret
+.size	AES_cbc_encrypt,.-AES_cbc_encrypt
+___
+}
+
+$code.=<<___;
+.align	64
+.LAES_Te:
+___
+	&_data_word(0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6);
+	&_data_word(0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591);
+	&_data_word(0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56);
+	&_data_word(0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec);
+	&_data_word(0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa);
+	&_data_word(0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb);
+	&_data_word(0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45);
+	&_data_word(0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b);
+	&_data_word(0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c);
+	&_data_word(0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83);
+	&_data_word(0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9);
+	&_data_word(0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a);
+	&_data_word(0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d);
+	&_data_word(0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f);
+	&_data_word(0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df);
+	&_data_word(0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea);
+	&_data_word(0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34);
+	&_data_word(0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b);
+	&_data_word(0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d);
+	&_data_word(0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413);
+	&_data_word(0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1);
+	&_data_word(0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6);
+	&_data_word(0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972);
+	&_data_word(0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85);
+	&_data_word(0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed);
+	&_data_word(0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511);
+	&_data_word(0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe);
+	&_data_word(0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b);
+	&_data_word(0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05);
+	&_data_word(0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1);
+	&_data_word(0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142);
+	&_data_word(0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf);
+	&_data_word(0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3);
+	&_data_word(0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e);
+	&_data_word(0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a);
+	&_data_word(0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6);
+	&_data_word(0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3);
+	&_data_word(0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b);
+	&_data_word(0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428);
+	&_data_word(0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad);
+	&_data_word(0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14);
+	&_data_word(0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8);
+	&_data_word(0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4);
+	&_data_word(0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2);
+	&_data_word(0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda);
+	&_data_word(0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949);
+	&_data_word(0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf);
+	&_data_word(0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810);
+	&_data_word(0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c);
+	&_data_word(0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697);
+	&_data_word(0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e);
+	&_data_word(0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f);
+	&_data_word(0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc);
+	&_data_word(0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c);
+	&_data_word(0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969);
+	&_data_word(0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27);
+	&_data_word(0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122);
+	&_data_word(0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433);
+	&_data_word(0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9);
+	&_data_word(0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5);
+	&_data_word(0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a);
+	&_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0);
+	&_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e);
+	&_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c);
+
+#Te4	# four copies of Te4 to choose from to avoid L1 aliasing
+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
+
+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
+
+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
+
+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
+#rcon:
+$code.=<<___;
+	.long	0x00000001, 0x00000002, 0x00000004, 0x00000008
+	.long	0x00000010, 0x00000020, 0x00000040, 0x00000080
+	.long	0x0000001b, 0x00000036, 0x80808080, 0x80808080
+	.long	0xfefefefe, 0xfefefefe, 0x1b1b1b1b, 0x1b1b1b1b
+___
+$code.=<<___;
+.align	64
+.LAES_Td:
+___
+	&_data_word(0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a);
+	&_data_word(0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b);
+	&_data_word(0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5);
+	&_data_word(0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5);
+	&_data_word(0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d);
+	&_data_word(0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b);
+	&_data_word(0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295);
+	&_data_word(0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e);
+	&_data_word(0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927);
+	&_data_word(0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d);
+	&_data_word(0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362);
+	&_data_word(0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9);
+	&_data_word(0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52);
+	&_data_word(0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566);
+	&_data_word(0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3);
+	&_data_word(0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed);
+	&_data_word(0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e);
+	&_data_word(0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4);
+	&_data_word(0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4);
+	&_data_word(0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd);
+	&_data_word(0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d);
+	&_data_word(0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060);
+	&_data_word(0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967);
+	&_data_word(0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879);
+	&_data_word(0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000);
+	&_data_word(0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c);
+	&_data_word(0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36);
+	&_data_word(0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624);
+	&_data_word(0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b);
+	&_data_word(0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c);
+	&_data_word(0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12);
+	&_data_word(0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14);
+	&_data_word(0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3);
+	&_data_word(0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b);
+	&_data_word(0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8);
+	&_data_word(0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684);
+	&_data_word(0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7);
+	&_data_word(0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177);
+	&_data_word(0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947);
+	&_data_word(0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322);
+	&_data_word(0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498);
+	&_data_word(0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f);
+	&_data_word(0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54);
+	&_data_word(0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382);
+	&_data_word(0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf);
+	&_data_word(0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb);
+	&_data_word(0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83);
+	&_data_word(0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef);
+	&_data_word(0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029);
+	&_data_word(0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235);
+	&_data_word(0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733);
+	&_data_word(0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117);
+	&_data_word(0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4);
+	&_data_word(0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546);
+	&_data_word(0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb);
+	&_data_word(0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d);
+	&_data_word(0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb);
+	&_data_word(0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a);
+	&_data_word(0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773);
+	&_data_word(0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478);
+	&_data_word(0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2);
+	&_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff);
+	&_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664);
+	&_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0);
+
+#Td4:	# four copies of Td4 to choose from to avoid L1 aliasing
+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
+$code.=<<___;
+	.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
+	.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
+___
+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
+$code.=<<___;
+	.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
+	.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
+___
+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
+$code.=<<___;
+	.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
+	.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
+___
+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
+$code.=<<___;
+	.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
+	.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
+.asciz  "AES for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
+.align	64
+___
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern	__imp_RtlVirtualUnwind
+.type	block_se_handler,\@abi-omnipotent
+.align	16
+block_se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	mov	8($disp),%rsi		# disp->ImageBase
+	mov	56($disp),%r11		# disp->HandlerData
+
+	mov	0(%r11),%r10d		# HandlerData[0]
+	lea	(%rsi,%r10),%r10	# prologue label
+	cmp	%r10,%rbx		# context->Rip<prologue label
+	jb	.Lin_block_prologue
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	mov	4(%r11),%r10d		# HandlerData[1]
+	lea	(%rsi,%r10),%r10	# epilogue label
+	cmp	%r10,%rbx		# context->Rip>=epilogue label
+	jae	.Lin_block_prologue
+
+	mov	24(%rax),%rax		# pull saved real stack pointer
+	lea	48(%rax),%rax		# adjust...
+
+	mov	-8(%rax),%rbx
+	mov	-16(%rax),%rbp
+	mov	-24(%rax),%r12
+	mov	-32(%rax),%r13
+	mov	-40(%rax),%r14
+	mov	-48(%rax),%r15
+	mov	%rbx,144($context)	# restore context->Rbx
+	mov	%rbp,160($context)	# restore context->Rbp
+	mov	%r12,216($context)	# restore context->R12
+	mov	%r13,224($context)	# restore context->R13
+	mov	%r14,232($context)	# restore context->R14
+	mov	%r15,240($context)	# restore context->R15
+
+.Lin_block_prologue:
+	mov	8(%rax),%rdi
+	mov	16(%rax),%rsi
+	mov	%rax,152($context)	# restore context->Rsp
+	mov	%rsi,168($context)	# restore context->Rsi
+	mov	%rdi,176($context)	# restore context->Rdi
+
+	jmp	.Lcommon_seh_exit
+.size	block_se_handler,.-block_se_handler
+
+.type	key_se_handler,\@abi-omnipotent
+.align	16
+key_se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	mov	8($disp),%rsi		# disp->ImageBase
+	mov	56($disp),%r11		# disp->HandlerData
+
+	mov	0(%r11),%r10d		# HandlerData[0]
+	lea	(%rsi,%r10),%r10	# prologue label
+	cmp	%r10,%rbx		# context->Rip<prologue label
+	jb	.Lin_key_prologue
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	mov	4(%r11),%r10d		# HandlerData[1]
+	lea	(%rsi,%r10),%r10	# epilogue label
+	cmp	%r10,%rbx		# context->Rip>=epilogue label
+	jae	.Lin_key_prologue
+
+	lea	56(%rax),%rax
+
+	mov	-8(%rax),%rbx
+	mov	-16(%rax),%rbp
+	mov	-24(%rax),%r12
+	mov	-32(%rax),%r13
+	mov	-40(%rax),%r14
+	mov	-48(%rax),%r15
+	mov	%rbx,144($context)	# restore context->Rbx
+	mov	%rbp,160($context)	# restore context->Rbp
+	mov	%r12,216($context)	# restore context->R12
+	mov	%r13,224($context)	# restore context->R13
+	mov	%r14,232($context)	# restore context->R14
+	mov	%r15,240($context)	# restore context->R15
+
+.Lin_key_prologue:
+	mov	8(%rax),%rdi
+	mov	16(%rax),%rsi
+	mov	%rax,152($context)	# restore context->Rsp
+	mov	%rsi,168($context)	# restore context->Rsi
+	mov	%rdi,176($context)	# restore context->Rdi
+
+	jmp	.Lcommon_seh_exit
+.size	key_se_handler,.-key_se_handler
+
+.type	cbc_se_handler,\@abi-omnipotent
+.align	16
+cbc_se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	lea	.Lcbc_prologue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lcbc_prologue
+	jb	.Lin_cbc_prologue
+
+	lea	.Lcbc_fast_body(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lcbc_fast_body
+	jb	.Lin_cbc_frame_setup
+
+	lea	.Lcbc_slow_prologue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lcbc_slow_prologue
+	jb	.Lin_cbc_body
+
+	lea	.Lcbc_slow_body(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lcbc_slow_body
+	jb	.Lin_cbc_frame_setup
+
+.Lin_cbc_body:
+	mov	152($context),%rax	# pull context->Rsp
+
+	lea	.Lcbc_epilogue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip>=.Lcbc_epilogue
+	jae	.Lin_cbc_prologue
+
+	lea	8(%rax),%rax
+
+	lea	.Lcbc_popfq(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip>=.Lcbc_popfq
+	jae	.Lin_cbc_prologue
+
+	mov	`16-8`(%rax),%rax	# biased $_rsp
+	lea	56(%rax),%rax
+
+.Lin_cbc_frame_setup:
+	mov	-16(%rax),%rbx
+	mov	-24(%rax),%rbp
+	mov	-32(%rax),%r12
+	mov	-40(%rax),%r13
+	mov	-48(%rax),%r14
+	mov	-56(%rax),%r15
+	mov	%rbx,144($context)	# restore context->Rbx
+	mov	%rbp,160($context)	# restore context->Rbp
+	mov	%r12,216($context)	# restore context->R12
+	mov	%r13,224($context)	# restore context->R13
+	mov	%r14,232($context)	# restore context->R14
+	mov	%r15,240($context)	# restore context->R15
+
+.Lin_cbc_prologue:
+	mov	8(%rax),%rdi
+	mov	16(%rax),%rsi
+	mov	%rax,152($context)	# restore context->Rsp
+	mov	%rsi,168($context)	# restore context->Rsi
+	mov	%rdi,176($context)	# restore context->Rdi
+
+.Lcommon_seh_exit:
+
+	mov	40($disp),%rdi		# disp->ContextRecord
+	mov	$context,%rsi		# context
+	mov	\$`1232/8`,%ecx		# sizeof(CONTEXT)
+	.long	0xa548f3fc		# cld; rep movsq
+
+	mov	$disp,%rsi
+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
+	mov	40(%rsi),%r10		# disp->ContextRecord
+	lea	56(%rsi),%r11		# &disp->HandlerData
+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
+	mov	%r10,32(%rsp)		# arg5
+	mov	%r11,40(%rsp)		# arg6
+	mov	%r12,48(%rsp)		# arg7
+	mov	%rcx,56(%rsp)		# arg8, (NULL)
+	call	*__imp_RtlVirtualUnwind(%rip)
+
+	mov	\$1,%eax		# ExceptionContinueSearch
+	add	\$64,%rsp
+	popfq
+	pop	%r15
+	pop	%r14
+	pop	%r13
+	pop	%r12
+	pop	%rbp
+	pop	%rbx
+	pop	%rdi
+	pop	%rsi
+	ret
+.size	cbc_se_handler,.-cbc_se_handler
+
+.section	.pdata
+.align	4
+	.rva	.LSEH_begin_AES_encrypt
+	.rva	.LSEH_end_AES_encrypt
+	.rva	.LSEH_info_AES_encrypt
+
+	.rva	.LSEH_begin_AES_decrypt
+	.rva	.LSEH_end_AES_decrypt
+	.rva	.LSEH_info_AES_decrypt
+
+	.rva	.LSEH_begin_AES_set_encrypt_key
+	.rva	.LSEH_end_AES_set_encrypt_key
+	.rva	.LSEH_info_AES_set_encrypt_key
+
+	.rva	.LSEH_begin_AES_set_decrypt_key
+	.rva	.LSEH_end_AES_set_decrypt_key
+	.rva	.LSEH_info_AES_set_decrypt_key
+
+	.rva	.LSEH_begin_AES_cbc_encrypt
+	.rva	.LSEH_end_AES_cbc_encrypt
+	.rva	.LSEH_info_AES_cbc_encrypt
+
+.section	.xdata
+.align	8
+.LSEH_info_AES_encrypt:
+	.byte	9,0,0,0
+	.rva	block_se_handler
+	.rva	.Lenc_prologue,.Lenc_epilogue	# HandlerData[]
+.LSEH_info_AES_decrypt:
+	.byte	9,0,0,0
+	.rva	block_se_handler
+	.rva	.Ldec_prologue,.Ldec_epilogue	# HandlerData[]
+.LSEH_info_AES_set_encrypt_key:
+	.byte	9,0,0,0
+	.rva	key_se_handler
+	.rva	.Lenc_key_prologue,.Lenc_key_epilogue	# HandlerData[]
+.LSEH_info_AES_set_decrypt_key:
+	.byte	9,0,0,0
+	.rva	key_se_handler
+	.rva	.Ldec_key_prologue,.Ldec_key_epilogue	# HandlerData[]
+.LSEH_info_AES_cbc_encrypt:
+	.byte	9,0,0,0
+	.rva	cbc_se_handler
+___
+}
+
+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+
+print $code;
+
+close STDOUT;
diff --git a/openssl/crypto/alphacpuid.pl b/openssl/crypto/alphacpuid.pl
new file mode 100644
index 0000000..4b3cbb9
--- /dev/null
+++ b/openssl/crypto/alphacpuid.pl
@@ -0,0 +1,126 @@
+#!/usr/bin/env perl
+print <<'___';
+.text
+
+.set	noat
+
+.globl	OPENSSL_cpuid_setup
+.ent	OPENSSL_cpuid_setup
+OPENSSL_cpuid_setup:
+	.frame	$30,0,$26
+	.prologue 0
+	ret	($26)
+.end	OPENSSL_cpuid_setup
+
+.globl	OPENSSL_wipe_cpu
+.ent	OPENSSL_wipe_cpu
+OPENSSL_wipe_cpu:
+	.frame	$30,0,$26
+	.prologue 0
+	clr	$1
+	clr	$2
+	clr	$3
+	clr	$4
+	clr	$5
+	clr	$6
+	clr	$7
+	clr	$8
+	clr	$16
+	clr	$17
+	clr	$18
+	clr	$19
+	clr	$20
+	clr	$21
+	clr	$22
+	clr	$23
+	clr	$24
+	clr	$25
+	clr	$27
+	clr	$at
+	clr	$29
+	fclr	$f0
+	fclr	$f1
+	fclr	$f10
+	fclr	$f11
+	fclr	$f12
+	fclr	$f13
+	fclr	$f14
+	fclr	$f15
+	fclr	$f16
+	fclr	$f17
+	fclr	$f18
+	fclr	$f19
+	fclr	$f20
+	fclr	$f21
+	fclr	$f22
+	fclr	$f23
+	fclr	$f24
+	fclr	$f25
+	fclr	$f26
+	fclr	$f27
+	fclr	$f28
+	fclr	$f29
+	fclr	$f30
+	mov	$sp,$0
+	ret	($26)
+.end	OPENSSL_wipe_cpu
+
+.globl	OPENSSL_atomic_add
+.ent	OPENSSL_atomic_add
+OPENSSL_atomic_add:
+	.frame	$30,0,$26
+	.prologue 0
+1:	ldl_l	$0,0($16)
+	addl	$0,$17,$1
+	stl_c	$1,0($16)
+	beq	$1,1b
+	addl	$0,$17,$0
+	ret	($26)
+.end	OPENSSL_atomic_add
+
+.globl	OPENSSL_rdtsc
+.ent	OPENSSL_rdtsc
+OPENSSL_rdtsc:
+	.frame	$30,0,$26
+	.prologue 0
+	rpcc	$0
+	ret	($26)
+.end	OPENSSL_rdtsc
+
+.globl	OPENSSL_cleanse
+.ent	OPENSSL_cleanse
+OPENSSL_cleanse:
+	.frame	$30,0,$26
+	.prologue 0
+	beq	$17,.Ldone
+	and	$16,7,$0
+	bic	$17,7,$at
+	beq	$at,.Little
+	beq	$0,.Laligned
+
+.Little:
+	subq	$0,8,$0
+	ldq_u	$1,0($16)
+	mov	$16,$2
+.Lalign:
+	mskbl	$1,$16,$1
+	lda	$16,1($16)
+	subq	$17,1,$17
+	addq	$0,1,$0
+	beq	$17,.Lout
+	bne	$0,.Lalign
+.Lout:	stq_u	$1,0($2)
+	beq	$17,.Ldone
+	bic	$17,7,$at
+	beq	$at,.Little
+
+.Laligned:
+	stq	$31,0($16)
+	subq	$17,8,$17
+	lda	$16,8($16)
+	bic	$17,7,$at
+	bne	$at,.Laligned
+	bne	$17,.Little
+.Ldone: ret	($26)
+.end	OPENSSL_cleanse
+___
diff --git a/openssl/crypto/asn1/Makefile b/openssl/crypto/asn1/Makefile
new file mode 100644
index 0000000..160544e
--- /dev/null
+++ b/openssl/crypto/asn1/Makefile
@@ -0,0 +1,930 @@
+#
+# OpenSSL/crypto/asn1/Makefile
+#
+
+DIR=	asn1
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile README
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=	a_object.c a_bitstr.c a_utctm.c a_gentm.c a_time.c a_int.c a_octet.c \
+	a_print.c a_type.c a_set.c a_dup.c a_d2i_fp.c a_i2d_fp.c \
+	a_enum.c a_utf8.c a_sign.c a_digest.c a_verify.c a_mbstr.c a_strex.c \
+	x_algor.c x_val.c x_pubkey.c x_sig.c x_req.c x_attrib.c x_bignum.c \
+	x_long.c x_name.c x_x509.c x_x509a.c x_crl.c x_info.c x_spki.c nsseq.c \
+	x_nx509.c d2i_pu.c d2i_pr.c i2d_pu.c i2d_pr.c\
+	t_req.c t_x509.c t_x509a.c t_crl.c t_pkey.c t_spki.c t_bitst.c \
+	tasn_new.c tasn_fre.c tasn_enc.c tasn_dec.c tasn_utl.c tasn_typ.c \
+	tasn_prn.c ameth_lib.c \
+	f_int.c f_string.c n_pkey.c \
+	f_enum.c x_pkey.c a_bool.c x_exten.c bio_asn1.c bio_ndef.c asn_mime.c \
+	asn1_gen.c asn1_par.c asn1_lib.c asn1_err.c a_bytes.c a_strnid.c \
+	evp_asn1.c asn_pack.c p5_pbe.c p5_pbev2.c p8_pkey.c asn_moid.c
+LIBOBJ= a_object.o a_bitstr.o a_utctm.o a_gentm.o a_time.o a_int.o a_octet.o \
+	a_print.o a_type.o a_set.o a_dup.o a_d2i_fp.o a_i2d_fp.o \
+	a_enum.o a_utf8.o a_sign.o a_digest.o a_verify.o a_mbstr.o a_strex.o \
+	x_algor.o x_val.o x_pubkey.o x_sig.o x_req.o x_attrib.o x_bignum.o \
+	x_long.o x_name.o x_x509.o x_x509a.o x_crl.o x_info.o x_spki.o nsseq.o \
+	x_nx509.o d2i_pu.o d2i_pr.o i2d_pu.o i2d_pr.o \
+	t_req.o t_x509.o t_x509a.o t_crl.o t_pkey.o t_spki.o t_bitst.o \
+	tasn_new.o tasn_fre.o tasn_enc.o tasn_dec.o tasn_utl.o tasn_typ.o \
+	tasn_prn.o ameth_lib.o \
+	f_int.o f_string.o n_pkey.o \
+	f_enum.o x_pkey.o a_bool.o x_exten.o bio_asn1.o bio_ndef.o asn_mime.o \
+	asn1_gen.o asn1_par.o asn1_lib.o asn1_err.o a_bytes.o a_strnid.o \
+	evp_asn1.o asn_pack.o p5_pbe.o p5_pbev2.o p8_pkey.o asn_moid.o
+
+SRC= $(LIBSRC)
+
+EXHEADER=  asn1.h asn1_mac.h asn1t.h
+HEADER=	$(EXHEADER) asn1_locl.h
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+test:	test.c
+	cc -g -I../../include -c test.c
+	cc -g -I../../include -o test test.o -L../.. -lcrypto
+
+pk:	pk.c
+	cc -g -I../../include -c pk.c
+	cc -g -I../../include -o pk pk.o -L../.. -lcrypto
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by top Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+a_bitstr.o: ../../e_os.h ../../include/openssl/asn1.h
+a_bitstr.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+a_bitstr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+a_bitstr.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+a_bitstr.o: ../../include/openssl/opensslconf.h
+a_bitstr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+a_bitstr.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+a_bitstr.o: ../../include/openssl/symhacks.h ../cryptlib.h a_bitstr.c
+a_bool.o: ../../e_os.h ../../include/openssl/asn1.h
+a_bool.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+a_bool.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+a_bool.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+a_bool.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+a_bool.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+a_bool.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+a_bool.o: ../../include/openssl/symhacks.h ../cryptlib.h a_bool.c
+a_bytes.o: ../../e_os.h ../../include/openssl/asn1.h
+a_bytes.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+a_bytes.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+a_bytes.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+a_bytes.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+a_bytes.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+a_bytes.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+a_bytes.o: ../cryptlib.h a_bytes.c
+a_d2i_fp.o: ../../e_os.h ../../include/openssl/asn1.h
+a_d2i_fp.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
+a_d2i_fp.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+a_d2i_fp.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+a_d2i_fp.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+a_d2i_fp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+a_d2i_fp.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+a_d2i_fp.o: ../../include/openssl/symhacks.h ../cryptlib.h a_d2i_fp.c
+a_digest.o: ../../e_os.h ../../include/openssl/asn1.h
+a_digest.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+a_digest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+a_digest.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+a_digest.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+a_digest.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+a_digest.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+a_digest.o: ../../include/openssl/opensslconf.h
+a_digest.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+a_digest.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+a_digest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+a_digest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+a_digest.o: ../../include/openssl/x509_vfy.h ../cryptlib.h a_digest.c
+a_dup.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+a_dup.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+a_dup.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+a_dup.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+a_dup.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+a_dup.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+a_dup.o: ../../include/openssl/symhacks.h ../cryptlib.h a_dup.c
+a_enum.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+a_enum.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+a_enum.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+a_enum.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+a_enum.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+a_enum.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+a_enum.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+a_enum.o: ../cryptlib.h a_enum.c
+a_gentm.o: ../../e_os.h ../../include/openssl/asn1.h
+a_gentm.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+a_gentm.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+a_gentm.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+a_gentm.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+a_gentm.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+a_gentm.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+a_gentm.o: ../cryptlib.h ../o_time.h a_gentm.c
+a_i2d_fp.o: ../../e_os.h ../../include/openssl/asn1.h
+a_i2d_fp.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+a_i2d_fp.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+a_i2d_fp.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+a_i2d_fp.o: ../../include/openssl/opensslconf.h
+a_i2d_fp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+a_i2d_fp.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+a_i2d_fp.o: ../../include/openssl/symhacks.h ../cryptlib.h a_i2d_fp.c
+a_int.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+a_int.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+a_int.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+a_int.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+a_int.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+a_int.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+a_int.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+a_int.o: ../cryptlib.h a_int.c
+a_mbstr.o: ../../e_os.h ../../include/openssl/asn1.h
+a_mbstr.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+a_mbstr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+a_mbstr.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+a_mbstr.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+a_mbstr.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+a_mbstr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+a_mbstr.o: ../cryptlib.h a_mbstr.c
+a_object.o: ../../e_os.h ../../include/openssl/asn1.h
+a_object.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+a_object.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+a_object.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+a_object.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+a_object.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+a_object.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+a_object.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+a_object.o: ../../include/openssl/symhacks.h ../cryptlib.h a_object.c
+a_octet.o: ../../e_os.h ../../include/openssl/asn1.h
+a_octet.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+a_octet.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+a_octet.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+a_octet.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+a_octet.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+a_octet.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+a_octet.o: ../cryptlib.h a_octet.c
+a_print.o: ../../e_os.h ../../include/openssl/asn1.h
+a_print.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+a_print.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+a_print.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+a_print.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+a_print.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+a_print.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+a_print.o: ../cryptlib.h a_print.c
+a_set.o: ../../e_os.h ../../include/openssl/asn1.h
+a_set.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
+a_set.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+a_set.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+a_set.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+a_set.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+a_set.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+a_set.o: ../../include/openssl/symhacks.h ../cryptlib.h a_set.c
+a_sign.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+a_sign.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+a_sign.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+a_sign.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+a_sign.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+a_sign.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+a_sign.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+a_sign.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+a_sign.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+a_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+a_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+a_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+a_sign.o: ../cryptlib.h a_sign.c asn1_locl.h
+a_strex.o: ../../e_os.h ../../include/openssl/asn1.h
+a_strex.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+a_strex.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+a_strex.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+a_strex.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+a_strex.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+a_strex.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+a_strex.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+a_strex.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+a_strex.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+a_strex.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+a_strex.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+a_strex.o: ../cryptlib.h a_strex.c charmap.h
+a_strnid.o: ../../e_os.h ../../include/openssl/asn1.h
+a_strnid.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+a_strnid.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+a_strnid.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+a_strnid.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+a_strnid.o: ../../include/openssl/opensslconf.h
+a_strnid.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+a_strnid.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+a_strnid.o: ../../include/openssl/symhacks.h ../cryptlib.h a_strnid.c
+a_time.o: ../../e_os.h ../../include/openssl/asn1.h
+a_time.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+a_time.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+a_time.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+a_time.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+a_time.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+a_time.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+a_time.o: ../../include/openssl/symhacks.h ../cryptlib.h ../o_time.h a_time.c
+a_type.o: ../../e_os.h ../../include/openssl/asn1.h
+a_type.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+a_type.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+a_type.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+a_type.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+a_type.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+a_type.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+a_type.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+a_type.o: ../../include/openssl/symhacks.h ../cryptlib.h a_type.c
+a_utctm.o: ../../e_os.h ../../include/openssl/asn1.h
+a_utctm.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+a_utctm.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+a_utctm.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+a_utctm.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+a_utctm.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+a_utctm.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+a_utctm.o: ../cryptlib.h ../o_time.h a_utctm.c
+a_utf8.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+a_utf8.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+a_utf8.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+a_utf8.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+a_utf8.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+a_utf8.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+a_utf8.o: ../../include/openssl/symhacks.h ../cryptlib.h a_utf8.c
+a_verify.o: ../../e_os.h ../../include/openssl/asn1.h
+a_verify.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+a_verify.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+a_verify.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+a_verify.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+a_verify.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+a_verify.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+a_verify.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+a_verify.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+a_verify.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+a_verify.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+a_verify.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+a_verify.o: ../../include/openssl/x509_vfy.h ../cryptlib.h a_verify.c
+a_verify.o: asn1_locl.h
+ameth_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+ameth_lib.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+ameth_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+ameth_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ameth_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ameth_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+ameth_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+ameth_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ameth_lib.o: ../../include/openssl/opensslconf.h
+ameth_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ameth_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+ameth_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ameth_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+ameth_lib.o: ../../include/openssl/x509_vfy.h ../cryptlib.h ameth_lib.c
+ameth_lib.o: asn1_locl.h
+asn1_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+asn1_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+asn1_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+asn1_err.o: ../../include/openssl/opensslconf.h
+asn1_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+asn1_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+asn1_err.o: ../../include/openssl/symhacks.h asn1_err.c
+asn1_gen.o: ../../e_os.h ../../include/openssl/asn1.h
+asn1_gen.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+asn1_gen.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+asn1_gen.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+asn1_gen.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+asn1_gen.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+asn1_gen.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+asn1_gen.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+asn1_gen.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+asn1_gen.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+asn1_gen.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+asn1_gen.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+asn1_gen.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+asn1_gen.o: ../cryptlib.h asn1_gen.c
+asn1_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+asn1_lib.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
+asn1_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+asn1_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+asn1_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+asn1_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+asn1_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+asn1_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h asn1_lib.c
+asn1_par.o: ../../e_os.h ../../include/openssl/asn1.h
+asn1_par.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+asn1_par.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+asn1_par.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+asn1_par.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+asn1_par.o: ../../include/openssl/opensslconf.h
+asn1_par.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+asn1_par.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+asn1_par.o: ../../include/openssl/symhacks.h ../cryptlib.h asn1_par.c
+asn_mime.o: ../../e_os.h ../../include/openssl/asn1.h
+asn_mime.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+asn_mime.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+asn_mime.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+asn_mime.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+asn_mime.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+asn_mime.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+asn_mime.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+asn_mime.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+asn_mime.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+asn_mime.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+asn_mime.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+asn_mime.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+asn_mime.o: ../cryptlib.h asn1_locl.h asn_mime.c
+asn_moid.o: ../../e_os.h ../../include/openssl/asn1.h
+asn_moid.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+asn_moid.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+asn_moid.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+asn_moid.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+asn_moid.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+asn_moid.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+asn_moid.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+asn_moid.o: ../../include/openssl/opensslconf.h
+asn_moid.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+asn_moid.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+asn_moid.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+asn_moid.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+asn_moid.o: ../../include/openssl/x509_vfy.h ../cryptlib.h asn_moid.c
+asn_pack.o: ../../e_os.h ../../include/openssl/asn1.h
+asn_pack.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+asn_pack.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+asn_pack.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+asn_pack.o: ../../include/openssl/opensslconf.h
+asn_pack.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+asn_pack.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+asn_pack.o: ../../include/openssl/symhacks.h ../cryptlib.h asn_pack.c
+bio_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+bio_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+bio_asn1.o: ../../include/openssl/opensslconf.h
+bio_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bio_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bio_asn1.o: ../../include/openssl/symhacks.h bio_asn1.c
+bio_ndef.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+bio_ndef.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+bio_ndef.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bio_ndef.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bio_ndef.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bio_ndef.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bio_ndef.o: ../../include/openssl/symhacks.h bio_ndef.c
+d2i_pr.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+d2i_pr.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+d2i_pr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+d2i_pr.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+d2i_pr.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+d2i_pr.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+d2i_pr.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+d2i_pr.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+d2i_pr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+d2i_pr.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+d2i_pr.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+d2i_pr.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+d2i_pr.o: ../../include/openssl/x509_vfy.h ../cryptlib.h asn1_locl.h d2i_pr.c
+d2i_pu.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+d2i_pu.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+d2i_pu.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+d2i_pu.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+d2i_pu.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+d2i_pu.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+d2i_pu.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+d2i_pu.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+d2i_pu.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+d2i_pu.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+d2i_pu.o: ../cryptlib.h d2i_pu.c
+evp_asn1.o: ../../e_os.h ../../include/openssl/asn1.h
+evp_asn1.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
+evp_asn1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+evp_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+evp_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+evp_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+evp_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+evp_asn1.o: ../../include/openssl/symhacks.h ../cryptlib.h evp_asn1.c
+f_enum.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+f_enum.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+f_enum.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+f_enum.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+f_enum.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+f_enum.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+f_enum.o: ../../include/openssl/symhacks.h ../cryptlib.h f_enum.c
+f_int.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+f_int.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+f_int.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+f_int.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+f_int.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+f_int.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+f_int.o: ../../include/openssl/symhacks.h ../cryptlib.h f_int.c
+f_string.o: ../../e_os.h ../../include/openssl/asn1.h
+f_string.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+f_string.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+f_string.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+f_string.o: ../../include/openssl/opensslconf.h
+f_string.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+f_string.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+f_string.o: ../../include/openssl/symhacks.h ../cryptlib.h f_string.c
+i2d_pr.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+i2d_pr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+i2d_pr.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+i2d_pr.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+i2d_pr.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+i2d_pr.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+i2d_pr.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+i2d_pr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+i2d_pr.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+i2d_pr.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+i2d_pr.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+i2d_pr.o: ../../include/openssl/x509_vfy.h ../cryptlib.h asn1_locl.h i2d_pr.c
+i2d_pu.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+i2d_pu.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+i2d_pu.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+i2d_pu.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+i2d_pu.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+i2d_pu.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+i2d_pu.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+i2d_pu.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+i2d_pu.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+i2d_pu.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+i2d_pu.o: ../cryptlib.h i2d_pu.c
+n_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
+n_pkey.o: ../../include/openssl/asn1_mac.h ../../include/openssl/asn1t.h
+n_pkey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+n_pkey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+n_pkey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+n_pkey.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+n_pkey.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+n_pkey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+n_pkey.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+n_pkey.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+n_pkey.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+n_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+n_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+n_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h n_pkey.c
+nsseq.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+nsseq.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+nsseq.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+nsseq.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+nsseq.o: ../../include/openssl/ecdsa.h ../../include/openssl/evp.h
+nsseq.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+nsseq.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+nsseq.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+nsseq.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+nsseq.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+nsseq.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+nsseq.o: ../../include/openssl/x509_vfy.h nsseq.c
+p5_pbe.o: ../../e_os.h ../../include/openssl/asn1.h
+p5_pbe.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+p5_pbe.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+p5_pbe.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+p5_pbe.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+p5_pbe.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+p5_pbe.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p5_pbe.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p5_pbe.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p5_pbe.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+p5_pbe.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p5_pbe.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p5_pbe.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p5_pbe.o: ../cryptlib.h p5_pbe.c
+p5_pbev2.o: ../../e_os.h ../../include/openssl/asn1.h
+p5_pbev2.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+p5_pbev2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+p5_pbev2.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+p5_pbev2.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+p5_pbev2.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+p5_pbev2.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p5_pbev2.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p5_pbev2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p5_pbev2.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+p5_pbev2.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p5_pbev2.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p5_pbev2.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p5_pbev2.o: ../cryptlib.h p5_pbev2.c
+p8_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
+p8_pkey.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+p8_pkey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+p8_pkey.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+p8_pkey.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+p8_pkey.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+p8_pkey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p8_pkey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p8_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p8_pkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+p8_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p8_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p8_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p8_pkey.c
+t_bitst.o: ../../e_os.h ../../include/openssl/asn1.h
+t_bitst.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+t_bitst.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+t_bitst.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+t_bitst.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+t_bitst.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+t_bitst.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+t_bitst.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+t_bitst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+t_bitst.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+t_bitst.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+t_bitst.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+t_bitst.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+t_bitst.o: ../cryptlib.h t_bitst.c
+t_crl.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+t_crl.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+t_crl.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+t_crl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+t_crl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+t_crl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+t_crl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+t_crl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+t_crl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+t_crl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+t_crl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+t_crl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+t_crl.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+t_crl.o: ../cryptlib.h t_crl.c
+t_pkey.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+t_pkey.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+t_pkey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+t_pkey.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+t_pkey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+t_pkey.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+t_pkey.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+t_pkey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+t_pkey.o: ../cryptlib.h t_pkey.c
+t_req.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+t_req.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+t_req.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+t_req.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+t_req.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+t_req.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+t_req.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+t_req.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+t_req.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+t_req.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+t_req.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+t_req.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+t_req.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+t_req.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+t_req.o: ../cryptlib.h t_req.c
+t_spki.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+t_spki.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+t_spki.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+t_spki.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+t_spki.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+t_spki.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+t_spki.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+t_spki.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+t_spki.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+t_spki.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+t_spki.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+t_spki.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+t_spki.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+t_spki.o: ../cryptlib.h t_spki.c
+t_x509.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+t_x509.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+t_x509.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+t_x509.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+t_x509.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+t_x509.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+t_x509.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+t_x509.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+t_x509.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+t_x509.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+t_x509.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+t_x509.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+t_x509.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+t_x509.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+t_x509.o: ../cryptlib.h t_x509.c
+t_x509a.o: ../../e_os.h ../../include/openssl/asn1.h
+t_x509a.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+t_x509a.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+t_x509a.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+t_x509a.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+t_x509a.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+t_x509a.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+t_x509a.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+t_x509a.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+t_x509a.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+t_x509a.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+t_x509a.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+t_x509a.o: ../cryptlib.h t_x509a.c
+tasn_dec.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+tasn_dec.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+tasn_dec.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+tasn_dec.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+tasn_dec.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+tasn_dec.o: ../../include/openssl/opensslconf.h
+tasn_dec.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tasn_dec.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+tasn_dec.o: ../../include/openssl/symhacks.h tasn_dec.c
+tasn_enc.o: ../../e_os.h ../../include/openssl/asn1.h
+tasn_enc.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+tasn_enc.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+tasn_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+tasn_enc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+tasn_enc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+tasn_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tasn_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+tasn_enc.o: ../../include/openssl/symhacks.h ../cryptlib.h tasn_enc.c
+tasn_fre.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+tasn_fre.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+tasn_fre.o: ../../include/openssl/e_os2.h ../../include/openssl/obj_mac.h
+tasn_fre.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+tasn_fre.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tasn_fre.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+tasn_fre.o: ../../include/openssl/symhacks.h tasn_fre.c
+tasn_new.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+tasn_new.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+tasn_new.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+tasn_new.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+tasn_new.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+tasn_new.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tasn_new.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+tasn_new.o: ../../include/openssl/symhacks.h tasn_new.c
+tasn_prn.o: ../../e_os.h ../../include/openssl/asn1.h
+tasn_prn.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+tasn_prn.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+tasn_prn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+tasn_prn.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+tasn_prn.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+tasn_prn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+tasn_prn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+tasn_prn.o: ../../include/openssl/opensslconf.h
+tasn_prn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tasn_prn.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+tasn_prn.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+tasn_prn.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+tasn_prn.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+tasn_prn.o: ../cryptlib.h asn1_locl.h tasn_prn.c
+tasn_typ.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+tasn_typ.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+tasn_typ.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+tasn_typ.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tasn_typ.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+tasn_typ.o: ../../include/openssl/symhacks.h tasn_typ.c
+tasn_utl.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+tasn_utl.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+tasn_utl.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+tasn_utl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+tasn_utl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+tasn_utl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tasn_utl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+tasn_utl.o: ../../include/openssl/symhacks.h tasn_utl.c
+x_algor.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+x_algor.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x_algor.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x_algor.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x_algor.o: ../../include/openssl/ecdsa.h ../../include/openssl/evp.h
+x_algor.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x_algor.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x_algor.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x_algor.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x_algor.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x_algor.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x_algor.o: ../../include/openssl/x509_vfy.h x_algor.c
+x_attrib.o: ../../e_os.h ../../include/openssl/asn1.h
+x_attrib.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+x_attrib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+x_attrib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x_attrib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x_attrib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x_attrib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x_attrib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x_attrib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x_attrib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x_attrib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x_attrib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x_attrib.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_attrib.c
+x_bignum.o: ../../e_os.h ../../include/openssl/asn1.h
+x_bignum.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+x_bignum.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+x_bignum.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x_bignum.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+x_bignum.o: ../../include/openssl/opensslconf.h
+x_bignum.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x_bignum.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+x_bignum.o: ../../include/openssl/symhacks.h ../cryptlib.h x_bignum.c
+x_crl.o: ../../e_os.h ../../include/openssl/asn1.h
+x_crl.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+x_crl.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+x_crl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x_crl.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x_crl.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+x_crl.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+x_crl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x_crl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x_crl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+x_crl.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x_crl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x_crl.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x_crl.o: ../../include/openssl/x509v3.h ../cryptlib.h asn1_locl.h x_crl.c
+x_exten.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+x_exten.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x_exten.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x_exten.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x_exten.o: ../../include/openssl/ecdsa.h ../../include/openssl/evp.h
+x_exten.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x_exten.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x_exten.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x_exten.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x_exten.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x_exten.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x_exten.o: ../../include/openssl/x509_vfy.h x_exten.c
+x_info.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+x_info.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+x_info.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x_info.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x_info.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x_info.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x_info.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x_info.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x_info.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x_info.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x_info.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x_info.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_info.c
+x_long.o: ../../e_os.h ../../include/openssl/asn1.h
+x_long.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+x_long.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+x_long.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x_long.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+x_long.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x_long.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+x_long.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x_long.o: ../cryptlib.h x_long.c
+x_name.o: ../../e_os.h ../../include/openssl/asn1.h
+x_name.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+x_name.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+x_name.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x_name.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x_name.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x_name.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x_name.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x_name.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x_name.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x_name.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x_name.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x_name.o: ../../include/openssl/x509_vfy.h ../cryptlib.h asn1_locl.h x_name.c
+x_nx509.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+x_nx509.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x_nx509.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x_nx509.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x_nx509.o: ../../include/openssl/ecdsa.h ../../include/openssl/evp.h
+x_nx509.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x_nx509.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x_nx509.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x_nx509.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x_nx509.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x_nx509.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x_nx509.o: ../../include/openssl/x509_vfy.h x_nx509.c
+x_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
+x_pkey.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
+x_pkey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+x_pkey.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x_pkey.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x_pkey.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x_pkey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x_pkey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x_pkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_pkey.c
+x_pubkey.o: ../../e_os.h ../../include/openssl/asn1.h
+x_pubkey.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+x_pubkey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+x_pubkey.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+x_pubkey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x_pubkey.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+x_pubkey.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+x_pubkey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x_pubkey.o: ../../include/openssl/opensslconf.h
+x_pubkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x_pubkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+x_pubkey.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x_pubkey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x_pubkey.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x_pubkey.o: ../cryptlib.h asn1_locl.h x_pubkey.c
+x_req.o: ../../e_os.h ../../include/openssl/asn1.h
+x_req.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+x_req.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+x_req.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x_req.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x_req.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x_req.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x_req.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x_req.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x_req.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x_req.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x_req.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x_req.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_req.c
+x_sig.o: ../../e_os.h ../../include/openssl/asn1.h
+x_sig.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+x_sig.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+x_sig.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x_sig.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x_sig.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x_sig.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x_sig.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x_sig.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x_sig.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x_sig.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x_sig.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x_sig.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_sig.c
+x_spki.o: ../../e_os.h ../../include/openssl/asn1.h
+x_spki.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+x_spki.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+x_spki.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x_spki.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x_spki.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x_spki.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x_spki.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x_spki.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x_spki.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x_spki.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x_spki.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x_spki.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_spki.c
+x_val.o: ../../e_os.h ../../include/openssl/asn1.h
+x_val.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+x_val.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+x_val.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x_val.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x_val.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x_val.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x_val.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x_val.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x_val.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x_val.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x_val.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x_val.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_val.c
+x_x509.o: ../../e_os.h ../../include/openssl/asn1.h
+x_x509.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+x_x509.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+x_x509.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x_x509.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x_x509.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+x_x509.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+x_x509.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x_x509.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x_x509.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+x_x509.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x_x509.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x_x509.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x_x509.o: ../../include/openssl/x509v3.h ../cryptlib.h x_x509.c
+x_x509a.o: ../../e_os.h ../../include/openssl/asn1.h
+x_x509a.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+x_x509a.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+x_x509a.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x_x509a.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x_x509a.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x_x509a.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x_x509a.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x_x509a.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x_x509a.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x_x509a.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x_x509a.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x_x509a.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_x509a.c
diff --git a/openssl/crypto/asn1/a_bitstr.c b/openssl/crypto/asn1/a_bitstr.c
new file mode 100644
index 0000000..3417996
--- /dev/null
+++ b/openssl/crypto/asn1/a_bitstr.c
@@ -0,0 +1,248 @@
+/* crypto/asn1/a_bitstr.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+
+int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
+{ return M_ASN1_BIT_STRING_set(x, d, len); }
+
+int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
+	{
+	int ret,j,bits,len;
+	unsigned char *p,*d;
+
+	if (a == NULL) return(0);
+
+	len=a->length;
+
+	if (len > 0)
+		{
+		if (a->flags & ASN1_STRING_FLAG_BITS_LEFT)
+			{
+			bits=(int)a->flags&0x07;
+			}
+		else
+			{
+			for ( ; len > 0; len--)
+				{
+				if (a->data[len-1]) break;
+				}
+			j=a->data[len-1];
+			if      (j & 0x01) bits=0;
+			else if (j & 0x02) bits=1;
+			else if (j & 0x04) bits=2;
+			else if (j & 0x08) bits=3;
+			else if (j & 0x10) bits=4;
+			else if (j & 0x20) bits=5;
+			else if (j & 0x40) bits=6;
+			else if (j & 0x80) bits=7;
+			else bits=0; /* should not happen */
+			}
+		}
+	else
+		bits=0;
+
+	ret=1+len;
+	if (pp == NULL) return(ret);
+
+	p= *pp;
+
+	*(p++)=(unsigned char)bits;
+	d=a->data;
+	memcpy(p,d,len);
+	p+=len;
+	if (len > 0) p[-1]&=(0xff<<bits);
+	*pp=p;
+	return(ret);
+	}
+
+ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
+	const unsigned char **pp, long len)
+	{
+	ASN1_BIT_STRING *ret=NULL;
+	const unsigned char *p;
+	unsigned char *s;
+	int i;
+
+	if (len < 1)
+		{
+		i=ASN1_R_STRING_TOO_SHORT;
+		goto err;
+		}
+
+	if ((a == NULL) || ((*a) == NULL))
+		{
+		if ((ret=M_ASN1_BIT_STRING_new()) == NULL) return(NULL);
+		}
+	else
+		ret=(*a);
+
+	p= *pp;
+	i= *(p++);
+	/* We do this to preserve the settings.  If we modify
+	 * the settings, via the _set_bit function, we will recalculate
+	 * on output */
+	ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
+	ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
+
+	if (len-- > 1) /* using one because of the bits left byte */
+		{
+		s=(unsigned char *)OPENSSL_malloc((int)len);
+		if (s == NULL)
+			{
+			i=ERR_R_MALLOC_FAILURE;
+			goto err;
+			}
+		memcpy(s,p,(int)len);
+		s[len-1]&=(0xff<<i);
+		p+=len;
+		}
+	else
+		s=NULL;
+
+	ret->length=(int)len;
+	if (ret->data != NULL) OPENSSL_free(ret->data);
+	ret->data=s;
+	ret->type=V_ASN1_BIT_STRING;
+	if (a != NULL) (*a)=ret;
+	*pp=p;
+	return(ret);
+err:
+	ASN1err(ASN1_F_C2I_ASN1_BIT_STRING,i);
+	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+		M_ASN1_BIT_STRING_free(ret);
+	return(NULL);
+	}
+
+/* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
+ */
+int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
+	{
+	int w,v,iv;
+	unsigned char *c;
+
+	w=n/8;
+	v=1<<(7-(n&0x07));
+	iv= ~v;
+	if (!value) v=0;
+
+	if (a == NULL)
+		return 0;
+
+	a->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear, set on write */
+
+	if ((a->length < (w+1)) || (a->data == NULL))
+		{
+		if (!value) return(1); /* Don't need to set */
+		if (a->data == NULL)
+			c=(unsigned char *)OPENSSL_malloc(w+1);
+		else
+			c=(unsigned char *)OPENSSL_realloc_clean(a->data,
+								 a->length,
+								 w+1);
+		if (c == NULL)
+			{
+			ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT,ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+  		if (w+1-a->length > 0) memset(c+a->length, 0, w+1-a->length);
+		a->data=c;
+		a->length=w+1;
+	}
+	a->data[w]=((a->data[w])&iv)|v;
+	while ((a->length > 0) && (a->data[a->length-1] == 0))
+		a->length--;
+	return(1);
+	}
+
+int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
+	{
+	int w,v;
+
+	w=n/8;
+	v=1<<(7-(n&0x07));
+	if ((a == NULL) || (a->length < (w+1)) || (a->data == NULL))
+		return(0);
+	return((a->data[w]&v) != 0);
+	}
+
+/*
+ * Checks if the given bit string contains only bits specified by 
+ * the flags vector. Returns 0 if there is at least one bit set in 'a'
+ * which is not specified in 'flags', 1 otherwise.
+ * 'len' is the length of 'flags'.
+ */
+int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
+			  unsigned char *flags, int flags_len)
+	{
+	int i, ok;
+	/* Check if there is one bit set at all. */
+	if (!a || !a->data) return 1;
+
+	/* Check each byte of the internal representation of the bit string. */
+	ok = 1;
+	for (i = 0; i < a->length && ok; ++i)
+		{
+		unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
+		/* We are done if there is an unneeded bit set. */
+		ok = (a->data[i] & mask) == 0;
+		}
+	return ok;
+	}
diff --git a/openssl/crypto/asn1/a_bool.c b/openssl/crypto/asn1/a_bool.c
new file mode 100644
index 0000000..331acdf
--- /dev/null
+++ b/openssl/crypto/asn1/a_bool.c
@@ -0,0 +1,114 @@
+/* crypto/asn1/a_bool.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+
+int i2d_ASN1_BOOLEAN(int a, unsigned char **pp)
+	{
+	int r;
+	unsigned char *p;
+
+	r=ASN1_object_size(0,1,V_ASN1_BOOLEAN);
+	if (pp == NULL) return(r);
+	p= *pp;
+
+	ASN1_put_object(&p,0,1,V_ASN1_BOOLEAN,V_ASN1_UNIVERSAL);
+	*(p++)= (unsigned char)a;
+	*pp=p;
+	return(r);
+	}
+
+int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length)
+	{
+	int ret= -1;
+	const unsigned char *p;
+	long len;
+	int inf,tag,xclass;
+	int i=0;
+
+	p= *pp;
+	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
+	if (inf & 0x80)
+		{
+		i=ASN1_R_BAD_OBJECT_HEADER;
+		goto err;
+		}
+
+	if (tag != V_ASN1_BOOLEAN)
+		{
+		i=ASN1_R_EXPECTING_A_BOOLEAN;
+		goto err;
+		}
+
+	if (len != 1)
+		{
+		i=ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
+		goto err;
+		}
+	ret= (int)*(p++);
+	if (a != NULL) (*a)=ret;
+	*pp=p;
+	return(ret);
+err:
+	ASN1err(ASN1_F_D2I_ASN1_BOOLEAN,i);
+	return(ret);
+	}
+
+
diff --git a/openssl/crypto/asn1/a_bytes.c b/openssl/crypto/asn1/a_bytes.c
new file mode 100644
index 0000000..92d630c
--- /dev/null
+++ b/openssl/crypto/asn1/a_bytes.c
@@ -0,0 +1,314 @@
+/* crypto/asn1/a_bytes.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+
+static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c);
+/* type is a 'bitmap' of acceptable string types.
+ */
+ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
+	     long length, int type)
+	{
+	ASN1_STRING *ret=NULL;
+	const unsigned char *p;
+	unsigned char *s;
+	long len;
+	int inf,tag,xclass;
+	int i=0;
+
+	p= *pp;
+	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
+	if (inf & 0x80) goto err;
+
+	if (tag >= 32)
+		{
+		i=ASN1_R_TAG_VALUE_TOO_HIGH;
+		goto err;
+		}
+	if (!(ASN1_tag2bit(tag) & type))
+		{
+		i=ASN1_R_WRONG_TYPE;
+		goto err;
+		}
+
+	/* If a bit-string, exit early */
+	if (tag == V_ASN1_BIT_STRING)
+		return(d2i_ASN1_BIT_STRING(a,pp,length));
+
+	if ((a == NULL) || ((*a) == NULL))
+		{
+		if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
+		}
+	else
+		ret=(*a);
+
+	if (len != 0)
+		{
+		s=(unsigned char *)OPENSSL_malloc((int)len+1);
+		if (s == NULL)
+			{
+			i=ERR_R_MALLOC_FAILURE;
+			goto err;
+			}
+		memcpy(s,p,(int)len);
+		s[len]='\0';
+		p+=len;
+		}
+	else
+		s=NULL;
+
+	if (ret->data != NULL) OPENSSL_free(ret->data);
+	ret->length=(int)len;
+	ret->data=s;
+	ret->type=tag;
+	if (a != NULL) (*a)=ret;
+	*pp=p;
+	return(ret);
+err:
+	ASN1err(ASN1_F_D2I_ASN1_TYPE_BYTES,i);
+	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+		ASN1_STRING_free(ret);
+	return(NULL);
+	}
+
+int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass)
+	{
+	int ret,r,constructed;
+	unsigned char *p;
+
+	if (a == NULL)  return(0);
+
+	if (tag == V_ASN1_BIT_STRING)
+		return(i2d_ASN1_BIT_STRING(a,pp));
+		
+	ret=a->length;
+	r=ASN1_object_size(0,ret,tag);
+	if (pp == NULL) return(r);
+	p= *pp;
+
+	if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
+		constructed=1;
+	else
+		constructed=0;
+	ASN1_put_object(&p,constructed,ret,tag,xclass);
+	memcpy(p,a->data,a->length);
+	p+=a->length;
+	*pp= p;
+	return(r);
+	}
+
+ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
+	     long length, int Ptag, int Pclass)
+	{
+	ASN1_STRING *ret=NULL;
+	const unsigned char *p;
+	unsigned char *s;
+	long len;
+	int inf,tag,xclass;
+	int i=0;
+
+	if ((a == NULL) || ((*a) == NULL))
+		{
+		if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
+		}
+	else
+		ret=(*a);
+
+	p= *pp;
+	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
+	if (inf & 0x80)
+		{
+		i=ASN1_R_BAD_OBJECT_HEADER;
+		goto err;
+		}
+
+	if (tag != Ptag)
+		{
+		i=ASN1_R_WRONG_TAG;
+		goto err;
+		}
+
+	if (inf & V_ASN1_CONSTRUCTED)
+		{
+		ASN1_const_CTX c;
+
+		c.pp=pp;
+		c.p=p;
+		c.inf=inf;
+		c.slen=len;
+		c.tag=Ptag;
+		c.xclass=Pclass;
+		c.max=(length == 0)?0:(p+length);
+		if (!asn1_collate_primitive(ret,&c)) 
+			goto err; 
+		else
+			{
+			p=c.p;
+			}
+		}
+	else
+		{
+		if (len != 0)
+			{
+			if ((ret->length < len) || (ret->data == NULL))
+				{
+				if (ret->data != NULL) OPENSSL_free(ret->data);
+				s=(unsigned char *)OPENSSL_malloc((int)len + 1);
+				if (s == NULL)
+					{
+					i=ERR_R_MALLOC_FAILURE;
+					goto err;
+					}
+				}
+			else
+				s=ret->data;
+			memcpy(s,p,(int)len);
+			s[len] = '\0';
+			p+=len;
+			}
+		else
+			{
+			s=NULL;
+			if (ret->data != NULL) OPENSSL_free(ret->data);
+			}
+
+		ret->length=(int)len;
+		ret->data=s;
+		ret->type=Ptag;
+		}
+
+	if (a != NULL) (*a)=ret;
+	*pp=p;
+	return(ret);
+err:
+	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+		ASN1_STRING_free(ret);
+	ASN1err(ASN1_F_D2I_ASN1_BYTES,i);
+	return(NULL);
+	}
+
+
+/* We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse
+ * them into the one structure that is then returned */
+/* There have been a few bug fixes for this function from
+ * Paul Keogh <paul.keogh@sse.ie>, many thanks to him */
+static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
+	{
+	ASN1_STRING *os=NULL;
+	BUF_MEM b;
+	int num;
+
+	b.length=0;
+	b.max=0;
+	b.data=NULL;
+
+	if (a == NULL)
+		{
+		c->error=ERR_R_PASSED_NULL_PARAMETER;
+		goto err;
+		}
+
+	num=0;
+	for (;;)
+		{
+		if (c->inf & 1)
+			{
+			c->eos=ASN1_const_check_infinite_end(&c->p,
+				(long)(c->max-c->p));
+			if (c->eos) break;
+			}
+		else
+			{
+			if (c->slen <= 0) break;
+			}
+
+		c->q=c->p;
+		if (d2i_ASN1_bytes(&os,&c->p,c->max-c->p,c->tag,c->xclass)
+			== NULL)
+			{
+			c->error=ERR_R_ASN1_LIB;
+			goto err;
+			}
+
+		if (!BUF_MEM_grow_clean(&b,num+os->length))
+			{
+			c->error=ERR_R_BUF_LIB;
+			goto err;
+			}
+		memcpy(&(b.data[num]),os->data,os->length);
+		if (!(c->inf & 1))
+			c->slen-=(c->p-c->q);
+		num+=os->length;
+		}
+
+	if (!asn1_const_Finish(c)) goto err;
+
+	a->length=num;
+	if (a->data != NULL) OPENSSL_free(a->data);
+	a->data=(unsigned char *)b.data;
+	if (os != NULL) ASN1_STRING_free(os);
+	return(1);
+err:
+	ASN1err(ASN1_F_ASN1_COLLATE_PRIMITIVE,c->error);
+	if (os != NULL) ASN1_STRING_free(os);
+	if (b.data != NULL) OPENSSL_free(b.data);
+	return(0);
+	}
+
diff --git a/openssl/crypto/asn1/a_d2i_fp.c b/openssl/crypto/asn1/a_d2i_fp.c
new file mode 100644
index 0000000..ece40bc
--- /dev/null
+++ b/openssl/crypto/asn1/a_d2i_fp.c
@@ -0,0 +1,260 @@
+/* crypto/asn1/a_d2i_fp.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1_mac.h>
+
+static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
+
+#ifndef NO_OLD_ASN1
+#ifndef OPENSSL_NO_FP_API
+
+void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x)
+        {
+        BIO *b;
+        void *ret;
+
+        if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_D2I_FP,ERR_R_BUF_LIB);
+                return(NULL);
+		}
+        BIO_set_fp(b,in,BIO_NOCLOSE);
+        ret=ASN1_d2i_bio(xnew,d2i,b,x);
+        BIO_free(b);
+        return(ret);
+        }
+#endif
+
+void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x)
+	{
+	BUF_MEM *b = NULL;
+	const unsigned char *p;
+	void *ret=NULL;
+	int len;
+
+	len = asn1_d2i_read_bio(in, &b);
+	if(len < 0) goto err;
+
+	p=(unsigned char *)b->data;
+	ret=d2i(x,&p,len);
+err:
+	if (b != NULL) BUF_MEM_free(b);
+	return(ret);
+	}
+
+#endif
+
+void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
+	{
+	BUF_MEM *b = NULL;
+	const unsigned char *p;
+	void *ret=NULL;
+	int len;
+
+	len = asn1_d2i_read_bio(in, &b);
+	if(len < 0) goto err;
+
+	p=(const unsigned char *)b->data;
+	ret=ASN1_item_d2i(x,&p,len, it);
+err:
+	if (b != NULL) BUF_MEM_free(b);
+	return(ret);
+	}
+
+#ifndef OPENSSL_NO_FP_API
+void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
+        {
+        BIO *b;
+        char *ret;
+
+        if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_ITEM_D2I_FP,ERR_R_BUF_LIB);
+                return(NULL);
+		}
+        BIO_set_fp(b,in,BIO_NOCLOSE);
+        ret=ASN1_item_d2i_bio(it,b,x);
+        BIO_free(b);
+        return(ret);
+        }
+#endif
+
+#define HEADER_SIZE   8
+static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
+	{
+	BUF_MEM *b;
+	unsigned char *p;
+	int i;
+	int ret=-1;
+	ASN1_const_CTX c;
+	int want=HEADER_SIZE;
+	int eos=0;
+#if defined(__GNUC__) && defined(__ia64)
+	/* pathetic compiler bug in all known versions as of Nov. 2002 */
+	long off=0;
+#else
+	int off=0;
+#endif
+	int len=0;
+
+	b=BUF_MEM_new();
+	if (b == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
+		return -1;
+		}
+
+	ERR_clear_error();
+	for (;;)
+		{
+		if (want >= (len-off))
+			{
+			want-=(len-off);
+
+			if (!BUF_MEM_grow_clean(b,len+want))
+				{
+				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			i=BIO_read(in,&(b->data[len]),want);
+			if ((i < 0) && ((len-off) == 0))
+				{
+				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_NOT_ENOUGH_DATA);
+				goto err;
+				}
+			if (i > 0)
+				len+=i;
+			}
+		/* else data already loaded */
+
+		p=(unsigned char *)&(b->data[off]);
+		c.p=p;
+		c.inf=ASN1_get_object(&(c.p),&(c.slen),&(c.tag),&(c.xclass),
+			len-off);
+		if (c.inf & 0x80)
+			{
+			unsigned long e;
+
+			e=ERR_GET_REASON(ERR_peek_error());
+			if (e != ASN1_R_TOO_LONG)
+				goto err;
+			else
+				ERR_clear_error(); /* clear error */
+			}
+		i=c.p-p;/* header length */
+		off+=i;	/* end of data */
+
+		if (c.inf & 1)
+			{
+			/* no data body so go round again */
+			eos++;
+			want=HEADER_SIZE;
+			}
+		else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC))
+			{
+			/* eos value, so go back and read another header */
+			eos--;
+			if (eos <= 0)
+				break;
+			else
+				want=HEADER_SIZE;
+			}
+		else 
+			{
+			/* suck in c.slen bytes of data */
+			want=(int)c.slen;
+			if (want > (len-off))
+				{
+				want-=(len-off);
+				if (!BUF_MEM_grow_clean(b,len+want))
+					{
+					ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
+					goto err;
+					}
+				while (want > 0)
+					{
+					i=BIO_read(in,&(b->data[len]),want);
+					if (i <= 0)
+						{
+						ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
+						    ASN1_R_NOT_ENOUGH_DATA);
+						goto err;
+						}
+					len+=i;
+					want -= i;
+					}
+				}
+			off+=(int)c.slen;
+			if (eos <= 0)
+				{
+				break;
+				}
+			else
+				want=HEADER_SIZE;
+			}
+		}
+
+	*pb = b;
+	return off;
+err:
+	if (b != NULL) BUF_MEM_free(b);
+	return(ret);
+	}
diff --git a/openssl/crypto/asn1/a_digest.c b/openssl/crypto/asn1/a_digest.c
new file mode 100644
index 0000000..d00d9e2
--- /dev/null
+++ b/openssl/crypto/asn1/a_digest.c
@@ -0,0 +1,111 @@
+/* crypto/asn1/a_digest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <time.h>
+
+#include "cryptlib.h"
+
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/buffer.h>
+#include <openssl/x509.h>
+
+#ifndef NO_ASN1_OLD
+
+int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
+		unsigned char *md, unsigned int *len)
+	{
+	int i;
+	unsigned char *str,*p;
+
+	i=i2d(data,NULL);
+	if ((str=(unsigned char *)OPENSSL_malloc(i)) == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_DIGEST,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	p=str;
+	i2d(data,&p);
+
+	EVP_Digest(str, i, md, len, type, NULL);
+	OPENSSL_free(str);
+	return(1);
+	}
+
+#endif
+
+
+int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
+		unsigned char *md, unsigned int *len)
+	{
+	int i;
+	unsigned char *str = NULL;
+
+	i=ASN1_item_i2d(asn,&str, it);
+	if (!str) return(0);
+
+	EVP_Digest(str, i, md, len, type, NULL);
+	OPENSSL_free(str);
+	return(1);
+	}
+
diff --git a/openssl/crypto/asn1/a_dup.c b/openssl/crypto/asn1/a_dup.c
new file mode 100644
index 0000000..d989925
--- /dev/null
+++ b/openssl/crypto/asn1/a_dup.c
@@ -0,0 +1,109 @@
+/* crypto/asn1/a_dup.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+
+#ifndef NO_OLD_ASN1
+
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
+	{
+	unsigned char *b,*p;
+	const unsigned char *p2;
+	int i;
+	char *ret;
+
+	if (x == NULL) return(NULL);
+
+	i=i2d(x,NULL);
+	b=OPENSSL_malloc(i+10);
+	if (b == NULL)
+		{ ASN1err(ASN1_F_ASN1_DUP,ERR_R_MALLOC_FAILURE); return(NULL); }
+	p= b;
+	i=i2d(x,&p);
+	p2= b;
+	ret=d2i(NULL,&p2,i);
+	OPENSSL_free(b);
+	return(ret);
+	}
+
+#endif
+
+/* ASN1_ITEM version of dup: this follows the model above except we don't need
+ * to allocate the buffer. At some point this could be rewritten to directly dup
+ * the underlying structure instead of doing and encode and decode.
+ */
+
+void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
+	{
+	unsigned char *b = NULL;
+	const unsigned char *p;
+	long i;
+	void *ret;
+
+	if (x == NULL) return(NULL);
+
+	i=ASN1_item_i2d(x,&b,it);
+	if (b == NULL)
+		{ ASN1err(ASN1_F_ASN1_ITEM_DUP,ERR_R_MALLOC_FAILURE); return(NULL); }
+	p= b;
+	ret=ASN1_item_d2i(NULL,&p,i, it);
+	OPENSSL_free(b);
+	return(ret);
+	}
diff --git a/openssl/crypto/asn1/a_enum.c b/openssl/crypto/asn1/a_enum.c
new file mode 100644
index 0000000..fe9aa13
--- /dev/null
+++ b/openssl/crypto/asn1/a_enum.c
@@ -0,0 +1,182 @@
+/* crypto/asn1/a_enum.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/bn.h>
+
+/* 
+ * Code for ENUMERATED type: identical to INTEGER apart from a different tag.
+ * for comments on encoding see a_int.c
+ */
+
+int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
+	{
+	int j,k;
+	unsigned int i;
+	unsigned char buf[sizeof(long)+1];
+	long d;
+
+	a->type=V_ASN1_ENUMERATED;
+	if (a->length < (int)(sizeof(long)+1))
+		{
+		if (a->data != NULL)
+			OPENSSL_free(a->data);
+		if ((a->data=(unsigned char *)OPENSSL_malloc(sizeof(long)+1)) != NULL)
+			memset((char *)a->data,0,sizeof(long)+1);
+		}
+	if (a->data == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_ENUMERATED_SET,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	d=v;
+	if (d < 0)
+		{
+		d= -d;
+		a->type=V_ASN1_NEG_ENUMERATED;
+		}
+
+	for (i=0; i<sizeof(long); i++)
+		{
+		if (d == 0) break;
+		buf[i]=(int)d&0xff;
+		d>>=8;
+		}
+	j=0;
+	for (k=i-1; k >=0; k--)
+		a->data[j++]=buf[k];
+	a->length=j;
+	return(1);
+	}
+
+long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
+	{
+	int neg=0,i;
+	long r=0;
+
+	if (a == NULL) return(0L);
+	i=a->type;
+	if (i == V_ASN1_NEG_ENUMERATED)
+		neg=1;
+	else if (i != V_ASN1_ENUMERATED)
+		return -1;
+	
+	if (a->length > (int)sizeof(long))
+		{
+		/* hmm... a bit ugly */
+		return(0xffffffffL);
+		}
+	if (a->data == NULL)
+		return 0;
+
+	for (i=0; i<a->length; i++)
+		{
+		r<<=8;
+		r|=(unsigned char)a->data[i];
+		}
+	if (neg) r= -r;
+	return(r);
+	}
+
+ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
+	{
+	ASN1_ENUMERATED *ret;
+	int len,j;
+
+	if (ai == NULL)
+		ret=M_ASN1_ENUMERATED_new();
+	else
+		ret=ai;
+	if (ret == NULL)
+		{
+		ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED,ERR_R_NESTED_ASN1_ERROR);
+		goto err;
+		}
+	if(BN_is_negative(bn)) ret->type = V_ASN1_NEG_ENUMERATED;
+	else ret->type=V_ASN1_ENUMERATED;
+	j=BN_num_bits(bn);
+	len=((j == 0)?0:((j/8)+1));
+	if (ret->length < len+4)
+		{
+		unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
+		if (!new_data)
+			{
+			ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		ret->data=new_data;
+		}
+
+	ret->length=BN_bn2bin(bn,ret->data);
+	return(ret);
+err:
+	if (ret != ai) M_ASN1_ENUMERATED_free(ret);
+	return(NULL);
+	}
+
+BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
+	{
+	BIGNUM *ret;
+
+	if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
+		ASN1err(ASN1_F_ASN1_ENUMERATED_TO_BN,ASN1_R_BN_LIB);
+	else if(ai->type == V_ASN1_NEG_ENUMERATED) BN_set_negative(ret,1);
+	return(ret);
+	}
diff --git a/openssl/crypto/asn1/a_gentm.c b/openssl/crypto/asn1/a_gentm.c
new file mode 100644
index 0000000..c79c6f5
--- /dev/null
+++ b/openssl/crypto/asn1/a_gentm.c
@@ -0,0 +1,263 @@
+/* crypto/asn1/a_gentm.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* GENERALIZEDTIME implementation, written by Steve Henson. Based on UTCTIME */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "o_time.h"
+#include <openssl/asn1.h>
+
+#if 0
+
+int i2d_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME *a, unsigned char **pp)
+	{
+#ifdef CHARSET_EBCDIC
+	/* KLUDGE! We convert to ascii before writing DER */
+	int len;
+	char tmp[24];
+	ASN1_STRING tmpstr = *(ASN1_STRING *)a;
+
+	len = tmpstr.length;
+	ebcdic2ascii(tmp, tmpstr.data, (len >= sizeof tmp) ? sizeof tmp : len);
+	tmpstr.data = tmp;
+
+	a = (ASN1_GENERALIZEDTIME *) &tmpstr;
+#endif
+	return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
+		V_ASN1_GENERALIZEDTIME,V_ASN1_UNIVERSAL));
+	}
+
+
+ASN1_GENERALIZEDTIME *d2i_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME **a,
+	     unsigned char **pp, long length)
+	{
+	ASN1_GENERALIZEDTIME *ret=NULL;
+
+	ret=(ASN1_GENERALIZEDTIME *)d2i_ASN1_bytes((ASN1_STRING **)a,pp,length,
+		V_ASN1_GENERALIZEDTIME,V_ASN1_UNIVERSAL);
+	if (ret == NULL)
+		{
+		ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME,ERR_R_NESTED_ASN1_ERROR);
+		return(NULL);
+		}
+#ifdef CHARSET_EBCDIC
+	ascii2ebcdic(ret->data, ret->data, ret->length);
+#endif
+	if (!ASN1_GENERALIZEDTIME_check(ret))
+		{
+		ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME,ASN1_R_INVALID_TIME_FORMAT);
+		goto err;
+		}
+
+	return(ret);
+err:
+	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+		M_ASN1_GENERALIZEDTIME_free(ret);
+	return(NULL);
+	}
+
+#endif
+
+int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
+	{
+	static const int min[9]={ 0, 0, 1, 1, 0, 0, 0, 0, 0};
+	static const int max[9]={99, 99,12,31,23,59,59,12,59};
+	char *a;
+	int n,i,l,o;
+
+	if (d->type != V_ASN1_GENERALIZEDTIME) return(0);
+	l=d->length;
+	a=(char *)d->data;
+	o=0;
+	/* GENERALIZEDTIME is similar to UTCTIME except the year is
+         * represented as YYYY. This stuff treats everything as a two digit
+         * field so make first two fields 00 to 99
+         */
+	if (l < 13) goto err;
+	for (i=0; i<7; i++)
+		{
+		if ((i == 6) && ((a[o] == 'Z') ||
+			(a[o] == '+') || (a[o] == '-')))
+			{ i++; break; }
+		if ((a[o] < '0') || (a[o] > '9')) goto err;
+		n= a[o]-'0';
+		if (++o > l) goto err;
+
+		if ((a[o] < '0') || (a[o] > '9')) goto err;
+		n=(n*10)+ a[o]-'0';
+		if (++o > l) goto err;
+
+		if ((n < min[i]) || (n > max[i])) goto err;
+		}
+	/* Optional fractional seconds: decimal point followed by one
+	 * or more digits.
+	 */
+	if (a[o] == '.')
+		{
+		if (++o > l) goto err;
+		i = o;
+		while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
+			o++;
+		/* Must have at least one digit after decimal point */
+		if (i == o) goto err;
+		}
+
+	if (a[o] == 'Z')
+		o++;
+	else if ((a[o] == '+') || (a[o] == '-'))
+		{
+		o++;
+		if (o+4 > l) goto err;
+		for (i=7; i<9; i++)
+			{
+			if ((a[o] < '0') || (a[o] > '9')) goto err;
+			n= a[o]-'0';
+			o++;
+			if ((a[o] < '0') || (a[o] > '9')) goto err;
+			n=(n*10)+ a[o]-'0';
+			if ((n < min[i]) || (n > max[i])) goto err;
+			o++;
+			}
+		}
+	else
+		{
+		/* Missing time zone information. */
+		goto err;
+		}
+	return(o == l);
+err:
+	return(0);
+	}
+
+int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
+	{
+	ASN1_GENERALIZEDTIME t;
+
+	t.type=V_ASN1_GENERALIZEDTIME;
+	t.length=strlen(str);
+	t.data=(unsigned char *)str;
+	if (ASN1_GENERALIZEDTIME_check(&t))
+		{
+		if (s != NULL)
+			{
+			if (!ASN1_STRING_set((ASN1_STRING *)s,
+				(unsigned char *)str,t.length))
+				return 0;
+			s->type=V_ASN1_GENERALIZEDTIME;
+			}
+		return(1);
+		}
+	else
+		return(0);
+	}
+
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
+	     time_t t)
+	{
+		return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
+	}
+
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
+	     time_t t, int offset_day, long offset_sec)
+	{
+	char *p;
+	struct tm *ts;
+	struct tm data;
+	size_t len = 20; 
+
+	if (s == NULL)
+		s=M_ASN1_GENERALIZEDTIME_new();
+	if (s == NULL)
+		return(NULL);
+
+	ts=OPENSSL_gmtime(&t, &data);
+	if (ts == NULL)
+		return(NULL);
+
+	if (offset_day || offset_sec)
+		{ 
+		if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+			return NULL;
+		}
+
+	p=(char *)s->data;
+	if ((p == NULL) || ((size_t)s->length < len))
+		{
+		p=OPENSSL_malloc(len);
+		if (p == NULL)
+			{
+			ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ,
+				ERR_R_MALLOC_FAILURE);
+			return(NULL);
+			}
+		if (s->data != NULL)
+			OPENSSL_free(s->data);
+		s->data=(unsigned char *)p;
+		}
+
+	BIO_snprintf(p,len,"%04d%02d%02d%02d%02d%02dZ",ts->tm_year + 1900,
+		     ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
+	s->length=strlen(p);
+	s->type=V_ASN1_GENERALIZEDTIME;
+#ifdef CHARSET_EBCDIC_not
+	ebcdic2ascii(s->data, s->data, s->length);
+#endif
+	return(s);
+	}
diff --git a/openssl/crypto/asn1/a_i2d_fp.c b/openssl/crypto/asn1/a_i2d_fp.c
new file mode 100644
index 0000000..a3ad76d
--- /dev/null
+++ b/openssl/crypto/asn1/a_i2d_fp.c
@@ -0,0 +1,163 @@
+/* crypto/asn1/a_i2d_fp.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+
+#ifndef NO_OLD_ASN1
+
+#ifndef OPENSSL_NO_FP_API
+int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
+        {
+        BIO *b;
+        int ret;
+
+        if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_I2D_FP,ERR_R_BUF_LIB);
+                return(0);
+		}
+        BIO_set_fp(b,out,BIO_NOCLOSE);
+        ret=ASN1_i2d_bio(i2d,b,x);
+        BIO_free(b);
+        return(ret);
+        }
+#endif
+
+int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
+	{
+	char *b;
+	unsigned char *p;
+	int i,j=0,n,ret=1;
+
+	n=i2d(x,NULL);
+	b=(char *)OPENSSL_malloc(n);
+	if (b == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_I2D_BIO,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+
+	p=(unsigned char *)b;
+	i2d(x,&p);
+	
+	for (;;)
+		{
+		i=BIO_write(out,&(b[j]),n);
+		if (i == n) break;
+		if (i <= 0)
+			{
+			ret=0;
+			break;
+			}
+		j+=i;
+		n-=i;
+		}
+	OPENSSL_free(b);
+	return(ret);
+	}
+
+#endif
+
+#ifndef OPENSSL_NO_FP_API
+int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
+        {
+        BIO *b;
+        int ret;
+
+        if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_ITEM_I2D_FP,ERR_R_BUF_LIB);
+                return(0);
+		}
+        BIO_set_fp(b,out,BIO_NOCLOSE);
+        ret=ASN1_item_i2d_bio(it,b,x);
+        BIO_free(b);
+        return(ret);
+        }
+#endif
+
+int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
+	{
+	unsigned char *b = NULL;
+	int i,j=0,n,ret=1;
+
+	n = ASN1_item_i2d(x, &b, it);
+	if (b == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_ITEM_I2D_BIO,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+
+	for (;;)
+		{
+		i=BIO_write(out,&(b[j]),n);
+		if (i == n) break;
+		if (i <= 0)
+			{
+			ret=0;
+			break;
+			}
+		j+=i;
+		n-=i;
+		}
+	OPENSSL_free(b);
+	return(ret);
+	}
diff --git a/openssl/crypto/asn1/a_int.c b/openssl/crypto/asn1/a_int.c
new file mode 100644
index 0000000..3348b87
--- /dev/null
+++ b/openssl/crypto/asn1/a_int.c
@@ -0,0 +1,458 @@
+/* crypto/asn1/a_int.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/bn.h>
+
+ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
+{ return M_ASN1_INTEGER_dup(x);}
+
+int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
+	{ 
+	int neg, ret;
+	/* Compare signs */
+	neg = x->type & V_ASN1_NEG;
+	if (neg != (y->type & V_ASN1_NEG))
+		{
+		if (neg)
+			return -1;
+		else
+			return 1;
+		}
+
+	ret = ASN1_STRING_cmp(x, y);
+
+	if (neg)
+		return -ret;
+	else
+		return ret;
+	}
+	
+
+/* 
+ * This converts an ASN1 INTEGER into its content encoding.
+ * The internal representation is an ASN1_STRING whose data is a big endian
+ * representation of the value, ignoring the sign. The sign is determined by
+ * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative. 
+ *
+ * Positive integers are no problem: they are almost the same as the DER
+ * encoding, except if the first byte is >= 0x80 we need to add a zero pad.
+ *
+ * Negative integers are a bit trickier...
+ * The DER representation of negative integers is in 2s complement form.
+ * The internal form is converted by complementing each octet and finally 
+ * adding one to the result. This can be done less messily with a little trick.
+ * If the internal form has trailing zeroes then they will become FF by the
+ * complement and 0 by the add one (due to carry) so just copy as many trailing 
+ * zeros to the destination as there are in the source. The carry will add one
+ * to the last none zero octet: so complement this octet and add one and finally
+ * complement any left over until you get to the start of the string.
+ *
+ * Padding is a little trickier too. If the first bytes is > 0x80 then we pad
+ * with 0xff. However if the first byte is 0x80 and one of the following bytes
+ * is non-zero we pad with 0xff. The reason for this distinction is that 0x80
+ * followed by optional zeros isn't padded.
+ */
+
+int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
+	{
+	int pad=0,ret,i,neg;
+	unsigned char *p,*n,pb=0;
+
+	if ((a == NULL) || (a->data == NULL)) return(0);
+	neg=a->type & V_ASN1_NEG;
+	if (a->length == 0)
+		ret=1;
+	else
+		{
+		ret=a->length;
+		i=a->data[0];
+		if (!neg && (i > 127)) {
+			pad=1;
+			pb=0;
+		} else if(neg) {
+			if(i>128) {
+				pad=1;
+				pb=0xFF;
+			} else if(i == 128) {
+			/*
+			 * Special case: if any other bytes non zero we pad:
+			 * otherwise we don't.
+			 */
+				for(i = 1; i < a->length; i++) if(a->data[i]) {
+						pad=1;
+						pb=0xFF;
+						break;
+				}
+			}
+		}
+		ret+=pad;
+		}
+	if (pp == NULL) return(ret);
+	p= *pp;
+
+	if (pad) *(p++)=pb;
+	if (a->length == 0) *(p++)=0;
+	else if (!neg) memcpy(p,a->data,(unsigned int)a->length);
+	else {
+		/* Begin at the end of the encoding */
+		n=a->data + a->length - 1;
+		p += a->length - 1;
+		i = a->length;
+		/* Copy zeros to destination as long as source is zero */
+		while(!*n) {
+			*(p--) = 0;
+			n--;
+			i--;
+		}
+		/* Complement and increment next octet */
+		*(p--) = ((*(n--)) ^ 0xff) + 1;
+		i--;
+		/* Complement any octets left */
+		for(;i > 0; i--) *(p--) = *(n--) ^ 0xff;
+	}
+
+	*pp+=ret;
+	return(ret);
+	}
+
+/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
+
+ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
+	     long len)
+	{
+	ASN1_INTEGER *ret=NULL;
+	const unsigned char *p, *pend;
+	unsigned char *to,*s;
+	int i;
+
+	if ((a == NULL) || ((*a) == NULL))
+		{
+		if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
+		ret->type=V_ASN1_INTEGER;
+		}
+	else
+		ret=(*a);
+
+	p= *pp;
+	pend = p + len;
+
+	/* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it
+	 * signifies a missing NULL parameter. */
+	s=(unsigned char *)OPENSSL_malloc((int)len+1);
+	if (s == NULL)
+		{
+		i=ERR_R_MALLOC_FAILURE;
+		goto err;
+		}
+	to=s;
+	if(!len) {
+		/* Strictly speaking this is an illegal INTEGER but we
+		 * tolerate it.
+		 */
+		ret->type=V_ASN1_INTEGER;
+	} else if (*p & 0x80) /* a negative number */
+		{
+		ret->type=V_ASN1_NEG_INTEGER;
+		if ((*p == 0xff) && (len != 1)) {
+			p++;
+			len--;
+		}
+		i = len;
+		p += i - 1;
+		to += i - 1;
+		while((!*p) && i) {
+			*(to--) = 0;
+			i--;
+			p--;
+		}
+		/* Special case: if all zeros then the number will be of
+		 * the form FF followed by n zero bytes: this corresponds to
+		 * 1 followed by n zero bytes. We've already written n zeros
+		 * so we just append an extra one and set the first byte to
+		 * a 1. This is treated separately because it is the only case
+		 * where the number of bytes is larger than len.
+		 */
+		if(!i) {
+			*s = 1;
+			s[len] = 0;
+			len++;
+		} else {
+			*(to--) = (*(p--) ^ 0xff) + 1;
+			i--;
+			for(;i > 0; i--) *(to--) = *(p--) ^ 0xff;
+		}
+	} else {
+		ret->type=V_ASN1_INTEGER;
+		if ((*p == 0) && (len != 1))
+			{
+			p++;
+			len--;
+			}
+		memcpy(s,p,(int)len);
+	}
+
+	if (ret->data != NULL) OPENSSL_free(ret->data);
+	ret->data=s;
+	ret->length=(int)len;
+	if (a != NULL) (*a)=ret;
+	*pp=pend;
+	return(ret);
+err:
+	ASN1err(ASN1_F_C2I_ASN1_INTEGER,i);
+	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+		M_ASN1_INTEGER_free(ret);
+	return(NULL);
+	}
+
+
+/* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
+ * ASN1 integers: some broken software can encode a positive INTEGER
+ * with its MSB set as negative (it doesn't add a padding zero).
+ */
+
+ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
+	     long length)
+	{
+	ASN1_INTEGER *ret=NULL;
+	const unsigned char *p;
+	unsigned char *s;
+	long len;
+	int inf,tag,xclass;
+	int i;
+
+	if ((a == NULL) || ((*a) == NULL))
+		{
+		if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
+		ret->type=V_ASN1_INTEGER;
+		}
+	else
+		ret=(*a);
+
+	p= *pp;
+	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
+	if (inf & 0x80)
+		{
+		i=ASN1_R_BAD_OBJECT_HEADER;
+		goto err;
+		}
+
+	if (tag != V_ASN1_INTEGER)
+		{
+		i=ASN1_R_EXPECTING_AN_INTEGER;
+		goto err;
+		}
+
+	/* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it
+	 * signifies a missing NULL parameter. */
+	s=(unsigned char *)OPENSSL_malloc((int)len+1);
+	if (s == NULL)
+		{
+		i=ERR_R_MALLOC_FAILURE;
+		goto err;
+		}
+	ret->type=V_ASN1_INTEGER;
+	if(len) {
+		if ((*p == 0) && (len != 1))
+			{
+			p++;
+			len--;
+			}
+		memcpy(s,p,(int)len);
+		p+=len;
+	}
+
+	if (ret->data != NULL) OPENSSL_free(ret->data);
+	ret->data=s;
+	ret->length=(int)len;
+	if (a != NULL) (*a)=ret;
+	*pp=p;
+	return(ret);
+err:
+	ASN1err(ASN1_F_D2I_ASN1_UINTEGER,i);
+	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+		M_ASN1_INTEGER_free(ret);
+	return(NULL);
+	}
+
+int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
+	{
+	int j,k;
+	unsigned int i;
+	unsigned char buf[sizeof(long)+1];
+	long d;
+
+	a->type=V_ASN1_INTEGER;
+	if (a->length < (int)(sizeof(long)+1))
+		{
+		if (a->data != NULL)
+			OPENSSL_free(a->data);
+		if ((a->data=(unsigned char *)OPENSSL_malloc(sizeof(long)+1)) != NULL)
+			memset((char *)a->data,0,sizeof(long)+1);
+		}
+	if (a->data == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_INTEGER_SET,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	d=v;
+	if (d < 0)
+		{
+		d= -d;
+		a->type=V_ASN1_NEG_INTEGER;
+		}
+
+	for (i=0; i<sizeof(long); i++)
+		{
+		if (d == 0) break;
+		buf[i]=(int)d&0xff;
+		d>>=8;
+		}
+	j=0;
+	for (k=i-1; k >=0; k--)
+		a->data[j++]=buf[k];
+	a->length=j;
+	return(1);
+	}
+
+long ASN1_INTEGER_get(const ASN1_INTEGER *a)
+	{
+	int neg=0,i;
+	long r=0;
+
+	if (a == NULL) return(0L);
+	i=a->type;
+	if (i == V_ASN1_NEG_INTEGER)
+		neg=1;
+	else if (i != V_ASN1_INTEGER)
+		return -1;
+	
+	if (a->length > (int)sizeof(long))
+		{
+		/* hmm... a bit ugly */
+		return(0xffffffffL);
+		}
+	if (a->data == NULL)
+		return 0;
+
+	for (i=0; i<a->length; i++)
+		{
+		r<<=8;
+		r|=(unsigned char)a->data[i];
+		}
+	if (neg) r= -r;
+	return(r);
+	}
+
+ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
+	{
+	ASN1_INTEGER *ret;
+	int len,j;
+
+	if (ai == NULL)
+		ret=M_ASN1_INTEGER_new();
+	else
+		ret=ai;
+	if (ret == NULL)
+		{
+		ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_NESTED_ASN1_ERROR);
+		goto err;
+		}
+	if (BN_is_negative(bn))
+		ret->type = V_ASN1_NEG_INTEGER;
+	else ret->type=V_ASN1_INTEGER;
+	j=BN_num_bits(bn);
+	len=((j == 0)?0:((j/8)+1));
+	if (ret->length < len+4)
+		{
+		unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
+		if (!new_data)
+			{
+			ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		ret->data=new_data;
+		}
+	ret->length=BN_bn2bin(bn,ret->data);
+	/* Correct zero case */
+	if(!ret->length)
+		{
+		ret->data[0] = 0;
+		ret->length = 1;
+		}
+	return(ret);
+err:
+	if (ret != ai) M_ASN1_INTEGER_free(ret);
+	return(NULL);
+	}
+
+BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
+	{
+	BIGNUM *ret;
+
+	if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
+		ASN1err(ASN1_F_ASN1_INTEGER_TO_BN,ASN1_R_BN_LIB);
+	else if(ai->type == V_ASN1_NEG_INTEGER)
+		BN_set_negative(ret, 1);
+	return(ret);
+	}
+
+IMPLEMENT_STACK_OF(ASN1_INTEGER)
+IMPLEMENT_ASN1_SET_OF(ASN1_INTEGER)
diff --git a/openssl/crypto/asn1/a_mbstr.c b/openssl/crypto/asn1/a_mbstr.c
new file mode 100644
index 0000000..1538e0a
--- /dev/null
+++ b/openssl/crypto/asn1/a_mbstr.c
@@ -0,0 +1,400 @@
+/* a_mbstr.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+
+static int traverse_string(const unsigned char *p, int len, int inform,
+		 int (*rfunc)(unsigned long value, void *in), void *arg);
+static int in_utf8(unsigned long value, void *arg);
+static int out_utf8(unsigned long value, void *arg);
+static int type_str(unsigned long value, void *arg);
+static int cpy_asc(unsigned long value, void *arg);
+static int cpy_bmp(unsigned long value, void *arg);
+static int cpy_univ(unsigned long value, void *arg);
+static int cpy_utf8(unsigned long value, void *arg);
+static int is_printable(unsigned long value);
+
+/* These functions take a string in UTF8, ASCII or multibyte form and
+ * a mask of permissible ASN1 string types. It then works out the minimal
+ * type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8)
+ * and creates a string of the correct type with the supplied data.
+ * Yes this is horrible: it has to be :-(
+ * The 'ncopy' form checks minimum and maximum size limits too.
+ */
+
+int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
+					int inform, unsigned long mask)
+{
+	return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
+}
+
+int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
+					int inform, unsigned long mask, 
+					long minsize, long maxsize)
+{
+	int str_type;
+	int ret;
+	char free_out;
+	int outform, outlen = 0;
+	ASN1_STRING *dest;
+	unsigned char *p;
+	int nchar;
+	char strbuf[32];
+	int (*cpyfunc)(unsigned long,void *) = NULL;
+	if(len == -1) len = strlen((const char *)in);
+	if(!mask) mask = DIRSTRING_TYPE;
+
+	/* First do a string check and work out the number of characters */
+	switch(inform) {
+
+		case MBSTRING_BMP:
+		if(len & 1) {
+			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
+					 ASN1_R_INVALID_BMPSTRING_LENGTH);
+			return -1;
+		}
+		nchar = len >> 1;
+		break;
+
+		case MBSTRING_UNIV:
+		if(len & 3) {
+			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
+					 ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
+			return -1;
+		}
+		nchar = len >> 2;
+		break;
+
+		case MBSTRING_UTF8:
+		nchar = 0;
+		/* This counts the characters and does utf8 syntax checking */
+		ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
+		if(ret < 0) {
+			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
+						 ASN1_R_INVALID_UTF8STRING);
+			return -1;
+		}
+		break;
+
+		case MBSTRING_ASC:
+		nchar = len;
+		break;
+
+		default:
+		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT);
+		return -1;
+	}
+
+	if((minsize > 0) && (nchar < minsize)) {
+		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT);
+		BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
+		ERR_add_error_data(2, "minsize=", strbuf);
+		return -1;
+	}
+
+	if((maxsize > 0) && (nchar > maxsize)) {
+		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG);
+		BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
+		ERR_add_error_data(2, "maxsize=", strbuf);
+		return -1;
+	}
+
+	/* Now work out minimal type (if any) */
+	if(traverse_string(in, len, inform, type_str, &mask) < 0) {
+		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS);
+		return -1;
+	}
+
+
+	/* Now work out output format and string type */
+	outform = MBSTRING_ASC;
+	if(mask & B_ASN1_PRINTABLESTRING) str_type = V_ASN1_PRINTABLESTRING;
+	else if(mask & B_ASN1_IA5STRING) str_type = V_ASN1_IA5STRING;
+	else if(mask & B_ASN1_T61STRING) str_type = V_ASN1_T61STRING;
+	else if(mask & B_ASN1_BMPSTRING) {
+		str_type = V_ASN1_BMPSTRING;
+		outform = MBSTRING_BMP;
+	} else if(mask & B_ASN1_UNIVERSALSTRING) {
+		str_type = V_ASN1_UNIVERSALSTRING;
+		outform = MBSTRING_UNIV;
+	} else {
+		str_type = V_ASN1_UTF8STRING;
+		outform = MBSTRING_UTF8;
+	}
+	if(!out) return str_type;
+	if(*out) {
+		free_out = 0;
+		dest = *out;
+		if(dest->data) {
+			dest->length = 0;
+			OPENSSL_free(dest->data);
+			dest->data = NULL;
+		}
+		dest->type = str_type;
+	} else {
+		free_out = 1;
+		dest = ASN1_STRING_type_new(str_type);
+		if(!dest) {
+			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
+							ERR_R_MALLOC_FAILURE);
+			return -1;
+		}
+		*out = dest;
+	}
+	/* If both the same type just copy across */
+	if(inform == outform) {
+		if(!ASN1_STRING_set(dest, in, len)) {
+			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,ERR_R_MALLOC_FAILURE);
+			return -1;
+		}
+		return str_type;
+	} 
+
+	/* Work out how much space the destination will need */
+	switch(outform) {
+		case MBSTRING_ASC:
+		outlen = nchar;
+		cpyfunc = cpy_asc;
+		break;
+
+		case MBSTRING_BMP:
+		outlen = nchar << 1;
+		cpyfunc = cpy_bmp;
+		break;
+
+		case MBSTRING_UNIV:
+		outlen = nchar << 2;
+		cpyfunc = cpy_univ;
+		break;
+
+		case MBSTRING_UTF8:
+		outlen = 0;
+		traverse_string(in, len, inform, out_utf8, &outlen);
+		cpyfunc = cpy_utf8;
+		break;
+	}
+	if(!(p = OPENSSL_malloc(outlen + 1))) {
+		if(free_out) ASN1_STRING_free(dest);
+		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,ERR_R_MALLOC_FAILURE);
+		return -1;
+	}
+	dest->length = outlen;
+	dest->data = p;
+	p[outlen] = 0;
+	traverse_string(in, len, inform, cpyfunc, &p);
+	return str_type;	
+}
+
+/* This function traverses a string and passes the value of each character
+ * to an optional function along with a void * argument.
+ */
+
+static int traverse_string(const unsigned char *p, int len, int inform,
+		 int (*rfunc)(unsigned long value, void *in), void *arg)
+{
+	unsigned long value;
+	int ret;
+	while(len) {
+		if(inform == MBSTRING_ASC) {
+			value = *p++;
+			len--;
+		} else if(inform == MBSTRING_BMP) {
+			value = *p++ << 8;
+			value |= *p++;
+			len -= 2;
+		} else if(inform == MBSTRING_UNIV) {
+			value = ((unsigned long)*p++) << 24;
+			value |= ((unsigned long)*p++) << 16;
+			value |= *p++ << 8;
+			value |= *p++;
+			len -= 4;
+		} else {
+			ret = UTF8_getc(p, len, &value);
+			if(ret < 0) return -1;
+			len -= ret;
+			p += ret;
+		}
+		if(rfunc) {
+			ret = rfunc(value, arg);
+			if(ret <= 0) return ret;
+		}
+	}
+	return 1;
+}
+
+/* Various utility functions for traverse_string */
+
+/* Just count number of characters */
+
+static int in_utf8(unsigned long value, void *arg)
+{
+	int *nchar;
+	nchar = arg;
+	(*nchar)++;
+	return 1;
+}
+
+/* Determine size of output as a UTF8 String */
+
+static int out_utf8(unsigned long value, void *arg)
+{
+	int *outlen;
+	outlen = arg;
+	*outlen += UTF8_putc(NULL, -1, value);
+	return 1;
+}
+
+/* Determine the "type" of a string: check each character against a
+ * supplied "mask".
+ */
+
+static int type_str(unsigned long value, void *arg)
+{
+	unsigned long types;
+	types = *((unsigned long *)arg);
+	if((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
+					types &= ~B_ASN1_PRINTABLESTRING;
+	if((types & B_ASN1_IA5STRING) && (value > 127))
+					types &= ~B_ASN1_IA5STRING;
+	if((types & B_ASN1_T61STRING) && (value > 0xff))
+					types &= ~B_ASN1_T61STRING;
+	if((types & B_ASN1_BMPSTRING) && (value > 0xffff))
+					types &= ~B_ASN1_BMPSTRING;
+	if(!types) return -1;
+	*((unsigned long *)arg) = types;
+	return 1;
+}
+
+/* Copy one byte per character ASCII like strings */
+
+static int cpy_asc(unsigned long value, void *arg)
+{
+	unsigned char **p, *q;
+	p = arg;
+	q = *p;
+	*q = (unsigned char) value;
+	(*p)++;
+	return 1;
+}
+
+/* Copy two byte per character BMPStrings */
+
+static int cpy_bmp(unsigned long value, void *arg)
+{
+	unsigned char **p, *q;
+	p = arg;
+	q = *p;
+	*q++ = (unsigned char) ((value >> 8) & 0xff);
+	*q = (unsigned char) (value & 0xff);
+	*p += 2;
+	return 1;
+}
+
+/* Copy four byte per character UniversalStrings */
+
+static int cpy_univ(unsigned long value, void *arg)
+{
+	unsigned char **p, *q;
+	p = arg;
+	q = *p;
+	*q++ = (unsigned char) ((value >> 24) & 0xff);
+	*q++ = (unsigned char) ((value >> 16) & 0xff);
+	*q++ = (unsigned char) ((value >> 8) & 0xff);
+	*q = (unsigned char) (value & 0xff);
+	*p += 4;
+	return 1;
+}
+
+/* Copy to a UTF8String */
+
+static int cpy_utf8(unsigned long value, void *arg)
+{
+	unsigned char **p;
+	int ret;
+	p = arg;
+	/* We already know there is enough room so pass 0xff as the length */
+	ret = UTF8_putc(*p, 0xff, value);
+	*p += ret;
+	return 1;
+}
+
+/* Return 1 if the character is permitted in a PrintableString */
+static int is_printable(unsigned long value)
+{
+	int ch;
+	if(value > 0x7f) return 0;
+	ch = (int) value;
+	/* Note: we can't use 'isalnum' because certain accented 
+	 * characters may count as alphanumeric in some environments.
+	 */
+#ifndef CHARSET_EBCDIC
+	if((ch >= 'a') && (ch <= 'z')) return 1;
+	if((ch >= 'A') && (ch <= 'Z')) return 1;
+	if((ch >= '0') && (ch <= '9')) return 1;
+	if ((ch == ' ') || strchr("'()+,-./:=?", ch)) return 1;
+#else /*CHARSET_EBCDIC*/
+	if((ch >= os_toascii['a']) && (ch <= os_toascii['z'])) return 1;
+	if((ch >= os_toascii['A']) && (ch <= os_toascii['Z'])) return 1;
+	if((ch >= os_toascii['0']) && (ch <= os_toascii['9'])) return 1;
+	if ((ch == os_toascii[' ']) || strchr("'()+,-./:=?", os_toebcdic[ch])) return 1;
+#endif /*CHARSET_EBCDIC*/
+	return 0;
+}
diff --git a/openssl/crypto/asn1/a_object.c b/openssl/crypto/asn1/a_object.c
new file mode 100644
index 0000000..3978c91
--- /dev/null
+++ b/openssl/crypto/asn1/a_object.c
@@ -0,0 +1,403 @@
+/* crypto/asn1/a_object.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <limits.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/bn.h>
+
+int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
+	{
+	unsigned char *p;
+	int objsize;
+
+	if ((a == NULL) || (a->data == NULL)) return(0);
+
+	objsize = ASN1_object_size(0,a->length,V_ASN1_OBJECT);
+	if (pp == NULL) return objsize;
+
+	p= *pp;
+	ASN1_put_object(&p,0,a->length,V_ASN1_OBJECT,V_ASN1_UNIVERSAL);
+	memcpy(p,a->data,a->length);
+	p+=a->length;
+
+	*pp=p;
+	return(objsize);
+	}
+
+int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
+	{
+	int i,first,len=0,c, use_bn;
+	char ftmp[24], *tmp = ftmp;
+	int tmpsize = sizeof ftmp;
+	const char *p;
+	unsigned long l;
+	BIGNUM *bl = NULL;
+
+	if (num == 0)
+		return(0);
+	else if (num == -1)
+		num=strlen(buf);
+
+	p=buf;
+	c= *(p++);
+	num--;
+	if ((c >= '0') && (c <= '2'))
+		{
+		first= c-'0';
+		}
+	else
+		{
+		ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_FIRST_NUM_TOO_LARGE);
+		goto err;
+		}
+
+	if (num <= 0)
+		{
+		ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_MISSING_SECOND_NUMBER);
+		goto err;
+		}
+	c= *(p++);
+	num--;
+	for (;;)
+		{
+		if (num <= 0) break;
+		if ((c != '.') && (c != ' '))
+			{
+			ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_SEPARATOR);
+			goto err;
+			}
+		l=0;
+		use_bn = 0;
+		for (;;)
+			{
+			if (num <= 0) break;
+			num--;
+			c= *(p++);
+			if ((c == ' ') || (c == '.'))
+				break;
+			if ((c < '0') || (c > '9'))
+				{
+				ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT);
+				goto err;
+				}
+			if (!use_bn && l >= ((ULONG_MAX - 80) / 10L))
+				{
+				use_bn = 1;
+				if (!bl)
+					bl = BN_new();
+				if (!bl || !BN_set_word(bl, l))
+					goto err;
+				}
+			if (use_bn)
+				{
+				if (!BN_mul_word(bl, 10L)
+					|| !BN_add_word(bl, c-'0'))
+					goto err;
+				}
+			else
+				l=l*10L+(long)(c-'0');
+			}
+		if (len == 0)
+			{
+			if ((first < 2) && (l >= 40))
+				{
+				ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_SECOND_NUMBER_TOO_LARGE);
+				goto err;
+				}
+			if (use_bn)
+				{
+				if (!BN_add_word(bl, first * 40))
+					goto err;
+				}
+			else
+				l+=(long)first*40;
+			}
+		i=0;
+		if (use_bn)
+			{
+			int blsize;
+			blsize = BN_num_bits(bl);
+			blsize = (blsize + 6)/7;
+			if (blsize > tmpsize)
+				{
+				if (tmp != ftmp)
+					OPENSSL_free(tmp);
+				tmpsize = blsize + 32;
+				tmp = OPENSSL_malloc(tmpsize);
+				if (!tmp)
+					goto err;
+				}
+			while(blsize--)
+				tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
+			}
+		else
+			{
+					
+			for (;;)
+				{
+				tmp[i++]=(unsigned char)l&0x7f;
+				l>>=7L;
+				if (l == 0L) break;
+				}
+
+			}
+		if (out != NULL)
+			{
+			if (len+i > olen)
+				{
+				ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_BUFFER_TOO_SMALL);
+				goto err;
+				}
+			while (--i > 0)
+				out[len++]=tmp[i]|0x80;
+			out[len++]=tmp[0];
+			}
+		else
+			len+=i;
+		}
+	if (tmp != ftmp)
+		OPENSSL_free(tmp);
+	if (bl)
+		BN_free(bl);
+	return(len);
+err:
+	if (tmp != ftmp)
+		OPENSSL_free(tmp);
+	if (bl)
+		BN_free(bl);
+	return(0);
+	}
+
+int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
+{
+	return OBJ_obj2txt(buf, buf_len, a, 0);
+}
+
+int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
+	{
+	char buf[80], *p = buf;
+	int i;
+
+	if ((a == NULL) || (a->data == NULL))
+		return(BIO_write(bp,"NULL",4));
+	i=i2t_ASN1_OBJECT(buf,sizeof buf,a);
+	if (i > (int)(sizeof(buf) - 1))
+		{
+		p = OPENSSL_malloc(i + 1);
+		if (!p)
+			return -1;
+		i2t_ASN1_OBJECT(p,i + 1,a);
+		}
+	if (i <= 0)
+		return BIO_write(bp, "<INVALID>", 9);
+	BIO_write(bp,p,i);
+	if (p != buf)
+		OPENSSL_free(p);
+	return(i);
+	}
+
+ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
+	     long length)
+{
+	const unsigned char *p;
+	long len;
+	int tag,xclass;
+	int inf,i;
+	ASN1_OBJECT *ret = NULL;
+	p= *pp;
+	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
+	if (inf & 0x80)
+		{
+		i=ASN1_R_BAD_OBJECT_HEADER;
+		goto err;
+		}
+
+	if (tag != V_ASN1_OBJECT)
+		{
+		i=ASN1_R_EXPECTING_AN_OBJECT;
+		goto err;
+		}
+	ret = c2i_ASN1_OBJECT(a, &p, len);
+	if(ret) *pp = p;
+	return ret;
+err:
+	ASN1err(ASN1_F_D2I_ASN1_OBJECT,i);
+	return(NULL);
+}
+ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
+	     long len)
+	{
+	ASN1_OBJECT *ret=NULL;
+	const unsigned char *p;
+	unsigned char *data;
+	int i;
+	/* Sanity check OID encoding: can't have leading 0x80 in
+	 * subidentifiers, see: X.690 8.19.2
+	 */
+	for (i = 0, p = *pp; i < len; i++, p++)
+		{
+		if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
+			{
+			ASN1err(ASN1_F_C2I_ASN1_OBJECT,ASN1_R_INVALID_OBJECT_ENCODING);
+			return NULL;
+			}
+		}
+
+	/* only the ASN1_OBJECTs from the 'table' will have values
+	 * for ->sn or ->ln */
+	if ((a == NULL) || ((*a) == NULL) ||
+		!((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC))
+		{
+		if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL);
+		}
+	else	ret=(*a);
+
+	p= *pp;
+	/* detach data from object */
+	data = (unsigned char *)ret->data;
+	ret->data = NULL;
+	/* once detached we can change it */
+	if ((data == NULL) || (ret->length < len))
+		{
+		ret->length=0;
+		if (data != NULL) OPENSSL_free(data);
+		data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1);
+		if (data == NULL)
+			{ i=ERR_R_MALLOC_FAILURE; goto err; }
+		ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+		}
+	memcpy(data,p,(int)len);
+	/* reattach data to object, after which it remains const */
+	ret->data  =data;
+	ret->length=(int)len;
+	ret->sn=NULL;
+	ret->ln=NULL;
+	/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
+	p+=len;
+
+	if (a != NULL) (*a)=ret;
+	*pp=p;
+	return(ret);
+err:
+	ASN1err(ASN1_F_C2I_ASN1_OBJECT,i);
+	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+		ASN1_OBJECT_free(ret);
+	return(NULL);
+	}
+
+ASN1_OBJECT *ASN1_OBJECT_new(void)
+	{
+	ASN1_OBJECT *ret;
+
+	ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
+	if (ret == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_OBJECT_NEW,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	ret->length=0;
+	ret->data=NULL;
+	ret->nid=0;
+	ret->sn=NULL;
+	ret->ln=NULL;
+	ret->flags=ASN1_OBJECT_FLAG_DYNAMIC;
+	return(ret);
+	}
+
+void ASN1_OBJECT_free(ASN1_OBJECT *a)
+	{
+	if (a == NULL) return;
+	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS)
+		{
+#ifndef CONST_STRICT /* disable purely for compile-time strict const checking. Doing this on a "real" compile will cause memory leaks */
+		if (a->sn != NULL) OPENSSL_free((void *)a->sn);
+		if (a->ln != NULL) OPENSSL_free((void *)a->ln);
+#endif
+		a->sn=a->ln=NULL;
+		}
+	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA)
+		{
+		if (a->data != NULL) OPENSSL_free((void *)a->data);
+		a->data=NULL;
+		a->length=0;
+		}
+	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
+		OPENSSL_free(a);
+	}
+
+ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
+	     const char *sn, const char *ln)
+	{
+	ASN1_OBJECT o;
+
+	o.sn=sn;
+	o.ln=ln;
+	o.data=data;
+	o.nid=nid;
+	o.length=len;
+	o.flags=ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
+		ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+	return(OBJ_dup(&o));
+	}
+
+IMPLEMENT_STACK_OF(ASN1_OBJECT)
+IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT)
diff --git a/openssl/crypto/asn1/a_octet.c b/openssl/crypto/asn1/a_octet.c
new file mode 100644
index 0000000..e8725e4
--- /dev/null
+++ b/openssl/crypto/asn1/a_octet.c
@@ -0,0 +1,71 @@
+/* crypto/asn1/a_octet.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+
+ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
+{ return M_ASN1_OCTET_STRING_dup(x); }
+
+int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b)
+{ return M_ASN1_OCTET_STRING_cmp(a, b); }
+
+int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len)
+{ return M_ASN1_OCTET_STRING_set(x, d, len); }
+
diff --git a/openssl/crypto/asn1/a_print.c b/openssl/crypto/asn1/a_print.c
new file mode 100644
index 0000000..d18e772
--- /dev/null
+++ b/openssl/crypto/asn1/a_print.c
@@ -0,0 +1,127 @@
+/* crypto/asn1/a_print.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+
+int ASN1_PRINTABLE_type(const unsigned char *s, int len)
+	{
+	int c;
+	int ia5=0;
+	int t61=0;
+
+	if (len <= 0) len= -1;
+	if (s == NULL) return(V_ASN1_PRINTABLESTRING);
+
+	while ((*s) && (len-- != 0))
+		{
+		c= *(s++);
+#ifndef CHARSET_EBCDIC
+		if (!(	((c >= 'a') && (c <= 'z')) ||
+			((c >= 'A') && (c <= 'Z')) ||
+			(c == ' ') ||
+			((c >= '0') && (c <= '9')) ||
+			(c == ' ') || (c == '\'') ||
+			(c == '(') || (c == ')') ||
+			(c == '+') || (c == ',') ||
+			(c == '-') || (c == '.') ||
+			(c == '/') || (c == ':') ||
+			(c == '=') || (c == '?')))
+			ia5=1;
+		if (c&0x80)
+			t61=1;
+#else
+		if (!isalnum(c) && (c != ' ') &&
+		    strchr("'()+,-./:=?", c) == NULL)
+			ia5=1;
+		if (os_toascii[c] & 0x80)
+			t61=1;
+#endif
+		}
+	if (t61) return(V_ASN1_T61STRING);
+	if (ia5) return(V_ASN1_IA5STRING);
+	return(V_ASN1_PRINTABLESTRING);
+	}
+
+int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s)
+	{
+	int i;
+	unsigned char *p;
+
+	if (s->type != V_ASN1_UNIVERSALSTRING) return(0);
+	if ((s->length%4) != 0) return(0);
+	p=s->data;
+	for (i=0; i<s->length; i+=4)
+		{
+		if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
+			break;
+		else
+			p+=4;
+		}
+	if (i < s->length) return(0);
+	p=s->data;
+	for (i=3; i<s->length; i+=4)
+		{
+		*(p++)=s->data[i];
+		}
+	*(p)='\0';
+	s->length/=4;
+	s->type=ASN1_PRINTABLE_type(s->data,s->length);
+	return(1);
+	}
diff --git a/openssl/crypto/asn1/a_set.c b/openssl/crypto/asn1/a_set.c
new file mode 100644
index 0000000..d726c8d
--- /dev/null
+++ b/openssl/crypto/asn1/a_set.c
@@ -0,0 +1,241 @@
+/* crypto/asn1/a_set.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1_mac.h>
+
+#ifndef NO_ASN1_OLD
+
+typedef struct
+    {
+    unsigned char *pbData;
+    int cbData;
+    } MYBLOB;
+
+/* SetBlobCmp
+ * This function compares two elements of SET_OF block
+ */
+static int SetBlobCmp(const void *elem1, const void *elem2 )
+    {
+    const MYBLOB *b1 = (const MYBLOB *)elem1;
+    const MYBLOB *b2 = (const MYBLOB *)elem2;
+    int r;
+
+    r = memcmp(b1->pbData, b2->pbData,
+	       b1->cbData < b2->cbData ? b1->cbData : b2->cbData);
+    if(r != 0)
+	return r;
+    return b1->cbData-b2->cbData;
+    }
+
+/* int is_set:  if TRUE, then sort the contents (i.e. it isn't a SEQUENCE)    */
+int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
+		 i2d_of_void *i2d, int ex_tag, int ex_class,
+		 int is_set)
+	{
+	int ret=0,r;
+	int i;
+	unsigned char *p;
+        unsigned char *pStart, *pTempMem;
+        MYBLOB *rgSetBlob;
+        int totSize;
+
+	if (a == NULL) return(0);
+	for (i=sk_OPENSSL_BLOCK_num(a)-1; i>=0; i--)
+		ret+=i2d(sk_OPENSSL_BLOCK_value(a,i),NULL);
+	r=ASN1_object_size(1,ret,ex_tag);
+	if (pp == NULL) return(r);
+
+	p= *pp;
+	ASN1_put_object(&p,1,ret,ex_tag,ex_class);
+
+/* Modified by gp@nsj.co.jp */
+	/* And then again by Ben */
+	/* And again by Steve */
+
+	if(!is_set || (sk_OPENSSL_BLOCK_num(a) < 2))
+		{
+		for (i=0; i<sk_OPENSSL_BLOCK_num(a); i++)
+                	i2d(sk_OPENSSL_BLOCK_value(a,i),&p);
+
+		*pp=p;
+		return(r);
+		}
+
+        pStart  = p; /* Catch the beg of Setblobs*/
+		/* In this array we will store the SET blobs */
+		rgSetBlob = OPENSSL_malloc(sk_OPENSSL_BLOCK_num(a) * sizeof(MYBLOB));
+		if (rgSetBlob == NULL)
+			{
+			ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE);
+			return(0);
+			}
+
+        for (i=0; i<sk_OPENSSL_BLOCK_num(a); i++)
+	        {
+                rgSetBlob[i].pbData = p;  /* catch each set encode blob */
+                i2d(sk_OPENSSL_BLOCK_value(a,i),&p);
+                rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this
+SetBlob
+*/
+		}
+        *pp=p;
+        totSize = p - pStart; /* This is the total size of all set blobs */
+
+ /* Now we have to sort the blobs. I am using a simple algo.
+    *Sort ptrs *Copy to temp-mem *Copy from temp-mem to user-mem*/
+        qsort( rgSetBlob, sk_OPENSSL_BLOCK_num(a), sizeof(MYBLOB), SetBlobCmp);
+		if (!(pTempMem = OPENSSL_malloc(totSize)))
+			{
+			ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE);
+			return(0);
+			}
+
+/* Copy to temp mem */
+        p = pTempMem;
+        for(i=0; i<sk_OPENSSL_BLOCK_num(a); ++i)
+		{
+                memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData);
+                p += rgSetBlob[i].cbData;
+		}
+
+/* Copy back to user mem*/
+        memcpy(pStart, pTempMem, totSize);
+        OPENSSL_free(pTempMem);
+        OPENSSL_free(rgSetBlob);
+
+        return(r);
+        }
+
+STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
+			      const unsigned char **pp,
+			      long length, d2i_of_void *d2i,
+			      void (*free_func)(OPENSSL_BLOCK), int ex_tag,
+			      int ex_class)
+	{
+	ASN1_const_CTX c;
+	STACK_OF(OPENSSL_BLOCK) *ret=NULL;
+
+	if ((a == NULL) || ((*a) == NULL))
+		{
+		if ((ret=sk_OPENSSL_BLOCK_new_null()) == NULL)
+			{
+			ASN1err(ASN1_F_D2I_ASN1_SET,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+	else
+		ret=(*a);
+
+	c.p= *pp;
+	c.max=(length == 0)?0:(c.p+length);
+
+	c.inf=ASN1_get_object(&c.p,&c.slen,&c.tag,&c.xclass,c.max-c.p);
+	if (c.inf & 0x80) goto err;
+	if (ex_class != c.xclass)
+		{
+		ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_BAD_CLASS);
+		goto err;
+		}
+	if (ex_tag != c.tag)
+		{
+		ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_BAD_TAG);
+		goto err;
+		}
+	if ((c.slen+c.p) > c.max)
+		{
+		ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_LENGTH_ERROR);
+		goto err;
+		}
+	/* check for infinite constructed - it can be as long
+	 * as the amount of data passed to us */
+	if (c.inf == (V_ASN1_CONSTRUCTED+1))
+		c.slen=length+ *pp-c.p;
+	c.max=c.p+c.slen;
+
+	while (c.p < c.max)
+		{
+		char *s;
+
+		if (M_ASN1_D2I_end_sequence()) break;
+		/* XXX: This was called with 4 arguments, incorrectly, it seems
+		   if ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL) */
+		if ((s=d2i(NULL,&c.p,c.slen)) == NULL)
+			{
+			ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_ERROR_PARSING_SET_ELEMENT);
+			asn1_add_error(*pp,(int)(c.p- *pp));
+			goto err;
+			}
+		if (!sk_OPENSSL_BLOCK_push(ret,s)) goto err;
+		}
+	if (a != NULL) (*a)=ret;
+	*pp=c.p;
+	return(ret);
+err:
+	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+		{
+		if (free_func != NULL)
+			sk_OPENSSL_BLOCK_pop_free(ret,free_func);
+		else
+			sk_OPENSSL_BLOCK_free(ret);
+		}
+	return(NULL);
+	}
+
+#endif
diff --git a/openssl/crypto/asn1/a_sign.c b/openssl/crypto/asn1/a_sign.c
new file mode 100644
index 0000000..ff63bfc
--- /dev/null
+++ b/openssl/crypto/asn1/a_sign.c
@@ -0,0 +1,298 @@
+/* crypto/asn1/a_sign.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <time.h>
+
+#include "cryptlib.h"
+
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include "asn1_locl.h"
+
+#ifndef NO_ASN1_OLD
+
+int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
+	      ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
+	      const EVP_MD *type)
+	{
+	EVP_MD_CTX ctx;
+	unsigned char *p,*buf_in=NULL,*buf_out=NULL;
+	int i,inl=0,outl=0,outll=0;
+	X509_ALGOR *a;
+
+	EVP_MD_CTX_init(&ctx);
+	for (i=0; i<2; i++)
+		{
+		if (i == 0)
+			a=algor1;
+		else
+			a=algor2;
+		if (a == NULL) continue;
+                if (type->pkey_type == NID_dsaWithSHA1)
+			{
+			/* special case: RFC 2459 tells us to omit 'parameters'
+			 * with id-dsa-with-sha1 */
+			ASN1_TYPE_free(a->parameter);
+			a->parameter = NULL;
+			}
+		else if ((a->parameter == NULL) || 
+			(a->parameter->type != V_ASN1_NULL))
+			{
+			ASN1_TYPE_free(a->parameter);
+			if ((a->parameter=ASN1_TYPE_new()) == NULL) goto err;
+			a->parameter->type=V_ASN1_NULL;
+			}
+		ASN1_OBJECT_free(a->algorithm);
+		a->algorithm=OBJ_nid2obj(type->pkey_type);
+		if (a->algorithm == NULL)
+			{
+			ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE);
+			goto err;
+			}
+		if (a->algorithm->length == 0)
+			{
+			ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
+			goto err;
+			}
+		}
+	inl=i2d(data,NULL);
+	buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl);
+	outll=outl=EVP_PKEY_size(pkey);
+	buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl);
+	if ((buf_in == NULL) || (buf_out == NULL))
+		{
+		outl=0;
+		ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	p=buf_in;
+
+	i2d(data,&p);
+	EVP_SignInit_ex(&ctx,type, NULL);
+	EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl);
+	if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out,
+			(unsigned int *)&outl,pkey))
+		{
+		outl=0;
+		ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB);
+		goto err;
+		}
+	if (signature->data != NULL) OPENSSL_free(signature->data);
+	signature->data=buf_out;
+	buf_out=NULL;
+	signature->length=outl;
+	/* In the interests of compatibility, I'll make sure that
+	 * the bit string has a 'not-used bits' value of 0
+	 */
+	signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
+	signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
+err:
+	EVP_MD_CTX_cleanup(&ctx);
+	if (buf_in != NULL)
+		{ OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); }
+	if (buf_out != NULL)
+		{ OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); }
+	return(outl);
+	}
+
+#endif
+
+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
+	     ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey,
+	     const EVP_MD *type)
+	{
+	EVP_MD_CTX ctx;
+	unsigned char *buf_in=NULL,*buf_out=NULL;
+	int inl=0,outl=0,outll=0;
+	int signid, paramtype;
+
+	if (type == NULL)
+		{
+		int def_nid;
+		if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
+			type = EVP_get_digestbynid(def_nid);
+		}
+
+	if (type == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_ITEM_SIGN, ASN1_R_NO_DEFAULT_DIGEST);
+		return 0;
+		}
+
+	if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
+		{
+		if (!pkey->ameth ||
+			!OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type),
+						pkey->ameth->pkey_id))
+			{
+			ASN1err(ASN1_F_ASN1_ITEM_SIGN,
+				ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+			return 0;
+			}
+		}
+	else
+		signid = type->pkey_type;
+
+	if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
+		paramtype = V_ASN1_NULL;
+	else
+		paramtype = V_ASN1_UNDEF;
+
+	if (algor1)
+		X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
+	if (algor2)
+		X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
+
+	EVP_MD_CTX_init(&ctx);
+	inl=ASN1_item_i2d(asn,&buf_in, it);
+	outll=outl=EVP_PKEY_size(pkey);
+	buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl);
+	if ((buf_in == NULL) || (buf_out == NULL))
+		{
+		outl=0;
+		ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	EVP_SignInit_ex(&ctx,type, NULL);
+	EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl);
+	if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out,
+			(unsigned int *)&outl,pkey))
+		{
+		outl=0;
+		ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_EVP_LIB);
+		goto err;
+		}
+	if (signature->data != NULL) OPENSSL_free(signature->data);
+	signature->data=buf_out;
+	buf_out=NULL;
+	signature->length=outl;
+	/* In the interests of compatibility, I'll make sure that
+	 * the bit string has a 'not-used bits' value of 0
+	 */
+	signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
+	signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
+err:
+	EVP_MD_CTX_cleanup(&ctx);
+	if (buf_in != NULL)
+		{ OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); }
+	if (buf_out != NULL)
+		{ OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); }
+	return(outl);
+	}
diff --git a/openssl/crypto/asn1/a_strex.c b/openssl/crypto/asn1/a_strex.c
new file mode 100644
index 0000000..264ebf2
--- /dev/null
+++ b/openssl/crypto/asn1/a_strex.c
@@ -0,0 +1,574 @@
+/* a_strex.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+
+#include "charmap.h"
+
+/* ASN1_STRING_print_ex() and X509_NAME_print_ex().
+ * Enhanced string and name printing routines handling
+ * multibyte characters, RFC2253 and a host of other
+ * options.
+ */
+
+
+#define CHARTYPE_BS_ESC		(ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253)
+
+#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \
+		  ASN1_STRFLGS_ESC_QUOTE | \
+		  ASN1_STRFLGS_ESC_CTRL | \
+		  ASN1_STRFLGS_ESC_MSB)
+
+
+/* Three IO functions for sending data to memory, a BIO and
+ * and a FILE pointer.
+ */
+#if 0				/* never used */
+static int send_mem_chars(void *arg, const void *buf, int len)
+{
+	unsigned char **out = arg;
+	if(!out) return 1;
+	memcpy(*out, buf, len);
+	*out += len;
+	return 1;
+}
+#endif
+
+static int send_bio_chars(void *arg, const void *buf, int len)
+{
+	if(!arg) return 1;
+	if(BIO_write(arg, buf, len) != len) return 0;
+	return 1;
+}
+
+static int send_fp_chars(void *arg, const void *buf, int len)
+{
+	if(!arg) return 1;
+	if(fwrite(buf, 1, len, arg) != (unsigned int)len) return 0;
+	return 1;
+}
+
+typedef int char_io(void *arg, const void *buf, int len);
+
+/* This function handles display of
+ * strings, one character at a time.
+ * It is passed an unsigned long for each
+ * character because it could come from 2 or even
+ * 4 byte forms.
+ */
+
+static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes, char_io *io_ch, void *arg)
+{
+	unsigned char chflgs, chtmp;
+	char tmphex[HEX_SIZE(long)+3];
+
+	if(c > 0xffffffffL)
+		return -1;
+	if(c > 0xffff) {
+		BIO_snprintf(tmphex, sizeof tmphex, "\\W%08lX", c);
+		if(!io_ch(arg, tmphex, 10)) return -1;
+		return 10;
+	}
+	if(c > 0xff) {
+		BIO_snprintf(tmphex, sizeof tmphex, "\\U%04lX", c);
+		if(!io_ch(arg, tmphex, 6)) return -1;
+		return 6;
+	}
+	chtmp = (unsigned char)c;
+	if(chtmp > 0x7f) chflgs = flags & ASN1_STRFLGS_ESC_MSB;
+	else chflgs = char_type[chtmp] & flags;
+	if(chflgs & CHARTYPE_BS_ESC) {
+		/* If we don't escape with quotes, signal we need quotes */
+		if(chflgs & ASN1_STRFLGS_ESC_QUOTE) {
+			if(do_quotes) *do_quotes = 1;
+			if(!io_ch(arg, &chtmp, 1)) return -1;
+			return 1;
+		}
+		if(!io_ch(arg, "\\", 1)) return -1;
+		if(!io_ch(arg, &chtmp, 1)) return -1;
+		return 2;
+	}
+	if(chflgs & (ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_ESC_MSB)) {
+		BIO_snprintf(tmphex, 11, "\\%02X", chtmp);
+		if(!io_ch(arg, tmphex, 3)) return -1;
+		return 3;
+	}
+	/* If we get this far and do any escaping at all must escape 
+	 * the escape character itself: backslash.
+	 */
+	if (chtmp == '\\' && flags & ESC_FLAGS) {
+		if(!io_ch(arg, "\\\\", 2)) return -1;
+		return 2;
+	}
+	if(!io_ch(arg, &chtmp, 1)) return -1;
+	return 1;
+}
+
+#define BUF_TYPE_WIDTH_MASK	0x7
+#define BUF_TYPE_CONVUTF8	0x8
+
+/* This function sends each character in a buffer to
+ * do_esc_char(). It interprets the content formats
+ * and converts to or from UTF8 as appropriate.
+ */
+
+static int do_buf(unsigned char *buf, int buflen,
+			int type, unsigned char flags, char *quotes, char_io *io_ch, void *arg)
+{
+	int i, outlen, len;
+	unsigned char orflags, *p, *q;
+	unsigned long c;
+	p = buf;
+	q = buf + buflen;
+	outlen = 0;
+	while(p != q) {
+		if(p == buf && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_FIRST_ESC_2253;
+		else orflags = 0;
+		switch(type & BUF_TYPE_WIDTH_MASK) {
+			case 4:
+			c = ((unsigned long)*p++) << 24;
+			c |= ((unsigned long)*p++) << 16;
+			c |= ((unsigned long)*p++) << 8;
+			c |= *p++;
+			break;
+
+			case 2:
+			c = ((unsigned long)*p++) << 8;
+			c |= *p++;
+			break;
+
+			case 1:
+			c = *p++;
+			break;
+			
+			case 0:
+			i = UTF8_getc(p, buflen, &c);
+			if(i < 0) return -1;	/* Invalid UTF8String */
+			p += i;
+			break;
+			default:
+			return -1;	/* invalid width */
+		}
+		if (p == q && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_LAST_ESC_2253;
+		if(type & BUF_TYPE_CONVUTF8) {
+			unsigned char utfbuf[6];
+			int utflen;
+			utflen = UTF8_putc(utfbuf, sizeof utfbuf, c);
+			for(i = 0; i < utflen; i++) {
+				/* We don't need to worry about setting orflags correctly
+				 * because if utflen==1 its value will be correct anyway 
+				 * otherwise each character will be > 0x7f and so the 
+				 * character will never be escaped on first and last.
+				 */
+				len = do_esc_char(utfbuf[i], (unsigned char)(flags | orflags), quotes, io_ch, arg);
+				if(len < 0) return -1;
+				outlen += len;
+			}
+		} else {
+			len = do_esc_char(c, (unsigned char)(flags | orflags), quotes, io_ch, arg);
+			if(len < 0) return -1;
+			outlen += len;
+		}
+	}
+	return outlen;
+}
+
+/* This function hex dumps a buffer of characters */
+
+static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf, int buflen)
+{
+	static const char hexdig[] = "0123456789ABCDEF";
+	unsigned char *p, *q;
+	char hextmp[2];
+	if(arg) {
+		p = buf;
+		q = buf + buflen;
+		while(p != q) {
+			hextmp[0] = hexdig[*p >> 4];
+			hextmp[1] = hexdig[*p & 0xf];
+			if(!io_ch(arg, hextmp, 2)) return -1;
+			p++;
+		}
+	}
+	return buflen << 1;
+}
+
+/* "dump" a string. This is done when the type is unknown,
+ * or the flags request it. We can either dump the content
+ * octets or the entire DER encoding. This uses the RFC2253
+ * #01234 format.
+ */
+
+static int do_dump(unsigned long lflags, char_io *io_ch, void *arg, ASN1_STRING *str)
+{
+	/* Placing the ASN1_STRING in a temp ASN1_TYPE allows
+	 * the DER encoding to readily obtained
+	 */
+	ASN1_TYPE t;
+	unsigned char *der_buf, *p;
+	int outlen, der_len;
+
+	if(!io_ch(arg, "#", 1)) return -1;
+	/* If we don't dump DER encoding just dump content octets */
+	if(!(lflags & ASN1_STRFLGS_DUMP_DER)) {
+		outlen = do_hex_dump(io_ch, arg, str->data, str->length);
+		if(outlen < 0) return -1;
+		return outlen + 1;
+	}
+	t.type = str->type;
+	t.value.ptr = (char *)str;
+	der_len = i2d_ASN1_TYPE(&t, NULL);
+	der_buf = OPENSSL_malloc(der_len);
+	if(!der_buf) return -1;
+	p = der_buf;
+	i2d_ASN1_TYPE(&t, &p);
+	outlen = do_hex_dump(io_ch, arg, der_buf, der_len);
+	OPENSSL_free(der_buf);
+	if(outlen < 0) return -1;
+	return outlen + 1;
+}
+
+/* Lookup table to convert tags to character widths,
+ * 0 = UTF8 encoded, -1 is used for non string types
+ * otherwise it is the number of bytes per character
+ */
+
+static const signed char tag2nbyte[] = {
+	-1, -1, -1, -1, -1,	/* 0-4 */
+	-1, -1, -1, -1, -1,	/* 5-9 */
+	-1, -1, 0, -1,		/* 10-13 */
+	-1, -1, -1, -1,		/* 15-17 */
+	-1, 1, 1,		/* 18-20 */
+	-1, 1, 1, 1,		/* 21-24 */
+	-1, 1, -1,		/* 25-27 */
+	4, -1, 2		/* 28-30 */
+};
+
+/* This is the main function, print out an
+ * ASN1_STRING taking note of various escape
+ * and display options. Returns number of
+ * characters written or -1 if an error
+ * occurred.
+ */
+
+static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags, ASN1_STRING *str)
+{
+	int outlen, len;
+	int type;
+	char quotes;
+	unsigned char flags;
+	quotes = 0;
+	/* Keep a copy of escape flags */
+	flags = (unsigned char)(lflags & ESC_FLAGS);
+
+	type = str->type;
+
+	outlen = 0;
+
+
+	if(lflags & ASN1_STRFLGS_SHOW_TYPE) {
+		const char *tagname;
+		tagname = ASN1_tag2str(type);
+		outlen += strlen(tagname);
+		if(!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1)) return -1; 
+		outlen++;
+	}
+
+	/* Decide what to do with type, either dump content or display it */
+
+	/* Dump everything */
+	if(lflags & ASN1_STRFLGS_DUMP_ALL) type = -1;
+	/* Ignore the string type */
+	else if(lflags & ASN1_STRFLGS_IGNORE_TYPE) type = 1;
+	else {
+		/* Else determine width based on type */
+		if((type > 0) && (type < 31)) type = tag2nbyte[type];
+		else type = -1;
+		if((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN)) type = 1;
+	}
+
+	if(type == -1) {
+		len = do_dump(lflags, io_ch, arg, str);
+		if(len < 0) return -1;
+		outlen += len;
+		return outlen;
+	}
+
+	if(lflags & ASN1_STRFLGS_UTF8_CONVERT) {
+		/* Note: if string is UTF8 and we want
+		 * to convert to UTF8 then we just interpret
+		 * it as 1 byte per character to avoid converting
+		 * twice.
+		 */
+		if(!type) type = 1;
+		else type |= BUF_TYPE_CONVUTF8;
+	}
+
+	len = do_buf(str->data, str->length, type, flags, &quotes, io_ch, NULL);
+	if(len < 0) return -1;
+	outlen += len;
+	if(quotes) outlen += 2;
+	if(!arg) return outlen;
+	if(quotes && !io_ch(arg, "\"", 1)) return -1;
+	if(do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0)
+		return -1;
+	if(quotes && !io_ch(arg, "\"", 1)) return -1;
+	return outlen;
+}
+
+/* Used for line indenting: print 'indent' spaces */
+
+static int do_indent(char_io *io_ch, void *arg, int indent)
+{
+	int i;
+	for(i = 0; i < indent; i++)
+			if(!io_ch(arg, " ", 1)) return 0;
+	return 1;
+}
+
+#define FN_WIDTH_LN	25
+#define FN_WIDTH_SN	10
+
+static int do_name_ex(char_io *io_ch, void *arg, X509_NAME *n,
+				int indent, unsigned long flags)
+{
+	int i, prev = -1, orflags, cnt;
+	int fn_opt, fn_nid;
+	ASN1_OBJECT *fn;
+	ASN1_STRING *val;
+	X509_NAME_ENTRY *ent;
+	char objtmp[80];
+	const char *objbuf;
+	int outlen, len;
+	char *sep_dn, *sep_mv, *sep_eq;
+	int sep_dn_len, sep_mv_len, sep_eq_len;
+	if(indent < 0) indent = 0;
+	outlen = indent;
+	if(!do_indent(io_ch, arg, indent)) return -1;
+	switch (flags & XN_FLAG_SEP_MASK)
+	{
+		case XN_FLAG_SEP_MULTILINE:
+		sep_dn = "\n";
+		sep_dn_len = 1;
+		sep_mv = " + ";
+		sep_mv_len = 3;
+		break;
+
+		case XN_FLAG_SEP_COMMA_PLUS:
+		sep_dn = ",";
+		sep_dn_len = 1;
+		sep_mv = "+";
+		sep_mv_len = 1;
+		indent = 0;
+		break;
+
+		case XN_FLAG_SEP_CPLUS_SPC:
+		sep_dn = ", ";
+		sep_dn_len = 2;
+		sep_mv = " + ";
+		sep_mv_len = 3;
+		indent = 0;
+		break;
+
+		case XN_FLAG_SEP_SPLUS_SPC:
+		sep_dn = "; ";
+		sep_dn_len = 2;
+		sep_mv = " + ";
+		sep_mv_len = 3;
+		indent = 0;
+		break;
+
+		default:
+		return -1;
+	}
+
+	if(flags & XN_FLAG_SPC_EQ) {
+		sep_eq = " = ";
+		sep_eq_len = 3;
+	} else {
+		sep_eq = "=";
+		sep_eq_len = 1;
+	}
+
+	fn_opt = flags & XN_FLAG_FN_MASK;
+
+	cnt = X509_NAME_entry_count(n);	
+	for(i = 0; i < cnt; i++) {
+		if(flags & XN_FLAG_DN_REV)
+				ent = X509_NAME_get_entry(n, cnt - i - 1);
+		else ent = X509_NAME_get_entry(n, i);
+		if(prev != -1) {
+			if(prev == ent->set) {
+				if(!io_ch(arg, sep_mv, sep_mv_len)) return -1;
+				outlen += sep_mv_len;
+			} else {
+				if(!io_ch(arg, sep_dn, sep_dn_len)) return -1;
+				outlen += sep_dn_len;
+				if(!do_indent(io_ch, arg, indent)) return -1;
+				outlen += indent;
+			}
+		}
+		prev = ent->set;
+		fn = X509_NAME_ENTRY_get_object(ent);
+		val = X509_NAME_ENTRY_get_data(ent);
+		fn_nid = OBJ_obj2nid(fn);
+		if(fn_opt != XN_FLAG_FN_NONE) {
+			int objlen, fld_len;
+			if((fn_opt == XN_FLAG_FN_OID) || (fn_nid==NID_undef) ) {
+				OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1);
+				fld_len = 0; /* XXX: what should this be? */
+				objbuf = objtmp;
+			} else {
+				if(fn_opt == XN_FLAG_FN_SN) {
+					fld_len = FN_WIDTH_SN;
+					objbuf = OBJ_nid2sn(fn_nid);
+				} else if(fn_opt == XN_FLAG_FN_LN) {
+					fld_len = FN_WIDTH_LN;
+					objbuf = OBJ_nid2ln(fn_nid);
+				} else {
+					fld_len = 0; /* XXX: what should this be? */
+					objbuf = "";
+				}
+			}
+			objlen = strlen(objbuf);
+			if(!io_ch(arg, objbuf, objlen)) return -1;
+			if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
+				if (!do_indent(io_ch, arg, fld_len - objlen)) return -1;
+				outlen += fld_len - objlen;
+			}
+			if(!io_ch(arg, sep_eq, sep_eq_len)) return -1;
+			outlen += objlen + sep_eq_len;
+		}
+		/* If the field name is unknown then fix up the DER dump
+		 * flag. We might want to limit this further so it will
+ 		 * DER dump on anything other than a few 'standard' fields.
+		 */
+		if((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS)) 
+					orflags = ASN1_STRFLGS_DUMP_ALL;
+		else orflags = 0;
+     
+		len = do_print_ex(io_ch, arg, flags | orflags, val);
+		if(len < 0) return -1;
+		outlen += len;
+	}
+	return outlen;
+}
+
+/* Wrappers round the main functions */
+
+int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags)
+{
+	if(flags == XN_FLAG_COMPAT)
+		return X509_NAME_print(out, nm, indent);
+	return do_name_ex(send_bio_chars, out, nm, indent, flags);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags)
+{
+	if(flags == XN_FLAG_COMPAT)
+		{
+		BIO *btmp;
+		int ret;
+		btmp = BIO_new_fp(fp, BIO_NOCLOSE);
+		if(!btmp) return -1;
+		ret = X509_NAME_print(btmp, nm, indent);
+		BIO_free(btmp);
+		return ret;
+		}
+	return do_name_ex(send_fp_chars, fp, nm, indent, flags);
+}
+#endif
+
+int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags)
+{
+	return do_print_ex(send_bio_chars, out, flags, str);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags)
+{
+	return do_print_ex(send_fp_chars, fp, flags, str);
+}
+#endif
+
+/* Utility function: convert any string type to UTF8, returns number of bytes
+ * in output string or a negative error code
+ */
+
+int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in)
+{
+	ASN1_STRING stmp, *str = &stmp;
+	int mbflag, type, ret;
+	if(!in) return -1;
+	type = in->type;
+	if((type < 0) || (type > 30)) return -1;
+	mbflag = tag2nbyte[type];
+	if(mbflag == -1) return -1;
+	mbflag |= MBSTRING_FLAG;
+	stmp.data = NULL;
+	ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING);
+	if(ret < 0) return ret;
+	*out = stmp.data;
+	return stmp.length;
+}
diff --git a/openssl/crypto/asn1/a_strnid.c b/openssl/crypto/asn1/a_strnid.c
new file mode 100644
index 0000000..2fc48c1
--- /dev/null
+++ b/openssl/crypto/asn1/a_strnid.c
@@ -0,0 +1,290 @@
+/* a_strnid.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+
+
+static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
+static void st_free(ASN1_STRING_TABLE *tbl);
+static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
+			const ASN1_STRING_TABLE * const *b);
+
+
+/* This is the global mask for the mbstring functions: this is use to
+ * mask out certain types (such as BMPString and UTF8String) because
+ * certain software (e.g. Netscape) has problems with them.
+ */
+
+static unsigned long global_mask = 0xFFFFFFFFL;
+
+void ASN1_STRING_set_default_mask(unsigned long mask)
+{
+	global_mask = mask;
+}
+
+unsigned long ASN1_STRING_get_default_mask(void)
+{
+	return global_mask;
+}
+
+/* This function sets the default to various "flavours" of configuration.
+ * based on an ASCII string. Currently this is:
+ * MASK:XXXX : a numerical mask value.
+ * nobmp : Don't use BMPStrings (just Printable, T61).
+ * pkix : PKIX recommendation in RFC2459.
+ * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004).
+ * default:   the default value, Printable, T61, BMP.
+ */
+
+int ASN1_STRING_set_default_mask_asc(const char *p)
+{
+	unsigned long mask;
+	char *end;
+	if(!strncmp(p, "MASK:", 5)) {
+		if(!p[5]) return 0;
+		mask = strtoul(p + 5, &end, 0);
+		if(*end) return 0;
+	} else if(!strcmp(p, "nombstr"))
+			 mask = ~((unsigned long)(B_ASN1_BMPSTRING|B_ASN1_UTF8STRING));
+	else if(!strcmp(p, "pkix"))
+			mask = ~((unsigned long)B_ASN1_T61STRING);
+	else if(!strcmp(p, "utf8only")) mask = B_ASN1_UTF8STRING;
+	else if(!strcmp(p, "default"))
+	    mask = 0xFFFFFFFFL;
+	else return 0;
+	ASN1_STRING_set_default_mask(mask);
+	return 1;
+}
+
+/* The following function generates an ASN1_STRING based on limits in a table.
+ * Frequently the types and length of an ASN1_STRING are restricted by a 
+ * corresponding OID. For example certificates and certificate requests.
+ */
+
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in,
+					int inlen, int inform, int nid)
+{
+	ASN1_STRING_TABLE *tbl;
+	ASN1_STRING *str = NULL;
+	unsigned long mask;
+	int ret;
+	if(!out) out = &str;
+	tbl = ASN1_STRING_TABLE_get(nid);
+	if(tbl) {
+		mask = tbl->mask;
+		if(!(tbl->flags & STABLE_NO_MASK)) mask &= global_mask;
+		ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
+					tbl->minsize, tbl->maxsize);
+	} else ret = ASN1_mbstring_copy(out, in, inlen, inform, DIRSTRING_TYPE & global_mask);
+	if(ret <= 0) return NULL;
+	return *out;
+}
+
+/* Now the tables and helper functions for the string table:
+ */
+
+/* size limits: this stuff is taken straight from RFC3280 */
+
+#define ub_name				32768
+#define ub_common_name			64
+#define ub_locality_name		128
+#define ub_state_name			128
+#define ub_organization_name		64
+#define ub_organization_unit_name	64
+#define ub_title			64
+#define ub_email_address		128
+#define ub_serial_number		64
+
+
+/* This table must be kept in NID order */
+
+static const ASN1_STRING_TABLE tbl_standard[] = {
+{NID_commonName,		1, ub_common_name, DIRSTRING_TYPE, 0},
+{NID_countryName,		2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+{NID_localityName,		1, ub_locality_name, DIRSTRING_TYPE, 0},
+{NID_stateOrProvinceName,	1, ub_state_name, DIRSTRING_TYPE, 0},
+{NID_organizationName,		1, ub_organization_name, DIRSTRING_TYPE, 0},
+{NID_organizationalUnitName,	1, ub_organization_unit_name, DIRSTRING_TYPE, 0},
+{NID_pkcs9_emailAddress,	1, ub_email_address, B_ASN1_IA5STRING, STABLE_NO_MASK},
+{NID_pkcs9_unstructuredName,	1, -1, PKCS9STRING_TYPE, 0},
+{NID_pkcs9_challengePassword,	1, -1, PKCS9STRING_TYPE, 0},
+{NID_pkcs9_unstructuredAddress,	1, -1, DIRSTRING_TYPE, 0},
+{NID_givenName,			1, ub_name, DIRSTRING_TYPE, 0},
+{NID_surname,			1, ub_name, DIRSTRING_TYPE, 0},
+{NID_initials,			1, ub_name, DIRSTRING_TYPE, 0},
+{NID_serialNumber,		1, ub_serial_number, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+{NID_friendlyName,		-1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
+{NID_name,			1, ub_name, DIRSTRING_TYPE, 0},
+{NID_dnQualifier,		-1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+{NID_domainComponent,		1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
+{NID_ms_csp_name,		-1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
+};
+
+static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
+			const ASN1_STRING_TABLE * const *b)
+{
+	return (*a)->nid - (*b)->nid;
+}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
+
+static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b)
+{
+	return a->nid - b->nid;
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
+
+ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
+{
+	int idx;
+	ASN1_STRING_TABLE *ttmp;
+	ASN1_STRING_TABLE fnd;
+	fnd.nid = nid;
+	ttmp = OBJ_bsearch_table(&fnd, tbl_standard, 
+			   sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE));
+	if(ttmp) return ttmp;
+	if(!stable) return NULL;
+	idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
+	if(idx < 0) return NULL;
+	return sk_ASN1_STRING_TABLE_value(stable, idx);
+}
+	
+int ASN1_STRING_TABLE_add(int nid,
+		 long minsize, long maxsize, unsigned long mask,
+				unsigned long flags)
+{
+	ASN1_STRING_TABLE *tmp;
+	char new_nid = 0;
+	flags &= ~STABLE_FLAGS_MALLOC;
+	if(!stable) stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
+	if(!stable) {
+		ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	if(!(tmp = ASN1_STRING_TABLE_get(nid))) {
+		tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE));
+		if(!tmp) {
+			ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD,
+							ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		tmp->flags = flags | STABLE_FLAGS_MALLOC;
+		tmp->nid = nid;
+		new_nid = 1;
+	} else tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
+	if(minsize != -1) tmp->minsize = minsize;
+	if(maxsize != -1) tmp->maxsize = maxsize;
+	tmp->mask = mask;
+	if(new_nid) sk_ASN1_STRING_TABLE_push(stable, tmp);
+	return 1;
+}
+
+void ASN1_STRING_TABLE_cleanup(void)
+{
+	STACK_OF(ASN1_STRING_TABLE) *tmp;
+	tmp = stable;
+	if(!tmp) return;
+	stable = NULL;
+	sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
+}
+
+static void st_free(ASN1_STRING_TABLE *tbl)
+{
+	if(tbl->flags & STABLE_FLAGS_MALLOC) OPENSSL_free(tbl);
+}
+
+
+IMPLEMENT_STACK_OF(ASN1_STRING_TABLE)
+
+#ifdef STRING_TABLE_TEST
+
+main()
+{
+	ASN1_STRING_TABLE *tmp;
+	int i, last_nid = -1;
+
+	for (tmp = tbl_standard, i = 0;
+		i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
+		{
+			if (tmp->nid < last_nid)
+				{
+				last_nid = 0;
+				break;
+				}
+			last_nid = tmp->nid;
+		}
+
+	if (last_nid != 0)
+		{
+		printf("Table order OK\n");
+		exit(0);
+		}
+
+	for (tmp = tbl_standard, i = 0;
+		i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
+			printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
+							OBJ_nid2ln(tmp->nid));
+
+}
+
+#endif
diff --git a/openssl/crypto/asn1/a_time.c b/openssl/crypto/asn1/a_time.c
new file mode 100644
index 0000000..e2eb9b2
--- /dev/null
+++ b/openssl/crypto/asn1/a_time.c
@@ -0,0 +1,198 @@
+/* crypto/asn1/a_time.c */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+/* This is an implementation of the ASN1 Time structure which is:
+ *    Time ::= CHOICE {
+ *      utcTime        UTCTime,
+ *      generalTime    GeneralizedTime }
+ * written by Steve Henson.
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "o_time.h"
+#include <openssl/asn1t.h>
+
+IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME)
+
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME)
+
+#if 0
+int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp)
+	{
+#ifdef CHARSET_EBCDIC
+	/* KLUDGE! We convert to ascii before writing DER */
+	char tmp[24];
+	ASN1_STRING tmpstr;
+
+	if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) {
+	    int len;
+
+	    tmpstr = *(ASN1_STRING *)a;
+	    len = tmpstr.length;
+	    ebcdic2ascii(tmp, tmpstr.data, (len >= sizeof tmp) ? sizeof tmp : len);
+	    tmpstr.data = tmp;
+	    a = (ASN1_GENERALIZEDTIME *) &tmpstr;
+	}
+#endif
+	if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME)
+				return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
+				     a->type ,V_ASN1_UNIVERSAL));
+	ASN1err(ASN1_F_I2D_ASN1_TIME,ASN1_R_EXPECTING_A_TIME);
+	return -1;
+	}
+#endif
+
+
+ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)
+	{
+	return ASN1_TIME_adj(s, t, 0, 0);
+	}
+
+ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
+				int offset_day, long offset_sec)
+	{
+	struct tm *ts;
+	struct tm data;
+
+	ts=OPENSSL_gmtime(&t,&data);
+	if (ts == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME);
+		return NULL;
+		}
+	if (offset_day || offset_sec)
+		{ 
+		if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+			return NULL;
+		}
+	if((ts->tm_year >= 50) && (ts->tm_year < 150))
+			return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
+	return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
+	}
+
+int ASN1_TIME_check(ASN1_TIME *t)
+	{
+	if (t->type == V_ASN1_GENERALIZEDTIME)
+		return ASN1_GENERALIZEDTIME_check(t);
+	else if (t->type == V_ASN1_UTCTIME)
+		return ASN1_UTCTIME_check(t);
+	return 0;
+	}
+
+/* Convert an ASN1_TIME structure to GeneralizedTime */
+ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
+	{
+	ASN1_GENERALIZEDTIME *ret;
+	char *str;
+	int newlen;
+
+	if (!ASN1_TIME_check(t)) return NULL;
+
+	if (!out || !*out)
+		{
+		if (!(ret = ASN1_GENERALIZEDTIME_new ()))
+			return NULL;
+		if (out) *out = ret;
+		}
+	else ret = *out;
+
+	/* If already GeneralizedTime just copy across */
+	if (t->type == V_ASN1_GENERALIZEDTIME)
+		{
+		if(!ASN1_STRING_set(ret, t->data, t->length))
+			return NULL;
+		return ret;
+		}
+
+	/* grow the string */
+	if (!ASN1_STRING_set(ret, NULL, t->length + 2))
+		return NULL;
+	/* ASN1_STRING_set() allocated 'len + 1' bytes. */
+	newlen = t->length + 2 + 1;
+	str = (char *)ret->data;
+	/* Work out the century and prepend */
+	if (t->data[0] >= '5') BUF_strlcpy(str, "19", newlen);
+	else BUF_strlcpy(str, "20", newlen);
+
+	BUF_strlcat(str, (char *)t->data, newlen);
+
+	return ret;
+	}
+
+int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
+	{
+	ASN1_TIME t;
+
+	t.length = strlen(str);
+	t.data = (unsigned char *)str;
+	t.flags = 0;
+	
+	t.type = V_ASN1_UTCTIME;
+
+	if (!ASN1_TIME_check(&t))
+		{
+		t.type = V_ASN1_GENERALIZEDTIME;
+		if (!ASN1_TIME_check(&t))
+			return 0;
+		}
+	
+	if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
+			return 0;
+
+	return 1;
+	}
diff --git a/openssl/crypto/asn1/a_type.c b/openssl/crypto/asn1/a_type.c
new file mode 100644
index 0000000..a45d2f9
--- /dev/null
+++ b/openssl/crypto/asn1/a_type.c
@@ -0,0 +1,159 @@
+/* crypto/asn1/a_type.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+
+int ASN1_TYPE_get(ASN1_TYPE *a)
+	{
+	if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
+		return(a->type);
+	else
+		return(0);
+	}
+
+void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
+	{
+	if (a->value.ptr != NULL)
+		{
+		ASN1_TYPE **tmp_a = &a;
+		ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
+		}
+	a->type=type;
+	if (type == V_ASN1_BOOLEAN)
+		a->value.boolean = value ? 0xff : 0;
+	else
+		a->value.ptr=value;
+	}
+
+int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
+	{
+	if (!value || (type == V_ASN1_BOOLEAN))
+		{
+		void *p = (void *)value;
+		ASN1_TYPE_set(a, type, p);
+		}
+	else if (type == V_ASN1_OBJECT)
+		{
+		ASN1_OBJECT *odup;
+		odup = OBJ_dup(value);
+		if (!odup)
+			return 0;
+		ASN1_TYPE_set(a, type, odup);
+		}
+	else
+		{
+		ASN1_STRING *sdup;
+		sdup = ASN1_STRING_dup(value);
+		if (!sdup)
+			return 0;
+		ASN1_TYPE_set(a, type, sdup);
+		}
+	return 1;
+	}
+
+IMPLEMENT_STACK_OF(ASN1_TYPE)
+IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
+
+/* Returns 0 if they are equal, != 0 otherwise. */
+int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
+	{
+	int result = -1;
+
+	if (!a || !b || a->type != b->type) return -1;
+
+	switch (a->type)
+		{
+	case V_ASN1_OBJECT:
+		result = OBJ_cmp(a->value.object, b->value.object);
+		break;
+	case V_ASN1_NULL:
+		result = 0;	/* They do not have content. */
+		break;
+	case V_ASN1_INTEGER:
+	case V_ASN1_NEG_INTEGER:
+	case V_ASN1_ENUMERATED:
+	case V_ASN1_NEG_ENUMERATED:
+	case V_ASN1_BIT_STRING:
+	case V_ASN1_OCTET_STRING:
+	case V_ASN1_SEQUENCE:
+	case V_ASN1_SET:
+	case V_ASN1_NUMERICSTRING:
+	case V_ASN1_PRINTABLESTRING:
+	case V_ASN1_T61STRING:
+	case V_ASN1_VIDEOTEXSTRING:
+	case V_ASN1_IA5STRING:
+	case V_ASN1_UTCTIME:
+	case V_ASN1_GENERALIZEDTIME:
+	case V_ASN1_GRAPHICSTRING:
+	case V_ASN1_VISIBLESTRING:
+	case V_ASN1_GENERALSTRING:
+	case V_ASN1_UNIVERSALSTRING:
+	case V_ASN1_BMPSTRING:
+	case V_ASN1_UTF8STRING:
+	case V_ASN1_OTHER:
+	default:
+		result = ASN1_STRING_cmp((ASN1_STRING *) a->value.ptr,
+					 (ASN1_STRING *) b->value.ptr);
+		break;
+		}
+
+	return result;
+	}
diff --git a/openssl/crypto/asn1/a_utctm.c b/openssl/crypto/asn1/a_utctm.c
new file mode 100644
index 0000000..072e236
--- /dev/null
+++ b/openssl/crypto/asn1/a_utctm.c
@@ -0,0 +1,318 @@
+/* crypto/asn1/a_utctm.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "o_time.h"
+#include <openssl/asn1.h>
+
+#if 0
+int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp)
+	{
+#ifndef CHARSET_EBCDIC
+	return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
+		V_ASN1_UTCTIME,V_ASN1_UNIVERSAL));
+#else
+	/* KLUDGE! We convert to ascii before writing DER */
+	int len;
+	char tmp[24];
+	ASN1_STRING x = *(ASN1_STRING *)a;
+
+	len = x.length;
+	ebcdic2ascii(tmp, x.data, (len >= sizeof tmp) ? sizeof tmp : len);
+	x.data = tmp;
+	return i2d_ASN1_bytes(&x, pp, V_ASN1_UTCTIME,V_ASN1_UNIVERSAL);
+#endif
+	}
+
+
+ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp,
+	     long length)
+	{
+	ASN1_UTCTIME *ret=NULL;
+
+	ret=(ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a,pp,length,
+		V_ASN1_UTCTIME,V_ASN1_UNIVERSAL);
+	if (ret == NULL)
+		{
+		ASN1err(ASN1_F_D2I_ASN1_UTCTIME,ERR_R_NESTED_ASN1_ERROR);
+		return(NULL);
+		}
+#ifdef CHARSET_EBCDIC
+	ascii2ebcdic(ret->data, ret->data, ret->length);
+#endif
+	if (!ASN1_UTCTIME_check(ret))
+		{
+		ASN1err(ASN1_F_D2I_ASN1_UTCTIME,ASN1_R_INVALID_TIME_FORMAT);
+		goto err;
+		}
+
+	return(ret);
+err:
+	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+		M_ASN1_UTCTIME_free(ret);
+	return(NULL);
+	}
+
+#endif
+
+int ASN1_UTCTIME_check(ASN1_UTCTIME *d)
+	{
+	static const int min[8]={ 0, 1, 1, 0, 0, 0, 0, 0};
+	static const int max[8]={99,12,31,23,59,59,12,59};
+	char *a;
+	int n,i,l,o;
+
+	if (d->type != V_ASN1_UTCTIME) return(0);
+	l=d->length;
+	a=(char *)d->data;
+	o=0;
+
+	if (l < 11) goto err;
+	for (i=0; i<6; i++)
+		{
+		if ((i == 5) && ((a[o] == 'Z') ||
+			(a[o] == '+') || (a[o] == '-')))
+			{ i++; break; }
+		if ((a[o] < '0') || (a[o] > '9')) goto err;
+		n= a[o]-'0';
+		if (++o > l) goto err;
+
+		if ((a[o] < '0') || (a[o] > '9')) goto err;
+		n=(n*10)+ a[o]-'0';
+		if (++o > l) goto err;
+
+		if ((n < min[i]) || (n > max[i])) goto err;
+		}
+	if (a[o] == 'Z')
+		o++;
+	else if ((a[o] == '+') || (a[o] == '-'))
+		{
+		o++;
+		if (o+4 > l) goto err;
+		for (i=6; i<8; i++)
+			{
+			if ((a[o] < '0') || (a[o] > '9')) goto err;
+			n= a[o]-'0';
+			o++;
+			if ((a[o] < '0') || (a[o] > '9')) goto err;
+			n=(n*10)+ a[o]-'0';
+			if ((n < min[i]) || (n > max[i])) goto err;
+			o++;
+			}
+		}
+	return(o == l);
+err:
+	return(0);
+	}
+
+int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
+	{
+	ASN1_UTCTIME t;
+
+	t.type=V_ASN1_UTCTIME;
+	t.length=strlen(str);
+	t.data=(unsigned char *)str;
+	if (ASN1_UTCTIME_check(&t))
+		{
+		if (s != NULL)
+			{
+			if (!ASN1_STRING_set((ASN1_STRING *)s,
+				(unsigned char *)str,t.length))
+				return 0;
+			s->type = V_ASN1_UTCTIME;
+			}
+		return(1);
+		}
+	else
+		return(0);
+	}
+
+ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
+	{
+	return ASN1_UTCTIME_adj(s, t, 0, 0);
+	}
+
+ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
+				int offset_day, long offset_sec)
+	{
+	char *p;
+	struct tm *ts;
+	struct tm data;
+	size_t len = 20;
+
+	if (s == NULL)
+		s=M_ASN1_UTCTIME_new();
+	if (s == NULL)
+		return(NULL);
+
+	ts=OPENSSL_gmtime(&t, &data);
+	if (ts == NULL)
+		return(NULL);
+
+	if (offset_day || offset_sec)
+		{ 
+		if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+			return NULL;
+		}
+
+	if((ts->tm_year < 50) || (ts->tm_year >= 150))
+		return NULL;
+
+	p=(char *)s->data;
+	if ((p == NULL) || ((size_t)s->length < len))
+		{
+		p=OPENSSL_malloc(len);
+		if (p == NULL)
+			{
+			ASN1err(ASN1_F_ASN1_UTCTIME_ADJ,ERR_R_MALLOC_FAILURE);
+			return(NULL);
+			}
+		if (s->data != NULL)
+			OPENSSL_free(s->data);
+		s->data=(unsigned char *)p;
+		}
+
+	BIO_snprintf(p,len,"%02d%02d%02d%02d%02d%02dZ",ts->tm_year%100,
+		     ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
+	s->length=strlen(p);
+	s->type=V_ASN1_UTCTIME;
+#ifdef CHARSET_EBCDIC_not
+	ebcdic2ascii(s->data, s->data, s->length);
+#endif
+	return(s);
+	}
+
+
+int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
+	{
+	struct tm *tm;
+	struct tm data;
+	int offset;
+	int year;
+
+#define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
+
+	if (s->data[12] == 'Z')
+		offset=0;
+	else
+		{
+		offset = g2(s->data+13)*60+g2(s->data+15);
+		if (s->data[12] == '-')
+			offset = -offset;
+		}
+
+	t -= offset*60; /* FIXME: may overflow in extreme cases */
+
+	tm = OPENSSL_gmtime(&t, &data);
+	
+#define return_cmp(a,b) if ((a)<(b)) return -1; else if ((a)>(b)) return 1
+	year = g2(s->data);
+	if (year < 50)
+		year += 100;
+	return_cmp(year,              tm->tm_year);
+	return_cmp(g2(s->data+2) - 1, tm->tm_mon);
+	return_cmp(g2(s->data+4),     tm->tm_mday);
+	return_cmp(g2(s->data+6),     tm->tm_hour);
+	return_cmp(g2(s->data+8),     tm->tm_min);
+	return_cmp(g2(s->data+10),    tm->tm_sec);
+#undef g2
+#undef return_cmp
+
+	return 0;
+	}
+
+
+#if 0
+time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s)
+	{
+	struct tm tm;
+	int offset;
+
+	memset(&tm,'\0',sizeof tm);
+
+#define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
+	tm.tm_year=g2(s->data);
+	if(tm.tm_year < 50)
+		tm.tm_year+=100;
+	tm.tm_mon=g2(s->data+2)-1;
+	tm.tm_mday=g2(s->data+4);
+	tm.tm_hour=g2(s->data+6);
+	tm.tm_min=g2(s->data+8);
+	tm.tm_sec=g2(s->data+10);
+	if(s->data[12] == 'Z')
+		offset=0;
+	else
+		{
+		offset=g2(s->data+13)*60+g2(s->data+15);
+		if(s->data[12] == '-')
+			offset= -offset;
+		}
+#undef g2
+
+	return mktime(&tm)-offset*60; /* FIXME: mktime assumes the current timezone
+	                               * instead of UTC, and unless we rewrite OpenSSL
+				       * in Lisp we cannot locally change the timezone
+				       * without possibly interfering with other parts
+	                               * of the program. timegm, which uses UTC, is
+				       * non-standard.
+	                               * Also time_t is inappropriate for general
+	                               * UTC times because it may a 32 bit type. */
+	}
+#endif
diff --git a/openssl/crypto/asn1/a_utf8.c b/openssl/crypto/asn1/a_utf8.c
new file mode 100644
index 0000000..508e11e
--- /dev/null
+++ b/openssl/crypto/asn1/a_utf8.c
@@ -0,0 +1,211 @@
+/* crypto/asn1/a_utf8.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+
+
+/* UTF8 utilities */
+
+/* This parses a UTF8 string one character at a time. It is passed a pointer
+ * to the string and the length of the string. It sets 'value' to the value of
+ * the current character. It returns the number of characters read or a
+ * negative error code:
+ * -1 = string too short
+ * -2 = illegal character
+ * -3 = subsequent characters not of the form 10xxxxxx
+ * -4 = character encoded incorrectly (not minimal length).
+ */
+
+int UTF8_getc(const unsigned char *str, int len, unsigned long *val)
+{
+	const unsigned char *p;
+	unsigned long value;
+	int ret;
+	if(len <= 0) return 0;
+	p = str;
+
+	/* Check syntax and work out the encoded value (if correct) */
+	if((*p & 0x80) == 0) {
+		value = *p++ & 0x7f;
+		ret = 1;
+	} else if((*p & 0xe0) == 0xc0) {
+		if(len < 2) return -1;
+		if((p[1] & 0xc0) != 0x80) return -3;
+		value = (*p++ & 0x1f) << 6;
+		value |= *p++ & 0x3f;
+		if(value < 0x80) return -4;
+		ret = 2;
+	} else if((*p & 0xf0) == 0xe0) {
+		if(len < 3) return -1;
+		if( ((p[1] & 0xc0) != 0x80)
+		   || ((p[2] & 0xc0) != 0x80) ) return -3;
+		value = (*p++ & 0xf) << 12;
+		value |= (*p++ & 0x3f) << 6;
+		value |= *p++ & 0x3f;
+		if(value < 0x800) return -4;
+		ret = 3;
+	} else if((*p & 0xf8) == 0xf0) {
+		if(len < 4) return -1;
+		if( ((p[1] & 0xc0) != 0x80)
+		   || ((p[2] & 0xc0) != 0x80) 
+		   || ((p[3] & 0xc0) != 0x80) ) return -3;
+		value = ((unsigned long)(*p++ & 0x7)) << 18;
+		value |= (*p++ & 0x3f) << 12;
+		value |= (*p++ & 0x3f) << 6;
+		value |= *p++ & 0x3f;
+		if(value < 0x10000) return -4;
+		ret = 4;
+	} else if((*p & 0xfc) == 0xf8) {
+		if(len < 5) return -1;
+		if( ((p[1] & 0xc0) != 0x80)
+		   || ((p[2] & 0xc0) != 0x80) 
+		   || ((p[3] & 0xc0) != 0x80) 
+		   || ((p[4] & 0xc0) != 0x80) ) return -3;
+		value = ((unsigned long)(*p++ & 0x3)) << 24;
+		value |= ((unsigned long)(*p++ & 0x3f)) << 18;
+		value |= ((unsigned long)(*p++ & 0x3f)) << 12;
+		value |= (*p++ & 0x3f) << 6;
+		value |= *p++ & 0x3f;
+		if(value < 0x200000) return -4;
+		ret = 5;
+	} else if((*p & 0xfe) == 0xfc) {
+		if(len < 6) return -1;
+		if( ((p[1] & 0xc0) != 0x80)
+		   || ((p[2] & 0xc0) != 0x80) 
+		   || ((p[3] & 0xc0) != 0x80) 
+		   || ((p[4] & 0xc0) != 0x80) 
+		   || ((p[5] & 0xc0) != 0x80) ) return -3;
+		value = ((unsigned long)(*p++ & 0x1)) << 30;
+		value |= ((unsigned long)(*p++ & 0x3f)) << 24;
+		value |= ((unsigned long)(*p++ & 0x3f)) << 18;
+		value |= ((unsigned long)(*p++ & 0x3f)) << 12;
+		value |= (*p++ & 0x3f) << 6;
+		value |= *p++ & 0x3f;
+		if(value < 0x4000000) return -4;
+		ret = 6;
+	} else return -2;
+	*val = value;
+	return ret;
+}
+
+/* This takes a character 'value' and writes the UTF8 encoded value in
+ * 'str' where 'str' is a buffer containing 'len' characters. Returns
+ * the number of characters written or -1 if 'len' is too small. 'str' can
+ * be set to NULL in which case it just returns the number of characters.
+ * It will need at most 6 characters.
+ */
+
+int UTF8_putc(unsigned char *str, int len, unsigned long value)
+{
+	if(!str) len = 6;	/* Maximum we will need */
+	else if(len <= 0) return -1;
+	if(value < 0x80) {
+		if(str) *str = (unsigned char)value;
+		return 1;
+	}
+	if(value < 0x800) {
+		if(len < 2) return -1;
+		if(str) {
+			*str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
+			*str = (unsigned char)((value & 0x3f) | 0x80);
+		}
+		return 2;
+	}
+	if(value < 0x10000) {
+		if(len < 3) return -1;
+		if(str) {
+			*str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
+			*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+			*str = (unsigned char)((value & 0x3f) | 0x80);
+		}
+		return 3;
+	}
+	if(value < 0x200000) {
+		if(len < 4) return -1;
+		if(str) {
+			*str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
+			*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+			*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+			*str = (unsigned char)((value & 0x3f) | 0x80);
+		}
+		return 4;
+	}
+	if(value < 0x4000000) {
+		if(len < 5) return -1;
+		if(str) {
+			*str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8);
+			*str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
+			*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+			*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+			*str = (unsigned char)((value & 0x3f) | 0x80);
+		}
+		return 5;
+	}
+	if(len < 6) return -1;
+	if(str) {
+		*str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc);
+		*str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80);
+		*str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
+		*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+		*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+		*str = (unsigned char)((value & 0x3f) | 0x80);
+	}
+	return 6;
+}
diff --git a/openssl/crypto/asn1/a_verify.c b/openssl/crypto/asn1/a_verify.c
new file mode 100644
index 0000000..cecdb13
--- /dev/null
+++ b/openssl/crypto/asn1/a_verify.c
@@ -0,0 +1,197 @@
+/* crypto/asn1/a_verify.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <time.h>
+
+#include "cryptlib.h"
+#include "asn1_locl.h"
+
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+
+#ifndef NO_ASN1_OLD
+
+int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
+		char *data, EVP_PKEY *pkey)
+	{
+	EVP_MD_CTX ctx;
+	const EVP_MD *type;
+	unsigned char *p,*buf_in=NULL;
+	int ret= -1,i,inl;
+
+	EVP_MD_CTX_init(&ctx);
+	i=OBJ_obj2nid(a->algorithm);
+	type=EVP_get_digestbyname(OBJ_nid2sn(i));
+	if (type == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+		goto err;
+		}
+	
+	inl=i2d(data,NULL);
+	buf_in=OPENSSL_malloc((unsigned int)inl);
+	if (buf_in == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	p=buf_in;
+
+	i2d(data,&p);
+	EVP_VerifyInit_ex(&ctx,type, NULL);
+	EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl);
+
+	OPENSSL_cleanse(buf_in,(unsigned int)inl);
+	OPENSSL_free(buf_in);
+
+	if (EVP_VerifyFinal(&ctx,(unsigned char *)signature->data,
+			(unsigned int)signature->length,pkey) <= 0)
+		{
+		ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_EVP_LIB);
+		ret=0;
+		goto err;
+		}
+	/* we don't need to zero the 'ctx' because we just checked
+	 * public information */
+	/* memset(&ctx,0,sizeof(ctx)); */
+	ret=1;
+err:
+	EVP_MD_CTX_cleanup(&ctx);
+	return(ret);
+	}
+
+#endif
+
+
+int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signature,
+	     void *asn, EVP_PKEY *pkey)
+	{
+	EVP_MD_CTX ctx;
+	const EVP_MD *type = NULL;
+	unsigned char *buf_in=NULL;
+	int ret= -1,inl;
+
+	int mdnid, pknid;
+
+	EVP_MD_CTX_init(&ctx);
+
+	/* Convert signature OID into digest and public key OIDs */
+	if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid))
+		{
+		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
+		goto err;
+		}
+	type=EVP_get_digestbynid(mdnid);
+	if (type == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+		goto err;
+		}
+
+	/* Check public key OID matches public key type */
+	if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id)
+		{
+		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_WRONG_PUBLIC_KEY_TYPE);
+		goto err;
+		}
+
+	if (!EVP_VerifyInit_ex(&ctx,type, NULL))
+		{
+		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
+		ret=0;
+		goto err;
+		}
+
+	inl = ASN1_item_i2d(asn, &buf_in, it);
+	
+	if (buf_in == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl);
+
+	OPENSSL_cleanse(buf_in,(unsigned int)inl);
+	OPENSSL_free(buf_in);
+
+	if (EVP_VerifyFinal(&ctx,(unsigned char *)signature->data,
+			(unsigned int)signature->length,pkey) <= 0)
+		{
+		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
+		ret=0;
+		goto err;
+		}
+	/* we don't need to zero the 'ctx' because we just checked
+	 * public information */
+	/* memset(&ctx,0,sizeof(ctx)); */
+	ret=1;
+err:
+	EVP_MD_CTX_cleanup(&ctx);
+	return(ret);
+	}
+
+
diff --git a/openssl/crypto/asn1/ameth_lib.c b/openssl/crypto/asn1/ameth_lib.c
new file mode 100644
index 0000000..5a581b9
--- /dev/null
+++ b/openssl/crypto/asn1/ameth_lib.c
@@ -0,0 +1,450 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include "asn1_locl.h"
+
+extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
+extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[];
+extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
+
+/* Keep this sorted in type order !! */
+static const EVP_PKEY_ASN1_METHOD *standard_methods[] = 
+	{
+#ifndef OPENSSL_NO_RSA
+	&rsa_asn1_meths[0],
+	&rsa_asn1_meths[1],
+#endif
+#ifndef OPENSSL_NO_DH
+	&dh_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_DSA
+	&dsa_asn1_meths[0],
+	&dsa_asn1_meths[1],
+	&dsa_asn1_meths[2],
+	&dsa_asn1_meths[3],
+	&dsa_asn1_meths[4],
+#endif
+#ifndef OPENSSL_NO_EC
+	&eckey_asn1_meth,
+#endif
+	&hmac_asn1_meth
+	};
+
+typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
+DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD)
+static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
+
+
+
+#ifdef TEST
+void main()
+	{
+	int i;
+	for (i = 0;
+		i < sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
+		i++)
+		fprintf(stderr, "Number %d id=%d (%s)\n", i,
+			standard_methods[i]->pkey_id,
+			OBJ_nid2sn(standard_methods[i]->pkey_id));
+	}
+#endif
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
+			   const EVP_PKEY_ASN1_METHOD *, ameth);
+
+static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a,
+		     const EVP_PKEY_ASN1_METHOD * const *b)
+	{
+        return ((*a)->pkey_id - (*b)->pkey_id);
+	}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
+			     const EVP_PKEY_ASN1_METHOD *, ameth);
+
+int EVP_PKEY_asn1_get_count(void)
+	{
+	int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
+	if (app_methods)
+		num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
+	return num;
+	}
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
+	{
+	int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
+	if (idx < 0)
+		return NULL; 
+	if (idx < num)
+		return standard_methods[idx];
+	idx -= num;
+	return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
+	}
+
+static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
+	{
+	EVP_PKEY_ASN1_METHOD tmp;
+	const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
+	tmp.pkey_id = type;
+	if (app_methods)
+		{
+		int idx;
+		idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
+		if (idx >= 0)
+			return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
+		}
+	ret = OBJ_bsearch_ameth(&t, standard_methods,
+			  sizeof(standard_methods)
+			  /sizeof(EVP_PKEY_ASN1_METHOD *));
+	if (!ret || !*ret)
+		return NULL;
+	return *ret;
+	}
+
+/* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL
+ * also search through engines and set *pe to a functional reference
+ * to the engine implementing 'type' or NULL if no engine implements 
+ * it.
+ */
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
+	{
+	const EVP_PKEY_ASN1_METHOD *t;
+
+	for (;;)
+		{
+		t = pkey_asn1_find(type);
+		if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
+			break;
+		type = t->pkey_base_id;
+		}
+	if (pe)
+		{
+#ifndef OPENSSL_NO_ENGINE
+		ENGINE *e;
+		/* type will contain the final unaliased type */
+		e = ENGINE_get_pkey_asn1_meth_engine(type);
+		if (e)
+			{
+			*pe = e;
+			return ENGINE_get_pkey_asn1_meth(e, type);
+			}
+#endif
+		*pe = NULL;
+		}
+	return t;
+	}
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
+					const char *str, int len)
+	{
+	int i;
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	if (len == -1)
+		len = strlen(str);
+	if (pe)
+		{
+#ifndef OPENSSL_NO_ENGINE
+		ENGINE *e;
+		ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
+		if (ameth)
+			{
+			/* Convert structural into
+			 * functional reference
+			 */
+			if (!ENGINE_init(e))
+				ameth = NULL;
+			ENGINE_free(e);
+			*pe = e;
+			return ameth;
+			}
+#endif
+		*pe = NULL;
+		}
+	for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
+		{
+		ameth = EVP_PKEY_asn1_get0(i);
+		if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
+			continue;
+		if (((int)strlen(ameth->pem_str) == len) && 
+			!strncasecmp(ameth->pem_str, str, len))
+			return ameth;
+		}
+	return NULL;
+	}
+
+int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
+	{
+	if (app_methods == NULL)
+		{
+		app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
+		if (!app_methods)
+			return 0;
+		}
+	if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
+		return 0;
+	sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
+	return 1;
+	}
+
+int EVP_PKEY_asn1_add_alias(int to, int from)
+	{
+	EVP_PKEY_ASN1_METHOD *ameth;
+	ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
+	if (!ameth)
+		return 0;
+	ameth->pkey_base_id = to;
+	return EVP_PKEY_asn1_add0(ameth);
+	}
+
+int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags,
+				const char **pinfo, const char **ppem_str,
+					const EVP_PKEY_ASN1_METHOD *ameth)
+	{
+	if (!ameth)
+		return 0;
+	if (ppkey_id)
+		*ppkey_id = ameth->pkey_id;
+	if (ppkey_base_id)
+		*ppkey_base_id = ameth->pkey_base_id;
+	if (ppkey_flags)
+		*ppkey_flags = ameth->pkey_flags;
+	if (pinfo)
+		*pinfo = ameth->info;
+	if (ppem_str)
+		*ppem_str = ameth->pem_str;
+	return 1;
+	}
+
+const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
+	{
+	return pkey->ameth;
+	}
+
+EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
+					const char *pem_str, const char *info)
+	{
+	EVP_PKEY_ASN1_METHOD *ameth;
+	ameth = OPENSSL_malloc(sizeof(EVP_PKEY_ASN1_METHOD));
+	if (!ameth)
+		return NULL;
+
+	ameth->pkey_id = id;
+	ameth->pkey_base_id = id;
+	ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
+
+	if (info)
+		{
+		ameth->info = BUF_strdup(info);
+		if (!ameth->info)
+			goto err;
+		}
+	else
+		ameth->info = NULL;
+
+	if (pem_str)
+		{
+		ameth->pem_str = BUF_strdup(pem_str);
+		if (!ameth->pem_str)
+			goto err;
+		}
+	else
+		ameth->pem_str = NULL;
+
+	ameth->pub_decode = 0;
+	ameth->pub_encode = 0;
+	ameth->pub_cmp = 0;
+	ameth->pub_print = 0;
+
+	ameth->priv_decode = 0;
+	ameth->priv_encode = 0;
+	ameth->priv_print = 0;
+
+	ameth->old_priv_encode = 0;
+	ameth->old_priv_decode = 0;
+
+	ameth->pkey_size = 0;
+	ameth->pkey_bits = 0;
+
+	ameth->param_decode = 0;
+	ameth->param_encode = 0;
+	ameth->param_missing = 0;
+	ameth->param_copy = 0;
+	ameth->param_cmp = 0;
+	ameth->param_print = 0;
+
+	ameth->pkey_free = 0;
+	ameth->pkey_ctrl = 0;
+
+	return ameth;
+
+	err:
+
+	EVP_PKEY_asn1_free(ameth);
+	return NULL;
+
+	}
+
+void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, 
+			const EVP_PKEY_ASN1_METHOD *src)
+	{
+
+	dst->pub_decode = src->pub_decode;
+	dst->pub_encode = src->pub_encode;
+	dst->pub_cmp = src->pub_cmp;
+	dst->pub_print = src->pub_print;
+
+	dst->priv_decode = src->priv_decode;
+	dst->priv_encode = src->priv_encode;
+	dst->priv_print = src->priv_print;
+
+	dst->old_priv_encode = src->old_priv_encode;
+	dst->old_priv_decode = src->old_priv_decode;
+
+	dst->pkey_size = src->pkey_size;
+	dst->pkey_bits = src->pkey_bits;
+
+	dst->param_decode = src->param_decode;
+	dst->param_encode = src->param_encode;
+	dst->param_missing = src->param_missing;
+	dst->param_copy = src->param_copy;
+	dst->param_cmp = src->param_cmp;
+	dst->param_print = src->param_print;
+
+	dst->pkey_free = src->pkey_free;
+	dst->pkey_ctrl = src->pkey_ctrl;
+
+	}
+
+void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
+	{
+	if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC))
+		{
+		if (ameth->pem_str)
+			OPENSSL_free(ameth->pem_str);
+		if (ameth->info)
+			OPENSSL_free(ameth->info);
+		OPENSSL_free(ameth);
+		}
+	}
+
+void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
+		int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub),
+		int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk),
+		int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
+		int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx),
+		int (*pkey_size)(const EVP_PKEY *pk),
+		int (*pkey_bits)(const EVP_PKEY *pk))
+	{
+	ameth->pub_decode = pub_decode;
+	ameth->pub_encode = pub_encode;
+	ameth->pub_cmp = pub_cmp;
+	ameth->pub_print = pub_print;
+	ameth->pkey_size = pkey_size;
+	ameth->pkey_bits = pkey_bits;
+	}
+
+void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
+		int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf),
+		int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk),
+		int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx))
+	{
+	ameth->priv_decode = priv_decode;
+	ameth->priv_encode = priv_encode;
+	ameth->priv_print = priv_print;
+	}
+
+void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
+		int (*param_decode)(EVP_PKEY *pkey,
+				const unsigned char **pder, int derlen),
+		int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder),
+		int (*param_missing)(const EVP_PKEY *pk),
+		int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from),
+		int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
+		int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx))
+	{
+	ameth->param_decode = param_decode;
+	ameth->param_encode = param_encode;
+	ameth->param_missing = param_missing;
+	ameth->param_copy = param_copy;
+	ameth->param_cmp = param_cmp;
+	ameth->param_print = param_print;
+	}
+
+void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
+		void (*pkey_free)(EVP_PKEY *pkey))
+	{
+	ameth->pkey_free = pkey_free;
+	}
+
+void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
+		int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
+							long arg1, void *arg2))
+	{
+	ameth->pkey_ctrl = pkey_ctrl;
+	}
diff --git a/openssl/crypto/asn1/asn1.h b/openssl/crypto/asn1/asn1.h
new file mode 100644
index 0000000..59540e4
--- /dev/null
+++ b/openssl/crypto/asn1/asn1.h
@@ -0,0 +1,1402 @@
+/* crypto/asn1/asn1.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ASN1_H
+#define HEADER_ASN1_H
+
+#include <time.h>
+#include <openssl/e_os2.h>
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#include <openssl/stack.h>
+#include <openssl/safestack.h>
+
+#include <openssl/symhacks.h>
+
+#include <openssl/ossl_typ.h>
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#endif
+
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define V_ASN1_UNIVERSAL		0x00
+#define	V_ASN1_APPLICATION		0x40
+#define V_ASN1_CONTEXT_SPECIFIC		0x80
+#define V_ASN1_PRIVATE			0xc0
+
+#define V_ASN1_CONSTRUCTED		0x20
+#define V_ASN1_PRIMITIVE_TAG		0x1f
+#define V_ASN1_PRIMATIVE_TAG		0x1f
+
+#define V_ASN1_APP_CHOOSE		-2	/* let the recipient choose */
+#define V_ASN1_OTHER			-3	/* used in ASN1_TYPE */
+#define V_ASN1_ANY			-4	/* used in ASN1 template code */
+
+#define V_ASN1_NEG			0x100	/* negative flag */
+
+#define V_ASN1_UNDEF			-1
+#define V_ASN1_EOC			0
+#define V_ASN1_BOOLEAN			1	/**/
+#define V_ASN1_INTEGER			2
+#define V_ASN1_NEG_INTEGER		(2 | V_ASN1_NEG)
+#define V_ASN1_BIT_STRING		3
+#define V_ASN1_OCTET_STRING		4
+#define V_ASN1_NULL			5
+#define V_ASN1_OBJECT			6
+#define V_ASN1_OBJECT_DESCRIPTOR	7
+#define V_ASN1_EXTERNAL			8
+#define V_ASN1_REAL			9
+#define V_ASN1_ENUMERATED		10
+#define V_ASN1_NEG_ENUMERATED		(10 | V_ASN1_NEG)
+#define V_ASN1_UTF8STRING		12
+#define V_ASN1_SEQUENCE			16
+#define V_ASN1_SET			17
+#define V_ASN1_NUMERICSTRING		18	/**/
+#define V_ASN1_PRINTABLESTRING		19
+#define V_ASN1_T61STRING		20
+#define V_ASN1_TELETEXSTRING		20	/* alias */
+#define V_ASN1_VIDEOTEXSTRING		21	/**/
+#define V_ASN1_IA5STRING		22
+#define V_ASN1_UTCTIME			23
+#define V_ASN1_GENERALIZEDTIME		24	/**/
+#define V_ASN1_GRAPHICSTRING		25	/**/
+#define V_ASN1_ISO64STRING		26	/**/
+#define V_ASN1_VISIBLESTRING		26	/* alias */
+#define V_ASN1_GENERALSTRING		27	/**/
+#define V_ASN1_UNIVERSALSTRING		28	/**/
+#define V_ASN1_BMPSTRING		30
+
+/* For use with d2i_ASN1_type_bytes() */
+#define B_ASN1_NUMERICSTRING	0x0001
+#define B_ASN1_PRINTABLESTRING	0x0002
+#define B_ASN1_T61STRING	0x0004
+#define B_ASN1_TELETEXSTRING	0x0004
+#define B_ASN1_VIDEOTEXSTRING	0x0008
+#define B_ASN1_IA5STRING	0x0010
+#define B_ASN1_GRAPHICSTRING	0x0020
+#define B_ASN1_ISO64STRING	0x0040
+#define B_ASN1_VISIBLESTRING	0x0040
+#define B_ASN1_GENERALSTRING	0x0080
+#define B_ASN1_UNIVERSALSTRING	0x0100
+#define B_ASN1_OCTET_STRING	0x0200
+#define B_ASN1_BIT_STRING	0x0400
+#define B_ASN1_BMPSTRING	0x0800
+#define B_ASN1_UNKNOWN		0x1000
+#define B_ASN1_UTF8STRING	0x2000
+#define B_ASN1_UTCTIME		0x4000
+#define B_ASN1_GENERALIZEDTIME	0x8000
+#define B_ASN1_SEQUENCE		0x10000
+
+/* For use with ASN1_mbstring_copy() */
+#define MBSTRING_FLAG		0x1000
+#define MBSTRING_UTF8		(MBSTRING_FLAG)
+#define MBSTRING_ASC		(MBSTRING_FLAG|1)
+#define MBSTRING_BMP		(MBSTRING_FLAG|2)
+#define MBSTRING_UNIV		(MBSTRING_FLAG|4)
+
+#define SMIME_OLDMIME		0x400
+#define SMIME_CRLFEOL		0x800
+#define SMIME_STREAM		0x1000
+
+struct X509_algor_st;
+DECLARE_STACK_OF(X509_ALGOR)
+
+#define DECLARE_ASN1_SET_OF(type) /* filled in by mkstack.pl */
+#define IMPLEMENT_ASN1_SET_OF(type) /* nothing, no longer needed */
+
+/* We MUST make sure that, except for constness, asn1_ctx_st and
+   asn1_const_ctx are exactly the same.  Fortunately, as soon as
+   the old ASN1 parsing macros are gone, we can throw this away
+   as well... */
+typedef struct asn1_ctx_st
+	{
+	unsigned char *p;/* work char pointer */
+	int eos;	/* end of sequence read for indefinite encoding */
+	int error;	/* error code to use when returning an error */
+	int inf;	/* constructed if 0x20, indefinite is 0x21 */
+	int tag;	/* tag from last 'get object' */
+	int xclass;	/* class from last 'get object' */
+	long slen;	/* length of last 'get object' */
+	unsigned char *max; /* largest value of p allowed */
+	unsigned char *q;/* temporary variable */
+	unsigned char **pp;/* variable */
+	int line;	/* used in error processing */
+	} ASN1_CTX;
+
+typedef struct asn1_const_ctx_st
+	{
+	const unsigned char *p;/* work char pointer */
+	int eos;	/* end of sequence read for indefinite encoding */
+	int error;	/* error code to use when returning an error */
+	int inf;	/* constructed if 0x20, indefinite is 0x21 */
+	int tag;	/* tag from last 'get object' */
+	int xclass;	/* class from last 'get object' */
+	long slen;	/* length of last 'get object' */
+	const unsigned char *max; /* largest value of p allowed */
+	const unsigned char *q;/* temporary variable */
+	const unsigned char **pp;/* variable */
+	int line;	/* used in error processing */
+	} ASN1_const_CTX;
+
+/* These are used internally in the ASN1_OBJECT to keep track of
+ * whether the names and data need to be free()ed */
+#define ASN1_OBJECT_FLAG_DYNAMIC	 0x01	/* internal use */
+#define ASN1_OBJECT_FLAG_CRITICAL	 0x02	/* critical x509v3 object id */
+#define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04	/* internal use */
+#define ASN1_OBJECT_FLAG_DYNAMIC_DATA 	 0x08	/* internal use */
+typedef struct asn1_object_st
+	{
+	const char *sn,*ln;
+	int nid;
+	int length;
+	const unsigned char *data;	/* data remains const after init */
+	int flags;	/* Should we free this one */
+	} ASN1_OBJECT;
+
+#define ASN1_STRING_FLAG_BITS_LEFT 0x08 /* Set if 0x07 has bits left value */
+/* This indicates that the ASN1_STRING is not a real value but just a place
+ * holder for the location where indefinite length constructed data should
+ * be inserted in the memory buffer 
+ */
+#define ASN1_STRING_FLAG_NDEF 0x010 
+
+/* This flag is used by the CMS code to indicate that a string is not
+ * complete and is a place holder for content when it had all been 
+ * accessed. The flag will be reset when content has been written to it.
+ */
+
+#define ASN1_STRING_FLAG_CONT 0x020 
+/* This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING
+ * type.
+ */
+#define ASN1_STRING_FLAG_MSTRING 0x040 
+/* This is the base type that holds just about everything :-) */
+typedef struct asn1_string_st
+	{
+	int length;
+	int type;
+	unsigned char *data;
+	/* The value of the following field depends on the type being
+	 * held.  It is mostly being used for BIT_STRING so if the
+	 * input data has a non-zero 'unused bits' value, it will be
+	 * handled correctly */
+	long flags;
+	} ASN1_STRING;
+
+/* ASN1_ENCODING structure: this is used to save the received
+ * encoding of an ASN1 type. This is useful to get round
+ * problems with invalid encodings which can break signatures.
+ */
+
+typedef struct ASN1_ENCODING_st
+	{
+	unsigned char *enc;	/* DER encoding */
+	long len;		/* Length of encoding */
+	int modified;		 /* set to 1 if 'enc' is invalid */
+	} ASN1_ENCODING;
+
+/* Used with ASN1 LONG type: if a long is set to this it is omitted */
+#define ASN1_LONG_UNDEF	0x7fffffffL
+
+#define STABLE_FLAGS_MALLOC	0x01
+#define STABLE_NO_MASK		0x02
+#define DIRSTRING_TYPE	\
+ (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING)
+#define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING)
+
+typedef struct asn1_string_table_st {
+	int nid;
+	long minsize;
+	long maxsize;
+	unsigned long mask;
+	unsigned long flags;
+} ASN1_STRING_TABLE;
+
+DECLARE_STACK_OF(ASN1_STRING_TABLE)
+
+/* size limits: this stuff is taken straight from RFC2459 */
+
+#define ub_name				32768
+#define ub_common_name			64
+#define ub_locality_name		128
+#define ub_state_name			128
+#define ub_organization_name		64
+#define ub_organization_unit_name	64
+#define ub_title			64
+#define ub_email_address		128
+
+/* Declarations for template structures: for full definitions
+ * see asn1t.h
+ */
+typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE;
+typedef struct ASN1_ITEM_st ASN1_ITEM;
+typedef struct ASN1_TLC_st ASN1_TLC;
+/* This is just an opaque pointer */
+typedef struct ASN1_VALUE_st ASN1_VALUE;
+
+/* Declare ASN1 functions: the implement macro in in asn1t.h */
+
+#define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type)
+
+#define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \
+	DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type)
+
+#define DECLARE_ASN1_FUNCTIONS_name(type, name) \
+	DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+	DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name)
+
+#define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \
+	DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+	DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name)
+
+#define	DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \
+	type *d2i_##name(type **a, const unsigned char **in, long len); \
+	int i2d_##name(type *a, unsigned char **out); \
+	DECLARE_ASN1_ITEM(itname)
+
+#define	DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \
+	type *d2i_##name(type **a, const unsigned char **in, long len); \
+	int i2d_##name(const type *a, unsigned char **out); \
+	DECLARE_ASN1_ITEM(name)
+
+#define	DECLARE_ASN1_NDEF_FUNCTION(name) \
+	int i2d_##name##_NDEF(name *a, unsigned char **out);
+
+#define DECLARE_ASN1_FUNCTIONS_const(name) \
+	DECLARE_ASN1_ALLOC_FUNCTIONS(name) \
+	DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name)
+
+#define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+	type *name##_new(void); \
+	void name##_free(type *a);
+
+#define DECLARE_ASN1_PRINT_FUNCTION(stname) \
+	DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname)
+
+#define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \
+	int fname##_print_ctx(BIO *out, stname *x, int indent, \
+					 const ASN1_PCTX *pctx);
+
+#define D2I_OF(type) type *(*)(type **,const unsigned char **,long)
+#define I2D_OF(type) int (*)(type *,unsigned char **)
+#define I2D_OF_const(type) int (*)(const type *,unsigned char **)
+
+#define CHECKED_D2I_OF(type, d2i) \
+    ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0)))
+#define CHECKED_I2D_OF(type, i2d) \
+    ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0)))
+#define CHECKED_NEW_OF(type, xnew) \
+    ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0)))
+#define CHECKED_PTR_OF(type, p) \
+    ((void*) (1 ? p : (type*)0))
+#define CHECKED_PPTR_OF(type, p) \
+    ((void**) (1 ? p : (type**)0))
+
+#define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long)
+#define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **)
+#define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type)
+
+TYPEDEF_D2I2D_OF(void);
+
+/* The following macros and typedefs allow an ASN1_ITEM
+ * to be embedded in a structure and referenced. Since
+ * the ASN1_ITEM pointers need to be globally accessible
+ * (possibly from shared libraries) they may exist in
+ * different forms. On platforms that support it the
+ * ASN1_ITEM structure itself will be globally exported.
+ * Other platforms will export a function that returns
+ * an ASN1_ITEM pointer.
+ *
+ * To handle both cases transparently the macros below
+ * should be used instead of hard coding an ASN1_ITEM
+ * pointer in a structure.
+ *
+ * The structure will look like this:
+ *
+ * typedef struct SOMETHING_st {
+ *      ...
+ *      ASN1_ITEM_EXP *iptr;
+ *      ...
+ * } SOMETHING; 
+ *
+ * It would be initialised as e.g.:
+ *
+ * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...};
+ *
+ * and the actual pointer extracted with:
+ *
+ * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr);
+ *
+ * Finally an ASN1_ITEM pointer can be extracted from an
+ * appropriate reference with: ASN1_ITEM_rptr(X509). This
+ * would be used when a function takes an ASN1_ITEM * argument.
+ *
+ */
+
+#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+/* ASN1_ITEM pointer exported type */
+typedef const ASN1_ITEM ASN1_ITEM_EXP;
+
+/* Macro to obtain ASN1_ITEM pointer from exported type */
+#define ASN1_ITEM_ptr(iptr) (iptr)
+
+/* Macro to include ASN1_ITEM pointer from base type */
+#define ASN1_ITEM_ref(iptr) (&(iptr##_it))
+
+#define ASN1_ITEM_rptr(ref) (&(ref##_it))
+
+#define DECLARE_ASN1_ITEM(name) \
+	OPENSSL_EXTERN const ASN1_ITEM name##_it;
+
+#else
+
+/* Platforms that can't easily handle shared global variables are declared
+ * as functions returning ASN1_ITEM pointers.
+ */
+
+/* ASN1_ITEM pointer exported type */
+typedef const ASN1_ITEM * ASN1_ITEM_EXP(void);
+
+/* Macro to obtain ASN1_ITEM pointer from exported type */
+#define ASN1_ITEM_ptr(iptr) (iptr())
+
+/* Macro to include ASN1_ITEM pointer from base type */
+#define ASN1_ITEM_ref(iptr) (iptr##_it)
+
+#define ASN1_ITEM_rptr(ref) (ref##_it())
+
+#define DECLARE_ASN1_ITEM(name) \
+	const ASN1_ITEM * name##_it(void);
+
+#endif
+
+/* Parameters used by ASN1_STRING_print_ex() */
+
+/* These determine which characters to escape:
+ * RFC2253 special characters, control characters and
+ * MSB set characters
+ */
+
+#define ASN1_STRFLGS_ESC_2253		1
+#define ASN1_STRFLGS_ESC_CTRL		2
+#define ASN1_STRFLGS_ESC_MSB		4
+
+
+/* This flag determines how we do escaping: normally
+ * RC2253 backslash only, set this to use backslash and
+ * quote.
+ */
+
+#define ASN1_STRFLGS_ESC_QUOTE		8
+
+
+/* These three flags are internal use only. */
+
+/* Character is a valid PrintableString character */
+#define CHARTYPE_PRINTABLESTRING	0x10
+/* Character needs escaping if it is the first character */
+#define CHARTYPE_FIRST_ESC_2253		0x20
+/* Character needs escaping if it is the last character */
+#define CHARTYPE_LAST_ESC_2253		0x40
+
+/* NB the internal flags are safely reused below by flags
+ * handled at the top level.
+ */
+
+/* If this is set we convert all character strings
+ * to UTF8 first 
+ */
+
+#define ASN1_STRFLGS_UTF8_CONVERT	0x10
+
+/* If this is set we don't attempt to interpret content:
+ * just assume all strings are 1 byte per character. This
+ * will produce some pretty odd looking output!
+ */
+
+#define ASN1_STRFLGS_IGNORE_TYPE	0x20
+
+/* If this is set we include the string type in the output */
+#define ASN1_STRFLGS_SHOW_TYPE		0x40
+
+/* This determines which strings to display and which to
+ * 'dump' (hex dump of content octets or DER encoding). We can
+ * only dump non character strings or everything. If we
+ * don't dump 'unknown' they are interpreted as character
+ * strings with 1 octet per character and are subject to
+ * the usual escaping options.
+ */
+
+#define ASN1_STRFLGS_DUMP_ALL		0x80
+#define ASN1_STRFLGS_DUMP_UNKNOWN	0x100
+
+/* These determine what 'dumping' does, we can dump the
+ * content octets or the DER encoding: both use the
+ * RFC2253 #XXXXX notation.
+ */
+
+#define ASN1_STRFLGS_DUMP_DER		0x200
+
+/* All the string flags consistent with RFC2253,
+ * escaping control characters isn't essential in
+ * RFC2253 but it is advisable anyway.
+ */
+
+#define ASN1_STRFLGS_RFC2253	(ASN1_STRFLGS_ESC_2253 | \
+				ASN1_STRFLGS_ESC_CTRL | \
+				ASN1_STRFLGS_ESC_MSB | \
+				ASN1_STRFLGS_UTF8_CONVERT | \
+				ASN1_STRFLGS_DUMP_UNKNOWN | \
+				ASN1_STRFLGS_DUMP_DER)
+
+DECLARE_STACK_OF(ASN1_INTEGER)
+DECLARE_ASN1_SET_OF(ASN1_INTEGER)
+
+DECLARE_STACK_OF(ASN1_GENERALSTRING)
+
+typedef struct asn1_type_st
+	{
+	int type;
+	union	{
+		char *ptr;
+		ASN1_BOOLEAN		boolean;
+		ASN1_STRING *		asn1_string;
+		ASN1_OBJECT *		object;
+		ASN1_INTEGER *		integer;
+		ASN1_ENUMERATED *	enumerated;
+		ASN1_BIT_STRING *	bit_string;
+		ASN1_OCTET_STRING *	octet_string;
+		ASN1_PRINTABLESTRING *	printablestring;
+		ASN1_T61STRING *	t61string;
+		ASN1_IA5STRING *	ia5string;
+		ASN1_GENERALSTRING *	generalstring;
+		ASN1_BMPSTRING *	bmpstring;
+		ASN1_UNIVERSALSTRING *	universalstring;
+		ASN1_UTCTIME *		utctime;
+		ASN1_GENERALIZEDTIME *	generalizedtime;
+		ASN1_VISIBLESTRING *	visiblestring;
+		ASN1_UTF8STRING *	utf8string;
+		/* set and sequence are left complete and still
+		 * contain the set or sequence bytes */
+		ASN1_STRING *		set;
+		ASN1_STRING *		sequence;
+		ASN1_VALUE *		asn1_value;
+		} value;
+	} ASN1_TYPE;
+
+DECLARE_STACK_OF(ASN1_TYPE)
+DECLARE_ASN1_SET_OF(ASN1_TYPE)
+
+typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY;
+
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY)
+
+typedef struct NETSCAPE_X509_st
+	{
+	ASN1_OCTET_STRING *header;
+	X509 *cert;
+	} NETSCAPE_X509;
+
+/* This is used to contain a list of bit names */
+typedef struct BIT_STRING_BITNAME_st {
+	int bitnum;
+	const char *lname;
+	const char *sname;
+} BIT_STRING_BITNAME;
+
+
+#define M_ASN1_STRING_length(x)	((x)->length)
+#define M_ASN1_STRING_length_set(x, n)	((x)->length = (n))
+#define M_ASN1_STRING_type(x)	((x)->type)
+#define M_ASN1_STRING_data(x)	((x)->data)
+
+/* Macros for string operations */
+#define M_ASN1_BIT_STRING_new()	(ASN1_BIT_STRING *)\
+		ASN1_STRING_type_new(V_ASN1_BIT_STRING)
+#define M_ASN1_BIT_STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\
+		ASN1_STRING_dup((const ASN1_STRING *)a)
+#define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\
+		(const ASN1_STRING *)a,(const ASN1_STRING *)b)
+#define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)
+
+#define M_ASN1_INTEGER_new()	(ASN1_INTEGER *)\
+		ASN1_STRING_type_new(V_ASN1_INTEGER)
+#define M_ASN1_INTEGER_free(a)		ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)\
+		ASN1_STRING_dup((const ASN1_STRING *)a)
+#define M_ASN1_INTEGER_cmp(a,b)	ASN1_STRING_cmp(\
+		(const ASN1_STRING *)a,(const ASN1_STRING *)b)
+
+#define M_ASN1_ENUMERATED_new()	(ASN1_ENUMERATED *)\
+		ASN1_STRING_type_new(V_ASN1_ENUMERATED)
+#define M_ASN1_ENUMERATED_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)\
+		ASN1_STRING_dup((const ASN1_STRING *)a)
+#define M_ASN1_ENUMERATED_cmp(a,b)	ASN1_STRING_cmp(\
+		(const ASN1_STRING *)a,(const ASN1_STRING *)b)
+
+#define M_ASN1_OCTET_STRING_new()	(ASN1_OCTET_STRING *)\
+		ASN1_STRING_type_new(V_ASN1_OCTET_STRING)
+#define M_ASN1_OCTET_STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\
+		ASN1_STRING_dup((const ASN1_STRING *)a)
+#define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\
+		(const ASN1_STRING *)a,(const ASN1_STRING *)b)
+#define M_ASN1_OCTET_STRING_set(a,b,c)	ASN1_STRING_set((ASN1_STRING *)a,b,c)
+#define M_ASN1_OCTET_STRING_print(a,b)	ASN1_STRING_print(a,(ASN1_STRING *)b)
+#define M_i2d_ASN1_OCTET_STRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_OCTET_STRING,\
+		V_ASN1_UNIVERSAL)
+
+#define B_ASN1_TIME \
+			B_ASN1_UTCTIME | \
+			B_ASN1_GENERALIZEDTIME
+
+#define B_ASN1_PRINTABLE \
+			B_ASN1_NUMERICSTRING| \
+			B_ASN1_PRINTABLESTRING| \
+			B_ASN1_T61STRING| \
+			B_ASN1_IA5STRING| \
+			B_ASN1_BIT_STRING| \
+			B_ASN1_UNIVERSALSTRING|\
+			B_ASN1_BMPSTRING|\
+			B_ASN1_UTF8STRING|\
+			B_ASN1_SEQUENCE|\
+			B_ASN1_UNKNOWN
+
+#define B_ASN1_DIRECTORYSTRING \
+			B_ASN1_PRINTABLESTRING| \
+			B_ASN1_TELETEXSTRING|\
+			B_ASN1_BMPSTRING|\
+			B_ASN1_UNIVERSALSTRING|\
+			B_ASN1_UTF8STRING
+
+#define B_ASN1_DISPLAYTEXT \
+			B_ASN1_IA5STRING| \
+			B_ASN1_VISIBLESTRING| \
+			B_ASN1_BMPSTRING|\
+			B_ASN1_UTF8STRING
+
+#define M_ASN1_PRINTABLE_new()	ASN1_STRING_type_new(V_ASN1_T61STRING)
+#define M_ASN1_PRINTABLE_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+		pp,a->type,V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_PRINTABLE(a,pp,l) \
+		d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+			B_ASN1_PRINTABLE)
+
+#define M_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
+#define M_DIRECTORYSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+						pp,a->type,V_ASN1_UNIVERSAL)
+#define M_d2i_DIRECTORYSTRING(a,pp,l) \
+		d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+			B_ASN1_DIRECTORYSTRING)
+
+#define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
+#define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+						pp,a->type,V_ASN1_UNIVERSAL)
+#define M_d2i_DISPLAYTEXT(a,pp,l) \
+		d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+			B_ASN1_DISPLAYTEXT)
+
+#define M_ASN1_PRINTABLESTRING_new() (ASN1_PRINTABLESTRING *)\
+		ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
+#define M_ASN1_PRINTABLESTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_PRINTABLESTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,\
+		V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) \
+		(ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_PRINTABLESTRING)
+
+#define M_ASN1_T61STRING_new()	(ASN1_T61STRING *)\
+		ASN1_STRING_type_new(V_ASN1_T61STRING)
+#define M_ASN1_T61STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_T61STRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_T61STRING,\
+		V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_T61STRING(a,pp,l) \
+		(ASN1_T61STRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_T61STRING)
+
+#define M_ASN1_IA5STRING_new()	(ASN1_IA5STRING *)\
+		ASN1_STRING_type_new(V_ASN1_IA5STRING)
+#define M_ASN1_IA5STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_IA5STRING_dup(a)	\
+		(ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a)
+#define M_i2d_ASN1_IA5STRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_IA5STRING(a,pp,l) \
+		(ASN1_IA5STRING *)d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l,\
+			B_ASN1_IA5STRING)
+
+#define M_ASN1_UTCTIME_new()	(ASN1_UTCTIME *)\
+		ASN1_STRING_type_new(V_ASN1_UTCTIME)
+#define M_ASN1_UTCTIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)\
+		ASN1_STRING_dup((const ASN1_STRING *)a)
+
+#define M_ASN1_GENERALIZEDTIME_new()	(ASN1_GENERALIZEDTIME *)\
+		ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME)
+#define M_ASN1_GENERALIZEDTIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\
+	(const ASN1_STRING *)a)
+
+#define M_ASN1_TIME_new()	(ASN1_TIME *)\
+		ASN1_STRING_type_new(V_ASN1_UTCTIME)
+#define M_ASN1_TIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_TIME_dup(a) (ASN1_TIME *)\
+	ASN1_STRING_dup((const ASN1_STRING *)a)
+
+#define M_ASN1_GENERALSTRING_new()	(ASN1_GENERALSTRING *)\
+		ASN1_STRING_type_new(V_ASN1_GENERALSTRING)
+#define M_ASN1_GENERALSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_GENERALSTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_GENERALSTRING(a,pp,l) \
+		(ASN1_GENERALSTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_GENERALSTRING)
+
+#define M_ASN1_UNIVERSALSTRING_new()	(ASN1_UNIVERSALSTRING *)\
+		ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING)
+#define M_ASN1_UNIVERSALSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_UNIVERSALSTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UNIVERSALSTRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_UNIVERSALSTRING(a,pp,l) \
+		(ASN1_UNIVERSALSTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_UNIVERSALSTRING)
+
+#define M_ASN1_BMPSTRING_new()	(ASN1_BMPSTRING *)\
+		ASN1_STRING_type_new(V_ASN1_BMPSTRING)
+#define M_ASN1_BMPSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_BMPSTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_BMPSTRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_BMPSTRING(a,pp,l) \
+		(ASN1_BMPSTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_BMPSTRING)
+
+#define M_ASN1_VISIBLESTRING_new()	(ASN1_VISIBLESTRING *)\
+		ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
+#define M_ASN1_VISIBLESTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_VISIBLESTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_VISIBLESTRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_VISIBLESTRING(a,pp,l) \
+		(ASN1_VISIBLESTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_VISIBLESTRING)
+
+#define M_ASN1_UTF8STRING_new()	(ASN1_UTF8STRING *)\
+		ASN1_STRING_type_new(V_ASN1_UTF8STRING)
+#define M_ASN1_UTF8STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_UTF8STRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UTF8STRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_UTF8STRING(a,pp,l) \
+		(ASN1_UTF8STRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_UTF8STRING)
+
+  /* for the is_set parameter to i2d_ASN1_SET */
+#define IS_SEQUENCE	0
+#define IS_SET		1
+
+DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
+
+int ASN1_TYPE_get(ASN1_TYPE *a);
+void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
+int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
+int            ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b);
+
+ASN1_OBJECT *	ASN1_OBJECT_new(void );
+void		ASN1_OBJECT_free(ASN1_OBJECT *a);
+int		i2d_ASN1_OBJECT(ASN1_OBJECT *a,unsigned char **pp);
+ASN1_OBJECT *	c2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
+			long length);
+ASN1_OBJECT *	d2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
+			long length);
+
+DECLARE_ASN1_ITEM(ASN1_OBJECT)
+
+DECLARE_STACK_OF(ASN1_OBJECT)
+DECLARE_ASN1_SET_OF(ASN1_OBJECT)
+
+ASN1_STRING *	ASN1_STRING_new(void);
+void		ASN1_STRING_free(ASN1_STRING *a);
+int		ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str);
+ASN1_STRING *	ASN1_STRING_dup(const ASN1_STRING *a);
+ASN1_STRING *	ASN1_STRING_type_new(int type );
+int 		ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b);
+  /* Since this is used to store all sorts of things, via macros, for now, make
+     its data void * */
+int 		ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
+void		ASN1_STRING_set0(ASN1_STRING *str, void *data, int len);
+int ASN1_STRING_length(const ASN1_STRING *x);
+void ASN1_STRING_length_set(ASN1_STRING *x, int n);
+int ASN1_STRING_type(ASN1_STRING *x);
+unsigned char * ASN1_STRING_data(ASN1_STRING *x);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING)
+int		i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp);
+ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,const unsigned char **pp,
+			long length);
+int		ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d,
+			int length );
+int		ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
+int		ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n);
+int            ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
+                                     unsigned char *flags, int flags_len);
+
+#ifndef OPENSSL_NO_BIO
+int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
+				BIT_STRING_BITNAME *tbl, int indent);
+#endif
+int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl);
+int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
+				BIT_STRING_BITNAME *tbl);
+
+int		i2d_ASN1_BOOLEAN(int a,unsigned char **pp);
+int 		d2i_ASN1_BOOLEAN(int *a,const unsigned char **pp,long length);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER)
+int		i2c_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp);
+ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,const unsigned char **pp,
+			long length);
+ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,const unsigned char **pp,
+			long length);
+ASN1_INTEGER *	ASN1_INTEGER_dup(const ASN1_INTEGER *x);
+int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
+
+int ASN1_UTCTIME_check(ASN1_UTCTIME *a);
+ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t);
+ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
+				int offset_day, long offset_sec);
+int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str);
+int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
+#if 0
+time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s);
+#endif
+
+int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a);
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t);
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
+	     time_t t, int offset_day, long offset_sec);
+int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
+ASN1_OCTET_STRING *	ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a);
+int 	ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b);
+int 	ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, int len);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_NULL)
+DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING)
+
+int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
+int UTF8_putc(unsigned char *str, int len, unsigned long value);
+
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
+
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
+DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME)
+DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
+DECLARE_ASN1_FUNCTIONS(ASN1_TIME)
+
+DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)
+
+ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t);
+ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s,time_t t,
+				int offset_day, long offset_sec);
+int ASN1_TIME_check(ASN1_TIME *t);
+ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);
+int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);
+
+int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
+		 i2d_of_void *i2d, int ex_tag, int ex_class,
+		 int is_set);
+STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
+			      const unsigned char **pp,
+			      long length, d2i_of_void *d2i,
+			      void (*free_func)(OPENSSL_BLOCK), int ex_tag,
+			      int ex_class);
+
+#ifndef OPENSSL_NO_BIO
+int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
+int a2i_ASN1_INTEGER(BIO *bp,ASN1_INTEGER *bs,char *buf,int size);
+int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a);
+int a2i_ASN1_ENUMERATED(BIO *bp,ASN1_ENUMERATED *bs,char *buf,int size);
+int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *a);
+int a2i_ASN1_STRING(BIO *bp,ASN1_STRING *bs,char *buf,int size);
+int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type);
+#endif
+int i2t_ASN1_OBJECT(char *buf,int buf_len,ASN1_OBJECT *a);
+
+int a2d_ASN1_OBJECT(unsigned char *out,int olen, const char *buf, int num);
+ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data,int len,
+	const char *sn, const char *ln);
+
+int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
+long ASN1_INTEGER_get(const ASN1_INTEGER *a);
+ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai);
+BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai,BIGNUM *bn);
+
+int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
+long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a);
+ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai);
+BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai,BIGNUM *bn);
+
+/* General */
+/* given a string, return the correct type, max is the maximum length */
+int ASN1_PRINTABLE_type(const unsigned char *s, int max);
+
+int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass);
+ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
+	long length, int Ptag, int Pclass);
+unsigned long ASN1_tag2bit(int tag);
+/* type is one or more of the B_ASN1_ values. */
+ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a,const unsigned char **pp,
+		long length,int type);
+
+/* PARSING */
+int asn1_Finish(ASN1_CTX *c);
+int asn1_const_Finish(ASN1_const_CTX *c);
+
+/* SPECIALS */
+int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
+	int *pclass, long omax);
+int ASN1_check_infinite_end(unsigned char **p,long len);
+int ASN1_const_check_infinite_end(const unsigned char **p,long len);
+void ASN1_put_object(unsigned char **pp, int constructed, int length,
+	int tag, int xclass);
+int ASN1_put_eoc(unsigned char **pp);
+int ASN1_object_size(int constructed, int length, int tag);
+
+/* Used to implement other functions */
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x);
+
+#define ASN1_dup_of(type,i2d,d2i,x) \
+    ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \
+		     CHECKED_D2I_OF(type, d2i), \
+		     CHECKED_PTR_OF(type, x)))
+
+#define ASN1_dup_of_const(type,i2d,d2i,x) \
+    ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \
+		     CHECKED_D2I_OF(type, d2i), \
+		     CHECKED_PTR_OF(const type, x)))
+
+void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
+
+/* ASN1 alloc/free macros for when a type is only used internally */
+
+#define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type))
+#define M_ASN1_free_of(x, type) \
+		ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type))
+
+#ifndef OPENSSL_NO_FP_API
+void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x);
+
+#define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \
+    ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \
+			CHECKED_D2I_OF(type, d2i), \
+			in, \
+			CHECKED_PPTR_OF(type, x)))
+
+void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
+int ASN1_i2d_fp(i2d_of_void *i2d,FILE *out,void *x);
+
+#define ASN1_i2d_fp_of(type,i2d,out,x) \
+    (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \
+		 out, \
+		 CHECKED_PTR_OF(type, x)))
+
+#define ASN1_i2d_fp_of_const(type,i2d,out,x) \
+    (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \
+		 out, \
+		 CHECKED_PTR_OF(const type, x)))
+
+int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x);
+int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags);
+#endif
+
+int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in);
+
+#ifndef OPENSSL_NO_BIO
+void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x);
+
+#define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \
+    ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \
+			  CHECKED_D2I_OF(type, d2i), \
+			  in, \
+			  CHECKED_PPTR_OF(type, x)))
+
+void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
+int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, unsigned char *x);
+
+#define ASN1_i2d_bio_of(type,i2d,out,x) \
+    (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \
+		  out, \
+		  CHECKED_PTR_OF(type, x)))
+
+#define ASN1_i2d_bio_of_const(type,i2d,out,x) \
+    (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \
+		  out, \
+		  CHECKED_PTR_OF(const type, x)))
+
+int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
+int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
+int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
+int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
+int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
+int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
+int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
+				unsigned char *buf, int off);
+int ASN1_parse(BIO *bp,const unsigned char *pp,long len,int indent);
+int ASN1_parse_dump(BIO *bp,const unsigned char *pp,long len,int indent,int dump);
+#endif
+const char *ASN1_tag2str(int tag);
+
+/* Used to load and write netscape format cert */
+
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_X509)
+
+int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s);
+
+int ASN1_TYPE_set_octetstring(ASN1_TYPE *a,
+	unsigned char *data, int len);
+int ASN1_TYPE_get_octetstring(ASN1_TYPE *a,
+	unsigned char *data, int max_len);
+int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num,
+	unsigned char *data, int len);
+int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a,long *num,
+	unsigned char *data, int max_len);
+
+STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
+				 d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK));
+unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
+			     unsigned char **buf, int *len );
+void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i);
+void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it);
+ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d,
+			      ASN1_OCTET_STRING **oct);
+
+#define ASN1_pack_string_of(type,obj,i2d,oct) \
+    (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \
+		      CHECKED_I2D_OF(type, i2d), \
+		      oct))
+
+ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct);
+
+void ASN1_STRING_set_default_mask(unsigned long mask);
+int ASN1_STRING_set_default_mask_asc(const char *p);
+unsigned long ASN1_STRING_get_default_mask(void);
+int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
+					int inform, unsigned long mask);
+int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
+					int inform, unsigned long mask, 
+					long minsize, long maxsize);
+
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, 
+		const unsigned char *in, int inlen, int inform, int nid);
+ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid);
+int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long);
+void ASN1_STRING_TABLE_cleanup(void);
+
+/* ASN1 template functions */
+
+/* Old API compatible functions */
+ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it);
+void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it);
+ASN1_VALUE * ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it);
+int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
+int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
+
+void ASN1_add_oid_module(void);
+
+ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
+ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
+
+/* ASN1 Print flags */
+
+/* Indicate missing OPTIONAL fields */
+#define ASN1_PCTX_FLAGS_SHOW_ABSENT		0x001	
+/* Mark start and end of SEQUENCE */
+#define ASN1_PCTX_FLAGS_SHOW_SEQUENCE		0x002
+/* Mark start and end of SEQUENCE/SET OF */
+#define ASN1_PCTX_FLAGS_SHOW_SSOF		0x004
+/* Show the ASN1 type of primitives */
+#define ASN1_PCTX_FLAGS_SHOW_TYPE		0x008
+/* Don't show ASN1 type of ANY */
+#define ASN1_PCTX_FLAGS_NO_ANY_TYPE		0x010
+/* Don't show ASN1 type of MSTRINGs */
+#define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE		0x020
+/* Don't show field names in SEQUENCE */
+#define ASN1_PCTX_FLAGS_NO_FIELD_NAME		0x040
+/* Show structure names of each SEQUENCE field */
+#define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME	0x080
+/* Don't show structure name even at top level */
+#define ASN1_PCTX_FLAGS_NO_STRUCT_NAME		0x100
+
+int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
+				const ASN1_ITEM *it, const ASN1_PCTX *pctx);
+ASN1_PCTX *ASN1_PCTX_new(void);
+void ASN1_PCTX_free(ASN1_PCTX *p);
+unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags);
+
+BIO_METHOD *BIO_f_asn1(void);
+
+BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it);
+
+int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+				const ASN1_ITEM *it);
+int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+				const char *hdr,
+				const ASN1_ITEM *it);
+int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
+				int ctype_nid, int econt_nid,
+				STACK_OF(X509_ALGOR) *mdalgs,
+				const ASN1_ITEM *it);
+ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it);
+int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
+int SMIME_text(BIO *in, BIO *out);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_ASN1_strings(void);
+
+/* Error codes for the ASN1 functions. */
+
+/* Function codes. */
+#define ASN1_F_A2D_ASN1_OBJECT				 100
+#define ASN1_F_A2I_ASN1_ENUMERATED			 101
+#define ASN1_F_A2I_ASN1_INTEGER				 102
+#define ASN1_F_A2I_ASN1_STRING				 103
+#define ASN1_F_APPEND_EXP				 176
+#define ASN1_F_ASN1_BIT_STRING_SET_BIT			 183
+#define ASN1_F_ASN1_CB					 177
+#define ASN1_F_ASN1_CHECK_TLEN				 104
+#define ASN1_F_ASN1_COLLATE_PRIMITIVE			 105
+#define ASN1_F_ASN1_COLLECT				 106
+#define ASN1_F_ASN1_D2I_EX_PRIMITIVE			 108
+#define ASN1_F_ASN1_D2I_FP				 109
+#define ASN1_F_ASN1_D2I_READ_BIO			 107
+#define ASN1_F_ASN1_DIGEST				 184
+#define ASN1_F_ASN1_DO_ADB				 110
+#define ASN1_F_ASN1_DUP					 111
+#define ASN1_F_ASN1_ENUMERATED_SET			 112
+#define ASN1_F_ASN1_ENUMERATED_TO_BN			 113
+#define ASN1_F_ASN1_EX_C2I				 204
+#define ASN1_F_ASN1_FIND_END				 190
+#define ASN1_F_ASN1_GENERALIZEDTIME_ADJ			 216
+#define ASN1_F_ASN1_GENERALIZEDTIME_SET			 185
+#define ASN1_F_ASN1_GENERATE_V3				 178
+#define ASN1_F_ASN1_GET_OBJECT				 114
+#define ASN1_F_ASN1_HEADER_NEW				 115
+#define ASN1_F_ASN1_I2D_BIO				 116
+#define ASN1_F_ASN1_I2D_FP				 117
+#define ASN1_F_ASN1_INTEGER_SET				 118
+#define ASN1_F_ASN1_INTEGER_TO_BN			 119
+#define ASN1_F_ASN1_ITEM_D2I_FP				 206
+#define ASN1_F_ASN1_ITEM_DUP				 191
+#define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW			 121
+#define ASN1_F_ASN1_ITEM_EX_D2I				 120
+#define ASN1_F_ASN1_ITEM_I2D_BIO			 192
+#define ASN1_F_ASN1_ITEM_I2D_FP				 193
+#define ASN1_F_ASN1_ITEM_PACK				 198
+#define ASN1_F_ASN1_ITEM_SIGN				 195
+#define ASN1_F_ASN1_ITEM_UNPACK				 199
+#define ASN1_F_ASN1_ITEM_VERIFY				 197
+#define ASN1_F_ASN1_MBSTRING_NCOPY			 122
+#define ASN1_F_ASN1_OBJECT_NEW				 123
+#define ASN1_F_ASN1_OUTPUT_DATA				 214
+#define ASN1_F_ASN1_PACK_STRING				 124
+#define ASN1_F_ASN1_PCTX_NEW				 205
+#define ASN1_F_ASN1_PKCS5_PBE_SET			 125
+#define ASN1_F_ASN1_SEQ_PACK				 126
+#define ASN1_F_ASN1_SEQ_UNPACK				 127
+#define ASN1_F_ASN1_SIGN				 128
+#define ASN1_F_ASN1_STR2TYPE				 179
+#define ASN1_F_ASN1_STRING_SET				 186
+#define ASN1_F_ASN1_STRING_TABLE_ADD			 129
+#define ASN1_F_ASN1_STRING_TYPE_NEW			 130
+#define ASN1_F_ASN1_TEMPLATE_EX_D2I			 132
+#define ASN1_F_ASN1_TEMPLATE_NEW			 133
+#define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I			 131
+#define ASN1_F_ASN1_TIME_ADJ				 217
+#define ASN1_F_ASN1_TIME_SET				 175
+#define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING		 134
+#define ASN1_F_ASN1_TYPE_GET_OCTETSTRING		 135
+#define ASN1_F_ASN1_UNPACK_STRING			 136
+#define ASN1_F_ASN1_UTCTIME_ADJ				 218
+#define ASN1_F_ASN1_UTCTIME_SET				 187
+#define ASN1_F_ASN1_VERIFY				 137
+#define ASN1_F_B64_READ_ASN1				 209
+#define ASN1_F_B64_WRITE_ASN1				 210
+#define ASN1_F_BIO_NEW_NDEF				 208
+#define ASN1_F_BITSTR_CB				 180
+#define ASN1_F_BN_TO_ASN1_ENUMERATED			 138
+#define ASN1_F_BN_TO_ASN1_INTEGER			 139
+#define ASN1_F_C2I_ASN1_BIT_STRING			 189
+#define ASN1_F_C2I_ASN1_INTEGER				 194
+#define ASN1_F_C2I_ASN1_OBJECT				 196
+#define ASN1_F_COLLECT_DATA				 140
+#define ASN1_F_D2I_ASN1_BIT_STRING			 141
+#define ASN1_F_D2I_ASN1_BOOLEAN				 142
+#define ASN1_F_D2I_ASN1_BYTES				 143
+#define ASN1_F_D2I_ASN1_GENERALIZEDTIME			 144
+#define ASN1_F_D2I_ASN1_HEADER				 145
+#define ASN1_F_D2I_ASN1_INTEGER				 146
+#define ASN1_F_D2I_ASN1_OBJECT				 147
+#define ASN1_F_D2I_ASN1_SET				 148
+#define ASN1_F_D2I_ASN1_TYPE_BYTES			 149
+#define ASN1_F_D2I_ASN1_UINTEGER			 150
+#define ASN1_F_D2I_ASN1_UTCTIME				 151
+#define ASN1_F_D2I_AUTOPRIVATEKEY			 207
+#define ASN1_F_D2I_NETSCAPE_RSA				 152
+#define ASN1_F_D2I_NETSCAPE_RSA_2			 153
+#define ASN1_F_D2I_PRIVATEKEY				 154
+#define ASN1_F_D2I_PUBLICKEY				 155
+#define ASN1_F_D2I_RSA_NET				 200
+#define ASN1_F_D2I_RSA_NET_2				 201
+#define ASN1_F_D2I_X509					 156
+#define ASN1_F_D2I_X509_CINF				 157
+#define ASN1_F_D2I_X509_PKEY				 159
+#define ASN1_F_I2D_ASN1_BIO_STREAM			 211
+#define ASN1_F_I2D_ASN1_SET				 188
+#define ASN1_F_I2D_ASN1_TIME				 160
+#define ASN1_F_I2D_DSA_PUBKEY				 161
+#define ASN1_F_I2D_EC_PUBKEY				 181
+#define ASN1_F_I2D_PRIVATEKEY				 163
+#define ASN1_F_I2D_PUBLICKEY				 164
+#define ASN1_F_I2D_RSA_NET				 162
+#define ASN1_F_I2D_RSA_PUBKEY				 165
+#define ASN1_F_LONG_C2I					 166
+#define ASN1_F_OID_MODULE_INIT				 174
+#define ASN1_F_PARSE_TAGGING				 182
+#define ASN1_F_PKCS5_PBE2_SET_IV			 167
+#define ASN1_F_PKCS5_PBE_SET				 202
+#define ASN1_F_PKCS5_PBE_SET0_ALGOR			 215
+#define ASN1_F_SMIME_READ_ASN1				 212
+#define ASN1_F_SMIME_TEXT				 213
+#define ASN1_F_X509_CINF_NEW				 168
+#define ASN1_F_X509_CRL_ADD0_REVOKED			 169
+#define ASN1_F_X509_INFO_NEW				 170
+#define ASN1_F_X509_NAME_ENCODE				 203
+#define ASN1_F_X509_NAME_EX_D2I				 158
+#define ASN1_F_X509_NAME_EX_NEW				 171
+#define ASN1_F_X509_NEW					 172
+#define ASN1_F_X509_PKEY_NEW				 173
+
+/* Reason codes. */
+#define ASN1_R_ADDING_OBJECT				 171
+#define ASN1_R_ASN1_PARSE_ERROR				 203
+#define ASN1_R_ASN1_SIG_PARSE_ERROR			 204
+#define ASN1_R_AUX_ERROR				 100
+#define ASN1_R_BAD_CLASS				 101
+#define ASN1_R_BAD_OBJECT_HEADER			 102
+#define ASN1_R_BAD_PASSWORD_READ			 103
+#define ASN1_R_BAD_TAG					 104
+#define ASN1_R_BMPSTRING_IS_WRONG_LENGTH		 214
+#define ASN1_R_BN_LIB					 105
+#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH			 106
+#define ASN1_R_BUFFER_TOO_SMALL				 107
+#define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER		 108
+#define ASN1_R_DATA_IS_WRONG				 109
+#define ASN1_R_DECODE_ERROR				 110
+#define ASN1_R_DECODING_ERROR				 111
+#define ASN1_R_DEPTH_EXCEEDED				 174
+#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED	 198
+#define ASN1_R_ENCODE_ERROR				 112
+#define ASN1_R_ERROR_GETTING_TIME			 173
+#define ASN1_R_ERROR_LOADING_SECTION			 172
+#define ASN1_R_ERROR_PARSING_SET_ELEMENT		 113
+#define ASN1_R_ERROR_SETTING_CIPHER_PARAMS		 114
+#define ASN1_R_EXPECTING_AN_INTEGER			 115
+#define ASN1_R_EXPECTING_AN_OBJECT			 116
+#define ASN1_R_EXPECTING_A_BOOLEAN			 117
+#define ASN1_R_EXPECTING_A_TIME				 118
+#define ASN1_R_EXPLICIT_LENGTH_MISMATCH			 119
+#define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED		 120
+#define ASN1_R_FIELD_MISSING				 121
+#define ASN1_R_FIRST_NUM_TOO_LARGE			 122
+#define ASN1_R_HEADER_TOO_LONG				 123
+#define ASN1_R_ILLEGAL_BITSTRING_FORMAT			 175
+#define ASN1_R_ILLEGAL_BOOLEAN				 176
+#define ASN1_R_ILLEGAL_CHARACTERS			 124
+#define ASN1_R_ILLEGAL_FORMAT				 177
+#define ASN1_R_ILLEGAL_HEX				 178
+#define ASN1_R_ILLEGAL_IMPLICIT_TAG			 179
+#define ASN1_R_ILLEGAL_INTEGER				 180
+#define ASN1_R_ILLEGAL_NESTED_TAGGING			 181
+#define ASN1_R_ILLEGAL_NULL				 125
+#define ASN1_R_ILLEGAL_NULL_VALUE			 182
+#define ASN1_R_ILLEGAL_OBJECT				 183
+#define ASN1_R_ILLEGAL_OPTIONAL_ANY			 126
+#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE		 170
+#define ASN1_R_ILLEGAL_TAGGED_ANY			 127
+#define ASN1_R_ILLEGAL_TIME_VALUE			 184
+#define ASN1_R_INTEGER_NOT_ASCII_FORMAT			 185
+#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG		 128
+#define ASN1_R_INVALID_BMPSTRING_LENGTH			 129
+#define ASN1_R_INVALID_DIGIT				 130
+#define ASN1_R_INVALID_MIME_TYPE			 205
+#define ASN1_R_INVALID_MODIFIER				 186
+#define ASN1_R_INVALID_NUMBER				 187
+#define ASN1_R_INVALID_OBJECT_ENCODING			 216
+#define ASN1_R_INVALID_SEPARATOR			 131
+#define ASN1_R_INVALID_TIME_FORMAT			 132
+#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH		 133
+#define ASN1_R_INVALID_UTF8STRING			 134
+#define ASN1_R_IV_TOO_LARGE				 135
+#define ASN1_R_LENGTH_ERROR				 136
+#define ASN1_R_LIST_ERROR				 188
+#define ASN1_R_MIME_NO_CONTENT_TYPE			 206
+#define ASN1_R_MIME_PARSE_ERROR				 207
+#define ASN1_R_MIME_SIG_PARSE_ERROR			 208
+#define ASN1_R_MISSING_EOC				 137
+#define ASN1_R_MISSING_SECOND_NUMBER			 138
+#define ASN1_R_MISSING_VALUE				 189
+#define ASN1_R_MSTRING_NOT_UNIVERSAL			 139
+#define ASN1_R_MSTRING_WRONG_TAG			 140
+#define ASN1_R_NESTED_ASN1_STRING			 197
+#define ASN1_R_NON_HEX_CHARACTERS			 141
+#define ASN1_R_NOT_ASCII_FORMAT				 190
+#define ASN1_R_NOT_ENOUGH_DATA				 142
+#define ASN1_R_NO_CONTENT_TYPE				 209
+#define ASN1_R_NO_DEFAULT_DIGEST			 201
+#define ASN1_R_NO_MATCHING_CHOICE_TYPE			 143
+#define ASN1_R_NO_MULTIPART_BODY_FAILURE		 210
+#define ASN1_R_NO_MULTIPART_BOUNDARY			 211
+#define ASN1_R_NO_SIG_CONTENT_TYPE			 212
+#define ASN1_R_NULL_IS_WRONG_LENGTH			 144
+#define ASN1_R_OBJECT_NOT_ASCII_FORMAT			 191
+#define ASN1_R_ODD_NUMBER_OF_CHARS			 145
+#define ASN1_R_PRIVATE_KEY_HEADER_MISSING		 146
+#define ASN1_R_SECOND_NUMBER_TOO_LARGE			 147
+#define ASN1_R_SEQUENCE_LENGTH_MISMATCH			 148
+#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED			 149
+#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG		 192
+#define ASN1_R_SHORT_LINE				 150
+#define ASN1_R_SIG_INVALID_MIME_TYPE			 213
+#define ASN1_R_STREAMING_NOT_SUPPORTED			 202
+#define ASN1_R_STRING_TOO_LONG				 151
+#define ASN1_R_STRING_TOO_SHORT				 152
+#define ASN1_R_TAG_VALUE_TOO_HIGH			 153
+#define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154
+#define ASN1_R_TIME_NOT_ASCII_FORMAT			 193
+#define ASN1_R_TOO_LONG					 155
+#define ASN1_R_TYPE_NOT_CONSTRUCTED			 156
+#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY			 157
+#define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY		 158
+#define ASN1_R_UNEXPECTED_EOC				 159
+#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH		 215
+#define ASN1_R_UNKNOWN_FORMAT				 160
+#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM		 161
+#define ASN1_R_UNKNOWN_OBJECT_TYPE			 162
+#define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE			 163
+#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM		 199
+#define ASN1_R_UNKNOWN_TAG				 194
+#define ASN1_R_UNKOWN_FORMAT				 195
+#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE		 164
+#define ASN1_R_UNSUPPORTED_CIPHER			 165
+#define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM		 166
+#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE		 167
+#define ASN1_R_UNSUPPORTED_TYPE				 196
+#define ASN1_R_WRONG_PUBLIC_KEY_TYPE			 200
+#define ASN1_R_WRONG_TAG				 168
+#define ASN1_R_WRONG_TYPE				 169
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/asn1/asn1_err.c b/openssl/crypto/asn1/asn1_err.c
new file mode 100644
index 0000000..6e04d08
--- /dev/null
+++ b/openssl/crypto/asn1/asn1_err.c
@@ -0,0 +1,329 @@
+/* crypto/asn1/asn1_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2009 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/asn1.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ASN1,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ASN1,0,reason)
+
+static ERR_STRING_DATA ASN1_str_functs[]=
+	{
+{ERR_FUNC(ASN1_F_A2D_ASN1_OBJECT),	"a2d_ASN1_OBJECT"},
+{ERR_FUNC(ASN1_F_A2I_ASN1_ENUMERATED),	"a2i_ASN1_ENUMERATED"},
+{ERR_FUNC(ASN1_F_A2I_ASN1_INTEGER),	"a2i_ASN1_INTEGER"},
+{ERR_FUNC(ASN1_F_A2I_ASN1_STRING),	"a2i_ASN1_STRING"},
+{ERR_FUNC(ASN1_F_APPEND_EXP),	"APPEND_EXP"},
+{ERR_FUNC(ASN1_F_ASN1_BIT_STRING_SET_BIT),	"ASN1_BIT_STRING_set_bit"},
+{ERR_FUNC(ASN1_F_ASN1_CB),	"ASN1_CB"},
+{ERR_FUNC(ASN1_F_ASN1_CHECK_TLEN),	"ASN1_CHECK_TLEN"},
+{ERR_FUNC(ASN1_F_ASN1_COLLATE_PRIMITIVE),	"ASN1_COLLATE_PRIMITIVE"},
+{ERR_FUNC(ASN1_F_ASN1_COLLECT),	"ASN1_COLLECT"},
+{ERR_FUNC(ASN1_F_ASN1_D2I_EX_PRIMITIVE),	"ASN1_D2I_EX_PRIMITIVE"},
+{ERR_FUNC(ASN1_F_ASN1_D2I_FP),	"ASN1_d2i_fp"},
+{ERR_FUNC(ASN1_F_ASN1_D2I_READ_BIO),	"ASN1_D2I_READ_BIO"},
+{ERR_FUNC(ASN1_F_ASN1_DIGEST),	"ASN1_digest"},
+{ERR_FUNC(ASN1_F_ASN1_DO_ADB),	"ASN1_DO_ADB"},
+{ERR_FUNC(ASN1_F_ASN1_DUP),	"ASN1_dup"},
+{ERR_FUNC(ASN1_F_ASN1_ENUMERATED_SET),	"ASN1_ENUMERATED_set"},
+{ERR_FUNC(ASN1_F_ASN1_ENUMERATED_TO_BN),	"ASN1_ENUMERATED_to_BN"},
+{ERR_FUNC(ASN1_F_ASN1_EX_C2I),	"ASN1_EX_C2I"},
+{ERR_FUNC(ASN1_F_ASN1_FIND_END),	"ASN1_FIND_END"},
+{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_ADJ),	"ASN1_GENERALIZEDTIME_adj"},
+{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_SET),	"ASN1_GENERALIZEDTIME_set"},
+{ERR_FUNC(ASN1_F_ASN1_GENERATE_V3),	"ASN1_generate_v3"},
+{ERR_FUNC(ASN1_F_ASN1_GET_OBJECT),	"ASN1_get_object"},
+{ERR_FUNC(ASN1_F_ASN1_HEADER_NEW),	"ASN1_HEADER_NEW"},
+{ERR_FUNC(ASN1_F_ASN1_I2D_BIO),	"ASN1_i2d_bio"},
+{ERR_FUNC(ASN1_F_ASN1_I2D_FP),	"ASN1_i2d_fp"},
+{ERR_FUNC(ASN1_F_ASN1_INTEGER_SET),	"ASN1_INTEGER_set"},
+{ERR_FUNC(ASN1_F_ASN1_INTEGER_TO_BN),	"ASN1_INTEGER_to_BN"},
+{ERR_FUNC(ASN1_F_ASN1_ITEM_D2I_FP),	"ASN1_item_d2i_fp"},
+{ERR_FUNC(ASN1_F_ASN1_ITEM_DUP),	"ASN1_item_dup"},
+{ERR_FUNC(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW),	"ASN1_ITEM_EX_COMBINE_NEW"},
+{ERR_FUNC(ASN1_F_ASN1_ITEM_EX_D2I),	"ASN1_ITEM_EX_D2I"},
+{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_BIO),	"ASN1_item_i2d_bio"},
+{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP),	"ASN1_item_i2d_fp"},
+{ERR_FUNC(ASN1_F_ASN1_ITEM_PACK),	"ASN1_item_pack"},
+{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN),	"ASN1_item_sign"},
+{ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK),	"ASN1_item_unpack"},
+{ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY),	"ASN1_item_verify"},
+{ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY),	"ASN1_mbstring_ncopy"},
+{ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW),	"ASN1_OBJECT_new"},
+{ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA),	"ASN1_OUTPUT_DATA"},
+{ERR_FUNC(ASN1_F_ASN1_PACK_STRING),	"ASN1_pack_string"},
+{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW),	"ASN1_PCTX_new"},
+{ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET),	"ASN1_PKCS5_PBE_SET"},
+{ERR_FUNC(ASN1_F_ASN1_SEQ_PACK),	"ASN1_seq_pack"},
+{ERR_FUNC(ASN1_F_ASN1_SEQ_UNPACK),	"ASN1_seq_unpack"},
+{ERR_FUNC(ASN1_F_ASN1_SIGN),	"ASN1_sign"},
+{ERR_FUNC(ASN1_F_ASN1_STR2TYPE),	"ASN1_STR2TYPE"},
+{ERR_FUNC(ASN1_F_ASN1_STRING_SET),	"ASN1_STRING_set"},
+{ERR_FUNC(ASN1_F_ASN1_STRING_TABLE_ADD),	"ASN1_STRING_TABLE_add"},
+{ERR_FUNC(ASN1_F_ASN1_STRING_TYPE_NEW),	"ASN1_STRING_type_new"},
+{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I),	"ASN1_TEMPLATE_EX_D2I"},
+{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW),	"ASN1_TEMPLATE_NEW"},
+{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I),	"ASN1_TEMPLATE_NOEXP_D2I"},
+{ERR_FUNC(ASN1_F_ASN1_TIME_ADJ),	"ASN1_TIME_adj"},
+{ERR_FUNC(ASN1_F_ASN1_TIME_SET),	"ASN1_TIME_set"},
+{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING),	"ASN1_TYPE_get_int_octetstring"},
+{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING),	"ASN1_TYPE_get_octetstring"},
+{ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING),	"ASN1_unpack_string"},
+{ERR_FUNC(ASN1_F_ASN1_UTCTIME_ADJ),	"ASN1_UTCTIME_adj"},
+{ERR_FUNC(ASN1_F_ASN1_UTCTIME_SET),	"ASN1_UTCTIME_set"},
+{ERR_FUNC(ASN1_F_ASN1_VERIFY),	"ASN1_verify"},
+{ERR_FUNC(ASN1_F_B64_READ_ASN1),	"B64_READ_ASN1"},
+{ERR_FUNC(ASN1_F_B64_WRITE_ASN1),	"B64_WRITE_ASN1"},
+{ERR_FUNC(ASN1_F_BIO_NEW_NDEF),	"BIO_new_NDEF"},
+{ERR_FUNC(ASN1_F_BITSTR_CB),	"BITSTR_CB"},
+{ERR_FUNC(ASN1_F_BN_TO_ASN1_ENUMERATED),	"BN_to_ASN1_ENUMERATED"},
+{ERR_FUNC(ASN1_F_BN_TO_ASN1_INTEGER),	"BN_to_ASN1_INTEGER"},
+{ERR_FUNC(ASN1_F_C2I_ASN1_BIT_STRING),	"c2i_ASN1_BIT_STRING"},
+{ERR_FUNC(ASN1_F_C2I_ASN1_INTEGER),	"c2i_ASN1_INTEGER"},
+{ERR_FUNC(ASN1_F_C2I_ASN1_OBJECT),	"c2i_ASN1_OBJECT"},
+{ERR_FUNC(ASN1_F_COLLECT_DATA),	"COLLECT_DATA"},
+{ERR_FUNC(ASN1_F_D2I_ASN1_BIT_STRING),	"D2I_ASN1_BIT_STRING"},
+{ERR_FUNC(ASN1_F_D2I_ASN1_BOOLEAN),	"d2i_ASN1_BOOLEAN"},
+{ERR_FUNC(ASN1_F_D2I_ASN1_BYTES),	"d2i_ASN1_bytes"},
+{ERR_FUNC(ASN1_F_D2I_ASN1_GENERALIZEDTIME),	"D2I_ASN1_GENERALIZEDTIME"},
+{ERR_FUNC(ASN1_F_D2I_ASN1_HEADER),	"D2I_ASN1_HEADER"},
+{ERR_FUNC(ASN1_F_D2I_ASN1_INTEGER),	"D2I_ASN1_INTEGER"},
+{ERR_FUNC(ASN1_F_D2I_ASN1_OBJECT),	"d2i_ASN1_OBJECT"},
+{ERR_FUNC(ASN1_F_D2I_ASN1_SET),	"d2i_ASN1_SET"},
+{ERR_FUNC(ASN1_F_D2I_ASN1_TYPE_BYTES),	"d2i_ASN1_type_bytes"},
+{ERR_FUNC(ASN1_F_D2I_ASN1_UINTEGER),	"d2i_ASN1_UINTEGER"},
+{ERR_FUNC(ASN1_F_D2I_ASN1_UTCTIME),	"D2I_ASN1_UTCTIME"},
+{ERR_FUNC(ASN1_F_D2I_AUTOPRIVATEKEY),	"d2i_AutoPrivateKey"},
+{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA),	"d2i_Netscape_RSA"},
+{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA_2),	"D2I_NETSCAPE_RSA_2"},
+{ERR_FUNC(ASN1_F_D2I_PRIVATEKEY),	"d2i_PrivateKey"},
+{ERR_FUNC(ASN1_F_D2I_PUBLICKEY),	"d2i_PublicKey"},
+{ERR_FUNC(ASN1_F_D2I_RSA_NET),	"d2i_RSA_NET"},
+{ERR_FUNC(ASN1_F_D2I_RSA_NET_2),	"D2I_RSA_NET_2"},
+{ERR_FUNC(ASN1_F_D2I_X509),	"D2I_X509"},
+{ERR_FUNC(ASN1_F_D2I_X509_CINF),	"D2I_X509_CINF"},
+{ERR_FUNC(ASN1_F_D2I_X509_PKEY),	"d2i_X509_PKEY"},
+{ERR_FUNC(ASN1_F_I2D_ASN1_BIO_STREAM),	"i2d_ASN1_bio_stream"},
+{ERR_FUNC(ASN1_F_I2D_ASN1_SET),	"i2d_ASN1_SET"},
+{ERR_FUNC(ASN1_F_I2D_ASN1_TIME),	"I2D_ASN1_TIME"},
+{ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY),	"i2d_DSA_PUBKEY"},
+{ERR_FUNC(ASN1_F_I2D_EC_PUBKEY),	"i2d_EC_PUBKEY"},
+{ERR_FUNC(ASN1_F_I2D_PRIVATEKEY),	"i2d_PrivateKey"},
+{ERR_FUNC(ASN1_F_I2D_PUBLICKEY),	"i2d_PublicKey"},
+{ERR_FUNC(ASN1_F_I2D_RSA_NET),	"i2d_RSA_NET"},
+{ERR_FUNC(ASN1_F_I2D_RSA_PUBKEY),	"i2d_RSA_PUBKEY"},
+{ERR_FUNC(ASN1_F_LONG_C2I),	"LONG_C2I"},
+{ERR_FUNC(ASN1_F_OID_MODULE_INIT),	"OID_MODULE_INIT"},
+{ERR_FUNC(ASN1_F_PARSE_TAGGING),	"PARSE_TAGGING"},
+{ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_IV),	"PKCS5_pbe2_set_iv"},
+{ERR_FUNC(ASN1_F_PKCS5_PBE_SET),	"PKCS5_pbe_set"},
+{ERR_FUNC(ASN1_F_PKCS5_PBE_SET0_ALGOR),	"PKCS5_pbe_set0_algor"},
+{ERR_FUNC(ASN1_F_SMIME_READ_ASN1),	"SMIME_read_ASN1"},
+{ERR_FUNC(ASN1_F_SMIME_TEXT),	"SMIME_text"},
+{ERR_FUNC(ASN1_F_X509_CINF_NEW),	"X509_CINF_NEW"},
+{ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED),	"X509_CRL_add0_revoked"},
+{ERR_FUNC(ASN1_F_X509_INFO_NEW),	"X509_INFO_new"},
+{ERR_FUNC(ASN1_F_X509_NAME_ENCODE),	"X509_NAME_ENCODE"},
+{ERR_FUNC(ASN1_F_X509_NAME_EX_D2I),	"X509_NAME_EX_D2I"},
+{ERR_FUNC(ASN1_F_X509_NAME_EX_NEW),	"X509_NAME_EX_NEW"},
+{ERR_FUNC(ASN1_F_X509_NEW),	"X509_NEW"},
+{ERR_FUNC(ASN1_F_X509_PKEY_NEW),	"X509_PKEY_new"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA ASN1_str_reasons[]=
+	{
+{ERR_REASON(ASN1_R_ADDING_OBJECT)        ,"adding object"},
+{ERR_REASON(ASN1_R_ASN1_PARSE_ERROR)     ,"asn1 parse error"},
+{ERR_REASON(ASN1_R_ASN1_SIG_PARSE_ERROR) ,"asn1 sig parse error"},
+{ERR_REASON(ASN1_R_AUX_ERROR)            ,"aux error"},
+{ERR_REASON(ASN1_R_BAD_CLASS)            ,"bad class"},
+{ERR_REASON(ASN1_R_BAD_OBJECT_HEADER)    ,"bad object header"},
+{ERR_REASON(ASN1_R_BAD_PASSWORD_READ)    ,"bad password read"},
+{ERR_REASON(ASN1_R_BAD_TAG)              ,"bad tag"},
+{ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH),"bmpstring is wrong length"},
+{ERR_REASON(ASN1_R_BN_LIB)               ,"bn lib"},
+{ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH),"boolean is wrong length"},
+{ERR_REASON(ASN1_R_BUFFER_TOO_SMALL)     ,"buffer too small"},
+{ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"},
+{ERR_REASON(ASN1_R_DATA_IS_WRONG)        ,"data is wrong"},
+{ERR_REASON(ASN1_R_DECODE_ERROR)         ,"decode error"},
+{ERR_REASON(ASN1_R_DECODING_ERROR)       ,"decoding error"},
+{ERR_REASON(ASN1_R_DEPTH_EXCEEDED)       ,"depth exceeded"},
+{ERR_REASON(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED),"digest and key type not supported"},
+{ERR_REASON(ASN1_R_ENCODE_ERROR)         ,"encode error"},
+{ERR_REASON(ASN1_R_ERROR_GETTING_TIME)   ,"error getting time"},
+{ERR_REASON(ASN1_R_ERROR_LOADING_SECTION),"error loading section"},
+{ERR_REASON(ASN1_R_ERROR_PARSING_SET_ELEMENT),"error parsing set element"},
+{ERR_REASON(ASN1_R_ERROR_SETTING_CIPHER_PARAMS),"error setting cipher params"},
+{ERR_REASON(ASN1_R_EXPECTING_AN_INTEGER) ,"expecting an integer"},
+{ERR_REASON(ASN1_R_EXPECTING_AN_OBJECT)  ,"expecting an object"},
+{ERR_REASON(ASN1_R_EXPECTING_A_BOOLEAN)  ,"expecting a boolean"},
+{ERR_REASON(ASN1_R_EXPECTING_A_TIME)     ,"expecting a time"},
+{ERR_REASON(ASN1_R_EXPLICIT_LENGTH_MISMATCH),"explicit length mismatch"},
+{ERR_REASON(ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED),"explicit tag not constructed"},
+{ERR_REASON(ASN1_R_FIELD_MISSING)        ,"field missing"},
+{ERR_REASON(ASN1_R_FIRST_NUM_TOO_LARGE)  ,"first num too large"},
+{ERR_REASON(ASN1_R_HEADER_TOO_LONG)      ,"header too long"},
+{ERR_REASON(ASN1_R_ILLEGAL_BITSTRING_FORMAT),"illegal bitstring format"},
+{ERR_REASON(ASN1_R_ILLEGAL_BOOLEAN)      ,"illegal boolean"},
+{ERR_REASON(ASN1_R_ILLEGAL_CHARACTERS)   ,"illegal characters"},
+{ERR_REASON(ASN1_R_ILLEGAL_FORMAT)       ,"illegal format"},
+{ERR_REASON(ASN1_R_ILLEGAL_HEX)          ,"illegal hex"},
+{ERR_REASON(ASN1_R_ILLEGAL_IMPLICIT_TAG) ,"illegal implicit tag"},
+{ERR_REASON(ASN1_R_ILLEGAL_INTEGER)      ,"illegal integer"},
+{ERR_REASON(ASN1_R_ILLEGAL_NESTED_TAGGING),"illegal nested tagging"},
+{ERR_REASON(ASN1_R_ILLEGAL_NULL)         ,"illegal null"},
+{ERR_REASON(ASN1_R_ILLEGAL_NULL_VALUE)   ,"illegal null value"},
+{ERR_REASON(ASN1_R_ILLEGAL_OBJECT)       ,"illegal object"},
+{ERR_REASON(ASN1_R_ILLEGAL_OPTIONAL_ANY) ,"illegal optional any"},
+{ERR_REASON(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE),"illegal options on item template"},
+{ERR_REASON(ASN1_R_ILLEGAL_TAGGED_ANY)   ,"illegal tagged any"},
+{ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE)   ,"illegal time value"},
+{ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT),"integer not ascii format"},
+{ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"},
+{ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"},
+{ERR_REASON(ASN1_R_INVALID_DIGIT)        ,"invalid digit"},
+{ERR_REASON(ASN1_R_INVALID_MIME_TYPE)    ,"invalid mime type"},
+{ERR_REASON(ASN1_R_INVALID_MODIFIER)     ,"invalid modifier"},
+{ERR_REASON(ASN1_R_INVALID_NUMBER)       ,"invalid number"},
+{ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING),"invalid object encoding"},
+{ERR_REASON(ASN1_R_INVALID_SEPARATOR)    ,"invalid separator"},
+{ERR_REASON(ASN1_R_INVALID_TIME_FORMAT)  ,"invalid time format"},
+{ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH),"invalid universalstring length"},
+{ERR_REASON(ASN1_R_INVALID_UTF8STRING)   ,"invalid utf8string"},
+{ERR_REASON(ASN1_R_IV_TOO_LARGE)         ,"iv too large"},
+{ERR_REASON(ASN1_R_LENGTH_ERROR)         ,"length error"},
+{ERR_REASON(ASN1_R_LIST_ERROR)           ,"list error"},
+{ERR_REASON(ASN1_R_MIME_NO_CONTENT_TYPE) ,"mime no content type"},
+{ERR_REASON(ASN1_R_MIME_PARSE_ERROR)     ,"mime parse error"},
+{ERR_REASON(ASN1_R_MIME_SIG_PARSE_ERROR) ,"mime sig parse error"},
+{ERR_REASON(ASN1_R_MISSING_EOC)          ,"missing eoc"},
+{ERR_REASON(ASN1_R_MISSING_SECOND_NUMBER),"missing second number"},
+{ERR_REASON(ASN1_R_MISSING_VALUE)        ,"missing value"},
+{ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL),"mstring not universal"},
+{ERR_REASON(ASN1_R_MSTRING_WRONG_TAG)    ,"mstring wrong tag"},
+{ERR_REASON(ASN1_R_NESTED_ASN1_STRING)   ,"nested asn1 string"},
+{ERR_REASON(ASN1_R_NON_HEX_CHARACTERS)   ,"non hex characters"},
+{ERR_REASON(ASN1_R_NOT_ASCII_FORMAT)     ,"not ascii format"},
+{ERR_REASON(ASN1_R_NOT_ENOUGH_DATA)      ,"not enough data"},
+{ERR_REASON(ASN1_R_NO_CONTENT_TYPE)      ,"no content type"},
+{ERR_REASON(ASN1_R_NO_DEFAULT_DIGEST)    ,"no default digest"},
+{ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE),"no matching choice type"},
+{ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"},
+{ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"},
+{ERR_REASON(ASN1_R_NO_SIG_CONTENT_TYPE)  ,"no sig content type"},
+{ERR_REASON(ASN1_R_NULL_IS_WRONG_LENGTH) ,"null is wrong length"},
+{ERR_REASON(ASN1_R_OBJECT_NOT_ASCII_FORMAT),"object not ascii format"},
+{ERR_REASON(ASN1_R_ODD_NUMBER_OF_CHARS)  ,"odd number of chars"},
+{ERR_REASON(ASN1_R_PRIVATE_KEY_HEADER_MISSING),"private key header missing"},
+{ERR_REASON(ASN1_R_SECOND_NUMBER_TOO_LARGE),"second number too large"},
+{ERR_REASON(ASN1_R_SEQUENCE_LENGTH_MISMATCH),"sequence length mismatch"},
+{ERR_REASON(ASN1_R_SEQUENCE_NOT_CONSTRUCTED),"sequence not constructed"},
+{ERR_REASON(ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG),"sequence or set needs config"},
+{ERR_REASON(ASN1_R_SHORT_LINE)           ,"short line"},
+{ERR_REASON(ASN1_R_SIG_INVALID_MIME_TYPE),"sig invalid mime type"},
+{ERR_REASON(ASN1_R_STREAMING_NOT_SUPPORTED),"streaming not supported"},
+{ERR_REASON(ASN1_R_STRING_TOO_LONG)      ,"string too long"},
+{ERR_REASON(ASN1_R_STRING_TOO_SHORT)     ,"string too short"},
+{ERR_REASON(ASN1_R_TAG_VALUE_TOO_HIGH)   ,"tag value too high"},
+{ERR_REASON(ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),"the asn1 object identifier is not known for this md"},
+{ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT),"time not ascii format"},
+{ERR_REASON(ASN1_R_TOO_LONG)             ,"too long"},
+{ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED) ,"type not constructed"},
+{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY),"unable to decode rsa key"},
+{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY),"unable to decode rsa private key"},
+{ERR_REASON(ASN1_R_UNEXPECTED_EOC)       ,"unexpected eoc"},
+{ERR_REASON(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH),"universalstring is wrong length"},
+{ERR_REASON(ASN1_R_UNKNOWN_FORMAT)       ,"unknown format"},
+{ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM),"unknown message digest algorithm"},
+{ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE)  ,"unknown object type"},
+{ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE),"unknown public key type"},
+{ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM),"unknown signature algorithm"},
+{ERR_REASON(ASN1_R_UNKNOWN_TAG)          ,"unknown tag"},
+{ERR_REASON(ASN1_R_UNKOWN_FORMAT)        ,"unkown format"},
+{ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE),"unsupported any defined by type"},
+{ERR_REASON(ASN1_R_UNSUPPORTED_CIPHER)   ,"unsupported cipher"},
+{ERR_REASON(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM),"unsupported encryption algorithm"},
+{ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE),"unsupported public key type"},
+{ERR_REASON(ASN1_R_UNSUPPORTED_TYPE)     ,"unsupported type"},
+{ERR_REASON(ASN1_R_WRONG_PUBLIC_KEY_TYPE),"wrong public key type"},
+{ERR_REASON(ASN1_R_WRONG_TAG)            ,"wrong tag"},
+{ERR_REASON(ASN1_R_WRONG_TYPE)           ,"wrong type"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_ASN1_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,ASN1_str_functs);
+		ERR_load_strings(0,ASN1_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/asn1/asn1_gen.c b/openssl/crypto/asn1/asn1_gen.c
new file mode 100644
index 0000000..4fc2419
--- /dev/null
+++ b/openssl/crypto/asn1/asn1_gen.c
@@ -0,0 +1,854 @@
+/* asn1_gen.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/x509v3.h>
+
+#define ASN1_GEN_FLAG		0x10000
+#define ASN1_GEN_FLAG_IMP	(ASN1_GEN_FLAG|1)
+#define ASN1_GEN_FLAG_EXP	(ASN1_GEN_FLAG|2)
+#define ASN1_GEN_FLAG_TAG	(ASN1_GEN_FLAG|3)
+#define ASN1_GEN_FLAG_BITWRAP	(ASN1_GEN_FLAG|4)
+#define ASN1_GEN_FLAG_OCTWRAP	(ASN1_GEN_FLAG|5)
+#define ASN1_GEN_FLAG_SEQWRAP	(ASN1_GEN_FLAG|6)
+#define ASN1_GEN_FLAG_SETWRAP	(ASN1_GEN_FLAG|7)
+#define ASN1_GEN_FLAG_FORMAT	(ASN1_GEN_FLAG|8)
+
+#define ASN1_GEN_STR(str,val)	{str, sizeof(str) - 1, val}
+
+#define ASN1_FLAG_EXP_MAX	20
+
+/* Input formats */
+
+/* ASCII: default */
+#define ASN1_GEN_FORMAT_ASCII	1
+/* UTF8 */
+#define ASN1_GEN_FORMAT_UTF8	2
+/* Hex */
+#define ASN1_GEN_FORMAT_HEX	3
+/* List of bits */
+#define ASN1_GEN_FORMAT_BITLIST	4
+
+
+struct tag_name_st
+	{
+	const char *strnam;
+	int len;
+	int tag;
+	};
+
+typedef struct
+	{
+	int exp_tag;
+	int exp_class;
+	int exp_constructed;
+	int exp_pad;
+	long exp_len;
+	} tag_exp_type;
+
+typedef struct
+	{
+	int imp_tag;
+	int imp_class;
+	int utype;
+	int format;
+	const char *str;
+	tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];
+	int exp_count;
+	} tag_exp_arg;
+
+static int bitstr_cb(const char *elem, int len, void *bitstr);
+static int asn1_cb(const char *elem, int len, void *bitstr);
+static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok);
+static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass);
+static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf);
+static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
+static int asn1_str2tag(const char *tagstr, int len);
+
+ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf)
+	{
+	X509V3_CTX cnf;
+
+	if (!nconf)
+		return ASN1_generate_v3(str, NULL);
+
+	X509V3_set_nconf(&cnf, nconf);
+	return ASN1_generate_v3(str, &cnf);
+	}
+
+ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
+	{
+	ASN1_TYPE *ret;
+	tag_exp_arg asn1_tags;
+	tag_exp_type *etmp;
+
+	int i, len;
+
+	unsigned char *orig_der = NULL, *new_der = NULL;
+	const unsigned char *cpy_start;
+	unsigned char *p;
+	const unsigned char *cp;
+	int cpy_len;
+	long hdr_len;
+	int hdr_constructed = 0, hdr_tag, hdr_class;
+	int r;
+
+	asn1_tags.imp_tag = -1;
+	asn1_tags.imp_class = -1;
+	asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
+	asn1_tags.exp_count = 0;
+	if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0)
+		return NULL;
+
+	if ((asn1_tags.utype == V_ASN1_SEQUENCE) || (asn1_tags.utype == V_ASN1_SET))
+		{
+		if (!cnf)
+			{
+			ASN1err(ASN1_F_ASN1_GENERATE_V3, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
+			return NULL;
+			}
+		ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
+		}
+	else
+		ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
+
+	if (!ret)
+		return NULL;
+
+	/* If no tagging return base type */
+	if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0))
+		return ret;
+
+	/* Generate the encoding */
+	cpy_len = i2d_ASN1_TYPE(ret, &orig_der);
+	ASN1_TYPE_free(ret);
+	ret = NULL;
+	/* Set point to start copying for modified encoding */
+	cpy_start = orig_der;
+
+	/* Do we need IMPLICIT tagging? */
+	if (asn1_tags.imp_tag != -1)
+		{
+		/* If IMPLICIT we will replace the underlying tag */
+		/* Skip existing tag+len */
+		r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, cpy_len);
+		if (r & 0x80)
+			goto err;
+		/* Update copy length */
+		cpy_len -= cpy_start - orig_der;
+		/* For IMPLICIT tagging the length should match the
+		 * original length and constructed flag should be
+		 * consistent.
+		 */
+		if (r & 0x1)
+			{
+			/* Indefinite length constructed */
+			hdr_constructed = 2;
+			hdr_len = 0;
+			}
+		else
+			/* Just retain constructed flag */
+			hdr_constructed = r & V_ASN1_CONSTRUCTED;
+		/* Work out new length with IMPLICIT tag: ignore constructed
+		 * because it will mess up if indefinite length
+		 */
+		len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
+		}
+	else
+		len = cpy_len;
+
+	/* Work out length in any EXPLICIT, starting from end */
+
+	for(i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; i < asn1_tags.exp_count; i++, etmp--)
+		{
+		/* Content length: number of content octets + any padding */
+		len += etmp->exp_pad;
+		etmp->exp_len = len;
+		/* Total object length: length including new header */
+		len = ASN1_object_size(0, len, etmp->exp_tag);
+		}
+
+	/* Allocate buffer for new encoding */
+
+	new_der = OPENSSL_malloc(len);
+	if (!new_der)
+		goto err;
+
+	/* Generate tagged encoding */
+
+	p = new_der;
+
+	/* Output explicit tags first */
+
+	for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; i++, etmp++)
+		{
+		ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,
+					etmp->exp_tag, etmp->exp_class);
+		if (etmp->exp_pad)
+			*p++ = 0;
+		}
+
+	/* If IMPLICIT, output tag */
+
+	if (asn1_tags.imp_tag != -1)
+		{
+		if (asn1_tags.imp_class == V_ASN1_UNIVERSAL 
+		    && (asn1_tags.imp_tag == V_ASN1_SEQUENCE
+		     || asn1_tags.imp_tag == V_ASN1_SET) )
+			hdr_constructed = V_ASN1_CONSTRUCTED;
+		ASN1_put_object(&p, hdr_constructed, hdr_len,
+					asn1_tags.imp_tag, asn1_tags.imp_class);
+		}
+
+	/* Copy across original encoding */
+	memcpy(p, cpy_start, cpy_len);
+
+	cp = new_der;
+
+	/* Obtain new ASN1_TYPE structure */
+	ret = d2i_ASN1_TYPE(NULL, &cp, len);
+
+	err:
+	if (orig_der)
+		OPENSSL_free(orig_der);
+	if (new_der)
+		OPENSSL_free(new_der);
+
+	return ret;
+
+	}
+
+static int asn1_cb(const char *elem, int len, void *bitstr)
+	{
+	tag_exp_arg *arg = bitstr;
+	int i;
+	int utype;
+	int vlen = 0;
+	const char *p, *vstart = NULL;
+
+	int tmp_tag, tmp_class;
+
+	for(i = 0, p = elem; i < len; p++, i++)
+		{
+		/* Look for the ':' in name value pairs */
+		if (*p == ':')
+			{
+			vstart = p + 1;
+			vlen = len - (vstart - elem);
+			len = p - elem;
+			break;
+			}
+		}
+
+	utype = asn1_str2tag(elem, len);
+
+	if (utype == -1)
+		{
+		ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG);
+		ERR_add_error_data(2, "tag=", elem);
+		return -1;
+		}
+
+	/* If this is not a modifier mark end of string and exit */
+	if (!(utype & ASN1_GEN_FLAG))
+		{
+		arg->utype = utype;
+		arg->str = vstart;
+		/* If no value and not end of string, error */
+		if (!vstart && elem[len])
+			{
+			ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE);
+			return -1;
+			}
+		return 0;
+		}
+
+	switch(utype)
+		{
+
+		case ASN1_GEN_FLAG_IMP:
+		/* Check for illegal multiple IMPLICIT tagging */
+		if (arg->imp_tag != -1)
+			{
+			ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING);
+			return -1;
+			}
+		if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class))
+			return -1;
+		break;
+
+		case ASN1_GEN_FLAG_EXP:
+
+		if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class))
+			return -1;
+		if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0))
+			return -1;
+		break;
+
+		case ASN1_GEN_FLAG_SEQWRAP:
+		if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1))
+			return -1;
+		break;
+
+		case ASN1_GEN_FLAG_SETWRAP:
+		if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1))
+			return -1;
+		break;
+
+		case ASN1_GEN_FLAG_BITWRAP:
+		if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1))
+			return -1;
+		break;
+
+		case ASN1_GEN_FLAG_OCTWRAP:
+		if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1))
+			return -1;
+		break;
+
+		case ASN1_GEN_FLAG_FORMAT:
+		if (!strncmp(vstart, "ASCII", 5))
+			arg->format = ASN1_GEN_FORMAT_ASCII;
+		else if (!strncmp(vstart, "UTF8", 4))
+			arg->format = ASN1_GEN_FORMAT_UTF8;
+		else if (!strncmp(vstart, "HEX", 3))
+			arg->format = ASN1_GEN_FORMAT_HEX;
+		else if (!strncmp(vstart, "BITLIST", 3))
+			arg->format = ASN1_GEN_FORMAT_BITLIST;
+		else
+			{
+			ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT);
+			return -1;
+			}
+		break;
+
+		}
+
+	return 1;
+
+	}
+
+static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
+	{
+	char erch[2];
+	long tag_num;
+	char *eptr;
+	if (!vstart)
+		return 0;
+	tag_num = strtoul(vstart, &eptr, 10);
+	/* Check we haven't gone past max length: should be impossible */
+	if (eptr && *eptr && (eptr > vstart + vlen))
+		return 0;
+	if (tag_num < 0)
+		{
+		ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER);
+		return 0;
+		}
+	*ptag = tag_num;
+	/* If we have non numeric characters, parse them */
+	if (eptr)
+		vlen -= eptr - vstart;
+	else 
+		vlen = 0;
+	if (vlen)
+		{
+		switch (*eptr)
+			{
+
+			case 'U':
+			*pclass = V_ASN1_UNIVERSAL;
+			break;
+
+			case 'A':
+			*pclass = V_ASN1_APPLICATION;
+			break;
+
+			case 'P':
+			*pclass = V_ASN1_PRIVATE;
+			break;
+
+			case 'C':
+			*pclass = V_ASN1_CONTEXT_SPECIFIC;
+			break;
+
+			default:
+			erch[0] = *eptr;
+			erch[1] = 0;
+			ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER);
+			ERR_add_error_data(2, "Char=", erch);
+			return 0;
+			break;
+
+			}
+		}
+	else
+		*pclass = V_ASN1_CONTEXT_SPECIFIC;
+
+	return 1;
+
+	}
+
+/* Handle multiple types: SET and SEQUENCE */
+
+static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
+	{
+	ASN1_TYPE *ret = NULL;
+	STACK_OF(ASN1_TYPE) *sk = NULL;
+	STACK_OF(CONF_VALUE) *sect = NULL;
+	unsigned char *der = NULL;
+	int derlen;
+	int i;
+	sk = sk_ASN1_TYPE_new_null();
+	if (!sk)
+		goto bad;
+	if (section)
+		{
+		if (!cnf)
+			goto bad;
+		sect = X509V3_get_section(cnf, (char *)section);
+		if (!sect)
+			goto bad;
+		for (i = 0; i < sk_CONF_VALUE_num(sect); i++)
+			{
+			ASN1_TYPE *typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
+			if (!typ)
+				goto bad;
+			if (!sk_ASN1_TYPE_push(sk, typ))
+				goto bad;
+			}
+		}
+
+	/* Now we has a STACK of the components, convert to the correct form */
+
+	if (utype == V_ASN1_SET)
+		derlen = i2d_ASN1_SET_ANY(sk, &der);
+	else
+		derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
+
+	if (derlen < 0)
+		goto bad;
+
+	if (!(ret = ASN1_TYPE_new()))
+		goto bad;
+
+	if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype)))
+		goto bad;
+
+	ret->type = utype;
+
+	ret->value.asn1_string->data = der;
+	ret->value.asn1_string->length = derlen;
+
+	der = NULL;
+
+	bad:
+
+	if (der)
+		OPENSSL_free(der);
+
+	if (sk)
+		sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
+	if (sect)
+		X509V3_section_free(cnf, sect);
+
+	return ret;
+	}
+
+static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok)
+	{
+	tag_exp_type *exp_tmp;
+	/* Can only have IMPLICIT if permitted */
+	if ((arg->imp_tag != -1) && !imp_ok)
+		{
+		ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG);
+		return 0;
+		}
+
+	if (arg->exp_count == ASN1_FLAG_EXP_MAX)
+		{
+		ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED);
+		return 0;
+		}
+
+	exp_tmp = &arg->exp_list[arg->exp_count++];
+
+	/* If IMPLICIT set tag to implicit value then
+	 * reset implicit tag since it has been used.
+	 */
+	if (arg->imp_tag != -1)
+		{
+		exp_tmp->exp_tag = arg->imp_tag;
+		exp_tmp->exp_class = arg->imp_class;
+		arg->imp_tag = -1;
+		arg->imp_class = -1;
+		}
+	else
+		{
+		exp_tmp->exp_tag = exp_tag;
+		exp_tmp->exp_class = exp_class;
+		}
+	exp_tmp->exp_constructed = exp_constructed;
+	exp_tmp->exp_pad = exp_pad;
+
+	return 1;
+	}
+
+
+static int asn1_str2tag(const char *tagstr, int len)
+	{
+	unsigned int i;
+	static const struct tag_name_st *tntmp, tnst [] = {
+		ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
+		ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN),
+		ASN1_GEN_STR("NULL", V_ASN1_NULL),
+		ASN1_GEN_STR("INT", V_ASN1_INTEGER),
+		ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER),
+		ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED),
+		ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED),
+		ASN1_GEN_STR("OID", V_ASN1_OBJECT),
+		ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT),
+		ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME),
+		ASN1_GEN_STR("UTC", V_ASN1_UTCTIME),
+		ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME),
+		ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME),
+		ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING),
+		ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING),
+		ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING),
+		ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING),
+		ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING),
+		ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING),
+		ASN1_GEN_STR("IA5", V_ASN1_IA5STRING),
+		ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING),
+		ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING),
+		ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING),
+		ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING),
+		ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING),
+		ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING),
+		ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING),
+		ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING),
+		ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING),
+		ASN1_GEN_STR("T61", V_ASN1_T61STRING),
+		ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING),
+		ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING),
+		ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING),
+		ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING),
+		ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING),
+		ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING),
+
+		/* Special cases */
+		ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE),
+		ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE),
+		ASN1_GEN_STR("SET", V_ASN1_SET),
+		/* type modifiers */
+		/* Explicit tag */
+		ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP),
+		ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP),
+		/* Implicit tag */
+		ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP),
+		ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP),
+		/* OCTET STRING wrapper */
+		ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP),
+		/* SEQUENCE wrapper */
+		ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP),
+		/* SET wrapper */
+		ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP),
+		/* BIT STRING wrapper */
+		ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP),
+		ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT),
+		ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT),
+	};
+
+	if (len == -1)
+		len = strlen(tagstr);
+	
+	tntmp = tnst;	
+	for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++)
+		{
+		if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len))
+			return tntmp->tag;
+		}
+	
+	return -1;
+	}
+
+static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
+	{
+	ASN1_TYPE *atmp = NULL;
+
+	CONF_VALUE vtmp;
+
+	unsigned char *rdata;
+	long rdlen;
+
+	int no_unused = 1;
+
+	if (!(atmp = ASN1_TYPE_new()))
+		{
+		ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+
+	if (!str)
+		str = "";
+
+	switch(utype)
+		{
+
+		case V_ASN1_NULL:
+		if (str && *str)
+			{
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE);
+			goto bad_form;
+			}
+		break;
+		
+		case V_ASN1_BOOLEAN:
+		if (format != ASN1_GEN_FORMAT_ASCII)
+			{
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT);
+			goto bad_form;
+			}
+		vtmp.name = NULL;
+		vtmp.section = NULL;
+		vtmp.value = (char *)str;
+		if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean))
+			{
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN);
+			goto bad_str;
+			}
+		break;
+
+		case V_ASN1_INTEGER:
+		case V_ASN1_ENUMERATED:
+		if (format != ASN1_GEN_FORMAT_ASCII)
+			{
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
+			goto bad_form;
+			}
+		if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str)))
+			{
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER);
+			goto bad_str;
+			}
+		break;
+
+		case V_ASN1_OBJECT:
+		if (format != ASN1_GEN_FORMAT_ASCII)
+			{
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
+			goto bad_form;
+			}
+		if (!(atmp->value.object = OBJ_txt2obj(str, 0)))
+			{
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT);
+			goto bad_str;
+			}
+		break;
+
+		case V_ASN1_UTCTIME:
+		case V_ASN1_GENERALIZEDTIME:
+		if (format != ASN1_GEN_FORMAT_ASCII)
+			{
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT);
+			goto bad_form;
+			}
+		if (!(atmp->value.asn1_string = ASN1_STRING_new()))
+			{
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+			goto bad_str;
+			}
+		if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1))
+			{
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+			goto bad_str;
+			}
+		atmp->value.asn1_string->type = utype;
+		if (!ASN1_TIME_check(atmp->value.asn1_string))
+			{
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE);
+			goto bad_str;
+			}
+
+		break;
+
+		case V_ASN1_BMPSTRING:
+		case V_ASN1_PRINTABLESTRING:
+		case V_ASN1_IA5STRING:
+		case V_ASN1_T61STRING:
+		case V_ASN1_UTF8STRING:
+		case V_ASN1_VISIBLESTRING:
+		case V_ASN1_UNIVERSALSTRING:
+		case V_ASN1_GENERALSTRING:
+		case V_ASN1_NUMERICSTRING:
+
+		if (format == ASN1_GEN_FORMAT_ASCII)
+			format = MBSTRING_ASC;
+		else if (format == ASN1_GEN_FORMAT_UTF8)
+			format = MBSTRING_UTF8;
+		else
+			{
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT);
+			goto bad_form;
+			}
+
+
+		if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
+						-1, format, ASN1_tag2bit(utype)) <= 0)
+			{
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+			goto bad_str;
+			}
+		
+
+		break;
+
+		case V_ASN1_BIT_STRING:
+
+		case V_ASN1_OCTET_STRING:
+
+		if (!(atmp->value.asn1_string = ASN1_STRING_new()))
+			{
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+			goto bad_form;
+			}
+
+		if (format == ASN1_GEN_FORMAT_HEX)
+			{
+
+			if (!(rdata = string_to_hex((char *)str, &rdlen)))
+				{
+				ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX);
+				goto bad_str;
+				}
+
+			atmp->value.asn1_string->data = rdata;
+			atmp->value.asn1_string->length = rdlen;
+			atmp->value.asn1_string->type = utype;
+
+			}
+		else if (format == ASN1_GEN_FORMAT_ASCII)
+			ASN1_STRING_set(atmp->value.asn1_string, str, -1);
+		else if ((format == ASN1_GEN_FORMAT_BITLIST) && (utype == V_ASN1_BIT_STRING))
+			{
+			if (!CONF_parse_list(str, ',', 1, bitstr_cb, atmp->value.bit_string))
+				{
+				ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR);
+				goto bad_str;
+				}
+			no_unused = 0;
+			
+			}
+		else 
+			{
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
+			goto bad_form;
+			}
+
+		if ((utype == V_ASN1_BIT_STRING) && no_unused)
+			{
+			atmp->value.asn1_string->flags
+				&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
+        		atmp->value.asn1_string->flags
+				|= ASN1_STRING_FLAG_BITS_LEFT;
+			}
+
+
+		break;
+
+		default:
+		ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE);
+		goto bad_str;
+		break;
+		}
+
+
+	atmp->type = utype;
+	return atmp;
+
+
+	bad_str:
+	ERR_add_error_data(2, "string=", str);
+	bad_form:
+
+	ASN1_TYPE_free(atmp);
+	return NULL;
+
+	}
+
+static int bitstr_cb(const char *elem, int len, void *bitstr)
+	{
+	long bitnum;
+	char *eptr;
+	if (!elem)
+		return 0;
+	bitnum = strtoul(elem, &eptr, 10);
+	if (eptr && *eptr && (eptr != elem + len))
+		return 0;
+	if (bitnum < 0)
+		{
+		ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER);
+		return 0;
+		}
+	if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1))
+		{
+		ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	return 1;
+	}
+
diff --git a/openssl/crypto/asn1/asn1_lib.c b/openssl/crypto/asn1/asn1_lib.c
new file mode 100644
index 0000000..1bcb44a
--- /dev/null
+++ b/openssl/crypto/asn1/asn1_lib.c
@@ -0,0 +1,482 @@
+/* crypto/asn1/asn1_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <limits.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1_mac.h>
+
+static int asn1_get_length(const unsigned char **pp,int *inf,long *rl,int max);
+static void asn1_put_length(unsigned char **pp, int length);
+const char ASN1_version[]="ASN.1" OPENSSL_VERSION_PTEXT;
+
+static int _asn1_check_infinite_end(const unsigned char **p, long len)
+	{
+	/* If there is 0 or 1 byte left, the length check should pick
+	 * things up */
+	if (len <= 0)
+		return(1);
+	else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0))
+		{
+		(*p)+=2;
+		return(1);
+		}
+	return(0);
+	}
+
+int ASN1_check_infinite_end(unsigned char **p, long len)
+	{
+	return _asn1_check_infinite_end((const unsigned char **)p, len);
+	}
+
+int ASN1_const_check_infinite_end(const unsigned char **p, long len)
+	{
+	return _asn1_check_infinite_end(p, len);
+	}
+
+
+int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
+	int *pclass, long omax)
+	{
+	int i,ret;
+	long l;
+	const unsigned char *p= *pp;
+	int tag,xclass,inf;
+	long max=omax;
+
+	if (!max) goto err;
+	ret=(*p&V_ASN1_CONSTRUCTED);
+	xclass=(*p&V_ASN1_PRIVATE);
+	i= *p&V_ASN1_PRIMITIVE_TAG;
+	if (i == V_ASN1_PRIMITIVE_TAG)
+		{		/* high-tag */
+		p++;
+		if (--max == 0) goto err;
+		l=0;
+		while (*p&0x80)
+			{
+			l<<=7L;
+			l|= *(p++)&0x7f;
+			if (--max == 0) goto err;
+			if (l > (INT_MAX >> 7L)) goto err;
+			}
+		l<<=7L;
+		l|= *(p++)&0x7f;
+		tag=(int)l;
+		if (--max == 0) goto err;
+		}
+	else
+		{ 
+		tag=i;
+		p++;
+		if (--max == 0) goto err;
+		}
+	*ptag=tag;
+	*pclass=xclass;
+	if (!asn1_get_length(&p,&inf,plength,(int)max)) goto err;
+
+#if 0
+	fprintf(stderr,"p=%d + *plength=%ld > omax=%ld + *pp=%d  (%d > %d)\n", 
+		(int)p,*plength,omax,(int)*pp,(int)(p+ *plength),
+		(int)(omax+ *pp));
+
+#endif
+	if (*plength > (omax - (p - *pp)))
+		{
+		ASN1err(ASN1_F_ASN1_GET_OBJECT,ASN1_R_TOO_LONG);
+		/* Set this so that even if things are not long enough
+		 * the values are set correctly */
+		ret|=0x80;
+		}
+	*pp=p;
+	return(ret|inf);
+err:
+	ASN1err(ASN1_F_ASN1_GET_OBJECT,ASN1_R_HEADER_TOO_LONG);
+	return(0x80);
+	}
+
+static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max)
+	{
+	const unsigned char *p= *pp;
+	unsigned long ret=0;
+	unsigned int i;
+
+	if (max-- < 1) return(0);
+	if (*p == 0x80)
+		{
+		*inf=1;
+		ret=0;
+		p++;
+		}
+	else
+		{
+		*inf=0;
+		i= *p&0x7f;
+		if (*(p++) & 0x80)
+			{
+			if (i > sizeof(long))
+				return 0;
+			if (max-- == 0) return(0);
+			while (i-- > 0)
+				{
+				ret<<=8L;
+				ret|= *(p++);
+				if (max-- == 0) return(0);
+				}
+			}
+		else
+			ret=i;
+		}
+	if (ret > LONG_MAX)
+		return 0;
+	*pp=p;
+	*rl=(long)ret;
+	return(1);
+	}
+
+/* class 0 is constructed
+ * constructed == 2 for indefinite length constructed */
+void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
+	     int xclass)
+	{
+	unsigned char *p= *pp;
+	int i, ttag;
+
+	i=(constructed)?V_ASN1_CONSTRUCTED:0;
+	i|=(xclass&V_ASN1_PRIVATE);
+	if (tag < 31)
+		*(p++)=i|(tag&V_ASN1_PRIMITIVE_TAG);
+	else
+		{
+		*(p++)=i|V_ASN1_PRIMITIVE_TAG;
+		for(i = 0, ttag = tag; ttag > 0; i++) ttag >>=7;
+		ttag = i;
+		while(i-- > 0)
+			{
+			p[i] = tag & 0x7f;
+			if(i != (ttag - 1)) p[i] |= 0x80;
+			tag >>= 7;
+			}
+		p += ttag;
+		}
+	if (constructed == 2)
+		*(p++)=0x80;
+	else
+		asn1_put_length(&p,length);
+	*pp=p;
+	}
+
+int ASN1_put_eoc(unsigned char **pp)
+	{
+	unsigned char *p = *pp;
+	*p++ = 0;
+	*p++ = 0;
+	*pp = p;
+	return 2;
+	}
+
+static void asn1_put_length(unsigned char **pp, int length)
+	{
+	unsigned char *p= *pp;
+	int i,l;
+	if (length <= 127)
+		*(p++)=(unsigned char)length;
+	else
+		{
+		l=length;
+		for (i=0; l > 0; i++)
+			l>>=8;
+		*(p++)=i|0x80;
+		l=i;
+		while (i-- > 0)
+			{
+			p[i]=length&0xff;
+			length>>=8;
+			}
+		p+=l;
+		}
+	*pp=p;
+	}
+
+int ASN1_object_size(int constructed, int length, int tag)
+	{
+	int ret;
+
+	ret=length;
+	ret++;
+	if (tag >= 31)
+		{
+		while (tag > 0)
+			{
+			tag>>=7;
+			ret++;
+			}
+		}
+	if (constructed == 2)
+		return ret + 3;
+	ret++;
+	if (length > 127)
+		{
+		while (length > 0)
+			{
+			length>>=8;
+			ret++;
+			}
+		}
+	return(ret);
+	}
+
+static int _asn1_Finish(ASN1_const_CTX *c)
+	{
+	if ((c->inf == (1|V_ASN1_CONSTRUCTED)) && (!c->eos))
+		{
+		if (!ASN1_const_check_infinite_end(&c->p,c->slen))
+			{
+			c->error=ERR_R_MISSING_ASN1_EOS;
+			return(0);
+			}
+		}
+	if (	((c->slen != 0) && !(c->inf & 1)) ||
+		((c->slen < 0) && (c->inf & 1)))
+		{
+		c->error=ERR_R_ASN1_LENGTH_MISMATCH;
+		return(0);
+		}
+	return(1);
+	}
+
+int asn1_Finish(ASN1_CTX *c)
+	{
+	return _asn1_Finish((ASN1_const_CTX *)c);
+	}
+
+int asn1_const_Finish(ASN1_const_CTX *c)
+	{
+	return _asn1_Finish(c);
+	}
+
+int asn1_GetSequence(ASN1_const_CTX *c, long *length)
+	{
+	const unsigned char *q;
+
+	q=c->p;
+	c->inf=ASN1_get_object(&(c->p),&(c->slen),&(c->tag),&(c->xclass),
+		*length);
+	if (c->inf & 0x80)
+		{
+		c->error=ERR_R_BAD_GET_ASN1_OBJECT_CALL;
+		return(0);
+		}
+	if (c->tag != V_ASN1_SEQUENCE)
+		{
+		c->error=ERR_R_EXPECTING_AN_ASN1_SEQUENCE;
+		return(0);
+		}
+	(*length)-=(c->p-q);
+	if (c->max && (*length < 0))
+		{
+		c->error=ERR_R_ASN1_LENGTH_MISMATCH;
+		return(0);
+		}
+	if (c->inf == (1|V_ASN1_CONSTRUCTED))
+		c->slen= *length+ *(c->pp)-c->p;
+	c->eos=0;
+	return(1);
+	}
+
+int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
+	{
+	if (str == NULL)
+		return 0;
+	dst->type = str->type;
+	if (!ASN1_STRING_set(dst,str->data,str->length))
+		return 0;
+	dst->flags = str->flags;
+	return 1;
+	}
+
+ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
+	{
+	ASN1_STRING *ret;
+	if (!str)
+		 return NULL;
+	ret=ASN1_STRING_new();
+	if (!ret)
+		return NULL;
+	if (!ASN1_STRING_copy(ret,str))
+		{
+		ASN1_STRING_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
+	{
+	unsigned char *c;
+	const char *data=_data;
+
+	if (len < 0)
+		{
+		if (data == NULL)
+			return(0);
+		else
+			len=strlen(data);
+		}
+	if ((str->length < len) || (str->data == NULL))
+		{
+		c=str->data;
+		if (c == NULL)
+			str->data=OPENSSL_malloc(len+1);
+		else
+			str->data=OPENSSL_realloc(c,len+1);
+
+		if (str->data == NULL)
+			{
+			ASN1err(ASN1_F_ASN1_STRING_SET,ERR_R_MALLOC_FAILURE);
+			str->data=c;
+			return(0);
+			}
+		}
+	str->length=len;
+	if (data != NULL)
+		{
+		memcpy(str->data,data,len);
+		/* an allowance for strings :-) */
+		str->data[len]='\0';
+		}
+	return(1);
+	}
+
+void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
+	{
+	if (str->data)
+		OPENSSL_free(str->data);
+	str->data = data;
+	str->length = len;
+	}
+
+ASN1_STRING *ASN1_STRING_new(void)
+	{
+	return(ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
+	}
+
+
+ASN1_STRING *ASN1_STRING_type_new(int type)
+	{
+	ASN1_STRING *ret;
+
+	ret=(ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
+	if (ret == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	ret->length=0;
+	ret->type=type;
+	ret->data=NULL;
+	ret->flags=0;
+	return(ret);
+	}
+
+void ASN1_STRING_free(ASN1_STRING *a)
+	{
+	if (a == NULL) return;
+	if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
+		OPENSSL_free(a->data);
+	OPENSSL_free(a);
+	}
+
+int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
+	{
+	int i;
+
+	i=(a->length-b->length);
+	if (i == 0)
+		{
+		i=memcmp(a->data,b->data,a->length);
+		if (i == 0)
+			return(a->type-b->type);
+		else
+			return(i);
+		}
+	else
+		return(i);
+	}
+
+void asn1_add_error(const unsigned char *address, int offset)
+	{
+	char buf1[DECIMAL_SIZE(address)+1],buf2[DECIMAL_SIZE(offset)+1];
+
+	BIO_snprintf(buf1,sizeof buf1,"%lu",(unsigned long)address);
+	BIO_snprintf(buf2,sizeof buf2,"%d",offset);
+	ERR_add_error_data(4,"address=",buf1," offset=",buf2);
+	}
+
+int ASN1_STRING_length(const ASN1_STRING *x)
+{ return M_ASN1_STRING_length(x); }
+
+void ASN1_STRING_length_set(ASN1_STRING *x, int len)
+{ M_ASN1_STRING_length_set(x, len); return; }
+
+int ASN1_STRING_type(ASN1_STRING *x)
+{ return M_ASN1_STRING_type(x); }
+
+unsigned char * ASN1_STRING_data(ASN1_STRING *x)
+{ return M_ASN1_STRING_data(x); }
diff --git a/openssl/crypto/asn1/asn1_locl.h b/openssl/crypto/asn1/asn1_locl.h
new file mode 100644
index 0000000..5aa65e2
--- /dev/null
+++ b/openssl/crypto/asn1/asn1_locl.h
@@ -0,0 +1,134 @@
+/* asn1t.h */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Internal ASN1 structures and functions: not for application use */
+
+/* ASN1 print context structure */
+
+struct asn1_pctx_st
+	{
+	unsigned long flags;
+	unsigned long nm_flags;
+	unsigned long cert_flags;
+	unsigned long oid_flags;
+	unsigned long str_flags;
+	} /* ASN1_PCTX */;
+
+/* ASN1 public key method structure */
+
+struct evp_pkey_asn1_method_st
+	{
+	int pkey_id;
+	int pkey_base_id;
+	unsigned long pkey_flags;
+
+	char *pem_str;
+	char *info;
+
+	int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub);
+	int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk);
+	int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
+	int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx);
+
+	int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf);
+	int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
+	int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx);
+
+	int (*pkey_size)(const EVP_PKEY *pk);
+	int (*pkey_bits)(const EVP_PKEY *pk);
+
+	int (*param_decode)(EVP_PKEY *pkey,
+				const unsigned char **pder, int derlen);
+	int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder);
+	int (*param_missing)(const EVP_PKEY *pk);
+	int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
+	int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
+	int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx);
+
+	void (*pkey_free)(EVP_PKEY *pkey);
+	int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
+
+	/* Legacy functions for old PEM */
+
+	int (*old_priv_decode)(EVP_PKEY *pkey,
+				const unsigned char **pder, int derlen);
+	int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
+
+	} /* EVP_PKEY_ASN1_METHOD */;
+
+/* Method to handle CRL access.
+ * In general a CRL could be very large (several Mb) and can consume large
+ * amounts of resources if stored in memory by multiple processes.
+ * This method allows general CRL operations to be redirected to more
+ * efficient callbacks: for example a CRL entry database.
+ */
+
+#define X509_CRL_METHOD_DYNAMIC		1
+
+struct x509_crl_method_st
+	{
+	int flags;
+	int (*crl_init)(X509_CRL *crl);
+	int (*crl_free)(X509_CRL *crl);
+	int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
+				ASN1_INTEGER *ser, X509_NAME *issuer);
+	int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk);
+	};
diff --git a/openssl/crypto/asn1/asn1_mac.h b/openssl/crypto/asn1/asn1_mac.h
new file mode 100644
index 0000000..87bd0e9
--- /dev/null
+++ b/openssl/crypto/asn1/asn1_mac.h
@@ -0,0 +1,578 @@
+/* crypto/asn1/asn1_mac.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ASN1_MAC_H
+#define HEADER_ASN1_MAC_H
+
+#include <openssl/asn1.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifndef ASN1_MAC_ERR_LIB
+#define ASN1_MAC_ERR_LIB	ERR_LIB_ASN1
+#endif 
+
+#define ASN1_MAC_H_err(f,r,line) \
+	ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),__FILE__,(line))
+
+#define M_ASN1_D2I_vars(a,type,func) \
+	ASN1_const_CTX c; \
+	type ret=NULL; \
+	\
+	c.pp=(const unsigned char **)pp; \
+	c.q= *(const unsigned char **)pp; \
+	c.error=ERR_R_NESTED_ASN1_ERROR; \
+	if ((a == NULL) || ((*a) == NULL)) \
+		{ if ((ret=(type)func()) == NULL) \
+			{ c.line=__LINE__; goto err; } } \
+	else	ret=(*a);
+
+#define M_ASN1_D2I_Init() \
+	c.p= *(const unsigned char **)pp; \
+	c.max=(length == 0)?0:(c.p+length);
+
+#define M_ASN1_D2I_Finish_2(a) \
+	if (!asn1_const_Finish(&c)) \
+		{ c.line=__LINE__; goto err; } \
+	*(const unsigned char **)pp=c.p; \
+	if (a != NULL) (*a)=ret; \
+	return(ret);
+
+#define M_ASN1_D2I_Finish(a,func,e) \
+	M_ASN1_D2I_Finish_2(a); \
+err:\
+	ASN1_MAC_H_err((e),c.error,c.line); \
+	asn1_add_error(*(const unsigned char **)pp,(int)(c.q- *pp)); \
+	if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
+	return(NULL)
+
+#define M_ASN1_D2I_start_sequence() \
+	if (!asn1_GetSequence(&c,&length)) \
+		{ c.line=__LINE__; goto err; }
+/* Begin reading ASN1 without a surrounding sequence */
+#define M_ASN1_D2I_begin() \
+	c.slen = length;
+
+/* End reading ASN1 with no check on length */
+#define M_ASN1_D2I_Finish_nolen(a, func, e) \
+	*pp=c.p; \
+	if (a != NULL) (*a)=ret; \
+	return(ret); \
+err:\
+	ASN1_MAC_H_err((e),c.error,c.line); \
+	asn1_add_error(*pp,(int)(c.q- *pp)); \
+	if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
+	return(NULL)
+
+#define M_ASN1_D2I_end_sequence() \
+	(((c.inf&1) == 0)?(c.slen <= 0): \
+		(c.eos=ASN1_const_check_infinite_end(&c.p,c.slen)))
+
+/* Don't use this with d2i_ASN1_BOOLEAN() */
+#define M_ASN1_D2I_get(b, func) \
+	c.q=c.p; \
+	if (func(&(b),&c.p,c.slen) == NULL) \
+		{c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+/* Don't use this with d2i_ASN1_BOOLEAN() */
+#define M_ASN1_D2I_get_x(type,b,func) \
+	c.q=c.p; \
+	if (((D2I_OF(type))func)(&(b),&c.p,c.slen) == NULL) \
+		{c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+/* use this instead () */
+#define M_ASN1_D2I_get_int(b,func) \
+	c.q=c.p; \
+	if (func(&(b),&c.p,c.slen) < 0) \
+		{c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+#define M_ASN1_D2I_get_opt(b,func,type) \
+	if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
+		== (V_ASN1_UNIVERSAL|(type)))) \
+		{ \
+		M_ASN1_D2I_get(b,func); \
+		}
+
+#define M_ASN1_D2I_get_int_opt(b,func,type) \
+	if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
+		== (V_ASN1_UNIVERSAL|(type)))) \
+		{ \
+		M_ASN1_D2I_get_int(b,func); \
+		}
+
+#define M_ASN1_D2I_get_imp(b,func, type) \
+	M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \
+	c.q=c.p; \
+	if (func(&(b),&c.p,c.slen) == NULL) \
+		{c.line=__LINE__; M_ASN1_next_prev = _tmp; goto err; } \
+	c.slen-=(c.p-c.q);\
+	M_ASN1_next_prev=_tmp;
+
+#define M_ASN1_D2I_get_IMP_opt(b,func,tag,type) \
+	if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) == \
+		(V_ASN1_CONTEXT_SPECIFIC|(tag)))) \
+		{ \
+		unsigned char _tmp = M_ASN1_next; \
+		M_ASN1_D2I_get_imp(b,func, type);\
+		}
+
+#define M_ASN1_D2I_get_set(r,func,free_func) \
+		M_ASN1_D2I_get_imp_set(r,func,free_func, \
+			V_ASN1_SET,V_ASN1_UNIVERSAL);
+
+#define M_ASN1_D2I_get_set_type(type,r,func,free_func) \
+		M_ASN1_D2I_get_imp_set_type(type,r,func,free_func, \
+			V_ASN1_SET,V_ASN1_UNIVERSAL);
+
+#define M_ASN1_D2I_get_set_opt(r,func,free_func) \
+	if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+		V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
+		{ M_ASN1_D2I_get_set(r,func,free_func); }
+
+#define M_ASN1_D2I_get_set_opt_type(type,r,func,free_func) \
+	if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+		V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
+		{ M_ASN1_D2I_get_set_type(type,r,func,free_func); }
+
+#define M_ASN1_I2D_len_SET_opt(a,f) \
+	if ((a != NULL) && (sk_num(a) != 0)) \
+		M_ASN1_I2D_len_SET(a,f);
+
+#define M_ASN1_I2D_put_SET_opt(a,f) \
+	if ((a != NULL) && (sk_num(a) != 0)) \
+		M_ASN1_I2D_put_SET(a,f);
+
+#define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
+	if ((a != NULL) && (sk_num(a) != 0)) \
+		M_ASN1_I2D_put_SEQUENCE(a,f);
+
+#define M_ASN1_I2D_put_SEQUENCE_opt_type(type,a,f) \
+	if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+		M_ASN1_I2D_put_SEQUENCE_type(type,a,f);
+
+#define M_ASN1_D2I_get_IMP_set_opt(b,func,free_func,tag) \
+	if ((c.slen != 0) && \
+		(M_ASN1_next == \
+		(V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
+		{ \
+		M_ASN1_D2I_get_imp_set(b,func,free_func,\
+			tag,V_ASN1_CONTEXT_SPECIFIC); \
+		}
+
+#define M_ASN1_D2I_get_IMP_set_opt_type(type,b,func,free_func,tag) \
+	if ((c.slen != 0) && \
+		(M_ASN1_next == \
+		(V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
+		{ \
+		M_ASN1_D2I_get_imp_set_type(type,b,func,free_func,\
+			tag,V_ASN1_CONTEXT_SPECIFIC); \
+		}
+
+#define M_ASN1_D2I_get_seq(r,func,free_func) \
+		M_ASN1_D2I_get_imp_set(r,func,free_func,\
+			V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
+
+#define M_ASN1_D2I_get_seq_type(type,r,func,free_func) \
+		M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
+					    V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)
+
+#define M_ASN1_D2I_get_seq_opt(r,func,free_func) \
+	if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+		V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
+		{ M_ASN1_D2I_get_seq(r,func,free_func); }
+
+#define M_ASN1_D2I_get_seq_opt_type(type,r,func,free_func) \
+	if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+		V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
+		{ M_ASN1_D2I_get_seq_type(type,r,func,free_func); }
+
+#define M_ASN1_D2I_get_IMP_set(r,func,free_func,x) \
+		M_ASN1_D2I_get_imp_set(r,func,free_func,\
+			x,V_ASN1_CONTEXT_SPECIFIC);
+
+#define M_ASN1_D2I_get_IMP_set_type(type,r,func,free_func,x) \
+		M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
+			x,V_ASN1_CONTEXT_SPECIFIC);
+
+#define M_ASN1_D2I_get_imp_set(r,func,free_func,a,b) \
+	c.q=c.p; \
+	if (d2i_ASN1_SET(&(r),&c.p,c.slen,(char *(*)())func,\
+		(void (*)())free_func,a,b) == NULL) \
+		{ c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+#define M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,a,b) \
+	c.q=c.p; \
+	if (d2i_ASN1_SET_OF_##type(&(r),&c.p,c.slen,func,\
+				   free_func,a,b) == NULL) \
+		{ c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+#define M_ASN1_D2I_get_set_strings(r,func,a,b) \
+	c.q=c.p; \
+	if (d2i_ASN1_STRING_SET(&(r),&c.p,c.slen,a,b) == NULL) \
+		{ c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+#define M_ASN1_D2I_get_EXP_opt(r,func,tag) \
+	if ((c.slen != 0L) && (M_ASN1_next == \
+		(V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
+		{ \
+		int Tinf,Ttag,Tclass; \
+		long Tlen; \
+		\
+		c.q=c.p; \
+		Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
+		if (Tinf & 0x80) \
+			{ c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
+			c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
+					Tlen = c.slen - (c.p - c.q) - 2; \
+		if (func(&(r),&c.p,Tlen) == NULL) \
+			{ c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
+			Tlen = c.slen - (c.p - c.q); \
+			if(!ASN1_const_check_infinite_end(&c.p, Tlen)) \
+				{ c.error=ERR_R_MISSING_ASN1_EOS; \
+				c.line=__LINE__; goto err; } \
+		}\
+		c.slen-=(c.p-c.q); \
+		}
+
+#define M_ASN1_D2I_get_EXP_set_opt(r,func,free_func,tag,b) \
+	if ((c.slen != 0) && (M_ASN1_next == \
+		(V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
+		{ \
+		int Tinf,Ttag,Tclass; \
+		long Tlen; \
+		\
+		c.q=c.p; \
+		Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
+		if (Tinf & 0x80) \
+			{ c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
+			c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
+					Tlen = c.slen - (c.p - c.q) - 2; \
+		if (d2i_ASN1_SET(&(r),&c.p,Tlen,(char *(*)())func, \
+			(void (*)())free_func, \
+			b,V_ASN1_UNIVERSAL) == NULL) \
+			{ c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
+			Tlen = c.slen - (c.p - c.q); \
+			if(!ASN1_check_infinite_end(&c.p, Tlen)) \
+				{ c.error=ERR_R_MISSING_ASN1_EOS; \
+				c.line=__LINE__; goto err; } \
+		}\
+		c.slen-=(c.p-c.q); \
+		}
+
+#define M_ASN1_D2I_get_EXP_set_opt_type(type,r,func,free_func,tag,b) \
+	if ((c.slen != 0) && (M_ASN1_next == \
+		(V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
+		{ \
+		int Tinf,Ttag,Tclass; \
+		long Tlen; \
+		\
+		c.q=c.p; \
+		Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
+		if (Tinf & 0x80) \
+			{ c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
+			c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
+					Tlen = c.slen - (c.p - c.q) - 2; \
+		if (d2i_ASN1_SET_OF_##type(&(r),&c.p,Tlen,func, \
+			free_func,b,V_ASN1_UNIVERSAL) == NULL) \
+			{ c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
+			Tlen = c.slen - (c.p - c.q); \
+			if(!ASN1_check_infinite_end(&c.p, Tlen)) \
+				{ c.error=ERR_R_MISSING_ASN1_EOS; \
+				c.line=__LINE__; goto err; } \
+		}\
+		c.slen-=(c.p-c.q); \
+		}
+
+/* New macros */
+#define M_ASN1_New_Malloc(ret,type) \
+	if ((ret=(type *)OPENSSL_malloc(sizeof(type))) == NULL) \
+		{ c.line=__LINE__; goto err2; }
+
+#define M_ASN1_New(arg,func) \
+	if (((arg)=func()) == NULL) return(NULL)
+
+#define M_ASN1_New_Error(a) \
+/*	err:	ASN1_MAC_H_err((a),ERR_R_NESTED_ASN1_ERROR,c.line); \
+		return(NULL);*/ \
+	err2:	ASN1_MAC_H_err((a),ERR_R_MALLOC_FAILURE,c.line); \
+		return(NULL)
+
+
+/* BIG UGLY WARNING!  This is so damn ugly I wanna puke.  Unfortunately,
+   some macros that use ASN1_const_CTX still insist on writing in the input
+   stream.  ARGH!  ARGH!  ARGH!  Let's get rid of this macro package.
+   Please?						-- Richard Levitte */
+#define M_ASN1_next		(*((unsigned char *)(c.p)))
+#define M_ASN1_next_prev	(*((unsigned char *)(c.q)))
+
+/*************************************************/
+
+#define M_ASN1_I2D_vars(a)	int r=0,ret=0; \
+				unsigned char *p; \
+				if (a == NULL) return(0)
+
+/* Length Macros */
+#define M_ASN1_I2D_len(a,f)	ret+=f(a,NULL)
+#define M_ASN1_I2D_len_IMP_opt(a,f)	if (a != NULL) M_ASN1_I2D_len(a,f)
+
+#define M_ASN1_I2D_len_SET(a,f) \
+		ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);
+
+#define M_ASN1_I2D_len_SET_type(type,a,f) \
+		ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SET, \
+					    V_ASN1_UNIVERSAL,IS_SET);
+
+#define M_ASN1_I2D_len_SEQUENCE(a,f) \
+		ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
+				  IS_SEQUENCE);
+
+#define M_ASN1_I2D_len_SEQUENCE_type(type,a,f) \
+		ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SEQUENCE, \
+					    V_ASN1_UNIVERSAL,IS_SEQUENCE)
+
+#define M_ASN1_I2D_len_SEQUENCE_opt(a,f) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			M_ASN1_I2D_len_SEQUENCE(a,f);
+
+#define M_ASN1_I2D_len_SEQUENCE_opt_type(type,a,f) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			M_ASN1_I2D_len_SEQUENCE_type(type,a,f);
+
+#define M_ASN1_I2D_len_IMP_SET(a,f,x) \
+		ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET);
+
+#define M_ASN1_I2D_len_IMP_SET_type(type,a,f,x) \
+		ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
+					    V_ASN1_CONTEXT_SPECIFIC,IS_SET);
+
+#define M_ASN1_I2D_len_IMP_SET_opt(a,f,x) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+					  IS_SET);
+
+#define M_ASN1_I2D_len_IMP_SET_opt_type(type,a,f,x) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
+					       V_ASN1_CONTEXT_SPECIFIC,IS_SET);
+
+#define M_ASN1_I2D_len_IMP_SEQUENCE(a,f,x) \
+		ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+				  IS_SEQUENCE);
+
+#define M_ASN1_I2D_len_IMP_SEQUENCE_opt(a,f,x) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+					  IS_SEQUENCE);
+
+#define M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(type,a,f,x) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
+						    V_ASN1_CONTEXT_SPECIFIC, \
+						    IS_SEQUENCE);
+
+#define M_ASN1_I2D_len_EXP_opt(a,f,mtag,v) \
+		if (a != NULL)\
+			{ \
+			v=f(a,NULL); \
+			ret+=ASN1_object_size(1,v,mtag); \
+			}
+
+#define M_ASN1_I2D_len_EXP_SET_opt(a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_num(a) != 0))\
+			{ \
+			v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
+			ret+=ASN1_object_size(1,v,mtag); \
+			}
+
+#define M_ASN1_I2D_len_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_num(a) != 0))\
+			{ \
+			v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL, \
+				       IS_SEQUENCE); \
+			ret+=ASN1_object_size(1,v,mtag); \
+			}
+
+#define M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0))\
+			{ \
+			v=i2d_ASN1_SET_OF_##type(a,NULL,f,tag, \
+						 V_ASN1_UNIVERSAL, \
+						 IS_SEQUENCE); \
+			ret+=ASN1_object_size(1,v,mtag); \
+			}
+
+/* Put Macros */
+#define M_ASN1_I2D_put(a,f)	f(a,&p)
+
+#define M_ASN1_I2D_put_IMP_opt(a,f,t)	\
+		if (a != NULL) \
+			{ \
+			unsigned char *q=p; \
+			f(a,&p); \
+			*q=(V_ASN1_CONTEXT_SPECIFIC|t|(*q&V_ASN1_CONSTRUCTED));\
+			}
+
+#define M_ASN1_I2D_put_SET(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SET,\
+			V_ASN1_UNIVERSAL,IS_SET)
+#define M_ASN1_I2D_put_SET_type(type,a,f) \
+     i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET)
+#define M_ASN1_I2D_put_IMP_SET(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
+			V_ASN1_CONTEXT_SPECIFIC,IS_SET)
+#define M_ASN1_I2D_put_IMP_SET_type(type,a,f,x) \
+     i2d_ASN1_SET_OF_##type(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET)
+#define M_ASN1_I2D_put_IMP_SEQUENCE(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
+			V_ASN1_CONTEXT_SPECIFIC,IS_SEQUENCE)
+
+#define M_ASN1_I2D_put_SEQUENCE(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SEQUENCE,\
+					     V_ASN1_UNIVERSAL,IS_SEQUENCE)
+
+#define M_ASN1_I2D_put_SEQUENCE_type(type,a,f) \
+     i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
+			    IS_SEQUENCE)
+
+#define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			M_ASN1_I2D_put_SEQUENCE(a,f);
+
+#define M_ASN1_I2D_put_IMP_SET_opt(a,f,x) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			{ i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+				       IS_SET); }
+
+#define M_ASN1_I2D_put_IMP_SET_opt_type(type,a,f,x) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			{ i2d_ASN1_SET_OF_##type(a,&p,f,x, \
+						 V_ASN1_CONTEXT_SPECIFIC, \
+						 IS_SET); }
+
+#define M_ASN1_I2D_put_IMP_SEQUENCE_opt(a,f,x) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			{ i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+				       IS_SEQUENCE); }
+
+#define M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(type,a,f,x) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			{ i2d_ASN1_SET_OF_##type(a,&p,f,x, \
+						 V_ASN1_CONTEXT_SPECIFIC, \
+						 IS_SEQUENCE); }
+
+#define M_ASN1_I2D_put_EXP_opt(a,f,tag,v) \
+		if (a != NULL) \
+			{ \
+			ASN1_put_object(&p,1,v,tag,V_ASN1_CONTEXT_SPECIFIC); \
+			f(a,&p); \
+			}
+
+#define M_ASN1_I2D_put_EXP_SET_opt(a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			{ \
+			ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
+			i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
+			}
+
+#define M_ASN1_I2D_put_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			{ \
+			ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
+			i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SEQUENCE); \
+			}
+
+#define M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			{ \
+			ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
+			i2d_ASN1_SET_OF_##type(a,&p,f,tag,V_ASN1_UNIVERSAL, \
+					       IS_SEQUENCE); \
+			}
+
+#define M_ASN1_I2D_seq_total() \
+		r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); \
+		if (pp == NULL) return(r); \
+		p= *pp; \
+		ASN1_put_object(&p,1,ret,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)
+
+#define M_ASN1_I2D_INF_seq_start(tag,ctx) \
+		*(p++)=(V_ASN1_CONSTRUCTED|(tag)|(ctx)); \
+		*(p++)=0x80
+
+#define M_ASN1_I2D_INF_seq_end() *(p++)=0x00; *(p++)=0x00
+
+#define M_ASN1_I2D_finish()	*pp=p; \
+				return(r);
+
+int asn1_GetSequence(ASN1_const_CTX *c, long *length);
+void asn1_add_error(const unsigned char *address,int offset);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/asn1/asn1_par.c b/openssl/crypto/asn1/asn1_par.c
new file mode 100644
index 0000000..aaca69a
--- /dev/null
+++ b/openssl/crypto/asn1/asn1_par.c
@@ -0,0 +1,437 @@
+/* crypto/asn1/asn1_par.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/asn1.h>
+
+static int asn1_print_info(BIO *bp, int tag, int xclass,int constructed,
+	int indent);
+static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
+	int offset, int depth, int indent, int dump);
+static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
+	     int indent)
+	{
+	static const char fmt[]="%-18s";
+	char str[128];
+	const char *p;
+
+	if (constructed & V_ASN1_CONSTRUCTED)
+		p="cons: ";
+	else
+		p="prim: ";
+	if (BIO_write(bp,p,6) < 6) goto err;
+	BIO_indent(bp,indent,128);
+
+	p=str;
+	if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
+		BIO_snprintf(str,sizeof str,"priv [ %d ] ",tag);
+	else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
+		BIO_snprintf(str,sizeof str,"cont [ %d ]",tag);
+	else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
+		BIO_snprintf(str,sizeof str,"appl [ %d ]",tag);
+	else if (tag > 30)
+		BIO_snprintf(str,sizeof str,"<ASN1 %d>",tag);
+	else
+		p = ASN1_tag2str(tag);
+
+	if (BIO_printf(bp,fmt,p) <= 0)
+		goto err;
+	return(1);
+err:
+	return(0);
+	}
+
+int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
+	{
+	return(asn1_parse2(bp,&pp,len,0,0,indent,0));
+	}
+
+int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, int dump)
+	{
+	return(asn1_parse2(bp,&pp,len,0,0,indent,dump));
+	}
+
+static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset,
+	     int depth, int indent, int dump)
+	{
+	const unsigned char *p,*ep,*tot,*op,*opp;
+	long len;
+	int tag,xclass,ret=0;
+	int nl,hl,j,r;
+	ASN1_OBJECT *o=NULL;
+	ASN1_OCTET_STRING *os=NULL;
+	/* ASN1_BMPSTRING *bmp=NULL;*/
+	int dump_indent;
+
+#if 0
+	dump_indent = indent;
+#else
+	dump_indent = 6;	/* Because we know BIO_dump_indent() */
+#endif
+	p= *pp;
+	tot=p+length;
+	op=p-1;
+	while ((p < tot) && (op < p))
+		{
+		op=p;
+		j=ASN1_get_object(&p,&len,&tag,&xclass,length);
+#ifdef LINT
+		j=j;
+#endif
+		if (j & 0x80)
+			{
+			if (BIO_write(bp,"Error in encoding\n",18) <= 0)
+				goto end;
+			ret=0;
+			goto end;
+			}
+		hl=(p-op);
+		length-=hl;
+		/* if j == 0x21 it is a constructed indefinite length object */
+		if (BIO_printf(bp,"%5ld:",(long)offset+(long)(op- *pp))
+			<= 0) goto end;
+
+		if (j != (V_ASN1_CONSTRUCTED | 1))
+			{
+			if (BIO_printf(bp,"d=%-2d hl=%ld l=%4ld ",
+				depth,(long)hl,len) <= 0)
+				goto end;
+			}
+		else
+			{
+			if (BIO_printf(bp,"d=%-2d hl=%ld l=inf  ",
+				depth,(long)hl) <= 0)
+				goto end;
+			}
+		if (!asn1_print_info(bp,tag,xclass,j,(indent)?depth:0))
+			goto end;
+		if (j & V_ASN1_CONSTRUCTED)
+			{
+			ep=p+len;
+			if (BIO_write(bp,"\n",1) <= 0) goto end;
+			if (len > length)
+				{
+				BIO_printf(bp,
+					"length is greater than %ld\n",length);
+				ret=0;
+				goto end;
+				}
+			if ((j == 0x21) && (len == 0))
+				{
+				for (;;)
+					{
+					r=asn1_parse2(bp,&p,(long)(tot-p),
+						offset+(p - *pp),depth+1,
+						indent,dump);
+					if (r == 0) { ret=0; goto end; }
+					if ((r == 2) || (p >= tot)) break;
+					}
+				}
+			else
+				while (p < ep)
+					{
+					r=asn1_parse2(bp,&p,(long)len,
+						offset+(p - *pp),depth+1,
+						indent,dump);
+					if (r == 0) { ret=0; goto end; }
+					}
+			}
+		else if (xclass != 0)
+			{
+			p+=len;
+			if (BIO_write(bp,"\n",1) <= 0) goto end;
+			}
+		else
+			{
+			nl=0;
+			if (	(tag == V_ASN1_PRINTABLESTRING) ||
+				(tag == V_ASN1_T61STRING) ||
+				(tag == V_ASN1_IA5STRING) ||
+				(tag == V_ASN1_VISIBLESTRING) ||
+				(tag == V_ASN1_NUMERICSTRING) ||
+				(tag == V_ASN1_UTF8STRING) ||
+				(tag == V_ASN1_UTCTIME) ||
+				(tag == V_ASN1_GENERALIZEDTIME))
+				{
+				if (BIO_write(bp,":",1) <= 0) goto end;
+				if ((len > 0) &&
+					BIO_write(bp,(const char *)p,(int)len)
+					!= (int)len)
+					goto end;
+				}
+			else if (tag == V_ASN1_OBJECT)
+				{
+				opp=op;
+				if (d2i_ASN1_OBJECT(&o,&opp,len+hl) != NULL)
+					{
+					if (BIO_write(bp,":",1) <= 0) goto end;
+					i2a_ASN1_OBJECT(bp,o);
+					}
+				else
+					{
+					if (BIO_write(bp,":BAD OBJECT",11) <= 0)
+						goto end;
+					}
+				}
+			else if (tag == V_ASN1_BOOLEAN)
+				{
+				int ii;
+
+				opp=op;
+				ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl);
+				if (ii < 0)
+					{
+					if (BIO_write(bp,"Bad boolean\n",12) <= 0)
+						goto end;
+					}
+				BIO_printf(bp,":%d",ii);
+				}
+			else if (tag == V_ASN1_BMPSTRING)
+				{
+				/* do the BMP thang */
+				}
+			else if (tag == V_ASN1_OCTET_STRING)
+				{
+				int i,printable=1;
+
+				opp=op;
+				os=d2i_ASN1_OCTET_STRING(NULL,&opp,len+hl);
+				if (os != NULL && os->length > 0)
+					{
+					opp = os->data;
+					/* testing whether the octet string is
+					 * printable */
+					for (i=0; i<os->length; i++)
+						{
+						if ((	(opp[i] < ' ') &&
+							(opp[i] != '\n') &&
+							(opp[i] != '\r') &&
+							(opp[i] != '\t')) ||
+							(opp[i] > '~'))
+							{
+							printable=0;
+							break;
+							}
+						}
+					if (printable)
+					/* printable string */
+						{
+						if (BIO_write(bp,":",1) <= 0)
+							goto end;
+						if (BIO_write(bp,(const char *)opp,
+							os->length) <= 0)
+							goto end;
+						}
+					else if (!dump)
+					/* not printable => print octet string
+					 * as hex dump */
+						{
+						if (BIO_write(bp,"[HEX DUMP]:",11) <= 0)
+							goto end;
+						for (i=0; i<os->length; i++)
+							{
+							if (BIO_printf(bp,"%02X"
+								, opp[i]) <= 0)
+								goto end;
+							}
+						}
+					else
+					/* print the normal dump */
+						{
+						if (!nl) 
+							{
+							if (BIO_write(bp,"\n",1) <= 0)
+								goto end;
+							}
+						if (BIO_dump_indent(bp,
+							(const char *)opp,
+							((dump == -1 || dump > 
+							os->length)?os->length:dump),
+							dump_indent) <= 0)
+							goto end;
+						nl=1;
+						}
+					}
+				if (os != NULL)
+					{
+					M_ASN1_OCTET_STRING_free(os);
+					os=NULL;
+					}
+				}
+			else if (tag == V_ASN1_INTEGER)
+				{
+				ASN1_INTEGER *bs;
+				int i;
+
+				opp=op;
+				bs=d2i_ASN1_INTEGER(NULL,&opp,len+hl);
+				if (bs != NULL)
+					{
+					if (BIO_write(bp,":",1) <= 0) goto end;
+					if (bs->type == V_ASN1_NEG_INTEGER)
+						if (BIO_write(bp,"-",1) <= 0)
+							goto end;
+					for (i=0; i<bs->length; i++)
+						{
+						if (BIO_printf(bp,"%02X",
+							bs->data[i]) <= 0)
+							goto end;
+						}
+					if (bs->length == 0)
+						{
+						if (BIO_write(bp,"00",2) <= 0)
+							goto end;
+						}
+					}
+				else
+					{
+					if (BIO_write(bp,"BAD INTEGER",11) <= 0)
+						goto end;
+					}
+				M_ASN1_INTEGER_free(bs);
+				}
+			else if (tag == V_ASN1_ENUMERATED)
+				{
+				ASN1_ENUMERATED *bs;
+				int i;
+
+				opp=op;
+				bs=d2i_ASN1_ENUMERATED(NULL,&opp,len+hl);
+				if (bs != NULL)
+					{
+					if (BIO_write(bp,":",1) <= 0) goto end;
+					if (bs->type == V_ASN1_NEG_ENUMERATED)
+						if (BIO_write(bp,"-",1) <= 0)
+							goto end;
+					for (i=0; i<bs->length; i++)
+						{
+						if (BIO_printf(bp,"%02X",
+							bs->data[i]) <= 0)
+							goto end;
+						}
+					if (bs->length == 0)
+						{
+						if (BIO_write(bp,"00",2) <= 0)
+							goto end;
+						}
+					}
+				else
+					{
+					if (BIO_write(bp,"BAD ENUMERATED",11) <= 0)
+						goto end;
+					}
+				M_ASN1_ENUMERATED_free(bs);
+				}
+			else if (len > 0 && dump)
+				{
+				if (!nl) 
+					{
+					if (BIO_write(bp,"\n",1) <= 0)
+						goto end;
+					}
+				if (BIO_dump_indent(bp,(const char *)p,
+					((dump == -1 || dump > len)?len:dump),
+					dump_indent) <= 0)
+					goto end;
+				nl=1;
+				}
+
+			if (!nl) 
+				{
+				if (BIO_write(bp,"\n",1) <= 0) goto end;
+				}
+			p+=len;
+			if ((tag == V_ASN1_EOC) && (xclass == 0))
+				{
+				ret=2; /* End of sequence */
+				goto end;
+				}
+			}
+		length-=len;
+		}
+	ret=1;
+end:
+	if (o != NULL) ASN1_OBJECT_free(o);
+	if (os != NULL) M_ASN1_OCTET_STRING_free(os);
+	*pp=p;
+	return(ret);
+	}
+
+const char *ASN1_tag2str(int tag)
+{
+	static const char * const tag2str[] = {
+	 "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
+	 "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
+	 "ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", 	    /* 10-13 */
+	"<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET", 		    /* 15-17 */
+	"NUMERICSTRING", "PRINTABLESTRING", "T61STRING",	    /* 18-20 */
+	"VIDEOTEXSTRING", "IA5STRING", "UTCTIME","GENERALIZEDTIME", /* 21-24 */
+	"GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING",	    /* 25-27 */
+	"UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING"		    /* 28-30 */
+	};
+
+	if((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
+							tag &= ~0x100;
+
+	if(tag < 0 || tag > 30) return "(unknown)";
+	return tag2str[tag];
+}
+
diff --git a/openssl/crypto/asn1/asn1t.h b/openssl/crypto/asn1/asn1t.h
new file mode 100644
index 0000000..d230e4b
--- /dev/null
+++ b/openssl/crypto/asn1/asn1t.h
@@ -0,0 +1,960 @@
+/* asn1t.h */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef HEADER_ASN1T_H
+#define HEADER_ASN1T_H
+
+#include <stddef.h>
+#include <openssl/e_os2.h>
+#include <openssl/asn1.h>
+
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+/* ASN1 template defines, structures and functions */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
+#define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr))
+
+
+/* Macros for start and end of ASN1_ITEM definition */
+
+#define ASN1_ITEM_start(itname) \
+	OPENSSL_GLOBAL const ASN1_ITEM itname##_it = {
+
+#define ASN1_ITEM_end(itname) \
+		};
+
+#else
+
+/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
+#define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr()))
+
+
+/* Macros for start and end of ASN1_ITEM definition */
+
+#define ASN1_ITEM_start(itname) \
+	const ASN1_ITEM * itname##_it(void) \
+	{ \
+		static const ASN1_ITEM local_it = { 
+
+#define ASN1_ITEM_end(itname) \
+		}; \
+	return &local_it; \
+	}
+
+#endif
+
+
+/* Macros to aid ASN1 template writing */
+
+#define ASN1_ITEM_TEMPLATE(tname) \
+	static const ASN1_TEMPLATE tname##_item_tt 
+
+#define ASN1_ITEM_TEMPLATE_END(tname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_PRIMITIVE,\
+		-1,\
+		&tname##_item_tt,\
+		0,\
+		NULL,\
+		0,\
+		#tname \
+	ASN1_ITEM_end(tname)
+
+
+/* This is a ASN1 type which just embeds a template */
+ 
+/* This pair helps declare a SEQUENCE. We can do:
+ *
+ * 	ASN1_SEQUENCE(stname) = {
+ * 		... SEQUENCE components ...
+ * 	} ASN1_SEQUENCE_END(stname)
+ *
+ * 	This will produce an ASN1_ITEM called stname_it
+ *	for a structure called stname.
+ *
+ * 	If you want the same structure but a different
+ *	name then use:
+ *
+ * 	ASN1_SEQUENCE(itname) = {
+ * 		... SEQUENCE components ...
+ * 	} ASN1_SEQUENCE_END_name(stname, itname)
+ *
+ *	This will create an item called itname_it using
+ *	a structure called stname.
+ */
+
+#define ASN1_SEQUENCE(tname) \
+	static const ASN1_TEMPLATE tname##_seq_tt[] 
+
+#define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)
+
+#define ASN1_SEQUENCE_END_name(stname, tname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_SEQUENCE,\
+		V_ASN1_SEQUENCE,\
+		tname##_seq_tt,\
+		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+		NULL,\
+		sizeof(stname),\
+		#stname \
+	ASN1_ITEM_end(tname)
+
+#define ASN1_NDEF_SEQUENCE(tname) \
+	ASN1_SEQUENCE(tname)
+
+#define ASN1_NDEF_SEQUENCE_cb(tname, cb) \
+	ASN1_SEQUENCE_cb(tname, cb)
+
+#define ASN1_SEQUENCE_cb(tname, cb) \
+	static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
+	ASN1_SEQUENCE(tname)
+
+#define ASN1_BROKEN_SEQUENCE(tname) \
+	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
+	ASN1_SEQUENCE(tname)
+
+#define ASN1_SEQUENCE_ref(tname, cb, lck) \
+	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \
+	ASN1_SEQUENCE(tname)
+
+#define ASN1_SEQUENCE_enc(tname, enc, cb) \
+	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
+	ASN1_SEQUENCE(tname)
+
+#define ASN1_NDEF_SEQUENCE_END(tname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_NDEF_SEQUENCE,\
+		V_ASN1_SEQUENCE,\
+		tname##_seq_tt,\
+		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+		NULL,\
+		sizeof(tname),\
+		#tname \
+	ASN1_ITEM_end(tname)
+
+#define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)
+
+#define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
+
+#define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
+
+#define ASN1_SEQUENCE_END_ref(stname, tname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_SEQUENCE,\
+		V_ASN1_SEQUENCE,\
+		tname##_seq_tt,\
+		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+		&tname##_aux,\
+		sizeof(stname),\
+		#stname \
+	ASN1_ITEM_end(tname)
+
+#define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_NDEF_SEQUENCE,\
+		V_ASN1_SEQUENCE,\
+		tname##_seq_tt,\
+		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+		&tname##_aux,\
+		sizeof(stname),\
+		#stname \
+	ASN1_ITEM_end(tname)
+
+
+/* This pair helps declare a CHOICE type. We can do:
+ *
+ * 	ASN1_CHOICE(chname) = {
+ * 		... CHOICE options ...
+ * 	ASN1_CHOICE_END(chname)
+ *
+ * 	This will produce an ASN1_ITEM called chname_it
+ *	for a structure called chname. The structure
+ *	definition must look like this:
+ *	typedef struct {
+ *		int type;
+ *		union {
+ *			ASN1_SOMETHING *opt1;
+ *			ASN1_SOMEOTHER *opt2;
+ *		} value;
+ *	} chname;
+ *	
+ *	the name of the selector must be 'type'.
+ * 	to use an alternative selector name use the
+ *      ASN1_CHOICE_END_selector() version.
+ */
+
+#define ASN1_CHOICE(tname) \
+	static const ASN1_TEMPLATE tname##_ch_tt[] 
+
+#define ASN1_CHOICE_cb(tname, cb) \
+	static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
+	ASN1_CHOICE(tname)
+
+#define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)
+
+#define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type)
+
+#define ASN1_CHOICE_END_selector(stname, tname, selname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_CHOICE,\
+		offsetof(stname,selname) ,\
+		tname##_ch_tt,\
+		sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
+		NULL,\
+		sizeof(stname),\
+		#stname \
+	ASN1_ITEM_end(tname)
+
+#define ASN1_CHOICE_END_cb(stname, tname, selname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_CHOICE,\
+		offsetof(stname,selname) ,\
+		tname##_ch_tt,\
+		sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
+		&tname##_aux,\
+		sizeof(stname),\
+		#stname \
+	ASN1_ITEM_end(tname)
+
+/* This helps with the template wrapper form of ASN1_ITEM */
+
+#define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \
+	(flags), (tag), 0,\
+	#name, ASN1_ITEM_ref(type) }
+
+/* These help with SEQUENCE or CHOICE components */
+
+/* used to declare other types */
+
+#define ASN1_EX_TYPE(flags, tag, stname, field, type) { \
+	(flags), (tag), offsetof(stname, field),\
+	#field, ASN1_ITEM_ref(type) }
+
+/* used when the structure is combined with the parent */
+
+#define ASN1_EX_COMBINE(flags, tag, type) { \
+	(flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) }
+
+/* implicit and explicit helper macros */
+
+#define ASN1_IMP_EX(stname, field, type, tag, ex) \
+		ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type)
+
+#define ASN1_EXP_EX(stname, field, type, tag, ex) \
+		ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type)
+
+/* Any defined by macros: the field used is in the table itself */
+
+#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+#define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
+#define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
+#else
+#define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb }
+#define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb }
+#endif
+/* Plain simple type */
+#define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)
+
+/* OPTIONAL simple type */
+#define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* IMPLICIT tagged simple type */
+#define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0)
+
+/* IMPLICIT tagged OPTIONAL simple type */
+#define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
+
+/* Same as above but EXPLICIT */
+
+#define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0)
+#define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
+
+/* SEQUENCE OF type */
+#define ASN1_SEQUENCE_OF(stname, field, type) \
+		ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type)
+
+/* OPTIONAL SEQUENCE OF */
+#define ASN1_SEQUENCE_OF_OPT(stname, field, type) \
+		ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* Same as above but for SET OF */
+
+#define ASN1_SET_OF(stname, field, type) \
+		ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type)
+
+#define ASN1_SET_OF_OPT(stname, field, type) \
+		ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */
+
+#define ASN1_IMP_SET_OF(stname, field, type, tag) \
+			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
+
+#define ASN1_EXP_SET_OF(stname, field, type, tag) \
+			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
+
+#define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \
+			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
+
+#define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \
+			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
+
+#define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \
+			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
+
+#define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \
+			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
+
+#define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \
+			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
+
+#define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
+			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
+
+/* EXPLICIT using indefinite length constructed form */
+#define ASN1_NDEF_EXP(stname, field, type, tag) \
+			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF)
+
+/* EXPLICIT OPTIONAL using indefinite length constructed form */
+#define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \
+			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF)
+
+/* Macros for the ASN1_ADB structure */
+
+#define ASN1_ADB(name) \
+	static const ASN1_ADB_TABLE name##_adbtbl[] 
+
+#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+#define ASN1_ADB_END(name, flags, field, app_table, def, none) \
+	;\
+	static const ASN1_ADB name##_adb = {\
+		flags,\
+		offsetof(name, field),\
+		app_table,\
+		name##_adbtbl,\
+		sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
+		def,\
+		none\
+	}
+
+#else
+
+#define ASN1_ADB_END(name, flags, field, app_table, def, none) \
+	;\
+	static const ASN1_ITEM *name##_adb(void) \
+	{ \
+	static const ASN1_ADB internal_adb = \
+		{\
+		flags,\
+		offsetof(name, field),\
+		app_table,\
+		name##_adbtbl,\
+		sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
+		def,\
+		none\
+		}; \
+		return (const ASN1_ITEM *) &internal_adb; \
+	} \
+	void dummy_function(void)
+
+#endif
+
+#define ADB_ENTRY(val, template) {val, template}
+
+#define ASN1_ADB_TEMPLATE(name) \
+	static const ASN1_TEMPLATE name##_tt 
+
+/* This is the ASN1 template structure that defines
+ * a wrapper round the actual type. It determines the
+ * actual position of the field in the value structure,
+ * various flags such as OPTIONAL and the field name.
+ */
+
+struct ASN1_TEMPLATE_st {
+unsigned long flags;		/* Various flags */
+long tag;			/* tag, not used if no tagging */
+unsigned long offset;		/* Offset of this field in structure */
+#ifndef NO_ASN1_FIELD_NAMES
+const char *field_name;		/* Field name */
+#endif
+ASN1_ITEM_EXP *item;		/* Relevant ASN1_ITEM or ASN1_ADB */
+};
+
+/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */
+
+#define ASN1_TEMPLATE_item(t) (t->item_ptr)
+#define ASN1_TEMPLATE_adb(t) (t->item_ptr)
+
+typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;
+typedef struct ASN1_ADB_st ASN1_ADB;
+
+struct ASN1_ADB_st {
+	unsigned long flags;	/* Various flags */
+	unsigned long offset;	/* Offset of selector field */
+	STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */
+	const ASN1_ADB_TABLE *tbl;	/* Table of possible types */
+	long tblcount;		/* Number of entries in tbl */
+	const ASN1_TEMPLATE *default_tt;  /* Type to use if no match */
+	const ASN1_TEMPLATE *null_tt;  /* Type to use if selector is NULL */
+};
+
+struct ASN1_ADB_TABLE_st {
+	long value;		/* NID for an object or value for an int */
+	const ASN1_TEMPLATE tt;		/* item for this value */
+};
+
+/* template flags */
+
+/* Field is optional */
+#define ASN1_TFLG_OPTIONAL	(0x1)
+
+/* Field is a SET OF */
+#define ASN1_TFLG_SET_OF	(0x1 << 1)
+
+/* Field is a SEQUENCE OF */
+#define ASN1_TFLG_SEQUENCE_OF	(0x2 << 1)
+
+/* Special case: this refers to a SET OF that
+ * will be sorted into DER order when encoded *and*
+ * the corresponding STACK will be modified to match
+ * the new order.
+ */
+#define ASN1_TFLG_SET_ORDER	(0x3 << 1)
+
+/* Mask for SET OF or SEQUENCE OF */
+#define ASN1_TFLG_SK_MASK	(0x3 << 1)
+
+/* These flags mean the tag should be taken from the
+ * tag field. If EXPLICIT then the underlying type
+ * is used for the inner tag.
+ */
+
+/* IMPLICIT tagging */
+#define ASN1_TFLG_IMPTAG	(0x1 << 3)
+
+
+/* EXPLICIT tagging, inner tag from underlying type */
+#define ASN1_TFLG_EXPTAG	(0x2 << 3)
+
+#define ASN1_TFLG_TAG_MASK	(0x3 << 3)
+
+/* context specific IMPLICIT */
+#define ASN1_TFLG_IMPLICIT	ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT
+
+/* context specific EXPLICIT */
+#define ASN1_TFLG_EXPLICIT	ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT
+
+/* If tagging is in force these determine the
+ * type of tag to use. Otherwise the tag is
+ * determined by the underlying type. These 
+ * values reflect the actual octet format.
+ */
+
+/* Universal tag */ 
+#define ASN1_TFLG_UNIVERSAL	(0x0<<6)
+/* Application tag */ 
+#define ASN1_TFLG_APPLICATION	(0x1<<6)
+/* Context specific tag */ 
+#define ASN1_TFLG_CONTEXT	(0x2<<6)
+/* Private tag */ 
+#define ASN1_TFLG_PRIVATE	(0x3<<6)
+
+#define ASN1_TFLG_TAG_CLASS	(0x3<<6)
+
+/* These are for ANY DEFINED BY type. In this case
+ * the 'item' field points to an ASN1_ADB structure
+ * which contains a table of values to decode the
+ * relevant type
+ */
+
+#define ASN1_TFLG_ADB_MASK	(0x3<<8)
+
+#define ASN1_TFLG_ADB_OID	(0x1<<8)
+
+#define ASN1_TFLG_ADB_INT	(0x1<<9)
+
+/* This flag means a parent structure is passed
+ * instead of the field: this is useful is a
+ * SEQUENCE is being combined with a CHOICE for
+ * example. Since this means the structure and
+ * item name will differ we need to use the
+ * ASN1_CHOICE_END_name() macro for example.
+ */
+
+#define ASN1_TFLG_COMBINE	(0x1<<10)
+
+/* This flag when present in a SEQUENCE OF, SET OF
+ * or EXPLICIT causes indefinite length constructed
+ * encoding to be used if required.
+ */
+
+#define ASN1_TFLG_NDEF		(0x1<<11)
+
+/* This is the actual ASN1 item itself */
+
+struct ASN1_ITEM_st {
+char itype;			/* The item type, primitive, SEQUENCE, CHOICE or extern */
+long utype;			/* underlying type */
+const ASN1_TEMPLATE *templates;	/* If SEQUENCE or CHOICE this contains the contents */
+long tcount;			/* Number of templates if SEQUENCE or CHOICE */
+const void *funcs;		/* functions that handle this type */
+long size;			/* Structure size (usually)*/
+#ifndef NO_ASN1_FIELD_NAMES
+const char *sname;		/* Structure name */
+#endif
+};
+
+/* These are values for the itype field and
+ * determine how the type is interpreted.
+ *
+ * For PRIMITIVE types the underlying type
+ * determines the behaviour if items is NULL.
+ *
+ * Otherwise templates must contain a single 
+ * template and the type is treated in the
+ * same way as the type specified in the template.
+ *
+ * For SEQUENCE types the templates field points
+ * to the members, the size field is the
+ * structure size.
+ *
+ * For CHOICE types the templates field points
+ * to each possible member (typically a union)
+ * and the 'size' field is the offset of the
+ * selector.
+ *
+ * The 'funcs' field is used for application
+ * specific functions. 
+ *
+ * For COMPAT types the funcs field gives a
+ * set of functions that handle this type, this
+ * supports the old d2i, i2d convention.
+ *
+ * The EXTERN type uses a new style d2i/i2d.
+ * The new style should be used where possible
+ * because it avoids things like the d2i IMPLICIT
+ * hack.
+ *
+ * MSTRING is a multiple string type, it is used
+ * for a CHOICE of character strings where the
+ * actual strings all occupy an ASN1_STRING
+ * structure. In this case the 'utype' field
+ * has a special meaning, it is used as a mask
+ * of acceptable types using the B_ASN1 constants.
+ *
+ * NDEF_SEQUENCE is the same as SEQUENCE except
+ * that it will use indefinite length constructed
+ * encoding if requested.
+ *
+ */
+
+#define ASN1_ITYPE_PRIMITIVE		0x0
+
+#define ASN1_ITYPE_SEQUENCE		0x1
+
+#define ASN1_ITYPE_CHOICE		0x2
+
+#define ASN1_ITYPE_COMPAT		0x3
+
+#define ASN1_ITYPE_EXTERN		0x4
+
+#define ASN1_ITYPE_MSTRING		0x5
+
+#define ASN1_ITYPE_NDEF_SEQUENCE	0x6
+
+/* Cache for ASN1 tag and length, so we
+ * don't keep re-reading it for things
+ * like CHOICE
+ */
+
+struct ASN1_TLC_st{
+	char valid;	/* Values below are valid */
+	int ret;	/* return value */
+	long plen;	/* length */
+	int ptag;	/* class value */
+	int pclass;	/* class value */
+	int hdrlen;	/* header length */
+};
+
+/* Typedefs for ASN1 function pointers */
+
+typedef ASN1_VALUE * ASN1_new_func(void);
+typedef void ASN1_free_func(ASN1_VALUE *a);
+typedef ASN1_VALUE * ASN1_d2i_func(ASN1_VALUE **a, const unsigned char ** in, long length);
+typedef int ASN1_i2d_func(ASN1_VALUE * a, unsigned char **in);
+
+typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it,
+					int tag, int aclass, char opt, ASN1_TLC *ctx);
+
+typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
+typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
+typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval, 
+						int indent, const char *fname, 
+						const ASN1_PCTX *pctx);
+
+typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
+typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
+typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
+
+typedef struct ASN1_COMPAT_FUNCS_st {
+	ASN1_new_func *asn1_new;
+	ASN1_free_func *asn1_free;
+	ASN1_d2i_func *asn1_d2i;
+	ASN1_i2d_func *asn1_i2d;
+} ASN1_COMPAT_FUNCS;
+
+typedef struct ASN1_EXTERN_FUNCS_st {
+	void *app_data;
+	ASN1_ex_new_func *asn1_ex_new;
+	ASN1_ex_free_func *asn1_ex_free;
+	ASN1_ex_free_func *asn1_ex_clear;
+	ASN1_ex_d2i *asn1_ex_d2i;
+	ASN1_ex_i2d *asn1_ex_i2d;
+	ASN1_ex_print_func *asn1_ex_print;
+} ASN1_EXTERN_FUNCS;
+
+typedef struct ASN1_PRIMITIVE_FUNCS_st {
+	void *app_data;
+	unsigned long flags;
+	ASN1_ex_new_func *prim_new;
+	ASN1_ex_free_func *prim_free;
+	ASN1_ex_free_func *prim_clear;
+	ASN1_primitive_c2i *prim_c2i;
+	ASN1_primitive_i2c *prim_i2c;
+	ASN1_primitive_print *prim_print;
+} ASN1_PRIMITIVE_FUNCS;
+
+/* This is the ASN1_AUX structure: it handles various
+ * miscellaneous requirements. For example the use of
+ * reference counts and an informational callback.
+ *
+ * The "informational callback" is called at various
+ * points during the ASN1 encoding and decoding. It can
+ * be used to provide minor customisation of the structures
+ * used. This is most useful where the supplied routines
+ * *almost* do the right thing but need some extra help
+ * at a few points. If the callback returns zero then
+ * it is assumed a fatal error has occurred and the 
+ * main operation should be abandoned.
+ *
+ * If major changes in the default behaviour are required
+ * then an external type is more appropriate.
+ */
+
+typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it,
+				void *exarg);
+
+typedef struct ASN1_AUX_st {
+	void *app_data;
+	int flags;
+	int ref_offset;		/* Offset of reference value */
+	int ref_lock;		/* Lock type to use */
+	ASN1_aux_cb *asn1_cb;
+	int enc_offset;		/* Offset of ASN1_ENCODING structure */
+} ASN1_AUX;
+
+/* For print related callbacks exarg points to this structure */
+typedef struct ASN1_PRINT_ARG_st {
+	BIO *out;
+	int indent;
+	const ASN1_PCTX *pctx;
+} ASN1_PRINT_ARG;
+
+/* For streaming related callbacks exarg points to this structure */
+typedef struct ASN1_STREAM_ARG_st {
+	/* BIO to stream through */
+	BIO *out;
+	/* BIO with filters appended */
+	BIO *ndef_bio;
+	/* Streaming I/O boundary */
+	unsigned char **boundary;
+} ASN1_STREAM_ARG;
+
+/* Flags in ASN1_AUX */
+
+/* Use a reference count */
+#define ASN1_AFLG_REFCOUNT	1
+/* Save the encoding of structure (useful for signatures) */
+#define ASN1_AFLG_ENCODING	2
+/* The Sequence length is invalid */
+#define ASN1_AFLG_BROKEN	4
+
+/* operation values for asn1_cb */
+
+#define ASN1_OP_NEW_PRE		0
+#define ASN1_OP_NEW_POST	1
+#define ASN1_OP_FREE_PRE	2
+#define ASN1_OP_FREE_POST	3
+#define ASN1_OP_D2I_PRE		4
+#define ASN1_OP_D2I_POST	5
+#define ASN1_OP_I2D_PRE		6
+#define ASN1_OP_I2D_POST	7
+#define ASN1_OP_PRINT_PRE	8
+#define ASN1_OP_PRINT_POST	9
+#define ASN1_OP_STREAM_PRE	10
+#define ASN1_OP_STREAM_POST	11
+#define ASN1_OP_DETACHED_PRE	12
+#define ASN1_OP_DETACHED_POST	13
+
+/* Macro to implement a primitive type */
+#define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)
+#define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \
+				ASN1_ITEM_start(itname) \
+					ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \
+				ASN1_ITEM_end(itname)
+
+/* Macro to implement a multi string type */
+#define IMPLEMENT_ASN1_MSTRING(itname, mask) \
+				ASN1_ITEM_start(itname) \
+					ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \
+				ASN1_ITEM_end(itname)
+
+/* Macro to implement an ASN1_ITEM in terms of old style funcs */
+
+#define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE)
+
+#define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \
+	static const ASN1_COMPAT_FUNCS sname##_ff = { \
+		(ASN1_new_func *)sname##_new, \
+		(ASN1_free_func *)sname##_free, \
+		(ASN1_d2i_func *)d2i_##sname, \
+		(ASN1_i2d_func *)i2d_##sname, \
+	}; \
+	ASN1_ITEM_start(sname) \
+		ASN1_ITYPE_COMPAT, \
+		tag, \
+		NULL, \
+		0, \
+		&sname##_ff, \
+		0, \
+		#sname \
+	ASN1_ITEM_end(sname)
+
+#define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \
+	ASN1_ITEM_start(sname) \
+		ASN1_ITYPE_EXTERN, \
+		tag, \
+		NULL, \
+		0, \
+		&fptrs, \
+		0, \
+		#sname \
+	ASN1_ITEM_end(sname)
+
+/* Macro to implement standard functions in terms of ASN1_ITEM structures */
+
+#define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)
+
+#define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname)
+
+#define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
+			IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)
+
+#define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \
+		IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname)
+
+#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \
+		IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)
+
+#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \
+	pre stname *fname##_new(void) \
+	{ \
+		return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
+	} \
+	pre void fname##_free(stname *a) \
+	{ \
+		ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
+	}
+
+#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \
+	stname *fname##_new(void) \
+	{ \
+		return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
+	} \
+	void fname##_free(stname *a) \
+	{ \
+		ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
+	}
+
+#define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \
+	IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
+	IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
+
+#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
+	stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
+	{ \
+		return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
+	} \
+	int i2d_##fname(stname *a, unsigned char **out) \
+	{ \
+		return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
+	} 
+
+#define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \
+	int i2d_##stname##_NDEF(stname *a, unsigned char **out) \
+	{ \
+		return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\
+	} 
+
+/* This includes evil casts to remove const: they will go away when full
+ * ASN1 constification is done.
+ */
+#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
+	stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
+	{ \
+		return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
+	} \
+	int i2d_##fname(const stname *a, unsigned char **out) \
+	{ \
+		return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
+	} 
+
+#define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \
+	stname * stname##_dup(stname *x) \
+        { \
+        return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
+        }
+
+#define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \
+	IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname)
+
+#define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \
+	int fname##_print_ctx(BIO *out, stname *x, int indent, \
+						const ASN1_PCTX *pctx) \
+	{ \
+		return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \
+			ASN1_ITEM_rptr(itname), pctx); \
+	} 
+
+#define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
+		IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)
+
+#define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \
+	IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
+	IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
+
+/* external definitions for primitive types */
+
+DECLARE_ASN1_ITEM(ASN1_BOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_TBOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_FBOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_SEQUENCE)
+DECLARE_ASN1_ITEM(CBIGNUM)
+DECLARE_ASN1_ITEM(BIGNUM)
+DECLARE_ASN1_ITEM(LONG)
+DECLARE_ASN1_ITEM(ZLONG)
+
+DECLARE_STACK_OF(ASN1_VALUE)
+
+/* Functions used internally by the ASN1 code */
+
+int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt);
+int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it,
+				int tag, int aclass, char opt, ASN1_TLC *ctx);
+
+int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
+int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt);
+void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
+int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
+
+int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it);
+
+ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+
+const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr);
+
+int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
+
+void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
+void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, const ASN1_ITEM *it);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/asn1/asn_mime.c b/openssl/crypto/asn1/asn_mime.c
new file mode 100644
index 0000000..c1d1b12
--- /dev/null
+++ b/openssl/crypto/asn1/asn_mime.c
@@ -0,0 +1,942 @@
+/* asn_mime.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include "asn1_locl.h"
+
+/* Generalised MIME like utilities for streaming ASN1. Although many
+ * have a PKCS7/CMS like flavour others are more general purpose.
+ */
+
+/* MIME format structures
+ * Note that all are translated to lower case apart from
+ * parameter values. Quotes are stripped off
+ */
+
+typedef struct {
+char *param_name;			/* Param name e.g. "micalg" */
+char *param_value;			/* Param value e.g. "sha1" */
+} MIME_PARAM;
+
+DECLARE_STACK_OF(MIME_PARAM)
+IMPLEMENT_STACK_OF(MIME_PARAM)
+
+typedef struct {
+char *name;				/* Name of line e.g. "content-type" */
+char *value;				/* Value of line e.g. "text/plain" */
+STACK_OF(MIME_PARAM) *params;		/* Zero or more parameters */
+} MIME_HEADER;
+
+DECLARE_STACK_OF(MIME_HEADER)
+IMPLEMENT_STACK_OF(MIME_HEADER)
+
+static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
+					const ASN1_ITEM *it);
+static char * strip_ends(char *name);
+static char * strip_start(char *name);
+static char * strip_end(char *name);
+static MIME_HEADER *mime_hdr_new(char *name, char *value);
+static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value);
+static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio);
+static int mime_hdr_cmp(const MIME_HEADER * const *a,
+			const MIME_HEADER * const *b);
+static int mime_param_cmp(const MIME_PARAM * const *a,
+			const MIME_PARAM * const *b);
+static void mime_param_free(MIME_PARAM *param);
+static int mime_bound_check(char *line, int linelen, char *bound, int blen);
+static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret);
+static int strip_eol(char *linebuf, int *plen);
+static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
+static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
+static void mime_hdr_free(MIME_HEADER *hdr);
+
+#define MAX_SMLEN 1024
+#define mime_debug(x) /* x */
+
+/* Output an ASN1 structure in BER format streaming if necessary */
+
+int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+				const ASN1_ITEM *it)
+	{
+	/* If streaming create stream BIO and copy all content through it */
+	if (flags & SMIME_STREAM)
+		{
+		BIO *bio, *tbio;
+		bio = BIO_new_NDEF(out, val, it);
+		if (!bio)
+			{
+			ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM,ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		SMIME_crlf_copy(in, bio, flags);
+		(void)BIO_flush(bio);
+		/* Free up successive BIOs until we hit the old output BIO */
+		do
+			{
+			tbio = BIO_pop(bio);
+			BIO_free(bio);
+			bio = tbio;
+			} while (bio != out);
+		}
+	/* else just write out ASN1 structure which will have all content
+	 * stored internally
+	 */
+	else
+		ASN1_item_i2d_bio(it, out, val);
+	return 1;
+	}
+
+/* Base 64 read and write of ASN1 structure */
+
+static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+				const ASN1_ITEM *it)
+	{
+	BIO *b64;
+	int r;
+	b64 = BIO_new(BIO_f_base64());
+	if(!b64)
+		{
+		ASN1err(ASN1_F_B64_WRITE_ASN1,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	/* prepend the b64 BIO so all data is base64 encoded.
+	 */
+	out = BIO_push(b64, out);
+	r = i2d_ASN1_bio_stream(out, val, in, flags, it);
+	(void)BIO_flush(out);
+	BIO_pop(out);
+	BIO_free(b64);
+	return r;
+	}
+
+/* Streaming ASN1 PEM write */
+
+int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+				const char *hdr,
+				const ASN1_ITEM *it)
+	{
+	int r;
+	BIO_printf(out, "-----BEGIN %s-----\n", hdr);
+	r = B64_write_ASN1(out, val, in, flags, it);
+	BIO_printf(out, "-----END %s-----\n", hdr);
+	return r;
+	}
+
+static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
+{
+	BIO *b64;
+	ASN1_VALUE *val;
+	if(!(b64 = BIO_new(BIO_f_base64()))) {
+		ASN1err(ASN1_F_B64_READ_ASN1,ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	bio = BIO_push(b64, bio);
+	val = ASN1_item_d2i_bio(it, bio, NULL);
+	if(!val)
+		ASN1err(ASN1_F_B64_READ_ASN1,ASN1_R_DECODE_ERROR);
+	(void)BIO_flush(bio);
+	bio = BIO_pop(bio);
+	BIO_free(b64);
+	return val;
+}
+
+/* Generate the MIME "micalg" parameter from RFC3851, RFC4490 */
+
+static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
+	{
+	const EVP_MD *md;
+	int i, have_unknown = 0, write_comma, ret = 0, md_nid;
+	have_unknown = 0;
+	write_comma = 0;
+	for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++)
+		{
+		if (write_comma)
+			BIO_write(out, ",", 1);
+		write_comma = 1;
+		md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm);
+		md = EVP_get_digestbynid(md_nid);
+		if (md && md->md_ctrl)
+			{
+			int rv;
+			char *micstr;
+			rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr);
+			if (rv > 0)
+				{
+				BIO_puts(out, micstr);
+				OPENSSL_free(micstr);
+				continue;
+				}
+			if (rv != -2)
+				goto err;
+			}
+		switch(md_nid)
+			{
+			case NID_sha1:
+			BIO_puts(out, "sha1");
+			break;
+
+			case NID_md5:
+			BIO_puts(out, "md5");
+			break;
+
+			case NID_sha256:
+			BIO_puts(out, "sha-256");
+			break;
+
+			case NID_sha384:
+			BIO_puts(out, "sha-384");
+			break;
+
+			case NID_sha512:
+			BIO_puts(out, "sha-512");
+			break;
+
+			case NID_id_GostR3411_94:
+			BIO_puts(out, "gostr3411-94");
+				goto err;
+			break;
+
+			default:
+			if (have_unknown)
+				write_comma = 0;
+			else
+				{
+				BIO_puts(out, "unknown");
+				have_unknown = 1;
+				}
+			break;
+
+			}
+		}
+
+	ret = 1;
+	err:
+
+	return ret;
+
+	}
+
+/* SMIME sender */
+
+int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
+				int ctype_nid, int econt_nid,
+				STACK_OF(X509_ALGOR) *mdalgs,
+				const ASN1_ITEM *it)
+{
+	char bound[33], c;
+	int i;
+	const char *mime_prefix, *mime_eol, *cname = "smime.p7m";
+	const char *msg_type=NULL;
+	if (flags & SMIME_OLDMIME)
+		mime_prefix = "application/x-pkcs7-";
+	else
+		mime_prefix = "application/pkcs7-";
+
+	if (flags & SMIME_CRLFEOL)
+		mime_eol = "\r\n";
+	else
+		mime_eol = "\n";
+	if((flags & SMIME_DETACHED) && data) {
+	/* We want multipart/signed */
+		/* Generate a random boundary */
+		RAND_pseudo_bytes((unsigned char *)bound, 32);
+		for(i = 0; i < 32; i++) {
+			c = bound[i] & 0xf;
+			if(c < 10) c += '0';
+			else c += 'A' - 10;
+			bound[i] = c;
+		}
+		bound[32] = 0;
+		BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
+		BIO_printf(bio, "Content-Type: multipart/signed;");
+		BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix);
+		BIO_puts(bio, " micalg=\"");
+		asn1_write_micalg(bio, mdalgs);
+		BIO_printf(bio, "\"; boundary=\"----%s\"%s%s",
+						bound, mime_eol, mime_eol);
+		BIO_printf(bio, "This is an S/MIME signed message%s%s",
+						mime_eol, mime_eol);
+		/* Now write out the first part */
+		BIO_printf(bio, "------%s%s", bound, mime_eol);
+		if (!asn1_output_data(bio, data, val, flags, it))
+			return 0;
+		BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
+
+		/* Headers for signature */
+
+		BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix); 
+		BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol);
+		BIO_printf(bio, "Content-Transfer-Encoding: base64%s",
+								mime_eol);
+		BIO_printf(bio, "Content-Disposition: attachment;");
+		BIO_printf(bio, " filename=\"smime.p7s\"%s%s",
+							mime_eol, mime_eol);
+		B64_write_ASN1(bio, val, NULL, 0, it);
+		BIO_printf(bio,"%s------%s--%s%s", mime_eol, bound,
+							mime_eol, mime_eol);
+		return 1;
+	}
+
+	/* Determine smime-type header */
+
+	if (ctype_nid == NID_pkcs7_enveloped)
+		msg_type = "enveloped-data";
+	else if (ctype_nid == NID_pkcs7_signed)
+		{
+		if (econt_nid == NID_id_smime_ct_receipt)
+			msg_type = "signed-receipt";
+		else if (sk_X509_ALGOR_num(mdalgs) >= 0)
+			msg_type = "signed-data";
+		else
+			msg_type = "certs-only";
+		}
+	else if (ctype_nid == NID_id_smime_ct_compressedData)
+		{
+		msg_type = "compressed-data";
+		cname = "smime.p7z";
+		}
+	/* MIME headers */
+	BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
+	BIO_printf(bio, "Content-Disposition: attachment;");
+	BIO_printf(bio, " filename=\"%s\"%s", cname, mime_eol);
+	BIO_printf(bio, "Content-Type: %smime;", mime_prefix);
+	if (msg_type)
+		BIO_printf(bio, " smime-type=%s;", msg_type);
+	BIO_printf(bio, " name=\"%s\"%s", cname, mime_eol);
+	BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s",
+						mime_eol, mime_eol);
+	if (!B64_write_ASN1(bio, val, data, flags, it))
+		return 0;
+	BIO_printf(bio, "%s", mime_eol);
+	return 1;
+}
+
+/* Handle output of ASN1 data */
+
+
+static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
+					const ASN1_ITEM *it)
+	{
+	BIO *tmpbio;
+	const ASN1_AUX *aux = it->funcs;
+	ASN1_STREAM_ARG sarg;
+
+	if (!(flags & SMIME_DETACHED))
+		{
+		SMIME_crlf_copy(data, out, flags);
+		return 1;
+		}
+
+	if (!aux || !aux->asn1_cb)
+		{
+		ASN1err(ASN1_F_ASN1_OUTPUT_DATA,
+					ASN1_R_STREAMING_NOT_SUPPORTED);
+		return 0;
+		}
+
+	sarg.out = out;
+	sarg.ndef_bio = NULL;
+	sarg.boundary = NULL;
+
+	/* Let ASN1 code prepend any needed BIOs */
+
+	if (aux->asn1_cb(ASN1_OP_DETACHED_PRE, &val, it, &sarg) <= 0)
+		return 0;
+
+	/* Copy data across, passing through filter BIOs for processing */
+	SMIME_crlf_copy(data, sarg.ndef_bio, flags);
+
+	/* Finalize structure */
+	if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0)
+		return 0;
+
+	/* Now remove any digests prepended to the BIO */
+
+	while (sarg.ndef_bio != out)
+		{
+		tmpbio = BIO_pop(sarg.ndef_bio);
+		BIO_free(sarg.ndef_bio);
+		sarg.ndef_bio = tmpbio;
+		}
+
+	return 1;
+
+	}
+
+/* SMIME reader: handle multipart/signed and opaque signing.
+ * in multipart case the content is placed in a memory BIO
+ * pointed to by "bcont". In opaque this is set to NULL
+ */
+
+ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
+{
+	BIO *asnin;
+	STACK_OF(MIME_HEADER) *headers = NULL;
+	STACK_OF(BIO) *parts = NULL;
+	MIME_HEADER *hdr;
+	MIME_PARAM *prm;
+	ASN1_VALUE *val;
+	int ret;
+
+	if(bcont) *bcont = NULL;
+
+	if (!(headers = mime_parse_hdr(bio))) {
+		ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_MIME_PARSE_ERROR);
+		return NULL;
+	}
+
+	if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
+		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+		ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE);
+		return NULL;
+	}
+
+	/* Handle multipart/signed */
+
+	if(!strcmp(hdr->value, "multipart/signed")) {
+		/* Split into two parts */
+		prm = mime_param_find(hdr, "boundary");
+		if(!prm || !prm->param_value) {
+			sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+			ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY);
+			return NULL;
+		}
+		ret = multi_split(bio, prm->param_value, &parts);
+		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+		if(!ret || (sk_BIO_num(parts) != 2) ) {
+			ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE);
+			sk_BIO_pop_free(parts, BIO_vfree);
+			return NULL;
+		}
+
+		/* Parse the signature piece */
+		asnin = sk_BIO_value(parts, 1);
+
+		if (!(headers = mime_parse_hdr(asnin))) {
+			ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_MIME_SIG_PARSE_ERROR);
+			sk_BIO_pop_free(parts, BIO_vfree);
+			return NULL;
+		}
+
+		/* Get content type */
+
+		if(!(hdr = mime_hdr_find(headers, "content-type")) ||
+								 !hdr->value) {
+			sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+			ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE);
+			return NULL;
+		}
+
+		if(strcmp(hdr->value, "application/x-pkcs7-signature") &&
+			strcmp(hdr->value, "application/pkcs7-signature")) {
+			sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+			ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_SIG_INVALID_MIME_TYPE);
+			ERR_add_error_data(2, "type: ", hdr->value);
+			sk_BIO_pop_free(parts, BIO_vfree);
+			return NULL;
+		}
+		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+		/* Read in ASN1 */
+		if(!(val = b64_read_asn1(asnin, it))) {
+			ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_ASN1_SIG_PARSE_ERROR);
+			sk_BIO_pop_free(parts, BIO_vfree);
+			return NULL;
+		}
+
+		if(bcont) {
+			*bcont = sk_BIO_value(parts, 0);
+			BIO_free(asnin);
+			sk_BIO_free(parts);
+		} else sk_BIO_pop_free(parts, BIO_vfree);
+		return val;
+	}
+		
+	/* OK, if not multipart/signed try opaque signature */
+
+	if (strcmp (hdr->value, "application/x-pkcs7-mime") &&
+	    strcmp (hdr->value, "application/pkcs7-mime")) {
+		ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_INVALID_MIME_TYPE);
+		ERR_add_error_data(2, "type: ", hdr->value);
+		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+		return NULL;
+	}
+
+	sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+	
+	if(!(val = b64_read_asn1(bio, it))) {
+		ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR);
+		return NULL;
+	}
+	return val;
+
+}
+
+/* Copy text from one BIO to another making the output CRLF at EOL */
+int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
+{
+	BIO *bf;
+	char eol;
+	int len;
+	char linebuf[MAX_SMLEN];
+	/* Buffer output so we don't write one line at a time. This is
+	 * useful when streaming as we don't end up with one OCTET STRING
+	 * per line.
+	 */
+	bf = BIO_new(BIO_f_buffer());
+	if (!bf)
+		return 0;
+	out = BIO_push(bf, out);
+	if(flags & SMIME_BINARY)
+		{
+		while((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
+						BIO_write(out, linebuf, len);
+		}
+	else
+		{
+		if(flags & SMIME_TEXT)
+			BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
+		while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0)
+			{
+			eol = strip_eol(linebuf, &len);
+			if (len)
+				BIO_write(out, linebuf, len);
+			if(eol) BIO_write(out, "\r\n", 2);
+			}
+		}
+	(void)BIO_flush(out);
+	BIO_pop(out);
+	BIO_free(bf);
+	return 1;
+}
+
+/* Strip off headers if they are text/plain */
+int SMIME_text(BIO *in, BIO *out)
+{
+	char iobuf[4096];
+	int len;
+	STACK_OF(MIME_HEADER) *headers;
+	MIME_HEADER *hdr;
+
+	if (!(headers = mime_parse_hdr(in))) {
+		ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_MIME_PARSE_ERROR);
+		return 0;
+	}
+	if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
+		ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_MIME_NO_CONTENT_TYPE);
+		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+		return 0;
+	}
+	if (strcmp (hdr->value, "text/plain")) {
+		ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_INVALID_MIME_TYPE);
+		ERR_add_error_data(2, "type: ", hdr->value);
+		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+		return 0;
+	}
+	sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+	while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
+						BIO_write(out, iobuf, len);
+	if (len < 0)
+		return 0;
+	return 1;
+}
+
+/* Split a multipart/XXX message body into component parts: result is
+ * canonical parts in a STACK of bios
+ */
+
+static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
+{
+	char linebuf[MAX_SMLEN];
+	int len, blen;
+	int eol = 0, next_eol = 0;
+	BIO *bpart = NULL;
+	STACK_OF(BIO) *parts;
+	char state, part, first;
+
+	blen = strlen(bound);
+	part = 0;
+	state = 0;
+	first = 1;
+	parts = sk_BIO_new_null();
+	*ret = parts;
+	while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
+		state = mime_bound_check(linebuf, len, bound, blen);
+		if(state == 1) {
+			first = 1;
+			part++;
+		} else if(state == 2) {
+			sk_BIO_push(parts, bpart);
+			return 1;
+		} else if(part) {
+			/* Strip CR+LF from linebuf */
+			next_eol = strip_eol(linebuf, &len);
+			if(first) {
+				first = 0;
+				if(bpart) sk_BIO_push(parts, bpart);
+				bpart = BIO_new(BIO_s_mem());
+				BIO_set_mem_eof_return(bpart, 0);
+			} else if (eol)
+				BIO_write(bpart, "\r\n", 2);
+			eol = next_eol;
+			if (len)
+				BIO_write(bpart, linebuf, len);
+		}
+	}
+	return 0;
+}
+
+/* This is the big one: parse MIME header lines up to message body */
+
+#define MIME_INVALID	0
+#define MIME_START	1
+#define MIME_TYPE	2
+#define MIME_NAME	3
+#define MIME_VALUE	4
+#define MIME_QUOTE	5
+#define MIME_COMMENT	6
+
+
+static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
+{
+	char *p, *q, c;
+	char *ntmp;
+	char linebuf[MAX_SMLEN];
+	MIME_HEADER *mhdr = NULL;
+	STACK_OF(MIME_HEADER) *headers;
+	int len, state, save_state = 0;
+
+	headers = sk_MIME_HEADER_new(mime_hdr_cmp);
+	while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
+	/* If whitespace at line start then continuation line */
+	if(mhdr && isspace((unsigned char)linebuf[0])) state = MIME_NAME;
+	else state = MIME_START;
+	ntmp = NULL;
+	/* Go through all characters */
+	for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) {
+
+	/* State machine to handle MIME headers
+	 * if this looks horrible that's because it *is*
+         */
+
+		switch(state) {
+			case MIME_START:
+			if(c == ':') {
+				state = MIME_TYPE;
+				*p = 0;
+				ntmp = strip_ends(q);
+				q = p + 1;
+			}
+			break;
+
+			case MIME_TYPE:
+			if(c == ';') {
+				mime_debug("Found End Value\n");
+				*p = 0;
+				mhdr = mime_hdr_new(ntmp, strip_ends(q));
+				sk_MIME_HEADER_push(headers, mhdr);
+				ntmp = NULL;
+				q = p + 1;
+				state = MIME_NAME;
+			} else if(c == '(') {
+				save_state = state;
+				state = MIME_COMMENT;
+			}
+			break;
+
+			case MIME_COMMENT:
+			if(c == ')') {
+				state = save_state;
+			}
+			break;
+
+			case MIME_NAME:
+			if(c == '=') {
+				state = MIME_VALUE;
+				*p = 0;
+				ntmp = strip_ends(q);
+				q = p + 1;
+			}
+			break ;
+
+			case MIME_VALUE:
+			if(c == ';') {
+				state = MIME_NAME;
+				*p = 0;
+				mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
+				ntmp = NULL;
+				q = p + 1;
+			} else if (c == '"') {
+				mime_debug("Found Quote\n");
+				state = MIME_QUOTE;
+			} else if(c == '(') {
+				save_state = state;
+				state = MIME_COMMENT;
+			}
+			break;
+
+			case MIME_QUOTE:
+			if(c == '"') {
+				mime_debug("Found Match Quote\n");
+				state = MIME_VALUE;
+			}
+			break;
+		}
+	}
+
+	if(state == MIME_TYPE) {
+		mhdr = mime_hdr_new(ntmp, strip_ends(q));
+		sk_MIME_HEADER_push(headers, mhdr);
+	} else if(state == MIME_VALUE)
+			 mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
+	if(p == linebuf) break;	/* Blank line means end of headers */
+}
+
+return headers;
+
+}
+
+static char *strip_ends(char *name)
+{
+	return strip_end(strip_start(name));
+}
+
+/* Strip a parameter of whitespace from start of param */
+static char *strip_start(char *name)
+{
+	char *p, c;
+	/* Look for first non white space or quote */
+	for(p = name; (c = *p) ;p++) {
+		if(c == '"') {
+			/* Next char is start of string if non null */
+			if(p[1]) return p + 1;
+			/* Else null string */
+			return NULL;
+		}
+		if(!isspace((unsigned char)c)) return p;
+	}
+	return NULL;
+}
+
+/* As above but strip from end of string : maybe should handle brackets? */
+static char *strip_end(char *name)
+{
+	char *p, c;
+	if(!name) return NULL;
+	/* Look for first non white space or quote */
+	for(p = name + strlen(name) - 1; p >= name ;p--) {
+		c = *p;
+		if(c == '"') {
+			if(p - 1 == name) return NULL;
+			*p = 0;
+			return name;
+		}
+		if(isspace((unsigned char)c)) *p = 0;	
+		else return name;
+	}
+	return NULL;
+}
+
+static MIME_HEADER *mime_hdr_new(char *name, char *value)
+{
+	MIME_HEADER *mhdr;
+	char *tmpname, *tmpval, *p;
+	int c;
+	if(name) {
+		if(!(tmpname = BUF_strdup(name))) return NULL;
+		for(p = tmpname ; *p; p++) {
+			c = *p;
+			if(isupper(c)) {
+				c = tolower(c);
+				*p = c;
+			}
+		}
+	} else tmpname = NULL;
+	if(value) {
+		if(!(tmpval = BUF_strdup(value))) return NULL;
+		for(p = tmpval ; *p; p++) {
+			c = *p;
+			if(isupper(c)) {
+				c = tolower(c);
+				*p = c;
+			}
+		}
+	} else tmpval = NULL;
+	mhdr = (MIME_HEADER *) OPENSSL_malloc(sizeof(MIME_HEADER));
+	if(!mhdr) return NULL;
+	mhdr->name = tmpname;
+	mhdr->value = tmpval;
+	if(!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) return NULL;
+	return mhdr;
+}
+		
+static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
+{
+	char *tmpname, *tmpval, *p;
+	int c;
+	MIME_PARAM *mparam;
+	if(name) {
+		tmpname = BUF_strdup(name);
+		if(!tmpname) return 0;
+		for(p = tmpname ; *p; p++) {
+			c = *p;
+			if(isupper(c)) {
+				c = tolower(c);
+				*p = c;
+			}
+		}
+	} else tmpname = NULL;
+	if(value) {
+		tmpval = BUF_strdup(value);
+		if(!tmpval) return 0;
+	} else tmpval = NULL;
+	/* Parameter values are case sensitive so leave as is */
+	mparam = (MIME_PARAM *) OPENSSL_malloc(sizeof(MIME_PARAM));
+	if(!mparam) return 0;
+	mparam->param_name = tmpname;
+	mparam->param_value = tmpval;
+	sk_MIME_PARAM_push(mhdr->params, mparam);
+	return 1;
+}
+
+static int mime_hdr_cmp(const MIME_HEADER * const *a,
+			const MIME_HEADER * const *b)
+{
+	return(strcmp((*a)->name, (*b)->name));
+}
+
+static int mime_param_cmp(const MIME_PARAM * const *a,
+			const MIME_PARAM * const *b)
+{
+	return(strcmp((*a)->param_name, (*b)->param_name));
+}
+
+/* Find a header with a given name (if possible) */
+
+static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name)
+{
+	MIME_HEADER htmp;
+	int idx;
+	htmp.name = name;
+	idx = sk_MIME_HEADER_find(hdrs, &htmp);
+	if(idx < 0) return NULL;
+	return sk_MIME_HEADER_value(hdrs, idx);
+}
+
+static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name)
+{
+	MIME_PARAM param;
+	int idx;
+	param.param_name = name;
+	idx = sk_MIME_PARAM_find(hdr->params, &param);
+	if(idx < 0) return NULL;
+	return sk_MIME_PARAM_value(hdr->params, idx);
+}
+
+static void mime_hdr_free(MIME_HEADER *hdr)
+{
+	if(hdr->name) OPENSSL_free(hdr->name);
+	if(hdr->value) OPENSSL_free(hdr->value);
+	if(hdr->params) sk_MIME_PARAM_pop_free(hdr->params, mime_param_free);
+	OPENSSL_free(hdr);
+}
+
+static void mime_param_free(MIME_PARAM *param)
+{
+	if(param->param_name) OPENSSL_free(param->param_name);
+	if(param->param_value) OPENSSL_free(param->param_value);
+	OPENSSL_free(param);
+}
+
+/* Check for a multipart boundary. Returns:
+ * 0 : no boundary
+ * 1 : part boundary
+ * 2 : final boundary
+ */
+static int mime_bound_check(char *line, int linelen, char *bound, int blen)
+{
+	if(linelen == -1) linelen = strlen(line);
+	if(blen == -1) blen = strlen(bound);
+	/* Quickly eliminate if line length too short */
+	if(blen + 2 > linelen) return 0;
+	/* Check for part boundary */
+	if(!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) {
+		if(!strncmp(line + blen + 2, "--", 2)) return 2;
+		else return 1;
+	}
+	return 0;
+}
+
+static int strip_eol(char *linebuf, int *plen)
+	{
+	int len = *plen;
+	char *p, c;
+	int is_eol = 0;
+	p = linebuf + len - 1;
+	for (p = linebuf + len - 1; len > 0; len--, p--)
+		{
+		c = *p;
+		if (c == '\n')
+			is_eol = 1;
+		else if (c != '\r')
+			break;
+		}
+	*plen = len;
+	return is_eol;
+	}
diff --git a/openssl/crypto/asn1/asn_moid.c b/openssl/crypto/asn1/asn_moid.c
new file mode 100644
index 0000000..1ea6a59
--- /dev/null
+++ b/openssl/crypto/asn1/asn_moid.c
@@ -0,0 +1,160 @@
+/* asn_moid.c */
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/dso.h>
+#include <openssl/x509.h>
+
+/* Simple ASN1 OID module: add all objects in a given section */
+
+static int do_create(char *value, char *name);
+
+static int oid_module_init(CONF_IMODULE *md, const CONF *cnf)
+	{
+	int i;
+	const char *oid_section;
+	STACK_OF(CONF_VALUE) *sktmp;
+	CONF_VALUE *oval;
+	oid_section = CONF_imodule_get_value(md);
+	if(!(sktmp = NCONF_get_section(cnf, oid_section)))
+		{
+		ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION);
+		return 0;
+		}
+	for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++)
+		{
+		oval = sk_CONF_VALUE_value(sktmp, i);
+		if(!do_create(oval->value, oval->name))
+			{
+			ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT);
+			return 0;
+			}
+		}
+	return 1;
+	}
+
+static void oid_module_finish(CONF_IMODULE *md)
+	{
+	OBJ_cleanup();
+	}
+
+void ASN1_add_oid_module(void)
+	{
+	CONF_module_add("oid_section", oid_module_init, oid_module_finish);
+	}
+
+/* Create an OID based on a name value pair. Accept two formats.
+ * shortname = 1.2.3.4
+ * shortname = some long name, 1.2.3.4
+ */
+
+
+static int do_create(char *value, char *name)
+	{
+	int nid;
+	ASN1_OBJECT *oid;
+	char *ln, *ostr, *p, *lntmp;
+	p = strrchr(value, ',');
+	if (!p)
+		{
+		ln = name;
+		ostr = value;
+		}
+	else
+		{
+		ln = NULL;
+		ostr = p + 1;
+		if (!*ostr)
+			return 0;
+		while(isspace((unsigned char)*ostr)) ostr++;
+		}
+
+	nid = OBJ_create(ostr, name, ln);
+
+	if (nid == NID_undef)
+		return 0;
+
+	if (p)
+		{
+		ln = value;
+		while(isspace((unsigned char)*ln)) ln++;
+		p--;
+		while(isspace((unsigned char)*p))
+			{
+			if (p == ln)
+				return 0;
+			p--;
+			}
+		p++;
+		lntmp = OPENSSL_malloc((p - ln) + 1);
+		if (lntmp == NULL)
+			return 0;
+		memcpy(lntmp, ln, p - ln);
+		lntmp[p - ln] = 0;
+		oid = OBJ_nid2obj(nid);
+		oid->ln = lntmp;
+		}
+
+	return 1;
+	}
+		
+		
diff --git a/openssl/crypto/asn1/asn_pack.c b/openssl/crypto/asn1/asn_pack.c
new file mode 100644
index 0000000..ad73821
--- /dev/null
+++ b/openssl/crypto/asn1/asn_pack.c
@@ -0,0 +1,191 @@
+/* asn_pack.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+
+#ifndef NO_ASN1_OLD
+
+/* ASN1 packing and unpacking functions */
+
+/* Turn an ASN1 encoded SEQUENCE OF into a STACK of structures */
+
+STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
+			 d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK))
+{
+    STACK_OF(OPENSSL_BLOCK) *sk;
+    const unsigned char *pbuf;
+    pbuf =  buf;
+    if (!(sk = d2i_ASN1_SET(NULL, &pbuf, len, d2i, free_func,
+					V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL)))
+		 ASN1err(ASN1_F_ASN1_SEQ_UNPACK,ASN1_R_DECODE_ERROR);
+    return sk;
+}
+
+/* Turn a STACK structures into an ASN1 encoded SEQUENCE OF structure in a
+ * OPENSSL_malloc'ed buffer
+ */
+
+unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
+			     unsigned char **buf, int *len)
+{
+	int safelen;
+	unsigned char *safe, *p;
+	if (!(safelen = i2d_ASN1_SET(safes, NULL, i2d, V_ASN1_SEQUENCE,
+					      V_ASN1_UNIVERSAL, IS_SEQUENCE))) {
+		ASN1err(ASN1_F_ASN1_SEQ_PACK,ASN1_R_ENCODE_ERROR);
+		return NULL;
+	}
+	if (!(safe = OPENSSL_malloc (safelen))) {
+		ASN1err(ASN1_F_ASN1_SEQ_PACK,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	p = safe;
+	i2d_ASN1_SET(safes, &p, i2d, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL,
+								 IS_SEQUENCE);
+	if (len) *len = safelen;
+	if (buf) *buf = safe;
+	return safe;
+}
+
+/* Extract an ASN1 object from an ASN1_STRING */
+
+void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i)
+{
+	const unsigned char *p;
+	char *ret;
+
+	p = oct->data;
+	if(!(ret = d2i(NULL, &p, oct->length)))
+		ASN1err(ASN1_F_ASN1_UNPACK_STRING,ASN1_R_DECODE_ERROR);
+	return ret;
+}
+
+/* Pack an ASN1 object into an ASN1_STRING */
+
+ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, ASN1_STRING **oct)
+{
+	unsigned char *p;
+	ASN1_STRING *octmp;
+
+	if (!oct || !*oct) {
+		if (!(octmp = ASN1_STRING_new ())) {
+			ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE);
+			return NULL;
+		}
+		if (oct) *oct = octmp;
+	} else octmp = *oct;
+		
+	if (!(octmp->length = i2d(obj, NULL))) {
+		ASN1err(ASN1_F_ASN1_PACK_STRING,ASN1_R_ENCODE_ERROR);
+		return NULL;
+	}
+	if (!(p = OPENSSL_malloc (octmp->length))) {
+		ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	octmp->data = p;
+	i2d (obj, &p);
+	return octmp;
+}
+
+#endif
+
+/* ASN1_ITEM versions of the above */
+
+ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
+{
+	ASN1_STRING *octmp;
+
+	if (!oct || !*oct) {
+		if (!(octmp = ASN1_STRING_new ())) {
+			ASN1err(ASN1_F_ASN1_ITEM_PACK,ERR_R_MALLOC_FAILURE);
+			return NULL;
+		}
+		if (oct) *oct = octmp;
+	} else octmp = *oct;
+
+	if(octmp->data) {
+		OPENSSL_free(octmp->data);
+		octmp->data = NULL;
+	}
+		
+	if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
+		ASN1err(ASN1_F_ASN1_ITEM_PACK,ASN1_R_ENCODE_ERROR);
+		return NULL;
+	}
+	if (!octmp->data) {
+		ASN1err(ASN1_F_ASN1_ITEM_PACK,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	return octmp;
+}
+
+/* Extract an ASN1 object from an ASN1_STRING */
+
+void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it)
+{
+	const unsigned char *p;
+	void *ret;
+
+	p = oct->data;
+	if(!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
+		ASN1err(ASN1_F_ASN1_ITEM_UNPACK,ASN1_R_DECODE_ERROR);
+	return ret;
+}
diff --git a/openssl/crypto/asn1/bio_asn1.c b/openssl/crypto/asn1/bio_asn1.c
new file mode 100644
index 0000000..dc7efd5
--- /dev/null
+++ b/openssl/crypto/asn1/bio_asn1.c
@@ -0,0 +1,495 @@
+/* bio_asn1.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Experimental ASN1 BIO. When written through the data is converted
+ * to an ASN1 string type: default is OCTET STRING. Additional functions
+ * can be provided to add prefix and suffix data.
+ */
+
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+
+/* Must be large enough for biggest tag+length */
+#define DEFAULT_ASN1_BUF_SIZE 20
+
+typedef enum 
+	{
+	ASN1_STATE_START,
+	ASN1_STATE_PRE_COPY,
+	ASN1_STATE_HEADER,
+	ASN1_STATE_HEADER_COPY,
+	ASN1_STATE_DATA_COPY,
+	ASN1_STATE_POST_COPY,
+	ASN1_STATE_DONE
+	} asn1_bio_state_t;
+
+typedef struct BIO_ASN1_EX_FUNCS_st
+	{
+	asn1_ps_func	*ex_func;
+	asn1_ps_func	*ex_free_func;
+	} BIO_ASN1_EX_FUNCS;
+
+typedef struct BIO_ASN1_BUF_CTX_t
+	{
+	/* Internal state */
+	asn1_bio_state_t state;
+	/* Internal buffer */
+	unsigned char *buf;
+	/* Size of buffer */
+	int bufsize;
+	/* Current position in buffer */
+	int bufpos;
+	/* Current buffer length */
+	int buflen;
+	/* Amount of data to copy */
+	int copylen;
+	/* Class and tag to use */
+	int asn1_class, asn1_tag;
+	asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
+	/* Extra buffer for prefix and suffix data */
+	unsigned char *ex_buf;
+	int ex_len;
+	int ex_pos;
+	void *ex_arg;
+	} BIO_ASN1_BUF_CTX;
+
+
+static int asn1_bio_write(BIO *h, const char *buf,int num);
+static int asn1_bio_read(BIO *h, char *buf, int size);
+static int asn1_bio_puts(BIO *h, const char *str);
+static int asn1_bio_gets(BIO *h, char *str, int size);
+static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int asn1_bio_new(BIO *h);
+static int asn1_bio_free(BIO *data);
+static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
+static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+				asn1_ps_func *cleanup, asn1_bio_state_t next);
+static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+				asn1_ps_func *setup, 
+				asn1_bio_state_t ex_state,
+				asn1_bio_state_t other_state);
+
+static BIO_METHOD methods_asn1=
+	{
+	BIO_TYPE_ASN1,
+	"asn1",
+	asn1_bio_write,
+	asn1_bio_read,
+	asn1_bio_puts,
+	asn1_bio_gets,
+	asn1_bio_ctrl,
+	asn1_bio_new,
+	asn1_bio_free,
+	asn1_bio_callback_ctrl,
+	};
+
+BIO_METHOD *BIO_f_asn1(void)
+	{
+	return(&methods_asn1);
+	}
+
+
+static int asn1_bio_new(BIO *b)
+	{
+	BIO_ASN1_BUF_CTX *ctx;
+	ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
+	if (!ctx)
+		return 0;
+	if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE))
+		return 0;
+	b->init = 1;
+	b->ptr = (char *)ctx;
+	b->flags = 0;
+	return 1;
+	}
+
+static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
+	{
+	ctx->buf = OPENSSL_malloc(size);
+	if (!ctx->buf)
+		return 0;
+	ctx->bufsize = size;
+	ctx->bufpos = 0;
+	ctx->buflen = 0;
+	ctx->copylen = 0;
+	ctx->asn1_class = V_ASN1_UNIVERSAL;
+	ctx->asn1_tag = V_ASN1_OCTET_STRING;
+	ctx->ex_buf = 0;
+	ctx->ex_pos = 0;
+	ctx->ex_len = 0;
+	ctx->state = ASN1_STATE_START;
+	return 1;
+	}
+
+static int asn1_bio_free(BIO *b)
+	{
+	BIO_ASN1_BUF_CTX *ctx;
+	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
+	if (ctx == NULL)
+		return 0;
+	if (ctx->buf)
+		OPENSSL_free(ctx->buf);
+	OPENSSL_free(ctx);
+	b->init = 0;
+	b->ptr = NULL;
+	b->flags = 0;
+	return 1;
+	}
+
+static int asn1_bio_write(BIO *b, const char *in , int inl)
+	{
+	BIO_ASN1_BUF_CTX *ctx;
+	int wrmax, wrlen, ret;
+	unsigned char *p;
+	if (!in || (inl < 0) || (b->next_bio == NULL))
+		return 0;
+	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
+	if (ctx == NULL)
+		return 0;
+
+	wrlen = 0;
+	ret = -1;
+
+	for(;;)
+		{
+		switch (ctx->state)
+			{
+
+			/* Setup prefix data, call it */
+			case ASN1_STATE_START:
+			if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
+				ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
+				return 0;
+			break;
+
+			/* Copy any pre data first */
+			case ASN1_STATE_PRE_COPY:
+
+			ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
+							ASN1_STATE_HEADER);
+
+			if (ret <= 0)
+				goto done;
+
+			break;
+
+			case ASN1_STATE_HEADER:
+			ctx->buflen =
+				ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
+			OPENSSL_assert(ctx->buflen <= ctx->bufsize);
+			p = ctx->buf;
+			ASN1_put_object(&p, 0, inl,
+					ctx->asn1_tag, ctx->asn1_class);
+			ctx->copylen = inl;
+			ctx->state = ASN1_STATE_HEADER_COPY;
+
+			break;
+
+			case ASN1_STATE_HEADER_COPY:	
+			ret = BIO_write(b->next_bio,
+					ctx->buf + ctx->bufpos, ctx->buflen);
+			if (ret <= 0)
+				goto done;
+
+			ctx->buflen -= ret;
+			if (ctx->buflen)
+				ctx->bufpos += ret;
+			else
+				{
+				ctx->bufpos = 0;
+				ctx->state = ASN1_STATE_DATA_COPY;
+				}
+
+			break;
+
+			case ASN1_STATE_DATA_COPY:
+
+			if (inl > ctx->copylen)
+				wrmax = ctx->copylen;
+			else
+				wrmax = inl;
+			ret = BIO_write(b->next_bio, in, wrmax);
+			if (ret <= 0)
+				break;
+			wrlen += ret;
+			ctx->copylen -= ret;
+			in += ret;
+			inl -= ret;
+
+			if (ctx->copylen == 0)
+				ctx->state = ASN1_STATE_HEADER;
+
+			if (inl == 0)
+				goto done;
+
+			break;
+
+			default:
+			BIO_clear_retry_flags(b);
+			return 0;
+
+			}
+
+		}
+
+	done:
+	BIO_clear_retry_flags(b);
+	BIO_copy_next_retry(b);
+
+	return (wrlen > 0) ? wrlen : ret;
+
+	}
+
+static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+				asn1_ps_func *cleanup, asn1_bio_state_t next)
+	{
+	int ret;
+	if (ctx->ex_len <= 0)
+		return 1;
+	for(;;)
+		{
+		ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos,
+								ctx->ex_len);
+		if (ret <= 0)
+			break;
+		ctx->ex_len -= ret;
+		if (ctx->ex_len > 0)
+			ctx->ex_pos += ret;
+		else
+			{
+			if(cleanup)
+				cleanup(b, &ctx->ex_buf, &ctx->ex_len,
+								&ctx->ex_arg);
+			ctx->state = next;
+			ctx->ex_pos = 0;
+			break;
+			}
+		}
+	return ret;
+	}
+
+static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+				asn1_ps_func *setup, 
+				asn1_bio_state_t ex_state,
+				asn1_bio_state_t other_state)
+	{
+	if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg))
+		{
+		BIO_clear_retry_flags(b);
+		return 0;
+		}
+	if (ctx->ex_len > 0)
+		ctx->state = ex_state;
+	else
+		ctx->state = other_state;
+	return 1;
+	}
+
+static int asn1_bio_read(BIO *b, char *in , int inl)
+	{
+	if (!b->next_bio)
+		return 0;
+	return BIO_read(b->next_bio, in , inl);
+	}
+
+static int asn1_bio_puts(BIO *b, const char *str)
+	{
+	return asn1_bio_write(b, str, strlen(str));
+	}
+
+static int asn1_bio_gets(BIO *b, char *str, int size)
+	{
+	if (!b->next_bio)
+		return 0;
+	return BIO_gets(b->next_bio, str , size);
+	}
+
+static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+	{
+	if (b->next_bio == NULL) return(0);
+	return BIO_callback_ctrl(b->next_bio,cmd,fp);
+	}
+
+static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
+	{
+	BIO_ASN1_BUF_CTX *ctx;
+	BIO_ASN1_EX_FUNCS *ex_func;
+	long ret = 1;
+	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
+	if (ctx == NULL)
+		return 0;
+	switch(cmd)
+		{
+
+		case BIO_C_SET_PREFIX:
+		ex_func = arg2;
+		ctx->prefix  = ex_func->ex_func;
+		ctx->prefix_free  = ex_func->ex_free_func;
+		break;
+
+		case BIO_C_GET_PREFIX:
+		ex_func = arg2;
+		ex_func->ex_func = ctx->prefix;
+		ex_func->ex_free_func = ctx->prefix_free;
+		break;
+
+		case BIO_C_SET_SUFFIX:
+		ex_func = arg2;
+		ctx->suffix  = ex_func->ex_func;
+		ctx->suffix_free  = ex_func->ex_free_func;
+		break;
+
+		case BIO_C_GET_SUFFIX:
+		ex_func = arg2;
+		ex_func->ex_func = ctx->suffix;
+		ex_func->ex_free_func = ctx->suffix_free;
+		break;
+
+		case BIO_C_SET_EX_ARG:
+		ctx->ex_arg = arg2;
+		break;
+
+		case BIO_C_GET_EX_ARG:
+		*(void **)arg2 = ctx->ex_arg;
+		break;
+
+		case BIO_CTRL_FLUSH:
+		if (!b->next_bio)
+			return 0;
+
+		/* Call post function if possible */
+		if (ctx->state == ASN1_STATE_HEADER)
+			{
+			if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
+				ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
+				return 0;
+			}
+
+		if (ctx->state == ASN1_STATE_POST_COPY)
+			{
+			ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
+							ASN1_STATE_DONE);
+			if (ret <= 0)
+				return ret;
+			}
+
+		if (ctx->state == ASN1_STATE_DONE)
+			return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
+		else
+			{
+			BIO_clear_retry_flags(b);
+			return 0;
+			}
+		break;
+
+
+		default:
+		if (!b->next_bio)
+			return 0;
+		return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
+
+		}
+
+	return ret;
+	}
+
+static int asn1_bio_set_ex(BIO *b, int cmd,
+		asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
+	{
+	BIO_ASN1_EX_FUNCS extmp;
+	extmp.ex_func = ex_func;
+	extmp.ex_free_func = ex_free_func;
+	return BIO_ctrl(b, cmd, 0, &extmp);
+	}
+
+static int asn1_bio_get_ex(BIO *b, int cmd,
+		asn1_ps_func **ex_func, asn1_ps_func **ex_free_func)
+	{
+	BIO_ASN1_EX_FUNCS extmp;
+	int ret;
+	ret = BIO_ctrl(b, cmd, 0, &extmp);
+	if (ret > 0)
+		{
+		*ex_func = extmp.ex_func;
+		*ex_free_func = extmp.ex_free_func;
+		}
+	return ret;
+	}
+
+int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, asn1_ps_func *prefix_free)
+	{
+	return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
+	}
+
+int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, asn1_ps_func **pprefix_free)
+	{
+	return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
+	}
+
+int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, asn1_ps_func *suffix_free)
+	{
+	return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
+	}
+
+int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_func **psuffix_free)
+	{
+	return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
+	}
diff --git a/openssl/crypto/asn1/bio_ndef.c b/openssl/crypto/asn1/bio_ndef.c
new file mode 100644
index 0000000..b91f97a
--- /dev/null
+++ b/openssl/crypto/asn1/bio_ndef.c
@@ -0,0 +1,243 @@
+/* bio_ndef.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+#include <stdio.h>
+
+/* Experimental NDEF ASN1 BIO support routines */
+
+/* The usage is quite simple, initialize an ASN1 structure,
+ * get a BIO from it then any data written through the BIO
+ * will end up translated to approptiate format on the fly.
+ * The data is streamed out and does *not* need to be
+ * all held in memory at once.
+ *
+ * When the BIO is flushed the output is finalized and any
+ * signatures etc written out.
+ *
+ * The BIO is a 'proper' BIO and can handle non blocking I/O
+ * correctly.
+ *
+ * The usage is simple. The implementation is *not*...
+ */
+
+/* BIO support data stored in the ASN1 BIO ex_arg */
+
+typedef struct ndef_aux_st
+	{
+	/* ASN1 structure this BIO refers to */
+	ASN1_VALUE *val;
+	const ASN1_ITEM *it;
+	/* Top of the BIO chain */
+	BIO *ndef_bio;
+	/* Output BIO */
+	BIO *out;
+	/* Boundary where content is inserted */
+	unsigned char **boundary;
+	/* DER buffer start */
+	unsigned char *derbuf;
+	} NDEF_SUPPORT;
+
+static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+
+BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
+	{
+	NDEF_SUPPORT *ndef_aux = NULL;
+	BIO *asn_bio = NULL;
+	const ASN1_AUX *aux = it->funcs;
+	ASN1_STREAM_ARG sarg;
+
+	if (!aux || !aux->asn1_cb)
+		{
+		ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
+		return NULL;
+		}
+	ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
+	asn_bio = BIO_new(BIO_f_asn1());
+
+	/* ASN1 bio needs to be next to output BIO */
+
+	out = BIO_push(asn_bio, out);
+
+	if (!ndef_aux || !asn_bio || !out)
+		goto err;
+
+	BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
+	BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
+
+	/* Now let callback prepend any digest, cipher etc BIOs
+	 * ASN1 structure needs.
+	 */
+
+	sarg.out = out;
+	sarg.ndef_bio = NULL;
+	sarg.boundary = NULL;
+
+	if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
+		goto err;
+
+	ndef_aux->val = val;
+	ndef_aux->it = it;
+	ndef_aux->ndef_bio = sarg.ndef_bio;
+	ndef_aux->boundary = sarg.boundary;
+	ndef_aux->out = out;
+
+	BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
+
+	return sarg.ndef_bio;
+
+	err:
+	if (asn_bio)
+		BIO_free(asn_bio);
+	if (ndef_aux)
+		OPENSSL_free(ndef_aux);
+	return NULL;
+	}
+
+static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+	{
+	NDEF_SUPPORT *ndef_aux;
+	unsigned char *p;
+	int derlen;
+
+	if (!parg)
+		return 0;
+
+	ndef_aux = *(NDEF_SUPPORT **)parg;
+
+	derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+	p = OPENSSL_malloc(derlen);
+	ndef_aux->derbuf = p;
+	*pbuf = p;
+	derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+
+	if (!*ndef_aux->boundary)
+		return 0;
+
+	*plen = *ndef_aux->boundary - *pbuf;
+
+	return 1;
+	}
+
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+	{
+	NDEF_SUPPORT *ndef_aux;
+
+	if (!parg)
+		return 0;
+
+	ndef_aux = *(NDEF_SUPPORT **)parg;
+
+	if (ndef_aux->derbuf)
+		OPENSSL_free(ndef_aux->derbuf);
+
+	ndef_aux->derbuf = NULL;
+	*pbuf = NULL;
+	*plen = 0;
+	return 1;
+	}
+
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+	{
+	NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
+	if (!ndef_prefix_free(b, pbuf, plen, parg))
+		return 0;
+	OPENSSL_free(*pndef_aux);
+	*pndef_aux = NULL;
+	return 1;
+	}
+
+static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+	{
+	NDEF_SUPPORT *ndef_aux;
+	unsigned char *p;
+	int derlen;
+	const ASN1_AUX *aux;
+	ASN1_STREAM_ARG sarg;
+
+	if (!parg)
+		return 0;
+
+	ndef_aux = *(NDEF_SUPPORT **)parg;
+
+	aux = ndef_aux->it->funcs;
+
+	/* Finalize structures */
+	sarg.ndef_bio = ndef_aux->ndef_bio;
+	sarg.out = ndef_aux->out;
+	sarg.boundary = ndef_aux->boundary;
+	if (aux->asn1_cb(ASN1_OP_STREAM_POST,
+				&ndef_aux->val, ndef_aux->it, &sarg) <= 0)
+		return 0;
+
+	derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+	p = OPENSSL_malloc(derlen);
+	ndef_aux->derbuf = p;
+	*pbuf = p;
+	derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+
+	if (!*ndef_aux->boundary)
+		return 0;
+	*pbuf = *ndef_aux->boundary;
+	*plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
+
+	return 1;
+	}
diff --git a/openssl/crypto/asn1/charmap.h b/openssl/crypto/asn1/charmap.h
new file mode 100644
index 0000000..b55e638
--- /dev/null
+++ b/openssl/crypto/asn1/charmap.h
@@ -0,0 +1,15 @@
+/* Auto generated with chartype.pl script.
+ * Mask of various character properties
+ */
+
+static const unsigned char char_type[] = {
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+120, 0, 1,40, 0, 0, 0,16,16,16, 0,25,25,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16, 9, 9,16, 9,16,
+ 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16, 0, 1, 0, 0, 0,
+ 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16, 0, 0, 0, 0, 2
+};
+
diff --git a/openssl/crypto/asn1/charmap.pl b/openssl/crypto/asn1/charmap.pl
new file mode 100644
index 0000000..2875c59
--- /dev/null
+++ b/openssl/crypto/asn1/charmap.pl
@@ -0,0 +1,80 @@
+#!/usr/local/bin/perl -w
+
+use strict;
+
+my ($i, @arr);
+
+# Set up an array with the type of ASCII characters
+# Each set bit represents a character property.
+
+# RFC2253 character properties
+my $RFC2253_ESC = 1;	# Character escaped with \
+my $ESC_CTRL	= 2;	# Escaped control character
+# These are used with RFC1779 quoting using "
+my $NOESC_QUOTE	= 8;	# Not escaped if quoted
+my $PSTRING_CHAR = 0x10;	# Valid PrintableString character
+my $RFC2253_FIRST_ESC = 0x20; # Escaped with \ if first character
+my $RFC2253_LAST_ESC = 0x40;  # Escaped with \ if last character
+
+for($i = 0; $i < 128; $i++) {
+	# Set the RFC2253 escape characters (control)
+	$arr[$i] = 0;
+	if(($i < 32) || ($i > 126)) {
+		$arr[$i] |= $ESC_CTRL;
+	}
+
+	# Some PrintableString characters
+	if(		   ( ( $i >= ord("a")) && ( $i <= ord("z")) )
+			|| (  ( $i >= ord("A")) && ( $i <= ord("Z")) )
+			|| (  ( $i >= ord("0")) && ( $i <= ord("9")) )  ) {
+		$arr[$i] |= $PSTRING_CHAR;
+	}
+}
+
+# Now setup the rest
+
+# Remaining RFC2253 escaped characters
+
+$arr[ord(" ")] |= $NOESC_QUOTE | $RFC2253_FIRST_ESC | $RFC2253_LAST_ESC;
+$arr[ord("#")] |= $NOESC_QUOTE | $RFC2253_FIRST_ESC;
+
+$arr[ord(",")] |= $NOESC_QUOTE | $RFC2253_ESC;
+$arr[ord("+")] |= $NOESC_QUOTE | $RFC2253_ESC;
+$arr[ord("\"")] |= $RFC2253_ESC;
+$arr[ord("\\")] |= $RFC2253_ESC;
+$arr[ord("<")] |= $NOESC_QUOTE | $RFC2253_ESC;
+$arr[ord(">")] |= $NOESC_QUOTE | $RFC2253_ESC;
+$arr[ord(";")] |= $NOESC_QUOTE | $RFC2253_ESC;
+
+# Remaining PrintableString characters
+
+$arr[ord(" ")] |= $PSTRING_CHAR;
+$arr[ord("'")] |= $PSTRING_CHAR;
+$arr[ord("(")] |= $PSTRING_CHAR;
+$arr[ord(")")] |= $PSTRING_CHAR;
+$arr[ord("+")] |= $PSTRING_CHAR;
+$arr[ord(",")] |= $PSTRING_CHAR;
+$arr[ord("-")] |= $PSTRING_CHAR;
+$arr[ord(".")] |= $PSTRING_CHAR;
+$arr[ord("/")] |= $PSTRING_CHAR;
+$arr[ord(":")] |= $PSTRING_CHAR;
+$arr[ord("=")] |= $PSTRING_CHAR;
+$arr[ord("?")] |= $PSTRING_CHAR;
+
+# Now generate the C code
+
+print <<EOF;
+/* Auto generated with chartype.pl script.
+ * Mask of various character properties
+ */
+
+static unsigned char char_type[] = {
+EOF
+
+for($i = 0; $i < 128; $i++) {
+	print("\n") if($i && (($i % 16) == 0));
+	printf("%2d", $arr[$i]);
+	print(",") if ($i != 127);
+}
+print("\n};\n\n");
+
diff --git a/openssl/crypto/asn1/d2i_pr.c b/openssl/crypto/asn1/d2i_pr.c
new file mode 100644
index 0000000..2828944
--- /dev/null
+++ b/openssl/crypto/asn1/d2i_pr.c
@@ -0,0 +1,170 @@
+/* crypto/asn1/d2i_pr.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include "asn1_locl.h"
+
+EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
+	     long length)
+	{
+	EVP_PKEY *ret;
+
+	if ((a == NULL) || (*a == NULL))
+		{
+		if ((ret=EVP_PKEY_new()) == NULL)
+			{
+			ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_EVP_LIB);
+			return(NULL);
+			}
+		}
+	else
+		{
+		ret= *a;
+#ifndef OPENSSL_NO_ENGINE
+		if (ret->engine)
+			{
+			ENGINE_finish(ret->engine);
+			ret->engine = NULL;
+			}
+#endif
+		}
+
+	if (!EVP_PKEY_set_type(ret, type))
+		{
+		ASN1err(ASN1_F_D2I_PRIVATEKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
+		goto err;
+		}
+
+	if (!ret->ameth->old_priv_decode ||
+			!ret->ameth->old_priv_decode(ret, pp, length))
+		{
+		if (ret->ameth->priv_decode) 
+			{
+			PKCS8_PRIV_KEY_INFO *p8=NULL;
+			p8=d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length);
+			if (!p8) goto err;
+			EVP_PKEY_free(ret);
+			ret = EVP_PKCS82PKEY(p8);
+			PKCS8_PRIV_KEY_INFO_free(p8);
+
+			} 
+		else 
+			{
+			ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB);
+			goto err;
+			}
+		}	
+	if (a != NULL) (*a)=ret;
+	return(ret);
+err:
+	if ((ret != NULL) && ((a == NULL) || (*a != ret))) EVP_PKEY_free(ret);
+	return(NULL);
+	}
+
+/* This works like d2i_PrivateKey() except it automatically works out the type */
+
+EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
+	     long length)
+{
+	STACK_OF(ASN1_TYPE) *inkey;
+	const unsigned char *p;
+	int keytype;
+	p = *pp;
+	/* Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE):
+	 * by analyzing it we can determine the passed structure: this
+	 * assumes the input is surrounded by an ASN1 SEQUENCE.
+	 */
+	inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
+	/* Since we only need to discern "traditional format" RSA and DSA
+	 * keys we can just count the elements.
+         */
+	if(sk_ASN1_TYPE_num(inkey) == 6) 
+		keytype = EVP_PKEY_DSA;
+	else if (sk_ASN1_TYPE_num(inkey) == 4)
+		keytype = EVP_PKEY_EC;
+	else if (sk_ASN1_TYPE_num(inkey) == 3)  
+		{ /* This seems to be PKCS8, not traditional format */
+			PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length);
+			EVP_PKEY *ret;
+
+			sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
+			if (!p8) 
+				{
+				ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+				return NULL;
+				}
+			ret = EVP_PKCS82PKEY(p8);
+			PKCS8_PRIV_KEY_INFO_free(p8);
+			if (a) {
+				*a = ret;
+			}	
+			return ret;
+		}
+	else keytype = EVP_PKEY_RSA;
+	sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
+	return d2i_PrivateKey(keytype, a, pp, length);
+}
diff --git a/openssl/crypto/asn1/d2i_pu.c b/openssl/crypto/asn1/d2i_pu.c
new file mode 100644
index 0000000..c8f39ce
--- /dev/null
+++ b/openssl/crypto/asn1/d2i_pu.c
@@ -0,0 +1,139 @@
+/* crypto/asn1/d2i_pu.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/asn1.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_EC
+#include <openssl/ec.h>
+#endif
+
+EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
+	     long length)
+	{
+	EVP_PKEY *ret;
+
+	if ((a == NULL) || (*a == NULL))
+		{
+		if ((ret=EVP_PKEY_new()) == NULL)
+			{
+			ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_EVP_LIB);
+			return(NULL);
+			}
+		}
+	else	ret= *a;
+
+	if (!EVP_PKEY_set_type(ret, type))
+		{
+		ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_EVP_LIB);
+		goto err;
+		}
+
+	switch (EVP_PKEY_id(ret))
+		{
+#ifndef OPENSSL_NO_RSA
+	case EVP_PKEY_RSA:
+		if ((ret->pkey.rsa=d2i_RSAPublicKey(NULL,
+			(const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */
+			{
+			ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_ASN1_LIB);
+			goto err;
+			}
+		break;
+#endif
+#ifndef OPENSSL_NO_DSA
+	case EVP_PKEY_DSA:
+		if (!d2i_DSAPublicKey(&(ret->pkey.dsa),
+			(const unsigned char **)pp,length)) /* TMP UGLY CAST */
+			{
+			ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_ASN1_LIB);
+			goto err;
+			}
+		break;
+#endif
+#ifndef OPENSSL_NO_EC
+	case EVP_PKEY_EC:
+		if (!o2i_ECPublicKey(&(ret->pkey.ec),
+				     (const unsigned char **)pp, length))
+			{
+			ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
+			goto err;
+			}
+	break;
+#endif
+	default:
+		ASN1err(ASN1_F_D2I_PUBLICKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
+		goto err;
+		/* break; */
+		}
+	if (a != NULL) (*a)=ret;
+	return(ret);
+err:
+	if ((ret != NULL) && ((a == NULL) || (*a != ret))) EVP_PKEY_free(ret);
+	return(NULL);
+	}
+
diff --git a/openssl/crypto/asn1/evp_asn1.c b/openssl/crypto/asn1/evp_asn1.c
new file mode 100644
index 0000000..f3d9804
--- /dev/null
+++ b/openssl/crypto/asn1/evp_asn1.c
@@ -0,0 +1,189 @@
+/* crypto/asn1/evp_asn1.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1_mac.h>
+
+int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len)
+	{
+	ASN1_STRING *os;
+
+	if ((os=M_ASN1_OCTET_STRING_new()) == NULL) return(0);
+	if (!M_ASN1_OCTET_STRING_set(os,data,len)) return(0);
+	ASN1_TYPE_set(a,V_ASN1_OCTET_STRING,os);
+	return(1);
+	}
+
+/* int max_len:  for returned value    */
+int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data,
+	     int max_len)
+	{
+	int ret,num;
+	unsigned char *p;
+
+	if ((a->type != V_ASN1_OCTET_STRING) || (a->value.octet_string == NULL))
+		{
+		ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING,ASN1_R_DATA_IS_WRONG);
+		return(-1);
+		}
+	p=M_ASN1_STRING_data(a->value.octet_string);
+	ret=M_ASN1_STRING_length(a->value.octet_string);
+	if (ret < max_len)
+		num=ret;
+	else
+		num=max_len;
+	memcpy(data,p,num);
+	return(ret);
+	}
+
+int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data,
+	     int len)
+	{
+	int n,size;
+	ASN1_OCTET_STRING os,*osp;
+	ASN1_INTEGER in;
+	unsigned char *p;
+	unsigned char buf[32]; /* when they have 256bit longs, 
+				* I'll be in trouble */
+	in.data=buf;
+	in.length=32;
+	os.data=data;
+	os.type=V_ASN1_OCTET_STRING;
+	os.length=len;
+	ASN1_INTEGER_set(&in,num);
+	n =  i2d_ASN1_INTEGER(&in,NULL);
+	n+=M_i2d_ASN1_OCTET_STRING(&os,NULL);
+
+	size=ASN1_object_size(1,n,V_ASN1_SEQUENCE);
+
+	if ((osp=ASN1_STRING_new()) == NULL) return(0);
+	/* Grow the 'string' */
+	if (!ASN1_STRING_set(osp,NULL,size))
+		{
+		ASN1_STRING_free(osp);
+		return(0);
+		}
+
+	M_ASN1_STRING_length_set(osp, size);
+	p=M_ASN1_STRING_data(osp);
+
+	ASN1_put_object(&p,1,n,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
+	  i2d_ASN1_INTEGER(&in,&p);
+	M_i2d_ASN1_OCTET_STRING(&os,&p);
+
+	ASN1_TYPE_set(a,V_ASN1_SEQUENCE,osp);
+	return(1);
+	}
+
+/* we return the actual length..., num may be missing, in which
+ * case, set it to zero */
+/* int max_len:  for returned value    */
+int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, unsigned char *data,
+	     int max_len)
+	{
+	int ret= -1,n;
+	ASN1_INTEGER *ai=NULL;
+	ASN1_OCTET_STRING *os=NULL;
+	const unsigned char *p;
+	long length;
+	ASN1_const_CTX c;
+
+	if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL))
+		{
+		goto err;
+		}
+	p=M_ASN1_STRING_data(a->value.sequence);
+	length=M_ASN1_STRING_length(a->value.sequence);
+
+	c.pp= &p;
+	c.p=p;
+	c.max=p+length;
+	c.error=ASN1_R_DATA_IS_WRONG;
+
+	M_ASN1_D2I_start_sequence();
+	c.q=c.p;
+	if ((ai=d2i_ASN1_INTEGER(NULL,&c.p,c.slen)) == NULL) goto err;
+        c.slen-=(c.p-c.q);
+	c.q=c.p;
+	if ((os=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) goto err;
+        c.slen-=(c.p-c.q);
+	if (!M_ASN1_D2I_end_sequence()) goto err;
+
+	if (num != NULL)
+		*num=ASN1_INTEGER_get(ai);
+
+	ret=M_ASN1_STRING_length(os);
+	if (max_len > ret)
+		n=ret;
+	else
+		n=max_len;
+
+	if (data != NULL)
+		memcpy(data,M_ASN1_STRING_data(os),n);
+	if (0)
+		{
+err:
+		ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING,ASN1_R_DATA_IS_WRONG);
+		}
+	if (os != NULL) M_ASN1_OCTET_STRING_free(os);
+	if (ai != NULL) M_ASN1_INTEGER_free(ai);
+	return(ret);
+	}
+
diff --git a/openssl/crypto/asn1/f_enum.c b/openssl/crypto/asn1/f_enum.c
new file mode 100644
index 0000000..56e3cc8
--- /dev/null
+++ b/openssl/crypto/asn1/f_enum.c
@@ -0,0 +1,207 @@
+/* crypto/asn1/f_enum.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+
+/* Based on a_int.c: equivalent ENUMERATED functions */
+
+int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a)
+	{
+	int i,n=0;
+	static const char *h="0123456789ABCDEF";
+	char buf[2];
+
+	if (a == NULL) return(0);
+
+	if (a->length == 0)
+		{
+		if (BIO_write(bp,"00",2) != 2) goto err;
+		n=2;
+		}
+	else
+		{
+		for (i=0; i<a->length; i++)
+			{
+			if ((i != 0) && (i%35 == 0))
+				{
+				if (BIO_write(bp,"\\\n",2) != 2) goto err;
+				n+=2;
+				}
+			buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
+			buf[1]=h[((unsigned char)a->data[i]   )&0x0f];
+			if (BIO_write(bp,buf,2) != 2) goto err;
+			n+=2;
+			}
+		}
+	return(n);
+err:
+	return(-1);
+	}
+
+int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
+	{
+	int ret=0;
+	int i,j,k,m,n,again,bufsize;
+	unsigned char *s=NULL,*sp;
+	unsigned char *bufp;
+	int num=0,slen=0,first=1;
+
+	bs->type=V_ASN1_ENUMERATED;
+
+	bufsize=BIO_gets(bp,buf,size);
+	for (;;)
+		{
+		if (bufsize < 1) goto err_sl;
+		i=bufsize;
+		if (buf[i-1] == '\n') buf[--i]='\0';
+		if (i == 0) goto err_sl;
+		if (buf[i-1] == '\r') buf[--i]='\0';
+		if (i == 0) goto err_sl;
+		again=(buf[i-1] == '\\');
+
+		for (j=0; j<i; j++)
+			{
+			if (!(	((buf[j] >= '0') && (buf[j] <= '9')) ||
+				((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+				((buf[j] >= 'A') && (buf[j] <= 'F'))))
+				{
+				i=j;
+				break;
+				}
+			}
+		buf[i]='\0';
+		/* We have now cleared all the crap off the end of the
+		 * line */
+		if (i < 2) goto err_sl;
+
+		bufp=(unsigned char *)buf;
+		if (first)
+			{
+			first=0;
+			if ((bufp[0] == '0') && (buf[1] == '0'))
+				{
+				bufp+=2;
+				i-=2;
+				}
+			}
+		k=0;
+		i-=again;
+		if (i%2 != 0)
+			{
+			ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_ODD_NUMBER_OF_CHARS);
+			goto err;
+			}
+		i/=2;
+		if (num+i > slen)
+			{
+			if (s == NULL)
+				sp=(unsigned char *)OPENSSL_malloc(
+					(unsigned int)num+i*2);
+			else
+				sp=(unsigned char *)OPENSSL_realloc(s,
+					(unsigned int)num+i*2);
+			if (sp == NULL)
+				{
+				ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
+				if (s != NULL) OPENSSL_free(s);
+				goto err;
+				}
+			s=sp;
+			slen=num+i*2;
+			}
+		for (j=0; j<i; j++,k+=2)
+			{
+			for (n=0; n<2; n++)
+				{
+				m=bufp[k+n];
+				if ((m >= '0') && (m <= '9'))
+					m-='0';
+				else if ((m >= 'a') && (m <= 'f'))
+					m=m-'a'+10;
+				else if ((m >= 'A') && (m <= 'F'))
+					m=m-'A'+10;
+				else
+					{
+					ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_NON_HEX_CHARACTERS);
+					goto err;
+					}
+				s[num+j]<<=4;
+				s[num+j]|=m;
+				}
+			}
+		num+=i;
+		if (again)
+			bufsize=BIO_gets(bp,buf,size);
+		else
+			break;
+		}
+	bs->length=num;
+	bs->data=s;
+	ret=1;
+err:
+	if (0)
+		{
+err_sl:
+		ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_SHORT_LINE);
+		}
+	return(ret);
+	}
+
diff --git a/openssl/crypto/asn1/f_int.c b/openssl/crypto/asn1/f_int.c
new file mode 100644
index 0000000..9494e59
--- /dev/null
+++ b/openssl/crypto/asn1/f_int.c
@@ -0,0 +1,219 @@
+/* crypto/asn1/f_int.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+
+int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a)
+	{
+	int i,n=0;
+	static const char *h="0123456789ABCDEF";
+	char buf[2];
+
+	if (a == NULL) return(0);
+
+	if (a->type & V_ASN1_NEG)
+		{
+		if (BIO_write(bp, "-", 1) != 1) goto err;
+		n = 1;
+		}
+
+	if (a->length == 0)
+		{
+		if (BIO_write(bp,"00",2) != 2) goto err;
+		n += 2;
+		}
+	else
+		{
+		for (i=0; i<a->length; i++)
+			{
+			if ((i != 0) && (i%35 == 0))
+				{
+				if (BIO_write(bp,"\\\n",2) != 2) goto err;
+				n+=2;
+				}
+			buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
+			buf[1]=h[((unsigned char)a->data[i]   )&0x0f];
+			if (BIO_write(bp,buf,2) != 2) goto err;
+			n+=2;
+			}
+		}
+	return(n);
+err:
+	return(-1);
+	}
+
+int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
+	{
+	int ret=0;
+	int i,j,k,m,n,again,bufsize;
+	unsigned char *s=NULL,*sp;
+	unsigned char *bufp;
+	int num=0,slen=0,first=1;
+
+	bs->type=V_ASN1_INTEGER;
+
+	bufsize=BIO_gets(bp,buf,size);
+	for (;;)
+		{
+		if (bufsize < 1) goto err_sl;
+		i=bufsize;
+		if (buf[i-1] == '\n') buf[--i]='\0';
+		if (i == 0) goto err_sl;
+		if (buf[i-1] == '\r') buf[--i]='\0';
+		if (i == 0) goto err_sl;
+		again=(buf[i-1] == '\\');
+
+		for (j=0; j<i; j++)
+			{
+#ifndef CHARSET_EBCDIC
+			if (!(	((buf[j] >= '0') && (buf[j] <= '9')) ||
+				((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+				((buf[j] >= 'A') && (buf[j] <= 'F'))))
+#else
+			/* This #ifdef is not strictly necessary, since
+			 * the characters A...F a...f 0...9 are contiguous
+			 * (yes, even in EBCDIC - but not the whole alphabet).
+			 * Nevertheless, isxdigit() is faster.
+			 */
+			if (!isxdigit(buf[j]))
+#endif
+				{
+				i=j;
+				break;
+				}
+			}
+		buf[i]='\0';
+		/* We have now cleared all the crap off the end of the
+		 * line */
+		if (i < 2) goto err_sl;
+
+		bufp=(unsigned char *)buf;
+		if (first)
+			{
+			first=0;
+			if ((bufp[0] == '0') && (buf[1] == '0'))
+				{
+				bufp+=2;
+				i-=2;
+				}
+			}
+		k=0;
+		i-=again;
+		if (i%2 != 0)
+			{
+			ASN1err(ASN1_F_A2I_ASN1_INTEGER,ASN1_R_ODD_NUMBER_OF_CHARS);
+			goto err;
+			}
+		i/=2;
+		if (num+i > slen)
+			{
+			if (s == NULL)
+				sp=(unsigned char *)OPENSSL_malloc(
+					(unsigned int)num+i*2);
+			else
+				sp=OPENSSL_realloc_clean(s,slen,num+i*2);
+			if (sp == NULL)
+				{
+				ASN1err(ASN1_F_A2I_ASN1_INTEGER,ERR_R_MALLOC_FAILURE);
+				if (s != NULL) OPENSSL_free(s);
+				goto err;
+				}
+			s=sp;
+			slen=num+i*2;
+			}
+		for (j=0; j<i; j++,k+=2)
+			{
+			for (n=0; n<2; n++)
+				{
+				m=bufp[k+n];
+				if ((m >= '0') && (m <= '9'))
+					m-='0';
+				else if ((m >= 'a') && (m <= 'f'))
+					m=m-'a'+10;
+				else if ((m >= 'A') && (m <= 'F'))
+					m=m-'A'+10;
+				else
+					{
+					ASN1err(ASN1_F_A2I_ASN1_INTEGER,ASN1_R_NON_HEX_CHARACTERS);
+					goto err;
+					}
+				s[num+j]<<=4;
+				s[num+j]|=m;
+				}
+			}
+		num+=i;
+		if (again)
+			bufsize=BIO_gets(bp,buf,size);
+		else
+			break;
+		}
+	bs->length=num;
+	bs->data=s;
+	ret=1;
+err:
+	if (0)
+		{
+err_sl:
+		ASN1err(ASN1_F_A2I_ASN1_INTEGER,ASN1_R_SHORT_LINE);
+		}
+	return(ret);
+	}
+
diff --git a/openssl/crypto/asn1/f_string.c b/openssl/crypto/asn1/f_string.c
new file mode 100644
index 0000000..968698a
--- /dev/null
+++ b/openssl/crypto/asn1/f_string.c
@@ -0,0 +1,212 @@
+/* crypto/asn1/f_string.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+
+int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type)
+	{
+	int i,n=0;
+	static const char *h="0123456789ABCDEF";
+	char buf[2];
+
+	if (a == NULL) return(0);
+
+	if (a->length == 0)
+		{
+		if (BIO_write(bp,"0",1) != 1) goto err;
+		n=1;
+		}
+	else
+		{
+		for (i=0; i<a->length; i++)
+			{
+			if ((i != 0) && (i%35 == 0))
+				{
+				if (BIO_write(bp,"\\\n",2) != 2) goto err;
+				n+=2;
+				}
+			buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
+			buf[1]=h[((unsigned char)a->data[i]   )&0x0f];
+			if (BIO_write(bp,buf,2) != 2) goto err;
+			n+=2;
+			}
+		}
+	return(n);
+err:
+	return(-1);
+	}
+
+int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
+	{
+	int ret=0;
+	int i,j,k,m,n,again,bufsize;
+	unsigned char *s=NULL,*sp;
+	unsigned char *bufp;
+	int num=0,slen=0,first=1;
+
+	bufsize=BIO_gets(bp,buf,size);
+	for (;;)
+		{
+		if (bufsize < 1)
+			{
+			if (first)
+				break;
+			else
+				goto err_sl;
+			}
+		first=0;
+
+		i=bufsize;
+		if (buf[i-1] == '\n') buf[--i]='\0';
+		if (i == 0) goto err_sl;
+		if (buf[i-1] == '\r') buf[--i]='\0';
+		if (i == 0) goto err_sl;
+		again=(buf[i-1] == '\\');
+
+		for (j=i-1; j>0; j--)
+			{
+#ifndef CHARSET_EBCDIC
+			if (!(	((buf[j] >= '0') && (buf[j] <= '9')) ||
+				((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+				((buf[j] >= 'A') && (buf[j] <= 'F'))))
+#else
+			/* This #ifdef is not strictly necessary, since
+			 * the characters A...F a...f 0...9 are contiguous
+			 * (yes, even in EBCDIC - but not the whole alphabet).
+			 * Nevertheless, isxdigit() is faster.
+			 */
+			if (!isxdigit(buf[j]))
+#endif
+				{
+				i=j;
+				break;
+				}
+			}
+		buf[i]='\0';
+		/* We have now cleared all the crap off the end of the
+		 * line */
+		if (i < 2) goto err_sl;
+
+		bufp=(unsigned char *)buf;
+
+		k=0;
+		i-=again;
+		if (i%2 != 0)
+			{
+			ASN1err(ASN1_F_A2I_ASN1_STRING,ASN1_R_ODD_NUMBER_OF_CHARS);
+			goto err;
+			}
+		i/=2;
+		if (num+i > slen)
+			{
+			if (s == NULL)
+				sp=(unsigned char *)OPENSSL_malloc(
+					(unsigned int)num+i*2);
+			else
+				sp=(unsigned char *)OPENSSL_realloc(s,
+					(unsigned int)num+i*2);
+			if (sp == NULL)
+				{
+				ASN1err(ASN1_F_A2I_ASN1_STRING,ERR_R_MALLOC_FAILURE);
+				if (s != NULL) OPENSSL_free(s);
+				goto err;
+				}
+			s=sp;
+			slen=num+i*2;
+			}
+		for (j=0; j<i; j++,k+=2)
+			{
+			for (n=0; n<2; n++)
+				{
+				m=bufp[k+n];
+				if ((m >= '0') && (m <= '9'))
+					m-='0';
+				else if ((m >= 'a') && (m <= 'f'))
+					m=m-'a'+10;
+				else if ((m >= 'A') && (m <= 'F'))
+					m=m-'A'+10;
+				else
+					{
+					ASN1err(ASN1_F_A2I_ASN1_STRING,ASN1_R_NON_HEX_CHARACTERS);
+					goto err;
+					}
+				s[num+j]<<=4;
+				s[num+j]|=m;
+				}
+			}
+		num+=i;
+		if (again)
+			bufsize=BIO_gets(bp,buf,size);
+		else
+			break;
+		}
+	bs->length=num;
+	bs->data=s;
+	ret=1;
+err:
+	if (0)
+		{
+err_sl:
+		ASN1err(ASN1_F_A2I_ASN1_STRING,ASN1_R_SHORT_LINE);
+		}
+	return(ret);
+	}
+
diff --git a/openssl/crypto/asn1/i2d_pr.c b/openssl/crypto/asn1/i2d_pr.c
new file mode 100644
index 0000000..e398b62
--- /dev/null
+++ b/openssl/crypto/asn1/i2d_pr.c
@@ -0,0 +1,80 @@
+/* crypto/asn1/i2d_pr.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include "asn1_locl.h"
+
+int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
+	{
+	if (a->ameth && a->ameth->old_priv_encode)
+		{
+		return a->ameth->old_priv_encode(a, pp);
+		}
+	if (a->ameth && a->ameth->priv_encode) {
+		PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
+		int ret = i2d_PKCS8_PRIV_KEY_INFO(p8,pp);
+		PKCS8_PRIV_KEY_INFO_free(p8);
+		return ret;
+	}	
+	ASN1err(ASN1_F_I2D_PRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+	return(-1);
+	}
+
diff --git a/openssl/crypto/asn1/i2d_pu.c b/openssl/crypto/asn1/i2d_pu.c
new file mode 100644
index 0000000..34286db
--- /dev/null
+++ b/openssl/crypto/asn1/i2d_pu.c
@@ -0,0 +1,95 @@
+/* crypto/asn1/i2d_pu.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_EC
+#include <openssl/ec.h>
+#endif
+
+int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp)
+	{
+	switch (a->type)
+		{
+#ifndef OPENSSL_NO_RSA
+	case EVP_PKEY_RSA:
+		return(i2d_RSAPublicKey(a->pkey.rsa,pp));
+#endif
+#ifndef OPENSSL_NO_DSA
+	case EVP_PKEY_DSA:
+		return(i2d_DSAPublicKey(a->pkey.dsa,pp));
+#endif
+#ifndef OPENSSL_NO_EC
+	case EVP_PKEY_EC:
+		return(i2o_ECPublicKey(a->pkey.ec, pp));
+#endif
+	default:
+		ASN1err(ASN1_F_I2D_PUBLICKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+		return(-1);
+		}
+	}
+
diff --git a/openssl/crypto/asn1/n_pkey.c b/openssl/crypto/asn1/n_pkey.c
new file mode 100644
index 0000000..e7d0439
--- /dev/null
+++ b/openssl/crypto/asn1/n_pkey.c
@@ -0,0 +1,343 @@
+/* crypto/asn1/n_pkey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#include <openssl/objects.h>
+#include <openssl/asn1t.h>
+#include <openssl/asn1_mac.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+
+#ifndef OPENSSL_NO_RC4
+
+typedef struct netscape_pkey_st
+	{
+	long version;
+	X509_ALGOR *algor;
+	ASN1_OCTET_STRING *private_key;
+	} NETSCAPE_PKEY;
+
+typedef struct netscape_encrypted_pkey_st
+	{
+	ASN1_OCTET_STRING *os;
+	/* This is the same structure as DigestInfo so use it:
+	 * although this isn't really anything to do with
+	 * digests.
+	 */
+	X509_SIG *enckey;
+	} NETSCAPE_ENCRYPTED_PKEY;
+
+
+ASN1_BROKEN_SEQUENCE(NETSCAPE_ENCRYPTED_PKEY) = {
+	ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, os, ASN1_OCTET_STRING),
+	ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, enckey, X509_SIG)
+} ASN1_BROKEN_SEQUENCE_END(NETSCAPE_ENCRYPTED_PKEY)
+
+DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY,NETSCAPE_ENCRYPTED_PKEY)
+IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
+
+ASN1_SEQUENCE(NETSCAPE_PKEY) = {
+	ASN1_SIMPLE(NETSCAPE_PKEY, version, LONG),
+	ASN1_SIMPLE(NETSCAPE_PKEY, algor, X509_ALGOR),
+	ASN1_SIMPLE(NETSCAPE_PKEY, private_key, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(NETSCAPE_PKEY)
+
+DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_PKEY,NETSCAPE_PKEY)
+IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
+
+static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
+			  int (*cb)(char *buf, int len, const char *prompt,
+				    int verify),
+			  int sgckey);
+
+int i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
+		     int (*cb)(char *buf, int len, const char *prompt,
+			       int verify))
+{
+	return i2d_RSA_NET(a, pp, cb, 0);
+}
+
+int i2d_RSA_NET(const RSA *a, unsigned char **pp,
+		int (*cb)(char *buf, int len, const char *prompt, int verify),
+		int sgckey)
+	{
+	int i, j, ret = 0;
+	int rsalen, pkeylen, olen;
+	NETSCAPE_PKEY *pkey = NULL;
+	NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
+	unsigned char buf[256],*zz;
+	unsigned char key[EVP_MAX_KEY_LENGTH];
+	EVP_CIPHER_CTX ctx;
+
+	if (a == NULL) return(0);
+
+	if ((pkey=NETSCAPE_PKEY_new()) == NULL) goto err;
+	if ((enckey=NETSCAPE_ENCRYPTED_PKEY_new()) == NULL) goto err;
+	pkey->version = 0;
+
+	pkey->algor->algorithm=OBJ_nid2obj(NID_rsaEncryption);
+	if ((pkey->algor->parameter=ASN1_TYPE_new()) == NULL) goto err;
+	pkey->algor->parameter->type=V_ASN1_NULL;
+
+	rsalen = i2d_RSAPrivateKey(a, NULL);
+
+	/* Fake some octet strings just for the initial length
+	 * calculation.
+ 	 */
+
+	pkey->private_key->length=rsalen;
+
+	pkeylen=i2d_NETSCAPE_PKEY(pkey,NULL);
+
+	enckey->enckey->digest->length = pkeylen;
+
+	enckey->os->length = 11;	/* "private-key" */
+
+	enckey->enckey->algor->algorithm=OBJ_nid2obj(NID_rc4);
+	if ((enckey->enckey->algor->parameter=ASN1_TYPE_new()) == NULL) goto err;
+	enckey->enckey->algor->parameter->type=V_ASN1_NULL;
+
+	if (pp == NULL)
+		{
+		olen = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, NULL);
+		NETSCAPE_PKEY_free(pkey);
+		NETSCAPE_ENCRYPTED_PKEY_free(enckey);
+		return olen;
+		}
+
+
+	/* Since its RC4 encrypted length is actual length */
+	if ((zz=(unsigned char *)OPENSSL_malloc(rsalen)) == NULL)
+		{
+		ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	pkey->private_key->data = zz;
+	/* Write out private key encoding */
+	i2d_RSAPrivateKey(a,&zz);
+
+	if ((zz=OPENSSL_malloc(pkeylen)) == NULL)
+		{
+		ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (!ASN1_STRING_set(enckey->os, "private-key", -1)) 
+		{
+		ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	enckey->enckey->digest->data = zz;
+	i2d_NETSCAPE_PKEY(pkey,&zz);
+
+	/* Wipe the private key encoding */
+	OPENSSL_cleanse(pkey->private_key->data, rsalen);
+		
+	if (cb == NULL)
+		cb=EVP_read_pw_string;
+	i=cb((char *)buf,256,"Enter Private Key password:",1);
+	if (i != 0)
+		{
+		ASN1err(ASN1_F_I2D_RSA_NET,ASN1_R_BAD_PASSWORD_READ);
+		goto err;
+		}
+	i = strlen((char *)buf);
+	/* If the key is used for SGC the algorithm is modified a little. */
+	if(sgckey) {
+		EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL);
+		memcpy(buf + 16, "SGCKEYSALT", 10);
+		i = 26;
+	}
+
+	EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL);
+	OPENSSL_cleanse(buf,256);
+
+	/* Encrypt private key in place */
+	zz = enckey->enckey->digest->data;
+	EVP_CIPHER_CTX_init(&ctx);
+	EVP_EncryptInit_ex(&ctx,EVP_rc4(),NULL,key,NULL);
+	EVP_EncryptUpdate(&ctx,zz,&i,zz,pkeylen);
+	EVP_EncryptFinal_ex(&ctx,zz + i,&j);
+	EVP_CIPHER_CTX_cleanup(&ctx);
+
+	ret = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, pp);
+err:
+	NETSCAPE_ENCRYPTED_PKEY_free(enckey);
+	NETSCAPE_PKEY_free(pkey);
+	return(ret);
+	}
+
+
+RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
+		      int (*cb)(char *buf, int len, const char *prompt,
+				int verify))
+{
+	return d2i_RSA_NET(a, pp, length, cb, 0);
+}
+
+RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
+		 int (*cb)(char *buf, int len, const char *prompt, int verify),
+		 int sgckey)
+	{
+	RSA *ret=NULL;
+	const unsigned char *p;
+	NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
+
+	p = *pp;
+
+	enckey = d2i_NETSCAPE_ENCRYPTED_PKEY(NULL, &p, length);
+	if(!enckey) {
+		ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_DECODING_ERROR);
+		return NULL;
+	}
+
+	if ((enckey->os->length != 11) || (strncmp("private-key",
+		(char *)enckey->os->data,11) != 0))
+		{
+		ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_PRIVATE_KEY_HEADER_MISSING);
+		NETSCAPE_ENCRYPTED_PKEY_free(enckey);
+		return NULL;
+		}
+	if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4)
+		{
+		ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM);
+		goto err;
+	}
+	if (cb == NULL)
+		cb=EVP_read_pw_string;
+	if ((ret=d2i_RSA_NET_2(a, enckey->enckey->digest,cb, sgckey)) == NULL) goto err;
+
+	*pp = p;
+
+	err:
+	NETSCAPE_ENCRYPTED_PKEY_free(enckey);
+	return ret;
+
+	}
+
+static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
+			  int (*cb)(char *buf, int len, const char *prompt,
+				    int verify), int sgckey)
+	{
+	NETSCAPE_PKEY *pkey=NULL;
+	RSA *ret=NULL;
+	int i,j;
+	unsigned char buf[256];
+	const unsigned char *zz;
+	unsigned char key[EVP_MAX_KEY_LENGTH];
+	EVP_CIPHER_CTX ctx;
+
+	i=cb((char *)buf,256,"Enter Private Key password:",0);
+	if (i != 0)
+		{
+		ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_BAD_PASSWORD_READ);
+		goto err;
+		}
+
+	i = strlen((char *)buf);
+	if(sgckey){
+		EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL);
+		memcpy(buf + 16, "SGCKEYSALT", 10);
+		i = 26;
+	}
+		
+	EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL);
+	OPENSSL_cleanse(buf,256);
+
+	EVP_CIPHER_CTX_init(&ctx);
+	EVP_DecryptInit_ex(&ctx,EVP_rc4(),NULL, key,NULL);
+	EVP_DecryptUpdate(&ctx,os->data,&i,os->data,os->length);
+	EVP_DecryptFinal_ex(&ctx,&(os->data[i]),&j);
+	EVP_CIPHER_CTX_cleanup(&ctx);
+	os->length=i+j;
+
+	zz=os->data;
+
+	if ((pkey=d2i_NETSCAPE_PKEY(NULL,&zz,os->length)) == NULL)
+		{
+		ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY);
+		goto err;
+		}
+		
+	zz=pkey->private_key->data;
+	if ((ret=d2i_RSAPrivateKey(a,&zz,pkey->private_key->length)) == NULL)
+		{
+		ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_UNABLE_TO_DECODE_RSA_KEY);
+		goto err;
+		}
+err:
+	NETSCAPE_PKEY_free(pkey);
+	return(ret);
+	}
+
+#endif /* OPENSSL_NO_RC4 */
+
+#else /* !OPENSSL_NO_RSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/crypto/asn1/nsseq.c b/openssl/crypto/asn1/nsseq.c
new file mode 100644
index 0000000..b8c4202
--- /dev/null
+++ b/openssl/crypto/asn1/nsseq.c
@@ -0,0 +1,83 @@
+/* nsseq.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+
+static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
+{
+	if(operation == ASN1_OP_NEW_POST) {
+		NETSCAPE_CERT_SEQUENCE *nsseq;
+		nsseq = (NETSCAPE_CERT_SEQUENCE *)*pval;
+		nsseq->type = OBJ_nid2obj(NID_netscape_cert_sequence);
+	}
+	return 1;
+}
+
+/* Netscape certificate sequence structure */
+
+ASN1_SEQUENCE_cb(NETSCAPE_CERT_SEQUENCE, nsseq_cb) = {
+	ASN1_SIMPLE(NETSCAPE_CERT_SEQUENCE, type, ASN1_OBJECT),
+	ASN1_EXP_SEQUENCE_OF_OPT(NETSCAPE_CERT_SEQUENCE, certs, X509, 0)
+} ASN1_SEQUENCE_END_cb(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE)
+
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
diff --git a/openssl/crypto/asn1/p5_pbe.c b/openssl/crypto/asn1/p5_pbe.c
new file mode 100644
index 0000000..94bc38b
--- /dev/null
+++ b/openssl/crypto/asn1/p5_pbe.c
@@ -0,0 +1,148 @@
+/* p5_pbe.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rand.h>
+
+/* PKCS#5 password based encryption structure */
+
+ASN1_SEQUENCE(PBEPARAM) = {
+	ASN1_SIMPLE(PBEPARAM, salt, ASN1_OCTET_STRING),
+	ASN1_SIMPLE(PBEPARAM, iter, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(PBEPARAM)
+
+IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM)
+
+
+/* Set an algorithm identifier for a PKCS#5 PBE algorithm */
+
+int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
+				const unsigned char *salt, int saltlen)
+	{
+	PBEPARAM *pbe=NULL;
+	ASN1_STRING *pbe_str=NULL;
+	unsigned char *sstr;
+
+	pbe = PBEPARAM_new();
+	if (!pbe)
+		{
+		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	if(iter <= 0)
+		iter = PKCS5_DEFAULT_ITER;
+	if (!ASN1_INTEGER_set(pbe->iter, iter))
+		{
+		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	if (!saltlen)
+		saltlen = PKCS5_SALT_LEN;
+	if (!ASN1_STRING_set(pbe->salt, NULL, saltlen))
+		{
+		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	sstr = ASN1_STRING_data(pbe->salt);
+	if (salt)
+		memcpy(sstr, salt, saltlen);
+	else if (RAND_pseudo_bytes(sstr, saltlen) < 0)
+		goto err;
+
+	if(!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str))
+		{
+		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	PBEPARAM_free(pbe);
+	pbe = NULL;
+
+	if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
+		return 1;
+
+err:
+	if (pbe != NULL)
+		PBEPARAM_free(pbe);
+	if (pbe_str != NULL)
+		ASN1_STRING_free(pbe_str);
+	return 0;
+	}
+
+/* Return an algorithm identifier for a PKCS#5 PBE algorithm */
+
+X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
+				const unsigned char *salt, int saltlen)
+	{
+	X509_ALGOR *ret;
+	ret = X509_ALGOR_new();
+	if (!ret)
+		{
+		ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+
+	if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen)) 
+		return ret;
+
+	X509_ALGOR_free(ret);
+	return NULL;
+	}
diff --git a/openssl/crypto/asn1/p5_pbev2.c b/openssl/crypto/asn1/p5_pbev2.c
new file mode 100644
index 0000000..cb49b66
--- /dev/null
+++ b/openssl/crypto/asn1/p5_pbev2.c
@@ -0,0 +1,235 @@
+/* p5_pbev2.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999-2004.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rand.h>
+
+/* PKCS#5 v2.0 password based encryption structures */
+
+ASN1_SEQUENCE(PBE2PARAM) = {
+	ASN1_SIMPLE(PBE2PARAM, keyfunc, X509_ALGOR),
+	ASN1_SIMPLE(PBE2PARAM, encryption, X509_ALGOR)
+} ASN1_SEQUENCE_END(PBE2PARAM)
+
+IMPLEMENT_ASN1_FUNCTIONS(PBE2PARAM)
+
+ASN1_SEQUENCE(PBKDF2PARAM) = {
+	ASN1_SIMPLE(PBKDF2PARAM, salt, ASN1_ANY),
+	ASN1_SIMPLE(PBKDF2PARAM, iter, ASN1_INTEGER),
+	ASN1_OPT(PBKDF2PARAM, keylength, ASN1_INTEGER),
+	ASN1_OPT(PBKDF2PARAM, prf, X509_ALGOR)
+} ASN1_SEQUENCE_END(PBKDF2PARAM)
+
+IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM)
+
+/* Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm:
+ * yes I know this is horrible!
+ *
+ * Extended version to allow application supplied PRF NID and IV.
+ */
+
+X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
+				 unsigned char *salt, int saltlen,
+				 unsigned char *aiv, int prf_nid)
+{
+	X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
+	int alg_nid;
+	EVP_CIPHER_CTX ctx;
+	unsigned char iv[EVP_MAX_IV_LENGTH];
+	PBKDF2PARAM *kdf = NULL;
+	PBE2PARAM *pbe2 = NULL;
+	ASN1_OCTET_STRING *osalt = NULL;
+	ASN1_OBJECT *obj;
+
+	alg_nid = EVP_CIPHER_type(cipher);
+	if(alg_nid == NID_undef) {
+		ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
+				ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
+		goto err;
+	}
+	obj = OBJ_nid2obj(alg_nid);
+
+	if(!(pbe2 = PBE2PARAM_new())) goto merr;
+
+	/* Setup the AlgorithmIdentifier for the encryption scheme */
+	scheme = pbe2->encryption;
+
+	scheme->algorithm = obj;
+	if(!(scheme->parameter = ASN1_TYPE_new())) goto merr;
+
+	/* Create random IV */
+	if (EVP_CIPHER_iv_length(cipher))
+		{
+		if (aiv)
+			memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
+		else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
+  			goto err;
+		}
+
+	EVP_CIPHER_CTX_init(&ctx);
+
+	/* Dummy cipherinit to just setup the IV, and PRF */
+	EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0);
+	if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
+		ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
+					ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
+		EVP_CIPHER_CTX_cleanup(&ctx);
+		goto err;
+	}
+	/* If prf NID unspecified see if cipher has a preference.
+	 * An error is OK here: just means use default PRF.
+	 */
+	if ((prf_nid == -1) && 
+	EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0)
+		{
+		ERR_clear_error();
+		prf_nid = NID_hmacWithSHA1;
+		}
+	EVP_CIPHER_CTX_cleanup(&ctx);
+
+	if(!(kdf = PBKDF2PARAM_new())) goto merr;
+	if(!(osalt = M_ASN1_OCTET_STRING_new())) goto merr;
+
+	if (!saltlen) saltlen = PKCS5_SALT_LEN;
+	if (!(osalt->data = OPENSSL_malloc (saltlen))) goto merr;
+	osalt->length = saltlen;
+	if (salt) memcpy (osalt->data, salt, saltlen);
+	else if (RAND_pseudo_bytes (osalt->data, saltlen) < 0) goto merr;
+
+	if(iter <= 0) iter = PKCS5_DEFAULT_ITER;
+	if(!ASN1_INTEGER_set(kdf->iter, iter)) goto merr;
+
+	/* Now include salt in kdf structure */
+	kdf->salt->value.octet_string = osalt;
+	kdf->salt->type = V_ASN1_OCTET_STRING;
+	osalt = NULL;
+
+	/* If its RC2 then we'd better setup the key length */
+
+	if(alg_nid == NID_rc2_cbc) {
+		if(!(kdf->keylength = M_ASN1_INTEGER_new())) goto merr;
+		if(!ASN1_INTEGER_set (kdf->keylength,
+				 EVP_CIPHER_key_length(cipher))) goto merr;
+	}
+
+	/* prf can stay NULL if we are using hmacWithSHA1 */
+	if (prf_nid != NID_hmacWithSHA1)
+		{
+		kdf->prf = X509_ALGOR_new();
+		if (!kdf->prf)
+			goto merr;
+		X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid),
+					V_ASN1_NULL, NULL);
+		}
+
+	/* Now setup the PBE2PARAM keyfunc structure */
+
+	pbe2->keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
+
+	/* Encode PBKDF2PARAM into parameter of pbe2 */
+
+	if(!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr;
+
+	if(!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
+			 &pbe2->keyfunc->parameter->value.sequence)) goto merr;
+	pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE;
+
+	PBKDF2PARAM_free(kdf);
+	kdf = NULL;
+
+	/* Now set up top level AlgorithmIdentifier */
+
+	if(!(ret = X509_ALGOR_new())) goto merr;
+	if(!(ret->parameter = ASN1_TYPE_new())) goto merr;
+
+	ret->algorithm = OBJ_nid2obj(NID_pbes2);
+
+	/* Encode PBE2PARAM into parameter */
+
+	if(!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
+				 &ret->parameter->value.sequence)) goto merr;
+	ret->parameter->type = V_ASN1_SEQUENCE;
+
+	PBE2PARAM_free(pbe2);
+	pbe2 = NULL;
+
+	return ret;
+
+	merr:
+	ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,ERR_R_MALLOC_FAILURE);
+
+	err:
+	PBE2PARAM_free(pbe2);
+	/* Note 'scheme' is freed as part of pbe2 */
+	M_ASN1_OCTET_STRING_free(osalt);
+	PBKDF2PARAM_free(kdf);
+	X509_ALGOR_free(kalg);
+	X509_ALGOR_free(ret);
+
+	return NULL;
+
+}
+
+X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
+				 unsigned char *salt, int saltlen)
+	{
+	return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1);
+	}
diff --git a/openssl/crypto/asn1/p8_pkey.c b/openssl/crypto/asn1/p8_pkey.c
new file mode 100644
index 0000000..17b68d3
--- /dev/null
+++ b/openssl/crypto/asn1/p8_pkey.c
@@ -0,0 +1,155 @@
+/* p8_pkey.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+
+/* Minor tweak to operation: zero private key data */
+static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
+{
+	/* Since the structure must still be valid use ASN1_OP_FREE_PRE */
+	if(operation == ASN1_OP_FREE_PRE) {
+		PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval;
+		if (key->pkey->value.octet_string)
+		OPENSSL_cleanse(key->pkey->value.octet_string->data,
+			key->pkey->value.octet_string->length);
+	}
+	return 1;
+}
+
+ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = {
+	ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER),
+	ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR),
+	ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_ANY),
+	ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0)
+} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
+
+int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
+					int version,
+					int ptype, void *pval,
+					unsigned char *penc, int penclen)
+	{
+	unsigned char **ppenc = NULL;
+	if (version >= 0)
+		{
+		if (!ASN1_INTEGER_set(priv->version, version))
+			return 0;
+		}
+	if (penc)
+		{
+		int pmtype;
+		ASN1_OCTET_STRING *oct;
+		oct = ASN1_OCTET_STRING_new();
+		if (!oct)
+			return 0;
+		oct->data = penc;
+		ppenc = &oct->data;
+		oct->length = penclen;
+		if (priv->broken == PKCS8_NO_OCTET)
+			pmtype = V_ASN1_SEQUENCE;
+		else
+			pmtype = V_ASN1_OCTET_STRING;
+		ASN1_TYPE_set(priv->pkey, pmtype, oct);
+		}
+	if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval))
+		{
+		/* If call fails do not swallow 'enc' */
+		if (ppenc)
+			*ppenc = NULL;
+		return 0;
+		}
+	return 1;
+	}
+
+int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
+		const unsigned char **pk, int *ppklen,
+		X509_ALGOR **pa,
+		PKCS8_PRIV_KEY_INFO *p8)
+	{
+	if (ppkalg)
+		*ppkalg = p8->pkeyalg->algorithm;
+	if(p8->pkey->type == V_ASN1_OCTET_STRING)
+		{
+		p8->broken = PKCS8_OK;
+		if (pk)
+			{
+			*pk = p8->pkey->value.octet_string->data;
+			*ppklen = p8->pkey->value.octet_string->length;
+			}
+		}
+	else if (p8->pkey->type == V_ASN1_SEQUENCE)
+		{
+		p8->broken = PKCS8_NO_OCTET;
+		if (pk)
+			{
+			*pk = p8->pkey->value.sequence->data;
+			*ppklen = p8->pkey->value.sequence->length;
+			}
+		}
+	else
+		return 0;
+	if (pa)
+		*pa = p8->pkeyalg;
+	return 1;
+	}
+
diff --git a/openssl/crypto/asn1/t_bitst.c b/openssl/crypto/asn1/t_bitst.c
new file mode 100644
index 0000000..2e59a25
--- /dev/null
+++ b/openssl/crypto/asn1/t_bitst.c
@@ -0,0 +1,102 @@
+/* t_bitst.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
+				BIT_STRING_BITNAME *tbl, int indent)
+{
+	BIT_STRING_BITNAME *bnam;
+	char first = 1;
+	BIO_printf(out, "%*s", indent, "");
+	for(bnam = tbl; bnam->lname; bnam++) {
+		if(ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
+			if(!first) BIO_puts(out, ", ");
+			BIO_puts(out, bnam->lname);
+			first = 0;
+		}
+	}
+	BIO_puts(out, "\n");
+	return 1;
+}
+
+int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
+				BIT_STRING_BITNAME *tbl)
+{
+	int bitnum;
+	bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
+	if(bitnum < 0) return 0;
+	if(bs) {
+		if(!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
+			return 0;
+	}
+	return 1;
+}
+
+int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl)
+{
+	BIT_STRING_BITNAME *bnam;
+	for(bnam = tbl; bnam->lname; bnam++) {
+		if(!strcmp(bnam->sname, name) ||
+			!strcmp(bnam->lname, name) ) return bnam->bitnum;
+	}
+	return -1;
+}
diff --git a/openssl/crypto/asn1/t_crl.c b/openssl/crypto/asn1/t_crl.c
new file mode 100644
index 0000000..ee5a687
--- /dev/null
+++ b/openssl/crypto/asn1/t_crl.c
@@ -0,0 +1,133 @@
+/* t_crl.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#ifndef OPENSSL_NO_FP_API
+int X509_CRL_print_fp(FILE *fp, X509_CRL *x)
+        {
+        BIO *b;
+        int ret;
+
+        if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		X509err(X509_F_X509_CRL_PRINT_FP,ERR_R_BUF_LIB);
+                return(0);
+		}
+        BIO_set_fp(b,fp,BIO_NOCLOSE);
+        ret=X509_CRL_print(b, x);
+        BIO_free(b);
+        return(ret);
+        }
+#endif
+
+int X509_CRL_print(BIO *out, X509_CRL *x)
+{
+	STACK_OF(X509_REVOKED) *rev;
+	X509_REVOKED *r;
+	long l;
+	int i;
+	char *p;
+
+	BIO_printf(out, "Certificate Revocation List (CRL):\n");
+	l = X509_CRL_get_version(x);
+	BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l+1, l);
+	i = OBJ_obj2nid(x->sig_alg->algorithm);
+	BIO_printf(out, "%8sSignature Algorithm: %s\n", "",
+				 (i == NID_undef) ? "NONE" : OBJ_nid2ln(i));
+	p=X509_NAME_oneline(X509_CRL_get_issuer(x),NULL,0);
+	BIO_printf(out,"%8sIssuer: %s\n","",p);
+	OPENSSL_free(p);
+	BIO_printf(out,"%8sLast Update: ","");
+	ASN1_TIME_print(out,X509_CRL_get_lastUpdate(x));
+	BIO_printf(out,"\n%8sNext Update: ","");
+	if (X509_CRL_get_nextUpdate(x))
+		 ASN1_TIME_print(out,X509_CRL_get_nextUpdate(x));
+	else BIO_printf(out,"NONE");
+	BIO_printf(out,"\n");
+
+	X509V3_extensions_print(out, "CRL extensions",
+						x->crl->extensions, 0, 8);
+
+	rev = X509_CRL_get_REVOKED(x);
+
+	if(sk_X509_REVOKED_num(rev) > 0)
+	    BIO_printf(out, "Revoked Certificates:\n");
+	else BIO_printf(out, "No Revoked Certificates.\n");
+
+	for(i = 0; i < sk_X509_REVOKED_num(rev); i++) {
+		r = sk_X509_REVOKED_value(rev, i);
+		BIO_printf(out,"    Serial Number: ");
+		i2a_ASN1_INTEGER(out,r->serialNumber);
+		BIO_printf(out,"\n        Revocation Date: ");
+		ASN1_TIME_print(out,r->revocationDate);
+		BIO_printf(out,"\n");
+		X509V3_extensions_print(out, "CRL entry extensions",
+						r->extensions, 0, 8);
+	}
+	X509_signature_print(out, x->sig_alg, x->signature);
+
+	return 1;
+
+}
diff --git a/openssl/crypto/asn1/t_pkey.c b/openssl/crypto/asn1/t_pkey.c
new file mode 100644
index 0000000..9dd18f6
--- /dev/null
+++ b/openssl/crypto/asn1/t_pkey.c
@@ -0,0 +1,114 @@
+/* crypto/asn1/t_pkey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+
+int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
+			unsigned char *buf, int off)
+	{
+	int n,i;
+	const char *neg;
+
+	if (num == NULL) return(1);
+	neg = (BN_is_negative(num))?"-":"";
+	if(!BIO_indent(bp,off,128))
+		return 0;
+	if (BN_is_zero(num))
+		{
+		if (BIO_printf(bp, "%s 0\n", number) <= 0)
+			return 0;
+		return 1;
+		}
+
+	if (BN_num_bytes(num) <= BN_BYTES)
+		{
+		if (BIO_printf(bp,"%s %s%lu (%s0x%lx)\n",number,neg,
+			(unsigned long)num->d[0],neg,(unsigned long)num->d[0])
+			<= 0) return(0);
+		}
+	else
+		{
+		buf[0]=0;
+		if (BIO_printf(bp,"%s%s",number,
+			(neg[0] == '-')?" (Negative)":"") <= 0)
+			return(0);
+		n=BN_bn2bin(num,&buf[1]);
+	
+		if (buf[1] & 0x80)
+			n++;
+		else	buf++;
+
+		for (i=0; i<n; i++)
+			{
+			if ((i%15) == 0)
+				{
+				if(BIO_puts(bp,"\n") <= 0
+				   || !BIO_indent(bp,off+4,128))
+				    return 0;
+				}
+			if (BIO_printf(bp,"%02x%s",buf[i],((i+1) == n)?"":":")
+				<= 0) return(0);
+			}
+		if (BIO_write(bp,"\n",1) <= 0) return(0);
+		}
+	return(1);
+	}
diff --git a/openssl/crypto/asn1/t_req.c b/openssl/crypto/asn1/t_req.c
new file mode 100644
index 0000000..ea1794e
--- /dev/null
+++ b/openssl/crypto/asn1/t_req.c
@@ -0,0 +1,266 @@
+/* crypto/asn1/t_req.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+
+#ifndef OPENSSL_NO_FP_API
+int X509_REQ_print_fp(FILE *fp, X509_REQ *x)
+        {
+        BIO *b;
+        int ret;
+
+        if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		X509err(X509_F_X509_REQ_PRINT_FP,ERR_R_BUF_LIB);
+                return(0);
+		}
+        BIO_set_fp(b,fp,BIO_NOCLOSE);
+        ret=X509_REQ_print(b, x);
+        BIO_free(b);
+        return(ret);
+        }
+#endif
+
+int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long cflag)
+	{
+	unsigned long l;
+	int i;
+	const char *neg;
+	X509_REQ_INFO *ri;
+	EVP_PKEY *pkey;
+	STACK_OF(X509_ATTRIBUTE) *sk;
+	STACK_OF(X509_EXTENSION) *exts;
+	char mlch = ' ';
+	int nmindent = 0;
+
+	if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+		mlch = '\n';
+		nmindent = 12;
+	}
+
+	if(nmflags == X509_FLAG_COMPAT)
+		nmindent = 16;
+
+
+	ri=x->req_info;
+	if(!(cflag & X509_FLAG_NO_HEADER))
+		{
+		if (BIO_write(bp,"Certificate Request:\n",21) <= 0) goto err;
+		if (BIO_write(bp,"    Data:\n",10) <= 0) goto err;
+		}
+	if(!(cflag & X509_FLAG_NO_VERSION))
+		{
+		neg=(ri->version->type == V_ASN1_NEG_INTEGER)?"-":"";
+		l=0;
+		for (i=0; i<ri->version->length; i++)
+			{ l<<=8; l+=ri->version->data[i]; }
+		if(BIO_printf(bp,"%8sVersion: %s%lu (%s0x%lx)\n","",neg,l,neg,
+			      l) <= 0)
+		    goto err;
+		}
+        if(!(cflag & X509_FLAG_NO_SUBJECT))
+                {
+                if (BIO_printf(bp,"        Subject:%c",mlch) <= 0) goto err;
+                if (X509_NAME_print_ex(bp,ri->subject,nmindent, nmflags) < 0) goto err;
+                if (BIO_write(bp,"\n",1) <= 0) goto err;
+                }
+	if(!(cflag & X509_FLAG_NO_PUBKEY))
+		{
+		if (BIO_write(bp,"        Subject Public Key Info:\n",33) <= 0)
+			goto err;
+		if (BIO_printf(bp,"%12sPublic Key Algorithm: ","") <= 0)
+			goto err;
+		if (i2a_ASN1_OBJECT(bp, ri->pubkey->algor->algorithm) <= 0)
+			goto err;
+		if (BIO_puts(bp, "\n") <= 0)
+			goto err;
+
+		pkey=X509_REQ_get_pubkey(x);
+		if (pkey == NULL)
+			{
+			BIO_printf(bp,"%12sUnable to load Public Key\n","");
+			ERR_print_errors(bp);
+			}
+		else
+			{
+			EVP_PKEY_print_public(bp, pkey, 16, NULL);
+			EVP_PKEY_free(pkey);
+			}
+		}
+
+	if(!(cflag & X509_FLAG_NO_ATTRIBUTES))
+		{
+		/* may not be */
+		if(BIO_printf(bp,"%8sAttributes:\n","") <= 0)
+		    goto err;
+
+		sk=x->req_info->attributes;
+		if (sk_X509_ATTRIBUTE_num(sk) == 0)
+			{
+			if(BIO_printf(bp,"%12sa0:00\n","") <= 0)
+			    goto err;
+			}
+		else
+			{
+			for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
+				{
+				ASN1_TYPE *at;
+				X509_ATTRIBUTE *a;
+				ASN1_BIT_STRING *bs=NULL;
+				ASN1_TYPE *t;
+				int j,type=0,count=1,ii=0;
+
+				a=sk_X509_ATTRIBUTE_value(sk,i);
+				if(X509_REQ_extension_nid(OBJ_obj2nid(a->object)))
+									continue;
+				if(BIO_printf(bp,"%12s","") <= 0)
+				    goto err;
+				if ((j=i2a_ASN1_OBJECT(bp,a->object)) > 0)
+				{
+				if (a->single)
+					{
+					t=a->value.single;
+					type=t->type;
+					bs=t->value.bit_string;
+					}
+				else
+					{
+					ii=0;
+					count=sk_ASN1_TYPE_num(a->value.set);
+get_next:
+					at=sk_ASN1_TYPE_value(a->value.set,ii);
+					type=at->type;
+					bs=at->value.asn1_string;
+					}
+				}
+				for (j=25-j; j>0; j--)
+					if (BIO_write(bp," ",1) != 1) goto err;
+				if (BIO_puts(bp,":") <= 0) goto err;
+				if (	(type == V_ASN1_PRINTABLESTRING) ||
+					(type == V_ASN1_T61STRING) ||
+					(type == V_ASN1_IA5STRING))
+					{
+					if (BIO_write(bp,(char *)bs->data,bs->length)
+						!= bs->length)
+						goto err;
+					BIO_puts(bp,"\n");
+					}
+				else
+					{
+					BIO_puts(bp,"unable to print attribute\n");
+					}
+				if (++ii < count) goto get_next;
+				}
+			}
+		}
+	if(!(cflag & X509_FLAG_NO_EXTENSIONS))
+		{
+		exts = X509_REQ_get_extensions(x);
+		if(exts)
+			{
+			BIO_printf(bp,"%8sRequested Extensions:\n","");
+			for (i=0; i<sk_X509_EXTENSION_num(exts); i++)
+				{
+				ASN1_OBJECT *obj;
+				X509_EXTENSION *ex;
+				int j;
+				ex=sk_X509_EXTENSION_value(exts, i);
+				if (BIO_printf(bp,"%12s","") <= 0) goto err;
+				obj=X509_EXTENSION_get_object(ex);
+				i2a_ASN1_OBJECT(bp,obj);
+				j=X509_EXTENSION_get_critical(ex);
+				if (BIO_printf(bp,": %s\n",j?"critical":"") <= 0)
+					goto err;
+				if(!X509V3_EXT_print(bp, ex, cflag, 16))
+					{
+					BIO_printf(bp, "%16s", "");
+					M_ASN1_OCTET_STRING_print(bp,ex->value);
+					}
+				if (BIO_write(bp,"\n",1) <= 0) goto err;
+				}
+			sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+			}
+		}
+
+	if(!(cflag & X509_FLAG_NO_SIGDUMP))
+		{
+		if(!X509_signature_print(bp, x->sig_alg, x->signature)) goto err;
+		}
+
+	return(1);
+err:
+	X509err(X509_F_X509_REQ_PRINT_EX,ERR_R_BUF_LIB);
+	return(0);
+	}
+
+int X509_REQ_print(BIO *bp, X509_REQ *x)
+	{
+	return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+	}
diff --git a/openssl/crypto/asn1/t_spki.c b/openssl/crypto/asn1/t_spki.c
new file mode 100644
index 0000000..079c081
--- /dev/null
+++ b/openssl/crypto/asn1/t_spki.c
@@ -0,0 +1,107 @@
+/* t_spki.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#include <openssl/bn.h>
+
+/* Print out an SPKI */
+
+int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki)
+{
+	EVP_PKEY *pkey;
+	ASN1_IA5STRING *chal;
+	int i, n;
+	char *s;
+	BIO_printf(out, "Netscape SPKI:\n");
+	i=OBJ_obj2nid(spki->spkac->pubkey->algor->algorithm);
+	BIO_printf(out,"  Public Key Algorithm: %s\n",
+				(i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i));
+	pkey = X509_PUBKEY_get(spki->spkac->pubkey);
+	if(!pkey) BIO_printf(out, "  Unable to load public key\n");
+	else
+		{
+		EVP_PKEY_print_public(out, pkey, 4, NULL);
+		EVP_PKEY_free(pkey);
+		}
+	chal = spki->spkac->challenge;
+	if(chal->length)
+		BIO_printf(out, "  Challenge String: %s\n", chal->data);
+	i=OBJ_obj2nid(spki->sig_algor->algorithm);
+	BIO_printf(out,"  Signature Algorithm: %s",
+				(i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i));
+
+	n=spki->signature->length;
+	s=(char *)spki->signature->data;
+	for (i=0; i<n; i++)
+		{
+		if ((i%18) == 0) BIO_write(out,"\n      ",7);
+		BIO_printf(out,"%02x%s",(unsigned char)s[i],
+						((i+1) == n)?"":":");
+		}
+	BIO_write(out,"\n",1);
+	return 1;
+}
diff --git a/openssl/crypto/asn1/t_x509.c b/openssl/crypto/asn1/t_x509.c
new file mode 100644
index 0000000..e061f2f
--- /dev/null
+++ b/openssl/crypto/asn1/t_x509.c
@@ -0,0 +1,493 @@
+/* crypto/asn1/t_x509.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_EC
+#include <openssl/ec.h>
+#endif
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#ifndef OPENSSL_NO_FP_API
+int X509_print_fp(FILE *fp, X509 *x)
+	{
+	return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+	}
+
+int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, unsigned long cflag)
+        {
+        BIO *b;
+        int ret;
+
+        if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		X509err(X509_F_X509_PRINT_EX_FP,ERR_R_BUF_LIB);
+                return(0);
+		}
+        BIO_set_fp(b,fp,BIO_NOCLOSE);
+        ret=X509_print_ex(b, x, nmflag, cflag);
+        BIO_free(b);
+        return(ret);
+        }
+#endif
+
+int X509_print(BIO *bp, X509 *x)
+{
+	return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
+
+int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
+	{
+	long l;
+	int ret=0,i;
+	char *m=NULL,mlch = ' ';
+	int nmindent = 0;
+	X509_CINF *ci;
+	ASN1_INTEGER *bs;
+	EVP_PKEY *pkey=NULL;
+	const char *neg;
+
+	if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+			mlch = '\n';
+			nmindent = 12;
+	}
+
+	if(nmflags == X509_FLAG_COMPAT)
+		nmindent = 16;
+
+	ci=x->cert_info;
+	if(!(cflag & X509_FLAG_NO_HEADER))
+		{
+		if (BIO_write(bp,"Certificate:\n",13) <= 0) goto err;
+		if (BIO_write(bp,"    Data:\n",10) <= 0) goto err;
+		}
+	if(!(cflag & X509_FLAG_NO_VERSION))
+		{
+		l=X509_get_version(x);
+		if (BIO_printf(bp,"%8sVersion: %lu (0x%lx)\n","",l+1,l) <= 0) goto err;
+		}
+	if(!(cflag & X509_FLAG_NO_SERIAL))
+		{
+
+		if (BIO_write(bp,"        Serial Number:",22) <= 0) goto err;
+
+		bs=X509_get_serialNumber(x);
+		if (bs->length <= 4)
+			{
+			l=ASN1_INTEGER_get(bs);
+			if (l < 0)
+				{
+				l= -l;
+				neg="-";
+				}
+			else
+				neg="";
+			if (BIO_printf(bp," %s%lu (%s0x%lx)\n",neg,l,neg,l) <= 0)
+				goto err;
+			}
+		else
+			{
+			neg=(bs->type == V_ASN1_NEG_INTEGER)?" (Negative)":"";
+			if (BIO_printf(bp,"\n%12s%s","",neg) <= 0) goto err;
+
+			for (i=0; i<bs->length; i++)
+				{
+				if (BIO_printf(bp,"%02x%c",bs->data[i],
+					((i+1 == bs->length)?'\n':':')) <= 0)
+					goto err;
+				}
+			}
+
+		}
+
+	if(!(cflag & X509_FLAG_NO_SIGNAME))
+		{
+		if (BIO_printf(bp,"%8sSignature Algorithm: ","") <= 0) 
+			goto err;
+		if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0)
+			goto err;
+		if (BIO_puts(bp, "\n") <= 0)
+			goto err;
+		}
+
+	if(!(cflag & X509_FLAG_NO_ISSUER))
+		{
+		if (BIO_printf(bp,"        Issuer:%c",mlch) <= 0) goto err;
+		if (X509_NAME_print_ex(bp,X509_get_issuer_name(x),nmindent, nmflags) < 0) goto err;
+		if (BIO_write(bp,"\n",1) <= 0) goto err;
+		}
+	if(!(cflag & X509_FLAG_NO_VALIDITY))
+		{
+		if (BIO_write(bp,"        Validity\n",17) <= 0) goto err;
+		if (BIO_write(bp,"            Not Before: ",24) <= 0) goto err;
+		if (!ASN1_TIME_print(bp,X509_get_notBefore(x))) goto err;
+		if (BIO_write(bp,"\n            Not After : ",25) <= 0) goto err;
+		if (!ASN1_TIME_print(bp,X509_get_notAfter(x))) goto err;
+		if (BIO_write(bp,"\n",1) <= 0) goto err;
+		}
+	if(!(cflag & X509_FLAG_NO_SUBJECT))
+		{
+		if (BIO_printf(bp,"        Subject:%c",mlch) <= 0) goto err;
+		if (X509_NAME_print_ex(bp,X509_get_subject_name(x),nmindent, nmflags) < 0) goto err;
+		if (BIO_write(bp,"\n",1) <= 0) goto err;
+		}
+	if(!(cflag & X509_FLAG_NO_PUBKEY))
+		{
+		if (BIO_write(bp,"        Subject Public Key Info:\n",33) <= 0)
+			goto err;
+		if (BIO_printf(bp,"%12sPublic Key Algorithm: ","") <= 0)
+			goto err;
+		if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0)
+			goto err;
+		if (BIO_puts(bp, "\n") <= 0)
+			goto err;
+
+		pkey=X509_get_pubkey(x);
+		if (pkey == NULL)
+			{
+			BIO_printf(bp,"%12sUnable to load Public Key\n","");
+			ERR_print_errors(bp);
+			}
+		else
+			{
+			EVP_PKEY_print_public(bp, pkey, 16, NULL);
+			EVP_PKEY_free(pkey);
+			}
+		}
+
+	if (!(cflag & X509_FLAG_NO_EXTENSIONS))
+		X509V3_extensions_print(bp, "X509v3 extensions",
+					ci->extensions, cflag, 8);
+
+	if(!(cflag & X509_FLAG_NO_SIGDUMP))
+		{
+		if(X509_signature_print(bp, x->sig_alg, x->signature) <= 0) goto err;
+		}
+	if(!(cflag & X509_FLAG_NO_AUX))
+		{
+		if (!X509_CERT_AUX_print(bp, x->aux, 0)) goto err;
+		}
+	ret=1;
+err:
+	if (m != NULL) OPENSSL_free(m);
+	return(ret);
+	}
+
+int X509_ocspid_print (BIO *bp, X509 *x)
+	{
+	unsigned char *der=NULL ;
+	unsigned char *dertmp;
+	int derlen;
+	int i;
+	unsigned char SHA1md[SHA_DIGEST_LENGTH];
+
+	/* display the hash of the subject as it would appear
+	   in OCSP requests */
+	if (BIO_printf(bp,"        Subject OCSP hash: ") <= 0)
+		goto err;
+	derlen = i2d_X509_NAME(x->cert_info->subject, NULL);
+	if ((der = dertmp = (unsigned char *)OPENSSL_malloc (derlen)) == NULL)
+		goto err;
+	i2d_X509_NAME(x->cert_info->subject, &dertmp);
+
+	EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL);
+	for (i=0; i < SHA_DIGEST_LENGTH; i++)
+		{
+		if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0) goto err;
+		}
+	OPENSSL_free (der);
+	der=NULL;
+
+	/* display the hash of the public key as it would appear
+	   in OCSP requests */
+	if (BIO_printf(bp,"\n        Public key OCSP hash: ") <= 0)
+		goto err;
+
+	EVP_Digest(x->cert_info->key->public_key->data,
+		x->cert_info->key->public_key->length, SHA1md, NULL, EVP_sha1(), NULL);
+	for (i=0; i < SHA_DIGEST_LENGTH; i++)
+		{
+		if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0)
+			goto err;
+		}
+	BIO_printf(bp,"\n");
+
+	return (1);
+err:
+	if (der != NULL) OPENSSL_free(der);
+	return(0);
+	}
+
+int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
+{
+	unsigned char *s;
+	int i, n;
+	if (BIO_puts(bp,"    Signature Algorithm: ") <= 0) return 0;
+	if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) return 0;
+
+	n=sig->length;
+	s=sig->data;
+	for (i=0; i<n; i++)
+		{
+		if ((i%18) == 0)
+			if (BIO_write(bp,"\n        ",9) <= 0) return 0;
+			if (BIO_printf(bp,"%02x%s",s[i],
+				((i+1) == n)?"":":") <= 0) return 0;
+		}
+	if (BIO_write(bp,"\n",1) != 1) return 0;
+	return 1;
+}
+
+int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
+	{
+	int i,n;
+	char buf[80];
+	const char *p;
+
+	if (v == NULL) return(0);
+	n=0;
+	p=(const char *)v->data;
+	for (i=0; i<v->length; i++)
+		{
+		if ((p[i] > '~') || ((p[i] < ' ') &&
+			(p[i] != '\n') && (p[i] != '\r')))
+			buf[n]='.';
+		else
+			buf[n]=p[i];
+		n++;
+		if (n >= 80)
+			{
+			if (BIO_write(bp,buf,n) <= 0)
+				return(0);
+			n=0;
+			}
+		}
+	if (n > 0)
+		if (BIO_write(bp,buf,n) <= 0)
+			return(0);
+	return(1);
+	}
+
+int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
+{
+	if(tm->type == V_ASN1_UTCTIME) return ASN1_UTCTIME_print(bp, tm);
+	if(tm->type == V_ASN1_GENERALIZEDTIME)
+				return ASN1_GENERALIZEDTIME_print(bp, tm);
+	BIO_write(bp,"Bad time value",14);
+	return(0);
+}
+
+static const char *mon[12]=
+    {
+    "Jan","Feb","Mar","Apr","May","Jun",
+    "Jul","Aug","Sep","Oct","Nov","Dec"
+    };
+
+int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
+	{
+	char *v;
+	int gmt=0;
+	int i;
+	int y=0,M=0,d=0,h=0,m=0,s=0;
+	char *f = NULL;
+	int f_len = 0;
+
+	i=tm->length;
+	v=(char *)tm->data;
+
+	if (i < 12) goto err;
+	if (v[i-1] == 'Z') gmt=1;
+	for (i=0; i<12; i++)
+		if ((v[i] > '9') || (v[i] < '0')) goto err;
+	y= (v[0]-'0')*1000+(v[1]-'0')*100 + (v[2]-'0')*10+(v[3]-'0');
+	M= (v[4]-'0')*10+(v[5]-'0');
+	if ((M > 12) || (M < 1)) goto err;
+	d= (v[6]-'0')*10+(v[7]-'0');
+	h= (v[8]-'0')*10+(v[9]-'0');
+	m=  (v[10]-'0')*10+(v[11]-'0');
+	if (tm->length >= 14 &&
+	    (v[12] >= '0') && (v[12] <= '9') &&
+	    (v[13] >= '0') && (v[13] <= '9'))
+		{
+		s=  (v[12]-'0')*10+(v[13]-'0');
+		/* Check for fractions of seconds. */
+		if (tm->length >= 15 && v[14] == '.')
+			{
+			int l = tm->length;
+			f = &v[14];	/* The decimal point. */
+			f_len = 1;
+			while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
+				++f_len;
+			}
+		}
+
+	if (BIO_printf(bp,"%s %2d %02d:%02d:%02d%.*s %d%s",
+		mon[M-1],d,h,m,s,f_len,f,y,(gmt)?" GMT":"") <= 0)
+		return(0);
+	else
+		return(1);
+err:
+	BIO_write(bp,"Bad time value",14);
+	return(0);
+	}
+
+int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
+	{
+	const char *v;
+	int gmt=0;
+	int i;
+	int y=0,M=0,d=0,h=0,m=0,s=0;
+
+	i=tm->length;
+	v=(const char *)tm->data;
+
+	if (i < 10) goto err;
+	if (v[i-1] == 'Z') gmt=1;
+	for (i=0; i<10; i++)
+		if ((v[i] > '9') || (v[i] < '0')) goto err;
+	y= (v[0]-'0')*10+(v[1]-'0');
+	if (y < 50) y+=100;
+	M= (v[2]-'0')*10+(v[3]-'0');
+	if ((M > 12) || (M < 1)) goto err;
+	d= (v[4]-'0')*10+(v[5]-'0');
+	h= (v[6]-'0')*10+(v[7]-'0');
+	m=  (v[8]-'0')*10+(v[9]-'0');
+	if (tm->length >=12 &&
+	    (v[10] >= '0') && (v[10] <= '9') &&
+	    (v[11] >= '0') && (v[11] <= '9'))
+		s=  (v[10]-'0')*10+(v[11]-'0');
+
+	if (BIO_printf(bp,"%s %2d %02d:%02d:%02d %d%s",
+		mon[M-1],d,h,m,s,y+1900,(gmt)?" GMT":"") <= 0)
+		return(0);
+	else
+		return(1);
+err:
+	BIO_write(bp,"Bad time value",14);
+	return(0);
+	}
+
+int X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
+	{
+	char *s,*c,*b;
+	int ret=0,l,i;
+
+	l=80-2-obase;
+
+	b=X509_NAME_oneline(name,NULL,0);
+	if (!*b)
+		{
+		OPENSSL_free(b);
+		return 1;
+		}
+	s=b+1; /* skip the first slash */
+
+	c=s;
+	for (;;)
+		{
+#ifndef CHARSET_EBCDIC
+		if (	((*s == '/') &&
+				((s[1] >= 'A') && (s[1] <= 'Z') && (
+					(s[2] == '=') ||
+					((s[2] >= 'A') && (s[2] <= 'Z') &&
+					(s[3] == '='))
+				 ))) ||
+			(*s == '\0'))
+#else
+		if (	((*s == '/') &&
+				(isupper(s[1]) && (
+					(s[2] == '=') ||
+					(isupper(s[2]) &&
+					(s[3] == '='))
+				 ))) ||
+			(*s == '\0'))
+#endif
+			{
+			i=s-c;
+			if (BIO_write(bp,c,i) != i) goto err;
+			c=s+1;	/* skip following slash */
+			if (*s != '\0')
+				{
+				if (BIO_write(bp,", ",2) != 2) goto err;
+				}
+			l--;
+			}
+		if (*s == '\0') break;
+		s++;
+		l--;
+		}
+	
+	ret=1;
+	if (0)
+		{
+err:
+		X509err(X509_F_X509_NAME_PRINT,ERR_R_BUF_LIB);
+		}
+	OPENSSL_free(b);
+	return(ret);
+	}
diff --git a/openssl/crypto/asn1/t_x509a.c b/openssl/crypto/asn1/t_x509a.c
new file mode 100644
index 0000000..8b18801
--- /dev/null
+++ b/openssl/crypto/asn1/t_x509a.c
@@ -0,0 +1,110 @@
+/* t_x509a.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+
+/* X509_CERT_AUX and string set routines
+ */
+
+int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
+{
+	char oidstr[80], first;
+	int i;
+	if(!aux) return 1;
+	if(aux->trust) {
+		first = 1;
+		BIO_printf(out, "%*sTrusted Uses:\n%*s",
+						indent, "", indent + 2, "");
+		for(i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) {
+			if(!first) BIO_puts(out, ", ");
+			else first = 0;
+			OBJ_obj2txt(oidstr, sizeof oidstr,
+				sk_ASN1_OBJECT_value(aux->trust, i), 0);
+			BIO_puts(out, oidstr);
+		}
+		BIO_puts(out, "\n");
+	} else BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
+	if(aux->reject) {
+		first = 1;
+		BIO_printf(out, "%*sRejected Uses:\n%*s",
+						indent, "", indent + 2, "");
+		for(i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) {
+			if(!first) BIO_puts(out, ", ");
+			else first = 0;
+			OBJ_obj2txt(oidstr, sizeof oidstr,
+				sk_ASN1_OBJECT_value(aux->reject, i), 0);
+			BIO_puts(out, oidstr);
+		}
+		BIO_puts(out, "\n");
+	} else BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
+	if(aux->alias) BIO_printf(out, "%*sAlias: %s\n", indent, "",
+							aux->alias->data);
+	if(aux->keyid) {
+		BIO_printf(out, "%*sKey Id: ", indent, "");
+		for(i = 0; i < aux->keyid->length; i++) 
+			BIO_printf(out, "%s%02X", 
+				i ? ":" : "",
+				aux->keyid->data[i]);
+		BIO_write(out,"\n",1);
+	}
+	return 1;
+}
diff --git a/openssl/crypto/asn1/tasn_dec.c b/openssl/crypto/asn1/tasn_dec.c
new file mode 100644
index 0000000..87d7dfd
--- /dev/null
+++ b/openssl/crypto/asn1/tasn_dec.c
@@ -0,0 +1,1347 @@
+/* tasn_dec.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stddef.h>
+#include <string.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+
+static int asn1_check_eoc(const unsigned char **in, long len);
+static int asn1_find_end(const unsigned char **in, long len, char inf);
+
+static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
+			char inf, int tag, int aclass, int depth);
+
+static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen);
+
+static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
+				char *inf, char *cst,
+				const unsigned char **in, long len,
+				int exptag, int expclass, char opt,
+				ASN1_TLC *ctx);
+
+static int asn1_template_ex_d2i(ASN1_VALUE **pval,
+				const unsigned char **in, long len,
+				const ASN1_TEMPLATE *tt, char opt,
+				ASN1_TLC *ctx);
+static int asn1_template_noexp_d2i(ASN1_VALUE **val,
+				const unsigned char **in, long len,
+				const ASN1_TEMPLATE *tt, char opt,
+				ASN1_TLC *ctx);
+static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
+				const unsigned char **in, long len,
+				const ASN1_ITEM *it,
+				int tag, int aclass, char opt, ASN1_TLC *ctx);
+
+/* Table to convert tags to bit values, used for MSTRING type */
+static const unsigned long tag2bit[32] = {
+0,	0,	0,	B_ASN1_BIT_STRING,	/* tags  0 -  3 */
+B_ASN1_OCTET_STRING,	0,	0,		B_ASN1_UNKNOWN,/* tags  4- 7 */
+B_ASN1_UNKNOWN,	B_ASN1_UNKNOWN,	B_ASN1_UNKNOWN,	B_ASN1_UNKNOWN,/* tags  8-11 */
+B_ASN1_UTF8STRING,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,/* tags 12-15 */
+B_ASN1_SEQUENCE,0,B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */
+B_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING,       /* tags 20-22 */
+B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME,			       /* tags 23-24 */	
+B_ASN1_GRAPHICSTRING,B_ASN1_ISO64STRING,B_ASN1_GENERALSTRING,  /* tags 25-27 */
+B_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN, /* tags 28-31 */
+	};
+
+unsigned long ASN1_tag2bit(int tag)
+	{
+	if ((tag < 0) || (tag > 30)) return 0;
+	return tag2bit[tag];
+	}
+
+/* Macro to initialize and invalidate the cache */
+
+#define asn1_tlc_clear(c)	if (c) (c)->valid = 0
+/* Version to avoid compiler warning about 'c' always non-NULL */
+#define asn1_tlc_clear_nc(c)	(c)->valid = 0
+
+/* Decode an ASN1 item, this currently behaves just 
+ * like a standard 'd2i' function. 'in' points to 
+ * a buffer to read the data from, in future we will
+ * have more advanced versions that can input data
+ * a piece at a time and this will simply be a special
+ * case.
+ */
+
+ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
+		const unsigned char **in, long len, const ASN1_ITEM *it)
+	{
+	ASN1_TLC c;
+	ASN1_VALUE *ptmpval = NULL;
+	if (!pval)
+		pval = &ptmpval;
+	asn1_tlc_clear_nc(&c);
+	if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) 
+		return *pval;
+	return NULL;
+	}
+
+int ASN1_template_d2i(ASN1_VALUE **pval,
+		const unsigned char **in, long len, const ASN1_TEMPLATE *tt)
+	{
+	ASN1_TLC c;
+	asn1_tlc_clear_nc(&c);
+	return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
+	}
+
+
+/* Decode an item, taking care of IMPLICIT tagging, if any.
+ * If 'opt' set and tag mismatch return -1 to handle OPTIONAL
+ */
+
+int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
+			const ASN1_ITEM *it,
+			int tag, int aclass, char opt, ASN1_TLC *ctx)
+	{
+	const ASN1_TEMPLATE *tt, *errtt = NULL;
+	const ASN1_COMPAT_FUNCS *cf;
+	const ASN1_EXTERN_FUNCS *ef;
+	const ASN1_AUX *aux = it->funcs;
+	ASN1_aux_cb *asn1_cb;
+	const unsigned char *p = NULL, *q;
+	unsigned char *wp=NULL;	/* BIG FAT WARNING!  BREAKS CONST WHERE USED */
+	unsigned char imphack = 0, oclass;
+	char seq_eoc, seq_nolen, cst, isopt;
+	long tmplen;
+	int i;
+	int otag;
+	int ret = 0;
+	ASN1_VALUE **pchptr, *ptmpval;
+	if (!pval)
+		return 0;
+	if (aux && aux->asn1_cb)
+		asn1_cb = aux->asn1_cb;
+	else asn1_cb = 0;
+
+	switch(it->itype)
+		{
+		case ASN1_ITYPE_PRIMITIVE:
+		if (it->templates)
+			{
+			/* tagging or OPTIONAL is currently illegal on an item
+			 * template because the flags can't get passed down.
+			 * In practice this isn't a problem: we include the
+			 * relevant flags from the item template in the
+			 * template itself.
+			 */
+			if ((tag != -1) || opt)
+				{
+				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+				ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
+				goto err;
+				}
+			return asn1_template_ex_d2i(pval, in, len,
+					it->templates, opt, ctx);
+		}
+		return asn1_d2i_ex_primitive(pval, in, len, it,
+						tag, aclass, opt, ctx);
+		break;
+
+		case ASN1_ITYPE_MSTRING:
+		p = *in;
+		/* Just read in tag and class */
+		ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
+						&p, len, -1, 0, 1, ctx);
+		if (!ret)
+			{
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+					ERR_R_NESTED_ASN1_ERROR);
+			goto err;
+			}
+
+		/* Must be UNIVERSAL class */
+		if (oclass != V_ASN1_UNIVERSAL)
+			{
+			/* If OPTIONAL, assume this is OK */
+			if (opt) return -1;
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+					ASN1_R_MSTRING_NOT_UNIVERSAL);
+			goto err;
+			}
+		/* Check tag matches bit map */
+		if (!(ASN1_tag2bit(otag) & it->utype))
+			{
+			/* If OPTIONAL, assume this is OK */
+			if (opt)
+				return -1;
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+					ASN1_R_MSTRING_WRONG_TAG);
+			goto err;
+			}
+		return asn1_d2i_ex_primitive(pval, in, len,
+						it, otag, 0, 0, ctx);
+
+		case ASN1_ITYPE_EXTERN:
+		/* Use new style d2i */
+		ef = it->funcs;
+		return ef->asn1_ex_d2i(pval, in, len,
+						it, tag, aclass, opt, ctx);
+
+		case ASN1_ITYPE_COMPAT:
+		/* we must resort to old style evil hackery */
+		cf = it->funcs;
+
+		/* If OPTIONAL see if it is there */
+		if (opt)
+			{
+			int exptag;
+			p = *in;
+			if (tag == -1)
+				exptag = it->utype;
+			else exptag = tag;
+			/* Don't care about anything other than presence
+			 * of expected tag */
+
+			ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL,
+					&p, len, exptag, aclass, 1, ctx);
+			if (!ret)
+				{
+				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+					ERR_R_NESTED_ASN1_ERROR);
+				goto err;
+				}
+			if (ret == -1)
+				return -1;
+			}
+
+		/* This is the old style evil hack IMPLICIT handling:
+		 * since the underlying code is expecting a tag and
+		 * class other than the one present we change the
+		 * buffer temporarily then change it back afterwards.
+		 * This doesn't and never did work for tags > 30.
+		 *
+		 * Yes this is *horrible* but it is only needed for
+		 * old style d2i which will hopefully not be around
+		 * for much longer.
+		 * FIXME: should copy the buffer then modify it so
+		 * the input buffer can be const: we should *always*
+		 * copy because the old style d2i might modify the
+		 * buffer.
+		 */
+
+		if (tag != -1)
+			{
+			wp = *(unsigned char **)in;
+			imphack = *wp;
+			if (p == NULL)
+				{
+				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+					ERR_R_NESTED_ASN1_ERROR);
+				goto err;
+				}
+			*wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED)
+								| it->utype);
+			}
+
+		ptmpval = cf->asn1_d2i(pval, in, len);
+
+		if (tag != -1)
+			*wp = imphack;
+
+		if (ptmpval)
+			return 1;
+
+		ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+		goto err;
+
+
+		case ASN1_ITYPE_CHOICE:
+		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
+				goto auxerr;
+
+		/* Allocate structure */
+		if (!*pval && !ASN1_item_ex_new(pval, it))
+			{
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+						ERR_R_NESTED_ASN1_ERROR);
+			goto err;
+			}
+		/* CHOICE type, try each possibility in turn */
+		p = *in;
+		for (i = 0, tt=it->templates; i < it->tcount; i++, tt++)
+			{
+			pchptr = asn1_get_field_ptr(pval, tt);
+			/* We mark field as OPTIONAL so its absence
+			 * can be recognised.
+			 */
+			ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx);
+			/* If field not present, try the next one */
+			if (ret == -1)
+				continue;
+			/* If positive return, read OK, break loop */
+			if (ret > 0)
+				break;
+			/* Otherwise must be an ASN1 parsing error */
+			errtt = tt;
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+						ERR_R_NESTED_ASN1_ERROR);
+			goto err;
+			}
+
+		/* Did we fall off the end without reading anything? */
+		if (i == it->tcount)
+			{
+			/* If OPTIONAL, this is OK */
+			if (opt)
+				{
+				/* Free and zero it */
+				ASN1_item_ex_free(pval, it);
+				return -1;
+				}
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+					ASN1_R_NO_MATCHING_CHOICE_TYPE);
+			goto err;
+			}
+
+		asn1_set_choice_selector(pval, i, it);
+		*in = p;
+		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
+				goto auxerr;
+		return 1;
+
+		case ASN1_ITYPE_NDEF_SEQUENCE:
+		case ASN1_ITYPE_SEQUENCE:
+		p = *in;
+		tmplen = len;
+
+		/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
+		if (tag == -1)
+			{
+			tag = V_ASN1_SEQUENCE;
+			aclass = V_ASN1_UNIVERSAL;
+			}
+		/* Get SEQUENCE length and update len, p */
+		ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst,
+					&p, len, tag, aclass, opt, ctx);
+		if (!ret)
+			{
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+					ERR_R_NESTED_ASN1_ERROR);
+			goto err;
+			}
+		else if (ret == -1)
+			return -1;
+		if (aux && (aux->flags & ASN1_AFLG_BROKEN))
+			{
+			len = tmplen - (p - *in);
+			seq_nolen = 1;
+			}
+		/* If indefinite we don't do a length check */
+		else seq_nolen = seq_eoc;
+		if (!cst)
+			{
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+				ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
+			goto err;
+			}
+
+		if (!*pval && !ASN1_item_ex_new(pval, it))
+			{
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+				ERR_R_NESTED_ASN1_ERROR);
+			goto err;
+			}
+
+		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
+				goto auxerr;
+
+		/* Get each field entry */
+		for (i = 0, tt = it->templates; i < it->tcount; i++, tt++)
+			{
+			const ASN1_TEMPLATE *seqtt;
+			ASN1_VALUE **pseqval;
+			seqtt = asn1_do_adb(pval, tt, 1);
+			if (!seqtt)
+				goto err;
+			pseqval = asn1_get_field_ptr(pval, seqtt);
+			/* Have we ran out of data? */
+			if (!len)
+				break;
+			q = p;
+			if (asn1_check_eoc(&p, len))
+				{
+				if (!seq_eoc)
+					{
+					ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+							ASN1_R_UNEXPECTED_EOC);
+					goto err;
+					}
+				len -= p - q;
+				seq_eoc = 0;
+				q = p;
+				break;
+				}
+			/* This determines the OPTIONAL flag value. The field
+			 * cannot be omitted if it is the last of a SEQUENCE
+			 * and there is still data to be read. This isn't
+			 * strictly necessary but it increases efficiency in
+			 * some cases.
+			 */
+			if (i == (it->tcount - 1))
+				isopt = 0;
+			else isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
+			/* attempt to read in field, allowing each to be
+			 * OPTIONAL */
+
+			ret = asn1_template_ex_d2i(pseqval, &p, len,
+							seqtt, isopt, ctx);
+			if (!ret)
+				{
+				errtt = seqtt;
+				goto err;
+				}
+			else if (ret == -1)
+				{
+				/* OPTIONAL component absent.
+				 * Free and zero the field.
+				 */
+				ASN1_template_free(pseqval, seqtt);
+				continue;
+				}
+			/* Update length */
+			len -= p - q;
+			}
+
+		/* Check for EOC if expecting one */
+		if (seq_eoc && !asn1_check_eoc(&p, len))
+			{
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC);
+			goto err;
+			}
+		/* Check all data read */
+		if (!seq_nolen && len)
+			{
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+					ASN1_R_SEQUENCE_LENGTH_MISMATCH);
+			goto err;
+			}
+
+		/* If we get here we've got no more data in the SEQUENCE,
+		 * however we may not have read all fields so check all
+		 * remaining are OPTIONAL and clear any that are.
+		 */
+		for (; i < it->tcount; tt++, i++)
+			{
+			const ASN1_TEMPLATE *seqtt;
+			seqtt = asn1_do_adb(pval, tt, 1);
+			if (!seqtt)
+				goto err;
+			if (seqtt->flags & ASN1_TFLG_OPTIONAL)
+				{
+				ASN1_VALUE **pseqval;
+				pseqval = asn1_get_field_ptr(pval, seqtt);
+				ASN1_template_free(pseqval, seqtt);
+				}
+			else
+				{
+				errtt = seqtt;
+				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+							ASN1_R_FIELD_MISSING);
+				goto err;
+				}
+			}
+		/* Save encoding */
+		if (!asn1_enc_save(pval, *in, p - *in, it))
+			goto auxerr;
+		*in = p;
+		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
+				goto auxerr;
+		return 1;
+
+		default:
+		return 0;
+		}
+	auxerr:
+	ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR);
+	err:
+	ASN1_item_ex_free(pval, it);
+	if (errtt)
+		ERR_add_error_data(4, "Field=", errtt->field_name,
+					", Type=", it->sname);
+	else
+		ERR_add_error_data(2, "Type=", it->sname);
+	return 0;
+	}
+
+/* Templates are handled with two separate functions.
+ * One handles any EXPLICIT tag and the other handles the rest.
+ */
+
+static int asn1_template_ex_d2i(ASN1_VALUE **val,
+				const unsigned char **in, long inlen,
+				const ASN1_TEMPLATE *tt, char opt,
+							ASN1_TLC *ctx)
+	{
+	int flags, aclass;
+	int ret;
+	long len;
+	const unsigned char *p, *q;
+	char exp_eoc;
+	if (!val)
+		return 0;
+	flags = tt->flags;
+	aclass = flags & ASN1_TFLG_TAG_CLASS;
+
+	p = *in;
+
+	/* Check if EXPLICIT tag expected */
+	if (flags & ASN1_TFLG_EXPTAG)
+		{
+		char cst;
+		/* Need to work out amount of data available to the inner
+		 * content and where it starts: so read in EXPLICIT header to
+		 * get the info.
+		 */
+		ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst,
+					&p, inlen, tt->tag, aclass, opt, ctx);
+		q = p;
+		if (!ret)
+			{
+			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
+					ERR_R_NESTED_ASN1_ERROR);
+			return 0;
+			}
+		else if (ret == -1)
+			return -1;
+		if (!cst)
+			{
+			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
+					ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
+			return 0;
+			}
+		/* We've found the field so it can't be OPTIONAL now */
+		ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
+		if (!ret)
+			{
+			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
+					ERR_R_NESTED_ASN1_ERROR);
+			return 0;
+			}
+		/* We read the field in OK so update length */
+		len -= p - q;
+		if (exp_eoc)
+			{
+			/* If NDEF we must have an EOC here */
+			if (!asn1_check_eoc(&p, len))
+				{
+				ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
+						ASN1_R_MISSING_EOC);
+				goto err;
+				}
+			}
+		else
+			{
+			/* Otherwise we must hit the EXPLICIT tag end or its
+			 * an error */
+			if (len)
+				{
+				ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
+					ASN1_R_EXPLICIT_LENGTH_MISMATCH);
+				goto err;
+				}
+			}
+		}
+		else 
+			return asn1_template_noexp_d2i(val, in, inlen,
+								tt, opt, ctx);
+
+	*in = p;
+	return 1;
+
+	err:
+	ASN1_template_free(val, tt);
+	return 0;
+	}
+
+static int asn1_template_noexp_d2i(ASN1_VALUE **val,
+				const unsigned char **in, long len,
+				const ASN1_TEMPLATE *tt, char opt,
+				ASN1_TLC *ctx)
+	{
+	int flags, aclass;
+	int ret;
+	const unsigned char *p, *q;
+	if (!val)
+		return 0;
+	flags = tt->flags;
+	aclass = flags & ASN1_TFLG_TAG_CLASS;
+
+	p = *in;
+	q = p;
+
+	if (flags & ASN1_TFLG_SK_MASK)
+		{
+		/* SET OF, SEQUENCE OF */
+		int sktag, skaclass;
+		char sk_eoc;
+		/* First work out expected inner tag value */
+		if (flags & ASN1_TFLG_IMPTAG)
+			{
+			sktag = tt->tag;
+			skaclass = aclass;
+			}
+		else
+			{
+			skaclass = V_ASN1_UNIVERSAL;
+			if (flags & ASN1_TFLG_SET_OF)
+				sktag = V_ASN1_SET;
+			else
+				sktag = V_ASN1_SEQUENCE;
+			}
+		/* Get the tag */
+		ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,
+					&p, len, sktag, skaclass, opt, ctx);
+		if (!ret)
+			{
+			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+						ERR_R_NESTED_ASN1_ERROR);
+			return 0;
+			}
+		else if (ret == -1)
+			return -1;
+		if (!*val)
+			*val = (ASN1_VALUE *)sk_new_null();
+		else
+			{
+			/* We've got a valid STACK: free up any items present */
+			STACK_OF(ASN1_VALUE) *sktmp
+			    = (STACK_OF(ASN1_VALUE) *)*val;
+			ASN1_VALUE *vtmp;
+			while(sk_ASN1_VALUE_num(sktmp) > 0)
+				{
+				vtmp = sk_ASN1_VALUE_pop(sktmp);
+				ASN1_item_ex_free(&vtmp,
+						ASN1_ITEM_ptr(tt->item));
+				}
+			}
+				
+		if (!*val)
+			{
+			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+						ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+
+		/* Read as many items as we can */
+		while(len > 0)
+			{
+			ASN1_VALUE *skfield;
+			q = p;
+			/* See if EOC found */
+			if (asn1_check_eoc(&p, len))
+				{
+				if (!sk_eoc)
+					{
+					ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+							ASN1_R_UNEXPECTED_EOC);
+					goto err;
+					}
+				len -= p - q;
+				sk_eoc = 0;
+				break;
+				}
+			skfield = NULL;
+			if (!ASN1_item_ex_d2i(&skfield, &p, len,
+						ASN1_ITEM_ptr(tt->item),
+						-1, 0, 0, ctx))
+				{
+				ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+					ERR_R_NESTED_ASN1_ERROR);
+				goto err;
+				}
+			len -= p - q;
+			if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val,
+						skfield))
+				{
+				ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+						ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			}
+		if (sk_eoc)
+			{
+			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC);
+			goto err;
+			}
+		}
+	else if (flags & ASN1_TFLG_IMPTAG)
+		{
+		/* IMPLICIT tagging */
+		ret = ASN1_item_ex_d2i(val, &p, len,
+			ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx);
+		if (!ret)
+			{
+			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+						ERR_R_NESTED_ASN1_ERROR);
+			goto err;
+			}
+		else if (ret == -1)
+			return -1;
+		}
+	else
+		{
+		/* Nothing special */
+		ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
+							-1, 0, opt, ctx);
+		if (!ret)
+			{
+			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+					ERR_R_NESTED_ASN1_ERROR);
+			goto err;
+			}
+		else if (ret == -1)
+			return -1;
+		}
+
+	*in = p;
+	return 1;
+
+	err:
+	ASN1_template_free(val, tt);
+	return 0;
+	}
+
+static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
+				const unsigned char **in, long inlen, 
+				const ASN1_ITEM *it,
+				int tag, int aclass, char opt, ASN1_TLC *ctx)
+	{
+	int ret = 0, utype;
+	long plen;
+	char cst, inf, free_cont = 0;
+	const unsigned char *p;
+	BUF_MEM buf;
+	const unsigned char *cont = NULL;
+	long len; 
+	if (!pval)
+		{
+		ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL);
+		return 0; /* Should never happen */
+		}
+
+	if (it->itype == ASN1_ITYPE_MSTRING)
+		{
+		utype = tag;
+		tag = -1;
+		}
+	else
+		utype = it->utype;
+
+	if (utype == V_ASN1_ANY)
+		{
+		/* If type is ANY need to figure out type from tag */
+		unsigned char oclass;
+		if (tag >= 0)
+			{
+			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+					ASN1_R_ILLEGAL_TAGGED_ANY);
+			return 0;
+			}
+		if (opt)
+			{
+			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+					ASN1_R_ILLEGAL_OPTIONAL_ANY);
+			return 0;
+			}
+		p = *in;
+		ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL,
+					&p, inlen, -1, 0, 0, ctx);
+		if (!ret)
+			{
+			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+					ERR_R_NESTED_ASN1_ERROR);
+			return 0;
+			}
+		if (oclass != V_ASN1_UNIVERSAL)
+			utype = V_ASN1_OTHER;
+		}
+	if (tag == -1)
+		{
+		tag = utype;
+		aclass = V_ASN1_UNIVERSAL;
+		}
+	p = *in;
+	/* Check header */
+	ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,
+				&p, inlen, tag, aclass, opt, ctx);
+	if (!ret)
+		{
+		ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
+		return 0;
+		}
+	else if (ret == -1)
+		return -1;
+        ret = 0;
+	/* SEQUENCE, SET and "OTHER" are left in encoded form */
+	if ((utype == V_ASN1_SEQUENCE)
+		|| (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER))
+		{
+		/* Clear context cache for type OTHER because the auto clear
+		 * when we have a exact match wont work
+		 */
+		if (utype == V_ASN1_OTHER)
+			{
+			asn1_tlc_clear(ctx);
+			}
+		/* SEQUENCE and SET must be constructed */
+		else if (!cst)
+			{
+			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+				ASN1_R_TYPE_NOT_CONSTRUCTED);
+			return 0;
+			}
+
+		cont = *in;
+		/* If indefinite length constructed find the real end */
+		if (inf)
+			{
+			if (!asn1_find_end(&p, plen, inf))
+				 goto err;
+			len = p - cont;
+			}
+		else
+			{
+			len = p - cont + plen;
+			p += plen;
+			buf.data = NULL;
+			}
+		}
+	else if (cst)
+		{
+		buf.length = 0;
+		buf.max = 0;
+		buf.data = NULL;
+		/* Should really check the internal tags are correct but
+		 * some things may get this wrong. The relevant specs
+		 * say that constructed string types should be OCTET STRINGs
+		 * internally irrespective of the type. So instead just check
+		 * for UNIVERSAL class and ignore the tag.
+		 */
+		if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0))
+			{
+			free_cont = 1;
+			goto err;
+			}
+		len = buf.length;
+		/* Append a final null to string */
+		if (!BUF_MEM_grow_clean(&buf, len + 1))
+			{
+			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+						ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		buf.data[len] = 0;
+		cont = (const unsigned char *)buf.data;
+		free_cont = 1;
+		}
+	else
+		{
+		cont = p;
+		len = plen;
+		p += plen;
+		}
+
+	/* We now have content length and type: translate into a structure */
+	if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
+		goto err;
+
+	*in = p;
+	ret = 1;
+	err:
+	if (free_cont && buf.data) OPENSSL_free(buf.data);
+	return ret;
+	}
+
+/* Translate ASN1 content octets into a structure */
+
+int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+			int utype, char *free_cont, const ASN1_ITEM *it)
+	{
+	ASN1_VALUE **opval = NULL;
+	ASN1_STRING *stmp;
+	ASN1_TYPE *typ = NULL;
+	int ret = 0;
+	const ASN1_PRIMITIVE_FUNCS *pf;
+	ASN1_INTEGER **tint;
+	pf = it->funcs;
+
+	if (pf && pf->prim_c2i)
+		return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
+	/* If ANY type clear type and set pointer to internal value */
+	if (it->utype == V_ASN1_ANY)
+		{
+		if (!*pval)
+			{
+			typ = ASN1_TYPE_new();
+			if (typ == NULL)
+				goto err;
+			*pval = (ASN1_VALUE *)typ;
+			}
+		else
+			typ = (ASN1_TYPE *)*pval;
+
+		if (utype != typ->type)
+			ASN1_TYPE_set(typ, utype, NULL);
+		opval = pval;
+		pval = &typ->value.asn1_value;
+		}
+	switch(utype)
+		{
+		case V_ASN1_OBJECT:
+		if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
+			goto err;
+		break;
+
+		case V_ASN1_NULL:
+		if (len)
+			{
+			ASN1err(ASN1_F_ASN1_EX_C2I,
+						ASN1_R_NULL_IS_WRONG_LENGTH);
+			goto err;
+			}
+		*pval = (ASN1_VALUE *)1;
+		break;
+
+		case V_ASN1_BOOLEAN:
+		if (len != 1)
+			{
+			ASN1err(ASN1_F_ASN1_EX_C2I,
+						ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
+			goto err;
+			}
+		else
+			{
+			ASN1_BOOLEAN *tbool;
+			tbool = (ASN1_BOOLEAN *)pval;
+			*tbool = *cont;
+			}
+		break;
+
+		case V_ASN1_BIT_STRING:
+		if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
+			goto err;
+		break;
+
+		case V_ASN1_INTEGER:
+		case V_ASN1_NEG_INTEGER:
+		case V_ASN1_ENUMERATED:
+		case V_ASN1_NEG_ENUMERATED:
+		tint = (ASN1_INTEGER **)pval;
+		if (!c2i_ASN1_INTEGER(tint, &cont, len))
+			goto err;
+		/* Fixup type to match the expected form */
+		(*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
+		break;
+
+		case V_ASN1_OCTET_STRING:
+		case V_ASN1_NUMERICSTRING:
+		case V_ASN1_PRINTABLESTRING:
+		case V_ASN1_T61STRING:
+		case V_ASN1_VIDEOTEXSTRING:
+		case V_ASN1_IA5STRING:
+		case V_ASN1_UTCTIME:
+		case V_ASN1_GENERALIZEDTIME:
+		case V_ASN1_GRAPHICSTRING:
+		case V_ASN1_VISIBLESTRING:
+		case V_ASN1_GENERALSTRING:
+		case V_ASN1_UNIVERSALSTRING:
+		case V_ASN1_BMPSTRING:
+		case V_ASN1_UTF8STRING:
+		case V_ASN1_OTHER:
+		case V_ASN1_SET:
+		case V_ASN1_SEQUENCE:
+		default:
+		if (utype == V_ASN1_BMPSTRING && (len & 1))
+			{
+			ASN1err(ASN1_F_ASN1_EX_C2I,
+					ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
+			goto err;
+			}
+		if (utype == V_ASN1_UNIVERSALSTRING && (len & 3))
+			{
+			ASN1err(ASN1_F_ASN1_EX_C2I,
+					ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
+			goto err;
+			}
+		/* All based on ASN1_STRING and handled the same */
+		if (!*pval)
+			{
+			stmp = ASN1_STRING_type_new(utype);
+			if (!stmp)
+				{
+				ASN1err(ASN1_F_ASN1_EX_C2I,
+							ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			*pval = (ASN1_VALUE *)stmp;
+			}
+		else
+			{
+			stmp = (ASN1_STRING *)*pval;
+			stmp->type = utype;
+			}
+		/* If we've already allocated a buffer use it */
+		if (*free_cont)
+			{
+			if (stmp->data)
+				OPENSSL_free(stmp->data);
+			stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
+			stmp->length = len;
+			*free_cont = 0;
+			}
+		else
+			{
+			if (!ASN1_STRING_set(stmp, cont, len))
+				{
+				ASN1err(ASN1_F_ASN1_EX_C2I,
+							ERR_R_MALLOC_FAILURE);
+				ASN1_STRING_free(stmp);	
+				*pval = NULL;
+				goto err;
+				}
+			}
+		break;
+		}
+	/* If ASN1_ANY and NULL type fix up value */
+	if (typ && (utype == V_ASN1_NULL))
+		 typ->value.ptr = NULL;
+
+	ret = 1;
+	err:
+	if (!ret)
+		{
+		ASN1_TYPE_free(typ);
+		if (opval)
+			*opval = NULL;
+		}
+	return ret;
+	}
+
+
+/* This function finds the end of an ASN1 structure when passed its maximum
+ * length, whether it is indefinite length and a pointer to the content.
+ * This is more efficient than calling asn1_collect because it does not
+ * recurse on each indefinite length header.
+ */
+
+static int asn1_find_end(const unsigned char **in, long len, char inf)
+	{
+	int expected_eoc;
+	long plen;
+	const unsigned char *p = *in, *q;
+	/* If not indefinite length constructed just add length */
+	if (inf == 0)
+		{
+		*in += len;
+		return 1;
+		}
+	expected_eoc = 1;
+	/* Indefinite length constructed form. Find the end when enough EOCs
+	 * are found. If more indefinite length constructed headers
+	 * are encountered increment the expected eoc count otherwise just
+	 * skip to the end of the data.
+	 */
+	while (len > 0)
+		{
+		if(asn1_check_eoc(&p, len))
+			{
+			expected_eoc--;
+			if (expected_eoc == 0)
+				break;
+			len -= 2;
+			continue;
+			}
+		q = p;
+		/* Just read in a header: only care about the length */
+		if(!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
+				-1, 0, 0, NULL))
+			{
+			ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR);
+			return 0;
+			}
+		if (inf)
+			expected_eoc++;
+		else
+			p += plen;
+		len -= p - q;
+		}
+	if (expected_eoc)
+		{
+		ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC);
+		return 0;
+		}
+	*in = p;
+	return 1;
+	}
+/* This function collects the asn1 data from a constructred string
+ * type into a buffer. The values of 'in' and 'len' should refer
+ * to the contents of the constructed type and 'inf' should be set
+ * if it is indefinite length.
+ */
+
+#ifndef ASN1_MAX_STRING_NEST
+/* This determines how many levels of recursion are permitted in ASN1
+ * string types. If it is not limited stack overflows can occur. If set
+ * to zero no recursion is allowed at all. Although zero should be adequate
+ * examples exist that require a value of 1. So 5 should be more than enough.
+ */
+#define ASN1_MAX_STRING_NEST 5
+#endif
+
+
+static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
+			char inf, int tag, int aclass, int depth)
+	{
+	const unsigned char *p, *q;
+	long plen;
+	char cst, ininf;
+	p = *in;
+	inf &= 1;
+	/* If no buffer and not indefinite length constructed just pass over
+	 * the encoded data */
+	if (!buf && !inf)
+		{
+		*in += len;
+		return 1;
+		}
+	while(len > 0)
+		{
+		q = p;
+		/* Check for EOC */
+		if (asn1_check_eoc(&p, len))
+			{
+			/* EOC is illegal outside indefinite length
+			 * constructed form */
+			if (!inf)
+				{
+				ASN1err(ASN1_F_ASN1_COLLECT,
+					ASN1_R_UNEXPECTED_EOC);
+				return 0;
+				}
+			inf = 0;
+			break;
+			}
+
+		if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
+					len, tag, aclass, 0, NULL))
+			{
+			ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR);
+			return 0;
+			}
+
+		/* If indefinite length constructed update max length */
+		if (cst)
+			{
+			if (depth >= ASN1_MAX_STRING_NEST)
+				{
+				ASN1err(ASN1_F_ASN1_COLLECT,
+					ASN1_R_NESTED_ASN1_STRING);
+				return 0;
+				}
+			if (!asn1_collect(buf, &p, plen, ininf, tag, aclass,
+						depth + 1))
+				return 0;
+			}
+		else if (plen && !collect_data(buf, &p, plen))
+			return 0;
+		len -= p - q;
+		}
+	if (inf)
+		{
+		ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC);
+		return 0;
+		}
+	*in = p;
+	return 1;
+	}
+
+static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
+	{
+	int len;
+	if (buf)
+		{
+		len = buf->length;
+		if (!BUF_MEM_grow_clean(buf, len + plen))
+			{
+			ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		memcpy(buf->data + len, *p, plen);
+		}
+	*p += plen;
+	return 1;
+	}
+
+/* Check for ASN1 EOC and swallow it if found */
+
+static int asn1_check_eoc(const unsigned char **in, long len)
+	{
+	const unsigned char *p;
+	if (len < 2) return 0;
+	p = *in;
+	if (!p[0] && !p[1])
+		{
+		*in += 2;
+		return 1;
+		}
+	return 0;
+	}
+
+/* Check an ASN1 tag and length: a bit like ASN1_get_object
+ * but it sets the length for indefinite length constructed
+ * form, we don't know the exact length but we can set an
+ * upper bound to the amount of data available minus the
+ * header length just read.
+ */
+
+static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
+				char *inf, char *cst,
+				const unsigned char **in, long len,
+				int exptag, int expclass, char opt,
+				ASN1_TLC *ctx)
+	{
+	int i;
+	int ptag, pclass;
+	long plen;
+	const unsigned char *p, *q;
+	p = *in;
+	q = p;
+
+	if (ctx && ctx->valid)
+		{
+		i = ctx->ret;
+		plen = ctx->plen;
+		pclass = ctx->pclass;
+		ptag = ctx->ptag;
+		p += ctx->hdrlen;
+		}
+	else
+		{
+		i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
+		if (ctx)
+			{
+			ctx->ret = i;
+			ctx->plen = plen;
+			ctx->pclass = pclass;
+			ctx->ptag = ptag;
+			ctx->hdrlen = p - q;
+			ctx->valid = 1;
+			/* If definite length, and no error, length +
+			 * header can't exceed total amount of data available. 
+			 */
+			if (!(i & 0x81) && ((plen + ctx->hdrlen) > len))
+				{
+				ASN1err(ASN1_F_ASN1_CHECK_TLEN,
+							ASN1_R_TOO_LONG);
+				asn1_tlc_clear(ctx);
+				return 0;
+				}
+			}
+		}
+
+	if (i & 0x80)
+		{
+		ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER);
+		asn1_tlc_clear(ctx);
+		return 0;
+		}
+	if (exptag >= 0)
+		{
+		if ((exptag != ptag) || (expclass != pclass))
+			{
+			/* If type is OPTIONAL, not an error:
+			 * indicate missing type.
+			 */
+			if (opt) return -1;
+			asn1_tlc_clear(ctx);
+			ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG);
+			return 0;
+			}
+		/* We have a tag and class match:
+		 * assume we are going to do something with it */
+		asn1_tlc_clear(ctx);
+		}
+
+	if (i & 1)
+		plen = len - (p - q);
+
+	if (inf)
+		*inf = i & 1;
+
+	if (cst)
+		*cst = i & V_ASN1_CONSTRUCTED;
+
+	if (olen)
+		*olen = plen;
+
+	if (oclass)
+		*oclass = pclass;
+
+	if (otag)
+		*otag = ptag;
+
+	*in = p;
+	return 1;
+	}
diff --git a/openssl/crypto/asn1/tasn_enc.c b/openssl/crypto/asn1/tasn_enc.c
new file mode 100644
index 0000000..936ad1f
--- /dev/null
+++ b/openssl/crypto/asn1/tasn_enc.c
@@ -0,0 +1,691 @@
+/* tasn_enc.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stddef.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+
+static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
+					const ASN1_ITEM *it,
+					int tag, int aclass);
+static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
+					int skcontlen, const ASN1_ITEM *item,
+					int do_sort, int iclass);
+static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+					const ASN1_TEMPLATE *tt,
+					int tag, int aclass);
+static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
+					const ASN1_ITEM *it, int flags);
+
+/* Top level i2d equivalents: the 'ndef' variant instructs the encoder
+ * to use indefinite length constructed encoding, where appropriate
+ */
+
+int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
+						const ASN1_ITEM *it)
+	{
+	return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
+	}
+
+int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
+	{
+	return asn1_item_flags_i2d(val, out, it, 0);
+	}
+
+/* Encode an ASN1 item, this is use by the
+ * standard 'i2d' function. 'out' points to 
+ * a buffer to output the data to.
+ *
+ * The new i2d has one additional feature. If the output
+ * buffer is NULL (i.e. *out == NULL) then a buffer is
+ * allocated and populated with the encoding.
+ */
+
+static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
+					const ASN1_ITEM *it, int flags)
+	{
+	if (out && !*out)
+		{
+		unsigned char *p, *buf;
+		int len;
+		len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
+		if (len <= 0)
+			return len;
+		buf = OPENSSL_malloc(len);
+		if (!buf)
+			return -1;
+		p = buf;
+		ASN1_item_ex_i2d(&val, &p, it, -1, flags);
+		*out = buf;
+		return len;
+		}
+
+	return ASN1_item_ex_i2d(&val, out, it, -1, flags);
+	}
+
+/* Encode an item, taking care of IMPLICIT tagging (if any).
+ * This function performs the normal item handling: it can be
+ * used in external types.
+ */
+
+int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+			const ASN1_ITEM *it, int tag, int aclass)
+	{
+	const ASN1_TEMPLATE *tt = NULL;
+	unsigned char *p = NULL;
+	int i, seqcontlen, seqlen, ndef = 1;
+	const ASN1_COMPAT_FUNCS *cf;
+	const ASN1_EXTERN_FUNCS *ef;
+	const ASN1_AUX *aux = it->funcs;
+	ASN1_aux_cb *asn1_cb = 0;
+
+	if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
+		return 0;
+
+	if (aux && aux->asn1_cb)
+		 asn1_cb = aux->asn1_cb;
+
+	switch(it->itype)
+		{
+
+		case ASN1_ITYPE_PRIMITIVE:
+		if (it->templates)
+			return asn1_template_ex_i2d(pval, out, it->templates,
+								tag, aclass);
+		return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
+		break;
+
+		case ASN1_ITYPE_MSTRING:
+		return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
+
+		case ASN1_ITYPE_CHOICE:
+		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
+				return 0;
+		i = asn1_get_choice_selector(pval, it);
+		if ((i >= 0) && (i < it->tcount))
+			{
+			ASN1_VALUE **pchval;
+			const ASN1_TEMPLATE *chtt;
+			chtt = it->templates + i;
+			pchval = asn1_get_field_ptr(pval, chtt);
+			return asn1_template_ex_i2d(pchval, out, chtt,
+								-1, aclass);
+			}
+		/* Fixme: error condition if selector out of range */
+		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
+				return 0;
+		break;
+
+		case ASN1_ITYPE_EXTERN:
+		/* If new style i2d it does all the work */
+		ef = it->funcs;
+		return ef->asn1_ex_i2d(pval, out, it, tag, aclass);
+
+		case ASN1_ITYPE_COMPAT:
+		/* old style hackery... */
+		cf = it->funcs;
+		if (out)
+			p = *out;
+		i = cf->asn1_i2d(*pval, out);
+		/* Fixup for IMPLICIT tag: note this messes up for tags > 30,
+		 * but so did the old code. Tags > 30 are very rare anyway.
+		 */
+		if (out && (tag != -1))
+			*p = aclass | tag | (*p & V_ASN1_CONSTRUCTED);
+		return i;
+		
+		case ASN1_ITYPE_NDEF_SEQUENCE:
+		/* Use indefinite length constructed if requested */
+		if (aclass & ASN1_TFLG_NDEF) ndef = 2;
+		/* fall through */
+
+		case ASN1_ITYPE_SEQUENCE:
+		i = asn1_enc_restore(&seqcontlen, out, pval, it);
+		/* An error occurred */
+		if (i < 0)
+			return 0;
+		/* We have a valid cached encoding... */
+		if (i > 0)
+			return seqcontlen;
+		/* Otherwise carry on */
+		seqcontlen = 0;
+		/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
+		if (tag == -1)
+			{
+			tag = V_ASN1_SEQUENCE;
+			/* Retain any other flags in aclass */
+			aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
+					| V_ASN1_UNIVERSAL;
+			}
+		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
+				return 0;
+		/* First work out sequence content length */
+		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
+			{
+			const ASN1_TEMPLATE *seqtt;
+			ASN1_VALUE **pseqval;
+			seqtt = asn1_do_adb(pval, tt, 1);
+			if (!seqtt)
+				return 0;
+			pseqval = asn1_get_field_ptr(pval, seqtt);
+			/* FIXME: check for errors in enhanced version */
+			seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
+								-1, aclass);
+			}
+
+		seqlen = ASN1_object_size(ndef, seqcontlen, tag);
+		if (!out)
+			return seqlen;
+		/* Output SEQUENCE header */
+		ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
+		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
+			{
+			const ASN1_TEMPLATE *seqtt;
+			ASN1_VALUE **pseqval;
+			seqtt = asn1_do_adb(pval, tt, 1);
+			if (!seqtt)
+				return 0;
+			pseqval = asn1_get_field_ptr(pval, seqtt);
+			/* FIXME: check for errors in enhanced version */
+			asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
+			}
+		if (ndef == 2)
+			ASN1_put_eoc(out);
+		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
+				return 0;
+		return seqlen;
+
+		default:
+		return 0;
+
+		}
+	return 0;
+	}
+
+int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
+							const ASN1_TEMPLATE *tt)
+	{
+	return asn1_template_ex_i2d(pval, out, tt, -1, 0);
+	}
+
+static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+				const ASN1_TEMPLATE *tt, int tag, int iclass)
+	{
+	int i, ret, flags, ttag, tclass, ndef;
+	flags = tt->flags;
+	/* Work out tag and class to use: tagging may come
+	 * either from the template or the arguments, not both
+	 * because this would create ambiguity. Additionally
+	 * the iclass argument may contain some additional flags
+	 * which should be noted and passed down to other levels.
+	 */
+	if (flags & ASN1_TFLG_TAG_MASK)
+		{
+		/* Error if argument and template tagging */
+		if (tag != -1)
+			/* FIXME: error code here */
+			return -1;
+		/* Get tagging from template */
+		ttag = tt->tag;
+		tclass = flags & ASN1_TFLG_TAG_CLASS;
+		}
+	else if (tag != -1)
+		{
+		/* No template tagging, get from arguments */
+		ttag = tag;
+		tclass = iclass & ASN1_TFLG_TAG_CLASS;
+		}
+	else
+		{
+		ttag = -1;
+		tclass = 0;
+		}
+	/* 
+	 * Remove any class mask from iflag.
+	 */
+	iclass &= ~ASN1_TFLG_TAG_CLASS;
+
+	/* At this point 'ttag' contains the outer tag to use,
+	 * 'tclass' is the class and iclass is any flags passed
+	 * to this function.
+	 */
+
+	/* if template and arguments require ndef, use it */
+	if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
+		ndef = 2;
+	else ndef = 1;
+
+	if (flags & ASN1_TFLG_SK_MASK)
+		{
+		/* SET OF, SEQUENCE OF */
+		STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
+		int isset, sktag, skaclass;
+		int skcontlen, sklen;
+		ASN1_VALUE *skitem;
+
+		if (!*pval)
+			return 0;
+
+		if (flags & ASN1_TFLG_SET_OF)
+			{
+			isset = 1;
+			/* 2 means we reorder */
+			if (flags & ASN1_TFLG_SEQUENCE_OF)
+				isset = 2;
+			}
+		else isset = 0;
+
+		/* Work out inner tag value: if EXPLICIT
+		 * or no tagging use underlying type.
+		 */
+		if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG))
+			{
+			sktag = ttag;
+			skaclass = tclass;
+			}
+		else
+			{
+			skaclass = V_ASN1_UNIVERSAL;
+			if (isset)
+				sktag = V_ASN1_SET;
+			else sktag = V_ASN1_SEQUENCE;
+			}
+
+		/* Determine total length of items */
+		skcontlen = 0;
+		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
+			{
+			skitem = sk_ASN1_VALUE_value(sk, i);
+			skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
+						ASN1_ITEM_ptr(tt->item),
+							-1, iclass);
+			}
+		sklen = ASN1_object_size(ndef, skcontlen, sktag);
+		/* If EXPLICIT need length of surrounding tag */
+		if (flags & ASN1_TFLG_EXPTAG)
+			ret = ASN1_object_size(ndef, sklen, ttag);
+		else ret = sklen;
+
+		if (!out)
+			return ret;
+
+		/* Now encode this lot... */
+		/* EXPLICIT tag */
+		if (flags & ASN1_TFLG_EXPTAG)
+			ASN1_put_object(out, ndef, sklen, ttag, tclass);
+		/* SET or SEQUENCE and IMPLICIT tag */
+		ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
+		/* And the stuff itself */
+		asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
+								isset, iclass);
+		if (ndef == 2)
+			{
+			ASN1_put_eoc(out);
+			if (flags & ASN1_TFLG_EXPTAG)
+				ASN1_put_eoc(out);
+			}
+
+		return ret;
+		}
+
+	if (flags & ASN1_TFLG_EXPTAG)
+		{
+		/* EXPLICIT tagging */
+		/* Find length of tagged item */
+		i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item),
+								-1, iclass);
+		if (!i)
+			return 0;
+		/* Find length of EXPLICIT tag */
+		ret = ASN1_object_size(ndef, i, ttag);
+		if (out)
+			{
+			/* Output tag and item */
+			ASN1_put_object(out, ndef, i, ttag, tclass);
+			ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
+								-1, iclass);
+			if (ndef == 2)
+				ASN1_put_eoc(out);
+			}
+		return ret;
+		}
+
+	/* Either normal or IMPLICIT tagging: combine class and flags */
+	return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
+						ttag, tclass | iclass);
+
+}
+
+/* Temporary structure used to hold DER encoding of items for SET OF */
+
+typedef	struct {
+	unsigned char *data;
+	int length;
+	ASN1_VALUE *field;
+} DER_ENC;
+
+static int der_cmp(const void *a, const void *b)
+	{
+	const DER_ENC *d1 = a, *d2 = b;
+	int cmplen, i;
+	cmplen = (d1->length < d2->length) ? d1->length : d2->length;
+	i = memcmp(d1->data, d2->data, cmplen);
+	if (i)
+		return i;
+	return d1->length - d2->length;
+	}
+
+/* Output the content octets of SET OF or SEQUENCE OF */
+
+static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
+					int skcontlen, const ASN1_ITEM *item,
+					int do_sort, int iclass)
+	{
+	int i;
+	ASN1_VALUE *skitem;
+	unsigned char *tmpdat = NULL, *p = NULL;
+	DER_ENC *derlst = NULL, *tder;
+	if (do_sort)
+		 {
+		/* Don't need to sort less than 2 items */
+		if (sk_ASN1_VALUE_num(sk) < 2)
+			do_sort = 0;
+		else
+			{
+			derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk)
+						* sizeof(*derlst));
+			tmpdat = OPENSSL_malloc(skcontlen);
+			if (!derlst || !tmpdat)
+				return 0;
+			}
+		}
+	/* If not sorting just output each item */
+	if (!do_sort)
+		{
+		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
+			{
+			skitem = sk_ASN1_VALUE_value(sk, i);
+			ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
+			}
+		return 1;
+		}
+	p = tmpdat;
+
+	/* Doing sort: build up a list of each member's DER encoding */
+	for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
+		{
+		skitem = sk_ASN1_VALUE_value(sk, i);
+		tder->data = p;
+		tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
+		tder->field = skitem;
+		}
+
+	/* Now sort them */
+	qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
+	/* Output sorted DER encoding */	
+	p = *out;
+	for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
+		{
+		memcpy(p, tder->data, tder->length);
+		p += tder->length;
+		}
+	*out = p;
+	/* If do_sort is 2 then reorder the STACK */
+	if (do_sort == 2)
+		{
+		for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk);
+							i++, tder++)
+			(void)sk_ASN1_VALUE_set(sk, i, tder->field);
+		}
+	OPENSSL_free(derlst);
+	OPENSSL_free(tmpdat);
+	return 1;
+	}
+
+static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
+				const ASN1_ITEM *it, int tag, int aclass)
+	{
+	int len;
+	int utype;
+	int usetag;
+	int ndef = 0;
+
+	utype = it->utype;
+
+	/* Get length of content octets and maybe find
+	 * out the underlying type.
+	 */
+
+	len = asn1_ex_i2c(pval, NULL, &utype, it);
+
+	/* If SEQUENCE, SET or OTHER then header is
+	 * included in pseudo content octets so don't
+	 * include tag+length. We need to check here
+	 * because the call to asn1_ex_i2c() could change
+	 * utype.
+	 */
+	if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
+	   (utype == V_ASN1_OTHER))
+		usetag = 0;
+	else usetag = 1;
+
+	/* -1 means omit type */
+
+	if (len == -1)
+		return 0;
+
+	/* -2 return is special meaning use ndef */
+	if (len == -2)
+		{
+		ndef = 2;
+		len = 0;
+		}
+
+	/* If not implicitly tagged get tag from underlying type */
+	if (tag == -1) tag = utype;
+
+	/* Output tag+length followed by content octets */
+	if (out)
+		{
+		if (usetag)
+			ASN1_put_object(out, ndef, len, tag, aclass);
+		asn1_ex_i2c(pval, *out, &utype, it);
+		if (ndef)
+			ASN1_put_eoc(out);
+		else
+			*out += len;
+		}
+
+	if (usetag)
+		return ASN1_object_size(ndef, len, tag);
+	return len;
+	}
+
+/* Produce content octets from a structure */
+
+int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
+				const ASN1_ITEM *it)
+	{
+	ASN1_BOOLEAN *tbool = NULL;
+	ASN1_STRING *strtmp;
+	ASN1_OBJECT *otmp;
+	int utype;
+	const unsigned char *cont;
+	unsigned char c;
+	int len;
+	const ASN1_PRIMITIVE_FUNCS *pf;
+	pf = it->funcs;
+	if (pf && pf->prim_i2c)
+		return pf->prim_i2c(pval, cout, putype, it);
+
+	/* Should type be omitted? */
+	if ((it->itype != ASN1_ITYPE_PRIMITIVE)
+		|| (it->utype != V_ASN1_BOOLEAN))
+		{
+		if (!*pval) return -1;
+		}
+
+	if (it->itype == ASN1_ITYPE_MSTRING)
+		{
+		/* If MSTRING type set the underlying type */
+		strtmp = (ASN1_STRING *)*pval;
+		utype = strtmp->type;
+		*putype = utype;
+		}
+	else if (it->utype == V_ASN1_ANY)
+		{
+		/* If ANY set type and pointer to value */
+		ASN1_TYPE *typ;
+		typ = (ASN1_TYPE *)*pval;
+		utype = typ->type;
+		*putype = utype;
+		pval = &typ->value.asn1_value;
+		}
+	else utype = *putype;
+
+	switch(utype)
+		{
+		case V_ASN1_OBJECT:
+		otmp = (ASN1_OBJECT *)*pval;
+		cont = otmp->data;
+		len = otmp->length;
+		break;
+
+		case V_ASN1_NULL:
+		cont = NULL;
+		len = 0;
+		break;
+
+		case V_ASN1_BOOLEAN:
+		tbool = (ASN1_BOOLEAN *)pval;
+		if (*tbool == -1)
+			return -1;
+		if (it->utype != V_ASN1_ANY)
+			{
+			/* Default handling if value == size field then omit */
+			if (*tbool && (it->size > 0))
+				return -1;
+			if (!*tbool && !it->size)
+				return -1;
+			}
+		c = (unsigned char)*tbool;
+		cont = &c;
+		len = 1;
+		break;
+
+		case V_ASN1_BIT_STRING:
+		return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
+							cout ? &cout : NULL);
+		break;
+
+		case V_ASN1_INTEGER:
+		case V_ASN1_NEG_INTEGER:
+		case V_ASN1_ENUMERATED:
+		case V_ASN1_NEG_ENUMERATED:
+		/* These are all have the same content format
+		 * as ASN1_INTEGER
+		 */
+		return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval,
+							cout ? &cout : NULL);
+		break;
+
+		case V_ASN1_OCTET_STRING:
+		case V_ASN1_NUMERICSTRING:
+		case V_ASN1_PRINTABLESTRING:
+		case V_ASN1_T61STRING:
+		case V_ASN1_VIDEOTEXSTRING:
+		case V_ASN1_IA5STRING:
+		case V_ASN1_UTCTIME:
+		case V_ASN1_GENERALIZEDTIME:
+		case V_ASN1_GRAPHICSTRING:
+		case V_ASN1_VISIBLESTRING:
+		case V_ASN1_GENERALSTRING:
+		case V_ASN1_UNIVERSALSTRING:
+		case V_ASN1_BMPSTRING:
+		case V_ASN1_UTF8STRING:
+		case V_ASN1_SEQUENCE:
+		case V_ASN1_SET:
+		default:
+		/* All based on ASN1_STRING and handled the same */
+		strtmp = (ASN1_STRING *)*pval;
+		/* Special handling for NDEF */
+		if ((it->size == ASN1_TFLG_NDEF)
+			&& (strtmp->flags & ASN1_STRING_FLAG_NDEF))
+			{
+			if (cout)
+				{
+				strtmp->data = cout;
+				strtmp->length = 0;
+				}
+			/* Special return code */
+			return -2;
+			}
+		cont = strtmp->data;
+		len = strtmp->length;
+
+		break;
+
+		}
+	if (cout && len)
+		memcpy(cout, cont, len);
+	return len;
+	}
diff --git a/openssl/crypto/asn1/tasn_fre.c b/openssl/crypto/asn1/tasn_fre.c
new file mode 100644
index 0000000..77d3092
--- /dev/null
+++ b/openssl/crypto/asn1/tasn_fre.c
@@ -0,0 +1,266 @@
+/* tasn_fre.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stddef.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+
+static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine);
+
+/* Free up an ASN1 structure */
+
+void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
+	{
+	asn1_item_combine_free(&val, it, 0);
+	}
+
+void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+	{
+	asn1_item_combine_free(pval, it, 0);
+	}
+
+static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
+	{
+	const ASN1_TEMPLATE *tt = NULL, *seqtt;
+	const ASN1_EXTERN_FUNCS *ef;
+	const ASN1_COMPAT_FUNCS *cf;
+	const ASN1_AUX *aux = it->funcs;
+	ASN1_aux_cb *asn1_cb;
+	int i;
+	if (!pval)
+		return;
+	if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
+		return;
+	if (aux && aux->asn1_cb)
+		asn1_cb = aux->asn1_cb;
+	else
+		asn1_cb = 0;
+
+	switch(it->itype)
+		{
+
+		case ASN1_ITYPE_PRIMITIVE:
+		if (it->templates)
+			ASN1_template_free(pval, it->templates);
+		else
+			ASN1_primitive_free(pval, it);
+		break;
+
+		case ASN1_ITYPE_MSTRING:
+		ASN1_primitive_free(pval, it);
+		break;
+
+		case ASN1_ITYPE_CHOICE:
+		if (asn1_cb)
+			{
+			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
+			if (i == 2)
+				return;
+			}
+		i = asn1_get_choice_selector(pval, it);
+		if ((i >= 0) && (i < it->tcount))
+			{
+			ASN1_VALUE **pchval;
+			tt = it->templates + i;
+			pchval = asn1_get_field_ptr(pval, tt);
+			ASN1_template_free(pchval, tt);
+			}
+		if (asn1_cb)
+			asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
+		if (!combine)
+			{
+			OPENSSL_free(*pval);
+			*pval = NULL;
+			}
+		break;
+
+		case ASN1_ITYPE_COMPAT:
+		cf = it->funcs;
+		if (cf && cf->asn1_free)
+			cf->asn1_free(*pval);
+		break;
+
+		case ASN1_ITYPE_EXTERN:
+		ef = it->funcs;
+		if (ef && ef->asn1_ex_free)
+			ef->asn1_ex_free(pval, it);
+		break;
+
+		case ASN1_ITYPE_NDEF_SEQUENCE:
+		case ASN1_ITYPE_SEQUENCE:
+		if (asn1_do_lock(pval, -1, it) > 0)
+			return;
+		if (asn1_cb)
+			{
+			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
+			if (i == 2)
+				return;
+			}		
+		asn1_enc_free(pval, it);
+		/* If we free up as normal we will invalidate any
+		 * ANY DEFINED BY field and we wont be able to 
+		 * determine the type of the field it defines. So
+		 * free up in reverse order.
+		 */
+		tt = it->templates + it->tcount - 1;
+		for (i = 0; i < it->tcount; tt--, i++)
+			{
+			ASN1_VALUE **pseqval;
+			seqtt = asn1_do_adb(pval, tt, 0);
+			if (!seqtt)
+				continue;
+			pseqval = asn1_get_field_ptr(pval, seqtt);
+			ASN1_template_free(pseqval, seqtt);
+			}
+		if (asn1_cb)
+			asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
+		if (!combine)
+			{
+			OPENSSL_free(*pval);
+			*pval = NULL;
+			}
+		break;
+		}
+	}
+
+void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+	{
+	int i;
+	if (tt->flags & ASN1_TFLG_SK_MASK)
+		{
+		STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
+		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
+			{
+			ASN1_VALUE *vtmp;
+			vtmp = sk_ASN1_VALUE_value(sk, i);
+			asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item),
+									0);
+			}
+		sk_ASN1_VALUE_free(sk);
+		*pval = NULL;
+		}
+	else
+		asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
+						tt->flags & ASN1_TFLG_COMBINE);
+	}
+
+void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+	{
+	int utype;
+	if (it)
+		{
+		const ASN1_PRIMITIVE_FUNCS *pf;
+		pf = it->funcs;
+		if (pf && pf->prim_free)
+			{
+			pf->prim_free(pval, it);
+			return;
+			}
+		}
+	/* Special case: if 'it' is NULL free contents of ASN1_TYPE */
+	if (!it)
+		{
+		ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
+		utype = typ->type;
+		pval = &typ->value.asn1_value;
+		if (!*pval)
+			return;
+		}
+	else if (it->itype == ASN1_ITYPE_MSTRING)
+		{
+		utype = -1;
+		if (!*pval)
+			return;
+		}
+	else
+		{
+		utype = it->utype;
+		if ((utype != V_ASN1_BOOLEAN) && !*pval)
+			return;
+		}
+
+	switch(utype)
+		{
+		case V_ASN1_OBJECT:
+		ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
+		break;
+
+		case V_ASN1_BOOLEAN:
+		if (it)
+			*(ASN1_BOOLEAN *)pval = it->size;
+		else
+			*(ASN1_BOOLEAN *)pval = -1;
+		return;
+
+		case V_ASN1_NULL:
+		break;
+
+		case V_ASN1_ANY:
+		ASN1_primitive_free(pval, NULL);
+		OPENSSL_free(*pval);
+		break;
+
+		default:
+		ASN1_STRING_free((ASN1_STRING *)*pval);
+		*pval = NULL;
+		break;
+		}
+	*pval = NULL;
+	}
diff --git a/openssl/crypto/asn1/tasn_new.c b/openssl/crypto/asn1/tasn_new.c
new file mode 100644
index 0000000..0d9e78c
--- /dev/null
+++ b/openssl/crypto/asn1/tasn_new.c
@@ -0,0 +1,396 @@
+/* tasn_new.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stddef.h>
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/err.h>
+#include <openssl/asn1t.h>
+#include <string.h>
+
+static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
+								int combine);
+static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
+	{
+	ASN1_VALUE *ret = NULL;
+	if (ASN1_item_ex_new(&ret, it) > 0)
+		return ret;
+	return NULL;
+	}
+
+/* Allocate an ASN1 structure */
+
+int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+	{
+	return asn1_item_ex_combine_new(pval, it, 0);
+	}
+
+static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
+								int combine)
+	{
+	const ASN1_TEMPLATE *tt = NULL;
+	const ASN1_COMPAT_FUNCS *cf;
+	const ASN1_EXTERN_FUNCS *ef;
+	const ASN1_AUX *aux = it->funcs;
+	ASN1_aux_cb *asn1_cb;
+	ASN1_VALUE **pseqval;
+	int i;
+	if (aux && aux->asn1_cb)
+		asn1_cb = aux->asn1_cb;
+	else
+		asn1_cb = 0;
+
+	if (!combine) *pval = NULL;
+
+#ifdef CRYPTO_MDEBUG
+	if (it->sname)
+		CRYPTO_push_info(it->sname);
+#endif
+
+	switch(it->itype)
+		{
+
+		case ASN1_ITYPE_EXTERN:
+		ef = it->funcs;
+		if (ef && ef->asn1_ex_new)
+			{
+			if (!ef->asn1_ex_new(pval, it))
+				goto memerr;
+			}
+		break;
+
+		case ASN1_ITYPE_COMPAT:
+		cf = it->funcs;
+		if (cf && cf->asn1_new) {
+			*pval = cf->asn1_new();
+			if (!*pval)
+				goto memerr;
+		}
+		break;
+
+		case ASN1_ITYPE_PRIMITIVE:
+		if (it->templates)
+			{
+			if (!ASN1_template_new(pval, it->templates))
+				goto memerr;
+			}
+		else if (!ASN1_primitive_new(pval, it))
+				goto memerr;
+		break;
+
+		case ASN1_ITYPE_MSTRING:
+		if (!ASN1_primitive_new(pval, it))
+				goto memerr;
+		break;
+
+		case ASN1_ITYPE_CHOICE:
+		if (asn1_cb)
+			{
+			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
+			if (!i)
+				goto auxerr;
+			if (i==2)
+				{
+#ifdef CRYPTO_MDEBUG
+				if (it->sname)
+					CRYPTO_pop_info();
+#endif
+				return 1;
+				}
+			}
+		if (!combine)
+			{
+			*pval = OPENSSL_malloc(it->size);
+			if (!*pval)
+				goto memerr;
+			memset(*pval, 0, it->size);
+			}
+		asn1_set_choice_selector(pval, -1, it);
+		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
+				goto auxerr;
+		break;
+
+		case ASN1_ITYPE_NDEF_SEQUENCE:
+		case ASN1_ITYPE_SEQUENCE:
+		if (asn1_cb)
+			{
+			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
+			if (!i)
+				goto auxerr;
+			if (i==2)
+				{
+#ifdef CRYPTO_MDEBUG
+				if (it->sname)
+					CRYPTO_pop_info();
+#endif
+				return 1;
+				}
+			}
+		if (!combine)
+			{
+			*pval = OPENSSL_malloc(it->size);
+			if (!*pval)
+				goto memerr;
+			memset(*pval, 0, it->size);
+			asn1_do_lock(pval, 0, it);
+			asn1_enc_init(pval, it);
+			}
+		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
+			{
+			pseqval = asn1_get_field_ptr(pval, tt);
+			if (!ASN1_template_new(pseqval, tt))
+				goto memerr;
+			}
+		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
+				goto auxerr;
+		break;
+	}
+#ifdef CRYPTO_MDEBUG
+	if (it->sname) CRYPTO_pop_info();
+#endif
+	return 1;
+
+	memerr:
+	ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE);
+#ifdef CRYPTO_MDEBUG
+	if (it->sname) CRYPTO_pop_info();
+#endif
+	return 0;
+
+	auxerr:
+	ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR);
+	ASN1_item_ex_free(pval, it);
+#ifdef CRYPTO_MDEBUG
+	if (it->sname) CRYPTO_pop_info();
+#endif
+	return 0;
+
+	}
+
+static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
+	{
+	const ASN1_EXTERN_FUNCS *ef;
+
+	switch(it->itype)
+		{
+
+		case ASN1_ITYPE_EXTERN:
+		ef = it->funcs;
+		if (ef && ef->asn1_ex_clear) 
+			ef->asn1_ex_clear(pval, it);
+		else *pval = NULL;
+		break;
+
+
+		case ASN1_ITYPE_PRIMITIVE:
+		if (it->templates) 
+			asn1_template_clear(pval, it->templates);
+		else
+			asn1_primitive_clear(pval, it);
+		break;
+
+		case ASN1_ITYPE_MSTRING:
+		asn1_primitive_clear(pval, it);
+		break;
+
+		case ASN1_ITYPE_COMPAT:
+		case ASN1_ITYPE_CHOICE:
+		case ASN1_ITYPE_SEQUENCE:
+		case ASN1_ITYPE_NDEF_SEQUENCE:
+		*pval = NULL;
+		break;
+		}
+	}
+
+
+int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+	{
+	const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
+	int ret;
+	if (tt->flags & ASN1_TFLG_OPTIONAL)
+		{
+		asn1_template_clear(pval, tt);
+		return 1;
+		}
+	/* If ANY DEFINED BY nothing to do */
+
+	if (tt->flags & ASN1_TFLG_ADB_MASK)
+		{
+		*pval = NULL;
+		return 1;
+		}
+#ifdef CRYPTO_MDEBUG
+	if (tt->field_name)
+		CRYPTO_push_info(tt->field_name);
+#endif
+	/* If SET OF or SEQUENCE OF, its a STACK */
+	if (tt->flags & ASN1_TFLG_SK_MASK)
+		{
+		STACK_OF(ASN1_VALUE) *skval;
+		skval = sk_ASN1_VALUE_new_null();
+		if (!skval)
+			{
+			ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);
+			ret = 0;
+			goto done;
+			}
+		*pval = (ASN1_VALUE *)skval;
+		ret = 1;
+		goto done;
+		}
+	/* Otherwise pass it back to the item routine */
+	ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
+	done:
+#ifdef CRYPTO_MDEBUG
+	if (it->sname)
+		CRYPTO_pop_info();
+#endif
+	return ret;
+	}
+
+static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+	{
+	/* If ADB or STACK just NULL the field */
+	if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK)) 
+		*pval = NULL;
+	else
+		asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
+	}
+
+
+/* NB: could probably combine most of the real XXX_new() behaviour and junk
+ * all the old functions.
+ */
+
+int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+	{
+	ASN1_TYPE *typ;
+	ASN1_STRING *str;
+	int utype;
+
+	if (it && it->funcs)
+		{
+		const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
+		if (pf->prim_new)
+			return pf->prim_new(pval, it);
+		}
+
+	if (!it || (it->itype == ASN1_ITYPE_MSTRING))
+		utype = -1;
+	else
+		utype = it->utype;
+	switch(utype)
+		{
+		case V_ASN1_OBJECT:
+		*pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
+		return 1;
+
+		case V_ASN1_BOOLEAN:
+		*(ASN1_BOOLEAN *)pval = it->size;
+		return 1;
+
+		case V_ASN1_NULL:
+		*pval = (ASN1_VALUE *)1;
+		return 1;
+
+		case V_ASN1_ANY:
+		typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
+		if (!typ)
+			return 0;
+		typ->value.ptr = NULL;
+		typ->type = -1;
+		*pval = (ASN1_VALUE *)typ;
+		break;
+
+		default:
+		str = ASN1_STRING_type_new(utype);
+		if (it->itype == ASN1_ITYPE_MSTRING && str)
+			str->flags |= ASN1_STRING_FLAG_MSTRING;
+		*pval = (ASN1_VALUE *)str;
+		break;
+		}
+	if (*pval)
+		return 1;
+	return 0;
+	}
+
+static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
+	{
+	int utype;
+	if (it && it->funcs)
+		{
+		const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
+		if (pf->prim_clear)
+			pf->prim_clear(pval, it);
+		else 
+			*pval = NULL;
+		return;
+		}
+	if (!it || (it->itype == ASN1_ITYPE_MSTRING))
+		utype = -1;
+	else
+		utype = it->utype;
+	if (utype == V_ASN1_BOOLEAN)
+		*(ASN1_BOOLEAN *)pval = it->size;
+	else *pval = NULL;
+	}
diff --git a/openssl/crypto/asn1/tasn_prn.c b/openssl/crypto/asn1/tasn_prn.c
new file mode 100644
index 0000000..4536980
--- /dev/null
+++ b/openssl/crypto/asn1/tasn_prn.c
@@ -0,0 +1,627 @@
+/* tasn_prn.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000,2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stddef.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#include "asn1_locl.h"
+
+/* Print routines.
+ */
+
+/* ASN1_PCTX routines */
+
+ASN1_PCTX default_pctx = 
+	{
+	ASN1_PCTX_FLAGS_SHOW_ABSENT,	/* flags */
+	0,	/* nm_flags */
+	0,	/* cert_flags */
+	0,	/* oid_flags */
+	0	/* str_flags */
+	};
+	
+
+ASN1_PCTX *ASN1_PCTX_new(void)
+	{
+	ASN1_PCTX *ret;
+	ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
+	if (ret == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+	ret->flags = 0;
+	ret->nm_flags = 0;
+	ret->cert_flags = 0;
+	ret->oid_flags = 0;
+	ret->str_flags = 0;
+	return ret;
+	}
+
+void ASN1_PCTX_free(ASN1_PCTX *p)
+	{
+	OPENSSL_free(p);
+	}
+
+unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p)
+	{
+	return p->flags;
+	}
+
+void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
+	{
+	p->flags = flags;
+	}
+
+unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p)
+	{
+	return p->nm_flags;
+	}
+
+void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
+	{
+	p->nm_flags = flags;
+	}
+
+unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p)
+	{
+	return p->cert_flags;
+	}
+
+void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
+	{
+	p->cert_flags = flags;
+	}
+
+unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p)
+	{
+	return p->oid_flags;
+	}
+
+void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
+	{
+	p->oid_flags = flags;
+	}
+
+unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p)
+	{
+	return p->str_flags;
+	}
+
+void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
+	{
+	p->str_flags = flags;
+	}
+
+/* Main print routines */
+
+static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+				const ASN1_ITEM *it,
+				const char *fname, const char *sname,
+				int nohdr, const ASN1_PCTX *pctx);
+
+int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+				const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
+
+static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
+				const ASN1_ITEM *it, int indent,
+				const char *fname, const char *sname,
+				const ASN1_PCTX *pctx);
+
+static int asn1_print_fsname(BIO *out, int indent,
+			const char *fname, const char *sname,
+			const ASN1_PCTX *pctx);
+
+int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
+				const ASN1_ITEM *it, const ASN1_PCTX *pctx)
+	{
+	const char *sname;
+	if (pctx == NULL)
+		pctx = &default_pctx;
+	if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
+		sname = NULL;
+	else
+		sname = it->sname;
+	return asn1_item_print_ctx(out, &ifld, indent, it,
+							NULL, sname, 0, pctx);
+	}
+
+static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+				const ASN1_ITEM *it,
+				const char *fname, const char *sname,
+				int nohdr, const ASN1_PCTX *pctx)
+	{
+	const ASN1_TEMPLATE *tt;
+	const ASN1_EXTERN_FUNCS *ef;
+	ASN1_VALUE **tmpfld;
+	const ASN1_AUX *aux = it->funcs;
+	ASN1_aux_cb *asn1_cb;
+	ASN1_PRINT_ARG parg;
+	int i;
+	if (aux && aux->asn1_cb)
+		{
+		parg.out = out;
+		parg.indent = indent;
+		parg.pctx = pctx;
+		asn1_cb = aux->asn1_cb;
+		}
+	else asn1_cb = 0;
+
+	if(*fld == NULL)
+		{
+		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT)
+			{
+			if (!nohdr && !asn1_print_fsname(out, indent,
+							fname, sname, pctx))
+				return 0;
+			if (BIO_puts(out, "<ABSENT>\n") <= 0)
+				return 0;
+			}
+		return 1;
+		}
+
+	switch(it->itype)
+		{
+		case ASN1_ITYPE_PRIMITIVE:
+		if(it->templates)
+			{
+			if (!asn1_template_print_ctx(out, fld, indent,
+							it->templates, pctx))
+				return 0;
+			}
+		/* fall thru */
+		case ASN1_ITYPE_MSTRING:
+		if (!asn1_primitive_print(out, fld, it,
+				indent, fname, sname,pctx))
+			return 0;
+		break;
+
+		case ASN1_ITYPE_EXTERN:
+		if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+			return 0;
+		/* Use new style print routine if possible */
+		ef = it->funcs;
+		if (ef && ef->asn1_ex_print)
+			{
+			i = ef->asn1_ex_print(out, fld, indent, "", pctx);
+			if (!i)
+				return 0;
+			if ((i == 2) && (BIO_puts(out, "\n") <= 0))
+				return 0;
+			return 1;
+			}
+		else if (sname && 
+			BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
+			return 0;
+		break;
+
+		case ASN1_ITYPE_CHOICE:
+#if 0
+		if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+			return 0;
+#endif
+		/* CHOICE type, get selector */
+		i = asn1_get_choice_selector(fld, it);
+		/* This should never happen... */
+		if((i < 0) || (i >= it->tcount))
+			{
+			if (BIO_printf(out,
+				"ERROR: selector [%d] invalid\n", i) <= 0)
+				return 0;
+			return 1;
+			}
+		tt = it->templates + i;
+		tmpfld = asn1_get_field_ptr(fld, tt);
+		if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
+			return 0;
+		break;
+
+		case ASN1_ITYPE_SEQUENCE:
+		case ASN1_ITYPE_NDEF_SEQUENCE:
+		if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+			return 0;
+		if (fname || sname)
+			{
+			if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
+				{
+				if (BIO_puts(out, " {\n") <= 0)
+					return 0;
+				}
+			else
+				{
+				if (BIO_puts(out, "\n") <= 0)
+					return 0;
+				}
+			}
+
+		if (asn1_cb)
+			{
+			i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
+			if (i == 0)
+				return 0;
+			if (i == 2)
+				return 1;
+			}
+
+		/* Print each field entry */
+		for(i = 0, tt = it->templates; i < it->tcount; i++, tt++)
+			{
+			const ASN1_TEMPLATE *seqtt;
+			seqtt = asn1_do_adb(fld, tt, 1);
+			tmpfld = asn1_get_field_ptr(fld, seqtt);
+			if (!asn1_template_print_ctx(out, tmpfld,
+						indent + 2, seqtt, pctx))
+				return 0;
+			}
+		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
+			{
+			if (BIO_printf(out, "%*s}\n", indent, "") < 0)
+				return 0;
+			}
+
+		if (asn1_cb)
+			{
+			i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
+			if (i == 0)
+				return 0;
+			}
+		break;
+
+		default:
+		BIO_printf(out, "Unprocessed type %d\n", it->itype);
+		return 0;
+		}
+
+	return 1;
+	}
+
+int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+				const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
+	{
+	int i, flags;
+	const char *sname, *fname;
+	flags = tt->flags;
+	if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
+		sname = ASN1_ITEM_ptr(tt->item)->sname;
+	else
+		sname = NULL;
+	if(pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
+		fname = NULL;
+	else
+		fname = tt->field_name;
+	if(flags & ASN1_TFLG_SK_MASK)
+		{
+		char *tname;
+		ASN1_VALUE *skitem;
+		STACK_OF(ASN1_VALUE) *stack;
+
+		/* SET OF, SEQUENCE OF */
+		if (fname)
+			{
+			if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF)
+				{
+				if(flags & ASN1_TFLG_SET_OF)
+					tname = "SET";
+				else
+					tname = "SEQUENCE";
+				if (BIO_printf(out, "%*s%s OF %s {\n",
+					indent, "", tname, tt->field_name) <= 0)
+					return 0;
+				}
+			else if (BIO_printf(out, "%*s%s:\n", indent, "",
+					fname) <= 0)
+				return 0;
+			}
+		stack = (STACK_OF(ASN1_VALUE) *)*fld;
+		for(i = 0; i < sk_ASN1_VALUE_num(stack); i++)
+			{
+			if ((i > 0) && (BIO_puts(out, "\n") <= 0))
+				return 0;
+
+			skitem = sk_ASN1_VALUE_value(stack, i);
+			if (!asn1_item_print_ctx(out, &skitem, indent + 2,
+				ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, pctx))
+				return 0;
+			}
+		if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
+				return 0;
+		if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
+			{
+			if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
+				return 0;
+			}
+		return 1;
+		}
+	return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
+							fname, sname, 0, pctx);
+	}
+
+static int asn1_print_fsname(BIO *out, int indent,
+			const char *fname, const char *sname,
+			const ASN1_PCTX *pctx)
+	{
+	static char spaces[] = "                    ";
+	const int nspaces = sizeof(spaces) - 1;
+
+#if 0
+	if (!sname && !fname)
+		return 1;
+#endif
+
+	while (indent > nspaces)
+		{
+		if (BIO_write(out, spaces, nspaces) != nspaces)
+			return 0;
+		indent -= nspaces;
+		}
+	if (BIO_write(out, spaces, indent) != indent)
+		return 0;
+	if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
+		sname = NULL;
+	if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
+		fname = NULL;
+	if (!sname && !fname)
+		return 1;
+	if (fname)
+		{
+		if (BIO_puts(out, fname) <= 0)
+			return 0;
+		}
+	if (sname)
+		{
+		if (fname)
+			{
+			if (BIO_printf(out, " (%s)", sname) <= 0)
+				return 0;
+			}
+		else
+			{
+			if (BIO_puts(out, sname) <= 0)
+				return 0;
+			}
+		}
+	if (BIO_write(out, ": ", 2) != 2)
+		return 0;
+	return 1;
+	}
+
+static int asn1_print_boolean_ctx(BIO *out, const int bool,
+							const ASN1_PCTX *pctx)
+	{
+	const char *str;
+	switch (bool)
+		{
+		case -1:
+		str = "BOOL ABSENT";
+		break;
+
+		case 0:
+		str = "FALSE";
+		break;
+
+		default:
+		str = "TRUE";
+		break;
+
+		}
+
+	if (BIO_puts(out, str) <= 0)
+		return 0;
+	return 1;
+
+	}
+
+static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str,
+						const ASN1_PCTX *pctx)
+	{
+	char *s;
+	int ret = 1;
+	s = i2s_ASN1_INTEGER(NULL, str);
+	if (BIO_puts(out, s) <= 0)
+		ret = 0;
+	OPENSSL_free(s);
+	return ret;
+	}
+
+static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid,
+						const ASN1_PCTX *pctx)
+	{
+	char objbuf[80];
+	const char *ln;
+	ln = OBJ_nid2ln(OBJ_obj2nid(oid));
+	if(!ln)
+		ln = "";
+	OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
+	if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
+		return 0;
+	return 1;
+	}
+
+static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent,
+						const ASN1_PCTX *pctx)
+	{
+	if (str->type == V_ASN1_BIT_STRING)
+		{
+		if (BIO_printf(out, " (%ld unused bits)\n",
+					str->flags & 0x7) <= 0)
+				return 0;
+		}
+	else if (BIO_puts(out, "\n") <= 0)
+		return 0;
+	if ((str->length > 0)
+		&& BIO_dump_indent(out, (char *)str->data, str->length,
+				indent + 2) <= 0)
+		return 0;
+	return 1;
+	}
+
+static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
+				const ASN1_ITEM *it, int indent,
+				const char *fname, const char *sname,
+				const ASN1_PCTX *pctx)
+	{
+	long utype;
+	ASN1_STRING *str;
+	int ret = 1, needlf = 1;
+	const char *pname;
+	const ASN1_PRIMITIVE_FUNCS *pf;
+	pf = it->funcs;
+	if (!asn1_print_fsname(out, indent, fname, sname, pctx))
+			return 0;
+	if (pf && pf->prim_print)
+		return pf->prim_print(out, fld, it, indent, pctx);
+	str = (ASN1_STRING *)*fld;
+	if (it->itype == ASN1_ITYPE_MSTRING)
+		utype = str->type & ~V_ASN1_NEG;
+	else
+		utype = it->utype;
+	if (utype == V_ASN1_ANY)
+		{
+		ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
+		utype = atype->type;
+		fld = &atype->value.asn1_value;
+		str = (ASN1_STRING *)*fld;
+		if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
+			pname = NULL;
+		else 
+			pname = ASN1_tag2str(utype);
+		}
+	else
+		{
+		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
+			pname = ASN1_tag2str(utype);
+		else 
+			pname = NULL;
+		}
+
+	if (utype == V_ASN1_NULL)
+		{
+		if (BIO_puts(out, "NULL\n") <= 0)
+			return 0;
+		return 1;
+		}
+
+	if (pname)
+		{
+		if (BIO_puts(out, pname) <= 0)
+			return 0;
+		if (BIO_puts(out, ":") <= 0)
+			return 0;
+		}
+
+	switch (utype)
+		{
+		case V_ASN1_BOOLEAN:
+			{
+			int bool = *(int *)fld;
+			if (bool == -1)
+				bool = it->size;
+			ret = asn1_print_boolean_ctx(out, bool, pctx);
+			}
+		break;
+
+		case V_ASN1_INTEGER:
+		case V_ASN1_ENUMERATED:
+		ret = asn1_print_integer_ctx(out, str, pctx);
+		break;
+
+		case V_ASN1_UTCTIME:
+		ret = ASN1_UTCTIME_print(out, str);
+		break;
+
+		case V_ASN1_GENERALIZEDTIME:
+		ret = ASN1_GENERALIZEDTIME_print(out, str);
+		break;
+
+		case V_ASN1_OBJECT:
+		ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx);
+		break;
+
+		case V_ASN1_OCTET_STRING:
+		case V_ASN1_BIT_STRING:
+		ret = asn1_print_obstring_ctx(out, str, indent, pctx);
+		needlf = 0;
+		break;
+
+		case V_ASN1_SEQUENCE:
+		case V_ASN1_SET:
+		case V_ASN1_OTHER:
+		if (BIO_puts(out, "\n") <= 0)
+			return 0;
+		if (ASN1_parse_dump(out, str->data, str->length,
+						indent, 0) <= 0)
+			ret = 0;
+		needlf = 0;
+		break;
+
+		default:
+		ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
+
+		}
+	if (!ret)
+		return 0;
+	if (needlf && BIO_puts(out, "\n") <= 0)
+		return 0;
+	return 1;
+	}
diff --git a/openssl/crypto/asn1/tasn_typ.c b/openssl/crypto/asn1/tasn_typ.c
new file mode 100644
index 0000000..6fb1c37
--- /dev/null
+++ b/openssl/crypto/asn1/tasn_typ.c
@@ -0,0 +1,148 @@
+/* tasn_typ.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <stdio.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+/* Declarations for string types */
+
+
+IMPLEMENT_ASN1_TYPE(ASN1_INTEGER)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_INTEGER)
+
+IMPLEMENT_ASN1_TYPE(ASN1_ENUMERATED)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_ENUMERATED)
+
+IMPLEMENT_ASN1_TYPE(ASN1_BIT_STRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_BIT_STRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_OCTET_STRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_NULL)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_NULL)
+
+IMPLEMENT_ASN1_TYPE(ASN1_OBJECT)
+
+IMPLEMENT_ASN1_TYPE(ASN1_UTF8STRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTF8STRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_PRINTABLESTRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_T61STRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_T61STRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_IA5STRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_IA5STRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_GENERALSTRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_UTCTIME)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTCTIME)
+
+IMPLEMENT_ASN1_TYPE(ASN1_GENERALIZEDTIME)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
+
+IMPLEMENT_ASN1_TYPE(ASN1_VISIBLESTRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_UNIVERSALSTRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_BMPSTRING)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_BMPSTRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_ANY)
+
+/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */
+IMPLEMENT_ASN1_TYPE(ASN1_SEQUENCE)
+
+IMPLEMENT_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
+
+/* Multistring types */
+
+IMPLEMENT_ASN1_MSTRING(ASN1_PRINTABLE, B_ASN1_PRINTABLE)
+IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
+
+IMPLEMENT_ASN1_MSTRING(DISPLAYTEXT, B_ASN1_DISPLAYTEXT)
+IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
+
+IMPLEMENT_ASN1_MSTRING(DIRECTORYSTRING, B_ASN1_DIRECTORYSTRING)
+IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
+
+/* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */
+IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1)
+IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1)
+IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0)
+
+/* Special, OCTET STRING with indefinite length constructed support */
+
+IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF)
+
+ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY)
+ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY)
+
+ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY)
+ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY)
diff --git a/openssl/crypto/asn1/tasn_utl.c b/openssl/crypto/asn1/tasn_utl.c
new file mode 100644
index 0000000..ca9ec7a
--- /dev/null
+++ b/openssl/crypto/asn1/tasn_utl.c
@@ -0,0 +1,279 @@
+/* tasn_utl.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stddef.h>
+#include <string.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include <openssl/err.h>
+
+/* Utility functions for manipulating fields and offsets */
+
+/* Add 'offset' to 'addr' */
+#define offset2ptr(addr, offset) (void *)(((char *) addr) + offset)
+
+/* Given an ASN1_ITEM CHOICE type return
+ * the selector value
+ */
+
+int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it)
+	{
+	int *sel = offset2ptr(*pval, it->utype);
+	return *sel;
+	}
+
+/* Given an ASN1_ITEM CHOICE type set
+ * the selector value, return old value.
+ */
+
+int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it)
+	{	
+	int *sel, ret;
+	sel = offset2ptr(*pval, it->utype);
+	ret = *sel;
+	*sel = value;
+	return ret;
+	}
+
+/* Do reference counting. The value 'op' decides what to do. 
+ * if it is +1 then the count is incremented. If op is 0 count is
+ * set to 1. If op is -1 count is decremented and the return value
+ * is the current refrence count or 0 if no reference count exists.
+ */
+
+int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
+	{
+	const ASN1_AUX *aux;
+	int *lck, ret;
+	if ((it->itype != ASN1_ITYPE_SEQUENCE)
+	   && (it->itype != ASN1_ITYPE_NDEF_SEQUENCE))
+		return 0;
+	aux = it->funcs;
+	if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT))
+		return 0;
+	lck = offset2ptr(*pval, aux->ref_offset);
+	if (op == 0)
+		{
+		*lck = 1;
+		return 1;
+		}
+	ret = CRYPTO_add(lck, op, aux->ref_lock);
+#ifdef REF_PRINT
+	fprintf(stderr, "%s: Reference Count: %d\n", it->sname, *lck);
+#endif
+#ifdef REF_CHECK
+	if (ret < 0) 
+		fprintf(stderr, "%s, bad reference count\n", it->sname);
+#endif
+	return ret;
+	}
+
+static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it)
+	{
+	const ASN1_AUX *aux;
+	if (!pval || !*pval)
+		return NULL;
+	aux = it->funcs;
+	if (!aux || !(aux->flags & ASN1_AFLG_ENCODING))
+		return NULL;
+	return offset2ptr(*pval, aux->enc_offset);
+	}
+
+void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it)
+	{
+	ASN1_ENCODING *enc;
+	enc = asn1_get_enc_ptr(pval, it);
+	if (enc)
+		{
+		enc->enc = NULL;
+		enc->len = 0;
+		enc->modified = 1;
+		}
+	}
+
+void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+	{
+	ASN1_ENCODING *enc;
+	enc = asn1_get_enc_ptr(pval, it);
+	if (enc)
+		{
+		if (enc->enc)
+			OPENSSL_free(enc->enc);
+		enc->enc = NULL;
+		enc->len = 0;
+		enc->modified = 1;
+		}
+	}
+
+int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
+							 const ASN1_ITEM *it)
+	{
+	ASN1_ENCODING *enc;
+	enc = asn1_get_enc_ptr(pval, it);
+	if (!enc)
+		return 1;
+
+	if (enc->enc)
+		OPENSSL_free(enc->enc);
+	enc->enc = OPENSSL_malloc(inlen);
+	if (!enc->enc)
+		return 0;
+	memcpy(enc->enc, in, inlen);
+	enc->len = inlen;
+	enc->modified = 0;
+
+	return 1;
+	}
+		
+int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
+							const ASN1_ITEM *it)
+	{
+	ASN1_ENCODING *enc;
+	enc = asn1_get_enc_ptr(pval, it);
+	if (!enc || enc->modified)
+		return 0;
+	if (out)
+		{
+		memcpy(*out, enc->enc, enc->len);
+		*out += enc->len;
+		}
+	if (len)
+		*len = enc->len;
+	return 1;
+	}
+
+/* Given an ASN1_TEMPLATE get a pointer to a field */
+ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+	{
+	ASN1_VALUE **pvaltmp;
+	if (tt->flags & ASN1_TFLG_COMBINE)
+		return pval;
+	pvaltmp = offset2ptr(*pval, tt->offset);
+	/* NOTE for BOOLEAN types the field is just a plain
+ 	 * int so we can't return int **, so settle for
+	 * (int *).
+	 */
+	return pvaltmp;
+	}
+
+/* Handle ANY DEFINED BY template, find the selector, look up
+ * the relevant ASN1_TEMPLATE in the table and return it.
+ */
+
+const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
+								int nullerr)
+	{
+	const ASN1_ADB *adb;
+	const ASN1_ADB_TABLE *atbl;
+	long selector;
+	ASN1_VALUE **sfld;
+	int i;
+	if (!(tt->flags & ASN1_TFLG_ADB_MASK))
+		return tt;
+
+	/* Else ANY DEFINED BY ... get the table */
+	adb = ASN1_ADB_ptr(tt->item);
+
+	/* Get the selector field */
+	sfld = offset2ptr(*pval, adb->offset);
+
+	/* Check if NULL */
+	if (!sfld)
+		{
+		if (!adb->null_tt)
+			goto err;
+		return adb->null_tt;
+		}
+
+	/* Convert type to a long:
+	 * NB: don't check for NID_undef here because it
+	 * might be a legitimate value in the table
+	 */
+	if (tt->flags & ASN1_TFLG_ADB_OID) 
+		selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld);
+	else 
+		selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld);
+
+	/* Try to find matching entry in table
+	 * Maybe should check application types first to
+	 * allow application override? Might also be useful
+	 * to have a flag which indicates table is sorted and
+	 * we can do a binary search. For now stick to a
+	 * linear search.
+	 */
+
+	for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++)
+		if (atbl->value == selector)
+			return &atbl->tt;
+
+	/* FIXME: need to search application table too */
+
+	/* No match, return default type */
+	if (!adb->default_tt)
+		goto err;		
+	return adb->default_tt;
+	
+	err:
+	/* FIXME: should log the value or OID of unsupported type */
+	if (nullerr)
+		ASN1err(ASN1_F_ASN1_DO_ADB,
+			ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
+	return NULL;
+	}
diff --git a/openssl/crypto/asn1/x_algor.c b/openssl/crypto/asn1/x_algor.c
new file mode 100644
index 0000000..99e5342
--- /dev/null
+++ b/openssl/crypto/asn1/x_algor.c
@@ -0,0 +1,130 @@
+/* x_algor.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stddef.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+ASN1_SEQUENCE(X509_ALGOR) = {
+	ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
+	ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY)
+} ASN1_SEQUENCE_END(X509_ALGOR)
+
+ASN1_ITEM_TEMPLATE(X509_ALGORS) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR)
+ASN1_ITEM_TEMPLATE_END(X509_ALGORS)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_ALGORS, X509_ALGORS, X509_ALGORS)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR)
+
+IMPLEMENT_STACK_OF(X509_ALGOR)
+IMPLEMENT_ASN1_SET_OF(X509_ALGOR)
+
+int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval)
+	{
+	if (!alg)
+		return 0;
+	if (ptype != V_ASN1_UNDEF)
+		{
+		if (alg->parameter == NULL)
+			alg->parameter = ASN1_TYPE_new();
+		if (alg->parameter == NULL)
+			return 0;
+		}
+	if (alg)
+		{
+		if (alg->algorithm)
+			ASN1_OBJECT_free(alg->algorithm);
+		alg->algorithm = aobj;
+		}
+	if (ptype == 0)
+		return 1;	
+	if (ptype == V_ASN1_UNDEF)
+		{
+		if (alg->parameter)
+			{
+			ASN1_TYPE_free(alg->parameter);
+			alg->parameter = NULL;
+			}
+		}
+	else
+		ASN1_TYPE_set(alg->parameter, ptype, pval);
+	return 1;
+	}
+
+void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
+						X509_ALGOR *algor)
+	{
+	if (paobj)
+		*paobj = algor->algorithm;
+	if (pptype)
+		{
+		if (algor->parameter == NULL)
+			{
+			*pptype = V_ASN1_UNDEF;
+			return;
+			}
+		else
+			*pptype = algor->parameter->type;
+		if (ppval)
+			*ppval = algor->parameter->value.ptr;
+		}
+	}
+
diff --git a/openssl/crypto/asn1/x_attrib.c b/openssl/crypto/asn1/x_attrib.c
new file mode 100644
index 0000000..1e3713f
--- /dev/null
+++ b/openssl/crypto/asn1/x_attrib.c
@@ -0,0 +1,118 @@
+/* crypto/asn1/x_attrib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+
+/* X509_ATTRIBUTE: this has the following form:
+ *
+ * typedef struct x509_attributes_st
+ *	{
+ *	ASN1_OBJECT *object;
+ *	int single;
+ *	union	{
+ *		char		*ptr;
+ * 		STACK_OF(ASN1_TYPE) *set;
+ * 		ASN1_TYPE	*single;
+ *		} value;
+ *	} X509_ATTRIBUTE;
+ *
+ * this needs some extra thought because the CHOICE type is
+ * merged with the main structure and because the value can
+ * be anything at all we *must* try the SET OF first because
+ * the ASN1_ANY type will swallow anything including the whole
+ * SET OF structure.
+ */
+
+ASN1_CHOICE(X509_ATTRIBUTE_SET) = {
+	ASN1_SET_OF(X509_ATTRIBUTE, value.set, ASN1_ANY),
+	ASN1_SIMPLE(X509_ATTRIBUTE, value.single, ASN1_ANY)
+} ASN1_CHOICE_END_selector(X509_ATTRIBUTE, X509_ATTRIBUTE_SET, single)
+
+ASN1_SEQUENCE(X509_ATTRIBUTE) = {
+	ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT),
+	/* CHOICE type merged with parent */
+	ASN1_EX_COMBINE(0, 0, X509_ATTRIBUTE_SET)
+} ASN1_SEQUENCE_END(X509_ATTRIBUTE)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_ATTRIBUTE)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_ATTRIBUTE)
+
+X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value)
+	{
+	X509_ATTRIBUTE *ret=NULL;
+	ASN1_TYPE *val=NULL;
+
+	if ((ret=X509_ATTRIBUTE_new()) == NULL)
+		return(NULL);
+	ret->object=OBJ_nid2obj(nid);
+	ret->single=0;
+	if ((ret->value.set=sk_ASN1_TYPE_new_null()) == NULL) goto err;
+	if ((val=ASN1_TYPE_new()) == NULL) goto err;
+	if (!sk_ASN1_TYPE_push(ret->value.set,val)) goto err;
+
+	ASN1_TYPE_set(val,atrtype,value);
+	return(ret);
+err:
+	if (ret != NULL) X509_ATTRIBUTE_free(ret);
+	if (val != NULL) ASN1_TYPE_free(val);
+	return(NULL);
+	}
diff --git a/openssl/crypto/asn1/x_bignum.c b/openssl/crypto/asn1/x_bignum.c
new file mode 100644
index 0000000..9cf3204
--- /dev/null
+++ b/openssl/crypto/asn1/x_bignum.c
@@ -0,0 +1,139 @@
+/* x_bignum.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/bn.h>
+
+/* Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER as a
+ * BIGNUM directly. Currently it ignores the sign which isn't a problem since all
+ * BIGNUMs used are non negative and anything that looks negative is normally due
+ * to an encoding error.
+ */
+
+#define BN_SENSITIVE	1
+
+static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
+static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
+
+static ASN1_PRIMITIVE_FUNCS bignum_pf = {
+	NULL, 0,
+	bn_new,
+	bn_free,
+	0,
+	bn_c2i,
+	bn_i2c
+};
+
+ASN1_ITEM_start(BIGNUM)
+	ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM"
+ASN1_ITEM_end(BIGNUM)
+
+ASN1_ITEM_start(CBIGNUM)
+	ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM"
+ASN1_ITEM_end(CBIGNUM)
+
+static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	*pval = (ASN1_VALUE *)BN_new();
+	if(*pval) return 1;
+	else return 0;
+}
+
+static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	if(!*pval) return;
+	if(it->size & BN_SENSITIVE) BN_clear_free((BIGNUM *)*pval);
+	else BN_free((BIGNUM *)*pval);
+	*pval = NULL;
+}
+
+static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it)
+{
+	BIGNUM *bn;
+	int pad;
+	if(!*pval) return -1;
+	bn = (BIGNUM *)*pval;
+	/* If MSB set in an octet we need a padding byte */
+	if(BN_num_bits(bn) & 0x7) pad = 0;
+	else pad = 1;
+	if(cont) {
+		if(pad) *cont++ = 0;
+		BN_bn2bin(bn, cont);
+	}
+	return pad + BN_num_bytes(bn);
+}
+
+static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+		  int utype, char *free_cont, const ASN1_ITEM *it)
+{
+	BIGNUM *bn;
+	if(!*pval) bn_new(pval, it);
+	bn  = (BIGNUM *)*pval;
+	if(!BN_bin2bn(cont, len, bn)) {
+		bn_free(pval, it);
+		return 0;
+	}
+	return 1;
+}
+
+
diff --git a/openssl/crypto/asn1/x_crl.c b/openssl/crypto/asn1/x_crl.c
new file mode 100644
index 0000000..c51c690
--- /dev/null
+++ b/openssl/crypto/asn1/x_crl.c
@@ -0,0 +1,527 @@
+/* crypto/asn1/x_crl.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "asn1_locl.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
+				const X509_REVOKED * const *b);
+static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
+
+ASN1_SEQUENCE(X509_REVOKED) = {
+	ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
+	ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME),
+	ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
+} ASN1_SEQUENCE_END(X509_REVOKED)
+
+static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r);
+static int def_crl_lookup(X509_CRL *crl,
+		X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer);
+
+static X509_CRL_METHOD int_crl_meth =
+	{
+	0,
+	0,0,
+	def_crl_lookup,
+	def_crl_verify
+	};
+
+static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;
+
+/* The X509_CRL_INFO structure needs a bit of customisation.
+ * Since we cache the original encoding the signature wont be affected by
+ * reordering of the revoked field.
+ */
+static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+								void *exarg)
+{
+	X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
+
+	if(!a || !a->revoked) return 1;
+	switch(operation) {
+		/* Just set cmp function here. We don't sort because that
+		 * would affect the output of X509_CRL_print().
+		 */
+		case ASN1_OP_D2I_POST:
+		(void)sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp);
+		break;
+	}
+	return 1;
+}
+
+
+ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = {
+	ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER),
+	ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR),
+	ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME),
+	ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME),
+	ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME),
+	ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED),
+	ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
+} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)
+
+/* Set CRL entry issuer according to CRL certificate issuer extension.
+ * Check for unhandled critical CRL entry extensions.
+ */
+
+static int crl_set_issuers(X509_CRL *crl)
+	{
+
+	int i, j;
+	GENERAL_NAMES *gens, *gtmp;
+	STACK_OF(X509_REVOKED) *revoked;
+
+	revoked = X509_CRL_get_REVOKED(crl);
+
+	gens = NULL;
+	for (i = 0; i < sk_X509_REVOKED_num(revoked); i++)
+		{
+		X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
+		STACK_OF(X509_EXTENSION) *exts;
+		ASN1_ENUMERATED *reason;
+		X509_EXTENSION *ext;
+		gtmp = X509_REVOKED_get_ext_d2i(rev, 
+						NID_certificate_issuer,
+						&j, NULL);
+		if (!gtmp && (j != -1))
+			{
+			crl->flags |= EXFLAG_INVALID;
+			return 1;
+			}
+
+		if (gtmp)
+			{
+			gens = gtmp;
+			if (!crl->issuers)
+				{
+				crl->issuers = sk_GENERAL_NAMES_new_null();
+				if (!crl->issuers)
+					return 0;
+				}
+			if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
+				return 0;
+			}
+		rev->issuer = gens;
+
+		reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason,
+								&j, NULL);
+		if (!reason && (j != -1))
+			{
+			crl->flags |= EXFLAG_INVALID;
+			return 1;
+			}
+
+		if (reason)
+			{
+			rev->reason = ASN1_ENUMERATED_get(reason);
+			ASN1_ENUMERATED_free(reason);
+			}
+		else
+			rev->reason = CRL_REASON_NONE;	
+
+		/* Check for critical CRL entry extensions */
+
+		exts = rev->extensions;
+
+		for (j = 0; j < sk_X509_EXTENSION_num(exts); j++)
+			{
+			ext = sk_X509_EXTENSION_value(exts, j);
+			if (ext->critical > 0)
+				{
+				if (OBJ_obj2nid(ext->object) ==
+					NID_certificate_issuer)
+					continue;
+				crl->flags |= EXFLAG_CRITICAL;
+				break;
+				}
+			}
+
+
+		}
+
+	return 1;
+
+	}
+
+/* The X509_CRL structure needs a bit of customisation. Cache some extensions
+ * and hash of the whole CRL.
+ */
+static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+								void *exarg)
+	{
+	X509_CRL *crl = (X509_CRL *)*pval;
+	STACK_OF(X509_EXTENSION) *exts;
+	X509_EXTENSION *ext;
+	int idx;
+
+	switch(operation)
+		{
+		case ASN1_OP_NEW_POST:
+		crl->idp = NULL;
+		crl->akid = NULL;
+		crl->flags = 0;
+		crl->idp_flags = 0;
+		crl->idp_reasons = CRLDP_ALL_REASONS;
+		crl->meth = default_crl_method;
+		crl->meth_data = NULL;
+		crl->issuers = NULL;
+		crl->crl_number = NULL;
+		crl->base_crl_number = NULL;
+		break;
+
+		case ASN1_OP_D2I_POST:
+#ifndef OPENSSL_NO_SHA
+		X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
+#endif
+		crl->idp = X509_CRL_get_ext_d2i(crl,
+				NID_issuing_distribution_point, NULL, NULL);
+		if (crl->idp)
+			setup_idp(crl, crl->idp);
+
+		crl->akid = X509_CRL_get_ext_d2i(crl,
+				NID_authority_key_identifier, NULL, NULL);	
+
+		crl->crl_number = X509_CRL_get_ext_d2i(crl,
+				NID_crl_number, NULL, NULL);	
+
+		crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
+				NID_delta_crl, NULL, NULL);	
+		/* Delta CRLs must have CRL number */
+		if (crl->base_crl_number && !crl->crl_number)
+			crl->flags |= EXFLAG_INVALID;
+
+		/* See if we have any unhandled critical CRL extensions and 
+		 * indicate this in a flag. We only currently handle IDP so
+		 * anything else critical sets the flag.
+		 *
+		 * This code accesses the X509_CRL structure directly:
+		 * applications shouldn't do this.
+		 */
+
+		exts = crl->crl->extensions;
+
+		for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++)
+			{
+			int nid;
+			ext = sk_X509_EXTENSION_value(exts, idx);
+			nid = OBJ_obj2nid(ext->object);
+			if (nid == NID_freshest_crl)
+				crl->flags |= EXFLAG_FRESHEST;
+			if (ext->critical > 0)
+				{
+				/* We handle IDP and deltas */
+				if ((nid == NID_issuing_distribution_point)
+					|| (nid == NID_delta_crl))
+					break;;
+				crl->flags |= EXFLAG_CRITICAL;
+				break;
+				}
+			}
+
+
+		if (!crl_set_issuers(crl))
+			return 0;
+
+		if (crl->meth->crl_init)
+			{
+			if (crl->meth->crl_init(crl) == 0)
+				return 0;
+			}
+		break;
+
+		case ASN1_OP_FREE_POST:
+		if (crl->meth->crl_free)
+			{
+			if (!crl->meth->crl_free(crl))
+				return 0;
+			}
+		if (crl->akid)
+			AUTHORITY_KEYID_free(crl->akid);
+		if (crl->idp)
+			ISSUING_DIST_POINT_free(crl->idp);
+		ASN1_INTEGER_free(crl->crl_number);
+		ASN1_INTEGER_free(crl->base_crl_number);
+		sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
+		break;
+		}
+	return 1;
+	}
+
+/* Convert IDP into a more convenient form */
+
+static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
+	{
+	int idp_only = 0;
+	/* Set various flags according to IDP */
+	crl->idp_flags |= IDP_PRESENT;
+	if (idp->onlyuser > 0)
+		{
+		idp_only++;
+		crl->idp_flags |= IDP_ONLYUSER;
+		}
+	if (idp->onlyCA > 0)
+		{
+		idp_only++;
+		crl->idp_flags |= IDP_ONLYCA;
+		}
+	if (idp->onlyattr > 0)
+		{
+		idp_only++;
+		crl->idp_flags |= IDP_ONLYATTR;
+		}
+
+	if (idp_only > 1)
+		crl->idp_flags |= IDP_INVALID;
+
+	if (idp->indirectCRL > 0)
+		crl->idp_flags |= IDP_INDIRECT;
+
+	if (idp->onlysomereasons)
+		{
+		crl->idp_flags |= IDP_REASONS;
+		if (idp->onlysomereasons->length > 0)
+			crl->idp_reasons = idp->onlysomereasons->data[0];
+		if (idp->onlysomereasons->length > 1)
+			crl->idp_reasons |=
+				(idp->onlysomereasons->data[1] << 8);
+		crl->idp_reasons &= CRLDP_ALL_REASONS;
+		}
+
+	DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
+	}
+
+ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = {
+	ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
+	ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
+	ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED)
+IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO)
+IMPLEMENT_ASN1_FUNCTIONS(X509_CRL)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL)
+
+static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
+			const X509_REVOKED * const *b)
+	{
+	return(ASN1_STRING_cmp(
+		(ASN1_STRING *)(*a)->serialNumber,
+		(ASN1_STRING *)(*b)->serialNumber));
+	}
+
+int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
+{
+	X509_CRL_INFO *inf;
+	inf = crl->crl;
+	if(!inf->revoked)
+		inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
+	if(!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
+		ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	inf->enc.modified = 1;
+	return 1;
+}
+
+int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
+	{
+	if (crl->meth->crl_verify)
+		return crl->meth->crl_verify(crl, r);
+	return 0;
+	}
+
+int X509_CRL_get0_by_serial(X509_CRL *crl,
+		X509_REVOKED **ret, ASN1_INTEGER *serial)
+	{
+	if (crl->meth->crl_lookup)
+		return crl->meth->crl_lookup(crl, ret, serial, NULL);
+	return 0;
+	}
+
+int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
+	{
+	if (crl->meth->crl_lookup)
+		return crl->meth->crl_lookup(crl, ret,
+						X509_get_serialNumber(x),
+						X509_get_issuer_name(x));
+	return 0;
+	}
+
+static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
+	{
+	return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
+		crl->sig_alg, crl->signature,crl->crl,r));
+	}
+
+static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
+						X509_REVOKED *rev)
+	{
+	int i;
+
+	if (!rev->issuer)
+		{
+		if (!nm)
+			return 1;
+		if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
+			return 1;
+		return 0;
+		}
+
+	if (!nm)
+		nm = X509_CRL_get_issuer(crl);
+
+	for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++)
+		{
+		GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
+		if (gen->type != GEN_DIRNAME)
+			continue;
+		if (!X509_NAME_cmp(nm, gen->d.directoryName))
+			return 1;
+		}
+	return 0;
+
+	}
+
+static int def_crl_lookup(X509_CRL *crl,
+		X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer)
+	{
+	X509_REVOKED rtmp, *rev;
+	int idx;
+	rtmp.serialNumber = serial;
+	/* Sort revoked into serial number order if not already sorted.
+	 * Do this under a lock to avoid race condition.
+ 	 */
+	if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
+		{
+		CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
+		sk_X509_REVOKED_sort(crl->crl->revoked);
+		CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
+		}
+	idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);
+	if(idx < 0)
+		return 0;
+	/* Need to look for matching name */
+	for(;idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++)
+		{
+		rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
+		if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
+			return 0;
+		if (crl_revoked_issuer_match(crl, issuer, rev))
+			{
+			if (ret)
+				*ret = rev;
+			if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
+				return 2;
+			return 1;
+			}
+		}
+	return 0;
+	}
+
+void X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
+	{
+	if (meth == NULL)
+		default_crl_method = &int_crl_meth;
+	else 
+		default_crl_method = meth;
+	}
+
+X509_CRL_METHOD *X509_CRL_METHOD_new(
+	int (*crl_init)(X509_CRL *crl),
+	int (*crl_free)(X509_CRL *crl),
+	int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
+				ASN1_INTEGER *ser, X509_NAME *issuer),
+	int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk))
+	{
+	X509_CRL_METHOD *m;
+	m = OPENSSL_malloc(sizeof(X509_CRL_METHOD));
+	if (!m)
+		return NULL;
+	m->crl_init = crl_init;
+	m->crl_free = crl_free;
+	m->crl_lookup = crl_lookup;
+	m->crl_verify = crl_verify;
+	m->flags = X509_CRL_METHOD_DYNAMIC;
+	return m;
+	}
+
+void X509_CRL_METHOD_free(X509_CRL_METHOD *m)
+	{
+	if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
+		return;
+	OPENSSL_free(m);
+	}
+
+void X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
+	{
+	crl->meth_data = dat;
+	}
+
+void *X509_CRL_get_meth_data(X509_CRL *crl)
+	{
+	return crl->meth_data;
+	}
+
+IMPLEMENT_STACK_OF(X509_REVOKED)
+IMPLEMENT_ASN1_SET_OF(X509_REVOKED)
+IMPLEMENT_STACK_OF(X509_CRL)
+IMPLEMENT_ASN1_SET_OF(X509_CRL)
diff --git a/openssl/crypto/asn1/x_exten.c b/openssl/crypto/asn1/x_exten.c
new file mode 100644
index 0000000..3a21239
--- /dev/null
+++ b/openssl/crypto/asn1/x_exten.c
@@ -0,0 +1,76 @@
+/* x_exten.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stddef.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+ASN1_SEQUENCE(X509_EXTENSION) = {
+	ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT),
+	ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN),
+	ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(X509_EXTENSION)
+
+ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION)
+ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_EXTENSION)
diff --git a/openssl/crypto/asn1/x_info.c b/openssl/crypto/asn1/x_info.c
new file mode 100644
index 0000000..d44f6cd
--- /dev/null
+++ b/openssl/crypto/asn1/x_info.c
@@ -0,0 +1,114 @@
+/* crypto/asn1/x_info.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+
+X509_INFO *X509_INFO_new(void)
+	{
+	X509_INFO *ret=NULL;
+
+	ret=(X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO));
+	if (ret == NULL)
+		{
+		ASN1err(ASN1_F_X509_INFO_NEW,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+ 
+        ret->enc_cipher.cipher=NULL;
+        ret->enc_len=0;
+        ret->enc_data=NULL;
+ 
+	ret->references=1;
+	ret->x509=NULL;
+	ret->crl=NULL;
+	ret->x_pkey=NULL;
+	return(ret);
+	}
+
+void X509_INFO_free(X509_INFO *x)
+	{
+	int i;
+
+	if (x == NULL) return;
+
+	i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_X509_INFO);
+#ifdef REF_PRINT
+	REF_PRINT("X509_INFO",x);
+#endif
+	if (i > 0) return;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"X509_INFO_free, bad reference count\n");
+		abort();
+		}
+#endif
+
+	if (x->x509 != NULL) X509_free(x->x509);
+	if (x->crl != NULL) X509_CRL_free(x->crl);
+	if (x->x_pkey != NULL) X509_PKEY_free(x->x_pkey);
+	if (x->enc_data != NULL) OPENSSL_free(x->enc_data);
+	OPENSSL_free(x);
+	}
+
+IMPLEMENT_STACK_OF(X509_INFO)
+
diff --git a/openssl/crypto/asn1/x_long.c b/openssl/crypto/asn1/x_long.c
new file mode 100644
index 0000000..7531741
--- /dev/null
+++ b/openssl/crypto/asn1/x_long.c
@@ -0,0 +1,179 @@
+/* x_long.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/bn.h>
+
+/* Custom primitive type for long handling. This converts between an ASN1_INTEGER
+ * and a long directly.
+ */
+
+
+static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
+static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
+static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
+
+static ASN1_PRIMITIVE_FUNCS long_pf = {
+	NULL, 0,
+	long_new,
+	long_free,
+	long_free,	/* Clear should set to initial value */
+	long_c2i,
+	long_i2c,
+	long_print
+};
+
+ASN1_ITEM_start(LONG)
+	ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG"
+ASN1_ITEM_end(LONG)
+
+ASN1_ITEM_start(ZLONG)
+	ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG"
+ASN1_ITEM_end(ZLONG)
+
+static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	*(long *)pval = it->size;
+	return 1;
+}
+
+static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	*(long *)pval = it->size;
+}
+
+static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it)
+{
+	long ltmp;
+	unsigned long utmp;
+	int clen, pad, i;
+	/* this exists to bypass broken gcc optimization */
+	char *cp = (char *)pval;
+
+	/* use memcpy, because we may not be long aligned */
+	memcpy(&ltmp, cp, sizeof(long));
+
+	if(ltmp == it->size) return -1;
+	/* Convert the long to positive: we subtract one if negative so
+	 * we can cleanly handle the padding if only the MSB of the leading
+	 * octet is set. 
+	 */
+	if(ltmp < 0) utmp = -ltmp - 1;
+	else utmp = ltmp;
+	clen = BN_num_bits_word(utmp);
+	/* If MSB of leading octet set we need to pad */
+	if(!(clen & 0x7)) pad = 1;
+	else pad = 0;
+
+	/* Convert number of bits to number of octets */
+	clen = (clen + 7) >> 3;
+
+	if(cont) {
+		if(pad) *cont++ = (ltmp < 0) ? 0xff : 0;
+		for(i = clen - 1; i >= 0; i--) {
+			cont[i] = (unsigned char)(utmp & 0xff);
+			if(ltmp < 0) cont[i] ^= 0xff;
+			utmp >>= 8;
+		}
+	}
+	return clen + pad;
+}
+
+static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+		    int utype, char *free_cont, const ASN1_ITEM *it)
+{
+	int neg, i;
+	long ltmp;
+	unsigned long utmp = 0;
+	char *cp = (char *)pval;
+	if(len > (int)sizeof(long)) {
+		ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+		return 0;
+	}
+	/* Is it negative? */
+	if(len && (cont[0] & 0x80)) neg = 1;
+	else neg = 0;
+	utmp = 0;
+	for(i = 0; i < len; i++) {
+		utmp <<= 8;
+		if(neg) utmp |= cont[i] ^ 0xff;
+		else utmp |= cont[i];
+	}
+	ltmp = (long)utmp;
+	if(neg) {
+		ltmp++;
+		ltmp = -ltmp;
+	}
+	if(ltmp == it->size) {
+		ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+		return 0;
+	}
+	memcpy(cp, &ltmp, sizeof(long));
+	return 1;
+}
+
+static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+			int indent, const ASN1_PCTX *pctx)
+	{
+	return BIO_printf(out, "%ld\n", *(long *)pval);
+	}
diff --git a/openssl/crypto/asn1/x_name.c b/openssl/crypto/asn1/x_name.c
new file mode 100644
index 0000000..49be08b
--- /dev/null
+++ b/openssl/crypto/asn1/x_name.c
@@ -0,0 +1,520 @@
+/* crypto/asn1/x_name.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "asn1_locl.h"
+
+typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
+DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
+
+static int x509_name_ex_d2i(ASN1_VALUE **val,
+				const unsigned char **in, long len,
+				const ASN1_ITEM *it,
+				int tag, int aclass, char opt, ASN1_TLC *ctx);
+
+static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
+				const ASN1_ITEM *it, int tag, int aclass);
+static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
+static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
+
+static int x509_name_encode(X509_NAME *a);
+static int x509_name_canon(X509_NAME *a);
+static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
+static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname,
+			  unsigned char **in);
+
+
+static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
+						int indent,
+						const char *fname, 
+						const ASN1_PCTX *pctx);
+
+ASN1_SEQUENCE(X509_NAME_ENTRY) = {
+	ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
+	ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
+} ASN1_SEQUENCE_END(X509_NAME_ENTRY)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
+
+/* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY }
+ * so declare two template wrappers for this
+ */
+
+ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
+ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
+
+ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
+ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
+
+/* Normally that's where it would end: we'd have two nested STACK structures
+ * representing the ASN1. Unfortunately X509_NAME uses a completely different
+ * form and caches encodings so we have to process the internal form and convert
+ * to the external form.
+ */
+
+const ASN1_EXTERN_FUNCS x509_name_ff = {
+	NULL,
+	x509_name_ex_new,
+	x509_name_ex_free,
+	0,	/* Default clear behaviour is OK */
+	x509_name_ex_d2i,
+	x509_name_ex_i2d,
+	x509_name_ex_print
+};
+
+IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) 
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
+
+static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
+{
+	X509_NAME *ret = NULL;
+	ret = OPENSSL_malloc(sizeof(X509_NAME));
+	if(!ret) goto memerr;
+	if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL)
+		goto memerr;
+	if((ret->bytes = BUF_MEM_new()) == NULL) goto memerr;
+	ret->canon_enc = NULL;
+	ret->canon_enclen = 0;
+	ret->modified=1;
+	*val = (ASN1_VALUE *)ret;
+	return 1;
+
+ memerr:
+	ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
+	if (ret)
+		{
+		if (ret->entries)
+			sk_X509_NAME_ENTRY_free(ret->entries);
+		OPENSSL_free(ret);
+		}
+	return 0;
+}
+
+static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	X509_NAME *a;
+	if(!pval || !*pval)
+	    return;
+	a = (X509_NAME *)*pval;
+
+	BUF_MEM_free(a->bytes);
+	sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free);
+	if (a->canon_enc)
+		OPENSSL_free(a->canon_enc);
+	OPENSSL_free(a);
+	*pval = NULL;
+}
+
+static int x509_name_ex_d2i(ASN1_VALUE **val,
+			const unsigned char **in, long len, const ASN1_ITEM *it,
+				int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+	const unsigned char *p = *in, *q;
+	union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
+		ASN1_VALUE *a; } intname = {NULL};
+	union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL};
+	int i, j, ret;
+	STACK_OF(X509_NAME_ENTRY) *entries;
+	X509_NAME_ENTRY *entry;
+	q = p;
+
+	/* Get internal representation of Name */
+	ret = ASN1_item_ex_d2i(&intname.a,
+			       &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
+			       tag, aclass, opt, ctx);
+	
+	if(ret <= 0) return ret;
+
+	if(*val) x509_name_ex_free(val, NULL);
+	if(!x509_name_ex_new(&nm.a, NULL)) goto err;
+	/* We've decoded it: now cache encoding */
+	if(!BUF_MEM_grow(nm.x->bytes, p - q)) goto err;
+	memcpy(nm.x->bytes->data, q, p - q);
+
+	/* Convert internal representation to X509_NAME structure */
+	for(i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
+		entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
+		for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
+			entry = sk_X509_NAME_ENTRY_value(entries, j);
+			entry->set = i;
+			if(!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
+				goto err;
+		}
+		sk_X509_NAME_ENTRY_free(entries);
+	}
+	sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
+	ret = x509_name_canon(nm.x);
+	if (!ret)
+		goto err;
+	nm.x->modified = 0;
+	*val = nm.a;
+	*in = p;
+	return ret;
+err:
+        if (nm.x != NULL)
+		X509_NAME_free(nm.x);
+	ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+	return 0;
+}
+
+static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass)
+{
+	int ret;
+	X509_NAME *a = (X509_NAME *)*val;
+	if(a->modified) {
+		ret = x509_name_encode(a);
+		if(ret < 0)
+			return ret;
+		ret = x509_name_canon(a);
+		if(ret < 0)
+			return ret;
+	}
+	ret = a->bytes->length;
+	if(out != NULL) {
+		memcpy(*out,a->bytes->data,ret);
+		*out+=ret;
+	}
+	return ret;
+}
+
+static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
+	{
+	sk_X509_NAME_ENTRY_free(ne);
+	}
+
+static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
+	{
+	sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
+	}
+
+static int x509_name_encode(X509_NAME *a)
+{
+	union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
+		ASN1_VALUE *a; } intname = {NULL};
+	int len;
+	unsigned char *p;
+	STACK_OF(X509_NAME_ENTRY) *entries = NULL;
+	X509_NAME_ENTRY *entry;
+	int i, set = -1;
+	intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
+	if(!intname.s) goto memerr;
+	for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
+		entry = sk_X509_NAME_ENTRY_value(a->entries, i);
+		if(entry->set != set) {
+			entries = sk_X509_NAME_ENTRY_new_null();
+			if(!entries) goto memerr;
+			if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s,
+							     entries))
+				goto memerr;
+			set = entry->set;
+		}
+		if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr;
+	}
+	len = ASN1_item_ex_i2d(&intname.a, NULL,
+			       ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
+	if (!BUF_MEM_grow(a->bytes,len)) goto memerr;
+	p=(unsigned char *)a->bytes->data;
+	ASN1_item_ex_i2d(&intname.a,
+			 &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
+	sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+					     local_sk_X509_NAME_ENTRY_free);
+	a->modified = 0;
+	return len;
+memerr:
+	sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+					     local_sk_X509_NAME_ENTRY_free);
+	ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
+	return -1;
+}
+
+static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
+						int indent,
+						const char *fname, 
+						const ASN1_PCTX *pctx)
+	{
+	if (X509_NAME_print_ex(out, (X509_NAME *)*pval,
+					indent, pctx->nm_flags) <= 0)
+		return 0;
+	return 2;
+	}
+
+/* This function generates the canonical encoding of the Name structure.
+ * In it all strings are converted to UTF8, leading, trailing and
+ * multiple spaces collapsed, converted to lower case and the leading
+ * SEQUENCE header removed.
+ *
+ * In future we could also normalize the UTF8 too.
+ *
+ * By doing this comparison of Name structures can be rapidly
+ * perfomed by just using memcmp() of the canonical encoding.
+ * By omitting the leading SEQUENCE name constraints of type
+ * dirName can also be checked with a simple memcmp().
+ */
+
+static int x509_name_canon(X509_NAME *a)
+	{
+	unsigned char *p;
+	STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
+	STACK_OF(X509_NAME_ENTRY) *entries = NULL;
+	X509_NAME_ENTRY *entry, *tmpentry = NULL;
+	int i, set = -1, ret = 0;
+
+	if (a->canon_enc)
+		{
+		OPENSSL_free(a->canon_enc);
+		a->canon_enc = NULL;
+		}
+	/* Special case: empty X509_NAME => null encoding */
+	if (sk_X509_NAME_ENTRY_num(a->entries) == 0)
+		{
+		a->canon_enclen = 0;
+		return 1;
+		}
+	intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
+	if(!intname)
+		goto err;
+	for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++)
+		{
+		entry = sk_X509_NAME_ENTRY_value(a->entries, i);
+		if(entry->set != set)
+			{
+			entries = sk_X509_NAME_ENTRY_new_null();
+			if(!entries)
+				goto err;
+			if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries))
+				goto err;
+			set = entry->set;
+			}
+		tmpentry = X509_NAME_ENTRY_new();
+		tmpentry->object = OBJ_dup(entry->object);
+		if (!asn1_string_canon(tmpentry->value, entry->value))
+			goto err;
+		if(!sk_X509_NAME_ENTRY_push(entries, tmpentry))
+			goto err;
+		tmpentry = NULL;
+		}
+
+	/* Finally generate encoding */
+
+	a->canon_enclen = i2d_name_canon(intname, NULL);
+
+	p = OPENSSL_malloc(a->canon_enclen);
+
+	if (!p)
+		goto err;
+
+	a->canon_enc = p;
+
+	i2d_name_canon(intname, &p);
+
+	ret = 1;
+
+	err:
+
+	if (tmpentry)
+		X509_NAME_ENTRY_free(tmpentry);
+	if (intname)
+		sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
+					local_sk_X509_NAME_ENTRY_pop_free);
+	return ret;
+	}
+
+/* Bitmap of all the types of string that will be canonicalized. */
+
+#define ASN1_MASK_CANON	\
+	(B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
+	| B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
+	| B_ASN1_VISIBLESTRING)
+	
+
+static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
+	{
+	unsigned char *to, *from;
+	int len, i;
+
+	/* If type not in bitmask just copy string across */
+	if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON))
+		{
+		out->type = in->type;
+		if (!ASN1_STRING_set(out, in->data, in->length))
+			return 0;
+		return 1;
+		}
+
+	out->type = V_ASN1_UTF8STRING;
+	out->length = ASN1_STRING_to_UTF8(&out->data, in);
+	if (out->length == -1)
+		return 0;
+
+	to = out->data;
+	from = to;
+
+	len = out->length;
+
+	/* Convert string in place to canonical form.
+	 * Ultimately we may need to handle a wider range of characters
+	 * but for now ignore anything with MSB set and rely on the
+	 * isspace() and tolower() functions.
+	 */
+
+	/* Ignore leading spaces */
+	while((len > 0) && !(*from & 0x80) && isspace(*from))
+		{
+		from++;
+		len--;
+		}
+
+	to = from + len - 1;
+
+	/* Ignore trailing spaces */
+	while ((len > 0) && !(*to & 0x80) && isspace(*to))
+		{
+		to--;
+		len--;
+		}
+
+	to = out->data;
+
+	i = 0;
+	while(i < len)
+		{
+		/* If MSB set just copy across */
+		if (*from & 0x80)
+			{
+			*to++ = *from++;
+			i++;
+			}
+		/* Collapse multiple spaces */
+		else if (isspace(*from))
+			{
+			/* Copy one space across */
+			*to++ = ' ';
+			/* Ignore subsequent spaces. Note: don't need to
+			 * check len here because we know the last 
+			 * character is a non-space so we can't overflow.
+			 */
+			do
+				{
+				from++;
+				i++;
+				}
+			while(!(*from & 0x80) && isspace(*from));
+			}
+		else
+			{
+			*to++ = tolower(*from);
+			from++;
+			i++;
+			}
+		}
+
+	out->length = to - out->data;
+
+	return 1;
+
+	}
+
+static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname,
+			  unsigned char **in)
+	{
+	int i, len, ltmp;
+	ASN1_VALUE *v;
+	STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
+
+	len = 0;
+	for (i = 0; i < sk_ASN1_VALUE_num(intname); i++)
+		{
+		v = sk_ASN1_VALUE_value(intname, i);
+		ltmp = ASN1_item_ex_i2d(&v, in,
+			ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
+		if (ltmp < 0)
+			return ltmp;
+		len += ltmp;
+		}
+	return len;
+	}
+
+int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
+	{
+	X509_NAME *in;
+
+	if (!xn || !name) return(0);
+
+	if (*xn != name)
+		{
+		in=X509_NAME_dup(name);
+		if (in != NULL)
+			{
+			X509_NAME_free(*xn);
+			*xn=in;
+			}
+		}
+	return(*xn != NULL);
+	}
+	
+IMPLEMENT_STACK_OF(X509_NAME_ENTRY)
+IMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY)
diff --git a/openssl/crypto/asn1/x_nx509.c b/openssl/crypto/asn1/x_nx509.c
new file mode 100644
index 0000000..fbd9a22
--- /dev/null
+++ b/openssl/crypto/asn1/x_nx509.c
@@ -0,0 +1,72 @@
+/* x_nx509.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stddef.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+/* Old netscape certificate wrapper format */
+
+ASN1_SEQUENCE(NETSCAPE_X509) = {
+	ASN1_SIMPLE(NETSCAPE_X509, header, ASN1_OCTET_STRING),
+	ASN1_OPT(NETSCAPE_X509, cert, X509)
+} ASN1_SEQUENCE_END(NETSCAPE_X509)
+
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_X509)
+
diff --git a/openssl/crypto/asn1/x_pkey.c b/openssl/crypto/asn1/x_pkey.c
new file mode 100644
index 0000000..8453618
--- /dev/null
+++ b/openssl/crypto/asn1/x_pkey.c
@@ -0,0 +1,151 @@
+/* crypto/asn1/x_pkey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/asn1_mac.h>
+#include <openssl/x509.h>
+
+/* need to implement */
+int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp)
+	{
+	return(0);
+	}
+
+X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp, long length)
+	{
+	int i;
+	M_ASN1_D2I_vars(a,X509_PKEY *,X509_PKEY_new);
+
+	M_ASN1_D2I_Init();
+	M_ASN1_D2I_start_sequence();
+	M_ASN1_D2I_get_x(X509_ALGOR,ret->enc_algor,d2i_X509_ALGOR);
+	M_ASN1_D2I_get_x(ASN1_OCTET_STRING,ret->enc_pkey,d2i_ASN1_OCTET_STRING);
+
+	ret->cipher.cipher=EVP_get_cipherbyname(
+		OBJ_nid2ln(OBJ_obj2nid(ret->enc_algor->algorithm)));
+	if (ret->cipher.cipher == NULL)
+		{
+		c.error=ASN1_R_UNSUPPORTED_CIPHER;
+		c.line=__LINE__;
+		goto err;
+		}
+	if (ret->enc_algor->parameter->type == V_ASN1_OCTET_STRING) 
+		{
+		i=ret->enc_algor->parameter->value.octet_string->length;
+		if (i > EVP_MAX_IV_LENGTH)
+			{
+			c.error=ASN1_R_IV_TOO_LARGE;
+			c.line=__LINE__;
+			goto err;
+			}
+		memcpy(ret->cipher.iv,
+			ret->enc_algor->parameter->value.octet_string->data,i);
+		}
+	else
+		memset(ret->cipher.iv,0,EVP_MAX_IV_LENGTH);
+	M_ASN1_D2I_Finish(a,X509_PKEY_free,ASN1_F_D2I_X509_PKEY);
+	}
+
+X509_PKEY *X509_PKEY_new(void)
+	{
+	X509_PKEY *ret=NULL;
+	ASN1_CTX c;
+
+	M_ASN1_New_Malloc(ret,X509_PKEY);
+	ret->version=0;
+	M_ASN1_New(ret->enc_algor,X509_ALGOR_new);
+	M_ASN1_New(ret->enc_pkey,M_ASN1_OCTET_STRING_new);
+	ret->dec_pkey=NULL;
+	ret->key_length=0;
+	ret->key_data=NULL;
+	ret->key_free=0;
+	ret->cipher.cipher=NULL;
+	memset(ret->cipher.iv,0,EVP_MAX_IV_LENGTH);
+	ret->references=1;
+	return(ret);
+	M_ASN1_New_Error(ASN1_F_X509_PKEY_NEW);
+	}
+
+void X509_PKEY_free(X509_PKEY *x)
+	{
+	int i;
+
+	if (x == NULL) return;
+
+	i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_X509_PKEY);
+#ifdef REF_PRINT
+	REF_PRINT("X509_PKEY",x);
+#endif
+	if (i > 0) return;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"X509_PKEY_free, bad reference count\n");
+		abort();
+		}
+#endif
+
+	if (x->enc_algor != NULL) X509_ALGOR_free(x->enc_algor);
+	if (x->enc_pkey != NULL) M_ASN1_OCTET_STRING_free(x->enc_pkey);
+	if (x->dec_pkey != NULL)EVP_PKEY_free(x->dec_pkey);
+	if ((x->key_data != NULL) && (x->key_free)) OPENSSL_free(x->key_data);
+	OPENSSL_free(x);
+	}
diff --git a/openssl/crypto/asn1/x_pubkey.c b/openssl/crypto/asn1/x_pubkey.c
new file mode 100644
index 0000000..d42b6a2
--- /dev/null
+++ b/openssl/crypto/asn1/x_pubkey.c
@@ -0,0 +1,373 @@
+/* crypto/asn1/x_pubkey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "asn1_locl.h"
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+
+/* Minor tweak to operation: free up EVP_PKEY */
+static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+			void *exarg)
+	{
+	if (operation == ASN1_OP_FREE_POST)
+		{
+		X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
+		EVP_PKEY_free(pubkey->pkey);
+		}
+	return 1;
+	}
+
+ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
+	ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
+	ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
+
+int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
+	{
+	X509_PUBKEY *pk=NULL;
+
+	if (x == NULL) return(0);
+
+	if ((pk=X509_PUBKEY_new()) == NULL) goto error;
+
+	if (pkey->ameth)
+		{
+		if (pkey->ameth->pub_encode)
+			{
+			if (!pkey->ameth->pub_encode(pk, pkey))
+				{
+				X509err(X509_F_X509_PUBKEY_SET,
+					X509_R_PUBLIC_KEY_ENCODE_ERROR);
+				goto error;
+				}
+			}
+		else
+			{
+			X509err(X509_F_X509_PUBKEY_SET,
+				X509_R_METHOD_NOT_SUPPORTED);
+			goto error;
+			}
+		}
+	else
+		{
+		X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM);
+		goto error;
+		}
+
+	if (*x != NULL)
+		X509_PUBKEY_free(*x);
+
+	*x=pk;
+
+	return 1;
+error:
+	if (pk != NULL) X509_PUBKEY_free(pk);
+	return 0;
+	}
+
+EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
+	{
+	EVP_PKEY *ret=NULL;
+
+	if (key == NULL) goto error;
+
+	if (key->pkey != NULL)
+		{
+		CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+		return key->pkey;
+		}
+
+	if (key->public_key == NULL) goto error;
+
+	if ((ret = EVP_PKEY_new()) == NULL)
+		{
+		X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
+		goto error;
+		}
+
+	if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm)))
+		{
+		X509err(X509_F_X509_PUBKEY_GET,X509_R_UNSUPPORTED_ALGORITHM);
+		goto error;
+		}
+
+	if (ret->ameth->pub_decode)
+		{
+		if (!ret->ameth->pub_decode(ret, key))
+			{
+			X509err(X509_F_X509_PUBKEY_GET,
+						X509_R_PUBLIC_KEY_DECODE_ERROR);
+			goto error;
+			}
+		}
+	else
+		{
+		X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED);
+		goto error;
+		}
+
+	key->pkey = ret;
+	CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
+
+	return ret;
+
+	error:
+	if (ret != NULL)
+		EVP_PKEY_free(ret);
+	return(NULL);
+	}
+
+/* Now two pseudo ASN1 routines that take an EVP_PKEY structure
+ * and encode or decode as X509_PUBKEY
+ */
+
+EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp,
+	     long length)
+	{
+	X509_PUBKEY *xpk;
+	EVP_PKEY *pktmp;
+	xpk = d2i_X509_PUBKEY(NULL, pp, length);
+	if(!xpk) return NULL;
+	pktmp = X509_PUBKEY_get(xpk);
+	X509_PUBKEY_free(xpk);
+	if(!pktmp) return NULL;
+	if(a)
+		{
+		EVP_PKEY_free(*a);
+		*a = pktmp;
+		}
+	return pktmp;
+	}
+
+int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
+	{
+	X509_PUBKEY *xpk=NULL;
+	int ret;
+	if(!a) return 0;
+	if(!X509_PUBKEY_set(&xpk, a)) return 0;
+	ret = i2d_X509_PUBKEY(xpk, pp);
+	X509_PUBKEY_free(xpk);
+	return ret;
+	}
+
+/* The following are equivalents but which return RSA and DSA
+ * keys
+ */
+#ifndef OPENSSL_NO_RSA
+RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp,
+	     long length)
+	{
+	EVP_PKEY *pkey;
+	RSA *key;
+	const unsigned char *q;
+	q = *pp;
+	pkey = d2i_PUBKEY(NULL, &q, length);
+	if (!pkey) return NULL;
+	key = EVP_PKEY_get1_RSA(pkey);
+	EVP_PKEY_free(pkey);
+	if (!key) return NULL;
+	*pp = q;
+	if (a)
+		{
+		RSA_free(*a);
+		*a = key;
+		}
+	return key;
+	}
+
+int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
+	{
+	EVP_PKEY *pktmp;
+	int ret;
+	if (!a) return 0;
+	pktmp = EVP_PKEY_new();
+	if (!pktmp)
+		{
+		ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	EVP_PKEY_set1_RSA(pktmp, a);
+	ret = i2d_PUBKEY(pktmp, pp);
+	EVP_PKEY_free(pktmp);
+	return ret;
+	}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp,
+	     long length)
+	{
+	EVP_PKEY *pkey;
+	DSA *key;
+	const unsigned char *q;
+	q = *pp;
+	pkey = d2i_PUBKEY(NULL, &q, length);
+	if (!pkey) return NULL;
+	key = EVP_PKEY_get1_DSA(pkey);
+	EVP_PKEY_free(pkey);
+	if (!key) return NULL;
+	*pp = q;
+	if (a)
+		{
+		DSA_free(*a);
+		*a = key;
+		}
+	return key;
+	}
+
+int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
+	{
+	EVP_PKEY *pktmp;
+	int ret;
+	if(!a) return 0;
+	pktmp = EVP_PKEY_new();
+	if(!pktmp)
+		{
+		ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	EVP_PKEY_set1_DSA(pktmp, a);
+	ret = i2d_PUBKEY(pktmp, pp);
+	EVP_PKEY_free(pktmp);
+	return ret;
+	}
+#endif
+
+#ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
+	{
+	EVP_PKEY *pkey;
+	EC_KEY *key;
+	const unsigned char *q;
+	q = *pp;
+	pkey = d2i_PUBKEY(NULL, &q, length);
+	if (!pkey) return(NULL);
+	key = EVP_PKEY_get1_EC_KEY(pkey);
+	EVP_PKEY_free(pkey);
+	if (!key)  return(NULL);
+	*pp = q;
+	if (a)
+		{
+		EC_KEY_free(*a);
+		*a = key;
+		}
+	return(key);
+	}
+
+int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
+	{
+	EVP_PKEY *pktmp;
+	int ret;
+	if (!a)	return(0);
+	if ((pktmp = EVP_PKEY_new()) == NULL)
+		{
+		ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	EVP_PKEY_set1_EC_KEY(pktmp, a);
+	ret = i2d_PUBKEY(pktmp, pp);
+	EVP_PKEY_free(pktmp);
+	return(ret);
+	}
+#endif
+
+int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
+					int ptype, void *pval,
+					unsigned char *penc, int penclen)
+	{
+	if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
+		return 0;
+	if (penc)
+		{
+		if (pub->public_key->data)
+			OPENSSL_free(pub->public_key->data);
+		pub->public_key->data = penc;
+		pub->public_key->length = penclen;
+  		/* Set number of unused bits to zero */
+		pub->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
+		pub->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;
+		}
+	return 1;
+	}
+
+int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
+		const unsigned char **pk, int *ppklen,
+		X509_ALGOR **pa,
+		X509_PUBKEY *pub)
+	{
+	if (ppkalg)
+		*ppkalg = pub->algor->algorithm;
+	if (pk)
+		{
+		*pk = pub->public_key->data;
+		*ppklen = pub->public_key->length;
+		}
+	if (pa)
+		*pa = pub->algor;
+	return 1;
+	}
diff --git a/openssl/crypto/asn1/x_req.c b/openssl/crypto/asn1/x_req.c
new file mode 100644
index 0000000..d575558
--- /dev/null
+++ b/openssl/crypto/asn1/x_req.c
@@ -0,0 +1,113 @@
+/* crypto/asn1/x_req.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+
+/* X509_REQ_INFO is handled in an unusual way to get round
+ * invalid encodings. Some broken certificate requests don't
+ * encode the attributes field if it is empty. This is in
+ * violation of PKCS#10 but we need to tolerate it. We do
+ * this by making the attributes field OPTIONAL then using
+ * the callback to initialise it to an empty STACK. 
+ *
+ * This means that the field will be correctly encoded unless
+ * we NULL out the field.
+ *
+ * As a result we no longer need the req_kludge field because
+ * the information is now contained in the attributes field:
+ * 1. If it is NULL then it's the invalid omission.
+ * 2. If it is empty it is the correct encoding.
+ * 3. If it is not empty then some attributes are present.
+ *
+ */
+
+static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
+{
+	X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
+
+	if(operation == ASN1_OP_NEW_POST) {
+		rinf->attributes = sk_X509_ATTRIBUTE_new_null();
+		if(!rinf->attributes) return 0;
+	}
+	return 1;
+}
+
+ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = {
+	ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER),
+	ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME),
+	ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY),
+	/* This isn't really OPTIONAL but it gets round invalid
+	 * encodings
+	 */
+	ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0)
+} ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO)
+
+ASN1_SEQUENCE_ref(X509_REQ, 0, CRYPTO_LOCK_X509_REQ) = {
+	ASN1_SIMPLE(X509_REQ, req_info, X509_REQ_INFO),
+	ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR),
+	ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_REQ)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ)
diff --git a/openssl/crypto/asn1/x_sig.c b/openssl/crypto/asn1/x_sig.c
new file mode 100644
index 0000000..42efa86
--- /dev/null
+++ b/openssl/crypto/asn1/x_sig.c
@@ -0,0 +1,69 @@
+/* crypto/asn1/x_sig.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+
+ASN1_SEQUENCE(X509_SIG) = {
+	ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR),
+	ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(X509_SIG)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_SIG)
diff --git a/openssl/crypto/asn1/x_spki.c b/openssl/crypto/asn1/x_spki.c
new file mode 100644
index 0000000..2aece07
--- /dev/null
+++ b/openssl/crypto/asn1/x_spki.c
@@ -0,0 +1,81 @@
+/* crypto/asn1/x_spki.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+ /* This module was send to me my Pat Richards <patr@x509.com> who
+  * wrote it.  It is under my Copyright with his permission
+  */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1t.h>
+
+ASN1_SEQUENCE(NETSCAPE_SPKAC) = {
+	ASN1_SIMPLE(NETSCAPE_SPKAC, pubkey, X509_PUBKEY),
+	ASN1_SIMPLE(NETSCAPE_SPKAC, challenge, ASN1_IA5STRING)
+} ASN1_SEQUENCE_END(NETSCAPE_SPKAC)
+
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
+
+ASN1_SEQUENCE(NETSCAPE_SPKI) = {
+	ASN1_SIMPLE(NETSCAPE_SPKI, spkac, NETSCAPE_SPKAC),
+	ASN1_SIMPLE(NETSCAPE_SPKI, sig_algor, X509_ALGOR),
+	ASN1_SIMPLE(NETSCAPE_SPKI, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END(NETSCAPE_SPKI)
+
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKI)
diff --git a/openssl/crypto/asn1/x_val.c b/openssl/crypto/asn1/x_val.c
new file mode 100644
index 0000000..dc17c67
--- /dev/null
+++ b/openssl/crypto/asn1/x_val.c
@@ -0,0 +1,69 @@
+/* crypto/asn1/x_val.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+
+ASN1_SEQUENCE(X509_VAL) = {
+	ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME),
+	ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME)
+} ASN1_SEQUENCE_END(X509_VAL)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_VAL)
diff --git a/openssl/crypto/asn1/x_x509.c b/openssl/crypto/asn1/x_x509.c
new file mode 100644
index 0000000..de3df9e
--- /dev/null
+++ b/openssl/crypto/asn1/x_x509.c
@@ -0,0 +1,194 @@
+/* crypto/asn1/x_x509.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = {
+	ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0),
+	ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER),
+	ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR),
+	ASN1_SIMPLE(X509_CINF, issuer, X509_NAME),
+	ASN1_SIMPLE(X509_CINF, validity, X509_VAL),
+	ASN1_SIMPLE(X509_CINF, subject, X509_NAME),
+	ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY),
+	ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1),
+	ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2),
+	ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3)
+} ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CINF)
+/* X509 top level structure needs a bit of customisation */
+
+extern void policy_cache_free(X509_POLICY_CACHE *cache);
+
+static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+								void *exarg)
+{
+	X509 *ret = (X509 *)*pval;
+
+	switch(operation) {
+
+		case ASN1_OP_NEW_POST:
+		ret->valid=0;
+		ret->name = NULL;
+		ret->ex_flags = 0;
+		ret->ex_pathlen = -1;
+		ret->skid = NULL;
+		ret->akid = NULL;
+#ifndef OPENSSL_NO_RFC3779
+		ret->rfc3779_addr = NULL;
+		ret->rfc3779_asid = NULL;
+#endif
+		ret->aux = NULL;
+		ret->crldp = NULL;
+		CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
+		break;
+
+		case ASN1_OP_D2I_POST:
+		if (ret->name != NULL) OPENSSL_free(ret->name);
+		ret->name=X509_NAME_oneline(ret->cert_info->subject,NULL,0);
+		break;
+
+		case ASN1_OP_FREE_POST:
+		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
+		X509_CERT_AUX_free(ret->aux);
+		ASN1_OCTET_STRING_free(ret->skid);
+		AUTHORITY_KEYID_free(ret->akid);
+		CRL_DIST_POINTS_free(ret->crldp);
+		policy_cache_free(ret->policy_cache);
+		GENERAL_NAMES_free(ret->altname);
+		NAME_CONSTRAINTS_free(ret->nc);
+#ifndef OPENSSL_NO_RFC3779
+		sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
+		ASIdentifiers_free(ret->rfc3779_asid);
+#endif
+
+		if (ret->name != NULL) OPENSSL_free(ret->name);
+		break;
+
+	}
+
+	return 1;
+
+}
+
+ASN1_SEQUENCE_ref(X509, x509_cb, CRYPTO_LOCK_X509) = {
+	ASN1_SIMPLE(X509, cert_info, X509_CINF),
+	ASN1_SIMPLE(X509, sig_alg, X509_ALGOR),
+	ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_ref(X509, X509)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509)
+
+int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+        {
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, argl, argp,
+				new_func, dup_func, free_func);
+        }
+
+int X509_set_ex_data(X509 *r, int idx, void *arg)
+	{
+	return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
+	}
+
+void *X509_get_ex_data(X509 *r, int idx)
+	{
+	return(CRYPTO_get_ex_data(&r->ex_data,idx));
+	}
+
+/* X509_AUX ASN1 routines. X509_AUX is the name given to
+ * a certificate with extra info tagged on the end. Since these
+ * functions set how a certificate is trusted they should only
+ * be used when the certificate comes from a reliable source
+ * such as local storage.
+ *
+ */
+
+X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
+{
+	const unsigned char *q;
+	X509 *ret;
+	/* Save start position */
+	q = *pp;
+	ret = d2i_X509(a, pp, length);
+	/* If certificate unreadable then forget it */
+	if(!ret) return NULL;
+	/* update length */
+	length -= *pp - q;
+	if(!length) return ret;
+	if(!d2i_X509_CERT_AUX(&ret->aux, pp, length)) goto err;
+	return ret;
+	err:
+	X509_free(ret);
+	return NULL;
+}
+
+int i2d_X509_AUX(X509 *a, unsigned char **pp)
+{
+	int length;
+	length = i2d_X509(a, pp);
+	if(a) length += i2d_X509_CERT_AUX(a->aux, pp);
+	return length;
+}
diff --git a/openssl/crypto/asn1/x_x509a.c b/openssl/crypto/asn1/x_x509a.c
new file mode 100644
index 0000000..b603f82
--- /dev/null
+++ b/openssl/crypto/asn1/x_x509a.c
@@ -0,0 +1,180 @@
+/* a_x509a.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+
+/* X509_CERT_AUX routines. These are used to encode additional
+ * user modifiable data about a certificate. This data is
+ * appended to the X509 encoding when the *_X509_AUX routines
+ * are used. This means that the "traditional" X509 routines
+ * will simply ignore the extra data. 
+ */
+
+static X509_CERT_AUX *aux_get(X509 *x);
+
+ASN1_SEQUENCE(X509_CERT_AUX) = {
+	ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT),
+	ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0),
+	ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING),
+	ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING),
+	ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, other, X509_ALGOR, 1)
+} ASN1_SEQUENCE_END(X509_CERT_AUX)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_AUX)
+
+static X509_CERT_AUX *aux_get(X509 *x)
+{
+	if(!x) return NULL;
+	if(!x->aux && !(x->aux = X509_CERT_AUX_new())) return NULL;
+	return x->aux;
+}
+
+int X509_alias_set1(X509 *x, unsigned char *name, int len)
+{
+	X509_CERT_AUX *aux;
+	if (!name)
+		{
+		if (!x || !x->aux || !x->aux->alias)
+			return 1;
+		ASN1_UTF8STRING_free(x->aux->alias);
+		x->aux->alias = NULL;
+		return 1;
+		}
+	if(!(aux = aux_get(x))) return 0;
+	if(!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) return 0;
+	return ASN1_STRING_set(aux->alias, name, len);
+}
+
+int X509_keyid_set1(X509 *x, unsigned char *id, int len)
+{
+	X509_CERT_AUX *aux;
+	if (!id)
+		{
+		if (!x || !x->aux || !x->aux->keyid)
+			return 1;
+		ASN1_OCTET_STRING_free(x->aux->keyid);
+		x->aux->keyid = NULL;
+		return 1;
+		}
+	if(!(aux = aux_get(x))) return 0;
+	if(!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new())) return 0;
+	return ASN1_STRING_set(aux->keyid, id, len);
+}
+
+unsigned char *X509_alias_get0(X509 *x, int *len)
+{
+	if(!x->aux || !x->aux->alias) return NULL;
+	if(len) *len = x->aux->alias->length;
+	return x->aux->alias->data;
+}
+
+unsigned char *X509_keyid_get0(X509 *x, int *len)
+{
+	if(!x->aux || !x->aux->keyid) return NULL;
+	if(len) *len = x->aux->keyid->length;
+	return x->aux->keyid->data;
+}
+
+int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj)
+{
+	X509_CERT_AUX *aux;
+	ASN1_OBJECT *objtmp;
+	if(!(objtmp = OBJ_dup(obj))) return 0;
+	if(!(aux = aux_get(x))) return 0;
+	if(!aux->trust
+		&& !(aux->trust = sk_ASN1_OBJECT_new_null())) return 0;
+	return sk_ASN1_OBJECT_push(aux->trust, objtmp);
+}
+
+int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj)
+{
+	X509_CERT_AUX *aux;
+	ASN1_OBJECT *objtmp;
+	if(!(objtmp = OBJ_dup(obj))) return 0;
+	if(!(aux = aux_get(x))) return 0;
+	if(!aux->reject
+		&& !(aux->reject = sk_ASN1_OBJECT_new_null())) return 0;
+	return sk_ASN1_OBJECT_push(aux->reject, objtmp);
+}
+
+void X509_trust_clear(X509 *x)
+{
+	if(x->aux && x->aux->trust) {
+		sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free);
+		x->aux->trust = NULL;
+	}
+}
+
+void X509_reject_clear(X509 *x)
+{
+	if(x->aux && x->aux->reject) {
+		sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free);
+		x->aux->reject = NULL;
+	}
+}
+
+ASN1_SEQUENCE(X509_CERT_PAIR) = {
+	ASN1_EXP_OPT(X509_CERT_PAIR, forward, X509, 0),
+	ASN1_EXP_OPT(X509_CERT_PAIR, reverse, X509, 1)
+} ASN1_SEQUENCE_END(X509_CERT_PAIR)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_PAIR)
diff --git a/openssl/crypto/bf/COPYRIGHT b/openssl/crypto/bf/COPYRIGHT
new file mode 100644
index 0000000..6857223
--- /dev/null
+++ b/openssl/crypto/bf/COPYRIGHT
@@ -0,0 +1,46 @@
+Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+All rights reserved.
+
+This package is an Blowfish implementation written
+by Eric Young (eay@cryptsoft.com).
+
+This library is free for commercial and non-commercial use as long as
+the following conditions are aheared to.  The following conditions
+apply to all code found in this distribution.
+
+Copyright remains Eric Young's, and as such any Copyright notices in
+the code are not to be removed.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+   must display the following acknowledgement:
+   This product includes software developed by Eric Young (eay@cryptsoft.com)
+
+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+The license and distribution terms for any publically available version or
+derivative of this code cannot be changed.  i.e. this code cannot simply be
+copied and put under another distrubution license
+[including the GNU Public License.]
+
+The reason behind this being stated in this direct manner is past
+experience in code simply being copied and the attribution removed
+from it and then being distributed as part of other packages. This
+implementation was a non-trivial and unpaid effort.
diff --git a/openssl/crypto/bf/INSTALL b/openssl/crypto/bf/INSTALL
new file mode 100644
index 0000000..3b25923
--- /dev/null
+++ b/openssl/crypto/bf/INSTALL
@@ -0,0 +1,14 @@
+This Eric Young's blowfish implementation, taken from his SSLeay library
+and made available as a separate library.
+ 
+The version number (0.7.2m) is the SSLeay version that this library was
+taken from.
+ 
+To build, just unpack and type make.
+If you are not using gcc, edit the Makefile.
+If you are compiling for an x86 box, try the assembler (it needs improving).
+There are also some compile time options that can improve performance,
+these are documented in the Makefile.
+ 
+eric 15-Apr-1997
+ 
diff --git a/openssl/crypto/bf/Makefile b/openssl/crypto/bf/Makefile
new file mode 100644
index 0000000..dd2c2c7
--- /dev/null
+++ b/openssl/crypto/bf/Makefile
@@ -0,0 +1,98 @@
+#
+# OpenSSL/crypto/blowfish/Makefile
+#
+
+DIR=	bf
+TOP=	../..
+CC=	cc
+CPP=	$(CC) -E
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+BF_ENC=		bf_enc.o
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+ASFLAGS= $(INCLUDES) $(ASFLAG)
+AFLAGS= $(ASFLAGS)
+
+GENERAL=Makefile
+TEST=bftest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=bf_skey.c bf_ecb.c bf_enc.c bf_cfb64.c bf_ofb64.c 
+LIBOBJ=bf_skey.o bf_ecb.o $(BF_ENC) bf_cfb64.o bf_ofb64.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= blowfish.h
+HEADER=	bf_pi.h bf_locl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+bf-586.s:	asm/bf-586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
+	$(PERL) asm/bf-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+# We need to use force because 'install' matches 'INSTALL' on case
+# insensitive systems
+FRC.install:
+install: FRC.install
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+bf_cfb64.o: ../../include/openssl/blowfish.h ../../include/openssl/e_os2.h
+bf_cfb64.o: ../../include/openssl/opensslconf.h bf_cfb64.c bf_locl.h
+bf_ecb.o: ../../include/openssl/blowfish.h ../../include/openssl/e_os2.h
+bf_ecb.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+bf_ecb.o: bf_ecb.c bf_locl.h
+bf_enc.o: ../../include/openssl/blowfish.h ../../include/openssl/e_os2.h
+bf_enc.o: ../../include/openssl/opensslconf.h bf_enc.c bf_locl.h
+bf_ofb64.o: ../../include/openssl/blowfish.h ../../include/openssl/e_os2.h
+bf_ofb64.o: ../../include/openssl/opensslconf.h bf_locl.h bf_ofb64.c
+bf_skey.o: ../../include/openssl/blowfish.h ../../include/openssl/e_os2.h
+bf_skey.o: ../../include/openssl/opensslconf.h bf_locl.h bf_pi.h bf_skey.c
diff --git a/openssl/crypto/bf/README b/openssl/crypto/bf/README
new file mode 100644
index 0000000..f2712fd
--- /dev/null
+++ b/openssl/crypto/bf/README
@@ -0,0 +1,8 @@
+This is a quick packaging up of my blowfish code into a library.
+It has been lifted from SSLeay.
+The copyright notices seem a little harsh because I have not spent the
+time to rewrite the conditions from the normal SSLeay ones.
+
+Basically if you just want to play with the library, not a problem.
+
+eric 15-Apr-1997
diff --git a/openssl/crypto/bf/VERSION b/openssl/crypto/bf/VERSION
new file mode 100644
index 0000000..be99585
--- /dev/null
+++ b/openssl/crypto/bf/VERSION
@@ -0,0 +1,6 @@
+The version numbers will follow my SSL implementation
+
+0.7.2r - Some reasonable default compiler options from 
+	Peter Gutman <pgut001@cs.auckland.ac.nz>
+
+0.7.2m - the first release
diff --git a/openssl/crypto/bf/asm/bf-586.pl b/openssl/crypto/bf/asm/bf-586.pl
new file mode 100644
index 0000000..b74cfba
--- /dev/null
+++ b/openssl/crypto/bf/asm/bf-586.pl
@@ -0,0 +1,137 @@
+#!/usr/local/bin/perl
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+require "cbc.pl";
+
+&asm_init($ARGV[0],"bf-586.pl",$ARGV[$#ARGV] eq "386");
+
+$BF_ROUNDS=16;
+$BF_OFF=($BF_ROUNDS+2)*4;
+$L="edi";
+$R="esi";
+$P="ebp";
+$tmp1="eax";
+$tmp2="ebx";
+$tmp3="ecx";
+$tmp4="edx";
+
+&BF_encrypt("BF_encrypt",1);
+&BF_encrypt("BF_decrypt",0);
+&cbc("BF_cbc_encrypt","BF_encrypt","BF_decrypt",1,4,5,3,-1,-1);
+&asm_finish();
+
+sub BF_encrypt
+	{
+	local($name,$enc)=@_;
+
+	&function_begin_B($name,"");
+
+	&comment("");
+
+	&push("ebp");
+	&push("ebx");
+	&mov($tmp2,&wparam(0));
+	&mov($P,&wparam(1));
+	&push("esi");
+	&push("edi");
+
+	&comment("Load the 2 words");
+	&mov($L,&DWP(0,$tmp2,"",0));
+	&mov($R,&DWP(4,$tmp2,"",0));
+
+	&xor(	$tmp1,	$tmp1);
+
+	# encrypting part
+
+	if ($enc)
+		{
+		 &mov($tmp2,&DWP(0,$P,"",0));
+		&xor(	$tmp3,	$tmp3);
+
+		&xor($L,$tmp2);
+		for ($i=0; $i<$BF_ROUNDS; $i+=2)
+			{
+			&comment("");
+			&comment("Round $i");
+			&BF_ENCRYPT($i+1,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,1);
+
+			&comment("");
+			&comment("Round ".sprintf("%d",$i+1));
+			&BF_ENCRYPT($i+2,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,1);
+			}
+		# &mov($tmp1,&wparam(0)); In last loop
+		&mov($tmp4,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
+		}
+	else
+		{
+		 &mov($tmp2,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
+		&xor(	$tmp3,	$tmp3);
+
+		&xor($L,$tmp2);
+		for ($i=$BF_ROUNDS; $i>0; $i-=2)
+			{
+			&comment("");
+			&comment("Round $i");
+			&BF_ENCRYPT($i,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,0);
+			&comment("");
+			&comment("Round ".sprintf("%d",$i-1));
+			&BF_ENCRYPT($i-1,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,0);
+			}
+		# &mov($tmp1,&wparam(0)); In last loop
+		&mov($tmp4,&DWP(0,$P,"",0));
+		}
+
+	&xor($R,$tmp4);
+	&mov(&DWP(4,$tmp1,"",0),$L);
+
+	&mov(&DWP(0,$tmp1,"",0),$R);
+	&function_end($name);
+	}
+
+sub BF_ENCRYPT
+	{
+	local($i,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,$enc)=@_;
+
+	&mov(	$tmp4,		&DWP(&n2a($i*4),$P,"",0)); # for next round
+
+	&mov(	$tmp2,		$R);
+	&xor(	$L,		$tmp4);
+
+	&shr(	$tmp2,		16);
+	&mov(	$tmp4,		$R);
+
+	&movb(	&LB($tmp1),	&HB($tmp2));	# A
+	&and(	$tmp2,		0xff);		# B
+
+	&movb(	&LB($tmp3),	&HB($tmp4));	# C
+	&and(	$tmp4,		0xff);		# D
+
+	&mov(	$tmp1,		&DWP(&n2a($BF_OFF+0x0000),$P,$tmp1,4));
+	&mov(	$tmp2,		&DWP(&n2a($BF_OFF+0x0400),$P,$tmp2,4));
+
+	&add(	$tmp2,		$tmp1);
+	&mov(	$tmp1,		&DWP(&n2a($BF_OFF+0x0800),$P,$tmp3,4));
+
+	&xor(	$tmp2,		$tmp1);
+	&mov(	$tmp4,		&DWP(&n2a($BF_OFF+0x0C00),$P,$tmp4,4));
+
+	&add(	$tmp2,		$tmp4);
+	if (($enc && ($i != 16)) || ((!$enc) && ($i != 1)))
+		{ &xor(	$tmp1,		$tmp1); }
+	else
+		{
+		&comment("Load parameter 0 ($i) enc=$enc");
+		&mov($tmp1,&wparam(0));
+		} # In last loop
+
+	&xor(	$L,		$tmp2);
+	# delay
+	}
+
+sub n2a
+	{
+	sprintf("%d",$_[0]);
+	}
+
diff --git a/openssl/crypto/bf/asm/bf-686.pl b/openssl/crypto/bf/asm/bf-686.pl
new file mode 100644
index 0000000..8e4c25f
--- /dev/null
+++ b/openssl/crypto/bf/asm/bf-686.pl
@@ -0,0 +1,127 @@
+#!/usr/local/bin/perl
+
+push(@INC,"perlasm","../../perlasm");
+require "x86asm.pl";
+require "cbc.pl";
+
+&asm_init($ARGV[0],"bf-686.pl");
+
+$BF_ROUNDS=16;
+$BF_OFF=($BF_ROUNDS+2)*4;
+$L="ecx";
+$R="edx";
+$P="edi";
+$tot="esi";
+$tmp1="eax";
+$tmp2="ebx";
+$tmp3="ebp";
+
+&des_encrypt("BF_encrypt",1);
+&des_encrypt("BF_decrypt",0);
+&cbc("BF_cbc_encrypt","BF_encrypt","BF_decrypt",1,4,5,3,-1,-1);
+
+&asm_finish();
+
+&file_end();
+
+sub des_encrypt
+	{
+	local($name,$enc)=@_;
+
+	&function_begin($name,"");
+
+	&comment("");
+	&comment("Load the 2 words");
+	&mov("eax",&wparam(0));
+	&mov($L,&DWP(0,"eax","",0));
+	&mov($R,&DWP(4,"eax","",0));
+
+	&comment("");
+	&comment("P pointer, s and enc flag");
+	&mov($P,&wparam(1));
+
+	&xor(	$tmp1,	$tmp1);
+	&xor(	$tmp2,	$tmp2);
+
+	# encrypting part
+
+	if ($enc)
+		{
+		&xor($L,&DWP(0,$P,"",0));
+		for ($i=0; $i<$BF_ROUNDS; $i+=2)
+			{
+			&comment("");
+			&comment("Round $i");
+			&BF_ENCRYPT($i+1,$R,$L,$P,$tot,$tmp1,$tmp2,$tmp3);
+
+			&comment("");
+			&comment("Round ".sprintf("%d",$i+1));
+			&BF_ENCRYPT($i+2,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3);
+			}
+		&xor($R,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
+
+		&mov("eax",&wparam(0));
+		&mov(&DWP(0,"eax","",0),$R);
+		&mov(&DWP(4,"eax","",0),$L);
+		&function_end_A($name);
+		}
+	else
+		{
+		&xor($L,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
+		for ($i=$BF_ROUNDS; $i>0; $i-=2)
+			{
+			&comment("");
+			&comment("Round $i");
+			&BF_ENCRYPT($i,$R,$L,$P,$tot,$tmp1,$tmp2,$tmp3);
+			&comment("");
+			&comment("Round ".sprintf("%d",$i-1));
+			&BF_ENCRYPT($i-1,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3);
+			}
+		&xor($R,&DWP(0,$P,"",0));
+
+		&mov("eax",&wparam(0));
+		&mov(&DWP(0,"eax","",0),$R);
+		&mov(&DWP(4,"eax","",0),$L);
+		&function_end_A($name);
+		}
+
+	&function_end_B($name);
+	}
+
+sub BF_ENCRYPT
+	{
+	local($i,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3)=@_;
+
+	&rotr(	$R,		16);
+	&mov(	$tot,		&DWP(&n2a($i*4),$P,"",0));
+
+	&movb(	&LB($tmp1),	&HB($R));
+	&movb(	&LB($tmp2),	&LB($R));
+
+	&rotr(	$R,		16);
+	&xor(	$L,		$tot);
+
+	&mov(	$tot,		&DWP(&n2a($BF_OFF+0x0000),$P,$tmp1,4));
+	&mov(	$tmp3,		&DWP(&n2a($BF_OFF+0x0400),$P,$tmp2,4));
+
+	&movb(	&LB($tmp1),	&HB($R));
+	&movb(	&LB($tmp2),	&LB($R));
+
+	&add(	$tot,		$tmp3);
+	&mov(	$tmp1,		&DWP(&n2a($BF_OFF+0x0800),$P,$tmp1,4)); # delay
+
+	&xor(	$tot,		$tmp1);
+	&mov(	$tmp3,		&DWP(&n2a($BF_OFF+0x0C00),$P,$tmp2,4));
+
+	&add(	$tot,		$tmp3);
+	&xor(	$tmp1,		$tmp1);
+
+	&xor(	$L,		$tot);					
+	# delay
+	}
+
+sub n2a
+	{
+	sprintf("%d",$_[0]);
+	}
+
diff --git a/openssl/crypto/bf/asm/readme b/openssl/crypto/bf/asm/readme
new file mode 100644
index 0000000..2385fa3
--- /dev/null
+++ b/openssl/crypto/bf/asm/readme
@@ -0,0 +1,10 @@
+There are blowfish assembler generation scripts.
+bf-586.pl version is for the pentium and
+bf-686.pl is my original version, which is faster on the pentium pro.
+
+When using a bf-586.pl, the pentium pro/II is %8 slower than using
+bf-686.pl.  When using a bf-686.pl, the pentium is %16 slower
+than bf-586.pl
+
+So the default is bf-586.pl
+
diff --git a/openssl/crypto/bf/bf_cbc.c b/openssl/crypto/bf/bf_cbc.c
new file mode 100644
index 0000000..f949629
--- /dev/null
+++ b/openssl/crypto/bf/bf_cbc.c
@@ -0,0 +1,143 @@
+/* crypto/bf/bf_cbc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/blowfish.h>
+#include "bf_locl.h"
+
+void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+	     const BF_KEY *schedule, unsigned char *ivec, int encrypt)
+	{
+	register BF_LONG tin0,tin1;
+	register BF_LONG tout0,tout1,xor0,xor1;
+	register long l=length;
+	BF_LONG tin[2];
+
+	if (encrypt)
+		{
+		n2l(ivec,tout0);
+		n2l(ivec,tout1);
+		ivec-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			n2l(in,tin0);
+			n2l(in,tin1);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			BF_encrypt(tin,schedule);
+			tout0=tin[0];
+			tout1=tin[1];
+			l2n(tout0,out);
+			l2n(tout1,out);
+			}
+		if (l != -8)
+			{
+			n2ln(in,tin0,tin1,l+8);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			BF_encrypt(tin,schedule);
+			tout0=tin[0];
+			tout1=tin[1];
+			l2n(tout0,out);
+			l2n(tout1,out);
+			}
+		l2n(tout0,ivec);
+		l2n(tout1,ivec);
+		}
+	else
+		{
+		n2l(ivec,xor0);
+		n2l(ivec,xor1);
+		ivec-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			n2l(in,tin0);
+			n2l(in,tin1);
+			tin[0]=tin0;
+			tin[1]=tin1;
+			BF_decrypt(tin,schedule);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2n(tout0,out);
+			l2n(tout1,out);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		if (l != -8)
+			{
+			n2l(in,tin0);
+			n2l(in,tin1);
+			tin[0]=tin0;
+			tin[1]=tin1;
+			BF_decrypt(tin,schedule);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2nn(tout0,tout1,out,l+8);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		l2n(xor0,ivec);
+		l2n(xor1,ivec);
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	tin[0]=tin[1]=0;
+	}
+
diff --git a/openssl/crypto/bf/bf_cfb64.c b/openssl/crypto/bf/bf_cfb64.c
new file mode 100644
index 0000000..6451c8d
--- /dev/null
+++ b/openssl/crypto/bf/bf_cfb64.c
@@ -0,0 +1,121 @@
+/* crypto/bf/bf_cfb64.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/blowfish.h>
+#include "bf_locl.h"
+
+/* The input and output encrypted as though 64bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+
+void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, long length,
+	     const BF_KEY *schedule, unsigned char *ivec, int *num, int encrypt)
+	{
+	register BF_LONG v0,v1,t;
+	register int n= *num;
+	register long l=length;
+	BF_LONG ti[2];
+	unsigned char *iv,c,cc;
+
+	iv=(unsigned char *)ivec;
+	if (encrypt)
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				n2l(iv,v0); ti[0]=v0;
+				n2l(iv,v1); ti[1]=v1;
+				BF_encrypt((BF_LONG *)ti,schedule);
+				iv=(unsigned char *)ivec;
+				t=ti[0]; l2n(t,iv);
+				t=ti[1]; l2n(t,iv);
+				iv=(unsigned char *)ivec;
+				}
+			c= *(in++)^iv[n];
+			*(out++)=c;
+			iv[n]=c;
+			n=(n+1)&0x07;
+			}
+		}
+	else
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				n2l(iv,v0); ti[0]=v0;
+				n2l(iv,v1); ti[1]=v1;
+				BF_encrypt((BF_LONG *)ti,schedule);
+				iv=(unsigned char *)ivec;
+				t=ti[0]; l2n(t,iv);
+				t=ti[1]; l2n(t,iv);
+				iv=(unsigned char *)ivec;
+				}
+			cc= *(in++);
+			c=iv[n];
+			iv[n]=cc;
+			*(out++)=c^cc;
+			n=(n+1)&0x07;
+			}
+		}
+	v0=v1=ti[0]=ti[1]=t=c=cc=0;
+	*num=n;
+	}
+
diff --git a/openssl/crypto/bf/bf_ecb.c b/openssl/crypto/bf/bf_ecb.c
new file mode 100644
index 0000000..1607cef
--- /dev/null
+++ b/openssl/crypto/bf/bf_ecb.c
@@ -0,0 +1,96 @@
+/* crypto/bf/bf_ecb.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/blowfish.h>
+#include "bf_locl.h"
+#include <openssl/opensslv.h>
+
+/* Blowfish as implemented from 'Blowfish: Springer-Verlag paper'
+ * (From LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION,
+ * CAMBRIDGE SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
+ */
+
+const char BF_version[]="Blowfish" OPENSSL_VERSION_PTEXT;
+
+const char *BF_options(void)
+	{
+#ifdef BF_PTR
+	return("blowfish(ptr)");
+#elif defined(BF_PTR2)
+	return("blowfish(ptr2)");
+#else
+	return("blowfish(idx)");
+#endif
+	}
+
+void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
+	     const BF_KEY *key, int encrypt)
+	{
+	BF_LONG l,d[2];
+
+	n2l(in,l); d[0]=l;
+	n2l(in,l); d[1]=l;
+	if (encrypt)
+		BF_encrypt(d,key);
+	else
+		BF_decrypt(d,key);
+	l=d[0]; l2n(l,out);
+	l=d[1]; l2n(l,out);
+	l=d[0]=d[1]=0;
+	}
+
diff --git a/openssl/crypto/bf/bf_enc.c b/openssl/crypto/bf/bf_enc.c
new file mode 100644
index 0000000..2d21d09
--- /dev/null
+++ b/openssl/crypto/bf/bf_enc.c
@@ -0,0 +1,306 @@
+/* crypto/bf/bf_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/blowfish.h>
+#include "bf_locl.h"
+
+/* Blowfish as implemented from 'Blowfish: Springer-Verlag paper'
+ * (From LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION,
+ * CAMBRIDGE SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
+ */
+
+#if (BF_ROUNDS != 16) && (BF_ROUNDS != 20)
+#error If you set BF_ROUNDS to some value other than 16 or 20, you will have \
+to modify the code.
+#endif
+
+void BF_encrypt(BF_LONG *data, const BF_KEY *key)
+	{
+#ifndef BF_PTR2
+	register BF_LONG l,r;
+	register const BF_LONG *p,*s;
+
+	p=key->P;
+	s= &(key->S[0]);
+	l=data[0];
+	r=data[1];
+
+	l^=p[0];
+	BF_ENC(r,l,s,p[ 1]);
+	BF_ENC(l,r,s,p[ 2]);
+	BF_ENC(r,l,s,p[ 3]);
+	BF_ENC(l,r,s,p[ 4]);
+	BF_ENC(r,l,s,p[ 5]);
+	BF_ENC(l,r,s,p[ 6]);
+	BF_ENC(r,l,s,p[ 7]);
+	BF_ENC(l,r,s,p[ 8]);
+	BF_ENC(r,l,s,p[ 9]);
+	BF_ENC(l,r,s,p[10]);
+	BF_ENC(r,l,s,p[11]);
+	BF_ENC(l,r,s,p[12]);
+	BF_ENC(r,l,s,p[13]);
+	BF_ENC(l,r,s,p[14]);
+	BF_ENC(r,l,s,p[15]);
+	BF_ENC(l,r,s,p[16]);
+#if BF_ROUNDS == 20
+	BF_ENC(r,l,s,p[17]);
+	BF_ENC(l,r,s,p[18]);
+	BF_ENC(r,l,s,p[19]);
+	BF_ENC(l,r,s,p[20]);
+#endif
+	r^=p[BF_ROUNDS+1];
+
+	data[1]=l&0xffffffffL;
+	data[0]=r&0xffffffffL;
+#else
+	register BF_LONG l,r,t,*k;
+
+	l=data[0];
+	r=data[1];
+	k=(BF_LONG*)key;
+
+	l^=k[0];
+	BF_ENC(r,l,k, 1);
+	BF_ENC(l,r,k, 2);
+	BF_ENC(r,l,k, 3);
+	BF_ENC(l,r,k, 4);
+	BF_ENC(r,l,k, 5);
+	BF_ENC(l,r,k, 6);
+	BF_ENC(r,l,k, 7);
+	BF_ENC(l,r,k, 8);
+	BF_ENC(r,l,k, 9);
+	BF_ENC(l,r,k,10);
+	BF_ENC(r,l,k,11);
+	BF_ENC(l,r,k,12);
+	BF_ENC(r,l,k,13);
+	BF_ENC(l,r,k,14);
+	BF_ENC(r,l,k,15);
+	BF_ENC(l,r,k,16);
+#if BF_ROUNDS == 20
+	BF_ENC(r,l,k,17);
+	BF_ENC(l,r,k,18);
+	BF_ENC(r,l,k,19);
+	BF_ENC(l,r,k,20);
+#endif
+	r^=k[BF_ROUNDS+1];
+
+	data[1]=l&0xffffffffL;
+	data[0]=r&0xffffffffL;
+#endif
+	}
+
+#ifndef BF_DEFAULT_OPTIONS
+
+void BF_decrypt(BF_LONG *data, const BF_KEY *key)
+	{
+#ifndef BF_PTR2
+	register BF_LONG l,r;
+	register const BF_LONG *p,*s;
+
+	p=key->P;
+	s= &(key->S[0]);
+	l=data[0];
+	r=data[1];
+
+	l^=p[BF_ROUNDS+1];
+#if BF_ROUNDS == 20
+	BF_ENC(r,l,s,p[20]);
+	BF_ENC(l,r,s,p[19]);
+	BF_ENC(r,l,s,p[18]);
+	BF_ENC(l,r,s,p[17]);
+#endif
+	BF_ENC(r,l,s,p[16]);
+	BF_ENC(l,r,s,p[15]);
+	BF_ENC(r,l,s,p[14]);
+	BF_ENC(l,r,s,p[13]);
+	BF_ENC(r,l,s,p[12]);
+	BF_ENC(l,r,s,p[11]);
+	BF_ENC(r,l,s,p[10]);
+	BF_ENC(l,r,s,p[ 9]);
+	BF_ENC(r,l,s,p[ 8]);
+	BF_ENC(l,r,s,p[ 7]);
+	BF_ENC(r,l,s,p[ 6]);
+	BF_ENC(l,r,s,p[ 5]);
+	BF_ENC(r,l,s,p[ 4]);
+	BF_ENC(l,r,s,p[ 3]);
+	BF_ENC(r,l,s,p[ 2]);
+	BF_ENC(l,r,s,p[ 1]);
+	r^=p[0];
+
+	data[1]=l&0xffffffffL;
+	data[0]=r&0xffffffffL;
+#else
+	register BF_LONG l,r,t,*k;
+
+	l=data[0];
+	r=data[1];
+	k=(BF_LONG *)key;
+
+	l^=k[BF_ROUNDS+1];
+#if BF_ROUNDS == 20
+	BF_ENC(r,l,k,20);
+	BF_ENC(l,r,k,19);
+	BF_ENC(r,l,k,18);
+	BF_ENC(l,r,k,17);
+#endif
+	BF_ENC(r,l,k,16);
+	BF_ENC(l,r,k,15);
+	BF_ENC(r,l,k,14);
+	BF_ENC(l,r,k,13);
+	BF_ENC(r,l,k,12);
+	BF_ENC(l,r,k,11);
+	BF_ENC(r,l,k,10);
+	BF_ENC(l,r,k, 9);
+	BF_ENC(r,l,k, 8);
+	BF_ENC(l,r,k, 7);
+	BF_ENC(r,l,k, 6);
+	BF_ENC(l,r,k, 5);
+	BF_ENC(r,l,k, 4);
+	BF_ENC(l,r,k, 3);
+	BF_ENC(r,l,k, 2);
+	BF_ENC(l,r,k, 1);
+	r^=k[0];
+
+	data[1]=l&0xffffffffL;
+	data[0]=r&0xffffffffL;
+#endif
+	}
+
+void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+	     const BF_KEY *schedule, unsigned char *ivec, int encrypt)
+	{
+	register BF_LONG tin0,tin1;
+	register BF_LONG tout0,tout1,xor0,xor1;
+	register long l=length;
+	BF_LONG tin[2];
+
+	if (encrypt)
+		{
+		n2l(ivec,tout0);
+		n2l(ivec,tout1);
+		ivec-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			n2l(in,tin0);
+			n2l(in,tin1);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			BF_encrypt(tin,schedule);
+			tout0=tin[0];
+			tout1=tin[1];
+			l2n(tout0,out);
+			l2n(tout1,out);
+			}
+		if (l != -8)
+			{
+			n2ln(in,tin0,tin1,l+8);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			BF_encrypt(tin,schedule);
+			tout0=tin[0];
+			tout1=tin[1];
+			l2n(tout0,out);
+			l2n(tout1,out);
+			}
+		l2n(tout0,ivec);
+		l2n(tout1,ivec);
+		}
+	else
+		{
+		n2l(ivec,xor0);
+		n2l(ivec,xor1);
+		ivec-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			n2l(in,tin0);
+			n2l(in,tin1);
+			tin[0]=tin0;
+			tin[1]=tin1;
+			BF_decrypt(tin,schedule);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2n(tout0,out);
+			l2n(tout1,out);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		if (l != -8)
+			{
+			n2l(in,tin0);
+			n2l(in,tin1);
+			tin[0]=tin0;
+			tin[1]=tin1;
+			BF_decrypt(tin,schedule);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2nn(tout0,tout1,out,l+8);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		l2n(xor0,ivec);
+		l2n(xor1,ivec);
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	tin[0]=tin[1]=0;
+	}
+
+#endif
diff --git a/openssl/crypto/bf/bf_locl.h b/openssl/crypto/bf/bf_locl.h
new file mode 100644
index 0000000..cc7c3ec
--- /dev/null
+++ b/openssl/crypto/bf/bf_locl.h
@@ -0,0 +1,219 @@
+/* crypto/bf/bf_locl.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BF_LOCL_H
+#define HEADER_BF_LOCL_H
+#include <openssl/opensslconf.h> /* BF_PTR, BF_PTR2 */
+
+#undef c2l
+#define c2l(c,l)	(l =((unsigned long)(*((c)++)))    , \
+			 l|=((unsigned long)(*((c)++)))<< 8L, \
+			 l|=((unsigned long)(*((c)++)))<<16L, \
+			 l|=((unsigned long)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#undef c2ln
+#define c2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
+			case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
+			case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
+			case 5: l2|=((unsigned long)(*(--(c))));     \
+			case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
+			case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
+			case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
+			case 1: l1|=((unsigned long)(*(--(c))));     \
+				} \
+			}
+
+#undef l2c
+#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#undef l2cn
+#define l2cn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
+				} \
+			}
+
+/* NOTE - c is not incremented as per n2l */
+#define n2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))    ; \
+			case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
+			case 6: l2|=((unsigned long)(*(--(c))))<<16; \
+			case 5: l2|=((unsigned long)(*(--(c))))<<24; \
+			case 4: l1 =((unsigned long)(*(--(c))))    ; \
+			case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
+			case 2: l1|=((unsigned long)(*(--(c))))<<16; \
+			case 1: l1|=((unsigned long)(*(--(c))))<<24; \
+				} \
+			}
+
+/* NOTE - c is not incremented as per l2n */
+#define l2nn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+				} \
+			}
+
+#undef n2l
+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++))))
+
+#undef l2n
+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)     )&0xff))
+
+/* This is actually a big endian algorithm, the most significant byte
+ * is used to lookup array 0 */
+
+#if defined(BF_PTR2)
+
+/*
+ * This is basically a special Intel version. Point is that Intel
+ * doesn't have many registers, but offers a reach choice of addressing
+ * modes. So we spare some registers by directly traversing BF_KEY
+ * structure and hiring the most decorated addressing mode. The code
+ * generated by EGCS is *perfectly* competitive with assembler
+ * implementation!
+ */
+#define BF_ENC(LL,R,KEY,Pi) (\
+	LL^=KEY[Pi], \
+	t=  KEY[BF_ROUNDS+2 +   0 + ((R>>24)&0xFF)], \
+	t+= KEY[BF_ROUNDS+2 + 256 + ((R>>16)&0xFF)], \
+	t^= KEY[BF_ROUNDS+2 + 512 + ((R>>8 )&0xFF)], \
+	t+= KEY[BF_ROUNDS+2 + 768 + ((R    )&0xFF)], \
+	LL^=t \
+	)
+
+#elif defined(BF_PTR)
+
+#ifndef BF_LONG_LOG2
+#define BF_LONG_LOG2  2       /* default to BF_LONG being 32 bits */
+#endif
+#define BF_M  (0xFF<<BF_LONG_LOG2)
+#define BF_0  (24-BF_LONG_LOG2)
+#define BF_1  (16-BF_LONG_LOG2)
+#define BF_2  ( 8-BF_LONG_LOG2)
+#define BF_3  BF_LONG_LOG2 /* left shift */
+
+/*
+ * This is normally very good on RISC platforms where normally you
+ * have to explicitly "multiply" array index by sizeof(BF_LONG)
+ * in order to calculate the effective address. This implementation
+ * excuses CPU from this extra work. Power[PC] uses should have most
+ * fun as (R>>BF_i)&BF_M gets folded into a single instruction, namely
+ * rlwinm. So let'em double-check if their compiler does it.
+ */
+
+#define BF_ENC(LL,R,S,P) ( \
+	LL^=P, \
+	LL^= (((*(BF_LONG *)((unsigned char *)&(S[  0])+((R>>BF_0)&BF_M))+ \
+		*(BF_LONG *)((unsigned char *)&(S[256])+((R>>BF_1)&BF_M)))^ \
+		*(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \
+		*(BF_LONG *)((unsigned char *)&(S[768])+((R<<BF_3)&BF_M))) \
+	)
+#else
+
+/*
+ * This is a *generic* version. Seem to perform best on platforms that
+ * offer explicit support for extraction of 8-bit nibbles preferably
+ * complemented with "multiplying" of array index by sizeof(BF_LONG).
+ * For the moment of this writing the list comprises Alpha CPU featuring
+ * extbl and s[48]addq instructions.
+ */
+
+#define BF_ENC(LL,R,S,P) ( \
+	LL^=P, \
+	LL^=(((	S[       ((int)(R>>24)&0xff)] + \
+		S[0x0100+((int)(R>>16)&0xff)])^ \
+		S[0x0200+((int)(R>> 8)&0xff)])+ \
+		S[0x0300+((int)(R    )&0xff)])&0xffffffffL \
+	)
+#endif
+
+#endif
diff --git a/openssl/crypto/bf/bf_ofb64.c b/openssl/crypto/bf/bf_ofb64.c
new file mode 100644
index 0000000..f2a9ff6
--- /dev/null
+++ b/openssl/crypto/bf/bf_ofb64.c
@@ -0,0 +1,110 @@
+/* crypto/bf/bf_ofb64.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/blowfish.h>
+#include "bf_locl.h"
+
+/* The input and output encrypted as though 64bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, long length,
+	     const BF_KEY *schedule, unsigned char *ivec, int *num)
+	{
+	register BF_LONG v0,v1,t;
+	register int n= *num;
+	register long l=length;
+	unsigned char d[8];
+	register char *dp;
+	BF_LONG ti[2];
+	unsigned char *iv;
+	int save=0;
+
+	iv=(unsigned char *)ivec;
+	n2l(iv,v0);
+	n2l(iv,v1);
+	ti[0]=v0;
+	ti[1]=v1;
+	dp=(char *)d;
+	l2n(v0,dp);
+	l2n(v1,dp);
+	while (l--)
+		{
+		if (n == 0)
+			{
+			BF_encrypt((BF_LONG *)ti,schedule);
+			dp=(char *)d;
+			t=ti[0]; l2n(t,dp);
+			t=ti[1]; l2n(t,dp);
+			save++;
+			}
+		*(out++)= *(in++)^d[n];
+		n=(n+1)&0x07;
+		}
+	if (save)
+		{
+		v0=ti[0];
+		v1=ti[1];
+		iv=(unsigned char *)ivec;
+		l2n(v0,iv);
+		l2n(v1,iv);
+		}
+	t=v0=v1=ti[0]=ti[1]=0;
+	*num=n;
+	}
+
diff --git a/openssl/crypto/bf/bf_opts.c b/openssl/crypto/bf/bf_opts.c
new file mode 100644
index 0000000..1721bb9
--- /dev/null
+++ b/openssl/crypto/bf/bf_opts.c
@@ -0,0 +1,331 @@
+/* crypto/bf/bf_opts.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
+ * This is for machines with 64k code segment size restrictions. */
+
+#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
+#define TIMES
+#endif
+
+#include <stdio.h>
+
+#include <openssl/e_os2.h>
+#include OPENSSL_UNISTD_IO
+OPENSSL_DECLARE_EXIT
+
+#ifndef OPENSSL_SYS_NETWARE
+#include <signal.h>
+#endif
+
+#ifndef _IRIX
+#include <time.h>
+#endif
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+#endif
+
+/* Depending on the VMS version, the tms structure is perhaps defined.
+   The __TMS macro will show if it was.  If it wasn't defined, we should
+   undefine TIMES, since that tells the rest of the program how things
+   should be handled.				-- Richard Levitte */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
+#undef TIMES
+#endif
+
+#ifndef TIMES
+#include <sys/timeb.h>
+#endif
+
+#if defined(sun) || defined(__ultrix)
+#define _POSIX_SOURCE
+#include <limits.h>
+#include <sys/param.h>
+#endif
+
+#include <openssl/blowfish.h>
+
+#define BF_DEFAULT_OPTIONS
+
+#undef BF_ENC
+#define BF_encrypt  BF_encrypt_normal
+#undef HEADER_BF_LOCL_H
+#include "bf_enc.c"
+
+#define BF_PTR
+#undef BF_PTR2
+#undef BF_ENC
+#undef BF_encrypt
+#define BF_encrypt  BF_encrypt_ptr
+#undef HEADER_BF_LOCL_H
+#include "bf_enc.c"
+
+#undef BF_PTR
+#define BF_PTR2
+#undef BF_ENC
+#undef BF_encrypt
+#define BF_encrypt  BF_encrypt_ptr2
+#undef HEADER_BF_LOCL_H
+#include "bf_enc.c"
+
+/* The following if from times(3) man page.  It may need to be changed */
+#ifndef HZ
+# ifndef CLK_TCK
+#  ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
+#   define HZ	100.0
+#  else /* _BSD_CLK_TCK_ */
+#   define HZ ((double)_BSD_CLK_TCK_)
+#  endif
+# else /* CLK_TCK */
+#  define HZ ((double)CLK_TCK)
+# endif
+#endif
+
+#define BUFSIZE	((long)1024)
+long run=0;
+
+double Time_F(int s);
+#ifdef SIGALRM
+#if defined(__STDC__) || defined(sgi)
+#define SIGRETTYPE void
+#else
+#define SIGRETTYPE int
+#endif
+
+SIGRETTYPE sig_done(int sig);
+SIGRETTYPE sig_done(int sig)
+	{
+	signal(SIGALRM,sig_done);
+	run=0;
+#ifdef LINT
+	sig=sig;
+#endif
+	}
+#endif
+
+#define START	0
+#define STOP	1
+
+double Time_F(int s)
+	{
+	double ret;
+#ifdef TIMES
+	static struct tms tstart,tend;
+
+	if (s == START)
+		{
+		times(&tstart);
+		return(0);
+		}
+	else
+		{
+		times(&tend);
+		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#else /* !times() */
+	static struct timeb tstart,tend;
+	long i;
+
+	if (s == START)
+		{
+		ftime(&tstart);
+		return(0);
+		}
+	else
+		{
+		ftime(&tend);
+		i=(long)tend.millitm-(long)tstart.millitm;
+		ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#endif
+	}
+
+#ifdef SIGALRM
+#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
+#else
+#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
+#endif
+	
+#define time_it(func,name,index) \
+	print_name(name); \
+	Time_F(START); \
+	for (count=0,run=1; COND(cb); count+=4) \
+		{ \
+		unsigned long d[2]; \
+		func(d,&sch); \
+		func(d,&sch); \
+		func(d,&sch); \
+		func(d,&sch); \
+		} \
+	tm[index]=Time_F(STOP); \
+	fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
+	tm[index]=((double)COUNT(cb))/tm[index];
+
+#define print_it(name,index) \
+	fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
+		tm[index]*8,1.0e6/tm[index]);
+
+int main(int argc, char **argv)
+	{
+	long count;
+	static unsigned char buf[BUFSIZE];
+	static char key[16]={	0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+				0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
+	BF_KEY sch;
+	double d,tm[16],max=0;
+	int rank[16];
+	char *str[16];
+	int max_idx=0,i,num=0,j;
+#ifndef SIGALARM
+	long ca,cb,cc,cd,ce;
+#endif
+
+	for (i=0; i<12; i++)
+		{
+		tm[i]=0.0;
+		rank[i]=0;
+		}
+
+#ifndef TIMES
+	fprintf(stderr,"To get the most accurate results, try to run this\n");
+	fprintf(stderr,"program when this computer is idle.\n");
+#endif
+
+	BF_set_key(&sch,16,key);
+
+#ifndef SIGALRM
+	fprintf(stderr,"First we calculate the approximate speed ...\n");
+	count=10;
+	do	{
+		long i;
+		unsigned long data[2];
+
+		count*=2;
+		Time_F(START);
+		for (i=count; i; i--)
+			BF_encrypt(data,&sch);
+		d=Time_F(STOP);
+		} while (d < 3.0);
+	ca=count;
+	cb=count*3;
+	cc=count*3*8/BUFSIZE+1;
+	cd=count*8/BUFSIZE+1;
+
+	ce=count/20+1;
+#define COND(d) (count != (d))
+#define COUNT(d) (d)
+#else
+#define COND(c) (run)
+#define COUNT(d) (count)
+        signal(SIGALRM,sig_done);
+        alarm(10);
+#endif
+
+	time_it(BF_encrypt_normal,	"BF_encrypt_normal ", 0);
+	time_it(BF_encrypt_ptr,		"BF_encrypt_ptr    ", 1);
+	time_it(BF_encrypt_ptr2,	"BF_encrypt_ptr2   ", 2);
+	num+=3;
+
+	str[0]="<nothing>";
+	print_it("BF_encrypt_normal ",0);
+	max=tm[0];
+	max_idx=0;
+	str[1]="ptr      ";
+	print_it("BF_encrypt_ptr ",1);
+	if (max < tm[1]) { max=tm[1]; max_idx=1; }
+	str[2]="ptr2     ";
+	print_it("BF_encrypt_ptr2 ",2);
+	if (max < tm[2]) { max=tm[2]; max_idx=2; }
+
+	printf("options    BF ecb/s\n");
+	printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
+	d=tm[max_idx];
+	tm[max_idx]= -2.0;
+	max= -1.0;
+	for (;;)
+		{
+		for (i=0; i<3; i++)
+			{
+			if (max < tm[i]) { max=tm[i]; j=i; }
+			}
+		if (max < 0.0) break;
+		printf("%s %12.2f  %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
+		tm[j]= -2.0;
+		max= -1.0;
+		}
+
+	switch (max_idx)
+		{
+	case 0:
+		printf("-DBF_DEFAULT_OPTIONS\n");
+		break;
+	case 1:
+		printf("-DBF_PTR\n");
+		break;
+	case 2:
+		printf("-DBF_PTR2\n");
+		break;
+		}
+	exit(0);
+#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
+	return(0);
+#endif
+	}
diff --git a/openssl/crypto/bf/bf_pi.h b/openssl/crypto/bf/bf_pi.h
new file mode 100644
index 0000000..9949513
--- /dev/null
+++ b/openssl/crypto/bf/bf_pi.h
@@ -0,0 +1,325 @@
+/* crypto/bf/bf_pi.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+static const BF_KEY bf_init= {
+	{
+	0x243f6a88L, 0x85a308d3L, 0x13198a2eL, 0x03707344L,
+	0xa4093822L, 0x299f31d0L, 0x082efa98L, 0xec4e6c89L,
+	0x452821e6L, 0x38d01377L, 0xbe5466cfL, 0x34e90c6cL,
+	0xc0ac29b7L, 0xc97c50ddL, 0x3f84d5b5L, 0xb5470917L,
+	0x9216d5d9L, 0x8979fb1b
+	},{
+	0xd1310ba6L, 0x98dfb5acL, 0x2ffd72dbL, 0xd01adfb7L, 
+	0xb8e1afedL, 0x6a267e96L, 0xba7c9045L, 0xf12c7f99L, 
+	0x24a19947L, 0xb3916cf7L, 0x0801f2e2L, 0x858efc16L, 
+	0x636920d8L, 0x71574e69L, 0xa458fea3L, 0xf4933d7eL, 
+	0x0d95748fL, 0x728eb658L, 0x718bcd58L, 0x82154aeeL, 
+	0x7b54a41dL, 0xc25a59b5L, 0x9c30d539L, 0x2af26013L, 
+	0xc5d1b023L, 0x286085f0L, 0xca417918L, 0xb8db38efL, 
+	0x8e79dcb0L, 0x603a180eL, 0x6c9e0e8bL, 0xb01e8a3eL, 
+	0xd71577c1L, 0xbd314b27L, 0x78af2fdaL, 0x55605c60L, 
+	0xe65525f3L, 0xaa55ab94L, 0x57489862L, 0x63e81440L, 
+	0x55ca396aL, 0x2aab10b6L, 0xb4cc5c34L, 0x1141e8ceL, 
+	0xa15486afL, 0x7c72e993L, 0xb3ee1411L, 0x636fbc2aL, 
+	0x2ba9c55dL, 0x741831f6L, 0xce5c3e16L, 0x9b87931eL, 
+	0xafd6ba33L, 0x6c24cf5cL, 0x7a325381L, 0x28958677L, 
+	0x3b8f4898L, 0x6b4bb9afL, 0xc4bfe81bL, 0x66282193L, 
+	0x61d809ccL, 0xfb21a991L, 0x487cac60L, 0x5dec8032L, 
+	0xef845d5dL, 0xe98575b1L, 0xdc262302L, 0xeb651b88L, 
+	0x23893e81L, 0xd396acc5L, 0x0f6d6ff3L, 0x83f44239L, 
+	0x2e0b4482L, 0xa4842004L, 0x69c8f04aL, 0x9e1f9b5eL, 
+	0x21c66842L, 0xf6e96c9aL, 0x670c9c61L, 0xabd388f0L, 
+	0x6a51a0d2L, 0xd8542f68L, 0x960fa728L, 0xab5133a3L, 
+	0x6eef0b6cL, 0x137a3be4L, 0xba3bf050L, 0x7efb2a98L, 
+	0xa1f1651dL, 0x39af0176L, 0x66ca593eL, 0x82430e88L, 
+	0x8cee8619L, 0x456f9fb4L, 0x7d84a5c3L, 0x3b8b5ebeL, 
+	0xe06f75d8L, 0x85c12073L, 0x401a449fL, 0x56c16aa6L, 
+	0x4ed3aa62L, 0x363f7706L, 0x1bfedf72L, 0x429b023dL, 
+	0x37d0d724L, 0xd00a1248L, 0xdb0fead3L, 0x49f1c09bL, 
+	0x075372c9L, 0x80991b7bL, 0x25d479d8L, 0xf6e8def7L, 
+	0xe3fe501aL, 0xb6794c3bL, 0x976ce0bdL, 0x04c006baL, 
+	0xc1a94fb6L, 0x409f60c4L, 0x5e5c9ec2L, 0x196a2463L, 
+	0x68fb6fafL, 0x3e6c53b5L, 0x1339b2ebL, 0x3b52ec6fL, 
+	0x6dfc511fL, 0x9b30952cL, 0xcc814544L, 0xaf5ebd09L, 
+	0xbee3d004L, 0xde334afdL, 0x660f2807L, 0x192e4bb3L, 
+	0xc0cba857L, 0x45c8740fL, 0xd20b5f39L, 0xb9d3fbdbL, 
+	0x5579c0bdL, 0x1a60320aL, 0xd6a100c6L, 0x402c7279L, 
+	0x679f25feL, 0xfb1fa3ccL, 0x8ea5e9f8L, 0xdb3222f8L, 
+	0x3c7516dfL, 0xfd616b15L, 0x2f501ec8L, 0xad0552abL, 
+	0x323db5faL, 0xfd238760L, 0x53317b48L, 0x3e00df82L, 
+	0x9e5c57bbL, 0xca6f8ca0L, 0x1a87562eL, 0xdf1769dbL, 
+	0xd542a8f6L, 0x287effc3L, 0xac6732c6L, 0x8c4f5573L, 
+	0x695b27b0L, 0xbbca58c8L, 0xe1ffa35dL, 0xb8f011a0L, 
+	0x10fa3d98L, 0xfd2183b8L, 0x4afcb56cL, 0x2dd1d35bL, 
+	0x9a53e479L, 0xb6f84565L, 0xd28e49bcL, 0x4bfb9790L, 
+	0xe1ddf2daL, 0xa4cb7e33L, 0x62fb1341L, 0xcee4c6e8L, 
+	0xef20cadaL, 0x36774c01L, 0xd07e9efeL, 0x2bf11fb4L, 
+	0x95dbda4dL, 0xae909198L, 0xeaad8e71L, 0x6b93d5a0L, 
+	0xd08ed1d0L, 0xafc725e0L, 0x8e3c5b2fL, 0x8e7594b7L, 
+	0x8ff6e2fbL, 0xf2122b64L, 0x8888b812L, 0x900df01cL, 
+	0x4fad5ea0L, 0x688fc31cL, 0xd1cff191L, 0xb3a8c1adL, 
+	0x2f2f2218L, 0xbe0e1777L, 0xea752dfeL, 0x8b021fa1L, 
+	0xe5a0cc0fL, 0xb56f74e8L, 0x18acf3d6L, 0xce89e299L, 
+	0xb4a84fe0L, 0xfd13e0b7L, 0x7cc43b81L, 0xd2ada8d9L, 
+	0x165fa266L, 0x80957705L, 0x93cc7314L, 0x211a1477L, 
+	0xe6ad2065L, 0x77b5fa86L, 0xc75442f5L, 0xfb9d35cfL, 
+	0xebcdaf0cL, 0x7b3e89a0L, 0xd6411bd3L, 0xae1e7e49L, 
+	0x00250e2dL, 0x2071b35eL, 0x226800bbL, 0x57b8e0afL, 
+	0x2464369bL, 0xf009b91eL, 0x5563911dL, 0x59dfa6aaL, 
+	0x78c14389L, 0xd95a537fL, 0x207d5ba2L, 0x02e5b9c5L, 
+	0x83260376L, 0x6295cfa9L, 0x11c81968L, 0x4e734a41L, 
+	0xb3472dcaL, 0x7b14a94aL, 0x1b510052L, 0x9a532915L, 
+	0xd60f573fL, 0xbc9bc6e4L, 0x2b60a476L, 0x81e67400L, 
+	0x08ba6fb5L, 0x571be91fL, 0xf296ec6bL, 0x2a0dd915L, 
+	0xb6636521L, 0xe7b9f9b6L, 0xff34052eL, 0xc5855664L, 
+	0x53b02d5dL, 0xa99f8fa1L, 0x08ba4799L, 0x6e85076aL, 
+	0x4b7a70e9L, 0xb5b32944L, 0xdb75092eL, 0xc4192623L, 
+	0xad6ea6b0L, 0x49a7df7dL, 0x9cee60b8L, 0x8fedb266L, 
+	0xecaa8c71L, 0x699a17ffL, 0x5664526cL, 0xc2b19ee1L, 
+	0x193602a5L, 0x75094c29L, 0xa0591340L, 0xe4183a3eL, 
+	0x3f54989aL, 0x5b429d65L, 0x6b8fe4d6L, 0x99f73fd6L, 
+	0xa1d29c07L, 0xefe830f5L, 0x4d2d38e6L, 0xf0255dc1L, 
+	0x4cdd2086L, 0x8470eb26L, 0x6382e9c6L, 0x021ecc5eL, 
+	0x09686b3fL, 0x3ebaefc9L, 0x3c971814L, 0x6b6a70a1L, 
+	0x687f3584L, 0x52a0e286L, 0xb79c5305L, 0xaa500737L, 
+	0x3e07841cL, 0x7fdeae5cL, 0x8e7d44ecL, 0x5716f2b8L, 
+	0xb03ada37L, 0xf0500c0dL, 0xf01c1f04L, 0x0200b3ffL, 
+	0xae0cf51aL, 0x3cb574b2L, 0x25837a58L, 0xdc0921bdL, 
+	0xd19113f9L, 0x7ca92ff6L, 0x94324773L, 0x22f54701L, 
+	0x3ae5e581L, 0x37c2dadcL, 0xc8b57634L, 0x9af3dda7L, 
+	0xa9446146L, 0x0fd0030eL, 0xecc8c73eL, 0xa4751e41L, 
+	0xe238cd99L, 0x3bea0e2fL, 0x3280bba1L, 0x183eb331L, 
+	0x4e548b38L, 0x4f6db908L, 0x6f420d03L, 0xf60a04bfL, 
+	0x2cb81290L, 0x24977c79L, 0x5679b072L, 0xbcaf89afL, 
+	0xde9a771fL, 0xd9930810L, 0xb38bae12L, 0xdccf3f2eL, 
+	0x5512721fL, 0x2e6b7124L, 0x501adde6L, 0x9f84cd87L, 
+	0x7a584718L, 0x7408da17L, 0xbc9f9abcL, 0xe94b7d8cL, 
+	0xec7aec3aL, 0xdb851dfaL, 0x63094366L, 0xc464c3d2L, 
+	0xef1c1847L, 0x3215d908L, 0xdd433b37L, 0x24c2ba16L, 
+	0x12a14d43L, 0x2a65c451L, 0x50940002L, 0x133ae4ddL, 
+	0x71dff89eL, 0x10314e55L, 0x81ac77d6L, 0x5f11199bL, 
+	0x043556f1L, 0xd7a3c76bL, 0x3c11183bL, 0x5924a509L, 
+	0xf28fe6edL, 0x97f1fbfaL, 0x9ebabf2cL, 0x1e153c6eL, 
+	0x86e34570L, 0xeae96fb1L, 0x860e5e0aL, 0x5a3e2ab3L, 
+	0x771fe71cL, 0x4e3d06faL, 0x2965dcb9L, 0x99e71d0fL, 
+	0x803e89d6L, 0x5266c825L, 0x2e4cc978L, 0x9c10b36aL, 
+	0xc6150ebaL, 0x94e2ea78L, 0xa5fc3c53L, 0x1e0a2df4L, 
+	0xf2f74ea7L, 0x361d2b3dL, 0x1939260fL, 0x19c27960L, 
+	0x5223a708L, 0xf71312b6L, 0xebadfe6eL, 0xeac31f66L, 
+	0xe3bc4595L, 0xa67bc883L, 0xb17f37d1L, 0x018cff28L, 
+	0xc332ddefL, 0xbe6c5aa5L, 0x65582185L, 0x68ab9802L, 
+	0xeecea50fL, 0xdb2f953bL, 0x2aef7dadL, 0x5b6e2f84L, 
+	0x1521b628L, 0x29076170L, 0xecdd4775L, 0x619f1510L, 
+	0x13cca830L, 0xeb61bd96L, 0x0334fe1eL, 0xaa0363cfL, 
+	0xb5735c90L, 0x4c70a239L, 0xd59e9e0bL, 0xcbaade14L, 
+	0xeecc86bcL, 0x60622ca7L, 0x9cab5cabL, 0xb2f3846eL, 
+	0x648b1eafL, 0x19bdf0caL, 0xa02369b9L, 0x655abb50L, 
+	0x40685a32L, 0x3c2ab4b3L, 0x319ee9d5L, 0xc021b8f7L, 
+	0x9b540b19L, 0x875fa099L, 0x95f7997eL, 0x623d7da8L, 
+	0xf837889aL, 0x97e32d77L, 0x11ed935fL, 0x16681281L, 
+	0x0e358829L, 0xc7e61fd6L, 0x96dedfa1L, 0x7858ba99L, 
+	0x57f584a5L, 0x1b227263L, 0x9b83c3ffL, 0x1ac24696L, 
+	0xcdb30aebL, 0x532e3054L, 0x8fd948e4L, 0x6dbc3128L, 
+	0x58ebf2efL, 0x34c6ffeaL, 0xfe28ed61L, 0xee7c3c73L, 
+	0x5d4a14d9L, 0xe864b7e3L, 0x42105d14L, 0x203e13e0L, 
+	0x45eee2b6L, 0xa3aaabeaL, 0xdb6c4f15L, 0xfacb4fd0L, 
+	0xc742f442L, 0xef6abbb5L, 0x654f3b1dL, 0x41cd2105L, 
+	0xd81e799eL, 0x86854dc7L, 0xe44b476aL, 0x3d816250L, 
+	0xcf62a1f2L, 0x5b8d2646L, 0xfc8883a0L, 0xc1c7b6a3L, 
+	0x7f1524c3L, 0x69cb7492L, 0x47848a0bL, 0x5692b285L, 
+	0x095bbf00L, 0xad19489dL, 0x1462b174L, 0x23820e00L, 
+	0x58428d2aL, 0x0c55f5eaL, 0x1dadf43eL, 0x233f7061L, 
+	0x3372f092L, 0x8d937e41L, 0xd65fecf1L, 0x6c223bdbL, 
+	0x7cde3759L, 0xcbee7460L, 0x4085f2a7L, 0xce77326eL, 
+	0xa6078084L, 0x19f8509eL, 0xe8efd855L, 0x61d99735L, 
+	0xa969a7aaL, 0xc50c06c2L, 0x5a04abfcL, 0x800bcadcL, 
+	0x9e447a2eL, 0xc3453484L, 0xfdd56705L, 0x0e1e9ec9L, 
+	0xdb73dbd3L, 0x105588cdL, 0x675fda79L, 0xe3674340L, 
+	0xc5c43465L, 0x713e38d8L, 0x3d28f89eL, 0xf16dff20L, 
+	0x153e21e7L, 0x8fb03d4aL, 0xe6e39f2bL, 0xdb83adf7L, 
+	0xe93d5a68L, 0x948140f7L, 0xf64c261cL, 0x94692934L, 
+	0x411520f7L, 0x7602d4f7L, 0xbcf46b2eL, 0xd4a20068L, 
+	0xd4082471L, 0x3320f46aL, 0x43b7d4b7L, 0x500061afL, 
+	0x1e39f62eL, 0x97244546L, 0x14214f74L, 0xbf8b8840L, 
+	0x4d95fc1dL, 0x96b591afL, 0x70f4ddd3L, 0x66a02f45L, 
+	0xbfbc09ecL, 0x03bd9785L, 0x7fac6dd0L, 0x31cb8504L, 
+	0x96eb27b3L, 0x55fd3941L, 0xda2547e6L, 0xabca0a9aL, 
+	0x28507825L, 0x530429f4L, 0x0a2c86daL, 0xe9b66dfbL, 
+	0x68dc1462L, 0xd7486900L, 0x680ec0a4L, 0x27a18deeL, 
+	0x4f3ffea2L, 0xe887ad8cL, 0xb58ce006L, 0x7af4d6b6L, 
+	0xaace1e7cL, 0xd3375fecL, 0xce78a399L, 0x406b2a42L, 
+	0x20fe9e35L, 0xd9f385b9L, 0xee39d7abL, 0x3b124e8bL, 
+	0x1dc9faf7L, 0x4b6d1856L, 0x26a36631L, 0xeae397b2L, 
+	0x3a6efa74L, 0xdd5b4332L, 0x6841e7f7L, 0xca7820fbL, 
+	0xfb0af54eL, 0xd8feb397L, 0x454056acL, 0xba489527L, 
+	0x55533a3aL, 0x20838d87L, 0xfe6ba9b7L, 0xd096954bL, 
+	0x55a867bcL, 0xa1159a58L, 0xcca92963L, 0x99e1db33L, 
+	0xa62a4a56L, 0x3f3125f9L, 0x5ef47e1cL, 0x9029317cL, 
+	0xfdf8e802L, 0x04272f70L, 0x80bb155cL, 0x05282ce3L, 
+	0x95c11548L, 0xe4c66d22L, 0x48c1133fL, 0xc70f86dcL, 
+	0x07f9c9eeL, 0x41041f0fL, 0x404779a4L, 0x5d886e17L, 
+	0x325f51ebL, 0xd59bc0d1L, 0xf2bcc18fL, 0x41113564L, 
+	0x257b7834L, 0x602a9c60L, 0xdff8e8a3L, 0x1f636c1bL, 
+	0x0e12b4c2L, 0x02e1329eL, 0xaf664fd1L, 0xcad18115L, 
+	0x6b2395e0L, 0x333e92e1L, 0x3b240b62L, 0xeebeb922L, 
+	0x85b2a20eL, 0xe6ba0d99L, 0xde720c8cL, 0x2da2f728L, 
+	0xd0127845L, 0x95b794fdL, 0x647d0862L, 0xe7ccf5f0L, 
+	0x5449a36fL, 0x877d48faL, 0xc39dfd27L, 0xf33e8d1eL, 
+	0x0a476341L, 0x992eff74L, 0x3a6f6eabL, 0xf4f8fd37L, 
+	0xa812dc60L, 0xa1ebddf8L, 0x991be14cL, 0xdb6e6b0dL, 
+	0xc67b5510L, 0x6d672c37L, 0x2765d43bL, 0xdcd0e804L, 
+	0xf1290dc7L, 0xcc00ffa3L, 0xb5390f92L, 0x690fed0bL, 
+	0x667b9ffbL, 0xcedb7d9cL, 0xa091cf0bL, 0xd9155ea3L, 
+	0xbb132f88L, 0x515bad24L, 0x7b9479bfL, 0x763bd6ebL, 
+	0x37392eb3L, 0xcc115979L, 0x8026e297L, 0xf42e312dL, 
+	0x6842ada7L, 0xc66a2b3bL, 0x12754cccL, 0x782ef11cL, 
+	0x6a124237L, 0xb79251e7L, 0x06a1bbe6L, 0x4bfb6350L, 
+	0x1a6b1018L, 0x11caedfaL, 0x3d25bdd8L, 0xe2e1c3c9L, 
+	0x44421659L, 0x0a121386L, 0xd90cec6eL, 0xd5abea2aL, 
+	0x64af674eL, 0xda86a85fL, 0xbebfe988L, 0x64e4c3feL, 
+	0x9dbc8057L, 0xf0f7c086L, 0x60787bf8L, 0x6003604dL, 
+	0xd1fd8346L, 0xf6381fb0L, 0x7745ae04L, 0xd736fcccL, 
+	0x83426b33L, 0xf01eab71L, 0xb0804187L, 0x3c005e5fL, 
+	0x77a057beL, 0xbde8ae24L, 0x55464299L, 0xbf582e61L, 
+	0x4e58f48fL, 0xf2ddfda2L, 0xf474ef38L, 0x8789bdc2L, 
+	0x5366f9c3L, 0xc8b38e74L, 0xb475f255L, 0x46fcd9b9L, 
+	0x7aeb2661L, 0x8b1ddf84L, 0x846a0e79L, 0x915f95e2L, 
+	0x466e598eL, 0x20b45770L, 0x8cd55591L, 0xc902de4cL, 
+	0xb90bace1L, 0xbb8205d0L, 0x11a86248L, 0x7574a99eL, 
+	0xb77f19b6L, 0xe0a9dc09L, 0x662d09a1L, 0xc4324633L, 
+	0xe85a1f02L, 0x09f0be8cL, 0x4a99a025L, 0x1d6efe10L, 
+	0x1ab93d1dL, 0x0ba5a4dfL, 0xa186f20fL, 0x2868f169L, 
+	0xdcb7da83L, 0x573906feL, 0xa1e2ce9bL, 0x4fcd7f52L, 
+	0x50115e01L, 0xa70683faL, 0xa002b5c4L, 0x0de6d027L, 
+	0x9af88c27L, 0x773f8641L, 0xc3604c06L, 0x61a806b5L, 
+	0xf0177a28L, 0xc0f586e0L, 0x006058aaL, 0x30dc7d62L, 
+	0x11e69ed7L, 0x2338ea63L, 0x53c2dd94L, 0xc2c21634L, 
+	0xbbcbee56L, 0x90bcb6deL, 0xebfc7da1L, 0xce591d76L, 
+	0x6f05e409L, 0x4b7c0188L, 0x39720a3dL, 0x7c927c24L, 
+	0x86e3725fL, 0x724d9db9L, 0x1ac15bb4L, 0xd39eb8fcL, 
+	0xed545578L, 0x08fca5b5L, 0xd83d7cd3L, 0x4dad0fc4L, 
+	0x1e50ef5eL, 0xb161e6f8L, 0xa28514d9L, 0x6c51133cL, 
+	0x6fd5c7e7L, 0x56e14ec4L, 0x362abfceL, 0xddc6c837L, 
+	0xd79a3234L, 0x92638212L, 0x670efa8eL, 0x406000e0L, 
+	0x3a39ce37L, 0xd3faf5cfL, 0xabc27737L, 0x5ac52d1bL, 
+	0x5cb0679eL, 0x4fa33742L, 0xd3822740L, 0x99bc9bbeL, 
+	0xd5118e9dL, 0xbf0f7315L, 0xd62d1c7eL, 0xc700c47bL, 
+	0xb78c1b6bL, 0x21a19045L, 0xb26eb1beL, 0x6a366eb4L, 
+	0x5748ab2fL, 0xbc946e79L, 0xc6a376d2L, 0x6549c2c8L, 
+	0x530ff8eeL, 0x468dde7dL, 0xd5730a1dL, 0x4cd04dc6L, 
+	0x2939bbdbL, 0xa9ba4650L, 0xac9526e8L, 0xbe5ee304L, 
+	0xa1fad5f0L, 0x6a2d519aL, 0x63ef8ce2L, 0x9a86ee22L, 
+	0xc089c2b8L, 0x43242ef6L, 0xa51e03aaL, 0x9cf2d0a4L, 
+	0x83c061baL, 0x9be96a4dL, 0x8fe51550L, 0xba645bd6L, 
+	0x2826a2f9L, 0xa73a3ae1L, 0x4ba99586L, 0xef5562e9L, 
+	0xc72fefd3L, 0xf752f7daL, 0x3f046f69L, 0x77fa0a59L, 
+	0x80e4a915L, 0x87b08601L, 0x9b09e6adL, 0x3b3ee593L, 
+	0xe990fd5aL, 0x9e34d797L, 0x2cf0b7d9L, 0x022b8b51L, 
+	0x96d5ac3aL, 0x017da67dL, 0xd1cf3ed6L, 0x7c7d2d28L, 
+	0x1f9f25cfL, 0xadf2b89bL, 0x5ad6b472L, 0x5a88f54cL, 
+	0xe029ac71L, 0xe019a5e6L, 0x47b0acfdL, 0xed93fa9bL, 
+	0xe8d3c48dL, 0x283b57ccL, 0xf8d56629L, 0x79132e28L, 
+	0x785f0191L, 0xed756055L, 0xf7960e44L, 0xe3d35e8cL, 
+	0x15056dd4L, 0x88f46dbaL, 0x03a16125L, 0x0564f0bdL, 
+	0xc3eb9e15L, 0x3c9057a2L, 0x97271aecL, 0xa93a072aL, 
+	0x1b3f6d9bL, 0x1e6321f5L, 0xf59c66fbL, 0x26dcf319L, 
+	0x7533d928L, 0xb155fdf5L, 0x03563482L, 0x8aba3cbbL, 
+	0x28517711L, 0xc20ad9f8L, 0xabcc5167L, 0xccad925fL, 
+	0x4de81751L, 0x3830dc8eL, 0x379d5862L, 0x9320f991L, 
+	0xea7a90c2L, 0xfb3e7bceL, 0x5121ce64L, 0x774fbe32L, 
+	0xa8b6e37eL, 0xc3293d46L, 0x48de5369L, 0x6413e680L, 
+	0xa2ae0810L, 0xdd6db224L, 0x69852dfdL, 0x09072166L, 
+	0xb39a460aL, 0x6445c0ddL, 0x586cdecfL, 0x1c20c8aeL, 
+	0x5bbef7ddL, 0x1b588d40L, 0xccd2017fL, 0x6bb4e3bbL, 
+	0xdda26a7eL, 0x3a59ff45L, 0x3e350a44L, 0xbcb4cdd5L, 
+	0x72eacea8L, 0xfa6484bbL, 0x8d6612aeL, 0xbf3c6f47L, 
+	0xd29be463L, 0x542f5d9eL, 0xaec2771bL, 0xf64e6370L, 
+	0x740e0d8dL, 0xe75b1357L, 0xf8721671L, 0xaf537d5dL, 
+	0x4040cb08L, 0x4eb4e2ccL, 0x34d2466aL, 0x0115af84L, 
+	0xe1b00428L, 0x95983a1dL, 0x06b89fb4L, 0xce6ea048L, 
+	0x6f3f3b82L, 0x3520ab82L, 0x011a1d4bL, 0x277227f8L, 
+	0x611560b1L, 0xe7933fdcL, 0xbb3a792bL, 0x344525bdL, 
+	0xa08839e1L, 0x51ce794bL, 0x2f32c9b7L, 0xa01fbac9L, 
+	0xe01cc87eL, 0xbcc7d1f6L, 0xcf0111c3L, 0xa1e8aac7L, 
+	0x1a908749L, 0xd44fbd9aL, 0xd0dadecbL, 0xd50ada38L, 
+	0x0339c32aL, 0xc6913667L, 0x8df9317cL, 0xe0b12b4fL, 
+	0xf79e59b7L, 0x43f5bb3aL, 0xf2d519ffL, 0x27d9459cL, 
+	0xbf97222cL, 0x15e6fc2aL, 0x0f91fc71L, 0x9b941525L, 
+	0xfae59361L, 0xceb69cebL, 0xc2a86459L, 0x12baa8d1L, 
+	0xb6c1075eL, 0xe3056a0cL, 0x10d25065L, 0xcb03a442L, 
+	0xe0ec6e0eL, 0x1698db3bL, 0x4c98a0beL, 0x3278e964L, 
+	0x9f1f9532L, 0xe0d392dfL, 0xd3a0342bL, 0x8971f21eL, 
+	0x1b0a7441L, 0x4ba3348cL, 0xc5be7120L, 0xc37632d8L, 
+	0xdf359f8dL, 0x9b992f2eL, 0xe60b6f47L, 0x0fe3f11dL, 
+	0xe54cda54L, 0x1edad891L, 0xce6279cfL, 0xcd3e7e6fL, 
+	0x1618b166L, 0xfd2c1d05L, 0x848fd2c5L, 0xf6fb2299L, 
+	0xf523f357L, 0xa6327623L, 0x93a83531L, 0x56cccd02L, 
+	0xacf08162L, 0x5a75ebb5L, 0x6e163697L, 0x88d273ccL, 
+	0xde966292L, 0x81b949d0L, 0x4c50901bL, 0x71c65614L, 
+	0xe6c6c7bdL, 0x327a140aL, 0x45e1d006L, 0xc3f27b9aL, 
+	0xc9aa53fdL, 0x62a80f00L, 0xbb25bfe2L, 0x35bdd2f6L, 
+	0x71126905L, 0xb2040222L, 0xb6cbcf7cL, 0xcd769c2bL, 
+	0x53113ec0L, 0x1640e3d3L, 0x38abbd60L, 0x2547adf0L, 
+	0xba38209cL, 0xf746ce76L, 0x77afa1c5L, 0x20756060L, 
+	0x85cbfe4eL, 0x8ae88dd8L, 0x7aaaf9b0L, 0x4cf9aa7eL, 
+	0x1948c25cL, 0x02fb8a8cL, 0x01c36ae4L, 0xd6ebe1f9L, 
+	0x90d4f869L, 0xa65cdea0L, 0x3f09252dL, 0xc208e69fL, 
+	0xb74e6132L, 0xce77e25bL, 0x578fdfe3L, 0x3ac372e6L, 
+	}
+	};
+
diff --git a/openssl/crypto/bf/bf_skey.c b/openssl/crypto/bf/bf_skey.c
new file mode 100644
index 0000000..3673cde
--- /dev/null
+++ b/openssl/crypto/bf/bf_skey.c
@@ -0,0 +1,116 @@
+/* crypto/bf/bf_skey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/blowfish.h>
+#include "bf_locl.h"
+#include "bf_pi.h"
+
+void BF_set_key(BF_KEY *key, int len, const unsigned char *data)
+	{
+	int i;
+	BF_LONG *p,ri,in[2];
+	const unsigned char *d,*end;
+
+
+	memcpy(key,&bf_init,sizeof(BF_KEY));
+	p=key->P;
+
+	if (len > ((BF_ROUNDS+2)*4)) len=(BF_ROUNDS+2)*4;
+
+	d=data;
+	end= &(data[len]);
+	for (i=0; i<(BF_ROUNDS+2); i++)
+		{
+		ri= *(d++);
+		if (d >= end) d=data;
+
+		ri<<=8;
+		ri|= *(d++);
+		if (d >= end) d=data;
+
+		ri<<=8;
+		ri|= *(d++);
+		if (d >= end) d=data;
+
+		ri<<=8;
+		ri|= *(d++);
+		if (d >= end) d=data;
+
+		p[i]^=ri;
+		}
+
+	in[0]=0L;
+	in[1]=0L;
+	for (i=0; i<(BF_ROUNDS+2); i+=2)
+		{
+		BF_encrypt(in,key);
+		p[i  ]=in[0];
+		p[i+1]=in[1];
+		}
+
+	p=key->S;
+	for (i=0; i<4*256; i+=2)
+		{
+		BF_encrypt(in,key);
+		p[i  ]=in[0];
+		p[i+1]=in[1];
+		}
+	}
+
diff --git a/openssl/crypto/bf/bfs.cpp b/openssl/crypto/bf/bfs.cpp
new file mode 100644
index 0000000..d74c457
--- /dev/null
+++ b/openssl/crypto/bf/bfs.cpp
@@ -0,0 +1,67 @@
+//
+// gettsc.inl
+//
+// gives access to the Pentium's (secret) cycle counter
+//
+// This software was written by Leonard Janke (janke@unixg.ubc.ca)
+// in 1996-7 and is entered, by him, into the public domain.
+
+#if defined(__WATCOMC__)
+void GetTSC(unsigned long&);
+#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
+#elif defined(__GNUC__)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  asm volatile(".byte 15, 49\n\t"
+	       : "=eax" (tsc)
+	       :
+	       : "%edx", "%eax");
+}
+#elif defined(_MSC_VER)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  unsigned long a;
+  __asm _emit 0fh
+  __asm _emit 31h
+  __asm mov a, eax;
+  tsc=a;
+}
+#endif      
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/blowfish.h>
+
+void main(int argc,char *argv[])
+	{
+	BF_KEY key;
+	unsigned long s1,s2,e1,e2;
+	unsigned long data[2];
+	int i,j;
+
+	for (j=0; j<6; j++)
+		{
+		for (i=0; i<1000; i++) /**/
+			{
+			BF_encrypt(&data[0],&key);
+			GetTSC(s1);
+			BF_encrypt(&data[0],&key);
+			BF_encrypt(&data[0],&key);
+			BF_encrypt(&data[0],&key);
+			GetTSC(e1);
+			GetTSC(s2);
+			BF_encrypt(&data[0],&key);
+			BF_encrypt(&data[0],&key);
+			BF_encrypt(&data[0],&key);
+			BF_encrypt(&data[0],&key);
+			GetTSC(e2);
+			BF_encrypt(&data[0],&key);
+			}
+
+		printf("blowfish %d %d (%d)\n",
+			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
+		}
+	}
+
diff --git a/openssl/crypto/bf/bfspeed.c b/openssl/crypto/bf/bfspeed.c
new file mode 100644
index 0000000..c41ef3b
--- /dev/null
+++ b/openssl/crypto/bf/bfspeed.c
@@ -0,0 +1,277 @@
+/* crypto/bf/bfspeed.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
+/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
+
+#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
+#define TIMES
+#endif
+
+#include <stdio.h>
+
+#include <openssl/e_os2.h>
+#include OPENSSL_UNISTD_IO
+OPENSSL_DECLARE_EXIT
+
+#ifndef OPENSSL_SYS_NETWARE
+#include <signal.h>
+#endif
+
+#ifndef _IRIX
+#include <time.h>
+#endif
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+#endif
+
+/* Depending on the VMS version, the tms structure is perhaps defined.
+   The __TMS macro will show if it was.  If it wasn't defined, we should
+   undefine TIMES, since that tells the rest of the program how things
+   should be handled.				-- Richard Levitte */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
+#undef TIMES
+#endif
+
+#ifndef TIMES
+#include <sys/timeb.h>
+#endif
+
+#if defined(sun) || defined(__ultrix)
+#define _POSIX_SOURCE
+#include <limits.h>
+#include <sys/param.h>
+#endif
+
+#include <openssl/blowfish.h>
+
+/* The following if from times(3) man page.  It may need to be changed */
+#ifndef HZ
+#ifndef CLK_TCK
+#define HZ	100.0
+#else /* CLK_TCK */
+#define HZ ((double)CLK_TCK)
+#endif
+#endif
+
+#define BUFSIZE	((long)1024)
+long run=0;
+
+double Time_F(int s);
+#ifdef SIGALRM
+#if defined(__STDC__) || defined(sgi) || defined(_AIX)
+#define SIGRETTYPE void
+#else
+#define SIGRETTYPE int
+#endif
+
+SIGRETTYPE sig_done(int sig);
+SIGRETTYPE sig_done(int sig)
+	{
+	signal(SIGALRM,sig_done);
+	run=0;
+#ifdef LINT
+	sig=sig;
+#endif
+	}
+#endif
+
+#define START	0
+#define STOP	1
+
+double Time_F(int s)
+	{
+	double ret;
+#ifdef TIMES
+	static struct tms tstart,tend;
+
+	if (s == START)
+		{
+		times(&tstart);
+		return(0);
+		}
+	else
+		{
+		times(&tend);
+		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#else /* !times() */
+	static struct timeb tstart,tend;
+	long i;
+
+	if (s == START)
+		{
+		ftime(&tstart);
+		return(0);
+		}
+	else
+		{
+		ftime(&tend);
+		i=(long)tend.millitm-(long)tstart.millitm;
+		ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#endif
+	}
+
+int main(int argc, char **argv)
+	{
+	long count;
+	static unsigned char buf[BUFSIZE];
+	static unsigned char key[] ={
+			0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+			0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
+			};
+	BF_KEY sch;
+	double a,b,c,d;
+#ifndef SIGALRM
+	long ca,cb,cc;
+#endif
+
+#ifndef TIMES
+	printf("To get the most accurate results, try to run this\n");
+	printf("program when this computer is idle.\n");
+#endif
+
+#ifndef SIGALRM
+	printf("First we calculate the approximate speed ...\n");
+	BF_set_key(&sch,16,key);
+	count=10;
+	do	{
+		long i;
+		BF_LONG data[2];
+
+		count*=2;
+		Time_F(START);
+		for (i=count; i; i--)
+			BF_encrypt(data,&sch);
+		d=Time_F(STOP);
+		} while (d < 3.0);
+	ca=count/512;
+	cb=count;
+	cc=count*8/BUFSIZE+1;
+	printf("Doing BF_set_key %ld times\n",ca);
+#define COND(d)	(count != (d))
+#define COUNT(d) (d)
+#else
+#define COND(c)	(run)
+#define COUNT(d) (count)
+	signal(SIGALRM,sig_done);
+	printf("Doing BF_set_key for 10 seconds\n");
+	alarm(10);
+#endif
+
+	Time_F(START);
+	for (count=0,run=1; COND(ca); count+=4)
+		{
+		BF_set_key(&sch,16,key);
+		BF_set_key(&sch,16,key);
+		BF_set_key(&sch,16,key);
+		BF_set_key(&sch,16,key);
+		}
+	d=Time_F(STOP);
+	printf("%ld BF_set_key's in %.2f seconds\n",count,d);
+	a=((double)COUNT(ca))/d;
+
+#ifdef SIGALRM
+	printf("Doing BF_encrypt's for 10 seconds\n");
+	alarm(10);
+#else
+	printf("Doing BF_encrypt %ld times\n",cb);
+#endif
+	Time_F(START);
+	for (count=0,run=1; COND(cb); count+=4)
+		{
+		BF_LONG data[2];
+
+		BF_encrypt(data,&sch);
+		BF_encrypt(data,&sch);
+		BF_encrypt(data,&sch);
+		BF_encrypt(data,&sch);
+		}
+	d=Time_F(STOP);
+	printf("%ld BF_encrypt's in %.2f second\n",count,d);
+	b=((double)COUNT(cb)*8)/d;
+
+#ifdef SIGALRM
+	printf("Doing BF_cbc_encrypt on %ld byte blocks for 10 seconds\n",
+		BUFSIZE);
+	alarm(10);
+#else
+	printf("Doing BF_cbc_encrypt %ld times on %ld byte blocks\n",cc,
+		BUFSIZE);
+#endif
+	Time_F(START);
+	for (count=0,run=1; COND(cc); count++)
+		BF_cbc_encrypt(buf,buf,BUFSIZE,&sch,
+			&(key[0]),BF_ENCRYPT);
+	d=Time_F(STOP);
+	printf("%ld BF_cbc_encrypt's of %ld byte blocks in %.2f second\n",
+		count,BUFSIZE,d);
+	c=((double)COUNT(cc)*BUFSIZE)/d;
+
+	printf("Blowfish set_key       per sec = %12.3f (%9.3fuS)\n",a,1.0e6/a);
+	printf("Blowfish raw ecb bytes per sec = %12.3f (%9.3fuS)\n",b,8.0e6/b);
+	printf("Blowfish cbc     bytes per sec = %12.3f (%9.3fuS)\n",c,8.0e6/c);
+	exit(0);
+#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
+	return(0);
+#endif
+	}
diff --git a/openssl/crypto/bf/bftest.c b/openssl/crypto/bf/bftest.c
new file mode 100644
index 0000000..97e6634
--- /dev/null
+++ b/openssl/crypto/bf/bftest.c
@@ -0,0 +1,540 @@
+/* crypto/bf/bftest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* This has been a quickly hacked 'ideatest.c'.  When I add tests for other
+ * RC2 modes, more of the code will be uncommented. */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_BF is defined */
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_BF
+int main(int argc, char *argv[])
+{
+    printf("No BF support\n");
+    return(0);
+}
+#else
+#include <openssl/blowfish.h>
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+static char *bf_key[2]={
+	"abcdefghijklmnopqrstuvwxyz",
+	"Who is John Galt?"
+	};
+
+/* big endian */
+static BF_LONG bf_plain[2][2]={
+	{0x424c4f57L,0x46495348L},
+	{0xfedcba98L,0x76543210L}
+	};
+
+static BF_LONG bf_cipher[2][2]={
+	{0x324ed0feL,0xf413a203L},
+	{0xcc91732bL,0x8022f684L}
+	};
+/************/
+
+/* Lets use the DES test vectors :-) */
+#define NUM_TESTS 34
+static unsigned char ecb_data[NUM_TESTS][8]={
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+	{0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10},
+	{0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57},
+	{0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E},
+	{0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86},
+	{0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E},
+	{0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6},
+	{0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE},
+	{0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6},
+	{0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE},
+	{0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16},
+	{0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F},
+	{0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46},
+	{0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E},
+	{0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76},
+	{0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07},
+	{0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F},
+	{0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7},
+	{0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF},
+	{0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6},
+	{0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF},
+	{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
+	{0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
+	{0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}};
+
+static unsigned char plain_data[NUM_TESTS][8]={
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+	{0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
+	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42},
+	{0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA},
+	{0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72},
+	{0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A},
+	{0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2},
+	{0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A},
+	{0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2},
+	{0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A},
+	{0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02},
+	{0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A},
+	{0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32},
+	{0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA},
+	{0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62},
+	{0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2},
+	{0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA},
+	{0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92},
+	{0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A},
+	{0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2},
+	{0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
+
+static unsigned char cipher_data[NUM_TESTS][8]={
+	{0x4E,0xF9,0x97,0x45,0x61,0x98,0xDD,0x78},
+	{0x51,0x86,0x6F,0xD5,0xB8,0x5E,0xCB,0x8A},
+	{0x7D,0x85,0x6F,0x9A,0x61,0x30,0x63,0xF2},
+	{0x24,0x66,0xDD,0x87,0x8B,0x96,0x3C,0x9D},
+	{0x61,0xF9,0xC3,0x80,0x22,0x81,0xB0,0x96},
+	{0x7D,0x0C,0xC6,0x30,0xAF,0xDA,0x1E,0xC7},
+	{0x4E,0xF9,0x97,0x45,0x61,0x98,0xDD,0x78},
+	{0x0A,0xCE,0xAB,0x0F,0xC6,0xA0,0xA2,0x8D},
+	{0x59,0xC6,0x82,0x45,0xEB,0x05,0x28,0x2B},
+	{0xB1,0xB8,0xCC,0x0B,0x25,0x0F,0x09,0xA0},
+	{0x17,0x30,0xE5,0x77,0x8B,0xEA,0x1D,0xA4},
+	{0xA2,0x5E,0x78,0x56,0xCF,0x26,0x51,0xEB},
+	{0x35,0x38,0x82,0xB1,0x09,0xCE,0x8F,0x1A},
+	{0x48,0xF4,0xD0,0x88,0x4C,0x37,0x99,0x18},
+	{0x43,0x21,0x93,0xB7,0x89,0x51,0xFC,0x98},
+	{0x13,0xF0,0x41,0x54,0xD6,0x9D,0x1A,0xE5},
+	{0x2E,0xED,0xDA,0x93,0xFF,0xD3,0x9C,0x79},
+	{0xD8,0x87,0xE0,0x39,0x3C,0x2D,0xA6,0xE3},
+	{0x5F,0x99,0xD0,0x4F,0x5B,0x16,0x39,0x69},
+	{0x4A,0x05,0x7A,0x3B,0x24,0xD3,0x97,0x7B},
+	{0x45,0x20,0x31,0xC1,0xE4,0xFA,0xDA,0x8E},
+	{0x75,0x55,0xAE,0x39,0xF5,0x9B,0x87,0xBD},
+	{0x53,0xC5,0x5F,0x9C,0xB4,0x9F,0xC0,0x19},
+	{0x7A,0x8E,0x7B,0xFA,0x93,0x7E,0x89,0xA3},
+	{0xCF,0x9C,0x5D,0x7A,0x49,0x86,0xAD,0xB5},
+	{0xD1,0xAB,0xB2,0x90,0x65,0x8B,0xC7,0x78},
+	{0x55,0xCB,0x37,0x74,0xD1,0x3E,0xF2,0x01},
+	{0xFA,0x34,0xEC,0x48,0x47,0xB2,0x68,0xB2},
+	{0xA7,0x90,0x79,0x51,0x08,0xEA,0x3C,0xAE},
+	{0xC3,0x9E,0x07,0x2D,0x9F,0xAC,0x63,0x1D},
+	{0x01,0x49,0x33,0xE0,0xCD,0xAF,0xF6,0xE4},
+	{0xF2,0x1E,0x9A,0x77,0xB7,0x1C,0x49,0xBC},
+	{0x24,0x59,0x46,0x88,0x57,0x54,0x36,0x9A},
+	{0x6B,0x5C,0x5A,0x9C,0x5D,0x9E,0x0A,0x5A},
+	};
+
+static unsigned char cbc_key [16]={
+	0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
+	0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87};
+static unsigned char cbc_iv [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
+static char cbc_data[40]="7654321 Now is the time for ";
+static unsigned char cbc_ok[32]={
+	0x6B,0x77,0xB4,0xD6,0x30,0x06,0xDE,0xE6,
+	0x05,0xB1,0x56,0xE2,0x74,0x03,0x97,0x93,
+	0x58,0xDE,0xB9,0xE7,0x15,0x46,0x16,0xD9,
+	0x59,0xF1,0x65,0x2B,0xD5,0xFF,0x92,0xCC};
+
+static unsigned char cfb64_ok[]={
+	0xE7,0x32,0x14,0xA2,0x82,0x21,0x39,0xCA,
+	0xF2,0x6E,0xCF,0x6D,0x2E,0xB9,0xE7,0x6E,
+	0x3D,0xA3,0xDE,0x04,0xD1,0x51,0x72,0x00,
+	0x51,0x9D,0x57,0xA6,0xC3};
+
+static unsigned char ofb64_ok[]={
+	0xE7,0x32,0x14,0xA2,0x82,0x21,0x39,0xCA,
+	0x62,0xB3,0x43,0xCC,0x5B,0x65,0x58,0x73,
+	0x10,0xDD,0x90,0x8D,0x0C,0x24,0x1B,0x22,
+	0x63,0xC2,0xCF,0x80,0xDA};
+
+#define KEY_TEST_NUM	25
+static unsigned char key_test[KEY_TEST_NUM]={
+	0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87,
+	0x78,0x69,0x5a,0x4b,0x3c,0x2d,0x1e,0x0f,
+	0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
+	0x88};
+
+static unsigned char key_data[8]=
+	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10};
+
+static unsigned char key_out[KEY_TEST_NUM][8]={
+	{0xF9,0xAD,0x59,0x7C,0x49,0xDB,0x00,0x5E},
+	{0xE9,0x1D,0x21,0xC1,0xD9,0x61,0xA6,0xD6},
+	{0xE9,0xC2,0xB7,0x0A,0x1B,0xC6,0x5C,0xF3},
+	{0xBE,0x1E,0x63,0x94,0x08,0x64,0x0F,0x05},
+	{0xB3,0x9E,0x44,0x48,0x1B,0xDB,0x1E,0x6E},
+	{0x94,0x57,0xAA,0x83,0xB1,0x92,0x8C,0x0D},
+	{0x8B,0xB7,0x70,0x32,0xF9,0x60,0x62,0x9D},
+	{0xE8,0x7A,0x24,0x4E,0x2C,0xC8,0x5E,0x82},
+	{0x15,0x75,0x0E,0x7A,0x4F,0x4E,0xC5,0x77},
+	{0x12,0x2B,0xA7,0x0B,0x3A,0xB6,0x4A,0xE0},
+	{0x3A,0x83,0x3C,0x9A,0xFF,0xC5,0x37,0xF6},
+	{0x94,0x09,0xDA,0x87,0xA9,0x0F,0x6B,0xF2},
+	{0x88,0x4F,0x80,0x62,0x50,0x60,0xB8,0xB4},
+	{0x1F,0x85,0x03,0x1C,0x19,0xE1,0x19,0x68},
+	{0x79,0xD9,0x37,0x3A,0x71,0x4C,0xA3,0x4F},
+	{0x93,0x14,0x28,0x87,0xEE,0x3B,0xE1,0x5C},
+	{0x03,0x42,0x9E,0x83,0x8C,0xE2,0xD1,0x4B},
+	{0xA4,0x29,0x9E,0x27,0x46,0x9F,0xF6,0x7B},
+	{0xAF,0xD5,0xAE,0xD1,0xC1,0xBC,0x96,0xA8},
+	{0x10,0x85,0x1C,0x0E,0x38,0x58,0xDA,0x9F},
+	{0xE6,0xF5,0x1E,0xD7,0x9B,0x9D,0xB2,0x1F},
+	{0x64,0xA6,0xE1,0x4A,0xFD,0x36,0xB4,0x6F},
+	{0x80,0xC7,0xD7,0xD4,0x5A,0x54,0x79,0xAD},
+	{0x05,0x04,0x4B,0x62,0xFA,0x52,0xD0,0x80},
+	};
+
+static int test(void );
+static int print_test_data(void );
+int main(int argc, char *argv[])
+	{
+	int ret;
+
+	if (argc > 1)
+		ret=print_test_data();
+	else
+		ret=test();
+
+#ifdef OPENSSL_SYS_NETWARE
+    if (ret) printf("ERROR: %d\n", ret);
+#endif
+	EXIT(ret);
+	return(0);
+	}
+
+static int print_test_data(void)
+	{
+	unsigned int i,j;
+
+	printf("ecb test data\n");
+	printf("key bytes\t\tclear bytes\t\tcipher bytes\n");
+	for (i=0; i<NUM_TESTS; i++)
+		{
+		for (j=0; j<8; j++)
+			printf("%02X",ecb_data[i][j]);
+		printf("\t");
+		for (j=0; j<8; j++)
+			printf("%02X",plain_data[i][j]);
+		printf("\t");
+		for (j=0; j<8; j++)
+			printf("%02X",cipher_data[i][j]);
+		printf("\n");
+		}
+
+	printf("set_key test data\n");
+	printf("data[8]= ");
+	for (j=0; j<8; j++)
+		printf("%02X",key_data[j]);
+	printf("\n");
+	for (i=0; i<KEY_TEST_NUM-1; i++)
+		{
+		printf("c=");
+		for (j=0; j<8; j++)
+			printf("%02X",key_out[i][j]);
+		printf(" k[%2u]=",i+1);
+		for (j=0; j<i+1; j++)
+			printf("%02X",key_test[j]);
+		printf("\n");
+		}
+
+	printf("\nchaining mode test data\n");
+	printf("key[16]   = ");
+	for (j=0; j<16; j++)
+		printf("%02X",cbc_key[j]);
+	printf("\niv[8]     = ");
+	for (j=0; j<8; j++)
+		printf("%02X",cbc_iv[j]);
+	printf("\ndata[%d]  = '%s'",(int)strlen(cbc_data)+1,cbc_data);
+	printf("\ndata[%d]  = ",(int)strlen(cbc_data)+1);
+	for (j=0; j<strlen(cbc_data)+1; j++)
+		printf("%02X",cbc_data[j]);
+	printf("\n");
+	printf("cbc cipher text\n");
+	printf("cipher[%d]= ",32);
+	for (j=0; j<32; j++)
+		printf("%02X",cbc_ok[j]);
+	printf("\n");
+
+	printf("cfb64 cipher text\n");
+	printf("cipher[%d]= ",(int)strlen(cbc_data)+1);
+	for (j=0; j<strlen(cbc_data)+1; j++)
+		printf("%02X",cfb64_ok[j]);
+	printf("\n");
+
+	printf("ofb64 cipher text\n");
+	printf("cipher[%d]= ",(int)strlen(cbc_data)+1);
+	for (j=0; j<strlen(cbc_data)+1; j++)
+		printf("%02X",ofb64_ok[j]);
+	printf("\n");
+	return(0);
+	}
+
+static int test(void)
+	{
+	unsigned char cbc_in[40],cbc_out[40],iv[8];
+	int i,n,err=0;
+	BF_KEY key;
+	BF_LONG data[2]; 
+	unsigned char out[8]; 
+	BF_LONG len;
+
+#ifdef CHARSET_EBCDIC
+	ebcdic2ascii(cbc_data, cbc_data, strlen(cbc_data));
+#endif
+
+	printf("testing blowfish in raw ecb mode\n");
+	for (n=0; n<2; n++)
+		{
+#ifdef CHARSET_EBCDIC
+		ebcdic2ascii(bf_key[n], bf_key[n], strlen(bf_key[n]));
+#endif
+		BF_set_key(&key,strlen(bf_key[n]),(unsigned char *)bf_key[n]);
+
+		data[0]=bf_plain[n][0];
+		data[1]=bf_plain[n][1];
+		BF_encrypt(data,&key);
+		if (memcmp(&(bf_cipher[n][0]),&(data[0]),8) != 0)
+			{
+			printf("BF_encrypt error encrypting\n");
+			printf("got     :");
+			for (i=0; i<2; i++)
+				printf("%08lX ",(unsigned long)data[i]);
+			printf("\n");
+			printf("expected:");
+			for (i=0; i<2; i++)
+				printf("%08lX ",(unsigned long)bf_cipher[n][i]);
+			err=1;
+			printf("\n");
+			}
+
+		BF_decrypt(&(data[0]),&key);
+		if (memcmp(&(bf_plain[n][0]),&(data[0]),8) != 0)
+			{
+			printf("BF_encrypt error decrypting\n");
+			printf("got     :");
+			for (i=0; i<2; i++)
+				printf("%08lX ",(unsigned long)data[i]);
+			printf("\n");
+			printf("expected:");
+			for (i=0; i<2; i++)
+				printf("%08lX ",(unsigned long)bf_plain[n][i]);
+			printf("\n");
+			err=1;
+			}
+		}
+
+	printf("testing blowfish in ecb mode\n");
+
+	for (n=0; n<NUM_TESTS; n++)
+		{
+		BF_set_key(&key,8,ecb_data[n]);
+
+		BF_ecb_encrypt(&(plain_data[n][0]),out,&key,BF_ENCRYPT);
+		if (memcmp(&(cipher_data[n][0]),out,8) != 0)
+			{
+			printf("BF_ecb_encrypt blowfish error encrypting\n");
+			printf("got     :");
+			for (i=0; i<8; i++)
+				printf("%02X ",out[i]);
+			printf("\n");
+			printf("expected:");
+			for (i=0; i<8; i++)
+				printf("%02X ",cipher_data[n][i]);
+			err=1;
+			printf("\n");
+			}
+
+		BF_ecb_encrypt(out,out,&key,BF_DECRYPT);
+		if (memcmp(&(plain_data[n][0]),out,8) != 0)
+			{
+			printf("BF_ecb_encrypt error decrypting\n");
+			printf("got     :");
+			for (i=0; i<8; i++)
+				printf("%02X ",out[i]);
+			printf("\n");
+			printf("expected:");
+			for (i=0; i<8; i++)
+				printf("%02X ",plain_data[n][i]);
+			printf("\n");
+			err=1;
+			}
+		}
+
+	printf("testing blowfish set_key\n");
+	for (n=1; n<KEY_TEST_NUM; n++)
+		{
+		BF_set_key(&key,n,key_test);
+		BF_ecb_encrypt(key_data,out,&key,BF_ENCRYPT);
+		/* mips-sgi-irix6.5-gcc  vv  -mabi=64 bug workaround */
+		if (memcmp(out,&(key_out[i=n-1][0]),8) != 0)
+			{
+			printf("blowfish setkey error\n");
+			err=1;
+			}
+		}
+
+	printf("testing blowfish in cbc mode\n");
+	len=strlen(cbc_data)+1;
+
+	BF_set_key(&key,16,cbc_key);
+	memset(cbc_in,0,sizeof cbc_in);
+	memset(cbc_out,0,sizeof cbc_out);
+	memcpy(iv,cbc_iv,sizeof iv);
+	BF_cbc_encrypt((unsigned char *)cbc_data,cbc_out,len,
+		&key,iv,BF_ENCRYPT);
+	if (memcmp(cbc_out,cbc_ok,32) != 0)
+		{
+		err=1;
+		printf("BF_cbc_encrypt encrypt error\n");
+		for (i=0; i<32; i++) printf("0x%02X,",cbc_out[i]);
+		}
+	memcpy(iv,cbc_iv,8);
+	BF_cbc_encrypt(cbc_out,cbc_in,len,
+		&key,iv,BF_DECRYPT);
+	if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0)
+		{
+		printf("BF_cbc_encrypt decrypt error\n");
+		err=1;
+		}
+
+	printf("testing blowfish in cfb64 mode\n");
+
+	BF_set_key(&key,16,cbc_key);
+	memset(cbc_in,0,40);
+	memset(cbc_out,0,40);
+	memcpy(iv,cbc_iv,8);
+	n=0;
+	BF_cfb64_encrypt((unsigned char *)cbc_data,cbc_out,(long)13,
+		&key,iv,&n,BF_ENCRYPT);
+	BF_cfb64_encrypt((unsigned char *)&(cbc_data[13]),&(cbc_out[13]),len-13,
+		&key,iv,&n,BF_ENCRYPT);
+	if (memcmp(cbc_out,cfb64_ok,(int)len) != 0)
+		{
+		err=1;
+		printf("BF_cfb64_encrypt encrypt error\n");
+		for (i=0; i<(int)len; i++) printf("0x%02X,",cbc_out[i]);
+		}
+	n=0;
+	memcpy(iv,cbc_iv,8);
+	BF_cfb64_encrypt(cbc_out,cbc_in,17,
+		&key,iv,&n,BF_DECRYPT);
+	BF_cfb64_encrypt(&(cbc_out[17]),&(cbc_in[17]),len-17,
+		&key,iv,&n,BF_DECRYPT);
+	if (memcmp(cbc_in,cbc_data,(int)len) != 0)
+		{
+		printf("BF_cfb64_encrypt decrypt error\n");
+		err=1;
+		}
+
+	printf("testing blowfish in ofb64\n");
+
+	BF_set_key(&key,16,cbc_key);
+	memset(cbc_in,0,40);
+	memset(cbc_out,0,40);
+	memcpy(iv,cbc_iv,8);
+	n=0;
+	BF_ofb64_encrypt((unsigned char *)cbc_data,cbc_out,(long)13,&key,iv,&n);
+	BF_ofb64_encrypt((unsigned char *)&(cbc_data[13]),
+		&(cbc_out[13]),len-13,&key,iv,&n);
+	if (memcmp(cbc_out,ofb64_ok,(int)len) != 0)
+		{
+		err=1;
+		printf("BF_ofb64_encrypt encrypt error\n");
+		for (i=0; i<(int)len; i++) printf("0x%02X,",cbc_out[i]);
+		}
+	n=0;
+	memcpy(iv,cbc_iv,8);
+	BF_ofb64_encrypt(cbc_out,cbc_in,17,&key,iv,&n);
+	BF_ofb64_encrypt(&(cbc_out[17]),&(cbc_in[17]),len-17,&key,iv,&n);
+	if (memcmp(cbc_in,cbc_data,(int)len) != 0)
+		{
+		printf("BF_ofb64_encrypt decrypt error\n");
+		err=1;
+		}
+
+	return(err);
+	}
+#endif
diff --git a/openssl/crypto/bf/blowfish.h b/openssl/crypto/bf/blowfish.h
new file mode 100644
index 0000000..b97e76f
--- /dev/null
+++ b/openssl/crypto/bf/blowfish.h
@@ -0,0 +1,127 @@
+/* crypto/bf/blowfish.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BLOWFISH_H
+#define HEADER_BLOWFISH_H
+
+#include <openssl/e_os2.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_BF
+#error BF is disabled.
+#endif
+
+#define BF_ENCRYPT	1
+#define BF_DECRYPT	0
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! BF_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! BF_LONG_LOG2 has to be defined along.                        !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#if defined(__LP32__)
+#define BF_LONG unsigned long
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#define BF_LONG unsigned long
+#define BF_LONG_LOG2 3
+/*
+ * _CRAY note. I could declare short, but I have no idea what impact
+ * does it have on performance on none-T3E machines. I could declare
+ * int, but at least on C90 sizeof(int) can be chosen at compile time.
+ * So I've chosen long...
+ *					<appro@fy.chalmers.se>
+ */
+#else
+#define BF_LONG unsigned int
+#endif
+
+#define BF_ROUNDS	16
+#define BF_BLOCK	8
+
+typedef struct bf_key_st
+	{
+	BF_LONG P[BF_ROUNDS+2];
+	BF_LONG S[4*256];
+	} BF_KEY;
+
+ 
+void BF_set_key(BF_KEY *key, int len, const unsigned char *data);
+
+void BF_encrypt(BF_LONG *data,const BF_KEY *key);
+void BF_decrypt(BF_LONG *data,const BF_KEY *key);
+
+void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
+	const BF_KEY *key, int enc);
+void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+	const BF_KEY *schedule, unsigned char *ivec, int enc);
+void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, long length,
+	const BF_KEY *schedule, unsigned char *ivec, int *num, int enc);
+void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, long length,
+	const BF_KEY *schedule, unsigned char *ivec, int *num);
+const char *BF_options(void);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/bio/Makefile b/openssl/crypto/bio/Makefile
new file mode 100644
index 0000000..c395d80
--- /dev/null
+++ b/openssl/crypto/bio/Makefile
@@ -0,0 +1,222 @@
+#
+# OpenSSL/crypto/bio/Makefile
+#
+
+DIR=	bio
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= bio_lib.c bio_cb.c bio_err.c \
+	bss_mem.c bss_null.c bss_fd.c \
+	bss_file.c bss_sock.c bss_conn.c \
+	bf_null.c bf_buff.c b_print.c b_dump.c \
+	b_sock.c bss_acpt.c bf_nbio.c bss_log.c bss_bio.c \
+	bss_dgram.c
+#	bf_lbuf.c
+LIBOBJ= bio_lib.o bio_cb.o bio_err.o \
+	bss_mem.o bss_null.o bss_fd.o \
+	bss_file.o bss_sock.o bss_conn.o \
+	bf_null.o bf_buff.o b_print.o b_dump.o \
+	b_sock.o bss_acpt.o bf_nbio.o bss_log.o bss_bio.o \
+	bss_dgram.o
+#	bf_lbuf.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= bio.h
+HEADER=	bio_lcl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+b_dump.o: ../../e_os.h ../../include/openssl/bio.h
+b_dump.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+b_dump.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+b_dump.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+b_dump.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+b_dump.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+b_dump.o: ../../include/openssl/symhacks.h ../cryptlib.h b_dump.c bio_lcl.h
+b_print.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+b_print.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+b_print.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+b_print.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+b_print.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+b_print.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+b_print.o: ../../include/openssl/symhacks.h ../cryptlib.h b_print.c
+b_sock.o: ../../e_os.h ../../include/openssl/bio.h
+b_sock.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+b_sock.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+b_sock.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+b_sock.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+b_sock.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+b_sock.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+b_sock.o: ../cryptlib.h b_sock.c
+bf_buff.o: ../../e_os.h ../../include/openssl/bio.h
+bf_buff.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bf_buff.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bf_buff.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bf_buff.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bf_buff.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bf_buff.o: ../../include/openssl/symhacks.h ../cryptlib.h bf_buff.c
+bf_nbio.o: ../../e_os.h ../../include/openssl/bio.h
+bf_nbio.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bf_nbio.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bf_nbio.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bf_nbio.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bf_nbio.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+bf_nbio.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+bf_nbio.o: ../cryptlib.h bf_nbio.c
+bf_null.o: ../../e_os.h ../../include/openssl/bio.h
+bf_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bf_null.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bf_null.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bf_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bf_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bf_null.o: ../../include/openssl/symhacks.h ../cryptlib.h bf_null.c
+bio_cb.o: ../../e_os.h ../../include/openssl/bio.h
+bio_cb.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bio_cb.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bio_cb.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bio_cb.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bio_cb.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bio_cb.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_cb.c
+bio_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+bio_err.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bio_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bio_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bio_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bio_err.o: ../../include/openssl/symhacks.h bio_err.c
+bio_lib.o: ../../e_os.h ../../include/openssl/bio.h
+bio_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bio_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bio_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bio_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bio_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bio_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_lib.c
+bss_acpt.o: ../../e_os.h ../../include/openssl/bio.h
+bss_acpt.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bss_acpt.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bss_acpt.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bss_acpt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bss_acpt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bss_acpt.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_acpt.c
+bss_bio.o: ../../e_os.h ../../include/openssl/bio.h
+bss_bio.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+bss_bio.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+bss_bio.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+bss_bio.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+bss_bio.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+bss_bio.o: bss_bio.c
+bss_conn.o: ../../e_os.h ../../include/openssl/bio.h
+bss_conn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bss_conn.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bss_conn.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bss_conn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bss_conn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bss_conn.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_conn.c
+bss_dgram.o: ../../e_os.h ../../include/openssl/bio.h
+bss_dgram.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bss_dgram.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bss_dgram.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bss_dgram.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bss_dgram.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bss_dgram.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_dgram.c
+bss_fd.o: ../../e_os.h ../../include/openssl/bio.h
+bss_fd.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bss_fd.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bss_fd.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bss_fd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bss_fd.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bss_fd.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_lcl.h bss_fd.c
+bss_file.o: ../../e_os.h ../../include/openssl/bio.h
+bss_file.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bss_file.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bss_file.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bss_file.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bss_file.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bss_file.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_lcl.h bss_file.c
+bss_log.o: ../../e_os.h ../../include/openssl/bio.h
+bss_log.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bss_log.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bss_log.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bss_log.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bss_log.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bss_log.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_log.c
+bss_mem.o: ../../e_os.h ../../include/openssl/bio.h
+bss_mem.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bss_mem.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bss_mem.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bss_mem.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bss_mem.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bss_mem.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_mem.c
+bss_null.o: ../../e_os.h ../../include/openssl/bio.h
+bss_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bss_null.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bss_null.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bss_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bss_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bss_null.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_null.c
+bss_sock.o: ../../e_os.h ../../include/openssl/bio.h
+bss_sock.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bss_sock.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bss_sock.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bss_sock.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bss_sock.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bss_sock.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_sock.c
diff --git a/openssl/crypto/bio/b_dump.c b/openssl/crypto/bio/b_dump.c
new file mode 100644
index 0000000..c80ecc4
--- /dev/null
+++ b/openssl/crypto/bio/b_dump.c
@@ -0,0 +1,187 @@
+/* crypto/bio/b_dump.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* 
+ * Stolen from tjh's ssl/ssl_trc.c stuff.
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bio_lcl.h"
+
+#define TRUNCATE
+#define DUMP_WIDTH	16
+#define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH-((i-(i>6?6:i)+3)/4))
+
+int BIO_dump_cb(int (*cb)(const void *data, size_t len, void *u),
+	void *u, const char *s, int len)
+	{
+	return BIO_dump_indent_cb(cb, u, s, len, 0);
+	}
+
+int BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u),
+	void *u, const char *s, int len, int indent)
+	{
+	int ret=0;
+	char buf[288+1],tmp[20],str[128+1];
+	int i,j,rows,trc;
+	unsigned char ch;
+	int dump_width;
+
+	trc=0;
+
+#ifdef TRUNCATE
+	for(; (len > 0) && ((s[len-1] == ' ') || (s[len-1] == '\0')); len--)
+		trc++;
+#endif
+
+	if (indent < 0)
+		indent = 0;
+	if (indent)
+		{
+		if (indent > 128) indent=128;
+		memset(str,' ',indent);
+		}
+	str[indent]='\0';
+
+	dump_width=DUMP_WIDTH_LESS_INDENT(indent);
+	rows=(len/dump_width);
+	if ((rows*dump_width)<len)
+		rows++;
+	for(i=0;i<rows;i++)
+		{
+		buf[0]='\0';	/* start with empty string */
+		BUF_strlcpy(buf,str,sizeof buf);
+		BIO_snprintf(tmp,sizeof tmp,"%04x - ",i*dump_width);
+		BUF_strlcat(buf,tmp,sizeof buf);
+		for(j=0;j<dump_width;j++)
+			{
+			if (((i*dump_width)+j)>=len)
+				{
+				BUF_strlcat(buf,"   ",sizeof buf);
+				}
+			else
+				{
+				ch=((unsigned char)*(s+i*dump_width+j)) & 0xff;
+				BIO_snprintf(tmp,sizeof tmp,"%02x%c",ch,
+					j==7?'-':' ');
+				BUF_strlcat(buf,tmp,sizeof buf);
+				}
+			}
+		BUF_strlcat(buf,"  ",sizeof buf);
+		for(j=0;j<dump_width;j++)
+			{
+			if (((i*dump_width)+j)>=len)
+				break;
+			ch=((unsigned char)*(s+i*dump_width+j)) & 0xff;
+#ifndef CHARSET_EBCDIC
+			BIO_snprintf(tmp,sizeof tmp,"%c",
+				((ch>=' ')&&(ch<='~'))?ch:'.');
+#else
+			BIO_snprintf(tmp,sizeof tmp,"%c",
+				((ch>=os_toascii[' '])&&(ch<=os_toascii['~']))
+				? os_toebcdic[ch]
+				: '.');
+#endif
+			BUF_strlcat(buf,tmp,sizeof buf);
+			}
+		BUF_strlcat(buf,"\n",sizeof buf);
+		/* if this is the last call then update the ddt_dump thing so
+		 * that we will move the selection point in the debug window
+		 */
+		ret+=cb((void *)buf,strlen(buf),u);
+		}
+#ifdef TRUNCATE
+	if (trc > 0)
+		{
+		BIO_snprintf(buf,sizeof buf,"%s%04x - <SPACES/NULS>\n",str,
+			len+trc);
+		ret+=cb((void *)buf,strlen(buf),u);
+		}
+#endif
+	return(ret);
+	}
+
+#ifndef OPENSSL_NO_FP_API
+static int write_fp(const void *data, size_t len, void *fp)
+	{
+	return UP_fwrite(data, len, 1, fp);
+	}
+int BIO_dump_fp(FILE *fp, const char *s, int len)
+	{
+	return BIO_dump_cb(write_fp, fp, s, len);
+	}
+int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent)
+	{
+	return BIO_dump_indent_cb(write_fp, fp, s, len, indent);
+	}
+#endif
+
+static int write_bio(const void *data, size_t len, void *bp)
+	{
+	return BIO_write((BIO *)bp, (const char *)data, len);
+	}
+int BIO_dump(BIO *bp, const char *s, int len)
+	{
+	return BIO_dump_cb(write_bio, bp, s, len);
+	}
+int BIO_dump_indent(BIO *bp, const char *s, int len, int indent)
+	{
+	return BIO_dump_indent_cb(write_bio, bp, s, len, indent);
+	}
+
diff --git a/openssl/crypto/bio/b_print.c b/openssl/crypto/bio/b_print.c
new file mode 100644
index 0000000..143a7cf
--- /dev/null
+++ b/openssl/crypto/bio/b_print.c
@@ -0,0 +1,842 @@
+/* crypto/bio/b_print.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* disable assert() unless BIO_DEBUG has been defined */
+#ifndef BIO_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+
+/* 
+ * Stolen from tjh's ssl/ssl_trc.c stuff.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <limits.h>
+#include "cryptlib.h"
+#ifndef NO_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <openssl/bn.h>         /* To get BN_LLONG properly defined */
+#include <openssl/bio.h>
+
+#if defined(BN_LLONG) || defined(SIXTY_FOUR_BIT)
+# ifndef HAVE_LONG_LONG
+#  define HAVE_LONG_LONG 1
+# endif
+#endif
+
+/***************************************************************************/
+
+/*
+ * Copyright Patrick Powell 1995
+ * This code is based on code written by Patrick Powell <papowell@astart.com>
+ * It may be used for any purpose as long as this notice remains intact
+ * on all source code distributions.
+ */
+
+/*
+ * This code contains numerious changes and enhancements which were
+ * made by lots of contributors over the last years to Patrick Powell's
+ * original code:
+ *
+ * o Patrick Powell <papowell@astart.com>      (1995)
+ * o Brandon Long <blong@fiction.net>          (1996, for Mutt)
+ * o Thomas Roessler <roessler@guug.de>        (1998, for Mutt)
+ * o Michael Elkins <me@cs.hmc.edu>            (1998, for Mutt)
+ * o Andrew Tridgell <tridge@samba.org>        (1998, for Samba)
+ * o Luke Mewburn <lukem@netbsd.org>           (1999, for LukemFTP)
+ * o Ralf S. Engelschall <rse@engelschall.com> (1999, for Pth)
+ * o ...                                       (for OpenSSL)
+ */
+
+#ifdef HAVE_LONG_DOUBLE
+#define LDOUBLE long double
+#else
+#define LDOUBLE double
+#endif
+
+#ifdef HAVE_LONG_LONG
+# if defined(_WIN32) && !defined(__GNUC__)
+# define LLONG __int64
+# else
+# define LLONG long long
+# endif
+#else
+#define LLONG long
+#endif
+
+static void fmtstr     (char **, char **, size_t *, size_t *,
+			const char *, int, int, int);
+static void fmtint     (char **, char **, size_t *, size_t *,
+			LLONG, int, int, int, int);
+static void fmtfp      (char **, char **, size_t *, size_t *,
+			LDOUBLE, int, int, int);
+static void doapr_outch (char **, char **, size_t *, size_t *, int);
+static void _dopr(char **sbuffer, char **buffer,
+		  size_t *maxlen, size_t *retlen, int *truncated,
+		  const char *format, va_list args);
+
+/* format read states */
+#define DP_S_DEFAULT    0
+#define DP_S_FLAGS      1
+#define DP_S_MIN        2
+#define DP_S_DOT        3
+#define DP_S_MAX        4
+#define DP_S_MOD        5
+#define DP_S_CONV       6
+#define DP_S_DONE       7
+
+/* format flags - Bits */
+#define DP_F_MINUS      (1 << 0)
+#define DP_F_PLUS       (1 << 1)
+#define DP_F_SPACE      (1 << 2)
+#define DP_F_NUM        (1 << 3)
+#define DP_F_ZERO       (1 << 4)
+#define DP_F_UP         (1 << 5)
+#define DP_F_UNSIGNED   (1 << 6)
+
+/* conversion flags */
+#define DP_C_SHORT      1
+#define DP_C_LONG       2
+#define DP_C_LDOUBLE    3
+#define DP_C_LLONG      4
+
+/* some handy macros */
+#define char_to_int(p) (p - '0')
+#define OSSL_MAX(p,q) ((p >= q) ? p : q)
+
+static void
+_dopr(
+    char **sbuffer,
+    char **buffer,
+    size_t *maxlen,
+    size_t *retlen,
+    int *truncated,
+    const char *format,
+    va_list args)
+{
+    char ch;
+    LLONG value;
+    LDOUBLE fvalue;
+    char *strvalue;
+    int min;
+    int max;
+    int state;
+    int flags;
+    int cflags;
+    size_t currlen;
+
+    state = DP_S_DEFAULT;
+    flags = currlen = cflags = min = 0;
+    max = -1;
+    ch = *format++;
+
+    while (state != DP_S_DONE) {
+        if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
+            state = DP_S_DONE;
+
+        switch (state) {
+        case DP_S_DEFAULT:
+            if (ch == '%')
+                state = DP_S_FLAGS;
+            else
+                doapr_outch(sbuffer,buffer, &currlen, maxlen, ch);
+            ch = *format++;
+            break;
+        case DP_S_FLAGS:
+            switch (ch) {
+            case '-':
+                flags |= DP_F_MINUS;
+                ch = *format++;
+                break;
+            case '+':
+                flags |= DP_F_PLUS;
+                ch = *format++;
+                break;
+            case ' ':
+                flags |= DP_F_SPACE;
+                ch = *format++;
+                break;
+            case '#':
+                flags |= DP_F_NUM;
+                ch = *format++;
+                break;
+            case '0':
+                flags |= DP_F_ZERO;
+                ch = *format++;
+                break;
+            default:
+                state = DP_S_MIN;
+                break;
+            }
+            break;
+        case DP_S_MIN:
+            if (isdigit((unsigned char)ch)) {
+                min = 10 * min + char_to_int(ch);
+                ch = *format++;
+            } else if (ch == '*') {
+                min = va_arg(args, int);
+                ch = *format++;
+                state = DP_S_DOT;
+            } else
+                state = DP_S_DOT;
+            break;
+        case DP_S_DOT:
+            if (ch == '.') {
+                state = DP_S_MAX;
+                ch = *format++;
+            } else
+                state = DP_S_MOD;
+            break;
+        case DP_S_MAX:
+            if (isdigit((unsigned char)ch)) {
+                if (max < 0)
+                    max = 0;
+                max = 10 * max + char_to_int(ch);
+                ch = *format++;
+            } else if (ch == '*') {
+                max = va_arg(args, int);
+                ch = *format++;
+                state = DP_S_MOD;
+            } else
+                state = DP_S_MOD;
+            break;
+        case DP_S_MOD:
+            switch (ch) {
+            case 'h':
+                cflags = DP_C_SHORT;
+                ch = *format++;
+                break;
+            case 'l':
+                if (*format == 'l') {
+                    cflags = DP_C_LLONG;
+                    format++;
+                } else
+                    cflags = DP_C_LONG;
+                ch = *format++;
+                break;
+            case 'q':
+                cflags = DP_C_LLONG;
+                ch = *format++;
+                break;
+            case 'L':
+                cflags = DP_C_LDOUBLE;
+                ch = *format++;
+                break;
+            default:
+                break;
+            }
+            state = DP_S_CONV;
+            break;
+        case DP_S_CONV:
+            switch (ch) {
+            case 'd':
+            case 'i':
+                switch (cflags) {
+                case DP_C_SHORT:
+                    value = (short int)va_arg(args, int);
+                    break;
+                case DP_C_LONG:
+                    value = va_arg(args, long int);
+                    break;
+                case DP_C_LLONG:
+                    value = va_arg(args, LLONG);
+                    break;
+                default:
+                    value = va_arg(args, int);
+                    break;
+                }
+                fmtint(sbuffer, buffer, &currlen, maxlen,
+                       value, 10, min, max, flags);
+                break;
+            case 'X':
+                flags |= DP_F_UP;
+                /* FALLTHROUGH */
+            case 'x':
+            case 'o':
+            case 'u':
+                flags |= DP_F_UNSIGNED;
+                switch (cflags) {
+                case DP_C_SHORT:
+                    value = (unsigned short int)va_arg(args, unsigned int);
+                    break;
+                case DP_C_LONG:
+                    value = (LLONG) va_arg(args,
+                        unsigned long int);
+                    break;
+                case DP_C_LLONG:
+                    value = va_arg(args, unsigned LLONG);
+                    break;
+                default:
+                    value = (LLONG) va_arg(args,
+                        unsigned int);
+                    break;
+                }
+                fmtint(sbuffer, buffer, &currlen, maxlen, value,
+                       ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
+                       min, max, flags);
+                break;
+            case 'f':
+                if (cflags == DP_C_LDOUBLE)
+                    fvalue = va_arg(args, LDOUBLE);
+                else
+                    fvalue = va_arg(args, double);
+                fmtfp(sbuffer, buffer, &currlen, maxlen,
+                      fvalue, min, max, flags);
+                break;
+            case 'E':
+                flags |= DP_F_UP;
+            case 'e':
+                if (cflags == DP_C_LDOUBLE)
+                    fvalue = va_arg(args, LDOUBLE);
+                else
+                    fvalue = va_arg(args, double);
+                break;
+            case 'G':
+                flags |= DP_F_UP;
+            case 'g':
+                if (cflags == DP_C_LDOUBLE)
+                    fvalue = va_arg(args, LDOUBLE);
+                else
+                    fvalue = va_arg(args, double);
+                break;
+            case 'c':
+                doapr_outch(sbuffer, buffer, &currlen, maxlen,
+                    va_arg(args, int));
+                break;
+            case 's':
+                strvalue = va_arg(args, char *);
+                if (max < 0) {
+		    if (buffer)
+			max = INT_MAX;
+		    else
+			max = *maxlen;
+		}
+                fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
+                       flags, min, max);
+                break;
+            case 'p':
+                value = (long)va_arg(args, void *);
+                fmtint(sbuffer, buffer, &currlen, maxlen,
+                    value, 16, min, max, flags|DP_F_NUM);
+                break;
+            case 'n': /* XXX */
+                if (cflags == DP_C_SHORT) {
+                    short int *num;
+                    num = va_arg(args, short int *);
+                    *num = currlen;
+                } else if (cflags == DP_C_LONG) { /* XXX */
+                    long int *num;
+                    num = va_arg(args, long int *);
+                    *num = (long int) currlen;
+                } else if (cflags == DP_C_LLONG) { /* XXX */
+                    LLONG *num;
+                    num = va_arg(args, LLONG *);
+                    *num = (LLONG) currlen;
+                } else {
+                    int    *num;
+                    num = va_arg(args, int *);
+                    *num = currlen;
+                }
+                break;
+            case '%':
+                doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
+                break;
+            case 'w':
+                /* not supported yet, treat as next char */
+                ch = *format++;
+                break;
+            default:
+                /* unknown, skip */
+                break;
+            }
+            ch = *format++;
+            state = DP_S_DEFAULT;
+            flags = cflags = min = 0;
+            max = -1;
+            break;
+        case DP_S_DONE:
+            break;
+        default:
+            break;
+        }
+    }
+    *truncated = (currlen > *maxlen - 1);
+    if (*truncated)
+        currlen = *maxlen - 1;
+    doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0');
+    *retlen = currlen - 1;
+    return;
+}
+
+static void
+fmtstr(
+    char **sbuffer,
+    char **buffer,
+    size_t *currlen,
+    size_t *maxlen,
+    const char *value,
+    int flags,
+    int min,
+    int max)
+{
+    int padlen, strln;
+    int cnt = 0;
+
+    if (value == 0)
+        value = "<NULL>";
+    for (strln = 0; value[strln]; ++strln)
+        ;
+    padlen = min - strln;
+    if (padlen < 0)
+        padlen = 0;
+    if (flags & DP_F_MINUS)
+        padlen = -padlen;
+
+    while ((padlen > 0) && (cnt < max)) {
+        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+        --padlen;
+        ++cnt;
+    }
+    while (*value && (cnt < max)) {
+        doapr_outch(sbuffer, buffer, currlen, maxlen, *value++);
+        ++cnt;
+    }
+    while ((padlen < 0) && (cnt < max)) {
+        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+        ++padlen;
+        ++cnt;
+    }
+}
+
+static void
+fmtint(
+    char **sbuffer,
+    char **buffer,
+    size_t *currlen,
+    size_t *maxlen,
+    LLONG value,
+    int base,
+    int min,
+    int max,
+    int flags)
+{
+    int signvalue = 0;
+    const char *prefix = "";
+    unsigned LLONG uvalue;
+    char convert[DECIMAL_SIZE(value)+3];
+    int place = 0;
+    int spadlen = 0;
+    int zpadlen = 0;
+    int caps = 0;
+
+    if (max < 0)
+        max = 0;
+    uvalue = value;
+    if (!(flags & DP_F_UNSIGNED)) {
+        if (value < 0) {
+            signvalue = '-';
+            uvalue = -value;
+        } else if (flags & DP_F_PLUS)
+            signvalue = '+';
+        else if (flags & DP_F_SPACE)
+            signvalue = ' ';
+    }
+    if (flags & DP_F_NUM) {
+	if (base == 8) prefix = "0";
+	if (base == 16) prefix = "0x";
+    }
+    if (flags & DP_F_UP)
+        caps = 1;
+    do {
+        convert[place++] =
+            (caps ? "0123456789ABCDEF" : "0123456789abcdef")
+            [uvalue % (unsigned) base];
+        uvalue = (uvalue / (unsigned) base);
+    } while (uvalue && (place < (int)sizeof(convert)));
+    if (place == sizeof(convert))
+        place--;
+    convert[place] = 0;
+
+    zpadlen = max - place;
+    spadlen = min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix);
+    if (zpadlen < 0)
+        zpadlen = 0;
+    if (spadlen < 0)
+        spadlen = 0;
+    if (flags & DP_F_ZERO) {
+        zpadlen = OSSL_MAX(zpadlen, spadlen);
+        spadlen = 0;
+    }
+    if (flags & DP_F_MINUS)
+        spadlen = -spadlen;
+
+    /* spaces */
+    while (spadlen > 0) {
+        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+        --spadlen;
+    }
+
+    /* sign */
+    if (signvalue)
+        doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
+
+    /* prefix */
+    while (*prefix) {
+	doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix);
+	prefix++;
+    }
+
+    /* zeros */
+    if (zpadlen > 0) {
+        while (zpadlen > 0) {
+            doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
+            --zpadlen;
+        }
+    }
+    /* digits */
+    while (place > 0)
+        doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]);
+
+    /* left justified spaces */
+    while (spadlen < 0) {
+        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+        ++spadlen;
+    }
+    return;
+}
+
+static LDOUBLE
+abs_val(LDOUBLE value)
+{
+    LDOUBLE result = value;
+    if (value < 0)
+        result = -value;
+    return result;
+}
+
+static LDOUBLE
+pow_10(int in_exp)
+{
+    LDOUBLE result = 1;
+    while (in_exp) {
+        result *= 10;
+        in_exp--;
+    }
+    return result;
+}
+
+static long
+roundv(LDOUBLE value)
+{
+    long intpart;
+    intpart = (long) value;
+    value = value - intpart;
+    if (value >= 0.5)
+        intpart++;
+    return intpart;
+}
+
+static void
+fmtfp(
+    char **sbuffer,
+    char **buffer,
+    size_t *currlen,
+    size_t *maxlen,
+    LDOUBLE fvalue,
+    int min,
+    int max,
+    int flags)
+{
+    int signvalue = 0;
+    LDOUBLE ufvalue;
+    char iconvert[20];
+    char fconvert[20];
+    int iplace = 0;
+    int fplace = 0;
+    int padlen = 0;
+    int zpadlen = 0;
+    int caps = 0;
+    long intpart;
+    long fracpart;
+    long max10;
+
+    if (max < 0)
+        max = 6;
+    ufvalue = abs_val(fvalue);
+    if (fvalue < 0)
+        signvalue = '-';
+    else if (flags & DP_F_PLUS)
+        signvalue = '+';
+    else if (flags & DP_F_SPACE)
+        signvalue = ' ';
+
+    intpart = (long)ufvalue;
+
+    /* sorry, we only support 9 digits past the decimal because of our
+       conversion method */
+    if (max > 9)
+        max = 9;
+
+    /* we "cheat" by converting the fractional part to integer by
+       multiplying by a factor of 10 */
+    max10 = roundv(pow_10(max));
+    fracpart = roundv(pow_10(max) * (ufvalue - intpart));
+
+    if (fracpart >= max10) {
+        intpart++;
+        fracpart -= max10;
+    }
+
+    /* convert integer part */
+    do {
+        iconvert[iplace++] =
+            (caps ? "0123456789ABCDEF"
+              : "0123456789abcdef")[intpart % 10];
+        intpart = (intpart / 10);
+    } while (intpart && (iplace < (int)sizeof(iconvert)));
+    if (iplace == sizeof iconvert)
+        iplace--;
+    iconvert[iplace] = 0;
+
+    /* convert fractional part */
+    do {
+        fconvert[fplace++] =
+            (caps ? "0123456789ABCDEF"
+              : "0123456789abcdef")[fracpart % 10];
+        fracpart = (fracpart / 10);
+    } while (fplace < max);
+    if (fplace == sizeof fconvert)
+        fplace--;
+    fconvert[fplace] = 0;
+
+    /* -1 for decimal point, another -1 if we are printing a sign */
+    padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
+    zpadlen = max - fplace;
+    if (zpadlen < 0)
+        zpadlen = 0;
+    if (padlen < 0)
+        padlen = 0;
+    if (flags & DP_F_MINUS)
+        padlen = -padlen;
+
+    if ((flags & DP_F_ZERO) && (padlen > 0)) {
+        if (signvalue) {
+            doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
+            --padlen;
+            signvalue = 0;
+        }
+        while (padlen > 0) {
+            doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
+            --padlen;
+        }
+    }
+    while (padlen > 0) {
+        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+        --padlen;
+    }
+    if (signvalue)
+        doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
+
+    while (iplace > 0)
+        doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]);
+
+    /*
+     * Decimal point. This should probably use locale to find the correct
+     * char to print out.
+     */
+    if (max > 0 || (flags & DP_F_NUM)) {
+        doapr_outch(sbuffer, buffer, currlen, maxlen, '.');
+
+        while (fplace > 0)
+            doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]);
+    }
+    while (zpadlen > 0) {
+        doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
+        --zpadlen;
+    }
+
+    while (padlen < 0) {
+        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+        ++padlen;
+    }
+}
+
+static void
+doapr_outch(
+    char **sbuffer,
+    char **buffer,
+    size_t *currlen,
+    size_t *maxlen,
+    int c)
+{
+    /* If we haven't at least one buffer, someone has doe a big booboo */
+    assert(*sbuffer != NULL || buffer != NULL);
+
+    if (buffer) {
+	while (*currlen >= *maxlen) {
+	    if (*buffer == NULL) {
+		if (*maxlen == 0)
+		    *maxlen = 1024;
+		*buffer = OPENSSL_malloc(*maxlen);
+		if (*currlen > 0) {
+		    assert(*sbuffer != NULL);
+		    memcpy(*buffer, *sbuffer, *currlen);
+		}
+		*sbuffer = NULL;
+	    } else {
+		*maxlen += 1024;
+		*buffer = OPENSSL_realloc(*buffer, *maxlen);
+	    }
+	}
+	/* What to do if *buffer is NULL? */
+	assert(*sbuffer != NULL || *buffer != NULL);
+    }
+
+    if (*currlen < *maxlen) {
+	if (*sbuffer)
+	    (*sbuffer)[(*currlen)++] = (char)c;
+	else
+	    (*buffer)[(*currlen)++] = (char)c;
+    }
+
+    return;
+}
+
+/***************************************************************************/
+
+int BIO_printf (BIO *bio, const char *format, ...)
+	{
+	va_list args;
+	int ret;
+
+	va_start(args, format);
+
+	ret = BIO_vprintf(bio, format, args);
+
+	va_end(args);
+	return(ret);
+	}
+
+int BIO_vprintf (BIO *bio, const char *format, va_list args)
+	{
+	int ret;
+	size_t retlen;
+	char hugebuf[1024*2];	/* Was previously 10k, which is unreasonable
+				   in small-stack environments, like threads
+				   or DOS programs. */
+	char *hugebufp = hugebuf;
+	size_t hugebufsize = sizeof(hugebuf);
+	char *dynbuf = NULL;
+	int ignored;
+
+	dynbuf = NULL;
+	CRYPTO_push_info("doapr()");
+	_dopr(&hugebufp, &dynbuf, &hugebufsize,
+		&retlen, &ignored, format, args);
+	if (dynbuf)
+		{
+		ret=BIO_write(bio, dynbuf, (int)retlen);
+		OPENSSL_free(dynbuf);
+		}
+	else
+		{
+		ret=BIO_write(bio, hugebuf, (int)retlen);
+		}
+	CRYPTO_pop_info();
+	return(ret);
+	}
+
+/* As snprintf is not available everywhere, we provide our own implementation.
+ * This function has nothing to do with BIOs, but it's closely related
+ * to BIO_printf, and we need *some* name prefix ...
+ * (XXX  the function should be renamed, but to what?) */
+int BIO_snprintf(char *buf, size_t n, const char *format, ...)
+	{
+	va_list args;
+	int ret;
+
+	va_start(args, format);
+
+	ret = BIO_vsnprintf(buf, n, format, args);
+
+	va_end(args);
+	return(ret);
+	}
+
+int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
+	{
+	size_t retlen;
+	int truncated;
+
+	_dopr(&buf, NULL, &n, &retlen, &truncated, format, args);
+
+	if (truncated)
+		/* In case of truncation, return -1 like traditional snprintf.
+		 * (Current drafts for ISO/IEC 9899 say snprintf should return
+		 * the number of characters that would have been written,
+		 * had the buffer been large enough.) */
+		return -1;
+	else
+		return (retlen <= INT_MAX) ? (int)retlen : -1;
+	}
diff --git a/openssl/crypto/bio/b_sock.c b/openssl/crypto/bio/b_sock.c
new file mode 100644
index 0000000..d47310d
--- /dev/null
+++ b/openssl/crypto/bio/b_sock.c
@@ -0,0 +1,975 @@
+/* crypto/bio/b_sock.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "cryptlib.h"
+#include <openssl/bio.h>
+#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
+#include <netdb.h>
+#if defined(NETWARE_CLIB)
+#include <sys/ioctl.h>
+NETDB_DEFINE_CONTEXT
+#endif
+#endif
+
+#ifndef OPENSSL_NO_SOCK
+
+#include <openssl/dso.h>
+
+#define SOCKET_PROTOCOL IPPROTO_TCP
+
+#ifdef SO_MAXCONN
+#define MAX_LISTEN  SO_MAXCONN
+#elif defined(SOMAXCONN)
+#define MAX_LISTEN  SOMAXCONN
+#else
+#define MAX_LISTEN  32
+#endif
+
+#if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
+static int wsa_init_done=0;
+#endif
+
+/*
+ * WSAAPI specifier is required to make indirect calls to run-time
+ * linked WinSock 2 functions used in this module, to be specific
+ * [get|free]addrinfo and getnameinfo. This is because WinSock uses
+ * uses non-C calling convention, __stdcall vs. __cdecl, on x86
+ * Windows. On non-WinSock platforms WSAAPI needs to be void.
+ */
+#ifndef WSAAPI
+#define WSAAPI
+#endif
+
+#if 0
+static unsigned long BIO_ghbn_hits=0L;
+static unsigned long BIO_ghbn_miss=0L;
+
+#define GHBN_NUM	4
+static struct ghbn_cache_st
+	{
+	char name[129];
+	struct hostent *ent;
+	unsigned long order;
+	} ghbn_cache[GHBN_NUM];
+#endif
+
+static int get_ip(const char *str,unsigned char *ip);
+#if 0
+static void ghbn_free(struct hostent *a);
+static struct hostent *ghbn_dup(struct hostent *a);
+#endif
+int BIO_get_host_ip(const char *str, unsigned char *ip)
+	{
+	int i;
+	int err = 1;
+	int locked = 0;
+	struct hostent *he;
+
+	i=get_ip(str,ip);
+	if (i < 0)
+		{
+		BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_INVALID_IP_ADDRESS);
+		goto err;
+		}
+
+	/* At this point, we have something that is most probably correct
+	   in some way, so let's init the socket. */
+	if (BIO_sock_init() != 1)
+		return 0; /* don't generate another error code here */
+
+	/* If the string actually contained an IP address, we need not do
+	   anything more */
+	if (i > 0) return(1);
+
+	/* do a gethostbyname */
+	CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
+	locked = 1;
+	he=BIO_gethostbyname(str);
+	if (he == NULL)
+		{
+		BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_BAD_HOSTNAME_LOOKUP);
+		goto err;
+		}
+
+	/* cast to short because of win16 winsock definition */
+	if ((short)he->h_addrtype != AF_INET)
+		{
+		BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
+		goto err;
+		}
+	for (i=0; i<4; i++)
+		ip[i]=he->h_addr_list[0][i];
+	err = 0;
+
+ err:
+	if (locked)
+		CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
+	if (err)
+		{
+		ERR_add_error_data(2,"host=",str);
+		return 0;
+		}
+	else
+		return 1;
+	}
+
+int BIO_get_port(const char *str, unsigned short *port_ptr)
+	{
+	int i;
+	struct servent *s;
+
+	if (str == NULL)
+		{
+		BIOerr(BIO_F_BIO_GET_PORT,BIO_R_NO_PORT_DEFINED);
+		return(0);
+		}
+	i=atoi(str);
+	if (i != 0)
+		*port_ptr=(unsigned short)i;
+	else
+		{
+		CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME);
+		/* Note: under VMS with SOCKETSHR, it seems like the first
+		 * parameter is 'char *', instead of 'const char *'
+		 */
+#ifndef CONST_STRICT
+		s=getservbyname((char *)str,"tcp");
+#else
+		s=getservbyname(str,"tcp");
+#endif
+		if(s != NULL)
+			*port_ptr=ntohs((unsigned short)s->s_port);
+		CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME);
+		if(s == NULL)
+			{
+			if (strcmp(str,"http") == 0)
+				*port_ptr=80;
+			else if (strcmp(str,"telnet") == 0)
+				*port_ptr=23;
+			else if (strcmp(str,"socks") == 0)
+				*port_ptr=1080;
+			else if (strcmp(str,"https") == 0)
+				*port_ptr=443;
+			else if (strcmp(str,"ssl") == 0)
+				*port_ptr=443;
+			else if (strcmp(str,"ftp") == 0)
+				*port_ptr=21;
+			else if (strcmp(str,"gopher") == 0)
+				*port_ptr=70;
+#if 0
+			else if (strcmp(str,"wais") == 0)
+				*port_ptr=21;
+#endif
+			else
+				{
+				SYSerr(SYS_F_GETSERVBYNAME,get_last_socket_error());
+				ERR_add_error_data(3,"service='",str,"'");
+				return(0);
+				}
+			}
+		}
+	return(1);
+	}
+
+int BIO_sock_error(int sock)
+	{
+	int j,i;
+	int size;
+		 
+#if defined(OPENSSL_SYS_BEOS_R5)
+	return 0;
+#endif
+		 
+	size=sizeof(int);
+	/* Note: under Windows the third parameter is of type (char *)
+	 * whereas under other systems it is (void *) if you don't have
+	 * a cast it will choke the compiler: if you do have a cast then
+	 * you can either go for (char *) or (void *).
+	 */
+	i=getsockopt(sock,SOL_SOCKET,SO_ERROR,(void *)&j,(void *)&size);
+	if (i < 0)
+		return(1);
+	else
+		return(j);
+	}
+
+#if 0
+long BIO_ghbn_ctrl(int cmd, int iarg, char *parg)
+	{
+	int i;
+	char **p;
+
+	switch (cmd)
+		{
+	case BIO_GHBN_CTRL_HITS:
+		return(BIO_ghbn_hits);
+		/* break; */
+	case BIO_GHBN_CTRL_MISSES:
+		return(BIO_ghbn_miss);
+		/* break; */
+	case BIO_GHBN_CTRL_CACHE_SIZE:
+		return(GHBN_NUM);
+		/* break; */
+	case BIO_GHBN_CTRL_GET_ENTRY:
+		if ((iarg >= 0) && (iarg <GHBN_NUM) &&
+			(ghbn_cache[iarg].order > 0))
+			{
+			p=(char **)parg;
+			if (p == NULL) return(0);
+			*p=ghbn_cache[iarg].name;
+			ghbn_cache[iarg].name[128]='\0';
+			return(1);
+			}
+		return(0);
+		/* break; */
+	case BIO_GHBN_CTRL_FLUSH:
+		for (i=0; i<GHBN_NUM; i++)
+			ghbn_cache[i].order=0;
+		break;
+	default:
+		return(0);
+		}
+	return(1);
+	}
+#endif
+
+#if 0
+static struct hostent *ghbn_dup(struct hostent *a)
+	{
+	struct hostent *ret;
+	int i,j;
+
+	MemCheck_off();
+	ret=(struct hostent *)OPENSSL_malloc(sizeof(struct hostent));
+	if (ret == NULL) return(NULL);
+	memset(ret,0,sizeof(struct hostent));
+
+	for (i=0; a->h_aliases[i] != NULL; i++)
+		;
+	i++;
+	ret->h_aliases = (char **)OPENSSL_malloc(i*sizeof(char *));
+	if (ret->h_aliases == NULL)
+		goto err;
+	memset(ret->h_aliases, 0, i*sizeof(char *));
+
+	for (i=0; a->h_addr_list[i] != NULL; i++)
+		;
+	i++;
+	ret->h_addr_list=(char **)OPENSSL_malloc(i*sizeof(char *));
+	if (ret->h_addr_list == NULL)
+		goto err;
+	memset(ret->h_addr_list, 0, i*sizeof(char *));
+
+	j=strlen(a->h_name)+1;
+	if ((ret->h_name=OPENSSL_malloc(j)) == NULL) goto err;
+	memcpy((char *)ret->h_name,a->h_name,j);
+	for (i=0; a->h_aliases[i] != NULL; i++)
+		{
+		j=strlen(a->h_aliases[i])+1;
+		if ((ret->h_aliases[i]=OPENSSL_malloc(j)) == NULL) goto err;
+		memcpy(ret->h_aliases[i],a->h_aliases[i],j);
+		}
+	ret->h_length=a->h_length;
+	ret->h_addrtype=a->h_addrtype;
+	for (i=0; a->h_addr_list[i] != NULL; i++)
+		{
+		if ((ret->h_addr_list[i]=OPENSSL_malloc(a->h_length)) == NULL)
+			goto err;
+		memcpy(ret->h_addr_list[i],a->h_addr_list[i],a->h_length);
+		}
+	if (0)
+		{
+err:	
+		if (ret != NULL)
+			ghbn_free(ret);
+		ret=NULL;
+		}
+	MemCheck_on();
+	return(ret);
+	}
+
+static void ghbn_free(struct hostent *a)
+	{
+	int i;
+
+	if(a == NULL)
+	    return;
+
+	if (a->h_aliases != NULL)
+		{
+		for (i=0; a->h_aliases[i] != NULL; i++)
+			OPENSSL_free(a->h_aliases[i]);
+		OPENSSL_free(a->h_aliases);
+		}
+	if (a->h_addr_list != NULL)
+		{
+		for (i=0; a->h_addr_list[i] != NULL; i++)
+			OPENSSL_free(a->h_addr_list[i]);
+		OPENSSL_free(a->h_addr_list);
+		}
+	if (a->h_name != NULL) OPENSSL_free(a->h_name);
+	OPENSSL_free(a);
+	}
+
+#endif
+
+struct hostent *BIO_gethostbyname(const char *name)
+	{
+#if 1
+	/* Caching gethostbyname() results forever is wrong,
+	 * so we have to let the true gethostbyname() worry about this */
+#if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__))
+	return gethostbyname((char*)name);
+#else
+	return gethostbyname(name);
+#endif
+#else
+	struct hostent *ret;
+	int i,lowi=0,j;
+	unsigned long low= (unsigned long)-1;
+
+
+#  if 0
+	/* It doesn't make sense to use locking here: The function interface
+	 * is not thread-safe, because threads can never be sure when
+	 * some other thread destroys the data they were given a pointer to.
+	 */
+	CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
+#  endif
+	j=strlen(name);
+	if (j < 128)
+		{
+		for (i=0; i<GHBN_NUM; i++)
+			{
+			if (low > ghbn_cache[i].order)
+				{
+				low=ghbn_cache[i].order;
+				lowi=i;
+				}
+			if (ghbn_cache[i].order > 0)
+				{
+				if (strncmp(name,ghbn_cache[i].name,128) == 0)
+					break;
+				}
+			}
+		}
+	else
+		i=GHBN_NUM;
+
+	if (i == GHBN_NUM) /* no hit*/
+		{
+		BIO_ghbn_miss++;
+		/* Note: under VMS with SOCKETSHR, it seems like the first
+		 * parameter is 'char *', instead of 'const char *'
+		 */
+#  ifndef CONST_STRICT
+		ret=gethostbyname((char *)name);
+#  else
+		ret=gethostbyname(name);
+#  endif
+
+		if (ret == NULL)
+			goto end;
+		if (j > 128) /* too big to cache */
+			{
+#  if 0
+			/* If we were trying to make this function thread-safe (which
+			 * is bound to fail), we'd have to give up in this case
+			 * (or allocate more memory). */
+			ret = NULL;
+#  endif
+			goto end;
+			}
+
+		/* else add to cache */
+		if (ghbn_cache[lowi].ent != NULL)
+			ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */
+		ghbn_cache[lowi].name[0] = '\0';
+
+		if((ret=ghbn_cache[lowi].ent=ghbn_dup(ret)) == NULL)
+			{
+			BIOerr(BIO_F_BIO_GETHOSTBYNAME,ERR_R_MALLOC_FAILURE);
+			goto end;
+			}
+		strncpy(ghbn_cache[lowi].name,name,128);
+		ghbn_cache[lowi].order=BIO_ghbn_miss+BIO_ghbn_hits;
+		}
+	else
+		{
+		BIO_ghbn_hits++;
+		ret= ghbn_cache[i].ent;
+		ghbn_cache[i].order=BIO_ghbn_miss+BIO_ghbn_hits;
+		}
+end:
+#  if 0
+	CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
+#  endif
+	return(ret);
+#endif
+	}
+
+
+int BIO_sock_init(void)
+	{
+#ifdef OPENSSL_SYS_WINDOWS
+	static struct WSAData wsa_state;
+
+	if (!wsa_init_done)
+		{
+		int err;
+	  
+		wsa_init_done=1;
+		memset(&wsa_state,0,sizeof(wsa_state));
+		/* Not making wsa_state available to the rest of the
+		 * code is formally wrong. But the structures we use
+		 * are [beleived to be] invariable among Winsock DLLs,
+		 * while API availability is [expected to be] probed
+		 * at run-time with DSO_global_lookup. */
+		if (WSAStartup(0x0202,&wsa_state)!=0)
+			{
+			err=WSAGetLastError();
+			SYSerr(SYS_F_WSASTARTUP,err);
+			BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
+			return(-1);
+			}
+		}
+#endif /* OPENSSL_SYS_WINDOWS */
+#ifdef WATT32
+	extern int _watt_do_exit;
+	_watt_do_exit = 0;    /* don't make sock_init() call exit() */
+	if (sock_init())
+		return (-1);
+#endif
+
+#if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
+    WORD wVerReq;
+    WSADATA wsaData;
+    int err;
+
+    if (!wsa_init_done)
+    {
+        wsa_init_done=1;
+        wVerReq = MAKEWORD( 2, 0 );
+        err = WSAStartup(wVerReq,&wsaData);
+        if (err != 0)
+        {
+            SYSerr(SYS_F_WSASTARTUP,err);
+            BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
+            return(-1);
+			}
+		}
+#endif
+
+	return(1);
+	}
+
+void BIO_sock_cleanup(void)
+	{
+#ifdef OPENSSL_SYS_WINDOWS
+	if (wsa_init_done)
+		{
+		wsa_init_done=0;
+#if 0		/* this call is claimed to be non-present in Winsock2 */
+		WSACancelBlockingCall();
+#endif
+		WSACleanup();
+		}
+#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
+   if (wsa_init_done)
+        {
+        wsa_init_done=0;
+        WSACleanup();
+		}
+#endif
+	}
+
+#if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000
+
+int BIO_socket_ioctl(int fd, long type, void *arg)
+	{
+	int i;
+
+#ifdef __DJGPP__
+	i=ioctlsocket(fd,type,(char *)arg);
+#else
+# if defined(OPENSSL_SYS_VMS)
+	/* 2011-02-18 SMS.
+	 * VMS ioctl() can't tolerate a 64-bit "void *arg", but we
+	 * observe that all the consumers pass in an "unsigned long *",
+	 * so we arrange a local copy with a short pointer, and use
+	 * that, instead.
+	 */
+#  if __INITIAL_POINTER_SIZE == 64
+#   define ARG arg_32p
+#   pragma pointer_size save
+#   pragma pointer_size 32
+	unsigned long arg_32;
+	unsigned long *arg_32p;
+#   pragma pointer_size restore
+	arg_32p = &arg_32;
+	arg_32 = *((unsigned long *) arg);
+#  else /* __INITIAL_POINTER_SIZE == 64 */
+#   define ARG arg
+#  endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+# else /* defined(OPENSSL_SYS_VMS) */
+#  define ARG arg
+# endif /* defined(OPENSSL_SYS_VMS) [else] */
+
+	i=ioctlsocket(fd,type,ARG);
+#endif /* __DJGPP__ */
+	if (i < 0)
+		SYSerr(SYS_F_IOCTLSOCKET,get_last_socket_error());
+	return(i);
+	}
+#endif /* __VMS_VER */
+
+/* The reason I have implemented this instead of using sscanf is because
+ * Visual C 1.52c gives an unresolved external when linking a DLL :-( */
+static int get_ip(const char *str, unsigned char ip[4])
+	{
+	unsigned int tmp[4];
+	int num=0,c,ok=0;
+
+	tmp[0]=tmp[1]=tmp[2]=tmp[3]=0;
+
+	for (;;)
+		{
+		c= *(str++);
+		if ((c >= '0') && (c <= '9'))
+			{
+			ok=1;
+			tmp[num]=tmp[num]*10+c-'0';
+			if (tmp[num] > 255) return(0);
+			}
+		else if (c == '.')
+			{
+			if (!ok) return(-1);
+			if (num == 3) return(0);
+			num++;
+			ok=0;
+			}
+		else if (c == '\0' && (num == 3) && ok)
+			break;
+		else
+			return(0);
+		}
+	ip[0]=tmp[0];
+	ip[1]=tmp[1];
+	ip[2]=tmp[2];
+	ip[3]=tmp[3];
+	return(1);
+	}
+
+int BIO_get_accept_socket(char *host, int bind_mode)
+	{
+	int ret=0;
+	union {
+		struct sockaddr sa;
+		struct sockaddr_in sa_in;
+#if OPENSSL_USE_IPV6
+		struct sockaddr_in6 sa_in6;
+#endif
+	} server,client;
+	int s=INVALID_SOCKET,cs,addrlen;
+	unsigned char ip[4];
+	unsigned short port;
+	char *str=NULL,*e;
+	char *h,*p;
+	unsigned long l;
+	int err_num;
+
+	if (BIO_sock_init() != 1) return(INVALID_SOCKET);
+
+	if ((str=BUF_strdup(host)) == NULL) return(INVALID_SOCKET);
+
+	h=p=NULL;
+	h=str;
+	for (e=str; *e; e++)
+		{
+		if (*e == ':')
+			{
+			p=e;
+			}
+		else if (*e == '/')
+			{
+			*e='\0';
+			break;
+			}
+		}
+	if (p)	*p++='\0';	/* points at last ':', '::port' is special [see below] */
+	else	p=h,h=NULL;
+
+#ifdef EAI_FAMILY
+	do {
+	static union {	void *p;
+			int (WSAAPI *f)(const char *,const char *,
+				 const struct addrinfo *,
+				 struct addrinfo **);
+			} p_getaddrinfo = {NULL};
+	static union {	void *p;
+			void (WSAAPI *f)(struct addrinfo *);
+			} p_freeaddrinfo = {NULL};
+	struct addrinfo *res,hint;
+
+	if (p_getaddrinfo.p==NULL)
+		{
+		if ((p_getaddrinfo.p=DSO_global_lookup("getaddrinfo"))==NULL ||
+		    (p_freeaddrinfo.p=DSO_global_lookup("freeaddrinfo"))==NULL)
+			p_getaddrinfo.p=(void*)-1;
+		}
+	if (p_getaddrinfo.p==(void *)-1) break;
+
+	/* '::port' enforces IPv6 wildcard listener. Some OSes,
+	 * e.g. Solaris, default to IPv6 without any hint. Also
+	 * note that commonly IPv6 wildchard socket can service
+	 * IPv4 connections just as well...  */
+	memset(&hint,0,sizeof(hint));
+	hint.ai_flags = AI_PASSIVE;
+	if (h)
+		{
+		if (strchr(h,':'))
+			{
+			if (h[1]=='\0') h=NULL;
+#if OPENSSL_USE_IPV6
+			hint.ai_family = AF_INET6;
+#else
+			h=NULL;
+#endif
+			}
+	    	else if (h[0]=='*' && h[1]=='\0')
+			{
+			hint.ai_family = AF_INET;
+			h=NULL;
+			}
+		}
+
+	if ((*p_getaddrinfo.f)(h,p,&hint,&res)) break;
+
+	addrlen = res->ai_addrlen<=sizeof(server) ?
+			res->ai_addrlen :
+			sizeof(server);
+	memcpy(&server, res->ai_addr, addrlen);
+
+	(*p_freeaddrinfo.f)(res);
+	goto again;
+	} while (0);
+#endif
+
+	if (!BIO_get_port(p,&port)) goto err;
+
+	memset((char *)&server,0,sizeof(server));
+	server.sa_in.sin_family=AF_INET;
+	server.sa_in.sin_port=htons(port);
+	addrlen = sizeof(server.sa_in);
+
+	if (h == NULL || strcmp(h,"*") == 0)
+		server.sa_in.sin_addr.s_addr=INADDR_ANY;
+	else
+		{
+                if (!BIO_get_host_ip(h,&(ip[0]))) goto err;
+		l=(unsigned long)
+			((unsigned long)ip[0]<<24L)|
+			((unsigned long)ip[1]<<16L)|
+			((unsigned long)ip[2]<< 8L)|
+			((unsigned long)ip[3]);
+		server.sa_in.sin_addr.s_addr=htonl(l);
+		}
+
+again:
+	s=socket(server.sa.sa_family,SOCK_STREAM,SOCKET_PROTOCOL);
+	if (s == INVALID_SOCKET)
+		{
+		SYSerr(SYS_F_SOCKET,get_last_socket_error());
+		ERR_add_error_data(3,"port='",host,"'");
+		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_CREATE_SOCKET);
+		goto err;
+		}
+
+#ifdef SO_REUSEADDR
+	if (bind_mode == BIO_BIND_REUSEADDR)
+		{
+		int i=1;
+
+		ret=setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&i,sizeof(i));
+		bind_mode=BIO_BIND_NORMAL;
+		}
+#endif
+	if (bind(s,&server.sa,addrlen) == -1)
+		{
+#ifdef SO_REUSEADDR
+		err_num=get_last_socket_error();
+		if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) &&
+#ifdef OPENSSL_SYS_WINDOWS
+			/* Some versions of Windows define EADDRINUSE to
+			 * a dummy value.
+			 */
+			(err_num == WSAEADDRINUSE))
+#else
+			(err_num == EADDRINUSE))
+#endif
+			{
+			client = server;
+			if (h == NULL || strcmp(h,"*") == 0)
+				{
+#if OPENSSL_USE_IPV6
+				if (client.sa.sa_family == AF_INET6)
+					{
+					memset(&client.sa_in6.sin6_addr,0,sizeof(client.sa_in6.sin6_addr));
+					client.sa_in6.sin6_addr.s6_addr[15]=1;
+					}
+				else
+#endif
+				if (client.sa.sa_family == AF_INET)
+					{
+					client.sa_in.sin_addr.s_addr=htonl(0x7F000001);
+					}
+				else	goto err;
+				}
+			cs=socket(client.sa.sa_family,SOCK_STREAM,SOCKET_PROTOCOL);
+			if (cs != INVALID_SOCKET)
+				{
+				int ii;
+				ii=connect(cs,&client.sa,addrlen);
+				closesocket(cs);
+				if (ii == INVALID_SOCKET)
+					{
+					bind_mode=BIO_BIND_REUSEADDR;
+					closesocket(s);
+					goto again;
+					}
+				/* else error */
+				}
+			/* else error */
+			}
+#endif
+		SYSerr(SYS_F_BIND,err_num);
+		ERR_add_error_data(3,"port='",host,"'");
+		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_BIND_SOCKET);
+		goto err;
+		}
+	if (listen(s,MAX_LISTEN) == -1)
+		{
+		SYSerr(SYS_F_BIND,get_last_socket_error());
+		ERR_add_error_data(3,"port='",host,"'");
+		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_LISTEN_SOCKET);
+		goto err;
+		}
+	ret=1;
+err:
+	if (str != NULL) OPENSSL_free(str);
+	if ((ret == 0) && (s != INVALID_SOCKET))
+		{
+		closesocket(s);
+		s= INVALID_SOCKET;
+		}
+	return(s);
+	}
+
+int BIO_accept(int sock, char **addr)
+	{
+	int ret=INVALID_SOCKET;
+	unsigned long l;
+	unsigned short port;
+	char *p;
+
+	struct {
+	/*
+	 * As for following union. Trouble is that there are platforms
+	 * that have socklen_t and there are platforms that don't, on
+	 * some platforms socklen_t is int and on some size_t. So what
+	 * one can do? One can cook #ifdef spaghetti, which is nothing
+	 * but masochistic. Or one can do union between int and size_t.
+	 * One naturally does it primarily for 64-bit platforms where
+	 * sizeof(int) != sizeof(size_t). But would it work? Note that
+	 * if size_t member is initialized to 0, then later int member
+	 * assignment naturally does the job on little-endian platforms
+	 * regardless accept's expectations! What about big-endians?
+	 * If accept expects int*, then it works, and if size_t*, then
+	 * length value would appear as unreasonably large. But this
+	 * won't prevent it from filling in the address structure. The
+	 * trouble of course would be if accept returns more data than
+	 * actual buffer can accomodate and overwrite stack... That's
+	 * where early OPENSSL_assert comes into picture. Besides, the
+	 * only 64-bit big-endian platform found so far that expects
+	 * size_t* is HP-UX, where stack grows towards higher address.
+	 * <appro>
+	 */
+	union { size_t s; int i; } len;
+	union {
+		struct sockaddr sa;
+		struct sockaddr_in sa_in;
+#if OPENSSL_USE_IPV6
+		struct sockaddr_in6 sa_in6;
+#endif
+		} from;
+	} sa;
+
+	sa.len.s=0;
+	sa.len.i=sizeof(sa.from);
+	memset(&sa.from,0,sizeof(sa.from));
+	ret=accept(sock,&sa.from.sa,(void *)&sa.len);
+	if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0)
+		{
+		OPENSSL_assert(sa.len.s<=sizeof(sa.from));
+		sa.len.i = (int)sa.len.s;
+		/* use sa.len.i from this point */
+		}
+	if (ret == INVALID_SOCKET)
+		{
+		if(BIO_sock_should_retry(ret)) return -2;
+		SYSerr(SYS_F_ACCEPT,get_last_socket_error());
+		BIOerr(BIO_F_BIO_ACCEPT,BIO_R_ACCEPT_ERROR);
+		goto end;
+		}
+
+	if (addr == NULL) goto end;
+
+#ifdef EAI_FAMILY
+	do {
+	char   h[NI_MAXHOST],s[NI_MAXSERV];
+	size_t nl;
+	static union {	void *p;
+			int (WSAAPI *f)(const struct sockaddr *,size_t/*socklen_t*/,
+				 char *,size_t,char *,size_t,int);
+			} p_getnameinfo = {NULL};
+			/* 2nd argument to getnameinfo is specified to
+			 * be socklen_t. Unfortunately there is a number
+			 * of environments where socklen_t is not defined.
+			 * As it's passed by value, it's safe to pass it
+			 * as size_t... <appro> */
+
+	if (p_getnameinfo.p==NULL)
+		{
+		if ((p_getnameinfo.p=DSO_global_lookup("getnameinfo"))==NULL)
+			p_getnameinfo.p=(void*)-1;
+		}
+	if (p_getnameinfo.p==(void *)-1) break;
+
+	if ((*p_getnameinfo.f)(&sa.from.sa,sa.len.i,h,sizeof(h),s,sizeof(s),
+	    NI_NUMERICHOST|NI_NUMERICSERV)) break;
+	nl = strlen(h)+strlen(s)+2;
+	p = *addr;
+	if (p)	{ *p = '\0'; p = OPENSSL_realloc(p,nl);	}
+	else	{ p = OPENSSL_malloc(nl);		}
+	if (p==NULL)
+		{
+		BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE);
+		goto end;
+		}
+	*addr = p;
+	BIO_snprintf(*addr,nl,"%s:%s",h,s);
+	goto end;
+	} while(0);
+#endif
+	if (sa.from.sa.sa_family != AF_INET) goto end;
+	l=ntohl(sa.from.sa_in.sin_addr.s_addr);
+	port=ntohs(sa.from.sa_in.sin_port);
+	if (*addr == NULL)
+		{
+		if ((p=OPENSSL_malloc(24)) == NULL)
+			{
+			BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE);
+			goto end;
+			}
+		*addr=p;
+		}
+	BIO_snprintf(*addr,24,"%d.%d.%d.%d:%d",
+		     (unsigned char)(l>>24L)&0xff,
+		     (unsigned char)(l>>16L)&0xff,
+		     (unsigned char)(l>> 8L)&0xff,
+		     (unsigned char)(l     )&0xff,
+		     port);
+end:
+	return(ret);
+	}
+
+int BIO_set_tcp_ndelay(int s, int on)
+	{
+	int ret=0;
+#if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
+	int opt;
+
+#ifdef SOL_TCP
+	opt=SOL_TCP;
+#else
+#ifdef IPPROTO_TCP
+	opt=IPPROTO_TCP;
+#endif
+#endif
+	
+	ret=setsockopt(s,opt,TCP_NODELAY,(char *)&on,sizeof(on));
+#endif
+	return(ret == 0);
+	}
+#endif
+
+int BIO_socket_nbio(int s, int mode)
+	{
+	int ret= -1;
+	int l;
+
+	l=mode;
+#ifdef FIONBIO
+	ret=BIO_socket_ioctl(s,FIONBIO,&l);
+#endif
+	return(ret == 0);
+	}
diff --git a/openssl/crypto/bio/bf_buff.c b/openssl/crypto/bio/bf_buff.c
new file mode 100644
index 0000000..4b5a132
--- /dev/null
+++ b/openssl/crypto/bio/bf_buff.c
@@ -0,0 +1,512 @@
+/* crypto/bio/bf_buff.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+
+static int buffer_write(BIO *h, const char *buf,int num);
+static int buffer_read(BIO *h, char *buf, int size);
+static int buffer_puts(BIO *h, const char *str);
+static int buffer_gets(BIO *h, char *str, int size);
+static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int buffer_new(BIO *h);
+static int buffer_free(BIO *data);
+static long buffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+#define DEFAULT_BUFFER_SIZE	4096
+
+static BIO_METHOD methods_buffer=
+	{
+	BIO_TYPE_BUFFER,
+	"buffer",
+	buffer_write,
+	buffer_read,
+	buffer_puts,
+	buffer_gets,
+	buffer_ctrl,
+	buffer_new,
+	buffer_free,
+	buffer_callback_ctrl,
+	};
+
+BIO_METHOD *BIO_f_buffer(void)
+	{
+	return(&methods_buffer);
+	}
+
+static int buffer_new(BIO *bi)
+	{
+	BIO_F_BUFFER_CTX *ctx;
+
+	ctx=(BIO_F_BUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_F_BUFFER_CTX));
+	if (ctx == NULL) return(0);
+	ctx->ibuf=(char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
+	if (ctx->ibuf == NULL) { OPENSSL_free(ctx); return(0); }
+	ctx->obuf=(char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
+	if (ctx->obuf == NULL) { OPENSSL_free(ctx->ibuf); OPENSSL_free(ctx); return(0); }
+	ctx->ibuf_size=DEFAULT_BUFFER_SIZE;
+	ctx->obuf_size=DEFAULT_BUFFER_SIZE;
+	ctx->ibuf_len=0;
+	ctx->ibuf_off=0;
+	ctx->obuf_len=0;
+	ctx->obuf_off=0;
+
+	bi->init=1;
+	bi->ptr=(char *)ctx;
+	bi->flags=0;
+	return(1);
+	}
+
+static int buffer_free(BIO *a)
+	{
+	BIO_F_BUFFER_CTX *b;
+
+	if (a == NULL) return(0);
+	b=(BIO_F_BUFFER_CTX *)a->ptr;
+	if (b->ibuf != NULL) OPENSSL_free(b->ibuf);
+	if (b->obuf != NULL) OPENSSL_free(b->obuf);
+	OPENSSL_free(a->ptr);
+	a->ptr=NULL;
+	a->init=0;
+	a->flags=0;
+	return(1);
+	}
+	
+static int buffer_read(BIO *b, char *out, int outl)
+	{
+	int i,num=0;
+	BIO_F_BUFFER_CTX *ctx;
+
+	if (out == NULL) return(0);
+	ctx=(BIO_F_BUFFER_CTX *)b->ptr;
+
+	if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
+	num=0;
+	BIO_clear_retry_flags(b);
+
+start:
+	i=ctx->ibuf_len;
+	/* If there is stuff left over, grab it */
+	if (i != 0)
+		{
+		if (i > outl) i=outl;
+		memcpy(out,&(ctx->ibuf[ctx->ibuf_off]),i);
+		ctx->ibuf_off+=i;
+		ctx->ibuf_len-=i;
+		num+=i;
+		if (outl == i)  return(num);
+		outl-=i;
+		out+=i;
+		}
+
+	/* We may have done a partial read. try to do more.
+	 * We have nothing in the buffer.
+	 * If we get an error and have read some data, just return it
+	 * and let them retry to get the error again.
+	 * copy direct to parent address space */
+	if (outl > ctx->ibuf_size)
+		{
+		for (;;)
+			{
+			i=BIO_read(b->next_bio,out,outl);
+			if (i <= 0)
+				{
+				BIO_copy_next_retry(b);
+				if (i < 0) return((num > 0)?num:i);
+				if (i == 0) return(num);
+				}
+			num+=i;
+			if (outl == i) return(num);
+			out+=i;
+			outl-=i;
+			}
+		}
+	/* else */
+
+	/* we are going to be doing some buffering */
+	i=BIO_read(b->next_bio,ctx->ibuf,ctx->ibuf_size);
+	if (i <= 0)
+		{
+		BIO_copy_next_retry(b);
+		if (i < 0) return((num > 0)?num:i);
+		if (i == 0) return(num);
+		}
+	ctx->ibuf_off=0;
+	ctx->ibuf_len=i;
+
+	/* Lets re-read using ourselves :-) */
+	goto start;
+	}
+
+static int buffer_write(BIO *b, const char *in, int inl)
+	{
+	int i,num=0;
+	BIO_F_BUFFER_CTX *ctx;
+
+	if ((in == NULL) || (inl <= 0)) return(0);
+	ctx=(BIO_F_BUFFER_CTX *)b->ptr;
+	if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
+
+	BIO_clear_retry_flags(b);
+start:
+	i=ctx->obuf_size-(ctx->obuf_len+ctx->obuf_off);
+	/* add to buffer and return */
+	if (i >= inl)
+		{
+		memcpy(&(ctx->obuf[ctx->obuf_off+ctx->obuf_len]),in,inl);
+		ctx->obuf_len+=inl;
+		return(num+inl);
+		}
+	/* else */
+	/* stuff already in buffer, so add to it first, then flush */
+	if (ctx->obuf_len != 0)
+		{
+		if (i > 0) /* lets fill it up if we can */
+			{
+			memcpy(&(ctx->obuf[ctx->obuf_off+ctx->obuf_len]),in,i);
+			in+=i;
+			inl-=i;
+			num+=i;
+			ctx->obuf_len+=i;
+			}
+		/* we now have a full buffer needing flushing */
+		for (;;)
+			{
+			i=BIO_write(b->next_bio,&(ctx->obuf[ctx->obuf_off]),
+				ctx->obuf_len);
+			if (i <= 0)
+				{
+				BIO_copy_next_retry(b);
+
+				if (i < 0) return((num > 0)?num:i);
+				if (i == 0) return(num);
+				}
+			ctx->obuf_off+=i;
+			ctx->obuf_len-=i;
+			if (ctx->obuf_len == 0) break;
+			}
+		}
+	/* we only get here if the buffer has been flushed and we
+	 * still have stuff to write */
+	ctx->obuf_off=0;
+
+	/* we now have inl bytes to write */
+	while (inl >= ctx->obuf_size)
+		{
+		i=BIO_write(b->next_bio,in,inl);
+		if (i <= 0)
+			{
+			BIO_copy_next_retry(b);
+			if (i < 0) return((num > 0)?num:i);
+			if (i == 0) return(num);
+			}
+		num+=i;
+		in+=i;
+		inl-=i;
+		if (inl == 0) return(num);
+		}
+
+	/* copy the rest into the buffer since we have only a small 
+	 * amount left */
+	goto start;
+	}
+
+static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	BIO *dbio;
+	BIO_F_BUFFER_CTX *ctx;
+	long ret=1;
+	char *p1,*p2;
+	int r,i,*ip;
+	int ibs,obs;
+
+	ctx=(BIO_F_BUFFER_CTX *)b->ptr;
+
+	switch (cmd)
+		{
+	case BIO_CTRL_RESET:
+		ctx->ibuf_off=0;
+		ctx->ibuf_len=0;
+		ctx->obuf_off=0;
+		ctx->obuf_len=0;
+		if (b->next_bio == NULL) return(0);
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_INFO:
+		ret=(long)ctx->obuf_len;
+		break;
+	case BIO_C_GET_BUFF_NUM_LINES:
+		ret=0;
+		p1=ctx->ibuf;
+		for (i=0; i<ctx->ibuf_len; i++)
+			{
+			if (p1[ctx->ibuf_off + i] == '\n') ret++;
+			}
+		break;
+	case BIO_CTRL_WPENDING:
+		ret=(long)ctx->obuf_len;
+		if (ret == 0)
+			{
+			if (b->next_bio == NULL) return(0);
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+			}
+		break;
+	case BIO_CTRL_PENDING:
+		ret=(long)ctx->ibuf_len;
+		if (ret == 0)
+			{
+			if (b->next_bio == NULL) return(0);
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+			}
+		break;
+	case BIO_C_SET_BUFF_READ_DATA:
+		if (num > ctx->ibuf_size)
+			{
+			p1=OPENSSL_malloc((int)num);
+			if (p1 == NULL) goto malloc_error;
+			if (ctx->ibuf != NULL) OPENSSL_free(ctx->ibuf);
+			ctx->ibuf=p1;
+			}
+		ctx->ibuf_off=0;
+		ctx->ibuf_len=(int)num;
+		memcpy(ctx->ibuf,ptr,(int)num);
+		ret=1;
+		break;
+	case BIO_C_SET_BUFF_SIZE:
+		if (ptr != NULL)
+			{
+			ip=(int *)ptr;
+			if (*ip == 0)
+				{
+				ibs=(int)num;
+				obs=ctx->obuf_size;
+				}
+			else /* if (*ip == 1) */
+				{
+				ibs=ctx->ibuf_size;
+				obs=(int)num;
+				}
+			}
+		else
+			{
+			ibs=(int)num;
+			obs=(int)num;
+			}
+		p1=ctx->ibuf;
+		p2=ctx->obuf;
+		if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size))
+			{
+			p1=(char *)OPENSSL_malloc((int)num);
+			if (p1 == NULL) goto malloc_error;
+			}
+		if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size))
+			{
+			p2=(char *)OPENSSL_malloc((int)num);
+			if (p2 == NULL)
+				{
+				if (p1 != ctx->ibuf) OPENSSL_free(p1);
+				goto malloc_error;
+				}
+			}
+		if (ctx->ibuf != p1)
+			{
+			OPENSSL_free(ctx->ibuf);
+			ctx->ibuf=p1;
+			ctx->ibuf_off=0;
+			ctx->ibuf_len=0;
+			ctx->ibuf_size=ibs;
+			}
+		if (ctx->obuf != p2)
+			{
+			OPENSSL_free(ctx->obuf);
+			ctx->obuf=p2;
+			ctx->obuf_off=0;
+			ctx->obuf_len=0;
+			ctx->obuf_size=obs;
+			}
+		break;
+	case BIO_C_DO_STATE_MACHINE:
+		if (b->next_bio == NULL) return(0);
+		BIO_clear_retry_flags(b);
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		BIO_copy_next_retry(b);
+		break;
+
+	case BIO_CTRL_FLUSH:
+		if (b->next_bio == NULL) return(0);
+		if (ctx->obuf_len <= 0)
+			{
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+			break;
+			}
+
+		for (;;)
+			{
+			BIO_clear_retry_flags(b);
+			if (ctx->obuf_len > 0)
+				{
+				r=BIO_write(b->next_bio,
+					&(ctx->obuf[ctx->obuf_off]),
+					ctx->obuf_len);
+#if 0
+fprintf(stderr,"FLUSH [%3d] %3d -> %3d\n",ctx->obuf_off,ctx->obuf_len,r);
+#endif
+				BIO_copy_next_retry(b);
+				if (r <= 0) return((long)r);
+				ctx->obuf_off+=r;
+				ctx->obuf_len-=r;
+				}
+			else
+				{
+				ctx->obuf_len=0;
+				ctx->obuf_off=0;
+				ret=1;
+				break;
+				}
+			}
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_DUP:
+		dbio=(BIO *)ptr;
+		if (	!BIO_set_read_buffer_size(dbio,ctx->ibuf_size) ||
+			!BIO_set_write_buffer_size(dbio,ctx->obuf_size))
+			ret=0;
+		break;
+	default:
+		if (b->next_bio == NULL) return(0);
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+		}
+	return(ret);
+malloc_error:
+	BIOerr(BIO_F_BUFFER_CTRL,ERR_R_MALLOC_FAILURE);
+	return(0);
+	}
+
+static long buffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+	{
+	long ret=1;
+
+	if (b->next_bio == NULL) return(0);
+	switch (cmd)
+		{
+	default:
+		ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+		break;
+		}
+	return(ret);
+	}
+
+static int buffer_gets(BIO *b, char *buf, int size)
+	{
+	BIO_F_BUFFER_CTX *ctx;
+	int num=0,i,flag;
+	char *p;
+
+	ctx=(BIO_F_BUFFER_CTX *)b->ptr;
+	size--; /* reserve space for a '\0' */
+	BIO_clear_retry_flags(b);
+
+	for (;;)
+		{
+		if (ctx->ibuf_len > 0)
+			{
+			p= &(ctx->ibuf[ctx->ibuf_off]);
+			flag=0;
+			for (i=0; (i<ctx->ibuf_len) && (i<size); i++)
+				{
+				*(buf++)=p[i];
+				if (p[i] == '\n')
+					{
+					flag=1;
+					i++;
+					break;
+					}
+				}
+			num+=i;
+			size-=i;
+			ctx->ibuf_len-=i;
+			ctx->ibuf_off+=i;
+			if (flag || size == 0)
+				{
+				*buf='\0';
+				return(num);
+				}
+			}
+		else	/* read another chunk */
+			{
+			i=BIO_read(b->next_bio,ctx->ibuf,ctx->ibuf_size);
+			if (i <= 0)
+				{
+				BIO_copy_next_retry(b);
+				*buf='\0';
+				if (i < 0) return((num > 0)?num:i);
+				if (i == 0) return(num);
+				}
+			ctx->ibuf_len=i;
+			ctx->ibuf_off=0;
+			}
+		}
+	}
+
+static int buffer_puts(BIO *b, const char *str)
+	{
+	return(buffer_write(b,str,strlen(str)));
+	}
+
diff --git a/openssl/crypto/bio/bf_lbuf.c b/openssl/crypto/bio/bf_lbuf.c
new file mode 100644
index 0000000..ec0f7eb
--- /dev/null
+++ b/openssl/crypto/bio/bf_lbuf.c
@@ -0,0 +1,397 @@
+/* crypto/bio/bf_buff.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+
+static int linebuffer_write(BIO *h, const char *buf,int num);
+static int linebuffer_read(BIO *h, char *buf, int size);
+static int linebuffer_puts(BIO *h, const char *str);
+static int linebuffer_gets(BIO *h, char *str, int size);
+static long linebuffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int linebuffer_new(BIO *h);
+static int linebuffer_free(BIO *data);
+static long linebuffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+/* A 10k maximum should be enough for most purposes */
+#define DEFAULT_LINEBUFFER_SIZE	1024*10
+
+/* #define DEBUG */
+
+static BIO_METHOD methods_linebuffer=
+	{
+	BIO_TYPE_LINEBUFFER,
+	"linebuffer",
+	linebuffer_write,
+	linebuffer_read,
+	linebuffer_puts,
+	linebuffer_gets,
+	linebuffer_ctrl,
+	linebuffer_new,
+	linebuffer_free,
+	linebuffer_callback_ctrl,
+	};
+
+BIO_METHOD *BIO_f_linebuffer(void)
+	{
+	return(&methods_linebuffer);
+	}
+
+typedef struct bio_linebuffer_ctx_struct
+	{
+	char *obuf;		/* the output char array */
+	int obuf_size;		/* how big is the output buffer */
+	int obuf_len;		/* how many bytes are in it */
+	} BIO_LINEBUFFER_CTX;
+
+static int linebuffer_new(BIO *bi)
+	{
+	BIO_LINEBUFFER_CTX *ctx;
+
+	ctx=(BIO_LINEBUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_LINEBUFFER_CTX));
+	if (ctx == NULL) return(0);
+	ctx->obuf=(char *)OPENSSL_malloc(DEFAULT_LINEBUFFER_SIZE);
+	if (ctx->obuf == NULL) { OPENSSL_free(ctx); return(0); }
+	ctx->obuf_size=DEFAULT_LINEBUFFER_SIZE;
+	ctx->obuf_len=0;
+
+	bi->init=1;
+	bi->ptr=(char *)ctx;
+	bi->flags=0;
+	return(1);
+	}
+
+static int linebuffer_free(BIO *a)
+	{
+	BIO_LINEBUFFER_CTX *b;
+
+	if (a == NULL) return(0);
+	b=(BIO_LINEBUFFER_CTX *)a->ptr;
+	if (b->obuf != NULL) OPENSSL_free(b->obuf);
+	OPENSSL_free(a->ptr);
+	a->ptr=NULL;
+	a->init=0;
+	a->flags=0;
+	return(1);
+	}
+	
+static int linebuffer_read(BIO *b, char *out, int outl)
+	{
+	int ret=0;
+ 
+	if (out == NULL) return(0);
+	if (b->next_bio == NULL) return(0);
+	ret=BIO_read(b->next_bio,out,outl);
+	BIO_clear_retry_flags(b);
+	BIO_copy_next_retry(b);
+	return(ret);
+	}
+
+static int linebuffer_write(BIO *b, const char *in, int inl)
+	{
+	int i,num=0,foundnl;
+	BIO_LINEBUFFER_CTX *ctx;
+
+	if ((in == NULL) || (inl <= 0)) return(0);
+	ctx=(BIO_LINEBUFFER_CTX *)b->ptr;
+	if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
+
+	BIO_clear_retry_flags(b);
+
+	do
+		{
+		const char *p;
+
+		for(p = in; p < in + inl && *p != '\n'; p++)
+			;
+		if (*p == '\n')
+			{
+			p++;
+			foundnl = 1;
+			}
+		else
+			foundnl = 0;
+
+		/* If a NL was found and we already have text in the save
+		   buffer, concatenate them and write */
+		while ((foundnl || p - in > ctx->obuf_size - ctx->obuf_len)
+			&& ctx->obuf_len > 0)
+			{
+			int orig_olen = ctx->obuf_len;
+			
+			i = ctx->obuf_size - ctx->obuf_len;
+			if (p - in > 0)
+				{
+				if (i >= p - in)
+					{
+					memcpy(&(ctx->obuf[ctx->obuf_len]),
+						in,p - in);
+					ctx->obuf_len += p - in;
+					inl -= p - in;
+					num += p - in;
+					in = p;
+					}
+				else
+					{
+					memcpy(&(ctx->obuf[ctx->obuf_len]),
+						in,i);
+					ctx->obuf_len += i;
+					inl -= i;
+					in += i;
+					num += i;
+					}
+				}
+
+#if 0
+BIO_write(b->next_bio, "<*<", 3);
+#endif
+			i=BIO_write(b->next_bio,
+				ctx->obuf, ctx->obuf_len);
+			if (i <= 0)
+				{
+				ctx->obuf_len = orig_olen;
+				BIO_copy_next_retry(b);
+
+#if 0
+BIO_write(b->next_bio, ">*>", 3);
+#endif
+				if (i < 0) return((num > 0)?num:i);
+				if (i == 0) return(num);
+				}
+#if 0
+BIO_write(b->next_bio, ">*>", 3);
+#endif
+			if (i < ctx->obuf_len)
+				memmove(ctx->obuf, ctx->obuf + i,
+					ctx->obuf_len - i);
+			ctx->obuf_len-=i;
+			}
+
+		/* Now that the save buffer is emptied, let's write the input
+		   buffer if a NL was found and there is anything to write. */
+		if ((foundnl || p - in > ctx->obuf_size) && p - in > 0)
+			{
+#if 0
+BIO_write(b->next_bio, "<*<", 3);
+#endif
+			i=BIO_write(b->next_bio,in,p - in);
+			if (i <= 0)
+				{
+				BIO_copy_next_retry(b);
+#if 0
+BIO_write(b->next_bio, ">*>", 3);
+#endif
+				if (i < 0) return((num > 0)?num:i);
+				if (i == 0) return(num);
+				}
+#if 0
+BIO_write(b->next_bio, ">*>", 3);
+#endif
+			num+=i;
+			in+=i;
+			inl-=i;
+			}
+		}
+	while(foundnl && inl > 0);
+	/* We've written as much as we can.  The rest of the input buffer, if
+	   any, is text that doesn't and with a NL and therefore needs to be
+	   saved for the next trip. */
+	if (inl > 0)
+		{
+		memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl);
+		ctx->obuf_len += inl;
+		num += inl;
+		}
+	return num;
+	}
+
+static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	BIO *dbio;
+	BIO_LINEBUFFER_CTX *ctx;
+	long ret=1;
+	char *p;
+	int r;
+	int obs;
+
+	ctx=(BIO_LINEBUFFER_CTX *)b->ptr;
+
+	switch (cmd)
+		{
+	case BIO_CTRL_RESET:
+		ctx->obuf_len=0;
+		if (b->next_bio == NULL) return(0);
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_INFO:
+		ret=(long)ctx->obuf_len;
+		break;
+	case BIO_CTRL_WPENDING:
+		ret=(long)ctx->obuf_len;
+		if (ret == 0)
+			{
+			if (b->next_bio == NULL) return(0);
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+			}
+		break;
+	case BIO_C_SET_BUFF_SIZE:
+		obs=(int)num;
+		p=ctx->obuf;
+		if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size))
+			{
+			p=(char *)OPENSSL_malloc((int)num);
+			if (p == NULL)
+				goto malloc_error;
+			}
+		if (ctx->obuf != p)
+			{
+			if (ctx->obuf_len > obs)
+				{
+				ctx->obuf_len = obs;
+				}
+			memcpy(p, ctx->obuf, ctx->obuf_len);
+			OPENSSL_free(ctx->obuf);
+			ctx->obuf=p;
+			ctx->obuf_size=obs;
+			}
+		break;
+	case BIO_C_DO_STATE_MACHINE:
+		if (b->next_bio == NULL) return(0);
+		BIO_clear_retry_flags(b);
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		BIO_copy_next_retry(b);
+		break;
+
+	case BIO_CTRL_FLUSH:
+		if (b->next_bio == NULL) return(0);
+		if (ctx->obuf_len <= 0)
+			{
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+			break;
+			}
+
+		for (;;)
+			{
+			BIO_clear_retry_flags(b);
+			if (ctx->obuf_len > 0)
+				{
+				r=BIO_write(b->next_bio,
+					ctx->obuf, ctx->obuf_len);
+#if 0
+fprintf(stderr,"FLUSH %3d -> %3d\n",ctx->obuf_len,r);
+#endif
+				BIO_copy_next_retry(b);
+				if (r <= 0) return((long)r);
+				if (r < ctx->obuf_len)
+					memmove(ctx->obuf, ctx->obuf + r,
+						ctx->obuf_len - r);
+				ctx->obuf_len-=r;
+				}
+			else
+				{
+				ctx->obuf_len=0;
+				ret=1;
+				break;
+				}
+			}
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_DUP:
+		dbio=(BIO *)ptr;
+		if (	!BIO_set_write_buffer_size(dbio,ctx->obuf_size))
+			ret=0;
+		break;
+	default:
+		if (b->next_bio == NULL) return(0);
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+		}
+	return(ret);
+malloc_error:
+	BIOerr(BIO_F_LINEBUFFER_CTRL,ERR_R_MALLOC_FAILURE);
+	return(0);
+	}
+
+static long linebuffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+	{
+	long ret=1;
+
+	if (b->next_bio == NULL) return(0);
+	switch (cmd)
+		{
+	default:
+		ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+		break;
+		}
+	return(ret);
+	}
+
+static int linebuffer_gets(BIO *b, char *buf, int size)
+	{
+	if (b->next_bio == NULL) return(0);
+	return(BIO_gets(b->next_bio,buf,size));
+	}
+
+static int linebuffer_puts(BIO *b, const char *str)
+	{
+	return(linebuffer_write(b,str,strlen(str)));
+	}
+
diff --git a/openssl/crypto/bio/bf_nbio.c b/openssl/crypto/bio/bf_nbio.c
new file mode 100644
index 0000000..028616c
--- /dev/null
+++ b/openssl/crypto/bio/bf_nbio.c
@@ -0,0 +1,253 @@
+/* crypto/bio/bf_nbio.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#include <openssl/bio.h>
+
+/* BIO_put and BIO_get both add to the digest,
+ * BIO_gets returns the digest */
+
+static int nbiof_write(BIO *h,const char *buf,int num);
+static int nbiof_read(BIO *h,char *buf,int size);
+static int nbiof_puts(BIO *h,const char *str);
+static int nbiof_gets(BIO *h,char *str,int size);
+static long nbiof_ctrl(BIO *h,int cmd,long arg1,void *arg2);
+static int nbiof_new(BIO *h);
+static int nbiof_free(BIO *data);
+static long nbiof_callback_ctrl(BIO *h,int cmd,bio_info_cb *fp);
+typedef struct nbio_test_st
+	{
+	/* only set if we sent a 'should retry' error */
+	int lrn;
+	int lwn;
+	} NBIO_TEST;
+
+static BIO_METHOD methods_nbiof=
+	{
+	BIO_TYPE_NBIO_TEST,
+	"non-blocking IO test filter",
+	nbiof_write,
+	nbiof_read,
+	nbiof_puts,
+	nbiof_gets,
+	nbiof_ctrl,
+	nbiof_new,
+	nbiof_free,
+	nbiof_callback_ctrl,
+	};
+
+BIO_METHOD *BIO_f_nbio_test(void)
+	{
+	return(&methods_nbiof);
+	}
+
+static int nbiof_new(BIO *bi)
+	{
+	NBIO_TEST *nt;
+
+	if (!(nt=(NBIO_TEST *)OPENSSL_malloc(sizeof(NBIO_TEST)))) return(0);
+	nt->lrn= -1;
+	nt->lwn= -1;
+	bi->ptr=(char *)nt;
+	bi->init=1;
+	bi->flags=0;
+	return(1);
+	}
+
+static int nbiof_free(BIO *a)
+	{
+	if (a == NULL) return(0);
+	if (a->ptr != NULL)
+		OPENSSL_free(a->ptr);
+	a->ptr=NULL;
+	a->init=0;
+	a->flags=0;
+	return(1);
+	}
+	
+static int nbiof_read(BIO *b, char *out, int outl)
+	{
+	int ret=0;
+#if 1
+	int num;
+	unsigned char n;
+#endif
+
+	if (out == NULL) return(0);
+	if (b->next_bio == NULL) return(0);
+
+	BIO_clear_retry_flags(b);
+#if 1
+	RAND_pseudo_bytes(&n,1);
+	num=(n&0x07);
+
+	if (outl > num) outl=num;
+
+	if (num == 0)
+		{
+		ret= -1;
+		BIO_set_retry_read(b);
+		}
+	else
+#endif
+		{
+		ret=BIO_read(b->next_bio,out,outl);
+		if (ret < 0)
+			BIO_copy_next_retry(b);
+		}
+	return(ret);
+	}
+
+static int nbiof_write(BIO *b, const char *in, int inl)
+	{
+	NBIO_TEST *nt;
+	int ret=0;
+	int num;
+	unsigned char n;
+
+	if ((in == NULL) || (inl <= 0)) return(0);
+	if (b->next_bio == NULL) return(0);
+	nt=(NBIO_TEST *)b->ptr;
+
+	BIO_clear_retry_flags(b);
+
+#if 1
+	if (nt->lwn > 0)
+		{
+		num=nt->lwn;
+		nt->lwn=0;
+		}
+	else
+		{
+		RAND_pseudo_bytes(&n,1);
+		num=(n&7);
+		}
+
+	if (inl > num) inl=num;
+
+	if (num == 0)
+		{
+		ret= -1;
+		BIO_set_retry_write(b);
+		}
+	else
+#endif
+		{
+		ret=BIO_write(b->next_bio,in,inl);
+		if (ret < 0)
+			{
+			BIO_copy_next_retry(b);
+			nt->lwn=inl;
+			}
+		}
+	return(ret);
+	}
+
+static long nbiof_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	long ret;
+
+	if (b->next_bio == NULL) return(0);
+	switch (cmd)
+		{
+        case BIO_C_DO_STATE_MACHINE:
+		BIO_clear_retry_flags(b);
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		BIO_copy_next_retry(b);
+		break;
+	case BIO_CTRL_DUP:
+		ret=0L;
+		break;
+	default:
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+		}
+	return(ret);
+	}
+
+static long nbiof_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+	{
+	long ret=1;
+
+	if (b->next_bio == NULL) return(0);
+	switch (cmd)
+		{
+	default:
+		ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+		break;
+		}
+	return(ret);
+	}
+
+static int nbiof_gets(BIO *bp, char *buf, int size)
+	{
+	if (bp->next_bio == NULL) return(0);
+	return(BIO_gets(bp->next_bio,buf,size));
+	}
+
+
+static int nbiof_puts(BIO *bp, const char *str)
+	{
+	if (bp->next_bio == NULL) return(0);
+	return(BIO_puts(bp->next_bio,str));
+	}
+
+
diff --git a/openssl/crypto/bio/bf_null.c b/openssl/crypto/bio/bf_null.c
new file mode 100644
index 0000000..c1bf39a
--- /dev/null
+++ b/openssl/crypto/bio/bf_null.c
@@ -0,0 +1,183 @@
+/* crypto/bio/bf_null.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+
+/* BIO_put and BIO_get both add to the digest,
+ * BIO_gets returns the digest */
+
+static int nullf_write(BIO *h, const char *buf, int num);
+static int nullf_read(BIO *h, char *buf, int size);
+static int nullf_puts(BIO *h, const char *str);
+static int nullf_gets(BIO *h, char *str, int size);
+static long nullf_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int nullf_new(BIO *h);
+static int nullf_free(BIO *data);
+static long nullf_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+static BIO_METHOD methods_nullf=
+	{
+	BIO_TYPE_NULL_FILTER,
+	"NULL filter",
+	nullf_write,
+	nullf_read,
+	nullf_puts,
+	nullf_gets,
+	nullf_ctrl,
+	nullf_new,
+	nullf_free,
+	nullf_callback_ctrl,
+	};
+
+BIO_METHOD *BIO_f_null(void)
+	{
+	return(&methods_nullf);
+	}
+
+static int nullf_new(BIO *bi)
+	{
+	bi->init=1;
+	bi->ptr=NULL;
+	bi->flags=0;
+	return(1);
+	}
+
+static int nullf_free(BIO *a)
+	{
+	if (a == NULL) return(0);
+/*	a->ptr=NULL;
+	a->init=0;
+	a->flags=0;*/
+	return(1);
+	}
+	
+static int nullf_read(BIO *b, char *out, int outl)
+	{
+	int ret=0;
+ 
+	if (out == NULL) return(0);
+	if (b->next_bio == NULL) return(0);
+	ret=BIO_read(b->next_bio,out,outl);
+	BIO_clear_retry_flags(b);
+	BIO_copy_next_retry(b);
+	return(ret);
+	}
+
+static int nullf_write(BIO *b, const char *in, int inl)
+	{
+	int ret=0;
+
+	if ((in == NULL) || (inl <= 0)) return(0);
+	if (b->next_bio == NULL) return(0);
+	ret=BIO_write(b->next_bio,in,inl);
+	BIO_clear_retry_flags(b);
+	BIO_copy_next_retry(b);
+	return(ret);
+	}
+
+static long nullf_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	long ret;
+
+	if (b->next_bio == NULL) return(0);
+	switch(cmd)
+		{
+        case BIO_C_DO_STATE_MACHINE:
+		BIO_clear_retry_flags(b);
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		BIO_copy_next_retry(b);
+		break;
+	case BIO_CTRL_DUP:
+		ret=0L;
+		break;
+	default:
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		}
+	return(ret);
+	}
+
+static long nullf_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+	{
+	long ret=1;
+
+	if (b->next_bio == NULL) return(0);
+	switch (cmd)
+		{
+	default:
+		ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+		break;
+		}
+	return(ret);
+	}
+
+static int nullf_gets(BIO *bp, char *buf, int size)
+	{
+	if (bp->next_bio == NULL) return(0);
+	return(BIO_gets(bp->next_bio,buf,size));
+	}
+
+
+static int nullf_puts(BIO *bp, const char *str)
+	{
+	if (bp->next_bio == NULL) return(0);
+	return(BIO_puts(bp->next_bio,str));
+	}
+
+
diff --git a/openssl/crypto/bio/bio.h b/openssl/crypto/bio/bio.h
new file mode 100644
index 0000000..ab47abc
--- /dev/null
+++ b/openssl/crypto/bio/bio.h
@@ -0,0 +1,779 @@
+/* crypto/bio/bio.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BIO_H
+#define HEADER_BIO_H
+
+#include <openssl/e_os2.h>
+
+#ifndef OPENSSL_NO_FP_API
+# include <stdio.h>
+#endif
+#include <stdarg.h>
+
+#include <openssl/crypto.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* These are the 'types' of BIOs */
+#define BIO_TYPE_NONE		0
+#define BIO_TYPE_MEM		(1|0x0400)
+#define BIO_TYPE_FILE		(2|0x0400)
+
+#define BIO_TYPE_FD		(4|0x0400|0x0100)
+#define BIO_TYPE_SOCKET		(5|0x0400|0x0100)
+#define BIO_TYPE_NULL		(6|0x0400)
+#define BIO_TYPE_SSL		(7|0x0200)
+#define BIO_TYPE_MD		(8|0x0200)		/* passive filter */
+#define BIO_TYPE_BUFFER		(9|0x0200)		/* filter */
+#define BIO_TYPE_CIPHER		(10|0x0200)		/* filter */
+#define BIO_TYPE_BASE64		(11|0x0200)		/* filter */
+#define BIO_TYPE_CONNECT	(12|0x0400|0x0100)	/* socket - connect */
+#define BIO_TYPE_ACCEPT		(13|0x0400|0x0100)	/* socket for accept */
+#define BIO_TYPE_PROXY_CLIENT	(14|0x0200)		/* client proxy BIO */
+#define BIO_TYPE_PROXY_SERVER	(15|0x0200)		/* server proxy BIO */
+#define BIO_TYPE_NBIO_TEST	(16|0x0200)		/* server proxy BIO */
+#define BIO_TYPE_NULL_FILTER	(17|0x0200)
+#define BIO_TYPE_BER		(18|0x0200)		/* BER -> bin filter */
+#define BIO_TYPE_BIO		(19|0x0400)		/* (half a) BIO pair */
+#define BIO_TYPE_LINEBUFFER	(20|0x0200)		/* filter */
+#define BIO_TYPE_DGRAM		(21|0x0400|0x0100)
+#define BIO_TYPE_ASN1 		(22|0x0200)		/* filter */
+#define BIO_TYPE_COMP 		(23|0x0200)		/* filter */
+
+#define BIO_TYPE_DESCRIPTOR	0x0100	/* socket, fd, connect or accept */
+#define BIO_TYPE_FILTER		0x0200
+#define BIO_TYPE_SOURCE_SINK	0x0400
+
+/* BIO_FILENAME_READ|BIO_CLOSE to open or close on free.
+ * BIO_set_fp(in,stdin,BIO_NOCLOSE); */
+#define BIO_NOCLOSE		0x00
+#define BIO_CLOSE		0x01
+
+/* These are used in the following macros and are passed to
+ * BIO_ctrl() */
+#define BIO_CTRL_RESET		1  /* opt - rewind/zero etc */
+#define BIO_CTRL_EOF		2  /* opt - are we at the eof */
+#define BIO_CTRL_INFO		3  /* opt - extra tit-bits */
+#define BIO_CTRL_SET		4  /* man - set the 'IO' type */
+#define BIO_CTRL_GET		5  /* man - get the 'IO' type */
+#define BIO_CTRL_PUSH		6  /* opt - internal, used to signify change */
+#define BIO_CTRL_POP		7  /* opt - internal, used to signify change */
+#define BIO_CTRL_GET_CLOSE	8  /* man - set the 'close' on free */
+#define BIO_CTRL_SET_CLOSE	9  /* man - set the 'close' on free */
+#define BIO_CTRL_PENDING	10  /* opt - is their more data buffered */
+#define BIO_CTRL_FLUSH		11  /* opt - 'flush' buffered output */
+#define BIO_CTRL_DUP		12  /* man - extra stuff for 'duped' BIO */
+#define BIO_CTRL_WPENDING	13  /* opt - number of bytes still to write */
+/* callback is int cb(BIO *bio,state,ret); */
+#define BIO_CTRL_SET_CALLBACK	14  /* opt - set callback function */
+#define BIO_CTRL_GET_CALLBACK	15  /* opt - set callback function */
+
+#define BIO_CTRL_SET_FILENAME	30	/* BIO_s_file special */
+
+/* dgram BIO stuff */
+#define BIO_CTRL_DGRAM_CONNECT       31  /* BIO dgram special */
+#define BIO_CTRL_DGRAM_SET_CONNECTED 32  /* allow for an externally
+					  * connected socket to be
+					  * passed in */ 
+#define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33 /* setsockopt, essentially */
+#define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34 /* getsockopt, essentially */
+#define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35 /* setsockopt, essentially */
+#define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36 /* getsockopt, essentially */
+
+#define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37 /* flag whether the last */
+#define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38 /* I/O operation tiemd out */
+					
+/* #ifdef IP_MTU_DISCOVER */
+#define BIO_CTRL_DGRAM_MTU_DISCOVER       39 /* set DF bit on egress packets */
+/* #endif */
+
+#define BIO_CTRL_DGRAM_QUERY_MTU          40 /* as kernel for current MTU */
+#define BIO_CTRL_DGRAM_GET_MTU            41 /* get cached value for MTU */
+#define BIO_CTRL_DGRAM_SET_MTU            42 /* set cached value for
+					      * MTU. want to use this
+					      * if asking the kernel
+					      * fails */
+
+#define BIO_CTRL_DGRAM_MTU_EXCEEDED       43 /* check whether the MTU
+					      * was exceed in the
+					      * previous write
+					      * operation */
+
+#define BIO_CTRL_DGRAM_GET_PEER           46
+#define BIO_CTRL_DGRAM_SET_PEER           44 /* Destination for the data */
+
+#define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT   45 /* Next DTLS handshake timeout to
+											  * adjust socket timeouts */
+
+/* modifiers */
+#define BIO_FP_READ		0x02
+#define BIO_FP_WRITE		0x04
+#define BIO_FP_APPEND		0x08
+#define BIO_FP_TEXT		0x10
+
+#define BIO_FLAGS_READ		0x01
+#define BIO_FLAGS_WRITE		0x02
+#define BIO_FLAGS_IO_SPECIAL	0x04
+#define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL)
+#define BIO_FLAGS_SHOULD_RETRY	0x08
+#ifndef	BIO_FLAGS_UPLINK
+/* "UPLINK" flag denotes file descriptors provided by application.
+   It defaults to 0, as most platforms don't require UPLINK interface. */
+#define	BIO_FLAGS_UPLINK	0
+#endif
+
+/* Used in BIO_gethostbyname() */
+#define BIO_GHBN_CTRL_HITS		1
+#define BIO_GHBN_CTRL_MISSES		2
+#define BIO_GHBN_CTRL_CACHE_SIZE	3
+#define BIO_GHBN_CTRL_GET_ENTRY		4
+#define BIO_GHBN_CTRL_FLUSH		5
+
+/* Mostly used in the SSL BIO */
+/* Not used anymore
+ * #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10
+ * #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20
+ * #define BIO_FLAGS_PROTOCOL_STARTUP	0x40
+ */
+
+#define BIO_FLAGS_BASE64_NO_NL	0x100
+
+/* This is used with memory BIOs: it means we shouldn't free up or change the
+ * data in any way.
+ */
+#define BIO_FLAGS_MEM_RDONLY	0x200
+
+typedef struct bio_st BIO;
+
+void BIO_set_flags(BIO *b, int flags);
+int  BIO_test_flags(const BIO *b, int flags);
+void BIO_clear_flags(BIO *b, int flags);
+
+#define BIO_get_flags(b) BIO_test_flags(b, ~(0x0))
+#define BIO_set_retry_special(b) \
+		BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY))
+#define BIO_set_retry_read(b) \
+		BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY))
+#define BIO_set_retry_write(b) \
+		BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY))
+
+/* These are normally used internally in BIOs */
+#define BIO_clear_retry_flags(b) \
+		BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+#define BIO_get_retry_flags(b) \
+		BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+
+/* These should be used by the application to tell why we should retry */
+#define BIO_should_read(a)		BIO_test_flags(a, BIO_FLAGS_READ)
+#define BIO_should_write(a)		BIO_test_flags(a, BIO_FLAGS_WRITE)
+#define BIO_should_io_special(a)	BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL)
+#define BIO_retry_type(a)		BIO_test_flags(a, BIO_FLAGS_RWS)
+#define BIO_should_retry(a)		BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY)
+
+/* The next three are used in conjunction with the
+ * BIO_should_io_special() condition.  After this returns true,
+ * BIO *BIO_get_retry_BIO(BIO *bio, int *reason); will walk the BIO 
+ * stack and return the 'reason' for the special and the offending BIO.
+ * Given a BIO, BIO_get_retry_reason(bio) will return the code. */
+/* Returned from the SSL bio when the certificate retrieval code had an error */
+#define BIO_RR_SSL_X509_LOOKUP		0x01
+/* Returned from the connect BIO when a connect would have blocked */
+#define BIO_RR_CONNECT			0x02
+/* Returned from the accept BIO when an accept would have blocked */
+#define BIO_RR_ACCEPT			0x03
+
+/* These are passed by the BIO callback */
+#define BIO_CB_FREE	0x01
+#define BIO_CB_READ	0x02
+#define BIO_CB_WRITE	0x03
+#define BIO_CB_PUTS	0x04
+#define BIO_CB_GETS	0x05
+#define BIO_CB_CTRL	0x06
+
+/* The callback is called before and after the underling operation,
+ * The BIO_CB_RETURN flag indicates if it is after the call */
+#define BIO_CB_RETURN	0x80
+#define BIO_CB_return(a) ((a)|BIO_CB_RETURN))
+#define BIO_cb_pre(a)	(!((a)&BIO_CB_RETURN))
+#define BIO_cb_post(a)	((a)&BIO_CB_RETURN)
+
+long (*BIO_get_callback(const BIO *b)) (struct bio_st *,int,const char *,int, long,long);
+void BIO_set_callback(BIO *b, 
+	long (*callback)(struct bio_st *,int,const char *,int, long,long));
+char *BIO_get_callback_arg(const BIO *b);
+void BIO_set_callback_arg(BIO *b, char *arg);
+
+const char * BIO_method_name(const BIO *b);
+int BIO_method_type(const BIO *b);
+
+typedef void bio_info_cb(struct bio_st *, int, const char *, int, long, long);
+
+typedef struct bio_method_st
+	{
+	int type;
+	const char *name;
+	int (*bwrite)(BIO *, const char *, int);
+	int (*bread)(BIO *, char *, int);
+	int (*bputs)(BIO *, const char *);
+	int (*bgets)(BIO *, char *, int);
+	long (*ctrl)(BIO *, int, long, void *);
+	int (*create)(BIO *);
+	int (*destroy)(BIO *);
+        long (*callback_ctrl)(BIO *, int, bio_info_cb *);
+	} BIO_METHOD;
+
+struct bio_st
+	{
+	BIO_METHOD *method;
+	/* bio, mode, argp, argi, argl, ret */
+	long (*callback)(struct bio_st *,int,const char *,int, long,long);
+	char *cb_arg; /* first argument for the callback */
+
+	int init;
+	int shutdown;
+	int flags;	/* extra storage */
+	int retry_reason;
+	int num;
+	void *ptr;
+	struct bio_st *next_bio;	/* used by filter BIOs */
+	struct bio_st *prev_bio;	/* used by filter BIOs */
+	int references;
+	unsigned long num_read;
+	unsigned long num_write;
+
+	CRYPTO_EX_DATA ex_data;
+	};
+
+DECLARE_STACK_OF(BIO)
+
+typedef struct bio_f_buffer_ctx_struct
+	{
+	/* Buffers are setup like this:
+	 *
+	 * <---------------------- size ----------------------->
+	 * +---------------------------------------------------+
+	 * | consumed | remaining          | free space        |
+	 * +---------------------------------------------------+
+	 * <-- off --><------- len ------->
+	 */
+
+	/* BIO *bio; */ /* this is now in the BIO struct */
+	int ibuf_size;	/* how big is the input buffer */
+	int obuf_size;	/* how big is the output buffer */
+
+	char *ibuf;		/* the char array */
+	int ibuf_len;		/* how many bytes are in it */
+	int ibuf_off;		/* write/read offset */
+
+	char *obuf;		/* the char array */
+	int obuf_len;		/* how many bytes are in it */
+	int obuf_off;		/* write/read offset */
+	} BIO_F_BUFFER_CTX;
+
+/* Prefix and suffix callback in ASN1 BIO */
+typedef int asn1_ps_func(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+
+/* connect BIO stuff */
+#define BIO_CONN_S_BEFORE		1
+#define BIO_CONN_S_GET_IP		2
+#define BIO_CONN_S_GET_PORT		3
+#define BIO_CONN_S_CREATE_SOCKET	4
+#define BIO_CONN_S_CONNECT		5
+#define BIO_CONN_S_OK			6
+#define BIO_CONN_S_BLOCKED_CONNECT	7
+#define BIO_CONN_S_NBIO			8
+/*#define BIO_CONN_get_param_hostname	BIO_ctrl */
+
+#define BIO_C_SET_CONNECT			100
+#define BIO_C_DO_STATE_MACHINE			101
+#define BIO_C_SET_NBIO				102
+#define BIO_C_SET_PROXY_PARAM			103
+#define BIO_C_SET_FD				104
+#define BIO_C_GET_FD				105
+#define BIO_C_SET_FILE_PTR			106
+#define BIO_C_GET_FILE_PTR			107
+#define BIO_C_SET_FILENAME			108
+#define BIO_C_SET_SSL				109
+#define BIO_C_GET_SSL				110
+#define BIO_C_SET_MD				111
+#define BIO_C_GET_MD				112
+#define BIO_C_GET_CIPHER_STATUS			113
+#define BIO_C_SET_BUF_MEM			114
+#define BIO_C_GET_BUF_MEM_PTR			115
+#define BIO_C_GET_BUFF_NUM_LINES		116
+#define BIO_C_SET_BUFF_SIZE			117
+#define BIO_C_SET_ACCEPT			118
+#define BIO_C_SSL_MODE				119
+#define BIO_C_GET_MD_CTX			120
+#define BIO_C_GET_PROXY_PARAM			121
+#define BIO_C_SET_BUFF_READ_DATA		122 /* data to read first */
+#define BIO_C_GET_CONNECT			123
+#define BIO_C_GET_ACCEPT			124
+#define BIO_C_SET_SSL_RENEGOTIATE_BYTES		125
+#define BIO_C_GET_SSL_NUM_RENEGOTIATES		126
+#define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT	127
+#define BIO_C_FILE_SEEK				128
+#define BIO_C_GET_CIPHER_CTX			129
+#define BIO_C_SET_BUF_MEM_EOF_RETURN		130/*return end of input value*/
+#define BIO_C_SET_BIND_MODE			131
+#define BIO_C_GET_BIND_MODE			132
+#define BIO_C_FILE_TELL				133
+#define BIO_C_GET_SOCKS				134
+#define BIO_C_SET_SOCKS				135
+
+#define BIO_C_SET_WRITE_BUF_SIZE		136/* for BIO_s_bio */
+#define BIO_C_GET_WRITE_BUF_SIZE		137
+#define BIO_C_MAKE_BIO_PAIR			138
+#define BIO_C_DESTROY_BIO_PAIR			139
+#define BIO_C_GET_WRITE_GUARANTEE		140
+#define BIO_C_GET_READ_REQUEST			141
+#define BIO_C_SHUTDOWN_WR			142
+#define BIO_C_NREAD0				143
+#define BIO_C_NREAD				144
+#define BIO_C_NWRITE0				145
+#define BIO_C_NWRITE				146
+#define BIO_C_RESET_READ_REQUEST		147
+#define BIO_C_SET_MD_CTX			148
+
+#define BIO_C_SET_PREFIX			149
+#define BIO_C_GET_PREFIX			150
+#define BIO_C_SET_SUFFIX			151
+#define BIO_C_GET_SUFFIX			152
+
+#define BIO_C_SET_EX_ARG			153
+#define BIO_C_GET_EX_ARG			154
+
+#define BIO_set_app_data(s,arg)		BIO_set_ex_data(s,0,arg)
+#define BIO_get_app_data(s)		BIO_get_ex_data(s,0)
+
+/* BIO_s_connect() and BIO_s_socks4a_connect() */
+#define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name)
+#define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port)
+#define BIO_set_conn_ip(b,ip)	  BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip)
+#define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port)
+#define BIO_get_conn_hostname(b)  BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0)
+#define BIO_get_conn_port(b)      BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)
+#define BIO_get_conn_ip(b) 		 BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2)
+#define BIO_get_conn_int_port(b) BIO_int_ctrl(b,BIO_C_GET_CONNECT,3,0)
+
+
+#define BIO_set_nbio(b,n)	BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)
+
+/* BIO_s_accept_socket() */
+#define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name)
+#define BIO_get_accept_port(b)	BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0)
+/* #define BIO_set_nbio(b,n)	BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */
+#define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?(void *)"a":NULL)
+#define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio)
+
+#define BIO_BIND_NORMAL			0
+#define BIO_BIND_REUSEADDR_IF_UNUSED	1
+#define BIO_BIND_REUSEADDR		2
+#define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL)
+#define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL)
+
+#define BIO_do_connect(b)	BIO_do_handshake(b)
+#define BIO_do_accept(b)	BIO_do_handshake(b)
+#define BIO_do_handshake(b)	BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL)
+
+/* BIO_s_proxy_client() */
+#define BIO_set_url(b,url)	BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url))
+#define BIO_set_proxies(b,p)	BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p))
+/* BIO_set_nbio(b,n) */
+#define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s))
+/* BIO *BIO_get_filter_bio(BIO *bio); */
+#define BIO_set_proxy_cb(b,cb) BIO_callback_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(void *(*cb)()))
+#define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk)
+#define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool)
+
+#define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp)
+#define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p))
+#define BIO_get_url(b,url)	BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url))
+#define BIO_get_no_connect_return(b)	BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL)
+
+#define BIO_set_fd(b,fd,c)	BIO_int_ctrl(b,BIO_C_SET_FD,c,fd)
+#define BIO_get_fd(b,c)		BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c)
+
+#define BIO_set_fp(b,fp,c)	BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp)
+#define BIO_get_fp(b,fpp)	BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp)
+
+#define BIO_seek(b,ofs)	(int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL)
+#define BIO_tell(b)	(int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL)
+
+/* name is cast to lose const, but might be better to route through a function
+   so we can do it safely */
+#ifdef CONST_STRICT
+/* If you are wondering why this isn't defined, its because CONST_STRICT is
+ * purely a compile-time kludge to allow const to be checked.
+ */
+int BIO_read_filename(BIO *b,const char *name);
+#else
+#define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+		BIO_CLOSE|BIO_FP_READ,(char *)name)
+#endif
+#define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+		BIO_CLOSE|BIO_FP_WRITE,name)
+#define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+		BIO_CLOSE|BIO_FP_APPEND,name)
+#define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+		BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name)
+
+/* WARNING WARNING, this ups the reference count on the read bio of the
+ * SSL structure.  This is because the ssl read BIO is now pointed to by
+ * the next_bio field in the bio.  So when you free the BIO, make sure
+ * you are doing a BIO_free_all() to catch the underlying BIO. */
+#define BIO_set_ssl(b,ssl,c)	BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl)
+#define BIO_get_ssl(b,sslp)	BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp)
+#define BIO_set_ssl_mode(b,client)	BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL)
+#define BIO_set_ssl_renegotiate_bytes(b,num) \
+	BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL);
+#define BIO_get_num_renegotiates(b) \
+	BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL);
+#define BIO_set_ssl_renegotiate_timeout(b,seconds) \
+	BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL);
+
+/* defined in evp.h */
+/* #define BIO_set_md(b,md)	BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */
+
+#define BIO_get_mem_data(b,pp)	BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)
+#define BIO_set_mem_buf(b,bm,c)	BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm)
+#define BIO_get_mem_ptr(b,pp)	BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp)
+#define BIO_set_mem_eof_return(b,v) \
+				BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL)
+
+/* For the BIO_f_buffer() type */
+#define BIO_get_buffer_num_lines(b)	BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL)
+#define BIO_set_buffer_size(b,size)	BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL)
+#define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0)
+#define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1)
+#define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf)
+
+/* Don't use the next one unless you know what you are doing :-) */
+#define BIO_dup_state(b,ret)	BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret))
+
+#define BIO_reset(b)		(int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL)
+#define BIO_eof(b)		(int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL)
+#define BIO_set_close(b,c)	(int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL)
+#define BIO_get_close(b)	(int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL)
+#define BIO_pending(b)		(int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
+#define BIO_wpending(b)		(int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL)
+/* ...pending macros have inappropriate return type */
+size_t BIO_ctrl_pending(BIO *b);
+size_t BIO_ctrl_wpending(BIO *b);
+#define BIO_flush(b)		(int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL)
+#define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \
+						   cbp)
+#define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb)
+
+/* For the BIO_f_buffer() type */
+#define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL)
+
+/* For BIO_s_bio() */
+#define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL)
+#define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL)
+#define BIO_make_bio_pair(b1,b2)   (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2)
+#define BIO_destroy_bio_pair(b)    (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL)
+#define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL)
+/* macros with inappropriate type -- but ...pending macros use int too: */
+#define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL)
+#define BIO_get_read_request(b)    (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL)
+size_t BIO_ctrl_get_write_guarantee(BIO *b);
+size_t BIO_ctrl_get_read_request(BIO *b);
+int BIO_ctrl_reset_read_request(BIO *b);
+
+/* ctrl macros for dgram */
+#define BIO_ctrl_dgram_connect(b,peer)  \
+                     (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)peer)
+#define BIO_ctrl_set_connected(b, state, peer) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, state, (char *)peer)
+#define BIO_dgram_recv_timedout(b) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL)
+#define BIO_dgram_send_timedout(b) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL)
+#define BIO_dgram_get_peer(b,peer) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer)
+#define BIO_dgram_set_peer(b,peer) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer)
+
+/* These two aren't currently implemented */
+/* int BIO_get_ex_num(BIO *bio); */
+/* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */
+int BIO_set_ex_data(BIO *bio,int idx,void *data);
+void *BIO_get_ex_data(BIO *bio,int idx);
+int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+unsigned long BIO_number_read(BIO *bio);
+unsigned long BIO_number_written(BIO *bio);
+
+/* For BIO_f_asn1() */
+int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
+					asn1_ps_func *prefix_free);
+int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
+					asn1_ps_func **pprefix_free);
+int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
+					asn1_ps_func *suffix_free);
+int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
+					asn1_ps_func **psuffix_free);
+
+# ifndef OPENSSL_NO_FP_API
+BIO_METHOD *BIO_s_file(void );
+BIO *BIO_new_file(const char *filename, const char *mode);
+BIO *BIO_new_fp(FILE *stream, int close_flag);
+# define BIO_s_file_internal	BIO_s_file
+# endif
+BIO *	BIO_new(BIO_METHOD *type);
+int	BIO_set(BIO *a,BIO_METHOD *type);
+int	BIO_free(BIO *a);
+void	BIO_vfree(BIO *a);
+int	BIO_read(BIO *b, void *data, int len);
+int	BIO_gets(BIO *bp,char *buf, int size);
+int	BIO_write(BIO *b, const void *data, int len);
+int	BIO_puts(BIO *bp,const char *buf);
+int	BIO_indent(BIO *b,int indent,int max);
+long	BIO_ctrl(BIO *bp,int cmd,long larg,void *parg);
+long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long));
+char *	BIO_ptr_ctrl(BIO *bp,int cmd,long larg);
+long	BIO_int_ctrl(BIO *bp,int cmd,long larg,int iarg);
+BIO *	BIO_push(BIO *b,BIO *append);
+BIO *	BIO_pop(BIO *b);
+void	BIO_free_all(BIO *a);
+BIO *	BIO_find_type(BIO *b,int bio_type);
+BIO *	BIO_next(BIO *b);
+BIO *	BIO_get_retry_BIO(BIO *bio, int *reason);
+int	BIO_get_retry_reason(BIO *bio);
+BIO *	BIO_dup_chain(BIO *in);
+
+int BIO_nread0(BIO *bio, char **buf);
+int BIO_nread(BIO *bio, char **buf, int num);
+int BIO_nwrite0(BIO *bio, char **buf);
+int BIO_nwrite(BIO *bio, char **buf, int num);
+
+long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
+	long argl,long ret);
+
+BIO_METHOD *BIO_s_mem(void);
+BIO *BIO_new_mem_buf(void *buf, int len);
+BIO_METHOD *BIO_s_socket(void);
+BIO_METHOD *BIO_s_connect(void);
+BIO_METHOD *BIO_s_accept(void);
+BIO_METHOD *BIO_s_fd(void);
+#ifndef OPENSSL_SYS_OS2
+BIO_METHOD *BIO_s_log(void);
+#endif
+BIO_METHOD *BIO_s_bio(void);
+BIO_METHOD *BIO_s_null(void);
+BIO_METHOD *BIO_f_null(void);
+BIO_METHOD *BIO_f_buffer(void);
+#ifdef OPENSSL_SYS_VMS
+BIO_METHOD *BIO_f_linebuffer(void);
+#endif
+BIO_METHOD *BIO_f_nbio_test(void);
+#ifndef OPENSSL_NO_DGRAM
+BIO_METHOD *BIO_s_datagram(void);
+#endif
+
+/* BIO_METHOD *BIO_f_ber(void); */
+
+int BIO_sock_should_retry(int i);
+int BIO_sock_non_fatal_error(int error);
+int BIO_dgram_non_fatal_error(int error);
+
+int BIO_fd_should_retry(int i);
+int BIO_fd_non_fatal_error(int error);
+int BIO_dump_cb(int (*cb)(const void *data, size_t len, void *u),
+		void *u, const char *s, int len);
+int BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u),
+		       void *u, const char *s, int len, int indent);
+int BIO_dump(BIO *b,const char *bytes,int len);
+int BIO_dump_indent(BIO *b,const char *bytes,int len,int indent);
+#ifndef OPENSSL_NO_FP_API
+int BIO_dump_fp(FILE *fp, const char *s, int len);
+int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent);
+#endif
+struct hostent *BIO_gethostbyname(const char *name);
+/* We might want a thread-safe interface too:
+ * struct hostent *BIO_gethostbyname_r(const char *name,
+ *     struct hostent *result, void *buffer, size_t buflen);
+ * or something similar (caller allocates a struct hostent,
+ * pointed to by "result", and additional buffer space for the various
+ * substructures; if the buffer does not suffice, NULL is returned
+ * and an appropriate error code is set).
+ */
+int BIO_sock_error(int sock);
+int BIO_socket_ioctl(int fd, long type, void *arg);
+int BIO_socket_nbio(int fd,int mode);
+int BIO_get_port(const char *str, unsigned short *port_ptr);
+int BIO_get_host_ip(const char *str, unsigned char *ip);
+int BIO_get_accept_socket(char *host_port,int mode);
+int BIO_accept(int sock,char **ip_port);
+int BIO_sock_init(void );
+void BIO_sock_cleanup(void);
+int BIO_set_tcp_ndelay(int sock,int turn_on);
+
+BIO *BIO_new_socket(int sock, int close_flag);
+BIO *BIO_new_dgram(int fd, int close_flag);
+BIO *BIO_new_fd(int fd, int close_flag);
+BIO *BIO_new_connect(char *host_port);
+BIO *BIO_new_accept(char *host_port);
+
+int BIO_new_bio_pair(BIO **bio1, size_t writebuf1,
+	BIO **bio2, size_t writebuf2);
+/* If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints.
+ * Otherwise returns 0 and sets *bio1 and *bio2 to NULL.
+ * Size 0 uses default value.
+ */
+
+void BIO_copy_next_retry(BIO *b);
+
+/*long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);*/
+
+#ifdef __GNUC__
+#  define __bio_h__attr__ __attribute__
+#else
+#  define __bio_h__attr__(x)
+#endif
+int BIO_printf(BIO *bio, const char *format, ...)
+	__bio_h__attr__((__format__(__printf__,2,3)));
+int BIO_vprintf(BIO *bio, const char *format, va_list args)
+	__bio_h__attr__((__format__(__printf__,2,0)));
+int BIO_snprintf(char *buf, size_t n, const char *format, ...)
+	__bio_h__attr__((__format__(__printf__,3,4)));
+int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
+	__bio_h__attr__((__format__(__printf__,3,0)));
+#undef __bio_h__attr__
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_BIO_strings(void);
+
+/* Error codes for the BIO functions. */
+
+/* Function codes. */
+#define BIO_F_ACPT_STATE				 100
+#define BIO_F_BIO_ACCEPT				 101
+#define BIO_F_BIO_BER_GET_HEADER			 102
+#define BIO_F_BIO_CALLBACK_CTRL				 131
+#define BIO_F_BIO_CTRL					 103
+#define BIO_F_BIO_GETHOSTBYNAME				 120
+#define BIO_F_BIO_GETS					 104
+#define BIO_F_BIO_GET_ACCEPT_SOCKET			 105
+#define BIO_F_BIO_GET_HOST_IP				 106
+#define BIO_F_BIO_GET_PORT				 107
+#define BIO_F_BIO_MAKE_PAIR				 121
+#define BIO_F_BIO_NEW					 108
+#define BIO_F_BIO_NEW_FILE				 109
+#define BIO_F_BIO_NEW_MEM_BUF				 126
+#define BIO_F_BIO_NREAD					 123
+#define BIO_F_BIO_NREAD0				 124
+#define BIO_F_BIO_NWRITE				 125
+#define BIO_F_BIO_NWRITE0				 122
+#define BIO_F_BIO_PUTS					 110
+#define BIO_F_BIO_READ					 111
+#define BIO_F_BIO_SOCK_INIT				 112
+#define BIO_F_BIO_WRITE					 113
+#define BIO_F_BUFFER_CTRL				 114
+#define BIO_F_CONN_CTRL					 127
+#define BIO_F_CONN_STATE				 115
+#define BIO_F_FILE_CTRL					 116
+#define BIO_F_FILE_READ					 130
+#define BIO_F_LINEBUFFER_CTRL				 129
+#define BIO_F_MEM_READ					 128
+#define BIO_F_MEM_WRITE					 117
+#define BIO_F_SSL_NEW					 118
+#define BIO_F_WSASTARTUP				 119
+
+/* Reason codes. */
+#define BIO_R_ACCEPT_ERROR				 100
+#define BIO_R_BAD_FOPEN_MODE				 101
+#define BIO_R_BAD_HOSTNAME_LOOKUP			 102
+#define BIO_R_BROKEN_PIPE				 124
+#define BIO_R_CONNECT_ERROR				 103
+#define BIO_R_EOF_ON_MEMORY_BIO				 127
+#define BIO_R_ERROR_SETTING_NBIO			 104
+#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET	 105
+#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET	 106
+#define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET		 107
+#define BIO_R_INVALID_ARGUMENT				 125
+#define BIO_R_INVALID_IP_ADDRESS			 108
+#define BIO_R_IN_USE					 123
+#define BIO_R_KEEPALIVE					 109
+#define BIO_R_NBIO_CONNECT_ERROR			 110
+#define BIO_R_NO_ACCEPT_PORT_SPECIFIED			 111
+#define BIO_R_NO_HOSTNAME_SPECIFIED			 112
+#define BIO_R_NO_PORT_DEFINED				 113
+#define BIO_R_NO_PORT_SPECIFIED				 114
+#define BIO_R_NO_SUCH_FILE				 128
+#define BIO_R_NULL_PARAMETER				 115
+#define BIO_R_TAG_MISMATCH				 116
+#define BIO_R_UNABLE_TO_BIND_SOCKET			 117
+#define BIO_R_UNABLE_TO_CREATE_SOCKET			 118
+#define BIO_R_UNABLE_TO_LISTEN_SOCKET			 119
+#define BIO_R_UNINITIALIZED				 120
+#define BIO_R_UNSUPPORTED_METHOD			 121
+#define BIO_R_WRITE_TO_READ_ONLY_BIO			 126
+#define BIO_R_WSASTARTUP				 122
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/bio/bio_cb.c b/openssl/crypto/bio/bio_cb.c
new file mode 100644
index 0000000..9bcbc32
--- /dev/null
+++ b/openssl/crypto/bio/bio_cb.c
@@ -0,0 +1,143 @@
+/* crypto/bio/bio_cb.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+long MS_CALLBACK BIO_debug_callback(BIO *bio, int cmd, const char *argp,
+	     int argi, long argl, long ret)
+	{
+	BIO *b;
+	MS_STATIC char buf[256];
+	char *p;
+	long r=1;
+	size_t p_maxlen;
+
+	if (BIO_CB_RETURN & cmd)
+		r=ret;
+
+	BIO_snprintf(buf,sizeof buf,"BIO[%08lX]:",(unsigned long)bio);
+	p= &(buf[14]);
+	p_maxlen = sizeof buf - 14;
+	switch (cmd)
+		{
+	case BIO_CB_FREE:
+		BIO_snprintf(p,p_maxlen,"Free - %s\n",bio->method->name);
+		break;
+	case BIO_CB_READ:
+		if (bio->method->type & BIO_TYPE_DESCRIPTOR)
+			BIO_snprintf(p,p_maxlen,"read(%d,%lu) - %s fd=%d\n",
+				 bio->num,(unsigned long)argi,
+				 bio->method->name,bio->num);
+		else
+			BIO_snprintf(p,p_maxlen,"read(%d,%lu) - %s\n",
+				 bio->num,(unsigned long)argi,
+				 bio->method->name);
+		break;
+	case BIO_CB_WRITE:
+		if (bio->method->type & BIO_TYPE_DESCRIPTOR)
+			BIO_snprintf(p,p_maxlen,"write(%d,%lu) - %s fd=%d\n",
+				 bio->num,(unsigned long)argi,
+				 bio->method->name,bio->num);
+		else
+			BIO_snprintf(p,p_maxlen,"write(%d,%lu) - %s\n",
+				 bio->num,(unsigned long)argi,
+				 bio->method->name);
+		break;
+	case BIO_CB_PUTS:
+		BIO_snprintf(p,p_maxlen,"puts() - %s\n",bio->method->name);
+		break;
+	case BIO_CB_GETS:
+		BIO_snprintf(p,p_maxlen,"gets(%lu) - %s\n",(unsigned long)argi,bio->method->name);
+		break;
+	case BIO_CB_CTRL:
+		BIO_snprintf(p,p_maxlen,"ctrl(%lu) - %s\n",(unsigned long)argi,bio->method->name);
+		break;
+	case BIO_CB_RETURN|BIO_CB_READ:
+		BIO_snprintf(p,p_maxlen,"read return %ld\n",ret);
+		break;
+	case BIO_CB_RETURN|BIO_CB_WRITE:
+		BIO_snprintf(p,p_maxlen,"write return %ld\n",ret);
+		break;
+	case BIO_CB_RETURN|BIO_CB_GETS:
+		BIO_snprintf(p,p_maxlen,"gets return %ld\n",ret);
+		break;
+	case BIO_CB_RETURN|BIO_CB_PUTS:
+		BIO_snprintf(p,p_maxlen,"puts return %ld\n",ret);
+		break;
+	case BIO_CB_RETURN|BIO_CB_CTRL:
+		BIO_snprintf(p,p_maxlen,"ctrl return %ld\n",ret);
+		break;
+	default:
+		BIO_snprintf(p,p_maxlen,"bio callback - unknown type (%d)\n",cmd);
+		break;
+		}
+
+	b=(BIO *)bio->cb_arg;
+	if (b != NULL)
+		BIO_write(b,buf,strlen(buf));
+#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
+	else
+		fputs(buf,stderr);
+#endif
+	return(r);
+	}
diff --git a/openssl/crypto/bio/bio_err.c b/openssl/crypto/bio/bio_err.c
new file mode 100644
index 0000000..a224edd
--- /dev/null
+++ b/openssl/crypto/bio/bio_err.c
@@ -0,0 +1,154 @@
+/* crypto/bio/bio_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/bio.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_BIO,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_BIO,0,reason)
+
+static ERR_STRING_DATA BIO_str_functs[]=
+	{
+{ERR_FUNC(BIO_F_ACPT_STATE),	"ACPT_STATE"},
+{ERR_FUNC(BIO_F_BIO_ACCEPT),	"BIO_accept"},
+{ERR_FUNC(BIO_F_BIO_BER_GET_HEADER),	"BIO_BER_GET_HEADER"},
+{ERR_FUNC(BIO_F_BIO_CALLBACK_CTRL),	"BIO_callback_ctrl"},
+{ERR_FUNC(BIO_F_BIO_CTRL),	"BIO_ctrl"},
+{ERR_FUNC(BIO_F_BIO_GETHOSTBYNAME),	"BIO_gethostbyname"},
+{ERR_FUNC(BIO_F_BIO_GETS),	"BIO_gets"},
+{ERR_FUNC(BIO_F_BIO_GET_ACCEPT_SOCKET),	"BIO_get_accept_socket"},
+{ERR_FUNC(BIO_F_BIO_GET_HOST_IP),	"BIO_get_host_ip"},
+{ERR_FUNC(BIO_F_BIO_GET_PORT),	"BIO_get_port"},
+{ERR_FUNC(BIO_F_BIO_MAKE_PAIR),	"BIO_MAKE_PAIR"},
+{ERR_FUNC(BIO_F_BIO_NEW),	"BIO_new"},
+{ERR_FUNC(BIO_F_BIO_NEW_FILE),	"BIO_new_file"},
+{ERR_FUNC(BIO_F_BIO_NEW_MEM_BUF),	"BIO_new_mem_buf"},
+{ERR_FUNC(BIO_F_BIO_NREAD),	"BIO_nread"},
+{ERR_FUNC(BIO_F_BIO_NREAD0),	"BIO_nread0"},
+{ERR_FUNC(BIO_F_BIO_NWRITE),	"BIO_nwrite"},
+{ERR_FUNC(BIO_F_BIO_NWRITE0),	"BIO_nwrite0"},
+{ERR_FUNC(BIO_F_BIO_PUTS),	"BIO_puts"},
+{ERR_FUNC(BIO_F_BIO_READ),	"BIO_read"},
+{ERR_FUNC(BIO_F_BIO_SOCK_INIT),	"BIO_sock_init"},
+{ERR_FUNC(BIO_F_BIO_WRITE),	"BIO_write"},
+{ERR_FUNC(BIO_F_BUFFER_CTRL),	"BUFFER_CTRL"},
+{ERR_FUNC(BIO_F_CONN_CTRL),	"CONN_CTRL"},
+{ERR_FUNC(BIO_F_CONN_STATE),	"CONN_STATE"},
+{ERR_FUNC(BIO_F_FILE_CTRL),	"FILE_CTRL"},
+{ERR_FUNC(BIO_F_FILE_READ),	"FILE_READ"},
+{ERR_FUNC(BIO_F_LINEBUFFER_CTRL),	"LINEBUFFER_CTRL"},
+{ERR_FUNC(BIO_F_MEM_READ),	"MEM_READ"},
+{ERR_FUNC(BIO_F_MEM_WRITE),	"MEM_WRITE"},
+{ERR_FUNC(BIO_F_SSL_NEW),	"SSL_new"},
+{ERR_FUNC(BIO_F_WSASTARTUP),	"WSASTARTUP"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA BIO_str_reasons[]=
+	{
+{ERR_REASON(BIO_R_ACCEPT_ERROR)          ,"accept error"},
+{ERR_REASON(BIO_R_BAD_FOPEN_MODE)        ,"bad fopen mode"},
+{ERR_REASON(BIO_R_BAD_HOSTNAME_LOOKUP)   ,"bad hostname lookup"},
+{ERR_REASON(BIO_R_BROKEN_PIPE)           ,"broken pipe"},
+{ERR_REASON(BIO_R_CONNECT_ERROR)         ,"connect error"},
+{ERR_REASON(BIO_R_EOF_ON_MEMORY_BIO)     ,"EOF on memory BIO"},
+{ERR_REASON(BIO_R_ERROR_SETTING_NBIO)    ,"error setting nbio"},
+{ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET),"error setting nbio on accepted socket"},
+{ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET),"error setting nbio on accept socket"},
+{ERR_REASON(BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET),"gethostbyname addr is not af inet"},
+{ERR_REASON(BIO_R_INVALID_ARGUMENT)      ,"invalid argument"},
+{ERR_REASON(BIO_R_INVALID_IP_ADDRESS)    ,"invalid ip address"},
+{ERR_REASON(BIO_R_IN_USE)                ,"in use"},
+{ERR_REASON(BIO_R_KEEPALIVE)             ,"keepalive"},
+{ERR_REASON(BIO_R_NBIO_CONNECT_ERROR)    ,"nbio connect error"},
+{ERR_REASON(BIO_R_NO_ACCEPT_PORT_SPECIFIED),"no accept port specified"},
+{ERR_REASON(BIO_R_NO_HOSTNAME_SPECIFIED) ,"no hostname specified"},
+{ERR_REASON(BIO_R_NO_PORT_DEFINED)       ,"no port defined"},
+{ERR_REASON(BIO_R_NO_PORT_SPECIFIED)     ,"no port specified"},
+{ERR_REASON(BIO_R_NO_SUCH_FILE)          ,"no such file"},
+{ERR_REASON(BIO_R_NULL_PARAMETER)        ,"null parameter"},
+{ERR_REASON(BIO_R_TAG_MISMATCH)          ,"tag mismatch"},
+{ERR_REASON(BIO_R_UNABLE_TO_BIND_SOCKET) ,"unable to bind socket"},
+{ERR_REASON(BIO_R_UNABLE_TO_CREATE_SOCKET),"unable to create socket"},
+{ERR_REASON(BIO_R_UNABLE_TO_LISTEN_SOCKET),"unable to listen socket"},
+{ERR_REASON(BIO_R_UNINITIALIZED)         ,"uninitialized"},
+{ERR_REASON(BIO_R_UNSUPPORTED_METHOD)    ,"unsupported method"},
+{ERR_REASON(BIO_R_WRITE_TO_READ_ONLY_BIO),"write to read only BIO"},
+{ERR_REASON(BIO_R_WSASTARTUP)            ,"WSAStartup"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_BIO_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(BIO_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,BIO_str_functs);
+		ERR_load_strings(0,BIO_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/bio/bio_lcl.h b/openssl/crypto/bio/bio_lcl.h
new file mode 100644
index 0000000..e7f7ec8
--- /dev/null
+++ b/openssl/crypto/bio/bio_lcl.h
@@ -0,0 +1,36 @@
+#include <openssl/bio.h>
+
+#if BIO_FLAGS_UPLINK==0
+/* Shortcut UPLINK calls on most platforms... */
+#define	UP_stdin	stdin
+#define	UP_stdout	stdout
+#define	UP_stderr	stderr
+#define	UP_fprintf	fprintf
+#define	UP_fgets	fgets
+#define	UP_fread	fread
+#define	UP_fwrite	fwrite
+#undef	UP_fsetmod
+#define	UP_feof		feof
+#define	UP_fclose	fclose
+
+#define	UP_fopen	fopen
+#define	UP_fseek	fseek
+#define	UP_ftell	ftell
+#define	UP_fflush	fflush
+#define	UP_ferror	ferror
+#ifdef _WIN32
+#define	UP_fileno	_fileno
+#define	UP_open		_open
+#define	UP_read		_read
+#define	UP_write	_write
+#define	UP_lseek	_lseek
+#define	UP_close	_close
+#else
+#define	UP_fileno	fileno
+#define	UP_open		open
+#define	UP_read		read
+#define	UP_write	write
+#define	UP_lseek	lseek
+#define	UP_close	close
+#endif
+#endif
diff --git a/openssl/crypto/bio/bio_lib.c b/openssl/crypto/bio/bio_lib.c
new file mode 100644
index 0000000..e12bc3a
--- /dev/null
+++ b/openssl/crypto/bio/bio_lib.c
@@ -0,0 +1,602 @@
+/* crypto/bio/bio_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+#include <openssl/stack.h>
+
+BIO *BIO_new(BIO_METHOD *method)
+	{
+	BIO *ret=NULL;
+
+	ret=(BIO *)OPENSSL_malloc(sizeof(BIO));
+	if (ret == NULL)
+		{
+		BIOerr(BIO_F_BIO_NEW,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	if (!BIO_set(ret,method))
+		{
+		OPENSSL_free(ret);
+		ret=NULL;
+		}
+	return(ret);
+	}
+
+int BIO_set(BIO *bio, BIO_METHOD *method)
+	{
+	bio->method=method;
+	bio->callback=NULL;
+	bio->cb_arg=NULL;
+	bio->init=0;
+	bio->shutdown=1;
+	bio->flags=0;
+	bio->retry_reason=0;
+	bio->num=0;
+	bio->ptr=NULL;
+	bio->prev_bio=NULL;
+	bio->next_bio=NULL;
+	bio->references=1;
+	bio->num_read=0L;
+	bio->num_write=0L;
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
+	if (method->create != NULL)
+		if (!method->create(bio))
+			{
+			CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio,
+					&bio->ex_data);
+			return(0);
+			}
+	return(1);
+	}
+
+int BIO_free(BIO *a)
+	{
+	int i;
+
+	if (a == NULL) return(0);
+
+	i=CRYPTO_add(&a->references,-1,CRYPTO_LOCK_BIO);
+#ifdef REF_PRINT
+	REF_PRINT("BIO",a);
+#endif
+	if (i > 0) return(1);
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"BIO_free, bad reference count\n");
+		abort();
+		}
+#endif
+	if ((a->callback != NULL) &&
+		((i=(int)a->callback(a,BIO_CB_FREE,NULL,0,0L,1L)) <= 0))
+			return(i);
+
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
+
+	if ((a->method == NULL) || (a->method->destroy == NULL)) return(1);
+	a->method->destroy(a);
+	OPENSSL_free(a);
+	return(1);
+	}
+
+void BIO_vfree(BIO *a)
+    { BIO_free(a); }
+
+void BIO_clear_flags(BIO *b, int flags)
+	{
+	b->flags &= ~flags;
+	}
+
+int	BIO_test_flags(const BIO *b, int flags)
+	{
+	return (b->flags & flags);
+	}
+
+void	BIO_set_flags(BIO *b, int flags)
+	{
+	b->flags |= flags;
+	}
+
+long (*BIO_get_callback(const BIO *b))(struct bio_st *,int,const char *,int, long,long)
+	{
+	return b->callback;
+	}
+
+void BIO_set_callback(BIO *b, long (*cb)(struct bio_st *,int,const char *,int, long,long))
+	{
+	b->callback = cb;
+	}
+
+void BIO_set_callback_arg(BIO *b, char *arg)
+	{
+	b->cb_arg = arg;
+	}
+
+char * BIO_get_callback_arg(const BIO *b)
+	{
+	return b->cb_arg;
+	}
+
+const char * BIO_method_name(const BIO *b)
+	{
+	return b->method->name;
+	}
+
+int BIO_method_type(const BIO *b)
+	{
+	return b->method->type;
+	}
+
+
+int BIO_read(BIO *b, void *out, int outl)
+	{
+	int i;
+	long (*cb)(BIO *,int,const char *,int,long,long);
+
+	if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL))
+		{
+		BIOerr(BIO_F_BIO_READ,BIO_R_UNSUPPORTED_METHOD);
+		return(-2);
+		}
+
+	cb=b->callback;
+	if ((cb != NULL) &&
+		((i=(int)cb(b,BIO_CB_READ,out,outl,0L,1L)) <= 0))
+			return(i);
+
+	if (!b->init)
+		{
+		BIOerr(BIO_F_BIO_READ,BIO_R_UNINITIALIZED);
+		return(-2);
+		}
+
+	i=b->method->bread(b,out,outl);
+
+	if (i > 0) b->num_read+=(unsigned long)i;
+
+	if (cb != NULL)
+		i=(int)cb(b,BIO_CB_READ|BIO_CB_RETURN,out,outl,
+			0L,(long)i);
+	return(i);
+	}
+
+int BIO_write(BIO *b, const void *in, int inl)
+	{
+	int i;
+	long (*cb)(BIO *,int,const char *,int,long,long);
+
+	if (b == NULL)
+		return(0);
+
+	cb=b->callback;
+	if ((b->method == NULL) || (b->method->bwrite == NULL))
+		{
+		BIOerr(BIO_F_BIO_WRITE,BIO_R_UNSUPPORTED_METHOD);
+		return(-2);
+		}
+
+	if ((cb != NULL) &&
+		((i=(int)cb(b,BIO_CB_WRITE,in,inl,0L,1L)) <= 0))
+			return(i);
+
+	if (!b->init)
+		{
+		BIOerr(BIO_F_BIO_WRITE,BIO_R_UNINITIALIZED);
+		return(-2);
+		}
+
+	i=b->method->bwrite(b,in,inl);
+
+	if (i > 0) b->num_write+=(unsigned long)i;
+
+	if (cb != NULL)
+		i=(int)cb(b,BIO_CB_WRITE|BIO_CB_RETURN,in,inl,
+			0L,(long)i);
+	return(i);
+	}
+
+int BIO_puts(BIO *b, const char *in)
+	{
+	int i;
+	long (*cb)(BIO *,int,const char *,int,long,long);
+
+	if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL))
+		{
+		BIOerr(BIO_F_BIO_PUTS,BIO_R_UNSUPPORTED_METHOD);
+		return(-2);
+		}
+
+	cb=b->callback;
+
+	if ((cb != NULL) &&
+		((i=(int)cb(b,BIO_CB_PUTS,in,0,0L,1L)) <= 0))
+			return(i);
+
+	if (!b->init)
+		{
+		BIOerr(BIO_F_BIO_PUTS,BIO_R_UNINITIALIZED);
+		return(-2);
+		}
+
+	i=b->method->bputs(b,in);
+
+	if (i > 0) b->num_write+=(unsigned long)i;
+
+	if (cb != NULL)
+		i=(int)cb(b,BIO_CB_PUTS|BIO_CB_RETURN,in,0,
+			0L,(long)i);
+	return(i);
+	}
+
+int BIO_gets(BIO *b, char *in, int inl)
+	{
+	int i;
+	long (*cb)(BIO *,int,const char *,int,long,long);
+
+	if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL))
+		{
+		BIOerr(BIO_F_BIO_GETS,BIO_R_UNSUPPORTED_METHOD);
+		return(-2);
+		}
+
+	cb=b->callback;
+
+	if ((cb != NULL) &&
+		((i=(int)cb(b,BIO_CB_GETS,in,inl,0L,1L)) <= 0))
+			return(i);
+
+	if (!b->init)
+		{
+		BIOerr(BIO_F_BIO_GETS,BIO_R_UNINITIALIZED);
+		return(-2);
+		}
+
+	i=b->method->bgets(b,in,inl);
+
+	if (cb != NULL)
+		i=(int)cb(b,BIO_CB_GETS|BIO_CB_RETURN,in,inl,
+			0L,(long)i);
+	return(i);
+	}
+
+int BIO_indent(BIO *b,int indent,int max)
+	{
+	if(indent < 0)
+		indent=0;
+	if(indent > max)
+		indent=max;
+	while(indent--)
+		if(BIO_puts(b," ") != 1)
+			return 0;
+	return 1;
+	}
+
+long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
+	{
+	int i;
+
+	i=iarg;
+	return(BIO_ctrl(b,cmd,larg,(char *)&i));
+	}
+
+char *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
+	{
+	char *p=NULL;
+
+	if (BIO_ctrl(b,cmd,larg,(char *)&p) <= 0)
+		return(NULL);
+	else
+		return(p);
+	}
+
+long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
+	{
+	long ret;
+	long (*cb)(BIO *,int,const char *,int,long,long);
+
+	if (b == NULL) return(0);
+
+	if ((b->method == NULL) || (b->method->ctrl == NULL))
+		{
+		BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD);
+		return(-2);
+		}
+
+	cb=b->callback;
+
+	if ((cb != NULL) &&
+		((ret=cb(b,BIO_CB_CTRL,parg,cmd,larg,1L)) <= 0))
+		return(ret);
+
+	ret=b->method->ctrl(b,cmd,larg,parg);
+
+	if (cb != NULL)
+		ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,parg,cmd,
+			larg,ret);
+	return(ret);
+	}
+
+long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long))
+	{
+	long ret;
+	long (*cb)(BIO *,int,const char *,int,long,long);
+
+	if (b == NULL) return(0);
+
+	if ((b->method == NULL) || (b->method->callback_ctrl == NULL))
+		{
+		BIOerr(BIO_F_BIO_CALLBACK_CTRL,BIO_R_UNSUPPORTED_METHOD);
+		return(-2);
+		}
+
+	cb=b->callback;
+
+	if ((cb != NULL) &&
+		((ret=cb(b,BIO_CB_CTRL,(void *)&fp,cmd,0,1L)) <= 0))
+		return(ret);
+
+	ret=b->method->callback_ctrl(b,cmd,fp);
+
+	if (cb != NULL)
+		ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,(void *)&fp,cmd,
+			0,ret);
+	return(ret);
+	}
+
+/* It is unfortunate to duplicate in functions what the BIO_(w)pending macros
+ * do; but those macros have inappropriate return type, and for interfacing
+ * from other programming languages, C macros aren't much of a help anyway. */
+size_t BIO_ctrl_pending(BIO *bio)
+	{
+	return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
+	}
+
+size_t BIO_ctrl_wpending(BIO *bio)
+	{
+	return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
+	}
+
+
+/* put the 'bio' on the end of b's list of operators */
+BIO *BIO_push(BIO *b, BIO *bio)
+	{
+	BIO *lb;
+
+	if (b == NULL) return(bio);
+	lb=b;
+	while (lb->next_bio != NULL)
+		lb=lb->next_bio;
+	lb->next_bio=bio;
+	if (bio != NULL)
+		bio->prev_bio=lb;
+	/* called to do internal processing */
+	BIO_ctrl(b,BIO_CTRL_PUSH,0,lb);
+	return(b);
+	}
+
+/* Remove the first and return the rest */
+BIO *BIO_pop(BIO *b)
+	{
+	BIO *ret;
+
+	if (b == NULL) return(NULL);
+	ret=b->next_bio;
+
+	BIO_ctrl(b,BIO_CTRL_POP,0,b);
+
+	if (b->prev_bio != NULL)
+		b->prev_bio->next_bio=b->next_bio;
+	if (b->next_bio != NULL)
+		b->next_bio->prev_bio=b->prev_bio;
+
+	b->next_bio=NULL;
+	b->prev_bio=NULL;
+	return(ret);
+	}
+
+BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
+	{
+	BIO *b,*last;
+
+	b=last=bio;
+	for (;;)
+		{
+		if (!BIO_should_retry(b)) break;
+		last=b;
+		b=b->next_bio;
+		if (b == NULL) break;
+		}
+	if (reason != NULL) *reason=last->retry_reason;
+	return(last);
+	}
+
+int BIO_get_retry_reason(BIO *bio)
+	{
+	return(bio->retry_reason);
+	}
+
+BIO *BIO_find_type(BIO *bio, int type)
+	{
+	int mt,mask;
+
+	if(!bio) return NULL;
+	mask=type&0xff;
+	do	{
+		if (bio->method != NULL)
+			{
+			mt=bio->method->type;
+
+			if (!mask)
+				{
+				if (mt & type) return(bio);
+				}
+			else if (mt == type)
+				return(bio);
+			}
+		bio=bio->next_bio;
+		} while (bio != NULL);
+	return(NULL);
+	}
+
+BIO *BIO_next(BIO *b)
+	{
+	if(!b) return NULL;
+	return b->next_bio;
+	}
+
+void BIO_free_all(BIO *bio)
+	{
+	BIO *b;
+	int ref;
+
+	while (bio != NULL)
+		{
+		b=bio;
+		ref=b->references;
+		bio=bio->next_bio;
+		BIO_free(b);
+		/* Since ref count > 1, don't free anyone else. */
+		if (ref > 1) break;
+		}
+	}
+
+BIO *BIO_dup_chain(BIO *in)
+	{
+	BIO *ret=NULL,*eoc=NULL,*bio,*new;
+
+	for (bio=in; bio != NULL; bio=bio->next_bio)
+		{
+		if ((new=BIO_new(bio->method)) == NULL) goto err;
+		new->callback=bio->callback;
+		new->cb_arg=bio->cb_arg;
+		new->init=bio->init;
+		new->shutdown=bio->shutdown;
+		new->flags=bio->flags;
+
+		/* This will let SSL_s_sock() work with stdin/stdout */
+		new->num=bio->num;
+
+		if (!BIO_dup_state(bio,(char *)new))
+			{
+			BIO_free(new);
+			goto err;
+			}
+
+		/* copy app data */
+		if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new->ex_data,
+					&bio->ex_data))
+			goto err;
+
+		if (ret == NULL)
+			{
+			eoc=new;
+			ret=eoc;
+			}
+		else
+			{
+			BIO_push(eoc,new);
+			eoc=new;
+			}
+		}
+	return(ret);
+err:
+	if (ret != NULL)
+		BIO_free(ret);
+	return(NULL);	
+	}
+
+void BIO_copy_next_retry(BIO *b)
+	{
+	BIO_set_flags(b,BIO_get_retry_flags(b->next_bio));
+	b->retry_reason=b->next_bio->retry_reason;
+	}
+
+int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+	{
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp,
+				new_func, dup_func, free_func);
+	}
+
+int BIO_set_ex_data(BIO *bio, int idx, void *data)
+	{
+	return(CRYPTO_set_ex_data(&(bio->ex_data),idx,data));
+	}
+
+void *BIO_get_ex_data(BIO *bio, int idx)
+	{
+	return(CRYPTO_get_ex_data(&(bio->ex_data),idx));
+	}
+
+unsigned long BIO_number_read(BIO *bio)
+{
+	if(bio) return bio->num_read;
+	return 0;
+}
+
+unsigned long BIO_number_written(BIO *bio)
+{
+	if(bio) return bio->num_write;
+	return 0;
+}
+
+IMPLEMENT_STACK_OF(BIO)
diff --git a/openssl/crypto/bio/bss_acpt.c b/openssl/crypto/bio/bss_acpt.c
new file mode 100644
index 0000000..5d49e1a
--- /dev/null
+++ b/openssl/crypto/bio/bss_acpt.c
@@ -0,0 +1,478 @@
+/* crypto/bio/bss_acpt.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "cryptlib.h"
+#include <openssl/bio.h>
+
+#ifndef OPENSSL_NO_SOCK
+
+#ifdef OPENSSL_SYS_WIN16
+#define SOCKET_PROTOCOL 0 /* more microsoft stupidity */
+#else
+#define SOCKET_PROTOCOL IPPROTO_TCP
+#endif
+
+#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
+/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
+#undef FIONBIO
+#endif
+
+typedef struct bio_accept_st
+	{
+	int state;
+	char *param_addr;
+
+	int accept_sock;
+	int accept_nbio;
+
+	char *addr;
+	int nbio;
+	/* If 0, it means normal, if 1, do a connect on bind failure,
+	 * and if there is no-one listening, bind with SO_REUSEADDR.
+	 * If 2, always use SO_REUSEADDR. */
+	int bind_mode;
+	BIO *bio_chain;
+	} BIO_ACCEPT;
+
+static int acpt_write(BIO *h, const char *buf, int num);
+static int acpt_read(BIO *h, char *buf, int size);
+static int acpt_puts(BIO *h, const char *str);
+static long acpt_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int acpt_new(BIO *h);
+static int acpt_free(BIO *data);
+static int acpt_state(BIO *b, BIO_ACCEPT *c);
+static void acpt_close_socket(BIO *data);
+static BIO_ACCEPT *BIO_ACCEPT_new(void );
+static void BIO_ACCEPT_free(BIO_ACCEPT *a);
+
+#define ACPT_S_BEFORE			1
+#define ACPT_S_GET_ACCEPT_SOCKET	2
+#define ACPT_S_OK			3
+
+static BIO_METHOD methods_acceptp=
+	{
+	BIO_TYPE_ACCEPT,
+	"socket accept",
+	acpt_write,
+	acpt_read,
+	acpt_puts,
+	NULL, /* connect_gets, */
+	acpt_ctrl,
+	acpt_new,
+	acpt_free,
+	NULL,
+	};
+
+BIO_METHOD *BIO_s_accept(void)
+	{
+	return(&methods_acceptp);
+	}
+
+static int acpt_new(BIO *bi)
+	{
+	BIO_ACCEPT *ba;
+
+	bi->init=0;
+	bi->num=INVALID_SOCKET;
+	bi->flags=0;
+	if ((ba=BIO_ACCEPT_new()) == NULL)
+		return(0);
+	bi->ptr=(char *)ba;
+	ba->state=ACPT_S_BEFORE;
+	bi->shutdown=1;
+	return(1);
+	}
+
+static BIO_ACCEPT *BIO_ACCEPT_new(void)
+	{
+	BIO_ACCEPT *ret;
+
+	if ((ret=(BIO_ACCEPT *)OPENSSL_malloc(sizeof(BIO_ACCEPT))) == NULL)
+		return(NULL);
+
+	memset(ret,0,sizeof(BIO_ACCEPT));
+	ret->accept_sock=INVALID_SOCKET;
+	ret->bind_mode=BIO_BIND_NORMAL;
+	return(ret);
+	}
+
+static void BIO_ACCEPT_free(BIO_ACCEPT *a)
+	{
+	if(a == NULL)
+	    return;
+
+	if (a->param_addr != NULL) OPENSSL_free(a->param_addr);
+	if (a->addr != NULL) OPENSSL_free(a->addr);
+	if (a->bio_chain != NULL) BIO_free(a->bio_chain);
+	OPENSSL_free(a);
+	}
+
+static void acpt_close_socket(BIO *bio)
+	{
+	BIO_ACCEPT *c;
+
+	c=(BIO_ACCEPT *)bio->ptr;
+	if (c->accept_sock != INVALID_SOCKET)
+		{
+		shutdown(c->accept_sock,2);
+		closesocket(c->accept_sock);
+		c->accept_sock=INVALID_SOCKET;
+		bio->num=INVALID_SOCKET;
+		}
+	}
+
+static int acpt_free(BIO *a)
+	{
+	BIO_ACCEPT *data;
+
+	if (a == NULL) return(0);
+	data=(BIO_ACCEPT *)a->ptr;
+	 
+	if (a->shutdown)
+		{
+		acpt_close_socket(a);
+		BIO_ACCEPT_free(data);
+		a->ptr=NULL;
+		a->flags=0;
+		a->init=0;
+		}
+	return(1);
+	}
+	
+static int acpt_state(BIO *b, BIO_ACCEPT *c)
+	{
+	BIO *bio=NULL,*dbio;
+	int s= -1;
+	int i;
+
+again:
+	switch (c->state)
+		{
+	case ACPT_S_BEFORE:
+		if (c->param_addr == NULL)
+			{
+			BIOerr(BIO_F_ACPT_STATE,BIO_R_NO_ACCEPT_PORT_SPECIFIED);
+			return(-1);
+			}
+		s=BIO_get_accept_socket(c->param_addr,c->bind_mode);
+		if (s == INVALID_SOCKET)
+			return(-1);
+
+		if (c->accept_nbio)
+			{
+			if (!BIO_socket_nbio(s,1))
+				{
+				closesocket(s);
+				BIOerr(BIO_F_ACPT_STATE,BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET);
+				return(-1);
+				}
+			}
+		c->accept_sock=s;
+		b->num=s;
+		c->state=ACPT_S_GET_ACCEPT_SOCKET;
+		return(1);
+		/* break; */
+	case ACPT_S_GET_ACCEPT_SOCKET:
+		if (b->next_bio != NULL)
+			{
+			c->state=ACPT_S_OK;
+			goto again;
+			}
+		BIO_clear_retry_flags(b);
+		b->retry_reason=0;
+		i=BIO_accept(c->accept_sock,&(c->addr));
+
+		/* -2 return means we should retry */
+		if(i == -2)
+			{
+			BIO_set_retry_special(b);
+			b->retry_reason=BIO_RR_ACCEPT;
+			return -1;
+			}
+
+		if (i < 0) return(i);
+
+		bio=BIO_new_socket(i,BIO_CLOSE);
+		if (bio == NULL) goto err;
+
+		BIO_set_callback(bio,BIO_get_callback(b));
+		BIO_set_callback_arg(bio,BIO_get_callback_arg(b));
+
+		if (c->nbio)
+			{
+			if (!BIO_socket_nbio(i,1))
+				{
+				BIOerr(BIO_F_ACPT_STATE,BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET);
+				goto err;
+				}
+			}
+
+		/* If the accept BIO has an bio_chain, we dup it and
+		 * put the new socket at the end. */
+		if (c->bio_chain != NULL)
+			{
+			if ((dbio=BIO_dup_chain(c->bio_chain)) == NULL)
+				goto err;
+			if (!BIO_push(dbio,bio)) goto err;
+			bio=dbio;
+			}
+		if (BIO_push(b,bio) == NULL) goto err;
+
+		c->state=ACPT_S_OK;
+		return(1);
+err:
+		if (bio != NULL)
+			BIO_free(bio);
+		else if (s >= 0)
+			closesocket(s);
+		return(0);
+		/* break; */
+	case ACPT_S_OK:
+		if (b->next_bio == NULL)
+			{
+			c->state=ACPT_S_GET_ACCEPT_SOCKET;
+			goto again;
+			}
+		return(1);
+		/* break; */
+	default:	
+		return(0);
+		/* break; */
+		}
+
+	}
+
+static int acpt_read(BIO *b, char *out, int outl)
+	{
+	int ret=0;
+	BIO_ACCEPT *data;
+
+	BIO_clear_retry_flags(b);
+	data=(BIO_ACCEPT *)b->ptr;
+
+	while (b->next_bio == NULL)
+		{
+		ret=acpt_state(b,data);
+		if (ret <= 0) return(ret);
+		}
+
+	ret=BIO_read(b->next_bio,out,outl);
+	BIO_copy_next_retry(b);
+	return(ret);
+	}
+
+static int acpt_write(BIO *b, const char *in, int inl)
+	{
+	int ret;
+	BIO_ACCEPT *data;
+
+	BIO_clear_retry_flags(b);
+	data=(BIO_ACCEPT *)b->ptr;
+
+	while (b->next_bio == NULL)
+		{
+		ret=acpt_state(b,data);
+		if (ret <= 0) return(ret);
+		}
+
+	ret=BIO_write(b->next_bio,in,inl);
+	BIO_copy_next_retry(b);
+	return(ret);
+	}
+
+static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	int *ip;
+	long ret=1;
+	BIO_ACCEPT *data;
+	char **pp;
+
+	data=(BIO_ACCEPT *)b->ptr;
+
+	switch (cmd)
+		{
+	case BIO_CTRL_RESET:
+		ret=0;
+		data->state=ACPT_S_BEFORE;
+		acpt_close_socket(b);
+		b->flags=0;
+		break;
+	case BIO_C_DO_STATE_MACHINE:
+		/* use this one to start the connection */
+		ret=(long)acpt_state(b,data);
+		break;
+	case BIO_C_SET_ACCEPT:
+		if (ptr != NULL)
+			{
+			if (num == 0)
+				{
+				b->init=1;
+				if (data->param_addr != NULL)
+					OPENSSL_free(data->param_addr);
+				data->param_addr=BUF_strdup(ptr);
+				}
+			else if (num == 1)
+				{
+				data->accept_nbio=(ptr != NULL);
+				}
+			else if (num == 2)
+				{
+				if (data->bio_chain != NULL)
+					BIO_free(data->bio_chain);
+				data->bio_chain=(BIO *)ptr;
+				}
+			}
+		break;
+	case BIO_C_SET_NBIO:
+		data->nbio=(int)num;
+		break;
+	case BIO_C_SET_FD:
+		b->init=1;
+		b->num= *((int *)ptr);
+		data->accept_sock=b->num;
+		data->state=ACPT_S_GET_ACCEPT_SOCKET;
+		b->shutdown=(int)num;
+		b->init=1;
+		break;
+	case BIO_C_GET_FD:
+		if (b->init)
+			{
+			ip=(int *)ptr;
+			if (ip != NULL)
+				*ip=data->accept_sock;
+			ret=data->accept_sock;
+			}
+		else
+			ret= -1;
+		break;
+	case BIO_C_GET_ACCEPT:
+		if (b->init)
+			{
+			if (ptr != NULL)
+				{
+				pp=(char **)ptr;
+				*pp=data->param_addr;
+				}
+			else
+				ret= -1;
+			}
+		else
+			ret= -1;
+		break;
+	case BIO_CTRL_GET_CLOSE:
+		ret=b->shutdown;
+		break;
+	case BIO_CTRL_SET_CLOSE:
+		b->shutdown=(int)num;
+		break;
+	case BIO_CTRL_PENDING:
+	case BIO_CTRL_WPENDING:
+		ret=0;
+		break;
+	case BIO_CTRL_FLUSH:
+		break;
+	case BIO_C_SET_BIND_MODE:
+		data->bind_mode=(int)num;
+		break;
+	case BIO_C_GET_BIND_MODE:
+		ret=(long)data->bind_mode;
+		break;
+	case BIO_CTRL_DUP:
+/*		dbio=(BIO *)ptr;
+		if (data->param_port) EAY EAY
+			BIO_set_port(dbio,data->param_port);
+		if (data->param_hostname)
+			BIO_set_hostname(dbio,data->param_hostname);
+		BIO_set_nbio(dbio,data->nbio); */
+		break;
+
+	default:
+		ret=0;
+		break;
+		}
+	return(ret);
+	}
+
+static int acpt_puts(BIO *bp, const char *str)
+	{
+	int n,ret;
+
+	n=strlen(str);
+	ret=acpt_write(bp,str,n);
+	return(ret);
+	}
+
+BIO *BIO_new_accept(char *str)
+	{
+	BIO *ret;
+
+	ret=BIO_new(BIO_s_accept());
+	if (ret == NULL) return(NULL);
+	if (BIO_set_accept_port(ret,str))
+		return(ret);
+	else
+		{
+		BIO_free(ret);
+		return(NULL);
+		}
+	}
+
+#endif
diff --git a/openssl/crypto/bio/bss_bio.c b/openssl/crypto/bio/bss_bio.c
new file mode 100644
index 0000000..76bd48e
--- /dev/null
+++ b/openssl/crypto/bio/bss_bio.c
@@ -0,0 +1,924 @@
+/* crypto/bio/bss_bio.c  -*- Mode: C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Special method for a BIO where the other endpoint is also a BIO
+ * of this kind, handled by the same thread (i.e. the "peer" is actually
+ * ourselves, wearing a different hat).
+ * Such "BIO pairs" are mainly for using the SSL library with I/O interfaces
+ * for which no specific BIO method is available.
+ * See ssl/ssltest.c for some hints on how this can be used. */
+
+/* BIO_DEBUG implies BIO_PAIR_DEBUG */
+#ifdef BIO_DEBUG
+# ifndef BIO_PAIR_DEBUG
+#  define BIO_PAIR_DEBUG
+# endif
+#endif
+
+/* disable assert() unless BIO_PAIR_DEBUG has been defined */
+#ifndef BIO_PAIR_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+
+#include <assert.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/crypto.h>
+
+#include "e_os.h"
+
+/* VxWorks defines SSIZE_MAX with an empty value causing compile errors */
+#if defined(OPENSSL_SYS_VXWORKS)
+# undef SSIZE_MAX
+#endif
+#ifndef SSIZE_MAX
+# define SSIZE_MAX INT_MAX
+#endif
+
+static int bio_new(BIO *bio);
+static int bio_free(BIO *bio);
+static int bio_read(BIO *bio, char *buf, int size);
+static int bio_write(BIO *bio, const char *buf, int num);
+static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
+static int bio_puts(BIO *bio, const char *str);
+
+static int bio_make_pair(BIO *bio1, BIO *bio2);
+static void bio_destroy_pair(BIO *bio);
+
+static BIO_METHOD methods_biop =
+{
+	BIO_TYPE_BIO,
+	"BIO pair",
+	bio_write,
+	bio_read,
+	bio_puts,
+	NULL /* no bio_gets */,
+	bio_ctrl,
+	bio_new,
+	bio_free,
+	NULL /* no bio_callback_ctrl */
+};
+
+BIO_METHOD *BIO_s_bio(void)
+	{
+	return &methods_biop;
+	}
+
+struct bio_bio_st
+{
+	BIO *peer;     /* NULL if buf == NULL.
+	                * If peer != NULL, then peer->ptr is also a bio_bio_st,
+	                * and its "peer" member points back to us.
+	                * peer != NULL iff init != 0 in the BIO. */
+	
+	/* This is for what we write (i.e. reading uses peer's struct): */
+	int closed;     /* valid iff peer != NULL */
+	size_t len;     /* valid iff buf != NULL; 0 if peer == NULL */
+	size_t offset;  /* valid iff buf != NULL; 0 if len == 0 */
+	size_t size;
+	char *buf;      /* "size" elements (if != NULL) */
+
+	size_t request; /* valid iff peer != NULL; 0 if len != 0,
+	                 * otherwise set by peer to number of bytes
+	                 * it (unsuccessfully) tried to read,
+	                 * never more than buffer space (size-len) warrants. */
+};
+
+static int bio_new(BIO *bio)
+	{
+	struct bio_bio_st *b;
+	
+	b = OPENSSL_malloc(sizeof *b);
+	if (b == NULL)
+		return 0;
+
+	b->peer = NULL;
+	b->size = 17*1024; /* enough for one TLS record (just a default) */
+	b->buf = NULL;
+
+	bio->ptr = b;
+	return 1;
+	}
+
+
+static int bio_free(BIO *bio)
+	{
+	struct bio_bio_st *b;
+
+	if (bio == NULL)
+		return 0;
+	b = bio->ptr;
+
+	assert(b != NULL);
+
+	if (b->peer)
+		bio_destroy_pair(bio);
+	
+	if (b->buf != NULL)
+		{
+		OPENSSL_free(b->buf);
+		}
+
+	OPENSSL_free(b);
+
+	return 1;
+	}
+
+
+
+static int bio_read(BIO *bio, char *buf, int size_)
+	{
+	size_t size = size_;
+	size_t rest;
+	struct bio_bio_st *b, *peer_b;
+
+	BIO_clear_retry_flags(bio);
+
+	if (!bio->init)
+		return 0;
+
+	b = bio->ptr;
+	assert(b != NULL);
+	assert(b->peer != NULL);
+	peer_b = b->peer->ptr;
+	assert(peer_b != NULL);
+	assert(peer_b->buf != NULL);
+
+	peer_b->request = 0; /* will be set in "retry_read" situation */
+
+	if (buf == NULL || size == 0)
+		return 0;
+
+	if (peer_b->len == 0)
+		{
+		if (peer_b->closed)
+			return 0; /* writer has closed, and no data is left */
+		else
+			{
+			BIO_set_retry_read(bio); /* buffer is empty */
+			if (size <= peer_b->size)
+				peer_b->request = size;
+			else
+				/* don't ask for more than the peer can
+				 * deliver in one write */
+				peer_b->request = peer_b->size;
+			return -1;
+			}
+		}
+
+	/* we can read */
+	if (peer_b->len < size)
+		size = peer_b->len;
+
+	/* now read "size" bytes */
+	
+	rest = size;
+	
+	assert(rest > 0);
+	do /* one or two iterations */
+		{
+		size_t chunk;
+		
+		assert(rest <= peer_b->len);
+		if (peer_b->offset + rest <= peer_b->size)
+			chunk = rest;
+		else
+			/* wrap around ring buffer */
+			chunk = peer_b->size - peer_b->offset;
+		assert(peer_b->offset + chunk <= peer_b->size);
+		
+		memcpy(buf, peer_b->buf + peer_b->offset, chunk);
+		
+		peer_b->len -= chunk;
+		if (peer_b->len)
+			{
+			peer_b->offset += chunk;
+			assert(peer_b->offset <= peer_b->size);
+			if (peer_b->offset == peer_b->size)
+				peer_b->offset = 0;
+			buf += chunk;
+			}
+		else
+			{
+			/* buffer now empty, no need to advance "buf" */
+			assert(chunk == rest);
+			peer_b->offset = 0;
+			}
+		rest -= chunk;
+		}
+	while (rest);
+	
+	return size;
+	}
+
+/* non-copying interface: provide pointer to available data in buffer
+ *    bio_nread0:  return number of available bytes
+ *    bio_nread:   also advance index
+ * (example usage:  bio_nread0(), read from buffer, bio_nread()
+ *  or just         bio_nread(), read from buffer)
+ */
+/* WARNING: The non-copying interface is largely untested as of yet
+ * and may contain bugs. */
+static ssize_t bio_nread0(BIO *bio, char **buf)
+	{
+	struct bio_bio_st *b, *peer_b;
+	ssize_t num;
+	
+	BIO_clear_retry_flags(bio);
+
+	if (!bio->init)
+		return 0;
+	
+	b = bio->ptr;
+	assert(b != NULL);
+	assert(b->peer != NULL);
+	peer_b = b->peer->ptr;
+	assert(peer_b != NULL);
+	assert(peer_b->buf != NULL);
+	
+	peer_b->request = 0;
+	
+	if (peer_b->len == 0)
+		{
+		char dummy;
+		
+		/* avoid code duplication -- nothing available for reading */
+		return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
+		}
+
+	num = peer_b->len;
+	if (peer_b->size < peer_b->offset + num)
+		/* no ring buffer wrap-around for non-copying interface */
+		num = peer_b->size - peer_b->offset;
+	assert(num > 0);
+
+	if (buf != NULL)
+		*buf = peer_b->buf + peer_b->offset;
+	return num;
+	}
+
+static ssize_t bio_nread(BIO *bio, char **buf, size_t num_)
+	{
+	struct bio_bio_st *b, *peer_b;
+	ssize_t num, available;
+
+	if (num_ > SSIZE_MAX)
+		num = SSIZE_MAX;
+	else
+		num = (ssize_t)num_;
+
+	available = bio_nread0(bio, buf);
+	if (num > available)
+		num = available;
+	if (num <= 0)
+		return num;
+
+	b = bio->ptr;
+	peer_b = b->peer->ptr;
+
+	peer_b->len -= num;
+	if (peer_b->len) 
+		{
+		peer_b->offset += num;
+		assert(peer_b->offset <= peer_b->size);
+		if (peer_b->offset == peer_b->size)
+			peer_b->offset = 0;
+		}
+	else
+		peer_b->offset = 0;
+
+	return num;
+	}
+
+
+static int bio_write(BIO *bio, const char *buf, int num_)
+	{
+	size_t num = num_;
+	size_t rest;
+	struct bio_bio_st *b;
+
+	BIO_clear_retry_flags(bio);
+
+	if (!bio->init || buf == NULL || num == 0)
+		return 0;
+
+	b = bio->ptr;		
+	assert(b != NULL);
+	assert(b->peer != NULL);
+	assert(b->buf != NULL);
+
+	b->request = 0;
+	if (b->closed)
+		{
+		/* we already closed */
+		BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE);
+		return -1;
+		}
+
+	assert(b->len <= b->size);
+
+	if (b->len == b->size)
+		{
+		BIO_set_retry_write(bio); /* buffer is full */
+		return -1;
+		}
+
+	/* we can write */
+	if (num > b->size - b->len)
+		num = b->size - b->len;
+	
+	/* now write "num" bytes */
+
+	rest = num;
+	
+	assert(rest > 0);
+	do /* one or two iterations */
+		{
+		size_t write_offset;
+		size_t chunk;
+
+		assert(b->len + rest <= b->size);
+
+		write_offset = b->offset + b->len;
+		if (write_offset >= b->size)
+			write_offset -= b->size;
+		/* b->buf[write_offset] is the first byte we can write to. */
+
+		if (write_offset + rest <= b->size)
+			chunk = rest;
+		else
+			/* wrap around ring buffer */
+			chunk = b->size - write_offset;
+		
+		memcpy(b->buf + write_offset, buf, chunk);
+		
+		b->len += chunk;
+
+		assert(b->len <= b->size);
+		
+		rest -= chunk;
+		buf += chunk;
+		}
+	while (rest);
+
+	return num;
+	}
+
+/* non-copying interface: provide pointer to region to write to
+ *   bio_nwrite0:  check how much space is available
+ *   bio_nwrite:   also increase length
+ * (example usage:  bio_nwrite0(), write to buffer, bio_nwrite()
+ *  or just         bio_nwrite(), write to buffer)
+ */
+static ssize_t bio_nwrite0(BIO *bio, char **buf)
+	{
+	struct bio_bio_st *b;
+	size_t num;
+	size_t write_offset;
+
+	BIO_clear_retry_flags(bio);
+
+	if (!bio->init)
+		return 0;
+
+	b = bio->ptr;		
+	assert(b != NULL);
+	assert(b->peer != NULL);
+	assert(b->buf != NULL);
+
+	b->request = 0;
+	if (b->closed)
+		{
+		BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE);
+		return -1;
+		}
+
+	assert(b->len <= b->size);
+
+	if (b->len == b->size)
+		{
+		BIO_set_retry_write(bio);
+		return -1;
+		}
+
+	num = b->size - b->len;
+	write_offset = b->offset + b->len;
+	if (write_offset >= b->size)
+		write_offset -= b->size;
+	if (write_offset + num > b->size)
+		/* no ring buffer wrap-around for non-copying interface
+		 * (to fulfil the promise by BIO_ctrl_get_write_guarantee,
+		 * BIO_nwrite may have to be called twice) */
+		num = b->size - write_offset;
+
+	if (buf != NULL)
+		*buf = b->buf + write_offset;
+	assert(write_offset + num <= b->size);
+
+	return num;
+	}
+
+static ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_)
+	{
+	struct bio_bio_st *b;
+	ssize_t num, space;
+
+	if (num_ > SSIZE_MAX)
+		num = SSIZE_MAX;
+	else
+		num = (ssize_t)num_;
+
+	space = bio_nwrite0(bio, buf);
+	if (num > space)
+		num = space;
+	if (num <= 0)
+		return num;
+	b = bio->ptr;
+	assert(b != NULL);
+	b->len += num;
+	assert(b->len <= b->size);
+
+	return num;
+	}
+
+
+static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
+	{
+	long ret;
+	struct bio_bio_st *b = bio->ptr;
+	
+	assert(b != NULL);
+
+	switch (cmd)
+		{
+	/* specific CTRL codes */
+
+	case BIO_C_SET_WRITE_BUF_SIZE:
+		if (b->peer)
+			{
+			BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);
+			ret = 0;
+			}
+		else if (num == 0)
+			{
+			BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);
+			ret = 0;
+			}
+		else
+			{
+			size_t new_size = num;
+
+			if (b->size != new_size)
+				{
+				if (b->buf) 
+					{
+					OPENSSL_free(b->buf);
+					b->buf = NULL;
+					}
+				b->size = new_size;
+				}
+			ret = 1;
+			}
+		break;
+
+	case BIO_C_GET_WRITE_BUF_SIZE:
+		ret = (long) b->size;
+		break;
+
+	case BIO_C_MAKE_BIO_PAIR:
+		{
+		BIO *other_bio = ptr;
+		
+		if (bio_make_pair(bio, other_bio))
+			ret = 1;
+		else
+			ret = 0;
+		}
+		break;
+		
+	case BIO_C_DESTROY_BIO_PAIR:
+		/* Affects both BIOs in the pair -- call just once!
+		 * Or let BIO_free(bio1); BIO_free(bio2); do the job. */
+		bio_destroy_pair(bio);
+		ret = 1;
+		break;
+
+	case BIO_C_GET_WRITE_GUARANTEE:
+		/* How many bytes can the caller feed to the next write
+		 * without having to keep any? */
+		if (b->peer == NULL || b->closed)
+			ret = 0;
+		else
+			ret = (long) b->size - b->len;
+		break;
+
+	case BIO_C_GET_READ_REQUEST:
+		/* If the peer unsuccessfully tried to read, how many bytes
+		 * were requested?  (As with BIO_CTRL_PENDING, that number
+		 * can usually be treated as boolean.) */
+		ret = (long) b->request;
+		break;
+
+	case BIO_C_RESET_READ_REQUEST:
+		/* Reset request.  (Can be useful after read attempts
+		 * at the other side that are meant to be non-blocking,
+		 * e.g. when probing SSL_read to see if any data is
+		 * available.) */
+		b->request = 0;
+		ret = 1;
+		break;
+
+	case BIO_C_SHUTDOWN_WR:
+		/* similar to shutdown(..., SHUT_WR) */
+		b->closed = 1;
+		ret = 1;
+		break;
+
+	case BIO_C_NREAD0:
+		/* prepare for non-copying read */
+		ret = (long) bio_nread0(bio, ptr);
+		break;
+		
+	case BIO_C_NREAD:
+		/* non-copying read */
+		ret = (long) bio_nread(bio, ptr, (size_t) num);
+		break;
+		
+	case BIO_C_NWRITE0:
+		/* prepare for non-copying write */
+		ret = (long) bio_nwrite0(bio, ptr);
+		break;
+
+	case BIO_C_NWRITE:
+		/* non-copying write */
+		ret = (long) bio_nwrite(bio, ptr, (size_t) num);
+		break;
+		
+
+	/* standard CTRL codes follow */
+
+	case BIO_CTRL_RESET:
+		if (b->buf != NULL)
+			{
+			b->len = 0;
+			b->offset = 0;
+			}
+		ret = 0;
+		break;		
+
+	case BIO_CTRL_GET_CLOSE:
+		ret = bio->shutdown;
+		break;
+
+	case BIO_CTRL_SET_CLOSE:
+		bio->shutdown = (int) num;
+		ret = 1;
+		break;
+
+	case BIO_CTRL_PENDING:
+		if (b->peer != NULL)
+			{
+			struct bio_bio_st *peer_b = b->peer->ptr;
+			
+			ret = (long) peer_b->len;
+			}
+		else
+			ret = 0;
+		break;
+
+	case BIO_CTRL_WPENDING:
+		if (b->buf != NULL)
+			ret = (long) b->len;
+		else
+			ret = 0;
+		break;
+
+	case BIO_CTRL_DUP:
+		/* See BIO_dup_chain for circumstances we have to expect. */
+		{
+		BIO *other_bio = ptr;
+		struct bio_bio_st *other_b;
+		
+		assert(other_bio != NULL);
+		other_b = other_bio->ptr;
+		assert(other_b != NULL);
+		
+		assert(other_b->buf == NULL); /* other_bio is always fresh */
+
+		other_b->size = b->size;
+		}
+
+		ret = 1;
+		break;
+
+	case BIO_CTRL_FLUSH:
+		ret = 1;
+		break;
+
+	case BIO_CTRL_EOF:
+		{
+		BIO *other_bio = ptr;
+		
+		if (other_bio)
+			{
+			struct bio_bio_st *other_b = other_bio->ptr;
+			
+			assert(other_b != NULL);
+			ret = other_b->len == 0 && other_b->closed;
+			}
+		else
+			ret = 1;
+		}
+		break;
+
+	default:
+		ret = 0;
+		}
+	return ret;
+	}
+
+static int bio_puts(BIO *bio, const char *str)
+	{
+	return bio_write(bio, str, strlen(str));
+	}
+
+
+static int bio_make_pair(BIO *bio1, BIO *bio2)
+	{
+	struct bio_bio_st *b1, *b2;
+
+	assert(bio1 != NULL);
+	assert(bio2 != NULL);
+
+	b1 = bio1->ptr;
+	b2 = bio2->ptr;
+	
+	if (b1->peer != NULL || b2->peer != NULL)
+		{
+		BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
+		return 0;
+		}
+	
+	if (b1->buf == NULL)
+		{
+		b1->buf = OPENSSL_malloc(b1->size);
+		if (b1->buf == NULL)
+			{
+			BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		b1->len = 0;
+		b1->offset = 0;
+		}
+	
+	if (b2->buf == NULL)
+		{
+		b2->buf = OPENSSL_malloc(b2->size);
+		if (b2->buf == NULL)
+			{
+			BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		b2->len = 0;
+		b2->offset = 0;
+		}
+	
+	b1->peer = bio2;
+	b1->closed = 0;
+	b1->request = 0;
+	b2->peer = bio1;
+	b2->closed = 0;
+	b2->request = 0;
+
+	bio1->init = 1;
+	bio2->init = 1;
+
+	return 1;
+	}
+
+static void bio_destroy_pair(BIO *bio)
+	{
+	struct bio_bio_st *b = bio->ptr;
+
+	if (b != NULL)
+		{
+		BIO *peer_bio = b->peer;
+
+		if (peer_bio != NULL)
+			{
+			struct bio_bio_st *peer_b = peer_bio->ptr;
+
+			assert(peer_b != NULL);
+			assert(peer_b->peer == bio);
+
+			peer_b->peer = NULL;
+			peer_bio->init = 0;
+			assert(peer_b->buf != NULL);
+			peer_b->len = 0;
+			peer_b->offset = 0;
+			
+			b->peer = NULL;
+			bio->init = 0;
+			assert(b->buf != NULL);
+			b->len = 0;
+			b->offset = 0;
+			}
+		}
+	}
+ 
+
+/* Exported convenience functions */
+int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1,
+	BIO **bio2_p, size_t writebuf2)
+	 {
+	 BIO *bio1 = NULL, *bio2 = NULL;
+	 long r;
+	 int ret = 0;
+
+	 bio1 = BIO_new(BIO_s_bio());
+	 if (bio1 == NULL)
+		 goto err;
+	 bio2 = BIO_new(BIO_s_bio());
+	 if (bio2 == NULL)
+		 goto err;
+
+	 if (writebuf1)
+		 {
+		 r = BIO_set_write_buf_size(bio1, writebuf1);
+		 if (!r)
+			 goto err;
+		 }
+	 if (writebuf2)
+		 {
+		 r = BIO_set_write_buf_size(bio2, writebuf2);
+		 if (!r)
+			 goto err;
+		 }
+
+	 r = BIO_make_bio_pair(bio1, bio2);
+	 if (!r)
+		 goto err;
+	 ret = 1;
+
+ err:
+	 if (ret == 0)
+		 {
+		 if (bio1)
+			 {
+			 BIO_free(bio1);
+			 bio1 = NULL;
+			 }
+		 if (bio2)
+			 {
+			 BIO_free(bio2);
+			 bio2 = NULL;
+			 }
+		 }
+
+	 *bio1_p = bio1;
+	 *bio2_p = bio2;
+	 return ret;
+	 }
+
+size_t BIO_ctrl_get_write_guarantee(BIO *bio)
+	{
+	return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
+	}
+
+size_t BIO_ctrl_get_read_request(BIO *bio)
+	{
+	return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
+	}
+
+int BIO_ctrl_reset_read_request(BIO *bio)
+	{
+	return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
+	}
+
+
+/* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
+ * (conceivably some other BIOs could allow non-copying reads and writes too.)
+ */
+int BIO_nread0(BIO *bio, char **buf)
+	{
+	long ret;
+
+	if (!bio->init)
+		{
+		BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
+		return -2;
+		}
+
+	ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
+	if (ret > INT_MAX)
+		return INT_MAX;
+	else
+		return (int) ret;
+	}
+
+int BIO_nread(BIO *bio, char **buf, int num)
+	{
+	int ret;
+
+	if (!bio->init)
+		{
+		BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
+		return -2;
+		}
+
+	ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf);
+	if (ret > 0)
+		bio->num_read += ret;
+	return ret;
+	}
+
+int BIO_nwrite0(BIO *bio, char **buf)
+	{
+	long ret;
+
+	if (!bio->init)
+		{
+		BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
+		return -2;
+		}
+
+	ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
+	if (ret > INT_MAX)
+		return INT_MAX;
+	else
+		return (int) ret;
+	}
+
+int BIO_nwrite(BIO *bio, char **buf, int num)
+	{
+	int ret;
+
+	if (!bio->init)
+		{
+		BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
+		return -2;
+		}
+
+	ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
+	if (ret > 0)
+		bio->num_write += ret;
+	return ret;
+	}
diff --git a/openssl/crypto/bio/bss_conn.c b/openssl/crypto/bio/bss_conn.c
new file mode 100644
index 0000000..c147278
--- /dev/null
+++ b/openssl/crypto/bio/bss_conn.c
@@ -0,0 +1,652 @@
+/* crypto/bio/bss_conn.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "cryptlib.h"
+#include <openssl/bio.h>
+
+#ifndef OPENSSL_NO_SOCK
+
+#ifdef OPENSSL_SYS_WIN16
+#define SOCKET_PROTOCOL 0 /* more microsoft stupidity */
+#else
+#define SOCKET_PROTOCOL IPPROTO_TCP
+#endif
+
+#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
+/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
+#undef FIONBIO
+#endif
+
+
+typedef struct bio_connect_st
+	{
+	int state;
+
+	char *param_hostname;
+	char *param_port;
+	int nbio;
+
+	unsigned char ip[4];
+	unsigned short port;
+
+	struct sockaddr_in them;
+
+	/* int socket; this will be kept in bio->num so that it is
+	 * compatible with the bss_sock bio */ 
+
+	/* called when the connection is initially made
+	 *  callback(BIO,state,ret);  The callback should return
+	 * 'ret'.  state is for compatibility with the ssl info_callback */
+	int (*info_callback)(const BIO *bio,int state,int ret);
+	} BIO_CONNECT;
+
+static int conn_write(BIO *h, const char *buf, int num);
+static int conn_read(BIO *h, char *buf, int size);
+static int conn_puts(BIO *h, const char *str);
+static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int conn_new(BIO *h);
+static int conn_free(BIO *data);
+static long conn_callback_ctrl(BIO *h, int cmd, bio_info_cb *);
+
+static int conn_state(BIO *b, BIO_CONNECT *c);
+static void conn_close_socket(BIO *data);
+BIO_CONNECT *BIO_CONNECT_new(void );
+void BIO_CONNECT_free(BIO_CONNECT *a);
+
+static BIO_METHOD methods_connectp=
+	{
+	BIO_TYPE_CONNECT,
+	"socket connect",
+	conn_write,
+	conn_read,
+	conn_puts,
+	NULL, /* connect_gets, */
+	conn_ctrl,
+	conn_new,
+	conn_free,
+	conn_callback_ctrl,
+	};
+
+static int conn_state(BIO *b, BIO_CONNECT *c)
+	{
+	int ret= -1,i;
+	unsigned long l;
+	char *p,*q;
+	int (*cb)(const BIO *,int,int)=NULL;
+
+	if (c->info_callback != NULL)
+		cb=c->info_callback;
+
+	for (;;)
+		{
+		switch (c->state)
+			{
+		case BIO_CONN_S_BEFORE:
+			p=c->param_hostname;
+			if (p == NULL)
+				{
+				BIOerr(BIO_F_CONN_STATE,BIO_R_NO_HOSTNAME_SPECIFIED);
+				goto exit_loop;
+				}
+			for ( ; *p != '\0'; p++)
+				{
+				if ((*p == ':') || (*p == '/')) break;
+				}
+
+			i= *p;
+			if ((i == ':') || (i == '/'))
+				{
+
+				*(p++)='\0';
+				if (i == ':')
+					{
+					for (q=p; *q; q++)
+						if (*q == '/')
+							{
+							*q='\0';
+							break;
+							}
+					if (c->param_port != NULL)
+						OPENSSL_free(c->param_port);
+					c->param_port=BUF_strdup(p);
+					}
+				}
+
+			if (c->param_port == NULL)
+				{
+				BIOerr(BIO_F_CONN_STATE,BIO_R_NO_PORT_SPECIFIED);
+				ERR_add_error_data(2,"host=",c->param_hostname);
+				goto exit_loop;
+				}
+			c->state=BIO_CONN_S_GET_IP;
+			break;
+
+		case BIO_CONN_S_GET_IP:
+			if (BIO_get_host_ip(c->param_hostname,&(c->ip[0])) <= 0)
+				goto exit_loop;
+			c->state=BIO_CONN_S_GET_PORT;
+			break;
+
+		case BIO_CONN_S_GET_PORT:
+			if (c->param_port == NULL)
+				{
+				/* abort(); */
+				goto exit_loop;
+				}
+			else if (BIO_get_port(c->param_port,&c->port) <= 0)
+				goto exit_loop;
+			c->state=BIO_CONN_S_CREATE_SOCKET;
+			break;
+
+		case BIO_CONN_S_CREATE_SOCKET:
+			/* now setup address */
+			memset((char *)&c->them,0,sizeof(c->them));
+			c->them.sin_family=AF_INET;
+			c->them.sin_port=htons((unsigned short)c->port);
+			l=(unsigned long)
+				((unsigned long)c->ip[0]<<24L)|
+				((unsigned long)c->ip[1]<<16L)|
+				((unsigned long)c->ip[2]<< 8L)|
+				((unsigned long)c->ip[3]);
+			c->them.sin_addr.s_addr=htonl(l);
+			c->state=BIO_CONN_S_CREATE_SOCKET;
+
+			ret=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
+			if (ret == INVALID_SOCKET)
+				{
+				SYSerr(SYS_F_SOCKET,get_last_socket_error());
+				ERR_add_error_data(4,"host=",c->param_hostname,
+					":",c->param_port);
+				BIOerr(BIO_F_CONN_STATE,BIO_R_UNABLE_TO_CREATE_SOCKET);
+				goto exit_loop;
+				}
+			b->num=ret;
+			c->state=BIO_CONN_S_NBIO;
+			break;
+
+		case BIO_CONN_S_NBIO:
+			if (c->nbio)
+				{
+				if (!BIO_socket_nbio(b->num,1))
+					{
+					BIOerr(BIO_F_CONN_STATE,BIO_R_ERROR_SETTING_NBIO);
+					ERR_add_error_data(4,"host=",
+						c->param_hostname,
+						":",c->param_port);
+					goto exit_loop;
+					}
+				}
+			c->state=BIO_CONN_S_CONNECT;
+
+#if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE)
+			i=1;
+			i=setsockopt(b->num,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
+			if (i < 0)
+				{
+				SYSerr(SYS_F_SOCKET,get_last_socket_error());
+				ERR_add_error_data(4,"host=",c->param_hostname,
+					":",c->param_port);
+				BIOerr(BIO_F_CONN_STATE,BIO_R_KEEPALIVE);
+				goto exit_loop;
+				}
+#endif
+			break;
+
+		case BIO_CONN_S_CONNECT:
+			BIO_clear_retry_flags(b);
+			ret=connect(b->num,
+				(struct sockaddr *)&c->them,
+				sizeof(c->them));
+			b->retry_reason=0;
+			if (ret < 0)
+				{
+				if (BIO_sock_should_retry(ret))
+					{
+					BIO_set_retry_special(b);
+					c->state=BIO_CONN_S_BLOCKED_CONNECT;
+					b->retry_reason=BIO_RR_CONNECT;
+					}
+				else
+					{
+					SYSerr(SYS_F_CONNECT,get_last_socket_error());
+					ERR_add_error_data(4,"host=",
+						c->param_hostname,
+						":",c->param_port);
+					BIOerr(BIO_F_CONN_STATE,BIO_R_CONNECT_ERROR);
+					}
+				goto exit_loop;
+				}
+			else
+				c->state=BIO_CONN_S_OK;
+			break;
+
+		case BIO_CONN_S_BLOCKED_CONNECT:
+			i=BIO_sock_error(b->num);
+			if (i)
+				{
+				BIO_clear_retry_flags(b);
+				SYSerr(SYS_F_CONNECT,i);
+				ERR_add_error_data(4,"host=",
+					c->param_hostname,
+					":",c->param_port);
+				BIOerr(BIO_F_CONN_STATE,BIO_R_NBIO_CONNECT_ERROR);
+				ret=0;
+				goto exit_loop;
+				}
+			else
+				c->state=BIO_CONN_S_OK;
+			break;
+
+		case BIO_CONN_S_OK:
+			ret=1;
+			goto exit_loop;
+		default:
+			/* abort(); */
+			goto exit_loop;
+			}
+
+		if (cb != NULL)
+			{
+			if (!(ret=cb((BIO *)b,c->state,ret)))
+				goto end;
+			}
+		}
+
+	/* Loop does not exit */
+exit_loop:
+	if (cb != NULL)
+		ret=cb((BIO *)b,c->state,ret);
+end:
+	return(ret);
+	}
+
+BIO_CONNECT *BIO_CONNECT_new(void)
+	{
+	BIO_CONNECT *ret;
+
+	if ((ret=(BIO_CONNECT *)OPENSSL_malloc(sizeof(BIO_CONNECT))) == NULL)
+		return(NULL);
+	ret->state=BIO_CONN_S_BEFORE;
+	ret->param_hostname=NULL;
+	ret->param_port=NULL;
+	ret->info_callback=NULL;
+	ret->nbio=0;
+	ret->ip[0]=0;
+	ret->ip[1]=0;
+	ret->ip[2]=0;
+	ret->ip[3]=0;
+	ret->port=0;
+	memset((char *)&ret->them,0,sizeof(ret->them));
+	return(ret);
+	}
+
+void BIO_CONNECT_free(BIO_CONNECT *a)
+	{
+	if(a == NULL)
+	    return;
+
+	if (a->param_hostname != NULL)
+		OPENSSL_free(a->param_hostname);
+	if (a->param_port != NULL)
+		OPENSSL_free(a->param_port);
+	OPENSSL_free(a);
+	}
+
+BIO_METHOD *BIO_s_connect(void)
+	{
+	return(&methods_connectp);
+	}
+
+static int conn_new(BIO *bi)
+	{
+	bi->init=0;
+	bi->num=INVALID_SOCKET;
+	bi->flags=0;
+	if ((bi->ptr=(char *)BIO_CONNECT_new()) == NULL)
+		return(0);
+	else
+		return(1);
+	}
+
+static void conn_close_socket(BIO *bio)
+	{
+	BIO_CONNECT *c;
+
+	c=(BIO_CONNECT *)bio->ptr;
+	if (bio->num != INVALID_SOCKET)
+		{
+		/* Only do a shutdown if things were established */
+		if (c->state == BIO_CONN_S_OK)
+			shutdown(bio->num,2);
+		closesocket(bio->num);
+		bio->num=INVALID_SOCKET;
+		}
+	}
+
+static int conn_free(BIO *a)
+	{
+	BIO_CONNECT *data;
+
+	if (a == NULL) return(0);
+	data=(BIO_CONNECT *)a->ptr;
+	 
+	if (a->shutdown)
+		{
+		conn_close_socket(a);
+		BIO_CONNECT_free(data);
+		a->ptr=NULL;
+		a->flags=0;
+		a->init=0;
+		}
+	return(1);
+	}
+	
+static int conn_read(BIO *b, char *out, int outl)
+	{
+	int ret=0;
+	BIO_CONNECT *data;
+
+	data=(BIO_CONNECT *)b->ptr;
+	if (data->state != BIO_CONN_S_OK)
+		{
+		ret=conn_state(b,data);
+		if (ret <= 0)
+				return(ret);
+		}
+
+	if (out != NULL)
+		{
+		clear_socket_error();
+		ret=readsocket(b->num,out,outl);
+		BIO_clear_retry_flags(b);
+		if (ret <= 0)
+			{
+			if (BIO_sock_should_retry(ret))
+				BIO_set_retry_read(b);
+			}
+		}
+	return(ret);
+	}
+
+static int conn_write(BIO *b, const char *in, int inl)
+	{
+	int ret;
+	BIO_CONNECT *data;
+
+	data=(BIO_CONNECT *)b->ptr;
+	if (data->state != BIO_CONN_S_OK)
+		{
+		ret=conn_state(b,data);
+		if (ret <= 0) return(ret);
+		}
+
+	clear_socket_error();
+	ret=writesocket(b->num,in,inl);
+	BIO_clear_retry_flags(b);
+	if (ret <= 0)
+		{
+		if (BIO_sock_should_retry(ret))
+			BIO_set_retry_write(b);
+		}
+	return(ret);
+	}
+
+static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	BIO *dbio;
+	int *ip;
+	const char **pptr;
+	long ret=1;
+	BIO_CONNECT *data;
+
+	data=(BIO_CONNECT *)b->ptr;
+
+	switch (cmd)
+		{
+	case BIO_CTRL_RESET:
+		ret=0;
+		data->state=BIO_CONN_S_BEFORE;
+		conn_close_socket(b);
+		b->flags=0;
+		break;
+	case BIO_C_DO_STATE_MACHINE:
+		/* use this one to start the connection */
+		if (data->state != BIO_CONN_S_OK)
+			ret=(long)conn_state(b,data);
+		else
+			ret=1;
+		break;
+	case BIO_C_GET_CONNECT:
+		if (ptr != NULL)
+			{
+			pptr=(const char **)ptr;
+			if (num == 0)
+				{
+				*pptr=data->param_hostname;
+
+				}
+			else if (num == 1)
+				{
+				*pptr=data->param_port;
+				}
+			else if (num == 2)
+				{
+				*pptr= (char *)&(data->ip[0]);
+				}
+			else if (num == 3)
+				{
+				*((int *)ptr)=data->port;
+				}
+			if ((!b->init) || (ptr == NULL))
+				*pptr="not initialized";
+			ret=1;
+			}
+		break;
+	case BIO_C_SET_CONNECT:
+		if (ptr != NULL)
+			{
+			b->init=1;
+			if (num == 0)
+				{
+				if (data->param_hostname != NULL)
+					OPENSSL_free(data->param_hostname);
+				data->param_hostname=BUF_strdup(ptr);
+				}
+			else if (num == 1)
+				{
+				if (data->param_port != NULL)
+					OPENSSL_free(data->param_port);
+				data->param_port=BUF_strdup(ptr);
+				}
+			else if (num == 2)
+				{
+				char buf[16];
+				unsigned char *p = ptr;
+
+				BIO_snprintf(buf,sizeof buf,"%d.%d.%d.%d",
+					     p[0],p[1],p[2],p[3]);
+				if (data->param_hostname != NULL)
+					OPENSSL_free(data->param_hostname);
+				data->param_hostname=BUF_strdup(buf);
+				memcpy(&(data->ip[0]),ptr,4);
+				}
+			else if (num == 3)
+				{
+				char buf[DECIMAL_SIZE(int)+1];
+
+				BIO_snprintf(buf,sizeof buf,"%d",*(int *)ptr);
+				if (data->param_port != NULL)
+					OPENSSL_free(data->param_port);
+				data->param_port=BUF_strdup(buf);
+				data->port= *(int *)ptr;
+				}
+			}
+		break;
+	case BIO_C_SET_NBIO:
+		data->nbio=(int)num;
+		break;
+	case BIO_C_GET_FD:
+		if (b->init)
+			{
+			ip=(int *)ptr;
+			if (ip != NULL)
+				*ip=b->num;
+			ret=b->num;
+			}
+		else
+			ret= -1;
+		break;
+	case BIO_CTRL_GET_CLOSE:
+		ret=b->shutdown;
+		break;
+	case BIO_CTRL_SET_CLOSE:
+		b->shutdown=(int)num;
+		break;
+	case BIO_CTRL_PENDING:
+	case BIO_CTRL_WPENDING:
+		ret=0;
+		break;
+	case BIO_CTRL_FLUSH:
+		break;
+	case BIO_CTRL_DUP:
+		{
+		dbio=(BIO *)ptr;
+		if (data->param_port)
+			BIO_set_conn_port(dbio,data->param_port);
+		if (data->param_hostname)
+			BIO_set_conn_hostname(dbio,data->param_hostname);
+		BIO_set_nbio(dbio,data->nbio);
+		/* FIXME: the cast of the function seems unlikely to be a good idea */
+                (void)BIO_set_info_callback(dbio,(bio_info_cb *)data->info_callback);
+		}
+		break;
+	case BIO_CTRL_SET_CALLBACK:
+		{
+#if 0 /* FIXME: Should this be used?  -- Richard Levitte */
+		BIOerr(BIO_F_CONN_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		ret = -1;
+#else
+		ret=0;
+#endif
+		}
+		break;
+	case BIO_CTRL_GET_CALLBACK:
+		{
+		int (**fptr)(const BIO *bio,int state,int xret);
+
+		fptr=(int (**)(const BIO *bio,int state,int xret))ptr;
+		*fptr=data->info_callback;
+		}
+		break;
+	default:
+		ret=0;
+		break;
+		}
+	return(ret);
+	}
+
+static long conn_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+	{
+	long ret=1;
+	BIO_CONNECT *data;
+
+	data=(BIO_CONNECT *)b->ptr;
+
+	switch (cmd)
+		{
+	case BIO_CTRL_SET_CALLBACK:
+		{
+		data->info_callback=(int (*)(const struct bio_st *, int, int))fp;
+		}
+		break;
+	default:
+		ret=0;
+		break;
+		}
+	return(ret);
+	}
+
+static int conn_puts(BIO *bp, const char *str)
+	{
+	int n,ret;
+
+	n=strlen(str);
+	ret=conn_write(bp,str,n);
+	return(ret);
+	}
+
+BIO *BIO_new_connect(char *str)
+	{
+	BIO *ret;
+
+	ret=BIO_new(BIO_s_connect());
+	if (ret == NULL) return(NULL);
+	if (BIO_set_conn_hostname(ret,str))
+		return(ret);
+	else
+		{
+		BIO_free(ret);
+		return(NULL);
+		}
+	}
+
+#endif
+
diff --git a/openssl/crypto/bio/bss_dgram.c b/openssl/crypto/bio/bss_dgram.c
new file mode 100644
index 0000000..a6d882b
--- /dev/null
+++ b/openssl/crypto/bio/bss_dgram.c
@@ -0,0 +1,836 @@
+/* crypto/bio/bio_dgram.c */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "cryptlib.h"
+
+#include <openssl/bio.h>
+#ifndef OPENSSL_NO_DGRAM
+
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
+#include <sys/timeb.h>
+#endif
+
+#ifdef OPENSSL_SYS_LINUX
+#define IP_MTU      14 /* linux is lame */
+#endif
+
+#ifdef WATT32
+#define sock_write SockWrite  /* Watt-32 uses same names */
+#define sock_read  SockRead
+#define sock_puts  SockPuts
+#endif
+
+static int dgram_write(BIO *h, const char *buf, int num);
+static int dgram_read(BIO *h, char *buf, int size);
+static int dgram_puts(BIO *h, const char *str);
+static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int dgram_new(BIO *h);
+static int dgram_free(BIO *data);
+static int dgram_clear(BIO *bio);
+
+static int BIO_dgram_should_retry(int s);
+
+static void get_current_time(struct timeval *t);
+
+static BIO_METHOD methods_dgramp=
+	{
+	BIO_TYPE_DGRAM,
+	"datagram socket",
+	dgram_write,
+	dgram_read,
+	dgram_puts,
+	NULL, /* dgram_gets, */
+	dgram_ctrl,
+	dgram_new,
+	dgram_free,
+	NULL,
+	};
+
+typedef struct bio_dgram_data_st
+	{
+	union {
+		struct sockaddr sa;
+		struct sockaddr_in sa_in;
+#if OPENSSL_USE_IPV6
+		struct sockaddr_in6 sa_in6;
+#endif
+	} peer;
+	unsigned int connected;
+	unsigned int _errno;
+	unsigned int mtu;
+	struct timeval next_timeout;
+	struct timeval socket_timeout;
+	} bio_dgram_data;
+
+BIO_METHOD *BIO_s_datagram(void)
+	{
+	return(&methods_dgramp);
+	}
+
+BIO *BIO_new_dgram(int fd, int close_flag)
+	{
+	BIO *ret;
+
+	ret=BIO_new(BIO_s_datagram());
+	if (ret == NULL) return(NULL);
+	BIO_set_fd(ret,fd,close_flag);
+	return(ret);
+	}
+
+static int dgram_new(BIO *bi)
+	{
+	bio_dgram_data *data = NULL;
+
+	bi->init=0;
+	bi->num=0;
+	data = OPENSSL_malloc(sizeof(bio_dgram_data));
+	if (data == NULL)
+		return 0;
+	memset(data, 0x00, sizeof(bio_dgram_data));
+    bi->ptr = data;
+
+	bi->flags=0;
+	return(1);
+	}
+
+static int dgram_free(BIO *a)
+	{
+	bio_dgram_data *data;
+
+	if (a == NULL) return(0);
+	if ( ! dgram_clear(a))
+		return 0;
+
+	data = (bio_dgram_data *)a->ptr;
+	if(data != NULL) OPENSSL_free(data);
+
+	return(1);
+	}
+
+static int dgram_clear(BIO *a)
+	{
+	if (a == NULL) return(0);
+	if (a->shutdown)
+		{
+		if (a->init)
+			{
+			SHUTDOWN2(a->num);
+			}
+		a->init=0;
+		a->flags=0;
+		}
+	return(1);
+	}
+
+static void dgram_adjust_rcv_timeout(BIO *b)
+	{
+#if defined(SO_RCVTIMEO)
+	bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+	int sz = sizeof(int);
+
+	/* Is a timer active? */
+	if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0)
+		{
+		struct timeval timenow, timeleft;
+
+		/* Read current socket timeout */
+#ifdef OPENSSL_SYS_WINDOWS
+		int timeout;
+		if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+					   (void*)&timeout, &sz) < 0)
+			{ perror("getsockopt"); }
+		else
+			{
+			data->socket_timeout.tv_sec = timeout / 1000;
+			data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
+			}
+#else
+		if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 
+						&(data->socket_timeout), (void *)&sz) < 0)
+			{ perror("getsockopt"); }
+#endif
+
+		/* Get current time */
+		get_current_time(&timenow);
+
+		/* Calculate time left until timer expires */
+		memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
+		timeleft.tv_sec -= timenow.tv_sec;
+		timeleft.tv_usec -= timenow.tv_usec;
+		if (timeleft.tv_usec < 0)
+			{
+			timeleft.tv_sec--;
+			timeleft.tv_usec += 1000000;
+			}
+
+		if (timeleft.tv_sec < 0)
+			{
+			timeleft.tv_sec = 0;
+			timeleft.tv_usec = 1;
+			}
+
+		/* Adjust socket timeout if next handhake message timer
+		 * will expire earlier.
+		 */
+		if ((data->socket_timeout.tv_sec == 0 && data->socket_timeout.tv_usec == 0) ||
+			(data->socket_timeout.tv_sec > timeleft.tv_sec) ||
+			(data->socket_timeout.tv_sec == timeleft.tv_sec &&
+			 data->socket_timeout.tv_usec >= timeleft.tv_usec))
+			{
+#ifdef OPENSSL_SYS_WINDOWS
+			timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000;
+			if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+						   (void*)&timeout, sizeof(timeout)) < 0)
+				{ perror("setsockopt"); }
+#else
+			if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft,
+							sizeof(struct timeval)) < 0)
+				{ perror("setsockopt"); }
+#endif
+			}
+		}
+#endif
+	}
+
+static void dgram_reset_rcv_timeout(BIO *b)
+	{
+#if defined(SO_RCVTIMEO)
+	bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+
+	/* Is a timer active? */
+	if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0)
+		{
+#ifdef OPENSSL_SYS_WINDOWS
+		int timeout = data->socket_timeout.tv_sec * 1000 +
+					  data->socket_timeout.tv_usec / 1000;
+		if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+					   (void*)&timeout, sizeof(timeout)) < 0)
+			{ perror("setsockopt"); }
+#else
+		if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout),
+						sizeof(struct timeval)) < 0)
+			{ perror("setsockopt"); }
+#endif
+		}
+#endif
+	}
+
+static int dgram_read(BIO *b, char *out, int outl)
+	{
+	int ret=0;
+	bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+
+	struct	{
+	/*
+	 * See commentary in b_sock.c. <appro>
+	 */
+	union	{ size_t s; int i; } len;
+	union	{
+		struct sockaddr sa;
+		struct sockaddr_in sa_in;
+#if OPENSSL_USE_IPV6
+		struct sockaddr_in6 sa_in6;
+#endif
+		} peer;
+	} sa;
+
+	sa.len.s=0;
+	sa.len.i=sizeof(sa.peer);
+
+	if (out != NULL)
+		{
+		clear_socket_error();
+		memset(&sa.peer, 0x00, sizeof(sa.peer));
+		dgram_adjust_rcv_timeout(b);
+		ret=recvfrom(b->num,out,outl,0,&sa.peer.sa,(void *)&sa.len);
+		if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0)
+			{
+			OPENSSL_assert(sa.len.s<=sizeof(sa.peer));
+			sa.len.i = (int)sa.len.s;
+			}
+
+		if ( ! data->connected  && ret >= 0)
+			BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer);
+
+		BIO_clear_retry_flags(b);
+		if (ret < 0)
+			{
+			if (BIO_dgram_should_retry(ret))
+				{
+				BIO_set_retry_read(b);
+				data->_errno = get_last_socket_error();
+				}
+			}
+
+		dgram_reset_rcv_timeout(b);
+		}
+	return(ret);
+	}
+
+static int dgram_write(BIO *b, const char *in, int inl)
+	{
+	int ret;
+	bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+	clear_socket_error();
+
+	if ( data->connected )
+		ret=writesocket(b->num,in,inl);
+	else
+		{
+		int peerlen = sizeof(data->peer);
+
+		if (data->peer.sa.sa_family == AF_INET)
+			peerlen = sizeof(data->peer.sa_in);
+#if OPENSSL_USE_IPV6
+		else if (data->peer.sa.sa_family == AF_INET6)
+			peerlen = sizeof(data->peer.sa_in6);
+#endif
+#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
+		ret=sendto(b->num, (char *)in, inl, 0, &data->peer.sa, peerlen);
+#else
+		ret=sendto(b->num, in, inl, 0, &data->peer.sa, peerlen);
+#endif
+		}
+
+	BIO_clear_retry_flags(b);
+	if (ret <= 0)
+		{
+		if (BIO_dgram_should_retry(ret))
+			{
+			BIO_set_retry_write(b);  
+			data->_errno = get_last_socket_error();
+
+#if 0 /* higher layers are responsible for querying MTU, if necessary */
+			if ( data->_errno == EMSGSIZE)
+				/* retrieve the new MTU */
+				BIO_ctrl(b, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
+#endif
+			}
+		}
+	return(ret);
+	}
+
+static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	long ret=1;
+	int *ip;
+	struct sockaddr *to = NULL;
+	bio_dgram_data *data = NULL;
+#if defined(IP_MTU_DISCOVER) || defined(IP_MTU)
+	long sockopt_val = 0;
+	socklen_t sockopt_len = 0;
+#endif
+#ifdef OPENSSL_SYS_LINUX
+	socklen_t addr_len;
+	union	{
+		struct sockaddr	sa;
+		struct sockaddr_in s4;
+#if OPENSSL_USE_IPV6
+		struct sockaddr_in6 s6;
+#endif
+		} addr;
+#endif
+
+	data = (bio_dgram_data *)b->ptr;
+
+	switch (cmd)
+		{
+	case BIO_CTRL_RESET:
+		num=0;
+	case BIO_C_FILE_SEEK:
+		ret=0;
+		break;
+	case BIO_C_FILE_TELL:
+	case BIO_CTRL_INFO:
+		ret=0;
+		break;
+	case BIO_C_SET_FD:
+		dgram_clear(b);
+		b->num= *((int *)ptr);
+		b->shutdown=(int)num;
+		b->init=1;
+		break;
+	case BIO_C_GET_FD:
+		if (b->init)
+			{
+			ip=(int *)ptr;
+			if (ip != NULL) *ip=b->num;
+			ret=b->num;
+			}
+		else
+			ret= -1;
+		break;
+	case BIO_CTRL_GET_CLOSE:
+		ret=b->shutdown;
+		break;
+	case BIO_CTRL_SET_CLOSE:
+		b->shutdown=(int)num;
+		break;
+	case BIO_CTRL_PENDING:
+	case BIO_CTRL_WPENDING:
+		ret=0;
+		break;
+	case BIO_CTRL_DUP:
+	case BIO_CTRL_FLUSH:
+		ret=1;
+		break;
+	case BIO_CTRL_DGRAM_CONNECT:
+		to = (struct sockaddr *)ptr;
+#if 0
+		if (connect(b->num, to, sizeof(struct sockaddr)) < 0)
+			{ perror("connect"); ret = 0; }
+		else
+			{
+#endif
+			switch (to->sa_family)
+				{
+				case AF_INET:
+					memcpy(&data->peer,to,sizeof(data->peer.sa_in));
+					break;
+#if OPENSSL_USE_IPV6
+				case AF_INET6:
+					memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
+					break;
+#endif
+				default:
+					memcpy(&data->peer,to,sizeof(data->peer.sa));
+					break;
+				}
+#if 0
+			}
+#endif
+		break;
+		/* (Linux)kernel sets DF bit on outgoing IP packets */
+	case BIO_CTRL_DGRAM_MTU_DISCOVER:
+#ifdef OPENSSL_SYS_LINUX
+		addr_len = (socklen_t)sizeof(addr);
+		memset((void *)&addr, 0, sizeof(addr));
+		if (getsockname(b->num, &addr.sa, &addr_len) < 0)
+			{
+			ret = 0;
+			break;
+			}
+		sockopt_len = sizeof(sockopt_val);
+		switch (addr.sa.sa_family)
+			{
+		case AF_INET:
+			sockopt_val = IP_PMTUDISC_DO;
+			if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
+				&sockopt_val, sizeof(sockopt_val))) < 0)
+				perror("setsockopt");
+			break;
+#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER)
+		case AF_INET6:
+			sockopt_val = IPV6_PMTUDISC_DO;
+			if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
+				&sockopt_val, sizeof(sockopt_val))) < 0)
+				perror("setsockopt");
+			break;
+#endif
+		default:
+			ret = -1;
+			break;
+			}
+		ret = -1;
+#else
+		break;
+#endif
+	case BIO_CTRL_DGRAM_QUERY_MTU:
+#ifdef OPENSSL_SYS_LINUX
+		addr_len = (socklen_t)sizeof(addr);
+		memset((void *)&addr, 0, sizeof(addr));
+		if (getsockname(b->num, &addr.sa, &addr_len) < 0)
+			{
+			ret = 0;
+			break;
+			}
+		sockopt_len = sizeof(sockopt_val);
+		switch (addr.sa.sa_family)
+			{
+		case AF_INET:
+			if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
+				&sockopt_len)) < 0 || sockopt_val < 0)
+				{
+				ret = 0;
+				}
+			else
+				{
+				/* we assume that the transport protocol is UDP and no
+				 * IP options are used.
+				 */
+				data->mtu = sockopt_val - 8 - 20;
+				ret = data->mtu;
+				}
+			break;
+#if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
+		case AF_INET6:
+			if ((ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, (void *)&sockopt_val,
+				&sockopt_len)) < 0 || sockopt_val < 0)
+				{
+				ret = 0;
+				}
+			else
+				{
+				/* we assume that the transport protocol is UDP and no
+				 * IPV6 options are used.
+				 */
+				data->mtu = sockopt_val - 8 - 40;
+				ret = data->mtu;
+				}
+			break;
+#endif
+		default:
+			ret = 0;
+			break;
+			}
+#else
+		ret = 0;
+#endif
+		break;
+	case BIO_CTRL_DGRAM_GET_MTU:
+		return data->mtu;
+		break;
+	case BIO_CTRL_DGRAM_SET_MTU:
+		data->mtu = num;
+		ret = num;
+		break;
+	case BIO_CTRL_DGRAM_SET_CONNECTED:
+		to = (struct sockaddr *)ptr;
+
+		if ( to != NULL)
+			{
+			data->connected = 1;
+			switch (to->sa_family)
+				{
+				case AF_INET:
+					memcpy(&data->peer,to,sizeof(data->peer.sa_in));
+					break;
+#if OPENSSL_USE_IPV6
+				case AF_INET6:
+					memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
+					break;
+#endif
+				default:
+					memcpy(&data->peer,to,sizeof(data->peer.sa));
+					break;
+				}
+			}
+		else
+			{
+			data->connected = 0;
+			memset(&(data->peer), 0x00, sizeof(data->peer));
+			}
+		break;
+	case BIO_CTRL_DGRAM_GET_PEER:
+		switch (data->peer.sa.sa_family)
+			{
+			case AF_INET:
+				ret=sizeof(data->peer.sa_in);
+				break;
+#if OPENSSL_USE_IPV6
+			case AF_INET6:
+				ret=sizeof(data->peer.sa_in6);
+				break;
+#endif
+			default:
+				ret=sizeof(data->peer.sa);
+				break;
+			}
+		if (num==0 || num>ret)
+			num=ret;
+		memcpy(ptr,&data->peer,(ret=num));
+		break;
+	case BIO_CTRL_DGRAM_SET_PEER:
+		to = (struct sockaddr *) ptr;
+		switch (to->sa_family)
+			{
+			case AF_INET:
+				memcpy(&data->peer,to,sizeof(data->peer.sa_in));
+				break;
+#if OPENSSL_USE_IPV6
+			case AF_INET6:
+				memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
+				break;
+#endif
+			default:
+				memcpy(&data->peer,to,sizeof(data->peer.sa));
+				break;
+			}
+		break;
+	case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
+		memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
+		break;
+#if defined(SO_RCVTIMEO)
+	case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
+#ifdef OPENSSL_SYS_WINDOWS
+		{
+		struct timeval *tv = (struct timeval *)ptr;
+		int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
+		if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+			(void*)&timeout, sizeof(timeout)) < 0)
+			{ perror("setsockopt"); ret = -1; }
+		}
+#else
+		if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
+			sizeof(struct timeval)) < 0)
+			{ perror("setsockopt");	ret = -1; }
+#endif
+		break;
+	case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
+#ifdef OPENSSL_SYS_WINDOWS
+		{
+		int timeout, sz = sizeof(timeout);
+		struct timeval *tv = (struct timeval *)ptr;
+		if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+			(void*)&timeout, &sz) < 0)
+			{ perror("getsockopt"); ret = -1; }
+		else
+			{
+			tv->tv_sec = timeout / 1000;
+			tv->tv_usec = (timeout % 1000) * 1000;
+			ret = sizeof(*tv);
+			}
+		}
+#else
+		if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 
+			ptr, (void *)&ret) < 0)
+			{ perror("getsockopt"); ret = -1; }
+#endif
+		break;
+#endif
+#if defined(SO_SNDTIMEO)
+	case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
+#ifdef OPENSSL_SYS_WINDOWS
+		{
+		struct timeval *tv = (struct timeval *)ptr;
+		int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
+		if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
+			(void*)&timeout, sizeof(timeout)) < 0)
+			{ perror("setsockopt"); ret = -1; }
+		}
+#else
+		if ( setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
+			sizeof(struct timeval)) < 0)
+			{ perror("setsockopt");	ret = -1; }
+#endif
+		break;
+	case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
+#ifdef OPENSSL_SYS_WINDOWS
+		{
+		int timeout, sz = sizeof(timeout);
+		struct timeval *tv = (struct timeval *)ptr;
+		if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
+			(void*)&timeout, &sz) < 0)
+			{ perror("getsockopt"); ret = -1; }
+		else
+			{
+			tv->tv_sec = timeout / 1000;
+			tv->tv_usec = (timeout % 1000) * 1000;
+			ret = sizeof(*tv);
+			}
+		}
+#else
+		if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, 
+			ptr, (void *)&ret) < 0)
+			{ perror("getsockopt"); ret = -1; }
+#endif
+		break;
+#endif
+	case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
+		/* fall-through */
+	case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
+#ifdef OPENSSL_SYS_WINDOWS
+		if ( data->_errno == WSAETIMEDOUT)
+#else
+		if ( data->_errno == EAGAIN)
+#endif
+			{
+			ret = 1;
+			data->_errno = 0;
+			}
+		else
+			ret = 0;
+		break;
+#ifdef EMSGSIZE
+	case BIO_CTRL_DGRAM_MTU_EXCEEDED:
+		if ( data->_errno == EMSGSIZE)
+			{
+			ret = 1;
+			data->_errno = 0;
+			}
+		else
+			ret = 0;
+		break;
+#endif
+	default:
+		ret=0;
+		break;
+		}
+	return(ret);
+	}
+
+static int dgram_puts(BIO *bp, const char *str)
+	{
+	int n,ret;
+
+	n=strlen(str);
+	ret=dgram_write(bp,str,n);
+	return(ret);
+	}
+
+static int BIO_dgram_should_retry(int i)
+	{
+	int err;
+
+	if ((i == 0) || (i == -1))
+		{
+		err=get_last_socket_error();
+
+#if defined(OPENSSL_SYS_WINDOWS)
+	/* If the socket return value (i) is -1
+	 * and err is unexpectedly 0 at this point,
+	 * the error code was overwritten by
+	 * another system call before this error
+	 * handling is called.
+	 */
+#endif
+
+		return(BIO_dgram_non_fatal_error(err));
+		}
+	return(0);
+	}
+
+int BIO_dgram_non_fatal_error(int err)
+	{
+	switch (err)
+		{
+#if defined(OPENSSL_SYS_WINDOWS)
+# if defined(WSAEWOULDBLOCK)
+	case WSAEWOULDBLOCK:
+# endif
+
+# if 0 /* This appears to always be an error */
+#  if defined(WSAENOTCONN)
+	case WSAENOTCONN:
+#  endif
+# endif
+#endif
+
+#ifdef EWOULDBLOCK
+# ifdef WSAEWOULDBLOCK
+#  if WSAEWOULDBLOCK != EWOULDBLOCK
+	case EWOULDBLOCK:
+#  endif
+# else
+	case EWOULDBLOCK:
+# endif
+#endif
+
+#ifdef EINTR
+	case EINTR:
+#endif
+
+#ifdef EAGAIN
+#if EWOULDBLOCK != EAGAIN
+	case EAGAIN:
+# endif
+#endif
+
+#ifdef EPROTO
+	case EPROTO:
+#endif
+
+#ifdef EINPROGRESS
+	case EINPROGRESS:
+#endif
+
+#ifdef EALREADY
+	case EALREADY:
+#endif
+
+		return(1);
+		/* break; */
+	default:
+		break;
+		}
+	return(0);
+	}
+
+static void get_current_time(struct timeval *t)
+	{
+#ifdef OPENSSL_SYS_WIN32
+	struct _timeb tb;
+	_ftime(&tb);
+	t->tv_sec = (long)tb.time;
+	t->tv_usec = (long)tb.millitm * 1000;
+#elif defined(OPENSSL_SYS_VMS)
+	struct timeb tb;
+	ftime(&tb);
+	t->tv_sec = (long)tb.time;
+	t->tv_usec = (long)tb.millitm * 1000;
+#else
+	gettimeofday(t, NULL);
+#endif
+	}
+
+#endif
diff --git a/openssl/crypto/bio/bss_fd.c b/openssl/crypto/bio/bss_fd.c
new file mode 100644
index 0000000..d1bf85a
--- /dev/null
+++ b/openssl/crypto/bio/bss_fd.c
@@ -0,0 +1,319 @@
+/* crypto/bio/bss_fd.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "cryptlib.h"
+
+#if defined(OPENSSL_NO_POSIX_IO)
+/*
+ * One can argue that one should implement dummy placeholder for
+ * BIO_s_fd here...
+ */
+#else
+/*
+ * As for unconditional usage of "UPLINK" interface in this module.
+ * Trouble is that unlike Unix file descriptors [which are indexes
+ * in kernel-side per-process table], corresponding descriptors on
+ * platforms which require "UPLINK" interface seem to be indexes
+ * in a user-land, non-global table. Well, in fact they are indexes
+ * in stdio _iob[], and recall that _iob[] was the very reason why
+ * "UPLINK" interface was introduced in first place. But one way on
+ * another. Neither libcrypto or libssl use this BIO meaning that
+ * file descriptors can only be provided by application. Therefore
+ * "UPLINK" calls are due...
+ */
+#include "bio_lcl.h"
+
+static int fd_write(BIO *h, const char *buf, int num);
+static int fd_read(BIO *h, char *buf, int size);
+static int fd_puts(BIO *h, const char *str);
+static int fd_gets(BIO *h, char *buf, int size);
+static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int fd_new(BIO *h);
+static int fd_free(BIO *data);
+int BIO_fd_should_retry(int s);
+
+static BIO_METHOD methods_fdp=
+	{
+	BIO_TYPE_FD,"file descriptor",
+	fd_write,
+	fd_read,
+	fd_puts,
+	fd_gets,
+	fd_ctrl,
+	fd_new,
+	fd_free,
+	NULL,
+	};
+
+BIO_METHOD *BIO_s_fd(void)
+	{
+	return(&methods_fdp);
+	}
+
+BIO *BIO_new_fd(int fd,int close_flag)
+	{
+	BIO *ret;
+	ret=BIO_new(BIO_s_fd());
+	if (ret == NULL) return(NULL);
+	BIO_set_fd(ret,fd,close_flag);
+	return(ret);
+	}
+
+static int fd_new(BIO *bi)
+	{
+	bi->init=0;
+	bi->num=-1;
+	bi->ptr=NULL;
+	bi->flags=BIO_FLAGS_UPLINK; /* essentially redundant */
+	return(1);
+	}
+
+static int fd_free(BIO *a)
+	{
+	if (a == NULL) return(0);
+	if (a->shutdown)
+		{
+		if (a->init)
+			{
+			UP_close(a->num);
+			}
+		a->init=0;
+		a->flags=BIO_FLAGS_UPLINK;
+		}
+	return(1);
+	}
+	
+static int fd_read(BIO *b, char *out,int outl)
+	{
+	int ret=0;
+
+	if (out != NULL)
+		{
+		clear_sys_error();
+		ret=UP_read(b->num,out,outl);
+		BIO_clear_retry_flags(b);
+		if (ret <= 0)
+			{
+			if (BIO_fd_should_retry(ret))
+				BIO_set_retry_read(b);
+			}
+		}
+	return(ret);
+	}
+
+static int fd_write(BIO *b, const char *in, int inl)
+	{
+	int ret;
+	clear_sys_error();
+	ret=UP_write(b->num,in,inl);
+	BIO_clear_retry_flags(b);
+	if (ret <= 0)
+		{
+		if (BIO_fd_should_retry(ret))
+			BIO_set_retry_write(b);
+		}
+	return(ret);
+	}
+
+static long fd_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	long ret=1;
+	int *ip;
+
+	switch (cmd)
+		{
+	case BIO_CTRL_RESET:
+		num=0;
+	case BIO_C_FILE_SEEK:
+		ret=(long)UP_lseek(b->num,num,0);
+		break;
+	case BIO_C_FILE_TELL:
+	case BIO_CTRL_INFO:
+		ret=(long)UP_lseek(b->num,0,1);
+		break;
+	case BIO_C_SET_FD:
+		fd_free(b);
+		b->num= *((int *)ptr);
+		b->shutdown=(int)num;
+		b->init=1;
+		break;
+	case BIO_C_GET_FD:
+		if (b->init)
+			{
+			ip=(int *)ptr;
+			if (ip != NULL) *ip=b->num;
+			ret=b->num;
+			}
+		else
+			ret= -1;
+		break;
+	case BIO_CTRL_GET_CLOSE:
+		ret=b->shutdown;
+		break;
+	case BIO_CTRL_SET_CLOSE:
+		b->shutdown=(int)num;
+		break;
+	case BIO_CTRL_PENDING:
+	case BIO_CTRL_WPENDING:
+		ret=0;
+		break;
+	case BIO_CTRL_DUP:
+	case BIO_CTRL_FLUSH:
+		ret=1;
+		break;
+	default:
+		ret=0;
+		break;
+		}
+	return(ret);
+	}
+
+static int fd_puts(BIO *bp, const char *str)
+	{
+	int n,ret;
+
+	n=strlen(str);
+	ret=fd_write(bp,str,n);
+	return(ret);
+	}
+
+static int fd_gets(BIO *bp, char *buf, int size)
+        {
+	int ret=0;
+	char *ptr=buf;
+	char *end=buf+size-1;
+
+	while ( (ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n') )
+		ptr++;
+
+	ptr[0]='\0';
+
+	if (buf[0] != '\0')
+		ret=strlen(buf);
+	return(ret);
+        }
+
+int BIO_fd_should_retry(int i)
+	{
+	int err;
+
+	if ((i == 0) || (i == -1))
+		{
+		err=get_last_sys_error();
+
+#if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */
+		if ((i == -1) && (err == 0))
+			return(1);
+#endif
+
+		return(BIO_fd_non_fatal_error(err));
+		}
+	return(0);
+	}
+
+int BIO_fd_non_fatal_error(int err)
+	{
+	switch (err)
+		{
+
+#ifdef EWOULDBLOCK
+# ifdef WSAEWOULDBLOCK
+#  if WSAEWOULDBLOCK != EWOULDBLOCK
+	case EWOULDBLOCK:
+#  endif
+# else
+	case EWOULDBLOCK:
+# endif
+#endif
+
+#if defined(ENOTCONN)
+	case ENOTCONN:
+#endif
+
+#ifdef EINTR
+	case EINTR:
+#endif
+
+#ifdef EAGAIN
+#if EWOULDBLOCK != EAGAIN
+	case EAGAIN:
+# endif
+#endif
+
+#ifdef EPROTO
+	case EPROTO:
+#endif
+
+#ifdef EINPROGRESS
+	case EINPROGRESS:
+#endif
+
+#ifdef EALREADY
+	case EALREADY:
+#endif
+		return(1);
+		/* break; */
+	default:
+		break;
+		}
+	return(0);
+	}
+#endif
diff --git a/openssl/crypto/bio/bss_file.c b/openssl/crypto/bio/bss_file.c
new file mode 100644
index 0000000..b954fe7
--- /dev/null
+++ b/openssl/crypto/bio/bss_file.c
@@ -0,0 +1,477 @@
+/* crypto/bio/bss_file.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*
+ * 03-Dec-1997	rdenny@dc3.com  Fix bug preventing use of stdin/stdout
+ *		with binary data (e.g. asn1parse -inform DER < xxx) under
+ *		Windows
+ */
+
+#ifndef HEADER_BSS_FILE_C
+#define HEADER_BSS_FILE_C
+
+#if defined(__linux) || defined(__sun) || defined(__hpux)
+/* Following definition aliases fopen to fopen64 on above mentioned
+ * platforms. This makes it possible to open and sequentially access
+ * files larger than 2GB from 32-bit application. It does not allow to
+ * traverse them beyond 2GB with fseek/ftell, but on the other hand *no*
+ * 32-bit platform permits that, not with fseek/ftell. Not to mention
+ * that breaking 2GB limit for seeking would require surgery to *our*
+ * API. But sequential access suffices for practical cases when you
+ * can run into large files, such as fingerprinting, so we can let API
+ * alone. For reference, the list of 32-bit platforms which allow for
+ * sequential access of large files without extra "magic" comprise *BSD,
+ * Darwin, IRIX...
+ */
+#ifndef _FILE_OFFSET_BITS
+#define _FILE_OFFSET_BITS 64
+#endif
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include "bio_lcl.h"
+#include <openssl/err.h>
+
+#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
+#include <nwfileio.h>
+#endif
+
+#if !defined(OPENSSL_NO_STDIO)
+
+static int MS_CALLBACK file_write(BIO *h, const char *buf, int num);
+static int MS_CALLBACK file_read(BIO *h, char *buf, int size);
+static int MS_CALLBACK file_puts(BIO *h, const char *str);
+static int MS_CALLBACK file_gets(BIO *h, char *str, int size);
+static long MS_CALLBACK file_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int MS_CALLBACK file_new(BIO *h);
+static int MS_CALLBACK file_free(BIO *data);
+static BIO_METHOD methods_filep=
+	{
+	BIO_TYPE_FILE,
+	"FILE pointer",
+	file_write,
+	file_read,
+	file_puts,
+	file_gets,
+	file_ctrl,
+	file_new,
+	file_free,
+	NULL,
+	};
+
+BIO *BIO_new_file(const char *filename, const char *mode)
+	{
+	BIO  *ret;
+	FILE *file=NULL;
+
+#if defined(_WIN32) && defined(CP_UTF8)
+	int sz, len_0 = (int)strlen(filename)+1;
+	DWORD flags;
+
+	/*
+	 * Basically there are three cases to cover: a) filename is
+	 * pure ASCII string; b) actual UTF-8 encoded string and
+	 * c) locale-ized string, i.e. one containing 8-bit
+	 * characters that are meaningful in current system locale.
+	 * If filename is pure ASCII or real UTF-8 encoded string,
+	 * MultiByteToWideChar succeeds and _wfopen works. If
+	 * filename is locale-ized string, chances are that
+	 * MultiByteToWideChar fails reporting
+	 * ERROR_NO_UNICODE_TRANSLATION, in which case we fall
+	 * back to fopen...
+	 */
+	if ((sz=MultiByteToWideChar(CP_UTF8,(flags=MB_ERR_INVALID_CHARS),
+					filename,len_0,NULL,0))>0 ||
+	    (GetLastError()==ERROR_INVALID_FLAGS &&
+	     (sz=MultiByteToWideChar(CP_UTF8,(flags=0),
+					filename,len_0,NULL,0))>0)
+	   )
+		{
+		WCHAR  wmode[8];
+		WCHAR *wfilename = _alloca(sz*sizeof(WCHAR));
+
+		if (MultiByteToWideChar(CP_UTF8,flags,
+					filename,len_0,wfilename,sz) &&
+		    MultiByteToWideChar(CP_UTF8,0,mode,strlen(mode)+1,
+			    		wmode,sizeof(wmode)/sizeof(wmode[0])) &&
+		    (file=_wfopen(wfilename,wmode))==NULL &&
+		    (errno==ENOENT || errno==EBADF)
+		   )	/* UTF-8 decode succeeded, but no file, filename
+			 * could still have been locale-ized... */
+			file = fopen(filename,mode);
+		}
+	else if (GetLastError()==ERROR_NO_UNICODE_TRANSLATION)
+		{
+		file = fopen(filename,mode);
+		}
+#else
+	file=fopen(filename,mode);	
+#endif
+	if (file == NULL)
+		{
+		SYSerr(SYS_F_FOPEN,get_last_sys_error());
+		ERR_add_error_data(5,"fopen('",filename,"','",mode,"')");
+		if (errno == ENOENT)
+			BIOerr(BIO_F_BIO_NEW_FILE,BIO_R_NO_SUCH_FILE);
+		else
+			BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB);
+		return(NULL);
+		}
+	if ((ret=BIO_new(BIO_s_file())) == NULL)
+		{
+		fclose(file);
+		return(NULL);
+		}
+
+	BIO_clear_flags(ret,BIO_FLAGS_UPLINK); /* we did fopen -> we disengage UPLINK */
+	BIO_set_fp(ret,file,BIO_CLOSE);
+	return(ret);
+	}
+
+BIO *BIO_new_fp(FILE *stream, int close_flag)
+	{
+	BIO *ret;
+
+	if ((ret=BIO_new(BIO_s_file())) == NULL)
+		return(NULL);
+
+	BIO_set_flags(ret,BIO_FLAGS_UPLINK); /* redundant, left for documentation puposes */
+	BIO_set_fp(ret,stream,close_flag);
+	return(ret);
+	}
+
+BIO_METHOD *BIO_s_file(void)
+	{
+	return(&methods_filep);
+	}
+
+static int MS_CALLBACK file_new(BIO *bi)
+	{
+	bi->init=0;
+	bi->num=0;
+	bi->ptr=NULL;
+	bi->flags=BIO_FLAGS_UPLINK; /* default to UPLINK */
+	return(1);
+	}
+
+static int MS_CALLBACK file_free(BIO *a)
+	{
+	if (a == NULL) return(0);
+	if (a->shutdown)
+		{
+		if ((a->init) && (a->ptr != NULL))
+			{
+			if (a->flags&BIO_FLAGS_UPLINK)
+				UP_fclose (a->ptr);
+			else
+				fclose (a->ptr);
+			a->ptr=NULL;
+			a->flags=BIO_FLAGS_UPLINK;
+			}
+		a->init=0;
+		}
+	return(1);
+	}
+	
+static int MS_CALLBACK file_read(BIO *b, char *out, int outl)
+	{
+	int ret=0;
+
+	if (b->init && (out != NULL))
+		{
+		if (b->flags&BIO_FLAGS_UPLINK)
+			ret=UP_fread(out,1,(int)outl,b->ptr);
+		else
+			ret=fread(out,1,(int)outl,(FILE *)b->ptr);
+		if(ret == 0 && (b->flags&BIO_FLAGS_UPLINK)?UP_ferror((FILE *)b->ptr):ferror((FILE *)b->ptr))
+			{
+			SYSerr(SYS_F_FREAD,get_last_sys_error());
+			BIOerr(BIO_F_FILE_READ,ERR_R_SYS_LIB);
+			ret=-1;
+			}
+		}
+	return(ret);
+	}
+
+static int MS_CALLBACK file_write(BIO *b, const char *in, int inl)
+	{
+	int ret=0;
+
+	if (b->init && (in != NULL))
+		{
+		if (b->flags&BIO_FLAGS_UPLINK)
+			ret=UP_fwrite(in,(int)inl,1,b->ptr);
+		else
+			ret=fwrite(in,(int)inl,1,(FILE *)b->ptr);
+		if (ret)
+			ret=inl;
+		/* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */
+		/* according to Tim Hudson <tjh@cryptsoft.com>, the commented
+		 * out version above can cause 'inl' write calls under
+		 * some stupid stdio implementations (VMS) */
+		}
+	return(ret);
+	}
+
+static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	long ret=1;
+	FILE *fp=(FILE *)b->ptr;
+	FILE **fpp;
+	char p[4];
+
+	switch (cmd)
+		{
+	case BIO_C_FILE_SEEK:
+	case BIO_CTRL_RESET:
+		if (b->flags&BIO_FLAGS_UPLINK)
+			ret=(long)UP_fseek(b->ptr,num,0);
+		else
+			ret=(long)fseek(fp,num,0);
+		break;
+	case BIO_CTRL_EOF:
+		if (b->flags&BIO_FLAGS_UPLINK)
+			ret=(long)UP_feof(fp);
+		else
+			ret=(long)feof(fp);
+		break;
+	case BIO_C_FILE_TELL:
+	case BIO_CTRL_INFO:
+		if (b->flags&BIO_FLAGS_UPLINK)
+			ret=UP_ftell(b->ptr);
+		else
+			ret=ftell(fp);
+		break;
+	case BIO_C_SET_FILE_PTR:
+		file_free(b);
+		b->shutdown=(int)num&BIO_CLOSE;
+		b->ptr=ptr;
+		b->init=1;
+#if BIO_FLAGS_UPLINK!=0
+#if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES)
+#define _IOB_ENTRIES 20
+#endif
+#if defined(_IOB_ENTRIES)
+		/* Safety net to catch purely internal BIO_set_fp calls */
+		if ((size_t)ptr >= (size_t)stdin &&
+		    (size_t)ptr <  (size_t)(stdin+_IOB_ENTRIES))
+			BIO_clear_flags(b,BIO_FLAGS_UPLINK);
+#endif
+#endif
+#ifdef UP_fsetmod
+		if (b->flags&BIO_FLAGS_UPLINK)
+			UP_fsetmod(b->ptr,(char)((num&BIO_FP_TEXT)?'t':'b'));
+		else
+#endif
+		{
+#if defined(OPENSSL_SYS_WINDOWS)
+		int fd = _fileno((FILE*)ptr);
+		if (num & BIO_FP_TEXT)
+			_setmode(fd,_O_TEXT);
+		else
+			_setmode(fd,_O_BINARY);
+#elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
+		int fd = fileno((FILE*)ptr);
+		/* Under CLib there are differences in file modes */
+		if (num & BIO_FP_TEXT)
+			setmode(fd,O_TEXT);
+		else
+			setmode(fd,O_BINARY);
+#elif defined(OPENSSL_SYS_MSDOS)
+		int fd = fileno((FILE*)ptr);
+		/* Set correct text/binary mode */
+		if (num & BIO_FP_TEXT)
+			_setmode(fd,_O_TEXT);
+		/* Dangerous to set stdin/stdout to raw (unless redirected) */
+		else
+			{
+			if (fd == STDIN_FILENO || fd == STDOUT_FILENO)
+				{
+				if (isatty(fd) <= 0)
+					_setmode(fd,_O_BINARY);
+				}
+			else
+				_setmode(fd,_O_BINARY);
+			}
+#elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
+		int fd = fileno((FILE*)ptr);
+		if (num & BIO_FP_TEXT)
+			setmode(fd, O_TEXT);
+		else
+			setmode(fd, O_BINARY);
+#endif
+		}
+		break;
+	case BIO_C_SET_FILENAME:
+		file_free(b);
+		b->shutdown=(int)num&BIO_CLOSE;
+		if (num & BIO_FP_APPEND)
+			{
+			if (num & BIO_FP_READ)
+				BUF_strlcpy(p,"a+",sizeof p);
+			else	BUF_strlcpy(p,"a",sizeof p);
+			}
+		else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
+			BUF_strlcpy(p,"r+",sizeof p);
+		else if (num & BIO_FP_WRITE)
+			BUF_strlcpy(p,"w",sizeof p);
+		else if (num & BIO_FP_READ)
+			BUF_strlcpy(p,"r",sizeof p);
+		else
+			{
+			BIOerr(BIO_F_FILE_CTRL,BIO_R_BAD_FOPEN_MODE);
+			ret=0;
+			break;
+			}
+#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
+		if (!(num & BIO_FP_TEXT))
+			strcat(p,"b");
+		else
+			strcat(p,"t");
+#endif
+#if defined(OPENSSL_SYS_NETWARE)
+		if (!(num & BIO_FP_TEXT))
+			strcat(p,"b");
+		else
+			strcat(p,"t");
+#endif
+		fp=fopen(ptr,p);
+		if (fp == NULL)
+			{
+			SYSerr(SYS_F_FOPEN,get_last_sys_error());
+			ERR_add_error_data(5,"fopen('",ptr,"','",p,"')");
+			BIOerr(BIO_F_FILE_CTRL,ERR_R_SYS_LIB);
+			ret=0;
+			break;
+			}
+		b->ptr=fp;
+		b->init=1;
+		BIO_clear_flags(b,BIO_FLAGS_UPLINK); /* we did fopen -> we disengage UPLINK */
+		break;
+	case BIO_C_GET_FILE_PTR:
+		/* the ptr parameter is actually a FILE ** in this case. */
+		if (ptr != NULL)
+			{
+			fpp=(FILE **)ptr;
+			*fpp=(FILE *)b->ptr;
+			}
+		break;
+	case BIO_CTRL_GET_CLOSE:
+		ret=(long)b->shutdown;
+		break;
+	case BIO_CTRL_SET_CLOSE:
+		b->shutdown=(int)num;
+		break;
+	case BIO_CTRL_FLUSH:
+		if (b->flags&BIO_FLAGS_UPLINK)
+			UP_fflush(b->ptr);
+		else
+			fflush((FILE *)b->ptr);
+		break;
+	case BIO_CTRL_DUP:
+		ret=1;
+		break;
+
+	case BIO_CTRL_WPENDING:
+	case BIO_CTRL_PENDING:
+	case BIO_CTRL_PUSH:
+	case BIO_CTRL_POP:
+	default:
+		ret=0;
+		break;
+		}
+	return(ret);
+	}
+
+static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size)
+	{
+	int ret=0;
+
+	buf[0]='\0';
+	if (bp->flags&BIO_FLAGS_UPLINK)
+		{
+		if (!UP_fgets(buf,size,bp->ptr))
+			goto err;
+		}
+	else
+		{
+		if (!fgets(buf,size,(FILE *)bp->ptr))
+			goto err;
+		}
+	if (buf[0] != '\0')
+		ret=strlen(buf);
+	err:
+	return(ret);
+	}
+
+static int MS_CALLBACK file_puts(BIO *bp, const char *str)
+	{
+	int n,ret;
+
+	n=strlen(str);
+	ret=file_write(bp,str,n);
+	return(ret);
+	}
+
+#endif /* OPENSSL_NO_STDIO */
+
+#endif /* HEADER_BSS_FILE_C */
+
+
diff --git a/openssl/crypto/bio/bss_log.c b/openssl/crypto/bio/bss_log.c
new file mode 100644
index 0000000..b7dce5c
--- /dev/null
+++ b/openssl/crypto/bio/bss_log.c
@@ -0,0 +1,399 @@
+/* crypto/bio/bss_log.c */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+	Why BIO_s_log?
+
+	BIO_s_log is useful for system daemons (or services under NT).
+	It is one-way BIO, it sends all stuff to syslogd (on system that
+	commonly use that), or event log (on NT), or OPCOM (on OpenVMS).
+
+*/
+
+
+#include <stdio.h>
+#include <errno.h>
+
+#include "cryptlib.h"
+
+#if defined(OPENSSL_SYS_WINCE)
+#elif defined(OPENSSL_SYS_WIN32)
+#elif defined(OPENSSL_SYS_VMS)
+#  include <opcdef.h>
+#  include <descrip.h>
+#  include <lib$routines.h>
+#  include <starlet.h>
+/* Some compiler options may mask the declaration of "_malloc32". */
+#  if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE
+#    if __INITIAL_POINTER_SIZE == 64
+#      pragma pointer_size save
+#      pragma pointer_size 32
+    void * _malloc32  (__size_t);
+#      pragma pointer_size restore
+#    endif /* __INITIAL_POINTER_SIZE == 64 */
+#  endif /* __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE */
+#elif defined(__ultrix)
+#  include <sys/syslog.h>
+#elif defined(OPENSSL_SYS_NETWARE)
+#  define NO_SYSLOG
+#elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG)
+#  include <syslog.h>
+#endif
+
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+
+#ifndef NO_SYSLOG
+
+#if defined(OPENSSL_SYS_WIN32)
+#define LOG_EMERG	0
+#define LOG_ALERT	1
+#define LOG_CRIT	2
+#define LOG_ERR		3
+#define LOG_WARNING	4
+#define LOG_NOTICE	5
+#define LOG_INFO	6
+#define LOG_DEBUG	7
+
+#define LOG_DAEMON	(3<<3)
+#elif defined(OPENSSL_SYS_VMS)
+/* On VMS, we don't really care about these, but we need them to compile */
+#define LOG_EMERG	0
+#define LOG_ALERT	1
+#define LOG_CRIT	2
+#define LOG_ERR		3
+#define LOG_WARNING	4
+#define LOG_NOTICE	5
+#define LOG_INFO	6
+#define LOG_DEBUG	7
+
+#define LOG_DAEMON	OPC$M_NM_NTWORK
+#endif
+
+static int MS_CALLBACK slg_write(BIO *h, const char *buf, int num);
+static int MS_CALLBACK slg_puts(BIO *h, const char *str);
+static long MS_CALLBACK slg_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int MS_CALLBACK slg_new(BIO *h);
+static int MS_CALLBACK slg_free(BIO *data);
+static void xopenlog(BIO* bp, char* name, int level);
+static void xsyslog(BIO* bp, int priority, const char* string);
+static void xcloselog(BIO* bp);
+
+static BIO_METHOD methods_slg=
+	{
+	BIO_TYPE_MEM,"syslog",
+	slg_write,
+	NULL,
+	slg_puts,
+	NULL,
+	slg_ctrl,
+	slg_new,
+	slg_free,
+	NULL,
+	};
+
+BIO_METHOD *BIO_s_log(void)
+	{
+	return(&methods_slg);
+	}
+
+static int MS_CALLBACK slg_new(BIO *bi)
+	{
+	bi->init=1;
+	bi->num=0;
+	bi->ptr=NULL;
+	xopenlog(bi, "application", LOG_DAEMON);
+	return(1);
+	}
+
+static int MS_CALLBACK slg_free(BIO *a)
+	{
+	if (a == NULL) return(0);
+	xcloselog(a);
+	return(1);
+	}
+	
+static int MS_CALLBACK slg_write(BIO *b, const char *in, int inl)
+	{
+	int ret= inl;
+	char* buf;
+	char* pp;
+	int priority, i;
+	static const struct
+		{
+		int strl;
+		char str[10];
+		int log_level;
+		}
+	mapping[] =
+		{
+		{ 6, "PANIC ", LOG_EMERG },
+		{ 6, "EMERG ", LOG_EMERG },
+		{ 4, "EMR ", LOG_EMERG },
+		{ 6, "ALERT ", LOG_ALERT },
+		{ 4, "ALR ", LOG_ALERT },
+		{ 5, "CRIT ", LOG_CRIT },
+		{ 4, "CRI ", LOG_CRIT },
+		{ 6, "ERROR ", LOG_ERR },
+		{ 4, "ERR ", LOG_ERR },
+		{ 8, "WARNING ", LOG_WARNING },
+		{ 5, "WARN ", LOG_WARNING },
+		{ 4, "WAR ", LOG_WARNING },
+		{ 7, "NOTICE ", LOG_NOTICE },
+		{ 5, "NOTE ", LOG_NOTICE },
+		{ 4, "NOT ", LOG_NOTICE },
+		{ 5, "INFO ", LOG_INFO },
+		{ 4, "INF ", LOG_INFO },
+		{ 6, "DEBUG ", LOG_DEBUG },
+		{ 4, "DBG ", LOG_DEBUG },
+		{ 0, "", LOG_ERR } /* The default */
+		};
+
+	if((buf= (char *)OPENSSL_malloc(inl+ 1)) == NULL){
+		return(0);
+	}
+	strncpy(buf, in, inl);
+	buf[inl]= '\0';
+
+	i = 0;
+	while(strncmp(buf, mapping[i].str, mapping[i].strl) != 0) i++;
+	priority = mapping[i].log_level;
+	pp = buf + mapping[i].strl;
+
+	xsyslog(b, priority, pp);
+
+	OPENSSL_free(buf);
+	return(ret);
+	}
+
+static long MS_CALLBACK slg_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	switch (cmd)
+		{
+	case BIO_CTRL_SET:
+		xcloselog(b);
+		xopenlog(b, ptr, num);
+		break;
+	default:
+		break;
+		}
+	return(0);
+	}
+
+static int MS_CALLBACK slg_puts(BIO *bp, const char *str)
+	{
+	int n,ret;
+
+	n=strlen(str);
+	ret=slg_write(bp,str,n);
+	return(ret);
+	}
+
+#if defined(OPENSSL_SYS_WIN32)
+
+static void xopenlog(BIO* bp, char* name, int level)
+{
+	if (GetVersion() < 0x80000000)
+		bp->ptr = RegisterEventSourceA(NULL,name);
+	else
+		bp->ptr = NULL;
+}
+
+static void xsyslog(BIO *bp, int priority, const char *string)
+{
+	LPCSTR lpszStrings[2];
+	WORD evtype= EVENTLOG_ERROR_TYPE;
+	char pidbuf[DECIMAL_SIZE(DWORD)+4];
+
+	if (bp->ptr == NULL)
+		return;
+
+	switch (priority)
+		{
+	case LOG_EMERG:
+	case LOG_ALERT:
+	case LOG_CRIT:
+	case LOG_ERR:
+		evtype = EVENTLOG_ERROR_TYPE;
+		break;
+	case LOG_WARNING:
+		evtype = EVENTLOG_WARNING_TYPE;
+		break;
+	case LOG_NOTICE:
+	case LOG_INFO:
+	case LOG_DEBUG:
+		evtype = EVENTLOG_INFORMATION_TYPE;
+		break;
+	default:		/* Should never happen, but set it
+				   as error anyway. */
+		evtype = EVENTLOG_ERROR_TYPE;
+		break;
+		}
+
+	sprintf(pidbuf, "[%u] ", GetCurrentProcessId());
+	lpszStrings[0] = pidbuf;
+	lpszStrings[1] = string;
+
+	ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0,
+				lpszStrings, NULL);
+}
+	
+static void xcloselog(BIO* bp)
+{
+	if(bp->ptr)
+		DeregisterEventSource((HANDLE)(bp->ptr));
+	bp->ptr= NULL;
+}
+
+#elif defined(OPENSSL_SYS_VMS)
+
+static int VMS_OPC_target = LOG_DAEMON;
+
+static void xopenlog(BIO* bp, char* name, int level)
+{
+	VMS_OPC_target = level; 
+}
+
+static void xsyslog(BIO *bp, int priority, const char *string)
+{
+	struct dsc$descriptor_s opc_dsc;
+
+/* Arrange 32-bit pointer to opcdef buffer and malloc(), if needed. */
+#if __INITIAL_POINTER_SIZE == 64
+# pragma pointer_size save
+# pragma pointer_size 32
+# define OPCDEF_TYPE __char_ptr32
+# define OPCDEF_MALLOC _malloc32
+#else /* __INITIAL_POINTER_SIZE == 64 */
+# define OPCDEF_TYPE char *
+# define OPCDEF_MALLOC OPENSSL_malloc
+#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+	struct opcdef *opcdef_p;
+
+#if __INITIAL_POINTER_SIZE == 64
+# pragma pointer_size restore
+#endif /* __INITIAL_POINTER_SIZE == 64 */
+
+	char buf[10240];
+	unsigned int len;
+        struct dsc$descriptor_s buf_dsc;
+	$DESCRIPTOR(fao_cmd, "!AZ: !AZ");
+	char *priority_tag;
+
+	switch (priority)
+	  {
+	  case LOG_EMERG: priority_tag = "Emergency"; break;
+	  case LOG_ALERT: priority_tag = "Alert"; break;
+	  case LOG_CRIT: priority_tag = "Critical"; break;
+	  case LOG_ERR: priority_tag = "Error"; break;
+	  case LOG_WARNING: priority_tag = "Warning"; break;
+	  case LOG_NOTICE: priority_tag = "Notice"; break;
+	  case LOG_INFO: priority_tag = "Info"; break;
+	  case LOG_DEBUG: priority_tag = "DEBUG"; break;
+	  }
+
+	buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+	buf_dsc.dsc$b_class = DSC$K_CLASS_S;
+	buf_dsc.dsc$a_pointer = buf;
+	buf_dsc.dsc$w_length = sizeof(buf) - 1;
+
+	lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string);
+
+	/* We know there's an 8-byte header.  That's documented. */
+	opcdef_p = OPCDEF_MALLOC( 8+ len);
+	opcdef_p->opc$b_ms_type = OPC$_RQ_RQST;
+	memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3);
+	opcdef_p->opc$l_ms_rqstid = 0;
+	memcpy(&opcdef_p->opc$l_ms_text, buf, len);
+
+	opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+	opc_dsc.dsc$b_class = DSC$K_CLASS_S;
+	opc_dsc.dsc$a_pointer = (OPCDEF_TYPE) opcdef_p;
+	opc_dsc.dsc$w_length = len + 8;
+
+	sys$sndopr(opc_dsc, 0);
+
+	OPENSSL_free(opcdef_p);
+}
+
+static void xcloselog(BIO* bp)
+{
+}
+
+#else /* Unix/Watt32 */
+
+static void xopenlog(BIO* bp, char* name, int level)
+{
+#ifdef WATT32   /* djgpp/DOS */
+	openlog(name, LOG_PID|LOG_CONS|LOG_NDELAY, level);
+#else
+	openlog(name, LOG_PID|LOG_CONS, level);
+#endif
+}
+
+static void xsyslog(BIO *bp, int priority, const char *string)
+{
+	syslog(priority, "%s", string);
+}
+
+static void xcloselog(BIO* bp)
+{
+	closelog();
+}
+
+#endif /* Unix */
+
+#endif /* NO_SYSLOG */
diff --git a/openssl/crypto/bio/bss_mem.c b/openssl/crypto/bio/bss_mem.c
new file mode 100644
index 0000000..37d4194
--- /dev/null
+++ b/openssl/crypto/bio/bss_mem.c
@@ -0,0 +1,319 @@
+/* crypto/bio/bss_mem.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+
+static int mem_write(BIO *h, const char *buf, int num);
+static int mem_read(BIO *h, char *buf, int size);
+static int mem_puts(BIO *h, const char *str);
+static int mem_gets(BIO *h, char *str, int size);
+static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int mem_new(BIO *h);
+static int mem_free(BIO *data);
+static BIO_METHOD mem_method=
+	{
+	BIO_TYPE_MEM,
+	"memory buffer",
+	mem_write,
+	mem_read,
+	mem_puts,
+	mem_gets,
+	mem_ctrl,
+	mem_new,
+	mem_free,
+	NULL,
+	};
+
+/* bio->num is used to hold the value to return on 'empty', if it is
+ * 0, should_retry is not set */
+
+BIO_METHOD *BIO_s_mem(void)
+	{
+	return(&mem_method);
+	}
+
+BIO *BIO_new_mem_buf(void *buf, int len)
+{
+	BIO *ret;
+	BUF_MEM *b;
+	size_t sz;
+
+	if (!buf) {
+		BIOerr(BIO_F_BIO_NEW_MEM_BUF,BIO_R_NULL_PARAMETER);
+		return NULL;
+	}
+	sz = (len<0) ? strlen(buf) : (size_t)len;
+	if(!(ret = BIO_new(BIO_s_mem())) ) return NULL;
+	b = (BUF_MEM *)ret->ptr;
+	b->data = buf;
+	b->length = sz;
+	b->max = sz;
+	ret->flags |= BIO_FLAGS_MEM_RDONLY;
+	/* Since this is static data retrying wont help */
+	ret->num = 0;
+	return ret;
+}
+
+static int mem_new(BIO *bi)
+	{
+	BUF_MEM *b;
+
+	if ((b=BUF_MEM_new()) == NULL)
+		return(0);
+	bi->shutdown=1;
+	bi->init=1;
+	bi->num= -1;
+	bi->ptr=(char *)b;
+	return(1);
+	}
+
+static int mem_free(BIO *a)
+	{
+	if (a == NULL) return(0);
+	if (a->shutdown)
+		{
+		if ((a->init) && (a->ptr != NULL))
+			{
+			BUF_MEM *b;
+			b = (BUF_MEM *)a->ptr;
+			if(a->flags & BIO_FLAGS_MEM_RDONLY) b->data = NULL;
+			BUF_MEM_free(b);
+			a->ptr=NULL;
+			}
+		}
+	return(1);
+	}
+	
+static int mem_read(BIO *b, char *out, int outl)
+	{
+	int ret= -1;
+	BUF_MEM *bm;
+
+	bm=(BUF_MEM *)b->ptr;
+	BIO_clear_retry_flags(b);
+	ret=(outl >=0 && (size_t)outl > bm->length)?(int)bm->length:outl;
+	if ((out != NULL) && (ret > 0)) {
+		memcpy(out,bm->data,ret);
+		bm->length-=ret;
+		if(b->flags & BIO_FLAGS_MEM_RDONLY) bm->data += ret;
+		else {
+			memmove(&(bm->data[0]),&(bm->data[ret]),bm->length);
+		}
+	} else if (bm->length == 0)
+		{
+		ret = b->num;
+		if (ret != 0)
+			BIO_set_retry_read(b);
+		}
+	return(ret);
+	}
+
+static int mem_write(BIO *b, const char *in, int inl)
+	{
+	int ret= -1;
+	int blen;
+	BUF_MEM *bm;
+
+	bm=(BUF_MEM *)b->ptr;
+	if (in == NULL)
+		{
+		BIOerr(BIO_F_MEM_WRITE,BIO_R_NULL_PARAMETER);
+		goto end;
+		}
+
+	if(b->flags & BIO_FLAGS_MEM_RDONLY) {
+		BIOerr(BIO_F_MEM_WRITE,BIO_R_WRITE_TO_READ_ONLY_BIO);
+		goto end;
+	}
+
+	BIO_clear_retry_flags(b);
+	blen=bm->length;
+	if (BUF_MEM_grow_clean(bm,blen+inl) != (blen+inl))
+		goto end;
+	memcpy(&(bm->data[blen]),in,inl);
+	ret=inl;
+end:
+	return(ret);
+	}
+
+static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	long ret=1;
+	char **pptr;
+
+	BUF_MEM *bm=(BUF_MEM *)b->ptr;
+
+	switch (cmd)
+		{
+	case BIO_CTRL_RESET:
+		if (bm->data != NULL)
+			{
+			/* For read only case reset to the start again */
+			if(b->flags & BIO_FLAGS_MEM_RDONLY) 
+				{
+				bm->data -= bm->max - bm->length;
+				bm->length = bm->max;
+				}
+			else
+				{
+				memset(bm->data,0,bm->max);
+				bm->length=0;
+				}
+			}
+		break;
+	case BIO_CTRL_EOF:
+		ret=(long)(bm->length == 0);
+		break;
+	case BIO_C_SET_BUF_MEM_EOF_RETURN:
+		b->num=(int)num;
+		break;
+	case BIO_CTRL_INFO:
+		ret=(long)bm->length;
+		if (ptr != NULL)
+			{
+			pptr=(char **)ptr;
+			*pptr=(char *)&(bm->data[0]);
+			}
+		break;
+	case BIO_C_SET_BUF_MEM:
+		mem_free(b);
+		b->shutdown=(int)num;
+		b->ptr=ptr;
+		break;
+	case BIO_C_GET_BUF_MEM_PTR:
+		if (ptr != NULL)
+			{
+			pptr=(char **)ptr;
+			*pptr=(char *)bm;
+			}
+		break;
+	case BIO_CTRL_GET_CLOSE:
+		ret=(long)b->shutdown;
+		break;
+	case BIO_CTRL_SET_CLOSE:
+		b->shutdown=(int)num;
+		break;
+
+	case BIO_CTRL_WPENDING:
+		ret=0L;
+		break;
+	case BIO_CTRL_PENDING:
+		ret=(long)bm->length;
+		break;
+	case BIO_CTRL_DUP:
+	case BIO_CTRL_FLUSH:
+		ret=1;
+		break;
+	case BIO_CTRL_PUSH:
+	case BIO_CTRL_POP:
+	default:
+		ret=0;
+		break;
+		}
+	return(ret);
+	}
+
+static int mem_gets(BIO *bp, char *buf, int size)
+	{
+	int i,j;
+	int ret= -1;
+	char *p;
+	BUF_MEM *bm=(BUF_MEM *)bp->ptr;
+
+	BIO_clear_retry_flags(bp);
+	j=bm->length;
+	if ((size-1) < j) j=size-1;
+	if (j <= 0)
+		{
+		*buf='\0';
+		return 0;
+		}
+	p=bm->data;
+	for (i=0; i<j; i++)
+		{
+		if (p[i] == '\n')
+			{
+			i++;
+			break;
+			}
+		}
+
+	/*
+	 * i is now the max num of bytes to copy, either j or up to
+	 * and including the first newline
+	 */ 
+
+	i=mem_read(bp,buf,i);
+	if (i > 0) buf[i]='\0';
+	ret=i;
+	return(ret);
+	}
+
+static int mem_puts(BIO *bp, const char *str)
+	{
+	int n,ret;
+
+	n=strlen(str);
+	ret=mem_write(bp,str,n);
+	/* memory semantics is that it will always work */
+	return(ret);
+	}
+
diff --git a/openssl/crypto/bio/bss_null.c b/openssl/crypto/bio/bss_null.c
new file mode 100644
index 0000000..46b7333
--- /dev/null
+++ b/openssl/crypto/bio/bss_null.c
@@ -0,0 +1,150 @@
+/* crypto/bio/bss_null.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+
+static int null_write(BIO *h, const char *buf, int num);
+static int null_read(BIO *h, char *buf, int size);
+static int null_puts(BIO *h, const char *str);
+static int null_gets(BIO *h, char *str, int size);
+static long null_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int null_new(BIO *h);
+static int null_free(BIO *data);
+static BIO_METHOD null_method=
+	{
+	BIO_TYPE_NULL,
+	"NULL",
+	null_write,
+	null_read,
+	null_puts,
+	null_gets,
+	null_ctrl,
+	null_new,
+	null_free,
+	NULL,
+	};
+
+BIO_METHOD *BIO_s_null(void)
+	{
+	return(&null_method);
+	}
+
+static int null_new(BIO *bi)
+	{
+	bi->init=1;
+	bi->num=0;
+	bi->ptr=(NULL);
+	return(1);
+	}
+
+static int null_free(BIO *a)
+	{
+	if (a == NULL) return(0);
+	return(1);
+	}
+	
+static int null_read(BIO *b, char *out, int outl)
+	{
+	return(0);
+	}
+
+static int null_write(BIO *b, const char *in, int inl)
+	{
+	return(inl);
+	}
+
+static long null_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	long ret=1;
+
+	switch (cmd)
+		{
+	case BIO_CTRL_RESET:
+	case BIO_CTRL_EOF:
+	case BIO_CTRL_SET:
+	case BIO_CTRL_SET_CLOSE:
+	case BIO_CTRL_FLUSH:
+	case BIO_CTRL_DUP:
+		ret=1;
+		break;
+	case BIO_CTRL_GET_CLOSE:
+	case BIO_CTRL_INFO:
+	case BIO_CTRL_GET:
+	case BIO_CTRL_PENDING:
+	case BIO_CTRL_WPENDING:
+	default:
+		ret=0;
+		break;
+		}
+	return(ret);
+	}
+
+static int null_gets(BIO *bp, char *buf, int size)
+	{
+	return(0);
+	}
+
+static int null_puts(BIO *bp, const char *str)
+	{
+	if (str == NULL) return(0);
+	return(strlen(str));
+	}
+
diff --git a/openssl/crypto/bio/bss_rtcp.c b/openssl/crypto/bio/bss_rtcp.c
new file mode 100644
index 0000000..7dae485
--- /dev/null
+++ b/openssl/crypto/bio/bss_rtcp.c
@@ -0,0 +1,294 @@
+/* crypto/bio/bss_rtcp.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Written by David L. Jones <jonesd@kcgl1.eng.ohio-state.edu>
+ * Date:   22-JUL-1996
+ * Revised: 25-SEP-1997		Update for 0.8.1, BIO_CTRL_SET -> BIO_C_SET_FD
+ */
+/* VMS */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+
+#include <iodef.h>		/* VMS IO$_ definitions */
+#include <starlet.h>
+
+typedef unsigned short io_channel;
+/*************************************************************************/
+struct io_status { short status, count; long flags; };
+
+struct rpc_msg {		/* Should have member alignment inhibited */
+   char channel;		/* 'A'-app data. 'R'-remote client 'G'-global */
+   char function;		/* 'G'-get, 'P'-put, 'C'-confirm, 'X'-close */
+   unsigned short int length;	/* Amount of data returned or max to return */
+   char data[4092];		/* variable data */
+};
+#define RPC_HDR_SIZE (sizeof(struct rpc_msg) - 4092)
+
+struct rpc_ctx {
+    int filled, pos;
+    struct rpc_msg msg;
+};
+
+static int rtcp_write(BIO *h,const char *buf,int num);
+static int rtcp_read(BIO *h,char *buf,int size);
+static int rtcp_puts(BIO *h,const char *str);
+static int rtcp_gets(BIO *h,char *str,int size);
+static long rtcp_ctrl(BIO *h,int cmd,long arg1,void *arg2);
+static int rtcp_new(BIO *h);
+static int rtcp_free(BIO *data);
+
+static BIO_METHOD rtcp_method=
+	{
+	BIO_TYPE_FD,
+	"RTCP",
+	rtcp_write,
+	rtcp_read,
+	rtcp_puts,
+	rtcp_gets,
+	rtcp_ctrl,
+	rtcp_new,
+	rtcp_free,
+	NULL,
+	};
+
+BIO_METHOD *BIO_s_rtcp(void)
+	{
+	return(&rtcp_method);
+	}
+/*****************************************************************************/
+/* Decnet I/O routines.
+ */
+
+#ifdef __DECC
+#pragma message save
+#pragma message disable DOLLARID
+#endif
+
+static int get ( io_channel chan, char *buffer, int maxlen, int *length )
+{
+    int status;
+    struct io_status iosb;
+    status = sys$qiow ( 0, chan, IO$_READVBLK, &iosb, 0, 0,
+	buffer, maxlen, 0, 0, 0, 0 );
+    if ( (status&1) == 1 ) status = iosb.status;
+    if ( (status&1) == 1 ) *length = iosb.count;
+    return status;
+}
+
+static int put ( io_channel chan, char *buffer, int length )
+{
+    int status;
+    struct io_status iosb;
+    status = sys$qiow ( 0, chan, IO$_WRITEVBLK, &iosb, 0, 0,
+	buffer, length, 0, 0, 0, 0 );
+    if ( (status&1) == 1 ) status = iosb.status;
+    return status;
+}
+
+#ifdef __DECC
+#pragma message restore
+#endif
+
+/***************************************************************************/
+
+static int rtcp_new(BIO *bi)
+{
+    struct rpc_ctx *ctx;
+	bi->init=1;
+	bi->num=0;
+	bi->flags = 0;
+	bi->ptr=OPENSSL_malloc(sizeof(struct rpc_ctx));
+	ctx = (struct rpc_ctx *) bi->ptr;
+	ctx->filled = 0;
+	ctx->pos = 0;
+	return(1);
+}
+
+static int rtcp_free(BIO *a)
+{
+	if (a == NULL) return(0);
+	if ( a->ptr ) OPENSSL_free ( a->ptr );
+	a->ptr = NULL;
+	return(1);
+}
+	
+static int rtcp_read(BIO *b, char *out, int outl)
+{
+    int status, length;
+    struct rpc_ctx *ctx;
+    /*
+     * read data, return existing.
+     */
+    ctx = (struct rpc_ctx *) b->ptr;
+    if ( ctx->pos < ctx->filled ) {
+	length = ctx->filled - ctx->pos;
+	if ( length > outl ) length = outl;
+	memmove ( out, &ctx->msg.data[ctx->pos], length );
+	ctx->pos += length;
+	return length;
+    }
+    /*
+     * Requst more data from R channel.
+     */
+    ctx->msg.channel = 'R';
+    ctx->msg.function = 'G';
+    ctx->msg.length = sizeof(ctx->msg.data);
+    status = put ( b->num, (char *) &ctx->msg, RPC_HDR_SIZE );
+    if ( (status&1) == 0 ) {
+	return -1;
+    }
+    /*
+     * Read.
+     */
+    ctx->pos = ctx->filled = 0;
+    status = get ( b->num, (char *) &ctx->msg, sizeof(ctx->msg), &length );
+    if ( (status&1) == 0 ) length = -1;
+    if ( ctx->msg.channel != 'R' || ctx->msg.function != 'C' ) {
+	length = -1;
+    }
+    ctx->filled = length - RPC_HDR_SIZE;
+    
+    if ( ctx->pos < ctx->filled ) {
+	length = ctx->filled - ctx->pos;
+	if ( length > outl ) length = outl;
+	memmove ( out, ctx->msg.data, length );
+	ctx->pos += length;
+	return length;
+    }
+
+    return length;
+}
+
+static int rtcp_write(BIO *b, const char *in, int inl)
+{
+    int status, i, segment, length;
+    struct rpc_ctx *ctx;
+    /*
+     * Output data, send in chunks no larger that sizeof(ctx->msg.data).
+     */
+    ctx = (struct rpc_ctx *) b->ptr;
+    for ( i = 0; i < inl; i += segment ) {
+	segment = inl - i;
+	if ( segment > sizeof(ctx->msg.data) ) segment = sizeof(ctx->msg.data);
+	ctx->msg.channel = 'R';
+	ctx->msg.function = 'P';
+	ctx->msg.length = segment;
+	memmove ( ctx->msg.data, &in[i], segment );
+	status = put ( b->num, (char *) &ctx->msg, segment + RPC_HDR_SIZE );
+	if ((status&1) == 0 ) { i = -1; break; }
+
+	status = get ( b->num, (char *) &ctx->msg, sizeof(ctx->msg), &length );
+	if ( ((status&1) == 0) || (length < RPC_HDR_SIZE) ) { i = -1; break; }
+	if ( (ctx->msg.channel != 'R') || (ctx->msg.function != 'C') ) {
+	   printf("unexpected response when confirming put %c %c\n",
+		ctx->msg.channel, ctx->msg.function );
+
+	}
+    }
+    return(i);
+}
+
+static long rtcp_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	long ret=1;
+
+	switch (cmd)
+		{
+	case BIO_CTRL_RESET:
+	case BIO_CTRL_EOF:
+		ret = 1;
+		break;
+	case BIO_C_SET_FD:
+		b->num = num;
+		ret = 1;
+	 	break;
+	case BIO_CTRL_SET_CLOSE:
+	case BIO_CTRL_FLUSH:
+	case BIO_CTRL_DUP:
+		ret=1;
+		break;
+	case BIO_CTRL_GET_CLOSE:
+	case BIO_CTRL_INFO:
+	case BIO_CTRL_GET:
+	case BIO_CTRL_PENDING:
+	case BIO_CTRL_WPENDING:
+	default:
+		ret=0;
+		break;
+		}
+	return(ret);
+	}
+
+static int rtcp_gets(BIO *bp, char *buf, int size)
+	{
+	return(0);
+	}
+
+static int rtcp_puts(BIO *bp, const char *str)
+{
+    int length;
+    if (str == NULL) return(0);
+    length = strlen ( str );
+    if ( length == 0 ) return (0);
+    return rtcp_write ( bp,str, length );
+}
+
diff --git a/openssl/crypto/bio/bss_sock.c b/openssl/crypto/bio/bss_sock.c
new file mode 100644
index 0000000..3df3193
--- /dev/null
+++ b/openssl/crypto/bio/bss_sock.c
@@ -0,0 +1,294 @@
+/* crypto/bio/bss_sock.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_SOCK
+
+#include <openssl/bio.h>
+
+#ifdef WATT32
+#define sock_write SockWrite  /* Watt-32 uses same names */
+#define sock_read  SockRead
+#define sock_puts  SockPuts
+#endif
+
+static int sock_write(BIO *h, const char *buf, int num);
+static int sock_read(BIO *h, char *buf, int size);
+static int sock_puts(BIO *h, const char *str);
+static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int sock_new(BIO *h);
+static int sock_free(BIO *data);
+int BIO_sock_should_retry(int s);
+
+static BIO_METHOD methods_sockp=
+	{
+	BIO_TYPE_SOCKET,
+	"socket",
+	sock_write,
+	sock_read,
+	sock_puts,
+	NULL, /* sock_gets, */
+	sock_ctrl,
+	sock_new,
+	sock_free,
+	NULL,
+	};
+
+BIO_METHOD *BIO_s_socket(void)
+	{
+	return(&methods_sockp);
+	}
+
+BIO *BIO_new_socket(int fd, int close_flag)
+	{
+	BIO *ret;
+
+	ret=BIO_new(BIO_s_socket());
+	if (ret == NULL) return(NULL);
+	BIO_set_fd(ret,fd,close_flag);
+	return(ret);
+	}
+
+static int sock_new(BIO *bi)
+	{
+	bi->init=0;
+	bi->num=0;
+	bi->ptr=NULL;
+	bi->flags=0;
+	return(1);
+	}
+
+static int sock_free(BIO *a)
+	{
+	if (a == NULL) return(0);
+	if (a->shutdown)
+		{
+		if (a->init)
+			{
+			SHUTDOWN2(a->num);
+			}
+		a->init=0;
+		a->flags=0;
+		}
+	return(1);
+	}
+	
+static int sock_read(BIO *b, char *out, int outl)
+	{
+	int ret=0;
+
+	if (out != NULL)
+		{
+		clear_socket_error();
+		ret=readsocket(b->num,out,outl);
+		BIO_clear_retry_flags(b);
+		if (ret <= 0)
+			{
+			if (BIO_sock_should_retry(ret))
+				BIO_set_retry_read(b);
+			}
+		}
+	return(ret);
+	}
+
+static int sock_write(BIO *b, const char *in, int inl)
+	{
+	int ret;
+	
+	clear_socket_error();
+	ret=writesocket(b->num,in,inl);
+	BIO_clear_retry_flags(b);
+	if (ret <= 0)
+		{
+		if (BIO_sock_should_retry(ret))
+			BIO_set_retry_write(b);
+		}
+	return(ret);
+	}
+
+static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	long ret=1;
+	int *ip;
+
+	switch (cmd)
+		{
+	case BIO_C_SET_FD:
+		sock_free(b);
+		b->num= *((int *)ptr);
+		b->shutdown=(int)num;
+		b->init=1;
+		break;
+	case BIO_C_GET_FD:
+		if (b->init)
+			{
+			ip=(int *)ptr;
+			if (ip != NULL) *ip=b->num;
+			ret=b->num;
+			}
+		else
+			ret= -1;
+		break;
+	case BIO_CTRL_GET_CLOSE:
+		ret=b->shutdown;
+		break;
+	case BIO_CTRL_SET_CLOSE:
+		b->shutdown=(int)num;
+		break;
+	case BIO_CTRL_DUP:
+	case BIO_CTRL_FLUSH:
+		ret=1;
+		break;
+	default:
+		ret=0;
+		break;
+		}
+	return(ret);
+	}
+
+static int sock_puts(BIO *bp, const char *str)
+	{
+	int n,ret;
+
+	n=strlen(str);
+	ret=sock_write(bp,str,n);
+	return(ret);
+	}
+
+int BIO_sock_should_retry(int i)
+	{
+	int err;
+
+	if ((i == 0) || (i == -1))
+		{
+		err=get_last_socket_error();
+
+#if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */
+		if ((i == -1) && (err == 0))
+			return(1);
+#endif
+
+		return(BIO_sock_non_fatal_error(err));
+		}
+	return(0);
+	}
+
+int BIO_sock_non_fatal_error(int err)
+	{
+	switch (err)
+		{
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_NETWARE)
+# if defined(WSAEWOULDBLOCK)
+	case WSAEWOULDBLOCK:
+# endif
+
+# if 0 /* This appears to always be an error */
+#  if defined(WSAENOTCONN)
+	case WSAENOTCONN:
+#  endif
+# endif
+#endif
+
+#ifdef EWOULDBLOCK
+# ifdef WSAEWOULDBLOCK
+#  if WSAEWOULDBLOCK != EWOULDBLOCK
+	case EWOULDBLOCK:
+#  endif
+# else
+	case EWOULDBLOCK:
+# endif
+#endif
+
+#if defined(ENOTCONN)
+	case ENOTCONN:
+#endif
+
+#ifdef EINTR
+	case EINTR:
+#endif
+
+#ifdef EAGAIN
+# if EWOULDBLOCK != EAGAIN
+	case EAGAIN:
+# endif
+#endif
+
+#ifdef EPROTO
+	case EPROTO:
+#endif
+
+#ifdef EINPROGRESS
+	case EINPROGRESS:
+#endif
+
+#ifdef EALREADY
+	case EALREADY:
+#endif
+		return(1);
+		/* break; */
+	default:
+		break;
+		}
+	return(0);
+	}
+
+#endif  /* #ifndef OPENSSL_NO_SOCK */
diff --git a/openssl/crypto/bn/Makefile b/openssl/crypto/bn/Makefile
new file mode 100644
index 0000000..aabc4f5
--- /dev/null
+++ b/openssl/crypto/bn/Makefile
@@ -0,0 +1,347 @@
+#
+# OpenSSL/crypto/bn/Makefile
+#
+
+DIR=	bn
+TOP=	../..
+CC=	cc
+CPP=    $(CC) -E
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+BN_ASM=		bn_asm.o
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+ASFLAGS= $(INCLUDES) $(ASFLAG)
+AFLAGS= $(ASFLAGS)
+
+GENERAL=Makefile
+TEST=bntest.c exptest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=	bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c bn_mod.c \
+	bn_print.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \
+	bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_err.c bn_sqr.c bn_asm.c \
+	bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c \
+	bn_depr.c bn_const.c
+
+LIBOBJ=	bn_add.o bn_div.o bn_exp.o bn_lib.o bn_ctx.o bn_mul.o bn_mod.o \
+	bn_print.o bn_rand.o bn_shift.o bn_word.o bn_blind.o \
+	bn_kron.o bn_sqrt.o bn_gcd.o bn_prime.o bn_err.o bn_sqr.o $(BN_ASM) \
+	bn_recp.o bn_mont.o bn_mpi.o bn_exp2.o bn_gf2m.o bn_nist.o \
+	bn_depr.o bn_const.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= bn.h
+HEADER=	bn_lcl.h bn_prime.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+bn_prime.h: bn_prime.pl
+	$(PERL) bn_prime.pl >bn_prime.h
+
+divtest: divtest.c ../../libcrypto.a
+	cc -I../../include divtest.c -o divtest ../../libcrypto.a
+
+bnbug: bnbug.c ../../libcrypto.a top
+	cc -g -I../../include bnbug.c -o bnbug ../../libcrypto.a
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+bn-586.s:	asm/bn-586.pl ../perlasm/x86asm.pl
+	$(PERL) asm/bn-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
+co-586.s:	asm/co-586.pl ../perlasm/x86asm.pl
+	$(PERL) asm/co-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
+x86-mont.s:	asm/x86-mont.pl ../perlasm/x86asm.pl
+	$(PERL) asm/x86-mont.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
+
+sparcv8.o:	asm/sparcv8.S
+	$(CC) $(CFLAGS) -c asm/sparcv8.S
+bn-sparcv9.o:	asm/sparcv8plus.S
+	$(CC) $(CFLAGS) -c -o $@ asm/sparcv8plus.S
+sparcv9a-mont.s:	asm/sparcv9a-mont.pl
+	$(PERL) asm/sparcv9a-mont.pl $(CFLAGS) > $@
+sparcv9-mont.s:		asm/sparcv9-mont.pl
+	$(PERL) asm/sparcv9-mont.pl $(CFLAGS) > $@
+
+bn-mips3.o:	asm/mips3.s
+	@if [ "$(CC)" = "gcc" ]; then \
+		ABI=`expr "$(CFLAGS)" : ".*-mabi=\([n3264]*\)"` && \
+		as -$$ABI -O -o $@ asm/mips3.s; \
+	else	$(CC) -c $(CFLAGS) -o $@ asm/mips3.s; fi
+
+bn-s390x.o:	asm/s390x.S
+	$(CC) $(CFLAGS) -c -o $@ asm/s390x.S
+
+x86_64-gcc.o:	asm/x86_64-gcc.c
+	$(CC) $(CFLAGS) -c -o $@ asm/x86_64-gcc.c
+x86_64-mont.s:	asm/x86_64-mont.pl
+	$(PERL) asm/x86_64-mont.pl $(PERLASM_SCHEME) > $@
+
+bn-ia64.s:	asm/ia64.S
+	$(CC) $(CFLAGS) -E asm/ia64.S > $@
+
+# GNU assembler fails to compile PA-RISC2 modules, insist on calling
+# vendor assembler...
+pa-risc2W.o: asm/pa-risc2W.s
+	/usr/ccs/bin/as -o pa-risc2W.o asm/pa-risc2W.s
+pa-risc2.o: asm/pa-risc2.s
+	/usr/ccs/bin/as -o pa-risc2.o asm/pa-risc2.s
+
+# ppc - AIX, Linux, MacOS X...
+bn-ppc.s:	asm/ppc.pl;	$(PERL) asm/ppc.pl $(PERLASM_SCHEME) $@
+ppc-mont.s:	asm/ppc-mont.pl;$(PERL) asm/ppc-mont.pl $(PERLASM_SCHEME) $@
+
+alpha-mont.s:	asm/alpha-mont.pl
+	$(PERL) $< | $(CC) -E - | tee $@ > /dev/null
+
+# GNU make "catch all"
+%-mont.s:	asm/%-mont.pl;	$(PERL) $< $(CFLAGS) > $@
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+exptest:
+	rm -f exptest
+	gcc -I../../include -g2 -ggdb -o exptest exptest.c ../../libcrypto.a
+
+div:
+	rm -f a.out
+	gcc -I.. -g div.c ../../libcrypto.a
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+bn_add.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_add.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_add.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_add.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_add.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_add.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_add.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_add.c bn_lcl.h
+bn_asm.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_asm.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_asm.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_asm.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_asm.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_asm.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_asm.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_asm.c bn_lcl.h
+bn_blind.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_blind.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_blind.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_blind.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_blind.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_blind.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_blind.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_blind.c bn_lcl.h
+bn_const.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+bn_const.o: ../../include/openssl/opensslconf.h
+bn_const.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_const.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_const.o: ../../include/openssl/symhacks.h bn.h bn_const.c
+bn_ctx.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_ctx.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_ctx.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_ctx.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_ctx.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_ctx.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_ctx.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_ctx.c bn_lcl.h
+bn_depr.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_depr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_depr.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_depr.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_depr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_depr.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+bn_depr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+bn_depr.o: ../cryptlib.h bn_depr.c bn_lcl.h
+bn_div.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_div.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_div.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_div.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_div.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_div.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_div.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_div.c bn_lcl.h
+bn_err.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+bn_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+bn_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+bn_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+bn_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+bn_err.o: bn_err.c
+bn_exp.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_exp.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_exp.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_exp.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_exp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_exp.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_exp.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_exp.c bn_lcl.h
+bn_exp2.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_exp2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_exp2.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_exp2.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_exp2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_exp2.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_exp2.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_exp2.c bn_lcl.h
+bn_gcd.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_gcd.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_gcd.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_gcd.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_gcd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_gcd.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_gcd.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_gcd.c bn_lcl.h
+bn_gf2m.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_gf2m.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_gf2m.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_gf2m.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_gf2m.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_gf2m.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_gf2m.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_gf2m.c bn_lcl.h
+bn_kron.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_kron.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_kron.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_kron.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_kron.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_kron.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_kron.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_kron.c bn_lcl.h
+bn_lib.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_lib.c
+bn_mod.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_mod.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_mod.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_mod.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_mod.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_mod.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_mod.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_mod.c
+bn_mont.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_mont.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_mont.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_mont.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_mont.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_mont.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_mont.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_mont.c
+bn_mpi.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_mpi.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_mpi.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_mpi.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_mpi.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_mpi.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_mpi.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_mpi.c
+bn_mul.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_mul.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_mul.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_mul.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_mul.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_mul.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_mul.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_mul.c
+bn_nist.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_nist.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_nist.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_nist.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_nist.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_nist.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_nist.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_nist.c
+bn_prime.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_prime.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_prime.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_prime.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_prime.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_prime.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+bn_prime.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+bn_prime.o: ../cryptlib.h bn_lcl.h bn_prime.c bn_prime.h
+bn_print.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_print.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_print.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_print.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_print.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_print.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_print.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_print.c
+bn_rand.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_rand.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_rand.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_rand.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+bn_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+bn_rand.o: ../cryptlib.h bn_lcl.h bn_rand.c
+bn_recp.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_recp.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_recp.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_recp.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_recp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_recp.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_recp.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_recp.c
+bn_shift.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_shift.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_shift.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_shift.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_shift.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_shift.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_shift.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_shift.c
+bn_sqr.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_sqr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_sqr.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_sqr.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_sqr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_sqr.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_sqr.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_sqr.c
+bn_sqrt.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_sqrt.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_sqrt.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_sqrt.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_sqrt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_sqrt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_sqrt.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_sqrt.c
+bn_word.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_word.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_word.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_word.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_word.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_word.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_word.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_word.c
diff --git a/openssl/crypto/bn/asm/README b/openssl/crypto/bn/asm/README
new file mode 100644
index 0000000..b0f3a68
--- /dev/null
+++ b/openssl/crypto/bn/asm/README
@@ -0,0 +1,27 @@
+<OBSOLETE>
+
+All assember in this directory are just version of the file
+crypto/bn/bn_asm.c.
+
+Quite a few of these files are just the assember output from gcc since on 
+quite a few machines they are 2 times faster than the system compiler.
+
+For the x86, I have hand written assember because of the bad job all
+compilers seem to do on it.  This normally gives a 2 time speed up in the RSA
+routines.
+
+For the DEC alpha, I also hand wrote the assember (except the division which
+is just the output from the C compiler pasted on the end of the file).
+On the 2 alpha C compilers I had access to, it was not possible to do
+64b x 64b -> 128b calculations (both long and the long long data types
+were 64 bits).  So the hand assember gives access to the 128 bit result and
+a 2 times speedup :-).
+
+There are 3 versions of assember for the HP PA-RISC.
+
+pa-risc.s is the origional one which works fine and generated using gcc :-)
+
+pa-risc2W.s and pa-risc2.s are 64 and 32-bit PA-RISC 2.0 implementations
+by Chris Ruemmler from HP (with some help from the HP C compiler).
+
+</OBSOLETE>
diff --git a/openssl/crypto/bn/asm/alpha-mont.pl b/openssl/crypto/bn/asm/alpha-mont.pl
new file mode 100644
index 0000000..03596e2
--- /dev/null
+++ b/openssl/crypto/bn/asm/alpha-mont.pl
@@ -0,0 +1,321 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# On 21264 RSA sign performance improves by 70/35/20/15 percent for
+# 512/1024/2048/4096 bit key lengths. This is against vendor compiler
+# instructed to '-tune host' code with in-line assembler. Other
+# benchmarks improve by 15-20%. To anchor it to something else, the
+# code provides approximately the same performance per GHz as AMD64.
+# I.e. if you compare 1GHz 21264 and 2GHz Opteron, you'll observe ~2x
+# difference.
+
+# int bn_mul_mont(
+$rp="a0";	# BN_ULONG *rp,
+$ap="a1";	# const BN_ULONG *ap,
+$bp="a2";	# const BN_ULONG *bp,
+$np="a3";	# const BN_ULONG *np,
+$n0="a4";	# const BN_ULONG *n0,
+$num="a5";	# int num);
+
+$lo0="t0";
+$hi0="t1";
+$lo1="t2";
+$hi1="t3";
+$aj="t4";
+$bi="t5";
+$nj="t6";
+$tp="t7";
+$alo="t8";
+$ahi="t9";
+$nlo="t10";
+$nhi="t11";
+$tj="t12";
+$i="s3";
+$j="s4";
+$m1="s5";
+
+$code=<<___;
+#ifdef __linux__
+#include <asm/regdef.h>
+#else
+#include <asm.h>
+#include <regdef.h>
+#endif
+
+.text
+
+.set	noat
+.set	noreorder
+
+.globl	bn_mul_mont
+.align	5
+.ent	bn_mul_mont
+bn_mul_mont:
+	lda	sp,-48(sp)
+	stq	ra,0(sp)
+	stq	s3,8(sp)
+	stq	s4,16(sp)
+	stq	s5,24(sp)
+	stq	fp,32(sp)
+	mov	sp,fp
+	.mask	0x0400f000,-48
+	.frame	fp,48,ra
+	.prologue 0
+
+	.align	4
+	.set	reorder
+	sextl	$num,$num
+	mov	0,v0
+	cmplt	$num,4,AT
+	bne	AT,.Lexit
+
+	ldq	$hi0,0($ap)	# ap[0]
+	s8addq	$num,16,AT
+	ldq	$aj,8($ap)
+	subq	sp,AT,sp
+	ldq	$bi,0($bp)	# bp[0]
+	lda	AT,-4096(zero)	# mov	-4096,AT
+	ldq	$n0,0($n0)
+	and	sp,AT,sp
+
+	mulq	$hi0,$bi,$lo0
+	ldq	$hi1,0($np)	# np[0]
+	umulh	$hi0,$bi,$hi0
+	ldq	$nj,8($np)
+
+	mulq	$lo0,$n0,$m1
+
+	mulq	$hi1,$m1,$lo1
+	umulh	$hi1,$m1,$hi1
+
+	addq	$lo1,$lo0,$lo1
+	cmpult	$lo1,$lo0,AT
+	addq	$hi1,AT,$hi1
+
+	mulq	$aj,$bi,$alo
+	mov	2,$j
+	umulh	$aj,$bi,$ahi
+	mov	sp,$tp
+
+	mulq	$nj,$m1,$nlo
+	s8addq	$j,$ap,$aj
+	umulh	$nj,$m1,$nhi
+	s8addq	$j,$np,$nj
+.align	4
+.L1st:
+	.set	noreorder
+	ldq	$aj,0($aj)
+	addl	$j,1,$j
+	ldq	$nj,0($nj)
+	lda	$tp,8($tp)
+
+	addq	$alo,$hi0,$lo0
+	mulq	$aj,$bi,$alo
+	cmpult	$lo0,$hi0,AT
+	addq	$nlo,$hi1,$lo1
+
+	mulq	$nj,$m1,$nlo
+	addq	$ahi,AT,$hi0
+	cmpult	$lo1,$hi1,v0
+	cmplt	$j,$num,$tj
+
+	umulh	$aj,$bi,$ahi
+	addq	$nhi,v0,$hi1
+	addq	$lo1,$lo0,$lo1
+	s8addq	$j,$ap,$aj
+
+	umulh	$nj,$m1,$nhi
+	cmpult	$lo1,$lo0,v0
+	addq	$hi1,v0,$hi1
+	s8addq	$j,$np,$nj
+
+	stq	$lo1,-8($tp)
+	nop
+	unop
+	bne	$tj,.L1st
+	.set	reorder
+
+	addq	$alo,$hi0,$lo0
+	addq	$nlo,$hi1,$lo1
+	cmpult	$lo0,$hi0,AT
+	cmpult	$lo1,$hi1,v0
+	addq	$ahi,AT,$hi0
+	addq	$nhi,v0,$hi1
+
+	addq	$lo1,$lo0,$lo1
+	cmpult	$lo1,$lo0,v0
+	addq	$hi1,v0,$hi1
+
+	stq	$lo1,0($tp)
+
+	addq	$hi1,$hi0,$hi1
+	cmpult	$hi1,$hi0,AT
+	stq	$hi1,8($tp)
+	stq	AT,16($tp)
+
+	mov	1,$i
+.align	4
+.Louter:
+	s8addq	$i,$bp,$bi
+	ldq	$hi0,0($ap)
+	ldq	$aj,8($ap)
+	ldq	$bi,0($bi)
+	ldq	$hi1,0($np)
+	ldq	$nj,8($np)
+	ldq	$tj,0(sp)
+
+	mulq	$hi0,$bi,$lo0
+	umulh	$hi0,$bi,$hi0
+
+	addq	$lo0,$tj,$lo0
+	cmpult	$lo0,$tj,AT
+	addq	$hi0,AT,$hi0
+
+	mulq	$lo0,$n0,$m1
+
+	mulq	$hi1,$m1,$lo1
+	umulh	$hi1,$m1,$hi1
+
+	addq	$lo1,$lo0,$lo1
+	cmpult	$lo1,$lo0,AT
+	mov	2,$j
+	addq	$hi1,AT,$hi1
+
+	mulq	$aj,$bi,$alo
+	mov	sp,$tp
+	umulh	$aj,$bi,$ahi
+
+	mulq	$nj,$m1,$nlo
+	s8addq	$j,$ap,$aj
+	umulh	$nj,$m1,$nhi
+.align	4
+.Linner:
+	.set	noreorder
+	ldq	$tj,8($tp)	#L0
+	nop			#U1
+	ldq	$aj,0($aj)	#L1
+	s8addq	$j,$np,$nj	#U0
+
+	ldq	$nj,0($nj)	#L0
+	nop			#U1
+	addq	$alo,$hi0,$lo0	#L1
+	lda	$tp,8($tp)
+
+	mulq	$aj,$bi,$alo	#U1
+	cmpult	$lo0,$hi0,AT	#L0
+	addq	$nlo,$hi1,$lo1	#L1
+	addl	$j,1,$j
+
+	mulq	$nj,$m1,$nlo	#U1
+	addq	$ahi,AT,$hi0	#L0
+	addq	$lo0,$tj,$lo0	#L1
+	cmpult	$lo1,$hi1,v0	#U0
+
+	umulh	$aj,$bi,$ahi	#U1
+	cmpult	$lo0,$tj,AT	#L0
+	addq	$lo1,$lo0,$lo1	#L1
+	addq	$nhi,v0,$hi1	#U0
+
+	umulh	$nj,$m1,$nhi	#U1
+	s8addq	$j,$ap,$aj	#L0
+	cmpult	$lo1,$lo0,v0	#L1
+	cmplt	$j,$num,$tj	#U0	# borrow $tj
+
+	addq	$hi0,AT,$hi0	#L0
+	addq	$hi1,v0,$hi1	#U1
+	stq	$lo1,-8($tp)	#L1
+	bne	$tj,.Linner	#U0
+	.set	reorder
+
+	ldq	$tj,8($tp)
+	addq	$alo,$hi0,$lo0
+	addq	$nlo,$hi1,$lo1
+	cmpult	$lo0,$hi0,AT
+	cmpult	$lo1,$hi1,v0
+	addq	$ahi,AT,$hi0
+	addq	$nhi,v0,$hi1
+
+	addq	$lo0,$tj,$lo0
+	cmpult	$lo0,$tj,AT
+	addq	$hi0,AT,$hi0
+
+	ldq	$tj,16($tp)
+	addq	$lo1,$lo0,$j
+	cmpult	$j,$lo0,v0
+	addq	$hi1,v0,$hi1
+
+	addq	$hi1,$hi0,$lo1
+	stq	$j,0($tp)
+	cmpult	$lo1,$hi0,$hi1
+	addq	$lo1,$tj,$lo1
+	cmpult	$lo1,$tj,AT
+	addl	$i,1,$i
+	addq	$hi1,AT,$hi1
+	stq	$lo1,8($tp)
+	cmplt	$i,$num,$tj	# borrow $tj
+	stq	$hi1,16($tp)
+	bne	$tj,.Louter
+
+	s8addq	$num,sp,$tj	# &tp[num]
+	mov	$rp,$bp		# put rp aside
+	mov	sp,$tp
+	mov	sp,$ap
+	mov	0,$hi0		# clear borrow bit
+
+.align	4
+.Lsub:	ldq	$lo0,0($tp)
+	ldq	$lo1,0($np)
+	lda	$tp,8($tp)
+	lda	$np,8($np)
+	subq	$lo0,$lo1,$lo1	# tp[i]-np[i]
+	cmpult	$lo0,$lo1,AT
+	subq	$lo1,$hi0,$lo0
+	cmpult	$lo1,$lo0,$hi0
+	or	$hi0,AT,$hi0
+	stq	$lo0,0($rp)
+	cmpult	$tp,$tj,v0
+	lda	$rp,8($rp)
+	bne	v0,.Lsub
+
+	subq	$hi1,$hi0,$hi0	# handle upmost overflow bit
+	mov	sp,$tp
+	mov	$bp,$rp		# restore rp
+
+	and	sp,$hi0,$ap
+	bic	$bp,$hi0,$bp
+	bis	$bp,$ap,$ap	# ap=borrow?tp:rp
+
+.align	4
+.Lcopy:	ldq	$aj,0($ap)	# copy or in-place refresh
+	lda	$tp,8($tp)
+	lda	$rp,8($rp)
+	lda	$ap,8($ap)
+	stq	zero,-8($tp)	# zap tp
+	cmpult	$tp,$tj,AT
+	stq	$aj,-8($rp)
+	bne	AT,.Lcopy
+	mov	1,v0
+
+.Lexit:
+	.set	noreorder
+	mov	fp,sp
+	/*ldq	ra,0(sp)*/
+	ldq	s3,8(sp)
+	ldq	s4,16(sp)
+	ldq	s5,24(sp)
+	ldq	fp,32(sp)
+	lda	sp,48(sp)
+	ret	(ra)
+.end	bn_mul_mont
+.ascii	"Montgomery Multiplication for Alpha, CRYPTOGAMS by <appro\@openssl.org>"
+.align	2
+___
+
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/bn/asm/armv4-mont.pl b/openssl/crypto/bn/asm/armv4-mont.pl
new file mode 100644
index 0000000..14e0d2d
--- /dev/null
+++ b/openssl/crypto/bn/asm/armv4-mont.pl
@@ -0,0 +1,201 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# January 2007.
+
+# Montgomery multiplication for ARMv4.
+#
+# Performance improvement naturally varies among CPU implementations
+# and compilers. The code was observed to provide +65-35% improvement
+# [depending on key length, less for longer keys] on ARM920T, and
+# +115-80% on Intel IXP425. This is compared to pre-bn_mul_mont code
+# base and compiler generated code with in-lined umull and even umlal
+# instructions. The latter means that this code didn't really have an 
+# "advantage" of utilizing some "secret" instruction.
+#
+# The code is interoperable with Thumb ISA and is rather compact, less
+# than 1/2KB. Windows CE port would be trivial, as it's exclusively
+# about decorations, ABI and instruction syntax are identical.
+
+$num="r0";	# starts as num argument, but holds &tp[num-1]
+$ap="r1";
+$bp="r2"; $bi="r2"; $rp="r2";
+$np="r3";
+$tp="r4";
+$aj="r5";
+$nj="r6";
+$tj="r7";
+$n0="r8";
+###########	# r9 is reserved by ELF as platform specific, e.g. TLS pointer
+$alo="r10";	# sl, gcc uses it to keep @GOT
+$ahi="r11";	# fp
+$nlo="r12";	# ip
+###########	# r13 is stack pointer
+$nhi="r14";	# lr
+###########	# r15 is program counter
+
+#### argument block layout relative to &tp[num-1], a.k.a. $num
+$_rp="$num,#12*4";
+# ap permanently resides in r1
+$_bp="$num,#13*4";
+# np permanently resides in r3
+$_n0="$num,#14*4";
+$_num="$num,#15*4";	$_bpend=$_num;
+
+$code=<<___;
+.text
+
+.global	bn_mul_mont
+.type	bn_mul_mont,%function
+
+.align	2
+bn_mul_mont:
+	stmdb	sp!,{r0,r2}		@ sp points at argument block
+	ldr	$num,[sp,#3*4]		@ load num
+	cmp	$num,#2
+	movlt	r0,#0
+	addlt	sp,sp,#2*4
+	blt	.Labrt
+
+	stmdb	sp!,{r4-r12,lr}		@ save 10 registers
+
+	mov	$num,$num,lsl#2		@ rescale $num for byte count
+	sub	sp,sp,$num		@ alloca(4*num)
+	sub	sp,sp,#4		@ +extra dword
+	sub	$num,$num,#4		@ "num=num-1"
+	add	$tp,$bp,$num		@ &bp[num-1]
+
+	add	$num,sp,$num		@ $num to point at &tp[num-1]
+	ldr	$n0,[$_n0]		@ &n0
+	ldr	$bi,[$bp]		@ bp[0]
+	ldr	$aj,[$ap],#4		@ ap[0],ap++
+	ldr	$nj,[$np],#4		@ np[0],np++
+	ldr	$n0,[$n0]		@ *n0
+	str	$tp,[$_bpend]		@ save &bp[num]
+
+	umull	$alo,$ahi,$aj,$bi	@ ap[0]*bp[0]
+	str	$n0,[$_n0]		@ save n0 value
+	mul	$n0,$alo,$n0		@ "tp[0]"*n0
+	mov	$nlo,#0
+	umlal	$alo,$nlo,$nj,$n0	@ np[0]*n0+"t[0]"
+	mov	$tp,sp
+
+.L1st:
+	ldr	$aj,[$ap],#4		@ ap[j],ap++
+	mov	$alo,$ahi
+	mov	$ahi,#0
+	umlal	$alo,$ahi,$aj,$bi	@ ap[j]*bp[0]
+	ldr	$nj,[$np],#4		@ np[j],np++
+	mov	$nhi,#0
+	umlal	$nlo,$nhi,$nj,$n0	@ np[j]*n0
+	adds	$nlo,$nlo,$alo
+	str	$nlo,[$tp],#4		@ tp[j-1]=,tp++
+	adc	$nlo,$nhi,#0
+	cmp	$tp,$num
+	bne	.L1st
+
+	adds	$nlo,$nlo,$ahi
+	mov	$nhi,#0
+	adc	$nhi,$nhi,#0
+	ldr	$tp,[$_bp]		@ restore bp
+	str	$nlo,[$num]		@ tp[num-1]=
+	ldr	$n0,[$_n0]		@ restore n0
+	str	$nhi,[$num,#4]		@ tp[num]=
+
+.Louter:
+	sub	$tj,$num,sp		@ "original" $num-1 value
+	sub	$ap,$ap,$tj		@ "rewind" ap to &ap[1]
+	sub	$np,$np,$tj		@ "rewind" np to &np[1]
+	ldr	$bi,[$tp,#4]!		@ *(++bp)
+	ldr	$aj,[$ap,#-4]		@ ap[0]
+	ldr	$nj,[$np,#-4]		@ np[0]
+	ldr	$alo,[sp]		@ tp[0]
+	ldr	$tj,[sp,#4]		@ tp[1]
+
+	mov	$ahi,#0
+	umlal	$alo,$ahi,$aj,$bi	@ ap[0]*bp[i]+tp[0]
+	str	$tp,[$_bp]		@ save bp
+	mul	$n0,$alo,$n0
+	mov	$nlo,#0
+	umlal	$alo,$nlo,$nj,$n0	@ np[0]*n0+"tp[0]"
+	mov	$tp,sp
+
+.Linner:
+	ldr	$aj,[$ap],#4		@ ap[j],ap++
+	adds	$alo,$ahi,$tj		@ +=tp[j]
+	mov	$ahi,#0
+	umlal	$alo,$ahi,$aj,$bi	@ ap[j]*bp[i]
+	ldr	$nj,[$np],#4		@ np[j],np++
+	mov	$nhi,#0
+	umlal	$nlo,$nhi,$nj,$n0	@ np[j]*n0
+	ldr	$tj,[$tp,#8]		@ tp[j+1]
+	adc	$ahi,$ahi,#0
+	adds	$nlo,$nlo,$alo
+	str	$nlo,[$tp],#4		@ tp[j-1]=,tp++
+	adc	$nlo,$nhi,#0
+	cmp	$tp,$num
+	bne	.Linner
+
+	adds	$nlo,$nlo,$ahi
+	mov	$nhi,#0
+	adc	$nhi,$nhi,#0
+	adds	$nlo,$nlo,$tj
+	adc	$nhi,$nhi,#0
+	ldr	$tp,[$_bp]		@ restore bp
+	ldr	$tj,[$_bpend]		@ restore &bp[num]
+	str	$nlo,[$num]		@ tp[num-1]=
+	ldr	$n0,[$_n0]		@ restore n0
+	str	$nhi,[$num,#4]		@ tp[num]=
+
+	cmp	$tp,$tj
+	bne	.Louter
+
+	ldr	$rp,[$_rp]		@ pull rp
+	add	$num,$num,#4		@ $num to point at &tp[num]
+	sub	$aj,$num,sp		@ "original" num value
+	mov	$tp,sp			@ "rewind" $tp
+	mov	$ap,$tp			@ "borrow" $ap
+	sub	$np,$np,$aj		@ "rewind" $np to &np[0]
+
+	subs	$tj,$tj,$tj		@ "clear" carry flag
+.Lsub:	ldr	$tj,[$tp],#4
+	ldr	$nj,[$np],#4
+	sbcs	$tj,$tj,$nj		@ tp[j]-np[j]
+	str	$tj,[$rp],#4		@ rp[j]=
+	teq	$tp,$num		@ preserve carry
+	bne	.Lsub
+	sbcs	$nhi,$nhi,#0		@ upmost carry
+	mov	$tp,sp			@ "rewind" $tp
+	sub	$rp,$rp,$aj		@ "rewind" $rp
+
+	and	$ap,$tp,$nhi
+	bic	$np,$rp,$nhi
+	orr	$ap,$ap,$np		@ ap=borrow?tp:rp
+
+.Lcopy:	ldr	$tj,[$ap],#4		@ copy or in-place refresh
+	str	sp,[$tp],#4		@ zap tp
+	str	$tj,[$rp],#4
+	cmp	$tp,$num
+	bne	.Lcopy
+
+	add	sp,$num,#4		@ skip over tp[num+1]
+	ldmia	sp!,{r4-r12,lr}		@ restore registers
+	add	sp,sp,#2*4		@ skip over {r0,r2}
+	mov	r0,#1
+.Labrt:	tst	lr,#1
+	moveq	pc,lr			@ be binary compatible with V4, yet
+	bx	lr			@ interoperable with Thumb ISA:-)
+.size	bn_mul_mont,.-bn_mul_mont
+.asciz	"Montgomery multiplication for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
+.align	2
+___
+
+$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/bn/asm/bn-586.pl b/openssl/crypto/bn/asm/bn-586.pl
new file mode 100644
index 0000000..332ef3e
--- /dev/null
+++ b/openssl/crypto/bn/asm/bn-586.pl
@@ -0,0 +1,774 @@
+#!/usr/local/bin/perl
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],$0);
+
+$sse2=0;
+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
+
+&external_label("OPENSSL_ia32cap_P") if ($sse2);
+
+&bn_mul_add_words("bn_mul_add_words");
+&bn_mul_words("bn_mul_words");
+&bn_sqr_words("bn_sqr_words");
+&bn_div_words("bn_div_words");
+&bn_add_words("bn_add_words");
+&bn_sub_words("bn_sub_words");
+&bn_sub_part_words("bn_sub_part_words");
+
+&asm_finish();
+
+sub bn_mul_add_words
+	{
+	local($name)=@_;
+
+	&function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
+
+	$r="eax";
+	$a="edx";
+	$c="ecx";
+
+	if ($sse2) {
+		&picmeup("eax","OPENSSL_ia32cap_P");
+		&bt(&DWP(0,"eax"),26);
+		&jnc(&label("maw_non_sse2"));
+
+		&mov($r,&wparam(0));
+		&mov($a,&wparam(1));
+		&mov($c,&wparam(2));
+		&movd("mm0",&wparam(3));	# mm0 = w
+		&pxor("mm1","mm1");		# mm1 = carry_in
+		&jmp(&label("maw_sse2_entry"));
+		
+	&set_label("maw_sse2_unrolled",16);
+		&movd("mm3",&DWP(0,$r,"",0));	# mm3 = r[0]
+		&paddq("mm1","mm3");		# mm1 = carry_in + r[0]
+		&movd("mm2",&DWP(0,$a,"",0));	# mm2 = a[0]
+		&pmuludq("mm2","mm0");		# mm2 = w*a[0]
+		&movd("mm4",&DWP(4,$a,"",0));	# mm4 = a[1]
+		&pmuludq("mm4","mm0");		# mm4 = w*a[1]
+		&movd("mm6",&DWP(8,$a,"",0));	# mm6 = a[2]
+		&pmuludq("mm6","mm0");		# mm6 = w*a[2]
+		&movd("mm7",&DWP(12,$a,"",0));	# mm7 = a[3]
+		&pmuludq("mm7","mm0");		# mm7 = w*a[3]
+		&paddq("mm1","mm2");		# mm1 = carry_in + r[0] + w*a[0]
+		&movd("mm3",&DWP(4,$r,"",0));	# mm3 = r[1]
+		&paddq("mm3","mm4");		# mm3 = r[1] + w*a[1]
+		&movd("mm5",&DWP(8,$r,"",0));	# mm5 = r[2]
+		&paddq("mm5","mm6");		# mm5 = r[2] + w*a[2]
+		&movd("mm4",&DWP(12,$r,"",0));	# mm4 = r[3]
+		&paddq("mm7","mm4");		# mm7 = r[3] + w*a[3]
+		&movd(&DWP(0,$r,"",0),"mm1");
+		&movd("mm2",&DWP(16,$a,"",0));	# mm2 = a[4]
+		&pmuludq("mm2","mm0");		# mm2 = w*a[4]
+		&psrlq("mm1",32);		# mm1 = carry0
+		&movd("mm4",&DWP(20,$a,"",0));	# mm4 = a[5]
+		&pmuludq("mm4","mm0");		# mm4 = w*a[5]
+		&paddq("mm1","mm3");		# mm1 = carry0 + r[1] + w*a[1]
+		&movd("mm6",&DWP(24,$a,"",0));	# mm6 = a[6]
+		&pmuludq("mm6","mm0");		# mm6 = w*a[6]
+		&movd(&DWP(4,$r,"",0),"mm1");
+		&psrlq("mm1",32);		# mm1 = carry1
+		&movd("mm3",&DWP(28,$a,"",0));	# mm3 = a[7]
+		&add($a,32);
+		&pmuludq("mm3","mm0");		# mm3 = w*a[7]
+		&paddq("mm1","mm5");		# mm1 = carry1 + r[2] + w*a[2]
+		&movd("mm5",&DWP(16,$r,"",0));	# mm5 = r[4]
+		&paddq("mm2","mm5");		# mm2 = r[4] + w*a[4]
+		&movd(&DWP(8,$r,"",0),"mm1");
+		&psrlq("mm1",32);		# mm1 = carry2
+		&paddq("mm1","mm7");		# mm1 = carry2 + r[3] + w*a[3]
+		&movd("mm5",&DWP(20,$r,"",0));	# mm5 = r[5]
+		&paddq("mm4","mm5");		# mm4 = r[5] + w*a[5]
+		&movd(&DWP(12,$r,"",0),"mm1");
+		&psrlq("mm1",32);		# mm1 = carry3
+		&paddq("mm1","mm2");		# mm1 = carry3 + r[4] + w*a[4]
+		&movd("mm5",&DWP(24,$r,"",0));	# mm5 = r[6]
+		&paddq("mm6","mm5");		# mm6 = r[6] + w*a[6]
+		&movd(&DWP(16,$r,"",0),"mm1");
+		&psrlq("mm1",32);		# mm1 = carry4
+		&paddq("mm1","mm4");		# mm1 = carry4 + r[5] + w*a[5]
+		&movd("mm5",&DWP(28,$r,"",0));	# mm5 = r[7]
+		&paddq("mm3","mm5");		# mm3 = r[7] + w*a[7]
+		&movd(&DWP(20,$r,"",0),"mm1");
+		&psrlq("mm1",32);		# mm1 = carry5
+		&paddq("mm1","mm6");		# mm1 = carry5 + r[6] + w*a[6]
+		&movd(&DWP(24,$r,"",0),"mm1");
+		&psrlq("mm1",32);		# mm1 = carry6
+		&paddq("mm1","mm3");		# mm1 = carry6 + r[7] + w*a[7]
+		&movd(&DWP(28,$r,"",0),"mm1");
+		&lea($r,&DWP(32,$r));
+		&psrlq("mm1",32);		# mm1 = carry_out
+
+		&sub($c,8);
+		&jz(&label("maw_sse2_exit"));
+	&set_label("maw_sse2_entry");
+		&test($c,0xfffffff8);
+		&jnz(&label("maw_sse2_unrolled"));
+
+	&set_label("maw_sse2_loop",4);
+		&movd("mm2",&DWP(0,$a));	# mm2 = a[i]
+		&movd("mm3",&DWP(0,$r));	# mm3 = r[i]
+		&pmuludq("mm2","mm0");		# a[i] *= w
+		&lea($a,&DWP(4,$a));
+		&paddq("mm1","mm3");		# carry += r[i]
+		&paddq("mm1","mm2");		# carry += a[i]*w
+		&movd(&DWP(0,$r),"mm1");	# r[i] = carry_low
+		&sub($c,1);
+		&psrlq("mm1",32);		# carry = carry_high
+		&lea($r,&DWP(4,$r));
+		&jnz(&label("maw_sse2_loop"));
+	&set_label("maw_sse2_exit");
+		&movd("eax","mm1");		# c = carry_out
+		&emms();
+		&ret();
+
+	&set_label("maw_non_sse2",16);
+	}
+
+	# function_begin prologue
+	&push("ebp");
+	&push("ebx");
+	&push("esi");
+	&push("edi");
+
+	&comment("");
+	$Low="eax";
+	$High="edx";
+	$a="ebx";
+	$w="ebp";
+	$r="edi";
+	$c="esi";
+
+	&xor($c,$c);		# clear carry
+	&mov($r,&wparam(0));	#
+
+	&mov("ecx",&wparam(2));	#
+	&mov($a,&wparam(1));	#
+
+	&and("ecx",0xfffffff8);	# num / 8
+	&mov($w,&wparam(3));	#
+
+	&push("ecx");		# Up the stack for a tmp variable
+
+	&jz(&label("maw_finish"));
+
+	&set_label("maw_loop",16);
+
+	for ($i=0; $i<32; $i+=4)
+		{
+		&comment("Round $i");
+
+		 &mov("eax",&DWP($i,$a)); 	# *a
+		&mul($w);			# *a * w
+		&add("eax",$c);			# L(t)+= c
+		&adc("edx",0);			# H(t)+=carry
+		 &add("eax",&DWP($i,$r));	# L(t)+= *r
+		&adc("edx",0);			# H(t)+=carry
+		 &mov(&DWP($i,$r),"eax");	# *r= L(t);
+		&mov($c,"edx");			# c=  H(t);
+		}
+
+	&comment("");
+	&sub("ecx",8);
+	&lea($a,&DWP(32,$a));
+	&lea($r,&DWP(32,$r));
+	&jnz(&label("maw_loop"));
+
+	&set_label("maw_finish",0);
+	&mov("ecx",&wparam(2));	# get num
+	&and("ecx",7);
+	&jnz(&label("maw_finish2"));	# helps branch prediction
+	&jmp(&label("maw_end"));
+
+	&set_label("maw_finish2",1);
+	for ($i=0; $i<7; $i++)
+		{
+		&comment("Tail Round $i");
+		 &mov("eax",&DWP($i*4,$a));	# *a
+		&mul($w);			# *a * w
+		&add("eax",$c);			# L(t)+=c
+		&adc("edx",0);			# H(t)+=carry
+		 &add("eax",&DWP($i*4,$r));	# L(t)+= *r
+		&adc("edx",0);			# H(t)+=carry
+		 &dec("ecx") if ($i != 7-1);
+		&mov(&DWP($i*4,$r),"eax");	# *r= L(t);
+		 &mov($c,"edx");		# c=  H(t);
+		&jz(&label("maw_end")) if ($i != 7-1);
+		}
+	&set_label("maw_end",0);
+	&mov("eax",$c);
+
+	&pop("ecx");	# clear variable from
+
+	&function_end($name);
+	}
+
+sub bn_mul_words
+	{
+	local($name)=@_;
+
+	&function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
+
+	$r="eax";
+	$a="edx";
+	$c="ecx";
+
+	if ($sse2) {
+		&picmeup("eax","OPENSSL_ia32cap_P");
+		&bt(&DWP(0,"eax"),26);
+		&jnc(&label("mw_non_sse2"));
+
+		&mov($r,&wparam(0));
+		&mov($a,&wparam(1));
+		&mov($c,&wparam(2));
+		&movd("mm0",&wparam(3));	# mm0 = w
+		&pxor("mm1","mm1");		# mm1 = carry = 0
+
+	&set_label("mw_sse2_loop",16);
+		&movd("mm2",&DWP(0,$a));	# mm2 = a[i]
+		&pmuludq("mm2","mm0");		# a[i] *= w
+		&lea($a,&DWP(4,$a));
+		&paddq("mm1","mm2");		# carry += a[i]*w
+		&movd(&DWP(0,$r),"mm1");	# r[i] = carry_low
+		&sub($c,1);
+		&psrlq("mm1",32);		# carry = carry_high
+		&lea($r,&DWP(4,$r));
+		&jnz(&label("mw_sse2_loop"));
+
+		&movd("eax","mm1");		# return carry
+		&emms();
+		&ret();
+	&set_label("mw_non_sse2",16);
+	}
+
+	# function_begin prologue
+	&push("ebp");
+	&push("ebx");
+	&push("esi");
+	&push("edi");
+
+	&comment("");
+	$Low="eax";
+	$High="edx";
+	$a="ebx";
+	$w="ecx";
+	$r="edi";
+	$c="esi";
+	$num="ebp";
+
+	&xor($c,$c);		# clear carry
+	&mov($r,&wparam(0));	#
+	&mov($a,&wparam(1));	#
+	&mov($num,&wparam(2));	#
+	&mov($w,&wparam(3));	#
+
+	&and($num,0xfffffff8);	# num / 8
+	&jz(&label("mw_finish"));
+
+	&set_label("mw_loop",0);
+	for ($i=0; $i<32; $i+=4)
+		{
+		&comment("Round $i");
+
+		 &mov("eax",&DWP($i,$a,"",0)); 	# *a
+		&mul($w);			# *a * w
+		&add("eax",$c);			# L(t)+=c
+		 # XXX
+
+		&adc("edx",0);			# H(t)+=carry
+		 &mov(&DWP($i,$r,"",0),"eax");	# *r= L(t);
+
+		&mov($c,"edx");			# c=  H(t);
+		}
+
+	&comment("");
+	&add($a,32);
+	&add($r,32);
+	&sub($num,8);
+	&jz(&label("mw_finish"));
+	&jmp(&label("mw_loop"));
+
+	&set_label("mw_finish",0);
+	&mov($num,&wparam(2));	# get num
+	&and($num,7);
+	&jnz(&label("mw_finish2"));
+	&jmp(&label("mw_end"));
+
+	&set_label("mw_finish2",1);
+	for ($i=0; $i<7; $i++)
+		{
+		&comment("Tail Round $i");
+		 &mov("eax",&DWP($i*4,$a,"",0));# *a
+		&mul($w);			# *a * w
+		&add("eax",$c);			# L(t)+=c
+		 # XXX
+		&adc("edx",0);			# H(t)+=carry
+		 &mov(&DWP($i*4,$r,"",0),"eax");# *r= L(t);
+		&mov($c,"edx");			# c=  H(t);
+		 &dec($num) if ($i != 7-1);
+		&jz(&label("mw_end")) if ($i != 7-1);
+		}
+	&set_label("mw_end",0);
+	&mov("eax",$c);
+
+	&function_end($name);
+	}
+
+sub bn_sqr_words
+	{
+	local($name)=@_;
+
+	&function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
+
+	$r="eax";
+	$a="edx";
+	$c="ecx";
+
+	if ($sse2) {
+		&picmeup("eax","OPENSSL_ia32cap_P");
+		&bt(&DWP(0,"eax"),26);
+		&jnc(&label("sqr_non_sse2"));
+
+		&mov($r,&wparam(0));
+		&mov($a,&wparam(1));
+		&mov($c,&wparam(2));
+
+	&set_label("sqr_sse2_loop",16);
+		&movd("mm0",&DWP(0,$a));	# mm0 = a[i]
+		&pmuludq("mm0","mm0");		# a[i] *= a[i]
+		&lea($a,&DWP(4,$a));		# a++
+		&movq(&QWP(0,$r),"mm0");	# r[i] = a[i]*a[i]
+		&sub($c,1);
+		&lea($r,&DWP(8,$r));		# r += 2
+		&jnz(&label("sqr_sse2_loop"));
+
+		&emms();
+		&ret();
+	&set_label("sqr_non_sse2",16);
+	}
+
+	# function_begin prologue
+	&push("ebp");
+	&push("ebx");
+	&push("esi");
+	&push("edi");
+
+	&comment("");
+	$r="esi";
+	$a="edi";
+	$num="ebx";
+
+	&mov($r,&wparam(0));	#
+	&mov($a,&wparam(1));	#
+	&mov($num,&wparam(2));	#
+
+	&and($num,0xfffffff8);	# num / 8
+	&jz(&label("sw_finish"));
+
+	&set_label("sw_loop",0);
+	for ($i=0; $i<32; $i+=4)
+		{
+		&comment("Round $i");
+		&mov("eax",&DWP($i,$a,"",0)); 	# *a
+		 # XXX
+		&mul("eax");			# *a * *a
+		&mov(&DWP($i*2,$r,"",0),"eax");	#
+		 &mov(&DWP($i*2+4,$r,"",0),"edx");#
+		}
+
+	&comment("");
+	&add($a,32);
+	&add($r,64);
+	&sub($num,8);
+	&jnz(&label("sw_loop"));
+
+	&set_label("sw_finish",0);
+	&mov($num,&wparam(2));	# get num
+	&and($num,7);
+	&jz(&label("sw_end"));
+
+	for ($i=0; $i<7; $i++)
+		{
+		&comment("Tail Round $i");
+		&mov("eax",&DWP($i*4,$a,"",0));	# *a
+		 # XXX
+		&mul("eax");			# *a * *a
+		&mov(&DWP($i*8,$r,"",0),"eax");	#
+		 &dec($num) if ($i != 7-1);
+		&mov(&DWP($i*8+4,$r,"",0),"edx");
+		 &jz(&label("sw_end")) if ($i != 7-1);
+		}
+	&set_label("sw_end",0);
+
+	&function_end($name);
+	}
+
+sub bn_div_words
+	{
+	local($name)=@_;
+
+	&function_begin_B($name,"");
+	&mov("edx",&wparam(0));	#
+	&mov("eax",&wparam(1));	#
+	&mov("ecx",&wparam(2));	#
+	&div("ecx");
+	&ret();
+	&function_end_B($name);
+	}
+
+sub bn_add_words
+	{
+	local($name)=@_;
+
+	&function_begin($name,"");
+
+	&comment("");
+	$a="esi";
+	$b="edi";
+	$c="eax";
+	$r="ebx";
+	$tmp1="ecx";
+	$tmp2="edx";
+	$num="ebp";
+
+	&mov($r,&wparam(0));	# get r
+	 &mov($a,&wparam(1));	# get a
+	&mov($b,&wparam(2));	# get b
+	 &mov($num,&wparam(3));	# get num
+	&xor($c,$c);		# clear carry
+	 &and($num,0xfffffff8);	# num / 8
+
+	&jz(&label("aw_finish"));
+
+	&set_label("aw_loop",0);
+	for ($i=0; $i<8; $i++)
+		{
+		&comment("Round $i");
+
+		&mov($tmp1,&DWP($i*4,$a,"",0)); 	# *a
+		 &mov($tmp2,&DWP($i*4,$b,"",0)); 	# *b
+		&add($tmp1,$c);
+		 &mov($c,0);
+		&adc($c,$c);
+		 &add($tmp1,$tmp2);
+		&adc($c,0);
+		 &mov(&DWP($i*4,$r,"",0),$tmp1); 	# *r
+		}
+
+	&comment("");
+	&add($a,32);
+	 &add($b,32);
+	&add($r,32);
+	 &sub($num,8);
+	&jnz(&label("aw_loop"));
+
+	&set_label("aw_finish",0);
+	&mov($num,&wparam(3));	# get num
+	&and($num,7);
+	 &jz(&label("aw_end"));
+
+	for ($i=0; $i<7; $i++)
+		{
+		&comment("Tail Round $i");
+		&mov($tmp1,&DWP($i*4,$a,"",0));	# *a
+		 &mov($tmp2,&DWP($i*4,$b,"",0));# *b
+		&add($tmp1,$c);
+		 &mov($c,0);
+		&adc($c,$c);
+		 &add($tmp1,$tmp2);
+		&adc($c,0);
+		 &dec($num) if ($i != 6);
+		&mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
+		 &jz(&label("aw_end")) if ($i != 6);
+		}
+	&set_label("aw_end",0);
+
+#	&mov("eax",$c);		# $c is "eax"
+
+	&function_end($name);
+	}
+
+sub bn_sub_words
+	{
+	local($name)=@_;
+
+	&function_begin($name,"");
+
+	&comment("");
+	$a="esi";
+	$b="edi";
+	$c="eax";
+	$r="ebx";
+	$tmp1="ecx";
+	$tmp2="edx";
+	$num="ebp";
+
+	&mov($r,&wparam(0));	# get r
+	 &mov($a,&wparam(1));	# get a
+	&mov($b,&wparam(2));	# get b
+	 &mov($num,&wparam(3));	# get num
+	&xor($c,$c);		# clear carry
+	 &and($num,0xfffffff8);	# num / 8
+
+	&jz(&label("aw_finish"));
+
+	&set_label("aw_loop",0);
+	for ($i=0; $i<8; $i++)
+		{
+		&comment("Round $i");
+
+		&mov($tmp1,&DWP($i*4,$a,"",0)); 	# *a
+		 &mov($tmp2,&DWP($i*4,$b,"",0)); 	# *b
+		&sub($tmp1,$c);
+		 &mov($c,0);
+		&adc($c,$c);
+		 &sub($tmp1,$tmp2);
+		&adc($c,0);
+		 &mov(&DWP($i*4,$r,"",0),$tmp1); 	# *r
+		}
+
+	&comment("");
+	&add($a,32);
+	 &add($b,32);
+	&add($r,32);
+	 &sub($num,8);
+	&jnz(&label("aw_loop"));
+
+	&set_label("aw_finish",0);
+	&mov($num,&wparam(3));	# get num
+	&and($num,7);
+	 &jz(&label("aw_end"));
+
+	for ($i=0; $i<7; $i++)
+		{
+		&comment("Tail Round $i");
+		&mov($tmp1,&DWP($i*4,$a,"",0));	# *a
+		 &mov($tmp2,&DWP($i*4,$b,"",0));# *b
+		&sub($tmp1,$c);
+		 &mov($c,0);
+		&adc($c,$c);
+		 &sub($tmp1,$tmp2);
+		&adc($c,0);
+		 &dec($num) if ($i != 6);
+		&mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
+		 &jz(&label("aw_end")) if ($i != 6);
+		}
+	&set_label("aw_end",0);
+
+#	&mov("eax",$c);		# $c is "eax"
+
+	&function_end($name);
+	}
+
+sub bn_sub_part_words
+	{
+	local($name)=@_;
+
+	&function_begin($name,"");
+
+	&comment("");
+	$a="esi";
+	$b="edi";
+	$c="eax";
+	$r="ebx";
+	$tmp1="ecx";
+	$tmp2="edx";
+	$num="ebp";
+
+	&mov($r,&wparam(0));	# get r
+	 &mov($a,&wparam(1));	# get a
+	&mov($b,&wparam(2));	# get b
+	 &mov($num,&wparam(3));	# get num
+	&xor($c,$c);		# clear carry
+	 &and($num,0xfffffff8);	# num / 8
+
+	&jz(&label("aw_finish"));
+
+	&set_label("aw_loop",0);
+	for ($i=0; $i<8; $i++)
+		{
+		&comment("Round $i");
+
+		&mov($tmp1,&DWP($i*4,$a,"",0)); 	# *a
+		 &mov($tmp2,&DWP($i*4,$b,"",0)); 	# *b
+		&sub($tmp1,$c);
+		 &mov($c,0);
+		&adc($c,$c);
+		 &sub($tmp1,$tmp2);
+		&adc($c,0);
+		 &mov(&DWP($i*4,$r,"",0),$tmp1); 	# *r
+		}
+
+	&comment("");
+	&add($a,32);
+	 &add($b,32);
+	&add($r,32);
+	 &sub($num,8);
+	&jnz(&label("aw_loop"));
+
+	&set_label("aw_finish",0);
+	&mov($num,&wparam(3));	# get num
+	&and($num,7);
+	 &jz(&label("aw_end"));
+
+	for ($i=0; $i<7; $i++)
+		{
+		&comment("Tail Round $i");
+		&mov($tmp1,&DWP(0,$a,"",0));	# *a
+		 &mov($tmp2,&DWP(0,$b,"",0));# *b
+		&sub($tmp1,$c);
+		 &mov($c,0);
+		&adc($c,$c);
+		 &sub($tmp1,$tmp2);
+		&adc($c,0);
+		&mov(&DWP(0,$r,"",0),$tmp1);	# *r
+		&add($a, 4);
+		&add($b, 4);
+		&add($r, 4);
+		 &dec($num) if ($i != 6);
+		 &jz(&label("aw_end")) if ($i != 6);
+		}
+	&set_label("aw_end",0);
+
+	&cmp(&wparam(4),0);
+	&je(&label("pw_end"));
+
+	&mov($num,&wparam(4));	# get dl
+	&cmp($num,0);
+	&je(&label("pw_end"));
+	&jge(&label("pw_pos"));
+
+	&comment("pw_neg");
+	&mov($tmp2,0);
+	&sub($tmp2,$num);
+	&mov($num,$tmp2);
+	&and($num,0xfffffff8);	# num / 8
+	&jz(&label("pw_neg_finish"));
+
+	&set_label("pw_neg_loop",0);
+	for ($i=0; $i<8; $i++)
+	{
+	    &comment("dl<0 Round $i");
+
+	    &mov($tmp1,0);
+	    &mov($tmp2,&DWP($i*4,$b,"",0)); 	# *b
+	    &sub($tmp1,$c);
+	    &mov($c,0);
+	    &adc($c,$c);
+	    &sub($tmp1,$tmp2);
+	    &adc($c,0);
+	    &mov(&DWP($i*4,$r,"",0),$tmp1); 	# *r
+	}
+	    
+	&comment("");
+	&add($b,32);
+	&add($r,32);
+	&sub($num,8);
+	&jnz(&label("pw_neg_loop"));
+	    
+	&set_label("pw_neg_finish",0);
+	&mov($tmp2,&wparam(4));	# get dl
+	&mov($num,0);
+	&sub($num,$tmp2);
+	&and($num,7);
+	&jz(&label("pw_end"));
+	    
+	for ($i=0; $i<7; $i++)
+	{
+	    &comment("dl<0 Tail Round $i");
+	    &mov($tmp1,0);
+	    &mov($tmp2,&DWP($i*4,$b,"",0));# *b
+	    &sub($tmp1,$c);
+	    &mov($c,0);
+	    &adc($c,$c);
+	    &sub($tmp1,$tmp2);
+	    &adc($c,0);
+	    &dec($num) if ($i != 6);
+	    &mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
+	    &jz(&label("pw_end")) if ($i != 6);
+	}
+
+	&jmp(&label("pw_end"));
+	
+	&set_label("pw_pos",0);
+	
+	&and($num,0xfffffff8);	# num / 8
+	&jz(&label("pw_pos_finish"));
+
+	&set_label("pw_pos_loop",0);
+
+	for ($i=0; $i<8; $i++)
+	{
+	    &comment("dl>0 Round $i");
+
+	    &mov($tmp1,&DWP($i*4,$a,"",0));	# *a
+	    &sub($tmp1,$c);
+	    &mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
+	    &jnc(&label("pw_nc".$i));
+	}
+	    
+	&comment("");
+	&add($a,32);
+	&add($r,32);
+	&sub($num,8);
+	&jnz(&label("pw_pos_loop"));
+	    
+	&set_label("pw_pos_finish",0);
+	&mov($num,&wparam(4));	# get dl
+	&and($num,7);
+	&jz(&label("pw_end"));
+	    
+	for ($i=0; $i<7; $i++)
+	{
+	    &comment("dl>0 Tail Round $i");
+	    &mov($tmp1,&DWP($i*4,$a,"",0));	# *a
+	    &sub($tmp1,$c);
+	    &mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
+	    &jnc(&label("pw_tail_nc".$i));
+	    &dec($num) if ($i != 6);
+	    &jz(&label("pw_end")) if ($i != 6);
+	}
+	&mov($c,1);
+	&jmp(&label("pw_end"));
+
+	&set_label("pw_nc_loop",0);
+	for ($i=0; $i<8; $i++)
+	{
+	    &mov($tmp1,&DWP($i*4,$a,"",0));	# *a
+	    &mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
+	    &set_label("pw_nc".$i,0);
+	}
+	    
+	&comment("");
+	&add($a,32);
+	&add($r,32);
+	&sub($num,8);
+	&jnz(&label("pw_nc_loop"));
+	    
+	&mov($num,&wparam(4));	# get dl
+	&and($num,7);
+	&jz(&label("pw_nc_end"));
+	    
+	for ($i=0; $i<7; $i++)
+	{
+	    &mov($tmp1,&DWP($i*4,$a,"",0));	# *a
+	    &mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
+	    &set_label("pw_tail_nc".$i,0);
+	    &dec($num) if ($i != 6);
+	    &jz(&label("pw_nc_end")) if ($i != 6);
+	}
+
+	&set_label("pw_nc_end",0);
+	&mov($c,0);
+
+	&set_label("pw_end",0);
+
+#	&mov("eax",$c);		# $c is "eax"
+
+	&function_end($name);
+	}
+
diff --git a/openssl/crypto/bn/asm/co-586.pl b/openssl/crypto/bn/asm/co-586.pl
new file mode 100644
index 0000000..57101a6
--- /dev/null
+++ b/openssl/crypto/bn/asm/co-586.pl
@@ -0,0 +1,287 @@
+#!/usr/local/bin/perl
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],$0);
+
+&bn_mul_comba("bn_mul_comba8",8);
+&bn_mul_comba("bn_mul_comba4",4);
+&bn_sqr_comba("bn_sqr_comba8",8);
+&bn_sqr_comba("bn_sqr_comba4",4);
+
+&asm_finish();
+
+sub mul_add_c
+	{
+	local($a,$ai,$b,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
+
+	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
+	# words, and 1 if load return value
+
+	&comment("mul a[$ai]*b[$bi]");
+
+	# "eax" and "edx" will always be pre-loaded.
+	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
+	# &mov("edx",&DWP($bi*4,$b,"",0));
+
+	&mul("edx");
+	&add($c0,"eax");
+	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# laod next a
+	 &mov("eax",&wparam(0)) if $pos > 0;			# load r[]
+	 ###
+	&adc($c1,"edx");
+	 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 0;	# laod next b
+	 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1;	# laod next b
+	 ###
+	&adc($c2,0);
+	 # is pos > 1, it means it is the last loop 
+	 &mov(&DWP($i*4,"eax","",0),$c0) if $pos > 0;		# save r[];
+	&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;		# laod next a
+	}
+
+sub sqr_add_c
+	{
+	local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
+
+	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
+	# words, and 1 if load return value
+
+	&comment("sqr a[$ai]*a[$bi]");
+
+	# "eax" and "edx" will always be pre-loaded.
+	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
+	# &mov("edx",&DWP($bi*4,$b,"",0));
+
+	if ($ai == $bi)
+		{ &mul("eax");}
+	else
+		{ &mul("edx");}
+	&add($c0,"eax");
+	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# load next a
+	 ###
+	&adc($c1,"edx");
+	 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos == 1) && ($na != $nb);
+	 ###
+	&adc($c2,0);
+	 # is pos > 1, it means it is the last loop 
+	 &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0;		# save r[];
+	&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;		# load next b
+	}
+
+sub sqr_add_c2
+	{
+	local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
+
+	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
+	# words, and 1 if load return value
+
+	&comment("sqr a[$ai]*a[$bi]");
+
+	# "eax" and "edx" will always be pre-loaded.
+	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
+	# &mov("edx",&DWP($bi*4,$a,"",0));
+
+	if ($ai == $bi)
+		{ &mul("eax");}
+	else
+		{ &mul("edx");}
+	&add("eax","eax");
+	 ###
+	&adc("edx","edx");
+	 ###
+	&adc($c2,0);
+	 &add($c0,"eax");
+	&adc($c1,"edx");
+	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# load next a
+	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;	# load next b
+	&adc($c2,0);
+	&mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0;		# save r[];
+	 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos <= 1) && ($na != $nb);
+	 ###
+	}
+
+sub bn_mul_comba
+	{
+	local($name,$num)=@_;
+	local($a,$b,$c0,$c1,$c2);
+	local($i,$as,$ae,$bs,$be,$ai,$bi);
+	local($tot,$end);
+
+	&function_begin_B($name,"");
+
+	$c0="ebx";
+	$c1="ecx";
+	$c2="ebp";
+	$a="esi";
+	$b="edi";
+	
+	$as=0;
+	$ae=0;
+	$bs=0;
+	$be=0;
+	$tot=$num+$num-1;
+
+	&push("esi");
+	 &mov($a,&wparam(1));
+	&push("edi");
+	 &mov($b,&wparam(2));
+	&push("ebp");
+	 &push("ebx");
+
+	&xor($c0,$c0);
+	 &mov("eax",&DWP(0,$a,"",0));	# load the first word 
+	&xor($c1,$c1);
+	 &mov("edx",&DWP(0,$b,"",0));	# load the first second 
+
+	for ($i=0; $i<$tot; $i++)
+		{
+		$ai=$as;
+		$bi=$bs;
+		$end=$be+1;
+
+		&comment("################## Calculate word $i"); 
+
+		for ($j=$bs; $j<$end; $j++)
+			{
+			&xor($c2,$c2) if ($j == $bs);
+			if (($j+1) == $end)
+				{
+				$v=1;
+				$v=2 if (($i+1) == $tot);
+				}
+			else
+				{ $v=0; }
+			if (($j+1) != $end)
+				{
+				$na=($ai-1);
+				$nb=($bi+1);
+				}
+			else
+				{
+				$na=$as+($i < ($num-1));
+				$nb=$bs+($i >= ($num-1));
+				}
+#printf STDERR "[$ai,$bi] -> [$na,$nb]\n";
+			&mul_add_c($a,$ai,$b,$bi,$c0,$c1,$c2,$v,$i,$na,$nb);
+			if ($v)
+				{
+				&comment("saved r[$i]");
+				# &mov("eax",&wparam(0));
+				# &mov(&DWP($i*4,"eax","",0),$c0);
+				($c0,$c1,$c2)=($c1,$c2,$c0);
+				}
+			$ai--;
+			$bi++;
+			}
+		$as++ if ($i < ($num-1));
+		$ae++ if ($i >= ($num-1));
+
+		$bs++ if ($i >= ($num-1));
+		$be++ if ($i < ($num-1));
+		}
+	&comment("save r[$i]");
+	# &mov("eax",&wparam(0));
+	&mov(&DWP($i*4,"eax","",0),$c0);
+
+	&pop("ebx");
+	&pop("ebp");
+	&pop("edi");
+	&pop("esi");
+	&ret();
+	&function_end_B($name);
+	}
+
+sub bn_sqr_comba
+	{
+	local($name,$num)=@_;
+	local($r,$a,$c0,$c1,$c2)=@_;
+	local($i,$as,$ae,$bs,$be,$ai,$bi);
+	local($b,$tot,$end,$half);
+
+	&function_begin_B($name,"");
+
+	$c0="ebx";
+	$c1="ecx";
+	$c2="ebp";
+	$a="esi";
+	$r="edi";
+
+	&push("esi");
+	 &push("edi");
+	&push("ebp");
+	 &push("ebx");
+	&mov($r,&wparam(0));
+	 &mov($a,&wparam(1));
+	&xor($c0,$c0);
+	 &xor($c1,$c1);
+	&mov("eax",&DWP(0,$a,"",0)); # load the first word
+
+	$as=0;
+	$ae=0;
+	$bs=0;
+	$be=0;
+	$tot=$num+$num-1;
+
+	for ($i=0; $i<$tot; $i++)
+		{
+		$ai=$as;
+		$bi=$bs;
+		$end=$be+1;
+
+		&comment("############### Calculate word $i");
+		for ($j=$bs; $j<$end; $j++)
+			{
+			&xor($c2,$c2) if ($j == $bs);
+			if (($ai-1) < ($bi+1))
+				{
+				$v=1;
+				$v=2 if ($i+1) == $tot;
+				}
+			else
+				{ $v=0; }
+			if (!$v)
+				{
+				$na=$ai-1;
+				$nb=$bi+1;
+				}
+			else
+				{
+				$na=$as+($i < ($num-1));
+				$nb=$bs+($i >= ($num-1));
+				}
+			if ($ai == $bi)
+				{
+				&sqr_add_c($r,$a,$ai,$bi,
+					$c0,$c1,$c2,$v,$i,$na,$nb);
+				}
+			else
+				{
+				&sqr_add_c2($r,$a,$ai,$bi,
+					$c0,$c1,$c2,$v,$i,$na,$nb);
+				}
+			if ($v)
+				{
+				&comment("saved r[$i]");
+				#&mov(&DWP($i*4,$r,"",0),$c0);
+				($c0,$c1,$c2)=($c1,$c2,$c0);
+				last;
+				}
+			$ai--;
+			$bi++;
+			}
+		$as++ if ($i < ($num-1));
+		$ae++ if ($i >= ($num-1));
+
+		$bs++ if ($i >= ($num-1));
+		$be++ if ($i < ($num-1));
+		}
+	&mov(&DWP($i*4,$r,"",0),$c0);
+	&pop("ebx");
+	&pop("ebp");
+	&pop("edi");
+	&pop("esi");
+	&ret();
+	&function_end_B($name);
+	}
diff --git a/openssl/crypto/bn/asm/ia64.S b/openssl/crypto/bn/asm/ia64.S
new file mode 100644
index 0000000..951abc5
--- /dev/null
+++ b/openssl/crypto/bn/asm/ia64.S
@@ -0,0 +1,1555 @@
+.explicit
+.text
+.ident	"ia64.S, Version 2.1"
+.ident	"IA-64 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
+
+//
+// ====================================================================
+// Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+// project.
+//
+// Rights for redistribution and usage in source and binary forms are
+// granted according to the OpenSSL license. Warranty of any kind is
+// disclaimed.
+// ====================================================================
+//
+// Version 2.x is Itanium2 re-tune. Few words about how Itanum2 is
+// different from Itanium to this module viewpoint. Most notably, is it
+// "wider" than Itanium? Can you experience loop scalability as
+// discussed in commentary sections? Not really:-( Itanium2 has 6
+// integer ALU ports, i.e. it's 2 ports wider, but it's not enough to
+// spin twice as fast, as I need 8 IALU ports. Amount of floating point
+// ports is the same, i.e. 2, while I need 4. In other words, to this
+// module Itanium2 remains effectively as "wide" as Itanium. Yet it's
+// essentially different in respect to this module, and a re-tune was
+// required. Well, because some intruction latencies has changed. Most
+// noticeably those intensively used:
+//
+//			Itanium	Itanium2
+//	ldf8		9	6		L2 hit
+//	ld8		2	1		L1 hit
+//	getf		2	5
+//	xma[->getf]	7[+1]	4[+0]
+//	add[->st8]	1[+1]	1[+0]
+//
+// What does it mean? You might ratiocinate that the original code
+// should run just faster... Because sum of latencies is smaller...
+// Wrong! Note that getf latency increased. This means that if a loop is
+// scheduled for lower latency (as they were), then it will suffer from
+// stall condition and the code will therefore turn anti-scalable, e.g.
+// original bn_mul_words spun at 5*n or 2.5 times slower than expected
+// on Itanium2! What to do? Reschedule loops for Itanium2? But then
+// Itanium would exhibit anti-scalability. So I've chosen to reschedule
+// for worst latency for every instruction aiming for best *all-round*
+// performance.  
+
+// Q.	How much faster does it get?
+// A.	Here is the output from 'openssl speed rsa dsa' for vanilla
+//	0.9.6a compiled with gcc version 2.96 20000731 (Red Hat
+//	Linux 7.1 2.96-81):
+//
+//	                  sign    verify    sign/s verify/s
+//	rsa  512 bits   0.0036s   0.0003s    275.3   2999.2
+//	rsa 1024 bits   0.0203s   0.0011s     49.3    894.1
+//	rsa 2048 bits   0.1331s   0.0040s      7.5    250.9
+//	rsa 4096 bits   0.9270s   0.0147s      1.1     68.1
+//	                  sign    verify    sign/s verify/s
+//	dsa  512 bits   0.0035s   0.0043s    288.3    234.8
+//	dsa 1024 bits   0.0111s   0.0135s     90.0     74.2
+//
+//	And here is similar output but for this assembler
+//	implementation:-)
+//
+//	                  sign    verify    sign/s verify/s
+//	rsa  512 bits   0.0021s   0.0001s    549.4   9638.5
+//	rsa 1024 bits   0.0055s   0.0002s    183.8   4481.1
+//	rsa 2048 bits   0.0244s   0.0006s     41.4   1726.3
+//	rsa 4096 bits   0.1295s   0.0018s      7.7    561.5
+//	                  sign    verify    sign/s verify/s
+//	dsa  512 bits   0.0012s   0.0013s    891.9    756.6
+//	dsa 1024 bits   0.0023s   0.0028s    440.4    376.2
+//	
+//	Yes, you may argue that it's not fair comparison as it's
+//	possible to craft the C implementation with BN_UMULT_HIGH
+//	inline assembler macro. But of course! Here is the output
+//	with the macro:
+//
+//	                  sign    verify    sign/s verify/s
+//	rsa  512 bits   0.0020s   0.0002s    495.0   6561.0
+//	rsa 1024 bits   0.0086s   0.0004s    116.2   2235.7
+//	rsa 2048 bits   0.0519s   0.0015s     19.3    667.3
+//	rsa 4096 bits   0.3464s   0.0053s      2.9    187.7
+//	                  sign    verify    sign/s verify/s
+//	dsa  512 bits   0.0016s   0.0020s    613.1    510.5
+//	dsa 1024 bits   0.0045s   0.0054s    221.0    183.9
+//
+//	My code is still way faster, huh:-) And I believe that even
+//	higher performance can be achieved. Note that as keys get
+//	longer, performance gain is larger. Why? According to the
+//	profiler there is another player in the field, namely
+//	BN_from_montgomery consuming larger and larger portion of CPU
+//	time as keysize decreases. I therefore consider putting effort
+//	to assembler implementation of the following routine:
+//
+//	void bn_mul_add_mont (BN_ULONG *rp,BN_ULONG *np,int nl,BN_ULONG n0)
+//	{
+//	int      i,j;
+//	BN_ULONG v;
+//
+//	for (i=0; i<nl; i++)
+//		{
+//		v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
+//		nrp++;
+//		rp++;
+//		if (((nrp[-1]+=v)&BN_MASK2) < v)
+//			for (j=0; ((++nrp[j])&BN_MASK2) == 0; j++) ;
+//		}
+//	}
+//
+//	It might as well be beneficial to implement even combaX
+//	variants, as it appears as it can literally unleash the
+//	performance (see comment section to bn_mul_comba8 below).
+//
+//	And finally for your reference the output for 0.9.6a compiled
+//	with SGIcc version 0.01.0-12 (keep in mind that for the moment
+//	of this writing it's not possible to convince SGIcc to use
+//	BN_UMULT_HIGH inline assembler macro, yet the code is fast,
+//	i.e. for a compiler generated one:-):
+//
+//	                  sign    verify    sign/s verify/s
+//	rsa  512 bits   0.0022s   0.0002s    452.7   5894.3
+//	rsa 1024 bits   0.0097s   0.0005s    102.7   2002.9
+//	rsa 2048 bits   0.0578s   0.0017s     17.3    600.2
+//	rsa 4096 bits   0.3838s   0.0061s      2.6    164.5
+//	                  sign    verify    sign/s verify/s
+//	dsa  512 bits   0.0018s   0.0022s    547.3    459.6
+//	dsa 1024 bits   0.0051s   0.0062s    196.6    161.3
+//
+//	Oh! Benchmarks were performed on 733MHz Lion-class Itanium
+//	system running Redhat Linux 7.1 (very special thanks to Ray
+//	McCaffity of Williams Communications for providing an account).
+//
+// Q.	What's the heck with 'rum 1<<5' at the end of every function?
+// A.	Well, by clearing the "upper FP registers written" bit of the
+//	User Mask I want to excuse the kernel from preserving upper
+//	(f32-f128) FP register bank over process context switch, thus
+//	minimizing bus bandwidth consumption during the switch (i.e.
+//	after PKI opration completes and the program is off doing
+//	something else like bulk symmetric encryption). Having said
+//	this, I also want to point out that it might be good idea
+//	to compile the whole toolkit (as well as majority of the
+//	programs for that matter) with -mfixed-range=f32-f127 command
+//	line option. No, it doesn't prevent the compiler from writing
+//	to upper bank, but at least discourages to do so. If you don't
+//	like the idea you have the option to compile the module with
+//	-Drum=nop.m in command line.
+//
+
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+#define	ADDP	addp4
+#else
+#define	ADDP	add
+#endif
+
+#if 1
+//
+// bn_[add|sub]_words routines.
+//
+// Loops are spinning in 2*(n+5) ticks on Itanuim (provided that the
+// data reside in L1 cache, i.e. 2 ticks away). It's possible to
+// compress the epilogue and get down to 2*n+6, but at the cost of
+// scalability (the neat feature of this implementation is that it
+// shall automagically spin in n+5 on "wider" IA-64 implementations:-)
+// I consider that the epilogue is short enough as it is to trade tiny
+// performance loss on Itanium for scalability.
+//
+// BN_ULONG bn_add_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num)
+//
+.global	bn_add_words#
+.proc	bn_add_words#
+.align	64
+.skip	32	// makes the loop body aligned at 64-byte boundary
+bn_add_words:
+	.prologue
+	.save	ar.pfs,r2
+{ .mii;	alloc		r2=ar.pfs,4,12,0,16
+	cmp4.le		p6,p0=r35,r0	};;
+{ .mfb;	mov		r8=r0			// return value
+(p6)	br.ret.spnt.many	b0	};;
+
+{ .mib;	sub		r10=r35,r0,1
+	.save	ar.lc,r3
+	mov		r3=ar.lc
+	brp.loop.imp	.L_bn_add_words_ctop,.L_bn_add_words_cend-16
+					}
+{ .mib;	ADDP		r14=0,r32		// rp
+	.save	pr,r9
+	mov		r9=pr		};;
+	.body
+{ .mii;	ADDP		r15=0,r33		// ap
+	mov		ar.lc=r10
+	mov		ar.ec=6		}
+{ .mib;	ADDP		r16=0,r34		// bp
+	mov		pr.rot=1<<16	};;
+
+.L_bn_add_words_ctop:
+{ .mii;	(p16)	ld8		r32=[r16],8	  // b=*(bp++)
+	(p18)	add		r39=r37,r34
+	(p19)	cmp.ltu.unc	p56,p0=r40,r38	}
+{ .mfb;	(p0)	nop.m		0x0
+	(p0)	nop.f		0x0
+	(p0)	nop.b		0x0		}
+{ .mii;	(p16)	ld8		r35=[r15],8	  // a=*(ap++)
+	(p58)	cmp.eq.or	p57,p0=-1,r41	  // (p20)
+	(p58)	add		r41=1,r41	} // (p20)
+{ .mfb;	(p21)	st8		[r14]=r42,8	  // *(rp++)=r
+	(p0)	nop.f		0x0
+	br.ctop.sptk	.L_bn_add_words_ctop	};;
+.L_bn_add_words_cend:
+
+{ .mii;
+(p59)	add		r8=1,r8		// return value
+	mov		pr=r9,0x1ffff
+	mov		ar.lc=r3	}
+{ .mbb;	nop.b		0x0
+	br.ret.sptk.many	b0	};;
+.endp	bn_add_words#
+
+//
+// BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num)
+//
+.global	bn_sub_words#
+.proc	bn_sub_words#
+.align	64
+.skip	32	// makes the loop body aligned at 64-byte boundary
+bn_sub_words:
+	.prologue
+	.save	ar.pfs,r2
+{ .mii;	alloc		r2=ar.pfs,4,12,0,16
+	cmp4.le		p6,p0=r35,r0	};;
+{ .mfb;	mov		r8=r0			// return value
+(p6)	br.ret.spnt.many	b0	};;
+
+{ .mib;	sub		r10=r35,r0,1
+	.save	ar.lc,r3
+	mov		r3=ar.lc
+	brp.loop.imp	.L_bn_sub_words_ctop,.L_bn_sub_words_cend-16
+					}
+{ .mib;	ADDP		r14=0,r32		// rp
+	.save	pr,r9
+	mov		r9=pr		};;
+	.body
+{ .mii;	ADDP		r15=0,r33		// ap
+	mov		ar.lc=r10
+	mov		ar.ec=6		}
+{ .mib;	ADDP		r16=0,r34		// bp
+	mov		pr.rot=1<<16	};;
+
+.L_bn_sub_words_ctop:
+{ .mii;	(p16)	ld8		r32=[r16],8	  // b=*(bp++)
+	(p18)	sub		r39=r37,r34
+	(p19)	cmp.gtu.unc	p56,p0=r40,r38	}
+{ .mfb;	(p0)	nop.m		0x0
+	(p0)	nop.f		0x0
+	(p0)	nop.b		0x0		}
+{ .mii;	(p16)	ld8		r35=[r15],8	  // a=*(ap++)
+	(p58)	cmp.eq.or	p57,p0=0,r41	  // (p20)
+	(p58)	add		r41=-1,r41	} // (p20)
+{ .mbb;	(p21)	st8		[r14]=r42,8	  // *(rp++)=r
+	(p0)	nop.b		0x0
+	br.ctop.sptk	.L_bn_sub_words_ctop	};;
+.L_bn_sub_words_cend:
+
+{ .mii;
+(p59)	add		r8=1,r8		// return value
+	mov		pr=r9,0x1ffff
+	mov		ar.lc=r3	}
+{ .mbb;	nop.b		0x0
+	br.ret.sptk.many	b0	};;
+.endp	bn_sub_words#
+#endif
+
+#if 0
+#define XMA_TEMPTATION
+#endif
+
+#if 1
+//
+// BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+//
+.global	bn_mul_words#
+.proc	bn_mul_words#
+.align	64
+.skip	32	// makes the loop body aligned at 64-byte boundary
+bn_mul_words:
+	.prologue
+	.save	ar.pfs,r2
+#ifdef XMA_TEMPTATION
+{ .mfi;	alloc		r2=ar.pfs,4,0,0,0	};;
+#else
+{ .mfi;	alloc		r2=ar.pfs,4,12,0,16	};;
+#endif
+{ .mib;	mov		r8=r0			// return value
+	cmp4.le		p6,p0=r34,r0
+(p6)	br.ret.spnt.many	b0		};;
+
+{ .mii;	sub	r10=r34,r0,1
+	.save	ar.lc,r3
+	mov	r3=ar.lc
+	.save	pr,r9
+	mov	r9=pr			};;
+
+	.body
+{ .mib;	setf.sig	f8=r35	// w
+	mov		pr.rot=0x800001<<16
+			// ------^----- serves as (p50) at first (p27)
+	brp.loop.imp	.L_bn_mul_words_ctop,.L_bn_mul_words_cend-16
+					}
+
+#ifndef XMA_TEMPTATION
+
+{ .mmi;	ADDP		r14=0,r32	// rp
+	ADDP		r15=0,r33	// ap
+	mov		ar.lc=r10	}
+{ .mmi;	mov		r40=0		// serves as r35 at first (p27)
+	mov		ar.ec=13	};;
+
+// This loop spins in 2*(n+12) ticks. It's scheduled for data in Itanium
+// L2 cache (i.e. 9 ticks away) as floating point load/store instructions
+// bypass L1 cache and L2 latency is actually best-case scenario for
+// ldf8. The loop is not scalable and shall run in 2*(n+12) even on
+// "wider" IA-64 implementations. It's a trade-off here. n+24 loop
+// would give us ~5% in *overall* performance improvement on "wider"
+// IA-64, but would hurt Itanium for about same because of longer
+// epilogue. As it's a matter of few percents in either case I've
+// chosen to trade the scalability for development time (you can see
+// this very instruction sequence in bn_mul_add_words loop which in
+// turn is scalable).
+.L_bn_mul_words_ctop:
+{ .mfi;	(p25)	getf.sig	r36=f52			// low
+	(p21)	xmpy.lu		f48=f37,f8
+	(p28)	cmp.ltu		p54,p50=r41,r39	}
+{ .mfi;	(p16)	ldf8		f32=[r15],8
+	(p21)	xmpy.hu		f40=f37,f8
+	(p0)	nop.i		0x0		};;
+{ .mii;	(p25)	getf.sig	r32=f44			// high
+	.pred.rel	"mutex",p50,p54
+	(p50)	add		r40=r38,r35		// (p27)
+	(p54)	add		r40=r38,r35,1	}	// (p27)
+{ .mfb;	(p28)	st8		[r14]=r41,8
+	(p0)	nop.f		0x0
+	br.ctop.sptk	.L_bn_mul_words_ctop	};;
+.L_bn_mul_words_cend:
+
+{ .mii;	nop.m		0x0
+.pred.rel	"mutex",p51,p55
+(p51)	add		r8=r36,r0
+(p55)	add		r8=r36,r0,1	}
+{ .mfb;	nop.m	0x0
+	nop.f	0x0
+	nop.b	0x0			}
+
+#else	// XMA_TEMPTATION
+
+	setf.sig	f37=r0	// serves as carry at (p18) tick
+	mov		ar.lc=r10
+	mov		ar.ec=5;;
+
+// Most of you examining this code very likely wonder why in the name
+// of Intel the following loop is commented out? Indeed, it looks so
+// neat that you find it hard to believe that it's something wrong
+// with it, right? The catch is that every iteration depends on the
+// result from previous one and the latter isn't available instantly.
+// The loop therefore spins at the latency of xma minus 1, or in other
+// words at 6*(n+4) ticks:-( Compare to the "production" loop above
+// that runs in 2*(n+11) where the low latency problem is worked around
+// by moving the dependency to one-tick latent interger ALU. Note that
+// "distance" between ldf8 and xma is not latency of ldf8, but the
+// *difference* between xma and ldf8 latencies.
+.L_bn_mul_words_ctop:
+{ .mfi;	(p16)	ldf8		f32=[r33],8
+	(p18)	xma.hu		f38=f34,f8,f39	}
+{ .mfb;	(p20)	stf8		[r32]=f37,8
+	(p18)	xma.lu		f35=f34,f8,f39
+	br.ctop.sptk	.L_bn_mul_words_ctop	};;
+.L_bn_mul_words_cend:
+
+	getf.sig	r8=f41		// the return value
+
+#endif	// XMA_TEMPTATION
+
+{ .mii;	nop.m		0x0
+	mov		pr=r9,0x1ffff
+	mov		ar.lc=r3	}
+{ .mfb;	rum		1<<5		// clear um.mfh
+	nop.f		0x0
+	br.ret.sptk.many	b0	};;
+.endp	bn_mul_words#
+#endif
+
+#if 1
+//
+// BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+//
+.global	bn_mul_add_words#
+.proc	bn_mul_add_words#
+.align	64
+.skip	48	// makes the loop body aligned at 64-byte boundary
+bn_mul_add_words:
+	.prologue
+	.save	ar.pfs,r2
+{ .mmi;	alloc		r2=ar.pfs,4,4,0,8
+	cmp4.le		p6,p0=r34,r0
+	.save	ar.lc,r3
+	mov		r3=ar.lc	};;
+{ .mib;	mov		r8=r0		// return value
+	sub		r10=r34,r0,1
+(p6)	br.ret.spnt.many	b0	};;
+
+{ .mib;	setf.sig	f8=r35		// w
+	.save	pr,r9
+	mov		r9=pr
+	brp.loop.imp	.L_bn_mul_add_words_ctop,.L_bn_mul_add_words_cend-16
+					}
+	.body
+{ .mmi;	ADDP		r14=0,r32	// rp
+	ADDP		r15=0,r33	// ap
+	mov		ar.lc=r10	}
+{ .mii;	ADDP		r16=0,r32	// rp copy
+	mov		pr.rot=0x2001<<16
+			// ------^----- serves as (p40) at first (p27)
+	mov		ar.ec=11	};;
+
+// This loop spins in 3*(n+10) ticks on Itanium and in 2*(n+10) on
+// Itanium 2. Yes, unlike previous versions it scales:-) Previous
+// version was peforming *all* additions in IALU and was starving
+// for those even on Itanium 2. In this version one addition is
+// moved to FPU and is folded with multiplication. This is at cost
+// of propogating the result from previous call to this subroutine
+// to L2 cache... In other words negligible even for shorter keys.
+// *Overall* performance improvement [over previous version] varies
+// from 11 to 22 percent depending on key length.
+.L_bn_mul_add_words_ctop:
+.pred.rel	"mutex",p40,p42
+{ .mfi;	(p23)	getf.sig	r36=f45			// low
+	(p20)	xma.lu		f42=f36,f8,f50		// low
+	(p40)	add		r39=r39,r35	}	// (p27)
+{ .mfi;	(p16)	ldf8		f32=[r15],8		// *(ap++)
+	(p20)	xma.hu		f36=f36,f8,f50		// high
+	(p42)	add		r39=r39,r35,1	};;	// (p27)
+{ .mmi;	(p24)	getf.sig	r32=f40			// high
+	(p16)	ldf8		f46=[r16],8		// *(rp1++)
+	(p40)	cmp.ltu		p41,p39=r39,r35	}	// (p27)
+{ .mib;	(p26)	st8		[r14]=r39,8		// *(rp2++)
+	(p42)	cmp.leu		p41,p39=r39,r35		// (p27)
+	br.ctop.sptk	.L_bn_mul_add_words_ctop};;
+.L_bn_mul_add_words_cend:
+
+{ .mmi;	.pred.rel	"mutex",p40,p42
+(p40)	add		r8=r35,r0
+(p42)	add		r8=r35,r0,1
+	mov		pr=r9,0x1ffff	}
+{ .mib;	rum		1<<5		// clear um.mfh
+	mov		ar.lc=r3
+	br.ret.sptk.many	b0	};;
+.endp	bn_mul_add_words#
+#endif
+
+#if 1
+//
+// void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num)
+//
+.global	bn_sqr_words#
+.proc	bn_sqr_words#
+.align	64
+.skip	32	// makes the loop body aligned at 64-byte boundary 
+bn_sqr_words:
+	.prologue
+	.save	ar.pfs,r2
+{ .mii;	alloc		r2=ar.pfs,3,0,0,0
+	sxt4		r34=r34		};;
+{ .mii;	cmp.le		p6,p0=r34,r0
+	mov		r8=r0		}	// return value
+{ .mfb;	ADDP		r32=0,r32
+	nop.f		0x0
+(p6)	br.ret.spnt.many	b0	};;
+
+{ .mii;	sub	r10=r34,r0,1
+	.save	ar.lc,r3
+	mov	r3=ar.lc
+	.save	pr,r9
+	mov	r9=pr			};;
+
+	.body
+{ .mib;	ADDP		r33=0,r33
+	mov		pr.rot=1<<16
+	brp.loop.imp	.L_bn_sqr_words_ctop,.L_bn_sqr_words_cend-16
+					}
+{ .mii;	add		r34=8,r32
+	mov		ar.lc=r10
+	mov		ar.ec=18	};;
+
+// 2*(n+17) on Itanium, (n+17) on "wider" IA-64 implementations. It's
+// possible to compress the epilogue (I'm getting tired to write this
+// comment over and over) and get down to 2*n+16 at the cost of
+// scalability. The decision will very likely be reconsidered after the
+// benchmark program is profiled. I.e. if perfomance gain on Itanium
+// will appear larger than loss on "wider" IA-64, then the loop should
+// be explicitely split and the epilogue compressed.
+.L_bn_sqr_words_ctop:
+{ .mfi;	(p16)	ldf8		f32=[r33],8
+	(p25)	xmpy.lu		f42=f41,f41
+	(p0)	nop.i		0x0		}
+{ .mib;	(p33)	stf8		[r32]=f50,16
+	(p0)	nop.i		0x0
+	(p0)	nop.b		0x0		}
+{ .mfi;	(p0)	nop.m		0x0
+	(p25)	xmpy.hu		f52=f41,f41
+	(p0)	nop.i		0x0		}
+{ .mib;	(p33)	stf8		[r34]=f60,16
+	(p0)	nop.i		0x0
+	br.ctop.sptk	.L_bn_sqr_words_ctop	};;
+.L_bn_sqr_words_cend:
+
+{ .mii;	nop.m		0x0
+	mov		pr=r9,0x1ffff
+	mov		ar.lc=r3	}
+{ .mfb;	rum		1<<5		// clear um.mfh
+	nop.f		0x0
+	br.ret.sptk.many	b0	};;
+.endp	bn_sqr_words#
+#endif
+
+#if 1
+// Apparently we win nothing by implementing special bn_sqr_comba8.
+// Yes, it is possible to reduce the number of multiplications by
+// almost factor of two, but then the amount of additions would
+// increase by factor of two (as we would have to perform those
+// otherwise performed by xma ourselves). Normally we would trade
+// anyway as multiplications are way more expensive, but not this
+// time... Multiplication kernel is fully pipelined and as we drain
+// one 128-bit multiplication result per clock cycle multiplications
+// are effectively as inexpensive as additions. Special implementation
+// might become of interest for "wider" IA-64 implementation as you'll
+// be able to get through the multiplication phase faster (there won't
+// be any stall issues as discussed in the commentary section below and
+// you therefore will be able to employ all 4 FP units)... But these
+// Itanium days it's simply too hard to justify the effort so I just
+// drop down to bn_mul_comba8 code:-)
+//
+// void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
+//
+.global	bn_sqr_comba8#
+.proc	bn_sqr_comba8#
+.align	64
+bn_sqr_comba8:
+	.prologue
+	.save	ar.pfs,r2
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+{ .mii;	alloc	r2=ar.pfs,2,1,0,0
+	addp4	r33=0,r33
+	addp4	r32=0,r32		};;
+{ .mii;
+#else
+{ .mii;	alloc	r2=ar.pfs,2,1,0,0
+#endif
+	mov	r34=r33
+	add	r14=8,r33		};;
+	.body
+{ .mii;	add	r17=8,r34
+	add	r15=16,r33
+	add	r18=16,r34		}
+{ .mfb;	add	r16=24,r33
+	br	.L_cheat_entry_point8	};;
+.endp	bn_sqr_comba8#
+#endif
+
+#if 1
+// I've estimated this routine to run in ~120 ticks, but in reality
+// (i.e. according to ar.itc) it takes ~160 ticks. Are those extra
+// cycles consumed for instructions fetch? Or did I misinterpret some
+// clause in Itanium µ-architecture manual? Comments are welcomed and
+// highly appreciated.
+//
+// On Itanium 2 it takes ~190 ticks. This is because of stalls on
+// result from getf.sig. I do nothing about it at this point for
+// reasons depicted below.
+//
+// However! It should be noted that even 160 ticks is darn good result
+// as it's over 10 (yes, ten, spelled as t-e-n) times faster than the
+// C version (compiled with gcc with inline assembler). I really
+// kicked compiler's butt here, didn't I? Yeah! This brings us to the
+// following statement. It's damn shame that this routine isn't called
+// very often nowadays! According to the profiler most CPU time is
+// consumed by bn_mul_add_words called from BN_from_montgomery. In
+// order to estimate what we're missing, I've compared the performance
+// of this routine against "traditional" implementation, i.e. against
+// following routine:
+//
+// void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+// {	r[ 8]=bn_mul_words(    &(r[0]),a,8,b[0]);
+//	r[ 9]=bn_mul_add_words(&(r[1]),a,8,b[1]);
+//	r[10]=bn_mul_add_words(&(r[2]),a,8,b[2]);
+//	r[11]=bn_mul_add_words(&(r[3]),a,8,b[3]);
+//	r[12]=bn_mul_add_words(&(r[4]),a,8,b[4]);
+//	r[13]=bn_mul_add_words(&(r[5]),a,8,b[5]);
+//	r[14]=bn_mul_add_words(&(r[6]),a,8,b[6]);
+//	r[15]=bn_mul_add_words(&(r[7]),a,8,b[7]);
+// }
+//
+// The one below is over 8 times faster than the one above:-( Even
+// more reasons to "combafy" bn_mul_add_mont...
+//
+// And yes, this routine really made me wish there were an optimizing
+// assembler! It also feels like it deserves a dedication.
+//
+//	To my wife for being there and to my kids...
+//
+// void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+//
+#define	carry1	r14
+#define	carry2	r15
+#define	carry3	r34
+.global	bn_mul_comba8#
+.proc	bn_mul_comba8#
+.align	64
+bn_mul_comba8:
+	.prologue
+	.save	ar.pfs,r2
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+{ .mii;	alloc	r2=ar.pfs,3,0,0,0
+	addp4	r33=0,r33
+	addp4	r34=0,r34		};;
+{ .mii;	addp4	r32=0,r32
+#else
+{ .mii;	alloc   r2=ar.pfs,3,0,0,0
+#endif
+	add	r14=8,r33
+	add	r17=8,r34		}
+	.body
+{ .mii;	add	r15=16,r33
+	add	r18=16,r34
+	add	r16=24,r33		}
+.L_cheat_entry_point8:
+{ .mmi;	add	r19=24,r34
+
+	ldf8	f32=[r33],32		};;
+
+{ .mmi;	ldf8	f120=[r34],32
+	ldf8	f121=[r17],32		}
+{ .mmi;	ldf8	f122=[r18],32
+	ldf8	f123=[r19],32		};;
+{ .mmi;	ldf8	f124=[r34]
+	ldf8	f125=[r17]		}
+{ .mmi;	ldf8	f126=[r18]
+	ldf8	f127=[r19]		}
+
+{ .mmi;	ldf8	f33=[r14],32
+	ldf8	f34=[r15],32		}
+{ .mmi;	ldf8	f35=[r16],32;;
+	ldf8	f36=[r33]		}
+{ .mmi;	ldf8	f37=[r14]
+	ldf8	f38=[r15]		}
+{ .mfi;	ldf8	f39=[r16]
+// -------\ Entering multiplier's heaven /-------
+// ------------\                    /------------
+// -----------------\          /-----------------
+// ----------------------\/----------------------
+		xma.hu	f41=f32,f120,f0		}
+{ .mfi;		xma.lu	f40=f32,f120,f0		};; // (*)
+{ .mfi;		xma.hu	f51=f32,f121,f0		}
+{ .mfi;		xma.lu	f50=f32,f121,f0		};;
+{ .mfi;		xma.hu	f61=f32,f122,f0		}
+{ .mfi;		xma.lu	f60=f32,f122,f0		};;
+{ .mfi;		xma.hu	f71=f32,f123,f0		}
+{ .mfi;		xma.lu	f70=f32,f123,f0		};;
+{ .mfi;		xma.hu	f81=f32,f124,f0		}
+{ .mfi;		xma.lu	f80=f32,f124,f0		};;
+{ .mfi;		xma.hu	f91=f32,f125,f0		}
+{ .mfi;		xma.lu	f90=f32,f125,f0		};;
+{ .mfi;		xma.hu	f101=f32,f126,f0	}
+{ .mfi;		xma.lu	f100=f32,f126,f0	};;
+{ .mfi;		xma.hu	f111=f32,f127,f0	}
+{ .mfi;		xma.lu	f110=f32,f127,f0	};;//
+// (*)	You can argue that splitting at every second bundle would
+//	prevent "wider" IA-64 implementations from achieving the peak
+//	performance. Well, not really... The catch is that if you
+//	intend to keep 4 FP units busy by splitting at every fourth
+//	bundle and thus perform these 16 multiplications in 4 ticks,
+//	the first bundle *below* would stall because the result from
+//	the first xma bundle *above* won't be available for another 3
+//	ticks (if not more, being an optimist, I assume that "wider"
+//	implementation will have same latency:-). This stall will hold
+//	you back and the performance would be as if every second bundle
+//	were split *anyway*...
+{ .mfi;	getf.sig	r16=f40
+		xma.hu	f42=f33,f120,f41
+	add		r33=8,r32		}
+{ .mfi;		xma.lu	f41=f33,f120,f41	};;
+{ .mfi;	getf.sig	r24=f50
+		xma.hu	f52=f33,f121,f51	}
+{ .mfi;		xma.lu	f51=f33,f121,f51	};;
+{ .mfi;	st8		[r32]=r16,16
+		xma.hu	f62=f33,f122,f61	}
+{ .mfi;		xma.lu	f61=f33,f122,f61	};;
+{ .mfi;		xma.hu	f72=f33,f123,f71	}
+{ .mfi;		xma.lu	f71=f33,f123,f71	};;
+{ .mfi;		xma.hu	f82=f33,f124,f81	}
+{ .mfi;		xma.lu	f81=f33,f124,f81	};;
+{ .mfi;		xma.hu	f92=f33,f125,f91	}
+{ .mfi;		xma.lu	f91=f33,f125,f91	};;
+{ .mfi;		xma.hu	f102=f33,f126,f101	}
+{ .mfi;		xma.lu	f101=f33,f126,f101	};;
+{ .mfi;		xma.hu	f112=f33,f127,f111	}
+{ .mfi;		xma.lu	f111=f33,f127,f111	};;//
+//-------------------------------------------------//
+{ .mfi;	getf.sig	r25=f41
+		xma.hu	f43=f34,f120,f42	}
+{ .mfi;		xma.lu	f42=f34,f120,f42	};;
+{ .mfi;	getf.sig	r16=f60
+		xma.hu	f53=f34,f121,f52	}
+{ .mfi;		xma.lu	f52=f34,f121,f52	};;
+{ .mfi;	getf.sig	r17=f51
+		xma.hu	f63=f34,f122,f62
+	add		r25=r25,r24		}
+{ .mfi;		xma.lu	f62=f34,f122,f62
+	mov		carry1=0		};;
+{ .mfi;	cmp.ltu		p6,p0=r25,r24
+		xma.hu	f73=f34,f123,f72	}
+{ .mfi;		xma.lu	f72=f34,f123,f72	};;
+{ .mfi;	st8		[r33]=r25,16
+		xma.hu	f83=f34,f124,f82
+(p6)	add		carry1=1,carry1		}
+{ .mfi;		xma.lu	f82=f34,f124,f82	};;
+{ .mfi;		xma.hu	f93=f34,f125,f92	}
+{ .mfi;		xma.lu	f92=f34,f125,f92	};;
+{ .mfi;		xma.hu	f103=f34,f126,f102	}
+{ .mfi;		xma.lu	f102=f34,f126,f102	};;
+{ .mfi;		xma.hu	f113=f34,f127,f112	}
+{ .mfi;		xma.lu	f112=f34,f127,f112	};;//
+//-------------------------------------------------//
+{ .mfi;	getf.sig	r18=f42
+		xma.hu	f44=f35,f120,f43
+	add		r17=r17,r16		}
+{ .mfi;		xma.lu	f43=f35,f120,f43	};;
+{ .mfi;	getf.sig	r24=f70
+		xma.hu	f54=f35,f121,f53	}
+{ .mfi;	mov		carry2=0
+		xma.lu	f53=f35,f121,f53	};;
+{ .mfi;	getf.sig	r25=f61
+		xma.hu	f64=f35,f122,f63
+	cmp.ltu		p7,p0=r17,r16		}
+{ .mfi;	add		r18=r18,r17
+		xma.lu	f63=f35,f122,f63	};;
+{ .mfi;	getf.sig	r26=f52
+		xma.hu	f74=f35,f123,f73
+(p7)	add		carry2=1,carry2		}
+{ .mfi;	cmp.ltu		p7,p0=r18,r17
+		xma.lu	f73=f35,f123,f73
+	add		r18=r18,carry1		};;
+{ .mfi;
+		xma.hu	f84=f35,f124,f83
+(p7)	add		carry2=1,carry2		}
+{ .mfi;	cmp.ltu		p7,p0=r18,carry1
+		xma.lu	f83=f35,f124,f83	};;
+{ .mfi;	st8		[r32]=r18,16
+		xma.hu	f94=f35,f125,f93
+(p7)	add		carry2=1,carry2		}
+{ .mfi;		xma.lu	f93=f35,f125,f93	};;
+{ .mfi;		xma.hu	f104=f35,f126,f103	}
+{ .mfi;		xma.lu	f103=f35,f126,f103	};;
+{ .mfi;		xma.hu	f114=f35,f127,f113	}
+{ .mfi;	mov		carry1=0
+		xma.lu	f113=f35,f127,f113
+	add		r25=r25,r24		};;//
+//-------------------------------------------------//
+{ .mfi;	getf.sig	r27=f43
+		xma.hu	f45=f36,f120,f44
+	cmp.ltu		p6,p0=r25,r24		}
+{ .mfi;		xma.lu	f44=f36,f120,f44	
+	add		r26=r26,r25		};;
+{ .mfi;	getf.sig	r16=f80
+		xma.hu	f55=f36,f121,f54
+(p6)	add		carry1=1,carry1		}
+{ .mfi;		xma.lu	f54=f36,f121,f54	};;
+{ .mfi;	getf.sig	r17=f71
+		xma.hu	f65=f36,f122,f64
+	cmp.ltu		p6,p0=r26,r25		}
+{ .mfi;		xma.lu	f64=f36,f122,f64
+	add		r27=r27,r26		};;
+{ .mfi;	getf.sig	r18=f62
+		xma.hu	f75=f36,f123,f74
+(p6)	add		carry1=1,carry1		}
+{ .mfi;	cmp.ltu		p6,p0=r27,r26
+		xma.lu	f74=f36,f123,f74
+	add		r27=r27,carry2		};;
+{ .mfi;	getf.sig	r19=f53
+		xma.hu	f85=f36,f124,f84
+(p6)	add		carry1=1,carry1		}
+{ .mfi;		xma.lu	f84=f36,f124,f84
+	cmp.ltu		p6,p0=r27,carry2	};;
+{ .mfi;	st8		[r33]=r27,16
+		xma.hu	f95=f36,f125,f94
+(p6)	add		carry1=1,carry1		}
+{ .mfi;		xma.lu	f94=f36,f125,f94	};;
+{ .mfi;		xma.hu	f105=f36,f126,f104	}
+{ .mfi;	mov		carry2=0
+		xma.lu	f104=f36,f126,f104
+	add		r17=r17,r16		};;
+{ .mfi;		xma.hu	f115=f36,f127,f114
+	cmp.ltu		p7,p0=r17,r16		}
+{ .mfi;		xma.lu	f114=f36,f127,f114
+	add		r18=r18,r17		};;//
+//-------------------------------------------------//
+{ .mfi;	getf.sig	r20=f44
+		xma.hu	f46=f37,f120,f45
+(p7)	add		carry2=1,carry2		}
+{ .mfi;	cmp.ltu		p7,p0=r18,r17
+		xma.lu	f45=f37,f120,f45
+	add		r19=r19,r18		};;
+{ .mfi;	getf.sig	r24=f90
+		xma.hu	f56=f37,f121,f55	}
+{ .mfi;		xma.lu	f55=f37,f121,f55	};;
+{ .mfi;	getf.sig	r25=f81
+		xma.hu	f66=f37,f122,f65
+(p7)	add		carry2=1,carry2		}
+{ .mfi;	cmp.ltu		p7,p0=r19,r18
+		xma.lu	f65=f37,f122,f65
+	add		r20=r20,r19		};;
+{ .mfi;	getf.sig	r26=f72
+		xma.hu	f76=f37,f123,f75
+(p7)	add		carry2=1,carry2		}
+{ .mfi;	cmp.ltu		p7,p0=r20,r19
+		xma.lu	f75=f37,f123,f75
+	add		r20=r20,carry1		};;
+{ .mfi;	getf.sig	r27=f63
+		xma.hu	f86=f37,f124,f85
+(p7)	add		carry2=1,carry2		}
+{ .mfi;		xma.lu	f85=f37,f124,f85
+	cmp.ltu		p7,p0=r20,carry1	};;
+{ .mfi;	getf.sig	r28=f54
+		xma.hu	f96=f37,f125,f95
+(p7)	add		carry2=1,carry2		}
+{ .mfi;	st8		[r32]=r20,16
+		xma.lu	f95=f37,f125,f95	};;
+{ .mfi;		xma.hu	f106=f37,f126,f105	}
+{ .mfi;	mov		carry1=0
+		xma.lu	f105=f37,f126,f105
+	add		r25=r25,r24		};;
+{ .mfi;		xma.hu	f116=f37,f127,f115
+	cmp.ltu		p6,p0=r25,r24		}
+{ .mfi;		xma.lu	f115=f37,f127,f115
+	add		r26=r26,r25		};;//
+//-------------------------------------------------//
+{ .mfi;	getf.sig	r29=f45
+		xma.hu	f47=f38,f120,f46
+(p6)	add		carry1=1,carry1		}
+{ .mfi;	cmp.ltu		p6,p0=r26,r25
+		xma.lu	f46=f38,f120,f46
+	add		r27=r27,r26		};;
+{ .mfi;	getf.sig	r16=f100
+		xma.hu	f57=f38,f121,f56
+(p6)	add		carry1=1,carry1		}
+{ .mfi;	cmp.ltu		p6,p0=r27,r26
+		xma.lu	f56=f38,f121,f56
+	add		r28=r28,r27		};;
+{ .mfi;	getf.sig	r17=f91
+		xma.hu	f67=f38,f122,f66
+(p6)	add		carry1=1,carry1		}
+{ .mfi;	cmp.ltu		p6,p0=r28,r27
+		xma.lu	f66=f38,f122,f66
+	add		r29=r29,r28		};;
+{ .mfi;	getf.sig	r18=f82
+		xma.hu	f77=f38,f123,f76
+(p6)	add		carry1=1,carry1		}
+{ .mfi;	cmp.ltu		p6,p0=r29,r28
+		xma.lu	f76=f38,f123,f76
+	add		r29=r29,carry2		};;
+{ .mfi;	getf.sig	r19=f73
+		xma.hu	f87=f38,f124,f86
+(p6)	add		carry1=1,carry1		}
+{ .mfi;		xma.lu	f86=f38,f124,f86
+	cmp.ltu		p6,p0=r29,carry2	};;
+{ .mfi;	getf.sig	r20=f64
+		xma.hu	f97=f38,f125,f96
+(p6)	add		carry1=1,carry1		}
+{ .mfi;	st8		[r33]=r29,16
+		xma.lu	f96=f38,f125,f96	};;
+{ .mfi;	getf.sig	r21=f55
+		xma.hu	f107=f38,f126,f106	}
+{ .mfi;	mov		carry2=0
+		xma.lu	f106=f38,f126,f106
+	add		r17=r17,r16		};;
+{ .mfi;		xma.hu	f117=f38,f127,f116
+	cmp.ltu		p7,p0=r17,r16		}
+{ .mfi;		xma.lu	f116=f38,f127,f116
+	add		r18=r18,r17		};;//
+//-------------------------------------------------//
+{ .mfi;	getf.sig	r22=f46
+		xma.hu	f48=f39,f120,f47
+(p7)	add		carry2=1,carry2		}
+{ .mfi;	cmp.ltu		p7,p0=r18,r17
+		xma.lu	f47=f39,f120,f47
+	add		r19=r19,r18		};;
+{ .mfi;	getf.sig	r24=f110
+		xma.hu	f58=f39,f121,f57
+(p7)	add		carry2=1,carry2		}
+{ .mfi;	cmp.ltu		p7,p0=r19,r18
+		xma.lu	f57=f39,f121,f57
+	add		r20=r20,r19		};;
+{ .mfi;	getf.sig	r25=f101
+		xma.hu	f68=f39,f122,f67
+(p7)	add		carry2=1,carry2		}
+{ .mfi;	cmp.ltu		p7,p0=r20,r19
+		xma.lu	f67=f39,f122,f67
+	add		r21=r21,r20		};;
+{ .mfi;	getf.sig	r26=f92
+		xma.hu	f78=f39,f123,f77
+(p7)	add		carry2=1,carry2		}
+{ .mfi;	cmp.ltu		p7,p0=r21,r20
+		xma.lu	f77=f39,f123,f77
+	add		r22=r22,r21		};;
+{ .mfi;	getf.sig	r27=f83
+		xma.hu	f88=f39,f124,f87
+(p7)	add		carry2=1,carry2		}
+{ .mfi;	cmp.ltu		p7,p0=r22,r21
+		xma.lu	f87=f39,f124,f87
+	add		r22=r22,carry1		};;
+{ .mfi;	getf.sig	r28=f74
+		xma.hu	f98=f39,f125,f97
+(p7)	add		carry2=1,carry2		}
+{ .mfi;		xma.lu	f97=f39,f125,f97
+	cmp.ltu		p7,p0=r22,carry1	};;
+{ .mfi;	getf.sig	r29=f65
+		xma.hu	f108=f39,f126,f107
+(p7)	add		carry2=1,carry2		}
+{ .mfi;	st8		[r32]=r22,16
+		xma.lu	f107=f39,f126,f107	};;
+{ .mfi;	getf.sig	r30=f56
+		xma.hu	f118=f39,f127,f117	}
+{ .mfi;		xma.lu	f117=f39,f127,f117	};;//
+//-------------------------------------------------//
+// Leaving muliplier's heaven... Quite a ride, huh?
+
+{ .mii;	getf.sig	r31=f47
+	add		r25=r25,r24
+	mov		carry1=0		};;
+{ .mii;		getf.sig	r16=f111
+	cmp.ltu		p6,p0=r25,r24
+	add		r26=r26,r25		};;
+{ .mfb;		getf.sig	r17=f102	}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r26,r25
+	add		r27=r27,r26		};;
+{ .mfb;	nop.m	0x0				}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r27,r26
+	add		r28=r28,r27		};;
+{ .mii;		getf.sig	r18=f93
+		add		r17=r17,r16
+		mov		carry3=0	}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r28,r27
+	add		r29=r29,r28		};;
+{ .mii;		getf.sig	r19=f84
+		cmp.ltu		p7,p0=r17,r16	}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r29,r28
+	add		r30=r30,r29		};;
+{ .mii;		getf.sig	r20=f75
+		add		r18=r18,r17	}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r30,r29
+	add		r31=r31,r30		};;
+{ .mfb;		getf.sig	r21=f66		}
+{ .mii;	(p7)	add		carry3=1,carry3
+		cmp.ltu		p7,p0=r18,r17
+		add		r19=r19,r18	}
+{ .mfb;	nop.m	0x0				}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r31,r30
+	add		r31=r31,carry2		};;
+{ .mfb;		getf.sig	r22=f57		}
+{ .mii;	(p7)	add		carry3=1,carry3
+		cmp.ltu		p7,p0=r19,r18
+		add		r20=r20,r19	}
+{ .mfb;	nop.m	0x0				}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r31,carry2	};;
+{ .mfb;		getf.sig	r23=f48		}
+{ .mii;	(p7)	add		carry3=1,carry3
+		cmp.ltu		p7,p0=r20,r19
+		add		r21=r21,r20	}
+{ .mii;
+(p6)	add		carry1=1,carry1		}
+{ .mfb;	st8		[r33]=r31,16		};;
+
+{ .mfb;	getf.sig	r24=f112		}
+{ .mii;	(p7)	add		carry3=1,carry3
+		cmp.ltu		p7,p0=r21,r20
+		add		r22=r22,r21	};;
+{ .mfb;	getf.sig	r25=f103		}
+{ .mii;	(p7)	add		carry3=1,carry3
+		cmp.ltu		p7,p0=r22,r21
+		add		r23=r23,r22	};;
+{ .mfb;	getf.sig	r26=f94			}
+{ .mii;	(p7)	add		carry3=1,carry3
+		cmp.ltu		p7,p0=r23,r22
+		add		r23=r23,carry1	};;
+{ .mfb;	getf.sig	r27=f85			}
+{ .mii;	(p7)	add		carry3=1,carry3
+		cmp.ltu		p7,p8=r23,carry1};;
+{ .mii;	getf.sig	r28=f76
+	add		r25=r25,r24
+	mov		carry1=0		}
+{ .mii;		st8		[r32]=r23,16
+	(p7)	add		carry2=1,carry3
+	(p8)	add		carry2=0,carry3	};;
+
+{ .mfb;	nop.m	0x0				}
+{ .mii;	getf.sig	r29=f67
+	cmp.ltu		p6,p0=r25,r24
+	add		r26=r26,r25		};;
+{ .mfb;	getf.sig	r30=f58			}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r26,r25
+	add		r27=r27,r26		};;
+{ .mfb;		getf.sig	r16=f113	}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r27,r26
+	add		r28=r28,r27		};;
+{ .mfb;		getf.sig	r17=f104	}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r28,r27
+	add		r29=r29,r28		};;
+{ .mfb;		getf.sig	r18=f95		}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r29,r28
+	add		r30=r30,r29		};;
+{ .mii;		getf.sig	r19=f86
+		add		r17=r17,r16
+		mov		carry3=0	}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r30,r29
+	add		r30=r30,carry2		};;
+{ .mii;		getf.sig	r20=f77
+		cmp.ltu		p7,p0=r17,r16
+		add		r18=r18,r17	}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r30,carry2	};;
+{ .mfb;		getf.sig	r21=f68		}
+{ .mii;	st8		[r33]=r30,16
+(p6)	add		carry1=1,carry1		};;
+
+{ .mfb;	getf.sig	r24=f114		}
+{ .mii;	(p7)	add		carry3=1,carry3
+		cmp.ltu		p7,p0=r18,r17
+		add		r19=r19,r18	};;
+{ .mfb;	getf.sig	r25=f105		}
+{ .mii;	(p7)	add		carry3=1,carry3
+		cmp.ltu		p7,p0=r19,r18
+		add		r20=r20,r19	};;
+{ .mfb;	getf.sig	r26=f96			}
+{ .mii;	(p7)	add		carry3=1,carry3
+		cmp.ltu		p7,p0=r20,r19
+		add		r21=r21,r20	};;
+{ .mfb;	getf.sig	r27=f87			}
+{ .mii;	(p7)	add		carry3=1,carry3
+		cmp.ltu		p7,p0=r21,r20
+		add		r21=r21,carry1	};;
+{ .mib;	getf.sig	r28=f78			
+	add		r25=r25,r24		}
+{ .mib;	(p7)	add		carry3=1,carry3
+		cmp.ltu		p7,p8=r21,carry1};;
+{ .mii;		st8		[r32]=r21,16
+	(p7)	add		carry2=1,carry3
+	(p8)	add		carry2=0,carry3	}
+
+{ .mii;	mov		carry1=0
+	cmp.ltu		p6,p0=r25,r24
+	add		r26=r26,r25		};;
+{ .mfb;		getf.sig	r16=f115	}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r26,r25
+	add		r27=r27,r26		};;
+{ .mfb;		getf.sig	r17=f106	}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r27,r26
+	add		r28=r28,r27		};;
+{ .mfb;		getf.sig	r18=f97		}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r28,r27
+	add		r28=r28,carry2		};;
+{ .mib;		getf.sig	r19=f88
+		add		r17=r17,r16	}
+{ .mib;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r28,carry2	};;
+{ .mii;	st8		[r33]=r28,16
+(p6)	add		carry1=1,carry1		}
+
+{ .mii;		mov		carry2=0
+		cmp.ltu		p7,p0=r17,r16
+		add		r18=r18,r17	};;
+{ .mfb;	getf.sig	r24=f116		}
+{ .mii;	(p7)	add		carry2=1,carry2
+		cmp.ltu		p7,p0=r18,r17
+		add		r19=r19,r18	};;
+{ .mfb;	getf.sig	r25=f107		}
+{ .mii;	(p7)	add		carry2=1,carry2
+		cmp.ltu		p7,p0=r19,r18
+		add		r19=r19,carry1	};;
+{ .mfb;	getf.sig	r26=f98			}
+{ .mii;	(p7)	add		carry2=1,carry2
+		cmp.ltu		p7,p0=r19,carry1};;
+{ .mii;		st8		[r32]=r19,16
+	(p7)	add		carry2=1,carry2	}
+
+{ .mfb;	add		r25=r25,r24		};;
+
+{ .mfb;		getf.sig	r16=f117	}
+{ .mii;	mov		carry1=0
+	cmp.ltu		p6,p0=r25,r24
+	add		r26=r26,r25		};;
+{ .mfb;		getf.sig	r17=f108	}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r26,r25
+	add		r26=r26,carry2		};;
+{ .mfb;	nop.m	0x0				}
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r26,carry2	};;
+{ .mii;	st8		[r33]=r26,16
+(p6)	add		carry1=1,carry1		}
+
+{ .mfb;		add		r17=r17,r16	};;
+{ .mfb;	getf.sig	r24=f118		}
+{ .mii;		mov		carry2=0
+		cmp.ltu		p7,p0=r17,r16
+		add		r17=r17,carry1	};;
+{ .mii;	(p7)	add		carry2=1,carry2
+		cmp.ltu		p7,p0=r17,carry1};;
+{ .mii;		st8		[r32]=r17
+	(p7)	add		carry2=1,carry2	};;
+{ .mfb;	add		r24=r24,carry2		};;
+{ .mib;	st8		[r33]=r24		}
+
+{ .mib;	rum		1<<5		// clear um.mfh
+	br.ret.sptk.many	b0	};;
+.endp	bn_mul_comba8#
+#undef	carry3
+#undef	carry2
+#undef	carry1
+#endif
+
+#if 1
+// It's possible to make it faster (see comment to bn_sqr_comba8), but
+// I reckon it doesn't worth the effort. Basically because the routine
+// (actually both of them) practically never called... So I just play
+// same trick as with bn_sqr_comba8.
+//
+// void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
+//
+.global	bn_sqr_comba4#
+.proc	bn_sqr_comba4#
+.align	64
+bn_sqr_comba4:
+	.prologue
+	.save	ar.pfs,r2
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+{ .mii;	alloc   r2=ar.pfs,2,1,0,0
+	addp4	r32=0,r32
+	addp4	r33=0,r33		};;
+{ .mii;
+#else
+{ .mii;	alloc	r2=ar.pfs,2,1,0,0
+#endif
+	mov	r34=r33
+	add	r14=8,r33		};;
+	.body
+{ .mii;	add	r17=8,r34
+	add	r15=16,r33
+	add	r18=16,r34		}
+{ .mfb;	add	r16=24,r33
+	br	.L_cheat_entry_point4	};;
+.endp	bn_sqr_comba4#
+#endif
+
+#if 1
+// Runs in ~115 cycles and ~4.5 times faster than C. Well, whatever...
+//
+// void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+//
+#define	carry1	r14
+#define	carry2	r15
+.global	bn_mul_comba4#
+.proc	bn_mul_comba4#
+.align	64
+bn_mul_comba4:
+	.prologue
+	.save	ar.pfs,r2
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+{ .mii;	alloc   r2=ar.pfs,3,0,0,0
+	addp4	r33=0,r33
+	addp4	r34=0,r34		};;
+{ .mii;	addp4	r32=0,r32
+#else
+{ .mii;	alloc	r2=ar.pfs,3,0,0,0
+#endif
+	add	r14=8,r33
+	add	r17=8,r34		}
+	.body
+{ .mii;	add	r15=16,r33
+	add	r18=16,r34
+	add	r16=24,r33		};;
+.L_cheat_entry_point4:
+{ .mmi;	add	r19=24,r34
+
+	ldf8	f32=[r33]		}
+
+{ .mmi;	ldf8	f120=[r34]
+	ldf8	f121=[r17]		};;
+{ .mmi;	ldf8	f122=[r18]
+	ldf8	f123=[r19]		}
+
+{ .mmi;	ldf8	f33=[r14]
+	ldf8	f34=[r15]		}
+{ .mfi;	ldf8	f35=[r16]
+
+		xma.hu	f41=f32,f120,f0		}
+{ .mfi;		xma.lu	f40=f32,f120,f0		};;
+{ .mfi;		xma.hu	f51=f32,f121,f0		}
+{ .mfi;		xma.lu	f50=f32,f121,f0		};;
+{ .mfi;		xma.hu	f61=f32,f122,f0		}
+{ .mfi;		xma.lu	f60=f32,f122,f0		};;
+{ .mfi;		xma.hu	f71=f32,f123,f0		}
+{ .mfi;		xma.lu	f70=f32,f123,f0		};;//
+// Major stall takes place here, and 3 more places below. Result from
+// first xma is not available for another 3 ticks.
+{ .mfi;	getf.sig	r16=f40
+		xma.hu	f42=f33,f120,f41
+	add		r33=8,r32		}
+{ .mfi;		xma.lu	f41=f33,f120,f41	};;
+{ .mfi;	getf.sig	r24=f50
+		xma.hu	f52=f33,f121,f51	}
+{ .mfi;		xma.lu	f51=f33,f121,f51	};;
+{ .mfi;	st8		[r32]=r16,16
+		xma.hu	f62=f33,f122,f61	}
+{ .mfi;		xma.lu	f61=f33,f122,f61	};;
+{ .mfi;		xma.hu	f72=f33,f123,f71	}
+{ .mfi;		xma.lu	f71=f33,f123,f71	};;//
+//-------------------------------------------------//
+{ .mfi;	getf.sig	r25=f41
+		xma.hu	f43=f34,f120,f42	}
+{ .mfi;		xma.lu	f42=f34,f120,f42	};;
+{ .mfi;	getf.sig	r16=f60
+		xma.hu	f53=f34,f121,f52	}
+{ .mfi;		xma.lu	f52=f34,f121,f52	};;
+{ .mfi;	getf.sig	r17=f51
+		xma.hu	f63=f34,f122,f62
+	add		r25=r25,r24		}
+{ .mfi;	mov		carry1=0
+		xma.lu	f62=f34,f122,f62	};;
+{ .mfi;	st8		[r33]=r25,16
+		xma.hu	f73=f34,f123,f72
+	cmp.ltu		p6,p0=r25,r24		}
+{ .mfi;		xma.lu	f72=f34,f123,f72	};;//
+//-------------------------------------------------//
+{ .mfi;	getf.sig	r18=f42
+		xma.hu	f44=f35,f120,f43
+(p6)	add		carry1=1,carry1		}
+{ .mfi;	add		r17=r17,r16
+		xma.lu	f43=f35,f120,f43
+	mov		carry2=0		};;
+{ .mfi;	getf.sig	r24=f70
+		xma.hu	f54=f35,f121,f53
+	cmp.ltu		p7,p0=r17,r16		}
+{ .mfi;		xma.lu	f53=f35,f121,f53	};;
+{ .mfi;	getf.sig	r25=f61
+		xma.hu	f64=f35,f122,f63
+	add		r18=r18,r17		}
+{ .mfi;		xma.lu	f63=f35,f122,f63
+(p7)	add		carry2=1,carry2		};;
+{ .mfi;	getf.sig	r26=f52
+		xma.hu	f74=f35,f123,f73
+	cmp.ltu		p7,p0=r18,r17		}
+{ .mfi;		xma.lu	f73=f35,f123,f73
+	add		r18=r18,carry1		};;
+//-------------------------------------------------//
+{ .mii;	st8		[r32]=r18,16
+(p7)	add		carry2=1,carry2
+	cmp.ltu		p7,p0=r18,carry1	};;
+
+{ .mfi;	getf.sig	r27=f43	// last major stall
+(p7)	add		carry2=1,carry2		};;
+{ .mii;		getf.sig	r16=f71
+	add		r25=r25,r24
+	mov		carry1=0		};;
+{ .mii;		getf.sig	r17=f62	
+	cmp.ltu		p6,p0=r25,r24
+	add		r26=r26,r25		};;
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r26,r25
+	add		r27=r27,r26		};;
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r27,r26
+	add		r27=r27,carry2		};;
+{ .mii;		getf.sig	r18=f53
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r27,carry2	};;
+{ .mfi;	st8		[r33]=r27,16
+(p6)	add		carry1=1,carry1		}
+
+{ .mii;		getf.sig	r19=f44
+		add		r17=r17,r16
+		mov		carry2=0	};;
+{ .mii;	getf.sig	r24=f72
+		cmp.ltu		p7,p0=r17,r16
+		add		r18=r18,r17	};;
+{ .mii;	(p7)	add		carry2=1,carry2
+		cmp.ltu		p7,p0=r18,r17
+		add		r19=r19,r18	};;
+{ .mii;	(p7)	add		carry2=1,carry2
+		cmp.ltu		p7,p0=r19,r18
+		add		r19=r19,carry1	};;
+{ .mii;	getf.sig	r25=f63
+	(p7)	add		carry2=1,carry2
+		cmp.ltu		p7,p0=r19,carry1};;
+{ .mii;		st8		[r32]=r19,16
+	(p7)	add		carry2=1,carry2	}
+
+{ .mii;	getf.sig	r26=f54
+	add		r25=r25,r24
+	mov		carry1=0		};;
+{ .mii;		getf.sig	r16=f73
+	cmp.ltu		p6,p0=r25,r24
+	add		r26=r26,r25		};;
+{ .mii;
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r26,r25
+	add		r26=r26,carry2		};;
+{ .mii;		getf.sig	r17=f64
+(p6)	add		carry1=1,carry1
+	cmp.ltu		p6,p0=r26,carry2	};;
+{ .mii;	st8		[r33]=r26,16
+(p6)	add		carry1=1,carry1		}
+
+{ .mii;	getf.sig	r24=f74
+		add		r17=r17,r16	
+		mov		carry2=0	};;
+{ .mii;		cmp.ltu		p7,p0=r17,r16
+		add		r17=r17,carry1	};;
+
+{ .mii;	(p7)	add		carry2=1,carry2
+		cmp.ltu		p7,p0=r17,carry1};;
+{ .mii;		st8		[r32]=r17,16
+	(p7)	add		carry2=1,carry2	};;
+
+{ .mii;	add		r24=r24,carry2		};;
+{ .mii;	st8		[r33]=r24		}
+
+{ .mib;	rum		1<<5		// clear um.mfh
+	br.ret.sptk.many	b0	};;
+.endp	bn_mul_comba4#
+#undef	carry2
+#undef	carry1
+#endif
+
+#if 1
+//
+// BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+//
+// In the nutshell it's a port of my MIPS III/IV implementation.
+//
+#define	AT	r14
+#define	H	r16
+#define	HH	r20
+#define	L	r17
+#define	D	r18
+#define	DH	r22
+#define	I	r21
+
+#if 0
+// Some preprocessors (most notably HP-UX) appear to be allergic to
+// macros enclosed to parenthesis [as these three were].
+#define	cont	p16
+#define	break	p0	// p20
+#define	equ	p24
+#else
+cont=p16
+break=p0
+equ=p24
+#endif
+
+.global	abort#
+.global	bn_div_words#
+.proc	bn_div_words#
+.align	64
+bn_div_words:
+	.prologue
+	.save	ar.pfs,r2
+{ .mii;	alloc		r2=ar.pfs,3,5,0,8
+	.save	b0,r3
+	mov		r3=b0
+	.save	pr,r10
+	mov		r10=pr		};;
+{ .mmb;	cmp.eq		p6,p0=r34,r0
+	mov		r8=-1
+(p6)	br.ret.spnt.many	b0	};;
+
+	.body
+{ .mii;	mov		H=r32		// save h
+	mov		ar.ec=0		// don't rotate at exit
+	mov		pr.rot=0	}
+{ .mii;	mov		L=r33		// save l
+	mov		r36=r0		};;
+
+.L_divw_shift:	// -vv- note signed comparison
+{ .mfi;	(p0)	cmp.lt		p16,p0=r0,r34	// d
+	(p0)	shladd		r33=r34,1,r0	}
+{ .mfb;	(p0)	add		r35=1,r36
+	(p0)	nop.f		0x0
+(p16)	br.wtop.dpnt		.L_divw_shift	};;
+
+{ .mii;	mov		D=r34
+	shr.u		DH=r34,32
+	sub		r35=64,r36		};;
+{ .mii;	setf.sig	f7=DH
+	shr.u		AT=H,r35
+	mov		I=r36			};;
+{ .mib;	cmp.ne		p6,p0=r0,AT
+	shl		H=H,r36
+(p6)	br.call.spnt.clr	b0=abort	};;	// overflow, die...
+
+{ .mfi;	fcvt.xuf.s1	f7=f7
+	shr.u		AT=L,r35		};;
+{ .mii;	shl		L=L,r36
+	or		H=H,AT			};;
+
+{ .mii;	nop.m		0x0
+	cmp.leu		p6,p0=D,H;;
+(p6)	sub		H=H,D			}
+
+{ .mlx;	setf.sig	f14=D
+	movl		AT=0xffffffff		};;
+///////////////////////////////////////////////////////////
+{ .mii;	setf.sig	f6=H
+	shr.u		HH=H,32;;
+	cmp.eq		p6,p7=HH,DH		};;
+{ .mfb;
+(p6)	setf.sig	f8=AT
+(p7)	fcvt.xuf.s1	f6=f6
+(p7)	br.call.sptk	b6=.L_udiv64_32_b6	};;
+
+{ .mfi;	getf.sig	r33=f8				// q
+	xmpy.lu		f9=f8,f14		}
+{ .mfi;	xmpy.hu		f10=f8,f14
+	shrp		H=H,L,32		};;
+
+{ .mmi;	getf.sig	r35=f9				// tl
+	getf.sig	r31=f10			};;	// th
+
+.L_divw_1st_iter:
+{ .mii;	(p0)	add		r32=-1,r33
+	(p0)	cmp.eq		equ,cont=HH,r31		};;
+{ .mii;	(p0)	cmp.ltu		p8,p0=r35,D
+	(p0)	sub		r34=r35,D
+	(equ)	cmp.leu		break,cont=r35,H	};;
+{ .mib;	(cont)	cmp.leu		cont,break=HH,r31
+	(p8)	add		r31=-1,r31
+(cont)	br.wtop.spnt		.L_divw_1st_iter	};;
+///////////////////////////////////////////////////////////
+{ .mii;	sub		H=H,r35
+	shl		r8=r33,32
+	shl		L=L,32			};;
+///////////////////////////////////////////////////////////
+{ .mii;	setf.sig	f6=H
+	shr.u		HH=H,32;;
+	cmp.eq		p6,p7=HH,DH		};;
+{ .mfb;
+(p6)	setf.sig	f8=AT
+(p7)	fcvt.xuf.s1	f6=f6
+(p7)	br.call.sptk	b6=.L_udiv64_32_b6	};;
+
+{ .mfi;	getf.sig	r33=f8				// q
+	xmpy.lu		f9=f8,f14		}
+{ .mfi;	xmpy.hu		f10=f8,f14
+	shrp		H=H,L,32		};;
+
+{ .mmi;	getf.sig	r35=f9				// tl
+	getf.sig	r31=f10			};;	// th
+
+.L_divw_2nd_iter:
+{ .mii;	(p0)	add		r32=-1,r33
+	(p0)	cmp.eq		equ,cont=HH,r31		};;
+{ .mii;	(p0)	cmp.ltu		p8,p0=r35,D
+	(p0)	sub		r34=r35,D
+	(equ)	cmp.leu		break,cont=r35,H	};;
+{ .mib;	(cont)	cmp.leu		cont,break=HH,r31
+	(p8)	add		r31=-1,r31
+(cont)	br.wtop.spnt		.L_divw_2nd_iter	};;
+///////////////////////////////////////////////////////////
+{ .mii;	sub	H=H,r35
+	or	r8=r8,r33
+	mov	ar.pfs=r2		};;
+{ .mii;	shr.u	r9=H,I			// remainder if anybody wants it
+	mov	pr=r10,0x1ffff		}
+{ .mfb;	br.ret.sptk.many	b0	};;
+
+// Unsigned 64 by 32 (well, by 64 for the moment) bit integer division
+// procedure.
+//
+// inputs:	f6 = (double)a, f7 = (double)b
+// output:	f8 = (int)(a/b)
+// clobbered:	f8,f9,f10,f11,pred
+pred=p15
+// One can argue that this snippet is copyrighted to Intel
+// Corporation, as it's essentially identical to one of those
+// found in "Divide, Square Root and Remainder" section at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+// Yes, I admit that the referred code was used as template,
+// but after I realized that there hardly is any other instruction
+// sequence which would perform this operation. I mean I figure that
+// any independent attempt to implement high-performance division
+// will result in code virtually identical to the Intel code. It
+// should be noted though that below division kernel is 1 cycle
+// faster than Intel one (note commented splits:-), not to mention
+// original prologue (rather lack of one) and epilogue.
+.align	32
+.skip	16
+.L_udiv64_32_b6:
+	frcpa.s1	f8,pred=f6,f7;;		// [0]  y0 = 1 / b
+
+(pred)	fnma.s1		f9=f7,f8,f1		// [5]  e0 = 1 - b * y0
+(pred)	fmpy.s1		f10=f6,f8;;		// [5]  q0 = a * y0
+(pred)	fmpy.s1		f11=f9,f9		// [10] e1 = e0 * e0
+(pred)	fma.s1		f10=f9,f10,f10;;	// [10] q1 = q0 + e0 * q0
+(pred)	fma.s1		f8=f9,f8,f8	//;;	// [15] y1 = y0 + e0 * y0
+(pred)	fma.s1		f9=f11,f10,f10;;	// [15] q2 = q1 + e1 * q1
+(pred)	fma.s1		f8=f11,f8,f8	//;;	// [20] y2 = y1 + e1 * y1
+(pred)	fnma.s1		f10=f7,f9,f6;;		// [20] r2 = a - b * q2
+(pred)	fma.s1		f8=f10,f8,f9;;		// [25] q3 = q2 + r2 * y2
+
+	fcvt.fxu.trunc.s1	f8=f8		// [30] q = trunc(q3)
+	br.ret.sptk.many	b6;;
+.endp	bn_div_words#
+#endif
diff --git a/openssl/crypto/bn/asm/mips3-mont.pl b/openssl/crypto/bn/asm/mips3-mont.pl
new file mode 100644
index 0000000..8f9156e
--- /dev/null
+++ b/openssl/crypto/bn/asm/mips3-mont.pl
@@ -0,0 +1,327 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# This module doesn't present direct interest for OpenSSL, because it
+# doesn't provide better performance for longer keys. While 512-bit
+# RSA private key operations are 40% faster, 1024-bit ones are hardly
+# faster at all, while longer key operations are slower by up to 20%.
+# It might be of interest to embedded system developers though, as
+# it's smaller than 1KB, yet offers ~3x improvement over compiler
+# generated code.
+#
+# The module targets N32 and N64 MIPS ABIs and currently is a bit
+# IRIX-centric, i.e. is likely to require adaptation for other OSes.
+
+# int bn_mul_mont(
+$rp="a0";	# BN_ULONG *rp,
+$ap="a1";	# const BN_ULONG *ap,
+$bp="a2";	# const BN_ULONG *bp,
+$np="a3";	# const BN_ULONG *np,
+$n0="a4";	# const BN_ULONG *n0,
+$num="a5";	# int num);
+
+$lo0="a6";
+$hi0="a7";
+$lo1="v0";
+$hi1="v1";
+$aj="t0";
+$bi="t1";
+$nj="t2";
+$tp="t3";
+$alo="s0";
+$ahi="s1";
+$nlo="s2";
+$nhi="s3";
+$tj="s4";
+$i="s5";
+$j="s6";
+$fp="t8";
+$m1="t9";
+
+$FRAME=8*(2+8);
+
+$code=<<___;
+#include <asm.h>
+#include <regdef.h>
+
+.text
+
+.set	noat
+.set	reorder
+
+.align	5
+.globl	bn_mul_mont
+.ent	bn_mul_mont
+bn_mul_mont:
+	.set	noreorder
+	PTR_SUB	sp,64
+	move	$fp,sp
+	.frame	$fp,64,ra
+	slt	AT,$num,4
+	li	v0,0
+	beqzl	AT,.Lproceed
+	nop
+	jr	ra
+	PTR_ADD	sp,$fp,64
+	.set	reorder
+.align	5
+.Lproceed:
+	ld	$n0,0($n0)
+	ld	$bi,0($bp)	# bp[0]
+	ld	$aj,0($ap)	# ap[0]
+	ld	$nj,0($np)	# np[0]
+	PTR_SUB	sp,16		# place for two extra words
+	sll	$num,3
+	li	AT,-4096
+	PTR_SUB	sp,$num
+	and	sp,AT
+
+	sd	s0,0($fp)
+	sd	s1,8($fp)
+	sd	s2,16($fp)
+	sd	s3,24($fp)
+	sd	s4,32($fp)
+	sd	s5,40($fp)
+	sd	s6,48($fp)
+	sd	s7,56($fp)
+
+	dmultu	$aj,$bi
+	ld	$alo,8($ap)
+	ld	$nlo,8($np)
+	mflo	$lo0
+	mfhi	$hi0
+	dmultu	$lo0,$n0
+	mflo	$m1
+
+	dmultu	$alo,$bi
+	mflo	$alo
+	mfhi	$ahi
+
+	dmultu	$nj,$m1
+	mflo	$lo1
+	mfhi	$hi1
+	dmultu	$nlo,$m1
+	daddu	$lo1,$lo0
+	sltu	AT,$lo1,$lo0
+	daddu	$hi1,AT
+	mflo	$nlo
+	mfhi	$nhi
+
+	move	$tp,sp
+	li	$j,16
+.align	4
+.L1st:
+	.set	noreorder
+	PTR_ADD	$aj,$ap,$j
+	ld	$aj,($aj)
+	PTR_ADD	$nj,$np,$j
+	ld	$nj,($nj)
+
+	dmultu	$aj,$bi
+	daddu	$lo0,$alo,$hi0
+	daddu	$lo1,$nlo,$hi1
+	sltu	AT,$lo0,$hi0
+	sltu	s7,$lo1,$hi1
+	daddu	$hi0,$ahi,AT
+	daddu	$hi1,$nhi,s7
+	mflo	$alo
+	mfhi	$ahi
+
+	daddu	$lo1,$lo0
+	sltu	AT,$lo1,$lo0
+	dmultu	$nj,$m1
+	daddu	$hi1,AT
+	addu	$j,8
+	sd	$lo1,($tp)
+	sltu	s7,$j,$num
+	mflo	$nlo
+	mfhi	$nhi
+
+	bnez	s7,.L1st
+	PTR_ADD	$tp,8
+	.set	reorder
+
+	daddu	$lo0,$alo,$hi0
+	sltu	AT,$lo0,$hi0
+	daddu	$hi0,$ahi,AT
+
+	daddu	$lo1,$nlo,$hi1
+	sltu	s7,$lo1,$hi1
+	daddu	$hi1,$nhi,s7
+	daddu	$lo1,$lo0
+	sltu	AT,$lo1,$lo0
+	daddu	$hi1,AT
+
+	sd	$lo1,($tp)
+
+	daddu	$hi1,$hi0
+	sltu	AT,$hi1,$hi0
+	sd	$hi1,8($tp)
+	sd	AT,16($tp)
+
+	li	$i,8
+.align	4
+.Louter:
+	PTR_ADD	$bi,$bp,$i
+	ld	$bi,($bi)
+	ld	$aj,($ap)
+	ld	$alo,8($ap)
+	ld	$tj,(sp)
+
+	dmultu	$aj,$bi
+	ld	$nj,($np)
+	ld	$nlo,8($np)
+	mflo	$lo0
+	mfhi	$hi0
+	daddu	$lo0,$tj
+	dmultu	$lo0,$n0
+	sltu	AT,$lo0,$tj
+	daddu	$hi0,AT
+	mflo	$m1
+
+	dmultu	$alo,$bi
+	mflo	$alo
+	mfhi	$ahi
+
+	dmultu	$nj,$m1
+	mflo	$lo1
+	mfhi	$hi1
+
+	dmultu	$nlo,$m1
+	daddu	$lo1,$lo0
+	sltu	AT,$lo1,$lo0
+	daddu	$hi1,AT
+	mflo	$nlo
+	mfhi	$nhi
+
+	move	$tp,sp
+	li	$j,16
+	ld	$tj,8($tp)
+.align	4
+.Linner:
+	.set	noreorder
+	PTR_ADD	$aj,$ap,$j
+	ld	$aj,($aj)
+	PTR_ADD	$nj,$np,$j
+	ld	$nj,($nj)
+
+	dmultu	$aj,$bi
+	daddu	$lo0,$alo,$hi0
+	daddu	$lo1,$nlo,$hi1
+	sltu	AT,$lo0,$hi0
+	sltu	s7,$lo1,$hi1
+	daddu	$hi0,$ahi,AT
+	daddu	$hi1,$nhi,s7
+	mflo	$alo
+	mfhi	$ahi
+
+	daddu	$lo0,$tj
+	addu	$j,8
+	dmultu	$nj,$m1
+	sltu	AT,$lo0,$tj
+	daddu	$lo1,$lo0
+	daddu	$hi0,AT
+	sltu	s7,$lo1,$lo0
+	ld	$tj,16($tp)
+	daddu	$hi1,s7
+	sltu	AT,$j,$num
+	mflo	$nlo
+	mfhi	$nhi
+	sd	$lo1,($tp)
+	bnez	AT,.Linner
+	PTR_ADD	$tp,8
+	.set	reorder
+
+	daddu	$lo0,$alo,$hi0
+	sltu	AT,$lo0,$hi0
+	daddu	$hi0,$ahi,AT
+	daddu	$lo0,$tj
+	sltu	s7,$lo0,$tj
+	daddu	$hi0,s7
+
+	ld	$tj,16($tp)
+	daddu	$lo1,$nlo,$hi1
+	sltu	AT,$lo1,$hi1
+	daddu	$hi1,$nhi,AT
+	daddu	$lo1,$lo0
+	sltu	s7,$lo1,$lo0
+	daddu	$hi1,s7
+	sd	$lo1,($tp)
+
+	daddu	$lo1,$hi1,$hi0
+	sltu	$hi1,$lo1,$hi0
+	daddu	$lo1,$tj
+	sltu	AT,$lo1,$tj
+	daddu	$hi1,AT
+	sd	$lo1,8($tp)
+	sd	$hi1,16($tp)
+
+	addu	$i,8
+	sltu	s7,$i,$num
+	bnez	s7,.Louter
+
+	.set	noreorder
+	PTR_ADD	$tj,sp,$num	# &tp[num]
+	move	$tp,sp
+	move	$ap,sp
+	li	$hi0,0		# clear borrow bit
+
+.align	4
+.Lsub:	ld	$lo0,($tp)
+	ld	$lo1,($np)
+	PTR_ADD	$tp,8
+	PTR_ADD	$np,8
+	dsubu	$lo1,$lo0,$lo1	# tp[i]-np[i]
+	sgtu	AT,$lo1,$lo0
+	dsubu	$lo0,$lo1,$hi0
+	sgtu	$hi0,$lo0,$lo1
+	sd	$lo0,($rp)
+	or	$hi0,AT
+	sltu	AT,$tp,$tj
+	bnez	AT,.Lsub
+	PTR_ADD	$rp,8
+
+	dsubu	$hi0,$hi1,$hi0	# handle upmost overflow bit
+	move	$tp,sp
+	PTR_SUB	$rp,$num	# restore rp
+	not	$hi1,$hi0
+
+	and	$ap,$hi0,sp
+	and	$bp,$hi1,$rp
+	or	$ap,$ap,$bp	# ap=borrow?tp:rp
+
+.align	4
+.Lcopy:	ld	$aj,($ap)
+	PTR_ADD	$ap,8
+	PTR_ADD	$tp,8
+	sd	zero,-8($tp)
+	sltu	AT,$tp,$tj
+	sd	$aj,($rp)
+	bnez	AT,.Lcopy
+	PTR_ADD	$rp,8
+
+	ld	s0,0($fp)
+	ld	s1,8($fp)
+	ld	s2,16($fp)
+	ld	s3,24($fp)
+	ld	s4,32($fp)
+	ld	s5,40($fp)
+	ld	s6,48($fp)
+	ld	s7,56($fp)
+	li	v0,1
+	jr	ra
+	PTR_ADD	sp,$fp,64
+	.set	reorder
+END(bn_mul_mont)
+.rdata
+.asciiz	"Montgomery Multiplication for MIPS III/IV, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/bn/asm/mips3.s b/openssl/crypto/bn/asm/mips3.s
new file mode 100644
index 0000000..dca4105
--- /dev/null
+++ b/openssl/crypto/bn/asm/mips3.s
@@ -0,0 +1,2201 @@
+.rdata
+.asciiz	"mips3.s, Version 1.1"
+.asciiz	"MIPS III/IV ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
+
+/*
+ * ====================================================================
+ * Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+ * project.
+ *
+ * Rights for redistribution and usage in source and binary forms are
+ * granted according to the OpenSSL license. Warranty of any kind is
+ * disclaimed.
+ * ====================================================================
+ */
+
+/*
+ * This is my modest contributon to the OpenSSL project (see
+ * http://www.openssl.org/ for more information about it) and is
+ * a drop-in MIPS III/IV ISA replacement for crypto/bn/bn_asm.c
+ * module. For updates see http://fy.chalmers.se/~appro/hpe/.
+ *
+ * The module is designed to work with either of the "new" MIPS ABI(5),
+ * namely N32 or N64, offered by IRIX 6.x. It's not ment to work under
+ * IRIX 5.x not only because it doesn't support new ABIs but also
+ * because 5.x kernels put R4x00 CPU into 32-bit mode and all those
+ * 64-bit instructions (daddu, dmultu, etc.) found below gonna only
+ * cause illegal instruction exception:-(
+ *
+ * In addition the code depends on preprocessor flags set up by MIPSpro
+ * compiler driver (either as or cc) and therefore (probably?) can't be
+ * compiled by the GNU assembler. GNU C driver manages fine though...
+ * I mean as long as -mmips-as is specified or is the default option,
+ * because then it simply invokes /usr/bin/as which in turn takes
+ * perfect care of the preprocessor definitions. Another neat feature
+ * offered by the MIPSpro assembler is an optimization pass. This gave
+ * me the opportunity to have the code looking more regular as all those
+ * architecture dependent instruction rescheduling details were left to
+ * the assembler. Cool, huh?
+ *
+ * Performance improvement is astonishing! 'apps/openssl speed rsa dsa'
+ * goes way over 3 times faster!
+ *
+ *					<appro@fy.chalmers.se>
+ */
+#include <asm.h>
+#include <regdef.h>
+
+#if _MIPS_ISA>=4
+#define	MOVNZ(cond,dst,src)	\
+	movn	dst,src,cond
+#else
+#define	MOVNZ(cond,dst,src)	\
+	.set	noreorder;	\
+	bnezl	cond,.+8;	\
+	move	dst,src;	\
+	.set	reorder
+#endif
+
+.text
+
+.set	noat
+.set	reorder
+
+#define	MINUS4	v1
+
+.align	5
+LEAF(bn_mul_add_words)
+	.set	noreorder
+	bgtzl	a2,.L_bn_mul_add_words_proceed
+	ld	t0,0(a1)
+	jr	ra
+	move	v0,zero
+	.set	reorder
+
+.L_bn_mul_add_words_proceed:
+	li	MINUS4,-4
+	and	ta0,a2,MINUS4
+	move	v0,zero
+	beqz	ta0,.L_bn_mul_add_words_tail
+
+.L_bn_mul_add_words_loop:
+	dmultu	t0,a3
+	ld	t1,0(a0)
+	ld	t2,8(a1)
+	ld	t3,8(a0)
+	ld	ta0,16(a1)
+	ld	ta1,16(a0)
+	daddu	t1,v0
+	sltu	v0,t1,v0	/* All manuals say it "compares 32-bit
+				 * values", but it seems to work fine
+				 * even on 64-bit registers. */
+	mflo	AT
+	mfhi	t0
+	daddu	t1,AT
+	daddu	v0,t0
+	sltu	AT,t1,AT
+	sd	t1,0(a0)
+	daddu	v0,AT
+
+	dmultu	t2,a3
+	ld	ta2,24(a1)
+	ld	ta3,24(a0)
+	daddu	t3,v0
+	sltu	v0,t3,v0
+	mflo	AT
+	mfhi	t2
+	daddu	t3,AT
+	daddu	v0,t2
+	sltu	AT,t3,AT
+	sd	t3,8(a0)
+	daddu	v0,AT
+
+	dmultu	ta0,a3
+	subu	a2,4
+	PTR_ADD	a0,32
+	PTR_ADD	a1,32
+	daddu	ta1,v0
+	sltu	v0,ta1,v0
+	mflo	AT
+	mfhi	ta0
+	daddu	ta1,AT
+	daddu	v0,ta0
+	sltu	AT,ta1,AT
+	sd	ta1,-16(a0)
+	daddu	v0,AT
+
+
+	dmultu	ta2,a3
+	and	ta0,a2,MINUS4
+	daddu	ta3,v0
+	sltu	v0,ta3,v0
+	mflo	AT
+	mfhi	ta2
+	daddu	ta3,AT
+	daddu	v0,ta2
+	sltu	AT,ta3,AT
+	sd	ta3,-8(a0)
+	daddu	v0,AT
+	.set	noreorder
+	bgtzl	ta0,.L_bn_mul_add_words_loop
+	ld	t0,0(a1)
+
+	bnezl	a2,.L_bn_mul_add_words_tail
+	ld	t0,0(a1)
+	.set	reorder
+
+.L_bn_mul_add_words_return:
+	jr	ra
+
+.L_bn_mul_add_words_tail:
+	dmultu	t0,a3
+	ld	t1,0(a0)
+	subu	a2,1
+	daddu	t1,v0
+	sltu	v0,t1,v0
+	mflo	AT
+	mfhi	t0
+	daddu	t1,AT
+	daddu	v0,t0
+	sltu	AT,t1,AT
+	sd	t1,0(a0)
+	daddu	v0,AT
+	beqz	a2,.L_bn_mul_add_words_return
+
+	ld	t0,8(a1)
+	dmultu	t0,a3
+	ld	t1,8(a0)
+	subu	a2,1
+	daddu	t1,v0
+	sltu	v0,t1,v0
+	mflo	AT
+	mfhi	t0
+	daddu	t1,AT
+	daddu	v0,t0
+	sltu	AT,t1,AT
+	sd	t1,8(a0)
+	daddu	v0,AT
+	beqz	a2,.L_bn_mul_add_words_return
+
+	ld	t0,16(a1)
+	dmultu	t0,a3
+	ld	t1,16(a0)
+	daddu	t1,v0
+	sltu	v0,t1,v0
+	mflo	AT
+	mfhi	t0
+	daddu	t1,AT
+	daddu	v0,t0
+	sltu	AT,t1,AT
+	sd	t1,16(a0)
+	daddu	v0,AT
+	jr	ra
+END(bn_mul_add_words)
+
+.align	5
+LEAF(bn_mul_words)
+	.set	noreorder
+	bgtzl	a2,.L_bn_mul_words_proceed
+	ld	t0,0(a1)
+	jr	ra
+	move	v0,zero
+	.set	reorder
+
+.L_bn_mul_words_proceed:
+	li	MINUS4,-4
+	and	ta0,a2,MINUS4
+	move	v0,zero
+	beqz	ta0,.L_bn_mul_words_tail
+
+.L_bn_mul_words_loop:
+	dmultu	t0,a3
+	ld	t2,8(a1)
+	ld	ta0,16(a1)
+	ld	ta2,24(a1)
+	mflo	AT
+	mfhi	t0
+	daddu	v0,AT
+	sltu	t1,v0,AT
+	sd	v0,0(a0)
+	daddu	v0,t1,t0
+
+	dmultu	t2,a3
+	subu	a2,4
+	PTR_ADD	a0,32
+	PTR_ADD	a1,32
+	mflo	AT
+	mfhi	t2
+	daddu	v0,AT
+	sltu	t3,v0,AT
+	sd	v0,-24(a0)
+	daddu	v0,t3,t2
+
+	dmultu	ta0,a3
+	mflo	AT
+	mfhi	ta0
+	daddu	v0,AT
+	sltu	ta1,v0,AT
+	sd	v0,-16(a0)
+	daddu	v0,ta1,ta0
+
+
+	dmultu	ta2,a3
+	and	ta0,a2,MINUS4
+	mflo	AT
+	mfhi	ta2
+	daddu	v0,AT
+	sltu	ta3,v0,AT
+	sd	v0,-8(a0)
+	daddu	v0,ta3,ta2
+	.set	noreorder
+	bgtzl	ta0,.L_bn_mul_words_loop
+	ld	t0,0(a1)
+
+	bnezl	a2,.L_bn_mul_words_tail
+	ld	t0,0(a1)
+	.set	reorder
+
+.L_bn_mul_words_return:
+	jr	ra
+
+.L_bn_mul_words_tail:
+	dmultu	t0,a3
+	subu	a2,1
+	mflo	AT
+	mfhi	t0
+	daddu	v0,AT
+	sltu	t1,v0,AT
+	sd	v0,0(a0)
+	daddu	v0,t1,t0
+	beqz	a2,.L_bn_mul_words_return
+
+	ld	t0,8(a1)
+	dmultu	t0,a3
+	subu	a2,1
+	mflo	AT
+	mfhi	t0
+	daddu	v0,AT
+	sltu	t1,v0,AT
+	sd	v0,8(a0)
+	daddu	v0,t1,t0
+	beqz	a2,.L_bn_mul_words_return
+
+	ld	t0,16(a1)
+	dmultu	t0,a3
+	mflo	AT
+	mfhi	t0
+	daddu	v0,AT
+	sltu	t1,v0,AT
+	sd	v0,16(a0)
+	daddu	v0,t1,t0
+	jr	ra
+END(bn_mul_words)
+
+.align	5
+LEAF(bn_sqr_words)
+	.set	noreorder
+	bgtzl	a2,.L_bn_sqr_words_proceed
+	ld	t0,0(a1)
+	jr	ra
+	move	v0,zero
+	.set	reorder
+
+.L_bn_sqr_words_proceed:
+	li	MINUS4,-4
+	and	ta0,a2,MINUS4
+	move	v0,zero
+	beqz	ta0,.L_bn_sqr_words_tail
+
+.L_bn_sqr_words_loop:
+	dmultu	t0,t0
+	ld	t2,8(a1)
+	ld	ta0,16(a1)
+	ld	ta2,24(a1)
+	mflo	t1
+	mfhi	t0
+	sd	t1,0(a0)
+	sd	t0,8(a0)
+
+	dmultu	t2,t2
+	subu	a2,4
+	PTR_ADD	a0,64
+	PTR_ADD	a1,32
+	mflo	t3
+	mfhi	t2
+	sd	t3,-48(a0)
+	sd	t2,-40(a0)
+
+	dmultu	ta0,ta0
+	mflo	ta1
+	mfhi	ta0
+	sd	ta1,-32(a0)
+	sd	ta0,-24(a0)
+
+
+	dmultu	ta2,ta2
+	and	ta0,a2,MINUS4
+	mflo	ta3
+	mfhi	ta2
+	sd	ta3,-16(a0)
+	sd	ta2,-8(a0)
+
+	.set	noreorder
+	bgtzl	ta0,.L_bn_sqr_words_loop
+	ld	t0,0(a1)
+
+	bnezl	a2,.L_bn_sqr_words_tail
+	ld	t0,0(a1)
+	.set	reorder
+
+.L_bn_sqr_words_return:
+	move	v0,zero
+	jr	ra
+
+.L_bn_sqr_words_tail:
+	dmultu	t0,t0
+	subu	a2,1
+	mflo	t1
+	mfhi	t0
+	sd	t1,0(a0)
+	sd	t0,8(a0)
+	beqz	a2,.L_bn_sqr_words_return
+
+	ld	t0,8(a1)
+	dmultu	t0,t0
+	subu	a2,1
+	mflo	t1
+	mfhi	t0
+	sd	t1,16(a0)
+	sd	t0,24(a0)
+	beqz	a2,.L_bn_sqr_words_return
+
+	ld	t0,16(a1)
+	dmultu	t0,t0
+	mflo	t1
+	mfhi	t0
+	sd	t1,32(a0)
+	sd	t0,40(a0)
+	jr	ra
+END(bn_sqr_words)
+
+.align	5
+LEAF(bn_add_words)
+	.set	noreorder
+	bgtzl	a3,.L_bn_add_words_proceed
+	ld	t0,0(a1)
+	jr	ra
+	move	v0,zero
+	.set	reorder
+
+.L_bn_add_words_proceed:
+	li	MINUS4,-4
+	and	AT,a3,MINUS4
+	move	v0,zero
+	beqz	AT,.L_bn_add_words_tail
+
+.L_bn_add_words_loop:
+	ld	ta0,0(a2)
+	subu	a3,4
+	ld	t1,8(a1)
+	and	AT,a3,MINUS4
+	ld	t2,16(a1)
+	PTR_ADD	a2,32
+	ld	t3,24(a1)
+	PTR_ADD	a0,32
+	ld	ta1,-24(a2)
+	PTR_ADD	a1,32
+	ld	ta2,-16(a2)
+	ld	ta3,-8(a2)
+	daddu	ta0,t0
+	sltu	t8,ta0,t0
+	daddu	t0,ta0,v0
+	sltu	v0,t0,ta0
+	sd	t0,-32(a0)
+	daddu	v0,t8
+
+	daddu	ta1,t1
+	sltu	t9,ta1,t1
+	daddu	t1,ta1,v0
+	sltu	v0,t1,ta1
+	sd	t1,-24(a0)
+	daddu	v0,t9
+
+	daddu	ta2,t2
+	sltu	t8,ta2,t2
+	daddu	t2,ta2,v0
+	sltu	v0,t2,ta2
+	sd	t2,-16(a0)
+	daddu	v0,t8
+	
+	daddu	ta3,t3
+	sltu	t9,ta3,t3
+	daddu	t3,ta3,v0
+	sltu	v0,t3,ta3
+	sd	t3,-8(a0)
+	daddu	v0,t9
+	
+	.set	noreorder
+	bgtzl	AT,.L_bn_add_words_loop
+	ld	t0,0(a1)
+
+	bnezl	a3,.L_bn_add_words_tail
+	ld	t0,0(a1)
+	.set	reorder
+
+.L_bn_add_words_return:
+	jr	ra
+
+.L_bn_add_words_tail:
+	ld	ta0,0(a2)
+	daddu	ta0,t0
+	subu	a3,1
+	sltu	t8,ta0,t0
+	daddu	t0,ta0,v0
+	sltu	v0,t0,ta0
+	sd	t0,0(a0)
+	daddu	v0,t8
+	beqz	a3,.L_bn_add_words_return
+
+	ld	t1,8(a1)
+	ld	ta1,8(a2)
+	daddu	ta1,t1
+	subu	a3,1
+	sltu	t9,ta1,t1
+	daddu	t1,ta1,v0
+	sltu	v0,t1,ta1
+	sd	t1,8(a0)
+	daddu	v0,t9
+	beqz	a3,.L_bn_add_words_return
+
+	ld	t2,16(a1)
+	ld	ta2,16(a2)
+	daddu	ta2,t2
+	sltu	t8,ta2,t2
+	daddu	t2,ta2,v0
+	sltu	v0,t2,ta2
+	sd	t2,16(a0)
+	daddu	v0,t8
+	jr	ra
+END(bn_add_words)
+
+.align	5
+LEAF(bn_sub_words)
+	.set	noreorder
+	bgtzl	a3,.L_bn_sub_words_proceed
+	ld	t0,0(a1)
+	jr	ra
+	move	v0,zero
+	.set	reorder
+
+.L_bn_sub_words_proceed:
+	li	MINUS4,-4
+	and	AT,a3,MINUS4
+	move	v0,zero
+	beqz	AT,.L_bn_sub_words_tail
+
+.L_bn_sub_words_loop:
+	ld	ta0,0(a2)
+	subu	a3,4
+	ld	t1,8(a1)
+	and	AT,a3,MINUS4
+	ld	t2,16(a1)
+	PTR_ADD	a2,32
+	ld	t3,24(a1)
+	PTR_ADD	a0,32
+	ld	ta1,-24(a2)
+	PTR_ADD	a1,32
+	ld	ta2,-16(a2)
+	ld	ta3,-8(a2)
+	sltu	t8,t0,ta0
+	dsubu	t0,ta0
+	dsubu	ta0,t0,v0
+	sd	ta0,-32(a0)
+	MOVNZ	(t0,v0,t8)
+
+	sltu	t9,t1,ta1
+	dsubu	t1,ta1
+	dsubu	ta1,t1,v0
+	sd	ta1,-24(a0)
+	MOVNZ	(t1,v0,t9)
+
+
+	sltu	t8,t2,ta2
+	dsubu	t2,ta2
+	dsubu	ta2,t2,v0
+	sd	ta2,-16(a0)
+	MOVNZ	(t2,v0,t8)
+
+	sltu	t9,t3,ta3
+	dsubu	t3,ta3
+	dsubu	ta3,t3,v0
+	sd	ta3,-8(a0)
+	MOVNZ	(t3,v0,t9)
+
+	.set	noreorder
+	bgtzl	AT,.L_bn_sub_words_loop
+	ld	t0,0(a1)
+
+	bnezl	a3,.L_bn_sub_words_tail
+	ld	t0,0(a1)
+	.set	reorder
+
+.L_bn_sub_words_return:
+	jr	ra
+
+.L_bn_sub_words_tail:
+	ld	ta0,0(a2)
+	subu	a3,1
+	sltu	t8,t0,ta0
+	dsubu	t0,ta0
+	dsubu	ta0,t0,v0
+	MOVNZ	(t0,v0,t8)
+	sd	ta0,0(a0)
+	beqz	a3,.L_bn_sub_words_return
+
+	ld	t1,8(a1)
+	subu	a3,1
+	ld	ta1,8(a2)
+	sltu	t9,t1,ta1
+	dsubu	t1,ta1
+	dsubu	ta1,t1,v0
+	MOVNZ	(t1,v0,t9)
+	sd	ta1,8(a0)
+	beqz	a3,.L_bn_sub_words_return
+
+	ld	t2,16(a1)
+	ld	ta2,16(a2)
+	sltu	t8,t2,ta2
+	dsubu	t2,ta2
+	dsubu	ta2,t2,v0
+	MOVNZ	(t2,v0,t8)
+	sd	ta2,16(a0)
+	jr	ra
+END(bn_sub_words)
+
+#undef	MINUS4
+
+.align 5
+LEAF(bn_div_3_words)
+	.set	reorder
+	move	a3,a0		/* we know that bn_div_words doesn't
+				 * touch a3, ta2, ta3 and preserves a2
+				 * so that we can save two arguments
+				 * and return address in registers
+				 * instead of stack:-)
+				 */
+	ld	a0,(a3)
+	move	ta2,a1
+	ld	a1,-8(a3)
+	bne	a0,a2,.L_bn_div_3_words_proceed
+	li	v0,-1
+	jr	ra
+.L_bn_div_3_words_proceed:
+	move	ta3,ra
+	bal	bn_div_words
+	move	ra,ta3
+	dmultu	ta2,v0
+	ld	t2,-16(a3)
+	move	ta0,zero
+	mfhi	t1
+	mflo	t0
+	sltu	t8,t1,v1
+.L_bn_div_3_words_inner_loop:
+	bnez	t8,.L_bn_div_3_words_inner_loop_done
+	sgeu	AT,t2,t0
+	seq	t9,t1,v1
+	and	AT,t9
+	sltu	t3,t0,ta2
+	daddu	v1,a2
+	dsubu	t1,t3
+	dsubu	t0,ta2
+	sltu	t8,t1,v1
+	sltu	ta0,v1,a2
+	or	t8,ta0
+	.set	noreorder
+	beqzl	AT,.L_bn_div_3_words_inner_loop
+	dsubu	v0,1
+	.set	reorder
+.L_bn_div_3_words_inner_loop_done:
+	jr	ra
+END(bn_div_3_words)
+
+.align	5
+LEAF(bn_div_words)
+	.set	noreorder
+	bnezl	a2,.L_bn_div_words_proceed
+	move	v1,zero
+	jr	ra
+	li	v0,-1		/* I'd rather signal div-by-zero
+				 * which can be done with 'break 7' */
+
+.L_bn_div_words_proceed:
+	bltz	a2,.L_bn_div_words_body
+	move	t9,v1
+	dsll	a2,1
+	bgtz	a2,.-4
+	addu	t9,1
+
+	.set	reorder
+	negu	t1,t9
+	li	t2,-1
+	dsll	t2,t1
+	and	t2,a0
+	dsrl	AT,a1,t1
+	.set	noreorder
+	bnezl	t2,.+8
+	break	6		/* signal overflow */
+	.set	reorder
+	dsll	a0,t9
+	dsll	a1,t9
+	or	a0,AT
+
+#define	QT	ta0
+#define	HH	ta1
+#define	DH	v1
+.L_bn_div_words_body:
+	dsrl	DH,a2,32
+	sgeu	AT,a0,a2
+	.set	noreorder
+	bnezl	AT,.+8
+	dsubu	a0,a2
+	.set	reorder
+
+	li	QT,-1
+	dsrl	HH,a0,32
+	dsrl	QT,32	/* q=0xffffffff */
+	beq	DH,HH,.L_bn_div_words_skip_div1
+	ddivu	zero,a0,DH
+	mflo	QT
+.L_bn_div_words_skip_div1:
+	dmultu	a2,QT
+	dsll	t3,a0,32
+	dsrl	AT,a1,32
+	or	t3,AT
+	mflo	t0
+	mfhi	t1
+.L_bn_div_words_inner_loop1:
+	sltu	t2,t3,t0
+	seq	t8,HH,t1
+	sltu	AT,HH,t1
+	and	t2,t8
+	sltu	v0,t0,a2
+	or	AT,t2
+	.set	noreorder
+	beqz	AT,.L_bn_div_words_inner_loop1_done
+	dsubu	t1,v0
+	dsubu	t0,a2
+	b	.L_bn_div_words_inner_loop1
+	dsubu	QT,1
+	.set	reorder
+.L_bn_div_words_inner_loop1_done:
+
+	dsll	a1,32
+	dsubu	a0,t3,t0
+	dsll	v0,QT,32
+
+	li	QT,-1
+	dsrl	HH,a0,32
+	dsrl	QT,32	/* q=0xffffffff */
+	beq	DH,HH,.L_bn_div_words_skip_div2
+	ddivu	zero,a0,DH
+	mflo	QT
+.L_bn_div_words_skip_div2:
+#undef	DH
+	dmultu	a2,QT
+	dsll	t3,a0,32
+	dsrl	AT,a1,32
+	or	t3,AT
+	mflo	t0
+	mfhi	t1
+.L_bn_div_words_inner_loop2:
+	sltu	t2,t3,t0
+	seq	t8,HH,t1
+	sltu	AT,HH,t1
+	and	t2,t8
+	sltu	v1,t0,a2
+	or	AT,t2
+	.set	noreorder
+	beqz	AT,.L_bn_div_words_inner_loop2_done
+	dsubu	t1,v1
+	dsubu	t0,a2
+	b	.L_bn_div_words_inner_loop2
+	dsubu	QT,1
+	.set	reorder
+.L_bn_div_words_inner_loop2_done:	
+#undef	HH
+
+	dsubu	a0,t3,t0
+	or	v0,QT
+	dsrl	v1,a0,t9	/* v1 contains remainder if anybody wants it */
+	dsrl	a2,t9		/* restore a2 */
+	jr	ra
+#undef	QT
+END(bn_div_words)
+
+#define	a_0	t0
+#define	a_1	t1
+#define	a_2	t2
+#define	a_3	t3
+#define	b_0	ta0
+#define	b_1	ta1
+#define	b_2	ta2
+#define	b_3	ta3
+
+#define	a_4	s0
+#define	a_5	s2
+#define	a_6	s4
+#define	a_7	a1	/* once we load a[7] we don't need a anymore */
+#define	b_4	s1
+#define	b_5	s3
+#define	b_6	s5
+#define	b_7	a2	/* once we load b[7] we don't need b anymore */
+
+#define	t_1	t8
+#define	t_2	t9
+
+#define	c_1	v0
+#define	c_2	v1
+#define	c_3	a3
+
+#define	FRAME_SIZE	48
+
+.align	5
+LEAF(bn_mul_comba8)
+	.set	noreorder
+	PTR_SUB	sp,FRAME_SIZE
+	.frame	sp,64,ra
+	.set	reorder
+	ld	a_0,0(a1)	/* If compiled with -mips3 option on
+				 * R5000 box assembler barks on this
+				 * line with "shouldn't have mult/div
+				 * as last instruction in bb (R10K
+				 * bug)" warning. If anybody out there
+				 * has a clue about how to circumvent
+				 * this do send me a note.
+				 *		<appro@fy.chalmers.se>
+				 */
+	ld	b_0,0(a2)
+	ld	a_1,8(a1)
+	ld	a_2,16(a1)
+	ld	a_3,24(a1)
+	ld	b_1,8(a2)
+	ld	b_2,16(a2)
+	ld	b_3,24(a2)
+	dmultu	a_0,b_0		/* mul_add_c(a[0],b[0],c1,c2,c3); */
+	sd	s0,0(sp)
+	sd	s1,8(sp)
+	sd	s2,16(sp)
+	sd	s3,24(sp)
+	sd	s4,32(sp)
+	sd	s5,40(sp)
+	mflo	c_1
+	mfhi	c_2
+
+	dmultu	a_0,b_1		/* mul_add_c(a[0],b[1],c2,c3,c1); */
+	ld	a_4,32(a1)
+	ld	a_5,40(a1)
+	ld	a_6,48(a1)
+	ld	a_7,56(a1)
+	ld	b_4,32(a2)
+	ld	b_5,40(a2)
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	c_3,t_2,AT
+	dmultu	a_1,b_0		/* mul_add_c(a[1],b[0],c2,c3,c1); */
+	ld	b_6,48(a2)
+	ld	b_7,56(a2)
+	sd	c_1,0(a0)	/* r[0]=c1; */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	c_1,c_3,t_2
+	sd	c_2,8(a0)	/* r[1]=c2; */
+
+	dmultu	a_2,b_0		/* mul_add_c(a[2],b[0],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	dmultu	a_1,b_1		/* mul_add_c(a[1],b[1],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	c_2,c_1,t_2
+	dmultu	a_0,b_2		/* mul_add_c(a[0],b[2],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	sd	c_3,16(a0)	/* r[2]=c3; */
+
+	dmultu	a_0,b_3		/* mul_add_c(a[0],b[3],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	c_3,c_2,t_2
+	dmultu	a_1,b_2		/* mul_add_c(a[1],b[2],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_2,b_1		/* mul_add_c(a[2],b[1],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_3,b_0		/* mul_add_c(a[3],b[0],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	sd	c_1,24(a0)	/* r[3]=c1; */
+
+	dmultu	a_4,b_0		/* mul_add_c(a[4],b[0],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	c_1,c_3,t_2
+	dmultu	a_3,b_1		/* mul_add_c(a[3],b[1],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_2,b_2		/* mul_add_c(a[2],b[2],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_1,b_3		/* mul_add_c(a[1],b[3],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_0,b_4		/* mul_add_c(a[0],b[4],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	sd	c_2,32(a0)	/* r[4]=c2; */
+
+	dmultu	a_0,b_5		/* mul_add_c(a[0],b[5],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	c_2,c_1,t_2
+	dmultu	a_1,b_4		/* mul_add_c(a[1],b[4],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_2,b_3		/* mul_add_c(a[2],b[3],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_3,b_2		/* mul_add_c(a[3],b[2],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_4,b_1		/* mul_add_c(a[4],b[1],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_5,b_0		/* mul_add_c(a[5],b[0],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	sd	c_3,40(a0)	/* r[5]=c3; */
+
+	dmultu	a_6,b_0		/* mul_add_c(a[6],b[0],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	c_3,c_2,t_2
+	dmultu	a_5,b_1		/* mul_add_c(a[5],b[1],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_4,b_2		/* mul_add_c(a[4],b[2],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_3,b_3		/* mul_add_c(a[3],b[3],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_2,b_4		/* mul_add_c(a[2],b[4],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_1,b_5		/* mul_add_c(a[1],b[5],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_0,b_6		/* mul_add_c(a[0],b[6],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	sd	c_1,48(a0)	/* r[6]=c1; */
+
+	dmultu	a_0,b_7		/* mul_add_c(a[0],b[7],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	c_1,c_3,t_2
+	dmultu	a_1,b_6		/* mul_add_c(a[1],b[6],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_2,b_5		/* mul_add_c(a[2],b[5],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_3,b_4		/* mul_add_c(a[3],b[4],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_4,b_3		/* mul_add_c(a[4],b[3],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_5,b_2		/* mul_add_c(a[5],b[2],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_6,b_1		/* mul_add_c(a[6],b[1],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_7,b_0		/* mul_add_c(a[7],b[0],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	sd	c_2,56(a0)	/* r[7]=c2; */
+
+	dmultu	a_7,b_1		/* mul_add_c(a[7],b[1],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	c_2,c_1,t_2
+	dmultu	a_6,b_2		/* mul_add_c(a[6],b[2],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_5,b_3		/* mul_add_c(a[5],b[3],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_4,b_4		/* mul_add_c(a[4],b[4],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_3,b_5		/* mul_add_c(a[3],b[5],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_2,b_6		/* mul_add_c(a[2],b[6],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_1,b_7		/* mul_add_c(a[1],b[7],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	sd	c_3,64(a0)	/* r[8]=c3; */
+
+	dmultu	a_2,b_7		/* mul_add_c(a[2],b[7],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	c_3,c_2,t_2
+	dmultu	a_3,b_6		/* mul_add_c(a[3],b[6],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_4,b_5		/* mul_add_c(a[4],b[5],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_5,b_4		/* mul_add_c(a[5],b[4],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_6,b_3		/* mul_add_c(a[6],b[3],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_7,b_2		/* mul_add_c(a[7],b[2],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	sd	c_1,72(a0)	/* r[9]=c1; */
+
+	dmultu	a_7,b_3		/* mul_add_c(a[7],b[3],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	c_1,c_3,t_2
+	dmultu	a_6,b_4		/* mul_add_c(a[6],b[4],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_5,b_5		/* mul_add_c(a[5],b[5],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_4,b_6		/* mul_add_c(a[4],b[6],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_3,b_7		/* mul_add_c(a[3],b[7],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	sd	c_2,80(a0)	/* r[10]=c2; */
+
+	dmultu	a_4,b_7		/* mul_add_c(a[4],b[7],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	c_2,c_1,t_2
+	dmultu	a_5,b_6		/* mul_add_c(a[5],b[6],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_6,b_5		/* mul_add_c(a[6],b[5],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_7,b_4		/* mul_add_c(a[7],b[4],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	sd	c_3,88(a0)	/* r[11]=c3; */
+
+	dmultu	a_7,b_5		/* mul_add_c(a[7],b[5],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	c_3,c_2,t_2
+	dmultu	a_6,b_6		/* mul_add_c(a[6],b[6],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_5,b_7		/* mul_add_c(a[5],b[7],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	sd	c_1,96(a0)	/* r[12]=c1; */
+
+	dmultu	a_6,b_7		/* mul_add_c(a[6],b[7],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	c_1,c_3,t_2
+	dmultu	a_7,b_6		/* mul_add_c(a[7],b[6],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	sd	c_2,104(a0)	/* r[13]=c2; */
+
+	dmultu	a_7,b_7		/* mul_add_c(a[7],b[7],c3,c1,c2); */
+	ld	s0,0(sp)
+	ld	s1,8(sp)
+	ld	s2,16(sp)
+	ld	s3,24(sp)
+	ld	s4,32(sp)
+	ld	s5,40(sp)
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sd	c_3,112(a0)	/* r[14]=c3; */
+	sd	c_1,120(a0)	/* r[15]=c1; */
+
+	PTR_ADD	sp,FRAME_SIZE
+
+	jr	ra
+END(bn_mul_comba8)
+
+.align	5
+LEAF(bn_mul_comba4)
+	.set	reorder
+	ld	a_0,0(a1)
+	ld	b_0,0(a2)
+	ld	a_1,8(a1)
+	ld	a_2,16(a1)
+	dmultu	a_0,b_0		/* mul_add_c(a[0],b[0],c1,c2,c3); */
+	ld	a_3,24(a1)
+	ld	b_1,8(a2)
+	ld	b_2,16(a2)
+	ld	b_3,24(a2)
+	mflo	c_1
+	mfhi	c_2
+	sd	c_1,0(a0)
+
+	dmultu	a_0,b_1		/* mul_add_c(a[0],b[1],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	c_3,t_2,AT
+	dmultu	a_1,b_0		/* mul_add_c(a[1],b[0],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	c_1,c_3,t_2
+	sd	c_2,8(a0)
+
+	dmultu	a_2,b_0		/* mul_add_c(a[2],b[0],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	dmultu	a_1,b_1		/* mul_add_c(a[1],b[1],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	c_2,c_1,t_2
+	dmultu	a_0,b_2		/* mul_add_c(a[0],b[2],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	sd	c_3,16(a0)
+
+	dmultu	a_0,b_3		/* mul_add_c(a[0],b[3],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	c_3,c_2,t_2
+	dmultu	a_1,b_2		/* mul_add_c(a[1],b[2],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_2,b_1		/* mul_add_c(a[2],b[1],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_3,b_0		/* mul_add_c(a[3],b[0],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	sd	c_1,24(a0)
+
+	dmultu	a_3,b_1		/* mul_add_c(a[3],b[1],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	c_1,c_3,t_2
+	dmultu	a_2,b_2		/* mul_add_c(a[2],b[2],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_1,b_3		/* mul_add_c(a[1],b[3],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	sd	c_2,32(a0)
+
+	dmultu	a_2,b_3		/* mul_add_c(a[2],b[3],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	c_2,c_1,t_2
+	dmultu	a_3,b_2		/* mul_add_c(a[3],b[2],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	sd	c_3,40(a0)
+
+	dmultu	a_3,b_3		/* mul_add_c(a[3],b[3],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sd	c_1,48(a0)
+	sd	c_2,56(a0)
+
+	jr	ra
+END(bn_mul_comba4)
+
+#undef	a_4
+#undef	a_5
+#undef	a_6
+#undef	a_7
+#define	a_4	b_0
+#define	a_5	b_1
+#define	a_6	b_2
+#define	a_7	b_3
+
+.align	5
+LEAF(bn_sqr_comba8)
+	.set	reorder
+	ld	a_0,0(a1)
+	ld	a_1,8(a1)
+	ld	a_2,16(a1)
+	ld	a_3,24(a1)
+
+	dmultu	a_0,a_0		/* mul_add_c(a[0],b[0],c1,c2,c3); */
+	ld	a_4,32(a1)
+	ld	a_5,40(a1)
+	ld	a_6,48(a1)
+	ld	a_7,56(a1)
+	mflo	c_1
+	mfhi	c_2
+	sd	c_1,0(a0)
+
+	dmultu	a_0,a_1		/* mul_add_c2(a[0],b[1],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_1,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	c_3,t_2,AT
+	sd	c_2,8(a0)
+
+	dmultu	a_2,a_0		/* mul_add_c2(a[2],b[0],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_2,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_1,a_1		/* mul_add_c(a[1],b[1],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	sd	c_3,16(a0)
+
+	dmultu	a_0,a_3		/* mul_add_c2(a[0],b[3],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_3,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_1,a_2		/* mul_add_c2(a[1],b[2],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	slt	AT,t_2,zero
+	daddu	c_3,AT
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	sd	c_1,24(a0)
+
+	dmultu	a_4,a_0		/* mul_add_c2(a[4],b[0],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_1,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_3,a_1		/* mul_add_c2(a[3],b[1],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	slt	AT,t_2,zero
+	daddu	c_1,AT
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_2,a_2		/* mul_add_c(a[2],b[2],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	sd	c_2,32(a0)
+
+	dmultu	a_0,a_5		/* mul_add_c2(a[0],b[5],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_2,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_1,a_4		/* mul_add_c2(a[1],b[4],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	slt	AT,t_2,zero
+	daddu	c_2,AT
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_2,a_3		/* mul_add_c2(a[2],b[3],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	slt	AT,t_2,zero
+	daddu	c_2,AT
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	sd	c_3,40(a0)
+
+	dmultu	a_6,a_0		/* mul_add_c2(a[6],b[0],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_3,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_5,a_1		/* mul_add_c2(a[5],b[1],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	slt	AT,t_2,zero
+	daddu	c_3,AT
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_4,a_2		/* mul_add_c2(a[4],b[2],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	slt	AT,t_2,zero
+	daddu	c_3,AT
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_3,a_3		/* mul_add_c(a[3],b[3],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	sd	c_1,48(a0)
+
+	dmultu	a_0,a_7		/* mul_add_c2(a[0],b[7],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_1,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_1,a_6		/* mul_add_c2(a[1],b[6],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	slt	AT,t_2,zero
+	daddu	c_1,AT
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_2,a_5		/* mul_add_c2(a[2],b[5],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	slt	AT,t_2,zero
+	daddu	c_1,AT
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_3,a_4		/* mul_add_c2(a[3],b[4],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	slt	AT,t_2,zero
+	daddu	c_1,AT
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	sd	c_2,56(a0)
+
+	dmultu	a_7,a_1		/* mul_add_c2(a[7],b[1],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_2,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_6,a_2		/* mul_add_c2(a[6],b[2],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	slt	AT,t_2,zero
+	daddu	c_2,AT
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_5,a_3		/* mul_add_c2(a[5],b[3],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	slt	AT,t_2,zero
+	daddu	c_2,AT
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_4,a_4		/* mul_add_c(a[4],b[4],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	sd	c_3,64(a0)
+
+	dmultu	a_2,a_7		/* mul_add_c2(a[2],b[7],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_3,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_3,a_6		/* mul_add_c2(a[3],b[6],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	slt	AT,t_2,zero
+	daddu	c_3,AT
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_4,a_5		/* mul_add_c2(a[4],b[5],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	slt	AT,t_2,zero
+	daddu	c_3,AT
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	sd	c_1,72(a0)
+
+	dmultu	a_7,a_3		/* mul_add_c2(a[7],b[3],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_1,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_6,a_4		/* mul_add_c2(a[6],b[4],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	slt	AT,t_2,zero
+	daddu	c_1,AT
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_5,a_5		/* mul_add_c(a[5],b[5],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	sd	c_2,80(a0)
+
+	dmultu	a_4,a_7		/* mul_add_c2(a[4],b[7],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_2,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_5,a_6		/* mul_add_c2(a[5],b[6],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	slt	AT,t_2,zero
+	daddu	c_2,AT
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	sd	c_3,88(a0)
+
+	dmultu	a_7,a_5		/* mul_add_c2(a[7],b[5],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_3,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_6,a_6		/* mul_add_c(a[6],b[6],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	sd	c_1,96(a0)
+
+	dmultu	a_6,a_7		/* mul_add_c2(a[6],b[7],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_1,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	sd	c_2,104(a0)
+
+	dmultu	a_7,a_7		/* mul_add_c(a[7],b[7],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sd	c_3,112(a0)
+	sd	c_1,120(a0)
+
+	jr	ra
+END(bn_sqr_comba8)
+
+.align	5
+LEAF(bn_sqr_comba4)
+	.set	reorder
+	ld	a_0,0(a1)
+	ld	a_1,8(a1)
+	ld	a_2,16(a1)
+	ld	a_3,24(a1)
+	dmultu	a_0,a_0		/* mul_add_c(a[0],b[0],c1,c2,c3); */
+	mflo	c_1
+	mfhi	c_2
+	sd	c_1,0(a0)
+
+	dmultu	a_0,a_1		/* mul_add_c2(a[0],b[1],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_1,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	c_3,t_2,AT
+	sd	c_2,8(a0)
+
+	dmultu	a_2,a_0		/* mul_add_c2(a[2],b[0],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_2,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	dmultu	a_1,a_1		/* mul_add_c(a[1],b[1],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	sd	c_3,16(a0)
+
+	dmultu	a_0,a_3		/* mul_add_c2(a[0],b[3],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_3,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	dmultu	a_1,a_2		/* mul_add_c(a2[1],b[2],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	slt	AT,t_2,zero
+	daddu	c_3,AT
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sltu	AT,c_2,t_2
+	daddu	c_3,AT
+	sd	c_1,24(a0)
+
+	dmultu	a_3,a_1		/* mul_add_c2(a[3],b[1],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_1,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	dmultu	a_2,a_2		/* mul_add_c(a[2],b[2],c2,c3,c1); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_2,t_1
+	sltu	AT,c_2,t_1
+	daddu	t_2,AT
+	daddu	c_3,t_2
+	sltu	AT,c_3,t_2
+	daddu	c_1,AT
+	sd	c_2,32(a0)
+
+	dmultu	a_2,a_3		/* mul_add_c2(a[2],b[3],c3,c1,c2); */
+	mflo	t_1
+	mfhi	t_2
+	slt	c_2,t_2,zero
+	dsll	t_2,1
+	slt	a2,t_1,zero
+	daddu	t_2,a2
+	dsll	t_1,1
+	daddu	c_3,t_1
+	sltu	AT,c_3,t_1
+	daddu	t_2,AT
+	daddu	c_1,t_2
+	sltu	AT,c_1,t_2
+	daddu	c_2,AT
+	sd	c_3,40(a0)
+
+	dmultu	a_3,a_3		/* mul_add_c(a[3],b[3],c1,c2,c3); */
+	mflo	t_1
+	mfhi	t_2
+	daddu	c_1,t_1
+	sltu	AT,c_1,t_1
+	daddu	t_2,AT
+	daddu	c_2,t_2
+	sd	c_1,48(a0)
+	sd	c_2,56(a0)
+
+	jr	ra
+END(bn_sqr_comba4)
diff --git a/openssl/crypto/bn/asm/pa-risc2.s b/openssl/crypto/bn/asm/pa-risc2.s
new file mode 100644
index 0000000..f3b1629
--- /dev/null
+++ b/openssl/crypto/bn/asm/pa-risc2.s
@@ -0,0 +1,1618 @@
+;
+; PA-RISC 2.0 implementation of bn_asm code, based on the
+; 64-bit version of the code.  This code is effectively the
+; same as the 64-bit version except the register model is
+; slightly different given all values must be 32-bit between
+; function calls.  Thus the 64-bit return values are returned
+; in %ret0 and %ret1 vs just %ret0 as is done in 64-bit
+;
+;
+; This code is approximately 2x faster than the C version
+; for RSA/DSA.
+;
+; See http://devresource.hp.com/  for more details on the PA-RISC
+; architecture.  Also see the book "PA-RISC 2.0 Architecture"
+; by Gerry Kane for information on the instruction set architecture.
+;
+; Code written by Chris Ruemmler (with some help from the HP C
+; compiler).
+;
+; The code compiles with HP's assembler
+;
+
+	.level	2.0N
+	.space	$TEXT$
+	.subspa	$CODE$,QUAD=0,ALIGN=8,ACCESS=0x2c,CODE_ONLY
+
+;
+; Global Register definitions used for the routines.
+;
+; Some information about HP's runtime architecture for 32-bits.
+;
+; "Caller save" means the calling function must save the register
+; if it wants the register to be preserved.
+; "Callee save" means if a function uses the register, it must save
+; the value before using it.
+;
+; For the floating point registers 
+;
+;    "caller save" registers: fr4-fr11, fr22-fr31
+;    "callee save" registers: fr12-fr21
+;    "special" registers: fr0-fr3 (status and exception registers)
+;
+; For the integer registers
+;     value zero             :  r0
+;     "caller save" registers: r1,r19-r26
+;     "callee save" registers: r3-r18
+;     return register        :  r2  (rp)
+;     return values          ; r28,r29  (ret0,ret1)
+;     Stack pointer          ; r30  (sp) 
+;     millicode return ptr   ; r31  (also a caller save register)
+
+
+;
+; Arguments to the routines
+;
+r_ptr       .reg %r26
+a_ptr       .reg %r25
+b_ptr       .reg %r24
+num         .reg %r24
+n           .reg %r23
+
+;
+; Note that the "w" argument for bn_mul_add_words and bn_mul_words
+; is passed on the stack at a delta of -56 from the top of stack
+; as the routine is entered.
+;
+
+;
+; Globals used in some routines
+;
+
+top_overflow .reg %r23
+high_mask    .reg %r22    ; value 0xffffffff80000000L
+
+
+;------------------------------------------------------------------------------
+;
+; bn_mul_add_words
+;
+;BN_ULONG bn_mul_add_words(BN_ULONG *r_ptr, BN_ULONG *a_ptr, 
+;								int num, BN_ULONG w)
+;
+; arg0 = r_ptr
+; arg1 = a_ptr
+; arg3 = num
+; -56(sp) =  w
+;
+; Local register definitions
+;
+
+fm1          .reg %fr22
+fm           .reg %fr23
+ht_temp      .reg %fr24
+ht_temp_1    .reg %fr25
+lt_temp      .reg %fr26
+lt_temp_1    .reg %fr27
+fm1_1        .reg %fr28
+fm_1         .reg %fr29
+
+fw_h         .reg %fr7L
+fw_l         .reg %fr7R
+fw           .reg %fr7
+
+fht_0        .reg %fr8L
+flt_0        .reg %fr8R
+t_float_0    .reg %fr8
+
+fht_1        .reg %fr9L
+flt_1        .reg %fr9R
+t_float_1    .reg %fr9
+
+tmp_0        .reg %r31
+tmp_1        .reg %r21
+m_0          .reg %r20 
+m_1          .reg %r19 
+ht_0         .reg %r1  
+ht_1         .reg %r3
+lt_0         .reg %r4
+lt_1         .reg %r5
+m1_0         .reg %r6 
+m1_1         .reg %r7 
+rp_val       .reg %r8
+rp_val_1     .reg %r9
+
+bn_mul_add_words
+	.export	bn_mul_add_words,entry,NO_RELOCATION,LONG_RETURN
+	.proc
+	.callinfo frame=128
+    .entry
+	.align 64
+
+    STD     %r3,0(%sp)          ; save r3  
+    STD     %r4,8(%sp)          ; save r4  
+	NOP                         ; Needed to make the loop 16-byte aligned
+	NOP                         ; needed to make the loop 16-byte aligned
+
+    STD     %r5,16(%sp)         ; save r5  
+	NOP
+    STD     %r6,24(%sp)         ; save r6  
+    STD     %r7,32(%sp)         ; save r7  
+
+    STD     %r8,40(%sp)         ; save r8  
+    STD     %r9,48(%sp)         ; save r9  
+    COPY    %r0,%ret1           ; return 0 by default
+    DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32    
+
+    CMPIB,>= 0,num,bn_mul_add_words_exit  ; if (num <= 0) then exit
+	LDO     128(%sp),%sp        ; bump stack
+
+	;
+	; The loop is unrolled twice, so if there is only 1 number
+    ; then go straight to the cleanup code.
+	;
+	CMPIB,= 1,num,bn_mul_add_words_single_top
+	FLDD    -184(%sp),fw        ; (-56-128) load up w into fw (fw_h/fw_l)
+
+	;
+	; This loop is unrolled 2 times (64-byte aligned as well)
+	;
+	; PA-RISC 2.0 chips have two fully pipelined multipliers, thus
+    ; two 32-bit mutiplies can be issued per cycle.
+    ; 
+bn_mul_add_words_unroll2
+
+    FLDD    0(a_ptr),t_float_0       ; load up 64-bit value (fr8L) ht(L)/lt(R)
+    FLDD    8(a_ptr),t_float_1       ; load up 64-bit value (fr8L) ht(L)/lt(R)
+    LDD     0(r_ptr),rp_val          ; rp[0]
+    LDD     8(r_ptr),rp_val_1        ; rp[1]
+
+    XMPYU   fht_0,fw_l,fm1           ; m1[0] = fht_0*fw_l
+    XMPYU   fht_1,fw_l,fm1_1         ; m1[1] = fht_1*fw_l
+    FSTD    fm1,-16(%sp)             ; -16(sp) = m1[0]
+    FSTD    fm1_1,-48(%sp)           ; -48(sp) = m1[1]
+
+    XMPYU   flt_0,fw_h,fm            ; m[0] = flt_0*fw_h
+    XMPYU   flt_1,fw_h,fm_1          ; m[1] = flt_1*fw_h
+    FSTD    fm,-8(%sp)               ; -8(sp) = m[0]
+    FSTD    fm_1,-40(%sp)            ; -40(sp) = m[1]
+
+    XMPYU   fht_0,fw_h,ht_temp       ; ht_temp   = fht_0*fw_h
+    XMPYU   fht_1,fw_h,ht_temp_1     ; ht_temp_1 = fht_1*fw_h
+    FSTD    ht_temp,-24(%sp)         ; -24(sp)   = ht_temp
+    FSTD    ht_temp_1,-56(%sp)       ; -56(sp)   = ht_temp_1
+
+    XMPYU   flt_0,fw_l,lt_temp       ; lt_temp = lt*fw_l
+    XMPYU   flt_1,fw_l,lt_temp_1     ; lt_temp = lt*fw_l
+    FSTD    lt_temp,-32(%sp)         ; -32(sp) = lt_temp 
+    FSTD    lt_temp_1,-64(%sp)       ; -64(sp) = lt_temp_1 
+
+    LDD     -8(%sp),m_0              ; m[0] 
+    LDD     -40(%sp),m_1             ; m[1]
+    LDD     -16(%sp),m1_0            ; m1[0]
+    LDD     -48(%sp),m1_1            ; m1[1]
+
+    LDD     -24(%sp),ht_0            ; ht[0]
+    LDD     -56(%sp),ht_1            ; ht[1]
+    ADD,L   m1_0,m_0,tmp_0           ; tmp_0 = m[0] + m1[0]; 
+    ADD,L   m1_1,m_1,tmp_1           ; tmp_1 = m[1] + m1[1]; 
+
+    LDD     -32(%sp),lt_0            
+    LDD     -64(%sp),lt_1            
+    CMPCLR,*>>= tmp_0,m1_0, %r0      ; if (m[0] < m1[0])
+    ADD,L   ht_0,top_overflow,ht_0   ; ht[0] += (1<<32)
+
+    CMPCLR,*>>= tmp_1,m1_1,%r0       ; if (m[1] < m1[1])
+    ADD,L   ht_1,top_overflow,ht_1   ; ht[1] += (1<<32)
+    EXTRD,U tmp_0,31,32,m_0          ; m[0]>>32  
+    DEPD,Z  tmp_0,31,32,m1_0         ; m1[0] = m[0]<<32 
+
+    EXTRD,U tmp_1,31,32,m_1          ; m[1]>>32  
+    DEPD,Z  tmp_1,31,32,m1_1         ; m1[1] = m[1]<<32 
+    ADD,L   ht_0,m_0,ht_0            ; ht[0]+= (m[0]>>32)
+    ADD,L   ht_1,m_1,ht_1            ; ht[1]+= (m[1]>>32)
+
+    ADD     lt_0,m1_0,lt_0           ; lt[0] = lt[0]+m1[0];
+	ADD,DC  ht_0,%r0,ht_0            ; ht[0]++
+    ADD     lt_1,m1_1,lt_1           ; lt[1] = lt[1]+m1[1];
+    ADD,DC  ht_1,%r0,ht_1            ; ht[1]++
+
+    ADD    %ret1,lt_0,lt_0           ; lt[0] = lt[0] + c;
+	ADD,DC  ht_0,%r0,ht_0            ; ht[0]++
+    ADD     lt_0,rp_val,lt_0         ; lt[0] = lt[0]+rp[0]
+    ADD,DC  ht_0,%r0,ht_0            ; ht[0]++
+
+	LDO    -2(num),num               ; num = num - 2;
+    ADD     ht_0,lt_1,lt_1           ; lt[1] = lt[1] + ht_0 (c);
+    ADD,DC  ht_1,%r0,ht_1            ; ht[1]++
+    STD     lt_0,0(r_ptr)            ; rp[0] = lt[0]
+
+    ADD     lt_1,rp_val_1,lt_1       ; lt[1] = lt[1]+rp[1]
+    ADD,DC  ht_1,%r0,%ret1           ; ht[1]++
+    LDO     16(a_ptr),a_ptr          ; a_ptr += 2
+
+    STD     lt_1,8(r_ptr)            ; rp[1] = lt[1]
+	CMPIB,<= 2,num,bn_mul_add_words_unroll2 ; go again if more to do
+    LDO     16(r_ptr),r_ptr          ; r_ptr += 2
+
+    CMPIB,=,N 0,num,bn_mul_add_words_exit ; are we done, or cleanup last one
+
+	;
+	; Top of loop aligned on 64-byte boundary
+	;
+bn_mul_add_words_single_top
+    FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
+    LDD     0(r_ptr),rp_val           ; rp[0]
+    LDO     8(a_ptr),a_ptr            ; a_ptr++
+    XMPYU   fht_0,fw_l,fm1            ; m1 = ht*fw_l
+    FSTD    fm1,-16(%sp)              ; -16(sp) = m1
+    XMPYU   flt_0,fw_h,fm             ; m = lt*fw_h
+    FSTD    fm,-8(%sp)                ; -8(sp) = m
+    XMPYU   fht_0,fw_h,ht_temp        ; ht_temp = ht*fw_h
+    FSTD    ht_temp,-24(%sp)          ; -24(sp) = ht
+    XMPYU   flt_0,fw_l,lt_temp        ; lt_temp = lt*fw_l
+    FSTD    lt_temp,-32(%sp)          ; -32(sp) = lt 
+
+    LDD     -8(%sp),m_0               
+    LDD    -16(%sp),m1_0              ; m1 = temp1 
+    ADD,L   m_0,m1_0,tmp_0            ; tmp_0 = m + m1; 
+    LDD     -24(%sp),ht_0             
+    LDD     -32(%sp),lt_0             
+
+    CMPCLR,*>>= tmp_0,m1_0,%r0        ; if (m < m1)
+    ADD,L   ht_0,top_overflow,ht_0    ; ht += (1<<32)
+
+    EXTRD,U tmp_0,31,32,m_0           ; m>>32  
+    DEPD,Z  tmp_0,31,32,m1_0          ; m1 = m<<32 
+
+    ADD,L   ht_0,m_0,ht_0             ; ht+= (m>>32)
+    ADD     lt_0,m1_0,tmp_0           ; tmp_0 = lt+m1;
+    ADD,DC  ht_0,%r0,ht_0             ; ht++
+    ADD     %ret1,tmp_0,lt_0          ; lt = lt + c;
+    ADD,DC  ht_0,%r0,ht_0             ; ht++
+    ADD     lt_0,rp_val,lt_0          ; lt = lt+rp[0]
+    ADD,DC  ht_0,%r0,%ret1            ; ht++
+    STD     lt_0,0(r_ptr)             ; rp[0] = lt
+
+bn_mul_add_words_exit
+    .EXIT
+	
+    EXTRD,U %ret1,31,32,%ret0         ; for 32-bit, return in ret0/ret1
+    LDD     -80(%sp),%r9              ; restore r9  
+    LDD     -88(%sp),%r8              ; restore r8  
+    LDD     -96(%sp),%r7              ; restore r7  
+    LDD     -104(%sp),%r6             ; restore r6  
+    LDD     -112(%sp),%r5             ; restore r5  
+    LDD     -120(%sp),%r4             ; restore r4  
+    BVE     (%rp)
+    LDD,MB  -128(%sp),%r3             ; restore r3
+	.PROCEND	;in=23,24,25,26,29;out=28;
+
+;----------------------------------------------------------------------------
+;
+;BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+;
+; arg0 = rp
+; arg1 = ap
+; arg3 = num
+; w on stack at -56(sp)
+
+bn_mul_words
+	.proc
+	.callinfo frame=128
+    .entry
+	.EXPORT	bn_mul_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+	.align 64
+
+    STD     %r3,0(%sp)          ; save r3  
+    STD     %r4,8(%sp)          ; save r4  
+	NOP
+    STD     %r5,16(%sp)         ; save r5  
+
+    STD     %r6,24(%sp)         ; save r6  
+    STD     %r7,32(%sp)         ; save r7  
+    COPY    %r0,%ret1           ; return 0 by default
+    DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32    
+
+    CMPIB,>= 0,num,bn_mul_words_exit
+	LDO     128(%sp),%sp    ; bump stack
+
+	;
+	; See if only 1 word to do, thus just do cleanup
+	;
+	CMPIB,= 1,num,bn_mul_words_single_top
+	FLDD    -184(%sp),fw        ; (-56-128) load up w into fw (fw_h/fw_l)
+
+	;
+	; This loop is unrolled 2 times (64-byte aligned as well)
+	;
+	; PA-RISC 2.0 chips have two fully pipelined multipliers, thus
+    ; two 32-bit mutiplies can be issued per cycle.
+    ; 
+bn_mul_words_unroll2
+
+    FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
+    FLDD    8(a_ptr),t_float_1        ; load up 64-bit value (fr8L) ht(L)/lt(R)
+    XMPYU   fht_0,fw_l,fm1            ; m1[0] = fht_0*fw_l
+    XMPYU   fht_1,fw_l,fm1_1          ; m1[1] = ht*fw_l
+
+    FSTD    fm1,-16(%sp)              ; -16(sp) = m1
+    FSTD    fm1_1,-48(%sp)            ; -48(sp) = m1
+    XMPYU   flt_0,fw_h,fm             ; m = lt*fw_h
+    XMPYU   flt_1,fw_h,fm_1           ; m = lt*fw_h
+
+    FSTD    fm,-8(%sp)                ; -8(sp) = m
+    FSTD    fm_1,-40(%sp)             ; -40(sp) = m
+    XMPYU   fht_0,fw_h,ht_temp        ; ht_temp = fht_0*fw_h
+    XMPYU   fht_1,fw_h,ht_temp_1      ; ht_temp = ht*fw_h
+
+    FSTD    ht_temp,-24(%sp)          ; -24(sp) = ht
+    FSTD    ht_temp_1,-56(%sp)        ; -56(sp) = ht
+    XMPYU   flt_0,fw_l,lt_temp        ; lt_temp = lt*fw_l
+    XMPYU   flt_1,fw_l,lt_temp_1      ; lt_temp = lt*fw_l
+
+    FSTD    lt_temp,-32(%sp)          ; -32(sp) = lt 
+    FSTD    lt_temp_1,-64(%sp)        ; -64(sp) = lt 
+    LDD     -8(%sp),m_0               
+    LDD     -40(%sp),m_1              
+
+    LDD    -16(%sp),m1_0              
+    LDD    -48(%sp),m1_1              
+    LDD     -24(%sp),ht_0             
+    LDD     -56(%sp),ht_1             
+
+    ADD,L   m1_0,m_0,tmp_0            ; tmp_0 = m + m1; 
+    ADD,L   m1_1,m_1,tmp_1            ; tmp_1 = m + m1; 
+    LDD     -32(%sp),lt_0             
+    LDD     -64(%sp),lt_1             
+
+    CMPCLR,*>>= tmp_0,m1_0, %r0       ; if (m < m1)
+    ADD,L   ht_0,top_overflow,ht_0    ; ht += (1<<32)
+    CMPCLR,*>>= tmp_1,m1_1,%r0        ; if (m < m1)
+    ADD,L   ht_1,top_overflow,ht_1    ; ht += (1<<32)
+
+    EXTRD,U tmp_0,31,32,m_0           ; m>>32  
+    DEPD,Z  tmp_0,31,32,m1_0          ; m1 = m<<32 
+    EXTRD,U tmp_1,31,32,m_1           ; m>>32  
+    DEPD,Z  tmp_1,31,32,m1_1          ; m1 = m<<32 
+
+    ADD,L   ht_0,m_0,ht_0             ; ht+= (m>>32)
+    ADD,L   ht_1,m_1,ht_1             ; ht+= (m>>32)
+    ADD     lt_0,m1_0,lt_0            ; lt = lt+m1;
+	ADD,DC  ht_0,%r0,ht_0             ; ht++
+
+    ADD     lt_1,m1_1,lt_1            ; lt = lt+m1;
+    ADD,DC  ht_1,%r0,ht_1             ; ht++
+    ADD    %ret1,lt_0,lt_0            ; lt = lt + c (ret1);
+	ADD,DC  ht_0,%r0,ht_0             ; ht++
+
+    ADD     ht_0,lt_1,lt_1            ; lt = lt + c (ht_0)
+    ADD,DC  ht_1,%r0,ht_1             ; ht++
+    STD     lt_0,0(r_ptr)             ; rp[0] = lt
+    STD     lt_1,8(r_ptr)             ; rp[1] = lt
+
+	COPY    ht_1,%ret1                ; carry = ht
+	LDO    -2(num),num                ; num = num - 2;
+    LDO     16(a_ptr),a_ptr           ; ap += 2
+	CMPIB,<= 2,num,bn_mul_words_unroll2
+    LDO     16(r_ptr),r_ptr           ; rp++
+
+    CMPIB,=,N 0,num,bn_mul_words_exit ; are we done?
+
+	;
+	; Top of loop aligned on 64-byte boundary
+	;
+bn_mul_words_single_top
+    FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
+
+    XMPYU   fht_0,fw_l,fm1            ; m1 = ht*fw_l
+    FSTD    fm1,-16(%sp)              ; -16(sp) = m1
+    XMPYU   flt_0,fw_h,fm             ; m = lt*fw_h
+    FSTD    fm,-8(%sp)                ; -8(sp) = m
+    XMPYU   fht_0,fw_h,ht_temp        ; ht_temp = ht*fw_h
+    FSTD    ht_temp,-24(%sp)          ; -24(sp) = ht
+    XMPYU   flt_0,fw_l,lt_temp        ; lt_temp = lt*fw_l
+    FSTD    lt_temp,-32(%sp)          ; -32(sp) = lt 
+
+    LDD     -8(%sp),m_0               
+    LDD    -16(%sp),m1_0              
+    ADD,L   m_0,m1_0,tmp_0            ; tmp_0 = m + m1; 
+    LDD     -24(%sp),ht_0             
+    LDD     -32(%sp),lt_0             
+
+    CMPCLR,*>>= tmp_0,m1_0,%r0        ; if (m < m1)
+    ADD,L   ht_0,top_overflow,ht_0    ; ht += (1<<32)
+
+    EXTRD,U tmp_0,31,32,m_0           ; m>>32  
+    DEPD,Z  tmp_0,31,32,m1_0          ; m1 = m<<32 
+
+    ADD,L   ht_0,m_0,ht_0             ; ht+= (m>>32)
+    ADD     lt_0,m1_0,lt_0            ; lt= lt+m1;
+    ADD,DC  ht_0,%r0,ht_0             ; ht++
+
+    ADD     %ret1,lt_0,lt_0           ; lt = lt + c;
+    ADD,DC  ht_0,%r0,ht_0             ; ht++
+
+    COPY    ht_0,%ret1                ; copy carry
+    STD     lt_0,0(r_ptr)             ; rp[0] = lt
+
+bn_mul_words_exit
+    .EXIT
+    EXTRD,U %ret1,31,32,%ret0           ; for 32-bit, return in ret0/ret1
+    LDD     -96(%sp),%r7              ; restore r7  
+    LDD     -104(%sp),%r6             ; restore r6  
+    LDD     -112(%sp),%r5             ; restore r5  
+    LDD     -120(%sp),%r4             ; restore r4  
+    BVE     (%rp)
+    LDD,MB  -128(%sp),%r3             ; restore r3
+	.PROCEND	
+
+;----------------------------------------------------------------------------
+;
+;void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num)
+;
+; arg0 = rp
+; arg1 = ap
+; arg2 = num
+;
+
+bn_sqr_words
+	.proc
+	.callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+	.EXPORT	bn_sqr_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+    .entry
+	.align 64
+
+    STD     %r3,0(%sp)          ; save r3  
+    STD     %r4,8(%sp)          ; save r4  
+	NOP
+    STD     %r5,16(%sp)         ; save r5  
+
+    CMPIB,>= 0,num,bn_sqr_words_exit
+	LDO     128(%sp),%sp       ; bump stack
+
+	;
+	; If only 1, the goto straight to cleanup
+	;
+	CMPIB,= 1,num,bn_sqr_words_single_top
+    DEPDI,Z -1,32,33,high_mask   ; Create Mask 0xffffffff80000000L
+
+	;
+	; This loop is unrolled 2 times (64-byte aligned as well)
+	;
+
+bn_sqr_words_unroll2
+    FLDD    0(a_ptr),t_float_0        ; a[0]
+    FLDD    8(a_ptr),t_float_1        ; a[1]
+    XMPYU   fht_0,flt_0,fm            ; m[0]
+    XMPYU   fht_1,flt_1,fm_1          ; m[1]
+
+    FSTD    fm,-24(%sp)               ; store m[0]
+    FSTD    fm_1,-56(%sp)             ; store m[1]
+    XMPYU   flt_0,flt_0,lt_temp       ; lt[0]
+    XMPYU   flt_1,flt_1,lt_temp_1     ; lt[1]
+
+    FSTD    lt_temp,-16(%sp)          ; store lt[0]
+    FSTD    lt_temp_1,-48(%sp)        ; store lt[1]
+    XMPYU   fht_0,fht_0,ht_temp       ; ht[0]
+    XMPYU   fht_1,fht_1,ht_temp_1     ; ht[1]
+
+    FSTD    ht_temp,-8(%sp)           ; store ht[0]
+    FSTD    ht_temp_1,-40(%sp)        ; store ht[1]
+    LDD     -24(%sp),m_0             
+    LDD     -56(%sp),m_1              
+
+    AND     m_0,high_mask,tmp_0       ; m[0] & Mask
+    AND     m_1,high_mask,tmp_1       ; m[1] & Mask
+    DEPD,Z  m_0,30,31,m_0             ; m[0] << 32+1
+    DEPD,Z  m_1,30,31,m_1             ; m[1] << 32+1
+
+    LDD     -16(%sp),lt_0        
+    LDD     -48(%sp),lt_1        
+    EXTRD,U tmp_0,32,33,tmp_0         ; tmp_0 = m[0]&Mask >> 32-1
+    EXTRD,U tmp_1,32,33,tmp_1         ; tmp_1 = m[1]&Mask >> 32-1
+
+    LDD     -8(%sp),ht_0            
+    LDD     -40(%sp),ht_1           
+    ADD,L   ht_0,tmp_0,ht_0           ; ht[0] += tmp_0
+    ADD,L   ht_1,tmp_1,ht_1           ; ht[1] += tmp_1
+
+    ADD     lt_0,m_0,lt_0             ; lt = lt+m
+    ADD,DC  ht_0,%r0,ht_0             ; ht[0]++
+    STD     lt_0,0(r_ptr)             ; rp[0] = lt[0]
+    STD     ht_0,8(r_ptr)             ; rp[1] = ht[1]
+
+    ADD     lt_1,m_1,lt_1             ; lt = lt+m
+    ADD,DC  ht_1,%r0,ht_1             ; ht[1]++
+    STD     lt_1,16(r_ptr)            ; rp[2] = lt[1]
+    STD     ht_1,24(r_ptr)            ; rp[3] = ht[1]
+
+	LDO    -2(num),num                ; num = num - 2;
+    LDO     16(a_ptr),a_ptr           ; ap += 2
+	CMPIB,<= 2,num,bn_sqr_words_unroll2
+    LDO     32(r_ptr),r_ptr           ; rp += 4
+
+    CMPIB,=,N 0,num,bn_sqr_words_exit ; are we done?
+
+	;
+	; Top of loop aligned on 64-byte boundary
+	;
+bn_sqr_words_single_top
+    FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
+
+    XMPYU   fht_0,flt_0,fm            ; m
+    FSTD    fm,-24(%sp)               ; store m
+
+    XMPYU   flt_0,flt_0,lt_temp       ; lt
+    FSTD    lt_temp,-16(%sp)          ; store lt
+
+    XMPYU   fht_0,fht_0,ht_temp       ; ht
+    FSTD    ht_temp,-8(%sp)           ; store ht
+
+    LDD     -24(%sp),m_0              ; load m
+    AND     m_0,high_mask,tmp_0       ; m & Mask
+    DEPD,Z  m_0,30,31,m_0             ; m << 32+1
+    LDD     -16(%sp),lt_0             ; lt
+
+    LDD     -8(%sp),ht_0              ; ht
+    EXTRD,U tmp_0,32,33,tmp_0         ; tmp_0 = m&Mask >> 32-1
+    ADD     m_0,lt_0,lt_0             ; lt = lt+m
+    ADD,L   ht_0,tmp_0,ht_0           ; ht += tmp_0
+    ADD,DC  ht_0,%r0,ht_0             ; ht++
+
+    STD     lt_0,0(r_ptr)             ; rp[0] = lt
+    STD     ht_0,8(r_ptr)             ; rp[1] = ht
+
+bn_sqr_words_exit
+    .EXIT
+    LDD     -112(%sp),%r5       ; restore r5  
+    LDD     -120(%sp),%r4       ; restore r4  
+    BVE     (%rp)
+    LDD,MB  -128(%sp),%r3 
+	.PROCEND	;in=23,24,25,26,29;out=28;
+
+
+;----------------------------------------------------------------------------
+;
+;BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+;
+; arg0 = rp 
+; arg1 = ap
+; arg2 = bp 
+; arg3 = n
+
+t  .reg %r22
+b  .reg %r21
+l  .reg %r20
+
+bn_add_words
+	.proc
+    .entry
+	.callinfo
+	.EXPORT	bn_add_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+	.align 64
+
+    CMPIB,>= 0,n,bn_add_words_exit
+    COPY    %r0,%ret1           ; return 0 by default
+
+	;
+	; If 2 or more numbers do the loop
+	;
+	CMPIB,= 1,n,bn_add_words_single_top
+	NOP
+
+	;
+	; This loop is unrolled 2 times (64-byte aligned as well)
+	;
+bn_add_words_unroll2
+	LDD     0(a_ptr),t
+	LDD     0(b_ptr),b
+	ADD     t,%ret1,t                    ; t = t+c;
+	ADD,DC  %r0,%r0,%ret1                ; set c to carry
+	ADD     t,b,l                        ; l = t + b[0]
+	ADD,DC  %ret1,%r0,%ret1              ; c+= carry
+	STD     l,0(r_ptr)
+
+	LDD     8(a_ptr),t
+	LDD     8(b_ptr),b
+	ADD     t,%ret1,t                     ; t = t+c;
+	ADD,DC  %r0,%r0,%ret1                 ; set c to carry
+	ADD     t,b,l                         ; l = t + b[0]
+	ADD,DC  %ret1,%r0,%ret1               ; c+= carry
+	STD     l,8(r_ptr)
+
+	LDO     -2(n),n
+	LDO     16(a_ptr),a_ptr
+	LDO     16(b_ptr),b_ptr
+
+	CMPIB,<= 2,n,bn_add_words_unroll2
+	LDO     16(r_ptr),r_ptr
+
+    CMPIB,=,N 0,n,bn_add_words_exit ; are we done?
+
+bn_add_words_single_top
+	LDD     0(a_ptr),t
+	LDD     0(b_ptr),b
+
+	ADD     t,%ret1,t                 ; t = t+c;
+	ADD,DC  %r0,%r0,%ret1             ; set c to carry (could use CMPCLR??)
+	ADD     t,b,l                     ; l = t + b[0]
+	ADD,DC  %ret1,%r0,%ret1           ; c+= carry
+	STD     l,0(r_ptr)
+
+bn_add_words_exit
+    .EXIT
+    BVE     (%rp)
+    EXTRD,U %ret1,31,32,%ret0           ; for 32-bit, return in ret0/ret1
+	.PROCEND	;in=23,24,25,26,29;out=28;
+
+;----------------------------------------------------------------------------
+;
+;BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+;
+; arg0 = rp 
+; arg1 = ap
+; arg2 = bp 
+; arg3 = n
+
+t1       .reg %r22
+t2       .reg %r21
+sub_tmp1 .reg %r20
+sub_tmp2 .reg %r19
+
+
+bn_sub_words
+	.proc
+	.callinfo 
+	.EXPORT	bn_sub_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+    .entry
+	.align 64
+
+    CMPIB,>=  0,n,bn_sub_words_exit
+    COPY    %r0,%ret1           ; return 0 by default
+
+	;
+	; If 2 or more numbers do the loop
+	;
+	CMPIB,= 1,n,bn_sub_words_single_top
+	NOP
+
+	;
+	; This loop is unrolled 2 times (64-byte aligned as well)
+	;
+bn_sub_words_unroll2
+	LDD     0(a_ptr),t1
+	LDD     0(b_ptr),t2
+	SUB     t1,t2,sub_tmp1           ; t3 = t1-t2; 
+	SUB     sub_tmp1,%ret1,sub_tmp1  ; t3 = t3- c; 
+
+	CMPCLR,*>> t1,t2,sub_tmp2        ; clear if t1 > t2
+	LDO      1(%r0),sub_tmp2
+	
+	CMPCLR,*= t1,t2,%r0
+	COPY    sub_tmp2,%ret1
+	STD     sub_tmp1,0(r_ptr)
+
+	LDD     8(a_ptr),t1
+	LDD     8(b_ptr),t2
+	SUB     t1,t2,sub_tmp1            ; t3 = t1-t2; 
+	SUB     sub_tmp1,%ret1,sub_tmp1   ; t3 = t3- c; 
+	CMPCLR,*>> t1,t2,sub_tmp2         ; clear if t1 > t2
+	LDO      1(%r0),sub_tmp2
+	
+	CMPCLR,*= t1,t2,%r0
+	COPY    sub_tmp2,%ret1
+	STD     sub_tmp1,8(r_ptr)
+
+	LDO     -2(n),n
+	LDO     16(a_ptr),a_ptr
+	LDO     16(b_ptr),b_ptr
+
+	CMPIB,<= 2,n,bn_sub_words_unroll2
+	LDO     16(r_ptr),r_ptr
+
+    CMPIB,=,N 0,n,bn_sub_words_exit ; are we done?
+
+bn_sub_words_single_top
+	LDD     0(a_ptr),t1
+	LDD     0(b_ptr),t2
+	SUB     t1,t2,sub_tmp1            ; t3 = t1-t2; 
+	SUB     sub_tmp1,%ret1,sub_tmp1   ; t3 = t3- c; 
+	CMPCLR,*>> t1,t2,sub_tmp2         ; clear if t1 > t2
+	LDO      1(%r0),sub_tmp2
+	
+	CMPCLR,*= t1,t2,%r0
+	COPY    sub_tmp2,%ret1
+
+	STD     sub_tmp1,0(r_ptr)
+
+bn_sub_words_exit
+    .EXIT
+    BVE     (%rp)
+    EXTRD,U %ret1,31,32,%ret0           ; for 32-bit, return in ret0/ret1
+	.PROCEND	;in=23,24,25,26,29;out=28;
+
+;------------------------------------------------------------------------------
+;
+; unsigned long bn_div_words(unsigned long h, unsigned long l, unsigned long d)
+;
+; arg0 = h
+; arg1 = l
+; arg2 = d
+;
+; This is mainly just output from the HP C compiler.  
+;
+;------------------------------------------------------------------------------
+bn_div_words
+	.PROC
+	.EXPORT	bn_div_words,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR,LONG_RETURN
+	.IMPORT	BN_num_bits_word,CODE
+	;--- not PIC	.IMPORT	__iob,DATA
+	;--- not PIC	.IMPORT	fprintf,CODE
+	.IMPORT	abort,CODE
+	.IMPORT	$$div2U,MILLICODE
+	.CALLINFO CALLER,FRAME=144,ENTRY_GR=%r9,SAVE_RP,ARGS_SAVED,ORDERING_AWARE
+        .ENTRY
+        STW     %r2,-20(%r30)   ;offset 0x8ec
+        STW,MA  %r3,192(%r30)   ;offset 0x8f0
+        STW     %r4,-188(%r30)  ;offset 0x8f4
+        DEPD    %r5,31,32,%r6   ;offset 0x8f8
+        STD     %r6,-184(%r30)  ;offset 0x8fc
+        DEPD    %r7,31,32,%r8   ;offset 0x900
+        STD     %r8,-176(%r30)  ;offset 0x904
+        STW     %r9,-168(%r30)  ;offset 0x908
+        LDD     -248(%r30),%r3  ;offset 0x90c
+        COPY    %r26,%r4        ;offset 0x910
+        COPY    %r24,%r5        ;offset 0x914
+        DEPD    %r25,31,32,%r4  ;offset 0x918
+        CMPB,*<>        %r3,%r0,$0006000C       ;offset 0x91c
+        DEPD    %r23,31,32,%r5  ;offset 0x920
+        MOVIB,TR        -1,%r29,$00060002       ;offset 0x924
+        EXTRD,U %r29,31,32,%r28 ;offset 0x928
+$0006002A
+        LDO     -1(%r29),%r29   ;offset 0x92c
+        SUB     %r23,%r7,%r23   ;offset 0x930
+$00060024
+        SUB     %r4,%r31,%r25   ;offset 0x934
+        AND     %r25,%r19,%r26  ;offset 0x938
+        CMPB,*<>,N      %r0,%r26,$00060046      ;offset 0x93c
+        DEPD,Z  %r25,31,32,%r20 ;offset 0x940
+        OR      %r20,%r24,%r21  ;offset 0x944
+        CMPB,*<<,N      %r21,%r23,$0006002A     ;offset 0x948
+        SUB     %r31,%r2,%r31   ;offset 0x94c
+$00060046
+$0006002E
+        DEPD,Z  %r23,31,32,%r25 ;offset 0x950
+        EXTRD,U %r23,31,32,%r26 ;offset 0x954
+        AND     %r25,%r19,%r24  ;offset 0x958
+        ADD,L   %r31,%r26,%r31  ;offset 0x95c
+        CMPCLR,*>>=     %r5,%r24,%r0    ;offset 0x960
+        LDO     1(%r31),%r31    ;offset 0x964
+$00060032
+        CMPB,*<<=,N     %r31,%r4,$00060036      ;offset 0x968
+        LDO     -1(%r29),%r29   ;offset 0x96c
+        ADD,L   %r4,%r3,%r4     ;offset 0x970
+$00060036
+        ADDIB,=,N       -1,%r8,$D0      ;offset 0x974
+        SUB     %r5,%r24,%r28   ;offset 0x978
+$0006003A
+        SUB     %r4,%r31,%r24   ;offset 0x97c
+        SHRPD   %r24,%r28,32,%r4        ;offset 0x980
+        DEPD,Z  %r29,31,32,%r9  ;offset 0x984
+        DEPD,Z  %r28,31,32,%r5  ;offset 0x988
+$0006001C
+        EXTRD,U %r4,31,32,%r31  ;offset 0x98c
+        CMPB,*<>,N      %r31,%r2,$00060020      ;offset 0x990
+        MOVB,TR %r6,%r29,$D1    ;offset 0x994
+        STD     %r29,-152(%r30) ;offset 0x998
+$0006000C
+        EXTRD,U %r3,31,32,%r25  ;offset 0x99c
+        COPY    %r3,%r26        ;offset 0x9a0
+        EXTRD,U %r3,31,32,%r9   ;offset 0x9a4
+        EXTRD,U %r4,31,32,%r8   ;offset 0x9a8
+        .CALL   ARGW0=GR,ARGW1=GR,RTNVAL=GR     ;in=25,26;out=28;
+        B,L     BN_num_bits_word,%r2    ;offset 0x9ac
+        EXTRD,U %r5,31,32,%r7   ;offset 0x9b0
+        LDI     64,%r20 ;offset 0x9b4
+        DEPD    %r7,31,32,%r5   ;offset 0x9b8
+        DEPD    %r8,31,32,%r4   ;offset 0x9bc
+        DEPD    %r9,31,32,%r3   ;offset 0x9c0
+        CMPB,=  %r28,%r20,$00060012     ;offset 0x9c4
+        COPY    %r28,%r24       ;offset 0x9c8
+        MTSARCM %r24    ;offset 0x9cc
+        DEPDI,Z -1,%sar,1,%r19  ;offset 0x9d0
+        CMPB,*>>,N      %r4,%r19,$D2    ;offset 0x9d4
+$00060012
+        SUBI    64,%r24,%r31    ;offset 0x9d8
+        CMPCLR,*<<      %r4,%r3,%r0     ;offset 0x9dc
+        SUB     %r4,%r3,%r4     ;offset 0x9e0
+$00060016
+        CMPB,=  %r31,%r0,$0006001A      ;offset 0x9e4
+        COPY    %r0,%r9 ;offset 0x9e8
+        MTSARCM %r31    ;offset 0x9ec
+        DEPD,Z  %r3,%sar,64,%r3 ;offset 0x9f0
+        SUBI    64,%r31,%r26    ;offset 0x9f4
+        MTSAR   %r26    ;offset 0x9f8
+        SHRPD   %r4,%r5,%sar,%r4        ;offset 0x9fc
+        MTSARCM %r31    ;offset 0xa00
+        DEPD,Z  %r5,%sar,64,%r5 ;offset 0xa04
+$0006001A
+        DEPDI,Z -1,31,32,%r19   ;offset 0xa08
+        AND     %r3,%r19,%r29   ;offset 0xa0c
+        EXTRD,U %r29,31,32,%r2  ;offset 0xa10
+        DEPDI,Z -1,63,32,%r6    ;offset 0xa14
+        MOVIB,TR        2,%r8,$0006001C ;offset 0xa18
+        EXTRD,U %r3,63,32,%r7   ;offset 0xa1c
+$D2
+        ;--- not PIC	ADDIL   LR'__iob-$global$,%r27,%r1      ;offset 0xa20
+        ;--- not PIC	LDIL    LR'C$7,%r21     ;offset 0xa24
+        ;--- not PIC	LDO     RR'__iob-$global$+32(%r1),%r26  ;offset 0xa28
+        ;--- not PIC	.CALL   ARGW0=GR,ARGW1=GR,ARGW2=GR,RTNVAL=GR    ;in=24,25,26;out=28;
+        ;--- not PIC	B,L     fprintf,%r2     ;offset 0xa2c
+        ;--- not PIC	LDO     RR'C$7(%r21),%r25       ;offset 0xa30
+        .CALL           ;
+        B,L     abort,%r2       ;offset 0xa34
+        NOP             ;offset 0xa38
+        B       $D3     ;offset 0xa3c
+        LDW     -212(%r30),%r2  ;offset 0xa40
+$00060020
+        COPY    %r4,%r26        ;offset 0xa44
+        EXTRD,U %r4,31,32,%r25  ;offset 0xa48
+        COPY    %r2,%r24        ;offset 0xa4c
+        .CALL   ;in=23,24,25,26;out=20,21,22,28,29; (MILLICALL)
+        B,L     $$div2U,%r31    ;offset 0xa50
+        EXTRD,U %r2,31,32,%r23  ;offset 0xa54
+        DEPD    %r28,31,32,%r29 ;offset 0xa58
+$00060022
+        STD     %r29,-152(%r30) ;offset 0xa5c
+$D1
+        AND     %r5,%r19,%r24   ;offset 0xa60
+        EXTRD,U %r24,31,32,%r24 ;offset 0xa64
+        STW     %r2,-160(%r30)  ;offset 0xa68
+        STW     %r7,-128(%r30)  ;offset 0xa6c
+        FLDD    -152(%r30),%fr4 ;offset 0xa70
+        FLDD    -152(%r30),%fr7 ;offset 0xa74
+        FLDW    -160(%r30),%fr8L        ;offset 0xa78
+        FLDW    -128(%r30),%fr5L        ;offset 0xa7c
+        XMPYU   %fr8L,%fr7L,%fr10       ;offset 0xa80
+        FSTD    %fr10,-136(%r30)        ;offset 0xa84
+        XMPYU   %fr8L,%fr7R,%fr22       ;offset 0xa88
+        FSTD    %fr22,-144(%r30)        ;offset 0xa8c
+        XMPYU   %fr5L,%fr4L,%fr11       ;offset 0xa90
+        XMPYU   %fr5L,%fr4R,%fr23       ;offset 0xa94
+        FSTD    %fr11,-112(%r30)        ;offset 0xa98
+        FSTD    %fr23,-120(%r30)        ;offset 0xa9c
+        LDD     -136(%r30),%r28 ;offset 0xaa0
+        DEPD,Z  %r28,31,32,%r31 ;offset 0xaa4
+        LDD     -144(%r30),%r20 ;offset 0xaa8
+        ADD,L   %r20,%r31,%r31  ;offset 0xaac
+        LDD     -112(%r30),%r22 ;offset 0xab0
+        DEPD,Z  %r22,31,32,%r22 ;offset 0xab4
+        LDD     -120(%r30),%r21 ;offset 0xab8
+        B       $00060024       ;offset 0xabc
+        ADD,L   %r21,%r22,%r23  ;offset 0xac0
+$D0
+        OR      %r9,%r29,%r29   ;offset 0xac4
+$00060040
+        EXTRD,U %r29,31,32,%r28 ;offset 0xac8
+$00060002
+$L2
+        LDW     -212(%r30),%r2  ;offset 0xacc
+$D3
+        LDW     -168(%r30),%r9  ;offset 0xad0
+        LDD     -176(%r30),%r8  ;offset 0xad4
+        EXTRD,U %r8,31,32,%r7   ;offset 0xad8
+        LDD     -184(%r30),%r6  ;offset 0xadc
+        EXTRD,U %r6,31,32,%r5   ;offset 0xae0
+        LDW     -188(%r30),%r4  ;offset 0xae4
+        BVE     (%r2)   ;offset 0xae8
+        .EXIT
+        LDW,MB  -192(%r30),%r3  ;offset 0xaec
+	.PROCEND	;in=23,25;out=28,29;fpin=105,107;
+
+
+
+
+;----------------------------------------------------------------------------
+;
+; Registers to hold 64-bit values to manipulate.  The "L" part
+; of the register corresponds to the upper 32-bits, while the "R"
+; part corresponds to the lower 32-bits
+; 
+; Note, that when using b6 and b7, the code must save these before
+; using them because they are callee save registers 
+; 
+;
+; Floating point registers to use to save values that
+; are manipulated.  These don't collide with ftemp1-6 and
+; are all caller save registers
+;
+a0        .reg %fr22
+a0L       .reg %fr22L
+a0R       .reg %fr22R
+
+a1        .reg %fr23
+a1L       .reg %fr23L
+a1R       .reg %fr23R
+
+a2        .reg %fr24
+a2L       .reg %fr24L
+a2R       .reg %fr24R
+
+a3        .reg %fr25
+a3L       .reg %fr25L
+a3R       .reg %fr25R
+
+a4        .reg %fr26
+a4L       .reg %fr26L
+a4R       .reg %fr26R
+
+a5        .reg %fr27
+a5L       .reg %fr27L
+a5R       .reg %fr27R
+
+a6        .reg %fr28
+a6L       .reg %fr28L
+a6R       .reg %fr28R
+
+a7        .reg %fr29
+a7L       .reg %fr29L
+a7R       .reg %fr29R
+
+b0        .reg %fr30
+b0L       .reg %fr30L
+b0R       .reg %fr30R
+
+b1        .reg %fr31
+b1L       .reg %fr31L
+b1R       .reg %fr31R
+
+;
+; Temporary floating point variables, these are all caller save
+; registers
+;
+ftemp1    .reg %fr4
+ftemp2    .reg %fr5
+ftemp3    .reg %fr6
+ftemp4    .reg %fr7
+
+;
+; The B set of registers when used.
+;
+
+b2        .reg %fr8
+b2L       .reg %fr8L
+b2R       .reg %fr8R
+
+b3        .reg %fr9
+b3L       .reg %fr9L
+b3R       .reg %fr9R
+
+b4        .reg %fr10
+b4L       .reg %fr10L
+b4R       .reg %fr10R
+
+b5        .reg %fr11
+b5L       .reg %fr11L
+b5R       .reg %fr11R
+
+b6        .reg %fr12
+b6L       .reg %fr12L
+b6R       .reg %fr12R
+
+b7        .reg %fr13
+b7L       .reg %fr13L
+b7R       .reg %fr13R
+
+c1           .reg %r21   ; only reg
+temp1        .reg %r20   ; only reg
+temp2        .reg %r19   ; only reg
+temp3        .reg %r31   ; only reg
+
+m1           .reg %r28   
+c2           .reg %r23   
+high_one     .reg %r1
+ht           .reg %r6
+lt           .reg %r5
+m            .reg %r4
+c3           .reg %r3
+
+SQR_ADD_C  .macro  A0L,A0R,C1,C2,C3
+    XMPYU   A0L,A0R,ftemp1       ; m
+    FSTD    ftemp1,-24(%sp)      ; store m
+
+    XMPYU   A0R,A0R,ftemp2       ; lt
+    FSTD    ftemp2,-16(%sp)      ; store lt
+
+    XMPYU   A0L,A0L,ftemp3       ; ht
+    FSTD    ftemp3,-8(%sp)       ; store ht
+
+    LDD     -24(%sp),m           ; load m
+    AND     m,high_mask,temp2    ; m & Mask
+    DEPD,Z  m,30,31,temp3        ; m << 32+1
+    LDD     -16(%sp),lt          ; lt
+
+    LDD     -8(%sp),ht           ; ht
+    EXTRD,U temp2,32,33,temp1    ; temp1 = m&Mask >> 32-1
+    ADD     temp3,lt,lt          ; lt = lt+m
+    ADD,L   ht,temp1,ht          ; ht += temp1
+    ADD,DC  ht,%r0,ht            ; ht++
+
+    ADD     C1,lt,C1             ; c1=c1+lt
+    ADD,DC  ht,%r0,ht            ; ht++
+
+    ADD     C2,ht,C2             ; c2=c2+ht
+    ADD,DC  C3,%r0,C3            ; c3++
+.endm
+
+SQR_ADD_C2 .macro  A0L,A0R,A1L,A1R,C1,C2,C3
+    XMPYU   A0L,A1R,ftemp1          ; m1 = bl*ht
+    FSTD    ftemp1,-16(%sp)         ;
+    XMPYU   A0R,A1L,ftemp2          ; m = bh*lt
+    FSTD    ftemp2,-8(%sp)          ;
+    XMPYU   A0R,A1R,ftemp3          ; lt = bl*lt
+    FSTD    ftemp3,-32(%sp)
+    XMPYU   A0L,A1L,ftemp4          ; ht = bh*ht
+    FSTD    ftemp4,-24(%sp)         ;
+
+    LDD     -8(%sp),m               ; r21 = m
+    LDD     -16(%sp),m1             ; r19 = m1
+    ADD,L   m,m1,m                  ; m+m1
+
+    DEPD,Z  m,31,32,temp3           ; (m+m1<<32)
+    LDD     -24(%sp),ht             ; r24 = ht
+
+    CMPCLR,*>>= m,m1,%r0            ; if (m < m1)
+    ADD,L   ht,high_one,ht          ; ht+=high_one
+
+    EXTRD,U m,31,32,temp1           ; m >> 32
+    LDD     -32(%sp),lt             ; lt
+    ADD,L   ht,temp1,ht             ; ht+= m>>32
+    ADD     lt,temp3,lt             ; lt = lt+m1
+    ADD,DC  ht,%r0,ht               ; ht++
+
+    ADD     ht,ht,ht                ; ht=ht+ht;
+    ADD,DC  C3,%r0,C3               ; add in carry (c3++)
+
+    ADD     lt,lt,lt                ; lt=lt+lt;
+    ADD,DC  ht,%r0,ht               ; add in carry (ht++)
+
+    ADD     C1,lt,C1                ; c1=c1+lt
+    ADD,DC,*NUV ht,%r0,ht           ; add in carry (ht++)
+    LDO     1(C3),C3              ; bump c3 if overflow,nullify otherwise
+
+    ADD     C2,ht,C2                ; c2 = c2 + ht
+    ADD,DC  C3,%r0,C3             ; add in carry (c3++)
+.endm
+
+;
+;void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
+; arg0 = r_ptr
+; arg1 = a_ptr
+;
+
+bn_sqr_comba8
+	.PROC
+	.CALLINFO FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+	.EXPORT	bn_sqr_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+    .ENTRY
+	.align 64
+
+    STD     %r3,0(%sp)          ; save r3
+    STD     %r4,8(%sp)          ; save r4
+    STD     %r5,16(%sp)         ; save r5
+    STD     %r6,24(%sp)         ; save r6
+
+	;
+	; Zero out carries
+	;
+	COPY     %r0,c1
+	COPY     %r0,c2
+	COPY     %r0,c3
+
+	LDO      128(%sp),%sp       ; bump stack
+    DEPDI,Z -1,32,33,high_mask   ; Create Mask 0xffffffff80000000L
+    DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
+
+	;
+	; Load up all of the values we are going to use
+	;
+    FLDD     0(a_ptr),a0       
+    FLDD     8(a_ptr),a1       
+    FLDD    16(a_ptr),a2       
+    FLDD    24(a_ptr),a3       
+    FLDD    32(a_ptr),a4       
+    FLDD    40(a_ptr),a5       
+    FLDD    48(a_ptr),a6       
+    FLDD    56(a_ptr),a7       
+
+	SQR_ADD_C a0L,a0R,c1,c2,c3
+	STD     c1,0(r_ptr)          ; r[0] = c1;
+	COPY    %r0,c1
+
+	SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1
+	STD     c2,8(r_ptr)          ; r[1] = c2;
+	COPY    %r0,c2
+
+	SQR_ADD_C a1L,a1R,c3,c1,c2
+	SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2
+	STD     c3,16(r_ptr)            ; r[2] = c3;
+	COPY    %r0,c3
+
+	SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3
+	SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3
+	STD     c1,24(r_ptr)           ; r[3] = c1;
+	COPY    %r0,c1
+
+	SQR_ADD_C a2L,a2R,c2,c3,c1
+	SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1
+	SQR_ADD_C2 a4L,a4R,a0L,a0R,c2,c3,c1
+	STD     c2,32(r_ptr)          ; r[4] = c2;
+	COPY    %r0,c2
+
+	SQR_ADD_C2 a5L,a5R,a0L,a0R,c3,c1,c2
+	SQR_ADD_C2 a4L,a4R,a1L,a1R,c3,c1,c2
+	SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2
+	STD     c3,40(r_ptr)          ; r[5] = c3;
+	COPY    %r0,c3
+
+	SQR_ADD_C a3L,a3R,c1,c2,c3
+	SQR_ADD_C2 a4L,a4R,a2L,a2R,c1,c2,c3
+	SQR_ADD_C2 a5L,a5R,a1L,a1R,c1,c2,c3
+	SQR_ADD_C2 a6L,a6R,a0L,a0R,c1,c2,c3
+	STD     c1,48(r_ptr)          ; r[6] = c1;
+	COPY    %r0,c1
+
+	SQR_ADD_C2 a7L,a7R,a0L,a0R,c2,c3,c1
+	SQR_ADD_C2 a6L,a6R,a1L,a1R,c2,c3,c1
+	SQR_ADD_C2 a5L,a5R,a2L,a2R,c2,c3,c1
+	SQR_ADD_C2 a4L,a4R,a3L,a3R,c2,c3,c1
+	STD     c2,56(r_ptr)          ; r[7] = c2;
+	COPY    %r0,c2
+
+	SQR_ADD_C a4L,a4R,c3,c1,c2
+	SQR_ADD_C2 a5L,a5R,a3L,a3R,c3,c1,c2
+	SQR_ADD_C2 a6L,a6R,a2L,a2R,c3,c1,c2
+	SQR_ADD_C2 a7L,a7R,a1L,a1R,c3,c1,c2
+	STD     c3,64(r_ptr)          ; r[8] = c3;
+	COPY    %r0,c3
+
+	SQR_ADD_C2 a7L,a7R,a2L,a2R,c1,c2,c3
+	SQR_ADD_C2 a6L,a6R,a3L,a3R,c1,c2,c3
+	SQR_ADD_C2 a5L,a5R,a4L,a4R,c1,c2,c3
+	STD     c1,72(r_ptr)          ; r[9] = c1;
+	COPY    %r0,c1
+
+	SQR_ADD_C a5L,a5R,c2,c3,c1
+	SQR_ADD_C2 a6L,a6R,a4L,a4R,c2,c3,c1
+	SQR_ADD_C2 a7L,a7R,a3L,a3R,c2,c3,c1
+	STD     c2,80(r_ptr)          ; r[10] = c2;
+	COPY    %r0,c2
+
+	SQR_ADD_C2 a7L,a7R,a4L,a4R,c3,c1,c2
+	SQR_ADD_C2 a6L,a6R,a5L,a5R,c3,c1,c2
+	STD     c3,88(r_ptr)          ; r[11] = c3;
+	COPY    %r0,c3
+	
+	SQR_ADD_C a6L,a6R,c1,c2,c3
+	SQR_ADD_C2 a7L,a7R,a5L,a5R,c1,c2,c3
+	STD     c1,96(r_ptr)          ; r[12] = c1;
+	COPY    %r0,c1
+
+	SQR_ADD_C2 a7L,a7R,a6L,a6R,c2,c3,c1
+	STD     c2,104(r_ptr)         ; r[13] = c2;
+	COPY    %r0,c2
+
+	SQR_ADD_C a7L,a7R,c3,c1,c2
+	STD     c3, 112(r_ptr)       ; r[14] = c3
+	STD     c1, 120(r_ptr)       ; r[15] = c1
+
+    .EXIT
+    LDD     -104(%sp),%r6        ; restore r6
+    LDD     -112(%sp),%r5        ; restore r5
+    LDD     -120(%sp),%r4        ; restore r4
+    BVE     (%rp)
+    LDD,MB  -128(%sp),%r3
+
+	.PROCEND	
+
+;-----------------------------------------------------------------------------
+;
+;void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
+; arg0 = r_ptr
+; arg1 = a_ptr
+;
+
+bn_sqr_comba4
+	.proc
+	.callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+	.EXPORT	bn_sqr_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+    .entry
+	.align 64
+    STD     %r3,0(%sp)          ; save r3
+    STD     %r4,8(%sp)          ; save r4
+    STD     %r5,16(%sp)         ; save r5
+    STD     %r6,24(%sp)         ; save r6
+
+	;
+	; Zero out carries
+	;
+	COPY     %r0,c1
+	COPY     %r0,c2
+	COPY     %r0,c3
+
+	LDO      128(%sp),%sp       ; bump stack
+    DEPDI,Z -1,32,33,high_mask   ; Create Mask 0xffffffff80000000L
+    DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
+
+	;
+	; Load up all of the values we are going to use
+	;
+    FLDD     0(a_ptr),a0       
+    FLDD     8(a_ptr),a1       
+    FLDD    16(a_ptr),a2       
+    FLDD    24(a_ptr),a3       
+    FLDD    32(a_ptr),a4       
+    FLDD    40(a_ptr),a5       
+    FLDD    48(a_ptr),a6       
+    FLDD    56(a_ptr),a7       
+
+	SQR_ADD_C a0L,a0R,c1,c2,c3
+
+	STD     c1,0(r_ptr)          ; r[0] = c1;
+	COPY    %r0,c1
+
+	SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1
+
+	STD     c2,8(r_ptr)          ; r[1] = c2;
+	COPY    %r0,c2
+
+	SQR_ADD_C a1L,a1R,c3,c1,c2
+	SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2
+
+	STD     c3,16(r_ptr)            ; r[2] = c3;
+	COPY    %r0,c3
+
+	SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3
+	SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3
+
+	STD     c1,24(r_ptr)           ; r[3] = c1;
+	COPY    %r0,c1
+
+	SQR_ADD_C a2L,a2R,c2,c3,c1
+	SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1
+
+	STD     c2,32(r_ptr)           ; r[4] = c2;
+	COPY    %r0,c2
+
+	SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2
+	STD     c3,40(r_ptr)           ; r[5] = c3;
+	COPY    %r0,c3
+
+	SQR_ADD_C a3L,a3R,c1,c2,c3
+	STD     c1,48(r_ptr)           ; r[6] = c1;
+	STD     c2,56(r_ptr)           ; r[7] = c2;
+
+    .EXIT
+    LDD     -104(%sp),%r6        ; restore r6
+    LDD     -112(%sp),%r5        ; restore r5
+    LDD     -120(%sp),%r4        ; restore r4
+    BVE     (%rp)
+    LDD,MB  -128(%sp),%r3
+
+	.PROCEND	
+
+
+;---------------------------------------------------------------------------
+
+MUL_ADD_C  .macro  A0L,A0R,B0L,B0R,C1,C2,C3
+    XMPYU   A0L,B0R,ftemp1        ; m1 = bl*ht
+    FSTD    ftemp1,-16(%sp)       ;
+    XMPYU   A0R,B0L,ftemp2        ; m = bh*lt
+    FSTD    ftemp2,-8(%sp)        ;
+    XMPYU   A0R,B0R,ftemp3        ; lt = bl*lt
+    FSTD    ftemp3,-32(%sp)
+    XMPYU   A0L,B0L,ftemp4        ; ht = bh*ht
+    FSTD    ftemp4,-24(%sp)       ;
+
+    LDD     -8(%sp),m             ; r21 = m
+    LDD     -16(%sp),m1           ; r19 = m1
+    ADD,L   m,m1,m                ; m+m1
+
+    DEPD,Z  m,31,32,temp3         ; (m+m1<<32)
+    LDD     -24(%sp),ht           ; r24 = ht
+
+    CMPCLR,*>>= m,m1,%r0          ; if (m < m1)
+    ADD,L   ht,high_one,ht        ; ht+=high_one
+
+    EXTRD,U m,31,32,temp1         ; m >> 32
+    LDD     -32(%sp),lt           ; lt
+    ADD,L   ht,temp1,ht           ; ht+= m>>32
+    ADD     lt,temp3,lt           ; lt = lt+m1
+    ADD,DC  ht,%r0,ht             ; ht++
+
+    ADD     C1,lt,C1              ; c1=c1+lt
+    ADD,DC  ht,%r0,ht             ; bump c3 if overflow,nullify otherwise
+
+    ADD     C2,ht,C2              ; c2 = c2 + ht
+    ADD,DC  C3,%r0,C3             ; add in carry (c3++)
+.endm
+
+
+;
+;void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+; arg0 = r_ptr
+; arg1 = a_ptr
+; arg2 = b_ptr
+;
+
+bn_mul_comba8
+	.proc
+	.callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+	.EXPORT	bn_mul_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+    .entry
+	.align 64
+
+    STD     %r3,0(%sp)          ; save r3
+    STD     %r4,8(%sp)          ; save r4
+    STD     %r5,16(%sp)         ; save r5
+    STD     %r6,24(%sp)         ; save r6
+    FSTD    %fr12,32(%sp)       ; save r6
+    FSTD    %fr13,40(%sp)       ; save r7
+
+	;
+	; Zero out carries
+	;
+	COPY     %r0,c1
+	COPY     %r0,c2
+	COPY     %r0,c3
+
+	LDO      128(%sp),%sp       ; bump stack
+    DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
+
+	;
+	; Load up all of the values we are going to use
+	;
+    FLDD      0(a_ptr),a0       
+    FLDD      8(a_ptr),a1       
+    FLDD     16(a_ptr),a2       
+    FLDD     24(a_ptr),a3       
+    FLDD     32(a_ptr),a4       
+    FLDD     40(a_ptr),a5       
+    FLDD     48(a_ptr),a6       
+    FLDD     56(a_ptr),a7       
+
+    FLDD      0(b_ptr),b0       
+    FLDD      8(b_ptr),b1       
+    FLDD     16(b_ptr),b2       
+    FLDD     24(b_ptr),b3       
+    FLDD     32(b_ptr),b4       
+    FLDD     40(b_ptr),b5       
+    FLDD     48(b_ptr),b6       
+    FLDD     56(b_ptr),b7       
+
+	MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3
+	STD       c1,0(r_ptr)
+	COPY      %r0,c1
+
+	MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1
+	MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1
+	STD       c2,8(r_ptr)
+	COPY      %r0,c2
+
+	MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2
+	MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2
+	MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2
+	STD       c3,16(r_ptr)
+	COPY      %r0,c3
+
+	MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3
+	MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3
+	MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3
+	MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3
+	STD       c1,24(r_ptr)
+	COPY      %r0,c1
+
+	MUL_ADD_C a4L,a4R,b0L,b0R,c2,c3,c1
+	MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1
+	MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1
+	MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1
+	MUL_ADD_C a0L,a0R,b4L,b4R,c2,c3,c1
+	STD       c2,32(r_ptr)
+	COPY      %r0,c2
+
+	MUL_ADD_C a0L,a0R,b5L,b5R,c3,c1,c2
+	MUL_ADD_C a1L,a1R,b4L,b4R,c3,c1,c2
+	MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2
+	MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2
+	MUL_ADD_C a4L,a4R,b1L,b1R,c3,c1,c2
+	MUL_ADD_C a5L,a5R,b0L,b0R,c3,c1,c2
+	STD       c3,40(r_ptr)
+	COPY      %r0,c3
+
+	MUL_ADD_C a6L,a6R,b0L,b0R,c1,c2,c3
+	MUL_ADD_C a5L,a5R,b1L,b1R,c1,c2,c3
+	MUL_ADD_C a4L,a4R,b2L,b2R,c1,c2,c3
+	MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3
+	MUL_ADD_C a2L,a2R,b4L,b4R,c1,c2,c3
+	MUL_ADD_C a1L,a1R,b5L,b5R,c1,c2,c3
+	MUL_ADD_C a0L,a0R,b6L,b6R,c1,c2,c3
+	STD       c1,48(r_ptr)
+	COPY      %r0,c1
+	
+	MUL_ADD_C a0L,a0R,b7L,b7R,c2,c3,c1
+	MUL_ADD_C a1L,a1R,b6L,b6R,c2,c3,c1
+	MUL_ADD_C a2L,a2R,b5L,b5R,c2,c3,c1
+	MUL_ADD_C a3L,a3R,b4L,b4R,c2,c3,c1
+	MUL_ADD_C a4L,a4R,b3L,b3R,c2,c3,c1
+	MUL_ADD_C a5L,a5R,b2L,b2R,c2,c3,c1
+	MUL_ADD_C a6L,a6R,b1L,b1R,c2,c3,c1
+	MUL_ADD_C a7L,a7R,b0L,b0R,c2,c3,c1
+	STD       c2,56(r_ptr)
+	COPY      %r0,c2
+
+	MUL_ADD_C a7L,a7R,b1L,b1R,c3,c1,c2
+	MUL_ADD_C a6L,a6R,b2L,b2R,c3,c1,c2
+	MUL_ADD_C a5L,a5R,b3L,b3R,c3,c1,c2
+	MUL_ADD_C a4L,a4R,b4L,b4R,c3,c1,c2
+	MUL_ADD_C a3L,a3R,b5L,b5R,c3,c1,c2
+	MUL_ADD_C a2L,a2R,b6L,b6R,c3,c1,c2
+	MUL_ADD_C a1L,a1R,b7L,b7R,c3,c1,c2
+	STD       c3,64(r_ptr)
+	COPY      %r0,c3
+
+	MUL_ADD_C a2L,a2R,b7L,b7R,c1,c2,c3
+	MUL_ADD_C a3L,a3R,b6L,b6R,c1,c2,c3
+	MUL_ADD_C a4L,a4R,b5L,b5R,c1,c2,c3
+	MUL_ADD_C a5L,a5R,b4L,b4R,c1,c2,c3
+	MUL_ADD_C a6L,a6R,b3L,b3R,c1,c2,c3
+	MUL_ADD_C a7L,a7R,b2L,b2R,c1,c2,c3
+	STD       c1,72(r_ptr)
+	COPY      %r0,c1
+
+	MUL_ADD_C a7L,a7R,b3L,b3R,c2,c3,c1
+	MUL_ADD_C a6L,a6R,b4L,b4R,c2,c3,c1
+	MUL_ADD_C a5L,a5R,b5L,b5R,c2,c3,c1
+	MUL_ADD_C a4L,a4R,b6L,b6R,c2,c3,c1
+	MUL_ADD_C a3L,a3R,b7L,b7R,c2,c3,c1
+	STD       c2,80(r_ptr)
+	COPY      %r0,c2
+
+	MUL_ADD_C a4L,a4R,b7L,b7R,c3,c1,c2
+	MUL_ADD_C a5L,a5R,b6L,b6R,c3,c1,c2
+	MUL_ADD_C a6L,a6R,b5L,b5R,c3,c1,c2
+	MUL_ADD_C a7L,a7R,b4L,b4R,c3,c1,c2
+	STD       c3,88(r_ptr)
+	COPY      %r0,c3
+
+	MUL_ADD_C a7L,a7R,b5L,b5R,c1,c2,c3
+	MUL_ADD_C a6L,a6R,b6L,b6R,c1,c2,c3
+	MUL_ADD_C a5L,a5R,b7L,b7R,c1,c2,c3
+	STD       c1,96(r_ptr)
+	COPY      %r0,c1
+
+	MUL_ADD_C a6L,a6R,b7L,b7R,c2,c3,c1
+	MUL_ADD_C a7L,a7R,b6L,b6R,c2,c3,c1
+	STD       c2,104(r_ptr)
+	COPY      %r0,c2
+
+	MUL_ADD_C a7L,a7R,b7L,b7R,c3,c1,c2
+	STD       c3,112(r_ptr)
+	STD       c1,120(r_ptr)
+
+    .EXIT
+    FLDD    -88(%sp),%fr13 
+    FLDD    -96(%sp),%fr12 
+    LDD     -104(%sp),%r6        ; restore r6
+    LDD     -112(%sp),%r5        ; restore r5
+    LDD     -120(%sp),%r4        ; restore r4
+    BVE     (%rp)
+    LDD,MB  -128(%sp),%r3
+
+	.PROCEND	
+
+;-----------------------------------------------------------------------------
+;
+;void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+; arg0 = r_ptr
+; arg1 = a_ptr
+; arg2 = b_ptr
+;
+
+bn_mul_comba4
+	.proc
+	.callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+	.EXPORT	bn_mul_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+    .entry
+	.align 64
+
+    STD     %r3,0(%sp)          ; save r3
+    STD     %r4,8(%sp)          ; save r4
+    STD     %r5,16(%sp)         ; save r5
+    STD     %r6,24(%sp)         ; save r6
+    FSTD    %fr12,32(%sp)       ; save r6
+    FSTD    %fr13,40(%sp)       ; save r7
+
+	;
+	; Zero out carries
+	;
+	COPY     %r0,c1
+	COPY     %r0,c2
+	COPY     %r0,c3
+
+	LDO      128(%sp),%sp       ; bump stack
+    DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
+
+	;
+	; Load up all of the values we are going to use
+	;
+    FLDD      0(a_ptr),a0       
+    FLDD      8(a_ptr),a1       
+    FLDD     16(a_ptr),a2       
+    FLDD     24(a_ptr),a3       
+
+    FLDD      0(b_ptr),b0       
+    FLDD      8(b_ptr),b1       
+    FLDD     16(b_ptr),b2       
+    FLDD     24(b_ptr),b3       
+
+	MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3
+	STD       c1,0(r_ptr)
+	COPY      %r0,c1
+
+	MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1
+	MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1
+	STD       c2,8(r_ptr)
+	COPY      %r0,c2
+
+	MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2
+	MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2
+	MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2
+	STD       c3,16(r_ptr)
+	COPY      %r0,c3
+
+	MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3
+	MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3
+	MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3
+	MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3
+	STD       c1,24(r_ptr)
+	COPY      %r0,c1
+
+	MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1
+	MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1
+	MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1
+	STD       c2,32(r_ptr)
+	COPY      %r0,c2
+
+	MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2
+	MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2
+	STD       c3,40(r_ptr)
+	COPY      %r0,c3
+
+	MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3
+	STD       c1,48(r_ptr)
+	STD       c2,56(r_ptr)
+
+    .EXIT
+    FLDD    -88(%sp),%fr13 
+    FLDD    -96(%sp),%fr12 
+    LDD     -104(%sp),%r6        ; restore r6
+    LDD     -112(%sp),%r5        ; restore r5
+    LDD     -120(%sp),%r4        ; restore r4
+    BVE     (%rp)
+    LDD,MB  -128(%sp),%r3
+
+	.PROCEND	
+
+
+;--- not PIC	.SPACE	$TEXT$
+;--- not PIC	.SUBSPA	$CODE$
+;--- not PIC	.SPACE	$PRIVATE$,SORT=16
+;--- not PIC	.IMPORT	$global$,DATA
+;--- not PIC	.SPACE	$TEXT$
+;--- not PIC	.SUBSPA	$CODE$
+;--- not PIC	.SUBSPA	$LIT$,ACCESS=0x2c
+;--- not PIC	C$7
+;--- not PIC	.ALIGN	8
+;--- not PIC	.STRINGZ	"Division would overflow (%d)\n"
+	.END
diff --git a/openssl/crypto/bn/asm/pa-risc2W.s b/openssl/crypto/bn/asm/pa-risc2W.s
new file mode 100644
index 0000000..a995457
--- /dev/null
+++ b/openssl/crypto/bn/asm/pa-risc2W.s
@@ -0,0 +1,1605 @@
+;
+; PA-RISC 64-bit implementation of bn_asm code
+;
+; This code is approximately 2x faster than the C version
+; for RSA/DSA.
+;
+; See http://devresource.hp.com/  for more details on the PA-RISC
+; architecture.  Also see the book "PA-RISC 2.0 Architecture"
+; by Gerry Kane for information on the instruction set architecture.
+;
+; Code written by Chris Ruemmler (with some help from the HP C
+; compiler).
+;
+; The code compiles with HP's assembler
+;
+
+	.level	2.0W
+	.space	$TEXT$
+	.subspa	$CODE$,QUAD=0,ALIGN=8,ACCESS=0x2c,CODE_ONLY
+
+;
+; Global Register definitions used for the routines.
+;
+; Some information about HP's runtime architecture for 64-bits.
+;
+; "Caller save" means the calling function must save the register
+; if it wants the register to be preserved.
+; "Callee save" means if a function uses the register, it must save
+; the value before using it.
+;
+; For the floating point registers 
+;
+;    "caller save" registers: fr4-fr11, fr22-fr31
+;    "callee save" registers: fr12-fr21
+;    "special" registers: fr0-fr3 (status and exception registers)
+;
+; For the integer registers
+;     value zero             :  r0
+;     "caller save" registers: r1,r19-r26
+;     "callee save" registers: r3-r18
+;     return register        :  r2  (rp)
+;     return values          ; r28  (ret0,ret1)
+;     Stack pointer          ; r30  (sp) 
+;     global data pointer    ; r27  (dp)
+;     argument pointer       ; r29  (ap)
+;     millicode return ptr   ; r31  (also a caller save register)
+
+
+;
+; Arguments to the routines
+;
+r_ptr       .reg %r26
+a_ptr       .reg %r25
+b_ptr       .reg %r24
+num         .reg %r24
+w           .reg %r23
+n           .reg %r23
+
+
+;
+; Globals used in some routines
+;
+
+top_overflow .reg %r29
+high_mask    .reg %r22    ; value 0xffffffff80000000L
+
+
+;------------------------------------------------------------------------------
+;
+; bn_mul_add_words
+;
+;BN_ULONG bn_mul_add_words(BN_ULONG *r_ptr, BN_ULONG *a_ptr, 
+;								int num, BN_ULONG w)
+;
+; arg0 = r_ptr
+; arg1 = a_ptr
+; arg2 = num
+; arg3 = w
+;
+; Local register definitions
+;
+
+fm1          .reg %fr22
+fm           .reg %fr23
+ht_temp      .reg %fr24
+ht_temp_1    .reg %fr25
+lt_temp      .reg %fr26
+lt_temp_1    .reg %fr27
+fm1_1        .reg %fr28
+fm_1         .reg %fr29
+
+fw_h         .reg %fr7L
+fw_l         .reg %fr7R
+fw           .reg %fr7
+
+fht_0        .reg %fr8L
+flt_0        .reg %fr8R
+t_float_0    .reg %fr8
+
+fht_1        .reg %fr9L
+flt_1        .reg %fr9R
+t_float_1    .reg %fr9
+
+tmp_0        .reg %r31
+tmp_1        .reg %r21
+m_0          .reg %r20 
+m_1          .reg %r19 
+ht_0         .reg %r1  
+ht_1         .reg %r3
+lt_0         .reg %r4
+lt_1         .reg %r5
+m1_0         .reg %r6 
+m1_1         .reg %r7 
+rp_val       .reg %r8
+rp_val_1     .reg %r9
+
+bn_mul_add_words
+	.export	bn_mul_add_words,entry,NO_RELOCATION,LONG_RETURN
+	.proc
+	.callinfo frame=128
+    .entry
+	.align 64
+
+    STD     %r3,0(%sp)          ; save r3  
+    STD     %r4,8(%sp)          ; save r4  
+	NOP                         ; Needed to make the loop 16-byte aligned
+	NOP                         ; Needed to make the loop 16-byte aligned
+
+    STD     %r5,16(%sp)         ; save r5  
+    STD     %r6,24(%sp)         ; save r6  
+    STD     %r7,32(%sp)         ; save r7  
+    STD     %r8,40(%sp)         ; save r8  
+
+    STD     %r9,48(%sp)         ; save r9  
+    COPY    %r0,%ret0           ; return 0 by default
+    DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32    
+	STD     w,56(%sp)           ; store w on stack
+
+    CMPIB,>= 0,num,bn_mul_add_words_exit  ; if (num <= 0) then exit
+	LDO     128(%sp),%sp       ; bump stack
+
+	;
+	; The loop is unrolled twice, so if there is only 1 number
+    ; then go straight to the cleanup code.
+	;
+	CMPIB,= 1,num,bn_mul_add_words_single_top
+	FLDD    -72(%sp),fw     ; load up w into fp register fw (fw_h/fw_l)
+
+	;
+	; This loop is unrolled 2 times (64-byte aligned as well)
+	;
+	; PA-RISC 2.0 chips have two fully pipelined multipliers, thus
+    ; two 32-bit mutiplies can be issued per cycle.
+    ; 
+bn_mul_add_words_unroll2
+
+    FLDD    0(a_ptr),t_float_0       ; load up 64-bit value (fr8L) ht(L)/lt(R)
+    FLDD    8(a_ptr),t_float_1       ; load up 64-bit value (fr8L) ht(L)/lt(R)
+    LDD     0(r_ptr),rp_val          ; rp[0]
+    LDD     8(r_ptr),rp_val_1        ; rp[1]
+
+    XMPYU   fht_0,fw_l,fm1           ; m1[0] = fht_0*fw_l
+    XMPYU   fht_1,fw_l,fm1_1         ; m1[1] = fht_1*fw_l
+    FSTD    fm1,-16(%sp)             ; -16(sp) = m1[0]
+    FSTD    fm1_1,-48(%sp)           ; -48(sp) = m1[1]
+
+    XMPYU   flt_0,fw_h,fm            ; m[0] = flt_0*fw_h
+    XMPYU   flt_1,fw_h,fm_1          ; m[1] = flt_1*fw_h
+    FSTD    fm,-8(%sp)               ; -8(sp) = m[0]
+    FSTD    fm_1,-40(%sp)            ; -40(sp) = m[1]
+
+    XMPYU   fht_0,fw_h,ht_temp       ; ht_temp   = fht_0*fw_h
+    XMPYU   fht_1,fw_h,ht_temp_1     ; ht_temp_1 = fht_1*fw_h
+    FSTD    ht_temp,-24(%sp)         ; -24(sp)   = ht_temp
+    FSTD    ht_temp_1,-56(%sp)       ; -56(sp)   = ht_temp_1
+
+    XMPYU   flt_0,fw_l,lt_temp       ; lt_temp = lt*fw_l
+    XMPYU   flt_1,fw_l,lt_temp_1     ; lt_temp = lt*fw_l
+    FSTD    lt_temp,-32(%sp)         ; -32(sp) = lt_temp 
+    FSTD    lt_temp_1,-64(%sp)       ; -64(sp) = lt_temp_1 
+
+    LDD     -8(%sp),m_0              ; m[0] 
+    LDD     -40(%sp),m_1             ; m[1]
+    LDD     -16(%sp),m1_0            ; m1[0]
+    LDD     -48(%sp),m1_1            ; m1[1]
+
+    LDD     -24(%sp),ht_0            ; ht[0]
+    LDD     -56(%sp),ht_1            ; ht[1]
+    ADD,L   m1_0,m_0,tmp_0           ; tmp_0 = m[0] + m1[0]; 
+    ADD,L   m1_1,m_1,tmp_1           ; tmp_1 = m[1] + m1[1]; 
+
+    LDD     -32(%sp),lt_0            
+    LDD     -64(%sp),lt_1            
+    CMPCLR,*>>= tmp_0,m1_0, %r0      ; if (m[0] < m1[0])
+    ADD,L   ht_0,top_overflow,ht_0   ; ht[0] += (1<<32)
+
+    CMPCLR,*>>= tmp_1,m1_1,%r0       ; if (m[1] < m1[1])
+    ADD,L   ht_1,top_overflow,ht_1   ; ht[1] += (1<<32)
+    EXTRD,U tmp_0,31,32,m_0          ; m[0]>>32  
+    DEPD,Z  tmp_0,31,32,m1_0         ; m1[0] = m[0]<<32 
+
+    EXTRD,U tmp_1,31,32,m_1          ; m[1]>>32  
+    DEPD,Z  tmp_1,31,32,m1_1         ; m1[1] = m[1]<<32 
+    ADD,L   ht_0,m_0,ht_0            ; ht[0]+= (m[0]>>32)
+    ADD,L   ht_1,m_1,ht_1            ; ht[1]+= (m[1]>>32)
+
+    ADD     lt_0,m1_0,lt_0           ; lt[0] = lt[0]+m1[0];
+	ADD,DC  ht_0,%r0,ht_0            ; ht[0]++
+    ADD     lt_1,m1_1,lt_1           ; lt[1] = lt[1]+m1[1];
+    ADD,DC  ht_1,%r0,ht_1            ; ht[1]++
+
+    ADD    %ret0,lt_0,lt_0           ; lt[0] = lt[0] + c;
+	ADD,DC  ht_0,%r0,ht_0            ; ht[0]++
+    ADD     lt_0,rp_val,lt_0         ; lt[0] = lt[0]+rp[0]
+    ADD,DC  ht_0,%r0,ht_0            ; ht[0]++
+
+	LDO    -2(num),num               ; num = num - 2;
+    ADD     ht_0,lt_1,lt_1           ; lt[1] = lt[1] + ht_0 (c);
+    ADD,DC  ht_1,%r0,ht_1            ; ht[1]++
+    STD     lt_0,0(r_ptr)            ; rp[0] = lt[0]
+
+    ADD     lt_1,rp_val_1,lt_1       ; lt[1] = lt[1]+rp[1]
+    ADD,DC  ht_1,%r0,%ret0           ; ht[1]++
+    LDO     16(a_ptr),a_ptr          ; a_ptr += 2
+
+    STD     lt_1,8(r_ptr)            ; rp[1] = lt[1]
+	CMPIB,<= 2,num,bn_mul_add_words_unroll2 ; go again if more to do
+    LDO     16(r_ptr),r_ptr          ; r_ptr += 2
+
+    CMPIB,=,N 0,num,bn_mul_add_words_exit ; are we done, or cleanup last one
+
+	;
+	; Top of loop aligned on 64-byte boundary
+	;
+bn_mul_add_words_single_top
+    FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
+    LDD     0(r_ptr),rp_val           ; rp[0]
+    LDO     8(a_ptr),a_ptr            ; a_ptr++
+    XMPYU   fht_0,fw_l,fm1            ; m1 = ht*fw_l
+    FSTD    fm1,-16(%sp)              ; -16(sp) = m1
+    XMPYU   flt_0,fw_h,fm             ; m = lt*fw_h
+    FSTD    fm,-8(%sp)                ; -8(sp) = m
+    XMPYU   fht_0,fw_h,ht_temp        ; ht_temp = ht*fw_h
+    FSTD    ht_temp,-24(%sp)          ; -24(sp) = ht
+    XMPYU   flt_0,fw_l,lt_temp        ; lt_temp = lt*fw_l
+    FSTD    lt_temp,-32(%sp)          ; -32(sp) = lt 
+
+    LDD     -8(%sp),m_0               
+    LDD    -16(%sp),m1_0              ; m1 = temp1 
+    ADD,L   m_0,m1_0,tmp_0            ; tmp_0 = m + m1; 
+    LDD     -24(%sp),ht_0             
+    LDD     -32(%sp),lt_0             
+
+    CMPCLR,*>>= tmp_0,m1_0,%r0        ; if (m < m1)
+    ADD,L   ht_0,top_overflow,ht_0    ; ht += (1<<32)
+
+    EXTRD,U tmp_0,31,32,m_0           ; m>>32  
+    DEPD,Z  tmp_0,31,32,m1_0          ; m1 = m<<32 
+
+    ADD,L   ht_0,m_0,ht_0             ; ht+= (m>>32)
+    ADD     lt_0,m1_0,tmp_0           ; tmp_0 = lt+m1;
+    ADD,DC  ht_0,%r0,ht_0             ; ht++
+    ADD     %ret0,tmp_0,lt_0          ; lt = lt + c;
+    ADD,DC  ht_0,%r0,ht_0             ; ht++
+    ADD     lt_0,rp_val,lt_0          ; lt = lt+rp[0]
+    ADD,DC  ht_0,%r0,%ret0            ; ht++
+    STD     lt_0,0(r_ptr)             ; rp[0] = lt
+
+bn_mul_add_words_exit
+    .EXIT
+    LDD     -80(%sp),%r9              ; restore r9  
+    LDD     -88(%sp),%r8              ; restore r8  
+    LDD     -96(%sp),%r7              ; restore r7  
+    LDD     -104(%sp),%r6             ; restore r6  
+    LDD     -112(%sp),%r5             ; restore r5  
+    LDD     -120(%sp),%r4             ; restore r4  
+    BVE     (%rp)
+    LDD,MB  -128(%sp),%r3             ; restore r3
+	.PROCEND	;in=23,24,25,26,29;out=28;
+
+;----------------------------------------------------------------------------
+;
+;BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+;
+; arg0 = rp
+; arg1 = ap
+; arg2 = num
+; arg3 = w
+
+bn_mul_words
+	.proc
+	.callinfo frame=128
+    .entry
+	.EXPORT	bn_mul_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+	.align 64
+
+    STD     %r3,0(%sp)          ; save r3  
+    STD     %r4,8(%sp)          ; save r4  
+    STD     %r5,16(%sp)         ; save r5  
+    STD     %r6,24(%sp)         ; save r6  
+
+    STD     %r7,32(%sp)         ; save r7  
+    COPY    %r0,%ret0           ; return 0 by default
+    DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32    
+	STD     w,56(%sp)           ; w on stack
+
+    CMPIB,>= 0,num,bn_mul_words_exit
+	LDO     128(%sp),%sp       ; bump stack
+
+	;
+	; See if only 1 word to do, thus just do cleanup
+	;
+	CMPIB,= 1,num,bn_mul_words_single_top
+	FLDD    -72(%sp),fw     ; load up w into fp register fw (fw_h/fw_l)
+
+	;
+	; This loop is unrolled 2 times (64-byte aligned as well)
+	;
+	; PA-RISC 2.0 chips have two fully pipelined multipliers, thus
+    ; two 32-bit mutiplies can be issued per cycle.
+    ; 
+bn_mul_words_unroll2
+
+    FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
+    FLDD    8(a_ptr),t_float_1        ; load up 64-bit value (fr8L) ht(L)/lt(R)
+    XMPYU   fht_0,fw_l,fm1            ; m1[0] = fht_0*fw_l
+    XMPYU   fht_1,fw_l,fm1_1          ; m1[1] = ht*fw_l
+
+    FSTD    fm1,-16(%sp)              ; -16(sp) = m1
+    FSTD    fm1_1,-48(%sp)            ; -48(sp) = m1
+    XMPYU   flt_0,fw_h,fm             ; m = lt*fw_h
+    XMPYU   flt_1,fw_h,fm_1           ; m = lt*fw_h
+
+    FSTD    fm,-8(%sp)                ; -8(sp) = m
+    FSTD    fm_1,-40(%sp)             ; -40(sp) = m
+    XMPYU   fht_0,fw_h,ht_temp        ; ht_temp = fht_0*fw_h
+    XMPYU   fht_1,fw_h,ht_temp_1      ; ht_temp = ht*fw_h
+
+    FSTD    ht_temp,-24(%sp)          ; -24(sp) = ht
+    FSTD    ht_temp_1,-56(%sp)        ; -56(sp) = ht
+    XMPYU   flt_0,fw_l,lt_temp        ; lt_temp = lt*fw_l
+    XMPYU   flt_1,fw_l,lt_temp_1      ; lt_temp = lt*fw_l
+
+    FSTD    lt_temp,-32(%sp)          ; -32(sp) = lt 
+    FSTD    lt_temp_1,-64(%sp)        ; -64(sp) = lt 
+    LDD     -8(%sp),m_0               
+    LDD     -40(%sp),m_1              
+
+    LDD    -16(%sp),m1_0              
+    LDD    -48(%sp),m1_1              
+    LDD     -24(%sp),ht_0             
+    LDD     -56(%sp),ht_1             
+
+    ADD,L   m1_0,m_0,tmp_0            ; tmp_0 = m + m1; 
+    ADD,L   m1_1,m_1,tmp_1            ; tmp_1 = m + m1; 
+    LDD     -32(%sp),lt_0             
+    LDD     -64(%sp),lt_1             
+
+    CMPCLR,*>>= tmp_0,m1_0, %r0       ; if (m < m1)
+    ADD,L   ht_0,top_overflow,ht_0    ; ht += (1<<32)
+    CMPCLR,*>>= tmp_1,m1_1,%r0        ; if (m < m1)
+    ADD,L   ht_1,top_overflow,ht_1    ; ht += (1<<32)
+
+    EXTRD,U tmp_0,31,32,m_0           ; m>>32  
+    DEPD,Z  tmp_0,31,32,m1_0          ; m1 = m<<32 
+    EXTRD,U tmp_1,31,32,m_1           ; m>>32  
+    DEPD,Z  tmp_1,31,32,m1_1          ; m1 = m<<32 
+
+    ADD,L   ht_0,m_0,ht_0             ; ht+= (m>>32)
+    ADD,L   ht_1,m_1,ht_1             ; ht+= (m>>32)
+    ADD     lt_0,m1_0,lt_0            ; lt = lt+m1;
+	ADD,DC  ht_0,%r0,ht_0             ; ht++
+
+    ADD     lt_1,m1_1,lt_1            ; lt = lt+m1;
+    ADD,DC  ht_1,%r0,ht_1             ; ht++
+    ADD    %ret0,lt_0,lt_0            ; lt = lt + c (ret0);
+	ADD,DC  ht_0,%r0,ht_0             ; ht++
+
+    ADD     ht_0,lt_1,lt_1            ; lt = lt + c (ht_0)
+    ADD,DC  ht_1,%r0,ht_1             ; ht++
+    STD     lt_0,0(r_ptr)             ; rp[0] = lt
+    STD     lt_1,8(r_ptr)             ; rp[1] = lt
+
+	COPY    ht_1,%ret0                ; carry = ht
+	LDO    -2(num),num                ; num = num - 2;
+    LDO     16(a_ptr),a_ptr           ; ap += 2
+	CMPIB,<= 2,num,bn_mul_words_unroll2
+    LDO     16(r_ptr),r_ptr           ; rp++
+
+    CMPIB,=,N 0,num,bn_mul_words_exit ; are we done?
+
+	;
+	; Top of loop aligned on 64-byte boundary
+	;
+bn_mul_words_single_top
+    FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
+
+    XMPYU   fht_0,fw_l,fm1            ; m1 = ht*fw_l
+    FSTD    fm1,-16(%sp)              ; -16(sp) = m1
+    XMPYU   flt_0,fw_h,fm             ; m = lt*fw_h
+    FSTD    fm,-8(%sp)                ; -8(sp) = m
+    XMPYU   fht_0,fw_h,ht_temp        ; ht_temp = ht*fw_h
+    FSTD    ht_temp,-24(%sp)          ; -24(sp) = ht
+    XMPYU   flt_0,fw_l,lt_temp        ; lt_temp = lt*fw_l
+    FSTD    lt_temp,-32(%sp)          ; -32(sp) = lt 
+
+    LDD     -8(%sp),m_0               
+    LDD    -16(%sp),m1_0              
+    ADD,L   m_0,m1_0,tmp_0            ; tmp_0 = m + m1; 
+    LDD     -24(%sp),ht_0             
+    LDD     -32(%sp),lt_0             
+
+    CMPCLR,*>>= tmp_0,m1_0,%r0        ; if (m < m1)
+    ADD,L   ht_0,top_overflow,ht_0    ; ht += (1<<32)
+
+    EXTRD,U tmp_0,31,32,m_0           ; m>>32  
+    DEPD,Z  tmp_0,31,32,m1_0          ; m1 = m<<32 
+
+    ADD,L   ht_0,m_0,ht_0             ; ht+= (m>>32)
+    ADD     lt_0,m1_0,lt_0            ; lt= lt+m1;
+    ADD,DC  ht_0,%r0,ht_0             ; ht++
+
+    ADD     %ret0,lt_0,lt_0           ; lt = lt + c;
+    ADD,DC  ht_0,%r0,ht_0             ; ht++
+
+    COPY    ht_0,%ret0                ; copy carry
+    STD     lt_0,0(r_ptr)             ; rp[0] = lt
+
+bn_mul_words_exit
+    .EXIT
+    LDD     -96(%sp),%r7              ; restore r7  
+    LDD     -104(%sp),%r6             ; restore r6  
+    LDD     -112(%sp),%r5             ; restore r5  
+    LDD     -120(%sp),%r4             ; restore r4  
+    BVE     (%rp)
+    LDD,MB  -128(%sp),%r3             ; restore r3
+	.PROCEND	;in=23,24,25,26,29;out=28;
+
+;----------------------------------------------------------------------------
+;
+;void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num)
+;
+; arg0 = rp
+; arg1 = ap
+; arg2 = num
+;
+
+bn_sqr_words
+	.proc
+	.callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+	.EXPORT	bn_sqr_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+    .entry
+	.align 64
+
+    STD     %r3,0(%sp)          ; save r3  
+    STD     %r4,8(%sp)          ; save r4  
+	NOP
+    STD     %r5,16(%sp)         ; save r5  
+
+    CMPIB,>= 0,num,bn_sqr_words_exit
+	LDO     128(%sp),%sp       ; bump stack
+
+	;
+	; If only 1, the goto straight to cleanup
+	;
+	CMPIB,= 1,num,bn_sqr_words_single_top
+    DEPDI,Z -1,32,33,high_mask   ; Create Mask 0xffffffff80000000L
+
+	;
+	; This loop is unrolled 2 times (64-byte aligned as well)
+	;
+
+bn_sqr_words_unroll2
+    FLDD    0(a_ptr),t_float_0        ; a[0]
+    FLDD    8(a_ptr),t_float_1        ; a[1]
+    XMPYU   fht_0,flt_0,fm            ; m[0]
+    XMPYU   fht_1,flt_1,fm_1          ; m[1]
+
+    FSTD    fm,-24(%sp)               ; store m[0]
+    FSTD    fm_1,-56(%sp)             ; store m[1]
+    XMPYU   flt_0,flt_0,lt_temp       ; lt[0]
+    XMPYU   flt_1,flt_1,lt_temp_1     ; lt[1]
+
+    FSTD    lt_temp,-16(%sp)          ; store lt[0]
+    FSTD    lt_temp_1,-48(%sp)        ; store lt[1]
+    XMPYU   fht_0,fht_0,ht_temp       ; ht[0]
+    XMPYU   fht_1,fht_1,ht_temp_1     ; ht[1]
+
+    FSTD    ht_temp,-8(%sp)           ; store ht[0]
+    FSTD    ht_temp_1,-40(%sp)        ; store ht[1]
+    LDD     -24(%sp),m_0             
+    LDD     -56(%sp),m_1              
+
+    AND     m_0,high_mask,tmp_0       ; m[0] & Mask
+    AND     m_1,high_mask,tmp_1       ; m[1] & Mask
+    DEPD,Z  m_0,30,31,m_0             ; m[0] << 32+1
+    DEPD,Z  m_1,30,31,m_1             ; m[1] << 32+1
+
+    LDD     -16(%sp),lt_0        
+    LDD     -48(%sp),lt_1        
+    EXTRD,U tmp_0,32,33,tmp_0         ; tmp_0 = m[0]&Mask >> 32-1
+    EXTRD,U tmp_1,32,33,tmp_1         ; tmp_1 = m[1]&Mask >> 32-1
+
+    LDD     -8(%sp),ht_0            
+    LDD     -40(%sp),ht_1           
+    ADD,L   ht_0,tmp_0,ht_0           ; ht[0] += tmp_0
+    ADD,L   ht_1,tmp_1,ht_1           ; ht[1] += tmp_1
+
+    ADD     lt_0,m_0,lt_0             ; lt = lt+m
+    ADD,DC  ht_0,%r0,ht_0             ; ht[0]++
+    STD     lt_0,0(r_ptr)             ; rp[0] = lt[0]
+    STD     ht_0,8(r_ptr)             ; rp[1] = ht[1]
+
+    ADD     lt_1,m_1,lt_1             ; lt = lt+m
+    ADD,DC  ht_1,%r0,ht_1             ; ht[1]++
+    STD     lt_1,16(r_ptr)            ; rp[2] = lt[1]
+    STD     ht_1,24(r_ptr)            ; rp[3] = ht[1]
+
+	LDO    -2(num),num                ; num = num - 2;
+    LDO     16(a_ptr),a_ptr           ; ap += 2
+	CMPIB,<= 2,num,bn_sqr_words_unroll2
+    LDO     32(r_ptr),r_ptr           ; rp += 4
+
+    CMPIB,=,N 0,num,bn_sqr_words_exit ; are we done?
+
+	;
+	; Top of loop aligned on 64-byte boundary
+	;
+bn_sqr_words_single_top
+    FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
+
+    XMPYU   fht_0,flt_0,fm            ; m
+    FSTD    fm,-24(%sp)               ; store m
+
+    XMPYU   flt_0,flt_0,lt_temp       ; lt
+    FSTD    lt_temp,-16(%sp)          ; store lt
+
+    XMPYU   fht_0,fht_0,ht_temp       ; ht
+    FSTD    ht_temp,-8(%sp)           ; store ht
+
+    LDD     -24(%sp),m_0              ; load m
+    AND     m_0,high_mask,tmp_0       ; m & Mask
+    DEPD,Z  m_0,30,31,m_0             ; m << 32+1
+    LDD     -16(%sp),lt_0             ; lt
+
+    LDD     -8(%sp),ht_0              ; ht
+    EXTRD,U tmp_0,32,33,tmp_0         ; tmp_0 = m&Mask >> 32-1
+    ADD     m_0,lt_0,lt_0             ; lt = lt+m
+    ADD,L   ht_0,tmp_0,ht_0           ; ht += tmp_0
+    ADD,DC  ht_0,%r0,ht_0             ; ht++
+
+    STD     lt_0,0(r_ptr)             ; rp[0] = lt
+    STD     ht_0,8(r_ptr)             ; rp[1] = ht
+
+bn_sqr_words_exit
+    .EXIT
+    LDD     -112(%sp),%r5       ; restore r5  
+    LDD     -120(%sp),%r4       ; restore r4  
+    BVE     (%rp)
+    LDD,MB  -128(%sp),%r3 
+	.PROCEND	;in=23,24,25,26,29;out=28;
+
+
+;----------------------------------------------------------------------------
+;
+;BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+;
+; arg0 = rp 
+; arg1 = ap
+; arg2 = bp 
+; arg3 = n
+
+t  .reg %r22
+b  .reg %r21
+l  .reg %r20
+
+bn_add_words
+	.proc
+    .entry
+	.callinfo
+	.EXPORT	bn_add_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+	.align 64
+
+    CMPIB,>= 0,n,bn_add_words_exit
+    COPY    %r0,%ret0           ; return 0 by default
+
+	;
+	; If 2 or more numbers do the loop
+	;
+	CMPIB,= 1,n,bn_add_words_single_top
+	NOP
+
+	;
+	; This loop is unrolled 2 times (64-byte aligned as well)
+	;
+bn_add_words_unroll2
+	LDD     0(a_ptr),t
+	LDD     0(b_ptr),b
+	ADD     t,%ret0,t                    ; t = t+c;
+	ADD,DC  %r0,%r0,%ret0                ; set c to carry
+	ADD     t,b,l                        ; l = t + b[0]
+	ADD,DC  %ret0,%r0,%ret0              ; c+= carry
+	STD     l,0(r_ptr)
+
+	LDD     8(a_ptr),t
+	LDD     8(b_ptr),b
+	ADD     t,%ret0,t                     ; t = t+c;
+	ADD,DC  %r0,%r0,%ret0                 ; set c to carry
+	ADD     t,b,l                         ; l = t + b[0]
+	ADD,DC  %ret0,%r0,%ret0               ; c+= carry
+	STD     l,8(r_ptr)
+
+	LDO     -2(n),n
+	LDO     16(a_ptr),a_ptr
+	LDO     16(b_ptr),b_ptr
+
+	CMPIB,<= 2,n,bn_add_words_unroll2
+	LDO     16(r_ptr),r_ptr
+
+    CMPIB,=,N 0,n,bn_add_words_exit ; are we done?
+
+bn_add_words_single_top
+	LDD     0(a_ptr),t
+	LDD     0(b_ptr),b
+
+	ADD     t,%ret0,t                 ; t = t+c;
+	ADD,DC  %r0,%r0,%ret0             ; set c to carry (could use CMPCLR??)
+	ADD     t,b,l                     ; l = t + b[0]
+	ADD,DC  %ret0,%r0,%ret0           ; c+= carry
+	STD     l,0(r_ptr)
+
+bn_add_words_exit
+    .EXIT
+    BVE     (%rp)
+	NOP
+	.PROCEND	;in=23,24,25,26,29;out=28;
+
+;----------------------------------------------------------------------------
+;
+;BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+;
+; arg0 = rp 
+; arg1 = ap
+; arg2 = bp 
+; arg3 = n
+
+t1       .reg %r22
+t2       .reg %r21
+sub_tmp1 .reg %r20
+sub_tmp2 .reg %r19
+
+
+bn_sub_words
+	.proc
+	.callinfo 
+	.EXPORT	bn_sub_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+    .entry
+	.align 64
+
+    CMPIB,>=  0,n,bn_sub_words_exit
+    COPY    %r0,%ret0           ; return 0 by default
+
+	;
+	; If 2 or more numbers do the loop
+	;
+	CMPIB,= 1,n,bn_sub_words_single_top
+	NOP
+
+	;
+	; This loop is unrolled 2 times (64-byte aligned as well)
+	;
+bn_sub_words_unroll2
+	LDD     0(a_ptr),t1
+	LDD     0(b_ptr),t2
+	SUB     t1,t2,sub_tmp1           ; t3 = t1-t2; 
+	SUB     sub_tmp1,%ret0,sub_tmp1  ; t3 = t3- c; 
+
+	CMPCLR,*>> t1,t2,sub_tmp2        ; clear if t1 > t2
+	LDO      1(%r0),sub_tmp2
+	
+	CMPCLR,*= t1,t2,%r0
+	COPY    sub_tmp2,%ret0
+	STD     sub_tmp1,0(r_ptr)
+
+	LDD     8(a_ptr),t1
+	LDD     8(b_ptr),t2
+	SUB     t1,t2,sub_tmp1            ; t3 = t1-t2; 
+	SUB     sub_tmp1,%ret0,sub_tmp1   ; t3 = t3- c; 
+	CMPCLR,*>> t1,t2,sub_tmp2         ; clear if t1 > t2
+	LDO      1(%r0),sub_tmp2
+	
+	CMPCLR,*= t1,t2,%r0
+	COPY    sub_tmp2,%ret0
+	STD     sub_tmp1,8(r_ptr)
+
+	LDO     -2(n),n
+	LDO     16(a_ptr),a_ptr
+	LDO     16(b_ptr),b_ptr
+
+	CMPIB,<= 2,n,bn_sub_words_unroll2
+	LDO     16(r_ptr),r_ptr
+
+    CMPIB,=,N 0,n,bn_sub_words_exit ; are we done?
+
+bn_sub_words_single_top
+	LDD     0(a_ptr),t1
+	LDD     0(b_ptr),t2
+	SUB     t1,t2,sub_tmp1            ; t3 = t1-t2; 
+	SUB     sub_tmp1,%ret0,sub_tmp1   ; t3 = t3- c; 
+	CMPCLR,*>> t1,t2,sub_tmp2         ; clear if t1 > t2
+	LDO      1(%r0),sub_tmp2
+	
+	CMPCLR,*= t1,t2,%r0
+	COPY    sub_tmp2,%ret0
+
+	STD     sub_tmp1,0(r_ptr)
+
+bn_sub_words_exit
+    .EXIT
+    BVE     (%rp)
+	NOP
+	.PROCEND	;in=23,24,25,26,29;out=28;
+
+;------------------------------------------------------------------------------
+;
+; unsigned long bn_div_words(unsigned long h, unsigned long l, unsigned long d)
+;
+; arg0 = h
+; arg1 = l
+; arg2 = d
+;
+; This is mainly just modified assembly from the compiler, thus the
+; lack of variable names.
+;
+;------------------------------------------------------------------------------
+bn_div_words
+	.proc
+	.callinfo CALLER,FRAME=272,ENTRY_GR=%r10,SAVE_RP,ARGS_SAVED,ORDERING_AWARE
+	.EXPORT	bn_div_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+	.IMPORT	BN_num_bits_word,CODE,NO_RELOCATION
+	.IMPORT	__iob,DATA
+	.IMPORT	fprintf,CODE,NO_RELOCATION
+	.IMPORT	abort,CODE,NO_RELOCATION
+	.IMPORT	$$div2U,MILLICODE
+    .entry
+    STD     %r2,-16(%r30)   
+    STD,MA  %r3,352(%r30)   
+    STD     %r4,-344(%r30)  
+    STD     %r5,-336(%r30)  
+    STD     %r6,-328(%r30)  
+    STD     %r7,-320(%r30)  
+    STD     %r8,-312(%r30)  
+    STD     %r9,-304(%r30)  
+    STD     %r10,-296(%r30)
+
+    STD     %r27,-288(%r30)             ; save gp
+
+    COPY    %r24,%r3           ; save d 
+    COPY    %r26,%r4           ; save h (high 64-bits)
+    LDO      -1(%r0),%ret0     ; return -1 by default	
+
+    CMPB,*=  %r0,%arg2,$D3     ; if (d == 0)
+    COPY    %r25,%r5           ; save l (low 64-bits)
+
+    LDO     -48(%r30),%r29     ; create ap 
+    .CALL   ;in=26,29;out=28;
+    B,L     BN_num_bits_word,%r2 
+    COPY    %r3,%r26        
+    LDD     -288(%r30),%r27    ; restore gp 
+    LDI     64,%r21 
+
+    CMPB,=  %r21,%ret0,$00000012   ;if (i == 64) (forward) 
+    COPY    %ret0,%r24             ; i   
+    MTSARCM %r24    
+    DEPDI,Z -1,%sar,1,%r29  
+    CMPB,*<<,N %r29,%r4,bn_div_err_case ; if (h > 1<<i) (forward) 
+
+$00000012
+    SUBI    64,%r24,%r31                       ; i = 64 - i;
+    CMPCLR,*<< %r4,%r3,%r0                     ; if (h >= d)
+    SUB     %r4,%r3,%r4                        ; h -= d
+    CMPB,=  %r31,%r0,$0000001A                 ; if (i)
+    COPY    %r0,%r10                           ; ret = 0
+    MTSARCM %r31                               ; i to shift
+    DEPD,Z  %r3,%sar,64,%r3                    ; d <<= i;
+    SUBI    64,%r31,%r19                       ; 64 - i; redundent
+    MTSAR   %r19                               ; (64 -i) to shift
+    SHRPD   %r4,%r5,%sar,%r4                   ; l>> (64-i)
+    MTSARCM %r31                               ; i to shift
+    DEPD,Z  %r5,%sar,64,%r5                    ; l <<= i;
+
+$0000001A
+    DEPDI,Z -1,31,32,%r19                      
+    EXTRD,U %r3,31,32,%r6                      ; dh=(d&0xfff)>>32
+    EXTRD,U %r3,63,32,%r8                      ; dl = d&0xffffff
+    LDO     2(%r0),%r9
+    STD    %r3,-280(%r30)                      ; "d" to stack
+
+$0000001C
+    DEPDI,Z -1,63,32,%r29                      ; 
+    EXTRD,U %r4,31,32,%r31                     ; h >> 32
+    CMPB,*=,N  %r31,%r6,$D2     	       ; if ((h>>32) != dh)(forward) div
+    COPY    %r4,%r26       
+    EXTRD,U %r4,31,32,%r25 
+    COPY    %r6,%r24      
+    .CALL   ;in=23,24,25,26;out=20,21,22,28,29; (MILLICALL)
+    B,L     $$div2U,%r2     
+    EXTRD,U %r6,31,32,%r23  
+    DEPD    %r28,31,32,%r29 
+$D2
+    STD     %r29,-272(%r30)                   ; q
+    AND     %r5,%r19,%r24                   ; t & 0xffffffff00000000;
+    EXTRD,U %r24,31,32,%r24                 ; ??? 
+    FLDD    -272(%r30),%fr7                 ; q
+    FLDD    -280(%r30),%fr8                 ; d
+    XMPYU   %fr8L,%fr7L,%fr10  
+    FSTD    %fr10,-256(%r30)   
+    XMPYU   %fr8L,%fr7R,%fr22  
+    FSTD    %fr22,-264(%r30)   
+    XMPYU   %fr8R,%fr7L,%fr11 
+    XMPYU   %fr8R,%fr7R,%fr23
+    FSTD    %fr11,-232(%r30)
+    FSTD    %fr23,-240(%r30)
+    LDD     -256(%r30),%r28
+    DEPD,Z  %r28,31,32,%r2 
+    LDD     -264(%r30),%r20
+    ADD,L   %r20,%r2,%r31   
+    LDD     -232(%r30),%r22 
+    DEPD,Z  %r22,31,32,%r22 
+    LDD     -240(%r30),%r21 
+    B       $00000024       ; enter loop  
+    ADD,L   %r21,%r22,%r23 
+
+$0000002A
+    LDO     -1(%r29),%r29   
+    SUB     %r23,%r8,%r23   
+$00000024
+    SUB     %r4,%r31,%r25   
+    AND     %r25,%r19,%r26  
+    CMPB,*<>,N      %r0,%r26,$00000046  ; (forward)
+    DEPD,Z  %r25,31,32,%r20 
+    OR      %r20,%r24,%r21  
+    CMPB,*<<,N  %r21,%r23,$0000002A ;(backward) 
+    SUB     %r31,%r6,%r31   
+;-------------Break path---------------------
+
+$00000046
+    DEPD,Z  %r23,31,32,%r25              ;tl
+    EXTRD,U %r23,31,32,%r26              ;t
+    AND     %r25,%r19,%r24               ;tl = (tl<<32)&0xfffffff0000000L
+    ADD,L   %r31,%r26,%r31               ;th += t; 
+    CMPCLR,*>>=     %r5,%r24,%r0         ;if (l<tl)
+    LDO     1(%r31),%r31                 ; th++;
+    CMPB,*<<=,N     %r31,%r4,$00000036   ;if (n < th) (forward)
+    LDO     -1(%r29),%r29                ;q--; 
+    ADD,L   %r4,%r3,%r4                  ;h += d;
+$00000036
+    ADDIB,=,N       -1,%r9,$D1 ;if (--count == 0) break (forward) 
+    SUB     %r5,%r24,%r28                ; l -= tl;
+    SUB     %r4,%r31,%r24                ; h -= th;
+    SHRPD   %r24,%r28,32,%r4             ; h = ((h<<32)|(l>>32));
+    DEPD,Z  %r29,31,32,%r10              ; ret = q<<32
+    b      $0000001C
+    DEPD,Z  %r28,31,32,%r5               ; l = l << 32 
+
+$D1
+    OR      %r10,%r29,%r28           ; ret |= q
+$D3
+    LDD     -368(%r30),%r2  
+$D0
+    LDD     -296(%r30),%r10 
+    LDD     -304(%r30),%r9  
+    LDD     -312(%r30),%r8  
+    LDD     -320(%r30),%r7  
+    LDD     -328(%r30),%r6  
+    LDD     -336(%r30),%r5  
+    LDD     -344(%r30),%r4  
+    BVE     (%r2)   
+        .EXIT
+    LDD,MB  -352(%r30),%r3 
+
+bn_div_err_case
+    MFIA    %r6     
+    ADDIL   L'bn_div_words-bn_div_err_case,%r6,%r1 
+    LDO     R'bn_div_words-bn_div_err_case(%r1),%r6  
+    ADDIL   LT'__iob,%r27,%r1       
+    LDD     RT'__iob(%r1),%r26      
+    ADDIL   L'C$4-bn_div_words,%r6,%r1    
+    LDO     R'C$4-bn_div_words(%r1),%r25  
+    LDO     64(%r26),%r26   
+    .CALL           ;in=24,25,26,29;out=28;
+    B,L     fprintf,%r2    
+    LDO     -48(%r30),%r29 
+    LDD     -288(%r30),%r27
+    .CALL           ;in=29;
+    B,L     abort,%r2      
+    LDO     -48(%r30),%r29 
+    LDD     -288(%r30),%r27
+    B       $D0         
+    LDD     -368(%r30),%r2  
+	.PROCEND	;in=24,25,26,29;out=28;
+
+;----------------------------------------------------------------------------
+;
+; Registers to hold 64-bit values to manipulate.  The "L" part
+; of the register corresponds to the upper 32-bits, while the "R"
+; part corresponds to the lower 32-bits
+; 
+; Note, that when using b6 and b7, the code must save these before
+; using them because they are callee save registers 
+; 
+;
+; Floating point registers to use to save values that
+; are manipulated.  These don't collide with ftemp1-6 and
+; are all caller save registers
+;
+a0        .reg %fr22
+a0L       .reg %fr22L
+a0R       .reg %fr22R
+
+a1        .reg %fr23
+a1L       .reg %fr23L
+a1R       .reg %fr23R
+
+a2        .reg %fr24
+a2L       .reg %fr24L
+a2R       .reg %fr24R
+
+a3        .reg %fr25
+a3L       .reg %fr25L
+a3R       .reg %fr25R
+
+a4        .reg %fr26
+a4L       .reg %fr26L
+a4R       .reg %fr26R
+
+a5        .reg %fr27
+a5L       .reg %fr27L
+a5R       .reg %fr27R
+
+a6        .reg %fr28
+a6L       .reg %fr28L
+a6R       .reg %fr28R
+
+a7        .reg %fr29
+a7L       .reg %fr29L
+a7R       .reg %fr29R
+
+b0        .reg %fr30
+b0L       .reg %fr30L
+b0R       .reg %fr30R
+
+b1        .reg %fr31
+b1L       .reg %fr31L
+b1R       .reg %fr31R
+
+;
+; Temporary floating point variables, these are all caller save
+; registers
+;
+ftemp1    .reg %fr4
+ftemp2    .reg %fr5
+ftemp3    .reg %fr6
+ftemp4    .reg %fr7
+
+;
+; The B set of registers when used.
+;
+
+b2        .reg %fr8
+b2L       .reg %fr8L
+b2R       .reg %fr8R
+
+b3        .reg %fr9
+b3L       .reg %fr9L
+b3R       .reg %fr9R
+
+b4        .reg %fr10
+b4L       .reg %fr10L
+b4R       .reg %fr10R
+
+b5        .reg %fr11
+b5L       .reg %fr11L
+b5R       .reg %fr11R
+
+b6        .reg %fr12
+b6L       .reg %fr12L
+b6R       .reg %fr12R
+
+b7        .reg %fr13
+b7L       .reg %fr13L
+b7R       .reg %fr13R
+
+c1           .reg %r21   ; only reg
+temp1        .reg %r20   ; only reg
+temp2        .reg %r19   ; only reg
+temp3        .reg %r31   ; only reg
+
+m1           .reg %r28   
+c2           .reg %r23   
+high_one     .reg %r1
+ht           .reg %r6
+lt           .reg %r5
+m            .reg %r4
+c3           .reg %r3
+
+SQR_ADD_C  .macro  A0L,A0R,C1,C2,C3
+    XMPYU   A0L,A0R,ftemp1       ; m
+    FSTD    ftemp1,-24(%sp)      ; store m
+
+    XMPYU   A0R,A0R,ftemp2       ; lt
+    FSTD    ftemp2,-16(%sp)      ; store lt
+
+    XMPYU   A0L,A0L,ftemp3       ; ht
+    FSTD    ftemp3,-8(%sp)       ; store ht
+
+    LDD     -24(%sp),m           ; load m
+    AND     m,high_mask,temp2    ; m & Mask
+    DEPD,Z  m,30,31,temp3        ; m << 32+1
+    LDD     -16(%sp),lt          ; lt
+
+    LDD     -8(%sp),ht           ; ht
+    EXTRD,U temp2,32,33,temp1    ; temp1 = m&Mask >> 32-1
+    ADD     temp3,lt,lt          ; lt = lt+m
+    ADD,L   ht,temp1,ht          ; ht += temp1
+    ADD,DC  ht,%r0,ht            ; ht++
+
+    ADD     C1,lt,C1             ; c1=c1+lt
+    ADD,DC  ht,%r0,ht            ; ht++
+
+    ADD     C2,ht,C2             ; c2=c2+ht
+    ADD,DC  C3,%r0,C3            ; c3++
+.endm
+
+SQR_ADD_C2 .macro  A0L,A0R,A1L,A1R,C1,C2,C3
+    XMPYU   A0L,A1R,ftemp1          ; m1 = bl*ht
+    FSTD    ftemp1,-16(%sp)         ;
+    XMPYU   A0R,A1L,ftemp2          ; m = bh*lt
+    FSTD    ftemp2,-8(%sp)          ;
+    XMPYU   A0R,A1R,ftemp3          ; lt = bl*lt
+    FSTD    ftemp3,-32(%sp)
+    XMPYU   A0L,A1L,ftemp4          ; ht = bh*ht
+    FSTD    ftemp4,-24(%sp)         ;
+
+    LDD     -8(%sp),m               ; r21 = m
+    LDD     -16(%sp),m1             ; r19 = m1
+    ADD,L   m,m1,m                  ; m+m1
+
+    DEPD,Z  m,31,32,temp3           ; (m+m1<<32)
+    LDD     -24(%sp),ht             ; r24 = ht
+
+    CMPCLR,*>>= m,m1,%r0            ; if (m < m1)
+    ADD,L   ht,high_one,ht          ; ht+=high_one
+
+    EXTRD,U m,31,32,temp1           ; m >> 32
+    LDD     -32(%sp),lt             ; lt
+    ADD,L   ht,temp1,ht             ; ht+= m>>32
+    ADD     lt,temp3,lt             ; lt = lt+m1
+    ADD,DC  ht,%r0,ht               ; ht++
+
+    ADD     ht,ht,ht                ; ht=ht+ht;
+    ADD,DC  C3,%r0,C3               ; add in carry (c3++)
+
+    ADD     lt,lt,lt                ; lt=lt+lt;
+    ADD,DC  ht,%r0,ht               ; add in carry (ht++)
+
+    ADD     C1,lt,C1                ; c1=c1+lt
+    ADD,DC,*NUV ht,%r0,ht           ; add in carry (ht++)
+    LDO     1(C3),C3              ; bump c3 if overflow,nullify otherwise
+
+    ADD     C2,ht,C2                ; c2 = c2 + ht
+    ADD,DC  C3,%r0,C3             ; add in carry (c3++)
+.endm
+
+;
+;void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
+; arg0 = r_ptr
+; arg1 = a_ptr
+;
+
+bn_sqr_comba8
+	.PROC
+	.CALLINFO FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+	.EXPORT	bn_sqr_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+    .ENTRY
+	.align 64
+
+    STD     %r3,0(%sp)          ; save r3
+    STD     %r4,8(%sp)          ; save r4
+    STD     %r5,16(%sp)         ; save r5
+    STD     %r6,24(%sp)         ; save r6
+
+	;
+	; Zero out carries
+	;
+	COPY     %r0,c1
+	COPY     %r0,c2
+	COPY     %r0,c3
+
+	LDO      128(%sp),%sp       ; bump stack
+    DEPDI,Z -1,32,33,high_mask   ; Create Mask 0xffffffff80000000L
+    DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
+
+	;
+	; Load up all of the values we are going to use
+	;
+    FLDD     0(a_ptr),a0       
+    FLDD     8(a_ptr),a1       
+    FLDD    16(a_ptr),a2       
+    FLDD    24(a_ptr),a3       
+    FLDD    32(a_ptr),a4       
+    FLDD    40(a_ptr),a5       
+    FLDD    48(a_ptr),a6       
+    FLDD    56(a_ptr),a7       
+
+	SQR_ADD_C a0L,a0R,c1,c2,c3
+	STD     c1,0(r_ptr)          ; r[0] = c1;
+	COPY    %r0,c1
+
+	SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1
+	STD     c2,8(r_ptr)          ; r[1] = c2;
+	COPY    %r0,c2
+
+	SQR_ADD_C a1L,a1R,c3,c1,c2
+	SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2
+	STD     c3,16(r_ptr)            ; r[2] = c3;
+	COPY    %r0,c3
+
+	SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3
+	SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3
+	STD     c1,24(r_ptr)           ; r[3] = c1;
+	COPY    %r0,c1
+
+	SQR_ADD_C a2L,a2R,c2,c3,c1
+	SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1
+	SQR_ADD_C2 a4L,a4R,a0L,a0R,c2,c3,c1
+	STD     c2,32(r_ptr)          ; r[4] = c2;
+	COPY    %r0,c2
+
+	SQR_ADD_C2 a5L,a5R,a0L,a0R,c3,c1,c2
+	SQR_ADD_C2 a4L,a4R,a1L,a1R,c3,c1,c2
+	SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2
+	STD     c3,40(r_ptr)          ; r[5] = c3;
+	COPY    %r0,c3
+
+	SQR_ADD_C a3L,a3R,c1,c2,c3
+	SQR_ADD_C2 a4L,a4R,a2L,a2R,c1,c2,c3
+	SQR_ADD_C2 a5L,a5R,a1L,a1R,c1,c2,c3
+	SQR_ADD_C2 a6L,a6R,a0L,a0R,c1,c2,c3
+	STD     c1,48(r_ptr)          ; r[6] = c1;
+	COPY    %r0,c1
+
+	SQR_ADD_C2 a7L,a7R,a0L,a0R,c2,c3,c1
+	SQR_ADD_C2 a6L,a6R,a1L,a1R,c2,c3,c1
+	SQR_ADD_C2 a5L,a5R,a2L,a2R,c2,c3,c1
+	SQR_ADD_C2 a4L,a4R,a3L,a3R,c2,c3,c1
+	STD     c2,56(r_ptr)          ; r[7] = c2;
+	COPY    %r0,c2
+
+	SQR_ADD_C a4L,a4R,c3,c1,c2
+	SQR_ADD_C2 a5L,a5R,a3L,a3R,c3,c1,c2
+	SQR_ADD_C2 a6L,a6R,a2L,a2R,c3,c1,c2
+	SQR_ADD_C2 a7L,a7R,a1L,a1R,c3,c1,c2
+	STD     c3,64(r_ptr)          ; r[8] = c3;
+	COPY    %r0,c3
+
+	SQR_ADD_C2 a7L,a7R,a2L,a2R,c1,c2,c3
+	SQR_ADD_C2 a6L,a6R,a3L,a3R,c1,c2,c3
+	SQR_ADD_C2 a5L,a5R,a4L,a4R,c1,c2,c3
+	STD     c1,72(r_ptr)          ; r[9] = c1;
+	COPY    %r0,c1
+
+	SQR_ADD_C a5L,a5R,c2,c3,c1
+	SQR_ADD_C2 a6L,a6R,a4L,a4R,c2,c3,c1
+	SQR_ADD_C2 a7L,a7R,a3L,a3R,c2,c3,c1
+	STD     c2,80(r_ptr)          ; r[10] = c2;
+	COPY    %r0,c2
+
+	SQR_ADD_C2 a7L,a7R,a4L,a4R,c3,c1,c2
+	SQR_ADD_C2 a6L,a6R,a5L,a5R,c3,c1,c2
+	STD     c3,88(r_ptr)          ; r[11] = c3;
+	COPY    %r0,c3
+	
+	SQR_ADD_C a6L,a6R,c1,c2,c3
+	SQR_ADD_C2 a7L,a7R,a5L,a5R,c1,c2,c3
+	STD     c1,96(r_ptr)          ; r[12] = c1;
+	COPY    %r0,c1
+
+	SQR_ADD_C2 a7L,a7R,a6L,a6R,c2,c3,c1
+	STD     c2,104(r_ptr)         ; r[13] = c2;
+	COPY    %r0,c2
+
+	SQR_ADD_C a7L,a7R,c3,c1,c2
+	STD     c3, 112(r_ptr)       ; r[14] = c3
+	STD     c1, 120(r_ptr)       ; r[15] = c1
+
+    .EXIT
+    LDD     -104(%sp),%r6        ; restore r6
+    LDD     -112(%sp),%r5        ; restore r5
+    LDD     -120(%sp),%r4        ; restore r4
+    BVE     (%rp)
+    LDD,MB  -128(%sp),%r3
+
+	.PROCEND	
+
+;-----------------------------------------------------------------------------
+;
+;void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
+; arg0 = r_ptr
+; arg1 = a_ptr
+;
+
+bn_sqr_comba4
+	.proc
+	.callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+	.EXPORT	bn_sqr_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+    .entry
+	.align 64
+    STD     %r3,0(%sp)          ; save r3
+    STD     %r4,8(%sp)          ; save r4
+    STD     %r5,16(%sp)         ; save r5
+    STD     %r6,24(%sp)         ; save r6
+
+	;
+	; Zero out carries
+	;
+	COPY     %r0,c1
+	COPY     %r0,c2
+	COPY     %r0,c3
+
+	LDO      128(%sp),%sp       ; bump stack
+    DEPDI,Z -1,32,33,high_mask   ; Create Mask 0xffffffff80000000L
+    DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
+
+	;
+	; Load up all of the values we are going to use
+	;
+    FLDD     0(a_ptr),a0       
+    FLDD     8(a_ptr),a1       
+    FLDD    16(a_ptr),a2       
+    FLDD    24(a_ptr),a3       
+    FLDD    32(a_ptr),a4       
+    FLDD    40(a_ptr),a5       
+    FLDD    48(a_ptr),a6       
+    FLDD    56(a_ptr),a7       
+
+	SQR_ADD_C a0L,a0R,c1,c2,c3
+
+	STD     c1,0(r_ptr)          ; r[0] = c1;
+	COPY    %r0,c1
+
+	SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1
+
+	STD     c2,8(r_ptr)          ; r[1] = c2;
+	COPY    %r0,c2
+
+	SQR_ADD_C a1L,a1R,c3,c1,c2
+	SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2
+
+	STD     c3,16(r_ptr)            ; r[2] = c3;
+	COPY    %r0,c3
+
+	SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3
+	SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3
+
+	STD     c1,24(r_ptr)           ; r[3] = c1;
+	COPY    %r0,c1
+
+	SQR_ADD_C a2L,a2R,c2,c3,c1
+	SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1
+
+	STD     c2,32(r_ptr)           ; r[4] = c2;
+	COPY    %r0,c2
+
+	SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2
+	STD     c3,40(r_ptr)           ; r[5] = c3;
+	COPY    %r0,c3
+
+	SQR_ADD_C a3L,a3R,c1,c2,c3
+	STD     c1,48(r_ptr)           ; r[6] = c1;
+	STD     c2,56(r_ptr)           ; r[7] = c2;
+
+    .EXIT
+    LDD     -104(%sp),%r6        ; restore r6
+    LDD     -112(%sp),%r5        ; restore r5
+    LDD     -120(%sp),%r4        ; restore r4
+    BVE     (%rp)
+    LDD,MB  -128(%sp),%r3
+
+	.PROCEND	
+
+
+;---------------------------------------------------------------------------
+
+MUL_ADD_C  .macro  A0L,A0R,B0L,B0R,C1,C2,C3
+    XMPYU   A0L,B0R,ftemp1        ; m1 = bl*ht
+    FSTD    ftemp1,-16(%sp)       ;
+    XMPYU   A0R,B0L,ftemp2        ; m = bh*lt
+    FSTD    ftemp2,-8(%sp)        ;
+    XMPYU   A0R,B0R,ftemp3        ; lt = bl*lt
+    FSTD    ftemp3,-32(%sp)
+    XMPYU   A0L,B0L,ftemp4        ; ht = bh*ht
+    FSTD    ftemp4,-24(%sp)       ;
+
+    LDD     -8(%sp),m             ; r21 = m
+    LDD     -16(%sp),m1           ; r19 = m1
+    ADD,L   m,m1,m                ; m+m1
+
+    DEPD,Z  m,31,32,temp3         ; (m+m1<<32)
+    LDD     -24(%sp),ht           ; r24 = ht
+
+    CMPCLR,*>>= m,m1,%r0          ; if (m < m1)
+    ADD,L   ht,high_one,ht        ; ht+=high_one
+
+    EXTRD,U m,31,32,temp1         ; m >> 32
+    LDD     -32(%sp),lt           ; lt
+    ADD,L   ht,temp1,ht           ; ht+= m>>32
+    ADD     lt,temp3,lt           ; lt = lt+m1
+    ADD,DC  ht,%r0,ht             ; ht++
+
+    ADD     C1,lt,C1              ; c1=c1+lt
+    ADD,DC  ht,%r0,ht             ; bump c3 if overflow,nullify otherwise
+
+    ADD     C2,ht,C2              ; c2 = c2 + ht
+    ADD,DC  C3,%r0,C3             ; add in carry (c3++)
+.endm
+
+
+;
+;void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+; arg0 = r_ptr
+; arg1 = a_ptr
+; arg2 = b_ptr
+;
+
+bn_mul_comba8
+	.proc
+	.callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+	.EXPORT	bn_mul_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+    .entry
+	.align 64
+
+    STD     %r3,0(%sp)          ; save r3
+    STD     %r4,8(%sp)          ; save r4
+    STD     %r5,16(%sp)         ; save r5
+    STD     %r6,24(%sp)         ; save r6
+    FSTD    %fr12,32(%sp)       ; save r6
+    FSTD    %fr13,40(%sp)       ; save r7
+
+	;
+	; Zero out carries
+	;
+	COPY     %r0,c1
+	COPY     %r0,c2
+	COPY     %r0,c3
+
+	LDO      128(%sp),%sp       ; bump stack
+    DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
+
+	;
+	; Load up all of the values we are going to use
+	;
+    FLDD      0(a_ptr),a0       
+    FLDD      8(a_ptr),a1       
+    FLDD     16(a_ptr),a2       
+    FLDD     24(a_ptr),a3       
+    FLDD     32(a_ptr),a4       
+    FLDD     40(a_ptr),a5       
+    FLDD     48(a_ptr),a6       
+    FLDD     56(a_ptr),a7       
+
+    FLDD      0(b_ptr),b0       
+    FLDD      8(b_ptr),b1       
+    FLDD     16(b_ptr),b2       
+    FLDD     24(b_ptr),b3       
+    FLDD     32(b_ptr),b4       
+    FLDD     40(b_ptr),b5       
+    FLDD     48(b_ptr),b6       
+    FLDD     56(b_ptr),b7       
+
+	MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3
+	STD       c1,0(r_ptr)
+	COPY      %r0,c1
+
+	MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1
+	MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1
+	STD       c2,8(r_ptr)
+	COPY      %r0,c2
+
+	MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2
+	MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2
+	MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2
+	STD       c3,16(r_ptr)
+	COPY      %r0,c3
+
+	MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3
+	MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3
+	MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3
+	MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3
+	STD       c1,24(r_ptr)
+	COPY      %r0,c1
+
+	MUL_ADD_C a4L,a4R,b0L,b0R,c2,c3,c1
+	MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1
+	MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1
+	MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1
+	MUL_ADD_C a0L,a0R,b4L,b4R,c2,c3,c1
+	STD       c2,32(r_ptr)
+	COPY      %r0,c2
+
+	MUL_ADD_C a0L,a0R,b5L,b5R,c3,c1,c2
+	MUL_ADD_C a1L,a1R,b4L,b4R,c3,c1,c2
+	MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2
+	MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2
+	MUL_ADD_C a4L,a4R,b1L,b1R,c3,c1,c2
+	MUL_ADD_C a5L,a5R,b0L,b0R,c3,c1,c2
+	STD       c3,40(r_ptr)
+	COPY      %r0,c3
+
+	MUL_ADD_C a6L,a6R,b0L,b0R,c1,c2,c3
+	MUL_ADD_C a5L,a5R,b1L,b1R,c1,c2,c3
+	MUL_ADD_C a4L,a4R,b2L,b2R,c1,c2,c3
+	MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3
+	MUL_ADD_C a2L,a2R,b4L,b4R,c1,c2,c3
+	MUL_ADD_C a1L,a1R,b5L,b5R,c1,c2,c3
+	MUL_ADD_C a0L,a0R,b6L,b6R,c1,c2,c3
+	STD       c1,48(r_ptr)
+	COPY      %r0,c1
+	
+	MUL_ADD_C a0L,a0R,b7L,b7R,c2,c3,c1
+	MUL_ADD_C a1L,a1R,b6L,b6R,c2,c3,c1
+	MUL_ADD_C a2L,a2R,b5L,b5R,c2,c3,c1
+	MUL_ADD_C a3L,a3R,b4L,b4R,c2,c3,c1
+	MUL_ADD_C a4L,a4R,b3L,b3R,c2,c3,c1
+	MUL_ADD_C a5L,a5R,b2L,b2R,c2,c3,c1
+	MUL_ADD_C a6L,a6R,b1L,b1R,c2,c3,c1
+	MUL_ADD_C a7L,a7R,b0L,b0R,c2,c3,c1
+	STD       c2,56(r_ptr)
+	COPY      %r0,c2
+
+	MUL_ADD_C a7L,a7R,b1L,b1R,c3,c1,c2
+	MUL_ADD_C a6L,a6R,b2L,b2R,c3,c1,c2
+	MUL_ADD_C a5L,a5R,b3L,b3R,c3,c1,c2
+	MUL_ADD_C a4L,a4R,b4L,b4R,c3,c1,c2
+	MUL_ADD_C a3L,a3R,b5L,b5R,c3,c1,c2
+	MUL_ADD_C a2L,a2R,b6L,b6R,c3,c1,c2
+	MUL_ADD_C a1L,a1R,b7L,b7R,c3,c1,c2
+	STD       c3,64(r_ptr)
+	COPY      %r0,c3
+
+	MUL_ADD_C a2L,a2R,b7L,b7R,c1,c2,c3
+	MUL_ADD_C a3L,a3R,b6L,b6R,c1,c2,c3
+	MUL_ADD_C a4L,a4R,b5L,b5R,c1,c2,c3
+	MUL_ADD_C a5L,a5R,b4L,b4R,c1,c2,c3
+	MUL_ADD_C a6L,a6R,b3L,b3R,c1,c2,c3
+	MUL_ADD_C a7L,a7R,b2L,b2R,c1,c2,c3
+	STD       c1,72(r_ptr)
+	COPY      %r0,c1
+
+	MUL_ADD_C a7L,a7R,b3L,b3R,c2,c3,c1
+	MUL_ADD_C a6L,a6R,b4L,b4R,c2,c3,c1
+	MUL_ADD_C a5L,a5R,b5L,b5R,c2,c3,c1
+	MUL_ADD_C a4L,a4R,b6L,b6R,c2,c3,c1
+	MUL_ADD_C a3L,a3R,b7L,b7R,c2,c3,c1
+	STD       c2,80(r_ptr)
+	COPY      %r0,c2
+
+	MUL_ADD_C a4L,a4R,b7L,b7R,c3,c1,c2
+	MUL_ADD_C a5L,a5R,b6L,b6R,c3,c1,c2
+	MUL_ADD_C a6L,a6R,b5L,b5R,c3,c1,c2
+	MUL_ADD_C a7L,a7R,b4L,b4R,c3,c1,c2
+	STD       c3,88(r_ptr)
+	COPY      %r0,c3
+
+	MUL_ADD_C a7L,a7R,b5L,b5R,c1,c2,c3
+	MUL_ADD_C a6L,a6R,b6L,b6R,c1,c2,c3
+	MUL_ADD_C a5L,a5R,b7L,b7R,c1,c2,c3
+	STD       c1,96(r_ptr)
+	COPY      %r0,c1
+
+	MUL_ADD_C a6L,a6R,b7L,b7R,c2,c3,c1
+	MUL_ADD_C a7L,a7R,b6L,b6R,c2,c3,c1
+	STD       c2,104(r_ptr)
+	COPY      %r0,c2
+
+	MUL_ADD_C a7L,a7R,b7L,b7R,c3,c1,c2
+	STD       c3,112(r_ptr)
+	STD       c1,120(r_ptr)
+
+    .EXIT
+    FLDD    -88(%sp),%fr13 
+    FLDD    -96(%sp),%fr12 
+    LDD     -104(%sp),%r6        ; restore r6
+    LDD     -112(%sp),%r5        ; restore r5
+    LDD     -120(%sp),%r4        ; restore r4
+    BVE     (%rp)
+    LDD,MB  -128(%sp),%r3
+
+	.PROCEND	
+
+;-----------------------------------------------------------------------------
+;
+;void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+; arg0 = r_ptr
+; arg1 = a_ptr
+; arg2 = b_ptr
+;
+
+bn_mul_comba4
+	.proc
+	.callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+	.EXPORT	bn_mul_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+    .entry
+	.align 64
+
+    STD     %r3,0(%sp)          ; save r3
+    STD     %r4,8(%sp)          ; save r4
+    STD     %r5,16(%sp)         ; save r5
+    STD     %r6,24(%sp)         ; save r6
+    FSTD    %fr12,32(%sp)       ; save r6
+    FSTD    %fr13,40(%sp)       ; save r7
+
+	;
+	; Zero out carries
+	;
+	COPY     %r0,c1
+	COPY     %r0,c2
+	COPY     %r0,c3
+
+	LDO      128(%sp),%sp       ; bump stack
+    DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
+
+	;
+	; Load up all of the values we are going to use
+	;
+    FLDD      0(a_ptr),a0       
+    FLDD      8(a_ptr),a1       
+    FLDD     16(a_ptr),a2       
+    FLDD     24(a_ptr),a3       
+
+    FLDD      0(b_ptr),b0       
+    FLDD      8(b_ptr),b1       
+    FLDD     16(b_ptr),b2       
+    FLDD     24(b_ptr),b3       
+
+	MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3
+	STD       c1,0(r_ptr)
+	COPY      %r0,c1
+
+	MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1
+	MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1
+	STD       c2,8(r_ptr)
+	COPY      %r0,c2
+
+	MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2
+	MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2
+	MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2
+	STD       c3,16(r_ptr)
+	COPY      %r0,c3
+
+	MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3
+	MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3
+	MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3
+	MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3
+	STD       c1,24(r_ptr)
+	COPY      %r0,c1
+
+	MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1
+	MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1
+	MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1
+	STD       c2,32(r_ptr)
+	COPY      %r0,c2
+
+	MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2
+	MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2
+	STD       c3,40(r_ptr)
+	COPY      %r0,c3
+
+	MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3
+	STD       c1,48(r_ptr)
+	STD       c2,56(r_ptr)
+
+    .EXIT
+    FLDD    -88(%sp),%fr13 
+    FLDD    -96(%sp),%fr12 
+    LDD     -104(%sp),%r6        ; restore r6
+    LDD     -112(%sp),%r5        ; restore r5
+    LDD     -120(%sp),%r4        ; restore r4
+    BVE     (%rp)
+    LDD,MB  -128(%sp),%r3
+
+	.PROCEND	
+
+
+	.SPACE	$TEXT$
+	.SUBSPA	$CODE$
+	.SPACE	$PRIVATE$,SORT=16
+	.IMPORT	$global$,DATA
+	.SPACE	$TEXT$
+	.SUBSPA	$CODE$
+	.SUBSPA	$LIT$,ACCESS=0x2c
+C$4
+	.ALIGN	8
+	.STRINGZ	"Division would overflow (%d)\n"
+	.END
diff --git a/openssl/crypto/bn/asm/ppc-mont.pl b/openssl/crypto/bn/asm/ppc-mont.pl
new file mode 100644
index 0000000..7849eae
--- /dev/null
+++ b/openssl/crypto/bn/asm/ppc-mont.pl
@@ -0,0 +1,323 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# April 2006
+
+# "Teaser" Montgomery multiplication module for PowerPC. It's possible
+# to gain a bit more by modulo-scheduling outer loop, then dedicated
+# squaring procedure should give further 20% and code can be adapted
+# for 32-bit application running on 64-bit CPU. As for the latter.
+# It won't be able to achieve "native" 64-bit performance, because in
+# 32-bit application context every addc instruction will have to be
+# expanded as addc, twice right shift by 32 and finally adde, etc.
+# So far RSA *sign* performance improvement over pre-bn_mul_mont asm
+# for 64-bit application running on PPC970/G5 is:
+#
+# 512-bit	+65%	
+# 1024-bit	+35%
+# 2048-bit	+18%
+# 4096-bit	+4%
+
+$flavour = shift;
+
+if ($flavour =~ /32/) {
+	$BITS=	32;
+	$BNSZ=	$BITS/8;
+	$SIZE_T=4;
+	$RZONE=	224;
+	$FRAME=	$SIZE_T*16;
+
+	$LD=	"lwz";		# load
+	$LDU=	"lwzu";		# load and update
+	$LDX=	"lwzx";		# load indexed
+	$ST=	"stw";		# store
+	$STU=	"stwu";		# store and update
+	$STX=	"stwx";		# store indexed
+	$STUX=	"stwux";	# store indexed and update
+	$UMULL=	"mullw";	# unsigned multiply low
+	$UMULH=	"mulhwu";	# unsigned multiply high
+	$UCMP=	"cmplw";	# unsigned compare
+	$SHRI=	"srwi";		# unsigned shift right by immediate	
+	$PUSH=	$ST;
+	$POP=	$LD;
+} elsif ($flavour =~ /64/) {
+	$BITS=	64;
+	$BNSZ=	$BITS/8;
+	$SIZE_T=8;
+	$RZONE=	288;
+	$FRAME=	$SIZE_T*16;
+
+	# same as above, but 64-bit mnemonics...
+	$LD=	"ld";		# load
+	$LDU=	"ldu";		# load and update
+	$LDX=	"ldx";		# load indexed
+	$ST=	"std";		# store
+	$STU=	"stdu";		# store and update
+	$STX=	"stdx";		# store indexed
+	$STUX=	"stdux";	# store indexed and update
+	$UMULL=	"mulld";	# unsigned multiply low
+	$UMULH=	"mulhdu";	# unsigned multiply high
+	$UCMP=	"cmpld";	# unsigned compare
+	$SHRI=	"srdi";		# unsigned shift right by immediate	
+	$PUSH=	$ST;
+	$POP=	$LD;
+} else { die "nonsense $flavour"; }
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
+
+$sp="r1";
+$toc="r2";
+$rp="r3";	$ovf="r3";
+$ap="r4";
+$bp="r5";
+$np="r6";
+$n0="r7";
+$num="r8";
+$rp="r9";	# $rp is reassigned
+$aj="r10";
+$nj="r11";
+$tj="r12";
+# non-volatile registers
+$i="r14";
+$j="r15";
+$tp="r16";
+$m0="r17";
+$m1="r18";
+$lo0="r19";
+$hi0="r20";
+$lo1="r21";
+$hi1="r22";
+$alo="r23";
+$ahi="r24";
+$nlo="r25";
+#
+$nhi="r0";
+
+$code=<<___;
+.machine "any"
+.text
+
+.globl	.bn_mul_mont
+.align	4
+.bn_mul_mont:
+	cmpwi	$num,4
+	mr	$rp,r3		; $rp is reassigned
+	li	r3,0
+	bltlr
+
+	slwi	$num,$num,`log($BNSZ)/log(2)`
+	li	$tj,-4096
+	addi	$ovf,$num,`$FRAME+$RZONE`
+	subf	$ovf,$ovf,$sp	; $sp-$ovf
+	and	$ovf,$ovf,$tj	; minimize TLB usage
+	subf	$ovf,$sp,$ovf	; $ovf-$sp
+	srwi	$num,$num,`log($BNSZ)/log(2)`
+	$STUX	$sp,$sp,$ovf
+
+	$PUSH	r14,`4*$SIZE_T`($sp)
+	$PUSH	r15,`5*$SIZE_T`($sp)
+	$PUSH	r16,`6*$SIZE_T`($sp)
+	$PUSH	r17,`7*$SIZE_T`($sp)
+	$PUSH	r18,`8*$SIZE_T`($sp)
+	$PUSH	r19,`9*$SIZE_T`($sp)
+	$PUSH	r20,`10*$SIZE_T`($sp)
+	$PUSH	r21,`11*$SIZE_T`($sp)
+	$PUSH	r22,`12*$SIZE_T`($sp)
+	$PUSH	r23,`13*$SIZE_T`($sp)
+	$PUSH	r24,`14*$SIZE_T`($sp)
+	$PUSH	r25,`15*$SIZE_T`($sp)
+
+	$LD	$n0,0($n0)	; pull n0[0] value
+	addi	$num,$num,-2	; adjust $num for counter register
+
+	$LD	$m0,0($bp)	; m0=bp[0]
+	$LD	$aj,0($ap)	; ap[0]
+	addi	$tp,$sp,$FRAME
+	$UMULL	$lo0,$aj,$m0	; ap[0]*bp[0]
+	$UMULH	$hi0,$aj,$m0
+
+	$LD	$aj,$BNSZ($ap)	; ap[1]
+	$LD	$nj,0($np)	; np[0]
+
+	$UMULL	$m1,$lo0,$n0	; "tp[0]"*n0
+
+	$UMULL	$alo,$aj,$m0	; ap[1]*bp[0]
+	$UMULH	$ahi,$aj,$m0
+
+	$UMULL	$lo1,$nj,$m1	; np[0]*m1
+	$UMULH	$hi1,$nj,$m1
+	$LD	$nj,$BNSZ($np)	; np[1]
+	addc	$lo1,$lo1,$lo0
+	addze	$hi1,$hi1
+
+	$UMULL	$nlo,$nj,$m1	; np[1]*m1
+	$UMULH	$nhi,$nj,$m1
+
+	mtctr	$num
+	li	$j,`2*$BNSZ`
+.align	4
+L1st:
+	$LDX	$aj,$ap,$j	; ap[j]
+	addc	$lo0,$alo,$hi0
+	$LDX	$nj,$np,$j	; np[j]
+	addze	$hi0,$ahi
+	$UMULL	$alo,$aj,$m0	; ap[j]*bp[0]
+	addc	$lo1,$nlo,$hi1
+	$UMULH	$ahi,$aj,$m0
+	addze	$hi1,$nhi
+	$UMULL	$nlo,$nj,$m1	; np[j]*m1
+	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[0]
+	$UMULH	$nhi,$nj,$m1
+	addze	$hi1,$hi1
+	$ST	$lo1,0($tp)	; tp[j-1]
+
+	addi	$j,$j,$BNSZ	; j++
+	addi	$tp,$tp,$BNSZ	; tp++
+	bdnz-	L1st
+;L1st
+	addc	$lo0,$alo,$hi0
+	addze	$hi0,$ahi
+
+	addc	$lo1,$nlo,$hi1
+	addze	$hi1,$nhi
+	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[0]
+	addze	$hi1,$hi1
+	$ST	$lo1,0($tp)	; tp[j-1]
+
+	li	$ovf,0
+	addc	$hi1,$hi1,$hi0
+	addze	$ovf,$ovf	; upmost overflow bit
+	$ST	$hi1,$BNSZ($tp)
+
+	li	$i,$BNSZ
+.align	4
+Louter:
+	$LDX	$m0,$bp,$i	; m0=bp[i]
+	$LD	$aj,0($ap)	; ap[0]
+	addi	$tp,$sp,$FRAME
+	$LD	$tj,$FRAME($sp)	; tp[0]
+	$UMULL	$lo0,$aj,$m0	; ap[0]*bp[i]
+	$UMULH	$hi0,$aj,$m0
+	$LD	$aj,$BNSZ($ap)	; ap[1]
+	$LD	$nj,0($np)	; np[0]
+	addc	$lo0,$lo0,$tj	; ap[0]*bp[i]+tp[0]
+	$UMULL	$alo,$aj,$m0	; ap[j]*bp[i]
+	addze	$hi0,$hi0
+	$UMULL	$m1,$lo0,$n0	; tp[0]*n0
+	$UMULH	$ahi,$aj,$m0
+	$UMULL	$lo1,$nj,$m1	; np[0]*m1
+	$UMULH	$hi1,$nj,$m1
+	$LD	$nj,$BNSZ($np)	; np[1]
+	addc	$lo1,$lo1,$lo0
+	$UMULL	$nlo,$nj,$m1	; np[1]*m1
+	addze	$hi1,$hi1
+	$UMULH	$nhi,$nj,$m1
+
+	mtctr	$num
+	li	$j,`2*$BNSZ`
+.align	4
+Linner:
+	$LDX	$aj,$ap,$j	; ap[j]
+	addc	$lo0,$alo,$hi0
+	$LD	$tj,$BNSZ($tp)	; tp[j]
+	addze	$hi0,$ahi
+	$LDX	$nj,$np,$j	; np[j]
+	addc	$lo1,$nlo,$hi1
+	$UMULL	$alo,$aj,$m0	; ap[j]*bp[i]
+	addze	$hi1,$nhi
+	$UMULH	$ahi,$aj,$m0
+	addc	$lo0,$lo0,$tj	; ap[j]*bp[i]+tp[j]
+	$UMULL	$nlo,$nj,$m1	; np[j]*m1
+	addze	$hi0,$hi0
+	$UMULH	$nhi,$nj,$m1
+	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[i]+tp[j]
+	addi	$j,$j,$BNSZ	; j++
+	addze	$hi1,$hi1
+	$ST	$lo1,0($tp)	; tp[j-1]
+	addi	$tp,$tp,$BNSZ	; tp++
+	bdnz-	Linner
+;Linner
+	$LD	$tj,$BNSZ($tp)	; tp[j]
+	addc	$lo0,$alo,$hi0
+	addze	$hi0,$ahi
+	addc	$lo0,$lo0,$tj	; ap[j]*bp[i]+tp[j]
+	addze	$hi0,$hi0
+
+	addc	$lo1,$nlo,$hi1
+	addze	$hi1,$nhi
+	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[i]+tp[j]
+	addze	$hi1,$hi1
+	$ST	$lo1,0($tp)	; tp[j-1]
+
+	addic	$ovf,$ovf,-1	; move upmost overflow to XER[CA]
+	li	$ovf,0
+	adde	$hi1,$hi1,$hi0
+	addze	$ovf,$ovf
+	$ST	$hi1,$BNSZ($tp)
+;
+	slwi	$tj,$num,`log($BNSZ)/log(2)`
+	$UCMP	$i,$tj
+	addi	$i,$i,$BNSZ
+	ble-	Louter
+
+	addi	$num,$num,2	; restore $num
+	subfc	$j,$j,$j	; j=0 and "clear" XER[CA]
+	addi	$tp,$sp,$FRAME
+	mtctr	$num
+
+.align	4
+Lsub:	$LDX	$tj,$tp,$j
+	$LDX	$nj,$np,$j
+	subfe	$aj,$nj,$tj	; tp[j]-np[j]
+	$STX	$aj,$rp,$j
+	addi	$j,$j,$BNSZ
+	bdnz-	Lsub
+
+	li	$j,0
+	mtctr	$num
+	subfe	$ovf,$j,$ovf	; handle upmost overflow bit
+	and	$ap,$tp,$ovf
+	andc	$np,$rp,$ovf
+	or	$ap,$ap,$np	; ap=borrow?tp:rp
+
+.align	4
+Lcopy:				; copy or in-place refresh
+	$LDX	$tj,$ap,$j
+	$STX	$tj,$rp,$j
+	$STX	$j,$tp,$j	; zap at once
+	addi	$j,$j,$BNSZ
+	bdnz-	Lcopy
+
+	$POP	r14,`4*$SIZE_T`($sp)
+	$POP	r15,`5*$SIZE_T`($sp)
+	$POP	r16,`6*$SIZE_T`($sp)
+	$POP	r17,`7*$SIZE_T`($sp)
+	$POP	r18,`8*$SIZE_T`($sp)
+	$POP	r19,`9*$SIZE_T`($sp)
+	$POP	r20,`10*$SIZE_T`($sp)
+	$POP	r21,`11*$SIZE_T`($sp)
+	$POP	r22,`12*$SIZE_T`($sp)
+	$POP	r23,`13*$SIZE_T`($sp)
+	$POP	r24,`14*$SIZE_T`($sp)
+	$POP	r25,`15*$SIZE_T`($sp)
+	$POP	$sp,0($sp)
+	li	r3,1
+	blr
+	.long	0
+.asciz  "Montgomery Multiplication for PPC, CRYPTOGAMS by <appro\@fy.chalmers.se>"
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/bn/asm/ppc.pl b/openssl/crypto/bn/asm/ppc.pl
new file mode 100644
index 0000000..f409317
--- /dev/null
+++ b/openssl/crypto/bn/asm/ppc.pl
@@ -0,0 +1,1981 @@
+#!/usr/bin/env perl
+#
+# Implemented as a Perl wrapper as we want to support several different
+# architectures with single file. We pick up the target based on the
+# file name we are asked to generate.
+#
+# It should be noted though that this perl code is nothing like
+# <openssl>/crypto/perlasm/x86*. In this case perl is used pretty much
+# as pre-processor to cover for platform differences in name decoration,
+# linker tables, 32-/64-bit instruction sets...
+#
+# As you might know there're several PowerPC ABI in use. Most notably
+# Linux and AIX use different 32-bit ABIs. Good news are that these ABIs
+# are similar enough to implement leaf(!) functions, which would be ABI
+# neutral. And that's what you find here: ABI neutral leaf functions.
+# In case you wonder what that is...
+#
+#       AIX performance
+#
+#	MEASUREMENTS WITH cc ON a 200 MhZ PowerPC 604e.
+#
+#	The following is the performance of 32-bit compiler
+#	generated code:
+#
+#	OpenSSL 0.9.6c 21 dec 2001
+#	built on: Tue Jun 11 11:06:51 EDT 2002
+#	options:bn(64,32) ...
+#compiler: cc -DTHREADS  -DAIX -DB_ENDIAN -DBN_LLONG -O3
+#                  sign    verify    sign/s verify/s
+#rsa  512 bits   0.0098s   0.0009s    102.0   1170.6
+#rsa 1024 bits   0.0507s   0.0026s     19.7    387.5
+#rsa 2048 bits   0.3036s   0.0085s      3.3    117.1
+#rsa 4096 bits   2.0040s   0.0299s      0.5     33.4
+#dsa  512 bits   0.0087s   0.0106s    114.3     94.5
+#dsa 1024 bits   0.0256s   0.0313s     39.0     32.0	
+#
+#	Same bechmark with this assembler code:
+#
+#rsa  512 bits   0.0056s   0.0005s    178.6   2049.2
+#rsa 1024 bits   0.0283s   0.0015s     35.3    674.1
+#rsa 2048 bits   0.1744s   0.0050s      5.7    201.2
+#rsa 4096 bits   1.1644s   0.0179s      0.9     55.7
+#dsa  512 bits   0.0052s   0.0062s    191.6    162.0
+#dsa 1024 bits   0.0149s   0.0180s     67.0     55.5
+#
+#	Number of operations increases by at almost 75%
+#
+#	Here are performance numbers for 64-bit compiler
+#	generated code:
+#
+#	OpenSSL 0.9.6g [engine] 9 Aug 2002
+#	built on: Fri Apr 18 16:59:20 EDT 2003
+#	options:bn(64,64) ...
+#	compiler: cc -DTHREADS -D_REENTRANT -q64 -DB_ENDIAN -O3
+#                  sign    verify    sign/s verify/s
+#rsa  512 bits   0.0028s   0.0003s    357.1   3844.4
+#rsa 1024 bits   0.0148s   0.0008s     67.5   1239.7
+#rsa 2048 bits   0.0963s   0.0028s     10.4    353.0
+#rsa 4096 bits   0.6538s   0.0102s      1.5     98.1
+#dsa  512 bits   0.0026s   0.0032s    382.5    313.7
+#dsa 1024 bits   0.0081s   0.0099s    122.8    100.6
+#
+#	Same benchmark with this assembler code:
+#
+#rsa  512 bits   0.0020s   0.0002s    510.4   6273.7
+#rsa 1024 bits   0.0088s   0.0005s    114.1   2128.3
+#rsa 2048 bits   0.0540s   0.0016s     18.5    622.5
+#rsa 4096 bits   0.3700s   0.0058s      2.7    171.0
+#dsa  512 bits   0.0016s   0.0020s    610.7    507.1
+#dsa 1024 bits   0.0047s   0.0058s    212.5    173.2
+#	
+#	Again, performance increases by at about 75%
+#
+#       Mac OS X, Apple G5 1.8GHz (Note this is 32 bit code)
+#       OpenSSL 0.9.7c 30 Sep 2003
+#
+#       Original code.
+#
+#rsa  512 bits   0.0011s   0.0001s    906.1  11012.5
+#rsa 1024 bits   0.0060s   0.0003s    166.6   3363.1
+#rsa 2048 bits   0.0370s   0.0010s     27.1    982.4
+#rsa 4096 bits   0.2426s   0.0036s      4.1    280.4
+#dsa  512 bits   0.0010s   0.0012s   1038.1    841.5
+#dsa 1024 bits   0.0030s   0.0037s    329.6    269.7
+#dsa 2048 bits   0.0101s   0.0127s     98.9     78.6
+#
+#       Same benchmark with this assembler code:
+#
+#rsa  512 bits   0.0007s   0.0001s   1416.2  16645.9
+#rsa 1024 bits   0.0036s   0.0002s    274.4   5380.6
+#rsa 2048 bits   0.0222s   0.0006s     45.1   1589.5
+#rsa 4096 bits   0.1469s   0.0022s      6.8    449.6
+#dsa  512 bits   0.0006s   0.0007s   1664.2   1376.2
+#dsa 1024 bits   0.0018s   0.0023s    545.0    442.2
+#dsa 2048 bits   0.0061s   0.0075s    163.5    132.8
+#
+#        Performance increase of ~60%
+#
+#	If you have comments or suggestions to improve code send
+#	me a note at schari@us.ibm.com
+#
+
+$flavour = shift;
+
+if ($flavour =~ /32/) {
+	$BITS=	32;
+	$BNSZ=	$BITS/8;
+	$ISA=	"\"ppc\"";
+
+	$LD=	"lwz";		# load
+	$LDU=	"lwzu";		# load and update
+	$ST=	"stw";		# store
+	$STU=	"stwu";		# store and update
+	$UMULL=	"mullw";	# unsigned multiply low
+	$UMULH=	"mulhwu";	# unsigned multiply high
+	$UDIV=	"divwu";	# unsigned divide
+	$UCMPI=	"cmplwi";	# unsigned compare with immediate
+	$UCMP=	"cmplw";	# unsigned compare
+	$CNTLZ=	"cntlzw";	# count leading zeros
+	$SHL=	"slw";		# shift left
+	$SHR=	"srw";		# unsigned shift right
+	$SHRI=	"srwi";		# unsigned shift right by immediate	
+	$SHLI=	"slwi";		# shift left by immediate
+	$CLRU=	"clrlwi";	# clear upper bits
+	$INSR=	"insrwi";	# insert right
+	$ROTL=	"rotlwi";	# rotate left by immediate
+	$TR=	"tw";		# conditional trap
+} elsif ($flavour =~ /64/) {
+	$BITS=	64;
+	$BNSZ=	$BITS/8;
+	$ISA=	"\"ppc64\"";
+
+	# same as above, but 64-bit mnemonics...
+	$LD=	"ld";		# load
+	$LDU=	"ldu";		# load and update
+	$ST=	"std";		# store
+	$STU=	"stdu";		# store and update
+	$UMULL=	"mulld";	# unsigned multiply low
+	$UMULH=	"mulhdu";	# unsigned multiply high
+	$UDIV=	"divdu";	# unsigned divide
+	$UCMPI=	"cmpldi";	# unsigned compare with immediate
+	$UCMP=	"cmpld";	# unsigned compare
+	$CNTLZ=	"cntlzd";	# count leading zeros
+	$SHL=	"sld";		# shift left
+	$SHR=	"srd";		# unsigned shift right
+	$SHRI=	"srdi";		# unsigned shift right by immediate	
+	$SHLI=	"sldi";		# shift left by immediate
+	$CLRU=	"clrldi";	# clear upper bits
+	$INSR=	"insrdi";	# insert right 
+	$ROTL=	"rotldi";	# rotate left by immediate
+	$TR=	"td";		# conditional trap
+} else { die "nonsense $flavour"; }
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
+
+$data=<<EOF;
+#--------------------------------------------------------------------
+#
+#
+#
+#
+#	File:		ppc32.s
+#
+#	Created by:	Suresh Chari
+#			IBM Thomas J. Watson Research Library
+#			Hawthorne, NY
+#
+#
+#	Description:	Optimized assembly routines for OpenSSL crypto
+#			on the 32 bitPowerPC platform.
+#
+#
+#	Version History
+#
+#	2. Fixed bn_add,bn_sub and bn_div_words, added comments,
+#	   cleaned up code. Also made a single version which can
+#	   be used for both the AIX and Linux compilers. See NOTE
+#	   below.
+#				12/05/03		Suresh Chari
+#			(with lots of help from)        Andy Polyakov
+##	
+#	1. Initial version	10/20/02		Suresh Chari
+#
+#
+#	The following file works for the xlc,cc
+#	and gcc compilers.
+#
+#	NOTE:	To get the file to link correctly with the gcc compiler
+#	        you have to change the names of the routines and remove
+#		the first .(dot) character. This should automatically
+#		be done in the build process.
+#
+#	Hand optimized assembly code for the following routines
+#	
+#	bn_sqr_comba4
+#	bn_sqr_comba8
+#	bn_mul_comba4
+#	bn_mul_comba8
+#	bn_sub_words
+#	bn_add_words
+#	bn_div_words
+#	bn_sqr_words
+#	bn_mul_words
+#	bn_mul_add_words
+#
+#	NOTE:	It is possible to optimize this code more for
+#	specific PowerPC or Power architectures. On the Northstar
+#	architecture the optimizations in this file do
+#	 NOT provide much improvement.
+#
+#	If you have comments or suggestions to improve code send
+#	me a note at schari\@us.ibm.com
+#
+#--------------------------------------------------------------------------
+#
+#	Defines to be used in the assembly code.
+#	
+#.set r0,0	# we use it as storage for value of 0
+#.set SP,1	# preserved
+#.set RTOC,2	# preserved 
+#.set r3,3	# 1st argument/return value
+#.set r4,4	# 2nd argument/volatile register
+#.set r5,5	# 3rd argument/volatile register
+#.set r6,6	# ...
+#.set r7,7
+#.set r8,8
+#.set r9,9
+#.set r10,10
+#.set r11,11
+#.set r12,12
+#.set r13,13	# not used, nor any other "below" it...
+
+#	Declare function names to be global
+#	NOTE:	For gcc these names MUST be changed to remove
+#	        the first . i.e. for example change ".bn_sqr_comba4"
+#		to "bn_sqr_comba4". This should be automatically done
+#		in the build.
+	
+	.globl	.bn_sqr_comba4
+	.globl	.bn_sqr_comba8
+	.globl	.bn_mul_comba4
+	.globl	.bn_mul_comba8
+	.globl	.bn_sub_words
+	.globl	.bn_add_words
+	.globl	.bn_div_words
+	.globl	.bn_sqr_words
+	.globl	.bn_mul_words
+	.globl	.bn_mul_add_words
+	
+# .text section
+	
+	.machine	"any"
+
+#
+#	NOTE:	The following label name should be changed to
+#		"bn_sqr_comba4" i.e. remove the first dot
+#		for the gcc compiler. This should be automatically
+#		done in the build
+#
+
+.align	4
+.bn_sqr_comba4:
+#
+# Optimized version of bn_sqr_comba4.
+#
+# void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
+# r3 contains r
+# r4 contains a
+#
+# Freely use registers r5,r6,r7,r8,r9,r10,r11 as follows:	
+# 
+# r5,r6 are the two BN_ULONGs being multiplied.
+# r7,r8 are the results of the 32x32 giving 64 bit multiply.
+# r9,r10, r11 are the equivalents of c1,c2, c3.
+# Here's the assembly
+#
+#
+	xor		r0,r0,r0		# set r0 = 0. Used in the addze
+						# instructions below
+	
+						#sqr_add_c(a,0,c1,c2,c3)
+	$LD		r5,`0*$BNSZ`(r4)		
+	$UMULL		r9,r5,r5		
+	$UMULH		r10,r5,r5		#in first iteration. No need
+						#to add since c1=c2=c3=0.
+						# Note c3(r11) is NOT set to 0
+						# but will be.
+
+	$ST		r9,`0*$BNSZ`(r3)	# r[0]=c1;
+						# sqr_add_c2(a,1,0,c2,c3,c1);
+	$LD		r6,`1*$BNSZ`(r4)		
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+					
+	addc		r7,r7,r7		# compute (r7,r8)=2*(r7,r8)
+	adde		r8,r8,r8
+	addze		r9,r0			# catch carry if any.
+						# r9= r0(=0) and carry 
+	
+	addc		r10,r7,r10		# now add to temp result.
+	addze		r11,r8                  # r8 added to r11 which is 0 
+	addze		r9,r9
+	
+	$ST		r10,`1*$BNSZ`(r3)	#r[1]=c2; 
+						#sqr_add_c(a,1,c3,c1,c2)
+	$UMULL		r7,r6,r6
+	$UMULH		r8,r6,r6
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r0
+						#sqr_add_c2(a,2,0,c3,c1,c2)
+	$LD		r6,`2*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	
+	addc		r7,r7,r7
+	adde		r8,r8,r8
+	addze		r10,r10
+	
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+	$ST		r11,`2*$BNSZ`(r3)	#r[2]=c3 
+						#sqr_add_c2(a,3,0,c1,c2,c3);
+	$LD		r6,`3*$BNSZ`(r4)		
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	addc		r7,r7,r7
+	adde		r8,r8,r8
+	addze		r11,r0
+	
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+						#sqr_add_c2(a,2,1,c1,c2,c3);
+	$LD		r5,`1*$BNSZ`(r4)
+	$LD		r6,`2*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	
+	addc		r7,r7,r7
+	adde		r8,r8,r8
+	addze		r11,r11
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+	$ST		r9,`3*$BNSZ`(r3)	#r[3]=c1
+						#sqr_add_c(a,2,c2,c3,c1);
+	$UMULL		r7,r6,r6
+	$UMULH		r8,r6,r6
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r0
+						#sqr_add_c2(a,3,1,c2,c3,c1);
+	$LD		r6,`3*$BNSZ`(r4)		
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	addc		r7,r7,r7
+	adde		r8,r8,r8
+	addze		r9,r9
+	
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r9
+	$ST		r10,`4*$BNSZ`(r3)	#r[4]=c2
+						#sqr_add_c2(a,3,2,c3,c1,c2);
+	$LD		r5,`2*$BNSZ`(r4)		
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	addc		r7,r7,r7
+	adde		r8,r8,r8
+	addze		r10,r0
+	
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+	$ST		r11,`5*$BNSZ`(r3)	#r[5] = c3
+						#sqr_add_c(a,3,c1,c2,c3);
+	$UMULL		r7,r6,r6		
+	$UMULH		r8,r6,r6
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+
+	$ST		r9,`6*$BNSZ`(r3)	#r[6]=c1
+	$ST		r10,`7*$BNSZ`(r3)	#r[7]=c2
+	blr
+	.long	0x00000000
+
+#
+#	NOTE:	The following label name should be changed to
+#		"bn_sqr_comba8" i.e. remove the first dot
+#		for the gcc compiler. This should be automatically
+#		done in the build
+#
+	
+.align	4
+.bn_sqr_comba8:
+#
+# This is an optimized version of the bn_sqr_comba8 routine.
+# Tightly uses the adde instruction
+#
+#
+# void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
+# r3 contains r
+# r4 contains a
+#
+# Freely use registers r5,r6,r7,r8,r9,r10,r11 as follows:	
+# 
+# r5,r6 are the two BN_ULONGs being multiplied.
+# r7,r8 are the results of the 32x32 giving 64 bit multiply.
+# r9,r10, r11 are the equivalents of c1,c2, c3.
+#
+# Possible optimization of loading all 8 longs of a into registers
+# doesnt provide any speedup
+# 
+
+	xor		r0,r0,r0		#set r0 = 0.Used in addze
+						#instructions below.
+
+						#sqr_add_c(a,0,c1,c2,c3);
+	$LD		r5,`0*$BNSZ`(r4)
+	$UMULL		r9,r5,r5		#1st iteration:	no carries.
+	$UMULH		r10,r5,r5
+	$ST		r9,`0*$BNSZ`(r3)	# r[0]=c1;
+						#sqr_add_c2(a,1,0,c2,c3,c1);
+	$LD		r6,`1*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6	
+	
+	addc		r10,r7,r10		#add the two register number
+	adde		r11,r8,r0 		# (r8,r7) to the three register
+	addze		r9,r0			# number (r9,r11,r10).NOTE:r0=0
+	
+	addc		r10,r7,r10		#add the two register number
+	adde		r11,r8,r11 		# (r8,r7) to the three register
+	addze		r9,r9			# number (r9,r11,r10).
+	
+	$ST		r10,`1*$BNSZ`(r3)	# r[1]=c2
+				
+						#sqr_add_c(a,1,c3,c1,c2);
+	$UMULL		r7,r6,r6
+	$UMULH		r8,r6,r6
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r0
+						#sqr_add_c2(a,2,0,c3,c1,c2);
+	$LD		r6,`2*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+	
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+	
+	$ST		r11,`2*$BNSZ`(r3)	#r[2]=c3
+						#sqr_add_c2(a,3,0,c1,c2,c3);
+	$LD		r6,`3*$BNSZ`(r4)	#r6 = a[3]. r5 is already a[0].
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r0
+	
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+						#sqr_add_c2(a,2,1,c1,c2,c3);
+	$LD		r5,`1*$BNSZ`(r4)
+	$LD		r6,`2*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+	
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+	
+	$ST		r9,`3*$BNSZ`(r3)	#r[3]=c1;
+						#sqr_add_c(a,2,c2,c3,c1);
+	$UMULL		r7,r6,r6
+	$UMULH		r8,r6,r6
+	
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r0
+						#sqr_add_c2(a,3,1,c2,c3,c1);
+	$LD		r6,`3*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r9
+	
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r9
+						#sqr_add_c2(a,4,0,c2,c3,c1);
+	$LD		r5,`0*$BNSZ`(r4)
+	$LD		r6,`4*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r9
+	
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r9
+	$ST		r10,`4*$BNSZ`(r3)	#r[4]=c2;
+						#sqr_add_c2(a,5,0,c3,c1,c2);
+	$LD		r6,`5*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r0
+	
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+						#sqr_add_c2(a,4,1,c3,c1,c2);
+	$LD		r5,`1*$BNSZ`(r4)
+	$LD		r6,`4*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+	
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+						#sqr_add_c2(a,3,2,c3,c1,c2);
+	$LD		r5,`2*$BNSZ`(r4)
+	$LD		r6,`3*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+	
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+	$ST		r11,`5*$BNSZ`(r3)	#r[5]=c3;
+						#sqr_add_c(a,3,c1,c2,c3);
+	$UMULL		r7,r6,r6
+	$UMULH		r8,r6,r6
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r0
+						#sqr_add_c2(a,4,2,c1,c2,c3);
+	$LD		r6,`4*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+	
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+						#sqr_add_c2(a,5,1,c1,c2,c3);
+	$LD		r5,`1*$BNSZ`(r4)
+	$LD		r6,`5*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+	
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+						#sqr_add_c2(a,6,0,c1,c2,c3);
+	$LD		r5,`0*$BNSZ`(r4)
+	$LD		r6,`6*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+	$ST		r9,`6*$BNSZ`(r3)	#r[6]=c1;
+						#sqr_add_c2(a,7,0,c2,c3,c1);
+	$LD		r6,`7*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r0
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r9
+						#sqr_add_c2(a,6,1,c2,c3,c1);
+	$LD		r5,`1*$BNSZ`(r4)
+	$LD		r6,`6*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r9
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r9
+						#sqr_add_c2(a,5,2,c2,c3,c1);
+	$LD		r5,`2*$BNSZ`(r4)
+	$LD		r6,`5*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r9
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r9
+						#sqr_add_c2(a,4,3,c2,c3,c1);
+	$LD		r5,`3*$BNSZ`(r4)
+	$LD		r6,`4*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r9
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r9
+	$ST		r10,`7*$BNSZ`(r3)	#r[7]=c2;
+						#sqr_add_c(a,4,c3,c1,c2);
+	$UMULL		r7,r6,r6
+	$UMULH		r8,r6,r6
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r0
+						#sqr_add_c2(a,5,3,c3,c1,c2);
+	$LD		r6,`5*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+						#sqr_add_c2(a,6,2,c3,c1,c2);
+	$LD		r5,`2*$BNSZ`(r4)
+	$LD		r6,`6*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+	
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+						#sqr_add_c2(a,7,1,c3,c1,c2);
+	$LD		r5,`1*$BNSZ`(r4)
+	$LD		r6,`7*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+	$ST		r11,`8*$BNSZ`(r3)	#r[8]=c3;
+						#sqr_add_c2(a,7,2,c1,c2,c3);
+	$LD		r5,`2*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r0
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+						#sqr_add_c2(a,6,3,c1,c2,c3);
+	$LD		r5,`3*$BNSZ`(r4)
+	$LD		r6,`6*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+						#sqr_add_c2(a,5,4,c1,c2,c3);
+	$LD		r5,`4*$BNSZ`(r4)
+	$LD		r6,`5*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+	$ST		r9,`9*$BNSZ`(r3)	#r[9]=c1;
+						#sqr_add_c(a,5,c2,c3,c1);
+	$UMULL		r7,r6,r6
+	$UMULH		r8,r6,r6
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r0
+						#sqr_add_c2(a,6,4,c2,c3,c1);
+	$LD		r6,`6*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r9
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r9
+						#sqr_add_c2(a,7,3,c2,c3,c1);
+	$LD		r5,`3*$BNSZ`(r4)
+	$LD		r6,`7*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r9
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r9
+	$ST		r10,`10*$BNSZ`(r3)	#r[10]=c2;
+						#sqr_add_c2(a,7,4,c3,c1,c2);
+	$LD		r5,`4*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r0
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+						#sqr_add_c2(a,6,5,c3,c1,c2);
+	$LD		r5,`5*$BNSZ`(r4)
+	$LD		r6,`6*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	addze		r10,r10
+	$ST		r11,`11*$BNSZ`(r3)	#r[11]=c3;
+						#sqr_add_c(a,6,c1,c2,c3);
+	$UMULL		r7,r6,r6
+	$UMULH		r8,r6,r6
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r0
+						#sqr_add_c2(a,7,5,c1,c2,c3)
+	$LD		r6,`7*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+	addc		r9,r7,r9
+	adde		r10,r8,r10
+	addze		r11,r11
+	$ST		r9,`12*$BNSZ`(r3)	#r[12]=c1;
+	
+						#sqr_add_c2(a,7,6,c2,c3,c1)
+	$LD		r5,`6*$BNSZ`(r4)
+	$UMULL		r7,r5,r6
+	$UMULH		r8,r5,r6
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r0
+	addc		r10,r7,r10
+	adde		r11,r8,r11
+	addze		r9,r9
+	$ST		r10,`13*$BNSZ`(r3)	#r[13]=c2;
+						#sqr_add_c(a,7,c3,c1,c2);
+	$UMULL		r7,r6,r6
+	$UMULH		r8,r6,r6
+	addc		r11,r7,r11
+	adde		r9,r8,r9
+	$ST		r11,`14*$BNSZ`(r3)	#r[14]=c3;
+	$ST		r9, `15*$BNSZ`(r3)	#r[15]=c1;
+
+
+	blr
+
+	.long	0x00000000
+
+#
+#	NOTE:	The following label name should be changed to
+#		"bn_mul_comba4" i.e. remove the first dot
+#		for the gcc compiler. This should be automatically
+#		done in the build
+#
+
+.align	4
+.bn_mul_comba4:
+#
+# This is an optimized version of the bn_mul_comba4 routine.
+#
+# void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+# r3 contains r
+# r4 contains a
+# r5 contains b
+# r6, r7 are the 2 BN_ULONGs being multiplied.
+# r8, r9 are the results of the 32x32 giving 64 multiply.
+# r10, r11, r12 are the equivalents of c1, c2, and c3.
+#
+	xor	r0,r0,r0		#r0=0. Used in addze below.
+					#mul_add_c(a[0],b[0],c1,c2,c3);
+	$LD	r6,`0*$BNSZ`(r4)		
+	$LD	r7,`0*$BNSZ`(r5)		
+	$UMULL	r10,r6,r7		
+	$UMULH	r11,r6,r7		
+	$ST	r10,`0*$BNSZ`(r3)	#r[0]=c1
+					#mul_add_c(a[0],b[1],c2,c3,c1);
+	$LD	r7,`1*$BNSZ`(r5)		
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r8,r11
+	adde	r12,r9,r0
+	addze	r10,r0
+					#mul_add_c(a[1],b[0],c2,c3,c1);
+	$LD	r6, `1*$BNSZ`(r4)		
+	$LD	r7, `0*$BNSZ`(r5)		
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r8,r11
+	adde	r12,r9,r12
+	addze	r10,r10
+	$ST	r11,`1*$BNSZ`(r3)	#r[1]=c2
+					#mul_add_c(a[2],b[0],c3,c1,c2);
+	$LD	r6,`2*$BNSZ`(r4)		
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r8,r12
+	adde	r10,r9,r10
+	addze	r11,r0
+					#mul_add_c(a[1],b[1],c3,c1,c2);
+	$LD	r6,`1*$BNSZ`(r4)		
+	$LD	r7,`1*$BNSZ`(r5)		
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r8,r12
+	adde	r10,r9,r10
+	addze	r11,r11
+					#mul_add_c(a[0],b[2],c3,c1,c2);
+	$LD	r6,`0*$BNSZ`(r4)		
+	$LD	r7,`2*$BNSZ`(r5)		
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r8,r12
+	adde	r10,r9,r10
+	addze	r11,r11
+	$ST	r12,`2*$BNSZ`(r3)	#r[2]=c3
+					#mul_add_c(a[0],b[3],c1,c2,c3);
+	$LD	r7,`3*$BNSZ`(r5)		
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r8,r10
+	adde	r11,r9,r11
+	addze	r12,r0
+					#mul_add_c(a[1],b[2],c1,c2,c3);
+	$LD	r6,`1*$BNSZ`(r4)
+	$LD	r7,`2*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r8,r10
+	adde	r11,r9,r11
+	addze	r12,r12
+					#mul_add_c(a[2],b[1],c1,c2,c3);
+	$LD	r6,`2*$BNSZ`(r4)
+	$LD	r7,`1*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r8,r10
+	adde	r11,r9,r11
+	addze	r12,r12
+					#mul_add_c(a[3],b[0],c1,c2,c3);
+	$LD	r6,`3*$BNSZ`(r4)
+	$LD	r7,`0*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r8,r10
+	adde	r11,r9,r11
+	addze	r12,r12
+	$ST	r10,`3*$BNSZ`(r3)	#r[3]=c1
+					#mul_add_c(a[3],b[1],c2,c3,c1);
+	$LD	r7,`1*$BNSZ`(r5)		
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r8,r11
+	adde	r12,r9,r12
+	addze	r10,r0
+					#mul_add_c(a[2],b[2],c2,c3,c1);
+	$LD	r6,`2*$BNSZ`(r4)
+	$LD	r7,`2*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r8,r11
+	adde	r12,r9,r12
+	addze	r10,r10
+					#mul_add_c(a[1],b[3],c2,c3,c1);
+	$LD	r6,`1*$BNSZ`(r4)
+	$LD	r7,`3*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r8,r11
+	adde	r12,r9,r12
+	addze	r10,r10
+	$ST	r11,`4*$BNSZ`(r3)	#r[4]=c2
+					#mul_add_c(a[2],b[3],c3,c1,c2);
+	$LD	r6,`2*$BNSZ`(r4)		
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r8,r12
+	adde	r10,r9,r10
+	addze	r11,r0
+					#mul_add_c(a[3],b[2],c3,c1,c2);
+	$LD	r6,`3*$BNSZ`(r4)
+	$LD	r7,`2*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r8,r12
+	adde	r10,r9,r10
+	addze	r11,r11
+	$ST	r12,`5*$BNSZ`(r3)	#r[5]=c3
+					#mul_add_c(a[3],b[3],c1,c2,c3);
+	$LD	r7,`3*$BNSZ`(r5)		
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r8,r10
+	adde	r11,r9,r11
+
+	$ST	r10,`6*$BNSZ`(r3)	#r[6]=c1
+	$ST	r11,`7*$BNSZ`(r3)	#r[7]=c2
+	blr
+	.long	0x00000000
+
+#
+#	NOTE:	The following label name should be changed to
+#		"bn_mul_comba8" i.e. remove the first dot
+#		for the gcc compiler. This should be automatically
+#		done in the build
+#
+	
+.align	4
+.bn_mul_comba8:
+#
+# Optimized version of the bn_mul_comba8 routine.
+#
+# void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+# r3 contains r
+# r4 contains a
+# r5 contains b
+# r6, r7 are the 2 BN_ULONGs being multiplied.
+# r8, r9 are the results of the 32x32 giving 64 multiply.
+# r10, r11, r12 are the equivalents of c1, c2, and c3.
+#
+	xor	r0,r0,r0		#r0=0. Used in addze below.
+	
+					#mul_add_c(a[0],b[0],c1,c2,c3);
+	$LD	r6,`0*$BNSZ`(r4)	#a[0]
+	$LD	r7,`0*$BNSZ`(r5)	#b[0]
+	$UMULL	r10,r6,r7
+	$UMULH	r11,r6,r7
+	$ST	r10,`0*$BNSZ`(r3)	#r[0]=c1;
+					#mul_add_c(a[0],b[1],c2,c3,c1);
+	$LD	r7,`1*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	addze	r12,r9			# since we didnt set r12 to zero before.
+	addze	r10,r0
+					#mul_add_c(a[1],b[0],c2,c3,c1);
+	$LD	r6,`1*$BNSZ`(r4)
+	$LD	r7,`0*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r10
+	$ST	r11,`1*$BNSZ`(r3)	#r[1]=c2;
+					#mul_add_c(a[2],b[0],c3,c1,c2);
+	$LD	r6,`2*$BNSZ`(r4)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r0
+					#mul_add_c(a[1],b[1],c3,c1,c2);
+	$LD	r6,`1*$BNSZ`(r4)
+	$LD	r7,`1*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r11
+					#mul_add_c(a[0],b[2],c3,c1,c2);
+	$LD	r6,`0*$BNSZ`(r4)
+	$LD	r7,`2*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r11
+	$ST	r12,`2*$BNSZ`(r3)	#r[2]=c3;
+					#mul_add_c(a[0],b[3],c1,c2,c3);
+	$LD	r7,`3*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r0
+					#mul_add_c(a[1],b[2],c1,c2,c3);
+	$LD	r6,`1*$BNSZ`(r4)
+	$LD	r7,`2*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r12
+		
+					#mul_add_c(a[2],b[1],c1,c2,c3);
+	$LD	r6,`2*$BNSZ`(r4)
+	$LD	r7,`1*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r12
+					#mul_add_c(a[3],b[0],c1,c2,c3);
+	$LD	r6,`3*$BNSZ`(r4)
+	$LD	r7,`0*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r12
+	$ST	r10,`3*$BNSZ`(r3)	#r[3]=c1;
+					#mul_add_c(a[4],b[0],c2,c3,c1);
+	$LD	r6,`4*$BNSZ`(r4)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r0
+					#mul_add_c(a[3],b[1],c2,c3,c1);
+	$LD	r6,`3*$BNSZ`(r4)
+	$LD	r7,`1*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r10
+					#mul_add_c(a[2],b[2],c2,c3,c1);
+	$LD	r6,`2*$BNSZ`(r4)
+	$LD	r7,`2*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r10
+					#mul_add_c(a[1],b[3],c2,c3,c1);
+	$LD	r6,`1*$BNSZ`(r4)
+	$LD	r7,`3*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r10
+					#mul_add_c(a[0],b[4],c2,c3,c1);
+	$LD	r6,`0*$BNSZ`(r4)
+	$LD	r7,`4*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r10
+	$ST	r11,`4*$BNSZ`(r3)	#r[4]=c2;
+					#mul_add_c(a[0],b[5],c3,c1,c2);
+	$LD	r7,`5*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r0
+					#mul_add_c(a[1],b[4],c3,c1,c2);
+	$LD	r6,`1*$BNSZ`(r4)		
+	$LD	r7,`4*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r11
+					#mul_add_c(a[2],b[3],c3,c1,c2);
+	$LD	r6,`2*$BNSZ`(r4)		
+	$LD	r7,`3*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r11
+					#mul_add_c(a[3],b[2],c3,c1,c2);
+	$LD	r6,`3*$BNSZ`(r4)		
+	$LD	r7,`2*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r11
+					#mul_add_c(a[4],b[1],c3,c1,c2);
+	$LD	r6,`4*$BNSZ`(r4)		
+	$LD	r7,`1*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r11
+					#mul_add_c(a[5],b[0],c3,c1,c2);
+	$LD	r6,`5*$BNSZ`(r4)		
+	$LD	r7,`0*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r11
+	$ST	r12,`5*$BNSZ`(r3)	#r[5]=c3;
+					#mul_add_c(a[6],b[0],c1,c2,c3);
+	$LD	r6,`6*$BNSZ`(r4)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r0
+					#mul_add_c(a[5],b[1],c1,c2,c3);
+	$LD	r6,`5*$BNSZ`(r4)
+	$LD	r7,`1*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r12
+					#mul_add_c(a[4],b[2],c1,c2,c3);
+	$LD	r6,`4*$BNSZ`(r4)
+	$LD	r7,`2*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r12
+					#mul_add_c(a[3],b[3],c1,c2,c3);
+	$LD	r6,`3*$BNSZ`(r4)
+	$LD	r7,`3*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r12
+					#mul_add_c(a[2],b[4],c1,c2,c3);
+	$LD	r6,`2*$BNSZ`(r4)
+	$LD	r7,`4*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r12
+					#mul_add_c(a[1],b[5],c1,c2,c3);
+	$LD	r6,`1*$BNSZ`(r4)
+	$LD	r7,`5*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r12
+					#mul_add_c(a[0],b[6],c1,c2,c3);
+	$LD	r6,`0*$BNSZ`(r4)
+	$LD	r7,`6*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r12
+	$ST	r10,`6*$BNSZ`(r3)	#r[6]=c1;
+					#mul_add_c(a[0],b[7],c2,c3,c1);
+	$LD	r7,`7*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r0
+					#mul_add_c(a[1],b[6],c2,c3,c1);
+	$LD	r6,`1*$BNSZ`(r4)
+	$LD	r7,`6*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r10
+					#mul_add_c(a[2],b[5],c2,c3,c1);
+	$LD	r6,`2*$BNSZ`(r4)
+	$LD	r7,`5*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r10
+					#mul_add_c(a[3],b[4],c2,c3,c1);
+	$LD	r6,`3*$BNSZ`(r4)
+	$LD	r7,`4*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r10
+					#mul_add_c(a[4],b[3],c2,c3,c1);
+	$LD	r6,`4*$BNSZ`(r4)
+	$LD	r7,`3*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r10
+					#mul_add_c(a[5],b[2],c2,c3,c1);
+	$LD	r6,`5*$BNSZ`(r4)
+	$LD	r7,`2*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r10
+					#mul_add_c(a[6],b[1],c2,c3,c1);
+	$LD	r6,`6*$BNSZ`(r4)
+	$LD	r7,`1*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r10
+					#mul_add_c(a[7],b[0],c2,c3,c1);
+	$LD	r6,`7*$BNSZ`(r4)
+	$LD	r7,`0*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r10
+	$ST	r11,`7*$BNSZ`(r3)	#r[7]=c2;
+					#mul_add_c(a[7],b[1],c3,c1,c2);
+	$LD	r7,`1*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r0
+					#mul_add_c(a[6],b[2],c3,c1,c2);
+	$LD	r6,`6*$BNSZ`(r4)
+	$LD	r7,`2*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r11
+					#mul_add_c(a[5],b[3],c3,c1,c2);
+	$LD	r6,`5*$BNSZ`(r4)
+	$LD	r7,`3*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r11
+					#mul_add_c(a[4],b[4],c3,c1,c2);
+	$LD	r6,`4*$BNSZ`(r4)
+	$LD	r7,`4*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r11
+					#mul_add_c(a[3],b[5],c3,c1,c2);
+	$LD	r6,`3*$BNSZ`(r4)
+	$LD	r7,`5*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r11
+					#mul_add_c(a[2],b[6],c3,c1,c2);
+	$LD	r6,`2*$BNSZ`(r4)
+	$LD	r7,`6*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r11
+					#mul_add_c(a[1],b[7],c3,c1,c2);
+	$LD	r6,`1*$BNSZ`(r4)
+	$LD	r7,`7*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r11
+	$ST	r12,`8*$BNSZ`(r3)	#r[8]=c3;
+					#mul_add_c(a[2],b[7],c1,c2,c3);
+	$LD	r6,`2*$BNSZ`(r4)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r0
+					#mul_add_c(a[3],b[6],c1,c2,c3);
+	$LD	r6,`3*$BNSZ`(r4)
+	$LD	r7,`6*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r12
+					#mul_add_c(a[4],b[5],c1,c2,c3);
+	$LD	r6,`4*$BNSZ`(r4)
+	$LD	r7,`5*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r12
+					#mul_add_c(a[5],b[4],c1,c2,c3);
+	$LD	r6,`5*$BNSZ`(r4)
+	$LD	r7,`4*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r12
+					#mul_add_c(a[6],b[3],c1,c2,c3);
+	$LD	r6,`6*$BNSZ`(r4)
+	$LD	r7,`3*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r12
+					#mul_add_c(a[7],b[2],c1,c2,c3);
+	$LD	r6,`7*$BNSZ`(r4)
+	$LD	r7,`2*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r12
+	$ST	r10,`9*$BNSZ`(r3)	#r[9]=c1;
+					#mul_add_c(a[7],b[3],c2,c3,c1);
+	$LD	r7,`3*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r0
+					#mul_add_c(a[6],b[4],c2,c3,c1);
+	$LD	r6,`6*$BNSZ`(r4)
+	$LD	r7,`4*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r10
+					#mul_add_c(a[5],b[5],c2,c3,c1);
+	$LD	r6,`5*$BNSZ`(r4)
+	$LD	r7,`5*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r10
+					#mul_add_c(a[4],b[6],c2,c3,c1);
+	$LD	r6,`4*$BNSZ`(r4)
+	$LD	r7,`6*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r10
+					#mul_add_c(a[3],b[7],c2,c3,c1);
+	$LD	r6,`3*$BNSZ`(r4)
+	$LD	r7,`7*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r10
+	$ST	r11,`10*$BNSZ`(r3)	#r[10]=c2;
+					#mul_add_c(a[4],b[7],c3,c1,c2);
+	$LD	r6,`4*$BNSZ`(r4)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r0
+					#mul_add_c(a[5],b[6],c3,c1,c2);
+	$LD	r6,`5*$BNSZ`(r4)
+	$LD	r7,`6*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r11
+					#mul_add_c(a[6],b[5],c3,c1,c2);
+	$LD	r6,`6*$BNSZ`(r4)
+	$LD	r7,`5*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r11
+					#mul_add_c(a[7],b[4],c3,c1,c2);
+	$LD	r6,`7*$BNSZ`(r4)
+	$LD	r7,`4*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	addze	r11,r11
+	$ST	r12,`11*$BNSZ`(r3)	#r[11]=c3;
+					#mul_add_c(a[7],b[5],c1,c2,c3);
+	$LD	r7,`5*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r0
+					#mul_add_c(a[6],b[6],c1,c2,c3);
+	$LD	r6,`6*$BNSZ`(r4)
+	$LD	r7,`6*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r12
+					#mul_add_c(a[5],b[7],c1,c2,c3);
+	$LD	r6,`5*$BNSZ`(r4)
+	$LD	r7,`7*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r10,r10,r8
+	adde	r11,r11,r9
+	addze	r12,r12
+	$ST	r10,`12*$BNSZ`(r3)	#r[12]=c1;
+					#mul_add_c(a[6],b[7],c2,c3,c1);
+	$LD	r6,`6*$BNSZ`(r4)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r0
+					#mul_add_c(a[7],b[6],c2,c3,c1);
+	$LD	r6,`7*$BNSZ`(r4)
+	$LD	r7,`6*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r11,r11,r8
+	adde	r12,r12,r9
+	addze	r10,r10
+	$ST	r11,`13*$BNSZ`(r3)	#r[13]=c2;
+					#mul_add_c(a[7],b[7],c3,c1,c2);
+	$LD	r7,`7*$BNSZ`(r5)
+	$UMULL	r8,r6,r7
+	$UMULH	r9,r6,r7
+	addc	r12,r12,r8
+	adde	r10,r10,r9
+	$ST	r12,`14*$BNSZ`(r3)	#r[14]=c3;
+	$ST	r10,`15*$BNSZ`(r3)	#r[15]=c1;
+	blr
+	.long	0x00000000
+
+#
+#	NOTE:	The following label name should be changed to
+#		"bn_sub_words" i.e. remove the first dot
+#		for the gcc compiler. This should be automatically
+#		done in the build
+#
+#
+.align	4
+.bn_sub_words:
+#
+#	Handcoded version of bn_sub_words
+#
+#BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+#
+#	r3 = r
+#	r4 = a
+#	r5 = b
+#	r6 = n
+#
+#       Note:	No loop unrolling done since this is not a performance
+#               critical loop.
+
+	xor	r0,r0,r0	#set r0 = 0
+#
+#	check for r6 = 0 AND set carry bit.
+#
+	subfc.	r7,r0,r6        # If r6 is 0 then result is 0.
+				# if r6 > 0 then result !=0
+				# In either case carry bit is set.
+	beq	Lppcasm_sub_adios
+	addi	r4,r4,-$BNSZ
+	addi	r3,r3,-$BNSZ
+	addi	r5,r5,-$BNSZ
+	mtctr	r6
+Lppcasm_sub_mainloop:	
+	$LDU	r7,$BNSZ(r4)
+	$LDU	r8,$BNSZ(r5)
+	subfe	r6,r8,r7	# r6 = r7+carry bit + onescomplement(r8)
+				# if carry = 1 this is r7-r8. Else it
+				# is r7-r8 -1 as we need.
+	$STU	r6,$BNSZ(r3)
+	bdnz-	Lppcasm_sub_mainloop
+Lppcasm_sub_adios:	
+	subfze	r3,r0		# if carry bit is set then r3 = 0 else -1
+	andi.	r3,r3,1         # keep only last bit.
+	blr
+	.long	0x00000000
+
+
+#
+#	NOTE:	The following label name should be changed to
+#		"bn_add_words" i.e. remove the first dot
+#		for the gcc compiler. This should be automatically
+#		done in the build
+#
+
+.align	4
+.bn_add_words:
+#
+#	Handcoded version of bn_add_words
+#
+#BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+#
+#	r3 = r
+#	r4 = a
+#	r5 = b
+#	r6 = n
+#
+#       Note:	No loop unrolling done since this is not a performance
+#               critical loop.
+
+	xor	r0,r0,r0
+#
+#	check for r6 = 0. Is this needed?
+#
+	addic.	r6,r6,0		#test r6 and clear carry bit.
+	beq	Lppcasm_add_adios
+	addi	r4,r4,-$BNSZ
+	addi	r3,r3,-$BNSZ
+	addi	r5,r5,-$BNSZ
+	mtctr	r6
+Lppcasm_add_mainloop:	
+	$LDU	r7,$BNSZ(r4)
+	$LDU	r8,$BNSZ(r5)
+	adde	r8,r7,r8
+	$STU	r8,$BNSZ(r3)
+	bdnz-	Lppcasm_add_mainloop
+Lppcasm_add_adios:	
+	addze	r3,r0			#return carry bit.
+	blr
+	.long	0x00000000
+
+#
+#	NOTE:	The following label name should be changed to
+#		"bn_div_words" i.e. remove the first dot
+#		for the gcc compiler. This should be automatically
+#		done in the build
+#
+
+.align	4
+.bn_div_words:
+#
+#	This is a cleaned up version of code generated by
+#	the AIX compiler. The only optimization is to use
+#	the PPC instruction to count leading zeros instead
+#	of call to num_bits_word. Since this was compiled
+#	only at level -O2 we can possibly squeeze it more?
+#	
+#	r3 = h
+#	r4 = l
+#	r5 = d
+	
+	$UCMPI	0,r5,0			# compare r5 and 0
+	bne	Lppcasm_div1		# proceed if d!=0
+	li	r3,-1			# d=0 return -1
+	blr
+Lppcasm_div1:
+	xor	r0,r0,r0		#r0=0
+	li	r8,$BITS
+	$CNTLZ.	r7,r5			#r7 = num leading 0s in d.
+	beq	Lppcasm_div2		#proceed if no leading zeros
+	subf	r8,r7,r8		#r8 = BN_num_bits_word(d)
+	$SHR.	r9,r3,r8		#are there any bits above r8'th?
+	$TR	16,r9,r0		#if there're, signal to dump core...
+Lppcasm_div2:
+	$UCMP	0,r3,r5			#h>=d?
+	blt	Lppcasm_div3		#goto Lppcasm_div3 if not
+	subf	r3,r5,r3		#h-=d ; 
+Lppcasm_div3:				#r7 = BN_BITS2-i. so r7=i
+	cmpi	0,0,r7,0		# is (i == 0)?
+	beq	Lppcasm_div4
+	$SHL	r3,r3,r7		# h = (h<< i)
+	$SHR	r8,r4,r8		# r8 = (l >> BN_BITS2 -i)
+	$SHL	r5,r5,r7		# d<<=i
+	or	r3,r3,r8		# h = (h<<i)|(l>>(BN_BITS2-i))
+	$SHL	r4,r4,r7		# l <<=i
+Lppcasm_div4:
+	$SHRI	r9,r5,`$BITS/2`		# r9 = dh
+					# dl will be computed when needed
+					# as it saves registers.
+	li	r6,2			#r6=2
+	mtctr	r6			#counter will be in count.
+Lppcasm_divouterloop: 
+	$SHRI	r8,r3,`$BITS/2`		#r8 = (h>>BN_BITS4)
+	$SHRI	r11,r4,`$BITS/2`	#r11= (l&BN_MASK2h)>>BN_BITS4
+					# compute here for innerloop.
+	$UCMP	0,r8,r9			# is (h>>BN_BITS4)==dh
+	bne	Lppcasm_div5		# goto Lppcasm_div5 if not
+
+	li	r8,-1
+	$CLRU	r8,r8,`$BITS/2`		#q = BN_MASK2l 
+	b	Lppcasm_div6
+Lppcasm_div5:
+	$UDIV	r8,r3,r9		#q = h/dh
+Lppcasm_div6:
+	$UMULL	r12,r9,r8		#th = q*dh
+	$CLRU	r10,r5,`$BITS/2`	#r10=dl
+	$UMULL	r6,r8,r10		#tl = q*dl
+	
+Lppcasm_divinnerloop:
+	subf	r10,r12,r3		#t = h -th
+	$SHRI	r7,r10,`$BITS/2`	#r7= (t &BN_MASK2H), sort of...
+	addic.	r7,r7,0			#test if r7 == 0. used below.
+					# now want to compute
+					# r7 = (t<<BN_BITS4)|((l&BN_MASK2h)>>BN_BITS4)
+					# the following 2 instructions do that
+	$SHLI	r7,r10,`$BITS/2`	# r7 = (t<<BN_BITS4)
+	or	r7,r7,r11		# r7|=((l&BN_MASK2h)>>BN_BITS4)
+	$UCMP	cr1,r6,r7		# compare (tl <= r7)
+	bne	Lppcasm_divinnerexit
+	ble	cr1,Lppcasm_divinnerexit
+	addi	r8,r8,-1		#q--
+	subf	r12,r9,r12		#th -=dh
+	$CLRU	r10,r5,`$BITS/2`	#r10=dl. t is no longer needed in loop.
+	subf	r6,r10,r6		#tl -=dl
+	b	Lppcasm_divinnerloop
+Lppcasm_divinnerexit:
+	$SHRI	r10,r6,`$BITS/2`	#t=(tl>>BN_BITS4)
+	$SHLI	r11,r6,`$BITS/2`	#tl=(tl<<BN_BITS4)&BN_MASK2h;
+	$UCMP	cr1,r4,r11		# compare l and tl
+	add	r12,r12,r10		# th+=t
+	bge	cr1,Lppcasm_div7	# if (l>=tl) goto Lppcasm_div7
+	addi	r12,r12,1		# th++
+Lppcasm_div7:
+	subf	r11,r11,r4		#r11=l-tl
+	$UCMP	cr1,r3,r12		#compare h and th
+	bge	cr1,Lppcasm_div8	#if (h>=th) goto Lppcasm_div8
+	addi	r8,r8,-1		# q--
+	add	r3,r5,r3		# h+=d
+Lppcasm_div8:
+	subf	r12,r12,r3		#r12 = h-th
+	$SHLI	r4,r11,`$BITS/2`	#l=(l&BN_MASK2l)<<BN_BITS4
+					# want to compute
+					# h = ((h<<BN_BITS4)|(l>>BN_BITS4))&BN_MASK2
+					# the following 2 instructions will do this.
+	$INSR	r11,r12,`$BITS/2`,`$BITS/2`	# r11 is the value we want rotated $BITS/2.
+	$ROTL	r3,r11,`$BITS/2`	# rotate by $BITS/2 and store in r3
+	bdz	Lppcasm_div9		#if (count==0) break ;
+	$SHLI	r0,r8,`$BITS/2`		#ret =q<<BN_BITS4
+	b	Lppcasm_divouterloop
+Lppcasm_div9:
+	or	r3,r8,r0
+	blr
+	.long	0x00000000
+
+#
+#	NOTE:	The following label name should be changed to
+#		"bn_sqr_words" i.e. remove the first dot
+#		for the gcc compiler. This should be automatically
+#		done in the build
+#
+.align	4
+.bn_sqr_words:
+#
+#	Optimized version of bn_sqr_words
+#
+#	void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n)
+#
+#	r3 = r
+#	r4 = a
+#	r5 = n
+#
+#	r6 = a[i].
+#	r7,r8 = product.
+#
+#	No unrolling done here. Not performance critical.
+
+	addic.	r5,r5,0			#test r5.
+	beq	Lppcasm_sqr_adios
+	addi	r4,r4,-$BNSZ
+	addi	r3,r3,-$BNSZ
+	mtctr	r5
+Lppcasm_sqr_mainloop:	
+					#sqr(r[0],r[1],a[0]);
+	$LDU	r6,$BNSZ(r4)
+	$UMULL	r7,r6,r6
+	$UMULH  r8,r6,r6
+	$STU	r7,$BNSZ(r3)
+	$STU	r8,$BNSZ(r3)
+	bdnz-	Lppcasm_sqr_mainloop
+Lppcasm_sqr_adios:	
+	blr
+	.long	0x00000000
+
+
+#
+#	NOTE:	The following label name should be changed to
+#		"bn_mul_words" i.e. remove the first dot
+#		for the gcc compiler. This should be automatically
+#		done in the build
+#
+
+.align	4	
+.bn_mul_words:
+#
+# BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+#
+# r3 = rp
+# r4 = ap
+# r5 = num
+# r6 = w
+	xor	r0,r0,r0
+	xor	r12,r12,r12		# used for carry
+	rlwinm.	r7,r5,30,2,31		# num >> 2
+	beq	Lppcasm_mw_REM
+	mtctr	r7
+Lppcasm_mw_LOOP:	
+					#mul(rp[0],ap[0],w,c1);
+	$LD	r8,`0*$BNSZ`(r4)
+	$UMULL	r9,r6,r8
+	$UMULH  r10,r6,r8
+	addc	r9,r9,r12
+	#addze	r10,r10			#carry is NOT ignored.
+					#will be taken care of
+					#in second spin below
+					#using adde.
+	$ST	r9,`0*$BNSZ`(r3)
+					#mul(rp[1],ap[1],w,c1);
+	$LD	r8,`1*$BNSZ`(r4)	
+	$UMULL	r11,r6,r8
+	$UMULH  r12,r6,r8
+	adde	r11,r11,r10
+	#addze	r12,r12
+	$ST	r11,`1*$BNSZ`(r3)
+					#mul(rp[2],ap[2],w,c1);
+	$LD	r8,`2*$BNSZ`(r4)
+	$UMULL	r9,r6,r8
+	$UMULH  r10,r6,r8
+	adde	r9,r9,r12
+	#addze	r10,r10
+	$ST	r9,`2*$BNSZ`(r3)
+					#mul_add(rp[3],ap[3],w,c1);
+	$LD	r8,`3*$BNSZ`(r4)
+	$UMULL	r11,r6,r8
+	$UMULH  r12,r6,r8
+	adde	r11,r11,r10
+	addze	r12,r12			#this spin we collect carry into
+					#r12
+	$ST	r11,`3*$BNSZ`(r3)
+	
+	addi	r3,r3,`4*$BNSZ`
+	addi	r4,r4,`4*$BNSZ`
+	bdnz-	Lppcasm_mw_LOOP
+
+Lppcasm_mw_REM:
+	andi.	r5,r5,0x3
+	beq	Lppcasm_mw_OVER
+					#mul(rp[0],ap[0],w,c1);
+	$LD	r8,`0*$BNSZ`(r4)
+	$UMULL	r9,r6,r8
+	$UMULH  r10,r6,r8
+	addc	r9,r9,r12
+	addze	r10,r10
+	$ST	r9,`0*$BNSZ`(r3)
+	addi	r12,r10,0
+	
+	addi	r5,r5,-1
+	cmpli	0,0,r5,0
+	beq	Lppcasm_mw_OVER
+
+	
+					#mul(rp[1],ap[1],w,c1);
+	$LD	r8,`1*$BNSZ`(r4)	
+	$UMULL	r9,r6,r8
+	$UMULH  r10,r6,r8
+	addc	r9,r9,r12
+	addze	r10,r10
+	$ST	r9,`1*$BNSZ`(r3)
+	addi	r12,r10,0
+	
+	addi	r5,r5,-1
+	cmpli	0,0,r5,0
+	beq	Lppcasm_mw_OVER
+	
+					#mul_add(rp[2],ap[2],w,c1);
+	$LD	r8,`2*$BNSZ`(r4)
+	$UMULL	r9,r6,r8
+	$UMULH  r10,r6,r8
+	addc	r9,r9,r12
+	addze	r10,r10
+	$ST	r9,`2*$BNSZ`(r3)
+	addi	r12,r10,0
+		
+Lppcasm_mw_OVER:	
+	addi	r3,r12,0
+	blr
+	.long	0x00000000
+
+#
+#	NOTE:	The following label name should be changed to
+#		"bn_mul_add_words" i.e. remove the first dot
+#		for the gcc compiler. This should be automatically
+#		done in the build
+#
+
+.align	4
+.bn_mul_add_words:
+#
+# BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+#
+# r3 = rp
+# r4 = ap
+# r5 = num
+# r6 = w
+#
+# empirical evidence suggests that unrolled version performs best!!
+#
+	xor	r0,r0,r0		#r0 = 0
+	xor	r12,r12,r12  		#r12 = 0 . used for carry		
+	rlwinm.	r7,r5,30,2,31		# num >> 2
+	beq	Lppcasm_maw_leftover	# if (num < 4) go LPPCASM_maw_leftover
+	mtctr	r7
+Lppcasm_maw_mainloop:	
+					#mul_add(rp[0],ap[0],w,c1);
+	$LD	r8,`0*$BNSZ`(r4)
+	$LD	r11,`0*$BNSZ`(r3)
+	$UMULL	r9,r6,r8
+	$UMULH  r10,r6,r8
+	addc	r9,r9,r12		#r12 is carry.
+	addze	r10,r10
+	addc	r9,r9,r11
+	#addze	r10,r10
+					#the above instruction addze
+					#is NOT needed. Carry will NOT
+					#be ignored. It's not affected
+					#by multiply and will be collected
+					#in the next spin
+	$ST	r9,`0*$BNSZ`(r3)
+	
+					#mul_add(rp[1],ap[1],w,c1);
+	$LD	r8,`1*$BNSZ`(r4)	
+	$LD	r9,`1*$BNSZ`(r3)
+	$UMULL	r11,r6,r8
+	$UMULH  r12,r6,r8
+	adde	r11,r11,r10		#r10 is carry.
+	addze	r12,r12
+	addc	r11,r11,r9
+	#addze	r12,r12
+	$ST	r11,`1*$BNSZ`(r3)
+	
+					#mul_add(rp[2],ap[2],w,c1);
+	$LD	r8,`2*$BNSZ`(r4)
+	$UMULL	r9,r6,r8
+	$LD	r11,`2*$BNSZ`(r3)
+	$UMULH  r10,r6,r8
+	adde	r9,r9,r12
+	addze	r10,r10
+	addc	r9,r9,r11
+	#addze	r10,r10
+	$ST	r9,`2*$BNSZ`(r3)
+	
+					#mul_add(rp[3],ap[3],w,c1);
+	$LD	r8,`3*$BNSZ`(r4)
+	$UMULL	r11,r6,r8
+	$LD	r9,`3*$BNSZ`(r3)
+	$UMULH  r12,r6,r8
+	adde	r11,r11,r10
+	addze	r12,r12
+	addc	r11,r11,r9
+	addze	r12,r12
+	$ST	r11,`3*$BNSZ`(r3)
+	addi	r3,r3,`4*$BNSZ`
+	addi	r4,r4,`4*$BNSZ`
+	bdnz-	Lppcasm_maw_mainloop
+	
+Lppcasm_maw_leftover:
+	andi.	r5,r5,0x3
+	beq	Lppcasm_maw_adios
+	addi	r3,r3,-$BNSZ
+	addi	r4,r4,-$BNSZ
+					#mul_add(rp[0],ap[0],w,c1);
+	mtctr	r5
+	$LDU	r8,$BNSZ(r4)
+	$UMULL	r9,r6,r8
+	$UMULH  r10,r6,r8
+	$LDU	r11,$BNSZ(r3)
+	addc	r9,r9,r11
+	addze	r10,r10
+	addc	r9,r9,r12
+	addze	r12,r10
+	$ST	r9,0(r3)
+	
+	bdz	Lppcasm_maw_adios
+					#mul_add(rp[1],ap[1],w,c1);
+	$LDU	r8,$BNSZ(r4)	
+	$UMULL	r9,r6,r8
+	$UMULH  r10,r6,r8
+	$LDU	r11,$BNSZ(r3)
+	addc	r9,r9,r11
+	addze	r10,r10
+	addc	r9,r9,r12
+	addze	r12,r10
+	$ST	r9,0(r3)
+	
+	bdz	Lppcasm_maw_adios
+					#mul_add(rp[2],ap[2],w,c1);
+	$LDU	r8,$BNSZ(r4)
+	$UMULL	r9,r6,r8
+	$UMULH  r10,r6,r8
+	$LDU	r11,$BNSZ(r3)
+	addc	r9,r9,r11
+	addze	r10,r10
+	addc	r9,r9,r12
+	addze	r12,r10
+	$ST	r9,0(r3)
+		
+Lppcasm_maw_adios:	
+	addi	r3,r12,0
+	blr
+	.long	0x00000000
+	.align	4
+EOF
+$data =~ s/\`([^\`]*)\`/eval $1/gem;
+print $data;
+close STDOUT;
diff --git a/openssl/crypto/bn/asm/ppc64-mont.pl b/openssl/crypto/bn/asm/ppc64-mont.pl
new file mode 100644
index 0000000..3449b35
--- /dev/null
+++ b/openssl/crypto/bn/asm/ppc64-mont.pl
@@ -0,0 +1,918 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# December 2007
+
+# The reason for undertaken effort is basically following. Even though
+# Power 6 CPU operates at incredible 4.7GHz clock frequency, its PKI
+# performance was observed to be less than impressive, essentially as
+# fast as 1.8GHz PPC970, or 2.6 times(!) slower than one would hope.
+# Well, it's not surprising that IBM had to make some sacrifices to
+# boost the clock frequency that much, but no overall improvement?
+# Having observed how much difference did switching to FPU make on
+# UltraSPARC, playing same stunt on Power 6 appeared appropriate...
+# Unfortunately the resulting performance improvement is not as
+# impressive, ~30%, and in absolute terms is still very far from what
+# one would expect from 4.7GHz CPU. There is a chance that I'm doing
+# something wrong, but in the lack of assembler level micro-profiling
+# data or at least decent platform guide I can't tell... Or better
+# results might be achieved with VMX... Anyway, this module provides
+# *worse* performance on other PowerPC implementations, ~40-15% slower
+# on PPC970 depending on key length and ~40% slower on Power 5 for all
+# key lengths. As it's obviously inappropriate as "best all-round"
+# alternative, it has to be complemented with run-time CPU family
+# detection. Oh! It should also be noted that unlike other PowerPC
+# implementation IALU ppc-mont.pl module performs *suboptimaly* on
+# >=1024-bit key lengths on Power 6. It should also be noted that
+# *everything* said so far applies to 64-bit builds! As far as 32-bit
+# application executed on 64-bit CPU goes, this module is likely to
+# become preferred choice, because it's easy to adapt it for such
+# case and *is* faster than 32-bit ppc-mont.pl on *all* processors.
+
+# February 2008
+
+# Micro-profiling assisted optimization results in ~15% improvement
+# over original ppc64-mont.pl version, or overall ~50% improvement
+# over ppc.pl module on Power 6. If compared to ppc-mont.pl on same
+# Power 6 CPU, this module is 5-150% faster depending on key length,
+# [hereafter] more for longer keys. But if compared to ppc-mont.pl
+# on 1.8GHz PPC970, it's only 5-55% faster. Still far from impressive
+# in absolute terms, but it's apparently the way Power 6 is...
+
+$flavour = shift;
+
+if ($flavour =~ /32/) {
+	$SIZE_T=4;
+	$RZONE=	224;
+	$FRAME=	$SIZE_T*12+8*12;
+	$fname=	"bn_mul_mont_ppc64";
+
+	$STUX=	"stwux";	# store indexed and update
+	$PUSH=	"stw";
+	$POP=	"lwz";
+	die "not implemented yet";
+} elsif ($flavour =~ /64/) {
+	$SIZE_T=8;
+	$RZONE=	288;
+	$FRAME=	$SIZE_T*12+8*12;
+	$fname=	"bn_mul_mont";
+
+	# same as above, but 64-bit mnemonics...
+	$STUX=	"stdux";	# store indexed and update
+	$PUSH=	"std";
+	$POP=	"ld";
+} else { die "nonsense $flavour"; }
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
+
+$FRAME=($FRAME+63)&~63;
+$TRANSFER=16*8;
+
+$carry="r0";
+$sp="r1";
+$toc="r2";
+$rp="r3";	$ovf="r3";
+$ap="r4";
+$bp="r5";
+$np="r6";
+$n0="r7";
+$num="r8";
+$rp="r9";	# $rp is reassigned
+$tp="r10";
+$j="r11";
+$i="r12";
+# non-volatile registers
+$nap_d="r14";	# interleaved ap and np in double format
+$a0="r15";	# ap[0]
+$t0="r16";	# temporary registers
+$t1="r17";
+$t2="r18";
+$t3="r19";
+$t4="r20";
+$t5="r21";
+$t6="r22";
+$t7="r23";
+
+# PPC offers enough register bank capacity to unroll inner loops twice
+#
+#     ..A3A2A1A0
+#           dcba
+#    -----------
+#            A0a
+#           A0b
+#          A0c
+#         A0d
+#          A1a
+#         A1b
+#        A1c
+#       A1d
+#        A2a
+#       A2b
+#      A2c
+#     A2d
+#      A3a
+#     A3b
+#    A3c
+#   A3d
+#    ..a
+#   ..b
+#
+$ba="f0";	$bb="f1";	$bc="f2";	$bd="f3";
+$na="f4";	$nb="f5";	$nc="f6";	$nd="f7";
+$dota="f8";	$dotb="f9";
+$A0="f10";	$A1="f11";	$A2="f12";	$A3="f13";
+$N0="f14";	$N1="f15";	$N2="f16";	$N3="f17";
+$T0a="f18";	$T0b="f19";
+$T1a="f20";	$T1b="f21";
+$T2a="f22";	$T2b="f23";
+$T3a="f24";	$T3b="f25";
+
+# sp----------->+-------------------------------+
+#		| saved sp			|
+#		+-------------------------------+
+#		|				|
+#		+-------------------------------+
+#		| 10 saved gpr, r14-r23		|
+#		.				.
+#		.				.
+#   +12*size_t	+-------------------------------+
+#		| 12 saved fpr, f14-f25		|
+#		.				.
+#		.				.
+#   +12*8	+-------------------------------+
+#		| padding to 64 byte boundary	|
+#		.				.
+#   +X		+-------------------------------+
+#		| 16 gpr<->fpr transfer zone	|
+#		.				.
+#		.				.
+#   +16*8	+-------------------------------+
+#		| __int64 tmp[-1]		|
+#		+-------------------------------+
+#		| __int64 tmp[num]		|
+#		.				.
+#		.				.
+#		.				.
+#   +(num+1)*8	+-------------------------------+
+#		| padding to 64 byte boundary	|
+#		.				.
+#   +X		+-------------------------------+
+#		| double nap_d[4*num]		|
+#		.				.
+#		.				.
+#		.				.
+#		+-------------------------------+
+
+$code=<<___;
+.machine "any"
+.text
+
+.globl	.$fname
+.align	5
+.$fname:
+	cmpwi	$num,4
+	mr	$rp,r3		; $rp is reassigned
+	li	r3,0		; possible "not handled" return code
+	bltlr-
+	andi.	r0,$num,1	; $num has to be even
+	bnelr-
+
+	slwi	$num,$num,3	; num*=8
+	li	$i,-4096
+	slwi	$tp,$num,2	; place for {an}p_{lh}[num], i.e. 4*num
+	add	$tp,$tp,$num	; place for tp[num+1]
+	addi	$tp,$tp,`$FRAME+$TRANSFER+8+64+$RZONE`
+	subf	$tp,$tp,$sp	; $sp-$tp
+	and	$tp,$tp,$i	; minimize TLB usage
+	subf	$tp,$sp,$tp	; $tp-$sp
+	$STUX	$sp,$sp,$tp	; alloca
+
+	$PUSH	r14,`2*$SIZE_T`($sp)
+	$PUSH	r15,`3*$SIZE_T`($sp)
+	$PUSH	r16,`4*$SIZE_T`($sp)
+	$PUSH	r17,`5*$SIZE_T`($sp)
+	$PUSH	r18,`6*$SIZE_T`($sp)
+	$PUSH	r19,`7*$SIZE_T`($sp)
+	$PUSH	r20,`8*$SIZE_T`($sp)
+	$PUSH	r21,`9*$SIZE_T`($sp)
+	$PUSH	r22,`10*$SIZE_T`($sp)
+	$PUSH	r23,`11*$SIZE_T`($sp)
+	stfd	f14,`12*$SIZE_T+0`($sp)
+	stfd	f15,`12*$SIZE_T+8`($sp)
+	stfd	f16,`12*$SIZE_T+16`($sp)
+	stfd	f17,`12*$SIZE_T+24`($sp)
+	stfd	f18,`12*$SIZE_T+32`($sp)
+	stfd	f19,`12*$SIZE_T+40`($sp)
+	stfd	f20,`12*$SIZE_T+48`($sp)
+	stfd	f21,`12*$SIZE_T+56`($sp)
+	stfd	f22,`12*$SIZE_T+64`($sp)
+	stfd	f23,`12*$SIZE_T+72`($sp)
+	stfd	f24,`12*$SIZE_T+80`($sp)
+	stfd	f25,`12*$SIZE_T+88`($sp)
+
+	ld	$a0,0($ap)	; pull ap[0] value
+	ld	$n0,0($n0)	; pull n0[0] value
+	ld	$t3,0($bp)	; bp[0]
+
+	addi	$tp,$sp,`$FRAME+$TRANSFER+8+64`
+	li	$i,-64
+	add	$nap_d,$tp,$num
+	and	$nap_d,$nap_d,$i	; align to 64 bytes
+
+	mulld	$t7,$a0,$t3	; ap[0]*bp[0]
+	; nap_d is off by 1, because it's used with stfdu/lfdu
+	addi	$nap_d,$nap_d,-8
+	srwi	$j,$num,`3+1`	; counter register, num/2
+	mulld	$t7,$t7,$n0	; tp[0]*n0
+	addi	$j,$j,-1
+	addi	$tp,$sp,`$FRAME+$TRANSFER-8`
+	li	$carry,0
+	mtctr	$j
+
+	; transfer bp[0] to FPU as 4x16-bit values
+	extrdi	$t0,$t3,16,48
+	extrdi	$t1,$t3,16,32
+	extrdi	$t2,$t3,16,16
+	extrdi	$t3,$t3,16,0
+	std	$t0,`$FRAME+0`($sp)
+	std	$t1,`$FRAME+8`($sp)
+	std	$t2,`$FRAME+16`($sp)
+	std	$t3,`$FRAME+24`($sp)
+	; transfer (ap[0]*bp[0])*n0 to FPU as 4x16-bit values
+	extrdi	$t4,$t7,16,48
+	extrdi	$t5,$t7,16,32
+	extrdi	$t6,$t7,16,16
+	extrdi	$t7,$t7,16,0
+	std	$t4,`$FRAME+32`($sp)
+	std	$t5,`$FRAME+40`($sp)
+	std	$t6,`$FRAME+48`($sp)
+	std	$t7,`$FRAME+56`($sp)
+	lwz	$t0,4($ap)		; load a[j] as 32-bit word pair
+	lwz	$t1,0($ap)
+	lwz	$t2,12($ap)		; load a[j+1] as 32-bit word pair
+	lwz	$t3,8($ap)
+	lwz	$t4,4($np)		; load n[j] as 32-bit word pair
+	lwz	$t5,0($np)
+	lwz	$t6,12($np)		; load n[j+1] as 32-bit word pair
+	lwz	$t7,8($np)
+	lfd	$ba,`$FRAME+0`($sp)
+	lfd	$bb,`$FRAME+8`($sp)
+	lfd	$bc,`$FRAME+16`($sp)
+	lfd	$bd,`$FRAME+24`($sp)
+	lfd	$na,`$FRAME+32`($sp)
+	lfd	$nb,`$FRAME+40`($sp)
+	lfd	$nc,`$FRAME+48`($sp)
+	lfd	$nd,`$FRAME+56`($sp)
+	std	$t0,`$FRAME+64`($sp)
+	std	$t1,`$FRAME+72`($sp)
+	std	$t2,`$FRAME+80`($sp)
+	std	$t3,`$FRAME+88`($sp)
+	std	$t4,`$FRAME+96`($sp)
+	std	$t5,`$FRAME+104`($sp)
+	std	$t6,`$FRAME+112`($sp)
+	std	$t7,`$FRAME+120`($sp)
+	fcfid	$ba,$ba
+	fcfid	$bb,$bb
+	fcfid	$bc,$bc
+	fcfid	$bd,$bd
+	fcfid	$na,$na
+	fcfid	$nb,$nb
+	fcfid	$nc,$nc
+	fcfid	$nd,$nd
+
+	lfd	$A0,`$FRAME+64`($sp)
+	lfd	$A1,`$FRAME+72`($sp)
+	lfd	$A2,`$FRAME+80`($sp)
+	lfd	$A3,`$FRAME+88`($sp)
+	lfd	$N0,`$FRAME+96`($sp)
+	lfd	$N1,`$FRAME+104`($sp)
+	lfd	$N2,`$FRAME+112`($sp)
+	lfd	$N3,`$FRAME+120`($sp)
+	fcfid	$A0,$A0
+	fcfid	$A1,$A1
+	fcfid	$A2,$A2
+	fcfid	$A3,$A3
+	fcfid	$N0,$N0
+	fcfid	$N1,$N1
+	fcfid	$N2,$N2
+	fcfid	$N3,$N3
+	addi	$ap,$ap,16
+	addi	$np,$np,16
+
+	fmul	$T1a,$A1,$ba
+	fmul	$T1b,$A1,$bb
+	stfd	$A0,8($nap_d)		; save a[j] in double format
+	stfd	$A1,16($nap_d)
+	fmul	$T2a,$A2,$ba
+	fmul	$T2b,$A2,$bb
+	stfd	$A2,24($nap_d)		; save a[j+1] in double format
+	stfd	$A3,32($nap_d)
+	fmul	$T3a,$A3,$ba
+	fmul	$T3b,$A3,$bb
+	stfd	$N0,40($nap_d)		; save n[j] in double format
+	stfd	$N1,48($nap_d)
+	fmul	$T0a,$A0,$ba
+	fmul	$T0b,$A0,$bb
+	stfd	$N2,56($nap_d)		; save n[j+1] in double format
+	stfdu	$N3,64($nap_d)
+
+	fmadd	$T1a,$A0,$bc,$T1a
+	fmadd	$T1b,$A0,$bd,$T1b
+	fmadd	$T2a,$A1,$bc,$T2a
+	fmadd	$T2b,$A1,$bd,$T2b
+	fmadd	$T3a,$A2,$bc,$T3a
+	fmadd	$T3b,$A2,$bd,$T3b
+	fmul	$dota,$A3,$bc
+	fmul	$dotb,$A3,$bd
+
+	fmadd	$T1a,$N1,$na,$T1a
+	fmadd	$T1b,$N1,$nb,$T1b
+	fmadd	$T2a,$N2,$na,$T2a
+	fmadd	$T2b,$N2,$nb,$T2b
+	fmadd	$T3a,$N3,$na,$T3a
+	fmadd	$T3b,$N3,$nb,$T3b
+	fmadd	$T0a,$N0,$na,$T0a
+	fmadd	$T0b,$N0,$nb,$T0b
+
+	fmadd	$T1a,$N0,$nc,$T1a
+	fmadd	$T1b,$N0,$nd,$T1b
+	fmadd	$T2a,$N1,$nc,$T2a
+	fmadd	$T2b,$N1,$nd,$T2b
+	fmadd	$T3a,$N2,$nc,$T3a
+	fmadd	$T3b,$N2,$nd,$T3b
+	fmadd	$dota,$N3,$nc,$dota
+	fmadd	$dotb,$N3,$nd,$dotb
+
+	fctid	$T0a,$T0a
+	fctid	$T0b,$T0b
+	fctid	$T1a,$T1a
+	fctid	$T1b,$T1b
+	fctid	$T2a,$T2a
+	fctid	$T2b,$T2b
+	fctid	$T3a,$T3a
+	fctid	$T3b,$T3b
+
+	stfd	$T0a,`$FRAME+0`($sp)
+	stfd	$T0b,`$FRAME+8`($sp)
+	stfd	$T1a,`$FRAME+16`($sp)
+	stfd	$T1b,`$FRAME+24`($sp)
+	stfd	$T2a,`$FRAME+32`($sp)
+	stfd	$T2b,`$FRAME+40`($sp)
+	stfd	$T3a,`$FRAME+48`($sp)
+	stfd	$T3b,`$FRAME+56`($sp)
+
+.align	5
+L1st:
+	lwz	$t0,4($ap)		; load a[j] as 32-bit word pair
+	lwz	$t1,0($ap)
+	lwz	$t2,12($ap)		; load a[j+1] as 32-bit word pair
+	lwz	$t3,8($ap)
+	lwz	$t4,4($np)		; load n[j] as 32-bit word pair
+	lwz	$t5,0($np)
+	lwz	$t6,12($np)		; load n[j+1] as 32-bit word pair
+	lwz	$t7,8($np)
+	std	$t0,`$FRAME+64`($sp)
+	std	$t1,`$FRAME+72`($sp)
+	std	$t2,`$FRAME+80`($sp)
+	std	$t3,`$FRAME+88`($sp)
+	std	$t4,`$FRAME+96`($sp)
+	std	$t5,`$FRAME+104`($sp)
+	std	$t6,`$FRAME+112`($sp)
+	std	$t7,`$FRAME+120`($sp)
+	ld	$t0,`$FRAME+0`($sp)
+	ld	$t1,`$FRAME+8`($sp)
+	ld	$t2,`$FRAME+16`($sp)
+	ld	$t3,`$FRAME+24`($sp)
+	ld	$t4,`$FRAME+32`($sp)
+	ld	$t5,`$FRAME+40`($sp)
+	ld	$t6,`$FRAME+48`($sp)
+	ld	$t7,`$FRAME+56`($sp)
+	lfd	$A0,`$FRAME+64`($sp)
+	lfd	$A1,`$FRAME+72`($sp)
+	lfd	$A2,`$FRAME+80`($sp)
+	lfd	$A3,`$FRAME+88`($sp)
+	lfd	$N0,`$FRAME+96`($sp)
+	lfd	$N1,`$FRAME+104`($sp)
+	lfd	$N2,`$FRAME+112`($sp)
+	lfd	$N3,`$FRAME+120`($sp)
+	fcfid	$A0,$A0
+	fcfid	$A1,$A1
+	fcfid	$A2,$A2
+	fcfid	$A3,$A3
+	fcfid	$N0,$N0
+	fcfid	$N1,$N1
+	fcfid	$N2,$N2
+	fcfid	$N3,$N3
+	addi	$ap,$ap,16
+	addi	$np,$np,16
+
+	fmul	$T1a,$A1,$ba
+	fmul	$T1b,$A1,$bb
+	fmul	$T2a,$A2,$ba
+	fmul	$T2b,$A2,$bb
+	stfd	$A0,8($nap_d)		; save a[j] in double format
+	stfd	$A1,16($nap_d)
+	fmul	$T3a,$A3,$ba
+	fmul	$T3b,$A3,$bb
+	fmadd	$T0a,$A0,$ba,$dota
+	fmadd	$T0b,$A0,$bb,$dotb
+	stfd	$A2,24($nap_d)		; save a[j+1] in double format
+	stfd	$A3,32($nap_d)
+
+	fmadd	$T1a,$A0,$bc,$T1a
+	fmadd	$T1b,$A0,$bd,$T1b
+	fmadd	$T2a,$A1,$bc,$T2a
+	fmadd	$T2b,$A1,$bd,$T2b
+	stfd	$N0,40($nap_d)		; save n[j] in double format
+	stfd	$N1,48($nap_d)
+	fmadd	$T3a,$A2,$bc,$T3a
+	fmadd	$T3b,$A2,$bd,$T3b
+	 add	$t0,$t0,$carry		; can not overflow
+	fmul	$dota,$A3,$bc
+	fmul	$dotb,$A3,$bd
+	stfd	$N2,56($nap_d)		; save n[j+1] in double format
+	stfdu	$N3,64($nap_d)
+	 srdi	$carry,$t0,16
+	 add	$t1,$t1,$carry
+	 srdi	$carry,$t1,16
+
+	fmadd	$T1a,$N1,$na,$T1a
+	fmadd	$T1b,$N1,$nb,$T1b
+	 insrdi	$t0,$t1,16,32
+	fmadd	$T2a,$N2,$na,$T2a
+	fmadd	$T2b,$N2,$nb,$T2b
+	 add	$t2,$t2,$carry
+	fmadd	$T3a,$N3,$na,$T3a
+	fmadd	$T3b,$N3,$nb,$T3b
+	 srdi	$carry,$t2,16
+	fmadd	$T0a,$N0,$na,$T0a
+	fmadd	$T0b,$N0,$nb,$T0b
+	 insrdi	$t0,$t2,16,16
+	 add	$t3,$t3,$carry
+	 srdi	$carry,$t3,16
+
+	fmadd	$T1a,$N0,$nc,$T1a
+	fmadd	$T1b,$N0,$nd,$T1b
+	 insrdi	$t0,$t3,16,0		; 0..63 bits
+	fmadd	$T2a,$N1,$nc,$T2a
+	fmadd	$T2b,$N1,$nd,$T2b
+	 add	$t4,$t4,$carry
+	fmadd	$T3a,$N2,$nc,$T3a
+	fmadd	$T3b,$N2,$nd,$T3b
+	 srdi	$carry,$t4,16
+	fmadd	$dota,$N3,$nc,$dota
+	fmadd	$dotb,$N3,$nd,$dotb
+	 add	$t5,$t5,$carry
+	 srdi	$carry,$t5,16
+	 insrdi	$t4,$t5,16,32
+
+	fctid	$T0a,$T0a
+	fctid	$T0b,$T0b
+	 add	$t6,$t6,$carry
+	fctid	$T1a,$T1a
+	fctid	$T1b,$T1b
+	 srdi	$carry,$t6,16
+	fctid	$T2a,$T2a
+	fctid	$T2b,$T2b
+	 insrdi	$t4,$t6,16,16
+	fctid	$T3a,$T3a
+	fctid	$T3b,$T3b
+	 add	$t7,$t7,$carry
+	 insrdi	$t4,$t7,16,0		; 64..127 bits
+	 srdi	$carry,$t7,16		; upper 33 bits
+
+	stfd	$T0a,`$FRAME+0`($sp)
+	stfd	$T0b,`$FRAME+8`($sp)
+	stfd	$T1a,`$FRAME+16`($sp)
+	stfd	$T1b,`$FRAME+24`($sp)
+	stfd	$T2a,`$FRAME+32`($sp)
+	stfd	$T2b,`$FRAME+40`($sp)
+	stfd	$T3a,`$FRAME+48`($sp)
+	stfd	$T3b,`$FRAME+56`($sp)
+	 std	$t0,8($tp)		; tp[j-1]
+	 stdu	$t4,16($tp)		; tp[j]
+	bdnz-	L1st
+
+	fctid	$dota,$dota
+	fctid	$dotb,$dotb
+
+	ld	$t0,`$FRAME+0`($sp)
+	ld	$t1,`$FRAME+8`($sp)
+	ld	$t2,`$FRAME+16`($sp)
+	ld	$t3,`$FRAME+24`($sp)
+	ld	$t4,`$FRAME+32`($sp)
+	ld	$t5,`$FRAME+40`($sp)
+	ld	$t6,`$FRAME+48`($sp)
+	ld	$t7,`$FRAME+56`($sp)
+	stfd	$dota,`$FRAME+64`($sp)
+	stfd	$dotb,`$FRAME+72`($sp)
+
+	add	$t0,$t0,$carry		; can not overflow
+	srdi	$carry,$t0,16
+	add	$t1,$t1,$carry
+	srdi	$carry,$t1,16
+	insrdi	$t0,$t1,16,32
+	add	$t2,$t2,$carry
+	srdi	$carry,$t2,16
+	insrdi	$t0,$t2,16,16
+	add	$t3,$t3,$carry
+	srdi	$carry,$t3,16
+	insrdi	$t0,$t3,16,0		; 0..63 bits
+	add	$t4,$t4,$carry
+	srdi	$carry,$t4,16
+	add	$t5,$t5,$carry
+	srdi	$carry,$t5,16
+	insrdi	$t4,$t5,16,32
+	add	$t6,$t6,$carry
+	srdi	$carry,$t6,16
+	insrdi	$t4,$t6,16,16
+	add	$t7,$t7,$carry
+	insrdi	$t4,$t7,16,0		; 64..127 bits
+	srdi	$carry,$t7,16		; upper 33 bits
+	ld	$t6,`$FRAME+64`($sp)
+	ld	$t7,`$FRAME+72`($sp)
+
+	std	$t0,8($tp)		; tp[j-1]
+	stdu	$t4,16($tp)		; tp[j]
+
+	add	$t6,$t6,$carry		; can not overflow
+	srdi	$carry,$t6,16
+	add	$t7,$t7,$carry
+	insrdi	$t6,$t7,48,0
+	srdi	$ovf,$t7,48
+	std	$t6,8($tp)		; tp[num-1]
+
+	slwi	$t7,$num,2
+	subf	$nap_d,$t7,$nap_d	; rewind pointer
+
+	li	$i,8			; i=1
+.align	5
+Louter:
+	ldx	$t3,$bp,$i	; bp[i]
+	ld	$t6,`$FRAME+$TRANSFER+8`($sp)	; tp[0]
+	mulld	$t7,$a0,$t3	; ap[0]*bp[i]
+
+	addi	$tp,$sp,`$FRAME+$TRANSFER`
+	add	$t7,$t7,$t6	; ap[0]*bp[i]+tp[0]
+	li	$carry,0
+	mulld	$t7,$t7,$n0	; tp[0]*n0
+	mtctr	$j
+
+	; transfer bp[i] to FPU as 4x16-bit values
+	extrdi	$t0,$t3,16,48
+	extrdi	$t1,$t3,16,32
+	extrdi	$t2,$t3,16,16
+	extrdi	$t3,$t3,16,0
+	std	$t0,`$FRAME+0`($sp)
+	std	$t1,`$FRAME+8`($sp)
+	std	$t2,`$FRAME+16`($sp)
+	std	$t3,`$FRAME+24`($sp)
+	; transfer (ap[0]*bp[i]+tp[0])*n0 to FPU as 4x16-bit values
+	extrdi	$t4,$t7,16,48
+	extrdi	$t5,$t7,16,32
+	extrdi	$t6,$t7,16,16
+	extrdi	$t7,$t7,16,0
+	std	$t4,`$FRAME+32`($sp)
+	std	$t5,`$FRAME+40`($sp)
+	std	$t6,`$FRAME+48`($sp)
+	std	$t7,`$FRAME+56`($sp)
+
+	lfd	$A0,8($nap_d)		; load a[j] in double format
+	lfd	$A1,16($nap_d)
+	lfd	$A2,24($nap_d)		; load a[j+1] in double format
+	lfd	$A3,32($nap_d)
+	lfd	$N0,40($nap_d)		; load n[j] in double format
+	lfd	$N1,48($nap_d)
+	lfd	$N2,56($nap_d)		; load n[j+1] in double format
+	lfdu	$N3,64($nap_d)
+
+	lfd	$ba,`$FRAME+0`($sp)
+	lfd	$bb,`$FRAME+8`($sp)
+	lfd	$bc,`$FRAME+16`($sp)
+	lfd	$bd,`$FRAME+24`($sp)
+	lfd	$na,`$FRAME+32`($sp)
+	lfd	$nb,`$FRAME+40`($sp)
+	lfd	$nc,`$FRAME+48`($sp)
+	lfd	$nd,`$FRAME+56`($sp)
+
+	fcfid	$ba,$ba
+	fcfid	$bb,$bb
+	fcfid	$bc,$bc
+	fcfid	$bd,$bd
+	fcfid	$na,$na
+	fcfid	$nb,$nb
+	fcfid	$nc,$nc
+	fcfid	$nd,$nd
+
+	fmul	$T1a,$A1,$ba
+	fmul	$T1b,$A1,$bb
+	fmul	$T2a,$A2,$ba
+	fmul	$T2b,$A2,$bb
+	fmul	$T3a,$A3,$ba
+	fmul	$T3b,$A3,$bb
+	fmul	$T0a,$A0,$ba
+	fmul	$T0b,$A0,$bb
+
+	fmadd	$T1a,$A0,$bc,$T1a
+	fmadd	$T1b,$A0,$bd,$T1b
+	fmadd	$T2a,$A1,$bc,$T2a
+	fmadd	$T2b,$A1,$bd,$T2b
+	fmadd	$T3a,$A2,$bc,$T3a
+	fmadd	$T3b,$A2,$bd,$T3b
+	fmul	$dota,$A3,$bc
+	fmul	$dotb,$A3,$bd
+
+	fmadd	$T1a,$N1,$na,$T1a
+	fmadd	$T1b,$N1,$nb,$T1b
+	 lfd	$A0,8($nap_d)		; load a[j] in double format
+	 lfd	$A1,16($nap_d)
+	fmadd	$T2a,$N2,$na,$T2a
+	fmadd	$T2b,$N2,$nb,$T2b
+	 lfd	$A2,24($nap_d)		; load a[j+1] in double format
+	 lfd	$A3,32($nap_d)
+	fmadd	$T3a,$N3,$na,$T3a
+	fmadd	$T3b,$N3,$nb,$T3b
+	fmadd	$T0a,$N0,$na,$T0a
+	fmadd	$T0b,$N0,$nb,$T0b
+
+	fmadd	$T1a,$N0,$nc,$T1a
+	fmadd	$T1b,$N0,$nd,$T1b
+	fmadd	$T2a,$N1,$nc,$T2a
+	fmadd	$T2b,$N1,$nd,$T2b
+	fmadd	$T3a,$N2,$nc,$T3a
+	fmadd	$T3b,$N2,$nd,$T3b
+	fmadd	$dota,$N3,$nc,$dota
+	fmadd	$dotb,$N3,$nd,$dotb
+
+	fctid	$T0a,$T0a
+	fctid	$T0b,$T0b
+	fctid	$T1a,$T1a
+	fctid	$T1b,$T1b
+	fctid	$T2a,$T2a
+	fctid	$T2b,$T2b
+	fctid	$T3a,$T3a
+	fctid	$T3b,$T3b
+
+	stfd	$T0a,`$FRAME+0`($sp)
+	stfd	$T0b,`$FRAME+8`($sp)
+	stfd	$T1a,`$FRAME+16`($sp)
+	stfd	$T1b,`$FRAME+24`($sp)
+	stfd	$T2a,`$FRAME+32`($sp)
+	stfd	$T2b,`$FRAME+40`($sp)
+	stfd	$T3a,`$FRAME+48`($sp)
+	stfd	$T3b,`$FRAME+56`($sp)
+
+.align	5
+Linner:
+	fmul	$T1a,$A1,$ba
+	fmul	$T1b,$A1,$bb
+	fmul	$T2a,$A2,$ba
+	fmul	$T2b,$A2,$bb
+	lfd	$N0,40($nap_d)		; load n[j] in double format
+	lfd	$N1,48($nap_d)
+	fmul	$T3a,$A3,$ba
+	fmul	$T3b,$A3,$bb
+	fmadd	$T0a,$A0,$ba,$dota
+	fmadd	$T0b,$A0,$bb,$dotb
+	lfd	$N2,56($nap_d)		; load n[j+1] in double format
+	lfdu	$N3,64($nap_d)
+
+	fmadd	$T1a,$A0,$bc,$T1a
+	fmadd	$T1b,$A0,$bd,$T1b
+	fmadd	$T2a,$A1,$bc,$T2a
+	fmadd	$T2b,$A1,$bd,$T2b
+	 lfd	$A0,8($nap_d)		; load a[j] in double format
+	 lfd	$A1,16($nap_d)
+	fmadd	$T3a,$A2,$bc,$T3a
+	fmadd	$T3b,$A2,$bd,$T3b
+	fmul	$dota,$A3,$bc
+	fmul	$dotb,$A3,$bd
+	 lfd	$A2,24($nap_d)		; load a[j+1] in double format
+	 lfd	$A3,32($nap_d)
+
+	fmadd	$T1a,$N1,$na,$T1a
+	fmadd	$T1b,$N1,$nb,$T1b
+	 ld	$t0,`$FRAME+0`($sp)
+	 ld	$t1,`$FRAME+8`($sp)
+	fmadd	$T2a,$N2,$na,$T2a
+	fmadd	$T2b,$N2,$nb,$T2b
+	 ld	$t2,`$FRAME+16`($sp)
+	 ld	$t3,`$FRAME+24`($sp)
+	fmadd	$T3a,$N3,$na,$T3a
+	fmadd	$T3b,$N3,$nb,$T3b
+	 add	$t0,$t0,$carry		; can not overflow
+	 ld	$t4,`$FRAME+32`($sp)
+	 ld	$t5,`$FRAME+40`($sp)
+	fmadd	$T0a,$N0,$na,$T0a
+	fmadd	$T0b,$N0,$nb,$T0b
+	 srdi	$carry,$t0,16
+	 add	$t1,$t1,$carry
+	 srdi	$carry,$t1,16
+	 ld	$t6,`$FRAME+48`($sp)
+	 ld	$t7,`$FRAME+56`($sp)
+
+	fmadd	$T1a,$N0,$nc,$T1a
+	fmadd	$T1b,$N0,$nd,$T1b
+	 insrdi	$t0,$t1,16,32
+	 ld	$t1,8($tp)		; tp[j]
+	fmadd	$T2a,$N1,$nc,$T2a
+	fmadd	$T2b,$N1,$nd,$T2b
+	 add	$t2,$t2,$carry
+	fmadd	$T3a,$N2,$nc,$T3a
+	fmadd	$T3b,$N2,$nd,$T3b
+	 srdi	$carry,$t2,16
+	 insrdi	$t0,$t2,16,16
+	fmadd	$dota,$N3,$nc,$dota
+	fmadd	$dotb,$N3,$nd,$dotb
+	 add	$t3,$t3,$carry
+	 ldu	$t2,16($tp)		; tp[j+1]
+	 srdi	$carry,$t3,16
+	 insrdi	$t0,$t3,16,0		; 0..63 bits
+	 add	$t4,$t4,$carry
+
+	fctid	$T0a,$T0a
+	fctid	$T0b,$T0b
+	 srdi	$carry,$t4,16
+	fctid	$T1a,$T1a
+	fctid	$T1b,$T1b
+	 add	$t5,$t5,$carry
+	fctid	$T2a,$T2a
+	fctid	$T2b,$T2b
+	 srdi	$carry,$t5,16
+	 insrdi	$t4,$t5,16,32
+	fctid	$T3a,$T3a
+	fctid	$T3b,$T3b
+	 add	$t6,$t6,$carry
+	 srdi	$carry,$t6,16
+	 insrdi	$t4,$t6,16,16
+
+	stfd	$T0a,`$FRAME+0`($sp)
+	stfd	$T0b,`$FRAME+8`($sp)
+	 add	$t7,$t7,$carry
+	 addc	$t3,$t0,$t1
+	stfd	$T1a,`$FRAME+16`($sp)
+	stfd	$T1b,`$FRAME+24`($sp)
+	 insrdi	$t4,$t7,16,0		; 64..127 bits
+	 srdi	$carry,$t7,16		; upper 33 bits
+	stfd	$T2a,`$FRAME+32`($sp)
+	stfd	$T2b,`$FRAME+40`($sp)
+	 adde	$t5,$t4,$t2
+	stfd	$T3a,`$FRAME+48`($sp)
+	stfd	$T3b,`$FRAME+56`($sp)
+	 addze	$carry,$carry
+	 std	$t3,-16($tp)		; tp[j-1]
+	 std	$t5,-8($tp)		; tp[j]
+	bdnz-	Linner
+
+	fctid	$dota,$dota
+	fctid	$dotb,$dotb
+	ld	$t0,`$FRAME+0`($sp)
+	ld	$t1,`$FRAME+8`($sp)
+	ld	$t2,`$FRAME+16`($sp)
+	ld	$t3,`$FRAME+24`($sp)
+	ld	$t4,`$FRAME+32`($sp)
+	ld	$t5,`$FRAME+40`($sp)
+	ld	$t6,`$FRAME+48`($sp)
+	ld	$t7,`$FRAME+56`($sp)
+	stfd	$dota,`$FRAME+64`($sp)
+	stfd	$dotb,`$FRAME+72`($sp)
+
+	add	$t0,$t0,$carry		; can not overflow
+	srdi	$carry,$t0,16
+	add	$t1,$t1,$carry
+	srdi	$carry,$t1,16
+	insrdi	$t0,$t1,16,32
+	add	$t2,$t2,$carry
+	ld	$t1,8($tp)		; tp[j]
+	srdi	$carry,$t2,16
+	insrdi	$t0,$t2,16,16
+	add	$t3,$t3,$carry
+	ldu	$t2,16($tp)		; tp[j+1]
+	srdi	$carry,$t3,16
+	insrdi	$t0,$t3,16,0		; 0..63 bits
+	add	$t4,$t4,$carry
+	srdi	$carry,$t4,16
+	add	$t5,$t5,$carry
+	srdi	$carry,$t5,16
+	insrdi	$t4,$t5,16,32
+	add	$t6,$t6,$carry
+	srdi	$carry,$t6,16
+	insrdi	$t4,$t6,16,16
+	add	$t7,$t7,$carry
+	insrdi	$t4,$t7,16,0		; 64..127 bits
+	srdi	$carry,$t7,16		; upper 33 bits
+	ld	$t6,`$FRAME+64`($sp)
+	ld	$t7,`$FRAME+72`($sp)
+
+	addc	$t3,$t0,$t1
+	adde	$t5,$t4,$t2
+	addze	$carry,$carry
+
+	std	$t3,-16($tp)		; tp[j-1]
+	std	$t5,-8($tp)		; tp[j]
+
+	add	$carry,$carry,$ovf	; comsume upmost overflow
+	add	$t6,$t6,$carry		; can not overflow
+	srdi	$carry,$t6,16
+	add	$t7,$t7,$carry
+	insrdi	$t6,$t7,48,0
+	srdi	$ovf,$t7,48
+	std	$t6,0($tp)		; tp[num-1]
+
+	slwi	$t7,$num,2
+	addi	$i,$i,8
+	subf	$nap_d,$t7,$nap_d	; rewind pointer
+	cmpw	$i,$num
+	blt-	Louter
+
+	subf	$np,$num,$np	; rewind np
+	addi	$j,$j,1		; restore counter
+	subfc	$i,$i,$i	; j=0 and "clear" XER[CA]
+	addi	$tp,$sp,`$FRAME+$TRANSFER+8`
+	addi	$t4,$sp,`$FRAME+$TRANSFER+16`
+	addi	$t5,$np,8
+	addi	$t6,$rp,8
+	mtctr	$j
+
+.align	4
+Lsub:	ldx	$t0,$tp,$i
+	ldx	$t1,$np,$i
+	ldx	$t2,$t4,$i
+	ldx	$t3,$t5,$i
+	subfe	$t0,$t1,$t0	; tp[j]-np[j]
+	subfe	$t2,$t3,$t2	; tp[j+1]-np[j+1]
+	stdx	$t0,$rp,$i
+	stdx	$t2,$t6,$i
+	addi	$i,$i,16
+	bdnz-	Lsub
+
+	li	$i,0
+	subfe	$ovf,$i,$ovf	; handle upmost overflow bit
+	and	$ap,$tp,$ovf
+	andc	$np,$rp,$ovf
+	or	$ap,$ap,$np	; ap=borrow?tp:rp
+	addi	$t7,$ap,8
+	mtctr	$j
+
+.align	4
+Lcopy:				; copy or in-place refresh
+	ldx	$t0,$ap,$i
+	ldx	$t1,$t7,$i
+	std	$i,8($nap_d)	; zap nap_d
+	std	$i,16($nap_d)
+	std	$i,24($nap_d)
+	std	$i,32($nap_d)
+	std	$i,40($nap_d)
+	std	$i,48($nap_d)
+	std	$i,56($nap_d)
+	stdu	$i,64($nap_d)
+	stdx	$t0,$rp,$i
+	stdx	$t1,$t6,$i
+	stdx	$i,$tp,$i	; zap tp at once
+	stdx	$i,$t4,$i
+	addi	$i,$i,16
+	bdnz-	Lcopy
+
+	$POP	r14,`2*$SIZE_T`($sp)
+	$POP	r15,`3*$SIZE_T`($sp)
+	$POP	r16,`4*$SIZE_T`($sp)
+	$POP	r17,`5*$SIZE_T`($sp)
+	$POP	r18,`6*$SIZE_T`($sp)
+	$POP	r19,`7*$SIZE_T`($sp)
+	$POP	r20,`8*$SIZE_T`($sp)
+	$POP	r21,`9*$SIZE_T`($sp)
+	$POP	r22,`10*$SIZE_T`($sp)
+	$POP	r23,`11*$SIZE_T`($sp)
+	lfd	f14,`12*$SIZE_T+0`($sp)
+	lfd	f15,`12*$SIZE_T+8`($sp)
+	lfd	f16,`12*$SIZE_T+16`($sp)
+	lfd	f17,`12*$SIZE_T+24`($sp)
+	lfd	f18,`12*$SIZE_T+32`($sp)
+	lfd	f19,`12*$SIZE_T+40`($sp)
+	lfd	f20,`12*$SIZE_T+48`($sp)
+	lfd	f21,`12*$SIZE_T+56`($sp)
+	lfd	f22,`12*$SIZE_T+64`($sp)
+	lfd	f23,`12*$SIZE_T+72`($sp)
+	lfd	f24,`12*$SIZE_T+80`($sp)
+	lfd	f25,`12*$SIZE_T+88`($sp)
+	$POP	$sp,0($sp)
+	li	r3,1	; signal "handled"
+	blr
+	.long	0
+.asciz  "Montgomery Multiplication for PPC64, CRYPTOGAMS by <appro\@fy.chalmers.se>"
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/bn/asm/s390x-mont.pl b/openssl/crypto/bn/asm/s390x-mont.pl
new file mode 100644
index 0000000..f61246f
--- /dev/null
+++ b/openssl/crypto/bn/asm/s390x-mont.pl
@@ -0,0 +1,225 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# April 2007.
+#
+# Performance improvement over vanilla C code varies from 85% to 45%
+# depending on key length and benchmark. Unfortunately in this context
+# these are not very impressive results [for code that utilizes "wide"
+# 64x64=128-bit multiplication, which is not commonly available to C
+# programmers], at least hand-coded bn_asm.c replacement is known to
+# provide 30-40% better results for longest keys. Well, on a second
+# thought it's not very surprising, because z-CPUs are single-issue
+# and _strictly_ in-order execution, while bn_mul_mont is more or less
+# dependent on CPU ability to pipe-line instructions and have several
+# of them "in-flight" at the same time. I mean while other methods,
+# for example Karatsuba, aim to minimize amount of multiplications at
+# the cost of other operations increase, bn_mul_mont aim to neatly
+# "overlap" multiplications and the other operations [and on most
+# platforms even minimize the amount of the other operations, in
+# particular references to memory]. But it's possible to improve this
+# module performance by implementing dedicated squaring code-path and
+# possibly by unrolling loops...
+
+# January 2009.
+#
+# Reschedule to minimize/avoid Address Generation Interlock hazard,
+# make inner loops counter-based.
+
+$mn0="%r0";
+$num="%r1";
+
+# int bn_mul_mont(
+$rp="%r2";		# BN_ULONG *rp,
+$ap="%r3";		# const BN_ULONG *ap,
+$bp="%r4";		# const BN_ULONG *bp,
+$np="%r5";		# const BN_ULONG *np,
+$n0="%r6";		# const BN_ULONG *n0,
+#$num="160(%r15)"	# int num);
+
+$bi="%r2";	# zaps rp
+$j="%r7";
+
+$ahi="%r8";
+$alo="%r9";
+$nhi="%r10";
+$nlo="%r11";
+$AHI="%r12";
+$NHI="%r13";
+$count="%r14";
+$sp="%r15";
+
+$code.=<<___;
+.text
+.globl	bn_mul_mont
+.type	bn_mul_mont,\@function
+bn_mul_mont:
+	lgf	$num,164($sp)	# pull $num
+	sla	$num,3		# $num to enumerate bytes
+	la	$bp,0($num,$bp)
+
+	stg	%r2,16($sp)
+
+	cghi	$num,16		#
+	lghi	%r2,0		#
+	blr	%r14		# if($num<16) return 0;
+	cghi	$num,96		#
+	bhr	%r14		# if($num>96) return 0;
+
+	stmg	%r3,%r15,24($sp)
+
+	lghi	$rp,-160-8	# leave room for carry bit
+	lcgr	$j,$num		# -$num
+	lgr	%r0,$sp
+	la	$rp,0($rp,$sp)
+	la	$sp,0($j,$rp)	# alloca
+	stg	%r0,0($sp)	# back chain
+
+	sra	$num,3		# restore $num
+	la	$bp,0($j,$bp)	# restore $bp
+	ahi	$num,-1		# adjust $num for inner loop
+	lg	$n0,0($n0)	# pull n0
+
+	lg	$bi,0($bp)
+	lg	$alo,0($ap)
+	mlgr	$ahi,$bi	# ap[0]*bp[0]
+	lgr	$AHI,$ahi
+
+	lgr	$mn0,$alo	# "tp[0]"*n0
+	msgr	$mn0,$n0
+
+	lg	$nlo,0($np)	#
+	mlgr	$nhi,$mn0	# np[0]*m1
+	algr	$nlo,$alo	# +="tp[0]"
+	lghi	$NHI,0
+	alcgr	$NHI,$nhi
+
+	la	$j,8(%r0)	# j=1
+	lr	$count,$num
+
+.align	16
+.L1st:
+	lg	$alo,0($j,$ap)
+	mlgr	$ahi,$bi	# ap[j]*bp[0]
+	algr	$alo,$AHI
+	lghi	$AHI,0
+	alcgr	$AHI,$ahi
+
+	lg	$nlo,0($j,$np)
+	mlgr	$nhi,$mn0	# np[j]*m1
+	algr	$nlo,$NHI
+	lghi	$NHI,0
+	alcgr	$nhi,$NHI	# +="tp[j]"
+	algr	$nlo,$alo
+	alcgr	$NHI,$nhi
+
+	stg	$nlo,160-8($j,$sp)	# tp[j-1]=
+	la	$j,8($j)	# j++
+	brct	$count,.L1st
+
+	algr	$NHI,$AHI
+	lghi	$AHI,0
+	alcgr	$AHI,$AHI	# upmost overflow bit
+	stg	$NHI,160-8($j,$sp)
+	stg	$AHI,160($j,$sp)
+	la	$bp,8($bp)	# bp++
+
+.Louter:
+	lg	$bi,0($bp)	# bp[i]
+	lg	$alo,0($ap)
+	mlgr	$ahi,$bi	# ap[0]*bp[i]
+	alg	$alo,160($sp)	# +=tp[0]
+	lghi	$AHI,0
+	alcgr	$AHI,$ahi
+
+	lgr	$mn0,$alo
+	msgr	$mn0,$n0	# tp[0]*n0
+
+	lg	$nlo,0($np)	# np[0]
+	mlgr	$nhi,$mn0	# np[0]*m1
+	algr	$nlo,$alo	# +="tp[0]"
+	lghi	$NHI,0
+	alcgr	$NHI,$nhi
+
+	la	$j,8(%r0)	# j=1
+	lr	$count,$num
+
+.align	16
+.Linner:
+	lg	$alo,0($j,$ap)
+	mlgr	$ahi,$bi	# ap[j]*bp[i]
+	algr	$alo,$AHI
+	lghi	$AHI,0
+	alcgr	$ahi,$AHI
+	alg	$alo,160($j,$sp)# +=tp[j]
+	alcgr	$AHI,$ahi
+
+	lg	$nlo,0($j,$np)
+	mlgr	$nhi,$mn0	# np[j]*m1
+	algr	$nlo,$NHI
+	lghi	$NHI,0
+	alcgr	$nhi,$NHI
+	algr	$nlo,$alo	# +="tp[j]"
+	alcgr	$NHI,$nhi
+
+	stg	$nlo,160-8($j,$sp)	# tp[j-1]=
+	la	$j,8($j)	# j++
+	brct	$count,.Linner
+
+	algr	$NHI,$AHI
+	lghi	$AHI,0
+	alcgr	$AHI,$AHI
+	alg	$NHI,160($j,$sp)# accumulate previous upmost overflow bit
+	lghi	$ahi,0
+	alcgr	$AHI,$ahi	# new upmost overflow bit
+	stg	$NHI,160-8($j,$sp)
+	stg	$AHI,160($j,$sp)
+
+	la	$bp,8($bp)	# bp++
+	clg	$bp,160+8+32($j,$sp)	# compare to &bp[num]
+	jne	.Louter
+
+	lg	$rp,160+8+16($j,$sp)	# reincarnate rp
+	la	$ap,160($sp)
+	ahi	$num,1		# restore $num, incidentally clears "borrow"
+
+	la	$j,0(%r0)
+	lr	$count,$num
+.Lsub:	lg	$alo,0($j,$ap)
+	slbg	$alo,0($j,$np)
+	stg	$alo,0($j,$rp)
+	la	$j,8($j)
+	brct	$count,.Lsub
+	lghi	$ahi,0
+	slbgr	$AHI,$ahi	# handle upmost carry
+
+	ngr	$ap,$AHI
+	lghi	$np,-1
+	xgr	$np,$AHI
+	ngr	$np,$rp
+	ogr	$ap,$np		# ap=borrow?tp:rp
+
+	la	$j,0(%r0)
+	lgr	$count,$num
+.Lcopy:	lg	$alo,0($j,$ap)	# copy or in-place refresh
+	stg	$j,160($j,$sp)	# zap tp
+	stg	$alo,0($j,$rp)
+	la	$j,8($j)
+	brct	$count,.Lcopy
+
+	la	%r1,160+8+48($j,$sp)
+	lmg	%r6,%r15,0(%r1)
+	lghi	%r2,1		# signal "processed"
+	br	%r14
+.size	bn_mul_mont,.-bn_mul_mont
+.string	"Montgomery Multiplication for s390x, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/bn/asm/s390x.S b/openssl/crypto/bn/asm/s390x.S
new file mode 100644
index 0000000..43fcb79
--- /dev/null
+++ b/openssl/crypto/bn/asm/s390x.S
@@ -0,0 +1,678 @@
+.ident "s390x.S, version 1.1"
+// ====================================================================
+// Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+// project.
+//
+// Rights for redistribution and usage in source and binary forms are
+// granted according to the OpenSSL license. Warranty of any kind is
+// disclaimed.
+// ====================================================================
+
+.text
+
+#define zero	%r0
+
+// BN_ULONG bn_mul_add_words(BN_ULONG *r2,BN_ULONG *r3,int r4,BN_ULONG r5);
+.globl	bn_mul_add_words
+.type	bn_mul_add_words,@function
+.align	4
+bn_mul_add_words:
+	lghi	zero,0		// zero = 0
+	la	%r1,0(%r2)	// put rp aside
+	lghi	%r2,0		// i=0;
+	ltgfr	%r4,%r4
+	bler	%r14		// if (len<=0) return 0;
+
+	stmg	%r6,%r10,48(%r15)
+	lghi	%r10,3
+	lghi	%r8,0		// carry = 0
+	nr	%r10,%r4	// len%4
+	sra	%r4,2		// cnt=len/4
+	jz	.Loop1_madd	// carry is incidentally cleared if branch taken
+	algr	zero,zero	// clear carry
+
+.Loop4_madd:
+	lg	%r7,0(%r2,%r3)	// ap[i]
+	mlgr	%r6,%r5		// *=w
+	alcgr	%r7,%r8		// +=carry
+	alcgr	%r6,zero
+	alg	%r7,0(%r2,%r1)	// +=rp[i]
+	stg	%r7,0(%r2,%r1)	// rp[i]=
+
+	lg	%r9,8(%r2,%r3)
+	mlgr	%r8,%r5
+	alcgr	%r9,%r6
+	alcgr	%r8,zero
+	alg	%r9,8(%r2,%r1)
+	stg	%r9,8(%r2,%r1)
+
+	lg	%r7,16(%r2,%r3)
+	mlgr	%r6,%r5
+	alcgr	%r7,%r8
+	alcgr	%r6,zero
+	alg	%r7,16(%r2,%r1)
+	stg	%r7,16(%r2,%r1)
+
+	lg	%r9,24(%r2,%r3)
+	mlgr	%r8,%r5
+	alcgr	%r9,%r6
+	alcgr	%r8,zero
+	alg	%r9,24(%r2,%r1)
+	stg	%r9,24(%r2,%r1)
+
+	la	%r2,32(%r2)	// i+=4
+	brct	%r4,.Loop4_madd
+
+	la	%r10,1(%r10)		// see if len%4 is zero ...
+	brct	%r10,.Loop1_madd	// without touching condition code:-)
+
+.Lend_madd:
+	alcgr	%r8,zero	// collect carry bit
+	lgr	%r2,%r8
+	lmg	%r6,%r10,48(%r15)
+	br	%r14
+
+.Loop1_madd:
+	lg	%r7,0(%r2,%r3)	// ap[i]
+	mlgr	%r6,%r5		// *=w
+	alcgr	%r7,%r8		// +=carry
+	alcgr	%r6,zero
+	alg	%r7,0(%r2,%r1)	// +=rp[i]
+	stg	%r7,0(%r2,%r1)	// rp[i]=
+
+	lgr	%r8,%r6
+	la	%r2,8(%r2)	// i++
+	brct	%r10,.Loop1_madd
+
+	j	.Lend_madd
+.size	bn_mul_add_words,.-bn_mul_add_words
+
+// BN_ULONG bn_mul_words(BN_ULONG *r2,BN_ULONG *r3,int r4,BN_ULONG r5);
+.globl	bn_mul_words
+.type	bn_mul_words,@function
+.align	4
+bn_mul_words:
+	lghi	zero,0		// zero = 0
+	la	%r1,0(%r2)	// put rp aside
+	lghi	%r2,0		// i=0;
+	ltgfr	%r4,%r4
+	bler	%r14		// if (len<=0) return 0;
+
+	stmg	%r6,%r10,48(%r15)
+	lghi	%r10,3
+	lghi	%r8,0		// carry = 0
+	nr	%r10,%r4	// len%4
+	sra	%r4,2		// cnt=len/4
+	jz	.Loop1_mul	// carry is incidentally cleared if branch taken
+	algr	zero,zero	// clear carry
+
+.Loop4_mul:
+	lg	%r7,0(%r2,%r3)	// ap[i]
+	mlgr	%r6,%r5		// *=w
+	alcgr	%r7,%r8		// +=carry
+	stg	%r7,0(%r2,%r1)	// rp[i]=
+
+	lg	%r9,8(%r2,%r3)
+	mlgr	%r8,%r5
+	alcgr	%r9,%r6
+	stg	%r9,8(%r2,%r1)
+
+	lg	%r7,16(%r2,%r3)
+	mlgr	%r6,%r5
+	alcgr	%r7,%r8
+	stg	%r7,16(%r2,%r1)
+
+	lg	%r9,24(%r2,%r3)
+	mlgr	%r8,%r5
+	alcgr	%r9,%r6
+	stg	%r9,24(%r2,%r1)
+
+	la	%r2,32(%r2)	// i+=4
+	brct	%r4,.Loop4_mul
+
+	la	%r10,1(%r10)		// see if len%4 is zero ...
+	brct	%r10,.Loop1_mul		// without touching condition code:-)
+
+.Lend_mul:
+	alcgr	%r8,zero	// collect carry bit
+	lgr	%r2,%r8
+	lmg	%r6,%r10,48(%r15)
+	br	%r14
+
+.Loop1_mul:
+	lg	%r7,0(%r2,%r3)	// ap[i]
+	mlgr	%r6,%r5		// *=w
+	alcgr	%r7,%r8		// +=carry
+	stg	%r7,0(%r2,%r1)	// rp[i]=
+
+	lgr	%r8,%r6
+	la	%r2,8(%r2)	// i++
+	brct	%r10,.Loop1_mul
+
+	j	.Lend_mul
+.size	bn_mul_words,.-bn_mul_words
+
+// void bn_sqr_words(BN_ULONG *r2,BN_ULONG *r2,int r4)
+.globl	bn_sqr_words
+.type	bn_sqr_words,@function
+.align	4
+bn_sqr_words:
+	ltgfr	%r4,%r4
+	bler	%r14
+
+	stmg	%r6,%r7,48(%r15)
+	srag	%r1,%r4,2	// cnt=len/4
+	jz	.Loop1_sqr
+
+.Loop4_sqr:
+	lg	%r7,0(%r3)
+	mlgr	%r6,%r7
+	stg	%r7,0(%r2)
+	stg	%r6,8(%r2)
+
+	lg	%r7,8(%r3)
+	mlgr	%r6,%r7
+	stg	%r7,16(%r2)
+	stg	%r6,24(%r2)
+
+	lg	%r7,16(%r3)
+	mlgr	%r6,%r7
+	stg	%r7,32(%r2)
+	stg	%r6,40(%r2)
+
+	lg	%r7,24(%r3)
+	mlgr	%r6,%r7
+	stg	%r7,48(%r2)
+	stg	%r6,56(%r2)
+
+	la	%r3,32(%r3)
+	la	%r2,64(%r2)
+	brct	%r1,.Loop4_sqr
+
+	lghi	%r1,3
+	nr	%r4,%r1		// cnt=len%4
+	jz	.Lend_sqr
+
+.Loop1_sqr:
+	lg	%r7,0(%r3)
+	mlgr	%r6,%r7
+	stg	%r7,0(%r2)
+	stg	%r6,8(%r2)
+
+	la	%r3,8(%r3)
+	la	%r2,16(%r2)
+	brct	%r4,.Loop1_sqr
+
+.Lend_sqr:
+	lmg	%r6,%r7,48(%r15)
+	br	%r14
+.size	bn_sqr_words,.-bn_sqr_words
+
+// BN_ULONG bn_div_words(BN_ULONG h,BN_ULONG l,BN_ULONG d);
+.globl	bn_div_words
+.type	bn_div_words,@function
+.align	4
+bn_div_words:
+	dlgr	%r2,%r4
+	lgr	%r2,%r3
+	br	%r14
+.size	bn_div_words,.-bn_div_words
+
+// BN_ULONG bn_add_words(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4,int r5);
+.globl	bn_add_words
+.type	bn_add_words,@function
+.align	4
+bn_add_words:
+	la	%r1,0(%r2)	// put rp aside
+	lghi	%r2,0		// i=0
+	ltgfr	%r5,%r5
+	bler	%r14		// if (len<=0) return 0;
+
+	stg	%r6,48(%r15)
+	lghi	%r6,3
+	nr	%r6,%r5		// len%4
+	sra	%r5,2		// len/4, use sra because it sets condition code
+	jz	.Loop1_add	// carry is incidentally cleared if branch taken
+	algr	%r2,%r2		// clear carry
+
+.Loop4_add:
+	lg	%r0,0(%r2,%r3)
+	alcg	%r0,0(%r2,%r4)
+	stg	%r0,0(%r2,%r1)
+	lg	%r0,8(%r2,%r3)
+	alcg	%r0,8(%r2,%r4)
+	stg	%r0,8(%r2,%r1)
+	lg	%r0,16(%r2,%r3)
+	alcg	%r0,16(%r2,%r4)
+	stg	%r0,16(%r2,%r1)
+	lg	%r0,24(%r2,%r3)
+	alcg	%r0,24(%r2,%r4)
+	stg	%r0,24(%r2,%r1)
+
+	la	%r2,32(%r2)	// i+=4
+	brct	%r5,.Loop4_add
+
+	la	%r6,1(%r6)	// see if len%4 is zero ...
+	brct	%r6,.Loop1_add	// without touching condition code:-)
+
+.Lexit_add:
+	lghi	%r2,0
+	alcgr	%r2,%r2
+	lg	%r6,48(%r15)
+	br	%r14
+
+.Loop1_add:
+	lg	%r0,0(%r2,%r3)
+	alcg	%r0,0(%r2,%r4)
+	stg	%r0,0(%r2,%r1)
+
+	la	%r2,8(%r2)	// i++
+	brct	%r6,.Loop1_add
+
+	j	.Lexit_add
+.size	bn_add_words,.-bn_add_words
+
+// BN_ULONG bn_sub_words(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4,int r5);
+.globl	bn_sub_words
+.type	bn_sub_words,@function
+.align	4
+bn_sub_words:
+	la	%r1,0(%r2)	// put rp aside
+	lghi	%r2,0		// i=0
+	ltgfr	%r5,%r5
+	bler	%r14		// if (len<=0) return 0;
+
+	stg	%r6,48(%r15)
+	lghi	%r6,3
+	nr	%r6,%r5		// len%4
+	sra	%r5,2		// len/4, use sra because it sets condition code
+	jnz	.Loop4_sub	// borrow is incidentally cleared if branch taken
+	slgr	%r2,%r2		// clear borrow
+
+.Loop1_sub:
+	lg	%r0,0(%r2,%r3)
+	slbg	%r0,0(%r2,%r4)
+	stg	%r0,0(%r2,%r1)
+
+	la	%r2,8(%r2)	// i++
+	brct	%r6,.Loop1_sub
+	j	.Lexit_sub
+
+.Loop4_sub:
+	lg	%r0,0(%r2,%r3)
+	slbg	%r0,0(%r2,%r4)
+	stg	%r0,0(%r2,%r1)
+	lg	%r0,8(%r2,%r3)
+	slbg	%r0,8(%r2,%r4)
+	stg	%r0,8(%r2,%r1)
+	lg	%r0,16(%r2,%r3)
+	slbg	%r0,16(%r2,%r4)
+	stg	%r0,16(%r2,%r1)
+	lg	%r0,24(%r2,%r3)
+	slbg	%r0,24(%r2,%r4)
+	stg	%r0,24(%r2,%r1)
+
+	la	%r2,32(%r2)	// i+=4
+	brct	%r5,.Loop4_sub
+
+	la	%r6,1(%r6)	// see if len%4 is zero ...
+	brct	%r6,.Loop1_sub	// without touching condition code:-)
+
+.Lexit_sub:
+	lghi	%r2,0
+	slbgr	%r2,%r2
+	lcgr	%r2,%r2
+	lg	%r6,48(%r15)
+	br	%r14
+.size	bn_sub_words,.-bn_sub_words
+
+#define c1	%r1
+#define c2	%r5
+#define c3	%r8
+
+#define mul_add_c(ai,bi,c1,c2,c3)	\
+	lg	%r7,ai*8(%r3);		\
+	mlg	%r6,bi*8(%r4);		\
+	algr	c1,%r7;			\
+	alcgr	c2,%r6;			\
+	alcgr	c3,zero
+
+// void bn_mul_comba8(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4);
+.globl	bn_mul_comba8
+.type	bn_mul_comba8,@function
+.align	4
+bn_mul_comba8:
+	stmg	%r6,%r8,48(%r15)
+
+	lghi	c1,0
+	lghi	c2,0
+	lghi	c3,0
+	lghi	zero,0
+
+	mul_add_c(0,0,c1,c2,c3);
+	stg	c1,0*8(%r2)
+	lghi	c1,0
+
+	mul_add_c(0,1,c2,c3,c1);
+	mul_add_c(1,0,c2,c3,c1);
+	stg	c2,1*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(2,0,c3,c1,c2);
+	mul_add_c(1,1,c3,c1,c2);
+	mul_add_c(0,2,c3,c1,c2);
+	stg	c3,2*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(0,3,c1,c2,c3);
+	mul_add_c(1,2,c1,c2,c3);
+	mul_add_c(2,1,c1,c2,c3);
+	mul_add_c(3,0,c1,c2,c3);
+	stg	c1,3*8(%r2)
+	lghi	c1,0
+
+	mul_add_c(4,0,c2,c3,c1);
+	mul_add_c(3,1,c2,c3,c1);
+	mul_add_c(2,2,c2,c3,c1);
+	mul_add_c(1,3,c2,c3,c1);
+	mul_add_c(0,4,c2,c3,c1);
+	stg	c2,4*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(0,5,c3,c1,c2);
+	mul_add_c(1,4,c3,c1,c2);
+	mul_add_c(2,3,c3,c1,c2);
+	mul_add_c(3,2,c3,c1,c2);
+	mul_add_c(4,1,c3,c1,c2);
+	mul_add_c(5,0,c3,c1,c2);
+	stg	c3,5*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(6,0,c1,c2,c3);
+	mul_add_c(5,1,c1,c2,c3);
+	mul_add_c(4,2,c1,c2,c3);
+	mul_add_c(3,3,c1,c2,c3);
+	mul_add_c(2,4,c1,c2,c3);
+	mul_add_c(1,5,c1,c2,c3);
+	mul_add_c(0,6,c1,c2,c3);
+	stg	c1,6*8(%r2)
+	lghi	c1,0
+
+	mul_add_c(0,7,c2,c3,c1);
+	mul_add_c(1,6,c2,c3,c1);
+	mul_add_c(2,5,c2,c3,c1);
+	mul_add_c(3,4,c2,c3,c1);
+	mul_add_c(4,3,c2,c3,c1);
+	mul_add_c(5,2,c2,c3,c1);
+	mul_add_c(6,1,c2,c3,c1);
+	mul_add_c(7,0,c2,c3,c1);
+	stg	c2,7*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(7,1,c3,c1,c2);
+	mul_add_c(6,2,c3,c1,c2);
+	mul_add_c(5,3,c3,c1,c2);
+	mul_add_c(4,4,c3,c1,c2);
+	mul_add_c(3,5,c3,c1,c2);
+	mul_add_c(2,6,c3,c1,c2);
+	mul_add_c(1,7,c3,c1,c2);
+	stg	c3,8*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(2,7,c1,c2,c3);
+	mul_add_c(3,6,c1,c2,c3);
+	mul_add_c(4,5,c1,c2,c3);
+	mul_add_c(5,4,c1,c2,c3);
+	mul_add_c(6,3,c1,c2,c3);
+	mul_add_c(7,2,c1,c2,c3);
+	stg	c1,9*8(%r2)
+	lghi	c1,0
+
+	mul_add_c(7,3,c2,c3,c1);
+	mul_add_c(6,4,c2,c3,c1);
+	mul_add_c(5,5,c2,c3,c1);
+	mul_add_c(4,6,c2,c3,c1);
+	mul_add_c(3,7,c2,c3,c1);
+	stg	c2,10*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(4,7,c3,c1,c2);
+	mul_add_c(5,6,c3,c1,c2);
+	mul_add_c(6,5,c3,c1,c2);
+	mul_add_c(7,4,c3,c1,c2);
+	stg	c3,11*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(7,5,c1,c2,c3);
+	mul_add_c(6,6,c1,c2,c3);
+	mul_add_c(5,7,c1,c2,c3);
+	stg	c1,12*8(%r2)
+	lghi	c1,0
+
+
+	mul_add_c(6,7,c2,c3,c1);
+	mul_add_c(7,6,c2,c3,c1);
+	stg	c2,13*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(7,7,c3,c1,c2);
+	stg	c3,14*8(%r2)
+	stg	c1,15*8(%r2)
+
+	lmg	%r6,%r8,48(%r15)
+	br	%r14
+.size	bn_mul_comba8,.-bn_mul_comba8
+
+// void bn_mul_comba4(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4);
+.globl	bn_mul_comba4
+.type	bn_mul_comba4,@function
+.align	4
+bn_mul_comba4:
+	stmg	%r6,%r8,48(%r15)
+
+	lghi	c1,0
+	lghi	c2,0
+	lghi	c3,0
+	lghi	zero,0
+
+	mul_add_c(0,0,c1,c2,c3);
+	stg	c1,0*8(%r3)
+	lghi	c1,0
+
+	mul_add_c(0,1,c2,c3,c1);
+	mul_add_c(1,0,c2,c3,c1);
+	stg	c2,1*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(2,0,c3,c1,c2);
+	mul_add_c(1,1,c3,c1,c2);
+	mul_add_c(0,2,c3,c1,c2);
+	stg	c3,2*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(0,3,c1,c2,c3);
+	mul_add_c(1,2,c1,c2,c3);
+	mul_add_c(2,1,c1,c2,c3);
+	mul_add_c(3,0,c1,c2,c3);
+	stg	c1,3*8(%r2)
+	lghi	c1,0
+
+	mul_add_c(3,1,c2,c3,c1);
+	mul_add_c(2,2,c2,c3,c1);
+	mul_add_c(1,3,c2,c3,c1);
+	stg	c2,4*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(2,3,c3,c1,c2);
+	mul_add_c(3,2,c3,c1,c2);
+	stg	c3,5*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(3,3,c1,c2,c3);
+	stg	c1,6*8(%r2)
+	stg	c2,7*8(%r2)
+
+	stmg	%r6,%r8,48(%r15)
+	br	%r14
+.size	bn_mul_comba4,.-bn_mul_comba4
+
+#define sqr_add_c(ai,c1,c2,c3)		\
+	lg	%r7,ai*8(%r3);		\
+	mlgr	%r6,%r7;		\
+	algr	c1,%r7;			\
+	alcgr	c2,%r6;			\
+	alcgr	c3,zero
+
+#define sqr_add_c2(ai,aj,c1,c2,c3)	\
+	lg	%r7,ai*8(%r3);		\
+	mlg	%r6,aj*8(%r3);		\
+	algr	c1,%r7;			\
+	alcgr	c2,%r6;			\
+	alcgr	c3,zero;		\
+	algr	c1,%r7;			\
+	alcgr	c2,%r6;			\
+	alcgr	c3,zero
+
+// void bn_sqr_comba8(BN_ULONG *r2,BN_ULONG *r3);
+.globl	bn_sqr_comba8
+.type	bn_sqr_comba8,@function
+.align	4
+bn_sqr_comba8:
+	stmg	%r6,%r8,48(%r15)
+
+	lghi	c1,0
+	lghi	c2,0
+	lghi	c3,0
+	lghi	zero,0
+
+	sqr_add_c(0,c1,c2,c3);
+	stg	c1,0*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c2(1,0,c2,c3,c1);
+	stg	c2,1*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c(1,c3,c1,c2);
+	sqr_add_c2(2,0,c3,c1,c2);
+	stg	c3,2*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c2(3,0,c1,c2,c3);
+	sqr_add_c2(2,1,c1,c2,c3);
+	stg	c1,3*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c(2,c2,c3,c1);
+	sqr_add_c2(3,1,c2,c3,c1);
+	sqr_add_c2(4,0,c2,c3,c1);
+	stg	c2,4*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c2(5,0,c3,c1,c2);
+	sqr_add_c2(4,1,c3,c1,c2);
+	sqr_add_c2(3,2,c3,c1,c2);
+	stg	c3,5*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c(3,c1,c2,c3);
+	sqr_add_c2(4,2,c1,c2,c3);
+	sqr_add_c2(5,1,c1,c2,c3);
+	sqr_add_c2(6,0,c1,c2,c3);
+	stg	c1,6*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c2(7,0,c2,c3,c1);
+	sqr_add_c2(6,1,c2,c3,c1);
+	sqr_add_c2(5,2,c2,c3,c1);
+	sqr_add_c2(4,3,c2,c3,c1);
+	stg	c2,7*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c(4,c3,c1,c2);
+	sqr_add_c2(5,3,c3,c1,c2);
+	sqr_add_c2(6,2,c3,c1,c2);
+	sqr_add_c2(7,1,c3,c1,c2);
+	stg	c3,8*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c2(7,2,c1,c2,c3);
+	sqr_add_c2(6,3,c1,c2,c3);
+	sqr_add_c2(5,4,c1,c2,c3);
+	stg	c1,9*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c(5,c2,c3,c1);
+	sqr_add_c2(6,4,c2,c3,c1);
+	sqr_add_c2(7,3,c2,c3,c1);
+	stg	c2,10*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c2(7,4,c3,c1,c2);
+	sqr_add_c2(6,5,c3,c1,c2);
+	stg	c3,11*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c(6,c1,c2,c3);
+	sqr_add_c2(7,5,c1,c2,c3);
+	stg	c1,12*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c2(7,6,c2,c3,c1);
+	stg	c2,13*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c(7,c3,c1,c2);
+	stg	c3,14*8(%r2)
+	stg	c1,15*8(%r2)
+
+	lmg	%r6,%r8,48(%r15)
+	br	%r14
+.size	bn_sqr_comba8,.-bn_sqr_comba8
+
+// void bn_sqr_comba4(BN_ULONG *r2,BN_ULONG *r3);
+.globl bn_sqr_comba4
+.type	bn_sqr_comba4,@function
+.align	4
+bn_sqr_comba4:
+	stmg	%r6,%r8,48(%r15)
+
+	lghi	c1,0
+	lghi	c2,0
+	lghi	c3,0
+	lghi	zero,0
+
+	sqr_add_c(0,c1,c2,c3);
+	stg	c1,0*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c2(1,0,c2,c3,c1);
+	stg	c2,1*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c(1,c3,c1,c2);
+	sqr_add_c2(2,0,c3,c1,c2);
+	stg	c3,2*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c2(3,0,c1,c2,c3);
+	sqr_add_c2(2,1,c1,c2,c3);
+	stg	c1,3*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c(2,c2,c3,c1);
+	sqr_add_c2(3,1,c2,c3,c1);
+	stg	c2,4*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c2(3,2,c3,c1,c2);
+	stg	c3,5*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c(3,c1,c2,c3);
+	stg	c1,6*8(%r2)
+	stg	c2,7*8(%r2)
+
+	lmg	%r6,%r8,48(%r15)
+	br	%r14
+.size	bn_sqr_comba4,.-bn_sqr_comba4
diff --git a/openssl/crypto/bn/asm/sparcv8.S b/openssl/crypto/bn/asm/sparcv8.S
new file mode 100644
index 0000000..88c5dc4
--- /dev/null
+++ b/openssl/crypto/bn/asm/sparcv8.S
@@ -0,0 +1,1458 @@
+.ident	"sparcv8.s, Version 1.4"
+.ident	"SPARC v8 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
+
+/*
+ * ====================================================================
+ * Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+ * project.
+ *
+ * Rights for redistribution and usage in source and binary forms are
+ * granted according to the OpenSSL license. Warranty of any kind is
+ * disclaimed.
+ * ====================================================================
+ */
+
+/*
+ * This is my modest contributon to OpenSSL project (see
+ * http://www.openssl.org/ for more information about it) and is
+ * a drop-in SuperSPARC ISA replacement for crypto/bn/bn_asm.c
+ * module. For updates see http://fy.chalmers.se/~appro/hpe/.
+ *
+ * See bn_asm.sparc.v8plus.S for more details.
+ */
+
+/*
+ * Revision history.
+ *
+ * 1.1	- new loop unrolling model(*);
+ * 1.2	- made gas friendly;
+ * 1.3	- fixed problem with /usr/ccs/lib/cpp;
+ * 1.4	- some retunes;
+ *
+ * (*)	see bn_asm.sparc.v8plus.S for details
+ */
+
+.section	".text",#alloc,#execinstr
+.file		"bn_asm.sparc.v8.S"
+
+.align	32
+
+.global bn_mul_add_words
+/*
+ * BN_ULONG bn_mul_add_words(rp,ap,num,w)
+ * BN_ULONG *rp,*ap;
+ * int num;
+ * BN_ULONG w;
+ */
+bn_mul_add_words:
+	cmp	%o2,0
+	bg,a	.L_bn_mul_add_words_proceed
+	ld	[%o1],%g2
+	retl
+	clr	%o0
+
+.L_bn_mul_add_words_proceed:
+	andcc	%o2,-4,%g0
+	bz	.L_bn_mul_add_words_tail
+	clr	%o5
+
+.L_bn_mul_add_words_loop:
+	ld	[%o0],%o4
+	ld	[%o1+4],%g3
+	umul	%o3,%g2,%g2
+	rd	%y,%g1
+	addcc	%o4,%o5,%o4
+	addx	%g1,0,%g1
+	addcc	%o4,%g2,%o4
+	st	%o4,[%o0]
+	addx	%g1,0,%o5
+
+	ld	[%o0+4],%o4
+	ld	[%o1+8],%g2
+	umul	%o3,%g3,%g3
+	dec	4,%o2
+	rd	%y,%g1
+	addcc	%o4,%o5,%o4
+	addx	%g1,0,%g1
+	addcc	%o4,%g3,%o4
+	st	%o4,[%o0+4]
+	addx	%g1,0,%o5
+
+	ld	[%o0+8],%o4
+	ld	[%o1+12],%g3
+	umul	%o3,%g2,%g2
+	inc	16,%o1
+	rd	%y,%g1
+	addcc	%o4,%o5,%o4
+	addx	%g1,0,%g1
+	addcc	%o4,%g2,%o4
+	st	%o4,[%o0+8]
+	addx	%g1,0,%o5
+
+	ld	[%o0+12],%o4
+	umul	%o3,%g3,%g3
+	inc	16,%o0
+	rd	%y,%g1
+	addcc	%o4,%o5,%o4
+	addx	%g1,0,%g1
+	addcc	%o4,%g3,%o4
+	st	%o4,[%o0-4]
+	addx	%g1,0,%o5
+	andcc	%o2,-4,%g0
+	bnz,a	.L_bn_mul_add_words_loop
+	ld	[%o1],%g2
+
+	tst	%o2
+	bnz,a	.L_bn_mul_add_words_tail
+	ld	[%o1],%g2
+.L_bn_mul_add_words_return:
+	retl
+	mov	%o5,%o0
+	nop
+
+.L_bn_mul_add_words_tail:
+	ld	[%o0],%o4
+	umul	%o3,%g2,%g2
+	addcc	%o4,%o5,%o4
+	rd	%y,%g1
+	addx	%g1,0,%g1
+	addcc	%o4,%g2,%o4
+	addx	%g1,0,%o5
+	deccc	%o2
+	bz	.L_bn_mul_add_words_return
+	st	%o4,[%o0]
+
+	ld	[%o1+4],%g2
+	ld	[%o0+4],%o4
+	umul	%o3,%g2,%g2
+	rd	%y,%g1
+	addcc	%o4,%o5,%o4
+	addx	%g1,0,%g1
+	addcc	%o4,%g2,%o4
+	addx	%g1,0,%o5
+	deccc	%o2
+	bz	.L_bn_mul_add_words_return
+	st	%o4,[%o0+4]
+
+	ld	[%o1+8],%g2
+	ld	[%o0+8],%o4
+	umul	%o3,%g2,%g2
+	rd	%y,%g1
+	addcc	%o4,%o5,%o4
+	addx	%g1,0,%g1
+	addcc	%o4,%g2,%o4
+	st	%o4,[%o0+8]
+	retl
+	addx	%g1,0,%o0
+
+.type	bn_mul_add_words,#function
+.size	bn_mul_add_words,(.-bn_mul_add_words)
+
+.align	32
+
+.global bn_mul_words
+/*
+ * BN_ULONG bn_mul_words(rp,ap,num,w)
+ * BN_ULONG *rp,*ap;
+ * int num;
+ * BN_ULONG w;
+ */
+bn_mul_words:
+	cmp	%o2,0
+	bg,a	.L_bn_mul_words_proceeed
+	ld	[%o1],%g2
+	retl
+	clr	%o0
+
+.L_bn_mul_words_proceeed:
+	andcc	%o2,-4,%g0
+	bz	.L_bn_mul_words_tail
+	clr	%o5
+
+.L_bn_mul_words_loop:
+	ld	[%o1+4],%g3
+	umul	%o3,%g2,%g2
+	addcc	%g2,%o5,%g2
+	rd	%y,%g1
+	addx	%g1,0,%o5
+	st	%g2,[%o0]
+
+	ld	[%o1+8],%g2
+	umul	%o3,%g3,%g3
+	addcc	%g3,%o5,%g3
+	rd	%y,%g1
+	dec	4,%o2
+	addx	%g1,0,%o5
+	st	%g3,[%o0+4]
+
+	ld	[%o1+12],%g3
+	umul	%o3,%g2,%g2
+	addcc	%g2,%o5,%g2
+	rd	%y,%g1
+	inc	16,%o1
+	st	%g2,[%o0+8]
+	addx	%g1,0,%o5
+
+	umul	%o3,%g3,%g3
+	addcc	%g3,%o5,%g3
+	rd	%y,%g1
+	inc	16,%o0
+	addx	%g1,0,%o5
+	st	%g3,[%o0-4]
+	andcc	%o2,-4,%g0
+	nop
+	bnz,a	.L_bn_mul_words_loop
+	ld	[%o1],%g2
+
+	tst	%o2
+	bnz,a	.L_bn_mul_words_tail
+	ld	[%o1],%g2
+.L_bn_mul_words_return:
+	retl
+	mov	%o5,%o0
+	nop
+
+.L_bn_mul_words_tail:
+	umul	%o3,%g2,%g2
+	addcc	%g2,%o5,%g2
+	rd	%y,%g1
+	addx	%g1,0,%o5
+	deccc	%o2
+	bz	.L_bn_mul_words_return
+	st	%g2,[%o0]
+	nop
+
+	ld	[%o1+4],%g2
+	umul	%o3,%g2,%g2
+	addcc	%g2,%o5,%g2
+	rd	%y,%g1
+	addx	%g1,0,%o5
+	deccc	%o2
+	bz	.L_bn_mul_words_return
+	st	%g2,[%o0+4]
+
+	ld	[%o1+8],%g2
+	umul	%o3,%g2,%g2
+	addcc	%g2,%o5,%g2
+	rd	%y,%g1
+	st	%g2,[%o0+8]
+	retl
+	addx	%g1,0,%o0
+
+.type	bn_mul_words,#function
+.size	bn_mul_words,(.-bn_mul_words)
+
+.align  32
+.global	bn_sqr_words
+/*
+ * void bn_sqr_words(r,a,n)
+ * BN_ULONG *r,*a;
+ * int n;
+ */
+bn_sqr_words:
+	cmp	%o2,0
+	bg,a	.L_bn_sqr_words_proceeed
+	ld	[%o1],%g2
+	retl
+	clr	%o0
+
+.L_bn_sqr_words_proceeed:
+	andcc	%o2,-4,%g0
+	bz	.L_bn_sqr_words_tail
+	clr	%o5
+
+.L_bn_sqr_words_loop:
+	ld	[%o1+4],%g3
+	umul	%g2,%g2,%o4
+	st	%o4,[%o0]
+	rd	%y,%o5
+	st	%o5,[%o0+4]
+
+	ld	[%o1+8],%g2
+	umul	%g3,%g3,%o4
+	dec	4,%o2
+	st	%o4,[%o0+8]
+	rd	%y,%o5
+	st	%o5,[%o0+12]
+	nop
+
+	ld	[%o1+12],%g3
+	umul	%g2,%g2,%o4
+	st	%o4,[%o0+16]
+	rd	%y,%o5
+	inc	16,%o1
+	st	%o5,[%o0+20]
+
+	umul	%g3,%g3,%o4
+	inc	32,%o0
+	st	%o4,[%o0-8]
+	rd	%y,%o5
+	st	%o5,[%o0-4]
+	andcc	%o2,-4,%g2
+	bnz,a	.L_bn_sqr_words_loop
+	ld	[%o1],%g2
+
+	tst	%o2
+	nop
+	bnz,a	.L_bn_sqr_words_tail
+	ld	[%o1],%g2
+.L_bn_sqr_words_return:
+	retl
+	clr	%o0
+
+.L_bn_sqr_words_tail:
+	umul	%g2,%g2,%o4
+	st	%o4,[%o0]
+	deccc	%o2
+	rd	%y,%o5
+	bz	.L_bn_sqr_words_return
+	st	%o5,[%o0+4]
+
+	ld	[%o1+4],%g2
+	umul	%g2,%g2,%o4
+	st	%o4,[%o0+8]
+	deccc	%o2
+	rd	%y,%o5
+	nop
+	bz	.L_bn_sqr_words_return
+	st	%o5,[%o0+12]
+
+	ld	[%o1+8],%g2
+	umul	%g2,%g2,%o4
+	st	%o4,[%o0+16]
+	rd	%y,%o5
+	st	%o5,[%o0+20]
+	retl
+	clr	%o0
+
+.type	bn_sqr_words,#function
+.size	bn_sqr_words,(.-bn_sqr_words)
+
+.align	32
+
+.global bn_div_words
+/*
+ * BN_ULONG bn_div_words(h,l,d)
+ * BN_ULONG h,l,d;
+ */
+bn_div_words:
+	wr	%o0,%y
+	udiv	%o1,%o2,%o0
+	retl
+	nop
+
+.type	bn_div_words,#function
+.size	bn_div_words,(.-bn_div_words)
+
+.align	32
+
+.global bn_add_words
+/*
+ * BN_ULONG bn_add_words(rp,ap,bp,n)
+ * BN_ULONG *rp,*ap,*bp;
+ * int n;
+ */
+bn_add_words:
+	cmp	%o3,0
+	bg,a	.L_bn_add_words_proceed
+	ld	[%o1],%o4
+	retl
+	clr	%o0
+
+.L_bn_add_words_proceed:
+	andcc	%o3,-4,%g0
+	bz	.L_bn_add_words_tail
+	clr	%g1
+	ba	.L_bn_add_words_warn_loop
+	addcc	%g0,0,%g0	! clear carry flag
+
+.L_bn_add_words_loop:
+	ld	[%o1],%o4
+.L_bn_add_words_warn_loop:
+	ld	[%o2],%o5
+	ld	[%o1+4],%g3
+	ld	[%o2+4],%g4
+	dec	4,%o3
+	addxcc	%o5,%o4,%o5
+	st	%o5,[%o0]
+
+	ld	[%o1+8],%o4
+	ld	[%o2+8],%o5
+	inc	16,%o1
+	addxcc	%g3,%g4,%g3
+	st	%g3,[%o0+4]
+	
+	ld	[%o1-4],%g3
+	ld	[%o2+12],%g4
+	inc	16,%o2
+	addxcc	%o5,%o4,%o5
+	st	%o5,[%o0+8]
+
+	inc	16,%o0
+	addxcc	%g3,%g4,%g3
+	st	%g3,[%o0-4]
+	addx	%g0,0,%g1
+	andcc	%o3,-4,%g0
+	bnz,a	.L_bn_add_words_loop
+	addcc	%g1,-1,%g0
+
+	tst	%o3
+	bnz,a	.L_bn_add_words_tail
+	ld	[%o1],%o4
+.L_bn_add_words_return:
+	retl
+	mov	%g1,%o0
+
+.L_bn_add_words_tail:
+	addcc	%g1,-1,%g0
+	ld	[%o2],%o5
+	addxcc	%o5,%o4,%o5
+	addx	%g0,0,%g1
+	deccc	%o3
+	bz	.L_bn_add_words_return
+	st	%o5,[%o0]
+
+	ld	[%o1+4],%o4
+	addcc	%g1,-1,%g0
+	ld	[%o2+4],%o5
+	addxcc	%o5,%o4,%o5
+	addx	%g0,0,%g1
+	deccc	%o3
+	bz	.L_bn_add_words_return
+	st	%o5,[%o0+4]
+
+	ld	[%o1+8],%o4
+	addcc	%g1,-1,%g0
+	ld	[%o2+8],%o5
+	addxcc	%o5,%o4,%o5
+	st	%o5,[%o0+8]
+	retl
+	addx	%g0,0,%o0
+
+.type	bn_add_words,#function
+.size	bn_add_words,(.-bn_add_words)
+
+.align	32
+
+.global bn_sub_words
+/*
+ * BN_ULONG bn_sub_words(rp,ap,bp,n)
+ * BN_ULONG *rp,*ap,*bp;
+ * int n;
+ */
+bn_sub_words:
+	cmp	%o3,0
+	bg,a	.L_bn_sub_words_proceed
+	ld	[%o1],%o4
+	retl
+	clr	%o0
+
+.L_bn_sub_words_proceed:
+	andcc	%o3,-4,%g0
+	bz	.L_bn_sub_words_tail
+	clr	%g1
+	ba	.L_bn_sub_words_warm_loop
+	addcc	%g0,0,%g0	! clear carry flag
+
+.L_bn_sub_words_loop:
+	ld	[%o1],%o4
+.L_bn_sub_words_warm_loop:
+	ld	[%o2],%o5
+	ld	[%o1+4],%g3
+	ld	[%o2+4],%g4
+	dec	4,%o3
+	subxcc	%o4,%o5,%o5
+	st	%o5,[%o0]
+
+	ld	[%o1+8],%o4
+	ld	[%o2+8],%o5
+	inc	16,%o1
+	subxcc	%g3,%g4,%g4
+	st	%g4,[%o0+4]
+	
+	ld	[%o1-4],%g3
+	ld	[%o2+12],%g4
+	inc	16,%o2
+	subxcc	%o4,%o5,%o5
+	st	%o5,[%o0+8]
+
+	inc	16,%o0
+	subxcc	%g3,%g4,%g4
+	st	%g4,[%o0-4]
+	addx	%g0,0,%g1
+	andcc	%o3,-4,%g0
+	bnz,a	.L_bn_sub_words_loop
+	addcc	%g1,-1,%g0
+
+	tst	%o3
+	nop
+	bnz,a	.L_bn_sub_words_tail
+	ld	[%o1],%o4
+.L_bn_sub_words_return:
+	retl
+	mov	%g1,%o0
+
+.L_bn_sub_words_tail:
+	addcc	%g1,-1,%g0
+	ld	[%o2],%o5
+	subxcc	%o4,%o5,%o5
+	addx	%g0,0,%g1
+	deccc	%o3
+	bz	.L_bn_sub_words_return
+	st	%o5,[%o0]
+	nop
+
+	ld	[%o1+4],%o4
+	addcc	%g1,-1,%g0
+	ld	[%o2+4],%o5
+	subxcc	%o4,%o5,%o5
+	addx	%g0,0,%g1
+	deccc	%o3
+	bz	.L_bn_sub_words_return
+	st	%o5,[%o0+4]
+
+	ld	[%o1+8],%o4
+	addcc	%g1,-1,%g0
+	ld	[%o2+8],%o5
+	subxcc	%o4,%o5,%o5
+	st	%o5,[%o0+8]
+	retl
+	addx	%g0,0,%o0
+
+.type	bn_sub_words,#function
+.size	bn_sub_words,(.-bn_sub_words)
+
+#define FRAME_SIZE	-96
+
+/*
+ * Here is register usage map for *all* routines below.
+ */
+#define t_1	%o0
+#define	t_2	%o1
+#define c_1	%o2
+#define c_2	%o3
+#define c_3	%o4
+
+#define ap(I)	[%i1+4*I]
+#define bp(I)	[%i2+4*I]
+#define rp(I)	[%i0+4*I]
+
+#define	a_0	%l0
+#define	a_1	%l1
+#define	a_2	%l2
+#define	a_3	%l3
+#define	a_4	%l4
+#define	a_5	%l5
+#define	a_6	%l6
+#define	a_7	%l7
+
+#define	b_0	%i3
+#define	b_1	%i4
+#define	b_2	%i5
+#define	b_3	%o5
+#define	b_4	%g1
+#define	b_5	%g2
+#define	b_6	%g3
+#define	b_7	%g4
+
+.align	32
+.global bn_mul_comba8
+/*
+ * void bn_mul_comba8(r,a,b)
+ * BN_ULONG *r,*a,*b;
+ */
+bn_mul_comba8:
+	save	%sp,FRAME_SIZE,%sp
+	ld	ap(0),a_0
+	ld	bp(0),b_0
+	umul	a_0,b_0,c_1	!=!mul_add_c(a[0],b[0],c1,c2,c3);
+	ld	bp(1),b_1
+	rd	%y,c_2
+	st	c_1,rp(0)	!r[0]=c1;
+
+	umul	a_0,b_1,t_1	!=!mul_add_c(a[0],b[1],c2,c3,c1);
+	ld	ap(1),a_1
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2
+	addxcc	%g0,t_2,c_3	!=
+	addx	%g0,%g0,c_1
+	ld	ap(2),a_2
+	umul	a_1,b_0,t_1	!mul_add_c(a[1],b[0],c2,c3,c1);
+	addcc	c_2,t_1,c_2	!=
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3
+	st	c_2,rp(1)	!r[1]=c2;
+	addx	c_1,%g0,c_1	!=
+
+	umul	a_2,b_0,t_1	!mul_add_c(a[2],b[0],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1	!=
+	addx	%g0,%g0,c_2
+	ld	bp(2),b_2
+	umul	a_1,b_1,t_1	!mul_add_c(a[1],b[1],c3,c1,c2);
+	addcc	c_3,t_1,c_3	!=
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	ld	bp(3),b_3
+	addx	c_2,%g0,c_2	!=
+	umul	a_0,b_2,t_1	!mul_add_c(a[0],b[2],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1	!=
+	addx	c_2,%g0,c_2
+	st	c_3,rp(2)	!r[2]=c3;
+
+	umul	a_0,b_3,t_1	!mul_add_c(a[0],b[3],c1,c2,c3);
+	addcc	c_1,t_1,c_1	!=
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	addx	%g0,%g0,c_3
+	umul	a_1,b_2,t_1	!=!mul_add_c(a[1],b[2],c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3	!=
+	ld	ap(3),a_3
+	umul	a_2,b_1,t_1	!mul_add_c(a[2],b[1],c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2		!=
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3
+	ld	ap(4),a_4
+	umul	a_3,b_0,t_1	!mul_add_c(a[3],b[0],c1,c2,c3);!=
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3	!=
+	st	c_1,rp(3)	!r[3]=c1;
+
+	umul	a_4,b_0,t_1	!mul_add_c(a[4],b[0],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	%g0,%g0,c_1
+	umul	a_3,b_1,t_1	!mul_add_c(a[3],b[1],c2,c3,c1);
+	addcc	c_2,t_1,c_2	!=
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1
+	umul	a_2,b_2,t_1	!=!mul_add_c(a[2],b[2],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1	!=
+	ld	bp(4),b_4
+	umul	a_1,b_3,t_1	!mul_add_c(a[1],b[3],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1
+	ld	bp(5),b_5
+	umul	a_0,b_4,t_1	!=!mul_add_c(a[0],b[4],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1	!=
+	st	c_2,rp(4)	!r[4]=c2;
+
+	umul	a_0,b_5,t_1	!mul_add_c(a[0],b[5],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2		!=
+	addxcc	c_1,t_2,c_1
+	addx	%g0,%g0,c_2
+	umul	a_1,b_4,t_1	!mul_add_c(a[1],b[4],c3,c1,c2);
+	addcc	c_3,t_1,c_3	!=
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2
+	umul	a_2,b_3,t_1	!=!mul_add_c(a[2],b[3],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2	!=
+	umul	a_3,b_2,t_1	!mul_add_c(a[3],b[2],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1	!=
+	addx	c_2,%g0,c_2
+	ld	ap(5),a_5
+	umul	a_4,b_1,t_1	!mul_add_c(a[4],b[1],c3,c1,c2);
+	addcc	c_3,t_1,c_3	!=
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	ld	ap(6),a_6
+	addx	c_2,%g0,c_2	!=
+	umul	a_5,b_0,t_1	!mul_add_c(a[5],b[0],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1	!=
+	addx	c_2,%g0,c_2
+	st	c_3,rp(5)	!r[5]=c3;
+
+	umul	a_6,b_0,t_1	!mul_add_c(a[6],b[0],c1,c2,c3);
+	addcc	c_1,t_1,c_1	!=
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	addx	%g0,%g0,c_3
+	umul	a_5,b_1,t_1	!=!mul_add_c(a[5],b[1],c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3	!=
+	umul	a_4,b_2,t_1	!mul_add_c(a[4],b[2],c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2	!=
+	addx	c_3,%g0,c_3
+	umul	a_3,b_3,t_1	!mul_add_c(a[3],b[3],c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2		!=
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3
+	umul	a_2,b_4,t_1	!mul_add_c(a[2],b[4],c1,c2,c3);
+	addcc	c_1,t_1,c_1	!=
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	ld	bp(6),b_6
+	addx	c_3,%g0,c_3	!=
+	umul	a_1,b_5,t_1	!mul_add_c(a[1],b[5],c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2	!=
+	addx	c_3,%g0,c_3
+	ld	bp(7),b_7
+	umul	a_0,b_6,t_1	!mul_add_c(a[0],b[6],c1,c2,c3);
+	addcc	c_1,t_1,c_1	!=
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	st	c_1,rp(6)	!r[6]=c1;
+	addx	c_3,%g0,c_3	!=
+
+	umul	a_0,b_7,t_1	!mul_add_c(a[0],b[7],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3	!=
+	addx	%g0,%g0,c_1
+	umul	a_1,b_6,t_1	!mul_add_c(a[1],b[6],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1
+	umul	a_2,b_5,t_1	!mul_add_c(a[2],b[5],c2,c3,c1);
+	addcc	c_2,t_1,c_2	!=
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1
+	umul	a_3,b_4,t_1	!=!mul_add_c(a[3],b[4],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1	!=
+	umul	a_4,b_3,t_1	!mul_add_c(a[4],b[3],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3	!=
+	addx	c_1,%g0,c_1
+	umul	a_5,b_2,t_1	!mul_add_c(a[5],b[2],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1
+	ld	ap(7),a_7
+	umul	a_6,b_1,t_1	!=!mul_add_c(a[6],b[1],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1	!=
+	umul	a_7,b_0,t_1	!mul_add_c(a[7],b[0],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3	!=
+	addx	c_1,%g0,c_1
+	st	c_2,rp(7)	!r[7]=c2;
+
+	umul	a_7,b_1,t_1	!mul_add_c(a[7],b[1],c3,c1,c2);
+	addcc	c_3,t_1,c_3	!=
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	addx	%g0,%g0,c_2
+	umul	a_6,b_2,t_1	!=!mul_add_c(a[6],b[2],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2	!=
+	umul	a_5,b_3,t_1	!mul_add_c(a[5],b[3],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1	!=
+	addx	c_2,%g0,c_2
+	umul	a_4,b_4,t_1	!mul_add_c(a[4],b[4],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2		!=
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2
+	umul	a_3,b_5,t_1	!mul_add_c(a[3],b[5],c3,c1,c2);
+	addcc	c_3,t_1,c_3	!=
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2
+	umul	a_2,b_6,t_1	!=!mul_add_c(a[2],b[6],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2	!=
+	umul	a_1,b_7,t_1	!mul_add_c(a[1],b[7],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1	!
+	addx	c_2,%g0,c_2
+	st	c_3,rp(8)	!r[8]=c3;
+
+	umul	a_2,b_7,t_1	!mul_add_c(a[2],b[7],c1,c2,c3);
+	addcc	c_1,t_1,c_1	!=
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	addx	%g0,%g0,c_3
+	umul	a_3,b_6,t_1	!=!mul_add_c(a[3],b[6],c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3	!=
+	umul	a_4,b_5,t_1	!mul_add_c(a[4],b[5],c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2	!=
+	addx	c_3,%g0,c_3
+	umul	a_5,b_4,t_1	!mul_add_c(a[5],b[4],c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2		!=
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3
+	umul	a_6,b_3,t_1	!mul_add_c(a[6],b[3],c1,c2,c3);
+	addcc	c_1,t_1,c_1	!=
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3
+	umul	a_7,b_2,t_1	!=!mul_add_c(a[7],b[2],c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3	!=
+	st	c_1,rp(9)	!r[9]=c1;
+
+	umul	a_7,b_3,t_1	!mul_add_c(a[7],b[3],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	%g0,%g0,c_1
+	umul	a_6,b_4,t_1	!mul_add_c(a[6],b[4],c2,c3,c1);
+	addcc	c_2,t_1,c_2	!=
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1
+	umul	a_5,b_5,t_1	!=!mul_add_c(a[5],b[5],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1	!=
+	umul	a_4,b_6,t_1	!mul_add_c(a[4],b[6],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3	!=
+	addx	c_1,%g0,c_1
+	umul	a_3,b_7,t_1	!mul_add_c(a[3],b[7],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1
+	st	c_2,rp(10)	!r[10]=c2;
+
+	umul	a_4,b_7,t_1	!=!mul_add_c(a[4],b[7],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	addx	%g0,%g0,c_2	!=
+	umul	a_5,b_6,t_1	!mul_add_c(a[5],b[6],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1	!=
+	addx	c_2,%g0,c_2
+	umul	a_6,b_5,t_1	!mul_add_c(a[6],b[5],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2		!=
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2
+	umul	a_7,b_4,t_1	!mul_add_c(a[7],b[4],c3,c1,c2);
+	addcc	c_3,t_1,c_3	!=
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	st	c_3,rp(11)	!r[11]=c3;
+	addx	c_2,%g0,c_2	!=
+
+	umul	a_7,b_5,t_1	!mul_add_c(a[7],b[5],c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2	!=
+	addx	%g0,%g0,c_3
+	umul	a_6,b_6,t_1	!mul_add_c(a[6],b[6],c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2		!=
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3
+	umul	a_5,b_7,t_1	!mul_add_c(a[5],b[7],c1,c2,c3);
+	addcc	c_1,t_1,c_1	!=
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	st	c_1,rp(12)	!r[12]=c1;
+	addx	c_3,%g0,c_3	!=
+
+	umul	a_6,b_7,t_1	!mul_add_c(a[6],b[7],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3	!=
+	addx	%g0,%g0,c_1
+	umul	a_7,b_6,t_1	!mul_add_c(a[7],b[6],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1
+	st	c_2,rp(13)	!r[13]=c2;
+
+	umul	a_7,b_7,t_1	!=!mul_add_c(a[7],b[7],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	nop			!=
+	st	c_3,rp(14)	!r[14]=c3;
+	st	c_1,rp(15)	!r[15]=c1;
+
+	ret
+	restore	%g0,%g0,%o0
+
+.type	bn_mul_comba8,#function
+.size	bn_mul_comba8,(.-bn_mul_comba8)
+
+.align	32
+
+.global bn_mul_comba4
+/*
+ * void bn_mul_comba4(r,a,b)
+ * BN_ULONG *r,*a,*b;
+ */
+bn_mul_comba4:
+	save	%sp,FRAME_SIZE,%sp
+	ld	ap(0),a_0
+	ld	bp(0),b_0
+	umul	a_0,b_0,c_1	!=!mul_add_c(a[0],b[0],c1,c2,c3);
+	ld	bp(1),b_1
+	rd	%y,c_2
+	st	c_1,rp(0)	!r[0]=c1;
+
+	umul	a_0,b_1,t_1	!=!mul_add_c(a[0],b[1],c2,c3,c1);
+	ld	ap(1),a_1
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	%g0,t_2,c_3
+	addx	%g0,%g0,c_1
+	ld	ap(2),a_2
+	umul	a_1,b_0,t_1	!=!mul_add_c(a[1],b[0],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1	!=
+	st	c_2,rp(1)	!r[1]=c2;
+
+	umul	a_2,b_0,t_1	!mul_add_c(a[2],b[0],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2		!=
+	addxcc	c_1,t_2,c_1
+	addx	%g0,%g0,c_2
+	ld	bp(2),b_2
+	umul	a_1,b_1,t_1	!=!mul_add_c(a[1],b[1],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2	!=
+	ld	bp(3),b_3
+	umul	a_0,b_2,t_1	!mul_add_c(a[0],b[2],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2		!=
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2
+	st	c_3,rp(2)	!r[2]=c3;
+
+	umul	a_0,b_3,t_1	!=!mul_add_c(a[0],b[3],c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	addx	%g0,%g0,c_3	!=
+	umul	a_1,b_2,t_1	!mul_add_c(a[1],b[2],c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2	!=
+	addx	c_3,%g0,c_3
+	ld	ap(3),a_3
+	umul	a_2,b_1,t_1	!mul_add_c(a[2],b[1],c1,c2,c3);
+	addcc	c_1,t_1,c_1	!=
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3
+	umul	a_3,b_0,t_1	!=!mul_add_c(a[3],b[0],c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3	!=
+	st	c_1,rp(3)	!r[3]=c1;
+
+	umul	a_3,b_1,t_1	!mul_add_c(a[3],b[1],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	%g0,%g0,c_1
+	umul	a_2,b_2,t_1	!mul_add_c(a[2],b[2],c2,c3,c1);
+	addcc	c_2,t_1,c_2	!=
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1
+	umul	a_1,b_3,t_1	!=!mul_add_c(a[1],b[3],c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1	!=
+	st	c_2,rp(4)	!r[4]=c2;
+
+	umul	a_2,b_3,t_1	!mul_add_c(a[2],b[3],c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2		!=
+	addxcc	c_1,t_2,c_1
+	addx	%g0,%g0,c_2
+	umul	a_3,b_2,t_1	!mul_add_c(a[3],b[2],c3,c1,c2);
+	addcc	c_3,t_1,c_3	!=
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	st	c_3,rp(5)	!r[5]=c3;
+	addx	c_2,%g0,c_2	!=
+
+	umul	a_3,b_3,t_1	!mul_add_c(a[3],b[3],c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2	!=
+	st	c_1,rp(6)	!r[6]=c1;
+	st	c_2,rp(7)	!r[7]=c2;
+	
+	ret
+	restore	%g0,%g0,%o0
+
+.type	bn_mul_comba4,#function
+.size	bn_mul_comba4,(.-bn_mul_comba4)
+
+.align	32
+
+.global bn_sqr_comba8
+bn_sqr_comba8:
+	save	%sp,FRAME_SIZE,%sp
+	ld	ap(0),a_0
+	ld	ap(1),a_1
+	umul	a_0,a_0,c_1	!=!sqr_add_c(a,0,c1,c2,c3);
+	rd	%y,c_2
+	st	c_1,rp(0)	!r[0]=c1;
+
+	ld	ap(2),a_2
+	umul	a_0,a_1,t_1	!=!sqr_add_c2(a,1,0,c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2
+	addxcc	%g0,t_2,c_3
+	addx	%g0,%g0,c_1	!=
+	addcc	c_2,t_1,c_2
+	addxcc	c_3,t_2,c_3
+	st	c_2,rp(1)	!r[1]=c2;
+	addx	c_1,%g0,c_1	!=
+
+	umul	a_2,a_0,t_1	!sqr_add_c2(a,2,0,c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1	!=
+	addx	%g0,%g0,c_2
+	addcc	c_3,t_1,c_3
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2	!=
+	ld	ap(3),a_3
+	umul	a_1,a_1,t_1	!sqr_add_c(a,1,c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2		!=
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2
+	st	c_3,rp(2)	!r[2]=c3;
+
+	umul	a_0,a_3,t_1	!=!sqr_add_c2(a,3,0,c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	addx	%g0,%g0,c_3	!=
+	addcc	c_1,t_1,c_1
+	addxcc	c_2,t_2,c_2
+	ld	ap(4),a_4
+	addx	c_3,%g0,c_3	!=
+	umul	a_1,a_2,t_1	!sqr_add_c2(a,2,1,c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2	!=
+	addx	c_3,%g0,c_3
+	addcc	c_1,t_1,c_1
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3	!=
+	st	c_1,rp(3)	!r[3]=c1;
+
+	umul	a_4,a_0,t_1	!sqr_add_c2(a,4,0,c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	%g0,%g0,c_1
+	addcc	c_2,t_1,c_2
+	addxcc	c_3,t_2,c_3	!=
+	addx	c_1,%g0,c_1
+	umul	a_3,a_1,t_1	!sqr_add_c2(a,3,1,c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1
+	addcc	c_2,t_1,c_2
+	addxcc	c_3,t_2,c_3	!=
+	addx	c_1,%g0,c_1
+	ld	ap(5),a_5
+	umul	a_2,a_2,t_1	!sqr_add_c(a,2,c2,c3,c1);
+	addcc	c_2,t_1,c_2	!=
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3
+	st	c_2,rp(4)	!r[4]=c2;
+	addx	c_1,%g0,c_1	!=
+
+	umul	a_0,a_5,t_1	!sqr_add_c2(a,5,0,c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1	!=
+	addx	%g0,%g0,c_2
+	addcc	c_3,t_1,c_3
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2	!=
+	umul	a_1,a_4,t_1	!sqr_add_c2(a,4,1,c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1	!=
+	addx	c_2,%g0,c_2
+	addcc	c_3,t_1,c_3
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2	!=
+	ld	ap(6),a_6
+	umul	a_2,a_3,t_1	!sqr_add_c2(a,3,2,c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2		!=
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2
+	addcc	c_3,t_1,c_3
+	addxcc	c_1,t_2,c_1	!=
+	addx	c_2,%g0,c_2
+	st	c_3,rp(5)	!r[5]=c3;
+
+	umul	a_6,a_0,t_1	!sqr_add_c2(a,6,0,c1,c2,c3);
+	addcc	c_1,t_1,c_1	!=
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	addx	%g0,%g0,c_3
+	addcc	c_1,t_1,c_1	!=
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3
+	umul	a_5,a_1,t_1	!sqr_add_c2(a,5,1,c1,c2,c3);
+	addcc	c_1,t_1,c_1	!=
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3
+	addcc	c_1,t_1,c_1	!=
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3
+	umul	a_4,a_2,t_1	!sqr_add_c2(a,4,2,c1,c2,c3);
+	addcc	c_1,t_1,c_1	!=
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3
+	addcc	c_1,t_1,c_1	!=
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3
+	ld	ap(7),a_7
+	umul	a_3,a_3,t_1	!=!sqr_add_c(a,3,c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3	!=
+	st	c_1,rp(6)	!r[6]=c1;
+
+	umul	a_0,a_7,t_1	!sqr_add_c2(a,7,0,c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	%g0,%g0,c_1
+	addcc	c_2,t_1,c_2
+	addxcc	c_3,t_2,c_3	!=
+	addx	c_1,%g0,c_1
+	umul	a_1,a_6,t_1	!sqr_add_c2(a,6,1,c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1
+	addcc	c_2,t_1,c_2
+	addxcc	c_3,t_2,c_3	!=
+	addx	c_1,%g0,c_1
+	umul	a_2,a_5,t_1	!sqr_add_c2(a,5,2,c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1
+	addcc	c_2,t_1,c_2
+	addxcc	c_3,t_2,c_3	!=
+	addx	c_1,%g0,c_1
+	umul	a_3,a_4,t_1	!sqr_add_c2(a,4,3,c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1
+	addcc	c_2,t_1,c_2
+	addxcc	c_3,t_2,c_3	!=
+	addx	c_1,%g0,c_1
+	st	c_2,rp(7)	!r[7]=c2;
+
+	umul	a_7,a_1,t_1	!sqr_add_c2(a,7,1,c3,c1,c2);
+	addcc	c_3,t_1,c_3	!=
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	addx	%g0,%g0,c_2
+	addcc	c_3,t_1,c_3	!=
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2
+	umul	a_6,a_2,t_1	!sqr_add_c2(a,6,2,c3,c1,c2);
+	addcc	c_3,t_1,c_3	!=
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2
+	addcc	c_3,t_1,c_3	!=
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2
+	umul	a_5,a_3,t_1	!sqr_add_c2(a,5,3,c3,c1,c2);
+	addcc	c_3,t_1,c_3	!=
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2
+	addcc	c_3,t_1,c_3	!=
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2
+	umul	a_4,a_4,t_1	!sqr_add_c(a,4,c3,c1,c2);
+	addcc	c_3,t_1,c_3	!=
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	st	c_3,rp(8)	!r[8]=c3;
+	addx	c_2,%g0,c_2	!=
+
+	umul	a_2,a_7,t_1	!sqr_add_c2(a,7,2,c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2	!=
+	addx	%g0,%g0,c_3
+	addcc	c_1,t_1,c_1
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3	!=
+	umul	a_3,a_6,t_1	!sqr_add_c2(a,6,3,c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2	!=
+	addx	c_3,%g0,c_3
+	addcc	c_1,t_1,c_1
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3	!=
+	umul	a_4,a_5,t_1	!sqr_add_c2(a,5,4,c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2	!=
+	addx	c_3,%g0,c_3
+	addcc	c_1,t_1,c_1
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3	!=
+	st	c_1,rp(9)	!r[9]=c1;
+
+	umul	a_7,a_3,t_1	!sqr_add_c2(a,7,3,c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	%g0,%g0,c_1
+	addcc	c_2,t_1,c_2
+	addxcc	c_3,t_2,c_3	!=
+	addx	c_1,%g0,c_1
+	umul	a_6,a_4,t_1	!sqr_add_c2(a,6,4,c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1
+	addcc	c_2,t_1,c_2
+	addxcc	c_3,t_2,c_3	!=
+	addx	c_1,%g0,c_1
+	umul	a_5,a_5,t_1	!sqr_add_c(a,5,c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1
+	st	c_2,rp(10)	!r[10]=c2;
+
+	umul	a_4,a_7,t_1	!=!sqr_add_c2(a,7,4,c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	addx	%g0,%g0,c_2	!=
+	addcc	c_3,t_1,c_3
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2
+	umul	a_5,a_6,t_1	!=!sqr_add_c2(a,6,5,c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	addx	c_2,%g0,c_2	!=
+	addcc	c_3,t_1,c_3
+	addxcc	c_1,t_2,c_1
+	st	c_3,rp(11)	!r[11]=c3;
+	addx	c_2,%g0,c_2	!=
+
+	umul	a_7,a_5,t_1	!sqr_add_c2(a,7,5,c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2	!=
+	addx	%g0,%g0,c_3
+	addcc	c_1,t_1,c_1
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3	!=
+	umul	a_6,a_6,t_1	!sqr_add_c(a,6,c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2	!=
+	addx	c_3,%g0,c_3
+	st	c_1,rp(12)	!r[12]=c1;
+
+	umul	a_6,a_7,t_1	!sqr_add_c2(a,7,6,c2,c3,c1);
+	addcc	c_2,t_1,c_2	!=
+	rd	%y,t_2
+	addxcc	c_3,t_2,c_3
+	addx	%g0,%g0,c_1
+	addcc	c_2,t_1,c_2	!=
+	addxcc	c_3,t_2,c_3
+	st	c_2,rp(13)	!r[13]=c2;
+	addx	c_1,%g0,c_1	!=
+
+	umul	a_7,a_7,t_1	!sqr_add_c(a,7,c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1	!=
+	st	c_3,rp(14)	!r[14]=c3;
+	st	c_1,rp(15)	!r[15]=c1;
+
+	ret
+	restore	%g0,%g0,%o0
+
+.type	bn_sqr_comba8,#function
+.size	bn_sqr_comba8,(.-bn_sqr_comba8)
+
+.align	32
+
+.global bn_sqr_comba4
+/*
+ * void bn_sqr_comba4(r,a)
+ * BN_ULONG *r,*a;
+ */
+bn_sqr_comba4:
+	save	%sp,FRAME_SIZE,%sp
+	ld	ap(0),a_0
+	umul	a_0,a_0,c_1	!sqr_add_c(a,0,c1,c2,c3);
+	ld	ap(1),a_1	!=
+	rd	%y,c_2
+	st	c_1,rp(0)	!r[0]=c1;
+
+	ld	ap(2),a_2
+	umul	a_0,a_1,t_1	!=!sqr_add_c2(a,1,0,c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2
+	addxcc	%g0,t_2,c_3
+	addx	%g0,%g0,c_1	!=
+	addcc	c_2,t_1,c_2
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1	!=
+	st	c_2,rp(1)	!r[1]=c2;
+
+	umul	a_2,a_0,t_1	!sqr_add_c2(a,2,0,c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2		!=
+	addxcc	c_1,t_2,c_1
+	addx	%g0,%g0,c_2
+	addcc	c_3,t_1,c_3
+	addxcc	c_1,t_2,c_1	!=
+	addx	c_2,%g0,c_2
+	ld	ap(3),a_3
+	umul	a_1,a_1,t_1	!sqr_add_c(a,1,c3,c1,c2);
+	addcc	c_3,t_1,c_3	!=
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	st	c_3,rp(2)	!r[2]=c3;
+	addx	c_2,%g0,c_2	!=
+
+	umul	a_0,a_3,t_1	!sqr_add_c2(a,3,0,c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2	!=
+	addx	%g0,%g0,c_3
+	addcc	c_1,t_1,c_1
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3	!=
+	umul	a_1,a_2,t_1	!sqr_add_c2(a,2,1,c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2	!=
+	addx	c_3,%g0,c_3
+	addcc	c_1,t_1,c_1
+	addxcc	c_2,t_2,c_2
+	addx	c_3,%g0,c_3	!=
+	st	c_1,rp(3)	!r[3]=c1;
+
+	umul	a_3,a_1,t_1	!sqr_add_c2(a,3,1,c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	%g0,%g0,c_1
+	addcc	c_2,t_1,c_2
+	addxcc	c_3,t_2,c_3	!=
+	addx	c_1,%g0,c_1
+	umul	a_2,a_2,t_1	!sqr_add_c(a,2,c2,c3,c1);
+	addcc	c_2,t_1,c_2
+	rd	%y,t_2		!=
+	addxcc	c_3,t_2,c_3
+	addx	c_1,%g0,c_1
+	st	c_2,rp(4)	!r[4]=c2;
+
+	umul	a_2,a_3,t_1	!=!sqr_add_c2(a,3,2,c3,c1,c2);
+	addcc	c_3,t_1,c_3
+	rd	%y,t_2
+	addxcc	c_1,t_2,c_1
+	addx	%g0,%g0,c_2	!=
+	addcc	c_3,t_1,c_3
+	addxcc	c_1,t_2,c_1
+	st	c_3,rp(5)	!r[5]=c3;
+	addx	c_2,%g0,c_2	!=
+
+	umul	a_3,a_3,t_1	!sqr_add_c(a,3,c1,c2,c3);
+	addcc	c_1,t_1,c_1
+	rd	%y,t_2
+	addxcc	c_2,t_2,c_2	!=
+	st	c_1,rp(6)	!r[6]=c1;
+	st	c_2,rp(7)	!r[7]=c2;
+	
+	ret
+	restore	%g0,%g0,%o0
+
+.type	bn_sqr_comba4,#function
+.size	bn_sqr_comba4,(.-bn_sqr_comba4)
+
+.align	32
diff --git a/openssl/crypto/bn/asm/sparcv8plus.S b/openssl/crypto/bn/asm/sparcv8plus.S
new file mode 100644
index 0000000..63de186
--- /dev/null
+++ b/openssl/crypto/bn/asm/sparcv8plus.S
@@ -0,0 +1,1558 @@
+.ident	"sparcv8plus.s, Version 1.4"
+.ident	"SPARC v9 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
+
+/*
+ * ====================================================================
+ * Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+ * project.
+ *
+ * Rights for redistribution and usage in source and binary forms are
+ * granted according to the OpenSSL license. Warranty of any kind is
+ * disclaimed.
+ * ====================================================================
+ */
+
+/*
+ * This is my modest contributon to OpenSSL project (see
+ * http://www.openssl.org/ for more information about it) and is
+ * a drop-in UltraSPARC ISA replacement for crypto/bn/bn_asm.c
+ * module. For updates see http://fy.chalmers.se/~appro/hpe/.
+ *
+ * Questions-n-answers.
+ *
+ * Q. How to compile?
+ * A. With SC4.x/SC5.x:
+ *
+ *	cc -xarch=v8plus -c bn_asm.sparc.v8plus.S -o bn_asm.o
+ *
+ *    and with gcc:
+ *
+ *	gcc -mcpu=ultrasparc -c bn_asm.sparc.v8plus.S -o bn_asm.o
+ *
+ *    or if above fails (it does if you have gas installed):
+ *
+ *	gcc -E bn_asm.sparc.v8plus.S | as -xarch=v8plus /dev/fd/0 -o bn_asm.o
+ *
+ *    Quick-n-dirty way to fuse the module into the library.
+ *    Provided that the library is already configured and built
+ *    (in 0.9.2 case with no-asm option):
+ *
+ *	# cd crypto/bn
+ *	# cp /some/place/bn_asm.sparc.v8plus.S .
+ *	# cc -xarch=v8plus -c bn_asm.sparc.v8plus.S -o bn_asm.o
+ *	# make
+ *	# cd ../..
+ *	# make; make test
+ *
+ *    Quick-n-dirty way to get rid of it:
+ *
+ *	# cd crypto/bn
+ *	# touch bn_asm.c
+ *	# make
+ *	# cd ../..
+ *	# make; make test
+ *
+ * Q. V8plus achitecture? What kind of beast is that?
+ * A. Well, it's rather a programming model than an architecture...
+ *    It's actually v9-compliant, i.e. *any* UltraSPARC, CPU under
+ *    special conditions, namely when kernel doesn't preserve upper
+ *    32 bits of otherwise 64-bit registers during a context switch.
+ *
+ * Q. Why just UltraSPARC? What about SuperSPARC?
+ * A. Original release did target UltraSPARC only. Now SuperSPARC
+ *    version is provided along. Both version share bn_*comba[48]
+ *    implementations (see comment later in code for explanation).
+ *    But what's so special about this UltraSPARC implementation?
+ *    Why didn't I let compiler do the job? Trouble is that most of
+ *    available compilers (well, SC5.0 is the only exception) don't
+ *    attempt to take advantage of UltraSPARC's 64-bitness under
+ *    32-bit kernels even though it's perfectly possible (see next
+ *    question).
+ *
+ * Q. 64-bit registers under 32-bit kernels? Didn't you just say it
+ *    doesn't work?
+ * A. You can't adress *all* registers as 64-bit wide:-( The catch is
+ *    that you actually may rely upon %o0-%o5 and %g1-%g4 being fully
+ *    preserved if you're in a leaf function, i.e. such never calling
+ *    any other functions. All functions in this module are leaf and
+ *    10 registers is a handful. And as a matter of fact none-"comba"
+ *    routines don't require even that much and I could even afford to
+ *    not allocate own stack frame for 'em:-)
+ *
+ * Q. What about 64-bit kernels?
+ * A. What about 'em? Just kidding:-) Pure 64-bit version is currently
+ *    under evaluation and development...
+ *
+ * Q. What about shared libraries?
+ * A. What about 'em? Kidding again:-) Code does *not* contain any
+ *    code position dependencies and it's safe to include it into
+ *    shared library as is.
+ *
+ * Q. How much faster does it go?
+ * A. Do you have a good benchmark? In either case below is what I
+ *    experience with crypto/bn/expspeed.c test program:
+ *
+ *	v8plus module on U10/300MHz against bn_asm.c compiled with:
+ *
+ *	cc-5.0 -xarch=v8plus -xO5 -xdepend	+7-12%
+ *	cc-4.2 -xarch=v8plus -xO5 -xdepend	+25-35%
+ *	egcs-1.1.2 -mcpu=ultrasparc -O3		+35-45%
+ *
+ *	v8 module on SS10/60MHz against bn_asm.c compiled with:
+ *
+ *	cc-5.0 -xarch=v8 -xO5 -xdepend		+7-10%
+ *	cc-4.2 -xarch=v8 -xO5 -xdepend		+10%
+ *	egcs-1.1.2 -mv8 -O3			+35-45%
+ *
+ *    As you can see it's damn hard to beat the new Sun C compiler
+ *    and it's in first place GNU C users who will appreciate this
+ *    assembler implementation:-)	
+ */
+
+/*
+ * Revision history.
+ *
+ * 1.0	- initial release;
+ * 1.1	- new loop unrolling model(*);
+ *	- some more fine tuning;
+ * 1.2	- made gas friendly;
+ *	- updates to documentation concerning v9;
+ *	- new performance comparison matrix;
+ * 1.3	- fixed problem with /usr/ccs/lib/cpp;
+ * 1.4	- native V9 bn_*_comba[48] implementation (15% more efficient)
+ *	  resulting in slight overall performance kick;
+ *	- some retunes;
+ *	- support for GNU as added;
+ *
+ * (*)	Originally unrolled loop looked like this:
+ *	    for (;;) {
+ *		op(p+0); if (--n==0) break;
+ *		op(p+1); if (--n==0) break;
+ *		op(p+2); if (--n==0) break;
+ *		op(p+3); if (--n==0) break;
+ *		p+=4;
+ *	    }
+ *	I unroll according to following:
+ *	    while (n&~3) {
+ *		op(p+0); op(p+1); op(p+2); op(p+3);
+ *		p+=4; n=-4;
+ *	    }
+ *	    if (n) {
+ *		op(p+0); if (--n==0) return;
+ *		op(p+2); if (--n==0) return;
+ *		op(p+3); return;
+ *	    }
+ */
+
+#if defined(__SUNPRO_C) && defined(__sparcv9)
+  /* They've said -xarch=v9 at command line */
+  .register	%g2,#scratch
+  .register	%g3,#scratch
+# define	FRAME_SIZE	-192
+#elif defined(__GNUC__) && defined(__arch64__)
+  /* They've said -m64 at command line */
+  .register	%g2,#scratch
+  .register	%g3,#scratch
+# define	FRAME_SIZE	-192
+#else 
+# define	FRAME_SIZE	-96
+#endif 
+/*
+ * GNU assembler can't stand stuw:-(
+ */
+#define stuw st
+
+.section	".text",#alloc,#execinstr
+.file		"bn_asm.sparc.v8plus.S"
+
+.align	32
+
+.global bn_mul_add_words
+/*
+ * BN_ULONG bn_mul_add_words(rp,ap,num,w)
+ * BN_ULONG *rp,*ap;
+ * int num;
+ * BN_ULONG w;
+ */
+bn_mul_add_words:
+	sra	%o2,%g0,%o2	! signx %o2
+	brgz,a	%o2,.L_bn_mul_add_words_proceed
+	lduw	[%o1],%g2
+	retl
+	clr	%o0
+	nop
+	nop
+	nop
+
+.L_bn_mul_add_words_proceed:
+	srl	%o3,%g0,%o3	! clruw	%o3
+	andcc	%o2,-4,%g0
+	bz,pn	%icc,.L_bn_mul_add_words_tail
+	clr	%o5
+
+.L_bn_mul_add_words_loop:	! wow! 32 aligned!
+	lduw	[%o0],%g1
+	lduw	[%o1+4],%g3
+	mulx	%o3,%g2,%g2
+	add	%g1,%o5,%o4
+	nop
+	add	%o4,%g2,%o4
+	stuw	%o4,[%o0]
+	srlx	%o4,32,%o5
+
+	lduw	[%o0+4],%g1
+	lduw	[%o1+8],%g2
+	mulx	%o3,%g3,%g3
+	add	%g1,%o5,%o4
+	dec	4,%o2
+	add	%o4,%g3,%o4
+	stuw	%o4,[%o0+4]
+	srlx	%o4,32,%o5
+
+	lduw	[%o0+8],%g1
+	lduw	[%o1+12],%g3
+	mulx	%o3,%g2,%g2
+	add	%g1,%o5,%o4
+	inc	16,%o1
+	add	%o4,%g2,%o4
+	stuw	%o4,[%o0+8]
+	srlx	%o4,32,%o5
+
+	lduw	[%o0+12],%g1
+	mulx	%o3,%g3,%g3
+	add	%g1,%o5,%o4
+	inc	16,%o0
+	add	%o4,%g3,%o4
+	andcc	%o2,-4,%g0
+	stuw	%o4,[%o0-4]
+	srlx	%o4,32,%o5
+	bnz,a,pt	%icc,.L_bn_mul_add_words_loop
+	lduw	[%o1],%g2
+
+	brnz,a,pn	%o2,.L_bn_mul_add_words_tail
+	lduw	[%o1],%g2
+.L_bn_mul_add_words_return:
+	retl
+	mov	%o5,%o0
+
+.L_bn_mul_add_words_tail:
+	lduw	[%o0],%g1
+	mulx	%o3,%g2,%g2
+	add	%g1,%o5,%o4
+	dec	%o2
+	add	%o4,%g2,%o4
+	srlx	%o4,32,%o5
+	brz,pt	%o2,.L_bn_mul_add_words_return
+	stuw	%o4,[%o0]
+
+	lduw	[%o1+4],%g2
+	lduw	[%o0+4],%g1
+	mulx	%o3,%g2,%g2
+	add	%g1,%o5,%o4
+	dec	%o2
+	add	%o4,%g2,%o4
+	srlx	%o4,32,%o5
+	brz,pt	%o2,.L_bn_mul_add_words_return
+	stuw	%o4,[%o0+4]
+
+	lduw	[%o1+8],%g2
+	lduw	[%o0+8],%g1
+	mulx	%o3,%g2,%g2
+	add	%g1,%o5,%o4
+	add	%o4,%g2,%o4
+	stuw	%o4,[%o0+8]
+	retl
+	srlx	%o4,32,%o0
+
+.type	bn_mul_add_words,#function
+.size	bn_mul_add_words,(.-bn_mul_add_words)
+
+.align	32
+
+.global bn_mul_words
+/*
+ * BN_ULONG bn_mul_words(rp,ap,num,w)
+ * BN_ULONG *rp,*ap;
+ * int num;
+ * BN_ULONG w;
+ */
+bn_mul_words:
+	sra	%o2,%g0,%o2	! signx %o2
+	brgz,a	%o2,.L_bn_mul_words_proceeed
+	lduw	[%o1],%g2
+	retl
+	clr	%o0
+	nop
+	nop
+	nop
+
+.L_bn_mul_words_proceeed:
+	srl	%o3,%g0,%o3	! clruw	%o3
+	andcc	%o2,-4,%g0
+	bz,pn	%icc,.L_bn_mul_words_tail
+	clr	%o5
+
+.L_bn_mul_words_loop:		! wow! 32 aligned!
+	lduw	[%o1+4],%g3
+	mulx	%o3,%g2,%g2
+	add	%g2,%o5,%o4
+	nop
+	stuw	%o4,[%o0]
+	srlx	%o4,32,%o5
+
+	lduw	[%o1+8],%g2
+	mulx	%o3,%g3,%g3
+	add	%g3,%o5,%o4
+	dec	4,%o2
+	stuw	%o4,[%o0+4]
+	srlx	%o4,32,%o5
+
+	lduw	[%o1+12],%g3
+	mulx	%o3,%g2,%g2
+	add	%g2,%o5,%o4
+	inc	16,%o1
+	stuw	%o4,[%o0+8]
+	srlx	%o4,32,%o5
+
+	mulx	%o3,%g3,%g3
+	add	%g3,%o5,%o4
+	inc	16,%o0
+	stuw	%o4,[%o0-4]
+	srlx	%o4,32,%o5
+	andcc	%o2,-4,%g0
+	bnz,a,pt	%icc,.L_bn_mul_words_loop
+	lduw	[%o1],%g2
+	nop
+	nop
+
+	brnz,a,pn	%o2,.L_bn_mul_words_tail
+	lduw	[%o1],%g2
+.L_bn_mul_words_return:
+	retl
+	mov	%o5,%o0
+
+.L_bn_mul_words_tail:
+	mulx	%o3,%g2,%g2
+	add	%g2,%o5,%o4
+	dec	%o2
+	srlx	%o4,32,%o5
+	brz,pt	%o2,.L_bn_mul_words_return
+	stuw	%o4,[%o0]
+
+	lduw	[%o1+4],%g2
+	mulx	%o3,%g2,%g2
+	add	%g2,%o5,%o4
+	dec	%o2
+	srlx	%o4,32,%o5
+	brz,pt	%o2,.L_bn_mul_words_return
+	stuw	%o4,[%o0+4]
+
+	lduw	[%o1+8],%g2
+	mulx	%o3,%g2,%g2
+	add	%g2,%o5,%o4
+	stuw	%o4,[%o0+8]
+	retl
+	srlx	%o4,32,%o0
+
+.type	bn_mul_words,#function
+.size	bn_mul_words,(.-bn_mul_words)
+
+.align  32
+.global	bn_sqr_words
+/*
+ * void bn_sqr_words(r,a,n)
+ * BN_ULONG *r,*a;
+ * int n;
+ */
+bn_sqr_words:
+	sra	%o2,%g0,%o2	! signx %o2
+	brgz,a	%o2,.L_bn_sqr_words_proceeed
+	lduw	[%o1],%g2
+	retl
+	clr	%o0
+	nop
+	nop
+	nop
+
+.L_bn_sqr_words_proceeed:
+	andcc	%o2,-4,%g0
+	nop
+	bz,pn	%icc,.L_bn_sqr_words_tail
+	nop
+
+.L_bn_sqr_words_loop:		! wow! 32 aligned!
+	lduw	[%o1+4],%g3
+	mulx	%g2,%g2,%o4
+	stuw	%o4,[%o0]
+	srlx	%o4,32,%o5
+	stuw	%o5,[%o0+4]
+	nop
+
+	lduw	[%o1+8],%g2
+	mulx	%g3,%g3,%o4
+	dec	4,%o2
+	stuw	%o4,[%o0+8]
+	srlx	%o4,32,%o5
+	stuw	%o5,[%o0+12]
+
+	lduw	[%o1+12],%g3
+	mulx	%g2,%g2,%o4
+	srlx	%o4,32,%o5
+	stuw	%o4,[%o0+16]
+	inc	16,%o1
+	stuw	%o5,[%o0+20]
+
+	mulx	%g3,%g3,%o4
+	inc	32,%o0
+	stuw	%o4,[%o0-8]
+	srlx	%o4,32,%o5
+	andcc	%o2,-4,%g2
+	stuw	%o5,[%o0-4]
+	bnz,a,pt	%icc,.L_bn_sqr_words_loop
+	lduw	[%o1],%g2
+	nop
+
+	brnz,a,pn	%o2,.L_bn_sqr_words_tail
+	lduw	[%o1],%g2
+.L_bn_sqr_words_return:
+	retl
+	clr	%o0
+
+.L_bn_sqr_words_tail:
+	mulx	%g2,%g2,%o4
+	dec	%o2
+	stuw	%o4,[%o0]
+	srlx	%o4,32,%o5
+	brz,pt	%o2,.L_bn_sqr_words_return
+	stuw	%o5,[%o0+4]
+
+	lduw	[%o1+4],%g2
+	mulx	%g2,%g2,%o4
+	dec	%o2
+	stuw	%o4,[%o0+8]
+	srlx	%o4,32,%o5
+	brz,pt	%o2,.L_bn_sqr_words_return
+	stuw	%o5,[%o0+12]
+
+	lduw	[%o1+8],%g2
+	mulx	%g2,%g2,%o4
+	srlx	%o4,32,%o5
+	stuw	%o4,[%o0+16]
+	stuw	%o5,[%o0+20]
+	retl
+	clr	%o0
+
+.type	bn_sqr_words,#function
+.size	bn_sqr_words,(.-bn_sqr_words)
+
+.align	32
+.global bn_div_words
+/*
+ * BN_ULONG bn_div_words(h,l,d)
+ * BN_ULONG h,l,d;
+ */
+bn_div_words:
+	sllx	%o0,32,%o0
+	or	%o0,%o1,%o0
+	udivx	%o0,%o2,%o0
+	retl
+	srl	%o0,%g0,%o0	! clruw	%o0
+
+.type	bn_div_words,#function
+.size	bn_div_words,(.-bn_div_words)
+
+.align	32
+
+.global bn_add_words
+/*
+ * BN_ULONG bn_add_words(rp,ap,bp,n)
+ * BN_ULONG *rp,*ap,*bp;
+ * int n;
+ */
+bn_add_words:
+	sra	%o3,%g0,%o3	! signx %o3
+	brgz,a	%o3,.L_bn_add_words_proceed
+	lduw	[%o1],%o4
+	retl
+	clr	%o0
+
+.L_bn_add_words_proceed:
+	andcc	%o3,-4,%g0
+	bz,pn	%icc,.L_bn_add_words_tail
+	addcc	%g0,0,%g0	! clear carry flag
+
+.L_bn_add_words_loop:		! wow! 32 aligned!
+	dec	4,%o3
+	lduw	[%o2],%o5
+	lduw	[%o1+4],%g1
+	lduw	[%o2+4],%g2
+	lduw	[%o1+8],%g3
+	lduw	[%o2+8],%g4
+	addccc	%o5,%o4,%o5
+	stuw	%o5,[%o0]
+
+	lduw	[%o1+12],%o4
+	lduw	[%o2+12],%o5
+	inc	16,%o1
+	addccc	%g1,%g2,%g1
+	stuw	%g1,[%o0+4]
+	
+	inc	16,%o2
+	addccc	%g3,%g4,%g3
+	stuw	%g3,[%o0+8]
+
+	inc	16,%o0
+	addccc	%o5,%o4,%o5
+	stuw	%o5,[%o0-4]
+	and	%o3,-4,%g1
+	brnz,a,pt	%g1,.L_bn_add_words_loop
+	lduw	[%o1],%o4
+
+	brnz,a,pn	%o3,.L_bn_add_words_tail
+	lduw	[%o1],%o4
+.L_bn_add_words_return:
+	clr	%o0
+	retl
+	movcs	%icc,1,%o0
+	nop
+
+.L_bn_add_words_tail:
+	lduw	[%o2],%o5
+	dec	%o3
+	addccc	%o5,%o4,%o5
+	brz,pt	%o3,.L_bn_add_words_return
+	stuw	%o5,[%o0]
+
+	lduw	[%o1+4],%o4
+	lduw	[%o2+4],%o5
+	dec	%o3
+	addccc	%o5,%o4,%o5
+	brz,pt	%o3,.L_bn_add_words_return
+	stuw	%o5,[%o0+4]
+
+	lduw	[%o1+8],%o4
+	lduw	[%o2+8],%o5
+	addccc	%o5,%o4,%o5
+	stuw	%o5,[%o0+8]
+	clr	%o0
+	retl
+	movcs	%icc,1,%o0
+
+.type	bn_add_words,#function
+.size	bn_add_words,(.-bn_add_words)
+
+.global bn_sub_words
+/*
+ * BN_ULONG bn_sub_words(rp,ap,bp,n)
+ * BN_ULONG *rp,*ap,*bp;
+ * int n;
+ */
+bn_sub_words:
+	sra	%o3,%g0,%o3	! signx %o3
+	brgz,a	%o3,.L_bn_sub_words_proceed
+	lduw	[%o1],%o4
+	retl
+	clr	%o0
+
+.L_bn_sub_words_proceed:
+	andcc	%o3,-4,%g0
+	bz,pn	%icc,.L_bn_sub_words_tail
+	addcc	%g0,0,%g0	! clear carry flag
+
+.L_bn_sub_words_loop:		! wow! 32 aligned!
+	dec	4,%o3
+	lduw	[%o2],%o5
+	lduw	[%o1+4],%g1
+	lduw	[%o2+4],%g2
+	lduw	[%o1+8],%g3
+	lduw	[%o2+8],%g4
+	subccc	%o4,%o5,%o5
+	stuw	%o5,[%o0]
+
+	lduw	[%o1+12],%o4
+	lduw	[%o2+12],%o5
+	inc	16,%o1
+	subccc	%g1,%g2,%g2
+	stuw	%g2,[%o0+4]
+
+	inc	16,%o2
+	subccc	%g3,%g4,%g4
+	stuw	%g4,[%o0+8]
+
+	inc	16,%o0
+	subccc	%o4,%o5,%o5
+	stuw	%o5,[%o0-4]
+	and	%o3,-4,%g1
+	brnz,a,pt	%g1,.L_bn_sub_words_loop
+	lduw	[%o1],%o4
+
+	brnz,a,pn	%o3,.L_bn_sub_words_tail
+	lduw	[%o1],%o4
+.L_bn_sub_words_return:
+	clr	%o0
+	retl
+	movcs	%icc,1,%o0
+	nop
+
+.L_bn_sub_words_tail:		! wow! 32 aligned!
+	lduw	[%o2],%o5
+	dec	%o3
+	subccc	%o4,%o5,%o5
+	brz,pt	%o3,.L_bn_sub_words_return
+	stuw	%o5,[%o0]
+
+	lduw	[%o1+4],%o4
+	lduw	[%o2+4],%o5
+	dec	%o3
+	subccc	%o4,%o5,%o5
+	brz,pt	%o3,.L_bn_sub_words_return
+	stuw	%o5,[%o0+4]
+
+	lduw	[%o1+8],%o4
+	lduw	[%o2+8],%o5
+	subccc	%o4,%o5,%o5
+	stuw	%o5,[%o0+8]
+	clr	%o0
+	retl
+	movcs	%icc,1,%o0
+
+.type	bn_sub_words,#function
+.size	bn_sub_words,(.-bn_sub_words)
+
+/*
+ * Code below depends on the fact that upper parts of the %l0-%l7
+ * and %i0-%i7 are zeroed by kernel after context switch. In
+ * previous versions this comment stated that "the trouble is that
+ * it's not feasible to implement the mumbo-jumbo in less V9
+ * instructions:-(" which apparently isn't true thanks to
+ * 'bcs,a %xcc,.+8; inc %rd' pair. But the performance improvement
+ * results not from the shorter code, but from elimination of
+ * multicycle none-pairable 'rd %y,%rd' instructions.
+ *
+ *							Andy.
+ */
+
+/*
+ * Here is register usage map for *all* routines below.
+ */
+#define t_1	%o0
+#define	t_2	%o1
+#define c_12	%o2
+#define c_3	%o3
+
+#define ap(I)	[%i1+4*I]
+#define bp(I)	[%i2+4*I]
+#define rp(I)	[%i0+4*I]
+
+#define	a_0	%l0
+#define	a_1	%l1
+#define	a_2	%l2
+#define	a_3	%l3
+#define	a_4	%l4
+#define	a_5	%l5
+#define	a_6	%l6
+#define	a_7	%l7
+
+#define	b_0	%i3
+#define	b_1	%i4
+#define	b_2	%i5
+#define	b_3	%o4
+#define	b_4	%o5
+#define	b_5	%o7
+#define	b_6	%g1
+#define	b_7	%g4
+
+.align	32
+.global bn_mul_comba8
+/*
+ * void bn_mul_comba8(r,a,b)
+ * BN_ULONG *r,*a,*b;
+ */
+bn_mul_comba8:
+	save	%sp,FRAME_SIZE,%sp
+	mov	1,t_2
+	lduw	ap(0),a_0
+	sllx	t_2,32,t_2
+	lduw	bp(0),b_0	!=
+	lduw	bp(1),b_1
+	mulx	a_0,b_0,t_1	!mul_add_c(a[0],b[0],c1,c2,c3);
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(0)	!=!r[0]=c1;
+
+	lduw	ap(1),a_1
+	mulx	a_0,b_1,t_1	!mul_add_c(a[0],b[1],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	clr	c_3		!=
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	lduw	ap(2),a_2
+	mulx	a_1,b_0,t_1	!=!mul_add_c(a[1],b[0],c2,c3,c1);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12	!=
+	stuw	t_1,rp(1)	!r[1]=c2;
+	or	c_12,c_3,c_12
+
+	mulx	a_2,b_0,t_1	!mul_add_c(a[2],b[0],c3,c1,c2);
+	addcc	c_12,t_1,c_12	!=
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	lduw	bp(2),b_2	!=
+	mulx	a_1,b_1,t_1	!mul_add_c(a[1],b[1],c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3	!=
+	lduw	bp(3),b_3
+	mulx	a_0,b_2,t_1	!mul_add_c(a[0],b[2],c3,c1,c2);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(2)	!r[2]=c3;
+	or	c_12,c_3,c_12	!=
+
+	mulx	a_0,b_3,t_1	!mul_add_c(a[0],b[3],c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_1,b_2,t_1	!=!mul_add_c(a[1],b[2],c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	lduw	ap(3),a_3
+	mulx	a_2,b_1,t_1	!mul_add_c(a[2],b[1],c1,c2,c3);
+	addcc	c_12,t_1,c_12	!=
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	lduw	ap(4),a_4
+	mulx	a_3,b_0,t_1	!=!mul_add_c(a[3],b[0],c1,c2,c3);!=
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12	!=
+	stuw	t_1,rp(3)	!r[3]=c1;
+	or	c_12,c_3,c_12
+
+	mulx	a_4,b_0,t_1	!mul_add_c(a[4],b[0],c2,c3,c1);
+	addcc	c_12,t_1,c_12	!=
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_3,b_1,t_1	!=!mul_add_c(a[3],b[1],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_2,b_2,t_1	!=!mul_add_c(a[2],b[2],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	lduw	bp(4),b_4	!=
+	mulx	a_1,b_3,t_1	!mul_add_c(a[1],b[3],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3	!=
+	lduw	bp(5),b_5
+	mulx	a_0,b_4,t_1	!mul_add_c(a[0],b[4],c2,c3,c1);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(4)	!r[4]=c2;
+	or	c_12,c_3,c_12	!=
+
+	mulx	a_0,b_5,t_1	!mul_add_c(a[0],b[5],c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_1,b_4,t_1	!mul_add_c(a[1],b[4],c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_2,b_3,t_1	!mul_add_c(a[2],b[3],c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_3,b_2,t_1	!mul_add_c(a[3],b[2],c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	lduw	ap(5),a_5
+	mulx	a_4,b_1,t_1	!mul_add_c(a[4],b[1],c3,c1,c2);
+	addcc	c_12,t_1,c_12	!=
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	lduw	ap(6),a_6
+	mulx	a_5,b_0,t_1	!=!mul_add_c(a[5],b[0],c3,c1,c2);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12	!=
+	stuw	t_1,rp(5)	!r[5]=c3;
+	or	c_12,c_3,c_12
+
+	mulx	a_6,b_0,t_1	!mul_add_c(a[6],b[0],c1,c2,c3);
+	addcc	c_12,t_1,c_12	!=
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_5,b_1,t_1	!=!mul_add_c(a[5],b[1],c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_4,b_2,t_1	!=!mul_add_c(a[4],b[2],c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_3,b_3,t_1	!=!mul_add_c(a[3],b[3],c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_2,b_4,t_1	!=!mul_add_c(a[2],b[4],c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	lduw	bp(6),b_6	!=
+	mulx	a_1,b_5,t_1	!mul_add_c(a[1],b[5],c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3	!=
+	lduw	bp(7),b_7
+	mulx	a_0,b_6,t_1	!mul_add_c(a[0],b[6],c1,c2,c3);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(6)	!r[6]=c1;
+	or	c_12,c_3,c_12	!=
+
+	mulx	a_0,b_7,t_1	!mul_add_c(a[0],b[7],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_1,b_6,t_1	!mul_add_c(a[1],b[6],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_2,b_5,t_1	!mul_add_c(a[2],b[5],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_3,b_4,t_1	!mul_add_c(a[3],b[4],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_4,b_3,t_1	!mul_add_c(a[4],b[3],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_5,b_2,t_1	!mul_add_c(a[5],b[2],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	lduw	ap(7),a_7
+	mulx	a_6,b_1,t_1	!=!mul_add_c(a[6],b[1],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_7,b_0,t_1	!=!mul_add_c(a[7],b[0],c2,c3,c1);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12	!=
+	stuw	t_1,rp(7)	!r[7]=c2;
+	or	c_12,c_3,c_12
+
+	mulx	a_7,b_1,t_1	!=!mul_add_c(a[7],b[1],c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3	!=
+	mulx	a_6,b_2,t_1	!mul_add_c(a[6],b[2],c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3	!=
+	mulx	a_5,b_3,t_1	!mul_add_c(a[5],b[3],c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3	!=
+	mulx	a_4,b_4,t_1	!mul_add_c(a[4],b[4],c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3	!=
+	mulx	a_3,b_5,t_1	!mul_add_c(a[3],b[5],c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3	!=
+	mulx	a_2,b_6,t_1	!mul_add_c(a[2],b[6],c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3	!=
+	mulx	a_1,b_7,t_1	!mul_add_c(a[1],b[7],c3,c1,c2);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3	!=
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(8)	!r[8]=c3;
+	or	c_12,c_3,c_12
+
+	mulx	a_2,b_7,t_1	!=!mul_add_c(a[2],b[7],c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3	!=
+	mulx	a_3,b_6,t_1	!mul_add_c(a[3],b[6],c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_4,b_5,t_1	!mul_add_c(a[4],b[5],c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_5,b_4,t_1	!mul_add_c(a[5],b[4],c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_6,b_3,t_1	!mul_add_c(a[6],b[3],c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_7,b_2,t_1	!mul_add_c(a[7],b[2],c1,c2,c3);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(9)	!r[9]=c1;
+	or	c_12,c_3,c_12	!=
+
+	mulx	a_7,b_3,t_1	!mul_add_c(a[7],b[3],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_6,b_4,t_1	!mul_add_c(a[6],b[4],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_5,b_5,t_1	!mul_add_c(a[5],b[5],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_4,b_6,t_1	!mul_add_c(a[4],b[6],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_3,b_7,t_1	!mul_add_c(a[3],b[7],c2,c3,c1);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(10)	!r[10]=c2;
+	or	c_12,c_3,c_12	!=
+
+	mulx	a_4,b_7,t_1	!mul_add_c(a[4],b[7],c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_5,b_6,t_1	!mul_add_c(a[5],b[6],c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_6,b_5,t_1	!mul_add_c(a[6],b[5],c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_7,b_4,t_1	!mul_add_c(a[7],b[4],c3,c1,c2);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(11)	!r[11]=c3;
+	or	c_12,c_3,c_12	!=
+
+	mulx	a_7,b_5,t_1	!mul_add_c(a[7],b[5],c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_6,b_6,t_1	!mul_add_c(a[6],b[6],c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_5,b_7,t_1	!mul_add_c(a[5],b[7],c1,c2,c3);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(12)	!r[12]=c1;
+	or	c_12,c_3,c_12	!=
+
+	mulx	a_6,b_7,t_1	!mul_add_c(a[6],b[7],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_7,b_6,t_1	!mul_add_c(a[7],b[6],c2,c3,c1);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	st	t_1,rp(13)	!r[13]=c2;
+	or	c_12,c_3,c_12	!=
+
+	mulx	a_7,b_7,t_1	!mul_add_c(a[7],b[7],c3,c1,c2);
+	addcc	c_12,t_1,t_1
+	srlx	t_1,32,c_12	!=
+	stuw	t_1,rp(14)	!r[14]=c3;
+	stuw	c_12,rp(15)	!r[15]=c1;
+
+	ret
+	restore	%g0,%g0,%o0	!=
+
+.type	bn_mul_comba8,#function
+.size	bn_mul_comba8,(.-bn_mul_comba8)
+
+.align	32
+
+.global bn_mul_comba4
+/*
+ * void bn_mul_comba4(r,a,b)
+ * BN_ULONG *r,*a,*b;
+ */
+bn_mul_comba4:
+	save	%sp,FRAME_SIZE,%sp
+	lduw	ap(0),a_0
+	mov	1,t_2
+	lduw	bp(0),b_0
+	sllx	t_2,32,t_2	!=
+	lduw	bp(1),b_1
+	mulx	a_0,b_0,t_1	!mul_add_c(a[0],b[0],c1,c2,c3);
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(0)	!=!r[0]=c1;
+
+	lduw	ap(1),a_1
+	mulx	a_0,b_1,t_1	!mul_add_c(a[0],b[1],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	clr	c_3		!=
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	lduw	ap(2),a_2
+	mulx	a_1,b_0,t_1	!=!mul_add_c(a[1],b[0],c2,c3,c1);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12	!=
+	stuw	t_1,rp(1)	!r[1]=c2;
+	or	c_12,c_3,c_12
+
+	mulx	a_2,b_0,t_1	!mul_add_c(a[2],b[0],c3,c1,c2);
+	addcc	c_12,t_1,c_12	!=
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	lduw	bp(2),b_2	!=
+	mulx	a_1,b_1,t_1	!mul_add_c(a[1],b[1],c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3	!=
+	lduw	bp(3),b_3
+	mulx	a_0,b_2,t_1	!mul_add_c(a[0],b[2],c3,c1,c2);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(2)	!r[2]=c3;
+	or	c_12,c_3,c_12	!=
+
+	mulx	a_0,b_3,t_1	!mul_add_c(a[0],b[3],c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	mulx	a_1,b_2,t_1	!mul_add_c(a[1],b[2],c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8	!=
+	add	c_3,t_2,c_3
+	lduw	ap(3),a_3
+	mulx	a_2,b_1,t_1	!mul_add_c(a[2],b[1],c1,c2,c3);
+	addcc	c_12,t_1,c_12	!=
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_3,b_0,t_1	!mul_add_c(a[3],b[0],c1,c2,c3);!=
+	addcc	c_12,t_1,t_1	!=
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(3)	!=!r[3]=c1;
+	or	c_12,c_3,c_12
+
+	mulx	a_3,b_1,t_1	!mul_add_c(a[3],b[1],c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	clr	c_3		!=
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_2,b_2,t_1	!mul_add_c(a[2],b[2],c2,c3,c1);
+	addcc	c_12,t_1,c_12	!=
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_1,b_3,t_1	!mul_add_c(a[1],b[3],c2,c3,c1);
+	addcc	c_12,t_1,t_1	!=
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(4)	!=!r[4]=c2;
+	or	c_12,c_3,c_12
+
+	mulx	a_2,b_3,t_1	!mul_add_c(a[2],b[3],c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	clr	c_3		!=
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_3,b_2,t_1	!mul_add_c(a[3],b[2],c3,c1,c2);
+	addcc	c_12,t_1,t_1	!=
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(5)	!=!r[5]=c3;
+	or	c_12,c_3,c_12
+
+	mulx	a_3,b_3,t_1	!mul_add_c(a[3],b[3],c1,c2,c3);
+	addcc	c_12,t_1,t_1
+	srlx	t_1,32,c_12	!=
+	stuw	t_1,rp(6)	!r[6]=c1;
+	stuw	c_12,rp(7)	!r[7]=c2;
+	
+	ret
+	restore	%g0,%g0,%o0
+
+.type	bn_mul_comba4,#function
+.size	bn_mul_comba4,(.-bn_mul_comba4)
+
+.align	32
+
+.global bn_sqr_comba8
+bn_sqr_comba8:
+	save	%sp,FRAME_SIZE,%sp
+	mov	1,t_2
+	lduw	ap(0),a_0
+	sllx	t_2,32,t_2
+	lduw	ap(1),a_1
+	mulx	a_0,a_0,t_1	!sqr_add_c(a,0,c1,c2,c3);
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(0)	!r[0]=c1;
+
+	lduw	ap(2),a_2
+	mulx	a_0,a_1,t_1	!=!sqr_add_c2(a,1,0,c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(1)	!r[1]=c2;
+	or	c_12,c_3,c_12
+
+	mulx	a_2,a_0,t_1	!sqr_add_c2(a,2,0,c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	lduw	ap(3),a_3
+	mulx	a_1,a_1,t_1	!sqr_add_c(a,1,c3,c1,c2);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(2)	!r[2]=c3;
+	or	c_12,c_3,c_12
+
+	mulx	a_0,a_3,t_1	!sqr_add_c2(a,3,0,c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	lduw	ap(4),a_4
+	mulx	a_1,a_2,t_1	!sqr_add_c2(a,2,1,c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	st	t_1,rp(3)	!r[3]=c1;
+	or	c_12,c_3,c_12
+
+	mulx	a_4,a_0,t_1	!sqr_add_c2(a,4,0,c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_3,a_1,t_1	!sqr_add_c2(a,3,1,c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	lduw	ap(5),a_5
+	mulx	a_2,a_2,t_1	!sqr_add_c(a,2,c2,c3,c1);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(4)	!r[4]=c2;
+	or	c_12,c_3,c_12
+
+	mulx	a_0,a_5,t_1	!sqr_add_c2(a,5,0,c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_1,a_4,t_1	!sqr_add_c2(a,4,1,c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	lduw	ap(6),a_6
+	mulx	a_2,a_3,t_1	!sqr_add_c2(a,3,2,c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(5)	!r[5]=c3;
+	or	c_12,c_3,c_12
+
+	mulx	a_6,a_0,t_1	!sqr_add_c2(a,6,0,c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_5,a_1,t_1	!sqr_add_c2(a,5,1,c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_4,a_2,t_1	!sqr_add_c2(a,4,2,c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	lduw	ap(7),a_7
+	mulx	a_3,a_3,t_1	!=!sqr_add_c(a,3,c1,c2,c3);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(6)	!r[6]=c1;
+	or	c_12,c_3,c_12
+
+	mulx	a_0,a_7,t_1	!sqr_add_c2(a,7,0,c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_1,a_6,t_1	!sqr_add_c2(a,6,1,c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_2,a_5,t_1	!sqr_add_c2(a,5,2,c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_3,a_4,t_1	!sqr_add_c2(a,4,3,c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(7)	!r[7]=c2;
+	or	c_12,c_3,c_12
+
+	mulx	a_7,a_1,t_1	!sqr_add_c2(a,7,1,c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_6,a_2,t_1	!sqr_add_c2(a,6,2,c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_5,a_3,t_1	!sqr_add_c2(a,5,3,c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_4,a_4,t_1	!sqr_add_c(a,4,c3,c1,c2);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(8)	!r[8]=c3;
+	or	c_12,c_3,c_12
+
+	mulx	a_2,a_7,t_1	!sqr_add_c2(a,7,2,c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_3,a_6,t_1	!sqr_add_c2(a,6,3,c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_4,a_5,t_1	!sqr_add_c2(a,5,4,c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(9)	!r[9]=c1;
+	or	c_12,c_3,c_12
+
+	mulx	a_7,a_3,t_1	!sqr_add_c2(a,7,3,c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_6,a_4,t_1	!sqr_add_c2(a,6,4,c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_5,a_5,t_1	!sqr_add_c(a,5,c2,c3,c1);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(10)	!r[10]=c2;
+	or	c_12,c_3,c_12
+
+	mulx	a_4,a_7,t_1	!sqr_add_c2(a,7,4,c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_5,a_6,t_1	!sqr_add_c2(a,6,5,c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(11)	!r[11]=c3;
+	or	c_12,c_3,c_12
+
+	mulx	a_7,a_5,t_1	!sqr_add_c2(a,7,5,c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_6,a_6,t_1	!sqr_add_c(a,6,c1,c2,c3);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(12)	!r[12]=c1;
+	or	c_12,c_3,c_12
+
+	mulx	a_6,a_7,t_1	!sqr_add_c2(a,7,6,c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(13)	!r[13]=c2;
+	or	c_12,c_3,c_12
+
+	mulx	a_7,a_7,t_1	!sqr_add_c(a,7,c3,c1,c2);
+	addcc	c_12,t_1,t_1
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(14)	!r[14]=c3;
+	stuw	c_12,rp(15)	!r[15]=c1;
+
+	ret
+	restore	%g0,%g0,%o0
+
+.type	bn_sqr_comba8,#function
+.size	bn_sqr_comba8,(.-bn_sqr_comba8)
+
+.align	32
+
+.global bn_sqr_comba4
+/*
+ * void bn_sqr_comba4(r,a)
+ * BN_ULONG *r,*a;
+ */
+bn_sqr_comba4:
+	save	%sp,FRAME_SIZE,%sp
+	mov	1,t_2
+	lduw	ap(0),a_0
+	sllx	t_2,32,t_2
+	lduw	ap(1),a_1
+	mulx	a_0,a_0,t_1	!sqr_add_c(a,0,c1,c2,c3);
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(0)	!r[0]=c1;
+
+	lduw	ap(2),a_2
+	mulx	a_0,a_1,t_1	!sqr_add_c2(a,1,0,c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(1)	!r[1]=c2;
+	or	c_12,c_3,c_12
+
+	mulx	a_2,a_0,t_1	!sqr_add_c2(a,2,0,c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	lduw	ap(3),a_3
+	mulx	a_1,a_1,t_1	!sqr_add_c(a,1,c3,c1,c2);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(2)	!r[2]=c3;
+	or	c_12,c_3,c_12
+
+	mulx	a_0,a_3,t_1	!sqr_add_c2(a,3,0,c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_1,a_2,t_1	!sqr_add_c2(a,2,1,c1,c2,c3);
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(3)	!r[3]=c1;
+	or	c_12,c_3,c_12
+
+	mulx	a_3,a_1,t_1	!sqr_add_c2(a,3,1,c2,c3,c1);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,c_12
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	mulx	a_2,a_2,t_1	!sqr_add_c(a,2,c2,c3,c1);
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(4)	!r[4]=c2;
+	or	c_12,c_3,c_12
+
+	mulx	a_2,a_3,t_1	!sqr_add_c2(a,3,2,c3,c1,c2);
+	addcc	c_12,t_1,c_12
+	clr	c_3
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	addcc	c_12,t_1,t_1
+	bcs,a	%xcc,.+8
+	add	c_3,t_2,c_3
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(5)	!r[5]=c3;
+	or	c_12,c_3,c_12
+
+	mulx	a_3,a_3,t_1	!sqr_add_c(a,3,c1,c2,c3);
+	addcc	c_12,t_1,t_1
+	srlx	t_1,32,c_12
+	stuw	t_1,rp(6)	!r[6]=c1;
+	stuw	c_12,rp(7)	!r[7]=c2;
+	
+	ret
+	restore	%g0,%g0,%o0
+
+.type	bn_sqr_comba4,#function
+.size	bn_sqr_comba4,(.-bn_sqr_comba4)
+
+.align	32
diff --git a/openssl/crypto/bn/asm/sparcv9-mont.pl b/openssl/crypto/bn/asm/sparcv9-mont.pl
new file mode 100644
index 0000000..b8fb1e8
--- /dev/null
+++ b/openssl/crypto/bn/asm/sparcv9-mont.pl
@@ -0,0 +1,606 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# December 2005
+#
+# Pure SPARCv9/8+ and IALU-only bn_mul_mont implementation. The reasons
+# for undertaken effort are multiple. First of all, UltraSPARC is not
+# the whole SPARCv9 universe and other VIS-free implementations deserve
+# optimized code as much. Secondly, newly introduced UltraSPARC T1,
+# a.k.a. Niagara, has shared FPU and concurrent FPU-intensive pathes,
+# such as sparcv9a-mont, will simply sink it. Yes, T1 is equipped with
+# several integrated RSA/DSA accelerator circuits accessible through
+# kernel driver [only(*)], but having decent user-land software
+# implementation is important too. Finally, reasons like desire to
+# experiment with dedicated squaring procedure. Yes, this module
+# implements one, because it was easiest to draft it in SPARCv9
+# instructions...
+
+# (*)	Engine accessing the driver in question is on my TODO list.
+#	For reference, acceleator is estimated to give 6 to 10 times
+#	improvement on single-threaded RSA sign. It should be noted
+#	that 6-10x improvement coefficient does not actually mean
+#	something extraordinary in terms of absolute [single-threaded]
+#	performance, as SPARCv9 instruction set is by all means least
+#	suitable for high performance crypto among other 64 bit
+#	platforms. 6-10x factor simply places T1 in same performance
+#	domain as say AMD64 and IA-64. Improvement of RSA verify don't
+#	appear impressive at all, but it's the sign operation which is
+#	far more critical/interesting.
+
+# You might notice that inner loops are modulo-scheduled:-) This has
+# essentially negligible impact on UltraSPARC performance, it's
+# Fujitsu SPARC64 V users who should notice and hopefully appreciate
+# the advantage... Currently this module surpasses sparcv9a-mont.pl
+# by ~20% on UltraSPARC-III and later cores, but recall that sparcv9a
+# module still have hidden potential [see TODO list there], which is
+# estimated to be larger than 20%...
+
+# int bn_mul_mont(
+$rp="%i0";	# BN_ULONG *rp,
+$ap="%i1";	# const BN_ULONG *ap,
+$bp="%i2";	# const BN_ULONG *bp,
+$np="%i3";	# const BN_ULONG *np,
+$n0="%i4";	# const BN_ULONG *n0,
+$num="%i5";	# int num);
+
+$bits=32;
+for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
+if ($bits==64)	{ $bias=2047; $frame=192; }
+else		{ $bias=0;    $frame=128; }
+
+$car0="%o0";
+$car1="%o1";
+$car2="%o2";	# 1 bit
+$acc0="%o3";
+$acc1="%o4";
+$mask="%g1";	# 32 bits, what a waste...
+$tmp0="%g4";
+$tmp1="%g5";
+
+$i="%l0";
+$j="%l1";
+$mul0="%l2";
+$mul1="%l3";
+$tp="%l4";
+$apj="%l5";
+$npj="%l6";
+$tpj="%l7";
+
+$fname="bn_mul_mont_int";
+
+$code=<<___;
+.section	".text",#alloc,#execinstr
+
+.global	$fname
+.align	32
+$fname:
+	cmp	%o5,4			! 128 bits minimum
+	bge,pt	%icc,.Lenter
+	sethi	%hi(0xffffffff),$mask
+	retl
+	clr	%o0
+.align	32
+.Lenter:
+	save	%sp,-$frame,%sp
+	sll	$num,2,$num		! num*=4
+	or	$mask,%lo(0xffffffff),$mask
+	ld	[$n0],$n0
+	cmp	$ap,$bp
+	and	$num,$mask,$num
+	ld	[$bp],$mul0		! bp[0]
+	nop
+
+	add	%sp,$bias,%o7		! real top of stack
+	ld	[$ap],$car0		! ap[0] ! redundant in squaring context
+	sub	%o7,$num,%o7
+	ld	[$ap+4],$apj		! ap[1]
+	and	%o7,-1024,%o7
+	ld	[$np],$car1		! np[0]
+	sub	%o7,$bias,%sp		! alloca
+	ld	[$np+4],$npj		! np[1]
+	be,pt	`$bits==32?"%icc":"%xcc"`,.Lbn_sqr_mont
+	mov	12,$j
+
+	mulx	$car0,$mul0,$car0	! ap[0]*bp[0]
+	mulx	$apj,$mul0,$tmp0	!prologue! ap[1]*bp[0]
+	and	$car0,$mask,$acc0
+	add	%sp,$bias+$frame,$tp
+	ld	[$ap+8],$apj		!prologue!
+
+	mulx	$n0,$acc0,$mul1		! "t[0]"*n0
+	and	$mul1,$mask,$mul1
+
+	mulx	$car1,$mul1,$car1	! np[0]*"t[0]"*n0
+	mulx	$npj,$mul1,$acc1	!prologue! np[1]*"t[0]"*n0
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	ld	[$np+8],$npj		!prologue!
+	srlx	$car1,32,$car1
+	mov	$tmp0,$acc0		!prologue!
+
+.L1st:
+	mulx	$apj,$mul0,$tmp0
+	mulx	$npj,$mul1,$tmp1
+	add	$acc0,$car0,$car0
+	ld	[$ap+$j],$apj		! ap[j]
+	and	$car0,$mask,$acc0
+	add	$acc1,$car1,$car1
+	ld	[$np+$j],$npj		! np[j]
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	add	$j,4,$j			! j++
+	mov	$tmp0,$acc0
+	st	$car1,[$tp]
+	cmp	$j,$num
+	mov	$tmp1,$acc1
+	srlx	$car1,32,$car1
+	bl	%icc,.L1st
+	add	$tp,4,$tp		! tp++
+!.L1st
+
+	mulx	$apj,$mul0,$tmp0	!epilogue!
+	mulx	$npj,$mul1,$tmp1
+	add	$acc0,$car0,$car0
+	and	$car0,$mask,$acc0
+	add	$acc1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+
+	add	$tmp0,$car0,$car0
+	and	$car0,$mask,$acc0
+	add	$tmp1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp+4]
+	srlx	$car1,32,$car1
+
+	add	$car0,$car1,$car1
+	st	$car1,[$tp+8]
+	srlx	$car1,32,$car2
+
+	mov	4,$i			! i++
+	ld	[$bp+4],$mul0		! bp[1]
+.Louter:
+	add	%sp,$bias+$frame,$tp
+	ld	[$ap],$car0		! ap[0]
+	ld	[$ap+4],$apj		! ap[1]
+	ld	[$np],$car1		! np[0]
+	ld	[$np+4],$npj		! np[1]
+	ld	[$tp],$tmp1		! tp[0]
+	ld	[$tp+4],$tpj		! tp[1]
+	mov	12,$j
+
+	mulx	$car0,$mul0,$car0
+	mulx	$apj,$mul0,$tmp0	!prologue!
+	add	$tmp1,$car0,$car0
+	ld	[$ap+8],$apj		!prologue!
+	and	$car0,$mask,$acc0
+
+	mulx	$n0,$acc0,$mul1
+	and	$mul1,$mask,$mul1
+
+	mulx	$car1,$mul1,$car1
+	mulx	$npj,$mul1,$acc1	!prologue!
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	ld	[$np+8],$npj		!prologue!
+	srlx	$car1,32,$car1
+	mov	$tmp0,$acc0		!prologue!
+
+.Linner:
+	mulx	$apj,$mul0,$tmp0
+	mulx	$npj,$mul1,$tmp1
+	add	$tpj,$car0,$car0
+	ld	[$ap+$j],$apj		! ap[j]
+	add	$acc0,$car0,$car0
+	add	$acc1,$car1,$car1
+	ld	[$np+$j],$npj		! np[j]
+	and	$car0,$mask,$acc0
+	ld	[$tp+8],$tpj		! tp[j]
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	add	$j,4,$j			! j++
+	mov	$tmp0,$acc0
+	st	$car1,[$tp]		! tp[j-1]
+	srlx	$car1,32,$car1
+	mov	$tmp1,$acc1
+	cmp	$j,$num
+	bl	%icc,.Linner
+	add	$tp,4,$tp		! tp++
+!.Linner
+
+	mulx	$apj,$mul0,$tmp0	!epilogue!
+	mulx	$npj,$mul1,$tmp1
+	add	$tpj,$car0,$car0
+	add	$acc0,$car0,$car0
+	ld	[$tp+8],$tpj		! tp[j]
+	and	$car0,$mask,$acc0
+	add	$acc1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]		! tp[j-1]
+	srlx	$car1,32,$car1
+
+	add	$tpj,$car0,$car0
+	add	$tmp0,$car0,$car0
+	and	$car0,$mask,$acc0
+	add	$tmp1,$car1,$car1
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp+4]		! tp[j-1]
+	srlx	$car0,32,$car0
+	add	$i,4,$i			! i++
+	srlx	$car1,32,$car1
+
+	add	$car0,$car1,$car1
+	cmp	$i,$num
+	add	$car2,$car1,$car1
+	st	$car1,[$tp+8]
+
+	srlx	$car1,32,$car2
+	bl,a	%icc,.Louter
+	ld	[$bp+$i],$mul0		! bp[i]
+!.Louter
+
+	add	$tp,12,$tp
+
+.Ltail:
+	add	$np,$num,$np
+	add	$rp,$num,$rp
+	mov	$tp,$ap
+	sub	%g0,$num,%o7		! k=-num
+	ba	.Lsub
+	subcc	%g0,%g0,%g0		! clear %icc.c
+.align	16
+.Lsub:
+	ld	[$tp+%o7],%o0
+	ld	[$np+%o7],%o1
+	subccc	%o0,%o1,%o1		! tp[j]-np[j]
+	add	$rp,%o7,$i
+	add	%o7,4,%o7
+	brnz	%o7,.Lsub
+	st	%o1,[$i]
+	subc	$car2,0,$car2		! handle upmost overflow bit
+	and	$tp,$car2,$ap
+	andn	$rp,$car2,$np
+	or	$ap,$np,$ap
+	sub	%g0,$num,%o7
+
+.Lcopy:
+	ld	[$ap+%o7],%o0		! copy or in-place refresh
+	st	%g0,[$tp+%o7]		! zap tp
+	st	%o0,[$rp+%o7]
+	add	%o7,4,%o7
+	brnz	%o7,.Lcopy
+	nop
+	mov	1,%i0
+	ret
+	restore
+___
+
+########
+######## .Lbn_sqr_mont gives up to 20% *overall* improvement over
+######## code without following dedicated squaring procedure.
+########
+$sbit="%i2";		# re-use $bp!
+
+$code.=<<___;
+.align	32
+.Lbn_sqr_mont:
+	mulx	$mul0,$mul0,$car0		! ap[0]*ap[0]
+	mulx	$apj,$mul0,$tmp0		!prologue!
+	and	$car0,$mask,$acc0
+	add	%sp,$bias+$frame,$tp
+	ld	[$ap+8],$apj			!prologue!
+
+	mulx	$n0,$acc0,$mul1			! "t[0]"*n0
+	srlx	$car0,32,$car0
+	and	$mul1,$mask,$mul1
+
+	mulx	$car1,$mul1,$car1		! np[0]*"t[0]"*n0
+	mulx	$npj,$mul1,$acc1		!prologue!
+	and	$car0,1,$sbit
+	ld	[$np+8],$npj			!prologue!
+	srlx	$car0,1,$car0
+	add	$acc0,$car1,$car1
+	srlx	$car1,32,$car1
+	mov	$tmp0,$acc0			!prologue!
+
+.Lsqr_1st:
+	mulx	$apj,$mul0,$tmp0
+	mulx	$npj,$mul1,$tmp1
+	add	$acc0,$car0,$car0		! ap[j]*a0+c0
+	add	$acc1,$car1,$car1
+	ld	[$ap+$j],$apj			! ap[j]
+	and	$car0,$mask,$acc0
+	ld	[$np+$j],$npj			! np[j]
+	srlx	$car0,32,$car0
+	add	$acc0,$acc0,$acc0
+	or	$sbit,$acc0,$acc0
+	mov	$tmp1,$acc1
+	srlx	$acc0,32,$sbit
+	add	$j,4,$j				! j++
+	and	$acc0,$mask,$acc0
+	cmp	$j,$num
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]
+	mov	$tmp0,$acc0
+	srlx	$car1,32,$car1
+	bl	%icc,.Lsqr_1st
+	add	$tp,4,$tp			! tp++
+!.Lsqr_1st
+
+	mulx	$apj,$mul0,$tmp0		! epilogue
+	mulx	$npj,$mul1,$tmp1
+	add	$acc0,$car0,$car0		! ap[j]*a0+c0
+	add	$acc1,$car1,$car1
+	and	$car0,$mask,$acc0
+	srlx	$car0,32,$car0
+	add	$acc0,$acc0,$acc0
+	or	$sbit,$acc0,$acc0
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+
+	add	$tmp0,$car0,$car0		! ap[j]*a0+c0
+	add	$tmp1,$car1,$car1
+	and	$car0,$mask,$acc0
+	srlx	$car0,32,$car0
+	add	$acc0,$acc0,$acc0
+	or	$sbit,$acc0,$acc0
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp+4]
+	srlx	$car1,32,$car1
+
+	add	$car0,$car0,$car0
+	or	$sbit,$car0,$car0
+	add	$car0,$car1,$car1
+	st	$car1,[$tp+8]
+	srlx	$car1,32,$car2
+
+	ld	[%sp+$bias+$frame],$tmp0	! tp[0]
+	ld	[%sp+$bias+$frame+4],$tmp1	! tp[1]
+	ld	[%sp+$bias+$frame+8],$tpj	! tp[2]
+	ld	[$ap+4],$mul0			! ap[1]
+	ld	[$ap+8],$apj			! ap[2]
+	ld	[$np],$car1			! np[0]
+	ld	[$np+4],$npj			! np[1]
+	mulx	$n0,$tmp0,$mul1
+
+	mulx	$mul0,$mul0,$car0
+	and	$mul1,$mask,$mul1
+
+	mulx	$car1,$mul1,$car1
+	mulx	$npj,$mul1,$acc1
+	add	$tmp0,$car1,$car1
+	and	$car0,$mask,$acc0
+	ld	[$np+8],$npj			! np[2]
+	srlx	$car1,32,$car1
+	add	$tmp1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	and	$car0,1,$sbit
+	add	$acc1,$car1,$car1
+	srlx	$car0,1,$car0
+	mov	12,$j
+	st	$car1,[%sp+$bias+$frame]	! tp[0]=
+	srlx	$car1,32,$car1
+	add	%sp,$bias+$frame+4,$tp
+
+.Lsqr_2nd:
+	mulx	$apj,$mul0,$acc0
+	mulx	$npj,$mul1,$acc1
+	add	$acc0,$car0,$car0
+	add	$tpj,$car1,$car1
+	ld	[$ap+$j],$apj			! ap[j]
+	and	$car0,$mask,$acc0
+	ld	[$np+$j],$npj			! np[j]
+	srlx	$car0,32,$car0
+	add	$acc1,$car1,$car1
+	ld	[$tp+8],$tpj			! tp[j]
+	add	$acc0,$acc0,$acc0
+	add	$j,4,$j				! j++
+	or	$sbit,$acc0,$acc0
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	cmp	$j,$num
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]			! tp[j-1]
+	srlx	$car1,32,$car1
+	bl	%icc,.Lsqr_2nd
+	add	$tp,4,$tp			! tp++
+!.Lsqr_2nd
+
+	mulx	$apj,$mul0,$acc0
+	mulx	$npj,$mul1,$acc1
+	add	$acc0,$car0,$car0
+	add	$tpj,$car1,$car1
+	and	$car0,$mask,$acc0
+	srlx	$car0,32,$car0
+	add	$acc1,$car1,$car1
+	add	$acc0,$acc0,$acc0
+	or	$sbit,$acc0,$acc0
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]			! tp[j-1]
+	srlx	$car1,32,$car1
+
+	add	$car0,$car0,$car0
+	or	$sbit,$car0,$car0
+	add	$car0,$car1,$car1
+	add	$car2,$car1,$car1
+	st	$car1,[$tp+4]
+	srlx	$car1,32,$car2
+
+	ld	[%sp+$bias+$frame],$tmp1	! tp[0]
+	ld	[%sp+$bias+$frame+4],$tpj	! tp[1]
+	ld	[$ap+8],$mul0			! ap[2]
+	ld	[$np],$car1			! np[0]
+	ld	[$np+4],$npj			! np[1]
+	mulx	$n0,$tmp1,$mul1
+	and	$mul1,$mask,$mul1
+	mov	8,$i
+
+	mulx	$mul0,$mul0,$car0
+	mulx	$car1,$mul1,$car1
+	and	$car0,$mask,$acc0
+	add	$tmp1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	%sp,$bias+$frame,$tp
+	srlx	$car1,32,$car1
+	and	$car0,1,$sbit
+	srlx	$car0,1,$car0
+	mov	4,$j
+
+.Lsqr_outer:
+.Lsqr_inner1:
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	add	$j,4,$j
+	ld	[$tp+8],$tpj
+	cmp	$j,$i
+	add	$acc1,$car1,$car1
+	ld	[$np+$j],$npj
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+	bl	%icc,.Lsqr_inner1
+	add	$tp,4,$tp
+!.Lsqr_inner1
+
+	add	$j,4,$j
+	ld	[$ap+$j],$apj			! ap[j]
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	ld	[$np+$j],$npj			! np[j]
+	add	$acc0,$car1,$car1
+	ld	[$tp+8],$tpj			! tp[j]
+	add	$acc1,$car1,$car1
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+
+	add	$j,4,$j
+	cmp	$j,$num
+	be,pn	%icc,.Lsqr_no_inner2
+	add	$tp,4,$tp
+
+.Lsqr_inner2:
+	mulx	$apj,$mul0,$acc0
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	add	$acc0,$car0,$car0
+	ld	[$ap+$j],$apj			! ap[j]
+	and	$car0,$mask,$acc0
+	ld	[$np+$j],$npj			! np[j]
+	srlx	$car0,32,$car0
+	add	$acc0,$acc0,$acc0
+	ld	[$tp+8],$tpj			! tp[j]
+	or	$sbit,$acc0,$acc0
+	add	$j,4,$j				! j++
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	cmp	$j,$num
+	add	$acc0,$car1,$car1
+	add	$acc1,$car1,$car1
+	st	$car1,[$tp]			! tp[j-1]
+	srlx	$car1,32,$car1
+	bl	%icc,.Lsqr_inner2
+	add	$tp,4,$tp			! tp++
+
+.Lsqr_no_inner2:
+	mulx	$apj,$mul0,$acc0
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	add	$acc0,$car0,$car0
+	and	$car0,$mask,$acc0
+	srlx	$car0,32,$car0
+	add	$acc0,$acc0,$acc0
+	or	$sbit,$acc0,$acc0
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	add	$acc0,$car1,$car1
+	add	$acc1,$car1,$car1
+	st	$car1,[$tp]			! tp[j-1]
+	srlx	$car1,32,$car1
+
+	add	$car0,$car0,$car0
+	or	$sbit,$car0,$car0
+	add	$car0,$car1,$car1
+	add	$car2,$car1,$car1
+	st	$car1,[$tp+4]
+	srlx	$car1,32,$car2
+
+	add	$i,4,$i				! i++
+	ld	[%sp+$bias+$frame],$tmp1	! tp[0]
+	ld	[%sp+$bias+$frame+4],$tpj	! tp[1]
+	ld	[$ap+$i],$mul0			! ap[j]
+	ld	[$np],$car1			! np[0]
+	ld	[$np+4],$npj			! np[1]
+	mulx	$n0,$tmp1,$mul1
+	and	$mul1,$mask,$mul1
+	add	$i,4,$tmp0
+
+	mulx	$mul0,$mul0,$car0
+	mulx	$car1,$mul1,$car1
+	and	$car0,$mask,$acc0
+	add	$tmp1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	%sp,$bias+$frame,$tp
+	srlx	$car1,32,$car1
+	and	$car0,1,$sbit
+	srlx	$car0,1,$car0
+
+	cmp	$tmp0,$num			! i<num-1
+	bl	%icc,.Lsqr_outer
+	mov	4,$j
+
+.Lsqr_last:
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	add	$j,4,$j
+	ld	[$tp+8],$tpj
+	cmp	$j,$i
+	add	$acc1,$car1,$car1
+	ld	[$np+$j],$npj
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+	bl	%icc,.Lsqr_last
+	add	$tp,4,$tp
+!.Lsqr_last
+
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	add	$acc0,$car1,$car1
+	add	$acc1,$car1,$car1
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+
+	add	$car0,$car0,$car0		! recover $car0
+	or	$sbit,$car0,$car0
+	add	$car0,$car1,$car1
+	add	$car2,$car1,$car1
+	st	$car1,[$tp+4]
+	srlx	$car1,32,$car2
+
+	ba	.Ltail
+	add	$tp,8,$tp
+.type	$fname,#function
+.size	$fname,(.-$fname)
+.asciz	"Montgomery Multipltication for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
+.align	32
+___
+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/bn/asm/sparcv9a-mont.pl b/openssl/crypto/bn/asm/sparcv9a-mont.pl
new file mode 100644
index 0000000..a14205f
--- /dev/null
+++ b/openssl/crypto/bn/asm/sparcv9a-mont.pl
@@ -0,0 +1,882 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# October 2005
+#
+# "Teaser" Montgomery multiplication module for UltraSPARC. Why FPU?
+# Because unlike integer multiplier, which simply stalls whole CPU,
+# FPU is fully pipelined and can effectively emit 48 bit partial
+# product every cycle. Why not blended SPARC v9? One can argue that
+# making this module dependent on UltraSPARC VIS extension limits its
+# binary compatibility. Well yes, it does exclude SPARC64 prior-V(!)
+# implementations from compatibility matrix. But the rest, whole Sun
+# UltraSPARC family and brand new Fujitsu's SPARC64 V, all support
+# VIS extension instructions used in this module. This is considered
+# good enough to not care about HAL SPARC64 users [if any] who have
+# integer-only pure SPARCv9 module to "fall down" to.
+
+# USI&II cores currently exhibit uniform 2x improvement [over pre-
+# bn_mul_mont codebase] for all key lengths and benchmarks. On USIII
+# performance improves few percents for shorter keys and worsens few
+# percents for longer keys. This is because USIII integer multiplier
+# is >3x faster than USI&II one, which is harder to match [but see
+# TODO list below]. It should also be noted that SPARC64 V features
+# out-of-order execution, which *might* mean that integer multiplier
+# is pipelined, which in turn *might* be impossible to match... On
+# additional note, SPARC64 V implements FP Multiply-Add instruction,
+# which is perfectly usable in this context... In other words, as far
+# as Fujitsu SPARC64 V goes, talk to the author:-)
+
+# The implementation implies following "non-natural" limitations on
+# input arguments:
+# - num may not be less than 4;
+# - num has to be even;
+# Failure to meet either condition has no fatal effects, simply
+# doesn't give any performance gain.
+
+# TODO:
+# - modulo-schedule inner loop for better performance (on in-order
+#   execution core such as UltraSPARC this shall result in further
+#   noticeable(!) improvement);
+# - dedicated squaring procedure[?];
+
+######################################################################
+# November 2006
+#
+# Modulo-scheduled inner loops allow to interleave floating point and
+# integer instructions and minimize Read-After-Write penalties. This
+# results in *further* 20-50% perfromance improvement [depending on
+# key length, more for longer keys] on USI&II cores and 30-80% - on
+# USIII&IV.
+
+$fname="bn_mul_mont_fpu";
+$bits=32;
+for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
+
+if ($bits==64) {
+	$bias=2047;
+	$frame=192;
+} else {
+	$bias=0;
+	$frame=128;	# 96 rounded up to largest known cache-line
+}
+$locals=64;
+
+# In order to provide for 32-/64-bit ABI duality, I keep integers wider
+# than 32 bit in %g1-%g4 and %o0-%o5. %l0-%l7 and %i0-%i5 are used
+# exclusively for pointers, indexes and other small values...
+# int bn_mul_mont(
+$rp="%i0";	# BN_ULONG *rp,
+$ap="%i1";	# const BN_ULONG *ap,
+$bp="%i2";	# const BN_ULONG *bp,
+$np="%i3";	# const BN_ULONG *np,
+$n0="%i4";	# const BN_ULONG *n0,
+$num="%i5";	# int num);
+
+$tp="%l0";	# t[num]
+$ap_l="%l1";	# a[num],n[num] are smashed to 32-bit words and saved
+$ap_h="%l2";	# to these four vectors as double-precision FP values.
+$np_l="%l3";	# This way a bunch of fxtods are eliminated in second
+$np_h="%l4";	# loop and L1-cache aliasing is minimized...
+$i="%l5";
+$j="%l6";
+$mask="%l7";	# 16-bit mask, 0xffff
+
+$n0="%g4";	# reassigned(!) to "64-bit" register
+$carry="%i4";	# %i4 reused(!) for a carry bit
+
+# FP register naming chart
+#
+#     ..HILO
+#       dcba
+#   --------
+#        LOa
+#       LOb
+#      LOc
+#     LOd
+#      HIa
+#     HIb
+#    HIc
+#   HId
+#    ..a
+#   ..b
+$ba="%f0";    $bb="%f2";    $bc="%f4";    $bd="%f6";
+$na="%f8";    $nb="%f10";   $nc="%f12";   $nd="%f14";
+$alo="%f16";  $alo_="%f17"; $ahi="%f18";  $ahi_="%f19";
+$nlo="%f20";  $nlo_="%f21"; $nhi="%f22";  $nhi_="%f23";
+
+$dota="%f24"; $dotb="%f26";
+
+$aloa="%f32"; $alob="%f34"; $aloc="%f36"; $alod="%f38";
+$ahia="%f40"; $ahib="%f42"; $ahic="%f44"; $ahid="%f46";
+$nloa="%f48"; $nlob="%f50"; $nloc="%f52"; $nlod="%f54";
+$nhia="%f56"; $nhib="%f58"; $nhic="%f60"; $nhid="%f62";
+
+$ASI_FL16_P=0xD2;	# magic ASI value to engage 16-bit FP load
+
+$code=<<___;
+.section	".text",#alloc,#execinstr
+
+.global $fname
+.align  32
+$fname:
+	save	%sp,-$frame-$locals,%sp
+
+	cmp	$num,4
+	bl,a,pn %icc,.Lret
+	clr	%i0
+	andcc	$num,1,%g0		! $num has to be even...
+	bnz,a,pn %icc,.Lret
+	clr	%i0			! signal "unsupported input value"
+
+	srl	$num,1,$num
+	sethi	%hi(0xffff),$mask
+	ld	[%i4+0],$n0		! $n0 reassigned, remember?
+	or	$mask,%lo(0xffff),$mask
+	ld	[%i4+4],%o0
+	sllx	%o0,32,%o0
+	or	%o0,$n0,$n0		! $n0=n0[1].n0[0]
+
+	sll	$num,3,$num		! num*=8
+
+	add	%sp,$bias,%o0		! real top of stack
+	sll	$num,2,%o1
+	add	%o1,$num,%o1		! %o1=num*5
+	sub	%o0,%o1,%o0
+	and	%o0,-2048,%o0		! optimize TLB utilization
+	sub	%o0,$bias,%sp		! alloca(5*num*8)
+
+	rd	%asi,%o7		! save %asi
+	add	%sp,$bias+$frame+$locals,$tp
+	add	$tp,$num,$ap_l
+	add	$ap_l,$num,$ap_l	! [an]p_[lh] point at the vectors' ends !
+	add	$ap_l,$num,$ap_h
+	add	$ap_h,$num,$np_l
+	add	$np_l,$num,$np_h
+
+	wr	%g0,$ASI_FL16_P,%asi	! setup %asi for 16-bit FP loads
+
+	add	$rp,$num,$rp		! readjust input pointers to point
+	add	$ap,$num,$ap		! at the ends too...
+	add	$bp,$num,$bp
+	add	$np,$num,$np
+
+	stx	%o7,[%sp+$bias+$frame+48]	! save %asi
+
+	sub	%g0,$num,$i		! i=-num
+	sub	%g0,$num,$j		! j=-num
+
+	add	$ap,$j,%o3
+	add	$bp,$i,%o4
+
+	ld	[%o3+4],%g1		! bp[0]
+	ld	[%o3+0],%o0
+	ld	[%o4+4],%g5		! ap[0]
+	sllx	%g1,32,%g1
+	ld	[%o4+0],%o1
+	sllx	%g5,32,%g5
+	or	%g1,%o0,%o0
+	or	%g5,%o1,%o1
+
+	add	$np,$j,%o5
+
+	mulx	%o1,%o0,%o0		! ap[0]*bp[0]
+	mulx	$n0,%o0,%o0		! ap[0]*bp[0]*n0
+	stx	%o0,[%sp+$bias+$frame+0]
+
+	ld	[%o3+0],$alo_	! load a[j] as pair of 32-bit words
+	fzeros	$alo
+	ld	[%o3+4],$ahi_
+	fzeros	$ahi
+	ld	[%o5+0],$nlo_	! load n[j] as pair of 32-bit words
+	fzeros	$nlo
+	ld	[%o5+4],$nhi_
+	fzeros	$nhi
+
+	! transfer b[i] to FPU as 4x16-bit values
+	ldda	[%o4+2]%asi,$ba
+	fxtod	$alo,$alo
+	ldda	[%o4+0]%asi,$bb
+	fxtod	$ahi,$ahi
+	ldda	[%o4+6]%asi,$bc
+	fxtod	$nlo,$nlo
+	ldda	[%o4+4]%asi,$bd
+	fxtod	$nhi,$nhi
+
+	! transfer ap[0]*b[0]*n0 to FPU as 4x16-bit values
+	ldda	[%sp+$bias+$frame+6]%asi,$na
+	fxtod	$ba,$ba
+	ldda	[%sp+$bias+$frame+4]%asi,$nb
+	fxtod	$bb,$bb
+	ldda	[%sp+$bias+$frame+2]%asi,$nc
+	fxtod	$bc,$bc
+	ldda	[%sp+$bias+$frame+0]%asi,$nd
+	fxtod	$bd,$bd
+
+	std	$alo,[$ap_l+$j]		! save smashed ap[j] in double format
+	fxtod	$na,$na
+	std	$ahi,[$ap_h+$j]
+	fxtod	$nb,$nb
+	std	$nlo,[$np_l+$j]		! save smashed np[j] in double format
+	fxtod	$nc,$nc
+	std	$nhi,[$np_h+$j]
+	fxtod	$nd,$nd
+
+		fmuld	$alo,$ba,$aloa
+		fmuld	$nlo,$na,$nloa
+		fmuld	$alo,$bb,$alob
+		fmuld	$nlo,$nb,$nlob
+		fmuld	$alo,$bc,$aloc
+	faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+		fmuld	$alo,$bd,$alod
+	faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+		fmuld	$ahi,$ba,$ahia
+	faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+		fmuld	$ahi,$bb,$ahib
+	faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+		fmuld	$ahi,$bc,$ahic
+	faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+		fmuld	$ahi,$bd,$ahid
+	faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+
+	faddd	$ahic,$nhic,$dota	! $nhic
+	faddd	$ahid,$nhid,$dotb	! $nhid
+
+	faddd	$nloc,$nhia,$nloc
+	faddd	$nlod,$nhib,$nlod
+
+	fdtox	$nloa,$nloa
+	fdtox	$nlob,$nlob
+	fdtox	$nloc,$nloc
+	fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	add	$j,8,$j
+	std	$nlob,[%sp+$bias+$frame+8]
+	add	$ap,$j,%o4
+	std	$nloc,[%sp+$bias+$frame+16]
+	add	$np,$j,%o5
+	std	$nlod,[%sp+$bias+$frame+24]
+
+	ld	[%o4+0],$alo_	! load a[j] as pair of 32-bit words
+	fzeros	$alo
+	ld	[%o4+4],$ahi_
+	fzeros	$ahi
+	ld	[%o5+0],$nlo_	! load n[j] as pair of 32-bit words
+	fzeros	$nlo
+	ld	[%o5+4],$nhi_
+	fzeros	$nhi
+
+	fxtod	$alo,$alo
+	fxtod	$ahi,$ahi
+	fxtod	$nlo,$nlo
+	fxtod	$nhi,$nhi
+
+	ldx	[%sp+$bias+$frame+0],%o0
+		fmuld	$alo,$ba,$aloa
+	ldx	[%sp+$bias+$frame+8],%o1
+		fmuld	$nlo,$na,$nloa
+	ldx	[%sp+$bias+$frame+16],%o2
+		fmuld	$alo,$bb,$alob
+	ldx	[%sp+$bias+$frame+24],%o3
+		fmuld	$nlo,$nb,$nlob
+
+	srlx	%o0,16,%o7
+	std	$alo,[$ap_l+$j]		! save smashed ap[j] in double format
+		fmuld	$alo,$bc,$aloc
+	add	%o7,%o1,%o1
+	std	$ahi,[$ap_h+$j]
+		faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+	srlx	%o1,16,%o7
+	std	$nlo,[$np_l+$j]		! save smashed np[j] in double format
+		fmuld	$alo,$bd,$alod
+	add	%o7,%o2,%o2
+	std	$nhi,[$np_h+$j]
+		faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+	srlx	%o2,16,%o7
+		fmuld	$ahi,$ba,$ahia
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+		faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+	!and	%o0,$mask,%o0
+	!and	%o1,$mask,%o1
+	!and	%o2,$mask,%o2
+	!sllx	%o1,16,%o1
+	!sllx	%o2,32,%o2
+	!sllx	%o3,48,%o7
+	!or	%o1,%o0,%o0
+	!or	%o2,%o0,%o0
+	!or	%o7,%o0,%o0		! 64-bit result
+	srlx	%o3,16,%g1		! 34-bit carry
+		fmuld	$ahi,$bb,$ahib
+
+	faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+		fmuld	$ahi,$bc,$ahic
+	faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+		fmuld	$ahi,$bd,$ahid
+	faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+
+	faddd	$dota,$nloa,$nloa
+	faddd	$dotb,$nlob,$nlob
+	faddd	$ahic,$nhic,$dota	! $nhic
+	faddd	$ahid,$nhid,$dotb	! $nhid
+
+	faddd	$nloc,$nhia,$nloc
+	faddd	$nlod,$nhib,$nlod
+
+	fdtox	$nloa,$nloa
+	fdtox	$nlob,$nlob
+	fdtox	$nloc,$nloc
+	fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	std	$nlob,[%sp+$bias+$frame+8]
+	addcc	$j,8,$j
+	std	$nloc,[%sp+$bias+$frame+16]
+	bz,pn	%icc,.L1stskip
+	std	$nlod,[%sp+$bias+$frame+24]
+
+.align	32			! incidentally already aligned !
+.L1st:
+	add	$ap,$j,%o4
+	add	$np,$j,%o5
+	ld	[%o4+0],$alo_	! load a[j] as pair of 32-bit words
+	fzeros	$alo
+	ld	[%o4+4],$ahi_
+	fzeros	$ahi
+	ld	[%o5+0],$nlo_	! load n[j] as pair of 32-bit words
+	fzeros	$nlo
+	ld	[%o5+4],$nhi_
+	fzeros	$nhi
+
+	fxtod	$alo,$alo
+	fxtod	$ahi,$ahi
+	fxtod	$nlo,$nlo
+	fxtod	$nhi,$nhi
+
+	ldx	[%sp+$bias+$frame+0],%o0
+		fmuld	$alo,$ba,$aloa
+	ldx	[%sp+$bias+$frame+8],%o1
+		fmuld	$nlo,$na,$nloa
+	ldx	[%sp+$bias+$frame+16],%o2
+		fmuld	$alo,$bb,$alob
+	ldx	[%sp+$bias+$frame+24],%o3
+		fmuld	$nlo,$nb,$nlob
+
+	srlx	%o0,16,%o7
+	std	$alo,[$ap_l+$j]		! save smashed ap[j] in double format
+		fmuld	$alo,$bc,$aloc
+	add	%o7,%o1,%o1
+	std	$ahi,[$ap_h+$j]
+		faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+	srlx	%o1,16,%o7
+	std	$nlo,[$np_l+$j]		! save smashed np[j] in double format
+		fmuld	$alo,$bd,$alod
+	add	%o7,%o2,%o2
+	std	$nhi,[$np_h+$j]
+		faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+	srlx	%o2,16,%o7
+		fmuld	$ahi,$ba,$ahia
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+	and	%o0,$mask,%o0
+		faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+	and	%o1,$mask,%o1
+	and	%o2,$mask,%o2
+		fmuld	$ahi,$bb,$ahib
+	sllx	%o1,16,%o1
+		faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+	sllx	%o2,32,%o2
+		fmuld	$ahi,$bc,$ahic
+	sllx	%o3,48,%o7
+	or	%o1,%o0,%o0
+		faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+	or	%o2,%o0,%o0
+		fmuld	$ahi,$bd,$ahid
+	or	%o7,%o0,%o0		! 64-bit result
+		faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+	addcc	%g1,%o0,%o0
+		faddd	$dota,$nloa,$nloa
+	srlx	%o3,16,%g1		! 34-bit carry
+		faddd	$dotb,$nlob,$nlob
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	stx	%o0,[$tp]		! tp[j-1]=
+
+	faddd	$ahic,$nhic,$dota	! $nhic
+	faddd	$ahid,$nhid,$dotb	! $nhid
+
+	faddd	$nloc,$nhia,$nloc
+	faddd	$nlod,$nhib,$nlod
+
+	fdtox	$nloa,$nloa
+	fdtox	$nlob,$nlob
+	fdtox	$nloc,$nloc
+	fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	std	$nlob,[%sp+$bias+$frame+8]
+	std	$nloc,[%sp+$bias+$frame+16]
+	std	$nlod,[%sp+$bias+$frame+24]
+
+	addcc	$j,8,$j
+	bnz,pt	%icc,.L1st
+	add	$tp,8,$tp
+
+.L1stskip:
+	fdtox	$dota,$dota
+	fdtox	$dotb,$dotb
+
+	ldx	[%sp+$bias+$frame+0],%o0
+	ldx	[%sp+$bias+$frame+8],%o1
+	ldx	[%sp+$bias+$frame+16],%o2
+	ldx	[%sp+$bias+$frame+24],%o3
+
+	srlx	%o0,16,%o7
+	std	$dota,[%sp+$bias+$frame+32]
+	add	%o7,%o1,%o1
+	std	$dotb,[%sp+$bias+$frame+40]
+	srlx	%o1,16,%o7
+	add	%o7,%o2,%o2
+	srlx	%o2,16,%o7
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+	and	%o0,$mask,%o0
+	and	%o1,$mask,%o1
+	and	%o2,$mask,%o2
+	sllx	%o1,16,%o1
+	sllx	%o2,32,%o2
+	sllx	%o3,48,%o7
+	or	%o1,%o0,%o0
+	or	%o2,%o0,%o0
+	or	%o7,%o0,%o0		! 64-bit result
+	ldx	[%sp+$bias+$frame+32],%o4
+	addcc	%g1,%o0,%o0
+	ldx	[%sp+$bias+$frame+40],%o5
+	srlx	%o3,16,%g1		! 34-bit carry
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	stx	%o0,[$tp]		! tp[j-1]=
+	add	$tp,8,$tp
+
+	srlx	%o4,16,%o7
+	add	%o7,%o5,%o5
+	and	%o4,$mask,%o4
+	sllx	%o5,16,%o7
+	or	%o7,%o4,%o4
+	addcc	%g1,%o4,%o4
+	srlx	%o5,48,%g1
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	mov	%g1,$carry
+	stx	%o4,[$tp]		! tp[num-1]=
+
+	ba	.Louter
+	add	$i,8,$i
+.align	32
+.Louter:
+	sub	%g0,$num,$j		! j=-num
+	add	%sp,$bias+$frame+$locals,$tp
+
+	add	$ap,$j,%o3
+	add	$bp,$i,%o4
+
+	ld	[%o3+4],%g1		! bp[i]
+	ld	[%o3+0],%o0
+	ld	[%o4+4],%g5		! ap[0]
+	sllx	%g1,32,%g1
+	ld	[%o4+0],%o1
+	sllx	%g5,32,%g5
+	or	%g1,%o0,%o0
+	or	%g5,%o1,%o1
+
+	ldx	[$tp],%o2		! tp[0]
+	mulx	%o1,%o0,%o0
+	addcc	%o2,%o0,%o0
+	mulx	$n0,%o0,%o0		! (ap[0]*bp[i]+t[0])*n0
+	stx	%o0,[%sp+$bias+$frame+0]
+
+	! transfer b[i] to FPU as 4x16-bit values
+	ldda	[%o4+2]%asi,$ba
+	ldda	[%o4+0]%asi,$bb
+	ldda	[%o4+6]%asi,$bc
+	ldda	[%o4+4]%asi,$bd
+
+	! transfer (ap[0]*b[i]+t[0])*n0 to FPU as 4x16-bit values
+	ldda	[%sp+$bias+$frame+6]%asi,$na
+	fxtod	$ba,$ba
+	ldda	[%sp+$bias+$frame+4]%asi,$nb
+	fxtod	$bb,$bb
+	ldda	[%sp+$bias+$frame+2]%asi,$nc
+	fxtod	$bc,$bc
+	ldda	[%sp+$bias+$frame+0]%asi,$nd
+	fxtod	$bd,$bd
+	ldd	[$ap_l+$j],$alo		! load a[j] in double format
+	fxtod	$na,$na
+	ldd	[$ap_h+$j],$ahi
+	fxtod	$nb,$nb
+	ldd	[$np_l+$j],$nlo		! load n[j] in double format
+	fxtod	$nc,$nc
+	ldd	[$np_h+$j],$nhi
+	fxtod	$nd,$nd
+
+		fmuld	$alo,$ba,$aloa
+		fmuld	$nlo,$na,$nloa
+		fmuld	$alo,$bb,$alob
+		fmuld	$nlo,$nb,$nlob
+		fmuld	$alo,$bc,$aloc
+	faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+		fmuld	$alo,$bd,$alod
+	faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+		fmuld	$ahi,$ba,$ahia
+	faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+		fmuld	$ahi,$bb,$ahib
+	faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+		fmuld	$ahi,$bc,$ahic
+	faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+		fmuld	$ahi,$bd,$ahid
+	faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+
+	faddd	$ahic,$nhic,$dota	! $nhic
+	faddd	$ahid,$nhid,$dotb	! $nhid
+
+	faddd	$nloc,$nhia,$nloc
+	faddd	$nlod,$nhib,$nlod
+
+	fdtox	$nloa,$nloa
+	fdtox	$nlob,$nlob
+	fdtox	$nloc,$nloc
+	fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	std	$nlob,[%sp+$bias+$frame+8]
+	std	$nloc,[%sp+$bias+$frame+16]
+	add	$j,8,$j
+	std	$nlod,[%sp+$bias+$frame+24]
+
+	ldd	[$ap_l+$j],$alo		! load a[j] in double format
+	ldd	[$ap_h+$j],$ahi
+	ldd	[$np_l+$j],$nlo		! load n[j] in double format
+	ldd	[$np_h+$j],$nhi
+
+		fmuld	$alo,$ba,$aloa
+		fmuld	$nlo,$na,$nloa
+		fmuld	$alo,$bb,$alob
+		fmuld	$nlo,$nb,$nlob
+		fmuld	$alo,$bc,$aloc
+	ldx	[%sp+$bias+$frame+0],%o0
+		faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+	ldx	[%sp+$bias+$frame+8],%o1
+		fmuld	$alo,$bd,$alod
+	ldx	[%sp+$bias+$frame+16],%o2
+		faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+	ldx	[%sp+$bias+$frame+24],%o3
+		fmuld	$ahi,$ba,$ahia
+
+	srlx	%o0,16,%o7
+		faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+	add	%o7,%o1,%o1
+		fmuld	$ahi,$bb,$ahib
+	srlx	%o1,16,%o7
+		faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+	add	%o7,%o2,%o2
+		fmuld	$ahi,$bc,$ahic
+	srlx	%o2,16,%o7
+		faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+	! why?
+	and	%o0,$mask,%o0
+		fmuld	$ahi,$bd,$ahid
+	and	%o1,$mask,%o1
+	and	%o2,$mask,%o2
+		faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+	sllx	%o1,16,%o1
+		faddd	$dota,$nloa,$nloa
+	sllx	%o2,32,%o2
+		faddd	$dotb,$nlob,$nlob
+	sllx	%o3,48,%o7
+	or	%o1,%o0,%o0
+		faddd	$ahic,$nhic,$dota	! $nhic
+	or	%o2,%o0,%o0
+		faddd	$ahid,$nhid,$dotb	! $nhid
+	or	%o7,%o0,%o0		! 64-bit result
+	ldx	[$tp],%o7
+		faddd	$nloc,$nhia,$nloc
+	addcc	%o7,%o0,%o0
+	! end-of-why?
+		faddd	$nlod,$nhib,$nlod
+	srlx	%o3,16,%g1		! 34-bit carry
+		fdtox	$nloa,$nloa
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	fdtox	$nlob,$nlob
+	fdtox	$nloc,$nloc
+	fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	std	$nlob,[%sp+$bias+$frame+8]
+	addcc	$j,8,$j
+	std	$nloc,[%sp+$bias+$frame+16]
+	bz,pn	%icc,.Linnerskip
+	std	$nlod,[%sp+$bias+$frame+24]
+
+	ba	.Linner
+	nop
+.align	32
+.Linner:
+	ldd	[$ap_l+$j],$alo		! load a[j] in double format
+	ldd	[$ap_h+$j],$ahi
+	ldd	[$np_l+$j],$nlo		! load n[j] in double format
+	ldd	[$np_h+$j],$nhi
+
+		fmuld	$alo,$ba,$aloa
+		fmuld	$nlo,$na,$nloa
+		fmuld	$alo,$bb,$alob
+		fmuld	$nlo,$nb,$nlob
+		fmuld	$alo,$bc,$aloc
+	ldx	[%sp+$bias+$frame+0],%o0
+		faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+	ldx	[%sp+$bias+$frame+8],%o1
+		fmuld	$alo,$bd,$alod
+	ldx	[%sp+$bias+$frame+16],%o2
+		faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+	ldx	[%sp+$bias+$frame+24],%o3
+		fmuld	$ahi,$ba,$ahia
+
+	srlx	%o0,16,%o7
+		faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+	add	%o7,%o1,%o1
+		fmuld	$ahi,$bb,$ahib
+	srlx	%o1,16,%o7
+		faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+	add	%o7,%o2,%o2
+		fmuld	$ahi,$bc,$ahic
+	srlx	%o2,16,%o7
+		faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+	and	%o0,$mask,%o0
+		fmuld	$ahi,$bd,$ahid
+	and	%o1,$mask,%o1
+	and	%o2,$mask,%o2
+		faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+	sllx	%o1,16,%o1
+		faddd	$dota,$nloa,$nloa
+	sllx	%o2,32,%o2
+		faddd	$dotb,$nlob,$nlob
+	sllx	%o3,48,%o7
+	or	%o1,%o0,%o0
+		faddd	$ahic,$nhic,$dota	! $nhic
+	or	%o2,%o0,%o0
+		faddd	$ahid,$nhid,$dotb	! $nhid
+	or	%o7,%o0,%o0		! 64-bit result
+		faddd	$nloc,$nhia,$nloc
+	addcc	%g1,%o0,%o0
+	ldx	[$tp+8],%o7		! tp[j]
+		faddd	$nlod,$nhib,$nlod
+	srlx	%o3,16,%g1		! 34-bit carry
+		fdtox	$nloa,$nloa
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+		fdtox	$nlob,$nlob
+	addcc	%o7,%o0,%o0
+		fdtox	$nloc,$nloc
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	stx	%o0,[$tp]		! tp[j-1]
+		fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	std	$nlob,[%sp+$bias+$frame+8]
+	std	$nloc,[%sp+$bias+$frame+16]
+	addcc	$j,8,$j
+	std	$nlod,[%sp+$bias+$frame+24]
+	bnz,pt	%icc,.Linner
+	add	$tp,8,$tp
+
+.Linnerskip:
+	fdtox	$dota,$dota
+	fdtox	$dotb,$dotb
+
+	ldx	[%sp+$bias+$frame+0],%o0
+	ldx	[%sp+$bias+$frame+8],%o1
+	ldx	[%sp+$bias+$frame+16],%o2
+	ldx	[%sp+$bias+$frame+24],%o3
+
+	srlx	%o0,16,%o7
+	std	$dota,[%sp+$bias+$frame+32]
+	add	%o7,%o1,%o1
+	std	$dotb,[%sp+$bias+$frame+40]
+	srlx	%o1,16,%o7
+	add	%o7,%o2,%o2
+	srlx	%o2,16,%o7
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+	and	%o0,$mask,%o0
+	and	%o1,$mask,%o1
+	and	%o2,$mask,%o2
+	sllx	%o1,16,%o1
+	sllx	%o2,32,%o2
+	sllx	%o3,48,%o7
+	or	%o1,%o0,%o0
+	or	%o2,%o0,%o0
+	ldx	[%sp+$bias+$frame+32],%o4
+	or	%o7,%o0,%o0		! 64-bit result
+	ldx	[%sp+$bias+$frame+40],%o5
+	addcc	%g1,%o0,%o0
+	ldx	[$tp+8],%o7		! tp[j]
+	srlx	%o3,16,%g1		! 34-bit carry
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	addcc	%o7,%o0,%o0
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	stx	%o0,[$tp]		! tp[j-1]
+	add	$tp,8,$tp
+
+	srlx	%o4,16,%o7
+	add	%o7,%o5,%o5
+	and	%o4,$mask,%o4
+	sllx	%o5,16,%o7
+	or	%o7,%o4,%o4
+	addcc	%g1,%o4,%o4
+	srlx	%o5,48,%g1
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	addcc	$carry,%o4,%o4
+	stx	%o4,[$tp]		! tp[num-1]
+	mov	%g1,$carry
+	bcs,a	%xcc,.+8
+	add	$carry,1,$carry
+
+	addcc	$i,8,$i
+	bnz	%icc,.Louter
+	nop
+
+	add	$tp,8,$tp		! adjust tp to point at the end
+	orn	%g0,%g0,%g4
+	sub	%g0,$num,%o7		! n=-num
+	ba	.Lsub
+	subcc	%g0,%g0,%g0		! clear %icc.c
+
+.align	32
+.Lsub:
+	ldx	[$tp+%o7],%o0
+	add	$np,%o7,%g1
+	ld	[%g1+0],%o2
+	ld	[%g1+4],%o3
+	srlx	%o0,32,%o1
+	subccc	%o0,%o2,%o2
+	add	$rp,%o7,%g1
+	subccc	%o1,%o3,%o3
+	st	%o2,[%g1+0]
+	add	%o7,8,%o7
+	brnz,pt	%o7,.Lsub
+	st	%o3,[%g1+4]
+	subc	$carry,0,%g4
+	sub	%g0,$num,%o7		! n=-num
+	ba	.Lcopy
+	nop
+
+.align	32
+.Lcopy:
+	ldx	[$tp+%o7],%o0
+	add	$rp,%o7,%g1
+	ld	[%g1+0],%o2
+	ld	[%g1+4],%o3
+	stx	%g0,[$tp+%o7]
+	and	%o0,%g4,%o0
+	srlx	%o0,32,%o1
+	andn	%o2,%g4,%o2
+	andn	%o3,%g4,%o3
+	or	%o2,%o0,%o0
+	or	%o3,%o1,%o1
+	st	%o0,[%g1+0]
+	add	%o7,8,%o7
+	brnz,pt	%o7,.Lcopy
+	st	%o1,[%g1+4]
+	sub	%g0,$num,%o7		! n=-num
+
+.Lzap:
+	stx	%g0,[$ap_l+%o7]
+	stx	%g0,[$ap_h+%o7]
+	stx	%g0,[$np_l+%o7]
+	stx	%g0,[$np_h+%o7]
+	add	%o7,8,%o7
+	brnz,pt	%o7,.Lzap
+	nop
+
+	ldx	[%sp+$bias+$frame+48],%o7
+	wr	%g0,%o7,%asi		! restore %asi
+
+	mov	1,%i0
+.Lret:
+	ret
+	restore
+.type   $fname,#function
+.size	$fname,(.-$fname)
+.asciz	"Montgomery Multipltication for UltraSPARC, CRYPTOGAMS by <appro\@openssl.org>"
+.align	32
+___
+
+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+
+# Below substitution makes it possible to compile without demanding
+# VIS extentions on command line, e.g. -xarch=v9 vs. -xarch=v9a. I
+# dare to do this, because VIS capability is detected at run-time now
+# and this routine is not called on CPU not capable to execute it. Do
+# note that fzeros is not the only VIS dependency! Another dependency
+# is implicit and is just _a_ numerical value loaded to %asi register,
+# which assembler can't recognize as VIS specific...
+$code =~ s/fzeros\s+%f([0-9]+)/
+	   sprintf(".word\t0x%x\t! fzeros %%f%d",0x81b00c20|($1<<25),$1)
+	  /gem;
+
+print $code;
+# flush
+close STDOUT;
diff --git a/openssl/crypto/bn/asm/via-mont.pl b/openssl/crypto/bn/asm/via-mont.pl
new file mode 100644
index 0000000..c046a51
--- /dev/null
+++ b/openssl/crypto/bn/asm/via-mont.pl
@@ -0,0 +1,242 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# Wrapper around 'rep montmul', VIA-specific instruction accessing
+# PadLock Montgomery Multiplier. The wrapper is designed as drop-in
+# replacement for OpenSSL bn_mul_mont [first implemented in 0.9.9].
+#
+# Below are interleaved outputs from 'openssl speed rsa dsa' for 4
+# different software configurations on 1.5GHz VIA Esther processor.
+# Lines marked with "software integer" denote performance of hand-
+# coded integer-only assembler found in OpenSSL 0.9.7. "Software SSE2"
+# refers to hand-coded SSE2 Montgomery multiplication procedure found
+# OpenSSL 0.9.9. "Hardware VIA SDK" refers to padlock_pmm routine from
+# Padlock SDK 2.0.1 available for download from VIA, which naturally
+# utilizes the magic 'repz montmul' instruction. And finally "hardware
+# this" refers to *this* implementation which also uses 'repz montmul'
+#
+#                   sign    verify    sign/s verify/s
+# rsa  512 bits 0.001720s 0.000140s    581.4   7149.7	software integer
+# rsa  512 bits 0.000690s 0.000086s   1450.3  11606.0	software SSE2
+# rsa  512 bits 0.006136s 0.000201s    163.0   4974.5	hardware VIA SDK
+# rsa  512 bits 0.000712s 0.000050s   1404.9  19858.5	hardware this
+#
+# rsa 1024 bits 0.008518s 0.000413s    117.4   2420.8	software integer
+# rsa 1024 bits 0.004275s 0.000277s    233.9   3609.7	software SSE2
+# rsa 1024 bits 0.012136s 0.000260s     82.4   3844.5	hardware VIA SDK
+# rsa 1024 bits 0.002522s 0.000116s    396.5   8650.9	hardware this
+#
+# rsa 2048 bits 0.050101s 0.001371s     20.0    729.6	software integer
+# rsa 2048 bits 0.030273s 0.001008s     33.0    991.9	software SSE2
+# rsa 2048 bits 0.030833s 0.000976s     32.4   1025.1	hardware VIA SDK
+# rsa 2048 bits 0.011879s 0.000342s     84.2   2921.7	hardware this
+#
+# rsa 4096 bits 0.327097s 0.004859s      3.1    205.8	software integer
+# rsa 4096 bits 0.229318s 0.003859s      4.4    259.2	software SSE2
+# rsa 4096 bits 0.233953s 0.003274s      4.3    305.4	hardware VIA SDK
+# rsa 4096 bits 0.070493s 0.001166s     14.2    857.6	hardware this
+#
+# dsa  512 bits 0.001342s 0.001651s    745.2    605.7	software integer
+# dsa  512 bits 0.000844s 0.000987s   1185.3   1013.1	software SSE2
+# dsa  512 bits 0.001902s 0.002247s    525.6    444.9	hardware VIA SDK
+# dsa  512 bits 0.000458s 0.000524s   2182.2   1909.1	hardware this
+#
+# dsa 1024 bits 0.003964s 0.004926s    252.3    203.0	software integer
+# dsa 1024 bits 0.002686s 0.003166s    372.3    315.8	software SSE2
+# dsa 1024 bits 0.002397s 0.002823s    417.1    354.3	hardware VIA SDK
+# dsa 1024 bits 0.000978s 0.001170s   1022.2    855.0	hardware this
+#
+# dsa 2048 bits 0.013280s 0.016518s     75.3     60.5	software integer
+# dsa 2048 bits 0.009911s 0.011522s    100.9     86.8	software SSE2
+# dsa 2048 bits 0.009542s 0.011763s    104.8     85.0	hardware VIA SDK
+# dsa 2048 bits 0.002884s 0.003352s    346.8    298.3	hardware this
+#
+# To give you some other reference point here is output for 2.4GHz P4
+# running hand-coded SSE2 bn_mul_mont found in 0.9.9, i.e. "software
+# SSE2" in above terms.
+#
+# rsa  512 bits 0.000407s 0.000047s   2454.2  21137.0
+# rsa 1024 bits 0.002426s 0.000141s    412.1   7100.0
+# rsa 2048 bits 0.015046s 0.000491s     66.5   2034.9
+# rsa 4096 bits 0.109770s 0.002379s      9.1    420.3
+# dsa  512 bits 0.000438s 0.000525s   2281.1   1904.1
+# dsa 1024 bits 0.001346s 0.001595s    742.7    627.0
+# dsa 2048 bits 0.004745s 0.005582s    210.7    179.1
+#
+# Conclusions: 
+# - VIA SDK leaves a *lot* of room for improvement (which this
+#   implementation successfully fills:-);
+# - 'rep montmul' gives up to >3x performance improvement depending on
+#   key length;
+# - in terms of absolute performance it delivers approximately as much
+#   as modern out-of-order 32-bit cores [again, for longer keys].
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"via-mont.pl");
+
+# int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
+$func="bn_mul_mont_padlock";
+
+$pad=16*1;	# amount of reserved bytes on top of every vector
+
+# stack layout
+$mZeroPrime=&DWP(0,"esp");		# these are specified by VIA
+$A=&DWP(4,"esp");
+$B=&DWP(8,"esp");
+$T=&DWP(12,"esp");
+$M=&DWP(16,"esp");
+$scratch=&DWP(20,"esp");
+$rp=&DWP(24,"esp");			# these are mine
+$sp=&DWP(28,"esp");
+# &DWP(32,"esp")			# 32 byte scratch area
+# &DWP(64+(4*$num+$pad)*0,"esp")	# padded tp[num]
+# &DWP(64+(4*$num+$pad)*1,"esp")	# padded copy of ap[num]
+# &DWP(64+(4*$num+$pad)*2,"esp")	# padded copy of bp[num]
+# &DWP(64+(4*$num+$pad)*3,"esp")	# padded copy of np[num]
+# Note that SDK suggests to unconditionally allocate 2K per vector. This
+# has quite an impact on performance. It naturally depends on key length,
+# but to give an example 1024 bit private RSA key operations suffer >30%
+# penalty. I allocate only as much as actually required...
+
+&function_begin($func);
+	&xor	("eax","eax");
+	&mov	("ecx",&wparam(5));	# num
+	# meet VIA's limitations for num [note that the specification
+	# expresses them in bits, while we work with amount of 32-bit words]
+	&test	("ecx",3);
+	&jnz	(&label("leave"));	# num % 4 != 0
+	&cmp	("ecx",8);
+	&jb	(&label("leave"));	# num < 8
+	&cmp	("ecx",1024);
+	&ja	(&label("leave"));	# num > 1024
+
+	&pushf	();
+	&cld	();
+
+	&mov	("edi",&wparam(0));	# rp
+	&mov	("eax",&wparam(1));	# ap
+	&mov	("ebx",&wparam(2));	# bp
+	&mov	("edx",&wparam(3));	# np
+	&mov	("esi",&wparam(4));	# n0
+	&mov	("esi",&DWP(0,"esi"));	# *n0
+
+	&lea	("ecx",&DWP($pad,"","ecx",4));	# ecx becomes vector size in bytes
+	&lea	("ebp",&DWP(64,"","ecx",4));	# allocate 4 vectors + 64 bytes
+	&neg	("ebp");
+	&add	("ebp","esp");
+	&and	("ebp",-64);		# align to cache-line
+	&xchg	("ebp","esp");		# alloca
+
+	&mov	($rp,"edi");		# save rp
+	&mov	($sp,"ebp");		# save esp
+
+	&mov	($mZeroPrime,"esi");
+	&lea	("esi",&DWP(64,"esp"));	# tp
+	&mov	($T,"esi");
+	&lea	("edi",&DWP(32,"esp"));	# scratch area
+	&mov	($scratch,"edi");
+	&mov	("esi","eax");
+
+	&lea	("ebp",&DWP(-$pad,"ecx"));
+	&shr	("ebp",2);		# restore original num value in ebp
+
+	&xor	("eax","eax");
+
+	&mov	("ecx","ebp");
+	&lea	("ecx",&DWP((32+$pad)/4,"ecx"));# padded tp + scratch
+	&data_byte(0xf3,0xab);		# rep stosl, bzero
+
+	&mov	("ecx","ebp");
+	&lea	("edi",&DWP(64+$pad,"esp","ecx",4));# pointer to ap copy
+	&mov	($A,"edi");
+	&data_byte(0xf3,0xa5);		# rep movsl, memcpy
+	&mov	("ecx",$pad/4);
+	&data_byte(0xf3,0xab);		# rep stosl, bzero pad
+	# edi points at the end of padded ap copy...
+
+	&mov	("ecx","ebp");
+	&mov	("esi","ebx");
+	&mov	($B,"edi");
+	&data_byte(0xf3,0xa5);		# rep movsl, memcpy
+	&mov	("ecx",$pad/4);
+	&data_byte(0xf3,0xab);		# rep stosl, bzero pad
+	# edi points at the end of padded bp copy...
+
+	&mov	("ecx","ebp");
+	&mov	("esi","edx");
+	&mov	($M,"edi");
+	&data_byte(0xf3,0xa5);		# rep movsl, memcpy
+	&mov	("ecx",$pad/4);
+	&data_byte(0xf3,0xab);		# rep stosl, bzero pad
+	# edi points at the end of padded np copy...
+
+	# let magic happen...
+	&mov	("ecx","ebp");
+	&mov	("esi","esp");
+	&shl	("ecx",5);		# convert word counter to bit counter
+	&align	(4);
+	&data_byte(0xf3,0x0f,0xa6,0xc0);# rep montmul
+
+	&mov	("ecx","ebp");
+	&lea	("esi",&DWP(64,"esp"));		# tp
+	# edi still points at the end of padded np copy...
+	&neg	("ebp");
+	&lea	("ebp",&DWP(-$pad,"edi","ebp",4));	# so just "rewind"
+	&mov	("edi",$rp);			# restore rp
+	&xor	("edx","edx");			# i=0 and clear CF
+
+&set_label("sub",8);
+	&mov	("eax",&DWP(0,"esi","edx",4));
+	&sbb	("eax",&DWP(0,"ebp","edx",4));
+	&mov	(&DWP(0,"edi","edx",4),"eax");	# rp[i]=tp[i]-np[i]
+	&lea	("edx",&DWP(1,"edx"));		# i++
+	&loop	(&label("sub"));		# doesn't affect CF!
+
+	&mov	("eax",&DWP(0,"esi","edx",4));	# upmost overflow bit
+	&sbb	("eax",0);
+	&and	("esi","eax");
+	&not	("eax");
+	&mov	("ebp","edi");
+	&and	("ebp","eax");
+	&or	("esi","ebp");			# tp=carry?tp:rp
+
+	&mov	("ecx","edx");			# num
+	&xor	("edx","edx");			# i=0
+
+&set_label("copy",8);
+	&mov	("eax",&DWP(0,"esi","edx",4));
+	&mov	(&DWP(64,"esp","edx",4),"ecx");	# zap tp
+	&mov	(&DWP(0,"edi","edx",4),"eax");
+	&lea	("edx",&DWP(1,"edx"));		# i++
+	&loop	(&label("copy"));
+
+	&mov	("ebp",$sp);
+	&xor	("eax","eax");
+
+	&mov	("ecx",64/4);
+	&mov	("edi","esp");		# zap frame including scratch area
+	&data_byte(0xf3,0xab);		# rep stosl, bzero
+
+	# zap copies of ap, bp and np
+	&lea	("edi",&DWP(64+$pad,"esp","edx",4));# pointer to ap
+	&lea	("ecx",&DWP(3*$pad/4,"edx","edx",2));
+	&data_byte(0xf3,0xab);		# rep stosl, bzero
+
+	&mov	("esp","ebp");
+	&inc	("eax");		# signal "done"
+	&popf	();
+&set_label("leave");
+&function_end($func);
+
+&asciz("Padlock Montgomery Multiplication, CRYPTOGAMS by <appro\@openssl.org>");
+
+&asm_finish();
diff --git a/openssl/crypto/bn/asm/vms.mar b/openssl/crypto/bn/asm/vms.mar
new file mode 100644
index 0000000..aefab15
--- /dev/null
+++ b/openssl/crypto/bn/asm/vms.mar
@@ -0,0 +1,6440 @@
+	.title	vax_bn_mul_add_words  unsigned multiply & add, 32*32+32+32=>64
+;
+; w.j.m. 15-jan-1999
+;
+; it's magic ...
+;
+; ULONG bn_mul_add_words(ULONG r[],ULONG a[],int n,ULONG w) {
+;	ULONG c = 0;
+;	int i;
+;	for(i = 0; i < n; i++) <c,r[i]> := r[i] + c + a[i] * w ;
+;	return c;
+; }
+
+r=4 ;(AP)
+a=8 ;(AP)
+n=12 ;(AP)	n	by value (input)
+w=16 ;(AP)	w	by value (input)
+
+
+	.psect	code,nowrt
+
+.entry	bn_mul_add_words,^m<r2,r3,r4,r5,r6>
+
+	moval	@r(ap),r2
+	moval	@a(ap),r3
+	movl	n(ap),r4	; assumed >0 by C code
+	movl	w(ap),r5
+	clrl	r6		; c
+
+0$:
+	emul	r5,(r3),(r2),r0		; w, a[], r[] considered signed
+
+	; fixup for "negative" r[]
+	tstl	(r2)
+	bgeq	10$
+	incl	r1
+10$:
+
+	; add in c
+	addl2	r6,r0
+	adwc	#0,r1
+
+	; combined fixup for "negative" w, a[]
+	tstl	r5
+	bgeq	20$
+	addl2	(r3),r1
+20$:
+	tstl	(r3)
+	bgeq	30$
+	addl2	r5,r1
+30$:
+
+	movl	r0,(r2)+		; store lo result in r[] & advance
+	addl	#4,r3			; advance a[]
+	movl	r1,r6			; store hi result => c
+
+	sobgtr	r4,0$
+
+	movl	r6,r0			; return c
+	ret
+
+	.title	vax_bn_mul_words  unsigned multiply & add, 32*32+32=>64
+;
+; w.j.m. 15-jan-1999
+;
+; it's magic ...
+;
+; ULONG bn_mul_words(ULONG r[],ULONG a[],int n,ULONG w) {
+;	ULONG c = 0;
+;	int i;
+;	for(i = 0; i < num; i++) <c,r[i]> := a[i] * w + c ;
+;	return(c);
+; }
+
+r=4 ;(AP)
+a=8 ;(AP)
+n=12 ;(AP)	n	by value (input)
+w=16 ;(AP)	w	by value (input)
+
+
+	.psect	code,nowrt
+
+.entry	bn_mul_words,^m<r2,r3,r4,r5,r6>
+
+	moval	@r(ap),r2	; r2 -> r[]
+	moval	@a(ap),r3	; r3 -> a[]
+	movl	n(ap),r4	; r4 = loop count (assumed >0 by C code)
+	movl	w(ap),r5	; r5 = w
+	clrl	r6		; r6 = c
+
+0$:
+	; <r1,r0> := w * a[] + c
+	emul	r5,(r3),r6,r0		; w, a[], c considered signed
+
+	; fixup for "negative" c
+	tstl	r6			; c
+	bgeq	10$
+	incl	r1
+10$:
+
+	; combined fixup for "negative" w, a[]
+	tstl	r5			; w
+	bgeq	20$
+	addl2	(r3),r1			; a[]
+20$:
+	tstl	(r3)			; a[]
+	bgeq	30$
+	addl2	r5,r1			; w
+30$:
+
+	movl	r0,(r2)+		; store lo result in r[] & advance
+	addl	#4,r3			; advance a[]
+	movl	r1,r6			; store hi result => c
+
+	sobgtr	r4,0$
+
+	movl	r6,r0			; return c
+	ret
+
+	.title	vax_bn_sqr_words  unsigned square, 32*32=>64
+;
+; w.j.m. 15-jan-1999
+;
+; it's magic ...
+;
+; void bn_sqr_words(ULONG r[],ULONG a[],int n) {
+;	int i;
+;	for(i = 0; i < n; i++) <r[2*i+1],r[2*i]> := a[i] * a[i] ;
+; }
+
+r=4 ;(AP)
+a=8 ;(AP)
+n=12 ;(AP)	n	by value (input)
+
+
+	.psect	code,nowrt
+
+.entry	bn_sqr_words,^m<r2,r3,r4,r5>
+
+	moval	@r(ap),r2	; r2 -> r[]
+	moval	@a(ap),r3	; r3 -> a[]
+	movl	n(ap),r4	; r4 = n (assumed >0 by C code)
+
+0$:
+	movl	(r3)+,r5		; r5 = a[] & advance
+
+	; <r1,r0> := a[] * a[]
+	emul	r5,r5,#0,r0		; a[] considered signed
+
+	; fixup for "negative" a[]
+	tstl	r5			; a[]
+	bgeq	30$
+	addl2	r5,r1			; a[]
+	addl2	r5,r1			; a[]
+30$:
+
+	movl	r0,(r2)+		; store lo result in r[] & advance
+	movl	r1,(r2)+		; store hi result in r[] & advance
+
+	sobgtr	r4,0$
+
+	movl	#1,r0			; return SS$_NORMAL
+	ret
+
+	.title	vax_bn_div_words  unsigned divide
+;
+; Richard Levitte 20-Nov-2000
+;
+; ULONG bn_div_words(ULONG h, ULONG l, ULONG d)
+; {
+;	return ((ULONG)((((ULLONG)h)<<32)|l) / (ULLONG)d);
+; }
+;
+; Using EDIV would be very easy, if it didn't do signed calculations.
+; Any time any of the input numbers are signed, there are problems,
+; usually with integer overflow, at which point it returns useless
+; data (the quotient gets the value of l, and the remainder becomes 0).
+;
+; If it was just for the dividend, it would be very easy, just divide
+; it by 2 (unsigned), do the division, multiply the resulting quotient
+; and remainder by 2, add the bit that was dropped when dividing by 2
+; to the remainder, and do some adjustment so the remainder doesn't
+; end up larger than the divisor.  For some cases when the divisor is
+; negative (from EDIV's point of view, i.e. when the highest bit is set),
+; dividing the dividend by 2 isn't enough, and since some operations
+; might generate integer overflows even when the dividend is divided by
+; 4 (when the high part of the shifted down dividend ends up being exactly
+; half of the divisor, the result is the quotient 0x80000000, which is
+; negative...) it needs to be divided by 8.  Furthermore, the divisor needs
+; to be divided by 2 (unsigned) as well, to avoid more problems with the sign.
+; In this case, a little extra fiddling with the remainder is required.
+;
+; So, the simplest way to handle this is always to divide the dividend
+; by 8, and to divide the divisor by 2 if it's highest bit is set.
+; After EDIV has been used, the quotient gets multiplied by 8 if the
+; original divisor was positive, otherwise 4.  The remainder, oddly
+; enough, is *always* multiplied by 8.
+; NOTE: in the case mentioned above, where the high part of the shifted
+; down dividend ends up being exactly half the shifted down divisor, we
+; end up with a 33 bit quotient.  That's no problem however, it usually
+; means we have ended up with a too large remainder as well, and the
+; problem is fixed by the last part of the algorithm (next paragraph).
+;
+; The routine ends with comparing the resulting remainder with the
+; original divisor and if the remainder is larger, subtract the
+; original divisor from it, and increase the quotient by 1.  This is
+; done until the remainder is smaller than the divisor.
+;
+; The complete algorithm looks like this:
+;
+; d'    = d
+; l'    = l & 7
+; [h,l] = [h,l] >> 3
+; [q,r] = floor([h,l] / d)	# This is the EDIV operation
+; if (q < 0) q = -q		# I doubt this is necessary any more
+;
+; r'    = r >> 29
+; if (d' >= 0)
+;   q'  = q >> 29
+;   q   = q << 3
+; else
+;   q'  = q >> 30
+;   q   = q << 2
+; r     = (r << 3) + l'
+;
+; if (d' < 0)
+;   {
+;     [r',r] = [r',r] - q
+;     while ([r',r] < 0)
+;       {
+;         [r',r] = [r',r] + d
+;         [q',q] = [q',q] - 1
+;       }
+;   }
+;
+; while ([r',r] >= d')
+;   {
+;     [r',r] = [r',r] - d'
+;     [q',q] = [q',q] + 1
+;   }
+;
+; return q
+
+h=4 ;(AP)	h	by value (input)
+l=8 ;(AP)	l	by value (input)
+d=12 ;(AP)	d	by value (input)
+
+;r2 = l, q
+;r3 = h, r
+;r4 = d
+;r5 = l'
+;r6 = r'
+;r7 = d'
+;r8 = q'
+
+	.psect	code,nowrt
+
+.entry	bn_div_words,^m<r2,r3,r4,r5,r6,r7,r8>
+	movl	l(ap),r2
+	movl	h(ap),r3
+	movl	d(ap),r4
+
+	bicl3	#^XFFFFFFF8,r2,r5 ; l' = l & 7
+	bicl3	#^X00000007,r2,r2
+
+	bicl3	#^XFFFFFFF8,r3,r6
+	bicl3	#^X00000007,r3,r3
+        
+	addl	r6,r2
+
+	rotl	#-3,r2,r2	; l = l >> 3
+	rotl	#-3,r3,r3	; h = h >> 3
+                
+	movl	r4,r7		; d' = d
+
+	movl	#0,r6		; r' = 0
+	movl	#0,r8		; q' = 0
+
+	tstl	r4
+	beql	666$		; Uh-oh, the divisor is 0...
+	bgtr	1$
+	rotl	#-1,r4,r4	; If d is negative, shift it right.
+	bicl2	#^X80000000,r4	; Since d is then a large number, the
+				; lowest bit is insignificant
+				; (contradict that, and I'll fix the problem!)
+1$:     
+	ediv	r4,r2,r2,r3	; Do the actual division
+
+	tstl	r2
+	bgeq	3$
+	mnegl	r2,r2		; if q < 0, negate it
+3$:     
+	tstl	r7
+	blss	4$
+	rotl	#3,r2,r2	;   q = q << 3
+	bicl3	#^XFFFFFFF8,r2,r8 ;    q' gets the high bits from q
+	bicl3	#^X00000007,r2,r2
+	bsb	41$
+4$:				; else
+	rotl	#2,r2,r2	;   q = q << 2
+	bicl3	#^XFFFFFFFC,r2,r8 ;   q' gets the high bits from q
+	bicl3	#^X00000003,r2,r2
+41$:
+	rotl	#3,r3,r3	; r = r << 3
+	bicl3	#^XFFFFFFF8,r3,r6 ; r' gets the high bits from r
+	bicl3	#^X00000007,r3,r3
+	addl	r5,r3		; r = r + l'
+
+	tstl	r7
+	bgeq	5$
+	bitl	#1,r7
+	beql	5$		; if d' < 0 && d' & 1
+	subl	r2,r3		;   [r',r] = [r',r] - [q',q]
+	sbwc	r8,r6
+45$:
+	bgeq	5$		;   while r < 0
+	decl	r2		;     [q',q] = [q',q] - 1
+	sbwc	#0,r8
+	addl	r7,r3		;     [r',r] = [r',r] + d'
+	adwc	#0,r6
+	brb	45$
+
+; The return points are placed in the middle to keep a short distance from
+; all the branch points
+42$:
+;	movl	r3,r1
+	movl	r2,r0
+	ret
+666$:
+	movl	#^XFFFFFFFF,r0
+	ret
+
+5$:
+	tstl	r6
+	bneq	6$
+	cmpl	r3,r7
+	blssu	42$		; while [r',r] >= d'
+6$:
+	subl	r7,r3		;   [r',r] = [r',r] - d'
+	sbwc	#0,r6
+	incl	r2		;   [q',q] = [q',q] + 1
+	adwc	#0,r8
+	brb	5$	
+
+	.title	vax_bn_add_words  unsigned add of two arrays
+;
+; Richard Levitte 20-Nov-2000
+;
+; ULONG bn_add_words(ULONG r[], ULONG a[], ULONG b[], int n) {
+;	ULONG c = 0;
+;	int i;
+;	for (i = 0; i < n; i++) <c,r[i]> = a[i] + b[i] + c;
+;	return(c);
+; }
+
+r=4 ;(AP)	r	by reference (output)
+a=8 ;(AP)	a	by reference (input)
+b=12 ;(AP)	b	by reference (input)
+n=16 ;(AP)	n	by value (input)
+
+
+	.psect	code,nowrt
+
+.entry	bn_add_words,^m<r2,r3,r4,r5,r6>
+
+	moval	@r(ap),r2
+	moval	@a(ap),r3
+	moval	@b(ap),r4
+	movl	n(ap),r5	; assumed >0 by C code
+	clrl	r0		; c
+
+	tstl	r5		; carry = 0
+	bleq	666$
+
+0$:
+	movl	(r3)+,r6	; carry untouched
+	adwc	(r4)+,r6	; carry used and touched
+	movl	r6,(r2)+	; carry untouched
+	sobgtr	r5,0$		; carry untouched
+
+	adwc	#0,r0
+666$:
+	ret
+
+	.title	vax_bn_sub_words  unsigned add of two arrays
+;
+; Richard Levitte 20-Nov-2000
+;
+; ULONG bn_sub_words(ULONG r[], ULONG a[], ULONG b[], int n) {
+;	ULONG c = 0;
+;	int i;
+;	for (i = 0; i < n; i++) <c,r[i]> = a[i] - b[i] - c;
+;	return(c);
+; }
+
+r=4 ;(AP)	r	by reference (output)
+a=8 ;(AP)	a	by reference (input)
+b=12 ;(AP)	b	by reference (input)
+n=16 ;(AP)	n	by value (input)
+
+
+	.psect	code,nowrt
+
+.entry	bn_sub_words,^m<r2,r3,r4,r5,r6>
+
+	moval	@r(ap),r2
+	moval	@a(ap),r3
+	moval	@b(ap),r4
+	movl	n(ap),r5	; assumed >0 by C code
+	clrl	r0		; c
+
+	tstl	r5		; carry = 0
+	bleq	666$
+
+0$:
+	movl	(r3)+,r6	; carry untouched
+	sbwc	(r4)+,r6	; carry used and touched
+	movl	r6,(r2)+	; carry untouched
+	sobgtr	r5,0$		; carry untouched
+
+	adwc	#0,r0
+666$:
+	ret
+
+
+;r=4 ;(AP)
+;a=8 ;(AP)
+;b=12 ;(AP)
+;n=16 ;(AP)	n	by value (input)
+
+	.psect	code,nowrt
+
+.entry	BN_MUL_COMBA8,^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
+	movab	-924(sp),sp
+	clrq	r8
+
+	clrl	r10
+
+	movl	8(ap),r6
+	movzwl	2(r6),r3
+	movl	12(ap),r7
+	bicl3	#-65536,(r7),r2
+	movzwl	2(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,(r6),-12(fp)
+	bicl3	#-65536,r3,-16(fp)
+	mull3	r0,-12(fp),-4(fp)
+	mull2	r2,-12(fp)
+	mull3	r2,-16(fp),-8(fp)
+	mull2	r0,-16(fp)
+	addl3	-4(fp),-8(fp),r0
+	bicl3	#0,r0,-4(fp)
+	cmpl	-4(fp),-8(fp)
+	bgequ	noname.45
+	addl2	#65536,-16(fp)
+noname.45:
+	movzwl	-2(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-16(fp)
+	bicl3	#-65536,-4(fp),r0
+	ashl	#16,r0,-8(fp)
+	addl3	-8(fp),-12(fp),r0
+	bicl3	#0,r0,-12(fp)
+	cmpl	-12(fp),-8(fp)
+	bgequ	noname.46
+	incl	-16(fp)
+noname.46:
+	movl	-12(fp),r1
+	movl	-16(fp),r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.47
+	incl	r2
+noname.47:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.48
+	incl	r10
+noname.48:
+
+	movl	4(ap),r11
+	movl	r9,(r11)
+
+	clrl	r9
+
+	movzwl	2(r6),r2
+	bicl3	#-65536,4(r7),r3
+	movzwl	6(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,(r6),-28(fp)
+	bicl3	#-65536,r2,-32(fp)
+	mull3	r0,-28(fp),-20(fp)
+	mull2	r3,-28(fp)
+	mull3	r3,-32(fp),-24(fp)
+	mull2	r0,-32(fp)
+	addl3	-20(fp),-24(fp),r0
+	bicl3	#0,r0,-20(fp)
+	cmpl	-20(fp),-24(fp)
+	bgequ	noname.49
+	addl2	#65536,-32(fp)
+noname.49:
+	movzwl	-18(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-32(fp)
+	bicl3	#-65536,-20(fp),r0
+	ashl	#16,r0,-24(fp)
+	addl3	-24(fp),-28(fp),r0
+	bicl3	#0,r0,-28(fp)
+	cmpl	-28(fp),-24(fp)
+	bgequ	noname.50
+	incl	-32(fp)
+noname.50:
+	movl	-28(fp),r1
+	movl	-32(fp),r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.51
+	incl	r2
+noname.51:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.52
+	incl	r9
+noname.52:
+
+	movzwl	6(r6),r2
+	bicl3	#-65536,(r7),r3
+	movzwl	2(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,4(r6),-44(fp)
+	bicl3	#-65536,r2,-48(fp)
+	mull3	r0,-44(fp),-36(fp)
+	mull2	r3,-44(fp)
+	mull3	r3,-48(fp),-40(fp)
+	mull2	r0,-48(fp)
+	addl3	-36(fp),-40(fp),r0
+	bicl3	#0,r0,-36(fp)
+	cmpl	-36(fp),-40(fp)
+	bgequ	noname.53
+	addl2	#65536,-48(fp)
+noname.53:
+	movzwl	-34(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-48(fp)
+	bicl3	#-65536,-36(fp),r0
+	ashl	#16,r0,-40(fp)
+	addl3	-40(fp),-44(fp),r0
+	bicl3	#0,r0,-44(fp)
+	cmpl	-44(fp),-40(fp)
+	bgequ	noname.54
+	incl	-48(fp)
+noname.54:
+	movl	-44(fp),r1
+	movl	-48(fp),r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.55
+	incl	r2
+noname.55:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.56
+	incl	r9
+noname.56:
+
+	movl	r8,4(r11)
+
+	clrl	r8
+
+	movzwl	10(r6),r2
+	bicl3	#-65536,(r7),r3
+	movzwl	2(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,8(r6),-60(fp)
+	bicl3	#-65536,r2,-64(fp)
+	mull3	r0,-60(fp),-52(fp)
+	mull2	r3,-60(fp)
+	mull3	r3,-64(fp),-56(fp)
+	mull2	r0,-64(fp)
+	addl3	-52(fp),-56(fp),r0
+	bicl3	#0,r0,-52(fp)
+	cmpl	-52(fp),-56(fp)
+	bgequ	noname.57
+	addl2	#65536,-64(fp)
+noname.57:
+	movzwl	-50(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-64(fp)
+	bicl3	#-65536,-52(fp),r0
+	ashl	#16,r0,-56(fp)
+	addl3	-56(fp),-60(fp),r0
+	bicl3	#0,r0,-60(fp)
+	cmpl	-60(fp),-56(fp)
+	bgequ	noname.58
+	incl	-64(fp)
+noname.58:
+	movl	-60(fp),r1
+	movl	-64(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.59
+	incl	r2
+noname.59:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.60
+	incl	r8
+noname.60:
+
+	movzwl	6(r6),r2
+	bicl3	#-65536,4(r7),r3
+	movzwl	6(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,4(r6),-76(fp)
+	bicl3	#-65536,r2,-80(fp)
+	mull3	r0,-76(fp),-68(fp)
+	mull2	r3,-76(fp)
+	mull3	r3,-80(fp),-72(fp)
+	mull2	r0,-80(fp)
+	addl3	-68(fp),-72(fp),r0
+	bicl3	#0,r0,-68(fp)
+	cmpl	-68(fp),-72(fp)
+	bgequ	noname.61
+	addl2	#65536,-80(fp)
+noname.61:
+	movzwl	-66(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-80(fp)
+	bicl3	#-65536,-68(fp),r0
+	ashl	#16,r0,-72(fp)
+	addl3	-72(fp),-76(fp),r0
+	bicl3	#0,r0,-76(fp)
+	cmpl	-76(fp),-72(fp)
+	bgequ	noname.62
+	incl	-80(fp)
+noname.62:
+	movl	-76(fp),r1
+	movl	-80(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.63
+	incl	r2
+noname.63:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.64
+	incl	r8
+noname.64:
+
+	movzwl	2(r6),r2
+	bicl3	#-65536,8(r7),r3
+	movzwl	10(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,(r6),-92(fp)
+	bicl3	#-65536,r2,-96(fp)
+	mull3	r0,-92(fp),-84(fp)
+	mull2	r3,-92(fp)
+	mull3	r3,-96(fp),-88(fp)
+	mull2	r0,-96(fp)
+	addl3	-84(fp),-88(fp),r0
+	bicl3	#0,r0,-84(fp)
+	cmpl	-84(fp),-88(fp)
+	bgequ	noname.65
+	addl2	#65536,-96(fp)
+noname.65:
+	movzwl	-82(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-96(fp)
+	bicl3	#-65536,-84(fp),r0
+	ashl	#16,r0,-88(fp)
+	addl3	-88(fp),-92(fp),r0
+	bicl3	#0,r0,-92(fp)
+	cmpl	-92(fp),-88(fp)
+	bgequ	noname.66
+	incl	-96(fp)
+noname.66:
+	movl	-92(fp),r1
+	movl	-96(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.67
+	incl	r2
+noname.67:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.68
+	incl	r8
+noname.68:
+
+	movl	r10,8(r11)
+
+	clrl	r10
+
+	movzwl	2(r6),r2
+	bicl3	#-65536,12(r7),r3
+	movzwl	14(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,(r6),-108(fp)
+	bicl3	#-65536,r2,-112(fp)
+	mull3	r0,-108(fp),-100(fp)
+	mull2	r3,-108(fp)
+	mull3	r3,-112(fp),-104(fp)
+	mull2	r0,-112(fp)
+	addl3	-100(fp),-104(fp),r0
+	bicl3	#0,r0,-100(fp)
+	cmpl	-100(fp),-104(fp)
+	bgequ	noname.69
+	addl2	#65536,-112(fp)
+noname.69:
+	movzwl	-98(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-112(fp)
+	bicl3	#-65536,-100(fp),r0
+	ashl	#16,r0,-104(fp)
+	addl3	-104(fp),-108(fp),r0
+	bicl3	#0,r0,-108(fp)
+	cmpl	-108(fp),-104(fp)
+	bgequ	noname.70
+	incl	-112(fp)
+noname.70:
+	movl	-108(fp),r1
+	movl	-112(fp),r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.71
+	incl	r2
+noname.71:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.72
+	incl	r10
+noname.72:
+
+	movzwl	6(r6),r2
+	bicl3	#-65536,8(r7),r3
+	movzwl	10(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,4(r6),-124(fp)
+	bicl3	#-65536,r2,-128(fp)
+	mull3	r0,-124(fp),-116(fp)
+	mull2	r3,-124(fp)
+	mull3	r3,-128(fp),-120(fp)
+	mull2	r0,-128(fp)
+	addl3	-116(fp),-120(fp),r0
+	bicl3	#0,r0,-116(fp)
+	cmpl	-116(fp),-120(fp)
+	bgequ	noname.73
+	addl2	#65536,-128(fp)
+noname.73:
+	movzwl	-114(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-128(fp)
+	bicl3	#-65536,-116(fp),r0
+	ashl	#16,r0,-120(fp)
+	addl3	-120(fp),-124(fp),r0
+	bicl3	#0,r0,-124(fp)
+	cmpl	-124(fp),-120(fp)
+	bgequ	noname.74
+	incl	-128(fp)
+noname.74:
+	movl	-124(fp),r1
+	movl	-128(fp),r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.75
+	incl	r2
+noname.75:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.76
+	incl	r10
+noname.76:
+
+	movzwl	10(r6),r2
+	bicl3	#-65536,4(r7),r3
+	movzwl	6(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,8(r6),-140(fp)
+	bicl3	#-65536,r2,-144(fp)
+	mull3	r0,-140(fp),-132(fp)
+	mull2	r3,-140(fp)
+	mull3	r3,-144(fp),-136(fp)
+	mull2	r0,-144(fp)
+	addl3	-132(fp),-136(fp),r0
+	bicl3	#0,r0,-132(fp)
+	cmpl	-132(fp),-136(fp)
+	bgequ	noname.77
+	addl2	#65536,-144(fp)
+noname.77:
+	movzwl	-130(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-144(fp)
+	bicl3	#-65536,-132(fp),r0
+	ashl	#16,r0,-136(fp)
+	addl3	-136(fp),-140(fp),r0
+	bicl3	#0,r0,-140(fp)
+	cmpl	-140(fp),-136(fp)
+	bgequ	noname.78
+	incl	-144(fp)
+noname.78:
+	movl	-140(fp),r1
+	movl	-144(fp),r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.79
+	incl	r2
+noname.79:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.80
+	incl	r10
+noname.80:
+
+	movzwl	14(r6),r2
+	bicl3	#-65536,(r7),r3
+	movzwl	2(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,12(r6),-156(fp)
+	bicl3	#-65536,r2,-160(fp)
+	mull3	r0,-156(fp),-148(fp)
+	mull2	r3,-156(fp)
+	mull3	r3,-160(fp),-152(fp)
+	mull2	r0,-160(fp)
+	addl3	-148(fp),-152(fp),r0
+	bicl3	#0,r0,-148(fp)
+	cmpl	-148(fp),-152(fp)
+	bgequ	noname.81
+	addl2	#65536,-160(fp)
+noname.81:
+	movzwl	-146(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-160(fp)
+	bicl3	#-65536,-148(fp),r0
+	ashl	#16,r0,-152(fp)
+	addl3	-152(fp),-156(fp),r0
+	bicl3	#0,r0,-156(fp)
+	cmpl	-156(fp),-152(fp)
+	bgequ	noname.82
+	incl	-160(fp)
+noname.82:
+	movl	-156(fp),r1
+	movl	-160(fp),r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.83
+	incl	r2
+noname.83:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.84
+	incl	r10
+noname.84:
+
+	movl	r9,12(r11)
+
+	clrl	r9
+
+	movzwl	18(r6),r2
+	bicl3	#-65536,(r7),r3
+	movzwl	2(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,16(r6),-172(fp)
+	bicl3	#-65536,r2,-176(fp)
+	mull3	r0,-172(fp),-164(fp)
+	mull2	r3,-172(fp)
+	mull3	r3,-176(fp),-168(fp)
+	mull2	r0,-176(fp)
+	addl3	-164(fp),-168(fp),r0
+	bicl3	#0,r0,-164(fp)
+	cmpl	-164(fp),-168(fp)
+	bgequ	noname.85
+	addl2	#65536,-176(fp)
+noname.85:
+	movzwl	-162(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-176(fp)
+	bicl3	#-65536,-164(fp),r0
+	ashl	#16,r0,-168(fp)
+	addl3	-168(fp),-172(fp),r0
+	bicl3	#0,r0,-172(fp)
+	cmpl	-172(fp),-168(fp)
+	bgequ	noname.86
+	incl	-176(fp)
+noname.86:
+	movl	-172(fp),r1
+	movl	-176(fp),r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.87
+	incl	r2
+noname.87:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.88
+	incl	r9
+noname.88:
+
+	movzwl	14(r6),r2
+	bicl3	#-65536,4(r7),r3
+	movzwl	6(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,12(r6),-188(fp)
+	bicl3	#-65536,r2,-192(fp)
+	mull3	r0,-188(fp),-180(fp)
+	mull2	r3,-188(fp)
+	mull3	r3,-192(fp),-184(fp)
+	mull2	r0,-192(fp)
+	addl3	-180(fp),-184(fp),r0
+	bicl3	#0,r0,-180(fp)
+	cmpl	-180(fp),-184(fp)
+	bgequ	noname.89
+	addl2	#65536,-192(fp)
+noname.89:
+	movzwl	-178(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-192(fp)
+	bicl3	#-65536,-180(fp),r0
+	ashl	#16,r0,-184(fp)
+	addl3	-184(fp),-188(fp),r0
+	bicl3	#0,r0,-188(fp)
+	cmpl	-188(fp),-184(fp)
+	bgequ	noname.90
+	incl	-192(fp)
+noname.90:
+	movl	-188(fp),r1
+	movl	-192(fp),r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.91
+	incl	r2
+noname.91:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.92
+	incl	r9
+noname.92:
+
+	movzwl	10(r6),r2
+	bicl3	#-65536,8(r7),r3
+	movzwl	10(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,8(r6),-204(fp)
+	bicl3	#-65536,r2,-208(fp)
+	mull3	r0,-204(fp),-196(fp)
+	mull2	r3,-204(fp)
+	mull3	r3,-208(fp),-200(fp)
+	mull2	r0,-208(fp)
+	addl3	-196(fp),-200(fp),r0
+	bicl3	#0,r0,-196(fp)
+	cmpl	-196(fp),-200(fp)
+	bgequ	noname.93
+	addl2	#65536,-208(fp)
+noname.93:
+	movzwl	-194(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-208(fp)
+	bicl3	#-65536,-196(fp),r0
+	ashl	#16,r0,-200(fp)
+	addl3	-200(fp),-204(fp),r0
+	bicl3	#0,r0,-204(fp)
+	cmpl	-204(fp),-200(fp)
+	bgequ	noname.94
+	incl	-208(fp)
+noname.94:
+	movl	-204(fp),r1
+	movl	-208(fp),r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.95
+	incl	r2
+noname.95:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.96
+	incl	r9
+noname.96:
+
+	movzwl	6(r6),r2
+	bicl3	#-65536,12(r7),r3
+	movzwl	14(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,4(r6),-220(fp)
+	bicl3	#-65536,r2,-224(fp)
+	mull3	r0,-220(fp),-212(fp)
+	mull2	r3,-220(fp)
+	mull3	r3,-224(fp),-216(fp)
+	mull2	r0,-224(fp)
+	addl3	-212(fp),-216(fp),r0
+	bicl3	#0,r0,-212(fp)
+	cmpl	-212(fp),-216(fp)
+	bgequ	noname.97
+	addl2	#65536,-224(fp)
+noname.97:
+	movzwl	-210(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-224(fp)
+	bicl3	#-65536,-212(fp),r0
+	ashl	#16,r0,-216(fp)
+	addl3	-216(fp),-220(fp),r0
+	bicl3	#0,r0,-220(fp)
+	cmpl	-220(fp),-216(fp)
+	bgequ	noname.98
+	incl	-224(fp)
+noname.98:
+	movl	-220(fp),r1
+	movl	-224(fp),r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.99
+	incl	r2
+noname.99:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.100
+	incl	r9
+noname.100:
+
+	movzwl	2(r6),r2
+	bicl3	#-65536,16(r7),r3
+	movzwl	18(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,(r6),-236(fp)
+	bicl3	#-65536,r2,-240(fp)
+	mull3	r0,-236(fp),-228(fp)
+	mull2	r3,-236(fp)
+	mull3	r3,-240(fp),-232(fp)
+	mull2	r0,-240(fp)
+	addl3	-228(fp),-232(fp),r0
+	bicl3	#0,r0,-228(fp)
+	cmpl	-228(fp),-232(fp)
+	bgequ	noname.101
+	addl2	#65536,-240(fp)
+noname.101:
+	movzwl	-226(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-240(fp)
+	bicl3	#-65536,-228(fp),r0
+	ashl	#16,r0,-232(fp)
+	addl3	-232(fp),-236(fp),r0
+	bicl3	#0,r0,-236(fp)
+	cmpl	-236(fp),-232(fp)
+	bgequ	noname.102
+	incl	-240(fp)
+noname.102:
+	movl	-236(fp),r1
+	movl	-240(fp),r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.103
+	incl	r2
+noname.103:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.104
+	incl	r9
+noname.104:
+
+	movl	r8,16(r11)
+
+	clrl	r8
+
+	movzwl	2(r6),r2
+	bicl3	#-65536,20(r7),r3
+	movzwl	22(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,(r6),-252(fp)
+	bicl3	#-65536,r2,-256(fp)
+	mull3	r0,-252(fp),-244(fp)
+	mull2	r3,-252(fp)
+	mull3	r3,-256(fp),-248(fp)
+	mull2	r0,-256(fp)
+	addl3	-244(fp),-248(fp),r0
+	bicl3	#0,r0,-244(fp)
+	cmpl	-244(fp),-248(fp)
+	bgequ	noname.105
+	addl2	#65536,-256(fp)
+noname.105:
+	movzwl	-242(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-256(fp)
+	bicl3	#-65536,-244(fp),r0
+	ashl	#16,r0,-248(fp)
+	addl3	-248(fp),-252(fp),r0
+	bicl3	#0,r0,-252(fp)
+	cmpl	-252(fp),-248(fp)
+	bgequ	noname.106
+	incl	-256(fp)
+noname.106:
+	movl	-252(fp),r1
+	movl	-256(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.107
+	incl	r2
+noname.107:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.108
+	incl	r8
+noname.108:
+
+	movzwl	6(r6),r2
+	bicl3	#-65536,16(r7),r3
+	movzwl	18(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,4(r6),-268(fp)
+	bicl3	#-65536,r2,-272(fp)
+	mull3	r0,-268(fp),-260(fp)
+	mull2	r3,-268(fp)
+	mull3	r3,-272(fp),-264(fp)
+	mull2	r0,-272(fp)
+	addl3	-260(fp),-264(fp),r0
+	bicl3	#0,r0,-260(fp)
+	cmpl	-260(fp),-264(fp)
+	bgequ	noname.109
+	addl2	#65536,-272(fp)
+noname.109:
+	movzwl	-258(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-272(fp)
+	bicl3	#-65536,-260(fp),r0
+	ashl	#16,r0,-264(fp)
+	addl3	-264(fp),-268(fp),r0
+	bicl3	#0,r0,-268(fp)
+	cmpl	-268(fp),-264(fp)
+	bgequ	noname.110
+	incl	-272(fp)
+noname.110:
+	movl	-268(fp),r1
+	movl	-272(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.111
+	incl	r2
+noname.111:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.112
+	incl	r8
+noname.112:
+
+	movzwl	10(r6),r2
+	bicl3	#-65536,12(r7),r3
+	movzwl	14(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,8(r6),-284(fp)
+	bicl3	#-65536,r2,-288(fp)
+	mull3	r0,-284(fp),-276(fp)
+	mull2	r3,-284(fp)
+	mull3	r3,-288(fp),-280(fp)
+	mull2	r0,-288(fp)
+	addl3	-276(fp),-280(fp),r0
+	bicl3	#0,r0,-276(fp)
+	cmpl	-276(fp),-280(fp)
+	bgequ	noname.113
+	addl2	#65536,-288(fp)
+noname.113:
+	movzwl	-274(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-288(fp)
+	bicl3	#-65536,-276(fp),r0
+	ashl	#16,r0,-280(fp)
+	addl3	-280(fp),-284(fp),r0
+	bicl3	#0,r0,-284(fp)
+	cmpl	-284(fp),-280(fp)
+	bgequ	noname.114
+	incl	-288(fp)
+noname.114:
+	movl	-284(fp),r1
+	movl	-288(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.115
+	incl	r2
+noname.115:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.116
+	incl	r8
+noname.116:
+
+	movzwl	14(r6),r2
+	bicl3	#-65536,8(r7),r3
+	movzwl	10(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,12(r6),-300(fp)
+	bicl3	#-65536,r2,-304(fp)
+	mull3	r0,-300(fp),-292(fp)
+	mull2	r3,-300(fp)
+	mull3	r3,-304(fp),-296(fp)
+	mull2	r0,-304(fp)
+	addl3	-292(fp),-296(fp),r0
+	bicl3	#0,r0,-292(fp)
+	cmpl	-292(fp),-296(fp)
+	bgequ	noname.117
+	addl2	#65536,-304(fp)
+noname.117:
+	movzwl	-290(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-304(fp)
+	bicl3	#-65536,-292(fp),r0
+	ashl	#16,r0,-296(fp)
+	addl3	-296(fp),-300(fp),r0
+	bicl3	#0,r0,-300(fp)
+	cmpl	-300(fp),-296(fp)
+	bgequ	noname.118
+	incl	-304(fp)
+noname.118:
+	movl	-300(fp),r1
+	movl	-304(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.119
+	incl	r2
+noname.119:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.120
+	incl	r8
+noname.120:
+
+	movzwl	18(r6),r2
+	bicl3	#-65536,4(r7),r3
+	movzwl	6(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,16(r6),-316(fp)
+	bicl3	#-65536,r2,-320(fp)
+	mull3	r0,-316(fp),-308(fp)
+	mull2	r3,-316(fp)
+	mull3	r3,-320(fp),-312(fp)
+	mull2	r0,-320(fp)
+	addl3	-308(fp),-312(fp),r0
+	bicl3	#0,r0,-308(fp)
+	cmpl	-308(fp),-312(fp)
+	bgequ	noname.121
+	addl2	#65536,-320(fp)
+noname.121:
+	movzwl	-306(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-320(fp)
+	bicl3	#-65536,-308(fp),r0
+	ashl	#16,r0,-312(fp)
+	addl3	-312(fp),-316(fp),r0
+	bicl3	#0,r0,-316(fp)
+	cmpl	-316(fp),-312(fp)
+	bgequ	noname.122
+	incl	-320(fp)
+noname.122:
+	movl	-316(fp),r1
+	movl	-320(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.123
+	incl	r2
+
+noname.123:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.124
+	incl	r8
+noname.124:
+
+	movzwl	22(r6),r2
+	bicl3	#-65536,(r7),r3
+	movzwl	2(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,20(r6),-332(fp)
+	bicl3	#-65536,r2,-336(fp)
+	mull3	r0,-332(fp),-324(fp)
+	mull2	r3,-332(fp)
+	mull3	r3,-336(fp),-328(fp)
+	mull2	r0,-336(fp)
+	addl3	-324(fp),-328(fp),r0
+	bicl3	#0,r0,-324(fp)
+	cmpl	-324(fp),-328(fp)
+	bgequ	noname.125
+	addl2	#65536,-336(fp)
+noname.125:
+	movzwl	-322(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-336(fp)
+	bicl3	#-65536,-324(fp),r0
+	ashl	#16,r0,-328(fp)
+	addl3	-328(fp),-332(fp),r0
+	bicl3	#0,r0,-332(fp)
+	cmpl	-332(fp),-328(fp)
+	bgequ	noname.126
+	incl	-336(fp)
+noname.126:
+	movl	-332(fp),r1
+	movl	-336(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.127
+	incl	r2
+noname.127:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.128
+	incl	r8
+noname.128:
+
+	movl	r10,20(r11)
+
+	clrl	r10
+
+	movzwl	26(r6),r2
+	bicl3	#-65536,(r7),r3
+	movzwl	2(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,24(r6),-348(fp)
+	bicl3	#-65536,r2,-352(fp)
+	mull3	r0,-348(fp),-340(fp)
+	mull2	r3,-348(fp)
+	mull3	r3,-352(fp),-344(fp)
+	mull2	r0,-352(fp)
+	addl3	-340(fp),-344(fp),r0
+	bicl3	#0,r0,-340(fp)
+	cmpl	-340(fp),-344(fp)
+	bgequ	noname.129
+	addl2	#65536,-352(fp)
+noname.129:
+	movzwl	-338(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-352(fp)
+	bicl3	#-65536,-340(fp),r0
+	ashl	#16,r0,-344(fp)
+	addl3	-344(fp),-348(fp),r0
+	bicl3	#0,r0,-348(fp)
+	cmpl	-348(fp),-344(fp)
+	bgequ	noname.130
+	incl	-352(fp)
+noname.130:
+	movl	-348(fp),r1
+	movl	-352(fp),r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.131
+	incl	r2
+noname.131:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.132
+	incl	r10
+noname.132:
+
+	movzwl	22(r6),r2
+	bicl3	#-65536,4(r7),r3
+	movzwl	6(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,20(r6),-364(fp)
+	bicl3	#-65536,r2,-368(fp)
+	mull3	r0,-364(fp),-356(fp)
+	mull2	r3,-364(fp)
+	mull3	r3,-368(fp),-360(fp)
+	mull2	r0,-368(fp)
+	addl3	-356(fp),-360(fp),r0
+	bicl3	#0,r0,-356(fp)
+	cmpl	-356(fp),-360(fp)
+	bgequ	noname.133
+	addl2	#65536,-368(fp)
+noname.133:
+	movzwl	-354(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-368(fp)
+	bicl3	#-65536,-356(fp),r0
+	ashl	#16,r0,-360(fp)
+	addl3	-360(fp),-364(fp),r0
+	bicl3	#0,r0,-364(fp)
+	cmpl	-364(fp),-360(fp)
+	bgequ	noname.134
+	incl	-368(fp)
+noname.134:
+	movl	-364(fp),r1
+	movl	-368(fp),r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.135
+	incl	r2
+noname.135:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.136
+	incl	r10
+noname.136:
+
+	movzwl	18(r6),r2
+	bicl3	#-65536,8(r7),r3
+	movzwl	10(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,16(r6),-380(fp)
+	bicl3	#-65536,r2,-384(fp)
+	mull3	r0,-380(fp),-372(fp)
+	mull2	r3,-380(fp)
+	mull3	r3,-384(fp),-376(fp)
+	mull2	r0,-384(fp)
+	addl3	-372(fp),-376(fp),r0
+	bicl3	#0,r0,-372(fp)
+	cmpl	-372(fp),-376(fp)
+	bgequ	noname.137
+	addl2	#65536,-384(fp)
+noname.137:
+	movzwl	-370(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-384(fp)
+	bicl3	#-65536,-372(fp),r0
+	ashl	#16,r0,-376(fp)
+	addl3	-376(fp),-380(fp),r0
+	bicl3	#0,r0,-380(fp)
+	cmpl	-380(fp),-376(fp)
+	bgequ	noname.138
+	incl	-384(fp)
+noname.138:
+	movl	-380(fp),r1
+	movl	-384(fp),r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.139
+	incl	r2
+noname.139:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.140
+	incl	r10
+noname.140:
+
+	movzwl	14(r6),r2
+	bicl3	#-65536,12(r7),r3
+	movzwl	14(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,12(r6),-396(fp)
+	bicl3	#-65536,r2,-400(fp)
+	mull3	r0,-396(fp),-388(fp)
+	mull2	r3,-396(fp)
+	mull3	r3,-400(fp),-392(fp)
+	mull2	r0,-400(fp)
+	addl3	-388(fp),-392(fp),r0
+	bicl3	#0,r0,-388(fp)
+	cmpl	-388(fp),-392(fp)
+	bgequ	noname.141
+	addl2	#65536,-400(fp)
+noname.141:
+	movzwl	-386(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-400(fp)
+	bicl3	#-65536,-388(fp),r0
+	ashl	#16,r0,-392(fp)
+	addl3	-392(fp),-396(fp),r0
+	bicl3	#0,r0,-396(fp)
+	cmpl	-396(fp),-392(fp)
+	bgequ	noname.142
+	incl	-400(fp)
+noname.142:
+	movl	-396(fp),r1
+	movl	-400(fp),r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.143
+	incl	r2
+noname.143:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.144
+	incl	r10
+noname.144:
+
+	movzwl	10(r6),r2
+	bicl3	#-65536,16(r7),r3
+	movzwl	18(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,8(r6),-412(fp)
+	bicl3	#-65536,r2,-416(fp)
+	mull3	r0,-412(fp),-404(fp)
+	mull2	r3,-412(fp)
+	mull3	r3,-416(fp),-408(fp)
+	mull2	r0,-416(fp)
+	addl3	-404(fp),-408(fp),r0
+	bicl3	#0,r0,-404(fp)
+	cmpl	-404(fp),-408(fp)
+	bgequ	noname.145
+	addl2	#65536,-416(fp)
+noname.145:
+	movzwl	-402(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-416(fp)
+	bicl3	#-65536,-404(fp),r0
+	ashl	#16,r0,-408(fp)
+	addl3	-408(fp),-412(fp),r0
+	bicl3	#0,r0,-412(fp)
+	cmpl	-412(fp),-408(fp)
+	bgequ	noname.146
+	incl	-416(fp)
+noname.146:
+	movl	-412(fp),r1
+	movl	-416(fp),r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.147
+	incl	r2
+noname.147:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.148
+	incl	r10
+noname.148:
+
+	movzwl	6(r6),r2
+	bicl3	#-65536,20(r7),r3
+	movzwl	22(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,4(r6),-428(fp)
+	bicl3	#-65536,r2,-432(fp)
+	mull3	r0,-428(fp),-420(fp)
+	mull2	r3,-428(fp)
+	mull3	r3,-432(fp),-424(fp)
+	mull2	r0,-432(fp)
+	addl3	-420(fp),-424(fp),r0
+	bicl3	#0,r0,-420(fp)
+	cmpl	-420(fp),-424(fp)
+	bgequ	noname.149
+	addl2	#65536,-432(fp)
+noname.149:
+	movzwl	-418(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-432(fp)
+	bicl3	#-65536,-420(fp),r0
+	ashl	#16,r0,-424(fp)
+	addl3	-424(fp),-428(fp),r0
+	bicl3	#0,r0,-428(fp)
+	cmpl	-428(fp),-424(fp)
+	bgequ	noname.150
+	incl	-432(fp)
+noname.150:
+	movl	-428(fp),r1
+	movl	-432(fp),r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.151
+	incl	r2
+noname.151:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.152
+	incl	r10
+noname.152:
+
+	movzwl	2(r6),r2
+	bicl3	#-65536,24(r7),r3
+	movzwl	26(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,(r6),-444(fp)
+	bicl3	#-65536,r2,-448(fp)
+	mull3	r0,-444(fp),-436(fp)
+	mull2	r3,-444(fp)
+	mull3	r3,-448(fp),-440(fp)
+	mull2	r0,-448(fp)
+	addl3	-436(fp),-440(fp),r0
+	bicl3	#0,r0,-436(fp)
+	cmpl	-436(fp),-440(fp)
+	bgequ	noname.153
+	addl2	#65536,-448(fp)
+noname.153:
+	movzwl	-434(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-448(fp)
+	bicl3	#-65536,-436(fp),r0
+	ashl	#16,r0,-440(fp)
+	addl3	-440(fp),-444(fp),r0
+	bicl3	#0,r0,-444(fp)
+	cmpl	-444(fp),-440(fp)
+	bgequ	noname.154
+	incl	-448(fp)
+noname.154:
+	movl	-444(fp),r1
+	movl	-448(fp),r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.155
+	incl	r2
+noname.155:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.156
+	incl	r10
+noname.156:
+
+	movl	r9,24(r11)
+
+	clrl	r9
+
+	movzwl	2(r6),r2
+	bicl3	#-65536,28(r7),r3
+	movzwl	30(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,(r6),-460(fp)
+	bicl3	#-65536,r2,-464(fp)
+	mull3	r0,-460(fp),-452(fp)
+	mull2	r3,-460(fp)
+	mull3	r3,-464(fp),-456(fp)
+	mull2	r0,-464(fp)
+	addl3	-452(fp),-456(fp),r0
+	bicl3	#0,r0,-452(fp)
+	cmpl	-452(fp),-456(fp)
+	bgequ	noname.157
+	addl2	#65536,-464(fp)
+noname.157:
+	movzwl	-450(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-464(fp)
+	bicl3	#-65536,-452(fp),r0
+	ashl	#16,r0,-456(fp)
+	addl3	-456(fp),-460(fp),r0
+	bicl3	#0,r0,-460(fp)
+	cmpl	-460(fp),-456(fp)
+	bgequ	noname.158
+	incl	-464(fp)
+noname.158:
+	movl	-460(fp),r1
+	movl	-464(fp),r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.159
+	incl	r2
+noname.159:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.160
+	incl	r9
+noname.160:
+
+	movzwl	6(r6),r2
+	bicl3	#-65536,24(r7),r3
+	movzwl	26(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,4(r6),-476(fp)
+	bicl3	#-65536,r2,-480(fp)
+	mull3	r0,-476(fp),-468(fp)
+	mull2	r3,-476(fp)
+	mull3	r3,-480(fp),-472(fp)
+	mull2	r0,-480(fp)
+	addl3	-468(fp),-472(fp),r0
+	bicl3	#0,r0,-468(fp)
+	cmpl	-468(fp),-472(fp)
+	bgequ	noname.161
+	addl2	#65536,-480(fp)
+noname.161:
+	movzwl	-466(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-480(fp)
+	bicl3	#-65536,-468(fp),r0
+	ashl	#16,r0,-472(fp)
+	addl3	-472(fp),-476(fp),r0
+	bicl3	#0,r0,-476(fp)
+	cmpl	-476(fp),-472(fp)
+	bgequ	noname.162
+	incl	-480(fp)
+noname.162:
+	movl	-476(fp),r1
+	movl	-480(fp),r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.163
+	incl	r2
+noname.163:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.164
+	incl	r9
+noname.164:
+
+	movzwl	10(r6),r2
+	bicl3	#-65536,20(r7),r3
+	movzwl	22(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,8(r6),-492(fp)
+	bicl3	#-65536,r2,-496(fp)
+	mull3	r0,-492(fp),-484(fp)
+	mull2	r3,-492(fp)
+	mull3	r3,-496(fp),-488(fp)
+	mull2	r0,-496(fp)
+	addl3	-484(fp),-488(fp),r0
+	bicl3	#0,r0,-484(fp)
+	cmpl	-484(fp),-488(fp)
+	bgequ	noname.165
+	addl2	#65536,-496(fp)
+noname.165:
+	movzwl	-482(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-496(fp)
+	bicl3	#-65536,-484(fp),r0
+	ashl	#16,r0,-488(fp)
+	addl3	-488(fp),-492(fp),r0
+	bicl3	#0,r0,-492(fp)
+	cmpl	-492(fp),-488(fp)
+	bgequ	noname.166
+	incl	-496(fp)
+noname.166:
+	movl	-492(fp),r1
+	movl	-496(fp),r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.167
+	incl	r2
+noname.167:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.168
+	incl	r9
+noname.168:
+
+	movzwl	14(r6),r2
+	bicl3	#-65536,16(r7),r3
+	movzwl	18(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,12(r6),-508(fp)
+	bicl3	#-65536,r2,-512(fp)
+	mull3	r0,-508(fp),-500(fp)
+	mull2	r3,-508(fp)
+	mull3	r3,-512(fp),-504(fp)
+	mull2	r0,-512(fp)
+	addl3	-500(fp),-504(fp),r0
+	bicl3	#0,r0,-500(fp)
+	cmpl	-500(fp),-504(fp)
+	bgequ	noname.169
+	addl2	#65536,-512(fp)
+noname.169:
+	movzwl	-498(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-512(fp)
+	bicl3	#-65536,-500(fp),r0
+	ashl	#16,r0,-504(fp)
+	addl3	-504(fp),-508(fp),r0
+	bicl3	#0,r0,-508(fp)
+	cmpl	-508(fp),-504(fp)
+	bgequ	noname.170
+	incl	-512(fp)
+noname.170:
+	movl	-508(fp),r1
+	movl	-512(fp),r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.171
+	incl	r2
+noname.171:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.172
+	incl	r9
+noname.172:
+
+	movzwl	18(r6),r2
+	bicl3	#-65536,12(r7),r3
+	movzwl	14(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,16(r6),-524(fp)
+	bicl3	#-65536,r2,-528(fp)
+	mull3	r0,-524(fp),-516(fp)
+	mull2	r3,-524(fp)
+	mull3	r3,-528(fp),-520(fp)
+	mull2	r0,-528(fp)
+	addl3	-516(fp),-520(fp),r0
+	bicl3	#0,r0,-516(fp)
+	cmpl	-516(fp),-520(fp)
+	bgequ	noname.173
+	addl2	#65536,-528(fp)
+noname.173:
+	movzwl	-514(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-528(fp)
+	bicl3	#-65536,-516(fp),r0
+	ashl	#16,r0,-520(fp)
+	addl3	-520(fp),-524(fp),r0
+	bicl3	#0,r0,-524(fp)
+	cmpl	-524(fp),-520(fp)
+	bgequ	noname.174
+	incl	-528(fp)
+noname.174:
+	movl	-524(fp),r1
+	movl	-528(fp),r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.175
+	incl	r2
+noname.175:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.176
+	incl	r9
+noname.176:
+
+	movzwl	22(r6),r2
+	bicl3	#-65536,8(r7),r3
+	movzwl	10(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,20(r6),-540(fp)
+	bicl3	#-65536,r2,-544(fp)
+	mull3	r0,-540(fp),-532(fp)
+	mull2	r3,-540(fp)
+	mull3	r3,-544(fp),-536(fp)
+	mull2	r0,-544(fp)
+	addl3	-532(fp),-536(fp),r0
+	bicl3	#0,r0,-532(fp)
+	cmpl	-532(fp),-536(fp)
+	bgequ	noname.177
+	addl2	#65536,-544(fp)
+noname.177:
+	movzwl	-530(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-544(fp)
+	bicl3	#-65536,-532(fp),r0
+	ashl	#16,r0,-536(fp)
+	addl3	-536(fp),-540(fp),r0
+	bicl3	#0,r0,-540(fp)
+	cmpl	-540(fp),-536(fp)
+	bgequ	noname.178
+	incl	-544(fp)
+noname.178:
+	movl	-540(fp),r1
+	movl	-544(fp),r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.179
+	incl	r2
+noname.179:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.180
+	incl	r9
+noname.180:
+
+	movzwl	26(r6),r2
+	bicl3	#-65536,4(r7),r3
+	movzwl	6(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,24(r6),-556(fp)
+	bicl3	#-65536,r2,-560(fp)
+	mull3	r0,-556(fp),-548(fp)
+	mull2	r3,-556(fp)
+	mull3	r3,-560(fp),-552(fp)
+	mull2	r0,-560(fp)
+	addl3	-548(fp),-552(fp),r0
+	bicl3	#0,r0,-548(fp)
+	cmpl	-548(fp),-552(fp)
+	bgequ	noname.181
+	addl2	#65536,-560(fp)
+noname.181:
+	movzwl	-546(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-560(fp)
+	bicl3	#-65536,-548(fp),r0
+	ashl	#16,r0,-552(fp)
+	addl3	-552(fp),-556(fp),r0
+	bicl3	#0,r0,-556(fp)
+	cmpl	-556(fp),-552(fp)
+	bgequ	noname.182
+	incl	-560(fp)
+noname.182:
+	movl	-556(fp),r1
+	movl	-560(fp),r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.183
+	incl	r2
+noname.183:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.184
+	incl	r9
+noname.184:
+
+	movzwl	30(r6),r2
+	bicl3	#-65536,(r7),r3
+	movzwl	2(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,28(r6),-572(fp)
+	bicl3	#-65536,r2,-576(fp)
+	mull3	r0,-572(fp),-564(fp)
+	mull2	r3,-572(fp)
+	mull3	r3,-576(fp),-568(fp)
+	mull2	r0,-576(fp)
+	addl3	-564(fp),-568(fp),r0
+	bicl3	#0,r0,-564(fp)
+	cmpl	-564(fp),-568(fp)
+	bgequ	noname.185
+	addl2	#65536,-576(fp)
+noname.185:
+	movzwl	-562(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-576(fp)
+	bicl3	#-65536,-564(fp),r0
+	ashl	#16,r0,-568(fp)
+	addl3	-568(fp),-572(fp),r0
+	bicl3	#0,r0,-572(fp)
+	cmpl	-572(fp),-568(fp)
+	bgequ	noname.186
+	incl	-576(fp)
+noname.186:
+	movl	-572(fp),r1
+	movl	-576(fp),r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.187
+	incl	r2
+noname.187:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.188
+	incl	r9
+noname.188:
+
+	movl	r8,28(r11)
+
+	clrl	r8
+
+	movzwl	30(r6),r2
+	bicl3	#-65536,4(r7),r3
+	movzwl	6(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,28(r6),-588(fp)
+	bicl3	#-65536,r2,-592(fp)
+	mull3	r0,-588(fp),-580(fp)
+	mull2	r3,-588(fp)
+	mull3	r3,-592(fp),-584(fp)
+	mull2	r0,-592(fp)
+	addl3	-580(fp),-584(fp),r0
+	bicl3	#0,r0,-580(fp)
+	cmpl	-580(fp),-584(fp)
+	bgequ	noname.189
+	addl2	#65536,-592(fp)
+noname.189:
+	movzwl	-578(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-592(fp)
+	bicl3	#-65536,-580(fp),r0
+	ashl	#16,r0,-584(fp)
+	addl3	-584(fp),-588(fp),r0
+	bicl3	#0,r0,-588(fp)
+	cmpl	-588(fp),-584(fp)
+	bgequ	noname.190
+	incl	-592(fp)
+noname.190:
+	movl	-588(fp),r1
+	movl	-592(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.191
+	incl	r2
+noname.191:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.192
+	incl	r8
+noname.192:
+
+	movzwl	26(r6),r2
+	bicl3	#-65536,8(r7),r3
+	movzwl	10(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,24(r6),-604(fp)
+	bicl3	#-65536,r2,-608(fp)
+	mull3	r0,-604(fp),-596(fp)
+	mull2	r3,-604(fp)
+	mull3	r3,-608(fp),-600(fp)
+	mull2	r0,-608(fp)
+	addl3	-596(fp),-600(fp),r0
+	bicl3	#0,r0,-596(fp)
+	cmpl	-596(fp),-600(fp)
+	bgequ	noname.193
+	addl2	#65536,-608(fp)
+noname.193:
+	movzwl	-594(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-608(fp)
+	bicl3	#-65536,-596(fp),r0
+	ashl	#16,r0,-600(fp)
+	addl3	-600(fp),-604(fp),r0
+	bicl3	#0,r0,-604(fp)
+	cmpl	-604(fp),-600(fp)
+	bgequ	noname.194
+	incl	-608(fp)
+noname.194:
+	movl	-604(fp),r1
+	movl	-608(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.195
+	incl	r2
+noname.195:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.196
+	incl	r8
+noname.196:
+
+	movzwl	22(r6),r2
+	bicl3	#-65536,12(r7),r3
+	movzwl	14(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,20(r6),-620(fp)
+	bicl3	#-65536,r2,-624(fp)
+	mull3	r0,-620(fp),-612(fp)
+	mull2	r3,-620(fp)
+	mull3	r3,-624(fp),-616(fp)
+	mull2	r0,-624(fp)
+	addl3	-612(fp),-616(fp),r0
+	bicl3	#0,r0,-612(fp)
+	cmpl	-612(fp),-616(fp)
+	bgequ	noname.197
+	addl2	#65536,-624(fp)
+noname.197:
+	movzwl	-610(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-624(fp)
+	bicl3	#-65536,-612(fp),r0
+	ashl	#16,r0,-616(fp)
+	addl3	-616(fp),-620(fp),r0
+	bicl3	#0,r0,-620(fp)
+	cmpl	-620(fp),-616(fp)
+	bgequ	noname.198
+	incl	-624(fp)
+noname.198:
+	movl	-620(fp),r1
+	movl	-624(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.199
+	incl	r2
+noname.199:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.200
+	incl	r8
+noname.200:
+
+	movzwl	18(r6),r2
+	bicl3	#-65536,16(r7),r3
+	movzwl	18(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,16(r6),-636(fp)
+	bicl3	#-65536,r2,-640(fp)
+	mull3	r0,-636(fp),-628(fp)
+	mull2	r3,-636(fp)
+	mull3	r3,-640(fp),-632(fp)
+	mull2	r0,-640(fp)
+	addl3	-628(fp),-632(fp),r0
+	bicl3	#0,r0,-628(fp)
+	cmpl	-628(fp),-632(fp)
+	bgequ	noname.201
+	addl2	#65536,-640(fp)
+noname.201:
+	movzwl	-626(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-640(fp)
+	bicl3	#-65536,-628(fp),r0
+	ashl	#16,r0,-632(fp)
+	addl3	-632(fp),-636(fp),r0
+	bicl3	#0,r0,-636(fp)
+	cmpl	-636(fp),-632(fp)
+	bgequ	noname.202
+	incl	-640(fp)
+noname.202:
+	movl	-636(fp),r1
+	movl	-640(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.203
+	incl	r2
+noname.203:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.204
+	incl	r8
+noname.204:
+
+	movzwl	14(r6),r2
+	bicl3	#-65536,20(r7),r3
+	movzwl	22(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,12(r6),-652(fp)
+	bicl3	#-65536,r2,-656(fp)
+	mull3	r0,-652(fp),-644(fp)
+	mull2	r3,-652(fp)
+	mull3	r3,-656(fp),-648(fp)
+	mull2	r0,-656(fp)
+	addl3	-644(fp),-648(fp),r0
+	bicl3	#0,r0,-644(fp)
+	cmpl	-644(fp),-648(fp)
+	bgequ	noname.205
+	addl2	#65536,-656(fp)
+noname.205:
+	movzwl	-642(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-656(fp)
+	bicl3	#-65536,-644(fp),r0
+	ashl	#16,r0,-648(fp)
+	addl3	-648(fp),-652(fp),r0
+	bicl3	#0,r0,-652(fp)
+	cmpl	-652(fp),-648(fp)
+	bgequ	noname.206
+	incl	-656(fp)
+noname.206:
+	movl	-652(fp),r1
+	movl	-656(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.207
+	incl	r2
+noname.207:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.208
+	incl	r8
+noname.208:
+
+	movzwl	10(r6),r2
+	bicl3	#-65536,24(r7),r3
+	movzwl	26(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,8(r6),-668(fp)
+	bicl3	#-65536,r2,-672(fp)
+	mull3	r0,-668(fp),-660(fp)
+	mull2	r3,-668(fp)
+	mull3	r3,-672(fp),-664(fp)
+	mull2	r0,-672(fp)
+	addl3	-660(fp),-664(fp),r0
+	bicl3	#0,r0,-660(fp)
+	cmpl	-660(fp),-664(fp)
+	bgequ	noname.209
+	addl2	#65536,-672(fp)
+noname.209:
+	movzwl	-658(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-672(fp)
+	bicl3	#-65536,-660(fp),r0
+	ashl	#16,r0,-664(fp)
+	addl3	-664(fp),-668(fp),r0
+	bicl3	#0,r0,-668(fp)
+	cmpl	-668(fp),-664(fp)
+	bgequ	noname.210
+	incl	-672(fp)
+noname.210:
+	movl	-668(fp),r1
+	movl	-672(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.211
+	incl	r2
+noname.211:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.212
+	incl	r8
+noname.212:
+
+	movzwl	6(r6),r2
+	bicl3	#-65536,28(r7),r3
+	movzwl	30(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,4(r6),-684(fp)
+	bicl3	#-65536,r2,-688(fp)
+	mull3	r0,-684(fp),-676(fp)
+	mull2	r3,-684(fp)
+	mull3	r3,-688(fp),-680(fp)
+	mull2	r0,-688(fp)
+	addl3	-676(fp),-680(fp),r0
+	bicl3	#0,r0,-676(fp)
+	cmpl	-676(fp),-680(fp)
+	bgequ	noname.213
+	addl2	#65536,-688(fp)
+noname.213:
+	movzwl	-674(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-688(fp)
+	bicl3	#-65536,-676(fp),r0
+	ashl	#16,r0,-680(fp)
+	addl3	-680(fp),-684(fp),r0
+	bicl3	#0,r0,-684(fp)
+	cmpl	-684(fp),-680(fp)
+	bgequ	noname.214
+	incl	-688(fp)
+noname.214:
+	movl	-684(fp),r1
+	movl	-688(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.215
+	incl	r2
+noname.215:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.216
+	incl	r8
+noname.216:
+
+	movl	r10,32(r11)
+
+	clrl	r10
+
+	movzwl	10(r6),r2
+	bicl3	#-65536,28(r7),r3
+	movzwl	30(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,8(r6),-700(fp)
+	bicl3	#-65536,r2,-704(fp)
+	mull3	r0,-700(fp),-692(fp)
+	mull2	r3,-700(fp)
+	mull3	r3,-704(fp),-696(fp)
+	mull2	r0,-704(fp)
+	addl3	-692(fp),-696(fp),r0
+	bicl3	#0,r0,-692(fp)
+	cmpl	-692(fp),-696(fp)
+	bgequ	noname.217
+	addl2	#65536,-704(fp)
+noname.217:
+	movzwl	-690(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-704(fp)
+	bicl3	#-65536,-692(fp),r0
+	ashl	#16,r0,-696(fp)
+	addl3	-696(fp),-700(fp),r0
+	bicl3	#0,r0,-700(fp)
+	cmpl	-700(fp),-696(fp)
+	bgequ	noname.218
+	incl	-704(fp)
+noname.218:
+	movl	-700(fp),r1
+	movl	-704(fp),r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.219
+	incl	r2
+noname.219:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.220
+	incl	r10
+noname.220:
+
+	movzwl	14(r6),r2
+	bicl3	#-65536,24(r7),r3
+	movzwl	26(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,12(r6),-716(fp)
+	bicl3	#-65536,r2,-720(fp)
+	mull3	r0,-716(fp),-708(fp)
+	mull2	r3,-716(fp)
+	mull3	r3,-720(fp),-712(fp)
+	mull2	r0,-720(fp)
+	addl3	-708(fp),-712(fp),r0
+	bicl3	#0,r0,-708(fp)
+	cmpl	-708(fp),-712(fp)
+	bgequ	noname.221
+	addl2	#65536,-720(fp)
+noname.221:
+	movzwl	-706(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-720(fp)
+	bicl3	#-65536,-708(fp),r0
+	ashl	#16,r0,-712(fp)
+	addl3	-712(fp),-716(fp),r0
+	bicl3	#0,r0,-716(fp)
+	cmpl	-716(fp),-712(fp)
+	bgequ	noname.222
+	incl	-720(fp)
+noname.222:
+	movl	-716(fp),r1
+	movl	-720(fp),r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.223
+	incl	r2
+noname.223:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.224
+	incl	r10
+noname.224:
+
+	movzwl	18(r6),r2
+	bicl3	#-65536,20(r7),r3
+	movzwl	22(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,16(r6),-732(fp)
+	bicl3	#-65536,r2,-736(fp)
+	mull3	r0,-732(fp),-724(fp)
+	mull2	r3,-732(fp)
+	mull3	r3,-736(fp),-728(fp)
+	mull2	r0,-736(fp)
+	addl3	-724(fp),-728(fp),r0
+	bicl3	#0,r0,-724(fp)
+	cmpl	-724(fp),-728(fp)
+	bgequ	noname.225
+	addl2	#65536,-736(fp)
+noname.225:
+	movzwl	-722(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-736(fp)
+	bicl3	#-65536,-724(fp),r0
+	ashl	#16,r0,-728(fp)
+	addl3	-728(fp),-732(fp),r0
+	bicl3	#0,r0,-732(fp)
+	cmpl	-732(fp),-728(fp)
+	bgequ	noname.226
+	incl	-736(fp)
+noname.226:
+	movl	-732(fp),r1
+	movl	-736(fp),r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.227
+	incl	r2
+noname.227:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.228
+	incl	r10
+noname.228:
+
+	movzwl	22(r6),r2
+	bicl3	#-65536,16(r7),r3
+	movzwl	18(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,20(r6),-748(fp)
+	bicl3	#-65536,r2,-752(fp)
+	mull3	r0,-748(fp),-740(fp)
+	mull2	r3,-748(fp)
+	mull3	r3,-752(fp),-744(fp)
+	mull2	r0,-752(fp)
+	addl3	-740(fp),-744(fp),r0
+	bicl3	#0,r0,-740(fp)
+	cmpl	-740(fp),-744(fp)
+	bgequ	noname.229
+	addl2	#65536,-752(fp)
+noname.229:
+	movzwl	-738(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-752(fp)
+	bicl3	#-65536,-740(fp),r0
+	ashl	#16,r0,-744(fp)
+	addl3	-744(fp),-748(fp),r0
+	bicl3	#0,r0,-748(fp)
+	cmpl	-748(fp),-744(fp)
+	bgequ	noname.230
+	incl	-752(fp)
+noname.230:
+	movl	-748(fp),r1
+	movl	-752(fp),r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.231
+	incl	r2
+noname.231:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.232
+	incl	r10
+noname.232:
+
+	movzwl	26(r6),r2
+	bicl3	#-65536,12(r7),r3
+	movzwl	14(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,24(r6),-764(fp)
+	bicl3	#-65536,r2,-768(fp)
+	mull3	r0,-764(fp),-756(fp)
+	mull2	r3,-764(fp)
+	mull3	r3,-768(fp),-760(fp)
+	mull2	r0,-768(fp)
+	addl3	-756(fp),-760(fp),r0
+	bicl3	#0,r0,-756(fp)
+	cmpl	-756(fp),-760(fp)
+	bgequ	noname.233
+	addl2	#65536,-768(fp)
+noname.233:
+	movzwl	-754(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-768(fp)
+	bicl3	#-65536,-756(fp),r0
+	ashl	#16,r0,-760(fp)
+	addl3	-760(fp),-764(fp),r0
+	bicl3	#0,r0,-764(fp)
+	cmpl	-764(fp),-760(fp)
+	bgequ	noname.234
+	incl	-768(fp)
+noname.234:
+	movl	-764(fp),r1
+	movl	-768(fp),r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.235
+	incl	r2
+noname.235:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.236
+	incl	r10
+noname.236:
+
+	bicl3	#-65536,28(r6),r3
+	movzwl	30(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,8(r7),r2
+	movzwl	10(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-772(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-776(fp)
+	mull2	r0,r4
+	addl3	-772(fp),-776(fp),r0
+	bicl3	#0,r0,-772(fp)
+	cmpl	-772(fp),-776(fp)
+	bgequ	noname.237
+	addl2	#65536,r4
+noname.237:
+	movzwl	-770(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-772(fp),r0
+	ashl	#16,r0,-776(fp)
+	addl2	-776(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-776(fp)
+	bgequ	noname.238
+	incl	r4
+noname.238:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.239
+	incl	r2
+noname.239:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.240
+	incl	r10
+noname.240:
+
+	movl	r9,36(r11)
+
+	clrl	r9
+
+	bicl3	#-65536,28(r6),r3
+	movzwl	30(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,12(r7),r2
+	movzwl	14(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-780(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-784(fp)
+	mull2	r0,r4
+	addl3	-780(fp),-784(fp),r0
+	bicl3	#0,r0,-780(fp)
+	cmpl	-780(fp),-784(fp)
+	bgequ	noname.241
+	addl2	#65536,r4
+noname.241:
+	movzwl	-778(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-780(fp),r0
+	ashl	#16,r0,-784(fp)
+	addl2	-784(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-784(fp)
+	bgequ	noname.242
+	incl	r4
+noname.242:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.243
+	incl	r2
+noname.243:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.244
+	incl	r9
+noname.244:
+
+	bicl3	#-65536,24(r6),r3
+	movzwl	26(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,16(r7),r2
+	movzwl	18(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-788(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-792(fp)
+	mull2	r0,r4
+	addl3	-788(fp),-792(fp),r0
+	bicl3	#0,r0,-788(fp)
+	cmpl	-788(fp),-792(fp)
+	bgequ	noname.245
+	addl2	#65536,r4
+noname.245:
+	movzwl	-786(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-788(fp),r0
+	ashl	#16,r0,-792(fp)
+	addl2	-792(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-792(fp)
+	bgequ	noname.246
+	incl	r4
+noname.246:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.247
+	incl	r2
+noname.247:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.248
+	incl	r9
+noname.248:
+
+	bicl3	#-65536,20(r6),r3
+	movzwl	22(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,20(r7),r2
+	movzwl	22(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-796(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-800(fp)
+	mull2	r0,r4
+	addl3	-796(fp),-800(fp),r0
+	bicl3	#0,r0,-796(fp)
+	cmpl	-796(fp),-800(fp)
+	bgequ	noname.249
+	addl2	#65536,r4
+noname.249:
+	movzwl	-794(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-796(fp),r0
+	ashl	#16,r0,-800(fp)
+	addl2	-800(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-800(fp)
+	bgequ	noname.250
+	incl	r4
+noname.250:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.251
+	incl	r2
+noname.251:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.252
+	incl	r9
+noname.252:
+
+	bicl3	#-65536,16(r6),r3
+	movzwl	18(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,24(r7),r2
+	movzwl	26(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-804(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-808(fp)
+	mull2	r0,r4
+	addl3	-804(fp),-808(fp),r0
+	bicl3	#0,r0,-804(fp)
+	cmpl	-804(fp),-808(fp)
+	bgequ	noname.253
+	addl2	#65536,r4
+noname.253:
+	movzwl	-802(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-804(fp),r0
+	ashl	#16,r0,-808(fp)
+	addl2	-808(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-808(fp)
+	bgequ	noname.254
+	incl	r4
+noname.254:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.255
+	incl	r2
+noname.255:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.256
+	incl	r9
+noname.256:
+
+	bicl3	#-65536,12(r6),r3
+	movzwl	14(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,28(r7),r2
+	movzwl	30(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-812(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-816(fp)
+	mull2	r0,r4
+	addl3	-812(fp),-816(fp),r0
+	bicl3	#0,r0,-812(fp)
+	cmpl	-812(fp),-816(fp)
+	bgequ	noname.257
+	addl2	#65536,r4
+noname.257:
+	movzwl	-810(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-812(fp),r0
+	ashl	#16,r0,-816(fp)
+	addl2	-816(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-816(fp)
+	bgequ	noname.258
+	incl	r4
+noname.258:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.259
+	incl	r2
+noname.259:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.260
+	incl	r9
+noname.260:
+
+	movl	r8,40(r11)
+
+	clrl	r8
+
+	bicl3	#-65536,16(r6),r3
+	movzwl	18(r6),r2
+	bicl3	#-65536,28(r7),r1
+	movzwl	30(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r4
+	bicl3	#-65536,r2,-828(fp)
+	mull3	r0,r4,-820(fp)
+	mull2	r1,r4
+	mull3	r1,-828(fp),-824(fp)
+	mull2	r0,-828(fp)
+	addl3	-820(fp),-824(fp),r0
+	bicl3	#0,r0,-820(fp)
+	cmpl	-820(fp),-824(fp)
+	bgequ	noname.261
+	addl2	#65536,-828(fp)
+noname.261:
+	movzwl	-818(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-828(fp)
+	bicl3	#-65536,-820(fp),r0
+	ashl	#16,r0,-824(fp)
+	addl2	-824(fp),r4
+	bicl2	#0,r4
+	cmpl	r4,-824(fp)
+	bgequ	noname.262
+	incl	-828(fp)
+noname.262:
+	movl	r4,r1
+	movl	-828(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.263
+	incl	r2
+noname.263:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.264
+	incl	r8
+noname.264:
+
+	movzwl	22(r6),r2
+	bicl3	#-65536,24(r7),r3
+	movzwl	26(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,20(r6),-840(fp)
+	bicl3	#-65536,r2,-844(fp)
+	mull3	r0,-840(fp),-832(fp)
+	mull2	r3,-840(fp)
+	mull3	r3,-844(fp),-836(fp)
+	mull2	r0,-844(fp)
+	addl3	-832(fp),-836(fp),r0
+	bicl3	#0,r0,-832(fp)
+	cmpl	-832(fp),-836(fp)
+	bgequ	noname.265
+	addl2	#65536,-844(fp)
+noname.265:
+	movzwl	-830(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-844(fp)
+	bicl3	#-65536,-832(fp),r0
+	ashl	#16,r0,-836(fp)
+	addl3	-836(fp),-840(fp),r0
+	bicl3	#0,r0,-840(fp)
+	cmpl	-840(fp),-836(fp)
+	bgequ	noname.266
+	incl	-844(fp)
+noname.266:
+	movl	-840(fp),r1
+	movl	-844(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.267
+	incl	r2
+noname.267:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.268
+	incl	r8
+noname.268:
+
+	bicl3	#-65536,24(r6),r3
+	movzwl	26(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,20(r7),r2
+	movzwl	22(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-848(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-852(fp)
+	mull2	r0,r4
+	addl3	-848(fp),-852(fp),r0
+	bicl3	#0,r0,-848(fp)
+	cmpl	-848(fp),-852(fp)
+	bgequ	noname.269
+	addl2	#65536,r4
+noname.269:
+	movzwl	-846(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-848(fp),r0
+	ashl	#16,r0,-852(fp)
+	addl2	-852(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-852(fp)
+	bgequ	noname.270
+	incl	r4
+noname.270:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.271
+	incl	r2
+noname.271:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.272
+	incl	r8
+noname.272:
+
+	bicl3	#-65536,28(r6),r3
+	movzwl	30(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,16(r7),r2
+	movzwl	18(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-856(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-860(fp)
+	mull2	r0,r4
+	addl3	-856(fp),-860(fp),r0
+	bicl3	#0,r0,-856(fp)
+	cmpl	-856(fp),-860(fp)
+	bgequ	noname.273
+	addl2	#65536,r4
+noname.273:
+	movzwl	-854(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-856(fp),r0
+	ashl	#16,r0,-860(fp)
+	addl2	-860(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-860(fp)
+	bgequ	noname.274
+	incl	r4
+noname.274:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.275
+	incl	r2
+noname.275:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.276
+	incl	r8
+noname.276:
+
+	movl	r10,44(r11)
+
+	clrl	r10
+
+	bicl3	#-65536,28(r6),r3
+	movzwl	30(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,20(r7),r2
+	movzwl	22(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-864(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-868(fp)
+	mull2	r0,r4
+	addl3	-864(fp),-868(fp),r0
+	bicl3	#0,r0,-864(fp)
+	cmpl	-864(fp),-868(fp)
+	bgequ	noname.277
+	addl2	#65536,r4
+noname.277:
+	movzwl	-862(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-864(fp),r0
+	ashl	#16,r0,-868(fp)
+	addl2	-868(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-868(fp)
+	bgequ	noname.278
+	incl	r4
+noname.278:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.279
+	incl	r2
+noname.279:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.280
+	incl	r10
+noname.280:
+
+	bicl3	#-65536,24(r6),r3
+	movzwl	26(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,24(r7),r2
+	movzwl	26(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-872(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-876(fp)
+	mull2	r0,r4
+	addl3	-872(fp),-876(fp),r0
+	bicl3	#0,r0,-872(fp)
+	cmpl	-872(fp),-876(fp)
+	bgequ	noname.281
+	addl2	#65536,r4
+noname.281:
+	movzwl	-870(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-872(fp),r0
+	ashl	#16,r0,-876(fp)
+	addl2	-876(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-876(fp)
+	bgequ	noname.282
+	incl	r4
+noname.282:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.283
+	incl	r2
+noname.283:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.284
+	incl	r10
+noname.284:
+
+	bicl3	#-65536,20(r6),r3
+	movzwl	22(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,28(r7),r2
+	movzwl	30(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-880(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-884(fp)
+	mull2	r0,r4
+	addl3	-880(fp),-884(fp),r0
+	bicl3	#0,r0,-880(fp)
+	cmpl	-880(fp),-884(fp)
+	bgequ	noname.285
+	addl2	#65536,r4
+noname.285:
+	movzwl	-878(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-880(fp),r0
+	ashl	#16,r0,-884(fp)
+	addl2	-884(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-884(fp)
+	bgequ	noname.286
+	incl	r4
+noname.286:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.287
+	incl	r2
+noname.287:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.288
+	incl	r10
+noname.288:
+
+	movl	r9,48(r11)
+
+	clrl	r9
+
+	bicl3	#-65536,24(r6),r3
+	movzwl	26(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,28(r7),r2
+	movzwl	30(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-888(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-892(fp)
+	mull2	r0,r4
+	addl3	-888(fp),-892(fp),r0
+	bicl3	#0,r0,-888(fp)
+	cmpl	-888(fp),-892(fp)
+	bgequ	noname.289
+	addl2	#65536,r4
+noname.289:
+	movzwl	-886(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-888(fp),r0
+	ashl	#16,r0,-892(fp)
+	addl2	-892(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-892(fp)
+	bgequ	noname.290
+	incl	r4
+noname.290:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.291
+	incl	r2
+noname.291:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.292
+	incl	r9
+noname.292:
+
+	movzwl	30(r6),r2
+	bicl3	#-65536,24(r7),r3
+	movzwl	26(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,28(r6),-904(fp)
+	bicl3	#-65536,r2,-908(fp)
+	mull3	r0,-904(fp),-896(fp)
+	mull2	r3,-904(fp)
+	mull3	r3,-908(fp),-900(fp)
+	mull2	r0,-908(fp)
+	addl3	-896(fp),-900(fp),r0
+	bicl3	#0,r0,-896(fp)
+	cmpl	-896(fp),-900(fp)
+	bgequ	noname.293
+	addl2	#65536,-908(fp)
+noname.293:
+	movzwl	-894(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-908(fp)
+	bicl3	#-65536,-896(fp),r0
+	ashl	#16,r0,-900(fp)
+	addl3	-900(fp),-904(fp),r0
+	bicl3	#0,r0,-904(fp)
+	cmpl	-904(fp),-900(fp)
+	bgequ	noname.294
+	incl	-908(fp)
+noname.294:
+	movl	-904(fp),r1
+	movl	-908(fp),r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.295
+	incl	r2
+noname.295:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.296
+	incl	r9
+noname.296:
+
+	movl	r8,52(r11)
+
+	clrl	r8
+
+	movzwl	30(r6),r2
+	bicl3	#-65536,28(r7),r3
+	movzwl	30(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,28(r6),-920(fp)
+	bicl3	#-65536,r2,-924(fp)
+	mull3	r0,-920(fp),-912(fp)
+	mull2	r3,-920(fp)
+	mull3	r3,-924(fp),-916(fp)
+	mull2	r0,-924(fp)
+	addl3	-912(fp),-916(fp),r0
+	bicl3	#0,r0,-912(fp)
+	cmpl	-912(fp),-916(fp)
+	bgequ	noname.297
+	addl2	#65536,-924(fp)
+noname.297:
+	movzwl	-910(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-924(fp)
+	bicl3	#-65536,-912(fp),r0
+	ashl	#16,r0,-916(fp)
+	addl3	-916(fp),-920(fp),r0
+	bicl3	#0,r0,-920(fp)
+	cmpl	-920(fp),-916(fp)
+	bgequ	noname.298
+	incl	-924(fp)
+noname.298:
+	movl	-920(fp),r1
+	movl	-924(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.299
+	incl	r2
+noname.299:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.300
+	incl	r8
+noname.300:
+
+	movl	r10,56(r11)
+
+	movl	r9,60(r11)
+
+	ret	
+
+
+
+;r=4 ;(AP)
+;a=8 ;(AP)
+;b=12 ;(AP)
+;n=16 ;(AP)	n	by value (input)
+
+	.psect	code,nowrt
+
+.entry	BN_MUL_COMBA4,^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
+	movab	-156(sp),sp
+
+	clrq	r9
+
+	clrl	r8
+
+	movl	8(ap),r6
+	bicl3	#-65536,(r6),r3
+	movzwl	2(r6),r2
+	bicl2	#-65536,r2
+	movl	12(ap),r7
+	bicl3	#-65536,(r7),r1
+	movzwl	2(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r2,r4
+	mull3	r0,r5,-4(fp)
+	mull2	r1,r5
+	mull3	r1,r4,-8(fp)
+	mull2	r0,r4
+	addl3	-4(fp),-8(fp),r0
+	bicl3	#0,r0,-4(fp)
+	cmpl	-4(fp),-8(fp)
+	bgequ	noname.303
+	addl2	#65536,r4
+noname.303:
+	movzwl	-2(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-4(fp),r0
+	ashl	#16,r0,-8(fp)
+	addl2	-8(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-8(fp)
+	bgequ	noname.304
+	incl	r4
+noname.304:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.305
+	incl	r2
+noname.305:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.306
+	incl	r8
+noname.306:
+
+	movl	4(ap),r11
+	movl	r10,(r11)
+
+	clrl	r10
+
+	bicl3	#-65536,(r6),r3
+	movzwl	2(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,4(r7),r2
+	movzwl	6(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-12(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-16(fp)
+	mull2	r0,r4
+	addl3	-12(fp),-16(fp),r0
+	bicl3	#0,r0,-12(fp)
+	cmpl	-12(fp),-16(fp)
+	bgequ	noname.307
+	addl2	#65536,r4
+noname.307:
+	movzwl	-10(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-12(fp),r0
+	ashl	#16,r0,-16(fp)
+	addl2	-16(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-16(fp)
+	bgequ	noname.308
+	incl	r4
+noname.308:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.309
+	incl	r2
+noname.309:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.310
+	incl	r10
+noname.310:
+
+	bicl3	#-65536,4(r6),r3
+	movzwl	6(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,(r7),r2
+	movzwl	2(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-20(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-24(fp)
+	mull2	r0,r4
+	addl3	-20(fp),-24(fp),r0
+	bicl3	#0,r0,-20(fp)
+	cmpl	-20(fp),-24(fp)
+	bgequ	noname.311
+	addl2	#65536,r4
+noname.311:
+	movzwl	-18(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-20(fp),r0
+	ashl	#16,r0,-24(fp)
+	addl2	-24(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-24(fp)
+	bgequ	noname.312
+	incl	r4
+noname.312:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.313
+	incl	r2
+noname.313:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.314
+	incl	r10
+noname.314:
+
+	movl	r9,4(r11)
+
+	clrl	r9
+
+	bicl3	#-65536,8(r6),r3
+	movzwl	10(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,(r7),r2
+	movzwl	2(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-28(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-32(fp)
+	mull2	r0,r4
+	addl3	-28(fp),-32(fp),r0
+	bicl3	#0,r0,-28(fp)
+	cmpl	-28(fp),-32(fp)
+	bgequ	noname.315
+	addl2	#65536,r4
+noname.315:
+	movzwl	-26(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-28(fp),r0
+	ashl	#16,r0,-32(fp)
+	addl2	-32(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-32(fp)
+	bgequ	noname.316
+	incl	r4
+noname.316:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.317
+	incl	r2
+noname.317:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.318
+	incl	r9
+noname.318:
+
+	bicl3	#-65536,4(r6),r3
+	movzwl	6(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,4(r7),r2
+	movzwl	6(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-36(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-40(fp)
+	mull2	r0,r4
+	addl3	-36(fp),-40(fp),r0
+	bicl3	#0,r0,-36(fp)
+	cmpl	-36(fp),-40(fp)
+	bgequ	noname.319
+	addl2	#65536,r4
+noname.319:
+	movzwl	-34(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-36(fp),r0
+	ashl	#16,r0,-40(fp)
+	addl2	-40(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-40(fp)
+	bgequ	noname.320
+	incl	r4
+noname.320:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.321
+	incl	r2
+noname.321:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.322
+	incl	r9
+noname.322:
+
+	bicl3	#-65536,(r6),r3
+	movzwl	2(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,8(r7),r2
+	movzwl	10(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-44(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-48(fp)
+	mull2	r0,r4
+	addl3	-44(fp),-48(fp),r0
+	bicl3	#0,r0,-44(fp)
+	cmpl	-44(fp),-48(fp)
+	bgequ	noname.323
+	addl2	#65536,r4
+noname.323:
+	movzwl	-42(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-44(fp),r0
+	ashl	#16,r0,-48(fp)
+	addl2	-48(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-48(fp)
+	bgequ	noname.324
+	incl	r4
+noname.324:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.325
+	incl	r2
+noname.325:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.326
+	incl	r9
+noname.326:
+
+	movl	r8,8(r11)
+
+	clrl	r8
+
+	bicl3	#-65536,(r6),r3
+	movzwl	2(r6),r2
+	bicl3	#-65536,12(r7),r1
+	movzwl	14(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r4
+	bicl3	#-65536,r2,-60(fp)
+	mull3	r0,r4,-52(fp)
+	mull2	r1,r4
+	mull3	r1,-60(fp),-56(fp)
+	mull2	r0,-60(fp)
+	addl3	-52(fp),-56(fp),r0
+	bicl3	#0,r0,-52(fp)
+	cmpl	-52(fp),-56(fp)
+	bgequ	noname.327
+	addl2	#65536,-60(fp)
+noname.327:
+	movzwl	-50(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-60(fp)
+	bicl3	#-65536,-52(fp),r0
+	ashl	#16,r0,-56(fp)
+	addl2	-56(fp),r4
+	bicl2	#0,r4
+	cmpl	r4,-56(fp)
+	bgequ	noname.328
+	incl	-60(fp)
+noname.328:
+	movl	r4,r1
+	movl	-60(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.329
+	incl	r2
+noname.329:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.330
+	incl	r8
+noname.330:
+
+	movzwl	6(r6),r2
+	bicl3	#-65536,8(r7),r3
+	movzwl	10(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,4(r6),-72(fp)
+	bicl3	#-65536,r2,-76(fp)
+	mull3	r0,-72(fp),-64(fp)
+	mull2	r3,-72(fp)
+	mull3	r3,-76(fp),-68(fp)
+	mull2	r0,-76(fp)
+	addl3	-64(fp),-68(fp),r0
+	bicl3	#0,r0,-64(fp)
+	cmpl	-64(fp),-68(fp)
+	bgequ	noname.331
+	addl2	#65536,-76(fp)
+noname.331:
+	movzwl	-62(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-76(fp)
+	bicl3	#-65536,-64(fp),r0
+	ashl	#16,r0,-68(fp)
+	addl3	-68(fp),-72(fp),r0
+	bicl3	#0,r0,-72(fp)
+	cmpl	-72(fp),-68(fp)
+	bgequ	noname.332
+	incl	-76(fp)
+noname.332:
+	movl	-72(fp),r1
+	movl	-76(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.333
+	incl	r2
+noname.333:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.334
+	incl	r8
+noname.334:
+
+	bicl3	#-65536,8(r6),r3
+	movzwl	10(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,4(r7),r2
+	movzwl	6(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-80(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-84(fp)
+	mull2	r0,r4
+	addl3	-80(fp),-84(fp),r0
+	bicl3	#0,r0,-80(fp)
+	cmpl	-80(fp),-84(fp)
+	bgequ	noname.335
+	addl2	#65536,r4
+noname.335:
+	movzwl	-78(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-80(fp),r0
+	ashl	#16,r0,-84(fp)
+	addl2	-84(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-84(fp)
+	bgequ	noname.336
+	incl	r4
+noname.336:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.337
+	incl	r2
+noname.337:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.338
+	incl	r8
+noname.338:
+
+	bicl3	#-65536,12(r6),r3
+	movzwl	14(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,(r7),r2
+	movzwl	2(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-88(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-92(fp)
+	mull2	r0,r4
+	addl3	-88(fp),-92(fp),r0
+	bicl3	#0,r0,-88(fp)
+	cmpl	-88(fp),-92(fp)
+	bgequ	noname.339
+	addl2	#65536,r4
+noname.339:
+	movzwl	-86(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-88(fp),r0
+	ashl	#16,r0,-92(fp)
+	addl2	-92(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-92(fp)
+	bgequ	noname.340
+	incl	r4
+noname.340:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.341
+	incl	r2
+noname.341:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.342
+	incl	r8
+noname.342:
+
+	movl	r10,12(r11)
+
+	clrl	r10
+
+	bicl3	#-65536,12(r6),r3
+	movzwl	14(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,4(r7),r2
+	movzwl	6(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-96(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-100(fp)
+	mull2	r0,r4
+	addl3	-96(fp),-100(fp),r0
+	bicl3	#0,r0,-96(fp)
+	cmpl	-96(fp),-100(fp)
+	bgequ	noname.343
+	addl2	#65536,r4
+noname.343:
+	movzwl	-94(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-96(fp),r0
+	ashl	#16,r0,-100(fp)
+	addl2	-100(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-100(fp)
+	bgequ	noname.344
+	incl	r4
+noname.344:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.345
+	incl	r2
+noname.345:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.346
+	incl	r10
+noname.346:
+
+	bicl3	#-65536,8(r6),r3
+	movzwl	10(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,8(r7),r2
+	movzwl	10(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-104(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-108(fp)
+	mull2	r0,r4
+	addl3	-104(fp),-108(fp),r0
+	bicl3	#0,r0,-104(fp)
+	cmpl	-104(fp),-108(fp)
+	bgequ	noname.347
+	addl2	#65536,r4
+noname.347:
+	movzwl	-102(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-104(fp),r0
+	ashl	#16,r0,-108(fp)
+	addl2	-108(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-108(fp)
+	bgequ	noname.348
+	incl	r4
+noname.348:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.349
+	incl	r2
+noname.349:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.350
+	incl	r10
+noname.350:
+
+	bicl3	#-65536,4(r6),r3
+	movzwl	6(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,12(r7),r2
+	movzwl	14(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-112(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-116(fp)
+	mull2	r0,r4
+	addl3	-112(fp),-116(fp),r0
+	bicl3	#0,r0,-112(fp)
+	cmpl	-112(fp),-116(fp)
+	bgequ	noname.351
+	addl2	#65536,r4
+noname.351:
+	movzwl	-110(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-112(fp),r0
+	ashl	#16,r0,-116(fp)
+	addl2	-116(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-116(fp)
+	bgequ	noname.352
+	incl	r4
+noname.352:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.353
+	incl	r2
+noname.353:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.354
+	incl	r10
+noname.354:
+
+	movl	r9,16(r11)
+
+	clrl	r9
+
+	bicl3	#-65536,8(r6),r3
+	movzwl	10(r6),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,12(r7),r2
+	movzwl	14(r7),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-120(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-124(fp)
+	mull2	r0,r4
+	addl3	-120(fp),-124(fp),r0
+	bicl3	#0,r0,-120(fp)
+	cmpl	-120(fp),-124(fp)
+	bgequ	noname.355
+	addl2	#65536,r4
+noname.355:
+	movzwl	-118(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-120(fp),r0
+	ashl	#16,r0,-124(fp)
+	addl2	-124(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-124(fp)
+	bgequ	noname.356
+	incl	r4
+noname.356:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.357
+	incl	r2
+noname.357:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.358
+	incl	r9
+noname.358:
+
+	movzwl	14(r6),r2
+	bicl3	#-65536,8(r7),r3
+	movzwl	10(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,12(r6),-136(fp)
+	bicl3	#-65536,r2,-140(fp)
+	mull3	r0,-136(fp),-128(fp)
+	mull2	r3,-136(fp)
+	mull3	r3,-140(fp),-132(fp)
+	mull2	r0,-140(fp)
+	addl3	-128(fp),-132(fp),r0
+	bicl3	#0,r0,-128(fp)
+	cmpl	-128(fp),-132(fp)
+	bgequ	noname.359
+	addl2	#65536,-140(fp)
+noname.359:
+	movzwl	-126(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-140(fp)
+	bicl3	#-65536,-128(fp),r0
+	ashl	#16,r0,-132(fp)
+	addl3	-132(fp),-136(fp),r0
+	bicl3	#0,r0,-136(fp)
+	cmpl	-136(fp),-132(fp)
+	bgequ	noname.360
+	incl	-140(fp)
+noname.360:
+	movl	-136(fp),r1
+	movl	-140(fp),r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.361
+	incl	r2
+noname.361:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.362
+	incl	r9
+noname.362:
+
+	movl	r8,20(r11)
+
+	clrl	r8
+
+	movzwl	14(r6),r2
+	bicl3	#-65536,12(r7),r3
+	movzwl	14(r7),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,12(r6),-152(fp)
+	bicl3	#-65536,r2,-156(fp)
+	mull3	r0,-152(fp),-144(fp)
+	mull2	r3,-152(fp)
+	mull3	r3,-156(fp),-148(fp)
+	mull2	r0,-156(fp)
+	addl3	-144(fp),-148(fp),r0
+	bicl3	#0,r0,-144(fp)
+	cmpl	-144(fp),-148(fp)
+	bgequ	noname.363
+	addl2	#65536,-156(fp)
+noname.363:
+	movzwl	-142(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-156(fp)
+	bicl3	#-65536,-144(fp),r0
+	ashl	#16,r0,-148(fp)
+	addl3	-148(fp),-152(fp),r0
+	bicl3	#0,r0,-152(fp)
+	cmpl	-152(fp),-148(fp)
+	bgequ	noname.364
+	incl	-156(fp)
+noname.364:
+	movl	-152(fp),r1
+	movl	-156(fp),r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.365
+	incl	r2
+noname.365:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.366
+	incl	r8
+noname.366:
+
+	movl	r10,24(r11)
+
+	movl	r9,28(r11)
+
+	ret	
+
+
+
+;r=4 ;(AP)
+;a=8 ;(AP)
+;b=12 ;(AP)
+;n=16 ;(AP)	n	by value (input)
+
+	.psect	code,nowrt
+
+.entry	BN_SQR_COMBA8,^m<r2,r3,r4,r5,r6,r7,r8,r9>
+	movab	-444(sp),sp
+
+	clrq	r8
+
+	clrl	r7
+
+	movl	8(ap),r4
+	movl	(r4),r3
+	bicl3	#-65536,r3,-4(fp)
+	extzv	#16,#16,r3,r0
+	bicl3	#-65536,r0,r3
+	movl	-4(fp),r0
+	mull3	r0,r3,-8(fp)
+	mull3	r0,r0,-4(fp)
+	mull2	r3,r3
+	bicl3	#32767,-8(fp),r0
+	extzv	#15,#17,r0,r0
+	addl2	r0,r3
+	bicl3	#-65536,-8(fp),r0
+	ashl	#17,r0,-8(fp)
+	addl3	-4(fp),-8(fp),r0
+	bicl3	#0,r0,-4(fp)
+	cmpl	-4(fp),-8(fp)
+	bgequ	noname.369
+	incl	r3
+noname.369:
+	movl	-4(fp),r1
+	movl	r3,r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.370
+	incl	r2
+noname.370:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.371
+	incl	r7
+noname.371:
+
+	movl	r9,@4(ap)
+
+	clrl	r9
+
+	movzwl	6(r4),r2
+	bicl3	#-65536,(r4),r3
+	movzwl	2(r4),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,4(r4),-20(fp)
+	bicl3	#-65536,r2,-24(fp)
+	mull3	r0,-20(fp),-12(fp)
+	mull2	r3,-20(fp)
+	mull3	r3,-24(fp),-16(fp)
+	mull2	r0,-24(fp)
+	addl3	-12(fp),-16(fp),r0
+	bicl3	#0,r0,-12(fp)
+	cmpl	-12(fp),-16(fp)
+	bgequ	noname.372
+	addl2	#65536,-24(fp)
+noname.372:
+	movzwl	-10(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-24(fp)
+	bicl3	#-65536,-12(fp),r0
+	ashl	#16,r0,-16(fp)
+	addl3	-16(fp),-20(fp),r0
+	bicl3	#0,r0,-20(fp)
+	cmpl	-20(fp),-16(fp)
+	bgequ	noname.373
+	incl	-24(fp)
+noname.373:
+	movl	-20(fp),r3
+	movl	-24(fp),r2
+	bbc	#31,r2,noname.374
+	incl	r9
+noname.374:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.375
+	incl	r2
+noname.375:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r8
+	bicl2	#0,r8
+	cmpl	r8,r3
+	bgequ	noname.376
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.376
+	incl	r9
+noname.376:
+	addl2	r2,r7
+	bicl2	#0,r7
+	cmpl	r7,r2
+	bgequ	noname.377
+	incl	r9
+noname.377:
+
+	movl	4(ap),r0
+	movl	r8,4(r0)
+
+	clrl	r8
+
+	movl	8(ap),r4
+	movl	4(r4),r3
+	bicl3	#-65536,r3,-28(fp)
+	extzv	#16,#16,r3,r0
+	bicl3	#-65536,r0,r3
+	movl	-28(fp),r0
+	mull3	r0,r3,-32(fp)
+	mull3	r0,r0,-28(fp)
+	mull2	r3,r3
+	bicl3	#32767,-32(fp),r0
+	extzv	#15,#17,r0,r0
+	addl2	r0,r3
+	bicl3	#-65536,-32(fp),r0
+	ashl	#17,r0,-32(fp)
+	addl3	-28(fp),-32(fp),r0
+	bicl3	#0,r0,-28(fp)
+	cmpl	-28(fp),-32(fp)
+	bgequ	noname.378
+	incl	r3
+noname.378:
+	movl	-28(fp),r1
+	movl	r3,r2
+	addl2	r1,r7
+	bicl2	#0,r7
+	cmpl	r7,r1
+	bgequ	noname.379
+	incl	r2
+noname.379:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.380
+	incl	r8
+noname.380:
+
+	movzwl	10(r4),r2
+	bicl3	#-65536,(r4),r3
+	movzwl	2(r4),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,8(r4),-44(fp)
+	bicl3	#-65536,r2,-48(fp)
+	mull3	r0,-44(fp),-36(fp)
+	mull2	r3,-44(fp)
+	mull3	r3,-48(fp),-40(fp)
+	mull2	r0,-48(fp)
+	addl3	-36(fp),-40(fp),r0
+	bicl3	#0,r0,-36(fp)
+	cmpl	-36(fp),-40(fp)
+	bgequ	noname.381
+	addl2	#65536,-48(fp)
+noname.381:
+	movzwl	-34(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-48(fp)
+	bicl3	#-65536,-36(fp),r0
+	ashl	#16,r0,-40(fp)
+	addl3	-40(fp),-44(fp),r0
+	bicl3	#0,r0,-44(fp)
+	cmpl	-44(fp),-40(fp)
+	bgequ	noname.382
+	incl	-48(fp)
+noname.382:
+	movl	-44(fp),r3
+	movl	-48(fp),r2
+	bbc	#31,r2,noname.383
+	incl	r8
+noname.383:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.384
+	incl	r2
+noname.384:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r7
+	bicl2	#0,r7
+	cmpl	r7,r3
+	bgequ	noname.385
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.385
+	incl	r8
+noname.385:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.386
+	incl	r8
+noname.386:
+
+	movl	4(ap),r0
+	movl	r7,8(r0)
+
+	clrl	r7
+
+	movl	8(ap),r0
+	movzwl	14(r0),r2
+	bicl3	#-65536,(r0),r3
+	movzwl	2(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,12(r0),-60(fp)
+	bicl3	#-65536,r2,-64(fp)
+	mull3	r1,-60(fp),-52(fp)
+	mull2	r3,-60(fp)
+	mull3	r3,-64(fp),-56(fp)
+	mull2	r1,-64(fp)
+	addl3	-52(fp),-56(fp),r0
+	bicl3	#0,r0,-52(fp)
+	cmpl	-52(fp),-56(fp)
+	bgequ	noname.387
+	addl2	#65536,-64(fp)
+noname.387:
+	movzwl	-50(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-64(fp)
+	bicl3	#-65536,-52(fp),r0
+	ashl	#16,r0,-56(fp)
+	addl3	-56(fp),-60(fp),r0
+	bicl3	#0,r0,-60(fp)
+	cmpl	-60(fp),-56(fp)
+	bgequ	noname.388
+	incl	-64(fp)
+noname.388:
+	movl	-60(fp),r3
+	movl	-64(fp),r2
+	bbc	#31,r2,noname.389
+	incl	r7
+noname.389:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.390
+	incl	r2
+noname.390:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r9
+	bicl2	#0,r9
+	cmpl	r9,r3
+	bgequ	noname.391
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.391
+	incl	r7
+noname.391:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.392
+	incl	r7
+noname.392:
+
+	movl	8(ap),r0
+	movzwl	10(r0),r2
+	bicl3	#-65536,4(r0),r3
+	movzwl	6(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,8(r0),-76(fp)
+	bicl3	#-65536,r2,-80(fp)
+	mull3	r1,-76(fp),-68(fp)
+	mull2	r3,-76(fp)
+	mull3	r3,-80(fp),-72(fp)
+	mull2	r1,-80(fp)
+	addl3	-68(fp),-72(fp),r0
+	bicl3	#0,r0,-68(fp)
+	cmpl	-68(fp),-72(fp)
+	bgequ	noname.393
+	addl2	#65536,-80(fp)
+noname.393:
+	movzwl	-66(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-80(fp)
+	bicl3	#-65536,-68(fp),r0
+	ashl	#16,r0,-72(fp)
+	addl3	-72(fp),-76(fp),r0
+	bicl3	#0,r0,-76(fp)
+	cmpl	-76(fp),-72(fp)
+	bgequ	noname.394
+	incl	-80(fp)
+noname.394:
+	movl	-76(fp),r3
+	movl	-80(fp),r2
+	bbc	#31,r2,noname.395
+	incl	r7
+noname.395:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.396
+	incl	r2
+noname.396:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r9
+	bicl2	#0,r9
+	cmpl	r9,r3
+	bgequ	noname.397
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.397
+	incl	r7
+noname.397:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.398
+	incl	r7
+noname.398:
+
+	movl	4(ap),r0
+	movl	r9,12(r0)
+
+	clrl	r9
+
+	movl	8(ap),r2
+	movl	8(r2),r4
+	bicl3	#-65536,r4,-84(fp)
+	extzv	#16,#16,r4,r0
+	bicl3	#-65536,r0,r4
+	movl	-84(fp),r0
+	mull3	r0,r4,-88(fp)
+	mull3	r0,r0,-84(fp)
+	mull2	r4,r4
+	bicl3	#32767,-88(fp),r0
+	extzv	#15,#17,r0,r0
+	addl2	r0,r4
+	bicl3	#-65536,-88(fp),r0
+	ashl	#17,r0,-88(fp)
+	addl3	-84(fp),-88(fp),r0
+	bicl3	#0,r0,-84(fp)
+	cmpl	-84(fp),-88(fp)
+	bgequ	noname.399
+	incl	r4
+noname.399:
+	movl	-84(fp),r1
+	movl	r4,r3
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.400
+	incl	r3
+noname.400:
+	addl2	r3,r7
+	bicl2	#0,r7
+	cmpl	r7,r3
+	bgequ	noname.401
+	incl	r9
+noname.401:
+
+	movzwl	14(r2),r3
+	bicl3	#-65536,4(r2),r1
+	movzwl	6(r2),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,12(r2),-100(fp)
+	bicl3	#-65536,r3,-104(fp)
+	mull3	r0,-100(fp),-92(fp)
+	mull2	r1,-100(fp)
+	mull3	r1,-104(fp),-96(fp)
+	mull2	r0,-104(fp)
+	addl3	-92(fp),-96(fp),r0
+	bicl3	#0,r0,-92(fp)
+	cmpl	-92(fp),-96(fp)
+	bgequ	noname.402
+	addl2	#65536,-104(fp)
+noname.402:
+	movzwl	-90(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-104(fp)
+	bicl3	#-65536,-92(fp),r0
+	ashl	#16,r0,-96(fp)
+	addl3	-96(fp),-100(fp),r0
+	bicl3	#0,r0,-100(fp)
+	cmpl	-100(fp),-96(fp)
+	bgequ	noname.403
+	incl	-104(fp)
+noname.403:
+	movl	-100(fp),r3
+	movl	-104(fp),r2
+	bbc	#31,r2,noname.404
+	incl	r9
+noname.404:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.405
+	incl	r2
+noname.405:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r8
+	bicl2	#0,r8
+	cmpl	r8,r3
+	bgequ	noname.406
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.406
+	incl	r9
+noname.406:
+	addl2	r2,r7
+	bicl2	#0,r7
+	cmpl	r7,r2
+	bgequ	noname.407
+	incl	r9
+noname.407:
+
+	movl	8(ap),r0
+	movzwl	18(r0),r2
+	bicl3	#-65536,(r0),r3
+	movzwl	2(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,16(r0),-116(fp)
+	bicl3	#-65536,r2,-120(fp)
+	mull3	r1,-116(fp),-108(fp)
+	mull2	r3,-116(fp)
+	mull3	r3,-120(fp),-112(fp)
+	mull2	r1,-120(fp)
+	addl3	-108(fp),-112(fp),r0
+	bicl3	#0,r0,-108(fp)
+	cmpl	-108(fp),-112(fp)
+	bgequ	noname.408
+	addl2	#65536,-120(fp)
+noname.408:
+	movzwl	-106(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-120(fp)
+	bicl3	#-65536,-108(fp),r0
+	ashl	#16,r0,-112(fp)
+	addl3	-112(fp),-116(fp),r0
+	bicl3	#0,r0,-116(fp)
+	cmpl	-116(fp),-112(fp)
+	bgequ	noname.409
+	incl	-120(fp)
+noname.409:
+	movl	-116(fp),r3
+	movl	-120(fp),r2
+	bbc	#31,r2,noname.410
+	incl	r9
+noname.410:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.411
+	incl	r2
+noname.411:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r8
+	bicl2	#0,r8
+	cmpl	r8,r3
+	bgequ	noname.412
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.412
+	incl	r9
+noname.412:
+	addl2	r2,r7
+	bicl2	#0,r7
+	cmpl	r7,r2
+	bgequ	noname.413
+	incl	r9
+noname.413:
+
+	movl	4(ap),r0
+	movl	r8,16(r0)
+
+	clrl	r8
+
+	movl	8(ap),r0
+	movzwl	22(r0),r2
+	bicl3	#-65536,(r0),r3
+	movzwl	2(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,20(r0),-132(fp)
+	bicl3	#-65536,r2,-136(fp)
+	mull3	r1,-132(fp),-124(fp)
+	mull2	r3,-132(fp)
+	mull3	r3,-136(fp),-128(fp)
+	mull2	r1,-136(fp)
+	addl3	-124(fp),-128(fp),r0
+	bicl3	#0,r0,-124(fp)
+	cmpl	-124(fp),-128(fp)
+	bgequ	noname.414
+	addl2	#65536,-136(fp)
+noname.414:
+	movzwl	-122(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-136(fp)
+	bicl3	#-65536,-124(fp),r0
+	ashl	#16,r0,-128(fp)
+	addl3	-128(fp),-132(fp),r0
+	bicl3	#0,r0,-132(fp)
+	cmpl	-132(fp),-128(fp)
+	bgequ	noname.415
+	incl	-136(fp)
+noname.415:
+	movl	-132(fp),r3
+	movl	-136(fp),r2
+	bbc	#31,r2,noname.416
+	incl	r8
+noname.416:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.417
+	incl	r2
+noname.417:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r7
+	bicl2	#0,r7
+	cmpl	r7,r3
+	bgequ	noname.418
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.418
+	incl	r8
+noname.418:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.419
+	incl	r8
+noname.419:
+
+	movl	8(ap),r0
+	movzwl	18(r0),r2
+	bicl3	#-65536,4(r0),r3
+	movzwl	6(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,16(r0),-148(fp)
+	bicl3	#-65536,r2,-152(fp)
+	mull3	r1,-148(fp),-140(fp)
+	mull2	r3,-148(fp)
+	mull3	r3,-152(fp),-144(fp)
+	mull2	r1,-152(fp)
+	addl3	-140(fp),-144(fp),r0
+	bicl3	#0,r0,-140(fp)
+	cmpl	-140(fp),-144(fp)
+	bgequ	noname.420
+	addl2	#65536,-152(fp)
+noname.420:
+	movzwl	-138(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-152(fp)
+	bicl3	#-65536,-140(fp),r0
+	ashl	#16,r0,-144(fp)
+	addl3	-144(fp),-148(fp),r0
+	bicl3	#0,r0,-148(fp)
+	cmpl	-148(fp),-144(fp)
+	bgequ	noname.421
+	incl	-152(fp)
+noname.421:
+	movl	-148(fp),r3
+	movl	-152(fp),r2
+	bbc	#31,r2,noname.422
+	incl	r8
+noname.422:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.423
+	incl	r2
+noname.423:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r7
+	bicl2	#0,r7
+	cmpl	r7,r3
+	bgequ	noname.424
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.424
+	incl	r8
+noname.424:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.425
+	incl	r8
+noname.425:
+
+	movl	8(ap),r0
+	movzwl	14(r0),r2
+	bicl3	#-65536,8(r0),r3
+	movzwl	10(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,12(r0),-164(fp)
+	bicl3	#-65536,r2,-168(fp)
+	mull3	r1,-164(fp),-156(fp)
+	mull2	r3,-164(fp)
+	mull3	r3,-168(fp),-160(fp)
+	mull2	r1,-168(fp)
+	addl3	-156(fp),-160(fp),r0
+	bicl3	#0,r0,-156(fp)
+	cmpl	-156(fp),-160(fp)
+	bgequ	noname.426
+	addl2	#65536,-168(fp)
+noname.426:
+	movzwl	-154(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-168(fp)
+	bicl3	#-65536,-156(fp),r0
+	ashl	#16,r0,-160(fp)
+	addl3	-160(fp),-164(fp),r0
+	bicl3	#0,r0,-164(fp)
+	cmpl	-164(fp),-160(fp)
+	bgequ	noname.427
+	incl	-168(fp)
+noname.427:
+	movl	-164(fp),r3
+	movl	-168(fp),r2
+	bbc	#31,r2,noname.428
+	incl	r8
+noname.428:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.429
+	incl	r2
+noname.429:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r7
+	bicl2	#0,r7
+	cmpl	r7,r3
+	bgequ	noname.430
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.430
+	incl	r8
+noname.430:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.431
+	incl	r8
+noname.431:
+
+	movl	4(ap),r0
+	movl	r7,20(r0)
+
+	clrl	r7
+
+	movl	8(ap),r2
+	movl	12(r2),r4
+	bicl3	#-65536,r4,-172(fp)
+	extzv	#16,#16,r4,r0
+	bicl3	#-65536,r0,r4
+	movl	-172(fp),r0
+	mull3	r0,r4,-176(fp)
+	mull3	r0,r0,-172(fp)
+	mull2	r4,r4
+	bicl3	#32767,-176(fp),r0
+	extzv	#15,#17,r0,r0
+	addl2	r0,r4
+	bicl3	#-65536,-176(fp),r0
+	ashl	#17,r0,-176(fp)
+	addl3	-172(fp),-176(fp),r0
+	bicl3	#0,r0,-172(fp)
+	cmpl	-172(fp),-176(fp)
+	bgequ	noname.432
+	incl	r4
+noname.432:
+	movl	-172(fp),r1
+	movl	r4,r3
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.433
+	incl	r3
+noname.433:
+	addl2	r3,r8
+	bicl2	#0,r8
+	cmpl	r8,r3
+	bgequ	noname.434
+	incl	r7
+noname.434:
+
+	movzwl	18(r2),r3
+	bicl3	#-65536,8(r2),r1
+	movzwl	10(r2),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,16(r2),-188(fp)
+	bicl3	#-65536,r3,-192(fp)
+	mull3	r0,-188(fp),-180(fp)
+	mull2	r1,-188(fp)
+	mull3	r1,-192(fp),-184(fp)
+	mull2	r0,-192(fp)
+	addl3	-180(fp),-184(fp),r0
+	bicl3	#0,r0,-180(fp)
+	cmpl	-180(fp),-184(fp)
+	bgequ	noname.435
+	addl2	#65536,-192(fp)
+noname.435:
+	movzwl	-178(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-192(fp)
+	bicl3	#-65536,-180(fp),r0
+	ashl	#16,r0,-184(fp)
+	addl3	-184(fp),-188(fp),r0
+	bicl3	#0,r0,-188(fp)
+	cmpl	-188(fp),-184(fp)
+	bgequ	noname.436
+	incl	-192(fp)
+noname.436:
+	movl	-188(fp),r3
+	movl	-192(fp),r2
+	bbc	#31,r2,noname.437
+	incl	r7
+noname.437:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.438
+	incl	r2
+noname.438:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r9
+	bicl2	#0,r9
+	cmpl	r9,r3
+	bgequ	noname.439
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.439
+	incl	r7
+noname.439:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.440
+	incl	r7
+noname.440:
+
+	movl	8(ap),r0
+	movzwl	22(r0),r2
+	bicl3	#-65536,4(r0),r3
+	movzwl	6(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,20(r0),-204(fp)
+	bicl3	#-65536,r2,-208(fp)
+	mull3	r1,-204(fp),-196(fp)
+	mull2	r3,-204(fp)
+	mull3	r3,-208(fp),-200(fp)
+	mull2	r1,-208(fp)
+	addl3	-196(fp),-200(fp),r0
+	bicl3	#0,r0,-196(fp)
+	cmpl	-196(fp),-200(fp)
+	bgequ	noname.441
+	addl2	#65536,-208(fp)
+noname.441:
+	movzwl	-194(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-208(fp)
+	bicl3	#-65536,-196(fp),r0
+	ashl	#16,r0,-200(fp)
+	addl3	-200(fp),-204(fp),r0
+	bicl3	#0,r0,-204(fp)
+	cmpl	-204(fp),-200(fp)
+	bgequ	noname.442
+	incl	-208(fp)
+noname.442:
+	movl	-204(fp),r3
+	movl	-208(fp),r2
+	bbc	#31,r2,noname.443
+	incl	r7
+noname.443:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.444
+	incl	r2
+noname.444:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r9
+	bicl2	#0,r9
+	cmpl	r9,r3
+	bgequ	noname.445
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.445
+	incl	r7
+noname.445:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.446
+	incl	r7
+noname.446:
+
+	movl	8(ap),r0
+	movzwl	26(r0),r2
+	bicl3	#-65536,(r0),r3
+	movzwl	2(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,24(r0),-220(fp)
+	bicl3	#-65536,r2,-224(fp)
+	mull3	r1,-220(fp),-212(fp)
+	mull2	r3,-220(fp)
+	mull3	r3,-224(fp),-216(fp)
+	mull2	r1,-224(fp)
+	addl3	-212(fp),-216(fp),r0
+	bicl3	#0,r0,-212(fp)
+	cmpl	-212(fp),-216(fp)
+	bgequ	noname.447
+	addl2	#65536,-224(fp)
+noname.447:
+	movzwl	-210(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-224(fp)
+	bicl3	#-65536,-212(fp),r0
+	ashl	#16,r0,-216(fp)
+	addl3	-216(fp),-220(fp),r0
+	bicl3	#0,r0,-220(fp)
+	cmpl	-220(fp),-216(fp)
+	bgequ	noname.448
+	incl	-224(fp)
+noname.448:
+	movl	-220(fp),r3
+	movl	-224(fp),r2
+	bbc	#31,r2,noname.449
+	incl	r7
+noname.449:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.450
+	incl	r2
+noname.450:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r9
+	bicl2	#0,r9
+	cmpl	r9,r3
+	bgequ	noname.451
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.451
+	incl	r7
+noname.451:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.452
+	incl	r7
+noname.452:
+
+	movl	4(ap),r0
+	movl	r9,24(r0)
+
+	clrl	r9
+
+	movl	8(ap),r0
+	movzwl	30(r0),r2
+	bicl3	#-65536,(r0),r3
+	movzwl	2(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,28(r0),-236(fp)
+	bicl3	#-65536,r2,-240(fp)
+	mull3	r1,-236(fp),-228(fp)
+	mull2	r3,-236(fp)
+	mull3	r3,-240(fp),-232(fp)
+	mull2	r1,-240(fp)
+	addl3	-228(fp),-232(fp),r0
+	bicl3	#0,r0,-228(fp)
+	cmpl	-228(fp),-232(fp)
+	bgequ	noname.453
+	addl2	#65536,-240(fp)
+noname.453:
+	movzwl	-226(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-240(fp)
+	bicl3	#-65536,-228(fp),r0
+	ashl	#16,r0,-232(fp)
+	addl3	-232(fp),-236(fp),r0
+	bicl3	#0,r0,-236(fp)
+	cmpl	-236(fp),-232(fp)
+	bgequ	noname.454
+	incl	-240(fp)
+noname.454:
+	movl	-236(fp),r3
+	movl	-240(fp),r2
+	bbc	#31,r2,noname.455
+	incl	r9
+noname.455:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.456
+	incl	r2
+noname.456:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r8
+	bicl2	#0,r8
+	cmpl	r8,r3
+	bgequ	noname.457
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.457
+	incl	r9
+noname.457:
+	addl2	r2,r7
+	bicl2	#0,r7
+	cmpl	r7,r2
+	bgequ	noname.458
+	incl	r9
+noname.458:
+
+	movl	8(ap),r0
+	movzwl	26(r0),r2
+	bicl3	#-65536,4(r0),r3
+	movzwl	6(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,24(r0),-252(fp)
+	bicl3	#-65536,r2,-256(fp)
+	mull3	r1,-252(fp),-244(fp)
+	mull2	r3,-252(fp)
+	mull3	r3,-256(fp),-248(fp)
+	mull2	r1,-256(fp)
+	addl3	-244(fp),-248(fp),r0
+	bicl3	#0,r0,-244(fp)
+	cmpl	-244(fp),-248(fp)
+	bgequ	noname.459
+	addl2	#65536,-256(fp)
+noname.459:
+	movzwl	-242(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-256(fp)
+	bicl3	#-65536,-244(fp),r0
+	ashl	#16,r0,-248(fp)
+	addl3	-248(fp),-252(fp),r0
+	bicl3	#0,r0,-252(fp)
+	cmpl	-252(fp),-248(fp)
+	bgequ	noname.460
+	incl	-256(fp)
+noname.460:
+	movl	-252(fp),r3
+	movl	-256(fp),r2
+	bbc	#31,r2,noname.461
+	incl	r9
+noname.461:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.462
+	incl	r2
+noname.462:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r8
+	bicl2	#0,r8
+	cmpl	r8,r3
+	bgequ	noname.463
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.463
+	incl	r9
+noname.463:
+	addl2	r2,r7
+	bicl2	#0,r7
+	cmpl	r7,r2
+	bgequ	noname.464
+	incl	r9
+noname.464:
+
+	movl	8(ap),r0
+	movzwl	22(r0),r2
+	bicl3	#-65536,8(r0),r3
+	movzwl	10(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,20(r0),-268(fp)
+	bicl3	#-65536,r2,-272(fp)
+	mull3	r1,-268(fp),-260(fp)
+	mull2	r3,-268(fp)
+	mull3	r3,-272(fp),-264(fp)
+	mull2	r1,-272(fp)
+	addl3	-260(fp),-264(fp),r0
+	bicl3	#0,r0,-260(fp)
+	cmpl	-260(fp),-264(fp)
+	bgequ	noname.465
+	addl2	#65536,-272(fp)
+noname.465:
+	movzwl	-258(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-272(fp)
+	bicl3	#-65536,-260(fp),r0
+	ashl	#16,r0,-264(fp)
+	addl3	-264(fp),-268(fp),r0
+	bicl3	#0,r0,-268(fp)
+	cmpl	-268(fp),-264(fp)
+	bgequ	noname.466
+	incl	-272(fp)
+noname.466:
+	movl	-268(fp),r3
+	movl	-272(fp),r2
+	bbc	#31,r2,noname.467
+	incl	r9
+noname.467:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.468
+	incl	r2
+noname.468:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r8
+	bicl2	#0,r8
+	cmpl	r8,r3
+	bgequ	noname.469
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.469
+	incl	r9
+noname.469:
+	addl2	r2,r7
+	bicl2	#0,r7
+	cmpl	r7,r2
+	bgequ	noname.470
+	incl	r9
+noname.470:
+
+	movl	8(ap),r0
+	movzwl	18(r0),r2
+	bicl3	#-65536,12(r0),r3
+	movzwl	14(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,16(r0),-284(fp)
+	bicl3	#-65536,r2,-288(fp)
+	mull3	r1,-284(fp),-276(fp)
+	mull2	r3,-284(fp)
+	mull3	r3,-288(fp),-280(fp)
+	mull2	r1,-288(fp)
+	addl3	-276(fp),-280(fp),r0
+	bicl3	#0,r0,-276(fp)
+	cmpl	-276(fp),-280(fp)
+	bgequ	noname.471
+	addl2	#65536,-288(fp)
+noname.471:
+	movzwl	-274(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-288(fp)
+	bicl3	#-65536,-276(fp),r0
+	ashl	#16,r0,-280(fp)
+	addl3	-280(fp),-284(fp),r0
+	bicl3	#0,r0,-284(fp)
+	cmpl	-284(fp),-280(fp)
+	bgequ	noname.472
+	incl	-288(fp)
+noname.472:
+	movl	-284(fp),r3
+	movl	-288(fp),r2
+	bbc	#31,r2,noname.473
+	incl	r9
+noname.473:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.474
+	incl	r2
+noname.474:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r8
+	bicl2	#0,r8
+	cmpl	r8,r3
+	bgequ	noname.475
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.475
+	incl	r9
+noname.475:
+	addl2	r2,r7
+	bicl2	#0,r7
+	cmpl	r7,r2
+	bgequ	noname.476
+	incl	r9
+noname.476:
+
+	movl	4(ap),r0
+	movl	r8,28(r0)
+
+	clrl	r8
+
+	movl	8(ap),r3
+	movl	16(r3),r4
+	bicl3	#-65536,r4,r5
+	extzv	#16,#16,r4,r0
+	bicl3	#-65536,r0,r4
+	mull3	r5,r4,-292(fp)
+	mull2	r5,r5
+	mull2	r4,r4
+	bicl3	#32767,-292(fp),r0
+	extzv	#15,#17,r0,r0
+	addl2	r0,r4
+	bicl3	#-65536,-292(fp),r0
+	ashl	#17,r0,-292(fp)
+	addl2	-292(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-292(fp)
+	bgequ	noname.477
+	incl	r4
+noname.477:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r7
+	bicl2	#0,r7
+	cmpl	r7,r1
+	bgequ	noname.478
+	incl	r2
+noname.478:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.479
+	incl	r8
+noname.479:
+
+	bicl3	#-65536,20(r3),r4
+	movzwl	22(r3),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,12(r3),r2
+	movzwl	14(r3),r0
+	bicl2	#-65536,r0
+	movl	r4,r6
+	movl	r1,r5
+	mull3	r0,r6,-296(fp)
+	mull2	r2,r6
+	mull3	r2,r5,-300(fp)
+	mull2	r0,r5
+	addl3	-296(fp),-300(fp),r0
+	bicl3	#0,r0,-296(fp)
+	cmpl	-296(fp),-300(fp)
+	bgequ	noname.480
+	addl2	#65536,r5
+noname.480:
+	movzwl	-294(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r5
+	bicl3	#-65536,-296(fp),r0
+	ashl	#16,r0,-300(fp)
+	addl2	-300(fp),r6
+	bicl2	#0,r6
+	cmpl	r6,-300(fp)
+	bgequ	noname.481
+	incl	r5
+noname.481:
+	movl	r6,r3
+	movl	r5,r2
+	bbc	#31,r2,noname.482
+	incl	r8
+noname.482:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.483
+	incl	r2
+noname.483:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r7
+	bicl2	#0,r7
+	cmpl	r7,r3
+	bgequ	noname.484
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.484
+	incl	r8
+noname.484:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.485
+	incl	r8
+noname.485:
+
+	movl	8(ap),r0
+	bicl3	#-65536,24(r0),r3
+	movzwl	26(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,8(r0),r2
+	movzwl	10(r0),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-304(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-308(fp)
+	mull2	r0,r4
+	addl3	-304(fp),-308(fp),r0
+	bicl3	#0,r0,-304(fp)
+	cmpl	-304(fp),-308(fp)
+	bgequ	noname.486
+	addl2	#65536,r4
+noname.486:
+	movzwl	-302(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-304(fp),r0
+	ashl	#16,r0,-308(fp)
+	addl2	-308(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-308(fp)
+	bgequ	noname.487
+	incl	r4
+noname.487:
+	movl	r5,r3
+	movl	r4,r2
+	bbc	#31,r2,noname.488
+	incl	r8
+noname.488:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.489
+	incl	r2
+noname.489:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r7
+	bicl2	#0,r7
+	cmpl	r7,r3
+	bgequ	noname.490
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.490
+	incl	r8
+noname.490:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.491
+	incl	r8
+noname.491:
+
+	movl	8(ap),r0
+	bicl3	#-65536,28(r0),r3
+	movzwl	30(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,4(r0),r2
+	movzwl	6(r0),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-312(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-316(fp)
+	mull2	r0,r4
+	addl3	-312(fp),-316(fp),r0
+	bicl3	#0,r0,-312(fp)
+	cmpl	-312(fp),-316(fp)
+	bgequ	noname.492
+	addl2	#65536,r4
+noname.492:
+	movzwl	-310(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-312(fp),r0
+	ashl	#16,r0,-316(fp)
+	addl2	-316(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-316(fp)
+	bgequ	noname.493
+	incl	r4
+noname.493:
+	movl	r5,r3
+	movl	r4,r2
+	bbc	#31,r2,noname.494
+	incl	r8
+noname.494:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.495
+	incl	r2
+noname.495:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r7
+	bicl2	#0,r7
+	cmpl	r7,r3
+	bgequ	noname.496
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.496
+	incl	r8
+noname.496:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.497
+	incl	r8
+noname.497:
+
+	movl	4(ap),r0
+	movl	r7,32(r0)
+
+	clrl	r7
+
+	movl	8(ap),r0
+	bicl3	#-65536,28(r0),r3
+	movzwl	30(r0),r2
+	bicl3	#-65536,8(r0),r1
+	movzwl	10(r0),r0
+	bicl2	#-65536,r0
+	movl	r3,r4
+	bicl3	#-65536,r2,-328(fp)
+	mull3	r0,r4,-320(fp)
+	mull2	r1,r4
+	mull3	r1,-328(fp),-324(fp)
+	mull2	r0,-328(fp)
+	addl3	-320(fp),-324(fp),r0
+	bicl3	#0,r0,-320(fp)
+	cmpl	-320(fp),-324(fp)
+	bgequ	noname.498
+	addl2	#65536,-328(fp)
+noname.498:
+	movzwl	-318(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-328(fp)
+	bicl3	#-65536,-320(fp),r0
+	ashl	#16,r0,-324(fp)
+	addl2	-324(fp),r4
+	bicl2	#0,r4
+	cmpl	r4,-324(fp)
+	bgequ	noname.499
+	incl	-328(fp)
+noname.499:
+	movl	r4,r3
+	movl	-328(fp),r2
+	bbc	#31,r2,noname.500
+	incl	r7
+noname.500:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.501
+	incl	r2
+noname.501:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r9
+	bicl2	#0,r9
+	cmpl	r9,r3
+	bgequ	noname.502
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.502
+	incl	r7
+noname.502:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.503
+	incl	r7
+noname.503:
+
+	movl	8(ap),r0
+	movzwl	26(r0),r2
+	bicl3	#-65536,12(r0),r3
+	movzwl	14(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,24(r0),-340(fp)
+	bicl3	#-65536,r2,-344(fp)
+	mull3	r1,-340(fp),-332(fp)
+	mull2	r3,-340(fp)
+	mull3	r3,-344(fp),-336(fp)
+	mull2	r1,-344(fp)
+	addl3	-332(fp),-336(fp),r0
+	bicl3	#0,r0,-332(fp)
+	cmpl	-332(fp),-336(fp)
+	bgequ	noname.504
+	addl2	#65536,-344(fp)
+noname.504:
+	movzwl	-330(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-344(fp)
+	bicl3	#-65536,-332(fp),r0
+	ashl	#16,r0,-336(fp)
+	addl3	-336(fp),-340(fp),r0
+	bicl3	#0,r0,-340(fp)
+	cmpl	-340(fp),-336(fp)
+	bgequ	noname.505
+	incl	-344(fp)
+noname.505:
+	movl	-340(fp),r3
+	movl	-344(fp),r2
+	bbc	#31,r2,noname.506
+	incl	r7
+noname.506:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.507
+	incl	r2
+noname.507:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r9
+	bicl2	#0,r9
+	cmpl	r9,r3
+	bgequ	noname.508
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.508
+	incl	r7
+noname.508:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.509
+	incl	r7
+noname.509:
+
+	movl	8(ap),r0
+	movzwl	22(r0),r2
+	bicl3	#-65536,16(r0),r3
+	movzwl	18(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,20(r0),-356(fp)
+	bicl3	#-65536,r2,-360(fp)
+	mull3	r1,-356(fp),-348(fp)
+	mull2	r3,-356(fp)
+	mull3	r3,-360(fp),-352(fp)
+	mull2	r1,-360(fp)
+	addl3	-348(fp),-352(fp),r0
+	bicl3	#0,r0,-348(fp)
+	cmpl	-348(fp),-352(fp)
+	bgequ	noname.510
+	addl2	#65536,-360(fp)
+noname.510:
+	movzwl	-346(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-360(fp)
+	bicl3	#-65536,-348(fp),r0
+	ashl	#16,r0,-352(fp)
+	addl3	-352(fp),-356(fp),r0
+	bicl3	#0,r0,-356(fp)
+	cmpl	-356(fp),-352(fp)
+	bgequ	noname.511
+	incl	-360(fp)
+noname.511:
+	movl	-356(fp),r3
+	movl	-360(fp),r2
+	bbc	#31,r2,noname.512
+	incl	r7
+noname.512:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.513
+	incl	r2
+noname.513:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r9
+	bicl2	#0,r9
+	cmpl	r9,r3
+	bgequ	noname.514
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.514
+	incl	r7
+noname.514:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.515
+	incl	r7
+noname.515:
+
+	movl	4(ap),r0
+	movl	r9,36(r0)
+
+	clrl	r9
+
+	movl	8(ap),r3
+	movl	20(r3),r4
+	bicl3	#-65536,r4,-364(fp)
+	extzv	#16,#16,r4,r0
+	bicl3	#-65536,r0,r4
+	movl	-364(fp),r0
+	mull3	r0,r4,-368(fp)
+	mull3	r0,r0,-364(fp)
+	mull2	r4,r4
+	bicl3	#32767,-368(fp),r0
+	extzv	#15,#17,r0,r0
+	addl2	r0,r4
+	bicl3	#-65536,-368(fp),r0
+	ashl	#17,r0,-368(fp)
+	addl3	-364(fp),-368(fp),r0
+	bicl3	#0,r0,-364(fp)
+	cmpl	-364(fp),-368(fp)
+	bgequ	noname.516
+	incl	r4
+noname.516:
+	movl	-364(fp),r1
+	movl	r4,r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.517
+	incl	r2
+noname.517:
+	addl2	r2,r7
+	bicl2	#0,r7
+	cmpl	r7,r2
+	bgequ	noname.518
+	incl	r9
+noname.518:
+
+	bicl3	#-65536,24(r3),r4
+	movzwl	26(r3),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,16(r3),r2
+	movzwl	18(r3),r0
+	bicl2	#-65536,r0
+	movl	r4,r6
+	movl	r1,r5
+	mull3	r0,r6,-372(fp)
+	mull2	r2,r6
+	mull3	r2,r5,-376(fp)
+	mull2	r0,r5
+	addl3	-372(fp),-376(fp),r0
+	bicl3	#0,r0,-372(fp)
+	cmpl	-372(fp),-376(fp)
+	bgequ	noname.519
+	addl2	#65536,r5
+noname.519:
+	movzwl	-370(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r5
+	bicl3	#-65536,-372(fp),r0
+	ashl	#16,r0,-376(fp)
+	addl2	-376(fp),r6
+	bicl2	#0,r6
+	cmpl	r6,-376(fp)
+	bgequ	noname.520
+	incl	r5
+noname.520:
+	movl	r6,r3
+	movl	r5,r2
+	bbc	#31,r2,noname.521
+	incl	r9
+noname.521:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.522
+	incl	r2
+noname.522:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r8
+	bicl2	#0,r8
+	cmpl	r8,r3
+	bgequ	noname.523
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.523
+	incl	r9
+noname.523:
+	addl2	r2,r7
+	bicl2	#0,r7
+	cmpl	r7,r2
+	bgequ	noname.524
+	incl	r9
+noname.524:
+
+	movl	8(ap),r0
+	bicl3	#-65536,28(r0),r3
+	movzwl	30(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,12(r0),r2
+	movzwl	14(r0),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-380(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-384(fp)
+	mull2	r0,r4
+	addl3	-380(fp),-384(fp),r0
+	bicl3	#0,r0,-380(fp)
+	cmpl	-380(fp),-384(fp)
+	bgequ	noname.525
+	addl2	#65536,r4
+noname.525:
+	movzwl	-378(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-380(fp),r0
+	ashl	#16,r0,-384(fp)
+	addl2	-384(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-384(fp)
+	bgequ	noname.526
+	incl	r4
+noname.526:
+	movl	r5,r3
+	movl	r4,r2
+	bbc	#31,r2,noname.527
+	incl	r9
+noname.527:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.528
+	incl	r2
+noname.528:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r8
+	bicl2	#0,r8
+	cmpl	r8,r3
+	bgequ	noname.529
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.529
+	incl	r9
+noname.529:
+	addl2	r2,r7
+	bicl2	#0,r7
+	cmpl	r7,r2
+	bgequ	noname.530
+	incl	r9
+noname.530:
+	movl	4(ap),r0
+	movl	r8,40(r0)
+
+	clrl	r8
+
+	movl	8(ap),r0
+	bicl3	#-65536,28(r0),r3
+	movzwl	30(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,16(r0),r2
+	movzwl	18(r0),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-388(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-392(fp)
+	mull2	r0,r4
+	addl3	-388(fp),-392(fp),r0
+	bicl3	#0,r0,-388(fp)
+	cmpl	-388(fp),-392(fp)
+	bgequ	noname.531
+	addl2	#65536,r4
+noname.531:
+	movzwl	-386(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-388(fp),r0
+	ashl	#16,r0,-392(fp)
+	addl2	-392(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-392(fp)
+	bgequ	noname.532
+	incl	r4
+noname.532:
+	movl	r5,r3
+	movl	r4,r2
+	bbc	#31,r2,noname.533
+	incl	r8
+noname.533:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.534
+	incl	r2
+noname.534:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r7
+	bicl2	#0,r7
+	cmpl	r7,r3
+	bgequ	noname.535
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.535
+	incl	r8
+noname.535:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.536
+	incl	r8
+noname.536:
+
+	movl	8(ap),r0
+	bicl3	#-65536,24(r0),r3
+	movzwl	26(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,20(r0),r2
+	movzwl	22(r0),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-396(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-400(fp)
+	mull2	r0,r4
+	addl3	-396(fp),-400(fp),r0
+	bicl3	#0,r0,-396(fp)
+	cmpl	-396(fp),-400(fp)
+	bgequ	noname.537
+	addl2	#65536,r4
+noname.537:
+	movzwl	-394(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-396(fp),r0
+	ashl	#16,r0,-400(fp)
+	addl2	-400(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-400(fp)
+	bgequ	noname.538
+	incl	r4
+noname.538:
+	movl	r5,r3
+	movl	r4,r2
+	bbc	#31,r2,noname.539
+	incl	r8
+noname.539:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.540
+	incl	r2
+noname.540:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r7
+	bicl2	#0,r7
+	cmpl	r7,r3
+	bgequ	noname.541
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.541
+	incl	r8
+noname.541:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.542
+	incl	r8
+noname.542:
+
+	movl	4(ap),r0
+	movl	r7,44(r0)
+
+	clrl	r7
+
+	movl	8(ap),r3
+	movl	24(r3),r4
+	bicl3	#-65536,r4,r5
+	extzv	#16,#16,r4,r0
+	bicl3	#-65536,r0,r4
+	mull3	r5,r4,-404(fp)
+	mull2	r5,r5
+	mull2	r4,r4
+	bicl3	#32767,-404(fp),r0
+	extzv	#15,#17,r0,r0
+	addl2	r0,r4
+	bicl3	#-65536,-404(fp),r0
+	ashl	#17,r0,-404(fp)
+	addl2	-404(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-404(fp)
+	bgequ	noname.543
+	incl	r4
+noname.543:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.544
+	incl	r2
+noname.544:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.545
+	incl	r7
+noname.545:
+
+	movzwl	30(r3),r2
+	bicl3	#-65536,20(r3),r1
+	movzwl	22(r3),r0
+	bicl2	#-65536,r0
+	bicl3	#-65536,28(r3),-416(fp)
+	bicl3	#-65536,r2,-420(fp)
+	mull3	r0,-416(fp),-408(fp)
+	mull2	r1,-416(fp)
+	mull3	r1,-420(fp),-412(fp)
+	mull2	r0,-420(fp)
+	addl3	-408(fp),-412(fp),r0
+	bicl3	#0,r0,-408(fp)
+	cmpl	-408(fp),-412(fp)
+	bgequ	noname.546
+	addl2	#65536,-420(fp)
+noname.546:
+	movzwl	-406(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-420(fp)
+	bicl3	#-65536,-408(fp),r0
+	ashl	#16,r0,-412(fp)
+	addl3	-412(fp),-416(fp),r0
+	bicl3	#0,r0,-416(fp)
+	cmpl	-416(fp),-412(fp)
+	bgequ	noname.547
+	incl	-420(fp)
+noname.547:
+	movl	-416(fp),r3
+	movl	-420(fp),r2
+	bbc	#31,r2,noname.548
+	incl	r7
+noname.548:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.549
+	incl	r2
+noname.549:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r9
+	bicl2	#0,r9
+	cmpl	r9,r3
+	bgequ	noname.550
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.550
+	incl	r7
+noname.550:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.551
+	incl	r7
+noname.551:
+
+	movl	4(ap),r0
+	movl	r9,48(r0)
+
+	clrl	r9
+
+	movl	8(ap),r0
+	movzwl	30(r0),r2
+	bicl3	#-65536,24(r0),r3
+	movzwl	26(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,28(r0),-432(fp)
+	bicl3	#-65536,r2,-436(fp)
+	mull3	r1,-432(fp),-424(fp)
+	mull2	r3,-432(fp)
+	mull3	r3,-436(fp),-428(fp)
+	mull2	r1,-436(fp)
+	addl3	-424(fp),-428(fp),r0
+	bicl3	#0,r0,-424(fp)
+	cmpl	-424(fp),-428(fp)
+	bgequ	noname.552
+	addl2	#65536,-436(fp)
+noname.552:
+	movzwl	-422(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,-436(fp)
+	bicl3	#-65536,-424(fp),r0
+	ashl	#16,r0,-428(fp)
+	addl3	-428(fp),-432(fp),r0
+	bicl3	#0,r0,-432(fp)
+	cmpl	-432(fp),-428(fp)
+	bgequ	noname.553
+	incl	-436(fp)
+noname.553:
+	movl	-432(fp),r3
+	movl	-436(fp),r2
+	bbc	#31,r2,noname.554
+	incl	r9
+noname.554:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.555
+	incl	r2
+noname.555:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r8
+	bicl2	#0,r8
+	cmpl	r8,r3
+	bgequ	noname.556
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.556
+	incl	r9
+noname.556:
+	addl2	r2,r7
+	bicl2	#0,r7
+	cmpl	r7,r2
+	bgequ	noname.557
+	incl	r9
+noname.557:
+
+	movl	4(ap),r4
+	movl	r8,52(r4)
+
+	clrl	r8
+
+	movl	8(ap),r0
+	movl	28(r0),r3
+	bicl3	#-65536,r3,-440(fp)
+	extzv	#16,#16,r3,r0
+	bicl3	#-65536,r0,r3
+	movl	-440(fp),r0
+	mull3	r0,r3,-444(fp)
+	mull3	r0,r0,-440(fp)
+	mull2	r3,r3
+	bicl3	#32767,-444(fp),r0
+	extzv	#15,#17,r0,r0
+	addl2	r0,r3
+	bicl3	#-65536,-444(fp),r0
+	ashl	#17,r0,-444(fp)
+	addl3	-440(fp),-444(fp),r0
+	bicl3	#0,r0,-440(fp)
+	cmpl	-440(fp),-444(fp)
+	bgequ	noname.558
+	incl	r3
+noname.558:
+	movl	-440(fp),r1
+	movl	r3,r2
+	addl2	r1,r7
+	bicl2	#0,r7
+	cmpl	r7,r1
+	bgequ	noname.559
+	incl	r2
+noname.559:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.560
+	incl	r8
+noname.560:
+
+	movl	r7,56(r4)
+
+	movl	r9,60(r4)
+
+	ret	
+
+
+
+;r=4 ;(AP)
+;a=8 ;(AP)
+;b=12 ;(AP)
+;n=16 ;(AP)	n	by value (input)
+
+	.psect	code,nowrt
+
+.entry	BN_SQR_COMBA4,^m<r2,r3,r4,r5,r6,r7,r8,r9,r10>
+	subl2	#44,sp
+
+	clrq	r8
+
+	clrl	r10
+
+	movl	8(ap),r5
+	movl	(r5),r3
+	bicl3	#-65536,r3,r4
+	extzv	#16,#16,r3,r0
+	bicl3	#-65536,r0,r3
+	mull3	r4,r3,-4(fp)
+	mull2	r4,r4
+	mull2	r3,r3
+	bicl3	#32767,-4(fp),r0
+	extzv	#15,#17,r0,r0
+	addl2	r0,r3
+	bicl3	#-65536,-4(fp),r0
+	ashl	#17,r0,-4(fp)
+	addl2	-4(fp),r4
+	bicl2	#0,r4
+	cmpl	r4,-4(fp)
+	bgequ	noname.563
+	incl	r3
+noname.563:
+	movl	r4,r1
+	movl	r3,r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.564
+	incl	r2
+noname.564:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.565
+	incl	r10
+noname.565:
+
+	movl	r9,@4(ap)
+
+	clrl	r9
+
+	bicl3	#-65536,4(r5),r3
+	movzwl	6(r5),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,(r5),r2
+	movzwl	2(r5),r0
+	bicl2	#-65536,r0
+	movl	r3,r6
+	movl	r1,r4
+	mull3	r0,r6,-8(fp)
+	mull2	r2,r6
+	mull2	r4,r2
+	mull2	r0,r4
+	addl3	-8(fp),r2,r0
+	bicl3	#0,r0,-8(fp)
+	cmpl	-8(fp),r2
+	bgequ	noname.566
+	addl2	#65536,r4
+noname.566:
+	movzwl	-6(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-8(fp),r0
+	ashl	#16,r0,r1
+	addl2	r1,r6
+	bicl2	#0,r6
+	cmpl	r6,r1
+	bgequ	noname.567
+	incl	r4
+noname.567:
+	movl	r6,r3
+	movl	r4,r2
+	bbc	#31,r2,noname.568
+	incl	r9
+noname.568:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.569
+	incl	r2
+noname.569:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r8
+	bicl2	#0,r8
+	cmpl	r8,r3
+	bgequ	noname.570
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.570
+	incl	r9
+noname.570:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.571
+	incl	r9
+noname.571:
+
+	movl	4(ap),r0
+	movl	r8,4(r0)
+
+	clrl	r8
+
+	movl	8(ap),r4
+	movl	4(r4),r3
+	bicl3	#-65536,r3,r5
+	extzv	#16,#16,r3,r0
+	bicl3	#-65536,r0,r3
+	mull3	r5,r3,r1
+	mull2	r5,r5
+	mull2	r3,r3
+	bicl3	#32767,r1,r0
+	extzv	#15,#17,r0,r0
+	addl2	r0,r3
+	bicl2	#-65536,r1
+	ashl	#17,r1,r1
+	addl2	r1,r5
+	bicl2	#0,r5
+	cmpl	r5,r1
+	bgequ	noname.572
+	incl	r3
+noname.572:
+	movl	r5,r1
+	movl	r3,r2
+	addl2	r1,r10
+	bicl2	#0,r10
+	cmpl	r10,r1
+	bgequ	noname.573
+	incl	r2
+noname.573:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.574
+	incl	r8
+noname.574:
+
+	bicl3	#-65536,8(r4),r3
+	movzwl	10(r4),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,(r4),r2
+	movzwl	2(r4),r0
+	bicl2	#-65536,r0
+	movl	r3,r6
+	movl	r1,r5
+	mull3	r0,r6,r7
+	mull2	r2,r6
+	mull2	r5,r2
+	mull2	r0,r5
+	addl2	r2,r7
+	bicl2	#0,r7
+	cmpl	r7,r2
+	bgequ	noname.575
+	addl2	#65536,r5
+noname.575:
+	extzv	#16,#16,r7,r0
+	bicl2	#-65536,r0
+	addl2	r0,r5
+	bicl3	#-65536,r7,r0
+	ashl	#16,r0,r1
+	addl2	r1,r6
+	bicl2	#0,r6
+	cmpl	r6,r1
+	bgequ	noname.576
+	incl	r5
+noname.576:
+	movl	r6,r3
+	movl	r5,r2
+	bbc	#31,r2,noname.577
+	incl	r8
+noname.577:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.578
+	incl	r2
+noname.578:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r10
+	bicl2	#0,r10
+	cmpl	r10,r3
+	bgequ	noname.579
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.579
+	incl	r8
+noname.579:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.580
+	incl	r8
+noname.580:
+
+	movl	4(ap),r0
+	movl	r10,8(r0)
+
+	clrl	r10
+
+	movl	8(ap),r0
+	bicl3	#-65536,12(r0),r3
+	movzwl	14(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,(r0),r2
+	movzwl	2(r0),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,r6
+	mull2	r2,r5
+	mull3	r2,r4,-12(fp)
+	mull2	r0,r4
+	addl2	-12(fp),r6
+	bicl2	#0,r6
+	cmpl	r6,-12(fp)
+	bgequ	noname.581
+	addl2	#65536,r4
+noname.581:
+	extzv	#16,#16,r6,r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,r6,r0
+	ashl	#16,r0,-12(fp)
+	addl2	-12(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-12(fp)
+	bgequ	noname.582
+	incl	r4
+noname.582:
+	movl	r5,r3
+	movl	r4,r2
+	bbc	#31,r2,noname.583
+	incl	r10
+noname.583:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.584
+	incl	r2
+noname.584:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r9
+	bicl2	#0,r9
+	cmpl	r9,r3
+	bgequ	noname.585
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.585
+	incl	r10
+noname.585:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.586
+	incl	r10
+noname.586:
+
+	movl	8(ap),r0
+	bicl3	#-65536,8(r0),r3
+	movzwl	10(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,4(r0),r2
+	movzwl	6(r0),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-16(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-20(fp)
+	mull2	r0,r4
+	addl3	-16(fp),-20(fp),r0
+	bicl3	#0,r0,-16(fp)
+	cmpl	-16(fp),-20(fp)
+	bgequ	noname.587
+	addl2	#65536,r4
+noname.587:
+	movzwl	-14(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-16(fp),r0
+	ashl	#16,r0,-20(fp)
+	addl2	-20(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-20(fp)
+	bgequ	noname.588
+	incl	r4
+noname.588:
+	movl	r5,r3
+	movl	r4,r2
+	bbc	#31,r2,noname.589
+	incl	r10
+noname.589:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.590
+	incl	r2
+noname.590:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r9
+	bicl2	#0,r9
+	cmpl	r9,r3
+	bgequ	noname.591
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.591
+	incl	r10
+noname.591:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.592
+	incl	r10
+noname.592:
+	movl	4(ap),r0
+	movl	r9,12(r0)
+
+	clrl	r9
+
+	movl	8(ap),r3
+	movl	8(r3),r4
+	bicl3	#-65536,r4,r5
+	extzv	#16,#16,r4,r0
+	bicl3	#-65536,r0,r4
+	mull3	r5,r4,-24(fp)
+	mull2	r5,r5
+	mull2	r4,r4
+	bicl3	#32767,-24(fp),r0
+	extzv	#15,#17,r0,r0
+	addl2	r0,r4
+	bicl3	#-65536,-24(fp),r0
+	ashl	#17,r0,-24(fp)
+	addl2	-24(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-24(fp)
+	bgequ	noname.593
+	incl	r4
+noname.593:
+	movl	r5,r1
+	movl	r4,r2
+	addl2	r1,r8
+	bicl2	#0,r8
+	cmpl	r8,r1
+	bgequ	noname.594
+	incl	r2
+noname.594:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.595
+	incl	r9
+noname.595:
+
+	bicl3	#-65536,12(r3),r4
+	movzwl	14(r3),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,4(r3),r2
+	movzwl	6(r3),r0
+	bicl2	#-65536,r0
+	movl	r4,r6
+	movl	r1,r5
+	mull3	r0,r6,-28(fp)
+	mull2	r2,r6
+	mull3	r2,r5,-32(fp)
+	mull2	r0,r5
+	addl3	-28(fp),-32(fp),r0
+	bicl3	#0,r0,-28(fp)
+	cmpl	-28(fp),-32(fp)
+	bgequ	noname.596
+	addl2	#65536,r5
+noname.596:
+	movzwl	-26(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r5
+	bicl3	#-65536,-28(fp),r0
+	ashl	#16,r0,-32(fp)
+	addl2	-32(fp),r6
+	bicl2	#0,r6
+	cmpl	r6,-32(fp)
+	bgequ	noname.597
+	incl	r5
+noname.597:
+	movl	r6,r3
+	movl	r5,r2
+	bbc	#31,r2,noname.598
+	incl	r9
+noname.598:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.599
+	incl	r2
+noname.599:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r8
+	bicl2	#0,r8
+	cmpl	r8,r3
+	bgequ	noname.600
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.600
+	incl	r9
+noname.600:
+	addl2	r2,r10
+	bicl2	#0,r10
+	cmpl	r10,r2
+	bgequ	noname.601
+	incl	r9
+noname.601:
+
+	movl	4(ap),r0
+	movl	r8,16(r0)
+
+	clrl	r8
+
+	movl	8(ap),r0
+	bicl3	#-65536,12(r0),r3
+	movzwl	14(r0),r1
+	bicl2	#-65536,r1
+	bicl3	#-65536,8(r0),r2
+	movzwl	10(r0),r0
+	bicl2	#-65536,r0
+	movl	r3,r5
+	movl	r1,r4
+	mull3	r0,r5,-36(fp)
+	mull2	r2,r5
+	mull3	r2,r4,-40(fp)
+	mull2	r0,r4
+	addl3	-36(fp),-40(fp),r0
+	bicl3	#0,r0,-36(fp)
+	cmpl	-36(fp),-40(fp)
+	bgequ	noname.602
+	addl2	#65536,r4
+noname.602:
+	movzwl	-34(fp),r0
+	bicl2	#-65536,r0
+	addl2	r0,r4
+	bicl3	#-65536,-36(fp),r0
+	ashl	#16,r0,-40(fp)
+	addl2	-40(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-40(fp)
+	bgequ	noname.603
+	incl	r4
+noname.603:
+	movl	r5,r3
+	movl	r4,r2
+	bbc	#31,r2,noname.604
+	incl	r8
+noname.604:
+	addl2	r2,r2
+	bicl2	#0,r2
+	bbc	#31,r3,noname.605
+	incl	r2
+noname.605:
+	addl2	r3,r3
+	bicl2	#0,r3
+	addl2	r3,r10
+	bicl2	#0,r10
+	cmpl	r10,r3
+	bgequ	noname.606
+	incl	r2
+	bicl3	#0,r2,r0
+	bneq	noname.606
+	incl	r8
+noname.606:
+	addl2	r2,r9
+	bicl2	#0,r9
+	cmpl	r9,r2
+	bgequ	noname.607
+	incl	r8
+noname.607:
+
+	movl	4(ap),r4
+	movl	r10,20(r4)
+
+	clrl	r10
+
+	movl	8(ap),r0
+	movl	12(r0),r3
+	bicl3	#-65536,r3,r5
+	extzv	#16,#16,r3,r0
+	bicl3	#-65536,r0,r3
+	mull3	r5,r3,-44(fp)
+	mull2	r5,r5
+	mull2	r3,r3
+	bicl3	#32767,-44(fp),r0
+	extzv	#15,#17,r0,r0
+	addl2	r0,r3
+	bicl3	#-65536,-44(fp),r0
+	ashl	#17,r0,-44(fp)
+	addl2	-44(fp),r5
+	bicl2	#0,r5
+	cmpl	r5,-44(fp)
+	bgequ	noname.608
+	incl	r3
+noname.608:
+	movl	r5,r1
+	movl	r3,r2
+	addl2	r1,r9
+	bicl2	#0,r9
+	cmpl	r9,r1
+	bgequ	noname.609
+	incl	r2
+noname.609:
+	addl2	r2,r8
+	bicl2	#0,r8
+	cmpl	r8,r2
+	bgequ	noname.610
+	incl	r10
+noname.610:
+
+	movl	r9,24(r4)
+
+	movl	r8,28(r4)
+
+	ret	
+
+; For now, the code below doesn't work, so I end this prematurely.
+.end
diff --git a/openssl/crypto/bn/asm/x86-mont.pl b/openssl/crypto/bn/asm/x86-mont.pl
new file mode 100644
index 0000000..e8f6b05
--- /dev/null
+++ b/openssl/crypto/bn/asm/x86-mont.pl
@@ -0,0 +1,593 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# October 2005
+#
+# This is a "teaser" code, as it can be improved in several ways...
+# First of all non-SSE2 path should be implemented (yes, for now it
+# performs Montgomery multiplication/convolution only on SSE2-capable
+# CPUs such as P4, others fall down to original code). Then inner loop
+# can be unrolled and modulo-scheduled to improve ILP and possibly
+# moved to 128-bit XMM register bank (though it would require input
+# rearrangement and/or increase bus bandwidth utilization). Dedicated
+# squaring procedure should give further performance improvement...
+# Yet, for being draft, the code improves rsa512 *sign* benchmark by
+# 110%(!), rsa1024 one - by 70% and rsa4096 - by 20%:-)
+
+# December 2006
+#
+# Modulo-scheduling SSE2 loops results in further 15-20% improvement.
+# Integer-only code [being equipped with dedicated squaring procedure]
+# gives ~40% on rsa512 sign benchmark...
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],$0);
+
+$sse2=0;
+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
+
+&external_label("OPENSSL_ia32cap_P") if ($sse2);
+
+&function_begin("bn_mul_mont");
+
+$i="edx";
+$j="ecx";
+$ap="esi";	$tp="esi";		# overlapping variables!!!
+$rp="edi";	$bp="edi";		# overlapping variables!!!
+$np="ebp";
+$num="ebx";
+
+$_num=&DWP(4*0,"esp");			# stack top layout
+$_rp=&DWP(4*1,"esp");
+$_ap=&DWP(4*2,"esp");
+$_bp=&DWP(4*3,"esp");
+$_np=&DWP(4*4,"esp");
+$_n0=&DWP(4*5,"esp");	$_n0q=&QWP(4*5,"esp");
+$_sp=&DWP(4*6,"esp");
+$_bpend=&DWP(4*7,"esp");
+$frame=32;				# size of above frame rounded up to 16n
+
+	&xor	("eax","eax");
+	&mov	("edi",&wparam(5));	# int num
+	&cmp	("edi",4);
+	&jl	(&label("just_leave"));
+
+	&lea	("esi",&wparam(0));	# put aside pointer to argument block
+	&lea	("edx",&wparam(1));	# load ap
+	&mov	("ebp","esp");		# saved stack pointer!
+	&add	("edi",2);		# extra two words on top of tp
+	&neg	("edi");
+	&lea	("esp",&DWP(-$frame,"esp","edi",4));	# alloca($frame+4*(num+2))
+	&neg	("edi");
+
+	# minimize cache contention by arraning 2K window between stack
+	# pointer and ap argument [np is also position sensitive vector,
+	# but it's assumed to be near ap, as it's allocated at ~same
+	# time].
+	&mov	("eax","esp");
+	&sub	("eax","edx");
+	&and	("eax",2047);
+	&sub	("esp","eax");		# this aligns sp and ap modulo 2048
+
+	&xor	("edx","esp");
+	&and	("edx",2048);
+	&xor	("edx",2048);
+	&sub	("esp","edx");		# this splits them apart modulo 4096
+
+	&and	("esp",-64);		# align to cache line
+
+	################################# load argument block...
+	&mov	("eax",&DWP(0*4,"esi"));# BN_ULONG *rp
+	&mov	("ebx",&DWP(1*4,"esi"));# const BN_ULONG *ap
+	&mov	("ecx",&DWP(2*4,"esi"));# const BN_ULONG *bp
+	&mov	("edx",&DWP(3*4,"esi"));# const BN_ULONG *np
+	&mov	("esi",&DWP(4*4,"esi"));# const BN_ULONG *n0
+	#&mov	("edi",&DWP(5*4,"esi"));# int num
+
+	&mov	("esi",&DWP(0,"esi"));	# pull n0[0]
+	&mov	($_rp,"eax");		# ... save a copy of argument block
+	&mov	($_ap,"ebx");
+	&mov	($_bp,"ecx");
+	&mov	($_np,"edx");
+	&mov	($_n0,"esi");
+	&lea	($num,&DWP(-3,"edi"));	# num=num-1 to assist modulo-scheduling
+	#&mov	($_num,$num);		# redundant as $num is not reused
+	&mov	($_sp,"ebp");		# saved stack pointer!
+
+if($sse2) {
+$acc0="mm0";	# mmx register bank layout
+$acc1="mm1";
+$car0="mm2";
+$car1="mm3";
+$mul0="mm4";
+$mul1="mm5";
+$temp="mm6";
+$mask="mm7";
+
+	&picmeup("eax","OPENSSL_ia32cap_P");
+	&bt	(&DWP(0,"eax"),26);
+	&jnc	(&label("non_sse2"));
+
+	&mov	("eax",-1);
+	&movd	($mask,"eax");		# mask 32 lower bits
+
+	&mov	($ap,$_ap);		# load input pointers
+	&mov	($bp,$_bp);
+	&mov	($np,$_np);
+
+	&xor	($i,$i);		# i=0
+	&xor	($j,$j);		# j=0
+
+	&movd	($mul0,&DWP(0,$bp));		# bp[0]
+	&movd	($mul1,&DWP(0,$ap));		# ap[0]
+	&movd	($car1,&DWP(0,$np));		# np[0]
+
+	&pmuludq($mul1,$mul0);			# ap[0]*bp[0]
+	&movq	($car0,$mul1);
+	&movq	($acc0,$mul1);			# I wish movd worked for
+	&pand	($acc0,$mask);			# inter-register transfers
+
+	&pmuludq($mul1,$_n0q);			# *=n0
+
+	&pmuludq($car1,$mul1);			# "t[0]"*np[0]*n0
+	&paddq	($car1,$acc0);
+
+	&movd	($acc1,&DWP(4,$np));		# np[1]
+	&movd	($acc0,&DWP(4,$ap));		# ap[1]
+
+	&psrlq	($car0,32);
+	&psrlq	($car1,32);
+
+	&inc	($j);				# j++
+&set_label("1st",16);
+	&pmuludq($acc0,$mul0);			# ap[j]*bp[0]
+	&pmuludq($acc1,$mul1);			# np[j]*m1
+	&paddq	($car0,$acc0);			# +=c0
+	&paddq	($car1,$acc1);			# +=c1
+
+	&movq	($acc0,$car0);
+	&pand	($acc0,$mask);
+	&movd	($acc1,&DWP(4,$np,$j,4));	# np[j+1]
+	&paddq	($car1,$acc0);			# +=ap[j]*bp[0];
+	&movd	($acc0,&DWP(4,$ap,$j,4));	# ap[j+1]
+	&psrlq	($car0,32);
+	&movd	(&DWP($frame-4,"esp",$j,4),$car1);	# tp[j-1]=
+	&psrlq	($car1,32);
+
+	&lea	($j,&DWP(1,$j));
+	&cmp	($j,$num);
+	&jl	(&label("1st"));
+
+	&pmuludq($acc0,$mul0);			# ap[num-1]*bp[0]
+	&pmuludq($acc1,$mul1);			# np[num-1]*m1
+	&paddq	($car0,$acc0);			# +=c0
+	&paddq	($car1,$acc1);			# +=c1
+
+	&movq	($acc0,$car0);
+	&pand	($acc0,$mask);
+	&paddq	($car1,$acc0);			# +=ap[num-1]*bp[0];
+	&movd	(&DWP($frame-4,"esp",$j,4),$car1);	# tp[num-2]=
+
+	&psrlq	($car0,32);
+	&psrlq	($car1,32);
+
+	&paddq	($car1,$car0);
+	&movq	(&QWP($frame,"esp",$num,4),$car1);	# tp[num].tp[num-1]
+
+	&inc	($i);				# i++
+&set_label("outer");
+	&xor	($j,$j);			# j=0
+
+	&movd	($mul0,&DWP(0,$bp,$i,4));	# bp[i]
+	&movd	($mul1,&DWP(0,$ap));		# ap[0]
+	&movd	($temp,&DWP($frame,"esp"));	# tp[0]
+	&movd	($car1,&DWP(0,$np));		# np[0]
+	&pmuludq($mul1,$mul0);			# ap[0]*bp[i]
+
+	&paddq	($mul1,$temp);			# +=tp[0]
+	&movq	($acc0,$mul1);
+	&movq	($car0,$mul1);
+	&pand	($acc0,$mask);
+
+	&pmuludq($mul1,$_n0q);			# *=n0
+
+	&pmuludq($car1,$mul1);
+	&paddq	($car1,$acc0);
+
+	&movd	($temp,&DWP($frame+4,"esp"));	# tp[1]
+	&movd	($acc1,&DWP(4,$np));		# np[1]
+	&movd	($acc0,&DWP(4,$ap));		# ap[1]
+
+	&psrlq	($car0,32);
+	&psrlq	($car1,32);
+	&paddq	($car0,$temp);			# +=tp[1]
+
+	&inc	($j);				# j++
+	&dec	($num);
+&set_label("inner");
+	&pmuludq($acc0,$mul0);			# ap[j]*bp[i]
+	&pmuludq($acc1,$mul1);			# np[j]*m1
+	&paddq	($car0,$acc0);			# +=c0
+	&paddq	($car1,$acc1);			# +=c1
+
+	&movq	($acc0,$car0);
+	&movd	($temp,&DWP($frame+4,"esp",$j,4));# tp[j+1]
+	&pand	($acc0,$mask);
+	&movd	($acc1,&DWP(4,$np,$j,4));	# np[j+1]
+	&paddq	($car1,$acc0);			# +=ap[j]*bp[i]+tp[j]
+	&movd	($acc0,&DWP(4,$ap,$j,4));	# ap[j+1]
+	&psrlq	($car0,32);
+	&movd	(&DWP($frame-4,"esp",$j,4),$car1);# tp[j-1]=
+	&psrlq	($car1,32);
+	&paddq	($car0,$temp);			# +=tp[j+1]
+
+	&dec	($num);
+	&lea	($j,&DWP(1,$j));		# j++
+	&jnz	(&label("inner"));
+
+	&mov	($num,$j);
+	&pmuludq($acc0,$mul0);			# ap[num-1]*bp[i]
+	&pmuludq($acc1,$mul1);			# np[num-1]*m1
+	&paddq	($car0,$acc0);			# +=c0
+	&paddq	($car1,$acc1);			# +=c1
+
+	&movq	($acc0,$car0);
+	&pand	($acc0,$mask);
+	&paddq	($car1,$acc0);			# +=ap[num-1]*bp[i]+tp[num-1]
+	&movd	(&DWP($frame-4,"esp",$j,4),$car1);	# tp[num-2]=
+	&psrlq	($car0,32);
+	&psrlq	($car1,32);
+
+	&movd	($temp,&DWP($frame+4,"esp",$num,4));	# += tp[num]
+	&paddq	($car1,$car0);
+	&paddq	($car1,$temp);
+	&movq	(&QWP($frame,"esp",$num,4),$car1);	# tp[num].tp[num-1]
+
+	&lea	($i,&DWP(1,$i));		# i++
+	&cmp	($i,$num);
+	&jle	(&label("outer"));
+
+	&emms	();				# done with mmx bank
+	&jmp	(&label("common_tail"));
+
+&set_label("non_sse2",16);
+}
+
+if (0) {
+	&mov	("esp",$_sp);
+	&xor	("eax","eax");	# signal "not fast enough [yet]"
+	&jmp	(&label("just_leave"));
+	# While the below code provides competitive performance for
+	# all key lengthes on modern Intel cores, it's still more
+	# than 10% slower for 4096-bit key elsewhere:-( "Competitive"
+	# means compared to the original integer-only assembler.
+	# 512-bit RSA sign is better by ~40%, but that's about all
+	# one can say about all CPUs...
+} else {
+$inp="esi";	# integer path uses these registers differently
+$word="edi";
+$carry="ebp";
+
+	&mov	($inp,$_ap);
+	&lea	($carry,&DWP(1,$num));
+	&mov	($word,$_bp);
+	&xor	($j,$j);				# j=0
+	&mov	("edx",$inp);
+	&and	($carry,1);				# see if num is even
+	&sub	("edx",$word);				# see if ap==bp
+	&lea	("eax",&DWP(4,$word,$num,4));		# &bp[num]
+	&or	($carry,"edx");
+	&mov	($word,&DWP(0,$word));			# bp[0]
+	&jz	(&label("bn_sqr_mont"));
+	&mov	($_bpend,"eax");
+	&mov	("eax",&DWP(0,$inp));
+	&xor	("edx","edx");
+
+&set_label("mull",16);
+	&mov	($carry,"edx");
+	&mul	($word);				# ap[j]*bp[0]
+	&add	($carry,"eax");
+	&lea	($j,&DWP(1,$j));
+	&adc	("edx",0);
+	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[j+1]
+	&cmp	($j,$num);
+	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j]=
+	&jl	(&label("mull"));
+
+	&mov	($carry,"edx");
+	&mul	($word);				# ap[num-1]*bp[0]
+	 &mov	($word,$_n0);
+	&add	("eax",$carry);
+	 &mov	($inp,$_np);
+	&adc	("edx",0);
+	 &imul	($word,&DWP($frame,"esp"));		# n0*tp[0]
+
+	&mov	(&DWP($frame,"esp",$num,4),"eax");	# tp[num-1]=
+	&xor	($j,$j);
+	&mov	(&DWP($frame+4,"esp",$num,4),"edx");	# tp[num]=
+	&mov	(&DWP($frame+8,"esp",$num,4),$j);	# tp[num+1]=
+
+	&mov	("eax",&DWP(0,$inp));			# np[0]
+	&mul	($word);				# np[0]*m
+	&add	("eax",&DWP($frame,"esp"));		# +=tp[0]
+	&mov	("eax",&DWP(4,$inp));			# np[1]
+	&adc	("edx",0);
+	&inc	($j);
+
+	&jmp	(&label("2ndmadd"));
+
+&set_label("1stmadd",16);
+	&mov	($carry,"edx");
+	&mul	($word);				# ap[j]*bp[i]
+	&add	($carry,&DWP($frame,"esp",$j,4));	# +=tp[j]
+	&lea	($j,&DWP(1,$j));
+	&adc	("edx",0);
+	&add	($carry,"eax");
+	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[j+1]
+	&adc	("edx",0);
+	&cmp	($j,$num);
+	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j]=
+	&jl	(&label("1stmadd"));
+
+	&mov	($carry,"edx");
+	&mul	($word);				# ap[num-1]*bp[i]
+	&add	("eax",&DWP($frame,"esp",$num,4));	# +=tp[num-1]
+	 &mov	($word,$_n0);
+	&adc	("edx",0);
+	 &mov	($inp,$_np);
+	&add	($carry,"eax");
+	&adc	("edx",0);
+	 &imul	($word,&DWP($frame,"esp"));		# n0*tp[0]
+
+	&xor	($j,$j);
+	&add	("edx",&DWP($frame+4,"esp",$num,4));	# carry+=tp[num]
+	&mov	(&DWP($frame,"esp",$num,4),$carry);	# tp[num-1]=
+	&adc	($j,0);
+	 &mov	("eax",&DWP(0,$inp));			# np[0]
+	&mov	(&DWP($frame+4,"esp",$num,4),"edx");	# tp[num]=
+	&mov	(&DWP($frame+8,"esp",$num,4),$j);	# tp[num+1]=
+
+	&mul	($word);				# np[0]*m
+	&add	("eax",&DWP($frame,"esp"));		# +=tp[0]
+	&mov	("eax",&DWP(4,$inp));			# np[1]
+	&adc	("edx",0);
+	&mov	($j,1);
+
+&set_label("2ndmadd",16);
+	&mov	($carry,"edx");
+	&mul	($word);				# np[j]*m
+	&add	($carry,&DWP($frame,"esp",$j,4));	# +=tp[j]
+	&lea	($j,&DWP(1,$j));
+	&adc	("edx",0);
+	&add	($carry,"eax");
+	&mov	("eax",&DWP(0,$inp,$j,4));		# np[j+1]
+	&adc	("edx",0);
+	&cmp	($j,$num);
+	&mov	(&DWP($frame-8,"esp",$j,4),$carry);	# tp[j-1]=
+	&jl	(&label("2ndmadd"));
+
+	&mov	($carry,"edx");
+	&mul	($word);				# np[j]*m
+	&add	($carry,&DWP($frame,"esp",$num,4));	# +=tp[num-1]
+	&adc	("edx",0);
+	&add	($carry,"eax");
+	&adc	("edx",0);
+	&mov	(&DWP($frame-4,"esp",$num,4),$carry);	# tp[num-2]=
+
+	&xor	("eax","eax");
+	 &mov	($j,$_bp);				# &bp[i]
+	&add	("edx",&DWP($frame+4,"esp",$num,4));	# carry+=tp[num]
+	&adc	("eax",&DWP($frame+8,"esp",$num,4));	# +=tp[num+1]
+	 &lea	($j,&DWP(4,$j));
+	&mov	(&DWP($frame,"esp",$num,4),"edx");	# tp[num-1]=
+	 &cmp	($j,$_bpend);
+	&mov	(&DWP($frame+4,"esp",$num,4),"eax");	# tp[num]=
+	&je	(&label("common_tail"));
+
+	&mov	($word,&DWP(0,$j));			# bp[i+1]
+	&mov	($inp,$_ap);
+	&mov	($_bp,$j);				# &bp[++i]
+	&xor	($j,$j);
+	&xor	("edx","edx");
+	&mov	("eax",&DWP(0,$inp));
+	&jmp	(&label("1stmadd"));
+
+&set_label("bn_sqr_mont",16);
+$sbit=$num;
+	&mov	($_num,$num);
+	&mov	($_bp,$j);				# i=0
+
+	&mov	("eax",$word);				# ap[0]
+	&mul	($word);				# ap[0]*ap[0]
+	&mov	(&DWP($frame,"esp"),"eax");		# tp[0]=
+	&mov	($sbit,"edx");
+	&shr	("edx",1);
+	&and	($sbit,1);
+	&inc	($j);
+&set_label("sqr",16);
+	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[j]
+	&mov	($carry,"edx");
+	&mul	($word);				# ap[j]*ap[0]
+	&add	("eax",$carry);
+	&lea	($j,&DWP(1,$j));
+	&adc	("edx",0);
+	&lea	($carry,&DWP(0,$sbit,"eax",2));
+	&shr	("eax",31);
+	&cmp	($j,$_num);
+	&mov	($sbit,"eax");
+	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j]=
+	&jl	(&label("sqr"));
+
+	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[num-1]
+	&mov	($carry,"edx");
+	&mul	($word);				# ap[num-1]*ap[0]
+	&add	("eax",$carry);
+	 &mov	($word,$_n0);
+	&adc	("edx",0);
+	 &mov	($inp,$_np);
+	&lea	($carry,&DWP(0,$sbit,"eax",2));
+	 &imul	($word,&DWP($frame,"esp"));		# n0*tp[0]
+	&shr	("eax",31);
+	&mov	(&DWP($frame,"esp",$j,4),$carry);	# tp[num-1]=
+
+	&lea	($carry,&DWP(0,"eax","edx",2));
+	 &mov	("eax",&DWP(0,$inp));			# np[0]
+	&shr	("edx",31);
+	&mov	(&DWP($frame+4,"esp",$j,4),$carry);	# tp[num]=
+	&mov	(&DWP($frame+8,"esp",$j,4),"edx");	# tp[num+1]=
+
+	&mul	($word);				# np[0]*m
+	&add	("eax",&DWP($frame,"esp"));		# +=tp[0]
+	&mov	($num,$j);
+	&adc	("edx",0);
+	&mov	("eax",&DWP(4,$inp));			# np[1]
+	&mov	($j,1);
+
+&set_label("3rdmadd",16);
+	&mov	($carry,"edx");
+	&mul	($word);				# np[j]*m
+	&add	($carry,&DWP($frame,"esp",$j,4));	# +=tp[j]
+	&adc	("edx",0);
+	&add	($carry,"eax");
+	&mov	("eax",&DWP(4,$inp,$j,4));		# np[j+1]
+	&adc	("edx",0);
+	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j-1]=
+
+	&mov	($carry,"edx");
+	&mul	($word);				# np[j+1]*m
+	&add	($carry,&DWP($frame+4,"esp",$j,4));	# +=tp[j+1]
+	&lea	($j,&DWP(2,$j));
+	&adc	("edx",0);
+	&add	($carry,"eax");
+	&mov	("eax",&DWP(0,$inp,$j,4));		# np[j+2]
+	&adc	("edx",0);
+	&cmp	($j,$num);
+	&mov	(&DWP($frame-8,"esp",$j,4),$carry);	# tp[j]=
+	&jl	(&label("3rdmadd"));
+
+	&mov	($carry,"edx");
+	&mul	($word);				# np[j]*m
+	&add	($carry,&DWP($frame,"esp",$num,4));	# +=tp[num-1]
+	&adc	("edx",0);
+	&add	($carry,"eax");
+	&adc	("edx",0);
+	&mov	(&DWP($frame-4,"esp",$num,4),$carry);	# tp[num-2]=
+
+	&mov	($j,$_bp);				# i
+	&xor	("eax","eax");
+	&mov	($inp,$_ap);
+	&add	("edx",&DWP($frame+4,"esp",$num,4));	# carry+=tp[num]
+	&adc	("eax",&DWP($frame+8,"esp",$num,4));	# +=tp[num+1]
+	&mov	(&DWP($frame,"esp",$num,4),"edx");	# tp[num-1]=
+	&cmp	($j,$num);
+	&mov	(&DWP($frame+4,"esp",$num,4),"eax");	# tp[num]=
+	&je	(&label("common_tail"));
+
+	&mov	($word,&DWP(4,$inp,$j,4));		# ap[i]
+	&lea	($j,&DWP(1,$j));
+	&mov	("eax",$word);
+	&mov	($_bp,$j);				# ++i
+	&mul	($word);				# ap[i]*ap[i]
+	&add	("eax",&DWP($frame,"esp",$j,4));	# +=tp[i]
+	&adc	("edx",0);
+	&mov	(&DWP($frame,"esp",$j,4),"eax");	# tp[i]=
+	&xor	($carry,$carry);
+	&cmp	($j,$num);
+	&lea	($j,&DWP(1,$j));
+	&je	(&label("sqrlast"));
+
+	&mov	($sbit,"edx");				# zaps $num
+	&shr	("edx",1);
+	&and	($sbit,1);
+&set_label("sqradd",16);
+	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[j]
+	&mov	($carry,"edx");
+	&mul	($word);				# ap[j]*ap[i]
+	&add	("eax",$carry);
+	&lea	($carry,&DWP(0,"eax","eax"));
+	&adc	("edx",0);
+	&shr	("eax",31);
+	&add	($carry,&DWP($frame,"esp",$j,4));	# +=tp[j]
+	&lea	($j,&DWP(1,$j));
+	&adc	("eax",0);
+	&add	($carry,$sbit);
+	&adc	("eax",0);
+	&cmp	($j,$_num);
+	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j]=
+	&mov	($sbit,"eax");
+	&jle	(&label("sqradd"));
+
+	&mov	($carry,"edx");
+	&add	("edx","edx");
+	&shr	($carry,31);
+	&add	("edx",$sbit);
+	&adc	($carry,0);
+&set_label("sqrlast");
+	&mov	($word,$_n0);
+	&mov	($inp,$_np);
+	&imul	($word,&DWP($frame,"esp"));		# n0*tp[0]
+
+	&add	("edx",&DWP($frame,"esp",$j,4));	# +=tp[num]
+	&mov	("eax",&DWP(0,$inp));			# np[0]
+	&adc	($carry,0);
+	&mov	(&DWP($frame,"esp",$j,4),"edx");	# tp[num]=
+	&mov	(&DWP($frame+4,"esp",$j,4),$carry);	# tp[num+1]=
+
+	&mul	($word);				# np[0]*m
+	&add	("eax",&DWP($frame,"esp"));		# +=tp[0]
+	&lea	($num,&DWP(-1,$j));
+	&adc	("edx",0);
+	&mov	($j,1);
+	&mov	("eax",&DWP(4,$inp));			# np[1]
+
+	&jmp	(&label("3rdmadd"));
+}
+
+&set_label("common_tail",16);
+	&mov	($np,$_np);			# load modulus pointer
+	&mov	($rp,$_rp);			# load result pointer
+	&lea	($tp,&DWP($frame,"esp"));	# [$ap and $bp are zapped]
+
+	&mov	("eax",&DWP(0,$tp));		# tp[0]
+	&mov	($j,$num);			# j=num-1
+	&xor	($i,$i);			# i=0 and clear CF!
+
+&set_label("sub",16);
+	&sbb	("eax",&DWP(0,$np,$i,4));
+	&mov	(&DWP(0,$rp,$i,4),"eax");	# rp[i]=tp[i]-np[i]
+	&dec	($j);				# doesn't affect CF!
+	&mov	("eax",&DWP(4,$tp,$i,4));	# tp[i+1]
+	&lea	($i,&DWP(1,$i));		# i++
+	&jge	(&label("sub"));
+
+	&sbb	("eax",0);			# handle upmost overflow bit
+	&and	($tp,"eax");
+	&not	("eax");
+	&mov	($np,$rp);
+	&and	($np,"eax");
+	&or	($tp,$np);			# tp=carry?tp:rp
+
+&set_label("copy",16);				# copy or in-place refresh
+	&mov	("eax",&DWP(0,$tp,$num,4));
+	&mov	(&DWP(0,$rp,$num,4),"eax");	# rp[i]=tp[i]
+	&mov	(&DWP($frame,"esp",$num,4),$j);	# zap temporary vector
+	&dec	($num);
+	&jge	(&label("copy"));
+
+	&mov	("esp",$_sp);		# pull saved stack pointer
+	&mov	("eax",1);
+&set_label("just_leave");
+&function_end("bn_mul_mont");
+
+&asciz("Montgomery Multiplication for x86, CRYPTOGAMS by <appro\@openssl.org>");
+
+&asm_finish();
diff --git a/openssl/crypto/bn/asm/x86.pl b/openssl/crypto/bn/asm/x86.pl
new file mode 100644
index 0000000..1bc4f1b
--- /dev/null
+++ b/openssl/crypto/bn/asm/x86.pl
@@ -0,0 +1,28 @@
+#!/usr/local/bin/perl
+
+push(@INC,"perlasm","../../perlasm");
+require "x86asm.pl";
+
+require("x86/mul_add.pl");
+require("x86/mul.pl");
+require("x86/sqr.pl");
+require("x86/div.pl");
+require("x86/add.pl");
+require("x86/sub.pl");
+require("x86/comba.pl");
+
+&asm_init($ARGV[0],$0);
+
+&bn_mul_add_words("bn_mul_add_words");
+&bn_mul_words("bn_mul_words");
+&bn_sqr_words("bn_sqr_words");
+&bn_div_words("bn_div_words");
+&bn_add_words("bn_add_words");
+&bn_sub_words("bn_sub_words");
+&bn_mul_comba("bn_mul_comba8",8);
+&bn_mul_comba("bn_mul_comba4",4);
+&bn_sqr_comba("bn_sqr_comba8",8);
+&bn_sqr_comba("bn_sqr_comba4",4);
+
+&asm_finish();
+
diff --git a/openssl/crypto/bn/asm/x86/add.pl b/openssl/crypto/bn/asm/x86/add.pl
new file mode 100644
index 0000000..0b5cf58
--- /dev/null
+++ b/openssl/crypto/bn/asm/x86/add.pl
@@ -0,0 +1,76 @@
+#!/usr/local/bin/perl
+# x86 assember
+
+sub bn_add_words
+	{
+	local($name)=@_;
+
+	&function_begin($name,"");
+
+	&comment("");
+	$a="esi";
+	$b="edi";
+	$c="eax";
+	$r="ebx";
+	$tmp1="ecx";
+	$tmp2="edx";
+	$num="ebp";
+
+	&mov($r,&wparam(0));	# get r
+	 &mov($a,&wparam(1));	# get a
+	&mov($b,&wparam(2));	# get b
+	 &mov($num,&wparam(3));	# get num
+	&xor($c,$c);		# clear carry
+	 &and($num,0xfffffff8);	# num / 8
+
+	&jz(&label("aw_finish"));
+
+	&set_label("aw_loop",0);
+	for ($i=0; $i<8; $i++)
+		{
+		&comment("Round $i");
+
+		&mov($tmp1,&DWP($i*4,$a,"",0)); 	# *a
+		 &mov($tmp2,&DWP($i*4,$b,"",0)); 	# *b
+		&add($tmp1,$c);
+		 &mov($c,0);
+		&adc($c,$c);
+		 &add($tmp1,$tmp2);
+		&adc($c,0);
+		 &mov(&DWP($i*4,$r,"",0),$tmp1); 	# *r
+		}
+
+	&comment("");
+	&add($a,32);
+	 &add($b,32);
+	&add($r,32);
+	 &sub($num,8);
+	&jnz(&label("aw_loop"));
+
+	&set_label("aw_finish",0);
+	&mov($num,&wparam(3));	# get num
+	&and($num,7);
+	 &jz(&label("aw_end"));
+
+	for ($i=0; $i<7; $i++)
+		{
+		&comment("Tail Round $i");
+		&mov($tmp1,&DWP($i*4,$a,"",0));	# *a
+		 &mov($tmp2,&DWP($i*4,$b,"",0));# *b
+		&add($tmp1,$c);
+		 &mov($c,0);
+		&adc($c,$c);
+		 &add($tmp1,$tmp2);
+		&adc($c,0);
+		 &dec($num) if ($i != 6);
+		&mov(&DWP($i*4,$r,"",0),$tmp1);	# *a
+		 &jz(&label("aw_end")) if ($i != 6);
+		}
+	&set_label("aw_end",0);
+
+#	&mov("eax",$c);		# $c is "eax"
+
+	&function_end($name);
+	}
+
+1;
diff --git a/openssl/crypto/bn/asm/x86/comba.pl b/openssl/crypto/bn/asm/x86/comba.pl
new file mode 100644
index 0000000..2291253
--- /dev/null
+++ b/openssl/crypto/bn/asm/x86/comba.pl
@@ -0,0 +1,277 @@
+#!/usr/local/bin/perl
+# x86 assember
+
+sub mul_add_c
+	{
+	local($a,$ai,$b,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
+
+	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
+	# words, and 1 if load return value
+
+	&comment("mul a[$ai]*b[$bi]");
+
+	# "eax" and "edx" will always be pre-loaded.
+	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
+	# &mov("edx",&DWP($bi*4,$b,"",0));
+
+	&mul("edx");
+	&add($c0,"eax");
+	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# laod next a
+	 &mov("eax",&wparam(0)) if $pos > 0;			# load r[]
+	 ###
+	&adc($c1,"edx");
+	 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 0;	# laod next b
+	 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1;	# laod next b
+	 ###
+	&adc($c2,0);
+	 # is pos > 1, it means it is the last loop 
+	 &mov(&DWP($i*4,"eax","",0),$c0) if $pos > 0;		# save r[];
+	&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;		# laod next a
+	}
+
+sub sqr_add_c
+	{
+	local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
+
+	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
+	# words, and 1 if load return value
+
+	&comment("sqr a[$ai]*a[$bi]");
+
+	# "eax" and "edx" will always be pre-loaded.
+	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
+	# &mov("edx",&DWP($bi*4,$b,"",0));
+
+	if ($ai == $bi)
+		{ &mul("eax");}
+	else
+		{ &mul("edx");}
+	&add($c0,"eax");
+	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# load next a
+	 ###
+	&adc($c1,"edx");
+	 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos == 1) && ($na != $nb);
+	 ###
+	&adc($c2,0);
+	 # is pos > 1, it means it is the last loop 
+	 &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0;		# save r[];
+	&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;		# load next b
+	}
+
+sub sqr_add_c2
+	{
+	local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
+
+	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
+	# words, and 1 if load return value
+
+	&comment("sqr a[$ai]*a[$bi]");
+
+	# "eax" and "edx" will always be pre-loaded.
+	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
+	# &mov("edx",&DWP($bi*4,$a,"",0));
+
+	if ($ai == $bi)
+		{ &mul("eax");}
+	else
+		{ &mul("edx");}
+	&add("eax","eax");
+	 ###
+	&adc("edx","edx");
+	 ###
+	&adc($c2,0);
+	 &add($c0,"eax");
+	&adc($c1,"edx");
+	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# load next a
+	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;	# load next b
+	&adc($c2,0);
+	&mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0;		# save r[];
+	 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos <= 1) && ($na != $nb);
+	 ###
+	}
+
+sub bn_mul_comba
+	{
+	local($name,$num)=@_;
+	local($a,$b,$c0,$c1,$c2);
+	local($i,$as,$ae,$bs,$be,$ai,$bi);
+	local($tot,$end);
+
+	&function_begin_B($name,"");
+
+	$c0="ebx";
+	$c1="ecx";
+	$c2="ebp";
+	$a="esi";
+	$b="edi";
+	
+	$as=0;
+	$ae=0;
+	$bs=0;
+	$be=0;
+	$tot=$num+$num-1;
+
+	&push("esi");
+	 &mov($a,&wparam(1));
+	&push("edi");
+	 &mov($b,&wparam(2));
+	&push("ebp");
+	 &push("ebx");
+
+	&xor($c0,$c0);
+	 &mov("eax",&DWP(0,$a,"",0));	# load the first word 
+	&xor($c1,$c1);
+	 &mov("edx",&DWP(0,$b,"",0));	# load the first second 
+
+	for ($i=0; $i<$tot; $i++)
+		{
+		$ai=$as;
+		$bi=$bs;
+		$end=$be+1;
+
+		&comment("################## Calculate word $i"); 
+
+		for ($j=$bs; $j<$end; $j++)
+			{
+			&xor($c2,$c2) if ($j == $bs);
+			if (($j+1) == $end)
+				{
+				$v=1;
+				$v=2 if (($i+1) == $tot);
+				}
+			else
+				{ $v=0; }
+			if (($j+1) != $end)
+				{
+				$na=($ai-1);
+				$nb=($bi+1);
+				}
+			else
+				{
+				$na=$as+($i < ($num-1));
+				$nb=$bs+($i >= ($num-1));
+				}
+#printf STDERR "[$ai,$bi] -> [$na,$nb]\n";
+			&mul_add_c($a,$ai,$b,$bi,$c0,$c1,$c2,$v,$i,$na,$nb);
+			if ($v)
+				{
+				&comment("saved r[$i]");
+				# &mov("eax",&wparam(0));
+				# &mov(&DWP($i*4,"eax","",0),$c0);
+				($c0,$c1,$c2)=($c1,$c2,$c0);
+				}
+			$ai--;
+			$bi++;
+			}
+		$as++ if ($i < ($num-1));
+		$ae++ if ($i >= ($num-1));
+
+		$bs++ if ($i >= ($num-1));
+		$be++ if ($i < ($num-1));
+		}
+	&comment("save r[$i]");
+	# &mov("eax",&wparam(0));
+	&mov(&DWP($i*4,"eax","",0),$c0);
+
+	&pop("ebx");
+	&pop("ebp");
+	&pop("edi");
+	&pop("esi");
+	&ret();
+	&function_end_B($name);
+	}
+
+sub bn_sqr_comba
+	{
+	local($name,$num)=@_;
+	local($r,$a,$c0,$c1,$c2)=@_;
+	local($i,$as,$ae,$bs,$be,$ai,$bi);
+	local($b,$tot,$end,$half);
+
+	&function_begin_B($name,"");
+
+	$c0="ebx";
+	$c1="ecx";
+	$c2="ebp";
+	$a="esi";
+	$r="edi";
+
+	&push("esi");
+	 &push("edi");
+	&push("ebp");
+	 &push("ebx");
+	&mov($r,&wparam(0));
+	 &mov($a,&wparam(1));
+	&xor($c0,$c0);
+	 &xor($c1,$c1);
+	&mov("eax",&DWP(0,$a,"",0)); # load the first word
+
+	$as=0;
+	$ae=0;
+	$bs=0;
+	$be=0;
+	$tot=$num+$num-1;
+
+	for ($i=0; $i<$tot; $i++)
+		{
+		$ai=$as;
+		$bi=$bs;
+		$end=$be+1;
+
+		&comment("############### Calculate word $i");
+		for ($j=$bs; $j<$end; $j++)
+			{
+			&xor($c2,$c2) if ($j == $bs);
+			if (($ai-1) < ($bi+1))
+				{
+				$v=1;
+				$v=2 if ($i+1) == $tot;
+				}
+			else
+				{ $v=0; }
+			if (!$v)
+				{
+				$na=$ai-1;
+				$nb=$bi+1;
+				}
+			else
+				{
+				$na=$as+($i < ($num-1));
+				$nb=$bs+($i >= ($num-1));
+				}
+			if ($ai == $bi)
+				{
+				&sqr_add_c($r,$a,$ai,$bi,
+					$c0,$c1,$c2,$v,$i,$na,$nb);
+				}
+			else
+				{
+				&sqr_add_c2($r,$a,$ai,$bi,
+					$c0,$c1,$c2,$v,$i,$na,$nb);
+				}
+			if ($v)
+				{
+				&comment("saved r[$i]");
+				#&mov(&DWP($i*4,$r,"",0),$c0);
+				($c0,$c1,$c2)=($c1,$c2,$c0);
+				last;
+				}
+			$ai--;
+			$bi++;
+			}
+		$as++ if ($i < ($num-1));
+		$ae++ if ($i >= ($num-1));
+
+		$bs++ if ($i >= ($num-1));
+		$be++ if ($i < ($num-1));
+		}
+	&mov(&DWP($i*4,$r,"",0),$c0);
+	&pop("ebx");
+	&pop("ebp");
+	&pop("edi");
+	&pop("esi");
+	&ret();
+	&function_end_B($name);
+	}
+
+1;
diff --git a/openssl/crypto/bn/asm/x86/div.pl b/openssl/crypto/bn/asm/x86/div.pl
new file mode 100644
index 0000000..0e90152
--- /dev/null
+++ b/openssl/crypto/bn/asm/x86/div.pl
@@ -0,0 +1,15 @@
+#!/usr/local/bin/perl
+# x86 assember
+
+sub bn_div_words
+	{
+	local($name)=@_;
+
+	&function_begin($name,"");
+	&mov("edx",&wparam(0));	#
+	&mov("eax",&wparam(1));	#
+	&mov("ebx",&wparam(2));	#
+	&div("ebx");
+	&function_end($name);
+	}
+1;
diff --git a/openssl/crypto/bn/asm/x86/f b/openssl/crypto/bn/asm/x86/f
new file mode 100644
index 0000000..22e4112
--- /dev/null
+++ b/openssl/crypto/bn/asm/x86/f
@@ -0,0 +1,3 @@
+#!/usr/local/bin/perl
+# x86 assember
+
diff --git a/openssl/crypto/bn/asm/x86/mul.pl b/openssl/crypto/bn/asm/x86/mul.pl
new file mode 100644
index 0000000..674cb9b
--- /dev/null
+++ b/openssl/crypto/bn/asm/x86/mul.pl
@@ -0,0 +1,77 @@
+#!/usr/local/bin/perl
+# x86 assember
+
+sub bn_mul_words
+	{
+	local($name)=@_;
+
+	&function_begin($name,"");
+
+	&comment("");
+	$Low="eax";
+	$High="edx";
+	$a="ebx";
+	$w="ecx";
+	$r="edi";
+	$c="esi";
+	$num="ebp";
+
+	&xor($c,$c);		# clear carry
+	&mov($r,&wparam(0));	#
+	&mov($a,&wparam(1));	#
+	&mov($num,&wparam(2));	#
+	&mov($w,&wparam(3));	#
+
+	&and($num,0xfffffff8);	# num / 8
+	&jz(&label("mw_finish"));
+
+	&set_label("mw_loop",0);
+	for ($i=0; $i<32; $i+=4)
+		{
+		&comment("Round $i");
+
+		 &mov("eax",&DWP($i,$a,"",0)); 	# *a
+		&mul($w);			# *a * w
+		&add("eax",$c);			# L(t)+=c
+		 # XXX
+
+		&adc("edx",0);			# H(t)+=carry
+		 &mov(&DWP($i,$r,"",0),"eax");	# *r= L(t);
+
+		&mov($c,"edx");			# c=  H(t);
+		}
+
+	&comment("");
+	&add($a,32);
+	&add($r,32);
+	&sub($num,8);
+	&jz(&label("mw_finish"));
+	&jmp(&label("mw_loop"));
+
+	&set_label("mw_finish",0);
+	&mov($num,&wparam(2));	# get num
+	&and($num,7);
+	&jnz(&label("mw_finish2"));
+	&jmp(&label("mw_end"));
+
+	&set_label("mw_finish2",1);
+	for ($i=0; $i<7; $i++)
+		{
+		&comment("Tail Round $i");
+		 &mov("eax",&DWP($i*4,$a,"",0));# *a
+		&mul($w);			# *a * w
+		&add("eax",$c);			# L(t)+=c
+		 # XXX
+		&adc("edx",0);			# H(t)+=carry
+		 &mov(&DWP($i*4,$r,"",0),"eax");# *r= L(t);
+		&mov($c,"edx");			# c=  H(t);
+		 &dec($num) if ($i != 7-1);
+		&jz(&label("mw_end")) if ($i != 7-1);
+		}
+	&set_label("mw_end",0);
+	&mov("eax",$c);
+
+	&function_end($name);
+	}
+
+1;
diff --git a/openssl/crypto/bn/asm/x86/mul_add.pl b/openssl/crypto/bn/asm/x86/mul_add.pl
new file mode 100644
index 0000000..61830d3
--- /dev/null
+++ b/openssl/crypto/bn/asm/x86/mul_add.pl
@@ -0,0 +1,87 @@
+#!/usr/local/bin/perl
+# x86 assember
+
+sub bn_mul_add_words
+	{
+	local($name)=@_;
+
+	&function_begin($name,"");
+
+	&comment("");
+	$Low="eax";
+	$High="edx";
+	$a="ebx";
+	$w="ebp";
+	$r="edi";
+	$c="esi";
+
+	&xor($c,$c);		# clear carry
+	&mov($r,&wparam(0));	#
+
+	&mov("ecx",&wparam(2));	#
+	&mov($a,&wparam(1));	#
+
+	&and("ecx",0xfffffff8);	# num / 8
+	&mov($w,&wparam(3));	#
+
+	&push("ecx");		# Up the stack for a tmp variable
+
+	&jz(&label("maw_finish"));
+
+	&set_label("maw_loop",0);
+
+	&mov(&swtmp(0),"ecx");	#
+
+	for ($i=0; $i<32; $i+=4)
+		{
+		&comment("Round $i");
+
+		 &mov("eax",&DWP($i,$a,"",0)); 	# *a
+		&mul($w);			# *a * w
+		&add("eax",$c);		# L(t)+= *r
+		 &mov($c,&DWP($i,$r,"",0));	# L(t)+= *r
+		&adc("edx",0);			# H(t)+=carry
+		 &add("eax",$c);		# L(t)+=c
+		&adc("edx",0);			# H(t)+=carry
+		 &mov(&DWP($i,$r,"",0),"eax");	# *r= L(t);
+		&mov($c,"edx");			# c=  H(t);
+		}
+
+	&comment("");
+	&mov("ecx",&swtmp(0));	#
+	&add($a,32);
+	&add($r,32);
+	&sub("ecx",8);
+	&jnz(&label("maw_loop"));
+
+	&set_label("maw_finish",0);
+	&mov("ecx",&wparam(2));	# get num
+	&and("ecx",7);
+	&jnz(&label("maw_finish2"));	# helps branch prediction
+	&jmp(&label("maw_end"));
+
+	&set_label("maw_finish2",1);
+	for ($i=0; $i<7; $i++)
+		{
+		&comment("Tail Round $i");
+		 &mov("eax",&DWP($i*4,$a,"",0));# *a
+		&mul($w);			# *a * w
+		&add("eax",$c);			# L(t)+=c
+		 &mov($c,&DWP($i*4,$r,"",0));	# L(t)+= *r
+		&adc("edx",0);			# H(t)+=carry
+		 &add("eax",$c);
+		&adc("edx",0);			# H(t)+=carry
+		 &dec("ecx") if ($i != 7-1);
+		&mov(&DWP($i*4,$r,"",0),"eax");	# *r= L(t);
+		 &mov($c,"edx");			# c=  H(t);
+		&jz(&label("maw_end")) if ($i != 7-1);
+		}
+	&set_label("maw_end",0);
+	&mov("eax",$c);
+
+	&pop("ecx");	# clear variable from
+
+	&function_end($name);
+	}
+
+1;
diff --git a/openssl/crypto/bn/asm/x86/sqr.pl b/openssl/crypto/bn/asm/x86/sqr.pl
new file mode 100644
index 0000000..1f90993
--- /dev/null
+++ b/openssl/crypto/bn/asm/x86/sqr.pl
@@ -0,0 +1,60 @@
+#!/usr/local/bin/perl
+# x86 assember
+
+sub bn_sqr_words
+	{
+	local($name)=@_;
+
+	&function_begin($name,"");
+
+	&comment("");
+	$r="esi";
+	$a="edi";
+	$num="ebx";
+
+	&mov($r,&wparam(0));	#
+	&mov($a,&wparam(1));	#
+	&mov($num,&wparam(2));	#
+
+	&and($num,0xfffffff8);	# num / 8
+	&jz(&label("sw_finish"));
+
+	&set_label("sw_loop",0);
+	for ($i=0; $i<32; $i+=4)
+		{
+		&comment("Round $i");
+		&mov("eax",&DWP($i,$a,"",0)); 	# *a
+		 # XXX
+		&mul("eax");			# *a * *a
+		&mov(&DWP($i*2,$r,"",0),"eax");	#
+		 &mov(&DWP($i*2+4,$r,"",0),"edx");#
+		}
+
+	&comment("");
+	&add($a,32);
+	&add($r,64);
+	&sub($num,8);
+	&jnz(&label("sw_loop"));
+
+	&set_label("sw_finish",0);
+	&mov($num,&wparam(2));	# get num
+	&and($num,7);
+	&jz(&label("sw_end"));
+
+	for ($i=0; $i<7; $i++)
+		{
+		&comment("Tail Round $i");
+		&mov("eax",&DWP($i*4,$a,"",0));	# *a
+		 # XXX
+		&mul("eax");			# *a * *a
+		&mov(&DWP($i*8,$r,"",0),"eax");	#
+		 &dec($num) if ($i != 7-1);
+		&mov(&DWP($i*8+4,$r,"",0),"edx");
+		 &jz(&label("sw_end")) if ($i != 7-1);
+		}
+	&set_label("sw_end",0);
+
+	&function_end($name);
+	}
+
+1;
diff --git a/openssl/crypto/bn/asm/x86/sub.pl b/openssl/crypto/bn/asm/x86/sub.pl
new file mode 100644
index 0000000..837b0e1
--- /dev/null
+++ b/openssl/crypto/bn/asm/x86/sub.pl
@@ -0,0 +1,76 @@
+#!/usr/local/bin/perl
+# x86 assember
+
+sub bn_sub_words
+	{
+	local($name)=@_;
+
+	&function_begin($name,"");
+
+	&comment("");
+	$a="esi";
+	$b="edi";
+	$c="eax";
+	$r="ebx";
+	$tmp1="ecx";
+	$tmp2="edx";
+	$num="ebp";
+
+	&mov($r,&wparam(0));	# get r
+	 &mov($a,&wparam(1));	# get a
+	&mov($b,&wparam(2));	# get b
+	 &mov($num,&wparam(3));	# get num
+	&xor($c,$c);		# clear carry
+	 &and($num,0xfffffff8);	# num / 8
+
+	&jz(&label("aw_finish"));
+
+	&set_label("aw_loop",0);
+	for ($i=0; $i<8; $i++)
+		{
+		&comment("Round $i");
+
+		&mov($tmp1,&DWP($i*4,$a,"",0)); 	# *a
+		 &mov($tmp2,&DWP($i*4,$b,"",0)); 	# *b
+		&sub($tmp1,$c);
+		 &mov($c,0);
+		&adc($c,$c);
+		 &sub($tmp1,$tmp2);
+		&adc($c,0);
+		 &mov(&DWP($i*4,$r,"",0),$tmp1); 	# *r
+		}
+
+	&comment("");
+	&add($a,32);
+	 &add($b,32);
+	&add($r,32);
+	 &sub($num,8);
+	&jnz(&label("aw_loop"));
+
+	&set_label("aw_finish",0);
+	&mov($num,&wparam(3));	# get num
+	&and($num,7);
+	 &jz(&label("aw_end"));
+
+	for ($i=0; $i<7; $i++)
+		{
+		&comment("Tail Round $i");
+		&mov($tmp1,&DWP($i*4,$a,"",0));	# *a
+		 &mov($tmp2,&DWP($i*4,$b,"",0));# *b
+		&sub($tmp1,$c);
+		 &mov($c,0);
+		&adc($c,$c);
+		 &sub($tmp1,$tmp2);
+		&adc($c,0);
+		 &dec($num) if ($i != 6);
+		&mov(&DWP($i*4,$r,"",0),$tmp1);	# *a
+		 &jz(&label("aw_end")) if ($i != 6);
+		}
+	&set_label("aw_end",0);
+
+#	&mov("eax",$c);		# $c is "eax"
+
+	&function_end($name);
+	}
+
+1;
diff --git a/openssl/crypto/bn/asm/x86_64-gcc.c b/openssl/crypto/bn/asm/x86_64-gcc.c
new file mode 100644
index 0000000..acb0b40
--- /dev/null
+++ b/openssl/crypto/bn/asm/x86_64-gcc.c
@@ -0,0 +1,606 @@
+#include "../bn_lcl.h"
+#if !(defined(__GNUC__) && __GNUC__>=2)
+# include "../bn_asm.c"	/* kind of dirty hack for Sun Studio */
+#else
+/*
+ * x86_64 BIGNUM accelerator version 0.1, December 2002.
+ *
+ * Implemented by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+ * project.
+ *
+ * Rights for redistribution and usage in source and binary forms are
+ * granted according to the OpenSSL license. Warranty of any kind is
+ * disclaimed.
+ *
+ * Q. Version 0.1? It doesn't sound like Andy, he used to assign real
+ *    versions, like 1.0...
+ * A. Well, that's because this code is basically a quick-n-dirty
+ *    proof-of-concept hack. As you can see it's implemented with
+ *    inline assembler, which means that you're bound to GCC and that
+ *    there might be enough room for further improvement.
+ *
+ * Q. Why inline assembler?
+ * A. x86_64 features own ABI which I'm not familiar with. This is
+ *    why I decided to let the compiler take care of subroutine
+ *    prologue/epilogue as well as register allocation. For reference.
+ *    Win64 implements different ABI for AMD64, different from Linux.
+ *
+ * Q. How much faster does it get?
+ * A. 'apps/openssl speed rsa dsa' output with no-asm:
+ *
+ *	                  sign    verify    sign/s verify/s
+ *	rsa  512 bits   0.0006s   0.0001s   1683.8  18456.2
+ *	rsa 1024 bits   0.0028s   0.0002s    356.0   6407.0
+ *	rsa 2048 bits   0.0172s   0.0005s     58.0   1957.8
+ *	rsa 4096 bits   0.1155s   0.0018s      8.7    555.6
+ *	                  sign    verify    sign/s verify/s
+ *	dsa  512 bits   0.0005s   0.0006s   2100.8   1768.3
+ *	dsa 1024 bits   0.0014s   0.0018s    692.3    559.2
+ *	dsa 2048 bits   0.0049s   0.0061s    204.7    165.0
+ *
+ *    'apps/openssl speed rsa dsa' output with this module:
+ *
+ *	                  sign    verify    sign/s verify/s
+ *	rsa  512 bits   0.0004s   0.0000s   2767.1  33297.9
+ *	rsa 1024 bits   0.0012s   0.0001s    867.4  14674.7
+ *	rsa 2048 bits   0.0061s   0.0002s    164.0   5270.0
+ *	rsa 4096 bits   0.0384s   0.0006s     26.1   1650.8
+ *	                  sign    verify    sign/s verify/s
+ *	dsa  512 bits   0.0002s   0.0003s   4442.2   3786.3
+ *	dsa 1024 bits   0.0005s   0.0007s   1835.1   1497.4
+ *	dsa 2048 bits   0.0016s   0.0020s    620.4    504.6
+ *
+ *    For the reference. IA-32 assembler implementation performs
+ *    very much like 64-bit code compiled with no-asm on the same
+ *    machine.
+ */
+
+#ifdef _WIN64
+#define BN_ULONG unsigned long long
+#else
+#define BN_ULONG unsigned long
+#endif
+
+#undef mul
+#undef mul_add
+#undef sqr
+
+/*
+ * "m"(a), "+m"(r)	is the way to favor DirectPath µ-code;
+ * "g"(0)		let the compiler to decide where does it
+ *			want to keep the value of zero;
+ */
+#define mul_add(r,a,word,carry) do {	\
+	register BN_ULONG high,low;	\
+	asm ("mulq %3"			\
+		: "=a"(low),"=d"(high)	\
+		: "a"(word),"m"(a)	\
+		: "cc");		\
+	asm ("addq %2,%0; adcq %3,%1"	\
+		: "+r"(carry),"+d"(high)\
+		: "a"(low),"g"(0)	\
+		: "cc");		\
+	asm ("addq %2,%0; adcq %3,%1"	\
+		: "+m"(r),"+d"(high)	\
+		: "r"(carry),"g"(0)	\
+		: "cc");		\
+	carry=high;			\
+	} while (0)
+
+#define mul(r,a,word,carry) do {	\
+	register BN_ULONG high,low;	\
+	asm ("mulq %3"			\
+		: "=a"(low),"=d"(high)	\
+		: "a"(word),"g"(a)	\
+		: "cc");		\
+	asm ("addq %2,%0; adcq %3,%1"	\
+		: "+r"(carry),"+d"(high)\
+		: "a"(low),"g"(0)	\
+		: "cc");		\
+	(r)=carry, carry=high;		\
+	} while (0)
+
+#define sqr(r0,r1,a)			\
+	asm ("mulq %2"			\
+		: "=a"(r0),"=d"(r1)	\
+		: "a"(a)		\
+		: "cc");
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+	{
+	BN_ULONG c1=0;
+
+	if (num <= 0) return(c1);
+
+	while (num&~3)
+		{
+		mul_add(rp[0],ap[0],w,c1);
+		mul_add(rp[1],ap[1],w,c1);
+		mul_add(rp[2],ap[2],w,c1);
+		mul_add(rp[3],ap[3],w,c1);
+		ap+=4; rp+=4; num-=4;
+		}
+	if (num)
+		{
+		mul_add(rp[0],ap[0],w,c1); if (--num==0) return c1;
+		mul_add(rp[1],ap[1],w,c1); if (--num==0) return c1;
+		mul_add(rp[2],ap[2],w,c1); return c1;
+		}
+	
+	return(c1);
+	} 
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+	{
+	BN_ULONG c1=0;
+
+	if (num <= 0) return(c1);
+
+	while (num&~3)
+		{
+		mul(rp[0],ap[0],w,c1);
+		mul(rp[1],ap[1],w,c1);
+		mul(rp[2],ap[2],w,c1);
+		mul(rp[3],ap[3],w,c1);
+		ap+=4; rp+=4; num-=4;
+		}
+	if (num)
+		{
+		mul(rp[0],ap[0],w,c1); if (--num == 0) return c1;
+		mul(rp[1],ap[1],w,c1); if (--num == 0) return c1;
+		mul(rp[2],ap[2],w,c1);
+		}
+	return(c1);
+	} 
+
+void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
+        {
+	if (n <= 0) return;
+
+	while (n&~3)
+		{
+		sqr(r[0],r[1],a[0]);
+		sqr(r[2],r[3],a[1]);
+		sqr(r[4],r[5],a[2]);
+		sqr(r[6],r[7],a[3]);
+		a+=4; r+=8; n-=4;
+		}
+	if (n)
+		{
+		sqr(r[0],r[1],a[0]); if (--n == 0) return;
+		sqr(r[2],r[3],a[1]); if (--n == 0) return;
+		sqr(r[4],r[5],a[2]);
+		}
+	}
+
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+{	BN_ULONG ret,waste;
+
+	asm ("divq	%4"
+		: "=a"(ret),"=d"(waste)
+		: "a"(l),"d"(h),"g"(d)
+		: "cc");
+
+	return ret;
+}
+
+BN_ULONG bn_add_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int n)
+{ BN_ULONG ret=0,i=0;
+
+	if (n <= 0) return 0;
+
+	asm (
+	"	subq	%2,%2		\n"
+	".p2align 4			\n"
+	"1:	movq	(%4,%2,8),%0	\n"
+	"	adcq	(%5,%2,8),%0	\n"
+	"	movq	%0,(%3,%2,8)	\n"
+	"	leaq	1(%2),%2	\n"
+	"	loop	1b		\n"
+	"	sbbq	%0,%0		\n"
+		: "=&a"(ret),"+c"(n),"=&r"(i)
+		: "r"(rp),"r"(ap),"r"(bp)
+		: "cc"
+	);
+
+  return ret&1;
+}
+
+#ifndef SIMICS
+BN_ULONG bn_sub_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int n)
+{ BN_ULONG ret=0,i=0;
+
+	if (n <= 0) return 0;
+
+	asm (
+	"	subq	%2,%2		\n"
+	".p2align 4			\n"
+	"1:	movq	(%4,%2,8),%0	\n"
+	"	sbbq	(%5,%2,8),%0	\n"
+	"	movq	%0,(%3,%2,8)	\n"
+	"	leaq	1(%2),%2	\n"
+	"	loop	1b		\n"
+	"	sbbq	%0,%0		\n"
+		: "=&a"(ret),"+c"(n),"=&r"(i)
+		: "r"(rp),"r"(ap),"r"(bp)
+		: "cc"
+	);
+
+  return ret&1;
+}
+#else
+/* Simics 1.4<7 has buggy sbbq:-( */
+#define BN_MASK2 0xffffffffffffffffL
+BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+        {
+	BN_ULONG t1,t2;
+	int c=0;
+
+	if (n <= 0) return((BN_ULONG)0);
+
+	for (;;)
+		{
+		t1=a[0]; t2=b[0];
+		r[0]=(t1-t2-c)&BN_MASK2;
+		if (t1 != t2) c=(t1 < t2);
+		if (--n <= 0) break;
+
+		t1=a[1]; t2=b[1];
+		r[1]=(t1-t2-c)&BN_MASK2;
+		if (t1 != t2) c=(t1 < t2);
+		if (--n <= 0) break;
+
+		t1=a[2]; t2=b[2];
+		r[2]=(t1-t2-c)&BN_MASK2;
+		if (t1 != t2) c=(t1 < t2);
+		if (--n <= 0) break;
+
+		t1=a[3]; t2=b[3];
+		r[3]=(t1-t2-c)&BN_MASK2;
+		if (t1 != t2) c=(t1 < t2);
+		if (--n <= 0) break;
+
+		a+=4;
+		b+=4;
+		r+=4;
+		}
+	return(c);
+	}
+#endif
+
+/* mul_add_c(a,b,c0,c1,c2)  -- c+=a*b for three word number c=(c2,c1,c0) */
+/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
+/* sqr_add_c(a,i,c0,c1,c2)  -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
+/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
+
+#if 0
+/* original macros are kept for reference purposes */
+#define mul_add_c(a,b,c0,c1,c2) {	\
+	BN_ULONG ta=(a),tb=(b);		\
+	t1 = ta * tb;			\
+	t2 = BN_UMULT_HIGH(ta,tb);	\
+	c0 += t1; t2 += (c0<t1)?1:0;	\
+	c1 += t2; c2 += (c1<t2)?1:0;	\
+	}
+
+#define mul_add_c2(a,b,c0,c1,c2) {	\
+	BN_ULONG ta=(a),tb=(b),t0;	\
+	t1 = BN_UMULT_HIGH(ta,tb);	\
+	t0 = ta * tb;			\
+	t2 = t1+t1; c2 += (t2<t1)?1:0;	\
+	t1 = t0+t0; t2 += (t1<t0)?1:0;	\
+	c0 += t1; t2 += (c0<t1)?1:0;	\
+	c1 += t2; c2 += (c1<t2)?1:0;	\
+	}
+#else
+#define mul_add_c(a,b,c0,c1,c2)	do {	\
+	asm ("mulq %3"			\
+		: "=a"(t1),"=d"(t2)	\
+		: "a"(a),"m"(b)		\
+		: "cc");		\
+	asm ("addq %2,%0; adcq %3,%1"	\
+		: "+r"(c0),"+d"(t2)	\
+		: "a"(t1),"g"(0)	\
+		: "cc");		\
+	asm ("addq %2,%0; adcq %3,%1"	\
+		: "+r"(c1),"+r"(c2)	\
+		: "d"(t2),"g"(0)	\
+		: "cc");		\
+	} while (0)
+
+#define sqr_add_c(a,i,c0,c1,c2)	do {	\
+	asm ("mulq %2"			\
+		: "=a"(t1),"=d"(t2)	\
+		: "a"(a[i])		\
+		: "cc");		\
+	asm ("addq %2,%0; adcq %3,%1"	\
+		: "+r"(c0),"+d"(t2)	\
+		: "a"(t1),"g"(0)	\
+		: "cc");		\
+	asm ("addq %2,%0; adcq %3,%1"	\
+		: "+r"(c1),"+r"(c2)	\
+		: "d"(t2),"g"(0)	\
+		: "cc");		\
+	} while (0)
+
+#define mul_add_c2(a,b,c0,c1,c2) do {	\
+	asm ("mulq %3"			\
+		: "=a"(t1),"=d"(t2)	\
+		: "a"(a),"m"(b)		\
+		: "cc");		\
+	asm ("addq %0,%0; adcq %2,%1"	\
+		: "+d"(t2),"+r"(c2)	\
+		: "g"(0)		\
+		: "cc");		\
+	asm ("addq %0,%0; adcq %2,%1"	\
+		: "+a"(t1),"+d"(t2)	\
+		: "g"(0)		\
+		: "cc");		\
+	asm ("addq %2,%0; adcq %3,%1"	\
+		: "+r"(c0),"+d"(t2)	\
+		: "a"(t1),"g"(0)	\
+		: "cc");		\
+	asm ("addq %2,%0; adcq %3,%1"	\
+		: "+r"(c1),"+r"(c2)	\
+		: "d"(t2),"g"(0)	\
+		: "cc");		\
+	} while (0)
+#endif
+
+#define sqr_add_c2(a,i,j,c0,c1,c2)	\
+	mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+	{
+	BN_ULONG t1,t2;
+	BN_ULONG c1,c2,c3;
+
+	c1=0;
+	c2=0;
+	c3=0;
+	mul_add_c(a[0],b[0],c1,c2,c3);
+	r[0]=c1;
+	c1=0;
+	mul_add_c(a[0],b[1],c2,c3,c1);
+	mul_add_c(a[1],b[0],c2,c3,c1);
+	r[1]=c2;
+	c2=0;
+	mul_add_c(a[2],b[0],c3,c1,c2);
+	mul_add_c(a[1],b[1],c3,c1,c2);
+	mul_add_c(a[0],b[2],c3,c1,c2);
+	r[2]=c3;
+	c3=0;
+	mul_add_c(a[0],b[3],c1,c2,c3);
+	mul_add_c(a[1],b[2],c1,c2,c3);
+	mul_add_c(a[2],b[1],c1,c2,c3);
+	mul_add_c(a[3],b[0],c1,c2,c3);
+	r[3]=c1;
+	c1=0;
+	mul_add_c(a[4],b[0],c2,c3,c1);
+	mul_add_c(a[3],b[1],c2,c3,c1);
+	mul_add_c(a[2],b[2],c2,c3,c1);
+	mul_add_c(a[1],b[3],c2,c3,c1);
+	mul_add_c(a[0],b[4],c2,c3,c1);
+	r[4]=c2;
+	c2=0;
+	mul_add_c(a[0],b[5],c3,c1,c2);
+	mul_add_c(a[1],b[4],c3,c1,c2);
+	mul_add_c(a[2],b[3],c3,c1,c2);
+	mul_add_c(a[3],b[2],c3,c1,c2);
+	mul_add_c(a[4],b[1],c3,c1,c2);
+	mul_add_c(a[5],b[0],c3,c1,c2);
+	r[5]=c3;
+	c3=0;
+	mul_add_c(a[6],b[0],c1,c2,c3);
+	mul_add_c(a[5],b[1],c1,c2,c3);
+	mul_add_c(a[4],b[2],c1,c2,c3);
+	mul_add_c(a[3],b[3],c1,c2,c3);
+	mul_add_c(a[2],b[4],c1,c2,c3);
+	mul_add_c(a[1],b[5],c1,c2,c3);
+	mul_add_c(a[0],b[6],c1,c2,c3);
+	r[6]=c1;
+	c1=0;
+	mul_add_c(a[0],b[7],c2,c3,c1);
+	mul_add_c(a[1],b[6],c2,c3,c1);
+	mul_add_c(a[2],b[5],c2,c3,c1);
+	mul_add_c(a[3],b[4],c2,c3,c1);
+	mul_add_c(a[4],b[3],c2,c3,c1);
+	mul_add_c(a[5],b[2],c2,c3,c1);
+	mul_add_c(a[6],b[1],c2,c3,c1);
+	mul_add_c(a[7],b[0],c2,c3,c1);
+	r[7]=c2;
+	c2=0;
+	mul_add_c(a[7],b[1],c3,c1,c2);
+	mul_add_c(a[6],b[2],c3,c1,c2);
+	mul_add_c(a[5],b[3],c3,c1,c2);
+	mul_add_c(a[4],b[4],c3,c1,c2);
+	mul_add_c(a[3],b[5],c3,c1,c2);
+	mul_add_c(a[2],b[6],c3,c1,c2);
+	mul_add_c(a[1],b[7],c3,c1,c2);
+	r[8]=c3;
+	c3=0;
+	mul_add_c(a[2],b[7],c1,c2,c3);
+	mul_add_c(a[3],b[6],c1,c2,c3);
+	mul_add_c(a[4],b[5],c1,c2,c3);
+	mul_add_c(a[5],b[4],c1,c2,c3);
+	mul_add_c(a[6],b[3],c1,c2,c3);
+	mul_add_c(a[7],b[2],c1,c2,c3);
+	r[9]=c1;
+	c1=0;
+	mul_add_c(a[7],b[3],c2,c3,c1);
+	mul_add_c(a[6],b[4],c2,c3,c1);
+	mul_add_c(a[5],b[5],c2,c3,c1);
+	mul_add_c(a[4],b[6],c2,c3,c1);
+	mul_add_c(a[3],b[7],c2,c3,c1);
+	r[10]=c2;
+	c2=0;
+	mul_add_c(a[4],b[7],c3,c1,c2);
+	mul_add_c(a[5],b[6],c3,c1,c2);
+	mul_add_c(a[6],b[5],c3,c1,c2);
+	mul_add_c(a[7],b[4],c3,c1,c2);
+	r[11]=c3;
+	c3=0;
+	mul_add_c(a[7],b[5],c1,c2,c3);
+	mul_add_c(a[6],b[6],c1,c2,c3);
+	mul_add_c(a[5],b[7],c1,c2,c3);
+	r[12]=c1;
+	c1=0;
+	mul_add_c(a[6],b[7],c2,c3,c1);
+	mul_add_c(a[7],b[6],c2,c3,c1);
+	r[13]=c2;
+	c2=0;
+	mul_add_c(a[7],b[7],c3,c1,c2);
+	r[14]=c3;
+	r[15]=c1;
+	}
+
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+	{
+	BN_ULONG t1,t2;
+	BN_ULONG c1,c2,c3;
+
+	c1=0;
+	c2=0;
+	c3=0;
+	mul_add_c(a[0],b[0],c1,c2,c3);
+	r[0]=c1;
+	c1=0;
+	mul_add_c(a[0],b[1],c2,c3,c1);
+	mul_add_c(a[1],b[0],c2,c3,c1);
+	r[1]=c2;
+	c2=0;
+	mul_add_c(a[2],b[0],c3,c1,c2);
+	mul_add_c(a[1],b[1],c3,c1,c2);
+	mul_add_c(a[0],b[2],c3,c1,c2);
+	r[2]=c3;
+	c3=0;
+	mul_add_c(a[0],b[3],c1,c2,c3);
+	mul_add_c(a[1],b[2],c1,c2,c3);
+	mul_add_c(a[2],b[1],c1,c2,c3);
+	mul_add_c(a[3],b[0],c1,c2,c3);
+	r[3]=c1;
+	c1=0;
+	mul_add_c(a[3],b[1],c2,c3,c1);
+	mul_add_c(a[2],b[2],c2,c3,c1);
+	mul_add_c(a[1],b[3],c2,c3,c1);
+	r[4]=c2;
+	c2=0;
+	mul_add_c(a[2],b[3],c3,c1,c2);
+	mul_add_c(a[3],b[2],c3,c1,c2);
+	r[5]=c3;
+	c3=0;
+	mul_add_c(a[3],b[3],c1,c2,c3);
+	r[6]=c1;
+	r[7]=c2;
+	}
+
+void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
+	{
+	BN_ULONG t1,t2;
+	BN_ULONG c1,c2,c3;
+
+	c1=0;
+	c2=0;
+	c3=0;
+	sqr_add_c(a,0,c1,c2,c3);
+	r[0]=c1;
+	c1=0;
+	sqr_add_c2(a,1,0,c2,c3,c1);
+	r[1]=c2;
+	c2=0;
+	sqr_add_c(a,1,c3,c1,c2);
+	sqr_add_c2(a,2,0,c3,c1,c2);
+	r[2]=c3;
+	c3=0;
+	sqr_add_c2(a,3,0,c1,c2,c3);
+	sqr_add_c2(a,2,1,c1,c2,c3);
+	r[3]=c1;
+	c1=0;
+	sqr_add_c(a,2,c2,c3,c1);
+	sqr_add_c2(a,3,1,c2,c3,c1);
+	sqr_add_c2(a,4,0,c2,c3,c1);
+	r[4]=c2;
+	c2=0;
+	sqr_add_c2(a,5,0,c3,c1,c2);
+	sqr_add_c2(a,4,1,c3,c1,c2);
+	sqr_add_c2(a,3,2,c3,c1,c2);
+	r[5]=c3;
+	c3=0;
+	sqr_add_c(a,3,c1,c2,c3);
+	sqr_add_c2(a,4,2,c1,c2,c3);
+	sqr_add_c2(a,5,1,c1,c2,c3);
+	sqr_add_c2(a,6,0,c1,c2,c3);
+	r[6]=c1;
+	c1=0;
+	sqr_add_c2(a,7,0,c2,c3,c1);
+	sqr_add_c2(a,6,1,c2,c3,c1);
+	sqr_add_c2(a,5,2,c2,c3,c1);
+	sqr_add_c2(a,4,3,c2,c3,c1);
+	r[7]=c2;
+	c2=0;
+	sqr_add_c(a,4,c3,c1,c2);
+	sqr_add_c2(a,5,3,c3,c1,c2);
+	sqr_add_c2(a,6,2,c3,c1,c2);
+	sqr_add_c2(a,7,1,c3,c1,c2);
+	r[8]=c3;
+	c3=0;
+	sqr_add_c2(a,7,2,c1,c2,c3);
+	sqr_add_c2(a,6,3,c1,c2,c3);
+	sqr_add_c2(a,5,4,c1,c2,c3);
+	r[9]=c1;
+	c1=0;
+	sqr_add_c(a,5,c2,c3,c1);
+	sqr_add_c2(a,6,4,c2,c3,c1);
+	sqr_add_c2(a,7,3,c2,c3,c1);
+	r[10]=c2;
+	c2=0;
+	sqr_add_c2(a,7,4,c3,c1,c2);
+	sqr_add_c2(a,6,5,c3,c1,c2);
+	r[11]=c3;
+	c3=0;
+	sqr_add_c(a,6,c1,c2,c3);
+	sqr_add_c2(a,7,5,c1,c2,c3);
+	r[12]=c1;
+	c1=0;
+	sqr_add_c2(a,7,6,c2,c3,c1);
+	r[13]=c2;
+	c2=0;
+	sqr_add_c(a,7,c3,c1,c2);
+	r[14]=c3;
+	r[15]=c1;
+	}
+
+void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
+	{
+	BN_ULONG t1,t2;
+	BN_ULONG c1,c2,c3;
+
+	c1=0;
+	c2=0;
+	c3=0;
+	sqr_add_c(a,0,c1,c2,c3);
+	r[0]=c1;
+	c1=0;
+	sqr_add_c2(a,1,0,c2,c3,c1);
+	r[1]=c2;
+	c2=0;
+	sqr_add_c(a,1,c3,c1,c2);
+	sqr_add_c2(a,2,0,c3,c1,c2);
+	r[2]=c3;
+	c3=0;
+	sqr_add_c2(a,3,0,c1,c2,c3);
+	sqr_add_c2(a,2,1,c1,c2,c3);
+	r[3]=c1;
+	c1=0;
+	sqr_add_c(a,2,c2,c3,c1);
+	sqr_add_c2(a,3,1,c2,c3,c1);
+	r[4]=c2;
+	c2=0;
+	sqr_add_c2(a,3,2,c3,c1,c2);
+	r[5]=c3;
+	c3=0;
+	sqr_add_c(a,3,c1,c2,c3);
+	r[6]=c1;
+	r[7]=c2;
+	}
+#endif
diff --git a/openssl/crypto/bn/asm/x86_64-mont.pl b/openssl/crypto/bn/asm/x86_64-mont.pl
new file mode 100755
index 0000000..3b7a6f2
--- /dev/null
+++ b/openssl/crypto/bn/asm/x86_64-mont.pl
@@ -0,0 +1,330 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# October 2005.
+#
+# Montgomery multiplication routine for x86_64. While it gives modest
+# 9% improvement of rsa4096 sign on Opteron, rsa512 sign runs more
+# than twice, >2x, as fast. Most common rsa1024 sign is improved by
+# respectful 50%. It remains to be seen if loop unrolling and
+# dedicated squaring routine can provide further improvement...
+
+$flavour = shift;
+$output  = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour $output";
+
+# int bn_mul_mont(
+$rp="%rdi";	# BN_ULONG *rp,
+$ap="%rsi";	# const BN_ULONG *ap,
+$bp="%rdx";	# const BN_ULONG *bp,
+$np="%rcx";	# const BN_ULONG *np,
+$n0="%r8";	# const BN_ULONG *n0,
+$num="%r9";	# int num);
+$lo0="%r10";
+$hi0="%r11";
+$bp="%r12";	# reassign $bp
+$hi1="%r13";
+$i="%r14";
+$j="%r15";
+$m0="%rbx";
+$m1="%rbp";
+
+$code=<<___;
+.text
+
+.globl	bn_mul_mont
+.type	bn_mul_mont,\@function,6
+.align	16
+bn_mul_mont:
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+
+	mov	${num}d,${num}d
+	lea	2($num),%r10
+	mov	%rsp,%r11
+	neg	%r10
+	lea	(%rsp,%r10,8),%rsp	# tp=alloca(8*(num+2))
+	and	\$-1024,%rsp		# minimize TLB usage
+
+	mov	%r11,8(%rsp,$num,8)	# tp[num+1]=%rsp
+.Lprologue:
+	mov	%rdx,$bp		# $bp reassigned, remember?
+
+	mov	($n0),$n0		# pull n0[0] value
+
+	xor	$i,$i			# i=0
+	xor	$j,$j			# j=0
+
+	mov	($bp),$m0		# m0=bp[0]
+	mov	($ap),%rax
+	mulq	$m0			# ap[0]*bp[0]
+	mov	%rax,$lo0
+	mov	%rdx,$hi0
+
+	imulq	$n0,%rax		# "tp[0]"*n0
+	mov	%rax,$m1
+
+	mulq	($np)			# np[0]*m1
+	add	$lo0,%rax		# discarded
+	adc	\$0,%rdx
+	mov	%rdx,$hi1
+
+	lea	1($j),$j		# j++
+.L1st:
+	mov	($ap,$j,8),%rax
+	mulq	$m0			# ap[j]*bp[0]
+	add	$hi0,%rax
+	adc	\$0,%rdx
+	mov	%rax,$lo0
+	mov	($np,$j,8),%rax
+	mov	%rdx,$hi0
+
+	mulq	$m1			# np[j]*m1
+	add	$hi1,%rax
+	lea	1($j),$j		# j++
+	adc	\$0,%rdx
+	add	$lo0,%rax		# np[j]*m1+ap[j]*bp[0]
+	adc	\$0,%rdx
+	mov	%rax,-16(%rsp,$j,8)	# tp[j-1]
+	cmp	$num,$j
+	mov	%rdx,$hi1
+	jl	.L1st
+
+	xor	%rdx,%rdx
+	add	$hi0,$hi1
+	adc	\$0,%rdx
+	mov	$hi1,-8(%rsp,$num,8)
+	mov	%rdx,(%rsp,$num,8)	# store upmost overflow bit
+
+	lea	1($i),$i		# i++
+.align	4
+.Louter:
+	xor	$j,$j			# j=0
+
+	mov	($bp,$i,8),$m0		# m0=bp[i]
+	mov	($ap),%rax		# ap[0]
+	mulq	$m0			# ap[0]*bp[i]
+	add	(%rsp),%rax		# ap[0]*bp[i]+tp[0]
+	adc	\$0,%rdx
+	mov	%rax,$lo0
+	mov	%rdx,$hi0
+
+	imulq	$n0,%rax		# tp[0]*n0
+	mov	%rax,$m1
+
+	mulq	($np,$j,8)		# np[0]*m1
+	add	$lo0,%rax		# discarded
+	mov	8(%rsp),$lo0		# tp[1]
+	adc	\$0,%rdx
+	mov	%rdx,$hi1
+
+	lea	1($j),$j		# j++
+.align	4
+.Linner:
+	mov	($ap,$j,8),%rax
+	mulq	$m0			# ap[j]*bp[i]
+	add	$hi0,%rax
+	adc	\$0,%rdx
+	add	%rax,$lo0		# ap[j]*bp[i]+tp[j]
+	mov	($np,$j,8),%rax
+	adc	\$0,%rdx
+	mov	%rdx,$hi0
+
+	mulq	$m1			# np[j]*m1
+	add	$hi1,%rax
+	lea	1($j),$j		# j++
+	adc	\$0,%rdx
+	add	$lo0,%rax		# np[j]*m1+ap[j]*bp[i]+tp[j]
+	adc	\$0,%rdx
+	mov	(%rsp,$j,8),$lo0
+	cmp	$num,$j
+	mov	%rax,-16(%rsp,$j,8)	# tp[j-1]
+	mov	%rdx,$hi1
+	jl	.Linner
+
+	xor	%rdx,%rdx
+	add	$hi0,$hi1
+	adc	\$0,%rdx
+	add	$lo0,$hi1		# pull upmost overflow bit
+	adc	\$0,%rdx
+	mov	$hi1,-8(%rsp,$num,8)
+	mov	%rdx,(%rsp,$num,8)	# store upmost overflow bit
+
+	lea	1($i),$i		# i++
+	cmp	$num,$i
+	jl	.Louter
+
+	lea	(%rsp),$ap		# borrow ap for tp
+	lea	-1($num),$j		# j=num-1
+
+	mov	($ap),%rax		# tp[0]
+	xor	$i,$i			# i=0 and clear CF!
+	jmp	.Lsub
+.align	16
+.Lsub:	sbb	($np,$i,8),%rax
+	mov	%rax,($rp,$i,8)		# rp[i]=tp[i]-np[i]
+	dec	$j			# doesn't affect CF!
+	mov	8($ap,$i,8),%rax	# tp[i+1]
+	lea	1($i),$i		# i++
+	jge	.Lsub
+
+	sbb	\$0,%rax		# handle upmost overflow bit
+	and	%rax,$ap
+	not	%rax
+	mov	$rp,$np
+	and	%rax,$np
+	lea	-1($num),$j
+	or	$np,$ap			# ap=borrow?tp:rp
+.align	16
+.Lcopy:					# copy or in-place refresh
+	mov	($ap,$j,8),%rax
+	mov	%rax,($rp,$j,8)		# rp[i]=tp[i]
+	mov	$i,(%rsp,$j,8)		# zap temporary vector
+	dec	$j
+	jge	.Lcopy
+
+	mov	8(%rsp,$num,8),%rsi	# restore %rsp
+	mov	\$1,%rax
+	mov	(%rsi),%r15
+	mov	8(%rsi),%r14
+	mov	16(%rsi),%r13
+	mov	24(%rsi),%r12
+	mov	32(%rsi),%rbp
+	mov	40(%rsi),%rbx
+	lea	48(%rsi),%rsp
+.Lepilogue:
+	ret
+.size	bn_mul_mont,.-bn_mul_mont
+.asciz	"Montgomery Multiplication for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
+.align	16
+___
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern	__imp_RtlVirtualUnwind
+.type	se_handler,\@abi-omnipotent
+.align	16
+se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	lea	.Lprologue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lprologue
+	jb	.Lin_prologue
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	lea	.Lepilogue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
+	jae	.Lin_prologue
+
+	mov	192($context),%r10	# pull $num
+	mov	8(%rax,%r10,8),%rax	# pull saved stack pointer
+	lea	48(%rax),%rax
+
+	mov	-8(%rax),%rbx
+	mov	-16(%rax),%rbp
+	mov	-24(%rax),%r12
+	mov	-32(%rax),%r13
+	mov	-40(%rax),%r14
+	mov	-48(%rax),%r15
+	mov	%rbx,144($context)	# restore context->Rbx
+	mov	%rbp,160($context)	# restore context->Rbp
+	mov	%r12,216($context)	# restore context->R12
+	mov	%r13,224($context)	# restore context->R13
+	mov	%r14,232($context)	# restore context->R14
+	mov	%r15,240($context)	# restore context->R15
+
+.Lin_prologue:
+	mov	8(%rax),%rdi
+	mov	16(%rax),%rsi
+	mov	%rax,152($context)	# restore context->Rsp
+	mov	%rsi,168($context)	# restore context->Rsi
+	mov	%rdi,176($context)	# restore context->Rdi
+
+	mov	40($disp),%rdi		# disp->ContextRecord
+	mov	$context,%rsi		# context
+	mov	\$154,%ecx		# sizeof(CONTEXT)
+	.long	0xa548f3fc		# cld; rep movsq
+
+	mov	$disp,%rsi
+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
+	mov	40(%rsi),%r10		# disp->ContextRecord
+	lea	56(%rsi),%r11		# &disp->HandlerData
+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
+	mov	%r10,32(%rsp)		# arg5
+	mov	%r11,40(%rsp)		# arg6
+	mov	%r12,48(%rsp)		# arg7
+	mov	%rcx,56(%rsp)		# arg8, (NULL)
+	call	*__imp_RtlVirtualUnwind(%rip)
+
+	mov	\$1,%eax		# ExceptionContinueSearch
+	add	\$64,%rsp
+	popfq
+	pop	%r15
+	pop	%r14
+	pop	%r13
+	pop	%r12
+	pop	%rbp
+	pop	%rbx
+	pop	%rdi
+	pop	%rsi
+	ret
+.size	se_handler,.-se_handler
+
+.section	.pdata
+.align	4
+	.rva	.LSEH_begin_bn_mul_mont
+	.rva	.LSEH_end_bn_mul_mont
+	.rva	.LSEH_info_bn_mul_mont
+
+.section	.xdata
+.align	8
+.LSEH_info_bn_mul_mont:
+	.byte	9,0,0,0
+	.rva	se_handler
+___
+}
+
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/bn/bn.h b/openssl/crypto/bn/bn.h
new file mode 100644
index 0000000..a0bc478
--- /dev/null
+++ b/openssl/crypto/bn/bn.h
@@ -0,0 +1,876 @@
+/* crypto/bn/bn.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the Eric Young open source
+ * license provided above.
+ *
+ * The binary polynomial arithmetic software is originally written by 
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#ifndef HEADER_BN_H
+#define HEADER_BN_H
+
+#include <openssl/e_os2.h>
+#ifndef OPENSSL_NO_FP_API
+#include <stdio.h> /* FILE */
+#endif
+#include <openssl/ossl_typ.h>
+#include <openssl/crypto.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* These preprocessor symbols control various aspects of the bignum headers and
+ * library code. They're not defined by any "normal" configuration, as they are
+ * intended for development and testing purposes. NB: defining all three can be
+ * useful for debugging application code as well as openssl itself.
+ *
+ * BN_DEBUG - turn on various debugging alterations to the bignum code
+ * BN_DEBUG_RAND - uses random poisoning of unused words to trip up
+ * mismanagement of bignum internals. You must also define BN_DEBUG.
+ */
+/* #define BN_DEBUG */
+/* #define BN_DEBUG_RAND */
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+#define BN_MUL_COMBA
+#define BN_SQR_COMBA
+#define BN_RECURSION
+#endif
+
+/* This next option uses the C libraries (2 word)/(1 word) function.
+ * If it is not defined, I use my C version (which is slower).
+ * The reason for this flag is that when the particular C compiler
+ * library routine is used, and the library is linked with a different
+ * compiler, the library is missing.  This mostly happens when the
+ * library is built with gcc and then linked using normal cc.  This would
+ * be a common occurrence because gcc normally produces code that is
+ * 2 times faster than system compilers for the big number stuff.
+ * For machines with only one compiler (or shared libraries), this should
+ * be on.  Again this in only really a problem on machines
+ * using "long long's", are 32bit, and are not using my assembler code. */
+#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || \
+    defined(OPENSSL_SYS_WIN32) || defined(linux)
+# ifndef BN_DIV2W
+#  define BN_DIV2W
+# endif
+#endif
+
+/* assuming long is 64bit - this is the DEC Alpha
+ * unsigned long long is only 64 bits :-(, don't define
+ * BN_LLONG for the DEC Alpha */
+#ifdef SIXTY_FOUR_BIT_LONG
+#define BN_ULLONG	unsigned long long
+#define BN_ULONG	unsigned long
+#define BN_LONG		long
+#define BN_BITS		128
+#define BN_BYTES	8
+#define BN_BITS2	64
+#define BN_BITS4	32
+#define BN_MASK		(0xffffffffffffffffffffffffffffffffLL)
+#define BN_MASK2	(0xffffffffffffffffL)
+#define BN_MASK2l	(0xffffffffL)
+#define BN_MASK2h	(0xffffffff00000000L)
+#define BN_MASK2h1	(0xffffffff80000000L)
+#define BN_TBIT		(0x8000000000000000L)
+#define BN_DEC_CONV	(10000000000000000000UL)
+#define BN_DEC_FMT1	"%lu"
+#define BN_DEC_FMT2	"%019lu"
+#define BN_DEC_NUM	19
+#define BN_HEX_FMT1	"%lX"
+#define BN_HEX_FMT2	"%016lX"
+#endif
+
+/* This is where the long long data type is 64 bits, but long is 32.
+ * For machines where there are 64bit registers, this is the mode to use.
+ * IRIX, on R4000 and above should use this mode, along with the relevant
+ * assembler code :-).  Do NOT define BN_LLONG.
+ */
+#ifdef SIXTY_FOUR_BIT
+#undef BN_LLONG
+#undef BN_ULLONG
+#define BN_ULONG	unsigned long long
+#define BN_LONG		long long
+#define BN_BITS		128
+#define BN_BYTES	8
+#define BN_BITS2	64
+#define BN_BITS4	32
+#define BN_MASK2	(0xffffffffffffffffLL)
+#define BN_MASK2l	(0xffffffffL)
+#define BN_MASK2h	(0xffffffff00000000LL)
+#define BN_MASK2h1	(0xffffffff80000000LL)
+#define BN_TBIT		(0x8000000000000000LL)
+#define BN_DEC_CONV	(10000000000000000000ULL)
+#define BN_DEC_FMT1	"%llu"
+#define BN_DEC_FMT2	"%019llu"
+#define BN_DEC_NUM	19
+#define BN_HEX_FMT1	"%llX"
+#define BN_HEX_FMT2	"%016llX"
+#endif
+
+#ifdef THIRTY_TWO_BIT
+#ifdef BN_LLONG
+# if defined(_WIN32) && !defined(__GNUC__)
+#  define BN_ULLONG	unsigned __int64
+#  define BN_MASK	(0xffffffffffffffffI64)
+# else
+#  define BN_ULLONG	unsigned long long
+#  define BN_MASK	(0xffffffffffffffffLL)
+# endif
+#endif
+#define BN_ULONG	unsigned int
+#define BN_LONG		int
+#define BN_BITS		64
+#define BN_BYTES	4
+#define BN_BITS2	32
+#define BN_BITS4	16
+#define BN_MASK2	(0xffffffffL)
+#define BN_MASK2l	(0xffff)
+#define BN_MASK2h1	(0xffff8000L)
+#define BN_MASK2h	(0xffff0000L)
+#define BN_TBIT		(0x80000000L)
+#define BN_DEC_CONV	(1000000000L)
+#define BN_DEC_FMT1	"%u"
+#define BN_DEC_FMT2	"%09u"
+#define BN_DEC_NUM	9
+#define BN_HEX_FMT1	"%X"
+#define BN_HEX_FMT2	"%08X"
+#endif
+
+/* 2011-02-22 SMS.
+ * In various places, a size_t variable or a type cast to size_t was
+ * used to perform integer-only operations on pointers.  This failed on
+ * VMS with 64-bit pointers (CC /POINTER_SIZE = 64) because size_t is
+ * still only 32 bits.  What's needed in these cases is an integer type
+ * with the same size as a pointer, which size_t is not certain to be. 
+ * The only fix here is VMS-specific.
+ */
+#if defined(OPENSSL_SYS_VMS)
+# if __INITIAL_POINTER_SIZE == 64
+#  define PTR_SIZE_INT long long
+# else /* __INITIAL_POINTER_SIZE == 64 */
+#  define PTR_SIZE_INT int
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+#else /* defined(OPENSSL_SYS_VMS) */
+# define PTR_SIZE_INT size_t
+#endif /* defined(OPENSSL_SYS_VMS) [else] */
+
+#define BN_DEFAULT_BITS	1280
+
+#define BN_FLG_MALLOCED		0x01
+#define BN_FLG_STATIC_DATA	0x02
+#define BN_FLG_CONSTTIME	0x04 /* avoid leaking exponent information through timing,
+                                      * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime,
+                                      * BN_div() will call BN_div_no_branch,
+                                      * BN_mod_inverse() will call BN_mod_inverse_no_branch.
+                                      */
+
+#ifndef OPENSSL_NO_DEPRECATED
+#define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME /* deprecated name for the flag */
+                                      /* avoid leaking exponent information through timings
+                                      * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */
+#endif
+
+#ifndef OPENSSL_NO_DEPRECATED
+#define BN_FLG_FREE		0x8000	/* used for debuging */
+#endif
+#define BN_set_flags(b,n)	((b)->flags|=(n))
+#define BN_get_flags(b,n)	((b)->flags&(n))
+
+/* get a clone of a BIGNUM with changed flags, for *temporary* use only
+ * (the two BIGNUMs cannot not be used in parallel!) */
+#define BN_with_flags(dest,b,n)  ((dest)->d=(b)->d, \
+                                  (dest)->top=(b)->top, \
+                                  (dest)->dmax=(b)->dmax, \
+                                  (dest)->neg=(b)->neg, \
+                                  (dest)->flags=(((dest)->flags & BN_FLG_MALLOCED) \
+                                                 |  ((b)->flags & ~BN_FLG_MALLOCED) \
+                                                 |  BN_FLG_STATIC_DATA \
+                                                 |  (n)))
+
+/* Already declared in ossl_typ.h */
+#if 0
+typedef struct bignum_st BIGNUM;
+/* Used for temp variables (declaration hidden in bn_lcl.h) */
+typedef struct bignum_ctx BN_CTX;
+typedef struct bn_blinding_st BN_BLINDING;
+typedef struct bn_mont_ctx_st BN_MONT_CTX;
+typedef struct bn_recp_ctx_st BN_RECP_CTX;
+typedef struct bn_gencb_st BN_GENCB;
+#endif
+
+struct bignum_st
+	{
+	BN_ULONG *d;	/* Pointer to an array of 'BN_BITS2' bit chunks. */
+	int top;	/* Index of last used d +1. */
+	/* The next are internal book keeping for bn_expand. */
+	int dmax;	/* Size of the d array. */
+	int neg;	/* one if the number is negative */
+	int flags;
+	};
+
+/* Used for montgomery multiplication */
+struct bn_mont_ctx_st
+	{
+	int ri;        /* number of bits in R */
+	BIGNUM RR;     /* used to convert to montgomery form */
+	BIGNUM N;      /* The modulus */
+	BIGNUM Ni;     /* R*(1/R mod N) - N*Ni = 1
+	                * (Ni is only stored for bignum algorithm) */
+	BN_ULONG n0[2];/* least significant word(s) of Ni;
+	                  (type changed with 0.9.9, was "BN_ULONG n0;" before) */
+	int flags;
+	};
+
+/* Used for reciprocal division/mod functions
+ * It cannot be shared between threads
+ */
+struct bn_recp_ctx_st
+	{
+	BIGNUM N;	/* the divisor */
+	BIGNUM Nr;	/* the reciprocal */
+	int num_bits;
+	int shift;
+	int flags;
+	};
+
+/* Used for slow "generation" functions. */
+struct bn_gencb_st
+	{
+	unsigned int ver;	/* To handle binary (in)compatibility */
+	void *arg;		/* callback-specific data */
+	union
+		{
+		/* if(ver==1) - handles old style callbacks */
+		void (*cb_1)(int, int, void *);
+		/* if(ver==2) - new callback style */
+		int (*cb_2)(int, int, BN_GENCB *);
+		} cb;
+	};
+/* Wrapper function to make using BN_GENCB easier,  */
+int BN_GENCB_call(BN_GENCB *cb, int a, int b);
+/* Macro to populate a BN_GENCB structure with an "old"-style callback */
+#define BN_GENCB_set_old(gencb, callback, cb_arg) { \
+		BN_GENCB *tmp_gencb = (gencb); \
+		tmp_gencb->ver = 1; \
+		tmp_gencb->arg = (cb_arg); \
+		tmp_gencb->cb.cb_1 = (callback); }
+/* Macro to populate a BN_GENCB structure with a "new"-style callback */
+#define BN_GENCB_set(gencb, callback, cb_arg) { \
+		BN_GENCB *tmp_gencb = (gencb); \
+		tmp_gencb->ver = 2; \
+		tmp_gencb->arg = (cb_arg); \
+		tmp_gencb->cb.cb_2 = (callback); }
+
+#define BN_prime_checks 0 /* default: select number of iterations
+			     based on the size of the number */
+
+/* number of Miller-Rabin iterations for an error rate  of less than 2^-80
+ * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook
+ * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996];
+ * original paper: Damgaard, Landrock, Pomerance: Average case error estimates
+ * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */
+#define BN_prime_checks_for_size(b) ((b) >= 1300 ?  2 : \
+                                (b) >=  850 ?  3 : \
+                                (b) >=  650 ?  4 : \
+                                (b) >=  550 ?  5 : \
+                                (b) >=  450 ?  6 : \
+                                (b) >=  400 ?  7 : \
+                                (b) >=  350 ?  8 : \
+                                (b) >=  300 ?  9 : \
+                                (b) >=  250 ? 12 : \
+                                (b) >=  200 ? 15 : \
+                                (b) >=  150 ? 18 : \
+                                /* b >= 100 */ 27)
+
+#define BN_num_bytes(a)	((BN_num_bits(a)+7)/8)
+
+/* Note that BN_abs_is_word didn't work reliably for w == 0 until 0.9.8 */
+#define BN_abs_is_word(a,w) ((((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) || \
+				(((w) == 0) && ((a)->top == 0)))
+#define BN_is_zero(a)       ((a)->top == 0)
+#define BN_is_one(a)        (BN_abs_is_word((a),1) && !(a)->neg)
+#define BN_is_word(a,w)     (BN_abs_is_word((a),(w)) && (!(w) || !(a)->neg))
+#define BN_is_odd(a)	    (((a)->top > 0) && ((a)->d[0] & 1))
+
+#define BN_one(a)	(BN_set_word((a),1))
+#define BN_zero_ex(a) \
+	do { \
+		BIGNUM *_tmp_bn = (a); \
+		_tmp_bn->top = 0; \
+		_tmp_bn->neg = 0; \
+	} while(0)
+#ifdef OPENSSL_NO_DEPRECATED
+#define BN_zero(a)	BN_zero_ex(a)
+#else
+#define BN_zero(a)	(BN_set_word((a),0))
+#endif
+
+const BIGNUM *BN_value_one(void);
+char *	BN_options(void);
+BN_CTX *BN_CTX_new(void);
+#ifndef OPENSSL_NO_DEPRECATED
+void	BN_CTX_init(BN_CTX *c);
+#endif
+void	BN_CTX_free(BN_CTX *c);
+void	BN_CTX_start(BN_CTX *ctx);
+BIGNUM *BN_CTX_get(BN_CTX *ctx);
+void	BN_CTX_end(BN_CTX *ctx);
+int     BN_rand(BIGNUM *rnd, int bits, int top,int bottom);
+int     BN_pseudo_rand(BIGNUM *rnd, int bits, int top,int bottom);
+int	BN_rand_range(BIGNUM *rnd, const BIGNUM *range);
+int	BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range);
+int	BN_num_bits(const BIGNUM *a);
+int	BN_num_bits_word(BN_ULONG);
+BIGNUM *BN_new(void);
+void	BN_init(BIGNUM *);
+void	BN_clear_free(BIGNUM *a);
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
+void	BN_swap(BIGNUM *a, BIGNUM *b);
+BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret);
+int	BN_bn2bin(const BIGNUM *a, unsigned char *to);
+BIGNUM *BN_mpi2bn(const unsigned char *s,int len,BIGNUM *ret);
+int	BN_bn2mpi(const BIGNUM *a, unsigned char *to);
+int	BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int	BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int	BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int	BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int	BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+int	BN_sqr(BIGNUM *r, const BIGNUM *a,BN_CTX *ctx);
+/** BN_set_negative sets sign of a BIGNUM
+ * \param  b  pointer to the BIGNUM object
+ * \param  n  0 if the BIGNUM b should be positive and a value != 0 otherwise 
+ */
+void	BN_set_negative(BIGNUM *b, int n);
+/** BN_is_negative returns 1 if the BIGNUM is negative
+ * \param  a  pointer to the BIGNUM object
+ * \return 1 if a < 0 and 0 otherwise
+ */
+#define BN_is_negative(a) ((a)->neg != 0)
+
+int	BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+	BN_CTX *ctx);
+#define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx))
+int	BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
+int	BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m);
+int	BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m);
+int	BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m);
+int	BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m);
+
+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
+int	BN_mul_word(BIGNUM *a, BN_ULONG w);
+int	BN_add_word(BIGNUM *a, BN_ULONG w);
+int	BN_sub_word(BIGNUM *a, BN_ULONG w);
+int	BN_set_word(BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_get_word(const BIGNUM *a);
+
+int	BN_cmp(const BIGNUM *a, const BIGNUM *b);
+void	BN_free(BIGNUM *a);
+int	BN_is_bit_set(const BIGNUM *a, int n);
+int	BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+int	BN_lshift1(BIGNUM *r, const BIGNUM *a);
+int	BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,BN_CTX *ctx);
+
+int	BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m,BN_CTX *ctx);
+int	BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont);
+int	BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int	BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1,
+	const BIGNUM *a2, const BIGNUM *p2,const BIGNUM *m,
+	BN_CTX *ctx,BN_MONT_CTX *m_ctx);
+int	BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m,BN_CTX *ctx);
+
+int	BN_mask_bits(BIGNUM *a,int n);
+#ifndef OPENSSL_NO_FP_API
+int	BN_print_fp(FILE *fp, const BIGNUM *a);
+#endif
+#ifdef HEADER_BIO_H
+int	BN_print(BIO *fp, const BIGNUM *a);
+#else
+int	BN_print(void *fp, const BIGNUM *a);
+#endif
+int	BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx);
+int	BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
+int	BN_rshift1(BIGNUM *r, const BIGNUM *a);
+void	BN_clear(BIGNUM *a);
+BIGNUM *BN_dup(const BIGNUM *a);
+int	BN_ucmp(const BIGNUM *a, const BIGNUM *b);
+int	BN_set_bit(BIGNUM *a, int n);
+int	BN_clear_bit(BIGNUM *a, int n);
+char *	BN_bn2hex(const BIGNUM *a);
+char *	BN_bn2dec(const BIGNUM *a);
+int 	BN_hex2bn(BIGNUM **a, const char *str);
+int 	BN_dec2bn(BIGNUM **a, const char *str);
+int	BN_asc2bn(BIGNUM **a, const char *str);
+int	BN_gcd(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx);
+int	BN_kronecker(const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); /* returns -2 for error */
+BIGNUM *BN_mod_inverse(BIGNUM *ret,
+	const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+BIGNUM *BN_mod_sqrt(BIGNUM *ret,
+	const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+
+/* Deprecated versions */
+#ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,
+	const BIGNUM *add, const BIGNUM *rem,
+	void (*callback)(int,int,void *),void *cb_arg);
+int	BN_is_prime(const BIGNUM *p,int nchecks,
+	void (*callback)(int,int,void *),
+	BN_CTX *ctx,void *cb_arg);
+int	BN_is_prime_fasttest(const BIGNUM *p,int nchecks,
+	void (*callback)(int,int,void *),BN_CTX *ctx,void *cb_arg,
+	int do_trial_division);
+#endif /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* Newer versions */
+int	BN_generate_prime_ex(BIGNUM *ret,int bits,int safe, const BIGNUM *add,
+		const BIGNUM *rem, BN_GENCB *cb);
+int	BN_is_prime_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, BN_GENCB *cb);
+int	BN_is_prime_fasttest_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx,
+		int do_trial_division, BN_GENCB *cb);
+
+BN_MONT_CTX *BN_MONT_CTX_new(void );
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
+int BN_mod_mul_montgomery(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,
+	BN_MONT_CTX *mont, BN_CTX *ctx);
+#define BN_to_montgomery(r,a,mont,ctx)	BN_mod_mul_montgomery(\
+	(r),(a),&((mont)->RR),(mont),(ctx))
+int BN_from_montgomery(BIGNUM *r,const BIGNUM *a,
+	BN_MONT_CTX *mont, BN_CTX *ctx);
+void BN_MONT_CTX_free(BN_MONT_CTX *mont);
+int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *mod,BN_CTX *ctx);
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from);
+BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
+					const BIGNUM *mod, BN_CTX *ctx);
+
+/* BN_BLINDING flags */
+#define	BN_BLINDING_NO_UPDATE	0x00000001
+#define	BN_BLINDING_NO_RECREATE	0x00000002
+
+BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod);
+void BN_BLINDING_free(BN_BLINDING *b);
+int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
+int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *);
+#ifndef OPENSSL_NO_DEPRECATED
+unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
+void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
+#endif
+CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *);
+unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
+void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
+BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
+	const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
+	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
+	BN_MONT_CTX *m_ctx);
+
+#ifndef OPENSSL_NO_DEPRECATED
+void BN_set_params(int mul,int high,int low,int mont);
+int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */
+#endif
+
+void	BN_RECP_CTX_init(BN_RECP_CTX *recp);
+BN_RECP_CTX *BN_RECP_CTX_new(void);
+void	BN_RECP_CTX_free(BN_RECP_CTX *recp);
+int	BN_RECP_CTX_set(BN_RECP_CTX *recp,const BIGNUM *rdiv,BN_CTX *ctx);
+int	BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
+	BN_RECP_CTX *recp,BN_CTX *ctx);
+int	BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx);
+int	BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
+	BN_RECP_CTX *recp, BN_CTX *ctx);
+
+/* Functions for arithmetic over binary polynomials represented by BIGNUMs. 
+ *
+ * The BIGNUM::neg property of BIGNUMs representing binary polynomials is
+ * ignored.
+ *
+ * Note that input arguments are not const so that their bit arrays can
+ * be expanded to the appropriate size if needed.
+ */
+
+int	BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); /*r = a + b*/
+#define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b)
+int	BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p); /*r=a mod p*/
+int	BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const BIGNUM *p, BN_CTX *ctx); /* r = (a * b) mod p */
+int	BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	BN_CTX *ctx); /* r = (a * a) mod p */
+int	BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p,
+	BN_CTX *ctx); /* r = (1 / b) mod p */
+int	BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const BIGNUM *p, BN_CTX *ctx); /* r = (a / b) mod p */
+int	BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const BIGNUM *p, BN_CTX *ctx); /* r = (a ^ b) mod p */
+int	BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	BN_CTX *ctx); /* r = sqrt(a) mod p */
+int	BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	BN_CTX *ctx); /* r^2 + r = a mod p */
+#define BN_GF2m_cmp(a, b) BN_ucmp((a), (b))
+/* Some functions allow for representation of the irreducible polynomials
+ * as an unsigned int[], say p.  The irreducible f(t) is then of the form:
+ *     t^p[0] + t^p[1] + ... + t^p[k]
+ * where m = p[0] > p[1] > ... > p[k] = 0.
+ */
+int	BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]);
+	/* r = a mod p */
+int	BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const int p[], BN_CTX *ctx); /* r = (a * b) mod p */
+int	BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[],
+	BN_CTX *ctx); /* r = (a * a) mod p */
+int	BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[],
+	BN_CTX *ctx); /* r = (1 / b) mod p */
+int	BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const int p[], BN_CTX *ctx); /* r = (a / b) mod p */
+int	BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */
+int	BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a,
+	const int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */
+int	BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a,
+	const int p[], BN_CTX *ctx); /* r^2 + r = a mod p */
+int	BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max);
+int	BN_GF2m_arr2poly(const int p[], BIGNUM *a);
+
+/* faster mod functions for the 'NIST primes' 
+ * 0 <= a < p^2 */
+int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+
+const BIGNUM *BN_get0_nist_prime_192(void);
+const BIGNUM *BN_get0_nist_prime_224(void);
+const BIGNUM *BN_get0_nist_prime_256(void);
+const BIGNUM *BN_get0_nist_prime_384(void);
+const BIGNUM *BN_get0_nist_prime_521(void);
+
+/* library internal functions */
+
+#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
+	(a):bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2))
+#define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
+BIGNUM *bn_expand2(BIGNUM *a, int words);
+#ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */
+#endif
+
+/* Bignum consistency macros
+ * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from
+ * bignum data after direct manipulations on the data. There is also an
+ * "internal" macro, bn_check_top(), for verifying that there are no leading
+ * zeroes. Unfortunately, some auditing is required due to the fact that
+ * bn_fix_top() has become an overabused duct-tape because bignum data is
+ * occasionally passed around in an inconsistent state. So the following
+ * changes have been made to sort this out;
+ * - bn_fix_top()s implementation has been moved to bn_correct_top()
+ * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and
+ *   bn_check_top() is as before.
+ * - if BN_DEBUG *is* defined;
+ *   - bn_check_top() tries to pollute unused words even if the bignum 'top' is
+ *     consistent. (ed: only if BN_DEBUG_RAND is defined)
+ *   - bn_fix_top() maps to bn_check_top() rather than "fixing" anything.
+ * The idea is to have debug builds flag up inconsistent bignums when they
+ * occur. If that occurs in a bn_fix_top(), we examine the code in question; if
+ * the use of bn_fix_top() was appropriate (ie. it follows directly after code
+ * that manipulates the bignum) it is converted to bn_correct_top(), and if it
+ * was not appropriate, we convert it permanently to bn_check_top() and track
+ * down the cause of the bug. Eventually, no internal code should be using the
+ * bn_fix_top() macro. External applications and libraries should try this with
+ * their own code too, both in terms of building against the openssl headers
+ * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it
+ * defined. This not only improves external code, it provides more test
+ * coverage for openssl's own code.
+ */
+
+#ifdef BN_DEBUG
+
+/* We only need assert() when debugging */
+#include <assert.h>
+
+#ifdef BN_DEBUG_RAND
+/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */
+#ifndef RAND_pseudo_bytes
+int RAND_pseudo_bytes(unsigned char *buf,int num);
+#define BN_DEBUG_TRIX
+#endif
+#define bn_pollute(a) \
+	do { \
+		const BIGNUM *_bnum1 = (a); \
+		if(_bnum1->top < _bnum1->dmax) { \
+			unsigned char _tmp_char; \
+			/* We cast away const without the compiler knowing, any \
+			 * *genuinely* constant variables that aren't mutable \
+			 * wouldn't be constructed with top!=dmax. */ \
+			BN_ULONG *_not_const; \
+			memcpy(&_not_const, &_bnum1->d, sizeof(BN_ULONG*)); \
+			RAND_pseudo_bytes(&_tmp_char, 1); \
+			memset((unsigned char *)(_not_const + _bnum1->top), _tmp_char, \
+				(_bnum1->dmax - _bnum1->top) * sizeof(BN_ULONG)); \
+		} \
+	} while(0)
+#ifdef BN_DEBUG_TRIX
+#undef RAND_pseudo_bytes
+#endif
+#else
+#define bn_pollute(a)
+#endif
+#define bn_check_top(a) \
+	do { \
+		const BIGNUM *_bnum2 = (a); \
+		if (_bnum2 != NULL) { \
+			assert((_bnum2->top == 0) || \
+				(_bnum2->d[_bnum2->top - 1] != 0)); \
+			bn_pollute(_bnum2); \
+		} \
+	} while(0)
+
+#define bn_fix_top(a)		bn_check_top(a)
+
+#else /* !BN_DEBUG */
+
+#define bn_pollute(a)
+#define bn_check_top(a)
+#define bn_fix_top(a)		bn_correct_top(a)
+
+#endif
+
+#define bn_correct_top(a) \
+        { \
+        BN_ULONG *ftl; \
+	int tmp_top = (a)->top; \
+	if (tmp_top > 0) \
+		{ \
+		for (ftl= &((a)->d[tmp_top-1]); tmp_top > 0; tmp_top--) \
+			if (*(ftl--)) break; \
+		(a)->top = tmp_top; \
+		} \
+	bn_pollute(a); \
+	}
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
+void     bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
+BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
+BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
+
+/* Primes from RFC 2409 */
+BIGNUM *get_rfc2409_prime_768(BIGNUM *bn);
+BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn);
+
+/* Primes from RFC 3526 */
+BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn);
+
+int BN_bntest_rand(BIGNUM *rnd, int bits, int top,int bottom);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_BN_strings(void);
+
+/* Error codes for the BN functions. */
+
+/* Function codes. */
+#define BN_F_BNRAND					 127
+#define BN_F_BN_BLINDING_CONVERT_EX			 100
+#define BN_F_BN_BLINDING_CREATE_PARAM			 128
+#define BN_F_BN_BLINDING_INVERT_EX			 101
+#define BN_F_BN_BLINDING_NEW				 102
+#define BN_F_BN_BLINDING_UPDATE				 103
+#define BN_F_BN_BN2DEC					 104
+#define BN_F_BN_BN2HEX					 105
+#define BN_F_BN_CTX_GET					 116
+#define BN_F_BN_CTX_NEW					 106
+#define BN_F_BN_CTX_START				 129
+#define BN_F_BN_DIV					 107
+#define BN_F_BN_DIV_NO_BRANCH				 138
+#define BN_F_BN_DIV_RECP				 130
+#define BN_F_BN_EXP					 123
+#define BN_F_BN_EXPAND2					 108
+#define BN_F_BN_EXPAND_INTERNAL				 120
+#define BN_F_BN_GF2M_MOD				 131
+#define BN_F_BN_GF2M_MOD_EXP				 132
+#define BN_F_BN_GF2M_MOD_MUL				 133
+#define BN_F_BN_GF2M_MOD_SOLVE_QUAD			 134
+#define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR			 135
+#define BN_F_BN_GF2M_MOD_SQR				 136
+#define BN_F_BN_GF2M_MOD_SQRT				 137
+#define BN_F_BN_MOD_EXP2_MONT				 118
+#define BN_F_BN_MOD_EXP_MONT				 109
+#define BN_F_BN_MOD_EXP_MONT_CONSTTIME			 124
+#define BN_F_BN_MOD_EXP_MONT_WORD			 117
+#define BN_F_BN_MOD_EXP_RECP				 125
+#define BN_F_BN_MOD_EXP_SIMPLE				 126
+#define BN_F_BN_MOD_INVERSE				 110
+#define BN_F_BN_MOD_INVERSE_NO_BRANCH			 139
+#define BN_F_BN_MOD_LSHIFT_QUICK			 119
+#define BN_F_BN_MOD_MUL_RECIPROCAL			 111
+#define BN_F_BN_MOD_SQRT				 121
+#define BN_F_BN_MPI2BN					 112
+#define BN_F_BN_NEW					 113
+#define BN_F_BN_RAND					 114
+#define BN_F_BN_RAND_RANGE				 122
+#define BN_F_BN_USUB					 115
+
+/* Reason codes. */
+#define BN_R_ARG2_LT_ARG3				 100
+#define BN_R_BAD_RECIPROCAL				 101
+#define BN_R_BIGNUM_TOO_LONG				 114
+#define BN_R_CALLED_WITH_EVEN_MODULUS			 102
+#define BN_R_DIV_BY_ZERO				 103
+#define BN_R_ENCODING_ERROR				 104
+#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA		 105
+#define BN_R_INPUT_NOT_REDUCED				 110
+#define BN_R_INVALID_LENGTH				 106
+#define BN_R_INVALID_RANGE				 115
+#define BN_R_NOT_A_SQUARE				 111
+#define BN_R_NOT_INITIALIZED				 107
+#define BN_R_NO_INVERSE					 108
+#define BN_R_NO_SOLUTION				 116
+#define BN_R_P_IS_NOT_PRIME				 112
+#define BN_R_TOO_MANY_ITERATIONS			 113
+#define BN_R_TOO_MANY_TEMPORARY_VARIABLES		 109
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/bn/bn.mul b/openssl/crypto/bn/bn.mul
new file mode 100644
index 0000000..9728870
--- /dev/null
+++ b/openssl/crypto/bn/bn.mul
@@ -0,0 +1,19 @@
+We need
+
+* bn_mul_comba8
+* bn_mul_comba4
+* bn_mul_normal
+* bn_mul_recursive
+
+* bn_sqr_comba8
+* bn_sqr_comba4
+bn_sqr_normal -> BN_sqr
+* bn_sqr_recursive
+
+* bn_mul_low_recursive
+* bn_mul_low_normal
+* bn_mul_high
+
+* bn_mul_part_recursive	# symetric but not power of 2
+
+bn_mul_asymetric_recursive # uneven, but do the chop up.
diff --git a/openssl/crypto/bn/bn_add.c b/openssl/crypto/bn/bn_add.c
new file mode 100644
index 0000000..9405163
--- /dev/null
+++ b/openssl/crypto/bn/bn_add.c
@@ -0,0 +1,313 @@
+/* crypto/bn/bn_add.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* r can == a or b */
+int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+	{
+	const BIGNUM *tmp;
+	int a_neg = a->neg, ret;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	/*  a +  b	a+b
+	 *  a + -b	a-b
+	 * -a +  b	b-a
+	 * -a + -b	-(a+b)
+	 */
+	if (a_neg ^ b->neg)
+		{
+		/* only one is negative */
+		if (a_neg)
+			{ tmp=a; a=b; b=tmp; }
+
+		/* we are now a - b */
+
+		if (BN_ucmp(a,b) < 0)
+			{
+			if (!BN_usub(r,b,a)) return(0);
+			r->neg=1;
+			}
+		else
+			{
+			if (!BN_usub(r,a,b)) return(0);
+			r->neg=0;
+			}
+		return(1);
+		}
+
+	ret = BN_uadd(r,a,b);
+	r->neg = a_neg;
+	bn_check_top(r);
+	return ret;
+	}
+
+/* unsigned add of b to a */
+int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+	{
+	int max,min,dif;
+	BN_ULONG *ap,*bp,*rp,carry,t1,t2;
+	const BIGNUM *tmp;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	if (a->top < b->top)
+		{ tmp=a; a=b; b=tmp; }
+	max = a->top;
+	min = b->top;
+	dif = max - min;
+
+	if (bn_wexpand(r,max+1) == NULL)
+		return 0;
+
+	r->top=max;
+
+
+	ap=a->d;
+	bp=b->d;
+	rp=r->d;
+
+	carry=bn_add_words(rp,ap,bp,min);
+	rp+=min;
+	ap+=min;
+	bp+=min;
+
+	if (carry)
+		{
+		while (dif)
+			{
+			dif--;
+			t1 = *(ap++);
+			t2 = (t1+1) & BN_MASK2;
+			*(rp++) = t2;
+			if (t2)
+				{
+				carry=0;
+				break;
+				}
+			}
+		if (carry)
+			{
+			/* carry != 0 => dif == 0 */
+			*rp = 1;
+			r->top++;
+			}
+		}
+	if (dif && rp != ap)
+		while (dif--)
+			/* copy remaining words if ap != rp */
+			*(rp++) = *(ap++);
+	r->neg = 0;
+	bn_check_top(r);
+	return 1;
+	}
+
+/* unsigned subtraction of b from a, a must be larger than b. */
+int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+	{
+	int max,min,dif;
+	register BN_ULONG t1,t2,*ap,*bp,*rp;
+	int i,carry;
+#if defined(IRIX_CC_BUG) && !defined(LINT)
+	int dummy;
+#endif
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	max = a->top;
+	min = b->top;
+	dif = max - min;
+
+	if (dif < 0)	/* hmm... should not be happening */
+		{
+		BNerr(BN_F_BN_USUB,BN_R_ARG2_LT_ARG3);
+		return(0);
+		}
+
+	if (bn_wexpand(r,max) == NULL) return(0);
+
+	ap=a->d;
+	bp=b->d;
+	rp=r->d;
+
+#if 1
+	carry=0;
+	for (i = min; i != 0; i--)
+		{
+		t1= *(ap++);
+		t2= *(bp++);
+		if (carry)
+			{
+			carry=(t1 <= t2);
+			t1=(t1-t2-1)&BN_MASK2;
+			}
+		else
+			{
+			carry=(t1 < t2);
+			t1=(t1-t2)&BN_MASK2;
+			}
+#if defined(IRIX_CC_BUG) && !defined(LINT)
+		dummy=t1;
+#endif
+		*(rp++)=t1&BN_MASK2;
+		}
+#else
+	carry=bn_sub_words(rp,ap,bp,min);
+	ap+=min;
+	bp+=min;
+	rp+=min;
+#endif
+	if (carry) /* subtracted */
+		{
+		if (!dif)
+			/* error: a < b */
+			return 0;
+		while (dif)
+			{
+			dif--;
+			t1 = *(ap++);
+			t2 = (t1-1)&BN_MASK2;
+			*(rp++) = t2;
+			if (t1)
+				break;
+			}
+		}
+#if 0
+	memcpy(rp,ap,sizeof(*rp)*(max-i));
+#else
+	if (rp != ap)
+		{
+		for (;;)
+			{
+			if (!dif--) break;
+			rp[0]=ap[0];
+			if (!dif--) break;
+			rp[1]=ap[1];
+			if (!dif--) break;
+			rp[2]=ap[2];
+			if (!dif--) break;
+			rp[3]=ap[3];
+			rp+=4;
+			ap+=4;
+			}
+		}
+#endif
+
+	r->top=max;
+	r->neg=0;
+	bn_correct_top(r);
+	return(1);
+	}
+
+int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+	{
+	int max;
+	int add=0,neg=0;
+	const BIGNUM *tmp;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	/*  a -  b	a-b
+	 *  a - -b	a+b
+	 * -a -  b	-(a+b)
+	 * -a - -b	b-a
+	 */
+	if (a->neg)
+		{
+		if (b->neg)
+			{ tmp=a; a=b; b=tmp; }
+		else
+			{ add=1; neg=1; }
+		}
+	else
+		{
+		if (b->neg) { add=1; neg=0; }
+		}
+
+	if (add)
+		{
+		if (!BN_uadd(r,a,b)) return(0);
+		r->neg=neg;
+		return(1);
+		}
+
+	/* We are actually doing a - b :-) */
+
+	max=(a->top > b->top)?a->top:b->top;
+	if (bn_wexpand(r,max) == NULL) return(0);
+	if (BN_ucmp(a,b) < 0)
+		{
+		if (!BN_usub(r,b,a)) return(0);
+		r->neg=1;
+		}
+	else
+		{
+		if (!BN_usub(r,a,b)) return(0);
+		r->neg=0;
+		}
+	bn_check_top(r);
+	return(1);
+	}
+
diff --git a/openssl/crypto/bn/bn_asm.c b/openssl/crypto/bn/bn_asm.c
new file mode 100644
index 0000000..c43c91c
--- /dev/null
+++ b/openssl/crypto/bn/bn_asm.c
@@ -0,0 +1,1030 @@
+/* crypto/bn/bn_asm.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef BN_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+	{
+	BN_ULONG c1=0;
+
+	assert(num >= 0);
+	if (num <= 0) return(c1);
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (num&~3)
+		{
+		mul_add(rp[0],ap[0],w,c1);
+		mul_add(rp[1],ap[1],w,c1);
+		mul_add(rp[2],ap[2],w,c1);
+		mul_add(rp[3],ap[3],w,c1);
+		ap+=4; rp+=4; num-=4;
+		}
+#endif
+	while (num)
+		{
+		mul_add(rp[0],ap[0],w,c1);
+		ap++; rp++; num--;
+		}
+	
+	return(c1);
+	} 
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+	{
+	BN_ULONG c1=0;
+
+	assert(num >= 0);
+	if (num <= 0) return(c1);
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (num&~3)
+		{
+		mul(rp[0],ap[0],w,c1);
+		mul(rp[1],ap[1],w,c1);
+		mul(rp[2],ap[2],w,c1);
+		mul(rp[3],ap[3],w,c1);
+		ap+=4; rp+=4; num-=4;
+		}
+#endif
+	while (num)
+		{
+		mul(rp[0],ap[0],w,c1);
+		ap++; rp++; num--;
+		}
+	return(c1);
+	} 
+
+void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
+        {
+	assert(n >= 0);
+	if (n <= 0) return;
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (n&~3)
+		{
+		sqr(r[0],r[1],a[0]);
+		sqr(r[2],r[3],a[1]);
+		sqr(r[4],r[5],a[2]);
+		sqr(r[6],r[7],a[3]);
+		a+=4; r+=8; n-=4;
+		}
+#endif
+	while (n)
+		{
+		sqr(r[0],r[1],a[0]);
+		a++; r+=2; n--;
+		}
+	}
+
+#else /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+	{
+	BN_ULONG c=0;
+	BN_ULONG bl,bh;
+
+	assert(num >= 0);
+	if (num <= 0) return((BN_ULONG)0);
+
+	bl=LBITS(w);
+	bh=HBITS(w);
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (num&~3)
+		{
+		mul_add(rp[0],ap[0],bl,bh,c);
+		mul_add(rp[1],ap[1],bl,bh,c);
+		mul_add(rp[2],ap[2],bl,bh,c);
+		mul_add(rp[3],ap[3],bl,bh,c);
+		ap+=4; rp+=4; num-=4;
+		}
+#endif
+	while (num)
+		{
+		mul_add(rp[0],ap[0],bl,bh,c);
+		ap++; rp++; num--;
+		}
+	return(c);
+	} 
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+	{
+	BN_ULONG carry=0;
+	BN_ULONG bl,bh;
+
+	assert(num >= 0);
+	if (num <= 0) return((BN_ULONG)0);
+
+	bl=LBITS(w);
+	bh=HBITS(w);
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (num&~3)
+		{
+		mul(rp[0],ap[0],bl,bh,carry);
+		mul(rp[1],ap[1],bl,bh,carry);
+		mul(rp[2],ap[2],bl,bh,carry);
+		mul(rp[3],ap[3],bl,bh,carry);
+		ap+=4; rp+=4; num-=4;
+		}
+#endif
+	while (num)
+		{
+		mul(rp[0],ap[0],bl,bh,carry);
+		ap++; rp++; num--;
+		}
+	return(carry);
+	} 
+
+void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
+        {
+	assert(n >= 0);
+	if (n <= 0) return;
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (n&~3)
+		{
+		sqr64(r[0],r[1],a[0]);
+		sqr64(r[2],r[3],a[1]);
+		sqr64(r[4],r[5],a[2]);
+		sqr64(r[6],r[7],a[3]);
+		a+=4; r+=8; n-=4;
+		}
+#endif
+	while (n)
+		{
+		sqr64(r[0],r[1],a[0]);
+		a++; r+=2; n--;
+		}
+	}
+
+#endif /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
+
+#if defined(BN_LLONG) && defined(BN_DIV2W)
+
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+	{
+	return((BN_ULONG)(((((BN_ULLONG)h)<<BN_BITS2)|l)/(BN_ULLONG)d));
+	}
+
+#else
+
+/* Divide h,l by d and return the result. */
+/* I need to test this some more :-( */
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+	{
+	BN_ULONG dh,dl,q,ret=0,th,tl,t;
+	int i,count=2;
+
+	if (d == 0) return(BN_MASK2);
+
+	i=BN_num_bits_word(d);
+	assert((i == BN_BITS2) || (h <= (BN_ULONG)1<<i));
+
+	i=BN_BITS2-i;
+	if (h >= d) h-=d;
+
+	if (i)
+		{
+		d<<=i;
+		h=(h<<i)|(l>>(BN_BITS2-i));
+		l<<=i;
+		}
+	dh=(d&BN_MASK2h)>>BN_BITS4;
+	dl=(d&BN_MASK2l);
+	for (;;)
+		{
+		if ((h>>BN_BITS4) == dh)
+			q=BN_MASK2l;
+		else
+			q=h/dh;
+
+		th=q*dh;
+		tl=dl*q;
+		for (;;)
+			{
+			t=h-th;
+			if ((t&BN_MASK2h) ||
+				((tl) <= (
+					(t<<BN_BITS4)|
+					((l&BN_MASK2h)>>BN_BITS4))))
+				break;
+			q--;
+			th-=dh;
+			tl-=dl;
+			}
+		t=(tl>>BN_BITS4);
+		tl=(tl<<BN_BITS4)&BN_MASK2h;
+		th+=t;
+
+		if (l < tl) th++;
+		l-=tl;
+		if (h < th)
+			{
+			h+=d;
+			q--;
+			}
+		h-=th;
+
+		if (--count == 0) break;
+
+		ret=q<<BN_BITS4;
+		h=((h<<BN_BITS4)|(l>>BN_BITS4))&BN_MASK2;
+		l=(l&BN_MASK2l)<<BN_BITS4;
+		}
+	ret|=q;
+	return(ret);
+	}
+#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */
+
+#ifdef BN_LLONG
+BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
+        {
+	BN_ULLONG ll=0;
+
+	assert(n >= 0);
+	if (n <= 0) return((BN_ULONG)0);
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (n&~3)
+		{
+		ll+=(BN_ULLONG)a[0]+b[0];
+		r[0]=(BN_ULONG)ll&BN_MASK2;
+		ll>>=BN_BITS2;
+		ll+=(BN_ULLONG)a[1]+b[1];
+		r[1]=(BN_ULONG)ll&BN_MASK2;
+		ll>>=BN_BITS2;
+		ll+=(BN_ULLONG)a[2]+b[2];
+		r[2]=(BN_ULONG)ll&BN_MASK2;
+		ll>>=BN_BITS2;
+		ll+=(BN_ULLONG)a[3]+b[3];
+		r[3]=(BN_ULONG)ll&BN_MASK2;
+		ll>>=BN_BITS2;
+		a+=4; b+=4; r+=4; n-=4;
+		}
+#endif
+	while (n)
+		{
+		ll+=(BN_ULLONG)a[0]+b[0];
+		r[0]=(BN_ULONG)ll&BN_MASK2;
+		ll>>=BN_BITS2;
+		a++; b++; r++; n--;
+		}
+	return((BN_ULONG)ll);
+	}
+#else /* !BN_LLONG */
+BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
+        {
+	BN_ULONG c,l,t;
+
+	assert(n >= 0);
+	if (n <= 0) return((BN_ULONG)0);
+
+	c=0;
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (n&~3)
+		{
+		t=a[0];
+		t=(t+c)&BN_MASK2;
+		c=(t < c);
+		l=(t+b[0])&BN_MASK2;
+		c+=(l < t);
+		r[0]=l;
+		t=a[1];
+		t=(t+c)&BN_MASK2;
+		c=(t < c);
+		l=(t+b[1])&BN_MASK2;
+		c+=(l < t);
+		r[1]=l;
+		t=a[2];
+		t=(t+c)&BN_MASK2;
+		c=(t < c);
+		l=(t+b[2])&BN_MASK2;
+		c+=(l < t);
+		r[2]=l;
+		t=a[3];
+		t=(t+c)&BN_MASK2;
+		c=(t < c);
+		l=(t+b[3])&BN_MASK2;
+		c+=(l < t);
+		r[3]=l;
+		a+=4; b+=4; r+=4; n-=4;
+		}
+#endif
+	while(n)
+		{
+		t=a[0];
+		t=(t+c)&BN_MASK2;
+		c=(t < c);
+		l=(t+b[0])&BN_MASK2;
+		c+=(l < t);
+		r[0]=l;
+		a++; b++; r++; n--;
+		}
+	return((BN_ULONG)c);
+	}
+#endif /* !BN_LLONG */
+
+BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
+        {
+	BN_ULONG t1,t2;
+	int c=0;
+
+	assert(n >= 0);
+	if (n <= 0) return((BN_ULONG)0);
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (n&~3)
+		{
+		t1=a[0]; t2=b[0];
+		r[0]=(t1-t2-c)&BN_MASK2;
+		if (t1 != t2) c=(t1 < t2);
+		t1=a[1]; t2=b[1];
+		r[1]=(t1-t2-c)&BN_MASK2;
+		if (t1 != t2) c=(t1 < t2);
+		t1=a[2]; t2=b[2];
+		r[2]=(t1-t2-c)&BN_MASK2;
+		if (t1 != t2) c=(t1 < t2);
+		t1=a[3]; t2=b[3];
+		r[3]=(t1-t2-c)&BN_MASK2;
+		if (t1 != t2) c=(t1 < t2);
+		a+=4; b+=4; r+=4; n-=4;
+		}
+#endif
+	while (n)
+		{
+		t1=a[0]; t2=b[0];
+		r[0]=(t1-t2-c)&BN_MASK2;
+		if (t1 != t2) c=(t1 < t2);
+		a++; b++; r++; n--;
+		}
+	return(c);
+	}
+
+#if defined(BN_MUL_COMBA) && !defined(OPENSSL_SMALL_FOOTPRINT)
+
+#undef bn_mul_comba8
+#undef bn_mul_comba4
+#undef bn_sqr_comba8
+#undef bn_sqr_comba4
+
+/* mul_add_c(a,b,c0,c1,c2)  -- c+=a*b for three word number c=(c2,c1,c0) */
+/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
+/* sqr_add_c(a,i,c0,c1,c2)  -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
+/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
+
+#ifdef BN_LLONG
+#define mul_add_c(a,b,c0,c1,c2) \
+	t=(BN_ULLONG)a*b; \
+	t1=(BN_ULONG)Lw(t); \
+	t2=(BN_ULONG)Hw(t); \
+	c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define mul_add_c2(a,b,c0,c1,c2) \
+	t=(BN_ULLONG)a*b; \
+	tt=(t+t)&BN_MASK; \
+	if (tt < t) c2++; \
+	t1=(BN_ULONG)Lw(tt); \
+	t2=(BN_ULONG)Hw(tt); \
+	c0=(c0+t1)&BN_MASK2;  \
+	if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
+	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define sqr_add_c(a,i,c0,c1,c2) \
+	t=(BN_ULLONG)a[i]*a[i]; \
+	t1=(BN_ULONG)Lw(t); \
+	t2=(BN_ULONG)Hw(t); \
+	c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define sqr_add_c2(a,i,j,c0,c1,c2) \
+	mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+#elif defined(BN_UMULT_LOHI)
+
+#define mul_add_c(a,b,c0,c1,c2)	{	\
+	BN_ULONG ta=(a),tb=(b);		\
+	BN_UMULT_LOHI(t1,t2,ta,tb);	\
+	c0 += t1; t2 += (c0<t1)?1:0;	\
+	c1 += t2; c2 += (c1<t2)?1:0;	\
+	}
+
+#define mul_add_c2(a,b,c0,c1,c2) {	\
+	BN_ULONG ta=(a),tb=(b),t0;	\
+	BN_UMULT_LOHI(t0,t1,ta,tb);	\
+	t2 = t1+t1; c2 += (t2<t1)?1:0;	\
+	t1 = t0+t0; t2 += (t1<t0)?1:0;	\
+	c0 += t1; t2 += (c0<t1)?1:0;	\
+	c1 += t2; c2 += (c1<t2)?1:0;	\
+	}
+
+#define sqr_add_c(a,i,c0,c1,c2)	{	\
+	BN_ULONG ta=(a)[i];		\
+	BN_UMULT_LOHI(t1,t2,ta,ta);	\
+	c0 += t1; t2 += (c0<t1)?1:0;	\
+	c1 += t2; c2 += (c1<t2)?1:0;	\
+	}
+
+#define sqr_add_c2(a,i,j,c0,c1,c2)	\
+	mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+#elif defined(BN_UMULT_HIGH)
+
+#define mul_add_c(a,b,c0,c1,c2)	{	\
+	BN_ULONG ta=(a),tb=(b);		\
+	t1 = ta * tb;			\
+	t2 = BN_UMULT_HIGH(ta,tb);	\
+	c0 += t1; t2 += (c0<t1)?1:0;	\
+	c1 += t2; c2 += (c1<t2)?1:0;	\
+	}
+
+#define mul_add_c2(a,b,c0,c1,c2) {	\
+	BN_ULONG ta=(a),tb=(b),t0;	\
+	t1 = BN_UMULT_HIGH(ta,tb);	\
+	t0 = ta * tb;			\
+	t2 = t1+t1; c2 += (t2<t1)?1:0;	\
+	t1 = t0+t0; t2 += (t1<t0)?1:0;	\
+	c0 += t1; t2 += (c0<t1)?1:0;	\
+	c1 += t2; c2 += (c1<t2)?1:0;	\
+	}
+
+#define sqr_add_c(a,i,c0,c1,c2)	{	\
+	BN_ULONG ta=(a)[i];		\
+	t1 = ta * ta;			\
+	t2 = BN_UMULT_HIGH(ta,ta);	\
+	c0 += t1; t2 += (c0<t1)?1:0;	\
+	c1 += t2; c2 += (c1<t2)?1:0;	\
+	}
+
+#define sqr_add_c2(a,i,j,c0,c1,c2)	\
+	mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+#else /* !BN_LLONG */
+#define mul_add_c(a,b,c0,c1,c2) \
+	t1=LBITS(a); t2=HBITS(a); \
+	bl=LBITS(b); bh=HBITS(b); \
+	mul64(t1,t2,bl,bh); \
+	c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define mul_add_c2(a,b,c0,c1,c2) \
+	t1=LBITS(a); t2=HBITS(a); \
+	bl=LBITS(b); bh=HBITS(b); \
+	mul64(t1,t2,bl,bh); \
+	if (t2 & BN_TBIT) c2++; \
+	t2=(t2+t2)&BN_MASK2; \
+	if (t1 & BN_TBIT) t2++; \
+	t1=(t1+t1)&BN_MASK2; \
+	c0=(c0+t1)&BN_MASK2;  \
+	if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
+	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define sqr_add_c(a,i,c0,c1,c2) \
+	sqr64(t1,t2,(a)[i]); \
+	c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define sqr_add_c2(a,i,j,c0,c1,c2) \
+	mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+#endif /* !BN_LLONG */
+
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+	{
+#ifdef BN_LLONG
+	BN_ULLONG t;
+#else
+	BN_ULONG bl,bh;
+#endif
+	BN_ULONG t1,t2;
+	BN_ULONG c1,c2,c3;
+
+	c1=0;
+	c2=0;
+	c3=0;
+	mul_add_c(a[0],b[0],c1,c2,c3);
+	r[0]=c1;
+	c1=0;
+	mul_add_c(a[0],b[1],c2,c3,c1);
+	mul_add_c(a[1],b[0],c2,c3,c1);
+	r[1]=c2;
+	c2=0;
+	mul_add_c(a[2],b[0],c3,c1,c2);
+	mul_add_c(a[1],b[1],c3,c1,c2);
+	mul_add_c(a[0],b[2],c3,c1,c2);
+	r[2]=c3;
+	c3=0;
+	mul_add_c(a[0],b[3],c1,c2,c3);
+	mul_add_c(a[1],b[2],c1,c2,c3);
+	mul_add_c(a[2],b[1],c1,c2,c3);
+	mul_add_c(a[3],b[0],c1,c2,c3);
+	r[3]=c1;
+	c1=0;
+	mul_add_c(a[4],b[0],c2,c3,c1);
+	mul_add_c(a[3],b[1],c2,c3,c1);
+	mul_add_c(a[2],b[2],c2,c3,c1);
+	mul_add_c(a[1],b[3],c2,c3,c1);
+	mul_add_c(a[0],b[4],c2,c3,c1);
+	r[4]=c2;
+	c2=0;
+	mul_add_c(a[0],b[5],c3,c1,c2);
+	mul_add_c(a[1],b[4],c3,c1,c2);
+	mul_add_c(a[2],b[3],c3,c1,c2);
+	mul_add_c(a[3],b[2],c3,c1,c2);
+	mul_add_c(a[4],b[1],c3,c1,c2);
+	mul_add_c(a[5],b[0],c3,c1,c2);
+	r[5]=c3;
+	c3=0;
+	mul_add_c(a[6],b[0],c1,c2,c3);
+	mul_add_c(a[5],b[1],c1,c2,c3);
+	mul_add_c(a[4],b[2],c1,c2,c3);
+	mul_add_c(a[3],b[3],c1,c2,c3);
+	mul_add_c(a[2],b[4],c1,c2,c3);
+	mul_add_c(a[1],b[5],c1,c2,c3);
+	mul_add_c(a[0],b[6],c1,c2,c3);
+	r[6]=c1;
+	c1=0;
+	mul_add_c(a[0],b[7],c2,c3,c1);
+	mul_add_c(a[1],b[6],c2,c3,c1);
+	mul_add_c(a[2],b[5],c2,c3,c1);
+	mul_add_c(a[3],b[4],c2,c3,c1);
+	mul_add_c(a[4],b[3],c2,c3,c1);
+	mul_add_c(a[5],b[2],c2,c3,c1);
+	mul_add_c(a[6],b[1],c2,c3,c1);
+	mul_add_c(a[7],b[0],c2,c3,c1);
+	r[7]=c2;
+	c2=0;
+	mul_add_c(a[7],b[1],c3,c1,c2);
+	mul_add_c(a[6],b[2],c3,c1,c2);
+	mul_add_c(a[5],b[3],c3,c1,c2);
+	mul_add_c(a[4],b[4],c3,c1,c2);
+	mul_add_c(a[3],b[5],c3,c1,c2);
+	mul_add_c(a[2],b[6],c3,c1,c2);
+	mul_add_c(a[1],b[7],c3,c1,c2);
+	r[8]=c3;
+	c3=0;
+	mul_add_c(a[2],b[7],c1,c2,c3);
+	mul_add_c(a[3],b[6],c1,c2,c3);
+	mul_add_c(a[4],b[5],c1,c2,c3);
+	mul_add_c(a[5],b[4],c1,c2,c3);
+	mul_add_c(a[6],b[3],c1,c2,c3);
+	mul_add_c(a[7],b[2],c1,c2,c3);
+	r[9]=c1;
+	c1=0;
+	mul_add_c(a[7],b[3],c2,c3,c1);
+	mul_add_c(a[6],b[4],c2,c3,c1);
+	mul_add_c(a[5],b[5],c2,c3,c1);
+	mul_add_c(a[4],b[6],c2,c3,c1);
+	mul_add_c(a[3],b[7],c2,c3,c1);
+	r[10]=c2;
+	c2=0;
+	mul_add_c(a[4],b[7],c3,c1,c2);
+	mul_add_c(a[5],b[6],c3,c1,c2);
+	mul_add_c(a[6],b[5],c3,c1,c2);
+	mul_add_c(a[7],b[4],c3,c1,c2);
+	r[11]=c3;
+	c3=0;
+	mul_add_c(a[7],b[5],c1,c2,c3);
+	mul_add_c(a[6],b[6],c1,c2,c3);
+	mul_add_c(a[5],b[7],c1,c2,c3);
+	r[12]=c1;
+	c1=0;
+	mul_add_c(a[6],b[7],c2,c3,c1);
+	mul_add_c(a[7],b[6],c2,c3,c1);
+	r[13]=c2;
+	c2=0;
+	mul_add_c(a[7],b[7],c3,c1,c2);
+	r[14]=c3;
+	r[15]=c1;
+	}
+
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+	{
+#ifdef BN_LLONG
+	BN_ULLONG t;
+#else
+	BN_ULONG bl,bh;
+#endif
+	BN_ULONG t1,t2;
+	BN_ULONG c1,c2,c3;
+
+	c1=0;
+	c2=0;
+	c3=0;
+	mul_add_c(a[0],b[0],c1,c2,c3);
+	r[0]=c1;
+	c1=0;
+	mul_add_c(a[0],b[1],c2,c3,c1);
+	mul_add_c(a[1],b[0],c2,c3,c1);
+	r[1]=c2;
+	c2=0;
+	mul_add_c(a[2],b[0],c3,c1,c2);
+	mul_add_c(a[1],b[1],c3,c1,c2);
+	mul_add_c(a[0],b[2],c3,c1,c2);
+	r[2]=c3;
+	c3=0;
+	mul_add_c(a[0],b[3],c1,c2,c3);
+	mul_add_c(a[1],b[2],c1,c2,c3);
+	mul_add_c(a[2],b[1],c1,c2,c3);
+	mul_add_c(a[3],b[0],c1,c2,c3);
+	r[3]=c1;
+	c1=0;
+	mul_add_c(a[3],b[1],c2,c3,c1);
+	mul_add_c(a[2],b[2],c2,c3,c1);
+	mul_add_c(a[1],b[3],c2,c3,c1);
+	r[4]=c2;
+	c2=0;
+	mul_add_c(a[2],b[3],c3,c1,c2);
+	mul_add_c(a[3],b[2],c3,c1,c2);
+	r[5]=c3;
+	c3=0;
+	mul_add_c(a[3],b[3],c1,c2,c3);
+	r[6]=c1;
+	r[7]=c2;
+	}
+
+void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
+	{
+#ifdef BN_LLONG
+	BN_ULLONG t,tt;
+#else
+	BN_ULONG bl,bh;
+#endif
+	BN_ULONG t1,t2;
+	BN_ULONG c1,c2,c3;
+
+	c1=0;
+	c2=0;
+	c3=0;
+	sqr_add_c(a,0,c1,c2,c3);
+	r[0]=c1;
+	c1=0;
+	sqr_add_c2(a,1,0,c2,c3,c1);
+	r[1]=c2;
+	c2=0;
+	sqr_add_c(a,1,c3,c1,c2);
+	sqr_add_c2(a,2,0,c3,c1,c2);
+	r[2]=c3;
+	c3=0;
+	sqr_add_c2(a,3,0,c1,c2,c3);
+	sqr_add_c2(a,2,1,c1,c2,c3);
+	r[3]=c1;
+	c1=0;
+	sqr_add_c(a,2,c2,c3,c1);
+	sqr_add_c2(a,3,1,c2,c3,c1);
+	sqr_add_c2(a,4,0,c2,c3,c1);
+	r[4]=c2;
+	c2=0;
+	sqr_add_c2(a,5,0,c3,c1,c2);
+	sqr_add_c2(a,4,1,c3,c1,c2);
+	sqr_add_c2(a,3,2,c3,c1,c2);
+	r[5]=c3;
+	c3=0;
+	sqr_add_c(a,3,c1,c2,c3);
+	sqr_add_c2(a,4,2,c1,c2,c3);
+	sqr_add_c2(a,5,1,c1,c2,c3);
+	sqr_add_c2(a,6,0,c1,c2,c3);
+	r[6]=c1;
+	c1=0;
+	sqr_add_c2(a,7,0,c2,c3,c1);
+	sqr_add_c2(a,6,1,c2,c3,c1);
+	sqr_add_c2(a,5,2,c2,c3,c1);
+	sqr_add_c2(a,4,3,c2,c3,c1);
+	r[7]=c2;
+	c2=0;
+	sqr_add_c(a,4,c3,c1,c2);
+	sqr_add_c2(a,5,3,c3,c1,c2);
+	sqr_add_c2(a,6,2,c3,c1,c2);
+	sqr_add_c2(a,7,1,c3,c1,c2);
+	r[8]=c3;
+	c3=0;
+	sqr_add_c2(a,7,2,c1,c2,c3);
+	sqr_add_c2(a,6,3,c1,c2,c3);
+	sqr_add_c2(a,5,4,c1,c2,c3);
+	r[9]=c1;
+	c1=0;
+	sqr_add_c(a,5,c2,c3,c1);
+	sqr_add_c2(a,6,4,c2,c3,c1);
+	sqr_add_c2(a,7,3,c2,c3,c1);
+	r[10]=c2;
+	c2=0;
+	sqr_add_c2(a,7,4,c3,c1,c2);
+	sqr_add_c2(a,6,5,c3,c1,c2);
+	r[11]=c3;
+	c3=0;
+	sqr_add_c(a,6,c1,c2,c3);
+	sqr_add_c2(a,7,5,c1,c2,c3);
+	r[12]=c1;
+	c1=0;
+	sqr_add_c2(a,7,6,c2,c3,c1);
+	r[13]=c2;
+	c2=0;
+	sqr_add_c(a,7,c3,c1,c2);
+	r[14]=c3;
+	r[15]=c1;
+	}
+
+void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
+	{
+#ifdef BN_LLONG
+	BN_ULLONG t,tt;
+#else
+	BN_ULONG bl,bh;
+#endif
+	BN_ULONG t1,t2;
+	BN_ULONG c1,c2,c3;
+
+	c1=0;
+	c2=0;
+	c3=0;
+	sqr_add_c(a,0,c1,c2,c3);
+	r[0]=c1;
+	c1=0;
+	sqr_add_c2(a,1,0,c2,c3,c1);
+	r[1]=c2;
+	c2=0;
+	sqr_add_c(a,1,c3,c1,c2);
+	sqr_add_c2(a,2,0,c3,c1,c2);
+	r[2]=c3;
+	c3=0;
+	sqr_add_c2(a,3,0,c1,c2,c3);
+	sqr_add_c2(a,2,1,c1,c2,c3);
+	r[3]=c1;
+	c1=0;
+	sqr_add_c(a,2,c2,c3,c1);
+	sqr_add_c2(a,3,1,c2,c3,c1);
+	r[4]=c2;
+	c2=0;
+	sqr_add_c2(a,3,2,c3,c1,c2);
+	r[5]=c3;
+	c3=0;
+	sqr_add_c(a,3,c1,c2,c3);
+	r[6]=c1;
+	r[7]=c2;
+	}
+
+#ifdef OPENSSL_NO_ASM
+#ifdef OPENSSL_BN_ASM_MONT
+#include <alloca.h>
+/*
+ * This is essentially reference implementation, which may or may not
+ * result in performance improvement. E.g. on IA-32 this routine was
+ * observed to give 40% faster rsa1024 private key operations and 10%
+ * faster rsa4096 ones, while on AMD64 it improves rsa1024 sign only
+ * by 10% and *worsens* rsa4096 sign by 15%. Once again, it's a
+ * reference implementation, one to be used as starting point for
+ * platform-specific assembler. Mentioned numbers apply to compiler
+ * generated code compiled with and without -DOPENSSL_BN_ASM_MONT and
+ * can vary not only from platform to platform, but even for compiler
+ * versions. Assembler vs. assembler improvement coefficients can
+ * [and are known to] differ and are to be documented elsewhere.
+ */
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0p, int num)
+	{
+	BN_ULONG c0,c1,ml,*tp,n0;
+#ifdef mul64
+	BN_ULONG mh;
+#endif
+	volatile BN_ULONG *vp;
+	int i=0,j;
+
+#if 0	/* template for platform-specific implementation */
+	if (ap==bp)	return bn_sqr_mont(rp,ap,np,n0p,num);
+#endif
+	vp = tp = alloca((num+2)*sizeof(BN_ULONG));
+
+	n0 = *n0p;
+
+	c0 = 0;
+	ml = bp[0];
+#ifdef mul64
+	mh = HBITS(ml);
+	ml = LBITS(ml);
+	for (j=0;j<num;++j)
+		mul(tp[j],ap[j],ml,mh,c0);
+#else
+	for (j=0;j<num;++j)
+		mul(tp[j],ap[j],ml,c0);
+#endif
+
+	tp[num]   = c0;
+	tp[num+1] = 0;
+	goto enter;
+
+	for(i=0;i<num;i++)
+		{
+		c0 = 0;
+		ml = bp[i];
+#ifdef mul64
+		mh = HBITS(ml);
+		ml = LBITS(ml);
+		for (j=0;j<num;++j)
+			mul_add(tp[j],ap[j],ml,mh,c0);
+#else
+		for (j=0;j<num;++j)
+			mul_add(tp[j],ap[j],ml,c0);
+#endif
+		c1 = (tp[num] + c0)&BN_MASK2;
+		tp[num]   = c1;
+		tp[num+1] = (c1<c0?1:0);
+	enter:
+		c1  = tp[0];
+		ml = (c1*n0)&BN_MASK2;
+		c0 = 0;
+#ifdef mul64
+		mh = HBITS(ml);
+		ml = LBITS(ml);
+		mul_add(c1,np[0],ml,mh,c0);
+#else
+		mul_add(c1,ml,np[0],c0);
+#endif
+		for(j=1;j<num;j++)
+			{
+			c1 = tp[j];
+#ifdef mul64
+			mul_add(c1,np[j],ml,mh,c0);
+#else
+			mul_add(c1,ml,np[j],c0);
+#endif
+			tp[j-1] = c1&BN_MASK2;
+			}
+		c1        = (tp[num] + c0)&BN_MASK2;
+		tp[num-1] = c1;
+		tp[num]   = tp[num+1] + (c1<c0?1:0);
+		}
+
+	if (tp[num]!=0 || tp[num-1]>=np[num-1])
+		{
+		c0 = bn_sub_words(rp,tp,np,num);
+		if (tp[num]!=0 || c0==0)
+			{
+			for(i=0;i<num+2;i++)	vp[i] = 0;
+			return 1;
+			}
+		}
+	for(i=0;i<num;i++)	rp[i] = tp[i],	vp[i] = 0;
+	vp[num]   = 0;
+	vp[num+1] = 0;
+	return 1;
+	}
+#else
+/*
+ * Return value of 0 indicates that multiplication/convolution was not
+ * performed to signal the caller to fall down to alternative/original
+ * code-path.
+ */
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num)
+{	return 0;	}
+#endif /* OPENSSL_BN_ASM_MONT */
+#endif
+
+#else /* !BN_MUL_COMBA */
+
+/* hmm... is it faster just to do a multiply? */
+#undef bn_sqr_comba4
+void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
+	{
+	BN_ULONG t[8];
+	bn_sqr_normal(r,a,4,t);
+	}
+
+#undef bn_sqr_comba8
+void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
+	{
+	BN_ULONG t[16];
+	bn_sqr_normal(r,a,8,t);
+	}
+
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+	{
+	r[4]=bn_mul_words(    &(r[0]),a,4,b[0]);
+	r[5]=bn_mul_add_words(&(r[1]),a,4,b[1]);
+	r[6]=bn_mul_add_words(&(r[2]),a,4,b[2]);
+	r[7]=bn_mul_add_words(&(r[3]),a,4,b[3]);
+	}
+
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+	{
+	r[ 8]=bn_mul_words(    &(r[0]),a,8,b[0]);
+	r[ 9]=bn_mul_add_words(&(r[1]),a,8,b[1]);
+	r[10]=bn_mul_add_words(&(r[2]),a,8,b[2]);
+	r[11]=bn_mul_add_words(&(r[3]),a,8,b[3]);
+	r[12]=bn_mul_add_words(&(r[4]),a,8,b[4]);
+	r[13]=bn_mul_add_words(&(r[5]),a,8,b[5]);
+	r[14]=bn_mul_add_words(&(r[6]),a,8,b[6]);
+	r[15]=bn_mul_add_words(&(r[7]),a,8,b[7]);
+	}
+
+#ifdef OPENSSL_NO_ASM
+#ifdef OPENSSL_BN_ASM_MONT
+#include <alloca.h>
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0p, int num)
+	{
+	BN_ULONG c0,c1,*tp,n0=*n0p;
+	volatile BN_ULONG *vp;
+	int i=0,j;
+
+	vp = tp = alloca((num+2)*sizeof(BN_ULONG));
+
+	for(i=0;i<=num;i++)	tp[i]=0;
+
+	for(i=0;i<num;i++)
+		{
+		c0         = bn_mul_add_words(tp,ap,num,bp[i]);
+		c1         = (tp[num] + c0)&BN_MASK2;
+		tp[num]    = c1;
+		tp[num+1]  = (c1<c0?1:0);
+
+		c0         = bn_mul_add_words(tp,np,num,tp[0]*n0);
+		c1         = (tp[num] + c0)&BN_MASK2;
+		tp[num]    = c1;
+		tp[num+1] += (c1<c0?1:0);
+		for(j=0;j<=num;j++)	tp[j]=tp[j+1];
+		}
+
+	if (tp[num]!=0 || tp[num-1]>=np[num-1])
+		{
+		c0 = bn_sub_words(rp,tp,np,num);
+		if (tp[num]!=0 || c0==0)
+			{
+			for(i=0;i<num+2;i++)	vp[i] = 0;
+			return 1;
+			}
+		}
+	for(i=0;i<num;i++)	rp[i] = tp[i],	vp[i] = 0;
+	vp[num]   = 0;
+	vp[num+1] = 0;
+	return 1;
+	}
+#else
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num)
+{	return 0;	}
+#endif /* OPENSSL_BN_ASM_MONT */
+#endif
+
+#endif /* !BN_MUL_COMBA */
diff --git a/openssl/crypto/bn/bn_blind.c b/openssl/crypto/bn/bn_blind.c
new file mode 100644
index 0000000..9ed8bc2
--- /dev/null
+++ b/openssl/crypto/bn/bn_blind.c
@@ -0,0 +1,385 @@
+/* crypto/bn/bn_blind.c */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#define BN_BLINDING_COUNTER	32
+
+struct bn_blinding_st
+	{
+	BIGNUM *A;
+	BIGNUM *Ai;
+	BIGNUM *e;
+	BIGNUM *mod; /* just a reference */
+#ifndef OPENSSL_NO_DEPRECATED
+	unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b;
+				  * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */
+#endif
+	CRYPTO_THREADID tid;
+	int counter;
+	unsigned long flags;
+	BN_MONT_CTX *m_ctx;
+	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			  const BIGNUM *m, BN_CTX *ctx,
+			  BN_MONT_CTX *m_ctx);
+	};
+
+BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
+	{
+	BN_BLINDING *ret=NULL;
+
+	bn_check_top(mod);
+
+	if ((ret=(BN_BLINDING *)OPENSSL_malloc(sizeof(BN_BLINDING))) == NULL)
+		{
+		BNerr(BN_F_BN_BLINDING_NEW,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	memset(ret,0,sizeof(BN_BLINDING));
+	if (A != NULL)
+		{
+		if ((ret->A  = BN_dup(A))  == NULL) goto err;
+		}
+	if (Ai != NULL)
+		{
+		if ((ret->Ai = BN_dup(Ai)) == NULL) goto err;
+		}
+
+	/* save a copy of mod in the BN_BLINDING structure */
+	if ((ret->mod = BN_dup(mod)) == NULL) goto err;
+	if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0)
+		BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
+
+	/* Set the counter to the special value -1
+	 * to indicate that this is never-used fresh blinding
+	 * that does not need updating before first use. */
+	ret->counter = -1;
+	CRYPTO_THREADID_current(&ret->tid);
+	return(ret);
+err:
+	if (ret != NULL) BN_BLINDING_free(ret);
+	return(NULL);
+	}
+
+void BN_BLINDING_free(BN_BLINDING *r)
+	{
+	if(r == NULL)
+	    return;
+
+	if (r->A  != NULL) BN_free(r->A );
+	if (r->Ai != NULL) BN_free(r->Ai);
+	if (r->e  != NULL) BN_free(r->e );
+	if (r->mod != NULL) BN_free(r->mod); 
+	OPENSSL_free(r);
+	}
+
+int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
+	{
+	int ret=0;
+
+	if ((b->A == NULL) || (b->Ai == NULL))
+		{
+		BNerr(BN_F_BN_BLINDING_UPDATE,BN_R_NOT_INITIALIZED);
+		goto err;
+		}
+
+	if (b->counter == -1)
+		b->counter = 0;
+
+	if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL &&
+		!(b->flags & BN_BLINDING_NO_RECREATE))
+		{
+		/* re-create blinding parameters */
+		if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL))
+			goto err;
+		}
+	else if (!(b->flags & BN_BLINDING_NO_UPDATE))
+		{
+		if (!BN_mod_mul(b->A,b->A,b->A,b->mod,ctx)) goto err;
+		if (!BN_mod_mul(b->Ai,b->Ai,b->Ai,b->mod,ctx)) goto err;
+		}
+
+	ret=1;
+err:
+	if (b->counter == BN_BLINDING_COUNTER)
+		b->counter = 0;
+	return(ret);
+	}
+
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
+	{
+	return BN_BLINDING_convert_ex(n, NULL, b, ctx);
+	}
+
+int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
+	{
+	int ret = 1;
+
+	bn_check_top(n);
+
+	if ((b->A == NULL) || (b->Ai == NULL))
+		{
+		BNerr(BN_F_BN_BLINDING_CONVERT_EX,BN_R_NOT_INITIALIZED);
+		return(0);
+		}
+
+	if (b->counter == -1)
+		/* Fresh blinding, doesn't need updating. */
+		b->counter = 0;
+	else if (!BN_BLINDING_update(b,ctx))
+		return(0);
+
+	if (r != NULL)
+		{
+		if (!BN_copy(r, b->Ai)) ret=0;
+		}
+
+	if (!BN_mod_mul(n,n,b->A,b->mod,ctx)) ret=0;
+	
+	return ret;
+	}
+
+int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
+	{
+	return BN_BLINDING_invert_ex(n, NULL, b, ctx);
+	}
+
+int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
+	{
+	int ret;
+
+	bn_check_top(n);
+
+	if (r != NULL)
+		ret = BN_mod_mul(n, n, r, b->mod, ctx);
+	else
+		{
+		if (b->Ai == NULL)
+			{
+			BNerr(BN_F_BN_BLINDING_INVERT_EX,BN_R_NOT_INITIALIZED);
+			return(0);
+			}
+		ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);
+		}
+
+	bn_check_top(n);
+	return(ret);
+	}
+
+#ifndef OPENSSL_NO_DEPRECATED
+unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b)
+	{
+	return b->thread_id;
+	}
+
+void BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n)
+	{
+	b->thread_id = n;
+	}
+#endif
+
+CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *b)
+	{
+	return &b->tid;
+	}
+
+unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b)
+	{
+	return b->flags;
+	}
+
+void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags)
+	{
+	b->flags = flags;
+	}
+
+BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
+	const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
+	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
+	BN_MONT_CTX *m_ctx)
+{
+	int    retry_counter = 32;
+	BN_BLINDING *ret = NULL;
+
+	if (b == NULL)
+		ret = BN_BLINDING_new(NULL, NULL, m);
+	else
+		ret = b;
+
+	if (ret == NULL)
+		goto err;
+
+	if (ret->A  == NULL && (ret->A  = BN_new()) == NULL)
+		goto err;
+	if (ret->Ai == NULL && (ret->Ai	= BN_new()) == NULL)
+		goto err;
+
+	if (e != NULL)
+		{
+		if (ret->e != NULL)
+			BN_free(ret->e);
+		ret->e = BN_dup(e);
+		}
+	if (ret->e == NULL)
+		goto err;
+
+	if (bn_mod_exp != NULL)
+		ret->bn_mod_exp = bn_mod_exp;
+	if (m_ctx != NULL)
+		ret->m_ctx = m_ctx;
+
+	do {
+		if (!BN_rand_range(ret->A, ret->mod)) goto err;
+		if (BN_mod_inverse(ret->Ai, ret->A, ret->mod, ctx) == NULL)
+			{
+			/* this should almost never happen for good RSA keys */
+			unsigned long error = ERR_peek_last_error();
+			if (ERR_GET_REASON(error) == BN_R_NO_INVERSE)
+				{
+				if (retry_counter-- == 0)
+				{
+					BNerr(BN_F_BN_BLINDING_CREATE_PARAM,
+						BN_R_TOO_MANY_ITERATIONS);
+					goto err;
+				}
+				ERR_clear_error();
+				}
+			else
+				goto err;
+			}
+		else
+			break;
+	} while (1);
+
+	if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL)
+		{
+		if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx))
+			goto err;
+		}
+	else
+		{
+		if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx))
+			goto err;
+		}
+
+	return ret;
+err:
+	if (b == NULL && ret != NULL)
+		{
+		BN_BLINDING_free(ret);
+		ret = NULL;
+		}
+
+	return ret;
+}
diff --git a/openssl/crypto/bn/bn_const.c b/openssl/crypto/bn/bn_const.c
new file mode 100755
index 0000000..eb60a25
--- /dev/null
+++ b/openssl/crypto/bn/bn_const.c
@@ -0,0 +1,402 @@
+/* crypto/bn/knownprimes.c */
+/* Insert boilerplate */
+
+#include "bn.h"
+
+/* "First Oakley Default Group" from RFC2409, section 6.1.
+ *
+ * The prime is: 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 }
+ *
+ * RFC2409 specifies a generator of 2.
+ * RFC2412 specifies a generator of of 22.
+ */
+
+BIGNUM *get_rfc2409_prime_768(BIGNUM *bn)
+	{
+	static const unsigned char RFC2409_PRIME_768[]={
+		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
+		0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
+		0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
+		0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+		0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
+		0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
+		0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
+		0xA6,0x3A,0x36,0x20,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+		};
+	return BN_bin2bn(RFC2409_PRIME_768,sizeof(RFC2409_PRIME_768),bn);
+	}
+
+/* "Second Oakley Default Group" from RFC2409, section 6.2.
+ *
+ * The prime is: 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }.
+ *
+ * RFC2409 specifies a generator of 2.
+ * RFC2412 specifies a generator of 22.
+ */
+
+BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn)
+	{
+	static const unsigned char RFC2409_PRIME_1024[]={
+		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
+		0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
+		0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
+		0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+		0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
+		0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
+		0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
+		0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+		0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
+		0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
+		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+		};
+	return BN_bin2bn(RFC2409_PRIME_1024,sizeof(RFC2409_PRIME_1024),bn);
+	}
+
+/* "1536-bit MODP Group" from RFC3526, Section 2.
+ *
+ * The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 }
+ *
+ * RFC3526 specifies a generator of 2.
+ * RFC2312 specifies a generator of 22.
+ */
+
+BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn)
+	{
+	static const unsigned char RFC3526_PRIME_1536[]={
+		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
+		0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
+		0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
+		0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+		0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
+		0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
+		0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
+		0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+		0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
+		0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
+		0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
+		0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+		0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
+		0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
+		0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
+		0xCA,0x23,0x73,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+		};
+	return BN_bin2bn(RFC3526_PRIME_1536,sizeof(RFC3526_PRIME_1536),bn);
+	}
+
+/* "2048-bit MODP Group" from RFC3526, Section 3.
+ *
+ * The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn)
+	{
+	static const unsigned char RFC3526_PRIME_2048[]={
+		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
+		0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
+		0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
+		0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+		0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
+		0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
+		0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
+		0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+		0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
+		0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
+		0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
+		0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+		0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
+		0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
+		0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
+		0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+		0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
+		0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
+		0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
+		0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+		0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,
+		0xFF,0xFF,0xFF,0xFF,
+		};
+	return BN_bin2bn(RFC3526_PRIME_2048,sizeof(RFC3526_PRIME_2048),bn);
+	}
+
+/* "3072-bit MODP Group" from RFC3526, Section 4.
+ *
+ * The prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn)
+	{
+	static const unsigned char RFC3526_PRIME_3072[]={
+		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
+		0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
+		0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
+		0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+		0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
+		0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
+		0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
+		0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+		0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
+		0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
+		0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
+		0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+		0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
+		0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
+		0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
+		0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+		0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
+		0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
+		0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
+		0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+		0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
+		0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
+		0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
+		0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+		0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
+		0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
+		0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
+		0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+		0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
+		0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
+		0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
+		0xA9,0x3A,0xD2,0xCA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+		};
+	return BN_bin2bn(RFC3526_PRIME_3072,sizeof(RFC3526_PRIME_3072),bn);
+	}
+
+/* "4096-bit MODP Group" from RFC3526, Section 5.
+ *
+ * The prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn)
+	{
+	static const unsigned char RFC3526_PRIME_4096[]={
+		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
+		0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
+		0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
+		0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+		0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
+		0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
+		0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
+		0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+		0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
+		0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
+		0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
+		0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+		0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
+		0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
+		0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
+		0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+		0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
+		0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
+		0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
+		0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+		0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
+		0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
+		0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
+		0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+		0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
+		0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
+		0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
+		0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+		0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
+		0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
+		0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
+		0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
+		0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
+		0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
+		0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
+		0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
+		0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
+		0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
+		0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
+		0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
+		0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
+		0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,
+		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+		};
+	return BN_bin2bn(RFC3526_PRIME_4096,sizeof(RFC3526_PRIME_4096),bn);
+	}
+
+/* "6144-bit MODP Group" from RFC3526, Section 6.
+ *
+ * The prime is: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn)
+	{
+	static const unsigned char RFC3526_PRIME_6144[]={
+		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
+		0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
+		0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
+		0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+		0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
+		0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
+		0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
+		0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+		0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
+		0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
+		0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
+		0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+		0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
+		0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
+		0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
+		0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+		0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
+		0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
+		0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
+		0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+		0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
+		0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
+		0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
+		0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+		0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
+		0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
+		0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
+		0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+		0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
+		0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
+		0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
+		0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
+		0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
+		0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
+		0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
+		0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
+		0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
+		0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
+		0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
+		0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
+		0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
+		0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
+		0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
+		0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
+		0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
+		0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
+		0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
+		0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
+		0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
+		0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
+		0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
+		0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
+		0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
+		0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
+		0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
+		0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
+		0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
+		0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
+		0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
+		0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
+		0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
+		0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
+		0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
+		0x6D,0xCC,0x40,0x24,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+		};
+	return BN_bin2bn(RFC3526_PRIME_6144,sizeof(RFC3526_PRIME_6144),bn);
+	}
+
+/* "8192-bit MODP Group" from RFC3526, Section 7.
+ *
+ * The prime is: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn)
+	{
+	static const unsigned char RFC3526_PRIME_8192[]={
+		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
+		0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
+		0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
+		0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+		0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
+		0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
+		0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
+		0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+		0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
+		0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
+		0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
+		0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+		0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
+		0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
+		0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
+		0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+		0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
+		0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
+		0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
+		0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+		0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
+		0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
+		0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
+		0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+		0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
+		0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
+		0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
+		0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+		0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
+		0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
+		0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
+		0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
+		0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
+		0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
+		0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
+		0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
+		0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
+		0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
+		0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
+		0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
+		0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
+		0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
+		0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
+		0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
+		0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
+		0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
+		0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
+		0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
+		0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
+		0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
+		0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
+		0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
+		0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
+		0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
+		0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
+		0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
+		0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
+		0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
+		0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
+		0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
+		0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
+		0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
+		0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
+		0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
+		0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,
+		0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,
+		0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93,
+		0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
+		0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,
+		0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,
+		0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8,
+		0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
+		0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,
+		0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,
+		0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8,
+		0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
+		0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,
+		0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,
+		0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3,
+		0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
+		0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,
+		0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,
+		0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2,
+		0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
+		0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,
+		0xFF,0xFF,0xFF,0xFF,
+		};
+	return BN_bin2bn(RFC3526_PRIME_8192,sizeof(RFC3526_PRIME_8192),bn);
+	}
+
diff --git a/openssl/crypto/bn/bn_ctx.c b/openssl/crypto/bn/bn_ctx.c
new file mode 100644
index 0000000..3f2256f
--- /dev/null
+++ b/openssl/crypto/bn/bn_ctx.c
@@ -0,0 +1,454 @@
+/* crypto/bn/bn_ctx.c */
+/* Written by Ulf Moeller for the OpenSSL project. */
+/* ====================================================================
+ * Copyright (c) 1998-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#if !defined(BN_CTX_DEBUG) && !defined(BN_DEBUG)
+#ifndef NDEBUG
+#define NDEBUG
+#endif
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* TODO list
+ *
+ * 1. Check a bunch of "(words+1)" type hacks in various bignum functions and
+ * check they can be safely removed.
+ *  - Check +1 and other ugliness in BN_from_montgomery()
+ *
+ * 2. Consider allowing a BN_new_ex() that, at least, lets you specify an
+ * appropriate 'block' size that will be honoured by bn_expand_internal() to
+ * prevent piddly little reallocations. OTOH, profiling bignum expansions in
+ * BN_CTX doesn't show this to be a big issue.
+ */
+
+/* How many bignums are in each "pool item"; */
+#define BN_CTX_POOL_SIZE	16
+/* The stack frame info is resizing, set a first-time expansion size; */
+#define BN_CTX_START_FRAMES	32
+
+/***********/
+/* BN_POOL */
+/***********/
+
+/* A bundle of bignums that can be linked with other bundles */
+typedef struct bignum_pool_item
+	{
+	/* The bignum values */
+	BIGNUM vals[BN_CTX_POOL_SIZE];
+	/* Linked-list admin */
+	struct bignum_pool_item *prev, *next;
+	} BN_POOL_ITEM;
+/* A linked-list of bignums grouped in bundles */
+typedef struct bignum_pool
+	{
+	/* Linked-list admin */
+	BN_POOL_ITEM *head, *current, *tail;
+	/* Stack depth and allocation size */
+	unsigned used, size;
+	} BN_POOL;
+static void		BN_POOL_init(BN_POOL *);
+static void		BN_POOL_finish(BN_POOL *);
+#ifndef OPENSSL_NO_DEPRECATED
+static void		BN_POOL_reset(BN_POOL *);
+#endif
+static BIGNUM *		BN_POOL_get(BN_POOL *);
+static void		BN_POOL_release(BN_POOL *, unsigned int);
+
+/************/
+/* BN_STACK */
+/************/
+
+/* A wrapper to manage the "stack frames" */
+typedef struct bignum_ctx_stack
+	{
+	/* Array of indexes into the bignum stack */
+	unsigned int *indexes;
+	/* Number of stack frames, and the size of the allocated array */
+	unsigned int depth, size;
+	} BN_STACK;
+static void		BN_STACK_init(BN_STACK *);
+static void		BN_STACK_finish(BN_STACK *);
+#ifndef OPENSSL_NO_DEPRECATED
+static void		BN_STACK_reset(BN_STACK *);
+#endif
+static int		BN_STACK_push(BN_STACK *, unsigned int);
+static unsigned int	BN_STACK_pop(BN_STACK *);
+
+/**********/
+/* BN_CTX */
+/**********/
+
+/* The opaque BN_CTX type */
+struct bignum_ctx
+	{
+	/* The bignum bundles */
+	BN_POOL pool;
+	/* The "stack frames", if you will */
+	BN_STACK stack;
+	/* The number of bignums currently assigned */
+	unsigned int used;
+	/* Depth of stack overflow */
+	int err_stack;
+	/* Block "gets" until an "end" (compatibility behaviour) */
+	int too_many;
+	};
+
+/* Enable this to find BN_CTX bugs */
+#ifdef BN_CTX_DEBUG
+static const char *ctxdbg_cur = NULL;
+static void ctxdbg(BN_CTX *ctx)
+	{
+	unsigned int bnidx = 0, fpidx = 0;
+	BN_POOL_ITEM *item = ctx->pool.head;
+	BN_STACK *stack = &ctx->stack;
+	fprintf(stderr,"(%08x): ", (unsigned int)ctx);
+	while(bnidx < ctx->used)
+		{
+		fprintf(stderr,"%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax);
+		if(!(bnidx % BN_CTX_POOL_SIZE))
+			item = item->next;
+		}
+	fprintf(stderr,"\n");
+	bnidx = 0;
+	fprintf(stderr,"          : ");
+	while(fpidx < stack->depth)
+		{
+		while(bnidx++ < stack->indexes[fpidx])
+			fprintf(stderr,"    ");
+		fprintf(stderr,"^^^ ");
+		bnidx++;
+		fpidx++;
+		}
+	fprintf(stderr,"\n");
+	}
+#define CTXDBG_ENTRY(str, ctx)	do { \
+				ctxdbg_cur = (str); \
+				fprintf(stderr,"Starting %s\n", ctxdbg_cur); \
+				ctxdbg(ctx); \
+				} while(0)
+#define CTXDBG_EXIT(ctx)	do { \
+				fprintf(stderr,"Ending %s\n", ctxdbg_cur); \
+				ctxdbg(ctx); \
+				} while(0)
+#define CTXDBG_RET(ctx,ret)
+#else
+#define CTXDBG_ENTRY(str, ctx)
+#define CTXDBG_EXIT(ctx)
+#define CTXDBG_RET(ctx,ret)
+#endif
+
+/* This function is an evil legacy and should not be used. This implementation
+ * is WYSIWYG, though I've done my best. */
+#ifndef OPENSSL_NO_DEPRECATED
+void BN_CTX_init(BN_CTX *ctx)
+	{
+	/* Assume the caller obtained the context via BN_CTX_new() and so is
+	 * trying to reset it for use. Nothing else makes sense, least of all
+	 * binary compatibility from a time when they could declare a static
+	 * variable. */
+	BN_POOL_reset(&ctx->pool);
+	BN_STACK_reset(&ctx->stack);
+	ctx->used = 0;
+	ctx->err_stack = 0;
+	ctx->too_many = 0;
+	}
+#endif
+
+BN_CTX *BN_CTX_new(void)
+	{
+	BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX));
+	if(!ret)
+		{
+		BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+	/* Initialise the structure */
+	BN_POOL_init(&ret->pool);
+	BN_STACK_init(&ret->stack);
+	ret->used = 0;
+	ret->err_stack = 0;
+	ret->too_many = 0;
+	return ret;
+	}
+
+void BN_CTX_free(BN_CTX *ctx)
+	{
+	if (ctx == NULL)
+		return;
+#ifdef BN_CTX_DEBUG
+	{
+	BN_POOL_ITEM *pool = ctx->pool.head;
+	fprintf(stderr,"BN_CTX_free, stack-size=%d, pool-bignums=%d\n",
+		ctx->stack.size, ctx->pool.size);
+	fprintf(stderr,"dmaxs: ");
+	while(pool) {
+		unsigned loop = 0;
+		while(loop < BN_CTX_POOL_SIZE)
+			fprintf(stderr,"%02x ", pool->vals[loop++].dmax);
+		pool = pool->next;
+	}
+	fprintf(stderr,"\n");
+	}
+#endif
+	BN_STACK_finish(&ctx->stack);
+	BN_POOL_finish(&ctx->pool);
+	OPENSSL_free(ctx);
+	}
+
+void BN_CTX_start(BN_CTX *ctx)
+	{
+	CTXDBG_ENTRY("BN_CTX_start", ctx);
+	/* If we're already overflowing ... */
+	if(ctx->err_stack || ctx->too_many)
+		ctx->err_stack++;
+	/* (Try to) get a new frame pointer */
+	else if(!BN_STACK_push(&ctx->stack, ctx->used))
+		{
+		BNerr(BN_F_BN_CTX_START,BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+		ctx->err_stack++;
+		}
+	CTXDBG_EXIT(ctx);
+	}
+
+void BN_CTX_end(BN_CTX *ctx)
+	{
+	CTXDBG_ENTRY("BN_CTX_end", ctx);
+	if(ctx->err_stack)
+		ctx->err_stack--;
+	else
+		{
+		unsigned int fp = BN_STACK_pop(&ctx->stack);
+		/* Does this stack frame have anything to release? */
+		if(fp < ctx->used)
+			BN_POOL_release(&ctx->pool, ctx->used - fp);
+		ctx->used = fp;
+		/* Unjam "too_many" in case "get" had failed */
+		ctx->too_many = 0;
+		}
+	CTXDBG_EXIT(ctx);
+	}
+
+BIGNUM *BN_CTX_get(BN_CTX *ctx)
+	{
+	BIGNUM *ret;
+	CTXDBG_ENTRY("BN_CTX_get", ctx);
+	if(ctx->err_stack || ctx->too_many) return NULL;
+	if((ret = BN_POOL_get(&ctx->pool)) == NULL)
+		{
+		/* Setting too_many prevents repeated "get" attempts from
+		 * cluttering the error stack. */
+		ctx->too_many = 1;
+		BNerr(BN_F_BN_CTX_GET,BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+		return NULL;
+		}
+	/* OK, make sure the returned bignum is "zero" */
+	BN_zero(ret);
+	ctx->used++;
+	CTXDBG_RET(ctx, ret);
+	return ret;
+	}
+
+/************/
+/* BN_STACK */
+/************/
+
+static void BN_STACK_init(BN_STACK *st)
+	{
+	st->indexes = NULL;
+	st->depth = st->size = 0;
+	}
+
+static void BN_STACK_finish(BN_STACK *st)
+	{
+	if(st->size) OPENSSL_free(st->indexes);
+	}
+
+#ifndef OPENSSL_NO_DEPRECATED
+static void BN_STACK_reset(BN_STACK *st)
+	{
+	st->depth = 0;
+	}
+#endif
+
+static int BN_STACK_push(BN_STACK *st, unsigned int idx)
+	{
+	if(st->depth == st->size)
+		/* Need to expand */
+		{
+		unsigned int newsize = (st->size ?
+				(st->size * 3 / 2) : BN_CTX_START_FRAMES);
+		unsigned int *newitems = OPENSSL_malloc(newsize *
+						sizeof(unsigned int));
+		if(!newitems) return 0;
+		if(st->depth)
+			memcpy(newitems, st->indexes, st->depth *
+						sizeof(unsigned int));
+		if(st->size) OPENSSL_free(st->indexes);
+		st->indexes = newitems;
+		st->size = newsize;
+		}
+	st->indexes[(st->depth)++] = idx;
+	return 1;
+	}
+
+static unsigned int BN_STACK_pop(BN_STACK *st)
+	{
+	return st->indexes[--(st->depth)];
+	}
+
+/***********/
+/* BN_POOL */
+/***********/
+
+static void BN_POOL_init(BN_POOL *p)
+	{
+	p->head = p->current = p->tail = NULL;
+	p->used = p->size = 0;
+	}
+
+static void BN_POOL_finish(BN_POOL *p)
+	{
+	while(p->head)
+		{
+		unsigned int loop = 0;
+		BIGNUM *bn = p->head->vals;
+		while(loop++ < BN_CTX_POOL_SIZE)
+			{
+			if(bn->d) BN_clear_free(bn);
+			bn++;
+			}
+		p->current = p->head->next;
+		OPENSSL_free(p->head);
+		p->head = p->current;
+		}
+	}
+
+#ifndef OPENSSL_NO_DEPRECATED
+static void BN_POOL_reset(BN_POOL *p)
+	{
+	BN_POOL_ITEM *item = p->head;
+	while(item)
+		{
+		unsigned int loop = 0;
+		BIGNUM *bn = item->vals;
+		while(loop++ < BN_CTX_POOL_SIZE)
+			{
+			if(bn->d) BN_clear(bn);
+			bn++;
+			}
+		item = item->next;
+		}
+	p->current = p->head;
+	p->used = 0;
+	}
+#endif
+
+static BIGNUM *BN_POOL_get(BN_POOL *p)
+	{
+	if(p->used == p->size)
+		{
+		BIGNUM *bn;
+		unsigned int loop = 0;
+		BN_POOL_ITEM *item = OPENSSL_malloc(sizeof(BN_POOL_ITEM));
+		if(!item) return NULL;
+		/* Initialise the structure */
+		bn = item->vals;
+		while(loop++ < BN_CTX_POOL_SIZE)
+			BN_init(bn++);
+		item->prev = p->tail;
+		item->next = NULL;
+		/* Link it in */
+		if(!p->head)
+			p->head = p->current = p->tail = item;
+		else
+			{
+			p->tail->next = item;
+			p->tail = item;
+			p->current = item;
+			}
+		p->size += BN_CTX_POOL_SIZE;
+		p->used++;
+		/* Return the first bignum from the new pool */
+		return item->vals;
+		}
+	if(!p->used)
+		p->current = p->head;
+	else if((p->used % BN_CTX_POOL_SIZE) == 0)
+		p->current = p->current->next;
+	return p->current->vals + ((p->used++) % BN_CTX_POOL_SIZE);
+	}
+
+static void BN_POOL_release(BN_POOL *p, unsigned int num)
+	{
+	unsigned int offset = (p->used - 1) % BN_CTX_POOL_SIZE;
+	p->used -= num;
+	while(num--)
+		{
+		bn_check_top(p->current->vals + offset);
+		if(!offset)
+			{
+			offset = BN_CTX_POOL_SIZE - 1;
+			p->current = p->current->prev;
+			}
+		else
+			offset--;
+		}
+	}
+
diff --git a/openssl/crypto/bn/bn_depr.c b/openssl/crypto/bn/bn_depr.c
new file mode 100644
index 0000000..27535e4
--- /dev/null
+++ b/openssl/crypto/bn/bn_depr.c
@@ -0,0 +1,112 @@
+/* crypto/bn/bn_depr.c */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Support for deprecated functions goes here - static linkage will only slurp
+ * this code if applications are using them directly. */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+#include <openssl/rand.h>
+
+static void *dummy=&dummy;
+
+#ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe,
+	const BIGNUM *add, const BIGNUM *rem,
+	void (*callback)(int,int,void *), void *cb_arg)
+	{
+	BN_GENCB cb;
+	BIGNUM *rnd=NULL;
+	int found = 0;
+
+	BN_GENCB_set_old(&cb, callback, cb_arg);
+
+	if (ret == NULL)
+		{
+		if ((rnd=BN_new()) == NULL) goto err;
+		}
+	else
+		rnd=ret;
+	if(!BN_generate_prime_ex(rnd, bits, safe, add, rem, &cb))
+		goto err;
+
+	/* we have a prime :-) */
+	found = 1;
+err:
+	if (!found && (ret == NULL) && (rnd != NULL)) BN_free(rnd);
+	return(found ? rnd : NULL);
+	}
+
+int BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int,int,void *),
+	BN_CTX *ctx_passed, void *cb_arg)
+	{
+	BN_GENCB cb;
+	BN_GENCB_set_old(&cb, callback, cb_arg);
+	return BN_is_prime_ex(a, checks, ctx_passed, &cb);
+	}
+
+int BN_is_prime_fasttest(const BIGNUM *a, int checks,
+		void (*callback)(int,int,void *),
+		BN_CTX *ctx_passed, void *cb_arg,
+		int do_trial_division)
+	{
+	BN_GENCB cb;
+	BN_GENCB_set_old(&cb, callback, cb_arg);
+	return BN_is_prime_fasttest_ex(a, checks, ctx_passed,
+				do_trial_division, &cb);
+	}
+#endif
diff --git a/openssl/crypto/bn/bn_div.c b/openssl/crypto/bn/bn_div.c
new file mode 100644
index 0000000..802a43d
--- /dev/null
+++ b/openssl/crypto/bn/bn_div.c
@@ -0,0 +1,650 @@
+/* crypto/bn/bn_div.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/bn.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+
+/* The old slow way */
+#if 0
+int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+	   BN_CTX *ctx)
+	{
+	int i,nm,nd;
+	int ret = 0;
+	BIGNUM *D;
+
+	bn_check_top(m);
+	bn_check_top(d);
+	if (BN_is_zero(d))
+		{
+		BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO);
+		return(0);
+		}
+
+	if (BN_ucmp(m,d) < 0)
+		{
+		if (rem != NULL)
+			{ if (BN_copy(rem,m) == NULL) return(0); }
+		if (dv != NULL) BN_zero(dv);
+		return(1);
+		}
+
+	BN_CTX_start(ctx);
+	D = BN_CTX_get(ctx);
+	if (dv == NULL) dv = BN_CTX_get(ctx);
+	if (rem == NULL) rem = BN_CTX_get(ctx);
+	if (D == NULL || dv == NULL || rem == NULL)
+		goto end;
+
+	nd=BN_num_bits(d);
+	nm=BN_num_bits(m);
+	if (BN_copy(D,d) == NULL) goto end;
+	if (BN_copy(rem,m) == NULL) goto end;
+
+	/* The next 2 are needed so we can do a dv->d[0]|=1 later
+	 * since BN_lshift1 will only work once there is a value :-) */
+	BN_zero(dv);
+	if(bn_wexpand(dv,1) == NULL) goto end;
+	dv->top=1;
+
+	if (!BN_lshift(D,D,nm-nd)) goto end;
+	for (i=nm-nd; i>=0; i--)
+		{
+		if (!BN_lshift1(dv,dv)) goto end;
+		if (BN_ucmp(rem,D) >= 0)
+			{
+			dv->d[0]|=1;
+			if (!BN_usub(rem,rem,D)) goto end;
+			}
+/* CAN IMPROVE (and have now :=) */
+		if (!BN_rshift1(D,D)) goto end;
+		}
+	rem->neg=BN_is_zero(rem)?0:m->neg;
+	dv->neg=m->neg^d->neg;
+	ret = 1;
+ end:
+	BN_CTX_end(ctx);
+	return(ret);
+	}
+
+#else
+
+#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) \
+    && !defined(PEDANTIC) && !defined(BN_DIV3W)
+# if defined(__GNUC__) && __GNUC__>=2
+#  if defined(__i386) || defined (__i386__)
+   /*
+    * There were two reasons for implementing this template:
+    * - GNU C generates a call to a function (__udivdi3 to be exact)
+    *   in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to
+    *   understand why...);
+    * - divl doesn't only calculate quotient, but also leaves
+    *   remainder in %edx which we can definitely use here:-)
+    *
+    *					<appro@fy.chalmers.se>
+    */
+#  define bn_div_words(n0,n1,d0)		\
+	({  asm volatile (			\
+		"divl	%4"			\
+		: "=a"(q), "=d"(rem)		\
+		: "a"(n1), "d"(n0), "g"(d0)	\
+		: "cc");			\
+	    q;					\
+	})
+#  define REMAINDER_IS_ALREADY_CALCULATED
+#  elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG)
+   /*
+    * Same story here, but it's 128-bit by 64-bit division. Wow!
+    *					<appro@fy.chalmers.se>
+    */
+#  define bn_div_words(n0,n1,d0)		\
+	({  asm volatile (			\
+		"divq	%4"			\
+		: "=a"(q), "=d"(rem)		\
+		: "a"(n1), "d"(n0), "g"(d0)	\
+		: "cc");			\
+	    q;					\
+	})
+#  define REMAINDER_IS_ALREADY_CALCULATED
+#  endif /* __<cpu> */
+# endif /* __GNUC__ */
+#endif /* OPENSSL_NO_ASM */
+
+
+/* BN_div[_no_branch] computes  dv := num / divisor,  rounding towards
+ * zero, and sets up rm  such that  dv*divisor + rm = num  holds.
+ * Thus:
+ *     dv->neg == num->neg ^ divisor->neg  (unless the result is zero)
+ *     rm->neg == num->neg                 (unless the remainder is zero)
+ * If 'dv' or 'rm' is NULL, the respective value is not returned.
+ */
+static int BN_div_no_branch(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,
+        const BIGNUM *divisor, BN_CTX *ctx);
+int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
+	   BN_CTX *ctx)
+	{
+	int norm_shift,i,loop;
+	BIGNUM *tmp,wnum,*snum,*sdiv,*res;
+	BN_ULONG *resp,*wnump;
+	BN_ULONG d0,d1;
+	int num_n,div_n;
+
+	/* Invalid zero-padding would have particularly bad consequences
+	 * in the case of 'num', so don't just rely on bn_check_top() for this one
+	 * (bn_check_top() works only for BN_DEBUG builds) */
+	if (num->top > 0 && num->d[num->top - 1] == 0)
+		{
+		BNerr(BN_F_BN_DIV,BN_R_NOT_INITIALIZED);
+		return 0;
+		}
+
+	bn_check_top(num);
+
+	if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0))
+		{
+		return BN_div_no_branch(dv, rm, num, divisor, ctx);
+		}
+
+	bn_check_top(dv);
+	bn_check_top(rm);
+	/* bn_check_top(num); */ /* 'num' has been checked already */
+	bn_check_top(divisor);
+
+	if (BN_is_zero(divisor))
+		{
+		BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO);
+		return(0);
+		}
+
+	if (BN_ucmp(num,divisor) < 0)
+		{
+		if (rm != NULL)
+			{ if (BN_copy(rm,num) == NULL) return(0); }
+		if (dv != NULL) BN_zero(dv);
+		return(1);
+		}
+
+	BN_CTX_start(ctx);
+	tmp=BN_CTX_get(ctx);
+	snum=BN_CTX_get(ctx);
+	sdiv=BN_CTX_get(ctx);
+	if (dv == NULL)
+		res=BN_CTX_get(ctx);
+	else	res=dv;
+	if (sdiv == NULL || res == NULL || tmp == NULL || snum == NULL)
+		goto err;
+
+	/* First we normalise the numbers */
+	norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
+	if (!(BN_lshift(sdiv,divisor,norm_shift))) goto err;
+	sdiv->neg=0;
+	norm_shift+=BN_BITS2;
+	if (!(BN_lshift(snum,num,norm_shift))) goto err;
+	snum->neg=0;
+	div_n=sdiv->top;
+	num_n=snum->top;
+	loop=num_n-div_n;
+	/* Lets setup a 'window' into snum
+	 * This is the part that corresponds to the current
+	 * 'area' being divided */
+	wnum.neg   = 0;
+	wnum.d     = &(snum->d[loop]);
+	wnum.top   = div_n;
+	/* only needed when BN_ucmp messes up the values between top and max */
+	wnum.dmax  = snum->dmax - loop; /* so we don't step out of bounds */
+
+	/* Get the top 2 words of sdiv */
+	/* div_n=sdiv->top; */
+	d0=sdiv->d[div_n-1];
+	d1=(div_n == 1)?0:sdiv->d[div_n-2];
+
+	/* pointer to the 'top' of snum */
+	wnump= &(snum->d[num_n-1]);
+
+	/* Setup to 'res' */
+	res->neg= (num->neg^divisor->neg);
+	if (!bn_wexpand(res,(loop+1))) goto err;
+	res->top=loop;
+	resp= &(res->d[loop-1]);
+
+	/* space for temp */
+	if (!bn_wexpand(tmp,(div_n+1))) goto err;
+
+	if (BN_ucmp(&wnum,sdiv) >= 0)
+		{
+		/* If BN_DEBUG_RAND is defined BN_ucmp changes (via
+		 * bn_pollute) the const bignum arguments =>
+		 * clean the values between top and max again */
+		bn_clear_top2max(&wnum);
+		bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n);
+		*resp=1;
+		}
+	else
+		res->top--;
+	/* if res->top == 0 then clear the neg value otherwise decrease
+	 * the resp pointer */
+	if (res->top == 0)
+		res->neg = 0;
+	else
+		resp--;
+
+	for (i=0; i<loop-1; i++, wnump--, resp--)
+		{
+		BN_ULONG q,l0;
+		/* the first part of the loop uses the top two words of
+		 * snum and sdiv to calculate a BN_ULONG q such that
+		 * | wnum - sdiv * q | < sdiv */
+#if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM)
+		BN_ULONG bn_div_3_words(BN_ULONG*,BN_ULONG,BN_ULONG);
+		q=bn_div_3_words(wnump,d1,d0);
+#else
+		BN_ULONG n0,n1,rem=0;
+
+		n0=wnump[0];
+		n1=wnump[-1];
+		if (n0 == d0)
+			q=BN_MASK2;
+		else 			/* n0 < d0 */
+			{
+#ifdef BN_LLONG
+			BN_ULLONG t2;
+
+#if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
+			q=(BN_ULONG)(((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0);
+#else
+			q=bn_div_words(n0,n1,d0);
+#ifdef BN_DEBUG_LEVITTE
+			fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
+X) -> 0x%08X\n",
+				n0, n1, d0, q);
+#endif
+#endif
+
+#ifndef REMAINDER_IS_ALREADY_CALCULATED
+			/*
+			 * rem doesn't have to be BN_ULLONG. The least we
+			 * know it's less that d0, isn't it?
+			 */
+			rem=(n1-q*d0)&BN_MASK2;
+#endif
+			t2=(BN_ULLONG)d1*q;
+
+			for (;;)
+				{
+				if (t2 <= ((((BN_ULLONG)rem)<<BN_BITS2)|wnump[-2]))
+					break;
+				q--;
+				rem += d0;
+				if (rem < d0) break; /* don't let rem overflow */
+				t2 -= d1;
+				}
+#else /* !BN_LLONG */
+			BN_ULONG t2l,t2h;
+
+			q=bn_div_words(n0,n1,d0);
+#ifdef BN_DEBUG_LEVITTE
+			fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
+X) -> 0x%08X\n",
+				n0, n1, d0, q);
+#endif
+#ifndef REMAINDER_IS_ALREADY_CALCULATED
+			rem=(n1-q*d0)&BN_MASK2;
+#endif
+
+#if defined(BN_UMULT_LOHI)
+			BN_UMULT_LOHI(t2l,t2h,d1,q);
+#elif defined(BN_UMULT_HIGH)
+			t2l = d1 * q;
+			t2h = BN_UMULT_HIGH(d1,q);
+#else
+			{
+			BN_ULONG ql, qh;
+			t2l=LBITS(d1); t2h=HBITS(d1);
+			ql =LBITS(q);  qh =HBITS(q);
+			mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
+			}
+#endif
+
+			for (;;)
+				{
+				if ((t2h < rem) ||
+					((t2h == rem) && (t2l <= wnump[-2])))
+					break;
+				q--;
+				rem += d0;
+				if (rem < d0) break; /* don't let rem overflow */
+				if (t2l < d1) t2h--; t2l -= d1;
+				}
+#endif /* !BN_LLONG */
+			}
+#endif /* !BN_DIV3W */
+
+		l0=bn_mul_words(tmp->d,sdiv->d,div_n,q);
+		tmp->d[div_n]=l0;
+		wnum.d--;
+		/* ingore top values of the bignums just sub the two 
+		 * BN_ULONG arrays with bn_sub_words */
+		if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n+1))
+			{
+			/* Note: As we have considered only the leading
+			 * two BN_ULONGs in the calculation of q, sdiv * q
+			 * might be greater than wnum (but then (q-1) * sdiv
+			 * is less or equal than wnum)
+			 */
+			q--;
+			if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n))
+				/* we can't have an overflow here (assuming
+				 * that q != 0, but if q == 0 then tmp is
+				 * zero anyway) */
+				(*wnump)++;
+			}
+		/* store part of the result */
+		*resp = q;
+		}
+	bn_correct_top(snum);
+	if (rm != NULL)
+		{
+		/* Keep a copy of the neg flag in num because if rm==num
+		 * BN_rshift() will overwrite it.
+		 */
+		int neg = num->neg;
+		BN_rshift(rm,snum,norm_shift);
+		if (!BN_is_zero(rm))
+			rm->neg = neg;
+		bn_check_top(rm);
+		}
+	BN_CTX_end(ctx);
+	return(1);
+err:
+	bn_check_top(rm);
+	BN_CTX_end(ctx);
+	return(0);
+	}
+
+
+/* BN_div_no_branch is a special version of BN_div. It does not contain
+ * branches that may leak sensitive information.
+ */
+static int BN_div_no_branch(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, 
+	const BIGNUM *divisor, BN_CTX *ctx)
+	{
+	int norm_shift,i,loop;
+	BIGNUM *tmp,wnum,*snum,*sdiv,*res;
+	BN_ULONG *resp,*wnump;
+	BN_ULONG d0,d1;
+	int num_n,div_n;
+
+	bn_check_top(dv);
+	bn_check_top(rm);
+	/* bn_check_top(num); */ /* 'num' has been checked in BN_div() */
+	bn_check_top(divisor);
+
+	if (BN_is_zero(divisor))
+		{
+		BNerr(BN_F_BN_DIV_NO_BRANCH,BN_R_DIV_BY_ZERO);
+		return(0);
+		}
+
+	BN_CTX_start(ctx);
+	tmp=BN_CTX_get(ctx);
+	snum=BN_CTX_get(ctx);
+	sdiv=BN_CTX_get(ctx);
+	if (dv == NULL)
+		res=BN_CTX_get(ctx);
+	else	res=dv;
+	if (sdiv == NULL || res == NULL) goto err;
+
+	/* First we normalise the numbers */
+	norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
+	if (!(BN_lshift(sdiv,divisor,norm_shift))) goto err;
+	sdiv->neg=0;
+	norm_shift+=BN_BITS2;
+	if (!(BN_lshift(snum,num,norm_shift))) goto err;
+	snum->neg=0;
+
+	/* Since we don't know whether snum is larger than sdiv,
+	 * we pad snum with enough zeroes without changing its
+	 * value. 
+	 */
+	if (snum->top <= sdiv->top+1) 
+		{
+		if (bn_wexpand(snum, sdiv->top + 2) == NULL) goto err;
+		for (i = snum->top; i < sdiv->top + 2; i++) snum->d[i] = 0;
+		snum->top = sdiv->top + 2;
+		}
+	else
+		{
+		if (bn_wexpand(snum, snum->top + 1) == NULL) goto err;
+		snum->d[snum->top] = 0;
+		snum->top ++;
+		}
+
+	div_n=sdiv->top;
+	num_n=snum->top;
+	loop=num_n-div_n;
+	/* Lets setup a 'window' into snum
+	 * This is the part that corresponds to the current
+	 * 'area' being divided */
+	wnum.neg   = 0;
+	wnum.d     = &(snum->d[loop]);
+	wnum.top   = div_n;
+	/* only needed when BN_ucmp messes up the values between top and max */
+	wnum.dmax  = snum->dmax - loop; /* so we don't step out of bounds */
+
+	/* Get the top 2 words of sdiv */
+	/* div_n=sdiv->top; */
+	d0=sdiv->d[div_n-1];
+	d1=(div_n == 1)?0:sdiv->d[div_n-2];
+
+	/* pointer to the 'top' of snum */
+	wnump= &(snum->d[num_n-1]);
+
+	/* Setup to 'res' */
+	res->neg= (num->neg^divisor->neg);
+	if (!bn_wexpand(res,(loop+1))) goto err;
+	res->top=loop-1;
+	resp= &(res->d[loop-1]);
+
+	/* space for temp */
+	if (!bn_wexpand(tmp,(div_n+1))) goto err;
+
+	/* if res->top == 0 then clear the neg value otherwise decrease
+	 * the resp pointer */
+	if (res->top == 0)
+		res->neg = 0;
+	else
+		resp--;
+
+	for (i=0; i<loop-1; i++, wnump--, resp--)
+		{
+		BN_ULONG q,l0;
+		/* the first part of the loop uses the top two words of
+		 * snum and sdiv to calculate a BN_ULONG q such that
+		 * | wnum - sdiv * q | < sdiv */
+#if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM)
+		BN_ULONG bn_div_3_words(BN_ULONG*,BN_ULONG,BN_ULONG);
+		q=bn_div_3_words(wnump,d1,d0);
+#else
+		BN_ULONG n0,n1,rem=0;
+
+		n0=wnump[0];
+		n1=wnump[-1];
+		if (n0 == d0)
+			q=BN_MASK2;
+		else 			/* n0 < d0 */
+			{
+#ifdef BN_LLONG
+			BN_ULLONG t2;
+
+#if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
+			q=(BN_ULONG)(((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0);
+#else
+			q=bn_div_words(n0,n1,d0);
+#ifdef BN_DEBUG_LEVITTE
+			fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
+X) -> 0x%08X\n",
+				n0, n1, d0, q);
+#endif
+#endif
+
+#ifndef REMAINDER_IS_ALREADY_CALCULATED
+			/*
+			 * rem doesn't have to be BN_ULLONG. The least we
+			 * know it's less that d0, isn't it?
+			 */
+			rem=(n1-q*d0)&BN_MASK2;
+#endif
+			t2=(BN_ULLONG)d1*q;
+
+			for (;;)
+				{
+				if (t2 <= ((((BN_ULLONG)rem)<<BN_BITS2)|wnump[-2]))
+					break;
+				q--;
+				rem += d0;
+				if (rem < d0) break; /* don't let rem overflow */
+				t2 -= d1;
+				}
+#else /* !BN_LLONG */
+			BN_ULONG t2l,t2h;
+
+			q=bn_div_words(n0,n1,d0);
+#ifdef BN_DEBUG_LEVITTE
+			fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
+X) -> 0x%08X\n",
+				n0, n1, d0, q);
+#endif
+#ifndef REMAINDER_IS_ALREADY_CALCULATED
+			rem=(n1-q*d0)&BN_MASK2;
+#endif
+
+#if defined(BN_UMULT_LOHI)
+			BN_UMULT_LOHI(t2l,t2h,d1,q);
+#elif defined(BN_UMULT_HIGH)
+			t2l = d1 * q;
+			t2h = BN_UMULT_HIGH(d1,q);
+#else
+			{
+			BN_ULONG ql, qh;
+			t2l=LBITS(d1); t2h=HBITS(d1);
+			ql =LBITS(q);  qh =HBITS(q);
+			mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
+			}
+#endif
+
+			for (;;)
+				{
+				if ((t2h < rem) ||
+					((t2h == rem) && (t2l <= wnump[-2])))
+					break;
+				q--;
+				rem += d0;
+				if (rem < d0) break; /* don't let rem overflow */
+				if (t2l < d1) t2h--; t2l -= d1;
+				}
+#endif /* !BN_LLONG */
+			}
+#endif /* !BN_DIV3W */
+
+		l0=bn_mul_words(tmp->d,sdiv->d,div_n,q);
+		tmp->d[div_n]=l0;
+		wnum.d--;
+		/* ingore top values of the bignums just sub the two 
+		 * BN_ULONG arrays with bn_sub_words */
+		if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n+1))
+			{
+			/* Note: As we have considered only the leading
+			 * two BN_ULONGs in the calculation of q, sdiv * q
+			 * might be greater than wnum (but then (q-1) * sdiv
+			 * is less or equal than wnum)
+			 */
+			q--;
+			if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n))
+				/* we can't have an overflow here (assuming
+				 * that q != 0, but if q == 0 then tmp is
+				 * zero anyway) */
+				(*wnump)++;
+			}
+		/* store part of the result */
+		*resp = q;
+		}
+	bn_correct_top(snum);
+	if (rm != NULL)
+		{
+		/* Keep a copy of the neg flag in num because if rm==num
+		 * BN_rshift() will overwrite it.
+		 */
+		int neg = num->neg;
+		BN_rshift(rm,snum,norm_shift);
+		if (!BN_is_zero(rm))
+			rm->neg = neg;
+		bn_check_top(rm);
+		}
+	bn_correct_top(res);
+	BN_CTX_end(ctx);
+	return(1);
+err:
+	bn_check_top(rm);
+	BN_CTX_end(ctx);
+	return(0);
+	}
+
+#endif
diff --git a/openssl/crypto/bn/bn_err.c b/openssl/crypto/bn/bn_err.c
new file mode 100644
index 0000000..cfe2eb9
--- /dev/null
+++ b/openssl/crypto/bn/bn_err.c
@@ -0,0 +1,150 @@
+/* crypto/bn/bn_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_BN,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_BN,0,reason)
+
+static ERR_STRING_DATA BN_str_functs[]=
+	{
+{ERR_FUNC(BN_F_BNRAND),	"BNRAND"},
+{ERR_FUNC(BN_F_BN_BLINDING_CONVERT_EX),	"BN_BLINDING_convert_ex"},
+{ERR_FUNC(BN_F_BN_BLINDING_CREATE_PARAM),	"BN_BLINDING_create_param"},
+{ERR_FUNC(BN_F_BN_BLINDING_INVERT_EX),	"BN_BLINDING_invert_ex"},
+{ERR_FUNC(BN_F_BN_BLINDING_NEW),	"BN_BLINDING_new"},
+{ERR_FUNC(BN_F_BN_BLINDING_UPDATE),	"BN_BLINDING_update"},
+{ERR_FUNC(BN_F_BN_BN2DEC),	"BN_bn2dec"},
+{ERR_FUNC(BN_F_BN_BN2HEX),	"BN_bn2hex"},
+{ERR_FUNC(BN_F_BN_CTX_GET),	"BN_CTX_get"},
+{ERR_FUNC(BN_F_BN_CTX_NEW),	"BN_CTX_new"},
+{ERR_FUNC(BN_F_BN_CTX_START),	"BN_CTX_start"},
+{ERR_FUNC(BN_F_BN_DIV),	"BN_div"},
+{ERR_FUNC(BN_F_BN_DIV_NO_BRANCH),	"BN_div_no_branch"},
+{ERR_FUNC(BN_F_BN_DIV_RECP),	"BN_div_recp"},
+{ERR_FUNC(BN_F_BN_EXP),	"BN_exp"},
+{ERR_FUNC(BN_F_BN_EXPAND2),	"bn_expand2"},
+{ERR_FUNC(BN_F_BN_EXPAND_INTERNAL),	"BN_EXPAND_INTERNAL"},
+{ERR_FUNC(BN_F_BN_GF2M_MOD),	"BN_GF2m_mod"},
+{ERR_FUNC(BN_F_BN_GF2M_MOD_EXP),	"BN_GF2m_mod_exp"},
+{ERR_FUNC(BN_F_BN_GF2M_MOD_MUL),	"BN_GF2m_mod_mul"},
+{ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD),	"BN_GF2m_mod_solve_quad"},
+{ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR),	"BN_GF2m_mod_solve_quad_arr"},
+{ERR_FUNC(BN_F_BN_GF2M_MOD_SQR),	"BN_GF2m_mod_sqr"},
+{ERR_FUNC(BN_F_BN_GF2M_MOD_SQRT),	"BN_GF2m_mod_sqrt"},
+{ERR_FUNC(BN_F_BN_MOD_EXP2_MONT),	"BN_mod_exp2_mont"},
+{ERR_FUNC(BN_F_BN_MOD_EXP_MONT),	"BN_mod_exp_mont"},
+{ERR_FUNC(BN_F_BN_MOD_EXP_MONT_CONSTTIME),	"BN_mod_exp_mont_consttime"},
+{ERR_FUNC(BN_F_BN_MOD_EXP_MONT_WORD),	"BN_mod_exp_mont_word"},
+{ERR_FUNC(BN_F_BN_MOD_EXP_RECP),	"BN_mod_exp_recp"},
+{ERR_FUNC(BN_F_BN_MOD_EXP_SIMPLE),	"BN_mod_exp_simple"},
+{ERR_FUNC(BN_F_BN_MOD_INVERSE),	"BN_mod_inverse"},
+{ERR_FUNC(BN_F_BN_MOD_INVERSE_NO_BRANCH),	"BN_mod_inverse_no_branch"},
+{ERR_FUNC(BN_F_BN_MOD_LSHIFT_QUICK),	"BN_mod_lshift_quick"},
+{ERR_FUNC(BN_F_BN_MOD_MUL_RECIPROCAL),	"BN_mod_mul_reciprocal"},
+{ERR_FUNC(BN_F_BN_MOD_SQRT),	"BN_mod_sqrt"},
+{ERR_FUNC(BN_F_BN_MPI2BN),	"BN_mpi2bn"},
+{ERR_FUNC(BN_F_BN_NEW),	"BN_new"},
+{ERR_FUNC(BN_F_BN_RAND),	"BN_rand"},
+{ERR_FUNC(BN_F_BN_RAND_RANGE),	"BN_rand_range"},
+{ERR_FUNC(BN_F_BN_USUB),	"BN_usub"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA BN_str_reasons[]=
+	{
+{ERR_REASON(BN_R_ARG2_LT_ARG3)           ,"arg2 lt arg3"},
+{ERR_REASON(BN_R_BAD_RECIPROCAL)         ,"bad reciprocal"},
+{ERR_REASON(BN_R_BIGNUM_TOO_LONG)        ,"bignum too long"},
+{ERR_REASON(BN_R_CALLED_WITH_EVEN_MODULUS),"called with even modulus"},
+{ERR_REASON(BN_R_DIV_BY_ZERO)            ,"div by zero"},
+{ERR_REASON(BN_R_ENCODING_ERROR)         ,"encoding error"},
+{ERR_REASON(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA),"expand on static bignum data"},
+{ERR_REASON(BN_R_INPUT_NOT_REDUCED)      ,"input not reduced"},
+{ERR_REASON(BN_R_INVALID_LENGTH)         ,"invalid length"},
+{ERR_REASON(BN_R_INVALID_RANGE)          ,"invalid range"},
+{ERR_REASON(BN_R_NOT_A_SQUARE)           ,"not a square"},
+{ERR_REASON(BN_R_NOT_INITIALIZED)        ,"not initialized"},
+{ERR_REASON(BN_R_NO_INVERSE)             ,"no inverse"},
+{ERR_REASON(BN_R_NO_SOLUTION)            ,"no solution"},
+{ERR_REASON(BN_R_P_IS_NOT_PRIME)         ,"p is not prime"},
+{ERR_REASON(BN_R_TOO_MANY_ITERATIONS)    ,"too many iterations"},
+{ERR_REASON(BN_R_TOO_MANY_TEMPORARY_VARIABLES),"too many temporary variables"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_BN_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(BN_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,BN_str_functs);
+		ERR_load_strings(0,BN_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/bn/bn_exp.c b/openssl/crypto/bn/bn_exp.c
new file mode 100644
index 0000000..d9b6c73
--- /dev/null
+++ b/openssl/crypto/bn/bn_exp.c
@@ -0,0 +1,991 @@
+/* crypto/bn/bn_exp.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* maximum precomputation table size for *variable* sliding windows */
+#define TABLE_SIZE	32
+
+/* this one works - simple but works */
+int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+	{
+	int i,bits,ret=0;
+	BIGNUM *v,*rr;
+
+	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
+		{
+		/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+		BNerr(BN_F_BN_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return -1;
+		}
+
+	BN_CTX_start(ctx);
+	if ((r == a) || (r == p))
+		rr = BN_CTX_get(ctx);
+	else
+		rr = r;
+	v = BN_CTX_get(ctx);
+	if (rr == NULL || v == NULL) goto err;
+
+	if (BN_copy(v,a) == NULL) goto err;
+	bits=BN_num_bits(p);
+
+	if (BN_is_odd(p))
+		{ if (BN_copy(rr,a) == NULL) goto err; }
+	else	{ if (!BN_one(rr)) goto err; }
+
+	for (i=1; i<bits; i++)
+		{
+		if (!BN_sqr(v,v,ctx)) goto err;
+		if (BN_is_bit_set(p,i))
+			{
+			if (!BN_mul(rr,rr,v,ctx)) goto err;
+			}
+		}
+	ret=1;
+err:
+	if (r != rr) BN_copy(r,rr);
+	BN_CTX_end(ctx);
+	bn_check_top(r);
+	return(ret);
+	}
+
+
+int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+	       BN_CTX *ctx)
+	{
+	int ret;
+
+	bn_check_top(a);
+	bn_check_top(p);
+	bn_check_top(m);
+
+	/* For even modulus  m = 2^k*m_odd,  it might make sense to compute
+	 * a^p mod m_odd  and  a^p mod 2^k  separately (with Montgomery
+	 * exponentiation for the odd part), using appropriate exponent
+	 * reductions, and combine the results using the CRT.
+	 *
+	 * For now, we use Montgomery only if the modulus is odd; otherwise,
+	 * exponentiation using the reciprocal-based quick remaindering
+	 * algorithm is used.
+	 *
+	 * (Timing obtained with expspeed.c [computations  a^p mod m
+	 * where  a, p, m  are of the same length: 256, 512, 1024, 2048,
+	 * 4096, 8192 bits], compared to the running time of the
+	 * standard algorithm:
+	 *
+	 *   BN_mod_exp_mont   33 .. 40 %  [AMD K6-2, Linux, debug configuration]
+         *                     55 .. 77 %  [UltraSparc processor, but
+	 *                                  debug-solaris-sparcv8-gcc conf.]
+	 * 
+	 *   BN_mod_exp_recp   50 .. 70 %  [AMD K6-2, Linux, debug configuration]
+	 *                     62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc]
+	 *
+	 * On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont
+	 * at 2048 and more bits, but at 512 and 1024 bits, it was
+	 * slower even than the standard algorithm!
+	 *
+	 * "Real" timings [linux-elf, solaris-sparcv9-gcc configurations]
+	 * should be obtained when the new Montgomery reduction code
+	 * has been integrated into OpenSSL.)
+	 */
+
+#define MONT_MUL_MOD
+#define MONT_EXP_WORD
+#define RECP_MUL_MOD
+
+#ifdef MONT_MUL_MOD
+	/* I have finally been able to take out this pre-condition of
+	 * the top bit being set.  It was caused by an error in BN_div
+	 * with negatives.  There was also another problem when for a^b%m
+	 * a >= m.  eay 07-May-97 */
+/*	if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */
+
+	if (BN_is_odd(m))
+		{
+#  ifdef MONT_EXP_WORD
+		if (a->top == 1 && !a->neg && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0))
+			{
+			BN_ULONG A = a->d[0];
+			ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL);
+			}
+		else
+#  endif
+			ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL);
+		}
+	else
+#endif
+#ifdef RECP_MUL_MOD
+		{ ret=BN_mod_exp_recp(r,a,p,m,ctx); }
+#else
+		{ ret=BN_mod_exp_simple(r,a,p,m,ctx); }
+#endif
+
+	bn_check_top(r);
+	return(ret);
+	}
+
+
+int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		    const BIGNUM *m, BN_CTX *ctx)
+	{
+	int i,j,bits,ret=0,wstart,wend,window,wvalue;
+	int start=1;
+	BIGNUM *aa;
+	/* Table of variables obtained from 'ctx' */
+	BIGNUM *val[TABLE_SIZE];
+	BN_RECP_CTX recp;
+
+	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
+		{
+		/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+		BNerr(BN_F_BN_MOD_EXP_RECP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return -1;
+		}
+
+	bits=BN_num_bits(p);
+
+	if (bits == 0)
+		{
+		ret = BN_one(r);
+		return ret;
+		}
+
+	BN_CTX_start(ctx);
+	aa = BN_CTX_get(ctx);
+	val[0] = BN_CTX_get(ctx);
+	if(!aa || !val[0]) goto err;
+
+	BN_RECP_CTX_init(&recp);
+	if (m->neg)
+		{
+		/* ignore sign of 'm' */
+		if (!BN_copy(aa, m)) goto err;
+		aa->neg = 0;
+		if (BN_RECP_CTX_set(&recp,aa,ctx) <= 0) goto err;
+		}
+	else
+		{
+		if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;
+		}
+
+	if (!BN_nnmod(val[0],a,m,ctx)) goto err;		/* 1 */
+	if (BN_is_zero(val[0]))
+		{
+		BN_zero(r);
+		ret = 1;
+		goto err;
+		}
+
+	window = BN_window_bits_for_exponent_size(bits);
+	if (window > 1)
+		{
+		if (!BN_mod_mul_reciprocal(aa,val[0],val[0],&recp,ctx))
+			goto err;				/* 2 */
+		j=1<<(window-1);
+		for (i=1; i<j; i++)
+			{
+			if(((val[i] = BN_CTX_get(ctx)) == NULL) ||
+					!BN_mod_mul_reciprocal(val[i],val[i-1],
+						aa,&recp,ctx))
+				goto err;
+			}
+		}
+		
+	start=1;	/* This is used to avoid multiplication etc
+			 * when there is only the value '1' in the
+			 * buffer. */
+	wvalue=0;	/* The 'value' of the window */
+	wstart=bits-1;	/* The top bit of the window */
+	wend=0;		/* The bottom bit of the window */
+
+	if (!BN_one(r)) goto err;
+
+	for (;;)
+		{
+		if (BN_is_bit_set(p,wstart) == 0)
+			{
+			if (!start)
+				if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
+				goto err;
+			if (wstart == 0) break;
+			wstart--;
+			continue;
+			}
+		/* We now have wstart on a 'set' bit, we now need to work out
+		 * how bit a window to do.  To do this we need to scan
+		 * forward until the last set bit before the end of the
+		 * window */
+		j=wstart;
+		wvalue=1;
+		wend=0;
+		for (i=1; i<window; i++)
+			{
+			if (wstart-i < 0) break;
+			if (BN_is_bit_set(p,wstart-i))
+				{
+				wvalue<<=(i-wend);
+				wvalue|=1;
+				wend=i;
+				}
+			}
+
+		/* wend is the size of the current window */
+		j=wend+1;
+		/* add the 'bytes above' */
+		if (!start)
+			for (i=0; i<j; i++)
+				{
+				if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
+					goto err;
+				}
+		
+		/* wvalue will be an odd number < 2^window */
+		if (!BN_mod_mul_reciprocal(r,r,val[wvalue>>1],&recp,ctx))
+			goto err;
+
+		/* move the 'window' down further */
+		wstart-=wend+1;
+		wvalue=0;
+		start=0;
+		if (wstart < 0) break;
+		}
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	BN_RECP_CTX_free(&recp);
+	bn_check_top(r);
+	return(ret);
+	}
+
+
+int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+		    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+	{
+	int i,j,bits,ret=0,wstart,wend,window,wvalue;
+	int start=1;
+	BIGNUM *d,*r;
+	const BIGNUM *aa;
+	/* Table of variables obtained from 'ctx' */
+	BIGNUM *val[TABLE_SIZE];
+	BN_MONT_CTX *mont=NULL;
+
+	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
+		{
+		return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
+		}
+
+	bn_check_top(a);
+	bn_check_top(p);
+	bn_check_top(m);
+
+	if (!BN_is_odd(m))
+		{
+		BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
+		return(0);
+		}
+	bits=BN_num_bits(p);
+	if (bits == 0)
+		{
+		ret = BN_one(rr);
+		return ret;
+		}
+
+	BN_CTX_start(ctx);
+	d = BN_CTX_get(ctx);
+	r = BN_CTX_get(ctx);
+	val[0] = BN_CTX_get(ctx);
+	if (!d || !r || !val[0]) goto err;
+
+	/* If this is not done, things will break in the montgomery
+	 * part */
+
+	if (in_mont != NULL)
+		mont=in_mont;
+	else
+		{
+		if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
+		if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
+		}
+
+	if (a->neg || BN_ucmp(a,m) >= 0)
+		{
+		if (!BN_nnmod(val[0],a,m,ctx))
+			goto err;
+		aa= val[0];
+		}
+	else
+		aa=a;
+	if (BN_is_zero(aa))
+		{
+		BN_zero(rr);
+		ret = 1;
+		goto err;
+		}
+	if (!BN_to_montgomery(val[0],aa,mont,ctx)) goto err; /* 1 */
+
+	window = BN_window_bits_for_exponent_size(bits);
+	if (window > 1)
+		{
+		if (!BN_mod_mul_montgomery(d,val[0],val[0],mont,ctx)) goto err; /* 2 */
+		j=1<<(window-1);
+		for (i=1; i<j; i++)
+			{
+			if(((val[i] = BN_CTX_get(ctx)) == NULL) ||
+					!BN_mod_mul_montgomery(val[i],val[i-1],
+						d,mont,ctx))
+				goto err;
+			}
+		}
+
+	start=1;	/* This is used to avoid multiplication etc
+			 * when there is only the value '1' in the
+			 * buffer. */
+	wvalue=0;	/* The 'value' of the window */
+	wstart=bits-1;	/* The top bit of the window */
+	wend=0;		/* The bottom bit of the window */
+
+	if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
+	for (;;)
+		{
+		if (BN_is_bit_set(p,wstart) == 0)
+			{
+			if (!start)
+				{
+				if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
+				goto err;
+				}
+			if (wstart == 0) break;
+			wstart--;
+			continue;
+			}
+		/* We now have wstart on a 'set' bit, we now need to work out
+		 * how bit a window to do.  To do this we need to scan
+		 * forward until the last set bit before the end of the
+		 * window */
+		j=wstart;
+		wvalue=1;
+		wend=0;
+		for (i=1; i<window; i++)
+			{
+			if (wstart-i < 0) break;
+			if (BN_is_bit_set(p,wstart-i))
+				{
+				wvalue<<=(i-wend);
+				wvalue|=1;
+				wend=i;
+				}
+			}
+
+		/* wend is the size of the current window */
+		j=wend+1;
+		/* add the 'bytes above' */
+		if (!start)
+			for (i=0; i<j; i++)
+				{
+				if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
+					goto err;
+				}
+		
+		/* wvalue will be an odd number < 2^window */
+		if (!BN_mod_mul_montgomery(r,r,val[wvalue>>1],mont,ctx))
+			goto err;
+
+		/* move the 'window' down further */
+		wstart-=wend+1;
+		wvalue=0;
+		start=0;
+		if (wstart < 0) break;
+		}
+	if (!BN_from_montgomery(rr,r,mont,ctx)) goto err;
+	ret=1;
+err:
+	if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
+	BN_CTX_end(ctx);
+	bn_check_top(rr);
+	return(ret);
+	}
+
+
+/* BN_mod_exp_mont_consttime() stores the precomputed powers in a specific layout
+ * so that accessing any of these table values shows the same access pattern as far
+ * as cache lines are concerned.  The following functions are used to transfer a BIGNUM
+ * from/to that table. */
+
+static int MOD_EXP_CTIME_COPY_TO_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx, int width)
+	{
+	size_t i, j;
+
+	if (bn_wexpand(b, top) == NULL)
+		return 0;
+	while (b->top < top)
+		{
+		b->d[b->top++] = 0;
+		}
+	
+	for (i = 0, j=idx; i < top * sizeof b->d[0]; i++, j+=width)
+		{
+		buf[j] = ((unsigned char*)b->d)[i];
+		}
+
+	bn_correct_top(b);
+	return 1;
+	}
+
+static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx, int width)
+	{
+	size_t i, j;
+
+	if (bn_wexpand(b, top) == NULL)
+		return 0;
+
+	for (i=0, j=idx; i < top * sizeof b->d[0]; i++, j+=width)
+		{
+		((unsigned char*)b->d)[i] = buf[j];
+		}
+
+	b->top = top;
+	bn_correct_top(b);
+	return 1;
+	}	
+
+/* Given a pointer value, compute the next address that is a cache line multiple. */
+#define MOD_EXP_CTIME_ALIGN(x_) \
+	((unsigned char*)(x_) + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - (((BN_ULONG)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK))))
+
+/* This variant of BN_mod_exp_mont() uses fixed windows and the special
+ * precomputation memory layout to limit data-dependency to a minimum
+ * to protect secret exponents (cf. the hyper-threading timing attacks
+ * pointed out by Colin Percival,
+ * http://www.daemonology.net/hyperthreading-considered-harmful/)
+ */
+int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+		    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+	{
+	int i,bits,ret=0,idx,window,wvalue;
+	int top;
+ 	BIGNUM *r;
+	const BIGNUM *aa;
+	BN_MONT_CTX *mont=NULL;
+
+	int numPowers;
+	unsigned char *powerbufFree=NULL;
+	int powerbufLen = 0;
+	unsigned char *powerbuf=NULL;
+	BIGNUM *computeTemp=NULL, *am=NULL;
+
+	bn_check_top(a);
+	bn_check_top(p);
+	bn_check_top(m);
+
+	top = m->top;
+
+	if (!(m->d[0] & 1))
+		{
+		BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME,BN_R_CALLED_WITH_EVEN_MODULUS);
+		return(0);
+		}
+	bits=BN_num_bits(p);
+	if (bits == 0)
+		{
+		ret = BN_one(rr);
+		return ret;
+		}
+
+ 	/* Initialize BIGNUM context and allocate intermediate result */
+	BN_CTX_start(ctx);
+	r = BN_CTX_get(ctx);
+	if (r == NULL) goto err;
+
+	/* Allocate a montgomery context if it was not supplied by the caller.
+	 * If this is not done, things will break in the montgomery part.
+ 	 */
+	if (in_mont != NULL)
+		mont=in_mont;
+	else
+		{
+		if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
+		if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
+		}
+
+	/* Get the window size to use with size of p. */
+	window = BN_window_bits_for_ctime_exponent_size(bits);
+
+	/* Allocate a buffer large enough to hold all of the pre-computed
+	 * powers of a.
+	 */
+	numPowers = 1 << window;
+	powerbufLen = sizeof(m->d[0])*top*numPowers;
+	if ((powerbufFree=(unsigned char*)OPENSSL_malloc(powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL)
+		goto err;
+		
+	powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree);
+	memset(powerbuf, 0, powerbufLen);
+
+ 	/* Initialize the intermediate result. Do this early to save double conversion,
+	 * once each for a^0 and intermediate result.
+	 */
+ 	if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
+	if (!MOD_EXP_CTIME_COPY_TO_PREBUF(r, top, powerbuf, 0, numPowers)) goto err;
+
+	/* Initialize computeTemp as a^1 with montgomery precalcs */
+	computeTemp = BN_CTX_get(ctx);
+	am = BN_CTX_get(ctx);
+	if (computeTemp==NULL || am==NULL) goto err;
+
+	if (a->neg || BN_ucmp(a,m) >= 0)
+		{
+		if (!BN_mod(am,a,m,ctx))
+			goto err;
+		aa= am;
+		}
+	else
+		aa=a;
+	if (!BN_to_montgomery(am,aa,mont,ctx)) goto err;
+	if (!BN_copy(computeTemp, am)) goto err;
+	if (!MOD_EXP_CTIME_COPY_TO_PREBUF(am, top, powerbuf, 1, numPowers)) goto err;
+
+	/* If the window size is greater than 1, then calculate
+	 * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1)
+	 * (even powers could instead be computed as (a^(i/2))^2
+	 * to use the slight performance advantage of sqr over mul).
+	 */
+	if (window > 1)
+		{
+		for (i=2; i<numPowers; i++)
+			{
+			/* Calculate a^i = a^(i-1) * a */
+			if (!BN_mod_mul_montgomery(computeTemp,am,computeTemp,mont,ctx))
+				goto err;
+			if (!MOD_EXP_CTIME_COPY_TO_PREBUF(computeTemp, top, powerbuf, i, numPowers)) goto err;
+			}
+		}
+
+ 	/* Adjust the number of bits up to a multiple of the window size.
+ 	 * If the exponent length is not a multiple of the window size, then
+ 	 * this pads the most significant bits with zeros to normalize the
+ 	 * scanning loop to there's no special cases.
+ 	 *
+ 	 * * NOTE: Making the window size a power of two less than the native
+	 * * word size ensures that the padded bits won't go past the last
+ 	 * * word in the internal BIGNUM structure. Going past the end will
+ 	 * * still produce the correct result, but causes a different branch
+ 	 * * to be taken in the BN_is_bit_set function.
+ 	 */
+ 	bits = ((bits+window-1)/window)*window;
+ 	idx=bits-1;	/* The top bit of the window */
+
+ 	/* Scan the exponent one window at a time starting from the most
+ 	 * significant bits.
+ 	 */
+ 	while (idx >= 0)
+  		{
+ 		wvalue=0; /* The 'value' of the window */
+ 		
+ 		/* Scan the window, squaring the result as we go */
+ 		for (i=0; i<window; i++,idx--)
+ 			{
+			if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))	goto err;
+			wvalue = (wvalue<<1)+BN_is_bit_set(p,idx);
+  			}
+ 		
+		/* Fetch the appropriate pre-computed value from the pre-buf */
+		if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(computeTemp, top, powerbuf, wvalue, numPowers)) goto err;
+
+ 		/* Multiply the result into the intermediate result */
+ 		if (!BN_mod_mul_montgomery(r,r,computeTemp,mont,ctx)) goto err;
+  		}
+
+ 	/* Convert the final result from montgomery to standard format */
+	if (!BN_from_montgomery(rr,r,mont,ctx)) goto err;
+	ret=1;
+err:
+	if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
+	if (powerbuf!=NULL)
+		{
+		OPENSSL_cleanse(powerbuf,powerbufLen);
+		OPENSSL_free(powerbufFree);
+		}
+ 	if (am!=NULL) BN_clear(am);
+ 	if (computeTemp!=NULL) BN_clear(computeTemp);
+	BN_CTX_end(ctx);
+	return(ret);
+	}
+
+int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
+                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+	{
+	BN_MONT_CTX *mont = NULL;
+	int b, bits, ret=0;
+	int r_is_one;
+	BN_ULONG w, next_w;
+	BIGNUM *d, *r, *t;
+	BIGNUM *swap_tmp;
+#define BN_MOD_MUL_WORD(r, w, m) \
+		(BN_mul_word(r, (w)) && \
+		(/* BN_ucmp(r, (m)) < 0 ? 1 :*/  \
+			(BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1))))
+		/* BN_MOD_MUL_WORD is only used with 'w' large,
+		 * so the BN_ucmp test is probably more overhead
+		 * than always using BN_mod (which uses BN_copy if
+		 * a similar test returns true). */
+		/* We can use BN_mod and do not need BN_nnmod because our
+		 * accumulator is never negative (the result of BN_mod does
+		 * not depend on the sign of the modulus).
+		 */
+#define BN_TO_MONTGOMERY_WORD(r, w, mont) \
+		(BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
+
+	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
+		{
+		/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+		BNerr(BN_F_BN_MOD_EXP_MONT_WORD,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return -1;
+		}
+
+	bn_check_top(p);
+	bn_check_top(m);
+
+	if (!BN_is_odd(m))
+		{
+		BNerr(BN_F_BN_MOD_EXP_MONT_WORD,BN_R_CALLED_WITH_EVEN_MODULUS);
+		return(0);
+		}
+	if (m->top == 1)
+		a %= m->d[0]; /* make sure that 'a' is reduced */
+
+	bits = BN_num_bits(p);
+	if (bits == 0)
+		{
+		ret = BN_one(rr);
+		return ret;
+		}
+	if (a == 0)
+		{
+		BN_zero(rr);
+		ret = 1;
+		return ret;
+		}
+
+	BN_CTX_start(ctx);
+	d = BN_CTX_get(ctx);
+	r = BN_CTX_get(ctx);
+	t = BN_CTX_get(ctx);
+	if (d == NULL || r == NULL || t == NULL) goto err;
+
+	if (in_mont != NULL)
+		mont=in_mont;
+	else
+		{
+		if ((mont = BN_MONT_CTX_new()) == NULL) goto err;
+		if (!BN_MONT_CTX_set(mont, m, ctx)) goto err;
+		}
+
+	r_is_one = 1; /* except for Montgomery factor */
+
+	/* bits-1 >= 0 */
+
+	/* The result is accumulated in the product r*w. */
+	w = a; /* bit 'bits-1' of 'p' is always set */
+	for (b = bits-2; b >= 0; b--)
+		{
+		/* First, square r*w. */
+		next_w = w*w;
+		if ((next_w/w) != w) /* overflow */
+			{
+			if (r_is_one)
+				{
+				if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
+				r_is_one = 0;
+				}
+			else
+				{
+				if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
+				}
+			next_w = 1;
+			}
+		w = next_w;
+		if (!r_is_one)
+			{
+			if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) goto err;
+			}
+
+		/* Second, multiply r*w by 'a' if exponent bit is set. */
+		if (BN_is_bit_set(p, b))
+			{
+			next_w = w*a;
+			if ((next_w/a) != w) /* overflow */
+				{
+				if (r_is_one)
+					{
+					if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
+					r_is_one = 0;
+					}
+				else
+					{
+					if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
+					}
+				next_w = a;
+				}
+			w = next_w;
+			}
+		}
+
+	/* Finally, set r:=r*w. */
+	if (w != 1)
+		{
+		if (r_is_one)
+			{
+			if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
+			r_is_one = 0;
+			}
+		else
+			{
+			if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
+			}
+		}
+
+	if (r_is_one) /* can happen only if a == 1*/
+		{
+		if (!BN_one(rr)) goto err;
+		}
+	else
+		{
+		if (!BN_from_montgomery(rr, r, mont, ctx)) goto err;
+		}
+	ret = 1;
+err:
+	if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
+	BN_CTX_end(ctx);
+	bn_check_top(rr);
+	return(ret);
+	}
+
+
+/* The old fallback, simple version :-) */
+int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx)
+	{
+	int i,j,bits,ret=0,wstart,wend,window,wvalue;
+	int start=1;
+	BIGNUM *d;
+	/* Table of variables obtained from 'ctx' */
+	BIGNUM *val[TABLE_SIZE];
+
+	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
+		{
+		/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+		BNerr(BN_F_BN_MOD_EXP_SIMPLE,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return -1;
+		}
+
+	bits=BN_num_bits(p);
+
+	if (bits == 0)
+		{
+		ret = BN_one(r);
+		return ret;
+		}
+
+	BN_CTX_start(ctx);
+	d = BN_CTX_get(ctx);
+	val[0] = BN_CTX_get(ctx);
+	if(!d || !val[0]) goto err;
+
+	if (!BN_nnmod(val[0],a,m,ctx)) goto err;		/* 1 */
+	if (BN_is_zero(val[0]))
+		{
+		BN_zero(r);
+		ret = 1;
+		goto err;
+		}
+
+	window = BN_window_bits_for_exponent_size(bits);
+	if (window > 1)
+		{
+		if (!BN_mod_mul(d,val[0],val[0],m,ctx))
+			goto err;				/* 2 */
+		j=1<<(window-1);
+		for (i=1; i<j; i++)
+			{
+			if(((val[i] = BN_CTX_get(ctx)) == NULL) ||
+					!BN_mod_mul(val[i],val[i-1],d,m,ctx))
+				goto err;
+			}
+		}
+
+	start=1;	/* This is used to avoid multiplication etc
+			 * when there is only the value '1' in the
+			 * buffer. */
+	wvalue=0;	/* The 'value' of the window */
+	wstart=bits-1;	/* The top bit of the window */
+	wend=0;		/* The bottom bit of the window */
+
+	if (!BN_one(r)) goto err;
+
+	for (;;)
+		{
+		if (BN_is_bit_set(p,wstart) == 0)
+			{
+			if (!start)
+				if (!BN_mod_mul(r,r,r,m,ctx))
+				goto err;
+			if (wstart == 0) break;
+			wstart--;
+			continue;
+			}
+		/* We now have wstart on a 'set' bit, we now need to work out
+		 * how bit a window to do.  To do this we need to scan
+		 * forward until the last set bit before the end of the
+		 * window */
+		j=wstart;
+		wvalue=1;
+		wend=0;
+		for (i=1; i<window; i++)
+			{
+			if (wstart-i < 0) break;
+			if (BN_is_bit_set(p,wstart-i))
+				{
+				wvalue<<=(i-wend);
+				wvalue|=1;
+				wend=i;
+				}
+			}
+
+		/* wend is the size of the current window */
+		j=wend+1;
+		/* add the 'bytes above' */
+		if (!start)
+			for (i=0; i<j; i++)
+				{
+				if (!BN_mod_mul(r,r,r,m,ctx))
+					goto err;
+				}
+		
+		/* wvalue will be an odd number < 2^window */
+		if (!BN_mod_mul(r,r,val[wvalue>>1],m,ctx))
+			goto err;
+
+		/* move the 'window' down further */
+		wstart-=wend+1;
+		wvalue=0;
+		start=0;
+		if (wstart < 0) break;
+		}
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	bn_check_top(r);
+	return(ret);
+	}
+
diff --git a/openssl/crypto/bn/bn_exp2.c b/openssl/crypto/bn/bn_exp2.c
new file mode 100644
index 0000000..bd0c34b
--- /dev/null
+++ b/openssl/crypto/bn/bn_exp2.c
@@ -0,0 +1,312 @@
+/* crypto/bn/bn_exp2.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#define TABLE_SIZE	32
+
+int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
+	const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
+	BN_CTX *ctx, BN_MONT_CTX *in_mont)
+	{
+	int i,j,bits,b,bits1,bits2,ret=0,wpos1,wpos2,window1,window2,wvalue1,wvalue2;
+	int r_is_one=1;
+	BIGNUM *d,*r;
+	const BIGNUM *a_mod_m;
+	/* Tables of variables obtained from 'ctx' */
+	BIGNUM *val1[TABLE_SIZE], *val2[TABLE_SIZE];
+	BN_MONT_CTX *mont=NULL;
+
+	bn_check_top(a1);
+	bn_check_top(p1);
+	bn_check_top(a2);
+	bn_check_top(p2);
+	bn_check_top(m);
+
+	if (!(m->d[0] & 1))
+		{
+		BNerr(BN_F_BN_MOD_EXP2_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
+		return(0);
+		}
+	bits1=BN_num_bits(p1);
+	bits2=BN_num_bits(p2);
+	if ((bits1 == 0) && (bits2 == 0))
+		{
+		ret = BN_one(rr);
+		return ret;
+		}
+	
+	bits=(bits1 > bits2)?bits1:bits2;
+
+	BN_CTX_start(ctx);
+	d = BN_CTX_get(ctx);
+	r = BN_CTX_get(ctx);
+	val1[0] = BN_CTX_get(ctx);
+	val2[0] = BN_CTX_get(ctx);
+	if(!d || !r || !val1[0] || !val2[0]) goto err;
+
+	if (in_mont != NULL)
+		mont=in_mont;
+	else
+		{
+		if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
+		if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
+		}
+
+	window1 = BN_window_bits_for_exponent_size(bits1);
+	window2 = BN_window_bits_for_exponent_size(bits2);
+
+	/*
+	 * Build table for a1:   val1[i] := a1^(2*i + 1) mod m  for i = 0 .. 2^(window1-1)
+	 */
+	if (a1->neg || BN_ucmp(a1,m) >= 0)
+		{
+		if (!BN_mod(val1[0],a1,m,ctx))
+			goto err;
+		a_mod_m = val1[0];
+		}
+	else
+		a_mod_m = a1;
+	if (BN_is_zero(a_mod_m))
+		{
+		BN_zero(rr);
+		ret = 1;
+		goto err;
+		}
+
+	if (!BN_to_montgomery(val1[0],a_mod_m,mont,ctx)) goto err;
+	if (window1 > 1)
+		{
+		if (!BN_mod_mul_montgomery(d,val1[0],val1[0],mont,ctx)) goto err;
+
+		j=1<<(window1-1);
+		for (i=1; i<j; i++)
+			{
+			if(((val1[i] = BN_CTX_get(ctx)) == NULL) ||
+					!BN_mod_mul_montgomery(val1[i],val1[i-1],
+						d,mont,ctx))
+				goto err;
+			}
+		}
+
+
+	/*
+	 * Build table for a2:   val2[i] := a2^(2*i + 1) mod m  for i = 0 .. 2^(window2-1)
+	 */
+	if (a2->neg || BN_ucmp(a2,m) >= 0)
+		{
+		if (!BN_mod(val2[0],a2,m,ctx))
+			goto err;
+		a_mod_m = val2[0];
+		}
+	else
+		a_mod_m = a2;
+	if (BN_is_zero(a_mod_m))
+		{
+		BN_zero(rr);
+		ret = 1;
+		goto err;
+		}
+	if (!BN_to_montgomery(val2[0],a_mod_m,mont,ctx)) goto err;
+	if (window2 > 1)
+		{
+		if (!BN_mod_mul_montgomery(d,val2[0],val2[0],mont,ctx)) goto err;
+
+		j=1<<(window2-1);
+		for (i=1; i<j; i++)
+			{
+			if(((val2[i] = BN_CTX_get(ctx)) == NULL) ||
+					!BN_mod_mul_montgomery(val2[i],val2[i-1],
+						d,mont,ctx))
+				goto err;
+			}
+		}
+
+
+	/* Now compute the power product, using independent windows. */
+	r_is_one=1;
+	wvalue1=0;  /* The 'value' of the first window */
+	wvalue2=0;  /* The 'value' of the second window */
+	wpos1=0;    /* If wvalue1 > 0, the bottom bit of the first window */
+	wpos2=0;    /* If wvalue2 > 0, the bottom bit of the second window */
+
+	if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
+	for (b=bits-1; b>=0; b--)
+		{
+		if (!r_is_one)
+			{
+			if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
+				goto err;
+			}
+		
+		if (!wvalue1)
+			if (BN_is_bit_set(p1, b))
+				{
+				/* consider bits b-window1+1 .. b for this window */
+				i = b-window1+1;
+				while (!BN_is_bit_set(p1, i)) /* works for i<0 */
+					i++;
+				wpos1 = i;
+				wvalue1 = 1;
+				for (i = b-1; i >= wpos1; i--)
+					{
+					wvalue1 <<= 1;
+					if (BN_is_bit_set(p1, i))
+						wvalue1++;
+					}
+				}
+		
+		if (!wvalue2)
+			if (BN_is_bit_set(p2, b))
+				{
+				/* consider bits b-window2+1 .. b for this window */
+				i = b-window2+1;
+				while (!BN_is_bit_set(p2, i))
+					i++;
+				wpos2 = i;
+				wvalue2 = 1;
+				for (i = b-1; i >= wpos2; i--)
+					{
+					wvalue2 <<= 1;
+					if (BN_is_bit_set(p2, i))
+						wvalue2++;
+					}
+				}
+
+		if (wvalue1 && b == wpos1)
+			{
+			/* wvalue1 is odd and < 2^window1 */
+			if (!BN_mod_mul_montgomery(r,r,val1[wvalue1>>1],mont,ctx))
+				goto err;
+			wvalue1 = 0;
+			r_is_one = 0;
+			}
+		
+		if (wvalue2 && b == wpos2)
+			{
+			/* wvalue2 is odd and < 2^window2 */
+			if (!BN_mod_mul_montgomery(r,r,val2[wvalue2>>1],mont,ctx))
+				goto err;
+			wvalue2 = 0;
+			r_is_one = 0;
+			}
+		}
+	if (!BN_from_montgomery(rr,r,mont,ctx))
+		goto err;
+	ret=1;
+err:
+	if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
+	BN_CTX_end(ctx);
+	bn_check_top(rr);
+	return(ret);
+	}
diff --git a/openssl/crypto/bn/bn_gcd.c b/openssl/crypto/bn/bn_gcd.c
new file mode 100644
index 0000000..4a35211
--- /dev/null
+++ b/openssl/crypto/bn/bn_gcd.c
@@ -0,0 +1,654 @@
+/* crypto/bn/bn_gcd.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+static BIGNUM *euclid(BIGNUM *a, BIGNUM *b);
+
+int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
+	{
+	BIGNUM *a,*b,*t;
+	int ret=0;
+
+	bn_check_top(in_a);
+	bn_check_top(in_b);
+
+	BN_CTX_start(ctx);
+	a = BN_CTX_get(ctx);
+	b = BN_CTX_get(ctx);
+	if (a == NULL || b == NULL) goto err;
+
+	if (BN_copy(a,in_a) == NULL) goto err;
+	if (BN_copy(b,in_b) == NULL) goto err;
+	a->neg = 0;
+	b->neg = 0;
+
+	if (BN_cmp(a,b) < 0) { t=a; a=b; b=t; }
+	t=euclid(a,b);
+	if (t == NULL) goto err;
+
+	if (BN_copy(r,t) == NULL) goto err;
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	bn_check_top(r);
+	return(ret);
+	}
+
+static BIGNUM *euclid(BIGNUM *a, BIGNUM *b)
+	{
+	BIGNUM *t;
+	int shifts=0;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	/* 0 <= b <= a */
+	while (!BN_is_zero(b))
+		{
+		/* 0 < b <= a */
+
+		if (BN_is_odd(a))
+			{
+			if (BN_is_odd(b))
+				{
+				if (!BN_sub(a,a,b)) goto err;
+				if (!BN_rshift1(a,a)) goto err;
+				if (BN_cmp(a,b) < 0)
+					{ t=a; a=b; b=t; }
+				}
+			else		/* a odd - b even */
+				{
+				if (!BN_rshift1(b,b)) goto err;
+				if (BN_cmp(a,b) < 0)
+					{ t=a; a=b; b=t; }
+				}
+			}
+		else			/* a is even */
+			{
+			if (BN_is_odd(b))
+				{
+				if (!BN_rshift1(a,a)) goto err;
+				if (BN_cmp(a,b) < 0)
+					{ t=a; a=b; b=t; }
+				}
+			else		/* a even - b even */
+				{
+				if (!BN_rshift1(a,a)) goto err;
+				if (!BN_rshift1(b,b)) goto err;
+				shifts++;
+				}
+			}
+		/* 0 <= b <= a */
+		}
+
+	if (shifts)
+		{
+		if (!BN_lshift(a,a,shifts)) goto err;
+		}
+	bn_check_top(a);
+	return(a);
+err:
+	return(NULL);
+	}
+
+
+/* solves ax == 1 (mod n) */
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
+        const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
+BIGNUM *BN_mod_inverse(BIGNUM *in,
+	const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
+	{
+	BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL;
+	BIGNUM *ret=NULL;
+	int sign;
+
+	if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0))
+		{
+		return BN_mod_inverse_no_branch(in, a, n, ctx);
+		}
+
+	bn_check_top(a);
+	bn_check_top(n);
+
+	BN_CTX_start(ctx);
+	A = BN_CTX_get(ctx);
+	B = BN_CTX_get(ctx);
+	X = BN_CTX_get(ctx);
+	D = BN_CTX_get(ctx);
+	M = BN_CTX_get(ctx);
+	Y = BN_CTX_get(ctx);
+	T = BN_CTX_get(ctx);
+	if (T == NULL) goto err;
+
+	if (in == NULL)
+		R=BN_new();
+	else
+		R=in;
+	if (R == NULL) goto err;
+
+	BN_one(X);
+	BN_zero(Y);
+	if (BN_copy(B,a) == NULL) goto err;
+	if (BN_copy(A,n) == NULL) goto err;
+	A->neg = 0;
+	if (B->neg || (BN_ucmp(B, A) >= 0))
+		{
+		if (!BN_nnmod(B, B, A, ctx)) goto err;
+		}
+	sign = -1;
+	/* From  B = a mod |n|,  A = |n|  it follows that
+	 *
+	 *      0 <= B < A,
+	 *     -sign*X*a  ==  B   (mod |n|),
+	 *      sign*Y*a  ==  A   (mod |n|).
+	 */
+
+	if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048)))
+		{
+		/* Binary inversion algorithm; requires odd modulus.
+		 * This is faster than the general algorithm if the modulus
+		 * is sufficiently small (about 400 .. 500 bits on 32-bit
+		 * sytems, but much more on 64-bit systems) */
+		int shift;
+		
+		while (!BN_is_zero(B))
+			{
+			/*
+			 *      0 < B < |n|,
+			 *      0 < A <= |n|,
+			 * (1) -sign*X*a  ==  B   (mod |n|),
+			 * (2)  sign*Y*a  ==  A   (mod |n|)
+			 */
+
+			/* Now divide  B  by the maximum possible power of two in the integers,
+			 * and divide  X  by the same value mod |n|.
+			 * When we're done, (1) still holds. */
+			shift = 0;
+			while (!BN_is_bit_set(B, shift)) /* note that 0 < B */
+				{
+				shift++;
+				
+				if (BN_is_odd(X))
+					{
+					if (!BN_uadd(X, X, n)) goto err;
+					}
+				/* now X is even, so we can easily divide it by two */
+				if (!BN_rshift1(X, X)) goto err;
+				}
+			if (shift > 0)
+				{
+				if (!BN_rshift(B, B, shift)) goto err;
+				}
+
+
+			/* Same for  A  and  Y.  Afterwards, (2) still holds. */
+			shift = 0;
+			while (!BN_is_bit_set(A, shift)) /* note that 0 < A */
+				{
+				shift++;
+				
+				if (BN_is_odd(Y))
+					{
+					if (!BN_uadd(Y, Y, n)) goto err;
+					}
+				/* now Y is even */
+				if (!BN_rshift1(Y, Y)) goto err;
+				}
+			if (shift > 0)
+				{
+				if (!BN_rshift(A, A, shift)) goto err;
+				}
+
+			
+			/* We still have (1) and (2).
+			 * Both  A  and  B  are odd.
+			 * The following computations ensure that
+			 *
+			 *     0 <= B < |n|,
+			 *      0 < A < |n|,
+			 * (1) -sign*X*a  ==  B   (mod |n|),
+			 * (2)  sign*Y*a  ==  A   (mod |n|),
+			 *
+			 * and that either  A  or  B  is even in the next iteration.
+			 */
+			if (BN_ucmp(B, A) >= 0)
+				{
+				/* -sign*(X + Y)*a == B - A  (mod |n|) */
+				if (!BN_uadd(X, X, Y)) goto err;
+				/* NB: we could use BN_mod_add_quick(X, X, Y, n), but that
+				 * actually makes the algorithm slower */
+				if (!BN_usub(B, B, A)) goto err;
+				}
+			else
+				{
+				/*  sign*(X + Y)*a == A - B  (mod |n|) */
+				if (!BN_uadd(Y, Y, X)) goto err;
+				/* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */
+				if (!BN_usub(A, A, B)) goto err;
+				}
+			}
+		}
+	else
+		{
+		/* general inversion algorithm */
+
+		while (!BN_is_zero(B))
+			{
+			BIGNUM *tmp;
+			
+			/*
+			 *      0 < B < A,
+			 * (*) -sign*X*a  ==  B   (mod |n|),
+			 *      sign*Y*a  ==  A   (mod |n|)
+			 */
+			
+			/* (D, M) := (A/B, A%B) ... */
+			if (BN_num_bits(A) == BN_num_bits(B))
+				{
+				if (!BN_one(D)) goto err;
+				if (!BN_sub(M,A,B)) goto err;
+				}
+			else if (BN_num_bits(A) == BN_num_bits(B) + 1)
+				{
+				/* A/B is 1, 2, or 3 */
+				if (!BN_lshift1(T,B)) goto err;
+				if (BN_ucmp(A,T) < 0)
+					{
+					/* A < 2*B, so D=1 */
+					if (!BN_one(D)) goto err;
+					if (!BN_sub(M,A,B)) goto err;
+					}
+				else
+					{
+					/* A >= 2*B, so D=2 or D=3 */
+					if (!BN_sub(M,A,T)) goto err;
+					if (!BN_add(D,T,B)) goto err; /* use D (:= 3*B) as temp */
+					if (BN_ucmp(A,D) < 0)
+						{
+						/* A < 3*B, so D=2 */
+						if (!BN_set_word(D,2)) goto err;
+						/* M (= A - 2*B) already has the correct value */
+						}
+					else
+						{
+						/* only D=3 remains */
+						if (!BN_set_word(D,3)) goto err;
+						/* currently  M = A - 2*B,  but we need  M = A - 3*B */
+						if (!BN_sub(M,M,B)) goto err;
+						}
+					}
+				}
+			else
+				{
+				if (!BN_div(D,M,A,B,ctx)) goto err;
+				}
+			
+			/* Now
+			 *      A = D*B + M;
+			 * thus we have
+			 * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
+			 */
+			
+			tmp=A; /* keep the BIGNUM object, the value does not matter */
+			
+			/* (A, B) := (B, A mod B) ... */
+			A=B;
+			B=M;
+			/* ... so we have  0 <= B < A  again */
+			
+			/* Since the former  M  is now  B  and the former  B  is now  A,
+			 * (**) translates into
+			 *       sign*Y*a  ==  D*A + B    (mod |n|),
+			 * i.e.
+			 *       sign*Y*a - D*A  ==  B    (mod |n|).
+			 * Similarly, (*) translates into
+			 *      -sign*X*a  ==  A          (mod |n|).
+			 *
+			 * Thus,
+			 *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
+			 * i.e.
+			 *        sign*(Y + D*X)*a  ==  B  (mod |n|).
+			 *
+			 * So if we set  (X, Y, sign) := (Y + D*X, X, -sign),  we arrive back at
+			 *      -sign*X*a  ==  B   (mod |n|),
+			 *       sign*Y*a  ==  A   (mod |n|).
+			 * Note that  X  and  Y  stay non-negative all the time.
+			 */
+			
+			/* most of the time D is very small, so we can optimize tmp := D*X+Y */
+			if (BN_is_one(D))
+				{
+				if (!BN_add(tmp,X,Y)) goto err;
+				}
+			else
+				{
+				if (BN_is_word(D,2))
+					{
+					if (!BN_lshift1(tmp,X)) goto err;
+					}
+				else if (BN_is_word(D,4))
+					{
+					if (!BN_lshift(tmp,X,2)) goto err;
+					}
+				else if (D->top == 1)
+					{
+					if (!BN_copy(tmp,X)) goto err;
+					if (!BN_mul_word(tmp,D->d[0])) goto err;
+					}
+				else
+					{
+					if (!BN_mul(tmp,D,X,ctx)) goto err;
+					}
+				if (!BN_add(tmp,tmp,Y)) goto err;
+				}
+			
+			M=Y; /* keep the BIGNUM object, the value does not matter */
+			Y=X;
+			X=tmp;
+			sign = -sign;
+			}
+		}
+		
+	/*
+	 * The while loop (Euclid's algorithm) ends when
+	 *      A == gcd(a,n);
+	 * we have
+	 *       sign*Y*a  ==  A  (mod |n|),
+	 * where  Y  is non-negative.
+	 */
+
+	if (sign < 0)
+		{
+		if (!BN_sub(Y,n,Y)) goto err;
+		}
+	/* Now  Y*a  ==  A  (mod |n|).  */
+	
+
+	if (BN_is_one(A))
+		{
+		/* Y*a == 1  (mod |n|) */
+		if (!Y->neg && BN_ucmp(Y,n) < 0)
+			{
+			if (!BN_copy(R,Y)) goto err;
+			}
+		else
+			{
+			if (!BN_nnmod(R,Y,n,ctx)) goto err;
+			}
+		}
+	else
+		{
+		BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE);
+		goto err;
+		}
+	ret=R;
+err:
+	if ((ret == NULL) && (in == NULL)) BN_free(R);
+	BN_CTX_end(ctx);
+	bn_check_top(ret);
+	return(ret);
+	}
+
+
+/* BN_mod_inverse_no_branch is a special version of BN_mod_inverse. 
+ * It does not contain branches that may leak sensitive information.
+ */
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
+	const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
+	{
+	BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL;
+	BIGNUM local_A, local_B;
+	BIGNUM *pA, *pB;
+	BIGNUM *ret=NULL;
+	int sign;
+
+	bn_check_top(a);
+	bn_check_top(n);
+
+	BN_CTX_start(ctx);
+	A = BN_CTX_get(ctx);
+	B = BN_CTX_get(ctx);
+	X = BN_CTX_get(ctx);
+	D = BN_CTX_get(ctx);
+	M = BN_CTX_get(ctx);
+	Y = BN_CTX_get(ctx);
+	T = BN_CTX_get(ctx);
+	if (T == NULL) goto err;
+
+	if (in == NULL)
+		R=BN_new();
+	else
+		R=in;
+	if (R == NULL) goto err;
+
+	BN_one(X);
+	BN_zero(Y);
+	if (BN_copy(B,a) == NULL) goto err;
+	if (BN_copy(A,n) == NULL) goto err;
+	A->neg = 0;
+
+	if (B->neg || (BN_ucmp(B, A) >= 0))
+		{
+		/* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
+	 	 * BN_div_no_branch will be called eventually.
+	 	 */
+		pB = &local_B;
+		BN_with_flags(pB, B, BN_FLG_CONSTTIME);	
+		if (!BN_nnmod(B, pB, A, ctx)) goto err;
+		}
+	sign = -1;
+	/* From  B = a mod |n|,  A = |n|  it follows that
+	 *
+	 *      0 <= B < A,
+	 *     -sign*X*a  ==  B   (mod |n|),
+	 *      sign*Y*a  ==  A   (mod |n|).
+	 */
+
+	while (!BN_is_zero(B))
+		{
+		BIGNUM *tmp;
+		
+		/*
+		 *      0 < B < A,
+		 * (*) -sign*X*a  ==  B   (mod |n|),
+		 *      sign*Y*a  ==  A   (mod |n|)
+		 */
+
+		/* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
+	 	 * BN_div_no_branch will be called eventually.
+	 	 */
+		pA = &local_A;
+		BN_with_flags(pA, A, BN_FLG_CONSTTIME);	
+		
+		/* (D, M) := (A/B, A%B) ... */		
+		if (!BN_div(D,M,pA,B,ctx)) goto err;
+		
+		/* Now
+		 *      A = D*B + M;
+		 * thus we have
+		 * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
+		 */
+		
+		tmp=A; /* keep the BIGNUM object, the value does not matter */
+		
+		/* (A, B) := (B, A mod B) ... */
+		A=B;
+		B=M;
+		/* ... so we have  0 <= B < A  again */
+		
+		/* Since the former  M  is now  B  and the former  B  is now  A,
+		 * (**) translates into
+		 *       sign*Y*a  ==  D*A + B    (mod |n|),
+		 * i.e.
+		 *       sign*Y*a - D*A  ==  B    (mod |n|).
+		 * Similarly, (*) translates into
+		 *      -sign*X*a  ==  A          (mod |n|).
+		 *
+		 * Thus,
+		 *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
+		 * i.e.
+		 *        sign*(Y + D*X)*a  ==  B  (mod |n|).
+		 *
+		 * So if we set  (X, Y, sign) := (Y + D*X, X, -sign),  we arrive back at
+		 *      -sign*X*a  ==  B   (mod |n|),
+		 *       sign*Y*a  ==  A   (mod |n|).
+		 * Note that  X  and  Y  stay non-negative all the time.
+		 */
+			
+		if (!BN_mul(tmp,D,X,ctx)) goto err;
+		if (!BN_add(tmp,tmp,Y)) goto err;
+
+		M=Y; /* keep the BIGNUM object, the value does not matter */
+		Y=X;
+		X=tmp;
+		sign = -sign;
+		}
+		
+	/*
+	 * The while loop (Euclid's algorithm) ends when
+	 *      A == gcd(a,n);
+	 * we have
+	 *       sign*Y*a  ==  A  (mod |n|),
+	 * where  Y  is non-negative.
+	 */
+
+	if (sign < 0)
+		{
+		if (!BN_sub(Y,n,Y)) goto err;
+		}
+	/* Now  Y*a  ==  A  (mod |n|).  */
+
+	if (BN_is_one(A))
+		{
+		/* Y*a == 1  (mod |n|) */
+		if (!Y->neg && BN_ucmp(Y,n) < 0)
+			{
+			if (!BN_copy(R,Y)) goto err;
+			}
+		else
+			{
+			if (!BN_nnmod(R,Y,n,ctx)) goto err;
+			}
+		}
+	else
+		{
+		BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH,BN_R_NO_INVERSE);
+		goto err;
+		}
+	ret=R;
+err:
+	if ((ret == NULL) && (in == NULL)) BN_free(R);
+	BN_CTX_end(ctx);
+	bn_check_top(ret);
+	return(ret);
+	}
diff --git a/openssl/crypto/bn/bn_gf2m.c b/openssl/crypto/bn/bn_gf2m.c
new file mode 100644
index 0000000..432a3aa
--- /dev/null
+++ b/openssl/crypto/bn/bn_gf2m.c
@@ -0,0 +1,1035 @@
+/* crypto/bn/bn_gf2m.c */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * In addition, Sun covenants to all licensees who provide a reciprocal
+ * covenant with respect to their own patents if any, not to sue under
+ * current and future patent claims necessarily infringed by the making,
+ * using, practicing, selling, offering for sale and/or otherwise
+ * disposing of the ECC Code as delivered hereunder (or portions thereof),
+ * provided that such covenant shall not apply:
+ *  1) for code that a licensee deletes from the ECC Code;
+ *  2) separates from the ECC Code; or
+ *  3) for infringements caused by:
+ *       i) the modification of the ECC Code or
+ *      ii) the combination of the ECC Code with other software or
+ *          devices where such combination causes the infringement.
+ *
+ * The software is originally written by Sheueling Chang Shantz and
+ * Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+/* NOTE: This file is licensed pursuant to the OpenSSL license below
+ * and may be modified; but after modifications, the above covenant
+ * may no longer apply!  In such cases, the corresponding paragraph
+ * ["In addition, Sun covenants ... causes the infringement."] and
+ * this note can be edited out; but please keep the Sun copyright
+ * notice and attribution. */
+
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should fail. */
+#define MAX_ITERATIONS 50
+
+static const BN_ULONG SQR_tb[16] =
+  {     0,     1,     4,     5,    16,    17,    20,    21,
+       64,    65,    68,    69,    80,    81,    84,    85 };
+/* Platform-specific macros to accelerate squaring. */
+#if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+#define SQR1(w) \
+    SQR_tb[(w) >> 60 & 0xF] << 56 | SQR_tb[(w) >> 56 & 0xF] << 48 | \
+    SQR_tb[(w) >> 52 & 0xF] << 40 | SQR_tb[(w) >> 48 & 0xF] << 32 | \
+    SQR_tb[(w) >> 44 & 0xF] << 24 | SQR_tb[(w) >> 40 & 0xF] << 16 | \
+    SQR_tb[(w) >> 36 & 0xF] <<  8 | SQR_tb[(w) >> 32 & 0xF]
+#define SQR0(w) \
+    SQR_tb[(w) >> 28 & 0xF] << 56 | SQR_tb[(w) >> 24 & 0xF] << 48 | \
+    SQR_tb[(w) >> 20 & 0xF] << 40 | SQR_tb[(w) >> 16 & 0xF] << 32 | \
+    SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >>  8 & 0xF] << 16 | \
+    SQR_tb[(w) >>  4 & 0xF] <<  8 | SQR_tb[(w)       & 0xF]
+#endif
+#ifdef THIRTY_TWO_BIT
+#define SQR1(w) \
+    SQR_tb[(w) >> 28 & 0xF] << 24 | SQR_tb[(w) >> 24 & 0xF] << 16 | \
+    SQR_tb[(w) >> 20 & 0xF] <<  8 | SQR_tb[(w) >> 16 & 0xF]
+#define SQR0(w) \
+    SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >>  8 & 0xF] << 16 | \
+    SQR_tb[(w) >>  4 & 0xF] <<  8 | SQR_tb[(w)       & 0xF]
+#endif
+
+/* Product of two polynomials a, b each with degree < BN_BITS2 - 1,
+ * result is a polynomial r with degree < 2 * BN_BITS - 1
+ * The caller MUST ensure that the variables have the right amount
+ * of space allocated.
+ */
+#ifdef THIRTY_TWO_BIT
+static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b)
+	{
+	register BN_ULONG h, l, s;
+	BN_ULONG tab[8], top2b = a >> 30; 
+	register BN_ULONG a1, a2, a4;
+
+	a1 = a & (0x3FFFFFFF); a2 = a1 << 1; a4 = a2 << 1;
+
+	tab[0] =  0; tab[1] = a1;    tab[2] = a2;    tab[3] = a1^a2;
+	tab[4] = a4; tab[5] = a1^a4; tab[6] = a2^a4; tab[7] = a1^a2^a4;
+
+	s = tab[b       & 0x7]; l  = s;
+	s = tab[b >>  3 & 0x7]; l ^= s <<  3; h  = s >> 29;
+	s = tab[b >>  6 & 0x7]; l ^= s <<  6; h ^= s >> 26;
+	s = tab[b >>  9 & 0x7]; l ^= s <<  9; h ^= s >> 23;
+	s = tab[b >> 12 & 0x7]; l ^= s << 12; h ^= s >> 20;
+	s = tab[b >> 15 & 0x7]; l ^= s << 15; h ^= s >> 17;
+	s = tab[b >> 18 & 0x7]; l ^= s << 18; h ^= s >> 14;
+	s = tab[b >> 21 & 0x7]; l ^= s << 21; h ^= s >> 11;
+	s = tab[b >> 24 & 0x7]; l ^= s << 24; h ^= s >>  8;
+	s = tab[b >> 27 & 0x7]; l ^= s << 27; h ^= s >>  5;
+	s = tab[b >> 30      ]; l ^= s << 30; h ^= s >>  2;
+
+	/* compensate for the top two bits of a */
+
+	if (top2b & 01) { l ^= b << 30; h ^= b >> 2; } 
+	if (top2b & 02) { l ^= b << 31; h ^= b >> 1; } 
+
+	*r1 = h; *r0 = l;
+	} 
+#endif
+#if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b)
+	{
+	register BN_ULONG h, l, s;
+	BN_ULONG tab[16], top3b = a >> 61;
+	register BN_ULONG a1, a2, a4, a8;
+
+	a1 = a & (0x1FFFFFFFFFFFFFFFULL); a2 = a1 << 1; a4 = a2 << 1; a8 = a4 << 1;
+
+	tab[ 0] = 0;     tab[ 1] = a1;       tab[ 2] = a2;       tab[ 3] = a1^a2;
+	tab[ 4] = a4;    tab[ 5] = a1^a4;    tab[ 6] = a2^a4;    tab[ 7] = a1^a2^a4;
+	tab[ 8] = a8;    tab[ 9] = a1^a8;    tab[10] = a2^a8;    tab[11] = a1^a2^a8;
+	tab[12] = a4^a8; tab[13] = a1^a4^a8; tab[14] = a2^a4^a8; tab[15] = a1^a2^a4^a8;
+
+	s = tab[b       & 0xF]; l  = s;
+	s = tab[b >>  4 & 0xF]; l ^= s <<  4; h  = s >> 60;
+	s = tab[b >>  8 & 0xF]; l ^= s <<  8; h ^= s >> 56;
+	s = tab[b >> 12 & 0xF]; l ^= s << 12; h ^= s >> 52;
+	s = tab[b >> 16 & 0xF]; l ^= s << 16; h ^= s >> 48;
+	s = tab[b >> 20 & 0xF]; l ^= s << 20; h ^= s >> 44;
+	s = tab[b >> 24 & 0xF]; l ^= s << 24; h ^= s >> 40;
+	s = tab[b >> 28 & 0xF]; l ^= s << 28; h ^= s >> 36;
+	s = tab[b >> 32 & 0xF]; l ^= s << 32; h ^= s >> 32;
+	s = tab[b >> 36 & 0xF]; l ^= s << 36; h ^= s >> 28;
+	s = tab[b >> 40 & 0xF]; l ^= s << 40; h ^= s >> 24;
+	s = tab[b >> 44 & 0xF]; l ^= s << 44; h ^= s >> 20;
+	s = tab[b >> 48 & 0xF]; l ^= s << 48; h ^= s >> 16;
+	s = tab[b >> 52 & 0xF]; l ^= s << 52; h ^= s >> 12;
+	s = tab[b >> 56 & 0xF]; l ^= s << 56; h ^= s >>  8;
+	s = tab[b >> 60      ]; l ^= s << 60; h ^= s >>  4;
+
+	/* compensate for the top three bits of a */
+
+	if (top3b & 01) { l ^= b << 61; h ^= b >> 3; } 
+	if (top3b & 02) { l ^= b << 62; h ^= b >> 2; } 
+	if (top3b & 04) { l ^= b << 63; h ^= b >> 1; } 
+
+	*r1 = h; *r0 = l;
+	} 
+#endif
+
+/* Product of two polynomials a, b each with degree < 2 * BN_BITS2 - 1,
+ * result is a polynomial r with degree < 4 * BN_BITS2 - 1
+ * The caller MUST ensure that the variables have the right amount
+ * of space allocated.
+ */
+static void bn_GF2m_mul_2x2(BN_ULONG *r, const BN_ULONG a1, const BN_ULONG a0, const BN_ULONG b1, const BN_ULONG b0)
+	{
+	BN_ULONG m1, m0;
+	/* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */
+	bn_GF2m_mul_1x1(r+3, r+2, a1, b1);
+	bn_GF2m_mul_1x1(r+1, r, a0, b0);
+	bn_GF2m_mul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1);
+	/* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */
+	r[2] ^= m1 ^ r[1] ^ r[3];  /* h0 ^= m1 ^ l1 ^ h1; */
+	r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0;  /* l1 ^= l0 ^ h0 ^ m0; */
+	}
+
+
+/* Add polynomials a and b and store result in r; r could be a or b, a and b 
+ * could be equal; r is the bitwise XOR of a and b.
+ */
+int	BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+	{
+	int i;
+	const BIGNUM *at, *bt;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	if (a->top < b->top) { at = b; bt = a; }
+	else { at = a; bt = b; }
+
+	if(bn_wexpand(r, at->top) == NULL)
+		return 0;
+
+	for (i = 0; i < bt->top; i++)
+		{
+		r->d[i] = at->d[i] ^ bt->d[i];
+		}
+	for (; i < at->top; i++)
+		{
+		r->d[i] = at->d[i];
+		}
+	
+	r->top = at->top;
+	bn_correct_top(r);
+	
+	return 1;
+	}
+
+
+/* Some functions allow for representation of the irreducible polynomials
+ * as an int[], say p.  The irreducible f(t) is then of the form:
+ *     t^p[0] + t^p[1] + ... + t^p[k]
+ * where m = p[0] > p[1] > ... > p[k] = 0.
+ */
+
+
+/* Performs modular reduction of a and store result in r.  r could be a. */
+int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[])
+	{
+	int j, k;
+	int n, dN, d0, d1;
+	BN_ULONG zz, *z;
+
+	bn_check_top(a);
+
+	if (!p[0])
+		{
+		/* reduction mod 1 => return 0 */
+		BN_zero(r);
+		return 1;
+		}
+
+	/* Since the algorithm does reduction in the r value, if a != r, copy
+	 * the contents of a into r so we can do reduction in r. 
+	 */
+	if (a != r)
+		{
+		if (!bn_wexpand(r, a->top)) return 0;
+		for (j = 0; j < a->top; j++)
+			{
+			r->d[j] = a->d[j];
+			}
+		r->top = a->top;
+		}
+	z = r->d;
+
+	/* start reduction */
+	dN = p[0] / BN_BITS2;  
+	for (j = r->top - 1; j > dN;)
+		{
+		zz = z[j];
+		if (z[j] == 0) { j--; continue; }
+		z[j] = 0;
+
+		for (k = 1; p[k] != 0; k++)
+			{
+			/* reducing component t^p[k] */
+			n = p[0] - p[k];
+			d0 = n % BN_BITS2;  d1 = BN_BITS2 - d0;
+			n /= BN_BITS2; 
+			z[j-n] ^= (zz>>d0);
+			if (d0) z[j-n-1] ^= (zz<<d1);
+			}
+
+		/* reducing component t^0 */
+		n = dN;  
+		d0 = p[0] % BN_BITS2;
+		d1 = BN_BITS2 - d0;
+		z[j-n] ^= (zz >> d0);
+		if (d0) z[j-n-1] ^= (zz << d1);
+		}
+
+	/* final round of reduction */
+	while (j == dN)
+		{
+
+		d0 = p[0] % BN_BITS2;
+		zz = z[dN] >> d0;
+		if (zz == 0) break;
+		d1 = BN_BITS2 - d0;
+		
+		/* clear up the top d1 bits */
+		if (d0)
+			z[dN] = (z[dN] << d1) >> d1;
+		else
+			z[dN] = 0;
+		z[0] ^= zz; /* reduction t^0 component */
+
+		for (k = 1; p[k] != 0; k++)
+			{
+			BN_ULONG tmp_ulong;
+
+			/* reducing component t^p[k]*/
+			n = p[k] / BN_BITS2;   
+			d0 = p[k] % BN_BITS2;
+			d1 = BN_BITS2 - d0;
+			z[n] ^= (zz << d0);
+			tmp_ulong = zz >> d1;
+                        if (d0 && tmp_ulong)
+                                z[n+1] ^= tmp_ulong;
+			}
+
+		
+		}
+
+	bn_correct_top(r);
+	return 1;
+	}
+
+/* Performs modular reduction of a by p and store result in r.  r could be a.
+ *
+ * This function calls down to the BN_GF2m_mod_arr implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the 
+ * BN_GF2m_mod_arr function.
+ */
+int	BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p)
+	{
+	int ret = 0;
+	const int max = BN_num_bits(p) + 1;
+	int *arr=NULL;
+	bn_check_top(a);
+	bn_check_top(p);
+	if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
+	ret = BN_GF2m_poly2arr(p, arr, max);
+	if (!ret || ret > max)
+		{
+		BNerr(BN_F_BN_GF2M_MOD,BN_R_INVALID_LENGTH);
+		goto err;
+		}
+	ret = BN_GF2m_mod_arr(r, a, arr);
+	bn_check_top(r);
+err:
+	if (arr) OPENSSL_free(arr);
+	return ret;
+	}
+
+
+/* Compute the product of two polynomials a and b, reduce modulo p, and store
+ * the result in r.  r could be a or b; a could be b.
+ */
+int	BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p[], BN_CTX *ctx)
+	{
+	int zlen, i, j, k, ret = 0;
+	BIGNUM *s;
+	BN_ULONG x1, x0, y1, y0, zz[4];
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	if (a == b)
+		{
+		return BN_GF2m_mod_sqr_arr(r, a, p, ctx);
+		}
+
+	BN_CTX_start(ctx);
+	if ((s = BN_CTX_get(ctx)) == NULL) goto err;
+	
+	zlen = a->top + b->top + 4;
+	if (!bn_wexpand(s, zlen)) goto err;
+	s->top = zlen;
+
+	for (i = 0; i < zlen; i++) s->d[i] = 0;
+
+	for (j = 0; j < b->top; j += 2)
+		{
+		y0 = b->d[j];
+		y1 = ((j+1) == b->top) ? 0 : b->d[j+1];
+		for (i = 0; i < a->top; i += 2)
+			{
+			x0 = a->d[i];
+			x1 = ((i+1) == a->top) ? 0 : a->d[i+1];
+			bn_GF2m_mul_2x2(zz, x1, x0, y1, y0);
+			for (k = 0; k < 4; k++) s->d[i+j+k] ^= zz[k];
+			}
+		}
+
+	bn_correct_top(s);
+	if (BN_GF2m_mod_arr(r, s, p))
+		ret = 1;
+	bn_check_top(r);
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+	}
+
+/* Compute the product of two polynomials a and b, reduce modulo p, and store
+ * the result in r.  r could be a or b; a could equal b.
+ *
+ * This function calls down to the BN_GF2m_mod_mul_arr implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the 
+ * BN_GF2m_mod_mul_arr function.
+ */
+int	BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx)
+	{
+	int ret = 0;
+	const int max = BN_num_bits(p) + 1;
+	int *arr=NULL;
+	bn_check_top(a);
+	bn_check_top(b);
+	bn_check_top(p);
+	if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
+	ret = BN_GF2m_poly2arr(p, arr, max);
+	if (!ret || ret > max)
+		{
+		BNerr(BN_F_BN_GF2M_MOD_MUL,BN_R_INVALID_LENGTH);
+		goto err;
+		}
+	ret = BN_GF2m_mod_mul_arr(r, a, b, arr, ctx);
+	bn_check_top(r);
+err:
+	if (arr) OPENSSL_free(arr);
+	return ret;
+	}
+
+
+/* Square a, reduce the result mod p, and store it in a.  r could be a. */
+int	BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], BN_CTX *ctx)
+	{
+	int i, ret = 0;
+	BIGNUM *s;
+
+	bn_check_top(a);
+	BN_CTX_start(ctx);
+	if ((s = BN_CTX_get(ctx)) == NULL) return 0;
+	if (!bn_wexpand(s, 2 * a->top)) goto err;
+
+	for (i = a->top - 1; i >= 0; i--)
+		{
+		s->d[2*i+1] = SQR1(a->d[i]);
+		s->d[2*i  ] = SQR0(a->d[i]);
+		}
+
+	s->top = 2 * a->top;
+	bn_correct_top(s);
+	if (!BN_GF2m_mod_arr(r, s, p)) goto err;
+	bn_check_top(r);
+	ret = 1;
+err:
+	BN_CTX_end(ctx);
+	return ret;
+	}
+
+/* Square a, reduce the result mod p, and store it in a.  r could be a.
+ *
+ * This function calls down to the BN_GF2m_mod_sqr_arr implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the 
+ * BN_GF2m_mod_sqr_arr function.
+ */
+int	BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+	{
+	int ret = 0;
+	const int max = BN_num_bits(p) + 1;
+	int *arr=NULL;
+
+	bn_check_top(a);
+	bn_check_top(p);
+	if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
+	ret = BN_GF2m_poly2arr(p, arr, max);
+	if (!ret || ret > max)
+		{
+		BNerr(BN_F_BN_GF2M_MOD_SQR,BN_R_INVALID_LENGTH);
+		goto err;
+		}
+	ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx);
+	bn_check_top(r);
+err:
+	if (arr) OPENSSL_free(arr);
+	return ret;
+	}
+
+
+/* Invert a, reduce modulo p, and store the result in r. r could be a. 
+ * Uses Modified Almost Inverse Algorithm (Algorithm 10) from
+ *     Hankerson, D., Hernandez, J.L., and Menezes, A.  "Software Implementation
+ *     of Elliptic Curve Cryptography Over Binary Fields".
+ */
+int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+	{
+	BIGNUM *b, *c, *u, *v, *tmp;
+	int ret = 0;
+
+	bn_check_top(a);
+	bn_check_top(p);
+
+	BN_CTX_start(ctx);
+	
+	b = BN_CTX_get(ctx);
+	c = BN_CTX_get(ctx);
+	u = BN_CTX_get(ctx);
+	v = BN_CTX_get(ctx);
+	if (v == NULL) goto err;
+
+	if (!BN_one(b)) goto err;
+	if (!BN_GF2m_mod(u, a, p)) goto err;
+	if (!BN_copy(v, p)) goto err;
+
+	if (BN_is_zero(u)) goto err;
+
+	while (1)
+		{
+		while (!BN_is_odd(u))
+			{
+			if (BN_is_zero(u)) goto err;
+			if (!BN_rshift1(u, u)) goto err;
+			if (BN_is_odd(b))
+				{
+				if (!BN_GF2m_add(b, b, p)) goto err;
+				}
+			if (!BN_rshift1(b, b)) goto err;
+			}
+
+		if (BN_abs_is_word(u, 1)) break;
+
+		if (BN_num_bits(u) < BN_num_bits(v))
+			{
+			tmp = u; u = v; v = tmp;
+			tmp = b; b = c; c = tmp;
+			}
+		
+		if (!BN_GF2m_add(u, u, v)) goto err;
+		if (!BN_GF2m_add(b, b, c)) goto err;
+		}
+
+
+	if (!BN_copy(r, b)) goto err;
+	bn_check_top(r);
+	ret = 1;
+
+err:
+  	BN_CTX_end(ctx);
+	return ret;
+	}
+
+/* Invert xx, reduce modulo p, and store the result in r. r could be xx. 
+ *
+ * This function calls down to the BN_GF2m_mod_inv implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the 
+ * BN_GF2m_mod_inv function.
+ */
+int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const int p[], BN_CTX *ctx)
+	{
+	BIGNUM *field;
+	int ret = 0;
+
+	bn_check_top(xx);
+	BN_CTX_start(ctx);
+	if ((field = BN_CTX_get(ctx)) == NULL) goto err;
+	if (!BN_GF2m_arr2poly(p, field)) goto err;
+	
+	ret = BN_GF2m_mod_inv(r, xx, field, ctx);
+	bn_check_top(r);
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+	}
+
+
+#ifndef OPENSSL_SUN_GF2M_DIV
+/* Divide y by x, reduce modulo p, and store the result in r. r could be x 
+ * or y, x could equal y.
+ */
+int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p, BN_CTX *ctx)
+	{
+	BIGNUM *xinv = NULL;
+	int ret = 0;
+
+	bn_check_top(y);
+	bn_check_top(x);
+	bn_check_top(p);
+
+	BN_CTX_start(ctx);
+	xinv = BN_CTX_get(ctx);
+	if (xinv == NULL) goto err;
+	
+	if (!BN_GF2m_mod_inv(xinv, x, p, ctx)) goto err;
+	if (!BN_GF2m_mod_mul(r, y, xinv, p, ctx)) goto err;
+	bn_check_top(r);
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+	}
+#else
+/* Divide y by x, reduce modulo p, and store the result in r. r could be x 
+ * or y, x could equal y.
+ * Uses algorithm Modular_Division_GF(2^m) from 
+ *     Chang-Shantz, S.  "From Euclid's GCD to Montgomery Multiplication to 
+ *     the Great Divide".
+ */
+int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p, BN_CTX *ctx)
+	{
+	BIGNUM *a, *b, *u, *v;
+	int ret = 0;
+
+	bn_check_top(y);
+	bn_check_top(x);
+	bn_check_top(p);
+
+	BN_CTX_start(ctx);
+	
+	a = BN_CTX_get(ctx);
+	b = BN_CTX_get(ctx);
+	u = BN_CTX_get(ctx);
+	v = BN_CTX_get(ctx);
+	if (v == NULL) goto err;
+
+	/* reduce x and y mod p */
+	if (!BN_GF2m_mod(u, y, p)) goto err;
+	if (!BN_GF2m_mod(a, x, p)) goto err;
+	if (!BN_copy(b, p)) goto err;
+	
+	while (!BN_is_odd(a))
+		{
+		if (!BN_rshift1(a, a)) goto err;
+		if (BN_is_odd(u)) if (!BN_GF2m_add(u, u, p)) goto err;
+		if (!BN_rshift1(u, u)) goto err;
+		}
+
+	do
+		{
+		if (BN_GF2m_cmp(b, a) > 0)
+			{
+			if (!BN_GF2m_add(b, b, a)) goto err;
+			if (!BN_GF2m_add(v, v, u)) goto err;
+			do
+				{
+				if (!BN_rshift1(b, b)) goto err;
+				if (BN_is_odd(v)) if (!BN_GF2m_add(v, v, p)) goto err;
+				if (!BN_rshift1(v, v)) goto err;
+				} while (!BN_is_odd(b));
+			}
+		else if (BN_abs_is_word(a, 1))
+			break;
+		else
+			{
+			if (!BN_GF2m_add(a, a, b)) goto err;
+			if (!BN_GF2m_add(u, u, v)) goto err;
+			do
+				{
+				if (!BN_rshift1(a, a)) goto err;
+				if (BN_is_odd(u)) if (!BN_GF2m_add(u, u, p)) goto err;
+				if (!BN_rshift1(u, u)) goto err;
+				} while (!BN_is_odd(a));
+			}
+		} while (1);
+
+	if (!BN_copy(r, u)) goto err;
+	bn_check_top(r);
+	ret = 1;
+
+err:
+  	BN_CTX_end(ctx);
+	return ret;
+	}
+#endif
+
+/* Divide yy by xx, reduce modulo p, and store the result in r. r could be xx 
+ * or yy, xx could equal yy.
+ *
+ * This function calls down to the BN_GF2m_mod_div implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the 
+ * BN_GF2m_mod_div function.
+ */
+int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, const int p[], BN_CTX *ctx)
+	{
+	BIGNUM *field;
+	int ret = 0;
+
+	bn_check_top(yy);
+	bn_check_top(xx);
+
+	BN_CTX_start(ctx);
+	if ((field = BN_CTX_get(ctx)) == NULL) goto err;
+	if (!BN_GF2m_arr2poly(p, field)) goto err;
+	
+	ret = BN_GF2m_mod_div(r, yy, xx, field, ctx);
+	bn_check_top(r);
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+	}
+
+
+/* Compute the bth power of a, reduce modulo p, and store
+ * the result in r.  r could be a.
+ * Uses simple square-and-multiply algorithm A.5.1 from IEEE P1363.
+ */
+int	BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p[], BN_CTX *ctx)
+	{
+	int ret = 0, i, n;
+	BIGNUM *u;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	if (BN_is_zero(b))
+		return(BN_one(r));
+
+	if (BN_abs_is_word(b, 1))
+		return (BN_copy(r, a) != NULL);
+
+	BN_CTX_start(ctx);
+	if ((u = BN_CTX_get(ctx)) == NULL) goto err;
+	
+	if (!BN_GF2m_mod_arr(u, a, p)) goto err;
+	
+	n = BN_num_bits(b) - 1;
+	for (i = n - 1; i >= 0; i--)
+		{
+		if (!BN_GF2m_mod_sqr_arr(u, u, p, ctx)) goto err;
+		if (BN_is_bit_set(b, i))
+			{
+			if (!BN_GF2m_mod_mul_arr(u, u, a, p, ctx)) goto err;
+			}
+		}
+	if (!BN_copy(r, u)) goto err;
+	bn_check_top(r);
+	ret = 1;
+err:
+	BN_CTX_end(ctx);
+	return ret;
+	}
+
+/* Compute the bth power of a, reduce modulo p, and store
+ * the result in r.  r could be a.
+ *
+ * This function calls down to the BN_GF2m_mod_exp_arr implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the 
+ * BN_GF2m_mod_exp_arr function.
+ */
+int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx)
+	{
+	int ret = 0;
+	const int max = BN_num_bits(p) + 1;
+	int *arr=NULL;
+	bn_check_top(a);
+	bn_check_top(b);
+	bn_check_top(p);
+	if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
+	ret = BN_GF2m_poly2arr(p, arr, max);
+	if (!ret || ret > max)
+		{
+		BNerr(BN_F_BN_GF2M_MOD_EXP,BN_R_INVALID_LENGTH);
+		goto err;
+		}
+	ret = BN_GF2m_mod_exp_arr(r, a, b, arr, ctx);
+	bn_check_top(r);
+err:
+	if (arr) OPENSSL_free(arr);
+	return ret;
+	}
+
+/* Compute the square root of a, reduce modulo p, and store
+ * the result in r.  r could be a.
+ * Uses exponentiation as in algorithm A.4.1 from IEEE P1363.
+ */
+int	BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const int p[], BN_CTX *ctx)
+	{
+	int ret = 0;
+	BIGNUM *u;
+
+	bn_check_top(a);
+
+	if (!p[0])
+		{
+		/* reduction mod 1 => return 0 */
+		BN_zero(r);
+		return 1;
+		}
+
+	BN_CTX_start(ctx);
+	if ((u = BN_CTX_get(ctx)) == NULL) goto err;
+	
+	if (!BN_set_bit(u, p[0] - 1)) goto err;
+	ret = BN_GF2m_mod_exp_arr(r, a, u, p, ctx);
+	bn_check_top(r);
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+	}
+
+/* Compute the square root of a, reduce modulo p, and store
+ * the result in r.  r could be a.
+ *
+ * This function calls down to the BN_GF2m_mod_sqrt_arr implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the 
+ * BN_GF2m_mod_sqrt_arr function.
+ */
+int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+	{
+	int ret = 0;
+	const int max = BN_num_bits(p) + 1;
+	int *arr=NULL;
+	bn_check_top(a);
+	bn_check_top(p);
+	if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
+	ret = BN_GF2m_poly2arr(p, arr, max);
+	if (!ret || ret > max)
+		{
+		BNerr(BN_F_BN_GF2M_MOD_SQRT,BN_R_INVALID_LENGTH);
+		goto err;
+		}
+	ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx);
+	bn_check_top(r);
+err:
+	if (arr) OPENSSL_free(arr);
+	return ret;
+	}
+
+/* Find r such that r^2 + r = a mod p.  r could be a. If no r exists returns 0.
+ * Uses algorithms A.4.7 and A.4.6 from IEEE P1363.
+ */
+int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[], BN_CTX *ctx)
+	{
+	int ret = 0, count = 0, j;
+	BIGNUM *a, *z, *rho, *w, *w2, *tmp;
+
+	bn_check_top(a_);
+
+	if (!p[0])
+		{
+		/* reduction mod 1 => return 0 */
+		BN_zero(r);
+		return 1;
+		}
+
+	BN_CTX_start(ctx);
+	a = BN_CTX_get(ctx);
+	z = BN_CTX_get(ctx);
+	w = BN_CTX_get(ctx);
+	if (w == NULL) goto err;
+
+	if (!BN_GF2m_mod_arr(a, a_, p)) goto err;
+	
+	if (BN_is_zero(a))
+		{
+		BN_zero(r);
+		ret = 1;
+		goto err;
+		}
+
+	if (p[0] & 0x1) /* m is odd */
+		{
+		/* compute half-trace of a */
+		if (!BN_copy(z, a)) goto err;
+		for (j = 1; j <= (p[0] - 1) / 2; j++)
+			{
+			if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) goto err;
+			if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) goto err;
+			if (!BN_GF2m_add(z, z, a)) goto err;
+			}
+		
+		}
+	else /* m is even */
+		{
+		rho = BN_CTX_get(ctx);
+		w2 = BN_CTX_get(ctx);
+		tmp = BN_CTX_get(ctx);
+		if (tmp == NULL) goto err;
+		do
+			{
+			if (!BN_rand(rho, p[0], 0, 0)) goto err;
+			if (!BN_GF2m_mod_arr(rho, rho, p)) goto err;
+			BN_zero(z);
+			if (!BN_copy(w, rho)) goto err;
+			for (j = 1; j <= p[0] - 1; j++)
+				{
+				if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) goto err;
+				if (!BN_GF2m_mod_sqr_arr(w2, w, p, ctx)) goto err;
+				if (!BN_GF2m_mod_mul_arr(tmp, w2, a, p, ctx)) goto err;
+				if (!BN_GF2m_add(z, z, tmp)) goto err;
+				if (!BN_GF2m_add(w, w2, rho)) goto err;
+				}
+			count++;
+			} while (BN_is_zero(w) && (count < MAX_ITERATIONS));
+		if (BN_is_zero(w))
+			{
+			BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR,BN_R_TOO_MANY_ITERATIONS);
+			goto err;
+			}
+		}
+	
+	if (!BN_GF2m_mod_sqr_arr(w, z, p, ctx)) goto err;
+	if (!BN_GF2m_add(w, z, w)) goto err;
+	if (BN_GF2m_cmp(w, a))
+		{
+		BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_NO_SOLUTION);
+		goto err;
+		}
+
+	if (!BN_copy(r, z)) goto err;
+	bn_check_top(r);
+
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+	}
+
+/* Find r such that r^2 + r = a mod p.  r could be a. If no r exists returns 0.
+ *
+ * This function calls down to the BN_GF2m_mod_solve_quad_arr implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the 
+ * BN_GF2m_mod_solve_quad_arr function.
+ */
+int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+	{
+	int ret = 0;
+	const int max = BN_num_bits(p) + 1;
+	int *arr=NULL;
+	bn_check_top(a);
+	bn_check_top(p);
+	if ((arr = (int *)OPENSSL_malloc(sizeof(int) *
+						max)) == NULL) goto err;
+	ret = BN_GF2m_poly2arr(p, arr, max);
+	if (!ret || ret > max)
+		{
+		BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD,BN_R_INVALID_LENGTH);
+		goto err;
+		}
+	ret = BN_GF2m_mod_solve_quad_arr(r, a, arr, ctx);
+	bn_check_top(r);
+err:
+	if (arr) OPENSSL_free(arr);
+	return ret;
+	}
+
+/* Convert the bit-string representation of a polynomial
+ * ( \sum_{i=0}^n a_i * x^i) into an array of integers corresponding 
+ * to the bits with non-zero coefficient.  Array is terminated with -1.
+ * Up to max elements of the array will be filled.  Return value is total
+ * number of array elements that would be filled if array was large enough.
+ */
+int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max)
+	{
+	int i, j, k = 0;
+	BN_ULONG mask;
+
+	if (BN_is_zero(a))
+		return 0;
+
+	for (i = a->top - 1; i >= 0; i--)
+		{
+		if (!a->d[i])
+			/* skip word if a->d[i] == 0 */
+			continue;
+		mask = BN_TBIT;
+		for (j = BN_BITS2 - 1; j >= 0; j--)
+			{
+			if (a->d[i] & mask) 
+				{
+				if (k < max) p[k] = BN_BITS2 * i + j;
+				k++;
+				}
+			mask >>= 1;
+			}
+		}
+
+	if (k < max) {
+		p[k] = -1;
+		k++;
+	}
+
+	return k;
+	}
+
+/* Convert the coefficient array representation of a polynomial to a 
+ * bit-string.  The array must be terminated by -1.
+ */
+int BN_GF2m_arr2poly(const int p[], BIGNUM *a)
+	{
+	int i;
+
+	bn_check_top(a);
+	BN_zero(a);
+	for (i = 0; p[i] != -1; i++)
+		{
+		if (BN_set_bit(a, p[i]) == 0)
+			return 0;
+		}
+	bn_check_top(a);
+
+	return 1;
+	}
+
diff --git a/openssl/crypto/bn/bn_kron.c b/openssl/crypto/bn/bn_kron.c
new file mode 100644
index 0000000..740359b
--- /dev/null
+++ b/openssl/crypto/bn/bn_kron.c
@@ -0,0 +1,184 @@
+/* crypto/bn/bn_kron.c */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* least significant word */
+#define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0])
+
+/* Returns -2 for errors because both -1 and 0 are valid results. */
+int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+	{
+	int i;
+	int ret = -2; /* avoid 'uninitialized' warning */
+	int err = 0;
+	BIGNUM *A, *B, *tmp;
+	/* In 'tab', only odd-indexed entries are relevant:
+	 * For any odd BIGNUM n,
+	 *     tab[BN_lsw(n) & 7]
+	 * is $(-1)^{(n^2-1)/8}$ (using TeX notation).
+	 * Note that the sign of n does not matter.
+	 */
+	static const int tab[8] = {0, 1, 0, -1, 0, -1, 0, 1};
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	BN_CTX_start(ctx);
+	A = BN_CTX_get(ctx);
+	B = BN_CTX_get(ctx);
+	if (B == NULL) goto end;
+	
+	err = !BN_copy(A, a);
+	if (err) goto end;
+	err = !BN_copy(B, b);
+	if (err) goto end;
+
+	/*
+	 * Kronecker symbol, imlemented according to Henri Cohen,
+	 * "A Course in Computational Algebraic Number Theory"
+	 * (algorithm 1.4.10).
+	 */
+
+	/* Cohen's step 1: */
+
+	if (BN_is_zero(B))
+		{
+		ret = BN_abs_is_word(A, 1);
+		goto end;
+ 		}
+	
+	/* Cohen's step 2: */
+
+	if (!BN_is_odd(A) && !BN_is_odd(B))
+		{
+		ret = 0;
+		goto end;
+		}
+
+	/* now  B  is non-zero */
+	i = 0;
+	while (!BN_is_bit_set(B, i))
+		i++;
+	err = !BN_rshift(B, B, i);
+	if (err) goto end;
+	if (i & 1)
+		{
+		/* i is odd */
+		/* (thus  B  was even, thus  A  must be odd!)  */
+
+		/* set 'ret' to $(-1)^{(A^2-1)/8}$ */
+		ret = tab[BN_lsw(A) & 7];
+		}
+	else
+		{
+		/* i is even */
+		ret = 1;
+		}
+	
+	if (B->neg)
+		{
+		B->neg = 0;
+		if (A->neg)
+			ret = -ret;
+		}
+
+	/* now  B  is positive and odd, so what remains to be done is
+	 * to compute the Jacobi symbol  (A/B)  and multiply it by 'ret' */
+
+	while (1)
+		{
+		/* Cohen's step 3: */
+
+		/*  B  is positive and odd */
+
+		if (BN_is_zero(A))
+			{
+			ret = BN_is_one(B) ? ret : 0;
+			goto end;
+			}
+
+		/* now  A  is non-zero */
+		i = 0;
+		while (!BN_is_bit_set(A, i))
+			i++;
+		err = !BN_rshift(A, A, i);
+		if (err) goto end;
+		if (i & 1)
+			{
+			/* i is odd */
+			/* multiply 'ret' by  $(-1)^{(B^2-1)/8}$ */
+			ret = ret * tab[BN_lsw(B) & 7];
+			}
+	
+		/* Cohen's step 4: */
+		/* multiply 'ret' by  $(-1)^{(A-1)(B-1)/4}$ */
+		if ((A->neg ? ~BN_lsw(A) : BN_lsw(A)) & BN_lsw(B) & 2)
+			ret = -ret;
+		
+		/* (A, B) := (B mod |A|, |A|) */
+		err = !BN_nnmod(B, B, A, ctx);
+		if (err) goto end;
+		tmp = A; A = B; B = tmp;
+		tmp->neg = 0;
+		}
+end:
+	BN_CTX_end(ctx);
+	if (err)
+		return -2;
+	else
+		return ret;
+	}
diff --git a/openssl/crypto/bn/bn_lcl.h b/openssl/crypto/bn/bn_lcl.h
new file mode 100644
index 0000000..8e5e98e
--- /dev/null
+++ b/openssl/crypto/bn/bn_lcl.h
@@ -0,0 +1,491 @@
+/* crypto/bn/bn_lcl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_BN_LCL_H
+#define HEADER_BN_LCL_H
+
+#include <openssl/bn.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
+ *
+ *
+ * For window size 'w' (w >= 2) and a random 'b' bits exponent,
+ * the number of multiplications is a constant plus on average
+ *
+ *    2^(w-1) + (b-w)/(w+1);
+ *
+ * here  2^(w-1)  is for precomputing the table (we actually need
+ * entries only for windows that have the lowest bit set), and
+ * (b-w)/(w+1)  is an approximation for the expected number of
+ * w-bit windows, not counting the first one.
+ *
+ * Thus we should use
+ *
+ *    w >= 6  if        b > 671
+ *     w = 5  if  671 > b > 239
+ *     w = 4  if  239 > b >  79
+ *     w = 3  if   79 > b >  23
+ *    w <= 2  if   23 > b
+ *
+ * (with draws in between).  Very small exponents are often selected
+ * with low Hamming weight, so we use  w = 1  for b <= 23.
+ */
+#if 1
+#define BN_window_bits_for_exponent_size(b) \
+		((b) > 671 ? 6 : \
+		 (b) > 239 ? 5 : \
+		 (b) >  79 ? 4 : \
+		 (b) >  23 ? 3 : 1)
+#else
+/* Old SSLeay/OpenSSL table.
+ * Maximum window size was 5, so this table differs for b==1024;
+ * but it coincides for other interesting values (b==160, b==512).
+ */
+#define BN_window_bits_for_exponent_size(b) \
+		((b) > 255 ? 5 : \
+		 (b) > 127 ? 4 : \
+		 (b) >  17 ? 3 : 1)
+#endif	 
+
+
+
+/* BN_mod_exp_mont_conttime is based on the assumption that the
+ * L1 data cache line width of the target processor is at least
+ * the following value.
+ */
+#define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH	( 64 )
+#define MOD_EXP_CTIME_MIN_CACHE_LINE_MASK	(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - 1)
+
+/* Window sizes optimized for fixed window size modular exponentiation
+ * algorithm (BN_mod_exp_mont_consttime).
+ *
+ * To achieve the security goals of BN_mode_exp_mont_consttime, the
+ * maximum size of the window must not exceed
+ * log_2(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH). 
+ *
+ * Window size thresholds are defined for cache line sizes of 32 and 64,
+ * cache line sizes where log_2(32)=5 and log_2(64)=6 respectively. A
+ * window size of 7 should only be used on processors that have a 128
+ * byte or greater cache line size.
+ */
+#if MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 64
+
+#  define BN_window_bits_for_ctime_exponent_size(b) \
+		((b) > 937 ? 6 : \
+		 (b) > 306 ? 5 : \
+		 (b) >  89 ? 4 : \
+		 (b) >  22 ? 3 : 1)
+#  define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE	(6)
+
+#elif MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 32
+
+#  define BN_window_bits_for_ctime_exponent_size(b) \
+		((b) > 306 ? 5 : \
+		 (b) >  89 ? 4 : \
+		 (b) >  22 ? 3 : 1)
+#  define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE	(5)
+
+#endif
+
+
+/* Pentium pro 16,16,16,32,64 */
+/* Alpha       16,16,16,16.64 */
+#define BN_MULL_SIZE_NORMAL			(16) /* 32 */
+#define BN_MUL_RECURSIVE_SIZE_NORMAL		(16) /* 32 less than */
+#define BN_SQR_RECURSIVE_SIZE_NORMAL		(16) /* 32 */
+#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL	(32) /* 32 */
+#define BN_MONT_CTX_SET_SIZE_WORD		(64) /* 32 */
+
+#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
+/*
+ * BN_UMULT_HIGH section.
+ *
+ * No, I'm not trying to overwhelm you when stating that the
+ * product of N-bit numbers is 2*N bits wide:-) No, I don't expect
+ * you to be impressed when I say that if the compiler doesn't
+ * support 2*N integer type, then you have to replace every N*N
+ * multiplication with 4 (N/2)*(N/2) accompanied by some shifts
+ * and additions which unavoidably results in severe performance
+ * penalties. Of course provided that the hardware is capable of
+ * producing 2*N result... That's when you normally start
+ * considering assembler implementation. However! It should be
+ * pointed out that some CPUs (most notably Alpha, PowerPC and
+ * upcoming IA-64 family:-) provide *separate* instruction
+ * calculating the upper half of the product placing the result
+ * into a general purpose register. Now *if* the compiler supports
+ * inline assembler, then it's not impossible to implement the
+ * "bignum" routines (and have the compiler optimize 'em)
+ * exhibiting "native" performance in C. That's what BN_UMULT_HIGH
+ * macro is about:-)
+ *
+ *					<appro@fy.chalmers.se>
+ */
+# if defined(__alpha) && (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
+#  if defined(__DECC)
+#   include <c_asm.h>
+#   define BN_UMULT_HIGH(a,b)	(BN_ULONG)asm("umulh %a0,%a1,%v0",(a),(b))
+#  elif defined(__GNUC__)
+#   define BN_UMULT_HIGH(a,b)	({	\
+	register BN_ULONG ret;		\
+	asm ("umulh	%1,%2,%0"	\
+	     : "=r"(ret)		\
+	     : "r"(a), "r"(b));		\
+	ret;			})
+#  endif	/* compiler */
+# elif defined(_ARCH_PPC) && defined(__64BIT__) && defined(SIXTY_FOUR_BIT_LONG)
+#  if defined(__GNUC__)
+#   define BN_UMULT_HIGH(a,b)	({	\
+	register BN_ULONG ret;		\
+	asm ("mulhdu	%0,%1,%2"	\
+	     : "=r"(ret)		\
+	     : "r"(a), "r"(b));		\
+	ret;			})
+#  endif	/* compiler */
+# elif (defined(__x86_64) || defined(__x86_64__)) && \
+       (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
+#  if defined(__GNUC__)
+#   define BN_UMULT_HIGH(a,b)	({	\
+	register BN_ULONG ret,discard;	\
+	asm ("mulq	%3"		\
+	     : "=a"(discard),"=d"(ret)	\
+	     : "a"(a), "g"(b)		\
+	     : "cc");			\
+	ret;			})
+#   define BN_UMULT_LOHI(low,high,a,b)	\
+	asm ("mulq	%3"		\
+		: "=a"(low),"=d"(high)	\
+		: "a"(a),"g"(b)		\
+		: "cc");
+#  endif
+# elif (defined(_M_AMD64) || defined(_M_X64)) && defined(SIXTY_FOUR_BIT)
+#  if defined(_MSC_VER) && _MSC_VER>=1400
+    unsigned __int64 __umulh	(unsigned __int64 a,unsigned __int64 b);
+    unsigned __int64 _umul128	(unsigned __int64 a,unsigned __int64 b,
+				 unsigned __int64 *h);
+#   pragma intrinsic(__umulh,_umul128)
+#   define BN_UMULT_HIGH(a,b)		__umulh((a),(b))
+#   define BN_UMULT_LOHI(low,high,a,b)	((low)=_umul128((a),(b),&(high)))
+#  endif
+# endif		/* cpu */
+#endif		/* OPENSSL_NO_ASM */
+
+/*************************************************************
+ * Using the long long type
+ */
+#define Lw(t)    (((BN_ULONG)(t))&BN_MASK2)
+#define Hw(t)    (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
+
+#ifdef BN_DEBUG_RAND
+#define bn_clear_top2max(a) \
+	{ \
+	int      ind = (a)->dmax - (a)->top; \
+	BN_ULONG *ftl = &(a)->d[(a)->top-1]; \
+	for (; ind != 0; ind--) \
+		*(++ftl) = 0x0; \
+	}
+#else
+#define bn_clear_top2max(a)
+#endif
+
+#ifdef BN_LLONG
+#define mul_add(r,a,w,c) { \
+	BN_ULLONG t; \
+	t=(BN_ULLONG)w * (a) + (r) + (c); \
+	(r)= Lw(t); \
+	(c)= Hw(t); \
+	}
+
+#define mul(r,a,w,c) { \
+	BN_ULLONG t; \
+	t=(BN_ULLONG)w * (a) + (c); \
+	(r)= Lw(t); \
+	(c)= Hw(t); \
+	}
+
+#define sqr(r0,r1,a) { \
+	BN_ULLONG t; \
+	t=(BN_ULLONG)(a)*(a); \
+	(r0)=Lw(t); \
+	(r1)=Hw(t); \
+	}
+
+#elif defined(BN_UMULT_LOHI)
+#define mul_add(r,a,w,c) {		\
+	BN_ULONG high,low,ret,tmp=(a);	\
+	ret =  (r);			\
+	BN_UMULT_LOHI(low,high,w,tmp);	\
+	ret += (c);			\
+	(c) =  (ret<(c))?1:0;		\
+	(c) += high;			\
+	ret += low;			\
+	(c) += (ret<low)?1:0;		\
+	(r) =  ret;			\
+	}
+
+#define mul(r,a,w,c)	{		\
+	BN_ULONG high,low,ret,ta=(a);	\
+	BN_UMULT_LOHI(low,high,w,ta);	\
+	ret =  low + (c);		\
+	(c) =  high;			\
+	(c) += (ret<low)?1:0;		\
+	(r) =  ret;			\
+	}
+
+#define sqr(r0,r1,a)	{		\
+	BN_ULONG tmp=(a);		\
+	BN_UMULT_LOHI(r0,r1,tmp,tmp);	\
+	}
+
+#elif defined(BN_UMULT_HIGH)
+#define mul_add(r,a,w,c) {		\
+	BN_ULONG high,low,ret,tmp=(a);	\
+	ret =  (r);			\
+	high=  BN_UMULT_HIGH(w,tmp);	\
+	ret += (c);			\
+	low =  (w) * tmp;		\
+	(c) =  (ret<(c))?1:0;		\
+	(c) += high;			\
+	ret += low;			\
+	(c) += (ret<low)?1:0;		\
+	(r) =  ret;			\
+	}
+
+#define mul(r,a,w,c)	{		\
+	BN_ULONG high,low,ret,ta=(a);	\
+	low =  (w) * ta;		\
+	high=  BN_UMULT_HIGH(w,ta);	\
+	ret =  low + (c);		\
+	(c) =  high;			\
+	(c) += (ret<low)?1:0;		\
+	(r) =  ret;			\
+	}
+
+#define sqr(r0,r1,a)	{		\
+	BN_ULONG tmp=(a);		\
+	(r0) = tmp * tmp;		\
+	(r1) = BN_UMULT_HIGH(tmp,tmp);	\
+	}
+
+#else
+/*************************************************************
+ * No long long type
+ */
+
+#define LBITS(a)	((a)&BN_MASK2l)
+#define HBITS(a)	(((a)>>BN_BITS4)&BN_MASK2l)
+#define	L2HBITS(a)	(((a)<<BN_BITS4)&BN_MASK2)
+
+#define LLBITS(a)	((a)&BN_MASKl)
+#define LHBITS(a)	(((a)>>BN_BITS2)&BN_MASKl)
+#define	LL2HBITS(a)	((BN_ULLONG)((a)&BN_MASKl)<<BN_BITS2)
+
+#define mul64(l,h,bl,bh) \
+	{ \
+	BN_ULONG m,m1,lt,ht; \
+ \
+	lt=l; \
+	ht=h; \
+	m =(bh)*(lt); \
+	lt=(bl)*(lt); \
+	m1=(bl)*(ht); \
+	ht =(bh)*(ht); \
+	m=(m+m1)&BN_MASK2; if (m < m1) ht+=L2HBITS((BN_ULONG)1); \
+	ht+=HBITS(m); \
+	m1=L2HBITS(m); \
+	lt=(lt+m1)&BN_MASK2; if (lt < m1) ht++; \
+	(l)=lt; \
+	(h)=ht; \
+	}
+
+#define sqr64(lo,ho,in) \
+	{ \
+	BN_ULONG l,h,m; \
+ \
+	h=(in); \
+	l=LBITS(h); \
+	h=HBITS(h); \
+	m =(l)*(h); \
+	l*=l; \
+	h*=h; \
+	h+=(m&BN_MASK2h1)>>(BN_BITS4-1); \
+	m =(m&BN_MASK2l)<<(BN_BITS4+1); \
+	l=(l+m)&BN_MASK2; if (l < m) h++; \
+	(lo)=l; \
+	(ho)=h; \
+	}
+
+#define mul_add(r,a,bl,bh,c) { \
+	BN_ULONG l,h; \
+ \
+	h= (a); \
+	l=LBITS(h); \
+	h=HBITS(h); \
+	mul64(l,h,(bl),(bh)); \
+ \
+	/* non-multiply part */ \
+	l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+	(c)=(r); \
+	l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+	(c)=h&BN_MASK2; \
+	(r)=l; \
+	}
+
+#define mul(r,a,bl,bh,c) { \
+	BN_ULONG l,h; \
+ \
+	h= (a); \
+	l=LBITS(h); \
+	h=HBITS(h); \
+	mul64(l,h,(bl),(bh)); \
+ \
+	/* non-multiply part */ \
+	l+=(c); if ((l&BN_MASK2) < (c)) h++; \
+	(c)=h&BN_MASK2; \
+	(r)=l&BN_MASK2; \
+	}
+#endif /* !BN_LLONG */
+
+void bn_mul_normal(BN_ULONG *r,BN_ULONG *a,int na,BN_ULONG *b,int nb);
+void bn_mul_comba8(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
+void bn_mul_comba4(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
+void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp);
+void bn_sqr_comba8(BN_ULONG *r,const BN_ULONG *a);
+void bn_sqr_comba4(BN_ULONG *r,const BN_ULONG *a);
+int bn_cmp_words(const BN_ULONG *a,const BN_ULONG *b,int n);
+int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
+	int cl, int dl);
+void bn_mul_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,
+	int dna,int dnb,BN_ULONG *t);
+void bn_mul_part_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,
+	int n,int tna,int tnb,BN_ULONG *t);
+void bn_sqr_recursive(BN_ULONG *r,const BN_ULONG *a, int n2, BN_ULONG *t);
+void bn_mul_low_normal(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, int n);
+void bn_mul_low_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,
+	BN_ULONG *t);
+void bn_mul_high(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,BN_ULONG *l,int n2,
+	BN_ULONG *t);
+BN_ULONG bn_add_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+	int cl, int dl);
+BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+	int cl, int dl);
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/bn/bn_lib.c b/openssl/crypto/bn/bn_lib.c
new file mode 100644
index 0000000..5470fbe
--- /dev/null
+++ b/openssl/crypto/bn/bn_lib.c
@@ -0,0 +1,845 @@
+/* crypto/bn/bn_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef BN_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+const char BN_version[]="Big Number" OPENSSL_VERSION_PTEXT;
+
+/* This stuff appears to be completely unused, so is deprecated */
+#ifndef OPENSSL_NO_DEPRECATED
+/* For a 32 bit machine
+ * 2 -   4 ==  128
+ * 3 -   8 ==  256
+ * 4 -  16 ==  512
+ * 5 -  32 == 1024
+ * 6 -  64 == 2048
+ * 7 - 128 == 4096
+ * 8 - 256 == 8192
+ */
+static int bn_limit_bits=0;
+static int bn_limit_num=8;        /* (1<<bn_limit_bits) */
+static int bn_limit_bits_low=0;
+static int bn_limit_num_low=8;    /* (1<<bn_limit_bits_low) */
+static int bn_limit_bits_high=0;
+static int bn_limit_num_high=8;   /* (1<<bn_limit_bits_high) */
+static int bn_limit_bits_mont=0;
+static int bn_limit_num_mont=8;   /* (1<<bn_limit_bits_mont) */
+
+void BN_set_params(int mult, int high, int low, int mont)
+	{
+	if (mult >= 0)
+		{
+		if (mult > (int)(sizeof(int)*8)-1)
+			mult=sizeof(int)*8-1;
+		bn_limit_bits=mult;
+		bn_limit_num=1<<mult;
+		}
+	if (high >= 0)
+		{
+		if (high > (int)(sizeof(int)*8)-1)
+			high=sizeof(int)*8-1;
+		bn_limit_bits_high=high;
+		bn_limit_num_high=1<<high;
+		}
+	if (low >= 0)
+		{
+		if (low > (int)(sizeof(int)*8)-1)
+			low=sizeof(int)*8-1;
+		bn_limit_bits_low=low;
+		bn_limit_num_low=1<<low;
+		}
+	if (mont >= 0)
+		{
+		if (mont > (int)(sizeof(int)*8)-1)
+			mont=sizeof(int)*8-1;
+		bn_limit_bits_mont=mont;
+		bn_limit_num_mont=1<<mont;
+		}
+	}
+
+int BN_get_params(int which)
+	{
+	if      (which == 0) return(bn_limit_bits);
+	else if (which == 1) return(bn_limit_bits_high);
+	else if (which == 2) return(bn_limit_bits_low);
+	else if (which == 3) return(bn_limit_bits_mont);
+	else return(0);
+	}
+#endif
+
+const BIGNUM *BN_value_one(void)
+	{
+	static const BN_ULONG data_one=1L;
+	static const BIGNUM const_one={(BN_ULONG *)&data_one,1,1,0,BN_FLG_STATIC_DATA};
+
+	return(&const_one);
+	}
+
+char *BN_options(void)
+	{
+	static int init=0;
+	static char data[16];
+
+	if (!init)
+		{
+		init++;
+#ifdef BN_LLONG
+		BIO_snprintf(data,sizeof data,"bn(%d,%d)",
+			     (int)sizeof(BN_ULLONG)*8,(int)sizeof(BN_ULONG)*8);
+#else
+		BIO_snprintf(data,sizeof data,"bn(%d,%d)",
+			     (int)sizeof(BN_ULONG)*8,(int)sizeof(BN_ULONG)*8);
+#endif
+		}
+	return(data);
+	}
+
+int BN_num_bits_word(BN_ULONG l)
+	{
+	static const unsigned char bits[256]={
+		0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
+		5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+		6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+		6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+		};
+
+#if defined(SIXTY_FOUR_BIT_LONG)
+	if (l & 0xffffffff00000000L)
+		{
+		if (l & 0xffff000000000000L)
+			{
+			if (l & 0xff00000000000000L)
+				{
+				return(bits[(int)(l>>56)]+56);
+				}
+			else	return(bits[(int)(l>>48)]+48);
+			}
+		else
+			{
+			if (l & 0x0000ff0000000000L)
+				{
+				return(bits[(int)(l>>40)]+40);
+				}
+			else	return(bits[(int)(l>>32)]+32);
+			}
+		}
+	else
+#else
+#ifdef SIXTY_FOUR_BIT
+	if (l & 0xffffffff00000000LL)
+		{
+		if (l & 0xffff000000000000LL)
+			{
+			if (l & 0xff00000000000000LL)
+				{
+				return(bits[(int)(l>>56)]+56);
+				}
+			else	return(bits[(int)(l>>48)]+48);
+			}
+		else
+			{
+			if (l & 0x0000ff0000000000LL)
+				{
+				return(bits[(int)(l>>40)]+40);
+				}
+			else	return(bits[(int)(l>>32)]+32);
+			}
+		}
+	else
+#endif
+#endif
+		{
+#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+		if (l & 0xffff0000L)
+			{
+			if (l & 0xff000000L)
+				return(bits[(int)(l>>24L)]+24);
+			else	return(bits[(int)(l>>16L)]+16);
+			}
+		else
+#endif
+			{
+#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+			if (l & 0xff00L)
+				return(bits[(int)(l>>8)]+8);
+			else	
+#endif
+				return(bits[(int)(l   )]  );
+			}
+		}
+	}
+
+int BN_num_bits(const BIGNUM *a)
+	{
+	int i = a->top - 1;
+	bn_check_top(a);
+
+	if (BN_is_zero(a)) return 0;
+	return ((i*BN_BITS2) + BN_num_bits_word(a->d[i]));
+	}
+
+void BN_clear_free(BIGNUM *a)
+	{
+	int i;
+
+	if (a == NULL) return;
+	bn_check_top(a);
+	if (a->d != NULL)
+		{
+		OPENSSL_cleanse(a->d,a->dmax*sizeof(a->d[0]));
+		if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
+			OPENSSL_free(a->d);
+		}
+	i=BN_get_flags(a,BN_FLG_MALLOCED);
+	OPENSSL_cleanse(a,sizeof(BIGNUM));
+	if (i)
+		OPENSSL_free(a);
+	}
+
+void BN_free(BIGNUM *a)
+	{
+	if (a == NULL) return;
+	bn_check_top(a);
+	if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
+		OPENSSL_free(a->d);
+	if (a->flags & BN_FLG_MALLOCED)
+		OPENSSL_free(a);
+	else
+		{
+#ifndef OPENSSL_NO_DEPRECATED
+		a->flags|=BN_FLG_FREE;
+#endif
+		a->d = NULL;
+		}
+	}
+
+void BN_init(BIGNUM *a)
+	{
+	memset(a,0,sizeof(BIGNUM));
+	bn_check_top(a);
+	}
+
+BIGNUM *BN_new(void)
+	{
+	BIGNUM *ret;
+
+	if ((ret=(BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL)
+		{
+		BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	ret->flags=BN_FLG_MALLOCED;
+	ret->top=0;
+	ret->neg=0;
+	ret->dmax=0;
+	ret->d=NULL;
+	bn_check_top(ret);
+	return(ret);
+	}
+
+/* This is used both by bn_expand2() and bn_dup_expand() */
+/* The caller MUST check that words > b->dmax before calling this */
+static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
+	{
+	BN_ULONG *A,*a = NULL;
+	const BN_ULONG *B;
+	int i;
+
+	bn_check_top(b);
+
+	if (words > (INT_MAX/(4*BN_BITS2)))
+		{
+		BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_BIGNUM_TOO_LONG);
+		return NULL;
+		}
+	if (BN_get_flags(b,BN_FLG_STATIC_DATA))
+		{
+		BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
+		return(NULL);
+		}
+	a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*words);
+	if (A == NULL)
+		{
+		BNerr(BN_F_BN_EXPAND_INTERNAL,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+#if 1
+	B=b->d;
+	/* Check if the previous number needs to be copied */
+	if (B != NULL)
+		{
+		for (i=b->top>>2; i>0; i--,A+=4,B+=4)
+			{
+			/*
+			 * The fact that the loop is unrolled
+			 * 4-wise is a tribute to Intel. It's
+			 * the one that doesn't have enough
+			 * registers to accomodate more data.
+			 * I'd unroll it 8-wise otherwise:-)
+			 *
+			 *		<appro@fy.chalmers.se>
+			 */
+			BN_ULONG a0,a1,a2,a3;
+			a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
+			A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
+			}
+		switch (b->top&3)
+			{
+		case 3:	A[2]=B[2];
+		case 2:	A[1]=B[1];
+		case 1:	A[0]=B[0];
+		case 0: /* workaround for ultrix cc: without 'case 0', the optimizer does
+		         * the switch table by doing a=top&3; a--; goto jump_table[a];
+		         * which fails for top== 0 */
+			;
+			}
+		}
+
+#else
+	memset(A,0,sizeof(BN_ULONG)*words);
+	memcpy(A,b->d,sizeof(b->d[0])*b->top);
+#endif
+		
+	return(a);
+	}
+
+/* This is an internal function that can be used instead of bn_expand2()
+ * when there is a need to copy BIGNUMs instead of only expanding the
+ * data part, while still expanding them.
+ * Especially useful when needing to expand BIGNUMs that are declared
+ * 'const' and should therefore not be changed.
+ * The reason to use this instead of a BN_dup() followed by a bn_expand2()
+ * is memory allocation overhead.  A BN_dup() followed by a bn_expand2()
+ * will allocate new memory for the BIGNUM data twice, and free it once,
+ * while bn_dup_expand() makes sure allocation is made only once.
+ */
+
+#ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
+	{
+	BIGNUM *r = NULL;
+
+	bn_check_top(b);
+
+	/* This function does not work if
+	 *      words <= b->dmax && top < words
+	 * because BN_dup() does not preserve 'dmax'!
+	 * (But bn_dup_expand() is not used anywhere yet.)
+	 */
+
+	if (words > b->dmax)
+		{
+		BN_ULONG *a = bn_expand_internal(b, words);
+
+		if (a)
+			{
+			r = BN_new();
+			if (r)
+				{
+				r->top = b->top;
+				r->dmax = words;
+				r->neg = b->neg;
+				r->d = a;
+				}
+			else
+				{
+				/* r == NULL, BN_new failure */
+				OPENSSL_free(a);
+				}
+			}
+		/* If a == NULL, there was an error in allocation in
+		   bn_expand_internal(), and NULL should be returned */
+		}
+	else
+		{
+		r = BN_dup(b);
+		}
+
+	bn_check_top(r);
+	return r;
+	}
+#endif
+
+/* This is an internal function that should not be used in applications.
+ * It ensures that 'b' has enough room for a 'words' word number
+ * and initialises any unused part of b->d with leading zeros.
+ * It is mostly used by the various BIGNUM routines. If there is an error,
+ * NULL is returned. If not, 'b' is returned. */
+
+BIGNUM *bn_expand2(BIGNUM *b, int words)
+	{
+	bn_check_top(b);
+
+	if (words > b->dmax)
+		{
+		BN_ULONG *a = bn_expand_internal(b, words);
+		if(!a) return NULL;
+		if(b->d) OPENSSL_free(b->d);
+		b->d=a;
+		b->dmax=words;
+		}
+
+/* None of this should be necessary because of what b->top means! */
+#if 0
+	/* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */
+	if (b->top < b->dmax)
+		{
+		int i;
+		BN_ULONG *A = &(b->d[b->top]);
+		for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8)
+			{
+			A[0]=0; A[1]=0; A[2]=0; A[3]=0;
+			A[4]=0; A[5]=0; A[6]=0; A[7]=0;
+			}
+		for (i=(b->dmax - b->top)&7; i>0; i--,A++)
+			A[0]=0;
+		assert(A == &(b->d[b->dmax]));
+		}
+#endif
+	bn_check_top(b);
+	return b;
+	}
+
+BIGNUM *BN_dup(const BIGNUM *a)
+	{
+	BIGNUM *t;
+
+	if (a == NULL) return NULL;
+	bn_check_top(a);
+
+	t = BN_new();
+	if (t == NULL) return NULL;
+	if(!BN_copy(t, a))
+		{
+		BN_free(t);
+		return NULL;
+		}
+	bn_check_top(t);
+	return t;
+	}
+
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
+	{
+	int i;
+	BN_ULONG *A;
+	const BN_ULONG *B;
+
+	bn_check_top(b);
+
+	if (a == b) return(a);
+	if (bn_wexpand(a,b->top) == NULL) return(NULL);
+
+#if 1
+	A=a->d;
+	B=b->d;
+	for (i=b->top>>2; i>0; i--,A+=4,B+=4)
+		{
+		BN_ULONG a0,a1,a2,a3;
+		a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
+		A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
+		}
+	switch (b->top&3)
+		{
+		case 3: A[2]=B[2];
+		case 2: A[1]=B[1];
+		case 1: A[0]=B[0];
+		case 0: ; /* ultrix cc workaround, see comments in bn_expand_internal */
+		}
+#else
+	memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
+#endif
+
+	a->top=b->top;
+	a->neg=b->neg;
+	bn_check_top(a);
+	return(a);
+	}
+
+void BN_swap(BIGNUM *a, BIGNUM *b)
+	{
+	int flags_old_a, flags_old_b;
+	BN_ULONG *tmp_d;
+	int tmp_top, tmp_dmax, tmp_neg;
+	
+	bn_check_top(a);
+	bn_check_top(b);
+
+	flags_old_a = a->flags;
+	flags_old_b = b->flags;
+
+	tmp_d = a->d;
+	tmp_top = a->top;
+	tmp_dmax = a->dmax;
+	tmp_neg = a->neg;
+	
+	a->d = b->d;
+	a->top = b->top;
+	a->dmax = b->dmax;
+	a->neg = b->neg;
+	
+	b->d = tmp_d;
+	b->top = tmp_top;
+	b->dmax = tmp_dmax;
+	b->neg = tmp_neg;
+	
+	a->flags = (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
+	b->flags = (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
+	bn_check_top(a);
+	bn_check_top(b);
+	}
+
+void BN_clear(BIGNUM *a)
+	{
+	bn_check_top(a);
+	if (a->d != NULL)
+		memset(a->d,0,a->dmax*sizeof(a->d[0]));
+	a->top=0;
+	a->neg=0;
+	}
+
+BN_ULONG BN_get_word(const BIGNUM *a)
+	{
+	if (a->top > 1)
+		return BN_MASK2;
+	else if (a->top == 1)
+		return a->d[0];
+	/* a->top == 0 */
+	return 0;
+	}
+
+int BN_set_word(BIGNUM *a, BN_ULONG w)
+	{
+	bn_check_top(a);
+	if (bn_expand(a,(int)sizeof(BN_ULONG)*8) == NULL) return(0);
+	a->neg = 0;
+	a->d[0] = w;
+	a->top = (w ? 1 : 0);
+	bn_check_top(a);
+	return(1);
+	}
+
+BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
+	{
+	unsigned int i,m;
+	unsigned int n;
+	BN_ULONG l;
+	BIGNUM  *bn = NULL;
+
+	if (ret == NULL)
+		ret = bn = BN_new();
+	if (ret == NULL) return(NULL);
+	bn_check_top(ret);
+	l=0;
+	n=len;
+	if (n == 0)
+		{
+		ret->top=0;
+		return(ret);
+		}
+	i=((n-1)/BN_BYTES)+1;
+	m=((n-1)%(BN_BYTES));
+	if (bn_wexpand(ret, (int)i) == NULL)
+		{
+		if (bn) BN_free(bn);
+		return NULL;
+		}
+	ret->top=i;
+	ret->neg=0;
+	while (n--)
+		{
+		l=(l<<8L)| *(s++);
+		if (m-- == 0)
+			{
+			ret->d[--i]=l;
+			l=0;
+			m=BN_BYTES-1;
+			}
+		}
+	/* need to call this due to clear byte at top if avoiding
+	 * having the top bit set (-ve number) */
+	bn_correct_top(ret);
+	return(ret);
+	}
+
+/* ignore negative */
+int BN_bn2bin(const BIGNUM *a, unsigned char *to)
+	{
+	int n,i;
+	BN_ULONG l;
+
+	bn_check_top(a);
+	n=i=BN_num_bytes(a);
+	while (i--)
+		{
+		l=a->d[i/BN_BYTES];
+		*(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
+		}
+	return(n);
+	}
+
+int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
+	{
+	int i;
+	BN_ULONG t1,t2,*ap,*bp;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	i=a->top-b->top;
+	if (i != 0) return(i);
+	ap=a->d;
+	bp=b->d;
+	for (i=a->top-1; i>=0; i--)
+		{
+		t1= ap[i];
+		t2= bp[i];
+		if (t1 != t2)
+			return((t1 > t2) ? 1 : -1);
+		}
+	return(0);
+	}
+
+int BN_cmp(const BIGNUM *a, const BIGNUM *b)
+	{
+	int i;
+	int gt,lt;
+	BN_ULONG t1,t2;
+
+	if ((a == NULL) || (b == NULL))
+		{
+		if (a != NULL)
+			return(-1);
+		else if (b != NULL)
+			return(1);
+		else
+			return(0);
+		}
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	if (a->neg != b->neg)
+		{
+		if (a->neg)
+			return(-1);
+		else	return(1);
+		}
+	if (a->neg == 0)
+		{ gt=1; lt= -1; }
+	else	{ gt= -1; lt=1; }
+
+	if (a->top > b->top) return(gt);
+	if (a->top < b->top) return(lt);
+	for (i=a->top-1; i>=0; i--)
+		{
+		t1=a->d[i];
+		t2=b->d[i];
+		if (t1 > t2) return(gt);
+		if (t1 < t2) return(lt);
+		}
+	return(0);
+	}
+
+int BN_set_bit(BIGNUM *a, int n)
+	{
+	int i,j,k;
+
+	if (n < 0)
+		return 0;
+
+	i=n/BN_BITS2;
+	j=n%BN_BITS2;
+	if (a->top <= i)
+		{
+		if (bn_wexpand(a,i+1) == NULL) return(0);
+		for(k=a->top; k<i+1; k++)
+			a->d[k]=0;
+		a->top=i+1;
+		}
+
+	a->d[i]|=(((BN_ULONG)1)<<j);
+	bn_check_top(a);
+	return(1);
+	}
+
+int BN_clear_bit(BIGNUM *a, int n)
+	{
+	int i,j;
+
+	bn_check_top(a);
+	if (n < 0) return 0;
+
+	i=n/BN_BITS2;
+	j=n%BN_BITS2;
+	if (a->top <= i) return(0);
+
+	a->d[i]&=(~(((BN_ULONG)1)<<j));
+	bn_correct_top(a);
+	return(1);
+	}
+
+int BN_is_bit_set(const BIGNUM *a, int n)
+	{
+	int i,j;
+
+	bn_check_top(a);
+	if (n < 0) return 0;
+	i=n/BN_BITS2;
+	j=n%BN_BITS2;
+	if (a->top <= i) return 0;
+	return (int)(((a->d[i])>>j)&((BN_ULONG)1));
+	}
+
+int BN_mask_bits(BIGNUM *a, int n)
+	{
+	int b,w;
+
+	bn_check_top(a);
+	if (n < 0) return 0;
+
+	w=n/BN_BITS2;
+	b=n%BN_BITS2;
+	if (w >= a->top) return 0;
+	if (b == 0)
+		a->top=w;
+	else
+		{
+		a->top=w+1;
+		a->d[w]&= ~(BN_MASK2<<b);
+		}
+	bn_correct_top(a);
+	return(1);
+	}
+
+void BN_set_negative(BIGNUM *a, int b)
+	{
+	if (b && !BN_is_zero(a))
+		a->neg = 1;
+	else
+		a->neg = 0;
+	}
+
+int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
+	{
+	int i;
+	BN_ULONG aa,bb;
+
+	aa=a[n-1];
+	bb=b[n-1];
+	if (aa != bb) return((aa > bb)?1:-1);
+	for (i=n-2; i>=0; i--)
+		{
+		aa=a[i];
+		bb=b[i];
+		if (aa != bb) return((aa > bb)?1:-1);
+		}
+	return(0);
+	}
+
+/* Here follows a specialised variants of bn_cmp_words().  It has the
+   property of performing the operation on arrays of different sizes.
+   The sizes of those arrays is expressed through cl, which is the
+   common length ( basicall, min(len(a),len(b)) ), and dl, which is the
+   delta between the two lengths, calculated as len(a)-len(b).
+   All lengths are the number of BN_ULONGs...  */
+
+int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
+	int cl, int dl)
+	{
+	int n,i;
+	n = cl-1;
+
+	if (dl < 0)
+		{
+		for (i=dl; i<0; i++)
+			{
+			if (b[n-i] != 0)
+				return -1; /* a < b */
+			}
+		}
+	if (dl > 0)
+		{
+		for (i=dl; i>0; i--)
+			{
+			if (a[n+i] != 0)
+				return 1; /* a > b */
+			}
+		}
+	return bn_cmp_words(a,b,cl);
+	}
diff --git a/openssl/crypto/bn/bn_mod.c b/openssl/crypto/bn/bn_mod.c
new file mode 100644
index 0000000..77d6ddb
--- /dev/null
+++ b/openssl/crypto/bn/bn_mod.c
@@ -0,0 +1,301 @@
+/* crypto/bn/bn_mod.c */
+/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
+ * for the OpenSSL project. */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+
+#if 0 /* now just a #define */
+int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
+	{
+	return(BN_div(NULL,rem,m,d,ctx));
+	/* note that  rem->neg == m->neg  (unless the remainder is zero) */
+	}
+#endif
+
+
+int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
+	{
+	/* like BN_mod, but returns non-negative remainder
+	 * (i.e.,  0 <= r < |d|  always holds) */
+
+	if (!(BN_mod(r,m,d,ctx)))
+		return 0;
+	if (!r->neg)
+		return 1;
+	/* now   -|d| < r < 0,  so we have to set  r := r + |d| */
+	return (d->neg ? BN_sub : BN_add)(r, r, d);
+}
+
+
+int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)
+	{
+	if (!BN_add(r, a, b)) return 0;
+	return BN_nnmod(r, r, m, ctx);
+	}
+
+
+/* BN_mod_add variant that may be used if both  a  and  b  are non-negative
+ * and less than  m */
+int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m)
+	{
+	if (!BN_uadd(r, a, b)) return 0;
+	if (BN_ucmp(r, m) >= 0)
+		return BN_usub(r, r, m);
+	return 1;
+	}
+
+
+int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)
+	{
+	if (!BN_sub(r, a, b)) return 0;
+	return BN_nnmod(r, r, m, ctx);
+	}
+
+
+/* BN_mod_sub variant that may be used if both  a  and  b  are non-negative
+ * and less than  m */
+int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m)
+	{
+	if (!BN_sub(r, a, b)) return 0;
+	if (r->neg)
+		return BN_add(r, r, m);
+	return 1;
+	}
+
+
+/* slow but works */
+int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+	BN_CTX *ctx)
+	{
+	BIGNUM *t;
+	int ret=0;
+
+	bn_check_top(a);
+	bn_check_top(b);
+	bn_check_top(m);
+
+	BN_CTX_start(ctx);
+	if ((t = BN_CTX_get(ctx)) == NULL) goto err;
+	if (a == b)
+		{ if (!BN_sqr(t,a,ctx)) goto err; }
+	else
+		{ if (!BN_mul(t,a,b,ctx)) goto err; }
+	if (!BN_nnmod(r,t,m,ctx)) goto err;
+	bn_check_top(r);
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	return(ret);
+	}
+
+
+int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
+	{
+	if (!BN_sqr(r, a, ctx)) return 0;
+	/* r->neg == 0,  thus we don't need BN_nnmod */
+	return BN_mod(r, r, m, ctx);
+	}
+
+
+int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
+	{
+	if (!BN_lshift1(r, a)) return 0;
+	bn_check_top(r);
+	return BN_nnmod(r, r, m, ctx);
+	}
+
+
+/* BN_mod_lshift1 variant that may be used if  a  is non-negative
+ * and less than  m */
+int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m)
+	{
+	if (!BN_lshift1(r, a)) return 0;
+	bn_check_top(r);
+	if (BN_cmp(r, m) >= 0)
+		return BN_sub(r, r, m);
+	return 1;
+	}
+
+
+int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx)
+	{
+	BIGNUM *abs_m = NULL;
+	int ret;
+
+	if (!BN_nnmod(r, a, m, ctx)) return 0;
+
+	if (m->neg)
+		{
+		abs_m = BN_dup(m);
+		if (abs_m == NULL) return 0;
+		abs_m->neg = 0;
+		}
+	
+	ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m));
+	bn_check_top(r);
+
+	if (abs_m)
+		BN_free(abs_m);
+	return ret;
+	}
+
+
+/* BN_mod_lshift variant that may be used if  a  is non-negative
+ * and less than  m */
+int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m)
+	{
+	if (r != a)
+		{
+		if (BN_copy(r, a) == NULL) return 0;
+		}
+
+	while (n > 0)
+		{
+		int max_shift;
+		
+		/* 0 < r < m */
+		max_shift = BN_num_bits(m) - BN_num_bits(r);
+		/* max_shift >= 0 */
+
+		if (max_shift < 0)
+			{
+			BNerr(BN_F_BN_MOD_LSHIFT_QUICK, BN_R_INPUT_NOT_REDUCED);
+			return 0;
+			}
+
+		if (max_shift > n)
+			max_shift = n;
+
+		if (max_shift)
+			{
+			if (!BN_lshift(r, r, max_shift)) return 0;
+			n -= max_shift;
+			}
+		else
+			{
+			if (!BN_lshift1(r, r)) return 0;
+			--n;
+			}
+
+		/* BN_num_bits(r) <= BN_num_bits(m) */
+
+		if (BN_cmp(r, m) >= 0) 
+			{
+			if (!BN_sub(r, r, m)) return 0;
+			}
+		}
+	bn_check_top(r);
+	
+	return 1;
+	}
diff --git a/openssl/crypto/bn/bn_mont.c b/openssl/crypto/bn/bn_mont.c
new file mode 100644
index 0000000..1a86688
--- /dev/null
+++ b/openssl/crypto/bn/bn_mont.c
@@ -0,0 +1,567 @@
+/* crypto/bn/bn_mont.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+ * Details about Montgomery multiplication algorithms can be found at
+ * http://security.ece.orst.edu/publications.html, e.g.
+ * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and
+ * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#define MONT_WORD /* use the faster word-based algorithm */
+
+#ifdef MONT_WORD
+static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
+#endif
+
+int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+			  BN_MONT_CTX *mont, BN_CTX *ctx)
+	{
+	BIGNUM *tmp;
+	int ret=0;
+#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)
+	int num = mont->N.top;
+
+	if (num>1 && a->top==num && b->top==num)
+		{
+		if (bn_wexpand(r,num) == NULL) return(0);
+		if (bn_mul_mont(r->d,a->d,b->d,mont->N.d,mont->n0,num))
+			{
+			r->neg = a->neg^b->neg;
+			r->top = num;
+			bn_correct_top(r);
+			return(1);
+			}
+		}
+#endif
+
+	BN_CTX_start(ctx);
+	tmp = BN_CTX_get(ctx);
+	if (tmp == NULL) goto err;
+
+	bn_check_top(tmp);
+	if (a == b)
+		{
+		if (!BN_sqr(tmp,a,ctx)) goto err;
+		}
+	else
+		{
+		if (!BN_mul(tmp,a,b,ctx)) goto err;
+		}
+	/* reduce from aRR to aR */
+#ifdef MONT_WORD
+	if (!BN_from_montgomery_word(r,tmp,mont)) goto err;
+#else
+	if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
+#endif
+	bn_check_top(r);
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	return(ret);
+	}
+
+#ifdef MONT_WORD
+static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
+	{
+	BIGNUM *n;
+	BN_ULONG *ap,*np,*rp,n0,v,*nrp;
+	int al,nl,max,i,x,ri;
+
+	n= &(mont->N);
+	/* mont->ri is the size of mont->N in bits (rounded up
+	   to the word size) */
+	al=ri=mont->ri/BN_BITS2;
+
+	nl=n->top;
+	if ((al == 0) || (nl == 0)) { ret->top=0; return(1); }
+
+	max=(nl+al+1); /* allow for overflow (no?) XXX */
+	if (bn_wexpand(r,max) == NULL) return(0);
+
+	r->neg^=n->neg;
+	np=n->d;
+	rp=r->d;
+	nrp= &(r->d[nl]);
+
+	/* clear the top words of T */
+#if 1
+	for (i=r->top; i<max; i++) /* memset? XXX */
+		r->d[i]=0;
+#else
+	memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); 
+#endif
+
+	r->top=max;
+	n0=mont->n0[0];
+
+#ifdef BN_COUNT
+	fprintf(stderr,"word BN_from_montgomery_word %d * %d\n",nl,nl);
+#endif
+	for (i=0; i<nl; i++)
+		{
+#ifdef __TANDEM
+                {
+                   long long t1;
+                   long long t2;
+                   long long t3;
+                   t1 = rp[0] * (n0 & 0177777);
+                   t2 = 037777600000l;
+                   t2 = n0 & t2;
+                   t3 = rp[0] & 0177777;
+                   t2 = (t3 * t2) & BN_MASK2;
+                   t1 = t1 + t2;
+                   v=bn_mul_add_words(rp,np,nl,(BN_ULONG) t1);
+                }
+#else
+		v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
+#endif
+		nrp++;
+		rp++;
+		if (((nrp[-1]+=v)&BN_MASK2) >= v)
+			continue;
+		else
+			{
+			if (((++nrp[0])&BN_MASK2) != 0) continue;
+			if (((++nrp[1])&BN_MASK2) != 0) continue;
+			for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ;
+			}
+		}
+	bn_correct_top(r);
+
+	/* mont->ri will be a multiple of the word size and below code
+	 * is kind of BN_rshift(ret,r,mont->ri) equivalent */
+	if (r->top <= ri)
+		{
+		ret->top=0;
+		return(1);
+		}
+	al=r->top-ri;
+
+#define BRANCH_FREE 1
+#if BRANCH_FREE
+	if (bn_wexpand(ret,ri) == NULL) return(0);
+	x=0-(((al-ri)>>(sizeof(al)*8-1))&1);
+	ret->top=x=(ri&~x)|(al&x);	/* min(ri,al) */
+	ret->neg=r->neg;
+
+	rp=ret->d;
+	ap=&(r->d[ri]);
+
+	{
+	size_t m1,m2;
+
+	v=bn_sub_words(rp,ap,np,ri);
+	/* this ----------------^^ works even in al<ri case
+	 * thanks to zealous zeroing of top of the vector in the
+	 * beginning. */
+
+	/* if (al==ri && !v) || al>ri) nrp=rp; else nrp=ap; */
+	/* in other words if subtraction result is real, then
+	 * trick unconditional memcpy below to perform in-place
+	 * "refresh" instead of actual copy. */
+	m1=0-(size_t)(((al-ri)>>(sizeof(al)*8-1))&1);	/* al<ri */
+	m2=0-(size_t)(((ri-al)>>(sizeof(al)*8-1))&1);	/* al>ri */
+	m1|=m2;			/* (al!=ri) */
+	m1|=(0-(size_t)v);	/* (al!=ri || v) */
+	m1&=~m2;		/* (al!=ri || v) && !al>ri */
+	nrp=(BN_ULONG *)(((PTR_SIZE_INT)rp&~m1)|((PTR_SIZE_INT)ap&m1));
+	}
+
+	/* 'i<ri' is chosen to eliminate dependency on input data, even
+	 * though it results in redundant copy in al<ri case. */
+	for (i=0,ri-=4; i<ri; i+=4)
+		{
+		BN_ULONG t1,t2,t3,t4;
+		
+		t1=nrp[i+0];
+		t2=nrp[i+1];
+		t3=nrp[i+2];	ap[i+0]=0;
+		t4=nrp[i+3];	ap[i+1]=0;
+		rp[i+0]=t1;	ap[i+2]=0;
+		rp[i+1]=t2;	ap[i+3]=0;
+		rp[i+2]=t3;
+		rp[i+3]=t4;
+		}
+	for (ri+=4; i<ri; i++)
+		rp[i]=nrp[i], ap[i]=0;
+	bn_correct_top(r);
+	bn_correct_top(ret);
+#else
+	if (bn_wexpand(ret,al) == NULL) return(0);
+	ret->top=al;
+	ret->neg=r->neg;
+
+	rp=ret->d;
+	ap=&(r->d[ri]);
+	al-=4;
+	for (i=0; i<al; i+=4)
+		{
+		BN_ULONG t1,t2,t3,t4;
+		
+		t1=ap[i+0];
+		t2=ap[i+1];
+		t3=ap[i+2];
+		t4=ap[i+3];
+		rp[i+0]=t1;
+		rp[i+1]=t2;
+		rp[i+2]=t3;
+		rp[i+3]=t4;
+		}
+	al+=4;
+	for (; i<al; i++)
+		rp[i]=ap[i];
+
+	if (BN_ucmp(ret, &(mont->N)) >= 0)
+		{
+		if (!BN_usub(ret,ret,&(mont->N))) return(0);
+		}
+#endif
+	bn_check_top(ret);
+
+	return(1);
+	}
+#endif	/* MONT_WORD */
+
+int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
+	     BN_CTX *ctx)
+	{
+	int retn=0;
+#ifdef MONT_WORD
+	BIGNUM *t;
+
+	BN_CTX_start(ctx);
+	if ((t = BN_CTX_get(ctx)) && BN_copy(t,a))
+		retn = BN_from_montgomery_word(ret,t,mont);
+	BN_CTX_end(ctx);
+#else /* !MONT_WORD */
+	BIGNUM *t1,*t2;
+
+	BN_CTX_start(ctx);
+	t1 = BN_CTX_get(ctx);
+	t2 = BN_CTX_get(ctx);
+	if (t1 == NULL || t2 == NULL) goto err;
+	
+	if (!BN_copy(t1,a)) goto err;
+	BN_mask_bits(t1,mont->ri);
+
+	if (!BN_mul(t2,t1,&mont->Ni,ctx)) goto err;
+	BN_mask_bits(t2,mont->ri);
+
+	if (!BN_mul(t1,t2,&mont->N,ctx)) goto err;
+	if (!BN_add(t2,a,t1)) goto err;
+	if (!BN_rshift(ret,t2,mont->ri)) goto err;
+
+	if (BN_ucmp(ret, &(mont->N)) >= 0)
+		{
+		if (!BN_usub(ret,ret,&(mont->N))) goto err;
+		}
+	retn=1;
+	bn_check_top(ret);
+ err:
+	BN_CTX_end(ctx);
+#endif /* MONT_WORD */
+	return(retn);
+	}
+
+BN_MONT_CTX *BN_MONT_CTX_new(void)
+	{
+	BN_MONT_CTX *ret;
+
+	if ((ret=(BN_MONT_CTX *)OPENSSL_malloc(sizeof(BN_MONT_CTX))) == NULL)
+		return(NULL);
+
+	BN_MONT_CTX_init(ret);
+	ret->flags=BN_FLG_MALLOCED;
+	return(ret);
+	}
+
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx)
+	{
+	ctx->ri=0;
+	BN_init(&(ctx->RR));
+	BN_init(&(ctx->N));
+	BN_init(&(ctx->Ni));
+	ctx->n0[0] = ctx->n0[1] = 0;
+	ctx->flags=0;
+	}
+
+void BN_MONT_CTX_free(BN_MONT_CTX *mont)
+	{
+	if(mont == NULL)
+	    return;
+
+	BN_free(&(mont->RR));
+	BN_free(&(mont->N));
+	BN_free(&(mont->Ni));
+	if (mont->flags & BN_FLG_MALLOCED)
+		OPENSSL_free(mont);
+	}
+
+int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
+	{
+	int ret = 0;
+	BIGNUM *Ri,*R;
+
+	BN_CTX_start(ctx);
+	if((Ri = BN_CTX_get(ctx)) == NULL) goto err;
+	R= &(mont->RR);					/* grab RR as a temp */
+	if (!BN_copy(&(mont->N),mod)) goto err;		/* Set N */
+	mont->N.neg = 0;
+
+#ifdef MONT_WORD
+		{
+		BIGNUM tmod;
+		BN_ULONG buf[2];
+
+		BN_init(&tmod);
+		tmod.d=buf;
+		tmod.dmax=2;
+		tmod.neg=0;
+
+		mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
+
+#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)
+		/* Only certain BN_BITS2<=32 platforms actually make use of
+		 * n0[1], and we could use the #else case (with a shorter R
+		 * value) for the others.  However, currently only the assembler
+		 * files do know which is which. */
+
+		BN_zero(R);
+		if (!(BN_set_bit(R,2*BN_BITS2))) goto err;
+
+								tmod.top=0;
+		if ((buf[0] = mod->d[0]))			tmod.top=1;
+		if ((buf[1] = mod->top>1 ? mod->d[1] : 0))	tmod.top=2;
+
+		if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL)
+			goto err;
+		if (!BN_lshift(Ri,Ri,2*BN_BITS2)) goto err; /* R*Ri */
+		if (!BN_is_zero(Ri))
+			{
+			if (!BN_sub_word(Ri,1)) goto err;
+			}
+		else /* if N mod word size == 1 */
+			{
+			if (bn_expand(Ri,(int)sizeof(BN_ULONG)*2) == NULL)
+				goto err;
+			/* Ri-- (mod double word size) */
+			Ri->neg=0;
+			Ri->d[0]=BN_MASK2;
+			Ri->d[1]=BN_MASK2;
+			Ri->top=2;
+			}
+		if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err;
+		/* Ni = (R*Ri-1)/N,
+		 * keep only couple of least significant words: */
+		mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
+		mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0;
+#else
+		BN_zero(R);
+		if (!(BN_set_bit(R,BN_BITS2))) goto err;	/* R */
+
+		buf[0]=mod->d[0]; /* tmod = N mod word size */
+		buf[1]=0;
+		tmod.top = buf[0] != 0 ? 1 : 0;
+							/* Ri = R^-1 mod N*/
+		if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL)
+			goto err;
+		if (!BN_lshift(Ri,Ri,BN_BITS2)) goto err; /* R*Ri */
+		if (!BN_is_zero(Ri))
+			{
+			if (!BN_sub_word(Ri,1)) goto err;
+			}
+		else /* if N mod word size == 1 */
+			{
+			if (!BN_set_word(Ri,BN_MASK2)) goto err;  /* Ri-- (mod word size) */
+			}
+		if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err;
+		/* Ni = (R*Ri-1)/N,
+		 * keep only least significant word: */
+		mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
+		mont->n0[1] = 0;
+#endif
+		}
+#else /* !MONT_WORD */
+		{ /* bignum version */
+		mont->ri=BN_num_bits(&mont->N);
+		BN_zero(R);
+		if (!BN_set_bit(R,mont->ri)) goto err;  /* R = 2^ri */
+		                                        /* Ri = R^-1 mod N*/
+		if ((BN_mod_inverse(Ri,R,&mont->N,ctx)) == NULL)
+			goto err;
+		if (!BN_lshift(Ri,Ri,mont->ri)) goto err; /* R*Ri */
+		if (!BN_sub_word(Ri,1)) goto err;
+							/* Ni = (R*Ri-1) / N */
+		if (!BN_div(&(mont->Ni),NULL,Ri,&mont->N,ctx)) goto err;
+		}
+#endif
+
+	/* setup RR for conversions */
+	BN_zero(&(mont->RR));
+	if (!BN_set_bit(&(mont->RR),mont->ri*2)) goto err;
+	if (!BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx)) goto err;
+
+	ret = 1;
+err:
+	BN_CTX_end(ctx);
+	return ret;
+	}
+
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
+	{
+	if (to == from) return(to);
+
+	if (!BN_copy(&(to->RR),&(from->RR))) return NULL;
+	if (!BN_copy(&(to->N),&(from->N))) return NULL;
+	if (!BN_copy(&(to->Ni),&(from->Ni))) return NULL;
+	to->ri=from->ri;
+	to->n0[0]=from->n0[0];
+	to->n0[1]=from->n0[1];
+	return(to);
+	}
+
+BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
+					const BIGNUM *mod, BN_CTX *ctx)
+	{
+	int got_write_lock = 0;
+	BN_MONT_CTX *ret;
+
+	CRYPTO_r_lock(lock);
+	if (!*pmont)
+		{
+		CRYPTO_r_unlock(lock);
+		CRYPTO_w_lock(lock);
+		got_write_lock = 1;
+
+		if (!*pmont)
+			{
+			ret = BN_MONT_CTX_new();
+			if (ret && !BN_MONT_CTX_set(ret, mod, ctx))
+				BN_MONT_CTX_free(ret);
+			else
+				*pmont = ret;
+			}
+		}
+	
+	ret = *pmont;
+	
+	if (got_write_lock)
+		CRYPTO_w_unlock(lock);
+	else
+		CRYPTO_r_unlock(lock);
+		
+	return ret;
+	}
diff --git a/openssl/crypto/bn/bn_mpi.c b/openssl/crypto/bn/bn_mpi.c
new file mode 100644
index 0000000..a054d21
--- /dev/null
+++ b/openssl/crypto/bn/bn_mpi.c
@@ -0,0 +1,130 @@
+/* crypto/bn/bn_mpi.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+int BN_bn2mpi(const BIGNUM *a, unsigned char *d)
+	{
+	int bits;
+	int num=0;
+	int ext=0;
+	long l;
+
+	bits=BN_num_bits(a);
+	num=(bits+7)/8;
+	if (bits > 0)
+		{
+		ext=((bits & 0x07) == 0);
+		}
+	if (d == NULL)
+		return(num+4+ext);
+
+	l=num+ext;
+	d[0]=(unsigned char)(l>>24)&0xff;
+	d[1]=(unsigned char)(l>>16)&0xff;
+	d[2]=(unsigned char)(l>> 8)&0xff;
+	d[3]=(unsigned char)(l    )&0xff;
+	if (ext) d[4]=0;
+	num=BN_bn2bin(a,&(d[4+ext]));
+	if (a->neg)
+		d[4]|=0x80;
+	return(num+4+ext);
+	}
+
+BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *a)
+	{
+	long len;
+	int neg=0;
+
+	if (n < 4)
+		{
+		BNerr(BN_F_BN_MPI2BN,BN_R_INVALID_LENGTH);
+		return(NULL);
+		}
+	len=((long)d[0]<<24)|((long)d[1]<<16)|((int)d[2]<<8)|(int)d[3];
+	if ((len+4) != n)
+		{
+		BNerr(BN_F_BN_MPI2BN,BN_R_ENCODING_ERROR);
+		return(NULL);
+		}
+
+	if (a == NULL) a=BN_new();
+	if (a == NULL) return(NULL);
+
+	if (len == 0)
+		{
+		a->neg=0;
+		a->top=0;
+		return(a);
+		}
+	d+=4;
+	if ((*d) & 0x80)
+		neg=1;
+	if (BN_bin2bn(d,(int)len,a) == NULL)
+		return(NULL);
+	a->neg=neg;
+	if (neg)
+		{
+		BN_clear_bit(a,BN_num_bits(a)-1);
+		}
+	bn_check_top(a);
+	return(a);
+	}
+
diff --git a/openssl/crypto/bn/bn_mul.c b/openssl/crypto/bn/bn_mul.c
new file mode 100644
index 0000000..12e5be8
--- /dev/null
+++ b/openssl/crypto/bn/bn_mul.c
@@ -0,0 +1,1166 @@
+/* crypto/bn/bn_mul.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef BN_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#if defined(OPENSSL_NO_ASM) || !defined(OPENSSL_BN_ASM_PART_WORDS)
+/* Here follows specialised variants of bn_add_words() and
+   bn_sub_words().  They have the property performing operations on
+   arrays of different sizes.  The sizes of those arrays is expressed through
+   cl, which is the common length ( basicall, min(len(a),len(b)) ), and dl,
+   which is the delta between the two lengths, calculated as len(a)-len(b).
+   All lengths are the number of BN_ULONGs...  For the operations that require
+   a result array as parameter, it must have the length cl+abs(dl).
+   These functions should probably end up in bn_asm.c as soon as there are
+   assembler counterparts for the systems that use assembler files.  */
+
+BN_ULONG bn_sub_part_words(BN_ULONG *r,
+	const BN_ULONG *a, const BN_ULONG *b,
+	int cl, int dl)
+	{
+	BN_ULONG c, t;
+
+	assert(cl >= 0);
+	c = bn_sub_words(r, a, b, cl);
+
+	if (dl == 0)
+		return c;
+
+	r += cl;
+	a += cl;
+	b += cl;
+
+	if (dl < 0)
+		{
+#ifdef BN_COUNT
+		fprintf(stderr, "  bn_sub_part_words %d + %d (dl < 0, c = %d)\n", cl, dl, c);
+#endif
+		for (;;)
+			{
+			t = b[0];
+			r[0] = (0-t-c)&BN_MASK2;
+			if (t != 0) c=1;
+			if (++dl >= 0) break;
+
+			t = b[1];
+			r[1] = (0-t-c)&BN_MASK2;
+			if (t != 0) c=1;
+			if (++dl >= 0) break;
+
+			t = b[2];
+			r[2] = (0-t-c)&BN_MASK2;
+			if (t != 0) c=1;
+			if (++dl >= 0) break;
+
+			t = b[3];
+			r[3] = (0-t-c)&BN_MASK2;
+			if (t != 0) c=1;
+			if (++dl >= 0) break;
+
+			b += 4;
+			r += 4;
+			}
+		}
+	else
+		{
+		int save_dl = dl;
+#ifdef BN_COUNT
+		fprintf(stderr, "  bn_sub_part_words %d + %d (dl > 0, c = %d)\n", cl, dl, c);
+#endif
+		while(c)
+			{
+			t = a[0];
+			r[0] = (t-c)&BN_MASK2;
+			if (t != 0) c=0;
+			if (--dl <= 0) break;
+
+			t = a[1];
+			r[1] = (t-c)&BN_MASK2;
+			if (t != 0) c=0;
+			if (--dl <= 0) break;
+
+			t = a[2];
+			r[2] = (t-c)&BN_MASK2;
+			if (t != 0) c=0;
+			if (--dl <= 0) break;
+
+			t = a[3];
+			r[3] = (t-c)&BN_MASK2;
+			if (t != 0) c=0;
+			if (--dl <= 0) break;
+
+			save_dl = dl;
+			a += 4;
+			r += 4;
+			}
+		if (dl > 0)
+			{
+#ifdef BN_COUNT
+			fprintf(stderr, "  bn_sub_part_words %d + %d (dl > 0, c == 0)\n", cl, dl);
+#endif
+			if (save_dl > dl)
+				{
+				switch (save_dl - dl)
+					{
+				case 1:
+					r[1] = a[1];
+					if (--dl <= 0) break;
+				case 2:
+					r[2] = a[2];
+					if (--dl <= 0) break;
+				case 3:
+					r[3] = a[3];
+					if (--dl <= 0) break;
+					}
+				a += 4;
+				r += 4;
+				}
+			}
+		if (dl > 0)
+			{
+#ifdef BN_COUNT
+			fprintf(stderr, "  bn_sub_part_words %d + %d (dl > 0, copy)\n", cl, dl);
+#endif
+			for(;;)
+				{
+				r[0] = a[0];
+				if (--dl <= 0) break;
+				r[1] = a[1];
+				if (--dl <= 0) break;
+				r[2] = a[2];
+				if (--dl <= 0) break;
+				r[3] = a[3];
+				if (--dl <= 0) break;
+
+				a += 4;
+				r += 4;
+				}
+			}
+		}
+	return c;
+	}
+#endif
+
+BN_ULONG bn_add_part_words(BN_ULONG *r,
+	const BN_ULONG *a, const BN_ULONG *b,
+	int cl, int dl)
+	{
+	BN_ULONG c, l, t;
+
+	assert(cl >= 0);
+	c = bn_add_words(r, a, b, cl);
+
+	if (dl == 0)
+		return c;
+
+	r += cl;
+	a += cl;
+	b += cl;
+
+	if (dl < 0)
+		{
+		int save_dl = dl;
+#ifdef BN_COUNT
+		fprintf(stderr, "  bn_add_part_words %d + %d (dl < 0, c = %d)\n", cl, dl, c);
+#endif
+		while (c)
+			{
+			l=(c+b[0])&BN_MASK2;
+			c=(l < c);
+			r[0]=l;
+			if (++dl >= 0) break;
+
+			l=(c+b[1])&BN_MASK2;
+			c=(l < c);
+			r[1]=l;
+			if (++dl >= 0) break;
+
+			l=(c+b[2])&BN_MASK2;
+			c=(l < c);
+			r[2]=l;
+			if (++dl >= 0) break;
+
+			l=(c+b[3])&BN_MASK2;
+			c=(l < c);
+			r[3]=l;
+			if (++dl >= 0) break;
+
+			save_dl = dl;
+			b+=4;
+			r+=4;
+			}
+		if (dl < 0)
+			{
+#ifdef BN_COUNT
+			fprintf(stderr, "  bn_add_part_words %d + %d (dl < 0, c == 0)\n", cl, dl);
+#endif
+			if (save_dl < dl)
+				{
+				switch (dl - save_dl)
+					{
+				case 1:
+					r[1] = b[1];
+					if (++dl >= 0) break;
+				case 2:
+					r[2] = b[2];
+					if (++dl >= 0) break;
+				case 3:
+					r[3] = b[3];
+					if (++dl >= 0) break;
+					}
+				b += 4;
+				r += 4;
+				}
+			}
+		if (dl < 0)
+			{
+#ifdef BN_COUNT
+			fprintf(stderr, "  bn_add_part_words %d + %d (dl < 0, copy)\n", cl, dl);
+#endif
+			for(;;)
+				{
+				r[0] = b[0];
+				if (++dl >= 0) break;
+				r[1] = b[1];
+				if (++dl >= 0) break;
+				r[2] = b[2];
+				if (++dl >= 0) break;
+				r[3] = b[3];
+				if (++dl >= 0) break;
+
+				b += 4;
+				r += 4;
+				}
+			}
+		}
+	else
+		{
+		int save_dl = dl;
+#ifdef BN_COUNT
+		fprintf(stderr, "  bn_add_part_words %d + %d (dl > 0)\n", cl, dl);
+#endif
+		while (c)
+			{
+			t=(a[0]+c)&BN_MASK2;
+			c=(t < c);
+			r[0]=t;
+			if (--dl <= 0) break;
+
+			t=(a[1]+c)&BN_MASK2;
+			c=(t < c);
+			r[1]=t;
+			if (--dl <= 0) break;
+
+			t=(a[2]+c)&BN_MASK2;
+			c=(t < c);
+			r[2]=t;
+			if (--dl <= 0) break;
+
+			t=(a[3]+c)&BN_MASK2;
+			c=(t < c);
+			r[3]=t;
+			if (--dl <= 0) break;
+
+			save_dl = dl;
+			a+=4;
+			r+=4;
+			}
+#ifdef BN_COUNT
+		fprintf(stderr, "  bn_add_part_words %d + %d (dl > 0, c == 0)\n", cl, dl);
+#endif
+		if (dl > 0)
+			{
+			if (save_dl > dl)
+				{
+				switch (save_dl - dl)
+					{
+				case 1:
+					r[1] = a[1];
+					if (--dl <= 0) break;
+				case 2:
+					r[2] = a[2];
+					if (--dl <= 0) break;
+				case 3:
+					r[3] = a[3];
+					if (--dl <= 0) break;
+					}
+				a += 4;
+				r += 4;
+				}
+			}
+		if (dl > 0)
+			{
+#ifdef BN_COUNT
+			fprintf(stderr, "  bn_add_part_words %d + %d (dl > 0, copy)\n", cl, dl);
+#endif
+			for(;;)
+				{
+				r[0] = a[0];
+				if (--dl <= 0) break;
+				r[1] = a[1];
+				if (--dl <= 0) break;
+				r[2] = a[2];
+				if (--dl <= 0) break;
+				r[3] = a[3];
+				if (--dl <= 0) break;
+
+				a += 4;
+				r += 4;
+				}
+			}
+		}
+	return c;
+	}
+
+#ifdef BN_RECURSION
+/* Karatsuba recursive multiplication algorithm
+ * (cf. Knuth, The Art of Computer Programming, Vol. 2) */
+
+/* r is 2*n2 words in size,
+ * a and b are both n2 words in size.
+ * n2 must be a power of 2.
+ * We multiply and return the result.
+ * t must be 2*n2 words in size
+ * We calculate
+ * a[0]*b[0]
+ * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
+ * a[1]*b[1]
+ */
+/* dnX may not be positive, but n2/2+dnX has to be */
+void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+	int dna, int dnb, BN_ULONG *t)
+	{
+	int n=n2/2,c1,c2;
+	int tna=n+dna, tnb=n+dnb;
+	unsigned int neg,zero;
+	BN_ULONG ln,lo,*p;
+
+# ifdef BN_COUNT
+	fprintf(stderr," bn_mul_recursive %d%+d * %d%+d\n",n2,dna,n2,dnb);
+# endif
+# ifdef BN_MUL_COMBA
+#  if 0
+	if (n2 == 4)
+		{
+		bn_mul_comba4(r,a,b);
+		return;
+		}
+#  endif
+	/* Only call bn_mul_comba 8 if n2 == 8 and the
+	 * two arrays are complete [steve]
+	 */
+	if (n2 == 8 && dna == 0 && dnb == 0)
+		{
+		bn_mul_comba8(r,a,b);
+		return; 
+		}
+# endif /* BN_MUL_COMBA */
+	/* Else do normal multiply */
+	if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL)
+		{
+		bn_mul_normal(r,a,n2+dna,b,n2+dnb);
+		if ((dna + dnb) < 0)
+			memset(&r[2*n2 + dna + dnb], 0,
+				sizeof(BN_ULONG) * -(dna + dnb));
+		return;
+		}
+	/* r=(a[0]-a[1])*(b[1]-b[0]) */
+	c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
+	c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
+	zero=neg=0;
+	switch (c1*3+c2)
+		{
+	case -4:
+		bn_sub_part_words(t,      &(a[n]),a,      tna,tna-n); /* - */
+		bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
+		break;
+	case -3:
+		zero=1;
+		break;
+	case -2:
+		bn_sub_part_words(t,      &(a[n]),a,      tna,tna-n); /* - */
+		bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n); /* + */
+		neg=1;
+		break;
+	case -1:
+	case 0:
+	case 1:
+		zero=1;
+		break;
+	case 2:
+		bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna); /* + */
+		bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
+		neg=1;
+		break;
+	case 3:
+		zero=1;
+		break;
+	case 4:
+		bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna);
+		bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n);
+		break;
+		}
+
+# ifdef BN_MUL_COMBA
+	if (n == 4 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba4 could take
+					       extra args to do this well */
+		{
+		if (!zero)
+			bn_mul_comba4(&(t[n2]),t,&(t[n]));
+		else
+			memset(&(t[n2]),0,8*sizeof(BN_ULONG));
+		
+		bn_mul_comba4(r,a,b);
+		bn_mul_comba4(&(r[n2]),&(a[n]),&(b[n]));
+		}
+	else if (n == 8 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba8 could
+						    take extra args to do this
+						    well */
+		{
+		if (!zero)
+			bn_mul_comba8(&(t[n2]),t,&(t[n]));
+		else
+			memset(&(t[n2]),0,16*sizeof(BN_ULONG));
+		
+		bn_mul_comba8(r,a,b);
+		bn_mul_comba8(&(r[n2]),&(a[n]),&(b[n]));
+		}
+	else
+# endif /* BN_MUL_COMBA */
+		{
+		p= &(t[n2*2]);
+		if (!zero)
+			bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
+		else
+			memset(&(t[n2]),0,n2*sizeof(BN_ULONG));
+		bn_mul_recursive(r,a,b,n,0,0,p);
+		bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,dna,dnb,p);
+		}
+
+	/* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
+	 * r[10] holds (a[0]*b[0])
+	 * r[32] holds (b[1]*b[1])
+	 */
+
+	c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
+
+	if (neg) /* if t[32] is negative */
+		{
+		c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
+		}
+	else
+		{
+		/* Might have a carry */
+		c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),t,n2));
+		}
+
+	/* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
+	 * r[10] holds (a[0]*b[0])
+	 * r[32] holds (b[1]*b[1])
+	 * c1 holds the carry bits
+	 */
+	c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
+	if (c1)
+		{
+		p= &(r[n+n2]);
+		lo= *p;
+		ln=(lo+c1)&BN_MASK2;
+		*p=ln;
+
+		/* The overflow will stop before we over write
+		 * words we should not overwrite */
+		if (ln < (BN_ULONG)c1)
+			{
+			do	{
+				p++;
+				lo= *p;
+				ln=(lo+1)&BN_MASK2;
+				*p=ln;
+				} while (ln == 0);
+			}
+		}
+	}
+
+/* n+tn is the word length
+ * t needs to be n*4 is size, as does r */
+/* tnX may not be negative but less than n */
+void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
+	     int tna, int tnb, BN_ULONG *t)
+	{
+	int i,j,n2=n*2;
+	int c1,c2,neg;
+	BN_ULONG ln,lo,*p;
+
+# ifdef BN_COUNT
+	fprintf(stderr," bn_mul_part_recursive (%d%+d) * (%d%+d)\n",
+		n, tna, n, tnb);
+# endif
+	if (n < 8)
+		{
+		bn_mul_normal(r,a,n+tna,b,n+tnb);
+		return;
+		}
+
+	/* r=(a[0]-a[1])*(b[1]-b[0]) */
+	c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
+	c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
+	neg=0;
+	switch (c1*3+c2)
+		{
+	case -4:
+		bn_sub_part_words(t,      &(a[n]),a,      tna,tna-n); /* - */
+		bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
+		break;
+	case -3:
+		/* break; */
+	case -2:
+		bn_sub_part_words(t,      &(a[n]),a,      tna,tna-n); /* - */
+		bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n); /* + */
+		neg=1;
+		break;
+	case -1:
+	case 0:
+	case 1:
+		/* break; */
+	case 2:
+		bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna); /* + */
+		bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
+		neg=1;
+		break;
+	case 3:
+		/* break; */
+	case 4:
+		bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna);
+		bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n);
+		break;
+		}
+		/* The zero case isn't yet implemented here. The speedup
+		   would probably be negligible. */
+# if 0
+	if (n == 4)
+		{
+		bn_mul_comba4(&(t[n2]),t,&(t[n]));
+		bn_mul_comba4(r,a,b);
+		bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
+		memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2));
+		}
+	else
+# endif
+	if (n == 8)
+		{
+		bn_mul_comba8(&(t[n2]),t,&(t[n]));
+		bn_mul_comba8(r,a,b);
+		bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
+		memset(&(r[n2+tna+tnb]),0,sizeof(BN_ULONG)*(n2-tna-tnb));
+		}
+	else
+		{
+		p= &(t[n2*2]);
+		bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
+		bn_mul_recursive(r,a,b,n,0,0,p);
+		i=n/2;
+		/* If there is only a bottom half to the number,
+		 * just do it */
+		if (tna > tnb)
+			j = tna - i;
+		else
+			j = tnb - i;
+		if (j == 0)
+			{
+			bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),
+				i,tna-i,tnb-i,p);
+			memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2));
+			}
+		else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */
+				{
+				bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]),
+					i,tna-i,tnb-i,p);
+				memset(&(r[n2+tna+tnb]),0,
+					sizeof(BN_ULONG)*(n2-tna-tnb));
+				}
+		else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
+			{
+			memset(&(r[n2]),0,sizeof(BN_ULONG)*n2);
+			if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL
+				&& tnb < BN_MUL_RECURSIVE_SIZE_NORMAL)
+				{
+				bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
+				}
+			else
+				{
+				for (;;)
+					{
+					i/=2;
+					/* these simplified conditions work
+					 * exclusively because difference
+					 * between tna and tnb is 1 or 0 */
+					if (i < tna || i < tnb)
+						{
+						bn_mul_part_recursive(&(r[n2]),
+							&(a[n]),&(b[n]),
+							i,tna-i,tnb-i,p);
+						break;
+						}
+					else if (i == tna || i == tnb)
+						{
+						bn_mul_recursive(&(r[n2]),
+							&(a[n]),&(b[n]),
+							i,tna-i,tnb-i,p);
+						break;
+						}
+					}
+				}
+			}
+		}
+
+	/* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
+	 * r[10] holds (a[0]*b[0])
+	 * r[32] holds (b[1]*b[1])
+	 */
+
+	c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
+
+	if (neg) /* if t[32] is negative */
+		{
+		c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
+		}
+	else
+		{
+		/* Might have a carry */
+		c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),t,n2));
+		}
+
+	/* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
+	 * r[10] holds (a[0]*b[0])
+	 * r[32] holds (b[1]*b[1])
+	 * c1 holds the carry bits
+	 */
+	c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
+	if (c1)
+		{
+		p= &(r[n+n2]);
+		lo= *p;
+		ln=(lo+c1)&BN_MASK2;
+		*p=ln;
+
+		/* The overflow will stop before we over write
+		 * words we should not overwrite */
+		if (ln < (BN_ULONG)c1)
+			{
+			do	{
+				p++;
+				lo= *p;
+				ln=(lo+1)&BN_MASK2;
+				*p=ln;
+				} while (ln == 0);
+			}
+		}
+	}
+
+/* a and b must be the same size, which is n2.
+ * r needs to be n2 words and t needs to be n2*2
+ */
+void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+	     BN_ULONG *t)
+	{
+	int n=n2/2;
+
+# ifdef BN_COUNT
+	fprintf(stderr," bn_mul_low_recursive %d * %d\n",n2,n2);
+# endif
+
+	bn_mul_recursive(r,a,b,n,0,0,&(t[0]));
+	if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL)
+		{
+		bn_mul_low_recursive(&(t[0]),&(a[0]),&(b[n]),n,&(t[n2]));
+		bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
+		bn_mul_low_recursive(&(t[0]),&(a[n]),&(b[0]),n,&(t[n2]));
+		bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
+		}
+	else
+		{
+		bn_mul_low_normal(&(t[0]),&(a[0]),&(b[n]),n);
+		bn_mul_low_normal(&(t[n]),&(a[n]),&(b[0]),n);
+		bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
+		bn_add_words(&(r[n]),&(r[n]),&(t[n]),n);
+		}
+	}
+
+/* a and b must be the same size, which is n2.
+ * r needs to be n2 words and t needs to be n2*2
+ * l is the low words of the output.
+ * t needs to be n2*3
+ */
+void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
+	     BN_ULONG *t)
+	{
+	int i,n;
+	int c1,c2;
+	int neg,oneg,zero;
+	BN_ULONG ll,lc,*lp,*mp;
+
+# ifdef BN_COUNT
+	fprintf(stderr," bn_mul_high %d * %d\n",n2,n2);
+# endif
+	n=n2/2;
+
+	/* Calculate (al-ah)*(bh-bl) */
+	neg=zero=0;
+	c1=bn_cmp_words(&(a[0]),&(a[n]),n);
+	c2=bn_cmp_words(&(b[n]),&(b[0]),n);
+	switch (c1*3+c2)
+		{
+	case -4:
+		bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
+		bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
+		break;
+	case -3:
+		zero=1;
+		break;
+	case -2:
+		bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
+		bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
+		neg=1;
+		break;
+	case -1:
+	case 0:
+	case 1:
+		zero=1;
+		break;
+	case 2:
+		bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
+		bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
+		neg=1;
+		break;
+	case 3:
+		zero=1;
+		break;
+	case 4:
+		bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
+		bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
+		break;
+		}
+		
+	oneg=neg;
+	/* t[10] = (a[0]-a[1])*(b[1]-b[0]) */
+	/* r[10] = (a[1]*b[1]) */
+# ifdef BN_MUL_COMBA
+	if (n == 8)
+		{
+		bn_mul_comba8(&(t[0]),&(r[0]),&(r[n]));
+		bn_mul_comba8(r,&(a[n]),&(b[n]));
+		}
+	else
+# endif
+		{
+		bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,0,0,&(t[n2]));
+		bn_mul_recursive(r,&(a[n]),&(b[n]),n,0,0,&(t[n2]));
+		}
+
+	/* s0 == low(al*bl)
+	 * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl)
+	 * We know s0 and s1 so the only unknown is high(al*bl)
+	 * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl))
+	 * high(al*bl) == s1 - (r[0]+l[0]+t[0])
+	 */
+	if (l != NULL)
+		{
+		lp= &(t[n2+n]);
+		c1=(int)(bn_add_words(lp,&(r[0]),&(l[0]),n));
+		}
+	else
+		{
+		c1=0;
+		lp= &(r[0]);
+		}
+
+	if (neg)
+		neg=(int)(bn_sub_words(&(t[n2]),lp,&(t[0]),n));
+	else
+		{
+		bn_add_words(&(t[n2]),lp,&(t[0]),n);
+		neg=0;
+		}
+
+	if (l != NULL)
+		{
+		bn_sub_words(&(t[n2+n]),&(l[n]),&(t[n2]),n);
+		}
+	else
+		{
+		lp= &(t[n2+n]);
+		mp= &(t[n2]);
+		for (i=0; i<n; i++)
+			lp[i]=((~mp[i])+1)&BN_MASK2;
+		}
+
+	/* s[0] = low(al*bl)
+	 * t[3] = high(al*bl)
+	 * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
+	 * r[10] = (a[1]*b[1])
+	 */
+	/* R[10] = al*bl
+	 * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
+	 * R[32] = ah*bh
+	 */
+	/* R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow)
+	 * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow)
+	 * R[3]=r[1]+(carry/borrow)
+	 */
+	if (l != NULL)
+		{
+		lp= &(t[n2]);
+		c1= (int)(bn_add_words(lp,&(t[n2+n]),&(l[0]),n));
+		}
+	else
+		{
+		lp= &(t[n2+n]);
+		c1=0;
+		}
+	c1+=(int)(bn_add_words(&(t[n2]),lp,  &(r[0]),n));
+	if (oneg)
+		c1-=(int)(bn_sub_words(&(t[n2]),&(t[n2]),&(t[0]),n));
+	else
+		c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),&(t[0]),n));
+
+	c2 =(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n2+n]),n));
+	c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(r[n]),n));
+	if (oneg)
+		c2-=(int)(bn_sub_words(&(r[0]),&(r[0]),&(t[n]),n));
+	else
+		c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n]),n));
+	
+	if (c1 != 0) /* Add starting at r[0], could be +ve or -ve */
+		{
+		i=0;
+		if (c1 > 0)
+			{
+			lc=c1;
+			do	{
+				ll=(r[i]+lc)&BN_MASK2;
+				r[i++]=ll;
+				lc=(lc > ll);
+				} while (lc);
+			}
+		else
+			{
+			lc= -c1;
+			do	{
+				ll=r[i];
+				r[i++]=(ll-lc)&BN_MASK2;
+				lc=(lc > ll);
+				} while (lc);
+			}
+		}
+	if (c2 != 0) /* Add starting at r[1] */
+		{
+		i=n;
+		if (c2 > 0)
+			{
+			lc=c2;
+			do	{
+				ll=(r[i]+lc)&BN_MASK2;
+				r[i++]=ll;
+				lc=(lc > ll);
+				} while (lc);
+			}
+		else
+			{
+			lc= -c2;
+			do	{
+				ll=r[i];
+				r[i++]=(ll-lc)&BN_MASK2;
+				lc=(lc > ll);
+				} while (lc);
+			}
+		}
+	}
+#endif /* BN_RECURSION */
+
+int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+	{
+	int ret=0;
+	int top,al,bl;
+	BIGNUM *rr;
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+	int i;
+#endif
+#ifdef BN_RECURSION
+	BIGNUM *t=NULL;
+	int j=0,k;
+#endif
+
+#ifdef BN_COUNT
+	fprintf(stderr,"BN_mul %d * %d\n",a->top,b->top);
+#endif
+
+	bn_check_top(a);
+	bn_check_top(b);
+	bn_check_top(r);
+
+	al=a->top;
+	bl=b->top;
+
+	if ((al == 0) || (bl == 0))
+		{
+		BN_zero(r);
+		return(1);
+		}
+	top=al+bl;
+
+	BN_CTX_start(ctx);
+	if ((r == a) || (r == b))
+		{
+		if ((rr = BN_CTX_get(ctx)) == NULL) goto err;
+		}
+	else
+		rr = r;
+	rr->neg=a->neg^b->neg;
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+	i = al-bl;
+#endif
+#ifdef BN_MUL_COMBA
+	if (i == 0)
+		{
+# if 0
+		if (al == 4)
+			{
+			if (bn_wexpand(rr,8) == NULL) goto err;
+			rr->top=8;
+			bn_mul_comba4(rr->d,a->d,b->d);
+			goto end;
+			}
+# endif
+		if (al == 8)
+			{
+			if (bn_wexpand(rr,16) == NULL) goto err;
+			rr->top=16;
+			bn_mul_comba8(rr->d,a->d,b->d);
+			goto end;
+			}
+		}
+#endif /* BN_MUL_COMBA */
+#ifdef BN_RECURSION
+	if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL))
+		{
+		if (i >= -1 && i <= 1)
+			{
+			/* Find out the power of two lower or equal
+			   to the longest of the two numbers */
+			if (i >= 0)
+				{
+				j = BN_num_bits_word((BN_ULONG)al);
+				}
+			if (i == -1)
+				{
+				j = BN_num_bits_word((BN_ULONG)bl);
+				}
+			j = 1<<(j-1);
+			assert(j <= al || j <= bl);
+			k = j+j;
+			t = BN_CTX_get(ctx);
+			if (t == NULL)
+				goto err;
+			if (al > j || bl > j)
+				{
+				if (bn_wexpand(t,k*4) == NULL) goto err;
+				if (bn_wexpand(rr,k*4) == NULL) goto err;
+				bn_mul_part_recursive(rr->d,a->d,b->d,
+					j,al-j,bl-j,t->d);
+				}
+			else	/* al <= j || bl <= j */
+				{
+				if (bn_wexpand(t,k*2) == NULL) goto err;
+				if (bn_wexpand(rr,k*2) == NULL) goto err;
+				bn_mul_recursive(rr->d,a->d,b->d,
+					j,al-j,bl-j,t->d);
+				}
+			rr->top=top;
+			goto end;
+			}
+#if 0
+		if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA))
+			{
+			BIGNUM *tmp_bn = (BIGNUM *)b;
+			if (bn_wexpand(tmp_bn,al) == NULL) goto err;
+			tmp_bn->d[bl]=0;
+			bl++;
+			i--;
+			}
+		else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA))
+			{
+			BIGNUM *tmp_bn = (BIGNUM *)a;
+			if (bn_wexpand(tmp_bn,bl) == NULL) goto err;
+			tmp_bn->d[al]=0;
+			al++;
+			i++;
+			}
+		if (i == 0)
+			{
+			/* symmetric and > 4 */
+			/* 16 or larger */
+			j=BN_num_bits_word((BN_ULONG)al);
+			j=1<<(j-1);
+			k=j+j;
+			t = BN_CTX_get(ctx);
+			if (al == j) /* exact multiple */
+				{
+				if (bn_wexpand(t,k*2) == NULL) goto err;
+				if (bn_wexpand(rr,k*2) == NULL) goto err;
+				bn_mul_recursive(rr->d,a->d,b->d,al,t->d);
+				}
+			else
+				{
+				if (bn_wexpand(t,k*4) == NULL) goto err;
+				if (bn_wexpand(rr,k*4) == NULL) goto err;
+				bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d);
+				}
+			rr->top=top;
+			goto end;
+			}
+#endif
+		}
+#endif /* BN_RECURSION */
+	if (bn_wexpand(rr,top) == NULL) goto err;
+	rr->top=top;
+	bn_mul_normal(rr->d,a->d,al,b->d,bl);
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+end:
+#endif
+	bn_correct_top(rr);
+	if (r != rr) BN_copy(r,rr);
+	ret=1;
+err:
+	bn_check_top(r);
+	BN_CTX_end(ctx);
+	return(ret);
+	}
+
+void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
+	{
+	BN_ULONG *rr;
+
+#ifdef BN_COUNT
+	fprintf(stderr," bn_mul_normal %d * %d\n",na,nb);
+#endif
+
+	if (na < nb)
+		{
+		int itmp;
+		BN_ULONG *ltmp;
+
+		itmp=na; na=nb; nb=itmp;
+		ltmp=a;   a=b;   b=ltmp;
+
+		}
+	rr= &(r[na]);
+	if (nb <= 0)
+		{
+		(void)bn_mul_words(r,a,na,0);
+		return;
+		}
+	else
+		rr[0]=bn_mul_words(r,a,na,b[0]);
+
+	for (;;)
+		{
+		if (--nb <= 0) return;
+		rr[1]=bn_mul_add_words(&(r[1]),a,na,b[1]);
+		if (--nb <= 0) return;
+		rr[2]=bn_mul_add_words(&(r[2]),a,na,b[2]);
+		if (--nb <= 0) return;
+		rr[3]=bn_mul_add_words(&(r[3]),a,na,b[3]);
+		if (--nb <= 0) return;
+		rr[4]=bn_mul_add_words(&(r[4]),a,na,b[4]);
+		rr+=4;
+		r+=4;
+		b+=4;
+		}
+	}
+
+void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+	{
+#ifdef BN_COUNT
+	fprintf(stderr," bn_mul_low_normal %d * %d\n",n,n);
+#endif
+	bn_mul_words(r,a,n,b[0]);
+
+	for (;;)
+		{
+		if (--n <= 0) return;
+		bn_mul_add_words(&(r[1]),a,n,b[1]);
+		if (--n <= 0) return;
+		bn_mul_add_words(&(r[2]),a,n,b[2]);
+		if (--n <= 0) return;
+		bn_mul_add_words(&(r[3]),a,n,b[3]);
+		if (--n <= 0) return;
+		bn_mul_add_words(&(r[4]),a,n,b[4]);
+		r+=4;
+		b+=4;
+		}
+	}
diff --git a/openssl/crypto/bn/bn_nist.c b/openssl/crypto/bn/bn_nist.c
new file mode 100644
index 0000000..c6de032
--- /dev/null
+++ b/openssl/crypto/bn/bn_nist.c
@@ -0,0 +1,844 @@
+/* crypto/bn/bn_nist.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "bn_lcl.h"
+#include "cryptlib.h"
+
+
+#define BN_NIST_192_TOP	(192+BN_BITS2-1)/BN_BITS2
+#define BN_NIST_224_TOP	(224+BN_BITS2-1)/BN_BITS2
+#define BN_NIST_256_TOP	(256+BN_BITS2-1)/BN_BITS2
+#define BN_NIST_384_TOP	(384+BN_BITS2-1)/BN_BITS2
+#define BN_NIST_521_TOP	(521+BN_BITS2-1)/BN_BITS2
+
+/* pre-computed tables are "carry-less" values of modulus*(i+1) */
+#if BN_BITS2 == 64
+static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
+	{0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFFULL},
+	{0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFFULL},
+	{0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFCULL,0xFFFFFFFFFFFFFFFFULL}
+	};
+static const BN_ULONG _nist_p_192_sqr[] = {
+	0x0000000000000001ULL,0x0000000000000002ULL,0x0000000000000001ULL,
+	0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFFULL
+	};
+static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
+	{0x0000000000000001ULL,0xFFFFFFFF00000000ULL,
+	 0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL},
+	{0x0000000000000002ULL,0xFFFFFFFE00000000ULL,
+	 0xFFFFFFFFFFFFFFFFULL,0x00000001FFFFFFFFULL} /* this one is "carry-full" */
+	};
+static const BN_ULONG _nist_p_224_sqr[] = {
+	0x0000000000000001ULL,0xFFFFFFFE00000000ULL,
+	0xFFFFFFFFFFFFFFFFULL,0x0000000200000000ULL,
+	0x0000000000000000ULL,0xFFFFFFFFFFFFFFFEULL,
+	0xFFFFFFFFFFFFFFFFULL
+	};
+static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
+	{0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL,
+	 0x0000000000000000ULL,0xFFFFFFFF00000001ULL},
+	{0xFFFFFFFFFFFFFFFEULL,0x00000001FFFFFFFFULL,
+	 0x0000000000000000ULL,0xFFFFFFFE00000002ULL},
+	{0xFFFFFFFFFFFFFFFDULL,0x00000002FFFFFFFFULL,
+	 0x0000000000000000ULL,0xFFFFFFFD00000003ULL},
+	{0xFFFFFFFFFFFFFFFCULL,0x00000003FFFFFFFFULL,
+	 0x0000000000000000ULL,0xFFFFFFFC00000004ULL},
+	{0xFFFFFFFFFFFFFFFBULL,0x00000004FFFFFFFFULL,
+	 0x0000000000000000ULL,0xFFFFFFFB00000005ULL},
+	};
+static const BN_ULONG _nist_p_256_sqr[] = {
+	0x0000000000000001ULL,0xFFFFFFFE00000000ULL,
+	0xFFFFFFFFFFFFFFFFULL,0x00000001FFFFFFFEULL,
+	0x00000001FFFFFFFEULL,0x00000001FFFFFFFEULL,
+	0xFFFFFFFE00000001ULL,0xFFFFFFFE00000002ULL
+	};
+static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
+	{0x00000000FFFFFFFFULL,0xFFFFFFFF00000000ULL,0xFFFFFFFFFFFFFFFEULL,
+	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
+	{0x00000001FFFFFFFEULL,0xFFFFFFFE00000000ULL,0xFFFFFFFFFFFFFFFDULL,
+	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
+	{0x00000002FFFFFFFDULL,0xFFFFFFFD00000000ULL,0xFFFFFFFFFFFFFFFCULL,
+	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
+	{0x00000003FFFFFFFCULL,0xFFFFFFFC00000000ULL,0xFFFFFFFFFFFFFFFBULL,
+	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
+	{0x00000004FFFFFFFBULL,0xFFFFFFFB00000000ULL,0xFFFFFFFFFFFFFFFAULL,
+	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
+	};
+static const BN_ULONG _nist_p_384_sqr[] = {
+	0xFFFFFFFE00000001ULL,0x0000000200000000ULL,0xFFFFFFFE00000000ULL,
+	0x0000000200000000ULL,0x0000000000000001ULL,0x0000000000000000ULL,
+	0x00000001FFFFFFFEULL,0xFFFFFFFE00000000ULL,0xFFFFFFFFFFFFFFFDULL,
+	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL
+	};
+static const BN_ULONG _nist_p_521[] =
+	{0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
+	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
+	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
+	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
+	0x00000000000001FFULL};
+static const BN_ULONG _nist_p_521_sqr[] = {
+	0x0000000000000001ULL,0x0000000000000000ULL,0x0000000000000000ULL,
+	0x0000000000000000ULL,0x0000000000000000ULL,0x0000000000000000ULL,
+	0x0000000000000000ULL,0x0000000000000000ULL,0xFFFFFFFFFFFFFC00ULL,
+	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
+	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
+	0xFFFFFFFFFFFFFFFFULL,0x000000000003FFFFULL
+	};
+#elif BN_BITS2 == 32
+static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
+	{0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+	{0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+	{0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFC,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}
+	};
+static const BN_ULONG _nist_p_192_sqr[] = {
+	0x00000001,0x00000000,0x00000002,0x00000000,0x00000001,0x00000000,
+	0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF
+	};
+static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
+	{0x00000001,0x00000000,0x00000000,0xFFFFFFFF,
+	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+	{0x00000002,0x00000000,0x00000000,0xFFFFFFFE,
+	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}
+	};
+static const BN_ULONG _nist_p_224_sqr[] = {
+	0x00000001,0x00000000,0x00000000,0xFFFFFFFE,
+	0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000002,
+	0x00000000,0x00000000,0xFFFFFFFE,0xFFFFFFFF,
+	0xFFFFFFFF,0xFFFFFFFF
+	};
+static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
+	{0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,
+	 0x00000000,0x00000000,0x00000001,0xFFFFFFFF},
+	{0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0x00000001,
+	 0x00000000,0x00000000,0x00000002,0xFFFFFFFE},
+	{0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0x00000002,
+	 0x00000000,0x00000000,0x00000003,0xFFFFFFFD},
+	{0xFFFFFFFC,0xFFFFFFFF,0xFFFFFFFF,0x00000003,
+	 0x00000000,0x00000000,0x00000004,0xFFFFFFFC},
+	{0xFFFFFFFB,0xFFFFFFFF,0xFFFFFFFF,0x00000004,
+	 0x00000000,0x00000000,0x00000005,0xFFFFFFFB},
+	};
+static const BN_ULONG _nist_p_256_sqr[] = {
+	0x00000001,0x00000000,0x00000000,0xFFFFFFFE,
+	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,0x00000001,
+	0xFFFFFFFE,0x00000001,0xFFFFFFFE,0x00000001,
+	0x00000001,0xFFFFFFFE,0x00000002,0xFFFFFFFE
+	};
+static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
+	{0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,
+	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+	{0xFFFFFFFE,0x00000001,0x00000000,0xFFFFFFFE,0xFFFFFFFD,0xFFFFFFFF,
+	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+	{0xFFFFFFFD,0x00000002,0x00000000,0xFFFFFFFD,0xFFFFFFFC,0xFFFFFFFF,
+	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+	{0xFFFFFFFC,0x00000003,0x00000000,0xFFFFFFFC,0xFFFFFFFB,0xFFFFFFFF,
+	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+	{0xFFFFFFFB,0x00000004,0x00000000,0xFFFFFFFB,0xFFFFFFFA,0xFFFFFFFF,
+	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+	};
+static const BN_ULONG _nist_p_384_sqr[] = {
+	0x00000001,0xFFFFFFFE,0x00000000,0x00000002,0x00000000,0xFFFFFFFE,
+	0x00000000,0x00000002,0x00000001,0x00000000,0x00000000,0x00000000,
+	0xFFFFFFFE,0x00000001,0x00000000,0xFFFFFFFE,0xFFFFFFFD,0xFFFFFFFF,
+	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF
+	};
+static const BN_ULONG _nist_p_521[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+	0xFFFFFFFF,0x000001FF};
+static const BN_ULONG _nist_p_521_sqr[] = {
+	0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+	0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+	0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFC00,0xFFFFFFFF,
+	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+	0xFFFFFFFF,0xFFFFFFFF,0x0003FFFF
+	};
+#else
+#error "unsupported BN_BITS2"
+#endif
+
+
+static const BIGNUM _bignum_nist_p_192 =
+	{
+	(BN_ULONG *)_nist_p_192[0],
+	BN_NIST_192_TOP,
+	BN_NIST_192_TOP,
+	0,
+	BN_FLG_STATIC_DATA
+	};
+
+static const BIGNUM _bignum_nist_p_224 =
+	{
+	(BN_ULONG *)_nist_p_224[0],
+	BN_NIST_224_TOP,
+	BN_NIST_224_TOP,
+	0,
+	BN_FLG_STATIC_DATA
+	};
+
+static const BIGNUM _bignum_nist_p_256 =
+	{
+	(BN_ULONG *)_nist_p_256[0],
+	BN_NIST_256_TOP,
+	BN_NIST_256_TOP,
+	0,
+	BN_FLG_STATIC_DATA
+	};
+
+static const BIGNUM _bignum_nist_p_384 =
+	{
+	(BN_ULONG *)_nist_p_384[0],
+	BN_NIST_384_TOP,
+	BN_NIST_384_TOP,
+	0,
+	BN_FLG_STATIC_DATA
+	};
+
+static const BIGNUM _bignum_nist_p_521 =
+	{
+	(BN_ULONG *)_nist_p_521,
+	BN_NIST_521_TOP,
+	BN_NIST_521_TOP,
+	0,
+	BN_FLG_STATIC_DATA
+	};
+
+
+const BIGNUM *BN_get0_nist_prime_192(void)
+	{
+	return &_bignum_nist_p_192;
+	}
+
+const BIGNUM *BN_get0_nist_prime_224(void)
+	{
+	return &_bignum_nist_p_224;
+	}
+
+const BIGNUM *BN_get0_nist_prime_256(void)
+	{
+	return &_bignum_nist_p_256;
+	}
+
+const BIGNUM *BN_get0_nist_prime_384(void)
+	{
+	return &_bignum_nist_p_384;
+	}
+
+const BIGNUM *BN_get0_nist_prime_521(void)
+	{
+	return &_bignum_nist_p_521;
+	}
+
+
+static void nist_cp_bn_0(BN_ULONG *buf, BN_ULONG *a, int top, int max)
+	{
+	int i;
+	BN_ULONG *_tmp1 = (buf), *_tmp2 = (a);
+
+#ifdef BN_DEBUG
+	OPENSSL_assert(top <= max);
+#endif
+	for (i = (top); i != 0; i--)
+		*_tmp1++ = *_tmp2++;
+	for (i = (max) - (top); i != 0; i--)
+		*_tmp1++ = (BN_ULONG) 0;
+	}
+
+static void nist_cp_bn(BN_ULONG *buf, BN_ULONG *a, int top)
+	{ 
+	int i;
+	BN_ULONG *_tmp1 = (buf), *_tmp2 = (a);
+	for (i = (top); i != 0; i--)
+		*_tmp1++ = *_tmp2++;
+	}
+
+#if BN_BITS2 == 64
+#define bn_cp_64(to, n, from, m)	(to)[n] = (m>=0)?((from)[m]):0;
+#define bn_64_set_0(to, n)		(to)[n] = (BN_ULONG)0;
+/*
+ * two following macros are implemented under assumption that they
+ * are called in a sequence with *ascending* n, i.e. as they are...
+ */
+#define bn_cp_32_naked(to, n, from, m)	(((n)&1)?(to[(n)/2]|=((m)&1)?(from[(m)/2]&BN_MASK2h):(from[(m)/2]<<32))\
+						:(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l)))
+#define bn_32_set_0(to, n)		(((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0));
+#define bn_cp_32(to,n,from,m)		((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n)
+#else
+#define bn_cp_64(to, n, from, m) \
+	{ \
+	bn_cp_32(to, (n)*2, from, (m)*2); \
+	bn_cp_32(to, (n)*2+1, from, (m)*2+1); \
+	}
+#define bn_64_set_0(to, n) \
+	{ \
+	bn_32_set_0(to, (n)*2); \
+	bn_32_set_0(to, (n)*2+1); \
+	}
+#if BN_BITS2 == 32
+#define bn_cp_32(to, n, from, m)	(to)[n] = (m>=0)?((from)[m]):0;
+#define bn_32_set_0(to, n)		(to)[n] = (BN_ULONG)0;
+#endif
+#endif /* BN_BITS2 != 64 */
+
+
+#define nist_set_192(to, from, a1, a2, a3) \
+	{ \
+	bn_cp_64(to, 0, from, (a3) - 3) \
+	bn_cp_64(to, 1, from, (a2) - 3) \
+	bn_cp_64(to, 2, from, (a1) - 3) \
+	}
+
+int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+	BN_CTX *ctx)
+	{
+	int      top = a->top, i;
+	int      carry;
+	register BN_ULONG *r_d, *a_d = a->d;
+	BN_ULONG t_d[BN_NIST_192_TOP],
+	         buf[BN_NIST_192_TOP],
+		 c_d[BN_NIST_192_TOP],
+		*res;
+	PTR_SIZE_INT mask;
+	static const BIGNUM _bignum_nist_p_192_sqr = {
+		(BN_ULONG *)_nist_p_192_sqr,
+		sizeof(_nist_p_192_sqr)/sizeof(_nist_p_192_sqr[0]),
+		sizeof(_nist_p_192_sqr)/sizeof(_nist_p_192_sqr[0]),
+		0,BN_FLG_STATIC_DATA };
+
+	field = &_bignum_nist_p_192; /* just to make sure */
+
+ 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_192_sqr)>=0)
+		return BN_nnmod(r, a, field, ctx);
+
+	i = BN_ucmp(field, a);
+	if (i == 0)
+		{
+		BN_zero(r);
+		return 1;
+		}
+	else if (i > 0)
+		return (r == a) ? 1 : (BN_copy(r ,a) != NULL);
+
+	if (r != a)
+		{
+		if (!bn_wexpand(r, BN_NIST_192_TOP))
+			return 0;
+		r_d = r->d;
+		nist_cp_bn(r_d, a_d, BN_NIST_192_TOP);
+		}
+	else
+		r_d = a_d;
+
+	nist_cp_bn_0(buf, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP, BN_NIST_192_TOP);
+
+	nist_set_192(t_d, buf, 0, 3, 3);
+	carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
+	nist_set_192(t_d, buf, 4, 4, 0);
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
+	nist_set_192(t_d, buf, 5, 5, 5)
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
+
+	if (carry > 0)
+		carry = (int)bn_sub_words(r_d,r_d,_nist_p_192[carry-1],BN_NIST_192_TOP);
+	else
+		carry = 1;
+
+	/*
+	 * we need 'if (carry==0 || result>=modulus) result-=modulus;'
+	 * as comparison implies subtraction, we can write
+	 * 'tmp=result-modulus; if (!carry || !borrow) result=tmp;'
+	 * this is what happens below, but without explicit if:-) a.
+	 */
+	mask  = 0-(PTR_SIZE_INT)bn_sub_words(c_d,r_d,_nist_p_192[0],BN_NIST_192_TOP);
+	mask &= 0-(PTR_SIZE_INT)carry;
+	res   = (BN_ULONG *)
+	 (((PTR_SIZE_INT)c_d&~mask) | ((PTR_SIZE_INT)r_d&mask));
+	nist_cp_bn(r_d, res, BN_NIST_192_TOP);
+	r->top = BN_NIST_192_TOP;
+	bn_correct_top(r);
+
+	return 1;
+	}
+
+typedef BN_ULONG (*bn_addsub_f)(BN_ULONG *,const BN_ULONG *,const BN_ULONG *,int);
+
+#define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \
+	{ \
+	bn_cp_32(to, 0, from, (a7) - 7) \
+	bn_cp_32(to, 1, from, (a6) - 7) \
+	bn_cp_32(to, 2, from, (a5) - 7) \
+	bn_cp_32(to, 3, from, (a4) - 7) \
+	bn_cp_32(to, 4, from, (a3) - 7) \
+	bn_cp_32(to, 5, from, (a2) - 7) \
+	bn_cp_32(to, 6, from, (a1) - 7) \
+	}
+
+int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+	BN_CTX *ctx)
+	{
+	int	top = a->top, i;
+	int	carry;
+	BN_ULONG *r_d, *a_d = a->d;
+	BN_ULONG t_d[BN_NIST_224_TOP],
+	         buf[BN_NIST_224_TOP],
+		 c_d[BN_NIST_224_TOP],
+		*res;
+	PTR_SIZE_INT mask;
+	union { bn_addsub_f f; PTR_SIZE_INT p; } u;
+	static const BIGNUM _bignum_nist_p_224_sqr = {
+		(BN_ULONG *)_nist_p_224_sqr,
+		sizeof(_nist_p_224_sqr)/sizeof(_nist_p_224_sqr[0]),
+		sizeof(_nist_p_224_sqr)/sizeof(_nist_p_224_sqr[0]),
+		0,BN_FLG_STATIC_DATA };
+
+
+	field = &_bignum_nist_p_224; /* just to make sure */
+
+ 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_224_sqr)>=0)
+		return BN_nnmod(r, a, field, ctx);
+
+	i = BN_ucmp(field, a);
+	if (i == 0)
+		{
+		BN_zero(r);
+		return 1;
+		}
+	else if (i > 0)
+		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
+
+	if (r != a)
+		{
+		if (!bn_wexpand(r, BN_NIST_224_TOP))
+			return 0;
+		r_d = r->d;
+		nist_cp_bn(r_d, a_d, BN_NIST_224_TOP);
+		}
+	else
+		r_d = a_d;
+
+#if BN_BITS2==64
+	/* copy upper 256 bits of 448 bit number ... */
+	nist_cp_bn_0(t_d, a_d + (BN_NIST_224_TOP-1), top - (BN_NIST_224_TOP-1), BN_NIST_224_TOP);
+	/* ... and right shift by 32 to obtain upper 224 bits */
+	nist_set_224(buf, t_d, 14, 13, 12, 11, 10, 9, 8);
+	/* truncate lower part to 224 bits too */
+	r_d[BN_NIST_224_TOP-1] &= BN_MASK2l;
+#else
+	nist_cp_bn_0(buf, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP, BN_NIST_224_TOP);
+#endif
+	nist_set_224(t_d, buf, 10, 9, 8, 7, 0, 0, 0);
+	carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+	nist_set_224(t_d, buf, 0, 13, 12, 11, 0, 0, 0);
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+	nist_set_224(t_d, buf, 13, 12, 11, 10, 9, 8, 7);
+	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+	nist_set_224(t_d, buf, 0, 0, 0, 0, 13, 12, 11);
+	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+
+#if BN_BITS2==64
+	carry = (int)(r_d[BN_NIST_224_TOP-1]>>32);
+#endif
+	u.f = bn_sub_words;
+	if (carry > 0)
+		{
+		carry = (int)bn_sub_words(r_d,r_d,_nist_p_224[carry-1],BN_NIST_224_TOP);
+#if BN_BITS2==64
+		carry=(int)(~(r_d[BN_NIST_224_TOP-1]>>32))&1;
+#endif
+		}
+	else if (carry < 0)
+		{
+		/* it's a bit more comlicated logic in this case.
+		 * if bn_add_words yields no carry, then result
+		 * has to be adjusted by unconditionally *adding*
+		 * the modulus. but if it does, then result has
+		 * to be compared to the modulus and conditionally
+		 * adjusted by *subtracting* the latter. */
+		carry = (int)bn_add_words(r_d,r_d,_nist_p_224[-carry-1],BN_NIST_224_TOP);
+		mask = 0-(PTR_SIZE_INT)carry;
+		u.p = ((PTR_SIZE_INT)bn_sub_words&mask) |
+		 ((PTR_SIZE_INT)bn_add_words&~mask);
+		}
+	else
+		carry = 1;
+
+	/* otherwise it's effectively same as in BN_nist_mod_192... */
+	mask  = 0-(PTR_SIZE_INT)(*u.f)(c_d,r_d,_nist_p_224[0],BN_NIST_224_TOP);
+	mask &= 0-(PTR_SIZE_INT)carry;
+	res   = (BN_ULONG *)(((PTR_SIZE_INT)c_d&~mask) |
+	 ((PTR_SIZE_INT)r_d&mask));
+	nist_cp_bn(r_d, res, BN_NIST_224_TOP);
+	r->top = BN_NIST_224_TOP;
+	bn_correct_top(r);
+
+	return 1;
+	}
+
+#define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \
+	{ \
+	bn_cp_32(to, 0, from, (a8) - 8) \
+	bn_cp_32(to, 1, from, (a7) - 8) \
+	bn_cp_32(to, 2, from, (a6) - 8) \
+	bn_cp_32(to, 3, from, (a5) - 8) \
+	bn_cp_32(to, 4, from, (a4) - 8) \
+	bn_cp_32(to, 5, from, (a3) - 8) \
+	bn_cp_32(to, 6, from, (a2) - 8) \
+	bn_cp_32(to, 7, from, (a1) - 8) \
+	}
+
+int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+	BN_CTX *ctx)
+	{
+	int	i, top = a->top;
+	int	carry = 0;
+	register BN_ULONG *a_d = a->d, *r_d;
+	BN_ULONG t_d[BN_NIST_256_TOP],
+	         buf[BN_NIST_256_TOP],
+		 c_d[BN_NIST_256_TOP],
+		*res;
+	PTR_SIZE_INT mask;
+	union { bn_addsub_f f; PTR_SIZE_INT p; } u;
+	static const BIGNUM _bignum_nist_p_256_sqr = {
+		(BN_ULONG *)_nist_p_256_sqr,
+		sizeof(_nist_p_256_sqr)/sizeof(_nist_p_256_sqr[0]),
+		sizeof(_nist_p_256_sqr)/sizeof(_nist_p_256_sqr[0]),
+		0,BN_FLG_STATIC_DATA };
+
+	field = &_bignum_nist_p_256; /* just to make sure */
+
+ 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_256_sqr)>=0)
+		return BN_nnmod(r, a, field, ctx);
+
+	i = BN_ucmp(field, a);
+	if (i == 0)
+		{
+		BN_zero(r);
+		return 1;
+		}
+	else if (i > 0)
+		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
+
+	if (r != a)
+		{
+		if (!bn_wexpand(r, BN_NIST_256_TOP))
+			return 0;
+		r_d = r->d;
+		nist_cp_bn(r_d, a_d, BN_NIST_256_TOP);
+		}
+	else
+		r_d = a_d;
+
+	nist_cp_bn_0(buf, a_d + BN_NIST_256_TOP, top - BN_NIST_256_TOP, BN_NIST_256_TOP);
+
+	/*S1*/
+	nist_set_256(t_d, buf, 15, 14, 13, 12, 11, 0, 0, 0);
+	/*S2*/
+	nist_set_256(c_d, buf, 0, 15, 14, 13, 12, 0, 0, 0);
+	carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP);
+	/* left shift */
+		{
+		register BN_ULONG *ap,t,c;
+		ap = t_d;
+		c=0;
+		for (i = BN_NIST_256_TOP; i != 0; --i)
+			{
+			t= *ap;
+			*(ap++)=((t<<1)|c)&BN_MASK2;
+			c=(t & BN_TBIT)?1:0;
+			}
+		carry <<= 1;
+		carry  |= c;
+		}
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+	/*S3*/
+	nist_set_256(t_d, buf, 15, 14, 0, 0, 0, 10, 9, 8);
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+	/*S4*/
+	nist_set_256(t_d, buf, 8, 13, 15, 14, 13, 11, 10, 9);
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+	/*D1*/
+	nist_set_256(t_d, buf, 10, 8, 0, 0, 0, 13, 12, 11);
+	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+	/*D2*/
+	nist_set_256(t_d, buf, 11, 9, 0, 0, 15, 14, 13, 12);
+	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+	/*D3*/
+	nist_set_256(t_d, buf, 12, 0, 10, 9, 8, 15, 14, 13);
+	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+	/*D4*/
+	nist_set_256(t_d, buf, 13, 0, 11, 10, 9, 0, 15, 14);
+	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+
+	/* see BN_nist_mod_224 for explanation */
+	u.f = bn_sub_words;
+	if (carry > 0)
+		carry = (int)bn_sub_words(r_d,r_d,_nist_p_256[carry-1],BN_NIST_256_TOP);
+	else if (carry < 0)
+		{
+		carry = (int)bn_add_words(r_d,r_d,_nist_p_256[-carry-1],BN_NIST_256_TOP);
+		mask = 0-(PTR_SIZE_INT)carry;
+		u.p = ((PTR_SIZE_INT)bn_sub_words&mask) |
+		 ((PTR_SIZE_INT)bn_add_words&~mask);
+		}
+	else
+		carry = 1;
+
+	mask  = 0-(PTR_SIZE_INT)(*u.f)(c_d,r_d,_nist_p_256[0],BN_NIST_256_TOP);
+	mask &= 0-(PTR_SIZE_INT)carry;
+	res   = (BN_ULONG *)(((PTR_SIZE_INT)c_d&~mask) |
+	 ((PTR_SIZE_INT)r_d&mask));
+	nist_cp_bn(r_d, res, BN_NIST_256_TOP);
+	r->top = BN_NIST_256_TOP;
+	bn_correct_top(r);
+
+	return 1;
+	}
+
+#define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \
+	{ \
+	bn_cp_32(to, 0, from,  (a12) - 12) \
+	bn_cp_32(to, 1, from,  (a11) - 12) \
+	bn_cp_32(to, 2, from,  (a10) - 12) \
+	bn_cp_32(to, 3, from,  (a9) - 12)  \
+	bn_cp_32(to, 4, from,  (a8) - 12)  \
+	bn_cp_32(to, 5, from,  (a7) - 12)  \
+	bn_cp_32(to, 6, from,  (a6) - 12)  \
+	bn_cp_32(to, 7, from,  (a5) - 12)  \
+	bn_cp_32(to, 8, from,  (a4) - 12)  \
+	bn_cp_32(to, 9, from,  (a3) - 12)  \
+	bn_cp_32(to, 10, from, (a2) - 12)  \
+	bn_cp_32(to, 11, from, (a1) - 12)  \
+	}
+
+int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+	BN_CTX *ctx)
+	{
+	int	i, top = a->top;
+	int	carry = 0;
+	register BN_ULONG *r_d, *a_d = a->d;
+	BN_ULONG t_d[BN_NIST_384_TOP],
+	         buf[BN_NIST_384_TOP],
+		 c_d[BN_NIST_384_TOP],
+		*res;
+	PTR_SIZE_INT mask;
+	union { bn_addsub_f f; PTR_SIZE_INT p; } u;
+	static const BIGNUM _bignum_nist_p_384_sqr = {
+		(BN_ULONG *)_nist_p_384_sqr,
+		sizeof(_nist_p_384_sqr)/sizeof(_nist_p_384_sqr[0]),
+		sizeof(_nist_p_384_sqr)/sizeof(_nist_p_384_sqr[0]),
+		0,BN_FLG_STATIC_DATA };
+
+
+	field = &_bignum_nist_p_384; /* just to make sure */
+
+ 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_384_sqr)>=0)
+		return BN_nnmod(r, a, field, ctx);
+
+	i = BN_ucmp(field, a);
+	if (i == 0)
+		{
+		BN_zero(r);
+		return 1;
+		}
+	else if (i > 0)
+		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
+
+	if (r != a)
+		{
+		if (!bn_wexpand(r, BN_NIST_384_TOP))
+			return 0;
+		r_d = r->d;
+		nist_cp_bn(r_d, a_d, BN_NIST_384_TOP);
+		}
+	else
+		r_d = a_d;
+
+	nist_cp_bn_0(buf, a_d + BN_NIST_384_TOP, top - BN_NIST_384_TOP, BN_NIST_384_TOP);
+
+	/*S1*/
+	nist_set_256(t_d, buf, 0, 0, 0, 0, 0, 23-4, 22-4, 21-4);
+		/* left shift */
+		{
+		register BN_ULONG *ap,t,c;
+		ap = t_d;
+		c=0;
+		for (i = 3; i != 0; --i)
+			{
+			t= *ap;
+			*(ap++)=((t<<1)|c)&BN_MASK2;
+			c=(t & BN_TBIT)?1:0;
+			}
+		*ap=c;
+		}
+	carry = (int)bn_add_words(r_d+(128/BN_BITS2), r_d+(128/BN_BITS2), 
+		t_d, BN_NIST_256_TOP);
+	/*S2 */
+	carry += (int)bn_add_words(r_d, r_d, buf, BN_NIST_384_TOP);
+	/*S3*/
+	nist_set_384(t_d,buf,20,19,18,17,16,15,14,13,12,23,22,21);
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+	/*S4*/
+	nist_set_384(t_d,buf,19,18,17,16,15,14,13,12,20,0,23,0);
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+	/*S5*/
+	nist_set_384(t_d, buf,0,0,0,0,23,22,21,20,0,0,0,0);
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+	/*S6*/
+	nist_set_384(t_d,buf,0,0,0,0,0,0,23,22,21,0,0,20);
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+	/*D1*/
+	nist_set_384(t_d,buf,22,21,20,19,18,17,16,15,14,13,12,23);
+	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+	/*D2*/
+	nist_set_384(t_d,buf,0,0,0,0,0,0,0,23,22,21,20,0);
+	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+	/*D3*/
+	nist_set_384(t_d,buf,0,0,0,0,0,0,0,23,23,0,0,0);
+	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+
+	/* see BN_nist_mod_224 for explanation */
+	u.f = bn_sub_words;
+	if (carry > 0)
+		carry = (int)bn_sub_words(r_d,r_d,_nist_p_384[carry-1],BN_NIST_384_TOP);
+	else if (carry < 0)
+		{
+		carry = (int)bn_add_words(r_d,r_d,_nist_p_384[-carry-1],BN_NIST_384_TOP);
+		mask = 0-(PTR_SIZE_INT)carry;
+		u.p = ((PTR_SIZE_INT)bn_sub_words&mask) |
+		 ((PTR_SIZE_INT)bn_add_words&~mask);
+		}
+	else
+		carry = 1;
+
+	mask  = 0-(PTR_SIZE_INT)(*u.f)(c_d,r_d,_nist_p_384[0],BN_NIST_384_TOP);
+	mask &= 0-(PTR_SIZE_INT)carry;
+	res   = (BN_ULONG *)(((PTR_SIZE_INT)c_d&~mask) |
+	 ((PTR_SIZE_INT)r_d&mask));
+	nist_cp_bn(r_d, res, BN_NIST_384_TOP);
+	r->top = BN_NIST_384_TOP;
+	bn_correct_top(r);
+
+	return 1;
+	}
+
+#define BN_NIST_521_RSHIFT	(521%BN_BITS2)
+#define BN_NIST_521_LSHIFT	(BN_BITS2-BN_NIST_521_RSHIFT)
+#define BN_NIST_521_TOP_MASK	((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT)
+
+int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+	BN_CTX *ctx)
+	{
+	int	top = a->top, i;
+	BN_ULONG *r_d, *a_d = a->d,
+		 t_d[BN_NIST_521_TOP],
+		 val,tmp,*res;
+	PTR_SIZE_INT mask;
+	static const BIGNUM _bignum_nist_p_521_sqr = {
+		(BN_ULONG *)_nist_p_521_sqr,
+		sizeof(_nist_p_521_sqr)/sizeof(_nist_p_521_sqr[0]),
+		sizeof(_nist_p_521_sqr)/sizeof(_nist_p_521_sqr[0]),
+		0,BN_FLG_STATIC_DATA };
+
+	field = &_bignum_nist_p_521; /* just to make sure */
+
+ 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_521_sqr)>=0)
+		return BN_nnmod(r, a, field, ctx);
+
+	i = BN_ucmp(field, a);
+	if (i == 0)
+		{
+		BN_zero(r);
+		return 1;
+		}
+	else if (i > 0)
+		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
+
+	if (r != a)
+		{
+		if (!bn_wexpand(r,BN_NIST_521_TOP))
+			return 0;
+		r_d = r->d;
+		nist_cp_bn(r_d,a_d, BN_NIST_521_TOP);
+		}
+	else
+		r_d = a_d;
+
+	/* upper 521 bits, copy ... */
+	nist_cp_bn_0(t_d,a_d + (BN_NIST_521_TOP-1), top - (BN_NIST_521_TOP-1),BN_NIST_521_TOP);
+	/* ... and right shift */
+	for (val=t_d[0],i=0; i<BN_NIST_521_TOP-1; i++)
+		{
+		tmp = val>>BN_NIST_521_RSHIFT;
+		val = t_d[i+1];
+		t_d[i] = (tmp | val<<BN_NIST_521_LSHIFT) & BN_MASK2;
+		}
+	t_d[i] = val>>BN_NIST_521_RSHIFT;
+	/* lower 521 bits */
+	r_d[i] &= BN_NIST_521_TOP_MASK;
+
+	bn_add_words(r_d,r_d,t_d,BN_NIST_521_TOP);
+	mask = 0-(PTR_SIZE_INT)bn_sub_words(t_d,r_d,_nist_p_521,BN_NIST_521_TOP);
+	res  = (BN_ULONG *)(((PTR_SIZE_INT)t_d&~mask) |
+	 ((PTR_SIZE_INT)r_d&mask));
+	nist_cp_bn(r_d,res,BN_NIST_521_TOP);
+	r->top = BN_NIST_521_TOP;
+	bn_correct_top(r);
+
+	return 1;
+	}
diff --git a/openssl/crypto/bn/bn_prime.c b/openssl/crypto/bn/bn_prime.c
new file mode 100644
index 0000000..7b25979
--- /dev/null
+++ b/openssl/crypto/bn/bn_prime.c
@@ -0,0 +1,494 @@
+/* crypto/bn/bn_prime.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+#include <openssl/rand.h>
+
+/* NB: these functions have been "upgraded", the deprecated versions (which are
+ * compatibility wrappers using these functions) are in bn_depr.c.
+ * - Geoff
+ */
+
+/* The quick sieve algorithm approach to weeding out primes is
+ * Philip Zimmermann's, as implemented in PGP.  I have had a read of
+ * his comments and implemented my own version.
+ */
+#include "bn_prime.h"
+
+static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
+	const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont);
+static int probable_prime(BIGNUM *rnd, int bits);
+static int probable_prime_dh(BIGNUM *rnd, int bits,
+	const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
+static int probable_prime_dh_safe(BIGNUM *rnd, int bits,
+	const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
+
+int BN_GENCB_call(BN_GENCB *cb, int a, int b)
+	{
+	/* No callback means continue */
+	if(!cb) return 1;
+	switch(cb->ver)
+		{
+	case 1:
+		/* Deprecated-style callbacks */
+		if(!cb->cb.cb_1)
+			return 1;
+		cb->cb.cb_1(a, b, cb->arg);
+		return 1;
+	case 2:
+		/* New-style callbacks */
+		return cb->cb.cb_2(a, b, cb);
+	default:
+		break;
+		}
+	/* Unrecognised callback type */
+	return 0;
+	}
+
+int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
+	const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb)
+	{
+	BIGNUM *t;
+	int found=0;
+	int i,j,c1=0;
+	BN_CTX *ctx;
+	int checks = BN_prime_checks_for_size(bits);
+
+	ctx=BN_CTX_new();
+	if (ctx == NULL) goto err;
+	BN_CTX_start(ctx);
+	t = BN_CTX_get(ctx);
+	if(!t) goto err;
+loop: 
+	/* make a random number and set the top and bottom bits */
+	if (add == NULL)
+		{
+		if (!probable_prime(ret,bits)) goto err;
+		}
+	else
+		{
+		if (safe)
+			{
+			if (!probable_prime_dh_safe(ret,bits,add,rem,ctx))
+				 goto err;
+			}
+		else
+			{
+			if (!probable_prime_dh(ret,bits,add,rem,ctx))
+				goto err;
+			}
+		}
+	/* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */
+	if(!BN_GENCB_call(cb, 0, c1++))
+		/* aborted */
+		goto err;
+
+	if (!safe)
+		{
+		i=BN_is_prime_fasttest_ex(ret,checks,ctx,0,cb);
+		if (i == -1) goto err;
+		if (i == 0) goto loop;
+		}
+	else
+		{
+		/* for "safe prime" generation,
+		 * check that (p-1)/2 is prime.
+		 * Since a prime is odd, We just
+		 * need to divide by 2 */
+		if (!BN_rshift1(t,ret)) goto err;
+
+		for (i=0; i<checks; i++)
+			{
+			j=BN_is_prime_fasttest_ex(ret,1,ctx,0,cb);
+			if (j == -1) goto err;
+			if (j == 0) goto loop;
+
+			j=BN_is_prime_fasttest_ex(t,1,ctx,0,cb);
+			if (j == -1) goto err;
+			if (j == 0) goto loop;
+
+			if(!BN_GENCB_call(cb, 2, c1-1))
+				goto err;
+			/* We have a safe prime test pass */
+			}
+		}
+	/* we have a prime :-) */
+	found = 1;
+err:
+	if (ctx != NULL)
+		{
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+		}
+	bn_check_top(ret);
+	return found;
+	}
+
+int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, BN_GENCB *cb)
+	{
+	return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb);
+	}
+
+int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
+		int do_trial_division, BN_GENCB *cb)
+	{
+	int i, j, ret = -1;
+	int k;
+	BN_CTX *ctx = NULL;
+	BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
+	BN_MONT_CTX *mont = NULL;
+	const BIGNUM *A = NULL;
+
+	if (BN_cmp(a, BN_value_one()) <= 0)
+		return 0;
+	
+	if (checks == BN_prime_checks)
+		checks = BN_prime_checks_for_size(BN_num_bits(a));
+
+	/* first look for small factors */
+	if (!BN_is_odd(a))
+		/* a is even => a is prime if and only if a == 2 */
+		return BN_is_word(a, 2);
+	if (do_trial_division)
+		{
+		for (i = 1; i < NUMPRIMES; i++)
+			if (BN_mod_word(a, primes[i]) == 0) 
+				return 0;
+		if(!BN_GENCB_call(cb, 1, -1))
+			goto err;
+		}
+
+	if (ctx_passed != NULL)
+		ctx = ctx_passed;
+	else
+		if ((ctx=BN_CTX_new()) == NULL)
+			goto err;
+	BN_CTX_start(ctx);
+
+	/* A := abs(a) */
+	if (a->neg)
+		{
+		BIGNUM *t;
+		if ((t = BN_CTX_get(ctx)) == NULL) goto err;
+		BN_copy(t, a);
+		t->neg = 0;
+		A = t;
+		}
+	else
+		A = a;
+	A1 = BN_CTX_get(ctx);
+	A1_odd = BN_CTX_get(ctx);
+	check = BN_CTX_get(ctx);
+	if (check == NULL) goto err;
+
+	/* compute A1 := A - 1 */
+	if (!BN_copy(A1, A))
+		goto err;
+	if (!BN_sub_word(A1, 1))
+		goto err;
+	if (BN_is_zero(A1))
+		{
+		ret = 0;
+		goto err;
+		}
+
+	/* write  A1  as  A1_odd * 2^k */
+	k = 1;
+	while (!BN_is_bit_set(A1, k))
+		k++;
+	if (!BN_rshift(A1_odd, A1, k))
+		goto err;
+
+	/* Montgomery setup for computations mod A */
+	mont = BN_MONT_CTX_new();
+	if (mont == NULL)
+		goto err;
+	if (!BN_MONT_CTX_set(mont, A, ctx))
+		goto err;
+	
+	for (i = 0; i < checks; i++)
+		{
+		if (!BN_pseudo_rand_range(check, A1))
+			goto err;
+		if (!BN_add_word(check, 1))
+			goto err;
+		/* now 1 <= check < A */
+
+		j = witness(check, A, A1, A1_odd, k, ctx, mont);
+		if (j == -1) goto err;
+		if (j)
+			{
+			ret=0;
+			goto err;
+			}
+		if(!BN_GENCB_call(cb, 1, i))
+			goto err;
+		}
+	ret=1;
+err:
+	if (ctx != NULL)
+		{
+		BN_CTX_end(ctx);
+		if (ctx_passed == NULL)
+			BN_CTX_free(ctx);
+		}
+	if (mont != NULL)
+		BN_MONT_CTX_free(mont);
+
+	return(ret);
+	}
+
+static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
+	const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont)
+	{
+	if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */
+		return -1;
+	if (BN_is_one(w))
+		return 0; /* probably prime */
+	if (BN_cmp(w, a1) == 0)
+		return 0; /* w == -1 (mod a),  'a' is probably prime */
+	while (--k)
+		{
+		if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */
+			return -1;
+		if (BN_is_one(w))
+			return 1; /* 'a' is composite, otherwise a previous 'w' would
+			           * have been == -1 (mod 'a') */
+		if (BN_cmp(w, a1) == 0)
+			return 0; /* w == -1 (mod a), 'a' is probably prime */
+		}
+	/* If we get here, 'w' is the (a-1)/2-th power of the original 'w',
+	 * and it is neither -1 nor +1 -- so 'a' cannot be prime */
+	bn_check_top(w);
+	return 1;
+	}
+
+static int probable_prime(BIGNUM *rnd, int bits)
+	{
+	int i;
+	prime_t mods[NUMPRIMES];
+	BN_ULONG delta,maxdelta;
+
+again:
+	if (!BN_rand(rnd,bits,1,1)) return(0);
+	/* we now have a random number 'rand' to test. */
+	for (i=1; i<NUMPRIMES; i++)
+		mods[i]=(prime_t)BN_mod_word(rnd,(BN_ULONG)primes[i]);
+	maxdelta=BN_MASK2 - primes[NUMPRIMES-1];
+	delta=0;
+	loop: for (i=1; i<NUMPRIMES; i++)
+		{
+		/* check that rnd is not a prime and also
+		 * that gcd(rnd-1,primes) == 1 (except for 2) */
+		if (((mods[i]+delta)%primes[i]) <= 1)
+			{
+			delta+=2;
+			if (delta > maxdelta) goto again;
+			goto loop;
+			}
+		}
+	if (!BN_add_word(rnd,delta)) return(0);
+	bn_check_top(rnd);
+	return(1);
+	}
+
+static int probable_prime_dh(BIGNUM *rnd, int bits,
+	const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx)
+	{
+	int i,ret=0;
+	BIGNUM *t1;
+
+	BN_CTX_start(ctx);
+	if ((t1 = BN_CTX_get(ctx)) == NULL) goto err;
+
+	if (!BN_rand(rnd,bits,0,1)) goto err;
+
+	/* we need ((rnd-rem) % add) == 0 */
+
+	if (!BN_mod(t1,rnd,add,ctx)) goto err;
+	if (!BN_sub(rnd,rnd,t1)) goto err;
+	if (rem == NULL)
+		{ if (!BN_add_word(rnd,1)) goto err; }
+	else
+		{ if (!BN_add(rnd,rnd,rem)) goto err; }
+
+	/* we now have a random number 'rand' to test. */
+
+	loop: for (i=1; i<NUMPRIMES; i++)
+		{
+		/* check that rnd is a prime */
+		if (BN_mod_word(rnd,(BN_ULONG)primes[i]) <= 1)
+			{
+			if (!BN_add(rnd,rnd,add)) goto err;
+			goto loop;
+			}
+		}
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	bn_check_top(rnd);
+	return(ret);
+	}
+
+static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
+	const BIGNUM *rem, BN_CTX *ctx)
+	{
+	int i,ret=0;
+	BIGNUM *t1,*qadd,*q;
+
+	bits--;
+	BN_CTX_start(ctx);
+	t1 = BN_CTX_get(ctx);
+	q = BN_CTX_get(ctx);
+	qadd = BN_CTX_get(ctx);
+	if (qadd == NULL) goto err;
+
+	if (!BN_rshift1(qadd,padd)) goto err;
+		
+	if (!BN_rand(q,bits,0,1)) goto err;
+
+	/* we need ((rnd-rem) % add) == 0 */
+	if (!BN_mod(t1,q,qadd,ctx)) goto err;
+	if (!BN_sub(q,q,t1)) goto err;
+	if (rem == NULL)
+		{ if (!BN_add_word(q,1)) goto err; }
+	else
+		{
+		if (!BN_rshift1(t1,rem)) goto err;
+		if (!BN_add(q,q,t1)) goto err;
+		}
+
+	/* we now have a random number 'rand' to test. */
+	if (!BN_lshift1(p,q)) goto err;
+	if (!BN_add_word(p,1)) goto err;
+
+	loop: for (i=1; i<NUMPRIMES; i++)
+		{
+		/* check that p and q are prime */
+		/* check that for p and q
+		 * gcd(p-1,primes) == 1 (except for 2) */
+		if (	(BN_mod_word(p,(BN_ULONG)primes[i]) == 0) ||
+			(BN_mod_word(q,(BN_ULONG)primes[i]) == 0))
+			{
+			if (!BN_add(p,p,padd)) goto err;
+			if (!BN_add(q,q,qadd)) goto err;
+			goto loop;
+			}
+		}
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	bn_check_top(p);
+	return(ret);
+	}
diff --git a/openssl/crypto/bn/bn_prime.h b/openssl/crypto/bn/bn_prime.h
new file mode 100644
index 0000000..51d2194
--- /dev/null
+++ b/openssl/crypto/bn/bn_prime.h
@@ -0,0 +1,327 @@
+/* Auto generated by bn_prime.pl */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef EIGHT_BIT
+#define NUMPRIMES 2048
+typedef unsigned short prime_t;
+#else
+#define NUMPRIMES 54
+typedef unsigned char prime_t;
+#endif
+static const prime_t primes[NUMPRIMES]=
+	{
+	   2,   3,   5,   7,  11,  13,  17,  19,
+	  23,  29,  31,  37,  41,  43,  47,  53,
+	  59,  61,  67,  71,  73,  79,  83,  89,
+	  97, 101, 103, 107, 109, 113, 127, 131,
+	 137, 139, 149, 151, 157, 163, 167, 173,
+	 179, 181, 191, 193, 197, 199, 211, 223,
+	 227, 229, 233, 239, 241, 251,
+#ifndef EIGHT_BIT
+	 257, 263,
+	 269, 271, 277, 281, 283, 293, 307, 311,
+	 313, 317, 331, 337, 347, 349, 353, 359,
+	 367, 373, 379, 383, 389, 397, 401, 409,
+	 419, 421, 431, 433, 439, 443, 449, 457,
+	 461, 463, 467, 479, 487, 491, 499, 503,
+	 509, 521, 523, 541, 547, 557, 563, 569,
+	 571, 577, 587, 593, 599, 601, 607, 613,
+	 617, 619, 631, 641, 643, 647, 653, 659,
+	 661, 673, 677, 683, 691, 701, 709, 719,
+	 727, 733, 739, 743, 751, 757, 761, 769,
+	 773, 787, 797, 809, 811, 821, 823, 827,
+	 829, 839, 853, 857, 859, 863, 877, 881,
+	 883, 887, 907, 911, 919, 929, 937, 941,
+	 947, 953, 967, 971, 977, 983, 991, 997,
+	1009,1013,1019,1021,1031,1033,1039,1049,
+	1051,1061,1063,1069,1087,1091,1093,1097,
+	1103,1109,1117,1123,1129,1151,1153,1163,
+	1171,1181,1187,1193,1201,1213,1217,1223,
+	1229,1231,1237,1249,1259,1277,1279,1283,
+	1289,1291,1297,1301,1303,1307,1319,1321,
+	1327,1361,1367,1373,1381,1399,1409,1423,
+	1427,1429,1433,1439,1447,1451,1453,1459,
+	1471,1481,1483,1487,1489,1493,1499,1511,
+	1523,1531,1543,1549,1553,1559,1567,1571,
+	1579,1583,1597,1601,1607,1609,1613,1619,
+	1621,1627,1637,1657,1663,1667,1669,1693,
+	1697,1699,1709,1721,1723,1733,1741,1747,
+	1753,1759,1777,1783,1787,1789,1801,1811,
+	1823,1831,1847,1861,1867,1871,1873,1877,
+	1879,1889,1901,1907,1913,1931,1933,1949,
+	1951,1973,1979,1987,1993,1997,1999,2003,
+	2011,2017,2027,2029,2039,2053,2063,2069,
+	2081,2083,2087,2089,2099,2111,2113,2129,
+	2131,2137,2141,2143,2153,2161,2179,2203,
+	2207,2213,2221,2237,2239,2243,2251,2267,
+	2269,2273,2281,2287,2293,2297,2309,2311,
+	2333,2339,2341,2347,2351,2357,2371,2377,
+	2381,2383,2389,2393,2399,2411,2417,2423,
+	2437,2441,2447,2459,2467,2473,2477,2503,
+	2521,2531,2539,2543,2549,2551,2557,2579,
+	2591,2593,2609,2617,2621,2633,2647,2657,
+	2659,2663,2671,2677,2683,2687,2689,2693,
+	2699,2707,2711,2713,2719,2729,2731,2741,
+	2749,2753,2767,2777,2789,2791,2797,2801,
+	2803,2819,2833,2837,2843,2851,2857,2861,
+	2879,2887,2897,2903,2909,2917,2927,2939,
+	2953,2957,2963,2969,2971,2999,3001,3011,
+	3019,3023,3037,3041,3049,3061,3067,3079,
+	3083,3089,3109,3119,3121,3137,3163,3167,
+	3169,3181,3187,3191,3203,3209,3217,3221,
+	3229,3251,3253,3257,3259,3271,3299,3301,
+	3307,3313,3319,3323,3329,3331,3343,3347,
+	3359,3361,3371,3373,3389,3391,3407,3413,
+	3433,3449,3457,3461,3463,3467,3469,3491,
+	3499,3511,3517,3527,3529,3533,3539,3541,
+	3547,3557,3559,3571,3581,3583,3593,3607,
+	3613,3617,3623,3631,3637,3643,3659,3671,
+	3673,3677,3691,3697,3701,3709,3719,3727,
+	3733,3739,3761,3767,3769,3779,3793,3797,
+	3803,3821,3823,3833,3847,3851,3853,3863,
+	3877,3881,3889,3907,3911,3917,3919,3923,
+	3929,3931,3943,3947,3967,3989,4001,4003,
+	4007,4013,4019,4021,4027,4049,4051,4057,
+	4073,4079,4091,4093,4099,4111,4127,4129,
+	4133,4139,4153,4157,4159,4177,4201,4211,
+	4217,4219,4229,4231,4241,4243,4253,4259,
+	4261,4271,4273,4283,4289,4297,4327,4337,
+	4339,4349,4357,4363,4373,4391,4397,4409,
+	4421,4423,4441,4447,4451,4457,4463,4481,
+	4483,4493,4507,4513,4517,4519,4523,4547,
+	4549,4561,4567,4583,4591,4597,4603,4621,
+	4637,4639,4643,4649,4651,4657,4663,4673,
+	4679,4691,4703,4721,4723,4729,4733,4751,
+	4759,4783,4787,4789,4793,4799,4801,4813,
+	4817,4831,4861,4871,4877,4889,4903,4909,
+	4919,4931,4933,4937,4943,4951,4957,4967,
+	4969,4973,4987,4993,4999,5003,5009,5011,
+	5021,5023,5039,5051,5059,5077,5081,5087,
+	5099,5101,5107,5113,5119,5147,5153,5167,
+	5171,5179,5189,5197,5209,5227,5231,5233,
+	5237,5261,5273,5279,5281,5297,5303,5309,
+	5323,5333,5347,5351,5381,5387,5393,5399,
+	5407,5413,5417,5419,5431,5437,5441,5443,
+	5449,5471,5477,5479,5483,5501,5503,5507,
+	5519,5521,5527,5531,5557,5563,5569,5573,
+	5581,5591,5623,5639,5641,5647,5651,5653,
+	5657,5659,5669,5683,5689,5693,5701,5711,
+	5717,5737,5741,5743,5749,5779,5783,5791,
+	5801,5807,5813,5821,5827,5839,5843,5849,
+	5851,5857,5861,5867,5869,5879,5881,5897,
+	5903,5923,5927,5939,5953,5981,5987,6007,
+	6011,6029,6037,6043,6047,6053,6067,6073,
+	6079,6089,6091,6101,6113,6121,6131,6133,
+	6143,6151,6163,6173,6197,6199,6203,6211,
+	6217,6221,6229,6247,6257,6263,6269,6271,
+	6277,6287,6299,6301,6311,6317,6323,6329,
+	6337,6343,6353,6359,6361,6367,6373,6379,
+	6389,6397,6421,6427,6449,6451,6469,6473,
+	6481,6491,6521,6529,6547,6551,6553,6563,
+	6569,6571,6577,6581,6599,6607,6619,6637,
+	6653,6659,6661,6673,6679,6689,6691,6701,
+	6703,6709,6719,6733,6737,6761,6763,6779,
+	6781,6791,6793,6803,6823,6827,6829,6833,
+	6841,6857,6863,6869,6871,6883,6899,6907,
+	6911,6917,6947,6949,6959,6961,6967,6971,
+	6977,6983,6991,6997,7001,7013,7019,7027,
+	7039,7043,7057,7069,7079,7103,7109,7121,
+	7127,7129,7151,7159,7177,7187,7193,7207,
+	7211,7213,7219,7229,7237,7243,7247,7253,
+	7283,7297,7307,7309,7321,7331,7333,7349,
+	7351,7369,7393,7411,7417,7433,7451,7457,
+	7459,7477,7481,7487,7489,7499,7507,7517,
+	7523,7529,7537,7541,7547,7549,7559,7561,
+	7573,7577,7583,7589,7591,7603,7607,7621,
+	7639,7643,7649,7669,7673,7681,7687,7691,
+	7699,7703,7717,7723,7727,7741,7753,7757,
+	7759,7789,7793,7817,7823,7829,7841,7853,
+	7867,7873,7877,7879,7883,7901,7907,7919,
+	7927,7933,7937,7949,7951,7963,7993,8009,
+	8011,8017,8039,8053,8059,8069,8081,8087,
+	8089,8093,8101,8111,8117,8123,8147,8161,
+	8167,8171,8179,8191,8209,8219,8221,8231,
+	8233,8237,8243,8263,8269,8273,8287,8291,
+	8293,8297,8311,8317,8329,8353,8363,8369,
+	8377,8387,8389,8419,8423,8429,8431,8443,
+	8447,8461,8467,8501,8513,8521,8527,8537,
+	8539,8543,8563,8573,8581,8597,8599,8609,
+	8623,8627,8629,8641,8647,8663,8669,8677,
+	8681,8689,8693,8699,8707,8713,8719,8731,
+	8737,8741,8747,8753,8761,8779,8783,8803,
+	8807,8819,8821,8831,8837,8839,8849,8861,
+	8863,8867,8887,8893,8923,8929,8933,8941,
+	8951,8963,8969,8971,8999,9001,9007,9011,
+	9013,9029,9041,9043,9049,9059,9067,9091,
+	9103,9109,9127,9133,9137,9151,9157,9161,
+	9173,9181,9187,9199,9203,9209,9221,9227,
+	9239,9241,9257,9277,9281,9283,9293,9311,
+	9319,9323,9337,9341,9343,9349,9371,9377,
+	9391,9397,9403,9413,9419,9421,9431,9433,
+	9437,9439,9461,9463,9467,9473,9479,9491,
+	9497,9511,9521,9533,9539,9547,9551,9587,
+	9601,9613,9619,9623,9629,9631,9643,9649,
+	9661,9677,9679,9689,9697,9719,9721,9733,
+	9739,9743,9749,9767,9769,9781,9787,9791,
+	9803,9811,9817,9829,9833,9839,9851,9857,
+	9859,9871,9883,9887,9901,9907,9923,9929,
+	9931,9941,9949,9967,9973,10007,10009,10037,
+	10039,10061,10067,10069,10079,10091,10093,10099,
+	10103,10111,10133,10139,10141,10151,10159,10163,
+	10169,10177,10181,10193,10211,10223,10243,10247,
+	10253,10259,10267,10271,10273,10289,10301,10303,
+	10313,10321,10331,10333,10337,10343,10357,10369,
+	10391,10399,10427,10429,10433,10453,10457,10459,
+	10463,10477,10487,10499,10501,10513,10529,10531,
+	10559,10567,10589,10597,10601,10607,10613,10627,
+	10631,10639,10651,10657,10663,10667,10687,10691,
+	10709,10711,10723,10729,10733,10739,10753,10771,
+	10781,10789,10799,10831,10837,10847,10853,10859,
+	10861,10867,10883,10889,10891,10903,10909,10937,
+	10939,10949,10957,10973,10979,10987,10993,11003,
+	11027,11047,11057,11059,11069,11071,11083,11087,
+	11093,11113,11117,11119,11131,11149,11159,11161,
+	11171,11173,11177,11197,11213,11239,11243,11251,
+	11257,11261,11273,11279,11287,11299,11311,11317,
+	11321,11329,11351,11353,11369,11383,11393,11399,
+	11411,11423,11437,11443,11447,11467,11471,11483,
+	11489,11491,11497,11503,11519,11527,11549,11551,
+	11579,11587,11593,11597,11617,11621,11633,11657,
+	11677,11681,11689,11699,11701,11717,11719,11731,
+	11743,11777,11779,11783,11789,11801,11807,11813,
+	11821,11827,11831,11833,11839,11863,11867,11887,
+	11897,11903,11909,11923,11927,11933,11939,11941,
+	11953,11959,11969,11971,11981,11987,12007,12011,
+	12037,12041,12043,12049,12071,12073,12097,12101,
+	12107,12109,12113,12119,12143,12149,12157,12161,
+	12163,12197,12203,12211,12227,12239,12241,12251,
+	12253,12263,12269,12277,12281,12289,12301,12323,
+	12329,12343,12347,12373,12377,12379,12391,12401,
+	12409,12413,12421,12433,12437,12451,12457,12473,
+	12479,12487,12491,12497,12503,12511,12517,12527,
+	12539,12541,12547,12553,12569,12577,12583,12589,
+	12601,12611,12613,12619,12637,12641,12647,12653,
+	12659,12671,12689,12697,12703,12713,12721,12739,
+	12743,12757,12763,12781,12791,12799,12809,12821,
+	12823,12829,12841,12853,12889,12893,12899,12907,
+	12911,12917,12919,12923,12941,12953,12959,12967,
+	12973,12979,12983,13001,13003,13007,13009,13033,
+	13037,13043,13049,13063,13093,13099,13103,13109,
+	13121,13127,13147,13151,13159,13163,13171,13177,
+	13183,13187,13217,13219,13229,13241,13249,13259,
+	13267,13291,13297,13309,13313,13327,13331,13337,
+	13339,13367,13381,13397,13399,13411,13417,13421,
+	13441,13451,13457,13463,13469,13477,13487,13499,
+	13513,13523,13537,13553,13567,13577,13591,13597,
+	13613,13619,13627,13633,13649,13669,13679,13681,
+	13687,13691,13693,13697,13709,13711,13721,13723,
+	13729,13751,13757,13759,13763,13781,13789,13799,
+	13807,13829,13831,13841,13859,13873,13877,13879,
+	13883,13901,13903,13907,13913,13921,13931,13933,
+	13963,13967,13997,13999,14009,14011,14029,14033,
+	14051,14057,14071,14081,14083,14087,14107,14143,
+	14149,14153,14159,14173,14177,14197,14207,14221,
+	14243,14249,14251,14281,14293,14303,14321,14323,
+	14327,14341,14347,14369,14387,14389,14401,14407,
+	14411,14419,14423,14431,14437,14447,14449,14461,
+	14479,14489,14503,14519,14533,14537,14543,14549,
+	14551,14557,14561,14563,14591,14593,14621,14627,
+	14629,14633,14639,14653,14657,14669,14683,14699,
+	14713,14717,14723,14731,14737,14741,14747,14753,
+	14759,14767,14771,14779,14783,14797,14813,14821,
+	14827,14831,14843,14851,14867,14869,14879,14887,
+	14891,14897,14923,14929,14939,14947,14951,14957,
+	14969,14983,15013,15017,15031,15053,15061,15073,
+	15077,15083,15091,15101,15107,15121,15131,15137,
+	15139,15149,15161,15173,15187,15193,15199,15217,
+	15227,15233,15241,15259,15263,15269,15271,15277,
+	15287,15289,15299,15307,15313,15319,15329,15331,
+	15349,15359,15361,15373,15377,15383,15391,15401,
+	15413,15427,15439,15443,15451,15461,15467,15473,
+	15493,15497,15511,15527,15541,15551,15559,15569,
+	15581,15583,15601,15607,15619,15629,15641,15643,
+	15647,15649,15661,15667,15671,15679,15683,15727,
+	15731,15733,15737,15739,15749,15761,15767,15773,
+	15787,15791,15797,15803,15809,15817,15823,15859,
+	15877,15881,15887,15889,15901,15907,15913,15919,
+	15923,15937,15959,15971,15973,15991,16001,16007,
+	16033,16057,16061,16063,16067,16069,16073,16087,
+	16091,16097,16103,16111,16127,16139,16141,16183,
+	16187,16189,16193,16217,16223,16229,16231,16249,
+	16253,16267,16273,16301,16319,16333,16339,16349,
+	16361,16363,16369,16381,16411,16417,16421,16427,
+	16433,16447,16451,16453,16477,16481,16487,16493,
+	16519,16529,16547,16553,16561,16567,16573,16603,
+	16607,16619,16631,16633,16649,16651,16657,16661,
+	16673,16691,16693,16699,16703,16729,16741,16747,
+	16759,16763,16787,16811,16823,16829,16831,16843,
+	16871,16879,16883,16889,16901,16903,16921,16927,
+	16931,16937,16943,16963,16979,16981,16987,16993,
+	17011,17021,17027,17029,17033,17041,17047,17053,
+	17077,17093,17099,17107,17117,17123,17137,17159,
+	17167,17183,17189,17191,17203,17207,17209,17231,
+	17239,17257,17291,17293,17299,17317,17321,17327,
+	17333,17341,17351,17359,17377,17383,17387,17389,
+	17393,17401,17417,17419,17431,17443,17449,17467,
+	17471,17477,17483,17489,17491,17497,17509,17519,
+	17539,17551,17569,17573,17579,17581,17597,17599,
+	17609,17623,17627,17657,17659,17669,17681,17683,
+	17707,17713,17729,17737,17747,17749,17761,17783,
+	17789,17791,17807,17827,17837,17839,17851,17863,
+#endif
+	};
diff --git a/openssl/crypto/bn/bn_prime.pl b/openssl/crypto/bn/bn_prime.pl
new file mode 100644
index 0000000..3fafb6f
--- /dev/null
+++ b/openssl/crypto/bn/bn_prime.pl
@@ -0,0 +1,119 @@
+#!/usr/local/bin/perl
+# bn_prime.pl
+
+$num=2048;
+$num=$ARGV[0] if ($#ARGV >= 0);
+
+push(@primes,2);
+$p=1;
+loop: while ($#primes < $num-1)
+	{
+	$p+=2;
+	$s=int(sqrt($p));
+
+	for ($i=0; defined($primes[$i]) && $primes[$i]<=$s; $i++)
+		{
+		next loop if (($p%$primes[$i]) == 0);
+		}
+	push(@primes,$p);
+	}
+
+# print <<"EOF";
+# /* Auto generated by bn_prime.pl */
+# /* Copyright (C) 1995-1997 Eric Young (eay\@mincom.oz.au).
+#  * All rights reserved.
+#  * Copyright remains Eric Young's, and as such any Copyright notices in
+#  * the code are not to be removed.
+#  * See the COPYRIGHT file in the SSLeay distribution for more details.
+#  */
+# 
+# EOF
+
+print <<\EOF;
+/* Auto generated by bn_prime.pl */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+EOF
+
+for ($i=0; $i <= $#primes; $i++)
+	{
+	if ($primes[$i] > 256)
+		{
+		$eight=$i;
+		last;
+		}
+	}
+
+printf "#ifndef EIGHT_BIT\n";
+printf "#define NUMPRIMES %d\n",$num;
+printf "typedef unsigned short prime_t;\n";
+printf "#else\n";
+printf "#define NUMPRIMES %d\n",$eight;
+printf "typedef unsigned char prime_t;\n";
+printf "#endif\n";
+print "static const prime_t primes[NUMPRIMES]=\n\t{\n\t";
+$init=0;
+for ($i=0; $i <= $#primes; $i++)
+	{
+	printf "\n#ifndef EIGHT_BIT\n\t" if ($primes[$i] > 256) && !($init++);
+	printf("\n\t") if (($i%8) == 0) && ($i != 0);
+	printf("%4d,",$primes[$i]);
+	}
+print "\n#endif\n\t};\n";
+
+
diff --git a/openssl/crypto/bn/bn_print.c b/openssl/crypto/bn/bn_print.c
new file mode 100644
index 0000000..bebb466
--- /dev/null
+++ b/openssl/crypto/bn/bn_print.c
@@ -0,0 +1,359 @@
+/* crypto/bn/bn_print.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include "bn_lcl.h"
+
+static const char Hex[]="0123456789ABCDEF";
+
+/* Must 'OPENSSL_free' the returned data */
+char *BN_bn2hex(const BIGNUM *a)
+	{
+	int i,j,v,z=0;
+	char *buf;
+	char *p;
+
+	buf=(char *)OPENSSL_malloc(a->top*BN_BYTES*2+2);
+	if (buf == NULL)
+		{
+		BNerr(BN_F_BN_BN2HEX,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	p=buf;
+	if (a->neg) *(p++)='-';
+	if (BN_is_zero(a)) *(p++)='0';
+	for (i=a->top-1; i >=0; i--)
+		{
+		for (j=BN_BITS2-8; j >= 0; j-=8)
+			{
+			/* strip leading zeros */
+			v=((int)(a->d[i]>>(long)j))&0xff;
+			if (z || (v != 0))
+				{
+				*(p++)=Hex[v>>4];
+				*(p++)=Hex[v&0x0f];
+				z=1;
+				}
+			}
+		}
+	*p='\0';
+err:
+	return(buf);
+	}
+
+/* Must 'OPENSSL_free' the returned data */
+char *BN_bn2dec(const BIGNUM *a)
+	{
+	int i=0,num, ok = 0;
+	char *buf=NULL;
+	char *p;
+	BIGNUM *t=NULL;
+	BN_ULONG *bn_data=NULL,*lp;
+
+	/* get an upper bound for the length of the decimal integer
+	 * num <= (BN_num_bits(a) + 1) * log(2)
+	 *     <= 3 * BN_num_bits(a) * 0.1001 + log(2) + 1     (rounding error)
+	 *     <= BN_num_bits(a)/10 + BN_num_bits/1000 + 1 + 1 
+	 */
+	i=BN_num_bits(a)*3;
+	num=(i/10+i/1000+1)+1;
+	bn_data=(BN_ULONG *)OPENSSL_malloc((num/BN_DEC_NUM+1)*sizeof(BN_ULONG));
+	buf=(char *)OPENSSL_malloc(num+3);
+	if ((buf == NULL) || (bn_data == NULL))
+		{
+		BNerr(BN_F_BN_BN2DEC,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	if ((t=BN_dup(a)) == NULL) goto err;
+
+#define BUF_REMAIN (num+3 - (size_t)(p - buf))
+	p=buf;
+	lp=bn_data;
+	if (BN_is_zero(t))
+		{
+		*(p++)='0';
+		*(p++)='\0';
+		}
+	else
+		{
+		if (BN_is_negative(t))
+			*p++ = '-';
+
+		i=0;
+		while (!BN_is_zero(t))
+			{
+			*lp=BN_div_word(t,BN_DEC_CONV);
+			lp++;
+			}
+		lp--;
+		/* We now have a series of blocks, BN_DEC_NUM chars
+		 * in length, where the last one needs truncation.
+		 * The blocks need to be reversed in order. */
+		BIO_snprintf(p,BUF_REMAIN,BN_DEC_FMT1,*lp);
+		while (*p) p++;
+		while (lp != bn_data)
+			{
+			lp--;
+			BIO_snprintf(p,BUF_REMAIN,BN_DEC_FMT2,*lp);
+			while (*p) p++;
+			}
+		}
+	ok = 1;
+err:
+	if (bn_data != NULL) OPENSSL_free(bn_data);
+	if (t != NULL) BN_free(t);
+	if (!ok && buf)
+		{
+		OPENSSL_free(buf);
+		buf = NULL;
+		}
+
+	return(buf);
+	}
+
+int BN_hex2bn(BIGNUM **bn, const char *a)
+	{
+	BIGNUM *ret=NULL;
+	BN_ULONG l=0;
+	int neg=0,h,m,i,j,k,c;
+	int num;
+
+	if ((a == NULL) || (*a == '\0')) return(0);
+
+	if (*a == '-') { neg=1; a++; }
+
+	for (i=0; isxdigit((unsigned char) a[i]); i++)
+		;
+
+	num=i+neg;
+	if (bn == NULL) return(num);
+
+	/* a is the start of the hex digits, and it is 'i' long */
+	if (*bn == NULL)
+		{
+		if ((ret=BN_new()) == NULL) return(0);
+		}
+	else
+		{
+		ret= *bn;
+		BN_zero(ret);
+		}
+
+	/* i is the number of hex digests; */
+	if (bn_expand(ret,i*4) == NULL) goto err;
+
+	j=i; /* least significant 'hex' */
+	m=0;
+	h=0;
+	while (j > 0)
+		{
+		m=((BN_BYTES*2) <= j)?(BN_BYTES*2):j;
+		l=0;
+		for (;;)
+			{
+			c=a[j-m];
+			if ((c >= '0') && (c <= '9')) k=c-'0';
+			else if ((c >= 'a') && (c <= 'f')) k=c-'a'+10;
+			else if ((c >= 'A') && (c <= 'F')) k=c-'A'+10;
+			else k=0; /* paranoia */
+			l=(l<<4)|k;
+
+			if (--m <= 0)
+				{
+				ret->d[h++]=l;
+				break;
+				}
+			}
+		j-=(BN_BYTES*2);
+		}
+	ret->top=h;
+	bn_correct_top(ret);
+	ret->neg=neg;
+
+	*bn=ret;
+	bn_check_top(ret);
+	return(num);
+err:
+	if (*bn == NULL) BN_free(ret);
+	return(0);
+	}
+
+int BN_dec2bn(BIGNUM **bn, const char *a)
+	{
+	BIGNUM *ret=NULL;
+	BN_ULONG l=0;
+	int neg=0,i,j;
+	int num;
+
+	if ((a == NULL) || (*a == '\0')) return(0);
+	if (*a == '-') { neg=1; a++; }
+
+	for (i=0; isdigit((unsigned char) a[i]); i++)
+		;
+
+	num=i+neg;
+	if (bn == NULL) return(num);
+
+	/* a is the start of the digits, and it is 'i' long.
+	 * We chop it into BN_DEC_NUM digits at a time */
+	if (*bn == NULL)
+		{
+		if ((ret=BN_new()) == NULL) return(0);
+		}
+	else
+		{
+		ret= *bn;
+		BN_zero(ret);
+		}
+
+	/* i is the number of digests, a bit of an over expand; */
+	if (bn_expand(ret,i*4) == NULL) goto err;
+
+	j=BN_DEC_NUM-(i%BN_DEC_NUM);
+	if (j == BN_DEC_NUM) j=0;
+	l=0;
+	while (*a)
+		{
+		l*=10;
+		l+= *a-'0';
+		a++;
+		if (++j == BN_DEC_NUM)
+			{
+			BN_mul_word(ret,BN_DEC_CONV);
+			BN_add_word(ret,l);
+			l=0;
+			j=0;
+			}
+		}
+	ret->neg=neg;
+
+	bn_correct_top(ret);
+	*bn=ret;
+	bn_check_top(ret);
+	return(num);
+err:
+	if (*bn == NULL) BN_free(ret);
+	return(0);
+	}
+
+int BN_asc2bn(BIGNUM **bn, const char *a)
+	{
+	const char *p = a;
+	if (*p == '-')
+		p++;
+
+	if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x'))
+		{		
+		if (!BN_hex2bn(bn, p + 2))
+			return 0;
+		}
+	else
+		{
+		if (!BN_dec2bn(bn, p))
+			return 0;
+		}
+	if (*a == '-')
+		(*bn)->neg = 1;
+	return 1;
+	}
+
+#ifndef OPENSSL_NO_BIO
+#ifndef OPENSSL_NO_FP_API
+int BN_print_fp(FILE *fp, const BIGNUM *a)
+	{
+	BIO *b;
+	int ret;
+
+	if ((b=BIO_new(BIO_s_file())) == NULL)
+		return(0);
+	BIO_set_fp(b,fp,BIO_NOCLOSE);
+	ret=BN_print(b,a);
+	BIO_free(b);
+	return(ret);
+	}
+#endif
+
+int BN_print(BIO *bp, const BIGNUM *a)
+	{
+	int i,j,v,z=0;
+	int ret=0;
+
+	if ((a->neg) && (BIO_write(bp,"-",1) != 1)) goto end;
+	if (BN_is_zero(a) && (BIO_write(bp,"0",1) != 1)) goto end;
+	for (i=a->top-1; i >=0; i--)
+		{
+		for (j=BN_BITS2-4; j >= 0; j-=4)
+			{
+			/* strip leading zeros */
+			v=((int)(a->d[i]>>(long)j))&0x0f;
+			if (z || (v != 0))
+				{
+				if (BIO_write(bp,&(Hex[v]),1) != 1)
+					goto end;
+				z=1;
+				}
+			}
+		}
+	ret=1;
+end:
+	return(ret);
+	}
+#endif
diff --git a/openssl/crypto/bn/bn_rand.c b/openssl/crypto/bn/bn_rand.c
new file mode 100644
index 0000000..b376c28
--- /dev/null
+++ b/openssl/crypto/bn/bn_rand.c
@@ -0,0 +1,305 @@
+/* crypto/bn/bn_rand.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+#include <openssl/rand.h>
+
+static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
+	{
+	unsigned char *buf=NULL;
+	int ret=0,bit,bytes,mask;
+	time_t tim;
+
+	if (bits == 0)
+		{
+		BN_zero(rnd);
+		return 1;
+		}
+
+	bytes=(bits+7)/8;
+	bit=(bits-1)%8;
+	mask=0xff<<(bit+1);
+
+	buf=(unsigned char *)OPENSSL_malloc(bytes);
+	if (buf == NULL)
+		{
+		BNerr(BN_F_BNRAND,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	/* make a random number and set the top and bottom bits */
+	time(&tim);
+	RAND_add(&tim,sizeof(tim),0.0);
+
+	if (pseudorand)
+		{
+		if (RAND_pseudo_bytes(buf, bytes) == -1)
+			goto err;
+		}
+	else
+		{
+		if (RAND_bytes(buf, bytes) <= 0)
+			goto err;
+		}
+
+#if 1
+	if (pseudorand == 2)
+		{
+		/* generate patterns that are more likely to trigger BN
+		   library bugs */
+		int i;
+		unsigned char c;
+
+		for (i = 0; i < bytes; i++)
+			{
+			RAND_pseudo_bytes(&c, 1);
+			if (c >= 128 && i > 0)
+				buf[i] = buf[i-1];
+			else if (c < 42)
+				buf[i] = 0;
+			else if (c < 84)
+				buf[i] = 255;
+			}
+		}
+#endif
+
+	if (top != -1)
+		{
+		if (top)
+			{
+			if (bit == 0)
+				{
+				buf[0]=1;
+				buf[1]|=0x80;
+				}
+			else
+				{
+				buf[0]|=(3<<(bit-1));
+				}
+			}
+		else
+			{
+			buf[0]|=(1<<bit);
+			}
+		}
+	buf[0] &= ~mask;
+	if (bottom) /* set bottom bit if requested */
+		buf[bytes-1]|=1;
+	if (!BN_bin2bn(buf,bytes,rnd)) goto err;
+	ret=1;
+err:
+	if (buf != NULL)
+		{
+		OPENSSL_cleanse(buf,bytes);
+		OPENSSL_free(buf);
+		}
+	bn_check_top(rnd);
+	return(ret);
+	}
+
+int     BN_rand(BIGNUM *rnd, int bits, int top, int bottom)
+	{
+	return bnrand(0, rnd, bits, top, bottom);
+	}
+
+int     BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom)
+	{
+	return bnrand(1, rnd, bits, top, bottom);
+	}
+
+#if 1
+int     BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom)
+	{
+	return bnrand(2, rnd, bits, top, bottom);
+	}
+#endif
+
+
+/* random number r:  0 <= r < range */
+static int bn_rand_range(int pseudo, BIGNUM *r, const BIGNUM *range)
+	{
+	int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand;
+	int n;
+	int count = 100;
+
+	if (range->neg || BN_is_zero(range))
+		{
+		BNerr(BN_F_BN_RAND_RANGE, BN_R_INVALID_RANGE);
+		return 0;
+		}
+
+	n = BN_num_bits(range); /* n > 0 */
+
+	/* BN_is_bit_set(range, n - 1) always holds */
+
+	if (n == 1)
+		BN_zero(r);
+	else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3))
+		{
+		/* range = 100..._2,
+		 * so  3*range (= 11..._2)  is exactly one bit longer than  range */
+		do
+			{
+			if (!bn_rand(r, n + 1, -1, 0)) return 0;
+			/* If  r < 3*range,  use  r := r MOD range
+			 * (which is either  r, r - range,  or  r - 2*range).
+			 * Otherwise, iterate once more.
+			 * Since  3*range = 11..._2, each iteration succeeds with
+			 * probability >= .75. */
+			if (BN_cmp(r ,range) >= 0)
+				{
+				if (!BN_sub(r, r, range)) return 0;
+				if (BN_cmp(r, range) >= 0)
+					if (!BN_sub(r, r, range)) return 0;
+				}
+
+			if (!--count)
+				{
+				BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
+				return 0;
+				}
+			
+			}
+		while (BN_cmp(r, range) >= 0);
+		}
+	else
+		{
+		do
+			{
+			/* range = 11..._2  or  range = 101..._2 */
+			if (!bn_rand(r, n, -1, 0)) return 0;
+
+			if (!--count)
+				{
+				BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
+				return 0;
+				}
+			}
+		while (BN_cmp(r, range) >= 0);
+		}
+
+	bn_check_top(r);
+	return 1;
+	}
+
+
+int	BN_rand_range(BIGNUM *r, const BIGNUM *range)
+	{
+	return bn_rand_range(0, r, range);
+	}
+
+int	BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range)
+	{
+	return bn_rand_range(1, r, range);
+	}
diff --git a/openssl/crypto/bn/bn_recp.c b/openssl/crypto/bn/bn_recp.c
new file mode 100644
index 0000000..2e8efb8
--- /dev/null
+++ b/openssl/crypto/bn/bn_recp.c
@@ -0,0 +1,234 @@
+/* crypto/bn/bn_recp.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+void BN_RECP_CTX_init(BN_RECP_CTX *recp)
+	{
+	BN_init(&(recp->N));
+	BN_init(&(recp->Nr));
+	recp->num_bits=0;
+	recp->flags=0;
+	}
+
+BN_RECP_CTX *BN_RECP_CTX_new(void)
+	{
+	BN_RECP_CTX *ret;
+
+	if ((ret=(BN_RECP_CTX *)OPENSSL_malloc(sizeof(BN_RECP_CTX))) == NULL)
+		return(NULL);
+
+	BN_RECP_CTX_init(ret);
+	ret->flags=BN_FLG_MALLOCED;
+	return(ret);
+	}
+
+void BN_RECP_CTX_free(BN_RECP_CTX *recp)
+	{
+	if(recp == NULL)
+	    return;
+
+	BN_free(&(recp->N));
+	BN_free(&(recp->Nr));
+	if (recp->flags & BN_FLG_MALLOCED)
+		OPENSSL_free(recp);
+	}
+
+int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
+	{
+	if (!BN_copy(&(recp->N),d)) return 0;
+	BN_zero(&(recp->Nr));
+	recp->num_bits=BN_num_bits(d);
+	recp->shift=0;
+	return(1);
+	}
+
+int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
+	BN_RECP_CTX *recp, BN_CTX *ctx)
+	{
+	int ret=0;
+	BIGNUM *a;
+	const BIGNUM *ca;
+
+	BN_CTX_start(ctx);
+	if ((a = BN_CTX_get(ctx)) == NULL) goto err;
+	if (y != NULL)
+		{
+		if (x == y)
+			{ if (!BN_sqr(a,x,ctx)) goto err; }
+		else
+			{ if (!BN_mul(a,x,y,ctx)) goto err; }
+		ca = a;
+		}
+	else
+		ca=x; /* Just do the mod */
+
+	ret = BN_div_recp(NULL,r,ca,recp,ctx);
+err:
+	BN_CTX_end(ctx);
+	bn_check_top(r);
+	return(ret);
+	}
+
+int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
+	BN_RECP_CTX *recp, BN_CTX *ctx)
+	{
+	int i,j,ret=0;
+	BIGNUM *a,*b,*d,*r;
+
+	BN_CTX_start(ctx);
+	a=BN_CTX_get(ctx);
+	b=BN_CTX_get(ctx);
+	if (dv != NULL)
+		d=dv;
+	else
+		d=BN_CTX_get(ctx);
+	if (rem != NULL)
+		r=rem;
+	else
+		r=BN_CTX_get(ctx);
+	if (a == NULL || b == NULL || d == NULL || r == NULL) goto err;
+
+	if (BN_ucmp(m,&(recp->N)) < 0)
+		{
+		BN_zero(d);
+		if (!BN_copy(r,m)) return 0;
+		BN_CTX_end(ctx);
+		return(1);
+		}
+
+	/* We want the remainder
+	 * Given input of ABCDEF / ab
+	 * we need multiply ABCDEF by 3 digests of the reciprocal of ab
+	 *
+	 */
+
+	/* i := max(BN_num_bits(m), 2*BN_num_bits(N)) */
+	i=BN_num_bits(m);
+	j=recp->num_bits<<1;
+	if (j>i) i=j;
+
+	/* Nr := round(2^i / N) */
+	if (i != recp->shift)
+		recp->shift=BN_reciprocal(&(recp->Nr),&(recp->N),
+			i,ctx); /* BN_reciprocal returns i, or -1 for an error */
+	if (recp->shift == -1) goto err;
+
+	/* d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i - BN_num_bits(N)))|
+	 *    = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i - BN_num_bits(N)))|
+	 *   <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)|
+	 *    = |m/N|
+	 */
+	if (!BN_rshift(a,m,recp->num_bits)) goto err;
+	if (!BN_mul(b,a,&(recp->Nr),ctx)) goto err;
+	if (!BN_rshift(d,b,i-recp->num_bits)) goto err;
+	d->neg=0;
+
+	if (!BN_mul(b,&(recp->N),d,ctx)) goto err;
+	if (!BN_usub(r,m,b)) goto err;
+	r->neg=0;
+
+#if 1
+	j=0;
+	while (BN_ucmp(r,&(recp->N)) >= 0)
+		{
+		if (j++ > 2)
+			{
+			BNerr(BN_F_BN_DIV_RECP,BN_R_BAD_RECIPROCAL);
+			goto err;
+			}
+		if (!BN_usub(r,r,&(recp->N))) goto err;
+		if (!BN_add_word(d,1)) goto err;
+		}
+#endif
+
+	r->neg=BN_is_zero(r)?0:m->neg;
+	d->neg=m->neg^recp->N.neg;
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	bn_check_top(dv);
+	bn_check_top(rem);
+	return(ret);
+	} 
+
+/* len is the expected size of the result
+ * We actually calculate with an extra word of precision, so
+ * we can do faster division if the remainder is not required.
+ */
+/* r := 2^len / m */
+int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx)
+	{
+	int ret= -1;
+	BIGNUM *t;
+
+	BN_CTX_start(ctx);
+	if((t = BN_CTX_get(ctx)) == NULL) goto err;
+
+	if (!BN_set_bit(t,len)) goto err;
+
+	if (!BN_div(r,NULL,t,m,ctx)) goto err;
+
+	ret=len;
+err:
+	bn_check_top(r);
+	BN_CTX_end(ctx);
+	return(ret);
+	}
diff --git a/openssl/crypto/bn/bn_shift.c b/openssl/crypto/bn/bn_shift.c
new file mode 100644
index 0000000..c4d301a
--- /dev/null
+++ b/openssl/crypto/bn/bn_shift.c
@@ -0,0 +1,220 @@
+/* crypto/bn/bn_shift.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+int BN_lshift1(BIGNUM *r, const BIGNUM *a)
+	{
+	register BN_ULONG *ap,*rp,t,c;
+	int i;
+
+	bn_check_top(r);
+	bn_check_top(a);
+
+	if (r != a)
+		{
+		r->neg=a->neg;
+		if (bn_wexpand(r,a->top+1) == NULL) return(0);
+		r->top=a->top;
+		}
+	else
+		{
+		if (bn_wexpand(r,a->top+1) == NULL) return(0);
+		}
+	ap=a->d;
+	rp=r->d;
+	c=0;
+	for (i=0; i<a->top; i++)
+		{
+		t= *(ap++);
+		*(rp++)=((t<<1)|c)&BN_MASK2;
+		c=(t & BN_TBIT)?1:0;
+		}
+	if (c)
+		{
+		*rp=1;
+		r->top++;
+		}
+	bn_check_top(r);
+	return(1);
+	}
+
+int BN_rshift1(BIGNUM *r, const BIGNUM *a)
+	{
+	BN_ULONG *ap,*rp,t,c;
+	int i;
+
+	bn_check_top(r);
+	bn_check_top(a);
+
+	if (BN_is_zero(a))
+		{
+		BN_zero(r);
+		return(1);
+		}
+	if (a != r)
+		{
+		if (bn_wexpand(r,a->top) == NULL) return(0);
+		r->top=a->top;
+		r->neg=a->neg;
+		}
+	ap=a->d;
+	rp=r->d;
+	c=0;
+	for (i=a->top-1; i>=0; i--)
+		{
+		t=ap[i];
+		rp[i]=((t>>1)&BN_MASK2)|c;
+		c=(t&1)?BN_TBIT:0;
+		}
+	bn_correct_top(r);
+	bn_check_top(r);
+	return(1);
+	}
+
+int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
+	{
+	int i,nw,lb,rb;
+	BN_ULONG *t,*f;
+	BN_ULONG l;
+
+	bn_check_top(r);
+	bn_check_top(a);
+
+	r->neg=a->neg;
+	nw=n/BN_BITS2;
+	if (bn_wexpand(r,a->top+nw+1) == NULL) return(0);
+	lb=n%BN_BITS2;
+	rb=BN_BITS2-lb;
+	f=a->d;
+	t=r->d;
+	t[a->top+nw]=0;
+	if (lb == 0)
+		for (i=a->top-1; i>=0; i--)
+			t[nw+i]=f[i];
+	else
+		for (i=a->top-1; i>=0; i--)
+			{
+			l=f[i];
+			t[nw+i+1]|=(l>>rb)&BN_MASK2;
+			t[nw+i]=(l<<lb)&BN_MASK2;
+			}
+	memset(t,0,nw*sizeof(t[0]));
+/*	for (i=0; i<nw; i++)
+		t[i]=0;*/
+	r->top=a->top+nw+1;
+	bn_correct_top(r);
+	bn_check_top(r);
+	return(1);
+	}
+
+int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
+	{
+	int i,j,nw,lb,rb;
+	BN_ULONG *t,*f;
+	BN_ULONG l,tmp;
+
+	bn_check_top(r);
+	bn_check_top(a);
+
+	nw=n/BN_BITS2;
+	rb=n%BN_BITS2;
+	lb=BN_BITS2-rb;
+	if (nw >= a->top || a->top == 0)
+		{
+		BN_zero(r);
+		return(1);
+		}
+	if (r != a)
+		{
+		r->neg=a->neg;
+		if (bn_wexpand(r,a->top-nw+1) == NULL) return(0);
+		}
+	else
+		{
+		if (n == 0)
+			return 1; /* or the copying loop will go berserk */
+		}
+
+	f= &(a->d[nw]);
+	t=r->d;
+	j=a->top-nw;
+	r->top=j;
+
+	if (rb == 0)
+		{
+		for (i=j; i != 0; i--)
+			*(t++)= *(f++);
+		}
+	else
+		{
+		l= *(f++);
+		for (i=j-1; i != 0; i--)
+			{
+			tmp =(l>>rb)&BN_MASK2;
+			l= *(f++);
+			*(t++) =(tmp|(l<<lb))&BN_MASK2;
+			}
+		*(t++) =(l>>rb)&BN_MASK2;
+		}
+	bn_correct_top(r);
+	bn_check_top(r);
+	return(1);
+	}
diff --git a/openssl/crypto/bn/bn_sqr.c b/openssl/crypto/bn/bn_sqr.c
new file mode 100644
index 0000000..270d0cd
--- /dev/null
+++ b/openssl/crypto/bn/bn_sqr.c
@@ -0,0 +1,294 @@
+/* crypto/bn/bn_sqr.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* r must not be a */
+/* I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 */
+int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
+	{
+	int max,al;
+	int ret = 0;
+	BIGNUM *tmp,*rr;
+
+#ifdef BN_COUNT
+	fprintf(stderr,"BN_sqr %d * %d\n",a->top,a->top);
+#endif
+	bn_check_top(a);
+
+	al=a->top;
+	if (al <= 0)
+		{
+		r->top=0;
+		return 1;
+		}
+
+	BN_CTX_start(ctx);
+	rr=(a != r) ? r : BN_CTX_get(ctx);
+	tmp=BN_CTX_get(ctx);
+	if (!rr || !tmp) goto err;
+
+	max = 2 * al; /* Non-zero (from above) */
+	if (bn_wexpand(rr,max) == NULL) goto err;
+
+	if (al == 4)
+		{
+#ifndef BN_SQR_COMBA
+		BN_ULONG t[8];
+		bn_sqr_normal(rr->d,a->d,4,t);
+#else
+		bn_sqr_comba4(rr->d,a->d);
+#endif
+		}
+	else if (al == 8)
+		{
+#ifndef BN_SQR_COMBA
+		BN_ULONG t[16];
+		bn_sqr_normal(rr->d,a->d,8,t);
+#else
+		bn_sqr_comba8(rr->d,a->d);
+#endif
+		}
+	else 
+		{
+#if defined(BN_RECURSION)
+		if (al < BN_SQR_RECURSIVE_SIZE_NORMAL)
+			{
+			BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL*2];
+			bn_sqr_normal(rr->d,a->d,al,t);
+			}
+		else
+			{
+			int j,k;
+
+			j=BN_num_bits_word((BN_ULONG)al);
+			j=1<<(j-1);
+			k=j+j;
+			if (al == j)
+				{
+				if (bn_wexpand(tmp,k*2) == NULL) goto err;
+				bn_sqr_recursive(rr->d,a->d,al,tmp->d);
+				}
+			else
+				{
+				if (bn_wexpand(tmp,max) == NULL) goto err;
+				bn_sqr_normal(rr->d,a->d,al,tmp->d);
+				}
+			}
+#else
+		if (bn_wexpand(tmp,max) == NULL) goto err;
+		bn_sqr_normal(rr->d,a->d,al,tmp->d);
+#endif
+		}
+
+	rr->neg=0;
+	/* If the most-significant half of the top word of 'a' is zero, then
+	 * the square of 'a' will max-1 words. */
+	if(a->d[al - 1] == (a->d[al - 1] & BN_MASK2l))
+		rr->top = max - 1;
+	else
+		rr->top = max;
+	if (rr != r) BN_copy(r,rr);
+	ret = 1;
+ err:
+	bn_check_top(rr);
+	bn_check_top(tmp);
+	BN_CTX_end(ctx);
+	return(ret);
+	}
+
+/* tmp must have 2*n words */
+void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
+	{
+	int i,j,max;
+	const BN_ULONG *ap;
+	BN_ULONG *rp;
+
+	max=n*2;
+	ap=a;
+	rp=r;
+	rp[0]=rp[max-1]=0;
+	rp++;
+	j=n;
+
+	if (--j > 0)
+		{
+		ap++;
+		rp[j]=bn_mul_words(rp,ap,j,ap[-1]);
+		rp+=2;
+		}
+
+	for (i=n-2; i>0; i--)
+		{
+		j--;
+		ap++;
+		rp[j]=bn_mul_add_words(rp,ap,j,ap[-1]);
+		rp+=2;
+		}
+
+	bn_add_words(r,r,r,max);
+
+	/* There will not be a carry */
+
+	bn_sqr_words(tmp,a,n);
+
+	bn_add_words(r,r,tmp,max);
+	}
+
+#ifdef BN_RECURSION
+/* r is 2*n words in size,
+ * a and b are both n words in size.    (There's not actually a 'b' here ...)
+ * n must be a power of 2.
+ * We multiply and return the result.
+ * t must be 2*n words in size
+ * We calculate
+ * a[0]*b[0]
+ * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
+ * a[1]*b[1]
+ */
+void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t)
+	{
+	int n=n2/2;
+	int zero,c1;
+	BN_ULONG ln,lo,*p;
+
+#ifdef BN_COUNT
+	fprintf(stderr," bn_sqr_recursive %d * %d\n",n2,n2);
+#endif
+	if (n2 == 4)
+		{
+#ifndef BN_SQR_COMBA
+		bn_sqr_normal(r,a,4,t);
+#else
+		bn_sqr_comba4(r,a);
+#endif
+		return;
+		}
+	else if (n2 == 8)
+		{
+#ifndef BN_SQR_COMBA
+		bn_sqr_normal(r,a,8,t);
+#else
+		bn_sqr_comba8(r,a);
+#endif
+		return;
+		}
+	if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL)
+		{
+		bn_sqr_normal(r,a,n2,t);
+		return;
+		}
+	/* r=(a[0]-a[1])*(a[1]-a[0]) */
+	c1=bn_cmp_words(a,&(a[n]),n);
+	zero=0;
+	if (c1 > 0)
+		bn_sub_words(t,a,&(a[n]),n);
+	else if (c1 < 0)
+		bn_sub_words(t,&(a[n]),a,n);
+	else
+		zero=1;
+
+	/* The result will always be negative unless it is zero */
+	p= &(t[n2*2]);
+
+	if (!zero)
+		bn_sqr_recursive(&(t[n2]),t,n,p);
+	else
+		memset(&(t[n2]),0,n2*sizeof(BN_ULONG));
+	bn_sqr_recursive(r,a,n,p);
+	bn_sqr_recursive(&(r[n2]),&(a[n]),n,p);
+
+	/* t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero
+	 * r[10] holds (a[0]*b[0])
+	 * r[32] holds (b[1]*b[1])
+	 */
+
+	c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
+
+	/* t[32] is negative */
+	c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
+
+	/* t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1])
+	 * r[10] holds (a[0]*a[0])
+	 * r[32] holds (a[1]*a[1])
+	 * c1 holds the carry bits
+	 */
+	c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
+	if (c1)
+		{
+		p= &(r[n+n2]);
+		lo= *p;
+		ln=(lo+c1)&BN_MASK2;
+		*p=ln;
+
+		/* The overflow will stop before we over write
+		 * words we should not overwrite */
+		if (ln < (BN_ULONG)c1)
+			{
+			do	{
+				p++;
+				lo= *p;
+				ln=(lo+1)&BN_MASK2;
+				*p=ln;
+				} while (ln == 0);
+			}
+		}
+	}
+#endif
diff --git a/openssl/crypto/bn/bn_sqrt.c b/openssl/crypto/bn/bn_sqrt.c
new file mode 100644
index 0000000..6beaf9e
--- /dev/null
+++ b/openssl/crypto/bn/bn_sqrt.c
@@ -0,0 +1,393 @@
+/* crypto/bn/bn_sqrt.c */
+/* Written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
+ * and Bodo Moeller for the OpenSSL project. */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+
+BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) 
+/* Returns 'ret' such that
+ *      ret^2 == a (mod p),
+ * using the Tonelli/Shanks algorithm (cf. Henri Cohen, "A Course
+ * in Algebraic Computational Number Theory", algorithm 1.5.1).
+ * 'p' must be prime!
+ */
+	{
+	BIGNUM *ret = in;
+	int err = 1;
+	int r;
+	BIGNUM *A, *b, *q, *t, *x, *y;
+	int e, i, j;
+	
+	if (!BN_is_odd(p) || BN_abs_is_word(p, 1))
+		{
+		if (BN_abs_is_word(p, 2))
+			{
+			if (ret == NULL)
+				ret = BN_new();
+			if (ret == NULL)
+				goto end;
+			if (!BN_set_word(ret, BN_is_bit_set(a, 0)))
+				{
+				if (ret != in)
+					BN_free(ret);
+				return NULL;
+				}
+			bn_check_top(ret);
+			return ret;
+			}
+
+		BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
+		return(NULL);
+		}
+
+	if (BN_is_zero(a) || BN_is_one(a))
+		{
+		if (ret == NULL)
+			ret = BN_new();
+		if (ret == NULL)
+			goto end;
+		if (!BN_set_word(ret, BN_is_one(a)))
+			{
+			if (ret != in)
+				BN_free(ret);
+			return NULL;
+			}
+		bn_check_top(ret);
+		return ret;
+		}
+
+	BN_CTX_start(ctx);
+	A = BN_CTX_get(ctx);
+	b = BN_CTX_get(ctx);
+	q = BN_CTX_get(ctx);
+	t = BN_CTX_get(ctx);
+	x = BN_CTX_get(ctx);
+	y = BN_CTX_get(ctx);
+	if (y == NULL) goto end;
+	
+	if (ret == NULL)
+		ret = BN_new();
+	if (ret == NULL) goto end;
+
+	/* A = a mod p */
+	if (!BN_nnmod(A, a, p, ctx)) goto end;
+
+	/* now write  |p| - 1  as  2^e*q  where  q  is odd */
+	e = 1;
+	while (!BN_is_bit_set(p, e))
+		e++;
+	/* we'll set  q  later (if needed) */
+
+	if (e == 1)
+		{
+		/* The easy case:  (|p|-1)/2  is odd, so 2 has an inverse
+		 * modulo  (|p|-1)/2,  and square roots can be computed
+		 * directly by modular exponentiation.
+		 * We have
+		 *     2 * (|p|+1)/4 == 1   (mod (|p|-1)/2),
+		 * so we can use exponent  (|p|+1)/4,  i.e.  (|p|-3)/4 + 1.
+		 */
+		if (!BN_rshift(q, p, 2)) goto end;
+		q->neg = 0;
+		if (!BN_add_word(q, 1)) goto end;
+		if (!BN_mod_exp(ret, A, q, p, ctx)) goto end;
+		err = 0;
+		goto vrfy;
+		}
+	
+	if (e == 2)
+		{
+		/* |p| == 5  (mod 8)
+		 *
+		 * In this case  2  is always a non-square since
+		 * Legendre(2,p) = (-1)^((p^2-1)/8)  for any odd prime.
+		 * So if  a  really is a square, then  2*a  is a non-square.
+		 * Thus for
+		 *      b := (2*a)^((|p|-5)/8),
+		 *      i := (2*a)*b^2
+		 * we have
+		 *     i^2 = (2*a)^((1 + (|p|-5)/4)*2)
+		 *         = (2*a)^((p-1)/2)
+		 *         = -1;
+		 * so if we set
+		 *      x := a*b*(i-1),
+		 * then
+		 *     x^2 = a^2 * b^2 * (i^2 - 2*i + 1)
+		 *         = a^2 * b^2 * (-2*i)
+		 *         = a*(-i)*(2*a*b^2)
+		 *         = a*(-i)*i
+		 *         = a.
+		 *
+		 * (This is due to A.O.L. Atkin, 
+		 * <URL: http://listserv.nodak.edu/scripts/wa.exe?A2=ind9211&L=nmbrthry&O=T&P=562>,
+		 * November 1992.)
+		 */
+
+		/* t := 2*a */
+		if (!BN_mod_lshift1_quick(t, A, p)) goto end;
+
+		/* b := (2*a)^((|p|-5)/8) */
+		if (!BN_rshift(q, p, 3)) goto end;
+		q->neg = 0;
+		if (!BN_mod_exp(b, t, q, p, ctx)) goto end;
+
+		/* y := b^2 */
+		if (!BN_mod_sqr(y, b, p, ctx)) goto end;
+
+		/* t := (2*a)*b^2 - 1*/
+		if (!BN_mod_mul(t, t, y, p, ctx)) goto end;
+		if (!BN_sub_word(t, 1)) goto end;
+
+		/* x = a*b*t */
+		if (!BN_mod_mul(x, A, b, p, ctx)) goto end;
+		if (!BN_mod_mul(x, x, t, p, ctx)) goto end;
+
+		if (!BN_copy(ret, x)) goto end;
+		err = 0;
+		goto vrfy;
+		}
+	
+	/* e > 2, so we really have to use the Tonelli/Shanks algorithm.
+	 * First, find some  y  that is not a square. */
+	if (!BN_copy(q, p)) goto end; /* use 'q' as temp */
+	q->neg = 0;
+	i = 2;
+	do
+		{
+		/* For efficiency, try small numbers first;
+		 * if this fails, try random numbers.
+		 */
+		if (i < 22)
+			{
+			if (!BN_set_word(y, i)) goto end;
+			}
+		else
+			{
+			if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0)) goto end;
+			if (BN_ucmp(y, p) >= 0)
+				{
+				if (!(p->neg ? BN_add : BN_sub)(y, y, p)) goto end;
+				}
+			/* now 0 <= y < |p| */
+			if (BN_is_zero(y))
+				if (!BN_set_word(y, i)) goto end;
+			}
+		
+		r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */
+		if (r < -1) goto end;
+		if (r == 0)
+			{
+			/* m divides p */
+			BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
+			goto end;
+			}
+		}
+	while (r == 1 && ++i < 82);
+	
+	if (r != -1)
+		{
+		/* Many rounds and still no non-square -- this is more likely
+		 * a bug than just bad luck.
+		 * Even if  p  is not prime, we should have found some  y
+		 * such that r == -1.
+		 */
+		BNerr(BN_F_BN_MOD_SQRT, BN_R_TOO_MANY_ITERATIONS);
+		goto end;
+		}
+
+	/* Here's our actual 'q': */
+	if (!BN_rshift(q, q, e)) goto end;
+
+	/* Now that we have some non-square, we can find an element
+	 * of order  2^e  by computing its q'th power. */
+	if (!BN_mod_exp(y, y, q, p, ctx)) goto end;
+	if (BN_is_one(y))
+		{
+		BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
+		goto end;
+		}
+
+	/* Now we know that (if  p  is indeed prime) there is an integer
+	 * k,  0 <= k < 2^e,  such that
+	 *
+	 *      a^q * y^k == 1   (mod p).
+	 *
+	 * As  a^q  is a square and  y  is not,  k  must be even.
+	 * q+1  is even, too, so there is an element
+	 *
+	 *     X := a^((q+1)/2) * y^(k/2),
+	 *
+	 * and it satisfies
+	 *
+	 *     X^2 = a^q * a     * y^k
+	 *         = a,
+	 *
+	 * so it is the square root that we are looking for.
+	 */
+	
+	/* t := (q-1)/2  (note that  q  is odd) */
+	if (!BN_rshift1(t, q)) goto end;
+	
+	/* x := a^((q-1)/2) */
+	if (BN_is_zero(t)) /* special case: p = 2^e + 1 */
+		{
+		if (!BN_nnmod(t, A, p, ctx)) goto end;
+		if (BN_is_zero(t))
+			{
+			/* special case: a == 0  (mod p) */
+			BN_zero(ret);
+			err = 0;
+			goto end;
+			}
+		else
+			if (!BN_one(x)) goto end;
+		}
+	else
+		{
+		if (!BN_mod_exp(x, A, t, p, ctx)) goto end;
+		if (BN_is_zero(x))
+			{
+			/* special case: a == 0  (mod p) */
+			BN_zero(ret);
+			err = 0;
+			goto end;
+			}
+		}
+
+	/* b := a*x^2  (= a^q) */
+	if (!BN_mod_sqr(b, x, p, ctx)) goto end;
+	if (!BN_mod_mul(b, b, A, p, ctx)) goto end;
+	
+	/* x := a*x    (= a^((q+1)/2)) */
+	if (!BN_mod_mul(x, x, A, p, ctx)) goto end;
+
+	while (1)
+		{
+		/* Now  b  is  a^q * y^k  for some even  k  (0 <= k < 2^E
+		 * where  E  refers to the original value of  e,  which we
+		 * don't keep in a variable),  and  x  is  a^((q+1)/2) * y^(k/2).
+		 *
+		 * We have  a*b = x^2,
+		 *    y^2^(e-1) = -1,
+		 *    b^2^(e-1) = 1.
+		 */
+
+		if (BN_is_one(b))
+			{
+			if (!BN_copy(ret, x)) goto end;
+			err = 0;
+			goto vrfy;
+			}
+
+
+		/* find smallest  i  such that  b^(2^i) = 1 */
+		i = 1;
+		if (!BN_mod_sqr(t, b, p, ctx)) goto end;
+		while (!BN_is_one(t))
+			{
+			i++;
+			if (i == e)
+				{
+				BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
+				goto end;
+				}
+			if (!BN_mod_mul(t, t, t, p, ctx)) goto end;
+			}
+		
+
+		/* t := y^2^(e - i - 1) */
+		if (!BN_copy(t, y)) goto end;
+		for (j = e - i - 1; j > 0; j--)
+			{
+			if (!BN_mod_sqr(t, t, p, ctx)) goto end;
+			}
+		if (!BN_mod_mul(y, t, t, p, ctx)) goto end;
+		if (!BN_mod_mul(x, x, t, p, ctx)) goto end;
+		if (!BN_mod_mul(b, b, y, p, ctx)) goto end;
+		e = i;
+		}
+
+ vrfy:
+	if (!err)
+		{
+		/* verify the result -- the input might have been not a square
+		 * (test added in 0.9.8) */
+		
+		if (!BN_mod_sqr(x, ret, p, ctx))
+			err = 1;
+		
+		if (!err && 0 != BN_cmp(x, A))
+			{
+			BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
+			err = 1;
+			}
+		}
+
+ end:
+	if (err)
+		{
+		if (ret != NULL && ret != in)
+			{
+			BN_clear_free(ret);
+			}
+		ret = NULL;
+		}
+	BN_CTX_end(ctx);
+	bn_check_top(ret);
+	return ret;
+	}
diff --git a/openssl/crypto/bn/bn_word.c b/openssl/crypto/bn/bn_word.c
new file mode 100644
index 0000000..ee7b87c
--- /dev/null
+++ b/openssl/crypto/bn/bn_word.c
@@ -0,0 +1,247 @@
+/* crypto/bn/bn_word.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
+	{
+#ifndef BN_LLONG
+	BN_ULONG ret=0;
+#else
+	BN_ULLONG ret=0;
+#endif
+	int i;
+
+	if (w == 0)
+		return (BN_ULONG)-1;
+
+	bn_check_top(a);
+	w&=BN_MASK2;
+	for (i=a->top-1; i>=0; i--)
+		{
+#ifndef BN_LLONG
+		ret=((ret<<BN_BITS4)|((a->d[i]>>BN_BITS4)&BN_MASK2l))%w;
+		ret=((ret<<BN_BITS4)|(a->d[i]&BN_MASK2l))%w;
+#else
+		ret=(BN_ULLONG)(((ret<<(BN_ULLONG)BN_BITS2)|a->d[i])%
+			(BN_ULLONG)w);
+#endif
+		}
+	return((BN_ULONG)ret);
+	}
+
+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
+	{
+	BN_ULONG ret = 0;
+	int i, j;
+
+	bn_check_top(a);
+	w &= BN_MASK2;
+
+	if (!w)
+		/* actually this an error (division by zero) */
+		return (BN_ULONG)-1;
+	if (a->top == 0)
+		return 0;
+
+	/* normalize input (so bn_div_words doesn't complain) */
+	j = BN_BITS2 - BN_num_bits_word(w);
+	w <<= j;
+	if (!BN_lshift(a, a, j))
+		return (BN_ULONG)-1;
+
+	for (i=a->top-1; i>=0; i--)
+		{
+		BN_ULONG l,d;
+		
+		l=a->d[i];
+		d=bn_div_words(ret,l,w);
+		ret=(l-((d*w)&BN_MASK2))&BN_MASK2;
+		a->d[i]=d;
+		}
+	if ((a->top > 0) && (a->d[a->top-1] == 0))
+		a->top--;
+	ret >>= j;
+	bn_check_top(a);
+	return(ret);
+	}
+
+int BN_add_word(BIGNUM *a, BN_ULONG w)
+	{
+	BN_ULONG l;
+	int i;
+
+	bn_check_top(a);
+	w &= BN_MASK2;
+
+	/* degenerate case: w is zero */
+	if (!w) return 1;
+	/* degenerate case: a is zero */
+	if(BN_is_zero(a)) return BN_set_word(a, w);
+	/* handle 'a' when negative */
+	if (a->neg)
+		{
+		a->neg=0;
+		i=BN_sub_word(a,w);
+		if (!BN_is_zero(a))
+			a->neg=!(a->neg);
+		return(i);
+		}
+	/* Only expand (and risk failing) if it's possibly necessary */
+	if (((BN_ULONG)(a->d[a->top - 1] + 1) == 0) &&
+			(bn_wexpand(a,a->top+1) == NULL))
+		return(0);
+	i=0;
+	for (;;)
+		{
+		if (i >= a->top)
+			l=w;
+		else
+			l=(a->d[i]+w)&BN_MASK2;
+		a->d[i]=l;
+		if (w > l)
+			w=1;
+		else
+			break;
+		i++;
+		}
+	if (i >= a->top)
+		a->top++;
+	bn_check_top(a);
+	return(1);
+	}
+
+int BN_sub_word(BIGNUM *a, BN_ULONG w)
+	{
+	int i;
+
+	bn_check_top(a);
+	w &= BN_MASK2;
+
+	/* degenerate case: w is zero */
+	if (!w) return 1;
+	/* degenerate case: a is zero */
+	if(BN_is_zero(a))
+		{
+		i = BN_set_word(a,w);
+		if (i != 0)
+			BN_set_negative(a, 1);
+		return i;
+		}
+	/* handle 'a' when negative */
+	if (a->neg)
+		{
+		a->neg=0;
+		i=BN_add_word(a,w);
+		a->neg=1;
+		return(i);
+		}
+
+	if ((a->top == 1) && (a->d[0] < w))
+		{
+		a->d[0]=w-a->d[0];
+		a->neg=1;
+		return(1);
+		}
+	i=0;
+	for (;;)
+		{
+		if (a->d[i] >= w)
+			{
+			a->d[i]-=w;
+			break;
+			}
+		else
+			{
+			a->d[i]=(a->d[i]-w)&BN_MASK2;
+			i++;
+			w=1;
+			}
+		}
+	if ((a->d[i] == 0) && (i == (a->top-1)))
+		a->top--;
+	bn_check_top(a);
+	return(1);
+	}
+
+int BN_mul_word(BIGNUM *a, BN_ULONG w)
+	{
+	BN_ULONG ll;
+
+	bn_check_top(a);
+	w&=BN_MASK2;
+	if (a->top)
+		{
+		if (w == 0)
+			BN_zero(a);
+		else
+			{
+			ll=bn_mul_words(a->d,a->d,a->top,w);
+			if (ll)
+				{
+				if (bn_wexpand(a,a->top+1) == NULL) return(0);
+				a->d[a->top++]=ll;
+				}
+			}
+		}
+	bn_check_top(a);
+	return(1);
+	}
+
diff --git a/openssl/crypto/bn/bnspeed.c b/openssl/crypto/bn/bnspeed.c
new file mode 100644
index 0000000..b554ac8
--- /dev/null
+++ b/openssl/crypto/bn/bnspeed.c
@@ -0,0 +1,233 @@
+/* unused */
+
+/* crypto/bn/bnspeed.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* most of this code has been pilfered from my libdes speed.c program */
+
+#define BASENUM	1000000
+#undef PROG
+#define PROG bnspeed_main
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+
+#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
+#define TIMES
+#endif
+
+#ifndef _IRIX
+#include <time.h>
+#endif
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+#endif
+
+/* Depending on the VMS version, the tms structure is perhaps defined.
+   The __TMS macro will show if it was.  If it wasn't defined, we should
+   undefine TIMES, since that tells the rest of the program how things
+   should be handled.				-- Richard Levitte */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
+#undef TIMES
+#endif
+
+#ifndef TIMES
+#include <sys/timeb.h>
+#endif
+
+#if defined(sun) || defined(__ultrix)
+#define _POSIX_SOURCE
+#include <limits.h>
+#include <sys/param.h>
+#endif
+
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+
+/* The following if from times(3) man page.  It may need to be changed */
+#ifndef HZ
+# ifndef CLK_TCK
+#  ifndef _BSD_CLK_TCK_ /* FreeBSD hack */
+#   define HZ	100.0
+#  else /* _BSD_CLK_TCK_ */
+#   define HZ ((double)_BSD_CLK_TCK_)
+#  endif
+# else /* CLK_TCK */
+#  define HZ ((double)CLK_TCK)
+# endif
+#endif
+
+#undef BUFSIZE
+#define BUFSIZE	((long)1024*8)
+int run=0;
+
+static double Time_F(int s);
+#define START	0
+#define STOP	1
+
+static double Time_F(int s)
+	{
+	double ret;
+#ifdef TIMES
+	static struct tms tstart,tend;
+
+	if (s == START)
+		{
+		times(&tstart);
+		return(0);
+		}
+	else
+		{
+		times(&tend);
+		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
+		return((ret < 1e-3)?1e-3:ret);
+		}
+#else /* !times() */
+	static struct timeb tstart,tend;
+	long i;
+
+	if (s == START)
+		{
+		ftime(&tstart);
+		return(0);
+		}
+	else
+		{
+		ftime(&tend);
+		i=(long)tend.millitm-(long)tstart.millitm;
+		ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
+		return((ret < 0.001)?0.001:ret);
+		}
+#endif
+	}
+
+#define NUM_SIZES	5
+static int sizes[NUM_SIZES]={128,256,512,1024,2048};
+/*static int sizes[NUM_SIZES]={59,179,299,419,539}; */
+
+void do_mul(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_CTX *ctx); 
+
+int main(int argc, char **argv)
+	{
+	BN_CTX *ctx;
+	BIGNUM a,b,c;
+
+	ctx=BN_CTX_new();
+	BN_init(&a);
+	BN_init(&b);
+	BN_init(&c);
+
+	do_mul(&a,&b,&c,ctx);
+	}
+
+void do_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+	{
+	int i,j,k;
+	double tm;
+	long num;
+
+	for (i=0; i<NUM_SIZES; i++)
+		{
+		num=BASENUM;
+		if (i) num/=(i*3);
+		BN_rand(a,sizes[i],1,0);
+		for (j=i; j<NUM_SIZES; j++)
+			{
+			BN_rand(b,sizes[j],1,0);
+			Time_F(START);
+			for (k=0; k<num; k++)
+				BN_mul(r,b,a,ctx);
+			tm=Time_F(STOP);
+			printf("mul %4d x %4d -> %8.3fms\n",sizes[i],sizes[j],tm*1000.0/num);
+			}
+		}
+
+	for (i=0; i<NUM_SIZES; i++)
+		{
+		num=BASENUM;
+		if (i) num/=(i*3);
+		BN_rand(a,sizes[i],1,0);
+		Time_F(START);
+		for (k=0; k<num; k++)
+			BN_sqr(r,a,ctx);
+		tm=Time_F(STOP);
+		printf("sqr %4d x %4d -> %8.3fms\n",sizes[i],sizes[i],tm*1000.0/num);
+		}
+
+	for (i=0; i<NUM_SIZES; i++)
+		{
+		num=BASENUM/10;
+		if (i) num/=(i*3);
+		BN_rand(a,sizes[i]-1,1,0);
+		for (j=i; j<NUM_SIZES; j++)
+			{
+			BN_rand(b,sizes[j],1,0);
+			Time_F(START);
+			for (k=0; k<100000; k++)
+				BN_div(r, NULL, b, a,ctx);
+			tm=Time_F(STOP);
+			printf("div %4d / %4d -> %8.3fms\n",sizes[j],sizes[i]-1,tm*1000.0/num);
+			}
+		}
+	}
+
diff --git a/openssl/crypto/bn/bntest.c b/openssl/crypto/bn/bntest.c
new file mode 100644
index 0000000..0cd99c5
--- /dev/null
+++ b/openssl/crypto/bn/bntest.c
@@ -0,0 +1,2013 @@
+/* crypto/bn/bntest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the Eric Young open source
+ * license provided above.
+ *
+ * The binary polynomial arithmetic software is originally written by 
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+/* Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code */
+#ifdef OPENSSL_NO_DEPRECATED
+#undef OPENSSL_NO_DEPRECATED
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "e_os.h"
+
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+
+const int num0 = 100; /* number of tests */
+const int num1 = 50;  /* additional tests for some functions */
+const int num2 = 5;   /* number of tests for slow functions */
+
+int test_add(BIO *bp);
+int test_sub(BIO *bp);
+int test_lshift1(BIO *bp);
+int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_);
+int test_rshift1(BIO *bp);
+int test_rshift(BIO *bp,BN_CTX *ctx);
+int test_div(BIO *bp,BN_CTX *ctx);
+int test_div_word(BIO *bp);
+int test_div_recp(BIO *bp,BN_CTX *ctx);
+int test_mul(BIO *bp);
+int test_sqr(BIO *bp,BN_CTX *ctx);
+int test_mont(BIO *bp,BN_CTX *ctx);
+int test_mod(BIO *bp,BN_CTX *ctx);
+int test_mod_mul(BIO *bp,BN_CTX *ctx);
+int test_mod_exp(BIO *bp,BN_CTX *ctx);
+int test_mod_exp_mont_consttime(BIO *bp,BN_CTX *ctx);
+int test_exp(BIO *bp,BN_CTX *ctx);
+int test_gf2m_add(BIO *bp);
+int test_gf2m_mod(BIO *bp);
+int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx);
+int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx);
+int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx);
+int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx);
+int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx);
+int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx);
+int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx);
+int test_kron(BIO *bp,BN_CTX *ctx);
+int test_sqrt(BIO *bp,BN_CTX *ctx);
+int rand_neg(void);
+static int results=0;
+
+static unsigned char lst[]="\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
+"\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0";
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+static void message(BIO *out, char *m)
+	{
+	fprintf(stderr, "test %s\n", m);
+	BIO_puts(out, "print \"test ");
+	BIO_puts(out, m);
+	BIO_puts(out, "\\n\"\n");
+	}
+
+int main(int argc, char *argv[])
+	{
+	BN_CTX *ctx;
+	BIO *out;
+	char *outfile=NULL;
+
+	results = 0;
+
+	RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
+
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if (strcmp(*argv,"-results") == 0)
+			results=1;
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) break;
+			outfile= *(++argv);
+			}
+		argc--;
+		argv++;
+		}
+
+
+	ctx=BN_CTX_new();
+	if (ctx == NULL) EXIT(1);
+
+	out=BIO_new(BIO_s_file());
+	if (out == NULL) EXIT(1);
+	if (outfile == NULL)
+		{
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+		}
+	else
+		{
+		if (!BIO_write_filename(out,outfile))
+			{
+			perror(outfile);
+			EXIT(1);
+			}
+		}
+
+	if (!results)
+		BIO_puts(out,"obase=16\nibase=16\n");
+
+	message(out,"BN_add");
+	if (!test_add(out)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_sub");
+	if (!test_sub(out)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_lshift1");
+	if (!test_lshift1(out)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_lshift (fixed)");
+	if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL)))
+	    goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_lshift");
+	if (!test_lshift(out,ctx,NULL)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_rshift1");
+	if (!test_rshift1(out)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_rshift");
+	if (!test_rshift(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_sqr");
+	if (!test_sqr(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_mul");
+	if (!test_mul(out)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_div");
+	if (!test_div(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_div_word");
+	if (!test_div_word(out)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_div_recp");
+	if (!test_div_recp(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_mod");
+	if (!test_mod(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_mod_mul");
+	if (!test_mod_mul(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_mont");
+	if (!test_mont(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_mod_exp");
+	if (!test_mod_exp(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_mod_exp_mont_consttime");
+	if (!test_mod_exp_mont_consttime(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_exp");
+	if (!test_exp(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_kronecker");
+	if (!test_kron(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_mod_sqrt");
+	if (!test_sqrt(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_GF2m_add");
+	if (!test_gf2m_add(out)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_GF2m_mod");
+	if (!test_gf2m_mod(out)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_GF2m_mod_mul");
+	if (!test_gf2m_mod_mul(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_GF2m_mod_sqr");
+	if (!test_gf2m_mod_sqr(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_GF2m_mod_inv");
+	if (!test_gf2m_mod_inv(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_GF2m_mod_div");
+	if (!test_gf2m_mod_div(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_GF2m_mod_exp");
+	if (!test_gf2m_mod_exp(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_GF2m_mod_sqrt");
+	if (!test_gf2m_mod_sqrt(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	message(out,"BN_GF2m_mod_solve_quad");
+	if (!test_gf2m_mod_solve_quad(out,ctx)) goto err;
+	(void)BIO_flush(out);
+
+	BN_CTX_free(ctx);
+	BIO_free(out);
+
+/**/
+	EXIT(0);
+err:
+	BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices
+	                      * the failure, see test_bn in test/Makefile.ssl*/
+	(void)BIO_flush(out);
+	ERR_load_crypto_strings();
+	ERR_print_errors_fp(stderr);
+	EXIT(1);
+	return(1);
+	}
+
+int test_add(BIO *bp)
+	{
+	BIGNUM a,b,c;
+	int i;
+
+	BN_init(&a);
+	BN_init(&b);
+	BN_init(&c);
+
+	BN_bntest_rand(&a,512,0,0);
+	for (i=0; i<num0; i++)
+		{
+		BN_bntest_rand(&b,450+i,0,0);
+		a.neg=rand_neg();
+		b.neg=rand_neg();
+		BN_add(&c,&a,&b);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," + ");
+				BN_print(bp,&b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&c);
+			BIO_puts(bp,"\n");
+			}
+		a.neg=!a.neg;
+		b.neg=!b.neg;
+		BN_add(&c,&c,&b);
+		BN_add(&c,&c,&a);
+		if(!BN_is_zero(&c))
+		    {
+		    fprintf(stderr,"Add test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(&a);
+	BN_free(&b);
+	BN_free(&c);
+	return(1);
+	}
+
+int test_sub(BIO *bp)
+	{
+	BIGNUM a,b,c;
+	int i;
+
+	BN_init(&a);
+	BN_init(&b);
+	BN_init(&c);
+
+	for (i=0; i<num0+num1; i++)
+		{
+		if (i < num1)
+			{
+			BN_bntest_rand(&a,512,0,0);
+			BN_copy(&b,&a);
+			if (BN_set_bit(&a,i)==0) return(0);
+			BN_add_word(&b,i);
+			}
+		else
+			{
+			BN_bntest_rand(&b,400+i-num1,0,0);
+			a.neg=rand_neg();
+			b.neg=rand_neg();
+			}
+		BN_sub(&c,&a,&b);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," - ");
+				BN_print(bp,&b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&c);
+			BIO_puts(bp,"\n");
+			}
+		BN_add(&c,&c,&b);
+		BN_sub(&c,&c,&a);
+		if(!BN_is_zero(&c))
+		    {
+		    fprintf(stderr,"Subtract test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(&a);
+	BN_free(&b);
+	BN_free(&c);
+	return(1);
+	}
+
+int test_div(BIO *bp, BN_CTX *ctx)
+	{
+	BIGNUM a,b,c,d,e;
+	int i;
+
+	BN_init(&a);
+	BN_init(&b);
+	BN_init(&c);
+	BN_init(&d);
+	BN_init(&e);
+
+	for (i=0; i<num0+num1; i++)
+		{
+		if (i < num1)
+			{
+			BN_bntest_rand(&a,400,0,0);
+			BN_copy(&b,&a);
+			BN_lshift(&a,&a,i);
+			BN_add_word(&a,i);
+			}
+		else
+			BN_bntest_rand(&b,50+3*(i-num1),0,0);
+		a.neg=rand_neg();
+		b.neg=rand_neg();
+		BN_div(&d,&c,&a,&b,ctx);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," / ");
+				BN_print(bp,&b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&d);
+			BIO_puts(bp,"\n");
+
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," % ");
+				BN_print(bp,&b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&c);
+			BIO_puts(bp,"\n");
+			}
+		BN_mul(&e,&d,&b,ctx);
+		BN_add(&d,&e,&c);
+		BN_sub(&d,&d,&a);
+		if(!BN_is_zero(&d))
+		    {
+		    fprintf(stderr,"Division test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(&a);
+	BN_free(&b);
+	BN_free(&c);
+	BN_free(&d);
+	BN_free(&e);
+	return(1);
+	}
+
+static void print_word(BIO *bp,BN_ULONG w)
+	{
+#ifdef SIXTY_FOUR_BIT
+	if (sizeof(w) > sizeof(unsigned long))
+		{
+		unsigned long	h=(unsigned long)(w>>32),
+				l=(unsigned long)(w);
+
+		if (h)	BIO_printf(bp,"%lX%08lX",h,l);
+		else	BIO_printf(bp,"%lX",l);
+		return;
+		}
+#endif
+	BIO_printf(bp,BN_HEX_FMT1,w);
+	}
+
+int test_div_word(BIO *bp)
+	{
+	BIGNUM   a,b;
+	BN_ULONG r,s;
+	int i;
+
+	BN_init(&a);
+	BN_init(&b);
+
+	for (i=0; i<num0; i++)
+		{
+		do {
+			BN_bntest_rand(&a,512,-1,0);
+			BN_bntest_rand(&b,BN_BITS2,-1,0);
+			s = b.d[0];
+		} while (!s);
+
+		BN_copy(&b, &a);
+		r = BN_div_word(&b, s);
+
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," / ");
+				print_word(bp,s);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&b);
+			BIO_puts(bp,"\n");
+
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," % ");
+				print_word(bp,s);
+				BIO_puts(bp," - ");
+				}
+			print_word(bp,r);
+			BIO_puts(bp,"\n");
+			}
+		BN_mul_word(&b,s);
+		BN_add_word(&b,r);
+		BN_sub(&b,&a,&b);
+		if(!BN_is_zero(&b))
+		    {
+		    fprintf(stderr,"Division (word) test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(&a);
+	BN_free(&b);
+	return(1);
+	}
+
+int test_div_recp(BIO *bp, BN_CTX *ctx)
+	{
+	BIGNUM a,b,c,d,e;
+	BN_RECP_CTX recp;
+	int i;
+
+	BN_RECP_CTX_init(&recp);
+	BN_init(&a);
+	BN_init(&b);
+	BN_init(&c);
+	BN_init(&d);
+	BN_init(&e);
+
+	for (i=0; i<num0+num1; i++)
+		{
+		if (i < num1)
+			{
+			BN_bntest_rand(&a,400,0,0);
+			BN_copy(&b,&a);
+			BN_lshift(&a,&a,i);
+			BN_add_word(&a,i);
+			}
+		else
+			BN_bntest_rand(&b,50+3*(i-num1),0,0);
+		a.neg=rand_neg();
+		b.neg=rand_neg();
+		BN_RECP_CTX_set(&recp,&b,ctx);
+		BN_div_recp(&d,&c,&a,&recp,ctx);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," / ");
+				BN_print(bp,&b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&d);
+			BIO_puts(bp,"\n");
+
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," % ");
+				BN_print(bp,&b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&c);
+			BIO_puts(bp,"\n");
+			}
+		BN_mul(&e,&d,&b,ctx);
+		BN_add(&d,&e,&c);
+		BN_sub(&d,&d,&a);
+		if(!BN_is_zero(&d))
+		    {
+		    fprintf(stderr,"Reciprocal division test failed!\n");
+		    fprintf(stderr,"a=");
+		    BN_print_fp(stderr,&a);
+		    fprintf(stderr,"\nb=");
+		    BN_print_fp(stderr,&b);
+		    fprintf(stderr,"\n");
+		    return 0;
+		    }
+		}
+	BN_free(&a);
+	BN_free(&b);
+	BN_free(&c);
+	BN_free(&d);
+	BN_free(&e);
+	BN_RECP_CTX_free(&recp);
+	return(1);
+	}
+
+int test_mul(BIO *bp)
+	{
+	BIGNUM a,b,c,d,e;
+	int i;
+	BN_CTX *ctx;
+
+	ctx = BN_CTX_new();
+	if (ctx == NULL) EXIT(1);
+	
+	BN_init(&a);
+	BN_init(&b);
+	BN_init(&c);
+	BN_init(&d);
+	BN_init(&e);
+
+	for (i=0; i<num0+num1; i++)
+		{
+		if (i <= num1)
+			{
+			BN_bntest_rand(&a,100,0,0);
+			BN_bntest_rand(&b,100,0,0);
+			}
+		else
+			BN_bntest_rand(&b,i-num1,0,0);
+		a.neg=rand_neg();
+		b.neg=rand_neg();
+		BN_mul(&c,&a,&b,ctx);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," * ");
+				BN_print(bp,&b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&c);
+			BIO_puts(bp,"\n");
+			}
+		BN_div(&d,&e,&c,&a,ctx);
+		BN_sub(&d,&d,&b);
+		if(!BN_is_zero(&d) || !BN_is_zero(&e))
+		    {
+		    fprintf(stderr,"Multiplication test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(&a);
+	BN_free(&b);
+	BN_free(&c);
+	BN_free(&d);
+	BN_free(&e);
+	BN_CTX_free(ctx);
+	return(1);
+	}
+
+int test_sqr(BIO *bp, BN_CTX *ctx)
+	{
+	BIGNUM a,c,d,e;
+	int i;
+
+	BN_init(&a);
+	BN_init(&c);
+	BN_init(&d);
+	BN_init(&e);
+
+	for (i=0; i<num0; i++)
+		{
+		BN_bntest_rand(&a,40+i*10,0,0);
+		a.neg=rand_neg();
+		BN_sqr(&c,&a,ctx);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," * ");
+				BN_print(bp,&a);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&c);
+			BIO_puts(bp,"\n");
+			}
+		BN_div(&d,&e,&c,&a,ctx);
+		BN_sub(&d,&d,&a);
+		if(!BN_is_zero(&d) || !BN_is_zero(&e))
+		    {
+		    fprintf(stderr,"Square test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(&a);
+	BN_free(&c);
+	BN_free(&d);
+	BN_free(&e);
+	return(1);
+	}
+
+int test_mont(BIO *bp, BN_CTX *ctx)
+	{
+	BIGNUM a,b,c,d,A,B;
+	BIGNUM n;
+	int i;
+	BN_MONT_CTX *mont;
+
+	BN_init(&a);
+	BN_init(&b);
+	BN_init(&c);
+	BN_init(&d);
+	BN_init(&A);
+	BN_init(&B);
+	BN_init(&n);
+
+	mont=BN_MONT_CTX_new();
+	if (mont == NULL)
+		return 0;
+
+	BN_bntest_rand(&a,100,0,0); /**/
+	BN_bntest_rand(&b,100,0,0); /**/
+	for (i=0; i<num2; i++)
+		{
+		int bits = (200*(i+1))/num2;
+
+		if (bits == 0)
+			continue;
+		BN_bntest_rand(&n,bits,0,1);
+		BN_MONT_CTX_set(mont,&n,ctx);
+
+		BN_nnmod(&a,&a,&n,ctx);
+		BN_nnmod(&b,&b,&n,ctx);
+
+		BN_to_montgomery(&A,&a,mont,ctx);
+		BN_to_montgomery(&B,&b,mont,ctx);
+
+		BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
+		BN_from_montgomery(&A,&c,mont,ctx);/**/
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+#ifdef undef
+fprintf(stderr,"%d * %d %% %d\n",
+BN_num_bits(&a),
+BN_num_bits(&b),
+BN_num_bits(mont->N));
+#endif
+				BN_print(bp,&a);
+				BIO_puts(bp," * ");
+				BN_print(bp,&b);
+				BIO_puts(bp," % ");
+				BN_print(bp,&(mont->N));
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&A);
+			BIO_puts(bp,"\n");
+			}
+		BN_mod_mul(&d,&a,&b,&n,ctx);
+		BN_sub(&d,&d,&A);
+		if(!BN_is_zero(&d))
+		    {
+		    fprintf(stderr,"Montgomery multiplication test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_MONT_CTX_free(mont);
+	BN_free(&a);
+	BN_free(&b);
+	BN_free(&c);
+	BN_free(&d);
+	BN_free(&A);
+	BN_free(&B);
+	BN_free(&n);
+	return(1);
+	}
+
+int test_mod(BIO *bp, BN_CTX *ctx)
+	{
+	BIGNUM *a,*b,*c,*d,*e;
+	int i;
+
+	a=BN_new();
+	b=BN_new();
+	c=BN_new();
+	d=BN_new();
+	e=BN_new();
+
+	BN_bntest_rand(a,1024,0,0); /**/
+	for (i=0; i<num0; i++)
+		{
+		BN_bntest_rand(b,450+i*10,0,0); /**/
+		a->neg=rand_neg();
+		b->neg=rand_neg();
+		BN_mod(c,a,b,ctx);/**/
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,a);
+				BIO_puts(bp," % ");
+				BN_print(bp,b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,c);
+			BIO_puts(bp,"\n");
+			}
+		BN_div(d,e,a,b,ctx);
+		BN_sub(e,e,c);
+		if(!BN_is_zero(e))
+		    {
+		    fprintf(stderr,"Modulo test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(a);
+	BN_free(b);
+	BN_free(c);
+	BN_free(d);
+	BN_free(e);
+	return(1);
+	}
+
+int test_mod_mul(BIO *bp, BN_CTX *ctx)
+	{
+	BIGNUM *a,*b,*c,*d,*e;
+	int i,j;
+
+	a=BN_new();
+	b=BN_new();
+	c=BN_new();
+	d=BN_new();
+	e=BN_new();
+
+	for (j=0; j<3; j++) {
+	BN_bntest_rand(c,1024,0,0); /**/
+	for (i=0; i<num0; i++)
+		{
+		BN_bntest_rand(a,475+i*10,0,0); /**/
+		BN_bntest_rand(b,425+i*11,0,0); /**/
+		a->neg=rand_neg();
+		b->neg=rand_neg();
+		if (!BN_mod_mul(e,a,b,c,ctx))
+			{
+			unsigned long l;
+
+			while ((l=ERR_get_error()))
+				fprintf(stderr,"ERROR:%s\n",
+					ERR_error_string(l,NULL));
+			EXIT(1);
+			}
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,a);
+				BIO_puts(bp," * ");
+				BN_print(bp,b);
+				BIO_puts(bp," % ");
+				BN_print(bp,c);
+				if ((a->neg ^ b->neg) && !BN_is_zero(e))
+					{
+					/* If  (a*b) % c  is negative,  c  must be added
+					 * in order to obtain the normalized remainder
+					 * (new with OpenSSL 0.9.7, previous versions of
+					 * BN_mod_mul could generate negative results)
+					 */
+					BIO_puts(bp," + ");
+					BN_print(bp,c);
+					}
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,e);
+			BIO_puts(bp,"\n");
+			}
+		BN_mul(d,a,b,ctx);
+		BN_sub(d,d,e);
+		BN_div(a,b,d,c,ctx);
+		if(!BN_is_zero(b))
+		    {
+		    fprintf(stderr,"Modulo multiply test failed!\n");
+		    ERR_print_errors_fp(stderr);
+		    return 0;
+		    }
+		}
+	}
+	BN_free(a);
+	BN_free(b);
+	BN_free(c);
+	BN_free(d);
+	BN_free(e);
+	return(1);
+	}
+
+int test_mod_exp(BIO *bp, BN_CTX *ctx)
+	{
+	BIGNUM *a,*b,*c,*d,*e;
+	int i;
+
+	a=BN_new();
+	b=BN_new();
+	c=BN_new();
+	d=BN_new();
+	e=BN_new();
+
+	BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */
+	for (i=0; i<num2; i++)
+		{
+		BN_bntest_rand(a,20+i*5,0,0); /**/
+		BN_bntest_rand(b,2+i,0,0); /**/
+
+		if (!BN_mod_exp(d,a,b,c,ctx))
+			return(0);
+
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,a);
+				BIO_puts(bp," ^ ");
+				BN_print(bp,b);
+				BIO_puts(bp," % ");
+				BN_print(bp,c);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,d);
+			BIO_puts(bp,"\n");
+			}
+		BN_exp(e,a,b,ctx);
+		BN_sub(e,e,d);
+		BN_div(a,b,e,c,ctx);
+		if(!BN_is_zero(b))
+		    {
+		    fprintf(stderr,"Modulo exponentiation test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(a);
+	BN_free(b);
+	BN_free(c);
+	BN_free(d);
+	BN_free(e);
+	return(1);
+	}
+
+int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx)
+	{
+	BIGNUM *a,*b,*c,*d,*e;
+	int i;
+
+	a=BN_new();
+	b=BN_new();
+	c=BN_new();
+	d=BN_new();
+	e=BN_new();
+
+	BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */
+	for (i=0; i<num2; i++)
+		{
+		BN_bntest_rand(a,20+i*5,0,0); /**/
+		BN_bntest_rand(b,2+i,0,0); /**/
+
+		if (!BN_mod_exp_mont_consttime(d,a,b,c,ctx,NULL))
+			return(00);
+
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,a);
+				BIO_puts(bp," ^ ");
+				BN_print(bp,b);
+				BIO_puts(bp," % ");
+				BN_print(bp,c);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,d);
+			BIO_puts(bp,"\n");
+			}
+		BN_exp(e,a,b,ctx);
+		BN_sub(e,e,d);
+		BN_div(a,b,e,c,ctx);
+		if(!BN_is_zero(b))
+		    {
+		    fprintf(stderr,"Modulo exponentiation test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(a);
+	BN_free(b);
+	BN_free(c);
+	BN_free(d);
+	BN_free(e);
+	return(1);
+	}
+
+int test_exp(BIO *bp, BN_CTX *ctx)
+	{
+	BIGNUM *a,*b,*d,*e,*one;
+	int i;
+
+	a=BN_new();
+	b=BN_new();
+	d=BN_new();
+	e=BN_new();
+	one=BN_new();
+	BN_one(one);
+
+	for (i=0; i<num2; i++)
+		{
+		BN_bntest_rand(a,20+i*5,0,0); /**/
+		BN_bntest_rand(b,2+i,0,0); /**/
+
+		if (BN_exp(d,a,b,ctx) <= 0)
+			return(0);
+
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,a);
+				BIO_puts(bp," ^ ");
+				BN_print(bp,b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,d);
+			BIO_puts(bp,"\n");
+			}
+		BN_one(e);
+		for( ; !BN_is_zero(b) ; BN_sub(b,b,one))
+		    BN_mul(e,e,a,ctx);
+		BN_sub(e,e,d);
+		if(!BN_is_zero(e))
+		    {
+		    fprintf(stderr,"Exponentiation test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(a);
+	BN_free(b);
+	BN_free(d);
+	BN_free(e);
+	BN_free(one);
+	return(1);
+	}
+
+int test_gf2m_add(BIO *bp)
+	{
+	BIGNUM a,b,c;
+	int i, ret = 0;
+
+	BN_init(&a);
+	BN_init(&b);
+	BN_init(&c);
+
+	for (i=0; i<num0; i++)
+		{
+		BN_rand(&a,512,0,0);
+		BN_copy(&b, BN_value_one());
+		a.neg=rand_neg();
+		b.neg=rand_neg();
+		BN_GF2m_add(&c,&a,&b);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," ^ ");
+				BN_print(bp,&b);
+				BIO_puts(bp," = ");
+				}
+			BN_print(bp,&c);
+			BIO_puts(bp,"\n");
+			}
+#endif
+		/* Test that two added values have the correct parity. */
+		if((BN_is_odd(&a) && BN_is_odd(&c)) || (!BN_is_odd(&a) && !BN_is_odd(&c)))
+			{
+		    fprintf(stderr,"GF(2^m) addition test (a) failed!\n");
+			goto err;
+			}
+		BN_GF2m_add(&c,&c,&c);
+		/* Test that c + c = 0. */
+		if(!BN_is_zero(&c))
+		    {
+		    fprintf(stderr,"GF(2^m) addition test (b) failed!\n");
+			goto err;
+		    }
+		}
+	ret = 1;
+  err:
+	BN_free(&a);
+	BN_free(&b);
+	BN_free(&c);
+	return ret;
+	}
+
+int test_gf2m_mod(BIO *bp)
+	{
+	BIGNUM *a,*b[2],*c,*d,*e;
+	int i, j, ret = 0;
+	int p0[] = {163,7,6,3,0,-1};
+	int p1[] = {193,15,0,-1};
+
+	a=BN_new();
+	b[0]=BN_new();
+	b[1]=BN_new();
+	c=BN_new();
+	d=BN_new();
+	e=BN_new();
+
+	BN_GF2m_arr2poly(p0, b[0]);
+	BN_GF2m_arr2poly(p1, b[1]);
+
+	for (i=0; i<num0; i++)
+		{
+		BN_bntest_rand(a, 1024, 0, 0);
+		for (j=0; j < 2; j++)
+			{
+			BN_GF2m_mod(c, a, b[j]);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+			if (bp != NULL)
+				{
+				if (!results)
+					{
+					BN_print(bp,a);
+					BIO_puts(bp," % ");
+					BN_print(bp,b[j]);
+					BIO_puts(bp," - ");
+					BN_print(bp,c);
+					BIO_puts(bp,"\n");
+					}
+				}
+#endif
+			BN_GF2m_add(d, a, c);
+			BN_GF2m_mod(e, d, b[j]);
+			/* Test that a + (a mod p) mod p == 0. */
+			if(!BN_is_zero(e))
+				{
+				fprintf(stderr,"GF(2^m) modulo test failed!\n");
+				goto err;
+				}
+			}
+		}
+	ret = 1;
+  err:
+	BN_free(a);
+	BN_free(b[0]);
+	BN_free(b[1]);
+	BN_free(c);
+	BN_free(d);
+	BN_free(e);
+	return ret;
+	}
+
+int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx)
+	{
+	BIGNUM *a,*b[2],*c,*d,*e,*f,*g,*h;
+	int i, j, ret = 0;
+	int p0[] = {163,7,6,3,0,-1};
+	int p1[] = {193,15,0,-1};
+
+	a=BN_new();
+	b[0]=BN_new();
+	b[1]=BN_new();
+	c=BN_new();
+	d=BN_new();
+	e=BN_new();
+	f=BN_new();
+	g=BN_new();
+	h=BN_new();
+
+	BN_GF2m_arr2poly(p0, b[0]);
+	BN_GF2m_arr2poly(p1, b[1]);
+
+	for (i=0; i<num0; i++)
+		{
+		BN_bntest_rand(a, 1024, 0, 0);
+		BN_bntest_rand(c, 1024, 0, 0);
+		BN_bntest_rand(d, 1024, 0, 0);
+		for (j=0; j < 2; j++)
+			{
+			BN_GF2m_mod_mul(e, a, c, b[j], ctx);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+			if (bp != NULL)
+				{
+				if (!results)
+					{
+					BN_print(bp,a);
+					BIO_puts(bp," * ");
+					BN_print(bp,c);
+					BIO_puts(bp," % ");
+					BN_print(bp,b[j]);
+					BIO_puts(bp," - ");
+					BN_print(bp,e);
+					BIO_puts(bp,"\n");
+					}
+				}
+#endif
+			BN_GF2m_add(f, a, d);
+			BN_GF2m_mod_mul(g, f, c, b[j], ctx);
+			BN_GF2m_mod_mul(h, d, c, b[j], ctx);
+			BN_GF2m_add(f, e, g);
+			BN_GF2m_add(f, f, h);
+			/* Test that (a+d)*c = a*c + d*c. */
+			if(!BN_is_zero(f))
+				{
+				fprintf(stderr,"GF(2^m) modular multiplication test failed!\n");
+				goto err;
+				}
+			}
+		}
+	ret = 1;
+  err:
+	BN_free(a);
+	BN_free(b[0]);
+	BN_free(b[1]);
+	BN_free(c);
+	BN_free(d);
+	BN_free(e);
+	BN_free(f);
+	BN_free(g);
+	BN_free(h);
+	return ret;
+	}
+
+int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx)
+	{
+	BIGNUM *a,*b[2],*c,*d;
+	int i, j, ret = 0;
+	int p0[] = {163,7,6,3,0,-1};
+	int p1[] = {193,15,0,-1};
+
+	a=BN_new();
+	b[0]=BN_new();
+	b[1]=BN_new();
+	c=BN_new();
+	d=BN_new();
+
+	BN_GF2m_arr2poly(p0, b[0]);
+	BN_GF2m_arr2poly(p1, b[1]);
+
+	for (i=0; i<num0; i++)
+		{
+		BN_bntest_rand(a, 1024, 0, 0);
+		for (j=0; j < 2; j++)
+			{
+			BN_GF2m_mod_sqr(c, a, b[j], ctx);
+			BN_copy(d, a);
+			BN_GF2m_mod_mul(d, a, d, b[j], ctx);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+			if (bp != NULL)
+				{
+				if (!results)
+					{
+					BN_print(bp,a);
+					BIO_puts(bp," ^ 2 % ");
+					BN_print(bp,b[j]);
+					BIO_puts(bp, " = ");
+					BN_print(bp,c);
+					BIO_puts(bp,"; a * a = ");
+					BN_print(bp,d);
+					BIO_puts(bp,"\n");
+					}
+				}
+#endif
+			BN_GF2m_add(d, c, d);
+			/* Test that a*a = a^2. */
+			if(!BN_is_zero(d))
+				{
+				fprintf(stderr,"GF(2^m) modular squaring test failed!\n");
+				goto err;
+				}
+			}
+		}
+	ret = 1;
+  err:
+	BN_free(a);
+	BN_free(b[0]);
+	BN_free(b[1]);
+	BN_free(c);
+	BN_free(d);
+	return ret;
+	}
+
+int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx)
+	{
+	BIGNUM *a,*b[2],*c,*d;
+	int i, j, ret = 0;
+	int p0[] = {163,7,6,3,0,-1};
+	int p1[] = {193,15,0,-1};
+
+	a=BN_new();
+	b[0]=BN_new();
+	b[1]=BN_new();
+	c=BN_new();
+	d=BN_new();
+
+	BN_GF2m_arr2poly(p0, b[0]);
+	BN_GF2m_arr2poly(p1, b[1]);
+
+	for (i=0; i<num0; i++)
+		{
+		BN_bntest_rand(a, 512, 0, 0); 
+		for (j=0; j < 2; j++)
+			{
+			BN_GF2m_mod_inv(c, a, b[j], ctx);
+			BN_GF2m_mod_mul(d, a, c, b[j], ctx);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+			if (bp != NULL)
+				{
+				if (!results)
+					{
+					BN_print(bp,a);
+					BIO_puts(bp, " * ");
+					BN_print(bp,c);
+					BIO_puts(bp," - 1 % ");
+					BN_print(bp,b[j]);
+					BIO_puts(bp,"\n");
+					}
+				}
+#endif
+			/* Test that ((1/a)*a) = 1. */
+			if(!BN_is_one(d))
+				{
+				fprintf(stderr,"GF(2^m) modular inversion test failed!\n");
+				goto err;
+				}
+			}
+		}
+	ret = 1;
+  err:
+	BN_free(a);
+	BN_free(b[0]);
+	BN_free(b[1]);
+	BN_free(c);
+	BN_free(d);
+	return ret;
+	}
+
+int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx)
+	{
+	BIGNUM *a,*b[2],*c,*d,*e,*f;
+	int i, j, ret = 0;
+	int p0[] = {163,7,6,3,0,-1};
+	int p1[] = {193,15,0,-1};
+
+	a=BN_new();
+	b[0]=BN_new();
+	b[1]=BN_new();
+	c=BN_new();
+	d=BN_new();
+	e=BN_new();
+	f=BN_new();
+
+	BN_GF2m_arr2poly(p0, b[0]);
+	BN_GF2m_arr2poly(p1, b[1]);
+
+	for (i=0; i<num0; i++)
+		{
+		BN_bntest_rand(a, 512, 0, 0); 
+		BN_bntest_rand(c, 512, 0, 0);
+		for (j=0; j < 2; j++)
+			{
+			BN_GF2m_mod_div(d, a, c, b[j], ctx);
+			BN_GF2m_mod_mul(e, d, c, b[j], ctx);
+			BN_GF2m_mod_div(f, a, e, b[j], ctx);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+			if (bp != NULL)
+				{
+				if (!results)
+					{
+					BN_print(bp,a);
+					BIO_puts(bp, " = ");
+					BN_print(bp,c);
+					BIO_puts(bp," * ");
+					BN_print(bp,d);
+					BIO_puts(bp, " % ");
+					BN_print(bp,b[j]);
+					BIO_puts(bp,"\n");
+					}
+				}
+#endif
+			/* Test that ((a/c)*c)/a = 1. */
+			if(!BN_is_one(f))
+				{
+				fprintf(stderr,"GF(2^m) modular division test failed!\n");
+				goto err;
+				}
+			}
+		}
+	ret = 1;
+  err:
+	BN_free(a);
+	BN_free(b[0]);
+	BN_free(b[1]);
+	BN_free(c);
+	BN_free(d);
+	BN_free(e);
+	BN_free(f);
+	return ret;
+	}
+
+int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx)
+	{
+	BIGNUM *a,*b[2],*c,*d,*e,*f;
+	int i, j, ret = 0;
+	int p0[] = {163,7,6,3,0,-1};
+	int p1[] = {193,15,0,-1};
+
+	a=BN_new();
+	b[0]=BN_new();
+	b[1]=BN_new();
+	c=BN_new();
+	d=BN_new();
+	e=BN_new();
+	f=BN_new();
+
+	BN_GF2m_arr2poly(p0, b[0]);
+	BN_GF2m_arr2poly(p1, b[1]);
+
+	for (i=0; i<num0; i++)
+		{
+		BN_bntest_rand(a, 512, 0, 0);
+		BN_bntest_rand(c, 512, 0, 0);
+		BN_bntest_rand(d, 512, 0, 0);
+		for (j=0; j < 2; j++)
+			{
+			BN_GF2m_mod_exp(e, a, c, b[j], ctx);
+			BN_GF2m_mod_exp(f, a, d, b[j], ctx);
+			BN_GF2m_mod_mul(e, e, f, b[j], ctx);
+			BN_add(f, c, d);
+			BN_GF2m_mod_exp(f, a, f, b[j], ctx);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+			if (bp != NULL)
+				{
+				if (!results)
+					{
+					BN_print(bp,a);
+					BIO_puts(bp, " ^ (");
+					BN_print(bp,c);
+					BIO_puts(bp," + ");
+					BN_print(bp,d);
+					BIO_puts(bp, ") = ");
+					BN_print(bp,e);
+					BIO_puts(bp, "; - ");
+					BN_print(bp,f);
+					BIO_puts(bp, " % ");
+					BN_print(bp,b[j]);
+					BIO_puts(bp,"\n");
+					}
+				}
+#endif
+			BN_GF2m_add(f, e, f);
+			/* Test that a^(c+d)=a^c*a^d. */
+			if(!BN_is_zero(f))
+				{
+				fprintf(stderr,"GF(2^m) modular exponentiation test failed!\n");
+				goto err;
+				}
+			}
+		}
+	ret = 1;
+  err:
+	BN_free(a);
+	BN_free(b[0]);
+	BN_free(b[1]);
+	BN_free(c);
+	BN_free(d);
+	BN_free(e);
+	BN_free(f);
+	return ret;
+	}
+
+int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx)
+	{
+	BIGNUM *a,*b[2],*c,*d,*e,*f;
+	int i, j, ret = 0;
+	int p0[] = {163,7,6,3,0,-1};
+	int p1[] = {193,15,0,-1};
+
+	a=BN_new();
+	b[0]=BN_new();
+	b[1]=BN_new();
+	c=BN_new();
+	d=BN_new();
+	e=BN_new();
+	f=BN_new();
+
+	BN_GF2m_arr2poly(p0, b[0]);
+	BN_GF2m_arr2poly(p1, b[1]);
+
+	for (i=0; i<num0; i++)
+		{
+		BN_bntest_rand(a, 512, 0, 0);
+		for (j=0; j < 2; j++)
+			{
+			BN_GF2m_mod(c, a, b[j]);
+			BN_GF2m_mod_sqrt(d, a, b[j], ctx);
+			BN_GF2m_mod_sqr(e, d, b[j], ctx);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+			if (bp != NULL)
+				{
+				if (!results)
+					{
+					BN_print(bp,d);
+					BIO_puts(bp, " ^ 2 - ");
+					BN_print(bp,a);
+					BIO_puts(bp,"\n");
+					}
+				}
+#endif
+			BN_GF2m_add(f, c, e);
+			/* Test that d^2 = a, where d = sqrt(a). */
+			if(!BN_is_zero(f))
+				{
+				fprintf(stderr,"GF(2^m) modular square root test failed!\n");
+				goto err;
+				}
+			}
+		}
+	ret = 1;
+  err:
+	BN_free(a);
+	BN_free(b[0]);
+	BN_free(b[1]);
+	BN_free(c);
+	BN_free(d);
+	BN_free(e);
+	BN_free(f);
+	return ret;
+	}
+
+int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx)
+	{
+	BIGNUM *a,*b[2],*c,*d,*e;
+	int i, j, s = 0, t, ret = 0;
+	int p0[] = {163,7,6,3,0,-1};
+	int p1[] = {193,15,0,-1};
+
+	a=BN_new();
+	b[0]=BN_new();
+	b[1]=BN_new();
+	c=BN_new();
+	d=BN_new();
+	e=BN_new();
+
+	BN_GF2m_arr2poly(p0, b[0]);
+	BN_GF2m_arr2poly(p1, b[1]);
+
+	for (i=0; i<num0; i++)
+		{
+		BN_bntest_rand(a, 512, 0, 0);
+		for (j=0; j < 2; j++)
+			{
+			t = BN_GF2m_mod_solve_quad(c, a, b[j], ctx);
+			if (t)
+				{
+				s++;
+				BN_GF2m_mod_sqr(d, c, b[j], ctx);
+				BN_GF2m_add(d, c, d);
+				BN_GF2m_mod(e, a, b[j]);
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+				if (bp != NULL)
+					{
+					if (!results)
+						{
+						BN_print(bp,c);
+						BIO_puts(bp, " is root of z^2 + z = ");
+						BN_print(bp,a);
+						BIO_puts(bp, " % ");
+						BN_print(bp,b[j]);
+						BIO_puts(bp, "\n");
+						}
+					}
+#endif
+				BN_GF2m_add(e, e, d);
+				/* Test that solution of quadratic c satisfies c^2 + c = a. */
+				if(!BN_is_zero(e))
+					{
+					fprintf(stderr,"GF(2^m) modular solve quadratic test failed!\n");
+					goto err;
+					}
+
+				}
+			else 
+				{
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+				if (bp != NULL)
+					{
+					if (!results)
+						{
+						BIO_puts(bp, "There are no roots of z^2 + z = ");
+						BN_print(bp,a);
+						BIO_puts(bp, " % ");
+						BN_print(bp,b[j]);
+						BIO_puts(bp, "\n");
+						}
+					}
+#endif
+				}
+			}
+		}
+	if (s == 0)
+		{	
+		fprintf(stderr,"All %i tests of GF(2^m) modular solve quadratic resulted in no roots;\n", num0);
+		fprintf(stderr,"this is very unlikely and probably indicates an error.\n");
+		goto err;
+		}
+	ret = 1;
+  err:
+	BN_free(a);
+	BN_free(b[0]);
+	BN_free(b[1]);
+	BN_free(c);
+	BN_free(d);
+	BN_free(e);
+	return ret;
+	}
+
+static int genprime_cb(int p, int n, BN_GENCB *arg)
+	{
+	char c='*';
+
+	if (p == 0) c='.';
+	if (p == 1) c='+';
+	if (p == 2) c='*';
+	if (p == 3) c='\n';
+	putc(c, stderr);
+	fflush(stderr);
+	return 1;
+	}
+
+int test_kron(BIO *bp, BN_CTX *ctx)
+	{
+	BN_GENCB cb;
+	BIGNUM *a,*b,*r,*t;
+	int i;
+	int legendre, kronecker;
+	int ret = 0;
+
+	a = BN_new();
+	b = BN_new();
+	r = BN_new();
+	t = BN_new();
+	if (a == NULL || b == NULL || r == NULL || t == NULL) goto err;
+
+	BN_GENCB_set(&cb, genprime_cb, NULL);
+	
+	/* We test BN_kronecker(a, b, ctx) just for  b  odd (Jacobi symbol).
+	 * In this case we know that if  b  is prime, then BN_kronecker(a, b, ctx)
+	 * is congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol).
+	 * So we generate a random prime  b  and compare these values
+	 * for a number of random  a's.  (That is, we run the Solovay-Strassen
+	 * primality test to confirm that  b  is prime, except that we
+	 * don't want to test whether  b  is prime but whether BN_kronecker
+	 * works.) */
+
+	if (!BN_generate_prime_ex(b, 512, 0, NULL, NULL, &cb)) goto err;
+	b->neg = rand_neg();
+	putc('\n', stderr);
+
+	for (i = 0; i < num0; i++)
+		{
+		if (!BN_bntest_rand(a, 512, 0, 0)) goto err;
+		a->neg = rand_neg();
+
+		/* t := (|b|-1)/2  (note that b is odd) */
+		if (!BN_copy(t, b)) goto err;
+		t->neg = 0;
+		if (!BN_sub_word(t, 1)) goto err;
+		if (!BN_rshift1(t, t)) goto err;
+		/* r := a^t mod b */
+		b->neg=0;
+		
+		if (!BN_mod_exp_recp(r, a, t, b, ctx)) goto err;
+		b->neg=1;
+
+		if (BN_is_word(r, 1))
+			legendre = 1;
+		else if (BN_is_zero(r))
+			legendre = 0;
+		else
+			{
+			if (!BN_add_word(r, 1)) goto err;
+			if (0 != BN_ucmp(r, b))
+				{
+				fprintf(stderr, "Legendre symbol computation failed\n");
+				goto err;
+				}
+			legendre = -1;
+			}
+		
+		kronecker = BN_kronecker(a, b, ctx);
+		if (kronecker < -1) goto err;
+		/* we actually need BN_kronecker(a, |b|) */
+		if (a->neg && b->neg)
+			kronecker = -kronecker;
+		
+		if (legendre != kronecker)
+			{
+			fprintf(stderr, "legendre != kronecker; a = ");
+			BN_print_fp(stderr, a);
+			fprintf(stderr, ", b = ");
+			BN_print_fp(stderr, b);
+			fprintf(stderr, "\n");
+			goto err;
+			}
+
+		putc('.', stderr);
+		fflush(stderr);
+		}
+
+	putc('\n', stderr);
+	fflush(stderr);
+	ret = 1;
+ err:
+	if (a != NULL) BN_free(a);
+	if (b != NULL) BN_free(b);
+	if (r != NULL) BN_free(r);
+	if (t != NULL) BN_free(t);
+	return ret;
+	}
+
+int test_sqrt(BIO *bp, BN_CTX *ctx)
+	{
+	BN_GENCB cb;
+	BIGNUM *a,*p,*r;
+	int i, j;
+	int ret = 0;
+
+	a = BN_new();
+	p = BN_new();
+	r = BN_new();
+	if (a == NULL || p == NULL || r == NULL) goto err;
+
+	BN_GENCB_set(&cb, genprime_cb, NULL);
+
+	for (i = 0; i < 16; i++)
+		{
+		if (i < 8)
+			{
+			unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 };
+			
+			if (!BN_set_word(p, primes[i])) goto err;
+			}
+		else
+			{
+			if (!BN_set_word(a, 32)) goto err;
+			if (!BN_set_word(r, 2*i + 1)) goto err;
+		
+			if (!BN_generate_prime_ex(p, 256, 0, a, r, &cb)) goto err;
+			putc('\n', stderr);
+			}
+		p->neg = rand_neg();
+
+		for (j = 0; j < num2; j++)
+			{
+			/* construct 'a' such that it is a square modulo p,
+			 * but in general not a proper square and not reduced modulo p */
+			if (!BN_bntest_rand(r, 256, 0, 3)) goto err;
+			if (!BN_nnmod(r, r, p, ctx)) goto err;
+			if (!BN_mod_sqr(r, r, p, ctx)) goto err;
+			if (!BN_bntest_rand(a, 256, 0, 3)) goto err;
+			if (!BN_nnmod(a, a, p, ctx)) goto err;
+			if (!BN_mod_sqr(a, a, p, ctx)) goto err;
+			if (!BN_mul(a, a, r, ctx)) goto err;
+			if (rand_neg())
+				if (!BN_sub(a, a, p)) goto err;
+
+			if (!BN_mod_sqrt(r, a, p, ctx)) goto err;
+			if (!BN_mod_sqr(r, r, p, ctx)) goto err;
+
+			if (!BN_nnmod(a, a, p, ctx)) goto err;
+
+			if (BN_cmp(a, r) != 0)
+				{
+				fprintf(stderr, "BN_mod_sqrt failed: a = ");
+				BN_print_fp(stderr, a);
+				fprintf(stderr, ", r = ");
+				BN_print_fp(stderr, r);
+				fprintf(stderr, ", p = ");
+				BN_print_fp(stderr, p);
+				fprintf(stderr, "\n");
+				goto err;
+				}
+
+			putc('.', stderr);
+			fflush(stderr);
+			}
+		
+		putc('\n', stderr);
+		fflush(stderr);
+		}
+	ret = 1;
+ err:
+	if (a != NULL) BN_free(a);
+	if (p != NULL) BN_free(p);
+	if (r != NULL) BN_free(r);
+	return ret;
+	}
+
+int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_)
+	{
+	BIGNUM *a,*b,*c,*d;
+	int i;
+
+	b=BN_new();
+	c=BN_new();
+	d=BN_new();
+	BN_one(c);
+
+	if(a_)
+	    a=a_;
+	else
+	    {
+	    a=BN_new();
+	    BN_bntest_rand(a,200,0,0); /**/
+	    a->neg=rand_neg();
+	    }
+	for (i=0; i<num0; i++)
+		{
+		BN_lshift(b,a,i+1);
+		BN_add(c,c,c);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,a);
+				BIO_puts(bp," * ");
+				BN_print(bp,c);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,b);
+			BIO_puts(bp,"\n");
+			}
+		BN_mul(d,a,c,ctx);
+		BN_sub(d,d,b);
+		if(!BN_is_zero(d))
+		    {
+		    fprintf(stderr,"Left shift test failed!\n");
+		    fprintf(stderr,"a=");
+		    BN_print_fp(stderr,a);
+		    fprintf(stderr,"\nb=");
+		    BN_print_fp(stderr,b);
+		    fprintf(stderr,"\nc=");
+		    BN_print_fp(stderr,c);
+		    fprintf(stderr,"\nd=");
+		    BN_print_fp(stderr,d);
+		    fprintf(stderr,"\n");
+		    return 0;
+		    }
+		}
+	BN_free(a);
+	BN_free(b);
+	BN_free(c);
+	BN_free(d);
+	return(1);
+	}
+
+int test_lshift1(BIO *bp)
+	{
+	BIGNUM *a,*b,*c;
+	int i;
+
+	a=BN_new();
+	b=BN_new();
+	c=BN_new();
+
+	BN_bntest_rand(a,200,0,0); /**/
+	a->neg=rand_neg();
+	for (i=0; i<num0; i++)
+		{
+		BN_lshift1(b,a);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,a);
+				BIO_puts(bp," * 2");
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,b);
+			BIO_puts(bp,"\n");
+			}
+		BN_add(c,a,a);
+		BN_sub(a,b,c);
+		if(!BN_is_zero(a))
+		    {
+		    fprintf(stderr,"Left shift one test failed!\n");
+		    return 0;
+		    }
+		
+		BN_copy(a,b);
+		}
+	BN_free(a);
+	BN_free(b);
+	BN_free(c);
+	return(1);
+	}
+
+int test_rshift(BIO *bp,BN_CTX *ctx)
+	{
+	BIGNUM *a,*b,*c,*d,*e;
+	int i;
+
+	a=BN_new();
+	b=BN_new();
+	c=BN_new();
+	d=BN_new();
+	e=BN_new();
+	BN_one(c);
+
+	BN_bntest_rand(a,200,0,0); /**/
+	a->neg=rand_neg();
+	for (i=0; i<num0; i++)
+		{
+		BN_rshift(b,a,i+1);
+		BN_add(c,c,c);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,a);
+				BIO_puts(bp," / ");
+				BN_print(bp,c);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,b);
+			BIO_puts(bp,"\n");
+			}
+		BN_div(d,e,a,c,ctx);
+		BN_sub(d,d,b);
+		if(!BN_is_zero(d))
+		    {
+		    fprintf(stderr,"Right shift test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(a);
+	BN_free(b);
+	BN_free(c);
+	BN_free(d);
+	BN_free(e);
+	return(1);
+	}
+
+int test_rshift1(BIO *bp)
+	{
+	BIGNUM *a,*b,*c;
+	int i;
+
+	a=BN_new();
+	b=BN_new();
+	c=BN_new();
+
+	BN_bntest_rand(a,200,0,0); /**/
+	a->neg=rand_neg();
+	for (i=0; i<num0; i++)
+		{
+		BN_rshift1(b,a);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,a);
+				BIO_puts(bp," / 2");
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,b);
+			BIO_puts(bp,"\n");
+			}
+		BN_sub(c,a,b);
+		BN_sub(c,c,b);
+		if(!BN_is_zero(c) && !BN_abs_is_word(c, 1))
+		    {
+		    fprintf(stderr,"Right shift one test failed!\n");
+		    return 0;
+		    }
+		BN_copy(a,b);
+		}
+	BN_free(a);
+	BN_free(b);
+	BN_free(c);
+	return(1);
+	}
+
+int rand_neg(void)
+	{
+	static unsigned int neg=0;
+	static int sign[8]={0,0,0,1,1,0,1,1};
+
+	return(sign[(neg++)%8]);
+	}
diff --git a/openssl/crypto/bn/divtest.c b/openssl/crypto/bn/divtest.c
new file mode 100644
index 0000000..d3fc688
--- /dev/null
+++ b/openssl/crypto/bn/divtest.c
@@ -0,0 +1,41 @@
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+
+static int Rand(n)
+{
+    unsigned char x[2];
+    RAND_pseudo_bytes(x,2);
+    return (x[0] + 2*x[1]);
+}
+
+static void bug(char *m, BIGNUM *a, BIGNUM *b)
+{
+    printf("%s!\na=",m);
+    BN_print_fp(stdout, a);
+    printf("\nb=");
+    BN_print_fp(stdout, b);
+    printf("\n");
+    fflush(stdout);
+}
+
+main()
+{
+    BIGNUM *a=BN_new(), *b=BN_new(), *c=BN_new(), *d=BN_new(),
+	*C=BN_new(), *D=BN_new();
+    BN_RECP_CTX *recp=BN_RECP_CTX_new();
+    BN_CTX *ctx=BN_CTX_new();
+
+    for(;;) {
+	BN_pseudo_rand(a,Rand(),0,0);
+	BN_pseudo_rand(b,Rand(),0,0);
+	if (BN_is_zero(b)) continue;
+
+	BN_RECP_CTX_set(recp,b,ctx);
+	if (BN_div(C,D,a,b,ctx) != 1)
+	    bug("BN_div failed",a,b);
+	if (BN_div_recp(c,d,a,recp,ctx) != 1)
+	    bug("BN_div_recp failed",a,b);
+	else if (BN_cmp(c,C) != 0 || BN_cmp(c,C) != 0)
+	    bug("mismatch",a,b);
+    }
+}
diff --git a/openssl/crypto/bn/exp.c b/openssl/crypto/bn/exp.c
new file mode 100644
index 0000000..4865b0e
--- /dev/null
+++ b/openssl/crypto/bn/exp.c
@@ -0,0 +1,62 @@
+/* unused */
+
+#include <stdio.h>
+#include <openssl/tmdiff.h>
+#include "bn_lcl.h"
+
+#define SIZE	256
+#define NUM	(8*8*8)
+#define MOD	(8*8*8*8*8)
+
+main(argc,argv)
+int argc;
+char *argv[];
+	{
+	BN_CTX ctx;
+	BIGNUM a,b,c,r,rr,t,l;
+	int j,i,size=SIZE,num=NUM,mod=MOD;
+	char *start,*end;
+	BN_MONT_CTX mont;
+	double d,md;
+
+	BN_MONT_CTX_init(&mont);
+	BN_CTX_init(&ctx);
+	BN_init(&a);
+	BN_init(&b);
+	BN_init(&c);
+	BN_init(&r);
+
+	start=ms_time_new();
+	end=ms_time_new();
+	while (size <= 1024*8)
+		{
+		BN_rand(&a,size,0,0);
+		BN_rand(&b,size,1,0);
+		BN_rand(&c,size,0,1);
+
+		BN_mod(&a,&a,&c,&ctx);
+
+		ms_time_get(start);
+		for (i=0; i<10; i++)
+			BN_MONT_CTX_set(&mont,&c,&ctx);
+		ms_time_get(end);
+		md=ms_time_diff(start,end);
+
+		ms_time_get(start);
+		for (i=0; i<num; i++)
+			{
+			/* bn_mull(&r,&a,&b,&ctx); */
+			/* BN_sqr(&r,&a,&ctx); */
+			BN_mod_exp_mont(&r,&a,&b,&c,&ctx,&mont);
+			}
+		ms_time_get(end);
+		d=ms_time_diff(start,end)/* *50/33 */;
+		printf("%5d bit:%6.2f %6d %6.4f %4d m_set(%5.4f)\n",size,
+			d,num,d/num,(int)((d/num)*mod),md/10.0);
+		num/=8;
+		mod/=8;
+		if (num <= 0) num=1;
+		size*=2;
+		}
+
+	}
diff --git a/openssl/crypto/bn/expspeed.c b/openssl/crypto/bn/expspeed.c
new file mode 100644
index 0000000..4d5f221
--- /dev/null
+++ b/openssl/crypto/bn/expspeed.c
@@ -0,0 +1,353 @@
+/* unused */
+
+/* crypto/bn/expspeed.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* most of this code has been pilfered from my libdes speed.c program */
+
+#define BASENUM	5000
+#define NUM_START 0
+
+
+/* determine timings for modexp, modmul, modsqr, gcd, Kronecker symbol,
+ * modular inverse, or modular square roots */
+#define TEST_EXP
+#undef TEST_MUL
+#undef TEST_SQR
+#undef TEST_GCD
+#undef TEST_KRON
+#undef TEST_INV
+#undef TEST_SQRT
+#define P_MOD_64 9 /* least significant 6 bits for prime to be used for BN_sqrt timings */
+
+#if defined(TEST_EXP) + defined(TEST_MUL) + defined(TEST_SQR) + defined(TEST_GCD) + defined(TEST_KRON) + defined(TEST_INV) +defined(TEST_SQRT) != 1
+#  error "choose one test"
+#endif
+
+#if defined(TEST_INV) || defined(TEST_SQRT)
+#  define C_PRIME
+static void genprime_cb(int p, int n, void *arg);
+#endif
+
+
+
+#undef PROG
+#define PROG bnspeed_main
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
+#define TIMES
+#endif
+
+#ifndef _IRIX
+#include <time.h>
+#endif
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+#endif
+
+/* Depending on the VMS version, the tms structure is perhaps defined.
+   The __TMS macro will show if it was.  If it wasn't defined, we should
+   undefine TIMES, since that tells the rest of the program how things
+   should be handled.				-- Richard Levitte */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
+#undef TIMES
+#endif
+
+#ifndef TIMES
+#include <sys/timeb.h>
+#endif
+
+#if defined(sun) || defined(__ultrix)
+#define _POSIX_SOURCE
+#include <limits.h>
+#include <sys/param.h>
+#endif
+
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+
+/* The following if from times(3) man page.  It may need to be changed */
+#ifndef HZ
+# ifndef CLK_TCK
+#  ifndef _BSD_CLK_TCK_ /* FreeBSD hack */
+#   define HZ	100.0
+#  else /* _BSD_CLK_TCK_ */
+#   define HZ ((double)_BSD_CLK_TCK_)
+#  endif
+# else /* CLK_TCK */
+#  define HZ ((double)CLK_TCK)
+# endif
+#endif
+
+#undef BUFSIZE
+#define BUFSIZE	((long)1024*8)
+int run=0;
+
+static double Time_F(int s);
+#define START	0
+#define STOP	1
+
+static double Time_F(int s)
+	{
+	double ret;
+#ifdef TIMES
+	static struct tms tstart,tend;
+
+	if (s == START)
+		{
+		times(&tstart);
+		return(0);
+		}
+	else
+		{
+		times(&tend);
+		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
+		return((ret < 1e-3)?1e-3:ret);
+		}
+#else /* !times() */
+	static struct timeb tstart,tend;
+	long i;
+
+	if (s == START)
+		{
+		ftime(&tstart);
+		return(0);
+		}
+	else
+		{
+		ftime(&tend);
+		i=(long)tend.millitm-(long)tstart.millitm;
+		ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
+		return((ret < 0.001)?0.001:ret);
+		}
+#endif
+	}
+
+#define NUM_SIZES	7
+#if NUM_START > NUM_SIZES
+#   error "NUM_START > NUM_SIZES"
+#endif
+static int sizes[NUM_SIZES]={128,256,512,1024,2048,4096,8192};
+static int mul_c[NUM_SIZES]={8*8*8*8*8*8,8*8*8*8*8,8*8*8*8,8*8*8,8*8,8,1};
+/*static int sizes[NUM_SIZES]={59,179,299,419,539}; */
+
+#define RAND_SEED(string) { const char str[] = string; RAND_seed(string, sizeof str); }
+
+void do_mul_exp(BIGNUM *r,BIGNUM *a,BIGNUM *b,BIGNUM *c,BN_CTX *ctx); 
+
+int main(int argc, char **argv)
+	{
+	BN_CTX *ctx;
+	BIGNUM *a,*b,*c,*r;
+
+#if 1
+	if (!CRYPTO_set_mem_debug_functions(0,0,0,0,0))
+		abort();
+#endif
+
+	ctx=BN_CTX_new();
+	a=BN_new();
+	b=BN_new();
+	c=BN_new();
+	r=BN_new();
+
+	while (!RAND_status())
+		/* not enough bits */
+		RAND_SEED("I demand a manual recount!");
+
+	do_mul_exp(r,a,b,c,ctx);
+	return 0;
+	}
+
+void do_mul_exp(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *c, BN_CTX *ctx)
+	{
+	int i,k;
+	double tm;
+	long num;
+
+	num=BASENUM;
+	for (i=NUM_START; i<NUM_SIZES; i++)
+		{
+#ifdef C_PRIME
+#  ifdef TEST_SQRT
+		if (!BN_set_word(a, 64)) goto err;
+		if (!BN_set_word(b, P_MOD_64)) goto err;
+#    define ADD a
+#    define REM b
+#  else
+#    define ADD NULL
+#    define REM NULL
+#  endif
+		if (!BN_generate_prime(c,sizes[i],0,ADD,REM,genprime_cb,NULL)) goto err;
+		putc('\n', stderr);
+		fflush(stderr);
+#endif
+
+		for (k=0; k<num; k++)
+			{
+			if (k%50 == 0) /* Average over num/50 different choices of random numbers. */
+				{
+				if (!BN_pseudo_rand(a,sizes[i],1,0)) goto err;
+
+				if (!BN_pseudo_rand(b,sizes[i],1,0)) goto err;
+
+#ifndef C_PRIME
+				if (!BN_pseudo_rand(c,sizes[i],1,1)) goto err;
+#endif
+
+#ifdef TEST_SQRT				
+				if (!BN_mod_sqr(a,a,c,ctx)) goto err;
+				if (!BN_mod_sqr(b,b,c,ctx)) goto err;
+#else
+				if (!BN_nnmod(a,a,c,ctx)) goto err;
+				if (!BN_nnmod(b,b,c,ctx)) goto err;
+#endif
+
+				if (k == 0)
+					Time_F(START);
+				}
+
+#if defined(TEST_EXP)
+			if (!BN_mod_exp(r,a,b,c,ctx)) goto err;
+#elif defined(TEST_MUL)
+			{
+			int i = 0;
+			for (i = 0; i < 50; i++)
+				if (!BN_mod_mul(r,a,b,c,ctx)) goto err;
+			}
+#elif defined(TEST_SQR)
+			{
+			int i = 0;
+			for (i = 0; i < 50; i++)
+				{
+				if (!BN_mod_sqr(r,a,c,ctx)) goto err;
+				if (!BN_mod_sqr(r,b,c,ctx)) goto err;
+				}
+			}
+#elif defined(TEST_GCD)
+			if (!BN_gcd(r,a,b,ctx)) goto err;
+			if (!BN_gcd(r,b,c,ctx)) goto err;
+			if (!BN_gcd(r,c,a,ctx)) goto err;
+#elif defined(TEST_KRON)
+			if (-2 == BN_kronecker(a,b,ctx)) goto err;
+			if (-2 == BN_kronecker(b,c,ctx)) goto err;
+			if (-2 == BN_kronecker(c,a,ctx)) goto err;
+#elif defined(TEST_INV)
+			if (!BN_mod_inverse(r,a,c,ctx)) goto err;
+			if (!BN_mod_inverse(r,b,c,ctx)) goto err;
+#else /* TEST_SQRT */
+			if (!BN_mod_sqrt(r,a,c,ctx)) goto err;
+			if (!BN_mod_sqrt(r,b,c,ctx)) goto err;
+#endif
+			}
+		tm=Time_F(STOP);
+		printf(
+#if defined(TEST_EXP)
+			"modexp %4d ^ %4d %% %4d"
+#elif defined(TEST_MUL)
+			"50*modmul %4d %4d %4d"
+#elif defined(TEST_SQR)
+			"100*modsqr %4d %4d %4d"
+#elif defined(TEST_GCD)
+			"3*gcd %4d %4d %4d"
+#elif defined(TEST_KRON)
+			"3*kronecker %4d %4d %4d"
+#elif defined(TEST_INV)
+			"2*inv %4d %4d mod %4d"
+#else /* TEST_SQRT */
+			"2*sqrt [prime == %d (mod 64)] %4d %4d mod %4d"
+#endif
+			" -> %8.6fms %5.1f (%ld)\n",
+#ifdef TEST_SQRT
+			P_MOD_64,
+#endif
+			sizes[i],sizes[i],sizes[i],tm*1000.0/num,tm*mul_c[i]/num, num);
+		num/=7;
+		if (num <= 0) num=1;
+		}
+	return;
+
+ err:
+	ERR_print_errors_fp(stderr);
+	}
+
+
+#ifdef C_PRIME
+static void genprime_cb(int p, int n, void *arg)
+	{
+	char c='*';
+
+	if (p == 0) c='.';
+	if (p == 1) c='+';
+	if (p == 2) c='*';
+	if (p == 3) c='\n';
+	putc(c, stderr);
+	fflush(stderr);
+	(void)n;
+	(void)arg;
+	}
+#endif
diff --git a/openssl/crypto/bn/exptest.c b/openssl/crypto/bn/exptest.c
new file mode 100644
index 0000000..074a8e8
--- /dev/null
+++ b/openssl/crypto/bn/exptest.c
@@ -0,0 +1,204 @@
+/* crypto/bn/exptest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../e_os.h"
+
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+#define NUM_BITS	(BN_BITS*2)
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+int main(int argc, char *argv[])
+	{
+	BN_CTX *ctx;
+	BIO *out=NULL;
+	int i,ret;
+	unsigned char c;
+	BIGNUM *r_mont,*r_mont_const,*r_recp,*r_simple,*a,*b,*m;
+
+	RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_rand may fail, and we don't
+	                                       * even check its return value
+	                                       * (which we should) */
+
+	ERR_load_BN_strings();
+
+	ctx=BN_CTX_new();
+	if (ctx == NULL) EXIT(1);
+	r_mont=BN_new();
+	r_mont_const=BN_new();
+	r_recp=BN_new();
+	r_simple=BN_new();
+	a=BN_new();
+	b=BN_new();
+	m=BN_new();
+	if (	(r_mont == NULL) || (r_recp == NULL) ||
+		(a == NULL) || (b == NULL))
+		goto err;
+
+	out=BIO_new(BIO_s_file());
+
+	if (out == NULL) EXIT(1);
+	BIO_set_fp(out,stdout,BIO_NOCLOSE);
+
+	for (i=0; i<200; i++)
+		{
+		RAND_bytes(&c,1);
+		c=(c%BN_BITS)-BN_BITS2;
+		BN_rand(a,NUM_BITS+c,0,0);
+
+		RAND_bytes(&c,1);
+		c=(c%BN_BITS)-BN_BITS2;
+		BN_rand(b,NUM_BITS+c,0,0);
+
+		RAND_bytes(&c,1);
+		c=(c%BN_BITS)-BN_BITS2;
+		BN_rand(m,NUM_BITS+c,0,1);
+
+		BN_mod(a,a,m,ctx);
+		BN_mod(b,b,m,ctx);
+
+		ret=BN_mod_exp_mont(r_mont,a,b,m,ctx,NULL);
+		if (ret <= 0)
+			{
+			printf("BN_mod_exp_mont() problems\n");
+			ERR_print_errors(out);
+			EXIT(1);
+			}
+
+		ret=BN_mod_exp_recp(r_recp,a,b,m,ctx);
+		if (ret <= 0)
+			{
+			printf("BN_mod_exp_recp() problems\n");
+			ERR_print_errors(out);
+			EXIT(1);
+			}
+
+		ret=BN_mod_exp_simple(r_simple,a,b,m,ctx);
+		if (ret <= 0)
+			{
+			printf("BN_mod_exp_simple() problems\n");
+			ERR_print_errors(out);
+			EXIT(1);
+			}
+
+		ret=BN_mod_exp_mont_consttime(r_mont_const,a,b,m,ctx,NULL);
+		if (ret <= 0)
+			{
+			printf("BN_mod_exp_mont_consttime() problems\n");
+			ERR_print_errors(out);
+			EXIT(1);
+			}
+
+		if (BN_cmp(r_simple, r_mont) == 0
+		    && BN_cmp(r_simple,r_recp) == 0
+			&& BN_cmp(r_simple,r_mont_const) == 0)
+			{
+			printf(".");
+			fflush(stdout);
+			}
+		else
+		  	{
+			if (BN_cmp(r_simple,r_mont) != 0)
+				printf("\nsimple and mont results differ\n");
+			if (BN_cmp(r_simple,r_mont_const) != 0)
+				printf("\nsimple and mont const time results differ\n");
+			if (BN_cmp(r_simple,r_recp) != 0)
+				printf("\nsimple and recp results differ\n");
+
+			printf("a (%3d) = ",BN_num_bits(a));   BN_print(out,a);
+			printf("\nb (%3d) = ",BN_num_bits(b)); BN_print(out,b);
+			printf("\nm (%3d) = ",BN_num_bits(m)); BN_print(out,m);
+			printf("\nsimple   =");	BN_print(out,r_simple);
+			printf("\nrecp     =");	BN_print(out,r_recp);
+			printf("\nmont     ="); BN_print(out,r_mont);
+			printf("\nmont_ct  ="); BN_print(out,r_mont_const);
+			printf("\n");
+			EXIT(1);
+			}
+		}
+	BN_free(r_mont);
+	BN_free(r_mont_const);
+	BN_free(r_recp);
+	BN_free(r_simple);
+	BN_free(a);
+	BN_free(b);
+	BN_free(m);
+	BN_CTX_free(ctx);
+	ERR_remove_thread_state(NULL);
+	CRYPTO_mem_leaks(out);
+	BIO_free(out);
+	printf(" done\n");
+	EXIT(0);
+err:
+	ERR_load_crypto_strings();
+	ERR_print_errors(out);
+#ifdef OPENSSL_SYS_NETWARE
+    printf("ERROR\n");
+#endif
+	EXIT(1);
+	return(1);
+	}
+
diff --git a/openssl/crypto/bn/todo b/openssl/crypto/bn/todo
new file mode 100644
index 0000000..e47e381
--- /dev/null
+++ b/openssl/crypto/bn/todo
@@ -0,0 +1,3 @@
+Cache RECP_CTX values
+make the result argument independant of the inputs.
+split up the _exp_ functions
diff --git a/openssl/crypto/bn/vms-helper.c b/openssl/crypto/bn/vms-helper.c
new file mode 100644
index 0000000..4b63149
--- /dev/null
+++ b/openssl/crypto/bn/vms-helper.c
@@ -0,0 +1,68 @@
+/* vms-helper.c */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+bn_div_words_abort(int i)
+{
+#ifdef BN_DEBUG
+#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
+	fprintf(stderr,"Division would overflow (%d)\n",i);
+#endif
+	abort();
+#endif
+}
diff --git a/openssl/crypto/buffer/Makefile b/openssl/crypto/buffer/Makefile
new file mode 100644
index 0000000..9f3a88d
--- /dev/null
+++ b/openssl/crypto/buffer/Makefile
@@ -0,0 +1,90 @@
+#
+# OpenSSL/crypto/buffer/Makefile
+#
+
+DIR=	buffer
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= buffer.c buf_err.c
+LIBOBJ= buffer.o buf_err.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= buffer.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+buf_err.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+buf_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+buf_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+buf_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+buf_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+buf_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+buf_err.o: buf_err.c
+buffer.o: ../../e_os.h ../../include/openssl/bio.h
+buffer.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+buffer.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+buffer.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+buffer.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+buffer.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+buffer.o: ../../include/openssl/symhacks.h ../cryptlib.h buffer.c
diff --git a/openssl/crypto/buffer/buf_err.c b/openssl/crypto/buffer/buf_err.c
new file mode 100644
index 0000000..8f1de61
--- /dev/null
+++ b/openssl/crypto/buffer/buf_err.c
@@ -0,0 +1,99 @@
+/* crypto/buffer/buf_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/buffer.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_BUF,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_BUF,0,reason)
+
+static ERR_STRING_DATA BUF_str_functs[]=
+	{
+{ERR_FUNC(BUF_F_BUF_MEMDUP),	"BUF_memdup"},
+{ERR_FUNC(BUF_F_BUF_MEM_GROW),	"BUF_MEM_grow"},
+{ERR_FUNC(BUF_F_BUF_MEM_GROW_CLEAN),	"BUF_MEM_grow_clean"},
+{ERR_FUNC(BUF_F_BUF_MEM_NEW),	"BUF_MEM_new"},
+{ERR_FUNC(BUF_F_BUF_STRDUP),	"BUF_strdup"},
+{ERR_FUNC(BUF_F_BUF_STRNDUP),	"BUF_strndup"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA BUF_str_reasons[]=
+	{
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_BUF_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(BUF_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,BUF_str_functs);
+		ERR_load_strings(0,BUF_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/buffer/buffer.c b/openssl/crypto/buffer/buffer.c
new file mode 100644
index 0000000..620ea8d
--- /dev/null
+++ b/openssl/crypto/buffer/buffer.c
@@ -0,0 +1,244 @@
+/* crypto/buffer/buffer.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+
+BUF_MEM *BUF_MEM_new(void)
+	{
+	BUF_MEM *ret;
+
+	ret=OPENSSL_malloc(sizeof(BUF_MEM));
+	if (ret == NULL)
+		{
+		BUFerr(BUF_F_BUF_MEM_NEW,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	ret->length=0;
+	ret->max=0;
+	ret->data=NULL;
+	return(ret);
+	}
+
+void BUF_MEM_free(BUF_MEM *a)
+	{
+	if(a == NULL)
+	    return;
+
+	if (a->data != NULL)
+		{
+		memset(a->data,0,(unsigned int)a->max);
+		OPENSSL_free(a->data);
+		}
+	OPENSSL_free(a);
+	}
+
+int BUF_MEM_grow(BUF_MEM *str, size_t len)
+	{
+	char *ret;
+	size_t n;
+
+	if (str->length >= len)
+		{
+		str->length=len;
+		return(len);
+		}
+	if (str->max >= len)
+		{
+		memset(&str->data[str->length],0,len-str->length);
+		str->length=len;
+		return(len);
+		}
+	n=(len+3)/3*4;
+	if (str->data == NULL)
+		ret=OPENSSL_malloc(n);
+	else
+		ret=OPENSSL_realloc(str->data,n);
+	if (ret == NULL)
+		{
+		BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE);
+		len=0;
+		}
+	else
+		{
+		str->data=ret;
+		str->max=n;
+		memset(&str->data[str->length],0,len-str->length);
+		str->length=len;
+		}
+	return(len);
+	}
+
+int BUF_MEM_grow_clean(BUF_MEM *str, size_t len)
+	{
+	char *ret;
+	size_t n;
+
+	if (str->length >= len)
+		{
+		memset(&str->data[len],0,str->length-len);
+		str->length=len;
+		return(len);
+		}
+	if (str->max >= len)
+		{
+		memset(&str->data[str->length],0,len-str->length);
+		str->length=len;
+		return(len);
+		}
+	n=(len+3)/3*4;
+	if (str->data == NULL)
+		ret=OPENSSL_malloc(n);
+	else
+		ret=OPENSSL_realloc_clean(str->data,str->max,n);
+	if (ret == NULL)
+		{
+		BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE);
+		len=0;
+		}
+	else
+		{
+		str->data=ret;
+		str->max=n;
+		memset(&str->data[str->length],0,len-str->length);
+		str->length=len;
+		}
+	return(len);
+	}
+
+char *BUF_strdup(const char *str)
+	{
+	if (str == NULL) return(NULL);
+	return BUF_strndup(str, strlen(str));
+	}
+
+char *BUF_strndup(const char *str, size_t siz)
+	{
+	char *ret;
+
+	if (str == NULL) return(NULL);
+
+	ret=OPENSSL_malloc(siz+1);
+	if (ret == NULL) 
+		{
+		BUFerr(BUF_F_BUF_STRNDUP,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	BUF_strlcpy(ret,str,siz+1);
+	return(ret);
+	}
+
+void *BUF_memdup(const void *data, size_t siz)
+	{
+	void *ret;
+
+	if (data == NULL) return(NULL);
+
+	ret=OPENSSL_malloc(siz);
+	if (ret == NULL) 
+		{
+		BUFerr(BUF_F_BUF_MEMDUP,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	return memcpy(ret, data, siz);
+	}	
+
+size_t BUF_strlcpy(char *dst, const char *src, size_t size)
+	{
+	size_t l = 0;
+	for(; size > 1 && *src; size--)
+		{
+		*dst++ = *src++;
+		l++;
+		}
+	if (size)
+		*dst = '\0';
+	return l + strlen(src);
+	}
+
+size_t BUF_strlcat(char *dst, const char *src, size_t size)
+	{
+	size_t l = 0;
+	for(; size > 0 && *dst; size--, dst++)
+		l++;
+	return l + BUF_strlcpy(dst, src, size);
+	}
+
+void BUF_reverse(unsigned char *out, unsigned char *in, size_t size)
+	{
+	size_t i;
+	if (in)
+		{
+		out += size - 1;
+		for (i = 0; i < size; i++)
+			*in++ = *out--;
+		}
+	else
+		{
+		unsigned char *q;
+		char c;
+		q = out + size - 1;
+		for (i = 0; i < size/2; i++)
+			{
+			c = *q;
+			*q-- = *out;
+			*out++ = c;
+			}
+		}
+	}
diff --git a/openssl/crypto/buffer/buffer.h b/openssl/crypto/buffer/buffer.h
new file mode 100644
index 0000000..178e418
--- /dev/null
+++ b/openssl/crypto/buffer/buffer.h
@@ -0,0 +1,119 @@
+/* crypto/buffer/buffer.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BUFFER_H
+#define HEADER_BUFFER_H
+
+#include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+
+#if !defined(NO_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+
+/* Already declared in ossl_typ.h */
+/* typedef struct buf_mem_st BUF_MEM; */
+
+struct buf_mem_st
+	{
+	size_t length;	/* current number of bytes */
+	char *data;
+	size_t max;	/* size of buffer */
+	};
+
+BUF_MEM *BUF_MEM_new(void);
+void	BUF_MEM_free(BUF_MEM *a);
+int	BUF_MEM_grow(BUF_MEM *str, size_t len);
+int	BUF_MEM_grow_clean(BUF_MEM *str, size_t len);
+char *	BUF_strdup(const char *str);
+char *	BUF_strndup(const char *str, size_t siz);
+void *	BUF_memdup(const void *data, size_t siz);
+void	BUF_reverse(unsigned char *out, unsigned char *in, size_t siz);
+
+/* safe string functions */
+size_t BUF_strlcpy(char *dst,const char *src,size_t siz);
+size_t BUF_strlcat(char *dst,const char *src,size_t siz);
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_BUF_strings(void);
+
+/* Error codes for the BUF functions. */
+
+/* Function codes. */
+#define BUF_F_BUF_MEMDUP				 103
+#define BUF_F_BUF_MEM_GROW				 100
+#define BUF_F_BUF_MEM_GROW_CLEAN			 105
+#define BUF_F_BUF_MEM_NEW				 101
+#define BUF_F_BUF_STRDUP				 102
+#define BUF_F_BUF_STRNDUP				 104
+
+/* Reason codes. */
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/camellia/Makefile b/openssl/crypto/camellia/Makefile
new file mode 100644
index 0000000..ff5fe4a
--- /dev/null
+++ b/openssl/crypto/camellia/Makefile
@@ -0,0 +1,103 @@
+#
+# crypto/camellia/Makefile
+#
+
+DIR= camellia
+TOP=	../..
+CC=	cc
+CPP=	$(CC) -E
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CMLL_ENC= camellia.o cmll_misc.o cmll_cbc.o
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+ASFLAGS= $(INCLUDES) $(ASFLAG)
+AFLAGS= $(ASFLAGS)
+
+GENERAL=Makefile
+#TEST=camelliatest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=camellia.c cmll_misc.c cmll_ecb.c cmll_cbc.c cmll_ofb.c \
+	   cmll_cfb.c cmll_ctr.c 
+
+LIBOBJ= cmll_ecb.o cmll_ofb.o cmll_cfb.o cmll_ctr.o $(CMLL_ENC)
+
+SRC= $(LIBSRC)
+
+EXHEADER= camellia.h
+HEADER= cmll_locl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+cmll-x86.s:	asm/cmll-x86.pl ../perlasm/x86asm.pl
+	$(PERL) asm/cmll-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
+cmll-x86_64.s:  asm/cmll-x86_64.pl
+	$(PERL) asm/cmll-x86_64.pl $(PERLASM_SCHEME) > $@
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+camellia.o: ../../include/openssl/opensslconf.h camellia.c camellia.h
+camellia.o: cmll_locl.h
+cmll_cbc.o: ../../include/openssl/camellia.h ../../include/openssl/modes.h
+cmll_cbc.o: ../../include/openssl/opensslconf.h cmll_cbc.c
+cmll_cfb.o: ../../include/openssl/camellia.h ../../include/openssl/modes.h
+cmll_cfb.o: ../../include/openssl/opensslconf.h cmll_cfb.c
+cmll_ctr.o: ../../include/openssl/camellia.h ../../include/openssl/modes.h
+cmll_ctr.o: ../../include/openssl/opensslconf.h cmll_ctr.c
+cmll_ecb.o: ../../include/openssl/camellia.h
+cmll_ecb.o: ../../include/openssl/opensslconf.h cmll_ecb.c cmll_locl.h
+cmll_misc.o: ../../include/openssl/camellia.h
+cmll_misc.o: ../../include/openssl/opensslconf.h
+cmll_misc.o: ../../include/openssl/opensslv.h cmll_locl.h cmll_misc.c
+cmll_ofb.o: ../../include/openssl/camellia.h ../../include/openssl/modes.h
+cmll_ofb.o: ../../include/openssl/opensslconf.h cmll_ofb.c
diff --git a/openssl/crypto/camellia/asm/cmll-x86.pl b/openssl/crypto/camellia/asm/cmll-x86.pl
new file mode 100644
index 0000000..027302a
--- /dev/null
+++ b/openssl/crypto/camellia/asm/cmll-x86.pl
@@ -0,0 +1,1138 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Copyright (c) 2008 Andy Polyakov <appro@openssl.org>
+#
+# This module may be used under the terms of either the GNU General
+# Public License version 2 or later, the GNU Lesser General Public
+# License version 2.1 or later, the Mozilla Public License version
+# 1.1 or the BSD License. The exact terms of either license are
+# distributed along with this module. For further details see
+# http://www.openssl.org/~appro/camellia/.
+# ====================================================================
+
+# Performance in cycles per processed byte (less is better) in
+# 'openssl speed ...' benchmark:
+#
+#			AMD K8	Core2	PIII	P4
+# -evp camellia-128-ecb	21.5	22.8	27.0	28.9
+# + over gcc 3.4.6	+90/11% +70/10%	+53/4%	+160/64%
+# + over icc 8.0	+48/19% +21/15%	+21/17%	+55/37%
+#
+# camellia-128-cbc	17.3	21.1	23.9	25.9
+#
+# 128-bit key setup	196	280	256	240	cycles/key
+# + over gcc 3.4.6	+30/0%	+17/11%	+11/0%	+63/40%
+# + over icc 8.0	+18/3%	+10/0%	+10/3%	+21/10%
+#
+# Pairs of numbers in "+" rows represent performance improvement over
+# compiler generated position-independent code, PIC, and non-PIC
+# respectively. PIC results are of greater relevance, as this module
+# is position-independent, i.e. suitable for a shared library or PIE.
+# Position independence "costs" one register, which is why compilers
+# are so close with non-PIC results, they have an extra register to
+# spare. CBC results are better than ECB ones thanks to "zero-copy"
+# private _x86_* interface, and are ~30-40% better than with compiler
+# generated cmll_cbc.o, and reach ~80-90% of x86_64 performance on
+# same CPU (where applicable).
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+$OPENSSL=1;
+
+&asm_init($ARGV[0],"cmll-586.pl",$ARGV[$#ARGV] eq "386");
+
+@T=("eax","ebx","ecx","edx");
+$idx="esi";
+$key="edi";
+$Tbl="ebp";
+
+# stack frame layout in _x86_Camellia_* routines, frame is allocated
+# by caller
+$__ra=&DWP(0,"esp");	# return address
+$__s0=&DWP(4,"esp");	# s0 backing store
+$__s1=&DWP(8,"esp");	# s1 backing store
+$__s2=&DWP(12,"esp");	# s2 backing store
+$__s3=&DWP(16,"esp");	# s3 backing store
+$__end=&DWP(20,"esp");	# pointer to end/start of key schedule
+
+# stack frame layout in Camellia_[en|crypt] routines, which differs from
+# above by 4 and overlaps by pointer to end/start of key schedule
+$_end=&DWP(16,"esp");
+$_esp=&DWP(20,"esp");
+
+# const unsigned int Camellia_SBOX[4][256];
+# Well, sort of... Camellia_SBOX[0][] is interleaved with [1][],
+# and [2][] - with [3][]. This is done to optimize code size.
+$SBOX1_1110=0;		# Camellia_SBOX[0]
+$SBOX4_4404=4;		# Camellia_SBOX[1]
+$SBOX2_0222=2048;	# Camellia_SBOX[2]
+$SBOX3_3033=2052;	# Camellia_SBOX[3]
+&static_label("Camellia_SIGMA");
+&static_label("Camellia_SBOX");
+
+sub Camellia_Feistel {
+my $i=@_[0];
+my $seed=defined(@_[1])?@_[1]:0;
+my $scale=$seed<0?-8:8;
+my $frame=defined(@_[2])?@_[2]:0;
+my $j=($i&1)*2;
+my $t0=@T[($j)%4],$t1=@T[($j+1)%4],$t2=@T[($j+2)%4],$t3=@T[($j+3)%4];
+
+	&xor	($t0,$idx);				# t0^=key[0]
+	&xor	($t1,&DWP($seed+$i*$scale+4,$key));	# t1^=key[1]
+	&movz	($idx,&HB($t0));			# (t0>>8)&0xff
+	&mov	($t3,&DWP($SBOX3_3033,$Tbl,$idx,8));	# t3=SBOX3_3033[0]
+	&movz	($idx,&LB($t0));			# (t0>>0)&0xff
+	&xor	($t3,&DWP($SBOX4_4404,$Tbl,$idx,8));	# t3^=SBOX4_4404[0]
+	&shr	($t0,16);
+	&movz	($idx,&LB($t1));			# (t1>>0)&0xff
+	&mov	($t2,&DWP($SBOX1_1110,$Tbl,$idx,8));	# t2=SBOX1_1110[1]
+	&movz	($idx,&HB($t0));			# (t0>>24)&0xff
+	&xor	($t3,&DWP($SBOX1_1110,$Tbl,$idx,8));	# t3^=SBOX1_1110[0]
+	&movz	($idx,&HB($t1));			# (t1>>8)&0xff
+	&xor	($t2,&DWP($SBOX4_4404,$Tbl,$idx,8));	# t2^=SBOX4_4404[1]
+	&shr	($t1,16);
+	&movz	($t0,&LB($t0));				# (t0>>16)&0xff
+	&xor	($t3,&DWP($SBOX2_0222,$Tbl,$t0,8));	# t3^=SBOX2_0222[0]
+	&movz	($idx,&HB($t1));			# (t1>>24)&0xff
+	&mov	($t0,&DWP($frame+4*(($j+3)%4),"esp"));	# prefetch "s3"
+	&xor	($t2,$t3);				# t2^=t3
+	&rotr	($t3,8);				# t3=RightRotate(t3,8)
+	&xor	($t2,&DWP($SBOX2_0222,$Tbl,$idx,8));	# t2^=SBOX2_0222[1]
+	&movz	($idx,&LB($t1));			# (t1>>16)&0xff
+	&mov	($t1,&DWP($frame+4*(($j+2)%4),"esp"));	# prefetch "s2"
+	&xor	($t3,$t0);				# t3^=s3
+	&xor	($t2,&DWP($SBOX3_3033,$Tbl,$idx,8));	# t2^=SBOX3_3033[1]
+	&mov	($idx,&DWP($seed+($i+1)*$scale,$key));	# prefetch key[i+1]
+	&xor	($t3,$t2);				# t3^=t2
+	&mov	(&DWP($frame+4*(($j+3)%4),"esp"),$t3);	# s3=t3
+	&xor	($t2,$t1);				# t2^=s2
+	&mov	(&DWP($frame+4*(($j+2)%4),"esp"),$t2);	# s2=t2
+}
+
+# void Camellia_EncryptBlock_Rounds(
+#		int grandRounds,
+#		const Byte plaintext[],
+#		const KEY_TABLE_TYPE keyTable,
+#		Byte ciphertext[])
+&function_begin("Camellia_EncryptBlock_Rounds");
+	&mov	("eax",&wparam(0));	# load grandRounds
+	&mov	($idx,&wparam(1));	# load plaintext pointer
+	&mov	($key,&wparam(2));	# load key schedule pointer
+
+	&mov	("ebx","esp");
+	&sub	("esp",7*4);		# place for s[0-3],keyEnd,esp and ra
+	&and	("esp",-64);
+
+	# place stack frame just "above mod 1024" the key schedule
+	# this ensures that cache associativity of 2 suffices
+	&lea	("ecx",&DWP(-64-63,$key));
+	&sub	("ecx","esp");
+	&neg	("ecx");
+	&and	("ecx",0x3C0);	# modulo 1024, but aligned to cache-line
+	&sub	("esp","ecx");
+	&add	("esp",4);	# 4 is reserved for callee's return address
+
+	&shl	("eax",6);
+	&lea	("eax",&DWP(0,$key,"eax"));
+	&mov	($_esp,"ebx");	# save %esp
+	&mov	($_end,"eax");	# save keyEnd
+
+	&call	(&label("pic_point"));
+	&set_label("pic_point");
+	&blindpop($Tbl);
+	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
+
+	&mov	(@T[0],&DWP(0,$idx));	# load plaintext
+	&mov	(@T[1],&DWP(4,$idx));
+	&mov	(@T[2],&DWP(8,$idx));
+	&bswap	(@T[0]);
+	&mov	(@T[3],&DWP(12,$idx));
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+
+	&call	("_x86_Camellia_encrypt");
+
+	&mov	("esp",$_esp);
+	&bswap	(@T[0]);
+	&mov	($idx,&wparam(3));	# load ciphertext pointer
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+	&mov	(&DWP(0,$idx),@T[0]);	# write ciphertext
+	&mov	(&DWP(4,$idx),@T[1]);
+	&mov	(&DWP(8,$idx),@T[2]);
+	&mov	(&DWP(12,$idx),@T[3]);
+&function_end("Camellia_EncryptBlock_Rounds");
+# V1.x API
+&function_begin_B("Camellia_EncryptBlock");
+	&mov	("eax",128);
+	&sub	("eax",&wparam(0));	# load keyBitLength
+	&mov	("eax",3);
+	&adc	("eax",0);		# keyBitLength==128?3:4
+	&mov	(&wparam(0),"eax");
+	&jmp	(&label("Camellia_EncryptBlock_Rounds"));
+&function_end_B("Camellia_EncryptBlock");
+
+if ($OPENSSL) {
+# void Camellia_encrypt(
+#		const unsigned char *in,
+#		unsigned char *out,
+#		const CAMELLIA_KEY *key)
+&function_begin("Camellia_encrypt");
+	&mov	($idx,&wparam(0));	# load plaintext pointer
+	&mov	($key,&wparam(2));	# load key schedule pointer
+
+	&mov	("ebx","esp");
+	&sub	("esp",7*4);		# place for s[0-3],keyEnd,esp and ra
+	&and	("esp",-64);
+	&mov	("eax",&DWP(272,$key));	# load grandRounds counter
+
+	# place stack frame just "above mod 1024" the key schedule
+	# this ensures that cache associativity of 2 suffices
+	&lea	("ecx",&DWP(-64-63,$key));
+	&sub	("ecx","esp");
+	&neg	("ecx");
+	&and	("ecx",0x3C0);	# modulo 1024, but aligned to cache-line
+	&sub	("esp","ecx");
+	&add	("esp",4);	# 4 is reserved for callee's return address
+
+	&shl	("eax",6);
+	&lea	("eax",&DWP(0,$key,"eax"));
+	&mov	($_esp,"ebx");	# save %esp
+	&mov	($_end,"eax");	# save keyEnd
+
+	&call	(&label("pic_point"));
+	&set_label("pic_point");
+	&blindpop($Tbl);
+	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
+
+	&mov	(@T[0],&DWP(0,$idx));	# load plaintext
+	&mov	(@T[1],&DWP(4,$idx));
+	&mov	(@T[2],&DWP(8,$idx));
+	&bswap	(@T[0]);
+	&mov	(@T[3],&DWP(12,$idx));
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+
+	&call	("_x86_Camellia_encrypt");
+
+	&mov	("esp",$_esp);
+	&bswap	(@T[0]);
+	&mov	($idx,&wparam(1));	# load ciphertext pointer
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+	&mov	(&DWP(0,$idx),@T[0]);	# write ciphertext
+	&mov	(&DWP(4,$idx),@T[1]);
+	&mov	(&DWP(8,$idx),@T[2]);
+	&mov	(&DWP(12,$idx),@T[3]);
+&function_end("Camellia_encrypt");
+}
+
+&function_begin_B("_x86_Camellia_encrypt");
+	&xor	(@T[0],&DWP(0,$key));	# ^=key[0-3]
+	&xor	(@T[1],&DWP(4,$key));
+	&xor	(@T[2],&DWP(8,$key));
+	&xor	(@T[3],&DWP(12,$key));
+	&mov	($idx,&DWP(16,$key));	# prefetch key[4]
+
+	&mov	($__s0,@T[0]);		# save s[0-3]
+	&mov	($__s1,@T[1]);
+	&mov	($__s2,@T[2]);
+	&mov	($__s3,@T[3]);
+
+&set_label("loop",16);
+	for ($i=0;$i<6;$i++) { Camellia_Feistel($i,16,4); }
+
+	&add	($key,16*4);
+	&cmp	($key,$__end);
+	&je	(&label("done"));
+
+	# @T[0-1] are preloaded, $idx is preloaded with key[0]
+	&and	($idx,@T[0]);
+	 &mov	 (@T[3],$__s3);
+	&rotl	($idx,1);
+	 &mov	 (@T[2],@T[3]);
+	&xor	(@T[1],$idx);
+	 &or	 (@T[2],&DWP(12,$key));
+	&mov	($__s1,@T[1]);		# s1^=LeftRotate(s0&key[0],1);
+	 &xor	 (@T[2],$__s2);
+
+	&mov	($idx,&DWP(4,$key));
+	 &mov	 ($__s2,@T[2]);		# s2^=s3|key[3];
+	&or	($idx,@T[1]);
+	 &and	 (@T[2],&DWP(8,$key));
+	&xor	(@T[0],$idx);
+	 &rotl	 (@T[2],1);
+	&mov	($__s0,@T[0]);		# s0^=s1|key[1];
+	 &xor	 (@T[3],@T[2]);
+	&mov	($idx,&DWP(16,$key));		# prefetch key[4]
+	 &mov	 ($__s3,@T[3]);		# s3^=LeftRotate(s2&key[2],1);
+	&jmp	(&label("loop"));
+
+&set_label("done",8);
+	&mov	(@T[2],@T[0]);		# SwapHalf
+	&mov	(@T[3],@T[1]);
+	&mov	(@T[0],$__s2);
+	&mov	(@T[1],$__s3);
+	&xor	(@T[0],$idx);		# $idx is preloaded with key[0]
+	&xor	(@T[1],&DWP(4,$key));
+	&xor	(@T[2],&DWP(8,$key));
+	&xor	(@T[3],&DWP(12,$key));
+	&ret	();
+&function_end_B("_x86_Camellia_encrypt");
+
+# void Camellia_DecryptBlock_Rounds(
+#		int grandRounds,
+#		const Byte ciphertext[],
+#		const KEY_TABLE_TYPE keyTable,
+#		Byte plaintext[])
+&function_begin("Camellia_DecryptBlock_Rounds");
+	&mov	("eax",&wparam(0));	# load grandRounds
+	&mov	($idx,&wparam(1));	# load ciphertext pointer
+	&mov	($key,&wparam(2));	# load key schedule pointer
+
+	&mov	("ebx","esp");
+	&sub	("esp",7*4);		# place for s[0-3],keyEnd,esp and ra
+	&and	("esp",-64);
+
+	# place stack frame just "above mod 1024" the key schedule
+	# this ensures that cache associativity of 2 suffices
+	&lea	("ecx",&DWP(-64-63,$key));
+	&sub	("ecx","esp");
+	&neg	("ecx");
+	&and	("ecx",0x3C0);	# modulo 1024, but aligned to cache-line
+	&sub	("esp","ecx");
+	&add	("esp",4);	# 4 is reserved for callee's return address
+
+	&shl	("eax",6);
+	&mov	(&DWP(4*4,"esp"),$key);	# save keyStart
+	&lea	($key,&DWP(0,$key,"eax"));
+	&mov	(&DWP(5*4,"esp"),"ebx");# save %esp
+
+	&call	(&label("pic_point"));
+	&set_label("pic_point");
+	&blindpop($Tbl);
+	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
+
+	&mov	(@T[0],&DWP(0,$idx));	# load ciphertext
+	&mov	(@T[1],&DWP(4,$idx));
+	&mov	(@T[2],&DWP(8,$idx));
+	&bswap	(@T[0]);
+	&mov	(@T[3],&DWP(12,$idx));
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+
+	&call	("_x86_Camellia_decrypt");
+
+	&mov	("esp",&DWP(5*4,"esp"));
+	&bswap	(@T[0]);
+	&mov	($idx,&wparam(3));	# load plaintext pointer
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+	&mov	(&DWP(0,$idx),@T[0]);	# write plaintext
+	&mov	(&DWP(4,$idx),@T[1]);
+	&mov	(&DWP(8,$idx),@T[2]);
+	&mov	(&DWP(12,$idx),@T[3]);
+&function_end("Camellia_DecryptBlock_Rounds");
+# V1.x API
+&function_begin_B("Camellia_DecryptBlock");
+	&mov	("eax",128);
+	&sub	("eax",&wparam(0));	# load keyBitLength
+	&mov	("eax",3);
+	&adc	("eax",0);		# keyBitLength==128?3:4
+	&mov	(&wparam(0),"eax");
+	&jmp	(&label("Camellia_DecryptBlock_Rounds"));
+&function_end_B("Camellia_DecryptBlock");
+
+if ($OPENSSL) {
+# void Camellia_decrypt(
+#		const unsigned char *in,
+#		unsigned char *out,
+#		const CAMELLIA_KEY *key)
+&function_begin("Camellia_decrypt");
+	&mov	($idx,&wparam(0));	# load ciphertext pointer
+	&mov	($key,&wparam(2));	# load key schedule pointer
+
+	&mov	("ebx","esp");
+	&sub	("esp",7*4);		# place for s[0-3],keyEnd,esp and ra
+	&and	("esp",-64);
+	&mov	("eax",&DWP(272,$key));	# load grandRounds counter
+
+	# place stack frame just "above mod 1024" the key schedule
+	# this ensures that cache associativity of 2 suffices
+	&lea	("ecx",&DWP(-64-63,$key));
+	&sub	("ecx","esp");
+	&neg	("ecx");
+	&and	("ecx",0x3C0);	# modulo 1024, but aligned to cache-line
+	&sub	("esp","ecx");
+	&add	("esp",4);	# 4 is reserved for callee's return address
+
+	&shl	("eax",6);
+	&mov	(&DWP(4*4,"esp"),$key);	# save keyStart
+	&lea	($key,&DWP(0,$key,"eax"));
+	&mov	(&DWP(5*4,"esp"),"ebx");# save %esp
+
+	&call	(&label("pic_point"));
+	&set_label("pic_point");
+	&blindpop($Tbl);
+	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
+
+	&mov	(@T[0],&DWP(0,$idx));	# load ciphertext
+	&mov	(@T[1],&DWP(4,$idx));
+	&mov	(@T[2],&DWP(8,$idx));
+	&bswap	(@T[0]);
+	&mov	(@T[3],&DWP(12,$idx));
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+
+	&call	("_x86_Camellia_decrypt");
+
+	&mov	("esp",&DWP(5*4,"esp"));
+	&bswap	(@T[0]);
+	&mov	($idx,&wparam(1));	# load plaintext pointer
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+	&mov	(&DWP(0,$idx),@T[0]);	# write plaintext
+	&mov	(&DWP(4,$idx),@T[1]);
+	&mov	(&DWP(8,$idx),@T[2]);
+	&mov	(&DWP(12,$idx),@T[3]);
+&function_end("Camellia_decrypt");
+}
+
+&function_begin_B("_x86_Camellia_decrypt");
+	&xor	(@T[0],&DWP(0,$key));	# ^=key[0-3]
+	&xor	(@T[1],&DWP(4,$key));
+	&xor	(@T[2],&DWP(8,$key));
+	&xor	(@T[3],&DWP(12,$key));
+	&mov	($idx,&DWP(-8,$key));	# prefetch key[-2]
+
+	&mov	($__s0,@T[0]);		# save s[0-3]
+	&mov	($__s1,@T[1]);
+	&mov	($__s2,@T[2]);
+	&mov	($__s3,@T[3]);
+
+&set_label("loop",16);
+	for ($i=0;$i<6;$i++) { Camellia_Feistel($i,-8,4); }
+
+	&sub	($key,16*4);
+	&cmp	($key,$__end);
+	&je	(&label("done"));
+
+	# @T[0-1] are preloaded, $idx is preloaded with key[2]
+	&and	($idx,@T[0]);
+	 &mov	 (@T[3],$__s3);
+	&rotl	($idx,1);
+	 &mov	 (@T[2],@T[3]);
+	&xor	(@T[1],$idx);
+	 &or	 (@T[2],&DWP(4,$key));
+	&mov	($__s1,@T[1]);		# s1^=LeftRotate(s0&key[0],1);
+	 &xor	 (@T[2],$__s2);
+
+	&mov	($idx,&DWP(12,$key));
+	 &mov	 ($__s2,@T[2]);		# s2^=s3|key[3];
+	&or	($idx,@T[1]);
+	 &and	 (@T[2],&DWP(0,$key));
+	&xor	(@T[0],$idx);
+	 &rotl	 (@T[2],1);
+	&mov	($__s0,@T[0]);		# s0^=s1|key[1];
+	 &xor	 (@T[3],@T[2]);
+	&mov	($idx,&DWP(-8,$key));	# prefetch key[4]
+	 &mov	 ($__s3,@T[3]);		# s3^=LeftRotate(s2&key[2],1);
+	&jmp	(&label("loop"));
+
+&set_label("done",8);
+	&mov	(@T[2],@T[0]);		# SwapHalf
+	&mov	(@T[3],@T[1]);
+	&mov	(@T[0],$__s2);
+	&mov	(@T[1],$__s3);
+	&xor	(@T[2],$idx);		# $idx is preloaded with key[2]
+	&xor	(@T[3],&DWP(12,$key));
+	&xor	(@T[0],&DWP(0,$key));
+	&xor	(@T[1],&DWP(4,$key));
+	&ret	();
+&function_end_B("_x86_Camellia_decrypt");
+
+# shld is very slow on Intel P4 family. Even on AMD it limits
+# instruction decode rate [because it's VectorPath] and consequently
+# performance. PIII, PM and Core[2] seem to be the only ones which
+# execute this code ~7% faster...
+sub __rotl128 {
+  my ($i0,$i1,$i2,$i3,$rot,$rnd,@T)=@_;
+
+    $rnd *= 2;
+    if ($rot) {
+	&mov	($idx,$i0);
+	&shld	($i0,$i1,$rot);
+	&shld	($i1,$i2,$rot);
+	&shld	($i2,$i3,$rot);
+	&shld	($i3,$idx,$rot);
+    }
+    &mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i0 eq @T[0]);
+    &mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i1 eq @T[0]);
+    &mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i2 eq @T[0]);
+    &mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i3 eq @T[0]);
+}
+
+# ... Implementing 128-bit rotate without shld gives >3x performance
+# improvement on P4, only ~7% degradation on other Intel CPUs and
+# not worse performance on AMD. This is therefore preferred.
+sub _rotl128 {
+  my ($i0,$i1,$i2,$i3,$rot,$rnd,@T)=@_;
+
+    $rnd *= 2;
+    if ($rot) {
+	&mov	($Tbl,$i0);
+	&shl	($i0,$rot);
+	&mov	($idx,$i1);
+	&shr	($idx,32-$rot);
+	&shl	($i1,$rot);
+	&or	($i0,$idx);
+	&mov	($idx,$i2);
+	&shl	($i2,$rot);
+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i0 eq @T[0]);
+	&shr	($idx,32-$rot);
+	&or	($i1,$idx);
+	&shr	($Tbl,32-$rot);
+	&mov	($idx,$i3);
+	&shr	($idx,32-$rot);
+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i1 eq @T[0]);
+	&shl	($i3,$rot);
+	&or	($i2,$idx);
+	&or	($i3,$Tbl);
+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i2 eq @T[0]);
+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i3 eq @T[0]);
+    } else {
+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i0 eq @T[0]);
+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i1 eq @T[0]);
+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i2 eq @T[0]);
+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i3 eq @T[0]);
+    }
+}
+
+sub _saveround {
+my ($rnd,$key,@T)=@_;
+my $bias=int(@T[0])?shift(@T):0;
+
+	&mov	(&DWP($bias+$rnd*8+0,$key),@T[0]);
+	&mov	(&DWP($bias+$rnd*8+4,$key),@T[1])	if ($#T>=1);
+	&mov	(&DWP($bias+$rnd*8+8,$key),@T[2])	if ($#T>=2);
+	&mov	(&DWP($bias+$rnd*8+12,$key),@T[3])	if ($#T>=3);
+}
+
+sub _loadround {
+my ($rnd,$key,@T)=@_;
+my $bias=int(@T[0])?shift(@T):0;
+
+	&mov	(@T[0],&DWP($bias+$rnd*8+0,$key));
+	&mov	(@T[1],&DWP($bias+$rnd*8+4,$key))	if ($#T>=1);
+	&mov	(@T[2],&DWP($bias+$rnd*8+8,$key))	if ($#T>=2);
+	&mov	(@T[3],&DWP($bias+$rnd*8+12,$key))	if ($#T>=3);
+}
+
+# void Camellia_Ekeygen(
+#		const int keyBitLength,
+#		const Byte *rawKey,
+#		KEY_TABLE_TYPE keyTable)
+&function_begin("Camellia_Ekeygen");
+{ my $step=0;
+
+	&stack_push(4);				# place for s[0-3]
+
+	&mov	($Tbl,&wparam(0));		# load arguments
+	&mov	($idx,&wparam(1));
+	&mov	($key,&wparam(2));
+
+	&mov	(@T[0],&DWP(0,$idx));		# load 0-127 bits
+	&mov	(@T[1],&DWP(4,$idx));
+	&mov	(@T[2],&DWP(8,$idx));
+	&mov	(@T[3],&DWP(12,$idx));
+
+	&bswap	(@T[0]);
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+
+	&_saveround	(0,$key,@T);		# KL<<<0
+
+	&cmp	($Tbl,128);
+	&je	(&label("1st128"));
+
+	&mov	(@T[0],&DWP(16,$idx));		# load 128-191 bits
+	&mov	(@T[1],&DWP(20,$idx));
+	&cmp	($Tbl,192);
+	&je	(&label("1st192"));
+	&mov	(@T[2],&DWP(24,$idx));		# load 192-255 bits
+	&mov	(@T[3],&DWP(28,$idx));
+	&jmp	(&label("1st256"));
+&set_label("1st192",4);
+	&mov	(@T[2],@T[0]);
+	&mov	(@T[3],@T[1]);
+	&not	(@T[2]);
+	&not	(@T[3]);
+&set_label("1st256",4);
+	&bswap	(@T[0]);
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+
+	&_saveround	(4,$key,@T);		# temporary storage for KR!
+
+	&xor	(@T[0],&DWP(0*8+0,$key));	# KR^KL
+	&xor	(@T[1],&DWP(0*8+4,$key));
+	&xor	(@T[2],&DWP(1*8+0,$key));
+	&xor	(@T[3],&DWP(1*8+4,$key));
+
+&set_label("1st128",4);
+	&call	(&label("pic_point"));
+	&set_label("pic_point");
+	&blindpop($Tbl);
+	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
+	&lea	($key,&DWP(&label("Camellia_SIGMA")."-".&label("Camellia_SBOX"),$Tbl));
+
+	&mov	($idx,&DWP($step*8,$key));	# prefetch SIGMA[0]
+	&mov	(&swtmp(0),@T[0]);		# save s[0-3]
+	&mov	(&swtmp(1),@T[1]);
+	&mov	(&swtmp(2),@T[2]);
+	&mov	(&swtmp(3),@T[3]);
+	&Camellia_Feistel($step++);
+	&Camellia_Feistel($step++);
+	&mov	(@T[2],&swtmp(2));
+	&mov	(@T[3],&swtmp(3));
+
+	&mov	($idx,&wparam(2));
+	&xor	(@T[0],&DWP(0*8+0,$idx));	# ^KL
+	&xor	(@T[1],&DWP(0*8+4,$idx));
+	&xor	(@T[2],&DWP(1*8+0,$idx));
+	&xor	(@T[3],&DWP(1*8+4,$idx));
+
+	&mov	($idx,&DWP($step*8,$key));	# prefetch SIGMA[4]
+	&mov	(&swtmp(0),@T[0]);		# save s[0-3]
+	&mov	(&swtmp(1),@T[1]);
+	&mov	(&swtmp(2),@T[2]);
+	&mov	(&swtmp(3),@T[3]);
+	&Camellia_Feistel($step++);
+	&Camellia_Feistel($step++);
+	&mov	(@T[2],&swtmp(2));
+	&mov	(@T[3],&swtmp(3));
+
+	&mov	($idx,&wparam(0));
+	&cmp	($idx,128);
+	&jne	(&label("2nd256"));
+
+	&mov	($key,&wparam(2));
+	&lea	($key,&DWP(128,$key));		# size optimization
+
+	####### process KA
+	&_saveround	(2,$key,-128,@T);	# KA<<<0
+	&_rotl128	(@T,15,6,@T);		# KA<<<15
+	&_rotl128	(@T,15,8,@T);		# KA<<<(15+15=30)
+	&_rotl128	(@T,15,12,@T[0],@T[1]);	# KA<<<(30+15=45)
+	&_rotl128	(@T,15,14,@T);		# KA<<<(45+15=60)
+	push		(@T,shift(@T));		# rotl128(@T,32);
+	&_rotl128	(@T,2,20,@T);		# KA<<<(60+32+2=94)
+	&_rotl128	(@T,17,24,@T);		# KA<<<(94+17=111)
+
+	####### process KL
+	&_loadround	(0,$key,-128,@T);	# load KL
+	&_rotl128	(@T,15,4,@T);		# KL<<<15
+	&_rotl128	(@T,30,10,@T);		# KL<<<(15+30=45)
+	&_rotl128	(@T,15,13,@T[2],@T[3]);	# KL<<<(45+15=60)
+	&_rotl128	(@T,17,16,@T);		# KL<<<(60+17=77)
+	&_rotl128	(@T,17,18,@T);		# KL<<<(77+17=94)
+	&_rotl128	(@T,17,22,@T);		# KL<<<(94+17=111)
+
+	while (@T[0] ne "eax")			# restore order
+	{   unshift	(@T,pop(@T));   }
+
+	&mov	("eax",3);			# 3 grandRounds
+	&jmp	(&label("done"));
+
+&set_label("2nd256",16);
+	&mov	($idx,&wparam(2));
+	&_saveround	(6,$idx,@T);		# temporary storage for KA!
+
+	&xor	(@T[0],&DWP(4*8+0,$idx));	# KA^KR
+	&xor	(@T[1],&DWP(4*8+4,$idx));
+	&xor	(@T[2],&DWP(5*8+0,$idx));
+	&xor	(@T[3],&DWP(5*8+4,$idx));
+
+	&mov	($idx,&DWP($step*8,$key));	# prefetch SIGMA[8]
+	&mov	(&swtmp(0),@T[0]);		# save s[0-3]
+	&mov	(&swtmp(1),@T[1]);
+	&mov	(&swtmp(2),@T[2]);
+	&mov	(&swtmp(3),@T[3]);
+	&Camellia_Feistel($step++);
+	&Camellia_Feistel($step++);
+	&mov	(@T[2],&swtmp(2));
+	&mov	(@T[3],&swtmp(3));
+
+	&mov	($key,&wparam(2));
+	&lea	($key,&DWP(128,$key));		# size optimization
+
+	####### process KB
+	&_saveround	(2,$key,-128,@T);	# KB<<<0
+	&_rotl128	(@T,30,10,@T);		# KB<<<30
+	&_rotl128	(@T,30,20,@T);		# KB<<<(30+30=60)
+	push		(@T,shift(@T));		# rotl128(@T,32);
+	&_rotl128	(@T,19,32,@T);		# KB<<<(60+32+19=111)
+
+	####### process KR
+	&_loadround	(4,$key,-128,@T);	# load KR
+	&_rotl128	(@T,15,4,@T);		# KR<<<15
+	&_rotl128	(@T,15,8,@T);		# KR<<<(15+15=30)
+	&_rotl128	(@T,30,18,@T);		# KR<<<(30+30=60)
+	push		(@T,shift(@T));		# rotl128(@T,32);
+	&_rotl128	(@T,2,26,@T);		# KR<<<(60+32+2=94)
+
+	####### process KA
+	&_loadround	(6,$key,-128,@T);	# load KA
+	&_rotl128	(@T,15,6,@T);		# KA<<<15
+	&_rotl128	(@T,30,14,@T);		# KA<<<(15+30=45)
+	push		(@T,shift(@T));		# rotl128(@T,32);
+	&_rotl128	(@T,0,24,@T);		# KA<<<(45+32+0=77)
+	&_rotl128	(@T,17,28,@T);		# KA<<<(77+17=94)
+
+	####### process KL
+	&_loadround	(0,$key,-128,@T);	# load KL
+	push		(@T,shift(@T));		# rotl128(@T,32);
+	&_rotl128	(@T,13,12,@T);		# KL<<<(32+13=45)
+	&_rotl128	(@T,15,16,@T);		# KL<<<(45+15=60)
+	&_rotl128	(@T,17,22,@T);		# KL<<<(60+17=77)
+	push		(@T,shift(@T));		# rotl128(@T,32);
+	&_rotl128	(@T,2,30,@T);		# KL<<<(77+32+2=111)
+
+	while (@T[0] ne "eax")			# restore order
+	{   unshift	(@T,pop(@T));   }
+
+	&mov	("eax",4);			# 4 grandRounds
+&set_label("done");
+	&lea	("edx",&DWP(272-128,$key));	# end of key schedule
+	&stack_pop(4);
+}
+&function_end("Camellia_Ekeygen");
+
+if ($OPENSSL) {
+# int Camellia_set_key (
+#		const unsigned char *userKey,
+#		int bits,
+#		CAMELLIA_KEY *key)
+&function_begin_B("Camellia_set_key");
+	&push	("ebx");
+	&mov	("ecx",&wparam(0));	# pull arguments
+	&mov	("ebx",&wparam(1));
+	&mov	("edx",&wparam(2));
+
+	&mov	("eax",-1);
+	&test	("ecx","ecx");
+	&jz	(&label("done"));	# userKey==NULL?
+	&test	("edx","edx");
+	&jz	(&label("done"));	# key==NULL?
+
+	&mov	("eax",-2);
+	&cmp	("ebx",256);
+	&je	(&label("arg_ok"));	# bits==256?
+	&cmp	("ebx",192);
+	&je	(&label("arg_ok"));	# bits==192?
+	&cmp	("ebx",128);
+	&jne	(&label("done"));	# bits!=128?
+&set_label("arg_ok",4);
+
+	&push	("edx");		# push arguments
+	&push	("ecx");
+	&push	("ebx");
+	&call	("Camellia_Ekeygen");
+	&stack_pop(3);
+
+	# eax holds grandRounds and edx points at where to put it
+	&mov	(&DWP(0,"edx"),"eax");
+	&xor	("eax","eax");
+&set_label("done",4);
+	&pop	("ebx");
+	&ret	();
+&function_end_B("Camellia_set_key");
+}
+
+@SBOX=(
+112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
+ 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
+134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
+166,225, 57,202,213, 71, 93, 61,217,  1, 90,214, 81, 86,108, 77,
+139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
+223, 76,203,194, 52,126,118,  5,109,183,169, 49,209, 23,  4,215,
+ 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
+254, 68,207,178,195,181,122,145, 36,  8,232,168, 96,252,105, 80,
+170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
+ 16,196,  0, 72,163,247,117,219,138,  3,230,218,  9, 63,221,148,
+135, 92,131,  2,205, 74,144, 51,115,103,246,243,157,127,191,226,
+ 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
+233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
+120,152,  6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
+114,  7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
+ 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158);
+
+sub S1110 { my $i=shift; $i=@SBOX[$i]; return $i<<24|$i<<16|$i<<8; }
+sub S4404 { my $i=shift; $i=($i<<1|$i>>7)&0xff; $i=@SBOX[$i]; return $i<<24|$i<<16|$i; }	
+sub S0222 { my $i=shift; $i=@SBOX[$i]; $i=($i<<1|$i>>7)&0xff; return $i<<16|$i<<8|$i; }	
+sub S3033 { my $i=shift; $i=@SBOX[$i]; $i=($i>>1|$i<<7)&0xff; return $i<<24|$i<<8|$i; }	
+
+&set_label("Camellia_SIGMA",64);
+&data_word(
+    0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2,
+    0xc6ef372f, 0xe94f82be, 0x54ff53a5, 0xf1d36f1c,
+    0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd,
+    0,          0,          0,          0);
+&set_label("Camellia_SBOX",64);
+# tables are interleaved, remember?
+for ($i=0;$i<256;$i++) { &data_word(&S1110($i),&S4404($i)); }
+for ($i=0;$i<256;$i++) { &data_word(&S0222($i),&S3033($i)); }
+
+# void Camellia_cbc_encrypt (const void char *inp, unsigned char *out,
+#			size_t length, const CAMELLIA_KEY *key,
+#			unsigned char *ivp,const int enc);
+{
+# stack frame layout
+#             -4(%esp)		# return address	 0(%esp)
+#              0(%esp)		# s0			 4(%esp)
+#              4(%esp)		# s1			 8(%esp)
+#              8(%esp)		# s2			12(%esp)
+#             12(%esp)		# s3			16(%esp)
+#             16(%esp)		# end of key schedule	20(%esp)
+#             20(%esp)		# %esp backup
+my $_inp=&DWP(24,"esp");	#copy of wparam(0)
+my $_out=&DWP(28,"esp");	#copy of wparam(1)
+my $_len=&DWP(32,"esp");	#copy of wparam(2)
+my $_key=&DWP(36,"esp");	#copy of wparam(3)
+my $_ivp=&DWP(40,"esp");	#copy of wparam(4)
+my $ivec=&DWP(44,"esp");	#ivec[16]
+my $_tmp=&DWP(44,"esp");	#volatile variable [yes, aliases with ivec]
+my ($s0,$s1,$s2,$s3) = @T;
+
+&function_begin("Camellia_cbc_encrypt");
+	&mov	($s2 eq "ecx"? $s2 : "",&wparam(2));	# load len
+	&cmp	($s2,0);
+	&je	(&label("enc_out"));
+
+	&pushf	();
+	&cld	();
+
+	&mov	($s0,&wparam(0));	# load inp
+	&mov	($s1,&wparam(1));	# load out
+	#&mov	($s2,&wparam(2));	# load len
+	&mov	($s3,&wparam(3));	# load key
+	&mov	($Tbl,&wparam(4));	# load ivp
+
+	# allocate aligned stack frame...
+	&lea	($idx,&DWP(-64,"esp"));
+	&and	($idx,-64);
+
+	# place stack frame just "above mod 1024" the key schedule
+	# this ensures that cache associativity of 2 suffices
+	&lea	($key,&DWP(-64-63,$s3));
+	&sub	($key,$idx);
+	&neg	($key);
+	&and	($key,0x3C0);	# modulo 1024, but aligned to cache-line
+	&sub	($idx,$key);
+
+	&mov	($key,&wparam(5));	# load enc
+
+	&exch	("esp",$idx);
+	&add	("esp",4);		# reserve for return address!
+	&mov	($_esp,$idx);		# save %esp
+
+	&mov	($_inp,$s0);		# save copy of inp
+	&mov	($_out,$s1);		# save copy of out
+	&mov	($_len,$s2);		# save copy of len
+	&mov	($_key,$s3);		# save copy of key
+	&mov	($_ivp,$Tbl);		# save copy of ivp
+
+	&call   (&label("pic_point"));	# make it PIC!
+	&set_label("pic_point");
+	&blindpop($Tbl);
+	&lea    ($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
+
+	&mov	($idx,32);
+	&set_label("prefetch_sbox",4);
+		&mov	($s0,&DWP(0,$Tbl));
+		&mov	($s1,&DWP(32,$Tbl));
+		&mov	($s2,&DWP(64,$Tbl));
+		&mov	($s3,&DWP(96,$Tbl));
+		&lea	($Tbl,&DWP(128,$Tbl));
+		&dec	($idx);
+	&jnz	(&label("prefetch_sbox"));
+	&mov	($s0,$_key);
+	&sub	($Tbl,4096);
+	&mov	($idx,$_inp);
+	&mov	($s3,&DWP(272,$s0));		# load grandRounds
+
+	&cmp	($key,0);
+	&je	(&label("DECRYPT"));
+
+	&mov	($s2,$_len);
+	&mov	($key,$_ivp);
+	&shl	($s3,6);
+	&lea	($s3,&DWP(0,$s0,$s3));
+	&mov	($_end,$s3);
+
+	&test	($s2,0xFFFFFFF0);
+	&jz	(&label("enc_tail"));		# short input...
+
+	&mov	($s0,&DWP(0,$key));		# load iv
+	&mov	($s1,&DWP(4,$key));
+
+	&set_label("enc_loop",4);
+		&mov	($s2,&DWP(8,$key));
+		&mov	($s3,&DWP(12,$key));
+
+		&xor	($s0,&DWP(0,$idx));	# xor input data
+		&xor	($s1,&DWP(4,$idx));
+		&xor	($s2,&DWP(8,$idx));
+		&bswap	($s0);
+		&xor	($s3,&DWP(12,$idx));
+		&bswap	($s1);
+		&mov	($key,$_key);		# load key
+		&bswap	($s2);
+		&bswap	($s3);
+
+		&call	("_x86_Camellia_encrypt");
+
+		&mov	($idx,$_inp);		# load inp
+		&mov	($key,$_out);		# load out
+
+		&bswap	($s0);
+		&bswap	($s1);
+		&bswap	($s2);
+		&mov	(&DWP(0,$key),$s0);	# save output data
+		&bswap	($s3);
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&mov	(&DWP(12,$key),$s3);
+
+		&mov	($s2,$_len);		# load len
+
+		&lea	($idx,&DWP(16,$idx));
+		&mov	($_inp,$idx);		# save inp
+
+		&lea	($s3,&DWP(16,$key));
+		&mov	($_out,$s3);		# save out
+
+		&sub	($s2,16);
+		&test	($s2,0xFFFFFFF0);
+		&mov	($_len,$s2);		# save len
+	&jnz	(&label("enc_loop"));
+	&test	($s2,15);
+	&jnz	(&label("enc_tail"));
+	&mov	($idx,$_ivp);		# load ivp
+	&mov	($s2,&DWP(8,$key));	# restore last dwords
+	&mov	($s3,&DWP(12,$key));
+	&mov	(&DWP(0,$idx),$s0);	# save ivec
+	&mov	(&DWP(4,$idx),$s1);
+	&mov	(&DWP(8,$idx),$s2);
+	&mov	(&DWP(12,$idx),$s3);
+
+	&mov	("esp",$_esp);
+	&popf	();
+    &set_label("enc_out");
+	&function_end_A();
+	&pushf	();			# kludge, never executed
+
+    &set_label("enc_tail",4);
+	&mov	($s0,$key eq "edi" ? $key : "");
+	&mov	($key,$_out);			# load out
+	&push	($s0);				# push ivp
+	&mov	($s1,16);
+	&sub	($s1,$s2);
+	&cmp	($key,$idx);			# compare with inp
+	&je	(&label("enc_in_place"));
+	&align	(4);
+	&data_word(0xA4F3F689);	# rep movsb	# copy input
+	&jmp	(&label("enc_skip_in_place"));
+    &set_label("enc_in_place");
+	&lea	($key,&DWP(0,$key,$s2));
+    &set_label("enc_skip_in_place");
+	&mov	($s2,$s1);
+	&xor	($s0,$s0);
+	&align	(4);
+	&data_word(0xAAF3F689);	# rep stosb	# zero tail
+	&pop	($key);				# pop ivp
+
+	&mov	($idx,$_out);			# output as input
+	&mov	($s0,&DWP(0,$key));
+	&mov	($s1,&DWP(4,$key));
+	&mov	($_len,16);			# len=16
+	&jmp	(&label("enc_loop"));		# one more spin...
+
+#----------------------------- DECRYPT -----------------------------#
+&set_label("DECRYPT",16);
+	&shl	($s3,6);
+	&lea	($s3,&DWP(0,$s0,$s3));
+	&mov	($_end,$s0);
+	&mov	($_key,$s3);
+
+	&cmp	($idx,$_out);
+	&je	(&label("dec_in_place"));	# in-place processing...
+
+	&mov	($key,$_ivp);			# load ivp
+	&mov	($_tmp,$key);
+
+	&set_label("dec_loop",4);
+		&mov	($s0,&DWP(0,$idx));	# read input
+		&mov	($s1,&DWP(4,$idx));
+		&mov	($s2,&DWP(8,$idx));
+		&bswap	($s0);
+		&mov	($s3,&DWP(12,$idx));
+		&bswap	($s1);
+		&mov	($key,$_key);		# load key
+		&bswap	($s2);
+		&bswap	($s3);
+
+		&call	("_x86_Camellia_decrypt");
+
+		&mov	($key,$_tmp);		# load ivp
+		&mov	($idx,$_len);		# load len
+
+		&bswap	($s0);
+		&bswap	($s1);
+		&bswap	($s2);
+		&xor	($s0,&DWP(0,$key));	# xor iv
+		&bswap	($s3);
+		&xor	($s1,&DWP(4,$key));
+		&xor	($s2,&DWP(8,$key));
+		&xor	($s3,&DWP(12,$key));
+
+		&sub	($idx,16);
+		&jc	(&label("dec_partial"));
+		&mov	($_len,$idx);		# save len
+		&mov	($idx,$_inp);		# load inp
+		&mov	($key,$_out);		# load out
+
+		&mov	(&DWP(0,$key),$s0);	# write output
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&mov	(&DWP(12,$key),$s3);
+
+		&mov	($_tmp,$idx);		# save ivp
+		&lea	($idx,&DWP(16,$idx));
+		&mov	($_inp,$idx);		# save inp
+
+		&lea	($key,&DWP(16,$key));
+		&mov	($_out,$key);		# save out
+
+	&jnz	(&label("dec_loop"));
+	&mov	($key,$_tmp);		# load temp ivp
+    &set_label("dec_end");
+	&mov	($idx,$_ivp);		# load user ivp
+	&mov	($s0,&DWP(0,$key));	# load iv
+	&mov	($s1,&DWP(4,$key));
+	&mov	($s2,&DWP(8,$key));
+	&mov	($s3,&DWP(12,$key));
+	&mov	(&DWP(0,$idx),$s0);	# copy back to user
+	&mov	(&DWP(4,$idx),$s1);
+	&mov	(&DWP(8,$idx),$s2);
+	&mov	(&DWP(12,$idx),$s3);
+	&jmp	(&label("dec_out"));
+
+    &set_label("dec_partial",4);
+	&lea	($key,$ivec);
+	&mov	(&DWP(0,$key),$s0);	# dump output to stack
+	&mov	(&DWP(4,$key),$s1);
+	&mov	(&DWP(8,$key),$s2);
+	&mov	(&DWP(12,$key),$s3);
+	&lea	($s2 eq "ecx" ? $s2 : "",&DWP(16,$idx));
+	&mov	($idx eq "esi" ? $idx : "",$key);
+	&mov	($key eq "edi" ? $key : "",$_out);	# load out
+	&data_word(0xA4F3F689);	# rep movsb		# copy output
+	&mov	($key,$_inp);				# use inp as temp ivp
+	&jmp	(&label("dec_end"));
+
+    &set_label("dec_in_place",4);
+	&set_label("dec_in_place_loop");
+		&lea	($key,$ivec);
+		&mov	($s0,&DWP(0,$idx));	# read input
+		&mov	($s1,&DWP(4,$idx));
+		&mov	($s2,&DWP(8,$idx));
+		&mov	($s3,&DWP(12,$idx));
+
+		&mov	(&DWP(0,$key),$s0);	# copy to temp
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&bswap	($s0);
+		&mov	(&DWP(12,$key),$s3);
+		&bswap	($s1);
+		&mov	($key,$_key);		# load key
+		&bswap	($s2);
+		&bswap	($s3);
+
+		&call	("_x86_Camellia_decrypt");
+
+		&mov	($key,$_ivp);		# load ivp
+		&mov	($idx,$_out);		# load out
+
+		&bswap	($s0);
+		&bswap	($s1);
+		&bswap	($s2);
+		&xor	($s0,&DWP(0,$key));	# xor iv
+		&bswap	($s3);
+		&xor	($s1,&DWP(4,$key));
+		&xor	($s2,&DWP(8,$key));
+		&xor	($s3,&DWP(12,$key));
+
+		&mov	(&DWP(0,$idx),$s0);	# write output
+		&mov	(&DWP(4,$idx),$s1);
+		&mov	(&DWP(8,$idx),$s2);
+		&mov	(&DWP(12,$idx),$s3);
+
+		&lea	($idx,&DWP(16,$idx));
+		&mov	($_out,$idx);		# save out
+
+		&lea	($idx,$ivec);
+		&mov	($s0,&DWP(0,$idx));	# read temp
+		&mov	($s1,&DWP(4,$idx));
+		&mov	($s2,&DWP(8,$idx));
+		&mov	($s3,&DWP(12,$idx));
+
+		&mov	(&DWP(0,$key),$s0);	# copy iv
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&mov	(&DWP(12,$key),$s3);
+
+		&mov	($idx,$_inp);		# load inp
+
+		&lea	($idx,&DWP(16,$idx));
+		&mov	($_inp,$idx);		# save inp
+
+		&mov	($s2,$_len);		# load len
+		&sub	($s2,16);
+		&jc	(&label("dec_in_place_partial"));
+		&mov	($_len,$s2);		# save len
+	&jnz	(&label("dec_in_place_loop"));
+	&jmp	(&label("dec_out"));
+
+    &set_label("dec_in_place_partial",4);
+	# one can argue if this is actually required...
+	&mov	($key eq "edi" ? $key : "",$_out);
+	&lea	($idx eq "esi" ? $idx : "",$ivec);
+	&lea	($key,&DWP(0,$key,$s2));
+	&lea	($idx,&DWP(16,$idx,$s2));
+	&neg	($s2 eq "ecx" ? $s2 : "");
+	&data_word(0xA4F3F689);	# rep movsb	# restore tail
+
+    &set_label("dec_out",4);
+    &mov	("esp",$_esp);
+    &popf	();
+&function_end("Camellia_cbc_encrypt");
+}
+
+&asciz("Camellia for x86 by <appro\@openssl.org>");
+
+&asm_finish();
diff --git a/openssl/crypto/camellia/asm/cmll-x86_64.pl b/openssl/crypto/camellia/asm/cmll-x86_64.pl
new file mode 100644
index 0000000..76955e4
--- /dev/null
+++ b/openssl/crypto/camellia/asm/cmll-x86_64.pl
@@ -0,0 +1,1080 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Copyright (c) 2008 Andy Polyakov <appro@openssl.org>
+#
+# This module may be used under the terms of either the GNU General
+# Public License version 2 or later, the GNU Lesser General Public
+# License version 2.1 or later, the Mozilla Public License version
+# 1.1 or the BSD License. The exact terms of either license are
+# distributed along with this module. For further details see
+# http://www.openssl.org/~appro/camellia/.
+# ====================================================================
+
+# Performance in cycles per processed byte (less is better) in
+# 'openssl speed ...' benchmark:
+#
+#			AMD64	Core2	EM64T
+# -evp camellia-128-ecb	16.7	21.0	22.7
+# + over gcc 3.4.6	+25%	+5%	0%
+#
+# camellia-128-cbc	15.7	20.4	21.1
+#
+# 128-bit key setup	128	216	205	cycles/key
+# + over gcc 3.4.6	+54%	+39%	+15%
+#
+# Numbers in "+" rows represent performance improvement over compiler
+# generated code. Key setup timings are impressive on AMD and Core2
+# thanks to 64-bit operations being covertly deployed. Improvement on
+# EM64T, pre-Core2 Intel x86_64 CPU, is not as impressive, because it
+# apparently emulates some of 64-bit operations in [32-bit] microcode.
+
+$flavour = shift;
+$output  = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour $output";
+
+sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/;    $r; }
+sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/;
+                        $r =~ s/%[er]([sd]i)/%\1l/;
+                        $r =~ s/%(r[0-9]+)[d]?/%\1b/;   $r; }
+
+$t0="%eax";$t1="%ebx";$t2="%ecx";$t3="%edx";
+@S=("%r8d","%r9d","%r10d","%r11d");
+$i0="%esi";
+$i1="%edi";
+$Tbl="%rbp";	# size optimization
+$inp="%r12";
+$out="%r13";
+$key="%r14";
+$keyend="%r15";
+$arg0d=$win64?"%ecx":"%edi";
+
+# const unsigned int Camellia_SBOX[4][256];
+# Well, sort of... Camellia_SBOX[0][] is interleaved with [1][],
+# and [2][] - with [3][]. This is done to minimize code size.
+$SBOX1_1110=0;		# Camellia_SBOX[0]
+$SBOX4_4404=4;		# Camellia_SBOX[1]
+$SBOX2_0222=2048;	# Camellia_SBOX[2]
+$SBOX3_3033=2052;	# Camellia_SBOX[3]
+
+sub Camellia_Feistel {
+my $i=@_[0];
+my $seed=defined(@_[1])?@_[1]:0;
+my $scale=$seed<0?-8:8;
+my $j=($i&1)*2;
+my $s0=@S[($j)%4],$s1=@S[($j+1)%4],$s2=@S[($j+2)%4],$s3=@S[($j+3)%4];
+
+$code.=<<___;
+	xor	$s0,$t0				# t0^=key[0]
+	xor	$s1,$t1				# t1^=key[1]
+	movz	`&hi("$t0")`,$i0		# (t0>>8)&0xff
+	movz	`&lo("$t1")`,$i1		# (t1>>0)&0xff
+	mov	$SBOX3_3033($Tbl,$i0,8),$t3	# t3=SBOX3_3033[0]
+	mov	$SBOX1_1110($Tbl,$i1,8),$t2	# t2=SBOX1_1110[1]
+	movz	`&lo("$t0")`,$i0		# (t0>>0)&0xff
+	shr	\$16,$t0
+	movz	`&hi("$t1")`,$i1		# (t1>>8)&0xff
+	xor	$SBOX4_4404($Tbl,$i0,8),$t3	# t3^=SBOX4_4404[0]
+	shr	\$16,$t1
+	xor	$SBOX4_4404($Tbl,$i1,8),$t2	# t2^=SBOX4_4404[1]
+	movz	`&hi("$t0")`,$i0		# (t0>>24)&0xff
+	movz	`&lo("$t1")`,$i1		# (t1>>16)&0xff
+	xor	$SBOX1_1110($Tbl,$i0,8),$t3	# t3^=SBOX1_1110[0]
+	xor	$SBOX3_3033($Tbl,$i1,8),$t2	# t2^=SBOX3_3033[1]
+	movz	`&lo("$t0")`,$i0		# (t0>>16)&0xff
+	movz	`&hi("$t1")`,$i1		# (t1>>24)&0xff
+	xor	$SBOX2_0222($Tbl,$i0,8),$t3	# t3^=SBOX2_0222[0]
+	xor	$SBOX2_0222($Tbl,$i1,8),$t2	# t2^=SBOX2_0222[1]
+	mov	`$seed+($i+1)*$scale`($key),$t1	# prefetch key[i+1]
+	mov	`$seed+($i+1)*$scale+4`($key),$t0
+	xor	$t3,$t2				# t2^=t3
+	ror	\$8,$t3				# t3=RightRotate(t3,8)
+	xor	$t2,$s2
+	xor	$t2,$s3
+	xor	$t3,$s3
+___
+}
+
+# void Camellia_EncryptBlock_Rounds(
+#		int grandRounds,
+#		const Byte plaintext[],
+#		const KEY_TABLE_TYPE keyTable,
+#		Byte ciphertext[])
+$code=<<___;
+.text
+
+# V1.x API
+.globl	Camellia_EncryptBlock
+.type	Camellia_EncryptBlock,\@abi-omnipotent
+.align	16
+Camellia_EncryptBlock:
+	movl	\$128,%eax
+	subl	$arg0d,%eax
+	movl	\$3,$arg0d
+	adcl	\$0,$arg0d	# keyBitLength==128?3:4
+	jmp	.Lenc_rounds
+.size	Camellia_EncryptBlock,.-Camellia_EncryptBlock
+# V2
+.globl	Camellia_EncryptBlock_Rounds
+.type	Camellia_EncryptBlock_Rounds,\@function,4
+.align	16
+.Lenc_rounds:
+Camellia_EncryptBlock_Rounds:
+	push	%rbx
+	push	%rbp
+	push	%r13
+	push	%r14
+	push	%r15
+.Lenc_prologue:
+
+	#mov	%rsi,$inp		# put away arguments
+	mov	%rcx,$out
+	mov	%rdx,$key
+
+	shl	\$6,%edi		# process grandRounds
+	lea	.LCamellia_SBOX(%rip),$Tbl
+	lea	($key,%rdi),$keyend
+
+	mov	0(%rsi),@S[0]		# load plaintext
+	mov	4(%rsi),@S[1]
+	mov	8(%rsi),@S[2]
+	bswap	@S[0]
+	mov	12(%rsi),@S[3]
+	bswap	@S[1]
+	bswap	@S[2]
+	bswap	@S[3]
+
+	call	_x86_64_Camellia_encrypt
+
+	bswap	@S[0]
+	bswap	@S[1]
+	bswap	@S[2]
+	mov	@S[0],0($out)
+	bswap	@S[3]
+	mov	@S[1],4($out)
+	mov	@S[2],8($out)
+	mov	@S[3],12($out)
+
+	mov	0(%rsp),%r15
+	mov	8(%rsp),%r14
+	mov	16(%rsp),%r13
+	mov	24(%rsp),%rbp
+	mov	32(%rsp),%rbx
+	lea	40(%rsp),%rsp
+.Lenc_epilogue:
+	ret
+.size	Camellia_EncryptBlock_Rounds,.-Camellia_EncryptBlock_Rounds
+
+.type	_x86_64_Camellia_encrypt,\@abi-omnipotent
+.align	16
+_x86_64_Camellia_encrypt:
+	xor	0($key),@S[1]
+	xor	4($key),@S[0]		# ^=key[0-3]
+	xor	8($key),@S[3]
+	xor	12($key),@S[2]
+.align	16
+.Leloop:
+	mov	16($key),$t1		# prefetch key[4-5]
+	mov	20($key),$t0
+
+___
+	for ($i=0;$i<6;$i++) { Camellia_Feistel($i,16); }
+$code.=<<___;
+	lea	16*4($key),$key
+	cmp	$keyend,$key
+	mov	8($key),$t3		# prefetch key[2-3]
+	mov	12($key),$t2
+	je	.Ledone
+
+	and	@S[0],$t0
+	or	@S[3],$t3
+	rol	\$1,$t0
+	xor	$t3,@S[2]		# s2^=s3|key[3];
+	xor	$t0,@S[1]		# s1^=LeftRotate(s0&key[0],1);
+	and	@S[2],$t2
+	or	@S[1],$t1
+	rol	\$1,$t2
+	xor	$t1,@S[0]		# s0^=s1|key[1];
+	xor	$t2,@S[3]		# s3^=LeftRotate(s2&key[2],1);
+	jmp	.Leloop
+
+.align	16
+.Ledone:
+	xor	@S[2],$t0		# SwapHalf
+	xor	@S[3],$t1
+	xor	@S[0],$t2
+	xor	@S[1],$t3
+
+	mov	$t0,@S[0]
+	mov	$t1,@S[1]
+	mov	$t2,@S[2]
+	mov	$t3,@S[3]
+
+	.byte	0xf3,0xc3		# rep ret
+.size	_x86_64_Camellia_encrypt,.-_x86_64_Camellia_encrypt
+
+# V1.x API
+.globl	Camellia_DecryptBlock
+.type	Camellia_DecryptBlock,\@abi-omnipotent
+.align	16
+Camellia_DecryptBlock:
+	movl	\$128,%eax
+	subl	$arg0d,%eax
+	movl	\$3,$arg0d
+	adcl	\$0,$arg0d	# keyBitLength==128?3:4
+	jmp	.Ldec_rounds
+.size	Camellia_DecryptBlock,.-Camellia_DecryptBlock
+# V2
+.globl	Camellia_DecryptBlock_Rounds
+.type	Camellia_DecryptBlock_Rounds,\@function,4
+.align	16
+.Ldec_rounds:
+Camellia_DecryptBlock_Rounds:
+	push	%rbx
+	push	%rbp
+	push	%r13
+	push	%r14
+	push	%r15
+.Ldec_prologue:
+
+	#mov	%rsi,$inp		# put away arguments
+	mov	%rcx,$out
+	mov	%rdx,$keyend
+
+	shl	\$6,%edi		# process grandRounds
+	lea	.LCamellia_SBOX(%rip),$Tbl
+	lea	($keyend,%rdi),$key
+
+	mov	0(%rsi),@S[0]		# load plaintext
+	mov	4(%rsi),@S[1]
+	mov	8(%rsi),@S[2]
+	bswap	@S[0]
+	mov	12(%rsi),@S[3]
+	bswap	@S[1]
+	bswap	@S[2]
+	bswap	@S[3]
+
+	call	_x86_64_Camellia_decrypt
+
+	bswap	@S[0]
+	bswap	@S[1]
+	bswap	@S[2]
+	mov	@S[0],0($out)
+	bswap	@S[3]
+	mov	@S[1],4($out)
+	mov	@S[2],8($out)
+	mov	@S[3],12($out)
+
+	mov	0(%rsp),%r15
+	mov	8(%rsp),%r14
+	mov	16(%rsp),%r13
+	mov	24(%rsp),%rbp
+	mov	32(%rsp),%rbx
+	lea	40(%rsp),%rsp
+.Ldec_epilogue:
+	ret
+.size	Camellia_DecryptBlock_Rounds,.-Camellia_DecryptBlock_Rounds
+
+.type	_x86_64_Camellia_decrypt,\@abi-omnipotent
+.align	16
+_x86_64_Camellia_decrypt:
+	xor	0($key),@S[1]
+	xor	4($key),@S[0]		# ^=key[0-3]
+	xor	8($key),@S[3]
+	xor	12($key),@S[2]
+.align	16
+.Ldloop:
+	mov	-8($key),$t1		# prefetch key[4-5]
+	mov	-4($key),$t0
+
+___
+	for ($i=0;$i<6;$i++) { Camellia_Feistel($i,-8); }
+$code.=<<___;
+	lea	-16*4($key),$key
+	cmp	$keyend,$key
+	mov	0($key),$t3		# prefetch key[2-3]
+	mov	4($key),$t2
+	je	.Lddone
+
+	and	@S[0],$t0
+	or	@S[3],$t3
+	rol	\$1,$t0
+	xor	$t3,@S[2]		# s2^=s3|key[3];
+	xor	$t0,@S[1]		# s1^=LeftRotate(s0&key[0],1);
+	and	@S[2],$t2
+	or	@S[1],$t1
+	rol	\$1,$t2
+	xor	$t1,@S[0]		# s0^=s1|key[1];
+	xor	$t2,@S[3]		# s3^=LeftRotate(s2&key[2],1);
+
+	jmp	.Ldloop
+
+.align	16
+.Lddone:
+	xor	@S[2],$t2
+	xor	@S[3],$t3
+	xor	@S[0],$t0
+	xor	@S[1],$t1
+
+	mov	$t2,@S[0]		# SwapHalf
+	mov	$t3,@S[1]
+	mov	$t0,@S[2]
+	mov	$t1,@S[3]
+
+	.byte	0xf3,0xc3		# rep ret
+.size	_x86_64_Camellia_decrypt,.-_x86_64_Camellia_decrypt
+___
+
+sub _saveround {
+my ($rnd,$key,@T)=@_;
+my $bias=int(@T[0])?shift(@T):0;
+
+    if ($#T==3) {
+	$code.=<<___;
+	mov	@T[1],`$bias+$rnd*8+0`($key)
+	mov	@T[0],`$bias+$rnd*8+4`($key)
+	mov	@T[3],`$bias+$rnd*8+8`($key)
+	mov	@T[2],`$bias+$rnd*8+12`($key)
+___
+    } else {
+	$code.="	mov	@T[0],`$bias+$rnd*8+0`($key)\n";
+	$code.="	mov	@T[1],`$bias+$rnd*8+8`($key)\n"	if ($#T>=1);
+    }
+}
+
+sub _loadround {
+my ($rnd,$key,@T)=@_;
+my $bias=int(@T[0])?shift(@T):0;
+
+$code.="	mov	`$bias+$rnd*8+0`($key),@T[0]\n";
+$code.="	mov	`$bias+$rnd*8+8`($key),@T[1]\n"	if ($#T>=1);
+}
+
+# shld is very slow on Intel EM64T family. Even on AMD it limits
+# instruction decode rate [because it's VectorPath] and consequently
+# performance...
+sub __rotl128 {
+my ($i0,$i1,$rot)=@_;
+
+    if ($rot) {
+	$code.=<<___;
+	mov	$i0,%r11
+	shld	\$$rot,$i1,$i0
+	shld	\$$rot,%r11,$i1
+___
+    }
+}
+
+# ... Implementing 128-bit rotate without shld gives 80% better
+# performance EM64T, +15% on AMD64 and only ~7% degradation on
+# Core2. This is therefore preferred.
+sub _rotl128 {
+my ($i0,$i1,$rot)=@_;
+
+    if ($rot) {
+	$code.=<<___;
+	mov	$i0,%r11
+	shl	\$$rot,$i0
+	mov	$i1,%r9
+	shr	\$`64-$rot`,%r9
+	shr	\$`64-$rot`,%r11
+	or	%r9,$i0
+	shl	\$$rot,$i1
+	or	%r11,$i1
+___
+    }
+}
+
+{ my $step=0;
+
+$code.=<<___;
+.globl	Camellia_Ekeygen
+.type	Camellia_Ekeygen,\@function,3
+.align	16
+Camellia_Ekeygen:
+	push	%rbx
+	push	%rbp
+	push	%r13
+	push	%r14
+	push	%r15
+.Lkey_prologue:
+
+	mov	%rdi,$keyend		# put away arguments, keyBitLength
+	mov	%rdx,$out		# keyTable
+
+	mov	0(%rsi),@S[0]		# load 0-127 bits
+	mov	4(%rsi),@S[1]
+	mov	8(%rsi),@S[2]
+	mov	12(%rsi),@S[3]
+
+	bswap	@S[0]
+	bswap	@S[1]
+	bswap	@S[2]
+	bswap	@S[3]
+___
+	&_saveround	(0,$out,@S);	# KL<<<0
+$code.=<<___;
+	cmp	\$128,$keyend		# check keyBitLength
+	je	.L1st128
+
+	mov	16(%rsi),@S[0]		# load 128-191 bits
+	mov	20(%rsi),@S[1]
+	cmp	\$192,$keyend
+	je	.L1st192
+	mov	24(%rsi),@S[2]		# load 192-255 bits
+	mov	28(%rsi),@S[3]
+	jmp	.L1st256
+.L1st192:
+	mov	@S[0],@S[2]
+	mov	@S[1],@S[3]
+	not	@S[2]
+	not	@S[3]
+.L1st256:
+	bswap	@S[0]
+	bswap	@S[1]
+	bswap	@S[2]
+	bswap	@S[3]
+___
+	&_saveround	(4,$out,@S);	# temp storage for KR!
+$code.=<<___;
+	xor	0($out),@S[1]		# KR^KL
+	xor	4($out),@S[0]
+	xor	8($out),@S[3]
+	xor	12($out),@S[2]
+
+.L1st128:
+	lea	.LCamellia_SIGMA(%rip),$key
+	lea	.LCamellia_SBOX(%rip),$Tbl
+
+	mov	0($key),$t1
+	mov	4($key),$t0
+___
+	&Camellia_Feistel($step++);
+	&Camellia_Feistel($step++);
+$code.=<<___;
+	xor	0($out),@S[1]		# ^KL
+	xor	4($out),@S[0]
+	xor	8($out),@S[3]
+	xor	12($out),@S[2]
+___
+	&Camellia_Feistel($step++);
+	&Camellia_Feistel($step++);
+$code.=<<___;
+	cmp	\$128,$keyend
+	jne	.L2nd256
+
+	lea	128($out),$out		# size optimization
+	shl	\$32,%r8		# @S[0]||
+	shl	\$32,%r10		# @S[2]||
+	or	%r9,%r8			# ||@S[1]
+	or	%r11,%r10		# ||@S[3]
+___
+	&_loadround	(0,$out,-128,"%rax","%rbx");	# KL
+	&_saveround	(2,$out,-128,"%r8","%r10");	# KA<<<0
+	&_rotl128	("%rax","%rbx",15);
+	&_saveround	(4,$out,-128,"%rax","%rbx");	# KL<<<15
+	&_rotl128	("%r8","%r10",15);
+	&_saveround	(6,$out,-128,"%r8","%r10");	# KA<<<15
+	&_rotl128	("%r8","%r10",15);		# 15+15=30
+	&_saveround	(8,$out,-128,"%r8","%r10");	# KA<<<30
+	&_rotl128	("%rax","%rbx",30);		# 15+30=45
+	&_saveround	(10,$out,-128,"%rax","%rbx");	# KL<<<45
+	&_rotl128	("%r8","%r10",15);		# 30+15=45
+	&_saveround	(12,$out,-128,"%r8");		# KA<<<45
+	&_rotl128	("%rax","%rbx",15);		# 45+15=60
+	&_saveround	(13,$out,-128,"%rbx");		# KL<<<60
+	&_rotl128	("%r8","%r10",15);		# 45+15=60
+	&_saveround	(14,$out,-128,"%r8","%r10");	# KA<<<60
+	&_rotl128	("%rax","%rbx",17);		# 60+17=77
+	&_saveround	(16,$out,-128,"%rax","%rbx");	# KL<<<77
+	&_rotl128	("%rax","%rbx",17);		# 77+17=94
+	&_saveround	(18,$out,-128,"%rax","%rbx");	# KL<<<94
+	&_rotl128	("%r8","%r10",34);		# 60+34=94
+	&_saveround	(20,$out,-128,"%r8","%r10");	# KA<<<94
+	&_rotl128	("%rax","%rbx",17);		# 94+17=111
+	&_saveround	(22,$out,-128,"%rax","%rbx");	# KL<<<111
+	&_rotl128	("%r8","%r10",17);		# 94+17=111
+	&_saveround	(24,$out,-128,"%r8","%r10");	# KA<<<111
+$code.=<<___;
+	mov	\$3,%eax
+	jmp	.Ldone
+.align	16
+.L2nd256:
+___
+	&_saveround	(6,$out,@S);	# temp storage for KA!
+$code.=<<___;
+	xor	`4*8+0`($out),@S[1]	# KA^KR
+	xor	`4*8+4`($out),@S[0]
+	xor	`5*8+0`($out),@S[3]
+	xor	`5*8+4`($out),@S[2]
+___
+	&Camellia_Feistel($step++);
+	&Camellia_Feistel($step++);
+
+	&_loadround	(0,$out,"%rax","%rbx");	# KL
+	&_loadround	(4,$out,"%rcx","%rdx");	# KR
+	&_loadround	(6,$out,"%r14","%r15");	# KA
+$code.=<<___;
+	lea	128($out),$out		# size optimization
+	shl	\$32,%r8		# @S[0]||
+	shl	\$32,%r10		# @S[2]||
+	or	%r9,%r8			# ||@S[1]
+	or	%r11,%r10		# ||@S[3]
+___
+	&_saveround	(2,$out,-128,"%r8","%r10");	# KB<<<0
+	&_rotl128	("%rcx","%rdx",15);
+	&_saveround	(4,$out,-128,"%rcx","%rdx");	# KR<<<15
+	&_rotl128	("%r14","%r15",15);
+	&_saveround	(6,$out,-128,"%r14","%r15");	# KA<<<15
+	&_rotl128	("%rcx","%rdx",15);		# 15+15=30
+	&_saveround	(8,$out,-128,"%rcx","%rdx");	# KR<<<30
+	&_rotl128	("%r8","%r10",30);
+	&_saveround	(10,$out,-128,"%r8","%r10");	# KB<<<30
+	&_rotl128	("%rax","%rbx",45);
+	&_saveround	(12,$out,-128,"%rax","%rbx");	# KL<<<45
+	&_rotl128	("%r14","%r15",30);		# 15+30=45
+	&_saveround	(14,$out,-128,"%r14","%r15");	# KA<<<45
+	&_rotl128	("%rax","%rbx",15);		# 45+15=60
+	&_saveround	(16,$out,-128,"%rax","%rbx");	# KL<<<60
+	&_rotl128	("%rcx","%rdx",30);		# 30+30=60
+	&_saveround	(18,$out,-128,"%rcx","%rdx");	# KR<<<60
+	&_rotl128	("%r8","%r10",30);		# 30+30=60
+	&_saveround	(20,$out,-128,"%r8","%r10");	# KB<<<60
+	&_rotl128	("%rax","%rbx",17);		# 60+17=77
+	&_saveround	(22,$out,-128,"%rax","%rbx");	# KL<<<77
+	&_rotl128	("%r14","%r15",32);		# 45+32=77
+	&_saveround	(24,$out,-128,"%r14","%r15");	# KA<<<77
+	&_rotl128	("%rcx","%rdx",34);		# 60+34=94
+	&_saveround	(26,$out,-128,"%rcx","%rdx");	# KR<<<94
+	&_rotl128	("%r14","%r15",17);		# 77+17=94
+	&_saveround	(28,$out,-128,"%r14","%r15");	# KA<<<77
+	&_rotl128	("%rax","%rbx",34);		# 77+34=111
+	&_saveround	(30,$out,-128,"%rax","%rbx");	# KL<<<111
+	&_rotl128	("%r8","%r10",51);		# 60+51=111
+	&_saveround	(32,$out,-128,"%r8","%r10");	# KB<<<111
+$code.=<<___;
+	mov	\$4,%eax
+.Ldone:
+	mov	0(%rsp),%r15
+	mov	8(%rsp),%r14
+	mov	16(%rsp),%r13
+	mov	24(%rsp),%rbp
+	mov	32(%rsp),%rbx
+	lea	40(%rsp),%rsp
+.Lkey_epilogue:
+	ret
+.size	Camellia_Ekeygen,.-Camellia_Ekeygen
+___
+}
+
+@SBOX=(
+112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
+ 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
+134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
+166,225, 57,202,213, 71, 93, 61,217,  1, 90,214, 81, 86,108, 77,
+139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
+223, 76,203,194, 52,126,118,  5,109,183,169, 49,209, 23,  4,215,
+ 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
+254, 68,207,178,195,181,122,145, 36,  8,232,168, 96,252,105, 80,
+170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
+ 16,196,  0, 72,163,247,117,219,138,  3,230,218,  9, 63,221,148,
+135, 92,131,  2,205, 74,144, 51,115,103,246,243,157,127,191,226,
+ 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
+233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
+120,152,  6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
+114,  7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
+ 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158);
+
+sub S1110 { my $i=shift; $i=@SBOX[$i]; $i=$i<<24|$i<<16|$i<<8; sprintf("0x%08x",$i); }
+sub S4404 { my $i=shift; $i=($i<<1|$i>>7)&0xff; $i=@SBOX[$i]; $i=$i<<24|$i<<16|$i; sprintf("0x%08x",$i); }
+sub S0222 { my $i=shift; $i=@SBOX[$i]; $i=($i<<1|$i>>7)&0xff; $i=$i<<16|$i<<8|$i; sprintf("0x%08x",$i); }
+sub S3033 { my $i=shift; $i=@SBOX[$i]; $i=($i>>1|$i<<7)&0xff; $i=$i<<24|$i<<8|$i; sprintf("0x%08x",$i); }
+
+$code.=<<___;
+.align	64
+.LCamellia_SIGMA:
+.long	0x3bcc908b, 0xa09e667f, 0x4caa73b2, 0xb67ae858
+.long	0xe94f82be, 0xc6ef372f, 0xf1d36f1c, 0x54ff53a5
+.long	0xde682d1d, 0x10e527fa, 0xb3e6c1fd, 0xb05688c2
+.long	0,          0,          0,          0
+.LCamellia_SBOX:
+___
+# tables are interleaved, remember?
+sub data_word { $code.=".long\t".join(',',@_)."\n"; }
+for ($i=0;$i<256;$i++) { &data_word(&S1110($i),&S4404($i)); }
+for ($i=0;$i<256;$i++) { &data_word(&S0222($i),&S3033($i)); }
+
+# void Camellia_cbc_encrypt (const void char *inp, unsigned char *out,
+#			size_t length, const CAMELLIA_KEY *key,
+#			unsigned char *ivp,const int enc);
+{
+$_key="0(%rsp)";
+$_end="8(%rsp)";	# inp+len&~15
+$_res="16(%rsp)";	# len&15
+$ivec="24(%rsp)";
+$_ivp="40(%rsp)";
+$_rsp="48(%rsp)";
+
+$code.=<<___;
+.globl	Camellia_cbc_encrypt
+.type	Camellia_cbc_encrypt,\@function,6
+.align	16
+Camellia_cbc_encrypt:
+	cmp	\$0,%rdx
+	je	.Lcbc_abort
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+.Lcbc_prologue:
+
+	mov	%rsp,%rbp
+	sub	\$64,%rsp
+	and	\$-64,%rsp
+
+	# place stack frame just "above mod 1024" the key schedule,
+	# this ensures that cache associativity suffices
+	lea	-64-63(%rcx),%r10
+	sub	%rsp,%r10
+	neg	%r10
+	and	\$0x3C0,%r10
+	sub	%r10,%rsp
+	#add	\$8,%rsp		# 8 is reserved for callee's ra
+
+	mov	%rdi,$inp		# inp argument
+	mov	%rsi,$out		# out argument
+	mov	%r8,%rbx		# ivp argument
+	mov	%rcx,$key		# key argument
+	mov	272(%rcx),${keyend}d	# grandRounds
+
+	mov	%r8,$_ivp
+	mov	%rbp,$_rsp
+
+.Lcbc_body:
+	lea	.LCamellia_SBOX(%rip),$Tbl
+
+	mov	\$32,%ecx
+.align	4
+.Lcbc_prefetch_sbox:
+	mov	0($Tbl),%rax
+	mov	32($Tbl),%rsi
+	mov	64($Tbl),%rdi
+	mov	96($Tbl),%r11
+	lea	128($Tbl),$Tbl
+	loop	.Lcbc_prefetch_sbox
+	sub	\$4096,$Tbl
+	shl	\$6,$keyend
+	mov	%rdx,%rcx		# len argument
+	lea	($key,$keyend),$keyend
+
+	cmp	\$0,%r9d		# enc argument
+	je	.LCBC_DECRYPT
+
+	and	\$-16,%rdx
+	and	\$15,%rcx		# length residue
+	lea	($inp,%rdx),%rdx
+	mov	$key,$_key
+	mov	%rdx,$_end
+	mov	%rcx,$_res
+
+	cmp	$inp,%rdx
+	mov	0(%rbx),@S[0]		# load IV
+	mov	4(%rbx),@S[1]
+	mov	8(%rbx),@S[2]
+	mov	12(%rbx),@S[3]
+	je	.Lcbc_enc_tail
+	jmp	.Lcbc_eloop
+
+.align	16
+.Lcbc_eloop:
+	xor	0($inp),@S[0]
+	xor	4($inp),@S[1]
+	xor	8($inp),@S[2]
+	bswap	@S[0]
+	xor	12($inp),@S[3]
+	bswap	@S[1]
+	bswap	@S[2]
+	bswap	@S[3]
+
+	call	_x86_64_Camellia_encrypt
+
+	mov	$_key,$key		# "rewind" the key
+	bswap	@S[0]
+	mov	$_end,%rdx
+	bswap	@S[1]
+	mov	$_res,%rcx
+	bswap	@S[2]
+	mov	@S[0],0($out)
+	bswap	@S[3]
+	mov	@S[1],4($out)
+	mov	@S[2],8($out)
+	lea	16($inp),$inp
+	mov	@S[3],12($out)
+	cmp	%rdx,$inp
+	lea	16($out),$out
+	jne	.Lcbc_eloop
+
+	cmp	\$0,%rcx
+	jne	.Lcbc_enc_tail
+
+	mov	$_ivp,$out
+	mov	@S[0],0($out)		# write out IV residue
+	mov	@S[1],4($out)
+	mov	@S[2],8($out)
+	mov	@S[3],12($out)
+	jmp	.Lcbc_done
+
+.align	16
+.Lcbc_enc_tail:
+	xor	%rax,%rax
+	mov	%rax,0+$ivec
+	mov	%rax,8+$ivec
+	mov	%rax,$_res
+
+.Lcbc_enc_pushf:
+	pushfq
+	cld
+	mov	$inp,%rsi
+	lea	8+$ivec,%rdi
+	.long	0x9066A4F3		# rep movsb
+	popfq
+.Lcbc_enc_popf:
+
+	lea	$ivec,$inp
+	lea	16+$ivec,%rax
+	mov	%rax,$_end
+	jmp	.Lcbc_eloop		# one more time
+
+.align	16
+.LCBC_DECRYPT:
+	xchg	$key,$keyend
+	add	\$15,%rdx
+	and	\$15,%rcx		# length residue
+	and	\$-16,%rdx
+	mov	$key,$_key
+	lea	($inp,%rdx),%rdx
+	mov	%rdx,$_end
+	mov	%rcx,$_res
+
+	mov	(%rbx),%rax		# load IV
+	mov	8(%rbx),%rbx
+	jmp	.Lcbc_dloop
+.align	16
+.Lcbc_dloop:
+	mov	0($inp),@S[0]
+	mov	4($inp),@S[1]
+	mov	8($inp),@S[2]
+	bswap	@S[0]
+	mov	12($inp),@S[3]
+	bswap	@S[1]
+	mov	%rax,0+$ivec		# save IV to temporary storage
+	bswap	@S[2]
+	mov	%rbx,8+$ivec
+	bswap	@S[3]
+
+	call	_x86_64_Camellia_decrypt
+
+	mov	$_key,$key		# "rewind" the key
+	mov	$_end,%rdx
+	mov	$_res,%rcx
+
+	bswap	@S[0]
+	mov	($inp),%rax		# load IV for next iteration
+	bswap	@S[1]
+	mov	8($inp),%rbx
+	bswap	@S[2]
+	xor	0+$ivec,@S[0]
+	bswap	@S[3]
+	xor	4+$ivec,@S[1]
+	xor	8+$ivec,@S[2]
+	lea	16($inp),$inp
+	xor	12+$ivec,@S[3]
+	cmp	%rdx,$inp
+	je	.Lcbc_ddone
+
+	mov	@S[0],0($out)
+	mov	@S[1],4($out)
+	mov	@S[2],8($out)
+	mov	@S[3],12($out)
+
+	lea	16($out),$out
+	jmp	.Lcbc_dloop
+
+.align	16
+.Lcbc_ddone:
+	mov	$_ivp,%rdx
+	cmp	\$0,%rcx
+	jne	.Lcbc_dec_tail
+
+	mov	@S[0],0($out)
+	mov	@S[1],4($out)
+	mov	@S[2],8($out)
+	mov	@S[3],12($out)
+
+	mov	%rax,(%rdx)		# write out IV residue
+	mov	%rbx,8(%rdx)
+	jmp	.Lcbc_done
+.align	16
+.Lcbc_dec_tail:
+	mov	@S[0],0+$ivec
+	mov	@S[1],4+$ivec
+	mov	@S[2],8+$ivec
+	mov	@S[3],12+$ivec
+
+.Lcbc_dec_pushf:
+	pushfq
+	cld
+	lea	8+$ivec,%rsi
+	lea	($out),%rdi
+	.long	0x9066A4F3		# rep movsb
+	popfq
+.Lcbc_dec_popf:
+
+	mov	%rax,(%rdx)		# write out IV residue
+	mov	%rbx,8(%rdx)
+	jmp	.Lcbc_done
+
+.align	16
+.Lcbc_done:
+	mov	$_rsp,%rcx
+	mov	0(%rcx),%r15
+	mov	8(%rcx),%r14
+	mov	16(%rcx),%r13
+	mov	24(%rcx),%r12
+	mov	32(%rcx),%rbp
+	mov	40(%rcx),%rbx
+	lea	48(%rcx),%rsp
+.Lcbc_abort:
+	ret
+.size	Camellia_cbc_encrypt,.-Camellia_cbc_encrypt
+
+.asciz	"Camellia for x86_64 by <appro\@openssl.org>"
+___
+}
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern	__imp_RtlVirtualUnwind
+.type	common_se_handler,\@abi-omnipotent
+.align	16
+common_se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	lea	-64(%rsp),%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	mov	8($disp),%rsi		# disp->ImageBase
+	mov	56($disp),%r11		# disp->HandlerData
+
+	mov	0(%r11),%r10d		# HandlerData[0]
+	lea	(%rsi,%r10),%r10	# prologue label
+	cmp	%r10,%rbx		# context->Rip<prologue label
+	jb	.Lin_prologue
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	mov	4(%r11),%r10d		# HandlerData[1]
+	lea	(%rsi,%r10),%r10	# epilogue label
+	cmp	%r10,%rbx		# context->Rip>=epilogue label
+	jae	.Lin_prologue
+
+	lea	40(%rax),%rax
+	mov	-8(%rax),%rbx
+	mov	-16(%rax),%rbp
+	mov	-24(%rax),%r13
+	mov	-32(%rax),%r14
+	mov	-40(%rax),%r15
+	mov	%rbx,144($context)	# restore context->Rbx
+	mov	%rbp,160($context)	# restore context->Rbp
+	mov	%r13,224($context)	# restore context->R13
+	mov	%r14,232($context)	# restore context->R14
+	mov	%r15,240($context)	# restore context->R15
+
+.Lin_prologue:
+	mov	8(%rax),%rdi
+	mov	16(%rax),%rsi
+	mov	%rax,152($context)	# restore context->Rsp
+	mov	%rsi,168($context)	# restore context->Rsi
+	mov	%rdi,176($context)	# restore context->Rdi
+
+	jmp	.Lcommon_seh_exit
+.size	common_se_handler,.-common_se_handler
+
+.type	cbc_se_handler,\@abi-omnipotent
+.align	16
+cbc_se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	lea	-64(%rsp),%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	lea	.Lcbc_prologue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lcbc_prologue
+	jb	.Lin_cbc_prologue
+
+	lea	.Lcbc_body(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lcbc_body
+	jb	.Lin_cbc_frame_setup
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	lea	.Lcbc_abort(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip>=.Lcbc_abort
+	jae	.Lin_cbc_prologue
+
+	# handle pushf/popf in Camellia_cbc_encrypt
+	lea	.Lcbc_enc_pushf(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<=.Lcbc_enc_pushf
+	jbe	.Lin_cbc_no_flag
+	lea	8(%rax),%rax
+	lea	.Lcbc_enc_popf(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lcbc_enc_popf
+	jb	.Lin_cbc_no_flag
+	lea	-8(%rax),%rax
+	lea	.Lcbc_dec_pushf(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<=.Lcbc_dec_pushf
+	jbe	.Lin_cbc_no_flag
+	lea	8(%rax),%rax
+	lea	.Lcbc_dec_popf(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lcbc_dec_popf
+	jb	.Lin_cbc_no_flag
+	lea	-8(%rax),%rax
+
+.Lin_cbc_no_flag:
+	mov	48(%rax),%rax		# $_rsp
+	lea	48(%rax),%rax
+
+.Lin_cbc_frame_setup:
+	mov	-8(%rax),%rbx
+	mov	-16(%rax),%rbp
+	mov	-24(%rax),%r12
+	mov	-32(%rax),%r13
+	mov	-40(%rax),%r14
+	mov	-48(%rax),%r15
+	mov	%rbx,144($context)	# restore context->Rbx
+	mov	%rbp,160($context)	# restore context->Rbp
+	mov	%r12,216($context)	# restore context->R12
+	mov	%r13,224($context)	# restore context->R13
+	mov	%r14,232($context)	# restore context->R14
+	mov	%r15,240($context)	# restore context->R15
+
+.Lin_cbc_prologue:
+	mov	8(%rax),%rdi
+	mov	16(%rax),%rsi
+	mov	%rax,152($context)	# restore context->Rsp
+	mov	%rsi,168($context)	# restore context->Rsi
+	mov	%rdi,176($context)	# restore context->Rdi
+
+.align	4
+.Lcommon_seh_exit:
+
+	mov	40($disp),%rdi		# disp->ContextRecord
+	mov	$context,%rsi		# context
+	mov	\$`1232/8`,%ecx		# sizeof(CONTEXT)
+	.long	0xa548f3fc		# cld; rep movsq
+
+	mov	$disp,%rsi
+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
+	mov	40(%rsi),%r10		# disp->ContextRecord
+	lea	56(%rsi),%r11		# &disp->HandlerData
+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
+	mov	%r10,32(%rsp)		# arg5
+	mov	%r11,40(%rsp)		# arg6
+	mov	%r12,48(%rsp)		# arg7
+	mov	%rcx,56(%rsp)		# arg8, (NULL)
+	call	*__imp_RtlVirtualUnwind(%rip)
+
+	mov	\$1,%eax		# ExceptionContinueSearch
+	lea	64(%rsp),%rsp
+	popfq
+	pop	%r15
+	pop	%r14
+	pop	%r13
+	pop	%r12
+	pop	%rbp
+	pop	%rbx
+	pop	%rdi
+	pop	%rsi
+	ret
+.size	cbc_se_handler,.-cbc_se_handler
+
+.section	.pdata
+.align	4
+	.rva	.LSEH_begin_Camellia_EncryptBlock_Rounds
+	.rva	.LSEH_end_Camellia_EncryptBlock_Rounds
+	.rva	.LSEH_info_Camellia_EncryptBlock_Rounds
+
+	.rva	.LSEH_begin_Camellia_DecryptBlock_Rounds
+	.rva	.LSEH_end_Camellia_DecryptBlock_Rounds
+	.rva	.LSEH_info_Camellia_DecryptBlock_Rounds
+
+	.rva	.LSEH_begin_Camellia_Ekeygen
+	.rva	.LSEH_end_Camellia_Ekeygen
+	.rva	.LSEH_info_Camellia_Ekeygen
+
+	.rva	.LSEH_begin_Camellia_cbc_encrypt
+	.rva	.LSEH_end_Camellia_cbc_encrypt
+	.rva	.LSEH_info_Camellia_cbc_encrypt
+
+.section	.xdata
+.align	8
+.LSEH_info_Camellia_EncryptBlock_Rounds:
+	.byte	9,0,0,0
+	.rva	common_se_handler
+	.rva	.Lenc_prologue,.Lenc_epilogue	# HandlerData[]
+.LSEH_info_Camellia_DecryptBlock_Rounds:
+	.byte	9,0,0,0
+	.rva	common_se_handler
+	.rva	.Ldec_prologue,.Ldec_epilogue	# HandlerData[]
+.LSEH_info_Camellia_Ekeygen:
+	.byte	9,0,0,0
+	.rva	common_se_handler
+	.rva	.Lkey_prologue,.Lkey_epilogue	# HandlerData[]
+.LSEH_info_Camellia_cbc_encrypt:
+	.byte	9,0,0,0
+	.rva	cbc_se_handler
+___
+}
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/camellia/camellia.c b/openssl/crypto/camellia/camellia.c
new file mode 100644
index 0000000..75fc899
--- /dev/null
+++ b/openssl/crypto/camellia/camellia.c
@@ -0,0 +1,582 @@
+/* crypto/camellia/camellia.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . 
+ * ALL RIGHTS RESERVED.
+ *
+ * Intellectual Property information for Camellia:
+ *     http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
+ *
+ * News Release for Announcement of Camellia open source:
+ *     http://www.ntt.co.jp/news/news06e/0604/060413a.html
+ *
+ * The Camellia Code included herein is developed by
+ * NTT (Nippon Telegraph and Telephone Corporation), and is contributed
+ * to the OpenSSL project.
+ *
+ * The Camellia Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+/* Algorithm Specification 
+   http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+*/
+ 
+/*
+ * This release balances code size and performance. In particular key
+ * schedule setup is fully unrolled, because doing so *significantly*
+ * reduces amount of instructions per setup round and code increase is
+ * justifiable. In block functions on the other hand only inner loops
+ * are unrolled, as full unroll gives only nominal performance boost,
+ * while code size grows 4 or 7 times. Also, unlike previous versions
+ * this one "encourages" compiler to keep intermediate variables in
+ * registers, which should give better "all round" results, in other
+ * words reasonable performance even with not so modern compilers.
+ */
+
+#include "camellia.h"
+#include "cmll_locl.h"
+#include <string.h>
+#include <stdlib.h>
+
+/* 32-bit rotations */
+#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+# if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
+#  define RightRotate(x, s) _lrotr(x, s)
+#  define LeftRotate(x, s)  _lrotl(x, s)
+#  if _MSC_VER >= 1400
+#   define SWAP(x) _byteswap_ulong(x)
+#  else
+#   define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+#  endif
+#  define GETU32(p)   SWAP(*((u32 *)(p)))
+#  define PUTU32(p,v) (*((u32 *)(p)) = SWAP((v)))
+# elif defined(__GNUC__) && __GNUC__>=2
+#  if defined(__i386) || defined(__x86_64)
+#   define RightRotate(x,s) ({u32 ret; asm ("rorl %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; })
+#   define LeftRotate(x,s)  ({u32 ret; asm ("roll %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; })
+#   if defined(B_ENDIAN) /* stratus.com does it */
+#    define GETU32(p)   (*(u32 *)(p))
+#    define PUTU32(p,v) (*(u32 *)(p)=(v))
+#   else
+#    define GETU32(p)   ({u32 r=*(const u32 *)(p); asm("bswapl %0":"=r"(r):"0"(r)); r; })
+#    define PUTU32(p,v) ({u32 r=(v); asm("bswapl %0":"=r"(r):"0"(r)); *(u32 *)(p)=r; })
+#   endif
+#  elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
+        defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
+#   define LeftRotate(x,s)  ({u32 ret; asm ("rlwinm %0,%1,%2,0,31":"=r"(ret):"r"(x),"I"(s)); ret; })
+#   define RightRotate(x,s) LeftRotate(x,(32-s))
+#  elif defined(__s390x__)
+#   define LeftRotate(x,s)  ({u32 ret; asm ("rll %0,%1,%2":"=r"(ret):"r"(x),"I"(s)); ret; })
+#   define RightRotate(x,s) LeftRotate(x,(32-s))
+#   define GETU32(p)   (*(u32 *)(p))
+#   define PUTU32(p,v) (*(u32 *)(p)=(v))
+#  endif
+# endif
+#endif
+
+#if !defined(RightRotate) && !defined(LeftRotate)
+# define RightRotate(x, s) ( ((x) >> (s)) + ((x) << (32 - s)) )
+# define LeftRotate(x, s)  ( ((x) << (s)) + ((x) >> (32 - s)) )
+#endif
+
+#if !defined(GETU32) && !defined(PUTU32)
+# define GETU32(p)   (((u32)(p)[0] << 24) ^ ((u32)(p)[1] << 16) ^ ((u32)(p)[2] <<  8) ^ ((u32)(p)[3]))
+# define PUTU32(p,v) ((p)[0] = (u8)((v) >> 24), (p)[1] = (u8)((v) >> 16), (p)[2] = (u8)((v) >>  8), (p)[3] = (u8)(v))
+#endif
+
+/* S-box data */
+#define SBOX1_1110 Camellia_SBOX[0]
+#define SBOX4_4404 Camellia_SBOX[1]
+#define SBOX2_0222 Camellia_SBOX[2]
+#define SBOX3_3033 Camellia_SBOX[3]
+static const u32 Camellia_SBOX[][256] = {
+{   0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, 
+    0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, 
+    0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00, 
+    0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, 
+    0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, 
+    0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, 
+    0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000, 
+    0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, 
+    0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, 
+    0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, 
+    0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00, 
+    0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, 
+    0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, 
+    0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, 
+    0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700, 
+    0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, 
+    0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, 
+    0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, 
+    0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400, 
+    0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, 
+    0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, 
+    0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, 
+    0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00, 
+    0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, 
+    0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, 
+    0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, 
+    0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00, 
+    0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, 
+    0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, 
+    0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, 
+    0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600, 
+    0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, 
+    0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, 
+    0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, 
+    0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800, 
+    0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, 
+    0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, 
+    0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, 
+    0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900, 
+    0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, 
+    0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, 
+    0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, 
+    0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00 },
+{   0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, 
+    0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, 
+    0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af, 
+    0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, 
+    0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, 
+    0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, 
+    0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb, 
+    0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, 
+    0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, 
+    0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, 
+    0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0, 
+    0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, 
+    0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, 
+    0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, 
+    0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8, 
+    0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, 
+    0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, 
+    0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, 
+    0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9, 
+    0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, 
+    0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, 
+    0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, 
+    0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093, 
+    0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, 
+    0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, 
+    0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, 
+    0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066, 
+    0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, 
+    0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, 
+    0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, 
+    0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2, 
+    0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, 
+    0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, 
+    0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, 
+    0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002, 
+    0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, 
+    0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, 
+    0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, 
+    0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a, 
+    0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, 
+    0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, 
+    0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, 
+    0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e },
+{   0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, 
+    0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, 
+    0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf, 
+    0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, 
+    0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, 
+    0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, 
+    0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060, 
+    0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, 
+    0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, 
+    0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, 
+    0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a, 
+    0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, 
+    0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, 
+    0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, 
+    0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f, 
+    0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, 
+    0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, 
+    0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, 
+    0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888, 
+    0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, 
+    0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, 
+    0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, 
+    0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6, 
+    0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, 
+    0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, 
+    0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, 
+    0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8, 
+    0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, 
+    0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, 
+    0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, 
+    0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d, 
+    0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, 
+    0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, 
+    0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, 
+    0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131, 
+    0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, 
+    0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, 
+    0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, 
+    0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292, 
+    0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, 
+    0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, 
+    0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, 
+    0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d },
+{   0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, 
+    0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, 
+    0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7, 
+    0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, 
+    0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, 
+    0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, 
+    0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818, 
+    0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, 
+    0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, 
+    0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, 
+    0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686, 
+    0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, 
+    0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, 
+    0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, 
+    0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb, 
+    0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, 
+    0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, 
+    0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, 
+    0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222, 
+    0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, 
+    0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, 
+    0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, 
+    0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad, 
+    0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, 
+    0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, 
+    0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, 
+    0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e, 
+    0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, 
+    0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, 
+    0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, 
+    0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b, 
+    0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, 
+    0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, 
+    0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, 
+    0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c, 
+    0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, 
+    0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, 
+    0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, 
+    0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4, 
+    0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, 
+    0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, 
+    0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, 
+    0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f }
+};
+
+/* Key generation constants */
+static const u32 SIGMA[] = {
+    0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, 0xc6ef372f, 0xe94f82be,
+    0x54ff53a5, 0xf1d36f1c, 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd
+};
+
+/* The phi algorithm given in C.2.7 of the Camellia spec document. */
+/*
+ * This version does not attempt to minimize amount of temporary
+ * variables, but instead explicitly exposes algorithm's parallelism.
+ * It is therefore most appropriate for platforms with not less than
+ * ~16 registers. For platforms with less registers [well, x86 to be
+ * specific] assembler version should be/is provided anyway...
+ */
+#define Camellia_Feistel(_s0,_s1,_s2,_s3,_key) do {\
+	register u32 _t0,_t1,_t2,_t3;\
+\
+	_t0  = _s0 ^ (_key)[0];\
+	_t3  = SBOX4_4404[_t0&0xff];\
+	_t1  = _s1 ^ (_key)[1];\
+	_t3 ^= SBOX3_3033[(_t0 >> 8)&0xff];\
+	_t2  = SBOX1_1110[_t1&0xff];\
+	_t3 ^= SBOX2_0222[(_t0 >> 16)&0xff];\
+	_t2 ^= SBOX4_4404[(_t1 >> 8)&0xff];\
+	_t3 ^= SBOX1_1110[(_t0 >> 24)];\
+	_t2 ^= _t3;\
+	_t3  = RightRotate(_t3,8);\
+	_t2 ^= SBOX3_3033[(_t1 >> 16)&0xff];\
+	_s3 ^= _t3;\
+	_t2 ^= SBOX2_0222[(_t1 >> 24)];\
+	_s2 ^= _t2; \
+	_s3 ^= _t2;\
+} while(0)
+
+/*
+ * Note that n has to be less than 32. Rotations for larger amount
+ * of bits are achieved by "rotating" order of s-elements and
+ * adjusting n accordingly, e.g. RotLeft128(s1,s2,s3,s0,n-32).
+ */
+#define RotLeft128(_s0,_s1,_s2,_s3,_n) do {\
+	u32 _t0=_s0>>(32-_n);\
+	_s0 = (_s0<<_n) | (_s1>>(32-_n));\
+	_s1 = (_s1<<_n) | (_s2>>(32-_n));\
+	_s2 = (_s2<<_n) | (_s3>>(32-_n));\
+	_s3 = (_s3<<_n) | _t0;\
+} while (0)
+
+int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE k)
+	{
+	register u32 s0,s1,s2,s3;
+
+	k[0] = s0 = GETU32(rawKey);
+	k[1] = s1 = GETU32(rawKey+4);
+	k[2] = s2 = GETU32(rawKey+8);
+	k[3] = s3 = GETU32(rawKey+12);
+
+	if (keyBitLength != 128)
+		{
+		k[8] = s0 = GETU32(rawKey+16);
+		k[9] = s1 = GETU32(rawKey+20);
+		if (keyBitLength == 192)
+			{
+			k[10] = s2 = ~s0;
+			k[11] = s3 = ~s1;
+			}
+		else
+			{
+			k[10] = s2 = GETU32(rawKey+24);
+			k[11] = s3 = GETU32(rawKey+28);
+			}
+		s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3];
+		}
+
+	/* Use the Feistel routine to scramble the key material */
+	Camellia_Feistel(s0,s1,s2,s3,SIGMA+0);
+	Camellia_Feistel(s2,s3,s0,s1,SIGMA+2);
+
+	s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3];
+	Camellia_Feistel(s0,s1,s2,s3,SIGMA+4);
+	Camellia_Feistel(s2,s3,s0,s1,SIGMA+6);
+
+	/* Fill the keyTable. Requires many block rotations. */
+	if (keyBitLength == 128)
+		{
+		k[ 4] = s0, k[ 5] = s1, k[ 6] = s2, k[ 7] = s3;
+		RotLeft128(s0,s1,s2,s3,15);	/* KA <<< 15 */
+		k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
+		RotLeft128(s0,s1,s2,s3,15);	/* KA <<< 30 */
+		k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3;
+		RotLeft128(s0,s1,s2,s3,15);	/* KA <<< 45 */
+		k[24] = s0, k[25] = s1;
+		RotLeft128(s0,s1,s2,s3,15);	/* KA <<< 60 */
+		k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3;
+		RotLeft128(s1,s2,s3,s0,2);	/* KA <<< 94 */
+		k[40] = s1, k[41] = s2, k[42] = s3, k[43] = s0;
+		RotLeft128(s1,s2,s3,s0,17);	/* KA <<<111 */
+		k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0;
+
+		s0 = k[ 0], s1 = k[ 1], s2 = k[ 2], s3 = k[ 3];
+		RotLeft128(s0,s1,s2,s3,15);	/* KL <<< 15 */
+		k[ 8] = s0, k[ 9] = s1, k[10] = s2, k[11] = s3;
+		RotLeft128(s0,s1,s2,s3,30);	/* KL <<< 45 */
+		k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3;
+		RotLeft128(s0,s1,s2,s3,15);	/* KL <<< 60 */
+		k[26] = s2, k[27] = s3;
+		RotLeft128(s0,s1,s2,s3,17);	/* KL <<< 77 */
+		k[32] = s0, k[33] = s1, k[34] = s2, k[35] = s3;
+		RotLeft128(s0,s1,s2,s3,17);	/* KL <<< 94 */
+		k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3;
+		RotLeft128(s0,s1,s2,s3,17);	/* KL <<<111 */
+		k[44] = s0, k[45] = s1, k[46] = s2, k[47] = s3;
+
+		return 3;	/* grand rounds */
+		}
+	else
+		{
+		k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
+		s0 ^= k[8], s1 ^= k[9], s2 ^=k[10], s3 ^=k[11];
+		Camellia_Feistel(s0,s1,s2,s3,(SIGMA+8));
+		Camellia_Feistel(s2,s3,s0,s1,(SIGMA+10));
+
+		k[ 4] = s0, k[ 5] = s1, k[ 6] = s2, k[ 7] = s3;
+		RotLeft128(s0,s1,s2,s3,30);	/* KB <<< 30 */
+		k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3;
+		RotLeft128(s0,s1,s2,s3,30);	/* KB <<< 60 */
+		k[40] = s0, k[41] = s1, k[42] = s2, k[43] = s3;
+		RotLeft128(s1,s2,s3,s0,19);	/* KB <<<111 */
+		k[64] = s1, k[65] = s2, k[66] = s3, k[67] = s0;
+
+		s0 = k[ 8], s1 = k[ 9], s2 = k[10], s3 = k[11];
+		RotLeft128(s0,s1,s2,s3,15);	/* KR <<< 15 */
+		k[ 8] = s0, k[ 9] = s1, k[10] = s2, k[11] = s3;
+		RotLeft128(s0,s1,s2,s3,15);	/* KR <<< 30 */
+		k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3;
+		RotLeft128(s0,s1,s2,s3,30);	/* KR <<< 60 */
+		k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3;
+		RotLeft128(s1,s2,s3,s0,2);	/* KR <<< 94 */
+		k[52] = s1, k[53] = s2, k[54] = s3, k[55] = s0;
+
+		s0 = k[12], s1 = k[13], s2 = k[14], s3 = k[15];
+		RotLeft128(s0,s1,s2,s3,15);	/* KA <<< 15 */
+		k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
+		RotLeft128(s0,s1,s2,s3,30);	/* KA <<< 45 */
+		k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3;
+						/* KA <<< 77 */
+		k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0;
+		RotLeft128(s1,s2,s3,s0,17);	/* KA <<< 94 */
+		k[56] = s1, k[57] = s2, k[58] = s3, k[59] = s0;
+
+		s0 = k[ 0], s1 = k[ 1], s2 = k[ 2], s3 = k[ 3];
+		RotLeft128(s1,s2,s3,s0,13);	/* KL <<< 45 */
+		k[24] = s1, k[25] = s2, k[26] = s3, k[27] = s0;
+		RotLeft128(s1,s2,s3,s0,15);	/* KL <<< 60 */
+		k[32] = s1, k[33] = s2, k[34] = s3, k[35] = s0;
+		RotLeft128(s1,s2,s3,s0,17);	/* KL <<< 77 */
+		k[44] = s1, k[45] = s2, k[46] = s3, k[47] = s0;
+		RotLeft128(s2,s3,s0,s1,2);	/* KL <<<111 */
+		k[60] = s2, k[61] = s3, k[62] = s0, k[63] = s1;
+
+		return 4;	/* grand rounds */
+		}
+	/*
+	 * It is possible to perform certain precalculations, which
+	 * would spare few cycles in block procedure. It's not done,
+	 * because it upsets the performance balance between key
+	 * setup and block procedures, negatively affecting overall
+	 * throughput in applications operating on short messages
+	 * and volatile keys.
+	 */ 
+	}
+
+void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], 
+		const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
+	{
+	register u32 s0,s1,s2,s3; 
+	const u32 *k = keyTable,*kend = keyTable+grandRounds*16; 
+
+	s0 = GETU32(plaintext)    ^ k[0];
+	s1 = GETU32(plaintext+4)  ^ k[1];
+	s2 = GETU32(plaintext+8)  ^ k[2];
+	s3 = GETU32(plaintext+12) ^ k[3];
+	k += 4;
+
+	while (1)
+		{
+		/* Camellia makes 6 Feistel rounds */
+		Camellia_Feistel(s0,s1,s2,s3,k+0);
+		Camellia_Feistel(s2,s3,s0,s1,k+2);
+		Camellia_Feistel(s0,s1,s2,s3,k+4);
+		Camellia_Feistel(s2,s3,s0,s1,k+6);
+		Camellia_Feistel(s0,s1,s2,s3,k+8);
+		Camellia_Feistel(s2,s3,s0,s1,k+10);
+		k += 12;
+
+		if (k == kend) break;
+
+		/* This is the same function as the diffusion function D
+		 * of the accompanying documentation. See section 3.2
+		 * for properties of the FLlayer function. */
+		s1 ^= LeftRotate(s0 & k[0], 1);
+		s2 ^= s3 | k[3];
+		s0 ^= s1 | k[1];
+		s3 ^= LeftRotate(s2 & k[2], 1);
+		k += 4;
+		}
+
+	s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3];
+
+	PUTU32(ciphertext,   s2);
+	PUTU32(ciphertext+4, s3);
+	PUTU32(ciphertext+8, s0);
+	PUTU32(ciphertext+12,s1);
+	}
+void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], 
+		const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
+	{
+	Camellia_EncryptBlock_Rounds(keyBitLength==128?3:4,
+			plaintext,keyTable,ciphertext);
+	}
+
+void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], 
+		const KEY_TABLE_TYPE keyTable, u8 plaintext[])
+	{
+	u32 s0,s1,s2,s3; 
+	const u32 *k = keyTable+grandRounds*16,*kend = keyTable+4; 
+
+	s0 = GETU32(ciphertext)    ^ k[0];
+	s1 = GETU32(ciphertext+4)  ^ k[1];
+	s2 = GETU32(ciphertext+8)  ^ k[2];
+	s3 = GETU32(ciphertext+12) ^ k[3];
+
+	while (1)
+		{
+		/* Camellia makes 6 Feistel rounds */
+		k -= 12;
+		Camellia_Feistel(s0,s1,s2,s3,k+10);
+		Camellia_Feistel(s2,s3,s0,s1,k+8);
+		Camellia_Feistel(s0,s1,s2,s3,k+6);
+		Camellia_Feistel(s2,s3,s0,s1,k+4);
+		Camellia_Feistel(s0,s1,s2,s3,k+2);
+		Camellia_Feistel(s2,s3,s0,s1,k+0);
+
+		if (k == kend) break;
+
+		/* This is the same function as the diffusion function D
+		 * of the accompanying documentation. See section 3.2
+		 * for properties of the FLlayer function. */
+		k -= 4;
+		s1 ^= LeftRotate(s0 & k[2], 1);
+		s2 ^= s3 | k[1];
+		s0 ^= s1 | k[3];
+		s3 ^= LeftRotate(s2 & k[0], 1);
+		}
+
+	k -= 4;
+	s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3];
+
+	PUTU32(plaintext,   s2);
+	PUTU32(plaintext+4, s3);
+	PUTU32(plaintext+8, s0);
+	PUTU32(plaintext+12,s1);
+	}
+void Camellia_DecryptBlock(int keyBitLength, const u8 plaintext[], 
+		const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
+	{
+	Camellia_DecryptBlock_Rounds(keyBitLength==128?3:4,
+			plaintext,keyTable,ciphertext);
+	}
diff --git a/openssl/crypto/camellia/camellia.h b/openssl/crypto/camellia/camellia.h
new file mode 100644
index 0000000..cf0457d
--- /dev/null
+++ b/openssl/crypto/camellia/camellia.h
@@ -0,0 +1,126 @@
+/* crypto/camellia/camellia.h -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#ifndef HEADER_CAMELLIA_H
+#define HEADER_CAMELLIA_H
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_CAMELLIA
+#error CAMELLIA is disabled.
+#endif
+
+#include <stddef.h>
+
+#define CAMELLIA_ENCRYPT	1
+#define CAMELLIA_DECRYPT	0
+
+/* Because array size can't be a const in C, the following two are macros.
+   Both sizes are in bytes. */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* This should be a hidden type, but EVP requires that the size be known */
+
+#define CAMELLIA_BLOCK_SIZE 16
+#define CAMELLIA_TABLE_BYTE_LEN 272
+#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
+
+typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match with WORD */
+
+struct camellia_key_st 
+	{
+	union	{
+		double d;	/* ensures 64-bit align */
+		KEY_TABLE_TYPE rd_key;
+		} u;
+	int grand_rounds;
+	};
+typedef struct camellia_key_st CAMELLIA_KEY;
+
+int Camellia_set_key(const unsigned char *userKey, const int bits,
+	CAMELLIA_KEY *key);
+
+void Camellia_encrypt(const unsigned char *in, unsigned char *out,
+	const CAMELLIA_KEY *key);
+void Camellia_decrypt(const unsigned char *in, unsigned char *out,
+	const CAMELLIA_KEY *key);
+
+void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out,
+	const CAMELLIA_KEY *key, const int enc);
+void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const CAMELLIA_KEY *key,
+	unsigned char *ivec, const int enc);
+void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const CAMELLIA_KEY *key,
+	unsigned char *ivec, int *num, const int enc);
+void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const CAMELLIA_KEY *key,
+	unsigned char *ivec, int *num, const int enc);
+void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const CAMELLIA_KEY *key,
+	unsigned char *ivec, int *num, const int enc);
+void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const CAMELLIA_KEY *key,
+	unsigned char *ivec, int *num);
+void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const CAMELLIA_KEY *key,
+	unsigned char ivec[CAMELLIA_BLOCK_SIZE],
+	unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE],
+	unsigned int *num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* !HEADER_Camellia_H */
diff --git a/openssl/crypto/camellia/cmll_cbc.c b/openssl/crypto/camellia/cmll_cbc.c
new file mode 100644
index 0000000..4c8d455
--- /dev/null
+++ b/openssl/crypto/camellia/cmll_cbc.c
@@ -0,0 +1,64 @@
+/* crypto/camellia/camellia_cbc.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/camellia.h>
+#include <openssl/modes.h>
+
+void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
+	size_t len, const CAMELLIA_KEY *key,
+	unsigned char *ivec, const int enc) 
+	{
+
+	if (enc)
+		CRYPTO_cbc128_encrypt(in,out,len,key,ivec,(block128_f)Camellia_encrypt);
+	else
+		CRYPTO_cbc128_decrypt(in,out,len,key,ivec,(block128_f)Camellia_decrypt);
+	}
diff --git a/openssl/crypto/camellia/cmll_cfb.c b/openssl/crypto/camellia/cmll_cfb.c
new file mode 100644
index 0000000..3d81b51
--- /dev/null
+++ b/openssl/crypto/camellia/cmll_cfb.c
@@ -0,0 +1,139 @@
+/* crypto/camellia/camellia_cfb.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/camellia.h>
+#include <openssl/modes.h>
+
+
+/* The input and output encrypted as though 128bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 128bit block we have used is contained in *num;
+ */
+
+void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const CAMELLIA_KEY *key,
+	unsigned char *ivec, int *num, const int enc)
+	{
+
+	CRYPTO_cfb128_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt);
+	}
+
+/* N.B. This expects the input to be packed, MS bit first */
+void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const CAMELLIA_KEY *key,
+	unsigned char *ivec, int *num, const int enc)
+	{
+	CRYPTO_cfb128_1_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt);
+	}
+
+void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const CAMELLIA_KEY *key,
+	unsigned char *ivec, int *num, const int enc)
+	{
+	CRYPTO_cfb128_8_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt);
+	}
+
diff --git a/openssl/crypto/camellia/cmll_ctr.c b/openssl/crypto/camellia/cmll_ctr.c
new file mode 100644
index 0000000..014e621
--- /dev/null
+++ b/openssl/crypto/camellia/cmll_ctr.c
@@ -0,0 +1,64 @@
+/* crypto/camellia/camellia_ctr.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/camellia.h>
+#include <openssl/modes.h>
+
+void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const CAMELLIA_KEY *key,
+	unsigned char ivec[CAMELLIA_BLOCK_SIZE],
+	unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE],
+	unsigned int *num) 
+	{
+
+	CRYPTO_ctr128_encrypt(in,out,length,key,ivec,ecount_buf,num,(block128_f)Camellia_encrypt);
+	}
+
diff --git a/openssl/crypto/camellia/cmll_ecb.c b/openssl/crypto/camellia/cmll_ecb.c
new file mode 100644
index 0000000..70dc0e5
--- /dev/null
+++ b/openssl/crypto/camellia/cmll_ecb.c
@@ -0,0 +1,74 @@
+/* crypto/camellia/camellia_ecb.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#ifndef CAMELLIA_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+#include <openssl/camellia.h>
+#include "cmll_locl.h"
+
+void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out,
+	const CAMELLIA_KEY *key, const int enc) 
+	{
+
+	assert(in && out && key);
+	assert((CAMELLIA_ENCRYPT == enc)||(CAMELLIA_DECRYPT == enc));
+
+	if (CAMELLIA_ENCRYPT == enc)
+		Camellia_encrypt(in, out, key);
+	else
+		Camellia_decrypt(in, out, key);
+	}
+
diff --git a/openssl/crypto/camellia/cmll_locl.h b/openssl/crypto/camellia/cmll_locl.h
new file mode 100644
index 0000000..4a4d880
--- /dev/null
+++ b/openssl/crypto/camellia/cmll_locl.h
@@ -0,0 +1,83 @@
+/* crypto/camellia/camellia_locl.h -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . 
+ * ALL RIGHTS RESERVED.
+ *
+ * Intellectual Property information for Camellia:
+ *     http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
+ *
+ * News Release for Announcement of Camellia open source:
+ *     http://www.ntt.co.jp/news/news06e/0604/060413a.html
+ *
+ * The Camellia Code included herein is developed by
+ * NTT (Nippon Telegraph and Telephone Corporation), and is contributed
+ * to the OpenSSL project.
+ *
+ * The Camellia Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#ifndef HEADER_CAMELLIA_LOCL_H
+#define HEADER_CAMELLIA_LOCL_H
+
+typedef unsigned int  u32;
+typedef unsigned char u8;
+
+int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE keyTable);
+void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], 
+		const KEY_TABLE_TYPE keyTable, u8 ciphertext[]);
+void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], 
+		const KEY_TABLE_TYPE keyTable, u8 plaintext[]);
+void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], 
+		const KEY_TABLE_TYPE keyTable, u8 ciphertext[]);
+void Camellia_DecryptBlock(int keyBitLength, const u8 ciphertext[], 
+		const KEY_TABLE_TYPE keyTable, u8 plaintext[]);
+#endif /* #ifndef HEADER_CAMELLIA_LOCL_H */
diff --git a/openssl/crypto/camellia/cmll_misc.c b/openssl/crypto/camellia/cmll_misc.c
new file mode 100644
index 0000000..f446891
--- /dev/null
+++ b/openssl/crypto/camellia/cmll_misc.c
@@ -0,0 +1,79 @@
+/* crypto/camellia/camellia_misc.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+ 
+#include <openssl/opensslv.h>
+#include <openssl/camellia.h>
+#include "cmll_locl.h"
+
+const char CAMELLIA_version[]="CAMELLIA" OPENSSL_VERSION_PTEXT;
+
+int Camellia_set_key(const unsigned char *userKey, const int bits,
+	CAMELLIA_KEY *key)
+	{
+	if(!userKey || !key)
+		return -1;
+	if(bits != 128 && bits != 192 && bits != 256)
+		return -2;
+	key->grand_rounds = Camellia_Ekeygen(bits , userKey, key->u.rd_key);
+	return 0;
+	}
+
+void Camellia_encrypt(const unsigned char *in, unsigned char *out,
+	const CAMELLIA_KEY *key)
+	{
+	Camellia_EncryptBlock_Rounds(key->grand_rounds, in , key->u.rd_key , out);
+	}
+
+void Camellia_decrypt(const unsigned char *in, unsigned char *out,
+	const CAMELLIA_KEY *key)
+	{
+	Camellia_DecryptBlock_Rounds(key->grand_rounds, in , key->u.rd_key , out);
+	}
diff --git a/openssl/crypto/camellia/cmll_ofb.c b/openssl/crypto/camellia/cmll_ofb.c
new file mode 100644
index 0000000..a482bef
--- /dev/null
+++ b/openssl/crypto/camellia/cmll_ofb.c
@@ -0,0 +1,119 @@
+/* crypto/camellia/camellia_ofb.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/camellia.h>
+#include <openssl/modes.h>
+
+/* The input and output encrypted as though 128bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 128bit block we have used is contained in *num;
+ */
+void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const CAMELLIA_KEY *key,
+	unsigned char *ivec, int *num) {
+	CRYPTO_ofb128_encrypt(in,out,length,key,ivec,num,(block128_f)Camellia_encrypt);
+}
diff --git a/openssl/crypto/cast/Makefile b/openssl/crypto/cast/Makefile
new file mode 100644
index 0000000..0acc38f
--- /dev/null
+++ b/openssl/crypto/cast/Makefile
@@ -0,0 +1,99 @@
+#
+# OpenSSL/crypto/cast/Makefile
+#
+
+DIR=	cast
+TOP=	../..
+CC=	cc
+CPP=	$(CC) -E
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CAST_ENC=c_enc.o
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+ASFLAGS= $(INCLUDES) $(ASFLAG)
+AFLAGS= $(ASFLAGS)
+
+GENERAL=Makefile
+TEST=casttest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=c_skey.c c_ecb.c c_enc.c c_cfb64.c c_ofb64.c 
+LIBOBJ=c_skey.o c_ecb.o $(CAST_ENC) c_cfb64.o c_ofb64.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= cast.h
+HEADER=	cast_s.h cast_lcl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+cast-586.s:	asm/cast-586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
+	$(PERL)	asm/cast-586.pl $(PERLASM_SCHEME) $(CLAGS) $(PROCESSOR) > $@
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+c_cfb64.o: ../../e_os.h ../../include/openssl/cast.h
+c_cfb64.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+c_cfb64.o: c_cfb64.c cast_lcl.h
+c_ecb.o: ../../e_os.h ../../include/openssl/cast.h
+c_ecb.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+c_ecb.o: ../../include/openssl/opensslv.h c_ecb.c cast_lcl.h
+c_enc.o: ../../e_os.h ../../include/openssl/cast.h
+c_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+c_enc.o: c_enc.c cast_lcl.h
+c_ofb64.o: ../../e_os.h ../../include/openssl/cast.h
+c_ofb64.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+c_ofb64.o: c_ofb64.c cast_lcl.h
+c_skey.o: ../../e_os.h ../../include/openssl/cast.h
+c_skey.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+c_skey.o: c_skey.c cast_lcl.h cast_s.h
diff --git a/openssl/crypto/cast/asm/cast-586.pl b/openssl/crypto/cast/asm/cast-586.pl
new file mode 100644
index 0000000..bf6810d
--- /dev/null
+++ b/openssl/crypto/cast/asm/cast-586.pl
@@ -0,0 +1,177 @@
+#!/usr/local/bin/perl
+
+# define for pentium pro friendly version
+$ppro=1;
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+require "cbc.pl";
+
+&asm_init($ARGV[0],"cast-586.pl",$ARGV[$#ARGV] eq "386");
+
+$CAST_ROUNDS=16;
+$L="edi";
+$R="esi";
+$K="ebp";
+$tmp1="ecx";
+$tmp2="ebx";
+$tmp3="eax";
+$tmp4="edx";
+$S1="CAST_S_table0";
+$S2="CAST_S_table1";
+$S3="CAST_S_table2";
+$S4="CAST_S_table3";
+
+@F1=("add","xor","sub");
+@F2=("xor","sub","add");
+@F3=("sub","add","xor");
+
+&CAST_encrypt("CAST_encrypt",1);
+&CAST_encrypt("CAST_decrypt",0);
+&cbc("CAST_cbc_encrypt","CAST_encrypt","CAST_decrypt",1,4,5,3,-1,-1);
+
+&asm_finish();
+
+sub CAST_encrypt {
+    local($name,$enc)=@_;
+
+    local($win_ex)=<<"EOF";
+EXTERN	_CAST_S_table0:DWORD
+EXTERN	_CAST_S_table1:DWORD
+EXTERN	_CAST_S_table2:DWORD
+EXTERN	_CAST_S_table3:DWORD
+EOF
+    &main::external_label(
+			  "CAST_S_table0",
+			  "CAST_S_table1",
+			  "CAST_S_table2",
+			  "CAST_S_table3",
+			  );
+
+    &function_begin_B($name,$win_ex);
+
+    &comment("");
+
+    &push("ebp");
+    &push("ebx");
+    &mov($tmp2,&wparam(0));
+    &mov($K,&wparam(1));
+    &push("esi");
+    &push("edi");
+
+    &comment("Load the 2 words");
+    &mov($L,&DWP(0,$tmp2,"",0));
+    &mov($R,&DWP(4,$tmp2,"",0));
+
+    &comment('Get short key flag');
+    &mov($tmp3,&DWP(128,$K,"",0));
+    if($enc) {
+	&push($tmp3);
+    } else {
+	&or($tmp3,$tmp3);
+	&jnz(&label('cast_dec_skip'));
+    }
+
+    &xor($tmp3,	$tmp3);
+
+    # encrypting part
+
+    if ($enc) {
+	&E_CAST( 0,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 1,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 2,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 3,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 4,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 5,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 6,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 7,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 8,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 9,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST(10,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST(11,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
+	&comment('test short key flag');
+	&pop($tmp4);
+	&or($tmp4,$tmp4);
+	&jnz(&label('cast_enc_done'));
+	&E_CAST(12,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST(13,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST(14,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST(15,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
+    } else {
+	&E_CAST(15,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST(14,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST(13,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST(12,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
+	&set_label('cast_dec_skip');
+	&E_CAST(11,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST(10,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 9,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 8,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 7,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 6,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 5,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 4,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 3,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 2,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 1,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
+	&E_CAST( 0,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
+    }
+
+    &set_label('cast_enc_done') if $enc;
+# Why the nop? - Ben 17/1/99
+    &nop();
+    &mov($tmp3,&wparam(0));
+    &mov(&DWP(4,$tmp3,"",0),$L);
+    &mov(&DWP(0,$tmp3,"",0),$R);
+    &function_end($name);
+}
+
+sub E_CAST {
+    local($i,$S,$L,$R,$K,$OP1,$OP2,$OP3,$tmp1,$tmp2,$tmp3,$tmp4)=@_;
+    # Ri needs to have 16 pre added.
+
+    &comment("round $i");
+    &mov(	$tmp4,		&DWP($i*8,$K,"",1));
+
+    &mov(	$tmp1,		&DWP($i*8+4,$K,"",1));
+    &$OP1(	$tmp4,		$R);
+
+    &rotl(	$tmp4,		&LB($tmp1));
+
+    if ($ppro) {
+	&mov(	$tmp2,		$tmp4);		# B
+	&xor(	$tmp1,		$tmp1);
+	
+	&movb(	&LB($tmp1),	&HB($tmp4));	# A
+	&and(	$tmp2,		0xff);
+
+	&shr(	$tmp4,		16); 		#
+	&xor(	$tmp3,		$tmp3);
+    } else {
+	&mov(	$tmp2,		$tmp4);		# B
+	&movb(	&LB($tmp1),	&HB($tmp4));	# A	# BAD BAD BAD
+	
+	&shr(	$tmp4,		16); 		#
+	&and(	$tmp2,		0xff);
+    }
+
+    &movb(	&LB($tmp3),	&HB($tmp4));	# C	# BAD BAD BAD
+    &and(	$tmp4,		0xff);		# D
+
+    &mov(	$tmp1,		&DWP($S1,"",$tmp1,4));
+    &mov(	$tmp2,		&DWP($S2,"",$tmp2,4));
+
+    &$OP2(	$tmp1,		$tmp2);
+    &mov(	$tmp2,		&DWP($S3,"",$tmp3,4));
+
+    &$OP3(	$tmp1,		$tmp2);
+    &mov(	$tmp2,		&DWP($S4,"",$tmp4,4));
+
+    &$OP1(	$tmp1,		$tmp2);
+    # XXX
+
+    &xor(	$L,		$tmp1);
+    # XXX
+}
+
diff --git a/openssl/crypto/cast/asm/readme b/openssl/crypto/cast/asm/readme
new file mode 100644
index 0000000..fbcd762
--- /dev/null
+++ b/openssl/crypto/cast/asm/readme
@@ -0,0 +1,7 @@
+There is a ppro flag in cast-586 which turns on/off
+generation of pentium pro/II friendly code
+
+This flag makes the inner loop one cycle longer, but generates 
+code that runs %30 faster on the pentium pro/II, while only %7 slower
+on the pentium.  By default, this flag is on.
+
diff --git a/openssl/crypto/cast/c_cfb64.c b/openssl/crypto/cast/c_cfb64.c
new file mode 100644
index 0000000..dcec13a
--- /dev/null
+++ b/openssl/crypto/cast/c_cfb64.c
@@ -0,0 +1,121 @@
+/* crypto/cast/c_cfb64.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/cast.h>
+#include "cast_lcl.h"
+
+/* The input and output encrypted as though 64bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+
+void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+			long length, const CAST_KEY *schedule, unsigned char *ivec,
+			int *num, int enc)
+	{
+	register CAST_LONG v0,v1,t;
+	register int n= *num;
+	register long l=length;
+	CAST_LONG ti[2];
+	unsigned char *iv,c,cc;
+
+	iv=ivec;
+	if (enc)
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				n2l(iv,v0); ti[0]=v0;
+				n2l(iv,v1); ti[1]=v1;
+				CAST_encrypt((CAST_LONG *)ti,schedule);
+				iv=ivec;
+				t=ti[0]; l2n(t,iv);
+				t=ti[1]; l2n(t,iv);
+				iv=ivec;
+				}
+			c= *(in++)^iv[n];
+			*(out++)=c;
+			iv[n]=c;
+			n=(n+1)&0x07;
+			}
+		}
+	else
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				n2l(iv,v0); ti[0]=v0;
+				n2l(iv,v1); ti[1]=v1;
+				CAST_encrypt((CAST_LONG *)ti,schedule);
+				iv=ivec;
+				t=ti[0]; l2n(t,iv);
+				t=ti[1]; l2n(t,iv);
+				iv=ivec;
+				}
+			cc= *(in++);
+			c=iv[n];
+			iv[n]=cc;
+			*(out++)=c^cc;
+			n=(n+1)&0x07;
+			}
+		}
+	v0=v1=ti[0]=ti[1]=t=c=cc=0;
+	*num=n;
+	}
diff --git a/openssl/crypto/cast/c_ecb.c b/openssl/crypto/cast/c_ecb.c
new file mode 100644
index 0000000..b6a3b1f
--- /dev/null
+++ b/openssl/crypto/cast/c_ecb.c
@@ -0,0 +1,79 @@
+/* crypto/cast/c_ecb.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/cast.h>
+#include "cast_lcl.h"
+#include <openssl/opensslv.h>
+
+const char CAST_version[]="CAST" OPENSSL_VERSION_PTEXT;
+
+void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out,
+		      const CAST_KEY *ks, int enc)
+	{
+	CAST_LONG l,d[2];
+
+	n2l(in,l); d[0]=l;
+	n2l(in,l); d[1]=l;
+	if (enc)
+		CAST_encrypt(d,ks);
+	else
+		CAST_decrypt(d,ks);
+	l=d[0]; l2n(l,out);
+	l=d[1]; l2n(l,out);
+	l=d[0]=d[1]=0;
+	}
diff --git a/openssl/crypto/cast/c_enc.c b/openssl/crypto/cast/c_enc.c
new file mode 100644
index 0000000..357c41e
--- /dev/null
+++ b/openssl/crypto/cast/c_enc.c
@@ -0,0 +1,208 @@
+/* crypto/cast/c_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/cast.h>
+#include "cast_lcl.h"
+
+void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key)
+	{
+	register CAST_LONG l,r,t;
+	const register CAST_LONG *k;
+
+	k= &(key->data[0]);
+	l=data[0];
+	r=data[1];
+
+	E_CAST( 0,k,l,r,+,^,-);
+	E_CAST( 1,k,r,l,^,-,+);
+	E_CAST( 2,k,l,r,-,+,^);
+	E_CAST( 3,k,r,l,+,^,-);
+	E_CAST( 4,k,l,r,^,-,+);
+	E_CAST( 5,k,r,l,-,+,^);
+	E_CAST( 6,k,l,r,+,^,-);
+	E_CAST( 7,k,r,l,^,-,+);
+	E_CAST( 8,k,l,r,-,+,^);
+	E_CAST( 9,k,r,l,+,^,-);
+	E_CAST(10,k,l,r,^,-,+);
+	E_CAST(11,k,r,l,-,+,^);
+	if(!key->short_key)
+	    {
+	    E_CAST(12,k,l,r,+,^,-);
+	    E_CAST(13,k,r,l,^,-,+);
+	    E_CAST(14,k,l,r,-,+,^);
+	    E_CAST(15,k,r,l,+,^,-);
+	    }
+
+	data[1]=l&0xffffffffL;
+	data[0]=r&0xffffffffL;
+	}
+
+void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key)
+	{
+	register CAST_LONG l,r,t;
+	const register CAST_LONG *k;
+
+	k= &(key->data[0]);
+	l=data[0];
+	r=data[1];
+
+	if(!key->short_key)
+	    {
+	    E_CAST(15,k,l,r,+,^,-);
+	    E_CAST(14,k,r,l,-,+,^);
+	    E_CAST(13,k,l,r,^,-,+);
+	    E_CAST(12,k,r,l,+,^,-);
+	    }
+	E_CAST(11,k,l,r,-,+,^);
+	E_CAST(10,k,r,l,^,-,+);
+	E_CAST( 9,k,l,r,+,^,-);
+	E_CAST( 8,k,r,l,-,+,^);
+	E_CAST( 7,k,l,r,^,-,+);
+	E_CAST( 6,k,r,l,+,^,-);
+	E_CAST( 5,k,l,r,-,+,^);
+	E_CAST( 4,k,r,l,^,-,+);
+	E_CAST( 3,k,l,r,+,^,-);
+	E_CAST( 2,k,r,l,-,+,^);
+	E_CAST( 1,k,l,r,^,-,+);
+	E_CAST( 0,k,r,l,+,^,-);
+
+	data[1]=l&0xffffffffL;
+	data[0]=r&0xffffffffL;
+	}
+
+void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+	     const CAST_KEY *ks, unsigned char *iv, int enc)
+	{
+	register CAST_LONG tin0,tin1;
+	register CAST_LONG tout0,tout1,xor0,xor1;
+	register long l=length;
+	CAST_LONG tin[2];
+
+	if (enc)
+		{
+		n2l(iv,tout0);
+		n2l(iv,tout1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			n2l(in,tin0);
+			n2l(in,tin1);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			CAST_encrypt(tin,ks);
+			tout0=tin[0];
+			tout1=tin[1];
+			l2n(tout0,out);
+			l2n(tout1,out);
+			}
+		if (l != -8)
+			{
+			n2ln(in,tin0,tin1,l+8);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			CAST_encrypt(tin,ks);
+			tout0=tin[0];
+			tout1=tin[1];
+			l2n(tout0,out);
+			l2n(tout1,out);
+			}
+		l2n(tout0,iv);
+		l2n(tout1,iv);
+		}
+	else
+		{
+		n2l(iv,xor0);
+		n2l(iv,xor1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			n2l(in,tin0);
+			n2l(in,tin1);
+			tin[0]=tin0;
+			tin[1]=tin1;
+			CAST_decrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2n(tout0,out);
+			l2n(tout1,out);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		if (l != -8)
+			{
+			n2l(in,tin0);
+			n2l(in,tin1);
+			tin[0]=tin0;
+			tin[1]=tin1;
+			CAST_decrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2nn(tout0,tout1,out,l+8);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		l2n(xor0,iv);
+		l2n(xor1,iv);
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	tin[0]=tin[1]=0;
+	}
diff --git a/openssl/crypto/cast/c_ofb64.c b/openssl/crypto/cast/c_ofb64.c
new file mode 100644
index 0000000..cb32224
--- /dev/null
+++ b/openssl/crypto/cast/c_ofb64.c
@@ -0,0 +1,110 @@
+/* crypto/cast/c_ofb64.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/cast.h>
+#include "cast_lcl.h"
+
+/* The input and output encrypted as though 64bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+			long length, const CAST_KEY *schedule, unsigned char *ivec,
+			int *num)
+	{
+	register CAST_LONG v0,v1,t;
+	register int n= *num;
+	register long l=length;
+	unsigned char d[8];
+	register char *dp;
+	CAST_LONG ti[2];
+	unsigned char *iv;
+	int save=0;
+
+	iv=ivec;
+	n2l(iv,v0);
+	n2l(iv,v1);
+	ti[0]=v0;
+	ti[1]=v1;
+	dp=(char *)d;
+	l2n(v0,dp);
+	l2n(v1,dp);
+	while (l--)
+		{
+		if (n == 0)
+			{
+			CAST_encrypt((CAST_LONG *)ti,schedule);
+			dp=(char *)d;
+			t=ti[0]; l2n(t,dp);
+			t=ti[1]; l2n(t,dp);
+			save++;
+			}
+		*(out++)= *(in++)^d[n];
+		n=(n+1)&0x07;
+		}
+	if (save)
+		{
+		v0=ti[0];
+		v1=ti[1];
+		iv=ivec;
+		l2n(v0,iv);
+		l2n(v1,iv);
+		}
+	t=v0=v1=ti[0]=ti[1]=0;
+	*num=n;
+	}
diff --git a/openssl/crypto/cast/c_skey.c b/openssl/crypto/cast/c_skey.c
new file mode 100644
index 0000000..76e4000
--- /dev/null
+++ b/openssl/crypto/cast/c_skey.c
@@ -0,0 +1,166 @@
+/* crypto/cast/c_skey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/cast.h>
+#include "cast_lcl.h"
+#include "cast_s.h"
+
+#define CAST_exp(l,A,a,n) \
+	A[n/4]=l; \
+	a[n+3]=(l    )&0xff; \
+	a[n+2]=(l>> 8)&0xff; \
+	a[n+1]=(l>>16)&0xff; \
+	a[n+0]=(l>>24)&0xff;
+
+#define S4 CAST_S_table4
+#define S5 CAST_S_table5
+#define S6 CAST_S_table6
+#define S7 CAST_S_table7
+
+void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data)
+	{
+	CAST_LONG x[16];
+	CAST_LONG z[16];
+	CAST_LONG k[32];
+	CAST_LONG X[4],Z[4];
+	CAST_LONG l,*K;
+	int i;
+
+	for (i=0; i<16; i++) x[i]=0;
+	if (len > 16) len=16;
+	for (i=0; i<len; i++)
+		x[i]=data[i];
+	if(len <= 10)
+	    key->short_key=1;
+	else
+	    key->short_key=0;
+
+	K= &k[0];
+	X[0]=((x[ 0]<<24)|(x[ 1]<<16)|(x[ 2]<<8)|x[ 3])&0xffffffffL;
+	X[1]=((x[ 4]<<24)|(x[ 5]<<16)|(x[ 6]<<8)|x[ 7])&0xffffffffL;
+	X[2]=((x[ 8]<<24)|(x[ 9]<<16)|(x[10]<<8)|x[11])&0xffffffffL;
+	X[3]=((x[12]<<24)|(x[13]<<16)|(x[14]<<8)|x[15])&0xffffffffL;
+
+	for (;;)
+		{
+	l=X[0]^S4[x[13]]^S5[x[15]]^S6[x[12]]^S7[x[14]]^S6[x[ 8]];
+	CAST_exp(l,Z,z, 0);
+	l=X[2]^S4[z[ 0]]^S5[z[ 2]]^S6[z[ 1]]^S7[z[ 3]]^S7[x[10]];
+	CAST_exp(l,Z,z, 4);
+	l=X[3]^S4[z[ 7]]^S5[z[ 6]]^S6[z[ 5]]^S7[z[ 4]]^S4[x[ 9]];
+	CAST_exp(l,Z,z, 8);
+	l=X[1]^S4[z[10]]^S5[z[ 9]]^S6[z[11]]^S7[z[ 8]]^S5[x[11]];
+	CAST_exp(l,Z,z,12);
+
+	K[ 0]= S4[z[ 8]]^S5[z[ 9]]^S6[z[ 7]]^S7[z[ 6]]^S4[z[ 2]];
+	K[ 1]= S4[z[10]]^S5[z[11]]^S6[z[ 5]]^S7[z[ 4]]^S5[z[ 6]];
+	K[ 2]= S4[z[12]]^S5[z[13]]^S6[z[ 3]]^S7[z[ 2]]^S6[z[ 9]];
+	K[ 3]= S4[z[14]]^S5[z[15]]^S6[z[ 1]]^S7[z[ 0]]^S7[z[12]];
+
+	l=Z[2]^S4[z[ 5]]^S5[z[ 7]]^S6[z[ 4]]^S7[z[ 6]]^S6[z[ 0]];
+	CAST_exp(l,X,x, 0);
+	l=Z[0]^S4[x[ 0]]^S5[x[ 2]]^S6[x[ 1]]^S7[x[ 3]]^S7[z[ 2]];
+	CAST_exp(l,X,x, 4);
+	l=Z[1]^S4[x[ 7]]^S5[x[ 6]]^S6[x[ 5]]^S7[x[ 4]]^S4[z[ 1]];
+	CAST_exp(l,X,x, 8);
+	l=Z[3]^S4[x[10]]^S5[x[ 9]]^S6[x[11]]^S7[x[ 8]]^S5[z[ 3]];
+	CAST_exp(l,X,x,12);
+
+	K[ 4]= S4[x[ 3]]^S5[x[ 2]]^S6[x[12]]^S7[x[13]]^S4[x[ 8]];
+	K[ 5]= S4[x[ 1]]^S5[x[ 0]]^S6[x[14]]^S7[x[15]]^S5[x[13]];
+	K[ 6]= S4[x[ 7]]^S5[x[ 6]]^S6[x[ 8]]^S7[x[ 9]]^S6[x[ 3]];
+	K[ 7]= S4[x[ 5]]^S5[x[ 4]]^S6[x[10]]^S7[x[11]]^S7[x[ 7]];
+
+	l=X[0]^S4[x[13]]^S5[x[15]]^S6[x[12]]^S7[x[14]]^S6[x[ 8]];
+	CAST_exp(l,Z,z, 0);
+	l=X[2]^S4[z[ 0]]^S5[z[ 2]]^S6[z[ 1]]^S7[z[ 3]]^S7[x[10]];
+	CAST_exp(l,Z,z, 4);
+	l=X[3]^S4[z[ 7]]^S5[z[ 6]]^S6[z[ 5]]^S7[z[ 4]]^S4[x[ 9]];
+	CAST_exp(l,Z,z, 8);
+	l=X[1]^S4[z[10]]^S5[z[ 9]]^S6[z[11]]^S7[z[ 8]]^S5[x[11]];
+	CAST_exp(l,Z,z,12);
+
+	K[ 8]= S4[z[ 3]]^S5[z[ 2]]^S6[z[12]]^S7[z[13]]^S4[z[ 9]];
+	K[ 9]= S4[z[ 1]]^S5[z[ 0]]^S6[z[14]]^S7[z[15]]^S5[z[12]];
+	K[10]= S4[z[ 7]]^S5[z[ 6]]^S6[z[ 8]]^S7[z[ 9]]^S6[z[ 2]];
+	K[11]= S4[z[ 5]]^S5[z[ 4]]^S6[z[10]]^S7[z[11]]^S7[z[ 6]];
+
+	l=Z[2]^S4[z[ 5]]^S5[z[ 7]]^S6[z[ 4]]^S7[z[ 6]]^S6[z[ 0]];
+	CAST_exp(l,X,x, 0);
+	l=Z[0]^S4[x[ 0]]^S5[x[ 2]]^S6[x[ 1]]^S7[x[ 3]]^S7[z[ 2]];
+	CAST_exp(l,X,x, 4);
+	l=Z[1]^S4[x[ 7]]^S5[x[ 6]]^S6[x[ 5]]^S7[x[ 4]]^S4[z[ 1]];
+	CAST_exp(l,X,x, 8);
+	l=Z[3]^S4[x[10]]^S5[x[ 9]]^S6[x[11]]^S7[x[ 8]]^S5[z[ 3]];
+	CAST_exp(l,X,x,12);
+
+	K[12]= S4[x[ 8]]^S5[x[ 9]]^S6[x[ 7]]^S7[x[ 6]]^S4[x[ 3]];
+	K[13]= S4[x[10]]^S5[x[11]]^S6[x[ 5]]^S7[x[ 4]]^S5[x[ 7]];
+	K[14]= S4[x[12]]^S5[x[13]]^S6[x[ 3]]^S7[x[ 2]]^S6[x[ 8]];
+	K[15]= S4[x[14]]^S5[x[15]]^S6[x[ 1]]^S7[x[ 0]]^S7[x[13]];
+	if (K != k)  break;
+	K+=16;
+		}
+
+	for (i=0; i<16; i++)
+		{
+		key->data[i*2]=k[i];
+		key->data[i*2+1]=((k[i+16])+16)&0x1f;
+		}
+	}
+
diff --git a/openssl/crypto/cast/cast.h b/openssl/crypto/cast/cast.h
new file mode 100644
index 0000000..1a264f8
--- /dev/null
+++ b/openssl/crypto/cast/cast.h
@@ -0,0 +1,105 @@
+/* crypto/cast/cast.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_CAST_H
+#define HEADER_CAST_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_CAST
+#error CAST is disabled.
+#endif
+
+#define CAST_ENCRYPT	1
+#define CAST_DECRYPT	0
+
+#define CAST_LONG unsigned int
+
+#define CAST_BLOCK	8
+#define CAST_KEY_LENGTH	16
+
+typedef struct cast_key_st
+	{
+	CAST_LONG data[32];
+	int short_key;	/* Use reduced rounds for short key */
+	} CAST_KEY;
+
+ 
+void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data);
+void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, const CAST_KEY *key,
+		      int enc);
+void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key);
+void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key);
+void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+		      const CAST_KEY *ks, unsigned char *iv, int enc);
+void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+			long length, const CAST_KEY *schedule, unsigned char *ivec,
+			int *num, int enc);
+void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, 
+			long length, const CAST_KEY *schedule, unsigned char *ivec,
+			int *num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/cast/cast_lcl.h b/openssl/crypto/cast/cast_lcl.h
new file mode 100644
index 0000000..e756021
--- /dev/null
+++ b/openssl/crypto/cast/cast_lcl.h
@@ -0,0 +1,227 @@
+/* crypto/cast/cast_lcl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+
+#include "e_os.h"
+
+#ifdef OPENSSL_SYS_WIN32
+#include <stdlib.h>
+#endif
+
+
+#undef c2l
+#define c2l(c,l)	(l =((unsigned long)(*((c)++)))    , \
+			 l|=((unsigned long)(*((c)++)))<< 8L, \
+			 l|=((unsigned long)(*((c)++)))<<16L, \
+			 l|=((unsigned long)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#undef c2ln
+#define c2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
+			case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
+			case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
+			case 5: l2|=((unsigned long)(*(--(c))));     \
+			case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
+			case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
+			case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
+			case 1: l1|=((unsigned long)(*(--(c))));     \
+				} \
+			}
+
+#undef l2c
+#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#undef l2cn
+#define l2cn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
+				} \
+			}
+
+/* NOTE - c is not incremented as per n2l */
+#define n2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))    ; \
+			case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
+			case 6: l2|=((unsigned long)(*(--(c))))<<16; \
+			case 5: l2|=((unsigned long)(*(--(c))))<<24; \
+			case 4: l1 =((unsigned long)(*(--(c))))    ; \
+			case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
+			case 2: l1|=((unsigned long)(*(--(c))))<<16; \
+			case 1: l1|=((unsigned long)(*(--(c))))<<24; \
+				} \
+			}
+
+/* NOTE - c is not incremented as per l2n */
+#define l2nn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+				} \
+			}
+
+#undef n2l
+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++))))
+
+#undef l2n
+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)     )&0xff))
+
+#if defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)
+#define ROTL(a,n)     (_lrotl(a,n))
+#else
+#define ROTL(a,n)     ((((a)<<(n))&0xffffffffL)|((a)>>(32-(n))))
+#endif
+
+#define C_M    0x3fc
+#define C_0    22L
+#define C_1    14L
+#define C_2     6L
+#define C_3     2L /* left shift */
+
+/* The rotate has an extra 16 added to it to help the x86 asm */
+#if defined(CAST_PTR)
+#define E_CAST(n,key,L,R,OP1,OP2,OP3) \
+	{ \
+	int i; \
+	t=(key[n*2] OP1 R)&0xffffffffL; \
+	i=key[n*2+1]; \
+	t=ROTL(t,i); \
+	L^= (((((*(CAST_LONG *)((unsigned char *) \
+			CAST_S_table0+((t>>C_2)&C_M)) OP2 \
+		*(CAST_LONG *)((unsigned char *) \
+			CAST_S_table1+((t<<C_3)&C_M)))&0xffffffffL) OP3 \
+		*(CAST_LONG *)((unsigned char *) \
+			CAST_S_table2+((t>>C_0)&C_M)))&0xffffffffL) OP1 \
+		*(CAST_LONG *)((unsigned char *) \
+			CAST_S_table3+((t>>C_1)&C_M)))&0xffffffffL; \
+	}
+#elif defined(CAST_PTR2)
+#define E_CAST(n,key,L,R,OP1,OP2,OP3) \
+	{ \
+	int i; \
+	CAST_LONG u,v,w; \
+	w=(key[n*2] OP1 R)&0xffffffffL; \
+	i=key[n*2+1]; \
+	w=ROTL(w,i); \
+	u=w>>C_2; \
+	v=w<<C_3; \
+	u&=C_M; \
+	v&=C_M; \
+	t= *(CAST_LONG *)((unsigned char *)CAST_S_table0+u); \
+	u=w>>C_0; \
+	t=(t OP2 *(CAST_LONG *)((unsigned char *)CAST_S_table1+v))&0xffffffffL;\
+	v=w>>C_1; \
+	u&=C_M; \
+	v&=C_M; \
+	t=(t OP3 *(CAST_LONG *)((unsigned char *)CAST_S_table2+u)&0xffffffffL);\
+	t=(t OP1 *(CAST_LONG *)((unsigned char *)CAST_S_table3+v)&0xffffffffL);\
+	L^=(t&0xffffffff); \
+	}
+#else
+#define E_CAST(n,key,L,R,OP1,OP2,OP3) \
+	{ \
+	CAST_LONG a,b,c,d; \
+	t=(key[n*2] OP1 R)&0xffffffff; \
+	t=ROTL(t,(key[n*2+1])); \
+	a=CAST_S_table0[(t>> 8)&0xff]; \
+	b=CAST_S_table1[(t    )&0xff]; \
+	c=CAST_S_table2[(t>>24)&0xff]; \
+	d=CAST_S_table3[(t>>16)&0xff]; \
+	L^=(((((a OP2 b)&0xffffffffL) OP3 c)&0xffffffffL) OP1 d)&0xffffffffL; \
+	}
+#endif
+
+extern const CAST_LONG CAST_S_table0[256];
+extern const CAST_LONG CAST_S_table1[256];
+extern const CAST_LONG CAST_S_table2[256];
+extern const CAST_LONG CAST_S_table3[256];
+extern const CAST_LONG CAST_S_table4[256];
+extern const CAST_LONG CAST_S_table5[256];
+extern const CAST_LONG CAST_S_table6[256];
+extern const CAST_LONG CAST_S_table7[256];
diff --git a/openssl/crypto/cast/cast_s.h b/openssl/crypto/cast/cast_s.h
new file mode 100644
index 0000000..c483fd5
--- /dev/null
+++ b/openssl/crypto/cast/cast_s.h
@@ -0,0 +1,585 @@
+/* crypto/cast/cast_s.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+OPENSSL_GLOBAL const CAST_LONG CAST_S_table0[256]={
+	0x30fb40d4,0x9fa0ff0b,0x6beccd2f,0x3f258c7a,
+	0x1e213f2f,0x9c004dd3,0x6003e540,0xcf9fc949,
+	0xbfd4af27,0x88bbbdb5,0xe2034090,0x98d09675,
+	0x6e63a0e0,0x15c361d2,0xc2e7661d,0x22d4ff8e,
+	0x28683b6f,0xc07fd059,0xff2379c8,0x775f50e2,
+	0x43c340d3,0xdf2f8656,0x887ca41a,0xa2d2bd2d,
+	0xa1c9e0d6,0x346c4819,0x61b76d87,0x22540f2f,
+	0x2abe32e1,0xaa54166b,0x22568e3a,0xa2d341d0,
+	0x66db40c8,0xa784392f,0x004dff2f,0x2db9d2de,
+	0x97943fac,0x4a97c1d8,0x527644b7,0xb5f437a7,
+	0xb82cbaef,0xd751d159,0x6ff7f0ed,0x5a097a1f,
+	0x827b68d0,0x90ecf52e,0x22b0c054,0xbc8e5935,
+	0x4b6d2f7f,0x50bb64a2,0xd2664910,0xbee5812d,
+	0xb7332290,0xe93b159f,0xb48ee411,0x4bff345d,
+	0xfd45c240,0xad31973f,0xc4f6d02e,0x55fc8165,
+	0xd5b1caad,0xa1ac2dae,0xa2d4b76d,0xc19b0c50,
+	0x882240f2,0x0c6e4f38,0xa4e4bfd7,0x4f5ba272,
+	0x564c1d2f,0xc59c5319,0xb949e354,0xb04669fe,
+	0xb1b6ab8a,0xc71358dd,0x6385c545,0x110f935d,
+	0x57538ad5,0x6a390493,0xe63d37e0,0x2a54f6b3,
+	0x3a787d5f,0x6276a0b5,0x19a6fcdf,0x7a42206a,
+	0x29f9d4d5,0xf61b1891,0xbb72275e,0xaa508167,
+	0x38901091,0xc6b505eb,0x84c7cb8c,0x2ad75a0f,
+	0x874a1427,0xa2d1936b,0x2ad286af,0xaa56d291,
+	0xd7894360,0x425c750d,0x93b39e26,0x187184c9,
+	0x6c00b32d,0x73e2bb14,0xa0bebc3c,0x54623779,
+	0x64459eab,0x3f328b82,0x7718cf82,0x59a2cea6,
+	0x04ee002e,0x89fe78e6,0x3fab0950,0x325ff6c2,
+	0x81383f05,0x6963c5c8,0x76cb5ad6,0xd49974c9,
+	0xca180dcf,0x380782d5,0xc7fa5cf6,0x8ac31511,
+	0x35e79e13,0x47da91d0,0xf40f9086,0xa7e2419e,
+	0x31366241,0x051ef495,0xaa573b04,0x4a805d8d,
+	0x548300d0,0x00322a3c,0xbf64cddf,0xba57a68e,
+	0x75c6372b,0x50afd341,0xa7c13275,0x915a0bf5,
+	0x6b54bfab,0x2b0b1426,0xab4cc9d7,0x449ccd82,
+	0xf7fbf265,0xab85c5f3,0x1b55db94,0xaad4e324,
+	0xcfa4bd3f,0x2deaa3e2,0x9e204d02,0xc8bd25ac,
+	0xeadf55b3,0xd5bd9e98,0xe31231b2,0x2ad5ad6c,
+	0x954329de,0xadbe4528,0xd8710f69,0xaa51c90f,
+	0xaa786bf6,0x22513f1e,0xaa51a79b,0x2ad344cc,
+	0x7b5a41f0,0xd37cfbad,0x1b069505,0x41ece491,
+	0xb4c332e6,0x032268d4,0xc9600acc,0xce387e6d,
+	0xbf6bb16c,0x6a70fb78,0x0d03d9c9,0xd4df39de,
+	0xe01063da,0x4736f464,0x5ad328d8,0xb347cc96,
+	0x75bb0fc3,0x98511bfb,0x4ffbcc35,0xb58bcf6a,
+	0xe11f0abc,0xbfc5fe4a,0xa70aec10,0xac39570a,
+	0x3f04442f,0x6188b153,0xe0397a2e,0x5727cb79,
+	0x9ceb418f,0x1cacd68d,0x2ad37c96,0x0175cb9d,
+	0xc69dff09,0xc75b65f0,0xd9db40d8,0xec0e7779,
+	0x4744ead4,0xb11c3274,0xdd24cb9e,0x7e1c54bd,
+	0xf01144f9,0xd2240eb1,0x9675b3fd,0xa3ac3755,
+	0xd47c27af,0x51c85f4d,0x56907596,0xa5bb15e6,
+	0x580304f0,0xca042cf1,0x011a37ea,0x8dbfaadb,
+	0x35ba3e4a,0x3526ffa0,0xc37b4d09,0xbc306ed9,
+	0x98a52666,0x5648f725,0xff5e569d,0x0ced63d0,
+	0x7c63b2cf,0x700b45e1,0xd5ea50f1,0x85a92872,
+	0xaf1fbda7,0xd4234870,0xa7870bf3,0x2d3b4d79,
+	0x42e04198,0x0cd0ede7,0x26470db8,0xf881814c,
+	0x474d6ad7,0x7c0c5e5c,0xd1231959,0x381b7298,
+	0xf5d2f4db,0xab838653,0x6e2f1e23,0x83719c9e,
+	0xbd91e046,0x9a56456e,0xdc39200c,0x20c8c571,
+	0x962bda1c,0xe1e696ff,0xb141ab08,0x7cca89b9,
+	0x1a69e783,0x02cc4843,0xa2f7c579,0x429ef47d,
+	0x427b169c,0x5ac9f049,0xdd8f0f00,0x5c8165bf,
+	};
+OPENSSL_GLOBAL const CAST_LONG CAST_S_table1[256]={
+	0x1f201094,0xef0ba75b,0x69e3cf7e,0x393f4380,
+	0xfe61cf7a,0xeec5207a,0x55889c94,0x72fc0651,
+	0xada7ef79,0x4e1d7235,0xd55a63ce,0xde0436ba,
+	0x99c430ef,0x5f0c0794,0x18dcdb7d,0xa1d6eff3,
+	0xa0b52f7b,0x59e83605,0xee15b094,0xe9ffd909,
+	0xdc440086,0xef944459,0xba83ccb3,0xe0c3cdfb,
+	0xd1da4181,0x3b092ab1,0xf997f1c1,0xa5e6cf7b,
+	0x01420ddb,0xe4e7ef5b,0x25a1ff41,0xe180f806,
+	0x1fc41080,0x179bee7a,0xd37ac6a9,0xfe5830a4,
+	0x98de8b7f,0x77e83f4e,0x79929269,0x24fa9f7b,
+	0xe113c85b,0xacc40083,0xd7503525,0xf7ea615f,
+	0x62143154,0x0d554b63,0x5d681121,0xc866c359,
+	0x3d63cf73,0xcee234c0,0xd4d87e87,0x5c672b21,
+	0x071f6181,0x39f7627f,0x361e3084,0xe4eb573b,
+	0x602f64a4,0xd63acd9c,0x1bbc4635,0x9e81032d,
+	0x2701f50c,0x99847ab4,0xa0e3df79,0xba6cf38c,
+	0x10843094,0x2537a95e,0xf46f6ffe,0xa1ff3b1f,
+	0x208cfb6a,0x8f458c74,0xd9e0a227,0x4ec73a34,
+	0xfc884f69,0x3e4de8df,0xef0e0088,0x3559648d,
+	0x8a45388c,0x1d804366,0x721d9bfd,0xa58684bb,
+	0xe8256333,0x844e8212,0x128d8098,0xfed33fb4,
+	0xce280ae1,0x27e19ba5,0xd5a6c252,0xe49754bd,
+	0xc5d655dd,0xeb667064,0x77840b4d,0xa1b6a801,
+	0x84db26a9,0xe0b56714,0x21f043b7,0xe5d05860,
+	0x54f03084,0x066ff472,0xa31aa153,0xdadc4755,
+	0xb5625dbf,0x68561be6,0x83ca6b94,0x2d6ed23b,
+	0xeccf01db,0xa6d3d0ba,0xb6803d5c,0xaf77a709,
+	0x33b4a34c,0x397bc8d6,0x5ee22b95,0x5f0e5304,
+	0x81ed6f61,0x20e74364,0xb45e1378,0xde18639b,
+	0x881ca122,0xb96726d1,0x8049a7e8,0x22b7da7b,
+	0x5e552d25,0x5272d237,0x79d2951c,0xc60d894c,
+	0x488cb402,0x1ba4fe5b,0xa4b09f6b,0x1ca815cf,
+	0xa20c3005,0x8871df63,0xb9de2fcb,0x0cc6c9e9,
+	0x0beeff53,0xe3214517,0xb4542835,0x9f63293c,
+	0xee41e729,0x6e1d2d7c,0x50045286,0x1e6685f3,
+	0xf33401c6,0x30a22c95,0x31a70850,0x60930f13,
+	0x73f98417,0xa1269859,0xec645c44,0x52c877a9,
+	0xcdff33a6,0xa02b1741,0x7cbad9a2,0x2180036f,
+	0x50d99c08,0xcb3f4861,0xc26bd765,0x64a3f6ab,
+	0x80342676,0x25a75e7b,0xe4e6d1fc,0x20c710e6,
+	0xcdf0b680,0x17844d3b,0x31eef84d,0x7e0824e4,
+	0x2ccb49eb,0x846a3bae,0x8ff77888,0xee5d60f6,
+	0x7af75673,0x2fdd5cdb,0xa11631c1,0x30f66f43,
+	0xb3faec54,0x157fd7fa,0xef8579cc,0xd152de58,
+	0xdb2ffd5e,0x8f32ce19,0x306af97a,0x02f03ef8,
+	0x99319ad5,0xc242fa0f,0xa7e3ebb0,0xc68e4906,
+	0xb8da230c,0x80823028,0xdcdef3c8,0xd35fb171,
+	0x088a1bc8,0xbec0c560,0x61a3c9e8,0xbca8f54d,
+	0xc72feffa,0x22822e99,0x82c570b4,0xd8d94e89,
+	0x8b1c34bc,0x301e16e6,0x273be979,0xb0ffeaa6,
+	0x61d9b8c6,0x00b24869,0xb7ffce3f,0x08dc283b,
+	0x43daf65a,0xf7e19798,0x7619b72f,0x8f1c9ba4,
+	0xdc8637a0,0x16a7d3b1,0x9fc393b7,0xa7136eeb,
+	0xc6bcc63e,0x1a513742,0xef6828bc,0x520365d6,
+	0x2d6a77ab,0x3527ed4b,0x821fd216,0x095c6e2e,
+	0xdb92f2fb,0x5eea29cb,0x145892f5,0x91584f7f,
+	0x5483697b,0x2667a8cc,0x85196048,0x8c4bacea,
+	0x833860d4,0x0d23e0f9,0x6c387e8a,0x0ae6d249,
+	0xb284600c,0xd835731d,0xdcb1c647,0xac4c56ea,
+	0x3ebd81b3,0x230eabb0,0x6438bc87,0xf0b5b1fa,
+	0x8f5ea2b3,0xfc184642,0x0a036b7a,0x4fb089bd,
+	0x649da589,0xa345415e,0x5c038323,0x3e5d3bb9,
+	0x43d79572,0x7e6dd07c,0x06dfdf1e,0x6c6cc4ef,
+	0x7160a539,0x73bfbe70,0x83877605,0x4523ecf1,
+	};
+OPENSSL_GLOBAL const CAST_LONG CAST_S_table2[256]={
+	0x8defc240,0x25fa5d9f,0xeb903dbf,0xe810c907,
+	0x47607fff,0x369fe44b,0x8c1fc644,0xaececa90,
+	0xbeb1f9bf,0xeefbcaea,0xe8cf1950,0x51df07ae,
+	0x920e8806,0xf0ad0548,0xe13c8d83,0x927010d5,
+	0x11107d9f,0x07647db9,0xb2e3e4d4,0x3d4f285e,
+	0xb9afa820,0xfade82e0,0xa067268b,0x8272792e,
+	0x553fb2c0,0x489ae22b,0xd4ef9794,0x125e3fbc,
+	0x21fffcee,0x825b1bfd,0x9255c5ed,0x1257a240,
+	0x4e1a8302,0xbae07fff,0x528246e7,0x8e57140e,
+	0x3373f7bf,0x8c9f8188,0xa6fc4ee8,0xc982b5a5,
+	0xa8c01db7,0x579fc264,0x67094f31,0xf2bd3f5f,
+	0x40fff7c1,0x1fb78dfc,0x8e6bd2c1,0x437be59b,
+	0x99b03dbf,0xb5dbc64b,0x638dc0e6,0x55819d99,
+	0xa197c81c,0x4a012d6e,0xc5884a28,0xccc36f71,
+	0xb843c213,0x6c0743f1,0x8309893c,0x0feddd5f,
+	0x2f7fe850,0xd7c07f7e,0x02507fbf,0x5afb9a04,
+	0xa747d2d0,0x1651192e,0xaf70bf3e,0x58c31380,
+	0x5f98302e,0x727cc3c4,0x0a0fb402,0x0f7fef82,
+	0x8c96fdad,0x5d2c2aae,0x8ee99a49,0x50da88b8,
+	0x8427f4a0,0x1eac5790,0x796fb449,0x8252dc15,
+	0xefbd7d9b,0xa672597d,0xada840d8,0x45f54504,
+	0xfa5d7403,0xe83ec305,0x4f91751a,0x925669c2,
+	0x23efe941,0xa903f12e,0x60270df2,0x0276e4b6,
+	0x94fd6574,0x927985b2,0x8276dbcb,0x02778176,
+	0xf8af918d,0x4e48f79e,0x8f616ddf,0xe29d840e,
+	0x842f7d83,0x340ce5c8,0x96bbb682,0x93b4b148,
+	0xef303cab,0x984faf28,0x779faf9b,0x92dc560d,
+	0x224d1e20,0x8437aa88,0x7d29dc96,0x2756d3dc,
+	0x8b907cee,0xb51fd240,0xe7c07ce3,0xe566b4a1,
+	0xc3e9615e,0x3cf8209d,0x6094d1e3,0xcd9ca341,
+	0x5c76460e,0x00ea983b,0xd4d67881,0xfd47572c,
+	0xf76cedd9,0xbda8229c,0x127dadaa,0x438a074e,
+	0x1f97c090,0x081bdb8a,0x93a07ebe,0xb938ca15,
+	0x97b03cff,0x3dc2c0f8,0x8d1ab2ec,0x64380e51,
+	0x68cc7bfb,0xd90f2788,0x12490181,0x5de5ffd4,
+	0xdd7ef86a,0x76a2e214,0xb9a40368,0x925d958f,
+	0x4b39fffa,0xba39aee9,0xa4ffd30b,0xfaf7933b,
+	0x6d498623,0x193cbcfa,0x27627545,0x825cf47a,
+	0x61bd8ba0,0xd11e42d1,0xcead04f4,0x127ea392,
+	0x10428db7,0x8272a972,0x9270c4a8,0x127de50b,
+	0x285ba1c8,0x3c62f44f,0x35c0eaa5,0xe805d231,
+	0x428929fb,0xb4fcdf82,0x4fb66a53,0x0e7dc15b,
+	0x1f081fab,0x108618ae,0xfcfd086d,0xf9ff2889,
+	0x694bcc11,0x236a5cae,0x12deca4d,0x2c3f8cc5,
+	0xd2d02dfe,0xf8ef5896,0xe4cf52da,0x95155b67,
+	0x494a488c,0xb9b6a80c,0x5c8f82bc,0x89d36b45,
+	0x3a609437,0xec00c9a9,0x44715253,0x0a874b49,
+	0xd773bc40,0x7c34671c,0x02717ef6,0x4feb5536,
+	0xa2d02fff,0xd2bf60c4,0xd43f03c0,0x50b4ef6d,
+	0x07478cd1,0x006e1888,0xa2e53f55,0xb9e6d4bc,
+	0xa2048016,0x97573833,0xd7207d67,0xde0f8f3d,
+	0x72f87b33,0xabcc4f33,0x7688c55d,0x7b00a6b0,
+	0x947b0001,0x570075d2,0xf9bb88f8,0x8942019e,
+	0x4264a5ff,0x856302e0,0x72dbd92b,0xee971b69,
+	0x6ea22fde,0x5f08ae2b,0xaf7a616d,0xe5c98767,
+	0xcf1febd2,0x61efc8c2,0xf1ac2571,0xcc8239c2,
+	0x67214cb8,0xb1e583d1,0xb7dc3e62,0x7f10bdce,
+	0xf90a5c38,0x0ff0443d,0x606e6dc6,0x60543a49,
+	0x5727c148,0x2be98a1d,0x8ab41738,0x20e1be24,
+	0xaf96da0f,0x68458425,0x99833be5,0x600d457d,
+	0x282f9350,0x8334b362,0xd91d1120,0x2b6d8da0,
+	0x642b1e31,0x9c305a00,0x52bce688,0x1b03588a,
+	0xf7baefd5,0x4142ed9c,0xa4315c11,0x83323ec5,
+	0xdfef4636,0xa133c501,0xe9d3531c,0xee353783,
+	};
+OPENSSL_GLOBAL const CAST_LONG CAST_S_table3[256]={
+	0x9db30420,0x1fb6e9de,0xa7be7bef,0xd273a298,
+	0x4a4f7bdb,0x64ad8c57,0x85510443,0xfa020ed1,
+	0x7e287aff,0xe60fb663,0x095f35a1,0x79ebf120,
+	0xfd059d43,0x6497b7b1,0xf3641f63,0x241e4adf,
+	0x28147f5f,0x4fa2b8cd,0xc9430040,0x0cc32220,
+	0xfdd30b30,0xc0a5374f,0x1d2d00d9,0x24147b15,
+	0xee4d111a,0x0fca5167,0x71ff904c,0x2d195ffe,
+	0x1a05645f,0x0c13fefe,0x081b08ca,0x05170121,
+	0x80530100,0xe83e5efe,0xac9af4f8,0x7fe72701,
+	0xd2b8ee5f,0x06df4261,0xbb9e9b8a,0x7293ea25,
+	0xce84ffdf,0xf5718801,0x3dd64b04,0xa26f263b,
+	0x7ed48400,0x547eebe6,0x446d4ca0,0x6cf3d6f5,
+	0x2649abdf,0xaea0c7f5,0x36338cc1,0x503f7e93,
+	0xd3772061,0x11b638e1,0x72500e03,0xf80eb2bb,
+	0xabe0502e,0xec8d77de,0x57971e81,0xe14f6746,
+	0xc9335400,0x6920318f,0x081dbb99,0xffc304a5,
+	0x4d351805,0x7f3d5ce3,0xa6c866c6,0x5d5bcca9,
+	0xdaec6fea,0x9f926f91,0x9f46222f,0x3991467d,
+	0xa5bf6d8e,0x1143c44f,0x43958302,0xd0214eeb,
+	0x022083b8,0x3fb6180c,0x18f8931e,0x281658e6,
+	0x26486e3e,0x8bd78a70,0x7477e4c1,0xb506e07c,
+	0xf32d0a25,0x79098b02,0xe4eabb81,0x28123b23,
+	0x69dead38,0x1574ca16,0xdf871b62,0x211c40b7,
+	0xa51a9ef9,0x0014377b,0x041e8ac8,0x09114003,
+	0xbd59e4d2,0xe3d156d5,0x4fe876d5,0x2f91a340,
+	0x557be8de,0x00eae4a7,0x0ce5c2ec,0x4db4bba6,
+	0xe756bdff,0xdd3369ac,0xec17b035,0x06572327,
+	0x99afc8b0,0x56c8c391,0x6b65811c,0x5e146119,
+	0x6e85cb75,0xbe07c002,0xc2325577,0x893ff4ec,
+	0x5bbfc92d,0xd0ec3b25,0xb7801ab7,0x8d6d3b24,
+	0x20c763ef,0xc366a5fc,0x9c382880,0x0ace3205,
+	0xaac9548a,0xeca1d7c7,0x041afa32,0x1d16625a,
+	0x6701902c,0x9b757a54,0x31d477f7,0x9126b031,
+	0x36cc6fdb,0xc70b8b46,0xd9e66a48,0x56e55a79,
+	0x026a4ceb,0x52437eff,0x2f8f76b4,0x0df980a5,
+	0x8674cde3,0xedda04eb,0x17a9be04,0x2c18f4df,
+	0xb7747f9d,0xab2af7b4,0xefc34d20,0x2e096b7c,
+	0x1741a254,0xe5b6a035,0x213d42f6,0x2c1c7c26,
+	0x61c2f50f,0x6552daf9,0xd2c231f8,0x25130f69,
+	0xd8167fa2,0x0418f2c8,0x001a96a6,0x0d1526ab,
+	0x63315c21,0x5e0a72ec,0x49bafefd,0x187908d9,
+	0x8d0dbd86,0x311170a7,0x3e9b640c,0xcc3e10d7,
+	0xd5cad3b6,0x0caec388,0xf73001e1,0x6c728aff,
+	0x71eae2a1,0x1f9af36e,0xcfcbd12f,0xc1de8417,
+	0xac07be6b,0xcb44a1d8,0x8b9b0f56,0x013988c3,
+	0xb1c52fca,0xb4be31cd,0xd8782806,0x12a3a4e2,
+	0x6f7de532,0x58fd7eb6,0xd01ee900,0x24adffc2,
+	0xf4990fc5,0x9711aac5,0x001d7b95,0x82e5e7d2,
+	0x109873f6,0x00613096,0xc32d9521,0xada121ff,
+	0x29908415,0x7fbb977f,0xaf9eb3db,0x29c9ed2a,
+	0x5ce2a465,0xa730f32c,0xd0aa3fe8,0x8a5cc091,
+	0xd49e2ce7,0x0ce454a9,0xd60acd86,0x015f1919,
+	0x77079103,0xdea03af6,0x78a8565e,0xdee356df,
+	0x21f05cbe,0x8b75e387,0xb3c50651,0xb8a5c3ef,
+	0xd8eeb6d2,0xe523be77,0xc2154529,0x2f69efdf,
+	0xafe67afb,0xf470c4b2,0xf3e0eb5b,0xd6cc9876,
+	0x39e4460c,0x1fda8538,0x1987832f,0xca007367,
+	0xa99144f8,0x296b299e,0x492fc295,0x9266beab,
+	0xb5676e69,0x9bd3ddda,0xdf7e052f,0xdb25701c,
+	0x1b5e51ee,0xf65324e6,0x6afce36c,0x0316cc04,
+	0x8644213e,0xb7dc59d0,0x7965291f,0xccd6fd43,
+	0x41823979,0x932bcdf6,0xb657c34d,0x4edfd282,
+	0x7ae5290c,0x3cb9536b,0x851e20fe,0x9833557e,
+	0x13ecf0b0,0xd3ffb372,0x3f85c5c1,0x0aef7ed2,
+	};
+OPENSSL_GLOBAL const CAST_LONG CAST_S_table4[256]={
+	0x7ec90c04,0x2c6e74b9,0x9b0e66df,0xa6337911,
+	0xb86a7fff,0x1dd358f5,0x44dd9d44,0x1731167f,
+	0x08fbf1fa,0xe7f511cc,0xd2051b00,0x735aba00,
+	0x2ab722d8,0x386381cb,0xacf6243a,0x69befd7a,
+	0xe6a2e77f,0xf0c720cd,0xc4494816,0xccf5c180,
+	0x38851640,0x15b0a848,0xe68b18cb,0x4caadeff,
+	0x5f480a01,0x0412b2aa,0x259814fc,0x41d0efe2,
+	0x4e40b48d,0x248eb6fb,0x8dba1cfe,0x41a99b02,
+	0x1a550a04,0xba8f65cb,0x7251f4e7,0x95a51725,
+	0xc106ecd7,0x97a5980a,0xc539b9aa,0x4d79fe6a,
+	0xf2f3f763,0x68af8040,0xed0c9e56,0x11b4958b,
+	0xe1eb5a88,0x8709e6b0,0xd7e07156,0x4e29fea7,
+	0x6366e52d,0x02d1c000,0xc4ac8e05,0x9377f571,
+	0x0c05372a,0x578535f2,0x2261be02,0xd642a0c9,
+	0xdf13a280,0x74b55bd2,0x682199c0,0xd421e5ec,
+	0x53fb3ce8,0xc8adedb3,0x28a87fc9,0x3d959981,
+	0x5c1ff900,0xfe38d399,0x0c4eff0b,0x062407ea,
+	0xaa2f4fb1,0x4fb96976,0x90c79505,0xb0a8a774,
+	0xef55a1ff,0xe59ca2c2,0xa6b62d27,0xe66a4263,
+	0xdf65001f,0x0ec50966,0xdfdd55bc,0x29de0655,
+	0x911e739a,0x17af8975,0x32c7911c,0x89f89468,
+	0x0d01e980,0x524755f4,0x03b63cc9,0x0cc844b2,
+	0xbcf3f0aa,0x87ac36e9,0xe53a7426,0x01b3d82b,
+	0x1a9e7449,0x64ee2d7e,0xcddbb1da,0x01c94910,
+	0xb868bf80,0x0d26f3fd,0x9342ede7,0x04a5c284,
+	0x636737b6,0x50f5b616,0xf24766e3,0x8eca36c1,
+	0x136e05db,0xfef18391,0xfb887a37,0xd6e7f7d4,
+	0xc7fb7dc9,0x3063fcdf,0xb6f589de,0xec2941da,
+	0x26e46695,0xb7566419,0xf654efc5,0xd08d58b7,
+	0x48925401,0xc1bacb7f,0xe5ff550f,0xb6083049,
+	0x5bb5d0e8,0x87d72e5a,0xab6a6ee1,0x223a66ce,
+	0xc62bf3cd,0x9e0885f9,0x68cb3e47,0x086c010f,
+	0xa21de820,0xd18b69de,0xf3f65777,0xfa02c3f6,
+	0x407edac3,0xcbb3d550,0x1793084d,0xb0d70eba,
+	0x0ab378d5,0xd951fb0c,0xded7da56,0x4124bbe4,
+	0x94ca0b56,0x0f5755d1,0xe0e1e56e,0x6184b5be,
+	0x580a249f,0x94f74bc0,0xe327888e,0x9f7b5561,
+	0xc3dc0280,0x05687715,0x646c6bd7,0x44904db3,
+	0x66b4f0a3,0xc0f1648a,0x697ed5af,0x49e92ff6,
+	0x309e374f,0x2cb6356a,0x85808573,0x4991f840,
+	0x76f0ae02,0x083be84d,0x28421c9a,0x44489406,
+	0x736e4cb8,0xc1092910,0x8bc95fc6,0x7d869cf4,
+	0x134f616f,0x2e77118d,0xb31b2be1,0xaa90b472,
+	0x3ca5d717,0x7d161bba,0x9cad9010,0xaf462ba2,
+	0x9fe459d2,0x45d34559,0xd9f2da13,0xdbc65487,
+	0xf3e4f94e,0x176d486f,0x097c13ea,0x631da5c7,
+	0x445f7382,0x175683f4,0xcdc66a97,0x70be0288,
+	0xb3cdcf72,0x6e5dd2f3,0x20936079,0x459b80a5,
+	0xbe60e2db,0xa9c23101,0xeba5315c,0x224e42f2,
+	0x1c5c1572,0xf6721b2c,0x1ad2fff3,0x8c25404e,
+	0x324ed72f,0x4067b7fd,0x0523138e,0x5ca3bc78,
+	0xdc0fd66e,0x75922283,0x784d6b17,0x58ebb16e,
+	0x44094f85,0x3f481d87,0xfcfeae7b,0x77b5ff76,
+	0x8c2302bf,0xaaf47556,0x5f46b02a,0x2b092801,
+	0x3d38f5f7,0x0ca81f36,0x52af4a8a,0x66d5e7c0,
+	0xdf3b0874,0x95055110,0x1b5ad7a8,0xf61ed5ad,
+	0x6cf6e479,0x20758184,0xd0cefa65,0x88f7be58,
+	0x4a046826,0x0ff6f8f3,0xa09c7f70,0x5346aba0,
+	0x5ce96c28,0xe176eda3,0x6bac307f,0x376829d2,
+	0x85360fa9,0x17e3fe2a,0x24b79767,0xf5a96b20,
+	0xd6cd2595,0x68ff1ebf,0x7555442c,0xf19f06be,
+	0xf9e0659a,0xeeb9491d,0x34010718,0xbb30cab8,
+	0xe822fe15,0x88570983,0x750e6249,0xda627e55,
+	0x5e76ffa8,0xb1534546,0x6d47de08,0xefe9e7d4,
+	};
+OPENSSL_GLOBAL const CAST_LONG CAST_S_table5[256]={
+	0xf6fa8f9d,0x2cac6ce1,0x4ca34867,0xe2337f7c,
+	0x95db08e7,0x016843b4,0xeced5cbc,0x325553ac,
+	0xbf9f0960,0xdfa1e2ed,0x83f0579d,0x63ed86b9,
+	0x1ab6a6b8,0xde5ebe39,0xf38ff732,0x8989b138,
+	0x33f14961,0xc01937bd,0xf506c6da,0xe4625e7e,
+	0xa308ea99,0x4e23e33c,0x79cbd7cc,0x48a14367,
+	0xa3149619,0xfec94bd5,0xa114174a,0xeaa01866,
+	0xa084db2d,0x09a8486f,0xa888614a,0x2900af98,
+	0x01665991,0xe1992863,0xc8f30c60,0x2e78ef3c,
+	0xd0d51932,0xcf0fec14,0xf7ca07d2,0xd0a82072,
+	0xfd41197e,0x9305a6b0,0xe86be3da,0x74bed3cd,
+	0x372da53c,0x4c7f4448,0xdab5d440,0x6dba0ec3,
+	0x083919a7,0x9fbaeed9,0x49dbcfb0,0x4e670c53,
+	0x5c3d9c01,0x64bdb941,0x2c0e636a,0xba7dd9cd,
+	0xea6f7388,0xe70bc762,0x35f29adb,0x5c4cdd8d,
+	0xf0d48d8c,0xb88153e2,0x08a19866,0x1ae2eac8,
+	0x284caf89,0xaa928223,0x9334be53,0x3b3a21bf,
+	0x16434be3,0x9aea3906,0xefe8c36e,0xf890cdd9,
+	0x80226dae,0xc340a4a3,0xdf7e9c09,0xa694a807,
+	0x5b7c5ecc,0x221db3a6,0x9a69a02f,0x68818a54,
+	0xceb2296f,0x53c0843a,0xfe893655,0x25bfe68a,
+	0xb4628abc,0xcf222ebf,0x25ac6f48,0xa9a99387,
+	0x53bddb65,0xe76ffbe7,0xe967fd78,0x0ba93563,
+	0x8e342bc1,0xe8a11be9,0x4980740d,0xc8087dfc,
+	0x8de4bf99,0xa11101a0,0x7fd37975,0xda5a26c0,
+	0xe81f994f,0x9528cd89,0xfd339fed,0xb87834bf,
+	0x5f04456d,0x22258698,0xc9c4c83b,0x2dc156be,
+	0x4f628daa,0x57f55ec5,0xe2220abe,0xd2916ebf,
+	0x4ec75b95,0x24f2c3c0,0x42d15d99,0xcd0d7fa0,
+	0x7b6e27ff,0xa8dc8af0,0x7345c106,0xf41e232f,
+	0x35162386,0xe6ea8926,0x3333b094,0x157ec6f2,
+	0x372b74af,0x692573e4,0xe9a9d848,0xf3160289,
+	0x3a62ef1d,0xa787e238,0xf3a5f676,0x74364853,
+	0x20951063,0x4576698d,0xb6fad407,0x592af950,
+	0x36f73523,0x4cfb6e87,0x7da4cec0,0x6c152daa,
+	0xcb0396a8,0xc50dfe5d,0xfcd707ab,0x0921c42f,
+	0x89dff0bb,0x5fe2be78,0x448f4f33,0x754613c9,
+	0x2b05d08d,0x48b9d585,0xdc049441,0xc8098f9b,
+	0x7dede786,0xc39a3373,0x42410005,0x6a091751,
+	0x0ef3c8a6,0x890072d6,0x28207682,0xa9a9f7be,
+	0xbf32679d,0xd45b5b75,0xb353fd00,0xcbb0e358,
+	0x830f220a,0x1f8fb214,0xd372cf08,0xcc3c4a13,
+	0x8cf63166,0x061c87be,0x88c98f88,0x6062e397,
+	0x47cf8e7a,0xb6c85283,0x3cc2acfb,0x3fc06976,
+	0x4e8f0252,0x64d8314d,0xda3870e3,0x1e665459,
+	0xc10908f0,0x513021a5,0x6c5b68b7,0x822f8aa0,
+	0x3007cd3e,0x74719eef,0xdc872681,0x073340d4,
+	0x7e432fd9,0x0c5ec241,0x8809286c,0xf592d891,
+	0x08a930f6,0x957ef305,0xb7fbffbd,0xc266e96f,
+	0x6fe4ac98,0xb173ecc0,0xbc60b42a,0x953498da,
+	0xfba1ae12,0x2d4bd736,0x0f25faab,0xa4f3fceb,
+	0xe2969123,0x257f0c3d,0x9348af49,0x361400bc,
+	0xe8816f4a,0x3814f200,0xa3f94043,0x9c7a54c2,
+	0xbc704f57,0xda41e7f9,0xc25ad33a,0x54f4a084,
+	0xb17f5505,0x59357cbe,0xedbd15c8,0x7f97c5ab,
+	0xba5ac7b5,0xb6f6deaf,0x3a479c3a,0x5302da25,
+	0x653d7e6a,0x54268d49,0x51a477ea,0x5017d55b,
+	0xd7d25d88,0x44136c76,0x0404a8c8,0xb8e5a121,
+	0xb81a928a,0x60ed5869,0x97c55b96,0xeaec991b,
+	0x29935913,0x01fdb7f1,0x088e8dfa,0x9ab6f6f5,
+	0x3b4cbf9f,0x4a5de3ab,0xe6051d35,0xa0e1d855,
+	0xd36b4cf1,0xf544edeb,0xb0e93524,0xbebb8fbd,
+	0xa2d762cf,0x49c92f54,0x38b5f331,0x7128a454,
+	0x48392905,0xa65b1db8,0x851c97bd,0xd675cf2f,
+	};
+OPENSSL_GLOBAL const CAST_LONG CAST_S_table6[256]={
+	0x85e04019,0x332bf567,0x662dbfff,0xcfc65693,
+	0x2a8d7f6f,0xab9bc912,0xde6008a1,0x2028da1f,
+	0x0227bce7,0x4d642916,0x18fac300,0x50f18b82,
+	0x2cb2cb11,0xb232e75c,0x4b3695f2,0xb28707de,
+	0xa05fbcf6,0xcd4181e9,0xe150210c,0xe24ef1bd,
+	0xb168c381,0xfde4e789,0x5c79b0d8,0x1e8bfd43,
+	0x4d495001,0x38be4341,0x913cee1d,0x92a79c3f,
+	0x089766be,0xbaeeadf4,0x1286becf,0xb6eacb19,
+	0x2660c200,0x7565bde4,0x64241f7a,0x8248dca9,
+	0xc3b3ad66,0x28136086,0x0bd8dfa8,0x356d1cf2,
+	0x107789be,0xb3b2e9ce,0x0502aa8f,0x0bc0351e,
+	0x166bf52a,0xeb12ff82,0xe3486911,0xd34d7516,
+	0x4e7b3aff,0x5f43671b,0x9cf6e037,0x4981ac83,
+	0x334266ce,0x8c9341b7,0xd0d854c0,0xcb3a6c88,
+	0x47bc2829,0x4725ba37,0xa66ad22b,0x7ad61f1e,
+	0x0c5cbafa,0x4437f107,0xb6e79962,0x42d2d816,
+	0x0a961288,0xe1a5c06e,0x13749e67,0x72fc081a,
+	0xb1d139f7,0xf9583745,0xcf19df58,0xbec3f756,
+	0xc06eba30,0x07211b24,0x45c28829,0xc95e317f,
+	0xbc8ec511,0x38bc46e9,0xc6e6fa14,0xbae8584a,
+	0xad4ebc46,0x468f508b,0x7829435f,0xf124183b,
+	0x821dba9f,0xaff60ff4,0xea2c4e6d,0x16e39264,
+	0x92544a8b,0x009b4fc3,0xaba68ced,0x9ac96f78,
+	0x06a5b79a,0xb2856e6e,0x1aec3ca9,0xbe838688,
+	0x0e0804e9,0x55f1be56,0xe7e5363b,0xb3a1f25d,
+	0xf7debb85,0x61fe033c,0x16746233,0x3c034c28,
+	0xda6d0c74,0x79aac56c,0x3ce4e1ad,0x51f0c802,
+	0x98f8f35a,0x1626a49f,0xeed82b29,0x1d382fe3,
+	0x0c4fb99a,0xbb325778,0x3ec6d97b,0x6e77a6a9,
+	0xcb658b5c,0xd45230c7,0x2bd1408b,0x60c03eb7,
+	0xb9068d78,0xa33754f4,0xf430c87d,0xc8a71302,
+	0xb96d8c32,0xebd4e7be,0xbe8b9d2d,0x7979fb06,
+	0xe7225308,0x8b75cf77,0x11ef8da4,0xe083c858,
+	0x8d6b786f,0x5a6317a6,0xfa5cf7a0,0x5dda0033,
+	0xf28ebfb0,0xf5b9c310,0xa0eac280,0x08b9767a,
+	0xa3d9d2b0,0x79d34217,0x021a718d,0x9ac6336a,
+	0x2711fd60,0x438050e3,0x069908a8,0x3d7fedc4,
+	0x826d2bef,0x4eeb8476,0x488dcf25,0x36c9d566,
+	0x28e74e41,0xc2610aca,0x3d49a9cf,0xbae3b9df,
+	0xb65f8de6,0x92aeaf64,0x3ac7d5e6,0x9ea80509,
+	0xf22b017d,0xa4173f70,0xdd1e16c3,0x15e0d7f9,
+	0x50b1b887,0x2b9f4fd5,0x625aba82,0x6a017962,
+	0x2ec01b9c,0x15488aa9,0xd716e740,0x40055a2c,
+	0x93d29a22,0xe32dbf9a,0x058745b9,0x3453dc1e,
+	0xd699296e,0x496cff6f,0x1c9f4986,0xdfe2ed07,
+	0xb87242d1,0x19de7eae,0x053e561a,0x15ad6f8c,
+	0x66626c1c,0x7154c24c,0xea082b2a,0x93eb2939,
+	0x17dcb0f0,0x58d4f2ae,0x9ea294fb,0x52cf564c,
+	0x9883fe66,0x2ec40581,0x763953c3,0x01d6692e,
+	0xd3a0c108,0xa1e7160e,0xe4f2dfa6,0x693ed285,
+	0x74904698,0x4c2b0edd,0x4f757656,0x5d393378,
+	0xa132234f,0x3d321c5d,0xc3f5e194,0x4b269301,
+	0xc79f022f,0x3c997e7e,0x5e4f9504,0x3ffafbbd,
+	0x76f7ad0e,0x296693f4,0x3d1fce6f,0xc61e45be,
+	0xd3b5ab34,0xf72bf9b7,0x1b0434c0,0x4e72b567,
+	0x5592a33d,0xb5229301,0xcfd2a87f,0x60aeb767,
+	0x1814386b,0x30bcc33d,0x38a0c07d,0xfd1606f2,
+	0xc363519b,0x589dd390,0x5479f8e6,0x1cb8d647,
+	0x97fd61a9,0xea7759f4,0x2d57539d,0x569a58cf,
+	0xe84e63ad,0x462e1b78,0x6580f87e,0xf3817914,
+	0x91da55f4,0x40a230f3,0xd1988f35,0xb6e318d2,
+	0x3ffa50bc,0x3d40f021,0xc3c0bdae,0x4958c24c,
+	0x518f36b2,0x84b1d370,0x0fedce83,0x878ddada,
+	0xf2a279c7,0x94e01be8,0x90716f4b,0x954b8aa3,
+	};
+OPENSSL_GLOBAL const CAST_LONG CAST_S_table7[256]={
+	0xe216300d,0xbbddfffc,0xa7ebdabd,0x35648095,
+	0x7789f8b7,0xe6c1121b,0x0e241600,0x052ce8b5,
+	0x11a9cfb0,0xe5952f11,0xece7990a,0x9386d174,
+	0x2a42931c,0x76e38111,0xb12def3a,0x37ddddfc,
+	0xde9adeb1,0x0a0cc32c,0xbe197029,0x84a00940,
+	0xbb243a0f,0xb4d137cf,0xb44e79f0,0x049eedfd,
+	0x0b15a15d,0x480d3168,0x8bbbde5a,0x669ded42,
+	0xc7ece831,0x3f8f95e7,0x72df191b,0x7580330d,
+	0x94074251,0x5c7dcdfa,0xabbe6d63,0xaa402164,
+	0xb301d40a,0x02e7d1ca,0x53571dae,0x7a3182a2,
+	0x12a8ddec,0xfdaa335d,0x176f43e8,0x71fb46d4,
+	0x38129022,0xce949ad4,0xb84769ad,0x965bd862,
+	0x82f3d055,0x66fb9767,0x15b80b4e,0x1d5b47a0,
+	0x4cfde06f,0xc28ec4b8,0x57e8726e,0x647a78fc,
+	0x99865d44,0x608bd593,0x6c200e03,0x39dc5ff6,
+	0x5d0b00a3,0xae63aff2,0x7e8bd632,0x70108c0c,
+	0xbbd35049,0x2998df04,0x980cf42a,0x9b6df491,
+	0x9e7edd53,0x06918548,0x58cb7e07,0x3b74ef2e,
+	0x522fffb1,0xd24708cc,0x1c7e27cd,0xa4eb215b,
+	0x3cf1d2e2,0x19b47a38,0x424f7618,0x35856039,
+	0x9d17dee7,0x27eb35e6,0xc9aff67b,0x36baf5b8,
+	0x09c467cd,0xc18910b1,0xe11dbf7b,0x06cd1af8,
+	0x7170c608,0x2d5e3354,0xd4de495a,0x64c6d006,
+	0xbcc0c62c,0x3dd00db3,0x708f8f34,0x77d51b42,
+	0x264f620f,0x24b8d2bf,0x15c1b79e,0x46a52564,
+	0xf8d7e54e,0x3e378160,0x7895cda5,0x859c15a5,
+	0xe6459788,0xc37bc75f,0xdb07ba0c,0x0676a3ab,
+	0x7f229b1e,0x31842e7b,0x24259fd7,0xf8bef472,
+	0x835ffcb8,0x6df4c1f2,0x96f5b195,0xfd0af0fc,
+	0xb0fe134c,0xe2506d3d,0x4f9b12ea,0xf215f225,
+	0xa223736f,0x9fb4c428,0x25d04979,0x34c713f8,
+	0xc4618187,0xea7a6e98,0x7cd16efc,0x1436876c,
+	0xf1544107,0xbedeee14,0x56e9af27,0xa04aa441,
+	0x3cf7c899,0x92ecbae6,0xdd67016d,0x151682eb,
+	0xa842eedf,0xfdba60b4,0xf1907b75,0x20e3030f,
+	0x24d8c29e,0xe139673b,0xefa63fb8,0x71873054,
+	0xb6f2cf3b,0x9f326442,0xcb15a4cc,0xb01a4504,
+	0xf1e47d8d,0x844a1be5,0xbae7dfdc,0x42cbda70,
+	0xcd7dae0a,0x57e85b7a,0xd53f5af6,0x20cf4d8c,
+	0xcea4d428,0x79d130a4,0x3486ebfb,0x33d3cddc,
+	0x77853b53,0x37effcb5,0xc5068778,0xe580b3e6,
+	0x4e68b8f4,0xc5c8b37e,0x0d809ea2,0x398feb7c,
+	0x132a4f94,0x43b7950e,0x2fee7d1c,0x223613bd,
+	0xdd06caa2,0x37df932b,0xc4248289,0xacf3ebc3,
+	0x5715f6b7,0xef3478dd,0xf267616f,0xc148cbe4,
+	0x9052815e,0x5e410fab,0xb48a2465,0x2eda7fa4,
+	0xe87b40e4,0xe98ea084,0x5889e9e1,0xefd390fc,
+	0xdd07d35b,0xdb485694,0x38d7e5b2,0x57720101,
+	0x730edebc,0x5b643113,0x94917e4f,0x503c2fba,
+	0x646f1282,0x7523d24a,0xe0779695,0xf9c17a8f,
+	0x7a5b2121,0xd187b896,0x29263a4d,0xba510cdf,
+	0x81f47c9f,0xad1163ed,0xea7b5965,0x1a00726e,
+	0x11403092,0x00da6d77,0x4a0cdd61,0xad1f4603,
+	0x605bdfb0,0x9eedc364,0x22ebe6a8,0xcee7d28a,
+	0xa0e736a0,0x5564a6b9,0x10853209,0xc7eb8f37,
+	0x2de705ca,0x8951570f,0xdf09822b,0xbd691a6c,
+	0xaa12e4f2,0x87451c0f,0xe0f6a27a,0x3ada4819,
+	0x4cf1764f,0x0d771c2b,0x67cdb156,0x350d8384,
+	0x5938fa0f,0x42399ef3,0x36997b07,0x0e84093d,
+	0x4aa93e61,0x8360d87b,0x1fa98b0c,0x1149382c,
+	0xe97625a5,0x0614d1b7,0x0e25244b,0x0c768347,
+	0x589e8d82,0x0d2059d1,0xa466bb1e,0xf8da0a82,
+	0x04f19130,0xba6e4ec0,0x99265164,0x1ee7230d,
+	0x50b2ad80,0xeaee6801,0x8db2a283,0xea8bf59e,
+	};
diff --git a/openssl/crypto/cast/cast_spd.c b/openssl/crypto/cast/cast_spd.c
new file mode 100644
index 0000000..d650af4
--- /dev/null
+++ b/openssl/crypto/cast/cast_spd.c
@@ -0,0 +1,278 @@
+/* crypto/cast/cast_spd.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
+/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
+
+#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
+#define TIMES
+#endif
+
+#include <stdio.h>
+
+#include <openssl/e_os2.h>
+#include OPENSSL_UNISTD_IO
+OPENSSL_DECLARE_EXIT
+
+#ifndef OPENSSL_SYS_NETWARE
+#include <signal.h>
+#endif
+
+#ifndef _IRIX
+#include <time.h>
+#endif
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+#endif
+
+/* Depending on the VMS version, the tms structure is perhaps defined.
+   The __TMS macro will show if it was.  If it wasn't defined, we should
+   undefine TIMES, since that tells the rest of the program how things
+   should be handled.				-- Richard Levitte */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
+#undef TIMES
+#endif
+
+#ifndef TIMES
+#include <sys/timeb.h>
+#endif
+
+#if defined(sun) || defined(__ultrix)
+#define _POSIX_SOURCE
+#include <limits.h>
+#include <sys/param.h>
+#endif
+
+#include <openssl/cast.h>
+
+/* The following if from times(3) man page.  It may need to be changed */
+#ifndef HZ
+#ifndef CLK_TCK
+#define HZ	100.0
+#else /* CLK_TCK */
+#define HZ ((double)CLK_TCK)
+#endif
+#endif
+
+#define BUFSIZE	((long)1024)
+long run=0;
+
+double Time_F(int s);
+#ifdef SIGALRM
+#if defined(__STDC__) || defined(sgi) || defined(_AIX)
+#define SIGRETTYPE void
+#else
+#define SIGRETTYPE int
+#endif
+
+SIGRETTYPE sig_done(int sig);
+SIGRETTYPE sig_done(int sig)
+	{
+	signal(SIGALRM,sig_done);
+	run=0;
+#ifdef LINT
+	sig=sig;
+#endif
+	}
+#endif
+
+#define START	0
+#define STOP	1
+
+double Time_F(int s)
+	{
+	double ret;
+#ifdef TIMES
+	static struct tms tstart,tend;
+
+	if (s == START)
+		{
+		times(&tstart);
+		return(0);
+		}
+	else
+		{
+		times(&tend);
+		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#else /* !times() */
+	static struct timeb tstart,tend;
+	long i;
+
+	if (s == START)
+		{
+		ftime(&tstart);
+		return(0);
+		}
+	else
+		{
+		ftime(&tend);
+		i=(long)tend.millitm-(long)tstart.millitm;
+		ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#endif
+	}
+
+int main(int argc, char **argv)
+	{
+	long count;
+	static unsigned char buf[BUFSIZE];
+	static unsigned char key[] ={
+			0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+			0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
+			};
+	CAST_KEY sch;
+	double a,b,c,d;
+#ifndef SIGALRM
+	long ca,cb,cc;
+#endif
+
+#ifndef TIMES
+	printf("To get the most accurate results, try to run this\n");
+	printf("program when this computer is idle.\n");
+#endif
+
+#ifndef SIGALRM
+	printf("First we calculate the approximate speed ...\n");
+	CAST_set_key(&sch,16,key);
+	count=10;
+	do	{
+		long i;
+		CAST_LONG data[2];
+
+		count*=2;
+		Time_F(START);
+		for (i=count; i; i--)
+			CAST_encrypt(data,&sch);
+		d=Time_F(STOP);
+		} while (d < 3.0);
+	ca=count/512;
+	cb=count;
+	cc=count*8/BUFSIZE+1;
+	printf("Doing CAST_set_key %ld times\n",ca);
+#define COND(d)	(count != (d))
+#define COUNT(d) (d)
+#else
+#define COND(c)	(run)
+#define COUNT(d) (count)
+	signal(SIGALRM,sig_done);
+	printf("Doing CAST_set_key for 10 seconds\n");
+	alarm(10);
+#endif
+
+	Time_F(START);
+	for (count=0,run=1; COND(ca); count+=4)
+		{
+		CAST_set_key(&sch,16,key);
+		CAST_set_key(&sch,16,key);
+		CAST_set_key(&sch,16,key);
+		CAST_set_key(&sch,16,key);
+		}
+	d=Time_F(STOP);
+	printf("%ld cast set_key's in %.2f seconds\n",count,d);
+	a=((double)COUNT(ca))/d;
+
+#ifdef SIGALRM
+	printf("Doing CAST_encrypt's for 10 seconds\n");
+	alarm(10);
+#else
+	printf("Doing CAST_encrypt %ld times\n",cb);
+#endif
+	Time_F(START);
+	for (count=0,run=1; COND(cb); count+=4)
+		{
+		CAST_LONG data[2];
+
+		CAST_encrypt(data,&sch);
+		CAST_encrypt(data,&sch);
+		CAST_encrypt(data,&sch);
+		CAST_encrypt(data,&sch);
+		}
+	d=Time_F(STOP);
+	printf("%ld CAST_encrypt's in %.2f second\n",count,d);
+	b=((double)COUNT(cb)*8)/d;
+
+#ifdef SIGALRM
+	printf("Doing CAST_cbc_encrypt on %ld byte blocks for 10 seconds\n",
+		BUFSIZE);
+	alarm(10);
+#else
+	printf("Doing CAST_cbc_encrypt %ld times on %ld byte blocks\n",cc,
+		BUFSIZE);
+#endif
+	Time_F(START);
+	for (count=0,run=1; COND(cc); count++)
+		CAST_cbc_encrypt(buf,buf,BUFSIZE,&sch,
+			&(key[0]),CAST_ENCRYPT);
+	d=Time_F(STOP);
+	printf("%ld CAST_cbc_encrypt's of %ld byte blocks in %.2f second\n",
+		count,BUFSIZE,d);
+	c=((double)COUNT(cc)*BUFSIZE)/d;
+
+	printf("CAST set_key       per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a);
+	printf("CAST raw ecb bytes per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b);
+	printf("CAST cbc     bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c);
+	exit(0);
+#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
+	return(0);
+#endif
+	}
+
diff --git a/openssl/crypto/cast/castopts.c b/openssl/crypto/cast/castopts.c
new file mode 100644
index 0000000..33b2c7b
--- /dev/null
+++ b/openssl/crypto/cast/castopts.c
@@ -0,0 +1,342 @@
+/* crypto/cast/castopts.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
+ * This is for machines with 64k code segment size restrictions. */
+
+#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC))
+#define TIMES
+#endif
+
+#include <stdio.h>
+
+#include <openssl/e_os2.h>
+#include OPENSSL_UNISTD_IO
+OPENSSL_DECLARE_EXIT
+
+#ifndef OPENSSL_SYS_NETWARE
+#include <signal.h>
+#endif
+
+#ifndef _IRIX
+#include <time.h>
+#endif
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+#endif
+
+/* Depending on the VMS version, the tms structure is perhaps defined.
+   The __TMS macro will show if it was.  If it wasn't defined, we should
+   undefine TIMES, since that tells the rest of the program how things
+   should be handled.				-- Richard Levitte */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
+#undef TIMES
+#endif
+
+#ifndef TIMES
+#include <sys/timeb.h>
+#endif
+
+#if defined(sun) || defined(__ultrix)
+#define _POSIX_SOURCE
+#include <limits.h>
+#include <sys/param.h>
+#endif
+
+#include <openssl/cast.h>
+
+#define CAST_DEFAULT_OPTIONS
+
+#undef E_CAST
+#define CAST_encrypt  CAST_encrypt_normal
+#define CAST_decrypt  CAST_decrypt_normal
+#define CAST_cbc_encrypt  CAST_cbc_encrypt_normal
+#undef HEADER_CAST_LOCL_H
+#include "c_enc.c"
+
+#define CAST_PTR
+#undef CAST_PTR2
+#undef E_CAST
+#undef CAST_encrypt
+#undef CAST_decrypt
+#undef CAST_cbc_encrypt
+#define CAST_encrypt  CAST_encrypt_ptr
+#define CAST_decrypt  CAST_decrypt_ptr
+#define CAST_cbc_encrypt  CAST_cbc_encrypt_ptr
+#undef HEADER_CAST_LOCL_H
+#include "c_enc.c"
+
+#undef CAST_PTR
+#define CAST_PTR2
+#undef E_CAST
+#undef CAST_encrypt
+#undef CAST_decrypt
+#undef CAST_cbc_encrypt
+#define CAST_encrypt  CAST_encrypt_ptr2
+#define CAST_decrypt  CAST_decrypt_ptr2
+#define CAST_cbc_encrypt  CAST_cbc_encrypt_ptr2
+#undef HEADER_CAST_LOCL_H
+#include "c_enc.c"
+
+/* The following if from times(3) man page.  It may need to be changed */
+#ifndef HZ
+# ifndef CLK_TCK
+#  ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
+#   define HZ	100.0
+#  else /* _BSD_CLK_TCK_ */
+#   define HZ ((double)_BSD_CLK_TCK_)
+#  endif
+# else /* CLK_TCK */
+#  define HZ ((double)CLK_TCK)
+# endif
+#endif
+
+#define BUFSIZE	((long)1024)
+long run=0;
+
+double Time_F(int s);
+#ifdef SIGALRM
+#if defined(__STDC__) || defined(sgi)
+#define SIGRETTYPE void
+#else
+#define SIGRETTYPE int
+#endif
+
+SIGRETTYPE sig_done(int sig);
+SIGRETTYPE sig_done(int sig)
+	{
+	signal(SIGALRM,sig_done);
+	run=0;
+#ifdef LINT
+	sig=sig;
+#endif
+	}
+#endif
+
+#define START	0
+#define STOP	1
+
+double Time_F(int s)
+	{
+	double ret;
+#ifdef TIMES
+	static struct tms tstart,tend;
+
+	if (s == START)
+		{
+		times(&tstart);
+		return(0);
+		}
+	else
+		{
+		times(&tend);
+		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#else /* !times() */
+	static struct timeb tstart,tend;
+	long i;
+
+	if (s == START)
+		{
+		ftime(&tstart);
+		return(0);
+		}
+	else
+		{
+		ftime(&tend);
+		i=(long)tend.millitm-(long)tstart.millitm;
+		ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#endif
+	}
+
+#ifdef SIGALRM
+#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
+#else
+#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
+#endif
+	
+#define time_it(func,name,index) \
+	print_name(name); \
+	Time_F(START); \
+	for (count=0,run=1; COND(cb); count+=4) \
+		{ \
+		unsigned long d[2]; \
+		func(d,&sch); \
+		func(d,&sch); \
+		func(d,&sch); \
+		func(d,&sch); \
+		} \
+	tm[index]=Time_F(STOP); \
+	fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
+	tm[index]=((double)COUNT(cb))/tm[index];
+
+#define print_it(name,index) \
+	fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
+		tm[index]*8,1.0e6/tm[index]);
+
+int main(int argc, char **argv)
+	{
+	long count;
+	static unsigned char buf[BUFSIZE];
+	static char key[16]={	0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+				0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
+	CAST_KEY sch;
+	double d,tm[16],max=0;
+	int rank[16];
+	char *str[16];
+	int max_idx=0,i,num=0,j;
+#ifndef SIGALARM
+	long ca,cb,cc,cd,ce;
+#endif
+
+	for (i=0; i<12; i++)
+		{
+		tm[i]=0.0;
+		rank[i]=0;
+		}
+
+#ifndef TIMES
+	fprintf(stderr,"To get the most accurate results, try to run this\n");
+	fprintf(stderr,"program when this computer is idle.\n");
+#endif
+
+	CAST_set_key(&sch,16,key);
+
+#ifndef SIGALRM
+	fprintf(stderr,"First we calculate the approximate speed ...\n");
+	count=10;
+	do	{
+		long i;
+		unsigned long data[2];
+
+		count*=2;
+		Time_F(START);
+		for (i=count; i; i--)
+			CAST_encrypt(data,&sch);
+		d=Time_F(STOP);
+		} while (d < 3.0);
+	ca=count;
+	cb=count*3;
+	cc=count*3*8/BUFSIZE+1;
+	cd=count*8/BUFSIZE+1;
+
+	ce=count/20+1;
+#define COND(d) (count != (d))
+#define COUNT(d) (d)
+#else
+#define COND(c) (run)
+#define COUNT(d) (count)
+        signal(SIGALRM,sig_done);
+        alarm(10);
+#endif
+
+	time_it(CAST_encrypt_normal,	"CAST_encrypt_normal ", 0);
+	time_it(CAST_encrypt_ptr,	"CAST_encrypt_ptr    ", 1);
+	time_it(CAST_encrypt_ptr2,	"CAST_encrypt_ptr2   ", 2);
+	num+=3;
+
+	str[0]="<nothing>";
+	print_it("CAST_encrypt_normal ",0);
+	max=tm[0];
+	max_idx=0;
+	str[1]="ptr      ";
+	print_it("CAST_encrypt_ptr ",1);
+	if (max < tm[1]) { max=tm[1]; max_idx=1; }
+	str[2]="ptr2     ";
+	print_it("CAST_encrypt_ptr2 ",2);
+	if (max < tm[2]) { max=tm[2]; max_idx=2; }
+
+	printf("options    CAST ecb/s\n");
+	printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
+	d=tm[max_idx];
+	tm[max_idx]= -2.0;
+	max= -1.0;
+	for (;;)
+		{
+		for (i=0; i<3; i++)
+			{
+			if (max < tm[i]) { max=tm[i]; j=i; }
+			}
+		if (max < 0.0) break;
+		printf("%s %12.2f  %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
+		tm[j]= -2.0;
+		max= -1.0;
+		}
+
+	switch (max_idx)
+		{
+	case 0:
+		printf("-DCAST_DEFAULT_OPTIONS\n");
+		break;
+	case 1:
+		printf("-DCAST_PTR\n");
+		break;
+	case 2:
+		printf("-DCAST_PTR2\n");
+		break;
+		}
+	exit(0);
+#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
+	return(0);
+#endif
+	}
+
diff --git a/openssl/crypto/cast/casts.cpp b/openssl/crypto/cast/casts.cpp
new file mode 100644
index 0000000..8d7bd46
--- /dev/null
+++ b/openssl/crypto/cast/casts.cpp
@@ -0,0 +1,70 @@
+//
+// gettsc.inl
+//
+// gives access to the Pentium's (secret) cycle counter
+//
+// This software was written by Leonard Janke (janke@unixg.ubc.ca)
+// in 1996-7 and is entered, by him, into the public domain.
+
+#if defined(__WATCOMC__)
+void GetTSC(unsigned long&);
+#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
+#elif defined(__GNUC__)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  asm volatile(".byte 15, 49\n\t"
+	       : "=eax" (tsc)
+	       :
+	       : "%edx", "%eax");
+}
+#elif defined(_MSC_VER)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  unsigned long a;
+  __asm _emit 0fh
+  __asm _emit 31h
+  __asm mov a, eax;
+  tsc=a;
+}
+#endif      
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/cast.h>
+
+void main(int argc,char *argv[])
+	{
+	CAST_KEY key;
+	unsigned long s1,s2,e1,e2;
+	unsigned long data[2];
+	int i,j;
+	static unsigned char d[16]={0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF};
+
+	CAST_set_key(&key, 16,d);
+
+	for (j=0; j<6; j++)
+		{
+		for (i=0; i<1000; i++) /**/
+			{
+			CAST_encrypt(&data[0],&key);
+			GetTSC(s1);
+			CAST_encrypt(&data[0],&key);
+			CAST_encrypt(&data[0],&key);
+			CAST_encrypt(&data[0],&key);
+			GetTSC(e1);
+			GetTSC(s2);
+			CAST_encrypt(&data[0],&key);
+			CAST_encrypt(&data[0],&key);
+			CAST_encrypt(&data[0],&key);
+			CAST_encrypt(&data[0],&key);
+			GetTSC(e2);
+			CAST_encrypt(&data[0],&key);
+			}
+
+		printf("cast %d %d (%d)\n",
+			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
+		}
+	}
+
diff --git a/openssl/crypto/cast/casttest.c b/openssl/crypto/cast/casttest.c
new file mode 100644
index 0000000..0d020d6
--- /dev/null
+++ b/openssl/crypto/cast/casttest.c
@@ -0,0 +1,233 @@
+/* crypto/cast/casttest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_CAST is defined */
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_CAST
+int main(int argc, char *argv[])
+{
+    printf("No CAST support\n");
+    return(0);
+}
+#else
+#include <openssl/cast.h>
+
+#define FULL_TEST
+
+static unsigned char k[16]={
+	0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
+	0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A
+	};
+
+static unsigned char in[8]={ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF};
+
+static int k_len[3]={16,10,5};
+static unsigned char c[3][8]={
+	{0x23,0x8B,0x4F,0xE5,0x84,0x7E,0x44,0xB2},
+	{0xEB,0x6A,0x71,0x1A,0x2C,0x02,0x27,0x1B},
+	{0x7A,0xC8,0x16,0xD1,0x6E,0x9B,0x30,0x2E},
+	};
+static unsigned char out[80];
+
+static unsigned char in_a[16]={
+	0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
+	0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A};
+static unsigned char in_b[16]={
+	0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
+	0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A};
+
+static unsigned char c_a[16]={
+	0xEE,0xA9,0xD0,0xA2,0x49,0xFD,0x3B,0xA6,
+	0xB3,0x43,0x6F,0xB8,0x9D,0x6D,0xCA,0x92};
+static unsigned char c_b[16]={
+	0xB2,0xC9,0x5E,0xB0,0x0C,0x31,0xAD,0x71,
+	0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E};
+
+#if 0
+char *text="Hello to all people out there";
+
+static unsigned char cfb_key[16]={
+	0xe1,0xf0,0xc3,0xd2,0xa5,0xb4,0x87,0x96,
+	0x69,0x78,0x4b,0x5a,0x2d,0x3c,0x0f,0x1e,
+	};
+static unsigned char cfb_iv[80]={0x34,0x12,0x78,0x56,0xab,0x90,0xef,0xcd};
+static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
+#define CFB_TEST_SIZE 24
+static unsigned char plain[CFB_TEST_SIZE]=
+        {
+        0x4e,0x6f,0x77,0x20,0x69,0x73,
+        0x20,0x74,0x68,0x65,0x20,0x74,
+        0x69,0x6d,0x65,0x20,0x66,0x6f,
+        0x72,0x20,0x61,0x6c,0x6c,0x20
+        };
+static unsigned char cfb_cipher64[CFB_TEST_SIZE]={
+	0x59,0xD8,0xE2,0x65,0x00,0x58,0x6C,0x3F,
+	0x2C,0x17,0x25,0xD0,0x1A,0x38,0xB7,0x2A,
+	0x39,0x61,0x37,0xDC,0x79,0xFB,0x9F,0x45
+
+/*	0xF9,0x78,0x32,0xB5,0x42,0x1A,0x6B,0x38,
+	0x9A,0x44,0xD6,0x04,0x19,0x43,0xC4,0xD9,
+	0x3D,0x1E,0xAE,0x47,0xFC,0xCF,0x29,0x0B,*/
+	}; 
+#endif
+
+int main(int argc, char *argv[])
+    {
+#ifdef FULL_TEST
+    long l;
+    CAST_KEY key_b;
+#endif
+    int i,z,err=0;
+    CAST_KEY key;
+
+    for (z=0; z<3; z++)
+	{
+	CAST_set_key(&key,k_len[z],k);
+
+	CAST_ecb_encrypt(in,out,&key,CAST_ENCRYPT);
+	if (memcmp(out,&(c[z][0]),8) != 0)
+	    {
+	    printf("ecb cast error encrypting for keysize %d\n",k_len[z]*8);
+	    printf("got     :");
+	    for (i=0; i<8; i++)
+		printf("%02X ",out[i]);
+	    printf("\n");
+	    printf("expected:");
+	    for (i=0; i<8; i++)
+		printf("%02X ",c[z][i]);
+	    err=20;
+	    printf("\n");
+	    }
+
+	CAST_ecb_encrypt(out,out,&key,CAST_DECRYPT);
+	if (memcmp(out,in,8) != 0)
+	    {
+	    printf("ecb cast error decrypting for keysize %d\n",k_len[z]*8);
+	    printf("got     :");
+	    for (i=0; i<8; i++)
+		printf("%02X ",out[i]);
+	    printf("\n");
+	    printf("expected:");
+	    for (i=0; i<8; i++)
+		printf("%02X ",in[i]);
+	    printf("\n");
+	    err=3;
+	    }
+	}
+    if (err == 0)
+	printf("ecb cast5 ok\n");
+
+#ifdef FULL_TEST
+      {
+      unsigned char out_a[16],out_b[16];
+      static char *hex="0123456789ABCDEF";
+      
+      printf("This test will take some time....");
+      fflush(stdout);
+      memcpy(out_a,in_a,sizeof(in_a));
+      memcpy(out_b,in_b,sizeof(in_b));
+      i=1;
+
+      for (l=0; l<1000000L; l++)
+	  {
+	  CAST_set_key(&key_b,16,out_b);
+	  CAST_ecb_encrypt(&(out_a[0]),&(out_a[0]),&key_b,CAST_ENCRYPT);
+	  CAST_ecb_encrypt(&(out_a[8]),&(out_a[8]),&key_b,CAST_ENCRYPT);
+	  CAST_set_key(&key,16,out_a);
+	  CAST_ecb_encrypt(&(out_b[0]),&(out_b[0]),&key,CAST_ENCRYPT);
+	  CAST_ecb_encrypt(&(out_b[8]),&(out_b[8]),&key,CAST_ENCRYPT);
+	  if ((l & 0xffff) == 0xffff)
+	      {
+	      printf("%c",hex[i&0x0f]);
+	      fflush(stdout);
+	      i++;
+	      }
+	  }
+
+      if (	(memcmp(out_a,c_a,sizeof(c_a)) != 0) ||
+		(memcmp(out_b,c_b,sizeof(c_b)) != 0))
+	  {
+	  printf("\n");
+	  printf("Error\n");
+
+	  printf("A out =");
+	  for (i=0; i<16; i++) printf("%02X ",out_a[i]);
+	  printf("\nactual=");
+	  for (i=0; i<16; i++) printf("%02X ",c_a[i]);
+	  printf("\n");
+
+	  printf("B out =");
+	  for (i=0; i<16; i++) printf("%02X ",out_b[i]);
+	  printf("\nactual=");
+	  for (i=0; i<16; i++) printf("%02X ",c_b[i]);
+	  printf("\n");
+	  }
+      else
+	  printf(" ok\n");
+      }
+#endif
+
+    EXIT(err);
+    return(err);
+    }
+#endif
diff --git a/openssl/crypto/cms/Makefile b/openssl/crypto/cms/Makefile
new file mode 100644
index 0000000..5837049
--- /dev/null
+++ b/openssl/crypto/cms/Makefile
@@ -0,0 +1,264 @@
+#
+# OpenSSL/crypto/cms/Makefile
+#
+
+DIR=	cms
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= cms_lib.c cms_asn1.c cms_att.c cms_io.c cms_smime.c cms_err.c \
+	cms_sd.c cms_dd.c cms_cd.c cms_env.c cms_enc.c cms_ess.c
+LIBOBJ= cms_lib.o cms_asn1.o cms_att.o cms_io.o cms_smime.o cms_err.o \
+	cms_sd.o cms_dd.o cms_cd.o cms_env.o cms_enc.o cms_ess.o
+
+SRC= $(LIBSRC)
+
+EXHEADER=  cms.h
+HEADER=	cms_lcl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+test:
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+cms_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+cms_asn1.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+cms_asn1.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+cms_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+cms_asn1.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+cms_asn1.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+cms_asn1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+cms_asn1.o: ../../include/openssl/opensslconf.h
+cms_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+cms_asn1.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+cms_asn1.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+cms_asn1.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+cms_asn1.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+cms_asn1.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+cms_asn1.o: cms.h cms_asn1.c cms_lcl.h
+cms_att.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+cms_att.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+cms_att.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+cms_att.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+cms_att.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+cms_att.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+cms_att.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+cms_att.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+cms_att.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+cms_att.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+cms_att.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+cms_att.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+cms_att.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+cms_att.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+cms_att.o: cms.h cms_att.c cms_lcl.h
+cms_cd.o: ../../e_os.h ../../include/openssl/asn1.h
+cms_cd.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+cms_cd.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
+cms_cd.o: ../../include/openssl/comp.h ../../include/openssl/conf.h
+cms_cd.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+cms_cd.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+cms_cd.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+cms_cd.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+cms_cd.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+cms_cd.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+cms_cd.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
+cms_cd.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
+cms_cd.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+cms_cd.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+cms_cd.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+cms_cd.o: ../../include/openssl/x509v3.h ../cryptlib.h cms_cd.c cms_lcl.h
+cms_dd.o: ../../e_os.h ../../include/openssl/asn1.h
+cms_dd.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+cms_dd.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
+cms_dd.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+cms_dd.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+cms_dd.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+cms_dd.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+cms_dd.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+cms_dd.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+cms_dd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+cms_dd.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+cms_dd.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+cms_dd.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+cms_dd.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+cms_dd.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+cms_dd.o: ../cryptlib.h cms_dd.c cms_lcl.h
+cms_enc.o: ../../e_os.h ../../include/openssl/asn1.h
+cms_enc.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+cms_enc.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
+cms_enc.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+cms_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+cms_enc.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+cms_enc.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+cms_enc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+cms_enc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+cms_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+cms_enc.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+cms_enc.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+cms_enc.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+cms_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+cms_enc.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+cms_enc.o: ../../include/openssl/x509v3.h ../cryptlib.h cms_enc.c cms_lcl.h
+cms_env.o: ../../e_os.h ../../include/openssl/aes.h
+cms_env.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+cms_env.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+cms_env.o: ../../include/openssl/cms.h ../../include/openssl/conf.h
+cms_env.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+cms_env.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+cms_env.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+cms_env.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+cms_env.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+cms_env.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+cms_env.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
+cms_env.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
+cms_env.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+cms_env.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+cms_env.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+cms_env.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+cms_env.o: ../asn1/asn1_locl.h ../cryptlib.h cms_env.c cms_lcl.h
+cms_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+cms_err.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
+cms_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+cms_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+cms_err.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+cms_err.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+cms_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+cms_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+cms_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+cms_err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+cms_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+cms_err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+cms_err.o: cms_err.c
+cms_ess.o: ../../e_os.h ../../include/openssl/asn1.h
+cms_ess.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+cms_ess.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
+cms_ess.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+cms_ess.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+cms_ess.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+cms_ess.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+cms_ess.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+cms_ess.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+cms_ess.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+cms_ess.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+cms_ess.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+cms_ess.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+cms_ess.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+cms_ess.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+cms_ess.o: ../../include/openssl/x509v3.h ../cryptlib.h cms_ess.c cms_lcl.h
+cms_io.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+cms_io.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+cms_io.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+cms_io.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+cms_io.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+cms_io.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+cms_io.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+cms_io.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+cms_io.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
+cms_io.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
+cms_io.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+cms_io.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+cms_io.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h cms.h
+cms_io.o: cms_io.c cms_lcl.h
+cms_lib.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+cms_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+cms_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+cms_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+cms_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+cms_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+cms_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+cms_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+cms_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
+cms_lib.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
+cms_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+cms_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+cms_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h cms.h
+cms_lib.o: cms_lcl.h cms_lib.c
+cms_sd.o: ../../e_os.h ../../include/openssl/asn1.h
+cms_sd.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+cms_sd.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
+cms_sd.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+cms_sd.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+cms_sd.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+cms_sd.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+cms_sd.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+cms_sd.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+cms_sd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+cms_sd.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+cms_sd.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+cms_sd.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+cms_sd.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+cms_sd.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+cms_sd.o: ../asn1/asn1_locl.h ../cryptlib.h cms_lcl.h cms_sd.c
+cms_smime.o: ../../e_os.h ../../include/openssl/asn1.h
+cms_smime.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+cms_smime.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
+cms_smime.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+cms_smime.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+cms_smime.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+cms_smime.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+cms_smime.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+cms_smime.o: ../../include/openssl/objects.h
+cms_smime.o: ../../include/openssl/opensslconf.h
+cms_smime.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+cms_smime.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+cms_smime.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+cms_smime.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+cms_smime.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+cms_smime.o: ../cryptlib.h cms_lcl.h cms_smime.c
diff --git a/openssl/crypto/cms/cms.h b/openssl/crypto/cms/cms.h
new file mode 100644
index 0000000..09c45d0
--- /dev/null
+++ b/openssl/crypto/cms/cms.h
@@ -0,0 +1,479 @@
+/* crypto/cms/cms.h */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+
+#ifndef HEADER_CMS_H
+#define HEADER_CMS_H
+
+#include <openssl/x509.h>
+
+#ifdef OPENSSL_NO_CMS
+#error CMS is disabled.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct CMS_ContentInfo_st CMS_ContentInfo;
+typedef struct CMS_SignerInfo_st CMS_SignerInfo;
+typedef struct CMS_CertificateChoices CMS_CertificateChoices;
+typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice;
+typedef struct CMS_RecipientInfo_st CMS_RecipientInfo;
+typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest;
+typedef struct CMS_Receipt_st CMS_Receipt;
+
+DECLARE_STACK_OF(CMS_SignerInfo)
+DECLARE_STACK_OF(GENERAL_NAMES)
+DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
+DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest)
+DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
+
+#define CMS_SIGNERINFO_ISSUER_SERIAL	0
+#define CMS_SIGNERINFO_KEYIDENTIFIER	1
+
+#define CMS_RECIPINFO_TRANS		0
+#define CMS_RECIPINFO_AGREE		1
+#define CMS_RECIPINFO_KEK		2
+#define CMS_RECIPINFO_PASS		3
+#define CMS_RECIPINFO_OTHER		4
+
+/* S/MIME related flags */
+
+#define CMS_TEXT			0x1
+#define CMS_NOCERTS			0x2
+#define CMS_NO_CONTENT_VERIFY		0x4
+#define CMS_NO_ATTR_VERIFY		0x8
+#define CMS_NOSIGS			\
+			(CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY)
+#define CMS_NOINTERN			0x10
+#define CMS_NO_SIGNER_CERT_VERIFY	0x20
+#define CMS_NOVERIFY			0x20
+#define CMS_DETACHED			0x40
+#define CMS_BINARY			0x80
+#define CMS_NOATTR			0x100
+#define	CMS_NOSMIMECAP			0x200
+#define CMS_NOOLDMIMETYPE		0x400
+#define CMS_CRLFEOL			0x800
+#define CMS_STREAM			0x1000
+#define CMS_NOCRL			0x2000
+#define CMS_PARTIAL			0x4000
+#define CMS_REUSE_DIGEST		0x8000
+#define CMS_USE_KEYID			0x10000
+
+const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms);
+
+BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont);
+int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio);
+
+ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms);
+int CMS_is_detached(CMS_ContentInfo *cms);
+int CMS_set_detached(CMS_ContentInfo *cms, int detached);
+
+#ifdef HEADER_PEM_H
+DECLARE_PEM_rw_const(CMS, CMS_ContentInfo)
+#endif
+
+int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms);
+CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms);
+int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms);
+
+BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms);
+int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
+int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
+CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont);
+int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags);
+
+int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags);
+
+CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
+						BIO *data, unsigned int flags);
+
+CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
+					X509 *signcert, EVP_PKEY *pkey,
+					STACK_OF(X509) *certs,
+					unsigned int flags);
+
+int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags);
+CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags);
+
+int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+							unsigned int flags);
+CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
+							unsigned int flags);
+
+int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
+				const unsigned char *key, size_t keylen,
+				BIO *dcont, BIO *out, unsigned int flags);
+
+CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
+					const unsigned char *key, size_t keylen,
+					unsigned int flags);
+
+int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
+				const unsigned char *key, size_t keylen);
+
+int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+		 X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags);
+
+int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
+			STACK_OF(X509) *certs,
+			X509_STORE *store, unsigned int flags);
+
+STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
+
+CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
+				const EVP_CIPHER *cipher, unsigned int flags);
+
+int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
+				BIO *dcont, BIO *out,
+				unsigned int flags);
+	
+int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert);
+int CMS_decrypt_set1_key(CMS_ContentInfo *cms, 
+				unsigned char *key, size_t keylen,
+				unsigned char *id, size_t idlen);
+
+STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
+int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
+CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
+CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
+					X509 *recip, unsigned int flags);
+int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey);
+int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert);
+int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
+					EVP_PKEY **pk, X509 **recip,
+					X509_ALGOR **palg);
+int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
+					ASN1_OCTET_STRING **keyid,
+					X509_NAME **issuer, ASN1_INTEGER **sno);
+
+CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
+					unsigned char *key, size_t keylen,
+					unsigned char *id, size_t idlen,
+					ASN1_GENERALIZEDTIME *date,
+					ASN1_OBJECT *otherTypeId,
+					ASN1_TYPE *otherType);
+
+int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
+					X509_ALGOR **palg,
+					ASN1_OCTET_STRING **pid,
+					ASN1_GENERALIZEDTIME **pdate,
+					ASN1_OBJECT **potherid,
+					ASN1_TYPE **pothertype);
+
+int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, 
+				unsigned char *key, size_t keylen);
+
+int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, 
+					const unsigned char *id, size_t idlen);
+
+int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
+	
+int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+							unsigned int flags);
+CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags);
+
+int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid);
+const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms);
+
+CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms);
+int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert);
+int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert);
+STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms);
+
+CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms);
+int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl);
+int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl);
+STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms);
+
+int CMS_SignedData_init(CMS_ContentInfo *cms);
+CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
+			X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
+			unsigned int flags);
+STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms);
+
+void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer);
+int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
+					ASN1_OCTET_STRING **keyid,
+					X509_NAME **issuer, ASN1_INTEGER **sno);
+int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert);
+int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+					unsigned int flags);
+void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer,
+					X509_ALGOR **pdig, X509_ALGOR **psig);
+int CMS_SignerInfo_sign(CMS_SignerInfo *si);
+int CMS_SignerInfo_verify(CMS_SignerInfo *si);
+int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain);
+
+int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs);
+int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
+				int algnid, int keysize);
+int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap);
+
+int CMS_signed_get_attr_count(const CMS_SignerInfo *si);
+int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+			  int lastpos);
+int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc);
+X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc);
+int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
+int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
+			const ASN1_OBJECT *obj, int type,
+			const void *bytes, int len);
+int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
+			int nid, int type,
+			const void *bytes, int len);
+int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
+			const char *attrname, int type,
+			const void *bytes, int len);
+void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+					int lastpos, int type);
+
+int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si);
+int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+			  int lastpos);
+int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc);
+X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc);
+int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
+int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
+			const ASN1_OBJECT *obj, int type,
+			const void *bytes, int len);
+int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
+			int nid, int type,
+			const void *bytes, int len);
+int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
+			const char *attrname, int type,
+			const void *bytes, int len);
+void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+					int lastpos, int type);
+
+#ifdef HEADER_X509V3_H
+
+int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
+CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
+				int allorfirst,
+				STACK_OF(GENERAL_NAMES) *receiptList,
+				STACK_OF(GENERAL_NAMES) *receiptsTo);
+int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
+void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
+					ASN1_STRING **pcid,
+					int *pallorfirst,
+					STACK_OF(GENERAL_NAMES) **plist,
+					STACK_OF(GENERAL_NAMES) **prto);
+
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_CMS_strings(void);
+
+/* Error codes for the CMS functions. */
+
+/* Function codes. */
+#define CMS_F_CHECK_CONTENT				 99
+#define CMS_F_CMS_ADD0_CERT				 164
+#define CMS_F_CMS_ADD0_RECIPIENT_KEY			 100
+#define CMS_F_CMS_ADD1_RECEIPTREQUEST			 158
+#define CMS_F_CMS_ADD1_RECIPIENT_CERT			 101
+#define CMS_F_CMS_ADD1_SIGNER				 102
+#define CMS_F_CMS_ADD1_SIGNINGTIME			 103
+#define CMS_F_CMS_COMPRESS				 104
+#define CMS_F_CMS_COMPRESSEDDATA_CREATE			 105
+#define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO		 106
+#define CMS_F_CMS_COPY_CONTENT				 107
+#define CMS_F_CMS_COPY_MESSAGEDIGEST			 108
+#define CMS_F_CMS_DATA					 109
+#define CMS_F_CMS_DATAFINAL				 110
+#define CMS_F_CMS_DATAINIT				 111
+#define CMS_F_CMS_DECRYPT				 112
+#define CMS_F_CMS_DECRYPT_SET1_KEY			 113
+#define CMS_F_CMS_DECRYPT_SET1_PKEY			 114
+#define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX		 115
+#define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO		 116
+#define CMS_F_CMS_DIGESTEDDATA_DO_FINAL			 117
+#define CMS_F_CMS_DIGEST_VERIFY				 118
+#define CMS_F_CMS_ENCODE_RECEIPT			 161
+#define CMS_F_CMS_ENCRYPT				 119
+#define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO		 120
+#define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT			 121
+#define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT			 122
+#define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY		 123
+#define CMS_F_CMS_ENVELOPEDDATA_CREATE			 124
+#define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO		 125
+#define CMS_F_CMS_ENVELOPED_DATA_INIT			 126
+#define CMS_F_CMS_FINAL					 127
+#define CMS_F_CMS_GET0_CERTIFICATE_CHOICES		 128
+#define CMS_F_CMS_GET0_CONTENT				 129
+#define CMS_F_CMS_GET0_ECONTENT_TYPE			 130
+#define CMS_F_CMS_GET0_ENVELOPED			 131
+#define CMS_F_CMS_GET0_REVOCATION_CHOICES		 132
+#define CMS_F_CMS_GET0_SIGNED				 133
+#define CMS_F_CMS_MSGSIGDIGEST_ADD1			 162
+#define CMS_F_CMS_RECEIPTREQUEST_CREATE0		 159
+#define CMS_F_CMS_RECEIPT_VERIFY			 160
+#define CMS_F_CMS_RECIPIENTINFO_DECRYPT			 134
+#define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT		 135
+#define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT		 136
+#define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID		 137
+#define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP		 138
+#define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP		 139
+#define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT		 140
+#define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT		 141
+#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS		 142
+#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID	 143
+#define CMS_F_CMS_RECIPIENTINFO_SET0_KEY		 144
+#define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY		 145
+#define CMS_F_CMS_SET1_SIGNERIDENTIFIER			 146
+#define CMS_F_CMS_SET_DETACHED				 147
+#define CMS_F_CMS_SIGN					 148
+#define CMS_F_CMS_SIGNED_DATA_INIT			 149
+#define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN		 150
+#define CMS_F_CMS_SIGNERINFO_SIGN			 151
+#define CMS_F_CMS_SIGNERINFO_VERIFY			 152
+#define CMS_F_CMS_SIGNERINFO_VERIFY_CERT		 153
+#define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT		 154
+#define CMS_F_CMS_SIGN_RECEIPT				 163
+#define CMS_F_CMS_STREAM				 155
+#define CMS_F_CMS_UNCOMPRESS				 156
+#define CMS_F_CMS_VERIFY				 157
+
+/* Reason codes. */
+#define CMS_R_ADD_SIGNER_ERROR				 99
+#define CMS_R_CERTIFICATE_ALREADY_PRESENT		 175
+#define CMS_R_CERTIFICATE_HAS_NO_KEYID			 160
+#define CMS_R_CERTIFICATE_VERIFY_ERROR			 100
+#define CMS_R_CIPHER_INITIALISATION_ERROR		 101
+#define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR	 102
+#define CMS_R_CMS_DATAFINAL_ERROR			 103
+#define CMS_R_CMS_LIB					 104
+#define CMS_R_CONTENTIDENTIFIER_MISMATCH		 170
+#define CMS_R_CONTENT_NOT_FOUND				 105
+#define CMS_R_CONTENT_TYPE_MISMATCH			 171
+#define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA		 106
+#define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA		 107
+#define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA		 108
+#define CMS_R_CONTENT_VERIFY_ERROR			 109
+#define CMS_R_CTRL_ERROR				 110
+#define CMS_R_CTRL_FAILURE				 111
+#define CMS_R_DECRYPT_ERROR				 112
+#define CMS_R_DIGEST_ERROR				 161
+#define CMS_R_ERROR_GETTING_PUBLIC_KEY			 113
+#define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE	 114
+#define CMS_R_ERROR_SETTING_KEY				 115
+#define CMS_R_ERROR_SETTING_RECIPIENTINFO		 116
+#define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH		 117
+#define CMS_R_INVALID_KEY_LENGTH			 118
+#define CMS_R_MD_BIO_INIT_ERROR				 119
+#define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH	 120
+#define CMS_R_MESSAGEDIGEST_WRONG_LENGTH		 121
+#define CMS_R_MSGSIGDIGEST_ERROR			 172
+#define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE		 162
+#define CMS_R_MSGSIGDIGEST_WRONG_LENGTH			 163
+#define CMS_R_NEED_ONE_SIGNER				 164
+#define CMS_R_NOT_A_SIGNED_RECEIPT			 165
+#define CMS_R_NOT_ENCRYPTED_DATA			 122
+#define CMS_R_NOT_KEK					 123
+#define CMS_R_NOT_KEY_TRANSPORT				 124
+#define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE		 125
+#define CMS_R_NO_CIPHER					 126
+#define CMS_R_NO_CONTENT				 127
+#define CMS_R_NO_CONTENT_TYPE				 173
+#define CMS_R_NO_DEFAULT_DIGEST				 128
+#define CMS_R_NO_DIGEST_SET				 129
+#define CMS_R_NO_KEY					 130
+#define CMS_R_NO_KEY_OR_CERT				 174
+#define CMS_R_NO_MATCHING_DIGEST			 131
+#define CMS_R_NO_MATCHING_RECIPIENT			 132
+#define CMS_R_NO_MATCHING_SIGNATURE			 166
+#define CMS_R_NO_MSGSIGDIGEST				 167
+#define CMS_R_NO_PRIVATE_KEY				 133
+#define CMS_R_NO_PUBLIC_KEY				 134
+#define CMS_R_NO_RECEIPT_REQUEST			 168
+#define CMS_R_NO_SIGNERS				 135
+#define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 136
+#define CMS_R_RECEIPT_DECODE_ERROR			 169
+#define CMS_R_RECIPIENT_ERROR				 137
+#define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND		 138
+#define CMS_R_SIGNFINAL_ERROR				 139
+#define CMS_R_SMIME_TEXT_ERROR				 140
+#define CMS_R_STORE_INIT_ERROR				 141
+#define CMS_R_TYPE_NOT_COMPRESSED_DATA			 142
+#define CMS_R_TYPE_NOT_DATA				 143
+#define CMS_R_TYPE_NOT_DIGESTED_DATA			 144
+#define CMS_R_TYPE_NOT_ENCRYPTED_DATA			 145
+#define CMS_R_TYPE_NOT_ENVELOPED_DATA			 146
+#define CMS_R_UNABLE_TO_FINALIZE_CONTEXT		 147
+#define CMS_R_UNKNOWN_CIPHER				 148
+#define CMS_R_UNKNOWN_DIGEST_ALGORIHM			 149
+#define CMS_R_UNKNOWN_ID				 150
+#define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM		 151
+#define CMS_R_UNSUPPORTED_CONTENT_TYPE			 152
+#define CMS_R_UNSUPPORTED_KEK_ALGORITHM			 153
+#define CMS_R_UNSUPPORTED_RECIPIENT_TYPE		 154
+#define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE		 155
+#define CMS_R_UNSUPPORTED_TYPE				 156
+#define CMS_R_UNWRAP_ERROR				 157
+#define CMS_R_VERIFICATION_FAILURE			 158
+#define CMS_R_WRAP_ERROR				 159
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/cms/cms_asn1.c b/openssl/crypto/cms/cms_asn1.c
new file mode 100644
index 0000000..fcba4dc
--- /dev/null
+++ b/openssl/crypto/cms/cms_asn1.c
@@ -0,0 +1,380 @@
+/* crypto/cms/cms_asn1.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include "cms.h"
+#include "cms_lcl.h"
+
+
+ASN1_SEQUENCE(CMS_IssuerAndSerialNumber) = {
+	ASN1_SIMPLE(CMS_IssuerAndSerialNumber, issuer, X509_NAME),
+	ASN1_SIMPLE(CMS_IssuerAndSerialNumber, serialNumber, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(CMS_IssuerAndSerialNumber)
+
+ASN1_SEQUENCE(CMS_OtherCertificateFormat) = {
+	ASN1_SIMPLE(CMS_OtherCertificateFormat, otherCertFormat, ASN1_OBJECT),
+	ASN1_OPT(CMS_OtherCertificateFormat, otherCert, ASN1_ANY)
+} ASN1_SEQUENCE_END(CMS_OtherCertificateFormat)
+
+ASN1_CHOICE(CMS_CertificateChoices) = {
+	ASN1_SIMPLE(CMS_CertificateChoices, d.certificate, X509),
+	ASN1_IMP(CMS_CertificateChoices, d.extendedCertificate, ASN1_SEQUENCE, 0),
+	ASN1_IMP(CMS_CertificateChoices, d.v1AttrCert, ASN1_SEQUENCE, 1),
+	ASN1_IMP(CMS_CertificateChoices, d.v2AttrCert, ASN1_SEQUENCE, 2),
+	ASN1_IMP(CMS_CertificateChoices, d.other, CMS_OtherCertificateFormat, 3)
+} ASN1_CHOICE_END(CMS_CertificateChoices)
+
+ASN1_CHOICE(CMS_SignerIdentifier) = {
+	ASN1_SIMPLE(CMS_SignerIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
+	ASN1_IMP(CMS_SignerIdentifier, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0)
+} ASN1_CHOICE_END(CMS_SignerIdentifier)
+
+ASN1_NDEF_SEQUENCE(CMS_EncapsulatedContentInfo) = {
+	ASN1_SIMPLE(CMS_EncapsulatedContentInfo, eContentType, ASN1_OBJECT),
+	ASN1_NDEF_EXP_OPT(CMS_EncapsulatedContentInfo, eContent, ASN1_OCTET_STRING_NDEF, 0)
+} ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo)
+
+/* Minor tweak to operation: free up signer key, cert */
+static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
+	{
+	if(operation == ASN1_OP_FREE_POST)
+		{
+		CMS_SignerInfo *si = (CMS_SignerInfo *)*pval;
+		if (si->pkey)
+			EVP_PKEY_free(si->pkey);
+		if (si->signer)
+			X509_free(si->signer);
+		}
+	return 1;
+	}
+
+ASN1_SEQUENCE_cb(CMS_SignerInfo, cms_si_cb) = {
+	ASN1_SIMPLE(CMS_SignerInfo, version, LONG),
+	ASN1_SIMPLE(CMS_SignerInfo, sid, CMS_SignerIdentifier),
+	ASN1_SIMPLE(CMS_SignerInfo, digestAlgorithm, X509_ALGOR),
+	ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, signedAttrs, X509_ATTRIBUTE, 0),
+	ASN1_SIMPLE(CMS_SignerInfo, signatureAlgorithm, X509_ALGOR),
+	ASN1_SIMPLE(CMS_SignerInfo, signature, ASN1_OCTET_STRING),
+	ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, unsignedAttrs, X509_ATTRIBUTE, 1)
+} ASN1_SEQUENCE_END_cb(CMS_SignerInfo, CMS_SignerInfo)
+
+ASN1_SEQUENCE(CMS_OtherRevocationInfoFormat) = {
+	ASN1_SIMPLE(CMS_OtherRevocationInfoFormat, otherRevInfoFormat, ASN1_OBJECT),
+	ASN1_OPT(CMS_OtherRevocationInfoFormat, otherRevInfo, ASN1_ANY)
+} ASN1_SEQUENCE_END(CMS_OtherRevocationInfoFormat)
+
+ASN1_CHOICE(CMS_RevocationInfoChoice) = {
+	ASN1_SIMPLE(CMS_RevocationInfoChoice, d.crl, X509_CRL),
+	ASN1_IMP(CMS_RevocationInfoChoice, d.other, CMS_OtherRevocationInfoFormat, 1)
+} ASN1_CHOICE_END(CMS_RevocationInfoChoice)
+
+ASN1_NDEF_SEQUENCE(CMS_SignedData) = {
+	ASN1_SIMPLE(CMS_SignedData, version, LONG),
+	ASN1_SET_OF(CMS_SignedData, digestAlgorithms, X509_ALGOR),
+	ASN1_SIMPLE(CMS_SignedData, encapContentInfo, CMS_EncapsulatedContentInfo),
+	ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0),
+	ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1),
+	ASN1_SET_OF(CMS_SignedData, signerInfos, CMS_SignerInfo)
+} ASN1_NDEF_SEQUENCE_END(CMS_SignedData)
+
+ASN1_SEQUENCE(CMS_OriginatorInfo) = {
+	ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, certificates, CMS_CertificateChoices, 0),
+	ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, crls, CMS_RevocationInfoChoice, 1)
+} ASN1_SEQUENCE_END(CMS_OriginatorInfo)
+
+ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = {
+	ASN1_SIMPLE(CMS_EncryptedContentInfo, contentType, ASN1_OBJECT),
+	ASN1_SIMPLE(CMS_EncryptedContentInfo, contentEncryptionAlgorithm, X509_ALGOR),
+	ASN1_IMP_OPT(CMS_EncryptedContentInfo, encryptedContent, ASN1_OCTET_STRING_NDEF, 0)
+} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedContentInfo)
+
+ASN1_SEQUENCE(CMS_KeyTransRecipientInfo) = {
+	ASN1_SIMPLE(CMS_KeyTransRecipientInfo, version, LONG),
+	ASN1_SIMPLE(CMS_KeyTransRecipientInfo, rid, CMS_SignerIdentifier),
+	ASN1_SIMPLE(CMS_KeyTransRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
+	ASN1_SIMPLE(CMS_KeyTransRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_KeyTransRecipientInfo)
+
+ASN1_SEQUENCE(CMS_OtherKeyAttribute) = {
+	ASN1_SIMPLE(CMS_OtherKeyAttribute, keyAttrId, ASN1_OBJECT),
+	ASN1_OPT(CMS_OtherKeyAttribute, keyAttr, ASN1_ANY)
+} ASN1_SEQUENCE_END(CMS_OtherKeyAttribute)
+
+ASN1_SEQUENCE(CMS_RecipientKeyIdentifier) = {
+	ASN1_SIMPLE(CMS_RecipientKeyIdentifier, subjectKeyIdentifier, ASN1_OCTET_STRING),
+	ASN1_OPT(CMS_RecipientKeyIdentifier, date, ASN1_GENERALIZEDTIME),
+	ASN1_OPT(CMS_RecipientKeyIdentifier, other, CMS_OtherKeyAttribute)
+} ASN1_SEQUENCE_END(CMS_RecipientKeyIdentifier)
+
+ASN1_CHOICE(CMS_KeyAgreeRecipientIdentifier) = {
+  ASN1_SIMPLE(CMS_KeyAgreeRecipientIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
+  ASN1_IMP(CMS_KeyAgreeRecipientIdentifier, d.rKeyId, CMS_RecipientKeyIdentifier, 0)
+} ASN1_CHOICE_END(CMS_KeyAgreeRecipientIdentifier)
+
+ASN1_SEQUENCE(CMS_RecipientEncryptedKey) = {
+	ASN1_SIMPLE(CMS_RecipientEncryptedKey, rid, CMS_KeyAgreeRecipientIdentifier),
+	ASN1_SIMPLE(CMS_RecipientEncryptedKey, encryptedKey, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_RecipientEncryptedKey)
+
+ASN1_SEQUENCE(CMS_OriginatorPublicKey) = {
+  ASN1_SIMPLE(CMS_OriginatorPublicKey, algorithm, X509_ALGOR),
+  ASN1_SIMPLE(CMS_OriginatorPublicKey, publicKey, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END(CMS_OriginatorPublicKey)
+
+ASN1_CHOICE(CMS_OriginatorIdentifierOrKey) = {
+  ASN1_SIMPLE(CMS_OriginatorIdentifierOrKey, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
+  ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0),
+  ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.originatorKey, CMS_OriginatorPublicKey, 1)
+} ASN1_CHOICE_END(CMS_OriginatorIdentifierOrKey)
+
+ASN1_SEQUENCE(CMS_KeyAgreeRecipientInfo) = {
+	ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, version, LONG),
+	ASN1_EXP(CMS_KeyAgreeRecipientInfo, originator, CMS_OriginatorIdentifierOrKey, 0),
+	ASN1_EXP_OPT(CMS_KeyAgreeRecipientInfo, ukm, ASN1_OCTET_STRING, 1),
+	ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
+	ASN1_SEQUENCE_OF(CMS_KeyAgreeRecipientInfo, recipientEncryptedKeys, CMS_RecipientEncryptedKey)
+} ASN1_SEQUENCE_END(CMS_KeyAgreeRecipientInfo)
+
+ASN1_SEQUENCE(CMS_KEKIdentifier) = {
+	ASN1_SIMPLE(CMS_KEKIdentifier, keyIdentifier, ASN1_OCTET_STRING),
+	ASN1_OPT(CMS_KEKIdentifier, date, ASN1_GENERALIZEDTIME),
+	ASN1_OPT(CMS_KEKIdentifier, other, CMS_OtherKeyAttribute)
+} ASN1_SEQUENCE_END(CMS_KEKIdentifier)
+
+ASN1_SEQUENCE(CMS_KEKRecipientInfo) = {
+	ASN1_SIMPLE(CMS_KEKRecipientInfo, version, LONG),
+	ASN1_SIMPLE(CMS_KEKRecipientInfo, kekid, CMS_KEKIdentifier),
+	ASN1_SIMPLE(CMS_KEKRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
+	ASN1_SIMPLE(CMS_KEKRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_KEKRecipientInfo)
+
+ASN1_SEQUENCE(CMS_PasswordRecipientInfo) = {
+	ASN1_SIMPLE(CMS_PasswordRecipientInfo, version, LONG),
+	ASN1_IMP_OPT(CMS_PasswordRecipientInfo, keyDerivationAlgorithm, X509_ALGOR, 0),
+	ASN1_SIMPLE(CMS_PasswordRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
+	ASN1_SIMPLE(CMS_PasswordRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_PasswordRecipientInfo)
+
+ASN1_SEQUENCE(CMS_OtherRecipientInfo) = {
+  ASN1_SIMPLE(CMS_OtherRecipientInfo, oriType, ASN1_OBJECT),
+  ASN1_OPT(CMS_OtherRecipientInfo, oriValue, ASN1_ANY)
+} ASN1_SEQUENCE_END(CMS_OtherRecipientInfo)
+
+/* Free up RecipientInfo additional data */
+static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
+	{
+	if(operation == ASN1_OP_FREE_PRE)
+		{
+		CMS_RecipientInfo *ri = (CMS_RecipientInfo *)*pval;
+		if (ri->type == CMS_RECIPINFO_TRANS)
+			{
+			CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
+			if (ktri->pkey)
+				EVP_PKEY_free(ktri->pkey);
+			if (ktri->recip)
+				X509_free(ktri->recip);
+			}
+		else if (ri->type == CMS_RECIPINFO_KEK)
+			{
+			CMS_KEKRecipientInfo *kekri = ri->d.kekri;
+			if (kekri->key)
+				{
+				OPENSSL_cleanse(kekri->key, kekri->keylen);
+				OPENSSL_free(kekri->key);
+				}
+			}
+		}
+	return 1;
+	}
+
+ASN1_CHOICE_cb(CMS_RecipientInfo, cms_ri_cb) = {
+	ASN1_SIMPLE(CMS_RecipientInfo, d.ktri, CMS_KeyTransRecipientInfo),
+	ASN1_IMP(CMS_RecipientInfo, d.kari, CMS_KeyAgreeRecipientInfo, 1),
+	ASN1_IMP(CMS_RecipientInfo, d.kekri, CMS_KEKRecipientInfo, 2),
+	ASN1_IMP(CMS_RecipientInfo, d.pwri, CMS_PasswordRecipientInfo, 3),
+	ASN1_IMP(CMS_RecipientInfo, d.ori, CMS_OtherRecipientInfo, 4)
+} ASN1_CHOICE_END_cb(CMS_RecipientInfo, CMS_RecipientInfo, type)
+
+ASN1_NDEF_SEQUENCE(CMS_EnvelopedData) = {
+	ASN1_SIMPLE(CMS_EnvelopedData, version, LONG),
+	ASN1_IMP_OPT(CMS_EnvelopedData, originatorInfo, CMS_OriginatorInfo, 0),
+	ASN1_SET_OF(CMS_EnvelopedData, recipientInfos, CMS_RecipientInfo),
+	ASN1_SIMPLE(CMS_EnvelopedData, encryptedContentInfo, CMS_EncryptedContentInfo),
+	ASN1_IMP_SET_OF_OPT(CMS_EnvelopedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
+} ASN1_NDEF_SEQUENCE_END(CMS_EnvelopedData)
+
+ASN1_NDEF_SEQUENCE(CMS_DigestedData) = {
+	ASN1_SIMPLE(CMS_DigestedData, version, LONG),
+	ASN1_SIMPLE(CMS_DigestedData, digestAlgorithm, X509_ALGOR),
+	ASN1_SIMPLE(CMS_DigestedData, encapContentInfo, CMS_EncapsulatedContentInfo),
+	ASN1_SIMPLE(CMS_DigestedData, digest, ASN1_OCTET_STRING)
+} ASN1_NDEF_SEQUENCE_END(CMS_DigestedData)
+
+ASN1_NDEF_SEQUENCE(CMS_EncryptedData) = {
+	ASN1_SIMPLE(CMS_EncryptedData, version, LONG),
+	ASN1_SIMPLE(CMS_EncryptedData, encryptedContentInfo, CMS_EncryptedContentInfo),
+	ASN1_IMP_SET_OF_OPT(CMS_EncryptedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
+} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedData)
+
+ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = {
+	ASN1_SIMPLE(CMS_AuthenticatedData, version, LONG),
+	ASN1_IMP_OPT(CMS_AuthenticatedData, originatorInfo, CMS_OriginatorInfo, 0),
+	ASN1_SET_OF(CMS_AuthenticatedData, recipientInfos, CMS_RecipientInfo),
+	ASN1_SIMPLE(CMS_AuthenticatedData, macAlgorithm, X509_ALGOR),
+	ASN1_IMP(CMS_AuthenticatedData, digestAlgorithm, X509_ALGOR, 1),
+	ASN1_SIMPLE(CMS_AuthenticatedData, encapContentInfo, CMS_EncapsulatedContentInfo),
+	ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, authAttrs, X509_ALGOR, 2),
+	ASN1_SIMPLE(CMS_AuthenticatedData, mac, ASN1_OCTET_STRING),
+	ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, unauthAttrs, X509_ALGOR, 3)
+} ASN1_NDEF_SEQUENCE_END(CMS_AuthenticatedData)
+
+ASN1_NDEF_SEQUENCE(CMS_CompressedData) = {
+	ASN1_SIMPLE(CMS_CompressedData, version, LONG),
+	ASN1_SIMPLE(CMS_CompressedData, compressionAlgorithm, X509_ALGOR),
+	ASN1_SIMPLE(CMS_CompressedData, encapContentInfo, CMS_EncapsulatedContentInfo),
+} ASN1_NDEF_SEQUENCE_END(CMS_CompressedData)
+
+/* This is the ANY DEFINED BY table for the top level ContentInfo structure */
+
+ASN1_ADB_TEMPLATE(cms_default) = ASN1_EXP(CMS_ContentInfo, d.other, ASN1_ANY, 0);
+
+ASN1_ADB(CMS_ContentInfo) = {
+	ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP(CMS_ContentInfo, d.data, ASN1_OCTET_STRING_NDEF, 0)),
+	ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP(CMS_ContentInfo, d.signedData, CMS_SignedData, 0)),
+	ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP(CMS_ContentInfo, d.envelopedData, CMS_EnvelopedData, 0)),
+	ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP(CMS_ContentInfo, d.digestedData, CMS_DigestedData, 0)),
+	ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP(CMS_ContentInfo, d.encryptedData, CMS_EncryptedData, 0)),
+	ADB_ENTRY(NID_id_smime_ct_authData, ASN1_NDEF_EXP(CMS_ContentInfo, d.authenticatedData, CMS_AuthenticatedData, 0)),
+	ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)),
+} ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL);
+
+/* CMS streaming support */
+static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
+	{
+	ASN1_STREAM_ARG *sarg = exarg;
+	CMS_ContentInfo *cms = NULL;
+	if (pval)
+		cms = (CMS_ContentInfo *)*pval;
+	else
+		return 1;
+	switch(operation)
+		{
+
+		case ASN1_OP_STREAM_PRE:
+		if (CMS_stream(&sarg->boundary, cms) <= 0)
+			return 0;
+		case ASN1_OP_DETACHED_PRE:
+		sarg->ndef_bio = CMS_dataInit(cms, sarg->out);
+		if (!sarg->ndef_bio)
+			return 0;
+		break;
+
+		case ASN1_OP_STREAM_POST:
+		case ASN1_OP_DETACHED_POST:
+		if (CMS_dataFinal(cms, sarg->ndef_bio) <= 0)
+			return 0;
+		break;
+
+		}
+	return 1;
+	}
+
+ASN1_NDEF_SEQUENCE_cb(CMS_ContentInfo, cms_cb) = {
+	ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT),
+	ASN1_ADB_OBJECT(CMS_ContentInfo)
+} ASN1_NDEF_SEQUENCE_END_cb(CMS_ContentInfo, CMS_ContentInfo)
+
+/* Specials for signed attributes */
+
+/* When signing attributes we want to reorder them to match the sorted
+ * encoding.
+ */
+
+ASN1_ITEM_TEMPLATE(CMS_Attributes_Sign) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, CMS_ATTRIBUTES, X509_ATTRIBUTE)
+ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Sign)
+
+/* When verifying attributes we need to use the received order. So 
+ * we use SEQUENCE OF and tag it to SET OF
+ */
+
+ASN1_ITEM_TEMPLATE(CMS_Attributes_Verify) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
+				V_ASN1_SET, CMS_ATTRIBUTES, X509_ATTRIBUTE)
+ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Verify)
+
+
+
+ASN1_CHOICE(CMS_ReceiptsFrom) = {
+  ASN1_IMP(CMS_ReceiptsFrom, d.allOrFirstTier, LONG, 0),
+  ASN1_IMP_SEQUENCE_OF(CMS_ReceiptsFrom, d.receiptList, GENERAL_NAMES, 1)
+} ASN1_CHOICE_END(CMS_ReceiptsFrom)
+
+ASN1_SEQUENCE(CMS_ReceiptRequest) = {
+  ASN1_SIMPLE(CMS_ReceiptRequest, signedContentIdentifier, ASN1_OCTET_STRING),
+  ASN1_SIMPLE(CMS_ReceiptRequest, receiptsFrom, CMS_ReceiptsFrom),
+  ASN1_SEQUENCE_OF(CMS_ReceiptRequest, receiptsTo, GENERAL_NAMES)
+} ASN1_SEQUENCE_END(CMS_ReceiptRequest)
+
+ASN1_SEQUENCE(CMS_Receipt) = {
+  ASN1_SIMPLE(CMS_Receipt, version, LONG),
+  ASN1_SIMPLE(CMS_Receipt, contentType, ASN1_OBJECT),
+  ASN1_SIMPLE(CMS_Receipt, signedContentIdentifier, ASN1_OCTET_STRING),
+  ASN1_SIMPLE(CMS_Receipt, originatorSignatureValue, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_Receipt)
+
diff --git a/openssl/crypto/cms/cms_att.c b/openssl/crypto/cms/cms_att.c
new file mode 100644
index 0000000..5b71722
--- /dev/null
+++ b/openssl/crypto/cms/cms_att.c
@@ -0,0 +1,195 @@
+/* crypto/cms/cms_att.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include "cms.h"
+#include "cms_lcl.h"
+
+/* CMS SignedData Attribute utilities */
+
+int CMS_signed_get_attr_count(const CMS_SignerInfo *si)
+{
+	return X509at_get_attr_count(si->signedAttrs);
+}
+
+int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+			  int lastpos)
+{
+	return X509at_get_attr_by_NID(si->signedAttrs, nid, lastpos);
+}
+
+int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
+			  int lastpos)
+{
+	return X509at_get_attr_by_OBJ(si->signedAttrs, obj, lastpos);
+}
+
+X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc)
+{
+	return X509at_get_attr(si->signedAttrs, loc);
+}
+
+X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc)
+{
+	return X509at_delete_attr(si->signedAttrs, loc);
+}
+
+int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
+{
+	if(X509at_add1_attr(&si->signedAttrs, attr)) return 1;
+	return 0;
+}
+
+int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
+			const ASN1_OBJECT *obj, int type,
+			const void *bytes, int len)
+{
+	if(X509at_add1_attr_by_OBJ(&si->signedAttrs, obj,
+				type, bytes, len)) return 1;
+	return 0;
+}
+
+int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
+			int nid, int type,
+			const void *bytes, int len)
+{
+	if(X509at_add1_attr_by_NID(&si->signedAttrs, nid,
+				type, bytes, len)) return 1;
+	return 0;
+}
+
+int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
+			const char *attrname, int type,
+			const void *bytes, int len)
+{
+	if(X509at_add1_attr_by_txt(&si->signedAttrs, attrname,
+				type, bytes, len)) return 1;
+	return 0;
+}
+
+void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+					int lastpos, int type)
+{
+	return X509at_get0_data_by_OBJ(si->signedAttrs, oid, lastpos, type);
+}
+
+int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si)
+{
+	return X509at_get_attr_count(si->unsignedAttrs);
+}
+
+int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+			  int lastpos)
+{
+	return X509at_get_attr_by_NID(si->unsignedAttrs, nid, lastpos);
+}
+
+int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
+			  int lastpos)
+{
+	return X509at_get_attr_by_OBJ(si->unsignedAttrs, obj, lastpos);
+}
+
+X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc)
+{
+	return X509at_get_attr(si->unsignedAttrs, loc);
+}
+
+X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc)
+{
+	return X509at_delete_attr(si->unsignedAttrs, loc);
+}
+
+int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
+{
+	if(X509at_add1_attr(&si->unsignedAttrs, attr)) return 1;
+	return 0;
+}
+
+int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
+			const ASN1_OBJECT *obj, int type,
+			const void *bytes, int len)
+{
+	if(X509at_add1_attr_by_OBJ(&si->unsignedAttrs, obj,
+				type, bytes, len)) return 1;
+	return 0;
+}
+
+int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
+			int nid, int type,
+			const void *bytes, int len)
+{
+	if(X509at_add1_attr_by_NID(&si->unsignedAttrs, nid,
+				type, bytes, len)) return 1;
+	return 0;
+}
+
+int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
+			const char *attrname, int type,
+			const void *bytes, int len)
+{
+	if(X509at_add1_attr_by_txt(&si->unsignedAttrs, attrname,
+				type, bytes, len)) return 1;
+	return 0;
+}
+
+void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+					int lastpos, int type)
+{
+	return X509at_get0_data_by_OBJ(si->unsignedAttrs, oid, lastpos, type);
+}
+
+/* Specific attribute cases */
diff --git a/openssl/crypto/cms/cms_cd.c b/openssl/crypto/cms/cms_cd.c
new file mode 100644
index 0000000..a5fc2c4
--- /dev/null
+++ b/openssl/crypto/cms/cms_cd.c
@@ -0,0 +1,134 @@
+/* crypto/cms/cms_cd.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include <openssl/bio.h>
+#include <openssl/comp.h>
+#include "cms_lcl.h"
+
+DECLARE_ASN1_ITEM(CMS_CompressedData)
+
+#ifdef ZLIB
+
+/* CMS CompressedData Utilities */
+
+CMS_ContentInfo *cms_CompressedData_create(int comp_nid)
+	{
+	CMS_ContentInfo *cms;
+	CMS_CompressedData *cd;
+	/* Will need something cleverer if there is ever more than one
+	 * compression algorithm or parameters have some meaning...
+	 */
+	if (comp_nid != NID_zlib_compression)
+		{
+		CMSerr(CMS_F_CMS_COMPRESSEDDATA_CREATE,
+				CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+		return NULL;
+		}
+	cms = CMS_ContentInfo_new();
+	if (!cms)
+		return NULL;
+
+	cd = M_ASN1_new_of(CMS_CompressedData);
+
+	if (!cd)
+		goto err;
+
+	cms->contentType = OBJ_nid2obj(NID_id_smime_ct_compressedData);
+	cms->d.compressedData = cd;
+
+	cd->version = 0;
+
+	X509_ALGOR_set0(cd->compressionAlgorithm,
+			OBJ_nid2obj(NID_zlib_compression),
+			V_ASN1_UNDEF, NULL);
+
+	cd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);
+
+	return cms;
+
+	err:
+
+	if (cms)
+		CMS_ContentInfo_free(cms);
+
+	return NULL;
+	}
+
+BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms)
+	{
+	CMS_CompressedData *cd;
+	ASN1_OBJECT *compoid;
+	if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData)
+		{
+		CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
+				CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA);
+		return NULL;
+		}
+	cd = cms->d.compressedData;
+	X509_ALGOR_get0(&compoid, NULL, NULL, cd->compressionAlgorithm);
+	if (OBJ_obj2nid(compoid) != NID_zlib_compression)
+		{
+		CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
+				CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+		return NULL;
+		}
+	return BIO_new(BIO_f_zlib());
+	}
+
+#endif
diff --git a/openssl/crypto/cms/cms_dd.c b/openssl/crypto/cms/cms_dd.c
new file mode 100644
index 0000000..8919c15
--- /dev/null
+++ b/openssl/crypto/cms/cms_dd.c
@@ -0,0 +1,148 @@
+/* crypto/cms/cms_dd.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+
+DECLARE_ASN1_ITEM(CMS_DigestedData)
+
+/* CMS DigestedData Utilities */
+
+CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md)
+	{
+	CMS_ContentInfo *cms;
+	CMS_DigestedData *dd;
+	cms = CMS_ContentInfo_new();
+	if (!cms)
+		return NULL;
+
+	dd = M_ASN1_new_of(CMS_DigestedData);
+
+	if (!dd)
+		goto err;
+
+	cms->contentType = OBJ_nid2obj(NID_pkcs7_digest);
+	cms->d.digestedData = dd;
+
+	dd->version = 0;
+	dd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);
+
+	cms_DigestAlgorithm_set(dd->digestAlgorithm, md);
+
+	return cms;
+
+	err:
+
+	if (cms)
+		CMS_ContentInfo_free(cms);
+
+	return NULL;
+	}
+
+BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms)
+	{
+	CMS_DigestedData *dd;
+	dd = cms->d.digestedData;
+	return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm);
+	}
+
+int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify)
+	{
+	EVP_MD_CTX mctx;
+	unsigned char md[EVP_MAX_MD_SIZE];
+	unsigned int mdlen;
+	int r = 0;
+	CMS_DigestedData *dd;
+	EVP_MD_CTX_init(&mctx);
+
+	dd = cms->d.digestedData;
+
+	if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, dd->digestAlgorithm))
+		goto err;
+
+	if (EVP_DigestFinal_ex(&mctx, md, &mdlen) <= 0)
+		goto err;
+
+	if (verify)
+		{
+		if (mdlen != (unsigned int)dd->digest->length)
+			{
+			CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
+				CMS_R_MESSAGEDIGEST_WRONG_LENGTH);
+			goto err;
+			}
+
+		if (memcmp(md, dd->digest->data, mdlen))
+			CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
+				CMS_R_VERIFICATION_FAILURE);
+		else
+			r = 1;
+		}
+	else
+		{
+		if (!ASN1_STRING_set(dd->digest, md, mdlen))
+			goto err;
+		r = 1;
+		}
+
+	err:
+	EVP_MD_CTX_cleanup(&mctx);
+
+	return r;
+
+	}
diff --git a/openssl/crypto/cms/cms_enc.c b/openssl/crypto/cms/cms_enc.c
new file mode 100644
index 0000000..bab2623
--- /dev/null
+++ b/openssl/crypto/cms/cms_enc.c
@@ -0,0 +1,262 @@
+/* crypto/cms/cms_enc.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include <openssl/rand.h>
+#include "cms_lcl.h"
+
+/* CMS EncryptedData Utilities */
+
+DECLARE_ASN1_ITEM(CMS_EncryptedData)
+
+/* Return BIO based on EncryptedContentInfo and key */
+
+BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
+	{
+	BIO *b;
+	EVP_CIPHER_CTX *ctx;
+	const EVP_CIPHER *ciph;
+	X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
+	unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;
+
+	int ok = 0;
+
+	int enc, keep_key = 0;
+
+	enc = ec->cipher ? 1 : 0;
+
+	b = BIO_new(BIO_f_cipher());
+	if (!b)
+		{
+		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+							ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+
+	BIO_get_cipher_ctx(b, &ctx);
+
+	if (enc)
+		{
+		ciph = ec->cipher;
+		/* If not keeping key set cipher to NULL so subsequent calls
+		 * decrypt.
+		 */
+		if (ec->key)
+			ec->cipher = NULL;
+		}
+	else
+		{
+		ciph = EVP_get_cipherbyobj(calg->algorithm);
+
+		if (!ciph)
+			{
+			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+							CMS_R_UNKNOWN_CIPHER);
+			goto err;
+			}
+		}
+
+	if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0)
+		{
+		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+				CMS_R_CIPHER_INITIALISATION_ERROR);
+		goto err;
+		}
+
+	if (enc)
+		{
+		int ivlen;
+		calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
+		/* Generate a random IV if we need one */
+		ivlen = EVP_CIPHER_CTX_iv_length(ctx);
+		if (ivlen > 0)
+			{
+			if (RAND_pseudo_bytes(iv, ivlen) <= 0)
+				goto err;
+			piv = iv;
+			}
+		}
+	else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0)
+		{
+		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
+		goto err;
+		}
+
+
+	if (enc && !ec->key)
+		{
+		/* Generate random key */
+		if (!ec->keylen)
+			ec->keylen = EVP_CIPHER_CTX_key_length(ctx);
+		ec->key = OPENSSL_malloc(ec->keylen);
+		if (!ec->key)
+			{
+			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+							ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		if (EVP_CIPHER_CTX_rand_key(ctx, ec->key) <= 0)
+			goto err;
+		keep_key = 1;
+		}
+	else if (ec->keylen != (unsigned int)EVP_CIPHER_CTX_key_length(ctx))
+		{
+		/* If necessary set key length */
+		if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0)
+			{
+			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+				CMS_R_INVALID_KEY_LENGTH);
+			goto err;
+			}
+		}
+
+	if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0)
+		{
+		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+				CMS_R_CIPHER_INITIALISATION_ERROR);
+		goto err;
+		}
+
+	if (piv)
+		{
+		calg->parameter = ASN1_TYPE_new();
+		if (!calg->parameter)
+			{
+			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+							ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0)
+			{
+			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
+			goto err;
+			}
+		}
+	ok = 1;
+
+	err:
+	if (ec->key && !keep_key)
+		{
+		OPENSSL_cleanse(ec->key, ec->keylen);
+		OPENSSL_free(ec->key);
+		ec->key = NULL;
+		}
+	if (ok)
+		return b;
+	BIO_free(b);
+	return NULL;
+	}
+
+int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, 
+				const EVP_CIPHER *cipher,
+				const unsigned char *key, size_t keylen)
+	{
+	ec->cipher = cipher;
+	if (key)
+		{
+		ec->key = OPENSSL_malloc(keylen);
+		if (!ec->key)
+			return 0;
+		memcpy(ec->key, key, keylen);
+		}
+	ec->keylen = keylen;
+	if (cipher)
+		ec->contentType = OBJ_nid2obj(NID_pkcs7_data);
+	return 1;
+	}
+
+int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
+				const unsigned char *key, size_t keylen)
+	{
+	CMS_EncryptedContentInfo *ec;
+	if (!key || !keylen)
+		{
+		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY);
+		return 0;
+		}
+	if (ciph)
+		{
+		cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData);
+		if (!cms->d.encryptedData)
+			{
+			CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY,
+				ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted);
+		cms->d.encryptedData->version = 0;
+		}
+	else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted)
+		{
+		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY,
+						CMS_R_NOT_ENCRYPTED_DATA);
+		return 0;
+		}
+	ec = cms->d.encryptedData->encryptedContentInfo;
+	return cms_EncryptedContent_init(ec, ciph, key, keylen);
+	}
+
+BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms)
+	{
+	CMS_EncryptedData *enc = cms->d.encryptedData;
+	if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs)
+		enc->version = 2;
+	return cms_EncryptedContent_init_bio(enc->encryptedContentInfo);
+	}
diff --git a/openssl/crypto/cms/cms_env.c b/openssl/crypto/cms/cms_env.c
new file mode 100644
index 0000000..b3237d4
--- /dev/null
+++ b/openssl/crypto/cms/cms_env.c
@@ -0,0 +1,862 @@
+/* crypto/cms/cms_env.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include <openssl/rand.h>
+#include <openssl/aes.h>
+#include "cms_lcl.h"
+#include "asn1_locl.h"
+
+/* CMS EnvelopedData Utilities */
+
+DECLARE_ASN1_ITEM(CMS_EnvelopedData)
+DECLARE_ASN1_ITEM(CMS_RecipientInfo)
+DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)
+DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo)
+DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute)
+
+DECLARE_STACK_OF(CMS_RecipientInfo)
+
+static CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
+	{
+	if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped)
+		{
+		CMSerr(CMS_F_CMS_GET0_ENVELOPED,
+				CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
+		return NULL;
+		}
+	return cms->d.envelopedData;
+	}
+
+static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
+	{
+	if (cms->d.other == NULL)
+		{
+		cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData);
+		if (!cms->d.envelopedData)
+			{
+			CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT,
+							ERR_R_MALLOC_FAILURE);
+			return NULL;
+			}
+		cms->d.envelopedData->version = 0;
+		cms->d.envelopedData->encryptedContentInfo->contentType =
+						OBJ_nid2obj(NID_pkcs7_data);
+		ASN1_OBJECT_free(cms->contentType);
+		cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
+		return cms->d.envelopedData;
+		}
+	return cms_get0_enveloped(cms);
+	}
+
+STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
+	{
+	CMS_EnvelopedData *env;
+	env = cms_get0_enveloped(cms);
+	if (!env)
+		return NULL;
+	return env->recipientInfos;
+	}
+
+int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
+	{
+	return ri->type;
+	}
+
+CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
+	{
+	CMS_ContentInfo *cms;
+	CMS_EnvelopedData *env;
+	cms = CMS_ContentInfo_new();
+	if (!cms)
+		goto merr;
+	env = cms_enveloped_data_init(cms);
+	if (!env)
+		goto merr;
+	if (!cms_EncryptedContent_init(env->encryptedContentInfo,
+					cipher, NULL, 0))
+		goto merr;
+	return cms;
+	merr:
+	if (cms)
+		CMS_ContentInfo_free(cms);
+	CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE);
+	return NULL;
+	}
+
+/* Key Transport Recipient Info (KTRI) routines */
+
+/* Add a recipient certificate. For now only handle key transport.
+ * If we ever handle key agreement will need updating.
+ */
+
+CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
+					X509 *recip, unsigned int flags)
+	{
+	CMS_RecipientInfo *ri = NULL;
+	CMS_KeyTransRecipientInfo *ktri;
+	CMS_EnvelopedData *env;
+	EVP_PKEY *pk = NULL;
+	int i, type;
+	env = cms_get0_enveloped(cms);
+	if (!env)
+		goto err;
+
+	/* Initialize recipient info */
+	ri = M_ASN1_new_of(CMS_RecipientInfo);
+	if (!ri)
+		goto merr;
+
+	/* Initialize and add key transport recipient info */
+
+	ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo);
+	if (!ri->d.ktri)
+		goto merr;
+	ri->type = CMS_RECIPINFO_TRANS;
+
+	ktri = ri->d.ktri;
+
+	X509_check_purpose(recip, -1, -1);
+	pk = X509_get_pubkey(recip);
+	if (!pk)
+		{
+		CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
+				CMS_R_ERROR_GETTING_PUBLIC_KEY);
+		goto err;
+		}
+	CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509);
+	ktri->pkey = pk;
+	ktri->recip = recip;
+
+	if (flags & CMS_USE_KEYID)
+		{
+		ktri->version = 2;
+		type = CMS_RECIPINFO_KEYIDENTIFIER;
+		}
+	else
+		{
+		ktri->version = 0;
+		type = CMS_RECIPINFO_ISSUER_SERIAL;
+		}
+
+	/* Not a typo: RecipientIdentifier and SignerIdentifier are the
+	 * same structure.
+	 */
+
+	if (!cms_set1_SignerIdentifier(ktri->rid, recip, type))
+		goto err;
+
+	if (pk->ameth && pk->ameth->pkey_ctrl)
+		{
+		i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_ENVELOPE,
+						0, ri);
+		if (i == -2)
+			{
+			CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
+				CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+			goto err;
+			}
+		if (i <= 0)
+			{
+			CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
+				CMS_R_CTRL_FAILURE);
+			goto err;
+			}
+		}
+
+	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
+		goto merr;
+
+	return ri;
+
+	merr:
+	CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE);
+	err:
+	if (ri)
+		M_ASN1_free_of(ri, CMS_RecipientInfo);
+	return NULL;
+
+	}
+
+int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
+					EVP_PKEY **pk, X509 **recip,
+					X509_ALGOR **palg)
+	{
+	CMS_KeyTransRecipientInfo *ktri;
+	if (ri->type != CMS_RECIPINFO_TRANS)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS,
+			CMS_R_NOT_KEY_TRANSPORT);
+		return 0;
+		}
+
+	ktri = ri->d.ktri;
+
+	if (pk)
+		*pk = ktri->pkey;
+	if (recip)
+		*recip = ktri->recip;
+	if (palg)
+		*palg = ktri->keyEncryptionAlgorithm;
+	return 1;
+	}
+
+int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
+					ASN1_OCTET_STRING **keyid,
+					X509_NAME **issuer, ASN1_INTEGER **sno)
+	{
+	CMS_KeyTransRecipientInfo *ktri;
+	if (ri->type != CMS_RECIPINFO_TRANS)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID,
+			CMS_R_NOT_KEY_TRANSPORT);
+		return 0;
+		}
+	ktri = ri->d.ktri;
+
+	return cms_SignerIdentifier_get0_signer_id(ktri->rid,
+							keyid, issuer, sno);
+	}
+
+int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
+	{
+	if (ri->type != CMS_RECIPINFO_TRANS)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
+			CMS_R_NOT_KEY_TRANSPORT);
+		return -2;
+		}
+	return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
+	}
+
+int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
+	{
+	if (ri->type != CMS_RECIPINFO_TRANS)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY,
+			CMS_R_NOT_KEY_TRANSPORT);
+		return 0;
+		}
+	ri->d.ktri->pkey = pkey;
+	return 1;
+	}
+
+/* Encrypt content key in key transport recipient info */
+
+static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
+					CMS_RecipientInfo *ri)
+	{
+	CMS_KeyTransRecipientInfo *ktri;
+	CMS_EncryptedContentInfo *ec;
+	EVP_PKEY_CTX *pctx = NULL;
+	unsigned char *ek = NULL;
+	size_t eklen;
+
+	int ret = 0;
+
+	if (ri->type != CMS_RECIPINFO_TRANS)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
+			CMS_R_NOT_KEY_TRANSPORT);
+		return 0;
+		}
+	ktri = ri->d.ktri;
+	ec = cms->d.envelopedData->encryptedContentInfo;
+
+	pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
+	if (!pctx)
+		return 0;
+
+	if (EVP_PKEY_encrypt_init(pctx) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
+				EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
+		goto err;
+		}
+
+	if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
+		goto err;
+
+	ek = OPENSSL_malloc(eklen);
+
+	if (ek == NULL)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
+							ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
+		goto err;
+
+	ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
+	ek = NULL;
+
+	ret = 1;
+
+	err:
+	if (pctx)
+		EVP_PKEY_CTX_free(pctx);
+	if (ek)
+		OPENSSL_free(ek);
+	return ret;
+
+	}
+
+/* Decrypt content key from KTRI */
+
+static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
+							CMS_RecipientInfo *ri)
+	{
+	CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
+	EVP_PKEY_CTX *pctx = NULL;
+	unsigned char *ek = NULL;
+	size_t eklen;
+	int ret = 0;
+
+	if (ktri->pkey == NULL)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
+			CMS_R_NO_PRIVATE_KEY);
+		return 0;
+		}
+
+	pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
+	if (!pctx)
+		return 0;
+
+	if (EVP_PKEY_decrypt_init(pctx) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
+				EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
+		goto err;
+		}
+
+	if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
+				ktri->encryptedKey->data,
+				ktri->encryptedKey->length) <= 0)
+		goto err;
+
+	ek = OPENSSL_malloc(eklen);
+
+	if (ek == NULL)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
+							ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (EVP_PKEY_decrypt(pctx, ek, &eklen,
+				ktri->encryptedKey->data,
+				ktri->encryptedKey->length) <= 0)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
+		goto err;
+		}
+
+	ret = 1;
+
+	cms->d.envelopedData->encryptedContentInfo->key = ek;
+	cms->d.envelopedData->encryptedContentInfo->keylen = eklen;
+
+	err:
+	if (pctx)
+		EVP_PKEY_CTX_free(pctx);
+	if (!ret && ek)
+		OPENSSL_free(ek);
+
+	return ret;
+	}
+
+/* Key Encrypted Key (KEK) RecipientInfo routines */
+
+int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, 
+					const unsigned char *id, size_t idlen)
+	{
+	ASN1_OCTET_STRING tmp_os;
+	CMS_KEKRecipientInfo *kekri;
+	if (ri->type != CMS_RECIPINFO_KEK)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK);
+		return -2;
+		}
+	kekri = ri->d.kekri;
+	tmp_os.type = V_ASN1_OCTET_STRING;
+	tmp_os.flags = 0;
+	tmp_os.data = (unsigned char *)id;
+	tmp_os.length = (int)idlen;
+	return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
+	}
+
+/* For now hard code AES key wrap info */
+
+static size_t aes_wrap_keylen(int nid)
+	{
+	switch (nid)
+		{
+		case NID_id_aes128_wrap:
+		return 16;
+
+		case NID_id_aes192_wrap:
+		return  24;
+
+		case NID_id_aes256_wrap:
+		return  32;
+
+		default:
+		return 0;
+		}
+	}
+
+CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
+					unsigned char *key, size_t keylen,
+					unsigned char *id, size_t idlen,
+					ASN1_GENERALIZEDTIME *date,
+					ASN1_OBJECT *otherTypeId,
+					ASN1_TYPE *otherType)
+	{
+	CMS_RecipientInfo *ri = NULL;
+	CMS_EnvelopedData *env;
+	CMS_KEKRecipientInfo *kekri;
+	env = cms_get0_enveloped(cms);
+	if (!env)
+		goto err;
+
+	if (nid == NID_undef)
+		{
+		switch (keylen)
+			{
+			case 16:
+			nid = NID_id_aes128_wrap;
+			break;
+
+			case  24:
+			nid = NID_id_aes192_wrap;
+			break;
+
+			case  32:
+			nid = NID_id_aes256_wrap;
+			break;
+
+			default:
+			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
+						CMS_R_INVALID_KEY_LENGTH);
+			goto err;
+			}
+
+		}
+	else
+		{
+
+		size_t exp_keylen = aes_wrap_keylen(nid);
+
+		if (!exp_keylen)
+			{
+			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
+					CMS_R_UNSUPPORTED_KEK_ALGORITHM);
+			goto err;
+			}
+
+		if (keylen != exp_keylen)
+			{
+			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
+					CMS_R_INVALID_KEY_LENGTH);
+			goto err;
+			}
+
+		}
+
+	/* Initialize recipient info */
+	ri = M_ASN1_new_of(CMS_RecipientInfo);
+	if (!ri)
+		goto merr;
+
+	ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
+	if (!ri->d.kekri)
+		goto merr;
+	ri->type = CMS_RECIPINFO_KEK;
+
+	kekri = ri->d.kekri;
+
+	if (otherTypeId)
+		{
+		kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
+		if (kekri->kekid->other == NULL)
+			goto merr;
+		}
+
+	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
+		goto merr;
+
+
+	/* After this point no calls can fail */
+
+	kekri->version = 4;
+
+	kekri->key = key;
+	kekri->keylen = keylen;
+
+	ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);
+
+	kekri->kekid->date = date;
+
+	if (kekri->kekid->other)
+		{
+		kekri->kekid->other->keyAttrId = otherTypeId;
+		kekri->kekid->other->keyAttr = otherType;
+		}
+
+	X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
+				OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);
+
+	return ri;
+
+	merr:
+	CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE);
+	err:
+	if (ri)
+		M_ASN1_free_of(ri, CMS_RecipientInfo);
+	return NULL;
+
+	}
+
+int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
+					X509_ALGOR **palg,
+					ASN1_OCTET_STRING **pid,
+					ASN1_GENERALIZEDTIME **pdate,
+					ASN1_OBJECT **potherid,
+					ASN1_TYPE **pothertype)
+	{
+	CMS_KEKIdentifier *rkid;
+	if (ri->type != CMS_RECIPINFO_KEK)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK);
+		return 0;
+		}
+	rkid =  ri->d.kekri->kekid;
+	if (palg)
+		*palg = ri->d.kekri->keyEncryptionAlgorithm;
+	if (pid)
+		*pid = rkid->keyIdentifier;
+	if (pdate)
+		*pdate = rkid->date;
+	if (potherid)
+		{
+		if (rkid->other)
+			*potherid = rkid->other->keyAttrId;
+		else
+			*potherid = NULL;
+		}
+	if (pothertype)
+		{
+		if (rkid->other)
+			*pothertype = rkid->other->keyAttr;
+		else
+			*pothertype = NULL;
+		}
+	return 1;
+	}
+
+int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, 
+				unsigned char *key, size_t keylen)
+	{
+	CMS_KEKRecipientInfo *kekri;
+	if (ri->type != CMS_RECIPINFO_KEK)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK);
+		return 0;
+		}
+
+	kekri = ri->d.kekri;
+	kekri->key = key;
+	kekri->keylen = keylen;
+	return 1;
+	}
+
+
+/* Encrypt content key in KEK recipient info */
+
+static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms,
+					CMS_RecipientInfo *ri)
+	{
+	CMS_EncryptedContentInfo *ec;
+	CMS_KEKRecipientInfo *kekri;
+	AES_KEY actx;
+	unsigned char *wkey = NULL;
+	int wkeylen;
+	int r = 0;
+
+	ec = cms->d.envelopedData->encryptedContentInfo;
+
+	kekri = ri->d.kekri;
+
+	if (!kekri->key)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY);
+		return 0;
+		}
+
+	if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx))
+		{ 
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
+						CMS_R_ERROR_SETTING_KEY);
+		goto err;
+		}
+
+	wkey = OPENSSL_malloc(ec->keylen + 8);
+
+	if (!wkey)
+		{ 
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
+						ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen);
+
+	if (wkeylen <= 0)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
+		goto err;
+		}
+
+	ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);
+
+	r = 1;
+
+	err:
+
+	if (!r && wkey)
+		OPENSSL_free(wkey);
+	OPENSSL_cleanse(&actx, sizeof(actx));
+
+	return r;
+
+	}
+
+/* Decrypt content key in KEK recipient info */
+
+static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
+					CMS_RecipientInfo *ri)
+	{
+	CMS_EncryptedContentInfo *ec;
+	CMS_KEKRecipientInfo *kekri;
+	AES_KEY actx;
+	unsigned char *ukey = NULL;
+	int ukeylen;
+	int r = 0, wrap_nid;
+
+	ec = cms->d.envelopedData->encryptedContentInfo;
+
+	kekri = ri->d.kekri;
+
+	if (!kekri->key)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY);
+		return 0;
+		}
+
+	wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
+	if (aes_wrap_keylen(wrap_nid) != kekri->keylen)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
+			CMS_R_INVALID_KEY_LENGTH);
+		return 0;
+		}
+
+	/* If encrypted key length is invalid don't bother */
+
+	if (kekri->encryptedKey->length < 16)
+		{ 
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
+					CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
+		goto err;
+		}
+
+	if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx))
+		{ 
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
+						CMS_R_ERROR_SETTING_KEY);
+		goto err;
+		}
+
+	ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
+
+	if (!ukey)
+		{ 
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
+						ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	ukeylen = AES_unwrap_key(&actx, NULL, ukey,
+					kekri->encryptedKey->data,
+					kekri->encryptedKey->length);
+
+	if (ukeylen <= 0)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
+							CMS_R_UNWRAP_ERROR);
+		goto err;
+		}
+
+	ec->key = ukey;
+	ec->keylen = ukeylen;
+
+	r = 1;
+
+	err:
+
+	if (!r && ukey)
+		OPENSSL_free(ukey);
+	OPENSSL_cleanse(&actx, sizeof(actx));
+
+	return r;
+
+	}
+
+int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
+	{
+	switch(ri->type)
+		{
+		case CMS_RECIPINFO_TRANS:
+		return cms_RecipientInfo_ktri_decrypt(cms, ri);
+
+		case CMS_RECIPINFO_KEK:
+		return cms_RecipientInfo_kekri_decrypt(cms, ri);
+
+		default:
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
+			CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE);
+		return 0;
+		}
+	}
+
+BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
+	{
+	CMS_EncryptedContentInfo *ec;
+	STACK_OF(CMS_RecipientInfo) *rinfos;
+	CMS_RecipientInfo *ri;
+	int i, r, ok = 0;
+	BIO *ret;
+
+	/* Get BIO first to set up key */
+
+	ec = cms->d.envelopedData->encryptedContentInfo;
+	ret = cms_EncryptedContent_init_bio(ec);
+
+	/* If error or no cipher end of processing */
+
+	if (!ret || !ec->cipher)
+		return ret;
+
+	/* Now encrypt content key according to each RecipientInfo type */
+
+	rinfos = cms->d.envelopedData->recipientInfos;
+
+	for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++)
+		{
+		ri = sk_CMS_RecipientInfo_value(rinfos, i);
+
+		switch (ri->type)
+			{
+			case CMS_RECIPINFO_TRANS:
+			r = cms_RecipientInfo_ktri_encrypt(cms, ri);
+			break;
+
+			case CMS_RECIPINFO_KEK:
+			r = cms_RecipientInfo_kekri_encrypt(cms, ri);
+			break;
+
+			default:
+			CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
+				CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
+			goto err;
+			}
+
+		if (r <= 0)
+			{
+			CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
+				CMS_R_ERROR_SETTING_RECIPIENTINFO);
+			goto err;
+			}
+		}
+
+	ok = 1;
+
+	err:
+	ec->cipher = NULL;
+	if (ec->key)
+		{
+		OPENSSL_cleanse(ec->key, ec->keylen);
+		OPENSSL_free(ec->key);
+		ec->key = NULL;
+		ec->keylen = 0;
+		}
+	if (ok)
+		return ret;
+	BIO_free(ret);
+	return NULL;
+
+	}
diff --git a/openssl/crypto/cms/cms_err.c b/openssl/crypto/cms/cms_err.c
new file mode 100644
index 0000000..ff7b030
--- /dev/null
+++ b/openssl/crypto/cms/cms_err.c
@@ -0,0 +1,236 @@
+/* crypto/cms/cms_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_CMS,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_CMS,0,reason)
+
+static ERR_STRING_DATA CMS_str_functs[]=
+	{
+{ERR_FUNC(CMS_F_CHECK_CONTENT),	"CHECK_CONTENT"},
+{ERR_FUNC(CMS_F_CMS_ADD0_CERT),	"CMS_add0_cert"},
+{ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_KEY),	"CMS_add0_recipient_key"},
+{ERR_FUNC(CMS_F_CMS_ADD1_RECEIPTREQUEST),	"CMS_add1_ReceiptRequest"},
+{ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT),	"CMS_add1_recipient_cert"},
+{ERR_FUNC(CMS_F_CMS_ADD1_SIGNER),	"CMS_add1_signer"},
+{ERR_FUNC(CMS_F_CMS_ADD1_SIGNINGTIME),	"CMS_ADD1_SIGNINGTIME"},
+{ERR_FUNC(CMS_F_CMS_COMPRESS),	"CMS_compress"},
+{ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_CREATE),	"cms_CompressedData_create"},
+{ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO),	"cms_CompressedData_init_bio"},
+{ERR_FUNC(CMS_F_CMS_COPY_CONTENT),	"CMS_COPY_CONTENT"},
+{ERR_FUNC(CMS_F_CMS_COPY_MESSAGEDIGEST),	"CMS_COPY_MESSAGEDIGEST"},
+{ERR_FUNC(CMS_F_CMS_DATA),	"CMS_data"},
+{ERR_FUNC(CMS_F_CMS_DATAFINAL),	"CMS_dataFinal"},
+{ERR_FUNC(CMS_F_CMS_DATAINIT),	"CMS_dataInit"},
+{ERR_FUNC(CMS_F_CMS_DECRYPT),	"CMS_decrypt"},
+{ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_KEY),	"CMS_decrypt_set1_key"},
+{ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PKEY),	"CMS_decrypt_set1_pkey"},
+{ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX),	"cms_DigestAlgorithm_find_ctx"},
+{ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO),	"cms_DigestAlgorithm_init_bio"},
+{ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL),	"cms_DigestedData_do_final"},
+{ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY),	"CMS_digest_verify"},
+{ERR_FUNC(CMS_F_CMS_ENCODE_RECEIPT),	"cms_encode_Receipt"},
+{ERR_FUNC(CMS_F_CMS_ENCRYPT),	"CMS_encrypt"},
+{ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO),	"cms_EncryptedContent_init_bio"},
+{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT),	"CMS_EncryptedData_decrypt"},
+{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT),	"CMS_EncryptedData_encrypt"},
+{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY),	"CMS_EncryptedData_set1_key"},
+{ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_CREATE),	"CMS_EnvelopedData_create"},
+{ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO),	"cms_EnvelopedData_init_bio"},
+{ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT),	"CMS_ENVELOPED_DATA_INIT"},
+{ERR_FUNC(CMS_F_CMS_FINAL),	"CMS_final"},
+{ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES),	"CMS_GET0_CERTIFICATE_CHOICES"},
+{ERR_FUNC(CMS_F_CMS_GET0_CONTENT),	"CMS_get0_content"},
+{ERR_FUNC(CMS_F_CMS_GET0_ECONTENT_TYPE),	"CMS_GET0_ECONTENT_TYPE"},
+{ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED),	"CMS_GET0_ENVELOPED"},
+{ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES),	"CMS_GET0_REVOCATION_CHOICES"},
+{ERR_FUNC(CMS_F_CMS_GET0_SIGNED),	"CMS_GET0_SIGNED"},
+{ERR_FUNC(CMS_F_CMS_MSGSIGDIGEST_ADD1),	"cms_msgSigDigest_add1"},
+{ERR_FUNC(CMS_F_CMS_RECEIPTREQUEST_CREATE0),	"CMS_ReceiptRequest_create0"},
+{ERR_FUNC(CMS_F_CMS_RECEIPT_VERIFY),	"cms_Receipt_verify"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_DECRYPT),	"CMS_RecipientInfo_decrypt"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT),	"CMS_RECIPIENTINFO_KEKRI_DECRYPT"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT),	"CMS_RECIPIENTINFO_KEKRI_ENCRYPT"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID),	"CMS_RecipientInfo_kekri_get0_id"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP),	"CMS_RecipientInfo_kekri_id_cmp"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP),	"CMS_RecipientInfo_ktri_cert_cmp"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT),	"CMS_RECIPIENTINFO_KTRI_DECRYPT"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT),	"CMS_RECIPIENTINFO_KTRI_ENCRYPT"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS),	"CMS_RecipientInfo_ktri_get0_algs"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID),	"CMS_RecipientInfo_ktri_get0_signer_id"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_KEY),	"CMS_RecipientInfo_set0_key"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY),	"CMS_RecipientInfo_set0_pkey"},
+{ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER),	"cms_set1_SignerIdentifier"},
+{ERR_FUNC(CMS_F_CMS_SET_DETACHED),	"CMS_set_detached"},
+{ERR_FUNC(CMS_F_CMS_SIGN),	"CMS_sign"},
+{ERR_FUNC(CMS_F_CMS_SIGNED_DATA_INIT),	"CMS_SIGNED_DATA_INIT"},
+{ERR_FUNC(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN),	"CMS_SIGNERINFO_CONTENT_SIGN"},
+{ERR_FUNC(CMS_F_CMS_SIGNERINFO_SIGN),	"CMS_SignerInfo_sign"},
+{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY),	"CMS_SignerInfo_verify"},
+{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT),	"CMS_SIGNERINFO_VERIFY_CERT"},
+{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT),	"CMS_SignerInfo_verify_content"},
+{ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT),	"CMS_sign_receipt"},
+{ERR_FUNC(CMS_F_CMS_STREAM),	"CMS_stream"},
+{ERR_FUNC(CMS_F_CMS_UNCOMPRESS),	"CMS_uncompress"},
+{ERR_FUNC(CMS_F_CMS_VERIFY),	"CMS_verify"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA CMS_str_reasons[]=
+	{
+{ERR_REASON(CMS_R_ADD_SIGNER_ERROR)      ,"add signer error"},
+{ERR_REASON(CMS_R_CERTIFICATE_ALREADY_PRESENT),"certificate already present"},
+{ERR_REASON(CMS_R_CERTIFICATE_HAS_NO_KEYID),"certificate has no keyid"},
+{ERR_REASON(CMS_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"},
+{ERR_REASON(CMS_R_CIPHER_INITIALISATION_ERROR),"cipher initialisation error"},
+{ERR_REASON(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR),"cipher parameter initialisation error"},
+{ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR)   ,"cms datafinal error"},
+{ERR_REASON(CMS_R_CMS_LIB)               ,"cms lib"},
+{ERR_REASON(CMS_R_CONTENTIDENTIFIER_MISMATCH),"contentidentifier mismatch"},
+{ERR_REASON(CMS_R_CONTENT_NOT_FOUND)     ,"content not found"},
+{ERR_REASON(CMS_R_CONTENT_TYPE_MISMATCH) ,"content type mismatch"},
+{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA),"content type not compressed data"},
+{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA),"content type not enveloped data"},
+{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA),"content type not signed data"},
+{ERR_REASON(CMS_R_CONTENT_VERIFY_ERROR)  ,"content verify error"},
+{ERR_REASON(CMS_R_CTRL_ERROR)            ,"ctrl error"},
+{ERR_REASON(CMS_R_CTRL_FAILURE)          ,"ctrl failure"},
+{ERR_REASON(CMS_R_DECRYPT_ERROR)         ,"decrypt error"},
+{ERR_REASON(CMS_R_DIGEST_ERROR)          ,"digest error"},
+{ERR_REASON(CMS_R_ERROR_GETTING_PUBLIC_KEY),"error getting public key"},
+{ERR_REASON(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE),"error reading messagedigest attribute"},
+{ERR_REASON(CMS_R_ERROR_SETTING_KEY)     ,"error setting key"},
+{ERR_REASON(CMS_R_ERROR_SETTING_RECIPIENTINFO),"error setting recipientinfo"},
+{ERR_REASON(CMS_R_INVALID_ENCRYPTED_KEY_LENGTH),"invalid encrypted key length"},
+{ERR_REASON(CMS_R_INVALID_KEY_LENGTH)    ,"invalid key length"},
+{ERR_REASON(CMS_R_MD_BIO_INIT_ERROR)     ,"md bio init error"},
+{ERR_REASON(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH),"messagedigest attribute wrong length"},
+{ERR_REASON(CMS_R_MESSAGEDIGEST_WRONG_LENGTH),"messagedigest wrong length"},
+{ERR_REASON(CMS_R_MSGSIGDIGEST_ERROR)    ,"msgsigdigest error"},
+{ERR_REASON(CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE),"msgsigdigest verification failure"},
+{ERR_REASON(CMS_R_MSGSIGDIGEST_WRONG_LENGTH),"msgsigdigest wrong length"},
+{ERR_REASON(CMS_R_NEED_ONE_SIGNER)       ,"need one signer"},
+{ERR_REASON(CMS_R_NOT_A_SIGNED_RECEIPT)  ,"not a signed receipt"},
+{ERR_REASON(CMS_R_NOT_ENCRYPTED_DATA)    ,"not encrypted data"},
+{ERR_REASON(CMS_R_NOT_KEK)               ,"not kek"},
+{ERR_REASON(CMS_R_NOT_KEY_TRANSPORT)     ,"not key transport"},
+{ERR_REASON(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"not supported for this key type"},
+{ERR_REASON(CMS_R_NO_CIPHER)             ,"no cipher"},
+{ERR_REASON(CMS_R_NO_CONTENT)            ,"no content"},
+{ERR_REASON(CMS_R_NO_CONTENT_TYPE)       ,"no content type"},
+{ERR_REASON(CMS_R_NO_DEFAULT_DIGEST)     ,"no default digest"},
+{ERR_REASON(CMS_R_NO_DIGEST_SET)         ,"no digest set"},
+{ERR_REASON(CMS_R_NO_KEY)                ,"no key"},
+{ERR_REASON(CMS_R_NO_KEY_OR_CERT)        ,"no key or cert"},
+{ERR_REASON(CMS_R_NO_MATCHING_DIGEST)    ,"no matching digest"},
+{ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT) ,"no matching recipient"},
+{ERR_REASON(CMS_R_NO_MATCHING_SIGNATURE) ,"no matching signature"},
+{ERR_REASON(CMS_R_NO_MSGSIGDIGEST)       ,"no msgsigdigest"},
+{ERR_REASON(CMS_R_NO_PRIVATE_KEY)        ,"no private key"},
+{ERR_REASON(CMS_R_NO_PUBLIC_KEY)         ,"no public key"},
+{ERR_REASON(CMS_R_NO_RECEIPT_REQUEST)    ,"no receipt request"},
+{ERR_REASON(CMS_R_NO_SIGNERS)            ,"no signers"},
+{ERR_REASON(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
+{ERR_REASON(CMS_R_RECEIPT_DECODE_ERROR)  ,"receipt decode error"},
+{ERR_REASON(CMS_R_RECIPIENT_ERROR)       ,"recipient error"},
+{ERR_REASON(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
+{ERR_REASON(CMS_R_SIGNFINAL_ERROR)       ,"signfinal error"},
+{ERR_REASON(CMS_R_SMIME_TEXT_ERROR)      ,"smime text error"},
+{ERR_REASON(CMS_R_STORE_INIT_ERROR)      ,"store init error"},
+{ERR_REASON(CMS_R_TYPE_NOT_COMPRESSED_DATA),"type not compressed data"},
+{ERR_REASON(CMS_R_TYPE_NOT_DATA)         ,"type not data"},
+{ERR_REASON(CMS_R_TYPE_NOT_DIGESTED_DATA),"type not digested data"},
+{ERR_REASON(CMS_R_TYPE_NOT_ENCRYPTED_DATA),"type not encrypted data"},
+{ERR_REASON(CMS_R_TYPE_NOT_ENVELOPED_DATA),"type not enveloped data"},
+{ERR_REASON(CMS_R_UNABLE_TO_FINALIZE_CONTEXT),"unable to finalize context"},
+{ERR_REASON(CMS_R_UNKNOWN_CIPHER)        ,"unknown cipher"},
+{ERR_REASON(CMS_R_UNKNOWN_DIGEST_ALGORIHM),"unknown digest algorihm"},
+{ERR_REASON(CMS_R_UNKNOWN_ID)            ,"unknown id"},
+{ERR_REASON(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"},
+{ERR_REASON(CMS_R_UNSUPPORTED_CONTENT_TYPE),"unsupported content type"},
+{ERR_REASON(CMS_R_UNSUPPORTED_KEK_ALGORITHM),"unsupported kek algorithm"},
+{ERR_REASON(CMS_R_UNSUPPORTED_RECIPIENT_TYPE),"unsupported recipient type"},
+{ERR_REASON(CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE),"unsupported recpientinfo type"},
+{ERR_REASON(CMS_R_UNSUPPORTED_TYPE)      ,"unsupported type"},
+{ERR_REASON(CMS_R_UNWRAP_ERROR)          ,"unwrap error"},
+{ERR_REASON(CMS_R_VERIFICATION_FAILURE)  ,"verification failure"},
+{ERR_REASON(CMS_R_WRAP_ERROR)            ,"wrap error"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_CMS_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(CMS_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,CMS_str_functs);
+		ERR_load_strings(0,CMS_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/cms/cms_ess.c b/openssl/crypto/cms/cms_ess.c
new file mode 100644
index 0000000..90c0b82
--- /dev/null
+++ b/openssl/crypto/cms/cms_ess.c
@@ -0,0 +1,420 @@
+/* crypto/cms/cms_ess.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+
+DECLARE_ASN1_ITEM(CMS_ReceiptRequest)
+DECLARE_ASN1_ITEM(CMS_Receipt)
+
+IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)
+
+/* ESS services: for now just Signed Receipt related */
+
+int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr)
+	{
+	ASN1_STRING *str;
+	CMS_ReceiptRequest *rr = NULL;
+	if (prr)
+		*prr = NULL;
+	str = CMS_signed_get0_data_by_OBJ(si,
+				OBJ_nid2obj(NID_id_smime_aa_receiptRequest),
+					-3, V_ASN1_SEQUENCE);
+	if (!str)
+		return 0;
+
+	rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest));
+	if (!rr)
+		return -1;
+	if (prr)
+		*prr = rr;
+	else
+		CMS_ReceiptRequest_free(rr);
+	return 1;
+	}
+
+CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
+				int allorfirst,
+				STACK_OF(GENERAL_NAMES) *receiptList,
+				STACK_OF(GENERAL_NAMES) *receiptsTo)
+	{
+	CMS_ReceiptRequest *rr = NULL;
+
+	rr = CMS_ReceiptRequest_new();
+	if (!rr)
+		goto merr;
+	if (id)
+		ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen);
+	else
+		{
+		if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32))
+			goto merr;
+		if (RAND_pseudo_bytes(rr->signedContentIdentifier->data, 32) 
+					<= 0)
+			goto err;
+		}
+
+	sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free);
+	rr->receiptsTo = receiptsTo;
+
+	if (receiptList)
+		{
+		rr->receiptsFrom->type = 1;
+		rr->receiptsFrom->d.receiptList = receiptList;
+		}
+	else
+		{
+		rr->receiptsFrom->type = 0;
+		rr->receiptsFrom->d.allOrFirstTier = allorfirst;
+		}
+
+	return rr;
+
+	merr:
+	CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE);
+
+	err:
+	if (rr)
+		CMS_ReceiptRequest_free(rr);
+
+	return NULL;
+	
+	}
+
+int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr)
+	{
+	unsigned char *rrder = NULL;
+	int rrderlen, r = 0;
+
+	rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder);
+	if (rrderlen < 0)
+		goto merr;
+
+	if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest,
+					V_ASN1_SEQUENCE, rrder, rrderlen))
+		goto merr;
+
+	r = 1;
+
+	merr:
+	if (!r)
+		CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE);
+
+	if (rrder)
+		OPENSSL_free(rrder);
+
+	return r;
+	
+	}
+
+void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
+					ASN1_STRING **pcid,
+					int *pallorfirst,
+					STACK_OF(GENERAL_NAMES) **plist,
+					STACK_OF(GENERAL_NAMES) **prto)
+	{
+	if (pcid)
+		*pcid = rr->signedContentIdentifier;
+	if (rr->receiptsFrom->type == 0)
+		{
+		if (pallorfirst)
+			*pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier;
+		if (plist)
+			*plist = NULL;
+		}
+	else
+		{
+		if (pallorfirst)
+			*pallorfirst = -1;
+		if (plist)
+			*plist = rr->receiptsFrom->d.receiptList;
+		}
+	if (prto)
+		*prto = rr->receiptsTo;
+	}
+
+/* Digest a SignerInfo structure for msgSigDigest attribute processing */
+
+static int cms_msgSigDigest(CMS_SignerInfo *si,
+				unsigned char *dig, unsigned int *diglen)
+	{
+	const EVP_MD *md;
+	md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
+	if (md == NULL)
+		return 0;
+	if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md,
+						si->signedAttrs, dig, diglen))
+		return 0;
+	return 1;
+	}
+
+/* Add a msgSigDigest attribute to a SignerInfo */
+
+int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src)
+	{
+	unsigned char dig[EVP_MAX_MD_SIZE];
+	unsigned int diglen;
+	if (!cms_msgSigDigest(src, dig, &diglen))
+		{
+		CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR);
+		return 0;
+		}
+	if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest,
+					V_ASN1_OCTET_STRING, dig, diglen))
+		{
+		CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	return 1;
+	}
+
+/* Verify signed receipt after it has already passed normal CMS verify */
+
+int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms)
+	{
+	int r = 0, i;
+	CMS_ReceiptRequest *rr = NULL;
+	CMS_Receipt *rct = NULL;
+	STACK_OF(CMS_SignerInfo) *sis, *osis;
+	CMS_SignerInfo *si, *osi = NULL;
+	ASN1_OCTET_STRING *msig, **pcont;
+	ASN1_OBJECT *octype;
+	unsigned char dig[EVP_MAX_MD_SIZE];
+	unsigned int diglen;
+
+	/* Get SignerInfos, also checks SignedData content type */
+	osis = CMS_get0_SignerInfos(req_cms);
+	sis = CMS_get0_SignerInfos(cms);
+	if (!osis || !sis)
+		goto err;
+
+	if (sk_CMS_SignerInfo_num(sis) != 1)
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER);
+		goto err;
+		}
+
+	/* Check receipt content type */
+	if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt)
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT);
+		goto err;
+		}
+
+	/* Extract and decode receipt content */
+	pcont = CMS_get0_content(cms);
+	if (!pcont || !*pcont)
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT);
+		goto err;
+		}
+
+	rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt));
+
+	if (!rct)	
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR);
+		goto err;
+		}
+
+	/* Locate original request */
+
+	for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++)
+		{
+		osi = sk_CMS_SignerInfo_value(osis, i);
+		if (!ASN1_STRING_cmp(osi->signature,
+					rct->originatorSignatureValue))
+			break;
+		}
+
+	if (i == sk_CMS_SignerInfo_num(osis))
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE);
+		goto err;
+		}
+
+	si = sk_CMS_SignerInfo_value(sis, 0);
+
+	/* Get msgSigDigest value and compare */
+
+	msig = CMS_signed_get0_data_by_OBJ(si,
+				OBJ_nid2obj(NID_id_smime_aa_msgSigDigest),
+					-3, V_ASN1_OCTET_STRING);
+
+	if (!msig)
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST);
+		goto err;
+		}
+
+	if (!cms_msgSigDigest(osi, dig, &diglen))
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR);
+		goto err;
+		}
+
+	if (diglen != (unsigned int)msig->length)
+			{
+			CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
+				CMS_R_MSGSIGDIGEST_WRONG_LENGTH);
+			goto err;
+			}
+
+	if (memcmp(dig, msig->data, diglen))
+			{
+			CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
+				CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE);
+			goto err;
+			}
+
+	/* Compare content types */
+
+	octype = CMS_signed_get0_data_by_OBJ(osi,
+				OBJ_nid2obj(NID_pkcs9_contentType),
+					-3, V_ASN1_OBJECT);
+	if (!octype)
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE);
+		goto err;
+		}
+
+	/* Compare details in receipt request */
+
+	if (OBJ_cmp(octype, rct->contentType))
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH);
+		goto err;
+		}
+
+	/* Get original receipt request details */
+
+	if (CMS_get1_ReceiptRequest(osi, &rr) <= 0)
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST);
+		goto err;
+		}
+
+	if (ASN1_STRING_cmp(rr->signedContentIdentifier,
+					rct->signedContentIdentifier))
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
+					CMS_R_CONTENTIDENTIFIER_MISMATCH);
+		goto err;
+		}
+
+	r = 1;
+
+	err:
+	if (rr)
+		CMS_ReceiptRequest_free(rr);
+	if (rct)
+		M_ASN1_free_of(rct, CMS_Receipt);
+
+	return r;
+
+	}
+
+/* Encode a Receipt into an OCTET STRING read for including into content of
+ * a SignedData ContentInfo.
+ */
+
+ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si)
+	{
+	CMS_Receipt rct;
+	CMS_ReceiptRequest *rr = NULL;
+	ASN1_OBJECT *ctype;
+	ASN1_OCTET_STRING *os = NULL;
+
+	/* Get original receipt request */
+
+	/* Get original receipt request details */
+
+	if (CMS_get1_ReceiptRequest(si, &rr) <= 0)
+		{
+		CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST);
+		goto err;
+		}
+
+	/* Get original content type */
+
+	ctype = CMS_signed_get0_data_by_OBJ(si,
+				OBJ_nid2obj(NID_pkcs9_contentType),
+					-3, V_ASN1_OBJECT);
+	if (!ctype)
+		{
+		CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE);
+		goto err;
+		}
+
+	rct.version = 1;
+	rct.contentType = ctype;
+	rct.signedContentIdentifier = rr->signedContentIdentifier;
+	rct.originatorSignatureValue = si->signature;
+
+	os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL);
+
+	err:
+	if (rr)
+		CMS_ReceiptRequest_free(rr);
+
+	return os;
+
+	}
+
+
diff --git a/openssl/crypto/cms/cms_io.c b/openssl/crypto/cms/cms_io.c
new file mode 100644
index 0000000..1cb0264
--- /dev/null
+++ b/openssl/crypto/cms/cms_io.c
@@ -0,0 +1,133 @@
+/* crypto/cms/cms_io.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include "cms.h"
+#include "cms_lcl.h"
+
+int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms)
+	{
+	ASN1_OCTET_STRING **pos;
+	pos = CMS_get0_content(cms);
+	if (!pos)
+		return 0;
+	if (!*pos)
+		*pos = ASN1_OCTET_STRING_new();
+	if (*pos)
+		{
+		(*pos)->flags |= ASN1_STRING_FLAG_NDEF;
+		(*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
+		*boundary = &(*pos)->data;
+		return 1;
+		}
+	CMSerr(CMS_F_CMS_STREAM, ERR_R_MALLOC_FAILURE);
+	return 0;
+	}
+
+CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms)
+	{
+	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
+	}
+
+int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms)
+	{
+	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
+	}
+
+IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo)
+
+BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms) 
+	{
+	return BIO_new_NDEF(out, (ASN1_VALUE *)cms,
+				ASN1_ITEM_rptr(CMS_ContentInfo));
+	}
+
+/* CMS wrappers round generalised stream and MIME routines */
+
+int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags)
+	{
+	return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)cms, in, flags,
+					ASN1_ITEM_rptr(CMS_ContentInfo));
+	}
+
+int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags)
+	{
+	return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *) cms, in, flags,
+					"CMS",
+					ASN1_ITEM_rptr(CMS_ContentInfo));
+	}
+
+int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags)
+	{
+	STACK_OF(X509_ALGOR) *mdalgs;
+	int ctype_nid = OBJ_obj2nid(cms->contentType);
+	int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms));
+	if (ctype_nid == NID_pkcs7_signed)
+		mdalgs = cms->d.signedData->digestAlgorithms;
+	else
+		mdalgs = NULL;
+
+	return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags,
+					ctype_nid, econt_nid, mdalgs,
+					ASN1_ITEM_rptr(CMS_ContentInfo));	
+	}
+
+CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont)
+	{
+	return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont,
+					ASN1_ITEM_rptr(CMS_ContentInfo));
+	}
+
diff --git a/openssl/crypto/cms/cms_lcl.h b/openssl/crypto/cms/cms_lcl.h
new file mode 100644
index 0000000..c8ecfa7
--- /dev/null
+++ b/openssl/crypto/cms/cms_lcl.h
@@ -0,0 +1,461 @@
+/* crypto/cms/cms_lcl.h */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#ifndef HEADER_CMS_LCL_H
+#define HEADER_CMS_LCL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <openssl/x509.h>
+
+/* Cryptographic message syntax (CMS) structures: taken
+ * from RFC3852
+ */
+
+/* Forward references */
+
+typedef struct CMS_IssuerAndSerialNumber_st CMS_IssuerAndSerialNumber;
+typedef struct CMS_EncapsulatedContentInfo_st CMS_EncapsulatedContentInfo;
+typedef struct CMS_SignerIdentifier_st CMS_SignerIdentifier;
+typedef struct CMS_SignedData_st CMS_SignedData;
+typedef struct CMS_OtherRevocationInfoFormat_st CMS_OtherRevocationInfoFormat;
+typedef struct CMS_OriginatorInfo_st CMS_OriginatorInfo;
+typedef struct CMS_EncryptedContentInfo_st CMS_EncryptedContentInfo;
+typedef struct CMS_EnvelopedData_st CMS_EnvelopedData;
+typedef struct CMS_DigestedData_st CMS_DigestedData;
+typedef struct CMS_EncryptedData_st CMS_EncryptedData;
+typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData;
+typedef struct CMS_CompressedData_st CMS_CompressedData;
+typedef struct CMS_OtherCertificateFormat_st CMS_OtherCertificateFormat;
+typedef struct CMS_KeyTransRecipientInfo_st CMS_KeyTransRecipientInfo;
+typedef struct CMS_OriginatorPublicKey_st CMS_OriginatorPublicKey;
+typedef struct CMS_OriginatorIdentifierOrKey_st CMS_OriginatorIdentifierOrKey;
+typedef struct CMS_KeyAgreeRecipientInfo_st CMS_KeyAgreeRecipientInfo;
+typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute;
+typedef struct CMS_RecipientKeyIdentifier_st CMS_RecipientKeyIdentifier;
+typedef struct CMS_KeyAgreeRecipientIdentifier_st CMS_KeyAgreeRecipientIdentifier;
+typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey;
+typedef struct CMS_KEKIdentifier_st CMS_KEKIdentifier;
+typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo;
+typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo;
+typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo;
+typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom;
+
+struct CMS_ContentInfo_st
+	{
+	ASN1_OBJECT *contentType;
+	union	{
+		ASN1_OCTET_STRING *data;
+		CMS_SignedData *signedData;
+		CMS_EnvelopedData *envelopedData;
+		CMS_DigestedData *digestedData;
+		CMS_EncryptedData *encryptedData;
+		CMS_AuthenticatedData *authenticatedData;
+		CMS_CompressedData *compressedData;
+		ASN1_TYPE *other;
+		/* Other types ... */
+		void *otherData;
+		} d;
+	};
+
+struct CMS_SignedData_st
+	{
+	long version;
+	STACK_OF(X509_ALGOR) *digestAlgorithms;
+	CMS_EncapsulatedContentInfo *encapContentInfo;
+	STACK_OF(CMS_CertificateChoices) *certificates;
+	STACK_OF(CMS_RevocationInfoChoice) *crls;
+	STACK_OF(CMS_SignerInfo) *signerInfos;
+	};
+ 
+struct CMS_EncapsulatedContentInfo_st
+	{
+	ASN1_OBJECT *eContentType;
+	ASN1_OCTET_STRING *eContent;
+	/* Set to 1 if incomplete structure only part set up */
+	int partial;
+	};
+
+struct CMS_SignerInfo_st
+	{
+	long version;
+	CMS_SignerIdentifier *sid;
+	X509_ALGOR *digestAlgorithm;
+	STACK_OF(X509_ATTRIBUTE) *signedAttrs;
+	X509_ALGOR *signatureAlgorithm;
+	ASN1_OCTET_STRING *signature;
+	STACK_OF(X509_ATTRIBUTE) *unsignedAttrs;
+	/* Signing certificate and key */
+	X509 *signer;
+	EVP_PKEY *pkey;
+	};
+
+struct CMS_SignerIdentifier_st
+	{
+	int type;
+	union	{
+		CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
+		ASN1_OCTET_STRING *subjectKeyIdentifier;
+		} d;
+	};
+
+struct CMS_EnvelopedData_st
+	{
+	long version;
+	CMS_OriginatorInfo *originatorInfo;
+	STACK_OF(CMS_RecipientInfo) *recipientInfos;
+	CMS_EncryptedContentInfo *encryptedContentInfo;
+	STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
+	};
+
+struct CMS_OriginatorInfo_st
+	{
+	STACK_OF(CMS_CertificateChoices) *certificates;
+	STACK_OF(CMS_RevocationInfoChoice) *crls;
+	};
+
+struct CMS_EncryptedContentInfo_st
+	{
+	ASN1_OBJECT *contentType;
+	X509_ALGOR *contentEncryptionAlgorithm;
+	ASN1_OCTET_STRING *encryptedContent;
+	/* Content encryption algorithm and key */
+	const EVP_CIPHER *cipher;
+	unsigned char *key;
+	size_t keylen;
+	};
+
+struct CMS_RecipientInfo_st
+	{
+ 	int type;
+ 	union	{
+  	 	CMS_KeyTransRecipientInfo *ktri;
+   		CMS_KeyAgreeRecipientInfo *kari;
+   		CMS_KEKRecipientInfo *kekri;
+		CMS_PasswordRecipientInfo *pwri;
+		CMS_OtherRecipientInfo *ori;
+		} d;
+	};
+
+typedef CMS_SignerIdentifier CMS_RecipientIdentifier;
+
+struct CMS_KeyTransRecipientInfo_st
+	{
+	long version;
+	CMS_RecipientIdentifier *rid;
+	X509_ALGOR *keyEncryptionAlgorithm;
+	ASN1_OCTET_STRING *encryptedKey;
+	/* Recipient Key and cert */
+	X509 *recip;
+	EVP_PKEY *pkey;
+	};
+
+struct CMS_KeyAgreeRecipientInfo_st
+	{
+	long version;
+	CMS_OriginatorIdentifierOrKey *originator;
+	ASN1_OCTET_STRING *ukm;
+ 	X509_ALGOR *keyEncryptionAlgorithm;
+	STACK_OF(CMS_RecipientEncryptedKey) *recipientEncryptedKeys;
+	};
+
+struct CMS_OriginatorIdentifierOrKey_st
+	{
+	int type;
+	union	{
+		CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
+		ASN1_OCTET_STRING *subjectKeyIdentifier;
+		CMS_OriginatorPublicKey *originatorKey;
+		} d;
+	};
+
+struct CMS_OriginatorPublicKey_st
+	{
+	X509_ALGOR *algorithm;
+	ASN1_BIT_STRING *publicKey;
+	};
+
+struct CMS_RecipientEncryptedKey_st
+	{
+ 	CMS_KeyAgreeRecipientIdentifier *rid;
+ 	ASN1_OCTET_STRING *encryptedKey;
+	};
+
+struct CMS_KeyAgreeRecipientIdentifier_st
+	{
+	int type;
+	union	{
+		CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
+		CMS_RecipientKeyIdentifier *rKeyId;
+		} d;
+	};
+
+struct CMS_RecipientKeyIdentifier_st
+	{
+ 	ASN1_OCTET_STRING *subjectKeyIdentifier;
+ 	ASN1_GENERALIZEDTIME *date;
+ 	CMS_OtherKeyAttribute *other;
+	};
+
+struct CMS_KEKRecipientInfo_st
+	{
+ 	long version;
+ 	CMS_KEKIdentifier *kekid;
+ 	X509_ALGOR *keyEncryptionAlgorithm;
+ 	ASN1_OCTET_STRING *encryptedKey;
+	/* Extra info: symmetric key to use */
+	unsigned char *key;
+	size_t keylen;
+	};
+
+struct CMS_KEKIdentifier_st
+	{
+ 	ASN1_OCTET_STRING *keyIdentifier;
+ 	ASN1_GENERALIZEDTIME *date;
+ 	CMS_OtherKeyAttribute *other;
+	};
+
+struct CMS_PasswordRecipientInfo_st
+	{
+ 	long version;
+ 	X509_ALGOR *keyDerivationAlgorithm;
+ 	X509_ALGOR *keyEncryptionAlgorithm;
+ 	ASN1_OCTET_STRING *encryptedKey;
+	};
+
+struct CMS_OtherRecipientInfo_st
+	{
+ 	ASN1_OBJECT *oriType;
+ 	ASN1_TYPE *oriValue;
+	};
+
+struct CMS_DigestedData_st
+	{
+	long version;
+	X509_ALGOR *digestAlgorithm;
+	CMS_EncapsulatedContentInfo *encapContentInfo;
+	ASN1_OCTET_STRING *digest;
+	};
+
+struct CMS_EncryptedData_st
+	{
+	long version;
+	CMS_EncryptedContentInfo *encryptedContentInfo;
+	STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
+	};
+
+struct CMS_AuthenticatedData_st
+	{
+	long version;
+	CMS_OriginatorInfo *originatorInfo;
+	STACK_OF(CMS_RecipientInfo) *recipientInfos;
+	X509_ALGOR *macAlgorithm;
+	X509_ALGOR *digestAlgorithm;
+	CMS_EncapsulatedContentInfo *encapContentInfo;
+	STACK_OF(X509_ATTRIBUTE) *authAttrs;
+	ASN1_OCTET_STRING *mac;
+	STACK_OF(X509_ATTRIBUTE) *unauthAttrs;
+	};
+
+struct CMS_CompressedData_st
+	{
+	long version;
+	X509_ALGOR *compressionAlgorithm;
+	STACK_OF(CMS_RecipientInfo) *recipientInfos;
+	CMS_EncapsulatedContentInfo *encapContentInfo;
+	};
+
+struct CMS_RevocationInfoChoice_st
+	{
+	int type;
+	union	{
+		X509_CRL *crl;
+		CMS_OtherRevocationInfoFormat *other;
+		} d;
+	};
+
+#define CMS_REVCHOICE_CRL		0
+#define CMS_REVCHOICE_OTHER		1
+
+struct CMS_OtherRevocationInfoFormat_st
+	{
+	ASN1_OBJECT *otherRevInfoFormat;
+ 	ASN1_TYPE *otherRevInfo;
+	};
+
+struct CMS_CertificateChoices
+	{
+	int type;
+		union {
+		X509 *certificate;
+		ASN1_STRING *extendedCertificate;	/* Obsolete */
+		ASN1_STRING *v1AttrCert;	/* Left encoded for now */
+		ASN1_STRING *v2AttrCert;	/* Left encoded for now */
+		CMS_OtherCertificateFormat *other;
+		} d;
+	};
+
+#define CMS_CERTCHOICE_CERT		0
+#define CMS_CERTCHOICE_EXCERT		1
+#define CMS_CERTCHOICE_V1ACERT		2
+#define CMS_CERTCHOICE_V2ACERT		3
+#define CMS_CERTCHOICE_OTHER		4
+
+struct CMS_OtherCertificateFormat_st
+	{
+	ASN1_OBJECT *otherCertFormat;
+ 	ASN1_TYPE *otherCert;
+	};
+
+/* This is also defined in pkcs7.h but we duplicate it
+ * to allow the CMS code to be independent of PKCS#7
+ */
+
+struct CMS_IssuerAndSerialNumber_st
+	{
+	X509_NAME *issuer;
+	ASN1_INTEGER *serialNumber;
+	};
+
+struct CMS_OtherKeyAttribute_st
+	{
+	ASN1_OBJECT *keyAttrId;
+ 	ASN1_TYPE *keyAttr;
+	};
+
+/* ESS structures */
+
+#ifdef HEADER_X509V3_H
+
+struct CMS_ReceiptRequest_st
+	{
+	ASN1_OCTET_STRING *signedContentIdentifier;
+	CMS_ReceiptsFrom *receiptsFrom;
+	STACK_OF(GENERAL_NAMES) *receiptsTo;
+	};
+
+
+struct CMS_ReceiptsFrom_st
+	{
+	int type;
+	union
+		{
+		long allOrFirstTier;
+		STACK_OF(GENERAL_NAMES) *receiptList;
+		} d;
+	};
+#endif
+
+struct CMS_Receipt_st
+	{
+	long version;
+	ASN1_OBJECT *contentType;
+	ASN1_OCTET_STRING *signedContentIdentifier;
+	ASN1_OCTET_STRING *originatorSignatureValue;
+	};
+
+DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
+DECLARE_ASN1_ITEM(CMS_SignerInfo)
+DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber)
+DECLARE_ASN1_ITEM(CMS_Attributes_Sign)
+DECLARE_ASN1_ITEM(CMS_Attributes_Verify)
+DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber)
+
+#define CMS_SIGNERINFO_ISSUER_SERIAL	0
+#define CMS_SIGNERINFO_KEYIDENTIFIER	1
+
+#define CMS_RECIPINFO_ISSUER_SERIAL	0
+#define CMS_RECIPINFO_KEYIDENTIFIER	1
+
+BIO *cms_content_bio(CMS_ContentInfo *cms);
+
+CMS_ContentInfo *cms_Data_create(void);
+
+CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md);
+BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms);
+int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify);
+
+BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms);
+int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain);
+int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type);
+int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
+					ASN1_OCTET_STRING **keyid,
+					X509_NAME **issuer, ASN1_INTEGER **sno);
+int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert);
+
+CMS_ContentInfo *cms_CompressedData_create(int comp_nid);
+BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms);
+
+void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md);
+BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
+int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
+					X509_ALGOR *mdalg);
+
+BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec);
+BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms);
+int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, 
+				const EVP_CIPHER *cipher,
+				const unsigned char *key, size_t keylen);
+
+int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms);
+int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src);
+ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si);
+
+BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
+	
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/cms/cms_lib.c b/openssl/crypto/cms/cms_lib.c
new file mode 100644
index 0000000..d00fe0f
--- /dev/null
+++ b/openssl/crypto/cms/cms_lib.c
@@ -0,0 +1,627 @@
+/* crypto/cms/cms_lib.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+#include "cms.h"
+#include "cms_lcl.h"
+
+IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo)
+IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
+
+DECLARE_ASN1_ITEM(CMS_CertificateChoices)
+DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice)
+DECLARE_STACK_OF(CMS_CertificateChoices)
+DECLARE_STACK_OF(CMS_RevocationInfoChoice)
+
+const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms)
+	{
+	return cms->contentType;
+	}
+
+CMS_ContentInfo *cms_Data_create(void)
+	{
+	CMS_ContentInfo *cms;
+	cms = CMS_ContentInfo_new();
+	if (cms)
+		{
+		cms->contentType = OBJ_nid2obj(NID_pkcs7_data);
+		/* Never detached */
+		CMS_set_detached(cms, 0);
+		}
+	return cms;
+	}
+
+BIO *cms_content_bio(CMS_ContentInfo *cms)
+	{
+	ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
+	if (!pos)
+		return NULL;
+	/* If content detached data goes nowhere: create NULL BIO */
+	if (!*pos)
+		return BIO_new(BIO_s_null());
+	/* If content not detached and created return memory BIO
+	 */
+	if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT))
+		return BIO_new(BIO_s_mem());
+	/* Else content was read in: return read only BIO for it */
+	return BIO_new_mem_buf((*pos)->data, (*pos)->length);
+	}
+
+BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
+	{
+	BIO *cmsbio, *cont;
+	if (icont)
+		cont = icont;
+	else
+		cont = cms_content_bio(cms);
+	if (!cont)
+		{
+		CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT);
+		return NULL;
+		}
+	switch (OBJ_obj2nid(cms->contentType))
+		{
+
+		case NID_pkcs7_data:
+		return cont;
+
+		case NID_pkcs7_signed:
+		cmsbio = cms_SignedData_init_bio(cms);
+		break;
+
+		case NID_pkcs7_digest:
+		cmsbio = cms_DigestedData_init_bio(cms);
+		break;
+#ifdef ZLIB
+		case NID_id_smime_ct_compressedData:
+		cmsbio = cms_CompressedData_init_bio(cms);
+		break;
+#endif
+
+		case NID_pkcs7_encrypted:
+		cmsbio = cms_EncryptedData_init_bio(cms);
+		break;
+
+		case NID_pkcs7_enveloped:
+		cmsbio = cms_EnvelopedData_init_bio(cms);
+		break;
+
+		default:
+		CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
+		return NULL;
+		}
+
+	if (cmsbio)
+		return BIO_push(cmsbio, cont);
+
+	if (!icont)
+		BIO_free(cont);
+	return NULL;
+
+	}
+
+int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
+	{
+	ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
+	if (!pos)
+		return 0;
+	/* If ebmedded content find memory BIO and set content */
+	if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT))
+		{
+		BIO *mbio;
+		unsigned char *cont;
+		long contlen;
+		mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM);
+		if (!mbio)
+			{
+			CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND);
+			return 0;
+			}
+		contlen = BIO_get_mem_data(mbio, &cont);
+		/* Set bio as read only so its content can't be clobbered */
+		BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY);
+		BIO_set_mem_eof_return(mbio, 0);
+		ASN1_STRING_set0(*pos, cont, contlen);
+		(*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
+		}
+
+	switch (OBJ_obj2nid(cms->contentType))
+		{
+
+		case NID_pkcs7_data:
+		case NID_pkcs7_enveloped:
+		case NID_pkcs7_encrypted:
+		case NID_id_smime_ct_compressedData:
+		/* Nothing to do */
+		return 1;
+
+		case NID_pkcs7_signed:
+		return cms_SignedData_final(cms, cmsbio);
+
+		case NID_pkcs7_digest:
+		return cms_DigestedData_do_final(cms, cmsbio, 0);
+
+		default:
+		CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE);
+		return 0;
+		}
+	}
+
+/* Return an OCTET STRING pointer to content. This allows it to
+ * be accessed or set later.
+ */
+
+ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms)
+	{
+	switch (OBJ_obj2nid(cms->contentType))
+		{
+
+		case NID_pkcs7_data:
+		return &cms->d.data;
+
+		case NID_pkcs7_signed:
+		return &cms->d.signedData->encapContentInfo->eContent;
+
+		case NID_pkcs7_enveloped:
+		return &cms->d.envelopedData->encryptedContentInfo->encryptedContent;
+
+		case NID_pkcs7_digest:
+		return &cms->d.digestedData->encapContentInfo->eContent;
+
+		case NID_pkcs7_encrypted:
+		return &cms->d.encryptedData->encryptedContentInfo->encryptedContent;
+
+		case NID_id_smime_ct_authData:
+		return &cms->d.authenticatedData->encapContentInfo->eContent;
+
+		case NID_id_smime_ct_compressedData:
+		return &cms->d.compressedData->encapContentInfo->eContent;
+
+		default:
+		if (cms->d.other->type == V_ASN1_OCTET_STRING)
+			return &cms->d.other->value.octet_string;
+		CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE);
+		return NULL;
+
+		}
+	}
+
+/* Return an ASN1_OBJECT pointer to content type. This allows it to
+ * be accessed or set later.
+ */
+
+static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms)
+	{
+	switch (OBJ_obj2nid(cms->contentType))
+		{
+
+		case NID_pkcs7_signed:
+		return &cms->d.signedData->encapContentInfo->eContentType;
+
+		case NID_pkcs7_enveloped:
+		return &cms->d.envelopedData->encryptedContentInfo->contentType;
+
+		case NID_pkcs7_digest:
+		return &cms->d.digestedData->encapContentInfo->eContentType;
+
+		case NID_pkcs7_encrypted:
+		return &cms->d.encryptedData->encryptedContentInfo->contentType;
+
+		case NID_id_smime_ct_authData:
+		return &cms->d.authenticatedData->encapContentInfo->eContentType;
+
+		case NID_id_smime_ct_compressedData:
+		return &cms->d.compressedData->encapContentInfo->eContentType;
+
+		default:
+		CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE,
+					CMS_R_UNSUPPORTED_CONTENT_TYPE);
+		return NULL;
+
+		}
+	}
+
+const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms)
+	{
+	ASN1_OBJECT **petype;
+	petype = cms_get0_econtent_type(cms);
+	if (petype)
+		return *petype;
+	return NULL;
+	}
+
+int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid)
+	{
+	ASN1_OBJECT **petype, *etype;
+	petype = cms_get0_econtent_type(cms);
+	if (!petype)
+		return 0;
+	if (!oid)
+		return 1;
+	etype = OBJ_dup(oid);
+	if (!etype)
+		return 0;
+	ASN1_OBJECT_free(*petype);
+	*petype = etype;
+	return 1;
+	}
+
+int CMS_is_detached(CMS_ContentInfo *cms)
+	{
+	ASN1_OCTET_STRING **pos;
+	pos = CMS_get0_content(cms);
+	if (!pos)
+		return -1;
+	if (*pos)
+		return 0;
+	return 1;
+	}
+
+int CMS_set_detached(CMS_ContentInfo *cms, int detached)
+	{
+	ASN1_OCTET_STRING **pos;
+	pos = CMS_get0_content(cms);
+	if (!pos)
+		return 0;
+	if (detached)
+		{
+		if (*pos)
+			{
+			ASN1_OCTET_STRING_free(*pos);
+			*pos = NULL;
+			}
+		return 1;
+		}
+	if (!*pos)
+		*pos = ASN1_OCTET_STRING_new();
+	if (*pos)
+		{
+		/* NB: special flag to show content is created and not
+		 * read in.
+		 */
+		(*pos)->flags |= ASN1_STRING_FLAG_CONT;
+		return 1;
+		}
+	CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE);
+	return 0;
+	}
+
+/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
+
+void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md)
+	{
+	int param_type;
+
+	if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
+		param_type = V_ASN1_UNDEF;
+	else
+		param_type = V_ASN1_NULL;
+
+	X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
+
+	}
+
+/* Create a digest BIO from an X509_ALGOR structure */
+
+BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
+	{
+	BIO *mdbio = NULL;
+	ASN1_OBJECT *digestoid;
+	const EVP_MD *digest;
+	X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
+	digest = EVP_get_digestbyobj(digestoid);
+	if (!digest)
+		{
+		CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
+				CMS_R_UNKNOWN_DIGEST_ALGORIHM);
+		goto err;	
+		}
+	mdbio = BIO_new(BIO_f_md());
+	if (!mdbio || !BIO_set_md(mdbio, digest))
+		{
+		CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
+				CMS_R_MD_BIO_INIT_ERROR);
+		goto err;	
+		}
+	return mdbio;
+	err:
+	if (mdbio)
+		BIO_free(mdbio);
+	return NULL;
+	}
+
+/* Locate a message digest content from a BIO chain based on SignerInfo */
+
+int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
+					X509_ALGOR *mdalg)
+	{
+	int nid;
+	ASN1_OBJECT *mdoid;
+	X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg);
+	nid = OBJ_obj2nid(mdoid);
+	/* Look for digest type to match signature */
+	for (;;)
+		{
+		EVP_MD_CTX *mtmp;
+		chain = BIO_find_type(chain, BIO_TYPE_MD);
+		if (chain == NULL)
+			{
+			CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX,
+						CMS_R_NO_MATCHING_DIGEST);
+			return 0;
+			}
+		BIO_get_md_ctx(chain, &mtmp);
+		if (EVP_MD_CTX_type(mtmp) == nid
+		/* Workaround for broken implementations that use signature
+		 * algorithm  OID instead of digest.
+		 */
+			|| EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)
+			{
+			EVP_MD_CTX_copy_ex(mctx, mtmp);
+			return 1;
+			}
+		chain = BIO_next(chain);
+		}
+	}
+
+static STACK_OF(CMS_CertificateChoices) **cms_get0_certificate_choices(CMS_ContentInfo *cms)
+	{
+	switch (OBJ_obj2nid(cms->contentType))
+		{
+
+		case NID_pkcs7_signed:
+		return &cms->d.signedData->certificates;
+
+		case NID_pkcs7_enveloped:
+		return &cms->d.envelopedData->originatorInfo->certificates;
+
+		default:
+		CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES,
+					CMS_R_UNSUPPORTED_CONTENT_TYPE);
+		return NULL;
+
+		}
+	}
+
+CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms)
+	{
+	STACK_OF(CMS_CertificateChoices) **pcerts;
+	CMS_CertificateChoices *cch;
+	pcerts = cms_get0_certificate_choices(cms);
+	if (!pcerts)
+		return NULL;
+	if (!*pcerts)
+		*pcerts = sk_CMS_CertificateChoices_new_null();
+	if (!*pcerts)
+		return NULL;
+	cch = M_ASN1_new_of(CMS_CertificateChoices);
+	if (!cch)
+		return NULL;
+	if (!sk_CMS_CertificateChoices_push(*pcerts, cch))
+		{
+		M_ASN1_free_of(cch, CMS_CertificateChoices);
+		return NULL;
+		}
+	return cch;
+	}
+
+int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert)
+	{
+	CMS_CertificateChoices *cch;
+	STACK_OF(CMS_CertificateChoices) **pcerts;
+	int i;
+	pcerts = cms_get0_certificate_choices(cms);
+	if (!pcerts)
+		return 0;
+	if (!pcerts)
+		return 0;
+	for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
+		{
+		cch = sk_CMS_CertificateChoices_value(*pcerts, i);
+		if (cch->type == CMS_CERTCHOICE_CERT)
+			{
+			if (!X509_cmp(cch->d.certificate, cert))
+				{
+				CMSerr(CMS_F_CMS_ADD0_CERT, 
+					CMS_R_CERTIFICATE_ALREADY_PRESENT);
+				return 0;
+				}
+			}
+		}
+	cch = CMS_add0_CertificateChoices(cms);
+	if (!cch)
+		return 0;
+	cch->type = CMS_CERTCHOICE_CERT;
+	cch->d.certificate = cert;
+	return 1;
+	}
+
+int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert)
+	{
+	int r;
+	r = CMS_add0_cert(cms, cert);
+	if (r > 0)
+		CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
+	return r;
+	}
+
+static STACK_OF(CMS_RevocationInfoChoice) **cms_get0_revocation_choices(CMS_ContentInfo *cms)
+	{
+	switch (OBJ_obj2nid(cms->contentType))
+		{
+
+		case NID_pkcs7_signed:
+		return &cms->d.signedData->crls;
+
+		case NID_pkcs7_enveloped:
+		return &cms->d.envelopedData->originatorInfo->crls;
+
+		default:
+		CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES,
+					CMS_R_UNSUPPORTED_CONTENT_TYPE);
+		return NULL;
+
+		}
+	}
+
+CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms)
+	{
+	STACK_OF(CMS_RevocationInfoChoice) **pcrls;
+	CMS_RevocationInfoChoice *rch;
+	pcrls = cms_get0_revocation_choices(cms);
+	if (!pcrls)
+		return NULL;
+	if (!*pcrls)
+		*pcrls = sk_CMS_RevocationInfoChoice_new_null();
+	if (!*pcrls)
+		return NULL;
+	rch = M_ASN1_new_of(CMS_RevocationInfoChoice);
+	if (!rch)
+		return NULL;
+	if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch))
+		{
+		M_ASN1_free_of(rch, CMS_RevocationInfoChoice);
+		return NULL;
+		}
+	return rch;
+	}
+
+int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl)
+	{
+	CMS_RevocationInfoChoice *rch;
+	rch = CMS_add0_RevocationInfoChoice(cms);
+	if (!rch)
+		return 0;
+	rch->type = CMS_REVCHOICE_CRL;
+	rch->d.crl = crl;
+	return 1;
+	}
+
+int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl)
+	{
+	int r;
+	r = CMS_add0_crl(cms, crl);
+	if (r > 0)
+		CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
+	return r;
+	}
+
+STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
+	{
+	STACK_OF(X509) *certs = NULL;
+	CMS_CertificateChoices *cch;
+	STACK_OF(CMS_CertificateChoices) **pcerts;
+	int i;
+	pcerts = cms_get0_certificate_choices(cms);
+	if (!pcerts)
+		return NULL;
+	for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
+		{
+		cch = sk_CMS_CertificateChoices_value(*pcerts, i);
+		if (cch->type == 0)
+			{
+			if (!certs)
+				{
+				certs = sk_X509_new_null();
+				if (!certs)
+					return NULL;
+				}
+			if (!sk_X509_push(certs, cch->d.certificate))
+				{
+				sk_X509_pop_free(certs, X509_free);
+				return NULL;
+				}
+			CRYPTO_add(&cch->d.certificate->references,
+						1, CRYPTO_LOCK_X509);
+			}
+		}
+	return certs;
+
+	}
+
+STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
+	{
+	STACK_OF(X509_CRL) *crls = NULL;
+	STACK_OF(CMS_RevocationInfoChoice) **pcrls;
+	CMS_RevocationInfoChoice *rch;
+	int i;
+	pcrls = cms_get0_revocation_choices(cms);
+	if (!pcrls)
+		return NULL;
+	for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++)
+		{
+		rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
+		if (rch->type == 0)
+			{
+			if (!crls)
+				{
+				crls = sk_X509_CRL_new_null();
+				if (!crls)
+					return NULL;
+				}
+			if (!sk_X509_CRL_push(crls, rch->d.crl))
+				{
+				sk_X509_CRL_pop_free(crls, X509_CRL_free);
+				return NULL;
+				}
+			CRYPTO_add(&rch->d.crl->references,
+						1, CRYPTO_LOCK_X509_CRL);
+			}
+		}
+	return crls;
+	}
diff --git a/openssl/crypto/cms/cms_sd.c b/openssl/crypto/cms/cms_sd.c
new file mode 100644
index 0000000..e3192b9
--- /dev/null
+++ b/openssl/crypto/cms/cms_sd.c
@@ -0,0 +1,984 @@
+/* crypto/cms/cms_sd.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+#include "asn1_locl.h"
+
+/* CMS SignedData Utilities */
+
+DECLARE_ASN1_ITEM(CMS_SignedData)
+
+static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms)
+	{
+	if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed)
+		{
+		CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA);
+		return NULL;
+		}
+	return cms->d.signedData;
+	}
+
+static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms)
+	{
+	if (cms->d.other == NULL)
+		{
+		cms->d.signedData = M_ASN1_new_of(CMS_SignedData);
+		if (!cms->d.signedData)
+			{
+			CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE);
+			return NULL;
+			}
+		cms->d.signedData->version = 1;
+		cms->d.signedData->encapContentInfo->eContentType =
+						OBJ_nid2obj(NID_pkcs7_data);
+		cms->d.signedData->encapContentInfo->partial = 1;
+		ASN1_OBJECT_free(cms->contentType);
+		cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);
+		return cms->d.signedData;
+		}
+	return cms_get0_signed(cms);
+	}
+
+/* Just initialize SignedData e.g. for certs only structure */
+
+int CMS_SignedData_init(CMS_ContentInfo *cms)
+	{
+	if (cms_signed_data_init(cms))
+		return 1;
+	else
+		return 0;
+	}
+
+/* Check structures and fixup version numbers (if necessary) */
+
+static void cms_sd_set_version(CMS_SignedData *sd)
+	{
+	int i;
+	CMS_CertificateChoices *cch;
+	CMS_RevocationInfoChoice *rch;
+	CMS_SignerInfo *si;
+
+	for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++)
+		{
+		cch = sk_CMS_CertificateChoices_value(sd->certificates, i);
+		if (cch->type == CMS_CERTCHOICE_OTHER)
+			{
+			if (sd->version < 5)
+				sd->version = 5;
+			}
+		else if (cch->type == CMS_CERTCHOICE_V2ACERT)
+			{
+			if (sd->version < 4)
+				sd->version = 4;
+			}
+		else if (cch->type == CMS_CERTCHOICE_V1ACERT)
+			{
+			if (sd->version < 3)
+				sd->version = 3;
+			}
+		}
+
+	for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++)
+		{
+		rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i);
+		if (rch->type == CMS_REVCHOICE_OTHER)
+			{
+			if (sd->version < 5)
+				sd->version = 5;
+			}
+		}
+
+	if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data)
+			&& (sd->version < 3))
+		sd->version = 3;
+
+	for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++)
+		{
+		si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
+		if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
+			{
+			if (si->version < 3)
+				si->version = 3;
+			if (sd->version < 3)
+				sd->version = 3;
+			}
+		else
+			sd->version = 1;
+		}
+
+	if (sd->version < 1)
+		sd->version = 1;
+
+	}
+	
+/* Copy an existing messageDigest value */
+
+static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
+	{
+	STACK_OF(CMS_SignerInfo) *sinfos;
+	CMS_SignerInfo *sitmp;
+	int i;
+	sinfos = CMS_get0_SignerInfos(cms);
+	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
+		{
+		ASN1_OCTET_STRING *messageDigest;
+		sitmp = sk_CMS_SignerInfo_value(sinfos, i);
+		if (sitmp == si)
+			continue;
+		if (CMS_signed_get_attr_count(sitmp) < 0)
+			continue;
+		if (OBJ_cmp(si->digestAlgorithm->algorithm,
+				sitmp->digestAlgorithm->algorithm))
+			continue;
+		messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,
+					OBJ_nid2obj(NID_pkcs9_messageDigest),
+					-3, V_ASN1_OCTET_STRING);
+		if (!messageDigest)
+			{
+			CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST,
+				CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
+			return 0;
+			}
+
+		if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
+						V_ASN1_OCTET_STRING,
+						messageDigest, -1))
+			return 1;
+		else
+			return 0;
+		}
+		CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST);
+		return 0;
+	}
+
+int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)
+	{
+	switch(type)
+		{
+		case CMS_SIGNERINFO_ISSUER_SERIAL:
+		sid->d.issuerAndSerialNumber =
+			M_ASN1_new_of(CMS_IssuerAndSerialNumber);
+		if (!sid->d.issuerAndSerialNumber)
+			goto merr;
+		if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer,
+					X509_get_issuer_name(cert)))
+			goto merr;
+		if (!ASN1_STRING_copy(
+			sid->d.issuerAndSerialNumber->serialNumber,
+				X509_get_serialNumber(cert)))
+			goto merr;
+		break;
+
+		case CMS_SIGNERINFO_KEYIDENTIFIER:
+		if (!cert->skid)
+			{
+			CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER,
+					CMS_R_CERTIFICATE_HAS_NO_KEYID);
+			return 0;
+			}
+		sid->d.subjectKeyIdentifier = ASN1_STRING_dup(cert->skid);
+		if (!sid->d.subjectKeyIdentifier)
+			goto merr;
+		break;
+
+		default:
+		CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID);
+		return 0;
+		}
+
+	sid->type = type;
+
+	return 1;
+
+	merr:
+	CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, ERR_R_MALLOC_FAILURE);
+	return 0;
+
+	}
+
+int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
+					ASN1_OCTET_STRING **keyid,
+					X509_NAME **issuer, ASN1_INTEGER **sno)
+	{
+	if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
+		{
+		if (issuer)
+			*issuer = sid->d.issuerAndSerialNumber->issuer;
+		if (sno)
+			*sno = sid->d.issuerAndSerialNumber->serialNumber;
+		}
+	else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
+		{
+		if (keyid)
+			*keyid = sid->d.subjectKeyIdentifier;
+		}
+	else
+		return 0;
+	return 1;
+	}
+
+int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
+	{
+	int ret;
+	if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
+		{
+		ret = X509_NAME_cmp(sid->d.issuerAndSerialNumber->issuer,
+					X509_get_issuer_name(cert));
+		if (ret)
+			return ret;
+		return ASN1_INTEGER_cmp(sid->d.issuerAndSerialNumber->serialNumber,
+					X509_get_serialNumber(cert));
+		}
+	else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
+		{
+		X509_check_purpose(cert, -1, -1);
+		if (!cert->skid)
+			return -1;
+		return ASN1_OCTET_STRING_cmp(sid->d.subjectKeyIdentifier,
+							cert->skid);
+		}
+	else
+		return -1;
+	}
+
+CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
+			X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
+			unsigned int flags)
+	{
+	CMS_SignedData *sd;
+	CMS_SignerInfo *si = NULL;
+	X509_ALGOR *alg;
+	int i, type;
+	if(!X509_check_private_key(signer, pk))
+		{
+		CMSerr(CMS_F_CMS_ADD1_SIGNER,
+			CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+                return NULL;
+		}
+	sd = cms_signed_data_init(cms);
+	if (!sd)
+		goto err;
+	si = M_ASN1_new_of(CMS_SignerInfo);
+	if (!si)
+		goto merr;
+	X509_check_purpose(signer, -1, -1);
+
+	CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
+	CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
+
+	si->pkey = pk;
+	si->signer = signer;
+
+	if (flags & CMS_USE_KEYID)
+		{
+		si->version = 3;
+		if (sd->version < 3)
+			sd->version = 3;
+		type = CMS_SIGNERINFO_KEYIDENTIFIER;
+		}
+	else
+		{
+		type = CMS_SIGNERINFO_ISSUER_SERIAL;
+		si->version = 1;
+		}
+
+	if (!cms_set1_SignerIdentifier(si->sid, signer, type))
+		goto err;
+
+	if (md == NULL)
+		{
+		int def_nid;
+		if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0)
+			goto err;
+		md = EVP_get_digestbynid(def_nid);
+		if (md == NULL)
+			{
+			CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST);
+			goto err;
+			}
+		}
+
+	if (!md)
+		{
+		CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET);
+		goto err;
+		}
+
+	cms_DigestAlgorithm_set(si->digestAlgorithm, md);
+
+	/* See if digest is present in digestAlgorithms */
+	for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++)
+		{
+		ASN1_OBJECT *aoid;
+		alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
+		X509_ALGOR_get0(&aoid, NULL, NULL, alg);
+		if (OBJ_obj2nid(aoid) == EVP_MD_type(md))
+			break;
+		}
+
+	if (i == sk_X509_ALGOR_num(sd->digestAlgorithms))
+		{
+		alg = X509_ALGOR_new();
+		if (!alg)
+			goto merr;
+		cms_DigestAlgorithm_set(alg, md);
+		if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg))
+			{
+			X509_ALGOR_free(alg);
+			goto merr;
+			}
+		}
+
+	if (pk->ameth && pk->ameth->pkey_ctrl)
+		{
+		i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_SIGN,
+						0, si);
+		if (i == -2)
+			{
+			CMSerr(CMS_F_CMS_ADD1_SIGNER,
+				CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+			goto err;
+			}
+		if (i <= 0)
+			{
+			CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_CTRL_FAILURE);
+			goto err;
+			}
+		}
+
+	if (!(flags & CMS_NOATTR))
+		{
+		/* Initialialize signed attributes strutucture so other
+		 * attributes such as signing time etc are added later
+		 * even if we add none here.
+		 */
+		if (!si->signedAttrs)
+			{
+			si->signedAttrs = sk_X509_ATTRIBUTE_new_null();
+			if (!si->signedAttrs)
+				goto merr;
+			}
+
+		if (!(flags & CMS_NOSMIMECAP))
+			{
+			STACK_OF(X509_ALGOR) *smcap = NULL;
+			i = CMS_add_standard_smimecap(&smcap);
+			if (i)
+				i = CMS_add_smimecap(si, smcap);
+			sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
+			if (!i)
+				goto merr;
+			}
+		if (flags & CMS_REUSE_DIGEST)
+			{
+			if (!cms_copy_messageDigest(cms, si))
+				goto err;
+			if (!(flags & CMS_PARTIAL) &&
+					!CMS_SignerInfo_sign(si))
+				goto err;
+			}
+		}
+
+	if (!(flags & CMS_NOCERTS))
+		{
+		/* NB ignore -1 return for duplicate cert */
+		if (!CMS_add1_cert(cms, signer))
+			goto merr;
+		}
+
+	if (!sd->signerInfos)
+		sd->signerInfos = sk_CMS_SignerInfo_new_null();
+	if (!sd->signerInfos ||
+		!sk_CMS_SignerInfo_push(sd->signerInfos, si))
+		goto merr;
+
+	return si;
+
+	merr:
+	CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
+	err:
+	if (si)
+		M_ASN1_free_of(si, CMS_SignerInfo);
+	return NULL;
+
+	}
+
+static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
+	{
+	ASN1_TIME *tt;
+	int r = 0;
+	if (t)
+		tt = t;
+	else
+		tt = X509_gmtime_adj(NULL, 0);
+
+	if (!tt)
+		goto merr;
+
+	if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,
+						tt->type, tt, -1) <= 0)
+		goto merr;
+
+	r = 1;
+
+	merr:
+
+	if (!t)
+		ASN1_TIME_free(tt);
+
+	if (!r)
+		CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE);
+
+	return r;
+
+	}
+
+STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
+	{
+	CMS_SignedData *sd;
+	sd = cms_get0_signed(cms);
+	if (!sd)
+		return NULL;
+	return sd->signerInfos;
+	}
+
+STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
+	{
+	STACK_OF(X509) *signers = NULL;
+	STACK_OF(CMS_SignerInfo) *sinfos;
+	CMS_SignerInfo *si;
+	int i;
+	sinfos = CMS_get0_SignerInfos(cms);
+	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
+		{
+		si = sk_CMS_SignerInfo_value(sinfos, i);
+		if (si->signer)
+			{
+			if (!signers)
+				{
+				signers = sk_X509_new_null();
+				if (!signers)
+					return NULL;
+				}
+			if (!sk_X509_push(signers, si->signer))
+				{
+				sk_X509_free(signers);
+				return NULL;
+				}
+			}
+		}
+	return signers;
+	}
+
+void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
+	{
+	if (signer)
+		{
+		CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
+		if (si->pkey)
+			EVP_PKEY_free(si->pkey);
+		si->pkey = X509_get_pubkey(signer);
+		}
+	if (si->signer)
+		X509_free(si->signer);
+	si->signer = signer;
+	}
+
+int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
+					ASN1_OCTET_STRING **keyid,
+					X509_NAME **issuer, ASN1_INTEGER **sno)
+	{
+	return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno);
+	}
+
+int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert)
+	{
+	return cms_SignerIdentifier_cert_cmp(si->sid, cert);
+	}
+
+int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
+				unsigned int flags)
+	{
+	CMS_SignedData *sd;
+	CMS_SignerInfo *si;
+	CMS_CertificateChoices *cch;
+	STACK_OF(CMS_CertificateChoices) *certs;
+	X509 *x;
+	int i, j;
+	int ret = 0;
+	sd = cms_get0_signed(cms);
+	if (!sd)
+		return -1;
+	certs = sd->certificates;
+	for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++)
+		{
+		si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
+		if (si->signer)
+			continue;
+
+		for (j = 0; j < sk_X509_num(scerts); j++)
+			{
+			x = sk_X509_value(scerts, j);
+			if (CMS_SignerInfo_cert_cmp(si, x) == 0)
+				{
+				CMS_SignerInfo_set1_signer_cert(si, x);
+				ret++;
+				break;
+				}
+			}
+
+		if (si->signer || (flags & CMS_NOINTERN))
+			continue;
+
+		for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++)
+			{
+			cch = sk_CMS_CertificateChoices_value(certs, j);
+			if (cch->type != 0)
+				continue;
+			x = cch->d.certificate;
+			if (CMS_SignerInfo_cert_cmp(si, x) == 0)
+				{
+				CMS_SignerInfo_set1_signer_cert(si, x);
+				ret++;
+				break;
+				}
+			}
+		}
+	return ret;
+	}
+
+void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer,
+					X509_ALGOR **pdig, X509_ALGOR **psig)
+	{
+	if (pk)
+		*pk = si->pkey;
+	if (signer)
+		*signer = si->signer;
+	if (pdig)
+		*pdig = si->digestAlgorithm;
+	if (psig)
+		*psig = si->signatureAlgorithm;
+	}
+
+static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
+					CMS_SignerInfo *si, BIO *chain)
+	{
+	EVP_MD_CTX mctx;
+	int r = 0;
+	EVP_MD_CTX_init(&mctx);
+
+
+	if (!si->pkey)
+		{
+		CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
+		return 0;
+		}
+
+	if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
+		goto err;
+
+	/* If any signed attributes calculate and add messageDigest attribute */
+
+	if (CMS_signed_get_attr_count(si) >= 0)
+		{
+		ASN1_OBJECT *ctype =
+			cms->d.signedData->encapContentInfo->eContentType; 
+		unsigned char md[EVP_MAX_MD_SIZE];
+		unsigned int mdlen;
+		EVP_DigestFinal_ex(&mctx, md, &mdlen);
+		if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
+						V_ASN1_OCTET_STRING,
+						md, mdlen))
+			goto err;
+		/* Copy content type across */
+		if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
+					V_ASN1_OBJECT, ctype, -1) <= 0)
+			goto err;
+		if (!CMS_SignerInfo_sign(si))
+			goto err;
+		}
+	else
+		{
+		unsigned char *sig;
+		unsigned int siglen;
+		sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
+		if (!sig)
+			{
+			CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN,
+					ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey))
+			{
+			CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN,
+					CMS_R_SIGNFINAL_ERROR);
+			OPENSSL_free(sig);
+			goto err;
+			}
+		ASN1_STRING_set0(si->signature, sig, siglen);
+		}
+
+	r = 1;
+
+	err:
+	EVP_MD_CTX_cleanup(&mctx);
+	return r;
+
+	}
+
+int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
+	{
+	STACK_OF(CMS_SignerInfo) *sinfos;
+	CMS_SignerInfo *si;
+	int i;
+	sinfos = CMS_get0_SignerInfos(cms);
+	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
+		{
+		si = sk_CMS_SignerInfo_value(sinfos, i);
+		if (!cms_SignerInfo_content_sign(cms, si, chain))
+			return 0;
+		}
+	cms->d.signedData->encapContentInfo->partial = 0;
+	return 1;
+	}
+
+int CMS_SignerInfo_sign(CMS_SignerInfo *si)
+	{
+	EVP_MD_CTX mctx;
+	EVP_PKEY_CTX *pctx;
+	unsigned char *abuf = NULL;
+	int alen;
+	size_t siglen;
+	const EVP_MD *md = NULL;
+
+	md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
+	if (md == NULL)
+		return 0;
+
+	EVP_MD_CTX_init(&mctx);
+
+	if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0)
+		{
+		if (!cms_add1_signingTime(si, NULL))
+			goto err;
+		}
+
+	if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
+				EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0)
+		{
+		CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
+		goto err;
+		}
+
+	alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf,
+				ASN1_ITEM_rptr(CMS_Attributes_Sign));
+	if(!abuf)
+		goto err;
+	if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0)
+		goto err;
+	if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
+		goto err;
+	OPENSSL_free(abuf);
+	abuf = OPENSSL_malloc(siglen);
+	if(!abuf)
+		goto err;
+	if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
+				EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0)
+		{
+		CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
+		goto err;
+		}
+
+	EVP_MD_CTX_cleanup(&mctx);
+
+	ASN1_STRING_set0(si->signature, abuf, siglen);
+
+	return 1;
+
+	err:
+	if (abuf)
+		OPENSSL_free(abuf);
+	EVP_MD_CTX_cleanup(&mctx);
+	return 0;
+
+	}
+
+int CMS_SignerInfo_verify(CMS_SignerInfo *si)
+	{
+	EVP_MD_CTX mctx;
+	EVP_PKEY_CTX *pctx;
+	unsigned char *abuf = NULL;
+	int alen, r = -1;
+	const EVP_MD *md = NULL;
+
+	if (!si->pkey)
+		{
+		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY);
+		return -1;
+		}
+
+	md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
+	if (md == NULL)
+		return -1;
+	EVP_MD_CTX_init(&mctx);
+	if (EVP_DigestVerifyInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
+		goto err;
+
+	alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf,
+				ASN1_ITEM_rptr(CMS_Attributes_Verify));
+	if(!abuf)
+		goto err;
+	r = EVP_DigestVerifyUpdate(&mctx, abuf, alen);
+	OPENSSL_free(abuf);
+	if (r <= 0)
+		{
+		r = -1;
+		goto err;
+		}
+	r = EVP_DigestVerifyFinal(&mctx,
+			si->signature->data, si->signature->length);
+	if (r <= 0)
+		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
+	err:
+	EVP_MD_CTX_cleanup(&mctx);
+	return r;
+	}
+
+/* Create a chain of digest BIOs from a CMS ContentInfo */
+
+BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
+	{
+	int i;
+	CMS_SignedData *sd;
+	BIO *chain = NULL;
+	sd = cms_get0_signed(cms);
+	if (!sd)
+		return NULL;
+	if (cms->d.signedData->encapContentInfo->partial)
+		cms_sd_set_version(sd);
+	for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++)
+		{
+		X509_ALGOR *digestAlgorithm;
+		BIO *mdbio;
+		digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
+		mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm);
+		if (!mdbio)
+			goto err;	
+		if (chain)
+			 BIO_push(chain, mdbio);
+		else
+			chain = mdbio;
+		}
+	return chain;
+	err:
+	if (chain)
+		BIO_free_all(chain);
+	return NULL;
+	}
+
+int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
+	{
+	ASN1_OCTET_STRING *os = NULL;
+	EVP_MD_CTX mctx;
+	int r = -1;
+	EVP_MD_CTX_init(&mctx);
+	/* If we have any signed attributes look for messageDigest value */
+	if (CMS_signed_get_attr_count(si) >= 0)
+		{
+		os = CMS_signed_get0_data_by_OBJ(si,
+					OBJ_nid2obj(NID_pkcs9_messageDigest),
+					-3, V_ASN1_OCTET_STRING);
+		if (!os)
+			{
+			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+				CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
+			goto err;
+			}
+		}
+
+	if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
+		goto err;
+
+	/* If messageDigest found compare it */
+
+	if (os)
+		{
+		unsigned char mval[EVP_MAX_MD_SIZE];
+		unsigned int mlen;
+		if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0)
+			{
+			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+				CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
+			goto err;
+			}
+		if (mlen != (unsigned int)os->length)
+			{
+			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+				CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
+			goto err;
+			}
+
+		if (memcmp(mval, os->data, mlen))
+			{
+			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+				CMS_R_VERIFICATION_FAILURE);
+			r = 0;
+			}
+		else
+			r = 1;
+		}
+	else
+		{
+		r = EVP_VerifyFinal(&mctx, si->signature->data,
+					si->signature->length, si->pkey);
+		if (r <= 0)
+			{
+			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+				CMS_R_VERIFICATION_FAILURE);
+			r = 0;
+			}
+		}
+
+	err:
+	EVP_MD_CTX_cleanup(&mctx);
+	return r;
+
+	}
+
+int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
+	{
+	unsigned char *smder = NULL;
+	int smderlen, r;
+	smderlen = i2d_X509_ALGORS(algs, &smder);
+	if (smderlen <= 0)
+		return 0;
+	r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities,
+					V_ASN1_SEQUENCE, smder, smderlen);
+	OPENSSL_free(smder);
+	return r;
+	}
+
+int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
+				int algnid, int keysize)
+	{
+	X509_ALGOR *alg;
+	ASN1_INTEGER *key = NULL;
+	if (keysize > 0)
+		{
+		key = ASN1_INTEGER_new();
+		if (!key || !ASN1_INTEGER_set(key, keysize))
+			return 0;
+		}
+	alg = X509_ALGOR_new();
+	if (!alg)
+		{
+		if (key)
+			ASN1_INTEGER_free(key);
+		return 0;
+		}
+		
+	X509_ALGOR_set0(alg, OBJ_nid2obj(algnid),
+				key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key);
+	if (!*algs)
+		*algs = sk_X509_ALGOR_new_null();
+	if (!*algs || !sk_X509_ALGOR_push(*algs, alg))
+		{
+		X509_ALGOR_free(alg);
+		return 0;
+		}
+	return 1;
+	}
+
+/* Check to see if a cipher exists and if so add S/MIME capabilities */
+
+static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
+	{
+	if (EVP_get_cipherbynid(nid))
+		return CMS_add_simple_smimecap(sk, nid, arg);
+	return 1;
+	}
+
+static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
+	{
+	if (EVP_get_digestbynid(nid))
+		return CMS_add_simple_smimecap(sk, nid, arg);
+	return 1;
+	}
+
+int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
+	{
+	if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
+		|| !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
+		|| !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
+		|| !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
+		|| !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
+		|| !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
+		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128)
+		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64)
+		|| !cms_add_cipher_smcap(smcap, NID_des_cbc, -1)
+		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40))
+		return 0;
+	return 1;
+	}
diff --git a/openssl/crypto/cms/cms_smime.c b/openssl/crypto/cms/cms_smime.c
new file mode 100644
index 0000000..4a799eb
--- /dev/null
+++ b/openssl/crypto/cms/cms_smime.c
@@ -0,0 +1,797 @@
+/* crypto/cms/cms_smime.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+
+static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
+	{
+	unsigned char buf[4096];
+	int r = 0, i;
+	BIO *tmpout = NULL;
+
+	if (out == NULL)
+		tmpout = BIO_new(BIO_s_null());
+	else if (flags & CMS_TEXT)
+		{
+		tmpout = BIO_new(BIO_s_mem());
+		BIO_set_mem_eof_return(tmpout, 0);
+		}
+	else
+		tmpout = out;
+
+	if(!tmpout)
+		{
+		CMSerr(CMS_F_CMS_COPY_CONTENT,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	/* Read all content through chain to process digest, decrypt etc */
+	for (;;)
+	{
+		i=BIO_read(in,buf,sizeof(buf));
+		if (i <= 0)
+			{
+			if (BIO_method_type(in) == BIO_TYPE_CIPHER)
+				{
+				if (!BIO_get_cipher_status(in))
+					goto err;
+				}
+			if (i < 0)
+				goto err;
+			break;
+			}
+				
+		if (tmpout && (BIO_write(tmpout, buf, i) != i))
+			goto err;
+	}
+
+	if(flags & CMS_TEXT)
+		{
+		if(!SMIME_text(tmpout, out))
+			{
+			CMSerr(CMS_F_CMS_COPY_CONTENT,CMS_R_SMIME_TEXT_ERROR);
+			goto err;
+			}
+		}
+
+	r = 1;
+
+	err:
+	if (tmpout && (tmpout != out))
+		BIO_free(tmpout);
+	return r;
+
+	}
+
+static int check_content(CMS_ContentInfo *cms)
+	{
+	ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
+	if (!pos || !*pos)
+		{
+		CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT);
+		return 0;
+		}
+	return 1;
+	}
+
+static void do_free_upto(BIO *f, BIO *upto)
+	{
+	if (upto)
+		{
+		BIO *tbio;
+		do 
+			{
+			tbio = BIO_pop(f);
+			BIO_free(f);
+			f = tbio;
+			}
+		while (f != upto);
+		}
+	else
+		BIO_free_all(f);
+	}
+
+int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
+	{
+	BIO *cont;
+	int r;
+	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data)
+		{
+		CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA);
+		return 0;
+		}
+	cont = CMS_dataInit(cms, NULL);
+	if (!cont)
+		return 0;
+	r = cms_copy_content(out, cont, flags);
+	BIO_free_all(cont);
+	return r;
+	}
+
+CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
+	{
+	CMS_ContentInfo *cms;
+	cms = cms_Data_create();
+	if (!cms)
+		return NULL;
+
+	if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
+		return cms;
+
+	CMS_ContentInfo_free(cms);
+
+	return NULL;
+	}
+
+int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+							unsigned int flags)
+	{
+	BIO *cont;
+	int r;
+	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest)
+		{
+		CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA);
+		return 0;
+		}
+
+	if (!dcont && !check_content(cms))
+		return 0;
+
+	cont = CMS_dataInit(cms, dcont);
+	if (!cont)
+		return 0;
+	r = cms_copy_content(out, cont, flags);
+	if (r)
+		r = cms_DigestedData_do_final(cms, cont, 1);
+	do_free_upto(cont, dcont);
+	return r;
+	}
+
+CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
+					unsigned int flags)
+	{
+	CMS_ContentInfo *cms;
+	if (!md)
+		md = EVP_sha1();
+	cms = cms_DigestedData_create(md);
+	if (!cms)
+		return NULL;
+
+	if(!(flags & CMS_DETACHED))
+		CMS_set_detached(cms, 0);
+
+	if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
+		return cms;
+
+	CMS_ContentInfo_free(cms);
+	return NULL;
+	}
+
+int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
+				const unsigned char *key, size_t keylen,
+				BIO *dcont, BIO *out, unsigned int flags)
+	{
+	BIO *cont;
+	int r;
+	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted)
+		{
+		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
+					CMS_R_TYPE_NOT_ENCRYPTED_DATA);
+		return 0;
+		}
+
+	if (!dcont && !check_content(cms))
+		return 0;
+
+	if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0)
+		return 0;
+	cont = CMS_dataInit(cms, dcont);
+	if (!cont)
+		return 0;
+	r = cms_copy_content(out, cont, flags);
+	do_free_upto(cont, dcont);
+	return r;
+	}
+
+CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
+					const unsigned char *key, size_t keylen,
+					unsigned int flags)
+	{
+	CMS_ContentInfo *cms;
+	if (!cipher)
+		{
+		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER);
+		return NULL;
+		}
+	cms = CMS_ContentInfo_new();
+	if (!cms)
+		return NULL;
+	if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen))
+		return NULL;
+
+	if(!(flags & CMS_DETACHED))
+		CMS_set_detached(cms, 0);
+
+	if ((flags & (CMS_STREAM|CMS_PARTIAL))
+		|| CMS_final(cms, in, NULL, flags))
+		return cms;
+
+	CMS_ContentInfo_free(cms);
+	return NULL;
+	}
+
+static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
+					X509_STORE *store,
+					STACK_OF(X509) *certs,
+					STACK_OF(X509_CRL) *crls,
+					unsigned int flags)
+	{
+	X509_STORE_CTX ctx;
+	X509 *signer;
+	int i, j, r = 0;
+	CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
+	if (!X509_STORE_CTX_init(&ctx, store, signer, certs))
+		{
+		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT,
+						CMS_R_STORE_INIT_ERROR);
+		goto err;
+		}
+	X509_STORE_CTX_set_default(&ctx, "smime_sign");
+	if (crls)
+		X509_STORE_CTX_set0_crls(&ctx, crls);
+
+	i = X509_verify_cert(&ctx);
+	if (i <= 0)
+		{
+		j = X509_STORE_CTX_get_error(&ctx);
+		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT,
+						CMS_R_CERTIFICATE_VERIFY_ERROR);
+		ERR_add_error_data(2, "Verify error:",
+					 X509_verify_cert_error_string(j));
+		goto err;
+		}
+	r = 1;
+	err:
+	X509_STORE_CTX_cleanup(&ctx);
+	return r;
+
+	}
+
+int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+		 X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags)
+	{
+	CMS_SignerInfo *si;
+	STACK_OF(CMS_SignerInfo) *sinfos;
+	STACK_OF(X509) *cms_certs = NULL;
+	STACK_OF(X509_CRL) *crls = NULL;
+	X509 *signer;
+	int i, scount = 0, ret = 0;
+	BIO *cmsbio = NULL, *tmpin = NULL;
+
+	if (!dcont && !check_content(cms))
+		return 0;
+
+	/* Attempt to find all signer certificates */
+
+	sinfos = CMS_get0_SignerInfos(cms);
+
+	if (sk_CMS_SignerInfo_num(sinfos) <= 0)
+		{
+		CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS);
+		goto err;
+		}
+
+	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
+		{
+		si = sk_CMS_SignerInfo_value(sinfos, i);
+		CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
+		if (signer)
+			scount++;
+		}
+
+	if (scount != sk_CMS_SignerInfo_num(sinfos))
+		scount += CMS_set1_signers_certs(cms, certs, flags);
+
+	if (scount != sk_CMS_SignerInfo_num(sinfos))
+		{
+		CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND);
+		goto err;
+		}
+
+	/* Attempt to verify all signers certs */
+
+	if (!(flags & CMS_NO_SIGNER_CERT_VERIFY))
+		{
+		cms_certs = CMS_get1_certs(cms);
+		if (!(flags & CMS_NOCRL))
+			crls = CMS_get1_crls(cms);
+		for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
+			{
+			si = sk_CMS_SignerInfo_value(sinfos, i);
+			if (!cms_signerinfo_verify_cert(si, store,
+							cms_certs, crls, flags))
+				goto err;
+			}
+		}
+
+	/* Attempt to verify all SignerInfo signed attribute signatures */
+
+	if (!(flags & CMS_NO_ATTR_VERIFY))
+		{
+		for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
+			{
+			si = sk_CMS_SignerInfo_value(sinfos, i);
+			if (CMS_signed_get_attr_count(si) < 0)
+				continue;
+			if (CMS_SignerInfo_verify(si) <= 0)
+				goto err;
+			}
+		}
+
+	/* Performance optimization: if the content is a memory BIO then
+	 * store its contents in a temporary read only memory BIO. This
+	 * avoids potentially large numbers of slow copies of data which will
+	 * occur when reading from a read write memory BIO when signatures
+	 * are calculated.
+	 */
+
+	if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM))
+		{
+		char *ptr;
+		long len;
+		len = BIO_get_mem_data(dcont, &ptr);
+		tmpin = BIO_new_mem_buf(ptr, len);
+		if (tmpin == NULL)
+			{
+			CMSerr(CMS_F_CMS_VERIFY,ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		}
+	else
+		tmpin = dcont;
+		
+
+	cmsbio=CMS_dataInit(cms, tmpin);
+	if (!cmsbio)
+		goto err;
+
+	if (!cms_copy_content(out, cmsbio, flags))
+		goto err;
+
+	if (!(flags & CMS_NO_CONTENT_VERIFY))
+		{
+		for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
+			{
+			si = sk_CMS_SignerInfo_value(sinfos, i);
+			if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0)
+				{
+				CMSerr(CMS_F_CMS_VERIFY,
+					CMS_R_CONTENT_VERIFY_ERROR);
+				goto err;
+				}
+			}
+		}
+
+	ret = 1;
+
+	err:
+	
+	if (dcont && (tmpin == dcont))
+		do_free_upto(cmsbio, dcont);
+	else
+		BIO_free_all(cmsbio);
+
+	if (cms_certs)
+		sk_X509_pop_free(cms_certs, X509_free);
+	if (crls)
+		sk_X509_CRL_pop_free(crls, X509_CRL_free);
+
+	return ret;
+	}
+
+int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
+			STACK_OF(X509) *certs,
+			X509_STORE *store, unsigned int flags)
+	{
+	int r;
+	flags &= ~(CMS_DETACHED|CMS_TEXT);
+	r = CMS_verify(rcms, certs, store, NULL, NULL, flags);
+	if (r <= 0)
+		return r;
+	return cms_Receipt_verify(rcms, ocms);
+	}
+
+CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
+						BIO *data, unsigned int flags)
+	{
+	CMS_ContentInfo *cms;
+	int i;
+
+	cms = CMS_ContentInfo_new();
+	if (!cms || !CMS_SignedData_init(cms))
+		goto merr;
+
+	if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags))
+		{
+		CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR);
+		goto err;
+		}
+
+	for (i = 0; i < sk_X509_num(certs); i++)
+		{
+		X509 *x = sk_X509_value(certs, i);
+		if (!CMS_add1_cert(cms, x))
+			goto merr;
+		}
+
+	if(!(flags & CMS_DETACHED))
+		CMS_set_detached(cms, 0);
+
+	if ((flags & (CMS_STREAM|CMS_PARTIAL))
+		|| CMS_final(cms, data, NULL, flags))
+		return cms;
+	else
+		goto err;
+
+	merr:
+	CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE);
+
+	err:
+	if (cms)
+		CMS_ContentInfo_free(cms);
+	return NULL;
+	}
+
+CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
+					X509 *signcert, EVP_PKEY *pkey,
+					STACK_OF(X509) *certs,
+					unsigned int flags)
+	{
+	CMS_SignerInfo *rct_si;
+	CMS_ContentInfo *cms = NULL;
+	ASN1_OCTET_STRING **pos, *os;
+	BIO *rct_cont = NULL;
+	int r = 0;
+
+	flags &= ~(CMS_STREAM|CMS_TEXT);
+	/* Not really detached but avoids content being allocated */
+	flags |= CMS_PARTIAL|CMS_BINARY|CMS_DETACHED;
+	if (!pkey || !signcert)
+		{
+		CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT);
+		return NULL;
+		}
+
+	/* Initialize signed data */
+
+	cms = CMS_sign(NULL, NULL, certs, NULL, flags);
+	if (!cms)
+		goto err;
+
+	/* Set inner content type to signed receipt */
+	if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt)))
+		goto err;
+
+	rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags);
+	if (!rct_si)
+		{
+		CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR);
+		goto err;
+		}
+
+	os = cms_encode_Receipt(si);
+
+	if (!os)
+		goto err;
+
+	/* Set content to digest */
+	rct_cont = BIO_new_mem_buf(os->data, os->length);
+	if (!rct_cont)
+		goto err;
+
+	/* Add msgSigDigest attribute */
+
+	if (!cms_msgSigDigest_add1(rct_si, si))
+		goto err;
+
+	/* Finalize structure */
+	if (!CMS_final(cms, rct_cont, NULL, flags))
+		goto err;
+
+	/* Set embedded content */
+	pos = CMS_get0_content(cms);
+	*pos = os;
+
+	r = 1;
+
+	err:
+	if (rct_cont)
+		BIO_free(rct_cont);
+	if (r)
+		return cms;
+	CMS_ContentInfo_free(cms);
+	return NULL;
+
+	}
+
+CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
+				const EVP_CIPHER *cipher, unsigned int flags)
+	{
+	CMS_ContentInfo *cms;
+	int i;
+	X509 *recip;
+	cms = CMS_EnvelopedData_create(cipher);
+	if (!cms)
+		goto merr;
+	for (i = 0; i < sk_X509_num(certs); i++)
+		{
+		recip = sk_X509_value(certs, i);
+		if (!CMS_add1_recipient_cert(cms, recip, flags))
+			{
+			CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR);
+			goto err;
+			}
+		}
+
+	if(!(flags & CMS_DETACHED))
+		CMS_set_detached(cms, 0);
+
+	if ((flags & (CMS_STREAM|CMS_PARTIAL))
+		|| CMS_final(cms, data, NULL, flags))
+		return cms;
+	else
+		goto err;
+
+	merr:
+	CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE);
+	err:
+	if (cms)
+		CMS_ContentInfo_free(cms);
+	return NULL;
+	}
+
+int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
+	{
+	STACK_OF(CMS_RecipientInfo) *ris;
+	CMS_RecipientInfo *ri;
+	int i, r;
+	ris = CMS_get0_RecipientInfos(cms);
+	for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
+		{
+		ri = sk_CMS_RecipientInfo_value(ris, i);
+		if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_TRANS)
+				continue;
+		/* If we have a cert try matching RecipientInfo
+		 * otherwise try them all.
+		 */
+		if (!cert || (CMS_RecipientInfo_ktri_cert_cmp(ri, cert) == 0))
+			{
+			CMS_RecipientInfo_set0_pkey(ri, pk);
+			r = CMS_RecipientInfo_decrypt(cms, ri);
+			CMS_RecipientInfo_set0_pkey(ri, NULL);
+			if (r > 0)
+				return 1;
+			if (cert)
+				{
+				CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY,
+						CMS_R_DECRYPT_ERROR);
+				return 0;
+				}
+			ERR_clear_error();
+			}
+		}
+
+	CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT);
+	return 0;
+
+	}
+
+int CMS_decrypt_set1_key(CMS_ContentInfo *cms, 
+				unsigned char *key, size_t keylen,
+				unsigned char *id, size_t idlen)
+	{
+	STACK_OF(CMS_RecipientInfo) *ris;
+	CMS_RecipientInfo *ri;
+	int i, r;
+	ris = CMS_get0_RecipientInfos(cms);
+	for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
+		{
+		ri = sk_CMS_RecipientInfo_value(ris, i);
+		if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK)
+				continue;
+
+		/* If we have an id try matching RecipientInfo
+		 * otherwise try them all.
+		 */
+		if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0))
+			{
+			CMS_RecipientInfo_set0_key(ri, key, keylen);
+			r = CMS_RecipientInfo_decrypt(cms, ri);
+			CMS_RecipientInfo_set0_key(ri, NULL, 0);
+			if (r > 0)
+				return 1;
+			if (id)
+				{
+				CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY,
+						CMS_R_DECRYPT_ERROR);
+				return 0;
+				}
+			ERR_clear_error();
+			}
+		}
+
+	CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT);
+	return 0;
+
+	}
+	
+int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
+				BIO *dcont, BIO *out,
+				unsigned int flags)
+	{
+	int r;
+	BIO *cont;
+	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped)
+		{
+		CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA);
+		return 0;
+		}
+	if (!dcont && !check_content(cms))
+		return 0;
+	if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert))
+		return 0;
+
+	cont = CMS_dataInit(cms, dcont);
+	if (!cont)
+		return 0;
+	r = cms_copy_content(out, cont, flags);
+	do_free_upto(cont, dcont);
+	return r;
+	}
+
+int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags)
+	{
+	BIO *cmsbio;
+	int ret = 0;
+	if (!(cmsbio = CMS_dataInit(cms, dcont)))
+		{
+		CMSerr(CMS_F_CMS_FINAL,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+
+	SMIME_crlf_copy(data, cmsbio, flags);
+
+	(void)BIO_flush(cmsbio);
+
+
+        if (!CMS_dataFinal(cms, cmsbio))
+		{
+		CMSerr(CMS_F_CMS_FINAL,CMS_R_CMS_DATAFINAL_ERROR);
+		goto err;
+		}
+
+	ret = 1;
+
+	err:
+	do_free_upto(cmsbio, dcont);
+
+	return ret;
+
+	}
+
+#ifdef ZLIB
+
+int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+							unsigned int flags)
+	{
+	BIO *cont;
+	int r;
+	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData)
+		{
+		CMSerr(CMS_F_CMS_UNCOMPRESS,
+					CMS_R_TYPE_NOT_COMPRESSED_DATA);
+		return 0;
+		}
+
+	if (!dcont && !check_content(cms))
+		return 0;
+
+	cont = CMS_dataInit(cms, dcont);
+	if (!cont)
+		return 0;
+	r = cms_copy_content(out, cont, flags);
+	do_free_upto(cont, dcont);
+	return r;
+	}
+
+CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
+	{
+	CMS_ContentInfo *cms;
+	if (comp_nid <= 0)
+		comp_nid = NID_zlib_compression;
+	cms = cms_CompressedData_create(comp_nid);
+	if (!cms)
+		return NULL;
+
+	if(!(flags & CMS_DETACHED))
+		CMS_set_detached(cms, 0);
+
+	if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
+		return cms;
+
+	CMS_ContentInfo_free(cms);
+	return NULL;
+	}
+
+#else
+
+int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+							unsigned int flags)
+	{
+	CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+	return 0;
+	}
+
+CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
+	{
+	CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+	return NULL;
+	}
+
+#endif
diff --git a/openssl/crypto/comp/Makefile b/openssl/crypto/comp/Makefile
new file mode 100644
index 0000000..efda832
--- /dev/null
+++ b/openssl/crypto/comp/Makefile
@@ -0,0 +1,108 @@
+#
+# OpenSSL/crypto/comp/Makefile
+#
+
+DIR=	comp
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= comp_lib.c comp_err.c \
+	c_rle.c c_zlib.c
+
+LIBOBJ=	comp_lib.o comp_err.o \
+	c_rle.o c_zlib.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= comp.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+c_rle.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+c_rle.o: ../../include/openssl/comp.h ../../include/openssl/crypto.h
+c_rle.o: ../../include/openssl/e_os2.h ../../include/openssl/obj_mac.h
+c_rle.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+c_rle.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+c_rle.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+c_rle.o: ../../include/openssl/symhacks.h c_rle.c
+c_zlib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+c_zlib.o: ../../include/openssl/comp.h ../../include/openssl/crypto.h
+c_zlib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+c_zlib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+c_zlib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+c_zlib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+c_zlib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+c_zlib.o: ../../include/openssl/symhacks.h c_zlib.c
+comp_err.o: ../../include/openssl/bio.h ../../include/openssl/comp.h
+comp_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+comp_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+comp_err.o: ../../include/openssl/opensslconf.h
+comp_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+comp_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+comp_err.o: ../../include/openssl/symhacks.h comp_err.c
+comp_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+comp_lib.o: ../../include/openssl/comp.h ../../include/openssl/crypto.h
+comp_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/obj_mac.h
+comp_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+comp_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+comp_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+comp_lib.o: ../../include/openssl/symhacks.h comp_lib.c
diff --git a/openssl/crypto/comp/c_rle.c b/openssl/crypto/comp/c_rle.c
new file mode 100644
index 0000000..18bceae
--- /dev/null
+++ b/openssl/crypto/comp/c_rle.c
@@ -0,0 +1,61 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/objects.h>
+#include <openssl/comp.h>
+
+static int rle_compress_block(COMP_CTX *ctx, unsigned char *out,
+	unsigned int olen, unsigned char *in, unsigned int ilen);
+static int rle_expand_block(COMP_CTX *ctx, unsigned char *out,
+	unsigned int olen, unsigned char *in, unsigned int ilen);
+
+static COMP_METHOD rle_method={
+	NID_rle_compression,
+	LN_rle_compression,
+	NULL,
+	NULL,
+	rle_compress_block,
+	rle_expand_block,
+	NULL,
+	NULL,
+	};
+
+COMP_METHOD *COMP_rle(void)
+	{
+	return(&rle_method);
+	}
+
+static int rle_compress_block(COMP_CTX *ctx, unsigned char *out,
+	     unsigned int olen, unsigned char *in, unsigned int ilen)
+	{
+	/* int i; */
+
+	if (olen < (ilen+1))
+		{
+		/* ZZZZZZZZZZZZZZZZZZZZZZ */
+		return(-1);
+		}
+
+	*(out++)=0;
+	memcpy(out,in,ilen);
+	return(ilen+1);
+	}
+
+static int rle_expand_block(COMP_CTX *ctx, unsigned char *out,
+	     unsigned int olen, unsigned char *in, unsigned int ilen)
+	{
+	int i;
+
+	if (ilen == 0 || olen < (ilen-1))
+		{
+		/* ZZZZZZZZZZZZZZZZZZZZZZ */
+		return(-1);
+		}
+
+	i= *(in++);
+	if (i == 0)
+		{
+		memcpy(out,in,ilen-1);
+		}
+	return(ilen-1);
+	}
diff --git a/openssl/crypto/comp/c_zlib.c b/openssl/crypto/comp/c_zlib.c
new file mode 100644
index 0000000..8adf35f
--- /dev/null
+++ b/openssl/crypto/comp/c_zlib.c
@@ -0,0 +1,799 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/objects.h>
+#include <openssl/comp.h>
+#include <openssl/err.h>
+
+COMP_METHOD *COMP_zlib(void );
+
+static COMP_METHOD zlib_method_nozlib={
+	NID_undef,
+	"(undef)",
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	};
+
+#ifndef ZLIB
+#undef ZLIB_SHARED
+#else
+
+#include <zlib.h>
+
+static int zlib_stateful_init(COMP_CTX *ctx);
+static void zlib_stateful_finish(COMP_CTX *ctx);
+static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
+	unsigned int olen, unsigned char *in, unsigned int ilen);
+static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
+	unsigned int olen, unsigned char *in, unsigned int ilen);
+
+
+/* memory allocations functions for zlib intialization */
+static void* zlib_zalloc(void* opaque, unsigned int no, unsigned int size)
+{
+	void *p;
+	
+	p=OPENSSL_malloc(no*size);
+	if (p)
+		memset(p, 0, no*size);
+	return p;
+}
+
+
+static void zlib_zfree(void* opaque, void* address)
+{
+	OPENSSL_free(address);
+}
+
+#if 0
+static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
+	unsigned int olen, unsigned char *in, unsigned int ilen);
+static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
+	unsigned int olen, unsigned char *in, unsigned int ilen);
+
+static int zz_uncompress(Bytef *dest, uLongf *destLen, const Bytef *source,
+	uLong sourceLen);
+
+static COMP_METHOD zlib_stateless_method={
+	NID_zlib_compression,
+	LN_zlib_compression,
+	NULL,
+	NULL,
+	zlib_compress_block,
+	zlib_expand_block,
+	NULL,
+	NULL,
+	};
+#endif
+
+static COMP_METHOD zlib_stateful_method={
+	NID_zlib_compression,
+	LN_zlib_compression,
+	zlib_stateful_init,
+	zlib_stateful_finish,
+	zlib_stateful_compress_block,
+	zlib_stateful_expand_block,
+	NULL,
+	NULL,
+	};
+
+/* 
+ * When OpenSSL is built on Windows, we do not want to require that
+ * the ZLIB.DLL be available in order for the OpenSSL DLLs to
+ * work.  Therefore, all ZLIB routines are loaded at run time
+ * and we do not link to a .LIB file when ZLIB_SHARED is set.
+ */
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
+# include <windows.h>
+#endif /* !(OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32) */
+
+#ifdef ZLIB_SHARED
+#include <openssl/dso.h>
+
+/* Function pointers */
+typedef int (*compress_ft)(Bytef *dest,uLongf *destLen,
+	const Bytef *source, uLong sourceLen);
+typedef int (*inflateEnd_ft)(z_streamp strm);
+typedef int (*inflate_ft)(z_streamp strm, int flush);
+typedef int (*inflateInit__ft)(z_streamp strm,
+	const char * version, int stream_size);
+typedef int (*deflateEnd_ft)(z_streamp strm);
+typedef int (*deflate_ft)(z_streamp strm, int flush);
+typedef int (*deflateInit__ft)(z_streamp strm, int level,
+	const char * version, int stream_size);
+typedef const char * (*zError__ft)(int err);
+static compress_ft	p_compress=NULL;
+static inflateEnd_ft	p_inflateEnd=NULL;
+static inflate_ft	p_inflate=NULL;
+static inflateInit__ft	p_inflateInit_=NULL;
+static deflateEnd_ft	p_deflateEnd=NULL;
+static deflate_ft	p_deflate=NULL;
+static deflateInit__ft	p_deflateInit_=NULL;
+static zError__ft	p_zError=NULL;
+
+static int zlib_loaded = 0;     /* only attempt to init func pts once */
+static DSO *zlib_dso = NULL;
+
+#define compress                p_compress
+#define inflateEnd              p_inflateEnd
+#define inflate                 p_inflate
+#define inflateInit_            p_inflateInit_
+#define deflateEnd              p_deflateEnd
+#define deflate                 p_deflate
+#define deflateInit_            p_deflateInit_
+#define zError			p_zError
+#endif /* ZLIB_SHARED */
+
+struct zlib_state
+	{
+	z_stream istream;
+	z_stream ostream;
+	};
+
+static int zlib_stateful_ex_idx = -1;
+
+static int zlib_stateful_init(COMP_CTX *ctx)
+	{
+	int err;
+	struct zlib_state *state =
+		(struct zlib_state *)OPENSSL_malloc(sizeof(struct zlib_state));
+
+	if (state == NULL)
+		goto err;
+
+	state->istream.zalloc = zlib_zalloc;
+	state->istream.zfree = zlib_zfree;
+	state->istream.opaque = Z_NULL;
+	state->istream.next_in = Z_NULL;
+	state->istream.next_out = Z_NULL;
+	state->istream.avail_in = 0;
+	state->istream.avail_out = 0;
+	err = inflateInit_(&state->istream,
+		ZLIB_VERSION, sizeof(z_stream));
+	if (err != Z_OK)
+		goto err;
+
+	state->ostream.zalloc = zlib_zalloc;
+	state->ostream.zfree = zlib_zfree;
+	state->ostream.opaque = Z_NULL;
+	state->ostream.next_in = Z_NULL;
+	state->ostream.next_out = Z_NULL;
+	state->ostream.avail_in = 0;
+	state->ostream.avail_out = 0;
+	err = deflateInit_(&state->ostream,Z_DEFAULT_COMPRESSION,
+		ZLIB_VERSION, sizeof(z_stream));
+	if (err != Z_OK)
+		goto err;
+
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data);
+	CRYPTO_set_ex_data(&ctx->ex_data,zlib_stateful_ex_idx,state);
+	return 1;
+ err:
+	if (state) OPENSSL_free(state);
+	return 0;
+	}
+
+static void zlib_stateful_finish(COMP_CTX *ctx)
+	{
+	struct zlib_state *state =
+		(struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
+			zlib_stateful_ex_idx);
+	inflateEnd(&state->istream);
+	deflateEnd(&state->ostream);
+	OPENSSL_free(state);
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data);
+	}
+
+static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
+	unsigned int olen, unsigned char *in, unsigned int ilen)
+	{
+	int err = Z_OK;
+	struct zlib_state *state =
+		(struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
+			zlib_stateful_ex_idx);
+
+	if (state == NULL)
+		return -1;
+
+	state->ostream.next_in = in;
+	state->ostream.avail_in = ilen;
+	state->ostream.next_out = out;
+	state->ostream.avail_out = olen;
+	if (ilen > 0)
+		err = deflate(&state->ostream, Z_SYNC_FLUSH);
+	if (err != Z_OK)
+		return -1;
+#ifdef DEBUG_ZLIB
+	fprintf(stderr,"compress(%4d)->%4d %s\n",
+		ilen,olen - state->ostream.avail_out,
+		(ilen != olen - state->ostream.avail_out)?"zlib":"clear");
+#endif
+	return olen - state->ostream.avail_out;
+	}
+
+static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
+	unsigned int olen, unsigned char *in, unsigned int ilen)
+	{
+	int err = Z_OK;
+
+	struct zlib_state *state =
+		(struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
+			zlib_stateful_ex_idx);
+
+	if (state == NULL)
+		return 0;
+
+	state->istream.next_in = in;
+	state->istream.avail_in = ilen;
+	state->istream.next_out = out;
+	state->istream.avail_out = olen;
+	if (ilen > 0)
+		err = inflate(&state->istream, Z_SYNC_FLUSH);
+	if (err != Z_OK)
+		return -1;
+#ifdef DEBUG_ZLIB
+	fprintf(stderr,"expand(%4d)->%4d %s\n",
+		ilen,olen - state->istream.avail_out,
+		(ilen != olen - state->istream.avail_out)?"zlib":"clear");
+#endif
+	return olen - state->istream.avail_out;
+	}
+
+#if 0
+static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
+	unsigned int olen, unsigned char *in, unsigned int ilen)
+	{
+	unsigned long l;
+	int i;
+	int clear=1;
+
+	if (ilen > 128)
+		{
+		out[0]=1;
+		l=olen-1;
+		i=compress(&(out[1]),&l,in,(unsigned long)ilen);
+		if (i != Z_OK)
+			return(-1);
+		if (ilen > l)
+			{
+			clear=0;
+			l++;
+			}
+		}
+	if (clear)
+		{
+		out[0]=0;
+		memcpy(&(out[1]),in,ilen);
+		l=ilen+1;
+		}
+#ifdef DEBUG_ZLIB
+	fprintf(stderr,"compress(%4d)->%4d %s\n",
+		ilen,(int)l,(clear)?"clear":"zlib");
+#endif
+	return((int)l);
+	}
+
+static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
+	unsigned int olen, unsigned char *in, unsigned int ilen)
+	{
+	unsigned long l;
+	int i;
+
+	if (in[0])
+		{
+		l=olen;
+		i=zz_uncompress(out,&l,&(in[1]),(unsigned long)ilen-1);
+		if (i != Z_OK)
+			return(-1);
+		}
+	else
+		{
+		memcpy(out,&(in[1]),ilen-1);
+		l=ilen-1;
+		}
+#ifdef DEBUG_ZLIB
+        fprintf(stderr,"expand  (%4d)->%4d %s\n",
+		ilen,(int)l,in[0]?"zlib":"clear");
+#endif
+	return((int)l);
+	}
+
+static int zz_uncompress (Bytef *dest, uLongf *destLen, const Bytef *source,
+	     uLong sourceLen)
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (Bytef*)source;
+    stream.avail_in = (uInt)sourceLen;
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+
+    err = inflateInit_(&stream,
+	    ZLIB_VERSION, sizeof(z_stream));
+    if (err != Z_OK) return err;
+
+    err = inflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        inflateEnd(&stream);
+        return err;
+    }
+    *destLen = stream.total_out;
+
+    err = inflateEnd(&stream);
+    return err;
+}
+#endif
+
+#endif
+
+COMP_METHOD *COMP_zlib(void)
+	{
+	COMP_METHOD *meth = &zlib_method_nozlib;
+
+#ifdef ZLIB_SHARED
+	if (!zlib_loaded)
+		{
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
+		zlib_dso = DSO_load(NULL, "ZLIB1", NULL, 0);
+#else
+		zlib_dso = DSO_load(NULL, "z", NULL, 0);
+#endif
+		if (zlib_dso != NULL)
+			{
+			p_compress
+				= (compress_ft) DSO_bind_func(zlib_dso,
+					"compress");
+			p_inflateEnd
+				= (inflateEnd_ft) DSO_bind_func(zlib_dso,
+					"inflateEnd");
+			p_inflate
+				= (inflate_ft) DSO_bind_func(zlib_dso,
+					"inflate");
+			p_inflateInit_
+				= (inflateInit__ft) DSO_bind_func(zlib_dso,
+					"inflateInit_");
+			p_deflateEnd
+				= (deflateEnd_ft) DSO_bind_func(zlib_dso,
+					"deflateEnd");
+			p_deflate
+				= (deflate_ft) DSO_bind_func(zlib_dso,
+					"deflate");
+			p_deflateInit_
+				= (deflateInit__ft) DSO_bind_func(zlib_dso,
+					"deflateInit_");
+			p_zError
+				= (zError__ft) DSO_bind_func(zlib_dso,
+					"zError");
+
+			if (p_compress && p_inflateEnd && p_inflate
+				&& p_inflateInit_ && p_deflateEnd
+				&& p_deflate && p_deflateInit_ && p_zError)
+				zlib_loaded++;
+			}
+		}
+
+#endif
+#ifdef ZLIB_SHARED
+	if (zlib_loaded)
+#endif
+#if defined(ZLIB) || defined(ZLIB_SHARED)
+		{
+		/* init zlib_stateful_ex_idx here so that in a multi-process
+		 * application it's enough to intialize openssl before forking
+		 * (idx will be inherited in all the children) */
+		if (zlib_stateful_ex_idx == -1)
+			{
+			CRYPTO_w_lock(CRYPTO_LOCK_COMP);
+			if (zlib_stateful_ex_idx == -1)
+				zlib_stateful_ex_idx =
+					CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
+						0,NULL,NULL,NULL,NULL);
+			CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
+			if (zlib_stateful_ex_idx == -1)
+				goto err;
+			}
+		
+		meth = &zlib_stateful_method;
+		}
+err:	
+#endif
+
+	return(meth);
+	}
+
+void COMP_zlib_cleanup(void)
+	{
+#ifdef ZLIB_SHARED
+	if (zlib_dso)
+		DSO_free(zlib_dso);
+#endif
+	}
+
+#ifdef ZLIB
+
+/* Zlib based compression/decompression filter BIO */
+
+typedef struct
+	{
+	unsigned char *ibuf;	/* Input buffer */
+	int ibufsize;		/* Buffer size */
+	z_stream zin;		/* Input decompress context */
+	unsigned char *obuf;	/* Output buffer */
+	int obufsize;		/* Output buffer size */
+	unsigned char *optr;	/* Position in output buffer */
+	int ocount;		/* Amount of data in output buffer */
+	int odone;		/* deflate EOF */
+	int comp_level;		/* Compression level to use */
+	z_stream zout;		/* Output compression context */
+	} BIO_ZLIB_CTX;
+
+#define ZLIB_DEFAULT_BUFSIZE 1024
+
+static int bio_zlib_new(BIO *bi);
+static int bio_zlib_free(BIO *bi);
+static int bio_zlib_read(BIO *b, char *out, int outl);
+static int bio_zlib_write(BIO *b, const char *in, int inl);
+static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr);
+static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp);
+
+static BIO_METHOD bio_meth_zlib = 
+	{
+	BIO_TYPE_COMP,
+	"zlib",
+	bio_zlib_write,
+	bio_zlib_read,
+	NULL,
+	NULL,
+	bio_zlib_ctrl,
+	bio_zlib_new,
+	bio_zlib_free,
+	bio_zlib_callback_ctrl
+	};
+
+BIO_METHOD *BIO_f_zlib(void)
+	{
+	return &bio_meth_zlib;
+	}
+
+
+static int bio_zlib_new(BIO *bi)
+	{
+	BIO_ZLIB_CTX *ctx;
+#ifdef ZLIB_SHARED
+	(void)COMP_zlib();
+	if (!zlib_loaded)
+		{
+		COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED);
+		return 0;
+		}
+#endif
+	ctx = OPENSSL_malloc(sizeof(BIO_ZLIB_CTX));
+	if(!ctx)
+		{
+		COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	ctx->ibuf = NULL;
+	ctx->obuf = NULL;
+	ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE;
+	ctx->obufsize = ZLIB_DEFAULT_BUFSIZE;
+	ctx->zin.zalloc = Z_NULL;
+	ctx->zin.zfree = Z_NULL;
+	ctx->zin.next_in = NULL;
+	ctx->zin.avail_in = 0;
+	ctx->zin.next_out = NULL;
+	ctx->zin.avail_out = 0;
+	ctx->zout.zalloc = Z_NULL;
+	ctx->zout.zfree = Z_NULL;
+	ctx->zout.next_in = NULL;
+	ctx->zout.avail_in = 0;
+	ctx->zout.next_out = NULL;
+	ctx->zout.avail_out = 0;
+	ctx->odone = 0;
+	ctx->comp_level = Z_DEFAULT_COMPRESSION;
+	bi->init = 1;
+	bi->ptr = (char *)ctx;
+	bi->flags = 0;
+	return 1;
+	}
+
+static int bio_zlib_free(BIO *bi)
+	{
+	BIO_ZLIB_CTX *ctx;
+	if(!bi) return 0;
+	ctx = (BIO_ZLIB_CTX *)bi->ptr;
+	if(ctx->ibuf)
+		{
+		/* Destroy decompress context */
+		inflateEnd(&ctx->zin);
+		OPENSSL_free(ctx->ibuf);
+		}
+	if(ctx->obuf)
+		{
+		/* Destroy compress context */
+		deflateEnd(&ctx->zout);
+		OPENSSL_free(ctx->obuf);
+		}
+	OPENSSL_free(ctx);
+	bi->ptr = NULL;
+	bi->init = 0;
+	bi->flags = 0;
+	return 1;
+	}
+
+static int bio_zlib_read(BIO *b, char *out, int outl)
+	{
+	BIO_ZLIB_CTX *ctx;
+	int ret;
+	z_stream *zin;
+	if(!out || !outl) return 0;
+	ctx = (BIO_ZLIB_CTX *)b->ptr;
+	zin = &ctx->zin;
+	BIO_clear_retry_flags(b);
+	if(!ctx->ibuf)
+		{
+		ctx->ibuf = OPENSSL_malloc(ctx->ibufsize);
+		if(!ctx->ibuf)
+			{
+			COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		inflateInit(zin);
+		zin->next_in = ctx->ibuf;
+		zin->avail_in = 0;
+		}
+
+	/* Copy output data directly to supplied buffer */
+	zin->next_out = (unsigned char *)out;
+	zin->avail_out = (unsigned int)outl;
+	for(;;)
+		{
+		/* Decompress while data available */
+		while(zin->avail_in)
+			{
+			ret = inflate(zin, 0);
+			if((ret != Z_OK) && (ret != Z_STREAM_END))
+				{
+				COMPerr(COMP_F_BIO_ZLIB_READ,
+						COMP_R_ZLIB_INFLATE_ERROR);
+				ERR_add_error_data(2, "zlib error:",
+							zError(ret));
+				return 0;
+				}
+			/* If EOF or we've read everything then return */
+			if((ret == Z_STREAM_END) || !zin->avail_out)
+				return outl - zin->avail_out;
+			}
+
+		/* No data in input buffer try to read some in,
+		 * if an error then return the total data read.
+		 */
+		ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize);
+		if(ret <= 0)
+			{
+			/* Total data read */
+			int tot = outl - zin->avail_out;
+			BIO_copy_next_retry(b);
+			if(ret < 0) return (tot > 0) ? tot : ret;
+			return tot;
+			}
+		zin->avail_in = ret;
+		zin->next_in = ctx->ibuf;
+		}
+	}
+
+static int bio_zlib_write(BIO *b, const char *in, int inl)
+	{
+	BIO_ZLIB_CTX *ctx;
+	int ret;
+	z_stream *zout;
+	if(!in || !inl) return 0;
+	ctx = (BIO_ZLIB_CTX *)b->ptr;
+	if(ctx->odone) return 0;
+	zout = &ctx->zout;
+	BIO_clear_retry_flags(b);
+	if(!ctx->obuf)
+		{
+		ctx->obuf = OPENSSL_malloc(ctx->obufsize);
+		/* Need error here */
+		if(!ctx->obuf)
+			{
+			COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		ctx->optr = ctx->obuf;
+		ctx->ocount = 0;
+		deflateInit(zout, ctx->comp_level);
+		zout->next_out = ctx->obuf;
+		zout->avail_out = ctx->obufsize;
+		}
+	/* Obtain input data directly from supplied buffer */
+	zout->next_in = (void *)in;
+	zout->avail_in = inl;
+	for(;;)
+		{
+		/* If data in output buffer write it first */
+		while(ctx->ocount) {
+			ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
+			if(ret <= 0)
+				{
+				/* Total data written */
+				int tot = inl - zout->avail_in;
+				BIO_copy_next_retry(b);
+				if(ret < 0) return (tot > 0) ? tot : ret;
+				return tot;
+				}
+			ctx->optr += ret;
+			ctx->ocount -= ret;
+		}
+
+		/* Have we consumed all supplied data? */
+		if(!zout->avail_in)
+			return inl;
+
+		/* Compress some more */
+
+		/* Reset buffer */
+		ctx->optr = ctx->obuf;
+		zout->next_out = ctx->obuf;
+		zout->avail_out = ctx->obufsize;
+		/* Compress some more */
+		ret = deflate(zout, 0);
+		if(ret != Z_OK)
+			{
+			COMPerr(COMP_F_BIO_ZLIB_WRITE,
+						COMP_R_ZLIB_DEFLATE_ERROR);
+			ERR_add_error_data(2, "zlib error:", zError(ret));
+			return 0;
+			}
+		ctx->ocount = ctx->obufsize - zout->avail_out;
+		}
+	}
+
+static int bio_zlib_flush(BIO *b)
+	{
+	BIO_ZLIB_CTX *ctx;
+	int ret;
+	z_stream *zout;
+	ctx = (BIO_ZLIB_CTX *)b->ptr;
+	/* If no data written or already flush show success */
+	if(!ctx->obuf || (ctx->odone && !ctx->ocount)) return 1;
+	zout = &ctx->zout;
+	BIO_clear_retry_flags(b);
+	/* No more input data */
+	zout->next_in = NULL;
+	zout->avail_in = 0;
+	for(;;)
+		{
+		/* If data in output buffer write it first */
+		while(ctx->ocount)
+			{
+			ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
+			if(ret <= 0)
+				{
+				BIO_copy_next_retry(b);
+				return ret;
+				}
+			ctx->optr += ret;
+			ctx->ocount -= ret;
+			}
+		if(ctx->odone) return 1;
+
+		/* Compress some more */
+
+		/* Reset buffer */
+		ctx->optr = ctx->obuf;
+		zout->next_out = ctx->obuf;
+		zout->avail_out = ctx->obufsize;
+		/* Compress some more */
+		ret = deflate(zout, Z_FINISH);
+		if(ret == Z_STREAM_END) ctx->odone = 1;
+		else if(ret != Z_OK)
+			{
+			COMPerr(COMP_F_BIO_ZLIB_FLUSH,
+						COMP_R_ZLIB_DEFLATE_ERROR);
+			ERR_add_error_data(2, "zlib error:", zError(ret));
+			return 0;
+			}
+		ctx->ocount = ctx->obufsize - zout->avail_out;
+		}
+	}
+
+static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	BIO_ZLIB_CTX *ctx;
+	int ret, *ip;
+	int ibs, obs;
+	if(!b->next_bio) return 0;
+	ctx = (BIO_ZLIB_CTX *)b->ptr;
+	switch (cmd)
+		{
+
+	case BIO_CTRL_RESET:
+		ctx->ocount = 0;
+		ctx->odone = 0;
+		ret = 1;
+		break;
+
+	case BIO_CTRL_FLUSH:
+		ret = bio_zlib_flush(b);
+		if (ret > 0)
+			ret = BIO_flush(b->next_bio);
+		break;
+
+	case BIO_C_SET_BUFF_SIZE:
+		ibs = -1;
+		obs = -1;
+		if (ptr != NULL)
+			{
+			ip = ptr;
+			if (*ip == 0)
+				ibs = (int) num;
+			else 
+				obs = (int) num;
+			}
+		else
+			{
+			ibs = (int)num;
+			obs = ibs;
+			}
+
+		if (ibs != -1)
+			{
+			if (ctx->ibuf)
+				{
+				OPENSSL_free(ctx->ibuf);
+				ctx->ibuf = NULL;
+				}
+			ctx->ibufsize = ibs;
+			}
+
+		if (obs != -1)
+			{
+			if (ctx->obuf)
+				{
+				OPENSSL_free(ctx->obuf);
+				ctx->obuf = NULL;
+				}
+			ctx->obufsize = obs;
+			}
+		ret = 1;
+		break;
+
+	case BIO_C_DO_STATE_MACHINE:
+		BIO_clear_retry_flags(b);
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		BIO_copy_next_retry(b);
+		break;
+
+	default:
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+
+		}
+
+	return ret;
+	}
+
+
+static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+	{
+	if(!b->next_bio)
+		return 0;
+	return
+		BIO_callback_ctrl(b->next_bio, cmd, fp);
+	}
+
+#endif
diff --git a/openssl/crypto/comp/comp.h b/openssl/crypto/comp/comp.h
new file mode 100644
index 0000000..4b405c7
--- /dev/null
+++ b/openssl/crypto/comp/comp.h
@@ -0,0 +1,80 @@
+
+#ifndef HEADER_COMP_H
+#define HEADER_COMP_H
+
+#include <openssl/crypto.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct comp_ctx_st COMP_CTX;
+
+typedef struct comp_method_st
+	{
+	int type;		/* NID for compression library */
+	const char *name;	/* A text string to identify the library */
+	int (*init)(COMP_CTX *ctx);
+	void (*finish)(COMP_CTX *ctx);
+	int (*compress)(COMP_CTX *ctx,
+			unsigned char *out, unsigned int olen,
+			unsigned char *in, unsigned int ilen);
+	int (*expand)(COMP_CTX *ctx,
+		      unsigned char *out, unsigned int olen,
+		      unsigned char *in, unsigned int ilen);
+	/* The following two do NOTHING, but are kept for backward compatibility */
+	long (*ctrl)(void);
+	long (*callback_ctrl)(void);
+	} COMP_METHOD;
+
+struct comp_ctx_st
+	{
+	COMP_METHOD *meth;
+	unsigned long compress_in;
+	unsigned long compress_out;
+	unsigned long expand_in;
+	unsigned long expand_out;
+
+	CRYPTO_EX_DATA	ex_data;
+	};
+
+
+COMP_CTX *COMP_CTX_new(COMP_METHOD *meth);
+void COMP_CTX_free(COMP_CTX *ctx);
+int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen,
+	unsigned char *in, int ilen);
+int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen,
+	unsigned char *in, int ilen);
+COMP_METHOD *COMP_rle(void );
+COMP_METHOD *COMP_zlib(void );
+void COMP_zlib_cleanup(void);
+
+#ifdef HEADER_BIO_H
+#ifdef ZLIB
+BIO_METHOD *BIO_f_zlib(void);
+#endif
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_COMP_strings(void);
+
+/* Error codes for the COMP functions. */
+
+/* Function codes. */
+#define COMP_F_BIO_ZLIB_FLUSH				 99
+#define COMP_F_BIO_ZLIB_NEW				 100
+#define COMP_F_BIO_ZLIB_READ				 101
+#define COMP_F_BIO_ZLIB_WRITE				 102
+
+/* Reason codes. */
+#define COMP_R_ZLIB_DEFLATE_ERROR			 99
+#define COMP_R_ZLIB_INFLATE_ERROR			 100
+#define COMP_R_ZLIB_NOT_SUPPORTED			 101
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/comp/comp_err.c b/openssl/crypto/comp/comp_err.c
new file mode 100644
index 0000000..661c94c
--- /dev/null
+++ b/openssl/crypto/comp/comp_err.c
@@ -0,0 +1,100 @@
+/* crypto/comp/comp_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/comp.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_COMP,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_COMP,0,reason)
+
+static ERR_STRING_DATA COMP_str_functs[]=
+	{
+{ERR_FUNC(COMP_F_BIO_ZLIB_FLUSH),	"BIO_ZLIB_FLUSH"},
+{ERR_FUNC(COMP_F_BIO_ZLIB_NEW),	"BIO_ZLIB_NEW"},
+{ERR_FUNC(COMP_F_BIO_ZLIB_READ),	"BIO_ZLIB_READ"},
+{ERR_FUNC(COMP_F_BIO_ZLIB_WRITE),	"BIO_ZLIB_WRITE"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA COMP_str_reasons[]=
+	{
+{ERR_REASON(COMP_R_ZLIB_DEFLATE_ERROR)   ,"zlib deflate error"},
+{ERR_REASON(COMP_R_ZLIB_INFLATE_ERROR)   ,"zlib inflate error"},
+{ERR_REASON(COMP_R_ZLIB_NOT_SUPPORTED)   ,"zlib not supported"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_COMP_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(COMP_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,COMP_str_functs);
+		ERR_load_strings(0,COMP_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/comp/comp_lib.c b/openssl/crypto/comp/comp_lib.c
new file mode 100644
index 0000000..b60ae37
--- /dev/null
+++ b/openssl/crypto/comp/comp_lib.c
@@ -0,0 +1,72 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/objects.h>
+#include <openssl/comp.h>
+
+COMP_CTX *COMP_CTX_new(COMP_METHOD *meth)
+	{
+	COMP_CTX *ret;
+
+	if ((ret=(COMP_CTX *)OPENSSL_malloc(sizeof(COMP_CTX))) == NULL)
+		{
+		/* ZZZZZZZZZZZZZZZZ */
+		return(NULL);
+		}
+	memset(ret,0,sizeof(COMP_CTX));
+	ret->meth=meth;
+	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
+		{
+		OPENSSL_free(ret);
+		ret=NULL;
+		}
+	return(ret);
+	}
+
+void COMP_CTX_free(COMP_CTX *ctx)
+	{
+	if(ctx == NULL)
+	    return;
+
+	if (ctx->meth->finish != NULL)
+		ctx->meth->finish(ctx);
+
+	OPENSSL_free(ctx);
+	}
+
+int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen,
+	     unsigned char *in, int ilen)
+	{
+	int ret;
+	if (ctx->meth->compress == NULL)
+		{
+		/* ZZZZZZZZZZZZZZZZZ */
+		return(-1);
+		}
+	ret=ctx->meth->compress(ctx,out,olen,in,ilen);
+	if (ret > 0)
+		{
+		ctx->compress_in+=ilen;
+		ctx->compress_out+=ret;
+		}
+	return(ret);
+	}
+
+int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen,
+	     unsigned char *in, int ilen)
+	{
+	int ret;
+
+	if (ctx->meth->expand == NULL)
+		{
+		/* ZZZZZZZZZZZZZZZZZ */
+		return(-1);
+		}
+	ret=ctx->meth->expand(ctx,out,olen,in,ilen);
+	if (ret > 0)
+		{
+		ctx->expand_in+=ilen;
+		ctx->expand_out+=ret;
+		}
+	return(ret);
+	}
diff --git a/openssl/crypto/conf/Makefile b/openssl/crypto/conf/Makefile
new file mode 100644
index 0000000..78bb324
--- /dev/null
+++ b/openssl/crypto/conf/Makefile
@@ -0,0 +1,152 @@
+#
+# OpenSSL/crypto/conf/Makefile
+#
+
+DIR=	conf
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= conf_err.c conf_lib.c conf_api.c conf_def.c conf_mod.c \
+	 conf_mall.c conf_sap.c
+
+LIBOBJ=	conf_err.o conf_lib.o conf_api.o conf_def.o conf_mod.o \
+	conf_mall.o conf_sap.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= conf.h conf_api.h
+HEADER=	conf_def.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+conf_api.o: ../../e_os.h ../../include/openssl/bio.h
+conf_api.o: ../../include/openssl/conf.h ../../include/openssl/conf_api.h
+conf_api.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+conf_api.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+conf_api.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+conf_api.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+conf_api.o: ../../include/openssl/symhacks.h conf_api.c
+conf_def.o: ../../e_os.h ../../include/openssl/bio.h
+conf_def.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+conf_def.o: ../../include/openssl/conf_api.h ../../include/openssl/crypto.h
+conf_def.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+conf_def.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+conf_def.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+conf_def.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+conf_def.o: ../../include/openssl/symhacks.h ../cryptlib.h conf_def.c
+conf_def.o: conf_def.h
+conf_err.o: ../../include/openssl/bio.h ../../include/openssl/conf.h
+conf_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+conf_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+conf_err.o: ../../include/openssl/opensslconf.h
+conf_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+conf_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+conf_err.o: ../../include/openssl/symhacks.h conf_err.c
+conf_lib.o: ../../include/openssl/bio.h ../../include/openssl/conf.h
+conf_lib.o: ../../include/openssl/conf_api.h ../../include/openssl/crypto.h
+conf_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+conf_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+conf_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+conf_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+conf_lib.o: ../../include/openssl/symhacks.h conf_lib.c
+conf_mall.o: ../../e_os.h ../../include/openssl/asn1.h
+conf_mall.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+conf_mall.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+conf_mall.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+conf_mall.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+conf_mall.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+conf_mall.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+conf_mall.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+conf_mall.o: ../../include/openssl/objects.h
+conf_mall.o: ../../include/openssl/opensslconf.h
+conf_mall.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+conf_mall.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+conf_mall.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+conf_mall.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+conf_mall.o: ../../include/openssl/x509_vfy.h ../cryptlib.h conf_mall.c
+conf_mod.o: ../../e_os.h ../../include/openssl/asn1.h
+conf_mod.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+conf_mod.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+conf_mod.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+conf_mod.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+conf_mod.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+conf_mod.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+conf_mod.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+conf_mod.o: ../../include/openssl/opensslconf.h
+conf_mod.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+conf_mod.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+conf_mod.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+conf_mod.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+conf_mod.o: ../../include/openssl/x509_vfy.h ../cryptlib.h conf_mod.c
+conf_sap.o: ../../e_os.h ../../include/openssl/asn1.h
+conf_sap.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+conf_sap.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+conf_sap.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+conf_sap.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+conf_sap.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+conf_sap.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+conf_sap.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+conf_sap.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+conf_sap.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+conf_sap.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+conf_sap.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+conf_sap.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+conf_sap.o: ../../include/openssl/x509_vfy.h ../cryptlib.h conf_sap.c
diff --git a/openssl/crypto/conf/README b/openssl/crypto/conf/README
new file mode 100644
index 0000000..96e53b3
--- /dev/null
+++ b/openssl/crypto/conf/README
@@ -0,0 +1,73 @@
+Configuration modules. These are a set of modules which can perform
+various configuration functions.
+
+Currently the routines should be called at most once when an application
+starts up: that is before it starts any threads.
+
+The routines read a configuration file set up like this:
+
+-----
+#default section
+openssl_conf=init_section
+
+[init_section]
+
+module1=value1
+#Second instance of module1
+module1.1=valueX
+module2=value2
+module3=dso_literal
+module4=dso_section
+
+[dso_section]
+
+path=/some/path/to/some/dso.so
+other_stuff=other_value
+----
+
+When this file is loaded a configuration module with the specified string
+(module* in the above example) is looked up and its init function called as:
+
+int conf_init_func(CONF_IMODULE *md, CONF *cnf);
+
+The function can then take whatever action is appropriate, for example further
+lookups based on the value. Multiple instances of the same config module can be
+loaded.
+
+When the application closes down the modules are cleaned up by calling an
+optional finish function:
+
+void conf_finish_func(CONF_IMODULE *md);
+
+The finish functions are called in reverse order: that is the last module
+loaded is the first one cleaned up.
+
+If no module exists with a given name then an attempt is made to load a DSO
+with the supplied name. This might mean that "module3" attempts to load a DSO
+called libmodule3.so or module3.dll for example. An explicit DSO name can be
+given by including a separate section as in the module4 example above.
+
+The DSO is expected to at least contain an initialization function:
+
+int OPENSSL_init(CONF_IMODULE *md, CONF *cnf);
+
+and may also include a finish function:
+
+void OPENSSL_finish(CONF_IMODULE *md);
+
+Static modules can also be added using,
+
+int CONF_module_add(char *name, dso_mod_init_func *ifunc, dso_mod_finish_func
+*ffunc);
+
+where "name" is the name in the configuration file this function corresponds
+to.
+
+A set of builtin modules (currently only an ASN1 non functional test module)
+can be added by calling OPENSSL_load_builtin_modules(). 
+
+The function OPENSSL_config() is intended as a simple configuration function
+that any application can call to perform various default configuration tasks.
+It uses the file openssl.cnf in the usual locations.
+
+
diff --git a/openssl/crypto/conf/cnf_save.c b/openssl/crypto/conf/cnf_save.c
new file mode 100644
index 0000000..1439487
--- /dev/null
+++ b/openssl/crypto/conf/cnf_save.c
@@ -0,0 +1,106 @@
+/* crypto/conf/cnf_save.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/conf.h>
+
+static void print_conf(CONF_VALUE *cv);
+static IMPLEMENT_LHASH_DOALL_FN(print_conf, CONF_VALUE *);
+
+main()
+	{
+	LHASH *conf;
+	long l;
+
+	conf=CONF_load(NULL,"../../apps/openssl.cnf",&l);
+	if (conf == NULL)
+		{
+		fprintf(stderr,"error loading config, line %ld\n",l);
+		exit(1);
+		}
+
+	lh_doall(conf,LHASH_DOALL_FN(print_conf));
+	}
+
+
+static void print_conf(CONF_VALUE *cv)
+	{
+	int i;
+	CONF_VALUE *v;
+	char *section;
+	char *name;
+	char *value;
+	STACK *s;
+
+	/* If it is a single entry, return */
+
+	if (cv->name != NULL) return;
+
+	printf("[ %s ]\n",cv->section);
+	s=(STACK *)cv->value;
+
+	for (i=0; i<sk_num(s); i++)
+		{
+		v=(CONF_VALUE *)sk_value(s,i);
+		section=(v->section == NULL)?"None":v->section;
+		name=(v->name == NULL)?"None":v->name;
+		value=(v->value == NULL)?"None":v->value;
+		printf("%s=%s\n",name,value);
+		}
+	printf("\n");
+	}
diff --git a/openssl/crypto/conf/conf.h b/openssl/crypto/conf/conf.h
new file mode 100644
index 0000000..c219997
--- /dev/null
+++ b/openssl/crypto/conf/conf.h
@@ -0,0 +1,263 @@
+/* crypto/conf/conf.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef  HEADER_CONF_H
+#define HEADER_CONF_H
+
+#include <openssl/bio.h>
+#include <openssl/lhash.h>
+#include <openssl/stack.h>
+#include <openssl/safestack.h>
+#include <openssl/e_os2.h>
+
+#include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+	{
+	char *section;
+	char *name;
+	char *value;
+	} CONF_VALUE;
+
+DECLARE_STACK_OF(CONF_VALUE)
+DECLARE_LHASH_OF(CONF_VALUE);
+
+struct conf_st;
+struct conf_method_st;
+typedef struct conf_method_st CONF_METHOD;
+
+struct conf_method_st
+	{
+	const char *name;
+	CONF *(*create)(CONF_METHOD *meth);
+	int (*init)(CONF *conf);
+	int (*destroy)(CONF *conf);
+	int (*destroy_data)(CONF *conf);
+	int (*load_bio)(CONF *conf, BIO *bp, long *eline);
+	int (*dump)(const CONF *conf, BIO *bp);
+	int (*is_number)(const CONF *conf, char c);
+	int (*to_int)(const CONF *conf, char c);
+	int (*load)(CONF *conf, const char *name, long *eline);
+	};
+
+/* Module definitions */
+
+typedef struct conf_imodule_st CONF_IMODULE;
+typedef struct conf_module_st CONF_MODULE;
+
+DECLARE_STACK_OF(CONF_MODULE)
+DECLARE_STACK_OF(CONF_IMODULE)
+
+/* DSO module function typedefs */
+typedef int conf_init_func(CONF_IMODULE *md, const CONF *cnf);
+typedef void conf_finish_func(CONF_IMODULE *md);
+
+#define	CONF_MFLAGS_IGNORE_ERRORS	0x1
+#define CONF_MFLAGS_IGNORE_RETURN_CODES	0x2
+#define CONF_MFLAGS_SILENT		0x4
+#define CONF_MFLAGS_NO_DSO		0x8
+#define CONF_MFLAGS_IGNORE_MISSING_FILE	0x10
+#define CONF_MFLAGS_DEFAULT_SECTION	0x20
+
+int CONF_set_default_method(CONF_METHOD *meth);
+void CONF_set_nconf(CONF *conf,LHASH_OF(CONF_VALUE) *hash);
+LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf,const char *file,
+				long *eline);
+#ifndef OPENSSL_NO_FP_API
+LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
+				   long *eline);
+#endif
+LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,long *eline);
+STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
+				       const char *section);
+char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf,const char *group,
+		      const char *name);
+long CONF_get_number(LHASH_OF(CONF_VALUE) *conf,const char *group,
+		     const char *name);
+void CONF_free(LHASH_OF(CONF_VALUE) *conf);
+int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out);
+int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out);
+
+void OPENSSL_config(const char *config_name);
+void OPENSSL_no_config(void);
+
+/* New conf code.  The semantics are different from the functions above.
+   If that wasn't the case, the above functions would have been replaced */
+
+struct conf_st
+	{
+	CONF_METHOD *meth;
+	void *meth_data;
+	LHASH_OF(CONF_VALUE) *data;
+	};
+
+CONF *NCONF_new(CONF_METHOD *meth);
+CONF_METHOD *NCONF_default(void);
+CONF_METHOD *NCONF_WIN32(void);
+#if 0 /* Just to give you an idea of what I have in mind */
+CONF_METHOD *NCONF_XML(void);
+#endif
+void NCONF_free(CONF *conf);
+void NCONF_free_data(CONF *conf);
+
+int NCONF_load(CONF *conf,const char *file,long *eline);
+#ifndef OPENSSL_NO_FP_API
+int NCONF_load_fp(CONF *conf, FILE *fp,long *eline);
+#endif
+int NCONF_load_bio(CONF *conf, BIO *bp,long *eline);
+STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf,const char *section);
+char *NCONF_get_string(const CONF *conf,const char *group,const char *name);
+int NCONF_get_number_e(const CONF *conf,const char *group,const char *name,
+		       long *result);
+int NCONF_dump_fp(const CONF *conf, FILE *out);
+int NCONF_dump_bio(const CONF *conf, BIO *out);
+
+#if 0 /* The following function has no error checking,
+	 and should therefore be avoided */
+long NCONF_get_number(CONF *conf,char *group,char *name);
+#else
+#define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r)
+#endif
+  
+/* Module functions */
+
+int CONF_modules_load(const CONF *cnf, const char *appname,
+		      unsigned long flags);
+int CONF_modules_load_file(const char *filename, const char *appname,
+			   unsigned long flags);
+void CONF_modules_unload(int all);
+void CONF_modules_finish(void);
+void CONF_modules_free(void);
+int CONF_module_add(const char *name, conf_init_func *ifunc,
+		    conf_finish_func *ffunc);
+
+const char *CONF_imodule_get_name(const CONF_IMODULE *md);
+const char *CONF_imodule_get_value(const CONF_IMODULE *md);
+void *CONF_imodule_get_usr_data(const CONF_IMODULE *md);
+void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data);
+CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md);
+unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md);
+void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags);
+void *CONF_module_get_usr_data(CONF_MODULE *pmod);
+void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data);
+
+char *CONF_get1_default_config_file(void);
+
+int CONF_parse_list(const char *list, int sep, int nospc,
+	int (*list_cb)(const char *elem, int len, void *usr), void *arg);
+
+void OPENSSL_load_builtin_modules(void);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_CONF_strings(void);
+
+/* Error codes for the CONF functions. */
+
+/* Function codes. */
+#define CONF_F_CONF_DUMP_FP				 104
+#define CONF_F_CONF_LOAD				 100
+#define CONF_F_CONF_LOAD_BIO				 102
+#define CONF_F_CONF_LOAD_FP				 103
+#define CONF_F_CONF_MODULES_LOAD			 116
+#define CONF_F_CONF_PARSE_LIST				 119
+#define CONF_F_DEF_LOAD					 120
+#define CONF_F_DEF_LOAD_BIO				 121
+#define CONF_F_MODULE_INIT				 115
+#define CONF_F_MODULE_LOAD_DSO				 117
+#define CONF_F_MODULE_RUN				 118
+#define CONF_F_NCONF_DUMP_BIO				 105
+#define CONF_F_NCONF_DUMP_FP				 106
+#define CONF_F_NCONF_GET_NUMBER				 107
+#define CONF_F_NCONF_GET_NUMBER_E			 112
+#define CONF_F_NCONF_GET_SECTION			 108
+#define CONF_F_NCONF_GET_STRING				 109
+#define CONF_F_NCONF_LOAD				 113
+#define CONF_F_NCONF_LOAD_BIO				 110
+#define CONF_F_NCONF_LOAD_FP				 114
+#define CONF_F_NCONF_NEW				 111
+#define CONF_F_STR_COPY					 101
+
+/* Reason codes. */
+#define CONF_R_ERROR_LOADING_DSO			 110
+#define CONF_R_LIST_CANNOT_BE_NULL			 115
+#define CONF_R_MISSING_CLOSE_SQUARE_BRACKET		 100
+#define CONF_R_MISSING_EQUAL_SIGN			 101
+#define CONF_R_MISSING_FINISH_FUNCTION			 111
+#define CONF_R_MISSING_INIT_FUNCTION			 112
+#define CONF_R_MODULE_INITIALIZATION_ERROR		 109
+#define CONF_R_NO_CLOSE_BRACE				 102
+#define CONF_R_NO_CONF					 105
+#define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE		 106
+#define CONF_R_NO_SECTION				 107
+#define CONF_R_NO_SUCH_FILE				 114
+#define CONF_R_NO_VALUE					 108
+#define CONF_R_UNABLE_TO_CREATE_NEW_SECTION		 103
+#define CONF_R_UNKNOWN_MODULE_NAME			 113
+#define CONF_R_VARIABLE_HAS_NO_VALUE			 104
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/conf/conf_api.c b/openssl/crypto/conf/conf_api.c
new file mode 100644
index 0000000..f5fcbb9
--- /dev/null
+++ b/openssl/crypto/conf/conf_api.c
@@ -0,0 +1,301 @@
+/* conf_api.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Part of the code in here was originally in conf.c, which is now removed */
+
+#ifndef CONF_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/conf.h>
+#include <openssl/conf_api.h>
+#include "e_os.h"
+
+static void value_free_hash_doall_arg(CONF_VALUE *a,
+				      LHASH_OF(CONF_VALUE) *conf);
+static void value_free_stack_doall(CONF_VALUE *a);
+static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE,
+				    LHASH_OF(CONF_VALUE))
+static IMPLEMENT_LHASH_DOALL_FN(value_free_stack, CONF_VALUE)
+
+/* Up until OpenSSL 0.9.5a, this was get_section */
+CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section)
+	{
+	CONF_VALUE *v,vv;
+
+	if ((conf == NULL) || (section == NULL)) return(NULL);
+	vv.name=NULL;
+	vv.section=(char *)section;
+	v=lh_CONF_VALUE_retrieve(conf->data,&vv);
+	return(v);
+	}
+
+/* Up until OpenSSL 0.9.5a, this was CONF_get_section */
+STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf,
+					       const char *section)
+	{
+	CONF_VALUE *v;
+
+	v=_CONF_get_section(conf,section);
+	if (v != NULL)
+		return((STACK_OF(CONF_VALUE) *)v->value);
+	else
+		return(NULL);
+	}
+
+int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value)
+	{
+	CONF_VALUE *v = NULL;
+	STACK_OF(CONF_VALUE) *ts;
+
+	ts = (STACK_OF(CONF_VALUE) *)section->value;
+
+	value->section=section->section;	
+	if (!sk_CONF_VALUE_push(ts,value))
+		{
+		return 0;
+		}
+
+	v = lh_CONF_VALUE_insert(conf->data, value);
+	if (v != NULL)
+		{
+		(void)sk_CONF_VALUE_delete_ptr(ts,v);
+		OPENSSL_free(v->name);
+		OPENSSL_free(v->value);
+		OPENSSL_free(v);
+		}
+	return 1;
+	}
+
+char *_CONF_get_string(const CONF *conf, const char *section, const char *name)
+	{
+	CONF_VALUE *v,vv;
+	char *p;
+
+	if (name == NULL) return(NULL);
+	if (conf != NULL)
+		{
+		if (section != NULL)
+			{
+			vv.name=(char *)name;
+			vv.section=(char *)section;
+			v=lh_CONF_VALUE_retrieve(conf->data,&vv);
+			if (v != NULL) return(v->value);
+			if (strcmp(section,"ENV") == 0)
+				{
+				p=getenv(name);
+				if (p != NULL) return(p);
+				}
+			}
+		vv.section="default";
+		vv.name=(char *)name;
+		v=lh_CONF_VALUE_retrieve(conf->data,&vv);
+		if (v != NULL)
+			return(v->value);
+		else
+			return(NULL);
+		}
+	else
+		return(getenv(name));
+	}
+
+#if 0 /* There's no way to provide error checking with this function, so
+	 force implementors of the higher levels to get a string and read
+	 the number themselves. */
+long _CONF_get_number(CONF *conf, char *section, char *name)
+	{
+	char *str;
+	long ret=0;
+
+	str=_CONF_get_string(conf,section,name);
+	if (str == NULL) return(0);
+	for (;;)
+		{
+		if (conf->meth->is_number(conf, *str))
+			ret=ret*10+conf->meth->to_int(conf, *str);
+		else
+			return(ret);
+		str++;
+		}
+	}
+#endif
+
+static unsigned long conf_value_hash(const CONF_VALUE *v)
+	{
+	return (lh_strhash(v->section)<<2)^lh_strhash(v->name);
+	}
+static IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE)
+
+static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b)
+	{
+	int i;
+
+	if (a->section != b->section)
+		{
+		i=strcmp(a->section,b->section);
+		if (i) return(i);
+		}
+
+	if ((a->name != NULL) && (b->name != NULL))
+		{
+		i=strcmp(a->name,b->name);
+		return(i);
+		}
+	else if (a->name == b->name)
+		return(0);
+	else
+		return((a->name == NULL)?-1:1);
+	}
+static IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE)
+
+int _CONF_new_data(CONF *conf)
+	{
+	if (conf == NULL)
+		{
+		return 0;
+		}
+	if (conf->data == NULL)
+		if ((conf->data = lh_CONF_VALUE_new()) == NULL)
+			{
+			return 0;
+			}
+	return 1;
+	}
+
+void _CONF_free_data(CONF *conf)
+	{
+	if (conf == NULL || conf->data == NULL) return;
+
+	lh_CONF_VALUE_down_load(conf->data)=0; /* evil thing to make
+				  * sure the 'OPENSSL_free()' works as
+				  * expected */
+	lh_CONF_VALUE_doall_arg(conf->data,
+				LHASH_DOALL_ARG_FN(value_free_hash),
+				LHASH_OF(CONF_VALUE), conf->data);
+
+	/* We now have only 'section' entries in the hash table.
+	 * Due to problems with */
+
+	lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack));
+	lh_CONF_VALUE_free(conf->data);
+	}
+
+static void value_free_hash_doall_arg(CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf)
+	{
+	if (a->name != NULL)
+		(void)lh_CONF_VALUE_delete(conf,a);
+	}
+
+static void value_free_stack_doall(CONF_VALUE *a)
+	{
+	CONF_VALUE *vv;
+	STACK_OF(CONF_VALUE) *sk;
+	int i;
+
+	if (a->name != NULL) return;
+
+	sk=(STACK_OF(CONF_VALUE) *)a->value;
+	for (i=sk_CONF_VALUE_num(sk)-1; i>=0; i--)
+		{
+		vv=sk_CONF_VALUE_value(sk,i);
+		OPENSSL_free(vv->value);
+		OPENSSL_free(vv->name);
+		OPENSSL_free(vv);
+		}
+	if (sk != NULL) sk_CONF_VALUE_free(sk);
+	OPENSSL_free(a->section);
+	OPENSSL_free(a);
+	}
+
+/* Up until OpenSSL 0.9.5a, this was new_section */
+CONF_VALUE *_CONF_new_section(CONF *conf, const char *section)
+	{
+	STACK_OF(CONF_VALUE) *sk=NULL;
+	int ok=0,i;
+	CONF_VALUE *v=NULL,*vv;
+
+	if ((sk=sk_CONF_VALUE_new_null()) == NULL)
+		goto err;
+	if ((v=OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL)
+		goto err;
+	i=strlen(section)+1;
+	if ((v->section=OPENSSL_malloc(i)) == NULL)
+		goto err;
+
+	memcpy(v->section,section,i);
+	v->name=NULL;
+	v->value=(char *)sk;
+	
+	vv=lh_CONF_VALUE_insert(conf->data,v);
+	OPENSSL_assert(vv == NULL);
+	ok=1;
+err:
+	if (!ok)
+		{
+		if (sk != NULL) sk_CONF_VALUE_free(sk);
+		if (v != NULL) OPENSSL_free(v);
+		v=NULL;
+		}
+	return(v);
+	}
+
+IMPLEMENT_STACK_OF(CONF_VALUE)
diff --git a/openssl/crypto/conf/conf_api.h b/openssl/crypto/conf/conf_api.h
new file mode 100644
index 0000000..87a954a
--- /dev/null
+++ b/openssl/crypto/conf/conf_api.h
@@ -0,0 +1,89 @@
+/* conf_api.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef  HEADER_CONF_API_H
+#define HEADER_CONF_API_H
+
+#include <openssl/lhash.h>
+#include <openssl/conf.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Up until OpenSSL 0.9.5a, this was new_section */
+CONF_VALUE *_CONF_new_section(CONF *conf, const char *section);
+/* Up until OpenSSL 0.9.5a, this was get_section */
+CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section);
+/* Up until OpenSSL 0.9.5a, this was CONF_get_section */
+STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf,
+					       const char *section);
+
+int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value);
+char *_CONF_get_string(const CONF *conf, const char *section,
+		       const char *name);
+long _CONF_get_number(const CONF *conf, const char *section, const char *name);
+
+int _CONF_new_data(CONF *conf);
+void _CONF_free_data(CONF *conf);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/openssl/crypto/conf/conf_def.c b/openssl/crypto/conf/conf_def.c
new file mode 100644
index 0000000..cf95132
--- /dev/null
+++ b/openssl/crypto/conf/conf_def.c
@@ -0,0 +1,740 @@
+/* crypto/conf/conf.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Part of the code in here was originally in conf.c, which is now removed */
+
+#include <stdio.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/stack.h>
+#include <openssl/lhash.h>
+#include <openssl/conf.h>
+#include <openssl/conf_api.h>
+#include "conf_def.h"
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+
+static char *eat_ws(CONF *conf, char *p);
+static char *eat_alpha_numeric(CONF *conf, char *p);
+static void clear_comments(CONF *conf, char *p);
+static int str_copy(CONF *conf,char *section,char **to, char *from);
+static char *scan_quote(CONF *conf, char *p);
+static char *scan_dquote(CONF *conf, char *p);
+#define scan_esc(conf,p)	(((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2)))
+
+static CONF *def_create(CONF_METHOD *meth);
+static int def_init_default(CONF *conf);
+static int def_init_WIN32(CONF *conf);
+static int def_destroy(CONF *conf);
+static int def_destroy_data(CONF *conf);
+static int def_load(CONF *conf, const char *name, long *eline);
+static int def_load_bio(CONF *conf, BIO *bp, long *eline);
+static int def_dump(const CONF *conf, BIO *bp);
+static int def_is_number(const CONF *conf, char c);
+static int def_to_int(const CONF *conf, char c);
+
+const char CONF_def_version[]="CONF_def" OPENSSL_VERSION_PTEXT;
+
+static CONF_METHOD default_method = {
+	"OpenSSL default",
+	def_create,
+	def_init_default,
+	def_destroy,
+	def_destroy_data,
+	def_load_bio,
+	def_dump,
+	def_is_number,
+	def_to_int,
+	def_load
+	};
+
+static CONF_METHOD WIN32_method = {
+	"WIN32",
+	def_create,
+	def_init_WIN32,
+	def_destroy,
+	def_destroy_data,
+	def_load_bio,
+	def_dump,
+	def_is_number,
+	def_to_int,
+	def_load
+	};
+
+CONF_METHOD *NCONF_default()
+	{
+	return &default_method;
+	}
+CONF_METHOD *NCONF_WIN32()
+	{
+	return &WIN32_method;
+	}
+
+static CONF *def_create(CONF_METHOD *meth)
+	{
+	CONF *ret;
+
+	ret = OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *));
+	if (ret)
+		if (meth->init(ret) == 0)
+			{
+			OPENSSL_free(ret);
+			ret = NULL;
+			}
+	return ret;
+	}
+	
+static int def_init_default(CONF *conf)
+	{
+	if (conf == NULL)
+		return 0;
+
+	conf->meth = &default_method;
+	conf->meth_data = CONF_type_default;
+	conf->data = NULL;
+
+	return 1;
+	}
+
+static int def_init_WIN32(CONF *conf)
+	{
+	if (conf == NULL)
+		return 0;
+
+	conf->meth = &WIN32_method;
+	conf->meth_data = (void *)CONF_type_win32;
+	conf->data = NULL;
+
+	return 1;
+	}
+
+static int def_destroy(CONF *conf)
+	{
+	if (def_destroy_data(conf))
+		{
+		OPENSSL_free(conf);
+		return 1;
+		}
+	return 0;
+	}
+
+static int def_destroy_data(CONF *conf)
+	{
+	if (conf == NULL)
+		return 0;
+	_CONF_free_data(conf);
+	return 1;
+	}
+
+static int def_load(CONF *conf, const char *name, long *line)
+	{
+	int ret;
+	BIO *in=NULL;
+
+#ifdef OPENSSL_SYS_VMS
+	in=BIO_new_file(name, "r");
+#else
+	in=BIO_new_file(name, "rb");
+#endif
+	if (in == NULL)
+		{
+		if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE)
+			CONFerr(CONF_F_DEF_LOAD,CONF_R_NO_SUCH_FILE);
+		else
+			CONFerr(CONF_F_DEF_LOAD,ERR_R_SYS_LIB);
+		return 0;
+		}
+
+	ret = def_load_bio(conf, in, line);
+	BIO_free(in);
+
+	return ret;
+	}
+
+static int def_load_bio(CONF *conf, BIO *in, long *line)
+	{
+/* The macro BUFSIZE conflicts with a system macro in VxWorks */
+#define CONFBUFSIZE	512
+	int bufnum=0,i,ii;
+	BUF_MEM *buff=NULL;
+	char *s,*p,*end;
+	int again;
+	long eline=0;
+	char btmp[DECIMAL_SIZE(eline)+1];
+	CONF_VALUE *v=NULL,*tv;
+	CONF_VALUE *sv=NULL;
+	char *section=NULL,*buf;
+	char *start,*psection,*pname;
+	void *h = (void *)(conf->data);
+
+	if ((buff=BUF_MEM_new()) == NULL)
+		{
+		CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_BUF_LIB);
+		goto err;
+		}
+
+	section=(char *)OPENSSL_malloc(10);
+	if (section == NULL)
+		{
+		CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	BUF_strlcpy(section,"default",10);
+
+	if (_CONF_new_data(conf) == 0)
+		{
+		CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	sv=_CONF_new_section(conf,section);
+	if (sv == NULL)
+		{
+		CONFerr(CONF_F_DEF_LOAD_BIO,
+					CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+		goto err;
+		}
+
+	bufnum=0;
+	again=0;
+	for (;;)
+		{
+		if (!BUF_MEM_grow(buff,bufnum+CONFBUFSIZE))
+			{
+			CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_BUF_LIB);
+			goto err;
+			}
+		p= &(buff->data[bufnum]);
+		*p='\0';
+		BIO_gets(in, p, CONFBUFSIZE-1);
+		p[CONFBUFSIZE-1]='\0';
+		ii=i=strlen(p);
+		if (i == 0 && !again) break;
+		again=0;
+		while (i > 0)
+			{
+			if ((p[i-1] != '\r') && (p[i-1] != '\n'))
+				break;
+			else
+				i--;
+			}
+		/* we removed some trailing stuff so there is a new
+		 * line on the end. */
+		if (ii && i == ii)
+			again=1; /* long line */
+		else
+			{
+			p[i]='\0';
+			eline++; /* another input line */
+			}
+
+		/* we now have a line with trailing \r\n removed */
+
+		/* i is the number of bytes */
+		bufnum+=i;
+
+		v=NULL;
+		/* check for line continuation */
+		if (bufnum >= 1)
+			{
+			/* If we have bytes and the last char '\\' and
+			 * second last char is not '\\' */
+			p= &(buff->data[bufnum-1]);
+			if (IS_ESC(conf,p[0]) &&
+				((bufnum <= 1) || !IS_ESC(conf,p[-1])))
+				{
+				bufnum--;
+				again=1;
+				}
+			}
+		if (again) continue;
+		bufnum=0;
+		buf=buff->data;
+
+		clear_comments(conf, buf);
+		s=eat_ws(conf, buf);
+		if (IS_EOF(conf,*s)) continue; /* blank line */
+		if (*s == '[')
+			{
+			char *ss;
+
+			s++;
+			start=eat_ws(conf, s);
+			ss=start;
+again:
+			end=eat_alpha_numeric(conf, ss);
+			p=eat_ws(conf, end);
+			if (*p != ']')
+				{
+				if (*p != '\0')
+					{
+					ss=p;
+					goto again;
+					}
+				CONFerr(CONF_F_DEF_LOAD_BIO,
+					CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
+				goto err;
+				}
+			*end='\0';
+			if (!str_copy(conf,NULL,&section,start)) goto err;
+			if ((sv=_CONF_get_section(conf,section)) == NULL)
+				sv=_CONF_new_section(conf,section);
+			if (sv == NULL)
+				{
+				CONFerr(CONF_F_DEF_LOAD_BIO,
+					CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+				goto err;
+				}
+			continue;
+			}
+		else
+			{
+			pname=s;
+			psection=NULL;
+			end=eat_alpha_numeric(conf, s);
+			if ((end[0] == ':') && (end[1] == ':'))
+				{
+				*end='\0';
+				end+=2;
+				psection=pname;
+				pname=end;
+				end=eat_alpha_numeric(conf, end);
+				}
+			p=eat_ws(conf, end);
+			if (*p != '=')
+				{
+				CONFerr(CONF_F_DEF_LOAD_BIO,
+						CONF_R_MISSING_EQUAL_SIGN);
+				goto err;
+				}
+			*end='\0';
+			p++;
+			start=eat_ws(conf, p);
+			while (!IS_EOF(conf,*p))
+				p++;
+			p--;
+			while ((p != start) && (IS_WS(conf,*p)))
+				p--;
+			p++;
+			*p='\0';
+
+			if (!(v=(CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE))))
+				{
+				CONFerr(CONF_F_DEF_LOAD_BIO,
+							ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			if (psection == NULL) psection=section;
+			v->name=(char *)OPENSSL_malloc(strlen(pname)+1);
+			v->value=NULL;
+			if (v->name == NULL)
+				{
+				CONFerr(CONF_F_DEF_LOAD_BIO,
+							ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			BUF_strlcpy(v->name,pname,strlen(pname)+1);
+			if (!str_copy(conf,psection,&(v->value),start)) goto err;
+
+			if (strcmp(psection,section) != 0)
+				{
+				if ((tv=_CONF_get_section(conf,psection))
+					== NULL)
+					tv=_CONF_new_section(conf,psection);
+				if (tv == NULL)
+					{
+					CONFerr(CONF_F_DEF_LOAD_BIO,
+					   CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+					goto err;
+					}
+				}
+			else
+				tv=sv;
+#if 1
+			if (_CONF_add_string(conf, tv, v) == 0)
+				{
+				CONFerr(CONF_F_DEF_LOAD_BIO,
+							ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+#else
+			v->section=tv->section;	
+			if (!sk_CONF_VALUE_push(ts,v))
+				{
+				CONFerr(CONF_F_DEF_LOAD_BIO,
+							ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			vv=(CONF_VALUE *)lh_insert(conf->data,v);
+			if (vv != NULL)
+				{
+				sk_CONF_VALUE_delete_ptr(ts,vv);
+				OPENSSL_free(vv->name);
+				OPENSSL_free(vv->value);
+				OPENSSL_free(vv);
+				}
+#endif
+			v=NULL;
+			}
+		}
+	if (buff != NULL) BUF_MEM_free(buff);
+	if (section != NULL) OPENSSL_free(section);
+	return(1);
+err:
+	if (buff != NULL) BUF_MEM_free(buff);
+	if (section != NULL) OPENSSL_free(section);
+	if (line != NULL) *line=eline;
+	BIO_snprintf(btmp,sizeof btmp,"%ld",eline);
+	ERR_add_error_data(2,"line ",btmp);
+	if ((h != conf->data) && (conf->data != NULL))
+		{
+		CONF_free(conf->data);
+		conf->data=NULL;
+		}
+	if (v != NULL)
+		{
+		if (v->name != NULL) OPENSSL_free(v->name);
+		if (v->value != NULL) OPENSSL_free(v->value);
+		if (v != NULL) OPENSSL_free(v);
+		}
+	return(0);
+	}
+
+static void clear_comments(CONF *conf, char *p)
+	{
+	for (;;)
+		{
+		if (IS_FCOMMENT(conf,*p))
+			{
+			*p='\0';
+			return;
+			}
+		if (!IS_WS(conf,*p))
+			{
+			break;
+			}
+		p++;
+		}
+
+	for (;;)
+		{
+		if (IS_COMMENT(conf,*p))
+			{
+			*p='\0';
+			return;
+			}
+		if (IS_DQUOTE(conf,*p))
+			{
+			p=scan_dquote(conf, p);
+			continue;
+			}
+		if (IS_QUOTE(conf,*p))
+			{
+			p=scan_quote(conf, p);
+			continue;
+			}
+		if (IS_ESC(conf,*p))
+			{
+			p=scan_esc(conf,p);
+			continue;
+			}
+		if (IS_EOF(conf,*p))
+			return;
+		else
+			p++;
+		}
+	}
+
+static int str_copy(CONF *conf, char *section, char **pto, char *from)
+	{
+	int q,r,rr=0,to=0,len=0;
+	char *s,*e,*rp,*p,*rrp,*np,*cp,v;
+	BUF_MEM *buf;
+
+	if ((buf=BUF_MEM_new()) == NULL) return(0);
+
+	len=strlen(from)+1;
+	if (!BUF_MEM_grow(buf,len)) goto err;
+
+	for (;;)
+		{
+		if (IS_QUOTE(conf,*from))
+			{
+			q= *from;
+			from++;
+			while (!IS_EOF(conf,*from) && (*from != q))
+				{
+				if (IS_ESC(conf,*from))
+					{
+					from++;
+					if (IS_EOF(conf,*from)) break;
+					}
+				buf->data[to++]= *(from++);
+				}
+			if (*from == q) from++;
+			}
+		else if (IS_DQUOTE(conf,*from))
+			{
+			q= *from;
+			from++;
+			while (!IS_EOF(conf,*from))
+				{
+				if (*from == q)
+					{
+					if (*(from+1) == q)
+						{
+						from++;
+						}
+					else
+						{
+						break;
+						}
+					}
+				buf->data[to++]= *(from++);
+				}
+			if (*from == q) from++;
+			}
+		else if (IS_ESC(conf,*from))
+			{
+			from++;
+			v= *(from++);
+			if (IS_EOF(conf,v)) break;
+			else if (v == 'r') v='\r';
+			else if (v == 'n') v='\n';
+			else if (v == 'b') v='\b';
+			else if (v == 't') v='\t';
+			buf->data[to++]= v;
+			}
+		else if (IS_EOF(conf,*from))
+			break;
+		else if (*from == '$')
+			{
+			/* try to expand it */
+			rrp=NULL;
+			s= &(from[1]);
+			if (*s == '{')
+				q='}';
+			else if (*s == '(')
+				q=')';
+			else q=0;
+
+			if (q) s++;
+			cp=section;
+			e=np=s;
+			while (IS_ALPHA_NUMERIC(conf,*e))
+				e++;
+			if ((e[0] == ':') && (e[1] == ':'))
+				{
+				cp=np;
+				rrp=e;
+				rr= *e;
+				*rrp='\0';
+				e+=2;
+				np=e;
+				while (IS_ALPHA_NUMERIC(conf,*e))
+					e++;
+				}
+			r= *e;
+			*e='\0';
+			rp=e;
+			if (q)
+				{
+				if (r != q)
+					{
+					CONFerr(CONF_F_STR_COPY,CONF_R_NO_CLOSE_BRACE);
+					goto err;
+					}
+				e++;
+				}
+			/* So at this point we have
+			 * np which is the start of the name string which is
+			 *   '\0' terminated. 
+			 * cp which is the start of the section string which is
+			 *   '\0' terminated.
+			 * e is the 'next point after'.
+			 * r and rr are the chars replaced by the '\0'
+			 * rp and rrp is where 'r' and 'rr' came from.
+			 */
+			p=_CONF_get_string(conf,cp,np);
+			if (rrp != NULL) *rrp=rr;
+			*rp=r;
+			if (p == NULL)
+				{
+				CONFerr(CONF_F_STR_COPY,CONF_R_VARIABLE_HAS_NO_VALUE);
+				goto err;
+				}
+			BUF_MEM_grow_clean(buf,(strlen(p)+buf->length-(e-from)));
+			while (*p)
+				buf->data[to++]= *(p++);
+
+			/* Since we change the pointer 'from', we also have
+			   to change the perceived length of the string it
+			   points at.  /RL */
+			len -= e-from;
+			from=e;
+
+			/* In case there were no braces or parenthesis around
+			   the variable reference, we have to put back the
+			   character that was replaced with a '\0'.  /RL */
+			*rp = r;
+			}
+		else
+			buf->data[to++]= *(from++);
+		}
+	buf->data[to]='\0';
+	if (*pto != NULL) OPENSSL_free(*pto);
+	*pto=buf->data;
+	OPENSSL_free(buf);
+	return(1);
+err:
+	if (buf != NULL) BUF_MEM_free(buf);
+	return(0);
+	}
+
+static char *eat_ws(CONF *conf, char *p)
+	{
+	while (IS_WS(conf,*p) && (!IS_EOF(conf,*p)))
+		p++;
+	return(p);
+	}
+
+static char *eat_alpha_numeric(CONF *conf, char *p)
+	{
+	for (;;)
+		{
+		if (IS_ESC(conf,*p))
+			{
+			p=scan_esc(conf,p);
+			continue;
+			}
+		if (!IS_ALPHA_NUMERIC_PUNCT(conf,*p))
+			return(p);
+		p++;
+		}
+	}
+
+static char *scan_quote(CONF *conf, char *p)
+	{
+	int q= *p;
+
+	p++;
+	while (!(IS_EOF(conf,*p)) && (*p != q))
+		{
+		if (IS_ESC(conf,*p))
+			{
+			p++;
+			if (IS_EOF(conf,*p)) return(p);
+			}
+		p++;
+		}
+	if (*p == q) p++;
+	return(p);
+	}
+
+
+static char *scan_dquote(CONF *conf, char *p)
+	{
+	int q= *p;
+
+	p++;
+	while (!(IS_EOF(conf,*p)))
+		{
+		if (*p == q)
+			{
+			if (*(p+1) == q)
+				{
+				p++;
+				}
+			else
+				{
+				break;
+				}
+			}
+		p++;
+		}
+	if (*p == q) p++;
+	return(p);
+	}
+
+static void dump_value_doall_arg(CONF_VALUE *a, BIO *out)
+	{
+	if (a->name)
+		BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value);
+	else
+		BIO_printf(out, "[[%s]]\n", a->section);
+	}
+
+static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, BIO)
+
+static int def_dump(const CONF *conf, BIO *out)
+	{
+	lh_CONF_VALUE_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value),
+				BIO, out);
+	return 1;
+	}
+
+static int def_is_number(const CONF *conf, char c)
+	{
+	return IS_NUMBER(conf,c);
+	}
+
+static int def_to_int(const CONF *conf, char c)
+	{
+	return c - '0';
+	}
+
diff --git a/openssl/crypto/conf/conf_def.h b/openssl/crypto/conf/conf_def.h
new file mode 100644
index 0000000..92a7d8a
--- /dev/null
+++ b/openssl/crypto/conf/conf_def.h
@@ -0,0 +1,180 @@
+/* crypto/conf/conf_def.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* THIS FILE WAS AUTOMAGICALLY GENERATED!
+   Please modify and use keysets.pl to regenerate it. */
+
+#define CONF_NUMBER		1
+#define CONF_UPPER		2
+#define CONF_LOWER		4
+#define CONF_UNDER		256
+#define CONF_PUNCTUATION	512
+#define CONF_WS			16
+#define CONF_ESC		32
+#define CONF_QUOTE		64
+#define CONF_DQUOTE		1024
+#define CONF_COMMENT		128
+#define CONF_FCOMMENT		2048
+#define CONF_EOF		8
+#define CONF_HIGHBIT		4096
+#define CONF_ALPHA		(CONF_UPPER|CONF_LOWER)
+#define CONF_ALPHA_NUMERIC	(CONF_ALPHA|CONF_NUMBER|CONF_UNDER)
+#define CONF_ALPHA_NUMERIC_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER| \
+					CONF_PUNCTUATION)
+
+#define KEYTYPES(c)		((unsigned short *)((c)->meth_data))
+#ifndef CHARSET_EBCDIC
+#define IS_COMMENT(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_COMMENT)
+#define IS_FCOMMENT(c,a)	(KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT)
+#define IS_EOF(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_EOF)
+#define IS_ESC(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_ESC)
+#define IS_NUMBER(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_NUMBER)
+#define IS_WS(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_WS)
+#define IS_ALPHA_NUMERIC(c,a)	(KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC)
+#define IS_ALPHA_NUMERIC_PUNCT(c,a) \
+				(KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT)
+#define IS_QUOTE(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_QUOTE)
+#define IS_DQUOTE(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE)
+#define IS_HIGHBIT(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT)
+
+#else /*CHARSET_EBCDIC*/
+
+#define IS_COMMENT(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_COMMENT)
+#define IS_FCOMMENT(c,a)	(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_FCOMMENT)
+#define IS_EOF(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_EOF)
+#define IS_ESC(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ESC)
+#define IS_NUMBER(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_NUMBER)
+#define IS_WS(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_WS)
+#define IS_ALPHA_NUMERIC(c,a)	(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC)
+#define IS_ALPHA_NUMERIC_PUNCT(c,a) \
+				(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC_PUNCT)
+#define IS_QUOTE(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_QUOTE)
+#define IS_DQUOTE(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_DQUOTE)
+#define IS_HIGHBIT(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_HIGHBIT)
+#endif /*CHARSET_EBCDIC*/
+
+static unsigned short CONF_type_default[256]={
+	0x0008,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+	0x0000,0x0010,0x0010,0x0000,0x0000,0x0010,0x0000,0x0000,
+	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+	0x0010,0x0200,0x0040,0x0080,0x0000,0x0200,0x0200,0x0040,
+	0x0000,0x0000,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,
+	0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,
+	0x0001,0x0001,0x0000,0x0200,0x0000,0x0000,0x0000,0x0200,
+	0x0200,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,
+	0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,
+	0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,
+	0x0002,0x0002,0x0002,0x0000,0x0020,0x0000,0x0200,0x0100,
+	0x0040,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,
+	0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,
+	0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,
+	0x0004,0x0004,0x0004,0x0000,0x0200,0x0000,0x0200,0x0000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	};
+
+static unsigned short CONF_type_win32[256]={
+	0x0008,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+	0x0000,0x0010,0x0010,0x0000,0x0000,0x0010,0x0000,0x0000,
+	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+	0x0010,0x0200,0x0400,0x0000,0x0000,0x0200,0x0200,0x0000,
+	0x0000,0x0000,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,
+	0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,
+	0x0001,0x0001,0x0000,0x0A00,0x0000,0x0000,0x0000,0x0200,
+	0x0200,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,
+	0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,
+	0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,
+	0x0002,0x0002,0x0002,0x0000,0x0000,0x0000,0x0200,0x0100,
+	0x0000,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,
+	0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,
+	0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,
+	0x0004,0x0004,0x0004,0x0000,0x0200,0x0000,0x0200,0x0000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
+	};
+
diff --git a/openssl/crypto/conf/conf_err.c b/openssl/crypto/conf/conf_err.c
new file mode 100644
index 0000000..25bb5dc
--- /dev/null
+++ b/openssl/crypto/conf/conf_err.c
@@ -0,0 +1,131 @@
+/* crypto/conf/conf_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/conf.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_CONF,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_CONF,0,reason)
+
+static ERR_STRING_DATA CONF_str_functs[]=
+	{
+{ERR_FUNC(CONF_F_CONF_DUMP_FP),	"CONF_dump_fp"},
+{ERR_FUNC(CONF_F_CONF_LOAD),	"CONF_load"},
+{ERR_FUNC(CONF_F_CONF_LOAD_BIO),	"CONF_load_bio"},
+{ERR_FUNC(CONF_F_CONF_LOAD_FP),	"CONF_load_fp"},
+{ERR_FUNC(CONF_F_CONF_MODULES_LOAD),	"CONF_modules_load"},
+{ERR_FUNC(CONF_F_CONF_PARSE_LIST),	"CONF_parse_list"},
+{ERR_FUNC(CONF_F_DEF_LOAD),	"DEF_LOAD"},
+{ERR_FUNC(CONF_F_DEF_LOAD_BIO),	"DEF_LOAD_BIO"},
+{ERR_FUNC(CONF_F_MODULE_INIT),	"MODULE_INIT"},
+{ERR_FUNC(CONF_F_MODULE_LOAD_DSO),	"MODULE_LOAD_DSO"},
+{ERR_FUNC(CONF_F_MODULE_RUN),	"MODULE_RUN"},
+{ERR_FUNC(CONF_F_NCONF_DUMP_BIO),	"NCONF_dump_bio"},
+{ERR_FUNC(CONF_F_NCONF_DUMP_FP),	"NCONF_dump_fp"},
+{ERR_FUNC(CONF_F_NCONF_GET_NUMBER),	"NCONF_get_number"},
+{ERR_FUNC(CONF_F_NCONF_GET_NUMBER_E),	"NCONF_get_number_e"},
+{ERR_FUNC(CONF_F_NCONF_GET_SECTION),	"NCONF_get_section"},
+{ERR_FUNC(CONF_F_NCONF_GET_STRING),	"NCONF_get_string"},
+{ERR_FUNC(CONF_F_NCONF_LOAD),	"NCONF_load"},
+{ERR_FUNC(CONF_F_NCONF_LOAD_BIO),	"NCONF_load_bio"},
+{ERR_FUNC(CONF_F_NCONF_LOAD_FP),	"NCONF_load_fp"},
+{ERR_FUNC(CONF_F_NCONF_NEW),	"NCONF_new"},
+{ERR_FUNC(CONF_F_STR_COPY),	"STR_COPY"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA CONF_str_reasons[]=
+	{
+{ERR_REASON(CONF_R_ERROR_LOADING_DSO)    ,"error loading dso"},
+{ERR_REASON(CONF_R_LIST_CANNOT_BE_NULL)  ,"list cannot be null"},
+{ERR_REASON(CONF_R_MISSING_CLOSE_SQUARE_BRACKET),"missing close square bracket"},
+{ERR_REASON(CONF_R_MISSING_EQUAL_SIGN)   ,"missing equal sign"},
+{ERR_REASON(CONF_R_MISSING_FINISH_FUNCTION),"missing finish function"},
+{ERR_REASON(CONF_R_MISSING_INIT_FUNCTION),"missing init function"},
+{ERR_REASON(CONF_R_MODULE_INITIALIZATION_ERROR),"module initialization error"},
+{ERR_REASON(CONF_R_NO_CLOSE_BRACE)       ,"no close brace"},
+{ERR_REASON(CONF_R_NO_CONF)              ,"no conf"},
+{ERR_REASON(CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE),"no conf or environment variable"},
+{ERR_REASON(CONF_R_NO_SECTION)           ,"no section"},
+{ERR_REASON(CONF_R_NO_SUCH_FILE)         ,"no such file"},
+{ERR_REASON(CONF_R_NO_VALUE)             ,"no value"},
+{ERR_REASON(CONF_R_UNABLE_TO_CREATE_NEW_SECTION),"unable to create new section"},
+{ERR_REASON(CONF_R_UNKNOWN_MODULE_NAME)  ,"unknown module name"},
+{ERR_REASON(CONF_R_VARIABLE_HAS_NO_VALUE),"variable has no value"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_CONF_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(CONF_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,CONF_str_functs);
+		ERR_load_strings(0,CONF_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/conf/conf_lib.c b/openssl/crypto/conf/conf_lib.c
new file mode 100644
index 0000000..54046de
--- /dev/null
+++ b/openssl/crypto/conf/conf_lib.c
@@ -0,0 +1,407 @@
+/* conf_lib.c */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/conf.h>
+#include <openssl/conf_api.h>
+#include <openssl/lhash.h>
+
+const char CONF_version[]="CONF" OPENSSL_VERSION_PTEXT;
+
+static CONF_METHOD *default_CONF_method=NULL;
+
+/* Init a 'CONF' structure from an old LHASH */
+
+void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash)
+	{
+	if (default_CONF_method == NULL)
+		default_CONF_method = NCONF_default();
+
+	default_CONF_method->init(conf);
+	conf->data = hash;
+	}
+
+/* The following section contains the "CONF classic" functions,
+   rewritten in terms of the new CONF interface. */
+
+int CONF_set_default_method(CONF_METHOD *meth)
+	{
+	default_CONF_method = meth;
+	return 1;
+	}
+
+LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file,
+				long *eline)
+	{
+	LHASH_OF(CONF_VALUE) *ltmp;
+	BIO *in=NULL;
+
+#ifdef OPENSSL_SYS_VMS
+	in=BIO_new_file(file, "r");
+#else
+	in=BIO_new_file(file, "rb");
+#endif
+	if (in == NULL)
+		{
+		CONFerr(CONF_F_CONF_LOAD,ERR_R_SYS_LIB);
+		return NULL;
+		}
+
+	ltmp = CONF_load_bio(conf, in, eline);
+	BIO_free(in);
+
+	return ltmp;
+	}
+
+#ifndef OPENSSL_NO_FP_API
+LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
+				   long *eline)
+	{
+	BIO *btmp;
+	LHASH_OF(CONF_VALUE) *ltmp;
+	if(!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) {
+		CONFerr(CONF_F_CONF_LOAD_FP,ERR_R_BUF_LIB);
+		return NULL;
+	}
+	ltmp = CONF_load_bio(conf, btmp, eline);
+	BIO_free(btmp);
+	return ltmp;
+	}
+#endif
+
+LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,
+				    long *eline)
+	{
+	CONF ctmp;
+	int ret;
+
+	CONF_set_nconf(&ctmp, conf);
+
+	ret = NCONF_load_bio(&ctmp, bp, eline);
+	if (ret)
+		return ctmp.data;
+	return NULL;
+	}
+
+STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
+				       const char *section)
+	{
+	if (conf == NULL)
+		{
+		return NULL;
+		}
+	else
+		{
+		CONF ctmp;
+		CONF_set_nconf(&ctmp, conf);
+		return NCONF_get_section(&ctmp, section);
+		}
+	}
+
+char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf,const char *group,
+		      const char *name)
+	{
+	if (conf == NULL)
+		{
+		return NCONF_get_string(NULL, group, name);
+		}
+	else
+		{
+		CONF ctmp;
+		CONF_set_nconf(&ctmp, conf);
+		return NCONF_get_string(&ctmp, group, name);
+		}
+	}
+
+long CONF_get_number(LHASH_OF(CONF_VALUE) *conf,const char *group,
+		     const char *name)
+	{
+	int status;
+	long result = 0;
+
+	if (conf == NULL)
+		{
+		status = NCONF_get_number_e(NULL, group, name, &result);
+		}
+	else
+		{
+		CONF ctmp;
+		CONF_set_nconf(&ctmp, conf);
+		status = NCONF_get_number_e(&ctmp, group, name, &result);
+		}
+
+	if (status == 0)
+		{
+		/* This function does not believe in errors... */
+		ERR_clear_error();
+		}
+	return result;
+	}
+
+void CONF_free(LHASH_OF(CONF_VALUE) *conf)
+	{
+	CONF ctmp;
+	CONF_set_nconf(&ctmp, conf);
+	NCONF_free_data(&ctmp);
+	}
+
+#ifndef OPENSSL_NO_FP_API
+int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out)
+	{
+	BIO *btmp;
+	int ret;
+
+	if(!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) {
+		CONFerr(CONF_F_CONF_DUMP_FP,ERR_R_BUF_LIB);
+		return 0;
+	}
+	ret = CONF_dump_bio(conf, btmp);
+	BIO_free(btmp);
+	return ret;
+	}
+#endif
+
+int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out)
+	{
+	CONF ctmp;
+	CONF_set_nconf(&ctmp, conf);
+	return NCONF_dump_bio(&ctmp, out);
+	}
+
+/* The following section contains the "New CONF" functions.  They are
+   completely centralised around a new CONF structure that may contain
+   basically anything, but at least a method pointer and a table of data.
+   These functions are also written in terms of the bridge functions used
+   by the "CONF classic" functions, for consistency.  */
+
+CONF *NCONF_new(CONF_METHOD *meth)
+	{
+	CONF *ret;
+
+	if (meth == NULL)
+		meth = NCONF_default();
+
+	ret = meth->create(meth);
+	if (ret == NULL)
+		{
+		CONFerr(CONF_F_NCONF_NEW,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+
+	return ret;
+	}
+
+void NCONF_free(CONF *conf)
+	{
+	if (conf == NULL)
+		return;
+	conf->meth->destroy(conf);
+	}
+
+void NCONF_free_data(CONF *conf)
+	{
+	if (conf == NULL)
+		return;
+	conf->meth->destroy_data(conf);
+	}
+
+int NCONF_load(CONF *conf, const char *file, long *eline)
+	{
+	if (conf == NULL)
+		{
+		CONFerr(CONF_F_NCONF_LOAD,CONF_R_NO_CONF);
+		return 0;
+		}
+
+	return conf->meth->load(conf, file, eline);
+	}
+
+#ifndef OPENSSL_NO_FP_API
+int NCONF_load_fp(CONF *conf, FILE *fp,long *eline)
+	{
+	BIO *btmp;
+	int ret;
+	if(!(btmp = BIO_new_fp(fp, BIO_NOCLOSE)))
+		{
+		CONFerr(CONF_F_NCONF_LOAD_FP,ERR_R_BUF_LIB);
+		return 0;
+		}
+	ret = NCONF_load_bio(conf, btmp, eline);
+	BIO_free(btmp);
+	return ret;
+	}
+#endif
+
+int NCONF_load_bio(CONF *conf, BIO *bp,long *eline)
+	{
+	if (conf == NULL)
+		{
+		CONFerr(CONF_F_NCONF_LOAD_BIO,CONF_R_NO_CONF);
+		return 0;
+		}
+
+	return conf->meth->load_bio(conf, bp, eline);
+	}
+
+STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf,const char *section)
+	{
+	if (conf == NULL)
+		{
+		CONFerr(CONF_F_NCONF_GET_SECTION,CONF_R_NO_CONF);
+		return NULL;
+		}
+
+	if (section == NULL)
+		{
+		CONFerr(CONF_F_NCONF_GET_SECTION,CONF_R_NO_SECTION);
+		return NULL;
+		}
+
+	return _CONF_get_section_values(conf, section);
+	}
+
+char *NCONF_get_string(const CONF *conf,const char *group,const char *name)
+	{
+	char *s = _CONF_get_string(conf, group, name);
+
+        /* Since we may get a value from an environment variable even
+           if conf is NULL, let's check the value first */
+        if (s) return s;
+
+	if (conf == NULL)
+		{
+		CONFerr(CONF_F_NCONF_GET_STRING,
+                        CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE);
+		return NULL;
+		}
+	CONFerr(CONF_F_NCONF_GET_STRING,
+		CONF_R_NO_VALUE);
+	ERR_add_error_data(4,"group=",group," name=",name);
+	return NULL;
+	}
+
+int NCONF_get_number_e(const CONF *conf,const char *group,const char *name,
+		       long *result)
+	{
+	char *str;
+
+	if (result == NULL)
+		{
+		CONFerr(CONF_F_NCONF_GET_NUMBER_E,ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+
+	str = NCONF_get_string(conf,group,name);
+
+	if (str == NULL)
+		return 0;
+
+	for (*result = 0;conf->meth->is_number(conf, *str);)
+		{
+		*result = (*result)*10 + conf->meth->to_int(conf, *str);
+		str++;
+		}
+
+	return 1;
+	}
+
+#ifndef OPENSSL_NO_FP_API
+int NCONF_dump_fp(const CONF *conf, FILE *out)
+	{
+	BIO *btmp;
+	int ret;
+	if(!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) {
+		CONFerr(CONF_F_NCONF_DUMP_FP,ERR_R_BUF_LIB);
+		return 0;
+	}
+	ret = NCONF_dump_bio(conf, btmp);
+	BIO_free(btmp);
+	return ret;
+	}
+#endif
+
+int NCONF_dump_bio(const CONF *conf, BIO *out)
+	{
+	if (conf == NULL)
+		{
+		CONFerr(CONF_F_NCONF_DUMP_BIO,CONF_R_NO_CONF);
+		return 0;
+		}
+
+	return conf->meth->dump(conf, out);
+	}
+
+
+/* This function should be avoided */
+#if 0
+long NCONF_get_number(CONF *conf,char *group,char *name)
+	{
+	int status;
+	long ret=0;
+
+	status = NCONF_get_number_e(conf, group, name, &ret);
+	if (status == 0)
+		{
+		/* This function does not believe in errors... */
+		ERR_get_error();
+		}
+	return ret;
+	}
+#endif
diff --git a/openssl/crypto/conf/conf_mall.c b/openssl/crypto/conf/conf_mall.c
new file mode 100644
index 0000000..c6f4cb2
--- /dev/null
+++ b/openssl/crypto/conf/conf_mall.c
@@ -0,0 +1,80 @@
+/* conf_mall.c */
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/dso.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+/* Load all OpenSSL builtin modules */
+
+void OPENSSL_load_builtin_modules(void)
+	{
+	/* Add builtin modules here */
+	ASN1_add_oid_module();
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE_add_conf_module();
+#endif
+	}
+
diff --git a/openssl/crypto/conf/conf_mod.c b/openssl/crypto/conf/conf_mod.c
new file mode 100644
index 0000000..df1642a
--- /dev/null
+++ b/openssl/crypto/conf/conf_mod.c
@@ -0,0 +1,623 @@
+/* conf_mod.c */
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/dso.h>
+#include <openssl/x509.h>
+
+
+#define DSO_mod_init_name "OPENSSL_init"
+#define DSO_mod_finish_name "OPENSSL_finish"
+
+
+/* This structure contains a data about supported modules.
+ * entries in this table correspond to either dynamic or
+ * static modules.
+ */
+
+struct conf_module_st
+	{
+	/* DSO of this module or NULL if static */
+	DSO *dso;
+	/* Name of the module */
+	char *name;
+	/* Init function */
+	conf_init_func *init; 
+	/* Finish function */
+	conf_finish_func *finish;
+	/* Number of successfully initialized modules */
+	int links;
+	void *usr_data;
+	};
+
+
+/* This structure contains information about modules that have been
+ * successfully initialized. There may be more than one entry for a
+ * given module.
+ */
+
+struct conf_imodule_st
+	{
+	CONF_MODULE *pmod;
+	char *name;
+	char *value;
+	unsigned long flags;
+	void *usr_data;
+	};
+
+static STACK_OF(CONF_MODULE) *supported_modules = NULL;
+static STACK_OF(CONF_IMODULE) *initialized_modules = NULL;
+
+static void module_free(CONF_MODULE *md);
+static void module_finish(CONF_IMODULE *imod);
+static int module_run(const CONF *cnf, char *name, char *value,
+					  unsigned long flags);
+static CONF_MODULE *module_add(DSO *dso, const char *name,
+			conf_init_func *ifunc, conf_finish_func *ffunc);
+static CONF_MODULE *module_find(char *name);
+static int module_init(CONF_MODULE *pmod, char *name, char *value,
+					   const CONF *cnf);
+static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,
+									unsigned long flags);
+
+/* Main function: load modules from a CONF structure */
+
+int CONF_modules_load(const CONF *cnf, const char *appname,
+		      unsigned long flags)
+	{
+	STACK_OF(CONF_VALUE) *values;
+	CONF_VALUE *vl;
+	char *vsection = NULL;
+
+	int ret, i;
+
+	if (!cnf)
+		return 1;
+
+	if (appname)
+		vsection = NCONF_get_string(cnf, NULL, appname);
+
+	if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION)))
+		vsection = NCONF_get_string(cnf, NULL, "openssl_conf");
+
+	if (!vsection)
+		{
+		ERR_clear_error();
+		return 1;
+		}
+
+	values = NCONF_get_section(cnf, vsection);
+
+	if (!values)
+		return 0;
+
+	for (i = 0; i < sk_CONF_VALUE_num(values); i++)
+		{
+		vl = sk_CONF_VALUE_value(values, i);
+		ret = module_run(cnf, vl->name, vl->value, flags);
+		if (ret <= 0)
+			if(!(flags & CONF_MFLAGS_IGNORE_ERRORS))
+				return ret;
+		}
+
+	return 1;
+
+	}
+
+int CONF_modules_load_file(const char *filename, const char *appname,
+			   unsigned long flags)
+	{
+	char *file = NULL;
+	CONF *conf = NULL;
+	int ret = 0;
+	conf = NCONF_new(NULL);
+	if (!conf)
+		goto err;
+
+	if (filename == NULL)
+		{
+		file = CONF_get1_default_config_file();
+		if (!file)
+			goto err;
+		}
+	else
+		file = (char *)filename;
+
+	if (NCONF_load(conf, file, NULL) <= 0)
+		{
+		if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) &&
+		  (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE))
+			{
+			ERR_clear_error();
+			ret = 1;
+			}
+		goto err;
+		}
+
+	ret = CONF_modules_load(conf, appname, flags);
+
+	err:
+	if (filename == NULL)
+		OPENSSL_free(file);
+	NCONF_free(conf);
+
+	return ret;
+	}
+
+static int module_run(const CONF *cnf, char *name, char *value,
+		      unsigned long flags)
+	{
+	CONF_MODULE *md;
+	int ret;
+
+	md = module_find(name);
+
+	/* Module not found: try to load DSO */
+	if (!md && !(flags & CONF_MFLAGS_NO_DSO))
+		md = module_load_dso(cnf, name, value, flags);
+
+	if (!md)
+		{
+		if (!(flags & CONF_MFLAGS_SILENT))
+			{
+			CONFerr(CONF_F_MODULE_RUN, CONF_R_UNKNOWN_MODULE_NAME);
+			ERR_add_error_data(2, "module=", name);
+			}
+		return -1;
+		}
+
+	ret = module_init(md, name, value, cnf);
+
+	if (ret <= 0)
+		{
+		if (!(flags & CONF_MFLAGS_SILENT))
+			{
+			char rcode[DECIMAL_SIZE(ret)+1];
+			CONFerr(CONF_F_MODULE_RUN, CONF_R_MODULE_INITIALIZATION_ERROR);
+			BIO_snprintf(rcode, sizeof rcode, "%-8d", ret);
+			ERR_add_error_data(6, "module=", name, ", value=", value, ", retcode=", rcode);
+			}
+		}
+
+	return ret;
+	}
+
+/* Load a module from a DSO */
+static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,
+				    unsigned long flags)
+	{
+	DSO *dso = NULL;
+	conf_init_func *ifunc;
+	conf_finish_func *ffunc;
+	char *path = NULL;
+	int errcode = 0;
+	CONF_MODULE *md;
+	/* Look for alternative path in module section */
+	path = NCONF_get_string(cnf, value, "path");
+	if (!path)
+		{
+		ERR_clear_error();
+		path = name;
+		}
+	dso = DSO_load(NULL, path, NULL, 0);
+	if (!dso)
+		{
+		errcode = CONF_R_ERROR_LOADING_DSO;
+		goto err;
+		}
+        ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name);
+	if (!ifunc)
+		{
+		errcode = CONF_R_MISSING_INIT_FUNCTION;
+		goto err;
+		}
+        ffunc = (conf_finish_func *)DSO_bind_func(dso, DSO_mod_finish_name);
+	/* All OK, add module */
+	md = module_add(dso, name, ifunc, ffunc);
+
+	if (!md)
+		goto err;
+
+	return md;
+
+	err:
+	if (dso)
+		DSO_free(dso);
+	CONFerr(CONF_F_MODULE_LOAD_DSO, errcode);
+	ERR_add_error_data(4, "module=", name, ", path=", path);
+	return NULL;
+	}
+
+/* add module to list */
+static CONF_MODULE *module_add(DSO *dso, const char *name,
+			       conf_init_func *ifunc, conf_finish_func *ffunc)
+	{
+	CONF_MODULE *tmod = NULL;
+	if (supported_modules == NULL)
+		supported_modules = sk_CONF_MODULE_new_null();
+	if (supported_modules == NULL)
+		return NULL;
+	tmod = OPENSSL_malloc(sizeof(CONF_MODULE));
+	if (tmod == NULL)
+		return NULL;
+
+	tmod->dso = dso;
+	tmod->name = BUF_strdup(name);
+	tmod->init = ifunc;
+	tmod->finish = ffunc;
+	tmod->links = 0;
+
+	if (!sk_CONF_MODULE_push(supported_modules, tmod))
+		{
+		OPENSSL_free(tmod);
+		return NULL;
+		}
+
+	return tmod;
+	}
+
+/* Find a module from the list. We allow module names of the
+ * form modname.XXXX to just search for modname to allow the
+ * same module to be initialized more than once.
+ */
+
+static CONF_MODULE *module_find(char *name)
+	{
+	CONF_MODULE *tmod;
+	int i, nchar;
+	char *p;
+	p = strrchr(name, '.');
+
+	if (p)
+		nchar = p - name;
+	else 
+		nchar = strlen(name);
+
+	for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++)
+		{
+		tmod = sk_CONF_MODULE_value(supported_modules, i);
+		if (!strncmp(tmod->name, name, nchar))
+			return tmod;
+		}
+
+	return NULL;
+
+	}
+
+/* initialize a module */
+static int module_init(CONF_MODULE *pmod, char *name, char *value,
+		       const CONF *cnf)
+	{
+	int ret = 1;
+	int init_called = 0;
+	CONF_IMODULE *imod = NULL;
+
+	/* Otherwise add initialized module to list */
+	imod = OPENSSL_malloc(sizeof(CONF_IMODULE));
+	if (!imod)
+		goto err;
+
+	imod->pmod = pmod;
+	imod->name = BUF_strdup(name);
+	imod->value = BUF_strdup(value);
+	imod->usr_data = NULL;
+
+	if (!imod->name || !imod->value)
+		goto memerr;
+
+	/* Try to initialize module */
+	if(pmod->init)
+		{
+		ret = pmod->init(imod, cnf);
+		init_called = 1;
+		/* Error occurred, exit */
+		if (ret <= 0)
+			goto err;
+		}
+
+	if (initialized_modules == NULL)
+		{
+		initialized_modules = sk_CONF_IMODULE_new_null();
+		if (!initialized_modules)
+			{
+			CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+
+	if (!sk_CONF_IMODULE_push(initialized_modules, imod))
+		{
+		CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	pmod->links++;
+
+	return ret;
+
+	err:
+
+	/* We've started the module so we'd better finish it */
+	if (pmod->finish && init_called)
+		pmod->finish(imod);
+
+	memerr:
+	if (imod)
+		{
+		if (imod->name)
+			OPENSSL_free(imod->name);
+		if (imod->value)
+			OPENSSL_free(imod->value);
+		OPENSSL_free(imod);
+		}
+
+	return -1;
+
+	}
+
+/* Unload any dynamic modules that have a link count of zero:
+ * i.e. have no active initialized modules. If 'all' is set
+ * then all modules are unloaded including static ones.
+ */
+
+void CONF_modules_unload(int all)
+	{
+	int i;
+	CONF_MODULE *md;
+	CONF_modules_finish();
+	/* unload modules in reverse order */
+	for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--)
+		{
+		md = sk_CONF_MODULE_value(supported_modules, i);
+		/* If static or in use and 'all' not set ignore it */
+		if (((md->links > 0) || !md->dso) && !all)
+			continue;
+		/* Since we're working in reverse this is OK */
+		(void)sk_CONF_MODULE_delete(supported_modules, i);
+		module_free(md);
+		}
+	if (sk_CONF_MODULE_num(supported_modules) == 0)
+		{
+		sk_CONF_MODULE_free(supported_modules);
+		supported_modules = NULL;
+		}
+	}
+
+/* unload a single module */
+static void module_free(CONF_MODULE *md)
+	{
+	if (md->dso)
+		DSO_free(md->dso);
+	OPENSSL_free(md->name);
+	OPENSSL_free(md);
+	}
+
+/* finish and free up all modules instances */
+
+void CONF_modules_finish(void)
+	{
+	CONF_IMODULE *imod;
+	while (sk_CONF_IMODULE_num(initialized_modules) > 0)
+		{
+		imod = sk_CONF_IMODULE_pop(initialized_modules);
+		module_finish(imod);
+		}
+	sk_CONF_IMODULE_free(initialized_modules);
+	initialized_modules = NULL;
+	}
+
+/* finish a module instance */
+
+static void module_finish(CONF_IMODULE *imod)
+	{
+	if (imod->pmod->finish)
+		imod->pmod->finish(imod);
+	imod->pmod->links--;
+	OPENSSL_free(imod->name);
+	OPENSSL_free(imod->value);
+	OPENSSL_free(imod);
+	}
+
+/* Add a static module to OpenSSL */
+
+int CONF_module_add(const char *name, conf_init_func *ifunc, 
+		    conf_finish_func *ffunc)
+	{
+	if (module_add(NULL, name, ifunc, ffunc))
+		return 1;
+	else
+		return 0;
+	}
+
+void CONF_modules_free(void)
+	{
+	CONF_modules_finish();
+	CONF_modules_unload(1);
+	}
+
+/* Utility functions */
+
+const char *CONF_imodule_get_name(const CONF_IMODULE *md)
+	{
+	return md->name;
+	}
+
+const char *CONF_imodule_get_value(const CONF_IMODULE *md)
+	{
+	return md->value;
+	}
+
+void *CONF_imodule_get_usr_data(const CONF_IMODULE *md)
+	{
+	return md->usr_data;
+	}
+
+void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data)
+	{
+	md->usr_data = usr_data;
+	}
+
+CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md)
+	{
+	return md->pmod;
+	}
+
+unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md)
+	{
+	return md->flags;
+	}
+
+void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags)
+	{
+	md->flags = flags;
+	}
+
+void *CONF_module_get_usr_data(CONF_MODULE *pmod)
+	{
+	return pmod->usr_data;
+	}
+
+void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data)
+	{
+	pmod->usr_data = usr_data;
+	}
+
+/* Return default config file name */
+
+char *CONF_get1_default_config_file(void)
+	{
+	char *file;
+	int len;
+
+	file = getenv("OPENSSL_CONF");
+	if (file) 
+		return BUF_strdup(file);
+
+	len = strlen(X509_get_default_cert_area());
+#ifndef OPENSSL_SYS_VMS
+	len++;
+#endif
+	len += strlen(OPENSSL_CONF);
+
+	file = OPENSSL_malloc(len + 1);
+
+	if (!file)
+		return NULL;
+	BUF_strlcpy(file,X509_get_default_cert_area(),len + 1);
+#ifndef OPENSSL_SYS_VMS
+	BUF_strlcat(file,"/",len + 1);
+#endif
+	BUF_strlcat(file,OPENSSL_CONF,len + 1);
+
+	return file;
+	}
+
+/* This function takes a list separated by 'sep' and calls the
+ * callback function giving the start and length of each member
+ * optionally stripping leading and trailing whitespace. This can
+ * be used to parse comma separated lists for example.
+ */
+
+int CONF_parse_list(const char *list_, int sep, int nospc,
+	int (*list_cb)(const char *elem, int len, void *usr), void *arg)
+	{
+	int ret;
+	const char *lstart, *tmpend, *p;
+
+	if(list_ == NULL)
+		{
+		CONFerr(CONF_F_CONF_PARSE_LIST, CONF_R_LIST_CANNOT_BE_NULL);
+		return 0;
+		}
+
+	lstart = list_;
+	for(;;)
+		{
+		if (nospc)
+			{
+			while(*lstart && isspace((unsigned char)*lstart))
+				lstart++;
+			}
+		p = strchr(lstart, sep);
+		if (p == lstart || !*lstart)
+			ret = list_cb(NULL, 0, arg);
+		else
+			{
+			if (p)
+				tmpend = p - 1;
+			else 
+				tmpend = lstart + strlen(lstart) - 1;
+			if (nospc)
+				{
+				while(isspace((unsigned char)*tmpend))
+					tmpend--;
+				}
+			ret = list_cb(lstart, tmpend - lstart + 1, arg);
+			}
+		if (ret <= 0)
+			return ret;
+		if (p == NULL)
+			return 1;
+		lstart = p + 1;
+		}
+	}
+
diff --git a/openssl/crypto/conf/conf_sap.c b/openssl/crypto/conf/conf_sap.c
new file mode 100644
index 0000000..760dc26
--- /dev/null
+++ b/openssl/crypto/conf/conf_sap.c
@@ -0,0 +1,111 @@
+/* conf_sap.c */
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/dso.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+/* This is the automatic configuration loader: it is called automatically by
+ * OpenSSL when any of a number of standard initialisation functions are called,
+ * unless this is overridden by calling OPENSSL_no_config()
+ */
+
+static int openssl_configured = 0;
+
+void OPENSSL_config(const char *config_name)
+	{
+	if (openssl_configured)
+		return;
+
+	OPENSSL_load_builtin_modules();
+#ifndef OPENSSL_NO_ENGINE
+	/* Need to load ENGINEs */
+	ENGINE_load_builtin_engines();
+#endif
+	/* Add others here? */
+
+
+	ERR_clear_error();
+	if (CONF_modules_load_file(NULL, config_name,
+	CONF_MFLAGS_DEFAULT_SECTION|CONF_MFLAGS_IGNORE_MISSING_FILE) <= 0)
+		{
+		BIO *bio_err;
+		ERR_load_crypto_strings();
+		if ((bio_err=BIO_new_fp(stderr, BIO_NOCLOSE)) != NULL)
+			{
+			BIO_printf(bio_err,"Auto configuration failed\n");
+			ERR_print_errors(bio_err);
+			BIO_free(bio_err);
+			}
+		exit(1);
+		}
+
+	return;
+	}
+
+void OPENSSL_no_config()
+	{
+	openssl_configured = 1;
+	}
diff --git a/openssl/crypto/conf/keysets.pl b/openssl/crypto/conf/keysets.pl
new file mode 100644
index 0000000..50ed67f
--- /dev/null
+++ b/openssl/crypto/conf/keysets.pl
@@ -0,0 +1,185 @@
+#!/usr/local/bin/perl
+
+$NUMBER=0x01;
+$UPPER=0x02;
+$LOWER=0x04;
+$UNDER=0x100;
+$PUNCTUATION=0x200;
+$WS=0x10;
+$ESC=0x20;
+$QUOTE=0x40;
+$DQUOTE=0x400;
+$COMMENT=0x80;
+$FCOMMENT=0x800;
+$EOF=0x08;
+$HIGHBIT=0x1000;
+
+foreach (0 .. 255)
+	{
+	$v=0;
+	$c=sprintf("%c",$_);
+	$v|=$NUMBER	if ($c =~ /[0-9]/);
+	$v|=$UPPER	if ($c =~ /[A-Z]/);
+	$v|=$LOWER	if ($c =~ /[a-z]/);
+	$v|=$UNDER	if ($c =~ /_/);
+	$v|=$PUNCTUATION if ($c =~ /[!\.%&\*\+,\/;\?\@\^\~\|-]/);
+	$v|=$WS		if ($c =~ /[ \t\r\n]/);
+	$v|=$ESC	if ($c =~ /\\/);
+	$v|=$QUOTE	if ($c =~ /['`"]/); # for emacs: "`'}/)
+	$v|=$COMMENT	if ($c =~ /\#/);
+	$v|=$EOF	if ($c =~ /\0/);
+	$v|=$HIGHBIT	if ($c =~/[\x80-\xff]/);
+
+	push(@V_def,$v);
+	}
+
+foreach (0 .. 255)
+	{
+	$v=0;
+	$c=sprintf("%c",$_);
+	$v|=$NUMBER	if ($c =~ /[0-9]/);
+	$v|=$UPPER	if ($c =~ /[A-Z]/);
+	$v|=$LOWER	if ($c =~ /[a-z]/);
+	$v|=$UNDER	if ($c =~ /_/);
+	$v|=$PUNCTUATION if ($c =~ /[!\.%&\*\+,\/;\?\@\^\~\|-]/);
+	$v|=$WS		if ($c =~ /[ \t\r\n]/);
+	$v|=$DQUOTE	if ($c =~ /["]/); # for emacs: "}/)
+	$v|=$FCOMMENT	if ($c =~ /;/);
+	$v|=$EOF	if ($c =~ /\0/);
+	$v|=$HIGHBIT	if ($c =~/[\x80-\xff]/);
+
+	push(@V_w32,$v);
+	}
+
+print <<"EOF";
+/* crypto/conf/conf_def.h */
+/* Copyright (C) 1995-1998 Eric Young (eay\@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay\@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh\@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay\@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh\@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* THIS FILE WAS AUTOMAGICALLY GENERATED!
+   Please modify and use keysets.pl to regenerate it. */
+
+#define CONF_NUMBER		$NUMBER
+#define CONF_UPPER		$UPPER
+#define CONF_LOWER		$LOWER
+#define CONF_UNDER		$UNDER
+#define CONF_PUNCTUATION	$PUNCTUATION
+#define CONF_WS			$WS
+#define CONF_ESC		$ESC
+#define CONF_QUOTE		$QUOTE
+#define CONF_DQUOTE		$DQUOTE
+#define CONF_COMMENT		$COMMENT
+#define CONF_FCOMMENT		$FCOMMENT
+#define CONF_EOF		$EOF
+#define CONF_HIGHBIT		$HIGHBIT
+#define CONF_ALPHA		(CONF_UPPER|CONF_LOWER)
+#define CONF_ALPHA_NUMERIC	(CONF_ALPHA|CONF_NUMBER|CONF_UNDER)
+#define CONF_ALPHA_NUMERIC_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER| \\
+					CONF_PUNCTUATION)
+
+#define KEYTYPES(c)		((unsigned short *)((c)->meth_data))
+#ifndef CHARSET_EBCDIC
+#define IS_COMMENT(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_COMMENT)
+#define IS_FCOMMENT(c,a)	(KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT)
+#define IS_EOF(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_EOF)
+#define IS_ESC(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_ESC)
+#define IS_NUMBER(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_NUMBER)
+#define IS_WS(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_WS)
+#define IS_ALPHA_NUMERIC(c,a)	(KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC)
+#define IS_ALPHA_NUMERIC_PUNCT(c,a) \\
+				(KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT)
+#define IS_QUOTE(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_QUOTE)
+#define IS_DQUOTE(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE)
+#define IS_HIGHBIT(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT)
+
+#else /*CHARSET_EBCDIC*/
+
+#define IS_COMMENT(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_COMMENT)
+#define IS_FCOMMENT(c,a)	(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_FCOMMENT)
+#define IS_EOF(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_EOF)
+#define IS_ESC(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ESC)
+#define IS_NUMBER(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_NUMBER)
+#define IS_WS(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_WS)
+#define IS_ALPHA_NUMERIC(c,a)	(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC)
+#define IS_ALPHA_NUMERIC_PUNCT(c,a) \\
+				(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC_PUNCT)
+#define IS_QUOTE(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_QUOTE)
+#define IS_DQUOTE(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_DQUOTE)
+#define IS_HIGHBIT(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_HIGHBIT)
+#endif /*CHARSET_EBCDIC*/
+
+EOF
+
+print "static unsigned short CONF_type_default[256]={";
+
+for ($i=0; $i<256; $i++)
+	{
+	print "\n\t" if ($i % 8) == 0;
+	printf "0x%04X,",$V_def[$i];
+	}
+
+print "\n\t};\n\n";
+
+print "static unsigned short CONF_type_win32[256]={";
+
+for ($i=0; $i<256; $i++)
+	{
+	print "\n\t" if ($i % 8) == 0;
+	printf "0x%04X,",$V_w32[$i];
+	}
+
+print "\n\t};\n\n";
diff --git a/openssl/crypto/conf/ssleay.cnf b/openssl/crypto/conf/ssleay.cnf
new file mode 100644
index 0000000..ed33af6
--- /dev/null
+++ b/openssl/crypto/conf/ssleay.cnf
@@ -0,0 +1,78 @@
+#
+# This is a test configuration file for use in SSLeay etc...
+#
+
+init = 5
+in\#it1 =10
+init2='10'
+init3='10\''
+init4="10'"
+init5='='10\'' again'
+
+SSLeay::version = 0.5.0
+
+[genrsa]
+default_bits	= 512
+SSLEAY::version = 0.5.0
+
+[gendh]
+default_bits	= 512
+def_generator	= 2
+
+[s_client]
+cipher1		= DES_CBC_MD5:DES_CBC_SHA:DES_EDE_SHA:RC4_MD5\
+cipher2		= 'DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5'
+cipher3		= "DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5"
+cipher4		= DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5
+
+[ default ]
+cert_dir	= $ENV::HOME/.ca_certs
+
+HOME		= /tmp/eay
+
+tmp_cert_dir	= $HOME/.ca_certs
+tmp2_cert_dir	= thisis$(HOME)stuff
+
+LOGNAME	= Eric Young (home=$HOME)
+
+[ special ]
+
+H=$HOME
+H=$default::HOME
+H=$ENV::HOME
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+RANDFILE		= $HOME/.rand
+
+[ req ]
+default_bits		= 512
+default_keyfile 	= privkey.pem
+
+Attribute_type_1	= countryName
+Attribute_text_1	= Country Name (2 letter code)
+Attribute_default_1	= AU
+
+Attribute_type_2	= stateOrProvinceName
+Attribute_text_2	= State or Province Name (full name)
+Attribute_default_2	= Queensland
+
+Attribute_type_3	= localityName
+Attribute_text_3	= Locality Name (eg, city)
+
+Attribute_type_4	= organizationName
+Attribute_text_4	= Organization Name (eg, company)
+Attribute_default_4	= Mincom Pty Ltd
+
+Attribute_type_5	= organizationalUnitName
+Attribute_text_5	= Organizational Unit Name (eg, section)
+Attribute_default_5	= TR
+
+Attribute_type_6	= commonName
+Attribute_text_6	= Common Name (eg, YOUR name)
+
+Attribute_type_7	= emailAddress
+Attribute_text_7	= Email Address
+
diff --git a/openssl/crypto/conf/test.c b/openssl/crypto/conf/test.c
new file mode 100644
index 0000000..7fab850
--- /dev/null
+++ b/openssl/crypto/conf/test.c
@@ -0,0 +1,98 @@
+/* crypto/conf/test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/conf.h>
+#include <openssl/err.h>
+
+main()
+	{
+	LHASH *conf;
+	long eline;
+	char *s,*s2;
+
+#ifdef USE_WIN32
+	CONF_set_default_method(CONF_WIN32);
+#endif
+	conf=CONF_load(NULL,"ssleay.cnf",&eline);
+	if (conf == NULL)
+		{
+		ERR_load_crypto_strings();
+		printf("unable to load configuration, line %ld\n",eline);
+		ERR_print_errors_fp(stderr);
+		exit(1);
+		}
+	lh_stats(conf,stdout);
+	lh_node_stats(conf,stdout);
+	lh_node_usage_stats(conf,stdout);
+
+	s=CONF_get_string(conf,NULL,"init2");
+	printf("init2=%s\n",(s == NULL)?"NULL":s);
+
+	s=CONF_get_string(conf,NULL,"cipher1");
+	printf("cipher1=%s\n",(s == NULL)?"NULL":s);
+
+	s=CONF_get_string(conf,"s_client","cipher1");
+	printf("s_client:cipher1=%s\n",(s == NULL)?"NULL":s);
+
+	printf("---------------------------- DUMP ------------------------\n");
+	CONF_dump_fp(conf, stdout);
+
+	exit(0);
+	}
diff --git a/openssl/crypto/cpt_err.c b/openssl/crypto/cpt_err.c
new file mode 100644
index 0000000..139b928
--- /dev/null
+++ b/openssl/crypto/cpt_err.c
@@ -0,0 +1,103 @@
+/* crypto/cpt_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/crypto.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_CRYPTO,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_CRYPTO,0,reason)
+
+static ERR_STRING_DATA CRYPTO_str_functs[]=
+	{
+{ERR_FUNC(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX),	"CRYPTO_get_ex_new_index"},
+{ERR_FUNC(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID),	"CRYPTO_get_new_dynlockid"},
+{ERR_FUNC(CRYPTO_F_CRYPTO_GET_NEW_LOCKID),	"CRYPTO_get_new_lockid"},
+{ERR_FUNC(CRYPTO_F_CRYPTO_SET_EX_DATA),	"CRYPTO_set_ex_data"},
+{ERR_FUNC(CRYPTO_F_DEF_ADD_INDEX),	"DEF_ADD_INDEX"},
+{ERR_FUNC(CRYPTO_F_DEF_GET_CLASS),	"DEF_GET_CLASS"},
+{ERR_FUNC(CRYPTO_F_INT_DUP_EX_DATA),	"INT_DUP_EX_DATA"},
+{ERR_FUNC(CRYPTO_F_INT_FREE_EX_DATA),	"INT_FREE_EX_DATA"},
+{ERR_FUNC(CRYPTO_F_INT_NEW_EX_DATA),	"INT_NEW_EX_DATA"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA CRYPTO_str_reasons[]=
+	{
+{ERR_REASON(CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK),"no dynlock create callback"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_CRYPTO_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(CRYPTO_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,CRYPTO_str_functs);
+		ERR_load_strings(0,CRYPTO_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/cryptlib.c b/openssl/crypto/cryptlib.c
new file mode 100644
index 0000000..5dfeec7
--- /dev/null
+++ b/openssl/crypto/cryptlib.c
@@ -0,0 +1,898 @@
+/* crypto/cryptlib.c */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include "cryptlib.h"
+#include <openssl/safestack.h>
+
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
+static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */
+#endif
+
+DECLARE_STACK_OF(CRYPTO_dynlock)
+
+/* real #defines in crypto.h, keep these upto date */
+static const char* const lock_names[CRYPTO_NUM_LOCKS] =
+	{
+	"<<ERROR>>",
+	"err",
+	"ex_data",
+	"x509",
+	"x509_info",
+	"x509_pkey",
+	"x509_crl",
+	"x509_req",
+	"dsa",
+	"rsa",
+	"evp_pkey",
+	"x509_store",
+	"ssl_ctx",
+	"ssl_cert",
+	"ssl_session",
+	"ssl_sess_cert",
+	"ssl",
+	"ssl_method",
+	"rand",
+	"rand2",
+	"debug_malloc",
+	"BIO",
+	"gethostbyname",
+	"getservbyname",
+	"readdir",
+	"RSA_blinding",
+	"dh",
+	"debug_malloc2",
+	"dso",
+	"dynlock",
+	"engine",
+	"ui",
+	"ecdsa",
+	"ec",
+	"ecdh",
+	"bn",
+	"ec_pre_comp",
+	"store",
+	"comp",
+	"fips",
+	"fips2",
+#if CRYPTO_NUM_LOCKS != 41
+# error "Inconsistency between crypto.h and cryptlib.c"
+#endif
+	};
+
+/* This is for applications to allocate new type names in the non-dynamic
+   array of lock names.  These are numbered with positive numbers.  */
+static STACK_OF(OPENSSL_STRING) *app_locks=NULL;
+
+/* For applications that want a more dynamic way of handling threads, the
+   following stack is used.  These are externally numbered with negative
+   numbers.  */
+static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL;
+
+
+static void (MS_FAR *locking_callback)(int mode,int type,
+	const char *file,int line)=0;
+static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
+	int type,const char *file,int line)=0;
+#ifndef OPENSSL_NO_DEPRECATED
+static unsigned long (MS_FAR *id_callback)(void)=0;
+#endif
+static void (MS_FAR *threadid_callback)(CRYPTO_THREADID *)=0;
+static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
+	(const char *file,int line)=0;
+static void (MS_FAR *dynlock_lock_callback)(int mode,
+	struct CRYPTO_dynlock_value *l, const char *file,int line)=0;
+static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
+	const char *file,int line)=0;
+
+int CRYPTO_get_new_lockid(char *name)
+	{
+	char *str;
+	int i;
+
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
+	/* A hack to make Visual C++ 5.0 work correctly when linking as
+	 * a DLL using /MT. Without this, the application cannot use
+	 * any floating point printf's.
+	 * It also seems to be needed for Visual C 1.5 (win16) */
+	SSLeay_MSVC5_hack=(double)name[0]*(double)name[1];
+#endif
+
+	if ((app_locks == NULL) && ((app_locks=sk_OPENSSL_STRING_new_null()) == NULL))
+		{
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	if ((str=BUF_strdup(name)) == NULL)
+		{
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	i=sk_OPENSSL_STRING_push(app_locks,str);
+	if (!i)
+		OPENSSL_free(str);
+	else
+		i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */
+	return(i);
+	}
+
+int CRYPTO_num_locks(void)
+	{
+	return CRYPTO_NUM_LOCKS;
+	}
+
+int CRYPTO_get_new_dynlockid(void)
+	{
+	int i = 0;
+	CRYPTO_dynlock *pointer = NULL;
+
+	if (dynlock_create_callback == NULL)
+		{
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
+		return(0);
+		}
+	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
+	if ((dyn_locks == NULL)
+		&& ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL))
+		{
+		CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+
+	pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock));
+	if (pointer == NULL)
+		{
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	pointer->references = 1;
+	pointer->data = dynlock_create_callback(__FILE__,__LINE__);
+	if (pointer->data == NULL)
+		{
+		OPENSSL_free(pointer);
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+
+	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
+	/* First, try to find an existing empty slot */
+	i=sk_CRYPTO_dynlock_find(dyn_locks,NULL);
+	/* If there was none, push, thereby creating a new one */
+	if (i == -1)
+		/* Since sk_push() returns the number of items on the
+		   stack, not the location of the pushed item, we need
+		   to transform the returned number into a position,
+		   by decreasing it.  */
+		i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1;
+	else
+		/* If we found a place with a NULL pointer, put our pointer
+		   in it.  */
+		(void)sk_CRYPTO_dynlock_set(dyn_locks,i,pointer);
+	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+
+	if (i == -1)
+		{
+		dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
+		OPENSSL_free(pointer);
+		}
+	else
+		i += 1; /* to avoid 0 */
+	return -i;
+	}
+
+void CRYPTO_destroy_dynlockid(int i)
+	{
+	CRYPTO_dynlock *pointer = NULL;
+	if (i)
+		i = -i-1;
+	if (dynlock_destroy_callback == NULL)
+		return;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
+
+	if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks))
+		{
+		CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+		return;
+		}
+	pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
+	if (pointer != NULL)
+		{
+		--pointer->references;
+#ifdef REF_CHECK
+		if (pointer->references < 0)
+			{
+			fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n");
+			abort();
+			}
+		else
+#endif
+			if (pointer->references <= 0)
+				{
+				(void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
+				}
+			else
+				pointer = NULL;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+
+	if (pointer)
+		{
+		dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
+		OPENSSL_free(pointer);
+		}
+	}
+
+struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
+	{
+	CRYPTO_dynlock *pointer = NULL;
+	if (i)
+		i = -i-1;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
+
+	if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
+		pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
+	if (pointer)
+		pointer->references++;
+
+	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+
+	if (pointer)
+		return pointer->data;
+	return NULL;
+	}
+
+struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))
+	(const char *file,int line)
+	{
+	return(dynlock_create_callback);
+	}
+
+void (*CRYPTO_get_dynlock_lock_callback(void))(int mode,
+	struct CRYPTO_dynlock_value *l, const char *file,int line)
+	{
+	return(dynlock_lock_callback);
+	}
+
+void (*CRYPTO_get_dynlock_destroy_callback(void))
+	(struct CRYPTO_dynlock_value *l, const char *file,int line)
+	{
+	return(dynlock_destroy_callback);
+	}
+
+void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
+	(const char *file, int line))
+	{
+	dynlock_create_callback=func;
+	}
+
+void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode,
+	struct CRYPTO_dynlock_value *l, const char *file, int line))
+	{
+	dynlock_lock_callback=func;
+	}
+
+void CRYPTO_set_dynlock_destroy_callback(void (*func)
+	(struct CRYPTO_dynlock_value *l, const char *file, int line))
+	{
+	dynlock_destroy_callback=func;
+	}
+
+
+void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
+		int line)
+	{
+	return(locking_callback);
+	}
+
+int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
+					  const char *file,int line)
+	{
+	return(add_lock_callback);
+	}
+
+void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
+					      const char *file,int line))
+	{
+	locking_callback=func;
+	}
+
+void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
+					      const char *file,int line))
+	{
+	add_lock_callback=func;
+	}
+
+/* the memset() here and in set_pointer() seem overkill, but for the sake of
+ * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause two
+ * "equal" THREADID structs to not be memcmp()-identical. */
+void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val)
+	{
+	memset(id, 0, sizeof(*id));
+	id->val = val;
+	}
+
+static const unsigned char hash_coeffs[] = { 3, 5, 7, 11, 13, 17, 19, 23 };
+void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr)
+	{
+	unsigned char *dest = (void *)&id->val;
+	unsigned int accum = 0;
+	unsigned char dnum = sizeof(id->val);
+
+	memset(id, 0, sizeof(*id));
+	id->ptr = ptr;
+	if (sizeof(id->val) >= sizeof(id->ptr))
+		{
+		/* 'ptr' can be embedded in 'val' without loss of uniqueness */
+		id->val = (unsigned long)id->ptr;
+		return;
+		}
+	/* hash ptr ==> val. Each byte of 'val' gets the mod-256 total of a
+	 * linear function over the bytes in 'ptr', the co-efficients of which
+	 * are a sequence of low-primes (hash_coeffs is an 8-element cycle) -
+	 * the starting prime for the sequence varies for each byte of 'val'
+	 * (unique polynomials unless pointers are >64-bit). For added spice,
+	 * the totals accumulate rather than restarting from zero, and the index
+	 * of the 'val' byte is added each time (position dependence). If I was
+	 * a black-belt, I'd scan big-endian pointers in reverse to give
+	 * low-order bits more play, but this isn't crypto and I'd prefer nobody
+	 * mistake it as such. Plus I'm lazy. */
+	while (dnum--)
+		{
+		const unsigned char *src = (void *)&id->ptr;
+		unsigned char snum = sizeof(id->ptr);
+		while (snum--)
+			accum += *(src++) * hash_coeffs[(snum + dnum) & 7];
+		accum += dnum;
+		*(dest++) = accum & 255;
+		}
+	}
+
+int CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *))
+	{
+	if (threadid_callback)
+		return 0;
+	threadid_callback = func;
+	return 1;
+	}
+
+void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *)
+	{
+	return threadid_callback;
+	}
+
+void CRYPTO_THREADID_current(CRYPTO_THREADID *id)
+	{
+	if (threadid_callback)
+		{
+		threadid_callback(id);
+		return;
+		}
+#ifndef OPENSSL_NO_DEPRECATED
+	/* If the deprecated callback was set, fall back to that */
+	if (id_callback)
+		{
+		CRYPTO_THREADID_set_numeric(id, id_callback());
+		return;
+		}
+#endif
+	/* Else pick a backup */
+#ifdef OPENSSL_SYS_WIN16
+	CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentTask());
+#elif defined(OPENSSL_SYS_WIN32)
+	CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentThreadId());
+#elif defined(OPENSSL_SYS_BEOS)
+	CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL));
+#else
+	/* For everything else, default to using the address of 'errno' */
+	CRYPTO_THREADID_set_pointer(id, (void*)&errno);
+#endif
+	}
+
+int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b)
+	{
+	return memcmp(a, b, sizeof(*a));
+	}
+
+void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src)
+	{
+	memcpy(dest, src, sizeof(*src));
+	}
+
+unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
+	{
+	return id->val;
+	}
+
+#ifndef OPENSSL_NO_DEPRECATED
+unsigned long (*CRYPTO_get_id_callback(void))(void)
+	{
+	return(id_callback);
+	}
+
+void CRYPTO_set_id_callback(unsigned long (*func)(void))
+	{
+	id_callback=func;
+	}
+
+unsigned long CRYPTO_thread_id(void)
+	{
+	unsigned long ret=0;
+
+	if (id_callback == NULL)
+		{
+#ifdef OPENSSL_SYS_WIN16
+		ret=(unsigned long)GetCurrentTask();
+#elif defined(OPENSSL_SYS_WIN32)
+		ret=(unsigned long)GetCurrentThreadId();
+#elif defined(GETPID_IS_MEANINGLESS)
+		ret=1L;
+#elif defined(OPENSSL_SYS_BEOS)
+		ret=(unsigned long)find_thread(NULL);
+#else
+		ret=(unsigned long)getpid();
+#endif
+		}
+	else
+		ret=id_callback();
+	return(ret);
+	}
+#endif
+
+void CRYPTO_lock(int mode, int type, const char *file, int line)
+	{
+#ifdef LOCK_DEBUG
+		{
+		CRYPTO_THREADID id;
+		char *rw_text,*operation_text;
+
+		if (mode & CRYPTO_LOCK)
+			operation_text="lock  ";
+		else if (mode & CRYPTO_UNLOCK)
+			operation_text="unlock";
+		else
+			operation_text="ERROR ";
+
+		if (mode & CRYPTO_READ)
+			rw_text="r";
+		else if (mode & CRYPTO_WRITE)
+			rw_text="w";
+		else
+			rw_text="ERROR";
+
+		CRYPTO_THREADID_current(&id);
+		fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n",
+			CRYPTO_THREADID_hash(&id), rw_text, operation_text,
+			CRYPTO_get_lock_name(type), file, line);
+		}
+#endif
+	if (type < 0)
+		{
+		if (dynlock_lock_callback != NULL)
+			{
+			struct CRYPTO_dynlock_value *pointer
+				= CRYPTO_get_dynlock_value(type);
+
+			OPENSSL_assert(pointer != NULL);
+
+			dynlock_lock_callback(mode, pointer, file, line);
+
+			CRYPTO_destroy_dynlockid(type);
+			}
+		}
+	else
+		if (locking_callback != NULL)
+			locking_callback(mode,type,file,line);
+	}
+
+int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
+	     int line)
+	{
+	int ret = 0;
+
+	if (add_lock_callback != NULL)
+		{
+#ifdef LOCK_DEBUG
+		int before= *pointer;
+#endif
+
+		ret=add_lock_callback(pointer,amount,type,file,line);
+#ifdef LOCK_DEBUG
+		{
+		CRYPTO_THREADID id;
+		CRYPTO_THREADID_current(&id);
+		fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
+			CRYPTO_THREADID_hash(&id), before,amount,ret,
+			CRYPTO_get_lock_name(type),
+			file,line);
+		}
+#endif
+		}
+	else
+		{
+		CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,file,line);
+
+		ret= *pointer+amount;
+#ifdef LOCK_DEBUG
+		{
+		CRYPTO_THREADID id;
+		CRYPTO_THREADID_current(&id);
+		fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
+			CRYPTO_THREADID_hash(&id),
+			*pointer,amount,ret,
+			CRYPTO_get_lock_name(type),
+			file,line);
+		}
+#endif
+		*pointer=ret;
+		CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line);
+		}
+	return(ret);
+	}
+
+const char *CRYPTO_get_lock_name(int type)
+	{
+	if (type < 0)
+		return("dynamic");
+	else if (type < CRYPTO_NUM_LOCKS)
+		return(lock_names[type]);
+	else if (type-CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks))
+		return("ERROR");
+	else
+		return(sk_OPENSSL_STRING_value(app_locks,type-CRYPTO_NUM_LOCKS));
+	}
+
+#if	defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
+	defined(__INTEL__) || \
+	defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
+
+unsigned long  OPENSSL_ia32cap_P=0;
+unsigned long *OPENSSL_ia32cap_loc(void) { return &OPENSSL_ia32cap_P; }
+
+#if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
+#define OPENSSL_CPUID_SETUP
+void OPENSSL_cpuid_setup(void)
+{ static int trigger=0;
+  unsigned long OPENSSL_ia32_cpuid(void);
+  char *env;
+
+    if (trigger)	return;
+
+    trigger=1;
+    if ((env=getenv("OPENSSL_ia32cap")))
+	OPENSSL_ia32cap_P = strtoul(env,NULL,0)|(1<<10);
+    else
+	OPENSSL_ia32cap_P = OPENSSL_ia32_cpuid()|(1<<10);
+    /*
+     * |(1<<10) sets a reserved bit to signal that variable
+     * was initialized already... This is to avoid interference
+     * with cpuid snippets in ELF .init segment.
+     */
+}
+#endif
+
+#else
+unsigned long *OPENSSL_ia32cap_loc(void) { return NULL; }
+#endif
+int OPENSSL_NONPIC_relocated = 0;
+#if !defined(OPENSSL_CPUID_SETUP)
+void OPENSSL_cpuid_setup(void) {}
+#endif
+
+#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL)
+#ifdef __CYGWIN__
+/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
+#include <windows.h>
+/* this has side-effect of _WIN32 getting defined, which otherwise
+ * is mutually exclusive with __CYGWIN__... */
+#endif
+
+/* All we really need to do is remove the 'error' state when a thread
+ * detaches */
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
+	     LPVOID lpvReserved)
+	{
+	switch(fdwReason)
+		{
+	case DLL_PROCESS_ATTACH:
+		OPENSSL_cpuid_setup();
+#if defined(_WIN32_WINNT)
+		{
+		IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *)hinstDLL;
+		IMAGE_NT_HEADERS *nt_headers;
+
+		if (dos_header->e_magic==IMAGE_DOS_SIGNATURE)
+			{
+			nt_headers = (IMAGE_NT_HEADERS *)((char *)dos_header
+						+ dos_header->e_lfanew);
+			if (nt_headers->Signature==IMAGE_NT_SIGNATURE &&
+			    hinstDLL!=(HINSTANCE)(nt_headers->OptionalHeader.ImageBase))
+				OPENSSL_NONPIC_relocated=1;
+			}
+		}
+#endif
+		break;
+	case DLL_THREAD_ATTACH:
+		break;
+	case DLL_THREAD_DETACH:
+		break;
+	case DLL_PROCESS_DETACH:
+		break;
+		}
+	return(TRUE);
+	}
+#endif
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include <tchar.h>
+#include <signal.h>
+#ifdef __WATCOMC__
+#if defined(_UNICODE) || defined(__UNICODE__)
+#define _vsntprintf _vsnwprintf
+#else
+#define _vsntprintf _vsnprintf
+#endif
+#endif
+#ifdef _MSC_VER
+#define alloca _alloca
+#endif
+
+#if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
+int OPENSSL_isservice(void)
+{ HWINSTA h;
+  DWORD len;
+  WCHAR *name;
+  static union { void *p; int (*f)(void); } _OPENSSL_isservice = { NULL };
+
+    if (_OPENSSL_isservice.p == NULL) {
+	HANDLE h = GetModuleHandle(NULL);
+	if (h != NULL)
+	    _OPENSSL_isservice.p = GetProcAddress(h,"_OPENSSL_isservice");
+	if (_OPENSSL_isservice.p == NULL)
+	    _OPENSSL_isservice.p = (void *)-1;
+    }
+
+    if (_OPENSSL_isservice.p != (void *)-1)
+	return (*_OPENSSL_isservice.f)();
+
+    (void)GetDesktopWindow(); /* return value is ignored */
+
+    h = GetProcessWindowStation();
+    if (h==NULL) return -1;
+
+    if (GetUserObjectInformationW (h,UOI_NAME,NULL,0,&len) ||
+	GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+	return -1;
+
+    if (len>512) return -1;		/* paranoia */
+    len++,len&=~1;			/* paranoia */
+    name=(WCHAR *)alloca(len+sizeof(WCHAR));
+    if (!GetUserObjectInformationW (h,UOI_NAME,name,len,&len))
+	return -1;
+
+    len++,len&=~1;			/* paranoia */
+    name[len/sizeof(WCHAR)]=L'\0';	/* paranoia */
+#if 1
+    /* This doesn't cover "interactive" services [working with real
+     * WinSta0's] nor programs started non-interactively by Task
+     * Scheduler [those are working with SAWinSta]. */
+    if (wcsstr(name,L"Service-0x"))	return 1;
+#else
+    /* This covers all non-interactive programs such as services. */
+    if (!wcsstr(name,L"WinSta0"))	return 1;
+#endif
+    else				return 0;
+}
+#else
+int OPENSSL_isservice(void) { return 0; }
+#endif
+
+void OPENSSL_showfatal (const char *fmta,...)
+{ va_list ap;
+  TCHAR buf[256];
+  const TCHAR *fmt;
+#ifdef STD_ERROR_HANDLE	/* what a dirty trick! */
+  HANDLE h;
+
+    if ((h=GetStdHandle(STD_ERROR_HANDLE)) != NULL &&
+	GetFileType(h)!=FILE_TYPE_UNKNOWN)
+    {	/* must be console application */
+	va_start (ap,fmta);
+	vfprintf (stderr,fmta,ap);
+	va_end (ap);
+	return;
+    }
+#endif
+
+    if (sizeof(TCHAR)==sizeof(char))
+	fmt=(const TCHAR *)fmta;
+    else do
+    { int    keepgoing;
+      size_t len_0=strlen(fmta)+1,i;
+      WCHAR *fmtw;
+
+	fmtw = (WCHAR *)alloca(len_0*sizeof(WCHAR));
+	if (fmtw == NULL) { fmt=(const TCHAR *)L"no stack?"; break; }
+
+#ifndef OPENSSL_NO_MULTIBYTE
+	if (!MultiByteToWideChar(CP_ACP,0,fmta,len_0,fmtw,len_0))
+#endif
+	    for (i=0;i<len_0;i++) fmtw[i]=(WCHAR)fmta[i];
+
+	for (i=0;i<len_0;i++)
+	{   if (fmtw[i]==L'%') do
+	    {	keepgoing=0;
+		switch (fmtw[i+1])
+		{   case L'0': case L'1': case L'2': case L'3': case L'4':
+		    case L'5': case L'6': case L'7': case L'8': case L'9':
+		    case L'.': case L'*':
+		    case L'-':	i++; keepgoing=1; break;
+		    case L's':	fmtw[i+1]=L'S';   break;
+		    case L'S':	fmtw[i+1]=L's';   break;
+		    case L'c':	fmtw[i+1]=L'C';   break;
+		    case L'C':	fmtw[i+1]=L'c';   break;
+		}
+	    } while (keepgoing);
+	}
+	fmt = (const TCHAR *)fmtw;
+    } while (0);
+
+    va_start (ap,fmta);
+    _vsntprintf (buf,sizeof(buf)/sizeof(TCHAR)-1,fmt,ap);
+    buf [sizeof(buf)/sizeof(TCHAR)-1] = _T('\0');
+    va_end (ap);
+
+#if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
+    /* this -------------v--- guards NT-specific calls */
+    if (GetVersion() < 0x80000000 && OPENSSL_isservice() > 0)
+    {	HANDLE h = RegisterEventSource(0,_T("OPENSSL"));
+	const TCHAR *pmsg=buf;
+	ReportEvent(h,EVENTLOG_ERROR_TYPE,0,0,0,1,0,&pmsg,0);
+	DeregisterEventSource(h);
+    }
+    else
+#endif
+	MessageBox (NULL,buf,_T("OpenSSL: FATAL"),MB_OK|MB_ICONSTOP);
+}
+#else
+void OPENSSL_showfatal (const char *fmta,...)
+{ va_list ap;
+
+    va_start (ap,fmta);
+    vfprintf (stderr,fmta,ap);
+    va_end (ap);
+}
+int OPENSSL_isservice (void) { return 0; }
+#endif
+
+void OpenSSLDie(const char *file,int line,const char *assertion)
+	{
+	OPENSSL_showfatal(
+		"%s(%d): OpenSSL internal error, assertion failed: %s\n",
+		file,line,assertion);
+#if !defined(_WIN32) || defined(__CYGWIN__)
+	abort();
+#else
+	/* Win32 abort() customarily shows a dialog, but we just did that... */
+	raise(SIGABRT);
+	_exit(3);
+#endif
+	}
+
+void *OPENSSL_stderr(void)	{ return stderr; }
diff --git a/openssl/crypto/cryptlib.h b/openssl/crypto/cryptlib.h
new file mode 100644
index 0000000..fc249c5
--- /dev/null
+++ b/openssl/crypto/cryptlib.h
@@ -0,0 +1,111 @@
+/* crypto/cryptlib.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_CRYPTLIB_H
+#define HEADER_CRYPTLIB_H
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "e_os.h"
+
+#ifdef OPENSSL_USE_APPLINK
+#define BIO_FLAGS_UPLINK 0x8000
+#include "ms/uplink.h"
+#endif
+
+#include <openssl/crypto.h>
+#include <openssl/buffer.h> 
+#include <openssl/bio.h> 
+#include <openssl/err.h>
+#include <openssl/opensslconf.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifndef OPENSSL_SYS_VMS
+#define X509_CERT_AREA		OPENSSLDIR
+#define X509_CERT_DIR		OPENSSLDIR "/certs"
+#define X509_CERT_FILE		OPENSSLDIR "/cert.pem"
+#define X509_PRIVATE_DIR	OPENSSLDIR "/private"
+#else
+#define X509_CERT_AREA		"SSLROOT:[000000]"
+#define X509_CERT_DIR		"SSLCERTS:"
+#define X509_CERT_FILE		"SSLCERTS:cert.pem"
+#define X509_PRIVATE_DIR        "SSLPRIVATE:"
+#endif
+
+#define X509_CERT_DIR_EVP        "SSL_CERT_DIR"
+#define X509_CERT_FILE_EVP       "SSL_CERT_FILE"
+
+/* size of string representations */
+#define DECIMAL_SIZE(type)	((sizeof(type)*8+2)/3+1)
+#define HEX_SIZE(type)		(sizeof(type)*2)
+
+void OPENSSL_cpuid_setup(void);
+extern unsigned long OPENSSL_ia32cap_P;
+void OPENSSL_showfatal(const char *,...);
+void *OPENSSL_stderr(void);
+extern int OPENSSL_NONPIC_relocated;
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/crypto-lib.com b/openssl/crypto/crypto-lib.com
new file mode 100644
index 0000000..a29c0af
--- /dev/null
+++ b/openssl/crypto/crypto-lib.com
@@ -0,0 +1,1507 @@
+$!
+$!  CRYPTO-LIB.COM
+$!  Written By:  Robert Byer
+$!               Vice-President
+$!               A-Com Computing, Inc.
+$!               byer@mail.all-net.net
+$!
+$!  Changes by Richard Levitte <richard@levitte.org>
+$!             Zoltan Arpadffy <arpadffy@polarhome.com>
+$!
+$!  This command files compiles and creates the "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" 
+$!  library for OpenSSL.  The "xxx" denotes the machine architecture, ALPHA,
+$!  IA64 or VAX.
+$!
+$!  It was re-written so it would try to determine what "C" compiler to use 
+$!  or you can specify which "C" compiler to use.
+$!
+$!  Specify the following as P1 to build just that part or ALL to just
+$!  build everything.
+$!
+$!    	LIBRARY    To just compile the [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library.
+$!    	APPS       To just compile the [.xxx.EXE.CRYPTO]*.EXE
+$!	ALL	   To do both LIBRARY and APPS
+$!
+$!  Specify DEBUG or NODEBUG as P2 to compile with or without debugger
+$!  information.
+$!
+$!  Specify which compiler at P3 to try to compile under.
+$!
+$!	VAXC	   For VAX C.
+$!	DECC	   For DEC C.
+$!	GNUC	   For GNU C.
+$!
+$!  If you don't specify a compiler, it will try to determine which
+$!  "C" compiler to use.
+$!
+$!  P4, if defined, sets a TCP/IP library to use, through one of the following
+$!  keywords:
+$!
+$!	UCX	   For UCX
+$!	TCPIP	   For TCPIP (post UCX)
+$!	SOCKETSHR  For SOCKETSHR+NETLIB
+$!
+$!  P5, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
+$!
+$!  P6, if defined, sets a choice of crypto methods to compile.
+$!  WARNING: this should only be done to recompile some part of an already
+$!  fully compiled library.
+$!
+$!  P7, if defined, specifies the C pointer size.  Ignored on VAX.
+$!      ("64=ARGV" gives more efficient code with HP C V7.3 or newer.)
+$!      Supported values are:
+$!
+$!      ""       Compile with default (/NOPOINTER_SIZE)
+$!      32       Compile with /POINTER_SIZE=32 (SHORT)
+$!      64       Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV]).
+$!               (Automatically select ARGV if compiler supports it.)
+$!      64=      Compile with /POINTER_SIZE=64 (LONG).
+$!      64=ARGV  Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV).
+$!
+$!  P8, if defined, specifies a directory where ZLIB files (zlib.h,
+$!  libz.olb) may be found.  Optionally, a non-default object library
+$!  name may be included ("dev:[dir]libz_64.olb", for example).
+$!
+$!
+$! Announce/identify.
+$!
+$ proc = f$environment( "procedure")
+$ write sys$output "@@@ "+ -
+   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
+$!
+$! Define A TCP/IP Library That We Will Need To Link To.
+$! (That Is, If We Need To Link To One.)
+$!
+$ TCPIP_LIB = ""
+$ ZLIB_LIB = ""
+$!
+$! Check Which Architecture We Are Using.
+$!
+$ IF (F$GETSYI("CPU").LT.128)
+$ THEN
+$!
+$!  The Architecture Is VAX
+$!
+$   ARCH = "VAX"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  The Architecture Is Alpha, IA64 or whatever comes in the future.
+$!
+$   ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
+$   IF (ARCH .EQS. "") THEN ARCH = "UNK"
+$!
+$! End The Architecture Check.
+$!
+$ ENDIF
+$!
+$ ARCHD = ARCH
+$ LIB32 = "32"
+$ OPT_FILE = ""
+$ POINTER_SIZE = ""
+$!
+$! Define The Different Encryption Types.
+$! NOTE: Some might think this list ugly.  However, it's made this way to
+$! reflect the SDIRS variable in [-]Makefile.org as closely as possible,
+$! thereby making it fairly easy to verify that the lists are the same.
+$!
+$ ET_WHIRLPOOL = "WHRLPOOL"
+$ IF ARCH .EQS. "VAX" THEN ET_WHIRLPOOL = ""
+$ ENCRYPT_TYPES = "Basic,"+ -
+		  "OBJECTS,"+ -
+		  "MD2,MD4,MD5,SHA,MDC2,HMAC,RIPEMD,"+ET_WHIRLPOOL+","+ -
+		  "DES,AES,RC2,RC4,RC5,IDEA,BF,CAST,CAMELLIA,SEED,MODES,"+ -
+		  "BN,EC,RSA,DSA,ECDSA,DH,ECDH,DSO,ENGINE,"+ -
+		  "BUFFER,BIO,STACK,LHASH,RAND,ERR,"+ -
+		  "EVP,EVP_2,EVP_3,ASN1,ASN1_2,PEM,X509,X509V3,"+ -
+		  "CONF,TXT_DB,PKCS7,PKCS12,COMP,OCSP,UI,KRB5,"+ -
+		  "STORE,CMS,PQUEUE,TS,JPAKE"
+$!
+$! Check To Make Sure We Have Valid Command Line Parameters.
+$!
+$ GOSUB CHECK_OPTIONS
+$!
+$! Define The OBJ and EXE Directories.
+$!
+$ OBJ_DIR := SYS$DISK:[-.'ARCHD'.OBJ.CRYPTO]
+$ EXE_DIR := SYS$DISK:[-.'ARCHD'.EXE.CRYPTO]
+$!
+$! Specify the destination directory in any /MAP option.
+$!
+$ if (LINKMAP .eqs. "MAP")
+$ then
+$   LINKMAP = LINKMAP+ "=''EXE_DIR'"
+$ endif
+$!
+$! Add the location prefix to the linker options file name.
+$!
+$ if (OPT_FILE .nes. "")
+$ then
+$   OPT_FILE = EXE_DIR+ OPT_FILE
+$ endif
+$!
+$! Initialise logical names and such
+$!
+$ GOSUB INITIALISE
+$!
+$! Tell The User What Kind of Machine We Run On.
+$!
+$ WRITE SYS$OUTPUT "Host system architecture: ''ARCHD'"
+$!
+$!
+$! Check To See If The Architecture Specific OBJ Directory Exists.
+$!
+$ IF (F$PARSE(OBJ_DIR).EQS."")
+$ THEN
+$!
+$!  It Dosen't Exist, So Create It.
+$!
+$   CREATE/DIR 'OBJ_DIR'
+$!
+$! End The Architecture Specific OBJ Directory Check.
+$!
+$ ENDIF
+$!
+$! Check To See If The Architecture Specific Directory Exists.
+$!
+$ IF (F$PARSE(EXE_DIR).EQS."")
+$ THEN
+$!
+$!  It Dosen't Exist, So Create It.
+$!
+$   CREATE/DIRECTORY 'EXE_DIR'
+$!
+$! End The Architecture Specific Directory Check.
+$!
+$ ENDIF
+$!
+$! Define The Library Name.
+$!
+$ LIB_NAME := 'EXE_DIR'SSL_LIBCRYPTO'LIB32'.OLB
+$!
+$! Define The CRYPTO-LIB We Are To Use.
+$!
+$ CRYPTO_LIB := 'EXE_DIR'SSL_LIBCRYPTO'LIB32'.OLB
+$!
+$! Check To See If We Already Have A "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" Library...
+$!
+$ IF (F$SEARCH(LIB_NAME).EQS."")
+$ THEN
+$!
+$! Guess Not, Create The Library.
+$!
+$   LIBRARY/CREATE/OBJECT 'LIB_NAME'
+$!
+$! End The Library Check.
+$!
+$ ENDIF
+$!
+$! Build our options file for the application
+$!
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Define The Different Encryption "library" Strings.
+$!
+$ APPS_DES = "DES/DES,CBC3_ENC"
+$ APPS_PKCS7 = "ENC/ENC;DEC/DEC;SIGN/SIGN;VERIFY/VERIFY,EXAMPLE"
+$
+$ LIB_ = "cryptlib,mem,mem_clr,mem_dbg,cversion,ex_data,cpt_err,ebcdic,uid,o_time,o_str,o_dir"
+$ LIB_MD2 = "md2_dgst,md2_one"
+$ LIB_MD4 = "md4_dgst,md4_one"
+$ LIB_MD5 = "md5_dgst,md5_one"
+$ LIB_SHA = "sha_dgst,sha1dgst,sha_one,sha1_one,sha256,sha512"
+$ LIB_MDC2 = "mdc2dgst,mdc2_one"
+$ LIB_HMAC = "hmac,hm_ameth,hm_pmeth"
+$ LIB_RIPEMD = "rmd_dgst,rmd_one"
+$ LIB_WHRLPOOL = "wp_dgst,wp_block"
+$ LIB_DES = "set_key,ecb_enc,cbc_enc,"+ -
+	"ecb3_enc,cfb64enc,cfb64ede,cfb_enc,ofb64ede,"+ -
+	"enc_read,enc_writ,ofb64enc,"+ -
+	"ofb_enc,str2key,pcbc_enc,qud_cksm,rand_key,"+ -
+	"des_enc,fcrypt_b,"+ -
+	"fcrypt,xcbc_enc,rpc_enc,cbc_cksm,"+ -
+	"ede_cbcm_enc,des_old,des_old2,read2pwd"
+$ LIB_RC2 = "rc2_ecb,rc2_skey,rc2_cbc,rc2cfb64,rc2ofb64"
+$ LIB_RC4 = "rc4_skey,rc4_enc"
+$ LIB_RC5 = "rc5_skey,rc5_ecb,rc5_enc,rc5cfb64,rc5ofb64"
+$ LIB_IDEA = "i_cbc,i_cfb64,i_ofb64,i_ecb,i_skey"
+$ LIB_BF = "bf_skey,bf_ecb,bf_enc,bf_cfb64,bf_ofb64"
+$ LIB_CAST = "c_skey,c_ecb,c_enc,c_cfb64,c_ofb64"
+$ LIB_CAMELLIA = "camellia,cmll_misc,cmll_ecb,cmll_cbc,cmll_ofb,"+ -
+	"cmll_cfb,cmll_ctr"
+$ LIB_SEED = "seed,seed_ecb,seed_cbc,seed_cfb,seed_ofb"
+$ LIB_MODES = "cbc128,ctr128,cts128,cfb128,ofb128"
+$ LIB_BN_ASM = "[.asm]vms.mar,vms-helper"
+$ IF F$TRNLNM("OPENSSL_NO_ASM") .OR. ARCH .NES. "VAX" THEN -
+     LIB_BN_ASM = "bn_asm"
+$ LIB_BN = "bn_add,bn_div,bn_exp,bn_lib,bn_ctx,bn_mul,bn_mod,"+ -
+	"bn_print,bn_rand,bn_shift,bn_word,bn_blind,"+ -
+	"bn_kron,bn_sqrt,bn_gcd,bn_prime,bn_err,bn_sqr,"+LIB_BN_ASM+","+ -
+	"bn_recp,bn_mont,bn_mpi,bn_exp2,bn_gf2m,bn_nist,"+ -
+	"bn_depr,bn_const"
+$ LIB_EC = "ec_lib,ecp_smpl,ecp_mont,ecp_nist,ec_cvt,ec_mult,"+ -
+	"ec_err,ec_curve,ec_check,ec_print,ec_asn1,ec_key,"+ -
+	"ec2_smpl,ec2_mult,ec_ameth,ec_pmeth,eck_prn"
+$ LIB_RSA = "rsa_eay,rsa_gen,rsa_lib,rsa_sign,rsa_saos,rsa_err,"+ -
+	"rsa_pk1,rsa_ssl,rsa_none,rsa_oaep,rsa_chk,rsa_null,"+ -
+	"rsa_pss,rsa_x931,rsa_asn1,rsa_depr,rsa_ameth,rsa_prn,"+ -
+	"rsa_pmeth"
+$ LIB_DSA = "dsa_gen,dsa_key,dsa_lib,dsa_asn1,dsa_vrf,dsa_sign,"+ -
+	"dsa_err,dsa_ossl,dsa_depr,dsa_ameth,dsa_pmeth,dsa_prn"
+$ LIB_ECDSA = "ecs_lib,ecs_asn1,ecs_ossl,ecs_sign,ecs_vrf,ecs_err"
+$ LIB_DH = "dh_asn1,dh_gen,dh_key,dh_lib,dh_check,dh_err,dh_depr,"+ -
+	"dh_ameth,dh_pmeth,dh_prn"
+$ LIB_ECDH = "ech_lib,ech_ossl,ech_key,ech_err"
+$ LIB_DSO = "dso_dl,dso_dlfcn,dso_err,dso_lib,dso_null,"+ -
+	"dso_openssl,dso_win32,dso_vms,dso_beos"
+$ LIB_ENGINE = "eng_err,eng_lib,eng_list,eng_init,eng_ctrl,"+ -
+	"eng_table,eng_pkey,eng_fat,eng_all,"+ -
+	"tb_rsa,tb_dsa,tb_ecdsa,tb_dh,tb_ecdh,tb_rand,tb_store,"+ -
+	"tb_cipher,tb_digest,tb_pkmeth,tb_asnmth,"+ -
+	"eng_openssl,eng_dyn,eng_cnf,eng_cryptodev"
+$ LIB_AES = "aes_core,aes_misc,aes_ecb,aes_cbc,aes_cfb,aes_ofb,aes_ctr,"+ -
+	"aes_ige,aes_wrap"
+$ LIB_BUFFER = "buffer,buf_err"
+$ LIB_BIO = "bio_lib,bio_cb,bio_err,"+ -
+	"bss_mem,bss_null,bss_fd,"+ -
+	"bss_file,bss_sock,bss_conn,"+ -
+	"bf_null,bf_buff,b_print,b_dump,"+ -
+	"b_sock,bss_acpt,bf_nbio,bss_rtcp,bss_bio,bss_log,"+ -
+	"bss_dgram,"+ -
+	"bf_lbuf"
+$ LIB_STACK = "stack"
+$ LIB_LHASH = "lhash,lh_stats"
+$ LIB_RAND = "md_rand,randfile,rand_lib,rand_err,rand_egd,"+ -
+	"rand_vms"
+$ LIB_ERR = "err,err_all,err_prn"
+$ LIB_OBJECTS = "o_names,obj_dat,obj_lib,obj_err,obj_xref"
+$ LIB_EVP = "encode,digest,evp_enc,evp_key,evp_acnf,"+ -
+	"e_des,e_bf,e_idea,e_des3,e_camellia,"+ -
+	"e_rc4,e_aes,names,e_seed,"+ -
+	"e_xcbc_d,e_rc2,e_cast,e_rc5"
+$ LIB_EVP_2 = "m_null,m_md2,m_md4,m_md5,m_sha,m_sha1,m_wp," + -
+	"m_dss,m_dss1,m_mdc2,m_ripemd,m_ecdsa,"+ -
+	"p_open,p_seal,p_sign,p_verify,p_lib,p_enc,p_dec,"+ -
+	"bio_md,bio_b64,bio_enc,evp_err,e_null,"+ -
+	"c_all,c_allc,c_alld,evp_lib,bio_ok,"+-
+	"evp_pkey,evp_pbe,p5_crpt,p5_crpt2"
+$ LIB_EVP_3 = "e_old,pmeth_lib,pmeth_fn,pmeth_gn,m_sigver"
+$ LIB_ASN1 = "a_object,a_bitstr,a_utctm,a_gentm,a_time,a_int,a_octet,"+ -
+	"a_print,a_type,a_set,a_dup,a_d2i_fp,a_i2d_fp,"+ -
+	"a_enum,a_utf8,a_sign,a_digest,a_verify,a_mbstr,a_strex,"+ -
+	"x_algor,x_val,x_pubkey,x_sig,x_req,x_attrib,x_bignum,"+ -
+	"x_long,x_name,x_x509,x_x509a,x_crl,x_info,x_spki,nsseq,"+ -
+	"x_nx509,d2i_pu,d2i_pr,i2d_pu,i2d_pr"
+$ LIB_ASN1_2 = "t_req,t_x509,t_x509a,t_crl,t_pkey,t_spki,t_bitst,"+ -
+	"tasn_new,tasn_fre,tasn_enc,tasn_dec,tasn_utl,tasn_typ,"+ -
+	"tasn_prn,ameth_lib,"+ -
+	"f_int,f_string,n_pkey,"+ -
+	"f_enum,x_pkey,a_bool,x_exten,bio_asn1,bio_ndef,asn_mime,"+ -
+	"asn1_gen,asn1_par,asn1_lib,asn1_err,a_bytes,a_strnid,"+ -
+	"evp_asn1,asn_pack,p5_pbe,p5_pbev2,p8_pkey,asn_moid"
+$ LIB_PEM = "pem_sign,pem_seal,pem_info,pem_lib,pem_all,pem_err,"+ -
+	"pem_x509,pem_xaux,pem_oth,pem_pk8,pem_pkey,pvkfmt"
+$ LIB_X509 = "x509_def,x509_d2,x509_r2x,x509_cmp,"+ -
+	"x509_obj,x509_req,x509spki,x509_vfy,"+ -
+	"x509_set,x509cset,x509rset,x509_err,"+ -
+	"x509name,x509_v3,x509_ext,x509_att,"+ -
+	"x509type,x509_lu,x_all,x509_txt,"+ -
+	"x509_trs,by_file,by_dir,x509_vpm"
+$ LIB_X509V3 = "v3_bcons,v3_bitst,v3_conf,v3_extku,v3_ia5,v3_lib,"+ -
+	"v3_prn,v3_utl,v3err,v3_genn,v3_alt,v3_skey,v3_akey,v3_pku,"+ -
+	"v3_int,v3_enum,v3_sxnet,v3_cpols,v3_crld,v3_purp,v3_info,"+ -
+	"v3_ocsp,v3_akeya,v3_pmaps,v3_pcons,v3_ncons,v3_pcia,v3_pci,"+ -
+	"pcy_cache,pcy_node,pcy_data,pcy_map,pcy_tree,pcy_lib,"+ -
+	"v3_asid,v3_addr"
+$ LIB_CONF = "conf_err,conf_lib,conf_api,conf_def,conf_mod,conf_mall,conf_sap"
+$ LIB_TXT_DB = "txt_db"
+$ LIB_PKCS7 = "pk7_asn1,pk7_lib,pkcs7err,pk7_doit,pk7_smime,pk7_attr,"+ -
+	"pk7_mime,bio_pk7"
+$ LIB_PKCS12 = "p12_add,p12_asn,p12_attr,p12_crpt,p12_crt,p12_decr,"+ -
+	"p12_init,p12_key,p12_kiss,p12_mutl,"+ -
+	"p12_utl,p12_npas,pk12err,p12_p8d,p12_p8e"
+$ LIB_COMP = "comp_lib,comp_err,"+ -
+	"c_rle,c_zlib"
+$ LIB_OCSP = "ocsp_asn,ocsp_ext,ocsp_ht,ocsp_lib,ocsp_cl,"+ -
+	"ocsp_srv,ocsp_prn,ocsp_vfy,ocsp_err"
+$ LIB_UI_COMPAT = ",ui_compat"
+$ LIB_UI = "ui_err,ui_lib,ui_openssl,ui_util"+LIB_UI_COMPAT
+$ LIB_KRB5 = "krb5_asn"
+$ LIB_STORE = "str_err,str_lib,str_meth,str_mem"
+$ LIB_CMS = "cms_lib,cms_asn1,cms_att,cms_io,cms_smime,cms_err,"+ -
+	"cms_sd,cms_dd,cms_cd,cms_env,cms_enc,cms_ess"
+$ LIB_PQUEUE = "pqueue"
+$ LIB_TS = "ts_err,ts_req_utils,ts_req_print,ts_rsp_utils,ts_rsp_print,"+ -
+	"ts_rsp_sign,ts_rsp_verify,ts_verify_ctx,ts_lib,ts_conf,"+ -
+	"ts_asn1"
+$ LIB_JPAKE = "jpake,jpake_err"
+$!
+$! Setup exceptional compilations
+$!
+$ CC3_SHOWN = 0
+$ CC4_SHOWN = 0
+$ CC5_SHOWN = 0
+$ CC6_SHOWN = 0
+$!
+$! The following lists must have leading and trailing commas, and no
+$! embedded spaces.  (They are scanned for ",name,".)
+$!
+$ ! Add definitions for no threads on OpenVMS 7.1 and higher.
+$ COMPILEWITH_CC3 = ",bss_rtcp,"
+$ ! Disable the DOLLARID warning.  Not needed with /STANDARD=RELAXED.
+$ COMPILEWITH_CC4 = "" !!! ",a_utctm,bss_log,o_time,o_dir,"
+$ ! Disable disjoint optimization on VAX with DECC.
+$ COMPILEWITH_CC5 = ",md2_dgst,md4_dgst,md5_dgst,mdc2dgst," + -
+                    "seed,sha_dgst,sha1dgst,rmd_dgst,bf_enc,"
+$ ! Disable the MIXLINKAGE warning.
+$ COMPILEWITH_CC6 = "" !!! ",enc_read,set_key,"
+$!
+$! Figure Out What Other Modules We Are To Build.
+$!
+$ BUILD_SET:
+$!
+$! Define A Module Counter.
+$!
+$ MODULE_COUNTER = 0
+$!
+$! Top Of The Loop.
+$!
+$ MODULE_NEXT:
+$!
+$! Extract The Module Name From The Encryption List.
+$!
+$ MODULE_NAME = F$ELEMENT(MODULE_COUNTER,",",ENCRYPT_TYPES)
+$ IF MODULE_NAME.EQS."Basic" THEN MODULE_NAME = ""
+$ MODULE_NAME1 = MODULE_NAME
+$!
+$! Check To See If We Are At The End Of The Module List.
+$!
+$ IF (MODULE_NAME.EQS.",") 
+$ THEN 
+$!
+$!  We Are At The End Of The Module List, Go To MODULE_DONE.
+$!
+$   GOTO MODULE_DONE
+$!
+$! End The Module List Check.
+$!
+$ ENDIF
+$!
+$! Increment The Moudle Counter.
+$!
+$ MODULE_COUNTER = MODULE_COUNTER + 1
+$!
+$! Create The Library and Apps Module Names.
+$!
+$ LIB_MODULE = "LIB_" + MODULE_NAME
+$ APPS_MODULE = "APPS_" + MODULE_NAME
+$ IF (F$EXTRACT(0,5,MODULE_NAME).EQS."ASN1_")
+$ THEN
+$   MODULE_NAME = "ASN1"
+$ ENDIF
+$ IF (F$EXTRACT(0,4,MODULE_NAME).EQS."EVP_")
+$ THEN
+$   MODULE_NAME = "EVP"
+$ ENDIF
+$!
+$! Set state (can be LIB and APPS)
+$!
+$ STATE = "LIB"
+$ IF BUILDALL .EQS. "APPS" THEN STATE = "APPS"
+$!
+$! Check if the library module name actually is defined
+$!
+$ IF F$TYPE('LIB_MODULE') .EQS. ""
+$ THEN
+$   WRITE SYS$ERROR ""
+$   WRITE SYS$ERROR "The module ",MODULE_NAME1," does not exist.  Continuing..."
+$   WRITE SYS$ERROR ""
+$   GOTO MODULE_NEXT
+$ ENDIF
+$!
+$! Top Of The Module Loop.
+$!
+$ MODULE_AGAIN:
+$!
+$! Tell The User What Module We Are Building.
+$!
+$ IF (MODULE_NAME1.NES."") 
+$ THEN
+$   IF STATE .EQS. "LIB"
+$   THEN
+$     WRITE SYS$OUTPUT "Compiling The ",MODULE_NAME1," Library Files. (",BUILDALL,",",STATE,")"
+$   ELSE IF F$TYPE('APPS_MODULE') .NES. ""
+$     THEN
+$       WRITE SYS$OUTPUT "Compiling The ",MODULE_NAME1," Applications. (",BUILDALL,",",STATE,")"
+$     ENDIF
+$   ENDIF
+$ ENDIF
+$!
+$!  Define A File Counter And Set It To "0".
+$!
+$ FILE_COUNTER = 0
+$ APPLICATION = ""
+$ APPLICATION_COUNTER = 0
+$!
+$! Top Of The File Loop.
+$!
+$ NEXT_FILE:
+$!
+$! Look in the LIB_MODULE is we're in state LIB
+$!
+$ IF STATE .EQS. "LIB"
+$ THEN
+$!
+$!   O.K, Extract The File Name From The File List.
+$!
+$   FILE_NAME = F$ELEMENT(FILE_COUNTER,",",'LIB_MODULE')
+$!
+$!   else
+$!
+$ ELSE
+$   FILE_NAME = ","
+$!
+$   IF F$TYPE('APPS_MODULE') .NES. ""
+$   THEN
+$!
+$!     Extract The File Name From The File List.
+$!     This part is a bit more complicated.
+$!
+$     IF APPLICATION .EQS. ""
+$     THEN
+$       APPLICATION = F$ELEMENT(APPLICATION_COUNTER,";",'APPS_MODULE')
+$       APPLICATION_COUNTER = APPLICATION_COUNTER + 1
+$       APPLICATION_OBJECTS = F$ELEMENT(1,"/",APPLICATION)
+$       APPLICATION = F$ELEMENT(0,"/",APPLICATION)
+$       FILE_COUNTER = 0
+$     ENDIF
+$
+$!     WRITE SYS$OUTPUT "DEBUG: SHOW SYMBOL APPLICATION*"
+$!     SHOW SYMBOL APPLICATION*
+$!
+$     IF APPLICATION .NES. ";"
+$     THEN
+$       FILE_NAME = F$ELEMENT(FILE_COUNTER,",",APPLICATION_OBJECTS)
+$       IF FILE_NAME .EQS. ","
+$       THEN
+$         APPLICATION = ""
+$         GOTO NEXT_FILE
+$       ENDIF
+$     ENDIF
+$   ENDIF
+$ ENDIF
+$!
+$! Check To See If We Are At The End Of The File List.
+$!
+$ IF (FILE_NAME.EQS.",") 
+$ THEN 
+$!
+$!  We Are At The End Of The File List, Change State Or Goto FILE_DONE.
+$!
+$   IF STATE .EQS. "LIB" .AND. BUILDALL .NES. "LIBRARY"
+$   THEN
+$     STATE = "APPS"
+$     GOTO MODULE_AGAIN
+$   ELSE
+$     GOTO FILE_DONE
+$   ENDIF
+$!
+$! End The File List Check.
+$!
+$ ENDIF
+$!
+$! Increment The Counter.
+$!
+$ FILE_COUNTER = FILE_COUNTER + 1
+$!
+$! Create The Source File Name.
+$!
+$ TMP_FILE_NAME = F$ELEMENT(1,"]",FILE_NAME)
+$ IF TMP_FILE_NAME .EQS. "]" THEN TMP_FILE_NAME = FILE_NAME
+$ IF F$ELEMENT(0,".",TMP_FILE_NAME) .EQS. TMP_FILE_NAME THEN -
+	FILE_NAME = FILE_NAME + ".c"
+$ IF (MODULE_NAME.NES."")
+$ THEN
+$   SOURCE_FILE = "SYS$DISK:[." + MODULE_NAME+ "]" + FILE_NAME
+$ ELSE
+$   SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME
+$ ENDIF
+$ SOURCE_FILE = SOURCE_FILE - "]["
+$!
+$! Create The Object File Name.
+$!
+$ OBJECT_FILE = OBJ_DIR + F$PARSE(FILE_NAME,,,"NAME","SYNTAX_ONLY") + ".OBJ"
+$ ON WARNING THEN GOTO NEXT_FILE
+$!
+$! Check To See If The File We Want To Compile Is Actually There.
+$!
+$ IF (F$SEARCH(SOURCE_FILE).EQS."")
+$ THEN
+$!
+$!  Tell The User That The File Doesn't Exist.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Doesn't Exist."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Exit The Build.
+$!
+$   GOTO EXIT
+$!
+$! End The File Exist Check.
+$!
+$ ENDIF
+$!
+$! Tell The User We Are Compiling The File.
+$!
+$ IF (MODULE_NAME.EQS."")
+$ THEN
+$   WRITE SYS$OUTPUT "Compiling The ",FILE_NAME," File.  (",BUILDALL,",",STATE,")"
+$ ENDIF
+$ IF (MODULE_NAME.NES."")
+$ THEN 
+$   WRITE SYS$OUTPUT "        ",FILE_NAME,""
+$ ENDIF
+$!
+$! Compile The File.
+$!
+$ ON ERROR THEN GOTO NEXT_FILE
+$ FILE_NAME0 = ","+ F$ELEMENT(0,".",FILE_NAME)+ ","
+$ IF FILE_NAME - ".mar" .NES. FILE_NAME
+$ THEN
+$   MACRO/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ELSE
+$   IF COMPILEWITH_CC3 - FILE_NAME0 .NES. COMPILEWITH_CC3
+$   THEN
+$     write sys$output "        \Using special rule (3)"
+$     if (.not. CC3_SHOWN)
+$     then
+$       CC3_SHOWN = 1
+$       x = "    "+ CC3
+$       write /symbol sys$output x
+$     endif
+$     CC3/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$   ELSE
+$     IF COMPILEWITH_CC4 - FILE_NAME0 .NES. COMPILEWITH_CC4
+$     THEN
+$       write /symbol sys$output "        \Using special rule (4)"
+$       if (.not. CC4_SHOWN)
+$       then
+$         CC4_SHOWN = 1
+$         x = "    "+ CC4
+$         write /symbol sys$output x
+$       endif
+$       CC4/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$     ELSE
+$       IF CC5_DIFFERENT .AND. -
+         (COMPILEWITH_CC5 - FILE_NAME0 .NES. COMPILEWITH_CC5)
+$       THEN
+$         write sys$output "        \Using special rule (5)"
+$         if (.not. CC5_SHOWN)
+$         then
+$           CC5_SHOWN = 1
+$           x = "    "+ CC5
+$           write /symbol sys$output x
+$         endif
+$         CC5/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$       ELSE
+$         IF COMPILEWITH_CC6 - FILE_NAME0 .NES. COMPILEWITH_CC6
+$         THEN
+$           write sys$output "        \Using special rule (6)"
+$           if (.not. CC6_SHOWN)
+$           then
+$             CC6_SHOWN = 1
+$             x = "    "+ CC6
+$             write /symbol sys$output x
+$           endif
+$           CC6/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$         ELSE
+$           CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$         ENDIF
+$       ENDIF
+$     ENDIF
+$   ENDIF
+$ ENDIF
+$ IF STATE .EQS. "LIB"
+$ THEN 
+$!
+$!   Add It To The Library.
+$!
+$   LIBRARY/REPLACE 'LIB_NAME' 'OBJECT_FILE'
+$!
+$!   Time To Clean Up The Object File.
+$!
+$   DELETE 'OBJECT_FILE';*
+$ ENDIF
+$!
+$! Go Back And Do It Again.
+$!
+$ GOTO NEXT_FILE
+$!
+$! All Done With This Library Part.
+$!
+$ FILE_DONE:
+$!
+$! Time To Build Some Applications
+$!
+$ IF F$TYPE('APPS_MODULE') .NES. "" .AND. BUILDALL .NES. "LIBRARY"
+$ THEN
+$   APPLICATION_COUNTER = 0
+$ NEXT_APPLICATION:
+$   APPLICATION = F$ELEMENT(APPLICATION_COUNTER,";",'APPS_MODULE')
+$   IF APPLICATION .EQS. ";" THEN GOTO APPLICATION_DONE
+$
+$   APPLICATION_COUNTER = APPLICATION_COUNTER + 1
+$   APPLICATION_OBJECTS = F$ELEMENT(1,"/",APPLICATION)
+$   APPLICATION = F$ELEMENT(0,"/",APPLICATION)
+$
+$!   WRITE SYS$OUTPUT "DEBUG: SHOW SYMBOL APPLICATION*"
+$!   SHOW SYMBOL APPLICATION*
+$!
+$! Tell the user what happens
+$!
+$   WRITE SYS$OUTPUT "        ",APPLICATION,".exe"
+$!
+$! Link The Program.
+$!
+$   ON ERROR THEN GOTO NEXT_APPLICATION
+$!
+$!  Link With A TCP/IP Library.
+$!
+$   LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' -
+     /EXE='EXE_DIR''APPLICATION'.EXE -
+     'OBJ_DIR''APPLICATION_OBJECTS', -
+     'CRYPTO_LIB'/LIBRARY -
+     'TCPIP_LIB' -
+     'ZLIB_LIB' -
+     ,'OPT_FILE' /OPTIONS
+$!
+$   GOTO NEXT_APPLICATION
+$  APPLICATION_DONE:
+$ ENDIF
+$!
+$! Go Back And Get The Next Module.
+$!
+$ GOTO MODULE_NEXT
+$!
+$! All Done With This Module.
+$!
+$ MODULE_DONE:
+$!
+$! Tell The User That We Are All Done.
+$!
+$ WRITE SYS$OUTPUT "All Done..."
+$ EXIT:
+$ GOSUB CLEANUP
+$ EXIT
+$!
+$! Check For The Link Option FIle.
+$!
+$ CHECK_OPT_FILE:
+$!
+$! Check To See If We Need To Make A VAX C Option File.
+$!
+$ IF (COMPILER.EQS."VAXC")
+$ THEN
+$!
+$!  Check To See If We Already Have A VAX C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    We Need A VAX C Linker Option File.
+$!
+$     CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against 
+! The Sharable VAX C Runtime Library.
+!
+SYS$SHARE:VAXCRTL.EXE/SHARE
+$EOD
+$!
+$!  End The Option File Check.
+$!
+$   ENDIF
+$!
+$! End The VAXC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A GNU C Option File.
+$!
+$ IF (COMPILER.EQS."GNUC")
+$ THEN
+$!
+$!  Check To See If We Already Have A GNU C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    We Need A GNU C Linker Option File.
+$!
+$     CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against 
+! The Sharable C Runtime Library.
+!
+GNU_CC:[000000]GCCLIB/LIBRARY
+SYS$SHARE:VAXCRTL/SHARE
+$EOD
+$!
+$!  End The Option File Check.
+$!
+$   ENDIF
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A DEC C Option File.
+$!
+$ IF (COMPILER.EQS."DECC")
+$ THEN
+$!
+$!  Check To See If We Already Have A DEC C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    Figure Out If We Need A non-VAX Or A VAX Linker Option File.
+$!
+$     IF ARCH .EQS. "VAX"
+$     THEN
+$!
+$!      We Need A DEC C Linker Option File For VAX.
+$!
+$       CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against 
+! The Sharable DEC C Runtime Library.
+!
+SYS$SHARE:DECC$SHR.EXE/SHARE
+$EOD
+$!
+$!    Else...
+$!
+$     ELSE
+$!
+$!      Create The non-VAX Linker Option File.
+$!
+$       CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File For non-VAX To Link Against 
+! The Sharable C Runtime Library.
+!
+SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
+SYS$SHARE:CMA$OPEN_RTL/SHARE
+$EOD
+$!
+$!    End The DEC C Option File Check.
+$!
+$     ENDIF
+$!
+$!  End The Option File Search.
+$!
+$   ENDIF
+$!
+$! End The DEC C Check.
+$!
+$ ENDIF
+$!
+$!  Tell The User What Linker Option File We Are Using.
+$!
+$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$!
+$! Check The User's Options.
+$!
+$ CHECK_OPTIONS:
+$!
+$! Check To See If P1 Is Blank.
+$!
+$ IF (P1.EQS."ALL")
+$ THEN
+$!
+$!   P1 Is Blank, So Build Everything.
+$!
+$    BUILDALL = "TRUE"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  Else, Check To See If P1 Has A Valid Argument.
+$!
+$   IF (P1.EQS."LIBRARY").OR.(P1.EQS."APPS")
+$   THEN
+$!
+$!    A Valid Argument.
+$!
+$     BUILDALL = P1
+$!
+$!  Else...
+$!
+$   ELSE
+$!
+$!    Tell The User We Don't Know What They Want.
+$!
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ",P1," Is Invalid.  The Valid Options Are:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "    ALL      :  Just Build Everything."
+$     WRITE SYS$OUTPUT "    LIBRARY  :  To Compile Just The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library."
+$     WRITE SYS$OUTPUT "    APPS     :  To Compile Just The [.xxx.EXE.CRYPTO]*.EXE Programs."
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT " Where 'xxx' Stands For:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "    ALPHA[64]:  Alpha Architecture."
+$     WRITE SYS$OUTPUT "    IA64[64] :  IA64 Architecture."
+$     WRITE SYS$OUTPUT "    VAX      :  VAX Architecture."
+$     WRITE SYS$OUTPUT ""
+$!
+$!    Time To EXIT.
+$!
+$     EXIT
+$!
+$!  End The Valid Argument Check.
+$!
+$   ENDIF
+$!
+$! End The P1 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P2 Is Blank.
+$!
+$ IF (P2.EQS."NODEBUG")
+$ THEN
+$!
+$!  P2 Is NODEBUG, So Compile Without The Debugger Information.
+$!
+$   DEBUGGER = "NODEBUG"
+$   LINKMAP = "NOMAP"
+$   TRACEBACK = "NOTRACEBACK" 
+$   GCC_OPTIMIZE = "OPTIMIZE"
+$   CC_OPTIMIZE = "OPTIMIZE"
+$   MACRO_OPTIMIZE = "OPTIMIZE"
+$   WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
+$   WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
+$ ELSE
+$!
+$!  Check To See If We Are To Compile With Debugger Information.
+$!
+$   IF (P2.EQS."DEBUG")
+$   THEN
+$!
+$!    Compile With Debugger Information.
+$!
+$     DEBUGGER = "DEBUG"
+$     LINKMAP = "MAP"
+$     TRACEBACK = "TRACEBACK"
+$     GCC_OPTIMIZE = "NOOPTIMIZE"
+$     CC_OPTIMIZE = "NOOPTIMIZE"
+$     MACRO_OPTIMIZE = "NOOPTIMIZE"
+$     WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
+$     WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
+$   ELSE 
+$!
+$!    They Entered An Invalid Option.
+$!
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ",P2," Is Invalid.  The Valid Options Are:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "     DEBUG   :  Compile With The Debugger Information."
+$     WRITE SYS$OUTPUT "     NODEBUG :  Compile Without The Debugger Information."
+$     WRITE SYS$OUTPUT ""
+$!
+$!    Time To EXIT.
+$!
+$     EXIT
+$!
+$!  End The Valid Argument Check.
+$!
+$   ENDIF
+$!
+$! End The P2 Check.
+$!
+$ ENDIF
+$!
+$! Special Threads For OpenVMS v7.1 Or Later
+$!
+$! Written By:  Richard Levitte
+$!              richard@levitte.org
+$!
+$!
+$! Check To See If We Have A Option For P5.
+$!
+$ IF (P5.EQS."")
+$ THEN
+$!
+$!  Get The Version Of VMS We Are Using.
+$!
+$   ISSEVEN :=
+$   TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
+$   TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
+$!
+$!  Check To See If The VMS Version Is v7.1 Or Later.
+$!
+$   IF (TMP.GE.71)
+$   THEN
+$!
+$!    We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
+$!
+$     ISSEVEN := ,PTHREAD_USE_D4
+$!
+$!  End The VMS Version Check.
+$!
+$   ENDIF
+$!
+$! End The P5 Check.
+$!
+$ ENDIF
+$!
+$! Check P7 (POINTER_SIZE).
+$!
+$ IF (P7 .NES. "") .AND. (ARCH .NES. "VAX")
+$ THEN
+$!
+$   IF (P7 .EQS. "32")
+$   THEN
+$     POINTER_SIZE = " /POINTER_SIZE=32"
+$   ELSE
+$     POINTER_SIZE = F$EDIT( P7, "COLLAPSE, UPCASE")
+$     IF ((POINTER_SIZE .EQS. "64") .OR. -
+       (POINTER_SIZE .EQS. "64=") .OR. -
+       (POINTER_SIZE .EQS. "64=ARGV"))
+$     THEN
+$       ARCHD = ARCH+ "_64"
+$       LIB32 = ""
+$       POINTER_SIZE = " /POINTER_SIZE=64"
+$     ELSE
+$!
+$!      Tell The User Entered An Invalid Option.
+$!
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT "The Option ", P7, -
+         " Is Invalid.  The Valid Options Are:"
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT -
+         "    """"       :  Compile with default (short) pointers."
+$       WRITE SYS$OUTPUT -
+         "    32       :  Compile with 32-bit (short) pointers."
+$       WRITE SYS$OUTPUT -
+         "    64       :  Compile with 64-bit (long) pointers (auto ARGV)."
+$       WRITE SYS$OUTPUT -
+         "    64=      :  Compile with 64-bit (long) pointers (no ARGV)."
+$       WRITE SYS$OUTPUT -
+         "    64=ARGV  :  Compile with 64-bit (long) pointers (ARGV)."
+$       WRITE SYS$OUTPUT ""
+$! 
+$!      Time To EXIT.
+$!
+$       EXIT
+$!
+$     ENDIF
+$!
+$   ENDIF
+$!
+$! End The P7 (POINTER_SIZE) Check.
+$!
+$ ENDIF
+$!
+$! Set basic C compiler /INCLUDE directories.
+$!
+$ CC_INCLUDES = "SYS$DISK:[.''ARCHD'],SYS$DISK:[],SYS$DISK:[-],"+ -
+   "SYS$DISK:[.ENGINE.VENDOR_DEFNS],SYS$DISK:[.EVP],SYS$DISK:[.ASN1]"
+$!
+$! Check To See If P3 Is Blank.
+$!
+$ IF (P3.EQS."")
+$ THEN
+$!
+$!  O.K., The User Didn't Specify A Compiler, Let's Try To
+$!  Find Out Which One To Use.
+$!
+$!  Check To See If We Have GNU C.
+$!
+$   IF (F$TRNLNM("GNU_CC").NES."")
+$   THEN
+$!
+$!    Looks Like GNUC, Set To Use GNUC.
+$!
+$     P3 = "GNUC"
+$!
+$!  Else...
+$!
+$   ELSE
+$!
+$!    Check To See If We Have VAXC Or DECC.
+$!
+$     IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
+$     THEN 
+$!
+$!      Looks Like DECC, Set To Use DECC.
+$!
+$       P3 = "DECC"
+$!
+$!    Else...
+$!
+$     ELSE
+$!
+$!      Looks Like VAXC, Set To Use VAXC.
+$!
+$       P3 = "VAXC"
+$!
+$!    End The VAXC Compiler Check.
+$!
+$     ENDIF
+$!
+$!  End The DECC & VAXC Compiler Check.
+$!
+$   ENDIF
+$!
+$!  End The Compiler Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have A Option For P4.
+$!
+$ IF (P4.EQS."")
+$ THEN
+$!
+$!  Find out what socket library we have available
+$!
+$   IF F$PARSE("SOCKETSHR:") .NES. ""
+$   THEN
+$!
+$!    We have SOCKETSHR, and it is my opinion that it's the best to use.
+$!
+$     P4 = "SOCKETSHR"
+$!
+$!    Tell the user
+$!
+$     WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
+$!
+$!    Else, let's look for something else
+$!
+$   ELSE
+$!
+$!    Like UCX (the reason to do this before Multinet is that the UCX
+$!    emulation is easier to use...)
+$!
+$     IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
+	 .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
+	 .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
+$     THEN
+$!
+$!	Last resort: a UCX or UCX-compatible library
+$!
+$	P4 = "UCX"
+$!
+$!      Tell the user
+$!
+$       WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
+$!
+$!	That was all...
+$!
+$     ENDIF
+$   ENDIF
+$ ENDIF
+$!
+$! Set Up Initial CC Definitions, Possibly With User Ones
+$!
+$ CCDEFS = "TCPIP_TYPE_''P4',DSO_VMS"
+$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
+$ CCEXTRAFLAGS = ""
+$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
+$ CCDISABLEWARNINGS = "" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
+$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
+	CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
+$!
+$! Check To See If We Have A ZLIB Option.
+$!
+$ ZLIB = P8
+$ IF (ZLIB .NES. "")
+$ THEN
+$!
+$!  Check for expected ZLIB files.
+$!
+$   err = 0
+$   file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY")
+$   if (f$search( file1) .eqs. "")
+$   then
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
+$     WRITE SYS$OUTPUT "    Can't find header: ''file1'"
+$     err = 1
+$   endif
+$   file1 = f$parse( "A.;", ZLIB)- "A.;"
+$!
+$   file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY")
+$   if (f$search( file2) .eqs. "")
+$   then
+$     if (err .eq. 0)
+$     then
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
+$     endif
+$     WRITE SYS$OUTPUT "    Can't find library: ''file2'"
+$     WRITE SYS$OUTPUT ""
+$     err = err+ 2
+$   endif
+$   if (err .eq. 1)
+$   then
+$     WRITE SYS$OUTPUT ""
+$   endif
+$!
+$   if (err .ne. 0)
+$   then
+$     EXIT
+$   endif
+$!
+$   CCDEFS = """ZLIB=1"", "+ CCDEFS
+$   CC_INCLUDES = CC_INCLUDES+ ", "+ file1
+$   ZLIB_LIB = ", ''file2' /library"
+$!
+$!  Print info
+$!
+$   WRITE SYS$OUTPUT "ZLIB library spec: ", file2
+$!
+$! End The ZLIB Check.
+$!
+$ ENDIF
+$!
+$!  Check To See If The User Entered A Valid Parameter.
+$!
+$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC")
+$ THEN
+$!
+$!    Check To See If The User Wanted DECC.
+$!
+$   IF (P3.EQS."DECC")
+$   THEN
+$!
+$!    Looks Like DECC, Set To Use DECC.
+$!
+$     COMPILER = "DECC"
+$!
+$!    Tell The User We Are Using DECC.
+$!
+$     WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$!    Use DECC...
+$!
+$     CC = "CC"
+$     IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
+	 THEN CC = "CC/DECC"
+$     CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ -
+       "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + -
+       " /INCLUDE=(''CC_INCLUDES')"+ -
+       CCEXTRAFLAGS
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "VAX_DECC_OPTIONS.OPT"
+$!
+$!  End DECC Check.
+$!
+$   ENDIF
+$!
+$!  Check To See If We Are To Use VAXC.
+$!
+$   IF (P3.EQS."VAXC")
+$   THEN
+$!
+$!    Looks Like VAXC, Set To Use VAXC.
+$!
+$     COMPILER = "VAXC"
+$!
+$!    Tell The User We Are Using VAX C.
+$!
+$     WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$!    Compile Using VAXC.
+$!
+$     CC = "CC"
+$     IF ARCH.NES."VAX"
+$     THEN
+$	WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
+$	EXIT
+$     ENDIF
+$     IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
+$     CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+       "/INCLUDE=(''CC_INCLUDES')"+ -
+	   CCEXTRAFLAGS
+$     CCDEFS = """VAXC""," + CCDEFS
+$!
+$!    Define <sys> As SYS$COMMON:[SYSLIB]
+$!
+$     DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "VAX_VAXC_OPTIONS.OPT"
+$!
+$!  End VAXC Check
+$!
+$   ENDIF
+$!
+$!  Check To See If We Are To Use GNU C.
+$!
+$   IF (P3.EQS."GNUC")
+$   THEN
+$!
+$!    Looks Like GNUC, Set To Use GNUC.
+$!
+$     COMPILER = "GNUC"
+$!
+$!    Tell The User We Are Using GNUC.
+$!
+$     WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$!    Use GNU C...
+$!
+$     CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+       "/INCLUDE=(''CC_INCLUDES')"+ -
+	   CCEXTRAFLAGS
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "VAX_GNUC_OPTIONS.OPT"
+$!
+$!  End The GNU C Check.
+$!
+$   ENDIF
+$!
+$!  Set up default defines
+$!
+$   CCDEFS = """FLAT_INC=1""," + CCDEFS
+$!
+$!  Finish up the definition of CC.
+$!
+$   IF COMPILER .EQS. "DECC"
+$   THEN
+$     IF CCDISABLEWARNINGS .EQS. ""
+$     THEN
+$       CC4DISABLEWARNINGS = "DOLLARID"
+$       CC6DISABLEWARNINGS = "MIXLINKAGE"
+$     ELSE
+$       CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
+$       CC6DISABLEWARNINGS = CCDISABLEWARNINGS + ",MIXLINKAGE"
+$       CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
+$     ENDIF
+$     CC4DISABLEWARNINGS = " /WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
+$     CC6DISABLEWARNINGS = " /WARNING=(DISABLE=(" + CC6DISABLEWARNINGS + "))"
+$   ELSE
+$     CCDISABLEWARNINGS = ""
+$     CC4DISABLEWARNINGS = ""
+$     CC6DISABLEWARNINGS = ""
+$   ENDIF
+$   CC3 = CC + " /DEFINE=(" + CCDEFS + ISSEVEN + ")" + CCDISABLEWARNINGS
+$   CC = CC + " /DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
+$   IF ARCH .EQS. "VAX" .AND. COMPILER .EQS. "DECC" .AND. P2 .NES. "DEBUG"
+$   THEN
+$     CC5 = CC + " /OPTIMIZE=NODISJOINT"
+$     CC5_DIFFERENT = 1
+$   ELSE
+$     CC5 = CC
+$     CC5_DIFFERENT = 0
+$   ENDIF
+$   CC4 = CC - CCDISABLEWARNINGS + CC4DISABLEWARNINGS
+$   CC6 = CC - CCDISABLEWARNINGS + CC6DISABLEWARNINGS
+$!
+$!  Show user the result
+$!
+$   WRITE/SYMBOL SYS$OUTPUT "Main C Compiling Command: ",CC
+$!
+$!  Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$!  Tell The User We Don't Know What They Want.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The Option ",P3," Is Invalid.  The Valid Options Are:"
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "    VAXC  :  To Compile With VAX C."
+$   WRITE SYS$OUTPUT "    DECC  :  To Compile With DEC C."
+$   WRITE SYS$OUTPUT "    GNUC  :  To Compile With GNU C."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Time To EXIT.
+$!
+$   EXIT
+$!
+$! End The Valid Argument Check.
+$!
+$ ENDIF
+$!
+$! Build a MACRO command for the architecture at hand
+$!
+$ IF ARCH .EQS. "VAX" THEN MACRO = "MACRO/''DEBUGGER'"
+$ IF ARCH .NES. "VAX" THEN MACRO = "MACRO/MIGRATION/''DEBUGGER'/''MACRO_OPTIMIZE'"
+$!
+$!  Show user the result
+$!
+$   WRITE/SYMBOL SYS$OUTPUT "Main MACRO Compiling Command: ",MACRO
+$!
+$! Time to check the contents, and to make sure we get the correct library.
+$!
+$ IF P4.EQS."SOCKETSHR" .OR. P4.EQS."MULTINET" .OR. P4.EQS."UCX" -
+     .OR. P4.EQS."TCPIP" .OR. P4.EQS."NONE"
+$ THEN
+$!
+$!  Check to see if SOCKETSHR was chosen
+$!
+$   IF P4.EQS."SOCKETSHR"
+$   THEN
+$!
+$!    Set the library to use SOCKETSHR
+$!
+$     TCPIP_LIB = ",SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
+$!
+$!    Done with SOCKETSHR
+$!
+$   ENDIF
+$!
+$!  Check to see if MULTINET was chosen
+$!
+$   IF P4.EQS."MULTINET"
+$   THEN
+$!
+$!    Set the library to use UCX emulation.
+$!
+$     P4 = "UCX"
+$!
+$!    Done with MULTINET
+$!
+$   ENDIF
+$!
+$!  Check to see if UCX was chosen
+$!
+$   IF P4.EQS."UCX"
+$   THEN
+$!
+$!    Set the library to use UCX.
+$!
+$     TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
+$     IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
+$     THEN
+$       TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS"
+$     ELSE
+$       IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
+	  TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS"
+$     ENDIF
+$!
+$!    Done with UCX
+$!
+$   ENDIF
+$!
+$!  Check to see if TCPIP was chosen
+$!
+$   IF P4.EQS."TCPIP"
+$   THEN
+$!
+$!    Set the library to use TCPIP (post UCX).
+$!
+$     TCPIP_LIB = ",SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
+$!
+$!    Done with TCPIP
+$!
+$   ENDIF
+$!
+$!  Check to see if NONE was chosen
+$!
+$   IF P4.EQS."NONE"
+$   THEN
+$!
+$!    Do not use a TCPIP library.
+$!
+$     TCPIP_LIB = ""
+$!
+$!    Done with TCPIP
+$!
+$   ENDIF
+$!
+$!  Print info
+$!
+$   WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB- ","
+$!
+$!  Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$!  Tell The User We Don't Know What They Want.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The Option ",P4," Is Invalid.  The Valid Options Are:"
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "    SOCKETSHR  :  To link with SOCKETSHR TCP/IP library."
+$   WRITE SYS$OUTPUT "    UCX        :  To link with UCX TCP/IP library."
+$   WRITE SYS$OUTPUT "    TCPIP      :  To link with TCPIP (post UCX) TCP/IP library."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Time To EXIT.
+$!
+$   EXIT
+$!
+$!  Done with TCP/IP libraries
+$!
+$ ENDIF
+$!
+$! Check if the user wanted to compile just a subset of all the encryption
+$! methods.
+$!
+$ IF P6 .NES. ""
+$ THEN
+$   ENCRYPT_TYPES = P6
+$ ENDIF
+$!
+$!  Time To RETURN...
+$!
+$ RETURN
+$!
+$ INITIALISE:
+$!
+$! Save old value of the logical name OPENSSL
+$!
+$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
+$!
+$! Save directory information
+$!
+$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
+$ __HERE = F$EDIT(__HERE,"UPCASE")
+$ __TOP = __HERE - "CRYPTO]"
+$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
+$!
+$! Set up the logical name OPENSSL to point at the include directory
+$!
+$ DEFINE OPENSSL/NOLOG '__INCLUDE'
+$!
+$! Done
+$!
+$ RETURN
+$!
+$ CLEANUP:
+$!
+$! Restore the logical name OPENSSL if it had a value
+$!
+$ IF __SAVE_OPENSSL .EQS. ""
+$ THEN
+$   DEASSIGN OPENSSL
+$ ELSE
+$   DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL'
+$ ENDIF
+$!
+$! Done
+$!
+$ RETURN
diff --git a/openssl/crypto/crypto.h b/openssl/crypto/crypto.h
new file mode 100644
index 0000000..b0360ce
--- /dev/null
+++ b/openssl/crypto/crypto.h
@@ -0,0 +1,575 @@
+/* crypto/crypto.h */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_CRYPTO_H
+#define HEADER_CRYPTO_H
+
+#include <stdlib.h>
+
+#include <openssl/e_os2.h>
+
+#ifndef OPENSSL_NO_FP_API
+#include <stdio.h>
+#endif
+
+#include <openssl/stack.h>
+#include <openssl/safestack.h>
+#include <openssl/opensslv.h>
+#include <openssl/ossl_typ.h>
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+/* Resolve problems on some operating systems with symbol names that clash
+   one way or another */
+#include <openssl/symhacks.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Backward compatibility to SSLeay */
+/* This is more to be used to check the correct DLL is being used
+ * in the MS world. */
+#define SSLEAY_VERSION_NUMBER	OPENSSL_VERSION_NUMBER
+#define SSLEAY_VERSION		0
+/* #define SSLEAY_OPTIONS	1 no longer supported */
+#define SSLEAY_CFLAGS		2
+#define SSLEAY_BUILT_ON		3
+#define SSLEAY_PLATFORM		4
+#define SSLEAY_DIR		5
+
+/* Already declared in ossl_typ.h */
+#if 0
+typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
+/* Called when a new object is created */
+typedef int CRYPTO_EX_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+					int idx, long argl, void *argp);
+/* Called when an object is free()ed */
+typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+					int idx, long argl, void *argp);
+/* Called when we need to dup an object */
+typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, 
+					int idx, long argl, void *argp);
+#endif
+
+/* A generic structure to pass assorted data in a expandable way */
+typedef struct openssl_item_st
+	{
+	int code;
+	void *value;		/* Not used for flag attributes */
+	size_t value_size;	/* Max size of value for output, length for input */
+	size_t *value_length;	/* Returned length of value for output */
+	} OPENSSL_ITEM;
+
+
+/* When changing the CRYPTO_LOCK_* list, be sure to maintin the text lock
+ * names in cryptlib.c
+ */
+
+#define	CRYPTO_LOCK_ERR			1
+#define	CRYPTO_LOCK_EX_DATA		2
+#define	CRYPTO_LOCK_X509		3
+#define	CRYPTO_LOCK_X509_INFO		4
+#define	CRYPTO_LOCK_X509_PKEY		5
+#define CRYPTO_LOCK_X509_CRL		6
+#define CRYPTO_LOCK_X509_REQ		7
+#define CRYPTO_LOCK_DSA			8
+#define CRYPTO_LOCK_RSA			9
+#define CRYPTO_LOCK_EVP_PKEY		10
+#define CRYPTO_LOCK_X509_STORE		11
+#define CRYPTO_LOCK_SSL_CTX		12
+#define CRYPTO_LOCK_SSL_CERT		13
+#define CRYPTO_LOCK_SSL_SESSION		14
+#define CRYPTO_LOCK_SSL_SESS_CERT	15
+#define CRYPTO_LOCK_SSL			16
+#define CRYPTO_LOCK_SSL_METHOD		17
+#define CRYPTO_LOCK_RAND		18
+#define CRYPTO_LOCK_RAND2		19
+#define CRYPTO_LOCK_MALLOC		20
+#define CRYPTO_LOCK_BIO			21
+#define CRYPTO_LOCK_GETHOSTBYNAME	22
+#define CRYPTO_LOCK_GETSERVBYNAME	23
+#define CRYPTO_LOCK_READDIR		24
+#define CRYPTO_LOCK_RSA_BLINDING	25
+#define CRYPTO_LOCK_DH			26
+#define CRYPTO_LOCK_MALLOC2		27
+#define CRYPTO_LOCK_DSO			28
+#define CRYPTO_LOCK_DYNLOCK		29
+#define CRYPTO_LOCK_ENGINE		30
+#define CRYPTO_LOCK_UI			31
+#define CRYPTO_LOCK_ECDSA               32
+#define CRYPTO_LOCK_EC			33
+#define CRYPTO_LOCK_ECDH		34
+#define CRYPTO_LOCK_BN  		35
+#define CRYPTO_LOCK_EC_PRE_COMP		36
+#define CRYPTO_LOCK_STORE		37
+#define CRYPTO_LOCK_COMP		38
+#define CRYPTO_LOCK_FIPS		39
+#define CRYPTO_LOCK_FIPS2		40
+#define CRYPTO_NUM_LOCKS		41
+
+#define CRYPTO_LOCK		1
+#define CRYPTO_UNLOCK		2
+#define CRYPTO_READ		4
+#define CRYPTO_WRITE		8
+
+#ifndef OPENSSL_NO_LOCKING
+#ifndef CRYPTO_w_lock
+#define CRYPTO_w_lock(type)	\
+	CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
+#define CRYPTO_w_unlock(type)	\
+	CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
+#define CRYPTO_r_lock(type)	\
+	CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__)
+#define CRYPTO_r_unlock(type)	\
+	CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__)
+#define CRYPTO_add(addr,amount,type)	\
+	CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__)
+#endif
+#else
+#define CRYPTO_w_lock(a)
+#define CRYPTO_w_unlock(a)
+#define CRYPTO_r_lock(a)
+#define CRYPTO_r_unlock(a)
+#define CRYPTO_add(a,b,c)	((*(a))+=(b))
+#endif
+
+/* Some applications as well as some parts of OpenSSL need to allocate
+   and deallocate locks in a dynamic fashion.  The following typedef
+   makes this possible in a type-safe manner.  */
+/* struct CRYPTO_dynlock_value has to be defined by the application. */
+typedef struct
+	{
+	int references;
+	struct CRYPTO_dynlock_value *data;
+	} CRYPTO_dynlock;
+
+
+/* The following can be used to detect memory leaks in the SSLeay library.
+ * It used, it turns on malloc checking */
+
+#define CRYPTO_MEM_CHECK_OFF	0x0	/* an enume */
+#define CRYPTO_MEM_CHECK_ON	0x1	/* a bit */
+#define CRYPTO_MEM_CHECK_ENABLE	0x2	/* a bit */
+#define CRYPTO_MEM_CHECK_DISABLE 0x3	/* an enume */
+
+/* The following are bit values to turn on or off options connected to the
+ * malloc checking functionality */
+
+/* Adds time to the memory checking information */
+#define V_CRYPTO_MDEBUG_TIME	0x1 /* a bit */
+/* Adds thread number to the memory checking information */
+#define V_CRYPTO_MDEBUG_THREAD	0x2 /* a bit */
+
+#define V_CRYPTO_MDEBUG_ALL (V_CRYPTO_MDEBUG_TIME | V_CRYPTO_MDEBUG_THREAD)
+
+
+/* predec of the BIO type */
+typedef struct bio_st BIO_dummy;
+
+struct crypto_ex_data_st
+	{
+	STACK_OF(void) *sk;
+	int dummy; /* gcc is screwing up this data structure :-( */
+	};
+DECLARE_STACK_OF(void)
+
+/* This stuff is basically class callback functions
+ * The current classes are SSL_CTX, SSL, SSL_SESSION, and a few more */
+
+typedef struct crypto_ex_data_func_st
+	{
+	long argl;	/* Arbitary long */
+	void *argp;	/* Arbitary void * */
+	CRYPTO_EX_new *new_func;
+	CRYPTO_EX_free *free_func;
+	CRYPTO_EX_dup *dup_func;
+	} CRYPTO_EX_DATA_FUNCS;
+
+DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS)
+
+/* Per class, we have a STACK of CRYPTO_EX_DATA_FUNCS for each CRYPTO_EX_DATA
+ * entry.
+ */
+
+#define CRYPTO_EX_INDEX_BIO		0
+#define CRYPTO_EX_INDEX_SSL		1
+#define CRYPTO_EX_INDEX_SSL_CTX		2
+#define CRYPTO_EX_INDEX_SSL_SESSION	3
+#define CRYPTO_EX_INDEX_X509_STORE	4
+#define CRYPTO_EX_INDEX_X509_STORE_CTX	5
+#define CRYPTO_EX_INDEX_RSA		6
+#define CRYPTO_EX_INDEX_DSA		7
+#define CRYPTO_EX_INDEX_DH		8
+#define CRYPTO_EX_INDEX_ENGINE		9
+#define CRYPTO_EX_INDEX_X509		10
+#define CRYPTO_EX_INDEX_UI		11
+#define CRYPTO_EX_INDEX_ECDSA		12
+#define CRYPTO_EX_INDEX_ECDH		13
+#define CRYPTO_EX_INDEX_COMP		14
+#define CRYPTO_EX_INDEX_STORE		15
+
+/* Dynamically assigned indexes start from this value (don't use directly, use
+ * via CRYPTO_ex_data_new_class). */
+#define CRYPTO_EX_INDEX_USER		100
+
+
+/* This is the default callbacks, but we can have others as well:
+ * this is needed in Win32 where the application malloc and the
+ * library malloc may not be the same.
+ */
+#define CRYPTO_malloc_init()	CRYPTO_set_mem_functions(\
+	malloc, realloc, free)
+
+#if defined CRYPTO_MDEBUG_ALL || defined CRYPTO_MDEBUG_TIME || defined CRYPTO_MDEBUG_THREAD
+# ifndef CRYPTO_MDEBUG /* avoid duplicate #define */
+#  define CRYPTO_MDEBUG
+# endif
+#endif
+
+/* Set standard debugging functions (not done by default
+ * unless CRYPTO_MDEBUG is defined) */
+#define CRYPTO_malloc_debug_init()	do {\
+	CRYPTO_set_mem_debug_functions(\
+		CRYPTO_dbg_malloc,\
+		CRYPTO_dbg_realloc,\
+		CRYPTO_dbg_free,\
+		CRYPTO_dbg_set_options,\
+		CRYPTO_dbg_get_options);\
+	} while(0)
+
+int CRYPTO_mem_ctrl(int mode);
+int CRYPTO_is_mem_check_on(void);
+
+/* for applications */
+#define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON)
+#define MemCheck_stop()	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF)
+
+/* for library-internal use */
+#define MemCheck_on()	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE)
+#define MemCheck_off()	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE)
+#define is_MemCheck_on() CRYPTO_is_mem_check_on()
+
+#define OPENSSL_malloc(num)	CRYPTO_malloc((int)num,__FILE__,__LINE__)
+#define OPENSSL_strdup(str)	CRYPTO_strdup((str),__FILE__,__LINE__)
+#define OPENSSL_realloc(addr,num) \
+	CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__)
+#define OPENSSL_realloc_clean(addr,old_num,num) \
+	CRYPTO_realloc_clean(addr,old_num,num,__FILE__,__LINE__)
+#define OPENSSL_remalloc(addr,num) \
+	CRYPTO_remalloc((char **)addr,(int)num,__FILE__,__LINE__)
+#define OPENSSL_freeFunc	CRYPTO_free
+#define OPENSSL_free(addr)	CRYPTO_free(addr)
+
+#define OPENSSL_malloc_locked(num) \
+	CRYPTO_malloc_locked((int)num,__FILE__,__LINE__)
+#define OPENSSL_free_locked(addr) CRYPTO_free_locked(addr)
+
+
+const char *SSLeay_version(int type);
+unsigned long SSLeay(void);
+
+int OPENSSL_issetugid(void);
+
+/* An opaque type representing an implementation of "ex_data" support */
+typedef struct st_CRYPTO_EX_DATA_IMPL	CRYPTO_EX_DATA_IMPL;
+/* Return an opaque pointer to the current "ex_data" implementation */
+const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void);
+/* Sets the "ex_data" implementation to be used (if it's not too late) */
+int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i);
+/* Get a new "ex_data" class, and return the corresponding "class_index" */
+int CRYPTO_ex_data_new_class(void);
+/* Within a given class, get/register a new index */
+int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
+		CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+		CRYPTO_EX_free *free_func);
+/* Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a given
+ * class (invokes whatever per-class callbacks are applicable) */
+int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+		CRYPTO_EX_DATA *from);
+void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+/* Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular index
+ * (relative to the class type involved) */
+int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val);
+void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad,int idx);
+/* This function cleans up all "ex_data" state. It mustn't be called under
+ * potential race-conditions. */
+void CRYPTO_cleanup_all_ex_data(void);
+
+int CRYPTO_get_new_lockid(char *name);
+
+int CRYPTO_num_locks(void); /* return CRYPTO_NUM_LOCKS (shared libs!) */
+void CRYPTO_lock(int mode, int type,const char *file,int line);
+void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
+					      const char *file,int line));
+void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
+		int line);
+void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
+					      const char *file, int line));
+int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
+					  const char *file,int line);
+
+/* Don't use this structure directly. */
+typedef struct crypto_threadid_st
+	{
+	void *ptr;
+	unsigned long val;
+	} CRYPTO_THREADID;
+/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
+void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
+void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
+int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *));
+void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *);
+void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
+int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b);
+void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src);
+unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id);
+#ifndef OPENSSL_NO_DEPRECATED
+void CRYPTO_set_id_callback(unsigned long (*func)(void));
+unsigned long (*CRYPTO_get_id_callback(void))(void);
+unsigned long CRYPTO_thread_id(void);
+#endif
+
+const char *CRYPTO_get_lock_name(int type);
+int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file,
+		    int line);
+
+int CRYPTO_get_new_dynlockid(void);
+void CRYPTO_destroy_dynlockid(int i);
+struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i);
+void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*dyn_create_function)(const char *file, int line));
+void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line));
+void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)(struct CRYPTO_dynlock_value *l, const char *file, int line));
+struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))(const char *file,int line);
+void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, struct CRYPTO_dynlock_value *l, const char *file,int line);
+void (*CRYPTO_get_dynlock_destroy_callback(void))(struct CRYPTO_dynlock_value *l, const char *file,int line);
+
+/* CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions --
+ * call the latter last if you need different functions */
+int CRYPTO_set_mem_functions(void *(*m)(size_t),void *(*r)(void *,size_t), void (*f)(void *));
+int CRYPTO_set_locked_mem_functions(void *(*m)(size_t), void (*free_func)(void *));
+int CRYPTO_set_mem_ex_functions(void *(*m)(size_t,const char *,int),
+                                void *(*r)(void *,size_t,const char *,int),
+                                void (*f)(void *));
+int CRYPTO_set_locked_mem_ex_functions(void *(*m)(size_t,const char *,int),
+                                       void (*free_func)(void *));
+int CRYPTO_set_mem_debug_functions(void (*m)(void *,int,const char *,int,int),
+				   void (*r)(void *,void *,int,const char *,int,int),
+				   void (*f)(void *,int),
+				   void (*so)(long),
+				   long (*go)(void));
+void CRYPTO_get_mem_functions(void *(**m)(size_t),void *(**r)(void *, size_t), void (**f)(void *));
+void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *));
+void CRYPTO_get_mem_ex_functions(void *(**m)(size_t,const char *,int),
+                                 void *(**r)(void *, size_t,const char *,int),
+                                 void (**f)(void *));
+void CRYPTO_get_locked_mem_ex_functions(void *(**m)(size_t,const char *,int),
+                                        void (**f)(void *));
+void CRYPTO_get_mem_debug_functions(void (**m)(void *,int,const char *,int,int),
+				    void (**r)(void *,void *,int,const char *,int,int),
+				    void (**f)(void *,int),
+				    void (**so)(long),
+				    long (**go)(void));
+
+void *CRYPTO_malloc_locked(int num, const char *file, int line);
+void CRYPTO_free_locked(void *);
+void *CRYPTO_malloc(int num, const char *file, int line);
+char *CRYPTO_strdup(const char *str, const char *file, int line);
+void CRYPTO_free(void *);
+void *CRYPTO_realloc(void *addr,int num, const char *file, int line);
+void *CRYPTO_realloc_clean(void *addr,int old_num,int num,const char *file,
+			   int line);
+void *CRYPTO_remalloc(void *addr,int num, const char *file, int line);
+
+void OPENSSL_cleanse(void *ptr, size_t len);
+
+void CRYPTO_set_mem_debug_options(long bits);
+long CRYPTO_get_mem_debug_options(void);
+
+#define CRYPTO_push_info(info) \
+        CRYPTO_push_info_(info, __FILE__, __LINE__);
+int CRYPTO_push_info_(const char *info, const char *file, int line);
+int CRYPTO_pop_info(void);
+int CRYPTO_remove_all_info(void);
+
+
+/* Default debugging functions (enabled by CRYPTO_malloc_debug_init() macro;
+ * used as default in CRYPTO_MDEBUG compilations): */
+/* The last argument has the following significance:
+ *
+ * 0:	called before the actual memory allocation has taken place
+ * 1:	called after the actual memory allocation has taken place
+ */
+void CRYPTO_dbg_malloc(void *addr,int num,const char *file,int line,int before_p);
+void CRYPTO_dbg_realloc(void *addr1,void *addr2,int num,const char *file,int line,int before_p);
+void CRYPTO_dbg_free(void *addr,int before_p);
+/* Tell the debugging code about options.  By default, the following values
+ * apply:
+ *
+ * 0:                           Clear all options.
+ * V_CRYPTO_MDEBUG_TIME (1):    Set the "Show Time" option.
+ * V_CRYPTO_MDEBUG_THREAD (2):  Set the "Show Thread Number" option.
+ * V_CRYPTO_MDEBUG_ALL (3):     1 + 2
+ */
+void CRYPTO_dbg_set_options(long bits);
+long CRYPTO_dbg_get_options(void);
+
+
+#ifndef OPENSSL_NO_FP_API
+void CRYPTO_mem_leaks_fp(FILE *);
+#endif
+void CRYPTO_mem_leaks(struct bio_st *bio);
+/* unsigned long order, char *file, int line, int num_bytes, char *addr */
+typedef void *CRYPTO_MEM_LEAK_CB(unsigned long, const char *, int, int, void *);
+void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb);
+
+/* die if we have to */
+void OpenSSLDie(const char *file,int line,const char *assertion);
+#define OPENSSL_assert(e)       (void)((e) ? 0 : (OpenSSLDie(__FILE__, __LINE__, #e),1))
+
+unsigned long *OPENSSL_ia32cap_loc(void);
+#define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc()))
+int OPENSSL_isservice(void);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_CRYPTO_strings(void);
+
+/* Error codes for the CRYPTO functions. */
+
+/* Function codes. */
+#define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX		 100
+#define CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID		 103
+#define CRYPTO_F_CRYPTO_GET_NEW_LOCKID			 101
+#define CRYPTO_F_CRYPTO_SET_EX_DATA			 102
+#define CRYPTO_F_DEF_ADD_INDEX				 104
+#define CRYPTO_F_DEF_GET_CLASS				 105
+#define CRYPTO_F_INT_DUP_EX_DATA			 106
+#define CRYPTO_F_INT_FREE_EX_DATA			 107
+#define CRYPTO_F_INT_NEW_EX_DATA			 108
+
+/* Reason codes. */
+#define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK		 100
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/cversion.c b/openssl/crypto/cversion.c
new file mode 100644
index 0000000..ea9f25f
--- /dev/null
+++ b/openssl/crypto/cversion.c
@@ -0,0 +1,117 @@
+/* crypto/cversion.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "cryptlib.h"
+
+#ifndef NO_WINDOWS_BRAINDEATH
+#include "buildinf.h"
+#endif
+
+const char *SSLeay_version(int t)
+	{
+	if (t == SSLEAY_VERSION)
+		return OPENSSL_VERSION_TEXT;
+	if (t == SSLEAY_BUILT_ON)
+		{
+#ifdef DATE
+		static char buf[sizeof(DATE)+11];
+
+		BIO_snprintf(buf,sizeof buf,"built on: %s",DATE);
+		return(buf);
+#else
+		return("built on: date not available");
+#endif
+		}
+	if (t == SSLEAY_CFLAGS)
+		{
+#ifdef CFLAGS
+		static char buf[sizeof(CFLAGS)+11];
+
+		BIO_snprintf(buf,sizeof buf,"compiler: %s",CFLAGS);
+		return(buf);
+#else
+		return("compiler: information not available");
+#endif
+		}
+	if (t == SSLEAY_PLATFORM)
+		{
+#ifdef PLATFORM
+		static char buf[sizeof(PLATFORM)+11];
+
+		BIO_snprintf(buf,sizeof buf,"platform: %s", PLATFORM);
+		return(buf);
+#else
+		return("platform: information not available");
+#endif
+		}
+	if (t == SSLEAY_DIR)
+		{
+#ifdef OPENSSLDIR
+		return "OPENSSLDIR: \"" OPENSSLDIR "\"";
+#else
+		return "OPENSSLDIR: N/A";
+#endif
+		}
+	return("not available");
+	}
+
+unsigned long SSLeay(void)
+	{
+	return(SSLEAY_VERSION_NUMBER);
+	}
+
diff --git a/openssl/crypto/des/COPYRIGHT b/openssl/crypto/des/COPYRIGHT
new file mode 100644
index 0000000..5469e1e
--- /dev/null
+++ b/openssl/crypto/des/COPYRIGHT
@@ -0,0 +1,50 @@
+Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+All rights reserved.
+
+This package is an DES implementation written by Eric Young (eay@cryptsoft.com).
+The implementation was written so as to conform with MIT's libdes.
+
+This library is free for commercial and non-commercial use as long as
+the following conditions are aheared to.  The following conditions
+apply to all code found in this distribution.
+
+Copyright remains Eric Young's, and as such any Copyright notices in
+the code are not to be removed.
+If this package is used in a product, Eric Young should be given attribution
+as the author of that the SSL library.  This can be in the form of a textual
+message at program startup or in documentation (online or textual) provided
+with the package.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+   must display the following acknowledgement:
+   This product includes software developed by Eric Young (eay@cryptsoft.com)
+
+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+The license and distribution terms for any publically available version or
+derivative of this code cannot be changed.  i.e. this code cannot simply be
+copied and put under another distrubution license
+[including the GNU Public License.]
+
+The reason behind this being stated in this direct manner is past
+experience in code simply being copied and the attribution removed
+from it and then being distributed as part of other packages. This
+implementation was a non-trivial and unpaid effort.
diff --git a/openssl/crypto/des/DES.pm b/openssl/crypto/des/DES.pm
new file mode 100644
index 0000000..6a175b6
--- /dev/null
+++ b/openssl/crypto/des/DES.pm
@@ -0,0 +1,19 @@
+package DES;
+
+require Exporter;
+require DynaLoader;
+@ISA = qw(Exporter DynaLoader);
+# Items to export into callers namespace by default
+# (move infrequently used names to @EXPORT_OK below)
+@EXPORT = qw(
+);
+# Other items we are prepared to export if requested
+@EXPORT_OK = qw(
+crypt
+);
+
+# Preloaded methods go here.  Autoload methods go after __END__, and are
+# processed by the autosplit program.
+bootstrap DES;
+1;
+__END__
diff --git a/openssl/crypto/des/DES.xs b/openssl/crypto/des/DES.xs
new file mode 100644
index 0000000..b8050b9
--- /dev/null
+++ b/openssl/crypto/des/DES.xs
@@ -0,0 +1,268 @@
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include "des.h"
+
+#define deschar	char
+static STRLEN len;
+
+static int
+not_here(s)
+char *s;
+{
+    croak("%s not implemented on this architecture", s);
+    return -1;
+}
+
+MODULE = DES	PACKAGE = DES	PREFIX = des_
+
+char *
+des_crypt(buf,salt)
+	char *	buf
+	char *	salt
+
+void
+des_set_odd_parity(key)
+	des_cblock *	key
+PPCODE:
+	{
+	SV *s;
+
+	s=sv_newmortal();
+	sv_setpvn(s,(char *)key,8);
+	des_set_odd_parity((des_cblock *)SvPV(s,na));
+	PUSHs(s);
+	}
+
+int
+des_is_weak_key(key)
+	des_cblock *	key
+
+des_key_schedule
+des_set_key(key)
+	des_cblock *	key
+CODE:
+	des_set_key(key,RETVAL);
+OUTPUT:
+RETVAL
+
+des_cblock
+des_ecb_encrypt(input,ks,encrypt)
+	des_cblock *	input
+	des_key_schedule *	ks
+	int	encrypt
+CODE:
+	des_ecb_encrypt(input,&RETVAL,*ks,encrypt);
+OUTPUT:
+RETVAL
+
+void
+des_cbc_encrypt(input,ks,ivec,encrypt)
+	char *	input
+	des_key_schedule *	ks
+	des_cblock *	ivec
+	int	encrypt
+PPCODE:
+	{
+	SV *s;
+	STRLEN len,l;
+	char *c;
+
+	l=SvCUR(ST(0));
+	len=((((unsigned long)l)+7)/8)*8;
+	s=sv_newmortal();
+	sv_setpvn(s,"",0);
+	SvGROW(s,len);
+	SvCUR_set(s,len);
+	c=(char *)SvPV(s,na);
+	des_cbc_encrypt((des_cblock *)input,(des_cblock *)c,
+		l,*ks,ivec,encrypt);
+	sv_setpvn(ST(2),(char *)c[len-8],8);
+	PUSHs(s);
+	}
+
+void
+des_cbc3_encrypt(input,ks1,ks2,ivec1,ivec2,encrypt)
+	char *	input
+	des_key_schedule *	ks1
+	des_key_schedule *	ks2
+	des_cblock *	ivec1
+	des_cblock *	ivec2
+	int	encrypt
+PPCODE:
+	{
+	SV *s;
+	STRLEN len,l;
+
+	l=SvCUR(ST(0));
+	len=((((unsigned long)l)+7)/8)*8;
+	s=sv_newmortal();
+	sv_setpvn(s,"",0);
+	SvGROW(s,len);
+	SvCUR_set(s,len);
+	des_3cbc_encrypt((des_cblock *)input,(des_cblock *)SvPV(s,na),
+		l,*ks1,*ks2,ivec1,ivec2,encrypt);
+	sv_setpvn(ST(3),(char *)ivec1,8);
+	sv_setpvn(ST(4),(char *)ivec2,8);
+	PUSHs(s);
+	}
+
+void
+des_cbc_cksum(input,ks,ivec)
+	char *	input
+	des_key_schedule *	ks
+	des_cblock *	ivec
+PPCODE:
+	{
+	SV *s1,*s2;
+	STRLEN len,l;
+	des_cblock c;
+	unsigned long i1,i2;
+
+	s1=sv_newmortal();
+	s2=sv_newmortal();
+	l=SvCUR(ST(0));
+	des_cbc_cksum((des_cblock *)input,(des_cblock *)c,
+		l,*ks,ivec);
+	i1=c[4]|(c[5]<<8)|(c[6]<<16)|(c[7]<<24);
+	i2=c[0]|(c[1]<<8)|(c[2]<<16)|(c[3]<<24);
+	sv_setiv(s1,i1);
+	sv_setiv(s2,i2);
+	sv_setpvn(ST(2),(char *)c,8);
+	PUSHs(s1);
+	PUSHs(s2);
+	}
+
+void
+des_cfb_encrypt(input,numbits,ks,ivec,encrypt)
+	char *	input
+	int	numbits
+	des_key_schedule *	ks
+	des_cblock *	ivec
+	int	encrypt
+PPCODE:
+	{
+	SV *s;
+	STRLEN len;
+	char *c;
+
+	len=SvCUR(ST(0));
+	s=sv_newmortal();
+	sv_setpvn(s,"",0);
+	SvGROW(s,len);
+	SvCUR_set(s,len);
+	c=(char *)SvPV(s,na);
+	des_cfb_encrypt((unsigned char *)input,(unsigned char *)c,
+		(int)numbits,(long)len,*ks,ivec,encrypt);
+	sv_setpvn(ST(3),(char *)ivec,8);
+	PUSHs(s);
+	}
+
+des_cblock *
+des_ecb3_encrypt(input,ks1,ks2,encrypt)
+	des_cblock *	input
+	des_key_schedule *	ks1
+	des_key_schedule *	ks2
+	int	encrypt
+CODE:
+	{
+	des_cblock c;
+
+	des_ecb3_encrypt((des_cblock *)input,(des_cblock *)&c,
+		*ks1,*ks2,encrypt);
+	RETVAL= &c;
+	}
+OUTPUT:
+RETVAL
+
+void
+des_ofb_encrypt(input,numbits,ks,ivec)
+	unsigned char *	input
+	int	numbits
+	des_key_schedule *	ks
+	des_cblock *	ivec
+PPCODE:
+	{
+	SV *s;
+	STRLEN len,l;
+	unsigned char *c;
+
+	len=SvCUR(ST(0));
+	s=sv_newmortal();
+	sv_setpvn(s,"",0);
+	SvGROW(s,len);
+	SvCUR_set(s,len);
+	c=(unsigned char *)SvPV(s,na);
+	des_ofb_encrypt((unsigned char *)input,(unsigned char *)c,
+		numbits,len,*ks,ivec);
+	sv_setpvn(ST(3),(char *)ivec,8);
+	PUSHs(s);
+	}
+
+void
+des_pcbc_encrypt(input,ks,ivec,encrypt)
+	char *	input
+	des_key_schedule *	ks
+	des_cblock *	ivec
+	int	encrypt
+PPCODE:
+	{
+	SV *s;
+	STRLEN len,l;
+	char *c;
+
+	l=SvCUR(ST(0));
+	len=((((unsigned long)l)+7)/8)*8;
+	s=sv_newmortal();
+	sv_setpvn(s,"",0);
+	SvGROW(s,len);
+	SvCUR_set(s,len);
+	c=(char *)SvPV(s,na);
+	des_pcbc_encrypt((des_cblock *)input,(des_cblock *)c,
+		l,*ks,ivec,encrypt);
+	sv_setpvn(ST(2),(char *)c[len-8],8);
+	PUSHs(s);
+	}
+
+des_cblock *
+des_random_key()
+CODE:
+	{
+	des_cblock c;
+
+	des_random_key(c);
+	RETVAL=&c;
+	}
+OUTPUT:
+RETVAL
+
+des_cblock *
+des_string_to_key(str)
+char *	str
+CODE:
+	{
+	des_cblock c;
+
+	des_string_to_key(str,&c);
+	RETVAL=&c;
+	}
+OUTPUT:
+RETVAL
+
+void
+des_string_to_2keys(str)
+char *	str
+PPCODE:
+	{
+	des_cblock c1,c2;
+	SV *s1,*s2;
+
+	des_string_to_2keys(str,&c1,&c2);
+	EXTEND(sp,2);
+	s1=sv_newmortal();
+	sv_setpvn(s1,(char *)c1,8);
+	s2=sv_newmortal();
+	sv_setpvn(s2,(char *)c2,8);
+	PUSHs(s1);
+	PUSHs(s2);
+	}
diff --git a/openssl/crypto/des/FILES0 b/openssl/crypto/des/FILES0
new file mode 100644
index 0000000..4c7ea2d
--- /dev/null
+++ b/openssl/crypto/des/FILES0
@@ -0,0 +1,96 @@
+/* General stuff */
+COPYRIGHT	- Copyright info.
+MODES.DES	- A description of the features of the different modes of DES.
+FILES		- This file.
+INSTALL		- How to make things compile.
+Imakefile	- For use with kerberos.
+README		- What this package is.
+VERSION		- Which version this is and what was changed.
+KERBEROS	- Kerberos version 4 notes.
+Makefile.PL	- An old makefile to build with perl5, not current.
+Makefile.ssl	- The SSLeay makefile
+Makefile.uni	- The normal unix makefile.
+GNUmakefile	- The makefile for use with glibc.
+makefile.bc	- A Borland C makefile
+times		- Some outputs from 'speed' on some machines.
+vms.com		- For use when compiling under VMS
+
+/* My SunOS des(1) replacement */
+des.c		- des(1) source code.
+des.man		- des(1) manual.
+
+/* Testing and timing programs. */
+destest.c	- Source for libdes.a test program.
+speed.c		- Source for libdes.a timing program.
+rpw.c		- Source for libdes.a testing password reading routines.
+
+/* libdes.a source code */
+des_crypt.man	- libdes.a manual page.
+des.h		- Public libdes.a header file.
+ecb_enc.c	- des_ecb_encrypt() source, this contains the basic DES code.
+ecb3_enc.c	- des_ecb3_encrypt() source.
+cbc_ckm.c	- des_cbc_cksum() source.
+cbc_enc.c	- des_cbc_encrypt() source.
+ncbc_enc.c	- des_cbc_encrypt() that is 'normal' in that it copies
+		  the new iv values back in the passed iv vector.
+ede_enc.c	- des_ede3_cbc_encrypt() cbc mode des using triple DES.
+cbc3_enc.c	- des_3cbc_encrypt() source, don't use this function.
+cfb_enc.c	- des_cfb_encrypt() source.
+cfb64enc.c	- des_cfb64_encrypt() cfb in 64 bit mode but setup to be
+		  used as a stream cipher.
+cfb64ede.c	- des_ede3_cfb64_encrypt() cfb in 64 bit mode but setup to be
+		  used as a stream cipher and using triple DES.
+ofb_enc.c	- des_cfb_encrypt() source.
+ofb64_enc.c	- des_ofb_encrypt() ofb in 64 bit mode but setup to be
+		  used as a stream cipher.
+ofb64ede.c	- des_ede3_ofb64_encrypt() ofb in 64 bit mode but setup to be
+		  used as a stream cipher and using triple DES.
+enc_read.c	- des_enc_read() source.
+enc_writ.c	- des_enc_write() source.
+pcbc_enc.c	- des_pcbc_encrypt() source.
+qud_cksm.c	- quad_cksum() source.
+rand_key.c	- des_random_key() source.
+read_pwd.c	- Source for des_read_password() plus related functions.
+set_key.c	- Source for des_set_key().
+str2key.c	- Covert a string of any length into a key.
+fcrypt.c	- A small, fast version of crypt(3).
+des_locl.h	- Internal libdes.a header file.
+podd.h		- Odd parity tables - used in des_set_key().
+sk.h		- Lookup tables used in des_set_key().
+spr.h		- What is left of the S tables - used in ecb_encrypt().
+des_ver.h	- header file for the external definition of the
+		  version string.
+des.doc		- SSLeay documentation for the library.
+
+/* The perl scripts - you can ignore these files they are only
+ * included for the curious */
+des.pl		- des in perl anyone? des_set_key and des_ecb_encrypt
+		  both done in a perl library.
+testdes.pl	- Testing program for des.pl
+doIP		- Perl script used to develop IP xor/shift code.
+doPC1		- Perl script used to develop PC1 xor/shift code.
+doPC2		- Generates sk.h.
+PC1		- Output of doPC1 should be the same as output from PC1.
+PC2		- used in development of doPC2.
+shifts.pl	- Perl library used by my perl scripts.
+
+/* I started making a perl5 dynamic library for libdes
+ * but did not fully finish, these files are part of that effort. */
+DES.pm
+DES.pod
+DES.xs
+t
+typemap
+
+/* The following are for use with sun RPC implementaions. */
+rpc_des.h
+rpc_enc.c
+
+/* The following are contibuted by Mark Murray <mark@grondar.za>.  They
+ * are not normally built into libdes due to machine specific routines
+ * contained in them.  They are for use in the most recent incarnation of
+ * export kerberos v 4 (eBones). */
+supp.c
+new_rkey.c
+
+
diff --git a/openssl/crypto/des/INSTALL b/openssl/crypto/des/INSTALL
new file mode 100644
index 0000000..8aebdfe
--- /dev/null
+++ b/openssl/crypto/des/INSTALL
@@ -0,0 +1,69 @@
+Check the CC and CFLAGS lines in the makefile
+
+If your C library does not support the times(3) function, change the
+#define TIMES to
+#undef TIMES in speed.c
+If it does, check the HZ value for the times(3) function.
+If your system does not define CLK_TCK it will be assumed to
+be 100.0.
+
+If possible use gcc v 2.7.?
+Turn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc)
+In recent times, some system compilers give better performace.
+
+type 'make'
+
+run './destest' to check things are ok.
+run './rpw' to check the tty code for reading passwords works.
+run './speed' to see how fast those optimisations make the library run :-)
+run './des_opts' to determin the best compile time options.
+
+The output from des_opts should be put in the makefile options and des_enc.c
+should be rebuilt.  For 64 bit computers, do not use the DES_PTR option.
+For the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int'
+and then you can use the 'DES_PTR' option.
+
+The file options.txt has the options listed for best speed on quite a
+few systems.  Look and the options (UNROLL, PTR, RISC2 etc) and then
+turn on the relevant option in the Makefile.
+
+There are some special Makefile targets that make life easier.
+make cc		- standard cc build
+make gcc	- standard gcc build
+make x86-elf	- x86 assembler (elf), linux-elf.
+make x86-out	- x86 assembler (a.out), FreeBSD
+make x86-solaris- x86 assembler
+make x86-bsdi	- x86 assembler (a.out with primative assembler).
+
+If at all possible use the assembler (for Windows NT/95, use
+asm/win32.obj to link with).  The x86 assembler is very very fast.
+
+A make install will by default install
+libdes.a      in /usr/local/lib/libdes.a
+des           in /usr/local/bin/des
+des_crypt.man in /usr/local/man/man3/des_crypt.3
+des.man       in /usr/local/man/man1/des.1
+des.h         in /usr/include/des.h
+
+des(1) should be compatible with sunOS's but I have been unable to
+test it.
+
+These routines should compile on MSDOS, most 32bit and 64bit version
+of Unix (BSD and SYSV) and VMS, without modification.
+The only problems should be #include files that are in the wrong places.
+
+These routines can be compiled under MSDOS.
+I have successfully encrypted files using des(1) under MSDOS and then
+decrypted the files on a SparcStation.
+I have been able to compile and test the routines with
+Microsoft C v 5.1 and Turbo C v 2.0.
+The code in this library is in no way optimised for the 16bit
+operation of MSDOS.
+
+When building for glibc, ignore all of the above and just unpack into
+glibc-1.??/des and then gmake as per normal.
+
+As a final note on performace.  Certain CPUs like sparcs and Alpha often give
+a %10 speed difference depending on the link order.  It is rather anoying
+when one program reports 'x' DES encrypts a second and another reports
+'x*0.9' the speed.
diff --git a/openssl/crypto/des/Imakefile b/openssl/crypto/des/Imakefile
new file mode 100644
index 0000000..1b9b562
--- /dev/null
+++ b/openssl/crypto/des/Imakefile
@@ -0,0 +1,35 @@
+# This Imakefile has not been tested for a while but it should still
+# work when placed in the correct directory in the kerberos v 4 distribution
+
+SRCS=   cbc_cksm.c cbc_enc.c ecb_enc.c pcbc_enc.c \
+        qud_cksm.c rand_key.c read_pwd.c set_key.c str2key.c \
+        enc_read.c enc_writ.c fcrypt.c cfb_enc.c \
+	ecb3_enc.c ofb_enc.c ofb64enc.c
+
+OBJS=   cbc_cksm.o cbc_enc.o ecb_enc.o pcbc_enc.o \
+	qud_cksm.o rand_key.o read_pwd.o set_key.o str2key.o \
+	enc_read.o enc_writ.o fcrypt.o cfb_enc.o \
+	ecb3_enc.o ofb_enc.o ofb64enc.o
+
+GENERAL=COPYRIGHT FILES INSTALL Imakefile README VERSION makefile times \
+	vms.com KERBEROS
+DES=    des.c des.man
+TESTING=destest.c speed.c rpw.c
+LIBDES= des_crypt.man des.h des_locl.h podd.h sk.h spr.h
+
+PERL=   des.pl testdes.pl doIP doPC1 doPC2 PC1 PC2 shifts.pl
+
+CODE=    $(GENERAL) $(DES) $(TESTING) $(SRCS) $(LIBDES) $(PERL)
+
+SRCDIR=$(SRCTOP)/lib/des
+
+DBG= -O
+INCLUDE= -I$(SRCDIR)
+CC= cc
+
+library_obj_rule()
+
+install_library_target(des,$(OBJS),$(SRCS),)
+
+test(destest,libdes.a,)
+test(rpw,libdes.a,)
diff --git a/openssl/crypto/des/KERBEROS b/openssl/crypto/des/KERBEROS
new file mode 100644
index 0000000..f401b10
--- /dev/null
+++ b/openssl/crypto/des/KERBEROS
@@ -0,0 +1,41 @@
+ [ This is an old file, I don't know if it is true anymore
+   but I will leave the file here - eay 21/11/95 ]
+
+To use this library with Bones (kerberos without DES):
+1) Get my modified Bones - eBones.  It can be found on
+   gondwana.ecr.mu.oz.au (128.250.1.63) /pub/athena/eBones-p9.tar.Z
+   and
+   nic.funet.fi (128.214.6.100) /pub/unix/security/Kerberos/eBones-p9.tar.Z
+
+2) Unpack this library in src/lib/des, makeing sure it is version
+   3.00 or greater (libdes.tar.93-10-07.Z).  This versions differences
+   from the version in comp.sources.misc volume 29 patchlevel2.
+   The primarily difference is that it should compile under kerberos :-).
+   It can be found at.
+   ftp.psy.uq.oz.au (130.102.32.1) /pub/DES/libdes.tar.93-10-07.Z
+
+Now do a normal kerberos build and things should work.
+
+One problem I found when I was build on my local sun.
+---
+For sunOS 4.1.1 apply the following patch to src/util/ss/make_commands.c
+
+*** make_commands.c.orig	Fri Jul  3 04:18:35 1987
+--- make_commands.c	Wed May 20 08:47:42 1992
+***************
+*** 98,104 ****
+       if (!rename(o_file, z_file)) {
+  	  if (!vfork()) {
+  	       chdir("/tmp");
+! 	       execl("/bin/ld", "ld", "-o", o_file+5, "-s", "-r", "-n",
+  		     z_file+5, 0);
+  	       perror("/bin/ld");
+  	       _exit(1);
+--- 98,104 ----
+       if (!rename(o_file, z_file)) {
+  	  if (!vfork()) {
+  	       chdir("/tmp");
+! 	       execl("/bin/ld", "ld", "-o", o_file+5, "-s", "-r",
+  		     z_file+5, 0);
+  	       perror("/bin/ld");
+  	       _exit(1);
diff --git a/openssl/crypto/des/Makefile b/openssl/crypto/des/Makefile
new file mode 100644
index 0000000..ae98226
--- /dev/null
+++ b/openssl/crypto/des/Makefile
@@ -0,0 +1,278 @@
+#
+# OpenSSL/crypto/des/Makefile
+#
+
+DIR=	des
+TOP=	../..
+CC=	cc
+CPP=	$(CC) -E
+INCLUDES=-I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+RANLIB=		ranlib
+DES_ENC=	des_enc.o fcrypt_b.o
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+ASFLAGS= $(INCLUDES) $(ASFLAG)
+AFLAGS= $(ASFLAGS)
+
+GENERAL=Makefile
+TEST=destest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=	cbc_cksm.c cbc_enc.c  cfb64enc.c cfb_enc.c  \
+	ecb3_enc.c ecb_enc.c  enc_read.c enc_writ.c \
+	fcrypt.c ofb64enc.c ofb_enc.c  pcbc_enc.c \
+	qud_cksm.c rand_key.c rpc_enc.c  set_key.c  \
+	des_enc.c fcrypt_b.c \
+	xcbc_enc.c \
+	str2key.c  cfb64ede.c ofb64ede.c ede_cbcm_enc.c des_old.c des_old2.c \
+	read2pwd.c
+
+LIBOBJ= set_key.o  ecb_enc.o  cbc_enc.o \
+	ecb3_enc.o cfb64enc.o cfb64ede.o cfb_enc.o  ofb64ede.o \
+	enc_read.o enc_writ.o ofb64enc.o \
+	ofb_enc.o  str2key.o  pcbc_enc.o qud_cksm.o rand_key.o \
+	${DES_ENC} \
+	fcrypt.o xcbc_enc.o rpc_enc.o  cbc_cksm.o \
+	ede_cbcm_enc.o des_old.o des_old2.o read2pwd.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= des.h des_old.h
+HEADER=	des_locl.h rpc_des.h spr.h des_ver.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+des: des.o cbc3_enc.o lib
+	$(CC) $(CFLAGS) -o des des.o cbc3_enc.o $(LIB)
+
+des_enc-sparc.S:	asm/des_enc.m4
+	m4 -B 8192 asm/des_enc.m4 > des_enc-sparc.S
+
+des-586.s:	asm/des-586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
+	$(PERL) asm/des-586.pl $(PERLASM_SCHEME) $(CFLAGS) > $@
+crypt586.s:	asm/crypt586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
+	$(PERL) asm/crypt586.pl $(PERLASM_SCHEME) $(CFLAGS) > $@
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+# We need to use force because 'install' matches 'INSTALL' on case
+# insensitive systems
+FRC.install:
+install: FRC.install
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.s *.o *.obj des lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+cbc_cksm.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+cbc_cksm.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+cbc_cksm.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+cbc_cksm.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+cbc_cksm.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+cbc_cksm.o: cbc_cksm.c des_locl.h
+cbc_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+cbc_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+cbc_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+cbc_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+cbc_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+cbc_enc.o: cbc_enc.c des_locl.h ncbc_enc.c
+cfb64ede.o: ../../e_os.h ../../include/openssl/des.h
+cfb64ede.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
+cfb64ede.o: ../../include/openssl/opensslconf.h
+cfb64ede.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+cfb64ede.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+cfb64ede.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+cfb64ede.o: cfb64ede.c des_locl.h
+cfb64enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+cfb64enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+cfb64enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+cfb64enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+cfb64enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+cfb64enc.o: cfb64enc.c des_locl.h
+cfb_enc.o: ../../e_os.h ../../include/openssl/des.h
+cfb_enc.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
+cfb_enc.o: ../../include/openssl/opensslconf.h ../../include/openssl/ossl_typ.h
+cfb_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+cfb_enc.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+cfb_enc.o: ../../include/openssl/ui_compat.h cfb_enc.c des_locl.h
+des_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+des_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+des_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+des_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+des_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+des_enc.o: des_enc.c des_locl.h ncbc_enc.c spr.h
+des_old.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+des_old.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+des_old.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+des_old.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+des_old.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+des_old.o: ../../include/openssl/ui_compat.h des_old.c
+des_old2.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+des_old2.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+des_old2.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+des_old2.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+des_old2.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+des_old2.o: ../../include/openssl/ui_compat.h des_old2.c
+ecb3_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+ecb3_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+ecb3_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+ecb3_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ecb3_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+ecb3_enc.o: des_locl.h ecb3_enc.c
+ecb_enc.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+ecb_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+ecb_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+ecb_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ecb_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ecb_enc.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+ecb_enc.o: ../../include/openssl/ui_compat.h des_locl.h des_ver.h ecb_enc.c
+ede_cbcm_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+ede_cbcm_enc.o: ../../include/openssl/e_os2.h
+ede_cbcm_enc.o: ../../include/openssl/opensslconf.h
+ede_cbcm_enc.o: ../../include/openssl/ossl_typ.h
+ede_cbcm_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ede_cbcm_enc.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+ede_cbcm_enc.o: ../../include/openssl/ui_compat.h des_locl.h ede_cbcm_enc.c
+enc_read.o: ../../e_os.h ../../include/openssl/bio.h
+enc_read.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+enc_read.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+enc_read.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+enc_read.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+enc_read.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+enc_read.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+enc_read.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+enc_read.o: ../../include/openssl/ui_compat.h ../cryptlib.h des_locl.h
+enc_read.o: enc_read.c
+enc_writ.o: ../../e_os.h ../../include/openssl/bio.h
+enc_writ.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+enc_writ.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+enc_writ.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+enc_writ.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+enc_writ.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+enc_writ.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+enc_writ.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+enc_writ.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+enc_writ.o: ../cryptlib.h des_locl.h enc_writ.c
+fcrypt.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+fcrypt.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+fcrypt.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+fcrypt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fcrypt.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+fcrypt.o: des_locl.h fcrypt.c
+fcrypt_b.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+fcrypt_b.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+fcrypt_b.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+fcrypt_b.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fcrypt_b.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+fcrypt_b.o: des_locl.h fcrypt_b.c
+ofb64ede.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+ofb64ede.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+ofb64ede.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+ofb64ede.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ofb64ede.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+ofb64ede.o: des_locl.h ofb64ede.c
+ofb64enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+ofb64enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+ofb64enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+ofb64enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ofb64enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+ofb64enc.o: des_locl.h ofb64enc.c
+ofb_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+ofb_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+ofb_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+ofb_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ofb_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+ofb_enc.o: des_locl.h ofb_enc.c
+pcbc_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+pcbc_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+pcbc_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+pcbc_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+pcbc_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+pcbc_enc.o: des_locl.h pcbc_enc.c
+qud_cksm.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+qud_cksm.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+qud_cksm.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+qud_cksm.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+qud_cksm.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+qud_cksm.o: des_locl.h qud_cksm.c
+rand_key.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+rand_key.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+rand_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+rand_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+rand_key.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+rand_key.o: ../../include/openssl/ui_compat.h rand_key.c
+read2pwd.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+read2pwd.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
+read2pwd.o: ../../include/openssl/opensslconf.h
+read2pwd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+read2pwd.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+read2pwd.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+read2pwd.o: ../../include/openssl/ui_compat.h read2pwd.c
+rpc_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+rpc_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+rpc_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+rpc_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rpc_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+rpc_enc.o: des_locl.h des_ver.h rpc_des.h rpc_enc.c
+set_key.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+set_key.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+set_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+set_key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+set_key.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+set_key.o: des_locl.h set_key.c
+str2key.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+str2key.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
+str2key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+str2key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+str2key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+str2key.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+str2key.o: des_locl.h str2key.c
+xcbc_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+xcbc_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+xcbc_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+xcbc_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+xcbc_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+xcbc_enc.o: des_locl.h xcbc_enc.c
diff --git a/openssl/crypto/des/README b/openssl/crypto/des/README
new file mode 100644
index 0000000..621a5ab
--- /dev/null
+++ b/openssl/crypto/des/README
@@ -0,0 +1,54 @@
+
+		libdes, Version 4.01 10-Jan-97
+
+		Copyright (c) 1997, Eric Young
+			  All rights reserved.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms specified in COPYRIGHT.
+    
+--
+The primary ftp site for this library is
+ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz
+libdes is now also shipped with SSLeay.  Primary ftp site of
+ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz
+
+The best way to build this library is to build it as part of SSLeay.
+
+This kit builds a DES encryption library and a DES encryption program.
+It supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb,
+triple cfb, desx, and MIT's pcbc encryption modes and also has a fast
+implementation of crypt(3).
+It contains support routines to read keys from a terminal,
+generate a random key, generate a key from an arbitrary length string,
+read/write encrypted data from/to a file descriptor.
+
+The implementation was written so as to conform with the manual entry
+for the des_crypt(3) library routines from MIT's project Athena.
+
+destest should be run after compilation to test the des routines.
+rpw should be run after compilation to test the read password routines.
+The des program is a replacement for the sun des command.  I believe it
+conforms to the sun version.
+
+The Imakefile is setup for use in the kerberos distribution.
+
+These routines are best compiled with gcc or any other good
+optimising compiler.
+Just turn you optimiser up to the highest settings and run destest
+after the build to make sure everything works.
+
+I believe these routines are close to the fastest and most portable DES
+routines that use small lookup tables (4.5k) that are publicly available.
+The fcrypt routine is faster than ufc's fcrypt (when compiling with
+gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines
+(on a sun3/260 168 vs 336).  It is a function of CPU on chip cache size.
+[ 10-Jan-97 and a function of an incorrect speed testing program in
+  ufc which gave much better test figures that reality ].
+
+It is worth noting that on sparc and Alpha CPUs, performance of the DES
+library can vary by upto %10 due to the positioning of files after application
+linkage.
+
+Eric Young (eay@cryptsoft.com)
+
diff --git a/openssl/crypto/des/VERSION b/openssl/crypto/des/VERSION
new file mode 100644
index 0000000..c7d0154
--- /dev/null
+++ b/openssl/crypto/des/VERSION
@@ -0,0 +1,412 @@
+	Fixed the weak key values which were wrong :-(
+	Defining SIGACTION causes sigaction() to be used instead of signal().
+	SIGUSR1/SIGUSR2 are no longer mapped in the read tty stuff because it
+	can cause problems.  This should hopefully not affect normal
+	applications.
+
+Version 4.04
+	Fixed a few tests in destest.  Also added x86 assember for
+	des_ncbc_encrypt() which is the standard cbc mode function.
+	This makes a very very large performace difference.
+	Ariel Glenn ariel@columbia.edu reports that the terminal
+	'turn echo off' can return (errno == EINVAL) under solaris
+	when redirection is used.  So I now catch that as well as ENOTTY.
+
+
+Version 4.03
+	Left a static out of enc_write.c, which caused to buffer to be
+	continiously malloc()ed.  Does anyone use these functions?  I keep
+	on feeling like removing them since I only had these in there
+	for a version of kerberised login.  Anyway, this was pointed out
+	by Theo de Raadt <deraadt@cvs.openbsd.org>
+	The 'n' bit ofb code was wrong, it was not shifting the shift
+	register. It worked correctly for n == 64.  Thanks to
+	Gigi Ankeny <Gigi.Ankeny@Eng.Sun.COM> for pointing this one out.
+
+Version 4.02
+	I was doing 'if (memcmp(weak_keys[i],key,sizeof(key)) == 0)'
+	when checking for weak keys which is wrong :-(, pointed out by
+	Markus F.X.J. Oberhumer <markus.oberhumer@jk.uni-linz.ac.at>.
+
+Version 4.01
+	Even faster inner loop in the DES assembler for x86 and a modification
+	for IP/FP which is faster on x86.  Both of these changes are
+	from Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>.  His
+	changes make the assembler run %40 faster on a pentium.  This is just
+	a case of getting the instruction sequence 'just right'.
+	All credit to 'Svend' :-)
+	Quite a few special x86 'make' targets.
+	A libdes-l (lite) distribution.
+
+Version 4.00
+	After a bit of a pause, I'll up the major version number since this
+	is mostly a performace release.  I've added x86 assembler and
+	added more options for performance.  A %28 speedup for gcc 
+	on a pentium and the assembler is a %50 speedup.
+	MIPS CPU's, sparc and Alpha are the main CPU's with speedups.
+	Run des_opts to work out which options should be used.
+	DES_RISC1/DES_RISC2 use alternative inner loops which use
+	more registers but should give speedups on any CPU that does
+	dual issue (pentium).  DES_UNROLL unrolls the inner loop,
+	which costs in code size.
+
+Version 3.26
+	I've finally removed one of the shifts in D_ENCRYPT.  This
+	meant I've changed the des_SPtrans table (spr.h), the set_key()
+	function and some things in des_enc.c.  This has definitly
+	made things faster :-).  I've known about this one for some
+	time but I've been too lazy to follow it up :-).
+	Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^..
+	instead of L^=((..)|(..)|(..)..  This should save a register at
+	least.
+	Assember for x86.  The file to replace is des_enc.c, which is replaced
+	by one of the assembler files found in asm.  Look at des/asm/readme
+	for more info.
+
+	/* Modification to fcrypt so it can be compiled to support
+	HPUX 10.x's long password format, define -DLONGCRYPT to use this.
+	Thanks to Jens Kupferschmidt <bt1cu@hpboot.rz.uni-leipzig.de>. */
+
+	SIGWINCH case put in des_read_passwd() so the function does not
+	'exit' if this function is recieved.
+
+Version 3.25 17/07/96
+	Modified read_pwd.c so that stdin can be read if not a tty.
+	Thanks to Jeff Barber <jeffb@issl.atl.hp.com> for the patches.
+	des_init_random_number_generator() shortened due to VMS linker
+	limits.
+	Added RSA's DESX cbc mode.  It is a form of cbc encryption, with 2
+	8 byte quantites xored before and after encryption.
+	des_xcbc_encryption() - the name is funny to preserve the des_
+	prefix on all functions.
+
+Version 3.24 20/04/96
+	The DES_PTR macro option checked and used by SSLeay configuration
+
+Version 3.23 11/04/96
+	Added DES_LONG.  If defined to 'unsigned int' on the DEC Alpha,
+	it gives a %20 speedup :-)
+	Fixed the problem with des.pl under perl5.  The patches were
+	sent by Ed Kubaitis (ejk@uiuc.edu).
+	if fcrypt.c, changed values to handle illegal salt values the way
+	normal crypt() implementations do.  Some programs apparently use
+	them :-(. The patch was sent by Bjorn Gronvall <bg@sics.se>
+
+Version 3.22 29/11/95
+	Bug in des(1), an error with the uuencoding stuff when the
+	'data' is small, thanks to Geoff Keating <keagchon@mehta.anu.edu.au>
+	for the patch.
+
+Version 3.21 22/11/95
+	After some emailing back and forth with 
+	Colin Plumb <colin@nyx10.cs.du.edu>, I've tweaked a few things
+	and in a future version I will probably put in some of the
+	optimisation he suggested for use with the DES_USE_PTR option.
+	Extra routines from Mark Murray <mark@grondar.za> for use in
+	freeBSD.  They mostly involve random number generation for use
+	with kerberos.  They involve evil machine specific system calls
+	etc so I would normally suggest pushing this stuff into the
+	application and/or using RAND_seed()/RAND_bytes() if you are
+	using this DES library as part of SSLeay.
+	Redone the read_pw() function so that it is cleaner and
+	supports termios, thanks to Sameer Parekh <sameer@c2.org>
+	for the initial patches for this.
+	Renamed 3ecb_encrypt() to ecb3_encrypt().  This has been
+	 done just to make things more consistent.
+	I have also now added triple DES versions of cfb and ofb.
+
+Version 3.20
+	Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com,
+	my des_random_seed() function was only copying 4 bytes of the
+	passed seed into the init structure.  It is now fixed to copy 8.
+	My own suggestion is to used something like MD5 :-)
+
+Version 3.19 
+	While looking at my code one day, I though, why do I keep on
+	calling des_encrypt(in,out,ks,enc) when every function that
+	calls it has in and out the same.  So I dropped the 'out'
+	parameter, people should not be using this function.
+
+Version 3.18 30/08/95
+	Fixed a few bit with the distribution and the filenames.
+	3.17 had been munged via a move to DOS and back again.
+	NO CODE CHANGES
+
+Version 3.17 14/07/95
+	Fixed ede3 cbc which I had broken in 3.16.  I have also
+	removed some unneeded variables in 7-8 of the routines.
+
+Version 3.16 26/06/95
+	Added des_encrypt2() which does not use IP/FP, used by triple
+	des routines.  Tweaked things a bit elsewhere. %13 speedup on
+	sparc and %6 on a R4400 for ede3 cbc mode.
+
+Version 3.15 06/06/95
+	Added des_ncbc_encrypt(), it is des_cbc mode except that it is
+	'normal' and copies the new iv value back over the top of the
+	passed parameter.
+	CHANGED des_ede3_cbc_encrypt() so that it too now overwrites
+	the iv.  THIS WILL BREAK EXISTING CODE, but since this function
+	only new, I feel I can change it, not so with des_cbc_encrypt :-(.
+	I need to update the documentation.
+
+Version 3.14 31/05/95
+	New release upon the world, as part of my SSL implementation.
+	New copyright and usage stuff.  Basically free for all to use
+	as long as you say it came from me :-)
+
+Version 3.13 31/05/95
+	A fix in speed.c, if HZ is not defined, I set it to 100.0
+	which is reasonable for most unixes except SunOS 4.x.
+	I now have a #ifdef sun but timing for SunOS 4.x looked very
+	good :-(.  At my last job where I used SunOS 4.x, it was
+	defined to be 60.0 (look at the old INSTALL documentation), at
+	the last release had it changed to 100.0 since I now work with
+	Solaris2 and SVR4 boxes.
+	Thanks to  Rory Chisholm <rchishol@math.ethz.ch> for pointing this
+	one out.
+
+Version 3.12 08/05/95
+	As pointed out by The Crypt Keeper <tck@bend.UCSD.EDU>,
+	my D_ENCRYPT macro in crypt() had an un-necessary variable.
+	It has been removed.
+
+Version 3.11 03/05/95
+	Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys
+	and one iv.  It is a standard and I needed it for my SSL code.
+	It makes more sense to use this for triple DES than
+	3cbc_encrypt().  I have also added (or should I say tested :-)
+	cfb64_encrypt() which is cfb64 but it will encrypt a partial
+	number of bytes - 3 bytes in 3 bytes out.  Again this is for
+	my SSL library, as a form of encryption to use with SSL
+	telnet.
+
+Version 3.10 22/03/95
+	Fixed a bug in 3cbc_encrypt() :-(.  When making repeated calls
+	to cbc3_encrypt, the 2 iv values that were being returned to
+	be used in the next call were reversed :-(.
+	Many thanks to Bill Wade <wade@Stoner.COM> for pointing out
+	this error.
+
+Version 3.09 01/02/95
+	Fixed des_random_key to far more random, it was rather feeble
+	with regards to picking the initial seed.  The problem was
+	pointed out by Olaf Kirch <okir@monad.swb.de>.
+
+Version 3.08 14/12/94
+	Added Makefile.PL so libdes can be built into perl5.
+	Changed des_locl.h so RAND is always defined.
+
+Version 3.07 05/12/94
+	Added GNUmake and stuff so the library can be build with
+	glibc.
+
+Version 3.06 30/08/94
+	Added rpc_enc.c which contains _des_crypt.  This is for use in
+	secure_rpc v 4.0
+	Finally fixed the cfb_enc problems.
+	Fixed a few parameter parsing bugs in des (-3 and -b), thanks
+	to Rob McMillan <R.McMillan@its.gu.edu.au>
+
+Version 3.05 21/04/94
+	for unsigned long l; gcc does not produce ((l>>34) == 0)
+	This causes bugs in cfb_enc.
+	Thanks to Hadmut Danisch <danisch@ira.uka.de>
+
+Version 3.04 20/04/94
+	Added a version number to des.c and libdes.a
+
+Version 3.03 12/01/94
+	Fixed a bug in non zero iv in 3cbc_enc.
+
+Version 3.02 29/10/93
+	I now work in a place where there are 6+ architectures and 14+
+	OS versions :-).
+	Fixed TERMIO definition so the most sys V boxes will work :-)
+
+Release upon comp.sources.misc
+Version 3.01 08/10/93
+	Added des_3cbc_encrypt()
+
+Version 3.00 07/10/93
+	Fixed up documentation.
+	quad_cksum definitely compatible with MIT's now.
+
+Version 2.30 24/08/93
+	Triple DES now defaults to triple cbc but can do triple ecb
+	 with the -b flag.
+	Fixed some MSDOS uuen/uudecoding problems, thanks to
+	Added prototypes.
+	
+Version 2.22 29/06/93
+	Fixed a bug in des_is_weak_key() which stopped it working :-(
+	thanks to engineering@MorningStar.Com.
+
+Version 2.21 03/06/93
+	des(1) with no arguments gives quite a bit of help.
+	Added -c (generate ckecksum) flag to des(1).
+	Added -3 (triple DES) flag to des(1).
+	Added cfb and ofb routines to the library.
+
+Version 2.20 11/03/93
+	Added -u (uuencode) flag to des(1).
+	I have been playing with byte order in quad_cksum to make it
+	 compatible with MIT's version.  All I can say is avid this
+	 function if possible since MIT's output is endian dependent.
+
+Version 2.12 14/10/92
+	Added MSDOS specific macro in ecb_encrypt which gives a %70
+	 speed up when the code is compiled with turbo C.
+
+Version 2.11 12/10/92
+	Speedup in set_key (recoding of PC-1)
+	 I now do it in 47 simple operations, down from 60.
+	 Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
+	 for motivating me to look for a faster system :-)
+	 The speedup is probably less that 1% but it is still 13
+	 instructions less :-).
+
+Version 2.10 06/10/92
+	The code now works on the 64bit ETA10 and CRAY without modifications or
+	 #defines.  I believe the code should work on any machine that
+	 defines long, int or short to be 8 bytes long.
+	Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu)
+	 for helping me fix the code to run on 64bit machines (he had
+	 access to an ETA10).
+	Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov>
+	 for testing the routines on a CRAY.
+	read_password.c has been renamed to read_passwd.c
+	string_to_key.c has been renamed to string2key.c
+
+Version 2.00 14/09/92
+	Made mods so that the library should work on 64bit CPU's.
+	Removed all my uchar and ulong defs.  To many different
+	 versions of unix define them in their header files in too many
+	 different combinations :-)
+	IRIX - Sillicon Graphics mods (mostly in read_password.c).
+	 Thanks to Andrew Daviel (advax@erich.triumf.ca)
+
+Version 1.99 26/08/92
+	Fixed a bug or 2 in enc_read.c
+	Fixed a bug in enc_write.c
+	Fixed a pseudo bug in fcrypt.c (very obscure).
+
+Version 1.98 31/07/92
+	Support for the ETA10.  This is a strange machine that defines
+	longs and ints as 8 bytes and shorts as 4 bytes.
+	Since I do evil things with long * that assume that they are 4
+	bytes.  Look in the Makefile for the option to compile for
+	this machine.  quad_cksum appears to have problems but I
+	will don't have the time to fix it right now, and this is not
+	a function that uses DES and so will not effect the main uses
+	of the library.
+
+Version 1.97 20/05/92 eay
+	Fixed the Imakefile and made some changes to des.h to fix some
+	problems when building this package with Kerberos v 4.
+
+Version 1.96 18/05/92 eay
+	Fixed a small bug in string_to_key() where problems could
+	occur if des_check_key was set to true and the string
+	generated a weak key.
+
+Patch2 posted to comp.sources.misc
+Version 1.95 13/05/92 eay
+	Added an alternative version of the D_ENCRYPT macro in
+	ecb_encrypt and fcrypt.  Depending on the compiler, one version or the
+	other will be faster.  This was inspired by 
+	Dana How <how@isl.stanford.edu>, and her pointers about doing the
+	*(ulong *)((uchar *)ptr+(value&0xfc))
+	vs
+	ptr[value&0x3f]
+	to stop the C compiler doing a <<2 to convert the long array index.
+
+Version 1.94 05/05/92 eay
+	Fixed an incompatibility between my string_to_key and the MIT
+	 version.  When the key is longer than 8 chars, I was wrapping
+	 with a different method.  To use the old version, define
+	 OLD_STR_TO_KEY in the makefile.  Thanks to
+	 viktor@newsu.shearson.com (Viktor Dukhovni).
+
+Version 1.93 28/04/92 eay
+	Fixed the VMS mods so that echo is now turned off in
+	 read_password.  Thanks again to brennan@coco.cchs.su.oz.AU.
+	MSDOS support added.  The routines can be compiled with
+	 Turbo C (v2.0) and MSC (v5.1).  Make sure MSDOS is defined.
+
+Patch1 posted to comp.sources.misc
+Version 1.92 13/04/92 eay
+	Changed D_ENCRYPT so that the rotation of R occurs outside of
+	 the loop.  This required rotating all the longs in sp.h (now
+	 called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+	speed.c has been changed so it will work without SIGALRM.  If
+	 times(3) is not present it will try to use ftime() instead.
+
+Version 1.91 08/04/92 eay
+	Added -E/-D options to des(1) so it can use string_to_key.
+	Added SVR4 mods suggested by witr@rwwa.COM
+	Added VMS mods suggested by brennan@coco.cchs.su.oz.AU.  If
+	anyone knows how to turn of tty echo in VMS please tell me or
+	implement it yourself :-).
+	Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS
+	does not like IN/OUT being used.
+
+Libdes posted to comp.sources.misc
+Version 1.9 24/03/92 eay
+	Now contains a fast small crypt replacement.
+	Added des(1) command.
+	Added des_rw_mode so people can use cbc encryption with
+	enc_read and enc_write.
+
+Version 1.8 15/10/91 eay
+	Bug in cbc_cksum.
+	Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this
+	one out.
+
+Version 1.7 24/09/91 eay
+	Fixed set_key :-)
+	set_key is 4 times faster and takes less space.
+	There are a few minor changes that could be made.
+
+Version 1.6 19/09/1991 eay
+	Finally go IP and FP finished.
+	Now I need to fix set_key.
+	This version is quite a bit faster that 1.51
+
+Version 1.52 15/06/1991 eay
+	20% speedup in ecb_encrypt by changing the E bit selection
+	to use 2 32bit words.  This also required modification of the
+	sp table.  There is still a way to speedup the IP and IP-1
+	(hints from outer@sq.com) still working on this one :-(.
+
+Version 1.51 07/06/1991 eay
+	Faster des_encrypt by loop unrolling
+	Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu)
+
+Version 1.50 28/05/1991 eay
+	Optimised the code a bit more for the sparc.  I have improved the
+	speed of the inner des_encrypt by speeding up the initial and
+	final permutations.
+
+Version 1.40 23/10/1990 eay
+	Fixed des_random_key, it did not produce a random key :-(
+
+Version 1.30  2/10/1990 eay
+	Have made des_quad_cksum the same as MIT's, the full package
+	should be compatible with MIT's
+	Have tested on a DECstation 3100
+	Still need to fix des_set_key (make it faster).
+	Does des_cbc_encrypts at 70.5k/sec on a 3100.
+
+Version 1.20 18/09/1990 eay
+	Fixed byte order dependencies.
+	Fixed (I hope) all the word alignment problems.
+	Speedup in des_ecb_encrypt.
+
+Version 1.10 11/09/1990 eay
+	Added des_enc_read and des_enc_write.
+	Still need to fix des_quad_cksum.
+	Still need to document des_enc_read and des_enc_write.
+
+Version 1.00 27/08/1990 eay
+
diff --git a/openssl/crypto/des/asm/crypt586.pl b/openssl/crypto/des/asm/crypt586.pl
new file mode 100644
index 0000000..e36f7d4
--- /dev/null
+++ b/openssl/crypto/des/asm/crypt586.pl
@@ -0,0 +1,209 @@
+#!/usr/local/bin/perl
+#
+# The inner loop instruction sequence and the IP/FP modifications are from
+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
+# I've added the stuff needed for crypt() but I've not worried about making
+# things perfect.
+#
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"crypt586.pl");
+
+$L="edi";
+$R="esi";
+
+&external_label("DES_SPtrans");
+&fcrypt_body("fcrypt_body");
+&asm_finish();
+
+sub fcrypt_body
+	{
+	local($name,$do_ip)=@_;
+
+	&function_begin($name);
+
+	&comment("");
+	&comment("Load the 2 words");
+	$trans="ebp";
+
+	&xor(	$L,	$L);
+	&xor(	$R,	$R);
+
+	# PIC-ification:-)
+	&picmeup("edx","DES_SPtrans");
+	#if ($cpp)	{ &picmeup("edx","DES_SPtrans");   }
+	#else		{ &lea("edx",&DWP("DES_SPtrans")); }
+	&push("edx");	# becomes &swtmp(1)
+	#
+	&mov($trans,&wparam(1)); # reloaded with DES_SPtrans in D_ENCRYPT
+
+	&push(&DWC(25)); # add a variable
+
+	&set_label("start");
+	for ($i=0; $i<16; $i+=2)
+		{
+		&comment("");
+		&comment("Round $i");
+		&D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx");
+
+		&comment("");
+		&comment("Round ".sprintf("%d",$i+1));
+		&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx");
+		}
+	 &mov("ebx",	&swtmp(0));
+	&mov("eax",	$L);
+	 &dec("ebx");
+	&mov($L,	$R);
+	 &mov($R,	"eax");
+	&mov(&swtmp(0),	"ebx");
+	 &jnz(&label("start"));
+
+	&comment("");
+	&comment("FP");
+	&mov("edx",&wparam(0));
+
+	&FP_new($R,$L,"eax",3);
+	&mov(&DWP(0,"edx","",0),"eax");
+	&mov(&DWP(4,"edx","",0),$L);
+
+	&add("esp",8);	# remove variables
+
+	&function_end($name);
+	}
+
+sub D_ENCRYPT
+	{
+	local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t)=@_;
+
+	&mov(	$u,		&wparam(2));			# 2
+	&mov(	$t,		$R);
+	&shr(	$t,		16);				# 1
+	&mov(	$tmp2,		&wparam(3));			# 2
+	&xor(	$t,		$R);				# 1
+
+	&and(	$u,		$t);				# 2
+	&and(	$t,		$tmp2);				# 2
+
+	&mov(	$tmp1,		$u);
+	&shl(	$tmp1,		16); 				# 1
+	&mov(	$tmp2,		$t);
+	&shl(	$tmp2,		16); 				# 1
+	&xor(	$u,		$tmp1);				# 2
+	&xor(	$t,		$tmp2);				# 2
+	&mov(	$tmp1,		&DWP(&n2a($S*4),$trans,"",0));	# 2
+	&xor(	$u,		$tmp1);
+	&mov(	$tmp2,		&DWP(&n2a(($S+1)*4),$trans,"",0));	# 2
+	&xor(	$u,		$R);
+	&xor(	$t,		$R);
+	&xor(	$t,		$tmp2);
+
+	&and(	$u,		"0xfcfcfcfc"	);		# 2
+	&xor(	$tmp1,		$tmp1);				# 1
+	&and(	$t,		"0xcfcfcfcf"	);		# 2
+	&xor(	$tmp2,		$tmp2);	
+	&movb(	&LB($tmp1),	&LB($u)	);
+	&movb(	&LB($tmp2),	&HB($u)	);
+	&rotr(	$t,		4		);
+	&mov(	$trans,		&swtmp(1));
+	&xor(	$L,		&DWP("     ",$trans,$tmp1,0));
+	&movb(	&LB($tmp1),	&LB($t)	);
+	&xor(	$L,		&DWP("0x200",$trans,$tmp2,0));
+	&movb(	&LB($tmp2),	&HB($t)	);
+	&shr(	$u,		16);
+	&xor(	$L,		&DWP("0x100",$trans,$tmp1,0));
+	&movb(	&LB($tmp1),	&HB($u)	);
+	&shr(	$t,		16);
+	&xor(	$L,		&DWP("0x300",$trans,$tmp2,0));
+	&movb(	&LB($tmp2),	&HB($t)	);
+	&and(	$u,		"0xff"	);
+	&and(	$t,		"0xff"	);
+	&mov(	$tmp1,		&DWP("0x600",$trans,$tmp1,0));
+	&xor(	$L,		$tmp1);
+	&mov(	$tmp1,		&DWP("0x700",$trans,$tmp2,0));
+	&xor(	$L,		$tmp1);
+	&mov(	$tmp1,		&DWP("0x400",$trans,$u,0));
+	&xor(	$L,		$tmp1);
+	&mov(	$tmp1,		&DWP("0x500",$trans,$t,0));
+	&xor(	$L,		$tmp1);
+	&mov(	$trans,		&wparam(1));
+	}
+
+sub n2a
+	{
+	sprintf("%d",$_[0]);
+	}
+
+# now has a side affect of rotating $a by $shift
+sub R_PERM_OP
+	{
+	local($a,$b,$tt,$shift,$mask,$last)=@_;
+
+	&rotl(	$a,		$shift		) if ($shift != 0);
+	&mov(	$tt,		$a		);
+	&xor(	$a,		$b		);
+	&and(	$a,		$mask		);
+	if ($notlast eq $b)
+		{
+		&xor(	$b,		$a		);
+		&xor(	$tt,		$a		);
+		}
+	else
+		{
+		&xor(	$tt,		$a		);
+		&xor(	$b,		$a		);
+		}
+	&comment("");
+	}
+
+sub IP_new
+	{
+	local($l,$r,$tt,$lr)=@_;
+
+	&R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
+	&R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
+	&R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
+	&R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
+	&R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
+	
+	if ($lr != 3)
+		{
+		if (($lr-3) < 0)
+			{ &rotr($tt,	3-$lr); }
+		else	{ &rotl($tt,	$lr-3); }
+		}
+	if ($lr != 2)
+		{
+		if (($lr-2) < 0)
+			{ &rotr($r,	2-$lr); }
+		else	{ &rotl($r,	$lr-2); }
+		}
+	}
+
+sub FP_new
+	{
+	local($l,$r,$tt,$lr)=@_;
+
+	if ($lr != 2)
+		{
+		if (($lr-2) < 0)
+			{ &rotl($r,	2-$lr); }
+		else	{ &rotr($r,	$lr-2); }
+		}
+	if ($lr != 3)
+		{
+		if (($lr-3) < 0)
+			{ &rotl($l,	3-$lr); }
+		else	{ &rotr($l,	$lr-3); }
+		}
+
+	&R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
+	&R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
+	&R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
+	&R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
+	&R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
+	&rotr($tt	, 4);
+	}
+
diff --git a/openssl/crypto/des/asm/des-586.pl b/openssl/crypto/des/asm/des-586.pl
new file mode 100644
index 0000000..5b5f39c
--- /dev/null
+++ b/openssl/crypto/des/asm/des-586.pl
@@ -0,0 +1,453 @@
+#!/usr/local/bin/perl
+#
+# The inner loop instruction sequence and the IP/FP modifications are from
+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
+#
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+require "cbc.pl";
+require "desboth.pl";
+
+# base code is in microsft
+# op dest, source
+# format.
+#
+
+&asm_init($ARGV[0],"des-586.pl");
+
+$L="edi";
+$R="esi";
+$trans="ebp";
+$small_footprint=1 if (grep(/\-DOPENSSL_SMALL_FOOTPRINT/,@ARGV));
+# one can discuss setting this variable to 1 unconditionally, as
+# the folded loop is only 3% slower than unrolled, but >7 times smaller
+
+&public_label("DES_SPtrans");
+
+&DES_encrypt_internal();
+&DES_decrypt_internal();
+&DES_encrypt("DES_encrypt1",1);
+&DES_encrypt("DES_encrypt2",0);
+&DES_encrypt3("DES_encrypt3",1);
+&DES_encrypt3("DES_decrypt3",0);
+&cbc("DES_ncbc_encrypt","DES_encrypt1","DES_encrypt1",0,4,5,3,5,-1);
+&cbc("DES_ede3_cbc_encrypt","DES_encrypt3","DES_decrypt3",0,6,7,3,4,5);
+&DES_SPtrans();
+
+&asm_finish();
+
+sub DES_encrypt_internal()
+	{
+	&function_begin_B("_x86_DES_encrypt");
+
+	if ($small_footprint)
+	    {
+	    &lea("edx",&DWP(128,"ecx"));
+	    &push("edx");
+	    &push("ecx");
+	    &set_label("eloop");
+		&D_ENCRYPT(0,$L,$R,0,$trans,"eax","ebx","ecx","edx",&swtmp(0));
+		&comment("");
+		&D_ENCRYPT(1,$R,$L,2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
+		&comment("");
+		&add("ecx",16);
+		&cmp("ecx",&swtmp(1));
+		&mov(&swtmp(0),"ecx");
+		&jb(&label("eloop"));
+	    &add("esp",8);
+	    }
+	else
+	    {
+	    &push("ecx");
+	    for ($i=0; $i<16; $i+=2)
+		{
+		&comment("Round $i");
+		&D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
+		&comment("Round ".sprintf("%d",$i+1));
+		&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
+		}
+	    &add("esp",4);
+	}
+	&ret();
+
+	&function_end_B("_x86_DES_encrypt");
+	}
+	
+sub DES_decrypt_internal()
+	{
+	&function_begin_B("_x86_DES_decrypt");
+
+	if ($small_footprint)
+	    {
+	    &push("ecx");
+	    &lea("ecx",&DWP(128,"ecx"));
+	    &push("ecx");
+	    &set_label("dloop");
+		&D_ENCRYPT(0,$L,$R,-2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
+		&comment("");
+		&D_ENCRYPT(1,$R,$L,-4,$trans,"eax","ebx","ecx","edx",&swtmp(0));
+		&comment("");
+		&sub("ecx",16);
+		&cmp("ecx",&swtmp(1));
+		&mov(&swtmp(0),"ecx");
+		&ja(&label("dloop"));
+	    &add("esp",8);
+	    }
+	else
+	    {
+	    &push("ecx");
+	    for ($i=15; $i>0; $i-=2)
+		{
+		&comment("Round $i");
+		&D_ENCRYPT(15-$i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
+		&comment("Round ".sprintf("%d",$i-1));
+		&D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
+		}
+	    &add("esp",4);
+	    }
+	&ret();
+
+	&function_end_B("_x86_DES_decrypt");
+	}
+	
+sub DES_encrypt
+	{
+	local($name,$do_ip)=@_;
+
+	&function_begin_B($name);
+
+	&push("esi");
+	&push("edi");
+
+	&comment("");
+	&comment("Load the 2 words");
+
+	if ($do_ip)
+		{
+		&mov($R,&wparam(0));
+		 &xor(	"ecx",		"ecx"		);
+
+		&push("ebx");
+		&push("ebp");
+
+		&mov("eax",&DWP(0,$R,"",0));
+		 &mov("ebx",&wparam(2));	# get encrypt flag
+		&mov($L,&DWP(4,$R,"",0));
+		&comment("");
+		&comment("IP");
+		&IP_new("eax",$L,$R,3);
+		}
+	else
+		{
+		&mov("eax",&wparam(0));
+		 &xor(	"ecx",		"ecx"		);
+
+		&push("ebx");
+		&push("ebp");
+
+		&mov($R,&DWP(0,"eax","",0));
+		 &mov("ebx",&wparam(2));	# get encrypt flag
+		&rotl($R,3);
+		&mov($L,&DWP(4,"eax","",0));
+		&rotl($L,3);
+		}
+
+	# PIC-ification:-)
+	&call	(&label("pic_point"));
+	&set_label("pic_point");
+	&blindpop($trans);
+	&lea	($trans,&DWP(&label("DES_SPtrans")."-".&label("pic_point"),$trans));
+
+	&mov(	"ecx",	&wparam(1)	);
+
+	&cmp("ebx","0");
+	&je(&label("decrypt"));
+	&call("_x86_DES_encrypt");
+	&jmp(&label("done"));
+	&set_label("decrypt");
+	&call("_x86_DES_decrypt");
+	&set_label("done");
+
+	if ($do_ip)
+		{
+		&comment("");
+		&comment("FP");
+		&mov("edx",&wparam(0));
+		&FP_new($L,$R,"eax",3);
+
+		&mov(&DWP(0,"edx","",0),"eax");
+		&mov(&DWP(4,"edx","",0),$R);
+		}
+	else
+		{
+		&comment("");
+		&comment("Fixup");
+		&rotr($L,3);		# r
+		 &mov("eax",&wparam(0));
+		&rotr($R,3);		# l
+		 &mov(&DWP(0,"eax","",0),$L);
+		 &mov(&DWP(4,"eax","",0),$R);
+		}
+
+	&pop("ebp");
+	&pop("ebx");
+	&pop("edi");
+	&pop("esi");
+	&ret();
+
+	&function_end_B($name);
+	}
+
+sub D_ENCRYPT
+	{
+	local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t,$wp1)=@_;
+
+	 &mov(	$u,		&DWP(&n2a($S*4),$tmp2,"",0));
+	&xor(	$tmp1,		$tmp1);
+	 &mov(	$t,		&DWP(&n2a(($S+1)*4),$tmp2,"",0));
+	&xor(	$u,		$R);
+	&xor(	$tmp2,		$tmp2);
+	 &xor(	$t,		$R);
+	&and(	$u,		"0xfcfcfcfc"	);
+	 &and(	$t,		"0xcfcfcfcf"	);
+	&movb(	&LB($tmp1),	&LB($u)	);
+	 &movb(	&LB($tmp2),	&HB($u)	);
+	&rotr(	$t,		4		);
+	&xor(	$L,		&DWP("     ",$trans,$tmp1,0));
+	 &movb(	&LB($tmp1),	&LB($t)	);
+	 &xor(	$L,		&DWP("0x200",$trans,$tmp2,0));
+	 &movb(	&LB($tmp2),	&HB($t)	);
+	&shr(	$u,		16);
+	 &xor(	$L,		&DWP("0x100",$trans,$tmp1,0));
+	 &movb(	&LB($tmp1),	&HB($u)	);
+	&shr(	$t,		16);
+	 &xor(	$L,		&DWP("0x300",$trans,$tmp2,0));
+	&movb(	&LB($tmp2),	&HB($t)	);
+	 &and(	$u,		"0xff"	);
+	&and(	$t,		"0xff"	);
+	 &xor(	$L,		&DWP("0x600",$trans,$tmp1,0));
+	 &xor(	$L,		&DWP("0x700",$trans,$tmp2,0));
+	&mov(	$tmp2,		$wp1	);
+	 &xor(	$L,		&DWP("0x400",$trans,$u,0));
+	 &xor(	$L,		&DWP("0x500",$trans,$t,0));
+	}
+
+sub n2a
+	{
+	sprintf("%d",$_[0]);
+	}
+
+# now has a side affect of rotating $a by $shift
+sub R_PERM_OP
+	{
+	local($a,$b,$tt,$shift,$mask,$last)=@_;
+
+	&rotl(	$a,		$shift		) if ($shift != 0);
+	&mov(	$tt,		$a		);
+	&xor(	$a,		$b		);
+	&and(	$a,		$mask		);
+	# This can never succeed, and besides it is difficult to see what the
+	# idea was - Ben 13 Feb 99
+	if (!$last eq $b)
+		{
+		&xor(	$b,		$a		);
+		&xor(	$tt,		$a		);
+		}
+	else
+		{
+		&xor(	$tt,		$a		);
+		&xor(	$b,		$a		);
+		}
+	&comment("");
+	}
+
+sub IP_new
+	{
+	local($l,$r,$tt,$lr)=@_;
+
+	&R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
+	&R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
+	&R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
+	&R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
+	&R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
+	
+	if ($lr != 3)
+		{
+		if (($lr-3) < 0)
+			{ &rotr($tt,	3-$lr); }
+		else	{ &rotl($tt,	$lr-3); }
+		}
+	if ($lr != 2)
+		{
+		if (($lr-2) < 0)
+			{ &rotr($r,	2-$lr); }
+		else	{ &rotl($r,	$lr-2); }
+		}
+	}
+
+sub FP_new
+	{
+	local($l,$r,$tt,$lr)=@_;
+
+	if ($lr != 2)
+		{
+		if (($lr-2) < 0)
+			{ &rotl($r,	2-$lr); }
+		else	{ &rotr($r,	$lr-2); }
+		}
+	if ($lr != 3)
+		{
+		if (($lr-3) < 0)
+			{ &rotl($l,	3-$lr); }
+		else	{ &rotr($l,	$lr-3); }
+		}
+
+	&R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
+	&R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
+	&R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
+	&R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
+	&R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
+	&rotr($tt	, 4);
+	}
+
+sub DES_SPtrans
+	{
+	&set_label("DES_SPtrans",64);
+	&data_word(0x02080800, 0x00080000, 0x02000002, 0x02080802);
+	&data_word(0x02000000, 0x00080802, 0x00080002, 0x02000002);
+	&data_word(0x00080802, 0x02080800, 0x02080000, 0x00000802);
+	&data_word(0x02000802, 0x02000000, 0x00000000, 0x00080002);
+	&data_word(0x00080000, 0x00000002, 0x02000800, 0x00080800);
+	&data_word(0x02080802, 0x02080000, 0x00000802, 0x02000800);
+	&data_word(0x00000002, 0x00000800, 0x00080800, 0x02080002);
+	&data_word(0x00000800, 0x02000802, 0x02080002, 0x00000000);
+	&data_word(0x00000000, 0x02080802, 0x02000800, 0x00080002);
+	&data_word(0x02080800, 0x00080000, 0x00000802, 0x02000800);
+	&data_word(0x02080002, 0x00000800, 0x00080800, 0x02000002);
+	&data_word(0x00080802, 0x00000002, 0x02000002, 0x02080000);
+	&data_word(0x02080802, 0x00080800, 0x02080000, 0x02000802);
+	&data_word(0x02000000, 0x00000802, 0x00080002, 0x00000000);
+	&data_word(0x00080000, 0x02000000, 0x02000802, 0x02080800);
+	&data_word(0x00000002, 0x02080002, 0x00000800, 0x00080802);
+	# nibble 1
+	&data_word(0x40108010, 0x00000000, 0x00108000, 0x40100000);
+	&data_word(0x40000010, 0x00008010, 0x40008000, 0x00108000);
+	&data_word(0x00008000, 0x40100010, 0x00000010, 0x40008000);
+	&data_word(0x00100010, 0x40108000, 0x40100000, 0x00000010);
+	&data_word(0x00100000, 0x40008010, 0x40100010, 0x00008000);
+	&data_word(0x00108010, 0x40000000, 0x00000000, 0x00100010);
+	&data_word(0x40008010, 0x00108010, 0x40108000, 0x40000010);
+	&data_word(0x40000000, 0x00100000, 0x00008010, 0x40108010);
+	&data_word(0x00100010, 0x40108000, 0x40008000, 0x00108010);
+	&data_word(0x40108010, 0x00100010, 0x40000010, 0x00000000);
+	&data_word(0x40000000, 0x00008010, 0x00100000, 0x40100010);
+	&data_word(0x00008000, 0x40000000, 0x00108010, 0x40008010);
+	&data_word(0x40108000, 0x00008000, 0x00000000, 0x40000010);
+	&data_word(0x00000010, 0x40108010, 0x00108000, 0x40100000);
+	&data_word(0x40100010, 0x00100000, 0x00008010, 0x40008000);
+	&data_word(0x40008010, 0x00000010, 0x40100000, 0x00108000);
+	# nibble 2
+	&data_word(0x04000001, 0x04040100, 0x00000100, 0x04000101);
+	&data_word(0x00040001, 0x04000000, 0x04000101, 0x00040100);
+	&data_word(0x04000100, 0x00040000, 0x04040000, 0x00000001);
+	&data_word(0x04040101, 0x00000101, 0x00000001, 0x04040001);
+	&data_word(0x00000000, 0x00040001, 0x04040100, 0x00000100);
+	&data_word(0x00000101, 0x04040101, 0x00040000, 0x04000001);
+	&data_word(0x04040001, 0x04000100, 0x00040101, 0x04040000);
+	&data_word(0x00040100, 0x00000000, 0x04000000, 0x00040101);
+	&data_word(0x04040100, 0x00000100, 0x00000001, 0x00040000);
+	&data_word(0x00000101, 0x00040001, 0x04040000, 0x04000101);
+	&data_word(0x00000000, 0x04040100, 0x00040100, 0x04040001);
+	&data_word(0x00040001, 0x04000000, 0x04040101, 0x00000001);
+	&data_word(0x00040101, 0x04000001, 0x04000000, 0x04040101);
+	&data_word(0x00040000, 0x04000100, 0x04000101, 0x00040100);
+	&data_word(0x04000100, 0x00000000, 0x04040001, 0x00000101);
+	&data_word(0x04000001, 0x00040101, 0x00000100, 0x04040000);
+	# nibble 3
+	&data_word(0x00401008, 0x10001000, 0x00000008, 0x10401008);
+	&data_word(0x00000000, 0x10400000, 0x10001008, 0x00400008);
+	&data_word(0x10401000, 0x10000008, 0x10000000, 0x00001008);
+	&data_word(0x10000008, 0x00401008, 0x00400000, 0x10000000);
+	&data_word(0x10400008, 0x00401000, 0x00001000, 0x00000008);
+	&data_word(0x00401000, 0x10001008, 0x10400000, 0x00001000);
+	&data_word(0x00001008, 0x00000000, 0x00400008, 0x10401000);
+	&data_word(0x10001000, 0x10400008, 0x10401008, 0x00400000);
+	&data_word(0x10400008, 0x00001008, 0x00400000, 0x10000008);
+	&data_word(0x00401000, 0x10001000, 0x00000008, 0x10400000);
+	&data_word(0x10001008, 0x00000000, 0x00001000, 0x00400008);
+	&data_word(0x00000000, 0x10400008, 0x10401000, 0x00001000);
+	&data_word(0x10000000, 0x10401008, 0x00401008, 0x00400000);
+	&data_word(0x10401008, 0x00000008, 0x10001000, 0x00401008);
+	&data_word(0x00400008, 0x00401000, 0x10400000, 0x10001008);
+	&data_word(0x00001008, 0x10000000, 0x10000008, 0x10401000);
+	# nibble 4
+	&data_word(0x08000000, 0x00010000, 0x00000400, 0x08010420);
+	&data_word(0x08010020, 0x08000400, 0x00010420, 0x08010000);
+	&data_word(0x00010000, 0x00000020, 0x08000020, 0x00010400);
+	&data_word(0x08000420, 0x08010020, 0x08010400, 0x00000000);
+	&data_word(0x00010400, 0x08000000, 0x00010020, 0x00000420);
+	&data_word(0x08000400, 0x00010420, 0x00000000, 0x08000020);
+	&data_word(0x00000020, 0x08000420, 0x08010420, 0x00010020);
+	&data_word(0x08010000, 0x00000400, 0x00000420, 0x08010400);
+	&data_word(0x08010400, 0x08000420, 0x00010020, 0x08010000);
+	&data_word(0x00010000, 0x00000020, 0x08000020, 0x08000400);
+	&data_word(0x08000000, 0x00010400, 0x08010420, 0x00000000);
+	&data_word(0x00010420, 0x08000000, 0x00000400, 0x00010020);
+	&data_word(0x08000420, 0x00000400, 0x00000000, 0x08010420);
+	&data_word(0x08010020, 0x08010400, 0x00000420, 0x00010000);
+	&data_word(0x00010400, 0x08010020, 0x08000400, 0x00000420);
+	&data_word(0x00000020, 0x00010420, 0x08010000, 0x08000020);
+	# nibble 5
+	&data_word(0x80000040, 0x00200040, 0x00000000, 0x80202000);
+	&data_word(0x00200040, 0x00002000, 0x80002040, 0x00200000);
+	&data_word(0x00002040, 0x80202040, 0x00202000, 0x80000000);
+	&data_word(0x80002000, 0x80000040, 0x80200000, 0x00202040);
+	&data_word(0x00200000, 0x80002040, 0x80200040, 0x00000000);
+	&data_word(0x00002000, 0x00000040, 0x80202000, 0x80200040);
+	&data_word(0x80202040, 0x80200000, 0x80000000, 0x00002040);
+	&data_word(0x00000040, 0x00202000, 0x00202040, 0x80002000);
+	&data_word(0x00002040, 0x80000000, 0x80002000, 0x00202040);
+	&data_word(0x80202000, 0x00200040, 0x00000000, 0x80002000);
+	&data_word(0x80000000, 0x00002000, 0x80200040, 0x00200000);
+	&data_word(0x00200040, 0x80202040, 0x00202000, 0x00000040);
+	&data_word(0x80202040, 0x00202000, 0x00200000, 0x80002040);
+	&data_word(0x80000040, 0x80200000, 0x00202040, 0x00000000);
+	&data_word(0x00002000, 0x80000040, 0x80002040, 0x80202000);
+	&data_word(0x80200000, 0x00002040, 0x00000040, 0x80200040);
+	# nibble 6
+	&data_word(0x00004000, 0x00000200, 0x01000200, 0x01000004);
+	&data_word(0x01004204, 0x00004004, 0x00004200, 0x00000000);
+	&data_word(0x01000000, 0x01000204, 0x00000204, 0x01004000);
+	&data_word(0x00000004, 0x01004200, 0x01004000, 0x00000204);
+	&data_word(0x01000204, 0x00004000, 0x00004004, 0x01004204);
+	&data_word(0x00000000, 0x01000200, 0x01000004, 0x00004200);
+	&data_word(0x01004004, 0x00004204, 0x01004200, 0x00000004);
+	&data_word(0x00004204, 0x01004004, 0x00000200, 0x01000000);
+	&data_word(0x00004204, 0x01004000, 0x01004004, 0x00000204);
+	&data_word(0x00004000, 0x00000200, 0x01000000, 0x01004004);
+	&data_word(0x01000204, 0x00004204, 0x00004200, 0x00000000);
+	&data_word(0x00000200, 0x01000004, 0x00000004, 0x01000200);
+	&data_word(0x00000000, 0x01000204, 0x01000200, 0x00004200);
+	&data_word(0x00000204, 0x00004000, 0x01004204, 0x01000000);
+	&data_word(0x01004200, 0x00000004, 0x00004004, 0x01004204);
+	&data_word(0x01000004, 0x01004200, 0x01004000, 0x00004004);
+	# nibble 7
+	&data_word(0x20800080, 0x20820000, 0x00020080, 0x00000000);
+	&data_word(0x20020000, 0x00800080, 0x20800000, 0x20820080);
+	&data_word(0x00000080, 0x20000000, 0x00820000, 0x00020080);
+	&data_word(0x00820080, 0x20020080, 0x20000080, 0x20800000);
+	&data_word(0x00020000, 0x00820080, 0x00800080, 0x20020000);
+	&data_word(0x20820080, 0x20000080, 0x00000000, 0x00820000);
+	&data_word(0x20000000, 0x00800000, 0x20020080, 0x20800080);
+	&data_word(0x00800000, 0x00020000, 0x20820000, 0x00000080);
+	&data_word(0x00800000, 0x00020000, 0x20000080, 0x20820080);
+	&data_word(0x00020080, 0x20000000, 0x00000000, 0x00820000);
+	&data_word(0x20800080, 0x20020080, 0x20020000, 0x00800080);
+	&data_word(0x20820000, 0x00000080, 0x00800080, 0x20020000);
+	&data_word(0x20820080, 0x00800000, 0x20800000, 0x20000080);
+	&data_word(0x00820000, 0x00020080, 0x20020080, 0x20800000);
+	&data_word(0x00000080, 0x20820000, 0x00820080, 0x00000000);
+	&data_word(0x20000000, 0x20800080, 0x00020000, 0x00820080);
+	}
diff --git a/openssl/crypto/des/asm/des_enc.m4 b/openssl/crypto/des/asm/des_enc.m4
new file mode 100644
index 0000000..3280595
--- /dev/null
+++ b/openssl/crypto/des/asm/des_enc.m4
@@ -0,0 +1,2099 @@
+!  des_enc.m4
+!  des_enc.S  (generated from des_enc.m4)
+!
+!  UltraSPARC assembler version of the LibDES/SSLeay/OpenSSL des_enc.c file.
+!
+!  Version 1.0. 32-bit version.
+!
+!  June 8, 2000.
+!
+!  Version 2.0. 32/64-bit, PIC-ification, blended CPU adaptation
+!		by Andy Polyakov.
+!
+!  January 1, 2003.
+!
+!  Assembler version: Copyright Svend Olaf Mikkelsen.
+!
+!  Original C code: Copyright Eric A. Young.
+!
+!  This code can be freely used by LibDES/SSLeay/OpenSSL users.
+!
+!  The LibDES/SSLeay/OpenSSL copyright notices must be respected.
+!
+!  This version can be redistributed.
+!
+!  To expand the m4 macros: m4 -B 8192 des_enc.m4 > des_enc.S
+!
+!  Global registers 1 to 5 are used. This is the same as done by the
+!  cc compiler. The UltraSPARC load/store little endian feature is used.
+!
+!  Instruction grouping often refers to one CPU cycle.
+!
+!  Assemble through gcc: gcc -c -mcpu=ultrasparc -o des_enc.o des_enc.S
+!
+!  Assemble through cc:  cc -c -xarch=v8plusa -o des_enc.o des_enc.S
+!
+!  Performance improvement according to './apps/openssl speed des'
+!
+!	32-bit build:
+!		23%  faster than cc-5.2 -xarch=v8plus -xO5
+!		115% faster than gcc-3.2.1 -m32 -mcpu=ultrasparc -O5
+!	64-bit build:
+!		50%  faster than cc-5.2 -xarch=v9 -xO5
+!		100% faster than gcc-3.2.1 -m64 -mcpu=ultrasparc -O5
+!
+
+.ident "des_enc.m4 2.1"
+.file  "des_enc-sparc.S"
+
+#if defined(__SUNPRO_C) && defined(__sparcv9)
+# define ABI64  /* They've said -xarch=v9 at command line */
+#elif defined(__GNUC__) && defined(__arch64__)
+# define ABI64  /* They've said -m64 at command line */
+#endif
+
+#ifdef ABI64
+  .register	%g2,#scratch
+  .register	%g3,#scratch
+# define	FRAME	-192
+# define	BIAS	2047
+# define	LDPTR	ldx
+# define	STPTR	stx
+# define	ARG0	128
+# define	ARGSZ	8
+# ifndef OPENSSL_SYSNAME_ULTRASPARC
+# define OPENSSL_SYSNAME_ULTRASPARC
+# endif
+#else
+# define	FRAME	-96
+# define	BIAS	0
+# define	LDPTR	ld
+# define	STPTR	st
+# define	ARG0	68
+# define	ARGSZ	4
+#endif
+
+#define LOOPS 7
+
+#define global0 %g0
+#define global1 %g1
+#define global2 %g2
+#define global3 %g3
+#define global4 %g4
+#define global5 %g5
+
+#define local0 %l0
+#define local1 %l1
+#define local2 %l2
+#define local3 %l3
+#define local4 %l4
+#define local5 %l5
+#define local7 %l6
+#define local6 %l7
+
+#define in0 %i0
+#define in1 %i1
+#define in2 %i2
+#define in3 %i3
+#define in4 %i4
+#define in5 %i5
+#define in6 %i6
+#define in7 %i7
+
+#define out0 %o0
+#define out1 %o1
+#define out2 %o2
+#define out3 %o3
+#define out4 %o4
+#define out5 %o5
+#define out6 %o6
+#define out7 %o7
+
+#define stub stb
+
+changequote({,})
+
+
+! Macro definitions:
+
+
+! {ip_macro}
+!
+! The logic used in initial and final permutations is the same as in
+! the C code. The permutations are done with a clever shift, xor, and
+! technique.
+!
+! The macro also loads address sbox 1 to 5 to global 1 to 5, address
+! sbox 6 to local6, and addres sbox 8 to out3.
+!
+! Rotates the halfs 3 left to bring the sbox bits in convenient positions.
+!
+! Loads key first round from address in parameter 5 to out0, out1.
+!
+! After the the original LibDES initial permutation, the resulting left
+! is in the variable initially used for right and vice versa. The macro
+! implements the possibility to keep the halfs in the original registers.
+!
+! parameter 1  left
+! parameter 2  right
+! parameter 3  result left (modify in first round)
+! parameter 4  result right (use in first round)
+! parameter 5  key address
+! parameter 6  1/2 for include encryption/decryption
+! parameter 7  1 for move in1 to in3
+! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
+! parameter 9  1 for load ks3 and ks2 to in4 and in3
+
+define(ip_macro, {
+
+! {ip_macro}
+! $1 $2 $4 $3 $5 $6 $7 $8 $9
+
+	ld	[out2+256], local1
+	srl	$2, 4, local4
+
+	xor	local4, $1, local4
+	ifelse($7,1,{mov in1, in3},{nop})
+
+	ld	[out2+260], local2
+	and	local4, local1, local4
+	ifelse($8,1,{mov in3, in4},{})
+	ifelse($8,2,{mov in4, in3},{})
+
+	ld	[out2+280], out4          ! loop counter
+	sll	local4, 4, local1
+	xor	$1, local4, $1
+
+	ld	[out2+264], local3
+	srl	$1, 16, local4
+	xor	$2, local1, $2
+
+	ifelse($9,1,{LDPTR	KS3, in4},{})
+	xor	local4, $2, local4
+	nop	!sethi	%hi(DES_SPtrans), global1 ! sbox addr
+
+	ifelse($9,1,{LDPTR	KS2, in3},{})
+	and	local4, local2, local4
+	nop	!or	global1, %lo(DES_SPtrans), global1   ! sbox addr
+
+	sll	local4, 16, local1
+	xor	$2, local4, $2
+
+	srl	$2, 2, local4
+	xor	$1, local1, $1
+
+	sethi	%hi(16711680), local5
+	xor	local4, $1, local4
+
+	and	local4, local3, local4
+	or	local5, 255, local5
+
+	sll	local4, 2, local2
+	xor	$1, local4, $1
+
+	srl	$1, 8, local4
+	xor	$2, local2, $2
+
+	xor	local4, $2, local4
+	add	global1, 768, global4
+
+	and	local4, local5, local4
+	add	global1, 1024, global5
+
+	ld	[out2+272], local7
+	sll	local4, 8, local1
+	xor	$2, local4, $2
+
+	srl	$2, 1, local4
+	xor	$1, local1, $1
+
+	ld	[$5], out0                ! key 7531
+	xor	local4, $1, local4
+	add	global1, 256, global2
+
+	ld	[$5+4], out1              ! key 8642
+	and	local4, local7, local4
+	add	global1, 512, global3
+
+	sll	local4, 1, local1
+	xor	$1, local4, $1
+
+	sll	$1, 3, local3
+	xor	$2, local1, $2
+
+	sll	$2, 3, local2
+	add	global1, 1280, local6     ! address sbox 8
+
+	srl	$1, 29, local4
+	add	global1, 1792, out3       ! address sbox 8
+
+	srl	$2, 29, local1
+	or	local4, local3, $4
+
+	or	local2, local1, $3
+
+	ifelse($6, 1, {
+
+		ld	[out2+284], local5     ! 0x0000FC00 used in the rounds
+		or	local2, local1, $3
+		xor	$4, out0, local1
+
+		call .des_enc.1
+		and	local1, 252, local1
+
+	},{})
+
+	ifelse($6, 2, {
+
+		ld	[out2+284], local5     ! 0x0000FC00 used in the rounds
+		or	local2, local1, $3
+		xor	$4, out0, local1
+
+		call .des_dec.1
+		and	local1, 252, local1
+
+	},{})
+})
+
+
+! {rounds_macro}
+!
+! The logic used in the DES rounds is the same as in the C code,
+! except that calculations for sbox 1 and sbox 5 begin before
+! the previous round is finished.
+!
+! In each round one half (work) is modified based on key and the
+! other half (use).
+!
+! In this version we do two rounds in a loop repeated 7 times
+! and two rounds seperately.
+!
+! One half has the bits for the sboxes in the following positions:
+!
+!	777777xx555555xx333333xx111111xx
+!
+!	88xx666666xx444444xx222222xx8888
+!
+! The bits for each sbox are xor-ed with the key bits for that box.
+! The above xx bits are cleared, and the result used for lookup in
+! the sbox table. Each sbox entry contains the 4 output bits permuted
+! into 32 bits according to the P permutation.
+!
+! In the description of DES, left and right are switched after
+! each round, except after last round. In this code the original
+! left and right are kept in the same register in all rounds, meaning
+! that after the 16 rounds the result for right is in the register
+! originally used for left.
+!
+! parameter 1  first work (left in first round)
+! parameter 2  first use (right in first round)
+! parameter 3  enc/dec  1/-1
+! parameter 4  loop label
+! parameter 5  key address register
+! parameter 6  optional address for key next encryption/decryption
+! parameter 7  not empty for include retl
+!
+! also compares in2 to 8
+
+define(rounds_macro, {
+
+! {rounds_macro}
+! $1 $2 $3 $4 $5 $6 $7 $8 $9
+
+	xor	$2, out0, local1
+
+	ld	[out2+284], local5        ! 0x0000FC00
+	ba	$4
+	and	local1, 252, local1
+
+	.align 32
+
+$4:
+	! local6 is address sbox 6
+	! out3   is address sbox 8
+	! out4   is loop counter
+
+	ld	[global1+local1], local1
+	xor	$2, out1, out1            ! 8642
+	xor	$2, out0, out0            ! 7531
+	! fmovs	%f0, %f0                  ! fxor used for alignment
+
+	srl	out1, 4, local0           ! rotate 4 right
+	and	out0, local5, local3      ! 3
+	! fmovs	%f0, %f0
+
+	ld	[$5+$3*8], local7         ! key 7531 next round
+	srl	local3, 8, local3         ! 3
+	and	local0, 252, local2       ! 2
+	! fmovs	%f0, %f0
+
+	ld	[global3+local3],local3   ! 3
+	sll	out1, 28, out1            ! rotate
+	xor	$1, local1, $1            ! 1 finished, local1 now sbox 7
+
+	ld	[global2+local2], local2  ! 2 
+	srl	out0, 24, local1          ! 7
+	or	out1, local0, out1        ! rotate
+
+	ldub	[out2+local1], local1     ! 7 (and 0xFC)
+	srl	out1, 24, local0          ! 8
+	and	out1, local5, local4      ! 4
+
+	ldub	[out2+local0], local0     ! 8 (and 0xFC)
+	srl	local4, 8, local4         ! 4
+	xor	$1, local2, $1            ! 2 finished local2 now sbox 6
+
+	ld	[global4+local4],local4   ! 4
+	srl	out1, 16, local2          ! 6
+	xor	$1, local3, $1            ! 3 finished local3 now sbox 5
+
+	ld	[out3+local0],local0      ! 8
+	and	local2, 252, local2       ! 6
+	add	global1, 1536, local5     ! address sbox 7
+
+	ld	[local6+local2], local2   ! 6
+	srl	out0, 16, local3          ! 5
+	xor	$1, local4, $1            ! 4 finished
+
+	ld	[local5+local1],local1    ! 7
+	and	local3, 252, local3       ! 5
+	xor	$1, local0, $1            ! 8 finished
+
+	ld	[global5+local3],local3   ! 5
+	xor	$1, local2, $1            ! 6 finished
+	subcc	out4, 1, out4
+
+	ld	[$5+$3*8+4], out0         ! key 8642 next round
+	xor	$1, local7, local2        ! sbox 5 next round
+	xor	$1, local1, $1            ! 7 finished
+
+	srl	local2, 16, local2        ! sbox 5 next round
+	xor	$1, local3, $1            ! 5 finished
+
+	ld	[$5+$3*16+4], out1        ! key 8642 next round again
+	and	local2, 252, local2       ! sbox5 next round
+! next round
+	xor	$1, local7, local7        ! 7531
+
+	ld	[global5+local2], local2  ! 5
+	srl	local7, 24, local3        ! 7
+	xor	$1, out0, out0            ! 8642
+
+	ldub	[out2+local3], local3     ! 7 (and 0xFC)
+	srl	out0, 4, local0           ! rotate 4 right
+	and	local7, 252, local1       ! 1
+
+	sll	out0, 28, out0            ! rotate
+	xor	$2, local2, $2            ! 5 finished local2 used
+
+	srl	local0, 8, local4         ! 4
+	and	local0, 252, local2       ! 2
+	ld	[local5+local3], local3   ! 7
+
+	srl	local0, 16, local5        ! 6
+	or	out0, local0, out0        ! rotate
+	ld	[global2+local2], local2  ! 2
+
+	srl	out0, 24, local0
+	ld	[$5+$3*16], out0          ! key 7531 next round
+	and	local4, 252, local4	  ! 4
+
+	and	local5, 252, local5       ! 6
+	ld	[global4+local4], local4  ! 4
+	xor	$2, local3, $2            ! 7 finished local3 used
+
+	and	local0, 252, local0       ! 8
+	ld	[local6+local5], local5   ! 6
+	xor	$2, local2, $2            ! 2 finished local2 now sbox 3
+
+	srl	local7, 8, local2         ! 3 start
+	ld	[out3+local0], local0     ! 8
+	xor	$2, local4, $2            ! 4 finished
+
+	and	local2, 252, local2       ! 3
+	ld	[global1+local1], local1  ! 1
+	xor	$2, local5, $2            ! 6 finished local5 used
+
+	ld	[global3+local2], local2  ! 3
+	xor	$2, local0, $2            ! 8 finished
+	add	$5, $3*16, $5             ! enc add 8, dec add -8 to key pointer
+
+	ld	[out2+284], local5        ! 0x0000FC00
+	xor	$2, out0, local4          ! sbox 1 next round
+	xor	$2, local1, $2            ! 1 finished
+
+	xor	$2, local2, $2            ! 3 finished
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	bne,pt	%icc, $4
+#else
+	bne	$4
+#endif
+	and	local4, 252, local1       ! sbox 1 next round
+
+! two rounds more:
+
+	ld	[global1+local1], local1
+	xor	$2, out1, out1
+	xor	$2, out0, out0
+
+	srl	out1, 4, local0           ! rotate
+	and	out0, local5, local3
+
+	ld	[$5+$3*8], local7         ! key 7531
+	srl	local3, 8, local3
+	and	local0, 252, local2
+
+	ld	[global3+local3],local3
+	sll	out1, 28, out1            ! rotate
+	xor	$1, local1, $1            ! 1 finished, local1 now sbox 7
+
+	ld	[global2+local2], local2
+	srl	out0, 24, local1
+	or	out1, local0, out1        ! rotate
+
+	ldub	[out2+local1], local1
+	srl	out1, 24, local0
+	and	out1, local5, local4
+
+	ldub	[out2+local0], local0
+	srl	local4, 8, local4
+	xor	$1, local2, $1            ! 2 finished local2 now sbox 6
+
+	ld	[global4+local4],local4
+	srl	out1, 16, local2
+	xor	$1, local3, $1            ! 3 finished local3 now sbox 5
+
+	ld	[out3+local0],local0
+	and	local2, 252, local2
+	add	global1, 1536, local5     ! address sbox 7
+
+	ld	[local6+local2], local2
+	srl	out0, 16, local3
+	xor	$1, local4, $1            ! 4 finished
+
+	ld	[local5+local1],local1
+	and	local3, 252, local3
+	xor	$1, local0, $1
+
+	ld	[global5+local3],local3
+	xor	$1, local2, $1            ! 6 finished
+	cmp	in2, 8
+
+	ifelse($6,{}, {}, {ld	[out2+280], out4})  ! loop counter
+	xor	$1, local7, local2        ! sbox 5 next round
+	xor	$1, local1, $1            ! 7 finished
+
+	ld	[$5+$3*8+4], out0
+	srl	local2, 16, local2        ! sbox 5 next round
+	xor	$1, local3, $1            ! 5 finished
+
+	and	local2, 252, local2
+! next round (two rounds more)
+	xor	$1, local7, local7        ! 7531
+
+	ld	[global5+local2], local2
+	srl	local7, 24, local3
+	xor	$1, out0, out0            ! 8642
+
+	ldub	[out2+local3], local3
+	srl	out0, 4, local0           ! rotate
+	and	local7, 252, local1
+
+	sll	out0, 28, out0            ! rotate
+	xor	$2, local2, $2            ! 5 finished local2 used
+
+	srl	local0, 8, local4
+	and	local0, 252, local2
+	ld	[local5+local3], local3
+
+	srl	local0, 16, local5
+	or	out0, local0, out0        ! rotate
+	ld	[global2+local2], local2
+
+	srl	out0, 24, local0
+	ifelse($6,{}, {}, {ld	[$6], out0})   ! key next encryption/decryption
+	and	local4, 252, local4
+
+	and	local5, 252, local5
+	ld	[global4+local4], local4
+	xor	$2, local3, $2            ! 7 finished local3 used
+
+	and	local0, 252, local0
+	ld	[local6+local5], local5
+	xor	$2, local2, $2            ! 2 finished local2 now sbox 3
+
+	srl	local7, 8, local2         ! 3 start
+	ld	[out3+local0], local0
+	xor	$2, local4, $2
+
+	and	local2, 252, local2
+	ld	[global1+local1], local1
+	xor	$2, local5, $2            ! 6 finished local5 used
+
+	ld	[global3+local2], local2
+	srl	$1, 3, local3
+	xor	$2, local0, $2
+
+	ifelse($6,{}, {}, {ld	[$6+4], out1}) ! key next encryption/decryption
+	sll	$1, 29, local4
+	xor	$2, local1, $2
+
+	ifelse($7,{}, {}, {retl})
+	xor	$2, local2, $2
+})
+
+
+! {fp_macro}
+!
+!  parameter 1   right (original left)
+!  parameter 2   left (original right)
+!  parameter 3   1 for optional store to [in0]
+!  parameter 4   1 for load input/output address to local5/7
+!
+!  The final permutation logic switches the halfes, meaning that
+!  left and right ends up the the registers originally used.
+
+define(fp_macro, {
+
+! {fp_macro}
+! $1 $2 $3 $4 $5 $6 $7 $8 $9
+
+	! initially undo the rotate 3 left done after initial permutation
+	! original left is received shifted 3 right and 29 left in local3/4
+
+	sll	$2, 29, local1
+	or	local3, local4, $1
+
+	srl	$2, 3, $2
+	sethi	%hi(0x55555555), local2
+
+	or	$2, local1, $2
+	or	local2, %lo(0x55555555), local2
+
+	srl	$2, 1, local3
+	sethi	%hi(0x00ff00ff), local1
+	xor	local3, $1, local3
+	or	local1, %lo(0x00ff00ff), local1
+	and	local3, local2, local3
+	sethi	%hi(0x33333333), local4
+	sll	local3, 1, local2
+
+	xor	$1, local3, $1
+
+	srl	$1, 8, local3
+	xor	$2, local2, $2
+	xor	local3, $2, local3
+	or	local4, %lo(0x33333333), local4
+	and	local3, local1, local3
+	sethi	%hi(0x0000ffff), local1
+	sll	local3, 8, local2
+
+	xor	$2, local3, $2
+
+	srl	$2, 2, local3
+	xor	$1, local2, $1
+	xor	local3, $1, local3
+	or	local1, %lo(0x0000ffff), local1
+	and	local3, local4, local3
+	sethi	%hi(0x0f0f0f0f), local4
+	sll	local3, 2, local2
+
+	ifelse($4,1, {LDPTR INPUT, local5})
+	xor	$1, local3, $1
+
+	ifelse($4,1, {LDPTR OUTPUT, local7})
+	srl	$1, 16, local3
+	xor	$2, local2, $2
+	xor	local3, $2, local3
+	or	local4, %lo(0x0f0f0f0f), local4
+	and	local3, local1, local3
+	sll	local3, 16, local2
+
+	xor	$2, local3, local1
+
+	srl	local1, 4, local3
+	xor	$1, local2, $1
+	xor	local3, $1, local3
+	and	local3, local4, local3
+	sll	local3, 4, local2
+
+	xor	$1, local3, $1
+
+	! optional store:
+
+	ifelse($3,1, {st $1, [in0]})
+
+	xor	local1, local2, $2
+
+	ifelse($3,1, {st $2, [in0+4]})
+
+})
+
+
+! {fp_ip_macro}
+!
+! Does initial permutation for next block mixed with
+! final permutation for current block.
+!
+! parameter 1   original left
+! parameter 2   original right
+! parameter 3   left ip
+! parameter 4   right ip
+! parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
+!                2: mov in4 to in3
+!
+! also adds -8 to length in2 and loads loop counter to out4
+
+define(fp_ip_macro, {
+
+! {fp_ip_macro}
+! $1 $2 $3 $4 $5 $6 $7 $8 $9
+
+	define({temp1},{out4})
+	define({temp2},{local3})
+
+	define({ip1},{local1})
+	define({ip2},{local2})
+	define({ip4},{local4})
+	define({ip5},{local5})
+
+	! $1 in local3, local4
+
+	ld	[out2+256], ip1
+	sll	out5, 29, temp1
+	or	local3, local4, $1
+
+	srl	out5, 3, $2
+	ifelse($5,2,{mov in4, in3})
+
+	ld	[out2+272], ip5
+	srl	$4, 4, local0
+	or	$2, temp1, $2
+
+	srl	$2, 1, temp1
+	xor	temp1, $1, temp1
+
+	and	temp1, ip5, temp1
+	xor	local0, $3, local0
+
+	sll	temp1, 1, temp2
+	xor	$1, temp1, $1
+
+	and	local0, ip1, local0
+	add	in2, -8, in2
+
+	sll	local0, 4, local7
+	xor	$3, local0, $3
+
+	ld	[out2+268], ip4
+	srl	$1, 8, temp1
+	xor	$2, temp2, $2
+	ld	[out2+260], ip2
+	srl	$3, 16, local0
+	xor	$4, local7, $4
+	xor	temp1, $2, temp1
+	xor	local0, $4, local0
+	and	temp1, ip4, temp1
+	and	local0, ip2, local0
+	sll	temp1, 8, temp2
+	xor	$2, temp1, $2
+	sll	local0, 16, local7
+	xor	$4, local0, $4
+
+	srl	$2, 2, temp1
+	xor	$1, temp2, $1
+
+	ld	[out2+264], temp2         ! ip3
+	srl	$4, 2, local0
+	xor	$3, local7, $3
+	xor	temp1, $1, temp1
+	xor	local0, $3, local0
+	and	temp1, temp2, temp1
+	and	local0, temp2, local0
+	sll	temp1, 2, temp2
+	xor	$1, temp1, $1
+	sll	local0, 2, local7
+	xor	$3, local0, $3
+
+	srl	$1, 16, temp1
+	xor	$2, temp2, $2
+	srl	$3, 8, local0
+	xor	$4, local7, $4
+	xor	temp1, $2, temp1
+	xor	local0, $4, local0
+	and	temp1, ip2, temp1
+	and	local0, ip4, local0
+	sll	temp1, 16, temp2
+	xor	$2, temp1, local4
+	sll	local0, 8, local7
+	xor	$4, local0, $4
+
+	srl	$4, 1, local0
+	xor	$3, local7, $3
+
+	srl	local4, 4, temp1
+	xor	local0, $3, local0
+
+	xor	$1, temp2, $1
+	and	local0, ip5, local0
+
+	sll	local0, 1, local7
+	xor	temp1, $1, temp1
+
+	xor	$3, local0, $3
+	xor	$4, local7, $4
+
+	sll	$3, 3, local5
+	and	temp1, ip1, temp1
+
+	sll	temp1, 4, temp2
+	xor	$1, temp1, $1
+
+	ifelse($5,1,{LDPTR	KS2, in4})
+	sll	$4, 3, local2
+	xor	local4, temp2, $2
+
+	! reload since used as temporar:
+
+	ld	[out2+280], out4          ! loop counter
+
+	srl	$3, 29, local0
+	ifelse($5,1,{add in4, 120, in4})
+
+	ifelse($5,1,{LDPTR	KS1, in3})
+	srl	$4, 29, local7
+
+	or	local0, local5, $4
+	or	local2, local7, $3
+
+})
+
+
+
+! {load_little_endian}
+!
+! parameter 1  address
+! parameter 2  destination left
+! parameter 3  destination right
+! parameter 4  temporar
+! parameter 5  label
+
+define(load_little_endian, {
+
+! {load_little_endian}
+! $1 $2 $3 $4 $5 $6 $7 $8 $9
+
+	! first in memory to rightmost in register
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	andcc	$1, 3, global0
+	bne,pn	%icc, $5
+	nop
+
+	lda	[$1] 0x88, $2
+	add	$1, 4, $4
+
+	ba,pt	%icc, $5a
+	lda	[$4] 0x88, $3
+#endif
+
+$5:
+	ldub	[$1+3], $2
+
+	ldub	[$1+2], $4
+	sll	$2, 8, $2
+	or	$2, $4, $2
+
+	ldub	[$1+1], $4
+	sll	$2, 8, $2
+	or	$2, $4, $2
+
+	ldub	[$1+0], $4
+	sll	$2, 8, $2
+	or	$2, $4, $2
+
+
+	ldub	[$1+3+4], $3
+
+	ldub	[$1+2+4], $4
+	sll	$3, 8, $3
+	or	$3, $4, $3
+
+	ldub	[$1+1+4], $4
+	sll	$3, 8, $3
+	or	$3, $4, $3
+
+	ldub	[$1+0+4], $4
+	sll	$3, 8, $3
+	or	$3, $4, $3
+$5a:
+
+})
+
+
+! {load_little_endian_inc}
+!
+! parameter 1  address
+! parameter 2  destination left
+! parameter 3  destination right
+! parameter 4  temporar
+! parameter 4  label
+!
+! adds 8 to address
+
+define(load_little_endian_inc, {
+
+! {load_little_endian_inc}
+! $1 $2 $3 $4 $5 $6 $7 $8 $9
+
+	! first in memory to rightmost in register
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	andcc	$1, 3, global0
+	bne,pn	%icc, $5
+	nop
+
+	lda	[$1] 0x88, $2
+	add	$1, 4, $1
+
+	lda	[$1] 0x88, $3
+	ba,pt	%icc, $5a
+	add	$1, 4, $1
+#endif
+
+$5:
+	ldub	[$1+3], $2
+
+	ldub	[$1+2], $4
+	sll	$2, 8, $2
+	or	$2, $4, $2
+
+	ldub	[$1+1], $4
+	sll	$2, 8, $2
+	or	$2, $4, $2
+
+	ldub	[$1+0], $4
+	sll	$2, 8, $2
+	or	$2, $4, $2
+
+	ldub	[$1+3+4], $3
+	add	$1, 8, $1
+
+	ldub	[$1+2+4-8], $4
+	sll	$3, 8, $3
+	or	$3, $4, $3
+
+	ldub	[$1+1+4-8], $4
+	sll	$3, 8, $3
+	or	$3, $4, $3
+
+	ldub	[$1+0+4-8], $4
+	sll	$3, 8, $3
+	or	$3, $4, $3
+$5a:
+
+})
+
+
+! {load_n_bytes}
+!
+! Loads 1 to 7 bytes little endian
+! Remaining bytes are zeroed.
+!
+! parameter 1  address
+! parameter 2  length
+! parameter 3  destination register left
+! parameter 4  destination register right
+! parameter 5  temp
+! parameter 6  temp2
+! parameter 7  label
+! parameter 8  return label
+
+define(load_n_bytes, {
+
+! {load_n_bytes}
+! $1 $2 $5 $6 $7 $8 $7 $8 $9
+
+$7.0:	call	.+8
+	sll	$2, 2, $6
+
+	add	%o7,$7.jmp.table-$7.0,$5
+
+	add	$5, $6, $5
+	mov	0, $4
+
+	ld	[$5], $5
+
+	jmp	%o7+$5
+	mov	0, $3
+
+$7.7:
+	ldub	[$1+6], $5
+	sll	$5, 16, $5
+	or	$3, $5, $3
+$7.6:
+	ldub	[$1+5], $5
+	sll	$5, 8, $5
+	or	$3, $5, $3
+$7.5:
+	ldub	[$1+4], $5
+	or	$3, $5, $3
+$7.4:
+	ldub	[$1+3], $5
+	sll	$5, 24, $5
+	or	$4, $5, $4
+$7.3:
+	ldub	[$1+2], $5
+	sll	$5, 16, $5
+	or	$4, $5, $4
+$7.2:
+	ldub	[$1+1], $5
+	sll	$5, 8, $5
+	or	$4, $5, $4
+$7.1:
+	ldub	[$1+0], $5
+	ba	$8
+	or	$4, $5, $4
+
+	.align 4
+
+$7.jmp.table:
+	.word	0
+	.word	$7.1-$7.0
+	.word	$7.2-$7.0
+	.word	$7.3-$7.0
+	.word	$7.4-$7.0
+	.word	$7.5-$7.0
+	.word	$7.6-$7.0
+	.word	$7.7-$7.0
+})
+
+
+! {store_little_endian}
+!
+! parameter 1  address
+! parameter 2  source left
+! parameter 3  source right
+! parameter 4  temporar
+
+define(store_little_endian, {
+
+! {store_little_endian}
+! $1 $2 $3 $4 $5 $6 $7 $8 $9
+
+	! rightmost in register to first in memory
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	andcc	$1, 3, global0
+	bne,pn	%icc, $5
+	nop
+
+	sta	$2, [$1] 0x88
+	add	$1, 4, $4
+
+	ba,pt	%icc, $5a
+	sta	$3, [$4] 0x88
+#endif
+
+$5:
+	and	$2, 255, $4
+	stub	$4, [$1+0]
+
+	srl	$2, 8, $4
+	and	$4, 255, $4
+	stub	$4, [$1+1]
+
+	srl	$2, 16, $4
+	and	$4, 255, $4
+	stub	$4, [$1+2]
+
+	srl	$2, 24, $4
+	stub	$4, [$1+3]
+
+
+	and	$3, 255, $4
+	stub	$4, [$1+0+4]
+
+	srl	$3, 8, $4
+	and	$4, 255, $4
+	stub	$4, [$1+1+4]
+
+	srl	$3, 16, $4
+	and	$4, 255, $4
+	stub	$4, [$1+2+4]
+
+	srl	$3, 24, $4
+	stub	$4, [$1+3+4]
+
+$5a:
+
+})
+
+
+! {store_n_bytes}
+!
+! Stores 1 to 7 bytes little endian
+!
+! parameter 1  address
+! parameter 2  length
+! parameter 3  source register left
+! parameter 4  source register right
+! parameter 5  temp
+! parameter 6  temp2
+! parameter 7  label
+! parameter 8  return label
+
+define(store_n_bytes, {
+
+! {store_n_bytes}
+! $1 $2 $5 $6 $7 $8 $7 $8 $9
+
+$7.0:	call	.+8
+	sll	$2, 2, $6
+
+	add	%o7,$7.jmp.table-$7.0,$5
+
+	add	$5, $6, $5
+
+	ld	[$5], $5
+
+	jmp	%o7+$5
+	nop
+
+$7.7:
+	srl	$3, 16, $5
+	and	$5, 0xff, $5
+	stub	$5, [$1+6]
+$7.6:
+	srl	$3, 8, $5
+	and	$5, 0xff, $5
+	stub	$5, [$1+5]
+$7.5:
+	and	$3, 0xff, $5
+	stub	$5, [$1+4]
+$7.4:
+	srl	$4, 24, $5
+	stub	$5, [$1+3]
+$7.3:
+	srl	$4, 16, $5
+	and	$5, 0xff, $5
+	stub	$5, [$1+2]
+$7.2:
+	srl	$4, 8, $5
+	and	$5, 0xff, $5
+	stub	$5, [$1+1]
+$7.1:
+	and	$4, 0xff, $5
+
+
+	ba	$8
+	stub	$5, [$1]
+
+	.align 4
+
+$7.jmp.table:
+
+	.word	0
+	.word	$7.1-$7.0
+	.word	$7.2-$7.0
+	.word	$7.3-$7.0
+	.word	$7.4-$7.0
+	.word	$7.5-$7.0
+	.word	$7.6-$7.0
+	.word	$7.7-$7.0
+})
+
+
+define(testvalue,{1})
+
+define(register_init, {
+
+! For test purposes:
+
+	sethi	%hi(testvalue), local0
+	or	local0, %lo(testvalue), local0
+
+	ifelse($1,{},{}, {mov	local0, $1})
+	ifelse($2,{},{}, {mov	local0, $2})
+	ifelse($3,{},{}, {mov	local0, $3})
+	ifelse($4,{},{}, {mov	local0, $4})
+	ifelse($5,{},{}, {mov	local0, $5})
+	ifelse($6,{},{}, {mov	local0, $6})
+	ifelse($7,{},{}, {mov	local0, $7})
+	ifelse($8,{},{}, {mov	local0, $8})
+
+	mov	local0, local1
+	mov	local0, local2
+	mov	local0, local3
+	mov	local0, local4
+	mov	local0, local5
+	mov	local0, local7
+	mov	local0, local6
+	mov	local0, out0
+	mov	local0, out1
+	mov	local0, out2
+	mov	local0, out3
+	mov	local0, out4
+	mov	local0, out5
+	mov	local0, global1
+	mov	local0, global2
+	mov	local0, global3
+	mov	local0, global4
+	mov	local0, global5
+
+})
+
+.section	".text"
+
+	.align 32
+
+.des_enc:
+
+	! key address in3
+	! loads key next encryption/decryption first round from [in4]
+
+	rounds_macro(in5, out5, 1, .des_enc.1, in3, in4, retl)
+
+
+	.align 32
+
+.des_dec:
+
+	! implemented with out5 as first parameter to avoid
+	! register exchange in ede modes
+
+	! key address in4
+	! loads key next encryption/decryption first round from [in3]
+
+	rounds_macro(out5, in5, -1, .des_dec.1, in4, in3, retl)
+
+
+
+! void DES_encrypt1(data, ks, enc)
+! *******************************
+
+	.align 32
+	.global DES_encrypt1
+	.type	 DES_encrypt1,#function
+
+DES_encrypt1:
+
+	save	%sp, FRAME, %sp
+
+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
+1:	call	.+8
+	add	%o7,global1,global1
+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
+
+	ld	[in0], in5                ! left
+	cmp	in2, 0                    ! enc
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	be,pn	%icc, .encrypt.dec        ! enc/dec
+#else
+	be	.encrypt.dec
+#endif
+	ld	[in0+4], out5             ! right
+
+	! parameter 6  1/2 for include encryption/decryption
+	! parameter 7  1 for move in1 to in3
+	! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
+
+	ip_macro(in5, out5, in5, out5, in3, 0, 1, 1)
+
+	rounds_macro(in5, out5, 1, .des_encrypt1.1, in3, in4) ! in4 not used
+
+	fp_macro(in5, out5, 1)            ! 1 for store to [in0]
+
+	ret
+	restore
+
+.encrypt.dec:
+
+	add	in1, 120, in3             ! use last subkey for first round
+
+	! parameter 6  1/2 for include encryption/decryption
+	! parameter 7  1 for move in1 to in3
+	! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
+
+	ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include dec,  ks in4
+
+	fp_macro(out5, in5, 1)            ! 1 for store to [in0]
+
+	ret
+	restore
+
+.DES_encrypt1.end:
+	.size	 DES_encrypt1,.DES_encrypt1.end-DES_encrypt1
+
+
+! void DES_encrypt2(data, ks, enc)
+!*********************************
+
+	! encrypts/decrypts without initial/final permutation
+
+	.align 32
+	.global DES_encrypt2
+	.type	 DES_encrypt2,#function
+
+DES_encrypt2:
+
+	save	%sp, FRAME, %sp
+
+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
+1:	call	.+8
+	add	%o7,global1,global1
+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
+
+	! Set sbox address 1 to 6 and rotate halfs 3 left
+	! Errors caught by destest? Yes. Still? *NO*
+
+	!sethi	%hi(DES_SPtrans), global1 ! address sbox 1
+
+	!or	global1, %lo(DES_SPtrans), global1  ! sbox 1
+
+	add	global1, 256, global2     ! sbox 2
+	add	global1, 512, global3     ! sbox 3
+
+	ld	[in0], out5               ! right
+	add	global1, 768, global4     ! sbox 4
+	add	global1, 1024, global5    ! sbox 5
+
+	ld	[in0+4], in5              ! left
+	add	global1, 1280, local6     ! sbox 6
+	add	global1, 1792, out3       ! sbox 8
+
+	! rotate
+
+	sll	in5, 3, local5
+	mov	in1, in3                  ! key address to in3
+
+	sll	out5, 3, local7
+	srl	in5, 29, in5
+
+	srl	out5, 29, out5
+	add	in5, local5, in5
+
+	add	out5, local7, out5
+	cmp	in2, 0
+
+	! we use our own stackframe
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	be,pn	%icc, .encrypt2.dec       ! decryption
+#else
+	be	.encrypt2.dec
+#endif
+	STPTR	in0, [%sp+BIAS+ARG0+0*ARGSZ]
+
+	ld	[in3], out0               ! key 7531 first round
+	mov	LOOPS, out4               ! loop counter
+
+	ld	[in3+4], out1             ! key 8642 first round
+	sethi	%hi(0x0000FC00), local5
+
+	call .des_enc
+	mov	in3, in4
+
+	! rotate
+	sll	in5, 29, in0
+	srl	in5, 3, in5
+	sll	out5, 29, in1
+	add	in5, in0, in5
+	srl	out5, 3, out5
+	LDPTR	[%sp+BIAS+ARG0+0*ARGSZ], in0
+	add	out5, in1, out5
+	st	in5, [in0]
+	st	out5, [in0+4]
+
+	ret
+	restore
+
+
+.encrypt2.dec:
+
+	add in3, 120, in4
+
+	ld	[in4], out0               ! key 7531 first round
+	mov	LOOPS, out4               ! loop counter
+
+	ld	[in4+4], out1             ! key 8642 first round
+	sethi	%hi(0x0000FC00), local5
+
+	mov	in5, local1               ! left expected in out5
+	mov	out5, in5
+
+	call .des_dec
+	mov	local1, out5
+
+.encrypt2.finish:
+
+	! rotate
+	sll	in5, 29, in0
+	srl	in5, 3, in5
+	sll	out5, 29, in1
+	add	in5, in0, in5
+	srl	out5, 3, out5
+	LDPTR	[%sp+BIAS+ARG0+0*ARGSZ], in0
+	add	out5, in1, out5
+	st	out5, [in0]
+	st	in5, [in0+4]
+
+	ret
+	restore
+
+.DES_encrypt2.end:
+	.size	 DES_encrypt2, .DES_encrypt2.end-DES_encrypt2
+
+
+! void DES_encrypt3(data, ks1, ks2, ks3)
+! **************************************
+
+	.align 32
+	.global DES_encrypt3
+	.type	 DES_encrypt3,#function
+
+DES_encrypt3:
+
+	save	%sp, FRAME, %sp
+	
+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
+1:	call	.+8
+	add	%o7,global1,global1
+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
+
+	ld	[in0], in5                ! left
+	add	in2, 120, in4             ! ks2
+
+	ld	[in0+4], out5             ! right
+	mov	in3, in2                  ! save ks3
+
+	! parameter 6  1/2 for include encryption/decryption
+	! parameter 7  1 for mov in1 to in3
+	! parameter 8  1 for mov in3 to in4
+	! parameter 9  1 for load ks3 and ks2 to in4 and in3
+
+	ip_macro(in5, out5, in5, out5, in3, 1, 1, 0, 0)
+
+	call	.des_dec
+	mov	in2, in3                  ! preload ks3
+
+	call	.des_enc
+	nop
+
+	fp_macro(in5, out5, 1)
+
+	ret
+	restore
+
+.DES_encrypt3.end:
+	.size	 DES_encrypt3,.DES_encrypt3.end-DES_encrypt3
+
+
+! void DES_decrypt3(data, ks1, ks2, ks3)
+! **************************************
+
+	.align 32
+	.global DES_decrypt3
+	.type	 DES_decrypt3,#function
+
+DES_decrypt3:
+
+	save	%sp, FRAME, %sp
+	
+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
+1:	call	.+8
+	add	%o7,global1,global1
+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
+
+	ld	[in0], in5                ! left
+	add	in3, 120, in4             ! ks3
+
+	ld	[in0+4], out5             ! right
+	mov	in2, in3                  ! ks2
+
+	! parameter 6  1/2 for include encryption/decryption
+	! parameter 7  1 for mov in1 to in3
+	! parameter 8  1 for mov in3 to in4
+	! parameter 9  1 for load ks3 and ks2 to in4 and in3
+
+	ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 0)
+
+	call	.des_enc
+	add	in1, 120, in4             ! preload ks1
+
+	call	.des_dec
+	nop
+
+	fp_macro(out5, in5, 1)
+
+	ret
+	restore
+
+.DES_decrypt3.end:
+	.size	 DES_decrypt3,.DES_decrypt3.end-DES_decrypt3
+
+! void DES_ncbc_encrypt(input, output, length, schedule, ivec, enc)
+! *****************************************************************
+
+
+	.align 32
+	.global DES_ncbc_encrypt
+	.type	 DES_ncbc_encrypt,#function
+
+DES_ncbc_encrypt:
+
+	save	%sp, FRAME, %sp
+	
+	define({INPUT},  { [%sp+BIAS+ARG0+0*ARGSZ] })
+	define({OUTPUT}, { [%sp+BIAS+ARG0+1*ARGSZ] })
+	define({IVEC},   { [%sp+BIAS+ARG0+4*ARGSZ] })
+
+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
+1:	call	.+8
+	add	%o7,global1,global1
+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
+
+	cmp	in5, 0                    ! enc   
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	be,pn	%icc, .ncbc.dec
+#else
+	be	.ncbc.dec
+#endif
+	STPTR	in4, IVEC
+
+	! addr  left  right  temp  label
+	load_little_endian(in4, in5, out5, local3, .LLE1)  ! iv
+
+	addcc	in2, -8, in2              ! bytes missing when first block done
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	bl,pn	%icc, .ncbc.enc.seven.or.less
+#else
+	bl	.ncbc.enc.seven.or.less
+#endif
+	mov	in3, in4                  ! schedule
+
+.ncbc.enc.next.block:
+
+	load_little_endian(in0, out4, global4, local3, .LLE2)  ! block
+
+.ncbc.enc.next.block_1:
+
+	xor	in5, out4, in5            ! iv xor
+	xor	out5, global4, out5       ! iv xor
+
+	! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
+	ip_macro(in5, out5, in5, out5, in3, 0, 0, 2)
+
+.ncbc.enc.next.block_2:
+
+!//	call .des_enc                     ! compares in2 to 8
+!	rounds inlined for alignment purposes
+
+	add	global1, 768, global4     ! address sbox 4 since register used below
+
+	rounds_macro(in5, out5, 1, .ncbc.enc.1, in3, in4) ! include encryption  ks in3
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	bl,pn	%icc, .ncbc.enc.next.block_fp
+#else
+	bl	.ncbc.enc.next.block_fp
+#endif
+	add	in0, 8, in0               ! input address
+
+	! If 8 or more bytes are to be encrypted after this block,
+	! we combine final permutation for this block with initial
+	! permutation for next block. Load next block:
+
+	load_little_endian(in0, global3, global4, local5, .LLE12)
+
+	!  parameter 1   original left
+	!  parameter 2   original right
+	!  parameter 3   left ip
+	!  parameter 4   right ip
+	!  parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
+	!                2: mov in4 to in3
+	!
+	! also adds -8 to length in2 and loads loop counter to out4
+
+	fp_ip_macro(out0, out1, global3, global4, 2)
+
+	store_little_endian(in1, out0, out1, local3, .SLE10)  ! block
+
+	ld	[in3], out0               ! key 7531 first round next block
+	mov 	in5, local1
+	xor	global3, out5, in5        ! iv xor next block
+
+	ld	[in3+4], out1             ! key 8642
+	add	global1, 512, global3     ! address sbox 3 since register used
+	xor	global4, local1, out5     ! iv xor next block
+
+	ba	.ncbc.enc.next.block_2
+	add	in1, 8, in1               ! output adress
+
+.ncbc.enc.next.block_fp:
+
+	fp_macro(in5, out5)
+
+	store_little_endian(in1, in5, out5, local3, .SLE1)  ! block
+
+	addcc   in2, -8, in2              ! bytes missing when next block done
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	bpos,pt	%icc, .ncbc.enc.next.block  ! also jumps if 0
+#else
+	bpos	.ncbc.enc.next.block
+#endif
+	add	in1, 8, in1
+
+.ncbc.enc.seven.or.less:
+
+	cmp	in2, -8
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	ble,pt	%icc, .ncbc.enc.finish
+#else
+	ble	.ncbc.enc.finish
+#endif
+	nop
+
+	add	in2, 8, local1            ! bytes to load
+
+	! addr, length, dest left, dest right, temp, temp2, label, ret label
+	load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB1, .ncbc.enc.next.block_1)
+
+	! Loads 1 to 7 bytes little endian to global4, out4
+
+
+.ncbc.enc.finish:
+
+	LDPTR	IVEC, local4
+	store_little_endian(local4, in5, out5, local5, .SLE2)  ! ivec
+
+	ret
+	restore
+
+
+.ncbc.dec:
+
+	STPTR	in0, INPUT
+	cmp	in2, 0                    ! length
+	add	in3, 120, in3
+
+	LDPTR	IVEC, local7              ! ivec
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	ble,pn	%icc, .ncbc.dec.finish
+#else
+	ble	.ncbc.dec.finish
+#endif
+	mov	in3, in4                  ! schedule
+
+	STPTR	in1, OUTPUT
+	mov	in0, local5               ! input
+
+	load_little_endian(local7, in0, in1, local3, .LLE3)   ! ivec
+
+.ncbc.dec.next.block:
+
+	load_little_endian(local5, in5, out5, local3, .LLE4)  ! block
+
+	! parameter 6  1/2 for include encryption/decryption
+	! parameter 7  1 for mov in1 to in3
+	! parameter 8  1 for mov in3 to in4
+
+	ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include decryprion  ks in4
+
+	fp_macro(out5, in5, 0, 1) ! 1 for input and output address to local5/7
+
+	! in2 is bytes left to be stored
+	! in2 is compared to 8 in the rounds
+
+	xor	out5, in0, out4           ! iv xor
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	bl,pn	%icc, .ncbc.dec.seven.or.less
+#else
+	bl	.ncbc.dec.seven.or.less
+#endif
+	xor	in5, in1, global4         ! iv xor
+
+	! Load ivec next block now, since input and output address might be the same.
+
+	load_little_endian_inc(local5, in0, in1, local3, .LLE5)  ! iv
+
+	store_little_endian(local7, out4, global4, local3, .SLE3)
+
+	STPTR	local5, INPUT
+	add	local7, 8, local7
+	addcc   in2, -8, in2
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	bg,pt	%icc, .ncbc.dec.next.block
+#else
+	bg	.ncbc.dec.next.block
+#endif
+	STPTR	local7, OUTPUT
+
+
+.ncbc.dec.store.iv:
+
+	LDPTR	IVEC, local4              ! ivec
+	store_little_endian(local4, in0, in1, local5, .SLE4)
+
+.ncbc.dec.finish:
+
+	ret
+	restore
+
+.ncbc.dec.seven.or.less:
+
+	load_little_endian_inc(local5, in0, in1, local3, .LLE13)     ! ivec
+
+	store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB1, .ncbc.dec.store.iv)
+
+
+.DES_ncbc_encrypt.end:
+	.size	 DES_ncbc_encrypt, .DES_ncbc_encrypt.end-DES_ncbc_encrypt
+
+
+! void DES_ede3_cbc_encrypt(input, output, lenght, ks1, ks2, ks3, ivec, enc)
+! **************************************************************************
+
+
+	.align 32
+	.global DES_ede3_cbc_encrypt
+	.type	 DES_ede3_cbc_encrypt,#function
+
+DES_ede3_cbc_encrypt:
+
+	save	%sp, FRAME, %sp
+
+	define({KS1}, { [%sp+BIAS+ARG0+3*ARGSZ] })
+	define({KS2}, { [%sp+BIAS+ARG0+4*ARGSZ] })
+	define({KS3}, { [%sp+BIAS+ARG0+5*ARGSZ] })
+
+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
+1:	call	.+8
+	add	%o7,global1,global1
+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
+
+	LDPTR	[%fp+BIAS+ARG0+7*ARGSZ], local3          ! enc
+	LDPTR	[%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
+	cmp	local3, 0                 ! enc
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	be,pn	%icc, .ede3.dec
+#else
+	be	.ede3.dec
+#endif
+	STPTR	in4, KS2
+
+	STPTR	in5, KS3
+
+	load_little_endian(local4, in5, out5, local3, .LLE6)  ! ivec
+
+	addcc	in2, -8, in2              ! bytes missing after next block
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	bl,pn	%icc,  .ede3.enc.seven.or.less
+#else
+	bl	.ede3.enc.seven.or.less
+#endif
+	STPTR	in3, KS1
+
+.ede3.enc.next.block:
+
+	load_little_endian(in0, out4, global4, local3, .LLE7)
+
+.ede3.enc.next.block_1:
+
+	LDPTR	KS2, in4
+	xor	in5, out4, in5            ! iv xor
+	xor	out5, global4, out5       ! iv xor
+
+	LDPTR	KS1, in3
+	add	in4, 120, in4             ! for decryption we use last subkey first
+	nop
+
+	ip_macro(in5, out5, in5, out5, in3)
+
+.ede3.enc.next.block_2:
+
+	call .des_enc                     ! ks1 in3
+	nop
+
+	call .des_dec                     ! ks2 in4
+	LDPTR	KS3, in3
+
+	call .des_enc                     ! ks3 in3  compares in2 to 8
+	nop
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	bl,pn	%icc, .ede3.enc.next.block_fp
+#else
+	bl	.ede3.enc.next.block_fp
+#endif
+	add	in0, 8, in0
+
+	! If 8 or more bytes are to be encrypted after this block,
+	! we combine final permutation for this block with initial
+	! permutation for next block. Load next block:
+
+	load_little_endian(in0, global3, global4, local5, .LLE11)
+
+	!  parameter 1   original left
+	!  parameter 2   original right
+	!  parameter 3   left ip
+	!  parameter 4   right ip
+	!  parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
+	!                2: mov in4 to in3
+	!
+	! also adds -8 to length in2 and loads loop counter to out4
+
+	fp_ip_macro(out0, out1, global3, global4, 1)
+
+	store_little_endian(in1, out0, out1, local3, .SLE9)  ! block
+
+	mov 	in5, local1
+	xor	global3, out5, in5        ! iv xor next block
+
+	ld	[in3], out0               ! key 7531
+	add	global1, 512, global3     ! address sbox 3
+	xor	global4, local1, out5     ! iv xor next block
+
+	ld	[in3+4], out1             ! key 8642
+	add	global1, 768, global4     ! address sbox 4
+	ba	.ede3.enc.next.block_2
+	add	in1, 8, in1
+
+.ede3.enc.next.block_fp:
+
+	fp_macro(in5, out5)
+
+	store_little_endian(in1, in5, out5, local3, .SLE5)  ! block
+
+	addcc   in2, -8, in2              ! bytes missing when next block done
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	bpos,pt	%icc, .ede3.enc.next.block
+#else
+	bpos	.ede3.enc.next.block
+#endif
+	add	in1, 8, in1
+
+.ede3.enc.seven.or.less:
+
+	cmp	in2, -8
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	ble,pt	%icc, .ede3.enc.finish
+#else
+	ble	.ede3.enc.finish
+#endif
+	nop
+
+	add	in2, 8, local1            ! bytes to load
+
+	! addr, length, dest left, dest right, temp, temp2, label, ret label
+	load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB2, .ede3.enc.next.block_1)
+
+.ede3.enc.finish:
+
+	LDPTR	[%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
+	store_little_endian(local4, in5, out5, local5, .SLE6)  ! ivec
+
+	ret
+	restore
+
+.ede3.dec:
+
+	STPTR	in0, INPUT
+	add	in5, 120, in5
+
+	STPTR	in1, OUTPUT
+	mov	in0, local5
+	add	in3, 120, in3
+
+	STPTR	in3, KS1
+	cmp	in2, 0
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	ble	%icc, .ede3.dec.finish
+#else
+	ble	.ede3.dec.finish
+#endif
+	STPTR	in5, KS3
+
+	LDPTR	[%fp+BIAS+ARG0+6*ARGSZ], local7          ! iv
+	load_little_endian(local7, in0, in1, local3, .LLE8)
+
+.ede3.dec.next.block:
+
+	load_little_endian(local5, in5, out5, local3, .LLE9)
+
+	! parameter 6  1/2 for include encryption/decryption
+	! parameter 7  1 for mov in1 to in3
+	! parameter 8  1 for mov in3 to in4
+	! parameter 9  1 for load ks3 and ks2 to in4 and in3
+
+	ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 1) ! inc .des_dec ks3 in4
+
+	call .des_enc                     ! ks2 in3
+	LDPTR	KS1, in4
+
+	call .des_dec                     ! ks1 in4
+	nop
+
+	fp_macro(out5, in5, 0, 1)   ! 1 for input and output address local5/7
+
+	! in2 is bytes left to be stored
+	! in2 is compared to 8 in the rounds
+
+	xor	out5, in0, out4
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	bl,pn	%icc, .ede3.dec.seven.or.less
+#else
+	bl	.ede3.dec.seven.or.less
+#endif
+	xor	in5, in1, global4
+
+	load_little_endian_inc(local5, in0, in1, local3, .LLE10)   ! iv next block
+
+	store_little_endian(local7, out4, global4, local3, .SLE7)  ! block
+
+	STPTR	local5, INPUT
+	addcc   in2, -8, in2
+	add	local7, 8, local7
+
+#ifdef OPENSSL_SYSNAME_ULTRASPARC
+	bg,pt	%icc, .ede3.dec.next.block
+#else
+	bg	.ede3.dec.next.block
+#endif
+	STPTR	local7, OUTPUT
+
+.ede3.dec.store.iv:
+
+	LDPTR	[%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
+	store_little_endian(local4, in0, in1, local5, .SLE8)  ! ivec
+
+.ede3.dec.finish:
+
+	ret
+	restore
+
+.ede3.dec.seven.or.less:
+
+	load_little_endian_inc(local5, in0, in1, local3, .LLE14)     ! iv
+
+	store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB2, .ede3.dec.store.iv)
+
+
+.DES_ede3_cbc_encrypt.end:
+	.size	 DES_ede3_cbc_encrypt,.DES_ede3_cbc_encrypt.end-DES_ede3_cbc_encrypt
+
+	.align	256
+	.type	 .des_and,#object
+	.size	 .des_and,284
+
+.des_and:
+
+! This table is used for AND 0xFC when it is known that register
+! bits 8-31 are zero. Makes it possible to do three arithmetic
+! operations in one cycle.
+
+	.byte  0, 0, 0, 0, 4, 4, 4, 4
+	.byte  8, 8, 8, 8, 12, 12, 12, 12
+	.byte  16, 16, 16, 16, 20, 20, 20, 20
+	.byte  24, 24, 24, 24, 28, 28, 28, 28
+	.byte  32, 32, 32, 32, 36, 36, 36, 36
+	.byte  40, 40, 40, 40, 44, 44, 44, 44
+	.byte  48, 48, 48, 48, 52, 52, 52, 52
+	.byte  56, 56, 56, 56, 60, 60, 60, 60
+	.byte  64, 64, 64, 64, 68, 68, 68, 68
+	.byte  72, 72, 72, 72, 76, 76, 76, 76
+	.byte  80, 80, 80, 80, 84, 84, 84, 84
+	.byte  88, 88, 88, 88, 92, 92, 92, 92
+	.byte  96, 96, 96, 96, 100, 100, 100, 100
+	.byte  104, 104, 104, 104, 108, 108, 108, 108
+	.byte  112, 112, 112, 112, 116, 116, 116, 116
+	.byte  120, 120, 120, 120, 124, 124, 124, 124
+	.byte  128, 128, 128, 128, 132, 132, 132, 132
+	.byte  136, 136, 136, 136, 140, 140, 140, 140
+	.byte  144, 144, 144, 144, 148, 148, 148, 148
+	.byte  152, 152, 152, 152, 156, 156, 156, 156
+	.byte  160, 160, 160, 160, 164, 164, 164, 164
+	.byte  168, 168, 168, 168, 172, 172, 172, 172
+	.byte  176, 176, 176, 176, 180, 180, 180, 180
+	.byte  184, 184, 184, 184, 188, 188, 188, 188
+	.byte  192, 192, 192, 192, 196, 196, 196, 196
+	.byte  200, 200, 200, 200, 204, 204, 204, 204
+	.byte  208, 208, 208, 208, 212, 212, 212, 212
+	.byte  216, 216, 216, 216, 220, 220, 220, 220
+	.byte  224, 224, 224, 224, 228, 228, 228, 228
+	.byte  232, 232, 232, 232, 236, 236, 236, 236
+	.byte  240, 240, 240, 240, 244, 244, 244, 244
+	.byte  248, 248, 248, 248, 252, 252, 252, 252
+
+	! 5 numbers for initil/final permutation
+
+	.word   0x0f0f0f0f                ! offset 256
+	.word	0x0000ffff                ! 260
+	.word	0x33333333                ! 264
+	.word	0x00ff00ff                ! 268
+	.word	0x55555555                ! 272
+
+	.word	0                         ! 276
+	.word	LOOPS                     ! 280
+	.word	0x0000FC00                ! 284
+
+	.global	DES_SPtrans
+	.type	DES_SPtrans,#object
+	.size	DES_SPtrans,2048
+.align	64
+DES_SPtrans:
+.PIC.DES_SPtrans:
+	! nibble 0
+	.word	0x02080800, 0x00080000, 0x02000002, 0x02080802
+	.word	0x02000000, 0x00080802, 0x00080002, 0x02000002
+	.word	0x00080802, 0x02080800, 0x02080000, 0x00000802
+	.word	0x02000802, 0x02000000, 0x00000000, 0x00080002
+	.word	0x00080000, 0x00000002, 0x02000800, 0x00080800
+	.word	0x02080802, 0x02080000, 0x00000802, 0x02000800
+	.word	0x00000002, 0x00000800, 0x00080800, 0x02080002
+	.word	0x00000800, 0x02000802, 0x02080002, 0x00000000
+	.word	0x00000000, 0x02080802, 0x02000800, 0x00080002
+	.word	0x02080800, 0x00080000, 0x00000802, 0x02000800
+	.word	0x02080002, 0x00000800, 0x00080800, 0x02000002
+	.word	0x00080802, 0x00000002, 0x02000002, 0x02080000
+	.word	0x02080802, 0x00080800, 0x02080000, 0x02000802
+	.word	0x02000000, 0x00000802, 0x00080002, 0x00000000
+	.word	0x00080000, 0x02000000, 0x02000802, 0x02080800
+	.word	0x00000002, 0x02080002, 0x00000800, 0x00080802
+	! nibble 1
+	.word	0x40108010, 0x00000000, 0x00108000, 0x40100000
+	.word	0x40000010, 0x00008010, 0x40008000, 0x00108000
+	.word	0x00008000, 0x40100010, 0x00000010, 0x40008000
+	.word	0x00100010, 0x40108000, 0x40100000, 0x00000010
+	.word	0x00100000, 0x40008010, 0x40100010, 0x00008000
+	.word	0x00108010, 0x40000000, 0x00000000, 0x00100010
+	.word	0x40008010, 0x00108010, 0x40108000, 0x40000010
+	.word	0x40000000, 0x00100000, 0x00008010, 0x40108010
+	.word	0x00100010, 0x40108000, 0x40008000, 0x00108010
+	.word	0x40108010, 0x00100010, 0x40000010, 0x00000000
+	.word	0x40000000, 0x00008010, 0x00100000, 0x40100010
+	.word	0x00008000, 0x40000000, 0x00108010, 0x40008010
+	.word	0x40108000, 0x00008000, 0x00000000, 0x40000010
+	.word	0x00000010, 0x40108010, 0x00108000, 0x40100000
+	.word	0x40100010, 0x00100000, 0x00008010, 0x40008000
+	.word	0x40008010, 0x00000010, 0x40100000, 0x00108000
+	! nibble 2
+	.word	0x04000001, 0x04040100, 0x00000100, 0x04000101
+	.word	0x00040001, 0x04000000, 0x04000101, 0x00040100
+	.word	0x04000100, 0x00040000, 0x04040000, 0x00000001
+	.word	0x04040101, 0x00000101, 0x00000001, 0x04040001
+	.word	0x00000000, 0x00040001, 0x04040100, 0x00000100
+	.word	0x00000101, 0x04040101, 0x00040000, 0x04000001
+	.word	0x04040001, 0x04000100, 0x00040101, 0x04040000
+	.word	0x00040100, 0x00000000, 0x04000000, 0x00040101
+	.word	0x04040100, 0x00000100, 0x00000001, 0x00040000
+	.word	0x00000101, 0x00040001, 0x04040000, 0x04000101
+	.word	0x00000000, 0x04040100, 0x00040100, 0x04040001
+	.word	0x00040001, 0x04000000, 0x04040101, 0x00000001
+	.word	0x00040101, 0x04000001, 0x04000000, 0x04040101
+	.word	0x00040000, 0x04000100, 0x04000101, 0x00040100
+	.word	0x04000100, 0x00000000, 0x04040001, 0x00000101
+	.word	0x04000001, 0x00040101, 0x00000100, 0x04040000
+	! nibble 3
+	.word	0x00401008, 0x10001000, 0x00000008, 0x10401008
+	.word	0x00000000, 0x10400000, 0x10001008, 0x00400008
+	.word	0x10401000, 0x10000008, 0x10000000, 0x00001008
+	.word	0x10000008, 0x00401008, 0x00400000, 0x10000000
+	.word	0x10400008, 0x00401000, 0x00001000, 0x00000008
+	.word	0x00401000, 0x10001008, 0x10400000, 0x00001000
+	.word	0x00001008, 0x00000000, 0x00400008, 0x10401000
+	.word	0x10001000, 0x10400008, 0x10401008, 0x00400000
+	.word	0x10400008, 0x00001008, 0x00400000, 0x10000008
+	.word	0x00401000, 0x10001000, 0x00000008, 0x10400000
+	.word	0x10001008, 0x00000000, 0x00001000, 0x00400008
+	.word	0x00000000, 0x10400008, 0x10401000, 0x00001000
+	.word	0x10000000, 0x10401008, 0x00401008, 0x00400000
+	.word	0x10401008, 0x00000008, 0x10001000, 0x00401008
+	.word	0x00400008, 0x00401000, 0x10400000, 0x10001008
+	.word	0x00001008, 0x10000000, 0x10000008, 0x10401000
+	! nibble 4
+	.word	0x08000000, 0x00010000, 0x00000400, 0x08010420
+	.word	0x08010020, 0x08000400, 0x00010420, 0x08010000
+	.word	0x00010000, 0x00000020, 0x08000020, 0x00010400
+	.word	0x08000420, 0x08010020, 0x08010400, 0x00000000
+	.word	0x00010400, 0x08000000, 0x00010020, 0x00000420
+	.word	0x08000400, 0x00010420, 0x00000000, 0x08000020
+	.word	0x00000020, 0x08000420, 0x08010420, 0x00010020
+	.word	0x08010000, 0x00000400, 0x00000420, 0x08010400
+	.word	0x08010400, 0x08000420, 0x00010020, 0x08010000
+	.word	0x00010000, 0x00000020, 0x08000020, 0x08000400
+	.word	0x08000000, 0x00010400, 0x08010420, 0x00000000
+	.word	0x00010420, 0x08000000, 0x00000400, 0x00010020
+	.word	0x08000420, 0x00000400, 0x00000000, 0x08010420
+	.word	0x08010020, 0x08010400, 0x00000420, 0x00010000
+	.word	0x00010400, 0x08010020, 0x08000400, 0x00000420
+	.word	0x00000020, 0x00010420, 0x08010000, 0x08000020
+	! nibble 5
+	.word	0x80000040, 0x00200040, 0x00000000, 0x80202000
+	.word	0x00200040, 0x00002000, 0x80002040, 0x00200000
+	.word	0x00002040, 0x80202040, 0x00202000, 0x80000000
+	.word	0x80002000, 0x80000040, 0x80200000, 0x00202040
+	.word	0x00200000, 0x80002040, 0x80200040, 0x00000000
+	.word	0x00002000, 0x00000040, 0x80202000, 0x80200040
+	.word	0x80202040, 0x80200000, 0x80000000, 0x00002040
+	.word	0x00000040, 0x00202000, 0x00202040, 0x80002000
+	.word	0x00002040, 0x80000000, 0x80002000, 0x00202040
+	.word	0x80202000, 0x00200040, 0x00000000, 0x80002000
+	.word	0x80000000, 0x00002000, 0x80200040, 0x00200000
+	.word	0x00200040, 0x80202040, 0x00202000, 0x00000040
+	.word	0x80202040, 0x00202000, 0x00200000, 0x80002040
+	.word	0x80000040, 0x80200000, 0x00202040, 0x00000000
+	.word	0x00002000, 0x80000040, 0x80002040, 0x80202000
+	.word	0x80200000, 0x00002040, 0x00000040, 0x80200040
+	! nibble 6
+	.word	0x00004000, 0x00000200, 0x01000200, 0x01000004
+	.word	0x01004204, 0x00004004, 0x00004200, 0x00000000
+	.word	0x01000000, 0x01000204, 0x00000204, 0x01004000
+	.word	0x00000004, 0x01004200, 0x01004000, 0x00000204
+	.word	0x01000204, 0x00004000, 0x00004004, 0x01004204
+	.word	0x00000000, 0x01000200, 0x01000004, 0x00004200
+	.word	0x01004004, 0x00004204, 0x01004200, 0x00000004
+	.word	0x00004204, 0x01004004, 0x00000200, 0x01000000
+	.word	0x00004204, 0x01004000, 0x01004004, 0x00000204
+	.word	0x00004000, 0x00000200, 0x01000000, 0x01004004
+	.word	0x01000204, 0x00004204, 0x00004200, 0x00000000
+	.word	0x00000200, 0x01000004, 0x00000004, 0x01000200
+	.word	0x00000000, 0x01000204, 0x01000200, 0x00004200
+	.word	0x00000204, 0x00004000, 0x01004204, 0x01000000
+	.word	0x01004200, 0x00000004, 0x00004004, 0x01004204
+	.word	0x01000004, 0x01004200, 0x01004000, 0x00004004
+	! nibble 7
+	.word	0x20800080, 0x20820000, 0x00020080, 0x00000000
+	.word	0x20020000, 0x00800080, 0x20800000, 0x20820080
+	.word	0x00000080, 0x20000000, 0x00820000, 0x00020080
+	.word	0x00820080, 0x20020080, 0x20000080, 0x20800000
+	.word	0x00020000, 0x00820080, 0x00800080, 0x20020000
+	.word	0x20820080, 0x20000080, 0x00000000, 0x00820000
+	.word	0x20000000, 0x00800000, 0x20020080, 0x20800080
+	.word	0x00800000, 0x00020000, 0x20820000, 0x00000080
+	.word	0x00800000, 0x00020000, 0x20000080, 0x20820080
+	.word	0x00020080, 0x20000000, 0x00000000, 0x00820000
+	.word	0x20800080, 0x20020080, 0x20020000, 0x00800080
+	.word	0x20820000, 0x00000080, 0x00800080, 0x20020000
+	.word	0x20820080, 0x00800000, 0x20800000, 0x20000080
+	.word	0x00820000, 0x00020080, 0x20020080, 0x20800000
+	.word	0x00000080, 0x20820000, 0x00820080, 0x00000000
+	.word	0x20000000, 0x20800080, 0x00020000, 0x00820080
+
diff --git a/openssl/crypto/des/asm/desboth.pl b/openssl/crypto/des/asm/desboth.pl
new file mode 100644
index 0000000..eec0088
--- /dev/null
+++ b/openssl/crypto/des/asm/desboth.pl
@@ -0,0 +1,79 @@
+#!/usr/local/bin/perl
+
+$L="edi";
+$R="esi";
+
+sub DES_encrypt3
+	{
+	local($name,$enc)=@_;
+
+	&function_begin_B($name,"");
+	&push("ebx");
+	&mov("ebx",&wparam(0));
+
+	&push("ebp");
+	&push("esi");
+
+	&push("edi");
+
+	&comment("");
+	&comment("Load the data words");
+	&mov($L,&DWP(0,"ebx","",0));
+	&mov($R,&DWP(4,"ebx","",0));
+	&stack_push(3);
+
+	&comment("");
+	&comment("IP");
+	&IP_new($L,$R,"edx",0);
+
+	# put them back
+	
+	if ($enc)
+		{
+		&mov(&DWP(4,"ebx","",0),$R);
+		 &mov("eax",&wparam(1));
+		&mov(&DWP(0,"ebx","",0),"edx");
+		 &mov("edi",&wparam(2));
+		 &mov("esi",&wparam(3));
+		}
+	else
+		{
+		&mov(&DWP(4,"ebx","",0),$R);
+		 &mov("esi",&wparam(1));
+		&mov(&DWP(0,"ebx","",0),"edx");
+		 &mov("edi",&wparam(2));
+		 &mov("eax",&wparam(3));
+		}
+	&mov(&swtmp(2),	(DWC(($enc)?"1":"0")));
+	&mov(&swtmp(1),	"eax");
+	&mov(&swtmp(0),	"ebx");
+	&call("DES_encrypt2");
+	&mov(&swtmp(2),	(DWC(($enc)?"0":"1")));
+	&mov(&swtmp(1),	"edi");
+	&mov(&swtmp(0),	"ebx");
+	&call("DES_encrypt2");
+	&mov(&swtmp(2),	(DWC(($enc)?"1":"0")));
+	&mov(&swtmp(1),	"esi");
+	&mov(&swtmp(0),	"ebx");
+	&call("DES_encrypt2");
+
+	&stack_pop(3);
+	&mov($L,&DWP(0,"ebx","",0));
+	&mov($R,&DWP(4,"ebx","",0));
+
+	&comment("");
+	&comment("FP");
+	&FP_new($L,$R,"eax",0);
+
+	&mov(&DWP(0,"ebx","",0),"eax");
+	&mov(&DWP(4,"ebx","",0),$R);
+
+	&pop("edi");
+	&pop("esi");
+	&pop("ebp");
+	&pop("ebx");
+	&ret();
+	&function_end_B($name);
+	}
+
+
diff --git a/openssl/crypto/des/asm/readme b/openssl/crypto/des/asm/readme
new file mode 100644
index 0000000..1beafe2
--- /dev/null
+++ b/openssl/crypto/des/asm/readme
@@ -0,0 +1,131 @@
+First up, let me say I don't like writing in assembler.  It is not portable,
+dependant on the particular CPU architecture release and is generally a pig
+to debug and get right.  Having said that, the x86 architecture is probably
+the most important for speed due to number of boxes and since
+it appears to be the worst architecture to to get
+good C compilers for.  So due to this, I have lowered myself to do
+assembler for the inner DES routines in libdes :-).
+
+The file to implement in assembler is des_enc.c.  Replace the following
+4 functions
+des_encrypt1(DES_LONG data[2],des_key_schedule ks, int encrypt);
+des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt);
+des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
+des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
+
+They encrypt/decrypt the 64 bits held in 'data' using
+the 'ks' key schedules.   The only difference between the 4 functions is that
+des_encrypt2() does not perform IP() or FP() on the data (this is an
+optimization for when doing triple DES and des_encrypt3() and des_decrypt3()
+perform triple des.  The triple DES routines are in here because it does
+make a big difference to have them located near the des_encrypt2 function
+at link time..
+
+Now as we all know, there are lots of different operating systems running on
+x86 boxes, and unfortunately they normally try to make sure their assembler
+formating is not the same as the other peoples.
+The 4 main formats I know of are
+Microsoft	Windows 95/Windows NT
+Elf		Includes Linux and FreeBSD(?).
+a.out		The older Linux.
+Solaris		Same as Elf but different comments :-(.
+
+Now I was not overly keen to write 4 different copies of the same code,
+so I wrote a few perl routines to output the correct assembler, given
+a target assembler type.  This code is ugly and is just a hack.
+The libraries are x86unix.pl and x86ms.pl.
+des586.pl, des686.pl and des-som[23].pl are the programs to actually
+generate the assembler.
+
+So to generate elf assembler
+perl des-som3.pl elf >dx86-elf.s
+For Windows 95/NT
+perl des-som2.pl win32 >win32.asm
+
+[ update 4 Jan 1996 ]
+I have added another way to do things.
+perl des-som3.pl cpp >dx86-cpp.s
+generates a file that will be included by dx86unix.cpp when it is compiled.
+To build for elf, a.out, solaris, bsdi etc,
+cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o
+cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o
+cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o
+cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o
+This was done to cut down the number of files in the distribution.
+
+Now the ugly part.  I acquired my copy of Intels
+"Optimization's For Intel's 32-Bit Processors" and found a few interesting
+things.  First, the aim of the exersize is to 'extract' one byte at a time
+from a word and do an array lookup.  This involves getting the byte from
+the 4 locations in the word and moving it to a new word and doing the lookup.
+The most obvious way to do this is
+xor	eax,	eax				# clear word
+movb	al,	cl				# get low byte
+xor	edi	DWORD PTR 0x100+des_SP[eax] 	# xor in word
+movb	al,	ch				# get next byte
+xor	edi	DWORD PTR 0x300+des_SP[eax] 	# xor in word
+shr	ecx	16
+which seems ok.  For the pentium, this system appears to be the best.
+One has to do instruction interleaving to keep both functional units
+operating, but it is basically very efficient.
+
+Now the crunch.  When a full register is used after a partial write, eg.
+mov	al,	cl
+xor	edi,	DWORD PTR 0x100+des_SP[eax]
+386	- 1 cycle stall
+486	- 1 cycle stall
+586	- 0 cycle stall
+686	- at least 7 cycle stall (page 22 of the above mentioned document).
+
+So the technique that produces the best results on a pentium, according to
+the documentation, will produce hideous results on a pentium pro.
+
+To get around this, des686.pl will generate code that is not as fast on
+a pentium, should be very good on a pentium pro.
+mov	eax,	ecx				# copy word 
+shr	ecx,	8				# line up next byte
+and	eax,	0fch				# mask byte
+xor	edi	DWORD PTR 0x100+des_SP[eax] 	# xor in array lookup
+mov	eax,	ecx				# get word
+shr	ecx	8				# line up next byte
+and	eax,	0fch				# mask byte
+xor	edi	DWORD PTR 0x300+des_SP[eax] 	# xor in array lookup
+
+Due to the execution units in the pentium, this actually works quite well.
+For a pentium pro it should be very good.  This is the type of output
+Visual C++ generates.
+
+There is a third option.  instead of using
+mov	al,	ch
+which is bad on the pentium pro, one may be able to use
+movzx	eax,	ch
+which may not incur the partial write penalty.  On the pentium,
+this instruction takes 4 cycles so is not worth using but on the
+pentium pro it appears it may be worth while.  I need access to one to
+experiment :-).
+
+eric (20 Oct 1996)
+
+22 Nov 1996 - I have asked people to run the 2 different version on pentium
+pros and it appears that the intel documentation is wrong.  The
+mov al,bh is still faster on a pentium pro, so just use the des586.pl
+install des686.pl
+
+3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these
+functions into des_enc.c because it does make a massive performance
+difference on some boxes to have the functions code located close to
+the des_encrypt2() function.
+
+9 Jan 1997 - des-som2.pl is now the correct perl script to use for
+pentiums.  It contains an inner loop from
+Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> which does raw ecb DES calls at
+273,000 per second.  He had a previous version at 250,000 and the best
+I was able to get was 203,000.  The content has not changed, this is all
+due to instruction sequencing (and actual instructions choice) which is able
+to keep both functional units of the pentium going.
+We may have lost the ugly register usage restrictions when x86 went 32 bit
+but for the pentium it has been replaced by evil instruction ordering tricks.
+
+13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf.
+raw DES at 281,000 per second on a pentium 100.
+
diff --git a/openssl/crypto/des/cbc3_enc.c b/openssl/crypto/des/cbc3_enc.c
new file mode 100644
index 0000000..b5db4e1
--- /dev/null
+++ b/openssl/crypto/des/cbc3_enc.c
@@ -0,0 +1,99 @@
+/* crypto/des/cbc3_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+/* HAS BUGS! DON'T USE - this is only present for use in des.c */
+void DES_3cbc_encrypt(DES_cblock *input, DES_cblock *output, long length,
+	     DES_key_schedule ks1, DES_key_schedule ks2, DES_cblock *iv1,
+	     DES_cblock *iv2, int enc)
+	{
+	int off=((int)length-1)/8;
+	long l8=((length+7)/8)*8;
+	DES_cblock niv1,niv2;
+
+	if (enc == DES_ENCRYPT)
+		{
+		DES_cbc_encrypt((unsigned char*)input,
+				(unsigned char*)output,length,&ks1,iv1,enc);
+		if (length >= sizeof(DES_cblock))
+			memcpy(niv1,output[off],sizeof(DES_cblock));
+		DES_cbc_encrypt((unsigned char*)output,
+				(unsigned char*)output,l8,&ks2,iv1,!enc);
+		DES_cbc_encrypt((unsigned char*)output,
+				(unsigned char*)output,l8,&ks1,iv2,enc);
+		if (length >= sizeof(DES_cblock))
+			memcpy(niv2,output[off],sizeof(DES_cblock));
+		}
+	else
+		{
+		if (length >= sizeof(DES_cblock))
+			memcpy(niv2,input[off],sizeof(DES_cblock));
+		DES_cbc_encrypt((unsigned char*)input,
+				(unsigned char*)output,l8,&ks1,iv2,enc);
+		DES_cbc_encrypt((unsigned char*)output,
+				(unsigned char*)output,l8,&ks2,iv1,!enc);
+		if (length >= sizeof(DES_cblock))
+			memcpy(niv1,output[off],sizeof(DES_cblock));
+		DES_cbc_encrypt((unsigned char*)output,
+				(unsigned char*)output,length,&ks1,iv1,enc);
+		}
+	memcpy(*iv1,niv1,sizeof(DES_cblock));
+	memcpy(*iv2,niv2,sizeof(DES_cblock));
+	}
+
diff --git a/openssl/crypto/des/cbc_cksm.c b/openssl/crypto/des/cbc_cksm.c
new file mode 100644
index 0000000..09a7ba5
--- /dev/null
+++ b/openssl/crypto/des/cbc_cksm.c
@@ -0,0 +1,106 @@
+/* crypto/des/cbc_cksm.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+DES_LONG DES_cbc_cksum(const unsigned char *in, DES_cblock *output,
+		       long length, DES_key_schedule *schedule,
+		       const_DES_cblock *ivec)
+	{
+	register DES_LONG tout0,tout1,tin0,tin1;
+	register long l=length;
+	DES_LONG tin[2];
+	unsigned char *out = &(*output)[0];
+	const unsigned char *iv = &(*ivec)[0];
+
+	c2l(iv,tout0);
+	c2l(iv,tout1);
+	for (; l>0; l-=8)
+		{
+		if (l >= 8)
+			{
+			c2l(in,tin0);
+			c2l(in,tin1);
+			}
+		else
+			c2ln(in,tin0,tin1,l);
+			
+		tin0^=tout0; tin[0]=tin0;
+		tin1^=tout1; tin[1]=tin1;
+		DES_encrypt1((DES_LONG *)tin,schedule,DES_ENCRYPT);
+		/* fix 15/10/91 eay - thanks to keithr@sco.COM */
+		tout0=tin[0];
+		tout1=tin[1];
+		}
+	if (out != NULL)
+		{
+		l2c(tout0,out);
+		l2c(tout1,out);
+		}
+	tout0=tin0=tin1=tin[0]=tin[1]=0;
+	/*
+	  Transform the data in tout1 so that it will
+	  match the return value that the MIT Kerberos
+	  mit_des_cbc_cksum API returns.
+	*/
+	tout1 = ((tout1 >> 24L) & 0x000000FF)
+	      | ((tout1 >> 8L)  & 0x0000FF00)
+	      | ((tout1 << 8L)  & 0x00FF0000)
+	      | ((tout1 << 24L) & 0xFF000000);
+	return(tout1);
+	}
diff --git a/openssl/crypto/des/cbc_enc.c b/openssl/crypto/des/cbc_enc.c
new file mode 100644
index 0000000..677903a
--- /dev/null
+++ b/openssl/crypto/des/cbc_enc.c
@@ -0,0 +1,61 @@
+/* crypto/des/cbc_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#define CBC_ENC_C__DONT_UPDATE_IV
+
+#include "ncbc_enc.c" /* des_cbc_encrypt */
diff --git a/openssl/crypto/des/cfb64ede.c b/openssl/crypto/des/cfb64ede.c
new file mode 100644
index 0000000..de34ecc
--- /dev/null
+++ b/openssl/crypto/des/cfb64ede.c
@@ -0,0 +1,254 @@
+/* crypto/des/cfb64ede.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+#include "e_os.h"
+
+/* The input and output encrypted as though 64bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+
+void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+			    long length, DES_key_schedule *ks1,
+			    DES_key_schedule *ks2, DES_key_schedule *ks3,
+			    DES_cblock *ivec, int *num, int enc)
+	{
+	register DES_LONG v0,v1;
+	register long l=length;
+	register int n= *num;
+	DES_LONG ti[2];
+	unsigned char *iv,c,cc;
+
+	iv=&(*ivec)[0];
+	if (enc)
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				c2l(iv,v0);
+				c2l(iv,v1);
+
+				ti[0]=v0;
+				ti[1]=v1;
+				DES_encrypt3(ti,ks1,ks2,ks3);
+				v0=ti[0];
+				v1=ti[1];
+
+				iv = &(*ivec)[0];
+				l2c(v0,iv);
+				l2c(v1,iv);
+				iv = &(*ivec)[0];
+				}
+			c= *(in++)^iv[n];
+			*(out++)=c;
+			iv[n]=c;
+			n=(n+1)&0x07;
+			}
+		}
+	else
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				c2l(iv,v0);
+				c2l(iv,v1);
+
+				ti[0]=v0;
+				ti[1]=v1;
+				DES_encrypt3(ti,ks1,ks2,ks3);
+				v0=ti[0];
+				v1=ti[1];
+
+				iv = &(*ivec)[0];
+				l2c(v0,iv);
+				l2c(v1,iv);
+				iv = &(*ivec)[0];
+				}
+			cc= *(in++);
+			c=iv[n];
+			iv[n]=cc;
+			*(out++)=c^cc;
+			n=(n+1)&0x07;
+			}
+		}
+	v0=v1=ti[0]=ti[1]=c=cc=0;
+	*num=n;
+	}
+
+#ifdef undef /* MACRO */
+void DES_ede2_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
+	     DES_key_schedule ks1, DES_key_schedule ks2, DES_cblock (*ivec),
+	     int *num, int enc)
+	{
+	DES_ede3_cfb64_encrypt(in,out,length,ks1,ks2,ks1,ivec,num,enc);
+	}
+#endif
+
+/* This is compatible with the single key CFB-r for DES, even thought that's
+ * not what EVP needs.
+ */
+
+void DES_ede3_cfb_encrypt(const unsigned char *in,unsigned char *out,
+			  int numbits,long length,DES_key_schedule *ks1,
+			  DES_key_schedule *ks2,DES_key_schedule *ks3,
+			  DES_cblock *ivec,int enc)
+	{
+	register DES_LONG d0,d1,v0,v1;
+	register unsigned long l=length,n=((unsigned int)numbits+7)/8;
+	register int num=numbits,i;
+	DES_LONG ti[2];
+	unsigned char *iv;
+	unsigned char ovec[16];
+
+	if (num > 64) return;
+	iv = &(*ivec)[0];
+	c2l(iv,v0);
+	c2l(iv,v1);
+	if (enc)
+		{
+		while (l >= n)
+			{
+			l-=n;
+			ti[0]=v0;
+			ti[1]=v1;
+			DES_encrypt3(ti,ks1,ks2,ks3);
+			c2ln(in,d0,d1,n);
+			in+=n;
+			d0^=ti[0];
+			d1^=ti[1];
+			l2cn(d0,d1,out,n);
+			out+=n;
+			/* 30-08-94 - eay - changed because l>>32 and
+			 * l<<32 are bad under gcc :-( */
+			if (num == 32)
+				{ v0=v1; v1=d0; }
+			else if (num == 64)
+				{ v0=d0; v1=d1; }
+			else
+				{
+				iv=&ovec[0];
+				l2c(v0,iv);
+				l2c(v1,iv);
+				l2c(d0,iv);
+				l2c(d1,iv);
+				/* shift ovec left most of the bits... */
+				memmove(ovec,ovec+num/8,8+(num%8 ? 1 : 0));
+				/* now the remaining bits */
+				if(num%8 != 0)
+					for(i=0 ; i < 8 ; ++i)
+						{
+						ovec[i]<<=num%8;
+						ovec[i]|=ovec[i+1]>>(8-num%8);
+						}
+				iv=&ovec[0];
+				c2l(iv,v0);
+				c2l(iv,v1);
+				}
+			}
+		}
+	else
+		{
+		while (l >= n)
+			{
+			l-=n;
+			ti[0]=v0;
+			ti[1]=v1;
+			DES_encrypt3(ti,ks1,ks2,ks3);
+			c2ln(in,d0,d1,n);
+			in+=n;
+			/* 30-08-94 - eay - changed because l>>32 and
+			 * l<<32 are bad under gcc :-( */
+			if (num == 32)
+				{ v0=v1; v1=d0; }
+			else if (num == 64)
+				{ v0=d0; v1=d1; }
+			else
+				{
+				iv=&ovec[0];
+				l2c(v0,iv);
+				l2c(v1,iv);
+				l2c(d0,iv);
+				l2c(d1,iv);
+				/* shift ovec left most of the bits... */
+				memmove(ovec,ovec+num/8,8+(num%8 ? 1 : 0));
+				/* now the remaining bits */
+				if(num%8 != 0)
+					for(i=0 ; i < 8 ; ++i)
+						{
+						ovec[i]<<=num%8;
+						ovec[i]|=ovec[i+1]>>(8-num%8);
+						}
+				iv=&ovec[0];
+				c2l(iv,v0);
+				c2l(iv,v1);
+				}
+			d0^=ti[0];
+			d1^=ti[1];
+			l2cn(d0,d1,out,n);
+			out+=n;
+			}
+		}
+	iv = &(*ivec)[0];
+	l2c(v0,iv);
+	l2c(v1,iv);
+	v0=v1=d0=d1=ti[0]=ti[1]=0;
+	}
+
diff --git a/openssl/crypto/des/cfb64enc.c b/openssl/crypto/des/cfb64enc.c
new file mode 100644
index 0000000..5ec8683
--- /dev/null
+++ b/openssl/crypto/des/cfb64enc.c
@@ -0,0 +1,121 @@
+/* crypto/des/cfb64enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+/* The input and output encrypted as though 64bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+
+void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+		       long length, DES_key_schedule *schedule,
+		       DES_cblock *ivec, int *num, int enc)
+	{
+	register DES_LONG v0,v1;
+	register long l=length;
+	register int n= *num;
+	DES_LONG ti[2];
+	unsigned char *iv,c,cc;
+
+	iv = &(*ivec)[0];
+	if (enc)
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				c2l(iv,v0); ti[0]=v0;
+				c2l(iv,v1); ti[1]=v1;
+				DES_encrypt1(ti,schedule,DES_ENCRYPT);
+				iv = &(*ivec)[0];
+				v0=ti[0]; l2c(v0,iv);
+				v0=ti[1]; l2c(v0,iv);
+				iv = &(*ivec)[0];
+				}
+			c= *(in++)^iv[n];
+			*(out++)=c;
+			iv[n]=c;
+			n=(n+1)&0x07;
+			}
+		}
+	else
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				c2l(iv,v0); ti[0]=v0;
+				c2l(iv,v1); ti[1]=v1;
+				DES_encrypt1(ti,schedule,DES_ENCRYPT);
+				iv = &(*ivec)[0];
+				v0=ti[0]; l2c(v0,iv);
+				v0=ti[1]; l2c(v0,iv);
+				iv = &(*ivec)[0];
+				}
+			cc= *(in++);
+			c=iv[n];
+			iv[n]=cc;
+			*(out++)=c^cc;
+			n=(n+1)&0x07;
+			}
+		}
+	v0=v1=ti[0]=ti[1]=c=cc=0;
+	*num=n;
+	}
+
diff --git a/openssl/crypto/des/cfb_enc.c b/openssl/crypto/des/cfb_enc.c
new file mode 100644
index 0000000..720f29a
--- /dev/null
+++ b/openssl/crypto/des/cfb_enc.c
@@ -0,0 +1,195 @@
+/* crypto/des/cfb_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "e_os.h"
+#include "des_locl.h"
+#include <assert.h>
+
+/* The input and output are loaded in multiples of 8 bits.
+ * What this means is that if you hame numbits=12 and length=2
+ * the first 12 bits will be retrieved from the first byte and half
+ * the second.  The second 12 bits will come from the 3rd and half the 4th
+ * byte.
+ */
+/* Until Aug 1 2003 this function did not correctly implement CFB-r, so it
+ * will not be compatible with any encryption prior to that date. Ben. */
+void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
+		     long length, DES_key_schedule *schedule, DES_cblock *ivec,
+		     int enc)
+	{
+	register DES_LONG d0,d1,v0,v1;
+	register unsigned long l=length;
+	register int num=numbits/8,n=(numbits+7)/8,i,rem=numbits%8;
+	DES_LONG ti[2];
+	unsigned char *iv;
+#ifndef L_ENDIAN
+	unsigned char ovec[16];
+#else
+	unsigned int  sh[4];
+	unsigned char *ovec=(unsigned char *)sh;
+
+	/* I kind of count that compiler optimizes away this assertioni,*/
+	assert (sizeof(sh[0])==4);	/* as this holds true for all,	*/
+					/* but 16-bit platforms...	*/
+					
+#endif
+
+	if (numbits<=0 || numbits > 64) return;
+	iv = &(*ivec)[0];
+	c2l(iv,v0);
+	c2l(iv,v1);
+	if (enc)
+		{
+		while (l >= (unsigned long)n)
+			{
+			l-=n;
+			ti[0]=v0;
+			ti[1]=v1;
+			DES_encrypt1((DES_LONG *)ti,schedule,DES_ENCRYPT);
+			c2ln(in,d0,d1,n);
+			in+=n;
+			d0^=ti[0];
+			d1^=ti[1];
+			l2cn(d0,d1,out,n);
+			out+=n;
+			/* 30-08-94 - eay - changed because l>>32 and
+			 * l<<32 are bad under gcc :-( */
+			if (numbits == 32)
+				{ v0=v1; v1=d0; }
+			else if (numbits == 64)
+				{ v0=d0; v1=d1; }
+			else
+				{
+#ifndef L_ENDIAN
+				iv=&ovec[0];
+				l2c(v0,iv);
+				l2c(v1,iv);
+				l2c(d0,iv);
+				l2c(d1,iv);
+#else
+				sh[0]=v0, sh[1]=v1, sh[2]=d0, sh[3]=d1;
+#endif
+				if (rem==0)
+					memmove(ovec,ovec+num,8);
+				else
+					for(i=0 ; i < 8 ; ++i)
+						ovec[i]=ovec[i+num]<<rem |
+							ovec[i+num+1]>>(8-rem);
+#ifdef L_ENDIAN
+				v0=sh[0], v1=sh[1];
+#else
+				iv=&ovec[0];
+				c2l(iv,v0);
+				c2l(iv,v1);
+#endif
+				}
+			}
+		}
+	else
+		{
+		while (l >= (unsigned long)n)
+			{
+			l-=n;
+			ti[0]=v0;
+			ti[1]=v1;
+			DES_encrypt1((DES_LONG *)ti,schedule,DES_ENCRYPT);
+			c2ln(in,d0,d1,n);
+			in+=n;
+			/* 30-08-94 - eay - changed because l>>32 and
+			 * l<<32 are bad under gcc :-( */
+			if (numbits == 32)
+				{ v0=v1; v1=d0; }
+			else if (numbits == 64)
+				{ v0=d0; v1=d1; }
+			else
+				{
+#ifndef L_ENDIAN
+				iv=&ovec[0];
+				l2c(v0,iv);
+				l2c(v1,iv);
+				l2c(d0,iv);
+				l2c(d1,iv);
+#else
+				sh[0]=v0, sh[1]=v1, sh[2]=d0, sh[3]=d1;
+#endif
+				if (rem==0)
+					memmove(ovec,ovec+num,8);
+				else
+					for(i=0 ; i < 8 ; ++i)
+						ovec[i]=ovec[i+num]<<rem |
+							ovec[i+num+1]>>(8-rem);
+#ifdef L_ENDIAN
+				v0=sh[0], v1=sh[1];
+#else
+				iv=&ovec[0];
+				c2l(iv,v0);
+				c2l(iv,v1);
+#endif
+				}
+			d0^=ti[0];
+			d1^=ti[1];
+			l2cn(d0,d1,out,n);
+			out+=n;
+			}
+		}
+	iv = &(*ivec)[0];
+	l2c(v0,iv);
+	l2c(v1,iv);
+	v0=v1=d0=d1=ti[0]=ti[1]=0;
+	}
+
diff --git a/openssl/crypto/des/des-lib.com b/openssl/crypto/des/des-lib.com
new file mode 100644
index 0000000..348f1c0
--- /dev/null
+++ b/openssl/crypto/des/des-lib.com
@@ -0,0 +1,1005 @@
+$!
+$!  DES-LIB.COM
+$!  Written By:  Robert Byer
+$!               Vice-President
+$!               A-Com Computing, Inc.
+$!               byer@mail.all-net.net
+$!
+$!  Changes by Richard Levitte <richard@levitte.org>
+$!
+$!  This command files compiles and creates the 
+$!  "[.xxx.EXE.CRYPTO.DES]LIBDES.OLB" library.  The "xxx" denotes the machine 
+$!  architecture of ALPHA, IA64 or VAX.
+$!
+$!  It was re-written to try to determine which "C" compiler to try to use
+$!  or the user can specify a compiler in P3.
+$!
+$!  Specify one of the following to build just that part, specify "ALL" to
+$!  just build everything.
+$!
+$!         ALL       To Just Build "Everything".
+$!         LIBRARY   To Just Build The [.xxx.EXE.CRYPTO.DES]LIBDES.OLB Library.
+$!         DESTEST   To Just Build The [.xxx.EXE.CRYPTO.DES]DESTEST.EXE Program.
+$!         SPEED     To Just Build The [.xxx.EXE.CRYPTO.DES]SPEED.EXE Program.
+$!         RPW       To Just Build The [.xxx.EXE.CRYPTO.DES]RPW.EXE Program.
+$!         DES       To Just Build The [.xxx.EXE.CRYPTO.DES]DES.EXE Program.
+$!         DES_OPTS  To Just Build The [.xxx.EXE.CRYPTO.DES]DES_OPTS.EXE Program.
+$!
+$!  Specify either DEBUG or NODEBUG as P2 to compile with or without
+$!  debugging information.
+$!
+$!  Specify which compiler at P3 to try to compile under.
+$!
+$!	   VAXC	 For VAX C.
+$!	   DECC	 For DEC C.
+$!	   GNUC	 For GNU C.
+$!
+$!  If you don't speficy a compiler, it will try to determine which
+$!  "C" compiler to try to use.
+$!
+$!  P4, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
+$!
+$!
+$! Make sure we know what architecture we run on.
+$!
+$!
+$! Check Which Architecture We Are Using.
+$!
+$ IF (F$GETSYI("CPU").LT.128)
+$ THEN
+$!
+$!  The Architecture Is VAX
+$!
+$   ARCH := VAX
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  The Architecture Is Alpha, IA64 or whatever comes in the future.
+$!
+$   ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
+$   IF (ARCH .EQS. "") THEN ARCH = "UNK"
+$!
+$! End The Architecture Check.
+$!
+$ ENDIF
+$!
+$! Define The OBJ Directory Name.
+$!
+$ OBJ_DIR := SYS$DISK:[--.'ARCH'.OBJ.CRYPTO.DES]
+$!
+$! Define The EXE Directory Name.
+$!
+$ EXE_DIR :== SYS$DISK:[--.'ARCH'.EXE.CRYPTO.DES]
+$!
+$! Check To Make Sure We Have Valid Command Line Parameters.
+$!
+$ GOSUB CHECK_OPTIONS
+$!
+$! Tell The User What Kind of Machine We Run On.
+$!
+$ WRITE SYS$OUTPUT "Compiling On A ",ARCH," Machine."
+$!
+$! Check To See If The Architecture Specific OBJ Directory Exists.
+$!
+$ IF (F$PARSE(OBJ_DIR).EQS."")
+$ THEN
+$!
+$!  It Dosen't Exist, So Create It.
+$!
+$   CREATE/DIR 'OBJ_DIR'
+$!
+$! End The Architecture Specific OBJ Directory Check.
+$!
+$ ENDIF
+$!
+$! Check To See If The Architecture Specific Directory Exists.
+$!
+$ IF (F$PARSE(EXE_DIR).EQS."")
+$ THEN
+$!
+$!  It Dosen't Exist, So Create It.
+$!
+$   CREATE/DIR 'EXE_DIR'
+$!
+$! End The Architecture Specific Directory Check.
+$!
+$ ENDIF
+$!
+$! Define The Library Name.
+$!
+$ LIB_NAME := 'EXE_DIR'LIBDES.OLB
+$!
+$! Check To See What We Are To Do.
+$!
+$ IF (BUILDALL.EQS."TRUE")
+$ THEN
+$!
+$!  Since Nothing Special Was Specified, Do Everything.
+$!
+$   GOSUB LIBRARY
+$   GOSUB DESTEST
+$   GOSUB SPEED
+$   GOSUB RPW
+$   GOSUB DES
+$   GOSUB DES_OPTS
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!    Build Just What The User Wants Us To Build.
+$!
+$     GOSUB 'BUILDALL'
+$!
+$! End The BUILDALL Check.
+$!
+$ ENDIF
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$ LIBRARY:
+$!
+$! Tell The User That We Are Compiling.
+$!
+$ WRITE SYS$OUTPUT "Compiling The ",LIB_NAME," Files."
+$!
+$! Check To See If We Already Have A "[.xxx.EXE.CRYPTO.DES]LIBDES.OLB" Library...
+$!
+$ IF (F$SEARCH(LIB_NAME).EQS."")
+$ THEN
+$!
+$! Guess Not, Create The Library.
+$!
+$   LIBRARY/CREATE/OBJECT 'LIB_NAME'
+$!
+$! End The Library Exist Check.
+$!
+$ ENDIF
+$!
+$! Define The DES Library Files.
+$!
+$ LIB_DES = "set_key,ecb_enc,cbc_enc,"+ -
+		"ecb3_enc,cfb64enc,cfb64ede,cfb_enc,ofb64ede,"+ -
+		"enc_read,enc_writ,ofb64enc,"+ -
+		"ofb_enc,str2key,pcbc_enc,qud_cksm,rand_key,"+ -
+		"des_enc,fcrypt_b,read2pwd,"+ -
+		"fcrypt,xcbc_enc,read_pwd,rpc_enc,cbc_cksm,supp"
+$!
+$!  Define A File Counter And Set It To "0".
+$!
+$ FILE_COUNTER = 0
+$!
+$! Top Of The File Loop.
+$!
+$ NEXT_FILE:
+$!
+$! O.K, Extract The File Name From The File List.
+$!
+$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",LIB_DES)
+$!
+$! Check To See If We Are At The End Of The File List.
+$!
+$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
+$!
+$! Increment The Counter.
+$!
+$ FILE_COUNTER = FILE_COUNTER + 1
+$!
+$! Create The Source File Name.
+$!
+$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME + ".C"
+$!
+$!  Tell The User We Are Compiling The Source File.
+$!
+$ WRITE SYS$OUTPUT "	",FILE_NAME,".C"
+$!
+$! Create The Object File Name.
+$!
+$ OBJECT_FILE = OBJ_DIR + FILE_NAME + "." + ARCH + "OBJ"
+$ ON WARNING THEN GOTO NEXT_FILE
+$!
+$! Check To See If The File We Want To Compile Actually Exists.
+$!
+$ IF (F$SEARCH(SOURCE_FILE).EQS."")
+$ THEN
+$!
+$!  Tell The User That The File Dosen't Exist.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Exit The Build.
+$!
+$   EXIT
+$!
+$! End The File Exists Check.
+$!
+$ ENDIF
+$!
+$! Compile The File.
+$!
+$ ON ERROR THEN GOTO NEXT_FILE
+$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$!
+$! Add It To The Library.
+$!
+$ LIBRARY/REPLACE/OBJECT 'LIB_NAME' 'OBJECT_FILE'
+$!
+$! Time To Clean Up The Object File.
+$!
+$ DELETE 'OBJECT_FILE';*
+$!
+$! Go Back And Do It Again.
+$!
+$ GOTO NEXT_FILE
+$!
+$! All Done With This Library Part.
+$!
+$ FILE_DONE:
+$!
+$! Tell The User That We Are All Done.
+$!
+$ WRITE SYS$OUTPUT "Library ",LIB_NAME," Built."
+$!
+$! All Done, Time To Return.
+$!
+$ RETURN
+$!
+$!  Compile The DESTEST Program.
+$!
+$ DESTEST:
+$!
+$! Check To See If We Have The Proper Libraries.
+$!
+$ GOSUB LIB_CHECK
+$!
+$! Check To See If We Have A Linker Option File.
+$!
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Check To See If The File We Want To Compile Actually Exists.
+$!
+$ IF (F$SEARCH("SYS$DISK:[]DESTEST.C").EQS."")
+$ THEN
+$!
+$!  Tell The User That The File Dosen't Exist.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The File DESTEST.C Dosen't Exist."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Exit The Build.
+$!
+$   EXIT
+$!
+$! End The DESTEST.C File Check.
+$!
+$ ENDIF
+$!
+$! Tell The User What We Are Building.
+$!
+$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"DESTEST.EXE"
+$!
+$! Compile The DESTEST Program.
+$!
+$ CC/OBJECT='OBJ_DIR'DESTEST.OBJ SYS$DISK:[]DESTEST.C
+$!
+$! Link The DESTEST Program.
+$!
+$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'DESTEST.EXE -
+      'OBJ_DIR'DESTEST.OBJ,'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION
+$!
+$! All Done, Time To Return.
+$!
+$ RETURN
+$!
+$!  Compile The SPEED Program.
+$!
+$ SPEED:
+$!
+$! Check To See If We Have The Proper Libraries.
+$!
+$ GOSUB LIB_CHECK
+$!
+$! Check To See If We Have A Linker Option File.
+$!
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Check To See If The File We Want To Compile Actually Exists.
+$!
+$ IF (F$SEARCH("SYS$DISK:[]SPEED.C").EQS."")
+$ THEN
+$!
+$!  Tell The User That The File Dosen't Exist.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The File SPEED.C Dosen't Exist."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Exit The Build.
+$!
+$   EXIT
+$!
+$! End The SPEED.C File Check.
+$!
+$ ENDIF
+$!
+$! Tell The User What We Are Building.
+$!
+$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"SPEED.EXE"
+$!
+$! Compile The SPEED Program.
+$!
+$ CC/OBJECT='OBJ_DIR'SPEED.OBJ SYS$DISK:[]SPEED.C
+$!
+$! Link The SPEED Program.
+$!
+$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'SPEED.EXE -
+      'OBJ_DIR'SPEED.OBJ,'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION
+$!
+$! All Done, Time To Return.
+$!
+$ RETURN
+$!
+$!  Compile The RPW Program.
+$!
+$ RPW:
+$!
+$! Check To See If We Have The Proper Libraries.
+$!
+$ GOSUB LIB_CHECK
+$!
+$! Check To See If We Have A Linker Option File.
+$!
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Check To See If The File We Want To Compile Actually Exists.
+$!
+$ IF (F$SEARCH("SYS$DISK:[]RPW.C").EQS."")
+$ THEN
+$!
+$!  Tell The User That The File Dosen't Exist.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The File RPW.C Dosen't Exist."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Exit The Build.
+$!
+$   EXIT
+$!
+$! End The RPW.C File Check.
+$!
+$ ENDIF
+$!
+$! Tell The User What We Are Building.
+$!
+$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"RPW.EXE"
+$!
+$! Compile The RPW Program.
+$!
+$ CC/OBJECT='OBJ_DIR'RPW.OBJ SYS$DISK:[]RPW.C
+$!
+$! Link The RPW Program.
+$!
+$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'RPW.EXE -
+      'OBJ_DIR'RPW.OBJ,'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION
+$!
+$! All Done, Time To Return.
+$!
+$ RETURN
+$!
+$!  Compile The DES Program.
+$!
+$ DES:
+$!
+$! Check To See If We Have The Proper Libraries.
+$!
+$ GOSUB LIB_CHECK
+$!
+$! Check To See If We Have A Linker Option File.
+$!
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Check To See If The File We Want To Compile Actually Exists.
+$!
+$ IF (F$SEARCH("SYS$DISK:[]DES.C").EQS."")
+$ THEN
+$!
+$!  Tell The User That The File Dosen't Exist.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The File DES.C Dosen't Exist."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Exit The Build.
+$!
+$   EXIT
+$!
+$! End The DES.C File Check.
+$!
+$ ENDIF
+$!
+$! Tell The User What We Are Building.
+$!
+$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"DES.EXE"
+$!
+$! Compile The DES Program.
+$!
+$ CC/OBJECT='OBJ_DIR'DES.OBJ SYS$DISK:[]DES.C
+$ CC/OBJECT='OBJ_DIR'DES.OBJ SYS$DISK:[]CBC3_ENC.C
+$!
+$! Link The DES Program.
+$!
+$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'DES.EXE -
+      'OBJ_DIR'DES.OBJ,'OBJ_DIR'CBC3_ENC.OBJ,-
+      'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION
+$!
+$! All Done, Time To Return.
+$!
+$ RETURN
+$!
+$!  Compile The DES_OPTS Program.
+$!
+$ DES_OPTS:
+$!
+$! Check To See If We Have The Proper Libraries.
+$!
+$ GOSUB LIB_CHECK
+$!
+$! Check To See If We Have A Linker Option File.
+$!
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Check To See If The File We Want To Compile Actually Exists.
+$!
+$ IF (F$SEARCH("SYS$DISK:[]DES_OPTS.C").EQS."")
+$ THEN
+$!
+$!  Tell The User That The File Dosen't Exist.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The File DES_OPTS.C Dosen't Exist."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Exit The Build.
+$!
+$   EXIT
+$!
+$! End The DES_OPTS.C File Check.
+$!
+$ ENDIF
+$!
+$! Tell The User What We Are Building.
+$!
+$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"DES_OPTS.EXE"
+$!
+$! Compile The DES_OPTS Program.
+$!
+$ CC/OBJECT='OBJ_DIR'DES_OPTS.OBJ SYS$DISK:[]DES_OPTS.C
+$!
+$! Link The DES_OPTS Program.
+$!
+$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'DES_OPTS.EXE -
+      'OBJ_DIR'DES_OPTS.OBJ,'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION
+$!
+$! All Done, Time To Return.
+$!
+$ RETURN
+$ EXIT
+$!
+$! Check For The Link Option FIle.
+$!
+$ CHECK_OPT_FILE:
+$!
+$! Check To See If We Need To Make A VAX C Option File.
+$!
+$ IF (COMPILER.EQS."VAXC")
+$ THEN
+$!
+$!  Check To See If We Already Have A VAX C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    We Need A VAX C Linker Option File.
+$!
+$     CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst 
+! The Sharable VAX C Runtime Library.
+!
+SYS$SHARE:VAXCRTL.EXE/SHARE
+$EOD
+$!
+$!  End The Option File Check.
+$!
+$   ENDIF
+$!
+$! End The VAXC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A GNU C Option File.
+$!
+$ IF (COMPILER.EQS."GNUC")
+$ THEN
+$!
+$!  Check To See If We Already Have A GNU C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    We Need A GNU C Linker Option File.
+$!
+$     CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst 
+! The Sharable C Runtime Library.
+!
+GNU_CC:[000000]GCCLIB/LIBRARY
+SYS$SHARE:VAXCRTL/SHARE
+$EOD
+$!
+$!  End The Option File Check.
+$!
+$   ENDIF
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A DEC C Option File.
+$!
+$ IF (COMPILER.EQS."DECC")
+$ THEN
+$!
+$!  Check To See If We Already Have A DEC C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    Figure Out If We Need An non-VAX Or A VAX Linker Option File.
+$!
+$     IF (F$GETSYI("CPU").LT.128)
+$     THEN
+$!
+$!      We Need A DEC C Linker Option File For VAX.
+$!
+$       CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst 
+! The Sharable DEC C Runtime Library.
+!
+SYS$SHARE:DECC$SHR.EXE/SHARE
+$EOD
+$!
+$!    Else...
+$!
+$     ELSE
+$!
+$!      Create The non-VAX Linker Option File.
+$!
+$       CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File For non-VAX To Link Agianst 
+! The Sharable C Runtime Library.
+!
+SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
+SYS$SHARE:CMA$OPEN_RTL/SHARE
+$EOD
+$!
+$!    End The DEC C Option File Check.
+$!
+$     ENDIF
+$!
+$!  End The Option File Search.
+$!
+$   ENDIF
+$!
+$! End The DEC C Check.
+$!
+$ ENDIF
+$!
+$!  Tell The User What Linker Option File We Are Using.
+$!
+$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."	
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$!
+$! Library Check.
+$!
+$ LIB_CHECK:
+$!
+$!  Look For The Library LIBDES.OLB.
+$!
+$ IF (F$SEARCH(LIB_NAME).EQS."")
+$ THEN
+$!
+$!    Tell The User We Can't Find The [.xxx.CRYPTO.DES]LIBDES.OLB Library.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "Can't Find The Library ",LIB_NAME,"."
+$   WRITE SYS$OUTPUT "We Can't Link Without It."
+$   WRITE SYS$OUTPUT ""
+$!
+$!    Since We Can't Link Without It, Exit.
+$!
+$   EXIT
+$ ENDIF
+$!
+$! Time To Return.
+$!
+$ RETURN
+$!
+$! Check The User's Options.
+$!
+$ CHECK_OPTIONS:
+$!
+$! Check To See If We Are To "Just Build Everything".
+$!
+$ IF (P1.EQS."ALL")
+$ THEN
+$!
+$!   P1 Is "ALL", So Build Everything.
+$!
+$    BUILDALL = "TRUE"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  Else, Check To See If P1 Has A Valid Argument.
+$!
+$   IF (P1.EQS."LIBRARY").OR.(P1.EQS."DESTEST").OR.(P1.EQS."SPEED") -
+       .OR.(P1.EQS."RPW").OR.(P1.EQS."DES").OR.(P1.EQS."DES_OPTS")
+$   THEN
+$!
+$!    A Valid Argument.
+$!
+$     BUILDALL = P1
+$!
+$!  Else...
+$!
+$   ELSE
+$!
+$!    Tell The User We Don't Know What They Want.
+$!
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ",P1," Is Invalid.  The Valid Options Are:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "    ALL      :  Just Build Everything."
+$     WRITE SYS$OUTPUT "    LIBRARY  :  To Compile Just The [.xxx.EXE.CRYPTO.DES]LIBDES.OLB Library."
+$     WRITE SYS$OUTPUT "    DESTEST  :  To Compile Just The [.xxx.EXE.CRYPTO.DES]DESTEST.EXE Program."
+$     WRITE SYS$OUTPUT "    SPEED    :  To Compile Just The [.xxx.EXE.CRYPTO.DES]SPEED.EXE Program."
+$     WRITE SYS$OUTPUT "    RPW      :  To Compile Just The [.xxx.EXE.CRYPTO.DES]RPW.EXE Program."
+$     WRITE SYS$OUTPUT "    DES      :  To Compile Just The [.xxx.EXE.CRYPTO.DES]DES.EXE Program."
+$     WRITE SYS$OUTPUT "    DES_OPTS :  To Compile Just The [.xxx.EXE.CRYTPO.DES]DES_OPTS.EXE Program."
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT " Where 'xxx' Stands For: "
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "    ALPHA    :  Alpha Architecture."
+$     WRITE SYS$OUTPUT "    IA64     :  IA64 Architecture."
+$     WRITE SYS$OUTPUT "    VAX      :  VAX Architecture."
+$     WRITE SYS$OUTPUT ""
+$!
+$!    Time To EXIT.
+$!
+$     EXIT
+$!
+$!  End The Valid Argument Check.
+$!
+$   ENDIF
+$!
+$! End The P1 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Compile Without Debugger Information.
+$!
+$ IF (P2.EQS."NODEBUG")
+$ THEN
+$!
+$!   P2 Is Blank, So Compile Without Debugger Information.
+$!
+$    DEBUGGER  = "NODEBUG"
+$    TRACEBACK = "NOTRACEBACK" 
+$    GCC_OPTIMIZE = "OPTIMIZE"
+$    CC_OPTIMIZE = "OPTIMIZE"
+$    WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
+$    WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  Check To See If We Are To Compile With Debugger Information.
+$!
+$   IF (P2.EQS."DEBUG")
+$   THEN
+$!
+$!    Compile With Debugger Information.
+$!
+$     DEBUGGER  = "DEBUG"
+$     TRACEBACK = "TRACEBACK"
+$     GCC_OPTIMIZE = "NOOPTIMIZE"
+$     CC_OPTIMIZE = "NOOPTIMIZE"
+$     WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
+$     WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
+$!
+$!  Else...
+$!
+$   ELSE
+$!
+$!    Tell The User Entered An Invalid Option..
+$!
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ",P2," Is Invalid.  The Valid Options Are:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "    DEBUG    :  Compile With The Debugger Information."
+$     WRITE SYS$OUTPUT "    NODEBUG  :  Compile Without The Debugger Information."
+$     WRITE SYS$OUTPUT ""
+$!
+$!    Time To EXIT.
+$!
+$     EXIT
+$!
+$!  End The Valid Argument Check.
+$!
+$   ENDIF
+$!
+$! End The P2 Check.
+$!
+$ ENDIF
+$!
+$! Special Threads For OpenVMS v7.1 Or Later.
+$!
+$! Written By:  Richard Levitte
+$!              richard@levitte.org
+$!
+$!
+$! Check To See If We Have A Option For P4.
+$!
+$ IF (P4.EQS."")
+$ THEN
+$!
+$!  Get The Version Of VMS We Are Using.
+$!
+$   ISSEVEN := ""
+$   TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
+$   TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
+$!
+$!  Check To See If The VMS Version Is v7.1 Or Later.
+$!
+$   IF (TMP.GE.71)
+$   THEN
+$!
+$!    We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
+$!
+$     ISSEVEN := ,PTHREAD_USE_D4
+$!
+$!  End The VMS Version Check.
+$!
+$   ENDIF
+$!
+$! End The P4 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P3 Is Blank.
+$!
+$ IF (P3.EQS."")
+$ THEN
+$!
+$!  O.K., The User Didn't Specify A Compiler, Let's Try To
+$!  Find Out Which One To Use.
+$!
+$!  Check To See If We Have GNU C.
+$!
+$   IF (F$TRNLNM("GNU_CC").NES."")
+$   THEN
+$!
+$!    Looks Like GNUC, Set To Use GNUC.
+$!
+$     P3 = "GNUC"
+$!
+$!  Else...
+$!
+$   ELSE
+$!
+$!    Check To See If We Have VAXC Or DECC.
+$!
+$     IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
+$     THEN 
+$!
+$!      Looks Like DECC, Set To Use DECC.
+$!
+$       P3 = "DECC"
+$!
+$!    Else...
+$!
+$     ELSE
+$!
+$!      Looks Like VAXC, Set To Use VAXC.
+$!
+$       P3 = "VAXC"
+$!
+$!    End The VAXC Compiler Check.
+$!
+$     ENDIF
+$!
+$!  End The DECC & VAXC Compiler Check.
+$!
+$   ENDIF
+$!
+$!  End The Compiler Check.
+$!
+$ ENDIF
+$!
+$! Set Up Initial CC Definitions, Possibly With User Ones
+$!
+$ CCDEFS = ""
+$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = USER_CCDEFS
+$ CCEXTRAFLAGS = ""
+$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
+$ CCDISABLEWARNINGS = ""
+$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
+	CCDISABLEWARNINGS = USER_CCDISABLEWARNINGS
+$!
+$!  Check To See If The User Entered A Valid Paramter.
+$!
+$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC")
+$ THEN
+$!
+$!    Check To See If The User Wanted DECC.
+$!
+$   IF (P3.EQS."DECC")
+$   THEN
+$!
+$!    Looks Like DECC, Set To Use DECC.
+$!
+$     COMPILER = "DECC"
+$!
+$!    Tell The User We Are Using DECC.
+$!
+$     WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$!    Use DECC...
+$!
+$     CC = "CC"
+$     IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
+	 THEN CC = "CC/DECC"
+$     CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/STANDARD=ANSI89" + -
+           "/NOLIST/PREFIX=ALL" + CCEXTRAFLAGS
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "''EXE_DIR'VAX_DECC_OPTIONS.OPT"
+$!
+$!  End DECC Check.
+$!
+$   ENDIF
+$!
+$!  Check To See If We Are To Use VAXC.
+$!
+$   IF (P3.EQS."VAXC")
+$   THEN
+$!
+$!    Looks Like VAXC, Set To Use VAXC.
+$!
+$     COMPILER = "VAXC"
+$!
+$!    Tell The User We Are Using VAX C.
+$!
+$     WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$!    Compile Using VAXC.
+$!
+$     CC = "CC"
+$     IF ARCH.NES."VAX"
+$     THEN
+$	WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
+$	EXIT
+$     ENDIF
+$     IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
+$     CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + CCEXTRAFLAGS
+$     CCDEFS = """VAXC""," + CCDEFS
+$!
+$!    Define <sys> As SYS$COMMON:[SYSLIB]
+$!
+$     DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "''EXE_DIR'VAX_VAXC_OPTIONS.OPT"
+$!
+$!  End VAXC Check
+$!
+$   ENDIF
+$!
+$!  Check To See If We Are To Use GNU C.
+$!
+$   IF (P3.EQS."GNUC")
+$   THEN
+$!
+$!    Looks Like GNUC, Set To Use GNUC.
+$!
+$     COMPILER = "GNUC"
+$!
+$!    Tell The User We Are Using GNUC.
+$!
+$     WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$!    Use GNU C...
+$!
+$     CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + CCEXTRAFLAGS
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "''EXE_DIR'VAX_GNUC_OPTIONS.OPT"
+$!
+$!  End The GNU C Check.
+$!
+$   ENDIF
+$!
+$!  Set up default defines
+$!
+$   CCDEFS = """FLAT_INC=1""," + CCDEFS
+$!
+$!  Finish up the definition of CC.
+$!
+$   IF COMPILER .EQS. "DECC"
+$   THEN
+$     IF CCDISABLEWARNINGS .EQS. ""
+$     THEN
+$       CC4DISABLEWARNINGS = "DOLLARID"
+$     ELSE
+$       CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
+$       CCDISABLEWARNINGS = "/WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
+$     ENDIF
+$     CC4DISABLEWARNINGS = "/WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
+$   ELSE
+$     CCDISABLEWARNINGS = ""
+$     CC4DISABLEWARNINGS = ""
+$   ENDIF
+$   CC = CC + "/DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
+$!
+$!  Show user the result
+$!
+$   WRITE SYS$OUTPUT "Main Compiling Command: ",CC
+$!
+$!  Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$!  Tell The User We Don't Know What They Want.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The Option ",P3," Is Invalid.  The Valid Options Are:"
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "    VAXC  :  To Compile With VAX C."
+$   WRITE SYS$OUTPUT "    DECC  :  To Compile With DEC C."
+$   WRITE SYS$OUTPUT "    GNUC  :  To Compile With GNU C."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Time To EXIT.
+$!
+$   EXIT
+$!
+$! End The P3 Check.
+$!
+$ ENDIF
+$!
+$!  Time To RETURN...
+$!
+$ RETURN
diff --git a/openssl/crypto/des/des.c b/openssl/crypto/des/des.c
new file mode 100644
index 0000000..343135f
--- /dev/null
+++ b/openssl/crypto/des/des.c
@@ -0,0 +1,932 @@
+/* crypto/des/des.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_SYS_MSDOS
+#ifndef OPENSSL_SYS_VMS
+#include OPENSSL_UNISTD
+#else /* OPENSSL_SYS_VMS */
+#ifdef __DECC
+#include <unistd.h>
+#else /* not __DECC */
+#include <math.h>
+#endif /* __DECC */
+#endif /* OPENSSL_SYS_VMS */
+#else /* OPENSSL_SYS_MSDOS */
+#include <io.h>
+#endif
+
+#include <time.h>
+#include "des_ver.h"
+
+#ifdef OPENSSL_SYS_VMS
+#include <types.h>
+#include <stat.h>
+#else
+#ifndef _IRIX
+#include <sys/types.h>
+#endif
+#include <sys/stat.h>
+#endif
+#include <openssl/des.h>
+#include <openssl/rand.h>
+#include <openssl/ui_compat.h>
+
+void usage(void);
+void doencryption(void);
+int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp);
+void uufwriteEnd(FILE *fp);
+int uufread(unsigned char *out,int size,unsigned int num,FILE *fp);
+int uuencode(unsigned char *in,int num,unsigned char *out);
+int uudecode(unsigned char *in,int num,unsigned char *out);
+void DES_3cbc_encrypt(DES_cblock *input,DES_cblock *output,long length,
+	DES_key_schedule sk1,DES_key_schedule sk2,
+	DES_cblock *ivec1,DES_cblock *ivec2,int enc);
+#ifdef OPENSSL_SYS_VMS
+#define EXIT(a) exit(a&0x10000000L)
+#else
+#define EXIT(a) exit(a)
+#endif
+
+#define BUFSIZE (8*1024)
+#define VERIFY  1
+#define KEYSIZ	8
+#define KEYSIZB 1024 /* should hit tty line limit first :-) */
+char key[KEYSIZB+1];
+int do_encrypt,longk=0;
+FILE *DES_IN,*DES_OUT,*CKSUM_OUT;
+char uuname[200];
+unsigned char uubuf[50];
+int uubufnum=0;
+#define INUUBUFN	(45*100)
+#define OUTUUBUF	(65*100)
+unsigned char b[OUTUUBUF];
+unsigned char bb[300];
+DES_cblock cksum={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+char cksumname[200]="";
+
+int vflag,cflag,eflag,dflag,kflag,bflag,fflag,sflag,uflag,flag3,hflag,error;
+
+int main(int argc, char **argv)
+	{
+	int i;
+	struct stat ins,outs;
+	char *p;
+	char *in=NULL,*out=NULL;
+
+	vflag=cflag=eflag=dflag=kflag=hflag=bflag=fflag=sflag=uflag=flag3=0;
+	error=0;
+	memset(key,0,sizeof(key));
+
+	for (i=1; i<argc; i++)
+		{
+		p=argv[i];
+		if ((p[0] == '-') && (p[1] != '\0'))
+			{
+			p++;
+			while (*p)
+				{
+				switch (*(p++))
+					{
+				case '3':
+					flag3=1;
+					longk=1;
+					break;
+				case 'c':
+					cflag=1;
+					strncpy(cksumname,p,200);
+					cksumname[sizeof(cksumname)-1]='\0';
+					p+=strlen(cksumname);
+					break;
+				case 'C':
+					cflag=1;
+					longk=1;
+					strncpy(cksumname,p,200);
+					cksumname[sizeof(cksumname)-1]='\0';
+					p+=strlen(cksumname);
+					break;
+				case 'e':
+					eflag=1;
+					break;
+				case 'v':
+					vflag=1;
+					break;
+				case 'E':
+					eflag=1;
+					longk=1;
+					break;
+				case 'd':
+					dflag=1;
+					break;
+				case 'D':
+					dflag=1;
+					longk=1;
+					break;
+				case 'b':
+					bflag=1;
+					break;
+				case 'f':
+					fflag=1;
+					break;
+				case 's':
+					sflag=1;
+					break;
+				case 'u':
+					uflag=1;
+					strncpy(uuname,p,200);
+					uuname[sizeof(uuname)-1]='\0';
+					p+=strlen(uuname);
+					break;
+				case 'h':
+					hflag=1;
+					break;
+				case 'k':
+					kflag=1;
+					if ((i+1) == argc)
+						{
+						fputs("must have a key with the -k option\n",stderr);
+						error=1;
+						}
+					else
+						{
+						int j;
+
+						i++;
+						strncpy(key,argv[i],KEYSIZB);
+						for (j=strlen(argv[i])-1; j>=0; j--)
+							argv[i][j]='\0';
+						}
+					break;
+				default:
+					fprintf(stderr,"'%c' unknown flag\n",p[-1]);
+					error=1;
+					break;
+					}
+				}
+			}
+		else
+			{
+			if (in == NULL)
+				in=argv[i];
+			else if (out == NULL)
+				out=argv[i];
+			else
+				error=1;
+			}
+		}
+	if (error) usage();
+	/* We either
+	 * do checksum or
+	 * do encrypt or
+	 * do decrypt or
+	 * do decrypt then ckecksum or
+	 * do checksum then encrypt
+	 */
+	if (((eflag+dflag) == 1) || cflag)
+		{
+		if (eflag) do_encrypt=DES_ENCRYPT;
+		if (dflag) do_encrypt=DES_DECRYPT;
+		}
+	else
+		{
+		if (vflag) 
+			{
+#ifndef _Windows			
+			fprintf(stderr,"des(1) built with %s\n",libdes_version);
+#endif			
+			EXIT(1);
+			}
+		else usage();
+		}
+
+#ifndef _Windows			
+	if (vflag) fprintf(stderr,"des(1) built with %s\n",libdes_version);
+#endif			
+	if (	(in != NULL) &&
+		(out != NULL) &&
+#ifndef OPENSSL_SYS_MSDOS
+		(stat(in,&ins) != -1) &&
+		(stat(out,&outs) != -1) &&
+		(ins.st_dev == outs.st_dev) &&
+		(ins.st_ino == outs.st_ino))
+#else /* OPENSSL_SYS_MSDOS */
+		(strcmp(in,out) == 0))
+#endif
+			{
+			fputs("input and output file are the same\n",stderr);
+			EXIT(3);
+			}
+
+	if (!kflag)
+		if (des_read_pw_string(key,KEYSIZB+1,"Enter key:",eflag?VERIFY:0))
+			{
+			fputs("password error\n",stderr);
+			EXIT(2);
+			}
+
+	if (in == NULL)
+		DES_IN=stdin;
+	else if ((DES_IN=fopen(in,"r")) == NULL)
+		{
+		perror("opening input file");
+		EXIT(4);
+		}
+
+	CKSUM_OUT=stdout;
+	if (out == NULL)
+		{
+		DES_OUT=stdout;
+		CKSUM_OUT=stderr;
+		}
+	else if ((DES_OUT=fopen(out,"w")) == NULL)
+		{
+		perror("opening output file");
+		EXIT(5);
+		}
+
+#ifdef OPENSSL_SYS_MSDOS
+	/* This should set the file to binary mode. */
+	{
+#include <fcntl.h>
+	if (!(uflag && dflag))
+		setmode(fileno(DES_IN),O_BINARY);
+	if (!(uflag && eflag))
+		setmode(fileno(DES_OUT),O_BINARY);
+	}
+#endif
+
+	doencryption();
+	fclose(DES_IN);
+	fclose(DES_OUT);
+	EXIT(0);
+	}
+
+void usage(void)
+	{
+	char **u;
+	static const char *Usage[]={
+"des <options> [input-file [output-file]]",
+"options:",
+"-v         : des(1) version number",
+"-e         : encrypt using SunOS compatible user key to DES key conversion.",
+"-E         : encrypt ",
+"-d         : decrypt using SunOS compatible user key to DES key conversion.",
+"-D         : decrypt ",
+"-c[ckname] : generate a cbc_cksum using SunOS compatible user key to",
+"             DES key conversion and output to ckname (stdout default,",
+"             stderr if data being output on stdout).  The checksum is",
+"             generated before encryption and after decryption if used",
+"             in conjunction with -[eEdD].",
+"-C[ckname] : generate a cbc_cksum as for -c but compatible with -[ED].",
+"-k key     : use key 'key'",
+"-h         : the key that is entered will be a hexadecimal number",
+"             that is used directly as the des key",
+"-u[uuname] : input file is uudecoded if -[dD] or output uuencoded data if -[eE]",
+"             (uuname is the filename to put in the uuencode header).",
+"-b         : encrypt using DES in ecb encryption mode, the default is cbc mode.",
+"-3         : encrypt using triple DES encryption.  This uses 2 keys",
+"             generated from the input key.  If the input key is less",
+"             than 8 characters long, this is equivalent to normal",
+"             encryption.  Default is triple cbc, -b makes it triple ecb.",
+NULL
+};
+	for (u=(char **)Usage; *u; u++)
+		{
+		fputs(*u,stderr);
+		fputc('\n',stderr);
+		}
+
+	EXIT(1);
+	}
+
+void doencryption(void)
+	{
+#ifdef _LIBC
+	extern unsigned long time();
+#endif
+
+	register int i;
+	DES_key_schedule ks,ks2;
+	DES_cblock iv,iv2;
+	char *p;
+	int num=0,j,k,l,rem,ll,len,last,ex=0;
+	DES_cblock kk,k2;
+	FILE *O;
+	int Exit=0;
+#ifndef OPENSSL_SYS_MSDOS
+	static unsigned char buf[BUFSIZE+8],obuf[BUFSIZE+8];
+#else
+	static unsigned char *buf=NULL,*obuf=NULL;
+
+	if (buf == NULL)
+		{
+		if (    (( buf=OPENSSL_malloc(BUFSIZE+8)) == NULL) ||
+			((obuf=OPENSSL_malloc(BUFSIZE+8)) == NULL))
+			{
+			fputs("Not enough memory\n",stderr);
+			Exit=10;
+			goto problems;
+			}
+		}
+#endif
+
+	if (hflag)
+		{
+		j=(flag3?16:8);
+		p=key;
+		for (i=0; i<j; i++)
+			{
+			k=0;
+			if ((*p <= '9') && (*p >= '0'))
+				k=(*p-'0')<<4;
+			else if ((*p <= 'f') && (*p >= 'a'))
+				k=(*p-'a'+10)<<4;
+			else if ((*p <= 'F') && (*p >= 'A'))
+				k=(*p-'A'+10)<<4;
+			else
+				{
+				fputs("Bad hex key\n",stderr);
+				Exit=9;
+				goto problems;
+				}
+			p++;
+			if ((*p <= '9') && (*p >= '0'))
+				k|=(*p-'0');
+			else if ((*p <= 'f') && (*p >= 'a'))
+				k|=(*p-'a'+10);
+			else if ((*p <= 'F') && (*p >= 'A'))
+				k|=(*p-'A'+10);
+			else
+				{
+				fputs("Bad hex key\n",stderr);
+				Exit=9;
+				goto problems;
+				}
+			p++;
+			if (i < 8)
+				kk[i]=k;
+			else
+				k2[i-8]=k;
+			}
+		DES_set_key_unchecked(&k2,&ks2);
+		OPENSSL_cleanse(k2,sizeof(k2));
+		}
+	else if (longk || flag3)
+		{
+		if (flag3)
+			{
+			DES_string_to_2keys(key,&kk,&k2);
+			DES_set_key_unchecked(&k2,&ks2);
+			OPENSSL_cleanse(k2,sizeof(k2));
+			}
+		else
+			DES_string_to_key(key,&kk);
+		}
+	else
+		for (i=0; i<KEYSIZ; i++)
+			{
+			l=0;
+			k=key[i];
+			for (j=0; j<8; j++)
+				{
+				if (k&1) l++;
+				k>>=1;
+				}
+			if (l & 1)
+				kk[i]=key[i]&0x7f;
+			else
+				kk[i]=key[i]|0x80;
+			}
+
+	DES_set_key_unchecked(&kk,&ks);
+	OPENSSL_cleanse(key,sizeof(key));
+	OPENSSL_cleanse(kk,sizeof(kk));
+	/* woops - A bug that does not showup under unix :-( */
+	memset(iv,0,sizeof(iv));
+	memset(iv2,0,sizeof(iv2));
+
+	l=1;
+	rem=0;
+	/* first read */
+	if (eflag || (!dflag && cflag))
+		{
+		for (;;)
+			{
+			num=l=fread(&(buf[rem]),1,BUFSIZE,DES_IN);
+			l+=rem;
+			num+=rem;
+			if (l < 0)
+				{
+				perror("read error");
+				Exit=6;
+				goto problems;
+				}
+
+			rem=l%8;
+			len=l-rem;
+			if (feof(DES_IN))
+				{
+				for (i=7-rem; i>0; i--)
+					RAND_pseudo_bytes(buf + l++, 1);
+				buf[l++]=rem;
+				ex=1;
+				len+=rem;
+				}
+			else
+				l-=rem;
+
+			if (cflag)
+				{
+				DES_cbc_cksum(buf,&cksum,
+					(long)len,&ks,&cksum);
+				if (!eflag)
+					{
+					if (feof(DES_IN)) break;
+					else continue;
+					}
+				}
+
+			if (bflag && !flag3)
+				for (i=0; i<l; i+=8)
+					DES_ecb_encrypt(
+						(DES_cblock *)&(buf[i]),
+						(DES_cblock *)&(obuf[i]),
+						&ks,do_encrypt);
+			else if (flag3 && bflag)
+				for (i=0; i<l; i+=8)
+					DES_ecb2_encrypt(
+						(DES_cblock *)&(buf[i]),
+						(DES_cblock *)&(obuf[i]),
+						&ks,&ks2,do_encrypt);
+			else if (flag3 && !bflag)
+				{
+				char tmpbuf[8];
+
+				if (rem) memcpy(tmpbuf,&(buf[l]),
+					(unsigned int)rem);
+				DES_3cbc_encrypt(
+					(DES_cblock *)buf,(DES_cblock *)obuf,
+					(long)l,ks,ks2,&iv,
+					&iv2,do_encrypt);
+				if (rem) memcpy(&(buf[l]),tmpbuf,
+					(unsigned int)rem);
+				}
+			else
+				{
+				DES_cbc_encrypt(
+					buf,obuf,
+					(long)l,&ks,&iv,do_encrypt);
+				if (l >= 8) memcpy(iv,&(obuf[l-8]),8);
+				}
+			if (rem) memcpy(buf,&(buf[l]),(unsigned int)rem);
+
+			i=0;
+			while (i < l)
+				{
+				if (uflag)
+					j=uufwrite(obuf,1,(unsigned int)l-i,
+						DES_OUT);
+				else
+					j=fwrite(obuf,1,(unsigned int)l-i,
+						DES_OUT);
+				if (j == -1)
+					{
+					perror("Write error");
+					Exit=7;
+					goto problems;
+					}
+				i+=j;
+				}
+			if (feof(DES_IN))
+				{
+				if (uflag) uufwriteEnd(DES_OUT);
+				break;
+				}
+			}
+		}
+	else /* decrypt */
+		{
+		ex=1;
+		for (;;)
+			{
+			if (ex) {
+				if (uflag)
+					l=uufread(buf,1,BUFSIZE,DES_IN);
+				else
+					l=fread(buf,1,BUFSIZE,DES_IN);
+				ex=0;
+				rem=l%8;
+				l-=rem;
+				}
+			if (l < 0)
+				{
+				perror("read error");
+				Exit=6;
+				goto problems;
+				}
+
+			if (bflag && !flag3)
+				for (i=0; i<l; i+=8)
+					DES_ecb_encrypt(
+						(DES_cblock *)&(buf[i]),
+						(DES_cblock *)&(obuf[i]),
+						&ks,do_encrypt);
+			else if (flag3 && bflag)
+				for (i=0; i<l; i+=8)
+					DES_ecb2_encrypt(
+						(DES_cblock *)&(buf[i]),
+						(DES_cblock *)&(obuf[i]),
+						&ks,&ks2,do_encrypt);
+			else if (flag3 && !bflag)
+				{
+				DES_3cbc_encrypt(
+					(DES_cblock *)buf,(DES_cblock *)obuf,
+					(long)l,ks,ks2,&iv,
+					&iv2,do_encrypt);
+				}
+			else
+				{
+				DES_cbc_encrypt(
+					buf,obuf,
+				 	(long)l,&ks,&iv,do_encrypt);
+				if (l >= 8) memcpy(iv,&(buf[l-8]),8);
+				}
+
+			if (uflag)
+				ll=uufread(&(buf[rem]),1,BUFSIZE,DES_IN);
+			else
+				ll=fread(&(buf[rem]),1,BUFSIZE,DES_IN);
+			ll+=rem;
+			rem=ll%8;
+			ll-=rem;
+			if (feof(DES_IN) && (ll == 0))
+				{
+				last=obuf[l-1];
+
+				if ((last > 7) || (last < 0))
+					{
+					fputs("The file was not decrypted correctly.\n",
+						stderr);
+					Exit=8;
+					last=0;
+					}
+				l=l-8+last;
+				}
+			i=0;
+			if (cflag) DES_cbc_cksum(obuf,
+				(DES_cblock *)cksum,(long)l/8*8,&ks,
+				(DES_cblock *)cksum);
+			while (i != l)
+				{
+				j=fwrite(obuf,1,(unsigned int)l-i,DES_OUT);
+				if (j == -1)
+					{
+					perror("Write error");
+					Exit=7;
+					goto problems;
+					}
+				i+=j;
+				}
+			l=ll;
+			if ((l == 0) && feof(DES_IN)) break;
+			}
+		}
+	if (cflag)
+		{
+		l=0;
+		if (cksumname[0] != '\0')
+			{
+			if ((O=fopen(cksumname,"w")) != NULL)
+				{
+				CKSUM_OUT=O;
+				l=1;
+				}
+			}
+		for (i=0; i<8; i++)
+			fprintf(CKSUM_OUT,"%02X",cksum[i]);
+		fprintf(CKSUM_OUT,"\n");
+		if (l) fclose(CKSUM_OUT);
+		}
+problems:
+	OPENSSL_cleanse(buf,sizeof(buf));
+	OPENSSL_cleanse(obuf,sizeof(obuf));
+	OPENSSL_cleanse(&ks,sizeof(ks));
+	OPENSSL_cleanse(&ks2,sizeof(ks2));
+	OPENSSL_cleanse(iv,sizeof(iv));
+	OPENSSL_cleanse(iv2,sizeof(iv2));
+	OPENSSL_cleanse(kk,sizeof(kk));
+	OPENSSL_cleanse(k2,sizeof(k2));
+	OPENSSL_cleanse(uubuf,sizeof(uubuf));
+	OPENSSL_cleanse(b,sizeof(b));
+	OPENSSL_cleanse(bb,sizeof(bb));
+	OPENSSL_cleanse(cksum,sizeof(cksum));
+	if (Exit) EXIT(Exit);
+	}
+
+/*    We ignore this parameter but it should be > ~50 I believe    */
+int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp)
+	{
+	int i,j,left,rem,ret=num;
+	static int start=1;
+
+	if (start)
+		{
+		fprintf(fp,"begin 600 %s\n",
+			(uuname[0] == '\0')?"text.d":uuname);
+		start=0;
+		}
+
+	if (uubufnum)
+		{
+		if (uubufnum+num < 45)
+			{
+			memcpy(&(uubuf[uubufnum]),data,(unsigned int)num);
+			uubufnum+=num;
+			return(num);
+			}
+		else
+			{
+			i=45-uubufnum;
+			memcpy(&(uubuf[uubufnum]),data,(unsigned int)i);
+			j=uuencode((unsigned char *)uubuf,45,b);
+			fwrite(b,1,(unsigned int)j,fp);
+			uubufnum=0;
+			data+=i;
+			num-=i;
+			}
+		}
+
+	for (i=0; i<(((int)num)-INUUBUFN); i+=INUUBUFN)
+		{
+		j=uuencode(&(data[i]),INUUBUFN,b);
+		fwrite(b,1,(unsigned int)j,fp);
+		}
+	rem=(num-i)%45;
+	left=(num-i-rem);
+	if (left)
+		{
+		j=uuencode(&(data[i]),left,b);
+		fwrite(b,1,(unsigned int)j,fp);
+		i+=left;
+		}
+	if (i != num)
+		{
+		memcpy(uubuf,&(data[i]),(unsigned int)rem);
+		uubufnum=rem;
+		}
+	return(ret);
+	}
+
+void uufwriteEnd(FILE *fp)
+	{
+	int j;
+	static const char *end=" \nend\n";
+
+	if (uubufnum != 0)
+		{
+		uubuf[uubufnum]='\0';
+		uubuf[uubufnum+1]='\0';
+		uubuf[uubufnum+2]='\0';
+		j=uuencode(uubuf,uubufnum,b);
+		fwrite(b,1,(unsigned int)j,fp);
+		}
+	fwrite(end,1,strlen(end),fp);
+	}
+
+/* int size:  should always be > ~ 60; I actually ignore this parameter :-)    */
+int uufread(unsigned char *out, int size, unsigned int num, FILE *fp)
+	{
+	int i,j,tot;
+	static int done=0;
+	static int valid=0;
+	static int start=1;
+
+	if (start)
+		{
+		for (;;)
+			{
+			b[0]='\0';
+			fgets((char *)b,300,fp);
+			if (b[0] == '\0')
+				{
+				fprintf(stderr,"no 'begin' found in uuencoded input\n");
+				return(-1);
+				}
+			if (strncmp((char *)b,"begin ",6) == 0) break;
+			}
+		start=0;
+		}
+	if (done) return(0);
+	tot=0;
+	if (valid)
+		{
+		memcpy(out,bb,(unsigned int)valid);
+		tot=valid;
+		valid=0;
+		}
+	for (;;)
+		{
+		b[0]='\0';
+		fgets((char *)b,300,fp);
+		if (b[0] == '\0') break;
+		i=strlen((char *)b);
+		if ((b[0] == 'e') && (b[1] == 'n') && (b[2] == 'd'))
+			{
+			done=1;
+			while (!feof(fp))
+				{
+				fgets((char *)b,300,fp);
+				}
+			break;
+			}
+		i=uudecode(b,i,bb);
+		if (i < 0) break;
+		if ((i+tot+8) > num)
+			{
+			/* num to copy to make it a multiple of 8 */
+			j=(num/8*8)-tot-8;
+			memcpy(&(out[tot]),bb,(unsigned int)j);
+			tot+=j;
+			memcpy(bb,&(bb[j]),(unsigned int)i-j);
+			valid=i-j;
+			break;
+			}
+		memcpy(&(out[tot]),bb,(unsigned int)i);
+		tot+=i;
+		}
+	return(tot);
+	}
+
+#define ccc2l(c,l)      (l =((DES_LONG)(*((c)++)))<<16, \
+			 l|=((DES_LONG)(*((c)++)))<< 8, \
+		 	 l|=((DES_LONG)(*((c)++))))
+
+#define l2ccc(l,c)      (*((c)++)=(unsigned char)(((l)>>16)&0xff), \
+                    *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+                    *((c)++)=(unsigned char)(((l)    )&0xff))
+
+
+int uuencode(unsigned char *in, int num, unsigned char *out)
+	{
+	int j,i,n,tot=0;
+	DES_LONG l;
+	register unsigned char *p;
+	p=out;
+
+	for (j=0; j<num; j+=45)
+		{
+		if (j+45 > num)
+			i=(num-j);
+		else	i=45;
+		*(p++)=i+' ';
+		for (n=0; n<i; n+=3)
+			{
+			ccc2l(in,l);
+			*(p++)=((l>>18)&0x3f)+' ';
+			*(p++)=((l>>12)&0x3f)+' ';
+			*(p++)=((l>> 6)&0x3f)+' ';
+			*(p++)=((l    )&0x3f)+' ';
+			tot+=4;
+			}
+		*(p++)='\n';
+		tot+=2;
+		}
+	*p='\0';
+	l=0;
+	return(tot);
+	}
+
+int uudecode(unsigned char *in, int num, unsigned char *out)
+	{
+	int j,i,k;
+	unsigned int n=0,space=0;
+	DES_LONG l;
+	DES_LONG w,x,y,z;
+	unsigned int blank=(unsigned int)'\n'-' ';
+
+	for (j=0; j<num; )
+		{
+		n= *(in++)-' ';
+		if (n == blank)
+			{
+			n=0;
+			in--;
+			}
+		if (n > 60)
+			{
+			fprintf(stderr,"uuencoded line length too long\n");
+			return(-1);
+			}
+		j++;
+
+		for (i=0; i<n; j+=4,i+=3)
+			{
+			/* the following is for cases where spaces are
+			 * removed from lines.
+			 */
+			if (space)
+				{
+				w=x=y=z=0;
+				}
+			else
+				{
+				w= *(in++)-' ';
+				x= *(in++)-' ';
+				y= *(in++)-' ';
+				z= *(in++)-' ';
+				}
+			if ((w > 63) || (x > 63) || (y > 63) || (z > 63))
+				{
+				k=0;
+				if (w == blank) k=1;
+				if (x == blank) k=2;
+				if (y == blank) k=3;
+				if (z == blank) k=4;
+				space=1;
+				switch (k) {
+				case 1:	w=0; in--;
+				case 2: x=0; in--;
+				case 3: y=0; in--;
+				case 4: z=0; in--;
+					break;
+				case 0:
+					space=0;
+					fprintf(stderr,"bad uuencoded data values\n");
+					w=x=y=z=0;
+					return(-1);
+					break;
+					}
+				}
+			l=(w<<18)|(x<<12)|(y<< 6)|(z    );
+			l2ccc(l,out);
+			}
+		if (*(in++) != '\n')
+			{
+			fprintf(stderr,"missing nl in uuencoded line\n");
+			w=x=y=z=0;
+			return(-1);
+			}
+		j++;
+		}
+	*out='\0';
+	w=x=y=z=0;
+	return(n);
+	}
diff --git a/openssl/crypto/des/des.h b/openssl/crypto/des/des.h
new file mode 100644
index 0000000..92b6663
--- /dev/null
+++ b/openssl/crypto/des/des.h
@@ -0,0 +1,245 @@
+/* crypto/des/des.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_NEW_DES_H
+#define HEADER_NEW_DES_H
+
+#include <openssl/e_os2.h>	/* OPENSSL_EXTERN, OPENSSL_NO_DES,
+				   DES_LONG (via openssl/opensslconf.h */
+
+#ifdef OPENSSL_NO_DES
+#error DES is disabled.
+#endif
+
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned char DES_cblock[8];
+typedef /* const */ unsigned char const_DES_cblock[8];
+/* With "const", gcc 2.8.1 on Solaris thinks that DES_cblock *
+ * and const_DES_cblock * are incompatible pointer types. */
+
+typedef struct DES_ks
+    {
+    union
+	{
+	DES_cblock cblock;
+	/* make sure things are correct size on machines with
+	 * 8 byte longs */
+	DES_LONG deslong[2];
+	} ks[16];
+    } DES_key_schedule;
+
+#ifndef OPENSSL_DISABLE_OLD_DES_SUPPORT
+# ifndef OPENSSL_ENABLE_OLD_DES_SUPPORT
+#  define OPENSSL_ENABLE_OLD_DES_SUPPORT
+# endif
+#endif
+
+#ifdef OPENSSL_ENABLE_OLD_DES_SUPPORT
+# include <openssl/des_old.h>
+#endif
+
+#define DES_KEY_SZ 	(sizeof(DES_cblock))
+#define DES_SCHEDULE_SZ (sizeof(DES_key_schedule))
+
+#define DES_ENCRYPT	1
+#define DES_DECRYPT	0
+
+#define DES_CBC_MODE	0
+#define DES_PCBC_MODE	1
+
+#define DES_ecb2_encrypt(i,o,k1,k2,e) \
+	DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+#define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+	DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+#define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+	DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+#define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+	DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+OPENSSL_DECLARE_GLOBAL(int,DES_check_key);	/* defaults to false */
+#define DES_check_key OPENSSL_GLOBAL_REF(DES_check_key)
+OPENSSL_DECLARE_GLOBAL(int,DES_rw_mode);	/* defaults to DES_PCBC_MODE */
+#define DES_rw_mode OPENSSL_GLOBAL_REF(DES_rw_mode)
+
+const char *DES_options(void);
+void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
+		      DES_key_schedule *ks1,DES_key_schedule *ks2,
+		      DES_key_schedule *ks3, int enc);
+DES_LONG DES_cbc_cksum(const unsigned char *input,DES_cblock *output,
+		       long length,DES_key_schedule *schedule,
+		       const_DES_cblock *ivec);
+/* DES_cbc_encrypt does not update the IV!  Use DES_ncbc_encrypt instead. */
+void DES_cbc_encrypt(const unsigned char *input,unsigned char *output,
+		     long length,DES_key_schedule *schedule,DES_cblock *ivec,
+		     int enc);
+void DES_ncbc_encrypt(const unsigned char *input,unsigned char *output,
+		      long length,DES_key_schedule *schedule,DES_cblock *ivec,
+		      int enc);
+void DES_xcbc_encrypt(const unsigned char *input,unsigned char *output,
+		      long length,DES_key_schedule *schedule,DES_cblock *ivec,
+		      const_DES_cblock *inw,const_DES_cblock *outw,int enc);
+void DES_cfb_encrypt(const unsigned char *in,unsigned char *out,int numbits,
+		     long length,DES_key_schedule *schedule,DES_cblock *ivec,
+		     int enc);
+void DES_ecb_encrypt(const_DES_cblock *input,DES_cblock *output,
+		     DES_key_schedule *ks,int enc);
+
+/* 	This is the DES encryption function that gets called by just about
+	every other DES routine in the library.  You should not use this
+	function except to implement 'modes' of DES.  I say this because the
+	functions that call this routine do the conversion from 'char *' to
+	long, and this needs to be done to make sure 'non-aligned' memory
+	access do not occur.  The characters are loaded 'little endian'.
+	Data is a pointer to 2 unsigned long's and ks is the
+	DES_key_schedule to use.  enc, is non zero specifies encryption,
+	zero if decryption. */
+void DES_encrypt1(DES_LONG *data,DES_key_schedule *ks, int enc);
+
+/* 	This functions is the same as DES_encrypt1() except that the DES
+	initial permutation (IP) and final permutation (FP) have been left
+	out.  As for DES_encrypt1(), you should not use this function.
+	It is used by the routines in the library that implement triple DES.
+	IP() DES_encrypt2() DES_encrypt2() DES_encrypt2() FP() is the same
+	as DES_encrypt1() DES_encrypt1() DES_encrypt1() except faster :-). */
+void DES_encrypt2(DES_LONG *data,DES_key_schedule *ks, int enc);
+
+void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
+		  DES_key_schedule *ks2, DES_key_schedule *ks3);
+void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
+		  DES_key_schedule *ks2, DES_key_schedule *ks3);
+void DES_ede3_cbc_encrypt(const unsigned char *input,unsigned char *output, 
+			  long length,
+			  DES_key_schedule *ks1,DES_key_schedule *ks2,
+			  DES_key_schedule *ks3,DES_cblock *ivec,int enc);
+void DES_ede3_cbcm_encrypt(const unsigned char *in,unsigned char *out,
+			   long length,
+			   DES_key_schedule *ks1,DES_key_schedule *ks2,
+			   DES_key_schedule *ks3,
+			   DES_cblock *ivec1,DES_cblock *ivec2,
+			   int enc);
+void DES_ede3_cfb64_encrypt(const unsigned char *in,unsigned char *out,
+			    long length,DES_key_schedule *ks1,
+			    DES_key_schedule *ks2,DES_key_schedule *ks3,
+			    DES_cblock *ivec,int *num,int enc);
+void DES_ede3_cfb_encrypt(const unsigned char *in,unsigned char *out,
+			  int numbits,long length,DES_key_schedule *ks1,
+			  DES_key_schedule *ks2,DES_key_schedule *ks3,
+			  DES_cblock *ivec,int enc);
+void DES_ede3_ofb64_encrypt(const unsigned char *in,unsigned char *out,
+			    long length,DES_key_schedule *ks1,
+			    DES_key_schedule *ks2,DES_key_schedule *ks3,
+			    DES_cblock *ivec,int *num);
+#if 0
+void DES_xwhite_in2out(const_DES_cblock *DES_key,const_DES_cblock *in_white,
+		       DES_cblock *out_white);
+#endif
+
+int DES_enc_read(int fd,void *buf,int len,DES_key_schedule *sched,
+		 DES_cblock *iv);
+int DES_enc_write(int fd,const void *buf,int len,DES_key_schedule *sched,
+		  DES_cblock *iv);
+char *DES_fcrypt(const char *buf,const char *salt, char *ret);
+char *DES_crypt(const char *buf,const char *salt);
+void DES_ofb_encrypt(const unsigned char *in,unsigned char *out,int numbits,
+		     long length,DES_key_schedule *schedule,DES_cblock *ivec);
+void DES_pcbc_encrypt(const unsigned char *input,unsigned char *output,
+		      long length,DES_key_schedule *schedule,DES_cblock *ivec,
+		      int enc);
+DES_LONG DES_quad_cksum(const unsigned char *input,DES_cblock output[],
+			long length,int out_count,DES_cblock *seed);
+int DES_random_key(DES_cblock *ret);
+void DES_set_odd_parity(DES_cblock *key);
+int DES_check_key_parity(const_DES_cblock *key);
+int DES_is_weak_key(const_DES_cblock *key);
+/* DES_set_key (= set_key = DES_key_sched = key_sched) calls
+ * DES_set_key_checked if global variable DES_check_key is set,
+ * DES_set_key_unchecked otherwise. */
+int DES_set_key(const_DES_cblock *key,DES_key_schedule *schedule);
+int DES_key_sched(const_DES_cblock *key,DES_key_schedule *schedule);
+int DES_set_key_checked(const_DES_cblock *key,DES_key_schedule *schedule);
+void DES_set_key_unchecked(const_DES_cblock *key,DES_key_schedule *schedule);
+void DES_string_to_key(const char *str,DES_cblock *key);
+void DES_string_to_2keys(const char *str,DES_cblock *key1,DES_cblock *key2);
+void DES_cfb64_encrypt(const unsigned char *in,unsigned char *out,long length,
+		       DES_key_schedule *schedule,DES_cblock *ivec,int *num,
+		       int enc);
+void DES_ofb64_encrypt(const unsigned char *in,unsigned char *out,long length,
+		       DES_key_schedule *schedule,DES_cblock *ivec,int *num);
+
+int DES_read_password(DES_cblock *key, const char *prompt, int verify);
+int DES_read_2passwords(DES_cblock *key1, DES_cblock *key2, const char *prompt,
+	int verify);
+
+#define DES_fixup_key_parity DES_set_odd_parity
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/des/des.pod b/openssl/crypto/des/des.pod
new file mode 100644
index 0000000..bf479e8
--- /dev/null
+++ b/openssl/crypto/des/des.pod
@@ -0,0 +1,217 @@
+=pod
+
+=head1 NAME
+
+des - encrypt or decrypt data using Data Encryption Standard
+
+=head1 SYNOPSIS
+
+B<des>
+(
+B<-e>
+|
+B<-E>
+) | (
+B<-d>
+|
+B<-D>
+) | (
+B<->[B<cC>][B<ckname>]
+) |
+[
+B<-b3hfs>
+] [
+B<-k>
+I<key>
+]
+] [
+B<-u>[I<uuname>]
+[
+I<input-file>
+[
+I<output-file>
+] ]
+
+=head1 NOTE
+
+This page describes the B<des> stand-alone program, not the B<openssl des>
+command.
+
+=head1 DESCRIPTION
+
+B<des>
+encrypts and decrypts data using the
+Data Encryption Standard algorithm.
+One of
+B<-e>, B<-E>
+(for encrypt) or
+B<-d>, B<-D>
+(for decrypt) must be specified.
+It is also possible to use
+B<-c>
+or
+B<-C>
+in conjunction or instead of the a encrypt/decrypt option to generate
+a 16 character hexadecimal checksum, generated via the
+I<des_cbc_cksum>.
+
+Two standard encryption modes are supported by the
+B<des>
+program, Cipher Block Chaining (the default) and Electronic Code Book
+(specified with
+B<-b>).
+
+The key used for the DES
+algorithm is obtained by prompting the user unless the
+B<-k>
+I<key>
+option is given.
+If the key is an argument to the
+B<des>
+command, it is potentially visible to users executing
+ps(1)
+or a derivative.  To minimise this possibility,
+B<des>
+takes care to destroy the key argument immediately upon entry.
+If your shell keeps a history file be careful to make sure it is not
+world readable.
+
+Since this program attempts to maintain compatibility with sunOS's
+des(1) command, there are 2 different methods used to convert the user
+supplied key to a des key.
+Whenever and one or more of
+B<-E>, B<-D>, B<-C>
+or
+B<-3>
+options are used, the key conversion procedure will not be compatible
+with the sunOS des(1) version but will use all the user supplied
+character to generate the des key.
+B<des>
+command reads from standard input unless
+I<input-file>
+is specified and writes to standard output unless
+I<output-file>
+is given.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-b>
+
+Select ECB
+(eight bytes at a time) encryption mode.
+
+=item B<-3>
+
+Encrypt using triple encryption.
+By default triple cbc encryption is used but if the
+B<-b>
+option is used then triple ECB encryption is performed.
+If the key is less than 8 characters long, the flag has no effect.
+
+=item B<-e>
+
+Encrypt data using an 8 byte key in a manner compatible with sunOS
+des(1).
+
+=item B<-E>
+
+Encrypt data using a key of nearly unlimited length (1024 bytes).
+This will product a more secure encryption.
+
+=item B<-d>
+
+Decrypt data that was encrypted with the B<-e> option.
+
+=item B<-D>
+
+Decrypt data that was encrypted with the B<-E> option.
+
+=item B<-c>
+
+Generate a 16 character hexadecimal cbc checksum and output this to
+stderr.
+If a filename was specified after the
+B<-c>
+option, the checksum is output to that file.
+The checksum is generated using a key generated in a sunOS compatible
+manner.
+
+=item B<-C>
+
+A cbc checksum is generated in the same manner as described for the
+B<-c>
+option but the DES key is generated in the same manner as used for the
+B<-E>
+and
+B<-D>
+options
+
+=item B<-f>
+
+Does nothing - allowed for compatibility with sunOS des(1) command.
+
+=item B<-s>
+
+Does nothing - allowed for compatibility with sunOS des(1) command.
+
+=item B<-k> I<key>
+
+Use the encryption 
+I<key>
+specified.
+
+=item B<-h>
+
+The
+I<key>
+is assumed to be a 16 character hexadecimal number.
+If the
+B<-3>
+option is used the key is assumed to be a 32 character hexadecimal
+number.
+
+=item B<-u>
+
+This flag is used to read and write uuencoded files.  If decrypting,
+the input file is assumed to contain uuencoded, DES encrypted data.
+If encrypting, the characters following the B<-u> are used as the name of
+the uuencoded file to embed in the begin line of the uuencoded
+output.  If there is no name specified after the B<-u>, the name text.des
+will be embedded in the header.
+
+=head1 SEE ALSO
+
+ps(1),
+L<des_crypt(3)|des_crypt(3)>
+
+=head1 BUGS
+
+The problem with using the
+B<-e>
+option is the short key length.
+It would be better to use a real 56-bit key rather than an
+ASCII-based 56-bit pattern.  Knowing that the key was derived from ASCII
+radically reduces the time necessary for a brute-force cryptographic attack.
+My attempt to remove this problem is to add an alternative text-key to
+DES-key function.  This alternative function (accessed via
+B<-E>, B<-D>, B<-S>
+and
+B<-3>)
+uses DES to help generate the key.
+
+Be carefully when using the B<-u> option.  Doing B<des -ud> I<filename> will
+not decrypt filename (the B<-u> option will gobble the B<-d> option).
+
+The VMS operating system operates in a world where files are always a
+multiple of 512 bytes.  This causes problems when encrypted data is
+send from Unix to VMS since a 88 byte file will suddenly be padded
+with 424 null bytes.  To get around this problem, use the B<-u> option
+to uuencode the data before it is send to the VMS system.
+
+=head1 AUTHOR
+
+Eric Young (eay@cryptsoft.com)
+
+=cut
diff --git a/openssl/crypto/des/des3s.cpp b/openssl/crypto/des/des3s.cpp
new file mode 100644
index 0000000..02d527c
--- /dev/null
+++ b/openssl/crypto/des/des3s.cpp
@@ -0,0 +1,67 @@
+//
+// gettsc.inl
+//
+// gives access to the Pentium's (secret) cycle counter
+//
+// This software was written by Leonard Janke (janke@unixg.ubc.ca)
+// in 1996-7 and is entered, by him, into the public domain.
+
+#if defined(__WATCOMC__)
+void GetTSC(unsigned long&);
+#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
+#elif defined(__GNUC__)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  asm volatile(".byte 15, 49\n\t"
+	       : "=eax" (tsc)
+	       :
+	       : "%edx", "%eax");
+}
+#elif defined(_MSC_VER)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  unsigned long a;
+  __asm _emit 0fh
+  __asm _emit 31h
+  __asm mov a, eax;
+  tsc=a;
+}
+#endif      
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/des.h>
+
+void main(int argc,char *argv[])
+	{
+	des_key_schedule key1,key2,key3;
+	unsigned long s1,s2,e1,e2;
+	unsigned long data[2];
+	int i,j;
+
+	for (j=0; j<6; j++)
+		{
+		for (i=0; i<1000; i++) /**/
+			{
+			des_encrypt3(&data[0],key1,key2,key3);
+			GetTSC(s1);
+			des_encrypt3(&data[0],key1,key2,key3);
+			des_encrypt3(&data[0],key1,key2,key3);
+			des_encrypt3(&data[0],key1,key2,key3);
+			GetTSC(e1);
+			GetTSC(s2);
+			des_encrypt3(&data[0],key1,key2,key3);
+			des_encrypt3(&data[0],key1,key2,key3);
+			des_encrypt3(&data[0],key1,key2,key3);
+			des_encrypt3(&data[0],key1,key2,key3);
+			GetTSC(e2);
+			des_encrypt3(&data[0],key1,key2,key3);
+			}
+
+		printf("des %d %d (%d)\n",
+			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
+		}
+	}
+
diff --git a/openssl/crypto/des/des_enc.c b/openssl/crypto/des/des_enc.c
new file mode 100644
index 0000000..828feba
--- /dev/null
+++ b/openssl/crypto/des/des_enc.c
@@ -0,0 +1,400 @@
+/* crypto/des/des_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+#include "spr.h"
+
+void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
+	{
+	register DES_LONG l,r,t,u;
+#ifdef DES_PTR
+	register const unsigned char *des_SP=(const unsigned char *)DES_SPtrans;
+#endif
+#ifndef DES_UNROLL
+	register int i;
+#endif
+	register DES_LONG *s;
+
+	r=data[0];
+	l=data[1];
+
+	IP(r,l);
+	/* Things have been modified so that the initial rotate is
+	 * done outside the loop.  This required the
+	 * DES_SPtrans values in sp.h to be rotated 1 bit to the right.
+	 * One perl script later and things have a 5% speed up on a sparc2.
+	 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+	 * for pointing this out. */
+	/* clear the top bits on machines with 8byte longs */
+	/* shift left by 2 */
+	r=ROTATE(r,29)&0xffffffffL;
+	l=ROTATE(l,29)&0xffffffffL;
+
+	s=ks->ks->deslong;
+	/* I don't know if it is worth the effort of loop unrolling the
+	 * inner loop */
+	if (enc)
+		{
+#ifdef DES_UNROLL
+		D_ENCRYPT(l,r, 0); /*  1 */
+		D_ENCRYPT(r,l, 2); /*  2 */
+		D_ENCRYPT(l,r, 4); /*  3 */
+		D_ENCRYPT(r,l, 6); /*  4 */
+		D_ENCRYPT(l,r, 8); /*  5 */
+		D_ENCRYPT(r,l,10); /*  6 */
+		D_ENCRYPT(l,r,12); /*  7 */
+		D_ENCRYPT(r,l,14); /*  8 */
+		D_ENCRYPT(l,r,16); /*  9 */
+		D_ENCRYPT(r,l,18); /*  10 */
+		D_ENCRYPT(l,r,20); /*  11 */
+		D_ENCRYPT(r,l,22); /*  12 */
+		D_ENCRYPT(l,r,24); /*  13 */
+		D_ENCRYPT(r,l,26); /*  14 */
+		D_ENCRYPT(l,r,28); /*  15 */
+		D_ENCRYPT(r,l,30); /*  16 */
+#else
+		for (i=0; i<32; i+=4)
+			{
+			D_ENCRYPT(l,r,i+0); /*  1 */
+			D_ENCRYPT(r,l,i+2); /*  2 */
+			}
+#endif
+		}
+	else
+		{
+#ifdef DES_UNROLL
+		D_ENCRYPT(l,r,30); /* 16 */
+		D_ENCRYPT(r,l,28); /* 15 */
+		D_ENCRYPT(l,r,26); /* 14 */
+		D_ENCRYPT(r,l,24); /* 13 */
+		D_ENCRYPT(l,r,22); /* 12 */
+		D_ENCRYPT(r,l,20); /* 11 */
+		D_ENCRYPT(l,r,18); /* 10 */
+		D_ENCRYPT(r,l,16); /*  9 */
+		D_ENCRYPT(l,r,14); /*  8 */
+		D_ENCRYPT(r,l,12); /*  7 */
+		D_ENCRYPT(l,r,10); /*  6 */
+		D_ENCRYPT(r,l, 8); /*  5 */
+		D_ENCRYPT(l,r, 6); /*  4 */
+		D_ENCRYPT(r,l, 4); /*  3 */
+		D_ENCRYPT(l,r, 2); /*  2 */
+		D_ENCRYPT(r,l, 0); /*  1 */
+#else
+		for (i=30; i>0; i-=4)
+			{
+			D_ENCRYPT(l,r,i-0); /* 16 */
+			D_ENCRYPT(r,l,i-2); /* 15 */
+			}
+#endif
+		}
+
+	/* rotate and clear the top bits on machines with 8byte longs */
+	l=ROTATE(l,3)&0xffffffffL;
+	r=ROTATE(r,3)&0xffffffffL;
+
+	FP(r,l);
+	data[0]=l;
+	data[1]=r;
+	l=r=t=u=0;
+	}
+
+void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc)
+	{
+	register DES_LONG l,r,t,u;
+#ifdef DES_PTR
+	register const unsigned char *des_SP=(const unsigned char *)DES_SPtrans;
+#endif
+#ifndef DES_UNROLL
+	register int i;
+#endif
+	register DES_LONG *s;
+
+	r=data[0];
+	l=data[1];
+
+	/* Things have been modified so that the initial rotate is
+	 * done outside the loop.  This required the
+	 * DES_SPtrans values in sp.h to be rotated 1 bit to the right.
+	 * One perl script later and things have a 5% speed up on a sparc2.
+	 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+	 * for pointing this out. */
+	/* clear the top bits on machines with 8byte longs */
+	r=ROTATE(r,29)&0xffffffffL;
+	l=ROTATE(l,29)&0xffffffffL;
+
+	s=ks->ks->deslong;
+	/* I don't know if it is worth the effort of loop unrolling the
+	 * inner loop */
+	if (enc)
+		{
+#ifdef DES_UNROLL
+		D_ENCRYPT(l,r, 0); /*  1 */
+		D_ENCRYPT(r,l, 2); /*  2 */
+		D_ENCRYPT(l,r, 4); /*  3 */
+		D_ENCRYPT(r,l, 6); /*  4 */
+		D_ENCRYPT(l,r, 8); /*  5 */
+		D_ENCRYPT(r,l,10); /*  6 */
+		D_ENCRYPT(l,r,12); /*  7 */
+		D_ENCRYPT(r,l,14); /*  8 */
+		D_ENCRYPT(l,r,16); /*  9 */
+		D_ENCRYPT(r,l,18); /*  10 */
+		D_ENCRYPT(l,r,20); /*  11 */
+		D_ENCRYPT(r,l,22); /*  12 */
+		D_ENCRYPT(l,r,24); /*  13 */
+		D_ENCRYPT(r,l,26); /*  14 */
+		D_ENCRYPT(l,r,28); /*  15 */
+		D_ENCRYPT(r,l,30); /*  16 */
+#else
+		for (i=0; i<32; i+=4)
+			{
+			D_ENCRYPT(l,r,i+0); /*  1 */
+			D_ENCRYPT(r,l,i+2); /*  2 */
+			}
+#endif
+		}
+	else
+		{
+#ifdef DES_UNROLL
+		D_ENCRYPT(l,r,30); /* 16 */
+		D_ENCRYPT(r,l,28); /* 15 */
+		D_ENCRYPT(l,r,26); /* 14 */
+		D_ENCRYPT(r,l,24); /* 13 */
+		D_ENCRYPT(l,r,22); /* 12 */
+		D_ENCRYPT(r,l,20); /* 11 */
+		D_ENCRYPT(l,r,18); /* 10 */
+		D_ENCRYPT(r,l,16); /*  9 */
+		D_ENCRYPT(l,r,14); /*  8 */
+		D_ENCRYPT(r,l,12); /*  7 */
+		D_ENCRYPT(l,r,10); /*  6 */
+		D_ENCRYPT(r,l, 8); /*  5 */
+		D_ENCRYPT(l,r, 6); /*  4 */
+		D_ENCRYPT(r,l, 4); /*  3 */
+		D_ENCRYPT(l,r, 2); /*  2 */
+		D_ENCRYPT(r,l, 0); /*  1 */
+#else
+		for (i=30; i>0; i-=4)
+			{
+			D_ENCRYPT(l,r,i-0); /* 16 */
+			D_ENCRYPT(r,l,i-2); /* 15 */
+			}
+#endif
+		}
+	/* rotate and clear the top bits on machines with 8byte longs */
+	data[0]=ROTATE(l,3)&0xffffffffL;
+	data[1]=ROTATE(r,3)&0xffffffffL;
+	l=r=t=u=0;
+	}
+
+void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
+		  DES_key_schedule *ks2, DES_key_schedule *ks3)
+	{
+	register DES_LONG l,r;
+
+	l=data[0];
+	r=data[1];
+	IP(l,r);
+	data[0]=l;
+	data[1]=r;
+	DES_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
+	DES_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
+	DES_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
+	l=data[0];
+	r=data[1];
+	FP(r,l);
+	data[0]=l;
+	data[1]=r;
+	}
+
+void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
+		  DES_key_schedule *ks2, DES_key_schedule *ks3)
+	{
+	register DES_LONG l,r;
+
+	l=data[0];
+	r=data[1];
+	IP(l,r);
+	data[0]=l;
+	data[1]=r;
+	DES_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
+	DES_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
+	DES_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
+	l=data[0];
+	r=data[1];
+	FP(r,l);
+	data[0]=l;
+	data[1]=r;
+	}
+
+#ifndef DES_DEFAULT_OPTIONS
+
+#undef CBC_ENC_C__DONT_UPDATE_IV
+#include "ncbc_enc.c" /* DES_ncbc_encrypt */
+
+void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
+			  long length, DES_key_schedule *ks1,
+			  DES_key_schedule *ks2, DES_key_schedule *ks3,
+			  DES_cblock *ivec, int enc)
+	{
+	register DES_LONG tin0,tin1;
+	register DES_LONG tout0,tout1,xor0,xor1;
+	register const unsigned char *in;
+	unsigned char *out;
+	register long l=length;
+	DES_LONG tin[2];
+	unsigned char *iv;
+
+	in=input;
+	out=output;
+	iv = &(*ivec)[0];
+
+	if (enc)
+		{
+		c2l(iv,tout0);
+		c2l(iv,tout1);
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0);
+			c2l(in,tin1);
+			tin0^=tout0;
+			tin1^=tout1;
+
+			tin[0]=tin0;
+			tin[1]=tin1;
+			DES_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+			tout0=tin[0];
+			tout1=tin[1];
+
+			l2c(tout0,out);
+			l2c(tout1,out);
+			}
+		if (l != -8)
+			{
+			c2ln(in,tin0,tin1,l+8);
+			tin0^=tout0;
+			tin1^=tout1;
+
+			tin[0]=tin0;
+			tin[1]=tin1;
+			DES_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+			tout0=tin[0];
+			tout1=tin[1];
+
+			l2c(tout0,out);
+			l2c(tout1,out);
+			}
+		iv = &(*ivec)[0];
+		l2c(tout0,iv);
+		l2c(tout1,iv);
+		}
+	else
+		{
+		register DES_LONG t0,t1;
+
+		c2l(iv,xor0);
+		c2l(iv,xor1);
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0);
+			c2l(in,tin1);
+
+			t0=tin0;
+			t1=tin1;
+
+			tin[0]=tin0;
+			tin[1]=tin1;
+			DES_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+			tout0=tin[0];
+			tout1=tin[1];
+
+			tout0^=xor0;
+			tout1^=xor1;
+			l2c(tout0,out);
+			l2c(tout1,out);
+			xor0=t0;
+			xor1=t1;
+			}
+		if (l != -8)
+			{
+			c2l(in,tin0);
+			c2l(in,tin1);
+			
+			t0=tin0;
+			t1=tin1;
+
+			tin[0]=tin0;
+			tin[1]=tin1;
+			DES_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+			tout0=tin[0];
+			tout1=tin[1];
+		
+			tout0^=xor0;
+			tout1^=xor1;
+			l2cn(tout0,tout1,out,l+8);
+			xor0=t0;
+			xor1=t1;
+			}
+
+		iv = &(*ivec)[0];
+		l2c(xor0,iv);
+		l2c(xor1,iv);
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	tin[0]=tin[1]=0;
+	}
+
+#endif /* DES_DEFAULT_OPTIONS */
diff --git a/openssl/crypto/des/des_locl.h b/openssl/crypto/des/des_locl.h
new file mode 100644
index 0000000..a3b512e
--- /dev/null
+++ b/openssl/crypto/des/des_locl.h
@@ -0,0 +1,432 @@
+/* crypto/des/des_locl.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_DES_LOCL_H
+#define HEADER_DES_LOCL_H
+
+#include <openssl/e_os2.h>
+
+#if defined(OPENSSL_SYS_WIN32)
+#ifndef OPENSSL_SYS_MSDOS
+#define OPENSSL_SYS_MSDOS
+#endif
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef OPENSSL_SYS_MSDOS
+#if !defined(OPENSSL_SYS_VMS) || defined(__DECC)
+#ifdef OPENSSL_UNISTD
+# include OPENSSL_UNISTD
+#else
+# include <unistd.h>
+#endif
+#include <math.h>
+#endif
+#endif
+#include <openssl/des.h>
+
+#ifdef OPENSSL_SYS_MSDOS		/* Visual C++ 2.1 (Windows NT/95) */
+#include <stdlib.h>
+#include <errno.h>
+#include <time.h>
+#include <io.h>
+#endif
+
+#if defined(__STDC__) || defined(OPENSSL_SYS_VMS) || defined(M_XENIX) || defined(OPENSSL_SYS_MSDOS)
+#include <string.h>
+#endif
+
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+#define ITERATIONS 16
+#define HALF_ITERATIONS 8
+
+/* used in des_read and des_write */
+#define MAXWRITE	(1024*16)
+#define BSIZE		(MAXWRITE+4)
+
+#define c2l(c,l)	(l =((DES_LONG)(*((c)++)))    , \
+			 l|=((DES_LONG)(*((c)++)))<< 8L, \
+			 l|=((DES_LONG)(*((c)++)))<<16L, \
+			 l|=((DES_LONG)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#define c2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
+			case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
+			case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
+			case 5: l2|=((DES_LONG)(*(--(c))));     \
+			case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
+			case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
+			case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
+			case 1: l1|=((DES_LONG)(*(--(c))));     \
+				} \
+			}
+
+#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* replacements for htonl and ntohl since I have no idea what to do
+ * when faced with machines with 8 byte longs. */
+#define HDRSIZE 4
+
+#define n2l(c,l)	(l =((DES_LONG)(*((c)++)))<<24L, \
+			 l|=((DES_LONG)(*((c)++)))<<16L, \
+			 l|=((DES_LONG)(*((c)++)))<< 8L, \
+			 l|=((DES_LONG)(*((c)++))))
+
+#define l2n(l,c)	(*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)     )&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#define l2cn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
+				} \
+			}
+
+#if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)) || defined(__ICC)
+#define	ROTATE(a,n)	(_lrotr(a,n))
+#elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
+# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+#  define ROTATE(a,n)	({ register unsigned int ret;	\
+				asm ("rorl %1,%0"	\
+					: "=r"(ret)	\
+					: "I"(n),"0"(a)	\
+					: "cc");	\
+			   ret;				\
+			})
+# endif
+#endif
+#ifndef ROTATE
+#define	ROTATE(a,n)	(((a)>>(n))+((a)<<(32-(n))))
+#endif
+
+/* Don't worry about the LOAD_DATA() stuff, that is used by
+ * fcrypt() to add it's little bit to the front */
+
+#ifdef DES_FCRYPT
+
+#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
+	{ DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
+
+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
+	t=R^(R>>16L); \
+	u=t&E0; t&=E1; \
+	tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \
+	tmp=(t<<16); t^=R^s[S+1]; t^=tmp
+#else
+#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
+	u=R^s[S  ]; \
+	t=R^s[S+1]
+#endif
+
+/* The changes to this macro may help or hinder, depending on the
+ * compiler and the architecture.  gcc2 always seems to do well :-).
+ * Inspired by Dana How <how@isl.stanford.edu>
+ * DO NOT use the alternative version on machines with 8 byte longs.
+ * It does not seem to work on the Alpha, even when DES_LONG is 4
+ * bytes, probably an issue of accessing non-word aligned objects :-( */
+#ifdef DES_PTR
+
+/* It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there
+ * is no reason to not xor all the sub items together.  This potentially
+ * saves a register since things can be xored directly into L */
+
+#if defined(DES_RISC1) || defined(DES_RISC2)
+#ifdef DES_RISC1
+#define D_ENCRYPT(LL,R,S) { \
+	unsigned int u1,u2,u3; \
+	LOAD_DATA(R,S,u,t,E0,E1,u1); \
+	u2=(int)u>>8L; \
+	u1=(int)u&0xfc; \
+	u2&=0xfc; \
+	t=ROTATE(t,4); \
+	u>>=16L; \
+	LL^= *(const DES_LONG *)(des_SP      +u1); \
+	LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
+	u3=(int)(u>>8L); \
+	u1=(int)u&0xfc; \
+	u3&=0xfc; \
+	LL^= *(const DES_LONG *)(des_SP+0x400+u1); \
+	LL^= *(const DES_LONG *)(des_SP+0x600+u3); \
+	u2=(int)t>>8L; \
+	u1=(int)t&0xfc; \
+	u2&=0xfc; \
+	t>>=16L; \
+	LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
+	LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
+	u3=(int)t>>8L; \
+	u1=(int)t&0xfc; \
+	u3&=0xfc; \
+	LL^= *(const DES_LONG *)(des_SP+0x500+u1); \
+	LL^= *(const DES_LONG *)(des_SP+0x700+u3); }
+#endif
+#ifdef DES_RISC2
+#define D_ENCRYPT(LL,R,S) { \
+	unsigned int u1,u2,s1,s2; \
+	LOAD_DATA(R,S,u,t,E0,E1,u1); \
+	u2=(int)u>>8L; \
+	u1=(int)u&0xfc; \
+	u2&=0xfc; \
+	t=ROTATE(t,4); \
+	LL^= *(const DES_LONG *)(des_SP      +u1); \
+	LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
+	s1=(int)(u>>16L); \
+	s2=(int)(u>>24L); \
+	s1&=0xfc; \
+	s2&=0xfc; \
+	LL^= *(const DES_LONG *)(des_SP+0x400+s1); \
+	LL^= *(const DES_LONG *)(des_SP+0x600+s2); \
+	u2=(int)t>>8L; \
+	u1=(int)t&0xfc; \
+	u2&=0xfc; \
+	LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
+	LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
+	s1=(int)(t>>16L); \
+	s2=(int)(t>>24L); \
+	s1&=0xfc; \
+	s2&=0xfc; \
+	LL^= *(const DES_LONG *)(des_SP+0x500+s1); \
+	LL^= *(const DES_LONG *)(des_SP+0x700+s2); }
+#endif
+#else
+#define D_ENCRYPT(LL,R,S) { \
+	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
+	t=ROTATE(t,4); \
+	LL^= \
+	*(const DES_LONG *)(des_SP      +((u     )&0xfc))^ \
+	*(const DES_LONG *)(des_SP+0x200+((u>> 8L)&0xfc))^ \
+	*(const DES_LONG *)(des_SP+0x400+((u>>16L)&0xfc))^ \
+	*(const DES_LONG *)(des_SP+0x600+((u>>24L)&0xfc))^ \
+	*(const DES_LONG *)(des_SP+0x100+((t     )&0xfc))^ \
+	*(const DES_LONG *)(des_SP+0x300+((t>> 8L)&0xfc))^ \
+	*(const DES_LONG *)(des_SP+0x500+((t>>16L)&0xfc))^ \
+	*(const DES_LONG *)(des_SP+0x700+((t>>24L)&0xfc)); }
+#endif
+
+#else /* original version */
+
+#if defined(DES_RISC1) || defined(DES_RISC2)
+#ifdef DES_RISC1
+#define D_ENCRYPT(LL,R,S) {\
+	unsigned int u1,u2,u3; \
+	LOAD_DATA(R,S,u,t,E0,E1,u1); \
+	u>>=2L; \
+	t=ROTATE(t,6); \
+	u2=(int)u>>8L; \
+	u1=(int)u&0x3f; \
+	u2&=0x3f; \
+	u>>=16L; \
+	LL^=DES_SPtrans[0][u1]; \
+	LL^=DES_SPtrans[2][u2]; \
+	u3=(int)u>>8L; \
+	u1=(int)u&0x3f; \
+	u3&=0x3f; \
+	LL^=DES_SPtrans[4][u1]; \
+	LL^=DES_SPtrans[6][u3]; \
+	u2=(int)t>>8L; \
+	u1=(int)t&0x3f; \
+	u2&=0x3f; \
+	t>>=16L; \
+	LL^=DES_SPtrans[1][u1]; \
+	LL^=DES_SPtrans[3][u2]; \
+	u3=(int)t>>8L; \
+	u1=(int)t&0x3f; \
+	u3&=0x3f; \
+	LL^=DES_SPtrans[5][u1]; \
+	LL^=DES_SPtrans[7][u3]; }
+#endif
+#ifdef DES_RISC2
+#define D_ENCRYPT(LL,R,S) {\
+	unsigned int u1,u2,s1,s2; \
+	LOAD_DATA(R,S,u,t,E0,E1,u1); \
+	u>>=2L; \
+	t=ROTATE(t,6); \
+	u2=(int)u>>8L; \
+	u1=(int)u&0x3f; \
+	u2&=0x3f; \
+	LL^=DES_SPtrans[0][u1]; \
+	LL^=DES_SPtrans[2][u2]; \
+	s1=(int)u>>16L; \
+	s2=(int)u>>24L; \
+	s1&=0x3f; \
+	s2&=0x3f; \
+	LL^=DES_SPtrans[4][s1]; \
+	LL^=DES_SPtrans[6][s2]; \
+	u2=(int)t>>8L; \
+	u1=(int)t&0x3f; \
+	u2&=0x3f; \
+	LL^=DES_SPtrans[1][u1]; \
+	LL^=DES_SPtrans[3][u2]; \
+	s1=(int)t>>16; \
+	s2=(int)t>>24L; \
+	s1&=0x3f; \
+	s2&=0x3f; \
+	LL^=DES_SPtrans[5][s1]; \
+	LL^=DES_SPtrans[7][s2]; }
+#endif
+
+#else
+
+#define D_ENCRYPT(LL,R,S) {\
+	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
+	t=ROTATE(t,4); \
+	LL^=\
+		DES_SPtrans[0][(u>> 2L)&0x3f]^ \
+		DES_SPtrans[2][(u>>10L)&0x3f]^ \
+		DES_SPtrans[4][(u>>18L)&0x3f]^ \
+		DES_SPtrans[6][(u>>26L)&0x3f]^ \
+		DES_SPtrans[1][(t>> 2L)&0x3f]^ \
+		DES_SPtrans[3][(t>>10L)&0x3f]^ \
+		DES_SPtrans[5][(t>>18L)&0x3f]^ \
+		DES_SPtrans[7][(t>>26L)&0x3f]; }
+#endif
+#endif
+
+	/* IP and FP
+	 * The problem is more of a geometric problem that random bit fiddling.
+	 0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
+	 8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
+	16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
+	24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
+
+	32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
+	40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
+	48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
+	56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
+
+	The output has been subject to swaps of the form
+	0 1 -> 3 1 but the odd and even bits have been put into
+	2 3    2 0
+	different words.  The main trick is to remember that
+	t=((l>>size)^r)&(mask);
+	r^=t;
+	l^=(t<<size);
+	can be used to swap and move bits between words.
+
+	So l =  0  1  2  3  r = 16 17 18 19
+	        4  5  6  7      20 21 22 23
+	        8  9 10 11      24 25 26 27
+	       12 13 14 15      28 29 30 31
+	becomes (for size == 2 and mask == 0x3333)
+	   t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
+		 6^20  7^21 -- --        4  5 20 21       6  7 22 23
+		10^24 11^25 -- --        8  9 24 25      10 11 24 25
+		14^28 15^29 -- --       12 13 28 29      14 15 28 29
+
+	Thanks for hints from Richard Outerbridge - he told me IP&FP
+	could be done in 15 xor, 10 shifts and 5 ands.
+	When I finally started to think of the problem in 2D
+	I first got ~42 operations without xors.  When I remembered
+	how to use xors :-) I got it to its final state.
+	*/
+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+	(b)^=(t),\
+	(a)^=((t)<<(n)))
+
+#define IP(l,r) \
+	{ \
+	register DES_LONG tt; \
+	PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
+	PERM_OP(l,r,tt,16,0x0000ffffL); \
+	PERM_OP(r,l,tt, 2,0x33333333L); \
+	PERM_OP(l,r,tt, 8,0x00ff00ffL); \
+	PERM_OP(r,l,tt, 1,0x55555555L); \
+	}
+
+#define FP(l,r) \
+	{ \
+	register DES_LONG tt; \
+	PERM_OP(l,r,tt, 1,0x55555555L); \
+	PERM_OP(r,l,tt, 8,0x00ff00ffL); \
+	PERM_OP(l,r,tt, 2,0x33333333L); \
+	PERM_OP(r,l,tt,16,0x0000ffffL); \
+	PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
+	}
+
+extern const DES_LONG DES_SPtrans[8][64];
+
+void fcrypt_body(DES_LONG *out,DES_key_schedule *ks,
+		 DES_LONG Eswap0, DES_LONG Eswap1);
+
+#ifdef OPENSSL_SMALL_FOOTPRINT
+#undef DES_UNROLL
+#endif
+#endif
diff --git a/openssl/crypto/des/des_old.c b/openssl/crypto/des/des_old.c
new file mode 100644
index 0000000..7c33ed7
--- /dev/null
+++ b/openssl/crypto/des/des_old.c
@@ -0,0 +1,273 @@
+/* crypto/des/des_old.c -*- mode:C; c-file-style: "eay" -*- */
+
+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *
+ * The function names in here are deprecated and are only present to
+ * provide an interface compatible with libdes.  OpenSSL now provides
+ * functions where "des_" has been replaced with "DES_" in the names,
+ * to make it possible to make incompatible changes that are needed
+ * for C type security and other stuff.
+ *
+ * Please consider starting to use the DES_ functions rather than the
+ * des_ ones.  The des_ functions will dissapear completely before
+ * OpenSSL 1.0!
+ *
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ */
+
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#define OPENSSL_DES_LIBDES_COMPATIBILITY
+#include <openssl/des.h>
+#include <openssl/rand.h>
+
+const char *_ossl_old_des_options(void)
+	{
+	return DES_options();
+	}
+void _ossl_old_des_ecb3_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
+	des_key_schedule ks1,des_key_schedule ks2,
+	des_key_schedule ks3, int enc)
+	{
+	DES_ecb3_encrypt((const_DES_cblock *)input, output,
+		(DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
+		(DES_key_schedule *)ks3, enc);
+	}
+DES_LONG _ossl_old_des_cbc_cksum(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
+	long length,des_key_schedule schedule,_ossl_old_des_cblock *ivec)
+	{
+	return DES_cbc_cksum((unsigned char *)input, output, length,
+		(DES_key_schedule *)schedule, ivec);
+	}
+void _ossl_old_des_cbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
+	des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc)
+	{
+	DES_cbc_encrypt((unsigned char *)input, (unsigned char *)output,
+		length, (DES_key_schedule *)schedule, ivec, enc);
+	}
+void _ossl_old_des_ncbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
+	des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc)
+	{
+	DES_ncbc_encrypt((unsigned char *)input, (unsigned char *)output,
+		length, (DES_key_schedule *)schedule, ivec, enc);
+	}
+void _ossl_old_des_xcbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
+	des_key_schedule schedule,_ossl_old_des_cblock *ivec,
+	_ossl_old_des_cblock *inw,_ossl_old_des_cblock *outw,int enc)
+	{
+	DES_xcbc_encrypt((unsigned char *)input, (unsigned char *)output,
+		length, (DES_key_schedule *)schedule, ivec, inw, outw, enc);
+	}
+void _ossl_old_des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
+	long length,des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc)
+	{
+	DES_cfb_encrypt(in, out, numbits, length,
+		(DES_key_schedule *)schedule, ivec, enc);
+	}
+void _ossl_old_des_ecb_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
+	des_key_schedule ks,int enc)
+	{
+	DES_ecb_encrypt(input, output, (DES_key_schedule *)ks, enc);
+	}
+void _ossl_old_des_encrypt(DES_LONG *data,des_key_schedule ks, int enc)
+	{
+	DES_encrypt1(data, (DES_key_schedule *)ks, enc);
+	}
+void _ossl_old_des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc)
+	{
+	DES_encrypt2(data, (DES_key_schedule *)ks, enc);
+	}
+void _ossl_old_des_encrypt3(DES_LONG *data, des_key_schedule ks1,
+	des_key_schedule ks2, des_key_schedule ks3)
+	{
+	DES_encrypt3(data, (DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
+		(DES_key_schedule *)ks3);
+	}
+void _ossl_old_des_decrypt3(DES_LONG *data, des_key_schedule ks1,
+	des_key_schedule ks2, des_key_schedule ks3)
+	{
+	DES_decrypt3(data, (DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
+		(DES_key_schedule *)ks3);
+	}
+void _ossl_old_des_ede3_cbc_encrypt(_ossl_old_des_cblock *input, _ossl_old_des_cblock *output, 
+	long length, des_key_schedule ks1, des_key_schedule ks2, 
+	des_key_schedule ks3, _ossl_old_des_cblock *ivec, int enc)
+	{
+	DES_ede3_cbc_encrypt((unsigned char *)input, (unsigned char *)output,
+		length, (DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
+		(DES_key_schedule *)ks3, ivec, enc);
+	}
+void _ossl_old_des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
+	long length, des_key_schedule ks1, des_key_schedule ks2,
+	des_key_schedule ks3, _ossl_old_des_cblock *ivec, int *num, int enc)
+	{
+	DES_ede3_cfb64_encrypt(in, out, length,
+		(DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
+		(DES_key_schedule *)ks3, ivec, num, enc);
+	}
+void _ossl_old_des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
+	long length, des_key_schedule ks1, des_key_schedule ks2,
+	des_key_schedule ks3, _ossl_old_des_cblock *ivec, int *num)
+	{
+	DES_ede3_ofb64_encrypt(in, out, length,
+		(DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
+		(DES_key_schedule *)ks3, ivec, num);
+	}
+
+#if 0 /* broken code, preserved just in case anyone specifically looks for this */
+void _ossl_old_des_xwhite_in2out(_ossl_old_des_cblock (*des_key), _ossl_old_des_cblock (*in_white),
+	_ossl_old_des_cblock (*out_white))
+	{
+	DES_xwhite_in2out(des_key, in_white, out_white);
+	}
+#endif
+
+int _ossl_old_des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
+	_ossl_old_des_cblock *iv)
+	{
+	return DES_enc_read(fd, buf, len, (DES_key_schedule *)sched, iv);
+	}
+int _ossl_old_des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
+	_ossl_old_des_cblock *iv)
+	{
+	return DES_enc_write(fd, buf, len, (DES_key_schedule *)sched, iv);
+	}
+char *_ossl_old_des_fcrypt(const char *buf,const char *salt, char *ret)
+	{
+	return DES_fcrypt(buf, salt, ret);
+	}
+char *_ossl_old_des_crypt(const char *buf,const char *salt)
+	{
+	return DES_crypt(buf, salt);
+	}
+char *_ossl_old_crypt(const char *buf,const char *salt)
+	{
+	return DES_crypt(buf, salt);
+	}
+void _ossl_old_des_ofb_encrypt(unsigned char *in,unsigned char *out,
+	int numbits,long length,des_key_schedule schedule,_ossl_old_des_cblock *ivec)
+	{
+	DES_ofb_encrypt(in, out, numbits, length, (DES_key_schedule *)schedule,
+		ivec);
+	}
+void _ossl_old_des_pcbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
+	des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc)
+	{
+	DES_pcbc_encrypt((unsigned char *)input, (unsigned char *)output,
+		length, (DES_key_schedule *)schedule, ivec, enc);
+	}
+DES_LONG _ossl_old_des_quad_cksum(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
+	long length,int out_count,_ossl_old_des_cblock *seed)
+	{
+	return DES_quad_cksum((unsigned char *)input, output, length,
+		out_count, seed);
+	}
+void _ossl_old_des_random_seed(_ossl_old_des_cblock key)
+	{
+	RAND_seed(key, sizeof(_ossl_old_des_cblock));
+	}
+void _ossl_old_des_random_key(_ossl_old_des_cblock ret)
+	{
+	DES_random_key((DES_cblock *)ret);
+	}
+int _ossl_old_des_read_password(_ossl_old_des_cblock *key, const char *prompt,
+				int verify)
+	{
+	return DES_read_password(key, prompt, verify);
+	}
+int _ossl_old_des_read_2passwords(_ossl_old_des_cblock *key1, _ossl_old_des_cblock *key2,
+	const char *prompt, int verify)
+	{
+	return DES_read_2passwords(key1, key2, prompt, verify);
+	}
+void _ossl_old_des_set_odd_parity(_ossl_old_des_cblock *key)
+	{
+	DES_set_odd_parity(key);
+	}
+int _ossl_old_des_is_weak_key(_ossl_old_des_cblock *key)
+	{
+	return DES_is_weak_key(key);
+	}
+int _ossl_old_des_set_key(_ossl_old_des_cblock *key,des_key_schedule schedule)
+	{
+	return DES_set_key(key, (DES_key_schedule *)schedule);
+	}
+int _ossl_old_des_key_sched(_ossl_old_des_cblock *key,des_key_schedule schedule)
+	{
+	return DES_key_sched(key, (DES_key_schedule *)schedule);
+	}
+void _ossl_old_des_string_to_key(char *str,_ossl_old_des_cblock *key)
+	{
+	DES_string_to_key(str, key);
+	}
+void _ossl_old_des_string_to_2keys(char *str,_ossl_old_des_cblock *key1,_ossl_old_des_cblock *key2)
+	{
+	DES_string_to_2keys(str, key1, key2);
+	}
+void _ossl_old_des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
+	des_key_schedule schedule, _ossl_old_des_cblock *ivec, int *num, int enc)
+	{
+	DES_cfb64_encrypt(in, out, length, (DES_key_schedule *)schedule,
+		ivec, num, enc);
+	}
+void _ossl_old_des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
+	des_key_schedule schedule, _ossl_old_des_cblock *ivec, int *num)
+	{
+	DES_ofb64_encrypt(in, out, length, (DES_key_schedule *)schedule,
+		ivec, num);
+	}
diff --git a/openssl/crypto/des/des_old.h b/openssl/crypto/des/des_old.h
new file mode 100644
index 0000000..2b2c372
--- /dev/null
+++ b/openssl/crypto/des/des_old.h
@@ -0,0 +1,446 @@
+/* crypto/des/des_old.h -*- mode:C; c-file-style: "eay" -*- */
+
+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *
+ * The function names in here are deprecated and are only present to
+ * provide an interface compatible with openssl 0.9.6 and older as
+ * well as libdes.  OpenSSL now provides functions where "des_" has
+ * been replaced with "DES_" in the names, to make it possible to
+ * make incompatible changes that are needed for C type security and
+ * other stuff.
+ *
+ * This include files has two compatibility modes:
+ *
+ *   - If OPENSSL_DES_LIBDES_COMPATIBILITY is defined, you get an API
+ *     that is compatible with libdes and SSLeay.
+ *   - If OPENSSL_DES_LIBDES_COMPATIBILITY isn't defined, you get an
+ *     API that is compatible with OpenSSL 0.9.5x to 0.9.6x.
+ *
+ * Note that these modes break earlier snapshots of OpenSSL, where
+ * libdes compatibility was the only available mode or (later on) the
+ * prefered compatibility mode.  However, after much consideration
+ * (and more or less violent discussions with external parties), it
+ * was concluded that OpenSSL should be compatible with earlier versions
+ * of itself before anything else.  Also, in all honesty, libdes is
+ * an old beast that shouldn't really be used any more.
+ *
+ * Please consider starting to use the DES_ functions rather than the
+ * des_ ones.  The des_ functions will disappear completely before
+ * OpenSSL 1.0!
+ *
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ */
+
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_DES_H
+#define HEADER_DES_H
+
+#include <openssl/e_os2.h>	/* OPENSSL_EXTERN, OPENSSL_NO_DES, DES_LONG */
+
+#ifdef OPENSSL_NO_DES
+#error DES is disabled.
+#endif
+
+#ifndef HEADER_NEW_DES_H
+#error You must include des.h, not des_old.h directly.
+#endif
+
+#ifdef _KERBEROS_DES_H
+#error <openssl/des_old.h> replaces <kerberos/des.h>.
+#endif
+
+#include <openssl/symhacks.h>
+
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef _
+#undef _
+#endif
+
+typedef unsigned char _ossl_old_des_cblock[8];
+typedef struct _ossl_old_des_ks_struct
+	{
+	union	{
+		_ossl_old_des_cblock _;
+		/* make sure things are correct size on machines with
+		 * 8 byte longs */
+		DES_LONG pad[2];
+		} ks;
+	} _ossl_old_des_key_schedule[16];
+
+#ifndef OPENSSL_DES_LIBDES_COMPATIBILITY
+#define des_cblock DES_cblock
+#define const_des_cblock const_DES_cblock
+#define des_key_schedule DES_key_schedule
+#define des_ecb3_encrypt(i,o,k1,k2,k3,e)\
+	DES_ecb3_encrypt((i),(o),&(k1),&(k2),&(k3),(e))
+#define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\
+	DES_ede3_cbc_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(e))
+#define des_ede3_cbcm_encrypt(i,o,l,k1,k2,k3,iv1,iv2,e)\
+	DES_ede3_cbcm_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv1),(iv2),(e))
+#define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\
+	DES_ede3_cfb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n),(e))
+#define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\
+	DES_ede3_ofb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n))
+#define des_options()\
+	DES_options()
+#define des_cbc_cksum(i,o,l,k,iv)\
+	DES_cbc_cksum((i),(o),(l),&(k),(iv))
+#define des_cbc_encrypt(i,o,l,k,iv,e)\
+	DES_cbc_encrypt((i),(o),(l),&(k),(iv),(e))
+#define des_ncbc_encrypt(i,o,l,k,iv,e)\
+	DES_ncbc_encrypt((i),(o),(l),&(k),(iv),(e))
+#define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\
+	DES_xcbc_encrypt((i),(o),(l),&(k),(iv),(inw),(outw),(e))
+#define des_cfb_encrypt(i,o,n,l,k,iv,e)\
+	DES_cfb_encrypt((i),(o),(n),(l),&(k),(iv),(e))
+#define des_ecb_encrypt(i,o,k,e)\
+	DES_ecb_encrypt((i),(o),&(k),(e))
+#define des_encrypt1(d,k,e)\
+	DES_encrypt1((d),&(k),(e))
+#define des_encrypt2(d,k,e)\
+	DES_encrypt2((d),&(k),(e))
+#define des_encrypt3(d,k1,k2,k3)\
+	DES_encrypt3((d),&(k1),&(k2),&(k3))
+#define des_decrypt3(d,k1,k2,k3)\
+	DES_decrypt3((d),&(k1),&(k2),&(k3))
+#define des_xwhite_in2out(k,i,o)\
+	DES_xwhite_in2out((k),(i),(o))
+#define des_enc_read(f,b,l,k,iv)\
+	DES_enc_read((f),(b),(l),&(k),(iv))
+#define des_enc_write(f,b,l,k,iv)\
+	DES_enc_write((f),(b),(l),&(k),(iv))
+#define des_fcrypt(b,s,r)\
+	DES_fcrypt((b),(s),(r))
+#if 0
+#define des_crypt(b,s)\
+	DES_crypt((b),(s))
+#if !defined(PERL5) && !defined(__FreeBSD__) && !defined(NeXT) && !defined(__OpenBSD__)
+#define crypt(b,s)\
+	DES_crypt((b),(s))
+#endif
+#endif
+#define des_ofb_encrypt(i,o,n,l,k,iv)\
+	DES_ofb_encrypt((i),(o),(n),(l),&(k),(iv))
+#define des_pcbc_encrypt(i,o,l,k,iv,e)\
+	DES_pcbc_encrypt((i),(o),(l),&(k),(iv),(e))
+#define des_quad_cksum(i,o,l,c,s)\
+	DES_quad_cksum((i),(o),(l),(c),(s))
+#define des_random_seed(k)\
+	_ossl_096_des_random_seed((k))
+#define des_random_key(r)\
+	DES_random_key((r))
+#define des_read_password(k,p,v) \
+	DES_read_password((k),(p),(v))
+#define des_read_2passwords(k1,k2,p,v) \
+	DES_read_2passwords((k1),(k2),(p),(v))
+#define des_set_odd_parity(k)\
+	DES_set_odd_parity((k))
+#define des_check_key_parity(k)\
+	DES_check_key_parity((k))
+#define des_is_weak_key(k)\
+	DES_is_weak_key((k))
+#define des_set_key(k,ks)\
+	DES_set_key((k),&(ks))
+#define des_key_sched(k,ks)\
+	DES_key_sched((k),&(ks))
+#define des_set_key_checked(k,ks)\
+	DES_set_key_checked((k),&(ks))
+#define des_set_key_unchecked(k,ks)\
+	DES_set_key_unchecked((k),&(ks))
+#define des_string_to_key(s,k)\
+	DES_string_to_key((s),(k))
+#define des_string_to_2keys(s,k1,k2)\
+	DES_string_to_2keys((s),(k1),(k2))
+#define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\
+	DES_cfb64_encrypt((i),(o),(l),&(ks),(iv),(n),(e))
+#define des_ofb64_encrypt(i,o,l,ks,iv,n)\
+	DES_ofb64_encrypt((i),(o),(l),&(ks),(iv),(n))
+		
+
+#define des_ecb2_encrypt(i,o,k1,k2,e) \
+	des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+	des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+	des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+	des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+#define des_check_key DES_check_key
+#define des_rw_mode DES_rw_mode
+#else /* libdes compatibility */
+/* Map all symbol names to _ossl_old_des_* form, so we avoid all
+   clashes with libdes */
+#define des_cblock _ossl_old_des_cblock
+#define des_key_schedule _ossl_old_des_key_schedule
+#define des_ecb3_encrypt(i,o,k1,k2,k3,e)\
+	_ossl_old_des_ecb3_encrypt((i),(o),(k1),(k2),(k3),(e))
+#define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\
+	_ossl_old_des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(e))
+#define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\
+	_ossl_old_des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n),(e))
+#define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\
+	_ossl_old_des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n))
+#define des_options()\
+	_ossl_old_des_options()
+#define des_cbc_cksum(i,o,l,k,iv)\
+	_ossl_old_des_cbc_cksum((i),(o),(l),(k),(iv))
+#define des_cbc_encrypt(i,o,l,k,iv,e)\
+	_ossl_old_des_cbc_encrypt((i),(o),(l),(k),(iv),(e))
+#define des_ncbc_encrypt(i,o,l,k,iv,e)\
+	_ossl_old_des_ncbc_encrypt((i),(o),(l),(k),(iv),(e))
+#define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\
+	_ossl_old_des_xcbc_encrypt((i),(o),(l),(k),(iv),(inw),(outw),(e))
+#define des_cfb_encrypt(i,o,n,l,k,iv,e)\
+	_ossl_old_des_cfb_encrypt((i),(o),(n),(l),(k),(iv),(e))
+#define des_ecb_encrypt(i,o,k,e)\
+	_ossl_old_des_ecb_encrypt((i),(o),(k),(e))
+#define des_encrypt(d,k,e)\
+	_ossl_old_des_encrypt((d),(k),(e))
+#define des_encrypt2(d,k,e)\
+	_ossl_old_des_encrypt2((d),(k),(e))
+#define des_encrypt3(d,k1,k2,k3)\
+	_ossl_old_des_encrypt3((d),(k1),(k2),(k3))
+#define des_decrypt3(d,k1,k2,k3)\
+	_ossl_old_des_decrypt3((d),(k1),(k2),(k3))
+#define des_xwhite_in2out(k,i,o)\
+	_ossl_old_des_xwhite_in2out((k),(i),(o))
+#define des_enc_read(f,b,l,k,iv)\
+	_ossl_old_des_enc_read((f),(b),(l),(k),(iv))
+#define des_enc_write(f,b,l,k,iv)\
+	_ossl_old_des_enc_write((f),(b),(l),(k),(iv))
+#define des_fcrypt(b,s,r)\
+	_ossl_old_des_fcrypt((b),(s),(r))
+#define des_crypt(b,s)\
+	_ossl_old_des_crypt((b),(s))
+#if 0
+#define crypt(b,s)\
+	_ossl_old_crypt((b),(s))
+#endif
+#define des_ofb_encrypt(i,o,n,l,k,iv)\
+	_ossl_old_des_ofb_encrypt((i),(o),(n),(l),(k),(iv))
+#define des_pcbc_encrypt(i,o,l,k,iv,e)\
+	_ossl_old_des_pcbc_encrypt((i),(o),(l),(k),(iv),(e))
+#define des_quad_cksum(i,o,l,c,s)\
+	_ossl_old_des_quad_cksum((i),(o),(l),(c),(s))
+#define des_random_seed(k)\
+	_ossl_old_des_random_seed((k))
+#define des_random_key(r)\
+	_ossl_old_des_random_key((r))
+#define des_read_password(k,p,v) \
+	_ossl_old_des_read_password((k),(p),(v))
+#define des_read_2passwords(k1,k2,p,v) \
+	_ossl_old_des_read_2passwords((k1),(k2),(p),(v))
+#define des_set_odd_parity(k)\
+	_ossl_old_des_set_odd_parity((k))
+#define des_is_weak_key(k)\
+	_ossl_old_des_is_weak_key((k))
+#define des_set_key(k,ks)\
+	_ossl_old_des_set_key((k),(ks))
+#define des_key_sched(k,ks)\
+	_ossl_old_des_key_sched((k),(ks))
+#define des_string_to_key(s,k)\
+	_ossl_old_des_string_to_key((s),(k))
+#define des_string_to_2keys(s,k1,k2)\
+	_ossl_old_des_string_to_2keys((s),(k1),(k2))
+#define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\
+	_ossl_old_des_cfb64_encrypt((i),(o),(l),(ks),(iv),(n),(e))
+#define des_ofb64_encrypt(i,o,l,ks,iv,n)\
+	_ossl_old_des_ofb64_encrypt((i),(o),(l),(ks),(iv),(n))
+		
+
+#define des_ecb2_encrypt(i,o,k1,k2,e) \
+	des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+	des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+	des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+	des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+#define des_check_key DES_check_key
+#define des_rw_mode DES_rw_mode
+#endif
+
+const char *_ossl_old_des_options(void);
+void _ossl_old_des_ecb3_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
+	_ossl_old_des_key_schedule ks1,_ossl_old_des_key_schedule ks2,
+	_ossl_old_des_key_schedule ks3, int enc);
+DES_LONG _ossl_old_des_cbc_cksum(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
+	long length,_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec);
+void _ossl_old_des_cbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
+	_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc);
+void _ossl_old_des_ncbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
+	_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc);
+void _ossl_old_des_xcbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
+	_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,
+	_ossl_old_des_cblock *inw,_ossl_old_des_cblock *outw,int enc);
+void _ossl_old_des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
+	long length,_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc);
+void _ossl_old_des_ecb_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
+	_ossl_old_des_key_schedule ks,int enc);
+void _ossl_old_des_encrypt(DES_LONG *data,_ossl_old_des_key_schedule ks, int enc);
+void _ossl_old_des_encrypt2(DES_LONG *data,_ossl_old_des_key_schedule ks, int enc);
+void _ossl_old_des_encrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1,
+	_ossl_old_des_key_schedule ks2, _ossl_old_des_key_schedule ks3);
+void _ossl_old_des_decrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1,
+	_ossl_old_des_key_schedule ks2, _ossl_old_des_key_schedule ks3);
+void _ossl_old_des_ede3_cbc_encrypt(_ossl_old_des_cblock *input, _ossl_old_des_cblock *output, 
+	long length, _ossl_old_des_key_schedule ks1, _ossl_old_des_key_schedule ks2, 
+	_ossl_old_des_key_schedule ks3, _ossl_old_des_cblock *ivec, int enc);
+void _ossl_old_des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
+	long length, _ossl_old_des_key_schedule ks1, _ossl_old_des_key_schedule ks2,
+	_ossl_old_des_key_schedule ks3, _ossl_old_des_cblock *ivec, int *num, int enc);
+void _ossl_old_des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
+	long length, _ossl_old_des_key_schedule ks1, _ossl_old_des_key_schedule ks2,
+	_ossl_old_des_key_schedule ks3, _ossl_old_des_cblock *ivec, int *num);
+#if 0
+void _ossl_old_des_xwhite_in2out(_ossl_old_des_cblock (*des_key), _ossl_old_des_cblock (*in_white),
+	_ossl_old_des_cblock (*out_white));
+#endif
+
+int _ossl_old_des_enc_read(int fd,char *buf,int len,_ossl_old_des_key_schedule sched,
+	_ossl_old_des_cblock *iv);
+int _ossl_old_des_enc_write(int fd,char *buf,int len,_ossl_old_des_key_schedule sched,
+	_ossl_old_des_cblock *iv);
+char *_ossl_old_des_fcrypt(const char *buf,const char *salt, char *ret);
+char *_ossl_old_des_crypt(const char *buf,const char *salt);
+#if !defined(PERL5) && !defined(NeXT)
+char *_ossl_old_crypt(const char *buf,const char *salt);
+#endif
+void _ossl_old_des_ofb_encrypt(unsigned char *in,unsigned char *out,
+	int numbits,long length,_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec);
+void _ossl_old_des_pcbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
+	_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc);
+DES_LONG _ossl_old_des_quad_cksum(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
+	long length,int out_count,_ossl_old_des_cblock *seed);
+void _ossl_old_des_random_seed(_ossl_old_des_cblock key);
+void _ossl_old_des_random_key(_ossl_old_des_cblock ret);
+int _ossl_old_des_read_password(_ossl_old_des_cblock *key,const char *prompt,int verify);
+int _ossl_old_des_read_2passwords(_ossl_old_des_cblock *key1,_ossl_old_des_cblock *key2,
+	const char *prompt,int verify);
+void _ossl_old_des_set_odd_parity(_ossl_old_des_cblock *key);
+int _ossl_old_des_is_weak_key(_ossl_old_des_cblock *key);
+int _ossl_old_des_set_key(_ossl_old_des_cblock *key,_ossl_old_des_key_schedule schedule);
+int _ossl_old_des_key_sched(_ossl_old_des_cblock *key,_ossl_old_des_key_schedule schedule);
+void _ossl_old_des_string_to_key(char *str,_ossl_old_des_cblock *key);
+void _ossl_old_des_string_to_2keys(char *str,_ossl_old_des_cblock *key1,_ossl_old_des_cblock *key2);
+void _ossl_old_des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
+	_ossl_old_des_key_schedule schedule, _ossl_old_des_cblock *ivec, int *num, int enc);
+void _ossl_old_des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
+	_ossl_old_des_key_schedule schedule, _ossl_old_des_cblock *ivec, int *num);
+
+void _ossl_096_des_random_seed(des_cblock *key);
+
+/* The following definitions provide compatibility with the MIT Kerberos
+ * library. The _ossl_old_des_key_schedule structure is not binary compatible. */
+
+#define _KERBEROS_DES_H
+
+#define KRBDES_ENCRYPT DES_ENCRYPT
+#define KRBDES_DECRYPT DES_DECRYPT
+
+#ifdef KERBEROS
+#  define ENCRYPT DES_ENCRYPT
+#  define DECRYPT DES_DECRYPT
+#endif
+
+#ifndef NCOMPAT
+#  define C_Block des_cblock
+#  define Key_schedule des_key_schedule
+#  define KEY_SZ DES_KEY_SZ
+#  define string_to_key des_string_to_key
+#  define read_pw_string des_read_pw_string
+#  define random_key des_random_key
+#  define pcbc_encrypt des_pcbc_encrypt
+#  define set_key des_set_key
+#  define key_sched des_key_sched
+#  define ecb_encrypt des_ecb_encrypt
+#  define cbc_encrypt des_cbc_encrypt
+#  define ncbc_encrypt des_ncbc_encrypt
+#  define xcbc_encrypt des_xcbc_encrypt
+#  define cbc_cksum des_cbc_cksum
+#  define quad_cksum des_quad_cksum
+#  define check_parity des_check_key_parity
+#endif
+
+#define des_fixup_key_parity DES_fixup_key_parity
+
+#ifdef  __cplusplus
+}
+#endif
+
+/* for DES_read_pw_string et al */
+#include <openssl/ui_compat.h>
+
+#endif
diff --git a/openssl/crypto/des/des_old2.c b/openssl/crypto/des/des_old2.c
new file mode 100644
index 0000000..c8fa3ee
--- /dev/null
+++ b/openssl/crypto/des/des_old2.c
@@ -0,0 +1,82 @@
+/* crypto/des/des_old.c -*- mode:C; c-file-style: "eay" -*- */
+
+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *
+ * The function names in here are deprecated and are only present to
+ * provide an interface compatible with OpenSSL 0.9.6c.  OpenSSL now
+ * provides functions where "des_" has been replaced with "DES_" in
+ * the names, to make it possible to make incompatible changes that
+ * are needed for C type security and other stuff.
+ *
+ * Please consider starting to use the DES_ functions rather than the
+ * des_ ones.  The des_ functions will dissapear completely before
+ * OpenSSL 1.0!
+ *
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ */
+
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#undef OPENSSL_DES_LIBDES_COMPATIBILITY
+#include <openssl/des.h>
+#include <openssl/rand.h>
+
+void _ossl_096_des_random_seed(DES_cblock *key)
+	{
+	RAND_seed(key, sizeof(DES_cblock));
+	}
diff --git a/openssl/crypto/des/des_opts.c b/openssl/crypto/des/des_opts.c
new file mode 100644
index 0000000..2df8296
--- /dev/null
+++ b/openssl/crypto/des/des_opts.c
@@ -0,0 +1,608 @@
+/* crypto/des/des_opts.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
+ * This is for machines with 64k code segment size restrictions. */
+
+#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
+#define TIMES
+#endif
+
+#include <stdio.h>
+#ifndef OPENSSL_SYS_MSDOS
+#include <openssl/e_os2.h>
+#include OPENSSL_UNISTD
+#else
+#include <io.h>
+extern void exit();
+#endif
+
+#ifndef OPENSSL_SYS_NETWARE
+#include <signal.h>
+#endif
+
+#ifndef _IRIX
+#include <time.h>
+#endif
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+#endif
+
+/* Depending on the VMS version, the tms structure is perhaps defined.
+   The __TMS macro will show if it was.  If it wasn't defined, we should
+   undefine TIMES, since that tells the rest of the program how things
+   should be handled.				-- Richard Levitte */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
+#undef TIMES
+#endif
+
+#ifndef TIMES
+#include <sys/timeb.h>
+#endif
+
+
+#if defined(sun) || defined(__ultrix)
+#define _POSIX_SOURCE
+#include <limits.h>
+#include <sys/param.h>
+#endif
+
+#include <openssl/des.h>
+#include "spr.h"
+
+#define DES_DEFAULT_OPTIONS
+
+#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4)
+#define PART1
+#define PART2
+#define PART3
+#define PART4
+#endif
+
+#ifdef PART1
+
+#undef DES_UNROLL
+#undef DES_RISC1
+#undef DES_RISC2
+#undef DES_PTR
+#undef D_ENCRYPT
+#define DES_encrypt1 des_encrypt_u4_cisc_idx
+#define DES_encrypt2 des_encrypt2_u4_cisc_idx
+#define DES_encrypt3 des_encrypt3_u4_cisc_idx
+#define DES_decrypt3 des_decrypt3_u4_cisc_idx
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#define DES_UNROLL
+#undef DES_RISC1
+#undef DES_RISC2
+#undef DES_PTR
+#undef D_ENCRYPT
+#undef DES_encrypt1
+#undef DES_encrypt2
+#undef DES_encrypt3
+#undef DES_decrypt3
+#define DES_encrypt1 des_encrypt_u16_cisc_idx
+#define DES_encrypt2 des_encrypt2_u16_cisc_idx
+#define DES_encrypt3 des_encrypt3_u16_cisc_idx
+#define DES_decrypt3 des_decrypt3_u16_cisc_idx
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#undef DES_UNROLL
+#define DES_RISC1
+#undef DES_RISC2
+#undef DES_PTR
+#undef D_ENCRYPT
+#undef DES_encrypt1
+#undef DES_encrypt2
+#undef DES_encrypt3
+#undef DES_decrypt3
+#define DES_encrypt1 des_encrypt_u4_risc1_idx
+#define DES_encrypt2 des_encrypt2_u4_risc1_idx
+#define DES_encrypt3 des_encrypt3_u4_risc1_idx
+#define DES_decrypt3 des_decrypt3_u4_risc1_idx
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#endif
+
+#ifdef PART2
+
+#undef DES_UNROLL
+#undef DES_RISC1
+#define DES_RISC2
+#undef DES_PTR
+#undef D_ENCRYPT
+#undef DES_encrypt1
+#undef DES_encrypt2
+#undef DES_encrypt3
+#undef DES_decrypt3
+#define DES_encrypt1 des_encrypt_u4_risc2_idx
+#define DES_encrypt2 des_encrypt2_u4_risc2_idx
+#define DES_encrypt3 des_encrypt3_u4_risc2_idx
+#define DES_decrypt3 des_decrypt3_u4_risc2_idx
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#define DES_UNROLL
+#define DES_RISC1
+#undef DES_RISC2
+#undef DES_PTR
+#undef D_ENCRYPT
+#undef DES_encrypt1
+#undef DES_encrypt2
+#undef DES_encrypt3
+#undef DES_decrypt3
+#define DES_encrypt1 des_encrypt_u16_risc1_idx
+#define DES_encrypt2 des_encrypt2_u16_risc1_idx
+#define DES_encrypt3 des_encrypt3_u16_risc1_idx
+#define DES_decrypt3 des_decrypt3_u16_risc1_idx
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#define DES_UNROLL
+#undef DES_RISC1
+#define DES_RISC2
+#undef DES_PTR
+#undef D_ENCRYPT
+#undef DES_encrypt1
+#undef DES_encrypt2
+#undef DES_encrypt3
+#undef DES_decrypt3
+#define DES_encrypt1 des_encrypt_u16_risc2_idx
+#define DES_encrypt2 des_encrypt2_u16_risc2_idx
+#define DES_encrypt3 des_encrypt3_u16_risc2_idx
+#define DES_decrypt3 des_decrypt3_u16_risc2_idx
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#endif
+
+#ifdef PART3
+
+#undef DES_UNROLL
+#undef DES_RISC1
+#undef DES_RISC2
+#define DES_PTR
+#undef D_ENCRYPT
+#undef DES_encrypt1
+#undef DES_encrypt2
+#undef DES_encrypt3
+#undef DES_decrypt3
+#define DES_encrypt1 des_encrypt_u4_cisc_ptr
+#define DES_encrypt2 des_encrypt2_u4_cisc_ptr
+#define DES_encrypt3 des_encrypt3_u4_cisc_ptr
+#define DES_decrypt3 des_decrypt3_u4_cisc_ptr
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#define DES_UNROLL
+#undef DES_RISC1
+#undef DES_RISC2
+#define DES_PTR
+#undef D_ENCRYPT
+#undef DES_encrypt1
+#undef DES_encrypt2
+#undef DES_encrypt3
+#undef DES_decrypt3
+#define DES_encrypt1 des_encrypt_u16_cisc_ptr
+#define DES_encrypt2 des_encrypt2_u16_cisc_ptr
+#define DES_encrypt3 des_encrypt3_u16_cisc_ptr
+#define DES_decrypt3 des_decrypt3_u16_cisc_ptr
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#undef DES_UNROLL
+#define DES_RISC1
+#undef DES_RISC2
+#define DES_PTR
+#undef D_ENCRYPT
+#undef DES_encrypt1
+#undef DES_encrypt2
+#undef DES_encrypt3
+#undef DES_decrypt3
+#define DES_encrypt1 des_encrypt_u4_risc1_ptr
+#define DES_encrypt2 des_encrypt2_u4_risc1_ptr
+#define DES_encrypt3 des_encrypt3_u4_risc1_ptr
+#define DES_decrypt3 des_decrypt3_u4_risc1_ptr
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#endif
+
+#ifdef PART4
+
+#undef DES_UNROLL
+#undef DES_RISC1
+#define DES_RISC2
+#define DES_PTR
+#undef D_ENCRYPT
+#undef DES_encrypt1
+#undef DES_encrypt2
+#undef DES_encrypt3
+#undef DES_decrypt3
+#define DES_encrypt1 des_encrypt_u4_risc2_ptr
+#define DES_encrypt2 des_encrypt2_u4_risc2_ptr
+#define DES_encrypt3 des_encrypt3_u4_risc2_ptr
+#define DES_decrypt3 des_decrypt3_u4_risc2_ptr
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#define DES_UNROLL
+#define DES_RISC1
+#undef DES_RISC2
+#define DES_PTR
+#undef D_ENCRYPT
+#undef DES_encrypt1
+#undef DES_encrypt2
+#undef DES_encrypt3
+#undef DES_decrypt3
+#define DES_encrypt1 des_encrypt_u16_risc1_ptr
+#define DES_encrypt2 des_encrypt2_u16_risc1_ptr
+#define DES_encrypt3 des_encrypt3_u16_risc1_ptr
+#define DES_decrypt3 des_decrypt3_u16_risc1_ptr
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#define DES_UNROLL
+#undef DES_RISC1
+#define DES_RISC2
+#define DES_PTR
+#undef D_ENCRYPT
+#undef DES_encrypt1
+#undef DES_encrypt2
+#undef DES_encrypt3
+#undef DES_decrypt3
+#define DES_encrypt1 des_encrypt_u16_risc2_ptr
+#define DES_encrypt2 des_encrypt2_u16_risc2_ptr
+#define DES_encrypt3 des_encrypt3_u16_risc2_ptr
+#define DES_decrypt3 des_decrypt3_u16_risc2_ptr
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#endif
+
+/* The following if from times(3) man page.  It may need to be changed */
+#ifndef HZ
+# ifndef CLK_TCK
+#  ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
+#   define HZ	100.0
+#  else /* _BSD_CLK_TCK_ */
+#   define HZ ((double)_BSD_CLK_TCK_)
+#  endif
+# else /* CLK_TCK */
+#  define HZ ((double)CLK_TCK)
+# endif
+#endif
+
+#define BUFSIZE	((long)1024)
+long run=0;
+
+double Time_F(int s);
+#ifdef SIGALRM
+#if defined(__STDC__) || defined(sgi)
+#define SIGRETTYPE void
+#else
+#define SIGRETTYPE int
+#endif
+
+SIGRETTYPE sig_done(int sig);
+SIGRETTYPE sig_done(int sig)
+	{
+	signal(SIGALRM,sig_done);
+	run=0;
+#ifdef LINT
+	sig=sig;
+#endif
+	}
+#endif
+
+#define START	0
+#define STOP	1
+
+double Time_F(int s)
+	{
+	double ret;
+#ifdef TIMES
+	static struct tms tstart,tend;
+
+	if (s == START)
+		{
+		times(&tstart);
+		return(0);
+		}
+	else
+		{
+		times(&tend);
+		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#else /* !times() */
+	static struct timeb tstart,tend;
+	long i;
+
+	if (s == START)
+		{
+		ftime(&tstart);
+		return(0);
+		}
+	else
+		{
+		ftime(&tend);
+		i=(long)tend.millitm-(long)tstart.millitm;
+		ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#endif
+	}
+
+#ifdef SIGALRM
+#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
+#else
+#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
+#endif
+	
+#define time_it(func,name,index) \
+	print_name(name); \
+	Time_F(START); \
+	for (count=0,run=1; COND(cb); count++) \
+		{ \
+		unsigned long d[2]; \
+		func(d,&sch,DES_ENCRYPT); \
+		} \
+	tm[index]=Time_F(STOP); \
+	fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
+	tm[index]=((double)COUNT(cb))/tm[index];
+
+#define print_it(name,index) \
+	fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
+		tm[index]*8,1.0e6/tm[index]);
+
+int main(int argc, char **argv)
+	{
+	long count;
+	static unsigned char buf[BUFSIZE];
+	static DES_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
+	static DES_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
+	static DES_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
+	DES_key_schedule sch,sch2,sch3;
+	double d,tm[16],max=0;
+	int rank[16];
+	char *str[16];
+	int max_idx=0,i,num=0,j;
+#ifndef SIGALARM
+	long ca,cb,cc,cd,ce;
+#endif
+
+	for (i=0; i<12; i++)
+		{
+		tm[i]=0.0;
+		rank[i]=0;
+		}
+
+#ifndef TIMES
+	fprintf(stderr,"To get the most accurate results, try to run this\n");
+	fprintf(stderr,"program when this computer is idle.\n");
+#endif
+
+	DES_set_key_unchecked(&key,&sch);
+	DES_set_key_unchecked(&key2,&sch2);
+	DES_set_key_unchecked(&key3,&sch3);
+
+#ifndef SIGALRM
+	fprintf(stderr,"First we calculate the approximate speed ...\n");
+	DES_set_key_unchecked(&key,sch);
+	count=10;
+	do	{
+		long i;
+		unsigned long data[2];
+
+		count*=2;
+		Time_F(START);
+		for (i=count; i; i--)
+			DES_encrypt1(data,&(sch[0]),DES_ENCRYPT);
+		d=Time_F(STOP);
+		} while (d < 3.0);
+	ca=count;
+	cb=count*3;
+	cc=count*3*8/BUFSIZE+1;
+	cd=count*8/BUFSIZE+1;
+
+	ce=count/20+1;
+#define COND(d) (count != (d))
+#define COUNT(d) (d)
+#else
+#define COND(c) (run)
+#define COUNT(d) (count)
+        signal(SIGALRM,sig_done);
+        alarm(10);
+#endif
+
+#ifdef PART1
+	time_it(des_encrypt_u4_cisc_idx,  "des_encrypt_u4_cisc_idx  ", 0);
+	time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1);
+	time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2);
+	num+=3;
+#endif
+#ifdef PART2
+	time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3);
+	time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4);
+	time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5);
+	num+=3;
+#endif
+#ifdef PART3
+	time_it(des_encrypt_u4_cisc_ptr,  "des_encrypt_u4_cisc_ptr  ", 6);
+	time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7);
+	time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8);
+	num+=3;
+#endif
+#ifdef PART4
+	time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9);
+	time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10);
+	time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11);
+	num+=3;
+#endif
+
+#ifdef PART1
+	str[0]=" 4  c i";
+	print_it("des_encrypt_u4_cisc_idx  ",0);
+	max=tm[0];
+	max_idx=0;
+	str[1]="16  c i";
+	print_it("des_encrypt_u16_cisc_idx ",1);
+	if (max < tm[1]) { max=tm[1]; max_idx=1; }
+	str[2]=" 4 r1 i";
+	print_it("des_encrypt_u4_risc1_idx ",2);
+	if (max < tm[2]) { max=tm[2]; max_idx=2; }
+#endif
+#ifdef PART2
+	str[3]="16 r1 i";
+	print_it("des_encrypt_u16_risc1_idx",3);
+	if (max < tm[3]) { max=tm[3]; max_idx=3; }
+	str[4]=" 4 r2 i";
+	print_it("des_encrypt_u4_risc2_idx ",4);
+	if (max < tm[4]) { max=tm[4]; max_idx=4; }
+	str[5]="16 r2 i";
+	print_it("des_encrypt_u16_risc2_idx",5);
+	if (max < tm[5]) { max=tm[5]; max_idx=5; }
+#endif
+#ifdef PART3
+	str[6]=" 4  c p";
+	print_it("des_encrypt_u4_cisc_ptr  ",6);
+	if (max < tm[6]) { max=tm[6]; max_idx=6; }
+	str[7]="16  c p";
+	print_it("des_encrypt_u16_cisc_ptr ",7);
+	if (max < tm[7]) { max=tm[7]; max_idx=7; }
+	str[8]=" 4 r1 p";
+	print_it("des_encrypt_u4_risc1_ptr ",8);
+	if (max < tm[8]) { max=tm[8]; max_idx=8; }
+#endif
+#ifdef PART4
+	str[9]="16 r1 p";
+	print_it("des_encrypt_u16_risc1_ptr",9);
+	if (max < tm[9]) { max=tm[9]; max_idx=9; }
+	str[10]=" 4 r2 p";
+	print_it("des_encrypt_u4_risc2_ptr ",10);
+	if (max < tm[10]) { max=tm[10]; max_idx=10; }
+	str[11]="16 r2 p";
+	print_it("des_encrypt_u16_risc2_ptr",11);
+	if (max < tm[11]) { max=tm[11]; max_idx=11; }
+#endif
+	printf("options    des ecb/s\n");
+	printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
+	d=tm[max_idx];
+	tm[max_idx]= -2.0;
+	max= -1.0;
+	for (;;)
+		{
+		for (i=0; i<12; i++)
+			{
+			if (max < tm[i]) { max=tm[i]; j=i; }
+			}
+		if (max < 0.0) break;
+		printf("%s %12.2f  %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
+		tm[j]= -2.0;
+		max= -1.0;
+		}
+
+	switch (max_idx)
+		{
+	case 0:
+		printf("-DDES_DEFAULT_OPTIONS\n");
+		break;
+	case 1:
+		printf("-DDES_UNROLL\n");
+		break;
+	case 2:
+		printf("-DDES_RISC1\n");
+		break;
+	case 3:
+		printf("-DDES_UNROLL -DDES_RISC1\n");
+		break;
+	case 4:
+		printf("-DDES_RISC2\n");
+		break;
+	case 5:
+		printf("-DDES_UNROLL -DDES_RISC2\n");
+		break;
+	case 6:
+		printf("-DDES_PTR\n");
+		break;
+	case 7:
+		printf("-DDES_UNROLL -DDES_PTR\n");
+		break;
+	case 8:
+		printf("-DDES_RISC1 -DDES_PTR\n");
+		break;
+	case 9:
+		printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n");
+		break;
+	case 10:
+		printf("-DDES_RISC2 -DDES_PTR\n");
+		break;
+	case 11:
+		printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n");
+		break;
+		}
+	exit(0);
+#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
+	return(0);
+#endif
+	}
diff --git a/openssl/crypto/des/des_ver.h b/openssl/crypto/des/des_ver.h
new file mode 100644
index 0000000..d1ada25
--- /dev/null
+++ b/openssl/crypto/des/des_ver.h
@@ -0,0 +1,71 @@
+/* crypto/des/des_ver.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/e_os2.h>
+
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+/* The following macros make sure the names are different from libdes names */
+#define DES_version OSSL_DES_version
+#define libdes_version OSSL_libdes_version
+
+OPENSSL_EXTERN const char OSSL_DES_version[];	/* SSLeay version string */
+OPENSSL_EXTERN const char OSSL_libdes_version[];	/* old libdes version string */
diff --git a/openssl/crypto/des/dess.cpp b/openssl/crypto/des/dess.cpp
new file mode 100644
index 0000000..5549bab
--- /dev/null
+++ b/openssl/crypto/des/dess.cpp
@@ -0,0 +1,67 @@
+//
+// gettsc.inl
+//
+// gives access to the Pentium's (secret) cycle counter
+//
+// This software was written by Leonard Janke (janke@unixg.ubc.ca)
+// in 1996-7 and is entered, by him, into the public domain.
+
+#if defined(__WATCOMC__)
+void GetTSC(unsigned long&);
+#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
+#elif defined(__GNUC__)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  asm volatile(".byte 15, 49\n\t"
+	       : "=eax" (tsc)
+	       :
+	       : "%edx", "%eax");
+}
+#elif defined(_MSC_VER)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  unsigned long a;
+  __asm _emit 0fh
+  __asm _emit 31h
+  __asm mov a, eax;
+  tsc=a;
+}
+#endif      
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/des.h>
+
+void main(int argc,char *argv[])
+	{
+	des_key_schedule key;
+	unsigned long s1,s2,e1,e2;
+	unsigned long data[2];
+	int i,j;
+
+	for (j=0; j<6; j++)
+		{
+		for (i=0; i<1000; i++) /**/
+			{
+			des_encrypt1(&data[0],key,1);
+			GetTSC(s1);
+			des_encrypt1(&data[0],key,1);
+			des_encrypt1(&data[0],key,1);
+			des_encrypt1(&data[0],key,1);
+			GetTSC(e1);
+			GetTSC(s2);
+			des_encrypt1(&data[0],key,1);
+			des_encrypt1(&data[0],key,1);
+			des_encrypt1(&data[0],key,1);
+			des_encrypt1(&data[0],key,1);
+			GetTSC(e2);
+			des_encrypt1(&data[0],key,1);
+			}
+
+		printf("des %d %d (%d)\n",
+			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
+		}
+	}
+
diff --git a/openssl/crypto/des/destest.c b/openssl/crypto/des/destest.c
new file mode 100644
index 0000000..64b92a3
--- /dev/null
+++ b/openssl/crypto/des/destest.c
@@ -0,0 +1,952 @@
+/* crypto/des/destest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <openssl/e_os2.h>
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_WINDOWS)
+#ifndef OPENSSL_SYS_MSDOS
+#define OPENSSL_SYS_MSDOS
+#endif
+#endif
+
+#ifndef OPENSSL_SYS_MSDOS
+#if !defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_VMS_DECC)
+#include OPENSSL_UNISTD
+#endif
+#else
+#include <io.h>
+#endif
+#include <string.h>
+
+#ifdef OPENSSL_NO_DES
+int main(int argc, char *argv[])
+{
+    printf("No DES support\n");
+    return(0);
+}
+#else
+#include <openssl/des.h>
+
+#define crypt(c,s) (DES_crypt((c),(s)))
+
+/* tisk tisk - the test keys don't all have odd parity :-( */
+/* test data */
+#define NUM_TESTS 34
+static unsigned char key_data[NUM_TESTS][8]={
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+	{0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10},
+	{0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57},
+	{0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E},
+	{0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86},
+	{0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E},
+	{0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6},
+	{0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE},
+	{0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6},
+	{0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE},
+	{0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16},
+	{0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F},
+	{0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46},
+	{0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E},
+	{0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76},
+	{0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07},
+	{0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F},
+	{0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7},
+	{0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF},
+	{0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6},
+	{0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF},
+	{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
+	{0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
+	{0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}};
+
+static unsigned char plain_data[NUM_TESTS][8]={
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+	{0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
+	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42},
+	{0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA},
+	{0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72},
+	{0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A},
+	{0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2},
+	{0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A},
+	{0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2},
+	{0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A},
+	{0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02},
+	{0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A},
+	{0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32},
+	{0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA},
+	{0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62},
+	{0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2},
+	{0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA},
+	{0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92},
+	{0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A},
+	{0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2},
+	{0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
+
+static unsigned char cipher_data[NUM_TESTS][8]={
+	{0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
+	{0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58},
+	{0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B},
+	{0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33},
+	{0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D},
+	{0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD},
+	{0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
+	{0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4},
+	{0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B},
+	{0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71},
+	{0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A},
+	{0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A},
+	{0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95},
+	{0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B},
+	{0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09},
+	{0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A},
+	{0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F},
+	{0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88},
+	{0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77},
+	{0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A},
+	{0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56},
+	{0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56},
+	{0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56},
+	{0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC},
+	{0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A},
+	{0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41},
+	{0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93},
+	{0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00},
+	{0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06},
+	{0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7},
+	{0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51},
+	{0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE},
+	{0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D},
+	{0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}};
+
+static unsigned char cipher_ecb2[NUM_TESTS-1][8]={
+	{0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E},
+	{0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16},
+	{0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27},
+	{0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6},
+	{0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25},
+	{0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A},
+	{0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74},
+	{0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6},
+	{0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67},
+	{0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10},
+	{0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85},
+	{0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA},
+	{0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3},
+	{0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3},
+	{0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A},
+	{0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69},
+	{0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1},
+	{0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7},
+	{0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F},
+	{0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87},
+	{0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A},
+	{0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE},
+	{0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3},
+	{0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD},
+	{0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84},
+	{0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85},
+	{0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC},
+	{0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89},
+	{0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E},
+	{0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89},
+	{0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7},
+	{0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8},
+	{0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}};
+
+static unsigned char cbc_key [8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char cbc2_key[8]={0xf1,0xe0,0xd3,0xc2,0xb5,0xa4,0x97,0x86};
+static unsigned char cbc3_key[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
+static unsigned char cbc_iv  [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
+/* Changed the following text constant to binary so it will work on ebcdic
+ * machines :-) */
+/* static char cbc_data[40]="7654321 Now is the time for \0001"; */
+static unsigned char cbc_data[40]={
+	0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x20,
+	0x4E,0x6F,0x77,0x20,0x69,0x73,0x20,0x74,
+	0x68,0x65,0x20,0x74,0x69,0x6D,0x65,0x20,
+	0x66,0x6F,0x72,0x20,0x00,0x31,0x00,0x00,
+	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	};
+
+static unsigned char cbc_ok[32]={
+	0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
+	0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb,
+	0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68,
+	0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
+
+#ifdef SCREW_THE_PARITY
+#error "SCREW_THE_PARITY is not ment to be defined."
+#error "Original vectors are preserved for reference only."
+static unsigned char cbc2_key[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87};
+static unsigned char xcbc_ok[32]={
+	0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48,
+	0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD,
+	0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76,
+	0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2,
+	};
+#else
+static unsigned char xcbc_ok[32]={
+	0x84,0x6B,0x29,0x14,0x85,0x1E,0x9A,0x29,
+	0x54,0x73,0x2F,0x8A,0xA0,0xA6,0x11,0xC1,
+	0x15,0xCD,0xC2,0xD7,0x95,0x1B,0x10,0x53,
+	0xA6,0x3C,0x5E,0x03,0xB2,0x1A,0xA3,0xC4,
+	};
+#endif
+
+static unsigned char cbc3_ok[32]={
+	0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0,
+	0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC,
+	0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4,
+	0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75};
+
+static unsigned char pcbc_ok[32]={
+	0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
+	0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15,
+	0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f,
+	0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88};
+
+static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
+static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
+static unsigned char plain[24]=
+	{
+	0x4e,0x6f,0x77,0x20,0x69,0x73,
+	0x20,0x74,0x68,0x65,0x20,0x74,
+	0x69,0x6d,0x65,0x20,0x66,0x6f,
+	0x72,0x20,0x61,0x6c,0x6c,0x20
+	};
+static unsigned char cfb_cipher8[24]= {
+	0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8,
+	0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 };
+static unsigned char cfb_cipher16[24]={
+	0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70,
+	0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B };
+static unsigned char cfb_cipher32[24]={
+	0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD,
+	0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 };
+static unsigned char cfb_cipher48[24]={
+	0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85,
+	0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F };
+static unsigned char cfb_cipher64[24]={
+	0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B,
+	0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 };
+
+static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
+static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8];
+static unsigned char ofb_cipher[24]=
+	{
+	0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51,
+	0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f,
+	0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3
+	};
+
+#if 0
+static DES_LONG cbc_cksum_ret=0xB462FEF7L;
+#else
+static DES_LONG cbc_cksum_ret=0xF7FE62B4L;
+#endif
+static unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
+
+static char *pt(unsigned char *p);
+static int cfb_test(int bits, unsigned char *cfb_cipher);
+static int cfb64_test(unsigned char *cfb_cipher);
+static int ede_cfb64_test(unsigned char *cfb_cipher);
+int main(int argc, char *argv[])
+	{
+	int j,err=0;
+	unsigned int i;
+	des_cblock in,out,outin,iv3,iv2;
+	des_key_schedule ks,ks2,ks3;
+	unsigned char cbc_in[40];
+	unsigned char cbc_out[40];
+	DES_LONG cs;
+	unsigned char cret[8];
+#ifdef _CRAY
+        struct {
+            int a:32;
+            int b:32;
+        } lqret[2];
+#else
+        DES_LONG lqret[4];
+#endif
+	int num;
+	char *str;
+
+#ifndef OPENSSL_NO_DESCBCM
+	printf("Doing cbcm\n");
+	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
+		{
+		printf("Key error %d\n",j);
+		err=1;
+		}
+	if ((j=DES_set_key_checked(&cbc2_key,&ks2)) != 0)
+		{
+		printf("Key error %d\n",j);
+		err=1;
+		}
+	if ((j=DES_set_key_checked(&cbc3_key,&ks3)) != 0)
+		{
+		printf("Key error %d\n",j);
+		err=1;
+		}
+	memset(cbc_out,0,40);
+	memset(cbc_in,0,40);
+	i=strlen((char *)cbc_data)+1;
+	/* i=((i+7)/8)*8; */
+	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+	memset(iv2,'\0',sizeof iv2);
+
+	DES_ede3_cbcm_encrypt(cbc_data,cbc_out,16L,&ks,&ks2,&ks3,&iv3,&iv2,
+			      DES_ENCRYPT);
+	DES_ede3_cbcm_encrypt(&cbc_data[16],&cbc_out[16],i-16,&ks,&ks2,&ks3,
+			      &iv3,&iv2,DES_ENCRYPT);
+	/*	if (memcmp(cbc_out,cbc3_ok,
+		(unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
+		{
+		printf("des_ede3_cbc_encrypt encrypt error\n");
+		err=1;
+		}
+	*/
+	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+	memset(iv2,'\0',sizeof iv2);
+	DES_ede3_cbcm_encrypt(cbc_out,cbc_in,i,&ks,&ks2,&ks3,&iv3,&iv2,DES_DECRYPT);
+	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
+		{
+		unsigned int n;
+
+		printf("des_ede3_cbcm_encrypt decrypt error\n");
+		for(n=0 ; n < i ; ++n)
+		    printf(" %02x",cbc_data[n]);
+		printf("\n");
+		for(n=0 ; n < i ; ++n)
+		    printf(" %02x",cbc_in[n]);
+		printf("\n");
+		err=1;
+		}
+#endif
+
+	printf("Doing ecb\n");
+	for (i=0; i<NUM_TESTS; i++)
+		{
+		DES_set_key_unchecked(&key_data[i],&ks);
+		memcpy(in,plain_data[i],8);
+		memset(out,0,8);
+		memset(outin,0,8);
+		des_ecb_encrypt(&in,&out,ks,DES_ENCRYPT);
+		des_ecb_encrypt(&out,&outin,ks,DES_DECRYPT);
+
+		if (memcmp(out,cipher_data[i],8) != 0)
+			{
+			printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
+				i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]),
+				pt(out));
+			err=1;
+			}
+		if (memcmp(in,outin,8) != 0)
+			{
+			printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
+				i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
+			err=1;
+			}
+		}
+
+#ifndef LIBDES_LIT
+	printf("Doing ede ecb\n");
+	for (i=0; i<(NUM_TESTS-2); i++)
+		{
+		DES_set_key_unchecked(&key_data[i],&ks);
+		DES_set_key_unchecked(&key_data[i+1],&ks2);
+		DES_set_key_unchecked(&key_data[i+2],&ks3);
+		memcpy(in,plain_data[i],8);
+		memset(out,0,8);
+		memset(outin,0,8);
+		des_ecb2_encrypt(&in,&out,ks,ks2,DES_ENCRYPT);
+		des_ecb2_encrypt(&out,&outin,ks,ks2,DES_DECRYPT);
+
+		if (memcmp(out,cipher_ecb2[i],8) != 0)
+			{
+			printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
+				i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]),
+				pt(out));
+			err=1;
+			}
+		if (memcmp(in,outin,8) != 0)
+			{
+			printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
+				i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
+			err=1;
+			}
+		}
+#endif
+
+	printf("Doing cbc\n");
+	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
+		{
+		printf("Key error %d\n",j);
+		err=1;
+		}
+	memset(cbc_out,0,40);
+	memset(cbc_in,0,40);
+	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+	des_ncbc_encrypt(cbc_data,cbc_out,strlen((char *)cbc_data)+1,ks,
+			 &iv3,DES_ENCRYPT);
+	if (memcmp(cbc_out,cbc_ok,32) != 0)
+		{
+		printf("cbc_encrypt encrypt error\n");
+		err=1;
+		}
+
+	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+	des_ncbc_encrypt(cbc_out,cbc_in,strlen((char *)cbc_data)+1,ks,
+			 &iv3,DES_DECRYPT);
+	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)) != 0)
+		{
+		printf("cbc_encrypt decrypt error\n");
+		err=1;
+		}
+
+#ifndef LIBDES_LIT
+	printf("Doing desx cbc\n");
+	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
+		{
+		printf("Key error %d\n",j);
+		err=1;
+		}
+	memset(cbc_out,0,40);
+	memset(cbc_in,0,40);
+	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+	des_xcbc_encrypt(cbc_data,cbc_out,strlen((char *)cbc_data)+1,ks,
+			 &iv3,&cbc2_key,&cbc3_key, DES_ENCRYPT);
+	if (memcmp(cbc_out,xcbc_ok,32) != 0)
+		{
+		printf("des_xcbc_encrypt encrypt error\n");
+		err=1;
+		}
+	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+	des_xcbc_encrypt(cbc_out,cbc_in,strlen((char *)cbc_data)+1,ks,
+			 &iv3,&cbc2_key,&cbc3_key, DES_DECRYPT);
+	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
+		{
+		printf("des_xcbc_encrypt decrypt error\n");
+		err=1;
+		}
+#endif
+
+	printf("Doing ede cbc\n");
+	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
+		{
+		printf("Key error %d\n",j);
+		err=1;
+		}
+	if ((j=DES_set_key_checked(&cbc2_key,&ks2)) != 0)
+		{
+		printf("Key error %d\n",j);
+		err=1;
+		}
+	if ((j=DES_set_key_checked(&cbc3_key,&ks3)) != 0)
+		{
+		printf("Key error %d\n",j);
+		err=1;
+		}
+	memset(cbc_out,0,40);
+	memset(cbc_in,0,40);
+	i=strlen((char *)cbc_data)+1;
+	/* i=((i+7)/8)*8; */
+	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+
+	des_ede3_cbc_encrypt(cbc_data,cbc_out,16L,ks,ks2,ks3,&iv3,
+			     DES_ENCRYPT);
+	des_ede3_cbc_encrypt(&(cbc_data[16]),&(cbc_out[16]),i-16,ks,ks2,ks3,
+			     &iv3,DES_ENCRYPT);
+	if (memcmp(cbc_out,cbc3_ok,
+		(unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
+		{
+		unsigned int n;
+
+		printf("des_ede3_cbc_encrypt encrypt error\n");
+		for(n=0 ; n < i ; ++n)
+		    printf(" %02x",cbc_out[n]);
+		printf("\n");
+		for(n=0 ; n < i ; ++n)
+		    printf(" %02x",cbc3_ok[n]);
+		printf("\n");
+		err=1;
+		}
+
+	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+	des_ede3_cbc_encrypt(cbc_out,cbc_in,i,ks,ks2,ks3,&iv3,DES_DECRYPT);
+	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
+		{
+		unsigned int n;
+
+		printf("des_ede3_cbc_encrypt decrypt error\n");
+		for(n=0 ; n < i ; ++n)
+		    printf(" %02x",cbc_data[n]);
+		printf("\n");
+		for(n=0 ; n < i ; ++n)
+		    printf(" %02x",cbc_in[n]);
+		printf("\n");
+		err=1;
+		}
+
+#ifndef LIBDES_LIT
+	printf("Doing pcbc\n");
+	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
+		{
+		printf("Key error %d\n",j);
+		err=1;
+		}
+	memset(cbc_out,0,40);
+	memset(cbc_in,0,40);
+	des_pcbc_encrypt(cbc_data,cbc_out,strlen((char *)cbc_data)+1,ks,
+			 &cbc_iv,DES_ENCRYPT);
+	if (memcmp(cbc_out,pcbc_ok,32) != 0)
+		{
+		printf("pcbc_encrypt encrypt error\n");
+		err=1;
+		}
+	des_pcbc_encrypt(cbc_out,cbc_in,strlen((char *)cbc_data)+1,ks,&cbc_iv,
+			 DES_DECRYPT);
+	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
+		{
+		printf("pcbc_encrypt decrypt error\n");
+		err=1;
+		}
+
+	printf("Doing ");
+	printf("cfb8 ");
+	err+=cfb_test(8,cfb_cipher8);
+	printf("cfb16 ");
+	err+=cfb_test(16,cfb_cipher16);
+	printf("cfb32 ");
+	err+=cfb_test(32,cfb_cipher32);
+	printf("cfb48 ");
+	err+=cfb_test(48,cfb_cipher48);
+	printf("cfb64 ");
+	err+=cfb_test(64,cfb_cipher64);
+
+	printf("cfb64() ");
+	err+=cfb64_test(cfb_cipher64);
+
+	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+	for (i=0; i<sizeof(plain); i++)
+		des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]),
+			8,1,ks,&cfb_tmp,DES_ENCRYPT);
+	if (memcmp(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0)
+		{
+		printf("cfb_encrypt small encrypt error\n");
+		err=1;
+		}
+
+	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+	for (i=0; i<sizeof(plain); i++)
+		des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]),
+			8,1,ks,&cfb_tmp,DES_DECRYPT);
+	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+		{
+		printf("cfb_encrypt small decrypt error\n");
+		err=1;
+		}
+
+	printf("ede_cfb64() ");
+	err+=ede_cfb64_test(cfb_cipher64);
+
+	printf("done\n");
+
+	printf("Doing ofb\n");
+	DES_set_key_checked(&ofb_key,&ks);
+	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+	des_ofb_encrypt(plain,ofb_buf1,64,sizeof(plain)/8,ks,&ofb_tmp);
+	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
+		{
+		printf("ofb_encrypt encrypt error\n");
+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
+ofb_buf1[8+0], ofb_buf1[8+1], ofb_buf1[8+2], ofb_buf1[8+3],
+ofb_buf1[8+4], ofb_buf1[8+5], ofb_buf1[8+6], ofb_buf1[8+7]);
+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
+ofb_buf1[8+0], ofb_cipher[8+1], ofb_cipher[8+2], ofb_cipher[8+3],
+ofb_buf1[8+4], ofb_cipher[8+5], ofb_cipher[8+6], ofb_cipher[8+7]);
+		err=1;
+		}
+	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+	des_ofb_encrypt(ofb_buf1,ofb_buf2,64,sizeof(ofb_buf1)/8,ks,&ofb_tmp);
+	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
+		{
+		printf("ofb_encrypt decrypt error\n");
+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
+ofb_buf2[8+0], ofb_buf2[8+1], ofb_buf2[8+2], ofb_buf2[8+3],
+ofb_buf2[8+4], ofb_buf2[8+5], ofb_buf2[8+6], ofb_buf2[8+7]);
+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
+plain[8+0], plain[8+1], plain[8+2], plain[8+3],
+plain[8+4], plain[8+5], plain[8+6], plain[8+7]);
+		err=1;
+		}
+
+	printf("Doing ofb64\n");
+	DES_set_key_checked(&ofb_key,&ks);
+	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+	memset(ofb_buf1,0,sizeof(ofb_buf1));
+	memset(ofb_buf2,0,sizeof(ofb_buf1));
+	num=0;
+	for (i=0; i<sizeof(plain); i++)
+		{
+		des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,&ofb_tmp,
+				  &num);
+		}
+	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
+		{
+		printf("ofb64_encrypt encrypt error\n");
+		err=1;
+		}
+	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+	num=0;
+	des_ofb64_encrypt(ofb_buf1,ofb_buf2,sizeof(ofb_buf1),ks,&ofb_tmp,
+			  &num);
+	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
+		{
+		printf("ofb64_encrypt decrypt error\n");
+		err=1;
+		}
+
+	printf("Doing ede_ofb64\n");
+	DES_set_key_checked(&ofb_key,&ks);
+	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+	memset(ofb_buf1,0,sizeof(ofb_buf1));
+	memset(ofb_buf2,0,sizeof(ofb_buf1));
+	num=0;
+	for (i=0; i<sizeof(plain); i++)
+		{
+		des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,
+				       ks,&ofb_tmp,&num);
+		}
+	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
+		{
+		printf("ede_ofb64_encrypt encrypt error\n");
+		err=1;
+		}
+	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+	num=0;
+	des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,sizeof(ofb_buf1),ks,ks,ks,
+			       &ofb_tmp,&num);
+	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
+		{
+		printf("ede_ofb64_encrypt decrypt error\n");
+		err=1;
+		}
+
+	printf("Doing cbc_cksum\n");
+	DES_set_key_checked(&cbc_key,&ks);
+	cs=des_cbc_cksum(cbc_data,&cret,strlen((char *)cbc_data),ks,&cbc_iv);
+	if (cs != cbc_cksum_ret)
+		{
+		printf("bad return value (%08lX), should be %08lX\n",
+			(unsigned long)cs,(unsigned long)cbc_cksum_ret);
+		err=1;
+		}
+	if (memcmp(cret,cbc_cksum_data,8) != 0)
+		{
+		printf("bad cbc_cksum block returned\n");
+		err=1;
+		}
+
+	printf("Doing quad_cksum\n");
+	cs=des_quad_cksum(cbc_data,(des_cblock *)lqret,
+		(long)strlen((char *)cbc_data),2,(des_cblock *)cbc_iv);
+	if (cs != 0x70d7a63aL)
+		{
+		printf("quad_cksum error, ret %08lx should be 70d7a63a\n",
+			(unsigned long)cs);
+		err=1;
+		}
+#ifdef _CRAY
+	if (lqret[0].a != 0x327eba8dL)
+		{
+		printf("quad_cksum error, out[0] %08lx is not %08lx\n",
+			(unsigned long)lqret[0].a,0x327eba8dUL);
+		err=1;
+		}
+	if (lqret[0].b != 0x201a49ccL)
+		{
+		printf("quad_cksum error, out[1] %08lx is not %08lx\n",
+			(unsigned long)lqret[0].b,0x201a49ccUL);
+		err=1;
+		}
+	if (lqret[1].a != 0x70d7a63aL)
+		{
+		printf("quad_cksum error, out[2] %08lx is not %08lx\n",
+			(unsigned long)lqret[1].a,0x70d7a63aUL);
+		err=1;
+		}
+	if (lqret[1].b != 0x501c2c26L)
+		{
+		printf("quad_cksum error, out[3] %08lx is not %08lx\n",
+			(unsigned long)lqret[1].b,0x501c2c26UL);
+		err=1;
+		}
+#else
+	if (lqret[0] != 0x327eba8dL)
+		{
+		printf("quad_cksum error, out[0] %08lx is not %08lx\n",
+			(unsigned long)lqret[0],0x327eba8dUL);
+		err=1;
+		}
+	if (lqret[1] != 0x201a49ccL)
+		{
+		printf("quad_cksum error, out[1] %08lx is not %08lx\n",
+			(unsigned long)lqret[1],0x201a49ccUL);
+		err=1;
+		}
+	if (lqret[2] != 0x70d7a63aL)
+		{
+		printf("quad_cksum error, out[2] %08lx is not %08lx\n",
+			(unsigned long)lqret[2],0x70d7a63aUL);
+		err=1;
+		}
+	if (lqret[3] != 0x501c2c26L)
+		{
+		printf("quad_cksum error, out[3] %08lx is not %08lx\n",
+			(unsigned long)lqret[3],0x501c2c26UL);
+		err=1;
+		}
+#endif
+#endif
+
+	printf("input word alignment test");
+	for (i=0; i<4; i++)
+		{
+		printf(" %d",i);
+		des_ncbc_encrypt(&(cbc_out[i]),cbc_in,
+				 strlen((char *)cbc_data)+1,ks,
+				 &cbc_iv,DES_ENCRYPT);
+		}
+	printf("\noutput word alignment test");
+	for (i=0; i<4; i++)
+		{
+		printf(" %d",i);
+		des_ncbc_encrypt(cbc_out,&(cbc_in[i]),
+				 strlen((char *)cbc_data)+1,ks,
+				 &cbc_iv,DES_ENCRYPT);
+		}
+	printf("\n");
+	printf("fast crypt test ");
+	str=crypt("testing","ef");
+	if (strcmp("efGnQx2725bI2",str) != 0)
+		{
+		printf("fast crypt error, %s should be efGnQx2725bI2\n",str);
+		err=1;
+		}
+	str=crypt("bca76;23","yA");
+	if (strcmp("yA1Rp/1hZXIJk",str) != 0)
+		{
+		printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str);
+		err=1;
+		}
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
+	printf("\n");
+	return(err);
+	}
+
+static char *pt(unsigned char *p)
+	{
+	static char bufs[10][20];
+	static int bnum=0;
+	char *ret;
+	int i;
+	static char *f="0123456789ABCDEF";
+
+	ret= &(bufs[bnum++][0]);
+	bnum%=10;
+	for (i=0; i<8; i++)
+		{
+		ret[i*2]=f[(p[i]>>4)&0xf];
+		ret[i*2+1]=f[p[i]&0xf];
+		}
+	ret[16]='\0';
+	return(ret);
+	}
+
+#ifndef LIBDES_LIT
+
+static int cfb_test(int bits, unsigned char *cfb_cipher)
+	{
+	des_key_schedule ks;
+	int i,err=0;
+
+	DES_set_key_checked(&cfb_key,&ks);
+	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+	des_cfb_encrypt(plain,cfb_buf1,bits,sizeof(plain),ks,&cfb_tmp,
+			DES_ENCRYPT);
+	if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
+		{
+		err=1;
+		printf("cfb_encrypt encrypt error\n");
+		for (i=0; i<24; i+=8)
+			printf("%s\n",pt(&(cfb_buf1[i])));
+		}
+	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+	des_cfb_encrypt(cfb_buf1,cfb_buf2,bits,sizeof(plain),ks,&cfb_tmp,
+			DES_DECRYPT);
+	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+		{
+		err=1;
+		printf("cfb_encrypt decrypt error\n");
+		for (i=0; i<24; i+=8)
+			printf("%s\n",pt(&(cfb_buf1[i])));
+		}
+	return(err);
+	}
+
+static int cfb64_test(unsigned char *cfb_cipher)
+	{
+	des_key_schedule ks;
+	int err=0,i,n;
+
+	DES_set_key_checked(&cfb_key,&ks);
+	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+	n=0;
+	des_cfb64_encrypt(plain,cfb_buf1,12,ks,&cfb_tmp,&n,DES_ENCRYPT);
+	des_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),sizeof(plain)-12,ks,
+			  &cfb_tmp,&n,DES_ENCRYPT);
+	if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
+		{
+		err=1;
+		printf("cfb_encrypt encrypt error\n");
+		for (i=0; i<24; i+=8)
+			printf("%s\n",pt(&(cfb_buf1[i])));
+		}
+	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+	n=0;
+	des_cfb64_encrypt(cfb_buf1,cfb_buf2,17,ks,&cfb_tmp,&n,DES_DECRYPT);
+	des_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
+			  sizeof(plain)-17,ks,&cfb_tmp,&n,DES_DECRYPT);
+	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+		{
+		err=1;
+		printf("cfb_encrypt decrypt error\n");
+		for (i=0; i<24; i+=8)
+			printf("%s\n",pt(&(cfb_buf2[i])));
+		}
+	return(err);
+	}
+
+static int ede_cfb64_test(unsigned char *cfb_cipher)
+	{
+	des_key_schedule ks;
+	int err=0,i,n;
+
+	DES_set_key_checked(&cfb_key,&ks);
+	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+	n=0;
+	des_ede3_cfb64_encrypt(plain,cfb_buf1,12,ks,ks,ks,&cfb_tmp,&n,
+			       DES_ENCRYPT);
+	des_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
+			       sizeof(plain)-12,ks,ks,ks,
+			       &cfb_tmp,&n,DES_ENCRYPT);
+	if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
+		{
+		err=1;
+		printf("ede_cfb_encrypt encrypt error\n");
+		for (i=0; i<24; i+=8)
+			printf("%s\n",pt(&(cfb_buf1[i])));
+		}
+	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+	n=0;
+	des_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,ks,ks,
+			       &cfb_tmp,&n,DES_DECRYPT);
+	des_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
+			       sizeof(plain)-17,ks,ks,ks,
+			       &cfb_tmp,&n,DES_DECRYPT);
+	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+		{
+		err=1;
+		printf("ede_cfb_encrypt decrypt error\n");
+		for (i=0; i<24; i+=8)
+			printf("%s\n",pt(&(cfb_buf2[i])));
+		}
+	return(err);
+	}
+
+#endif
+#endif
diff --git a/openssl/crypto/des/ecb3_enc.c b/openssl/crypto/des/ecb3_enc.c
new file mode 100644
index 0000000..c3437bc
--- /dev/null
+++ b/openssl/crypto/des/ecb3_enc.c
@@ -0,0 +1,83 @@
+/* crypto/des/ecb3_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
+		      DES_key_schedule *ks1, DES_key_schedule *ks2,
+		      DES_key_schedule *ks3,
+	     int enc)
+	{
+	register DES_LONG l0,l1;
+	DES_LONG ll[2];
+	const unsigned char *in = &(*input)[0];
+	unsigned char *out = &(*output)[0];
+
+	c2l(in,l0);
+	c2l(in,l1);
+	ll[0]=l0;
+	ll[1]=l1;
+	if (enc)
+		DES_encrypt3(ll,ks1,ks2,ks3);
+	else
+		DES_decrypt3(ll,ks1,ks2,ks3);
+	l0=ll[0];
+	l1=ll[1];
+	l2c(l0,out);
+	l2c(l1,out);
+	}
diff --git a/openssl/crypto/des/ecb_enc.c b/openssl/crypto/des/ecb_enc.c
new file mode 100644
index 0000000..0684e76
--- /dev/null
+++ b/openssl/crypto/des/ecb_enc.c
@@ -0,0 +1,122 @@
+/* crypto/des/ecb_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+#include "des_ver.h"
+#include <openssl/opensslv.h>
+#include <openssl/bio.h>
+
+OPENSSL_GLOBAL const char libdes_version[]="libdes" OPENSSL_VERSION_PTEXT;
+OPENSSL_GLOBAL const char DES_version[]="DES" OPENSSL_VERSION_PTEXT;
+
+const char *DES_options(void)
+	{
+	static int init=1;
+	static char buf[32];
+
+	if (init)
+		{
+		const char *ptr,*unroll,*risc,*size;
+
+#ifdef DES_PTR
+		ptr="ptr";
+#else
+		ptr="idx";
+#endif
+#if defined(DES_RISC1) || defined(DES_RISC2)
+#ifdef DES_RISC1
+		risc="risc1";
+#endif
+#ifdef DES_RISC2
+		risc="risc2";
+#endif
+#else
+		risc="cisc";
+#endif
+#ifdef DES_UNROLL
+		unroll="16";
+#else
+		unroll="2";
+#endif
+		if (sizeof(DES_LONG) != sizeof(long))
+			size="int";
+		else
+			size="long";
+		BIO_snprintf(buf,sizeof buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,
+			     size);
+		init=0;
+		}
+	return(buf);
+	}
+		
+
+void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output,
+		     DES_key_schedule *ks, int enc)
+	{
+	register DES_LONG l;
+	DES_LONG ll[2];
+	const unsigned char *in = &(*input)[0];
+	unsigned char *out = &(*output)[0];
+
+	c2l(in,l); ll[0]=l;
+	c2l(in,l); ll[1]=l;
+	DES_encrypt1(ll,ks,enc);
+	l=ll[0]; l2c(l,out);
+	l=ll[1]; l2c(l,out);
+	l=ll[0]=ll[1]=0;
+	}
diff --git a/openssl/crypto/des/ede_cbcm_enc.c b/openssl/crypto/des/ede_cbcm_enc.c
new file mode 100644
index 0000000..adfcb75
--- /dev/null
+++ b/openssl/crypto/des/ede_cbcm_enc.c
@@ -0,0 +1,199 @@
+/* ede_cbcm_enc.c */
+/* Written by Ben Laurie <ben@algroup.co.uk> for the OpenSSL
+ * project 13 Feb 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+
+This is an implementation of Triple DES Cipher Block Chaining with Output
+Feedback Masking, by Coppersmith, Johnson and Matyas, (IBM and Certicom).
+
+Note that there is a known attack on this by Biham and Knudsen but it takes
+a lot of work:
+
+http://www.cs.technion.ac.il/users/wwwb/cgi-bin/tr-get.cgi/1998/CS/CS0928.ps.gz
+
+*/
+
+#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_DESCBCM is defined */
+
+#ifndef OPENSSL_NO_DESCBCM
+#include "des_locl.h"
+
+void DES_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out,
+	     long length, DES_key_schedule *ks1, DES_key_schedule *ks2,
+	     DES_key_schedule *ks3, DES_cblock *ivec1, DES_cblock *ivec2,
+	     int enc)
+    {
+    register DES_LONG tin0,tin1;
+    register DES_LONG tout0,tout1,xor0,xor1,m0,m1;
+    register long l=length;
+    DES_LONG tin[2];
+    unsigned char *iv1,*iv2;
+
+    iv1 = &(*ivec1)[0];
+    iv2 = &(*ivec2)[0];
+
+    if (enc)
+	{
+	c2l(iv1,m0);
+	c2l(iv1,m1);
+	c2l(iv2,tout0);
+	c2l(iv2,tout1);
+	for (l-=8; l>=-7; l-=8)
+	    {
+	    tin[0]=m0;
+	    tin[1]=m1;
+	    DES_encrypt1(tin,ks3,1);
+	    m0=tin[0];
+	    m1=tin[1];
+
+	    if(l < 0)
+		{
+		c2ln(in,tin0,tin1,l+8);
+		}
+	    else
+		{
+		c2l(in,tin0);
+		c2l(in,tin1);
+		}
+	    tin0^=tout0;
+	    tin1^=tout1;
+
+	    tin[0]=tin0;
+	    tin[1]=tin1;
+	    DES_encrypt1(tin,ks1,1);
+	    tin[0]^=m0;
+	    tin[1]^=m1;
+	    DES_encrypt1(tin,ks2,0);
+	    tin[0]^=m0;
+	    tin[1]^=m1;
+	    DES_encrypt1(tin,ks1,1);
+	    tout0=tin[0];
+	    tout1=tin[1];
+
+	    l2c(tout0,out);
+	    l2c(tout1,out);
+	    }
+	iv1=&(*ivec1)[0];
+	l2c(m0,iv1);
+	l2c(m1,iv1);
+
+	iv2=&(*ivec2)[0];
+	l2c(tout0,iv2);
+	l2c(tout1,iv2);
+	}
+    else
+	{
+	register DES_LONG t0,t1;
+
+	c2l(iv1,m0);
+	c2l(iv1,m1);
+	c2l(iv2,xor0);
+	c2l(iv2,xor1);
+	for (l-=8; l>=-7; l-=8)
+	    {
+	    tin[0]=m0;
+	    tin[1]=m1;
+	    DES_encrypt1(tin,ks3,1);
+	    m0=tin[0];
+	    m1=tin[1];
+
+	    c2l(in,tin0);
+	    c2l(in,tin1);
+
+	    t0=tin0;
+	    t1=tin1;
+
+	    tin[0]=tin0;
+	    tin[1]=tin1;
+	    DES_encrypt1(tin,ks1,0);
+	    tin[0]^=m0;
+	    tin[1]^=m1;
+	    DES_encrypt1(tin,ks2,1);
+	    tin[0]^=m0;
+	    tin[1]^=m1;
+	    DES_encrypt1(tin,ks1,0);
+	    tout0=tin[0];
+	    tout1=tin[1];
+
+	    tout0^=xor0;
+	    tout1^=xor1;
+	    if(l < 0)
+		{
+		l2cn(tout0,tout1,out,l+8);
+		}
+	    else
+		{
+		l2c(tout0,out);
+		l2c(tout1,out);
+		}
+	    xor0=t0;
+	    xor1=t1;
+	    }
+
+	iv1=&(*ivec1)[0];
+	l2c(m0,iv1);
+	l2c(m1,iv1);
+
+	iv2=&(*ivec2)[0];
+	l2c(xor0,iv2);
+	l2c(xor1,iv2);
+	}
+    tin0=tin1=tout0=tout1=xor0=xor1=0;
+    tin[0]=tin[1]=0;
+    }
+#endif
diff --git a/openssl/crypto/des/enc_read.c b/openssl/crypto/des/enc_read.c
new file mode 100644
index 0000000..edb6620
--- /dev/null
+++ b/openssl/crypto/des/enc_read.c
@@ -0,0 +1,240 @@
+/* crypto/des/enc_read.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include "des_locl.h"
+
+/* This has some uglies in it but it works - even over sockets. */
+/*extern int errno;*/
+OPENSSL_IMPLEMENT_GLOBAL(int,DES_rw_mode,DES_PCBC_MODE)
+
+
+/*
+ * WARNINGS:
+ *
+ *  -  The data format used by DES_enc_write() and DES_enc_read()
+ *     has a cryptographic weakness: When asked to write more
+ *     than MAXWRITE bytes, DES_enc_write will split the data
+ *     into several chunks that are all encrypted
+ *     using the same IV.  So don't use these functions unless you
+ *     are sure you know what you do (in which case you might
+ *     not want to use them anyway).
+ *
+ *  -  This code cannot handle non-blocking sockets.
+ *
+ *  -  This function uses an internal state and thus cannot be
+ *     used on multiple files.
+ */
+
+
+int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched,
+		 DES_cblock *iv)
+	{
+#if defined(OPENSSL_NO_POSIX_IO)
+	return(0);
+#else
+	/* data to be unencrypted */
+	int net_num=0;
+	static unsigned char *net=NULL;
+	/* extra unencrypted data 
+	 * for when a block of 100 comes in but is des_read one byte at
+	 * a time. */
+	static unsigned char *unnet=NULL;
+	static int unnet_start=0;
+	static int unnet_left=0;
+	static unsigned char *tmpbuf=NULL;
+	int i;
+	long num=0,rnum;
+	unsigned char *p;
+
+	if (tmpbuf == NULL)
+		{
+		tmpbuf=OPENSSL_malloc(BSIZE);
+		if (tmpbuf == NULL) return(-1);
+		}
+	if (net == NULL)
+		{
+		net=OPENSSL_malloc(BSIZE);
+		if (net == NULL) return(-1);
+		}
+	if (unnet == NULL)
+		{
+		unnet=OPENSSL_malloc(BSIZE);
+		if (unnet == NULL) return(-1);
+		}
+	/* left over data from last decrypt */
+	if (unnet_left != 0)
+		{
+		if (unnet_left < len)
+			{
+			/* we still still need more data but will return
+			 * with the number of bytes we have - should always
+			 * check the return value */
+			memcpy(buf,&(unnet[unnet_start]),
+			       unnet_left);
+			/* eay 26/08/92 I had the next 2 lines
+			 * reversed :-( */
+			i=unnet_left;
+			unnet_start=unnet_left=0;
+			}
+		else
+			{
+			memcpy(buf,&(unnet[unnet_start]),len);
+			unnet_start+=len;
+			unnet_left-=len;
+			i=len;
+			}
+		return(i);
+		}
+
+	/* We need to get more data. */
+	if (len > MAXWRITE) len=MAXWRITE;
+
+	/* first - get the length */
+	while (net_num < HDRSIZE) 
+		{
+#ifndef OPENSSL_SYS_WIN32
+		i=read(fd,(void *)&(net[net_num]),HDRSIZE-net_num);
+#else
+		i=_read(fd,(void *)&(net[net_num]),HDRSIZE-net_num);
+#endif
+#ifdef EINTR
+		if ((i == -1) && (errno == EINTR)) continue;
+#endif
+		if (i <= 0) return(0);
+		net_num+=i;
+		}
+
+	/* we now have at net_num bytes in net */
+	p=net;
+	/* num=0;  */
+	n2l(p,num);
+	/* num should be rounded up to the next group of eight
+	 * we make sure that we have read a multiple of 8 bytes from the net.
+	 */
+	if ((num > MAXWRITE) || (num < 0)) /* error */
+		return(-1);
+	rnum=(num < 8)?8:((num+7)/8*8);
+
+	net_num=0;
+	while (net_num < rnum)
+		{
+#ifndef OPENSSL_SYS_WIN32
+		i=read(fd,(void *)&(net[net_num]),rnum-net_num);
+#else
+		i=_read(fd,(void *)&(net[net_num]),rnum-net_num);
+#endif
+#ifdef EINTR
+		if ((i == -1) && (errno == EINTR)) continue;
+#endif
+		if (i <= 0) return(0);
+		net_num+=i;
+		}
+
+	/* Check if there will be data left over. */
+	if (len < num)
+		{
+		if (DES_rw_mode & DES_PCBC_MODE)
+			DES_pcbc_encrypt(net,unnet,num,sched,iv,DES_DECRYPT);
+		else
+			DES_cbc_encrypt(net,unnet,num,sched,iv,DES_DECRYPT);
+		memcpy(buf,unnet,len);
+		unnet_start=len;
+		unnet_left=num-len;
+
+		/* The following line is done because we return num
+		 * as the number of bytes read. */
+		num=len;
+		}
+	else
+		{
+		/* >output is a multiple of 8 byes, if len < rnum
+		 * >we must be careful.  The user must be aware that this
+		 * >routine will write more bytes than he asked for.
+		 * >The length of the buffer must be correct.
+		 * FIXED - Should be ok now 18-9-90 - eay */
+		if (len < rnum)
+			{
+
+			if (DES_rw_mode & DES_PCBC_MODE)
+				DES_pcbc_encrypt(net,tmpbuf,num,sched,iv,
+						 DES_DECRYPT);
+			else
+				DES_cbc_encrypt(net,tmpbuf,num,sched,iv,
+						DES_DECRYPT);
+
+			/* eay 26/08/92 fix a bug that returned more
+			 * bytes than you asked for (returned len bytes :-( */
+			memcpy(buf,tmpbuf,num);
+			}
+		else
+			{
+			if (DES_rw_mode & DES_PCBC_MODE)
+				DES_pcbc_encrypt(net,buf,num,sched,iv,
+						 DES_DECRYPT);
+			else
+				DES_cbc_encrypt(net,buf,num,sched,iv,
+						DES_DECRYPT);
+			}
+		}
+	return num;
+#endif /* OPENSSL_NO_POSIX_IO */
+	}
+
diff --git a/openssl/crypto/des/enc_writ.c b/openssl/crypto/des/enc_writ.c
new file mode 100644
index 0000000..2353ac1
--- /dev/null
+++ b/openssl/crypto/des/enc_writ.c
@@ -0,0 +1,179 @@
+/* crypto/des/enc_writ.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <errno.h>
+#include <time.h>
+#include <stdio.h>
+#include "cryptlib.h"
+#include "des_locl.h"
+#include <openssl/rand.h>
+
+/*
+ * WARNINGS:
+ *
+ *  -  The data format used by DES_enc_write() and DES_enc_read()
+ *     has a cryptographic weakness: When asked to write more
+ *     than MAXWRITE bytes, DES_enc_write will split the data
+ *     into several chunks that are all encrypted
+ *     using the same IV.  So don't use these functions unless you
+ *     are sure you know what you do (in which case you might
+ *     not want to use them anyway).
+ *
+ *  -  This code cannot handle non-blocking sockets.
+ */
+
+int DES_enc_write(int fd, const void *_buf, int len,
+		  DES_key_schedule *sched, DES_cblock *iv)
+	{
+#if defined(OPENSSL_NO_POSIX_IO)
+	return (-1);
+#else
+#ifdef _LIBC
+	extern unsigned long time();
+	extern int write();
+#endif
+	const unsigned char *buf=_buf;
+	long rnum;
+	int i,j,k,outnum;
+	static unsigned char *outbuf=NULL;
+	unsigned char shortbuf[8];
+	unsigned char *p;
+	const unsigned char *cp;
+	static int start=1;
+
+	if (outbuf == NULL)
+		{
+		outbuf=OPENSSL_malloc(BSIZE+HDRSIZE);
+		if (outbuf == NULL) return(-1);
+		}
+	/* If we are sending less than 8 bytes, the same char will look
+	 * the same if we don't pad it out with random bytes */
+	if (start)
+		{
+		start=0;
+		}
+
+	/* lets recurse if we want to send the data in small chunks */
+	if (len > MAXWRITE)
+		{
+		j=0;
+		for (i=0; i<len; i+=k)
+			{
+			k=DES_enc_write(fd,&(buf[i]),
+				((len-i) > MAXWRITE)?MAXWRITE:(len-i),sched,iv);
+			if (k < 0)
+				return(k);
+			else
+				j+=k;
+			}
+		return(j);
+		}
+
+	/* write length first */
+	p=outbuf;
+	l2n(len,p);
+
+	/* pad short strings */
+	if (len < 8)
+		{
+		cp=shortbuf;
+		memcpy(shortbuf,buf,len);
+		RAND_pseudo_bytes(shortbuf+len, 8-len);
+		rnum=8;
+		}
+	else
+		{
+		cp=buf;
+		rnum=((len+7)/8*8); /* round up to nearest eight */
+		}
+
+	if (DES_rw_mode & DES_PCBC_MODE)
+		DES_pcbc_encrypt(cp,&(outbuf[HDRSIZE]),(len<8)?8:len,sched,iv,
+				 DES_ENCRYPT); 
+	else
+		DES_cbc_encrypt(cp,&(outbuf[HDRSIZE]),(len<8)?8:len,sched,iv,
+				DES_ENCRYPT); 
+
+	/* output */
+	outnum=rnum+HDRSIZE;
+
+	for (j=0; j<outnum; j+=i)
+		{
+		/* eay 26/08/92 I was not doing writing from where we
+		 * got up to. */
+#ifndef _WIN32
+		i=write(fd,(void *)&(outbuf[j]),outnum-j);
+#else
+		i=_write(fd,(void *)&(outbuf[j]),outnum-j);
+#endif
+		if (i == -1)
+			{
+#ifdef EINTR
+			if (errno == EINTR)
+				i=0;
+			else
+#endif
+			        /* This is really a bad error - very bad
+				 * It will stuff-up both ends. */
+				return(-1);
+			}
+		}
+
+	return(len);
+#endif /* OPENSSL_NO_POSIX_IO */
+	}
diff --git a/openssl/crypto/des/fcrypt.c b/openssl/crypto/des/fcrypt.c
new file mode 100644
index 0000000..ccbdff2
--- /dev/null
+++ b/openssl/crypto/des/fcrypt.c
@@ -0,0 +1,170 @@
+/* NOCW */
+#include <stdio.h>
+#ifdef _OSD_POSIX
+#ifndef CHARSET_EBCDIC
+#define CHARSET_EBCDIC 1
+#endif
+#endif
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+/* This version of crypt has been developed from my MIT compatible
+ * DES library.
+ * Eric Young (eay@cryptsoft.com)
+ */
+
+/* Modification by Jens Kupferschmidt (Cu)
+ * I have included directive PARA for shared memory computers.
+ * I have included a directive LONGCRYPT to using this routine to cipher
+ * passwords with more then 8 bytes like HP-UX 10.x it used. The MAXPLEN
+ * definition is the maximum of length of password and can changed. I have
+ * defined 24.
+ */
+
+#include "des_locl.h"
+
+/* Added more values to handle illegal salt values the way normal
+ * crypt() implementations do.  The patch was sent by 
+ * Bjorn Gronvall <bg@sics.se>
+ */
+static unsigned const char con_salt[128]={
+0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
+0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,
+0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
+0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,
+0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
+0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01,
+0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
+0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A,
+0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,
+0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,
+0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,
+0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24,
+0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,
+0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,
+0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,
+0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,
+};
+
+static unsigned const char cov_2char[64]={
+0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
+0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
+0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
+0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
+0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
+0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
+0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
+0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
+};
+
+char *DES_crypt(const char *buf, const char *salt)
+	{
+	static char buff[14];
+
+#ifndef CHARSET_EBCDIC
+	return(DES_fcrypt(buf,salt,buff));
+#else
+	char e_salt[2+1];
+	char e_buf[32+1];	/* replace 32 by 8 ? */
+	char *ret;
+
+	/* Copy at most 2 chars of salt */
+	if ((e_salt[0] = salt[0]) != '\0')
+	    e_salt[1] = salt[1];
+
+	/* Copy at most 32 chars of password */
+	strncpy (e_buf, buf, sizeof(e_buf));
+
+	/* Make sure we have a delimiter */
+	e_salt[sizeof(e_salt)-1] = e_buf[sizeof(e_buf)-1] = '\0';
+
+	/* Convert the e_salt to ASCII, as that's what DES_fcrypt works on */
+	ebcdic2ascii(e_salt, e_salt, sizeof e_salt);
+
+	/* Convert the cleartext password to ASCII */
+	ebcdic2ascii(e_buf, e_buf, sizeof e_buf);
+
+	/* Encrypt it (from/to ASCII) */
+	ret = DES_fcrypt(e_buf,e_salt,buff);
+
+	/* Convert the result back to EBCDIC */
+	ascii2ebcdic(ret, ret, strlen(ret));
+	
+	return ret;
+#endif
+	}
+
+
+char *DES_fcrypt(const char *buf, const char *salt, char *ret)
+	{
+	unsigned int i,j,x,y;
+	DES_LONG Eswap0,Eswap1;
+	DES_LONG out[2],ll;
+	DES_cblock key;
+	DES_key_schedule ks;
+	unsigned char bb[9];
+	unsigned char *b=bb;
+	unsigned char c,u;
+
+	/* eay 25/08/92
+	 * If you call crypt("pwd","*") as often happens when you
+	 * have * as the pwd field in /etc/passwd, the function
+	 * returns *\0XXXXXXXXX
+	 * The \0 makes the string look like * so the pwd "*" would
+	 * crypt to "*".  This was found when replacing the crypt in
+	 * our shared libraries.  People found that the disabled
+	 * accounts effectively had no passwd :-(. */
+#ifndef CHARSET_EBCDIC
+	x=ret[0]=((salt[0] == '\0')?'A':salt[0]);
+	Eswap0=con_salt[x]<<2;
+	x=ret[1]=((salt[1] == '\0')?'A':salt[1]);
+	Eswap1=con_salt[x]<<6;
+#else
+	x=ret[0]=((salt[0] == '\0')?os_toascii['A']:salt[0]);
+	Eswap0=con_salt[x]<<2;
+	x=ret[1]=((salt[1] == '\0')?os_toascii['A']:salt[1]);
+	Eswap1=con_salt[x]<<6;
+#endif
+
+/* EAY
+r=strlen(buf);
+r=(r+7)/8;
+*/
+	for (i=0; i<8; i++)
+		{
+		c= *(buf++);
+		if (!c) break;
+		key[i]=(c<<1);
+		}
+	for (; i<8; i++)
+		key[i]=0;
+
+	DES_set_key_unchecked(&key,&ks);
+	fcrypt_body(&(out[0]),&ks,Eswap0,Eswap1);
+
+	ll=out[0]; l2c(ll,b);
+	ll=out[1]; l2c(ll,b);
+	y=0;
+	u=0x80;
+	bb[8]=0;
+	for (i=2; i<13; i++)
+		{
+		c=0;
+		for (j=0; j<6; j++)
+			{
+			c<<=1;
+			if (bb[y] & u) c|=1;
+			u>>=1;
+			if (!u)
+				{
+				y++;
+				u=0x80;
+				}
+			}
+		ret[i]=cov_2char[c];
+		}
+	ret[13]='\0';
+	return(ret);
+	}
+
diff --git a/openssl/crypto/des/fcrypt_b.c b/openssl/crypto/des/fcrypt_b.c
new file mode 100644
index 0000000..8822816
--- /dev/null
+++ b/openssl/crypto/des/fcrypt_b.c
@@ -0,0 +1,143 @@
+/* crypto/des/fcrypt_b.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+
+/* This version of crypt has been developed from my MIT compatible
+ * DES library.
+ * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
+ * Eric Young (eay@cryptsoft.com)
+ */
+
+#define DES_FCRYPT
+#include "des_locl.h"
+#undef DES_FCRYPT
+
+#undef PERM_OP
+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+	(b)^=(t),\
+	(a)^=((t)<<(n)))
+
+#undef HPERM_OP
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+	(a)=(a)^(t)^(t>>(16-(n))))\
+
+void fcrypt_body(DES_LONG *out, DES_key_schedule *ks, DES_LONG Eswap0,
+		 DES_LONG Eswap1)
+	{
+	register DES_LONG l,r,t,u;
+#ifdef DES_PTR
+	register const unsigned char *des_SP=(const unsigned char *)DES_SPtrans;
+#endif
+	register DES_LONG *s;
+	register int j;
+	register DES_LONG E0,E1;
+
+	l=0;
+	r=0;
+
+	s=(DES_LONG *)ks;
+	E0=Eswap0;
+	E1=Eswap1;
+
+	for (j=0; j<25; j++)
+		{
+#ifndef DES_UNROLL
+		register int i;
+
+		for (i=0; i<32; i+=4)
+			{
+			D_ENCRYPT(l,r,i+0); /*  1 */
+			D_ENCRYPT(r,l,i+2); /*  2 */
+			}
+#else
+		D_ENCRYPT(l,r, 0); /*  1 */
+		D_ENCRYPT(r,l, 2); /*  2 */
+		D_ENCRYPT(l,r, 4); /*  3 */
+		D_ENCRYPT(r,l, 6); /*  4 */
+		D_ENCRYPT(l,r, 8); /*  5 */
+		D_ENCRYPT(r,l,10); /*  6 */
+		D_ENCRYPT(l,r,12); /*  7 */
+		D_ENCRYPT(r,l,14); /*  8 */
+		D_ENCRYPT(l,r,16); /*  9 */
+		D_ENCRYPT(r,l,18); /*  10 */
+		D_ENCRYPT(l,r,20); /*  11 */
+		D_ENCRYPT(r,l,22); /*  12 */
+		D_ENCRYPT(l,r,24); /*  13 */
+		D_ENCRYPT(r,l,26); /*  14 */
+		D_ENCRYPT(l,r,28); /*  15 */
+		D_ENCRYPT(r,l,30); /*  16 */
+#endif
+
+		t=l;
+		l=r;
+		r=t;
+		}
+	l=ROTATE(l,3)&0xffffffffL;
+	r=ROTATE(r,3)&0xffffffffL;
+
+	PERM_OP(l,r,t, 1,0x55555555L);
+	PERM_OP(r,l,t, 8,0x00ff00ffL);
+	PERM_OP(l,r,t, 2,0x33333333L);
+	PERM_OP(r,l,t,16,0x0000ffffL);
+	PERM_OP(l,r,t, 4,0x0f0f0f0fL);
+
+	out[0]=r;
+	out[1]=l;
+	}
+
diff --git a/openssl/crypto/des/makefile.bc b/openssl/crypto/des/makefile.bc
new file mode 100644
index 0000000..1fe6d49
--- /dev/null
+++ b/openssl/crypto/des/makefile.bc
@@ -0,0 +1,50 @@
+#
+# Origional BC Makefile from Teun <Teun.Nijssen@kub.nl>
+#
+#
+CC      = bcc
+TLIB    = tlib /0 /C
+# note: the -3 flag produces code for 386, 486, Pentium etc; omit it for 286s
+OPTIMIZE= -3 -O2
+#WINDOWS= -W
+CFLAGS  = -c -ml -d $(OPTIMIZE) $(WINDOWS) -DMSDOS
+LFLAGS  = -ml $(WINDOWS)
+
+.c.obj:
+	$(CC) $(CFLAGS) $*.c
+
+.obj.exe:
+	$(CC) $(LFLAGS) -e$*.exe $*.obj libdes.lib  
+
+all: $(LIB) destest.exe rpw.exe des.exe speed.exe
+
+# "make clean": use a directory containing only libdes .exe and .obj files...
+clean:
+	del *.exe
+	del *.obj
+	del libdes.lib
+	del libdes.rsp
+
+OBJS=   cbc_cksm.obj cbc_enc.obj  ecb_enc.obj  pcbc_enc.obj \
+	qud_cksm.obj rand_key.obj set_key.obj  str2key.obj \
+	enc_read.obj enc_writ.obj fcrypt.obj   cfb_enc.obj \
+	ecb3_enc.obj ofb_enc.obj  cbc3_enc.obj read_pwd.obj\
+	cfb64enc.obj ofb64enc.obj ede_enc.obj  cfb64ede.obj\
+	ofb64ede.obj supp.obj
+
+LIB=    libdes.lib
+
+$(LIB): $(OBJS)
+	del $(LIB)
+	makersp "+%s &\n" &&|
+	$(OBJS)
+|       >libdes.rsp
+	$(TLIB) libdes.lib @libdes.rsp,nul
+	del libdes.rsp
+
+destest.exe: destest.obj libdes.lib
+rpw.exe:     rpw.obj libdes.lib
+speed.exe:   speed.obj libdes.lib
+des.exe:     des.obj libdes.lib
+
+
diff --git a/openssl/crypto/des/ncbc_enc.c b/openssl/crypto/des/ncbc_enc.c
new file mode 100644
index 0000000..fda23d5
--- /dev/null
+++ b/openssl/crypto/des/ncbc_enc.c
@@ -0,0 +1,148 @@
+/* crypto/des/ncbc_enc.c */
+/*
+ * #included by:
+ *    cbc_enc.c  (DES_cbc_encrypt)
+ *    des_enc.c  (DES_ncbc_encrypt)
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+#ifdef CBC_ENC_C__DONT_UPDATE_IV
+void DES_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+		     DES_key_schedule *_schedule, DES_cblock *ivec, int enc)
+#else
+void DES_ncbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+		     DES_key_schedule *_schedule, DES_cblock *ivec, int enc)
+#endif
+	{
+	register DES_LONG tin0,tin1;
+	register DES_LONG tout0,tout1,xor0,xor1;
+	register long l=length;
+	DES_LONG tin[2];
+	unsigned char *iv;
+
+	iv = &(*ivec)[0];
+
+	if (enc)
+		{
+		c2l(iv,tout0);
+		c2l(iv,tout1);
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0);
+			c2l(in,tin1);
+			tin0^=tout0; tin[0]=tin0;
+			tin1^=tout1; tin[1]=tin1;
+			DES_encrypt1((DES_LONG *)tin,_schedule,DES_ENCRYPT);
+			tout0=tin[0]; l2c(tout0,out);
+			tout1=tin[1]; l2c(tout1,out);
+			}
+		if (l != -8)
+			{
+			c2ln(in,tin0,tin1,l+8);
+			tin0^=tout0; tin[0]=tin0;
+			tin1^=tout1; tin[1]=tin1;
+			DES_encrypt1((DES_LONG *)tin,_schedule,DES_ENCRYPT);
+			tout0=tin[0]; l2c(tout0,out);
+			tout1=tin[1]; l2c(tout1,out);
+			}
+#ifndef CBC_ENC_C__DONT_UPDATE_IV
+		iv = &(*ivec)[0];
+		l2c(tout0,iv);
+		l2c(tout1,iv);
+#endif
+		}
+	else
+		{
+		c2l(iv,xor0);
+		c2l(iv,xor1);
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0); tin[0]=tin0;
+			c2l(in,tin1); tin[1]=tin1;
+			DES_encrypt1((DES_LONG *)tin,_schedule,DES_DECRYPT);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2c(tout0,out);
+			l2c(tout1,out);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		if (l != -8)
+			{
+			c2l(in,tin0); tin[0]=tin0;
+			c2l(in,tin1); tin[1]=tin1;
+			DES_encrypt1((DES_LONG *)tin,_schedule,DES_DECRYPT);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2cn(tout0,tout1,out,l+8);
+#ifndef CBC_ENC_C__DONT_UPDATE_IV
+			xor0=tin0;
+			xor1=tin1;
+#endif
+			}
+#ifndef CBC_ENC_C__DONT_UPDATE_IV 
+		iv = &(*ivec)[0];
+		l2c(xor0,iv);
+		l2c(xor1,iv);
+#endif
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	tin[0]=tin[1]=0;
+	}
diff --git a/openssl/crypto/des/ofb64ede.c b/openssl/crypto/des/ofb64ede.c
new file mode 100644
index 0000000..26bbf9a
--- /dev/null
+++ b/openssl/crypto/des/ofb64ede.c
@@ -0,0 +1,125 @@
+/* crypto/des/ofb64ede.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+/* The input and output encrypted as though 64bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+void DES_ede3_ofb64_encrypt(register const unsigned char *in,
+			    register unsigned char *out, long length,
+			    DES_key_schedule *k1, DES_key_schedule *k2,
+			    DES_key_schedule *k3, DES_cblock *ivec,
+			    int *num)
+	{
+	register DES_LONG v0,v1;
+	register int n= *num;
+	register long l=length;
+	DES_cblock d;
+	register char *dp;
+	DES_LONG ti[2];
+	unsigned char *iv;
+	int save=0;
+
+	iv = &(*ivec)[0];
+	c2l(iv,v0);
+	c2l(iv,v1);
+	ti[0]=v0;
+	ti[1]=v1;
+	dp=(char *)d;
+	l2c(v0,dp);
+	l2c(v1,dp);
+	while (l--)
+		{
+		if (n == 0)
+			{
+			/* ti[0]=v0; */
+			/* ti[1]=v1; */
+			DES_encrypt3(ti,k1,k2,k3);
+			v0=ti[0];
+			v1=ti[1];
+
+			dp=(char *)d;
+			l2c(v0,dp);
+			l2c(v1,dp);
+			save++;
+			}
+		*(out++)= *(in++)^d[n];
+		n=(n+1)&0x07;
+		}
+	if (save)
+		{
+/*		v0=ti[0];
+		v1=ti[1];*/
+		iv = &(*ivec)[0];
+		l2c(v0,iv);
+		l2c(v1,iv);
+		}
+	v0=v1=ti[0]=ti[1]=0;
+	*num=n;
+	}
+
+#ifdef undef /* MACRO */
+void DES_ede2_ofb64_encrypt(register unsigned char *in,
+	     register unsigned char *out, long length, DES_key_schedule k1,
+	     DES_key_schedule k2, DES_cblock (*ivec), int *num)
+	{
+	DES_ede3_ofb64_encrypt(in, out, length, k1,k2,k1, ivec, num);
+	}
+#endif
diff --git a/openssl/crypto/des/ofb64enc.c b/openssl/crypto/des/ofb64enc.c
new file mode 100644
index 0000000..8ca3d49
--- /dev/null
+++ b/openssl/crypto/des/ofb64enc.c
@@ -0,0 +1,110 @@
+/* crypto/des/ofb64enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+/* The input and output encrypted as though 64bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+void DES_ofb64_encrypt(register const unsigned char *in,
+		       register unsigned char *out, long length,
+		       DES_key_schedule *schedule, DES_cblock *ivec, int *num)
+	{
+	register DES_LONG v0,v1,t;
+	register int n= *num;
+	register long l=length;
+	DES_cblock d;
+	register unsigned char *dp;
+	DES_LONG ti[2];
+	unsigned char *iv;
+	int save=0;
+
+	iv = &(*ivec)[0];
+	c2l(iv,v0);
+	c2l(iv,v1);
+	ti[0]=v0;
+	ti[1]=v1;
+	dp=d;
+	l2c(v0,dp);
+	l2c(v1,dp);
+	while (l--)
+		{
+		if (n == 0)
+			{
+			DES_encrypt1(ti,schedule,DES_ENCRYPT);
+			dp=d;
+			t=ti[0]; l2c(t,dp);
+			t=ti[1]; l2c(t,dp);
+			save++;
+			}
+		*(out++)= *(in++)^d[n];
+		n=(n+1)&0x07;
+		}
+	if (save)
+		{
+		v0=ti[0];
+		v1=ti[1];
+		iv = &(*ivec)[0];
+		l2c(v0,iv);
+		l2c(v1,iv);
+		}
+	t=v0=v1=ti[0]=ti[1]=0;
+	*num=n;
+	}
+
diff --git a/openssl/crypto/des/ofb_enc.c b/openssl/crypto/des/ofb_enc.c
new file mode 100644
index 0000000..e887a3c
--- /dev/null
+++ b/openssl/crypto/des/ofb_enc.c
@@ -0,0 +1,135 @@
+/* crypto/des/ofb_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+/* The input and output are loaded in multiples of 8 bits.
+ * What this means is that if you hame numbits=12 and length=2
+ * the first 12 bits will be retrieved from the first byte and half
+ * the second.  The second 12 bits will come from the 3rd and half the 4th
+ * byte.
+ */
+void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
+		     long length, DES_key_schedule *schedule,
+		     DES_cblock *ivec)
+	{
+	register DES_LONG d0,d1,vv0,vv1,v0,v1,n=(numbits+7)/8;
+	register DES_LONG mask0,mask1;
+	register long l=length;
+	register int num=numbits;
+	DES_LONG ti[2];
+	unsigned char *iv;
+
+	if (num > 64) return;
+	if (num > 32)
+		{
+		mask0=0xffffffffL;
+		if (num >= 64)
+			mask1=mask0;
+		else
+			mask1=(1L<<(num-32))-1;
+		}
+	else
+		{
+		if (num == 32)
+			mask0=0xffffffffL;
+		else
+			mask0=(1L<<num)-1;
+		mask1=0x00000000L;
+		}
+
+	iv = &(*ivec)[0];
+	c2l(iv,v0);
+	c2l(iv,v1);
+	ti[0]=v0;
+	ti[1]=v1;
+	while (l-- > 0)
+		{
+		ti[0]=v0;
+		ti[1]=v1;
+		DES_encrypt1((DES_LONG *)ti,schedule,DES_ENCRYPT);
+		vv0=ti[0];
+		vv1=ti[1];
+		c2ln(in,d0,d1,n);
+		in+=n;
+		d0=(d0^vv0)&mask0;
+		d1=(d1^vv1)&mask1;
+		l2cn(d0,d1,out,n);
+		out+=n;
+
+		if (num == 32)
+			{ v0=v1; v1=vv0; }
+		else if (num == 64)
+				{ v0=vv0; v1=vv1; }
+		else if (num > 32) /* && num != 64 */
+			{
+			v0=((v1>>(num-32))|(vv0<<(64-num)))&0xffffffffL;
+			v1=((vv0>>(num-32))|(vv1<<(64-num)))&0xffffffffL;
+			}
+		else /* num < 32 */
+			{
+			v0=((v0>>num)|(v1<<(32-num)))&0xffffffffL;
+			v1=((v1>>num)|(vv0<<(32-num)))&0xffffffffL;
+			}
+		}
+	iv = &(*ivec)[0];
+	l2c(v0,iv);
+	l2c(v1,iv);
+	v0=v1=d0=d1=ti[0]=ti[1]=vv0=vv1=0;
+	}
+
diff --git a/openssl/crypto/des/options.txt b/openssl/crypto/des/options.txt
new file mode 100644
index 0000000..6e2b50f
--- /dev/null
+++ b/openssl/crypto/des/options.txt
@@ -0,0 +1,39 @@
+Note that the UNROLL option makes the 'inner' des loop unroll all 16 rounds
+instead of the default 4.
+RISC1 and RISC2 are 2 alternatives for the inner loop and
+PTR means to use pointers arithmatic instead of arrays.
+
+FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - assembler		577,000 4620k/s
+IRIX 6.2 - R10000 195mhz - cc (-O3 -n32) - UNROLL RISC2 PTR	496,000 3968k/s
+solaris 2.5.1 usparc 167mhz?? - SC4.0 - UNROLL RISC1 PTR [1]	459,400 3672k/s
+FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - UNROLL RISC1	433,000 3468k/s
+solaris 2.5.1 usparc 167mhz?? - gcc 2.7.2 - UNROLL 		380,000 3041k/s
+linux - pentium 100mhz - gcc 2.7.0 - assembler			281,000 2250k/s
+NT 4.0 - pentium 100mhz - VC 4.2 - assembler			281,000 2250k/s
+AIX 4.1? - PPC604 100mhz - cc - UNROLL 				275,000 2200k/s
+IRIX 5.3 - R4400 200mhz - gcc 2.6.3 - UNROLL RISC2 PTR		235,300 1882k/s
+IRIX 5.3 - R4400 200mhz - cc - UNROLL RISC2 PTR			233,700 1869k/s
+NT 4.0 - pentium 100mhz - VC 4.2 - UNROLL RISC1 PTR		191,000 1528k/s
+DEC Alpha 165mhz??  - cc - RISC2 PTR [2]			181,000 1448k/s
+linux - pentium 100mhz - gcc 2.7.0 - UNROLL RISC1 PTR		158,500 1268k/s
+HPUX 10 - 9000/887 - cc - UNROLL [3]	 			148,000	1190k/s
+solaris 2.5.1 - sparc 10 50mhz - gcc 2.7.2 - UNROLL		123,600  989k/s
+IRIX 5.3 - R4000 100mhz - cc - UNROLL RISC2 PTR			101,000  808k/s
+DGUX - 88100 50mhz(?) - gcc 2.6.3 - UNROLL			 81,000  648k/s
+solaris 2.4 486 50mhz - gcc 2.6.3 - assembler			 65,000  522k/s
+HPUX 10 - 9000/887 - k&r cc (default compiler) - UNROLL PTR	 76,000	 608k/s
+solaris 2.4 486 50mhz - gcc 2.6.3 - UNROLL RISC2		 43,500  344k/s
+AIX - old slow one :-) - cc -					 39,000  312k/s
+
+Notes.
+[1] For the ultra sparc, SunC 4.0 
+    cc -xtarget=ultra -xarch=v8plus -Xa -xO5, running 'des_opts'
+    gives a speed of 344,000 des/s while 'speed' gives 459,000 des/s.
+    I'll record the higher since it is coming from the library but it
+    is all rather weird.
+[2] Similar to the ultra sparc ([1]), 181,000 for 'des_opts' vs 175,000.
+[3] I was unable to get access to this machine when it was not heavily loaded.
+    As such, my timing program was never able to get more that %30 of the CPU.
+    This would cause the program to give much lower speed numbers because
+    it would be 'fighting' to stay in the cache with the other CPU burning
+    processes.
diff --git a/openssl/crypto/des/pcbc_enc.c b/openssl/crypto/des/pcbc_enc.c
new file mode 100644
index 0000000..17a40f9
--- /dev/null
+++ b/openssl/crypto/des/pcbc_enc.c
@@ -0,0 +1,123 @@
+/* crypto/des/pcbc_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output,
+		      long length, DES_key_schedule *schedule,
+		      DES_cblock *ivec, int enc)
+	{
+	register DES_LONG sin0,sin1,xor0,xor1,tout0,tout1;
+	DES_LONG tin[2];
+	const unsigned char *in;
+	unsigned char *out,*iv;
+
+	in=input;
+	out=output;
+	iv = &(*ivec)[0];
+
+	if (enc)
+		{
+		c2l(iv,xor0);
+		c2l(iv,xor1);
+		for (; length>0; length-=8)
+			{
+			if (length >= 8)
+				{
+				c2l(in,sin0);
+				c2l(in,sin1);
+				}
+			else
+				c2ln(in,sin0,sin1,length);
+			tin[0]=sin0^xor0;
+			tin[1]=sin1^xor1;
+			DES_encrypt1((DES_LONG *)tin,schedule,DES_ENCRYPT);
+			tout0=tin[0];
+			tout1=tin[1];
+			xor0=sin0^tout0;
+			xor1=sin1^tout1;
+			l2c(tout0,out);
+			l2c(tout1,out);
+			}
+		}
+	else
+		{
+		c2l(iv,xor0); c2l(iv,xor1);
+		for (; length>0; length-=8)
+			{
+			c2l(in,sin0);
+			c2l(in,sin1);
+			tin[0]=sin0;
+			tin[1]=sin1;
+			DES_encrypt1((DES_LONG *)tin,schedule,DES_DECRYPT);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			if (length >= 8)
+				{
+				l2c(tout0,out);
+				l2c(tout1,out);
+				}
+			else
+				l2cn(tout0,tout1,out,length);
+			xor0=tout0^sin0;
+			xor1=tout1^sin1;
+			}
+		}
+	tin[0]=tin[1]=0;
+	sin0=sin1=xor0=xor1=tout0=tout1=0;
+	}
diff --git a/openssl/crypto/des/qud_cksm.c b/openssl/crypto/des/qud_cksm.c
new file mode 100644
index 0000000..dac2012
--- /dev/null
+++ b/openssl/crypto/des/qud_cksm.c
@@ -0,0 +1,139 @@
+/* crypto/des/qud_cksm.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* From "Message Authentication"  R.R. Jueneman, S.M. Matyas, C.H. Meyer
+ * IEEE Communications Magazine Sept 1985 Vol. 23 No. 9 p 29-40
+ * This module in only based on the code in this paper and is
+ * almost definitely not the same as the MIT implementation.
+ */
+#include "des_locl.h"
+
+/* bug fix for dos - 7/6/91 - Larry hughes@logos.ucs.indiana.edu */
+#define Q_B0(a)	(((DES_LONG)(a)))
+#define Q_B1(a)	(((DES_LONG)(a))<<8)
+#define Q_B2(a)	(((DES_LONG)(a))<<16)
+#define Q_B3(a)	(((DES_LONG)(a))<<24)
+
+/* used to scramble things a bit */
+/* Got the value MIT uses via brute force :-) 2/10/90 eay */
+#define NOISE	((DES_LONG)83653421L)
+
+DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[],
+	     long length, int out_count, DES_cblock *seed)
+	{
+	DES_LONG z0,z1,t0,t1;
+	int i;
+	long l;
+	const unsigned char *cp;
+#ifdef _CRAY
+	struct lp_st { int a:32; int b:32; } *lp;
+#else
+	DES_LONG *lp;
+#endif
+
+	if (out_count < 1) out_count=1;
+#ifdef _CRAY
+	lp = (struct lp_st *) &(output[0])[0];
+#else
+	lp = (DES_LONG *) &(output[0])[0];
+#endif
+
+	z0=Q_B0((*seed)[0])|Q_B1((*seed)[1])|Q_B2((*seed)[2])|Q_B3((*seed)[3]);
+	z1=Q_B0((*seed)[4])|Q_B1((*seed)[5])|Q_B2((*seed)[6])|Q_B3((*seed)[7]);
+
+	for (i=0; ((i<4)&&(i<out_count)); i++)
+		{
+		cp=input;
+		l=length;
+		while (l > 0)
+			{
+			if (l > 1)
+				{
+				t0= (DES_LONG)(*(cp++));
+				t0|=(DES_LONG)Q_B1(*(cp++));
+				l--;
+				}
+			else
+				t0= (DES_LONG)(*(cp++));
+			l--;
+			/* add */
+			t0+=z0;
+			t0&=0xffffffffL;
+			t1=z1;
+			/* square, well sort of square */
+			z0=((((t0*t0)&0xffffffffL)+((t1*t1)&0xffffffffL))
+				&0xffffffffL)%0x7fffffffL; 
+			z1=((t0*((t1+NOISE)&0xffffffffL))&0xffffffffL)%0x7fffffffL;
+			}
+		if (lp != NULL)
+			{
+			/* The MIT library assumes that the checksum is
+			 * composed of 2*out_count 32 bit ints */
+#ifdef _CRAY
+			(*lp).a = z0;
+			(*lp).b = z1;
+			lp++;
+#else
+			*lp++ = z0;
+			*lp++ = z1;
+#endif
+			}
+		}
+	return(z0);
+	}
+
diff --git a/openssl/crypto/des/rand_key.c b/openssl/crypto/des/rand_key.c
new file mode 100644
index 0000000..2398165
--- /dev/null
+++ b/openssl/crypto/des/rand_key.c
@@ -0,0 +1,68 @@
+/* crypto/des/rand_key.c */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/des.h>
+#include <openssl/rand.h>
+
+int DES_random_key(DES_cblock *ret)
+	{
+	do
+		{
+		if (RAND_bytes((unsigned char *)ret, sizeof(DES_cblock)) != 1)
+			return (0);
+		} while (DES_is_weak_key(ret));
+	DES_set_odd_parity(ret);
+	return (1);
+	}
diff --git a/openssl/crypto/des/read2pwd.c b/openssl/crypto/des/read2pwd.c
new file mode 100644
index 0000000..ee6969f
--- /dev/null
+++ b/openssl/crypto/des/read2pwd.c
@@ -0,0 +1,140 @@
+/* crypto/des/read2pwd.c */
+/* ====================================================================
+ * Copyright (c) 2001-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <string.h>
+#include <openssl/des.h>
+#include <openssl/ui.h>
+#include <openssl/crypto.h>
+
+int DES_read_password(DES_cblock *key, const char *prompt, int verify)
+	{
+	int ok;
+	char buf[BUFSIZ],buff[BUFSIZ];
+
+	if ((ok=UI_UTIL_read_pw(buf,buff,BUFSIZ,prompt,verify)) == 0)
+		DES_string_to_key(buf,key);
+	OPENSSL_cleanse(buf,BUFSIZ);
+	OPENSSL_cleanse(buff,BUFSIZ);
+	return(ok);
+	}
+
+int DES_read_2passwords(DES_cblock *key1, DES_cblock *key2, const char *prompt,
+	     int verify)
+	{
+	int ok;
+	char buf[BUFSIZ],buff[BUFSIZ];
+
+	if ((ok=UI_UTIL_read_pw(buf,buff,BUFSIZ,prompt,verify)) == 0)
+		DES_string_to_2keys(buf,key1,key2);
+	OPENSSL_cleanse(buf,BUFSIZ);
+	OPENSSL_cleanse(buff,BUFSIZ);
+	return(ok);
+	}
diff --git a/openssl/crypto/des/read_pwd.c b/openssl/crypto/des/read_pwd.c
new file mode 100644
index 0000000..ce5fa00
--- /dev/null
+++ b/openssl/crypto/des/read_pwd.c
@@ -0,0 +1,521 @@
+/* crypto/des/read_pwd.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/e_os2.h>
+#if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_WIN32)
+#ifdef OPENSSL_UNISTD
+# include OPENSSL_UNISTD
+#else
+# include <unistd.h>
+#endif
+/* If unistd.h defines _POSIX_VERSION, we conclude that we
+ * are on a POSIX system and have sigaction and termios. */
+#if defined(_POSIX_VERSION)
+
+# define SIGACTION
+# if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY)
+# define TERMIOS
+# endif
+
+#endif
+#endif
+
+/* #define SIGACTION */ /* Define this if you have sigaction() */
+
+#ifdef WIN16TTY
+#undef OPENSSL_SYS_WIN16
+#undef _WINDOWS
+#include <graph.h>
+#endif
+
+/* 06-Apr-92 Luke Brennan    Support for VMS */
+#include "des_locl.h"
+#include "cryptlib.h"
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <setjmp.h>
+#include <errno.h>
+
+#ifdef OPENSSL_SYS_VMS			/* prototypes for sys$whatever */
+#include <starlet.h>
+#ifdef __DECC
+#pragma message disable DOLLARID
+#endif
+#endif
+
+#ifdef WIN_CONSOLE_BUG
+#include <windows.h>
+#ifndef OPENSSL_SYS_WINCE
+#include <wincon.h>
+#endif
+#endif
+
+
+/* There are 5 types of terminal interface supported,
+ * TERMIO, TERMIOS, VMS, MSDOS and SGTTY
+ */
+
+#if defined(__sgi) && !defined(TERMIOS)
+#define TERMIOS
+#undef  TERMIO
+#undef  SGTTY
+#endif
+
+#if defined(linux) && !defined(TERMIO)
+#undef  TERMIOS
+#define TERMIO
+#undef  SGTTY
+#endif
+
+#ifdef _LIBC
+#undef  TERMIOS
+#define TERMIO
+#undef  SGTTY
+#endif
+
+#if !defined(TERMIO) && !defined(TERMIOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MSDOS) && !defined(MAC_OS_pre_X) && !defined(MAC_OS_GUSI_SOURCE)
+#undef  TERMIOS
+#undef  TERMIO
+#define SGTTY
+#endif
+
+#if defined(OPENSSL_SYS_VXWORKS)
+#undef TERMIOS
+#undef TERMIO
+#undef SGTTY
+#endif
+
+#ifdef TERMIOS
+#include <termios.h>
+#define TTY_STRUCT		struct termios
+#define TTY_FLAGS		c_lflag
+#define	TTY_get(tty,data)	tcgetattr(tty,data)
+#define TTY_set(tty,data)	tcsetattr(tty,TCSANOW,data)
+#endif
+
+#ifdef TERMIO
+#include <termio.h>
+#define TTY_STRUCT		struct termio
+#define TTY_FLAGS		c_lflag
+#define TTY_get(tty,data)	ioctl(tty,TCGETA,data)
+#define TTY_set(tty,data)	ioctl(tty,TCSETA,data)
+#endif
+
+#ifdef SGTTY
+#include <sgtty.h>
+#define TTY_STRUCT		struct sgttyb
+#define TTY_FLAGS		sg_flags
+#define TTY_get(tty,data)	ioctl(tty,TIOCGETP,data)
+#define TTY_set(tty,data)	ioctl(tty,TIOCSETP,data)
+#endif
+
+#if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(MAC_OS_pre_X)
+#include <sys/ioctl.h>
+#endif
+
+#if defined(OPENSSL_SYS_MSDOS) && !defined(__CYGWIN32__) && !defined(OPENSSL_SYS_WINCE)
+#include <conio.h>
+#define fgets(a,b,c) noecho_fgets(a,b,c)
+#endif
+
+#ifdef OPENSSL_SYS_VMS
+#include <ssdef.h>
+#include <iodef.h>
+#include <ttdef.h>
+#include <descrip.h>
+struct IOSB {
+	short iosb$w_value;
+	short iosb$w_count;
+	long  iosb$l_info;
+	};
+#endif
+
+#if defined(MAC_OS_pre_X) || defined(MAC_OS_GUSI_SOURCE)
+/*
+ * This one needs work. As a matter of fact the code is unoperational
+ * and this is only a trick to get it compiled.
+ *					<appro@fy.chalmers.se>
+ */
+#define TTY_STRUCT int
+#endif
+
+#ifndef NX509_SIG
+#define NX509_SIG 32
+#endif
+
+static void read_till_nl(FILE *);
+static void recsig(int);
+static void pushsig(void);
+static void popsig(void);
+#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16)
+static int noecho_fgets(char *buf, int size, FILE *tty);
+#endif
+#ifdef SIGACTION
+ static struct sigaction savsig[NX509_SIG];
+#else
+  static void (*savsig[NX509_SIG])(int );
+#endif
+static jmp_buf save;
+
+int des_read_pw_string(char *buf, int length, const char *prompt,
+	     int verify)
+	{
+	char buff[BUFSIZ];
+	int ret;
+
+	ret=des_read_pw(buf,buff,(length>BUFSIZ)?BUFSIZ:length,prompt,verify);
+	OPENSSL_cleanse(buff,BUFSIZ);
+	return(ret);
+	}
+
+#ifdef OPENSSL_SYS_WINCE
+
+int des_read_pw(char *buf, char *buff, int size, const char *prompt, int verify)
+	{ 
+	memset(buf,0,size);
+	memset(buff,0,size);
+	return(0);
+	}
+
+#elif defined(OPENSSL_SYS_WIN16)
+
+int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify)
+	{ 
+	memset(buf,0,size);
+	memset(buff,0,size);
+	return(0);
+	}
+
+#else /* !OPENSSL_SYS_WINCE && !OPENSSL_SYS_WIN16 */
+
+static void read_till_nl(FILE *in)
+	{
+#define SIZE 4
+	char buf[SIZE+1];
+
+	do	{
+		fgets(buf,SIZE,in);
+		} while (strchr(buf,'\n') == NULL);
+	}
+
+
+/* return 0 if ok, 1 (or -1) otherwise */
+int des_read_pw(char *buf, char *buff, int size, const char *prompt,
+	     int verify)
+	{
+#ifdef OPENSSL_SYS_VMS
+	struct IOSB iosb;
+	$DESCRIPTOR(terminal,"TT");
+	long tty_orig[3], tty_new[3];
+	long status;
+	unsigned short channel = 0;
+#else
+#if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__)
+	TTY_STRUCT tty_orig,tty_new;
+#endif
+#endif
+	int number;
+	int ok;
+	/* statics are simply to avoid warnings about longjmp clobbering
+	   things */
+	static int ps;
+	int is_a_tty;
+	static FILE *tty;
+	char *p;
+
+	if (setjmp(save))
+		{
+		ok=0;
+		goto error;
+		}
+
+	number=5;
+	ok=0;
+	ps=0;
+	is_a_tty=1;
+	tty=NULL;
+
+#ifdef OPENSSL_SYS_MSDOS
+	if ((tty=fopen("con","r")) == NULL)
+		tty=stdin;
+#elif defined(MAC_OS_pre_X) || defined(OPENSSL_SYS_VXWORKS)
+	tty=stdin;
+#else
+#ifndef OPENSSL_SYS_MPE
+	if ((tty=fopen("/dev/tty","r")) == NULL)
+#endif
+		tty=stdin;
+#endif
+
+#if defined(TTY_get) && !defined(OPENSSL_SYS_VMS)
+	if (TTY_get(fileno(tty),&tty_orig) == -1)
+		{
+#ifdef ENOTTY
+		if (errno == ENOTTY)
+			is_a_tty=0;
+		else
+#endif
+#ifdef EINVAL
+		/* Ariel Glenn ariel@columbia.edu reports that solaris
+		 * can return EINVAL instead.  This should be ok */
+		if (errno == EINVAL)
+			is_a_tty=0;
+		else
+#endif
+			return(-1);
+		}
+	memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig));
+#endif
+#ifdef OPENSSL_SYS_VMS
+	status = sys$assign(&terminal,&channel,0,0);
+	if (status != SS$_NORMAL)
+		return(-1);
+	status=sys$qiow(0,channel,IO$_SENSEMODE,&iosb,0,0,tty_orig,12,0,0,0,0);
+	if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
+		return(-1);
+#endif
+
+	pushsig();
+	ps=1;
+
+#ifdef TTY_FLAGS
+	tty_new.TTY_FLAGS &= ~ECHO;
+#endif
+
+#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
+	if (is_a_tty && (TTY_set(fileno(tty),&tty_new) == -1))
+#ifdef OPENSSL_SYS_MPE 
+		; /* MPE lies -- echo really has been disabled */
+#else
+		return(-1);
+#endif
+#endif
+#ifdef OPENSSL_SYS_VMS
+	tty_new[0] = tty_orig[0];
+	tty_new[1] = tty_orig[1] | TT$M_NOECHO;
+	tty_new[2] = tty_orig[2];
+	status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0);
+	if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
+		return(-1);
+#endif
+	ps=2;
+
+	while ((!ok) && (number--))
+		{
+		fputs(prompt,stderr);
+		fflush(stderr);
+
+		buf[0]='\0';
+		fgets(buf,size,tty);
+		if (feof(tty)) goto error;
+		if (ferror(tty)) goto error;
+		if ((p=(char *)strchr(buf,'\n')) != NULL)
+			*p='\0';
+		else	read_till_nl(tty);
+		if (verify)
+			{
+			fprintf(stderr,"\nVerifying password - %s",prompt);
+			fflush(stderr);
+			buff[0]='\0';
+			fgets(buff,size,tty);
+			if (feof(tty)) goto error;
+			if ((p=(char *)strchr(buff,'\n')) != NULL)
+				*p='\0';
+			else	read_till_nl(tty);
+				
+			if (strcmp(buf,buff) != 0)
+				{
+				fprintf(stderr,"\nVerify failure");
+				fflush(stderr);
+				break;
+				/* continue; */
+				}
+			}
+		ok=1;
+		}
+
+error:
+	fprintf(stderr,"\n");
+#if 0
+	perror("fgets(tty)");
+#endif
+	/* What can we do if there is an error? */
+#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
+	if (ps >= 2) TTY_set(fileno(tty),&tty_orig);
+#endif
+#ifdef OPENSSL_SYS_VMS
+	if (ps >= 2)
+		status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0
+			,tty_orig,12,0,0,0,0);
+#endif
+	
+	if (ps >= 1) popsig();
+	if (stdin != tty) fclose(tty);
+#ifdef OPENSSL_SYS_VMS
+	status = sys$dassgn(channel);
+#endif
+	return(!ok);
+	}
+
+static void pushsig(void)
+	{
+	int i;
+#ifdef SIGACTION
+	struct sigaction sa;
+
+	memset(&sa,0,sizeof sa);
+	sa.sa_handler=recsig;
+#endif
+
+	for (i=1; i<NX509_SIG; i++)
+		{
+#ifdef SIGUSR1
+		if (i == SIGUSR1)
+			continue;
+#endif
+#ifdef SIGUSR2
+		if (i == SIGUSR2)
+			continue;
+#endif
+#ifdef SIGACTION
+		sigaction(i,&sa,&savsig[i]);
+#else
+		savsig[i]=signal(i,recsig);
+#endif
+		}
+
+#ifdef SIGWINCH
+	signal(SIGWINCH,SIG_DFL);
+#endif
+	}
+
+static void popsig(void)
+	{
+	int i;
+
+	for (i=1; i<NX509_SIG; i++)
+		{
+#ifdef SIGUSR1
+		if (i == SIGUSR1)
+			continue;
+#endif
+#ifdef SIGUSR2
+		if (i == SIGUSR2)
+			continue;
+#endif
+#ifdef SIGACTION
+		sigaction(i,&savsig[i],NULL);
+#else
+		signal(i,savsig[i]);
+#endif
+		}
+	}
+
+static void recsig(int i)
+	{
+	longjmp(save,1);
+#ifdef LINT
+	i=i;
+#endif
+	}
+
+#ifdef OPENSSL_SYS_MSDOS
+static int noecho_fgets(char *buf, int size, FILE *tty)
+	{
+	int i;
+	char *p;
+
+	p=buf;
+	for (;;)
+		{
+		if (size == 0)
+			{
+			*p='\0';
+			break;
+			}
+		size--;
+#ifdef WIN16TTY
+		i=_inchar();
+#else
+		i=getch();
+#endif
+		if (i == '\r') i='\n';
+		*(p++)=i;
+		if (i == '\n')
+			{
+			*p='\0';
+			break;
+			}
+		}
+#ifdef WIN_CONSOLE_BUG
+/* Win95 has several evil console bugs: one of these is that the
+ * last character read using getch() is passed to the next read: this is
+ * usually a CR so this can be trouble. No STDIO fix seems to work but
+ * flushing the console appears to do the trick.
+ */
+		{
+			HANDLE inh;
+			inh = GetStdHandle(STD_INPUT_HANDLE);
+			FlushConsoleInputBuffer(inh);
+		}
+#endif
+	return(strlen(buf));
+	}
+#endif
+#endif /* !OPENSSL_SYS_WINCE && !WIN16 */
diff --git a/openssl/crypto/des/rpc_des.h b/openssl/crypto/des/rpc_des.h
new file mode 100644
index 0000000..41328d7
--- /dev/null
+++ b/openssl/crypto/des/rpc_des.h
@@ -0,0 +1,131 @@
+/* crypto/des/rpc_des.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*  @(#)des.h	2.2 88/08/10 4.0 RPCSRC; from 2.7 88/02/08 SMI  */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*
+ * Generic DES driver interface
+ * Keep this file hardware independent!
+ * Copyright (c) 1986 by Sun Microsystems, Inc.
+ */
+
+#define DES_MAXLEN 	65536	/* maximum # of bytes to encrypt  */
+#define DES_QUICKLEN	16	/* maximum # of bytes to encrypt quickly */
+
+#ifdef HEADER_DES_H
+#undef ENCRYPT
+#undef DECRYPT
+#endif
+
+enum desdir { ENCRYPT, DECRYPT };
+enum desmode { CBC, ECB };
+
+/*
+ * parameters to ioctl call
+ */
+struct desparams {
+	unsigned char des_key[8];	/* key (with low bit parity) */
+	enum desdir des_dir;	/* direction */
+	enum desmode des_mode;	/* mode */
+	unsigned char des_ivec[8];	/* input vector */
+	unsigned des_len;	/* number of bytes to crypt */
+	union {
+		unsigned char UDES_data[DES_QUICKLEN];
+		unsigned char *UDES_buf;
+	} UDES;
+#	define des_data UDES.UDES_data	/* direct data here if quick */
+#	define des_buf	UDES.UDES_buf	/* otherwise, pointer to data */
+};
+
+/*
+ * Encrypt an arbitrary sized buffer
+ */
+#define	DESIOCBLOCK	_IOWR('d', 6, struct desparams)
+
+/* 
+ * Encrypt of small amount of data, quickly
+ */
+#define DESIOCQUICK	_IOWR('d', 7, struct desparams) 
+
diff --git a/openssl/crypto/des/rpc_enc.c b/openssl/crypto/des/rpc_enc.c
new file mode 100644
index 0000000..d937d08
--- /dev/null
+++ b/openssl/crypto/des/rpc_enc.c
@@ -0,0 +1,98 @@
+/* crypto/des/rpc_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "rpc_des.h"
+#include "des_locl.h"
+#include "des_ver.h"
+
+int _des_crypt(char *buf,int len,struct desparams *desp);
+int _des_crypt(char *buf, int len, struct desparams *desp)
+	{
+	DES_key_schedule ks;
+	int enc;
+
+	DES_set_key_unchecked(&desp->des_key,&ks);
+	enc=(desp->des_dir == ENCRYPT)?DES_ENCRYPT:DES_DECRYPT;
+
+	if (desp->des_mode == CBC)
+		DES_ecb_encrypt((const_DES_cblock *)desp->UDES.UDES_buf,
+				(DES_cblock *)desp->UDES.UDES_buf,&ks,
+				enc);
+	else
+		{
+		DES_ncbc_encrypt(desp->UDES.UDES_buf,desp->UDES.UDES_buf,
+				len,&ks,&desp->des_ivec,enc);
+#ifdef undef
+		/* len will always be %8 if called from common_crypt
+		 * in secure_rpc.
+		 * Libdes's cbc encrypt does not copy back the iv,
+		 * so we have to do it here. */
+		/* It does now :-) eay 20/09/95 */
+
+		a=(char *)&(desp->UDES.UDES_buf[len-8]);
+		b=(char *)&(desp->des_ivec[0]);
+
+		*(a++)= *(b++); *(a++)= *(b++);
+		*(a++)= *(b++); *(a++)= *(b++);
+		*(a++)= *(b++); *(a++)= *(b++);
+		*(a++)= *(b++); *(a++)= *(b++);
+#endif
+		}
+	return(1);	
+	}
+
diff --git a/openssl/crypto/des/rpw.c b/openssl/crypto/des/rpw.c
new file mode 100644
index 0000000..8a9473c
--- /dev/null
+++ b/openssl/crypto/des/rpw.c
@@ -0,0 +1,99 @@
+/* crypto/des/rpw.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/des.h>
+
+int main(int argc, char *argv[])
+	{
+	DES_cblock k,k1;
+	int i;
+
+	printf("read passwd\n");
+	if ((i=des_read_password(&k,"Enter password:",0)) == 0)
+		{
+		printf("password = ");
+		for (i=0; i<8; i++)
+			printf("%02x ",k[i]);
+		}
+	else
+		printf("error %d\n",i);
+	printf("\n");
+	printf("read 2passwds and verify\n");
+	if ((i=des_read_2passwords(&k,&k1,
+		"Enter verified password:",1)) == 0)
+		{
+		printf("password1 = ");
+		for (i=0; i<8; i++)
+			printf("%02x ",k[i]);
+		printf("\n");
+		printf("password2 = ");
+		for (i=0; i<8; i++)
+			printf("%02x ",k1[i]);
+		printf("\n");
+		exit(1);
+		}
+	else
+		{
+		printf("error %d\n",i);
+		exit(0);
+		}
+#ifdef LINT
+	return(0);
+#endif
+	}
diff --git a/openssl/crypto/des/set_key.c b/openssl/crypto/des/set_key.c
new file mode 100644
index 0000000..3004cc3
--- /dev/null
+++ b/openssl/crypto/des/set_key.c
@@ -0,0 +1,407 @@
+/* crypto/des/set_key.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* set_key.c v 1.4 eay 24/9/91
+ * 1.4 Speed up by 400% :-)
+ * 1.3 added register declarations.
+ * 1.2 unrolled make_key_sched a bit more
+ * 1.1 added norm_expand_bits
+ * 1.0 First working version
+ */
+#include "des_locl.h"
+
+OPENSSL_IMPLEMENT_GLOBAL(int,DES_check_key,0)	/* defaults to false */
+
+static const unsigned char odd_parity[256]={
+  1,  1,  2,  2,  4,  4,  7,  7,  8,  8, 11, 11, 13, 13, 14, 14,
+ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
+ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
+ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
+ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
+ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
+ 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
+112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
+128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
+145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
+161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
+176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
+193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
+208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
+224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
+241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
+
+void DES_set_odd_parity(DES_cblock *key)
+	{
+	unsigned int i;
+
+	for (i=0; i<DES_KEY_SZ; i++)
+		(*key)[i]=odd_parity[(*key)[i]];
+	}
+
+int DES_check_key_parity(const_DES_cblock *key)
+	{
+	unsigned int i;
+
+	for (i=0; i<DES_KEY_SZ; i++)
+		{
+		if ((*key)[i] != odd_parity[(*key)[i]])
+			return(0);
+		}
+	return(1);
+	}
+
+/* Weak and semi week keys as take from
+ * %A D.W. Davies
+ * %A W.L. Price
+ * %T Security for Computer Networks
+ * %I John Wiley & Sons
+ * %D 1984
+ * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
+ * (and actual cblock values).
+ */
+#define NUM_WEAK_KEY	16
+static const DES_cblock weak_keys[NUM_WEAK_KEY]={
+	/* weak keys */
+	{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
+	{0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
+	{0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
+	{0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
+	/* semi-weak keys */
+	{0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
+	{0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
+	{0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
+	{0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
+	{0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
+	{0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
+	{0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
+	{0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
+	{0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
+	{0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
+	{0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
+	{0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
+
+int DES_is_weak_key(const_DES_cblock *key)
+	{
+	int i;
+
+	for (i=0; i<NUM_WEAK_KEY; i++)
+		/* Added == 0 to comparison, I obviously don't run
+		 * this section very often :-(, thanks to
+		 * engineering@MorningStar.Com for the fix
+		 * eay 93/06/29
+		 * Another problem, I was comparing only the first 4
+		 * bytes, 97/03/18 */
+		if (memcmp(weak_keys[i],key,sizeof(DES_cblock)) == 0) return(1);
+	return(0);
+	}
+
+/* NOW DEFINED IN des_local.h
+ * See ecb_encrypt.c for a pseudo description of these macros. 
+ * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+ * 	(b)^=(t),\
+ * 	(a)=((a)^((t)<<(n))))
+ */
+
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+	(a)=(a)^(t)^(t>>(16-(n))))
+
+static const DES_LONG des_skb[8][64]={
+	{
+	/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+	0x00000000L,0x00000010L,0x20000000L,0x20000010L,
+	0x00010000L,0x00010010L,0x20010000L,0x20010010L,
+	0x00000800L,0x00000810L,0x20000800L,0x20000810L,
+	0x00010800L,0x00010810L,0x20010800L,0x20010810L,
+	0x00000020L,0x00000030L,0x20000020L,0x20000030L,
+	0x00010020L,0x00010030L,0x20010020L,0x20010030L,
+	0x00000820L,0x00000830L,0x20000820L,0x20000830L,
+	0x00010820L,0x00010830L,0x20010820L,0x20010830L,
+	0x00080000L,0x00080010L,0x20080000L,0x20080010L,
+	0x00090000L,0x00090010L,0x20090000L,0x20090010L,
+	0x00080800L,0x00080810L,0x20080800L,0x20080810L,
+	0x00090800L,0x00090810L,0x20090800L,0x20090810L,
+	0x00080020L,0x00080030L,0x20080020L,0x20080030L,
+	0x00090020L,0x00090030L,0x20090020L,0x20090030L,
+	0x00080820L,0x00080830L,0x20080820L,0x20080830L,
+	0x00090820L,0x00090830L,0x20090820L,0x20090830L,
+	},{
+	/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
+	0x00000000L,0x02000000L,0x00002000L,0x02002000L,
+	0x00200000L,0x02200000L,0x00202000L,0x02202000L,
+	0x00000004L,0x02000004L,0x00002004L,0x02002004L,
+	0x00200004L,0x02200004L,0x00202004L,0x02202004L,
+	0x00000400L,0x02000400L,0x00002400L,0x02002400L,
+	0x00200400L,0x02200400L,0x00202400L,0x02202400L,
+	0x00000404L,0x02000404L,0x00002404L,0x02002404L,
+	0x00200404L,0x02200404L,0x00202404L,0x02202404L,
+	0x10000000L,0x12000000L,0x10002000L,0x12002000L,
+	0x10200000L,0x12200000L,0x10202000L,0x12202000L,
+	0x10000004L,0x12000004L,0x10002004L,0x12002004L,
+	0x10200004L,0x12200004L,0x10202004L,0x12202004L,
+	0x10000400L,0x12000400L,0x10002400L,0x12002400L,
+	0x10200400L,0x12200400L,0x10202400L,0x12202400L,
+	0x10000404L,0x12000404L,0x10002404L,0x12002404L,
+	0x10200404L,0x12200404L,0x10202404L,0x12202404L,
+	},{
+	/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
+	0x00000000L,0x00000001L,0x00040000L,0x00040001L,
+	0x01000000L,0x01000001L,0x01040000L,0x01040001L,
+	0x00000002L,0x00000003L,0x00040002L,0x00040003L,
+	0x01000002L,0x01000003L,0x01040002L,0x01040003L,
+	0x00000200L,0x00000201L,0x00040200L,0x00040201L,
+	0x01000200L,0x01000201L,0x01040200L,0x01040201L,
+	0x00000202L,0x00000203L,0x00040202L,0x00040203L,
+	0x01000202L,0x01000203L,0x01040202L,0x01040203L,
+	0x08000000L,0x08000001L,0x08040000L,0x08040001L,
+	0x09000000L,0x09000001L,0x09040000L,0x09040001L,
+	0x08000002L,0x08000003L,0x08040002L,0x08040003L,
+	0x09000002L,0x09000003L,0x09040002L,0x09040003L,
+	0x08000200L,0x08000201L,0x08040200L,0x08040201L,
+	0x09000200L,0x09000201L,0x09040200L,0x09040201L,
+	0x08000202L,0x08000203L,0x08040202L,0x08040203L,
+	0x09000202L,0x09000203L,0x09040202L,0x09040203L,
+	},{
+	/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
+	0x00000000L,0x00100000L,0x00000100L,0x00100100L,
+	0x00000008L,0x00100008L,0x00000108L,0x00100108L,
+	0x00001000L,0x00101000L,0x00001100L,0x00101100L,
+	0x00001008L,0x00101008L,0x00001108L,0x00101108L,
+	0x04000000L,0x04100000L,0x04000100L,0x04100100L,
+	0x04000008L,0x04100008L,0x04000108L,0x04100108L,
+	0x04001000L,0x04101000L,0x04001100L,0x04101100L,
+	0x04001008L,0x04101008L,0x04001108L,0x04101108L,
+	0x00020000L,0x00120000L,0x00020100L,0x00120100L,
+	0x00020008L,0x00120008L,0x00020108L,0x00120108L,
+	0x00021000L,0x00121000L,0x00021100L,0x00121100L,
+	0x00021008L,0x00121008L,0x00021108L,0x00121108L,
+	0x04020000L,0x04120000L,0x04020100L,0x04120100L,
+	0x04020008L,0x04120008L,0x04020108L,0x04120108L,
+	0x04021000L,0x04121000L,0x04021100L,0x04121100L,
+	0x04021008L,0x04121008L,0x04021108L,0x04121108L,
+	},{
+	/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+	0x00000000L,0x10000000L,0x00010000L,0x10010000L,
+	0x00000004L,0x10000004L,0x00010004L,0x10010004L,
+	0x20000000L,0x30000000L,0x20010000L,0x30010000L,
+	0x20000004L,0x30000004L,0x20010004L,0x30010004L,
+	0x00100000L,0x10100000L,0x00110000L,0x10110000L,
+	0x00100004L,0x10100004L,0x00110004L,0x10110004L,
+	0x20100000L,0x30100000L,0x20110000L,0x30110000L,
+	0x20100004L,0x30100004L,0x20110004L,0x30110004L,
+	0x00001000L,0x10001000L,0x00011000L,0x10011000L,
+	0x00001004L,0x10001004L,0x00011004L,0x10011004L,
+	0x20001000L,0x30001000L,0x20011000L,0x30011000L,
+	0x20001004L,0x30001004L,0x20011004L,0x30011004L,
+	0x00101000L,0x10101000L,0x00111000L,0x10111000L,
+	0x00101004L,0x10101004L,0x00111004L,0x10111004L,
+	0x20101000L,0x30101000L,0x20111000L,0x30111000L,
+	0x20101004L,0x30101004L,0x20111004L,0x30111004L,
+	},{
+	/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
+	0x00000000L,0x08000000L,0x00000008L,0x08000008L,
+	0x00000400L,0x08000400L,0x00000408L,0x08000408L,
+	0x00020000L,0x08020000L,0x00020008L,0x08020008L,
+	0x00020400L,0x08020400L,0x00020408L,0x08020408L,
+	0x00000001L,0x08000001L,0x00000009L,0x08000009L,
+	0x00000401L,0x08000401L,0x00000409L,0x08000409L,
+	0x00020001L,0x08020001L,0x00020009L,0x08020009L,
+	0x00020401L,0x08020401L,0x00020409L,0x08020409L,
+	0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
+	0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
+	0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
+	0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
+	0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
+	0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
+	0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
+	0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
+	},{
+	/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
+	0x00000000L,0x00000100L,0x00080000L,0x00080100L,
+	0x01000000L,0x01000100L,0x01080000L,0x01080100L,
+	0x00000010L,0x00000110L,0x00080010L,0x00080110L,
+	0x01000010L,0x01000110L,0x01080010L,0x01080110L,
+	0x00200000L,0x00200100L,0x00280000L,0x00280100L,
+	0x01200000L,0x01200100L,0x01280000L,0x01280100L,
+	0x00200010L,0x00200110L,0x00280010L,0x00280110L,
+	0x01200010L,0x01200110L,0x01280010L,0x01280110L,
+	0x00000200L,0x00000300L,0x00080200L,0x00080300L,
+	0x01000200L,0x01000300L,0x01080200L,0x01080300L,
+	0x00000210L,0x00000310L,0x00080210L,0x00080310L,
+	0x01000210L,0x01000310L,0x01080210L,0x01080310L,
+	0x00200200L,0x00200300L,0x00280200L,0x00280300L,
+	0x01200200L,0x01200300L,0x01280200L,0x01280300L,
+	0x00200210L,0x00200310L,0x00280210L,0x00280310L,
+	0x01200210L,0x01200310L,0x01280210L,0x01280310L,
+	},{
+	/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
+	0x00000000L,0x04000000L,0x00040000L,0x04040000L,
+	0x00000002L,0x04000002L,0x00040002L,0x04040002L,
+	0x00002000L,0x04002000L,0x00042000L,0x04042000L,
+	0x00002002L,0x04002002L,0x00042002L,0x04042002L,
+	0x00000020L,0x04000020L,0x00040020L,0x04040020L,
+	0x00000022L,0x04000022L,0x00040022L,0x04040022L,
+	0x00002020L,0x04002020L,0x00042020L,0x04042020L,
+	0x00002022L,0x04002022L,0x00042022L,0x04042022L,
+	0x00000800L,0x04000800L,0x00040800L,0x04040800L,
+	0x00000802L,0x04000802L,0x00040802L,0x04040802L,
+	0x00002800L,0x04002800L,0x00042800L,0x04042800L,
+	0x00002802L,0x04002802L,0x00042802L,0x04042802L,
+	0x00000820L,0x04000820L,0x00040820L,0x04040820L,
+	0x00000822L,0x04000822L,0x00040822L,0x04040822L,
+	0x00002820L,0x04002820L,0x00042820L,0x04042820L,
+	0x00002822L,0x04002822L,0x00042822L,0x04042822L,
+	}};
+
+int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule)
+	{
+	if (DES_check_key)
+		{
+		return DES_set_key_checked(key, schedule);
+		}
+	else
+		{
+		DES_set_key_unchecked(key, schedule);
+		return 0;
+		}
+	}
+
+/* return 0 if key parity is odd (correct),
+ * return -1 if key parity error,
+ * return -2 if illegal weak key.
+ */
+int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule)
+	{
+	if (!DES_check_key_parity(key))
+		return(-1);
+	if (DES_is_weak_key(key))
+		return(-2);
+	DES_set_key_unchecked(key, schedule);
+	return 0;
+	}
+
+void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
+	{
+	static const int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
+	register DES_LONG c,d,t,s,t2;
+	register const unsigned char *in;
+	register DES_LONG *k;
+	register int i;
+
+#ifdef OPENBSD_DEV_CRYPTO
+	memcpy(schedule->key,key,sizeof schedule->key);
+	schedule->session=NULL;
+#endif
+	k = &schedule->ks->deslong[0];
+	in = &(*key)[0];
+
+	c2l(in,c);
+	c2l(in,d);
+
+	/* do PC1 in 47 simple operations :-)
+	 * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
+	 * for the inspiration. :-) */
+	PERM_OP (d,c,t,4,0x0f0f0f0fL);
+	HPERM_OP(c,t,-2,0xcccc0000L);
+	HPERM_OP(d,t,-2,0xcccc0000L);
+	PERM_OP (d,c,t,1,0x55555555L);
+	PERM_OP (c,d,t,8,0x00ff00ffL);
+	PERM_OP (d,c,t,1,0x55555555L);
+	d=	(((d&0x000000ffL)<<16L)| (d&0x0000ff00L)     |
+		 ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
+	c&=0x0fffffffL;
+
+	for (i=0; i<ITERATIONS; i++)
+		{
+		if (shifts2[i])
+			{ c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
+		else
+			{ c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
+		c&=0x0fffffffL;
+		d&=0x0fffffffL;
+		/* could be a few less shifts but I am to lazy at this
+		 * point in time to investigate */
+		s=	des_skb[0][ (c    )&0x3f                ]|
+			des_skb[1][((c>> 6L)&0x03)|((c>> 7L)&0x3c)]|
+			des_skb[2][((c>>13L)&0x0f)|((c>>14L)&0x30)]|
+			des_skb[3][((c>>20L)&0x01)|((c>>21L)&0x06) |
+						  ((c>>22L)&0x38)];
+		t=	des_skb[4][ (d    )&0x3f                ]|
+			des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
+			des_skb[6][ (d>>15L)&0x3f                ]|
+			des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
+
+		/* table contained 0213 4657 */
+		t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
+		*(k++)=ROTATE(t2,30)&0xffffffffL;
+
+		t2=((s>>16L)|(t&0xffff0000L));
+		*(k++)=ROTATE(t2,26)&0xffffffffL;
+		}
+	}
+
+int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule)
+	{
+	return(DES_set_key(key,schedule));
+	}
+/*
+#undef des_fixup_key_parity
+void des_fixup_key_parity(des_cblock *key)
+	{
+	des_set_odd_parity(key);
+	}
+*/
diff --git a/openssl/crypto/des/speed.c b/openssl/crypto/des/speed.c
new file mode 100644
index 0000000..1616f4b
--- /dev/null
+++ b/openssl/crypto/des/speed.c
@@ -0,0 +1,314 @@
+/* crypto/des/speed.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
+/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
+
+#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
+#define TIMES
+#endif
+
+#include <stdio.h>
+
+#include <openssl/e_os2.h>
+#include OPENSSL_UNISTD_IO
+OPENSSL_DECLARE_EXIT
+
+#ifndef OPENSSL_SYS_NETWARE
+#include <signal.h>
+#define crypt(c,s) (des_crypt((c),(s)))
+#endif
+
+#ifndef _IRIX
+#include <time.h>
+#endif
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+#endif
+
+/* Depending on the VMS version, the tms structure is perhaps defined.
+   The __TMS macro will show if it was.  If it wasn't defined, we should
+   undefine TIMES, since that tells the rest of the program how things
+   should be handled.				-- Richard Levitte */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
+#undef TIMES
+#endif
+
+#ifndef TIMES
+#include <sys/timeb.h>
+#endif
+
+#if defined(sun) || defined(__ultrix)
+#define _POSIX_SOURCE
+#include <limits.h>
+#include <sys/param.h>
+#endif
+
+#include <openssl/des.h>
+
+/* The following if from times(3) man page.  It may need to be changed */
+#ifndef HZ
+# ifndef CLK_TCK
+#  ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
+#   define HZ	100.0
+#  else /* _BSD_CLK_TCK_ */
+#   define HZ ((double)_BSD_CLK_TCK_)
+#  endif
+# else /* CLK_TCK */
+#  define HZ ((double)CLK_TCK)
+# endif
+#endif
+
+#define BUFSIZE	((long)1024)
+long run=0;
+
+double Time_F(int s);
+#ifdef SIGALRM
+#if defined(__STDC__) || defined(sgi) || defined(_AIX)
+#define SIGRETTYPE void
+#else
+#define SIGRETTYPE int
+#endif
+
+SIGRETTYPE sig_done(int sig);
+SIGRETTYPE sig_done(int sig)
+	{
+	signal(SIGALRM,sig_done);
+	run=0;
+#ifdef LINT
+	sig=sig;
+#endif
+	}
+#endif
+
+#define START	0
+#define STOP	1
+
+double Time_F(int s)
+	{
+	double ret;
+#ifdef TIMES
+	static struct tms tstart,tend;
+
+	if (s == START)
+		{
+		times(&tstart);
+		return(0);
+		}
+	else
+		{
+		times(&tend);
+		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#else /* !times() */
+	static struct timeb tstart,tend;
+	long i;
+
+	if (s == START)
+		{
+		ftime(&tstart);
+		return(0);
+		}
+	else
+		{
+		ftime(&tend);
+		i=(long)tend.millitm-(long)tstart.millitm;
+		ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#endif
+	}
+
+int main(int argc, char **argv)
+	{
+	long count;
+	static unsigned char buf[BUFSIZE];
+	static DES_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
+	static DES_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
+	static DES_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
+	DES_key_schedule sch,sch2,sch3;
+	double a,b,c,d,e;
+#ifndef SIGALRM
+	long ca,cb,cc,cd,ce;
+#endif
+
+#ifndef TIMES
+	printf("To get the most accurate results, try to run this\n");
+	printf("program when this computer is idle.\n");
+#endif
+
+	DES_set_key_unchecked(&key2,&sch2);
+	DES_set_key_unchecked(&key3,&sch3);
+
+#ifndef SIGALRM
+	printf("First we calculate the approximate speed ...\n");
+	DES_set_key_unchecked(&key,&sch);
+	count=10;
+	do	{
+		long i;
+		DES_LONG data[2];
+
+		count*=2;
+		Time_F(START);
+		for (i=count; i; i--)
+			DES_encrypt1(data,&sch,DES_ENCRYPT);
+		d=Time_F(STOP);
+		} while (d < 3.0);
+	ca=count;
+	cb=count*3;
+	cc=count*3*8/BUFSIZE+1;
+	cd=count*8/BUFSIZE+1;
+	ce=count/20+1;
+	printf("Doing set_key %ld times\n",ca);
+#define COND(d)	(count != (d))
+#define COUNT(d) (d)
+#else
+#define COND(c)	(run)
+#define COUNT(d) (count)
+	signal(SIGALRM,sig_done);
+	printf("Doing set_key for 10 seconds\n");
+	alarm(10);
+#endif
+
+	Time_F(START);
+	for (count=0,run=1; COND(ca); count++)
+		DES_set_key_unchecked(&key,&sch);
+	d=Time_F(STOP);
+	printf("%ld set_key's in %.2f seconds\n",count,d);
+	a=((double)COUNT(ca))/d;
+
+#ifdef SIGALRM
+	printf("Doing DES_encrypt's for 10 seconds\n");
+	alarm(10);
+#else
+	printf("Doing DES_encrypt %ld times\n",cb);
+#endif
+	Time_F(START);
+	for (count=0,run=1; COND(cb); count++)
+		{
+		DES_LONG data[2];
+
+		DES_encrypt1(data,&sch,DES_ENCRYPT);
+		}
+	d=Time_F(STOP);
+	printf("%ld DES_encrypt's in %.2f second\n",count,d);
+	b=((double)COUNT(cb)*8)/d;
+
+#ifdef SIGALRM
+	printf("Doing DES_cbc_encrypt on %ld byte blocks for 10 seconds\n",
+		BUFSIZE);
+	alarm(10);
+#else
+	printf("Doing DES_cbc_encrypt %ld times on %ld byte blocks\n",cc,
+		BUFSIZE);
+#endif
+	Time_F(START);
+	for (count=0,run=1; COND(cc); count++)
+		DES_ncbc_encrypt(buf,buf,BUFSIZE,&sch,
+			&key,DES_ENCRYPT);
+	d=Time_F(STOP);
+	printf("%ld DES_cbc_encrypt's of %ld byte blocks in %.2f second\n",
+		count,BUFSIZE,d);
+	c=((double)COUNT(cc)*BUFSIZE)/d;
+
+#ifdef SIGALRM
+	printf("Doing DES_ede_cbc_encrypt on %ld byte blocks for 10 seconds\n",
+		BUFSIZE);
+	alarm(10);
+#else
+	printf("Doing DES_ede_cbc_encrypt %ld times on %ld byte blocks\n",cd,
+		BUFSIZE);
+#endif
+	Time_F(START);
+	for (count=0,run=1; COND(cd); count++)
+		DES_ede3_cbc_encrypt(buf,buf,BUFSIZE,
+			&sch,
+			&sch2,
+			&sch3,
+			&key,
+			DES_ENCRYPT);
+	d=Time_F(STOP);
+	printf("%ld DES_ede_cbc_encrypt's of %ld byte blocks in %.2f second\n",
+		count,BUFSIZE,d);
+	d=((double)COUNT(cd)*BUFSIZE)/d;
+
+#ifdef SIGALRM
+	printf("Doing crypt for 10 seconds\n");
+	alarm(10);
+#else
+	printf("Doing crypt %ld times\n",ce);
+#endif
+	Time_F(START);
+	for (count=0,run=1; COND(ce); count++)
+		crypt("testing1","ef");
+	e=Time_F(STOP);
+	printf("%ld crypts in %.2f second\n",count,e);
+	e=((double)COUNT(ce))/e;
+
+	printf("set_key            per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a);
+	printf("DES raw ecb bytes  per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b);
+	printf("DES cbc bytes      per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c);
+	printf("DES ede cbc bytes  per sec = %12.2f (%9.3fuS)\n",d,8.0e6/d);
+	printf("crypt              per sec = %12.2f (%9.3fuS)\n",e,1.0e6/e);
+	exit(0);
+#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
+	return(0);
+#endif
+	}
diff --git a/openssl/crypto/des/spr.h b/openssl/crypto/des/spr.h
new file mode 100644
index 0000000..b91936a
--- /dev/null
+++ b/openssl/crypto/des/spr.h
@@ -0,0 +1,204 @@
+/* crypto/des/spr.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+OPENSSL_GLOBAL const DES_LONG DES_SPtrans[8][64]={
+{
+/* nibble 0 */
+0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
+0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
+0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
+0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
+0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
+0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
+0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
+0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
+0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
+0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
+0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
+0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
+0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
+0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
+0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
+0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
+},{
+/* nibble 1 */
+0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
+0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
+0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
+0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
+0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
+0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
+0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
+0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
+0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
+0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
+0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
+0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
+0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
+0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
+0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
+0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
+},{
+/* nibble 2 */
+0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
+0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
+0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
+0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
+0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
+0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
+0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
+0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
+0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
+0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
+0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
+0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
+0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
+0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
+0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
+0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
+},{
+/* nibble 3 */
+0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
+0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
+0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
+0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
+0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
+0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
+0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
+0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
+0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
+0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
+0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
+0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
+0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
+0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
+0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
+0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
+},{
+/* nibble 4 */
+0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
+0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
+0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
+0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
+0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
+0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
+0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
+0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
+0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
+0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
+0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
+0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
+0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
+0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
+0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
+0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
+},{
+/* nibble 5 */
+0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
+0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
+0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
+0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
+0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
+0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
+0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
+0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
+0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
+0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
+0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
+0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
+0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
+0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
+0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
+0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
+},{
+/* nibble 6 */
+0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
+0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
+0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
+0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
+0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
+0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
+0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
+0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
+0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
+0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
+0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
+0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
+0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
+0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
+0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
+0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
+},{
+/* nibble 7 */
+0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
+0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
+0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
+0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
+0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
+0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
+0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
+0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
+0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
+0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
+0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
+0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
+0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
+0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
+0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
+0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
+}};
diff --git a/openssl/crypto/des/str2key.c b/openssl/crypto/des/str2key.c
new file mode 100644
index 0000000..9c2054b
--- /dev/null
+++ b/openssl/crypto/des/str2key.c
@@ -0,0 +1,174 @@
+/* crypto/des/str2key.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+#include <openssl/crypto.h>
+
+void DES_string_to_key(const char *str, DES_cblock *key)
+	{
+	DES_key_schedule ks;
+	int i,length;
+	register unsigned char j;
+
+	memset(key,0,8);
+	length=strlen(str);
+#ifdef OLD_STR_TO_KEY
+	for (i=0; i<length; i++)
+		(*key)[i%8]^=(str[i]<<1);
+#else /* MIT COMPATIBLE */
+	for (i=0; i<length; i++)
+		{
+		j=str[i];
+		if ((i%16) < 8)
+			(*key)[i%8]^=(j<<1);
+		else
+			{
+			/* Reverse the bit order 05/05/92 eay */
+			j=((j<<4)&0xf0)|((j>>4)&0x0f);
+			j=((j<<2)&0xcc)|((j>>2)&0x33);
+			j=((j<<1)&0xaa)|((j>>1)&0x55);
+			(*key)[7-(i%8)]^=j;
+			}
+		}
+#endif
+	DES_set_odd_parity(key);
+#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY
+	if(DES_is_weak_key(key))
+	    (*key)[7] ^= 0xF0;
+	DES_set_key(key,&ks);
+#else
+	DES_set_key_unchecked(key,&ks);
+#endif
+	DES_cbc_cksum((const unsigned char*)str,key,length,&ks,key);
+	OPENSSL_cleanse(&ks,sizeof(ks));
+	DES_set_odd_parity(key);
+	}
+
+void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2)
+	{
+	DES_key_schedule ks;
+	int i,length;
+	register unsigned char j;
+
+	memset(key1,0,8);
+	memset(key2,0,8);
+	length=strlen(str);
+#ifdef OLD_STR_TO_KEY
+	if (length <= 8)
+		{
+		for (i=0; i<length; i++)
+			{
+			(*key2)[i]=(*key1)[i]=(str[i]<<1);
+			}
+		}
+	else
+		{
+		for (i=0; i<length; i++)
+			{
+			if ((i/8)&1)
+				(*key2)[i%8]^=(str[i]<<1);
+			else
+				(*key1)[i%8]^=(str[i]<<1);
+			}
+		}
+#else /* MIT COMPATIBLE */
+	for (i=0; i<length; i++)
+		{
+		j=str[i];
+		if ((i%32) < 16)
+			{
+			if ((i%16) < 8)
+				(*key1)[i%8]^=(j<<1);
+			else
+				(*key2)[i%8]^=(j<<1);
+			}
+		else
+			{
+			j=((j<<4)&0xf0)|((j>>4)&0x0f);
+			j=((j<<2)&0xcc)|((j>>2)&0x33);
+			j=((j<<1)&0xaa)|((j>>1)&0x55);
+			if ((i%16) < 8)
+				(*key1)[7-(i%8)]^=j;
+			else
+				(*key2)[7-(i%8)]^=j;
+			}
+		}
+	if (length <= 8) memcpy(key2,key1,8);
+#endif
+	DES_set_odd_parity(key1);
+	DES_set_odd_parity(key2);
+#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY
+	if(DES_is_weak_key(key1))
+	    (*key1)[7] ^= 0xF0;
+	DES_set_key(key1,&ks);
+#else
+	DES_set_key_unchecked(key1,&ks);
+#endif
+	DES_cbc_cksum((const unsigned char*)str,key1,length,&ks,key1);
+#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY
+	if(DES_is_weak_key(key2))
+	    (*key2)[7] ^= 0xF0;
+	DES_set_key(key2,&ks);
+#else
+	DES_set_key_unchecked(key2,&ks);
+#endif
+	DES_cbc_cksum((const unsigned char*)str,key2,length,&ks,key2);
+	OPENSSL_cleanse(&ks,sizeof(ks));
+	DES_set_odd_parity(key1);
+	DES_set_odd_parity(key2);
+	}
diff --git a/openssl/crypto/des/t/test b/openssl/crypto/des/t/test
new file mode 100644
index 0000000..97acd05
--- /dev/null
+++ b/openssl/crypto/des/t/test
@@ -0,0 +1,27 @@
+#!./perl
+
+BEGIN { push(@INC, qw(../../../lib ../../lib ../lib lib)); }
+
+use DES;
+
+$key='00000000';
+$ks=DES::set_key($key);
+@a=split(//,$ks);
+foreach (@a) { printf "%02x-",ord($_); }
+print "\n";
+
+
+$key=DES::random_key();
+print "($_)\n";
+@a=split(//,$key);
+foreach (@a) { printf "%02x-",ord($_); }
+print "\n";
+$str="this is and again into the breach";
+($k1,$k2)=DES::string_to_2keys($str);
+@a=split(//,$k1);
+foreach (@a) { printf "%02x-",ord($_); }
+print "\n";
+@a=split(//,$k2);
+foreach (@a) { printf "%02x-",ord($_); }
+print "\n";
+
diff --git a/openssl/crypto/des/times/486-50.sol b/openssl/crypto/des/times/486-50.sol
new file mode 100644
index 0000000..0de62d6
--- /dev/null
+++ b/openssl/crypto/des/times/486-50.sol
@@ -0,0 +1,16 @@
+Solaris 2.4, 486 50mhz, gcc 2.6.3
+options    des ecb/s
+16 r2 i     43552.51 100.0%
+16 r1 i     43487.45  99.9%
+16  c p     43003.23  98.7%
+16 r2 p     42339.00  97.2%
+16  c i     41900.91  96.2%
+16 r1 p     41360.64  95.0%
+ 4  c i     38728.48  88.9%
+ 4  c p     38225.63  87.8%
+ 4 r1 i     38085.79  87.4%
+ 4 r2 i     37825.64  86.9%
+ 4 r2 p     34611.00  79.5%
+ 4 r1 p     31802.00  73.0%
+-DDES_UNROLL -DDES_RISC2
+
diff --git a/openssl/crypto/des/times/586-100.lnx b/openssl/crypto/des/times/586-100.lnx
new file mode 100644
index 0000000..4323914
--- /dev/null
+++ b/openssl/crypto/des/times/586-100.lnx
@@ -0,0 +1,20 @@
+Pentium 100
+Linux 2 kernel
+gcc 2.7.0 -O3 -fomit-frame-pointer
+No X server running, just a console, it makes the top speed jump from 151,000
+to 158,000 :-).
+options    des ecb/s
+assember   281000.00 177.1%
+16 r1 p    158667.40 100.0%
+16 r1 i    148471.70  93.6%
+16 r2 p    143961.80  90.7%
+16 r2 i    141689.20  89.3%
+ 4 r1 i    140100.00  88.3%
+ 4 r2 i    134049.40  84.5%
+16  c i    124145.20  78.2%
+16  c p    121584.20  76.6%
+ 4  c i    118116.00  74.4%
+ 4 r2 p    117977.90  74.4%
+ 4  c p    114971.40  72.5%
+ 4 r1 p    114578.40  72.2%
+-DDES_UNROLL -DDES_RISC1 -DDES_PTR
diff --git a/openssl/crypto/des/times/686-200.fre b/openssl/crypto/des/times/686-200.fre
new file mode 100644
index 0000000..7d83f6a
--- /dev/null
+++ b/openssl/crypto/des/times/686-200.fre
@@ -0,0 +1,18 @@
+Pentium 100
+Free BSD 2.1.5 kernel
+gcc 2.7.2.2 -O3 -fomit-frame-pointer
+options    des ecb/s
+assember   578000.00 133.1%
+16 r2 i    434454.80 100.0%
+16 r1 i    433621.43  99.8%
+16 r2 p    431375.69  99.3%
+ 4 r1 i    423722.30  97.5%
+ 4 r2 i    422399.40  97.2%
+16 r1 p    421739.40  97.1%
+16  c i    399027.94  91.8%
+16  c p    372251.70  85.7%
+ 4  c i    365118.35  84.0%
+ 4  c p    352880.51  81.2%
+ 4 r2 p    255104.90  58.7%
+ 4 r1 p    251289.18  57.8%
+-DDES_UNROLL -DDES_RISC2
diff --git a/openssl/crypto/des/times/aix.cc b/openssl/crypto/des/times/aix.cc
new file mode 100644
index 0000000..d96b74e
--- /dev/null
+++ b/openssl/crypto/des/times/aix.cc
@@ -0,0 +1,26 @@
+From: Paco Garcia <pgarcia@cam.es>
+
+This machine is a Bull Estrella  Minitower Model MT604-100
+Processor        : PPC604 
+P.Speed          : 100Mhz 
+Data/Instr Cache :    16 K
+L2 Cache         :   256 K
+PCI BUS Speed    :    33 Mhz
+TransfRate PCI   :   132 MB/s
+Memory           :    96 MB
+
+options    des ecb/s       
+ 4  c p    275118.61 100.0%
+ 4  c i    273545.07  99.4%
+ 4 r2 p    270441.02  98.3%
+ 4 r1 p    253052.15  92.0%
+ 4 r2 i    240842.97  87.5%
+ 4 r1 i    240556.66  87.4%
+16  c i    224603.99  81.6%
+16  c p    224483.98  81.6%
+16 r2 p    215691.19  78.4%
+16 r1 p    208332.83  75.7%
+16 r1 i    199206.50  72.4%
+16 r2 i    198963.70  72.3%
+-DDES_PTR
+
diff --git a/openssl/crypto/des/times/alpha.cc b/openssl/crypto/des/times/alpha.cc
new file mode 100644
index 0000000..95c17ef
--- /dev/null
+++ b/openssl/crypto/des/times/alpha.cc
@@ -0,0 +1,18 @@
+cc -O2
+DES_LONG is 'unsigned int'
+
+options    des ecb/s
+ 4 r2 p    181146.14 100.0%
+16 r2 p    172102.94  95.0%
+ 4 r2 i    165424.11  91.3%
+16  c p    160468.64  88.6%
+ 4  c p    156653.59  86.5%
+ 4  c i    155245.18  85.7%
+ 4 r1 p    154729.68  85.4%
+16 r2 i    154137.69  85.1%
+16 r1 p    152357.96  84.1%
+16  c i    148743.91  82.1%
+ 4 r1 i    146695.59  81.0%
+16 r1 i    144961.00  80.0%
+-DDES_RISC2 -DDES_PTR
+
diff --git a/openssl/crypto/des/times/hpux.cc b/openssl/crypto/des/times/hpux.cc
new file mode 100644
index 0000000..3de856d
--- /dev/null
+++ b/openssl/crypto/des/times/hpux.cc
@@ -0,0 +1,17 @@
+HPUX 10 - 9000/887 - cc -D_HPUX_SOURCE -Aa +ESlit +O2 -Wl,-a,archive
+
+options    des ecb/s
+16  c i    149448.90 100.0%
+ 4  c i    145861.79  97.6%
+16 r2 i    141710.96  94.8%
+16 r1 i    139455.33  93.3%
+ 4 r2 i    138800.00  92.9%
+ 4 r1 i    136692.65  91.5%
+16 r2 p    110228.17  73.8%
+16 r1 p    109397.07  73.2%
+16  c p    109209.89  73.1%
+ 4  c p    108014.71  72.3%
+ 4 r2 p    107873.88  72.2%
+ 4 r1 p    107685.83  72.1%
+-DDES_UNROLL
+
diff --git a/openssl/crypto/des/times/sparc.gcc b/openssl/crypto/des/times/sparc.gcc
new file mode 100644
index 0000000..8eaa042
--- /dev/null
+++ b/openssl/crypto/des/times/sparc.gcc
@@ -0,0 +1,17 @@
+solaris 2.5.1 - sparc 10 50mhz - gcc 2.7.2
+
+options    des ecb/s
+16  c i    124382.70 100.0%
+ 4  c i    118884.68  95.6%
+16  c p    112261.20  90.3%
+16 r2 i    111777.10  89.9%
+16 r2 p    108896.30  87.5%
+16 r1 p    108791.59  87.5%
+ 4  c p    107290.10  86.3%
+ 4 r1 p    104583.80  84.1%
+16 r1 i    104206.20  83.8%
+ 4 r2 p    103709.80  83.4%
+ 4 r2 i     98306.43  79.0%
+ 4 r1 i     91525.80  73.6%
+-DDES_UNROLL
+      
diff --git a/openssl/crypto/des/times/usparc.cc b/openssl/crypto/des/times/usparc.cc
new file mode 100644
index 0000000..0864285
--- /dev/null
+++ b/openssl/crypto/des/times/usparc.cc
@@ -0,0 +1,31 @@
+solaris 2.5.1 usparc 167mhz?? - SC4.0 cc -fast -Xa -xO5
+
+For the ultra sparc, SunC 4.0 cc -fast -Xa -xO5, running 'des_opts'
+gives a speed of 475,000 des/s while 'speed' gives 417,000 des/s.
+I believe the difference is tied up in optimisation that the compiler
+is able to perform when the code is 'inlined'.  For 'speed', the DES
+routines are being linked from a library.  I'll record the higher
+speed since if performance is everything, you can always inline
+'des_enc.c'.
+
+[ 16-Jan-06 - I've been playing with the
+  '-xtarget=ultra -xarch=v8plus -Xa -xO5 -Xa'
+  and while it makes the des_opts numbers much slower, it makes the
+  actual 'speed' numbers look better which is a realistic version of
+  using the libraries. ]
+
+options    des ecb/s
+16 r1 p    475516.90 100.0%
+16 r2 p    439388.10  92.4%
+16  c i    427001.40  89.8%
+16  c p    419516.50  88.2%
+ 4 r2 p    409491.70  86.1%
+ 4 r1 p    404266.90  85.0%
+ 4  c p    398121.00  83.7%
+ 4  c i    370588.40  77.9%
+ 4 r1 i    362742.20  76.3%
+16 r2 i    331275.50  69.7%
+16 r1 i    324730.60  68.3%
+ 4 r2 i     63535.10  13.4%	<-- very very weird, must be cache problems.
+-DDES_UNROLL -DDES_RISC1 -DDES_PTR
+
diff --git a/openssl/crypto/des/typemap b/openssl/crypto/des/typemap
new file mode 100644
index 0000000..a524f53
--- /dev/null
+++ b/openssl/crypto/des/typemap
@@ -0,0 +1,34 @@
+#
+# DES SECTION
+#
+deschar *	T_DESCHARP
+des_cblock *	T_CBLOCK
+des_cblock	T_CBLOCK
+des_key_schedule	T_SCHEDULE
+des_key_schedule *	T_SCHEDULE
+
+INPUT
+T_CBLOCK
+	$var=(des_cblock *)SvPV($arg,len);
+	if (len < DES_KEY_SZ)
+		{
+		croak(\"$var needs to be at least %u bytes long\",DES_KEY_SZ);
+		}
+
+T_SCHEDULE
+	$var=(des_key_schedule *)SvPV($arg,len);
+	if (len < DES_SCHEDULE_SZ)
+		{
+		croak(\"$var needs to be at least %u bytes long\",
+			DES_SCHEDULE_SZ);
+		}
+
+OUTPUT
+T_CBLOCK
+	sv_setpvn($arg,(char *)$var,DES_KEY_SZ);
+
+T_SCHEDULE
+	sv_setpvn($arg,(char *)$var,DES_SCHEDULE_SZ);
+
+T_DESCHARP
+	sv_setpvn($arg,(char *)$var,len);
diff --git a/openssl/crypto/des/xcbc_enc.c b/openssl/crypto/des/xcbc_enc.c
new file mode 100644
index 0000000..058cab6
--- /dev/null
+++ b/openssl/crypto/des/xcbc_enc.c
@@ -0,0 +1,197 @@
+/* crypto/des/xcbc_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+/* RSA's DESX */
+
+#if 0 /* broken code, preserved just in case anyone specifically looks for this */
+static const unsigned char desx_white_in2out[256]={
+0xBD,0x56,0xEA,0xF2,0xA2,0xF1,0xAC,0x2A,0xB0,0x93,0xD1,0x9C,0x1B,0x33,0xFD,0xD0,
+0x30,0x04,0xB6,0xDC,0x7D,0xDF,0x32,0x4B,0xF7,0xCB,0x45,0x9B,0x31,0xBB,0x21,0x5A,
+0x41,0x9F,0xE1,0xD9,0x4A,0x4D,0x9E,0xDA,0xA0,0x68,0x2C,0xC3,0x27,0x5F,0x80,0x36,
+0x3E,0xEE,0xFB,0x95,0x1A,0xFE,0xCE,0xA8,0x34,0xA9,0x13,0xF0,0xA6,0x3F,0xD8,0x0C,
+0x78,0x24,0xAF,0x23,0x52,0xC1,0x67,0x17,0xF5,0x66,0x90,0xE7,0xE8,0x07,0xB8,0x60,
+0x48,0xE6,0x1E,0x53,0xF3,0x92,0xA4,0x72,0x8C,0x08,0x15,0x6E,0x86,0x00,0x84,0xFA,
+0xF4,0x7F,0x8A,0x42,0x19,0xF6,0xDB,0xCD,0x14,0x8D,0x50,0x12,0xBA,0x3C,0x06,0x4E,
+0xEC,0xB3,0x35,0x11,0xA1,0x88,0x8E,0x2B,0x94,0x99,0xB7,0x71,0x74,0xD3,0xE4,0xBF,
+0x3A,0xDE,0x96,0x0E,0xBC,0x0A,0xED,0x77,0xFC,0x37,0x6B,0x03,0x79,0x89,0x62,0xC6,
+0xD7,0xC0,0xD2,0x7C,0x6A,0x8B,0x22,0xA3,0x5B,0x05,0x5D,0x02,0x75,0xD5,0x61,0xE3,
+0x18,0x8F,0x55,0x51,0xAD,0x1F,0x0B,0x5E,0x85,0xE5,0xC2,0x57,0x63,0xCA,0x3D,0x6C,
+0xB4,0xC5,0xCC,0x70,0xB2,0x91,0x59,0x0D,0x47,0x20,0xC8,0x4F,0x58,0xE0,0x01,0xE2,
+0x16,0x38,0xC4,0x6F,0x3B,0x0F,0x65,0x46,0xBE,0x7E,0x2D,0x7B,0x82,0xF9,0x40,0xB5,
+0x1D,0x73,0xF8,0xEB,0x26,0xC7,0x87,0x97,0x25,0x54,0xB1,0x28,0xAA,0x98,0x9D,0xA5,
+0x64,0x6D,0x7A,0xD4,0x10,0x81,0x44,0xEF,0x49,0xD6,0xAE,0x2E,0xDD,0x76,0x5C,0x2F,
+0xA7,0x1C,0xC9,0x09,0x69,0x9A,0x83,0xCF,0x29,0x39,0xB9,0xE9,0x4C,0xFF,0x43,0xAB,
+	};
+
+void DES_xwhite_in2out(const_DES_cblock *des_key, const_DES_cblock *in_white,
+	     DES_cblock *out_white)
+	{
+	int out0,out1;
+	int i;
+	const unsigned char *key = &(*des_key)[0];
+	const unsigned char *in = &(*in_white)[0];
+	unsigned char *out = &(*out_white)[0];
+
+	out[0]=out[1]=out[2]=out[3]=out[4]=out[5]=out[6]=out[7]=0;
+	out0=out1=0;
+	for (i=0; i<8; i++)
+		{
+		out[i]=key[i]^desx_white_in2out[out0^out1];
+		out0=out1;
+		out1=(int)out[i&0x07];
+		}
+
+	out0=out[0];
+	out1=out[i]; /* BUG: out-of-bounds read */
+	for (i=0; i<8; i++)
+		{
+		out[i]=in[i]^desx_white_in2out[out0^out1];
+		out0=out1;
+		out1=(int)out[i&0x07];
+		}
+	}
+#endif
+
+void DES_xcbc_encrypt(const unsigned char *in, unsigned char *out,
+		      long length, DES_key_schedule *schedule,
+		      DES_cblock *ivec, const_DES_cblock *inw,
+		      const_DES_cblock *outw, int enc)
+	{
+	register DES_LONG tin0,tin1;
+	register DES_LONG tout0,tout1,xor0,xor1;
+	register DES_LONG inW0,inW1,outW0,outW1;
+	register const unsigned char *in2;
+	register long l=length;
+	DES_LONG tin[2];
+	unsigned char *iv;
+
+	in2 = &(*inw)[0];
+	c2l(in2,inW0);
+	c2l(in2,inW1);
+	in2 = &(*outw)[0];
+	c2l(in2,outW0);
+	c2l(in2,outW1);
+
+	iv = &(*ivec)[0];
+
+	if (enc)
+		{
+		c2l(iv,tout0);
+		c2l(iv,tout1);
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0);
+			c2l(in,tin1);
+			tin0^=tout0^inW0; tin[0]=tin0;
+			tin1^=tout1^inW1; tin[1]=tin1;
+			DES_encrypt1(tin,schedule,DES_ENCRYPT);
+			tout0=tin[0]^outW0; l2c(tout0,out);
+			tout1=tin[1]^outW1; l2c(tout1,out);
+			}
+		if (l != -8)
+			{
+			c2ln(in,tin0,tin1,l+8);
+			tin0^=tout0^inW0; tin[0]=tin0;
+			tin1^=tout1^inW1; tin[1]=tin1;
+			DES_encrypt1(tin,schedule,DES_ENCRYPT);
+			tout0=tin[0]^outW0; l2c(tout0,out);
+			tout1=tin[1]^outW1; l2c(tout1,out);
+			}
+		iv = &(*ivec)[0];
+		l2c(tout0,iv);
+		l2c(tout1,iv);
+		}
+	else
+		{
+		c2l(iv,xor0);
+		c2l(iv,xor1);
+		for (l-=8; l>0; l-=8)
+			{
+			c2l(in,tin0); tin[0]=tin0^outW0;
+			c2l(in,tin1); tin[1]=tin1^outW1;
+			DES_encrypt1(tin,schedule,DES_DECRYPT);
+			tout0=tin[0]^xor0^inW0;
+			tout1=tin[1]^xor1^inW1;
+			l2c(tout0,out);
+			l2c(tout1,out);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		if (l != -8)
+			{
+			c2l(in,tin0); tin[0]=tin0^outW0;
+			c2l(in,tin1); tin[1]=tin1^outW1;
+			DES_encrypt1(tin,schedule,DES_DECRYPT);
+			tout0=tin[0]^xor0^inW0;
+			tout1=tin[1]^xor1^inW1;
+			l2cn(tout0,tout1,out,l+8);
+			xor0=tin0;
+			xor1=tin1;
+			}
+
+		iv = &(*ivec)[0];
+		l2c(xor0,iv);
+		l2c(xor1,iv);
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	inW0=inW1=outW0=outW1=0;
+	tin[0]=tin[1]=0;
+	}
+
diff --git a/openssl/crypto/dh/Makefile b/openssl/crypto/dh/Makefile
new file mode 100644
index 0000000..f23b4f7
--- /dev/null
+++ b/openssl/crypto/dh/Makefile
@@ -0,0 +1,180 @@
+#
+# OpenSSL/crypto/dh/Makefile
+#
+
+DIR=	dh
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST= dhtest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= dh_asn1.c dh_gen.c dh_key.c dh_lib.c dh_check.c dh_err.c dh_depr.c \
+	dh_ameth.c dh_pmeth.c dh_prn.c
+LIBOBJ= dh_asn1.o dh_gen.o dh_key.o dh_lib.o dh_check.o dh_err.o dh_depr.o \
+	dh_ameth.o dh_pmeth.o dh_prn.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= dh.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+dh_ameth.o: ../../e_os.h ../../include/openssl/asn1.h
+dh_ameth.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+dh_ameth.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dh_ameth.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
+dh_ameth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+dh_ameth.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+dh_ameth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+dh_ameth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+dh_ameth.o: ../../include/openssl/opensslconf.h
+dh_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dh_ameth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+dh_ameth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dh_ameth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+dh_ameth.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
+dh_ameth.o: dh_ameth.c
+dh_asn1.o: ../../e_os.h ../../include/openssl/asn1.h
+dh_asn1.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+dh_asn1.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+dh_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+dh_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+dh_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+dh_asn1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+dh_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dh_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dh_asn1.o: ../../include/openssl/symhacks.h ../cryptlib.h dh_asn1.c
+dh_check.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+dh_check.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dh_check.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
+dh_check.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dh_check.o: ../../include/openssl/opensslconf.h
+dh_check.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dh_check.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dh_check.o: ../../include/openssl/symhacks.h ../cryptlib.h dh_check.c
+dh_depr.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+dh_depr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dh_depr.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
+dh_depr.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dh_depr.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dh_depr.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+dh_depr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dh_depr.o: ../cryptlib.h dh_depr.c
+dh_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+dh_err.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
+dh_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dh_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dh_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+dh_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dh_err.o: dh_err.c
+dh_gen.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+dh_gen.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dh_gen.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
+dh_gen.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dh_gen.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dh_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+dh_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dh_gen.o: ../cryptlib.h dh_gen.c
+dh_key.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+dh_key.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dh_key.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
+dh_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dh_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dh_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+dh_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dh_key.o: ../../include/openssl/symhacks.h ../cryptlib.h dh_key.c
+dh_lib.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+dh_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+dh_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+dh_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+dh_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+dh_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+dh_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+dh_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+dh_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dh_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+dh_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+dh_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dh_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+dh_lib.o: ../cryptlib.h dh_lib.c
+dh_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
+dh_pmeth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+dh_pmeth.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+dh_pmeth.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+dh_pmeth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+dh_pmeth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+dh_pmeth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+dh_pmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+dh_pmeth.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+dh_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dh_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+dh_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dh_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+dh_pmeth.o: ../../include/openssl/x509_vfy.h ../cryptlib.h ../evp/evp_locl.h
+dh_pmeth.o: dh_pmeth.c
+dh_prn.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+dh_prn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dh_prn.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
+dh_prn.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+dh_prn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+dh_prn.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+dh_prn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dh_prn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dh_prn.o: ../../include/openssl/symhacks.h ../cryptlib.h dh_prn.c
diff --git a/openssl/crypto/dh/dh.h b/openssl/crypto/dh/dh.h
new file mode 100644
index 0000000..849309a
--- /dev/null
+++ b/openssl/crypto/dh/dh.h
@@ -0,0 +1,260 @@
+/* crypto/dh/dh.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_DH_H
+#define HEADER_DH_H
+
+#include <openssl/e_os2.h>
+
+#ifdef OPENSSL_NO_DH
+#error DH is disabled.
+#endif
+
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#include <openssl/ossl_typ.h>
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#endif
+	
+#ifndef OPENSSL_DH_MAX_MODULUS_BITS
+# define OPENSSL_DH_MAX_MODULUS_BITS	10000
+#endif
+
+#define DH_FLAG_CACHE_MONT_P     0x01
+#define DH_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DH
+                                       * implementation now uses constant time
+                                       * modular exponentiation for secret exponents
+                                       * by default. This flag causes the
+                                       * faster variable sliding window method to
+                                       * be used for all exponents.
+                                       */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct dh_st DH; */
+/* typedef struct dh_method DH_METHOD; */
+
+struct dh_method
+	{
+	const char *name;
+	/* Methods here */
+	int (*generate_key)(DH *dh);
+	int (*compute_key)(unsigned char *key,const BIGNUM *pub_key,DH *dh);
+	int (*bn_mod_exp)(const DH *dh, BIGNUM *r, const BIGNUM *a,
+				const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+				BN_MONT_CTX *m_ctx); /* Can be null */
+
+	int (*init)(DH *dh);
+	int (*finish)(DH *dh);
+	int flags;
+	char *app_data;
+	/* If this is non-NULL, it will be used to generate parameters */
+	int (*generate_params)(DH *dh, int prime_len, int generator, BN_GENCB *cb);
+	};
+
+struct dh_st
+	{
+	/* This first argument is used to pick up errors when
+	 * a DH is passed instead of a EVP_PKEY */
+	int pad;
+	int version;
+	BIGNUM *p;
+	BIGNUM *g;
+	long length; /* optional */
+	BIGNUM *pub_key;	/* g^x */
+	BIGNUM *priv_key;	/* x */
+
+	int flags;
+	BN_MONT_CTX *method_mont_p;
+	/* Place holders if we want to do X9.42 DH */
+	BIGNUM *q;
+	BIGNUM *j;
+	unsigned char *seed;
+	int seedlen;
+	BIGNUM *counter;
+
+	int references;
+	CRYPTO_EX_DATA ex_data;
+	const DH_METHOD *meth;
+	ENGINE *engine;
+	};
+
+#define DH_GENERATOR_2		2
+/* #define DH_GENERATOR_3	3 */
+#define DH_GENERATOR_5		5
+
+/* DH_check error codes */
+#define DH_CHECK_P_NOT_PRIME		0x01
+#define DH_CHECK_P_NOT_SAFE_PRIME	0x02
+#define DH_UNABLE_TO_CHECK_GENERATOR	0x04
+#define DH_NOT_SUITABLE_GENERATOR	0x08
+
+/* DH_check_pub_key error codes */
+#define DH_CHECK_PUBKEY_TOO_SMALL	0x01
+#define DH_CHECK_PUBKEY_TOO_LARGE	0x02
+
+/* primes p where (p-1)/2 is prime too are called "safe"; we define
+   this for backward compatibility: */
+#define DH_CHECK_P_NOT_STRONG_PRIME	DH_CHECK_P_NOT_SAFE_PRIME
+
+#define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
+		(char *(*)())d2i_DHparams,(fp),(unsigned char **)(x))
+#define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \
+		(unsigned char *)(x))
+#define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x)
+#define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x)
+
+DH *DHparams_dup(DH *);
+
+const DH_METHOD *DH_OpenSSL(void);
+
+void DH_set_default_method(const DH_METHOD *meth);
+const DH_METHOD *DH_get_default_method(void);
+int DH_set_method(DH *dh, const DH_METHOD *meth);
+DH *DH_new_method(ENGINE *engine);
+
+DH *	DH_new(void);
+void	DH_free(DH *dh);
+int	DH_up_ref(DH *dh);
+int	DH_size(const DH *dh);
+int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int DH_set_ex_data(DH *d, int idx, void *arg);
+void *DH_get_ex_data(DH *d, int idx);
+
+/* Deprecated version */
+#ifndef OPENSSL_NO_DEPRECATED
+DH *	DH_generate_parameters(int prime_len,int generator,
+		void (*callback)(int,int,void *),void *cb_arg);
+#endif /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* New version */
+int	DH_generate_parameters_ex(DH *dh, int prime_len,int generator, BN_GENCB *cb);
+
+int	DH_check(const DH *dh,int *codes);
+int	DH_check_pub_key(const DH *dh,const BIGNUM *pub_key, int *codes);
+int	DH_generate_key(DH *dh);
+int	DH_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh);
+DH *	d2i_DHparams(DH **a,const unsigned char **pp, long length);
+int	i2d_DHparams(const DH *a,unsigned char **pp);
+#ifndef OPENSSL_NO_FP_API
+int	DHparams_print_fp(FILE *fp, const DH *x);
+#endif
+#ifndef OPENSSL_NO_BIO
+int	DHparams_print(BIO *bp, const DH *x);
+#else
+int	DHparams_print(char *bp, const DH *x);
+#endif
+
+#define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+			EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL)
+
+#define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+			EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL)
+
+#define	EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN	(EVP_PKEY_ALG_CTRL + 1)
+#define	EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR	(EVP_PKEY_ALG_CTRL + 2)
+		
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_DH_strings(void);
+
+/* Error codes for the DH functions. */
+
+/* Function codes. */
+#define DH_F_COMPUTE_KEY				 102
+#define DH_F_DHPARAMS_PRINT_FP				 101
+#define DH_F_DH_BUILTIN_GENPARAMS			 106
+#define DH_F_DH_NEW_METHOD				 105
+#define DH_F_DH_PARAM_DECODE				 107
+#define DH_F_DH_PRIV_DECODE				 110
+#define DH_F_DH_PRIV_ENCODE				 111
+#define DH_F_DH_PUB_DECODE				 108
+#define DH_F_DH_PUB_ENCODE				 109
+#define DH_F_DO_DH_PRINT				 100
+#define DH_F_GENERATE_KEY				 103
+#define DH_F_GENERATE_PARAMETERS			 104
+#define DH_F_PKEY_DH_DERIVE				 112
+#define DH_F_PKEY_DH_KEYGEN				 113
+
+/* Reason codes. */
+#define DH_R_BAD_GENERATOR				 101
+#define DH_R_BN_DECODE_ERROR				 109
+#define DH_R_BN_ERROR					 106
+#define DH_R_DECODE_ERROR				 104
+#define DH_R_INVALID_PUBKEY				 102
+#define DH_R_KEYS_NOT_SET				 108
+#define DH_R_MODULUS_TOO_LARGE				 103
+#define DH_R_NO_PARAMETERS_SET				 107
+#define DH_R_NO_PRIVATE_VALUE				 100
+#define DH_R_PARAMETER_ENCODING_ERROR			 105
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/dh/dh1024.pem b/openssl/crypto/dh/dh1024.pem
new file mode 100644
index 0000000..81d43f6
--- /dev/null
+++ b/openssl/crypto/dh/dh1024.pem
@@ -0,0 +1,5 @@
+-----BEGIN DH PARAMETERS-----
+MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq
+/Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx
+/mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC
+-----END DH PARAMETERS-----
diff --git a/openssl/crypto/dh/dh192.pem b/openssl/crypto/dh/dh192.pem
new file mode 100644
index 0000000..521c072
--- /dev/null
+++ b/openssl/crypto/dh/dh192.pem
@@ -0,0 +1,3 @@
+-----BEGIN DH PARAMETERS-----
+MB4CGQDUoLoCULb9LsYm5+/WN992xxbiLQlEuIsCAQM=
+-----END DH PARAMETERS-----
diff --git a/openssl/crypto/dh/dh2048.pem b/openssl/crypto/dh/dh2048.pem
new file mode 100644
index 0000000..295460f
--- /dev/null
+++ b/openssl/crypto/dh/dh2048.pem
@@ -0,0 +1,16 @@
+-----BEGIN DH PARAMETERS-----
+MIIBCAKCAQEA7ZKJNYJFVcs7+6J2WmkEYb8h86tT0s0h2v94GRFS8Q7B4lW9aG9o
+AFO5Imov5Jo0H2XMWTKKvbHbSe3fpxJmw/0hBHAY8H/W91hRGXKCeyKpNBgdL8sh
+z22SrkO2qCnHJ6PLAMXy5fsKpFmFor2tRfCzrfnggTXu2YOzzK7q62bmqVdmufEo
+pT8igNcLpvZxk5uBDvhakObMym9mX3rAEBoe8PwttggMYiiw7NuJKO4MqD1llGkW
+aVM8U2ATsCun1IKHrRxynkE1/MJ86VHeYYX8GZt2YA8z+GuzylIOKcMH6JAWzMwA
+Gbatw6QwizOhr9iMjZ0B26TE3X8LvW84wwIBAg==
+-----END DH PARAMETERS-----
+-----BEGIN DH PARAMETERS-----
+MIIBCAKCAQEArtA3w73zP6Lu3EOQtwogiXt3AXXpuS6yD4BhzNS1pZFyPHk0/an5
+8ydEkPhQZHKDW+BZJxxPLANaTudWo2YT8TgtvUdN6KSgMiEi6McwqDw+SADuvW+F
+SKUYFxG6VFIxyEP6xBdf+vhJxEDbRG2EYsHDRRtJ76gp9cSKTHusf2R+4AAVGqnt
+gRAbNqtcOar/7FSj+Pl8G3v0Bty0LcCSpbqgYlnv6z+rErQmmC6PPvSz97TDMCok
+yKpCE9hFA1zkqK3TH4FmFvGeIaXJUIBZf4mArWuBTjWFW3nmhESRUn1VK3K3x42N
+a5k6c2+EhrMFiLjxuH6JZoqL0/E93FF9SwIBAg==
+-----END DH PARAMETERS-----
diff --git a/openssl/crypto/dh/dh4096.pem b/openssl/crypto/dh/dh4096.pem
new file mode 100644
index 0000000..390943a
--- /dev/null
+++ b/openssl/crypto/dh/dh4096.pem
@@ -0,0 +1,14 @@
+-----BEGIN DH PARAMETERS-----
+MIICCAKCAgEA/urRnb6vkPYc/KEGXWnbCIOaKitq7ySIq9dTH7s+Ri59zs77zty7
+vfVlSe6VFTBWgYjD2XKUFmtqq6CqXMhVX5ElUDoYDpAyTH85xqNFLzFC7nKrff/H
+TFKNttp22cZE9V0IPpzedPfnQkE7aUdmF9JnDyv21Z/818O93u1B4r0szdnmEvEF
+bKuIxEHX+bp0ZR7RqE1AeifXGJX3d6tsd2PMAObxwwsv55RGkn50vHO4QxtTARr1
+rRUV5j3B3oPMgC7Offxx+98Xn45B1/G0Prp11anDsR1PGwtaCYipqsvMwQUSJtyE
+EOQWk+yFkeMe4vWv367eEi0Sd/wnC+TSXBE3pYvpYerJ8n1MceI5GQTdarJ77OW9
+bGTHmxRsLSCM1jpLdPja5jjb4siAa6EHc4qN9c/iFKS3PQPJEnX7pXKBRs5f7AF3
+W3RIGt+G9IVNZfXaS7Z/iCpgzgvKCs0VeqN38QsJGtC1aIkwOeyjPNy2G6jJ4yqH
+ovXYt/0mc00vCWeSNS1wren0pR2EiLxX0ypjjgsU1mk/Z3b/+zVf7fZSIB+nDLjb
+NPtUlJCVGnAeBK1J1nG3TQicqowOXoM6ISkdaXj5GPJdXHab2+S7cqhKGv5qC7rR
+jT6sx7RUr0CNTxzLI7muV2/a4tGmj0PSdXQdsZ7tw7gbXlaWT1+MM2MCAQI=
+-----END DH PARAMETERS-----
+
diff --git a/openssl/crypto/dh/dh512.pem b/openssl/crypto/dh/dh512.pem
new file mode 100644
index 0000000..0a4d863
--- /dev/null
+++ b/openssl/crypto/dh/dh512.pem
@@ -0,0 +1,4 @@
+-----BEGIN DH PARAMETERS-----
+MEYCQQDaWDwW2YUiidDkr3VvTMqS3UvlM7gE+w/tlO+cikQD7VdGUNNpmdsp13Yn
+a6LT1BLiGPTdHghM9tgAPnxHdOgzAgEC
+-----END DH PARAMETERS-----
diff --git a/openssl/crypto/dh/dh_ameth.c b/openssl/crypto/dh/dh_ameth.c
new file mode 100644
index 0000000..377caf9
--- /dev/null
+++ b/openssl/crypto/dh/dh_ameth.c
@@ -0,0 +1,500 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/dh.h>
+#include <openssl/bn.h>
+#include "asn1_locl.h"
+
+static void int_dh_free(EVP_PKEY *pkey)
+	{
+	DH_free(pkey->pkey.dh);
+	}
+
+static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+	{
+	const unsigned char *p, *pm;
+	int pklen, pmlen;
+	int ptype;
+	void *pval;
+	ASN1_STRING *pstr;
+	X509_ALGOR *palg;
+	ASN1_INTEGER *public_key = NULL;
+
+	DH *dh = NULL;
+
+	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
+		return 0;
+	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+	if (ptype != V_ASN1_SEQUENCE)
+		{
+		DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR);
+		goto err;
+		}
+
+	pstr = pval;	
+	pm = pstr->data;
+	pmlen = pstr->length;
+
+	if (!(dh = d2i_DHparams(NULL, &pm, pmlen)))
+		{
+		DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
+		goto err;
+		}
+
+	if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen)))
+		{
+		DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
+		goto err;
+		}
+
+	/* We have parameters now set public key */
+	if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
+		{
+		DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR);
+		goto err;
+		}
+
+	ASN1_INTEGER_free(public_key);
+	EVP_PKEY_assign_DH(pkey, dh);
+	return 1;
+
+	err:
+	if (public_key)
+		ASN1_INTEGER_free(public_key);
+	if (dh)
+		DH_free(dh);
+	return 0;
+
+	}
+
+static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+	{
+	DH *dh;
+	void *pval = NULL;
+	int ptype;
+	unsigned char *penc = NULL;
+	int penclen;
+	ASN1_STRING *str;
+	ASN1_INTEGER *pub_key = NULL;
+
+	dh=pkey->pkey.dh;
+
+	str = ASN1_STRING_new();
+	str->length = i2d_DHparams(dh, &str->data);
+	if (str->length <= 0)
+		{
+		DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	pval = str;
+	ptype = V_ASN1_SEQUENCE;
+
+	pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL);
+	if (!pub_key)
+		goto err;
+
+	penclen = i2d_ASN1_INTEGER(pub_key, &penc);
+
+	ASN1_INTEGER_free(pub_key);
+
+	if (penclen <= 0)
+		{
+		DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DH),
+				ptype, pval, penc, penclen))
+		return 1;
+
+	err:
+	if (penc)
+		OPENSSL_free(penc);
+	if (pval)
+		ASN1_STRING_free(pval);
+
+	return 0;
+	}
+
+
+/* PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in
+ * that the AlgorithmIdentifier contains the paramaters, the private key
+ * is explcitly included and the pubkey must be recalculated.
+ */
+	
+static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
+	{
+	const unsigned char *p, *pm;
+	int pklen, pmlen;
+	int ptype;
+	void *pval;
+	ASN1_STRING *pstr;
+	X509_ALGOR *palg;
+	ASN1_INTEGER *privkey = NULL;
+
+	DH *dh = NULL;
+
+	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
+		return 0;
+
+	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+	if (ptype != V_ASN1_SEQUENCE)
+			goto decerr;
+
+	if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
+		goto decerr;
+
+
+	pstr = pval;	
+	pm = pstr->data;
+	pmlen = pstr->length;
+	if (!(dh = d2i_DHparams(NULL, &pm, pmlen)))
+		goto decerr;
+	/* We have parameters now set private key */
+	if (!(dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)))
+		{
+		DHerr(DH_F_DH_PRIV_DECODE,DH_R_BN_ERROR);
+		goto dherr;
+		}
+	/* Calculate public key */
+	if (!DH_generate_key(dh))
+		goto dherr;
+
+	EVP_PKEY_assign_DH(pkey, dh);
+
+	ASN1_INTEGER_free(privkey);
+
+	return 1;
+
+	decerr:
+	DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR);
+	dherr:
+	DH_free(dh);
+	return 0;
+	}
+
+static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+{
+	ASN1_STRING *params = NULL;
+	ASN1_INTEGER *prkey = NULL;
+	unsigned char *dp = NULL;
+	int dplen;
+
+	params = ASN1_STRING_new();
+
+	if (!params)
+		{
+		DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	params->length = i2d_DHparams(pkey->pkey.dh, &params->data);
+	if (params->length <= 0)
+		{
+		DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	params->type = V_ASN1_SEQUENCE;
+
+	/* Get private key into integer */
+	prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL);
+
+	if (!prkey)
+		{
+		DHerr(DH_F_DH_PRIV_ENCODE,DH_R_BN_ERROR);
+		goto err;
+		}
+
+	dplen = i2d_ASN1_INTEGER(prkey, &dp);
+
+	ASN1_INTEGER_free(prkey);
+
+	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dhKeyAgreement), 0,
+				V_ASN1_SEQUENCE, params, dp, dplen))
+		goto err;
+
+	return 1;
+
+err:
+	if (dp != NULL)
+		OPENSSL_free(dp);
+	if (params != NULL)
+		ASN1_STRING_free(params);
+	if (prkey != NULL)
+		ASN1_INTEGER_free(prkey);
+	return 0;
+}
+
+
+static void update_buflen(const BIGNUM *b, size_t *pbuflen)
+	{
+	size_t i;
+	if (!b)
+		return;
+	if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
+			*pbuflen = i;
+	}
+
+static int dh_param_decode(EVP_PKEY *pkey,
+					const unsigned char **pder, int derlen)
+	{
+	DH *dh;
+	if (!(dh = d2i_DHparams(NULL, pder, derlen)))
+		{
+		DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB);
+		return 0;
+		}
+	EVP_PKEY_assign_DH(pkey, dh);
+	return 1;
+	}
+
+static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+	{
+	return i2d_DHparams(pkey->pkey.dh, pder);
+	}
+
+static int do_dh_print(BIO *bp, const DH *x, int indent,
+						ASN1_PCTX *ctx, int ptype)
+	{
+	unsigned char *m=NULL;
+	int reason=ERR_R_BUF_LIB,ret=0;
+	size_t buf_len=0;
+
+	const char *ktype = NULL;
+
+	BIGNUM *priv_key, *pub_key;
+
+	if (ptype == 2)
+		priv_key = x->priv_key;
+	else
+		priv_key = NULL;
+
+	if (ptype > 0)
+		pub_key = x->pub_key;
+	else
+		pub_key = NULL;
+
+	update_buflen(x->p, &buf_len);
+
+	if (buf_len == 0)
+		{
+		reason = ERR_R_PASSED_NULL_PARAMETER;
+		goto err;
+		}
+
+	update_buflen(x->g, &buf_len);
+	update_buflen(pub_key, &buf_len);
+	update_buflen(priv_key, &buf_len);
+
+	if (ptype == 2)
+		ktype = "PKCS#3 DH Private-Key";
+	else if (ptype == 1)
+		ktype = "PKCS#3 DH Public-Key";
+	else
+		ktype = "PKCS#3 DH Parameters";
+
+	m= OPENSSL_malloc(buf_len+10);
+	if (m == NULL)
+		{
+		reason=ERR_R_MALLOC_FAILURE;
+		goto err;
+		}
+
+	BIO_indent(bp, indent, 128);
+	if (BIO_printf(bp,"%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0)
+		goto err;
+	indent += 4;
+
+	if (!ASN1_bn_print(bp,"private-key:",priv_key,m,indent)) goto err;
+	if (!ASN1_bn_print(bp,"public-key:",pub_key,m,indent)) goto err;
+
+	if (!ASN1_bn_print(bp,"prime:",x->p,m,indent)) goto err;
+	if (!ASN1_bn_print(bp,"generator:",x->g,m,indent)) goto err;
+	if (x->length != 0)
+		{
+		BIO_indent(bp, indent, 128);
+		if (BIO_printf(bp,"recommended-private-length: %d bits\n",
+			(int)x->length) <= 0) goto err;
+		}
+
+
+	ret=1;
+	if (0)
+		{
+err:
+		DHerr(DH_F_DO_DH_PRINT,reason);
+		}
+	if (m != NULL) OPENSSL_free(m);
+	return(ret);
+	}
+
+static int int_dh_size(const EVP_PKEY *pkey)
+	{
+	return(DH_size(pkey->pkey.dh));
+	}
+
+static int dh_bits(const EVP_PKEY *pkey)
+	{
+	return BN_num_bits(pkey->pkey.dh->p);
+	}
+
+static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+	{
+	if (	BN_cmp(a->pkey.dh->p,b->pkey.dh->p) ||
+		BN_cmp(a->pkey.dh->g,b->pkey.dh->g))
+		return 0;
+	else
+		return 1;
+	}
+
+static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+	{
+	BIGNUM *a;
+
+	if ((a=BN_dup(from->pkey.dh->p)) == NULL)
+		return 0;
+	if (to->pkey.dh->p != NULL)
+		BN_free(to->pkey.dh->p);
+	to->pkey.dh->p=a;
+
+	if ((a=BN_dup(from->pkey.dh->g)) == NULL)
+		return 0;
+	if (to->pkey.dh->g != NULL)
+		BN_free(to->pkey.dh->g);
+	to->pkey.dh->g=a;
+
+	return 1;
+	}
+
+static int dh_missing_parameters(const EVP_PKEY *a)
+	{
+	if (!a->pkey.dh->p || !a->pkey.dh->g)
+		return 1;
+	return 0;
+	}
+
+static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+	{
+	if (dh_cmp_parameters(a, b) == 0)
+		return 0;
+	if (BN_cmp(b->pkey.dh->pub_key,a->pkey.dh->pub_key) != 0)
+		return 0;
+	else
+		return 1;
+	}
+
+static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 0);
+	}
+
+static int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 1);
+	}
+
+static int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 2);
+	}
+
+int DHparams_print(BIO *bp, const DH *x)
+	{
+	return do_dh_print(bp, x, 4, NULL, 0);
+	}
+
+const EVP_PKEY_ASN1_METHOD dh_asn1_meth = 
+	{
+	EVP_PKEY_DH,
+	EVP_PKEY_DH,
+	0,
+
+	"DH",
+	"OpenSSL PKCS#3 DH method",
+
+	dh_pub_decode,
+	dh_pub_encode,
+	dh_pub_cmp,
+	dh_public_print,
+
+	dh_priv_decode,
+	dh_priv_encode,
+	dh_private_print,
+
+	int_dh_size,
+	dh_bits,
+
+	dh_param_decode,
+	dh_param_encode,
+	dh_missing_parameters,
+	dh_copy_parameters,
+	dh_cmp_parameters,
+	dh_param_print,
+
+	int_dh_free,
+	0
+	};
+
diff --git a/openssl/crypto/dh/dh_asn1.c b/openssl/crypto/dh/dh_asn1.c
new file mode 100644
index 0000000..0b4357d
--- /dev/null
+++ b/openssl/crypto/dh/dh_asn1.c
@@ -0,0 +1,93 @@
+/* dh_asn1.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/objects.h>
+#include <openssl/asn1t.h>
+
+/* Override the default free and new methods */
+static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+						void *exarg)
+{
+	if(operation == ASN1_OP_NEW_PRE) {
+		*pval = (ASN1_VALUE *)DH_new();
+		if(*pval) return 2;
+		return 0;
+	} else if(operation == ASN1_OP_FREE_PRE) {
+		DH_free((DH *)*pval);
+		*pval = NULL;
+		return 2;
+	}
+	return 1;
+}
+
+ASN1_SEQUENCE_cb(DHparams, dh_cb) = {
+	ASN1_SIMPLE(DH, p, BIGNUM),
+	ASN1_SIMPLE(DH, g, BIGNUM),
+	ASN1_OPT(DH, length, ZLONG),
+} ASN1_SEQUENCE_END_cb(DH, DHparams)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams)
+
+DH *DHparams_dup(DH *dh)
+	{
+	return ASN1_item_dup(ASN1_ITEM_rptr(DHparams), dh);
+	}
diff --git a/openssl/crypto/dh/dh_check.c b/openssl/crypto/dh/dh_check.c
new file mode 100644
index 0000000..0668981
--- /dev/null
+++ b/openssl/crypto/dh/dh_check.c
@@ -0,0 +1,142 @@
+/* crypto/dh/dh_check.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+
+/* Check that p is a safe prime and
+ * if g is 2, 3 or 5, check that it is a suitable generator
+ * where
+ * for 2, p mod 24 == 11
+ * for 3, p mod 12 == 5
+ * for 5, p mod 10 == 3 or 7
+ * should hold.
+ */
+
+int DH_check(const DH *dh, int *ret)
+	{
+	int ok=0;
+	BN_CTX *ctx=NULL;
+	BN_ULONG l;
+	BIGNUM *q=NULL;
+
+	*ret=0;
+	ctx=BN_CTX_new();
+	if (ctx == NULL) goto err;
+	q=BN_new();
+	if (q == NULL) goto err;
+
+	if (BN_is_word(dh->g,DH_GENERATOR_2))
+		{
+		l=BN_mod_word(dh->p,24);
+		if (l != 11) *ret|=DH_NOT_SUITABLE_GENERATOR;
+		}
+#if 0
+	else if (BN_is_word(dh->g,DH_GENERATOR_3))
+		{
+		l=BN_mod_word(dh->p,12);
+		if (l != 5) *ret|=DH_NOT_SUITABLE_GENERATOR;
+		}
+#endif
+	else if (BN_is_word(dh->g,DH_GENERATOR_5))
+		{
+		l=BN_mod_word(dh->p,10);
+		if ((l != 3) && (l != 7))
+			*ret|=DH_NOT_SUITABLE_GENERATOR;
+		}
+	else
+		*ret|=DH_UNABLE_TO_CHECK_GENERATOR;
+
+	if (!BN_is_prime_ex(dh->p,BN_prime_checks,ctx,NULL))
+		*ret|=DH_CHECK_P_NOT_PRIME;
+	else
+		{
+		if (!BN_rshift1(q,dh->p)) goto err;
+		if (!BN_is_prime_ex(q,BN_prime_checks,ctx,NULL))
+			*ret|=DH_CHECK_P_NOT_SAFE_PRIME;
+		}
+	ok=1;
+err:
+	if (ctx != NULL) BN_CTX_free(ctx);
+	if (q != NULL) BN_free(q);
+	return(ok);
+	}
+
+int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
+	{
+	int ok=0;
+	BIGNUM *q=NULL;
+
+	*ret=0;
+	q=BN_new();
+	if (q == NULL) goto err;
+	BN_set_word(q,1);
+	if (BN_cmp(pub_key,q)<=0)
+		*ret|=DH_CHECK_PUBKEY_TOO_SMALL;
+	BN_copy(q,dh->p);
+	BN_sub_word(q,1);
+	if (BN_cmp(pub_key,q)>=0)
+		*ret|=DH_CHECK_PUBKEY_TOO_LARGE;
+
+	ok = 1;
+err:
+	if (q != NULL) BN_free(q);
+	return(ok);
+	}
diff --git a/openssl/crypto/dh/dh_depr.c b/openssl/crypto/dh/dh_depr.c
new file mode 100644
index 0000000..acc05f2
--- /dev/null
+++ b/openssl/crypto/dh/dh_depr.c
@@ -0,0 +1,83 @@
+/* crypto/dh/dh_depr.c */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+/* This file contains deprecated functions as wrappers to the new ones */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+
+static void *dummy=&dummy;
+
+#ifndef OPENSSL_NO_DEPRECATED
+DH *DH_generate_parameters(int prime_len, int generator,
+	     void (*callback)(int,int,void *), void *cb_arg)
+	{
+	BN_GENCB cb;
+	DH *ret=NULL;
+
+	if((ret=DH_new()) == NULL)
+		return NULL;
+
+	BN_GENCB_set_old(&cb, callback, cb_arg);
+
+	if(DH_generate_parameters_ex(ret, prime_len, generator, &cb))
+		return ret;
+	DH_free(ret);
+	return NULL;
+	}
+#endif
diff --git a/openssl/crypto/dh/dh_err.c b/openssl/crypto/dh/dh_err.c
new file mode 100644
index 0000000..d5cf0c2
--- /dev/null
+++ b/openssl/crypto/dh/dh_err.c
@@ -0,0 +1,117 @@
+/* crypto/dh/dh_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/dh.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_DH,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_DH,0,reason)
+
+static ERR_STRING_DATA DH_str_functs[]=
+	{
+{ERR_FUNC(DH_F_COMPUTE_KEY),	"COMPUTE_KEY"},
+{ERR_FUNC(DH_F_DHPARAMS_PRINT_FP),	"DHparams_print_fp"},
+{ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS),	"DH_BUILTIN_GENPARAMS"},
+{ERR_FUNC(DH_F_DH_NEW_METHOD),	"DH_new_method"},
+{ERR_FUNC(DH_F_DH_PARAM_DECODE),	"DH_PARAM_DECODE"},
+{ERR_FUNC(DH_F_DH_PRIV_DECODE),	"DH_PRIV_DECODE"},
+{ERR_FUNC(DH_F_DH_PRIV_ENCODE),	"DH_PRIV_ENCODE"},
+{ERR_FUNC(DH_F_DH_PUB_DECODE),	"DH_PUB_DECODE"},
+{ERR_FUNC(DH_F_DH_PUB_ENCODE),	"DH_PUB_ENCODE"},
+{ERR_FUNC(DH_F_DO_DH_PRINT),	"DO_DH_PRINT"},
+{ERR_FUNC(DH_F_GENERATE_KEY),	"GENERATE_KEY"},
+{ERR_FUNC(DH_F_GENERATE_PARAMETERS),	"GENERATE_PARAMETERS"},
+{ERR_FUNC(DH_F_PKEY_DH_DERIVE),	"PKEY_DH_DERIVE"},
+{ERR_FUNC(DH_F_PKEY_DH_KEYGEN),	"PKEY_DH_KEYGEN"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA DH_str_reasons[]=
+	{
+{ERR_REASON(DH_R_BAD_GENERATOR)          ,"bad generator"},
+{ERR_REASON(DH_R_BN_DECODE_ERROR)        ,"bn decode error"},
+{ERR_REASON(DH_R_BN_ERROR)               ,"bn error"},
+{ERR_REASON(DH_R_DECODE_ERROR)           ,"decode error"},
+{ERR_REASON(DH_R_INVALID_PUBKEY)         ,"invalid public key"},
+{ERR_REASON(DH_R_KEYS_NOT_SET)           ,"keys not set"},
+{ERR_REASON(DH_R_MODULUS_TOO_LARGE)      ,"modulus too large"},
+{ERR_REASON(DH_R_NO_PARAMETERS_SET)      ,"no parameters set"},
+{ERR_REASON(DH_R_NO_PRIVATE_VALUE)       ,"no private value"},
+{ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_DH_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(DH_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,DH_str_functs);
+		ERR_load_strings(0,DH_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/dh/dh_gen.c b/openssl/crypto/dh/dh_gen.c
new file mode 100644
index 0000000..cfd5b11
--- /dev/null
+++ b/openssl/crypto/dh/dh_gen.c
@@ -0,0 +1,175 @@
+/* crypto/dh/dh_gen.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* NB: These functions have been upgraded - the previous prototypes are in
+ * dh_depr.c as wrappers to these ones.
+ *  - Geoff
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+
+static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb);
+
+int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb)
+	{
+	if(ret->meth->generate_params)
+		return ret->meth->generate_params(ret, prime_len, generator, cb);
+	return dh_builtin_genparams(ret, prime_len, generator, cb);
+	}
+
+/* We generate DH parameters as follows
+ * find a prime q which is prime_len/2 bits long.
+ * p=(2*q)+1 or (p-1)/2 = q
+ * For this case, g is a generator if
+ * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1.
+ * Since the factors of p-1 are q and 2, we just need to check
+ * g^2 mod p != 1 and g^q mod p != 1.
+ *
+ * Having said all that,
+ * there is another special case method for the generators 2, 3 and 5.
+ * for 2, p mod 24 == 11
+ * for 3, p mod 12 == 5  <<<<< does not work for safe primes.
+ * for 5, p mod 10 == 3 or 7
+ *
+ * Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the
+ * special generators and for answering some of my questions.
+ *
+ * I've implemented the second simple method :-).
+ * Since DH should be using a safe prime (both p and q are prime),
+ * this generator function can take a very very long time to run.
+ */
+/* Actually there is no reason to insist that 'generator' be a generator.
+ * It's just as OK (and in some sense better) to use a generator of the
+ * order-q subgroup.
+ */
+static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb)
+	{
+	BIGNUM *t1,*t2;
+	int g,ok= -1;
+	BN_CTX *ctx=NULL;
+
+	ctx=BN_CTX_new();
+	if (ctx == NULL) goto err;
+	BN_CTX_start(ctx);
+	t1 = BN_CTX_get(ctx);
+	t2 = BN_CTX_get(ctx);
+	if (t1 == NULL || t2 == NULL) goto err;
+
+	/* Make sure 'ret' has the necessary elements */
+	if(!ret->p && ((ret->p = BN_new()) == NULL)) goto err;
+	if(!ret->g && ((ret->g = BN_new()) == NULL)) goto err;
+	
+	if (generator <= 1)
+		{
+		DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
+		goto err;
+		}
+	if (generator == DH_GENERATOR_2)
+		{
+		if (!BN_set_word(t1,24)) goto err;
+		if (!BN_set_word(t2,11)) goto err;
+		g=2;
+		}
+#if 0 /* does not work for safe primes */
+	else if (generator == DH_GENERATOR_3)
+		{
+		if (!BN_set_word(t1,12)) goto err;
+		if (!BN_set_word(t2,5)) goto err;
+		g=3;
+		}
+#endif
+	else if (generator == DH_GENERATOR_5)
+		{
+		if (!BN_set_word(t1,10)) goto err;
+		if (!BN_set_word(t2,3)) goto err;
+		/* BN_set_word(t3,7); just have to miss
+		 * out on these ones :-( */
+		g=5;
+		}
+	else
+		{
+		/* in the general case, don't worry if 'generator' is a
+		 * generator or not: since we are using safe primes,
+		 * it will generate either an order-q or an order-2q group,
+		 * which both is OK */
+		if (!BN_set_word(t1,2)) goto err;
+		if (!BN_set_word(t2,1)) goto err;
+		g=generator;
+		}
+	
+	if(!BN_generate_prime_ex(ret->p,prime_len,1,t1,t2,cb)) goto err;
+	if(!BN_GENCB_call(cb, 3, 0)) goto err;
+	if (!BN_set_word(ret->g,g)) goto err;
+	ok=1;
+err:
+	if (ok == -1)
+		{
+		DHerr(DH_F_DH_BUILTIN_GENPARAMS,ERR_R_BN_LIB);
+		ok=0;
+		}
+
+	if (ctx != NULL)
+		{
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+		}
+	return ok;
+	}
diff --git a/openssl/crypto/dh/dh_key.c b/openssl/crypto/dh/dh_key.c
new file mode 100644
index 0000000..e7db440
--- /dev/null
+++ b/openssl/crypto/dh/dh_key.c
@@ -0,0 +1,263 @@
+/* crypto/dh/dh_key.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/dh.h>
+
+static int generate_key(DH *dh);
+static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
+static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
+			const BIGNUM *a, const BIGNUM *p,
+			const BIGNUM *m, BN_CTX *ctx,
+			BN_MONT_CTX *m_ctx);
+static int dh_init(DH *dh);
+static int dh_finish(DH *dh);
+
+int DH_generate_key(DH *dh)
+	{
+	return dh->meth->generate_key(dh);
+	}
+
+int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+	{
+	return dh->meth->compute_key(key, pub_key, dh);
+	}
+
+static DH_METHOD dh_ossl = {
+"OpenSSL DH Method",
+generate_key,
+compute_key,
+dh_bn_mod_exp,
+dh_init,
+dh_finish,
+0,
+NULL,
+NULL
+};
+
+const DH_METHOD *DH_OpenSSL(void)
+{
+	return &dh_ossl;
+}
+
+static int generate_key(DH *dh)
+	{
+	int ok=0;
+	int generate_new_key=0;
+	unsigned l;
+	BN_CTX *ctx;
+	BN_MONT_CTX *mont=NULL;
+	BIGNUM *pub_key=NULL,*priv_key=NULL;
+
+	ctx = BN_CTX_new();
+	if (ctx == NULL) goto err;
+
+	if (dh->priv_key == NULL)
+		{
+		priv_key=BN_new();
+		if (priv_key == NULL) goto err;
+		generate_new_key=1;
+		}
+	else
+		priv_key=dh->priv_key;
+
+	if (dh->pub_key == NULL)
+		{
+		pub_key=BN_new();
+		if (pub_key == NULL) goto err;
+		}
+	else
+		pub_key=dh->pub_key;
+
+
+	if (dh->flags & DH_FLAG_CACHE_MONT_P)
+		{
+		mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
+				CRYPTO_LOCK_DH, dh->p, ctx);
+		if (!mont)
+			goto err;
+		}
+
+	if (generate_new_key)
+		{
+		l = dh->length ? dh->length : BN_num_bits(dh->p)-1; /* secret exponent length */
+		if (!BN_rand(priv_key, l, 0, 0)) goto err;
+		}
+
+	{
+		BIGNUM local_prk;
+		BIGNUM *prk;
+
+		if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
+			{
+			BN_init(&local_prk);
+			prk = &local_prk;
+			BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
+			}
+		else
+			prk = priv_key;
+
+		if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) goto err;
+	}
+		
+	dh->pub_key=pub_key;
+	dh->priv_key=priv_key;
+	ok=1;
+err:
+	if (ok != 1)
+		DHerr(DH_F_GENERATE_KEY,ERR_R_BN_LIB);
+
+	if ((pub_key != NULL)  && (dh->pub_key == NULL))  BN_free(pub_key);
+	if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key);
+	BN_CTX_free(ctx);
+	return(ok);
+	}
+
+static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+	{
+	BN_CTX *ctx=NULL;
+	BN_MONT_CTX *mont=NULL;
+	BIGNUM *tmp;
+	int ret= -1;
+        int check_result;
+
+	if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS)
+		{
+		DHerr(DH_F_COMPUTE_KEY,DH_R_MODULUS_TOO_LARGE);
+		goto err;
+		}
+
+	ctx = BN_CTX_new();
+	if (ctx == NULL) goto err;
+	BN_CTX_start(ctx);
+	tmp = BN_CTX_get(ctx);
+	
+	if (dh->priv_key == NULL)
+		{
+		DHerr(DH_F_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE);
+		goto err;
+		}
+
+	if (dh->flags & DH_FLAG_CACHE_MONT_P)
+		{
+		mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
+				CRYPTO_LOCK_DH, dh->p, ctx);
+		if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
+			{
+			/* XXX */
+			BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME);
+			}
+		if (!mont)
+			goto err;
+		}
+
+        if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result)
+		{
+		DHerr(DH_F_COMPUTE_KEY,DH_R_INVALID_PUBKEY);
+		goto err;
+		}
+
+	if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont))
+		{
+		DHerr(DH_F_COMPUTE_KEY,ERR_R_BN_LIB);
+		goto err;
+		}
+
+	ret=BN_bn2bin(tmp,key);
+err:
+	if (ctx != NULL)
+		{
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+		}
+	return(ret);
+	}
+
+static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
+			const BIGNUM *a, const BIGNUM *p,
+			const BIGNUM *m, BN_CTX *ctx,
+			BN_MONT_CTX *m_ctx)
+	{
+	/* If a is only one word long and constant time is false, use the faster
+	 * exponenentiation function.
+	 */
+	if (a->top == 1 && ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) != 0))
+		{
+		BN_ULONG A = a->d[0];
+		return BN_mod_exp_mont_word(r,A,p,m,ctx,m_ctx);
+		}
+	else
+		return BN_mod_exp_mont(r,a,p,m,ctx,m_ctx);
+	}
+
+
+static int dh_init(DH *dh)
+	{
+	dh->flags |= DH_FLAG_CACHE_MONT_P;
+	return(1);
+	}
+
+static int dh_finish(DH *dh)
+	{
+	if(dh->method_mont_p)
+		BN_MONT_CTX_free(dh->method_mont_p);
+	return(1);
+	}
diff --git a/openssl/crypto/dh/dh_lib.c b/openssl/crypto/dh/dh_lib.c
new file mode 100644
index 0000000..7aef080
--- /dev/null
+++ b/openssl/crypto/dh/dh_lib.c
@@ -0,0 +1,247 @@
+/* crypto/dh/dh_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+const char DH_version[]="Diffie-Hellman" OPENSSL_VERSION_PTEXT;
+
+static const DH_METHOD *default_DH_method = NULL;
+
+void DH_set_default_method(const DH_METHOD *meth)
+	{
+	default_DH_method = meth;
+	}
+
+const DH_METHOD *DH_get_default_method(void)
+	{
+	if(!default_DH_method)
+		default_DH_method = DH_OpenSSL();
+	return default_DH_method;
+	}
+
+int DH_set_method(DH *dh, const DH_METHOD *meth)
+	{
+	/* NB: The caller is specifically setting a method, so it's not up to us
+	 * to deal with which ENGINE it comes from. */
+        const DH_METHOD *mtmp;
+        mtmp = dh->meth;
+        if (mtmp->finish) mtmp->finish(dh);
+#ifndef OPENSSL_NO_ENGINE
+	if (dh->engine)
+		{
+		ENGINE_finish(dh->engine);
+		dh->engine = NULL;
+		}
+#endif
+        dh->meth = meth;
+        if (meth->init) meth->init(dh);
+        return 1;
+	}
+
+DH *DH_new(void)
+	{
+	return DH_new_method(NULL);
+	}
+
+DH *DH_new_method(ENGINE *engine)
+	{
+	DH *ret;
+
+	ret=(DH *)OPENSSL_malloc(sizeof(DH));
+	if (ret == NULL)
+		{
+		DHerr(DH_F_DH_NEW_METHOD,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+
+	ret->meth = DH_get_default_method();
+#ifndef OPENSSL_NO_ENGINE
+	if (engine)
+		{
+		if (!ENGINE_init(engine))
+			{
+			DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB);
+			OPENSSL_free(ret);
+			return NULL;
+			}
+		ret->engine = engine;
+		}
+	else
+		ret->engine = ENGINE_get_default_DH();
+	if(ret->engine)
+		{
+		ret->meth = ENGINE_get_DH(ret->engine);
+		if(!ret->meth)
+			{
+			DHerr(DH_F_DH_NEW_METHOD,ERR_R_ENGINE_LIB);
+			ENGINE_finish(ret->engine);
+			OPENSSL_free(ret);
+			return NULL;
+			}
+		}
+#endif
+
+	ret->pad=0;
+	ret->version=0;
+	ret->p=NULL;
+	ret->g=NULL;
+	ret->length=0;
+	ret->pub_key=NULL;
+	ret->priv_key=NULL;
+	ret->q=NULL;
+	ret->j=NULL;
+	ret->seed = NULL;
+	ret->seedlen = 0;
+	ret->counter = NULL;
+	ret->method_mont_p=NULL;
+	ret->references = 1;
+	ret->flags=ret->meth->flags;
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data);
+	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
+		{
+#ifndef OPENSSL_NO_ENGINE
+		if (ret->engine)
+			ENGINE_finish(ret->engine);
+#endif
+		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data);
+		OPENSSL_free(ret);
+		ret=NULL;
+		}
+	return(ret);
+	}
+
+void DH_free(DH *r)
+	{
+	int i;
+	if(r == NULL) return;
+	i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_DH);
+#ifdef REF_PRINT
+	REF_PRINT("DH",r);
+#endif
+	if (i > 0) return;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"DH_free, bad reference count\n");
+		abort();
+	}
+#endif
+
+	if (r->meth->finish)
+		r->meth->finish(r);
+#ifndef OPENSSL_NO_ENGINE
+	if (r->engine)
+		ENGINE_finish(r->engine);
+#endif
+
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data);
+
+	if (r->p != NULL) BN_clear_free(r->p);
+	if (r->g != NULL) BN_clear_free(r->g);
+	if (r->q != NULL) BN_clear_free(r->q);
+	if (r->j != NULL) BN_clear_free(r->j);
+	if (r->seed) OPENSSL_free(r->seed);
+	if (r->counter != NULL) BN_clear_free(r->counter);
+	if (r->pub_key != NULL) BN_clear_free(r->pub_key);
+	if (r->priv_key != NULL) BN_clear_free(r->priv_key);
+	OPENSSL_free(r);
+	}
+
+int DH_up_ref(DH *r)
+	{
+	int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DH);
+#ifdef REF_PRINT
+	REF_PRINT("DH",r);
+#endif
+#ifdef REF_CHECK
+	if (i < 2)
+		{
+		fprintf(stderr, "DH_up, bad reference count\n");
+		abort();
+		}
+#endif
+	return ((i > 1) ? 1 : 0);
+	}
+
+int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+        {
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DH, argl, argp,
+				new_func, dup_func, free_func);
+        }
+
+int DH_set_ex_data(DH *d, int idx, void *arg)
+	{
+	return(CRYPTO_set_ex_data(&d->ex_data,idx,arg));
+	}
+
+void *DH_get_ex_data(DH *d, int idx)
+	{
+	return(CRYPTO_get_ex_data(&d->ex_data,idx));
+	}
+
+int DH_size(const DH *dh)
+	{
+	return(BN_num_bytes(dh->p));
+	}
diff --git a/openssl/crypto/dh/dh_pmeth.c b/openssl/crypto/dh/dh_pmeth.c
new file mode 100644
index 0000000..5ae72b7
--- /dev/null
+++ b/openssl/crypto/dh/dh_pmeth.c
@@ -0,0 +1,254 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/evp.h>
+#include <openssl/dh.h>
+#include <openssl/bn.h>
+#include "evp_locl.h"
+
+/* DH pkey context structure */
+
+typedef struct
+	{
+	/* Parameter gen parameters */
+	int prime_len;
+	int generator;
+	int use_dsa;
+	/* Keygen callback info */
+	int gentmp[2];
+	/* message digest */
+	} DH_PKEY_CTX;
+
+static int pkey_dh_init(EVP_PKEY_CTX *ctx)
+	{
+	DH_PKEY_CTX *dctx;
+	dctx = OPENSSL_malloc(sizeof(DH_PKEY_CTX));
+	if (!dctx)
+		return 0;
+	dctx->prime_len = 1024;
+	dctx->generator = 2;
+	dctx->use_dsa = 0;
+
+	ctx->data = dctx;
+	ctx->keygen_info = dctx->gentmp;
+	ctx->keygen_info_count = 2;
+	
+	return 1;
+	}
+
+static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+	{
+	DH_PKEY_CTX *dctx, *sctx;
+	if (!pkey_dh_init(dst))
+		return 0;
+       	sctx = src->data;
+	dctx = dst->data;
+	dctx->prime_len = sctx->prime_len;
+	dctx->generator = sctx->generator;
+	dctx->use_dsa = sctx->use_dsa;
+	return 1;
+	}
+
+static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
+	{
+	DH_PKEY_CTX *dctx = ctx->data;
+	if (dctx)
+		OPENSSL_free(dctx);
+	}
+
+static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+	{
+	DH_PKEY_CTX *dctx = ctx->data;
+	switch (type)
+		{
+		case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
+		if (p1 < 256)
+			return -2;
+		dctx->prime_len = p1;
+		return 1;
+
+		case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
+		dctx->generator = p1;
+		return 1;
+
+		case EVP_PKEY_CTRL_PEER_KEY:
+		/* Default behaviour is OK */
+		return 1;
+
+		default:
+		return -2;
+
+		}
+	}
+
+			
+static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
+			const char *type, const char *value)
+	{
+	if (!strcmp(type, "dh_paramgen_prime_len"))
+		{
+		int len;
+		len = atoi(value);
+		return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
+		}
+	if (!strcmp(type, "dh_paramgen_generator"))
+		{
+		int len;
+		len = atoi(value);
+		return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
+		}
+	return -2;
+	}
+
+static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+	DH *dh = NULL;
+	DH_PKEY_CTX *dctx = ctx->data;
+	BN_GENCB *pcb, cb;
+	int ret;
+	if (ctx->pkey_gencb)
+		{
+		pcb = &cb;
+		evp_pkey_set_cb_translate(pcb, ctx);
+		}
+	else
+		pcb = NULL;
+	dh = DH_new();
+	if (!dh)
+		return 0;
+	ret = DH_generate_parameters_ex(dh,
+					dctx->prime_len, dctx->generator, pcb);
+	if (ret)
+		EVP_PKEY_assign_DH(pkey, dh);
+	else
+		DH_free(dh);
+	return ret;
+	}
+
+static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+	DH *dh = NULL;
+	if (ctx->pkey == NULL)
+		{
+		DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
+		return 0;
+		}
+	dh = DH_new();
+	if (!dh)
+		return 0;
+	EVP_PKEY_assign_DH(pkey, dh);
+	/* Note: if error return, pkey is freed by parent routine */
+	if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
+		return 0;
+	return DH_generate_key(pkey->pkey.dh);
+	}
+
+static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
+	{
+	int ret;
+	if (!ctx->pkey || !ctx->peerkey)
+		{
+		DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
+		return 0;
+		}
+	ret = DH_compute_key(key, ctx->peerkey->pkey.dh->pub_key,
+							ctx->pkey->pkey.dh);
+	if (ret < 0)
+		return ret;
+	*keylen = ret;
+	return 1;
+	}
+
+const EVP_PKEY_METHOD dh_pkey_meth = 
+	{
+	EVP_PKEY_DH,
+	EVP_PKEY_FLAG_AUTOARGLEN,
+	pkey_dh_init,
+	pkey_dh_copy,
+	pkey_dh_cleanup,
+
+	0,
+	pkey_dh_paramgen,
+
+	0,
+	pkey_dh_keygen,
+
+	0,
+	0,
+
+	0,
+	0,
+
+	0,0,
+
+	0,0,0,0,
+
+	0,0,
+
+	0,0,
+
+	0,
+	pkey_dh_derive,
+
+	pkey_dh_ctrl,
+	pkey_dh_ctrl_str
+
+	};
diff --git a/openssl/crypto/dh/dh_prn.c b/openssl/crypto/dh/dh_prn.c
new file mode 100644
index 0000000..ae58c2a
--- /dev/null
+++ b/openssl/crypto/dh/dh_prn.c
@@ -0,0 +1,80 @@
+/* crypto/asn1/t_pkey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/dh.h>
+
+#ifndef OPENSSL_NO_FP_API
+int DHparams_print_fp(FILE *fp, const DH *x)
+	{
+	BIO *b;
+	int ret;
+
+	if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		DHerr(DH_F_DHPARAMS_PRINT_FP,ERR_R_BUF_LIB);
+		return(0);
+		}
+	BIO_set_fp(b,fp,BIO_NOCLOSE);
+	ret=DHparams_print(b, x);
+	BIO_free(b);
+	return(ret);
+	}
+#endif
diff --git a/openssl/crypto/dh/dhtest.c b/openssl/crypto/dh/dhtest.c
new file mode 100644
index 0000000..882f5c3
--- /dev/null
+++ b/openssl/crypto/dh/dhtest.c
@@ -0,0 +1,226 @@
+/* crypto/dh/dhtest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code */
+#ifdef OPENSSL_NO_DEPRECATED
+#undef OPENSSL_NO_DEPRECATED
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../e_os.h"
+
+#include <openssl/crypto.h>
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+#ifdef OPENSSL_NO_DH
+int main(int argc, char *argv[])
+{
+    printf("No DH support\n");
+    return(0);
+}
+#else
+#include <openssl/dh.h>
+
+#ifdef OPENSSL_SYS_WIN16
+#define MS_CALLBACK	_far _loadds
+#else
+#define MS_CALLBACK
+#endif
+
+static int MS_CALLBACK cb(int p, int n, BN_GENCB *arg);
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+int main(int argc, char *argv[])
+	{
+	BN_GENCB _cb;
+	DH *a;
+	DH *b=NULL;
+	char buf[12];
+	unsigned char *abuf=NULL,*bbuf=NULL;
+	int i,alen,blen,aout,bout,ret=1;
+	BIO *out;
+
+	CRYPTO_malloc_debug_init();
+	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
+	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+#ifdef OPENSSL_SYS_WIN32
+	CRYPTO_malloc_init();
+#endif
+
+	RAND_seed(rnd_seed, sizeof rnd_seed);
+
+	out=BIO_new(BIO_s_file());
+	if (out == NULL) EXIT(1);
+	BIO_set_fp(out,stdout,BIO_NOCLOSE);
+
+	BN_GENCB_set(&_cb, &cb, out);
+	if(((a = DH_new()) == NULL) || !DH_generate_parameters_ex(a, 64,
+				DH_GENERATOR_5, &_cb))
+		goto err;
+
+	if (!DH_check(a, &i)) goto err;
+	if (i & DH_CHECK_P_NOT_PRIME)
+		BIO_puts(out, "p value is not prime\n");
+	if (i & DH_CHECK_P_NOT_SAFE_PRIME)
+		BIO_puts(out, "p value is not a safe prime\n");
+	if (i & DH_UNABLE_TO_CHECK_GENERATOR)
+		BIO_puts(out, "unable to check the generator value\n");
+	if (i & DH_NOT_SUITABLE_GENERATOR)
+		BIO_puts(out, "the g value is not a generator\n");
+
+	BIO_puts(out,"\np    =");
+	BN_print(out,a->p);
+	BIO_puts(out,"\ng    =");
+	BN_print(out,a->g);
+	BIO_puts(out,"\n");
+
+	b=DH_new();
+	if (b == NULL) goto err;
+
+	b->p=BN_dup(a->p);
+	b->g=BN_dup(a->g);
+	if ((b->p == NULL) || (b->g == NULL)) goto err;
+
+	/* Set a to run with normal modexp and b to use constant time */
+	a->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
+	b->flags |= DH_FLAG_NO_EXP_CONSTTIME;
+
+	if (!DH_generate_key(a)) goto err;
+	BIO_puts(out,"pri 1=");
+	BN_print(out,a->priv_key);
+	BIO_puts(out,"\npub 1=");
+	BN_print(out,a->pub_key);
+	BIO_puts(out,"\n");
+
+	if (!DH_generate_key(b)) goto err;
+	BIO_puts(out,"pri 2=");
+	BN_print(out,b->priv_key);
+	BIO_puts(out,"\npub 2=");
+	BN_print(out,b->pub_key);
+	BIO_puts(out,"\n");
+
+	alen=DH_size(a);
+	abuf=(unsigned char *)OPENSSL_malloc(alen);
+	aout=DH_compute_key(abuf,b->pub_key,a);
+
+	BIO_puts(out,"key1 =");
+	for (i=0; i<aout; i++)
+		{
+		sprintf(buf,"%02X",abuf[i]);
+		BIO_puts(out,buf);
+		}
+	BIO_puts(out,"\n");
+
+	blen=DH_size(b);
+	bbuf=(unsigned char *)OPENSSL_malloc(blen);
+	bout=DH_compute_key(bbuf,a->pub_key,b);
+
+	BIO_puts(out,"key2 =");
+	for (i=0; i<bout; i++)
+		{
+		sprintf(buf,"%02X",bbuf[i]);
+		BIO_puts(out,buf);
+		}
+	BIO_puts(out,"\n");
+	if ((aout < 4) || (bout != aout) || (memcmp(abuf,bbuf,aout) != 0))
+		{
+		fprintf(stderr,"Error in DH routines\n");
+		ret=1;
+		}
+	else
+		ret=0;
+err:
+	ERR_print_errors_fp(stderr);
+
+	if (abuf != NULL) OPENSSL_free(abuf);
+	if (bbuf != NULL) OPENSSL_free(bbuf);
+	if(b != NULL) DH_free(b);
+	if(a != NULL) DH_free(a);
+	BIO_free(out);
+#ifdef OPENSSL_SYS_NETWARE
+    if (ret) printf("ERROR: %d\n", ret);
+#endif
+	EXIT(ret);
+	return(ret);
+	}
+
+static int MS_CALLBACK cb(int p, int n, BN_GENCB *arg)
+	{
+	char c='*';
+
+	if (p == 0) c='.';
+	if (p == 1) c='+';
+	if (p == 2) c='*';
+	if (p == 3) c='\n';
+	BIO_write(arg->arg,&c,1);
+	(void)BIO_flush(arg->arg);
+#ifdef LINT
+	p=n;
+#endif
+	return 1;
+	}
+#endif
diff --git a/openssl/crypto/dh/example b/openssl/crypto/dh/example
new file mode 100644
index 0000000..16a33d2
--- /dev/null
+++ b/openssl/crypto/dh/example
@@ -0,0 +1,50 @@
+From owner-cypherpunks@toad.com Mon Sep 25 10:50:51 1995
+Received: from minbne.mincom.oz.au by orb.mincom.oz.au with SMTP id AA10562
+  (5.65c/IDA-1.4.4 for eay); Wed, 27 Sep 1995 19:41:55 +1000
+Received: by minbne.mincom.oz.au id AA19958
+  (5.65c/IDA-1.4.4 for eay@orb.mincom.oz.au); Wed, 27 Sep 1995 19:34:59 +1000
+Received: from relay3.UU.NET by bunyip.cc.uq.oz.au with SMTP (PP);
+          Wed, 27 Sep 1995 19:13:05 +1000
+Received: from toad.com by relay3.UU.NET with SMTP id QQzizb16156;
+          Wed, 27 Sep 1995 04:48:46 -0400
+Received: by toad.com id AA07905; Tue, 26 Sep 95 06:31:45 PDT
+Received: from by toad.com id AB07851; Tue, 26 Sep 95 06:31:40 PDT
+Received: from servo.qualcomm.com (servo.qualcomm.com [129.46.128.14]) 
+          by cygnus.com (8.6.12/8.6.9) with ESMTP id RAA18442 
+          for <cypherpunks@toad.com>; Mon, 25 Sep 1995 17:52:47 -0700
+Received: (karn@localhost) by servo.qualcomm.com (8.6.12/QC-BSD-2.5.1) 
+          id RAA14732; Mon, 25 Sep 1995 17:50:51 -0700
+Date: Mon, 25 Sep 1995 17:50:51 -0700
+From: Phil Karn <karn@qualcomm.com>
+Message-Id: <199509260050.RAA14732@servo.qualcomm.com>
+To: cypherpunks@toad.com, ipsec-dev@eit.com
+Subject: Primality verification needed
+Sender: owner-cypherpunks@toad.com
+Precedence: bulk
+Status: RO
+X-Status: 
+
+Hi. I've generated a 2047-bit "strong" prime number that I would like to
+use with Diffie-Hellman key exchange. I assert that not only is this number
+'p' prime, but so is (p-1)/2.
+
+I've used the mpz_probab_prime() function in the Gnu Math Package (GMP) version
+1.3.2 to test this number. This function uses the Miller-Rabin primality test.
+However, to increase my confidence that this number really is a strong prime,
+I'd like to ask others to confirm it with other tests. Here's the number in hex:
+
+72a925f760b2f954ed287f1b0953f3e6aef92e456172f9fe86fdd8822241b9c9788fbc289982743e
+fbcd2ccf062b242d7a567ba8bbb40d79bca7b8e0b6c05f835a5b938d985816bc648985adcff5402a
+a76756b36c845a840a1d059ce02707e19cf47af0b5a882f32315c19d1b86a56c5389c5e9bee16b65
+fde7b1a8d74a7675de9b707d4c5a4633c0290c95ff30a605aeb7ae864ff48370f13cf01d49adb9f2
+3d19a439f753ee7703cf342d87f431105c843c78ca4df639931f3458fae8a94d1687e99a76ed99d0
+ba87189f42fd31ad8262c54a8cf5914ae6c28c540d714a5f6087a171fb74f4814c6f968d72386ef3
+56a05180c3bec7ddd5ef6fe76b1f717b
+
+The generator, g, for this prime is 2.
+
+Thanks!
+
+Phil Karn
+
+
diff --git a/openssl/crypto/dh/generate b/openssl/crypto/dh/generate
new file mode 100644
index 0000000..5d40723
--- /dev/null
+++ b/openssl/crypto/dh/generate
@@ -0,0 +1,65 @@
+From: stewarts@ix.netcom.com (Bill Stewart)
+Newsgroups: sci.crypt
+Subject: Re: Diffie-Hellman key exchange
+Date: Wed, 11 Oct 1995 23:08:28 GMT
+Organization: Freelance Information Architect
+Lines: 32
+Message-ID: <45hir2$7l8@ixnews7.ix.netcom.com>
+References: <458rhn$76m$1@mhadf.production.compuserve.com>
+NNTP-Posting-Host: ix-pl4-16.ix.netcom.com
+X-NETCOM-Date: Wed Oct 11  4:09:22 PM PDT 1995
+X-Newsreader: Forte Free Agent 1.0.82
+
+Kent Briggs <72124.3234@CompuServe.COM> wrote:
+
+>I have a copy of the 1976 IEEE article describing the
+>Diffie-Hellman public key exchange algorithm: y=a^x mod q.  I'm
+>looking for sources that give examples of secure a,q pairs and
+>possible some source code that I could examine.
+
+q should be prime, and ideally should be a "strong prime",
+which means it's of the form 2n+1 where n is also prime.
+q also needs to be long enough to prevent the attacks LaMacchia and
+Odlyzko described (some variant on a factoring attack which generates
+a large pile of simultaneous equations and then solves them);
+long enough is about the same size as factoring, so 512 bits may not
+be secure enough for most applications.  (The 192 bits used by
+"secure NFS" was certainly not long enough.)
+
+a should be a generator for q, which means it needs to be
+relatively prime to q-1.   Usually a small prime like 2, 3 or 5 will
+work.  
+
+....
+
+Date: Tue, 26 Sep 1995 13:52:36 MST
+From: "Richard Schroeppel" <rcs@cs.arizona.edu>
+To: karn
+Cc: ho@cs.arizona.edu
+Subject: random large primes
+
+Since your prime is really random, proving it is hard.
+My personal limit on rigorously proved primes is ~350 digits.
+If you really want a proof, we should talk to Francois Morain,
+or the Australian group.
+
+If you want 2 to be a generator (mod P), then you need it
+to be a non-square.  If (P-1)/2 is also prime, then
+non-square == primitive-root for bases << P.
+
+In the case at hand, this means 2 is a generator iff P = 11 (mod 24).
+If you want this, you should restrict your sieve accordingly.
+
+3 is a generator iff P = 5 (mod 12).
+
+5 is a generator iff P = 3 or 7 (mod 10).
+
+2 is perfectly usable as a base even if it's a non-generator, since
+it still covers half the space of possible residues.  And an
+eavesdropper can always determine the low-bit of your exponent for
+a generator anyway.
+
+Rich  rcs@cs.arizona.edu
+
+
+
diff --git a/openssl/crypto/dh/p1024.c b/openssl/crypto/dh/p1024.c
new file mode 100644
index 0000000..368ceca
--- /dev/null
+++ b/openssl/crypto/dh/p1024.c
@@ -0,0 +1,92 @@
+/* crypto/dh/p1024.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/bn.h>
+#include <openssl/asn1.h>
+#include <openssl/dh.h>
+#include <openssl/pem.h>
+
+unsigned char data[]={0x97,0xF6,0x42,0x61,0xCA,0xB5,0x05,0xDD,
+	0x28,0x28,0xE1,0x3F,0x1D,0x68,0xB6,0xD3,
+	0xDB,0xD0,0xF3,0x13,0x04,0x7F,0x40,0xE8,
+	0x56,0xDA,0x58,0xCB,0x13,0xB8,0xA1,0xBF,
+	0x2B,0x78,0x3A,0x4C,0x6D,0x59,0xD5,0xF9,
+	0x2A,0xFC,0x6C,0xFF,0x3D,0x69,0x3F,0x78,
+	0xB2,0x3D,0x4F,0x31,0x60,0xA9,0x50,0x2E,
+	0x3E,0xFA,0xF7,0xAB,0x5E,0x1A,0xD5,0xA6,
+	0x5E,0x55,0x43,0x13,0x82,0x8D,0xA8,0x3B,
+	0x9F,0xF2,0xD9,0x41,0xDE,0xE9,0x56,0x89,
+	0xFA,0xDA,0xEA,0x09,0x36,0xAD,0xDF,0x19,
+	0x71,0xFE,0x63,0x5B,0x20,0xAF,0x47,0x03,
+	0x64,0x60,0x3C,0x2D,0xE0,0x59,0xF5,0x4B,
+	0x65,0x0A,0xD8,0xFA,0x0C,0xF7,0x01,0x21,
+	0xC7,0x47,0x99,0xD7,0x58,0x71,0x32,0xBE,
+	0x9B,0x99,0x9B,0xB9,0xB7,0x87,0xE8,0xAB,
+	};
+
+main()
+	{
+	DH *dh;
+
+	dh=DH_new();
+	dh->p=BN_bin2bn(data,sizeof(data),NULL);
+	dh->g=BN_new();
+	BN_set_word(dh->g,2);
+	PEM_write_DHparams(stdout,dh);
+	}
diff --git a/openssl/crypto/dh/p192.c b/openssl/crypto/dh/p192.c
new file mode 100644
index 0000000..7bdf404
--- /dev/null
+++ b/openssl/crypto/dh/p192.c
@@ -0,0 +1,80 @@
+/* crypto/dh/p192.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/bn.h>
+#include <openssl/asn1.h>
+#include <openssl/dh.h>
+#include <openssl/pem.h>
+
+unsigned char data[]={
+0xD4,0xA0,0xBA,0x02,0x50,0xB6,0xFD,0x2E,
+0xC6,0x26,0xE7,0xEF,0xD6,0x37,0xDF,0x76,
+0xC7,0x16,0xE2,0x2D,0x09,0x44,0xB8,0x8B,
+	};
+
+main()
+	{
+	DH *dh;
+
+	dh=DH_new();
+	dh->p=BN_bin2bn(data,sizeof(data),NULL);
+	dh->g=BN_new();
+	BN_set_word(dh->g,3);
+	PEM_write_DHparams(stdout,dh);
+	}
diff --git a/openssl/crypto/dh/p512.c b/openssl/crypto/dh/p512.c
new file mode 100644
index 0000000..a9b6aa8
--- /dev/null
+++ b/openssl/crypto/dh/p512.c
@@ -0,0 +1,85 @@
+/* crypto/dh/p512.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/bn.h>
+#include <openssl/asn1.h>
+#include <openssl/dh.h>
+#include <openssl/pem.h>
+
+unsigned char data[]={
+0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,
+0xD0,0xE4,0xAF,0x75,0x6F,0x4C,0xCA,0x92,
+0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
+0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,
+0x57,0x46,0x50,0xD3,0x69,0x99,0xDB,0x29,
+0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
+0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,
+0xD8,0x00,0x3E,0x7C,0x47,0x74,0xE8,0x33,
+	};
+
+main()
+	{
+	DH *dh;
+
+	dh=DH_new();
+	dh->p=BN_bin2bn(data,sizeof(data),NULL);
+	dh->g=BN_new();
+	BN_set_word(dh->g,2);
+	PEM_write_DHparams(stdout,dh);
+	}
diff --git a/openssl/crypto/dsa/Makefile b/openssl/crypto/dsa/Makefile
new file mode 100644
index 0000000..8073c4e
--- /dev/null
+++ b/openssl/crypto/dsa/Makefile
@@ -0,0 +1,208 @@
+#
+# OpenSSL/crypto/dsa/Makefile
+#
+
+DIR=	dsa
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=dsatest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= dsa_gen.c dsa_key.c dsa_lib.c dsa_asn1.c dsa_vrf.c dsa_sign.c \
+	dsa_err.c dsa_ossl.c dsa_depr.c dsa_ameth.c dsa_pmeth.c dsa_prn.c
+LIBOBJ= dsa_gen.o dsa_key.o dsa_lib.o dsa_asn1.o dsa_vrf.o dsa_sign.o \
+	dsa_err.o dsa_ossl.o dsa_depr.o dsa_ameth.o dsa_pmeth.o dsa_prn.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= dsa.h
+HEADER=	dsa_locl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+dsa_ameth.o: ../../e_os.h ../../include/openssl/asn1.h
+dsa_ameth.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+dsa_ameth.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
+dsa_ameth.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+dsa_ameth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+dsa_ameth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+dsa_ameth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+dsa_ameth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+dsa_ameth.o: ../../include/openssl/objects.h
+dsa_ameth.o: ../../include/openssl/opensslconf.h
+dsa_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dsa_ameth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+dsa_ameth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dsa_ameth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+dsa_ameth.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
+dsa_ameth.o: dsa_ameth.c
+dsa_asn1.o: ../../e_os.h ../../include/openssl/asn1.h
+dsa_asn1.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+dsa_asn1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dsa_asn1.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+dsa_asn1.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dsa_asn1.o: ../../include/openssl/opensslconf.h
+dsa_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dsa_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dsa_asn1.o: ../../include/openssl/symhacks.h ../cryptlib.h dsa_asn1.c
+dsa_depr.o: ../../e_os.h ../../include/openssl/asn1.h
+dsa_depr.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+dsa_depr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dsa_depr.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+dsa_depr.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+dsa_depr.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+dsa_depr.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+dsa_depr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dsa_depr.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+dsa_depr.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dsa_depr.o: ../../include/openssl/symhacks.h ../cryptlib.h dsa_depr.c
+dsa_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+dsa_err.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+dsa_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dsa_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dsa_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+dsa_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dsa_err.o: dsa_err.c
+dsa_gen.o: ../../e_os.h ../../include/openssl/asn1.h
+dsa_gen.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+dsa_gen.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dsa_gen.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+dsa_gen.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+dsa_gen.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+dsa_gen.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+dsa_gen.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dsa_gen.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+dsa_gen.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dsa_gen.o: ../../include/openssl/symhacks.h ../cryptlib.h dsa_gen.c dsa_locl.h
+dsa_key.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+dsa_key.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dsa_key.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+dsa_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dsa_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dsa_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+dsa_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dsa_key.o: ../../include/openssl/symhacks.h ../cryptlib.h dsa_key.c
+dsa_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+dsa_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+dsa_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dsa_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+dsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+dsa_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+dsa_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+dsa_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+dsa_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+dsa_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dsa_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+dsa_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+dsa_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dsa_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+dsa_lib.o: ../cryptlib.h dsa_lib.c
+dsa_ossl.o: ../../e_os.h ../../include/openssl/asn1.h
+dsa_ossl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+dsa_ossl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dsa_ossl.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+dsa_ossl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dsa_ossl.o: ../../include/openssl/opensslconf.h
+dsa_ossl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dsa_ossl.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+dsa_ossl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dsa_ossl.o: ../../include/openssl/symhacks.h ../cryptlib.h dsa_ossl.c
+dsa_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
+dsa_pmeth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+dsa_pmeth.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+dsa_pmeth.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+dsa_pmeth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+dsa_pmeth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+dsa_pmeth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+dsa_pmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+dsa_pmeth.o: ../../include/openssl/objects.h
+dsa_pmeth.o: ../../include/openssl/opensslconf.h
+dsa_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dsa_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+dsa_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dsa_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+dsa_pmeth.o: ../../include/openssl/x509_vfy.h ../cryptlib.h ../evp/evp_locl.h
+dsa_pmeth.o: dsa_locl.h dsa_pmeth.c
+dsa_prn.o: ../../e_os.h ../../include/openssl/asn1.h
+dsa_prn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+dsa_prn.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+dsa_prn.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+dsa_prn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+dsa_prn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+dsa_prn.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dsa_prn.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+dsa_prn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dsa_prn.o: ../cryptlib.h dsa_prn.c
+dsa_sign.o: ../../e_os.h ../../include/openssl/bio.h
+dsa_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dsa_sign.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+dsa_sign.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dsa_sign.o: ../../include/openssl/opensslconf.h
+dsa_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dsa_sign.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+dsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dsa_sign.o: ../cryptlib.h dsa_sign.c
+dsa_vrf.o: ../../e_os.h ../../include/openssl/bio.h
+dsa_vrf.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dsa_vrf.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+dsa_vrf.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dsa_vrf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dsa_vrf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+dsa_vrf.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dsa_vrf.o: ../cryptlib.h dsa_vrf.c
diff --git a/openssl/crypto/dsa/README b/openssl/crypto/dsa/README
new file mode 100644
index 0000000..6a7e9c1
--- /dev/null
+++ b/openssl/crypto/dsa/README
@@ -0,0 +1,4 @@
+The stuff in here is based on patches supplied to me by
+Steven Schoch <schoch@sheba.arc.nasa.gov> to do DSS.
+I have since modified a them a little but a debt of gratitude
+is due for doing the initial work.
diff --git a/openssl/crypto/dsa/dsa.h b/openssl/crypto/dsa/dsa.h
new file mode 100644
index 0000000..ac50a5c
--- /dev/null
+++ b/openssl/crypto/dsa/dsa.h
@@ -0,0 +1,307 @@
+/* crypto/dsa/dsa.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*
+ * The DSS routines are based on patches supplied by
+ * Steven Schoch <schoch@sheba.arc.nasa.gov>.  He basically did the
+ * work and I have just tweaked them a little to fit into my
+ * stylistic vision for SSLeay :-) */
+
+#ifndef HEADER_DSA_H
+#define HEADER_DSA_H
+
+#include <openssl/e_os2.h>
+
+#ifdef OPENSSL_NO_DSA
+#error DSA is disabled.
+#endif
+
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#include <openssl/crypto.h>
+#include <openssl/ossl_typ.h>
+
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_DH
+# include <openssl/dh.h>
+#endif
+#endif
+
+#ifndef OPENSSL_DSA_MAX_MODULUS_BITS
+# define OPENSSL_DSA_MAX_MODULUS_BITS	10000
+#endif
+
+#define DSA_FLAG_CACHE_MONT_P	0x01
+#define DSA_FLAG_NO_EXP_CONSTTIME       0x02 /* new with 0.9.7h; the built-in DSA
+                                              * implementation now uses constant time
+                                              * modular exponentiation for secret exponents
+                                              * by default. This flag causes the
+                                              * faster variable sliding window method to
+                                              * be used for all exponents.
+                                              */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct dsa_st DSA; */
+/* typedef struct dsa_method DSA_METHOD; */
+
+typedef struct DSA_SIG_st
+	{
+	BIGNUM *r;
+	BIGNUM *s;
+	} DSA_SIG;
+
+struct dsa_method
+	{
+	const char *name;
+	DSA_SIG * (*dsa_do_sign)(const unsigned char *dgst, int dlen, DSA *dsa);
+	int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
+								BIGNUM **rp);
+	int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len,
+			     DSA_SIG *sig, DSA *dsa);
+	int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
+			BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
+			BN_MONT_CTX *in_mont);
+	int (*bn_mod_exp)(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+				const BIGNUM *m, BN_CTX *ctx,
+				BN_MONT_CTX *m_ctx); /* Can be null */
+	int (*init)(DSA *dsa);
+	int (*finish)(DSA *dsa);
+	int flags;
+	char *app_data;
+	/* If this is non-NULL, it is used to generate DSA parameters */
+	int (*dsa_paramgen)(DSA *dsa, int bits,
+			const unsigned char *seed, int seed_len,
+			int *counter_ret, unsigned long *h_ret,
+			BN_GENCB *cb);
+	/* If this is non-NULL, it is used to generate DSA keys */
+	int (*dsa_keygen)(DSA *dsa);
+	};
+
+struct dsa_st
+	{
+	/* This first variable is used to pick up errors where
+	 * a DSA is passed instead of of a EVP_PKEY */
+	int pad;
+	long version;
+	int write_params;
+	BIGNUM *p;
+	BIGNUM *q;	/* == 20 */
+	BIGNUM *g;
+
+	BIGNUM *pub_key;  /* y public key */
+	BIGNUM *priv_key; /* x private key */
+
+	BIGNUM *kinv;	/* Signing pre-calc */
+	BIGNUM *r;	/* Signing pre-calc */
+
+	int flags;
+	/* Normally used to cache montgomery values */
+	BN_MONT_CTX *method_mont_p;
+	int references;
+	CRYPTO_EX_DATA ex_data;
+	const DSA_METHOD *meth;
+	/* functional reference if 'meth' is ENGINE-provided */
+	ENGINE *engine;
+	};
+
+#define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \
+		(char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x))
+#define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \
+		(unsigned char *)(x))
+#define d2i_DSAparams_bio(bp,x) ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAparams,bp,x)
+#define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x)
+
+
+DSA *DSAparams_dup(DSA *x);
+DSA_SIG * DSA_SIG_new(void);
+void	DSA_SIG_free(DSA_SIG *a);
+int	i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp);
+DSA_SIG * d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length);
+
+DSA_SIG * DSA_do_sign(const unsigned char *dgst,int dlen,DSA *dsa);
+int	DSA_do_verify(const unsigned char *dgst,int dgst_len,
+		      DSA_SIG *sig,DSA *dsa);
+
+const DSA_METHOD *DSA_OpenSSL(void);
+
+void	DSA_set_default_method(const DSA_METHOD *);
+const DSA_METHOD *DSA_get_default_method(void);
+int	DSA_set_method(DSA *dsa, const DSA_METHOD *);
+
+DSA *	DSA_new(void);
+DSA *	DSA_new_method(ENGINE *engine);
+void	DSA_free (DSA *r);
+/* "up" the DSA object's reference count */
+int	DSA_up_ref(DSA *r);
+int	DSA_size(const DSA *);
+	/* next 4 return -1 on error */
+int	DSA_sign_setup( DSA *dsa,BN_CTX *ctx_in,BIGNUM **kinvp,BIGNUM **rp);
+int	DSA_sign(int type,const unsigned char *dgst,int dlen,
+		unsigned char *sig, unsigned int *siglen, DSA *dsa);
+int	DSA_verify(int type,const unsigned char *dgst,int dgst_len,
+		const unsigned char *sigbuf, int siglen, DSA *dsa);
+int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int DSA_set_ex_data(DSA *d, int idx, void *arg);
+void *DSA_get_ex_data(DSA *d, int idx);
+
+DSA *	d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length);
+DSA *	d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length);
+DSA * 	d2i_DSAparams(DSA **a, const unsigned char **pp, long length);
+
+/* Deprecated version */
+#ifndef OPENSSL_NO_DEPRECATED
+DSA *	DSA_generate_parameters(int bits,
+		unsigned char *seed,int seed_len,
+		int *counter_ret, unsigned long *h_ret,void
+		(*callback)(int, int, void *),void *cb_arg);
+#endif /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* New version */
+int	DSA_generate_parameters_ex(DSA *dsa, int bits,
+		const unsigned char *seed,int seed_len,
+		int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
+
+int	DSA_generate_key(DSA *a);
+int	i2d_DSAPublicKey(const DSA *a, unsigned char **pp);
+int 	i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
+int	i2d_DSAparams(const DSA *a,unsigned char **pp);
+
+#ifndef OPENSSL_NO_BIO
+int	DSAparams_print(BIO *bp, const DSA *x);
+int	DSA_print(BIO *bp, const DSA *x, int off);
+#endif
+#ifndef OPENSSL_NO_FP_API
+int	DSAparams_print_fp(FILE *fp, const DSA *x);
+int	DSA_print_fp(FILE *bp, const DSA *x, int off);
+#endif
+
+#define DSS_prime_checks 50
+/* Primality test according to FIPS PUB 186[-1], Appendix 2.1:
+ * 50 rounds of Rabin-Miller */
+#define DSA_is_prime(n, callback, cb_arg) \
+	BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg)
+
+#ifndef OPENSSL_NO_DH
+/* Convert DSA structure (key or just parameters) into DH structure
+ * (be careful to avoid small subgroup attacks when using this!) */
+DH *DSA_dup_DH(const DSA *r);
+#endif
+
+#define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \
+				EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL)
+
+#define	EVP_PKEY_CTRL_DSA_PARAMGEN_BITS		(EVP_PKEY_ALG_CTRL + 1)
+#define	EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS	(EVP_PKEY_ALG_CTRL + 2)
+#define	EVP_PKEY_CTRL_DSA_PARAMGEN_MD		(EVP_PKEY_ALG_CTRL + 3)
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_DSA_strings(void);
+
+/* Error codes for the DSA functions. */
+
+/* Function codes. */
+#define DSA_F_D2I_DSA_SIG				 110
+#define DSA_F_DO_DSA_PRINT				 104
+#define DSA_F_DSAPARAMS_PRINT				 100
+#define DSA_F_DSAPARAMS_PRINT_FP			 101
+#define DSA_F_DSA_DO_SIGN				 112
+#define DSA_F_DSA_DO_VERIFY				 113
+#define DSA_F_DSA_NEW_METHOD				 103
+#define DSA_F_DSA_PARAM_DECODE				 119
+#define DSA_F_DSA_PRINT_FP				 105
+#define DSA_F_DSA_PRIV_DECODE				 115
+#define DSA_F_DSA_PRIV_ENCODE				 116
+#define DSA_F_DSA_PUB_DECODE				 117
+#define DSA_F_DSA_PUB_ENCODE				 118
+#define DSA_F_DSA_SIGN					 106
+#define DSA_F_DSA_SIGN_SETUP				 107
+#define DSA_F_DSA_SIG_NEW				 109
+#define DSA_F_DSA_VERIFY				 108
+#define DSA_F_I2D_DSA_SIG				 111
+#define DSA_F_OLD_DSA_PRIV_DECODE			 122
+#define DSA_F_PKEY_DSA_CTRL				 120
+#define DSA_F_PKEY_DSA_KEYGEN				 121
+#define DSA_F_SIG_CB					 114
+
+/* Reason codes. */
+#define DSA_R_BAD_Q_VALUE				 102
+#define DSA_R_BN_DECODE_ERROR				 108
+#define DSA_R_BN_ERROR					 109
+#define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 100
+#define DSA_R_DECODE_ERROR				 104
+#define DSA_R_INVALID_DIGEST_TYPE			 106
+#define DSA_R_MISSING_PARAMETERS			 101
+#define DSA_R_MODULUS_TOO_LARGE				 103
+#define DSA_R_NO_PARAMETERS_SET				 107
+#define DSA_R_PARAMETER_ENCODING_ERROR			 105
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/dsa/dsa_ameth.c b/openssl/crypto/dsa/dsa_ameth.c
new file mode 100644
index 0000000..6413aae
--- /dev/null
+++ b/openssl/crypto/dsa/dsa_ameth.c
@@ -0,0 +1,657 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/dsa.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_CMS
+#include <openssl/cms.h>
+#endif
+#include "asn1_locl.h"
+
+static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+	{
+	const unsigned char *p, *pm;
+	int pklen, pmlen;
+	int ptype;
+	void *pval;
+	ASN1_STRING *pstr;
+	X509_ALGOR *palg;
+	ASN1_INTEGER *public_key = NULL;
+
+	DSA *dsa = NULL;
+
+	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
+		return 0;
+	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+
+	if (ptype == V_ASN1_SEQUENCE)
+		{
+		pstr = pval;	
+		pm = pstr->data;
+		pmlen = pstr->length;
+
+		if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
+			{
+			DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
+			goto err;
+			}
+
+		}
+	else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF))
+		{
+		if (!(dsa = DSA_new()))
+			{
+			DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+	else
+		{
+		DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR);
+		goto err;
+		}
+
+	if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen)))
+		{
+		DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
+		goto err;
+		}
+
+	if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
+		{
+		DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR);
+		goto err;
+		}
+
+	ASN1_INTEGER_free(public_key);
+	EVP_PKEY_assign_DSA(pkey, dsa);
+	return 1;
+
+	err:
+	if (public_key)
+		ASN1_INTEGER_free(public_key);
+	if (dsa)
+		DSA_free(dsa);
+	return 0;
+
+	}
+
+static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+	{
+	DSA *dsa;
+	void *pval = NULL;
+	int ptype;
+	unsigned char *penc = NULL;
+	int penclen;
+
+	dsa=pkey->pkey.dsa;
+	if (pkey->save_parameters && dsa->p && dsa->q && dsa->g)
+		{
+		ASN1_STRING *str;
+		str = ASN1_STRING_new();
+		str->length = i2d_DSAparams(dsa, &str->data);
+		if (str->length <= 0)
+			{
+			DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		pval = str;
+		ptype = V_ASN1_SEQUENCE;
+		}
+	else
+		ptype = V_ASN1_UNDEF;
+
+	dsa->write_params=0;
+
+	penclen = i2d_DSAPublicKey(dsa, &penc);
+
+	if (penclen <= 0)
+		{
+		DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA),
+				ptype, pval, penc, penclen))
+		return 1;
+
+	err:
+	if (penc)
+		OPENSSL_free(penc);
+	if (pval)
+		ASN1_STRING_free(pval);
+
+	return 0;
+	}
+
+/* In PKCS#8 DSA: you just get a private key integer and parameters in the
+ * AlgorithmIdentifier the pubkey must be recalculated.
+ */
+	
+static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
+	{
+	const unsigned char *p, *pm;
+	int pklen, pmlen;
+	int ptype;
+	void *pval;
+	ASN1_STRING *pstr;
+	X509_ALGOR *palg;
+	ASN1_INTEGER *privkey = NULL;
+	BN_CTX *ctx = NULL;
+
+	STACK_OF(ASN1_TYPE) *ndsa = NULL;
+	DSA *dsa = NULL;
+
+	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
+		return 0;
+	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+	/* Check for broken DSA PKCS#8, UGH! */
+	if (*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED))
+		{
+		ASN1_TYPE *t1, *t2;
+	    	if(!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen)))
+			goto decerr;
+		if (sk_ASN1_TYPE_num(ndsa) != 2)
+			goto decerr;
+		/* Handle Two broken types:
+	    	 * SEQUENCE {parameters, priv_key}
+		 * SEQUENCE {pub_key, priv_key}
+		 */
+
+		t1 = sk_ASN1_TYPE_value(ndsa, 0);
+		t2 = sk_ASN1_TYPE_value(ndsa, 1);
+		if (t1->type == V_ASN1_SEQUENCE)
+			{
+			p8->broken = PKCS8_EMBEDDED_PARAM;
+			pval = t1->value.ptr;
+			}
+		else if (ptype == V_ASN1_SEQUENCE)
+			p8->broken = PKCS8_NS_DB;
+		else
+			goto decerr;
+
+		if (t2->type != V_ASN1_INTEGER)
+			goto decerr;
+
+		privkey = t2->value.integer;
+		}
+	else
+		{
+		const unsigned char *q = p;
+		if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
+			goto decerr;
+		if (privkey->type == V_ASN1_NEG_INTEGER)
+			{
+			p8->broken = PKCS8_NEG_PRIVKEY;
+			ASN1_INTEGER_free(privkey);
+			if (!(privkey=d2i_ASN1_UINTEGER(NULL, &q, pklen)))
+				goto decerr;
+			}
+		if (ptype != V_ASN1_SEQUENCE)
+			goto decerr;
+		}
+
+	pstr = pval;	
+	pm = pstr->data;
+	pmlen = pstr->length;
+	if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
+		goto decerr;
+	/* We have parameters now set private key */
+	if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)))
+		{
+		DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
+		goto dsaerr;
+		}
+	/* Calculate public key */
+	if (!(dsa->pub_key = BN_new()))
+		{
+		DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
+		goto dsaerr;
+		}
+	if (!(ctx = BN_CTX_new()))
+		{
+		DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
+		goto dsaerr;
+		}
+			
+	if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx))
+		{
+		DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
+		goto dsaerr;
+		}
+
+	EVP_PKEY_assign_DSA(pkey, dsa);
+	BN_CTX_free (ctx);
+	if(ndsa)
+		sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
+	else
+		ASN1_INTEGER_free(privkey);
+
+	return 1;
+
+	decerr:
+	DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR);
+	dsaerr:
+	BN_CTX_free (ctx);
+	if (privkey)
+		ASN1_INTEGER_free(privkey);
+	sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
+	DSA_free(dsa);
+	return 0;
+	}
+
+static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+{
+	ASN1_STRING *params = NULL;
+	ASN1_INTEGER *prkey = NULL;
+	unsigned char *dp = NULL;
+	int dplen;
+
+	params = ASN1_STRING_new();
+
+	if (!params)
+		{
+		DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
+	if (params->length <= 0)
+		{
+		DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	params->type = V_ASN1_SEQUENCE;
+
+	/* Get private key into integer */
+	prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
+
+	if (!prkey)
+		{
+		DSAerr(DSA_F_DSA_PRIV_ENCODE,DSA_R_BN_ERROR);
+		goto err;
+		}
+
+	dplen = i2d_ASN1_INTEGER(prkey, &dp);
+
+	ASN1_INTEGER_free(prkey);
+
+	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0,
+				V_ASN1_SEQUENCE, params, dp, dplen))
+		goto err;
+
+	return 1;
+
+err:
+	if (dp != NULL)
+		OPENSSL_free(dp);
+	if (params != NULL)
+		ASN1_STRING_free(params);
+	if (prkey != NULL)
+		ASN1_INTEGER_free(prkey);
+	return 0;
+}
+
+static int int_dsa_size(const EVP_PKEY *pkey)
+	{
+	return(DSA_size(pkey->pkey.dsa));
+	}
+
+static int dsa_bits(const EVP_PKEY *pkey)
+	{
+	return BN_num_bits(pkey->pkey.dsa->p);
+	}
+
+static int dsa_missing_parameters(const EVP_PKEY *pkey)
+	{
+	DSA *dsa;
+	dsa=pkey->pkey.dsa;
+	if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
+			return 1;
+	return 0;
+	}
+
+static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+	{
+	BIGNUM *a;
+
+	if ((a=BN_dup(from->pkey.dsa->p)) == NULL)
+		return 0;
+	if (to->pkey.dsa->p != NULL)
+		BN_free(to->pkey.dsa->p);
+	to->pkey.dsa->p=a;
+
+	if ((a=BN_dup(from->pkey.dsa->q)) == NULL)
+		return 0;
+	if (to->pkey.dsa->q != NULL)
+		BN_free(to->pkey.dsa->q);
+	to->pkey.dsa->q=a;
+
+	if ((a=BN_dup(from->pkey.dsa->g)) == NULL)
+		return 0;
+	if (to->pkey.dsa->g != NULL)
+		BN_free(to->pkey.dsa->g);
+	to->pkey.dsa->g=a;
+	return 1;
+	}
+
+static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+	{
+	if (	BN_cmp(a->pkey.dsa->p,b->pkey.dsa->p) ||
+		BN_cmp(a->pkey.dsa->q,b->pkey.dsa->q) ||
+		BN_cmp(a->pkey.dsa->g,b->pkey.dsa->g))
+		return 0;
+	else
+		return 1;
+	}
+
+static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+	{
+	if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0)
+		return 0;
+	else
+		return 1;
+	}
+
+static void int_dsa_free(EVP_PKEY *pkey)
+	{
+	DSA_free(pkey->pkey.dsa);
+	}
+
+static void update_buflen(const BIGNUM *b, size_t *pbuflen)
+	{
+	size_t i;
+	if (!b)
+		return;
+	if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
+			*pbuflen = i;
+	}
+
+static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
+	{
+	unsigned char *m=NULL;
+	int ret=0;
+	size_t buf_len=0;
+	const char *ktype = NULL;
+
+	const BIGNUM *priv_key, *pub_key;
+
+	if (ptype == 2)
+		priv_key = x->priv_key;
+	else
+		priv_key = NULL;
+
+	if (ptype > 0)
+		pub_key = x->pub_key;
+	else
+		pub_key = NULL;
+
+	if (ptype == 2)
+		ktype = "Private-Key";
+	else if (ptype == 1)
+		ktype = "Public-Key";
+	else
+		ktype = "DSA-Parameters";
+
+	update_buflen(x->p, &buf_len);
+	update_buflen(x->q, &buf_len);
+	update_buflen(x->g, &buf_len);
+	update_buflen(priv_key, &buf_len);
+	update_buflen(pub_key, &buf_len);
+
+	m=(unsigned char *)OPENSSL_malloc(buf_len+10);
+	if (m == NULL)
+		{
+		DSAerr(DSA_F_DO_DSA_PRINT,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (priv_key)
+		{
+		if(!BIO_indent(bp,off,128))
+		   goto err;
+		if (BIO_printf(bp,"%s: (%d bit)\n",ktype, BN_num_bits(x->p))
+			<= 0) goto err;
+		}
+
+	if (!ASN1_bn_print(bp,"priv:",priv_key,m,off))
+		goto err;
+	if (!ASN1_bn_print(bp,"pub: ",pub_key,m,off))
+		goto err;
+	if (!ASN1_bn_print(bp,"P:   ",x->p,m,off)) goto err;
+	if (!ASN1_bn_print(bp,"Q:   ",x->q,m,off)) goto err;
+	if (!ASN1_bn_print(bp,"G:   ",x->g,m,off)) goto err;
+	ret=1;
+err:
+	if (m != NULL) OPENSSL_free(m);
+	return(ret);
+	}
+
+static int dsa_param_decode(EVP_PKEY *pkey,
+					const unsigned char **pder, int derlen)
+	{
+	DSA *dsa;
+	if (!(dsa = d2i_DSAparams(NULL, pder, derlen)))
+		{
+		DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB);
+		return 0;
+		}
+	EVP_PKEY_assign_DSA(pkey, dsa);
+	return 1;
+	}
+
+static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+	{
+	return i2d_DSAparams(pkey->pkey.dsa, pder);
+	}
+
+static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
+	}
+
+static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
+	}
+
+
+static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
+	}
+
+static int old_dsa_priv_decode(EVP_PKEY *pkey,
+					const unsigned char **pder, int derlen)
+	{
+	DSA *dsa;
+	if (!(dsa = d2i_DSAPrivateKey (NULL, pder, derlen)))
+		{
+		DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB);
+		return 0;
+		}
+	EVP_PKEY_assign_DSA(pkey, dsa);
+	return 1;
+	}
+
+static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
+	{
+	return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
+	}
+
+static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+	{
+	switch (op)
+		{
+		case ASN1_PKEY_CTRL_PKCS7_SIGN:
+		if (arg1 == 0)
+			{
+			int snid, hnid;
+			X509_ALGOR *alg1, *alg2;
+			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
+			if (alg1 == NULL || alg1->algorithm == NULL)
+				return -1;
+			hnid = OBJ_obj2nid(alg1->algorithm);
+			if (hnid == NID_undef)
+				return -1;
+			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
+				return -1; 
+			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
+			}
+		return 1;
+#ifndef OPENSSL_NO_CMS
+		case ASN1_PKEY_CTRL_CMS_SIGN:
+		if (arg1 == 0)
+			{
+			int snid, hnid;
+			X509_ALGOR *alg1, *alg2;
+			CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
+			if (alg1 == NULL || alg1->algorithm == NULL)
+				return -1;
+			hnid = OBJ_obj2nid(alg1->algorithm);
+			if (hnid == NID_undef)
+				return -1;
+			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
+				return -1; 
+			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
+			}
+		return 1;
+#endif
+
+		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+		*(int *)arg2 = NID_sha1;
+		return 2;
+
+		default:
+		return -2;
+
+		}
+
+	}
+
+/* NB these are sorted in pkey_id order, lowest first */
+
+const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = 
+	{
+
+		{
+		EVP_PKEY_DSA2,
+		EVP_PKEY_DSA,
+		ASN1_PKEY_ALIAS
+		},
+
+		{
+		EVP_PKEY_DSA1,
+		EVP_PKEY_DSA,
+		ASN1_PKEY_ALIAS
+		},
+
+		{
+		EVP_PKEY_DSA4,
+		EVP_PKEY_DSA,
+		ASN1_PKEY_ALIAS
+		},
+
+		{
+		EVP_PKEY_DSA3,
+		EVP_PKEY_DSA,
+		ASN1_PKEY_ALIAS
+		},
+
+		{
+		EVP_PKEY_DSA,
+		EVP_PKEY_DSA,
+		0,
+
+		"DSA",
+		"OpenSSL DSA method",
+
+		dsa_pub_decode,
+		dsa_pub_encode,
+		dsa_pub_cmp,
+		dsa_pub_print,
+
+		dsa_priv_decode,
+		dsa_priv_encode,
+		dsa_priv_print,
+
+		int_dsa_size,
+		dsa_bits,
+
+		dsa_param_decode,
+		dsa_param_encode,
+		dsa_missing_parameters,
+		dsa_copy_parameters,
+		dsa_cmp_parameters,
+		dsa_param_print,
+
+		int_dsa_free,
+		dsa_pkey_ctrl,
+		old_dsa_priv_decode,
+		old_dsa_priv_encode
+		}
+	};
+
diff --git a/openssl/crypto/dsa/dsa_asn1.c b/openssl/crypto/dsa/dsa_asn1.c
new file mode 100644
index 0000000..c37460b
--- /dev/null
+++ b/openssl/crypto/dsa/dsa_asn1.c
@@ -0,0 +1,150 @@
+/* dsa_asn1.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/dsa.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+/* Override the default new methods */
+static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+								void *exarg)
+{
+	if(operation == ASN1_OP_NEW_PRE) {
+		DSA_SIG *sig;
+		sig = OPENSSL_malloc(sizeof(DSA_SIG));
+		if (!sig)
+			{
+			DSAerr(DSA_F_SIG_CB, ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		sig->r = NULL;
+		sig->s = NULL;
+		*pval = (ASN1_VALUE *)sig;
+		return 2;
+	}
+	return 1;
+}
+
+ASN1_SEQUENCE_cb(DSA_SIG, sig_cb) = {
+	ASN1_SIMPLE(DSA_SIG, r, CBIGNUM),
+	ASN1_SIMPLE(DSA_SIG, s, CBIGNUM)
+} ASN1_SEQUENCE_END_cb(DSA_SIG, DSA_SIG)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(DSA_SIG)
+
+/* Override the default free and new methods */
+static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
+{
+	if(operation == ASN1_OP_NEW_PRE) {
+		*pval = (ASN1_VALUE *)DSA_new();
+		if(*pval) return 2;
+		return 0;
+	} else if(operation == ASN1_OP_FREE_PRE) {
+		DSA_free((DSA *)*pval);
+		*pval = NULL;
+		return 2;
+	}
+	return 1;
+}
+
+ASN1_SEQUENCE_cb(DSAPrivateKey, dsa_cb) = {
+	ASN1_SIMPLE(DSA, version, LONG),
+	ASN1_SIMPLE(DSA, p, BIGNUM),
+	ASN1_SIMPLE(DSA, q, BIGNUM),
+	ASN1_SIMPLE(DSA, g, BIGNUM),
+	ASN1_SIMPLE(DSA, pub_key, BIGNUM),
+	ASN1_SIMPLE(DSA, priv_key, BIGNUM)
+} ASN1_SEQUENCE_END_cb(DSA, DSAPrivateKey)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPrivateKey, DSAPrivateKey)
+
+ASN1_SEQUENCE_cb(DSAparams, dsa_cb) = {
+	ASN1_SIMPLE(DSA, p, BIGNUM),
+	ASN1_SIMPLE(DSA, q, BIGNUM),
+	ASN1_SIMPLE(DSA, g, BIGNUM),
+} ASN1_SEQUENCE_END_cb(DSA, DSAparams)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAparams, DSAparams)
+
+/* DSA public key is a bit trickier... its effectively a CHOICE type
+ * decided by a field called write_params which can either write out
+ * just the public key as an INTEGER or the parameters and public key
+ * in a SEQUENCE
+ */
+
+ASN1_SEQUENCE(dsa_pub_internal) = {
+	ASN1_SIMPLE(DSA, pub_key, BIGNUM),
+	ASN1_SIMPLE(DSA, p, BIGNUM),
+	ASN1_SIMPLE(DSA, q, BIGNUM),
+	ASN1_SIMPLE(DSA, g, BIGNUM)
+} ASN1_SEQUENCE_END_name(DSA, dsa_pub_internal)
+
+ASN1_CHOICE_cb(DSAPublicKey, dsa_cb) = {
+	ASN1_SIMPLE(DSA, pub_key, BIGNUM),
+	ASN1_EX_COMBINE(0, 0, dsa_pub_internal)
+} ASN1_CHOICE_END_cb(DSA, DSAPublicKey, write_params)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey)
+
+DSA *DSAparams_dup(DSA *dsa)
+	{
+	return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa);
+	}
diff --git a/openssl/crypto/dsa/dsa_depr.c b/openssl/crypto/dsa/dsa_depr.c
new file mode 100644
index 0000000..f2da680
--- /dev/null
+++ b/openssl/crypto/dsa/dsa_depr.c
@@ -0,0 +1,106 @@
+/* crypto/dsa/dsa_depr.c */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* This file contains deprecated function(s) that are now wrappers to the new
+ * version(s). */
+
+#undef GENUINE_DSA
+
+#ifdef GENUINE_DSA
+/* Parameter generation follows the original release of FIPS PUB 186,
+ * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) */
+#define HASH    EVP_sha()
+#else
+/* Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
+ * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in
+ * FIPS PUB 180-1) */
+#define HASH    EVP_sha1()
+#endif 
+
+static void *dummy=&dummy;
+
+#ifndef OPENSSL_NO_SHA
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+#ifndef OPENSSL_NO_DEPRECATED
+DSA *DSA_generate_parameters(int bits,
+		unsigned char *seed_in, int seed_len,
+		int *counter_ret, unsigned long *h_ret,
+		void (*callback)(int, int, void *),
+		void *cb_arg)
+	{
+	BN_GENCB cb;
+	DSA *ret;
+
+	if ((ret=DSA_new()) == NULL) return NULL;
+
+	BN_GENCB_set_old(&cb, callback, cb_arg);
+
+	if(DSA_generate_parameters_ex(ret, bits, seed_in, seed_len,
+				counter_ret, h_ret, &cb))
+		return ret;
+	DSA_free(ret);
+	return NULL;
+	}
+#endif
+#endif
diff --git a/openssl/crypto/dsa/dsa_err.c b/openssl/crypto/dsa/dsa_err.c
new file mode 100644
index 0000000..bba984e
--- /dev/null
+++ b/openssl/crypto/dsa/dsa_err.c
@@ -0,0 +1,125 @@
+/* crypto/dsa/dsa_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/dsa.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSA,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSA,0,reason)
+
+static ERR_STRING_DATA DSA_str_functs[]=
+	{
+{ERR_FUNC(DSA_F_D2I_DSA_SIG),	"d2i_DSA_SIG"},
+{ERR_FUNC(DSA_F_DO_DSA_PRINT),	"DO_DSA_PRINT"},
+{ERR_FUNC(DSA_F_DSAPARAMS_PRINT),	"DSAparams_print"},
+{ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP),	"DSAparams_print_fp"},
+{ERR_FUNC(DSA_F_DSA_DO_SIGN),	"DSA_do_sign"},
+{ERR_FUNC(DSA_F_DSA_DO_VERIFY),	"DSA_do_verify"},
+{ERR_FUNC(DSA_F_DSA_NEW_METHOD),	"DSA_new_method"},
+{ERR_FUNC(DSA_F_DSA_PARAM_DECODE),	"DSA_PARAM_DECODE"},
+{ERR_FUNC(DSA_F_DSA_PRINT_FP),	"DSA_print_fp"},
+{ERR_FUNC(DSA_F_DSA_PRIV_DECODE),	"DSA_PRIV_DECODE"},
+{ERR_FUNC(DSA_F_DSA_PRIV_ENCODE),	"DSA_PRIV_ENCODE"},
+{ERR_FUNC(DSA_F_DSA_PUB_DECODE),	"DSA_PUB_DECODE"},
+{ERR_FUNC(DSA_F_DSA_PUB_ENCODE),	"DSA_PUB_ENCODE"},
+{ERR_FUNC(DSA_F_DSA_SIGN),	"DSA_sign"},
+{ERR_FUNC(DSA_F_DSA_SIGN_SETUP),	"DSA_sign_setup"},
+{ERR_FUNC(DSA_F_DSA_SIG_NEW),	"DSA_SIG_new"},
+{ERR_FUNC(DSA_F_DSA_VERIFY),	"DSA_verify"},
+{ERR_FUNC(DSA_F_I2D_DSA_SIG),	"i2d_DSA_SIG"},
+{ERR_FUNC(DSA_F_OLD_DSA_PRIV_DECODE),	"OLD_DSA_PRIV_DECODE"},
+{ERR_FUNC(DSA_F_PKEY_DSA_CTRL),	"PKEY_DSA_CTRL"},
+{ERR_FUNC(DSA_F_PKEY_DSA_KEYGEN),	"PKEY_DSA_KEYGEN"},
+{ERR_FUNC(DSA_F_SIG_CB),	"SIG_CB"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA DSA_str_reasons[]=
+	{
+{ERR_REASON(DSA_R_BAD_Q_VALUE)           ,"bad q value"},
+{ERR_REASON(DSA_R_BN_DECODE_ERROR)       ,"bn decode error"},
+{ERR_REASON(DSA_R_BN_ERROR)              ,"bn error"},
+{ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"},
+{ERR_REASON(DSA_R_DECODE_ERROR)          ,"decode error"},
+{ERR_REASON(DSA_R_INVALID_DIGEST_TYPE)   ,"invalid digest type"},
+{ERR_REASON(DSA_R_MISSING_PARAMETERS)    ,"missing parameters"},
+{ERR_REASON(DSA_R_MODULUS_TOO_LARGE)     ,"modulus too large"},
+{ERR_REASON(DSA_R_NO_PARAMETERS_SET)     ,"no parameters set"},
+{ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_DSA_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(DSA_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,DSA_str_functs);
+		ERR_load_strings(0,DSA_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/dsa/dsa_gen.c b/openssl/crypto/dsa/dsa_gen.c
new file mode 100644
index 0000000..cb0b453
--- /dev/null
+++ b/openssl/crypto/dsa/dsa_gen.c
@@ -0,0 +1,344 @@
+/* crypto/dsa/dsa_gen.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#undef GENUINE_DSA
+
+#ifdef GENUINE_DSA
+/* Parameter generation follows the original release of FIPS PUB 186,
+ * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) */
+#define HASH    EVP_sha()
+#else
+/* Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
+ * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in
+ * FIPS PUB 180-1) */
+#define HASH    EVP_sha1()
+#endif 
+
+#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_SHA is defined */
+
+#ifndef OPENSSL_NO_SHA
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+#include "dsa_locl.h"
+
+int DSA_generate_parameters_ex(DSA *ret, int bits,
+		const unsigned char *seed_in, int seed_len,
+		int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
+	{
+	if(ret->meth->dsa_paramgen)
+		return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
+				counter_ret, h_ret, cb);
+	else
+		{
+		const EVP_MD *evpmd;
+		size_t qbits = bits >= 2048 ? 256 : 160;
+
+		if (bits >= 2048)
+			{
+			qbits = 256;
+			evpmd = EVP_sha256();
+			}
+		else
+			{
+			qbits = 160;
+			evpmd = EVP_sha1();
+			}
+
+		return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
+				seed_in, seed_len, counter_ret, h_ret, cb);
+		}
+	}
+
+int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
+	const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
+	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
+	{
+	int ok=0;
+	unsigned char seed[SHA256_DIGEST_LENGTH];
+	unsigned char md[SHA256_DIGEST_LENGTH];
+	unsigned char buf[SHA256_DIGEST_LENGTH],buf2[SHA256_DIGEST_LENGTH];
+	BIGNUM *r0,*W,*X,*c,*test;
+	BIGNUM *g=NULL,*q=NULL,*p=NULL;
+	BN_MONT_CTX *mont=NULL;
+	int i, k, n=0, m=0, qsize = qbits >> 3;
+	int counter=0;
+	int r=0;
+	BN_CTX *ctx=NULL;
+	unsigned int h=2;
+
+	if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
+	    qsize != SHA256_DIGEST_LENGTH)
+		/* invalid q size */
+		return 0;
+
+	if (evpmd == NULL)
+		/* use SHA1 as default */
+		evpmd = EVP_sha1();
+
+	if (bits < 512)
+		bits = 512;
+
+	bits = (bits+63)/64*64;
+
+	/* NB: seed_len == 0 is special case: copy generated seed to
+ 	 * seed_in if it is not NULL.
+ 	 */
+	if (seed_len && (seed_len < (size_t)qsize))
+		seed_in = NULL;		/* seed buffer too small -- ignore */
+	if (seed_len > (size_t)qsize) 
+		seed_len = qsize;	/* App. 2.2 of FIPS PUB 186 allows larger SEED,
+					 * but our internal buffers are restricted to 160 bits*/
+	if (seed_in != NULL)
+		memcpy(seed, seed_in, seed_len);
+
+	if ((ctx=BN_CTX_new()) == NULL)
+		goto err;
+
+	if ((mont=BN_MONT_CTX_new()) == NULL)
+		goto err;
+
+	BN_CTX_start(ctx);
+	r0 = BN_CTX_get(ctx);
+	g = BN_CTX_get(ctx);
+	W = BN_CTX_get(ctx);
+	q = BN_CTX_get(ctx);
+	X = BN_CTX_get(ctx);
+	c = BN_CTX_get(ctx);
+	p = BN_CTX_get(ctx);
+	test = BN_CTX_get(ctx);
+
+	if (!BN_lshift(test,BN_value_one(),bits-1))
+		goto err;
+
+	for (;;)
+		{
+		for (;;) /* find q */
+			{
+			int seed_is_random;
+
+			/* step 1 */
+			if(!BN_GENCB_call(cb, 0, m++))
+				goto err;
+
+			if (!seed_len)
+				{
+				RAND_pseudo_bytes(seed, qsize);
+				seed_is_random = 1;
+				}
+			else
+				{
+				seed_is_random = 0;
+				seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/
+				}
+			memcpy(buf , seed, qsize);
+			memcpy(buf2, seed, qsize);
+			/* precompute "SEED + 1" for step 7: */
+			for (i = qsize-1; i >= 0; i--)
+				{
+				buf[i]++;
+				if (buf[i] != 0)
+					break;
+				}
+
+			/* step 2 */
+			EVP_Digest(seed, qsize, md,   NULL, evpmd, NULL);
+			EVP_Digest(buf,  qsize, buf2, NULL, evpmd, NULL);
+			for (i = 0; i < qsize; i++)
+				md[i]^=buf2[i];
+
+			/* step 3 */
+			md[0] |= 0x80;
+			md[qsize-1] |= 0x01;
+			if (!BN_bin2bn(md, qsize, q))
+				goto err;
+
+			/* step 4 */
+			r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
+					seed_is_random, cb);
+			if (r > 0)
+				break;
+			if (r != 0)
+				goto err;
+
+			/* do a callback call */
+			/* step 5 */
+			}
+
+		if(!BN_GENCB_call(cb, 2, 0)) goto err;
+		if(!BN_GENCB_call(cb, 3, 0)) goto err;
+
+		/* step 6 */
+		counter=0;
+		/* "offset = 2" */
+
+		n=(bits-1)/160;
+
+		for (;;)
+			{
+			if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
+				goto err;
+
+			/* step 7 */
+			BN_zero(W);
+			/* now 'buf' contains "SEED + offset - 1" */
+			for (k=0; k<=n; k++)
+				{
+				/* obtain "SEED + offset + k" by incrementing: */
+				for (i = qsize-1; i >= 0; i--)
+					{
+					buf[i]++;
+					if (buf[i] != 0)
+						break;
+					}
+
+				EVP_Digest(buf, qsize, md ,NULL, evpmd, NULL);
+
+				/* step 8 */
+				if (!BN_bin2bn(md, qsize, r0))
+					goto err;
+				if (!BN_lshift(r0,r0,(qsize << 3)*k)) goto err;
+				if (!BN_add(W,W,r0)) goto err;
+				}
+
+			/* more of step 8 */
+			if (!BN_mask_bits(W,bits-1)) goto err;
+			if (!BN_copy(X,W)) goto err;
+			if (!BN_add(X,X,test)) goto err;
+
+			/* step 9 */
+			if (!BN_lshift1(r0,q)) goto err;
+			if (!BN_mod(c,X,r0,ctx)) goto err;
+			if (!BN_sub(r0,c,BN_value_one())) goto err;
+			if (!BN_sub(p,X,r0)) goto err;
+
+			/* step 10 */
+			if (BN_cmp(p,test) >= 0)
+				{
+				/* step 11 */
+				r = BN_is_prime_fasttest_ex(p, DSS_prime_checks,
+						ctx, 1, cb);
+				if (r > 0)
+						goto end; /* found it */
+				if (r != 0)
+					goto err;
+				}
+
+			/* step 13 */
+			counter++;
+			/* "offset = offset + n + 1" */
+
+			/* step 14 */
+			if (counter >= 4096) break;
+			}
+		}
+end:
+	if(!BN_GENCB_call(cb, 2, 1))
+		goto err;
+
+	/* We now need to generate g */
+	/* Set r0=(p-1)/q */
+	if (!BN_sub(test,p,BN_value_one())) goto err;
+	if (!BN_div(r0,NULL,test,q,ctx)) goto err;
+
+	if (!BN_set_word(test,h)) goto err;
+	if (!BN_MONT_CTX_set(mont,p,ctx)) goto err;
+
+	for (;;)
+		{
+		/* g=test^r0%p */
+		if (!BN_mod_exp_mont(g,test,r0,p,ctx,mont)) goto err;
+		if (!BN_is_one(g)) break;
+		if (!BN_add(test,test,BN_value_one())) goto err;
+		h++;
+		}
+
+	if(!BN_GENCB_call(cb, 3, 1))
+		goto err;
+
+	ok=1;
+err:
+	if (ok)
+		{
+		if(ret->p) BN_free(ret->p);
+		if(ret->q) BN_free(ret->q);
+		if(ret->g) BN_free(ret->g);
+		ret->p=BN_dup(p);
+		ret->q=BN_dup(q);
+		ret->g=BN_dup(g);
+		if (ret->p == NULL || ret->q == NULL || ret->g == NULL)
+			{
+			ok=0;
+			goto err;
+			}
+		if (counter_ret != NULL) *counter_ret=counter;
+		if (h_ret != NULL) *h_ret=h;
+		}
+	if(ctx)
+		{
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+		}
+	if (mont != NULL) BN_MONT_CTX_free(mont);
+	return ok;
+	}
+#endif
diff --git a/openssl/crypto/dsa/dsa_key.c b/openssl/crypto/dsa/dsa_key.c
new file mode 100644
index 0000000..c4aa86b
--- /dev/null
+++ b/openssl/crypto/dsa/dsa_key.c
@@ -0,0 +1,128 @@
+/* crypto/dsa/dsa_key.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#ifndef OPENSSL_NO_SHA
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+
+static int dsa_builtin_keygen(DSA *dsa);
+
+int DSA_generate_key(DSA *dsa)
+	{
+	if(dsa->meth->dsa_keygen)
+		return dsa->meth->dsa_keygen(dsa);
+	return dsa_builtin_keygen(dsa);
+	}
+
+static int dsa_builtin_keygen(DSA *dsa)
+	{
+	int ok=0;
+	BN_CTX *ctx=NULL;
+	BIGNUM *pub_key=NULL,*priv_key=NULL;
+
+	if ((ctx=BN_CTX_new()) == NULL) goto err;
+
+	if (dsa->priv_key == NULL)
+		{
+		if ((priv_key=BN_new()) == NULL) goto err;
+		}
+	else
+		priv_key=dsa->priv_key;
+
+	do
+		if (!BN_rand_range(priv_key,dsa->q)) goto err;
+	while (BN_is_zero(priv_key));
+
+	if (dsa->pub_key == NULL)
+		{
+		if ((pub_key=BN_new()) == NULL) goto err;
+		}
+	else
+		pub_key=dsa->pub_key;
+	
+	{
+		BIGNUM local_prk;
+		BIGNUM *prk;
+
+		if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
+			{
+			BN_init(&local_prk);
+			prk = &local_prk;
+			BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
+			}
+		else
+			prk = priv_key;
+
+		if (!BN_mod_exp(pub_key,dsa->g,prk,dsa->p,ctx)) goto err;
+	}
+
+	dsa->priv_key=priv_key;
+	dsa->pub_key=pub_key;
+	ok=1;
+
+err:
+	if ((pub_key != NULL) && (dsa->pub_key == NULL)) BN_free(pub_key);
+	if ((priv_key != NULL) && (dsa->priv_key == NULL)) BN_free(priv_key);
+	if (ctx != NULL) BN_CTX_free(ctx);
+	return(ok);
+	}
+#endif
diff --git a/openssl/crypto/dsa/dsa_lib.c b/openssl/crypto/dsa/dsa_lib.c
new file mode 100644
index 0000000..e9b7590
--- /dev/null
+++ b/openssl/crypto/dsa/dsa_lib.c
@@ -0,0 +1,311 @@
+/* crypto/dsa/dsa_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/asn1.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+
+const char DSA_version[]="DSA" OPENSSL_VERSION_PTEXT;
+
+static const DSA_METHOD *default_DSA_method = NULL;
+
+void DSA_set_default_method(const DSA_METHOD *meth)
+	{
+	default_DSA_method = meth;
+	}
+
+const DSA_METHOD *DSA_get_default_method(void)
+	{
+	if(!default_DSA_method)
+		default_DSA_method = DSA_OpenSSL();
+	return default_DSA_method;
+	}
+
+DSA *DSA_new(void)
+	{
+	return DSA_new_method(NULL);
+	}
+
+int DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
+	{
+	/* NB: The caller is specifically setting a method, so it's not up to us
+	 * to deal with which ENGINE it comes from. */
+        const DSA_METHOD *mtmp;
+        mtmp = dsa->meth;
+        if (mtmp->finish) mtmp->finish(dsa);
+#ifndef OPENSSL_NO_ENGINE
+	if (dsa->engine)
+		{
+		ENGINE_finish(dsa->engine);
+		dsa->engine = NULL;
+		}
+#endif
+        dsa->meth = meth;
+        if (meth->init) meth->init(dsa);
+        return 1;
+	}
+
+DSA *DSA_new_method(ENGINE *engine)
+	{
+	DSA *ret;
+
+	ret=(DSA *)OPENSSL_malloc(sizeof(DSA));
+	if (ret == NULL)
+		{
+		DSAerr(DSA_F_DSA_NEW_METHOD,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	ret->meth = DSA_get_default_method();
+#ifndef OPENSSL_NO_ENGINE
+	if (engine)
+		{
+		if (!ENGINE_init(engine))
+			{
+			DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
+			OPENSSL_free(ret);
+			return NULL;
+			}
+		ret->engine = engine;
+		}
+	else
+		ret->engine = ENGINE_get_default_DSA();
+	if(ret->engine)
+		{
+		ret->meth = ENGINE_get_DSA(ret->engine);
+		if(!ret->meth)
+			{
+			DSAerr(DSA_F_DSA_NEW_METHOD,
+				ERR_R_ENGINE_LIB);
+			ENGINE_finish(ret->engine);
+			OPENSSL_free(ret);
+			return NULL;
+			}
+		}
+#endif
+
+	ret->pad=0;
+	ret->version=0;
+	ret->write_params=1;
+	ret->p=NULL;
+	ret->q=NULL;
+	ret->g=NULL;
+
+	ret->pub_key=NULL;
+	ret->priv_key=NULL;
+
+	ret->kinv=NULL;
+	ret->r=NULL;
+	ret->method_mont_p=NULL;
+
+	ret->references=1;
+	ret->flags=ret->meth->flags;
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data);
+	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
+		{
+#ifndef OPENSSL_NO_ENGINE
+		if (ret->engine)
+			ENGINE_finish(ret->engine);
+#endif
+		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data);
+		OPENSSL_free(ret);
+		ret=NULL;
+		}
+	
+	return(ret);
+	}
+
+void DSA_free(DSA *r)
+	{
+	int i;
+
+	if (r == NULL) return;
+
+	i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_DSA);
+#ifdef REF_PRINT
+	REF_PRINT("DSA",r);
+#endif
+	if (i > 0) return;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"DSA_free, bad reference count\n");
+		abort();
+		}
+#endif
+
+	if(r->meth->finish)
+		r->meth->finish(r);
+#ifndef OPENSSL_NO_ENGINE
+	if(r->engine)
+		ENGINE_finish(r->engine);
+#endif
+
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data);
+
+	if (r->p != NULL) BN_clear_free(r->p);
+	if (r->q != NULL) BN_clear_free(r->q);
+	if (r->g != NULL) BN_clear_free(r->g);
+	if (r->pub_key != NULL) BN_clear_free(r->pub_key);
+	if (r->priv_key != NULL) BN_clear_free(r->priv_key);
+	if (r->kinv != NULL) BN_clear_free(r->kinv);
+	if (r->r != NULL) BN_clear_free(r->r);
+	OPENSSL_free(r);
+	}
+
+int DSA_up_ref(DSA *r)
+	{
+	int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DSA);
+#ifdef REF_PRINT
+	REF_PRINT("DSA",r);
+#endif
+#ifdef REF_CHECK
+	if (i < 2)
+		{
+		fprintf(stderr, "DSA_up_ref, bad reference count\n");
+		abort();
+		}
+#endif
+	return ((i > 1) ? 1 : 0);
+	}
+
+int DSA_size(const DSA *r)
+	{
+	int ret,i;
+	ASN1_INTEGER bs;
+	unsigned char buf[4];	/* 4 bytes looks really small.
+				   However, i2d_ASN1_INTEGER() will not look
+				   beyond the first byte, as long as the second
+				   parameter is NULL. */
+
+	i=BN_num_bits(r->q);
+	bs.length=(i+7)/8;
+	bs.data=buf;
+	bs.type=V_ASN1_INTEGER;
+	/* If the top bit is set the asn1 encoding is 1 larger. */
+	buf[0]=0xff;	
+
+	i=i2d_ASN1_INTEGER(&bs,NULL);
+	i+=i; /* r and s */
+	ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
+	return(ret);
+	}
+
+int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+        {
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DSA, argl, argp,
+				new_func, dup_func, free_func);
+        }
+
+int DSA_set_ex_data(DSA *d, int idx, void *arg)
+	{
+	return(CRYPTO_set_ex_data(&d->ex_data,idx,arg));
+	}
+
+void *DSA_get_ex_data(DSA *d, int idx)
+	{
+	return(CRYPTO_get_ex_data(&d->ex_data,idx));
+	}
+
+#ifndef OPENSSL_NO_DH
+DH *DSA_dup_DH(const DSA *r)
+	{
+	/* DSA has p, q, g, optional pub_key, optional priv_key.
+	 * DH has p, optional length, g, optional pub_key, optional priv_key.
+	 */ 
+
+	DH *ret = NULL;
+
+	if (r == NULL)
+		goto err;
+	ret = DH_new();
+	if (ret == NULL)
+		goto err;
+	if (r->p != NULL) 
+		if ((ret->p = BN_dup(r->p)) == NULL)
+			goto err;
+	if (r->q != NULL)
+		ret->length = BN_num_bits(r->q);
+	if (r->g != NULL)
+		if ((ret->g = BN_dup(r->g)) == NULL)
+			goto err;
+	if (r->pub_key != NULL)
+		if ((ret->pub_key = BN_dup(r->pub_key)) == NULL)
+			goto err;
+	if (r->priv_key != NULL)
+		if ((ret->priv_key = BN_dup(r->priv_key)) == NULL)
+			goto err;
+
+	return ret;
+
+ err:
+	if (ret != NULL)
+		DH_free(ret);
+	return NULL;
+	}
+#endif
diff --git a/openssl/crypto/dsa/dsa_locl.h b/openssl/crypto/dsa/dsa_locl.h
new file mode 100644
index 0000000..2b8cfee
--- /dev/null
+++ b/openssl/crypto/dsa/dsa_locl.h
@@ -0,0 +1,59 @@
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/dsa.h>
+
+int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
+	const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
+	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
diff --git a/openssl/crypto/dsa/dsa_ossl.c b/openssl/crypto/dsa/dsa_ossl.c
new file mode 100644
index 0000000..a3ddd7d
--- /dev/null
+++ b/openssl/crypto/dsa/dsa_ossl.c
@@ -0,0 +1,398 @@
+/* crypto/dsa/dsa_ossl.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/sha.h>
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+#include <openssl/asn1.h>
+
+static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
+static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
+			 DSA *dsa);
+static int dsa_init(DSA *dsa);
+static int dsa_finish(DSA *dsa);
+
+static DSA_METHOD openssl_dsa_meth = {
+"OpenSSL DSA method",
+dsa_do_sign,
+dsa_sign_setup,
+dsa_do_verify,
+NULL, /* dsa_mod_exp, */
+NULL, /* dsa_bn_mod_exp, */
+dsa_init,
+dsa_finish,
+0,
+NULL,
+NULL,
+NULL
+};
+
+/* These macro wrappers replace attempts to use the dsa_mod_exp() and
+ * bn_mod_exp() handlers in the DSA_METHOD structure. We avoid the problem of
+ * having a the macro work as an expression by bundling an "err_instr". So;
+ * 
+ *     if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,&k,dsa->p,ctx,
+ *                 dsa->method_mont_p)) goto err;
+ *
+ * can be replaced by;
+ *
+ *     DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, &k, dsa->p, ctx,
+ *                 dsa->method_mont_p);
+ */
+
+#define DSA_MOD_EXP(err_instr,dsa,rr,a1,p1,a2,p2,m,ctx,in_mont) \
+	do { \
+	int _tmp_res53; \
+	if((dsa)->meth->dsa_mod_exp) \
+		_tmp_res53 = (dsa)->meth->dsa_mod_exp((dsa), (rr), (a1), (p1), \
+				(a2), (p2), (m), (ctx), (in_mont)); \
+	else \
+		_tmp_res53 = BN_mod_exp2_mont((rr), (a1), (p1), (a2), (p2), \
+				(m), (ctx), (in_mont)); \
+	if(!_tmp_res53) err_instr; \
+	} while(0)
+#define DSA_BN_MOD_EXP(err_instr,dsa,r,a,p,m,ctx,m_ctx) \
+	do { \
+	int _tmp_res53; \
+	if((dsa)->meth->bn_mod_exp) \
+		_tmp_res53 = (dsa)->meth->bn_mod_exp((dsa), (r), (a), (p), \
+				(m), (ctx), (m_ctx)); \
+	else \
+		_tmp_res53 = BN_mod_exp_mont((r), (a), (p), (m), (ctx), (m_ctx)); \
+	if(!_tmp_res53) err_instr; \
+	} while(0)
+
+const DSA_METHOD *DSA_OpenSSL(void)
+{
+	return &openssl_dsa_meth;
+}
+
+static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+	{
+	BIGNUM *kinv=NULL,*r=NULL,*s=NULL;
+	BIGNUM m;
+	BIGNUM xr;
+	BN_CTX *ctx=NULL;
+	int reason=ERR_R_BN_LIB;
+	DSA_SIG *ret=NULL;
+
+	BN_init(&m);
+	BN_init(&xr);
+
+	if (!dsa->p || !dsa->q || !dsa->g)
+		{
+		reason=DSA_R_MISSING_PARAMETERS;
+		goto err;
+		}
+
+	s=BN_new();
+	if (s == NULL) goto err;
+	ctx=BN_CTX_new();
+	if (ctx == NULL) goto err;
+
+	if ((dsa->kinv == NULL) || (dsa->r == NULL))
+		{
+		if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err;
+		}
+	else
+		{
+		kinv=dsa->kinv;
+		dsa->kinv=NULL;
+		r=dsa->r;
+		dsa->r=NULL;
+		}
+
+	
+	if (dlen > BN_num_bytes(dsa->q))
+		/* if the digest length is greater than the size of q use the
+		 * BN_num_bits(dsa->q) leftmost bits of the digest, see
+		 * fips 186-3, 4.2 */
+		dlen = BN_num_bytes(dsa->q);
+	if (BN_bin2bn(dgst,dlen,&m) == NULL)
+		goto err;
+
+	/* Compute  s = inv(k) (m + xr) mod q */
+	if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */
+	if (!BN_add(s, &xr, &m)) goto err;		/* s = m + xr */
+	if (BN_cmp(s,dsa->q) > 0)
+		if (!BN_sub(s,s,dsa->q)) goto err;
+	if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err;
+
+	ret=DSA_SIG_new();
+	if (ret == NULL) goto err;
+	ret->r = r;
+	ret->s = s;
+	
+err:
+	if (!ret)
+		{
+		DSAerr(DSA_F_DSA_DO_SIGN,reason);
+		BN_free(r);
+		BN_free(s);
+		}
+	if (ctx != NULL) BN_CTX_free(ctx);
+	BN_clear_free(&m);
+	BN_clear_free(&xr);
+	if (kinv != NULL) /* dsa->kinv is NULL now if we used it */
+	    BN_clear_free(kinv);
+	return(ret);
+	}
+
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+	{
+	BN_CTX *ctx;
+	BIGNUM k,kq,*K,*kinv=NULL,*r=NULL;
+	int ret=0;
+
+	if (!dsa->p || !dsa->q || !dsa->g)
+		{
+		DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS);
+		return 0;
+		}
+
+	BN_init(&k);
+	BN_init(&kq);
+
+	if (ctx_in == NULL)
+		{
+		if ((ctx=BN_CTX_new()) == NULL) goto err;
+		}
+	else
+		ctx=ctx_in;
+
+	if ((r=BN_new()) == NULL) goto err;
+
+	/* Get random k */
+	do
+		if (!BN_rand_range(&k, dsa->q)) goto err;
+	while (BN_is_zero(&k));
+	if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
+		{
+		BN_set_flags(&k, BN_FLG_CONSTTIME);
+		}
+
+	if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
+		{
+		if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
+						CRYPTO_LOCK_DSA,
+						dsa->p, ctx))
+			goto err;
+		}
+
+	/* Compute r = (g^k mod p) mod q */
+
+	if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
+		{
+		if (!BN_copy(&kq, &k)) goto err;
+
+		/* We do not want timing information to leak the length of k,
+		 * so we compute g^k using an equivalent exponent of fixed length.
+		 *
+		 * (This is a kludge that we need because the BN_mod_exp_mont()
+		 * does not let us specify the desired timing behaviour.) */
+
+		if (!BN_add(&kq, &kq, dsa->q)) goto err;
+		if (BN_num_bits(&kq) <= BN_num_bits(dsa->q))
+			{
+			if (!BN_add(&kq, &kq, dsa->q)) goto err;
+			}
+
+		K = &kq;
+		}
+	else
+		{
+		K = &k;
+		}
+	DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx,
+			dsa->method_mont_p);
+	if (!BN_mod(r,r,dsa->q,ctx)) goto err;
+
+	/* Compute  part of 's = inv(k) (m + xr) mod q' */
+	if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err;
+
+	if (*kinvp != NULL) BN_clear_free(*kinvp);
+	*kinvp=kinv;
+	kinv=NULL;
+	if (*rp != NULL) BN_clear_free(*rp);
+	*rp=r;
+	ret=1;
+err:
+	if (!ret)
+		{
+		DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB);
+		if (r != NULL)
+			BN_clear_free(r);
+		}
+	if (ctx_in == NULL) BN_CTX_free(ctx);
+	BN_clear_free(&k);
+	BN_clear_free(&kq);
+	return(ret);
+	}
+
+static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
+			 DSA *dsa)
+	{
+	BN_CTX *ctx;
+	BIGNUM u1,u2,t1;
+	BN_MONT_CTX *mont=NULL;
+	int ret = -1, i;
+	if (!dsa->p || !dsa->q || !dsa->g)
+		{
+		DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS);
+		return -1;
+		}
+
+	i = BN_num_bits(dsa->q);
+	/* fips 186-3 allows only different sizes for q */
+	if (i != 160 && i != 224 && i != 256)
+		{
+		DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE);
+		return -1;
+		}
+
+	if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS)
+		{
+		DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE);
+		return -1;
+		}
+	BN_init(&u1);
+	BN_init(&u2);
+	BN_init(&t1);
+
+	if ((ctx=BN_CTX_new()) == NULL) goto err;
+
+	if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
+	    BN_ucmp(sig->r, dsa->q) >= 0)
+		{
+		ret = 0;
+		goto err;
+		}
+	if (BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
+	    BN_ucmp(sig->s, dsa->q) >= 0)
+		{
+		ret = 0;
+		goto err;
+		}
+
+	/* Calculate W = inv(S) mod Q
+	 * save W in u2 */
+	if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err;
+
+	/* save M in u1 */
+	if (dgst_len > (i >> 3))
+		/* if the digest length is greater than the size of q use the
+		 * BN_num_bits(dsa->q) leftmost bits of the digest, see
+		 * fips 186-3, 4.2 */
+		dgst_len = (i >> 3);
+	if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err;
+
+	/* u1 = M * w mod q */
+	if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err;
+
+	/* u2 = r * w mod q */
+	if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err;
+
+
+	if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
+		{
+		mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p,
+					CRYPTO_LOCK_DSA, dsa->p, ctx);
+		if (!mont)
+			goto err;
+		}
+
+
+	DSA_MOD_EXP(goto err, dsa, &t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx, mont);
+	/* BN_copy(&u1,&t1); */
+	/* let u1 = u1 mod q */
+	if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err;
+
+	/* V is now in u1.  If the signature is correct, it will be
+	 * equal to R. */
+	ret=(BN_ucmp(&u1, sig->r) == 0);
+
+	err:
+	/* XXX: surely this is wrong - if ret is 0, it just didn't verify;
+	   there is no error in BN. Test should be ret == -1 (Ben) */
+	if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB);
+	if (ctx != NULL) BN_CTX_free(ctx);
+	BN_free(&u1);
+	BN_free(&u2);
+	BN_free(&t1);
+	return(ret);
+	}
+
+static int dsa_init(DSA *dsa)
+{
+	dsa->flags|=DSA_FLAG_CACHE_MONT_P;
+	return(1);
+}
+
+static int dsa_finish(DSA *dsa)
+{
+	if(dsa->method_mont_p)
+		BN_MONT_CTX_free(dsa->method_mont_p);
+	return(1);
+}
+
diff --git a/openssl/crypto/dsa/dsa_pmeth.c b/openssl/crypto/dsa/dsa_pmeth.c
new file mode 100644
index 0000000..e2df54f
--- /dev/null
+++ b/openssl/crypto/dsa/dsa_pmeth.c
@@ -0,0 +1,316 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include "evp_locl.h"
+#include "dsa_locl.h"
+
+/* DSA pkey context structure */
+
+typedef struct
+	{
+	/* Parameter gen parameters */
+	int nbits;		/* size of p in bits (default: 1024) */
+	int qbits;		/* size of q in bits (default: 160)  */
+	const EVP_MD *pmd;	/* MD for parameter generation */
+	/* Keygen callback info */
+	int gentmp[2];
+	/* message digest */
+	const EVP_MD *md;	/* MD for the signature */
+	} DSA_PKEY_CTX;
+
+static int pkey_dsa_init(EVP_PKEY_CTX *ctx)
+	{
+	DSA_PKEY_CTX *dctx;
+	dctx = OPENSSL_malloc(sizeof(DSA_PKEY_CTX));
+	if (!dctx)
+		return 0;
+	dctx->nbits = 1024;
+	dctx->qbits = 160;
+	dctx->pmd = NULL;
+	dctx->md = NULL;
+
+	ctx->data = dctx;
+	ctx->keygen_info = dctx->gentmp;
+	ctx->keygen_info_count = 2;
+	
+	return 1;
+	}
+
+static int pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+	{
+	DSA_PKEY_CTX *dctx, *sctx;
+	if (!pkey_dsa_init(dst))
+		return 0;
+       	sctx = src->data;
+	dctx = dst->data;
+	dctx->nbits = sctx->nbits;
+	dctx->qbits = sctx->qbits;
+	dctx->pmd = sctx->pmd;
+	dctx->md  = sctx->md;
+	return 1;
+	}
+
+static void pkey_dsa_cleanup(EVP_PKEY_CTX *ctx)
+	{
+	DSA_PKEY_CTX *dctx = ctx->data;
+	if (dctx)
+		OPENSSL_free(dctx);
+	}
+
+static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					const unsigned char *tbs, size_t tbslen)
+	{
+	int ret, type;
+	unsigned int sltmp;
+	DSA_PKEY_CTX *dctx = ctx->data;
+	DSA *dsa = ctx->pkey->pkey.dsa;
+
+	if (dctx->md)
+		type = EVP_MD_type(dctx->md);
+	else
+		type = NID_sha1;
+
+	ret = DSA_sign(type, tbs, tbslen, sig, &sltmp, dsa);
+
+	if (ret <= 0)
+		return ret;
+	*siglen = sltmp;
+	return 1;
+	}
+
+static int pkey_dsa_verify(EVP_PKEY_CTX *ctx,
+					const unsigned char *sig, size_t siglen,
+					const unsigned char *tbs, size_t tbslen)
+	{
+	int ret, type;
+	DSA_PKEY_CTX *dctx = ctx->data;
+	DSA *dsa = ctx->pkey->pkey.dsa;
+
+	if (dctx->md)
+		type = EVP_MD_type(dctx->md);
+	else
+		type = NID_sha1;
+
+	ret = DSA_verify(type, tbs, tbslen, sig, siglen, dsa);
+
+	return ret;
+	}
+
+static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+	{
+	DSA_PKEY_CTX *dctx = ctx->data;
+	switch (type)
+		{
+		case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS:
+		if (p1 < 256)
+			return -2;
+		dctx->nbits = p1;
+		return 1;
+
+		case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS:
+		if (p1 != 160 && p1 != 224 && p1 && p1 != 256)
+			return -2;
+		dctx->qbits = p1;
+		return 1;
+
+		case EVP_PKEY_CTRL_DSA_PARAMGEN_MD:
+		if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1   &&
+		    EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
+		    EVP_MD_type((const EVP_MD *)p2) != NID_sha256)
+			{
+			DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
+			return 0;
+			}
+		dctx->md = p2;
+		return 1;
+
+		case EVP_PKEY_CTRL_MD:
+		if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1   &&
+		    EVP_MD_type((const EVP_MD *)p2) != NID_dsa    &&
+		    EVP_MD_type((const EVP_MD *)p2) != NID_dsaWithSHA    &&
+		    EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
+		    EVP_MD_type((const EVP_MD *)p2) != NID_sha256)
+			{
+			DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
+			return 0;
+			}
+		dctx->md = p2;
+		return 1;
+
+		case EVP_PKEY_CTRL_DIGESTINIT:
+		case EVP_PKEY_CTRL_PKCS7_SIGN:
+		case EVP_PKEY_CTRL_CMS_SIGN:
+		return 1;
+		
+		case EVP_PKEY_CTRL_PEER_KEY:
+			DSAerr(DSA_F_PKEY_DSA_CTRL,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+			return -2;	
+		default:
+		return -2;
+
+		}
+	}
+			
+static int pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx,
+			const char *type, const char *value)
+	{
+	if (!strcmp(type, "dsa_paramgen_bits"))
+		{
+		int nbits;
+		nbits = atoi(value);
+		return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits);
+		}
+	if (!strcmp(type, "dsa_paramgen_q_bits"))
+		{
+		int qbits = atoi(value);
+		return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
+		                         EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits, NULL);
+		}
+	if (!strcmp(type, "dsa_paramgen_md"))
+		{
+		return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
+		                         EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, 
+		                         (void *)EVP_get_digestbyname(value));
+		}
+	return -2;
+	}
+
+static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+	DSA *dsa = NULL;
+	DSA_PKEY_CTX *dctx = ctx->data;
+	BN_GENCB *pcb, cb;
+	int ret;
+	if (ctx->pkey_gencb)
+		{
+		pcb = &cb;
+		evp_pkey_set_cb_translate(pcb, ctx);
+		}
+	else
+		pcb = NULL;
+	dsa = DSA_new();
+	if (!dsa)
+		return 0;
+	ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd,
+	                           NULL, 0, NULL, NULL, pcb);
+	if (ret)
+		EVP_PKEY_assign_DSA(pkey, dsa);
+	else
+		DSA_free(dsa);
+	return ret;
+	}
+
+static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+	DSA *dsa = NULL;
+	if (ctx->pkey == NULL)
+		{
+		DSAerr(DSA_F_PKEY_DSA_KEYGEN, DSA_R_NO_PARAMETERS_SET);
+		return 0;
+		}
+	dsa = DSA_new();
+	if (!dsa)
+		return 0;
+	EVP_PKEY_assign_DSA(pkey, dsa);
+	/* Note: if error return, pkey is freed by parent routine */
+	if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
+		return 0;
+	return DSA_generate_key(pkey->pkey.dsa);
+	}
+
+const EVP_PKEY_METHOD dsa_pkey_meth = 
+	{
+	EVP_PKEY_DSA,
+	EVP_PKEY_FLAG_AUTOARGLEN,
+	pkey_dsa_init,
+	pkey_dsa_copy,
+	pkey_dsa_cleanup,
+
+	0,
+	pkey_dsa_paramgen,
+
+	0,
+	pkey_dsa_keygen,
+
+	0,
+	pkey_dsa_sign,
+
+	0,
+	pkey_dsa_verify,
+
+	0,0,
+
+	0,0,0,0,
+
+	0,0,
+
+	0,0,
+
+	0,0,
+
+	pkey_dsa_ctrl,
+	pkey_dsa_ctrl_str
+
+
+	};
diff --git a/openssl/crypto/dsa/dsa_prn.c b/openssl/crypto/dsa/dsa_prn.c
new file mode 100644
index 0000000..6f29f5e
--- /dev/null
+++ b/openssl/crypto/dsa/dsa_prn.c
@@ -0,0 +1,121 @@
+/* crypto/dsa/dsa_prn.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/dsa.h>
+
+#ifndef OPENSSL_NO_FP_API
+int DSA_print_fp(FILE *fp, const DSA *x, int off)
+	{
+	BIO *b;
+	int ret;
+
+	if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		DSAerr(DSA_F_DSA_PRINT_FP,ERR_R_BUF_LIB);
+		return(0);
+		}
+	BIO_set_fp(b,fp,BIO_NOCLOSE);
+	ret=DSA_print(b,x,off);
+	BIO_free(b);
+	return(ret);
+	}
+
+int DSAparams_print_fp(FILE *fp, const DSA *x)
+	{
+	BIO *b;
+	int ret;
+
+	if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		DSAerr(DSA_F_DSAPARAMS_PRINT_FP,ERR_R_BUF_LIB);
+		return(0);
+		}
+	BIO_set_fp(b,fp,BIO_NOCLOSE);
+	ret=DSAparams_print(b, x);
+	BIO_free(b);
+	return(ret);
+	}
+#endif
+
+int DSA_print(BIO *bp, const DSA *x, int off)
+	{
+	EVP_PKEY *pk;
+	int ret;
+	pk = EVP_PKEY_new();
+	if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x))
+		return 0;
+	ret = EVP_PKEY_print_private(bp, pk, off, NULL);
+	EVP_PKEY_free(pk);
+	return ret;
+	}
+
+int DSAparams_print(BIO *bp, const DSA *x)
+	{
+	EVP_PKEY *pk;
+	int ret;
+	pk = EVP_PKEY_new();
+	if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x))
+		return 0;
+	ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
+	EVP_PKEY_free(pk);
+	return ret;
+	}
+
diff --git a/openssl/crypto/dsa/dsa_sign.c b/openssl/crypto/dsa/dsa_sign.c
new file mode 100644
index 0000000..17555e5
--- /dev/null
+++ b/openssl/crypto/dsa/dsa_sign.c
@@ -0,0 +1,90 @@
+/* crypto/dsa/dsa_sign.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include "cryptlib.h"
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+
+DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+	{
+	return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
+	}
+
+int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
+	     unsigned int *siglen, DSA *dsa)
+	{
+	DSA_SIG *s;
+	RAND_seed(dgst, dlen);
+	s=DSA_do_sign(dgst,dlen,dsa);
+	if (s == NULL)
+		{
+		*siglen=0;
+		return(0);
+		}
+	*siglen=i2d_DSA_SIG(s,&sig);
+	DSA_SIG_free(s);
+	return(1);
+	}
+
+int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+	{
+	return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
+	}
+
diff --git a/openssl/crypto/dsa/dsa_vrf.c b/openssl/crypto/dsa/dsa_vrf.c
new file mode 100644
index 0000000..226a75f
--- /dev/null
+++ b/openssl/crypto/dsa/dsa_vrf.c
@@ -0,0 +1,89 @@
+/* crypto/dsa/dsa_vrf.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include "cryptlib.h"
+#include <openssl/dsa.h>
+
+int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
+		  DSA *dsa)
+	{
+	return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
+	}
+
+/* data has already been hashed (probably with SHA or SHA-1). */
+/* returns
+ *      1: correct signature
+ *      0: incorrect signature
+ *     -1: error
+ */
+int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
+	     const unsigned char *sigbuf, int siglen, DSA *dsa)
+	{
+	DSA_SIG *s;
+	int ret=-1;
+
+	s = DSA_SIG_new();
+	if (s == NULL) return(ret);
+	if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
+	ret=DSA_do_verify(dgst,dgst_len,s,dsa);
+err:
+	DSA_SIG_free(s);
+	return(ret);
+	}
diff --git a/openssl/crypto/dsa/dsagen.c b/openssl/crypto/dsa/dsagen.c
new file mode 100644
index 0000000..1b6a1cc
--- /dev/null
+++ b/openssl/crypto/dsa/dsagen.c
@@ -0,0 +1,111 @@
+/* crypto/dsa/dsagen.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/dsa.h>
+
+#define TEST
+#define GENUINE_DSA
+
+#ifdef GENUINE_DSA
+#define LAST_VALUE 0xbd
+#else
+#define LAST_VALUE 0xd3
+#endif
+
+#ifdef TEST
+unsigned char seed[20]={
+	0xd5,0x01,0x4e,0x4b,
+	0x60,0xef,0x2b,0xa8,
+	0xb6,0x21,0x1b,0x40,
+	0x62,0xba,0x32,0x24,
+	0xe0,0x42,0x7d,LAST_VALUE};
+#endif
+
+int cb(int p, int n)
+	{
+	char c='*';
+
+	if (p == 0) c='.';
+	if (p == 1) c='+';
+	if (p == 2) c='*';
+	if (p == 3) c='\n';
+	printf("%c",c);
+	fflush(stdout);
+	}
+
+main()
+	{
+	int i;
+	BIGNUM *n;
+	BN_CTX *ctx;
+	unsigned char seed_buf[20];
+	DSA *dsa;
+	int counter,h;
+	BIO *bio_err=NULL;
+
+	if (bio_err == NULL)
+		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+
+	memcpy(seed_buf,seed,20);
+	dsa=DSA_generate_parameters(1024,seed,20,&counter,&h,cb,bio_err);
+
+	if (dsa == NULL)
+		DSA_print(bio_err,dsa,0);
+	}
+
diff --git a/openssl/crypto/dsa/dsatest.c b/openssl/crypto/dsa/dsatest.c
new file mode 100644
index 0000000..edffd24
--- /dev/null
+++ b/openssl/crypto/dsa/dsatest.c
@@ -0,0 +1,259 @@
+/* crypto/dsa/dsatest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code */
+#ifdef OPENSSL_NO_DEPRECATED
+#undef OPENSSL_NO_DEPRECATED
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "../e_os.h"
+
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+
+#ifdef OPENSSL_NO_DSA
+int main(int argc, char *argv[])
+{
+    printf("No DSA support\n");
+    return(0);
+}
+#else
+#include <openssl/dsa.h>
+
+#ifdef OPENSSL_SYS_WIN16
+#define MS_CALLBACK     _far _loadds
+#else
+#define MS_CALLBACK
+#endif
+
+static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *arg);
+
+/* seed, out_p, out_q, out_g are taken from the updated Appendix 5 to
+ * FIPS PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1 */
+static unsigned char seed[20]={
+	0xd5,0x01,0x4e,0x4b,0x60,0xef,0x2b,0xa8,0xb6,0x21,0x1b,0x40,
+	0x62,0xba,0x32,0x24,0xe0,0x42,0x7d,0xd3,
+	};
+
+static unsigned char out_p[]={
+	0x8d,0xf2,0xa4,0x94,0x49,0x22,0x76,0xaa,
+	0x3d,0x25,0x75,0x9b,0xb0,0x68,0x69,0xcb,
+	0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7,
+	0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5,
+	0xd0,0x76,0x2f,0xc5,0xb7,0x21,0x0e,0xaf,
+	0xc2,0xe9,0xad,0xac,0x32,0xab,0x7a,0xac,
+	0x49,0x69,0x3d,0xfb,0xf8,0x37,0x24,0xc2,
+	0xec,0x07,0x36,0xee,0x31,0xc8,0x02,0x91,
+	};
+
+static unsigned char out_q[]={
+	0xc7,0x73,0x21,0x8c,0x73,0x7e,0xc8,0xee,
+	0x99,0x3b,0x4f,0x2d,0xed,0x30,0xf4,0x8e,
+	0xda,0xce,0x91,0x5f,
+	};
+
+static unsigned char out_g[]={
+	0x62,0x6d,0x02,0x78,0x39,0xea,0x0a,0x13,
+	0x41,0x31,0x63,0xa5,0x5b,0x4c,0xb5,0x00,
+	0x29,0x9d,0x55,0x22,0x95,0x6c,0xef,0xcb,
+	0x3b,0xff,0x10,0xf3,0x99,0xce,0x2c,0x2e,
+	0x71,0xcb,0x9d,0xe5,0xfa,0x24,0xba,0xbf,
+	0x58,0xe5,0xb7,0x95,0x21,0x92,0x5c,0x9c,
+	0xc4,0x2e,0x9f,0x6f,0x46,0x4b,0x08,0x8c,
+	0xc5,0x72,0xaf,0x53,0xe6,0xd7,0x88,0x02,
+	};
+
+static const unsigned char str1[]="12345678901234567890";
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+static BIO *bio_err=NULL;
+
+int main(int argc, char **argv)
+	{
+	BN_GENCB cb;
+	DSA *dsa=NULL;
+	int counter,ret=0,i,j;
+	unsigned char buf[256];
+	unsigned long h;
+	unsigned char sig[256];
+	unsigned int siglen;
+
+	if (bio_err == NULL)
+		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+
+	CRYPTO_malloc_debug_init();
+	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
+	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+	ERR_load_crypto_strings();
+	RAND_seed(rnd_seed, sizeof rnd_seed);
+
+	BIO_printf(bio_err,"test generation of DSA parameters\n");
+
+	BN_GENCB_set(&cb, dsa_cb, bio_err);
+	if(((dsa = DSA_new()) == NULL) || !DSA_generate_parameters_ex(dsa, 512,
+				seed, 20, &counter, &h, &cb))
+		goto end;
+
+	BIO_printf(bio_err,"seed\n");
+	for (i=0; i<20; i+=4)
+		{
+		BIO_printf(bio_err,"%02X%02X%02X%02X ",
+			seed[i],seed[i+1],seed[i+2],seed[i+3]);
+		}
+	BIO_printf(bio_err,"\ncounter=%d h=%ld\n",counter,h);
+		
+	DSA_print(bio_err,dsa,0);
+	if (counter != 105) 
+		{
+		BIO_printf(bio_err,"counter should be 105\n");
+		goto end;
+		}
+	if (h != 2)
+		{
+		BIO_printf(bio_err,"h should be 2\n");
+		goto end;
+		}
+
+	i=BN_bn2bin(dsa->q,buf);
+	j=sizeof(out_q);
+	if ((i != j) || (memcmp(buf,out_q,i) != 0))
+		{
+		BIO_printf(bio_err,"q value is wrong\n");
+		goto end;
+		}
+
+	i=BN_bn2bin(dsa->p,buf);
+	j=sizeof(out_p);
+	if ((i != j) || (memcmp(buf,out_p,i) != 0))
+		{
+		BIO_printf(bio_err,"p value is wrong\n");
+		goto end;
+		}
+
+	i=BN_bn2bin(dsa->g,buf);
+	j=sizeof(out_g);
+	if ((i != j) || (memcmp(buf,out_g,i) != 0))
+		{
+		BIO_printf(bio_err,"g value is wrong\n");
+		goto end;
+		}
+
+	dsa->flags |= DSA_FLAG_NO_EXP_CONSTTIME;
+	DSA_generate_key(dsa);
+	DSA_sign(0, str1, 20, sig, &siglen, dsa);
+	if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1)
+		ret=1;
+
+	dsa->flags &= ~DSA_FLAG_NO_EXP_CONSTTIME;
+	DSA_generate_key(dsa);
+	DSA_sign(0, str1, 20, sig, &siglen, dsa);
+	if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1)
+		ret=1;
+
+end:
+	if (!ret)
+		ERR_print_errors(bio_err);
+	if (dsa != NULL) DSA_free(dsa);
+	CRYPTO_cleanup_all_ex_data();
+	ERR_remove_thread_state(NULL);
+	ERR_free_strings();
+	CRYPTO_mem_leaks(bio_err);
+	if (bio_err != NULL)
+		{
+		BIO_free(bio_err);
+		bio_err = NULL;
+		}
+#ifdef OPENSSL_SYS_NETWARE
+    if (!ret) printf("ERROR\n");
+#endif
+	EXIT(!ret);
+	return(0);
+	}
+
+static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *arg)
+	{
+	char c='*';
+	static int ok=0,num=0;
+
+	if (p == 0) { c='.'; num++; };
+	if (p == 1) c='+';
+	if (p == 2) { c='*'; ok++; }
+	if (p == 3) c='\n';
+	BIO_write(arg->arg,&c,1);
+	(void)BIO_flush(arg->arg);
+
+	if (!ok && (p == 0) && (num > 1))
+		{
+		BIO_printf((BIO *)arg,"error in dsatest\n");
+		return 0;
+		}
+	return 1;
+	}
+#endif
diff --git a/openssl/crypto/dsa/fips186a.txt b/openssl/crypto/dsa/fips186a.txt
new file mode 100644
index 0000000..3a2e0a0
--- /dev/null
+++ b/openssl/crypto/dsa/fips186a.txt
@@ -0,0 +1,122 @@
+The origional FIPE 180 used SHA-0 (FIPS 180) for its appendix 5
+examples.  This is an updated version that uses SHA-1 (FIPS 180-1)
+supplied to me by Wei Dai
+--
+		     APPENDIX 5. EXAMPLE OF THE DSA
+
+
+This appendix is for informational purposes only and is not required to meet
+the standard.
+
+Let L = 512 (size of p).  The values in this example are expressed in
+hexadecimal notation.  The p and q given here were generated by the prime
+generation standard described in appendix 2 using the 160-bit SEED:
+
+          d5014e4b 60ef2ba8 b6211b40 62ba3224 e0427dd3
+
+With this SEED, the algorithm found p and q when the counter was at 105.
+
+x was generated by the algorithm described in appendix 3, section 3.1, using
+the SHA to construct G (as in appendix 3, section 3.3) and a 160-bit XSEED:
+
+XSEED =   
+
+	bd029bbe 7f51960b cf9edb2b 61f06f0f eb5a38b6
+
+t =
+	67452301 EFCDAB89 98BADCFE 10325476 C3D2E1F0
+
+x = G(t,XSEED) mod q
+
+k was generated by the algorithm described in appendix 3, section 3.2, using
+the SHA to construct G (as in appendix 3, section 3.3) and a 160-bit KSEED:
+
+KSEED =
+
+	687a66d9 0648f993 867e121f 4ddf9ddb 01205584
+
+t =
+	EFCDAB89 98BADCFE 10325476 C3D2E1F0 67452301
+
+k = G(t,KSEED) mod q
+
+Finally:
+
+h = 2
+
+p =
+	8df2a494 492276aa 3d25759b b06869cb eac0d83a fb8d0cf7
+	cbb8324f 0d7882e5 d0762fc5 b7210eaf c2e9adac 32ab7aac
+	49693dfb f83724c2 ec0736ee 31c80291
+
+
+q =
+	c773218c 737ec8ee 993b4f2d ed30f48e dace915f
+
+
+g =
+	626d0278 39ea0a13 413163a5 5b4cb500 299d5522 956cefcb
+	3bff10f3 99ce2c2e 71cb9de5 fa24babf 58e5b795 21925c9c
+	c42e9f6f 464b088c c572af53 e6d78802
+
+
+x =
+	2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614
+
+
+k =
+	358dad57 1462710f 50e254cf 1a376b2b deaadfbf
+
+
+kinv = 
+
+	0d516729 8202e49b 4116ac10 4fc3f415 ae52f917
+
+M = ASCII form of "abc" (See FIPS PUB 180-1, Appendix A)
+
+SHA(M) =  
+
+	a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d
+
+
+y =
+
+	19131871 d75b1612 a819f29d 78d1b0d7 346f7aa7 7bb62a85 
+	9bfd6c56 75da9d21 2d3a36ef 1672ef66 0b8c7c25 5cc0ec74
+	858fba33 f44c0669 9630a76b 030ee333
+
+
+r =
+	8bac1ab6 6410435c b7181f95 b16ab97c 92b341c0
+
+s =
+	41e2345f 1f56df24 58f426d1 55b4ba2d b6dcd8c8
+
+
+w =
+	9df4ece5 826be95f ed406d41 b43edc0b 1c18841b
+
+
+u1 =
+	bf655bd0 46f0b35e c791b004 804afcbb 8ef7d69d
+
+
+u2 =
+	821a9263 12e97ade abcc8d08 2b527897 8a2df4b0
+
+
+gu1 mod p =
+
+	51b1bf86 7888e5f3 af6fb476 9dd016bc fe667a65 aafc2753
+	9063bd3d 2b138b4c e02cc0c0 2ec62bb6 7306c63e 4db95bbf
+	6f96662a 1987a21b e4ec1071 010b6069
+
+
+yu2 mod p =
+
+	8b510071 2957e950 50d6b8fd 376a668e 4b0d633c 1e46e665
+	5c611a72 e2b28483 be52c74d 4b30de61 a668966e dc307a67 
+	c19441f4 22bf3c34 08aeba1f 0a4dbec7
+
+v =
+	8bac1ab6 6410435c b7181f95 b16ab97c 92b341c0
diff --git a/openssl/crypto/dso/Makefile b/openssl/crypto/dso/Makefile
new file mode 100644
index 0000000..fb2709e
--- /dev/null
+++ b/openssl/crypto/dso/Makefile
@@ -0,0 +1,150 @@
+#
+# OpenSSL/crypto/dso/Makefile
+#
+
+DIR=	dso
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= dso_dl.c dso_dlfcn.c dso_err.c dso_lib.c dso_null.c \
+	dso_openssl.c dso_win32.c dso_vms.c dso_beos.c
+LIBOBJ= dso_dl.o dso_dlfcn.o dso_err.o dso_lib.o dso_null.o \
+	dso_openssl.o dso_win32.o dso_vms.o dso_beos.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= dso.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+dso_beos.o: ../../e_os.h ../../include/openssl/bio.h
+dso_beos.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dso_beos.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+dso_beos.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dso_beos.o: ../../include/openssl/opensslconf.h
+dso_beos.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dso_beos.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dso_beos.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_beos.c
+dso_dl.o: ../../e_os.h ../../include/openssl/bio.h
+dso_dl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dso_dl.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+dso_dl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dso_dl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dso_dl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+dso_dl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dso_dl.o: ../cryptlib.h dso_dl.c
+dso_dlfcn.o: ../../e_os.h ../../include/openssl/bio.h
+dso_dlfcn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dso_dlfcn.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+dso_dlfcn.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dso_dlfcn.o: ../../include/openssl/opensslconf.h
+dso_dlfcn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dso_dlfcn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dso_dlfcn.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_dlfcn.c
+dso_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+dso_err.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+dso_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dso_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dso_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+dso_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dso_err.o: dso_err.c
+dso_lib.o: ../../e_os.h ../../include/openssl/bio.h
+dso_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dso_lib.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+dso_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dso_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dso_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+dso_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dso_lib.o: ../cryptlib.h dso_lib.c
+dso_null.o: ../../e_os.h ../../include/openssl/bio.h
+dso_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dso_null.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+dso_null.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dso_null.o: ../../include/openssl/opensslconf.h
+dso_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dso_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dso_null.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_null.c
+dso_openssl.o: ../../e_os.h ../../include/openssl/bio.h
+dso_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dso_openssl.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+dso_openssl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dso_openssl.o: ../../include/openssl/opensslconf.h
+dso_openssl.o: ../../include/openssl/opensslv.h
+dso_openssl.o: ../../include/openssl/ossl_typ.h
+dso_openssl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dso_openssl.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_openssl.c
+dso_vms.o: ../../e_os.h ../../include/openssl/bio.h
+dso_vms.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dso_vms.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+dso_vms.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dso_vms.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dso_vms.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+dso_vms.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dso_vms.o: ../cryptlib.h dso_vms.c
+dso_win32.o: ../../e_os.h ../../include/openssl/bio.h
+dso_win32.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dso_win32.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+dso_win32.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dso_win32.o: ../../include/openssl/opensslconf.h
+dso_win32.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dso_win32.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dso_win32.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_win32.c
diff --git a/openssl/crypto/dso/README b/openssl/crypto/dso/README
new file mode 100644
index 0000000..d0bc9a8
--- /dev/null
+++ b/openssl/crypto/dso/README
@@ -0,0 +1,22 @@
+NOTES
+-----
+
+I've checked out HPUX (well, version 11 at least) and shl_t is
+a pointer type so it's safe to use in the way it has been in
+dso_dl.c. On the other hand, HPUX11 support dlfcn too and
+according to their man page, prefer developers to move to that.
+I'll leave Richard's changes there as I guess dso_dl is needed
+for HPUX10.20.
+
+There is now a callback scheme in place where filename conversion can
+(a) be turned off altogether through the use of the
+    DSO_FLAG_NO_NAME_TRANSLATION flag,
+(b) be handled by default using the default DSO_METHOD's converter
+(c) overriden per-DSO by setting the override callback
+(d) a mix of (b) and (c) - eg. implement an override callback that;
+    (i) checks if we're win32 (if(strstr(dso->meth->name, "win32")....)
+        and if so, convert "blah" into "blah32.dll" (the default is
+	otherwise to make it "blah.dll").
+    (ii) default to the normal behaviour - we're not on win32, eg.
+         finish with (return dso->meth->dso_name_converter(dso,NULL)).
+
diff --git a/openssl/crypto/dso/dso.h b/openssl/crypto/dso/dso.h
new file mode 100644
index 0000000..839f2e0
--- /dev/null
+++ b/openssl/crypto/dso/dso.h
@@ -0,0 +1,409 @@
+/* dso.h -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_DSO_H
+#define HEADER_DSO_H
+
+#include <openssl/crypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* These values are used as commands to DSO_ctrl() */
+#define DSO_CTRL_GET_FLAGS	1
+#define DSO_CTRL_SET_FLAGS	2
+#define DSO_CTRL_OR_FLAGS	3
+
+/* By default, DSO_load() will translate the provided filename into a form
+ * typical for the platform (more specifically the DSO_METHOD) using the
+ * dso_name_converter function of the method. Eg. win32 will transform "blah"
+ * into "blah.dll", and dlfcn will transform it into "libblah.so". The
+ * behaviour can be overriden by setting the name_converter callback in the DSO
+ * object (using DSO_set_name_converter()). This callback could even utilise
+ * the DSO_METHOD's converter too if it only wants to override behaviour for
+ * one or two possible DSO methods. However, the following flag can be set in a
+ * DSO to prevent *any* native name-translation at all - eg. if the caller has
+ * prompted the user for a path to a driver library so the filename should be
+ * interpreted as-is. */
+#define DSO_FLAG_NO_NAME_TRANSLATION		0x01
+/* An extra flag to give if only the extension should be added as
+ * translation.  This is obviously only of importance on Unix and
+ * other operating systems where the translation also may prefix
+ * the name with something, like 'lib', and ignored everywhere else.
+ * This flag is also ignored if DSO_FLAG_NO_NAME_TRANSLATION is used
+ * at the same time. */
+#define DSO_FLAG_NAME_TRANSLATION_EXT_ONLY	0x02
+
+/* The following flag controls the translation of symbol names to upper
+ * case.  This is currently only being implemented for OpenVMS.
+ */
+#define DSO_FLAG_UPCASE_SYMBOL			0x10
+
+/* This flag loads the library with public symbols.
+ * Meaning: The exported symbols of this library are public
+ * to all libraries loaded after this library.
+ * At the moment only implemented in unix.
+ */
+#define DSO_FLAG_GLOBAL_SYMBOLS			0x20
+
+
+typedef void (*DSO_FUNC_TYPE)(void);
+
+typedef struct dso_st DSO;
+
+/* The function prototype used for method functions (or caller-provided
+ * callbacks) that transform filenames. They are passed a DSO structure pointer
+ * (or NULL if they are to be used independantly of a DSO object) and a
+ * filename to transform. They should either return NULL (if there is an error
+ * condition) or a newly allocated string containing the transformed form that
+ * the caller will need to free with OPENSSL_free() when done. */
+typedef char* (*DSO_NAME_CONVERTER_FUNC)(DSO *, const char *);
+/* The function prototype used for method functions (or caller-provided
+ * callbacks) that merge two file specifications. They are passed a
+ * DSO structure pointer (or NULL if they are to be used independantly of
+ * a DSO object) and two file specifications to merge. They should
+ * either return NULL (if there is an error condition) or a newly allocated
+ * string containing the result of merging that the caller will need
+ * to free with OPENSSL_free() when done.
+ * Here, merging means that bits and pieces are taken from each of the
+ * file specifications and added together in whatever fashion that is
+ * sensible for the DSO method in question.  The only rule that really
+ * applies is that if the two specification contain pieces of the same
+ * type, the copy from the first string takes priority.  One could see
+ * it as the first specification is the one given by the user and the
+ * second being a bunch of defaults to add on if they're missing in the
+ * first. */
+typedef char* (*DSO_MERGER_FUNC)(DSO *, const char *, const char *);
+
+typedef struct dso_meth_st
+	{
+	const char *name;
+	/* Loads a shared library, NB: new DSO_METHODs must ensure that a
+	 * successful load populates the loaded_filename field, and likewise a
+	 * successful unload OPENSSL_frees and NULLs it out. */
+	int (*dso_load)(DSO *dso);
+	/* Unloads a shared library */
+	int (*dso_unload)(DSO *dso);
+	/* Binds a variable */
+	void *(*dso_bind_var)(DSO *dso, const char *symname);
+	/* Binds a function - assumes a return type of DSO_FUNC_TYPE.
+	 * This should be cast to the real function prototype by the
+	 * caller. Platforms that don't have compatible representations
+	 * for different prototypes (this is possible within ANSI C)
+	 * are highly unlikely to have shared libraries at all, let
+	 * alone a DSO_METHOD implemented for them. */
+	DSO_FUNC_TYPE (*dso_bind_func)(DSO *dso, const char *symname);
+
+/* I don't think this would actually be used in any circumstances. */
+#if 0
+	/* Unbinds a variable */
+	int (*dso_unbind_var)(DSO *dso, char *symname, void *symptr);
+	/* Unbinds a function */
+	int (*dso_unbind_func)(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
+#endif
+	/* The generic (yuck) "ctrl()" function. NB: Negative return
+	 * values (rather than zero) indicate errors. */
+	long (*dso_ctrl)(DSO *dso, int cmd, long larg, void *parg);
+	/* The default DSO_METHOD-specific function for converting filenames to
+	 * a canonical native form. */
+	DSO_NAME_CONVERTER_FUNC dso_name_converter;
+	/* The default DSO_METHOD-specific function for converting filenames to
+	 * a canonical native form. */
+	DSO_MERGER_FUNC dso_merger;
+
+	/* [De]Initialisation handlers. */
+	int (*init)(DSO *dso);
+	int (*finish)(DSO *dso);
+
+	/* Return pathname of the module containing location */
+	int (*pathbyaddr)(void *addr,char *path,int sz);
+	/* Perform global symbol lookup, i.e. among *all* modules */
+	void *(*globallookup)(const char *symname);
+	} DSO_METHOD;
+
+/**********************************************************************/
+/* The low-level handle type used to refer to a loaded shared library */
+
+struct dso_st
+	{
+	DSO_METHOD *meth;
+	/* Standard dlopen uses a (void *). Win32 uses a HANDLE. VMS
+	 * doesn't use anything but will need to cache the filename
+	 * for use in the dso_bind handler. All in all, let each
+	 * method control its own destiny. "Handles" and such go in
+	 * a STACK. */
+	STACK_OF(void) *meth_data;
+	int references;
+	int flags;
+	/* For use by applications etc ... use this for your bits'n'pieces,
+	 * don't touch meth_data! */
+	CRYPTO_EX_DATA ex_data;
+	/* If this callback function pointer is set to non-NULL, then it will
+	 * be used in DSO_load() in place of meth->dso_name_converter. NB: This
+	 * should normally set using DSO_set_name_converter(). */
+	DSO_NAME_CONVERTER_FUNC name_converter;
+	/* If this callback function pointer is set to non-NULL, then it will
+	 * be used in DSO_load() in place of meth->dso_merger. NB: This
+	 * should normally set using DSO_set_merger(). */
+	DSO_MERGER_FUNC merger;
+	/* This is populated with (a copy of) the platform-independant
+	 * filename used for this DSO. */
+	char *filename;
+	/* This is populated with (a copy of) the translated filename by which
+	 * the DSO was actually loaded. It is NULL iff the DSO is not currently
+	 * loaded. NB: This is here because the filename translation process
+	 * may involve a callback being invoked more than once not only to
+	 * convert to a platform-specific form, but also to try different
+	 * filenames in the process of trying to perform a load. As such, this
+	 * variable can be used to indicate (a) whether this DSO structure
+	 * corresponds to a loaded library or not, and (b) the filename with
+	 * which it was actually loaded. */
+	char *loaded_filename;
+	};
+
+
+DSO *	DSO_new(void);
+DSO *	DSO_new_method(DSO_METHOD *method);
+int	DSO_free(DSO *dso);
+int	DSO_flags(DSO *dso);
+int	DSO_up_ref(DSO *dso);
+long	DSO_ctrl(DSO *dso, int cmd, long larg, void *parg);
+
+/* This function sets the DSO's name_converter callback. If it is non-NULL,
+ * then it will be used instead of the associated DSO_METHOD's function. If
+ * oldcb is non-NULL then it is set to the function pointer value being
+ * replaced. Return value is non-zero for success. */
+int	DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb,
+				DSO_NAME_CONVERTER_FUNC *oldcb);
+/* These functions can be used to get/set the platform-independant filename
+ * used for a DSO. NB: set will fail if the DSO is already loaded. */
+const char *DSO_get_filename(DSO *dso);
+int	DSO_set_filename(DSO *dso, const char *filename);
+/* This function will invoke the DSO's name_converter callback to translate a
+ * filename, or if the callback isn't set it will instead use the DSO_METHOD's
+ * converter. If "filename" is NULL, the "filename" in the DSO itself will be
+ * used. If the DSO_FLAG_NO_NAME_TRANSLATION flag is set, then the filename is
+ * simply duplicated. NB: This function is usually called from within a
+ * DSO_METHOD during the processing of a DSO_load() call, and is exposed so that
+ * caller-created DSO_METHODs can do the same thing. A non-NULL return value
+ * will need to be OPENSSL_free()'d. */
+char	*DSO_convert_filename(DSO *dso, const char *filename);
+/* This function will invoke the DSO's merger callback to merge two file
+ * specifications, or if the callback isn't set it will instead use the
+ * DSO_METHOD's merger.  A non-NULL return value will need to be
+ * OPENSSL_free()'d. */
+char	*DSO_merge(DSO *dso, const char *filespec1, const char *filespec2);
+/* If the DSO is currently loaded, this returns the filename that it was loaded
+ * under, otherwise it returns NULL. So it is also useful as a test as to
+ * whether the DSO is currently loaded. NB: This will not necessarily return
+ * the same value as DSO_convert_filename(dso, dso->filename), because the
+ * DSO_METHOD's load function may have tried a variety of filenames (with
+ * and/or without the aid of the converters) before settling on the one it
+ * actually loaded. */
+const char *DSO_get_loaded_filename(DSO *dso);
+
+void	DSO_set_default_method(DSO_METHOD *meth);
+DSO_METHOD *DSO_get_default_method(void);
+DSO_METHOD *DSO_get_method(DSO *dso);
+DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth);
+
+/* The all-singing all-dancing load function, you normally pass NULL
+ * for the first and third parameters. Use DSO_up and DSO_free for
+ * subsequent reference count handling. Any flags passed in will be set
+ * in the constructed DSO after its init() function but before the
+ * load operation. If 'dso' is non-NULL, 'flags' is ignored. */
+DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags);
+
+/* This function binds to a variable inside a shared library. */
+void *DSO_bind_var(DSO *dso, const char *symname);
+
+/* This function binds to a function inside a shared library. */
+DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname);
+
+/* This method is the default, but will beg, borrow, or steal whatever
+ * method should be the default on any particular platform (including
+ * DSO_METH_null() if necessary). */
+DSO_METHOD *DSO_METHOD_openssl(void);
+
+/* This method is defined for all platforms - if a platform has no
+ * DSO support then this will be the only method! */
+DSO_METHOD *DSO_METHOD_null(void);
+
+/* If DSO_DLFCN is defined, the standard dlfcn.h-style functions
+ * (dlopen, dlclose, dlsym, etc) will be used and incorporated into
+ * this method. If not, this method will return NULL. */
+DSO_METHOD *DSO_METHOD_dlfcn(void);
+
+/* If DSO_DL is defined, the standard dl.h-style functions (shl_load, 
+ * shl_unload, shl_findsym, etc) will be used and incorporated into
+ * this method. If not, this method will return NULL. */
+DSO_METHOD *DSO_METHOD_dl(void);
+
+/* If WIN32 is defined, use DLLs. If not, return NULL. */
+DSO_METHOD *DSO_METHOD_win32(void);
+
+/* If VMS is defined, use shared images. If not, return NULL. */
+DSO_METHOD *DSO_METHOD_vms(void);
+
+/* This function writes null-terminated pathname of DSO module
+ * containing 'addr' into 'sz' large caller-provided 'path' and
+ * returns the number of characters [including trailing zero]
+ * written to it. If 'sz' is 0 or negative, 'path' is ignored and
+ * required amount of charachers [including trailing zero] to
+ * accomodate pathname is returned. If 'addr' is NULL, then
+ * pathname of cryptolib itself is returned. Negative or zero
+ * return value denotes error.
+ */
+int DSO_pathbyaddr(void *addr,char *path,int sz);
+
+/* This function should be used with caution! It looks up symbols in
+ * *all* loaded modules and if module gets unloaded by somebody else
+ * attempt to dereference the pointer is doomed to have fatal
+ * consequences. Primary usage for this function is to probe *core*
+ * system functionality, e.g. check if getnameinfo(3) is available
+ * at run-time without bothering about OS-specific details such as
+ * libc.so.versioning or where does it actually reside: in libc
+ * itself or libsocket. */
+void *DSO_global_lookup(const char *name);
+
+/* If BeOS is defined, use shared images. If not, return NULL. */
+DSO_METHOD *DSO_METHOD_beos(void);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_DSO_strings(void);
+
+/* Error codes for the DSO functions. */
+
+/* Function codes. */
+#define DSO_F_BEOS_BIND_FUNC				 144
+#define DSO_F_BEOS_BIND_VAR				 145
+#define DSO_F_BEOS_LOAD					 146
+#define DSO_F_BEOS_NAME_CONVERTER			 147
+#define DSO_F_BEOS_UNLOAD				 148
+#define DSO_F_DLFCN_BIND_FUNC				 100
+#define DSO_F_DLFCN_BIND_VAR				 101
+#define DSO_F_DLFCN_LOAD				 102
+#define DSO_F_DLFCN_MERGER				 130
+#define DSO_F_DLFCN_NAME_CONVERTER			 123
+#define DSO_F_DLFCN_UNLOAD				 103
+#define DSO_F_DL_BIND_FUNC				 104
+#define DSO_F_DL_BIND_VAR				 105
+#define DSO_F_DL_LOAD					 106
+#define DSO_F_DL_MERGER					 131
+#define DSO_F_DL_NAME_CONVERTER				 124
+#define DSO_F_DL_UNLOAD					 107
+#define DSO_F_DSO_BIND_FUNC				 108
+#define DSO_F_DSO_BIND_VAR				 109
+#define DSO_F_DSO_CONVERT_FILENAME			 126
+#define DSO_F_DSO_CTRL					 110
+#define DSO_F_DSO_FREE					 111
+#define DSO_F_DSO_GET_FILENAME				 127
+#define DSO_F_DSO_GET_LOADED_FILENAME			 128
+#define DSO_F_DSO_GLOBAL_LOOKUP				 139
+#define DSO_F_DSO_LOAD					 112
+#define DSO_F_DSO_MERGE					 132
+#define DSO_F_DSO_NEW_METHOD				 113
+#define DSO_F_DSO_PATHBYADDR				 140
+#define DSO_F_DSO_SET_FILENAME				 129
+#define DSO_F_DSO_SET_NAME_CONVERTER			 122
+#define DSO_F_DSO_UP_REF				 114
+#define DSO_F_GLOBAL_LOOKUP_FUNC			 138
+#define DSO_F_PATHBYADDR				 137
+#define DSO_F_VMS_BIND_SYM				 115
+#define DSO_F_VMS_LOAD					 116
+#define DSO_F_VMS_MERGER				 133
+#define DSO_F_VMS_UNLOAD				 117
+#define DSO_F_WIN32_BIND_FUNC				 118
+#define DSO_F_WIN32_BIND_VAR				 119
+#define DSO_F_WIN32_GLOBALLOOKUP			 142
+#define DSO_F_WIN32_GLOBALLOOKUP_FUNC			 143
+#define DSO_F_WIN32_JOINER				 135
+#define DSO_F_WIN32_LOAD				 120
+#define DSO_F_WIN32_MERGER				 134
+#define DSO_F_WIN32_NAME_CONVERTER			 125
+#define DSO_F_WIN32_PATHBYADDR				 141
+#define DSO_F_WIN32_SPLITTER				 136
+#define DSO_F_WIN32_UNLOAD				 121
+
+/* Reason codes. */
+#define DSO_R_CTRL_FAILED				 100
+#define DSO_R_DSO_ALREADY_LOADED			 110
+#define DSO_R_EMPTY_FILE_STRUCTURE			 113
+#define DSO_R_FAILURE					 114
+#define DSO_R_FILENAME_TOO_BIG				 101
+#define DSO_R_FINISH_FAILED				 102
+#define DSO_R_INCORRECT_FILE_SYNTAX			 115
+#define DSO_R_LOAD_FAILED				 103
+#define DSO_R_NAME_TRANSLATION_FAILED			 109
+#define DSO_R_NO_FILENAME				 111
+#define DSO_R_NO_FILE_SPECIFICATION			 116
+#define DSO_R_NULL_HANDLE				 104
+#define DSO_R_SET_FILENAME_FAILED			 112
+#define DSO_R_STACK_ERROR				 105
+#define DSO_R_SYM_FAILURE				 106
+#define DSO_R_UNLOAD_FAILED				 107
+#define DSO_R_UNSUPPORTED				 108
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/dso/dso_beos.c b/openssl/crypto/dso/dso_beos.c
new file mode 100644
index 0000000..553966e
--- /dev/null
+++ b/openssl/crypto/dso/dso_beos.c
@@ -0,0 +1,270 @@
+/* dso_beos.c */
+/* Written by Marcin Konicki (ahwayakchih@neoni.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+
+#if !defined(OPENSSL_SYS_BEOS)
+DSO_METHOD *DSO_METHOD_beos(void)
+	{
+	return NULL;
+	}
+#else
+
+#include <kernel/image.h>
+
+static int beos_load(DSO *dso);
+static int beos_unload(DSO *dso);
+static void *beos_bind_var(DSO *dso, const char *symname);
+static DSO_FUNC_TYPE beos_bind_func(DSO *dso, const char *symname);
+#if 0
+static int beos_unbind_var(DSO *dso, char *symname, void *symptr);
+static int beos_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
+static int beos_init(DSO *dso);
+static int beos_finish(DSO *dso);
+static long beos_ctrl(DSO *dso, int cmd, long larg, void *parg);
+#endif
+static char *beos_name_converter(DSO *dso, const char *filename);
+
+static DSO_METHOD dso_meth_beos = {
+	"OpenSSL 'beos' shared library method",
+	beos_load,
+	beos_unload,
+	beos_bind_var,
+	beos_bind_func,
+/* For now, "unbind" doesn't exist */
+#if 0
+	NULL, /* unbind_var */
+	NULL, /* unbind_func */
+#endif
+	NULL, /* ctrl */
+	beos_name_converter,
+	NULL, /* init */
+	NULL  /* finish */
+	};
+
+DSO_METHOD *DSO_METHOD_beos(void)
+	{
+	return(&dso_meth_beos);
+	}
+
+/* For this DSO_METHOD, our meth_data STACK will contain;
+ * (i) a pointer to the handle (image_id) returned from
+ *     load_add_on().
+ */
+
+static int beos_load(DSO *dso)
+	{
+	image_id id;
+	/* See applicable comments from dso_dl.c */
+	char *filename = DSO_convert_filename(dso, NULL);
+
+	if(filename == NULL)
+		{
+		DSOerr(DSO_F_BEOS_LOAD,DSO_R_NO_FILENAME);
+		goto err;
+		}
+	id = load_add_on(filename);
+	if(id < 1)
+		{
+		DSOerr(DSO_F_BEOS_LOAD,DSO_R_LOAD_FAILED);
+		ERR_add_error_data(3, "filename(", filename, ")");
+		goto err;
+		}
+	if(!sk_push(dso->meth_data, (char *)id))
+		{
+		DSOerr(DSO_F_BEOS_LOAD,DSO_R_STACK_ERROR);
+		goto err;
+		}
+	/* Success */
+	dso->loaded_filename = filename;
+	return(1);
+err:
+	/* Cleanup !*/
+	if(filename != NULL)
+		OPENSSL_free(filename);
+	if(id > 0)
+		unload_add_on(id);
+	return(0);
+	}
+
+static int beos_unload(DSO *dso)
+	{
+	image_id id;
+	if(dso == NULL)
+		{
+		DSOerr(DSO_F_BEOS_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	if(sk_num(dso->meth_data) < 1)
+		return(1);
+	id = (image_id)sk_pop(dso->meth_data);
+	if(id < 1)
+		{
+		DSOerr(DSO_F_BEOS_UNLOAD,DSO_R_NULL_HANDLE);
+		return(0);
+		}
+	if(unload_add_on(id) != B_OK)
+		{
+		DSOerr(DSO_F_BEOS_UNLOAD,DSO_R_UNLOAD_FAILED);
+		/* We should push the value back onto the stack in
+		 * case of a retry. */
+		sk_push(dso->meth_data, (char *)id);
+		return(0);
+		}
+	return(1);
+	}
+
+static void *beos_bind_var(DSO *dso, const char *symname)
+	{
+	image_id id;
+	void *sym;
+
+	if((dso == NULL) || (symname == NULL))
+		{
+		DSOerr(DSO_F_BEOS_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	if(sk_num(dso->meth_data) < 1)
+		{
+		DSOerr(DSO_F_BEOS_BIND_VAR,DSO_R_STACK_ERROR);
+		return(NULL);
+		}
+	id = (image_id)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
+	if(id < 1)
+		{
+		DSOerr(DSO_F_BEOS_BIND_VAR,DSO_R_NULL_HANDLE);
+		return(NULL);
+		}
+	if(get_image_symbol(id, symname, B_SYMBOL_TYPE_DATA, &sym) != B_OK)
+		{
+		DSOerr(DSO_F_BEOS_BIND_VAR,DSO_R_SYM_FAILURE);
+		ERR_add_error_data(3, "symname(", symname, ")");
+		return(NULL);
+		}
+	return(sym);
+	}
+
+static DSO_FUNC_TYPE beos_bind_func(DSO *dso, const char *symname)
+	{
+	image_id id;
+	void *sym;
+
+	if((dso == NULL) || (symname == NULL))
+		{
+		DSOerr(DSO_F_BEOS_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	if(sk_num(dso->meth_data) < 1)
+		{
+		DSOerr(DSO_F_BEOS_BIND_FUNC,DSO_R_STACK_ERROR);
+		return(NULL);
+		}
+	id = (image_id)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
+	if(id < 1)
+		{
+		DSOerr(DSO_F_BEOS_BIND_FUNC,DSO_R_NULL_HANDLE);
+		return(NULL);
+		}
+	if(get_image_symbol(id, symname, B_SYMBOL_TYPE_TEXT, &sym) != B_OK)
+		{
+		DSOerr(DSO_F_BEOS_BIND_FUNC,DSO_R_SYM_FAILURE);
+		ERR_add_error_data(3, "symname(", symname, ")");
+		return(NULL);
+		}
+	return((DSO_FUNC_TYPE)sym);
+	}
+
+/* This one is the same as the one in dlfcn */
+static char *beos_name_converter(DSO *dso, const char *filename)
+	{
+	char *translated;
+	int len, rsize, transform;
+
+	len = strlen(filename);
+	rsize = len + 1;
+	transform = (strstr(filename, "/") == NULL);
+	if(transform)
+		{
+		/* We will convert this to "%s.so" or "lib%s.so" */
+		rsize += 3;	/* The length of ".so" */
+		if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
+			rsize += 3; /* The length of "lib" */
+		}
+	translated = OPENSSL_malloc(rsize);
+	if(translated == NULL)
+		{
+		DSOerr(DSO_F_BEOS_NAME_CONVERTER,
+				DSO_R_NAME_TRANSLATION_FAILED);
+		return(NULL);
+		}
+	if(transform)
+		{
+		if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
+			sprintf(translated, "lib%s.so", filename);
+		else
+			sprintf(translated, "%s.so", filename);
+		}
+	else
+		sprintf(translated, "%s", filename);
+	return(translated);
+	}
+
+#endif
diff --git a/openssl/crypto/dso/dso_dl.c b/openssl/crypto/dso/dso_dl.c
new file mode 100644
index 0000000..fc4236b
--- /dev/null
+++ b/openssl/crypto/dso/dso_dl.c
@@ -0,0 +1,393 @@
+/* dso_dl.c -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+
+#ifndef DSO_DL
+DSO_METHOD *DSO_METHOD_dl(void)
+       {
+       return NULL;
+       }
+#else
+
+#include <dl.h>
+
+/* Part of the hack in "dl_load" ... */
+#define DSO_MAX_TRANSLATED_SIZE 256
+
+static int dl_load(DSO *dso);
+static int dl_unload(DSO *dso);
+static void *dl_bind_var(DSO *dso, const char *symname);
+static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname);
+#if 0
+static int dl_unbind_var(DSO *dso, char *symname, void *symptr);
+static int dl_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
+static int dl_init(DSO *dso);
+static int dl_finish(DSO *dso);
+static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg);
+#endif
+static char *dl_name_converter(DSO *dso, const char *filename);
+static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2);
+static int dl_pathbyaddr(void *addr,char *path,int sz);
+static void *dl_globallookup(const char *name);
+
+static DSO_METHOD dso_meth_dl = {
+	"OpenSSL 'dl' shared library method",
+	dl_load,
+	dl_unload,
+	dl_bind_var,
+	dl_bind_func,
+/* For now, "unbind" doesn't exist */
+#if 0
+	NULL, /* unbind_var */
+	NULL, /* unbind_func */
+#endif
+	NULL, /* ctrl */
+	dl_name_converter,
+	dl_merger,
+	NULL, /* init */
+	NULL, /* finish */
+	dl_pathbyaddr,
+	dl_globallookup
+	};
+
+DSO_METHOD *DSO_METHOD_dl(void)
+	{
+	return(&dso_meth_dl);
+	}
+
+/* For this DSO_METHOD, our meth_data STACK will contain;
+ * (i) the handle (shl_t) returned from shl_load().
+ * NB: I checked on HPUX11 and shl_t is itself a pointer
+ * type so the cast is safe.
+ */
+
+static int dl_load(DSO *dso)
+	{
+	shl_t ptr = NULL;
+	/* We don't do any fancy retries or anything, just take the method's
+	 * (or DSO's if it has the callback set) best translation of the
+	 * platform-independant filename and try once with that. */
+	char *filename= DSO_convert_filename(dso, NULL);
+
+	if(filename == NULL)
+		{
+		DSOerr(DSO_F_DL_LOAD,DSO_R_NO_FILENAME);
+		goto err;
+		}
+	ptr = shl_load(filename, BIND_IMMEDIATE |
+		(dso->flags&DSO_FLAG_NO_NAME_TRANSLATION?0:DYNAMIC_PATH), 0L);
+	if(ptr == NULL)
+		{
+		DSOerr(DSO_F_DL_LOAD,DSO_R_LOAD_FAILED);
+		ERR_add_error_data(4, "filename(", filename, "): ",
+			strerror(errno));
+		goto err;
+		}
+	if(!sk_push(dso->meth_data, (char *)ptr))
+		{
+		DSOerr(DSO_F_DL_LOAD,DSO_R_STACK_ERROR);
+		goto err;
+		}
+	/* Success, stick the converted filename we've loaded under into the DSO
+	 * (it also serves as the indicator that we are currently loaded). */
+	dso->loaded_filename = filename;
+	return(1);
+err:
+	/* Cleanup! */
+	if(filename != NULL)
+		OPENSSL_free(filename);
+	if(ptr != NULL)
+		shl_unload(ptr);
+	return(0);
+	}
+
+static int dl_unload(DSO *dso)
+	{
+	shl_t ptr;
+	if(dso == NULL)
+		{
+		DSOerr(DSO_F_DL_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	if(sk_num(dso->meth_data) < 1)
+		return(1);
+	/* Is this statement legal? */
+	ptr = (shl_t)sk_pop(dso->meth_data);
+	if(ptr == NULL)
+		{
+		DSOerr(DSO_F_DL_UNLOAD,DSO_R_NULL_HANDLE);
+		/* Should push the value back onto the stack in
+		 * case of a retry. */
+		sk_push(dso->meth_data, (char *)ptr);
+		return(0);
+		}
+	shl_unload(ptr);
+	return(1);
+	}
+
+static void *dl_bind_var(DSO *dso, const char *symname)
+	{
+	shl_t ptr;
+	void *sym;
+
+	if((dso == NULL) || (symname == NULL))
+		{
+		DSOerr(DSO_F_DL_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	if(sk_num(dso->meth_data) < 1)
+		{
+		DSOerr(DSO_F_DL_BIND_VAR,DSO_R_STACK_ERROR);
+		return(NULL);
+		}
+	ptr = (shl_t)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
+	if(ptr == NULL)
+		{
+		DSOerr(DSO_F_DL_BIND_VAR,DSO_R_NULL_HANDLE);
+		return(NULL);
+		}
+	if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0)
+		{
+		DSOerr(DSO_F_DL_BIND_VAR,DSO_R_SYM_FAILURE);
+		ERR_add_error_data(4, "symname(", symname, "): ",
+			strerror(errno));
+		return(NULL);
+		}
+	return(sym);
+	}
+
+static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname)
+	{
+	shl_t ptr;
+	void *sym;
+
+	if((dso == NULL) || (symname == NULL))
+		{
+		DSOerr(DSO_F_DL_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	if(sk_num(dso->meth_data) < 1)
+		{
+		DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_STACK_ERROR);
+		return(NULL);
+		}
+	ptr = (shl_t)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
+	if(ptr == NULL)
+		{
+		DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_NULL_HANDLE);
+		return(NULL);
+		}
+	if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0)
+		{
+		DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_SYM_FAILURE);
+		ERR_add_error_data(4, "symname(", symname, "): ",
+			strerror(errno));
+		return(NULL);
+		}
+	return((DSO_FUNC_TYPE)sym);
+	}
+
+static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2)
+	{
+	char *merged;
+
+	if(!filespec1 && !filespec2)
+		{
+		DSOerr(DSO_F_DL_MERGER,
+				ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	/* If the first file specification is a rooted path, it rules.
+	   same goes if the second file specification is missing. */
+	if (!filespec2 || filespec1[0] == '/')
+		{
+		merged = OPENSSL_malloc(strlen(filespec1) + 1);
+		if(!merged)
+			{
+			DSOerr(DSO_F_DL_MERGER,
+				ERR_R_MALLOC_FAILURE);
+			return(NULL);
+			}
+		strcpy(merged, filespec1);
+		}
+	/* If the first file specification is missing, the second one rules. */
+	else if (!filespec1)
+		{
+		merged = OPENSSL_malloc(strlen(filespec2) + 1);
+		if(!merged)
+			{
+			DSOerr(DSO_F_DL_MERGER,
+				ERR_R_MALLOC_FAILURE);
+			return(NULL);
+			}
+		strcpy(merged, filespec2);
+		}
+	else
+		/* This part isn't as trivial as it looks.  It assumes that
+		   the second file specification really is a directory, and
+		   makes no checks whatsoever.  Therefore, the result becomes
+		   the concatenation of filespec2 followed by a slash followed
+		   by filespec1. */
+		{
+		int spec2len, len;
+
+		spec2len = (filespec2 ? strlen(filespec2) : 0);
+		len = spec2len + (filespec1 ? strlen(filespec1) : 0);
+
+		if(filespec2 && filespec2[spec2len - 1] == '/')
+			{
+			spec2len--;
+			len--;
+			}
+		merged = OPENSSL_malloc(len + 2);
+		if(!merged)
+			{
+			DSOerr(DSO_F_DL_MERGER,
+				ERR_R_MALLOC_FAILURE);
+			return(NULL);
+			}
+		strcpy(merged, filespec2);
+		merged[spec2len] = '/';
+		strcpy(&merged[spec2len + 1], filespec1);
+		}
+	return(merged);
+	}
+
+/* This function is identical to the one in dso_dlfcn.c, but as it is highly
+ * unlikely that both the "dl" *and* "dlfcn" variants are being compiled at the
+ * same time, there's no great duplicating the code. Figuring out an elegant 
+ * way to share one copy of the code would be more difficult and would not
+ * leave the implementations independant. */
+#if defined(__hpux)
+static const char extension[] = ".sl";
+#else
+static const char extension[] = ".so";
+#endif
+static char *dl_name_converter(DSO *dso, const char *filename)
+	{
+	char *translated;
+	int len, rsize, transform;
+
+	len = strlen(filename);
+	rsize = len + 1;
+	transform = (strstr(filename, "/") == NULL);
+		{
+		/* We will convert this to "%s.s?" or "lib%s.s?" */
+		rsize += strlen(extension);/* The length of ".s?" */
+		if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
+			rsize += 3; /* The length of "lib" */
+		}
+	translated = OPENSSL_malloc(rsize);
+	if(translated == NULL)
+		{
+		DSOerr(DSO_F_DL_NAME_CONVERTER,
+				DSO_R_NAME_TRANSLATION_FAILED); 
+		return(NULL);   
+		}
+	if(transform)
+		{
+		if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
+			sprintf(translated, "lib%s%s", filename, extension);
+		else
+			sprintf(translated, "%s%s", filename, extension);
+		}
+	else
+		sprintf(translated, "%s", filename);
+	return(translated);
+	}
+
+static int dl_pathbyaddr(void *addr,char *path,int sz)
+	{
+	struct shl_descriptor inf;
+	int i,len;
+
+	if (addr == NULL)
+		{
+		union	{ int(*f)(void*,char*,int); void *p; } t =
+			{ dl_pathbyaddr };
+		addr = t.p;
+		}
+
+	for (i=-1;shl_get_r(i,&inf)==0;i++)
+		{
+		if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) ||
+		    ((size_t)addr >= inf.dstart && (size_t)addr < inf.dend))
+			{
+			len = (int)strlen(inf.filename);
+			if (sz <= 0) return len+1;
+			if (len >= sz) len=sz-1;
+			memcpy(path,inf.filename,len);
+			path[len++] = 0;
+			return len;
+			}
+		}
+
+	return -1;
+	}
+
+static void *dl_globallookup(const char *name)
+	{
+	void *ret;
+	shl_t h = NULL;
+
+	return shl_findsym(&h,name,TYPE_UNDEFINED,&ret) ? NULL : ret;
+	}
+#endif /* DSO_DL */
diff --git a/openssl/crypto/dso/dso_dlfcn.c b/openssl/crypto/dso/dso_dlfcn.c
new file mode 100644
index 0000000..c2bc617
--- /dev/null
+++ b/openssl/crypto/dso/dso_dlfcn.c
@@ -0,0 +1,483 @@
+/* dso_dlfcn.c -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* We need to do this early, because stdio.h includes the header files
+   that handle _GNU_SOURCE and other similar macros.  Defining it later
+   is simply too late, because those headers are protected from re-
+   inclusion.  */
+#ifdef __linux
+# ifndef _GNU_SOURCE
+#  define _GNU_SOURCE	/* make sure dladdr is declared */
+# endif
+#endif
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+
+#ifndef DSO_DLFCN
+DSO_METHOD *DSO_METHOD_dlfcn(void)
+	{
+	return NULL;
+	}
+#else
+
+#ifdef HAVE_DLFCN_H
+# ifdef __osf__
+#  define __EXTENSIONS__
+# endif
+# include <dlfcn.h>
+# define HAVE_DLINFO 1
+# if defined(_AIX) || defined(__CYGWIN__) || \
+     defined(__SCO_VERSION__) || defined(_SCO_ELF) || \
+     (defined(__osf__) && !defined(RTLD_NEXT))     || \
+     (defined(__OpenBSD__) && !defined(RTLD_SELF))
+#  undef HAVE_DLINFO
+# endif
+#endif
+
+/* Part of the hack in "dlfcn_load" ... */
+#define DSO_MAX_TRANSLATED_SIZE 256
+
+static int dlfcn_load(DSO *dso);
+static int dlfcn_unload(DSO *dso);
+static void *dlfcn_bind_var(DSO *dso, const char *symname);
+static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname);
+#if 0
+static int dlfcn_unbind(DSO *dso, char *symname, void *symptr);
+static int dlfcn_init(DSO *dso);
+static int dlfcn_finish(DSO *dso);
+static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg);
+#endif
+static char *dlfcn_name_converter(DSO *dso, const char *filename);
+static char *dlfcn_merger(DSO *dso, const char *filespec1,
+	const char *filespec2);
+static int dlfcn_pathbyaddr(void *addr,char *path,int sz);
+static void *dlfcn_globallookup(const char *name);
+
+static DSO_METHOD dso_meth_dlfcn = {
+	"OpenSSL 'dlfcn' shared library method",
+	dlfcn_load,
+	dlfcn_unload,
+	dlfcn_bind_var,
+	dlfcn_bind_func,
+/* For now, "unbind" doesn't exist */
+#if 0
+	NULL, /* unbind_var */
+	NULL, /* unbind_func */
+#endif
+	NULL, /* ctrl */
+	dlfcn_name_converter,
+	dlfcn_merger,
+	NULL, /* init */
+	NULL, /* finish */
+	dlfcn_pathbyaddr,
+	dlfcn_globallookup
+	};
+
+DSO_METHOD *DSO_METHOD_dlfcn(void)
+	{
+	return(&dso_meth_dlfcn);
+	}
+
+/* Prior to using the dlopen() function, we should decide on the flag
+ * we send. There's a few different ways of doing this and it's a
+ * messy venn-diagram to match up which platforms support what. So
+ * as we don't have autoconf yet, I'm implementing a hack that could
+ * be hacked further relatively easily to deal with cases as we find
+ * them. Initially this is to cope with OpenBSD. */
+#if defined(__OpenBSD__) || defined(__NetBSD__)
+#	ifdef DL_LAZY
+#		define DLOPEN_FLAG DL_LAZY
+#	else
+#		ifdef RTLD_NOW
+#			define DLOPEN_FLAG RTLD_NOW
+#		else
+#			define DLOPEN_FLAG 0
+#		endif
+#	endif
+#else
+#	ifdef OPENSSL_SYS_SUNOS
+#		define DLOPEN_FLAG 1
+#	else
+#		define DLOPEN_FLAG RTLD_NOW /* Hope this works everywhere else */
+#	endif
+#endif
+
+/* For this DSO_METHOD, our meth_data STACK will contain;
+ * (i) the handle (void*) returned from dlopen().
+ */
+
+static int dlfcn_load(DSO *dso)
+	{
+	void *ptr = NULL;
+	/* See applicable comments in dso_dl.c */
+	char *filename = DSO_convert_filename(dso, NULL);
+	int flags = DLOPEN_FLAG;
+
+	if(filename == NULL)
+		{
+		DSOerr(DSO_F_DLFCN_LOAD,DSO_R_NO_FILENAME);
+		goto err;
+		}
+
+#ifdef RTLD_GLOBAL
+	if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS)
+		flags |= RTLD_GLOBAL;
+#endif
+	ptr = dlopen(filename, flags);
+	if(ptr == NULL)
+		{
+		DSOerr(DSO_F_DLFCN_LOAD,DSO_R_LOAD_FAILED);
+		ERR_add_error_data(4, "filename(", filename, "): ", dlerror());
+		goto err;
+		}
+	if(!sk_void_push(dso->meth_data, (char *)ptr))
+		{
+		DSOerr(DSO_F_DLFCN_LOAD,DSO_R_STACK_ERROR);
+		goto err;
+		}
+	/* Success */
+	dso->loaded_filename = filename;
+	return(1);
+err:
+	/* Cleanup! */
+	if(filename != NULL)
+		OPENSSL_free(filename);
+	if(ptr != NULL)
+		dlclose(ptr);
+	return(0);
+}
+
+static int dlfcn_unload(DSO *dso)
+	{
+	void *ptr;
+	if(dso == NULL)
+		{
+		DSOerr(DSO_F_DLFCN_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	if(sk_void_num(dso->meth_data) < 1)
+		return(1);
+	ptr = sk_void_pop(dso->meth_data);
+	if(ptr == NULL)
+		{
+		DSOerr(DSO_F_DLFCN_UNLOAD,DSO_R_NULL_HANDLE);
+		/* Should push the value back onto the stack in
+		 * case of a retry. */
+		sk_void_push(dso->meth_data, ptr);
+		return(0);
+		}
+	/* For now I'm not aware of any errors associated with dlclose() */
+	dlclose(ptr);
+	return(1);
+	}
+
+static void *dlfcn_bind_var(DSO *dso, const char *symname)
+	{
+	void *ptr, *sym;
+
+	if((dso == NULL) || (symname == NULL))
+		{
+		DSOerr(DSO_F_DLFCN_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	if(sk_void_num(dso->meth_data) < 1)
+		{
+		DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_STACK_ERROR);
+		return(NULL);
+		}
+	ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
+	if(ptr == NULL)
+		{
+		DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_NULL_HANDLE);
+		return(NULL);
+		}
+	sym = dlsym(ptr, symname);
+	if(sym == NULL)
+		{
+		DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_SYM_FAILURE);
+		ERR_add_error_data(4, "symname(", symname, "): ", dlerror());
+		return(NULL);
+		}
+	return(sym);
+	}
+
+static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
+	{
+	void *ptr;
+	union {
+		DSO_FUNC_TYPE sym;
+		void *dlret;
+	} u;
+
+	if((dso == NULL) || (symname == NULL))
+		{
+		DSOerr(DSO_F_DLFCN_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	if(sk_void_num(dso->meth_data) < 1)
+		{
+		DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_STACK_ERROR);
+		return(NULL);
+		}
+	ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
+	if(ptr == NULL)
+		{
+		DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE);
+		return(NULL);
+		}
+	u.dlret = dlsym(ptr, symname);
+	if(u.dlret == NULL)
+		{
+		DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE);
+		ERR_add_error_data(4, "symname(", symname, "): ", dlerror());
+		return(NULL);
+		}
+	return u.sym;
+	}
+
+static char *dlfcn_merger(DSO *dso, const char *filespec1,
+	const char *filespec2)
+	{
+	char *merged;
+
+	if(!filespec1 && !filespec2)
+		{
+		DSOerr(DSO_F_DLFCN_MERGER,
+				ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	/* If the first file specification is a rooted path, it rules.
+	   same goes if the second file specification is missing. */
+	if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/'))
+		{
+		merged = OPENSSL_malloc(strlen(filespec1) + 1);
+		if(!merged)
+			{
+			DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
+			return(NULL);
+			}
+		strcpy(merged, filespec1);
+		}
+	/* If the first file specification is missing, the second one rules. */
+	else if (!filespec1)
+		{
+		merged = OPENSSL_malloc(strlen(filespec2) + 1);
+		if(!merged)
+			{
+			DSOerr(DSO_F_DLFCN_MERGER,
+				ERR_R_MALLOC_FAILURE);
+			return(NULL);
+			}
+		strcpy(merged, filespec2);
+		}
+	else
+		/* This part isn't as trivial as it looks.  It assumes that
+		   the second file specification really is a directory, and
+		   makes no checks whatsoever.  Therefore, the result becomes
+		   the concatenation of filespec2 followed by a slash followed
+		   by filespec1. */
+		{
+		int spec2len, len;
+
+		spec2len = strlen(filespec2);
+		len = spec2len + (filespec1 ? strlen(filespec1) : 0);
+
+		if(filespec2 && filespec2[spec2len - 1] == '/')
+			{
+			spec2len--;
+			len--;
+			}
+		merged = OPENSSL_malloc(len + 2);
+		if(!merged)
+			{
+			DSOerr(DSO_F_DLFCN_MERGER,
+				ERR_R_MALLOC_FAILURE);
+			return(NULL);
+			}
+		strcpy(merged, filespec2);
+		merged[spec2len] = '/';
+		strcpy(&merged[spec2len + 1], filespec1);
+		}
+	return(merged);
+	}
+
+#ifdef OPENSSL_SYS_MACOSX
+#define DSO_ext	".dylib"
+#define DSO_extlen 6
+#else
+#define DSO_ext	".so"
+#define DSO_extlen 3
+#endif
+
+
+static char *dlfcn_name_converter(DSO *dso, const char *filename)
+	{
+	char *translated;
+	int len, rsize, transform;
+
+	len = strlen(filename);
+	rsize = len + 1;
+	transform = (strstr(filename, "/") == NULL);
+	if(transform)
+		{
+		/* We will convert this to "%s.so" or "lib%s.so" etc */
+		rsize += DSO_extlen;	/* The length of ".so" */
+		if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
+			rsize += 3; /* The length of "lib" */
+		}
+	translated = OPENSSL_malloc(rsize);
+	if(translated == NULL)
+		{
+		DSOerr(DSO_F_DLFCN_NAME_CONVERTER,
+				DSO_R_NAME_TRANSLATION_FAILED);
+		return(NULL);
+		}
+	if(transform)
+		{
+		if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
+			sprintf(translated, "lib%s" DSO_ext, filename);
+		else
+			sprintf(translated, "%s" DSO_ext, filename);
+		}
+	else
+		sprintf(translated, "%s", filename);
+	return(translated);
+	}
+
+#ifdef __sgi
+/*
+This is a quote from IRIX manual for dladdr(3c):
+
+     <dlfcn.h> does not contain a prototype for dladdr or definition of
+     Dl_info.  The #include <dlfcn.h>  in the SYNOPSIS line is traditional,
+     but contains no dladdr prototype and no IRIX library contains an
+     implementation.  Write your own declaration based on the code below.
+
+     The following code is dependent on internal interfaces that are not
+     part of the IRIX compatibility guarantee; however, there is no future
+     intention to change this interface, so on a practical level, the code
+     below is safe to use on IRIX.
+*/
+#include <rld_interface.h>
+#ifndef _RLD_INTERFACE_DLFCN_H_DLADDR
+#define _RLD_INTERFACE_DLFCN_H_DLADDR
+typedef struct Dl_info {
+    const char * dli_fname;
+    void       * dli_fbase;
+    const char * dli_sname;
+    void       * dli_saddr;
+    int          dli_version;
+    int          dli_reserved1;
+    long         dli_reserved[4];
+} Dl_info;
+#else
+typedef struct Dl_info Dl_info;
+#endif
+#define _RLD_DLADDR             14
+
+static int dladdr(void *address, Dl_info *dl)
+{
+	void *v;
+	v = _rld_new_interface(_RLD_DLADDR,address,dl);
+	return (int)v;
+}
+#endif /* __sgi */
+
+static int dlfcn_pathbyaddr(void *addr,char *path,int sz)
+	{
+#ifdef HAVE_DLINFO
+	Dl_info dli;
+	int len;
+
+	if (addr == NULL)
+		{
+		union	{ int(*f)(void*,char*,int); void *p; } t =
+			{ dlfcn_pathbyaddr };
+		addr = t.p;
+		}
+
+	if (dladdr(addr,&dli))
+		{
+		len = (int)strlen(dli.dli_fname);
+		if (sz <= 0) return len+1;
+		if (len >= sz) len=sz-1;
+		memcpy(path,dli.dli_fname,len);
+		path[len++]=0;
+		return len;
+		}
+
+	ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror());
+#endif
+	return -1;
+	}
+
+static void *dlfcn_globallookup(const char *name)
+	{
+	void *ret = NULL,*handle = dlopen(NULL,RTLD_LAZY);
+	
+	if (handle)
+		{
+		ret = dlsym(handle,name);
+		dlclose(handle);
+		}
+
+	return ret;
+	}
+#endif /* DSO_DLFCN */
diff --git a/openssl/crypto/dso/dso_err.c b/openssl/crypto/dso/dso_err.c
new file mode 100644
index 0000000..2bb07c2
--- /dev/null
+++ b/openssl/crypto/dso/dso_err.c
@@ -0,0 +1,159 @@
+/* crypto/dso/dso_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/dso.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSO,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSO,0,reason)
+
+static ERR_STRING_DATA DSO_str_functs[]=
+	{
+{ERR_FUNC(DSO_F_BEOS_BIND_FUNC),	"BEOS_BIND_FUNC"},
+{ERR_FUNC(DSO_F_BEOS_BIND_VAR),	"BEOS_BIND_VAR"},
+{ERR_FUNC(DSO_F_BEOS_LOAD),	"BEOS_LOAD"},
+{ERR_FUNC(DSO_F_BEOS_NAME_CONVERTER),	"BEOS_NAME_CONVERTER"},
+{ERR_FUNC(DSO_F_BEOS_UNLOAD),	"BEOS_UNLOAD"},
+{ERR_FUNC(DSO_F_DLFCN_BIND_FUNC),	"DLFCN_BIND_FUNC"},
+{ERR_FUNC(DSO_F_DLFCN_BIND_VAR),	"DLFCN_BIND_VAR"},
+{ERR_FUNC(DSO_F_DLFCN_LOAD),	"DLFCN_LOAD"},
+{ERR_FUNC(DSO_F_DLFCN_MERGER),	"DLFCN_MERGER"},
+{ERR_FUNC(DSO_F_DLFCN_NAME_CONVERTER),	"DLFCN_NAME_CONVERTER"},
+{ERR_FUNC(DSO_F_DLFCN_UNLOAD),	"DLFCN_UNLOAD"},
+{ERR_FUNC(DSO_F_DL_BIND_FUNC),	"DL_BIND_FUNC"},
+{ERR_FUNC(DSO_F_DL_BIND_VAR),	"DL_BIND_VAR"},
+{ERR_FUNC(DSO_F_DL_LOAD),	"DL_LOAD"},
+{ERR_FUNC(DSO_F_DL_MERGER),	"DL_MERGER"},
+{ERR_FUNC(DSO_F_DL_NAME_CONVERTER),	"DL_NAME_CONVERTER"},
+{ERR_FUNC(DSO_F_DL_UNLOAD),	"DL_UNLOAD"},
+{ERR_FUNC(DSO_F_DSO_BIND_FUNC),	"DSO_bind_func"},
+{ERR_FUNC(DSO_F_DSO_BIND_VAR),	"DSO_bind_var"},
+{ERR_FUNC(DSO_F_DSO_CONVERT_FILENAME),	"DSO_convert_filename"},
+{ERR_FUNC(DSO_F_DSO_CTRL),	"DSO_ctrl"},
+{ERR_FUNC(DSO_F_DSO_FREE),	"DSO_free"},
+{ERR_FUNC(DSO_F_DSO_GET_FILENAME),	"DSO_get_filename"},
+{ERR_FUNC(DSO_F_DSO_GET_LOADED_FILENAME),	"DSO_get_loaded_filename"},
+{ERR_FUNC(DSO_F_DSO_GLOBAL_LOOKUP),	"DSO_global_lookup"},
+{ERR_FUNC(DSO_F_DSO_LOAD),	"DSO_load"},
+{ERR_FUNC(DSO_F_DSO_MERGE),	"DSO_merge"},
+{ERR_FUNC(DSO_F_DSO_NEW_METHOD),	"DSO_new_method"},
+{ERR_FUNC(DSO_F_DSO_PATHBYADDR),	"DSO_pathbyaddr"},
+{ERR_FUNC(DSO_F_DSO_SET_FILENAME),	"DSO_set_filename"},
+{ERR_FUNC(DSO_F_DSO_SET_NAME_CONVERTER),	"DSO_set_name_converter"},
+{ERR_FUNC(DSO_F_DSO_UP_REF),	"DSO_up_ref"},
+{ERR_FUNC(DSO_F_GLOBAL_LOOKUP_FUNC),	"GLOBAL_LOOKUP_FUNC"},
+{ERR_FUNC(DSO_F_PATHBYADDR),	"PATHBYADDR"},
+{ERR_FUNC(DSO_F_VMS_BIND_SYM),	"VMS_BIND_SYM"},
+{ERR_FUNC(DSO_F_VMS_LOAD),	"VMS_LOAD"},
+{ERR_FUNC(DSO_F_VMS_MERGER),	"VMS_MERGER"},
+{ERR_FUNC(DSO_F_VMS_UNLOAD),	"VMS_UNLOAD"},
+{ERR_FUNC(DSO_F_WIN32_BIND_FUNC),	"WIN32_BIND_FUNC"},
+{ERR_FUNC(DSO_F_WIN32_BIND_VAR),	"WIN32_BIND_VAR"},
+{ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP),	"WIN32_GLOBALLOOKUP"},
+{ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP_FUNC),	"WIN32_GLOBALLOOKUP_FUNC"},
+{ERR_FUNC(DSO_F_WIN32_JOINER),	"WIN32_JOINER"},
+{ERR_FUNC(DSO_F_WIN32_LOAD),	"WIN32_LOAD"},
+{ERR_FUNC(DSO_F_WIN32_MERGER),	"WIN32_MERGER"},
+{ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER),	"WIN32_NAME_CONVERTER"},
+{ERR_FUNC(DSO_F_WIN32_PATHBYADDR),	"WIN32_PATHBYADDR"},
+{ERR_FUNC(DSO_F_WIN32_SPLITTER),	"WIN32_SPLITTER"},
+{ERR_FUNC(DSO_F_WIN32_UNLOAD),	"WIN32_UNLOAD"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA DSO_str_reasons[]=
+	{
+{ERR_REASON(DSO_R_CTRL_FAILED)           ,"control command failed"},
+{ERR_REASON(DSO_R_DSO_ALREADY_LOADED)    ,"dso already loaded"},
+{ERR_REASON(DSO_R_EMPTY_FILE_STRUCTURE)  ,"empty file structure"},
+{ERR_REASON(DSO_R_FAILURE)               ,"failure"},
+{ERR_REASON(DSO_R_FILENAME_TOO_BIG)      ,"filename too big"},
+{ERR_REASON(DSO_R_FINISH_FAILED)         ,"cleanup method function failed"},
+{ERR_REASON(DSO_R_INCORRECT_FILE_SYNTAX) ,"incorrect file syntax"},
+{ERR_REASON(DSO_R_LOAD_FAILED)           ,"could not load the shared library"},
+{ERR_REASON(DSO_R_NAME_TRANSLATION_FAILED),"name translation failed"},
+{ERR_REASON(DSO_R_NO_FILENAME)           ,"no filename"},
+{ERR_REASON(DSO_R_NO_FILE_SPECIFICATION) ,"no file specification"},
+{ERR_REASON(DSO_R_NULL_HANDLE)           ,"a null shared library handle was used"},
+{ERR_REASON(DSO_R_SET_FILENAME_FAILED)   ,"set filename failed"},
+{ERR_REASON(DSO_R_STACK_ERROR)           ,"the meth_data stack is corrupt"},
+{ERR_REASON(DSO_R_SYM_FAILURE)           ,"could not bind to the requested symbol name"},
+{ERR_REASON(DSO_R_UNLOAD_FAILED)         ,"could not unload the shared library"},
+{ERR_REASON(DSO_R_UNSUPPORTED)           ,"functionality not supported"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_DSO_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(DSO_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,DSO_str_functs);
+		ERR_load_strings(0,DSO_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/dso/dso_lib.c b/openssl/crypto/dso/dso_lib.c
new file mode 100644
index 0000000..8a15b79
--- /dev/null
+++ b/openssl/crypto/dso/dso_lib.c
@@ -0,0 +1,483 @@
+/* dso_lib.c -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+
+static DSO_METHOD *default_DSO_meth = NULL;
+
+DSO *DSO_new(void)
+	{
+	return(DSO_new_method(NULL));
+	}
+
+void DSO_set_default_method(DSO_METHOD *meth)
+	{
+	default_DSO_meth = meth;
+	}
+
+DSO_METHOD *DSO_get_default_method(void)
+	{
+	return(default_DSO_meth);
+	}
+
+DSO_METHOD *DSO_get_method(DSO *dso)
+	{
+	return(dso->meth);
+	}
+
+DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth)
+	{
+	DSO_METHOD *mtmp;
+	mtmp = dso->meth;
+	dso->meth = meth;
+	return(mtmp);
+	}
+
+DSO *DSO_new_method(DSO_METHOD *meth)
+	{
+	DSO *ret;
+
+	if(default_DSO_meth == NULL)
+		/* We default to DSO_METH_openssl() which in turn defaults
+		 * to stealing the "best available" method. Will fallback
+		 * to DSO_METH_null() in the worst case. */
+		default_DSO_meth = DSO_METHOD_openssl();
+	ret = (DSO *)OPENSSL_malloc(sizeof(DSO));
+	if(ret == NULL)
+		{
+		DSOerr(DSO_F_DSO_NEW_METHOD,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	memset(ret, 0, sizeof(DSO));
+	ret->meth_data = sk_void_new_null();
+	if(ret->meth_data == NULL)
+		{
+		/* sk_new doesn't generate any errors so we do */
+		DSOerr(DSO_F_DSO_NEW_METHOD,ERR_R_MALLOC_FAILURE);
+		OPENSSL_free(ret);
+		return(NULL);
+		}
+	if(meth == NULL)
+		ret->meth = default_DSO_meth;
+	else
+		ret->meth = meth;
+	ret->references = 1;
+	if((ret->meth->init != NULL) && !ret->meth->init(ret))
+		{
+		OPENSSL_free(ret);
+		ret=NULL;
+		}
+	return(ret);
+	}
+
+int DSO_free(DSO *dso)
+	{
+        int i;
+ 
+	if(dso == NULL)
+		{
+		DSOerr(DSO_F_DSO_FREE,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+ 
+	i=CRYPTO_add(&dso->references,-1,CRYPTO_LOCK_DSO);
+#ifdef REF_PRINT
+	REF_PRINT("DSO",dso);
+#endif
+	if(i > 0) return(1);
+#ifdef REF_CHECK
+	if(i < 0)
+		{
+		fprintf(stderr,"DSO_free, bad reference count\n");
+		abort();
+		}
+#endif
+
+	if((dso->meth->dso_unload != NULL) && !dso->meth->dso_unload(dso))
+		{
+		DSOerr(DSO_F_DSO_FREE,DSO_R_UNLOAD_FAILED);
+		return(0);
+		}
+ 
+	if((dso->meth->finish != NULL) && !dso->meth->finish(dso))
+		{
+		DSOerr(DSO_F_DSO_FREE,DSO_R_FINISH_FAILED);
+		return(0);
+		}
+	
+	sk_void_free(dso->meth_data);
+	if(dso->filename != NULL)
+		OPENSSL_free(dso->filename);
+	if(dso->loaded_filename != NULL)
+		OPENSSL_free(dso->loaded_filename);
+ 
+	OPENSSL_free(dso);
+	return(1);
+	}
+
+int DSO_flags(DSO *dso)
+	{
+	return((dso == NULL) ? 0 : dso->flags);
+	}
+
+
+int DSO_up_ref(DSO *dso)
+	{
+	if (dso == NULL)
+		{
+		DSOerr(DSO_F_DSO_UP_REF,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+
+	CRYPTO_add(&dso->references,1,CRYPTO_LOCK_DSO);
+	return(1);
+	}
+
+DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags)
+	{
+	DSO *ret;
+	int allocated = 0;
+
+	if(dso == NULL)
+		{
+		ret = DSO_new_method(meth);
+		if(ret == NULL)
+			{
+			DSOerr(DSO_F_DSO_LOAD,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		allocated = 1;
+		/* Pass the provided flags to the new DSO object */
+		if(DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0)
+			{
+			DSOerr(DSO_F_DSO_LOAD,DSO_R_CTRL_FAILED);
+			goto err;
+			}
+		}
+	else
+		ret = dso;
+	/* Don't load if we're currently already loaded */
+	if(ret->filename != NULL)
+		{
+		DSOerr(DSO_F_DSO_LOAD,DSO_R_DSO_ALREADY_LOADED);
+		goto err;
+		}
+	/* filename can only be NULL if we were passed a dso that already has
+	 * one set. */
+	if(filename != NULL)
+		if(!DSO_set_filename(ret, filename))
+			{
+			DSOerr(DSO_F_DSO_LOAD,DSO_R_SET_FILENAME_FAILED);
+			goto err;
+			}
+	filename = ret->filename;
+	if(filename == NULL)
+		{
+		DSOerr(DSO_F_DSO_LOAD,DSO_R_NO_FILENAME);
+		goto err;
+		}
+	if(ret->meth->dso_load == NULL)
+		{
+		DSOerr(DSO_F_DSO_LOAD,DSO_R_UNSUPPORTED);
+		goto err;
+		}
+	if(!ret->meth->dso_load(ret))
+		{
+		DSOerr(DSO_F_DSO_LOAD,DSO_R_LOAD_FAILED);
+		goto err;
+		}
+	/* Load succeeded */
+	return(ret);
+err:
+	if(allocated)
+		DSO_free(ret);
+	return(NULL);
+	}
+
+void *DSO_bind_var(DSO *dso, const char *symname)
+	{
+	void *ret = NULL;
+
+	if((dso == NULL) || (symname == NULL))
+		{
+		DSOerr(DSO_F_DSO_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	if(dso->meth->dso_bind_var == NULL)
+		{
+		DSOerr(DSO_F_DSO_BIND_VAR,DSO_R_UNSUPPORTED);
+		return(NULL);
+		}
+	if((ret = dso->meth->dso_bind_var(dso, symname)) == NULL)
+		{
+		DSOerr(DSO_F_DSO_BIND_VAR,DSO_R_SYM_FAILURE);
+		return(NULL);
+		}
+	/* Success */
+	return(ret);
+	}
+
+DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname)
+	{
+	DSO_FUNC_TYPE ret = NULL;
+
+	if((dso == NULL) || (symname == NULL))
+		{
+		DSOerr(DSO_F_DSO_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	if(dso->meth->dso_bind_func == NULL)
+		{
+		DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_UNSUPPORTED);
+		return(NULL);
+		}
+	if((ret = dso->meth->dso_bind_func(dso, symname)) == NULL)
+		{
+		DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_SYM_FAILURE);
+		return(NULL);
+		}
+	/* Success */
+	return(ret);
+	}
+
+/* I don't really like these *_ctrl functions very much to be perfectly
+ * honest. For one thing, I think I have to return a negative value for
+ * any error because possible DSO_ctrl() commands may return values
+ * such as "size"s that can legitimately be zero (making the standard
+ * "if(DSO_cmd(...))" form that works almost everywhere else fail at
+ * odd times. I'd prefer "output" values to be passed by reference and
+ * the return value as success/failure like usual ... but we conform
+ * when we must... :-) */
+long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg)
+	{
+	if(dso == NULL)
+		{
+		DSOerr(DSO_F_DSO_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+		return(-1);
+		}
+	/* We should intercept certain generic commands and only pass control
+	 * to the method-specific ctrl() function if it's something we don't
+	 * handle. */
+	switch(cmd)
+		{
+	case DSO_CTRL_GET_FLAGS:
+		return dso->flags;
+	case DSO_CTRL_SET_FLAGS:
+		dso->flags = (int)larg;
+		return(0);
+	case DSO_CTRL_OR_FLAGS:
+		dso->flags |= (int)larg;
+		return(0);
+	default:
+		break;
+		}
+	if((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL))
+		{
+		DSOerr(DSO_F_DSO_CTRL,DSO_R_UNSUPPORTED);
+		return(-1);
+		}
+	return(dso->meth->dso_ctrl(dso,cmd,larg,parg));
+	}
+
+int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb,
+			DSO_NAME_CONVERTER_FUNC *oldcb)
+	{
+	if(dso == NULL)
+		{
+		DSOerr(DSO_F_DSO_SET_NAME_CONVERTER,
+				ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	if(oldcb)
+		*oldcb = dso->name_converter;
+	dso->name_converter = cb;
+	return(1);
+	}
+
+const char *DSO_get_filename(DSO *dso)
+	{
+	if(dso == NULL)
+		{
+		DSOerr(DSO_F_DSO_GET_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	return(dso->filename);
+	}
+
+int DSO_set_filename(DSO *dso, const char *filename)
+	{
+	char *copied;
+
+	if((dso == NULL) || (filename == NULL))
+		{
+		DSOerr(DSO_F_DSO_SET_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	if(dso->loaded_filename)
+		{
+		DSOerr(DSO_F_DSO_SET_FILENAME,DSO_R_DSO_ALREADY_LOADED);
+		return(0);
+		}
+	/* We'll duplicate filename */
+	copied = OPENSSL_malloc(strlen(filename) + 1);
+	if(copied == NULL)
+		{
+		DSOerr(DSO_F_DSO_SET_FILENAME,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	BUF_strlcpy(copied, filename, strlen(filename) + 1);
+	if(dso->filename)
+		OPENSSL_free(dso->filename);
+	dso->filename = copied;
+	return(1);
+	}
+
+char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2)
+	{
+	char *result = NULL;
+
+	if(dso == NULL || filespec1 == NULL)
+		{
+		DSOerr(DSO_F_DSO_MERGE,ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	if((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0)
+		{
+		if(dso->merger != NULL)
+			result = dso->merger(dso, filespec1, filespec2);
+		else if(dso->meth->dso_merger != NULL)
+			result = dso->meth->dso_merger(dso,
+				filespec1, filespec2);
+		}
+	return(result);
+	}
+
+char *DSO_convert_filename(DSO *dso, const char *filename)
+	{
+	char *result = NULL;
+
+	if(dso == NULL)
+		{
+		DSOerr(DSO_F_DSO_CONVERT_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	if(filename == NULL)
+		filename = dso->filename;
+	if(filename == NULL)
+		{
+		DSOerr(DSO_F_DSO_CONVERT_FILENAME,DSO_R_NO_FILENAME);
+		return(NULL);
+		}
+	if((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0)
+		{
+		if(dso->name_converter != NULL)
+			result = dso->name_converter(dso, filename);
+		else if(dso->meth->dso_name_converter != NULL)
+			result = dso->meth->dso_name_converter(dso, filename);
+		}
+	if(result == NULL)
+		{
+		result = OPENSSL_malloc(strlen(filename) + 1);
+		if(result == NULL)
+			{
+			DSOerr(DSO_F_DSO_CONVERT_FILENAME,
+					ERR_R_MALLOC_FAILURE);
+			return(NULL);
+			}
+		BUF_strlcpy(result, filename, strlen(filename) + 1);
+		}
+	return(result);
+	}
+
+const char *DSO_get_loaded_filename(DSO *dso)
+	{
+	if(dso == NULL)
+		{
+		DSOerr(DSO_F_DSO_GET_LOADED_FILENAME,
+				ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	return(dso->loaded_filename);
+	}
+
+int DSO_pathbyaddr(void *addr,char *path,int sz)
+	{
+	DSO_METHOD *meth = default_DSO_meth;
+	if (meth == NULL) meth = DSO_METHOD_openssl();
+	if (meth->pathbyaddr == NULL)
+		{
+		DSOerr(DSO_F_DSO_PATHBYADDR,DSO_R_UNSUPPORTED);
+		return -1;
+		}
+	return (*meth->pathbyaddr)(addr,path,sz);
+	}
+
+void *DSO_global_lookup(const char *name)
+	{
+	DSO_METHOD *meth = default_DSO_meth;
+	if (meth == NULL) meth = DSO_METHOD_openssl();
+	if (meth->globallookup == NULL)
+		{
+		DSOerr(DSO_F_DSO_GLOBAL_LOOKUP,DSO_R_UNSUPPORTED);
+		return NULL;
+		}
+	return (*meth->globallookup)(name);
+	}
diff --git a/openssl/crypto/dso/dso_null.c b/openssl/crypto/dso/dso_null.c
new file mode 100644
index 0000000..49d842d
--- /dev/null
+++ b/openssl/crypto/dso/dso_null.c
@@ -0,0 +1,90 @@
+/* dso_null.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* This "NULL" method is provided as the fallback for systems that have
+ * no appropriate support for "shared-libraries". */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+
+static DSO_METHOD dso_meth_null = {
+	"NULL shared library method",
+	NULL, /* load */
+	NULL, /* unload */
+	NULL, /* bind_var */
+	NULL, /* bind_func */
+/* For now, "unbind" doesn't exist */
+#if 0
+	NULL, /* unbind_var */
+	NULL, /* unbind_func */
+#endif
+	NULL, /* ctrl */
+	NULL, /* dso_name_converter */
+	NULL, /* dso_merger */
+	NULL, /* init */
+	NULL, /* finish */
+	NULL, /* pathbyaddr */
+	NULL  /* globallookup */
+	};
+
+DSO_METHOD *DSO_METHOD_null(void)
+	{
+	return(&dso_meth_null);
+	}
+
diff --git a/openssl/crypto/dso/dso_openssl.c b/openssl/crypto/dso/dso_openssl.c
new file mode 100644
index 0000000..b17e8e8
--- /dev/null
+++ b/openssl/crypto/dso/dso_openssl.c
@@ -0,0 +1,83 @@
+/* dso_openssl.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+
+/* We just pinch the method from an appropriate "default" method. */
+
+DSO_METHOD *DSO_METHOD_openssl(void)
+	{
+#ifdef DEF_DSO_METHOD
+	return(DEF_DSO_METHOD());
+#elif defined(DSO_DLFCN)
+	return(DSO_METHOD_dlfcn());
+#elif defined(DSO_DL)
+	return(DSO_METHOD_dl());
+#elif defined(DSO_WIN32)
+	return(DSO_METHOD_win32());
+#elif defined(DSO_VMS)
+	return(DSO_METHOD_vms());
+#elif defined(DSO_BEOS)
+	return(DSO_METHOD_beos());
+#else
+	return(DSO_METHOD_null());
+#endif
+	}
+
diff --git a/openssl/crypto/dso/dso_vms.c b/openssl/crypto/dso/dso_vms.c
new file mode 100644
index 0000000..eee20d1
--- /dev/null
+++ b/openssl/crypto/dso/dso_vms.c
@@ -0,0 +1,525 @@
+/* dso_vms.c -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+#ifdef OPENSSL_SYS_VMS
+#pragma message disable DOLLARID
+#include <rms.h>
+#include <lib$routines.h>
+#include <stsdef.h>
+#include <descrip.h>
+#include <starlet.h>
+#include "vms_rms.h"
+#endif
+
+/* Some compiler options may mask the declaration of "_malloc32". */
+#if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE
+# if __INITIAL_POINTER_SIZE == 64
+#  pragma pointer_size save
+#  pragma pointer_size 32
+    void * _malloc32  (__size_t);
+#  pragma pointer_size restore
+# endif /* __INITIAL_POINTER_SIZE == 64 */
+#endif /* __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE */
+
+
+#ifndef OPENSSL_SYS_VMS
+DSO_METHOD *DSO_METHOD_vms(void)
+	{
+	return NULL;
+	}
+#else
+#pragma message disable DOLLARID
+
+static int vms_load(DSO *dso);
+static int vms_unload(DSO *dso);
+static void *vms_bind_var(DSO *dso, const char *symname);
+static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname);
+#if 0
+static int vms_unbind_var(DSO *dso, char *symname, void *symptr);
+static int vms_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
+static int vms_init(DSO *dso);
+static int vms_finish(DSO *dso);
+static long vms_ctrl(DSO *dso, int cmd, long larg, void *parg);
+#endif
+static char *vms_name_converter(DSO *dso, const char *filename);
+static char *vms_merger(DSO *dso, const char *filespec1,
+	const char *filespec2);
+
+static DSO_METHOD dso_meth_vms = {
+	"OpenSSL 'VMS' shared library method",
+	vms_load,
+	NULL, /* unload */
+	vms_bind_var,
+	vms_bind_func,
+/* For now, "unbind" doesn't exist */
+#if 0
+	NULL, /* unbind_var */
+	NULL, /* unbind_func */
+#endif
+	NULL, /* ctrl */
+	vms_name_converter,
+	vms_merger,
+	NULL, /* init */
+	NULL  /* finish */
+	};
+
+/* On VMS, the only "handle" is the file name.  LIB$FIND_IMAGE_SYMBOL depends
+ * on the reference to the file name being the same for all calls regarding
+ * one shared image, so we'll just store it in an instance of the following
+ * structure and put a pointer to that instance in the meth_data stack.
+ */
+typedef struct dso_internal_st
+	{
+	/* This should contain the name only, no directory,
+	 * no extension, nothing but a name. */
+	struct dsc$descriptor_s filename_dsc;
+	char filename[ NAMX_MAXRSS+ 1];
+	/* This contains whatever is not in filename, if needed.
+	 * Normally not defined. */
+	struct dsc$descriptor_s imagename_dsc;
+	char imagename[ NAMX_MAXRSS+ 1];
+	} DSO_VMS_INTERNAL;
+
+DSO_METHOD *DSO_METHOD_vms(void)
+	{
+	return(&dso_meth_vms);
+	}
+
+static int vms_load(DSO *dso)
+	{
+	void *ptr = NULL;
+	/* See applicable comments in dso_dl.c */
+	char *filename = DSO_convert_filename(dso, NULL);
+
+/* Ensure 32-bit pointer for "p", and appropriate malloc() function. */
+#if __INITIAL_POINTER_SIZE == 64
+# define DSO_MALLOC _malloc32
+# pragma pointer_size save
+# pragma pointer_size 32
+#else /* __INITIAL_POINTER_SIZE == 64 */
+# define DSO_MALLOC OPENSSL_malloc
+#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+	DSO_VMS_INTERNAL *p = NULL;
+
+#if __INITIAL_POINTER_SIZE == 64
+# pragma pointer_size restore
+#endif /* __INITIAL_POINTER_SIZE == 64 */
+
+	const char *sp1, *sp2;	/* Search result */
+
+	if(filename == NULL)
+		{
+		DSOerr(DSO_F_VMS_LOAD,DSO_R_NO_FILENAME);
+		goto err;
+		}
+
+	/* A file specification may look like this:
+	 *
+	 *	node::dev:[dir-spec]name.type;ver
+	 *
+	 * or (for compatibility with TOPS-20):
+	 *
+	 *	node::dev:<dir-spec>name.type;ver
+	 *
+	 * and the dir-spec uses '.' as separator.  Also, a dir-spec
+	 * may consist of several parts, with mixed use of [] and <>:
+	 *
+	 *	[dir1.]<dir2>
+	 *
+	 * We need to split the file specification into the name and
+	 * the rest (both before and after the name itself).
+	 */
+	/* Start with trying to find the end of a dir-spec, and save the
+	   position of the byte after in sp1 */
+	sp1 = strrchr(filename, ']');
+	sp2 = strrchr(filename, '>');
+	if (sp1 == NULL) sp1 = sp2;
+	if (sp2 != NULL && sp2 > sp1) sp1 = sp2;
+	if (sp1 == NULL) sp1 = strrchr(filename, ':');
+	if (sp1 == NULL)
+		sp1 = filename;
+	else
+		sp1++;		/* The byte after the found character */
+	/* Now, let's see if there's a type, and save the position in sp2 */
+	sp2 = strchr(sp1, '.');
+	/* If we found it, that's where we'll cut.  Otherwise, look for a
+	   version number and save the position in sp2 */
+	if (sp2 == NULL) sp2 = strchr(sp1, ';');
+	/* If there was still nothing to find, set sp2 to point at the end of
+	   the string */
+	if (sp2 == NULL) sp2 = sp1 + strlen(sp1);
+
+	/* Check that we won't get buffer overflows */
+	if (sp2 - sp1 > FILENAME_MAX
+		|| (sp1 - filename) + strlen(sp2) > FILENAME_MAX)
+		{
+		DSOerr(DSO_F_VMS_LOAD,DSO_R_FILENAME_TOO_BIG);
+		goto err;
+		}
+
+	p = DSO_MALLOC(sizeof(DSO_VMS_INTERNAL));
+	if(p == NULL)
+		{
+		DSOerr(DSO_F_VMS_LOAD,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	strncpy(p->filename, sp1, sp2-sp1);
+	p->filename[sp2-sp1] = '\0';
+
+	strncpy(p->imagename, filename, sp1-filename);
+	p->imagename[sp1-filename] = '\0';
+	strcat(p->imagename, sp2);
+
+	p->filename_dsc.dsc$w_length = strlen(p->filename);
+	p->filename_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+	p->filename_dsc.dsc$b_class = DSC$K_CLASS_S;
+	p->filename_dsc.dsc$a_pointer = p->filename;
+	p->imagename_dsc.dsc$w_length = strlen(p->imagename);
+	p->imagename_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+	p->imagename_dsc.dsc$b_class = DSC$K_CLASS_S;
+	p->imagename_dsc.dsc$a_pointer = p->imagename;
+
+	if(!sk_void_push(dso->meth_data, (char *)p))
+		{
+		DSOerr(DSO_F_VMS_LOAD,DSO_R_STACK_ERROR);
+		goto err;
+		}
+
+	/* Success (for now, we lie.  We actually do not know...) */
+	dso->loaded_filename = filename;
+	return(1);
+err:
+	/* Cleanup! */
+	if(p != NULL)
+		OPENSSL_free(p);
+	if(filename != NULL)
+		OPENSSL_free(filename);
+	return(0);
+	}
+
+/* Note that this doesn't actually unload the shared image, as there is no
+ * such thing in VMS.  Next time it get loaded again, a new copy will
+ * actually be loaded.
+ */
+static int vms_unload(DSO *dso)
+	{
+	DSO_VMS_INTERNAL *p;
+	if(dso == NULL)
+		{
+		DSOerr(DSO_F_VMS_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	if(sk_void_num(dso->meth_data) < 1)
+		return(1);
+	p = (DSO_VMS_INTERNAL *)sk_void_pop(dso->meth_data);
+	if(p == NULL)
+		{
+		DSOerr(DSO_F_VMS_UNLOAD,DSO_R_NULL_HANDLE);
+		return(0);
+		}
+	/* Cleanup */
+	OPENSSL_free(p);
+	return(1);
+	}
+
+/* We must do this in a separate function because of the way the exception
+   handler works (it makes this function return */
+static int do_find_symbol(DSO_VMS_INTERNAL *ptr,
+	struct dsc$descriptor_s *symname_dsc, void **sym,
+	unsigned long flags)
+	{
+	/* Make sure that signals are caught and returned instead of
+	   aborting the program.  The exception handler gets unestablished
+	   automatically on return from this function.  */
+	lib$establish(lib$sig_to_ret);
+
+	if(ptr->imagename_dsc.dsc$w_length)
+		return lib$find_image_symbol(&ptr->filename_dsc,
+			symname_dsc, sym,
+			&ptr->imagename_dsc, flags);
+	else
+		return lib$find_image_symbol(&ptr->filename_dsc,
+			symname_dsc, sym,
+			0, flags);
+	}
+
+void vms_bind_sym(DSO *dso, const char *symname, void **sym)
+	{
+	DSO_VMS_INTERNAL *ptr;
+	int status;
+#if 0
+	int flags = (1<<4); /* LIB$M_FIS_MIXEDCASE, but this symbol isn't
+                               defined in VMS older than 7.0 or so */
+#else
+	int flags = 0;
+#endif
+	struct dsc$descriptor_s symname_dsc;
+
+/* Arrange 32-bit pointer to (copied) string storage, if needed. */
+#if __INITIAL_POINTER_SIZE == 64
+# define SYMNAME symname_32p
+# pragma pointer_size save
+# pragma pointer_size 32
+	char *symname_32p;
+# pragma pointer_size restore
+	char symname_32[ NAMX_MAXRSS+ 1];
+#else /* __INITIAL_POINTER_SIZE == 64 */
+# define SYMNAME ((char *) symname)
+#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+	*sym = NULL;
+
+	if((dso == NULL) || (symname == NULL))
+		{
+		DSOerr(DSO_F_VMS_BIND_SYM,ERR_R_PASSED_NULL_PARAMETER);
+		return;
+		}
+
+#if __INITIAL_POINTER_SIZE == 64
+	/* Copy the symbol name to storage with a 32-bit pointer. */
+	symname_32p = symname_32;
+	strcpy( symname_32p, symname);
+#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+	symname_dsc.dsc$w_length = strlen(SYMNAME);
+	symname_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+	symname_dsc.dsc$b_class = DSC$K_CLASS_S;
+	symname_dsc.dsc$a_pointer = SYMNAME;
+
+	if(sk_void_num(dso->meth_data) < 1)
+		{
+		DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_STACK_ERROR);
+		return;
+		}
+	ptr = (DSO_VMS_INTERNAL *)sk_void_value(dso->meth_data,
+		sk_void_num(dso->meth_data) - 1);
+	if(ptr == NULL)
+		{
+		DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_NULL_HANDLE);
+		return;
+		}
+
+	if(dso->flags & DSO_FLAG_UPCASE_SYMBOL) flags = 0;
+
+	status = do_find_symbol(ptr, &symname_dsc, sym, flags);
+
+	if(!$VMS_STATUS_SUCCESS(status))
+		{
+		unsigned short length;
+		char errstring[257];
+		struct dsc$descriptor_s errstring_dsc;
+
+		errstring_dsc.dsc$w_length = sizeof(errstring);
+		errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+		errstring_dsc.dsc$b_class = DSC$K_CLASS_S;
+		errstring_dsc.dsc$a_pointer = errstring;
+
+		*sym = NULL;
+
+		status = sys$getmsg(status, &length, &errstring_dsc, 1, 0);
+
+		if (!$VMS_STATUS_SUCCESS(status))
+			lib$signal(status); /* This is really bad.  Abort!  */
+		else
+			{
+			errstring[length] = '\0';
+
+			DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_SYM_FAILURE);
+			if (ptr->imagename_dsc.dsc$w_length)
+				ERR_add_error_data(9,
+					"Symbol ", symname,
+					" in ", ptr->filename,
+					" (", ptr->imagename, ")",
+					": ", errstring);
+			else
+				ERR_add_error_data(6,
+					"Symbol ", symname,
+					" in ", ptr->filename,
+					": ", errstring);
+			}
+		return;
+		}
+	return;
+	}
+
+static void *vms_bind_var(DSO *dso, const char *symname)
+	{
+	void *sym = 0;
+	vms_bind_sym(dso, symname, &sym);
+	return sym;
+	}
+
+static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname)
+	{
+	DSO_FUNC_TYPE sym = 0;
+	vms_bind_sym(dso, symname, (void **)&sym);
+	return sym;
+	}
+
+
+static char *vms_merger(DSO *dso, const char *filespec1, const char *filespec2)
+	{
+	int status;
+	int filespec1len, filespec2len;
+	struct FAB fab;
+	struct NAMX_STRUCT nam;
+	char esa[ NAMX_MAXRSS+ 1];
+	char *merged;
+
+/* Arrange 32-bit pointer to (copied) string storage, if needed. */
+#if __INITIAL_POINTER_SIZE == 64
+# define FILESPEC1 filespec1_32p;
+# define FILESPEC2 filespec2_32p;
+# pragma pointer_size save
+# pragma pointer_size 32
+	char *filespec1_32p;
+	char *filespec2_32p;
+# pragma pointer_size restore
+	char filespec1_32[ NAMX_MAXRSS+ 1];
+	char filespec2_32[ NAMX_MAXRSS+ 1];
+#else /* __INITIAL_POINTER_SIZE == 64 */
+# define FILESPEC1 ((char *) filespec1)
+# define FILESPEC2 ((char *) filespec2)
+#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+	if (!filespec1) filespec1 = "";
+	if (!filespec2) filespec2 = "";
+	filespec1len = strlen(filespec1);
+	filespec2len = strlen(filespec2);
+
+#if __INITIAL_POINTER_SIZE == 64
+	/* Copy the file names to storage with a 32-bit pointer. */
+	filespec1_32p = filespec1_32;
+	filespec2_32p = filespec2_32;
+	strcpy( filespec1_32p, filespec1);
+	strcpy( filespec2_32p, filespec2);
+#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+	fab = cc$rms_fab;
+	nam = CC_RMS_NAMX;
+
+	FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNA = FILESPEC1;
+	FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNS = filespec1len;
+	FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNA = FILESPEC2;
+	FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNS = filespec2len;
+	NAMX_DNA_FNA_SET( fab)
+
+	nam.NAMX_ESA = esa;
+	nam.NAMX_ESS = NAMX_MAXRSS;
+	nam.NAMX_NOP = NAM$M_SYNCHK | NAM$M_PWD;
+	SET_NAMX_NO_SHORT_UPCASE( nam);
+
+	fab.FAB_NAMX = &nam;
+
+	status = sys$parse(&fab, 0, 0);
+
+	if(!$VMS_STATUS_SUCCESS(status))
+		{
+		unsigned short length;
+		char errstring[257];
+		struct dsc$descriptor_s errstring_dsc;
+
+		errstring_dsc.dsc$w_length = sizeof(errstring);
+		errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+		errstring_dsc.dsc$b_class = DSC$K_CLASS_S;
+		errstring_dsc.dsc$a_pointer = errstring;
+
+		status = sys$getmsg(status, &length, &errstring_dsc, 1, 0);
+
+		if (!$VMS_STATUS_SUCCESS(status))
+			lib$signal(status); /* This is really bad.  Abort!  */
+		else
+			{
+			errstring[length] = '\0';
+
+			DSOerr(DSO_F_VMS_MERGER,DSO_R_FAILURE);
+			ERR_add_error_data(7,
+					   "filespec \"", filespec1, "\", ",
+					   "defaults \"", filespec2, "\": ",
+					   errstring);
+			}
+		return(NULL);
+		}
+
+	merged = OPENSSL_malloc( nam.NAMX_ESL+ 1);
+	if(!merged)
+		goto malloc_err;
+	strncpy( merged, nam.NAMX_ESA, nam.NAMX_ESL);
+	merged[ nam.NAMX_ESL] = '\0';
+	return(merged);
+ malloc_err:
+	DSOerr(DSO_F_VMS_MERGER,
+		ERR_R_MALLOC_FAILURE);
+	}
+
+static char *vms_name_converter(DSO *dso, const char *filename)
+	{
+        int len = strlen(filename);
+        char *not_translated = OPENSSL_malloc(len+1);
+        strcpy(not_translated,filename);
+	return(not_translated);
+	}
+
+#endif /* OPENSSL_SYS_VMS */
diff --git a/openssl/crypto/dso/dso_win32.c b/openssl/crypto/dso/dso_win32.c
new file mode 100644
index 0000000..6fb6c54
--- /dev/null
+++ b/openssl/crypto/dso/dso_win32.c
@@ -0,0 +1,844 @@
+/* dso_win32.c -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+
+#if !defined(DSO_WIN32)
+DSO_METHOD *DSO_METHOD_win32(void)
+	{
+	return NULL;
+	}
+#else
+
+#ifdef _WIN32_WCE
+# if _WIN32_WCE < 300
+static FARPROC GetProcAddressA(HMODULE hModule,LPCSTR lpProcName)
+	{
+	WCHAR lpProcNameW[64];
+	int i;
+
+	for (i=0;lpProcName[i] && i<64;i++)
+		lpProcNameW[i] = (WCHAR)lpProcName[i];
+	if (i==64) return NULL;
+	lpProcNameW[i] = 0;
+
+	return GetProcAddressW(hModule,lpProcNameW);
+	}
+# endif
+# undef GetProcAddress
+# define GetProcAddress GetProcAddressA
+
+static HINSTANCE LoadLibraryA(LPCSTR lpLibFileName)
+	{
+	WCHAR *fnamw;
+	size_t len_0=strlen(lpLibFileName)+1,i;
+
+#ifdef _MSC_VER
+	fnamw = (WCHAR *)_alloca (len_0*sizeof(WCHAR));
+#else
+	fnamw = (WCHAR *)alloca (len_0*sizeof(WCHAR));
+#endif
+	if (fnamw == NULL)
+		{
+		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+		return NULL;
+		}
+
+#if defined(_WIN32_WCE) && _WIN32_WCE>=101
+	if (!MultiByteToWideChar(CP_ACP,0,lpLibFileName,len_0,fnamw,len_0))
+#endif
+		for (i=0;i<len_0;i++) fnamw[i]=(WCHAR)lpLibFileName[i];
+
+	return LoadLibraryW(fnamw);
+	}
+#endif
+
+/* Part of the hack in "win32_load" ... */
+#define DSO_MAX_TRANSLATED_SIZE 256
+
+static int win32_load(DSO *dso);
+static int win32_unload(DSO *dso);
+static void *win32_bind_var(DSO *dso, const char *symname);
+static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname);
+#if 0
+static int win32_unbind_var(DSO *dso, char *symname, void *symptr);
+static int win32_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
+static int win32_init(DSO *dso);
+static int win32_finish(DSO *dso);
+static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg);
+#endif
+static char *win32_name_converter(DSO *dso, const char *filename);
+static char *win32_merger(DSO *dso, const char *filespec1,
+	const char *filespec2);
+static int win32_pathbyaddr(void *addr,char *path,int sz);
+static void *win32_globallookup(const char *name);
+
+static const char *openssl_strnchr(const char *string, int c, size_t len);
+
+static DSO_METHOD dso_meth_win32 = {
+	"OpenSSL 'win32' shared library method",
+	win32_load,
+	win32_unload,
+	win32_bind_var,
+	win32_bind_func,
+/* For now, "unbind" doesn't exist */
+#if 0
+	NULL, /* unbind_var */
+	NULL, /* unbind_func */
+#endif
+	NULL, /* ctrl */
+	win32_name_converter,
+	win32_merger,
+	NULL, /* init */
+	NULL, /* finish */
+	win32_pathbyaddr,
+	win32_globallookup
+	};
+
+DSO_METHOD *DSO_METHOD_win32(void)
+	{
+	return(&dso_meth_win32);
+	}
+
+/* For this DSO_METHOD, our meth_data STACK will contain;
+ * (i) a pointer to the handle (HINSTANCE) returned from
+ *     LoadLibrary(), and copied.
+ */
+
+static int win32_load(DSO *dso)
+	{
+	HINSTANCE h = NULL, *p = NULL;
+	/* See applicable comments from dso_dl.c */
+	char *filename = DSO_convert_filename(dso, NULL);
+
+	if(filename == NULL)
+		{
+		DSOerr(DSO_F_WIN32_LOAD,DSO_R_NO_FILENAME);
+		goto err;
+		}
+	h = LoadLibraryA(filename);
+	if(h == NULL)
+		{
+		DSOerr(DSO_F_WIN32_LOAD,DSO_R_LOAD_FAILED);
+		ERR_add_error_data(3, "filename(", filename, ")");
+		goto err;
+		}
+	p = (HINSTANCE *)OPENSSL_malloc(sizeof(HINSTANCE));
+	if(p == NULL)
+		{
+		DSOerr(DSO_F_WIN32_LOAD,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	*p = h;
+	if(!sk_void_push(dso->meth_data, p))
+		{
+		DSOerr(DSO_F_WIN32_LOAD,DSO_R_STACK_ERROR);
+		goto err;
+		}
+	/* Success */
+	dso->loaded_filename = filename;
+	return(1);
+err:
+	/* Cleanup !*/
+	if(filename != NULL)
+		OPENSSL_free(filename);
+	if(p != NULL)
+		OPENSSL_free(p);
+	if(h != NULL)
+		FreeLibrary(h);
+	return(0);
+	}
+
+static int win32_unload(DSO *dso)
+	{
+	HINSTANCE *p;
+	if(dso == NULL)
+		{
+		DSOerr(DSO_F_WIN32_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	if(sk_void_num(dso->meth_data) < 1)
+		return(1);
+	p = sk_void_pop(dso->meth_data);
+	if(p == NULL)
+		{
+		DSOerr(DSO_F_WIN32_UNLOAD,DSO_R_NULL_HANDLE);
+		return(0);
+		}
+	if(!FreeLibrary(*p))
+		{
+		DSOerr(DSO_F_WIN32_UNLOAD,DSO_R_UNLOAD_FAILED);
+		/* We should push the value back onto the stack in
+		 * case of a retry. */
+		sk_void_push(dso->meth_data, p);
+		return(0);
+		}
+	/* Cleanup */
+	OPENSSL_free(p);
+	return(1);
+	}
+
+/* Using GetProcAddress for variables? TODO: Check this out in
+ * the Win32 API docs, there's probably a variant for variables. */
+static void *win32_bind_var(DSO *dso, const char *symname)
+	{
+	HINSTANCE *ptr;
+	void *sym;
+
+	if((dso == NULL) || (symname == NULL))
+		{
+		DSOerr(DSO_F_WIN32_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	if(sk_void_num(dso->meth_data) < 1)
+		{
+		DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_STACK_ERROR);
+		return(NULL);
+		}
+	ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
+	if(ptr == NULL)
+		{
+		DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_NULL_HANDLE);
+		return(NULL);
+		}
+	sym = GetProcAddress(*ptr, symname);
+	if(sym == NULL)
+		{
+		DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_SYM_FAILURE);
+		ERR_add_error_data(3, "symname(", symname, ")");
+		return(NULL);
+		}
+	return(sym);
+	}
+
+static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname)
+	{
+	HINSTANCE *ptr;
+	void *sym;
+
+	if((dso == NULL) || (symname == NULL))
+		{
+		DSOerr(DSO_F_WIN32_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	if(sk_void_num(dso->meth_data) < 1)
+		{
+		DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_STACK_ERROR);
+		return(NULL);
+		}
+	ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
+	if(ptr == NULL)
+		{
+		DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_NULL_HANDLE);
+		return(NULL);
+		}
+	sym = GetProcAddress(*ptr, symname);
+	if(sym == NULL)
+		{
+		DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_SYM_FAILURE);
+		ERR_add_error_data(3, "symname(", symname, ")");
+		return(NULL);
+		}
+	return((DSO_FUNC_TYPE)sym);
+	}
+
+struct file_st
+	{
+	const char *node; int nodelen;
+	const char *device; int devicelen;
+	const char *predir; int predirlen;
+	const char *dir; int dirlen;
+	const char *file; int filelen;
+	};
+
+static struct file_st *win32_splitter(DSO *dso, const char *filename,
+	int assume_last_is_dir)
+	{
+	struct file_st *result = NULL;
+	enum { IN_NODE, IN_DEVICE, IN_FILE } position;
+	const char *start = filename;
+	char last;
+
+	if (!filename)
+		{
+		DSOerr(DSO_F_WIN32_SPLITTER,DSO_R_NO_FILENAME);
+		/*goto err;*/
+		return(NULL);
+		}
+
+	result = OPENSSL_malloc(sizeof(struct file_st));
+	if(result == NULL)
+		{
+		DSOerr(DSO_F_WIN32_SPLITTER,
+			ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+
+	memset(result, 0, sizeof(struct file_st));
+	position = IN_DEVICE;
+
+	if((filename[0] == '\\' && filename[1] == '\\')
+		|| (filename[0] == '/' && filename[1] == '/'))
+		{
+		position = IN_NODE;
+		filename += 2;
+		start = filename;
+		result->node = start;
+		}
+
+	do
+		{
+		last = filename[0];
+		switch(last)
+			{
+		case ':':
+			if(position != IN_DEVICE)
+				{
+				DSOerr(DSO_F_WIN32_SPLITTER,
+					DSO_R_INCORRECT_FILE_SYNTAX);
+				/*goto err;*/
+				OPENSSL_free(result);
+				return(NULL);
+				}
+			result->device = start;
+			result->devicelen = (int)(filename - start);
+			position = IN_FILE;
+			start = ++filename;
+			result->dir = start;
+			break;
+		case '\\':
+		case '/':
+			if(position == IN_NODE)
+				{
+				result->nodelen = (int)(filename - start);
+				position = IN_FILE;
+				start = ++filename;
+				result->dir = start;
+				}
+			else if(position == IN_DEVICE)
+				{
+				position = IN_FILE;
+				filename++;
+				result->dir = start;
+				result->dirlen = (int)(filename - start);
+				start = filename;
+				}
+			else
+				{
+				filename++;
+				result->dirlen += (int)(filename - start);
+				start = filename;
+				}
+			break;
+		case '\0':
+			if(position == IN_NODE)
+				{
+				result->nodelen = (int)(filename - start);
+				}
+			else
+				{
+				if(filename - start > 0)
+					{
+					if (assume_last_is_dir)
+						{
+						if (position == IN_DEVICE)
+							{
+							result->dir = start;
+							result->dirlen = 0;
+							}
+						result->dirlen +=
+							(int)(filename - start);
+						}
+					else
+						{
+						result->file = start;
+						result->filelen =
+							(int)(filename - start);
+						}
+					}
+				}
+			break;
+		default:
+			filename++;
+			break;
+			}
+		}
+	while(last);
+
+	if(!result->nodelen) result->node = NULL;
+	if(!result->devicelen) result->device = NULL;
+	if(!result->dirlen) result->dir = NULL;
+	if(!result->filelen) result->file = NULL;
+
+	return(result);
+	}
+
+static char *win32_joiner(DSO *dso, const struct file_st *file_split)
+	{
+	int len = 0, offset = 0;
+	char *result = NULL;
+	const char *start;
+
+	if(!file_split)
+		{
+		DSOerr(DSO_F_WIN32_JOINER,
+				ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	if(file_split->node)
+		{
+		len += 2 + file_split->nodelen;	/* 2 for starting \\ */
+		if(file_split->predir || file_split->dir || file_split->file)
+			len++;	/* 1 for ending \ */
+		}
+	else if(file_split->device)
+		{
+		len += file_split->devicelen + 1; /* 1 for ending : */
+		}
+	len += file_split->predirlen;
+	if(file_split->predir && (file_split->dir || file_split->file))
+		{
+		len++;	/* 1 for ending \ */
+		}
+	len += file_split->dirlen;
+	if(file_split->dir && file_split->file)
+		{
+		len++;	/* 1 for ending \ */
+		}
+	len += file_split->filelen;
+
+	if(!len)
+		{
+		DSOerr(DSO_F_WIN32_JOINER, DSO_R_EMPTY_FILE_STRUCTURE);
+		return(NULL);
+		}
+
+	result = OPENSSL_malloc(len + 1);
+	if (!result)
+		{
+		DSOerr(DSO_F_WIN32_JOINER,
+			ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+
+	if(file_split->node)
+		{
+		strcpy(&result[offset], "\\\\"); offset += 2;
+		strncpy(&result[offset], file_split->node,
+			file_split->nodelen); offset += file_split->nodelen;
+		if(file_split->predir || file_split->dir || file_split->file)
+			{
+			result[offset] = '\\'; offset++;
+			}
+		}
+	else if(file_split->device)
+		{
+		strncpy(&result[offset], file_split->device,
+			file_split->devicelen); offset += file_split->devicelen;
+		result[offset] = ':'; offset++;
+		}
+	start = file_split->predir;
+	while(file_split->predirlen > (start - file_split->predir))
+		{
+		const char *end = openssl_strnchr(start, '/',
+			file_split->predirlen - (start - file_split->predir));
+		if(!end)
+			end = start
+				+ file_split->predirlen
+				- (start - file_split->predir);
+		strncpy(&result[offset], start,
+			end - start); offset += (int)(end - start);
+		result[offset] = '\\'; offset++;
+		start = end + 1;
+		}
+#if 0 /* Not needed, since the directory converter above already appeneded
+	 a backslash */
+	if(file_split->predir && (file_split->dir || file_split->file))
+		{
+		result[offset] = '\\'; offset++;
+		}
+#endif
+	start = file_split->dir;
+	while(file_split->dirlen > (start - file_split->dir))
+		{
+		const char *end = openssl_strnchr(start, '/',
+			file_split->dirlen - (start - file_split->dir));
+		if(!end)
+			end = start
+				+ file_split->dirlen
+				- (start - file_split->dir);
+		strncpy(&result[offset], start,
+			end - start); offset += (int)(end - start);
+		result[offset] = '\\'; offset++;
+		start = end + 1;
+		}
+#if 0 /* Not needed, since the directory converter above already appeneded
+	 a backslash */
+	if(file_split->dir && file_split->file)
+		{
+		result[offset] = '\\'; offset++;
+		}
+#endif
+	strncpy(&result[offset], file_split->file,
+		file_split->filelen); offset += file_split->filelen;
+	result[offset] = '\0';
+	return(result);
+	}
+
+static char *win32_merger(DSO *dso, const char *filespec1, const char *filespec2)
+	{
+	char *merged = NULL;
+	struct file_st *filespec1_split = NULL;
+	struct file_st *filespec2_split = NULL;
+
+	if(!filespec1 && !filespec2)
+		{
+		DSOerr(DSO_F_WIN32_MERGER,
+				ERR_R_PASSED_NULL_PARAMETER);
+		return(NULL);
+		}
+	if (!filespec2)
+		{
+		merged = OPENSSL_malloc(strlen(filespec1) + 1);
+		if(!merged)
+			{
+			DSOerr(DSO_F_WIN32_MERGER,
+				ERR_R_MALLOC_FAILURE);
+			return(NULL);
+			}
+		strcpy(merged, filespec1);
+		}
+	else if (!filespec1)
+		{
+		merged = OPENSSL_malloc(strlen(filespec2) + 1);
+		if(!merged)
+			{
+			DSOerr(DSO_F_WIN32_MERGER,
+				ERR_R_MALLOC_FAILURE);
+			return(NULL);
+			}
+		strcpy(merged, filespec2);
+		}
+	else
+		{
+		filespec1_split = win32_splitter(dso, filespec1, 0);
+		if (!filespec1_split)
+			{
+			DSOerr(DSO_F_WIN32_MERGER,
+				ERR_R_MALLOC_FAILURE);
+			return(NULL);
+			}
+		filespec2_split = win32_splitter(dso, filespec2, 1);
+		if (!filespec2_split)
+			{
+			DSOerr(DSO_F_WIN32_MERGER,
+				ERR_R_MALLOC_FAILURE);
+			OPENSSL_free(filespec1_split);
+			return(NULL);
+			}
+
+		/* Fill in into filespec1_split */
+		if (!filespec1_split->node && !filespec1_split->device)
+			{
+			filespec1_split->node = filespec2_split->node;
+			filespec1_split->nodelen = filespec2_split->nodelen;
+			filespec1_split->device = filespec2_split->device;
+			filespec1_split->devicelen = filespec2_split->devicelen;
+			}
+		if (!filespec1_split->dir)
+			{
+			filespec1_split->dir = filespec2_split->dir;
+			filespec1_split->dirlen = filespec2_split->dirlen;
+			}
+		else if (filespec1_split->dir[0] != '\\'
+			&& filespec1_split->dir[0] != '/')
+			{
+			filespec1_split->predir = filespec2_split->dir;
+			filespec1_split->predirlen = filespec2_split->dirlen;
+			}
+		if (!filespec1_split->file)
+			{
+			filespec1_split->file = filespec2_split->file;
+			filespec1_split->filelen = filespec2_split->filelen;
+			}
+
+		merged = win32_joiner(dso, filespec1_split);
+		}
+	OPENSSL_free(filespec1_split);
+	OPENSSL_free(filespec2_split);
+	return(merged);
+	}
+
+static char *win32_name_converter(DSO *dso, const char *filename)
+	{
+	char *translated;
+	int len, transform;
+
+	len = strlen(filename);
+	transform = ((strstr(filename, "/") == NULL) &&
+			(strstr(filename, "\\") == NULL) &&
+			(strstr(filename, ":") == NULL));
+	if(transform)
+		/* We will convert this to "%s.dll" */
+		translated = OPENSSL_malloc(len + 5);
+	else
+		/* We will simply duplicate filename */
+		translated = OPENSSL_malloc(len + 1);
+	if(translated == NULL)
+		{
+		DSOerr(DSO_F_WIN32_NAME_CONVERTER,
+				DSO_R_NAME_TRANSLATION_FAILED); 
+		return(NULL);   
+		}
+	if(transform)
+		sprintf(translated, "%s.dll", filename);
+	else
+		sprintf(translated, "%s", filename);
+	return(translated);
+	}
+
+static const char *openssl_strnchr(const char *string, int c, size_t len)
+	{
+	size_t i;
+	const char *p;
+	for (i = 0, p = string; i < len && *p; i++, p++)
+		{
+		if (*p == c)
+			return p;
+		}
+	return NULL;
+	}
+
+#include <tlhelp32.h>
+#ifdef _WIN32_WCE
+# define DLLNAME "TOOLHELP.DLL"
+#else
+# ifdef MODULEENTRY32
+# undef MODULEENTRY32	/* unmask the ASCII version! */
+# endif
+# define DLLNAME "KERNEL32.DLL"
+#endif
+
+typedef HANDLE (WINAPI *CREATETOOLHELP32SNAPSHOT)(DWORD, DWORD);
+typedef BOOL (WINAPI *CLOSETOOLHELP32SNAPSHOT)(HANDLE);
+typedef BOOL (WINAPI *MODULE32)(HANDLE, MODULEENTRY32 *);
+
+static int win32_pathbyaddr(void *addr,char *path,int sz)
+	{
+	HMODULE dll;
+	HANDLE hModuleSnap = INVALID_HANDLE_VALUE; 
+	MODULEENTRY32 me32; 
+	CREATETOOLHELP32SNAPSHOT create_snap;
+	CLOSETOOLHELP32SNAPSHOT  close_snap;
+	MODULE32 module_first, module_next;
+	int len;
+ 
+	if (addr == NULL)
+		{
+		union	{ int(*f)(void*,char*,int); void *p; } t =
+			{ win32_pathbyaddr };
+		addr = t.p;
+		}
+
+	dll = LoadLibrary(TEXT(DLLNAME));
+	if (dll == NULL)
+		{
+		DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED);
+		return -1;
+		}
+
+	create_snap = (CREATETOOLHELP32SNAPSHOT)
+		GetProcAddress(dll,"CreateToolhelp32Snapshot");
+	if (create_snap == NULL)
+		{
+		FreeLibrary(dll);
+		DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED);
+		return -1;
+		}
+	/* We take the rest for granted... */
+#ifdef _WIN32_WCE
+	close_snap = (CLOSETOOLHELP32SNAPSHOT)
+		GetProcAddress(dll,"CloseToolhelp32Snapshot");
+#else
+	close_snap = (CLOSETOOLHELP32SNAPSHOT)CloseHandle;
+#endif
+	module_first = (MODULE32)GetProcAddress(dll,"Module32First");
+	module_next  = (MODULE32)GetProcAddress(dll,"Module32Next");
+
+	hModuleSnap = (*create_snap)(TH32CS_SNAPMODULE,0); 
+	if( hModuleSnap == INVALID_HANDLE_VALUE ) 
+		{ 
+		FreeLibrary(dll);
+		DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED);
+		return -1;
+		} 
+ 
+	me32.dwSize = sizeof(me32); 
+ 
+	if(!(*module_first)(hModuleSnap,&me32)) 
+		{ 
+		(*close_snap)(hModuleSnap);
+		FreeLibrary(dll);
+		DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_FAILURE);
+		return -1;
+		}
+ 
+	do	{ 
+		if ((BYTE *)addr >= me32.modBaseAddr &&
+		    (BYTE *)addr <  me32.modBaseAddr+me32.modBaseSize)
+			{
+			(*close_snap)(hModuleSnap);
+			FreeLibrary(dll);
+#ifdef _WIN32_WCE
+# if _WIN32_WCE >= 101
+			return WideCharToMultiByte(CP_ACP,0,me32.szExePath,-1,
+							path,sz,NULL,NULL);
+# else
+			len = (int)wcslen(me32.szExePath);
+			if (sz <= 0) return len+1;
+			if (len >= sz) len=sz-1;
+			for(i=0;i<len;i++)
+				path[i] = (char)me32.szExePath[i];
+			path[len++] = 0;
+			return len;
+# endif
+#else
+			len = (int)strlen(me32.szExePath);
+			if (sz <= 0) return len+1;
+			if (len >= sz) len=sz-1;
+			memcpy(path,me32.szExePath,len);
+			path[len++] = 0;
+			return len;
+#endif
+			} 
+		} while((*module_next)(hModuleSnap, &me32)); 
+ 
+	(*close_snap)(hModuleSnap); 
+	FreeLibrary(dll);
+	return 0;
+	}
+
+static void *win32_globallookup(const char *name)
+	{
+	HMODULE dll;
+	HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
+	MODULEENTRY32 me32;
+	CREATETOOLHELP32SNAPSHOT create_snap;
+	CLOSETOOLHELP32SNAPSHOT  close_snap;
+	MODULE32 module_first, module_next;
+	FARPROC ret=NULL;
+
+	dll = LoadLibrary(TEXT(DLLNAME));
+	if (dll == NULL)
+		{
+		DSOerr(DSO_F_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED);
+		return NULL;
+		}
+
+	create_snap = (CREATETOOLHELP32SNAPSHOT)
+		GetProcAddress(dll,"CreateToolhelp32Snapshot");
+	if (create_snap == NULL)
+		{
+		FreeLibrary(dll);
+		DSOerr(DSO_F_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED);
+		return NULL;
+		}
+	/* We take the rest for granted... */
+#ifdef _WIN32_WCE
+	close_snap = (CLOSETOOLHELP32SNAPSHOT)
+		GetProcAddress(dll,"CloseToolhelp32Snapshot");
+#else
+	close_snap = (CLOSETOOLHELP32SNAPSHOT)CloseHandle;
+#endif
+	module_first = (MODULE32)GetProcAddress(dll,"Module32First");
+	module_next  = (MODULE32)GetProcAddress(dll,"Module32Next");
+
+	hModuleSnap = (*create_snap)(TH32CS_SNAPMODULE,0);
+	if( hModuleSnap == INVALID_HANDLE_VALUE )
+		{
+		FreeLibrary(dll);
+		DSOerr(DSO_F_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED);
+		return NULL;
+		}
+
+	me32.dwSize = sizeof(me32);
+
+	if (!(*module_first)(hModuleSnap,&me32))
+		{
+		(*close_snap)(hModuleSnap);
+		FreeLibrary(dll);
+		return NULL;
+		}
+
+	do	{
+		if ((ret = GetProcAddress(me32.hModule,name)))
+			{
+			(*close_snap)(hModuleSnap);
+			FreeLibrary(dll);
+			return ret;
+			}
+		} while((*module_next)(hModuleSnap,&me32));
+
+	(*close_snap)(hModuleSnap); 
+	FreeLibrary(dll);
+	return NULL;
+	}
+#endif /* DSO_WIN32 */
diff --git a/openssl/crypto/ebcdic.c b/openssl/crypto/ebcdic.c
new file mode 100644
index 0000000..43e53bc
--- /dev/null
+++ b/openssl/crypto/ebcdic.c
@@ -0,0 +1,221 @@
+/* crypto/ebcdic.c */
+
+#ifndef CHARSET_EBCDIC
+
+#include <openssl/e_os2.h>
+#if defined(PEDANTIC) || defined(__DECC) || defined(OPENSSL_SYS_MACOSX)
+static void *dummy=&dummy;
+#endif
+
+#else /*CHARSET_EBCDIC*/
+
+#include "ebcdic.h"
+/*      Initial Port for  Apache-1.3     by <Martin.Kraemer@Mch.SNI.De>
+ *      Adapted for       OpenSSL-0.9.4  by <Martin.Kraemer@Mch.SNI.De>
+ */
+
+#ifdef _OSD_POSIX
+/*
+    "BS2000 OSD" is a POSIX subsystem on a main frame.
+    It is made by Siemens AG, Germany, for their BS2000 mainframe machines.
+    Within the POSIX subsystem, the same character set was chosen as in
+    "native BS2000", namely EBCDIC. (EDF04)
+
+    The name "ASCII" in these routines is misleading: actually, conversion
+    is not between EBCDIC and ASCII, but EBCDIC(EDF04) and ISO-8859.1;
+    that means that (western european) national characters are preserved.
+
+    This table is identical to the one used by rsh/rcp/ftp and other POSIX tools.
+*/
+
+/* Here's the bijective ebcdic-to-ascii table: */
+const unsigned char os_toascii[256] = {
+/*00*/ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f,
+       0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /*................*/
+/*10*/ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97,
+       0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /*................*/
+/*20*/ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b,
+       0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /*................*/
+/*30*/ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
+       0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /*................*/
+/*40*/ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5,
+       0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* .........`.<(+|*/
+/*50*/ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef,
+       0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x9f, /*&.........!$*);.*/
+/*60*/ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5,
+       0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /*-/........^,%_>?*/
+/*70*/ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf,
+       0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /*..........:#@'="*/
+/*80*/ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+       0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /*.abcdefghi......*/
+/*90*/ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
+       0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /*.jklmnopqr......*/
+/*a0*/ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+       0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae, /*..stuvwxyz......*/
+/*b0*/ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc,
+       0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, 0xb4, 0xd7, /*...........[\]..*/
+/*c0*/ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+       0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /*.ABCDEFGHI......*/
+/*d0*/ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
+       0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, 0xfa, 0xff, /*.JKLMNOPQR......*/
+/*e0*/ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+       0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /*..STUVWXYZ......*/
+/*f0*/ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+       0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e  /*0123456789.{.}.~*/
+};
+
+
+/* The ascii-to-ebcdic table: */
+const unsigned char os_toebcdic[256] = {
+/*00*/  0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f,
+	0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,  /*................*/
+/*10*/  0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26,
+	0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f,  /*................*/
+/*20*/  0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d,
+	0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61,  /* !"#$%&'()*+,-./ */
+/*30*/  0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+	0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f,  /*0123456789:;<=>?*/
+/*40*/  0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+	0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,  /*@ABCDEFGHIJKLMNO*/
+/*50*/  0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
+	0xe7, 0xe8, 0xe9, 0xbb, 0xbc, 0xbd, 0x6a, 0x6d,  /*PQRSTUVWXYZ[\]^_*/
+/*60*/  0x4a, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+	0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,  /*`abcdefghijklmno*/
+/*70*/  0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
+	0xa7, 0xa8, 0xa9, 0xfb, 0x4f, 0xfd, 0xff, 0x07,  /*pqrstuvwxyz{|}~.*/
+/*80*/  0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08,
+	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14,  /*................*/
+/*90*/  0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17,
+	0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0x5f,  /*................*/
+/*a0*/  0x41, 0xaa, 0xb0, 0xb1, 0x9f, 0xb2, 0xd0, 0xb5,
+	0x79, 0xb4, 0x9a, 0x8a, 0xba, 0xca, 0xaf, 0xa1,  /*................*/
+/*b0*/  0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3,
+	0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab,  /*................*/
+/*c0*/  0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68,
+	0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77,  /*................*/
+/*d0*/  0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf,
+	0x80, 0xe0, 0xfe, 0xdd, 0xfc, 0xad, 0xae, 0x59,  /*................*/
+/*e0*/  0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48,
+	0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57,  /*................*/
+/*f0*/  0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1,
+	0x70, 0xc0, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf   /*................*/
+};
+
+#else  /*_OSD_POSIX*/
+
+/*
+This code does basic character mapping for IBM's TPF and OS/390 operating systems.
+It is a modified version of the BS2000 table.
+
+Bijective EBCDIC (character set IBM-1047) to US-ASCII table:
+This table is bijective - there are no ambigous or duplicate characters.
+*/
+const unsigned char os_toascii[256] = {
+    0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, /* 00-0f:           */
+    0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
+    0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, /* 10-1f:           */
+    0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
+    0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, /* 20-2f:           */
+    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */
+    0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30-3f:           */
+    0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */
+    0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, /* 40-4f:           */
+    0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /*  ...........<(+| */
+    0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, /* 50-5f:           */
+    0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, /* &.........!$*);^ */
+    0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, /* 60-6f:           */
+    0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /* -/.........,%_>? */
+    0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, /* 70-7f:           */
+    0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* .........`:#@'=" */
+    0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80-8f:           */
+    0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */
+    0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* 90-9f:           */
+    0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */
+    0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* a0-af:           */
+    0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae, /* .~stuvwxyz...[.. */
+    0xac, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, /* b0-bf:           */
+    0xbd, 0xbe, 0xdd, 0xa8, 0xaf, 0x5d, 0xb4, 0xd7, /* .............].. */
+    0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* c0-cf:           */
+    0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* {ABCDEFGHI...... */
+    0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, /* d0-df:           */
+    0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff, /* }JKLMNOPQR...... */
+    0x5c, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* e0-ef:           */
+    0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* \.STUVWXYZ...... */
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* f0-ff:           */
+    0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f  /* 0123456789...... */
+};
+
+
+/*
+The US-ASCII to EBCDIC (character set IBM-1047) table:
+This table is bijective (no ambiguous or duplicate characters)
+*/
+const unsigned char os_toebcdic[256] = {
+    0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, /* 00-0f:           */
+    0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
+    0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, /* 10-1f:           */
+    0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
+    0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, /* 20-2f:           */
+    0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /*  !"#$%&'()*+,-./ */
+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 30-3f:           */
+    0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /* 0123456789:;<=>? */
+    0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 40-4f:           */
+    0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /* @ABCDEFGHIJKLMNO */
+    0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, /* 50-5f:           */
+    0xe7, 0xe8, 0xe9, 0xad, 0xe0, 0xbd, 0x5f, 0x6d, /* PQRSTUVWXYZ[\]^_ */
+    0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60-6f:           */
+    0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* `abcdefghijklmno */
+    0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, /* 70-7f:           */
+    0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07, /* pqrstuvwxyz{|}~. */
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08, /* 80-8f:           */
+    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /* ................ */
+    0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17, /* 90-9f:           */
+    0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0xff, /* ................ */
+    0x41, 0xaa, 0x4a, 0xb1, 0x9f, 0xb2, 0x6a, 0xb5, /* a0-af:           */
+    0xbb, 0xb4, 0x9a, 0x8a, 0xb0, 0xca, 0xaf, 0xbc, /* ................ */
+    0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3, /* b0-bf:           */
+    0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /* ................ */
+    0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68, /* c0-cf:           */
+    0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* ................ */
+    0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf, /* d0-df:           */
+    0x80, 0xfd, 0xfe, 0xfb, 0xfc, 0xba, 0xae, 0x59, /* ................ */
+    0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48, /* e0-ef:           */
+    0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* ................ */
+    0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1, /* f0-ff:           */
+    0x70, 0xdd, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf  /* ................ */
+};
+#endif /*_OSD_POSIX*/
+
+/* Translate a memory block from EBCDIC (host charset) to ASCII (net charset)
+ * dest and srce may be identical, or separate memory blocks, but
+ * should not overlap. These functions intentionally have an interface
+ * compatible to memcpy(3).
+ */
+
+void *
+ebcdic2ascii(void *dest, const void *srce, size_t count)
+{
+    unsigned char *udest = dest;
+    const unsigned char *usrce = srce;
+
+    while (count-- != 0) {
+        *udest++ = os_toascii[*usrce++];
+    }
+
+    return dest;
+}
+
+void *
+ascii2ebcdic(void *dest, const void *srce, size_t count)
+{
+    unsigned char *udest = dest;
+    const unsigned char *usrce = srce;
+
+    while (count-- != 0) {
+        *udest++ = os_toebcdic[*usrce++];
+    }
+
+    return dest;
+}
+
+#endif
diff --git a/openssl/crypto/ebcdic.h b/openssl/crypto/ebcdic.h
new file mode 100644
index 0000000..6d65afc
--- /dev/null
+++ b/openssl/crypto/ebcdic.h
@@ -0,0 +1,19 @@
+/* crypto/ebcdic.h */
+
+#ifndef HEADER_EBCDIC_H
+#define HEADER_EBCDIC_H
+
+#include <sys/types.h>
+
+/* Avoid name clashes with other applications */
+#define os_toascii   _openssl_os_toascii
+#define os_toebcdic  _openssl_os_toebcdic
+#define ebcdic2ascii _openssl_ebcdic2ascii
+#define ascii2ebcdic _openssl_ascii2ebcdic
+
+extern const unsigned char os_toascii[256];
+extern const unsigned char os_toebcdic[256];
+void *ebcdic2ascii(void *dest, const void *srce, size_t count);
+void *ascii2ebcdic(void *dest, const void *srce, size_t count);
+
+#endif
diff --git a/openssl/crypto/ec/Makefile b/openssl/crypto/ec/Makefile
new file mode 100644
index 0000000..db380ed
--- /dev/null
+++ b/openssl/crypto/ec/Makefile
@@ -0,0 +1,231 @@
+#
+# crypto/ec/Makefile
+#
+
+DIR=	ec
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=ectest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=	ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c\
+	ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c\
+	ec2_smpl.c ec2_mult.c ec_ameth.c ec_pmeth.c eck_prn.c
+
+LIBOBJ=	ec_lib.o ecp_smpl.o ecp_mont.o ecp_nist.o ec_cvt.o ec_mult.o\
+	ec_err.o ec_curve.o ec_check.o ec_print.o ec_asn1.o ec_key.o\
+	ec2_smpl.o ec2_mult.o ec_ameth.o ec_pmeth.o eck_prn.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= ec.h
+HEADER=	ec_lcl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+ec2_mult.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ec2_mult.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+ec2_mult.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ec2_mult.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec2_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ec2_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec2_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec2_mult.o: ../../include/openssl/symhacks.h ec2_mult.c ec_lcl.h
+ec2_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ec2_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+ec2_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ec2_smpl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec2_smpl.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ec2_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec2_smpl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec2_smpl.o: ../../include/openssl/symhacks.h ec2_smpl.c ec_lcl.h
+ec_ameth.o: ../../e_os.h ../../include/openssl/asn1.h
+ec_ameth.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+ec_ameth.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
+ec_ameth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+ec_ameth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+ec_ameth.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+ec_ameth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+ec_ameth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ec_ameth.o: ../../include/openssl/opensslconf.h
+ec_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec_ameth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+ec_ameth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ec_ameth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+ec_ameth.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
+ec_ameth.o: ec_ameth.c
+ec_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+ec_asn1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+ec_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+ec_asn1.o: ../../include/openssl/ec.h ../../include/openssl/err.h
+ec_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ec_asn1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+ec_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec_asn1.o: ../../include/openssl/symhacks.h ec_asn1.c ec_lcl.h
+ec_check.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ec_check.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+ec_check.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ec_check.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec_check.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ec_check.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec_check.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec_check.o: ../../include/openssl/symhacks.h ec_check.c ec_lcl.h
+ec_curve.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ec_curve.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+ec_curve.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ec_curve.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec_curve.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ec_curve.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec_curve.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec_curve.o: ../../include/openssl/symhacks.h ec_curve.c ec_lcl.h
+ec_cvt.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ec_cvt.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+ec_cvt.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ec_cvt.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec_cvt.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ec_cvt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec_cvt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec_cvt.o: ../../include/openssl/symhacks.h ec_cvt.c ec_lcl.h
+ec_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ec_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+ec_err.o: ../../include/openssl/ec.h ../../include/openssl/err.h
+ec_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+ec_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec_err.o: ../../include/openssl/symhacks.h ec_err.c
+ec_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ec_key.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+ec_key.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ec_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ec_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec_key.o: ../../include/openssl/symhacks.h ec_key.c ec_lcl.h
+ec_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ec_lib.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+ec_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ec_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ec_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec_lib.o: ../../include/openssl/symhacks.h ec_lcl.h ec_lib.c
+ec_mult.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ec_mult.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+ec_mult.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ec_mult.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ec_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec_mult.o: ../../include/openssl/symhacks.h ec_lcl.h ec_mult.c
+ec_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
+ec_pmeth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+ec_pmeth.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+ec_pmeth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ec_pmeth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ec_pmeth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+ec_pmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ec_pmeth.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+ec_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+ec_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ec_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+ec_pmeth.o: ../../include/openssl/x509_vfy.h ../cryptlib.h ../evp/evp_locl.h
+ec_pmeth.o: ec_pmeth.c
+ec_print.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ec_print.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+ec_print.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ec_print.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ec_print.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec_print.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec_print.o: ../../include/openssl/symhacks.h ec_lcl.h ec_print.c
+eck_prn.o: ../../e_os.h ../../include/openssl/asn1.h
+eck_prn.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+eck_prn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+eck_prn.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+eck_prn.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+eck_prn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+eck_prn.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+eck_prn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+eck_prn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+eck_prn.o: ../../include/openssl/symhacks.h ../cryptlib.h eck_prn.c
+ecp_mont.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ecp_mont.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+ecp_mont.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ecp_mont.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ecp_mont.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ecp_mont.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ecp_mont.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ecp_mont.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_mont.c
+ecp_nist.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ecp_nist.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+ecp_nist.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ecp_nist.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ecp_nist.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ecp_nist.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ecp_nist.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ecp_nist.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_nist.c
+ecp_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ecp_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+ecp_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ecp_smpl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ecp_smpl.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ecp_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ecp_smpl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ecp_smpl.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_smpl.c
diff --git a/openssl/crypto/ec/ec.h b/openssl/crypto/ec/ec.h
new file mode 100644
index 0000000..ee70781
--- /dev/null
+++ b/openssl/crypto/ec/ec.h
@@ -0,0 +1,1100 @@
+/* crypto/ec/ec.h */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/**
+ * \file crypto/ec/ec.h Include file for the OpenSSL EC functions
+ * \author Originally written by Bodo Moeller for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by 
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#ifndef HEADER_EC_H
+#define HEADER_EC_H
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_EC
+#error EC is disabled.
+#endif
+
+#include <openssl/asn1.h>
+#include <openssl/symhacks.h>
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#elif defined(__SUNPRO_C)
+# if __SUNPRO_C >= 0x520
+# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
+# endif
+#endif
+
+  
+#ifndef OPENSSL_ECC_MAX_FIELD_BITS
+# define OPENSSL_ECC_MAX_FIELD_BITS 661
+#endif
+
+/** Enum for the point conversion form as defined in X9.62 (ECDSA)
+ *  for the encoding of a elliptic curve point (x,y) */
+typedef enum {
+	/** the point is encoded as z||x, where the octet z specifies 
+	 *  which solution of the quadratic equation y is  */
+	POINT_CONVERSION_COMPRESSED = 2,
+	/** the point is encoded as z||x||y, where z is the octet 0x02  */
+	POINT_CONVERSION_UNCOMPRESSED = 4,
+	/** the point is encoded as z||x||y, where the octet z specifies
+         *  which solution of the quadratic equation y is  */
+	POINT_CONVERSION_HYBRID = 6
+} point_conversion_form_t;
+
+
+typedef struct ec_method_st EC_METHOD;
+
+typedef struct ec_group_st
+	/*
+	 EC_METHOD *meth;
+	 -- field definition
+	 -- curve coefficients
+	 -- optional generator with associated information (order, cofactor)
+	 -- optional extra data (precomputed table for fast computation of multiples of generator)
+	 -- ASN1 stuff
+	*/
+	EC_GROUP;
+
+typedef struct ec_point_st EC_POINT;
+
+
+/********************************************************************/
+/*               EC_METHODs for curves over GF(p)                   */       
+/********************************************************************/
+
+/** Returns the basic GFp ec methods which provides the basis for the
+ *  optimized methods. 
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_simple_method(void);
+
+/** Returns GFp methods using montgomery multiplication.
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_mont_method(void);
+
+/** Returns GFp methods using optimized methods for NIST recommended curves
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_nist_method(void);
+
+
+/********************************************************************/ 
+/*           EC_METHOD for curves over GF(2^m)                      */
+/********************************************************************/
+
+/** Returns the basic GF2m ec method 
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GF2m_simple_method(void);
+
+
+/********************************************************************/
+/*                   EC_GROUP functions                             */
+/********************************************************************/
+
+/** Creates a new EC_GROUP object
+ *  \param   meth  EC_METHOD to use
+ *  \return  newly created EC_GROUP object or NULL in case of an error.
+ */
+EC_GROUP *EC_GROUP_new(const EC_METHOD *meth);
+
+/** Frees a EC_GROUP object
+ *  \param  group  EC_GROUP object to be freed.
+ */
+void EC_GROUP_free(EC_GROUP *group);
+
+/** Clears and frees a EC_GROUP object
+ *  \param  group  EC_GROUP object to be cleared and freed.
+ */
+void EC_GROUP_clear_free(EC_GROUP *group);
+
+/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD.
+ *  \param  dst  destination EC_GROUP object
+ *  \param  src  source EC_GROUP object
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src);
+
+/** Creates a new EC_GROUP object and copies the copies the content
+ *  form src to the newly created EC_KEY object
+ *  \param  src  source EC_GROUP object
+ *  \return newly created EC_GROUP object or NULL in case of an error.
+ */
+EC_GROUP *EC_GROUP_dup(const EC_GROUP *src);
+
+/** Returns the EC_METHOD of the EC_GROUP object.
+ *  \param  group  EC_GROUP object 
+ *  \return EC_METHOD used in this EC_GROUP object.
+ */
+const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);
+
+/** Returns the field type of the EC_METHOD.
+ *  \param  meth  EC_METHOD object
+ *  \return NID of the underlying field type OID.
+ */
+int EC_METHOD_get_field_type(const EC_METHOD *meth);
+
+/** Sets the generator and it's order/cofactor of a EC_GROUP object.
+ *  \param  group      EC_GROUP object 
+ *  \param  generator  EC_POINT object with the generator.
+ *  \param  order      the order of the group generated by the generator.
+ *  \param  cofactor   the index of the sub-group generated by the generator
+ *                     in the group of all points on the elliptic curve.
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor);
+
+/** Returns the generator of a EC_GROUP object.
+ *  \param  group  EC_GROUP object
+ *  \return the currently used generator (possibly NULL).
+ */
+const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);
+
+/** Gets the order of a EC_GROUP
+ *  \param  group  EC_GROUP object
+ *  \param  order  BIGNUM to which the order is copied
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx);
+
+/** Gets the cofactor of a EC_GROUP
+ *  \param  group     EC_GROUP object
+ *  \param  cofactor  BIGNUM to which the cofactor is copied
+ *  \param  ctx       BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx);
+
+/** Sets the name of a EC_GROUP object
+ *  \param  group  EC_GROUP object
+ *  \param  nid    NID of the curve name OID
+ */
+void EC_GROUP_set_curve_name(EC_GROUP *group, int nid);
+
+/** Returns the curve name of a EC_GROUP object
+ *  \param  group  EC_GROUP object
+ *  \return NID of the curve name OID or 0 if not set.
+ */
+int EC_GROUP_get_curve_name(const EC_GROUP *group);
+
+void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
+int EC_GROUP_get_asn1_flag(const EC_GROUP *group);
+
+void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t);
+point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
+
+unsigned char *EC_GROUP_get0_seed(const EC_GROUP *);
+size_t EC_GROUP_get_seed_len(const EC_GROUP *);
+size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
+
+/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM with the prime number
+ *  \param  a      BIGNUM with parameter a of the equation
+ *  \param  b      BIGNUM with parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+
+/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM for the prime number
+ *  \param  a      BIGNUM for parameter a of the equation
+ *  \param  b      BIGNUM for parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+
+/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM with the polynomial defining the underlying field
+ *  \param  a      BIGNUM with parameter a of the equation
+ *  \param  b      BIGNUM with parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+
+/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM for the polynomial defining the underlying field
+ *  \param  a      BIGNUM for parameter a of the equation
+ *  \param  b      BIGNUM for parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+
+/** Returns the number of bits needed to represent a field element 
+ *  \param  group  EC_GROUP object
+ *  \return number of bits needed to represent a field element
+ */
+int EC_GROUP_get_degree(const EC_GROUP *group);
+
+/** Checks whether the parameter in the EC_GROUP define a valid ec group
+ *  \param  group  EC_GROUP object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 if group is a valid ec group and 0 otherwise
+ */
+int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
+
+/** Checks whether the discriminant of the elliptic curve is zero or not
+ *  \param  group  EC_GROUP object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 if the discriminant is not zero and 0 otherwise
+ */
+int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx);
+
+/** Compares two EC_GROUP objects
+ *  \param  a    first EC_GROUP object
+ *  \param  b    second EC_GROUP object
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return 0 if both groups are equal and 1 otherwise
+ */
+int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx);
+
+/* EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*()
+ * after choosing an appropriate EC_METHOD */
+
+/** Creates a new EC_GROUP object with the specified parameters defined
+ *  over GFp (defined by the equation y^2 = x^3 + a*x + b)
+ *  \param  p    BIGNUM with the prime number
+ *  \param  a    BIGNUM with the parameter a of the equation
+ *  \param  b    BIGNUM with the parameter b of the equation
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return newly created EC_GROUP object with the specified parameters
+ */
+EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+
+/** Creates a new EC_GROUP object with the specified parameters defined
+ *  over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b)
+ *  \param  p    BIGNUM with the polynomial defining the underlying field
+ *  \param  a    BIGNUM with the parameter a of the equation
+ *  \param  b    BIGNUM with the parameter b of the equation
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return newly created EC_GROUP object with the specified parameters
+ */
+EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+
+/** Creates a EC_GROUP object with a curve specified by a NID
+ *  \param  nid  NID of the OID of the curve name
+ *  \return newly created EC_GROUP object with specified curve or NULL
+ *          if an error occurred
+ */
+EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
+
+
+/********************************************************************/
+/*               handling of internal curves                        */
+/********************************************************************/
+
+typedef struct { 
+	int nid;
+	const char *comment;
+	} EC_builtin_curve;
+
+/* EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number 
+ * of all available curves or zero if a error occurred. 
+ * In case r ist not zero nitems EC_builtin_curve structures 
+ * are filled with the data of the first nitems internal groups */
+size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
+
+
+/********************************************************************/
+/*                    EC_POINT functions                            */
+/********************************************************************/
+
+/** Creates a new EC_POINT object for the specified EC_GROUP
+ *  \param  group  EC_GROUP the underlying EC_GROUP object
+ *  \return newly created EC_POINT object or NULL if an error occurred
+ */
+EC_POINT *EC_POINT_new(const EC_GROUP *group);
+
+/** Frees a EC_POINT object
+ *  \param  point  EC_POINT object to be freed
+ */
+void EC_POINT_free(EC_POINT *point);
+
+/** Clears and frees a EC_POINT object
+ *  \param  point  EC_POINT object to be cleared and freed
+ */
+void EC_POINT_clear_free(EC_POINT *point);
+
+/** Copies EC_POINT object
+ *  \param  dst  destination EC_POINT object
+ *  \param  src  source EC_POINT object
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src);
+
+/** Creates a new EC_POINT object and copies the content of the supplied
+ *  EC_POINT
+ *  \param  src    source EC_POINT object
+ *  \param  group  underlying the EC_GROUP object
+ *  \return newly created EC_POINT object or NULL if an error occurred 
+ */
+EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group);
+ 
+/** Returns the EC_METHOD used in EC_POINT object 
+ *  \param  point  EC_POINT object
+ *  \return the EC_METHOD used
+ */
+const EC_METHOD *EC_POINT_method_of(const EC_POINT *point);
+
+/** Sets a point to infinity (neutral element)
+ *  \param  group  underlying EC_GROUP object
+ *  \param  point  EC_POINT to set to infinity
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point);
+
+/** Sets the jacobian projective coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with the x-coordinate
+ *  \param  y      BIGNUM with the y-coordinate
+ *  \param  z      BIGNUM with the z-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
+	const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx);
+
+/** Gets the jacobian projective coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM for the x-coordinate
+ *  \param  y      BIGNUM for the y-coordinate
+ *  \param  z      BIGNUM for the z-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
+	const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx);
+
+/** Sets the affine coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with the x-coordinate
+ *  \param  y      BIGNUM with the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
+
+/** Gets the affine coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM for the x-coordinate
+ *  \param  y      BIGNUM for the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
+	const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
+
+/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with x-coordinate
+ *  \param  y_bit  integer with the y-Bit (either 0 or 1)
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
+	const BIGNUM *x, int y_bit, BN_CTX *ctx);
+
+/** Sets the affine coordinates of a EC_POINT over GF2m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with the x-coordinate
+ *  \param  y      BIGNUM with the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
+
+/** Gets the affine coordinates of a EC_POINT over GF2m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM for the x-coordinate
+ *  \param  y      BIGNUM for the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
+	const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
+
+/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with x-coordinate
+ *  \param  y_bit  integer with the y-Bit (either 0 or 1)
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
+	const BIGNUM *x, int y_bit, BN_CTX *ctx);
+
+/** Encodes a EC_POINT object to a octet string
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  form   point conversion form
+ *  \param  buf    memory buffer for the result. If NULL the function returns
+ *                 required buffer size.
+ *  \param  len    length of the memory buffer
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return the length of the encoded octet string or 0 if an error occurred
+ */
+size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p,
+	point_conversion_form_t form,
+        unsigned char *buf, size_t len, BN_CTX *ctx);
+
+/** Decodes a EC_POINT from a octet string
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  buf    memory buffer with the encoded ec point
+ *  \param  len    length of the encoded ec point
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p,
+        const unsigned char *buf, size_t len, BN_CTX *ctx);
+
+/* other interfaces to point2oct/oct2point: */
+BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
+	point_conversion_form_t form, BIGNUM *, BN_CTX *);
+EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *,
+	EC_POINT *, BN_CTX *);
+char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *,
+	point_conversion_form_t form, BN_CTX *);
+EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
+	EC_POINT *, BN_CTX *);
+
+
+/********************************************************************/
+/*         functions for doing EC_POINT arithmetic                  */
+/********************************************************************/
+
+/** Computes the sum of two EC_POINT 
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result (r = a + b)
+ *  \param  a      EC_POINT object with the first summand
+ *  \param  b      EC_POINT object with the second summand
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
+
+/** Computes the double of a EC_POINT
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result (r = 2 * a)
+ *  \param  a      EC_POINT object 
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx);
+
+/** Computes the inverse of a EC_POINT
+ *  \param  group  underlying EC_GROUP object
+ *  \param  a      EC_POINT object to be inverted (it's used for the result as well)
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx);
+
+/** Checks whether the point is the neutral element of the group
+ *  \param  group  the underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \return 1 if the point is the neutral element and 0 otherwise
+ */
+int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p);
+
+/** Checks whether the point is on the curve 
+ *  \param  group  underlying EC_GROUP object
+ *  \param  point  EC_POINT object to check
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 if point if on the curve and 0 otherwise
+ */
+int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx);
+
+/** Compares two EC_POINTs 
+ *  \param  group  underlying EC_GROUP object
+ *  \param  a      first EC_POINT object
+ *  \param  b      second EC_POINT object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 0 if both points are equal and a value != 0 otherwise
+ */
+int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
+
+int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
+
+/** Computes r = generator * n sum_{i=0}^num p[i] * m[i]
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result
+ *  \param  n      BIGNUM with the multiplier for the group generator (optional)
+ *  \param  num    number futher summands
+ *  \param  p      array of size num of EC_POINT objects
+ *  \param  m      array of size num of BIGNUM objects
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, size_t num, const EC_POINT *p[], const BIGNUM *m[], BN_CTX *ctx);
+
+/** Computes r = generator * n + q * m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result
+ *  \param  n      BIGNUM with the multiplier for the group generator (optional)
+ *  \param  q      EC_POINT object with the first factor of the second summand
+ *  \param  m      BIGNUM with the second factor of the second summand
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
+
+/** Stores multiples of generator for faster point multiplication
+ *  \param  group  EC_GROUP object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+
+/** Reports whether a precomputation has been done
+ *  \param  group  EC_GROUP object
+ *  \return 1 if a pre-computation has been done and 0 otherwise
+ */
+int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
+
+
+/********************************************************************/
+/*                       ASN1 stuff                                 */
+/********************************************************************/
+
+/* EC_GROUP_get_basis_type() returns the NID of the basis type
+ * used to represent the field elements */
+int EC_GROUP_get_basis_type(const EC_GROUP *);
+int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k);
+int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1, 
+	unsigned int *k2, unsigned int *k3);
+
+#define OPENSSL_EC_NAMED_CURVE	0x001
+
+typedef struct ecpk_parameters_st ECPKPARAMETERS;
+
+EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
+int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);
+
+#define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x)
+#define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x)
+#define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \
+                (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x))
+#define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \
+		(unsigned char *)(x))
+
+#ifndef OPENSSL_NO_BIO
+int     ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
+#endif
+#ifndef OPENSSL_NO_FP_API
+int     ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
+#endif
+
+
+/********************************************************************/
+/*                      EC_KEY functions                            */
+/********************************************************************/
+
+typedef struct ec_key_st EC_KEY;
+
+/* some values for the encoding_flag */
+#define EC_PKEY_NO_PARAMETERS	0x001
+#define EC_PKEY_NO_PUBKEY	0x002
+
+/** Creates a new EC_KEY object.
+ *  \return EC_KEY object or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_new(void);
+
+/** Creates a new EC_KEY object using a named curve as underlying
+ *  EC_GROUP object.
+ *  \param  nid  NID of the named curve.
+ *  \return EC_KEY object or NULL if an error occurred. 
+ */
+EC_KEY *EC_KEY_new_by_curve_name(int nid);
+
+/** Frees a EC_KEY object.
+ *  \param  key  EC_KEY object to be freed.
+ */
+void EC_KEY_free(EC_KEY *key);
+
+/** Copies a EC_KEY object.
+ *  \param  dst  destination EC_KEY object
+ *  \param  src  src EC_KEY object
+ *  \return dst or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);
+
+/** Creates a new EC_KEY object and copies the content from src to it.
+ *  \param  src  the source EC_KEY object
+ *  \return newly created EC_KEY object or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_dup(const EC_KEY *src);
+
+/** Increases the internal reference count of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_up_ref(EC_KEY *key);
+
+/** Returns the EC_GROUP object of a EC_KEY object
+ *  \param  key  EC_KEY object
+ *  \return the EC_GROUP object (possibly NULL).
+ */
+const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);
+
+/** Sets the EC_GROUP of a EC_KEY object.
+ *  \param  key    EC_KEY object
+ *  \param  group  EC_GROUP to use in the EC_KEY object (note: the EC_KEY
+ *                 object will use an own copy of the EC_GROUP).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group);
+
+/** Returns the private key of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \return a BIGNUM with the private key (possibly NULL).
+ */
+const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);
+
+/** Sets the private key of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \param  prv  BIGNUM with the private key (note: the EC_KEY object
+ *               will use an own copy of the BIGNUM).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);
+
+/** Returns the public key of a EC_KEY object.
+ *  \param  key  the EC_KEY object
+ *  \return a EC_POINT object with the public key (possibly NULL)
+ */
+const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
+
+/** Sets the public key of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \param  pub  EC_POINT object with the public key (note: the EC_KEY object
+ *               will use an own copy of the EC_POINT object).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
+
+unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
+void EC_KEY_set_enc_flags(EC_KEY *, unsigned int);
+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *);
+void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t);
+/* functions to set/get method specific data  */
+void *EC_KEY_get_key_method_data(EC_KEY *, 
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
+void EC_KEY_insert_key_method_data(EC_KEY *, void *data,
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
+/* wrapper functions for the underlying EC_GROUP object */
+void EC_KEY_set_asn1_flag(EC_KEY *, int);
+
+/** Creates a table of pre-computed multiples of the generator to 
+ *  accelerate further EC_KEY operations.
+ *  \param  key  EC_KEY object
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
+
+/** Creates a new ec private (and optional a new public) key.
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_generate_key(EC_KEY *key);
+
+/** Verifies that a private and/or public key is valid.
+ *  \param  key  the EC_KEY object
+ *  \return 1 on success and 0 otherwise.
+ */
+int EC_KEY_check_key(const EC_KEY *key);
+
+
+/********************************************************************/
+/*        de- and encoding functions for SEC1 ECPrivateKey          */
+/********************************************************************/
+
+/** Decodes a private key from a memory buffer.
+ *  \param  key  a pointer to a EC_KEY object which should be used (or NULL)
+ *  \param  in   pointer to memory with the DER encoded private key
+ *  \param  len  length of the DER encoded private key
+ *  \return the decoded private key or NULL if an error occurred.
+ */
+EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes a private key object and stores the result in a buffer.
+ *  \param  key  the EC_KEY object to encode
+ *  \param  out  the buffer for the result (if NULL the function returns number
+ *               of bytes needed).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out);
+
+
+/********************************************************************/
+/*        de- and encoding functions for EC parameters              */
+/********************************************************************/
+
+/** Decodes ec parameter from a memory buffer.
+ *  \param  key  a pointer to a EC_KEY object which should be used (or NULL)
+ *  \param  in   pointer to memory with the DER encoded ec parameters
+ *  \param  len  length of the DER encoded ec parameters
+ *  \return a EC_KEY object with the decoded parameters or NULL if an error
+ *          occurred.
+ */
+EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes ec parameter and stores the result in a buffer.
+ *  \param  key  the EC_KEY object with ec paramters to encode
+ *  \param  out  the buffer for the result (if NULL the function returns number
+ *               of bytes needed).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int i2d_ECParameters(EC_KEY *key, unsigned char **out);
+
+
+/********************************************************************/
+/*         de- and encoding functions for EC public key             */
+/*         (octet string, not DER -- hence 'o2i' and 'i2o')         */
+/********************************************************************/
+
+/** Decodes a ec public key from a octet string.
+ *  \param  key  a pointer to a EC_KEY object which should be used
+ *  \param  in   memory buffer with the encoded public key
+ *  \param  len  length of the encoded public key
+ *  \return EC_KEY object with decoded public key or NULL if an error
+ *          occurred.
+ */
+EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes a ec public key in an octet string.
+ *  \param  key  the EC_KEY object with the public key
+ *  \param  out  the buffer for the result (if NULL the function returns number
+ *               of bytes needed).
+ *  \return 1 on success and 0 if an error occurred
+ */
+int i2o_ECPublicKey(EC_KEY *key, unsigned char **out);
+
+#ifndef OPENSSL_NO_BIO
+/** Prints out the ec parameters on human readable form.
+ *  \param  bp   BIO object to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred
+ */
+int	ECParameters_print(BIO *bp, const EC_KEY *key);
+
+/** Prints out the contents of a EC_KEY object
+ *  \param  bp   BIO object to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \param  off  line offset 
+ *  \return 1 on success and 0 if an error occurred
+ */
+int	EC_KEY_print(BIO *bp, const EC_KEY *key, int off);
+
+#endif
+#ifndef OPENSSL_NO_FP_API
+/** Prints out the ec parameters on human readable form.
+ *  \param  fp   file descriptor to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred
+ */
+int	ECParameters_print_fp(FILE *fp, const EC_KEY *key);
+
+/** Prints out the contents of a EC_KEY object
+ *  \param  fp   file descriptor to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \param  off  line offset 
+ *  \return 1 on success and 0 if an error occurred
+ */
+int	EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);
+
+#endif
+
+#define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x)
+
+#ifndef __cplusplus
+#if defined(__SUNPRO_C)
+#  if __SUNPRO_C >= 0x520
+# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
+#  endif
+# endif
+#endif
+
+#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_PARAMGEN, \
+				EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)
+
+
+#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID		(EVP_PKEY_ALG_CTRL + 1)
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_EC_strings(void);
+
+/* Error codes for the EC functions. */
+
+/* Function codes. */
+#define EC_F_COMPUTE_WNAF				 143
+#define EC_F_D2I_ECPARAMETERS				 144
+#define EC_F_D2I_ECPKPARAMETERS				 145
+#define EC_F_D2I_ECPRIVATEKEY				 146
+#define EC_F_DO_EC_KEY_PRINT				 221
+#define EC_F_ECKEY_PARAM2TYPE				 223
+#define EC_F_ECKEY_PARAM_DECODE				 212
+#define EC_F_ECKEY_PRIV_DECODE				 213
+#define EC_F_ECKEY_PRIV_ENCODE				 214
+#define EC_F_ECKEY_PUB_DECODE				 215
+#define EC_F_ECKEY_PUB_ENCODE				 216
+#define EC_F_ECKEY_TYPE2PARAM				 220
+#define EC_F_ECPARAMETERS_PRINT				 147
+#define EC_F_ECPARAMETERS_PRINT_FP			 148
+#define EC_F_ECPKPARAMETERS_PRINT			 149
+#define EC_F_ECPKPARAMETERS_PRINT_FP			 150
+#define EC_F_ECP_NIST_MOD_192				 203
+#define EC_F_ECP_NIST_MOD_224				 204
+#define EC_F_ECP_NIST_MOD_256				 205
+#define EC_F_ECP_NIST_MOD_521				 206
+#define EC_F_EC_ASN1_GROUP2CURVE			 153
+#define EC_F_EC_ASN1_GROUP2FIELDID			 154
+#define EC_F_EC_ASN1_GROUP2PARAMETERS			 155
+#define EC_F_EC_ASN1_GROUP2PKPARAMETERS			 156
+#define EC_F_EC_ASN1_PARAMETERS2GROUP			 157
+#define EC_F_EC_ASN1_PKPARAMETERS2GROUP			 158
+#define EC_F_EC_EX_DATA_SET_DATA			 211
+#define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY		 208
+#define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT	 159
+#define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE		 195
+#define EC_F_EC_GF2M_SIMPLE_OCT2POINT			 160
+#define EC_F_EC_GF2M_SIMPLE_POINT2OCT			 161
+#define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162
+#define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163
+#define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES	 164
+#define EC_F_EC_GFP_MONT_FIELD_DECODE			 133
+#define EC_F_EC_GFP_MONT_FIELD_ENCODE			 134
+#define EC_F_EC_GFP_MONT_FIELD_MUL			 131
+#define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE		 209
+#define EC_F_EC_GFP_MONT_FIELD_SQR			 132
+#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE		 189
+#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP		 135
+#define EC_F_EC_GFP_NIST_FIELD_MUL			 200
+#define EC_F_EC_GFP_NIST_FIELD_SQR			 201
+#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE		 202
+#define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT	 165
+#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE		 166
+#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP		 100
+#define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR		 101
+#define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE			 102
+#define EC_F_EC_GFP_SIMPLE_OCT2POINT			 103
+#define EC_F_EC_GFP_SIMPLE_POINT2OCT			 104
+#define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE		 137
+#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES	 167
+#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105
+#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES	 168
+#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128
+#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES	 169
+#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129
+#define EC_F_EC_GROUP_CHECK				 170
+#define EC_F_EC_GROUP_CHECK_DISCRIMINANT		 171
+#define EC_F_EC_GROUP_COPY				 106
+#define EC_F_EC_GROUP_GET0_GENERATOR			 139
+#define EC_F_EC_GROUP_GET_COFACTOR			 140
+#define EC_F_EC_GROUP_GET_CURVE_GF2M			 172
+#define EC_F_EC_GROUP_GET_CURVE_GFP			 130
+#define EC_F_EC_GROUP_GET_DEGREE			 173
+#define EC_F_EC_GROUP_GET_ORDER				 141
+#define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS		 193
+#define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS		 194
+#define EC_F_EC_GROUP_NEW				 108
+#define EC_F_EC_GROUP_NEW_BY_CURVE_NAME			 174
+#define EC_F_EC_GROUP_NEW_FROM_DATA			 175
+#define EC_F_EC_GROUP_PRECOMPUTE_MULT			 142
+#define EC_F_EC_GROUP_SET_CURVE_GF2M			 176
+#define EC_F_EC_GROUP_SET_CURVE_GFP			 109
+#define EC_F_EC_GROUP_SET_EXTRA_DATA			 110
+#define EC_F_EC_GROUP_SET_GENERATOR			 111
+#define EC_F_EC_KEY_CHECK_KEY				 177
+#define EC_F_EC_KEY_COPY				 178
+#define EC_F_EC_KEY_GENERATE_KEY			 179
+#define EC_F_EC_KEY_NEW					 182
+#define EC_F_EC_KEY_PRINT				 180
+#define EC_F_EC_KEY_PRINT_FP				 181
+#define EC_F_EC_POINTS_MAKE_AFFINE			 136
+#define EC_F_EC_POINT_ADD				 112
+#define EC_F_EC_POINT_CMP				 113
+#define EC_F_EC_POINT_COPY				 114
+#define EC_F_EC_POINT_DBL				 115
+#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M	 183
+#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP	 116
+#define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP	 117
+#define EC_F_EC_POINT_INVERT				 210
+#define EC_F_EC_POINT_IS_AT_INFINITY			 118
+#define EC_F_EC_POINT_IS_ON_CURVE			 119
+#define EC_F_EC_POINT_MAKE_AFFINE			 120
+#define EC_F_EC_POINT_MUL				 184
+#define EC_F_EC_POINT_NEW				 121
+#define EC_F_EC_POINT_OCT2POINT				 122
+#define EC_F_EC_POINT_POINT2OCT				 123
+#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M	 185
+#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP	 124
+#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M	 186
+#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP	 125
+#define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP	 126
+#define EC_F_EC_POINT_SET_TO_INFINITY			 127
+#define EC_F_EC_PRE_COMP_DUP				 207
+#define EC_F_EC_PRE_COMP_NEW				 196
+#define EC_F_EC_WNAF_MUL				 187
+#define EC_F_EC_WNAF_PRECOMPUTE_MULT			 188
+#define EC_F_I2D_ECPARAMETERS				 190
+#define EC_F_I2D_ECPKPARAMETERS				 191
+#define EC_F_I2D_ECPRIVATEKEY				 192
+#define EC_F_I2O_ECPUBLICKEY				 151
+#define EC_F_O2I_ECPUBLICKEY				 152
+#define EC_F_OLD_EC_PRIV_DECODE				 222
+#define EC_F_PKEY_EC_CTRL				 197
+#define EC_F_PKEY_EC_CTRL_STR				 198
+#define EC_F_PKEY_EC_DERIVE				 217
+#define EC_F_PKEY_EC_KEYGEN				 199
+#define EC_F_PKEY_EC_PARAMGEN				 219
+#define EC_F_PKEY_EC_SIGN				 218
+
+/* Reason codes. */
+#define EC_R_ASN1_ERROR					 115
+#define EC_R_ASN1_UNKNOWN_FIELD				 116
+#define EC_R_BUFFER_TOO_SMALL				 100
+#define EC_R_D2I_ECPKPARAMETERS_FAILURE			 117
+#define EC_R_DECODE_ERROR				 142
+#define EC_R_DISCRIMINANT_IS_ZERO			 118
+#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE		 119
+#define EC_R_FIELD_TOO_LARGE				 143
+#define EC_R_GROUP2PKPARAMETERS_FAILURE			 120
+#define EC_R_I2D_ECPKPARAMETERS_FAILURE			 121
+#define EC_R_INCOMPATIBLE_OBJECTS			 101
+#define EC_R_INVALID_ARGUMENT				 112
+#define EC_R_INVALID_COMPRESSED_POINT			 110
+#define EC_R_INVALID_COMPRESSION_BIT			 109
+#define EC_R_INVALID_CURVE				 141
+#define EC_R_INVALID_DIGEST_TYPE			 138
+#define EC_R_INVALID_ENCODING				 102
+#define EC_R_INVALID_FIELD				 103
+#define EC_R_INVALID_FORM				 104
+#define EC_R_INVALID_GROUP_ORDER			 122
+#define EC_R_INVALID_PENTANOMIAL_BASIS			 132
+#define EC_R_INVALID_PRIVATE_KEY			 123
+#define EC_R_INVALID_TRINOMIAL_BASIS			 137
+#define EC_R_KEYS_NOT_SET				 140
+#define EC_R_MISSING_PARAMETERS				 124
+#define EC_R_MISSING_PRIVATE_KEY			 125
+#define EC_R_NOT_A_NIST_PRIME				 135
+#define EC_R_NOT_A_SUPPORTED_NIST_PRIME			 136
+#define EC_R_NOT_IMPLEMENTED				 126
+#define EC_R_NOT_INITIALIZED				 111
+#define EC_R_NO_FIELD_MOD				 133
+#define EC_R_NO_PARAMETERS_SET				 139
+#define EC_R_PASSED_NULL_PARAMETER			 134
+#define EC_R_PKPARAMETERS2GROUP_FAILURE			 127
+#define EC_R_POINT_AT_INFINITY				 106
+#define EC_R_POINT_IS_NOT_ON_CURVE			 107
+#define EC_R_SLOT_FULL					 108
+#define EC_R_UNDEFINED_GENERATOR			 113
+#define EC_R_UNDEFINED_ORDER				 128
+#define EC_R_UNKNOWN_GROUP				 129
+#define EC_R_UNKNOWN_ORDER				 114
+#define EC_R_UNSUPPORTED_FIELD				 131
+#define EC_R_WRONG_ORDER				 130
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/ec/ec2_mult.c b/openssl/crypto/ec/ec2_mult.c
new file mode 100644
index 0000000..e12b9b2
--- /dev/null
+++ b/openssl/crypto/ec/ec2_mult.c
@@ -0,0 +1,386 @@
+/* crypto/ec/ec2_mult.c */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The software is originally written by Sheueling Chang Shantz and
+ * Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/err.h>
+
+#include "ec_lcl.h"
+
+
+/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective 
+ * coordinates.
+ * Uses algorithm Mdouble in appendix of 
+ *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
+ *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
+ * modified to not require precomputation of c=b^{2^{m-1}}.
+ */
+static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx)
+	{
+	BIGNUM *t1;
+	int ret = 0;
+	
+	/* Since Mdouble is static we can guarantee that ctx != NULL. */
+	BN_CTX_start(ctx);
+	t1 = BN_CTX_get(ctx);
+	if (t1 == NULL) goto err;
+
+	if (!group->meth->field_sqr(group, x, x, ctx)) goto err;
+	if (!group->meth->field_sqr(group, t1, z, ctx)) goto err;
+	if (!group->meth->field_mul(group, z, x, t1, ctx)) goto err;
+	if (!group->meth->field_sqr(group, x, x, ctx)) goto err;
+	if (!group->meth->field_sqr(group, t1, t1, ctx)) goto err;
+	if (!group->meth->field_mul(group, t1, &group->b, t1, ctx)) goto err;
+	if (!BN_GF2m_add(x, x, t1)) goto err;
+
+	ret = 1;
+
+ err:
+	BN_CTX_end(ctx);
+	return ret;
+	}
+
+/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery 
+ * projective coordinates.
+ * Uses algorithm Madd in appendix of 
+ *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
+ *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
+ */
+static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM *z1, 
+	const BIGNUM *x2, const BIGNUM *z2, BN_CTX *ctx)
+	{
+	BIGNUM *t1, *t2;
+	int ret = 0;
+	
+	/* Since Madd is static we can guarantee that ctx != NULL. */
+	BN_CTX_start(ctx);
+	t1 = BN_CTX_get(ctx);
+	t2 = BN_CTX_get(ctx);
+	if (t2 == NULL) goto err;
+
+	if (!BN_copy(t1, x)) goto err;
+	if (!group->meth->field_mul(group, x1, x1, z2, ctx)) goto err;
+	if (!group->meth->field_mul(group, z1, z1, x2, ctx)) goto err;
+	if (!group->meth->field_mul(group, t2, x1, z1, ctx)) goto err;
+	if (!BN_GF2m_add(z1, z1, x1)) goto err;
+	if (!group->meth->field_sqr(group, z1, z1, ctx)) goto err;
+	if (!group->meth->field_mul(group, x1, z1, t1, ctx)) goto err;
+	if (!BN_GF2m_add(x1, x1, t2)) goto err;
+
+	ret = 1;
+
+ err:
+	BN_CTX_end(ctx);
+	return ret;
+	}
+
+/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2) 
+ * using Montgomery point multiplication algorithm Mxy() in appendix of 
+ *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
+ *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
+ * Returns:
+ *     0 on error
+ *     1 if return value should be the point at infinity
+ *     2 otherwise
+ */
+static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, BIGNUM *x1, 
+	BIGNUM *z1, BIGNUM *x2, BIGNUM *z2, BN_CTX *ctx)
+	{
+	BIGNUM *t3, *t4, *t5;
+	int ret = 0;
+	
+	if (BN_is_zero(z1))
+		{
+		BN_zero(x2);
+		BN_zero(z2);
+		return 1;
+		}
+	
+	if (BN_is_zero(z2))
+		{
+		if (!BN_copy(x2, x)) return 0;
+		if (!BN_GF2m_add(z2, x, y)) return 0;
+		return 2;
+		}
+		
+	/* Since Mxy is static we can guarantee that ctx != NULL. */
+	BN_CTX_start(ctx);
+	t3 = BN_CTX_get(ctx);
+	t4 = BN_CTX_get(ctx);
+	t5 = BN_CTX_get(ctx);
+	if (t5 == NULL) goto err;
+
+	if (!BN_one(t5)) goto err;
+
+	if (!group->meth->field_mul(group, t3, z1, z2, ctx)) goto err;
+
+	if (!group->meth->field_mul(group, z1, z1, x, ctx)) goto err;
+	if (!BN_GF2m_add(z1, z1, x1)) goto err;
+	if (!group->meth->field_mul(group, z2, z2, x, ctx)) goto err;
+	if (!group->meth->field_mul(group, x1, z2, x1, ctx)) goto err;
+	if (!BN_GF2m_add(z2, z2, x2)) goto err;
+
+	if (!group->meth->field_mul(group, z2, z2, z1, ctx)) goto err;
+	if (!group->meth->field_sqr(group, t4, x, ctx)) goto err;
+	if (!BN_GF2m_add(t4, t4, y)) goto err;
+	if (!group->meth->field_mul(group, t4, t4, t3, ctx)) goto err;
+	if (!BN_GF2m_add(t4, t4, z2)) goto err;
+
+	if (!group->meth->field_mul(group, t3, t3, x, ctx)) goto err;
+	if (!group->meth->field_div(group, t3, t5, t3, ctx)) goto err;
+	if (!group->meth->field_mul(group, t4, t3, t4, ctx)) goto err;
+	if (!group->meth->field_mul(group, x2, x1, t3, ctx)) goto err;
+	if (!BN_GF2m_add(z2, x2, x)) goto err;
+
+	if (!group->meth->field_mul(group, z2, z2, t4, ctx)) goto err;
+	if (!BN_GF2m_add(z2, z2, y)) goto err;
+
+	ret = 2;
+
+ err:
+	BN_CTX_end(ctx);
+	return ret;
+	}
+
+/* Computes scalar*point and stores the result in r.
+ * point can not equal r.
+ * Uses algorithm 2P of
+ *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
+ *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
+ */
+static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+	const EC_POINT *point, BN_CTX *ctx)
+	{
+	BIGNUM *x1, *x2, *z1, *z2;
+	int ret = 0, i;
+	BN_ULONG mask,word;
+
+	if (r == point)
+		{
+		ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, EC_R_INVALID_ARGUMENT);
+		return 0;
+		}
+	
+	/* if result should be point at infinity */
+	if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) || 
+		EC_POINT_is_at_infinity(group, point))
+		{
+		return EC_POINT_set_to_infinity(group, r);
+		}
+
+	/* only support affine coordinates */
+	if (!point->Z_is_one) return 0;
+
+	/* Since point_multiply is static we can guarantee that ctx != NULL. */
+	BN_CTX_start(ctx);
+	x1 = BN_CTX_get(ctx);
+	z1 = BN_CTX_get(ctx);
+	if (z1 == NULL) goto err;
+
+	x2 = &r->X;
+	z2 = &r->Y;
+
+	if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */
+	if (!BN_one(z1)) goto err; /* z1 = 1 */
+	if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */
+	if (!group->meth->field_sqr(group, x2, z2, ctx)) goto err;
+	if (!BN_GF2m_add(x2, x2, &group->b)) goto err; /* x2 = x^4 + b */
+
+	/* find top most bit and go one past it */
+	i = scalar->top - 1;
+	mask = BN_TBIT;
+	word = scalar->d[i];
+	while (!(word & mask)) mask >>= 1;
+	mask >>= 1;
+	/* if top most bit was at word break, go to next word */
+	if (!mask) 
+		{
+		i--;
+		mask = BN_TBIT;
+		}
+
+	for (; i >= 0; i--)
+		{
+		word = scalar->d[i];
+		while (mask)
+			{
+			if (word & mask)
+				{
+				if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err;
+				if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err;
+				}
+			else
+				{
+				if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
+				if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
+				}
+			mask >>= 1;
+			}
+		mask = BN_TBIT;
+		}
+
+	/* convert out of "projective" coordinates */
+	i = gf2m_Mxy(group, &point->X, &point->Y, x1, z1, x2, z2, ctx);
+	if (i == 0) goto err;
+	else if (i == 1) 
+		{
+		if (!EC_POINT_set_to_infinity(group, r)) goto err;
+		}
+	else
+		{
+		if (!BN_one(&r->Z)) goto err;
+		r->Z_is_one = 1;
+		}
+
+	/* GF(2^m) field elements should always have BIGNUM::neg = 0 */
+	BN_set_negative(&r->X, 0);
+	BN_set_negative(&r->Y, 0);
+
+	ret = 1;
+
+ err:
+	BN_CTX_end(ctx);
+	return ret;
+	}
+
+
+/* Computes the sum
+ *     scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1]
+ * gracefully ignoring NULL scalar values.
+ */
+int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
+	{
+	BN_CTX *new_ctx = NULL;
+	int ret = 0;
+	size_t i;
+	EC_POINT *p=NULL;
+	EC_POINT *acc = NULL;
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+		}
+
+	/* This implementation is more efficient than the wNAF implementation for 2
+	 * or fewer points.  Use the ec_wNAF_mul implementation for 3 or more points,
+	 * or if we can perform a fast multiplication based on precomputation.
+	 */
+	if ((scalar && (num > 1)) || (num > 2) || (num == 0 && EC_GROUP_have_precompute_mult(group)))
+		{
+		ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
+		goto err;
+		}
+
+	if ((p = EC_POINT_new(group)) == NULL) goto err;
+	if ((acc = EC_POINT_new(group)) == NULL) goto err;
+
+	if (!EC_POINT_set_to_infinity(group, acc)) goto err;
+
+	if (scalar)
+		{
+		if (!ec_GF2m_montgomery_point_multiply(group, p, scalar, group->generator, ctx)) goto err;
+		if (BN_is_negative(scalar))
+			if (!group->meth->invert(group, p, ctx)) goto err;
+		if (!group->meth->add(group, acc, acc, p, ctx)) goto err;
+		}
+
+	for (i = 0; i < num; i++)
+		{
+		if (!ec_GF2m_montgomery_point_multiply(group, p, scalars[i], points[i], ctx)) goto err;
+		if (BN_is_negative(scalars[i]))
+			if (!group->meth->invert(group, p, ctx)) goto err;
+		if (!group->meth->add(group, acc, acc, p, ctx)) goto err;
+		}
+
+	if (!EC_POINT_copy(r, acc)) goto err;
+
+	ret = 1;
+
+  err:
+	if (p) EC_POINT_free(p);
+	if (acc) EC_POINT_free(acc);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+/* Precomputation for point multiplication: fall back to wNAF methods
+ * because ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate */
+
+int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+	{
+	return ec_wNAF_precompute_mult(group, ctx);
+ 	}
+
+int ec_GF2m_have_precompute_mult(const EC_GROUP *group)
+	{
+	return ec_wNAF_have_precompute_mult(group);
+ 	}
diff --git a/openssl/crypto/ec/ec2_smpl.c b/openssl/crypto/ec/ec2_smpl.c
new file mode 100644
index 0000000..03deae6
--- /dev/null
+++ b/openssl/crypto/ec/ec2_smpl.c
@@ -0,0 +1,1042 @@
+/* crypto/ec/ec2_smpl.c */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The software is originally written by Sheueling Chang Shantz and
+ * Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/err.h>
+
+#include "ec_lcl.h"
+
+
+const EC_METHOD *EC_GF2m_simple_method(void)
+	{
+	static const EC_METHOD ret = {
+		NID_X9_62_characteristic_two_field,
+		ec_GF2m_simple_group_init,
+		ec_GF2m_simple_group_finish,
+		ec_GF2m_simple_group_clear_finish,
+		ec_GF2m_simple_group_copy,
+		ec_GF2m_simple_group_set_curve,
+		ec_GF2m_simple_group_get_curve,
+		ec_GF2m_simple_group_get_degree,
+		ec_GF2m_simple_group_check_discriminant,
+		ec_GF2m_simple_point_init,
+		ec_GF2m_simple_point_finish,
+		ec_GF2m_simple_point_clear_finish,
+		ec_GF2m_simple_point_copy,
+		ec_GF2m_simple_point_set_to_infinity,
+		0 /* set_Jprojective_coordinates_GFp */,
+		0 /* get_Jprojective_coordinates_GFp */,
+		ec_GF2m_simple_point_set_affine_coordinates,
+		ec_GF2m_simple_point_get_affine_coordinates,
+		ec_GF2m_simple_set_compressed_coordinates,
+		ec_GF2m_simple_point2oct,
+		ec_GF2m_simple_oct2point,
+		ec_GF2m_simple_add,
+		ec_GF2m_simple_dbl,
+		ec_GF2m_simple_invert,
+		ec_GF2m_simple_is_at_infinity,
+		ec_GF2m_simple_is_on_curve,
+		ec_GF2m_simple_cmp,
+		ec_GF2m_simple_make_affine,
+		ec_GF2m_simple_points_make_affine,
+
+		/* the following three method functions are defined in ec2_mult.c */
+		ec_GF2m_simple_mul,
+		ec_GF2m_precompute_mult,
+		ec_GF2m_have_precompute_mult,
+
+		ec_GF2m_simple_field_mul,
+		ec_GF2m_simple_field_sqr,
+		ec_GF2m_simple_field_div,
+		0 /* field_encode */,
+		0 /* field_decode */,
+		0 /* field_set_to_one */ };
+
+	return &ret;
+	}
+
+
+/* Initialize a GF(2^m)-based EC_GROUP structure.
+ * Note that all other members are handled by EC_GROUP_new.
+ */
+int ec_GF2m_simple_group_init(EC_GROUP *group)
+	{
+	BN_init(&group->field);
+	BN_init(&group->a);
+	BN_init(&group->b);
+	return 1;
+	}
+
+
+/* Free a GF(2^m)-based EC_GROUP structure.
+ * Note that all other members are handled by EC_GROUP_free.
+ */
+void ec_GF2m_simple_group_finish(EC_GROUP *group)
+	{
+	BN_free(&group->field);
+	BN_free(&group->a);
+	BN_free(&group->b);
+	}
+
+
+/* Clear and free a GF(2^m)-based EC_GROUP structure.
+ * Note that all other members are handled by EC_GROUP_clear_free.
+ */
+void ec_GF2m_simple_group_clear_finish(EC_GROUP *group)
+	{
+	BN_clear_free(&group->field);
+	BN_clear_free(&group->a);
+	BN_clear_free(&group->b);
+	group->poly[0] = 0;
+	group->poly[1] = 0;
+	group->poly[2] = 0;
+	group->poly[3] = 0;
+	group->poly[4] = 0;
+	group->poly[5] = -1;
+	}
+
+
+/* Copy a GF(2^m)-based EC_GROUP structure.
+ * Note that all other members are handled by EC_GROUP_copy.
+ */
+int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
+	{
+	int i;
+	if (!BN_copy(&dest->field, &src->field)) return 0;
+	if (!BN_copy(&dest->a, &src->a)) return 0;
+	if (!BN_copy(&dest->b, &src->b)) return 0;
+	dest->poly[0] = src->poly[0];
+	dest->poly[1] = src->poly[1];
+	dest->poly[2] = src->poly[2];
+	dest->poly[3] = src->poly[3];
+	dest->poly[4] = src->poly[4];
+	dest->poly[5] = src->poly[5];
+	if (bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
+	if (bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
+	for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0;
+	for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0;
+	return 1;
+	}
+
+
+/* Set the curve parameters of an EC_GROUP structure. */
+int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
+	const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+	{
+	int ret = 0, i;
+
+	/* group->field */
+	if (!BN_copy(&group->field, p)) goto err;
+	i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1;
+	if ((i != 5) && (i != 3))
+		{
+		ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
+		goto err;
+		}
+
+	/* group->a */
+	if (!BN_GF2m_mod_arr(&group->a, a, group->poly)) goto err;
+	if(bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err;
+	for (i = group->a.top; i < group->a.dmax; i++) group->a.d[i] = 0;
+	
+	/* group->b */
+	if (!BN_GF2m_mod_arr(&group->b, b, group->poly)) goto err;
+	if(bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err;
+	for (i = group->b.top; i < group->b.dmax; i++) group->b.d[i] = 0;
+		
+	ret = 1;
+  err:
+	return ret;
+	}
+
+
+/* Get the curve parameters of an EC_GROUP structure.
+ * If p, a, or b are NULL then there values will not be set but the method will return with success.
+ */
+int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+	{
+	int ret = 0;
+	
+	if (p != NULL)
+		{
+		if (!BN_copy(p, &group->field)) return 0;
+		}
+
+	if (a != NULL)
+		{
+		if (!BN_copy(a, &group->a)) goto err;
+		}
+
+	if (b != NULL)
+		{
+		if (!BN_copy(b, &group->b)) goto err;
+		}
+	
+	ret = 1;
+	
+  err:
+	return ret;
+	}
+
+
+/* Gets the degree of the field.  For a curve over GF(2^m) this is the value m. */
+int ec_GF2m_simple_group_get_degree(const EC_GROUP *group)
+	{
+	return BN_num_bits(&group->field)-1;
+	}
+
+
+/* Checks the discriminant of the curve.
+ * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p) 
+ */
+int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
+	{
+	int ret = 0;
+	BIGNUM *b;
+	BN_CTX *new_ctx = NULL;
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			{
+			ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+	BN_CTX_start(ctx);
+	b = BN_CTX_get(ctx);
+	if (b == NULL) goto err;
+
+	if (!BN_GF2m_mod_arr(b, &group->b, group->poly)) goto err;
+	
+	/* check the discriminant:
+	 * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p) 
+	 */
+	if (BN_is_zero(b)) goto err;
+
+	ret = 1;
+
+err:
+	if (ctx != NULL)
+		BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+/* Initializes an EC_POINT. */
+int ec_GF2m_simple_point_init(EC_POINT *point)
+	{
+	BN_init(&point->X);
+	BN_init(&point->Y);
+	BN_init(&point->Z);
+	return 1;
+	}
+
+
+/* Frees an EC_POINT. */
+void ec_GF2m_simple_point_finish(EC_POINT *point)
+	{
+	BN_free(&point->X);
+	BN_free(&point->Y);
+	BN_free(&point->Z);
+	}
+
+
+/* Clears and frees an EC_POINT. */
+void ec_GF2m_simple_point_clear_finish(EC_POINT *point)
+	{
+	BN_clear_free(&point->X);
+	BN_clear_free(&point->Y);
+	BN_clear_free(&point->Z);
+	point->Z_is_one = 0;
+	}
+
+
+/* Copy the contents of one EC_POINT into another.  Assumes dest is initialized. */
+int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
+	{
+	if (!BN_copy(&dest->X, &src->X)) return 0;
+	if (!BN_copy(&dest->Y, &src->Y)) return 0;
+	if (!BN_copy(&dest->Z, &src->Z)) return 0;
+	dest->Z_is_one = src->Z_is_one;
+
+	return 1;
+	}
+
+
+/* Set an EC_POINT to the point at infinity.  
+ * A point at infinity is represented by having Z=0.
+ */
+int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
+	{
+	point->Z_is_one = 0;
+	BN_zero(&point->Z);
+	return 1;
+	}
+
+
+/* Set the coordinates of an EC_POINT using affine coordinates. 
+ * Note that the simple implementation only uses affine coordinates.
+ */
+int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
+	{
+	int ret = 0;	
+	if (x == NULL || y == NULL)
+		{
+		ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+
+	if (!BN_copy(&point->X, x)) goto err;
+	BN_set_negative(&point->X, 0);
+	if (!BN_copy(&point->Y, y)) goto err;
+	BN_set_negative(&point->Y, 0);
+	if (!BN_copy(&point->Z, BN_value_one())) goto err;
+	BN_set_negative(&point->Z, 0);
+	point->Z_is_one = 1;
+	ret = 1;
+
+  err:
+	return ret;
+	}
+
+
+/* Gets the affine coordinates of an EC_POINT. 
+ * Note that the simple implementation only uses affine coordinates.
+ */
+int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
+	BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
+	{
+	int ret = 0;
+
+	if (EC_POINT_is_at_infinity(group, point))
+		{
+		ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
+		return 0;
+		}
+
+	if (BN_cmp(&point->Z, BN_value_one())) 
+		{
+		ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (x != NULL)
+		{
+		if (!BN_copy(x, &point->X)) goto err;
+		BN_set_negative(x, 0);
+		}
+	if (y != NULL)
+		{
+		if (!BN_copy(y, &point->Y)) goto err;
+		BN_set_negative(y, 0);
+		}
+	ret = 1;
+		
+ err:
+	return ret;
+	}
+
+
+/* Calculates and sets the affine coordinates of an EC_POINT from the given
+ * compressed coordinates.  Uses algorithm 2.3.4 of SEC 1. 
+ * Note that the simple implementation only uses affine coordinates.
+ *
+ * The method is from the following publication:
+ * 
+ *     Harper, Menezes, Vanstone:
+ *     "Public-Key Cryptosystems with Very Small Key Lengths",
+ *     EUROCRYPT '92, Springer-Verlag LNCS 658,
+ *     published February 1993
+ *
+ * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
+ * the same method, but claim no priority date earlier than July 29, 1994
+ * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
+ */
+int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
+	const BIGNUM *x_, int y_bit, BN_CTX *ctx)
+	{
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *tmp, *x, *y, *z;
+	int ret = 0, z0;
+
+	/* clear error queue */
+	ERR_clear_error();
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+		}
+
+	y_bit = (y_bit != 0) ? 1 : 0;
+
+	BN_CTX_start(ctx);
+	tmp = BN_CTX_get(ctx);
+	x = BN_CTX_get(ctx);
+	y = BN_CTX_get(ctx);
+	z = BN_CTX_get(ctx);
+	if (z == NULL) goto err;
+
+	if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err;
+	if (BN_is_zero(x))
+		{
+		if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err;
+		}
+	else
+		{
+		if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err;
+		if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err;
+		if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err;
+		if (!BN_GF2m_add(tmp, x, tmp)) goto err;
+		if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx))
+			{
+			unsigned long err = ERR_peek_last_error();
+			
+			if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION)
+				{
+				ERR_clear_error();
+				ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
+				}
+			else
+				ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
+			goto err;
+			}
+		z0 = (BN_is_odd(z)) ? 1 : 0;
+		if (!group->meth->field_mul(group, y, x, z, ctx)) goto err;
+		if (z0 != y_bit)
+			{
+			if (!BN_GF2m_add(y, y, x)) goto err;
+			}
+		}
+
+	if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
+
+	ret = 1;
+
+ err:
+	BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+/* Converts an EC_POINT to an octet string.  
+ * If buf is NULL, the encoded length will be returned.
+ * If the length len of buf is smaller than required an error will be returned.
+ */
+size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
+	unsigned char *buf, size_t len, BN_CTX *ctx)
+	{
+	size_t ret;
+	BN_CTX *new_ctx = NULL;
+	int used_ctx = 0;
+	BIGNUM *x, *y, *yxi;
+	size_t field_len, i, skip;
+
+	if ((form != POINT_CONVERSION_COMPRESSED)
+		&& (form != POINT_CONVERSION_UNCOMPRESSED)
+		&& (form != POINT_CONVERSION_HYBRID))
+		{
+		ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
+		goto err;
+		}
+
+	if (EC_POINT_is_at_infinity(group, point))
+		{
+		/* encodes to a single 0 octet */
+		if (buf != NULL)
+			{
+			if (len < 1)
+				{
+				ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+				return 0;
+				}
+			buf[0] = 0;
+			}
+		return 1;
+		}
+
+
+	/* ret := required output buffer length */
+	field_len = (EC_GROUP_get_degree(group) + 7) / 8;
+	ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
+
+	/* if 'buf' is NULL, just return required length */
+	if (buf != NULL)
+		{
+		if (len < ret)
+			{
+			ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+			goto err;
+			}
+
+		if (ctx == NULL)
+			{
+			ctx = new_ctx = BN_CTX_new();
+			if (ctx == NULL)
+				return 0;
+			}
+
+		BN_CTX_start(ctx);
+		used_ctx = 1;
+		x = BN_CTX_get(ctx);
+		y = BN_CTX_get(ctx);
+		yxi = BN_CTX_get(ctx);
+		if (yxi == NULL) goto err;
+
+		if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
+
+		buf[0] = form;
+		if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x))
+			{
+			if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
+			if (BN_is_odd(yxi)) buf[0]++;
+			}
+
+		i = 1;
+		
+		skip = field_len - BN_num_bytes(x);
+		if (skip > field_len)
+			{
+			ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+		while (skip > 0)
+			{
+			buf[i++] = 0;
+			skip--;
+			}
+		skip = BN_bn2bin(x, buf + i);
+		i += skip;
+		if (i != 1 + field_len)
+			{
+			ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+
+		if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
+			{
+			skip = field_len - BN_num_bytes(y);
+			if (skip > field_len)
+				{
+				ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+			while (skip > 0)
+				{
+				buf[i++] = 0;
+				skip--;
+				}
+			skip = BN_bn2bin(y, buf + i);
+			i += skip;
+			}
+
+		if (i != ret)
+			{
+			ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+		}
+	
+	if (used_ctx)
+		BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+
+ err:
+	if (used_ctx)
+		BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return 0;
+	}
+
+
+/* Converts an octet string representation to an EC_POINT. 
+ * Note that the simple implementation only uses affine coordinates.
+ */
+int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
+	const unsigned char *buf, size_t len, BN_CTX *ctx)
+	{
+	point_conversion_form_t form;
+	int y_bit;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *x, *y, *yxi;
+	size_t field_len, enc_len;
+	int ret = 0;
+
+	if (len == 0)
+		{
+		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
+		return 0;
+		}
+	form = buf[0];
+	y_bit = form & 1;
+	form = form & ~1U;
+	if ((form != 0)	&& (form != POINT_CONVERSION_COMPRESSED)
+		&& (form != POINT_CONVERSION_UNCOMPRESSED)
+		&& (form != POINT_CONVERSION_HYBRID))
+		{
+		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+		return 0;
+		}
+	if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
+		{
+		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+		return 0;
+		}
+
+	if (form == 0)
+		{
+		if (len != 1)
+			{
+			ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+			return 0;
+			}
+
+		return EC_POINT_set_to_infinity(group, point);
+		}
+	
+	field_len = (EC_GROUP_get_degree(group) + 7) / 8;
+	enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
+
+	if (len != enc_len)
+		{
+		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+		return 0;
+		}
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+		}
+
+	BN_CTX_start(ctx);
+	x = BN_CTX_get(ctx);
+	y = BN_CTX_get(ctx);
+	yxi = BN_CTX_get(ctx);
+	if (yxi == NULL) goto err;
+
+	if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
+	if (BN_ucmp(x, &group->field) >= 0)
+		{
+		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+		goto err;
+		}
+
+	if (form == POINT_CONVERSION_COMPRESSED)
+		{
+		if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx)) goto err;
+		}
+	else
+		{
+		if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
+		if (BN_ucmp(y, &group->field) >= 0)
+			{
+			ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+			goto err;
+			}
+		if (form == POINT_CONVERSION_HYBRID)
+			{
+			if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
+			if (y_bit != BN_is_odd(yxi))
+				{
+				ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+				goto err;
+				}
+			}
+
+		if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
+		}
+	
+	if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
+		{
+		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
+		goto err;
+		}
+
+	ret = 1;
+	
+ err:
+	BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+/* Computes a + b and stores the result in r.  r could be a or b, a could be b.
+ * Uses algorithm A.10.2 of IEEE P1363.
+ */
+int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
+	{
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t;
+	int ret = 0;
+	
+	if (EC_POINT_is_at_infinity(group, a))
+		{
+		if (!EC_POINT_copy(r, b)) return 0;
+		return 1;
+		}
+
+	if (EC_POINT_is_at_infinity(group, b))
+		{
+		if (!EC_POINT_copy(r, a)) return 0;
+		return 1;
+		}
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+		}
+
+	BN_CTX_start(ctx);
+	x0 = BN_CTX_get(ctx);
+	y0 = BN_CTX_get(ctx);
+	x1 = BN_CTX_get(ctx);
+	y1 = BN_CTX_get(ctx);
+	x2 = BN_CTX_get(ctx);
+	y2 = BN_CTX_get(ctx);
+	s = BN_CTX_get(ctx);
+	t = BN_CTX_get(ctx);
+	if (t == NULL) goto err;
+
+	if (a->Z_is_one) 
+		{
+		if (!BN_copy(x0, &a->X)) goto err;
+		if (!BN_copy(y0, &a->Y)) goto err;
+		}
+	else
+		{
+		if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx)) goto err;
+		}
+	if (b->Z_is_one) 
+		{
+		if (!BN_copy(x1, &b->X)) goto err;
+		if (!BN_copy(y1, &b->Y)) goto err;
+		}
+	else
+		{
+		if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx)) goto err;
+		}
+
+
+	if (BN_GF2m_cmp(x0, x1))
+		{
+		if (!BN_GF2m_add(t, x0, x1)) goto err;
+		if (!BN_GF2m_add(s, y0, y1)) goto err;
+		if (!group->meth->field_div(group, s, s, t, ctx)) goto err;
+		if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
+		if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
+		if (!BN_GF2m_add(x2, x2, s)) goto err;
+		if (!BN_GF2m_add(x2, x2, t)) goto err;
+		}
+	else
+		{
+		if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1))
+			{
+			if (!EC_POINT_set_to_infinity(group, r)) goto err;
+			ret = 1;
+			goto err;
+			}
+		if (!group->meth->field_div(group, s, y1, x1, ctx)) goto err;
+		if (!BN_GF2m_add(s, s, x1)) goto err;
+		
+		if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
+		if (!BN_GF2m_add(x2, x2, s)) goto err;
+		if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
+		}
+
+	if (!BN_GF2m_add(y2, x1, x2)) goto err;
+	if (!group->meth->field_mul(group, y2, y2, s, ctx)) goto err;
+	if (!BN_GF2m_add(y2, y2, x2)) goto err;
+	if (!BN_GF2m_add(y2, y2, y1)) goto err;
+
+	if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx)) goto err;
+
+	ret = 1;
+
+ err:
+	BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+/* Computes 2 * a and stores the result in r.  r could be a.
+ * Uses algorithm A.10.2 of IEEE P1363.
+ */
+int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
+	{
+	return ec_GF2m_simple_add(group, r, a, a, ctx);
+	}
+
+
+int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
+	{
+	if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))
+		/* point is its own inverse */
+		return 1;
+	
+	if (!EC_POINT_make_affine(group, point, ctx)) return 0;
+	return BN_GF2m_add(&point->Y, &point->X, &point->Y);
+	}
+
+
+/* Indicates whether the given point is the point at infinity. */
+int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
+	{
+	return BN_is_zero(&point->Z);
+	}
+
+
+/* Determines whether the given EC_POINT is an actual point on the curve defined
+ * in the EC_GROUP.  A point is valid if it satisfies the Weierstrass equation:
+ *      y^2 + x*y = x^3 + a*x^2 + b.
+ */
+int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
+	{
+	int ret = -1;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *lh, *y2;
+	int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
+	int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+
+	if (EC_POINT_is_at_infinity(group, point))
+		return 1;
+
+	field_mul = group->meth->field_mul;
+	field_sqr = group->meth->field_sqr;	
+
+	/* only support affine coordinates */
+	if (!point->Z_is_one) return -1;
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return -1;
+		}
+
+	BN_CTX_start(ctx);
+	y2 = BN_CTX_get(ctx);
+	lh = BN_CTX_get(ctx);
+	if (lh == NULL) goto err;
+
+	/* We have a curve defined by a Weierstrass equation
+	 *      y^2 + x*y = x^3 + a*x^2 + b.
+	 *  <=> x^3 + a*x^2 + x*y + b + y^2 = 0
+	 *  <=> ((x + a) * x + y ) * x + b + y^2 = 0
+	 */
+	if (!BN_GF2m_add(lh, &point->X, &group->a)) goto err;
+	if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;
+	if (!BN_GF2m_add(lh, lh, &point->Y)) goto err;
+	if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;
+	if (!BN_GF2m_add(lh, lh, &group->b)) goto err;
+	if (!field_sqr(group, y2, &point->Y, ctx)) goto err;
+	if (!BN_GF2m_add(lh, lh, y2)) goto err;
+	ret = BN_is_zero(lh);
+ err:
+	if (ctx) BN_CTX_end(ctx);
+	if (new_ctx) BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+/* Indicates whether two points are equal.
+ * Return values:
+ *  -1   error
+ *   0   equal (in affine coordinates)
+ *   1   not equal
+ */
+int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
+	{
+	BIGNUM *aX, *aY, *bX, *bY;
+	BN_CTX *new_ctx = NULL;
+	int ret = -1;
+
+	if (EC_POINT_is_at_infinity(group, a))
+		{
+		return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
+		}
+
+	if (EC_POINT_is_at_infinity(group, b))
+		return 1;
+	
+	if (a->Z_is_one && b->Z_is_one)
+		{
+		return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
+		}
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return -1;
+		}
+
+	BN_CTX_start(ctx);
+	aX = BN_CTX_get(ctx);
+	aY = BN_CTX_get(ctx);
+	bX = BN_CTX_get(ctx);
+	bY = BN_CTX_get(ctx);
+	if (bY == NULL) goto err;
+
+	if (!EC_POINT_get_affine_coordinates_GF2m(group, a, aX, aY, ctx)) goto err;
+	if (!EC_POINT_get_affine_coordinates_GF2m(group, b, bX, bY, ctx)) goto err;
+	ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1;
+
+  err:	
+	if (ctx) BN_CTX_end(ctx);
+	if (new_ctx) BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+/* Forces the given EC_POINT to internally use affine coordinates. */
+int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
+	{
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *x, *y;
+	int ret = 0;
+
+	if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
+		return 1;
+	
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+		}
+
+	BN_CTX_start(ctx);
+	x = BN_CTX_get(ctx);
+	y = BN_CTX_get(ctx);
+	if (y == NULL) goto err;
+	
+	if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
+	if (!BN_copy(&point->X, x)) goto err;
+	if (!BN_copy(&point->Y, y)) goto err;
+	if (!BN_one(&point->Z)) goto err;
+	
+	ret = 1;		
+
+  err:
+	if (ctx) BN_CTX_end(ctx);
+	if (new_ctx) BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+/* Forces each of the EC_POINTs in the given array to use affine coordinates. */
+int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
+	{
+	size_t i;
+
+	for (i = 0; i < num; i++)
+		{
+		if (!group->meth->make_affine(group, points[i], ctx)) return 0;
+		}
+
+	return 1;
+	}
+
+
+/* Wrapper to simple binary polynomial field multiplication implementation. */
+int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+	{
+	return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx);
+	}
+
+
+/* Wrapper to simple binary polynomial field squaring implementation. */
+int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
+	{
+	return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx);
+	}
+
+
+/* Wrapper to simple binary polynomial field division implementation. */
+int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+	{
+	return BN_GF2m_mod_div(r, a, b, &group->field, ctx);
+	}
diff --git a/openssl/crypto/ec/ec_ameth.c b/openssl/crypto/ec/ec_ameth.c
new file mode 100644
index 0000000..c00f7d7
--- /dev/null
+++ b/openssl/crypto/ec/ec_ameth.c
@@ -0,0 +1,659 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/ec.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_CMS
+#include <openssl/cms.h>
+#endif
+#include "asn1_locl.h"
+
+static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
+	{
+	const EC_GROUP  *group;
+	int nid;
+	if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) 
+	{
+		ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS);
+		return 0;
+	}
+	if (EC_GROUP_get_asn1_flag(group)
+                     && (nid = EC_GROUP_get_curve_name(group)))
+		/* we have a 'named curve' => just set the OID */
+		{
+		*ppval = OBJ_nid2obj(nid);
+		*pptype = V_ASN1_OBJECT;
+		}
+	else	/* explicit parameters */
+		{
+		ASN1_STRING *pstr = NULL;
+		pstr = ASN1_STRING_new();
+		if (!pstr)
+			return 0;
+		pstr->length = i2d_ECParameters(ec_key, &pstr->data);
+		if (pstr->length < 0)
+			{
+			ASN1_STRING_free(pstr);
+			ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
+			return 0;
+			}
+		*ppval = pstr;
+		*pptype = V_ASN1_SEQUENCE;
+		}
+	return 1;
+	}
+
+static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+	{
+	EC_KEY *ec_key = pkey->pkey.ec;
+	void *pval = NULL;
+	int ptype;
+	unsigned char *penc = NULL, *p;
+	int penclen;
+
+	if (!eckey_param2type(&ptype, &pval, ec_key))
+		{
+		ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB);
+		return 0;
+		}
+	penclen = i2o_ECPublicKey(ec_key, NULL);
+	if (penclen <= 0)
+		goto err;
+	penc = OPENSSL_malloc(penclen);
+	if (!penc)
+		goto err;
+	p = penc;
+	penclen = i2o_ECPublicKey(ec_key, &p);
+	if (penclen <= 0)
+		goto err;
+	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
+				ptype, pval, penc, penclen))
+		return 1;
+	err:
+	if (ptype == V_ASN1_OBJECT)
+		ASN1_OBJECT_free(pval);
+	else
+		ASN1_STRING_free(pval);
+	if (penc)
+		OPENSSL_free(penc);
+	return 0;
+	}
+
+static EC_KEY *eckey_type2param(int ptype, void *pval)
+	{
+	EC_KEY *eckey = NULL;
+	if (ptype == V_ASN1_SEQUENCE)
+		{
+		ASN1_STRING *pstr = pval;
+		const unsigned char *pm = NULL;
+		int pmlen;
+		pm = pstr->data;
+		pmlen = pstr->length;
+		if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen)))
+			{
+			ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
+			goto ecerr;
+			}
+		}
+	else if (ptype == V_ASN1_OBJECT)
+		{
+		ASN1_OBJECT *poid = pval;
+		EC_GROUP *group;
+
+		/* type == V_ASN1_OBJECT => the parameters are given
+		 * by an asn1 OID
+		 */
+		if ((eckey = EC_KEY_new()) == NULL)
+			{
+			ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
+			goto ecerr;
+			}
+		group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
+		if (group == NULL)
+			goto ecerr;
+		EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
+		if (EC_KEY_set_group(eckey, group) == 0)
+			goto ecerr;
+		EC_GROUP_free(group);
+		}
+	else
+		{
+		ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
+		goto ecerr;
+		}
+
+	return eckey;
+
+	ecerr:
+	if (eckey)
+		EC_KEY_free(eckey);
+	return NULL;
+	}
+
+static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+	{
+	const unsigned char *p = NULL;
+	void *pval;
+	int ptype, pklen;
+	EC_KEY *eckey = NULL;
+	X509_ALGOR *palg;
+
+	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
+		return 0;
+	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+	eckey = eckey_type2param(ptype, pval);
+
+	if (!eckey)
+		{
+		ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
+		return 0;
+		}
+
+	/* We have parameters now set public key */
+	if (!o2i_ECPublicKey(&eckey, &p, pklen))
+		{
+		ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
+		goto ecerr;
+		}
+
+	EVP_PKEY_assign_EC_KEY(pkey, eckey);
+	return 1;
+
+	ecerr:
+	if (eckey)
+		EC_KEY_free(eckey);
+	return 0;
+	}
+
+static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+	{
+	int  r;
+	const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
+	const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
+	               *pb = EC_KEY_get0_public_key(b->pkey.ec);
+	r = EC_POINT_cmp(group, pa, pb, NULL);
+	if (r == 0)
+		return 1;
+	if (r == 1)
+		return 0;
+	return -2;
+	}
+
+static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
+	{
+	const unsigned char *p = NULL;
+	void *pval;
+	int ptype, pklen;
+	EC_KEY *eckey = NULL;
+	X509_ALGOR *palg;
+
+	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
+		return 0;
+	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+	eckey = eckey_type2param(ptype, pval);
+
+	if (!eckey)
+		goto ecliberr;
+
+	/* We have parameters now set private key */
+	if (!d2i_ECPrivateKey(&eckey, &p, pklen))
+		{
+		ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
+		goto ecerr;
+		}
+
+	/* calculate public key (if necessary) */
+	if (EC_KEY_get0_public_key(eckey) == NULL)
+		{
+		const BIGNUM *priv_key;
+		const EC_GROUP *group;
+		EC_POINT *pub_key;
+		/* the public key was not included in the SEC1 private
+		 * key => calculate the public key */
+		group   = EC_KEY_get0_group(eckey);
+		pub_key = EC_POINT_new(group);
+		if (pub_key == NULL)
+			{
+			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
+			goto ecliberr;
+			}
+		if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
+			{
+			EC_POINT_free(pub_key);
+			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
+			goto ecliberr;
+			}
+		priv_key = EC_KEY_get0_private_key(eckey);
+		if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL))
+			{
+			EC_POINT_free(pub_key);
+			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
+			goto ecliberr;
+			}
+		if (EC_KEY_set_public_key(eckey, pub_key) == 0)
+			{
+			EC_POINT_free(pub_key);
+			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
+			goto ecliberr;
+			}
+		EC_POINT_free(pub_key);
+		}
+
+	EVP_PKEY_assign_EC_KEY(pkey, eckey);
+	return 1;
+
+	ecliberr:
+	ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
+	ecerr:
+	if (eckey)
+		EC_KEY_free(eckey);
+	return 0;
+	}
+
+static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+{
+	EC_KEY		*ec_key;
+	unsigned char	*ep, *p;
+	int 		eplen, ptype;
+	void		*pval;
+	unsigned int    tmp_flags, old_flags;
+
+	ec_key = pkey->pkey.ec;
+
+	if (!eckey_param2type(&ptype, &pval, ec_key))
+		{
+		ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
+		return 0;
+		}
+
+	/* set the private key */
+
+	/* do not include the parameters in the SEC1 private key
+	 * see PKCS#11 12.11 */
+	old_flags = EC_KEY_get_enc_flags(ec_key);
+	tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
+	EC_KEY_set_enc_flags(ec_key, tmp_flags);
+	eplen = i2d_ECPrivateKey(ec_key, NULL);
+	if (!eplen)
+	{
+		EC_KEY_set_enc_flags(ec_key, old_flags);
+		ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
+		return 0;
+	}
+	ep = (unsigned char *) OPENSSL_malloc(eplen);
+	if (!ep)
+	{
+		EC_KEY_set_enc_flags(ec_key, old_flags);
+		ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	p = ep;
+	if (!i2d_ECPrivateKey(ec_key, &p))
+	{
+		EC_KEY_set_enc_flags(ec_key, old_flags);
+		OPENSSL_free(ep);
+		ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
+	}
+	/* restore old encoding flags */
+	EC_KEY_set_enc_flags(ec_key, old_flags);
+
+	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
+				ptype, pval, ep, eplen))
+		return 0;
+
+	return 1;
+}
+
+static int int_ec_size(const EVP_PKEY *pkey)
+	{
+	return ECDSA_size(pkey->pkey.ec);
+	}
+
+static int ec_bits(const EVP_PKEY *pkey)
+	{
+	BIGNUM *order = BN_new();
+	const EC_GROUP *group;
+	int ret;
+
+	if (!order)
+		{
+		ERR_clear_error();
+		return 0;
+		}
+	group = EC_KEY_get0_group(pkey->pkey.ec);
+	if (!EC_GROUP_get_order(group, order, NULL))
+		{
+		ERR_clear_error();
+		return 0;
+		}
+
+	ret = BN_num_bits(order);
+	BN_free(order);
+	return ret;
+	}
+
+static int ec_missing_parameters(const EVP_PKEY *pkey)
+	{
+	if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
+		return 1;
+	return 0;
+	}
+
+static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+	{
+	EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
+	if (group == NULL)
+		return 0;
+	if (EC_KEY_set_group(to->pkey.ec, group) == 0)
+		return 0;
+	EC_GROUP_free(group);
+	return 1;
+	}
+
+static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+	{
+	const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
+	               *group_b = EC_KEY_get0_group(b->pkey.ec);
+	if (EC_GROUP_cmp(group_a, group_b, NULL))
+		return 0;
+	else
+		return 1;
+	}
+
+static void int_ec_free(EVP_PKEY *pkey)
+	{
+	EC_KEY_free(pkey->pkey.ec);
+	}
+
+static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
+	{
+	unsigned char *buffer=NULL;
+	const char *ecstr;
+	size_t	buf_len=0, i;
+	int     ret=0, reason=ERR_R_BIO_LIB;
+	BIGNUM  *pub_key=NULL, *order=NULL;
+	BN_CTX  *ctx=NULL;
+	const EC_GROUP *group;
+	const EC_POINT *public_key;
+	const BIGNUM *priv_key;
+ 
+	if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
+		{
+		reason = ERR_R_PASSED_NULL_PARAMETER;
+		goto err;
+		}
+
+	ctx = BN_CTX_new();
+	if (ctx == NULL)
+		{
+		reason = ERR_R_MALLOC_FAILURE;
+		goto err;
+		}
+
+	if (ktype > 0)
+		{
+		public_key = EC_KEY_get0_public_key(x);
+		if ((pub_key = EC_POINT_point2bn(group, public_key,
+			EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
+			{
+			reason = ERR_R_EC_LIB;
+			goto err;
+			}
+		if (pub_key)
+			buf_len = (size_t)BN_num_bytes(pub_key);
+		}
+
+	if (ktype == 2)
+		{
+		priv_key = EC_KEY_get0_private_key(x);
+		if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len)
+			buf_len = i;
+		}
+	else
+		priv_key = NULL;
+
+	if (ktype > 0)
+		{
+		buf_len += 10;
+		if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
+			{
+			reason = ERR_R_MALLOC_FAILURE;
+			goto err;
+			}
+		}
+	if (ktype == 2)
+		ecstr = "Private-Key";
+	else if (ktype == 1)
+		ecstr = "Public-Key";
+	else
+		ecstr = "ECDSA-Parameters";
+
+	if (!BIO_indent(bp, off, 128))
+		goto err;
+	if ((order = BN_new()) == NULL)
+		goto err;
+	if (!EC_GROUP_get_order(group, order, NULL))
+		goto err;
+	if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
+		BN_num_bits(order)) <= 0) goto err;
+  
+	if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, 
+		buffer, off))
+		goto err;
+	if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
+		buffer, off))
+		goto err;
+	if (!ECPKParameters_print(bp, group, off))
+		goto err;
+	ret=1;
+err:
+	if (!ret)
+ 		ECerr(EC_F_DO_EC_KEY_PRINT, reason);
+	if (pub_key) 
+		BN_free(pub_key);
+	if (order)
+		BN_free(order);
+	if (ctx)
+		BN_CTX_free(ctx);
+	if (buffer != NULL)
+		OPENSSL_free(buffer);
+	return(ret);
+	}
+
+static int eckey_param_decode(EVP_PKEY *pkey,
+					const unsigned char **pder, int derlen)
+	{
+	EC_KEY *eckey;
+	if (!(eckey = d2i_ECParameters(NULL, pder, derlen)))
+		{
+		ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
+		return 0;
+		}
+	EVP_PKEY_assign_EC_KEY(pkey, eckey);
+	return 1;
+	}
+
+static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+	{
+	return i2d_ECParameters(pkey->pkey.ec, pder);
+	}
+
+static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
+	}
+
+static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
+	}
+
+
+static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
+	}
+
+static int old_ec_priv_decode(EVP_PKEY *pkey,
+					const unsigned char **pder, int derlen)
+	{
+	EC_KEY *ec;
+	if (!(ec = d2i_ECPrivateKey (NULL, pder, derlen)))
+		{
+		ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
+		return 0;
+		}
+	EVP_PKEY_assign_EC_KEY(pkey, ec);
+	return 1;
+	}
+
+static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
+	{
+	return i2d_ECPrivateKey(pkey->pkey.ec, pder);
+	}
+
+static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+	{
+	switch (op)
+		{
+		case ASN1_PKEY_CTRL_PKCS7_SIGN:
+		if (arg1 == 0)
+			{
+			int snid, hnid;
+			X509_ALGOR *alg1, *alg2;
+			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
+			if (alg1 == NULL || alg1->algorithm == NULL)
+				return -1;
+			hnid = OBJ_obj2nid(alg1->algorithm);
+			if (hnid == NID_undef)
+				return -1;
+			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
+				return -1; 
+			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
+			}
+		return 1;
+#ifndef OPENSSL_NO_CMS
+		case ASN1_PKEY_CTRL_CMS_SIGN:
+		if (arg1 == 0)
+			{
+			int snid, hnid;
+			X509_ALGOR *alg1, *alg2;
+			CMS_SignerInfo_get0_algs(arg2, NULL, NULL,
+								&alg1, &alg2);
+			if (alg1 == NULL || alg1->algorithm == NULL)
+				return -1;
+			hnid = OBJ_obj2nid(alg1->algorithm);
+			if (hnid == NID_undef)
+				return -1;
+			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
+				return -1; 
+			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
+			}
+		return 1;
+#endif
+
+		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+		*(int *)arg2 = NID_sha1;
+		return 2;
+
+		default:
+		return -2;
+
+		}
+
+	}
+
+const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = 
+	{
+	EVP_PKEY_EC,
+	EVP_PKEY_EC,
+	0,
+	"EC",
+	"OpenSSL EC algorithm",
+
+	eckey_pub_decode,
+	eckey_pub_encode,
+	eckey_pub_cmp,
+	eckey_pub_print,
+
+	eckey_priv_decode,
+	eckey_priv_encode,
+	eckey_priv_print,
+
+	int_ec_size,
+	ec_bits,
+
+	eckey_param_decode,
+	eckey_param_encode,
+	ec_missing_parameters,
+	ec_copy_parameters,
+	ec_cmp_parameters,
+	eckey_param_print,
+
+	int_ec_free,
+	ec_pkey_ctrl,
+	old_ec_priv_decode,
+	old_ec_priv_encode
+	};
diff --git a/openssl/crypto/ec/ec_asn1.c b/openssl/crypto/ec/ec_asn1.c
new file mode 100644
index 0000000..ae55539
--- /dev/null
+++ b/openssl/crypto/ec/ec_asn1.c
@@ -0,0 +1,1429 @@
+/* crypto/ec/ec_asn1.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+#include "ec_lcl.h"
+#include <openssl/err.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+
+
+int EC_GROUP_get_basis_type(const EC_GROUP *group)
+	{
+	int i=0;
+
+	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
+		NID_X9_62_characteristic_two_field)
+		/* everything else is currently not supported */
+		return 0;
+
+	while (group->poly[i] != 0)
+		i++;
+
+	if (i == 4)
+		return NID_X9_62_ppBasis;
+	else if (i == 2)
+		return NID_X9_62_tpBasis;
+	else
+		/* everything else is currently not supported */
+		return 0;
+	}
+
+int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
+	{
+	if (group == NULL)
+		return 0;
+
+	if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve
+	    || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0)))
+		{
+		ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+
+	if (k)
+		*k = group->poly[1];
+
+	return 1;
+	}
+
+int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
+	unsigned int *k2, unsigned int *k3)
+	{
+	if (group == NULL)
+		return 0;
+
+	if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve
+	    || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] != 0) && (group->poly[3] != 0) && (group->poly[4] == 0)))
+		{
+		ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+
+	if (k1)
+		*k1 = group->poly[3];
+	if (k2)
+		*k2 = group->poly[2];
+	if (k3)
+		*k3 = group->poly[1];
+
+	return 1;
+	}
+
+
+
+/* some structures needed for the asn1 encoding */
+typedef struct x9_62_pentanomial_st {
+	long k1;
+	long k2;
+	long k3;
+	} X9_62_PENTANOMIAL;
+
+typedef struct x9_62_characteristic_two_st {
+	long m;
+	ASN1_OBJECT  *type;
+	union	{
+		char *ptr;
+		/* NID_X9_62_onBasis */
+		ASN1_NULL    *onBasis;
+		/* NID_X9_62_tpBasis */
+		ASN1_INTEGER *tpBasis;
+		/* NID_X9_62_ppBasis */
+		X9_62_PENTANOMIAL *ppBasis;
+		/* anything else */
+		ASN1_TYPE *other;
+		} p;
+	} X9_62_CHARACTERISTIC_TWO;
+
+typedef struct x9_62_fieldid_st {
+        ASN1_OBJECT *fieldType;
+	union	{
+		char *ptr;
+		/* NID_X9_62_prime_field */
+		ASN1_INTEGER *prime;
+		/* NID_X9_62_characteristic_two_field */
+		X9_62_CHARACTERISTIC_TWO *char_two;
+		/* anything else */
+		ASN1_TYPE *other;
+		} p;
+	} X9_62_FIELDID;
+
+typedef struct x9_62_curve_st {
+        ASN1_OCTET_STRING *a;
+        ASN1_OCTET_STRING *b;
+        ASN1_BIT_STRING   *seed;
+        } X9_62_CURVE;
+
+typedef struct ec_parameters_st {
+        long              version;
+        X9_62_FIELDID     *fieldID;
+        X9_62_CURVE       *curve;
+        ASN1_OCTET_STRING *base;
+        ASN1_INTEGER      *order;
+        ASN1_INTEGER      *cofactor;
+        } ECPARAMETERS;
+
+struct ecpk_parameters_st {
+	int	type;
+	union {
+		ASN1_OBJECT  *named_curve;
+		ECPARAMETERS *parameters;
+		ASN1_NULL    *implicitlyCA;
+	} value;
+	}/* ECPKPARAMETERS */;
+
+/* SEC1 ECPrivateKey */
+typedef struct ec_privatekey_st {
+	long              version;
+	ASN1_OCTET_STRING *privateKey;
+        ECPKPARAMETERS    *parameters;
+	ASN1_BIT_STRING   *publicKey;
+	} EC_PRIVATEKEY;
+
+/* the OpenSSL ASN.1 definitions */
+ASN1_SEQUENCE(X9_62_PENTANOMIAL) = {
+	ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG),
+	ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG),
+	ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG)
+} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL)
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
+
+ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY);
+
+ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = {
+	ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)),
+	ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)),
+	ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL))
+} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL);
+
+ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = {
+	ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG),
+	ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT),
+	ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO)
+} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO)
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
+
+ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);
+
+ASN1_ADB(X9_62_FIELDID) = {
+	ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)),
+	ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO))
+} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL);
+
+ASN1_SEQUENCE(X9_62_FIELDID) = {
+	ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
+	ASN1_ADB_OBJECT(X9_62_FIELDID)
+} ASN1_SEQUENCE_END(X9_62_FIELDID)
+
+ASN1_SEQUENCE(X9_62_CURVE) = {
+	ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
+	ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
+	ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END(X9_62_CURVE)
+
+ASN1_SEQUENCE(ECPARAMETERS) = {
+	ASN1_SIMPLE(ECPARAMETERS, version, LONG),
+	ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
+	ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
+	ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
+	ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
+	ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(ECPARAMETERS)
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
+
+ASN1_CHOICE(ECPKPARAMETERS) = {
+	ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
+	ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
+	ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL)
+} ASN1_CHOICE_END(ECPKPARAMETERS)
+
+DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
+IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
+
+ASN1_SEQUENCE(EC_PRIVATEKEY) = {
+	ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
+	ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
+	ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
+	ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
+} ASN1_SEQUENCE_END(EC_PRIVATEKEY)
+
+DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
+IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
+
+/* some declarations of internal function */
+
+/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */ 
+static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *);
+/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */ 
+static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
+/* ec_asn1_parameters2group() creates a EC_GROUP object from a
+ * ECPARAMETERS object */
+static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *); 
+/* ec_asn1_group2parameters() creates a ECPARAMETERS object from a 
+ * EC_GROUP object */
+static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *,ECPARAMETERS *);
+/* ec_asn1_pkparameters2group() creates a EC_GROUP object from a
+ * ECPKPARAMETERS object */
+static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *); 
+/* ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a 
+ * EC_GROUP object */
+static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *, 
+	ECPKPARAMETERS *);
+
+
+/* the function definitions */
+
+static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
+	{
+	int			ok=0, nid;
+	BIGNUM			*tmp = NULL;
+	
+	if (group == NULL || field == NULL)
+		return 0;
+
+	/* clear the old values (if necessary) */
+	if (field->fieldType != NULL)
+		ASN1_OBJECT_free(field->fieldType);
+	if (field->p.other != NULL)
+		ASN1_TYPE_free(field->p.other);
+
+	nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
+	/* set OID for the field */
+	if ((field->fieldType = OBJ_nid2obj(nid)) == NULL)
+		{
+		ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
+		goto err;
+		}
+
+	if (nid == NID_X9_62_prime_field)
+		{
+		if ((tmp = BN_new()) == NULL) 
+			{
+			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		/* the parameters are specified by the prime number p */
+		if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL))
+			{
+			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
+			goto err;
+			}
+		/* set the prime number */
+		field->p.prime = BN_to_ASN1_INTEGER(tmp,NULL);
+		if (field->p.prime == NULL)
+			{
+			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
+			goto err;
+			}
+		}
+	else	/* nid == NID_X9_62_characteristic_two_field */
+		{
+		int		field_type;
+		X9_62_CHARACTERISTIC_TWO *char_two;
+
+		field->p.char_two = X9_62_CHARACTERISTIC_TWO_new();
+		char_two = field->p.char_two;
+
+		if (char_two == NULL)
+			{
+			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+	
+		char_two->m = (long)EC_GROUP_get_degree(group);
+
+		field_type = EC_GROUP_get_basis_type(group);
+
+		if (field_type == 0)
+			{
+			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
+			goto err;
+			}
+		/* set base type OID */
+		if ((char_two->type = OBJ_nid2obj(field_type)) == NULL)
+			{
+			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
+			goto err;
+			}
+
+		if (field_type == NID_X9_62_tpBasis)
+			{
+			unsigned int k;
+
+			if (!EC_GROUP_get_trinomial_basis(group, &k))
+				goto err;
+
+			char_two->p.tpBasis = ASN1_INTEGER_new();
+			if (!char_two->p.tpBasis)
+				{
+				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k))
+				{
+				ECerr(EC_F_EC_ASN1_GROUP2FIELDID,
+					ERR_R_ASN1_LIB);
+				goto err;
+				}
+			}
+		else if (field_type == NID_X9_62_ppBasis)
+			{
+			unsigned int k1, k2, k3;
+
+			if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))
+				goto err;
+
+			char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
+			if (!char_two->p.ppBasis)
+				{
+				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+
+			/* set k? values */
+			char_two->p.ppBasis->k1 = (long)k1;
+			char_two->p.ppBasis->k2 = (long)k2;
+			char_two->p.ppBasis->k3 = (long)k3;
+			}
+		else /* field_type == NID_X9_62_onBasis */
+			{
+			/* for ONB the parameters are (asn1) NULL */
+			char_two->p.onBasis = ASN1_NULL_new();
+			if (!char_two->p.onBasis)
+				{
+				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			}
+		}
+
+	ok = 1;
+
+err :	if (tmp)
+		BN_free(tmp);
+	return(ok);
+}
+
+static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
+	{
+	int           ok=0, nid;
+	BIGNUM        *tmp_1=NULL, *tmp_2=NULL;
+	unsigned char *buffer_1=NULL, *buffer_2=NULL,
+	              *a_buf=NULL, *b_buf=NULL;
+	size_t        len_1, len_2;
+	unsigned char char_zero = 0;
+
+	if (!group || !curve || !curve->a || !curve->b)
+		return 0;
+
+	if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL)
+		{
+		ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
+
+	/* get a and b */
+	if (nid == NID_X9_62_prime_field)
+		{
+		if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL))
+			{
+			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
+			goto err;
+			}
+		}
+	else	/* nid == NID_X9_62_characteristic_two_field */
+		{
+		if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL))
+			{
+			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
+			goto err;
+			}
+		}
+
+	len_1 = (size_t)BN_num_bytes(tmp_1);
+	len_2 = (size_t)BN_num_bytes(tmp_2);
+
+	if (len_1 == 0)
+		{
+		/* len_1 == 0 => a == 0 */
+		a_buf = &char_zero;
+		len_1 = 1;
+		}
+	else
+		{
+		if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL)
+			{
+			ECerr(EC_F_EC_ASN1_GROUP2CURVE,
+			      ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		if ( (len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0)
+			{
+			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
+			goto err;
+			}
+		a_buf = buffer_1;
+		}
+
+	if (len_2 == 0)
+		{
+		/* len_2 == 0 => b == 0 */
+		b_buf = &char_zero;
+		len_2 = 1;
+		}
+	else
+		{
+		if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL)
+			{
+			ECerr(EC_F_EC_ASN1_GROUP2CURVE,
+			      ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		if ( (len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0)
+			{
+			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
+			goto err;
+			}
+		b_buf = buffer_2;
+		}
+	
+	/* set a and b */
+	if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) ||
+	    !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2))
+		{
+		ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
+		goto err;
+		}
+	
+	/* set the seed (optional) */
+	if (group->seed)
+		{	
+		if (!curve->seed)
+			if ((curve->seed = ASN1_BIT_STRING_new()) == NULL)
+				{
+				ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+		curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
+		curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+		if (!ASN1_BIT_STRING_set(curve->seed, group->seed, 
+		                         (int)group->seed_len))
+			{
+			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
+			goto err;
+			}
+		}
+	else
+		{
+		if (curve->seed)
+			{
+			ASN1_BIT_STRING_free(curve->seed);
+			curve->seed = NULL;
+			}
+		}
+
+	ok = 1;
+
+err:	if (buffer_1)
+		OPENSSL_free(buffer_1);
+	if (buffer_2)
+		OPENSSL_free(buffer_2);
+	if (tmp_1)
+		BN_free(tmp_1);
+	if (tmp_2)
+		BN_free(tmp_2);
+	return(ok);
+	}
+
+static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group,
+                                              ECPARAMETERS *param)
+	{
+	int	ok=0;
+	size_t  len=0;
+	ECPARAMETERS   *ret=NULL;
+	BIGNUM	       *tmp=NULL;
+	unsigned char  *buffer=NULL;
+	const EC_POINT *point=NULL;
+	point_conversion_form_t form;
+
+	if ((tmp = BN_new()) == NULL)
+		{
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (param == NULL)
+	{
+		if ((ret = ECPARAMETERS_new()) == NULL)
+			{
+			ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, 
+			      ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+	}
+	else
+		ret = param;
+
+	/* set the version (always one) */
+	ret->version = (long)0x1;
+
+	/* set the fieldID */
+	if (!ec_asn1_group2fieldid(group, ret->fieldID))
+		{
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
+		goto err;
+		}
+
+	/* set the curve */
+	if (!ec_asn1_group2curve(group, ret->curve))
+		{
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
+		goto err;
+		}
+
+	/* set the base point */
+	if ((point = EC_GROUP_get0_generator(group)) == NULL)
+		{
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR);
+		goto err;
+		}
+
+	form = EC_GROUP_get_point_conversion_form(group);
+
+	len = EC_POINT_point2oct(group, point, form, NULL, len, NULL);
+	if (len == 0)
+		{
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
+		goto err;
+		}
+	if ((buffer = OPENSSL_malloc(len)) == NULL)
+		{
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL))
+		{
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
+		goto err;
+		}
+	if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL)
+		{
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	if (!ASN1_OCTET_STRING_set(ret->base, buffer, len))
+		{
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
+		goto err;
+		}
+
+	/* set the order */
+	if (!EC_GROUP_get_order(group, tmp, NULL))
+		{
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
+		goto err;
+		}
+	ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
+	if (ret->order == NULL)
+		{
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
+		goto err;
+		}
+
+	/* set the cofactor (optional) */
+	if (EC_GROUP_get_cofactor(group, tmp, NULL))
+		{
+		ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
+		if (ret->cofactor == NULL)
+			{
+			ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
+			goto err;
+			}
+		}
+
+	ok = 1;
+
+err :	if(!ok)
+		{
+		if (ret && !param)
+			ECPARAMETERS_free(ret);
+		ret = NULL;
+		}
+	if (tmp)
+		BN_free(tmp);
+	if (buffer)
+		OPENSSL_free(buffer);
+	return(ret);
+	}
+
+ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group, 
+                                           ECPKPARAMETERS *params)
+	{
+	int            ok = 1, tmp;
+	ECPKPARAMETERS *ret = params;
+
+	if (ret == NULL)
+		{
+		if ((ret = ECPKPARAMETERS_new()) == NULL)
+			{
+			ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS, 
+			      ERR_R_MALLOC_FAILURE);
+			return NULL;
+			}
+		}
+	else
+		{
+		if (ret->type == 0 && ret->value.named_curve)
+			ASN1_OBJECT_free(ret->value.named_curve);
+		else if (ret->type == 1 && ret->value.parameters)
+			ECPARAMETERS_free(ret->value.parameters);
+		}
+
+	if (EC_GROUP_get_asn1_flag(group))
+		{
+		/* use the asn1 OID to describe the
+		 * the elliptic curve parameters
+		 */
+		tmp = EC_GROUP_get_curve_name(group);
+		if (tmp)
+			{
+			ret->type = 0;
+			if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
+				ok = 0;
+			}
+		else
+			/* we don't kmow the nid => ERROR */
+			ok = 0;
+		}
+	else
+		{	
+		/* use the ECPARAMETERS structure */
+		ret->type = 1;
+		if ((ret->value.parameters = ec_asn1_group2parameters(
+		     group, NULL)) == NULL)
+			ok = 0;
+		}
+
+	if (!ok)
+		{
+		ECPKPARAMETERS_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
+	{
+	int			ok = 0, tmp;
+	EC_GROUP		*ret = NULL;
+	BIGNUM			*p = NULL, *a = NULL, *b = NULL;
+	EC_POINT		*point=NULL;
+	long    		field_bits;
+
+	if (!params->fieldID || !params->fieldID->fieldType || 
+	    !params->fieldID->p.ptr)
+		{
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+		goto err;
+		}
+
+	/* now extract the curve parameters a and b */
+	if (!params->curve || !params->curve->a || 
+	    !params->curve->a->data || !params->curve->b ||
+	    !params->curve->b->data)
+		{
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+		goto err;
+		}
+	a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
+	if (a == NULL)
+		{
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
+		goto err;
+		}
+	b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
+	if (b == NULL)
+		{
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
+		goto err;
+		}
+
+	/* get the field parameters */
+	tmp = OBJ_obj2nid(params->fieldID->fieldType);
+
+	if (tmp == NID_X9_62_characteristic_two_field)
+		{
+		X9_62_CHARACTERISTIC_TWO *char_two;
+
+		char_two = params->fieldID->p.char_two;
+
+		field_bits = char_two->m;
+		if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
+			{
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
+			goto err;
+			}
+
+		if ((p = BN_new()) == NULL)
+			{
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+
+		/* get the base type */
+		tmp = OBJ_obj2nid(char_two->type);
+
+		if (tmp ==  NID_X9_62_tpBasis)
+			{
+			long tmp_long;
+
+			if (!char_two->p.tpBasis)
+				{
+				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+				goto err;
+				}
+
+			tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
+
+			if (!(char_two->m > tmp_long && tmp_long > 0))
+				{
+				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_TRINOMIAL_BASIS);
+				goto err;
+				}
+			
+			/* create the polynomial */
+			if (!BN_set_bit(p, (int)char_two->m))
+				goto err;
+			if (!BN_set_bit(p, (int)tmp_long))
+				goto err;
+			if (!BN_set_bit(p, 0))
+				goto err;
+			}
+		else if (tmp == NID_X9_62_ppBasis)
+			{
+			X9_62_PENTANOMIAL *penta;
+
+			penta = char_two->p.ppBasis;
+			if (!penta)
+				{
+				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+				goto err;
+				}
+
+			if (!(char_two->m > penta->k3 && penta->k3 > penta->k2 && penta->k2 > penta->k1 && penta->k1 > 0))
+				{
+				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_PENTANOMIAL_BASIS);
+				goto err;
+				}
+			
+			/* create the polynomial */
+			if (!BN_set_bit(p, (int)char_two->m)) goto err;
+			if (!BN_set_bit(p, (int)penta->k1)) goto err;
+			if (!BN_set_bit(p, (int)penta->k2)) goto err;
+			if (!BN_set_bit(p, (int)penta->k3)) goto err;
+			if (!BN_set_bit(p, 0)) goto err;
+			}
+		else if (tmp == NID_X9_62_onBasis)
+			{
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED);
+			goto err;
+			}
+		else /* error */
+			{
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+			goto err;
+			}
+
+		/* create the EC_GROUP structure */
+		ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
+		}
+	else if (tmp == NID_X9_62_prime_field)
+		{
+		/* we have a curve over a prime field */
+		/* extract the prime number */
+		if (!params->fieldID->p.prime)
+			{
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+			goto err;
+			}
+		p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
+		if (p == NULL)
+			{
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
+			goto err;
+			}
+
+		if (BN_is_negative(p) || BN_is_zero(p))
+			{
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
+			goto err;
+			}
+
+		field_bits = BN_num_bits(p);
+		if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
+			{
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
+			goto err;
+			}
+
+		/* create the EC_GROUP structure */
+		ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
+		}
+	else
+		{
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
+		goto err;
+		}
+
+	if (ret == NULL)
+		{
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
+		goto err;
+		}
+
+	/* extract seed (optional) */
+	if (params->curve->seed != NULL)
+		{
+		if (ret->seed != NULL)
+			OPENSSL_free(ret->seed);
+		if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length)))
+			{
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, 
+			      ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		memcpy(ret->seed, params->curve->seed->data, 
+		       params->curve->seed->length);
+		ret->seed_len = params->curve->seed->length;
+		}
+
+	if (!params->order || !params->base || !params->base->data)
+		{
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+		goto err;
+		}
+
+	if ((point = EC_POINT_new(ret)) == NULL) goto err;
+
+	/* set the point conversion form */
+	EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
+				(params->base->data[0] & ~0x01));
+
+	/* extract the ec point */
+	if (!EC_POINT_oct2point(ret, point, params->base->data, 
+		                params->base->length, NULL))
+		{
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
+		goto err;
+		}
+
+	/* extract the order */
+	if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL)
+		{
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
+		goto err;
+		}
+	if (BN_is_negative(a) || BN_is_zero(a))
+		{
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
+		goto err;
+		}
+	if (BN_num_bits(a) > (int)field_bits + 1) /* Hasse bound */
+		{
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
+		goto err;
+		}
+	
+	/* extract the cofactor (optional) */
+	if (params->cofactor == NULL)
+		{
+		if (b)
+			{
+			BN_free(b);
+			b = NULL;
+			}
+		}
+	else
+		if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL)
+			{
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
+			goto err;
+			}
+	/* set the generator, order and cofactor (if present) */
+	if (!EC_GROUP_set_generator(ret, point, a, b))
+		{
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
+		goto err;
+		}
+
+	ok = 1;
+
+err:	if (!ok)
+		{
+		if (ret) 
+			EC_GROUP_clear_free(ret);
+		ret = NULL;
+		}
+
+	if (p)	
+		BN_free(p);
+	if (a)	
+		BN_free(a);
+	if (b)	
+		BN_free(b);
+	if (point)	
+		EC_POINT_free(point);
+	return(ret);
+}
+
+EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
+	{
+	EC_GROUP *ret=NULL;
+	int      tmp=0;
+
+	if (params == NULL)
+		{
+		ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, 
+		      EC_R_MISSING_PARAMETERS);
+		return NULL;
+		}
+
+	if (params->type == 0)
+		{ /* the curve is given by an OID */
+		tmp = OBJ_obj2nid(params->value.named_curve);
+		if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL)
+			{
+			ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, 
+			      EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
+			return NULL;
+			}
+		EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
+		}
+	else if (params->type == 1)
+		{ /* the parameters are given by a ECPARAMETERS
+		   * structure */
+		ret = ec_asn1_parameters2group(params->value.parameters);
+		if (!ret)
+			{
+			ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB);
+			return NULL;
+			}
+		EC_GROUP_set_asn1_flag(ret, 0x0);
+		}
+	else if (params->type == 2)
+		{ /* implicitlyCA */
+		return NULL;
+		}
+	else
+		{
+		ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR);
+		return NULL;
+		}
+
+	return ret;
+	}
+
+/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
+
+EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
+	{
+	EC_GROUP	*group  = NULL;
+	ECPKPARAMETERS	*params = NULL;
+
+	if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL)
+		{
+		ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
+		ECPKPARAMETERS_free(params);
+		return NULL;
+		}
+	
+	if ((group = ec_asn1_pkparameters2group(params)) == NULL)
+		{
+		ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
+		return NULL; 
+		}
+
+	
+	if (a && *a)
+		EC_GROUP_clear_free(*a);
+	if (a)
+		*a = group;
+
+	ECPKPARAMETERS_free(params);
+	return(group);
+	}
+
+int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
+	{
+	int		ret=0;
+	ECPKPARAMETERS	*tmp = ec_asn1_group2pkparameters(a, NULL);
+	if (tmp == NULL)
+		{
+		ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
+		return 0;
+		}
+	if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0)
+		{
+		ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
+		ECPKPARAMETERS_free(tmp);
+		return 0;
+		}	
+	ECPKPARAMETERS_free(tmp);
+	return(ret);
+	}
+
+/* some EC_KEY functions */
+
+EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
+	{
+	int             ok=0;
+	EC_KEY          *ret=NULL;
+	EC_PRIVATEKEY   *priv_key=NULL;
+
+	if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
+		{
+		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+
+	if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL)
+		{
+		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+		EC_PRIVATEKEY_free(priv_key);
+		return NULL;
+		}
+
+	if (a == NULL || *a == NULL)
+		{
+		if ((ret = EC_KEY_new()) == NULL)	
+			{
+			ECerr(EC_F_D2I_ECPRIVATEKEY,
+                                 ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		if (a)
+			*a = ret;
+		}
+	else
+		ret = *a;
+
+	if (priv_key->parameters)
+		{
+		if (ret->group)
+			EC_GROUP_clear_free(ret->group);
+		ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
+		}
+
+	if (ret->group == NULL)
+		{
+		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+		goto err;
+		}
+
+	ret->version = priv_key->version;
+
+	if (priv_key->privateKey)
+		{
+		ret->priv_key = BN_bin2bn(
+			M_ASN1_STRING_data(priv_key->privateKey),
+			M_ASN1_STRING_length(priv_key->privateKey),
+			ret->priv_key);
+		if (ret->priv_key == NULL)
+			{
+			ECerr(EC_F_D2I_ECPRIVATEKEY,
+                              ERR_R_BN_LIB);
+			goto err;
+			}
+		}
+	else
+		{
+		ECerr(EC_F_D2I_ECPRIVATEKEY, 
+                      EC_R_MISSING_PRIVATE_KEY);
+		goto err;
+		}
+
+	if (priv_key->publicKey)
+		{
+		const unsigned char *pub_oct;
+		size_t pub_oct_len;
+
+		if (ret->pub_key)
+			EC_POINT_clear_free(ret->pub_key);
+		ret->pub_key = EC_POINT_new(ret->group);
+		if (ret->pub_key == NULL)
+			{
+			ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+			goto err;
+			}
+		pub_oct     = M_ASN1_STRING_data(priv_key->publicKey);
+		pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
+		/* save the point conversion form */
+		ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
+		if (!EC_POINT_oct2point(ret->group, ret->pub_key,
+			pub_oct, pub_oct_len, NULL))
+			{
+			ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+			goto err;
+			}
+		}
+
+	ok = 1;
+err:
+	if (!ok)
+		{
+		if (ret)
+			EC_KEY_free(ret);
+		ret = NULL;
+		}
+
+	if (priv_key)
+		EC_PRIVATEKEY_free(priv_key);
+
+	return(ret);
+	}
+
+int	i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
+	{
+	int             ret=0, ok=0;
+	unsigned char   *buffer=NULL;
+	size_t          buf_len=0, tmp_len;
+	EC_PRIVATEKEY   *priv_key=NULL;
+
+	if (a == NULL || a->group == NULL || a->priv_key == NULL)
+		{
+		ECerr(EC_F_I2D_ECPRIVATEKEY,
+                      ERR_R_PASSED_NULL_PARAMETER);
+		goto err;
+		}
+
+	if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
+		{
+		ECerr(EC_F_I2D_ECPRIVATEKEY,
+                      ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	priv_key->version = a->version;
+
+	buf_len = (size_t)BN_num_bytes(a->priv_key);
+	buffer = OPENSSL_malloc(buf_len);
+	if (buffer == NULL)
+		{
+		ECerr(EC_F_I2D_ECPRIVATEKEY,
+                      ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	
+	if (!BN_bn2bin(a->priv_key, buffer))
+		{
+		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
+		goto err;
+		}
+
+	if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len))
+		{
+		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
+		goto err;
+		}	
+
+	if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS))
+		{
+		if ((priv_key->parameters = ec_asn1_group2pkparameters(
+			a->group, priv_key->parameters)) == NULL)
+			{
+			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+			goto err;
+			}
+		}
+
+	if (!(a->enc_flag & EC_PKEY_NO_PUBKEY))
+		{
+		priv_key->publicKey = M_ASN1_BIT_STRING_new();
+		if (priv_key->publicKey == NULL)
+			{
+			ECerr(EC_F_I2D_ECPRIVATEKEY,
+				ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+
+		tmp_len = EC_POINT_point2oct(a->group, a->pub_key, 
+				a->conv_form, NULL, 0, NULL);
+
+		if (tmp_len > buf_len)
+			{
+			unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
+			if (!tmp_buffer)
+				{
+				ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			buffer = tmp_buffer;
+			buf_len = tmp_len;
+			}
+
+		if (!EC_POINT_point2oct(a->group, a->pub_key, 
+			a->conv_form, buffer, buf_len, NULL))
+			{
+			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+			goto err;
+			}
+
+		priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
+		priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+		if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, 
+				buf_len))
+			{
+			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
+			goto err;
+			}
+		}
+
+	if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0)
+		{
+		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+		goto err;
+		}
+	ok=1;
+err:
+	if (buffer)
+		OPENSSL_free(buffer);
+	if (priv_key)
+		EC_PRIVATEKEY_free(priv_key);
+	return(ok?ret:0);
+	}
+
+int i2d_ECParameters(EC_KEY *a, unsigned char **out)
+	{
+	if (a == NULL)
+		{
+		ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	return i2d_ECPKParameters(a->group, out);
+	}
+
+EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
+	{
+	EC_KEY   *ret;
+
+	if (in == NULL || *in == NULL)
+		{
+		ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
+		return NULL;
+		}
+
+	if (a == NULL || *a == NULL)
+		{
+		if ((ret = EC_KEY_new()) == NULL)
+			{
+			ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
+			return NULL;
+			}
+		if (a)
+			*a = ret;
+		}
+	else
+		ret = *a;
+
+	if (!d2i_ECPKParameters(&ret->group, in, len))
+		{
+		ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
+		return NULL;
+		}
+
+	return ret;
+	}
+
+EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len)
+	{
+	EC_KEY *ret=NULL;
+
+	if (a == NULL || (*a) == NULL || (*a)->group == NULL)
+		{
+		/* sorry, but a EC_GROUP-structur is necessary
+                 * to set the public key */
+		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	ret = *a;
+	if (ret->pub_key == NULL && 
+		(ret->pub_key = EC_POINT_new(ret->group)) == NULL)
+		{
+		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL))
+		{
+		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
+		return 0;
+		}
+	/* save the point conversion form */
+	ret->conv_form = (point_conversion_form_t)(*in[0] & ~0x01);
+	*in += len;
+	return ret;
+	}
+
+int i2o_ECPublicKey(EC_KEY *a, unsigned char **out)
+	{
+        size_t buf_len=0;
+	int new_buffer = 0;
+
+        if (a == NULL) 
+		{
+		ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+
+        buf_len = EC_POINT_point2oct(a->group, a->pub_key, 
+                              a->conv_form, NULL, 0, NULL);
+
+	if (out == NULL || buf_len == 0)
+	/* out == NULL => just return the length of the octet string */
+		return buf_len;
+
+	if (*out == NULL)
+		{
+		if ((*out = OPENSSL_malloc(buf_len)) == NULL)
+			{
+			ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		new_buffer = 1;
+		}
+        if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
+				*out, buf_len, NULL))
+		{
+		ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
+		OPENSSL_free(*out);
+		*out = NULL;
+		return 0;
+		}
+	if (!new_buffer)
+		*out += buf_len;
+	return buf_len;
+	}
diff --git a/openssl/crypto/ec/ec_check.c b/openssl/crypto/ec/ec_check.c
new file mode 100644
index 0000000..0e316b4
--- /dev/null
+++ b/openssl/crypto/ec/ec_check.c
@@ -0,0 +1,123 @@
+/* crypto/ec/ec_check.c */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "ec_lcl.h"
+#include <openssl/err.h>
+
+int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
+	{
+	int ret = 0;
+	BIGNUM *order;
+	BN_CTX *new_ctx = NULL;
+	EC_POINT *point = NULL;
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			{
+			ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+	BN_CTX_start(ctx);
+	if ((order = BN_CTX_get(ctx)) == NULL) goto err;
+
+	/* check the discriminant */
+	if (!EC_GROUP_check_discriminant(group, ctx))
+		{
+		ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
+		goto err;
+		}
+
+	/* check the generator */
+	if (group->generator == NULL)
+		{
+		ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
+		goto err;
+		}
+	if (!EC_POINT_is_on_curve(group, group->generator, ctx))
+		{
+		ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
+		goto err;
+		}
+
+	/* check the order of the generator */
+	if ((point = EC_POINT_new(group)) == NULL) goto err;
+	if (!EC_GROUP_get_order(group, order, ctx)) goto err; 
+	if (BN_is_zero(order))
+		{
+		ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
+		goto err;
+		}
+	
+	if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx)) goto err;
+	if (!EC_POINT_is_at_infinity(group, point))
+		{
+		ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER);
+		goto err;
+		}
+
+	ret = 1;
+
+err:
+	if (ctx != NULL)
+		BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	if (point)
+		EC_POINT_free(point);
+	return ret;
+	}
diff --git a/openssl/crypto/ec/ec_curve.c b/openssl/crypto/ec/ec_curve.c
new file mode 100644
index 0000000..23274e4
--- /dev/null
+++ b/openssl/crypto/ec/ec_curve.c
@@ -0,0 +1,2059 @@
+/* crypto/ec/ec_curve.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by 
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#include "ec_lcl.h"
+#include <openssl/err.h>
+#include <openssl/obj_mac.h>
+
+typedef struct {
+	int	field_type,	/* either NID_X9_62_prime_field or
+				 * NID_X9_62_characteristic_two_field */
+		seed_len,
+		param_len;
+	unsigned int cofactor;	/* promoted to BN_ULONG */
+} EC_CURVE_DATA;
+
+/* the nist prime curves */
+static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
+	_EC_NIST_PRIME_192 = {
+	{ NID_X9_62_prime_field,20,24,1 },
+	{ 0x30,0x45,0xAE,0x6F,0xC8,0x42,0x2F,0x64,0xED,0x57,	/* seed */
+	  0x95,0x28,0xD3,0x81,0x20,0xEA,0xE1,0x21,0x96,0xD5,
+
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFC,
+	  0x64,0x21,0x05,0x19,0xE5,0x9C,0x80,0xE7,0x0F,0xA7,	/* b */
+	  0xE9,0xAB,0x72,0x24,0x30,0x49,0xFE,0xB8,0xDE,0xEC,
+	  0xC1,0x46,0xB9,0xB1,
+	  0x18,0x8D,0xA8,0x0E,0xB0,0x30,0x90,0xF6,0x7C,0xBF,	/* x */
+	  0x20,0xEB,0x43,0xA1,0x88,0x00,0xF4,0xFF,0x0A,0xFD,
+	  0x82,0xFF,0x10,0x12,
+	  0x07,0x19,0x2b,0x95,0xff,0xc8,0xda,0x78,0x63,0x10,	/* y */
+	  0x11,0xed,0x6b,0x24,0xcd,0xd5,0x73,0xf9,0x77,0xa1,
+	  0x1e,0x79,0x48,0x11,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0x99,0xDE,0xF8,0x36,0x14,0x6B,0xC9,0xB1,
+	  0xB4,0xD2,0x28,0x31 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+28*6]; }
+	_EC_NIST_PRIME_224 = {
+	{ NID_X9_62_prime_field,20,28,1 },
+	{ 0xBD,0x71,0x34,0x47,0x99,0xD5,0xC7,0xFC,0xDC,0x45,	/* seed */
+	  0xB5,0x9F,0xA3,0xB9,0xAB,0x8F,0x6A,0x94,0x8B,0xC5,
+
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
+	  0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41,	/* b */
+	  0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA,
+	  0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4,
+	  0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13,	/* x */
+	  0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22,
+	  0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21,
+	  0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22,	/* y */
+	  0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64,
+	  0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0x16,0xA2,0xE0,0xB8,0xF0,0x3E,
+	  0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+48*6]; }
+	_EC_NIST_PRIME_384 = {
+	{ NID_X9_62_prime_field,20,48,1 },
+	{ 0xA3,0x35,0x92,0x6A,0xA3,0x19,0xA2,0x7A,0x1D,0x00,	/* seed */
+	  0x89,0x6A,0x67,0x73,0xA4,0x82,0x7A,0xCD,0xAC,0x73,
+
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFC,
+	  0xB3,0x31,0x2F,0xA7,0xE2,0x3E,0xE7,0xE4,0x98,0x8E,	/* b */
+	  0x05,0x6B,0xE3,0xF8,0x2D,0x19,0x18,0x1D,0x9C,0x6E,
+	  0xFE,0x81,0x41,0x12,0x03,0x14,0x08,0x8F,0x50,0x13,
+	  0x87,0x5A,0xC6,0x56,0x39,0x8D,0x8A,0x2E,0xD1,0x9D,
+	  0x2A,0x85,0xC8,0xED,0xD3,0xEC,0x2A,0xEF,
+	  0xAA,0x87,0xCA,0x22,0xBE,0x8B,0x05,0x37,0x8E,0xB1,	/* x */
+	  0xC7,0x1E,0xF3,0x20,0xAD,0x74,0x6E,0x1D,0x3B,0x62,
+	  0x8B,0xA7,0x9B,0x98,0x59,0xF7,0x41,0xE0,0x82,0x54,
+	  0x2A,0x38,0x55,0x02,0xF2,0x5D,0xBF,0x55,0x29,0x6C,
+	  0x3A,0x54,0x5E,0x38,0x72,0x76,0x0A,0xB7,
+	  0x36,0x17,0xde,0x4a,0x96,0x26,0x2c,0x6f,0x5d,0x9e,	/* y */
+	  0x98,0xbf,0x92,0x92,0xdc,0x29,0xf8,0xf4,0x1d,0xbd,
+	  0x28,0x9a,0x14,0x7c,0xe9,0xda,0x31,0x13,0xb5,0xf0,
+	  0xb8,0xc0,0x0a,0x60,0xb1,0xce,0x1d,0x7e,0x81,0x9d,
+	  0x7a,0x43,0x1d,0x7c,0x90,0xea,0x0e,0x5f,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xC7,0x63,0x4D,0x81,0xF4,0x37,
+	  0x2D,0xDF,0x58,0x1A,0x0D,0xB2,0x48,0xB0,0xA7,0x7A,
+	  0xEC,0xEC,0x19,0x6A,0xCC,0xC5,0x29,0x73 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+66*6]; }
+	_EC_NIST_PRIME_521 = {
+	{ NID_X9_62_prime_field,20,66,1 },
+	{ 0xD0,0x9E,0x88,0x00,0x29,0x1C,0xB8,0x53,0x96,0xCC,	/* seed */
+	  0x67,0x17,0x39,0x32,0x84,0xAA,0xA0,0xDA,0x64,0xBA,
+
+	  0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,
+	  0x00,0x51,0x95,0x3E,0xB9,0x61,0x8E,0x1C,0x9A,0x1F,	/* b */
+	  0x92,0x9A,0x21,0xA0,0xB6,0x85,0x40,0xEE,0xA2,0xDA,
+	  0x72,0x5B,0x99,0xB3,0x15,0xF3,0xB8,0xB4,0x89,0x91,
+	  0x8E,0xF1,0x09,0xE1,0x56,0x19,0x39,0x51,0xEC,0x7E,
+	  0x93,0x7B,0x16,0x52,0xC0,0xBD,0x3B,0xB1,0xBF,0x07,
+	  0x35,0x73,0xDF,0x88,0x3D,0x2C,0x34,0xF1,0xEF,0x45,
+	  0x1F,0xD4,0x6B,0x50,0x3F,0x00,
+	  0x00,0xC6,0x85,0x8E,0x06,0xB7,0x04,0x04,0xE9,0xCD,	/* x */
+	  0x9E,0x3E,0xCB,0x66,0x23,0x95,0xB4,0x42,0x9C,0x64,
+	  0x81,0x39,0x05,0x3F,0xB5,0x21,0xF8,0x28,0xAF,0x60,
+	  0x6B,0x4D,0x3D,0xBA,0xA1,0x4B,0x5E,0x77,0xEF,0xE7,
+	  0x59,0x28,0xFE,0x1D,0xC1,0x27,0xA2,0xFF,0xA8,0xDE,
+	  0x33,0x48,0xB3,0xC1,0x85,0x6A,0x42,0x9B,0xF9,0x7E,
+	  0x7E,0x31,0xC2,0xE5,0xBD,0x66,
+	  0x01,0x18,0x39,0x29,0x6a,0x78,0x9a,0x3b,0xc0,0x04,	/* y */
+	  0x5c,0x8a,0x5f,0xb4,0x2c,0x7d,0x1b,0xd9,0x98,0xf5,
+	  0x44,0x49,0x57,0x9b,0x44,0x68,0x17,0xaf,0xbd,0x17,
+	  0x27,0x3e,0x66,0x2c,0x97,0xee,0x72,0x99,0x5e,0xf4,
+	  0x26,0x40,0xc5,0x50,0xb9,0x01,0x3f,0xad,0x07,0x61,
+	  0x35,0x3c,0x70,0x86,0xa2,0x72,0xc2,0x40,0x88,0xbe,
+	  0x94,0x76,0x9f,0xd1,0x66,0x50,
+	  0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFA,0x51,0x86,0x87,0x83,0xBF,0x2F,
+	  0x96,0x6B,0x7F,0xCC,0x01,0x48,0xF7,0x09,0xA5,0xD0,
+	  0x3B,0xB5,0xC9,0xB8,0x89,0x9C,0x47,0xAE,0xBB,0x6F,
+	  0xB7,0x1E,0x91,0x38,0x64,0x09 }
+	};
+
+/* the x9.62 prime curves (minus the nist prime curves) */
+static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
+	_EC_X9_62_PRIME_192V2 = {
+	{ NID_X9_62_prime_field,20,24,1 },
+	{ 0x31,0xA9,0x2E,0xE2,0x02,0x9F,0xD1,0x0D,0x90,0x1B,	/* seed */
+	  0x11,0x3E,0x99,0x07,0x10,0xF0,0xD2,0x1A,0xC6,0xB6,
+
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFC,
+	  0xCC,0x22,0xD6,0xDF,0xB9,0x5C,0x6B,0x25,0xE4,0x9C,	/* b */
+	  0x0D,0x63,0x64,0xA4,0xE5,0x98,0x0C,0x39,0x3A,0xA2,
+	  0x16,0x68,0xD9,0x53,
+	  0xEE,0xA2,0xBA,0xE7,0xE1,0x49,0x78,0x42,0xF2,0xDE,	/* x */
+	  0x77,0x69,0xCF,0xE9,0xC9,0x89,0xC0,0x72,0xAD,0x69,
+	  0x6F,0x48,0x03,0x4A,
+	  0x65,0x74,0xd1,0x1d,0x69,0xb6,0xec,0x7a,0x67,0x2b,	/* y */
+	  0xb8,0x2a,0x08,0x3d,0xf2,0xf2,0xb0,0x84,0x7d,0xe9,
+	  0x70,0xb2,0xde,0x15,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFE,0x5F,0xB1,0xA7,0x24,0xDC,0x80,0x41,0x86,
+	  0x48,0xD8,0xDD,0x31 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
+	_EC_X9_62_PRIME_192V3 = {
+	{ NID_X9_62_prime_field,20,24,1 },
+	{ 0xC4,0x69,0x68,0x44,0x35,0xDE,0xB3,0x78,0xC4,0xB6,	/* seed */
+	  0x5C,0xA9,0x59,0x1E,0x2A,0x57,0x63,0x05,0x9A,0x2E,
+
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFC,
+	  0x22,0x12,0x3D,0xC2,0x39,0x5A,0x05,0xCA,0xA7,0x42,	/* b */
+	  0x3D,0xAE,0xCC,0xC9,0x47,0x60,0xA7,0xD4,0x62,0x25,
+	  0x6B,0xD5,0x69,0x16,
+	  0x7D,0x29,0x77,0x81,0x00,0xC6,0x5A,0x1D,0xA1,0x78,	/* x */
+	  0x37,0x16,0x58,0x8D,0xCE,0x2B,0x8B,0x4A,0xEE,0x8E,
+	  0x22,0x8F,0x18,0x96,
+	  0x38,0xa9,0x0f,0x22,0x63,0x73,0x37,0x33,0x4b,0x49,	/* y */
+	  0xdc,0xb6,0x6a,0x6d,0xc8,0xf9,0x97,0x8a,0xca,0x76,
+	  0x48,0xa9,0x43,0xb0,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0x7A,0x62,0xD0,0x31,0xC8,0x3F,0x42,0x94,
+	  0xF6,0x40,0xEC,0x13 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
+	_EC_X9_62_PRIME_239V1 = {
+	{ NID_X9_62_prime_field,20,30,1 },
+	{ 0xE4,0x3B,0xB4,0x60,0xF0,0xB8,0x0C,0xC0,0xC0,0xB0,	/* seed */
+	  0x75,0x79,0x8E,0x94,0x80,0x60,0xF8,0x32,0x1B,0x7D,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
+	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
+	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
+
+	  0x6B,0x01,0x6C,0x3B,0xDC,0xF1,0x89,0x41,0xD0,0xD6,	/* b */
+	  0x54,0x92,0x14,0x75,0xCA,0x71,0xA9,0xDB,0x2F,0xB2,
+	  0x7D,0x1D,0x37,0x79,0x61,0x85,0xC2,0x94,0x2C,0x0A,
+
+	  0x0F,0xFA,0x96,0x3C,0xDC,0xA8,0x81,0x6C,0xCC,0x33,	/* x */
+	  0xB8,0x64,0x2B,0xED,0xF9,0x05,0xC3,0xD3,0x58,0x57,
+	  0x3D,0x3F,0x27,0xFB,0xBD,0x3B,0x3C,0xB9,0xAA,0xAF,
+
+	  0x7d,0xeb,0xe8,0xe4,0xe9,0x0a,0x5d,0xae,0x6e,0x40,	/* y */
+	  0x54,0xca,0x53,0x0b,0xa0,0x46,0x54,0xb3,0x68,0x18,
+	  0xce,0x22,0x6b,0x39,0xfc,0xcb,0x7b,0x02,0xf1,0xae,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0x7F,0xFF,0xFF,0x9E,0x5E,0x9A,0x9F,0x5D,
+	  0x90,0x71,0xFB,0xD1,0x52,0x26,0x88,0x90,0x9D,0x0B }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
+	_EC_X9_62_PRIME_239V2 = {
+	{ NID_X9_62_prime_field,20,30,1 },
+	{ 0xE8,0xB4,0x01,0x16,0x04,0x09,0x53,0x03,0xCA,0x3B,	/* seed */
+	  0x80,0x99,0x98,0x2B,0xE0,0x9F,0xCB,0x9A,0xE6,0x16,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
+	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
+	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
+
+	  0x61,0x7F,0xAB,0x68,0x32,0x57,0x6C,0xBB,0xFE,0xD5,	/* b */
+	  0x0D,0x99,0xF0,0x24,0x9C,0x3F,0xEE,0x58,0xB9,0x4B,
+	  0xA0,0x03,0x8C,0x7A,0xE8,0x4C,0x8C,0x83,0x2F,0x2C,
+
+	  0x38,0xAF,0x09,0xD9,0x87,0x27,0x70,0x51,0x20,0xC9,	/* x */
+	  0x21,0xBB,0x5E,0x9E,0x26,0x29,0x6A,0x3C,0xDC,0xF2,
+	  0xF3,0x57,0x57,0xA0,0xEA,0xFD,0x87,0xB8,0x30,0xE7,
+
+	  0x5b,0x01,0x25,0xe4,0xdb,0xea,0x0e,0xc7,0x20,0x6d,	/* y */
+	  0xa0,0xfc,0x01,0xd9,0xb0,0x81,0x32,0x9f,0xb5,0x55,
+	  0xde,0x6e,0xf4,0x60,0x23,0x7d,0xff,0x8b,0xe4,0xba,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0x80,0x00,0x00,0xCF,0xA7,0xE8,0x59,0x43,
+	  0x77,0xD4,0x14,0xC0,0x38,0x21,0xBC,0x58,0x20,0x63 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
+	_EC_X9_62_PRIME_239V3 = {
+	{ NID_X9_62_prime_field,20,30,1 },
+	{ 0x7D,0x73,0x74,0x16,0x8F,0xFE,0x34,0x71,0xB6,0x0A,	/* seed */
+	  0x85,0x76,0x86,0xA1,0x94,0x75,0xD3,0xBF,0xA2,0xFF,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
+	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
+	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
+
+	  0x25,0x57,0x05,0xFA,0x2A,0x30,0x66,0x54,0xB1,0xF4,	/* b */
+	  0xCB,0x03,0xD6,0xA7,0x50,0xA3,0x0C,0x25,0x01,0x02,
+	  0xD4,0x98,0x87,0x17,0xD9,0xBA,0x15,0xAB,0x6D,0x3E,
+
+	  0x67,0x68,0xAE,0x8E,0x18,0xBB,0x92,0xCF,0xCF,0x00,	/* x */
+	  0x5C,0x94,0x9A,0xA2,0xC6,0xD9,0x48,0x53,0xD0,0xE6,
+	  0x60,0xBB,0xF8,0x54,0xB1,0xC9,0x50,0x5F,0xE9,0x5A,
+
+	  0x16,0x07,0xe6,0x89,0x8f,0x39,0x0c,0x06,0xbc,0x1d,	/* y */
+	  0x55,0x2b,0xad,0x22,0x6f,0x3b,0x6f,0xcf,0xe4,0x8b,
+	  0x6e,0x81,0x84,0x99,0xaf,0x18,0xe3,0xed,0x6c,0xf3,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0x7F,0xFF,0xFF,0x97,0x5D,0xEB,0x41,0xB3,
+	  0xA6,0x05,0x7C,0x3C,0x43,0x21,0x46,0x52,0x65,0x51 }
+	};
+
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+32*6]; }
+	_EC_X9_62_PRIME_256V1 = {
+	{ NID_X9_62_prime_field,20,32,1 },
+	{ 0xC4,0x9D,0x36,0x08,0x86,0xE7,0x04,0x93,0x6A,0x66,	/* seed */
+	  0x78,0xE1,0x13,0x9D,0x26,0xB7,0x81,0x9F,0x7E,0x90,
+
+	  0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFC,
+	  0x5A,0xC6,0x35,0xD8,0xAA,0x3A,0x93,0xE7,0xB3,0xEB,	/* b */
+	  0xBD,0x55,0x76,0x98,0x86,0xBC,0x65,0x1D,0x06,0xB0,
+	  0xCC,0x53,0xB0,0xF6,0x3B,0xCE,0x3C,0x3E,0x27,0xD2,
+	  0x60,0x4B,
+	  0x6B,0x17,0xD1,0xF2,0xE1,0x2C,0x42,0x47,0xF8,0xBC,	/* x */
+	  0xE6,0xE5,0x63,0xA4,0x40,0xF2,0x77,0x03,0x7D,0x81,
+	  0x2D,0xEB,0x33,0xA0,0xF4,0xA1,0x39,0x45,0xD8,0x98,
+	  0xC2,0x96,
+	  0x4f,0xe3,0x42,0xe2,0xfe,0x1a,0x7f,0x9b,0x8e,0xe7,	/* y */
+	  0xeb,0x4a,0x7c,0x0f,0x9e,0x16,0x2b,0xce,0x33,0x57,
+	  0x6b,0x31,0x5e,0xce,0xcb,0xb6,0x40,0x68,0x37,0xbf,
+	  0x51,0xf5,
+	  0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBC,0xE6,0xFA,0xAD,
+	  0xA7,0x17,0x9E,0x84,0xF3,0xB9,0xCA,0xC2,0xFC,0x63,
+	  0x25,0x51 }
+	};
+
+/* the secg prime curves (minus the nist and x9.62 prime curves) */
+static const struct { EC_CURVE_DATA h; unsigned char data[20+14*6]; }
+	_EC_SECG_PRIME_112R1 = {
+	{ NID_X9_62_prime_field,20,14,1 },
+	{ 0x00,0xF5,0x0B,0x02,0x8E,0x4D,0x69,0x6E,0x67,0x68,	/* seed */
+	  0x75,0x61,0x51,0x75,0x29,0x04,0x72,0x78,0x3F,0xB1,
+
+	  0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76,	/* p */
+	  0xBE,0xAD,0x20,0x8B,
+	  0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76,	/* a */
+	  0xBE,0xAD,0x20,0x88,
+	  0x65,0x9E,0xF8,0xBA,0x04,0x39,0x16,0xEE,0xDE,0x89,	/* b */
+	  0x11,0x70,0x2B,0x22,
+	  0x09,0x48,0x72,0x39,0x99,0x5A,0x5E,0xE7,0x6B,0x55,	/* x */
+	  0xF9,0xC2,0xF0,0x98,
+	  0xa8,0x9c,0xe5,0xaf,0x87,0x24,0xc0,0xa2,0x3e,0x0e,	/* y */
+	  0x0f,0xf7,0x75,0x00,
+	  0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x76,0x28,0xDF,	/* order */
+	  0xAC,0x65,0x61,0xC5 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+14*6]; }
+	_EC_SECG_PRIME_112R2 = {
+	{ NID_X9_62_prime_field,20,14,4 },
+	{ 0x00,0x27,0x57,0xA1,0x11,0x4D,0x69,0x6E,0x67,0x68,	/* seed */
+	  0x75,0x61,0x51,0x75,0x53,0x16,0xC0,0x5E,0x0B,0xD4,
+
+	  0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76,	/* p */
+	  0xBE,0xAD,0x20,0x8B,
+	  0x61,0x27,0xC2,0x4C,0x05,0xF3,0x8A,0x0A,0xAA,0xF6,	/* a */
+	  0x5C,0x0E,0xF0,0x2C,
+	  0x51,0xDE,0xF1,0x81,0x5D,0xB5,0xED,0x74,0xFC,0xC3,	/* b */
+	  0x4C,0x85,0xD7,0x09,
+	  0x4B,0xA3,0x0A,0xB5,0xE8,0x92,0xB4,0xE1,0x64,0x9D,	/* x */
+	  0xD0,0x92,0x86,0x43,
+	  0xad,0xcd,0x46,0xf5,0x88,0x2e,0x37,0x47,0xde,0xf3,	/* y */
+	  0x6e,0x95,0x6e,0x97,
+	  0x36,0xDF,0x0A,0xAF,0xD8,0xB8,0xD7,0x59,0x7C,0xA1,	/* order */
+	  0x05,0x20,0xD0,0x4B }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+16*6]; }
+	_EC_SECG_PRIME_128R1 = {
+	{ NID_X9_62_prime_field,20,16,1 },
+	{ 0x00,0x0E,0x0D,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,	/* seed */
+	  0x51,0x75,0x0C,0xC0,0x3A,0x44,0x73,0xD0,0x36,0x79,
+
+	  0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,
+	  0xE8,0x75,0x79,0xC1,0x10,0x79,0xF4,0x3D,0xD8,0x24,	/* b */
+	  0x99,0x3C,0x2C,0xEE,0x5E,0xD3,
+	  0x16,0x1F,0xF7,0x52,0x8B,0x89,0x9B,0x2D,0x0C,0x28,	/* x */
+	  0x60,0x7C,0xA5,0x2C,0x5B,0x86,
+	  0xcf,0x5a,0xc8,0x39,0x5b,0xaf,0xeb,0x13,0xc0,0x2d,	/* y */
+	  0xa2,0x92,0xdd,0xed,0x7a,0x83,
+	  0xFF,0xFF,0xFF,0xFE,0x00,0x00,0x00,0x00,0x75,0xA3,	/* order */
+	  0x0D,0x1B,0x90,0x38,0xA1,0x15 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+16*6]; }
+	_EC_SECG_PRIME_128R2 = {
+	{ NID_X9_62_prime_field,20,16,4 },
+	{ 0x00,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,	/* seed */
+	  0x12,0xD8,0xF0,0x34,0x31,0xFC,0xE6,0x3B,0x88,0xF4,
+
+	  0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xD6,0x03,0x19,0x98,0xD1,0xB3,0xBB,0xFE,0xBF,0x59,	/* a */
+	  0xCC,0x9B,0xBF,0xF9,0xAE,0xE1,
+	  0x5E,0xEE,0xFC,0xA3,0x80,0xD0,0x29,0x19,0xDC,0x2C,	/* b */
+	  0x65,0x58,0xBB,0x6D,0x8A,0x5D,
+	  0x7B,0x6A,0xA5,0xD8,0x5E,0x57,0x29,0x83,0xE6,0xFB,	/* x */
+	  0x32,0xA7,0xCD,0xEB,0xC1,0x40,
+	  0x27,0xb6,0x91,0x6a,0x89,0x4d,0x3a,0xee,0x71,0x06,	/* y */
+	  0xfe,0x80,0x5f,0xc3,0x4b,0x44,
+	  0x3F,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xBE,0x00,	/* order */
+	  0x24,0x72,0x06,0x13,0xB5,0xA3 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
+	_EC_SECG_PRIME_160K1 = {
+	{ NID_X9_62_prime_field,0,21,1 },
+	{							/* no seed */
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
+	  0x73,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x07,
+	  0x00,0x3B,0x4C,0x38,0x2C,0xE3,0x7A,0xA1,0x92,0xA4,	/* x */
+	  0x01,0x9E,0x76,0x30,0x36,0xF4,0xF5,0xDD,0x4D,0x7E,
+	  0xBB,
+	  0x00,0x93,0x8c,0xf9,0x35,0x31,0x8f,0xdc,0xed,0x6b,	/* y */
+	  0xc2,0x82,0x86,0x53,0x17,0x33,0xc3,0xf0,0x3c,0x4f,
+	  0xee,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x01,0xB8,0xFA,0x16,0xDF,0xAB,0x9A,0xCA,0x16,0xB6,
+	  0xB3 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
+	_EC_SECG_PRIME_160R1 = {
+	{ NID_X9_62_prime_field,20,21,1 },
+	{ 0x10,0x53,0xCD,0xE4,0x2C,0x14,0xD6,0x96,0xE6,0x76,	/* seed */
+	  0x87,0x56,0x15,0x17,0x53,0x3B,0xF3,0xF8,0x33,0x45,
+
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,
+	  0xFF,
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,
+	  0xFC,
+	  0x00,0x1C,0x97,0xBE,0xFC,0x54,0xBD,0x7A,0x8B,0x65,	/* b */
+	  0xAC,0xF8,0x9F,0x81,0xD4,0xD4,0xAD,0xC5,0x65,0xFA,
+	  0x45,
+	  0x00,0x4A,0x96,0xB5,0x68,0x8E,0xF5,0x73,0x28,0x46,	/* x */
+	  0x64,0x69,0x89,0x68,0xC3,0x8B,0xB9,0x13,0xCB,0xFC,
+	  0x82,
+	  0x00,0x23,0xa6,0x28,0x55,0x31,0x68,0x94,0x7d,0x59,	/* y */
+	  0xdc,0xc9,0x12,0x04,0x23,0x51,0x37,0x7a,0xc5,0xfb,
+	  0x32,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x01,0xF4,0xC8,0xF9,0x27,0xAE,0xD3,0xCA,0x75,0x22,
+	  0x57 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
+	_EC_SECG_PRIME_160R2 = {
+	{ NID_X9_62_prime_field,20,21,1 },
+	{ 0xB9,0x9B,0x99,0xB0,0x99,0xB3,0x23,0xE0,0x27,0x09,	/* seed */
+	  0xA4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x51,
+
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
+	  0x73,
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
+	  0x70,
+	  0x00,0xB4,0xE1,0x34,0xD3,0xFB,0x59,0xEB,0x8B,0xAB,	/* b */
+	  0x57,0x27,0x49,0x04,0x66,0x4D,0x5A,0xF5,0x03,0x88,
+	  0xBA,
+	  0x00,0x52,0xDC,0xB0,0x34,0x29,0x3A,0x11,0x7E,0x1F,	/* x */
+	  0x4F,0xF1,0x1B,0x30,0xF7,0x19,0x9D,0x31,0x44,0xCE,
+	  0x6D,
+	  0x00,0xfe,0xaf,0xfe,0xf2,0xe3,0x31,0xf2,0x96,0xe0,	/* y */
+	  0x71,0xfa,0x0d,0xf9,0x98,0x2c,0xfe,0xa7,0xd4,0x3f,
+	  0x2e,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x35,0x1E,0xE7,0x86,0xA8,0x18,0xF3,0xA1,0xA1,
+	  0x6B }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+24*6]; }
+	_EC_SECG_PRIME_192K1 = {
+	{ NID_X9_62_prime_field,0,24,1 },
+	{							/* no seed */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
+	  0xFF,0xFF,0xEE,0x37,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x03,
+	  0xDB,0x4F,0xF1,0x0E,0xC0,0x57,0xE9,0xAE,0x26,0xB0,	/* x */
+	  0x7D,0x02,0x80,0xB7,0xF4,0x34,0x1D,0xA5,0xD1,0xB1,
+	  0xEA,0xE0,0x6C,0x7D,
+	  0x9b,0x2f,0x2f,0x6d,0x9c,0x56,0x28,0xa7,0x84,0x41,	/* y */
+	  0x63,0xd0,0x15,0xbe,0x86,0x34,0x40,0x82,0xaa,0x88,
+	  0xd9,0x5e,0x2f,0x9d,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFE,0x26,0xF2,0xFC,0x17,0x0F,0x69,0x46,0x6A,
+	  0x74,0xDE,0xFD,0x8D }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+29*6]; }
+	_EC_SECG_PRIME_224K1 = {
+	{ NID_X9_62_prime_field,0,29,1 },
+	{							/* no seed */
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xE5,0x6D,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
+	  0x00,0xA1,0x45,0x5B,0x33,0x4D,0xF0,0x99,0xDF,0x30,	/* x */
+	  0xFC,0x28,0xA1,0x69,0xA4,0x67,0xE9,0xE4,0x70,0x75,
+	  0xA9,0x0F,0x7E,0x65,0x0E,0xB6,0xB7,0xA4,0x5C,
+	  0x00,0x7e,0x08,0x9f,0xed,0x7f,0xba,0x34,0x42,0x82,	/* y */
+	  0xca,0xfb,0xd6,0xf7,0xe3,0x19,0xf7,0xc0,0xb0,0xbd,
+	  0x59,0xe2,0xca,0x4b,0xdb,0x55,0x6d,0x61,0xa5,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x00,0x00,0x01,0xDC,0xE8,0xD2,0xEC,0x61,
+	  0x84,0xCA,0xF0,0xA9,0x71,0x76,0x9F,0xB1,0xF7 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+32*6]; }
+	_EC_SECG_PRIME_256K1 = {
+	{ NID_X9_62_prime_field,0,32,1 },
+	{							/* no seed */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,
+	  0xFC,0x2F,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x07,
+	  0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,	/* x */
+	  0x62,0x95,0xCE,0x87,0x0B,0x07,0x02,0x9B,0xFC,0xDB,
+	  0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
+	  0x17,0x98,
+	  0x48,0x3a,0xda,0x77,0x26,0xa3,0xc4,0x65,0x5d,0xa4,	/* y */
+	  0xfb,0xfc,0x0e,0x11,0x08,0xa8,0xfd,0x17,0xb4,0x48,
+	  0xa6,0x85,0x54,0x19,0x9c,0x47,0xd0,0x8f,0xfb,0x10,
+	  0xd4,0xb8,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,
+	  0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,0x8C,0xD0,0x36,
+	  0x41,0x41 }
+	};
+
+/* some wap/wtls curves */
+static const struct { EC_CURVE_DATA h; unsigned char data[0+15*6]; }
+	_EC_WTLS_8 = {
+	{ NID_X9_62_prime_field,0,15,1 },
+	{							/* no seed */
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFD,0xE7,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x03,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* x */
+	  0x00,0x00,0x00,0x00,0x01,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* y */
+	  0x00,0x00,0x00,0x00,0x02,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xEC,0xEA,	/* order */
+	  0x55,0x1A,0xD8,0x37,0xE9 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
+	_EC_WTLS_9 = {
+	{ NID_X9_62_prime_field,0,21,1 },
+	{							/* no seed */
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0x80,
+	  0x8F,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x03,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* x */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x01,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* y */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x02,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x01,0xCD,0xC9,0x8A,0xE0,0xE2,0xDE,0x57,0x4A,0xBF,
+	  0x33 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+28*6]; }
+	_EC_WTLS_12 = {
+	{ NID_X9_62_prime_field,0,28,1 },
+	{							/* no seed */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
+	  0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41,	/* b */
+	  0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA,
+	  0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4,
+	  0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13,	/* x */
+	  0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22,
+	  0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21,
+	  0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22,	/* y */
+	  0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64,
+	  0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0x16,0xA2,0xE0,0xB8,0xF0,0x3E,
+	  0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D }
+	};
+
+/* characteristic two curves */
+static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; }
+	_EC_SECG_CHAR2_113R1 = {
+	{ NID_X9_62_characteristic_two_field,20,15,2 },
+	{ 0x10,0xE7,0x23,0xAB,0x14,0xD6,0x96,0xE6,0x76,0x87,	/* seed */
+	  0x56,0x15,0x17,0x56,0xFE,0xBF,0x8F,0xCB,0x49,0xA9,
+
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x02,0x01,
+	  0x00,0x30,0x88,0x25,0x0C,0xA6,0xE7,0xC7,0xFE,0x64,	/* a */
+	  0x9C,0xE8,0x58,0x20,0xF7,
+	  0x00,0xE8,0xBE,0xE4,0xD3,0xE2,0x26,0x07,0x44,0x18,	/* b */
+	  0x8B,0xE0,0xE9,0xC7,0x23,
+	  0x00,0x9D,0x73,0x61,0x6F,0x35,0xF4,0xAB,0x14,0x07,	/* x */
+	  0xD7,0x35,0x62,0xC1,0x0F,
+	  0x00,0xA5,0x28,0x30,0x27,0x79,0x58,0xEE,0x84,0xD1,	/* y */
+	  0x31,0x5E,0xD3,0x18,0x86,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD9,0xCC,	/* order */
+	  0xEC,0x8A,0x39,0xE5,0x6F }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; }
+	_EC_SECG_CHAR2_113R2 = {
+	{ NID_X9_62_characteristic_two_field,20,15,2 },
+	{ 0x10,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE,	/* seed */
+	  0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x5D,
+
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x02,0x01,
+	  0x00,0x68,0x99,0x18,0xDB,0xEC,0x7E,0x5A,0x0D,0xD6,	/* a */
+	  0xDF,0xC0,0xAA,0x55,0xC7,
+	  0x00,0x95,0xE9,0xA9,0xEC,0x9B,0x29,0x7B,0xD4,0xBF,	/* b */
+	  0x36,0xE0,0x59,0x18,0x4F,
+	  0x01,0xA5,0x7A,0x6A,0x7B,0x26,0xCA,0x5E,0xF5,0x2F,	/* x */
+	  0xCD,0xB8,0x16,0x47,0x97,
+	  0x00,0xB3,0xAD,0xC9,0x4E,0xD1,0xFE,0x67,0x4C,0x06,	/* y */
+	  0xE6,0x95,0xBA,0xBA,0x1D,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x08,0x78,	/* order */
+	  0x9B,0x24,0x96,0xAF,0x93 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+17*6]; }
+	_EC_SECG_CHAR2_131R1 = {
+	{ NID_X9_62_characteristic_two_field,20,17,2 },
+	{ 0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,0x98,	/* seed */
+	  0x5B,0xD3,0xAD,0xBA,0xDA,0x21,0xB4,0x3A,0x97,0xE2,
+
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x01,0x0D,
+	  0x07,0xA1,0x1B,0x09,0xA7,0x6B,0x56,0x21,0x44,0x41,	/* a */
+	  0x8F,0xF3,0xFF,0x8C,0x25,0x70,0xB8,
+	  0x02,0x17,0xC0,0x56,0x10,0x88,0x4B,0x63,0xB9,0xC6,	/* b */
+	  0xC7,0x29,0x16,0x78,0xF9,0xD3,0x41,
+	  0x00,0x81,0xBA,0xF9,0x1F,0xDF,0x98,0x33,0xC4,0x0F,	/* x */
+	  0x9C,0x18,0x13,0x43,0x63,0x83,0x99,
+	  0x07,0x8C,0x6E,0x7E,0xA3,0x8C,0x00,0x1F,0x73,0xC8,	/* y */
+	  0x13,0x4B,0x1B,0x4E,0xF9,0xE1,0x50,
+	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x31,	/* order */
+	  0x23,0x95,0x3A,0x94,0x64,0xB5,0x4D }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+17*6]; }
+	_EC_SECG_CHAR2_131R2 = {
+	{ NID_X9_62_characteristic_two_field,20,17,2 },
+	{ 0x98,0x5B,0xD3,0xAD,0xBA,0xD4,0xD6,0x96,0xE6,0x76,	/* seed */
+	  0x87,0x56,0x15,0x17,0x5A,0x21,0xB4,0x3A,0x97,0xE3,
+
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x01,0x0D,
+	  0x03,0xE5,0xA8,0x89,0x19,0xD7,0xCA,0xFC,0xBF,0x41,	/* a */
+	  0x5F,0x07,0xC2,0x17,0x65,0x73,0xB2,
+	  0x04,0xB8,0x26,0x6A,0x46,0xC5,0x56,0x57,0xAC,0x73,	/* b */
+	  0x4C,0xE3,0x8F,0x01,0x8F,0x21,0x92,
+	  0x03,0x56,0xDC,0xD8,0xF2,0xF9,0x50,0x31,0xAD,0x65,	/* x */
+	  0x2D,0x23,0x95,0x1B,0xB3,0x66,0xA8,
+	  0x06,0x48,0xF0,0x6D,0x86,0x79,0x40,0xA5,0x36,0x6D,	/* y */
+	  0x9E,0x26,0x5D,0xE9,0xEB,0x24,0x0F,
+	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x69,	/* order */
+	  0x54,0xA2,0x33,0x04,0x9B,0xA9,0x8F }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
+	_EC_NIST_CHAR2_163K = {
+	{ NID_X9_62_characteristic_two_field,0,21,2 },
+	{							/* no seed */
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0xC9,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x01,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x01,
+	  0x02,0xFE,0x13,0xC0,0x53,0x7B,0xBC,0x11,0xAC,0xAA,	/* x */
+	  0x07,0xD7,0x93,0xDE,0x4E,0x6D,0x5E,0x5C,0x94,0xEE,
+	  0xE8,
+	  0x02,0x89,0x07,0x0F,0xB0,0x5D,0x38,0xFF,0x58,0x32,	/* y */
+	  0x1F,0x2E,0x80,0x05,0x36,0xD5,0x38,0xCC,0xDA,0xA3,
+	  0xD9,
+	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x02,0x01,0x08,0xA2,0xE0,0xCC,0x0D,0x99,0xF8,0xA5,
+	  0xEF }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
+	_EC_SECG_CHAR2_163R1 = {
+	{ NID_X9_62_characteristic_two_field,0,21,2 },
+	{							/* no seed */
+#if 0
+/* The algorithm used to derive the curve parameters from
+ * the seed used here is slightly different than the
+ * algorithm described in X9.62 . */
+	  0x24,0xB7,0xB1,0x37,0xC8,0xA1,0x4D,0x69,0x6E,0x67,
+	  0x68,0x75,0x61,0x51,0x75,0x6F,0xD0,0xDA,0x2E,0x5C,
+#endif
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0xC9,
+	  0x07,0xB6,0x88,0x2C,0xAA,0xEF,0xA8,0x4F,0x95,0x54,	/* a */
+	  0xFF,0x84,0x28,0xBD,0x88,0xE2,0x46,0xD2,0x78,0x2A,
+	  0xE2,
+	  0x07,0x13,0x61,0x2D,0xCD,0xDC,0xB4,0x0A,0xAB,0x94,	/* b */
+	  0x6B,0xDA,0x29,0xCA,0x91,0xF7,0x3A,0xF9,0x58,0xAF,
+	  0xD9,
+	  0x03,0x69,0x97,0x96,0x97,0xAB,0x43,0x89,0x77,0x89,	/* x */
+	  0x56,0x67,0x89,0x56,0x7F,0x78,0x7A,0x78,0x76,0xA6,
+	  0x54,
+	  0x00,0x43,0x5E,0xDB,0x42,0xEF,0xAF,0xB2,0x98,0x9D,	/* y */
+	  0x51,0xFE,0xFC,0xE3,0xC8,0x09,0x88,0xF4,0x1F,0xF8,
+	  0x83,
+	  0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0x48,0xAA,0xB6,0x89,0xC2,0x9C,0xA7,0x10,0x27,
+	  0x9B }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
+	_EC_NIST_CHAR2_163B = {
+	{ NID_X9_62_characteristic_two_field,0,21,2 },
+	{							/* no seed */
+#if 0
+/* The seed here was used to created the curve parameters in normal
+ * basis representation (and not the polynomial representation used here) */
+	  0x85,0xE2,0x5B,0xFE,0x5C,0x86,0x22,0x6C,0xDB,0x12,
+	  0x01,0x6F,0x75,0x53,0xF9,0xD0,0xE6,0x93,0xA2,0x68,
+#endif
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0xC9,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x01,
+	  0x02,0x0A,0x60,0x19,0x07,0xB8,0xC9,0x53,0xCA,0x14,	/* b */
+	  0x81,0xEB,0x10,0x51,0x2F,0x78,0x74,0x4A,0x32,0x05,
+	  0xFD,
+	  0x03,0xF0,0xEB,0xA1,0x62,0x86,0xA2,0xD5,0x7E,0xA0,	/* x */
+	  0x99,0x11,0x68,0xD4,0x99,0x46,0x37,0xE8,0x34,0x3E,
+	  0x36,
+	  0x00,0xD5,0x1F,0xBC,0x6C,0x71,0xA0,0x09,0x4F,0xA2,	/* y */
+	  0xCD,0xD5,0x45,0xB1,0x1C,0x5C,0x0C,0x79,0x73,0x24,
+	  0xF1,
+	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x02,0x92,0xFE,0x77,0xE7,0x0C,0x12,0xA4,0x23,0x4C,
+	  0x33 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+25*6]; }
+	_EC_SECG_CHAR2_193R1 = {
+	{ NID_X9_62_characteristic_two_field,20,25,2 },
+	{ 0x10,0x3F,0xAE,0xC7,0x4D,0x69,0x6E,0x67,0x68,0x75,	/* seed */
+	  0x61,0x51,0x75,0x77,0x7F,0xC5,0xB1,0x91,0xEF,0x30,
+
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x80,0x01,
+	  0x00,0x17,0x85,0x8F,0xEB,0x7A,0x98,0x97,0x51,0x69,	/* a */
+	  0xE1,0x71,0xF7,0x7B,0x40,0x87,0xDE,0x09,0x8A,0xC8,
+	  0xA9,0x11,0xDF,0x7B,0x01,
+	  0x00,0xFD,0xFB,0x49,0xBF,0xE6,0xC3,0xA8,0x9F,0xAC,	/* b */
+	  0xAD,0xAA,0x7A,0x1E,0x5B,0xBC,0x7C,0xC1,0xC2,0xE5,
+	  0xD8,0x31,0x47,0x88,0x14,
+	  0x01,0xF4,0x81,0xBC,0x5F,0x0F,0xF8,0x4A,0x74,0xAD,	/* x */
+	  0x6C,0xDF,0x6F,0xDE,0xF4,0xBF,0x61,0x79,0x62,0x53,
+	  0x72,0xD8,0xC0,0xC5,0xE1,
+	  0x00,0x25,0xE3,0x99,0xF2,0x90,0x37,0x12,0xCC,0xF3,	/* y */
+	  0xEA,0x9E,0x3A,0x1A,0xD1,0x7F,0xB0,0xB3,0x20,0x1B,
+	  0x6A,0xF7,0xCE,0x1B,0x05,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x00,0xC7,0xF3,0x4A,0x77,0x8F,0x44,0x3A,
+	  0xCC,0x92,0x0E,0xBA,0x49 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+25*6]; }
+	_EC_SECG_CHAR2_193R2 = {
+	{ NID_X9_62_characteristic_two_field,20,25,2 },
+	{ 0x10,0xB7,0xB4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,	/* seed */
+	  0x17,0x51,0x37,0xC8,0xA1,0x6F,0xD0,0xDA,0x22,0x11,
+
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x80,0x01,
+	  0x01,0x63,0xF3,0x5A,0x51,0x37,0xC2,0xCE,0x3E,0xA6,	/* a */
+	  0xED,0x86,0x67,0x19,0x0B,0x0B,0xC4,0x3E,0xCD,0x69,
+	  0x97,0x77,0x02,0x70,0x9B,
+	  0x00,0xC9,0xBB,0x9E,0x89,0x27,0xD4,0xD6,0x4C,0x37,	/* b */
+	  0x7E,0x2A,0xB2,0x85,0x6A,0x5B,0x16,0xE3,0xEF,0xB7,
+	  0xF6,0x1D,0x43,0x16,0xAE,
+	  0x00,0xD9,0xB6,0x7D,0x19,0x2E,0x03,0x67,0xC8,0x03,	/* x */
+	  0xF3,0x9E,0x1A,0x7E,0x82,0xCA,0x14,0xA6,0x51,0x35,
+	  0x0A,0xAE,0x61,0x7E,0x8F,
+	  0x01,0xCE,0x94,0x33,0x56,0x07,0xC3,0x04,0xAC,0x29,	/* y */
+	  0xE7,0xDE,0xFB,0xD9,0xCA,0x01,0xF5,0x96,0xF9,0x27,
+	  0x22,0x4C,0xDE,0xCF,0x6C,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x01,0x5A,0xAB,0x56,0x1B,0x00,0x54,0x13,
+	  0xCC,0xD4,0xEE,0x99,0xD5 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+30*6]; }
+	_EC_NIST_CHAR2_233K = {
+	{ NID_X9_62_characteristic_two_field,0,30,4 },
+	{							/* no seed */
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+
+	  0x01,0x72,0x32,0xBA,0x85,0x3A,0x7E,0x73,0x1A,0xF1,	/* x */
+	  0x29,0xF2,0x2F,0xF4,0x14,0x95,0x63,0xA4,0x19,0xC2,
+	  0x6B,0xF5,0x0A,0x4C,0x9D,0x6E,0xEF,0xAD,0x61,0x26,
+
+	  0x01,0xDB,0x53,0x7D,0xEC,0xE8,0x19,0xB7,0xF7,0x0F,	/* y */
+	  0x55,0x5A,0x67,0xC4,0x27,0xA8,0xCD,0x9B,0xF1,0x8A,
+	  0xEB,0x9B,0x56,0xE0,0xC1,0x10,0x56,0xFA,0xE6,0xA3,
+
+	  0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x00,0x00,0x00,0x06,0x9D,0x5B,0xB9,0x15,
+	  0xBC,0xD4,0x6E,0xFB,0x1A,0xD5,0xF1,0x73,0xAB,0xDF }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
+	_EC_NIST_CHAR2_233B = {
+	{ NID_X9_62_characteristic_two_field,20,30,2 },
+	{ 0x74,0xD5,0x9F,0xF0,0x7F,0x6B,0x41,0x3D,0x0E,0xA1,	/* seed */
+	  0x4B,0x34,0x4B,0x20,0xA2,0xDB,0x04,0x9B,0x50,0xC3,
+
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+
+	  0x00,0x66,0x64,0x7E,0xDE,0x6C,0x33,0x2C,0x7F,0x8C,	/* b */
+	  0x09,0x23,0xBB,0x58,0x21,0x3B,0x33,0x3B,0x20,0xE9,
+	  0xCE,0x42,0x81,0xFE,0x11,0x5F,0x7D,0x8F,0x90,0xAD,
+
+	  0x00,0xFA,0xC9,0xDF,0xCB,0xAC,0x83,0x13,0xBB,0x21,	/* x */
+	  0x39,0xF1,0xBB,0x75,0x5F,0xEF,0x65,0xBC,0x39,0x1F,
+	  0x8B,0x36,0xF8,0xF8,0xEB,0x73,0x71,0xFD,0x55,0x8B,
+
+	  0x01,0x00,0x6A,0x08,0xA4,0x19,0x03,0x35,0x06,0x78,	/* y */
+	  0xE5,0x85,0x28,0xBE,0xBF,0x8A,0x0B,0xEF,0xF8,0x67,
+	  0xA7,0xCA,0x36,0x71,0x6F,0x7E,0x01,0xF8,0x10,0x52,
+
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x00,0x00,0x00,0x13,0xE9,0x74,0xE7,0x2F,
+	  0x8A,0x69,0x22,0x03,0x1D,0x26,0x03,0xCF,0xE0,0xD7 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+30*6]; }
+	_EC_SECG_CHAR2_239K1 = {
+	{ NID_X9_62_characteristic_two_field,0,30,4 },
+	{							/* no seed */
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+
+	  0x29,0xA0,0xB6,0xA8,0x87,0xA9,0x83,0xE9,0x73,0x09,	/* x */
+	  0x88,0xA6,0x87,0x27,0xA8,0xB2,0xD1,0x26,0xC4,0x4C,
+	  0xC2,0xCC,0x7B,0x2A,0x65,0x55,0x19,0x30,0x35,0xDC,
+
+	  0x76,0x31,0x08,0x04,0xF1,0x2E,0x54,0x9B,0xDB,0x01,	/* y */
+	  0x1C,0x10,0x30,0x89,0xE7,0x35,0x10,0xAC,0xB2,0x75,
+	  0xFC,0x31,0x2A,0x5D,0xC6,0xB7,0x65,0x53,0xF0,0xCA,
+
+	  0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x00,0x00,0x00,0x5A,0x79,0xFE,0xC6,0x7C,
+	  0xB6,0xE9,0x1F,0x1C,0x1D,0xA8,0x00,0xE4,0x78,0xA5 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+36*6]; }
+	_EC_NIST_CHAR2_283K = {
+	{ NID_X9_62_characteristic_two_field,0,36,4 },
+	{							/* no seed */
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x10,0xA1,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x01,
+	  0x05,0x03,0x21,0x3F,0x78,0xCA,0x44,0x88,0x3F,0x1A,	/* x */
+	  0x3B,0x81,0x62,0xF1,0x88,0xE5,0x53,0xCD,0x26,0x5F,
+	  0x23,0xC1,0x56,0x7A,0x16,0x87,0x69,0x13,0xB0,0xC2,
+	  0xAC,0x24,0x58,0x49,0x28,0x36,
+	  0x01,0xCC,0xDA,0x38,0x0F,0x1C,0x9E,0x31,0x8D,0x90,	/* y */
+	  0xF9,0x5D,0x07,0xE5,0x42,0x6F,0xE8,0x7E,0x45,0xC0,
+	  0xE8,0x18,0x46,0x98,0xE4,0x59,0x62,0x36,0x4E,0x34,
+	  0x11,0x61,0x77,0xDD,0x22,0x59,
+	  0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE9,0xAE,
+	  0x2E,0xD0,0x75,0x77,0x26,0x5D,0xFF,0x7F,0x94,0x45,
+	  0x1E,0x06,0x1E,0x16,0x3C,0x61 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+36*6]; }
+	_EC_NIST_CHAR2_283B = {
+	{ NID_X9_62_characteristic_two_field,20,36,2 },
+	{ 0x77,0xE2,0xB0,0x73,0x70,0xEB,0x0F,0x83,0x2A,0x6D,	/* no seed */
+	  0xD5,0xB6,0x2D,0xFC,0x88,0xCD,0x06,0xBB,0x84,0xBE,
+
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x10,0xA1,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x01,
+	  0x02,0x7B,0x68,0x0A,0xC8,0xB8,0x59,0x6D,0xA5,0xA4,	/* b */
+	  0xAF,0x8A,0x19,0xA0,0x30,0x3F,0xCA,0x97,0xFD,0x76,
+	  0x45,0x30,0x9F,0xA2,0xA5,0x81,0x48,0x5A,0xF6,0x26,
+	  0x3E,0x31,0x3B,0x79,0xA2,0xF5,
+	  0x05,0xF9,0x39,0x25,0x8D,0xB7,0xDD,0x90,0xE1,0x93,	/* x */
+	  0x4F,0x8C,0x70,0xB0,0xDF,0xEC,0x2E,0xED,0x25,0xB8,
+	  0x55,0x7E,0xAC,0x9C,0x80,0xE2,0xE1,0x98,0xF8,0xCD,
+	  0xBE,0xCD,0x86,0xB1,0x20,0x53,
+	  0x03,0x67,0x68,0x54,0xFE,0x24,0x14,0x1C,0xB9,0x8F,	/* y */
+	  0xE6,0xD4,0xB2,0x0D,0x02,0xB4,0x51,0x6F,0xF7,0x02,
+	  0x35,0x0E,0xDD,0xB0,0x82,0x67,0x79,0xC8,0x13,0xF0,
+	  0xDF,0x45,0xBE,0x81,0x12,0xF4,
+	  0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0x90,
+	  0x39,0x96,0x60,0xFC,0x93,0x8A,0x90,0x16,0x5B,0x04,
+	  0x2A,0x7C,0xEF,0xAD,0xB3,0x07 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+52*6]; }
+	_EC_NIST_CHAR2_409K = {
+	{ NID_X9_62_characteristic_two_field,0,52,4 },
+	{							/* no seed */
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x01,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x01,
+	  0x00,0x60,0xF0,0x5F,0x65,0x8F,0x49,0xC1,0xAD,0x3A,	/* x */
+	  0xB1,0x89,0x0F,0x71,0x84,0x21,0x0E,0xFD,0x09,0x87,
+	  0xE3,0x07,0xC8,0x4C,0x27,0xAC,0xCF,0xB8,0xF9,0xF6,
+	  0x7C,0xC2,0xC4,0x60,0x18,0x9E,0xB5,0xAA,0xAA,0x62,
+	  0xEE,0x22,0x2E,0xB1,0xB3,0x55,0x40,0xCF,0xE9,0x02,
+	  0x37,0x46,
+	  0x01,0xE3,0x69,0x05,0x0B,0x7C,0x4E,0x42,0xAC,0xBA,	/* y */
+	  0x1D,0xAC,0xBF,0x04,0x29,0x9C,0x34,0x60,0x78,0x2F,
+	  0x91,0x8E,0xA4,0x27,0xE6,0x32,0x51,0x65,0xE9,0xEA,
+	  0x10,0xE3,0xDA,0x5F,0x6C,0x42,0xE9,0xC5,0x52,0x15,
+	  0xAA,0x9C,0xA2,0x7A,0x58,0x63,0xEC,0x48,0xD8,0xE0,
+	  0x28,0x6B,
+	  0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x5F,0x83,0xB2,
+	  0xD4,0xEA,0x20,0x40,0x0E,0xC4,0x55,0x7D,0x5E,0xD3,
+	  0xE3,0xE7,0xCA,0x5B,0x4B,0x5C,0x83,0xB8,0xE0,0x1E,
+	  0x5F,0xCF }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+52*6]; }
+	_EC_NIST_CHAR2_409B = {
+	{ NID_X9_62_characteristic_two_field,20,52,2 },
+	{ 0x40,0x99,0xB5,0xA4,0x57,0xF9,0xD6,0x9F,0x79,0x21,	/* seed */
+	  0x3D,0x09,0x4C,0x4B,0xCD,0x4D,0x42,0x62,0x21,0x0B,
+
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x01,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x01,
+	  0x00,0x21,0xA5,0xC2,0xC8,0xEE,0x9F,0xEB,0x5C,0x4B,	/* b */
+	  0x9A,0x75,0x3B,0x7B,0x47,0x6B,0x7F,0xD6,0x42,0x2E,
+	  0xF1,0xF3,0xDD,0x67,0x47,0x61,0xFA,0x99,0xD6,0xAC,
+	  0x27,0xC8,0xA9,0xA1,0x97,0xB2,0x72,0x82,0x2F,0x6C,
+	  0xD5,0x7A,0x55,0xAA,0x4F,0x50,0xAE,0x31,0x7B,0x13,
+	  0x54,0x5F,
+	  0x01,0x5D,0x48,0x60,0xD0,0x88,0xDD,0xB3,0x49,0x6B,	/* x */
+	  0x0C,0x60,0x64,0x75,0x62,0x60,0x44,0x1C,0xDE,0x4A,
+	  0xF1,0x77,0x1D,0x4D,0xB0,0x1F,0xFE,0x5B,0x34,0xE5,
+	  0x97,0x03,0xDC,0x25,0x5A,0x86,0x8A,0x11,0x80,0x51,
+	  0x56,0x03,0xAE,0xAB,0x60,0x79,0x4E,0x54,0xBB,0x79,
+	  0x96,0xA7,
+	  0x00,0x61,0xB1,0xCF,0xAB,0x6B,0xE5,0xF3,0x2B,0xBF,	/* y */
+	  0xA7,0x83,0x24,0xED,0x10,0x6A,0x76,0x36,0xB9,0xC5,
+	  0xA7,0xBD,0x19,0x8D,0x01,0x58,0xAA,0x4F,0x54,0x88,
+	  0xD0,0x8F,0x38,0x51,0x4F,0x1F,0xDF,0x4B,0x4F,0x40,
+	  0xD2,0x18,0x1B,0x36,0x81,0xC3,0x64,0xBA,0x02,0x73,
+	  0xC7,0x06,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xE2,0xAA,0xD6,
+	  0xA6,0x12,0xF3,0x33,0x07,0xBE,0x5F,0xA4,0x7C,0x3C,
+	  0x9E,0x05,0x2F,0x83,0x81,0x64,0xCD,0x37,0xD9,0xA2,
+	  0x11,0x73 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+72*6]; }
+	_EC_NIST_CHAR2_571K = {
+	{ NID_X9_62_characteristic_two_field,0,72,4 },
+	{							/* no seed */
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x04,0x25,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x01,
+	  0x02,0x6E,0xB7,0xA8,0x59,0x92,0x3F,0xBC,0x82,0x18,	/* x */
+	  0x96,0x31,0xF8,0x10,0x3F,0xE4,0xAC,0x9C,0xA2,0x97,
+	  0x00,0x12,0xD5,0xD4,0x60,0x24,0x80,0x48,0x01,0x84,
+	  0x1C,0xA4,0x43,0x70,0x95,0x84,0x93,0xB2,0x05,0xE6,
+	  0x47,0xDA,0x30,0x4D,0xB4,0xCE,0xB0,0x8C,0xBB,0xD1,
+	  0xBA,0x39,0x49,0x47,0x76,0xFB,0x98,0x8B,0x47,0x17,
+	  0x4D,0xCA,0x88,0xC7,0xE2,0x94,0x52,0x83,0xA0,0x1C,
+	  0x89,0x72,
+	  0x03,0x49,0xDC,0x80,0x7F,0x4F,0xBF,0x37,0x4F,0x4A,	/* y */
+	  0xEA,0xDE,0x3B,0xCA,0x95,0x31,0x4D,0xD5,0x8C,0xEC,
+	  0x9F,0x30,0x7A,0x54,0xFF,0xC6,0x1E,0xFC,0x00,0x6D,
+	  0x8A,0x2C,0x9D,0x49,0x79,0xC0,0xAC,0x44,0xAE,0xA7,
+	  0x4F,0xBE,0xBB,0xB9,0xF7,0x72,0xAE,0xDC,0xB6,0x20,
+	  0xB0,0x1A,0x7B,0xA7,0xAF,0x1B,0x32,0x04,0x30,0xC8,
+	  0x59,0x19,0x84,0xF6,0x01,0xCD,0x4C,0x14,0x3E,0xF1,
+	  0xC7,0xA3,
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x18,0x50,0xE1,
+	  0xF1,0x9A,0x63,0xE4,0xB3,0x91,0xA8,0xDB,0x91,0x7F,
+	  0x41,0x38,0xB6,0x30,0xD8,0x4B,0xE5,0xD6,0x39,0x38,
+	  0x1E,0x91,0xDE,0xB4,0x5C,0xFE,0x77,0x8F,0x63,0x7C,
+	  0x10,0x01 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+72*6]; }
+	_EC_NIST_CHAR2_571B = {
+	{ NID_X9_62_characteristic_two_field,20,72,2 },
+	{ 0x2A,0xA0,0x58,0xF7,0x3A,0x0E,0x33,0xAB,0x48,0x6B,	/* seed */
+	  0x0F,0x61,0x04,0x10,0xC5,0x3A,0x7F,0x13,0x23,0x10,
+
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x04,0x25,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x01,
+	  0x02,0xF4,0x0E,0x7E,0x22,0x21,0xF2,0x95,0xDE,0x29,	/* b */
+	  0x71,0x17,0xB7,0xF3,0xD6,0x2F,0x5C,0x6A,0x97,0xFF,
+	  0xCB,0x8C,0xEF,0xF1,0xCD,0x6B,0xA8,0xCE,0x4A,0x9A,
+	  0x18,0xAD,0x84,0xFF,0xAB,0xBD,0x8E,0xFA,0x59,0x33,
+	  0x2B,0xE7,0xAD,0x67,0x56,0xA6,0x6E,0x29,0x4A,0xFD,
+	  0x18,0x5A,0x78,0xFF,0x12,0xAA,0x52,0x0E,0x4D,0xE7,
+	  0x39,0xBA,0xCA,0x0C,0x7F,0xFE,0xFF,0x7F,0x29,0x55,
+	  0x72,0x7A,
+	  0x03,0x03,0x00,0x1D,0x34,0xB8,0x56,0x29,0x6C,0x16,	/* x */
+	  0xC0,0xD4,0x0D,0x3C,0xD7,0x75,0x0A,0x93,0xD1,0xD2,
+	  0x95,0x5F,0xA8,0x0A,0xA5,0xF4,0x0F,0xC8,0xDB,0x7B,
+	  0x2A,0xBD,0xBD,0xE5,0x39,0x50,0xF4,0xC0,0xD2,0x93,
+	  0xCD,0xD7,0x11,0xA3,0x5B,0x67,0xFB,0x14,0x99,0xAE,
+	  0x60,0x03,0x86,0x14,0xF1,0x39,0x4A,0xBF,0xA3,0xB4,
+	  0xC8,0x50,0xD9,0x27,0xE1,0xE7,0x76,0x9C,0x8E,0xEC,
+	  0x2D,0x19,
+	  0x03,0x7B,0xF2,0x73,0x42,0xDA,0x63,0x9B,0x6D,0xCC,	/* y */
+	  0xFF,0xFE,0xB7,0x3D,0x69,0xD7,0x8C,0x6C,0x27,0xA6,
+	  0x00,0x9C,0xBB,0xCA,0x19,0x80,0xF8,0x53,0x39,0x21,
+	  0xE8,0xA6,0x84,0x42,0x3E,0x43,0xBA,0xB0,0x8A,0x57,
+	  0x62,0x91,0xAF,0x8F,0x46,0x1B,0xB2,0xA8,0xB3,0x53,
+	  0x1D,0x2F,0x04,0x85,0xC1,0x9B,0x16,0xE2,0xF1,0x51,
+	  0x6E,0x23,0xDD,0x3C,0x1A,0x48,0x27,0xAF,0x1B,0x8A,
+	  0xC1,0x5B,
+	  0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6,0x61,0xCE,0x18,
+	  0xFF,0x55,0x98,0x73,0x08,0x05,0x9B,0x18,0x68,0x23,
+	  0x85,0x1E,0xC7,0xDD,0x9C,0xA1,0x16,0x1D,0xE9,0x3D,
+	  0x51,0x74,0xD6,0x6E,0x83,0x82,0xE9,0xBB,0x2F,0xE8,
+	  0x4E,0x47 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
+	_EC_X9_62_CHAR2_163V1 = {
+	{ NID_X9_62_characteristic_two_field,20,21,2 },
+	{ 0xD2,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE,
+	  0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x54,	/* seed */
+
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+	  0x07,
+	  0x07,0x25,0x46,0xB5,0x43,0x52,0x34,0xA4,0x22,0xE0,	/* a */
+	  0x78,0x96,0x75,0xF4,0x32,0xC8,0x94,0x35,0xDE,0x52,
+	  0x42,
+	  0x00,0xC9,0x51,0x7D,0x06,0xD5,0x24,0x0D,0x3C,0xFF,	/* b */
+	  0x38,0xC7,0x4B,0x20,0xB6,0xCD,0x4D,0x6F,0x9D,0xD4,
+	  0xD9,
+	  0x07,0xAF,0x69,0x98,0x95,0x46,0x10,0x3D,0x79,0x32,	/* x */
+	  0x9F,0xCC,0x3D,0x74,0x88,0x0F,0x33,0xBB,0xE8,0x03,
+	  0xCB,
+	  0x01,0xEC,0x23,0x21,0x1B,0x59,0x66,0xAD,0xEA,0x1D,	/* y */
+	  0x3F,0x87,0xF7,0xEA,0x58,0x48,0xAE,0xF0,0xB7,0xCA,
+	  0x9F,
+	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x01,0xE6,0x0F,0xC8,0x82,0x1C,0xC7,0x4D,0xAE,0xAF,
+	  0xC1 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
+	_EC_X9_62_CHAR2_163V2 = {
+	{ NID_X9_62_characteristic_two_field,20,21,2 },
+	{ 0x53,0x81,0x4C,0x05,0x0D,0x44,0xD6,0x96,0xE6,0x76,	/* seed */
+	  0x87,0x56,0x15,0x17,0x58,0x0C,0xA4,0xE2,0x9F,0xFD,
+
+ 	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+	  0x07,
+	  0x01,0x08,0xB3,0x9E,0x77,0xC4,0xB1,0x08,0xBE,0xD9,	/* a */
+	  0x81,0xED,0x0E,0x89,0x0E,0x11,0x7C,0x51,0x1C,0xF0,
+	  0x72,
+	  0x06,0x67,0xAC,0xEB,0x38,0xAF,0x4E,0x48,0x8C,0x40,	/* b */
+	  0x74,0x33,0xFF,0xAE,0x4F,0x1C,0x81,0x16,0x38,0xDF,
+	  0x20,
+	  0x00,0x24,0x26,0x6E,0x4E,0xB5,0x10,0x6D,0x0A,0x96,	/* x */
+	  0x4D,0x92,0xC4,0x86,0x0E,0x26,0x71,0xDB,0x9B,0x6C,
+	  0xC5,
+	  0x07,0x9F,0x68,0x4D,0xDF,0x66,0x84,0xC5,0xCD,0x25,	/* y */
+	  0x8B,0x38,0x90,0x02,0x1B,0x23,0x86,0xDF,0xD1,0x9F,
+	  0xC5,
+	  0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFD,0xF6,0x4D,0xE1,0x15,0x1A,0xDB,0xB7,0x8F,0x10,
+	  0xA7 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
+	_EC_X9_62_CHAR2_163V3 = {
+	{ NID_X9_62_characteristic_two_field,20,21,2 },
+	{ 0x50,0xCB,0xF1,0xD9,0x5C,0xA9,0x4D,0x69,0x6E,0x67,	/* seed */
+	  0x68,0x75,0x61,0x51,0x75,0xF1,0x6A,0x36,0xA3,0xB8,
+
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+	  0x07,
+	  0x07,0xA5,0x26,0xC6,0x3D,0x3E,0x25,0xA2,0x56,0xA0,	/* a */
+	  0x07,0x69,0x9F,0x54,0x47,0xE3,0x2A,0xE4,0x56,0xB5,
+	  0x0E,
+	  0x03,0xF7,0x06,0x17,0x98,0xEB,0x99,0xE2,0x38,0xFD,	/* b */
+	  0x6F,0x1B,0xF9,0x5B,0x48,0xFE,0xEB,0x48,0x54,0x25,
+	  0x2B,
+	  0x02,0xF9,0xF8,0x7B,0x7C,0x57,0x4D,0x0B,0xDE,0xCF,	/* x */
+	  0x8A,0x22,0xE6,0x52,0x47,0x75,0xF9,0x8C,0xDE,0xBD,
+	  0xCB,
+	  0x05,0xB9,0x35,0x59,0x0C,0x15,0x5E,0x17,0xEA,0x48,	/* y */
+	  0xEB,0x3F,0xF3,0x71,0x8B,0x89,0x3D,0xF5,0x9A,0x05,
+	  0xD0,
+	  0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFE,0x1A,0xEE,0x14,0x0F,0x11,0x0A,0xFF,0x96,0x13,
+	  0x09 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+23*6]; }
+	_EC_X9_62_CHAR2_176V1 = {
+	{ NID_X9_62_characteristic_two_field,0,23,0xFF6E },
+	{							/* no seed */
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,
+	  0x00,0x00,0x07,
+	  0x00,0xE4,0xE6,0xDB,0x29,0x95,0x06,0x5C,0x40,0x7D,	/* a */
+	  0x9D,0x39,0xB8,0xD0,0x96,0x7B,0x96,0x70,0x4B,0xA8,
+	  0xE9,0xC9,0x0B,
+	  0x00,0x5D,0xDA,0x47,0x0A,0xBE,0x64,0x14,0xDE,0x8E,	/* b */
+	  0xC1,0x33,0xAE,0x28,0xE9,0xBB,0xD7,0xFC,0xEC,0x0A,
+	  0xE0,0xFF,0xF2,
+	  0x00,0x8D,0x16,0xC2,0x86,0x67,0x98,0xB6,0x00,0xF9,	/* x */
+	  0xF0,0x8B,0xB4,0xA8,0xE8,0x60,0xF3,0x29,0x8C,0xE0,
+	  0x4A,0x57,0x98,
+	  0x00,0x6F,0xA4,0x53,0x9C,0x2D,0xAD,0xDD,0xD6,0xBA,	/* y */
+	  0xB5,0x16,0x7D,0x61,0xB4,0x36,0xE1,0xD9,0x2B,0xB1,
+	  0x6A,0x56,0x2C,
+	  0x00,0x00,0x01,0x00,0x92,0x53,0x73,0x97,0xEC,0xA4,	/* order */
+	  0xF6,0x14,0x57,0x99,0xD6,0x2B,0x0A,0x19,0xCE,0x06,
+	  0xFE,0x26,0xAD }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
+	_EC_X9_62_CHAR2_191V1 = {
+	{ NID_X9_62_characteristic_two_field,20,24,2 },
+	{ 0x4E,0x13,0xCA,0x54,0x27,0x44,0xD6,0x96,0xE6,0x76,	/* seed */
+	  0x87,0x56,0x15,0x17,0x55,0x2F,0x27,0x9A,0x8C,0x84,
+
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x02,0x01,
+	  0x28,0x66,0x53,0x7B,0x67,0x67,0x52,0x63,0x6A,0x68,	/* a */
+	  0xF5,0x65,0x54,0xE1,0x26,0x40,0x27,0x6B,0x64,0x9E,
+	  0xF7,0x52,0x62,0x67,
+	  0x2E,0x45,0xEF,0x57,0x1F,0x00,0x78,0x6F,0x67,0xB0,	/* b */
+	  0x08,0x1B,0x94,0x95,0xA3,0xD9,0x54,0x62,0xF5,0xDE,
+	  0x0A,0xA1,0x85,0xEC,
+	  0x36,0xB3,0xDA,0xF8,0xA2,0x32,0x06,0xF9,0xC4,0xF2,	/* x */
+	  0x99,0xD7,0xB2,0x1A,0x9C,0x36,0x91,0x37,0xF2,0xC8,
+	  0x4A,0xE1,0xAA,0x0D,
+	  0x76,0x5B,0xE7,0x34,0x33,0xB3,0xF9,0x5E,0x33,0x29,	/* y */
+	  0x32,0xE7,0x0E,0xA2,0x45,0xCA,0x24,0x18,0xEA,0x0E,
+	  0xF9,0x80,0x18,0xFB,
+	  0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x04,0xA2,0x0E,0x90,0xC3,0x90,0x67,0xC8,
+	  0x93,0xBB,0xB9,0xA5 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
+	_EC_X9_62_CHAR2_191V2 = {
+	{ NID_X9_62_characteristic_two_field,20,24,4 },
+	{ 0x08,0x71,0xEF,0x2F,0xEF,0x24,0xD6,0x96,0xE6,0x76,	/* seed */
+	  0x87,0x56,0x15,0x17,0x58,0xBE,0xE0,0xD9,0x5C,0x15,
+
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x02,0x01,
+	  0x40,0x10,0x28,0x77,0x4D,0x77,0x77,0xC7,0xB7,0x66,	/* a */
+	  0x6D,0x13,0x66,0xEA,0x43,0x20,0x71,0x27,0x4F,0x89,
+	  0xFF,0x01,0xE7,0x18,
+	  0x06,0x20,0x04,0x8D,0x28,0xBC,0xBD,0x03,0xB6,0x24,	/* b */
+	  0x9C,0x99,0x18,0x2B,0x7C,0x8C,0xD1,0x97,0x00,0xC3,
+	  0x62,0xC4,0x6A,0x01,
+	  0x38,0x09,0xB2,0xB7,0xCC,0x1B,0x28,0xCC,0x5A,0x87,	/* x */
+	  0x92,0x6A,0xAD,0x83,0xFD,0x28,0x78,0x9E,0x81,0xE2,
+	  0xC9,0xE3,0xBF,0x10,
+	  0x17,0x43,0x43,0x86,0x62,0x6D,0x14,0xF3,0xDB,0xF0,	/* y */
+	  0x17,0x60,0xD9,0x21,0x3A,0x3E,0x1C,0xF3,0x7A,0xEC,
+	  0x43,0x7D,0x66,0x8A,
+	  0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x50,0x50,0x8C,0xB8,0x9F,0x65,0x28,0x24,
+	  0xE0,0x6B,0x81,0x73 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
+	_EC_X9_62_CHAR2_191V3 = {
+	{ NID_X9_62_characteristic_two_field,20,24,6 },
+	{ 0xE0,0x53,0x51,0x2D,0xC6,0x84,0xD6,0x96,0xE6,0x76,	/* seed */
+	  0x87,0x56,0x15,0x17,0x50,0x67,0xAE,0x78,0x6D,0x1F,
+
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x02,0x01,
+	  0x6C,0x01,0x07,0x47,0x56,0x09,0x91,0x22,0x22,0x10,	/* a */
+	  0x56,0x91,0x1C,0x77,0xD7,0x7E,0x77,0xA7,0x77,0xE7,
+	  0xE7,0xE7,0x7F,0xCB,
+	  0x71,0xFE,0x1A,0xF9,0x26,0xCF,0x84,0x79,0x89,0xEF,	/* b */
+	  0xEF,0x8D,0xB4,0x59,0xF6,0x63,0x94,0xD9,0x0F,0x32,
+	  0xAD,0x3F,0x15,0xE8,
+	  0x37,0x5D,0x4C,0xE2,0x4F,0xDE,0x43,0x44,0x89,0xDE,	/* x */
+	  0x87,0x46,0xE7,0x17,0x86,0x01,0x50,0x09,0xE6,0x6E,
+	  0x38,0xA9,0x26,0xDD,
+	  0x54,0x5A,0x39,0x17,0x61,0x96,0x57,0x5D,0x98,0x59,	/* y */
+	  0x99,0x36,0x6E,0x6A,0xD3,0x4C,0xE0,0xA7,0x7C,0xD7,
+	  0x12,0x7B,0x06,0xBE,
+	  0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,	/* order */
+	  0x55,0x55,0x61,0x0C,0x0B,0x19,0x68,0x12,0xBF,0xB6,
+	  0x28,0x8A,0x3E,0xA3 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+27*6]; }
+	_EC_X9_62_CHAR2_208W1 = {
+	{ NID_X9_62_characteristic_two_field,0,27,0xFE48 },
+	{							/* no seed */
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0xC8,0x61,0x9E,0xD4,0x5A,0x62,0xE6,0x21,0x2E,	/* b */
+	  0x11,0x60,0x34,0x9E,0x2B,0xFA,0x84,0x44,0x39,0xFA,
+	  0xFC,0x2A,0x3F,0xD1,0x63,0x8F,0x9E,
+	  0x00,0x89,0xFD,0xFB,0xE4,0xAB,0xE1,0x93,0xDF,0x95,	/* x */
+	  0x59,0xEC,0xF0,0x7A,0xC0,0xCE,0x78,0x55,0x4E,0x27,
+	  0x84,0xEB,0x8C,0x1E,0xD1,0xA5,0x7A,
+	  0x00,0x0F,0x55,0xB5,0x1A,0x06,0xE7,0x8E,0x9A,0xC3,	/* y */
+	  0x8A,0x03,0x5F,0xF5,0x20,0xD8,0xB0,0x17,0x81,0xBE,
+	  0xB1,0xA6,0xBB,0x08,0x61,0x7D,0xE3,
+	  0x00,0x00,0x01,0x01,0xBA,0xF9,0x5C,0x97,0x23,0xC5,	/* order */
+	  0x7B,0x6C,0x21,0xDA,0x2E,0xFF,0x2D,0x5E,0xD5,0x88,
+	  0xBD,0xD5,0x71,0x7E,0x21,0x2F,0x9D }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
+	_EC_X9_62_CHAR2_239V1 = {
+	{ NID_X9_62_characteristic_two_field,20,30,4 },
+	{ 0xD3,0x4B,0x9A,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,	/* seed */
+	  0x51,0x75,0xCA,0x71,0xB9,0x20,0xBF,0xEF,0xB0,0x5D,
+
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
+
+	  0x32,0x01,0x08,0x57,0x07,0x7C,0x54,0x31,0x12,0x3A,	/* a */
+	  0x46,0xB8,0x08,0x90,0x67,0x56,0xF5,0x43,0x42,0x3E,
+	  0x8D,0x27,0x87,0x75,0x78,0x12,0x57,0x78,0xAC,0x76,
+
+	  0x79,0x04,0x08,0xF2,0xEE,0xDA,0xF3,0x92,0xB0,0x12,	/* b */
+	  0xED,0xEF,0xB3,0x39,0x2F,0x30,0xF4,0x32,0x7C,0x0C,
+	  0xA3,0xF3,0x1F,0xC3,0x83,0xC4,0x22,0xAA,0x8C,0x16,
+
+	  0x57,0x92,0x70,0x98,0xFA,0x93,0x2E,0x7C,0x0A,0x96,	/* x */
+	  0xD3,0xFD,0x5B,0x70,0x6E,0xF7,0xE5,0xF5,0xC1,0x56,
+	  0xE1,0x6B,0x7E,0x7C,0x86,0x03,0x85,0x52,0xE9,0x1D,
+
+	  0x61,0xD8,0xEE,0x50,0x77,0xC3,0x3F,0xEC,0xF6,0xF1,	/* y */
+	  0xA1,0x6B,0x26,0x8D,0xE4,0x69,0xC3,0xC7,0x74,0x4E,
+	  0xA9,0xA9,0x71,0x64,0x9F,0xC7,0xA9,0x61,0x63,0x05,
+
+	  0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x00,0x00,0x00,0x0F,0x4D,0x42,0xFF,0xE1,
+	  0x49,0x2A,0x49,0x93,0xF1,0xCA,0xD6,0x66,0xE4,0x47 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
+	_EC_X9_62_CHAR2_239V2 = {
+	{ NID_X9_62_characteristic_two_field,20,30,6 },
+	{ 0x2A,0xA6,0x98,0x2F,0xDF,0xA4,0xD6,0x96,0xE6,0x76,	/* seed */
+	  0x87,0x56,0x15,0x17,0x5D,0x26,0x67,0x27,0x27,0x7D,
+
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
+
+	  0x42,0x30,0x01,0x77,0x57,0xA7,0x67,0xFA,0xE4,0x23,	/* a */
+	  0x98,0x56,0x9B,0x74,0x63,0x25,0xD4,0x53,0x13,0xAF,
+	  0x07,0x66,0x26,0x64,0x79,0xB7,0x56,0x54,0xE6,0x5F,
+
+	  0x50,0x37,0xEA,0x65,0x41,0x96,0xCF,0xF0,0xCD,0x82,	/* b */
+	  0xB2,0xC1,0x4A,0x2F,0xCF,0x2E,0x3F,0xF8,0x77,0x52,
+	  0x85,0xB5,0x45,0x72,0x2F,0x03,0xEA,0xCD,0xB7,0x4B,
+
+	  0x28,0xF9,0xD0,0x4E,0x90,0x00,0x69,0xC8,0xDC,0x47,	/* x */
+	  0xA0,0x85,0x34,0xFE,0x76,0xD2,0xB9,0x00,0xB7,0xD7,
+	  0xEF,0x31,0xF5,0x70,0x9F,0x20,0x0C,0x4C,0xA2,0x05,
+
+	  0x56,0x67,0x33,0x4C,0x45,0xAF,0xF3,0xB5,0xA0,0x3B,	/* y */
+	  0xAD,0x9D,0xD7,0x5E,0x2C,0x71,0xA9,0x93,0x62,0x56,
+	  0x7D,0x54,0x53,0xF7,0xFA,0x6E,0x22,0x7E,0xC8,0x33,
+
+	  0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,	/* order */
+	  0x55,0x55,0x55,0x55,0x55,0x3C,0x6F,0x28,0x85,0x25,
+	  0x9C,0x31,0xE3,0xFC,0xDF,0x15,0x46,0x24,0x52,0x2D }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
+	_EC_X9_62_CHAR2_239V3 = {
+	{ NID_X9_62_characteristic_two_field,20,30,0xA },
+	{ 0x9E,0x07,0x6F,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,	/* seed */
+	  0x51,0x75,0xE1,0x1E,0x9F,0xDD,0x77,0xF9,0x20,0x41,
+
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
+
+	  0x01,0x23,0x87,0x74,0x66,0x6A,0x67,0x76,0x6D,0x66,	/* a */
+	  0x76,0xF7,0x78,0xE6,0x76,0xB6,0x69,0x99,0x17,0x66,
+	  0x66,0xE6,0x87,0x66,0x6D,0x87,0x66,0xC6,0x6A,0x9F,
+
+	  0x6A,0x94,0x19,0x77,0xBA,0x9F,0x6A,0x43,0x51,0x99,	/* b */
+	  0xAC,0xFC,0x51,0x06,0x7E,0xD5,0x87,0xF5,0x19,0xC5,
+	  0xEC,0xB5,0x41,0xB8,0xE4,0x41,0x11,0xDE,0x1D,0x40,
+
+	  0x70,0xF6,0xE9,0xD0,0x4D,0x28,0x9C,0x4E,0x89,0x91,	/* x */
+	  0x3C,0xE3,0x53,0x0B,0xFD,0xE9,0x03,0x97,0x7D,0x42,
+	  0xB1,0x46,0xD5,0x39,0xBF,0x1B,0xDE,0x4E,0x9C,0x92,
+
+	  0x2E,0x5A,0x0E,0xAF,0x6E,0x5E,0x13,0x05,0xB9,0x00,	/* y */
+	  0x4D,0xCE,0x5C,0x0E,0xD7,0xFE,0x59,0xA3,0x56,0x08,
+	  0xF3,0x38,0x37,0xC8,0x16,0xD8,0x0B,0x79,0xF4,0x61,
+
+	  0x0C,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,	/* order */
+	  0xCC,0xCC,0xCC,0xCC,0xCC,0xAC,0x49,0x12,0xD2,0xD9,
+	  0xDF,0x90,0x3E,0xF9,0x88,0x8B,0x8A,0x0E,0x4C,0xFF }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+35*6]; }
+	_EC_X9_62_CHAR2_272W1 = {
+	{ NID_X9_62_characteristic_two_field,0,35,0xFF06 },
+	{							/* no seed */
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x0B,
+	  0x00,0x91,0xA0,0x91,0xF0,0x3B,0x5F,0xBA,0x4A,0xB2,	/* a */
+	  0xCC,0xF4,0x9C,0x4E,0xDD,0x22,0x0F,0xB0,0x28,0x71,
+	  0x2D,0x42,0xBE,0x75,0x2B,0x2C,0x40,0x09,0x4D,0xBA,
+	  0xCD,0xB5,0x86,0xFB,0x20,
+	  0x00,0x71,0x67,0xEF,0xC9,0x2B,0xB2,0xE3,0xCE,0x7C,	/* b */
+	  0x8A,0xAA,0xFF,0x34,0xE1,0x2A,0x9C,0x55,0x70,0x03,
+	  0xD7,0xC7,0x3A,0x6F,0xAF,0x00,0x3F,0x99,0xF6,0xCC,
+	  0x84,0x82,0xE5,0x40,0xF7,
+	  0x00,0x61,0x08,0xBA,0xBB,0x2C,0xEE,0xBC,0xF7,0x87,	/* x */
+	  0x05,0x8A,0x05,0x6C,0xBE,0x0C,0xFE,0x62,0x2D,0x77,
+	  0x23,0xA2,0x89,0xE0,0x8A,0x07,0xAE,0x13,0xEF,0x0D,
+	  0x10,0xD1,0x71,0xDD,0x8D,
+	  0x00,0x10,0xC7,0x69,0x57,0x16,0x85,0x1E,0xEF,0x6B,	/* y */
+	  0xA7,0xF6,0x87,0x2E,0x61,0x42,0xFB,0xD2,0x41,0xB8,
+	  0x30,0xFF,0x5E,0xFC,0xAC,0xEC,0xCA,0xB0,0x5E,0x02,
+	  0x00,0x5D,0xDE,0x9D,0x23,
+	  0x00,0x00,0x01,0x00,0xFA,0xF5,0x13,0x54,0xE0,0xE3,	/* order */
+	  0x9E,0x48,0x92,0xDF,0x6E,0x31,0x9C,0x72,0xC8,0x16,
+	  0x16,0x03,0xFA,0x45,0xAA,0x7B,0x99,0x8A,0x16,0x7B,
+	  0x8F,0x1E,0x62,0x95,0x21 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+39*6]; }
+	_EC_X9_62_CHAR2_304W1 = {
+	{ NID_X9_62_characteristic_two_field,0,39,0xFE2E },
+	{							/* no seed */
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x07,
+	  0x00,0xFD,0x0D,0x69,0x31,0x49,0xA1,0x18,0xF6,0x51,	/* a */
+	  0xE6,0xDC,0xE6,0x80,0x20,0x85,0x37,0x7E,0x5F,0x88,
+	  0x2D,0x1B,0x51,0x0B,0x44,0x16,0x00,0x74,0xC1,0x28,
+	  0x80,0x78,0x36,0x5A,0x03,0x96,0xC8,0xE6,0x81,
+	  0x00,0xBD,0xDB,0x97,0xE5,0x55,0xA5,0x0A,0x90,0x8E,	/* b */
+	  0x43,0xB0,0x1C,0x79,0x8E,0xA5,0xDA,0xA6,0x78,0x8F,
+	  0x1E,0xA2,0x79,0x4E,0xFC,0xF5,0x71,0x66,0xB8,0xC1,
+	  0x40,0x39,0x60,0x1E,0x55,0x82,0x73,0x40,0xBE,
+	  0x00,0x19,0x7B,0x07,0x84,0x5E,0x9B,0xE2,0xD9,0x6A,	/* x */
+	  0xDB,0x0F,0x5F,0x3C,0x7F,0x2C,0xFF,0xBD,0x7A,0x3E,
+	  0xB8,0xB6,0xFE,0xC3,0x5C,0x7F,0xD6,0x7F,0x26,0xDD,
+	  0xF6,0x28,0x5A,0x64,0x4F,0x74,0x0A,0x26,0x14,
+	  0x00,0xE1,0x9F,0xBE,0xB7,0x6E,0x0D,0xA1,0x71,0x51,	/* y */
+	  0x7E,0xCF,0x40,0x1B,0x50,0x28,0x9B,0xF0,0x14,0x10,
+	  0x32,0x88,0x52,0x7A,0x9B,0x41,0x6A,0x10,0x5E,0x80,
+	  0x26,0x0B,0x54,0x9F,0xDC,0x1B,0x92,0xC0,0x3B,
+	  0x00,0x00,0x01,0x01,0xD5,0x56,0x57,0x2A,0xAB,0xAC,	/* order */
+	  0x80,0x01,0x01,0xD5,0x56,0x57,0x2A,0xAB,0xAC,0x80,
+	  0x01,0x02,0x2D,0x5C,0x91,0xDD,0x17,0x3F,0x8F,0xB5,
+	  0x61,0xDA,0x68,0x99,0x16,0x44,0x43,0x05,0x1D }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+45*6]; }
+	_EC_X9_62_CHAR2_359V1 = {
+	{ NID_X9_62_characteristic_two_field,20,45,0x4C },
+	{ 0x2B,0x35,0x49,0x20,0xB7,0x24,0xD6,0x96,0xE6,0x76,	/* seed */
+	  0x87,0x56,0x15,0x17,0x58,0x5B,0xA1,0x33,0x2D,0xC6,
+
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x01,
+	  0x56,0x67,0x67,0x6A,0x65,0x4B,0x20,0x75,0x4F,0x35,	/* a */
+	  0x6E,0xA9,0x20,0x17,0xD9,0x46,0x56,0x7C,0x46,0x67,
+	  0x55,0x56,0xF1,0x95,0x56,0xA0,0x46,0x16,0xB5,0x67,
+	  0xD2,0x23,0xA5,0xE0,0x56,0x56,0xFB,0x54,0x90,0x16,
+	  0xA9,0x66,0x56,0xA5,0x57,
+	  0x24,0x72,0xE2,0xD0,0x19,0x7C,0x49,0x36,0x3F,0x1F,	/* b */
+	  0xE7,0xF5,0xB6,0xDB,0x07,0x5D,0x52,0xB6,0x94,0x7D,
+	  0x13,0x5D,0x8C,0xA4,0x45,0x80,0x5D,0x39,0xBC,0x34,
+	  0x56,0x26,0x08,0x96,0x87,0x74,0x2B,0x63,0x29,0xE7,
+	  0x06,0x80,0x23,0x19,0x88,
+	  0x3C,0x25,0x8E,0xF3,0x04,0x77,0x67,0xE7,0xED,0xE0,	/* x */
+	  0xF1,0xFD,0xAA,0x79,0xDA,0xEE,0x38,0x41,0x36,0x6A,
+	  0x13,0x2E,0x16,0x3A,0xCE,0xD4,0xED,0x24,0x01,0xDF,
+	  0x9C,0x6B,0xDC,0xDE,0x98,0xE8,0xE7,0x07,0xC0,0x7A,
+	  0x22,0x39,0xB1,0xB0,0x97,
+	  0x53,0xD7,0xE0,0x85,0x29,0x54,0x70,0x48,0x12,0x1E,	/* y */
+	  0x9C,0x95,0xF3,0x79,0x1D,0xD8,0x04,0x96,0x39,0x48,
+	  0xF3,0x4F,0xAE,0x7B,0xF4,0x4E,0xA8,0x23,0x65,0xDC,
+	  0x78,0x68,0xFE,0x57,0xE4,0xAE,0x2D,0xE2,0x11,0x30,
+	  0x5A,0x40,0x71,0x04,0xBD,
+	  0x01,0xAF,0x28,0x6B,0xCA,0x1A,0xF2,0x86,0xBC,0xA1,	/* order */
+	  0xAF,0x28,0x6B,0xCA,0x1A,0xF2,0x86,0xBC,0xA1,0xAF,
+	  0x28,0x6B,0xC9,0xFB,0x8F,0x6B,0x85,0xC5,0x56,0x89,
+	  0x2C,0x20,0xA7,0xEB,0x96,0x4F,0xE7,0x71,0x9E,0x74,
+	  0xF4,0x90,0x75,0x8D,0x3B }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+47*6]; }
+	_EC_X9_62_CHAR2_368W1 = {
+	{ NID_X9_62_characteristic_two_field,0,47,0xFF70 },
+	{							/* no seed */
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+	  0x00,0xE0,0xD2,0xEE,0x25,0x09,0x52,0x06,0xF5,0xE2,	/* a */
+	  0xA4,0xF9,0xED,0x22,0x9F,0x1F,0x25,0x6E,0x79,0xA0,
+	  0xE2,0xB4,0x55,0x97,0x0D,0x8D,0x0D,0x86,0x5B,0xD9,
+	  0x47,0x78,0xC5,0x76,0xD6,0x2F,0x0A,0xB7,0x51,0x9C,
+	  0xCD,0x2A,0x1A,0x90,0x6A,0xE3,0x0D,
+	  0x00,0xFC,0x12,0x17,0xD4,0x32,0x0A,0x90,0x45,0x2C,	/* b */
+	  0x76,0x0A,0x58,0xED,0xCD,0x30,0xC8,0xDD,0x06,0x9B,
+	  0x3C,0x34,0x45,0x38,0x37,0xA3,0x4E,0xD5,0x0C,0xB5,
+	  0x49,0x17,0xE1,0xC2,0x11,0x2D,0x84,0xD1,0x64,0xF4,
+	  0x44,0xF8,0xF7,0x47,0x86,0x04,0x6A,
+	  0x00,0x10,0x85,0xE2,0x75,0x53,0x81,0xDC,0xCC,0xE3,	/* x */
+	  0xC1,0x55,0x7A,0xFA,0x10,0xC2,0xF0,0xC0,0xC2,0x82,
+	  0x56,0x46,0xC5,0xB3,0x4A,0x39,0x4C,0xBC,0xFA,0x8B,
+	  0xC1,0x6B,0x22,0xE7,0xE7,0x89,0xE9,0x27,0xBE,0x21,
+	  0x6F,0x02,0xE1,0xFB,0x13,0x6A,0x5F,
+	  0x00,0x7B,0x3E,0xB1,0xBD,0xDC,0xBA,0x62,0xD5,0xD8,	/* y */
+	  0xB2,0x05,0x9B,0x52,0x57,0x97,0xFC,0x73,0x82,0x2C,
+	  0x59,0x05,0x9C,0x62,0x3A,0x45,0xFF,0x38,0x43,0xCE,
+	  0xE8,0xF8,0x7C,0xD1,0x85,0x5A,0xDA,0xA8,0x1E,0x2A,
+	  0x07,0x50,0xB8,0x0F,0xDA,0x23,0x10,
+	  0x00,0x00,0x01,0x00,0x90,0x51,0x2D,0xA9,0xAF,0x72,	/* order */
+	  0xB0,0x83,0x49,0xD9,0x8A,0x5D,0xD4,0xC7,0xB0,0x53,
+	  0x2E,0xCA,0x51,0xCE,0x03,0xE2,0xD1,0x0F,0x3B,0x7A,
+	  0xC5,0x79,0xBD,0x87,0xE9,0x09,0xAE,0x40,0xA6,0xF1,
+	  0x31,0xE9,0xCF,0xCE,0x5B,0xD9,0x67 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+54*6]; }
+	_EC_X9_62_CHAR2_431R1 = {
+	{ NID_X9_62_characteristic_two_field,0,54,0x2760 },
+	{							/* no seed */
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x01,
+	  0x1A,0x82,0x7E,0xF0,0x0D,0xD6,0xFC,0x0E,0x23,0x4C,	/* a */
+	  0xAF,0x04,0x6C,0x6A,0x5D,0x8A,0x85,0x39,0x5B,0x23,
+	  0x6C,0xC4,0xAD,0x2C,0xF3,0x2A,0x0C,0xAD,0xBD,0xC9,
+	  0xDD,0xF6,0x20,0xB0,0xEB,0x99,0x06,0xD0,0x95,0x7F,
+	  0x6C,0x6F,0xEA,0xCD,0x61,0x54,0x68,0xDF,0x10,0x4D,
+	  0xE2,0x96,0xCD,0x8F,
+	  0x10,0xD9,0xB4,0xA3,0xD9,0x04,0x7D,0x8B,0x15,0x43,	/* b */
+	  0x59,0xAB,0xFB,0x1B,0x7F,0x54,0x85,0xB0,0x4C,0xEB,
+	  0x86,0x82,0x37,0xDD,0xC9,0xDE,0xDA,0x98,0x2A,0x67,
+	  0x9A,0x5A,0x91,0x9B,0x62,0x6D,0x4E,0x50,0xA8,0xDD,
+	  0x73,0x1B,0x10,0x7A,0x99,0x62,0x38,0x1F,0xB5,0xD8,
+	  0x07,0xBF,0x26,0x18,
+	  0x12,0x0F,0xC0,0x5D,0x3C,0x67,0xA9,0x9D,0xE1,0x61,	/* x */
+	  0xD2,0xF4,0x09,0x26,0x22,0xFE,0xCA,0x70,0x1B,0xE4,
+	  0xF5,0x0F,0x47,0x58,0x71,0x4E,0x8A,0x87,0xBB,0xF2,
+	  0xA6,0x58,0xEF,0x8C,0x21,0xE7,0xC5,0xEF,0xE9,0x65,
+	  0x36,0x1F,0x6C,0x29,0x99,0xC0,0xC2,0x47,0xB0,0xDB,
+	  0xD7,0x0C,0xE6,0xB7,
+	  0x20,0xD0,0xAF,0x89,0x03,0xA9,0x6F,0x8D,0x5F,0xA2,	/* y */
+	  0xC2,0x55,0x74,0x5D,0x3C,0x45,0x1B,0x30,0x2C,0x93,
+	  0x46,0xD9,0xB7,0xE4,0x85,0xE7,0xBC,0xE4,0x1F,0x6B,
+	  0x59,0x1F,0x3E,0x8F,0x6A,0xDD,0xCB,0xB0,0xBC,0x4C,
+	  0x2F,0x94,0x7A,0x7D,0xE1,0xA8,0x9B,0x62,0x5D,0x6A,
+	  0x59,0x8B,0x37,0x60,
+	  0x00,0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,	/* order */
+	  0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,0x03,
+	  0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x23,
+	  0xC3,0x13,0xFA,0xB5,0x05,0x89,0x70,0x3B,0x5E,0xC6,
+	  0x8D,0x35,0x87,0xFE,0xC6,0x0D,0x16,0x1C,0xC1,0x49,
+	  0xC1,0xAD,0x4A,0x91 }
+	};
+
+static const struct { EC_CURVE_DATA h; unsigned char data[0+15*6]; }
+	_EC_WTLS_1 = {
+	{ NID_X9_62_characteristic_two_field,0,15,2 },
+	{							/* no seed */
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x02,0x01,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x01,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x01,
+	  0x01,0x66,0x79,0x79,0xA4,0x0B,0xA4,0x97,0xE5,0xD5,	/* x */
+	  0xC2,0x70,0x78,0x06,0x17,
+	  0x00,0xF4,0x4B,0x4A,0xF1,0xEC,0xC2,0x63,0x0E,0x08,	/* y */
+	  0x78,0x5C,0xEB,0xCC,0x15,
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xBF,	/* order */
+	  0x91,0xAF,0x6D,0xEA,0x73 }
+	};
+
+/* IPSec curves */
+/* NOTE: The of curves over a extension field of non prime degree
+ * is not recommended (Weil-descent).
+ * As the group order is not a prime this curve is not suitable
+ * for ECDSA.
+ */
+static const struct { EC_CURVE_DATA h; unsigned char data[0+20*6]; }
+	_EC_IPSEC_155_ID3 = {
+	{ NID_X9_62_characteristic_two_field,0,20,3 },
+	{							/* no seed */
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x33,0x8f,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* x */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7b,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* y */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xc8,
+
+	  0x02,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,	/* order */
+	  0xC7,0xF3,0xC7,0x88,0x1B,0xD0,0x86,0x8F,0xA8,0x6C }
+	};
+
+/* NOTE: The of curves over a extension field of non prime degree
+ * is not recommended (Weil-descent).
+ * As the group order is not a prime this curve is not suitable
+ * for ECDSA.
+ */
+static const struct { EC_CURVE_DATA h; unsigned char data[0+24*6]; }
+	_EC_IPSEC_185_ID4 = {
+	{ NID_X9_62_characteristic_two_field,0,24,2 },
+	{							/* no seed */
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x01,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x1e,0xe9,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* x */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x18,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* y */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x0d,
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xED,0xF9,0x7C,0x44,0xDB,0x9F,0x24,0x20,
+	  0xBA,0xFC,0xA7,0x5E }
+	};
+
+typedef struct _ec_list_element_st {
+	int	nid;
+	const EC_CURVE_DATA *data;
+	const char *comment;
+	} ec_list_element;
+
+static const ec_list_element curve_list[] = {
+	/* prime field curves */	
+	/* secg curves */
+	{ NID_secp112r1, &_EC_SECG_PRIME_112R1.h, "SECG/WTLS curve over a 112 bit prime field"},
+	{ NID_secp112r2, &_EC_SECG_PRIME_112R2.h, "SECG curve over a 112 bit prime field"},
+	{ NID_secp128r1, &_EC_SECG_PRIME_128R1.h, "SECG curve over a 128 bit prime field"},
+	{ NID_secp128r2, &_EC_SECG_PRIME_128R2.h, "SECG curve over a 128 bit prime field"},
+	{ NID_secp160k1, &_EC_SECG_PRIME_160K1.h, "SECG curve over a 160 bit prime field"},
+	{ NID_secp160r1, &_EC_SECG_PRIME_160R1.h, "SECG curve over a 160 bit prime field"},
+	{ NID_secp160r2, &_EC_SECG_PRIME_160R2.h, "SECG/WTLS curve over a 160 bit prime field"},
+	/* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */
+	{ NID_secp192k1, &_EC_SECG_PRIME_192K1.h, "SECG curve over a 192 bit prime field"},
+	{ NID_secp224k1, &_EC_SECG_PRIME_224K1.h, "SECG curve over a 224 bit prime field"},
+	{ NID_secp224r1, &_EC_NIST_PRIME_224.h,   "NIST/SECG curve over a 224 bit prime field"},
+	{ NID_secp256k1, &_EC_SECG_PRIME_256K1.h, "SECG curve over a 256 bit prime field"},
+	/* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
+	{ NID_secp384r1, &_EC_NIST_PRIME_384.h, "NIST/SECG curve over a 384 bit prime field"},
+	{ NID_secp521r1, &_EC_NIST_PRIME_521.h, "NIST/SECG curve over a 521 bit prime field"},
+	/* X9.62 curves */
+	{ NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, "NIST/X9.62/SECG curve over a 192 bit prime field"},
+	{ NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, "X9.62 curve over a 192 bit prime field"},
+	{ NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, "X9.62 curve over a 192 bit prime field"},
+	{ NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, "X9.62 curve over a 239 bit prime field"},
+	{ NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, "X9.62 curve over a 239 bit prime field"},
+	{ NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, "X9.62 curve over a 239 bit prime field"},
+	{ NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, "X9.62/SECG curve over a 256 bit prime field"},
+	/* characteristic two field curves */
+	/* NIST/SECG curves */
+	{ NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, "SECG curve over a 113 bit binary field"},
+	{ NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, "SECG curve over a 113 bit binary field"},
+	{ NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, "SECG/WTLS curve over a 131 bit binary field"},
+	{ NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, "SECG curve over a 131 bit binary field"},
+	{ NID_sect163k1, &_EC_NIST_CHAR2_163K.h,  "NIST/SECG/WTLS curve over a 163 bit binary field" },
+	{ NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, "SECG curve over a 163 bit binary field"},
+	{ NID_sect163r2, &_EC_NIST_CHAR2_163B.h,  "NIST/SECG curve over a 163 bit binary field" },
+	{ NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, "SECG curve over a 193 bit binary field"},
+	{ NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, "SECG curve over a 193 bit binary field"},
+	{ NID_sect233k1, &_EC_NIST_CHAR2_233K.h,  "NIST/SECG/WTLS curve over a 233 bit binary field" },
+	{ NID_sect233r1, &_EC_NIST_CHAR2_233B.h,  "NIST/SECG/WTLS curve over a 233 bit binary field" },
+	{ NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, "SECG curve over a 239 bit binary field"},
+	{ NID_sect283k1, &_EC_NIST_CHAR2_283K.h,  "NIST/SECG curve over a 283 bit binary field" },
+	{ NID_sect283r1, &_EC_NIST_CHAR2_283B.h,  "NIST/SECG curve over a 283 bit binary field" },
+	{ NID_sect409k1, &_EC_NIST_CHAR2_409K.h,  "NIST/SECG curve over a 409 bit binary field" },
+	{ NID_sect409r1, &_EC_NIST_CHAR2_409B.h,  "NIST/SECG curve over a 409 bit binary field" },
+	{ NID_sect571k1, &_EC_NIST_CHAR2_571K.h,  "NIST/SECG curve over a 571 bit binary field" },
+	{ NID_sect571r1, &_EC_NIST_CHAR2_571B.h,  "NIST/SECG curve over a 571 bit binary field" },
+	/* X9.62 curves */
+	{ NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, "X9.62 curve over a 163 bit binary field"},
+	{ NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, "X9.62 curve over a 163 bit binary field"},
+	{ NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, "X9.62 curve over a 163 bit binary field"},
+	{ NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, "X9.62 curve over a 176 bit binary field"},
+	{ NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, "X9.62 curve over a 191 bit binary field"},
+	{ NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, "X9.62 curve over a 191 bit binary field"},
+	{ NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, "X9.62 curve over a 191 bit binary field"},
+	{ NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, "X9.62 curve over a 208 bit binary field"},
+	{ NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, "X9.62 curve over a 239 bit binary field"},
+	{ NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, "X9.62 curve over a 239 bit binary field"},
+	{ NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, "X9.62 curve over a 239 bit binary field"},
+	{ NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, "X9.62 curve over a 272 bit binary field"},
+	{ NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, "X9.62 curve over a 304 bit binary field"},
+	{ NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, "X9.62 curve over a 359 bit binary field"},
+	{ NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, "X9.62 curve over a 368 bit binary field"},
+	{ NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, "X9.62 curve over a 431 bit binary field"},
+	/* the WAP/WTLS curves
+	 * [unlike SECG, spec has its own OIDs for curves from X9.62] */
+	{ NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, "WTLS curve over a 113 bit binary field"},
+	{ NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h,   "NIST/SECG/WTLS curve over a 163 bit binary field"},
+	{ NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h,  "SECG curve over a 113 bit binary field"},
+	{ NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, "X9.62 curve over a 163 bit binary field"},
+	{ NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h,  "SECG/WTLS curve over a 112 bit prime field"},
+	{ NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h,  "SECG/WTLS curve over a 160 bit prime field"},
+	{ NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, "WTLS curve over a 112 bit prime field"},
+	{ NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, "WTLS curve over a 160 bit prime field" },
+	{ NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, "NIST/SECG/WTLS curve over a 233 bit binary field"},
+	{ NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, "NIST/SECG/WTLS curve over a 233 bit binary field"},
+	{ NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, "WTLS curvs over a 224 bit prime field"},
+	/* IPSec curves */
+	{ NID_ipsec3, &_EC_IPSEC_155_ID3.h, "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n""\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
+	{ NID_ipsec4, &_EC_IPSEC_185_ID4.h, "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n""\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
+};
+
+#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element))
+
+static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data)
+	{
+	EC_GROUP *group=NULL;
+	EC_POINT *P=NULL;
+	BN_CTX	 *ctx=NULL;
+	BIGNUM 	 *p=NULL, *a=NULL, *b=NULL, *x=NULL, *y=NULL, *order=NULL;
+	int	 ok=0;
+	int	 seed_len,param_len;
+	const unsigned char *params;
+
+	if ((ctx = BN_CTX_new()) == NULL)
+		{
+		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	seed_len  = data->seed_len;
+	param_len = data->param_len;
+	params    = (const unsigned char *)(data+1);	/* skip header */
+	params   += seed_len;				/* skip seed   */
+
+	if (!(p = BN_bin2bn(params+0*param_len, param_len, NULL))
+		|| !(a = BN_bin2bn(params+1*param_len, param_len, NULL))
+		|| !(b = BN_bin2bn(params+2*param_len, param_len, NULL)))
+		{
+		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
+		goto err;
+		}
+
+	if (data->field_type == NID_X9_62_prime_field)
+		{
+		if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL)
+			{
+			ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+			goto err;
+			}
+		}
+	else	/* field_type == NID_X9_62_characteristic_two_field */
+		{
+		if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL)
+			{
+			ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+			goto err;
+			}
+		}
+
+	if ((P = EC_POINT_new(group)) == NULL)
+		{
+		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+		goto err;
+		}
+	
+	if (!(x = BN_bin2bn(params+3*param_len, param_len, NULL))
+		|| !(y = BN_bin2bn(params+4*param_len, param_len, NULL)))
+		{
+		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
+		goto err;
+		}
+	if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx))
+		{
+		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+		goto err;
+		}
+	if (!(order = BN_bin2bn(params+5*param_len, param_len, NULL))
+		|| !BN_set_word(x, (BN_ULONG)data->cofactor))
+		{
+		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
+		goto err;
+		}
+	if (!EC_GROUP_set_generator(group, P, order, x))
+		{
+		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+		goto err;
+		}
+	if (seed_len)
+		{
+		if (!EC_GROUP_set_seed(group, params-seed_len, seed_len))
+			{
+			ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+			goto err;
+			}
+		}
+	ok=1;
+err:
+	if (!ok)
+		{
+		EC_GROUP_free(group);
+		group = NULL;
+		}
+	if (P)
+		EC_POINT_free(P);
+	if (ctx)
+		BN_CTX_free(ctx);
+	if (p)
+		BN_free(p);
+	if (a)
+		BN_free(a);
+	if (b)
+		BN_free(b);
+	if (order)
+		BN_free(order);
+	if (x)
+		BN_free(x);
+	if (y)
+		BN_free(y);
+	return group;
+	}
+
+EC_GROUP *EC_GROUP_new_by_curve_name(int nid)
+	{
+	size_t i;
+	EC_GROUP *ret = NULL;
+
+	if (nid <= 0)
+		return NULL;
+
+	for (i=0; i<curve_list_length; i++)
+		if (curve_list[i].nid == nid)
+			{
+			ret = ec_group_new_from_data(curve_list[i].data);
+			break;
+			}
+
+	if (ret == NULL)
+		{
+		ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP);
+		return NULL;
+		}
+
+	EC_GROUP_set_curve_name(ret, nid);
+
+	return ret;
+	}
+
+size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems)
+	{
+	size_t	i, min;
+
+	if (r == NULL || nitems == 0)
+		return curve_list_length;
+
+	min = nitems < curve_list_length ? nitems : curve_list_length;
+
+	for (i = 0; i < min; i++)
+		{
+		r[i].nid = curve_list[i].nid;
+		r[i].comment = curve_list[i].comment;
+		}
+
+	return curve_list_length;
+	}
diff --git a/openssl/crypto/ec/ec_cvt.c b/openssl/crypto/ec/ec_cvt.c
new file mode 100644
index 0000000..d45640b
--- /dev/null
+++ b/openssl/crypto/ec/ec_cvt.c
@@ -0,0 +1,144 @@
+/* crypto/ec/ec_cvt.c */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#include <openssl/err.h>
+#include "ec_lcl.h"
+
+
+EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+	{
+	const EC_METHOD *meth;
+	EC_GROUP *ret;
+
+	meth = EC_GFp_nist_method();
+	
+	ret = EC_GROUP_new(meth);
+	if (ret == NULL)
+		return NULL;
+
+	if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
+		{
+		unsigned long err;
+		  
+		err = ERR_peek_last_error();
+
+		if (!(ERR_GET_LIB(err) == ERR_LIB_EC &&
+			((ERR_GET_REASON(err) == EC_R_NOT_A_NIST_PRIME) ||
+			 (ERR_GET_REASON(err) == EC_R_NOT_A_SUPPORTED_NIST_PRIME))))
+			{
+			/* real error */
+			
+			EC_GROUP_clear_free(ret);
+			return NULL;
+			}
+			
+		
+		/* not an actual error, we just cannot use EC_GFp_nist_method */
+
+		ERR_clear_error();
+
+		EC_GROUP_clear_free(ret);
+		meth = EC_GFp_mont_method();
+
+		ret = EC_GROUP_new(meth);
+		if (ret == NULL)
+			return NULL;
+
+		if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
+			{
+			EC_GROUP_clear_free(ret);
+			return NULL;
+			}
+		}
+
+	return ret;
+	}
+
+
+EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+	{
+	const EC_METHOD *meth;
+	EC_GROUP *ret;
+	
+	meth = EC_GF2m_simple_method();
+	
+	ret = EC_GROUP_new(meth);
+	if (ret == NULL)
+		return NULL;
+
+	if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx))
+		{
+		EC_GROUP_clear_free(ret);
+		return NULL;
+		}
+
+	return ret;
+	}
diff --git a/openssl/crypto/ec/ec_err.c b/openssl/crypto/ec/ec_err.c
new file mode 100644
index 0000000..84b4833
--- /dev/null
+++ b/openssl/crypto/ec/ec_err.c
@@ -0,0 +1,258 @@
+/* crypto/ec/ec_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ec.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_EC,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason)
+
+static ERR_STRING_DATA EC_str_functs[]=
+	{
+{ERR_FUNC(EC_F_COMPUTE_WNAF),	"COMPUTE_WNAF"},
+{ERR_FUNC(EC_F_D2I_ECPARAMETERS),	"d2i_ECParameters"},
+{ERR_FUNC(EC_F_D2I_ECPKPARAMETERS),	"d2i_ECPKParameters"},
+{ERR_FUNC(EC_F_D2I_ECPRIVATEKEY),	"d2i_ECPrivateKey"},
+{ERR_FUNC(EC_F_DO_EC_KEY_PRINT),	"DO_EC_KEY_PRINT"},
+{ERR_FUNC(EC_F_ECKEY_PARAM2TYPE),	"ECKEY_PARAM2TYPE"},
+{ERR_FUNC(EC_F_ECKEY_PARAM_DECODE),	"ECKEY_PARAM_DECODE"},
+{ERR_FUNC(EC_F_ECKEY_PRIV_DECODE),	"ECKEY_PRIV_DECODE"},
+{ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE),	"ECKEY_PRIV_ENCODE"},
+{ERR_FUNC(EC_F_ECKEY_PUB_DECODE),	"ECKEY_PUB_DECODE"},
+{ERR_FUNC(EC_F_ECKEY_PUB_ENCODE),	"ECKEY_PUB_ENCODE"},
+{ERR_FUNC(EC_F_ECKEY_TYPE2PARAM),	"ECKEY_TYPE2PARAM"},
+{ERR_FUNC(EC_F_ECPARAMETERS_PRINT),	"ECParameters_print"},
+{ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP),	"ECParameters_print_fp"},
+{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT),	"ECPKParameters_print"},
+{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP),	"ECPKParameters_print_fp"},
+{ERR_FUNC(EC_F_ECP_NIST_MOD_192),	"ECP_NIST_MOD_192"},
+{ERR_FUNC(EC_F_ECP_NIST_MOD_224),	"ECP_NIST_MOD_224"},
+{ERR_FUNC(EC_F_ECP_NIST_MOD_256),	"ECP_NIST_MOD_256"},
+{ERR_FUNC(EC_F_ECP_NIST_MOD_521),	"ECP_NIST_MOD_521"},
+{ERR_FUNC(EC_F_EC_ASN1_GROUP2CURVE),	"EC_ASN1_GROUP2CURVE"},
+{ERR_FUNC(EC_F_EC_ASN1_GROUP2FIELDID),	"EC_ASN1_GROUP2FIELDID"},
+{ERR_FUNC(EC_F_EC_ASN1_GROUP2PARAMETERS),	"EC_ASN1_GROUP2PARAMETERS"},
+{ERR_FUNC(EC_F_EC_ASN1_GROUP2PKPARAMETERS),	"EC_ASN1_GROUP2PKPARAMETERS"},
+{ERR_FUNC(EC_F_EC_ASN1_PARAMETERS2GROUP),	"EC_ASN1_PARAMETERS2GROUP"},
+{ERR_FUNC(EC_F_EC_ASN1_PKPARAMETERS2GROUP),	"EC_ASN1_PKPARAMETERS2GROUP"},
+{ERR_FUNC(EC_F_EC_EX_DATA_SET_DATA),	"EC_EX_DATA_set_data"},
+{ERR_FUNC(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY),	"EC_GF2M_MONTGOMERY_POINT_MULTIPLY"},
+{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT),	"ec_GF2m_simple_group_check_discriminant"},
+{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE),	"ec_GF2m_simple_group_set_curve"},
+{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_OCT2POINT),	"ec_GF2m_simple_oct2point"},
+{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT2OCT),	"ec_GF2m_simple_point2oct"},
+{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES),	"ec_GF2m_simple_point_get_affine_coordinates"},
+{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES),	"ec_GF2m_simple_point_set_affine_coordinates"},
+{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES),	"ec_GF2m_simple_set_compressed_coordinates"},
+{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE),	"ec_GFp_mont_field_decode"},
+{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE),	"ec_GFp_mont_field_encode"},
+{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL),	"ec_GFp_mont_field_mul"},
+{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE),	"ec_GFp_mont_field_set_to_one"},
+{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR),	"ec_GFp_mont_field_sqr"},
+{ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE),	"ec_GFp_mont_group_set_curve"},
+{ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP),	"EC_GFP_MONT_GROUP_SET_CURVE_GFP"},
+{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL),	"ec_GFp_nist_field_mul"},
+{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR),	"ec_GFp_nist_field_sqr"},
+{ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE),	"ec_GFp_nist_group_set_curve"},
+{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT),	"ec_GFp_simple_group_check_discriminant"},
+{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE),	"ec_GFp_simple_group_set_curve"},
+{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP),	"EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP"},
+{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR),	"EC_GFP_SIMPLE_GROUP_SET_GENERATOR"},
+{ERR_FUNC(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE),	"ec_GFp_simple_make_affine"},
+{ERR_FUNC(EC_F_EC_GFP_SIMPLE_OCT2POINT),	"ec_GFp_simple_oct2point"},
+{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT2OCT),	"ec_GFp_simple_point2oct"},
+{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE),	"ec_GFp_simple_points_make_affine"},
+{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES),	"ec_GFp_simple_point_get_affine_coordinates"},
+{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP),	"EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP"},
+{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES),	"ec_GFp_simple_point_set_affine_coordinates"},
+{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP),	"EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP"},
+{ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES),	"ec_GFp_simple_set_compressed_coordinates"},
+{ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP),	"EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP"},
+{ERR_FUNC(EC_F_EC_GROUP_CHECK),	"EC_GROUP_check"},
+{ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT),	"EC_GROUP_check_discriminant"},
+{ERR_FUNC(EC_F_EC_GROUP_COPY),	"EC_GROUP_copy"},
+{ERR_FUNC(EC_F_EC_GROUP_GET0_GENERATOR),	"EC_GROUP_get0_generator"},
+{ERR_FUNC(EC_F_EC_GROUP_GET_COFACTOR),	"EC_GROUP_get_cofactor"},
+{ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GF2M),	"EC_GROUP_get_curve_GF2m"},
+{ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP),	"EC_GROUP_get_curve_GFp"},
+{ERR_FUNC(EC_F_EC_GROUP_GET_DEGREE),	"EC_GROUP_get_degree"},
+{ERR_FUNC(EC_F_EC_GROUP_GET_ORDER),	"EC_GROUP_get_order"},
+{ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS),	"EC_GROUP_get_pentanomial_basis"},
+{ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS),	"EC_GROUP_get_trinomial_basis"},
+{ERR_FUNC(EC_F_EC_GROUP_NEW),	"EC_GROUP_new"},
+{ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME),	"EC_GROUP_new_by_curve_name"},
+{ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA),	"EC_GROUP_NEW_FROM_DATA"},
+{ERR_FUNC(EC_F_EC_GROUP_PRECOMPUTE_MULT),	"EC_GROUP_precompute_mult"},
+{ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M),	"EC_GROUP_set_curve_GF2m"},
+{ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP),	"EC_GROUP_set_curve_GFp"},
+{ERR_FUNC(EC_F_EC_GROUP_SET_EXTRA_DATA),	"EC_GROUP_SET_EXTRA_DATA"},
+{ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR),	"EC_GROUP_set_generator"},
+{ERR_FUNC(EC_F_EC_KEY_CHECK_KEY),	"EC_KEY_check_key"},
+{ERR_FUNC(EC_F_EC_KEY_COPY),	"EC_KEY_copy"},
+{ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY),	"EC_KEY_generate_key"},
+{ERR_FUNC(EC_F_EC_KEY_NEW),	"EC_KEY_new"},
+{ERR_FUNC(EC_F_EC_KEY_PRINT),	"EC_KEY_print"},
+{ERR_FUNC(EC_F_EC_KEY_PRINT_FP),	"EC_KEY_print_fp"},
+{ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE),	"EC_POINTs_make_affine"},
+{ERR_FUNC(EC_F_EC_POINT_ADD),	"EC_POINT_add"},
+{ERR_FUNC(EC_F_EC_POINT_CMP),	"EC_POINT_cmp"},
+{ERR_FUNC(EC_F_EC_POINT_COPY),	"EC_POINT_copy"},
+{ERR_FUNC(EC_F_EC_POINT_DBL),	"EC_POINT_dbl"},
+{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M),	"EC_POINT_get_affine_coordinates_GF2m"},
+{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP),	"EC_POINT_get_affine_coordinates_GFp"},
+{ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP),	"EC_POINT_get_Jprojective_coordinates_GFp"},
+{ERR_FUNC(EC_F_EC_POINT_INVERT),	"EC_POINT_invert"},
+{ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY),	"EC_POINT_is_at_infinity"},
+{ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE),	"EC_POINT_is_on_curve"},
+{ERR_FUNC(EC_F_EC_POINT_MAKE_AFFINE),	"EC_POINT_make_affine"},
+{ERR_FUNC(EC_F_EC_POINT_MUL),	"EC_POINT_mul"},
+{ERR_FUNC(EC_F_EC_POINT_NEW),	"EC_POINT_new"},
+{ERR_FUNC(EC_F_EC_POINT_OCT2POINT),	"EC_POINT_oct2point"},
+{ERR_FUNC(EC_F_EC_POINT_POINT2OCT),	"EC_POINT_point2oct"},
+{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M),	"EC_POINT_set_affine_coordinates_GF2m"},
+{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP),	"EC_POINT_set_affine_coordinates_GFp"},
+{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M),	"EC_POINT_set_compressed_coordinates_GF2m"},
+{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP),	"EC_POINT_set_compressed_coordinates_GFp"},
+{ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP),	"EC_POINT_set_Jprojective_coordinates_GFp"},
+{ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY),	"EC_POINT_set_to_infinity"},
+{ERR_FUNC(EC_F_EC_PRE_COMP_DUP),	"EC_PRE_COMP_DUP"},
+{ERR_FUNC(EC_F_EC_PRE_COMP_NEW),	"EC_PRE_COMP_NEW"},
+{ERR_FUNC(EC_F_EC_WNAF_MUL),	"ec_wNAF_mul"},
+{ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT),	"ec_wNAF_precompute_mult"},
+{ERR_FUNC(EC_F_I2D_ECPARAMETERS),	"i2d_ECParameters"},
+{ERR_FUNC(EC_F_I2D_ECPKPARAMETERS),	"i2d_ECPKParameters"},
+{ERR_FUNC(EC_F_I2D_ECPRIVATEKEY),	"i2d_ECPrivateKey"},
+{ERR_FUNC(EC_F_I2O_ECPUBLICKEY),	"i2o_ECPublicKey"},
+{ERR_FUNC(EC_F_O2I_ECPUBLICKEY),	"o2i_ECPublicKey"},
+{ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE),	"OLD_EC_PRIV_DECODE"},
+{ERR_FUNC(EC_F_PKEY_EC_CTRL),	"PKEY_EC_CTRL"},
+{ERR_FUNC(EC_F_PKEY_EC_CTRL_STR),	"PKEY_EC_CTRL_STR"},
+{ERR_FUNC(EC_F_PKEY_EC_DERIVE),	"PKEY_EC_DERIVE"},
+{ERR_FUNC(EC_F_PKEY_EC_KEYGEN),	"PKEY_EC_KEYGEN"},
+{ERR_FUNC(EC_F_PKEY_EC_PARAMGEN),	"PKEY_EC_PARAMGEN"},
+{ERR_FUNC(EC_F_PKEY_EC_SIGN),	"PKEY_EC_SIGN"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA EC_str_reasons[]=
+	{
+{ERR_REASON(EC_R_ASN1_ERROR)             ,"asn1 error"},
+{ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD)     ,"asn1 unknown field"},
+{ERR_REASON(EC_R_BUFFER_TOO_SMALL)       ,"buffer too small"},
+{ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),"d2i ecpkparameters failure"},
+{ERR_REASON(EC_R_DECODE_ERROR)           ,"decode error"},
+{ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO)   ,"discriminant is zero"},
+{ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),"ec group new by name failure"},
+{ERR_REASON(EC_R_FIELD_TOO_LARGE)        ,"field too large"},
+{ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE),"group2pkparameters failure"},
+{ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE),"i2d ecpkparameters failure"},
+{ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS)   ,"incompatible objects"},
+{ERR_REASON(EC_R_INVALID_ARGUMENT)       ,"invalid argument"},
+{ERR_REASON(EC_R_INVALID_COMPRESSED_POINT),"invalid compressed point"},
+{ERR_REASON(EC_R_INVALID_COMPRESSION_BIT),"invalid compression bit"},
+{ERR_REASON(EC_R_INVALID_CURVE)          ,"invalid curve"},
+{ERR_REASON(EC_R_INVALID_DIGEST_TYPE)    ,"invalid digest type"},
+{ERR_REASON(EC_R_INVALID_ENCODING)       ,"invalid encoding"},
+{ERR_REASON(EC_R_INVALID_FIELD)          ,"invalid field"},
+{ERR_REASON(EC_R_INVALID_FORM)           ,"invalid form"},
+{ERR_REASON(EC_R_INVALID_GROUP_ORDER)    ,"invalid group order"},
+{ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS),"invalid pentanomial basis"},
+{ERR_REASON(EC_R_INVALID_PRIVATE_KEY)    ,"invalid private key"},
+{ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS),"invalid trinomial basis"},
+{ERR_REASON(EC_R_KEYS_NOT_SET)           ,"keys not set"},
+{ERR_REASON(EC_R_MISSING_PARAMETERS)     ,"missing parameters"},
+{ERR_REASON(EC_R_MISSING_PRIVATE_KEY)    ,"missing private key"},
+{ERR_REASON(EC_R_NOT_A_NIST_PRIME)       ,"not a NIST prime"},
+{ERR_REASON(EC_R_NOT_A_SUPPORTED_NIST_PRIME),"not a supported NIST prime"},
+{ERR_REASON(EC_R_NOT_IMPLEMENTED)        ,"not implemented"},
+{ERR_REASON(EC_R_NOT_INITIALIZED)        ,"not initialized"},
+{ERR_REASON(EC_R_NO_FIELD_MOD)           ,"no field mod"},
+{ERR_REASON(EC_R_NO_PARAMETERS_SET)      ,"no parameters set"},
+{ERR_REASON(EC_R_PASSED_NULL_PARAMETER)  ,"passed null parameter"},
+{ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE),"pkparameters2group failure"},
+{ERR_REASON(EC_R_POINT_AT_INFINITY)      ,"point at infinity"},
+{ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE)  ,"point is not on curve"},
+{ERR_REASON(EC_R_SLOT_FULL)              ,"slot full"},
+{ERR_REASON(EC_R_UNDEFINED_GENERATOR)    ,"undefined generator"},
+{ERR_REASON(EC_R_UNDEFINED_ORDER)        ,"undefined order"},
+{ERR_REASON(EC_R_UNKNOWN_GROUP)          ,"unknown group"},
+{ERR_REASON(EC_R_UNKNOWN_ORDER)          ,"unknown order"},
+{ERR_REASON(EC_R_UNSUPPORTED_FIELD)      ,"unsupported field"},
+{ERR_REASON(EC_R_WRONG_ORDER)            ,"wrong order"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_EC_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(EC_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,EC_str_functs);
+		ERR_load_strings(0,EC_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/ec/ec_key.c b/openssl/crypto/ec/ec_key.c
new file mode 100644
index 0000000..522802c
--- /dev/null
+++ b/openssl/crypto/ec/ec_key.c
@@ -0,0 +1,463 @@
+/* crypto/ec/ec_key.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions originally developed by SUN MICROSYSTEMS, INC., and 
+ * contributed to the OpenSSL project.
+ */
+
+#include <string.h>
+#include "ec_lcl.h"
+#include <openssl/err.h>
+#include <string.h>
+
+EC_KEY *EC_KEY_new(void)
+	{
+	EC_KEY *ret;
+
+	ret=(EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY));
+	if (ret == NULL)
+		{
+		ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+
+	ret->version = 1;	
+	ret->group   = NULL;
+	ret->pub_key = NULL;
+	ret->priv_key= NULL;
+	ret->enc_flag= 0; 
+	ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
+	ret->references= 1;
+	ret->method_data = NULL;
+	return(ret);
+	}
+
+EC_KEY *EC_KEY_new_by_curve_name(int nid)
+	{
+	EC_KEY *ret = EC_KEY_new();
+	if (ret == NULL)
+		return NULL;
+	ret->group = EC_GROUP_new_by_curve_name(nid);
+	if (ret->group == NULL)
+		{
+		EC_KEY_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+void EC_KEY_free(EC_KEY *r)
+	{
+	int i;
+
+	if (r == NULL) return;
+
+	i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_EC);
+#ifdef REF_PRINT
+	REF_PRINT("EC_KEY",r);
+#endif
+	if (i > 0) return;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"EC_KEY_free, bad reference count\n");
+		abort();
+		}
+#endif
+
+	if (r->group    != NULL) 
+		EC_GROUP_free(r->group);
+	if (r->pub_key  != NULL)
+		EC_POINT_free(r->pub_key);
+	if (r->priv_key != NULL)
+		BN_clear_free(r->priv_key);
+
+	EC_EX_DATA_free_all_data(&r->method_data);
+
+	OPENSSL_cleanse((void *)r, sizeof(EC_KEY));
+
+	OPENSSL_free(r);
+	}
+
+EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
+	{
+	EC_EXTRA_DATA *d;
+
+	if (dest == NULL || src == NULL)
+		{
+		ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
+		return NULL;
+		}
+	/* copy the parameters */
+	if (src->group)
+		{
+		const EC_METHOD *meth = EC_GROUP_method_of(src->group);
+		/* clear the old group */
+		if (dest->group)
+			EC_GROUP_free(dest->group);
+		dest->group = EC_GROUP_new(meth);
+		if (dest->group == NULL)
+			return NULL;
+		if (!EC_GROUP_copy(dest->group, src->group))
+			return NULL;
+		}
+	/*  copy the public key */
+	if (src->pub_key && src->group)
+		{
+		if (dest->pub_key)
+			EC_POINT_free(dest->pub_key);
+		dest->pub_key = EC_POINT_new(src->group);
+		if (dest->pub_key == NULL)
+			return NULL;
+		if (!EC_POINT_copy(dest->pub_key, src->pub_key))
+			return NULL;
+		}
+	/* copy the private key */
+	if (src->priv_key)
+		{
+		if (dest->priv_key == NULL)
+			{
+			dest->priv_key = BN_new();
+			if (dest->priv_key == NULL)
+				return NULL;
+			}
+		if (!BN_copy(dest->priv_key, src->priv_key))
+			return NULL;
+		}
+	/* copy method/extra data */
+	EC_EX_DATA_free_all_data(&dest->method_data);
+
+	for (d = src->method_data; d != NULL; d = d->next)
+		{
+		void *t = d->dup_func(d->data);
+		
+		if (t == NULL)
+			return 0;
+		if (!EC_EX_DATA_set_data(&dest->method_data, t, d->dup_func, d->free_func, d->clear_free_func))
+			return 0;
+		}
+
+	/* copy the rest */
+	dest->enc_flag  = src->enc_flag;
+	dest->conv_form = src->conv_form;
+	dest->version   = src->version;
+
+	return dest;
+	}
+
+EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
+	{
+	EC_KEY *ret = EC_KEY_new();
+	if (ret == NULL)
+		return NULL;
+	if (EC_KEY_copy(ret, ec_key) == NULL)
+		{
+		EC_KEY_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+int EC_KEY_up_ref(EC_KEY *r)
+	{
+	int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC);
+#ifdef REF_PRINT
+	REF_PRINT("EC_KEY",r);
+#endif
+#ifdef REF_CHECK
+	if (i < 2)
+		{
+		fprintf(stderr, "EC_KEY_up, bad reference count\n");
+		abort();
+		}
+#endif
+	return ((i > 1) ? 1 : 0);
+	}
+
+int EC_KEY_generate_key(EC_KEY *eckey)
+	{	
+	int	ok = 0;
+	BN_CTX	*ctx = NULL;
+	BIGNUM	*priv_key = NULL, *order = NULL;
+	EC_POINT *pub_key = NULL;
+
+	if (!eckey || !eckey->group)
+		{
+		ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+
+	if ((order = BN_new()) == NULL) goto err;
+	if ((ctx = BN_CTX_new()) == NULL) goto err;
+
+	if (eckey->priv_key == NULL)
+		{
+		priv_key = BN_new();
+		if (priv_key == NULL)
+			goto err;
+		}
+	else
+		priv_key = eckey->priv_key;
+
+	if (!EC_GROUP_get_order(eckey->group, order, ctx))
+		goto err;
+
+	do
+		if (!BN_rand_range(priv_key, order))
+			goto err;
+	while (BN_is_zero(priv_key));
+
+	if (eckey->pub_key == NULL)
+		{
+		pub_key = EC_POINT_new(eckey->group);
+		if (pub_key == NULL)
+			goto err;
+		}
+	else
+		pub_key = eckey->pub_key;
+
+	if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
+		goto err;
+
+	eckey->priv_key = priv_key;
+	eckey->pub_key  = pub_key;
+
+	ok=1;
+
+err:	
+	if (order)
+		BN_free(order);
+	if (pub_key  != NULL && eckey->pub_key  == NULL)
+		EC_POINT_free(pub_key);
+	if (priv_key != NULL && eckey->priv_key == NULL)
+		BN_free(priv_key);
+	if (ctx != NULL)
+		BN_CTX_free(ctx);
+	return(ok);
+	}
+
+int EC_KEY_check_key(const EC_KEY *eckey)
+	{
+	int	ok   = 0;
+	BN_CTX	*ctx = NULL;
+	const BIGNUM	*order  = NULL;
+	EC_POINT *point = NULL;
+
+	if (!eckey || !eckey->group || !eckey->pub_key)
+		{
+		ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+
+	if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key))
+		{
+		ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY);
+		goto err;
+		}
+
+	if ((ctx = BN_CTX_new()) == NULL)
+		goto err;
+	if ((point = EC_POINT_new(eckey->group)) == NULL)
+		goto err;
+
+	/* testing whether the pub_key is on the elliptic curve */
+	if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx))
+		{
+		ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
+		goto err;
+		}
+	/* testing whether pub_key * order is the point at infinity */
+	order = &eckey->group->order;
+	if (BN_is_zero(order))
+		{
+		ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
+		goto err;
+		}
+	if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx))
+		{
+		ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
+		goto err;
+		}
+	if (!EC_POINT_is_at_infinity(eckey->group, point))
+		{
+		ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
+		goto err;
+		}
+	/* in case the priv_key is present : 
+	 * check if generator * priv_key == pub_key 
+	 */
+	if (eckey->priv_key)
+		{
+		if (BN_cmp(eckey->priv_key, order) >= 0)
+			{
+			ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
+			goto err;
+			}
+		if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
+			NULL, NULL, ctx))
+			{
+			ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
+			goto err;
+			}
+		if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, 
+			ctx) != 0)
+			{
+			ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
+			goto err;
+			}
+		}
+	ok = 1;
+err:
+	if (ctx   != NULL)
+		BN_CTX_free(ctx);
+	if (point != NULL)
+		EC_POINT_free(point);
+	return(ok);
+	}
+
+const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
+	{
+	return key->group;
+	}
+
+int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
+	{
+	if (key->group != NULL)
+		EC_GROUP_free(key->group);
+	key->group = EC_GROUP_dup(group);
+	return (key->group == NULL) ? 0 : 1;
+	}
+
+const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
+	{
+	return key->priv_key;
+	}
+
+int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
+	{
+	if (key->priv_key)
+		BN_clear_free(key->priv_key);
+	key->priv_key = BN_dup(priv_key);
+	return (key->priv_key == NULL) ? 0 : 1;
+	}
+
+const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
+	{
+	return key->pub_key;
+	}
+
+int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
+	{
+	if (key->pub_key != NULL)
+		EC_POINT_free(key->pub_key);
+	key->pub_key = EC_POINT_dup(pub_key, key->group);
+	return (key->pub_key == NULL) ? 0 : 1;
+	}
+
+unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
+	{
+	return key->enc_flag;
+	}
+
+void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
+	{
+	key->enc_flag = flags;
+	}
+
+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
+	{
+	return key->conv_form;
+	}
+
+void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
+	{
+	key->conv_form = cform;
+	if (key->group != NULL)
+		EC_GROUP_set_point_conversion_form(key->group, cform);
+	}
+
+void *EC_KEY_get_key_method_data(EC_KEY *key,
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
+	{
+	return EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
+	}
+
+void EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
+	{
+	EC_EXTRA_DATA *ex_data;
+	CRYPTO_w_lock(CRYPTO_LOCK_EC);
+	ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
+	if (ex_data == NULL)
+		EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
+	CRYPTO_w_unlock(CRYPTO_LOCK_EC);
+	}
+
+void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
+	{
+	if (key->group != NULL)
+		EC_GROUP_set_asn1_flag(key->group, flag);
+	}
+
+int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
+	{
+	if (key->group == NULL)
+		return 0;
+	return EC_GROUP_precompute_mult(key->group, ctx);
+	}
diff --git a/openssl/crypto/ec/ec_lcl.h b/openssl/crypto/ec/ec_lcl.h
new file mode 100644
index 0000000..3e2c34b
--- /dev/null
+++ b/openssl/crypto/ec/ec_lcl.h
@@ -0,0 +1,393 @@
+/* crypto/ec/ec_lcl.h */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by 
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+
+#include <stdlib.h>
+
+#include <openssl/obj_mac.h>
+#include <openssl/ec.h>
+#include <openssl/bn.h>
+
+#if defined(__SUNPRO_C)
+# if __SUNPRO_C >= 0x520
+# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
+# endif
+#endif
+
+/* Structure details are not part of the exported interface,
+ * so all this may change in future versions. */
+
+struct ec_method_st {
+	/* used by EC_METHOD_get_field_type: */
+	int field_type; /* a NID */
+
+	/* used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, EC_GROUP_copy: */
+	int (*group_init)(EC_GROUP *);
+	void (*group_finish)(EC_GROUP *);
+	void (*group_clear_finish)(EC_GROUP *);
+	int (*group_copy)(EC_GROUP *, const EC_GROUP *);
+
+	/* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */
+	/* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */
+	int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+	int (*group_get_curve)(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
+
+	/* used by EC_GROUP_get_degree: */
+	int (*group_get_degree)(const EC_GROUP *);
+
+	/* used by EC_GROUP_check: */
+	int (*group_check_discriminant)(const EC_GROUP *, BN_CTX *);
+
+	/* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, EC_POINT_copy: */
+	int (*point_init)(EC_POINT *);
+	void (*point_finish)(EC_POINT *);
+	void (*point_clear_finish)(EC_POINT *);
+	int (*point_copy)(EC_POINT *, const EC_POINT *);
+
+	/* used by EC_POINT_set_to_infinity,
+	 * EC_POINT_set_Jprojective_coordinates_GFp,
+	 * EC_POINT_get_Jprojective_coordinates_GFp,
+	 * EC_POINT_set_affine_coordinates_GFp,     ..._GF2m,
+	 * EC_POINT_get_affine_coordinates_GFp,     ..._GF2m,
+	 * EC_POINT_set_compressed_coordinates_GFp, ..._GF2m:
+	 */
+	int (*point_set_to_infinity)(const EC_GROUP *, EC_POINT *);
+	int (*point_set_Jprojective_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
+		const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
+	int (*point_get_Jprojective_coordinates_GFp)(const EC_GROUP *, const EC_POINT *,
+		BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
+	int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *,
+		const BIGNUM *x, const BIGNUM *y, BN_CTX *);
+	int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
+		BIGNUM *x, BIGNUM *y, BN_CTX *);
+	int (*point_set_compressed_coordinates)(const EC_GROUP *, EC_POINT *,
+		const BIGNUM *x, int y_bit, BN_CTX *);
+
+	/* used by EC_POINT_point2oct, EC_POINT_oct2point: */
+	size_t (*point2oct)(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
+	        unsigned char *buf, size_t len, BN_CTX *);
+	int (*oct2point)(const EC_GROUP *, EC_POINT *,
+	        const unsigned char *buf, size_t len, BN_CTX *);
+
+	/* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */
+	int (*add)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+	int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
+	int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *);
+
+	/* used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp: */
+	int (*is_at_infinity)(const EC_GROUP *, const EC_POINT *);
+	int (*is_on_curve)(const EC_GROUP *, const EC_POINT *, BN_CTX *);
+	int (*point_cmp)(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+
+	/* used by EC_POINT_make_affine, EC_POINTs_make_affine: */
+	int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *);
+	int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
+
+	/* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, EC_POINT_have_precompute_mult
+	 * (default implementations are used if the 'mul' pointer is 0): */
+	int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+		size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
+	int (*precompute_mult)(EC_GROUP *group, BN_CTX *);
+	int (*have_precompute_mult)(const EC_GROUP *group);
+
+
+	/* internal functions */
+
+	/* 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and 'dbl' so that
+	 * the same implementations of point operations can be used with different
+	 * optimized implementations of expensive field operations: */
+	int (*field_mul)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+	int (*field_sqr)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
+	int (*field_div)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+
+	int (*field_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. to Montgomery */
+	int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. from Montgomery */
+	int (*field_set_to_one)(const EC_GROUP *, BIGNUM *r, BN_CTX *);
+} /* EC_METHOD */;
+
+typedef struct ec_extra_data_st {
+	struct ec_extra_data_st *next;
+	void *data;
+	void *(*dup_func)(void *);
+	void (*free_func)(void *);
+	void (*clear_free_func)(void *);
+} EC_EXTRA_DATA; /* used in EC_GROUP */
+
+struct ec_group_st {
+	const EC_METHOD *meth;
+
+	EC_POINT *generator; /* optional */
+	BIGNUM order, cofactor;
+
+	int curve_name;/* optional NID for named curve */
+	int asn1_flag; /* flag to control the asn1 encoding */
+	point_conversion_form_t asn1_form;
+
+	unsigned char *seed; /* optional seed for parameters (appears in ASN1) */
+	size_t seed_len;
+
+	EC_EXTRA_DATA *extra_data; /* linked list */
+
+	/* The following members are handled by the method functions,
+	 * even if they appear generic */
+	
+	BIGNUM field; /* Field specification.
+	               * For curves over GF(p), this is the modulus;
+	               * for curves over GF(2^m), this is the 
+	               * irreducible polynomial defining the field.
+	               */
+
+	int poly[6]; /* Field specification for curves over GF(2^m).
+	              * The irreducible f(t) is then of the form:
+	              *     t^poly[0] + t^poly[1] + ... + t^poly[k]
+	              * where m = poly[0] > poly[1] > ... > poly[k] = 0.
+	              * The array is terminated with poly[k+1]=-1.
+	              * All elliptic curve irreducibles have at most 5
+	              * non-zero terms.
+	              */
+
+	BIGNUM a, b; /* Curve coefficients.
+	              * (Here the assumption is that BIGNUMs can be used
+	              * or abused for all kinds of fields, not just GF(p).)
+	              * For characteristic  > 3,  the curve is defined
+	              * by a Weierstrass equation of the form
+	              *     y^2 = x^3 + a*x + b.
+	              * For characteristic  2,  the curve is defined by
+	              * an equation of the form
+	              *     y^2 + x*y = x^3 + a*x^2 + b.
+	              */
+
+	int a_is_minus3; /* enable optimized point arithmetics for special case */
+
+	void *field_data1; /* method-specific (e.g., Montgomery structure) */
+	void *field_data2; /* method-specific */
+	int (*field_mod_func)(BIGNUM *, const BIGNUM *, const BIGNUM *,	BN_CTX *); /* method-specific */
+} /* EC_GROUP */;
+
+struct ec_key_st {
+	int version;
+
+	EC_GROUP *group;
+
+	EC_POINT *pub_key;
+	BIGNUM	 *priv_key;
+
+	unsigned int enc_flag;
+	point_conversion_form_t conv_form;
+
+	int 	references;
+
+	EC_EXTRA_DATA *method_data;
+} /* EC_KEY */;
+
+/* Basically a 'mixin' for extra data, but available for EC_GROUPs/EC_KEYs only
+ * (with visibility limited to 'package' level for now).
+ * We use the function pointers as index for retrieval; this obviates
+ * global ex_data-style index tables.
+ */
+int EC_EX_DATA_set_data(EC_EXTRA_DATA **, void *data,
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
+void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *,
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
+void EC_EX_DATA_free_data(EC_EXTRA_DATA **,
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
+void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **,
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
+void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **);
+void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **);
+
+
+
+struct ec_point_st {
+	const EC_METHOD *meth;
+
+	/* All members except 'meth' are handled by the method functions,
+	 * even if they appear generic */
+
+	BIGNUM X;
+	BIGNUM Y;
+	BIGNUM Z; /* Jacobian projective coordinates:
+	           * (X, Y, Z)  represents  (X/Z^2, Y/Z^3)  if  Z != 0 */
+	int Z_is_one; /* enable optimized point arithmetics for special case */
+} /* EC_POINT */;
+
+
+
+/* method functions in ec_mult.c
+ * (ec_lib.c uses these as defaults if group->method->mul is 0) */
+int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
+int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
+int ec_wNAF_have_precompute_mult(const EC_GROUP *group);
+
+
+/* method functions in ecp_smpl.c */
+int ec_GFp_simple_group_init(EC_GROUP *);
+void ec_GFp_simple_group_finish(EC_GROUP *);
+void ec_GFp_simple_group_clear_finish(EC_GROUP *);
+int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
+int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
+int ec_GFp_simple_group_get_degree(const EC_GROUP *);
+int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
+int ec_GFp_simple_point_init(EC_POINT *);
+void ec_GFp_simple_point_finish(EC_POINT *);
+void ec_GFp_simple_point_clear_finish(EC_POINT *);
+int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *);
+int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
+int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
+int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
+	BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
+int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *);
+int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *,
+	BIGNUM *x, BIGNUM *y, BN_CTX *);
+int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, int y_bit, BN_CTX *);
+size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
+	unsigned char *buf, size_t len, BN_CTX *);
+int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *,
+	const unsigned char *buf, size_t len, BN_CTX *);
+int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
+int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
+int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
+int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
+int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
+
+
+/* method functions in ecp_mont.c */
+int ec_GFp_mont_group_init(EC_GROUP *);
+int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+void ec_GFp_mont_group_finish(EC_GROUP *);
+void ec_GFp_mont_group_clear_finish(EC_GROUP *);
+int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
+int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
+int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
+int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
+int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *);
+
+
+/* method functions in ecp_nist.c */
+int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src);
+int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
+
+
+/* method functions in ec2_smpl.c */
+int ec_GF2m_simple_group_init(EC_GROUP *);
+void ec_GF2m_simple_group_finish(EC_GROUP *);
+void ec_GF2m_simple_group_clear_finish(EC_GROUP *);
+int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *);
+int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
+int ec_GF2m_simple_group_get_degree(const EC_GROUP *);
+int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
+int ec_GF2m_simple_point_init(EC_POINT *);
+void ec_GF2m_simple_point_finish(EC_POINT *);
+void ec_GF2m_simple_point_clear_finish(EC_POINT *);
+int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *);
+int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
+int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *);
+int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *,
+	BIGNUM *x, BIGNUM *y, BN_CTX *);
+int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, int y_bit, BN_CTX *);
+size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
+	unsigned char *buf, size_t len, BN_CTX *);
+int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *,
+	const unsigned char *buf, size_t len, BN_CTX *);
+int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
+int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
+int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
+int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
+int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
+int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+
+
+/* method functions in ec2_mult.c */
+int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
+int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
diff --git a/openssl/crypto/ec/ec_lib.c b/openssl/crypto/ec/ec_lib.c
new file mode 100644
index 0000000..dd7da0f
--- /dev/null
+++ b/openssl/crypto/ec/ec_lib.c
@@ -0,0 +1,1164 @@
+/* crypto/ec/ec_lib.c */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Binary polynomial ECC support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include <string.h>
+
+#include <openssl/err.h>
+#include <openssl/opensslv.h>
+
+#include "ec_lcl.h"
+
+static const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT;
+
+
+/* functions for EC_GROUP objects */
+
+EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
+	{
+	EC_GROUP *ret;
+
+	if (meth == NULL)
+		{
+		ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL);
+		return NULL;
+		}
+	if (meth->group_init == 0)
+		{
+		ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return NULL;
+		}
+
+	ret = OPENSSL_malloc(sizeof *ret);
+	if (ret == NULL)
+		{
+		ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+
+	ret->meth = meth;
+
+	ret->extra_data = NULL;
+
+	ret->generator = NULL;
+	BN_init(&ret->order);
+	BN_init(&ret->cofactor);
+
+	ret->curve_name = 0;	
+	ret->asn1_flag  = 0;
+	ret->asn1_form  = POINT_CONVERSION_UNCOMPRESSED;
+
+	ret->seed = NULL;
+	ret->seed_len = 0;
+
+	if (!meth->group_init(ret))
+		{
+		OPENSSL_free(ret);
+		return NULL;
+		}
+	
+	return ret;
+	}
+
+
+void EC_GROUP_free(EC_GROUP *group)
+	{
+	if (!group) return;
+
+	if (group->meth->group_finish != 0)
+		group->meth->group_finish(group);
+
+	EC_EX_DATA_free_all_data(&group->extra_data);
+
+	if (group->generator != NULL)
+		EC_POINT_free(group->generator);
+	BN_free(&group->order);
+	BN_free(&group->cofactor);
+
+	if (group->seed)
+		OPENSSL_free(group->seed);
+
+	OPENSSL_free(group);
+	}
+ 
+
+void EC_GROUP_clear_free(EC_GROUP *group)
+	{
+	if (!group) return;
+
+	if (group->meth->group_clear_finish != 0)
+		group->meth->group_clear_finish(group);
+	else if (group->meth->group_finish != 0)
+		group->meth->group_finish(group);
+
+	EC_EX_DATA_clear_free_all_data(&group->extra_data);
+
+	if (group->generator != NULL)
+		EC_POINT_clear_free(group->generator);
+	BN_clear_free(&group->order);
+	BN_clear_free(&group->cofactor);
+
+	if (group->seed)
+		{
+		OPENSSL_cleanse(group->seed, group->seed_len);
+		OPENSSL_free(group->seed);
+		}
+
+	OPENSSL_cleanse(group, sizeof *group);
+	OPENSSL_free(group);
+	}
+
+
+int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
+	{
+	EC_EXTRA_DATA *d;
+
+	if (dest->meth->group_copy == 0)
+		{
+		ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (dest->meth != src->meth)
+		{
+		ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	if (dest == src)
+		return 1;
+	
+	EC_EX_DATA_free_all_data(&dest->extra_data);
+
+	for (d = src->extra_data; d != NULL; d = d->next)
+		{
+		void *t = d->dup_func(d->data);
+		
+		if (t == NULL)
+			return 0;
+		if (!EC_EX_DATA_set_data(&dest->extra_data, t, d->dup_func, d->free_func, d->clear_free_func))
+			return 0;
+		}
+
+	if (src->generator != NULL)
+		{
+		if (dest->generator == NULL)
+			{
+			dest->generator = EC_POINT_new(dest);
+			if (dest->generator == NULL) return 0;
+			}
+		if (!EC_POINT_copy(dest->generator, src->generator)) return 0;
+		}
+	else
+		{
+		/* src->generator == NULL */
+		if (dest->generator != NULL)
+			{
+			EC_POINT_clear_free(dest->generator);
+			dest->generator = NULL;
+			}
+		}
+
+	if (!BN_copy(&dest->order, &src->order)) return 0;
+	if (!BN_copy(&dest->cofactor, &src->cofactor)) return 0;
+
+	dest->curve_name = src->curve_name;
+	dest->asn1_flag  = src->asn1_flag;
+	dest->asn1_form  = src->asn1_form;
+
+	if (src->seed)
+		{
+		if (dest->seed)
+			OPENSSL_free(dest->seed);
+		dest->seed = OPENSSL_malloc(src->seed_len);
+		if (dest->seed == NULL)
+			return 0;
+		if (!memcpy(dest->seed, src->seed, src->seed_len))
+			return 0;
+		dest->seed_len = src->seed_len;
+		}
+	else
+		{
+		if (dest->seed)
+			OPENSSL_free(dest->seed);
+		dest->seed = NULL;
+		dest->seed_len = 0;
+		}
+	
+
+	return dest->meth->group_copy(dest, src);
+	}
+
+
+EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
+	{
+	EC_GROUP *t = NULL;
+	int ok = 0;
+
+	if (a == NULL) return NULL;
+
+	if ((t = EC_GROUP_new(a->meth)) == NULL) return(NULL);
+	if (!EC_GROUP_copy(t, a)) goto err;
+
+	ok = 1;
+
+  err:	
+	if (!ok)
+		{
+		if (t) EC_GROUP_free(t);
+		return NULL;
+		}
+	else return t;
+	}
+
+
+const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
+	{
+	return group->meth;
+	}
+
+
+int EC_METHOD_get_field_type(const EC_METHOD *meth)
+        {
+        return meth->field_type;
+        }
+
+
+int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor)
+	{
+	if (generator == NULL)
+		{
+		ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
+		return 0   ;
+		}
+
+	if (group->generator == NULL)
+		{
+		group->generator = EC_POINT_new(group);
+		if (group->generator == NULL) return 0;
+		}
+	if (!EC_POINT_copy(group->generator, generator)) return 0;
+
+	if (order != NULL)
+		{ if (!BN_copy(&group->order, order)) return 0; }	
+	else
+		BN_zero(&group->order);
+
+	if (cofactor != NULL)
+		{ if (!BN_copy(&group->cofactor, cofactor)) return 0; }	
+	else
+		BN_zero(&group->cofactor);
+
+	return 1;
+	}
+
+
+const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
+	{
+	return group->generator;
+	}
+
+
+int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
+	{
+	if (!BN_copy(order, &group->order))
+		return 0;
+
+	return !BN_is_zero(order);
+	}
+
+
+int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
+	{
+	if (!BN_copy(cofactor, &group->cofactor))
+		return 0;
+
+	return !BN_is_zero(&group->cofactor);
+	}
+
+
+void EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
+	{
+	group->curve_name = nid;
+	}
+
+
+int EC_GROUP_get_curve_name(const EC_GROUP *group)
+	{
+	return group->curve_name;
+	}
+
+
+void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
+	{
+	group->asn1_flag = flag;
+	}
+
+
+int EC_GROUP_get_asn1_flag(const EC_GROUP *group)
+	{
+	return group->asn1_flag;
+	}
+
+
+void EC_GROUP_set_point_conversion_form(EC_GROUP *group, 
+                                        point_conversion_form_t form)
+	{
+	group->asn1_form = form;
+	}
+
+
+point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *group)
+	{
+	return group->asn1_form;
+	}
+
+
+size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
+	{
+	if (group->seed)
+		{
+		OPENSSL_free(group->seed);
+		group->seed = NULL;
+		group->seed_len = 0;
+		}
+
+	if (!len || !p)
+		return 1;
+
+	if ((group->seed = OPENSSL_malloc(len)) == NULL)
+		return 0;
+	memcpy(group->seed, p, len);
+	group->seed_len = len;
+
+	return len;
+	}
+
+
+unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group)
+	{
+	return group->seed;
+	}
+
+
+size_t EC_GROUP_get_seed_len(const EC_GROUP *group)
+	{
+	return group->seed_len;
+	}
+
+
+int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+	{
+	if (group->meth->group_set_curve == 0)
+		{
+		ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	return group->meth->group_set_curve(group, p, a, b, ctx);
+	}
+
+
+int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+	{
+	if (group->meth->group_get_curve == 0)
+		{
+		ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	return group->meth->group_get_curve(group, p, a, b, ctx);
+	}
+
+
+int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+	{
+	if (group->meth->group_set_curve == 0)
+		{
+		ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	return group->meth->group_set_curve(group, p, a, b, ctx);
+	}
+
+
+int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+	{
+	if (group->meth->group_get_curve == 0)
+		{
+		ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	return group->meth->group_get_curve(group, p, a, b, ctx);
+	}
+
+
+int EC_GROUP_get_degree(const EC_GROUP *group)
+	{
+	if (group->meth->group_get_degree == 0)
+		{
+		ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	return group->meth->group_get_degree(group);
+	}
+
+
+int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
+	{
+	if (group->meth->group_check_discriminant == 0)
+		{
+		ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	return group->meth->group_check_discriminant(group, ctx);
+	}
+
+
+int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
+	{
+	int    r = 0;
+	BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
+	BN_CTX *ctx_new = NULL;
+
+	/* compare the field types*/
+	if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
+	    EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
+		return 1;
+	/* compare the curve name (if present) */
+	if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
+	    EC_GROUP_get_curve_name(a) == EC_GROUP_get_curve_name(b))
+		return 0;
+
+	if (!ctx)
+		ctx_new = ctx = BN_CTX_new();
+	if (!ctx)
+		return -1;
+	
+	BN_CTX_start(ctx);
+	a1 = BN_CTX_get(ctx);
+	a2 = BN_CTX_get(ctx);
+	a3 = BN_CTX_get(ctx);
+	b1 = BN_CTX_get(ctx);
+	b2 = BN_CTX_get(ctx);
+	b3 = BN_CTX_get(ctx);
+	if (!b3)
+		{
+		BN_CTX_end(ctx);
+		if (ctx_new)
+			BN_CTX_free(ctx);
+		return -1;
+		}
+
+	/* XXX This approach assumes that the external representation
+	 * of curves over the same field type is the same.
+	 */
+	if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
+	    !b->meth->group_get_curve(b, b1, b2, b3, ctx))
+		r = 1;
+
+	if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
+		r = 1;
+
+	/* XXX EC_POINT_cmp() assumes that the methods are equal */
+	if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
+	    EC_GROUP_get0_generator(b), ctx))
+		r = 1;
+
+	if (!r)
+		{
+		/* compare the order and cofactor */
+		if (!EC_GROUP_get_order(a, a1, ctx) ||
+		    !EC_GROUP_get_order(b, b1, ctx) ||
+		    !EC_GROUP_get_cofactor(a, a2, ctx) ||
+		    !EC_GROUP_get_cofactor(b, b2, ctx))
+			{
+			BN_CTX_end(ctx);
+			if (ctx_new)
+				BN_CTX_free(ctx);
+			return -1;
+			}
+		if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
+			r = 1;
+		}
+
+	BN_CTX_end(ctx);
+	if (ctx_new)
+		BN_CTX_free(ctx);
+
+	return r;
+	}
+
+
+/* this has 'package' visibility */
+int EC_EX_DATA_set_data(EC_EXTRA_DATA **ex_data, void *data,
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
+	{
+	EC_EXTRA_DATA *d;
+
+	if (ex_data == NULL)
+		return 0;
+
+	for (d = *ex_data; d != NULL; d = d->next)
+		{
+		if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func)
+			{
+			ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL);
+			return 0;
+			}
+		}
+
+	if (data == NULL)
+		/* no explicit entry needed */
+		return 1;
+
+	d = OPENSSL_malloc(sizeof *d);
+	if (d == NULL)
+		return 0;
+
+	d->data = data;
+	d->dup_func = dup_func;
+	d->free_func = free_func;
+	d->clear_free_func = clear_free_func;
+
+	d->next = *ex_data;
+	*ex_data = d;
+
+	return 1;
+	}
+
+/* this has 'package' visibility */
+void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data,
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
+	{
+	const EC_EXTRA_DATA *d;
+
+	for (d = ex_data; d != NULL; d = d->next)
+		{
+		if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func)
+			return d->data;
+		}
+	
+	return NULL;
+	}
+
+/* this has 'package' visibility */
+void EC_EX_DATA_free_data(EC_EXTRA_DATA **ex_data,
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
+	{
+	EC_EXTRA_DATA **p;
+
+	if (ex_data == NULL)
+		return;
+
+	for (p = ex_data; *p != NULL; p = &((*p)->next))
+		{
+		if ((*p)->dup_func == dup_func && (*p)->free_func == free_func && (*p)->clear_free_func == clear_free_func)
+			{
+			EC_EXTRA_DATA *next = (*p)->next;
+
+			(*p)->free_func((*p)->data);
+			OPENSSL_free(*p);
+			
+			*p = next;
+			return;
+			}
+		}
+	}
+
+/* this has 'package' visibility */
+void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **ex_data,
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
+	{
+	EC_EXTRA_DATA **p;
+
+	if (ex_data == NULL)
+		return;
+
+	for (p = ex_data; *p != NULL; p = &((*p)->next))
+		{
+		if ((*p)->dup_func == dup_func && (*p)->free_func == free_func && (*p)->clear_free_func == clear_free_func)
+			{
+			EC_EXTRA_DATA *next = (*p)->next;
+
+			(*p)->clear_free_func((*p)->data);
+			OPENSSL_free(*p);
+			
+			*p = next;
+			return;
+			}
+		}
+	}
+
+/* this has 'package' visibility */
+void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **ex_data)
+	{
+	EC_EXTRA_DATA *d;
+
+	if (ex_data == NULL)
+		return;
+
+	d = *ex_data;
+	while (d)
+		{
+		EC_EXTRA_DATA *next = d->next;
+		
+		d->free_func(d->data);
+		OPENSSL_free(d);
+		
+		d = next;
+		}
+	*ex_data = NULL;
+	}
+
+/* this has 'package' visibility */
+void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **ex_data)
+	{
+	EC_EXTRA_DATA *d;
+
+	if (ex_data == NULL)
+		return;
+
+	d = *ex_data;
+	while (d)
+		{
+		EC_EXTRA_DATA *next = d->next;
+		
+		d->clear_free_func(d->data);
+		OPENSSL_free(d);
+		
+		d = next;
+		}
+	*ex_data = NULL;
+	}
+
+
+/* functions for EC_POINT objects */
+
+EC_POINT *EC_POINT_new(const EC_GROUP *group)
+	{
+	EC_POINT *ret;
+
+	if (group == NULL)
+		{
+		ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
+		return NULL;
+		}
+	if (group->meth->point_init == 0)
+		{
+		ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return NULL;
+		}
+
+	ret = OPENSSL_malloc(sizeof *ret);
+	if (ret == NULL)
+		{
+		ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+
+	ret->meth = group->meth;
+	
+	if (!ret->meth->point_init(ret))
+		{
+		OPENSSL_free(ret);
+		return NULL;
+		}
+	
+	return ret;
+	}
+
+
+void EC_POINT_free(EC_POINT *point)
+	{
+	if (!point) return;
+
+	if (point->meth->point_finish != 0)
+		point->meth->point_finish(point);
+	OPENSSL_free(point);
+	}
+ 
+
+void EC_POINT_clear_free(EC_POINT *point)
+	{
+	if (!point) return;
+
+	if (point->meth->point_clear_finish != 0)
+		point->meth->point_clear_finish(point);
+	else if (point->meth->point_finish != 0)
+		point->meth->point_finish(point);
+	OPENSSL_cleanse(point, sizeof *point);
+	OPENSSL_free(point);
+	}
+
+
+int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
+	{
+	if (dest->meth->point_copy == 0)
+		{
+		ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (dest->meth != src->meth)
+		{
+		ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	if (dest == src)
+		return 1;
+	return dest->meth->point_copy(dest, src);
+	}
+
+
+EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
+	{
+	EC_POINT *t;
+	int r;
+
+	if (a == NULL) return NULL;
+
+	t = EC_POINT_new(group);
+	if (t == NULL) return(NULL);
+	r = EC_POINT_copy(t, a);
+	if (!r)
+		{
+		EC_POINT_free(t);
+		return NULL;
+		}
+	else return t;
+	}
+
+
+const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
+	{
+	return point->meth;
+	}
+
+
+int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
+	{
+	if (group->meth->point_set_to_infinity == 0)
+		{
+		ECerr(EC_F_EC_POINT_SET_TO_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (group->meth != point->meth)
+		{
+		ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->point_set_to_infinity(group, point);
+	}
+
+
+int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
+	const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
+	{
+	if (group->meth->point_set_Jprojective_coordinates_GFp == 0)
+		{
+		ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (group->meth != point->meth)
+		{
+		ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
+	}
+
+
+int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
+	BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
+	{
+	if (group->meth->point_get_Jprojective_coordinates_GFp == 0)
+		{
+		ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (group->meth != point->meth)
+		{
+		ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
+	}
+
+
+int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
+	{
+	if (group->meth->point_set_affine_coordinates == 0)
+		{
+		ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (group->meth != point->meth)
+		{
+		ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
+	}
+
+
+int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
+	{
+	if (group->meth->point_set_affine_coordinates == 0)
+		{
+		ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (group->meth != point->meth)
+		{
+		ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
+	}
+
+
+int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
+	BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
+	{
+	if (group->meth->point_get_affine_coordinates == 0)
+		{
+		ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (group->meth != point->meth)
+		{
+		ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
+	}
+
+
+int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *point,
+	BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
+	{
+	if (group->meth->point_get_affine_coordinates == 0)
+		{
+		ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (group->meth != point->meth)
+		{
+		ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
+	}
+
+
+int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
+	const BIGNUM *x, int y_bit, BN_CTX *ctx)
+	{
+	if (group->meth->point_set_compressed_coordinates == 0)
+		{
+		ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (group->meth != point->meth)
+		{
+		ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
+	}
+
+
+int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
+	const BIGNUM *x, int y_bit, BN_CTX *ctx)
+	{
+	if (group->meth->point_set_compressed_coordinates == 0)
+		{
+		ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (group->meth != point->meth)
+		{
+		ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
+	}
+
+
+size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
+        unsigned char *buf, size_t len, BN_CTX *ctx)
+	{
+	if (group->meth->point2oct == 0)
+		{
+		ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (group->meth != point->meth)
+		{
+		ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->point2oct(group, point, form, buf, len, ctx);
+	}
+
+
+int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
+        const unsigned char *buf, size_t len, BN_CTX *ctx)
+	{
+	if (group->meth->oct2point == 0)
+		{
+		ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (group->meth != point->meth)
+		{
+		ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->oct2point(group, point, buf, len, ctx);
+	}
+
+
+int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
+	{
+	if (group->meth->add == 0)
+		{
+		ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth))
+		{
+		ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->add(group, r, a, b, ctx);
+	}
+
+
+int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
+	{
+	if (group->meth->dbl == 0)
+		{
+		ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if ((group->meth != r->meth) || (r->meth != a->meth))
+		{
+		ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->dbl(group, r, a, ctx);
+	}
+
+
+int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
+	{
+	if (group->meth->dbl == 0)
+		{
+		ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (group->meth != a->meth)
+		{
+		ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->invert(group, a, ctx);
+	}
+
+
+int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
+	{
+	if (group->meth->is_at_infinity == 0)
+		{
+		ECerr(EC_F_EC_POINT_IS_AT_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (group->meth != point->meth)
+		{
+		ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->is_at_infinity(group, point);
+	}
+
+
+int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
+	{
+	if (group->meth->is_on_curve == 0)
+		{
+		ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (group->meth != point->meth)
+		{
+		ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->is_on_curve(group, point, ctx);
+	}
+
+
+int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
+	{
+	if (group->meth->point_cmp == 0)
+		{
+		ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if ((group->meth != a->meth) || (a->meth != b->meth))
+		{
+		ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->point_cmp(group, a, b, ctx);
+	}
+
+
+int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
+	{
+	if (group->meth->make_affine == 0)
+		{
+		ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	if (group->meth != point->meth)
+		{
+		ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+	return group->meth->make_affine(group, point, ctx);
+	}
+
+
+int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
+	{
+	size_t i;
+
+	if (group->meth->points_make_affine == 0)
+		{
+		ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+		}
+	for (i = 0; i < num; i++)
+		{
+		if (group->meth != points[i]->meth)
+			{
+			ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
+			return 0;
+			}
+		}
+	return group->meth->points_make_affine(group, num, points, ctx);
+	}
+
+
+/* Functions for point multiplication.
+ *
+ * If group->meth->mul is 0, we use the wNAF-based implementations in ec_mult.c;
+ * otherwise we dispatch through methods.
+ */
+
+int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
+	{
+	if (group->meth->mul == 0)
+		/* use default */
+		return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
+
+	return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
+	}
+
+int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
+	const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
+	{
+	/* just a convenient interface to EC_POINTs_mul() */
+
+	const EC_POINT *points[1];
+	const BIGNUM *scalars[1];
+
+	points[0] = point;
+	scalars[0] = p_scalar;
+
+	return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL), points, scalars, ctx);
+	}
+
+int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+	{
+	if (group->meth->mul == 0)
+		/* use default */
+		return ec_wNAF_precompute_mult(group, ctx);
+
+	if (group->meth->precompute_mult != 0)
+		return group->meth->precompute_mult(group, ctx);
+	else
+		return 1; /* nothing to do, so report success */
+	}
+
+int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
+	{
+	if (group->meth->mul == 0)
+		/* use default */
+		return ec_wNAF_have_precompute_mult(group);
+
+	if (group->meth->have_precompute_mult != 0)
+		return group->meth->have_precompute_mult(group);
+	else
+		return 0; /* cannot tell whether precomputation has been performed */
+	}
diff --git a/openssl/crypto/ec/ec_mult.c b/openssl/crypto/ec/ec_mult.c
new file mode 100644
index 0000000..19f2167
--- /dev/null
+++ b/openssl/crypto/ec/ec_mult.c
@@ -0,0 +1,940 @@
+/* crypto/ec/ec_mult.c */
+/*
+ * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include <string.h>
+
+#include <openssl/err.h>
+
+#include "ec_lcl.h"
+
+
+/*
+ * This file implements the wNAF-based interleaving multi-exponentation method
+ * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>);
+ * for multiplication with precomputation, we use wNAF splitting
+ * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>).
+ */
+
+
+
+
+/* structure for precomputed multiples of the generator */
+typedef struct ec_pre_comp_st {
+	const EC_GROUP *group; /* parent EC_GROUP object */
+	size_t blocksize;      /* block size for wNAF splitting */
+	size_t numblocks;      /* max. number of blocks for which we have precomputation */
+	size_t w;              /* window size */
+	EC_POINT **points;     /* array with pre-calculated multiples of generator:
+	                        * 'num' pointers to EC_POINT objects followed by a NULL */
+	size_t num;            /* numblocks * 2^(w-1) */
+	int references;
+} EC_PRE_COMP;
+ 
+/* functions to manage EC_PRE_COMP within the EC_GROUP extra_data framework */
+static void *ec_pre_comp_dup(void *);
+static void ec_pre_comp_free(void *);
+static void ec_pre_comp_clear_free(void *);
+
+static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group)
+	{
+	EC_PRE_COMP *ret = NULL;
+
+	if (!group)
+		return NULL;
+
+	ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP));
+	if (!ret)
+		{
+		ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+		return ret;
+		}
+	ret->group = group;
+	ret->blocksize = 8; /* default */
+	ret->numblocks = 0;
+	ret->w = 4; /* default */
+	ret->points = NULL;
+	ret->num = 0;
+	ret->references = 1;
+	return ret;
+	}
+
+static void *ec_pre_comp_dup(void *src_)
+	{
+	EC_PRE_COMP *src = src_;
+
+	/* no need to actually copy, these objects never change! */
+
+	CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
+
+	return src_;
+	}
+
+static void ec_pre_comp_free(void *pre_)
+	{
+	int i;
+	EC_PRE_COMP *pre = pre_;
+
+	if (!pre)
+		return;
+
+	i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+	if (i > 0)
+		return;
+
+	if (pre->points)
+		{
+		EC_POINT **p;
+
+		for (p = pre->points; *p != NULL; p++)
+			EC_POINT_free(*p);
+		OPENSSL_free(pre->points);
+		}
+	OPENSSL_free(pre);
+	}
+
+static void ec_pre_comp_clear_free(void *pre_)
+	{
+	int i;
+	EC_PRE_COMP *pre = pre_;
+
+	if (!pre)
+		return;
+
+	i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+	if (i > 0)
+		return;
+
+	if (pre->points)
+		{
+		EC_POINT **p;
+
+		for (p = pre->points; *p != NULL; p++)
+			{
+			EC_POINT_clear_free(*p);
+			OPENSSL_cleanse(p, sizeof *p);
+			}
+		OPENSSL_free(pre->points);
+		}
+	OPENSSL_cleanse(pre, sizeof *pre);
+	OPENSSL_free(pre);
+	}
+
+
+
+
+/* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
+ * This is an array  r[]  of values that are either zero or odd with an
+ * absolute value less than  2^w  satisfying
+ *     scalar = \sum_j r[j]*2^j
+ * where at most one of any  w+1  consecutive digits is non-zero
+ * with the exception that the most significant digit may be only
+ * w-1 zeros away from that next non-zero digit.
+ */
+static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
+	{
+	int window_val;
+	int ok = 0;
+	signed char *r = NULL;
+	int sign = 1;
+	int bit, next_bit, mask;
+	size_t len = 0, j;
+	
+	if (BN_is_zero(scalar))
+		{
+		r = OPENSSL_malloc(1);
+		if (!r)
+			{
+			ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		r[0] = 0;
+		*ret_len = 1;
+		return r;
+		}
+		
+	if (w <= 0 || w > 7) /* 'signed char' can represent integers with absolute values less than 2^7 */
+		{
+		ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+		goto err;
+		}
+	bit = 1 << w; /* at most 128 */
+	next_bit = bit << 1; /* at most 256 */
+	mask = next_bit - 1; /* at most 255 */
+
+	if (BN_is_negative(scalar))
+		{
+		sign = -1;
+		}
+
+	if (scalar->d == NULL || scalar->top == 0)
+		{
+		ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+		goto err;
+		}
+
+	len = BN_num_bits(scalar);
+	r = OPENSSL_malloc(len + 1); /* modified wNAF may be one digit longer than binary representation
+	                              * (*ret_len will be set to the actual length, i.e. at most
+	                              * BN_num_bits(scalar) + 1) */
+	if (r == NULL)
+		{
+		ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	window_val = scalar->d[0] & mask;
+	j = 0;
+	while ((window_val != 0) || (j + w + 1 < len)) /* if j+w+1 >= len, window_val will not increase */
+		{
+		int digit = 0;
+
+		/* 0 <= window_val <= 2^(w+1) */
+
+		if (window_val & 1)
+			{
+			/* 0 < window_val < 2^(w+1) */
+
+			if (window_val & bit)
+				{
+				digit = window_val - next_bit; /* -2^w < digit < 0 */
+
+#if 1 /* modified wNAF */
+				if (j + w + 1 >= len)
+					{
+					/* special case for generating modified wNAFs:
+					 * no new bits will be added into window_val,
+					 * so using a positive digit here will decrease
+					 * the total length of the representation */
+					
+					digit = window_val & (mask >> 1); /* 0 < digit < 2^w */
+					}
+#endif
+				}
+			else
+				{
+				digit = window_val; /* 0 < digit < 2^w */
+				}
+			
+			if (digit <= -bit || digit >= bit || !(digit & 1))
+				{
+				ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+
+			window_val -= digit;
+
+			/* now window_val is 0 or 2^(w+1) in standard wNAF generation;
+			 * for modified window NAFs, it may also be 2^w
+			 */
+			if (window_val != 0 && window_val != next_bit && window_val != bit)
+				{
+				ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+			}
+
+		r[j++] = sign * digit;
+
+		window_val >>= 1;
+		window_val += bit * BN_is_bit_set(scalar, j + w);
+
+		if (window_val > next_bit)
+			{
+			ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+		}
+
+	if (j > len + 1)
+		{
+		ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+		goto err;
+		}
+	len = j;
+	ok = 1;
+
+ err:
+	if (!ok)
+		{
+		OPENSSL_free(r);
+		r = NULL;
+		}
+	if (ok)
+		*ret_len = len;
+	return r;
+	}
+
+
+/* TODO: table should be optimised for the wNAF-based implementation,
+ *       sometimes smaller windows will give better performance
+ *       (thus the boundaries should be increased)
+ */
+#define EC_window_bits_for_scalar_size(b) \
+		((size_t) \
+		 ((b) >= 2000 ? 6 : \
+		  (b) >=  800 ? 5 : \
+		  (b) >=  300 ? 4 : \
+		  (b) >=   70 ? 3 : \
+		  (b) >=   20 ? 2 : \
+		  1))
+
+/* Compute
+ *      \sum scalars[i]*points[i],
+ * also including
+ *      scalar*generator
+ * in the addition if scalar != NULL
+ */
+int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
+	{
+	BN_CTX *new_ctx = NULL;
+	const EC_POINT *generator = NULL;
+	EC_POINT *tmp = NULL;
+	size_t totalnum;
+	size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */
+	size_t pre_points_per_block = 0;
+	size_t i, j;
+	int k;
+	int r_is_inverted = 0;
+	int r_is_at_infinity = 1;
+	size_t *wsize = NULL; /* individual window sizes */
+	signed char **wNAF = NULL; /* individual wNAFs */
+	size_t *wNAF_len = NULL;
+	size_t max_len = 0;
+	size_t num_val;
+	EC_POINT **val = NULL; /* precomputation */
+	EC_POINT **v;
+	EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or 'pre_comp->points' */
+	const EC_PRE_COMP *pre_comp = NULL;
+	int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be treated like other scalars,
+	                     * i.e. precomputation is not available */
+	int ret = 0;
+	
+	if (group->meth != r->meth)
+		{
+		ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+		}
+
+	if ((scalar == NULL) && (num == 0))
+		{
+		return EC_POINT_set_to_infinity(group, r);
+		}
+
+	for (i = 0; i < num; i++)
+		{
+		if (group->meth != points[i]->meth)
+			{
+			ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
+			return 0;
+			}
+		}
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			goto err;
+		}
+
+	if (scalar != NULL)
+		{
+		generator = EC_GROUP_get0_generator(group);
+		if (generator == NULL)
+			{
+			ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR);
+			goto err;
+			}
+		
+		/* look if we can use precomputed multiples of generator */
+
+		pre_comp = EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
+
+		if (pre_comp && pre_comp->numblocks && (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == 0))
+			{
+			blocksize = pre_comp->blocksize;
+
+			/* determine maximum number of blocks that wNAF splitting may yield
+			 * (NB: maximum wNAF length is bit length plus one) */
+			numblocks = (BN_num_bits(scalar) / blocksize) + 1;
+
+			/* we cannot use more blocks than we have precomputation for */
+			if (numblocks > pre_comp->numblocks)
+				numblocks = pre_comp->numblocks;
+
+			pre_points_per_block = (size_t)1 << (pre_comp->w - 1);
+
+			/* check that pre_comp looks sane */
+			if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block))
+				{
+				ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+			}
+		else
+			{
+			/* can't use precomputation */
+			pre_comp = NULL;
+			numblocks = 1;
+			num_scalar = 1; /* treat 'scalar' like 'num'-th element of 'scalars' */
+			}
+		}
+	
+	totalnum = num + numblocks;
+
+	wsize    = OPENSSL_malloc(totalnum * sizeof wsize[0]);
+	wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]);
+	wNAF     = OPENSSL_malloc((totalnum + 1) * sizeof wNAF[0]); /* includes space for pivot */
+	val_sub  = OPENSSL_malloc(totalnum * sizeof val_sub[0]);
+		 
+	if (!wsize || !wNAF_len || !wNAF || !val_sub)
+		{
+		ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	wNAF[0] = NULL;	/* preliminary pivot */
+
+	/* num_val will be the total number of temporarily precomputed points */
+	num_val = 0;
+
+	for (i = 0; i < num + num_scalar; i++)
+		{
+		size_t bits;
+
+		bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);
+		wsize[i] = EC_window_bits_for_scalar_size(bits);
+		num_val += (size_t)1 << (wsize[i] - 1);
+		wNAF[i + 1] = NULL; /* make sure we always have a pivot */
+		wNAF[i] = compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i]);
+		if (wNAF[i] == NULL)
+			goto err;
+		if (wNAF_len[i] > max_len)
+			max_len = wNAF_len[i];
+		}
+
+	if (numblocks)
+		{
+		/* we go here iff scalar != NULL */
+		
+		if (pre_comp == NULL)
+			{
+			if (num_scalar != 1)
+				{
+				ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+			/* we have already generated a wNAF for 'scalar' */
+			}
+		else
+			{
+			signed char *tmp_wNAF = NULL;
+			size_t tmp_len = 0;
+			
+			if (num_scalar != 0)
+				{
+				ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+
+			/* use the window size for which we have precomputation */
+			wsize[num] = pre_comp->w;
+			tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len);
+			if (!tmp_wNAF)
+				goto err;
+
+			if (tmp_len <= max_len)
+				{
+				/* One of the other wNAFs is at least as long
+				 * as the wNAF belonging to the generator,
+				 * so wNAF splitting will not buy us anything. */
+
+				numblocks = 1;
+				totalnum = num + 1; /* don't use wNAF splitting */
+				wNAF[num] = tmp_wNAF;
+				wNAF[num + 1] = NULL;
+				wNAF_len[num] = tmp_len;
+				if (tmp_len > max_len)
+					max_len = tmp_len;
+				/* pre_comp->points starts with the points that we need here: */
+				val_sub[num] = pre_comp->points;
+				}
+			else
+				{
+				/* don't include tmp_wNAF directly into wNAF array
+				 * - use wNAF splitting and include the blocks */
+
+				signed char *pp;
+				EC_POINT **tmp_points;
+				
+				if (tmp_len < numblocks * blocksize)
+					{
+					/* possibly we can do with fewer blocks than estimated */
+					numblocks = (tmp_len + blocksize - 1) / blocksize;
+					if (numblocks > pre_comp->numblocks)
+						{
+						ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+						goto err;
+						}
+					totalnum = num + numblocks;
+					}
+				
+				/* split wNAF in 'numblocks' parts */
+				pp = tmp_wNAF;
+				tmp_points = pre_comp->points;
+
+				for (i = num; i < totalnum; i++)
+					{
+					if (i < totalnum - 1)
+						{
+						wNAF_len[i] = blocksize;
+						if (tmp_len < blocksize)
+							{
+							ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+							goto err;
+							}
+						tmp_len -= blocksize;
+						}
+					else
+						/* last block gets whatever is left
+						 * (this could be more or less than 'blocksize'!) */
+						wNAF_len[i] = tmp_len;
+					
+					wNAF[i + 1] = NULL;
+					wNAF[i] = OPENSSL_malloc(wNAF_len[i]);
+					if (wNAF[i] == NULL)
+						{
+						ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
+						OPENSSL_free(tmp_wNAF);
+						goto err;
+						}
+					memcpy(wNAF[i], pp, wNAF_len[i]);
+					if (wNAF_len[i] > max_len)
+						max_len = wNAF_len[i];
+
+					if (*tmp_points == NULL)
+						{
+						ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+						OPENSSL_free(tmp_wNAF);
+						goto err;
+						}
+					val_sub[i] = tmp_points;
+					tmp_points += pre_points_per_block;
+					pp += blocksize;
+					}
+				OPENSSL_free(tmp_wNAF);
+				}
+			}
+		}
+
+	/* All points we precompute now go into a single array 'val'.
+	 * 'val_sub[i]' is a pointer to the subarray for the i-th point,
+	 * or to a subarray of 'pre_comp->points' if we already have precomputation. */
+	val = OPENSSL_malloc((num_val + 1) * sizeof val[0]);
+	if (val == NULL)
+		{
+		ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	val[num_val] = NULL; /* pivot element */
+
+	/* allocate points for precomputation */
+	v = val;
+	for (i = 0; i < num + num_scalar; i++)
+		{
+		val_sub[i] = v;
+		for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++)
+			{
+			*v = EC_POINT_new(group);
+			if (*v == NULL) goto err;
+			v++;
+			}
+		}
+	if (!(v == val + num_val))
+		{
+		ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+		goto err;
+		}
+
+	if (!(tmp = EC_POINT_new(group)))
+		goto err;
+
+	/* prepare precomputed values:
+	 *    val_sub[i][0] :=     points[i]
+	 *    val_sub[i][1] := 3 * points[i]
+	 *    val_sub[i][2] := 5 * points[i]
+	 *    ...
+	 */
+	for (i = 0; i < num + num_scalar; i++)
+		{
+		if (i < num)
+			{
+			if (!EC_POINT_copy(val_sub[i][0], points[i])) goto err;
+			}
+		else
+			{
+			if (!EC_POINT_copy(val_sub[i][0], generator)) goto err;
+			}
+
+		if (wsize[i] > 1)
+			{
+			if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) goto err;
+			for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++)
+				{
+				if (!EC_POINT_add(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) goto err;
+				}
+			}
+		}
+
+#if 1 /* optional; EC_window_bits_for_scalar_size assumes we do this step */
+	if (!EC_POINTs_make_affine(group, num_val, val, ctx))
+		goto err;
+#endif
+
+	r_is_at_infinity = 1;
+
+	for (k = max_len - 1; k >= 0; k--)
+		{
+		if (!r_is_at_infinity)
+			{
+			if (!EC_POINT_dbl(group, r, r, ctx)) goto err;
+			}
+		
+		for (i = 0; i < totalnum; i++)
+			{
+			if (wNAF_len[i] > (size_t)k)
+				{
+				int digit = wNAF[i][k];
+				int is_neg;
+
+				if (digit) 
+					{
+					is_neg = digit < 0;
+
+					if (is_neg)
+						digit = -digit;
+
+					if (is_neg != r_is_inverted)
+						{
+						if (!r_is_at_infinity)
+							{
+							if (!EC_POINT_invert(group, r, ctx)) goto err;
+							}
+						r_is_inverted = !r_is_inverted;
+						}
+
+					/* digit > 0 */
+
+					if (r_is_at_infinity)
+						{
+						if (!EC_POINT_copy(r, val_sub[i][digit >> 1])) goto err;
+						r_is_at_infinity = 0;
+						}
+					else
+						{
+						if (!EC_POINT_add(group, r, r, val_sub[i][digit >> 1], ctx)) goto err;
+						}
+					}
+				}
+			}
+		}
+
+	if (r_is_at_infinity)
+		{
+		if (!EC_POINT_set_to_infinity(group, r)) goto err;
+		}
+	else
+		{
+		if (r_is_inverted)
+			if (!EC_POINT_invert(group, r, ctx)) goto err;
+		}
+	
+	ret = 1;
+
+ err:
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	if (tmp != NULL)
+		EC_POINT_free(tmp);
+	if (wsize != NULL)
+		OPENSSL_free(wsize);
+	if (wNAF_len != NULL)
+		OPENSSL_free(wNAF_len);
+	if (wNAF != NULL)
+		{
+		signed char **w;
+		
+		for (w = wNAF; *w != NULL; w++)
+			OPENSSL_free(*w);
+		
+		OPENSSL_free(wNAF);
+		}
+	if (val != NULL)
+		{
+		for (v = val; *v != NULL; v++)
+			EC_POINT_clear_free(*v);
+
+		OPENSSL_free(val);
+		}
+	if (val_sub != NULL)
+		{
+		OPENSSL_free(val_sub);
+		}
+	return ret;
+	}
+
+
+/* ec_wNAF_precompute_mult()
+ * creates an EC_PRE_COMP object with preprecomputed multiples of the generator
+ * for use with wNAF splitting as implemented in ec_wNAF_mul().
+ * 
+ * 'pre_comp->points' is an array of multiples of the generator
+ * of the following form:
+ * points[0] =     generator;
+ * points[1] = 3 * generator;
+ * ...
+ * points[2^(w-1)-1] =     (2^(w-1)-1) * generator;
+ * points[2^(w-1)]   =     2^blocksize * generator;
+ * points[2^(w-1)+1] = 3 * 2^blocksize * generator;
+ * ...
+ * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) *  2^(blocksize*(numblocks-2)) * generator
+ * points[2^(w-1)*(numblocks-1)]   =              2^(blocksize*(numblocks-1)) * generator
+ * ...
+ * points[2^(w-1)*numblocks-1]     = (2^(w-1)) *  2^(blocksize*(numblocks-1)) * generator
+ * points[2^(w-1)*numblocks]       = NULL
+ */
+int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+	{
+	const EC_POINT *generator;
+	EC_POINT *tmp_point = NULL, *base = NULL, **var;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *order;
+	size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num;
+	EC_POINT **points = NULL;
+	EC_PRE_COMP *pre_comp;
+	int ret = 0;
+
+	/* if there is an old EC_PRE_COMP object, throw it away */
+	EC_EX_DATA_free_data(&group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
+
+	if ((pre_comp = ec_pre_comp_new(group)) == NULL)
+		return 0;
+
+	generator = EC_GROUP_get0_generator(group);
+	if (generator == NULL)
+		{
+		ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR);
+		goto err;
+		}
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			goto err;
+		}
+	
+	BN_CTX_start(ctx);
+	order = BN_CTX_get(ctx);
+	if (order == NULL) goto err;
+	
+	if (!EC_GROUP_get_order(group, order, ctx)) goto err;		
+	if (BN_is_zero(order))
+		{
+		ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER);
+		goto err;
+		}
+
+	bits = BN_num_bits(order);
+	/* The following parameters mean we precompute (approximately)
+	 * one point per bit.
+	 *
+	 * TBD: The combination  8, 4  is perfect for 160 bits; for other
+	 * bit lengths, other parameter combinations might provide better
+	 * efficiency.
+	 */
+	blocksize = 8;
+	w = 4;
+	if (EC_window_bits_for_scalar_size(bits) > w)
+		{
+		/* let's not make the window too small ... */
+		w = EC_window_bits_for_scalar_size(bits);
+		}
+
+	numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks to use for wNAF splitting */
+	
+	pre_points_per_block = (size_t)1 << (w - 1);
+	num = pre_points_per_block * numblocks; /* number of points to compute and store */
+
+	points = OPENSSL_malloc(sizeof (EC_POINT*)*(num + 1));
+	if (!points)
+		{
+		ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	var = points;
+	var[num] = NULL; /* pivot */
+	for (i = 0; i < num; i++)
+		{
+		if ((var[i] = EC_POINT_new(group)) == NULL)
+			{
+			ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+
+	if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group)))
+		{
+		ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}	
+	
+	if (!EC_POINT_copy(base, generator))
+		goto err;
+	
+	/* do the precomputation */
+	for (i = 0; i < numblocks; i++)
+		{
+		size_t j;
+
+		if (!EC_POINT_dbl(group, tmp_point, base, ctx))
+			goto err;
+
+		if (!EC_POINT_copy(*var++, base))
+			goto err;
+
+		for (j = 1; j < pre_points_per_block; j++, var++)
+			{
+			/* calculate odd multiples of the current base point */
+			if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx))
+				goto err;
+			}
+
+		if (i < numblocks - 1)
+			{
+			/* get the next base (multiply current one by 2^blocksize) */
+			size_t k;
+
+			if (blocksize <= 2)
+				{
+				ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}				
+
+			if (!EC_POINT_dbl(group, base, tmp_point, ctx))
+				goto err;
+			for (k = 2; k < blocksize; k++)
+				{
+				if (!EC_POINT_dbl(group,base,base,ctx))
+					goto err;
+				}
+			}
+ 		}
+
+	if (!EC_POINTs_make_affine(group, num, points, ctx))
+		goto err;
+	
+	pre_comp->group = group;
+	pre_comp->blocksize = blocksize;
+	pre_comp->numblocks = numblocks;
+	pre_comp->w = w;
+	pre_comp->points = points;
+	points = NULL;
+	pre_comp->num = num;
+
+	if (!EC_EX_DATA_set_data(&group->extra_data, pre_comp,
+		ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free))
+		goto err;
+	pre_comp = NULL;
+
+	ret = 1;
+ err:
+	if (ctx != NULL)
+		BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	if (pre_comp)
+		ec_pre_comp_free(pre_comp);
+	if (points)
+		{
+		EC_POINT **p;
+
+		for (p = points; *p != NULL; p++)
+			EC_POINT_free(*p);
+		OPENSSL_free(points);
+		}
+	if (tmp_point)
+		EC_POINT_free(tmp_point);
+	if (base)
+		EC_POINT_free(base);
+	return ret;
+	}
+
+
+int ec_wNAF_have_precompute_mult(const EC_GROUP *group)
+	{
+	if (EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free) != NULL)
+		return 1;
+	else
+		return 0;
+	}
diff --git a/openssl/crypto/ec/ec_pmeth.c b/openssl/crypto/ec/ec_pmeth.c
new file mode 100644
index 0000000..f433076
--- /dev/null
+++ b/openssl/crypto/ec/ec_pmeth.c
@@ -0,0 +1,340 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/ec.h>
+#include <openssl/ecdsa.h>
+#include <openssl/evp.h>
+#include "evp_locl.h"
+
+/* EC pkey context structure */
+
+typedef struct
+	{
+	/* Key and paramgen group */
+	EC_GROUP *gen_group;
+	/* message digest */
+	const EVP_MD *md;
+	} EC_PKEY_CTX;
+
+static int pkey_ec_init(EVP_PKEY_CTX *ctx)
+	{
+	EC_PKEY_CTX *dctx;
+	dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX));
+	if (!dctx)
+		return 0;
+	dctx->gen_group = NULL;
+	dctx->md = NULL;
+
+	ctx->data = dctx;
+
+	return 1;
+	}
+
+static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+	{
+	EC_PKEY_CTX *dctx, *sctx;
+	if (!pkey_ec_init(dst))
+		return 0;
+       	sctx = src->data;
+	dctx = dst->data;
+	if (sctx->gen_group)
+		{
+		dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
+		if (!dctx->gen_group)
+			return 0;
+		}
+	dctx->md = sctx->md;
+	return 1;
+	}
+
+static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx)
+	{
+	EC_PKEY_CTX *dctx = ctx->data;
+	if (dctx)
+		{
+		if (dctx->gen_group)
+			EC_GROUP_free(dctx->gen_group);
+		OPENSSL_free(dctx);
+		}
+	}
+
+static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					const unsigned char *tbs, size_t tbslen)
+	{
+	int ret, type;
+	unsigned int sltmp;
+	EC_PKEY_CTX *dctx = ctx->data;
+	EC_KEY *ec = ctx->pkey->pkey.ec;
+
+	if (!sig)
+		{
+		*siglen = ECDSA_size(ec);
+		return 1;
+		}
+	else if(*siglen < (size_t)ECDSA_size(ec))
+		{
+		ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
+		return 0;
+		}
+
+	if (dctx->md)
+		type = EVP_MD_type(dctx->md);
+	else
+		type = NID_sha1;
+
+
+	ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
+
+	if (ret <= 0)
+		return ret;
+	*siglen = (size_t)sltmp;
+	return 1;
+	}
+
+static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
+					const unsigned char *sig, size_t siglen,
+					const unsigned char *tbs, size_t tbslen)
+	{
+	int ret, type;
+	EC_PKEY_CTX *dctx = ctx->data;
+	EC_KEY *ec = ctx->pkey->pkey.ec;
+
+	if (dctx->md)
+		type = EVP_MD_type(dctx->md);
+	else
+		type = NID_sha1;
+
+	ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
+
+	return ret;
+	}
+
+static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
+	{
+	int ret;
+	size_t outlen;
+	const EC_POINT *pubkey = NULL;
+	if (!ctx->pkey || !ctx->peerkey)
+		{
+		ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET);
+		return 0;
+		}
+
+	if (!key)
+		{
+		const EC_GROUP *group;
+		group = EC_KEY_get0_group(ctx->pkey->pkey.ec);
+		*keylen = (EC_GROUP_get_degree(group) + 7)/8;
+		return 1;
+		}
+
+	pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
+
+	/* NB: unlike PKS#3 DH, if *outlen is less than maximum size this is
+	 * not an error, the result is truncated.
+	 */
+
+	outlen = *keylen;
+		
+	ret = ECDH_compute_key(key, outlen, pubkey, ctx->pkey->pkey.ec, 0);
+	if (ret < 0)
+		return ret;
+	*keylen = ret;
+	return 1;
+	}
+
+static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+	{
+	EC_PKEY_CTX *dctx = ctx->data;
+	EC_GROUP *group;
+	switch (type)
+		{
+		case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
+		group = EC_GROUP_new_by_curve_name(p1);
+		if (group == NULL)
+			{
+			ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
+			return 0;
+			}
+		if (dctx->gen_group)
+			EC_GROUP_free(dctx->gen_group);
+		dctx->gen_group = group;
+		return 1;
+
+		case EVP_PKEY_CTRL_MD:
+		if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
+		    EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
+		    EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
+		    EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
+		    EVP_MD_type((const EVP_MD *)p2) != NID_sha512)
+			{
+			ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
+			return 0;
+			}
+		dctx->md = p2;
+		return 1;
+
+		case EVP_PKEY_CTRL_PEER_KEY:
+		/* Default behaviour is OK */
+		case EVP_PKEY_CTRL_DIGESTINIT:
+		case EVP_PKEY_CTRL_PKCS7_SIGN:
+		case EVP_PKEY_CTRL_CMS_SIGN:
+		return 1;
+
+		default:
+		return -2;
+
+		}
+	}
+			
+static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
+			const char *type, const char *value)
+	{
+	if (!strcmp(type, "ec_paramgen_curve"))
+		{
+		int nid;
+		nid = OBJ_sn2nid(value);
+		if (nid == NID_undef)
+			nid = OBJ_ln2nid(value);
+		if (nid == NID_undef)
+			{
+			ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
+			return 0;
+			}
+		return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
+		}
+	return -2;
+	}
+
+static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+	EC_KEY *ec = NULL;
+	EC_PKEY_CTX *dctx = ctx->data;
+	int ret = 0;
+	if (dctx->gen_group == NULL)
+		{
+		ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
+		return 0;
+		}
+	ec = EC_KEY_new();
+	if (!ec)
+		return 0;
+	ret = EC_KEY_set_group(ec, dctx->gen_group);
+	if (ret)
+		EVP_PKEY_assign_EC_KEY(pkey, ec);
+	else
+		EC_KEY_free(ec);
+	return ret;
+	}
+
+static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+	EC_KEY *ec = NULL;
+	if (ctx->pkey == NULL)
+		{
+		ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
+		return 0;
+		}
+	ec = EC_KEY_new();
+	if (!ec)
+		return 0;
+	EVP_PKEY_assign_EC_KEY(pkey, ec);
+	/* Note: if error return, pkey is freed by parent routine */
+	if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
+		return 0;
+	return EC_KEY_generate_key(pkey->pkey.ec);
+	}
+
+const EVP_PKEY_METHOD ec_pkey_meth = 
+	{
+	EVP_PKEY_EC,
+	0,
+	pkey_ec_init,
+	pkey_ec_copy,
+	pkey_ec_cleanup,
+
+	0,
+	pkey_ec_paramgen,
+
+	0,
+	pkey_ec_keygen,
+
+	0,
+	pkey_ec_sign,
+
+	0,
+	pkey_ec_verify,
+
+	0,0,
+
+	0,0,0,0,
+
+	0,0,
+
+	0,0,
+
+	0,
+	pkey_ec_derive,
+
+	pkey_ec_ctrl,
+	pkey_ec_ctrl_str
+
+	};
diff --git a/openssl/crypto/ec/ec_print.c b/openssl/crypto/ec/ec_print.c
new file mode 100644
index 0000000..f7c8a30
--- /dev/null
+++ b/openssl/crypto/ec/ec_print.c
@@ -0,0 +1,195 @@
+/* crypto/ec/ec_print.c */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/crypto.h>
+#include "ec_lcl.h"
+
+BIGNUM *EC_POINT_point2bn(const EC_GROUP *group, 
+                          const EC_POINT *point, 
+                          point_conversion_form_t form,
+                          BIGNUM *ret,
+                          BN_CTX *ctx)
+	{
+	size_t        buf_len=0;
+	unsigned char *buf;
+
+	buf_len = EC_POINT_point2oct(group, point, form,
+                                     NULL, 0, ctx);
+	if (buf_len == 0)
+		return NULL;
+
+	if ((buf = OPENSSL_malloc(buf_len)) == NULL)
+		return NULL;
+
+	if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx))
+		{
+		OPENSSL_free(buf);
+		return NULL;
+		}
+
+	ret = BN_bin2bn(buf, buf_len, ret);
+
+	OPENSSL_free(buf);
+
+	return ret;
+}
+
+EC_POINT *EC_POINT_bn2point(const EC_GROUP *group,
+                            const BIGNUM *bn,
+                            EC_POINT *point, 
+                            BN_CTX *ctx)
+	{
+	size_t        buf_len=0;
+	unsigned char *buf;
+	EC_POINT      *ret;
+
+	if ((buf_len = BN_num_bytes(bn)) == 0) return NULL;
+	buf = OPENSSL_malloc(buf_len);
+	if (buf == NULL)
+		return NULL;
+
+	if (!BN_bn2bin(bn, buf)) 
+		{
+		OPENSSL_free(buf);
+		return NULL;
+		}
+
+	if (point == NULL)
+		{
+		if ((ret = EC_POINT_new(group)) == NULL)
+			{
+			OPENSSL_free(buf);
+			return NULL;
+			}
+		}
+	else
+		ret = point;
+
+	if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx))
+		{
+		if (point == NULL)
+			EC_POINT_clear_free(ret);
+		OPENSSL_free(buf);
+		return NULL;
+		}
+
+	OPENSSL_free(buf);
+	return ret;
+	}
+
+static const char *HEX_DIGITS = "0123456789ABCDEF";
+
+/* the return value must be freed (using OPENSSL_free()) */
+char *EC_POINT_point2hex(const EC_GROUP *group,
+                         const EC_POINT *point,
+                         point_conversion_form_t form,
+                         BN_CTX *ctx)
+	{
+	char          *ret, *p;
+	size_t        buf_len=0,i;
+	unsigned char *buf, *pbuf;
+
+	buf_len = EC_POINT_point2oct(group, point, form,
+                                     NULL, 0, ctx);
+	if (buf_len == 0)
+		return NULL;
+
+	if ((buf = OPENSSL_malloc(buf_len)) == NULL)
+		return NULL;
+
+	if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx))
+		{
+		OPENSSL_free(buf);
+		return NULL;
+		}
+
+	ret = (char *)OPENSSL_malloc(buf_len*2+2);
+	if (ret == NULL)
+		{
+		OPENSSL_free(buf);
+		return NULL;
+		}
+	p = ret;
+	pbuf = buf;
+	for (i=buf_len; i > 0; i--)
+		{
+			int v = (int) *(pbuf++);
+			*(p++)=HEX_DIGITS[v>>4];
+			*(p++)=HEX_DIGITS[v&0x0F];
+		}
+	*p='\0';
+
+	OPENSSL_free(buf);
+
+	return ret;
+	}
+
+EC_POINT *EC_POINT_hex2point(const EC_GROUP *group,
+                             const char *buf,
+                             EC_POINT *point,
+                             BN_CTX *ctx)
+	{
+	EC_POINT *ret=NULL;
+	BIGNUM   *tmp_bn=NULL;
+
+	if (!BN_hex2bn(&tmp_bn, buf))
+		return NULL;
+
+	ret = EC_POINT_bn2point(group, tmp_bn, point, ctx);
+
+	BN_clear_free(tmp_bn);
+
+	return ret;
+	}
diff --git a/openssl/crypto/ec/eck_prn.c b/openssl/crypto/ec/eck_prn.c
new file mode 100644
index 0000000..7d3e175
--- /dev/null
+++ b/openssl/crypto/ec/eck_prn.c
@@ -0,0 +1,391 @@
+/* crypto/ec/eck_prn.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions originally developed by SUN MICROSYSTEMS, INC., and 
+ * contributed to the OpenSSL project.
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/ec.h>
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_FP_API
+int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
+	{
+	BIO *b;
+	int ret;
+
+	if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB);
+		return(0);
+		}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = ECPKParameters_print(b, x, off);
+	BIO_free(b);
+	return(ret);
+	}
+
+int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
+	{
+	BIO *b;
+	int ret;
+ 
+	if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
+		return(0);
+		}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = EC_KEY_print(b, x, off);
+	BIO_free(b);
+	return(ret);
+	}
+
+int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
+	{
+	BIO *b;
+	int ret;
+ 
+	if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
+		return(0);
+		}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = ECParameters_print(b, x);
+	BIO_free(b);
+	return(ret);
+	}
+#endif
+
+int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
+	{
+	EVP_PKEY *pk;
+	int ret;
+	pk = EVP_PKEY_new();
+	if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x))
+		return 0;
+	ret = EVP_PKEY_print_private(bp, pk, off, NULL);
+	EVP_PKEY_free(pk);
+	return ret;
+	}
+
+int ECParameters_print(BIO *bp, const EC_KEY *x)
+	{
+	EVP_PKEY *pk;
+	int ret;
+	pk = EVP_PKEY_new();
+	if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x))
+		return 0;
+	ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
+	EVP_PKEY_free(pk);
+	return ret;
+	}
+
+static int print_bin(BIO *fp, const char *str, const unsigned char *num,
+		size_t len, int off);
+
+int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
+	{
+	unsigned char *buffer=NULL;
+	size_t	buf_len=0, i;
+	int     ret=0, reason=ERR_R_BIO_LIB;
+	BN_CTX  *ctx=NULL;
+	const EC_POINT *point=NULL;
+	BIGNUM	*p=NULL, *a=NULL, *b=NULL, *gen=NULL,
+		*order=NULL, *cofactor=NULL;
+	const unsigned char *seed;
+	size_t	seed_len=0;
+	
+	static const char *gen_compressed = "Generator (compressed):";
+	static const char *gen_uncompressed = "Generator (uncompressed):";
+	static const char *gen_hybrid = "Generator (hybrid):";
+ 
+	if (!x)
+		{
+		reason = ERR_R_PASSED_NULL_PARAMETER;
+		goto err;
+		}
+
+	ctx = BN_CTX_new();
+	if (ctx == NULL)
+		{
+		reason = ERR_R_MALLOC_FAILURE;
+		goto err;
+		}
+
+	if (EC_GROUP_get_asn1_flag(x))
+		{
+		/* the curve parameter are given by an asn1 OID */
+		int nid;
+
+		if (!BIO_indent(bp, off, 128))
+			goto err;
+
+		nid = EC_GROUP_get_curve_name(x);
+		if (nid == 0)
+			goto err;
+
+		if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
+			goto err;
+		if (BIO_printf(bp, "\n") <= 0)
+			goto err;
+		}
+	else
+		{
+		/* explicit parameters */
+		int is_char_two = 0;
+		point_conversion_form_t form;
+		int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
+
+		if (tmp_nid == NID_X9_62_characteristic_two_field)
+			is_char_two = 1;
+
+		if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
+			(b = BN_new()) == NULL || (order = BN_new()) == NULL ||
+			(cofactor = BN_new()) == NULL)
+			{
+			reason = ERR_R_MALLOC_FAILURE;
+			goto err;
+			}
+
+		if (is_char_two)
+			{
+			if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx))
+				{
+				reason = ERR_R_EC_LIB;
+				goto err;
+				}
+			}
+		else /* prime field */
+			{
+			if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx))
+				{
+				reason = ERR_R_EC_LIB;
+				goto err;
+				}
+			}
+
+		if ((point = EC_GROUP_get0_generator(x)) == NULL)
+			{
+			reason = ERR_R_EC_LIB;
+			goto err;
+			}
+		if (!EC_GROUP_get_order(x, order, NULL) || 
+            		!EC_GROUP_get_cofactor(x, cofactor, NULL))
+			{
+			reason = ERR_R_EC_LIB;
+			goto err;
+			}
+		
+		form = EC_GROUP_get_point_conversion_form(x);
+
+		if ((gen = EC_POINT_point2bn(x, point, 
+				form, NULL, ctx)) == NULL)
+			{
+			reason = ERR_R_EC_LIB;
+			goto err;
+			}
+
+		buf_len = (size_t)BN_num_bytes(p);
+		if (buf_len < (i = (size_t)BN_num_bytes(a)))
+			buf_len = i;
+		if (buf_len < (i = (size_t)BN_num_bytes(b)))
+			buf_len = i;
+		if (buf_len < (i = (size_t)BN_num_bytes(gen)))
+			buf_len = i;
+		if (buf_len < (i = (size_t)BN_num_bytes(order)))
+			buf_len = i;
+		if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) 
+			buf_len = i;
+
+		if ((seed = EC_GROUP_get0_seed(x)) != NULL)
+			seed_len = EC_GROUP_get_seed_len(x);
+
+		buf_len += 10;
+		if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
+			{
+			reason = ERR_R_MALLOC_FAILURE;
+			goto err;
+			}
+
+		if (!BIO_indent(bp, off, 128))
+			goto err;
+
+		/* print the 'short name' of the field type */
+		if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
+			<= 0)
+			goto err;  
+
+		if (is_char_two)
+			{
+			/* print the 'short name' of the base type OID */
+			int basis_type = EC_GROUP_get_basis_type(x);
+			if (basis_type == 0)
+				goto err;
+
+			if (!BIO_indent(bp, off, 128))
+				goto err;
+
+			if (BIO_printf(bp, "Basis Type: %s\n", 
+				OBJ_nid2sn(basis_type)) <= 0)
+				goto err;
+
+			/* print the polynomial */
+			if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer,
+				off))
+				goto err;
+			}
+		else
+			{
+			if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer,off))
+				goto err;
+			}
+		if ((a != NULL) && !ASN1_bn_print(bp, "A:   ", a, buffer, off)) 
+			goto err;
+		if ((b != NULL) && !ASN1_bn_print(bp, "B:   ", b, buffer, off))
+			goto err;
+		if (form == POINT_CONVERSION_COMPRESSED)
+			{
+			if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
+				buffer, off))
+				goto err;
+			}
+		else if (form == POINT_CONVERSION_UNCOMPRESSED)
+			{
+			if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
+				buffer, off))
+				goto err;
+			}
+		else /* form == POINT_CONVERSION_HYBRID */
+			{
+			if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
+				buffer, off))
+				goto err;
+			}
+		if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order, 
+			buffer, off)) goto err;
+		if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor, 
+			buffer, off)) goto err;
+		if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
+			goto err;
+		}
+	ret=1;
+err:
+	if (!ret)
+ 		ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
+	if (p) 
+		BN_free(p);
+	if (a) 
+		BN_free(a);
+	if (b)
+		BN_free(b);
+	if (gen)
+		BN_free(gen);
+	if (order)
+		BN_free(order);
+	if (cofactor)
+		BN_free(cofactor);
+	if (ctx)
+		BN_CTX_free(ctx);
+	if (buffer != NULL) 
+		OPENSSL_free(buffer);
+	return(ret);	
+	}
+
+static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
+		size_t len, int off)
+	{
+	size_t i;
+	char str[128];
+
+	if (buf == NULL)
+		return 1;
+	if (off)
+		{
+		if (off > 128)
+			off=128;
+		memset(str,' ',off);
+		if (BIO_write(fp, str, off) <= 0)
+			return 0;
+		}
+
+	if (BIO_printf(fp,"%s", name) <= 0)
+		return 0;
+
+	for (i=0; i<len; i++)
+		{
+		if ((i%15) == 0)
+			{
+			str[0]='\n';
+			memset(&(str[1]),' ',off+4);
+			if (BIO_write(fp, str, off+1+4) <= 0)
+				return 0;
+			}
+		if (BIO_printf(fp,"%02x%s",buf[i],((i+1) == len)?"":":") <= 0)
+			return 0;
+		}
+	if (BIO_write(fp,"\n",1) <= 0)
+		return 0;
+
+	return 1;
+	}
diff --git a/openssl/crypto/ec/ecp_mont.c b/openssl/crypto/ec/ecp_mont.c
new file mode 100644
index 0000000..9fc4a46
--- /dev/null
+++ b/openssl/crypto/ec/ecp_mont.c
@@ -0,0 +1,315 @@
+/* crypto/ec/ecp_mont.c */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include <openssl/err.h>
+
+#include "ec_lcl.h"
+
+
+const EC_METHOD *EC_GFp_mont_method(void)
+	{
+	static const EC_METHOD ret = {
+		NID_X9_62_prime_field,
+		ec_GFp_mont_group_init,
+		ec_GFp_mont_group_finish,
+		ec_GFp_mont_group_clear_finish,
+		ec_GFp_mont_group_copy,
+		ec_GFp_mont_group_set_curve,
+		ec_GFp_simple_group_get_curve,
+		ec_GFp_simple_group_get_degree,
+		ec_GFp_simple_group_check_discriminant,
+		ec_GFp_simple_point_init,
+		ec_GFp_simple_point_finish,
+		ec_GFp_simple_point_clear_finish,
+		ec_GFp_simple_point_copy,
+		ec_GFp_simple_point_set_to_infinity,
+		ec_GFp_simple_set_Jprojective_coordinates_GFp,
+		ec_GFp_simple_get_Jprojective_coordinates_GFp,
+		ec_GFp_simple_point_set_affine_coordinates,
+		ec_GFp_simple_point_get_affine_coordinates,
+		ec_GFp_simple_set_compressed_coordinates,
+		ec_GFp_simple_point2oct,
+		ec_GFp_simple_oct2point,
+		ec_GFp_simple_add,
+		ec_GFp_simple_dbl,
+		ec_GFp_simple_invert,
+		ec_GFp_simple_is_at_infinity,
+		ec_GFp_simple_is_on_curve,
+		ec_GFp_simple_cmp,
+		ec_GFp_simple_make_affine,
+		ec_GFp_simple_points_make_affine,
+		0 /* mul */,
+		0 /* precompute_mult */,
+		0 /* have_precompute_mult */,	
+		ec_GFp_mont_field_mul,
+		ec_GFp_mont_field_sqr,
+		0 /* field_div */,
+		ec_GFp_mont_field_encode,
+		ec_GFp_mont_field_decode,
+		ec_GFp_mont_field_set_to_one };
+
+	return &ret;
+	}
+
+
+int ec_GFp_mont_group_init(EC_GROUP *group)
+	{
+	int ok;
+
+	ok = ec_GFp_simple_group_init(group);
+	group->field_data1 = NULL;
+	group->field_data2 = NULL;
+	return ok;
+	}
+
+
+void ec_GFp_mont_group_finish(EC_GROUP *group)
+	{
+	if (group->field_data1 != NULL)
+		{
+		BN_MONT_CTX_free(group->field_data1);
+		group->field_data1 = NULL;
+		}
+	if (group->field_data2 != NULL)
+		{
+		BN_free(group->field_data2);
+		group->field_data2 = NULL;
+		}
+	ec_GFp_simple_group_finish(group);
+	}
+
+
+void ec_GFp_mont_group_clear_finish(EC_GROUP *group)
+	{
+	if (group->field_data1 != NULL)
+		{
+		BN_MONT_CTX_free(group->field_data1);
+		group->field_data1 = NULL;
+		}
+	if (group->field_data2 != NULL)
+		{
+		BN_clear_free(group->field_data2);
+		group->field_data2 = NULL;
+		}
+	ec_GFp_simple_group_clear_finish(group);
+	}
+
+
+int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
+	{
+	if (dest->field_data1 != NULL)
+		{
+		BN_MONT_CTX_free(dest->field_data1);
+		dest->field_data1 = NULL;
+		}
+	if (dest->field_data2 != NULL)
+		{
+		BN_clear_free(dest->field_data2);
+		dest->field_data2 = NULL;
+		}
+
+	if (!ec_GFp_simple_group_copy(dest, src)) return 0;
+
+	if (src->field_data1 != NULL)
+		{
+		dest->field_data1 = BN_MONT_CTX_new();
+		if (dest->field_data1 == NULL) return 0;
+		if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1)) goto err;
+		}
+	if (src->field_data2 != NULL)
+		{
+		dest->field_data2 = BN_dup(src->field_data2);
+		if (dest->field_data2 == NULL) goto err;
+		}
+
+	return 1;
+
+ err:
+	if (dest->field_data1 != NULL)
+		{
+		BN_MONT_CTX_free(dest->field_data1);
+		dest->field_data1 = NULL;
+		}
+	return 0;	
+	}
+
+
+int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+	{
+	BN_CTX *new_ctx = NULL;
+	BN_MONT_CTX *mont = NULL;
+	BIGNUM *one = NULL;
+	int ret = 0;
+
+	if (group->field_data1 != NULL)
+		{
+		BN_MONT_CTX_free(group->field_data1);
+		group->field_data1 = NULL;
+		}
+	if (group->field_data2 != NULL)
+		{
+		BN_free(group->field_data2);
+		group->field_data2 = NULL;
+		}
+	
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+		}
+
+	mont = BN_MONT_CTX_new();
+	if (mont == NULL) goto err;
+	if (!BN_MONT_CTX_set(mont, p, ctx))
+		{
+		ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
+		goto err;
+		}
+	one = BN_new();
+	if (one == NULL) goto err;
+	if (!BN_to_montgomery(one, BN_value_one(), mont, ctx)) goto err;
+
+	group->field_data1 = mont;
+	mont = NULL;
+	group->field_data2 = one;
+	one = NULL;
+
+	ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+
+	if (!ret)
+		{
+		BN_MONT_CTX_free(group->field_data1);
+		group->field_data1 = NULL;
+		BN_free(group->field_data2);
+		group->field_data2 = NULL;
+		}
+
+ err:
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	if (mont != NULL)
+		BN_MONT_CTX_free(mont);
+	return ret;
+	}
+
+
+int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+	{
+	if (group->field_data1 == NULL)
+		{
+		ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED);
+		return 0;
+		}
+
+	return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx);
+	}
+
+
+int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
+	{
+	if (group->field_data1 == NULL)
+		{
+		ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED);
+		return 0;
+		}
+
+	return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
+	}
+
+
+int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
+	{
+	if (group->field_data1 == NULL)
+		{
+		ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED);
+		return 0;
+		}
+
+	return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx);
+	}
+
+
+int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
+	{
+	if (group->field_data1 == NULL)
+		{
+		ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED);
+		return 0;
+		}
+
+	return BN_from_montgomery(r, a, group->field_data1, ctx);
+	}
+
+
+int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, BN_CTX *ctx)
+	{
+	if (group->field_data2 == NULL)
+		{
+		ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED);
+		return 0;
+		}
+
+	if (!BN_copy(r, group->field_data2)) return 0;
+	return 1;
+	}
diff --git a/openssl/crypto/ec/ecp_nist.c b/openssl/crypto/ec/ecp_nist.c
new file mode 100644
index 0000000..2a5682e
--- /dev/null
+++ b/openssl/crypto/ec/ecp_nist.c
@@ -0,0 +1,210 @@
+/* crypto/ec/ecp_nist.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include <limits.h>
+
+#include <openssl/err.h>
+#include <openssl/obj_mac.h>
+#include "ec_lcl.h"
+
+const EC_METHOD *EC_GFp_nist_method(void)
+	{
+	static const EC_METHOD ret = {
+		NID_X9_62_prime_field,
+		ec_GFp_simple_group_init,
+		ec_GFp_simple_group_finish,
+		ec_GFp_simple_group_clear_finish,
+		ec_GFp_nist_group_copy,
+		ec_GFp_nist_group_set_curve,
+		ec_GFp_simple_group_get_curve,
+		ec_GFp_simple_group_get_degree,
+		ec_GFp_simple_group_check_discriminant,
+		ec_GFp_simple_point_init,
+		ec_GFp_simple_point_finish,
+		ec_GFp_simple_point_clear_finish,
+		ec_GFp_simple_point_copy,
+		ec_GFp_simple_point_set_to_infinity,
+		ec_GFp_simple_set_Jprojective_coordinates_GFp,
+		ec_GFp_simple_get_Jprojective_coordinates_GFp,
+		ec_GFp_simple_point_set_affine_coordinates,
+		ec_GFp_simple_point_get_affine_coordinates,
+		ec_GFp_simple_set_compressed_coordinates,
+		ec_GFp_simple_point2oct,
+		ec_GFp_simple_oct2point,
+		ec_GFp_simple_add,
+		ec_GFp_simple_dbl,
+		ec_GFp_simple_invert,
+		ec_GFp_simple_is_at_infinity,
+		ec_GFp_simple_is_on_curve,
+		ec_GFp_simple_cmp,
+		ec_GFp_simple_make_affine,
+		ec_GFp_simple_points_make_affine,
+		0 /* mul */,
+		0 /* precompute_mult */,
+		0 /* have_precompute_mult */,	
+		ec_GFp_nist_field_mul,
+		ec_GFp_nist_field_sqr,
+		0 /* field_div */,
+		0 /* field_encode */,
+		0 /* field_decode */,
+		0 /* field_set_to_one */ };
+
+	return &ret;
+	}
+
+int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
+	{
+	dest->field_mod_func = src->field_mod_func;
+
+	return ec_GFp_simple_group_copy(dest, src);
+	}
+
+int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+	const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+	{
+	int ret = 0;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *tmp_bn;
+	
+	if (ctx == NULL)
+		if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
+
+	BN_CTX_start(ctx);
+	if ((tmp_bn = BN_CTX_get(ctx)) == NULL) goto err;
+
+	if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
+		group->field_mod_func = BN_nist_mod_192;
+	else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
+		group->field_mod_func = BN_nist_mod_224;
+	else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
+		group->field_mod_func = BN_nist_mod_256;
+	else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
+		group->field_mod_func = BN_nist_mod_384;
+	else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
+		group->field_mod_func = BN_nist_mod_521;
+	else
+		{
+		ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME);
+		goto err;
+		}
+
+	ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+
+ err:
+	BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+	const BIGNUM *b, BN_CTX *ctx)
+	{
+	int	ret=0;
+	BN_CTX	*ctx_new=NULL;
+
+	if (!group || !r || !a || !b)
+		{
+		ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER);
+		goto err;
+		}
+	if (!ctx)
+		if ((ctx_new = ctx = BN_CTX_new()) == NULL) goto err;
+
+	if (!BN_mul(r, a, b, ctx)) goto err;
+	if (!group->field_mod_func(r, r, &group->field, ctx))
+		goto err;
+
+	ret=1;
+err:
+	if (ctx_new)
+		BN_CTX_free(ctx_new);
+	return ret;
+	}
+
+
+int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+	BN_CTX *ctx)
+	{
+	int	ret=0;
+	BN_CTX	*ctx_new=NULL;
+
+	if (!group || !r || !a)
+		{
+		ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER);
+		goto err;
+		}
+	if (!ctx)
+		if ((ctx_new = ctx = BN_CTX_new()) == NULL) goto err;
+
+	if (!BN_sqr(r, a, ctx)) goto err;
+	if (!group->field_mod_func(r, r, &group->field, ctx))
+		goto err;
+
+	ret=1;
+err:
+	if (ctx_new)
+		BN_CTX_free(ctx_new);
+	return ret;
+	}
diff --git a/openssl/crypto/ec/ecp_smpl.c b/openssl/crypto/ec/ecp_smpl.c
new file mode 100644
index 0000000..66a92e2
--- /dev/null
+++ b/openssl/crypto/ec/ecp_smpl.c
@@ -0,0 +1,1719 @@
+/* crypto/ec/ecp_smpl.c */
+/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
+ * for the OpenSSL project. 
+ * Includes code written by Bodo Moeller for the OpenSSL project.
+*/
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include <openssl/err.h>
+#include <openssl/symhacks.h>
+
+#include "ec_lcl.h"
+
+const EC_METHOD *EC_GFp_simple_method(void)
+	{
+	static const EC_METHOD ret = {
+		NID_X9_62_prime_field,
+		ec_GFp_simple_group_init,
+		ec_GFp_simple_group_finish,
+		ec_GFp_simple_group_clear_finish,
+		ec_GFp_simple_group_copy,
+		ec_GFp_simple_group_set_curve,
+		ec_GFp_simple_group_get_curve,
+		ec_GFp_simple_group_get_degree,
+		ec_GFp_simple_group_check_discriminant,
+		ec_GFp_simple_point_init,
+		ec_GFp_simple_point_finish,
+		ec_GFp_simple_point_clear_finish,
+		ec_GFp_simple_point_copy,
+		ec_GFp_simple_point_set_to_infinity,
+		ec_GFp_simple_set_Jprojective_coordinates_GFp,
+		ec_GFp_simple_get_Jprojective_coordinates_GFp,
+		ec_GFp_simple_point_set_affine_coordinates,
+		ec_GFp_simple_point_get_affine_coordinates,
+		ec_GFp_simple_set_compressed_coordinates,
+		ec_GFp_simple_point2oct,
+		ec_GFp_simple_oct2point,
+		ec_GFp_simple_add,
+		ec_GFp_simple_dbl,
+		ec_GFp_simple_invert,
+		ec_GFp_simple_is_at_infinity,
+		ec_GFp_simple_is_on_curve,
+		ec_GFp_simple_cmp,
+		ec_GFp_simple_make_affine,
+		ec_GFp_simple_points_make_affine,
+		0 /* mul */,
+		0 /* precompute_mult */,
+		0 /* have_precompute_mult */,	
+		ec_GFp_simple_field_mul,
+		ec_GFp_simple_field_sqr,
+		0 /* field_div */,
+		0 /* field_encode */,
+		0 /* field_decode */,
+		0 /* field_set_to_one */ };
+
+	return &ret;
+	}
+
+
+/* Most method functions in this file are designed to work with
+ * non-trivial representations of field elements if necessary
+ * (see ecp_mont.c): while standard modular addition and subtraction
+ * are used, the field_mul and field_sqr methods will be used for
+ * multiplication, and field_encode and field_decode (if defined)
+ * will be used for converting between representations.
+
+ * Functions ec_GFp_simple_points_make_affine() and
+ * ec_GFp_simple_point_get_affine_coordinates() specifically assume
+ * that if a non-trivial representation is used, it is a Montgomery
+ * representation (i.e. 'encoding' means multiplying by some factor R).
+ */
+
+
+int ec_GFp_simple_group_init(EC_GROUP *group)
+	{
+	BN_init(&group->field);
+	BN_init(&group->a);
+	BN_init(&group->b);
+	group->a_is_minus3 = 0;
+	return 1;
+	}
+
+
+void ec_GFp_simple_group_finish(EC_GROUP *group)
+	{
+	BN_free(&group->field);
+	BN_free(&group->a);
+	BN_free(&group->b);
+	}
+
+
+void ec_GFp_simple_group_clear_finish(EC_GROUP *group)
+	{
+	BN_clear_free(&group->field);
+	BN_clear_free(&group->a);
+	BN_clear_free(&group->b);
+	}
+
+
+int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
+	{
+	if (!BN_copy(&dest->field, &src->field)) return 0;
+	if (!BN_copy(&dest->a, &src->a)) return 0;
+	if (!BN_copy(&dest->b, &src->b)) return 0;
+
+	dest->a_is_minus3 = src->a_is_minus3;
+
+	return 1;
+	}
+
+
+int ec_GFp_simple_group_set_curve(EC_GROUP *group,
+	const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+	{
+	int ret = 0;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *tmp_a;
+	
+	/* p must be a prime > 3 */
+	if (BN_num_bits(p) <= 2 || !BN_is_odd(p))
+		{
+		ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD);
+		return 0;
+		}
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+		}
+
+	BN_CTX_start(ctx);
+	tmp_a = BN_CTX_get(ctx);
+	if (tmp_a == NULL) goto err;
+
+	/* group->field */
+	if (!BN_copy(&group->field, p)) goto err;
+	BN_set_negative(&group->field, 0);
+
+	/* group->a */
+	if (!BN_nnmod(tmp_a, a, p, ctx)) goto err;
+	if (group->meth->field_encode)
+		{ if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) goto err; }	
+	else
+		if (!BN_copy(&group->a, tmp_a)) goto err;
+	
+	/* group->b */
+	if (!BN_nnmod(&group->b, b, p, ctx)) goto err;
+	if (group->meth->field_encode)
+		if (!group->meth->field_encode(group, &group->b, &group->b, ctx)) goto err;
+	
+	/* group->a_is_minus3 */
+	if (!BN_add_word(tmp_a, 3)) goto err;
+	group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field));
+
+	ret = 1;
+
+ err:
+	BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+	{
+	int ret = 0;
+	BN_CTX *new_ctx = NULL;
+	
+	if (p != NULL)
+		{
+		if (!BN_copy(p, &group->field)) return 0;
+		}
+
+	if (a != NULL || b != NULL)
+		{
+		if (group->meth->field_decode)
+			{
+			if (ctx == NULL)
+				{
+				ctx = new_ctx = BN_CTX_new();
+				if (ctx == NULL)
+					return 0;
+				}
+			if (a != NULL)
+				{
+				if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err;
+				}
+			if (b != NULL)
+				{
+				if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err;
+				}
+			}
+		else
+			{
+			if (a != NULL)
+				{
+				if (!BN_copy(a, &group->a)) goto err;
+				}
+			if (b != NULL)
+				{
+				if (!BN_copy(b, &group->b)) goto err;
+				}
+			}
+		}
+	
+	ret = 1;
+	
+ err:
+	if (new_ctx)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+int ec_GFp_simple_group_get_degree(const EC_GROUP *group)
+	{
+	return BN_num_bits(&group->field);
+	}
+
+
+int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
+	{
+	int ret = 0;
+	BIGNUM *a,*b,*order,*tmp_1,*tmp_2;
+	const BIGNUM *p = &group->field;
+	BN_CTX *new_ctx = NULL;
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			{
+			ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+	BN_CTX_start(ctx);
+	a = BN_CTX_get(ctx);
+	b = BN_CTX_get(ctx);
+	tmp_1 = BN_CTX_get(ctx);
+	tmp_2 = BN_CTX_get(ctx);
+	order = BN_CTX_get(ctx);
+	if (order == NULL) goto err;
+
+	if (group->meth->field_decode)
+		{
+		if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err;
+		if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err;
+		}
+	else
+		{
+		if (!BN_copy(a, &group->a)) goto err;
+		if (!BN_copy(b, &group->b)) goto err;
+		}
+	
+	/* check the discriminant:
+	 * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p) 
+         * 0 =< a, b < p */
+	if (BN_is_zero(a))
+		{
+		if (BN_is_zero(b)) goto err;
+		}
+	else if (!BN_is_zero(b))
+		{
+		if (!BN_mod_sqr(tmp_1, a, p, ctx)) goto err;
+		if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx)) goto err;
+		if (!BN_lshift(tmp_1, tmp_2, 2)) goto err;
+		/* tmp_1 = 4*a^3 */
+
+		if (!BN_mod_sqr(tmp_2, b, p, ctx)) goto err;
+		if (!BN_mul_word(tmp_2, 27)) goto err;
+		/* tmp_2 = 27*b^2 */
+
+		if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx)) goto err;
+		if (BN_is_zero(a)) goto err;
+		}
+	ret = 1;
+
+err:
+	if (ctx != NULL)
+		BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+int ec_GFp_simple_point_init(EC_POINT *point)
+	{
+	BN_init(&point->X);
+	BN_init(&point->Y);
+	BN_init(&point->Z);
+	point->Z_is_one = 0;
+
+	return 1;
+	}
+
+
+void ec_GFp_simple_point_finish(EC_POINT *point)
+	{
+	BN_free(&point->X);
+	BN_free(&point->Y);
+	BN_free(&point->Z);
+	}
+
+
+void ec_GFp_simple_point_clear_finish(EC_POINT *point)
+	{
+	BN_clear_free(&point->X);
+	BN_clear_free(&point->Y);
+	BN_clear_free(&point->Z);
+	point->Z_is_one = 0;
+	}
+
+
+int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
+	{
+	if (!BN_copy(&dest->X, &src->X)) return 0;
+	if (!BN_copy(&dest->Y, &src->Y)) return 0;
+	if (!BN_copy(&dest->Z, &src->Z)) return 0;
+	dest->Z_is_one = src->Z_is_one;
+
+	return 1;
+	}
+
+
+int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
+	{
+	point->Z_is_one = 0;
+	BN_zero(&point->Z);
+	return 1;
+	}
+
+
+int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
+	const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
+	{
+	BN_CTX *new_ctx = NULL;
+	int ret = 0;
+	
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+		}
+
+	if (x != NULL)
+		{
+		if (!BN_nnmod(&point->X, x, &group->field, ctx)) goto err;
+		if (group->meth->field_encode)
+			{
+			if (!group->meth->field_encode(group, &point->X, &point->X, ctx)) goto err;
+			}
+		}
+	
+	if (y != NULL)
+		{
+		if (!BN_nnmod(&point->Y, y, &group->field, ctx)) goto err;
+		if (group->meth->field_encode)
+			{
+			if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx)) goto err;
+			}
+		}
+	
+	if (z != NULL)
+		{
+		int Z_is_one;
+
+		if (!BN_nnmod(&point->Z, z, &group->field, ctx)) goto err;
+		Z_is_one = BN_is_one(&point->Z);
+		if (group->meth->field_encode)
+			{
+			if (Z_is_one && (group->meth->field_set_to_one != 0))
+				{
+				if (!group->meth->field_set_to_one(group, &point->Z, ctx)) goto err;
+				}
+			else
+				{
+				if (!group->meth->field_encode(group, &point->Z, &point->Z, ctx)) goto err;
+				}
+			}
+		point->Z_is_one = Z_is_one;
+		}
+	
+	ret = 1;
+	
+ err:
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
+	BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
+	{
+	BN_CTX *new_ctx = NULL;
+	int ret = 0;
+	
+	if (group->meth->field_decode != 0)
+		{
+		if (ctx == NULL)
+			{
+			ctx = new_ctx = BN_CTX_new();
+			if (ctx == NULL)
+				return 0;
+			}
+
+		if (x != NULL)
+			{
+			if (!group->meth->field_decode(group, x, &point->X, ctx)) goto err;
+			}
+		if (y != NULL)
+			{
+			if (!group->meth->field_decode(group, y, &point->Y, ctx)) goto err;
+			}
+		if (z != NULL)
+			{
+			if (!group->meth->field_decode(group, z, &point->Z, ctx)) goto err;
+			}
+		}
+	else	
+		{
+		if (x != NULL)
+			{
+			if (!BN_copy(x, &point->X)) goto err;
+			}
+		if (y != NULL)
+			{
+			if (!BN_copy(y, &point->Y)) goto err;
+			}
+		if (z != NULL)
+			{
+			if (!BN_copy(z, &point->Z)) goto err;
+			}
+		}
+	
+	ret = 1;
+
+ err:
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
+	{
+	if (x == NULL || y == NULL)
+		{
+		/* unlike for projective coordinates, we do not tolerate this */
+		ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+
+	return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y, BN_value_one(), ctx);
+	}
+
+
+int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
+	BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
+	{
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *Z, *Z_1, *Z_2, *Z_3;
+	const BIGNUM *Z_;
+	int ret = 0;
+
+	if (EC_POINT_is_at_infinity(group, point))
+		{
+		ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
+		return 0;
+		}
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+		}
+
+	BN_CTX_start(ctx);
+	Z = BN_CTX_get(ctx);
+	Z_1 = BN_CTX_get(ctx);
+	Z_2 = BN_CTX_get(ctx);
+	Z_3 = BN_CTX_get(ctx);
+	if (Z_3 == NULL) goto err;
+
+	/* transform  (X, Y, Z)  into  (x, y) := (X/Z^2, Y/Z^3) */
+	
+	if (group->meth->field_decode)
+		{
+		if (!group->meth->field_decode(group, Z, &point->Z, ctx)) goto err;
+		Z_ = Z;
+		}
+	else
+		{
+		Z_ = &point->Z;
+		}
+	
+	if (BN_is_one(Z_))
+		{
+		if (group->meth->field_decode)
+			{
+			if (x != NULL)
+				{
+				if (!group->meth->field_decode(group, x, &point->X, ctx)) goto err;
+				}
+			if (y != NULL)
+				{
+				if (!group->meth->field_decode(group, y, &point->Y, ctx)) goto err;
+				}
+			}
+		else
+			{
+			if (x != NULL)
+				{
+				if (!BN_copy(x, &point->X)) goto err;
+				}
+			if (y != NULL)
+				{
+				if (!BN_copy(y, &point->Y)) goto err;
+				}
+			}
+		}
+	else
+		{
+		if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx))
+			{
+			ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB);
+			goto err;
+			}
+		
+		if (group->meth->field_encode == 0)
+			{
+			/* field_sqr works on standard representation */
+			if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) goto err;
+			}
+		else
+			{
+			if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) goto err;
+			}
+	
+		if (x != NULL)
+			{
+			/* in the Montgomery case, field_mul will cancel out Montgomery factor in X: */
+			if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx)) goto err;
+			}
+
+		if (y != NULL)
+			{
+			if (group->meth->field_encode == 0)
+				{
+				/* field_mul works on standard representation */
+				if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) goto err;
+				}
+			else
+				{
+				if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) goto err;
+				}
+
+			/* in the Montgomery case, field_mul will cancel out Montgomery factor in Y: */
+			if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) goto err;
+			}
+		}
+
+	ret = 1;
+
+ err:
+	BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
+	const BIGNUM *x_, int y_bit, BN_CTX *ctx)
+	{
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *tmp1, *tmp2, *x, *y;
+	int ret = 0;
+
+	/* clear error queue*/
+	ERR_clear_error();
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+		}
+
+	y_bit = (y_bit != 0);
+
+	BN_CTX_start(ctx);
+	tmp1 = BN_CTX_get(ctx);
+	tmp2 = BN_CTX_get(ctx);
+	x = BN_CTX_get(ctx);
+	y = BN_CTX_get(ctx);
+	if (y == NULL) goto err;
+
+	/* Recover y.  We have a Weierstrass equation
+	 *     y^2 = x^3 + a*x + b,
+	 * so  y  is one of the square roots of  x^3 + a*x + b.
+	 */
+
+	/* tmp1 := x^3 */
+	if (!BN_nnmod(x, x_, &group->field,ctx)) goto err;
+	if (group->meth->field_decode == 0)
+		{
+		/* field_{sqr,mul} work on standard representation */
+		if (!group->meth->field_sqr(group, tmp2, x_, ctx)) goto err;
+		if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) goto err;
+		}
+	else
+		{
+		if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) goto err;
+		if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) goto err;
+		}
+	
+	/* tmp1 := tmp1 + a*x */
+	if (group->a_is_minus3)
+		{
+		if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) goto err;
+		if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) goto err;
+		if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
+		}
+	else
+		{
+		if (group->meth->field_decode)
+			{
+			if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) goto err;
+			if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) goto err;
+			}
+		else
+			{
+			/* field_mul works on standard representation */
+			if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) goto err;
+			}
+		
+		if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
+		}
+	
+	/* tmp1 := tmp1 + b */
+	if (group->meth->field_decode)
+		{
+		if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) goto err;
+		if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
+		}
+	else
+		{
+		if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) goto err;
+		}
+	
+	if (!BN_mod_sqrt(y, tmp1, &group->field, ctx))
+		{
+		unsigned long err = ERR_peek_last_error();
+		
+		if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE)
+			{
+			ERR_clear_error();
+			ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
+			}
+		else
+			ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
+		goto err;
+		}
+
+	if (y_bit != BN_is_odd(y))
+		{
+		if (BN_is_zero(y))
+			{
+			int kron;
+
+			kron = BN_kronecker(x, &group->field, ctx);
+			if (kron == -2) goto err;
+
+			if (kron == 1)
+				ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSION_BIT);
+			else
+				/* BN_mod_sqrt() should have cought this error (not a square) */
+				ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
+			goto err;
+			}
+		if (!BN_usub(y, &group->field, y)) goto err;
+		}
+	if (y_bit != BN_is_odd(y))
+		{
+		ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_INTERNAL_ERROR);
+		goto err;
+		}
+
+	if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
+
+	ret = 1;
+
+ err:
+	BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
+	unsigned char *buf, size_t len, BN_CTX *ctx)
+	{
+	size_t ret;
+	BN_CTX *new_ctx = NULL;
+	int used_ctx = 0;
+	BIGNUM *x, *y;
+	size_t field_len, i, skip;
+
+	if ((form != POINT_CONVERSION_COMPRESSED)
+		&& (form != POINT_CONVERSION_UNCOMPRESSED)
+		&& (form != POINT_CONVERSION_HYBRID))
+		{
+		ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
+		goto err;
+		}
+
+	if (EC_POINT_is_at_infinity(group, point))
+		{
+		/* encodes to a single 0 octet */
+		if (buf != NULL)
+			{
+			if (len < 1)
+				{
+				ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+				return 0;
+				}
+			buf[0] = 0;
+			}
+		return 1;
+		}
+
+
+	/* ret := required output buffer length */
+	field_len = BN_num_bytes(&group->field);
+	ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
+
+	/* if 'buf' is NULL, just return required length */
+	if (buf != NULL)
+		{
+		if (len < ret)
+			{
+			ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+			goto err;
+			}
+
+		if (ctx == NULL)
+			{
+			ctx = new_ctx = BN_CTX_new();
+			if (ctx == NULL)
+				return 0;
+			}
+
+		BN_CTX_start(ctx);
+		used_ctx = 1;
+		x = BN_CTX_get(ctx);
+		y = BN_CTX_get(ctx);
+		if (y == NULL) goto err;
+
+		if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
+
+		if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
+			buf[0] = form + 1;
+		else
+			buf[0] = form;
+	
+		i = 1;
+		
+		skip = field_len - BN_num_bytes(x);
+		if (skip > field_len)
+			{
+			ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+		while (skip > 0)
+			{
+			buf[i++] = 0;
+			skip--;
+			}
+		skip = BN_bn2bin(x, buf + i);
+		i += skip;
+		if (i != 1 + field_len)
+			{
+			ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+
+		if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
+			{
+			skip = field_len - BN_num_bytes(y);
+			if (skip > field_len)
+				{
+				ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+			while (skip > 0)
+				{
+				buf[i++] = 0;
+				skip--;
+				}
+			skip = BN_bn2bin(y, buf + i);
+			i += skip;
+			}
+
+		if (i != ret)
+			{
+			ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+		}
+	
+	if (used_ctx)
+		BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+
+ err:
+	if (used_ctx)
+		BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return 0;
+	}
+
+
+int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
+	const unsigned char *buf, size_t len, BN_CTX *ctx)
+	{
+	point_conversion_form_t form;
+	int y_bit;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *x, *y;
+	size_t field_len, enc_len;
+	int ret = 0;
+
+	if (len == 0)
+		{
+		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
+		return 0;
+		}
+	form = buf[0];
+	y_bit = form & 1;
+	form = form & ~1U;
+	if ((form != 0)	&& (form != POINT_CONVERSION_COMPRESSED)
+		&& (form != POINT_CONVERSION_UNCOMPRESSED)
+		&& (form != POINT_CONVERSION_HYBRID))
+		{
+		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+		return 0;
+		}
+	if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
+		{
+		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+		return 0;
+		}
+
+	if (form == 0)
+		{
+		if (len != 1)
+			{
+			ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+			return 0;
+			}
+
+		return EC_POINT_set_to_infinity(group, point);
+		}
+	
+	field_len = BN_num_bytes(&group->field);
+	enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
+
+	if (len != enc_len)
+		{
+		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+		return 0;
+		}
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+		}
+
+	BN_CTX_start(ctx);
+	x = BN_CTX_get(ctx);
+	y = BN_CTX_get(ctx);
+	if (y == NULL) goto err;
+
+	if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
+	if (BN_ucmp(x, &group->field) >= 0)
+		{
+		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+		goto err;
+		}
+
+	if (form == POINT_CONVERSION_COMPRESSED)
+		{
+		if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx)) goto err;
+		}
+	else
+		{
+		if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
+		if (BN_ucmp(y, &group->field) >= 0)
+			{
+			ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+			goto err;
+			}
+		if (form == POINT_CONVERSION_HYBRID)
+			{
+			if (y_bit != BN_is_odd(y))
+				{
+				ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+				goto err;
+				}
+			}
+
+		if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
+		}
+	
+	if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
+		{
+		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
+		goto err;
+		}
+
+	ret = 1;
+	
+ err:
+	BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
+	{
+	int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
+	int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+	const BIGNUM *p;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
+	int ret = 0;
+	
+	if (a == b)
+		return EC_POINT_dbl(group, r, a, ctx);
+	if (EC_POINT_is_at_infinity(group, a))
+		return EC_POINT_copy(r, b);
+	if (EC_POINT_is_at_infinity(group, b))
+		return EC_POINT_copy(r, a);
+	
+	field_mul = group->meth->field_mul;
+	field_sqr = group->meth->field_sqr;
+	p = &group->field;
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+		}
+
+	BN_CTX_start(ctx);
+	n0 = BN_CTX_get(ctx);
+	n1 = BN_CTX_get(ctx);
+	n2 = BN_CTX_get(ctx);
+	n3 = BN_CTX_get(ctx);
+	n4 = BN_CTX_get(ctx);
+	n5 = BN_CTX_get(ctx);
+	n6 = BN_CTX_get(ctx);
+	if (n6 == NULL) goto end;
+
+	/* Note that in this function we must not read components of 'a' or 'b'
+	 * once we have written the corresponding components of 'r'.
+	 * ('r' might be one of 'a' or 'b'.)
+	 */
+
+	/* n1, n2 */
+	if (b->Z_is_one)
+		{
+		if (!BN_copy(n1, &a->X)) goto end;
+		if (!BN_copy(n2, &a->Y)) goto end;
+		/* n1 = X_a */
+		/* n2 = Y_a */
+		}
+	else
+		{
+		if (!field_sqr(group, n0, &b->Z, ctx)) goto end;
+		if (!field_mul(group, n1, &a->X, n0, ctx)) goto end;
+		/* n1 = X_a * Z_b^2 */
+
+		if (!field_mul(group, n0, n0, &b->Z, ctx)) goto end;
+		if (!field_mul(group, n2, &a->Y, n0, ctx)) goto end;
+		/* n2 = Y_a * Z_b^3 */
+		}
+
+	/* n3, n4 */
+	if (a->Z_is_one)
+		{
+		if (!BN_copy(n3, &b->X)) goto end;
+		if (!BN_copy(n4, &b->Y)) goto end;
+		/* n3 = X_b */
+		/* n4 = Y_b */
+		}
+	else
+		{
+		if (!field_sqr(group, n0, &a->Z, ctx)) goto end;
+		if (!field_mul(group, n3, &b->X, n0, ctx)) goto end;
+		/* n3 = X_b * Z_a^2 */
+
+		if (!field_mul(group, n0, n0, &a->Z, ctx)) goto end;
+		if (!field_mul(group, n4, &b->Y, n0, ctx)) goto end;
+		/* n4 = Y_b * Z_a^3 */
+		}
+
+	/* n5, n6 */
+	if (!BN_mod_sub_quick(n5, n1, n3, p)) goto end;
+	if (!BN_mod_sub_quick(n6, n2, n4, p)) goto end;
+	/* n5 = n1 - n3 */
+	/* n6 = n2 - n4 */
+
+	if (BN_is_zero(n5))
+		{
+		if (BN_is_zero(n6))
+			{
+			/* a is the same point as b */
+			BN_CTX_end(ctx);
+			ret = EC_POINT_dbl(group, r, a, ctx);
+			ctx = NULL;
+			goto end;
+			}
+		else
+			{
+			/* a is the inverse of b */
+			BN_zero(&r->Z);
+			r->Z_is_one = 0;
+			ret = 1;
+			goto end;
+			}
+		}
+
+	/* 'n7', 'n8' */
+	if (!BN_mod_add_quick(n1, n1, n3, p)) goto end;
+	if (!BN_mod_add_quick(n2, n2, n4, p)) goto end;
+	/* 'n7' = n1 + n3 */
+	/* 'n8' = n2 + n4 */
+
+	/* Z_r */
+	if (a->Z_is_one && b->Z_is_one)
+		{
+		if (!BN_copy(&r->Z, n5)) goto end;
+		}
+	else
+		{
+		if (a->Z_is_one)
+			{ if (!BN_copy(n0, &b->Z)) goto end; }
+		else if (b->Z_is_one)
+			{ if (!BN_copy(n0, &a->Z)) goto end; }
+		else
+			{ if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) goto end; }
+		if (!field_mul(group, &r->Z, n0, n5, ctx)) goto end;
+		}
+	r->Z_is_one = 0;
+	/* Z_r = Z_a * Z_b * n5 */
+
+	/* X_r */
+	if (!field_sqr(group, n0, n6, ctx)) goto end;
+	if (!field_sqr(group, n4, n5, ctx)) goto end;
+	if (!field_mul(group, n3, n1, n4, ctx)) goto end;
+	if (!BN_mod_sub_quick(&r->X, n0, n3, p)) goto end;
+	/* X_r = n6^2 - n5^2 * 'n7' */
+	
+	/* 'n9' */
+	if (!BN_mod_lshift1_quick(n0, &r->X, p)) goto end;
+	if (!BN_mod_sub_quick(n0, n3, n0, p)) goto end;
+	/* n9 = n5^2 * 'n7' - 2 * X_r */
+
+	/* Y_r */
+	if (!field_mul(group, n0, n0, n6, ctx)) goto end;
+	if (!field_mul(group, n5, n4, n5, ctx)) goto end; /* now n5 is n5^3 */
+	if (!field_mul(group, n1, n2, n5, ctx)) goto end;
+	if (!BN_mod_sub_quick(n0, n0, n1, p)) goto end;
+	if (BN_is_odd(n0))
+		if (!BN_add(n0, n0, p)) goto end;
+	/* now  0 <= n0 < 2*p,  and n0 is even */
+	if (!BN_rshift1(&r->Y, n0)) goto end;
+	/* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
+
+	ret = 1;
+
+ end:
+	if (ctx) /* otherwise we already called BN_CTX_end */
+		BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
+	{
+	int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
+	int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+	const BIGNUM *p;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *n0, *n1, *n2, *n3;
+	int ret = 0;
+	
+	if (EC_POINT_is_at_infinity(group, a))
+		{
+		BN_zero(&r->Z);
+		r->Z_is_one = 0;
+		return 1;
+		}
+
+	field_mul = group->meth->field_mul;
+	field_sqr = group->meth->field_sqr;
+	p = &group->field;
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+		}
+
+	BN_CTX_start(ctx);
+	n0 = BN_CTX_get(ctx);
+	n1 = BN_CTX_get(ctx);
+	n2 = BN_CTX_get(ctx);
+	n3 = BN_CTX_get(ctx);
+	if (n3 == NULL) goto err;
+
+	/* Note that in this function we must not read components of 'a'
+	 * once we have written the corresponding components of 'r'.
+	 * ('r' might the same as 'a'.)
+	 */
+
+	/* n1 */
+	if (a->Z_is_one)
+		{
+		if (!field_sqr(group, n0, &a->X, ctx)) goto err;
+		if (!BN_mod_lshift1_quick(n1, n0, p)) goto err;
+		if (!BN_mod_add_quick(n0, n0, n1, p)) goto err;
+		if (!BN_mod_add_quick(n1, n0, &group->a, p)) goto err;
+		/* n1 = 3 * X_a^2 + a_curve */
+		}
+	else if (group->a_is_minus3)
+		{
+		if (!field_sqr(group, n1, &a->Z, ctx)) goto err;
+		if (!BN_mod_add_quick(n0, &a->X, n1, p)) goto err;
+		if (!BN_mod_sub_quick(n2, &a->X, n1, p)) goto err;
+		if (!field_mul(group, n1, n0, n2, ctx)) goto err;
+		if (!BN_mod_lshift1_quick(n0, n1, p)) goto err;
+		if (!BN_mod_add_quick(n1, n0, n1, p)) goto err;
+		/* n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)
+		 *    = 3 * X_a^2 - 3 * Z_a^4 */
+		}
+	else
+		{
+		if (!field_sqr(group, n0, &a->X, ctx)) goto err;
+		if (!BN_mod_lshift1_quick(n1, n0, p)) goto err;
+		if (!BN_mod_add_quick(n0, n0, n1, p)) goto err;
+		if (!field_sqr(group, n1, &a->Z, ctx)) goto err;
+		if (!field_sqr(group, n1, n1, ctx)) goto err;
+		if (!field_mul(group, n1, n1, &group->a, ctx)) goto err;
+		if (!BN_mod_add_quick(n1, n1, n0, p)) goto err;
+		/* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
+		}
+
+	/* Z_r */
+	if (a->Z_is_one)
+		{
+		if (!BN_copy(n0, &a->Y)) goto err;
+		}
+	else
+		{
+		if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) goto err;
+		}
+	if (!BN_mod_lshift1_quick(&r->Z, n0, p)) goto err;
+	r->Z_is_one = 0;
+	/* Z_r = 2 * Y_a * Z_a */
+
+	/* n2 */
+	if (!field_sqr(group, n3, &a->Y, ctx)) goto err;
+	if (!field_mul(group, n2, &a->X, n3, ctx)) goto err;
+	if (!BN_mod_lshift_quick(n2, n2, 2, p)) goto err;
+	/* n2 = 4 * X_a * Y_a^2 */
+
+	/* X_r */
+	if (!BN_mod_lshift1_quick(n0, n2, p)) goto err;
+	if (!field_sqr(group, &r->X, n1, ctx)) goto err;
+	if (!BN_mod_sub_quick(&r->X, &r->X, n0, p)) goto err;
+	/* X_r = n1^2 - 2 * n2 */
+	
+	/* n3 */
+	if (!field_sqr(group, n0, n3, ctx)) goto err;
+	if (!BN_mod_lshift_quick(n3, n0, 3, p)) goto err;
+	/* n3 = 8 * Y_a^4 */
+	
+	/* Y_r */
+	if (!BN_mod_sub_quick(n0, n2, &r->X, p)) goto err;
+	if (!field_mul(group, n0, n1, n0, ctx)) goto err;
+	if (!BN_mod_sub_quick(&r->Y, n0, n3, p)) goto err;
+	/* Y_r = n1 * (n2 - X_r) - n3 */
+
+	ret = 1;
+
+ err:
+	BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
+	{
+	if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))
+		/* point is its own inverse */
+		return 1;
+	
+	return BN_usub(&point->Y, &group->field, &point->Y);
+	}
+
+
+int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
+	{
+	return BN_is_zero(&point->Z);
+	}
+
+
+int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
+	{
+	int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
+	int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+	const BIGNUM *p;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *rh, *tmp, *Z4, *Z6;
+	int ret = -1;
+
+	if (EC_POINT_is_at_infinity(group, point))
+		return 1;
+	
+	field_mul = group->meth->field_mul;
+	field_sqr = group->meth->field_sqr;
+	p = &group->field;
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return -1;
+		}
+
+	BN_CTX_start(ctx);
+	rh = BN_CTX_get(ctx);
+	tmp = BN_CTX_get(ctx);
+	Z4 = BN_CTX_get(ctx);
+	Z6 = BN_CTX_get(ctx);
+	if (Z6 == NULL) goto err;
+
+	/* We have a curve defined by a Weierstrass equation
+	 *      y^2 = x^3 + a*x + b.
+	 * The point to consider is given in Jacobian projective coordinates
+	 * where  (X, Y, Z)  represents  (x, y) = (X/Z^2, Y/Z^3).
+	 * Substituting this and multiplying by  Z^6  transforms the above equation into
+	 *      Y^2 = X^3 + a*X*Z^4 + b*Z^6.
+	 * To test this, we add up the right-hand side in 'rh'.
+	 */
+
+	/* rh := X^2 */
+	if (!field_sqr(group, rh, &point->X, ctx)) goto err;
+
+	if (!point->Z_is_one)
+		{
+		if (!field_sqr(group, tmp, &point->Z, ctx)) goto err;
+		if (!field_sqr(group, Z4, tmp, ctx)) goto err;
+		if (!field_mul(group, Z6, Z4, tmp, ctx)) goto err;
+
+		/* rh := (rh + a*Z^4)*X */
+		if (group->a_is_minus3)
+			{
+			if (!BN_mod_lshift1_quick(tmp, Z4, p)) goto err;
+			if (!BN_mod_add_quick(tmp, tmp, Z4, p)) goto err;
+			if (!BN_mod_sub_quick(rh, rh, tmp, p)) goto err;
+			if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
+			}
+		else
+			{
+			if (!field_mul(group, tmp, Z4, &group->a, ctx)) goto err;
+			if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
+			if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
+			}
+
+		/* rh := rh + b*Z^6 */
+		if (!field_mul(group, tmp, &group->b, Z6, ctx)) goto err;
+		if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
+		}
+	else
+		{
+		/* point->Z_is_one */
+
+		/* rh := (rh + a)*X */
+		if (!BN_mod_add_quick(rh, rh, &group->a, p)) goto err;
+		if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
+		/* rh := rh + b */
+		if (!BN_mod_add_quick(rh, rh, &group->b, p)) goto err;
+		}
+
+	/* 'lh' := Y^2 */
+	if (!field_sqr(group, tmp, &point->Y, ctx)) goto err;
+
+	ret = (0 == BN_ucmp(tmp, rh));
+
+ err:
+	BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
+	{
+	/* return values:
+	 *  -1   error
+	 *   0   equal (in affine coordinates)
+	 *   1   not equal
+	 */
+
+	int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
+	int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
+	const BIGNUM *tmp1_, *tmp2_;
+	int ret = -1;
+	
+	if (EC_POINT_is_at_infinity(group, a))
+		{
+		return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
+		}
+
+	if (EC_POINT_is_at_infinity(group, b))
+		return 1;
+	
+	if (a->Z_is_one && b->Z_is_one)
+		{
+		return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
+		}
+
+	field_mul = group->meth->field_mul;
+	field_sqr = group->meth->field_sqr;
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return -1;
+		}
+
+	BN_CTX_start(ctx);
+	tmp1 = BN_CTX_get(ctx);
+	tmp2 = BN_CTX_get(ctx);
+	Za23 = BN_CTX_get(ctx);
+	Zb23 = BN_CTX_get(ctx);
+	if (Zb23 == NULL) goto end;
+
+	/* We have to decide whether
+	 *     (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
+	 * or equivalently, whether
+	 *     (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
+	 */
+
+	if (!b->Z_is_one)
+		{
+		if (!field_sqr(group, Zb23, &b->Z, ctx)) goto end;
+		if (!field_mul(group, tmp1, &a->X, Zb23, ctx)) goto end;
+		tmp1_ = tmp1;
+		}
+	else
+		tmp1_ = &a->X;
+	if (!a->Z_is_one)
+		{
+		if (!field_sqr(group, Za23, &a->Z, ctx)) goto end;
+		if (!field_mul(group, tmp2, &b->X, Za23, ctx)) goto end;
+		tmp2_ = tmp2;
+		}
+	else
+		tmp2_ = &b->X;
+	
+	/* compare  X_a*Z_b^2  with  X_b*Z_a^2 */
+	if (BN_cmp(tmp1_, tmp2_) != 0)
+		{
+		ret = 1; /* points differ */
+		goto end;
+		}
+
+
+	if (!b->Z_is_one)
+		{
+		if (!field_mul(group, Zb23, Zb23, &b->Z, ctx)) goto end;
+		if (!field_mul(group, tmp1, &a->Y, Zb23, ctx)) goto end;
+		/* tmp1_ = tmp1 */
+		}
+	else
+		tmp1_ = &a->Y;
+	if (!a->Z_is_one)
+		{
+		if (!field_mul(group, Za23, Za23, &a->Z, ctx)) goto end;
+		if (!field_mul(group, tmp2, &b->Y, Za23, ctx)) goto end;
+		/* tmp2_ = tmp2 */
+		}
+	else
+		tmp2_ = &b->Y;
+
+	/* compare  Y_a*Z_b^3  with  Y_b*Z_a^3 */
+	if (BN_cmp(tmp1_, tmp2_) != 0)
+		{
+		ret = 1; /* points differ */
+		goto end;
+		}
+
+	/* points are equal */
+	ret = 0;
+
+ end:
+	BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
+	{
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *x, *y;
+	int ret = 0;
+
+	if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
+		return 1;
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+		}
+
+	BN_CTX_start(ctx);
+	x = BN_CTX_get(ctx);
+	y = BN_CTX_get(ctx);
+	if (y == NULL) goto err;
+
+	if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
+	if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
+	if (!point->Z_is_one)
+		{
+		ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR);
+		goto err;
+		}
+	
+	ret = 1;
+
+ err:
+	BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
+
+
+int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
+	{
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *tmp0, *tmp1;
+	size_t pow2 = 0;
+	BIGNUM **heap = NULL;
+	size_t i;
+	int ret = 0;
+
+	if (num == 0)
+		return 1;
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+		}
+
+	BN_CTX_start(ctx);
+	tmp0 = BN_CTX_get(ctx);
+	tmp1 = BN_CTX_get(ctx);
+	if (tmp0  == NULL || tmp1 == NULL) goto err;
+
+	/* Before converting the individual points, compute inverses of all Z values.
+	 * Modular inversion is rather slow, but luckily we can do with a single
+	 * explicit inversion, plus about 3 multiplications per input value.
+	 */
+
+	pow2 = 1;
+	while (num > pow2)
+		pow2 <<= 1;
+	/* Now pow2 is the smallest power of 2 satifsying pow2 >= num.
+	 * We need twice that. */
+	pow2 <<= 1;
+
+	heap = OPENSSL_malloc(pow2 * sizeof heap[0]);
+	if (heap == NULL) goto err;
+	
+	/* The array is used as a binary tree, exactly as in heapsort:
+	 *
+	 *                               heap[1]
+	 *                 heap[2]                     heap[3]
+	 *          heap[4]       heap[5]       heap[6]       heap[7]
+	 *   heap[8]heap[9] heap[10]heap[11] heap[12]heap[13] heap[14] heap[15]
+	 *
+	 * We put the Z's in the last line;
+	 * then we set each other node to the product of its two child-nodes (where
+	 * empty or 0 entries are treated as ones);
+	 * then we invert heap[1];
+	 * then we invert each other node by replacing it by the product of its
+	 * parent (after inversion) and its sibling (before inversion).
+	 */
+	heap[0] = NULL;
+	for (i = pow2/2 - 1; i > 0; i--)
+		heap[i] = NULL;
+	for (i = 0; i < num; i++)
+		heap[pow2/2 + i] = &points[i]->Z;
+	for (i = pow2/2 + num; i < pow2; i++)
+		heap[i] = NULL;
+	
+	/* set each node to the product of its children */
+	for (i = pow2/2 - 1; i > 0; i--)
+		{
+		heap[i] = BN_new();
+		if (heap[i] == NULL) goto err;
+		
+		if (heap[2*i] != NULL)
+			{
+			if ((heap[2*i + 1] == NULL) || BN_is_zero(heap[2*i + 1]))
+				{
+				if (!BN_copy(heap[i], heap[2*i])) goto err;
+				}
+			else
+				{
+				if (BN_is_zero(heap[2*i]))
+					{
+					if (!BN_copy(heap[i], heap[2*i + 1])) goto err;
+					}
+				else
+					{
+					if (!group->meth->field_mul(group, heap[i],
+						heap[2*i], heap[2*i + 1], ctx)) goto err;
+					}
+				}
+			}
+		}
+
+	/* invert heap[1] */
+	if (!BN_is_zero(heap[1]))
+		{
+		if (!BN_mod_inverse(heap[1], heap[1], &group->field, ctx))
+			{
+			ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
+			goto err;
+			}
+		}
+	if (group->meth->field_encode != 0)
+		{
+		/* in the Montgomery case, we just turned  R*H  (representing H)
+		 * into  1/(R*H),  but we need  R*(1/H)  (representing 1/H);
+		 * i.e. we have need to multiply by the Montgomery factor twice */
+		if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err;
+		if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err;
+		}
+
+	/* set other heap[i]'s to their inverses */
+	for (i = 2; i < pow2/2 + num; i += 2)
+		{
+		/* i is even */
+		if ((heap[i + 1] != NULL) && !BN_is_zero(heap[i + 1]))
+			{
+			if (!group->meth->field_mul(group, tmp0, heap[i/2], heap[i + 1], ctx)) goto err;
+			if (!group->meth->field_mul(group, tmp1, heap[i/2], heap[i], ctx)) goto err;
+			if (!BN_copy(heap[i], tmp0)) goto err;
+			if (!BN_copy(heap[i + 1], tmp1)) goto err;
+			}
+		else
+			{
+			if (!BN_copy(heap[i], heap[i/2])) goto err;
+			}
+		}
+
+	/* we have replaced all non-zero Z's by their inverses, now fix up all the points */
+	for (i = 0; i < num; i++)
+		{
+		EC_POINT *p = points[i];
+		
+		if (!BN_is_zero(&p->Z))
+			{
+			/* turn  (X, Y, 1/Z)  into  (X/Z^2, Y/Z^3, 1) */
+
+			if (!group->meth->field_sqr(group, tmp1, &p->Z, ctx)) goto err;
+			if (!group->meth->field_mul(group, &p->X, &p->X, tmp1, ctx)) goto err;
+
+			if (!group->meth->field_mul(group, tmp1, tmp1, &p->Z, ctx)) goto err;
+			if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp1, ctx)) goto err;
+		
+			if (group->meth->field_set_to_one != 0)
+				{
+				if (!group->meth->field_set_to_one(group, &p->Z, ctx)) goto err;
+				}
+			else
+				{
+				if (!BN_one(&p->Z)) goto err;
+				}
+			p->Z_is_one = 1;
+			}
+		}
+
+	ret = 1;
+		
+ err:
+	BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	if (heap != NULL)
+		{
+		/* heap[pow2/2] .. heap[pow2-1] have not been allocated locally! */
+		for (i = pow2/2 - 1; i > 0; i--)
+			{
+			if (heap[i] != NULL)
+				BN_clear_free(heap[i]);
+			}
+		OPENSSL_free(heap);
+		}
+	return ret;
+	}
+
+
+int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+	{
+	return BN_mod_mul(r, a, b, &group->field, ctx);
+	}
+
+
+int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
+	{
+	return BN_mod_sqr(r, a, &group->field, ctx);
+	}
diff --git a/openssl/crypto/ec/ectest.c b/openssl/crypto/ec/ectest.c
new file mode 100644
index 0000000..7509cb9
--- /dev/null
+++ b/openssl/crypto/ec/ectest.c
@@ -0,0 +1,1334 @@
+/* crypto/ec/ectest.c */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by 
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef FLAT_INC
+#include "e_os.h"
+#else
+#include "../e_os.h"
+#endif
+#include <string.h>
+#include <time.h>
+
+
+#ifdef OPENSSL_NO_EC
+int main(int argc, char * argv[]) { puts("Elliptic curves are disabled."); return 0; }
+#else
+
+
+#include <openssl/ec.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/err.h>
+#include <openssl/obj_mac.h>
+#include <openssl/objects.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+
+#if defined(_MSC_VER) && defined(_MIPS_) && (_MSC_VER/100==12)
+/* suppress "too big too optimize" warning */
+#pragma warning(disable:4959)
+#endif
+
+#define ABORT do { \
+	fflush(stdout); \
+	fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \
+	ERR_print_errors_fp(stderr); \
+	EXIT(1); \
+} while (0)
+
+void prime_field_tests(void);
+void char2_field_tests(void);
+void internal_curve_test(void);
+
+#define TIMING_BASE_PT 0
+#define TIMING_RAND_PT 1
+#define TIMING_SIMUL 2
+
+#if 0
+static void timings(EC_GROUP *group, int type, BN_CTX *ctx)
+	{
+	clock_t clck;
+	int i, j;
+	BIGNUM *s;
+	BIGNUM *r[10], *r0[10];
+	EC_POINT *P;
+		
+	s = BN_new();
+	if (s == NULL) ABORT;
+
+	fprintf(stdout, "Timings for %d-bit field, ", EC_GROUP_get_degree(group));
+	if (!EC_GROUP_get_order(group, s, ctx)) ABORT;
+	fprintf(stdout, "%d-bit scalars ", (int)BN_num_bits(s));
+	fflush(stdout);
+
+	P = EC_POINT_new(group);
+	if (P == NULL) ABORT;
+	EC_POINT_copy(P, EC_GROUP_get0_generator(group));
+
+	for (i = 0; i < 10; i++)
+		{
+		if ((r[i] = BN_new()) == NULL) ABORT;
+		if (!BN_pseudo_rand(r[i], BN_num_bits(s), 0, 0)) ABORT;
+		if (type != TIMING_BASE_PT)
+			{
+			if ((r0[i] = BN_new()) == NULL) ABORT;
+			if (!BN_pseudo_rand(r0[i], BN_num_bits(s), 0, 0)) ABORT;
+			}
+		}
+
+	clck = clock();
+	for (i = 0; i < 10; i++)
+		{
+		for (j = 0; j < 10; j++)
+			{
+			if (!EC_POINT_mul(group, P, (type != TIMING_RAND_PT) ? r[i] : NULL, 
+				(type != TIMING_BASE_PT) ? P : NULL, (type != TIMING_BASE_PT) ? r0[i] : NULL, ctx)) ABORT;
+			}
+		}
+	clck = clock() - clck;
+
+	fprintf(stdout, "\n");
+
+#ifdef CLOCKS_PER_SEC
+	/* "To determine the time in seconds, the value returned
+	 * by the clock function should be divided by the value
+	 * of the macro CLOCKS_PER_SEC."
+	 *                                       -- ISO/IEC 9899 */
+#	define UNIT "s"
+#else
+	/* "`CLOCKS_PER_SEC' undeclared (first use this function)"
+	 *                            -- cc on NeXTstep/OpenStep */
+#	define UNIT "units"
+#	define CLOCKS_PER_SEC 1
+#endif
+
+	if (type == TIMING_BASE_PT) {
+		fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
+			"base point multiplications", (double)clck/CLOCKS_PER_SEC);
+	} else if (type == TIMING_RAND_PT) {
+		fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
+			"random point multiplications", (double)clck/CLOCKS_PER_SEC);
+	} else if (type == TIMING_SIMUL) {
+		fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
+			"s*P+t*Q operations", (double)clck/CLOCKS_PER_SEC);
+	}
+	fprintf(stdout, "average: %.4f " UNIT "\n", (double)clck/(CLOCKS_PER_SEC*i*j));
+
+	EC_POINT_free(P);
+	BN_free(s);
+	for (i = 0; i < 10; i++)
+		{
+		BN_free(r[i]);
+		if (type != TIMING_BASE_PT) BN_free(r0[i]);
+		}
+	}
+#endif
+
+void prime_field_tests()
+	{	
+	BN_CTX *ctx = NULL;
+	BIGNUM *p, *a, *b;
+	EC_GROUP *group;
+	EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
+	EC_POINT *P, *Q, *R;
+	BIGNUM *x, *y, *z;
+	unsigned char buf[100];
+	size_t i, len;
+	int k;
+	
+#if 1 /* optional */
+	ctx = BN_CTX_new();
+	if (!ctx) ABORT;
+#endif
+
+	p = BN_new();
+	a = BN_new();
+	b = BN_new();
+	if (!p || !a || !b) ABORT;
+
+	if (!BN_hex2bn(&p, "17")) ABORT;
+	if (!BN_hex2bn(&a, "1")) ABORT;
+	if (!BN_hex2bn(&b, "1")) ABORT;
+	
+	group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp
+	                                             * so that the library gets to choose the EC_METHOD */
+	if (!group) ABORT;
+
+	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
+
+	{
+		EC_GROUP *tmp;
+		tmp = EC_GROUP_new(EC_GROUP_method_of(group));
+		if (!tmp) ABORT;
+		if (!EC_GROUP_copy(tmp, group)) ABORT;
+		EC_GROUP_free(group);
+		group = tmp;
+	}
+	
+	if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) ABORT;
+
+	fprintf(stdout, "Curve defined by Weierstrass equation\n     y^2 = x^3 + a*x + b  (mod 0x");
+	BN_print_fp(stdout, p);
+	fprintf(stdout, ")\n     a = 0x");
+	BN_print_fp(stdout, a);
+	fprintf(stdout, "\n     b = 0x");
+	BN_print_fp(stdout, b);
+	fprintf(stdout, "\n");
+
+	P = EC_POINT_new(group);
+	Q = EC_POINT_new(group);
+	R = EC_POINT_new(group);
+	if (!P || !Q || !R) ABORT;
+	
+	if (!EC_POINT_set_to_infinity(group, P)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+	buf[0] = 0;
+	if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) ABORT;
+
+	if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+	x = BN_new();
+	y = BN_new();
+	z = BN_new();
+	if (!x || !y || !z) ABORT;
+
+	if (!BN_hex2bn(&x, "D")) ABORT;
+	if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) ABORT;
+	if (!EC_POINT_is_on_curve(group, Q, ctx))
+		{
+		if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx)) ABORT;
+		fprintf(stderr, "Point is not on curve: x = 0x");
+		BN_print_fp(stderr, x);
+		fprintf(stderr, ", y = 0x");
+		BN_print_fp(stderr, y);
+		fprintf(stderr, "\n");
+		ABORT;
+		}
+
+	fprintf(stdout, "A cyclic subgroup:\n");
+	k = 100;
+	do
+		{
+		if (k-- == 0) ABORT;
+
+		if (EC_POINT_is_at_infinity(group, P))
+			fprintf(stdout, "     point at infinity\n");
+		else
+			{
+			if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
+
+			fprintf(stdout, "     x = 0x");
+			BN_print_fp(stdout, x);
+			fprintf(stdout, ", y = 0x");
+			BN_print_fp(stdout, y);
+			fprintf(stdout, "\n");
+			}
+		
+		if (!EC_POINT_copy(R, P)) ABORT;
+		if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
+
+#if 0 /* optional */
+		{
+			EC_POINT *points[3];
+		
+			points[0] = R;
+			points[1] = Q;
+			points[2] = P;
+			if (!EC_POINTs_make_affine(group, 2, points, ctx)) ABORT;
+		}
+#endif
+
+		}
+	while (!EC_POINT_is_at_infinity(group, P));
+
+	if (!EC_POINT_add(group, P, Q, R, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx);
+	if (len == 0) ABORT;
+	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
+	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
+	fprintf(stdout, "Generator as octect string, compressed form:\n     ");
+	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
+	
+	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
+	if (len == 0) ABORT;
+	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
+	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
+	fprintf(stdout, "\nGenerator as octect string, uncompressed form:\n     ");
+	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
+	
+	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
+	if (len == 0) ABORT;
+	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
+	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
+	fprintf(stdout, "\nGenerator as octect string, hybrid form:\n     ");
+	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
+	
+	if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx)) ABORT;
+	fprintf(stdout, "\nA representation of the inverse of that generator in\nJacobian projective coordinates:\n     X = 0x");
+	BN_print_fp(stdout, x);
+	fprintf(stdout, ", Y = 0x");
+	BN_print_fp(stdout, y);
+	fprintf(stdout, ", Z = 0x");
+	BN_print_fp(stdout, z);
+	fprintf(stdout, "\n");
+
+	if (!EC_POINT_invert(group, P, ctx)) ABORT;
+	if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
+
+
+	/* Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2, 2000)
+	 * -- not a NIST curve, but commonly used */
+	
+	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")) ABORT;
+	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
+	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC")) ABORT;
+	if (!BN_hex2bn(&b, "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45")) ABORT;
+	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
+
+	if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) ABORT;
+	if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) ABORT;
+	if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
+	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+	if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) ABORT;
+	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
+
+	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
+	fprintf(stdout, "\nSEC2 curve secp160r1 -- Generator:\n     x = 0x");
+	BN_print_fp(stdout, x);
+	fprintf(stdout, "\n     y = 0x");
+	BN_print_fp(stdout, y);
+	fprintf(stdout, "\n");
+	/* G_y value taken from the standard: */
+	if (!BN_hex2bn(&z, "23a628553168947d59dcc912042351377ac5fb32")) ABORT;
+	if (0 != BN_cmp(y, z)) ABORT;
+
+	fprintf(stdout, "verify degree ...");
+	if (EC_GROUP_get_degree(group) != 160) ABORT;
+	fprintf(stdout, " ok\n");
+	
+	fprintf(stdout, "verify group order ...");
+	fflush(stdout);
+	if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
+	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
+	fprintf(stdout, ".");
+	fflush(stdout);
+	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
+	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
+	fprintf(stdout, " ok\n");
+
+	if (!(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
+	if (!EC_GROUP_copy(P_160, group)) ABORT;
+
+
+	/* Curve P-192 (FIPS PUB 186-2, App. 6) */
+	
+	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")) ABORT;
+	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
+	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")) ABORT;
+	if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")) ABORT;
+	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
+
+	if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) ABORT;
+	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
+	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) ABORT;
+	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
+
+	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
+	fprintf(stdout, "\nNIST curve P-192 -- Generator:\n     x = 0x");
+	BN_print_fp(stdout, x);
+	fprintf(stdout, "\n     y = 0x");
+	BN_print_fp(stdout, y);
+	fprintf(stdout, "\n");
+	/* G_y value taken from the standard: */
+	if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")) ABORT;
+	if (0 != BN_cmp(y, z)) ABORT;
+
+	fprintf(stdout, "verify degree ...");
+	if (EC_GROUP_get_degree(group) != 192) ABORT;
+	fprintf(stdout, " ok\n");
+	
+	fprintf(stdout, "verify group order ...");
+	fflush(stdout);
+	if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
+	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
+	fprintf(stdout, ".");
+	fflush(stdout);
+	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
+	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
+	fprintf(stdout, " ok\n");
+
+	if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
+	if (!EC_GROUP_copy(P_192, group)) ABORT;
+
+
+	/* Curve P-224 (FIPS PUB 186-2, App. 6) */
+	
+	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) ABORT;
+	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
+	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) ABORT;
+	if (!BN_hex2bn(&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) ABORT;
+	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
+
+	if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT;
+	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
+	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT;
+	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
+
+	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
+	fprintf(stdout, "\nNIST curve P-224 -- Generator:\n     x = 0x");
+	BN_print_fp(stdout, x);
+	fprintf(stdout, "\n     y = 0x");
+	BN_print_fp(stdout, y);
+	fprintf(stdout, "\n");
+	/* G_y value taken from the standard: */
+	if (!BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) ABORT;
+	if (0 != BN_cmp(y, z)) ABORT;
+	
+	fprintf(stdout, "verify degree ...");
+	if (EC_GROUP_get_degree(group) != 224) ABORT;
+	fprintf(stdout, " ok\n");
+	
+	fprintf(stdout, "verify group order ...");
+	fflush(stdout);
+	if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
+	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
+	fprintf(stdout, ".");
+	fflush(stdout);
+	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
+	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
+	fprintf(stdout, " ok\n");
+
+	if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
+	if (!EC_GROUP_copy(P_224, group)) ABORT;
+
+
+	/* Curve P-256 (FIPS PUB 186-2, App. 6) */
+	
+	if (!BN_hex2bn(&p, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
+	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
+	if (!BN_hex2bn(&a, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
+	if (!BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")) ABORT;
+	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
+
+	if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) ABORT;
+	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
+	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+	if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E"
+		"84F3B9CAC2FC632551")) ABORT;
+	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
+
+	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
+	fprintf(stdout, "\nNIST curve P-256 -- Generator:\n     x = 0x");
+	BN_print_fp(stdout, x);
+	fprintf(stdout, "\n     y = 0x");
+	BN_print_fp(stdout, y);
+	fprintf(stdout, "\n");
+	/* G_y value taken from the standard: */
+	if (!BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")) ABORT;
+	if (0 != BN_cmp(y, z)) ABORT;
+	
+	fprintf(stdout, "verify degree ...");
+	if (EC_GROUP_get_degree(group) != 256) ABORT;
+	fprintf(stdout, " ok\n");
+	
+	fprintf(stdout, "verify group order ...");
+	fflush(stdout);
+	if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
+	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
+	fprintf(stdout, ".");
+	fflush(stdout);
+	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
+	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
+	fprintf(stdout, " ok\n");
+
+	if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
+	if (!EC_GROUP_copy(P_256, group)) ABORT;
+
+
+	/* Curve P-384 (FIPS PUB 186-2, App. 6) */
+	
+	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+		"FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")) ABORT;
+	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
+	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+		"FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")) ABORT;
+	if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141"
+		"120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")) ABORT;
+	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
+
+	if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B"
+		"9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT;
+	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
+	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+		"FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT;
+	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
+
+	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
+	fprintf(stdout, "\nNIST curve P-384 -- Generator:\n     x = 0x");
+	BN_print_fp(stdout, x);
+	fprintf(stdout, "\n     y = 0x");
+	BN_print_fp(stdout, y);
+	fprintf(stdout, "\n");
+	/* G_y value taken from the standard: */
+	if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14"
+		"7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")) ABORT;
+	if (0 != BN_cmp(y, z)) ABORT;
+	
+	fprintf(stdout, "verify degree ...");
+	if (EC_GROUP_get_degree(group) != 384) ABORT;
+	fprintf(stdout, " ok\n");
+	
+	fprintf(stdout, "verify group order ...");
+	fflush(stdout);
+	if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
+	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
+	fprintf(stdout, ".");
+	fflush(stdout);
+	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
+	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
+	fprintf(stdout, " ok\n");
+
+	if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
+	if (!EC_GROUP_copy(P_384, group)) ABORT;
+
+
+	/* Curve P-521 (FIPS PUB 186-2, App. 6) */
+	
+	if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+		"FFFFFFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
+	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
+	if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+		"FFFFFFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
+	if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B"
+		"315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573"
+		"DF883D2C34F1EF451FD46B503F00")) ABORT;
+	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
+
+	if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F"
+		"B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B"
+		"3C1856A429BF97E7E31C2E5BD66")) ABORT;
+	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
+	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+	if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+		"FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5"
+		"C9B8899C47AEBB6FB71E91386409")) ABORT;
+	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
+
+	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
+	fprintf(stdout, "\nNIST curve P-521 -- Generator:\n     x = 0x");
+	BN_print_fp(stdout, x);
+	fprintf(stdout, "\n     y = 0x");
+	BN_print_fp(stdout, y);
+	fprintf(stdout, "\n");
+	/* G_y value taken from the standard: */
+	if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579"
+		"B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C"
+		"7086A272C24088BE94769FD16650")) ABORT;
+	if (0 != BN_cmp(y, z)) ABORT;
+	
+	fprintf(stdout, "verify degree ...");
+	if (EC_GROUP_get_degree(group) != 521) ABORT;
+	fprintf(stdout, " ok\n");
+	
+	fprintf(stdout, "verify group order ...");
+	fflush(stdout);
+	if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
+	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
+	fprintf(stdout, ".");
+	fflush(stdout);
+	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
+	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
+	fprintf(stdout, " ok\n");
+
+	if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
+	if (!EC_GROUP_copy(P_521, group)) ABORT;
+
+
+	/* more tests using the last curve */
+
+	if (!EC_POINT_copy(Q, P)) ABORT;
+	if (EC_POINT_is_at_infinity(group, Q)) ABORT;
+	if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
+	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+	if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
+
+	if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
+	if (!EC_POINT_add(group, R, R, Q, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */
+
+	{
+		const EC_POINT *points[4];
+		const BIGNUM *scalars[4];
+		BIGNUM scalar3;
+	
+		if (EC_POINT_is_at_infinity(group, Q)) ABORT;
+		points[0] = Q;
+		points[1] = Q;
+		points[2] = Q;
+		points[3] = Q;
+
+		if (!BN_add(y, z, BN_value_one())) ABORT;
+		if (BN_is_odd(y)) ABORT;
+		if (!BN_rshift1(y, y)) ABORT;
+		scalars[0] = y; /* (group order + 1)/2,  so  y*Q + y*Q = Q */
+		scalars[1] = y;
+
+		fprintf(stdout, "combined multiplication ...");
+		fflush(stdout);
+
+		/* z is still the group order */
+		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
+		if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) ABORT;
+		if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
+		if (0 != EC_POINT_cmp(group, R, Q, ctx)) ABORT;
+
+		fprintf(stdout, ".");
+		fflush(stdout);
+
+		if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
+		if (!BN_add(z, z, y)) ABORT;
+		BN_set_negative(z, 1);
+		scalars[0] = y;
+		scalars[1] = z; /* z = -(order + y) */
+
+		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
+		if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+		fprintf(stdout, ".");
+		fflush(stdout);
+
+		if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
+		if (!BN_add(z, x, y)) ABORT;
+		BN_set_negative(z, 1);
+		scalars[0] = x;
+		scalars[1] = y;
+		scalars[2] = z; /* z = -(x+y) */
+
+		BN_init(&scalar3);
+		BN_zero(&scalar3);
+		scalars[3] = &scalar3;
+
+		if (!EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx)) ABORT;
+		if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+		fprintf(stdout, " ok\n\n");
+
+		BN_free(&scalar3);
+	}
+
+
+#if 0
+	timings(P_160, TIMING_BASE_PT, ctx);
+	timings(P_160, TIMING_RAND_PT, ctx);
+	timings(P_160, TIMING_SIMUL, ctx);
+	timings(P_192, TIMING_BASE_PT, ctx);
+	timings(P_192, TIMING_RAND_PT, ctx);
+	timings(P_192, TIMING_SIMUL, ctx);
+	timings(P_224, TIMING_BASE_PT, ctx);
+	timings(P_224, TIMING_RAND_PT, ctx);
+	timings(P_224, TIMING_SIMUL, ctx);
+	timings(P_256, TIMING_BASE_PT, ctx);
+	timings(P_256, TIMING_RAND_PT, ctx);
+	timings(P_256, TIMING_SIMUL, ctx);
+	timings(P_384, TIMING_BASE_PT, ctx);
+	timings(P_384, TIMING_RAND_PT, ctx);
+	timings(P_384, TIMING_SIMUL, ctx);
+	timings(P_521, TIMING_BASE_PT, ctx);
+	timings(P_521, TIMING_RAND_PT, ctx);
+	timings(P_521, TIMING_SIMUL, ctx);
+#endif
+
+
+	if (ctx)
+		BN_CTX_free(ctx);
+	BN_free(p); BN_free(a);	BN_free(b);
+	EC_GROUP_free(group);
+	EC_POINT_free(P);
+	EC_POINT_free(Q);
+	EC_POINT_free(R);
+	BN_free(x); BN_free(y); BN_free(z);
+
+	if (P_160) EC_GROUP_free(P_160);
+	if (P_192) EC_GROUP_free(P_192);
+	if (P_224) EC_GROUP_free(P_224);
+	if (P_256) EC_GROUP_free(P_256);
+	if (P_384) EC_GROUP_free(P_384);
+	if (P_521) EC_GROUP_free(P_521);
+
+	}
+
+/* Change test based on whether binary point compression is enabled or not. */
+#ifdef OPENSSL_EC_BIN_PT_COMP
+#define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
+	if (!BN_hex2bn(&x, _x)) ABORT; \
+	if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \
+	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
+	if (!BN_hex2bn(&z, _order)) ABORT; \
+	if (!BN_hex2bn(&cof, _cof)) ABORT; \
+	if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
+	if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
+	fprintf(stdout, "\n%s -- Generator:\n     x = 0x", _name); \
+	BN_print_fp(stdout, x); \
+	fprintf(stdout, "\n     y = 0x"); \
+	BN_print_fp(stdout, y); \
+	fprintf(stdout, "\n"); \
+	/* G_y value taken from the standard: */ \
+	if (!BN_hex2bn(&z, _y)) ABORT; \
+	if (0 != BN_cmp(y, z)) ABORT;
+#else 
+#define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
+	if (!BN_hex2bn(&x, _x)) ABORT; \
+	if (!BN_hex2bn(&y, _y)) ABORT; \
+	if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
+	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
+	if (!BN_hex2bn(&z, _order)) ABORT; \
+	if (!BN_hex2bn(&cof, _cof)) ABORT; \
+	if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
+	fprintf(stdout, "\n%s -- Generator:\n     x = 0x", _name); \
+	BN_print_fp(stdout, x); \
+	fprintf(stdout, "\n     y = 0x"); \
+	BN_print_fp(stdout, y); \
+	fprintf(stdout, "\n");
+#endif
+
+#define CHAR2_CURVE_TEST(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
+	if (!BN_hex2bn(&p, _p)) ABORT; \
+	if (!BN_hex2bn(&a, _a)) ABORT; \
+	if (!BN_hex2bn(&b, _b)) ABORT; \
+	if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT; \
+	CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
+	fprintf(stdout, "verify degree ..."); \
+	if (EC_GROUP_get_degree(group) != _degree) ABORT; \
+	fprintf(stdout, " ok\n"); \
+	fprintf(stdout, "verify group order ..."); \
+	fflush(stdout); \
+	if (!EC_GROUP_get_order(group, z, ctx)) ABORT; \
+	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; \
+	if (!EC_POINT_is_at_infinity(group, Q)) ABORT; \
+	fprintf(stdout, "."); \
+	fflush(stdout); \
+	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT; \
+	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; \
+	if (!EC_POINT_is_at_infinity(group, Q)) ABORT; \
+	fprintf(stdout, " ok\n"); \
+	if (!(_variable = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; \
+	if (!EC_GROUP_copy(_variable, group)) ABORT;
+
+void char2_field_tests()
+	{	
+	BN_CTX *ctx = NULL;
+	BIGNUM *p, *a, *b;
+	EC_GROUP *group;
+	EC_GROUP *C2_K163 = NULL, *C2_K233 = NULL, *C2_K283 = NULL, *C2_K409 = NULL, *C2_K571 = NULL;
+	EC_GROUP *C2_B163 = NULL, *C2_B233 = NULL, *C2_B283 = NULL, *C2_B409 = NULL, *C2_B571 = NULL;
+	EC_POINT *P, *Q, *R;
+	BIGNUM *x, *y, *z, *cof;
+	unsigned char buf[100];
+	size_t i, len;
+	int k;
+	
+#if 1 /* optional */
+	ctx = BN_CTX_new();
+	if (!ctx) ABORT;
+#endif
+
+	p = BN_new();
+	a = BN_new();
+	b = BN_new();
+	if (!p || !a || !b) ABORT;
+
+	if (!BN_hex2bn(&p, "13")) ABORT;
+	if (!BN_hex2bn(&a, "3")) ABORT;
+	if (!BN_hex2bn(&b, "1")) ABORT;
+	
+	group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use EC_GROUP_new_curve_GF2m
+	                                                * so that the library gets to choose the EC_METHOD */
+	if (!group) ABORT;
+	if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT;
+
+	{
+		EC_GROUP *tmp;
+		tmp = EC_GROUP_new(EC_GROUP_method_of(group));
+		if (!tmp) ABORT;
+		if (!EC_GROUP_copy(tmp, group)) ABORT;
+		EC_GROUP_free(group);
+		group = tmp;
+	}
+	
+	if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)) ABORT;
+
+	fprintf(stdout, "Curve defined by Weierstrass equation\n     y^2 + x*y = x^3 + a*x^2 + b  (mod 0x");
+	BN_print_fp(stdout, p);
+	fprintf(stdout, ")\n     a = 0x");
+	BN_print_fp(stdout, a);
+	fprintf(stdout, "\n     b = 0x");
+	BN_print_fp(stdout, b);
+	fprintf(stdout, "\n(0x... means binary polynomial)\n");
+
+	P = EC_POINT_new(group);
+	Q = EC_POINT_new(group);
+	R = EC_POINT_new(group);
+	if (!P || !Q || !R) ABORT;
+	
+	if (!EC_POINT_set_to_infinity(group, P)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+	buf[0] = 0;
+	if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) ABORT;
+
+	if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+	x = BN_new();
+	y = BN_new();
+	z = BN_new();
+	cof = BN_new();
+	if (!x || !y || !z || !cof) ABORT;
+
+	if (!BN_hex2bn(&x, "6")) ABORT;
+/* Change test based on whether binary point compression is enabled or not. */
+#ifdef OPENSSL_EC_BIN_PT_COMP
+	if (!EC_POINT_set_compressed_coordinates_GF2m(group, Q, x, 1, ctx)) ABORT;
+#else
+	if (!BN_hex2bn(&y, "8")) ABORT;
+	if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
+#endif
+	if (!EC_POINT_is_on_curve(group, Q, ctx))
+		{
+/* Change test based on whether binary point compression is enabled or not. */
+#ifdef OPENSSL_EC_BIN_PT_COMP
+		if (!EC_POINT_get_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
+#endif
+		fprintf(stderr, "Point is not on curve: x = 0x");
+		BN_print_fp(stderr, x);
+		fprintf(stderr, ", y = 0x");
+		BN_print_fp(stderr, y);
+		fprintf(stderr, "\n");
+		ABORT;
+		}
+
+	fprintf(stdout, "A cyclic subgroup:\n");
+	k = 100;
+	do
+		{
+		if (k-- == 0) ABORT;
+
+		if (EC_POINT_is_at_infinity(group, P))
+			fprintf(stdout, "     point at infinity\n");
+		else
+			{
+			if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT;
+
+			fprintf(stdout, "     x = 0x");
+			BN_print_fp(stdout, x);
+			fprintf(stdout, ", y = 0x");
+			BN_print_fp(stdout, y);
+			fprintf(stdout, "\n");
+			}
+		
+		if (!EC_POINT_copy(R, P)) ABORT;
+		if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
+		}
+	while (!EC_POINT_is_at_infinity(group, P));
+
+	if (!EC_POINT_add(group, P, Q, R, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+/* Change test based on whether binary point compression is enabled or not. */
+#ifdef OPENSSL_EC_BIN_PT_COMP
+	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx);
+	if (len == 0) ABORT;
+	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
+	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
+	fprintf(stdout, "Generator as octet string, compressed form:\n     ");
+	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
+#endif
+	
+	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
+	if (len == 0) ABORT;
+	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
+	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
+	fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n     ");
+	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
+	
+/* Change test based on whether binary point compression is enabled or not. */
+#ifdef OPENSSL_EC_BIN_PT_COMP
+	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
+	if (len == 0) ABORT;
+	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
+	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
+	fprintf(stdout, "\nGenerator as octet string, hybrid form:\n     ");
+	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
+#endif
+
+	fprintf(stdout, "\n");
+	
+	if (!EC_POINT_invert(group, P, ctx)) ABORT;
+	if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
+
+
+	/* Curve K-163 (FIPS PUB 186-2, App. 6) */
+	CHAR2_CURVE_TEST
+		(
+		"NIST curve K-163",
+		"0800000000000000000000000000000000000000C9",
+		"1",
+		"1",
+		"02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
+		"0289070FB05D38FF58321F2E800536D538CCDAA3D9",
+		1,
+		"04000000000000000000020108A2E0CC0D99F8A5EF",
+		"2",
+		163,
+		C2_K163
+		);
+
+	/* Curve B-163 (FIPS PUB 186-2, App. 6) */
+	CHAR2_CURVE_TEST
+		(
+		"NIST curve B-163",
+		"0800000000000000000000000000000000000000C9",
+		"1",
+		"020A601907B8C953CA1481EB10512F78744A3205FD",
+		"03F0EBA16286A2D57EA0991168D4994637E8343E36",
+		"00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
+		1,
+		"040000000000000000000292FE77E70C12A4234C33",
+		"2",
+		163,
+		C2_B163
+		);
+
+	/* Curve K-233 (FIPS PUB 186-2, App. 6) */
+	CHAR2_CURVE_TEST
+		(
+		"NIST curve K-233",
+		"020000000000000000000000000000000000000004000000000000000001",
+		"0",
+		"1",
+		"017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
+		"01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
+		0,
+		"008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
+		"4",
+		233,
+		C2_K233
+		);
+
+	/* Curve B-233 (FIPS PUB 186-2, App. 6) */
+	CHAR2_CURVE_TEST
+		(
+		"NIST curve B-233",
+		"020000000000000000000000000000000000000004000000000000000001",
+		"000000000000000000000000000000000000000000000000000000000001",
+		"0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
+		"00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
+		"01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
+		1,
+		"01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
+		"2",
+		233,
+		C2_B233
+		);
+
+	/* Curve K-283 (FIPS PUB 186-2, App. 6) */
+	CHAR2_CURVE_TEST
+		(
+		"NIST curve K-283",
+		"0800000000000000000000000000000000000000000000000000000000000000000010A1",
+		"0",
+		"1",
+		"0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
+		"01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
+		0,
+		"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
+		"4",
+		283,
+		C2_K283
+		);
+
+	/* Curve B-283 (FIPS PUB 186-2, App. 6) */
+	CHAR2_CURVE_TEST
+		(
+		"NIST curve B-283",
+		"0800000000000000000000000000000000000000000000000000000000000000000010A1",
+		"000000000000000000000000000000000000000000000000000000000000000000000001",
+		"027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
+		"05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
+		"03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
+		1,
+		"03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
+		"2",
+		283,
+		C2_B283
+		);
+
+	/* Curve K-409 (FIPS PUB 186-2, App. 6) */
+	CHAR2_CURVE_TEST
+		(
+		"NIST curve K-409",
+		"02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
+		"0",
+		"1",
+		"0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
+		"01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
+		1,
+		"007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
+		"4",
+		409,
+		C2_K409
+		);
+
+	/* Curve B-409 (FIPS PUB 186-2, App. 6) */
+	CHAR2_CURVE_TEST
+		(
+		"NIST curve B-409",
+		"02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
+		"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+		"0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
+		"015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
+		"0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
+		1,
+		"010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
+		"2",
+		409,
+		C2_B409
+		);
+
+	/* Curve K-571 (FIPS PUB 186-2, App. 6) */
+	CHAR2_CURVE_TEST
+		(
+		"NIST curve K-571",
+		"80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
+		"0",
+		"1",
+		"026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
+		"0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
+		0,
+		"020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
+		"4",
+		571,
+		C2_K571
+		);
+
+	/* Curve B-571 (FIPS PUB 186-2, App. 6) */
+	CHAR2_CURVE_TEST
+		(
+		"NIST curve B-571",
+		"80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
+		"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+		"02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
+		"0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
+		"037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
+		1,
+		"03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
+		"2",
+		571,
+		C2_B571
+		);
+
+	/* more tests using the last curve */
+
+	if (!EC_POINT_copy(Q, P)) ABORT;
+	if (EC_POINT_is_at_infinity(group, Q)) ABORT;
+	if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
+	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+	if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
+
+	if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
+	if (!EC_POINT_add(group, R, R, Q, ctx)) ABORT;
+	if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */
+
+	{
+		const EC_POINT *points[3];
+		const BIGNUM *scalars[3];
+	
+		if (EC_POINT_is_at_infinity(group, Q)) ABORT;
+		points[0] = Q;
+		points[1] = Q;
+		points[2] = Q;
+
+		if (!BN_add(y, z, BN_value_one())) ABORT;
+		if (BN_is_odd(y)) ABORT;
+		if (!BN_rshift1(y, y)) ABORT;
+		scalars[0] = y; /* (group order + 1)/2,  so  y*Q + y*Q = Q */
+		scalars[1] = y;
+
+		fprintf(stdout, "combined multiplication ...");
+		fflush(stdout);
+
+		/* z is still the group order */
+		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
+		if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) ABORT;
+		if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
+		if (0 != EC_POINT_cmp(group, R, Q, ctx)) ABORT;
+
+		fprintf(stdout, ".");
+		fflush(stdout);
+
+		if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
+		if (!BN_add(z, z, y)) ABORT;
+		BN_set_negative(z, 1);
+		scalars[0] = y;
+		scalars[1] = z; /* z = -(order + y) */
+
+		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
+		if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+		fprintf(stdout, ".");
+		fflush(stdout);
+
+		if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
+		if (!BN_add(z, x, y)) ABORT;
+		BN_set_negative(z, 1);
+		scalars[0] = x;
+		scalars[1] = y;
+		scalars[2] = z; /* z = -(x+y) */
+
+		if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx)) ABORT;
+		if (!EC_POINT_is_at_infinity(group, P)) ABORT;
+
+		fprintf(stdout, " ok\n\n");
+	}
+
+
+#if 0
+	timings(C2_K163, TIMING_BASE_PT, ctx);
+	timings(C2_K163, TIMING_RAND_PT, ctx);
+	timings(C2_K163, TIMING_SIMUL, ctx);
+	timings(C2_B163, TIMING_BASE_PT, ctx);
+	timings(C2_B163, TIMING_RAND_PT, ctx);
+	timings(C2_B163, TIMING_SIMUL, ctx);
+	timings(C2_K233, TIMING_BASE_PT, ctx);
+	timings(C2_K233, TIMING_RAND_PT, ctx);
+	timings(C2_K233, TIMING_SIMUL, ctx);
+	timings(C2_B233, TIMING_BASE_PT, ctx);
+	timings(C2_B233, TIMING_RAND_PT, ctx);
+	timings(C2_B233, TIMING_SIMUL, ctx);
+	timings(C2_K283, TIMING_BASE_PT, ctx);
+	timings(C2_K283, TIMING_RAND_PT, ctx);
+	timings(C2_K283, TIMING_SIMUL, ctx);
+	timings(C2_B283, TIMING_BASE_PT, ctx);
+	timings(C2_B283, TIMING_RAND_PT, ctx);
+	timings(C2_B283, TIMING_SIMUL, ctx);
+	timings(C2_K409, TIMING_BASE_PT, ctx);
+	timings(C2_K409, TIMING_RAND_PT, ctx);
+	timings(C2_K409, TIMING_SIMUL, ctx);
+	timings(C2_B409, TIMING_BASE_PT, ctx);
+	timings(C2_B409, TIMING_RAND_PT, ctx);
+	timings(C2_B409, TIMING_SIMUL, ctx);
+	timings(C2_K571, TIMING_BASE_PT, ctx);
+	timings(C2_K571, TIMING_RAND_PT, ctx);
+	timings(C2_K571, TIMING_SIMUL, ctx);
+	timings(C2_B571, TIMING_BASE_PT, ctx);
+	timings(C2_B571, TIMING_RAND_PT, ctx);
+	timings(C2_B571, TIMING_SIMUL, ctx);
+#endif
+
+
+	if (ctx)
+		BN_CTX_free(ctx);
+	BN_free(p); BN_free(a);	BN_free(b);
+	EC_GROUP_free(group);
+	EC_POINT_free(P);
+	EC_POINT_free(Q);
+	EC_POINT_free(R);
+	BN_free(x); BN_free(y); BN_free(z); BN_free(cof);
+
+	if (C2_K163) EC_GROUP_free(C2_K163);
+	if (C2_B163) EC_GROUP_free(C2_B163);
+	if (C2_K233) EC_GROUP_free(C2_K233);
+	if (C2_B233) EC_GROUP_free(C2_B233);
+	if (C2_K283) EC_GROUP_free(C2_K283);
+	if (C2_B283) EC_GROUP_free(C2_B283);
+	if (C2_K409) EC_GROUP_free(C2_K409);
+	if (C2_B409) EC_GROUP_free(C2_B409);
+	if (C2_K571) EC_GROUP_free(C2_K571);
+	if (C2_B571) EC_GROUP_free(C2_B571);
+
+	}
+
+void internal_curve_test(void)
+	{
+	EC_builtin_curve *curves = NULL;
+	size_t crv_len = 0, n = 0;
+	int    ok = 1;
+
+	crv_len = EC_get_builtin_curves(NULL, 0);
+
+	curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);
+
+	if (curves == NULL)
+		return;
+
+	if (!EC_get_builtin_curves(curves, crv_len))
+		{
+		OPENSSL_free(curves);
+		return;
+		}
+
+	fprintf(stdout, "testing internal curves: ");
+		
+	for (n = 0; n < crv_len; n++)
+		{
+		EC_GROUP *group = NULL;
+		int nid = curves[n].nid;
+		if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL)
+			{
+			ok = 0;
+			fprintf(stdout, "\nEC_GROUP_new_curve_name() failed with"
+				" curve %s\n", OBJ_nid2sn(nid));
+			/* try next curve */
+			continue;
+			}
+		if (!EC_GROUP_check(group, NULL))
+			{
+			ok = 0;
+			fprintf(stdout, "\nEC_GROUP_check() failed with"
+				" curve %s\n", OBJ_nid2sn(nid));
+			EC_GROUP_free(group);
+			/* try the next curve */
+			continue;
+			}
+		fprintf(stdout, ".");
+		fflush(stdout);
+		EC_GROUP_free(group);
+		}
+	if (ok)
+		fprintf(stdout, " ok\n");
+	else
+		fprintf(stdout, " failed\n");
+	OPENSSL_free(curves);
+	return;
+	}
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+int main(int argc, char *argv[])
+	{	
+	
+	/* enable memory leak checking unless explicitly disabled */
+	if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
+		{
+		CRYPTO_malloc_debug_init();
+		CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+		}
+	else
+		{
+		/* OPENSSL_DEBUG_MEMORY=off */
+		CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
+		}
+	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+	ERR_load_crypto_strings();
+
+	RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
+
+	prime_field_tests();
+	puts("");
+	char2_field_tests();
+	/* test the internal curves */
+	internal_curve_test();
+
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE_cleanup();
+#endif
+	CRYPTO_cleanup_all_ex_data();
+	ERR_free_strings();
+	ERR_remove_thread_state(NULL);
+	CRYPTO_mem_leaks_fp(stderr);
+	
+	return 0;
+	}
+#endif
diff --git a/openssl/crypto/ecdh/Makefile b/openssl/crypto/ecdh/Makefile
new file mode 100644
index 0000000..65d8904
--- /dev/null
+++ b/openssl/crypto/ecdh/Makefile
@@ -0,0 +1,121 @@
+#
+# crypto/ecdh/Makefile
+#
+
+DIR=	ecdh
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g -Wall
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=ecdhtest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=	ech_lib.c ech_ossl.c ech_key.c ech_err.c
+
+LIBOBJ=	ech_lib.o ech_ossl.o ech_key.o ech_err.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= ecdh.h
+HEADER=	ech_locl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+ech_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ech_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+ech_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+ech_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ech_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+ech_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+ech_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ech_err.o: ech_err.c
+ech_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ech_key.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+ech_key.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ech_key.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ech_key.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
+ech_key.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ech_key.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+ech_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ech_key.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+ech_key.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ech_key.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+ech_key.o: ../../include/openssl/x509_vfy.h ech_key.c ech_locl.h
+ech_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ech_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+ech_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ech_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ech_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+ech_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+ech_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ech_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+ech_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+ech_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+ech_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ech_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ech_lib.o: ech_lib.c ech_locl.h
+ech_ossl.o: ../../e_os.h ../../include/openssl/asn1.h
+ech_ossl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+ech_ossl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+ech_ossl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ech_ossl.o: ../../include/openssl/ecdh.h ../../include/openssl/err.h
+ech_ossl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ech_ossl.o: ../../include/openssl/opensslconf.h
+ech_ossl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ech_ossl.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+ech_ossl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ech_ossl.o: ../cryptlib.h ech_locl.h ech_ossl.c
diff --git a/openssl/crypto/ecdh/ecdh.h b/openssl/crypto/ecdh/ecdh.h
new file mode 100644
index 0000000..b4b58ee
--- /dev/null
+++ b/openssl/crypto/ecdh/ecdh.h
@@ -0,0 +1,123 @@
+/* crypto/ecdh/ecdh.h */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The ECDH software is originally written by Douglas Stebila of
+ * Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef HEADER_ECDH_H
+#define HEADER_ECDH_H
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_ECDH
+#error ECDH is disabled.
+#endif
+
+#include <openssl/ec.h>
+#include <openssl/ossl_typ.h>
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const ECDH_METHOD *ECDH_OpenSSL(void);
+
+void	  ECDH_set_default_method(const ECDH_METHOD *);
+const ECDH_METHOD *ECDH_get_default_method(void);
+int 	  ECDH_set_method(EC_KEY *, const ECDH_METHOD *);
+
+int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh,
+                     void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen));
+
+int 	  ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new 
+		*new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int 	  ECDH_set_ex_data(EC_KEY *d, int idx, void *arg);
+void 	  *ECDH_get_ex_data(EC_KEY *d, int idx);
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_ECDH_strings(void);
+
+/* Error codes for the ECDH functions. */
+
+/* Function codes. */
+#define ECDH_F_ECDH_COMPUTE_KEY				 100
+#define ECDH_F_ECDH_DATA_NEW_METHOD			 101
+
+/* Reason codes. */
+#define ECDH_R_KDF_FAILED				 102
+#define ECDH_R_NO_PRIVATE_VALUE				 100
+#define ECDH_R_POINT_ARITHMETIC_FAILURE			 101
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/ecdh/ecdhtest.c b/openssl/crypto/ecdh/ecdhtest.c
new file mode 100644
index 0000000..212a87e
--- /dev/null
+++ b/openssl/crypto/ecdh/ecdhtest.c
@@ -0,0 +1,368 @@
+/* crypto/ecdh/ecdhtest.c */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The ECDH software is originally written by Douglas Stebila of
+ * Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../e_os.h"
+
+#include <openssl/opensslconf.h>	/* for OPENSSL_NO_ECDH */
+#include <openssl/crypto.h>
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+#include <openssl/err.h>
+
+#ifdef OPENSSL_NO_ECDH
+int main(int argc, char *argv[])
+{
+    printf("No ECDH support\n");
+    return(0);
+}
+#else
+#include <openssl/ec.h>
+#include <openssl/ecdh.h>
+
+#ifdef OPENSSL_SYS_WIN16
+#define MS_CALLBACK	_far _loadds
+#else
+#define MS_CALLBACK
+#endif
+
+#if 0
+static void MS_CALLBACK cb(int p, int n, void *arg);
+#endif
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+
+static const int KDF1_SHA1_len = 20;
+static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen)
+	{
+#ifndef OPENSSL_NO_SHA
+	if (*outlen < SHA_DIGEST_LENGTH)
+		return NULL;
+	else
+		*outlen = SHA_DIGEST_LENGTH;
+	return SHA1(in, inlen, out);
+#else
+	return NULL;
+#endif
+	}
+
+
+static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out)
+	{
+	EC_KEY *a=NULL;
+	EC_KEY *b=NULL;
+	BIGNUM *x_a=NULL, *y_a=NULL,
+	       *x_b=NULL, *y_b=NULL;
+	char buf[12];
+	unsigned char *abuf=NULL,*bbuf=NULL;
+	int i,alen,blen,aout,bout,ret=0;
+	const EC_GROUP *group;
+
+	a = EC_KEY_new_by_curve_name(nid);
+	b = EC_KEY_new_by_curve_name(nid);
+	if (a == NULL || b == NULL)
+		goto err;
+
+	group = EC_KEY_get0_group(a);
+
+	if ((x_a=BN_new()) == NULL) goto err;
+	if ((y_a=BN_new()) == NULL) goto err;
+	if ((x_b=BN_new()) == NULL) goto err;
+	if ((y_b=BN_new()) == NULL) goto err;
+
+	BIO_puts(out,"Testing key generation with ");
+	BIO_puts(out,text);
+#ifdef NOISY
+	BIO_puts(out,"\n");
+#else
+	(void)BIO_flush(out);
+#endif
+
+	if (!EC_KEY_generate_key(a)) goto err;
+	
+	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) 
+		{
+		if (!EC_POINT_get_affine_coordinates_GFp(group,
+			EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
+		}
+	else
+		{
+		if (!EC_POINT_get_affine_coordinates_GF2m(group,
+			EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
+		}
+#ifdef NOISY
+	BIO_puts(out,"  pri 1=");
+	BN_print(out,a->priv_key);
+	BIO_puts(out,"\n  pub 1=");
+	BN_print(out,x_a);
+	BIO_puts(out,",");
+	BN_print(out,y_a);
+	BIO_puts(out,"\n");
+#else
+	BIO_printf(out," .");
+	(void)BIO_flush(out);
+#endif
+
+	if (!EC_KEY_generate_key(b)) goto err;
+
+	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) 
+		{
+		if (!EC_POINT_get_affine_coordinates_GFp(group, 
+			EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
+		}
+	else
+		{
+		if (!EC_POINT_get_affine_coordinates_GF2m(group, 
+			EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
+		}
+
+#ifdef NOISY
+	BIO_puts(out,"  pri 2=");
+	BN_print(out,b->priv_key);
+	BIO_puts(out,"\n  pub 2=");
+	BN_print(out,x_b);
+	BIO_puts(out,",");
+	BN_print(out,y_b);
+	BIO_puts(out,"\n");
+#else
+	BIO_printf(out,".");
+	(void)BIO_flush(out);
+#endif
+
+	alen=KDF1_SHA1_len;
+	abuf=(unsigned char *)OPENSSL_malloc(alen);
+	aout=ECDH_compute_key(abuf,alen,EC_KEY_get0_public_key(b),a,KDF1_SHA1);
+
+#ifdef NOISY
+	BIO_puts(out,"  key1 =");
+	for (i=0; i<aout; i++)
+		{
+		sprintf(buf,"%02X",abuf[i]);
+		BIO_puts(out,buf);
+		}
+	BIO_puts(out,"\n");
+#else
+	BIO_printf(out,".");
+	(void)BIO_flush(out);
+#endif
+
+	blen=KDF1_SHA1_len;
+	bbuf=(unsigned char *)OPENSSL_malloc(blen);
+	bout=ECDH_compute_key(bbuf,blen,EC_KEY_get0_public_key(a),b,KDF1_SHA1);
+
+#ifdef NOISY
+	BIO_puts(out,"  key2 =");
+	for (i=0; i<bout; i++)
+		{
+		sprintf(buf,"%02X",bbuf[i]);
+		BIO_puts(out,buf);
+		}
+	BIO_puts(out,"\n");
+#else
+	BIO_printf(out,".");
+	(void)BIO_flush(out);
+#endif
+
+	if ((aout < 4) || (bout != aout) || (memcmp(abuf,bbuf,aout) != 0))
+		{
+#ifndef NOISY
+		BIO_printf(out, " failed\n\n");
+		BIO_printf(out, "key a:\n");
+		BIO_printf(out, "private key: ");
+		BN_print(out, EC_KEY_get0_private_key(a));
+		BIO_printf(out, "\n");
+		BIO_printf(out, "public key (x,y): ");
+		BN_print(out, x_a);
+		BIO_printf(out, ",");
+		BN_print(out, y_a);
+		BIO_printf(out, "\nkey b:\n");
+		BIO_printf(out, "private key: ");
+		BN_print(out, EC_KEY_get0_private_key(b));
+		BIO_printf(out, "\n");
+		BIO_printf(out, "public key (x,y): ");
+		BN_print(out, x_b);
+		BIO_printf(out, ",");
+		BN_print(out, y_b);
+		BIO_printf(out, "\n");
+		BIO_printf(out, "generated key a: ");
+		for (i=0; i<bout; i++)
+			{
+			sprintf(buf, "%02X", bbuf[i]);
+			BIO_puts(out, buf);
+			}
+		BIO_printf(out, "\n");
+		BIO_printf(out, "generated key b: ");
+		for (i=0; i<aout; i++)
+			{
+			sprintf(buf, "%02X", abuf[i]);
+			BIO_puts(out,buf);
+			}
+		BIO_printf(out, "\n");
+#endif
+		fprintf(stderr,"Error in ECDH routines\n");
+		ret=0;
+		}
+	else
+		{
+#ifndef NOISY
+		BIO_printf(out, " ok\n");
+#endif
+		ret=1;
+		}
+err:
+	ERR_print_errors_fp(stderr);
+
+	if (abuf != NULL) OPENSSL_free(abuf);
+	if (bbuf != NULL) OPENSSL_free(bbuf);
+	if (x_a) BN_free(x_a);
+	if (y_a) BN_free(y_a);
+	if (x_b) BN_free(x_b);
+	if (y_b) BN_free(y_b);
+	if (b) EC_KEY_free(b);
+	if (a) EC_KEY_free(a);
+	return(ret);
+	}
+
+int main(int argc, char *argv[])
+	{
+	BN_CTX *ctx=NULL;
+	int ret=1;
+	BIO *out;
+
+	CRYPTO_malloc_debug_init();
+	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
+	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+#ifdef OPENSSL_SYS_WIN32
+	CRYPTO_malloc_init();
+#endif
+
+	RAND_seed(rnd_seed, sizeof rnd_seed);
+
+	out=BIO_new(BIO_s_file());
+	if (out == NULL) EXIT(1);
+	BIO_set_fp(out,stdout,BIO_NOCLOSE);
+
+	if ((ctx=BN_CTX_new()) == NULL) goto err;
+
+	/* NIST PRIME CURVES TESTS */
+	if (!test_ecdh_curve(NID_X9_62_prime192v1, "NIST Prime-Curve P-192", ctx, out)) goto err;
+	if (!test_ecdh_curve(NID_secp224r1, "NIST Prime-Curve P-224", ctx, out)) goto err;
+	if (!test_ecdh_curve(NID_X9_62_prime256v1, "NIST Prime-Curve P-256", ctx, out)) goto err;
+	if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out)) goto err;
+	if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out)) goto err;
+	/* NIST BINARY CURVES TESTS */
+	if (!test_ecdh_curve(NID_sect163k1, "NIST Binary-Curve K-163", ctx, out)) goto err;
+	if (!test_ecdh_curve(NID_sect163r2, "NIST Binary-Curve B-163", ctx, out)) goto err;
+	if (!test_ecdh_curve(NID_sect233k1, "NIST Binary-Curve K-233", ctx, out)) goto err;
+	if (!test_ecdh_curve(NID_sect233r1, "NIST Binary-Curve B-233", ctx, out)) goto err;
+	if (!test_ecdh_curve(NID_sect283k1, "NIST Binary-Curve K-283", ctx, out)) goto err;
+	if (!test_ecdh_curve(NID_sect283r1, "NIST Binary-Curve B-283", ctx, out)) goto err;
+	if (!test_ecdh_curve(NID_sect409k1, "NIST Binary-Curve K-409", ctx, out)) goto err;
+	if (!test_ecdh_curve(NID_sect409r1, "NIST Binary-Curve B-409", ctx, out)) goto err;
+	if (!test_ecdh_curve(NID_sect571k1, "NIST Binary-Curve K-571", ctx, out)) goto err;
+	if (!test_ecdh_curve(NID_sect571r1, "NIST Binary-Curve B-571", ctx, out)) goto err;
+
+	ret = 0;
+
+err:
+	ERR_print_errors_fp(stderr);
+	if (ctx) BN_CTX_free(ctx);
+	BIO_free(out);
+	CRYPTO_cleanup_all_ex_data();
+	ERR_remove_thread_state(NULL);
+	CRYPTO_mem_leaks_fp(stderr);
+	EXIT(ret);
+	return(ret);
+	}
+
+#if 0
+static void MS_CALLBACK cb(int p, int n, void *arg)
+	{
+	char c='*';
+
+	if (p == 0) c='.';
+	if (p == 1) c='+';
+	if (p == 2) c='*';
+	if (p == 3) c='\n';
+	BIO_write((BIO *)arg,&c,1);
+	(void)BIO_flush((BIO *)arg);
+#ifdef LINT
+	p=n;
+#endif
+	}
+#endif
+#endif
diff --git a/openssl/crypto/ecdh/ech_err.c b/openssl/crypto/ecdh/ech_err.c
new file mode 100644
index 0000000..6f4b0c9
--- /dev/null
+++ b/openssl/crypto/ecdh/ech_err.c
@@ -0,0 +1,98 @@
+/* crypto/ecdh/ech_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ecdh.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDH,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDH,0,reason)
+
+static ERR_STRING_DATA ECDH_str_functs[]=
+	{
+{ERR_FUNC(ECDH_F_ECDH_COMPUTE_KEY),	"ECDH_compute_key"},
+{ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD),	"ECDH_DATA_new_method"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA ECDH_str_reasons[]=
+	{
+{ERR_REASON(ECDH_R_KDF_FAILED)           ,"KDF failed"},
+{ERR_REASON(ECDH_R_NO_PRIVATE_VALUE)     ,"no private value"},
+{ERR_REASON(ECDH_R_POINT_ARITHMETIC_FAILURE),"point arithmetic failure"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_ECDH_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(ECDH_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,ECDH_str_functs);
+		ERR_load_strings(0,ECDH_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/ecdh/ech_key.c b/openssl/crypto/ecdh/ech_key.c
new file mode 100644
index 0000000..f44da92
--- /dev/null
+++ b/openssl/crypto/ecdh/ech_key.c
@@ -0,0 +1,83 @@
+/* crypto/ecdh/ecdh_key.c */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The ECDH software is originally written by Douglas Stebila of
+ * Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "ech_locl.h"
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
+	EC_KEY *eckey,
+	void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen))
+{
+	ECDH_DATA *ecdh = ecdh_check(eckey);
+	if (ecdh == NULL)
+		return 0;
+	return ecdh->meth->compute_key(out, outlen, pub_key, eckey, KDF);
+}
diff --git a/openssl/crypto/ecdh/ech_lib.c b/openssl/crypto/ecdh/ech_lib.c
new file mode 100644
index 0000000..4d8ea03
--- /dev/null
+++ b/openssl/crypto/ecdh/ech_lib.c
@@ -0,0 +1,246 @@
+/* crypto/ecdh/ech_lib.c */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The ECDH software is originally written by Douglas Stebila of
+ * Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "ech_locl.h"
+#include <string.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/err.h>
+
+const char ECDH_version[]="ECDH" OPENSSL_VERSION_PTEXT;
+
+static const ECDH_METHOD *default_ECDH_method = NULL;
+
+static void *ecdh_data_new(void);
+static void *ecdh_data_dup(void *);
+static void  ecdh_data_free(void *);
+
+void ECDH_set_default_method(const ECDH_METHOD *meth)
+	{
+	default_ECDH_method = meth;
+	}
+
+const ECDH_METHOD *ECDH_get_default_method(void)
+	{
+	if(!default_ECDH_method) 
+		default_ECDH_method = ECDH_OpenSSL();
+	return default_ECDH_method;
+	}
+
+int ECDH_set_method(EC_KEY *eckey, const ECDH_METHOD *meth)
+	{
+	ECDH_DATA *ecdh;
+
+	ecdh = ecdh_check(eckey);
+
+	if (ecdh == NULL)
+		return 0;
+
+#if 0
+        mtmp = ecdh->meth;
+        if (mtmp->finish)
+		mtmp->finish(eckey);
+#endif
+#ifndef OPENSSL_NO_ENGINE
+	if (ecdh->engine)
+		{
+		ENGINE_finish(ecdh->engine);
+		ecdh->engine = NULL;
+		}
+#endif
+        ecdh->meth = meth;
+#if 0
+        if (meth->init) 
+		meth->init(eckey);
+#endif
+        return 1;
+	}
+
+static ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine)
+	{
+	ECDH_DATA *ret;
+
+	ret=(ECDH_DATA *)OPENSSL_malloc(sizeof(ECDH_DATA));
+	if (ret == NULL)
+		{
+		ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+
+	ret->init = NULL;
+
+	ret->meth = ECDH_get_default_method();
+	ret->engine = engine;
+#ifndef OPENSSL_NO_ENGINE
+	if (!ret->engine)
+		ret->engine = ENGINE_get_default_ECDH();
+	if (ret->engine)
+		{
+		ret->meth = ENGINE_get_ECDH(ret->engine);
+		if (!ret->meth)
+			{
+			ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_ENGINE_LIB);
+			ENGINE_finish(ret->engine);
+			OPENSSL_free(ret);
+			return NULL;
+			}
+		}
+#endif
+
+	ret->flags = ret->meth->flags;
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data);
+#if 0
+	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
+		{
+		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data);
+		OPENSSL_free(ret);
+		ret=NULL;
+		}
+#endif	
+	return(ret);
+	}
+
+static void *ecdh_data_new(void)
+	{
+	return (void *)ECDH_DATA_new_method(NULL);
+	}
+
+static void *ecdh_data_dup(void *data)
+{
+	ECDH_DATA *r = (ECDH_DATA *)data;
+
+	/* XXX: dummy operation */
+	if (r == NULL)
+		return NULL;
+
+	return (void *)ecdh_data_new();
+}
+
+void ecdh_data_free(void *data)
+	{
+	ECDH_DATA *r = (ECDH_DATA *)data;
+
+#ifndef OPENSSL_NO_ENGINE
+	if (r->engine)
+		ENGINE_finish(r->engine);
+#endif
+
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, r, &r->ex_data);
+
+	OPENSSL_cleanse((void *)r, sizeof(ECDH_DATA));
+
+	OPENSSL_free(r);
+	}
+
+ECDH_DATA *ecdh_check(EC_KEY *key)
+	{
+	ECDH_DATA *ecdh_data;
+ 
+	void *data = EC_KEY_get_key_method_data(key, ecdh_data_dup,
+					ecdh_data_free, ecdh_data_free);
+	if (data == NULL)
+	{
+		ecdh_data = (ECDH_DATA *)ecdh_data_new();
+		if (ecdh_data == NULL)
+			return NULL;
+		EC_KEY_insert_key_method_data(key, (void *)ecdh_data,
+			ecdh_data_dup, ecdh_data_free, ecdh_data_free);
+	}
+	else
+		ecdh_data = (ECDH_DATA *)data;
+	
+
+	return ecdh_data;
+	}
+
+int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+	{
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDH, argl, argp,
+				new_func, dup_func, free_func);
+	}
+
+int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg)
+	{
+	ECDH_DATA *ecdh;
+	ecdh = ecdh_check(d);
+	if (ecdh == NULL)
+		return 0;
+	return(CRYPTO_set_ex_data(&ecdh->ex_data,idx,arg));
+	}
+
+void *ECDH_get_ex_data(EC_KEY *d, int idx)
+	{
+	ECDH_DATA *ecdh;
+	ecdh = ecdh_check(d);
+	if (ecdh == NULL)
+		return NULL;
+	return(CRYPTO_get_ex_data(&ecdh->ex_data,idx));
+	}
diff --git a/openssl/crypto/ecdh/ech_locl.h b/openssl/crypto/ecdh/ech_locl.h
new file mode 100644
index 0000000..f658526
--- /dev/null
+++ b/openssl/crypto/ecdh/ech_locl.h
@@ -0,0 +1,94 @@
+/* crypto/ecdh/ech_locl.h */
+/* ====================================================================
+ * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_ECH_LOCL_H
+#define HEADER_ECH_LOCL_H
+
+#include <openssl/ecdh.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+struct ecdh_method 
+	{
+	const char *name;
+	int (*compute_key)(void *key, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh,
+	                   void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen));
+#if 0
+	int (*init)(EC_KEY *eckey);
+	int (*finish)(EC_KEY *eckey);
+#endif
+	int flags;
+	char *app_data;
+	};
+
+typedef struct ecdh_data_st {
+	/* EC_KEY_METH_DATA part */
+	int (*init)(EC_KEY *);
+	/* method specific part */
+	ENGINE	*engine;
+	int	flags;
+	const ECDH_METHOD *meth;
+	CRYPTO_EX_DATA ex_data;
+} ECDH_DATA;
+
+ECDH_DATA *ecdh_check(EC_KEY *);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* HEADER_ECH_LOCL_H */
diff --git a/openssl/crypto/ecdh/ech_ossl.c b/openssl/crypto/ecdh/ech_ossl.c
new file mode 100644
index 0000000..2a40ff1
--- /dev/null
+++ b/openssl/crypto/ecdh/ech_ossl.c
@@ -0,0 +1,213 @@
+/* crypto/ecdh/ech_ossl.c */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The ECDH software is originally written by Douglas Stebila of
+ * Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <string.h>
+#include <limits.h>
+
+#include "cryptlib.h"
+
+#include "ech_locl.h"
+#include <openssl/err.h>
+#include <openssl/sha.h>
+#include <openssl/obj_mac.h>
+#include <openssl/bn.h>
+
+static int ecdh_compute_key(void *out, size_t len, const EC_POINT *pub_key,
+	EC_KEY *ecdh, 
+	void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen));
+
+static ECDH_METHOD openssl_ecdh_meth = {
+	"OpenSSL ECDH method",
+	ecdh_compute_key,
+#if 0
+	NULL, /* init     */
+	NULL, /* finish   */
+#endif
+	0,    /* flags    */
+	NULL  /* app_data */
+};
+
+const ECDH_METHOD *ECDH_OpenSSL(void)
+	{
+	return &openssl_ecdh_meth;
+	}
+
+
+/* This implementation is based on the following primitives in the IEEE 1363 standard:
+ *  - ECKAS-DH1
+ *  - ECSVDP-DH
+ * Finally an optional KDF is applied.
+ */
+static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
+	EC_KEY *ecdh,
+	void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen))
+	{
+	BN_CTX *ctx;
+	EC_POINT *tmp=NULL;
+	BIGNUM *x=NULL, *y=NULL;
+	const BIGNUM *priv_key;
+	const EC_GROUP* group;
+	int ret= -1;
+	size_t buflen, len;
+	unsigned char *buf=NULL;
+
+	if (outlen > INT_MAX)
+		{
+		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE); /* sort of, anyway */
+		return -1;
+		}
+
+	if ((ctx = BN_CTX_new()) == NULL) goto err;
+	BN_CTX_start(ctx);
+	x = BN_CTX_get(ctx);
+	y = BN_CTX_get(ctx);
+	
+	priv_key = EC_KEY_get0_private_key(ecdh);
+	if (priv_key == NULL)
+		{
+		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);
+		goto err;
+		}
+
+	group = EC_KEY_get0_group(ecdh);
+	if ((tmp=EC_POINT_new(group)) == NULL)
+		{
+		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) 
+		{
+		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
+		goto err;
+		}
+		
+	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) 
+		{
+		if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) 
+			{
+			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
+			goto err;
+			}
+		}
+	else
+		{
+		if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx)) 
+			{
+			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
+			goto err;
+			}
+		}
+
+	buflen = (EC_GROUP_get_degree(group) + 7)/8;
+	len = BN_num_bytes(x);
+	if (len > buflen)
+		{
+		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_INTERNAL_ERROR);
+		goto err;
+		}
+	if ((buf = OPENSSL_malloc(buflen)) == NULL)
+		{
+		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	
+	memset(buf, 0, buflen - len);
+	if (len != (size_t)BN_bn2bin(x, buf + buflen - len))
+		{
+		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
+		goto err;
+		}
+
+	if (KDF != 0)
+		{
+		if (KDF(buf, buflen, out, &outlen) == NULL)
+			{
+			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_KDF_FAILED);
+			goto err;
+			}
+		ret = outlen;
+		}
+	else
+		{
+		/* no KDF, just copy as much as we can */
+		if (outlen > buflen)
+			outlen = buflen;
+		memcpy(out, buf, outlen);
+		ret = outlen;
+		}
+	
+err:
+	if (tmp) EC_POINT_free(tmp);
+	if (ctx) BN_CTX_end(ctx);
+	if (ctx) BN_CTX_free(ctx);
+	if (buf) OPENSSL_free(buf);
+	return(ret);
+	}
diff --git a/openssl/crypto/ecdsa/Makefile b/openssl/crypto/ecdsa/Makefile
new file mode 100644
index 0000000..e89e0c0
--- /dev/null
+++ b/openssl/crypto/ecdsa/Makefile
@@ -0,0 +1,140 @@
+#
+# crypto/ecdsa/Makefile
+#
+
+DIR=	ecdsa
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g -Wall
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=ecdsatest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=	ecs_lib.c ecs_asn1.c ecs_ossl.c ecs_sign.c ecs_vrf.c ecs_err.c
+
+LIBOBJ=	ecs_lib.o ecs_asn1.o ecs_ossl.o ecs_sign.o ecs_vrf.o ecs_err.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= ecdsa.h
+HEADER=	ecs_locl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+ecs_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+ecs_asn1.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+ecs_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ecs_asn1.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+ecs_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+ecs_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ecs_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ecs_asn1.o: ../../include/openssl/symhacks.h ecs_asn1.c ecs_locl.h
+ecs_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ecs_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+ecs_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdsa.h
+ecs_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ecs_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+ecs_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+ecs_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ecs_err.o: ecs_err.c
+ecs_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ecs_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+ecs_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+ecs_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+ecs_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+ecs_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+ecs_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ecs_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+ecs_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ecs_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+ecs_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ecs_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+ecs_lib.o: ../../include/openssl/x509_vfy.h ecs_lib.c ecs_locl.h
+ecs_ossl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ecs_ossl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+ecs_ossl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ecs_ossl.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+ecs_ossl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ecs_ossl.o: ../../include/openssl/opensslconf.h
+ecs_ossl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ecs_ossl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ecs_ossl.o: ../../include/openssl/symhacks.h ecs_locl.h ecs_ossl.c
+ecs_sign.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ecs_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+ecs_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ecs_sign.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ecs_sign.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
+ecs_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ecs_sign.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+ecs_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ecs_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+ecs_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+ecs_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ecs_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ecs_sign.o: ecs_locl.h ecs_sign.c
+ecs_vrf.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ecs_vrf.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+ecs_vrf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ecs_vrf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ecs_vrf.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
+ecs_vrf.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ecs_vrf.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+ecs_vrf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ecs_vrf.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+ecs_vrf.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ecs_vrf.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+ecs_vrf.o: ../../include/openssl/x509_vfy.h ecs_locl.h ecs_vrf.c
diff --git a/openssl/crypto/ecdsa/ecdsa.h b/openssl/crypto/ecdsa/ecdsa.h
new file mode 100644
index 0000000..e61c539
--- /dev/null
+++ b/openssl/crypto/ecdsa/ecdsa.h
@@ -0,0 +1,258 @@
+/* crypto/ecdsa/ecdsa.h */
+/**
+ * \file   crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions
+ * \author Written by Nils Larsch for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef HEADER_ECDSA_H
+#define HEADER_ECDSA_H
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_ECDSA
+#error ECDSA is disabled.
+#endif
+
+#include <openssl/ec.h>
+#include <openssl/ossl_typ.h>
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct ECDSA_SIG_st
+	{
+	BIGNUM *r;
+	BIGNUM *s;
+	} ECDSA_SIG;
+
+/** Allocates and initialize a ECDSA_SIG structure
+ *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
+ */
+ECDSA_SIG *ECDSA_SIG_new(void);
+
+/** frees a ECDSA_SIG structure
+ *  \param  sig  pointer to the ECDSA_SIG structure
+ */
+void	  ECDSA_SIG_free(ECDSA_SIG *sig);
+
+/** DER encode content of ECDSA_SIG object (note: this function modifies *pp
+ *  (*pp += length of the DER encoded signature)).
+ *  \param  sig  pointer to the ECDSA_SIG object
+ *  \param  pp   pointer to a unsigned char pointer for the output or NULL
+ *  \return the length of the DER encoded ECDSA_SIG object or 0 
+ */
+int	  i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
+
+/** Decodes a DER encoded ECDSA signature (note: this function changes *pp
+ *  (*pp += len)). 
+ *  \param  sig  pointer to ECDSA_SIG pointer (may be NULL)
+ *  \param  pp   memory buffer with the DER encoded signature
+ *  \param  len  length of the buffer
+ *  \return pointer to the decoded ECDSA_SIG structure (or NULL)
+ */
+ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len);
+
+/** Computes the ECDSA signature of the given hash value using
+ *  the supplied private key and returns the created signature.
+ *  \param  dgst      pointer to the hash value
+ *  \param  dgst_len  length of the hash value
+ *  \param  eckey     EC_KEY object containing a private EC key
+ *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
+ */
+ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst,int dgst_len,EC_KEY *eckey);
+
+/** Computes ECDSA signature of a given hash value using the supplied
+ *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ *  \param  dgst     pointer to the hash value to sign
+ *  \param  dgstlen  length of the hash value
+ *  \param  kinv     BIGNUM with a pre-computed inverse k (optional)
+ *  \param  rp       BIGNUM with a pre-computed rp value (optioanl), 
+ *                   see ECDSA_sign_setup
+ *  \param  eckey    EC_KEY object containing a private EC key
+ *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
+ */
+ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, 
+		const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey);
+
+/** Verifies that the supplied signature is a valid ECDSA
+ *  signature of the supplied hash value using the supplied public key.
+ *  \param  dgst      pointer to the hash value
+ *  \param  dgst_len  length of the hash value
+ *  \param  sig       ECDSA_SIG structure
+ *  \param  eckey     EC_KEY object containing a public EC key
+ *  \return 1 if the signature is valid, 0 if the signature is invalid
+ *          and -1 on error
+ */
+int	  ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
+		const ECDSA_SIG *sig, EC_KEY* eckey);
+
+const ECDSA_METHOD *ECDSA_OpenSSL(void);
+
+/** Sets the default ECDSA method
+ *  \param  meth  new default ECDSA_METHOD
+ */
+void	  ECDSA_set_default_method(const ECDSA_METHOD *meth);
+
+/** Returns the default ECDSA method
+ *  \return pointer to ECDSA_METHOD structure containing the default method
+ */
+const ECDSA_METHOD *ECDSA_get_default_method(void);
+
+/** Sets method to be used for the ECDSA operations
+ *  \param  eckey  EC_KEY object
+ *  \param  meth   new method
+ *  \return 1 on success and 0 otherwise 
+ */
+int 	  ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth);
+
+/** Returns the maximum length of the DER encoded signature
+ *  \param  eckey  EC_KEY object
+ *  \return numbers of bytes required for the DER encoded signature
+ */
+int	  ECDSA_size(const EC_KEY *eckey);
+
+/** Precompute parts of the signing operation
+ *  \param  eckey  EC_KEY object containing a private EC key
+ *  \param  ctx    BN_CTX object (optional)
+ *  \param  kinv   BIGNUM pointer for the inverse of k
+ *  \param  rp     BIGNUM pointer for x coordinate of k * generator
+ *  \return 1 on success and 0 otherwise
+ */
+int 	  ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, 
+		BIGNUM **rp);
+
+/** Computes ECDSA signature of a given hash value using the supplied
+ *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ *  \param  type     this parameter is ignored
+ *  \param  dgst     pointer to the hash value to sign
+ *  \param  dgstlen  length of the hash value
+ *  \param  sig      memory for the DER encoded created signature
+ *  \param  siglen   pointer to the length of the returned signature
+ *  \param  eckey    EC_KEY object containing a private EC key
+ *  \return 1 on success and 0 otherwise
+ */
+int	  ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, 
+		unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);
+
+
+/** Computes ECDSA signature of a given hash value using the supplied
+ *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ *  \param  type     this parameter is ignored
+ *  \param  dgst     pointer to the hash value to sign
+ *  \param  dgstlen  length of the hash value
+ *  \param  sig      buffer to hold the DER encoded signature
+ *  \param  siglen   pointer to the length of the returned signature
+ *  \param  kinv     BIGNUM with a pre-computed inverse k (optional)
+ *  \param  rp       BIGNUM with a pre-computed rp value (optioanl), 
+ *                   see ECDSA_sign_setup
+ *  \param  eckey    EC_KEY object containing a private EC key
+ *  \return 1 on success and 0 otherwise
+ */
+int	  ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, 
+		unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv,
+		const BIGNUM *rp, EC_KEY *eckey);
+
+/** Verifies that the given signature is valid ECDSA signature
+ *  of the supplied hash value using the specified public key.
+ *  \param  type     this parameter is ignored
+ *  \param  dgst     pointer to the hash value 
+ *  \param  dgstlen  length of the hash value
+ *  \param  sig      pointer to the DER encoded signature
+ *  \param  siglen   length of the DER encoded signature
+ *  \param  eckey    EC_KEY object containing a public EC key
+ *  \return 1 if the signature is valid, 0 if the signature is invalid
+ *          and -1 on error
+ */
+int 	  ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, 
+		const unsigned char *sig, int siglen, EC_KEY *eckey);
+
+/* the standard ex_data functions */
+int 	  ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new 
+		*new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int 	  ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg);
+void 	  *ECDSA_get_ex_data(EC_KEY *d, int idx);
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_ECDSA_strings(void);
+
+/* Error codes for the ECDSA functions. */
+
+/* Function codes. */
+#define ECDSA_F_ECDSA_DATA_NEW_METHOD			 100
+#define ECDSA_F_ECDSA_DO_SIGN				 101
+#define ECDSA_F_ECDSA_DO_VERIFY				 102
+#define ECDSA_F_ECDSA_SIGN_SETUP			 103
+
+/* Reason codes. */
+#define ECDSA_R_BAD_SIGNATURE				 100
+#define ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 101
+#define ECDSA_R_ERR_EC_LIB				 102
+#define ECDSA_R_MISSING_PARAMETERS			 103
+#define ECDSA_R_NEED_NEW_SETUP_VALUES			 106
+#define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED		 104
+#define ECDSA_R_SIGNATURE_MALLOC_FAILED			 105
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/ecdsa/ecdsatest.c b/openssl/crypto/ecdsa/ecdsatest.c
new file mode 100644
index 0000000..54cfb8c
--- /dev/null
+++ b/openssl/crypto/ecdsa/ecdsatest.c
@@ -0,0 +1,570 @@
+/* crypto/ecdsa/ecdsatest.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by 
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_ECDSA is defined */
+
+#ifdef OPENSSL_NO_ECDSA
+int main(int argc, char * argv[])
+	{
+	puts("Elliptic curves are disabled.");
+	return 0;
+	}
+#else
+
+#include <openssl/crypto.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/ecdsa.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+static const char rnd_seed[] = "string to make the random number generator "
+	"think it has entropy";
+
+/* declaration of the test functions */
+int x9_62_tests(BIO *);
+int x9_62_test_internal(BIO *out, int nid, const char *r, const char *s);
+int test_builtin(BIO *);
+
+/* functions to change the RAND_METHOD */
+int change_rand(void);
+int restore_rand(void);
+int fbytes(unsigned char *buf, int num);
+
+RAND_METHOD	fake_rand;
+const RAND_METHOD *old_rand;
+
+int change_rand(void)
+	{
+	/* save old rand method */
+	if ((old_rand = RAND_get_rand_method()) == NULL)
+		return 0;
+
+	fake_rand.seed    = old_rand->seed;
+	fake_rand.cleanup = old_rand->cleanup;
+	fake_rand.add     = old_rand->add;
+	fake_rand.status  = old_rand->status;
+	/* use own random function */
+	fake_rand.bytes      = fbytes;
+	fake_rand.pseudorand = old_rand->bytes;
+	/* set new RAND_METHOD */
+	if (!RAND_set_rand_method(&fake_rand))
+		return 0;
+	return 1;
+	}
+
+int restore_rand(void)
+	{
+	if (!RAND_set_rand_method(old_rand))
+		return 0;
+	else
+		return 1;
+	}
+
+static int fbytes_counter = 0;
+static const char *numbers[8] = {
+	"651056770906015076056810763456358567190100156695615665659",
+	"6140507067065001063065065565667405560006161556565665656654",
+	"8763001015071075675010661307616710783570106710677817767166"
+	"71676178726717",
+	"7000000175690566466555057817571571075705015757757057795755"
+	"55657156756655",
+	"1275552191113212300012030439187146164646146646466749494799",
+	"1542725565216523985789236956265265265235675811949404040041",
+	"1456427555219115346513212300075341203043918714616464614664"
+	"64667494947990",
+	"1712787255652165239672857892369562652652652356758119494040"
+	"40041670216363"};
+
+int fbytes(unsigned char *buf, int num)
+	{
+	int	ret;
+	BIGNUM	*tmp = NULL;
+
+	if (fbytes_counter >= 8)
+		return 0;
+	tmp = BN_new();
+	if (!tmp)
+		return 0;
+	if (!BN_dec2bn(&tmp, numbers[fbytes_counter]))
+		{
+		BN_free(tmp);
+		return 0;
+		}
+	fbytes_counter ++;
+	if (num != BN_num_bytes(tmp) || !BN_bn2bin(tmp, buf))
+		ret = 0;
+	else 
+		ret = 1;
+	if (tmp)
+		BN_free(tmp);
+	return ret;
+	}
+
+/* some tests from the X9.62 draft */
+int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in)
+	{
+	int	ret = 0;
+	const char message[] = "abc";
+	unsigned char digest[20];
+	unsigned int  dgst_len = 0;
+	EVP_MD_CTX md_ctx;
+	EC_KEY    *key = NULL;
+	ECDSA_SIG *signature = NULL;
+	BIGNUM    *r = NULL, *s = NULL;
+
+	EVP_MD_CTX_init(&md_ctx);
+	/* get the message digest */
+	EVP_DigestInit(&md_ctx, EVP_ecdsa());
+	EVP_DigestUpdate(&md_ctx, (const void*)message, 3);
+	EVP_DigestFinal(&md_ctx, digest, &dgst_len);
+
+	BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid));
+	/* create the key */
+	if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
+		goto x962_int_err;
+	if (!EC_KEY_generate_key(key))
+		goto x962_int_err;
+	BIO_printf(out, ".");
+	(void)BIO_flush(out);
+	/* create the signature */
+	signature = ECDSA_do_sign(digest, 20, key);
+	if (signature == NULL)
+		goto x962_int_err;
+	BIO_printf(out, ".");
+	(void)BIO_flush(out);
+	/* compare the created signature with the expected signature */
+	if ((r = BN_new()) == NULL || (s = BN_new()) == NULL)
+		goto x962_int_err;
+	if (!BN_dec2bn(&r, r_in) ||
+	    !BN_dec2bn(&s, s_in))
+		goto x962_int_err;
+	if (BN_cmp(signature->r ,r) || BN_cmp(signature->s, s))
+		goto x962_int_err;
+	BIO_printf(out, ".");
+	(void)BIO_flush(out);
+	/* verify the signature */
+	if (ECDSA_do_verify(digest, 20, signature, key) != 1)
+		goto x962_int_err;
+	BIO_printf(out, ".");
+	(void)BIO_flush(out);
+
+	BIO_printf(out, " ok\n");
+	ret = 1;
+x962_int_err:
+	if (!ret)
+		BIO_printf(out, " failed\n");
+	if (key)
+		EC_KEY_free(key);
+	if (signature)
+		ECDSA_SIG_free(signature);
+	if (r)
+		BN_free(r);
+	if (s)
+		BN_free(s);
+	EVP_MD_CTX_cleanup(&md_ctx);
+	return ret;
+	}
+
+int x9_62_tests(BIO *out)
+	{
+	int ret = 0;
+
+	BIO_printf(out, "some tests from X9.62:\n");
+
+	/* set own rand method */
+	if (!change_rand())
+		goto x962_err;
+
+	if (!x9_62_test_internal(out, NID_X9_62_prime192v1,
+		"3342403536405981729393488334694600415596881826869351677613",
+		"5735822328888155254683894997897571951568553642892029982342"))
+		goto x962_err;
+	if (!x9_62_test_internal(out, NID_X9_62_prime239v1,
+		"3086361431751678114926225473006680188549593787585317781474"
+		"62058306432176",
+		"3238135532097973577080787768312505059318910517550078427819"
+		"78505179448783"))
+		goto x962_err;
+	if (!x9_62_test_internal(out, NID_X9_62_c2tnb191v1,
+		"87194383164871543355722284926904419997237591535066528048",
+		"308992691965804947361541664549085895292153777025772063598"))
+		goto x962_err;
+	if (!x9_62_test_internal(out, NID_X9_62_c2tnb239v1,
+		"2159633321041961198501834003903461262881815148684178964245"
+		"5876922391552",
+		"1970303740007316867383349976549972270528498040721988191026"
+		"49413465737174"))
+		goto x962_err;
+
+	ret = 1;
+x962_err:
+	if (!restore_rand())
+		ret = 0;
+	return ret;
+	}
+
+int test_builtin(BIO *out)
+	{
+	EC_builtin_curve *curves = NULL;
+	size_t		crv_len = 0, n = 0;
+	EC_KEY		*eckey = NULL, *wrong_eckey = NULL;
+	EC_GROUP	*group;
+	ECDSA_SIG	*ecdsa_sig = NULL;
+	unsigned char	digest[20], wrong_digest[20];
+	unsigned char	*signature = NULL;
+	unsigned char	*sig_ptr;
+	unsigned char	*raw_buf = NULL;
+	unsigned int	sig_len, degree, r_len, s_len, bn_len, buf_len;
+	int		nid, ret =  0;
+	
+	/* fill digest values with some random data */
+	if (!RAND_pseudo_bytes(digest, 20) ||
+	    !RAND_pseudo_bytes(wrong_digest, 20))
+		{
+		BIO_printf(out, "ERROR: unable to get random data\n");
+		goto builtin_err;
+		}
+
+	/* create and verify a ecdsa signature with every availble curve
+	 * (with ) */
+	BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() "
+		"with some internal curves:\n");
+
+	/* get a list of all internal curves */
+	crv_len = EC_get_builtin_curves(NULL, 0);
+
+	curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);
+
+	if (curves == NULL)
+		{
+		BIO_printf(out, "malloc error\n");
+		goto builtin_err;
+		}
+	
+	if (!EC_get_builtin_curves(curves, crv_len))
+		{
+		BIO_printf(out, "unable to get internal curves\n");
+		goto builtin_err;
+		}
+
+	/* now create and verify a signature for every curve */
+	for (n = 0; n < crv_len; n++)
+		{
+		unsigned char dirt, offset;
+
+		nid = curves[n].nid;
+		if (nid == NID_ipsec4)
+			continue;
+		/* create new ecdsa key (== EC_KEY) */
+		if ((eckey = EC_KEY_new()) == NULL)
+			goto builtin_err;
+		group = EC_GROUP_new_by_curve_name(nid);
+		if (group == NULL)
+			goto builtin_err;
+		if (EC_KEY_set_group(eckey, group) == 0)
+			goto builtin_err;
+		EC_GROUP_free(group);
+		degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey));
+		if (degree < 160)
+			/* drop the curve */ 
+			{
+			EC_KEY_free(eckey);
+			eckey = NULL;
+			continue;
+			}
+		BIO_printf(out, "%s: ", OBJ_nid2sn(nid));
+		/* create key */
+		if (!EC_KEY_generate_key(eckey))
+			{
+			BIO_printf(out, " failed\n");
+			goto builtin_err;
+			}
+		/* create second key */
+		if ((wrong_eckey = EC_KEY_new()) == NULL)
+			goto builtin_err;
+		group = EC_GROUP_new_by_curve_name(nid);
+		if (group == NULL)
+			goto builtin_err;
+		if (EC_KEY_set_group(wrong_eckey, group) == 0)
+			goto builtin_err;
+		EC_GROUP_free(group);
+		if (!EC_KEY_generate_key(wrong_eckey))
+			{
+			BIO_printf(out, " failed\n");
+			goto builtin_err;
+			}
+
+		BIO_printf(out, ".");
+		(void)BIO_flush(out);
+		/* check key */
+		if (!EC_KEY_check_key(eckey))
+			{
+			BIO_printf(out, " failed\n");
+			goto builtin_err;
+			}
+		BIO_printf(out, ".");
+		(void)BIO_flush(out);
+		/* create signature */
+		sig_len = ECDSA_size(eckey);
+		if ((signature = OPENSSL_malloc(sig_len)) == NULL)
+			goto builtin_err;
+                if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey))
+			{
+			BIO_printf(out, " failed\n");
+			goto builtin_err;
+			}
+		BIO_printf(out, ".");
+		(void)BIO_flush(out);
+		/* verify signature */
+		if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1)
+			{
+			BIO_printf(out, " failed\n");
+			goto builtin_err;
+			}
+		BIO_printf(out, ".");
+		(void)BIO_flush(out);
+		/* verify signature with the wrong key */
+		if (ECDSA_verify(0, digest, 20, signature, sig_len, 
+			wrong_eckey) == 1)
+			{
+			BIO_printf(out, " failed\n");
+			goto builtin_err;
+			}
+		BIO_printf(out, ".");
+		(void)BIO_flush(out);
+		/* wrong digest */
+		if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len,
+			eckey) == 1)
+			{
+			BIO_printf(out, " failed\n");
+			goto builtin_err;
+			}
+		BIO_printf(out, ".");
+		(void)BIO_flush(out);
+		/* wrong length */
+		if (ECDSA_verify(0, digest, 20, signature, sig_len - 1,
+			eckey) == 1)
+			{
+			BIO_printf(out, " failed\n");
+			goto builtin_err;
+			}
+		BIO_printf(out, ".");
+		(void)BIO_flush(out);
+
+		/* Modify a single byte of the signature: to ensure we don't
+		 * garble the ASN1 structure, we read the raw signature and
+		 * modify a byte in one of the bignums directly. */
+		sig_ptr = signature;
+		if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL)
+			{
+			BIO_printf(out, " failed\n");
+			goto builtin_err;
+			}
+
+		/* Store the two BIGNUMs in raw_buf. */
+		r_len = BN_num_bytes(ecdsa_sig->r);
+		s_len = BN_num_bytes(ecdsa_sig->s);
+		bn_len = (degree + 7) / 8;
+		if ((r_len > bn_len) || (s_len > bn_len))
+			{
+			BIO_printf(out, " failed\n");
+			goto builtin_err;
+			}
+		buf_len = 2 * bn_len;
+		if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL)
+			goto builtin_err;
+		/* Pad the bignums with leading zeroes. */
+		memset(raw_buf, 0, buf_len);
+		BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len);
+		BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len);
+
+		/* Modify a single byte in the buffer. */
+		offset = raw_buf[10] % buf_len;
+		dirt   = raw_buf[11] ? raw_buf[11] : 1;
+		raw_buf[offset] ^= dirt;
+		/* Now read the BIGNUMs back in from raw_buf. */
+		if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
+			(BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
+			goto builtin_err;
+
+		sig_ptr = signature;
+		sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr);
+		if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1)
+			{
+			BIO_printf(out, " failed\n");
+			goto builtin_err;
+			}
+		/* Sanity check: undo the modification and verify signature. */
+		raw_buf[offset] ^= dirt;
+		if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
+			(BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
+			goto builtin_err;
+
+		sig_ptr = signature;
+		sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr);
+		if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1)
+			{
+			BIO_printf(out, " failed\n");
+			goto builtin_err;
+			}
+		BIO_printf(out, ".");
+		(void)BIO_flush(out);
+		
+		BIO_printf(out, " ok\n");
+		/* cleanup */
+		/* clean bogus errors */
+		ERR_clear_error();
+		OPENSSL_free(signature);
+		signature = NULL;
+		EC_KEY_free(eckey);
+		eckey = NULL;
+		EC_KEY_free(wrong_eckey);
+		wrong_eckey = NULL;
+		ECDSA_SIG_free(ecdsa_sig);
+		ecdsa_sig = NULL;
+		OPENSSL_free(raw_buf);
+		raw_buf = NULL;
+		}
+
+	ret = 1;	
+builtin_err:
+	if (eckey)
+		EC_KEY_free(eckey);
+	if (wrong_eckey)
+		EC_KEY_free(wrong_eckey);
+	if (ecdsa_sig)
+		ECDSA_SIG_free(ecdsa_sig);
+	if (signature)
+		OPENSSL_free(signature);
+	if (raw_buf)
+		OPENSSL_free(raw_buf);
+	if (curves)
+		OPENSSL_free(curves);
+
+	return ret;
+	}
+
+int main(void)
+	{
+	int 	ret = 1;
+	BIO	*out;
+
+	out = BIO_new_fp(stdout, BIO_NOCLOSE);
+	
+	/* enable memory leak checking unless explicitly disabled */
+	if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && 
+		(0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
+		{
+		CRYPTO_malloc_debug_init();
+		CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+		}
+	else
+		{
+		/* OPENSSL_DEBUG_MEMORY=off */
+		CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
+		}
+	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+	ERR_load_crypto_strings();
+
+	/* initialize the prng */
+	RAND_seed(rnd_seed, sizeof(rnd_seed));
+
+	/* the tests */
+	if (!x9_62_tests(out))  goto err;
+	if (!test_builtin(out)) goto err;
+	
+	ret = 0;
+err:	
+	if (ret) 	
+		BIO_printf(out, "\nECDSA test failed\n");
+	else 
+		BIO_printf(out, "\nECDSA test passed\n");
+	if (ret)
+		ERR_print_errors(out);
+	CRYPTO_cleanup_all_ex_data();
+	ERR_remove_thread_state(NULL);
+	ERR_free_strings();
+	CRYPTO_mem_leaks(out);
+	if (out != NULL)
+		BIO_free(out);
+	return ret;
+	}	
+#endif
diff --git a/openssl/crypto/ecdsa/ecs_asn1.c b/openssl/crypto/ecdsa/ecs_asn1.c
new file mode 100644
index 0000000..b295489
--- /dev/null
+++ b/openssl/crypto/ecdsa/ecs_asn1.c
@@ -0,0 +1,67 @@
+/* crypto/ecdsa/ecs_asn1.c */
+/* ====================================================================
+ * Copyright (c) 2000-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "ecs_locl.h"
+#include <openssl/err.h>
+#include <openssl/asn1t.h>
+
+ASN1_SEQUENCE(ECDSA_SIG) = {
+	ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM),
+	ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM)
+} ASN1_SEQUENCE_END(ECDSA_SIG)
+
+DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG)
+IMPLEMENT_ASN1_FUNCTIONS_const(ECDSA_SIG)
diff --git a/openssl/crypto/ecdsa/ecs_err.c b/openssl/crypto/ecdsa/ecs_err.c
new file mode 100644
index 0000000..98e38d5
--- /dev/null
+++ b/openssl/crypto/ecdsa/ecs_err.c
@@ -0,0 +1,104 @@
+/* crypto/ecdsa/ecs_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ecdsa.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDSA,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDSA,0,reason)
+
+static ERR_STRING_DATA ECDSA_str_functs[]=
+	{
+{ERR_FUNC(ECDSA_F_ECDSA_DATA_NEW_METHOD),	"ECDSA_DATA_NEW_METHOD"},
+{ERR_FUNC(ECDSA_F_ECDSA_DO_SIGN),	"ECDSA_do_sign"},
+{ERR_FUNC(ECDSA_F_ECDSA_DO_VERIFY),	"ECDSA_do_verify"},
+{ERR_FUNC(ECDSA_F_ECDSA_SIGN_SETUP),	"ECDSA_sign_setup"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA ECDSA_str_reasons[]=
+	{
+{ERR_REASON(ECDSA_R_BAD_SIGNATURE)       ,"bad signature"},
+{ERR_REASON(ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"},
+{ERR_REASON(ECDSA_R_ERR_EC_LIB)          ,"err ec lib"},
+{ERR_REASON(ECDSA_R_MISSING_PARAMETERS)  ,"missing parameters"},
+{ERR_REASON(ECDSA_R_NEED_NEW_SETUP_VALUES),"need new setup values"},
+{ERR_REASON(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED),"random number generation failed"},
+{ERR_REASON(ECDSA_R_SIGNATURE_MALLOC_FAILED),"signature malloc failed"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_ECDSA_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(ECDSA_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,ECDSA_str_functs);
+		ERR_load_strings(0,ECDSA_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/ecdsa/ecs_lib.c b/openssl/crypto/ecdsa/ecs_lib.c
new file mode 100644
index 0000000..2ebae3a
--- /dev/null
+++ b/openssl/crypto/ecdsa/ecs_lib.c
@@ -0,0 +1,259 @@
+/* crypto/ecdsa/ecs_lib.c */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+#include "ecs_locl.h"
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/err.h>
+#include <openssl/bn.h>
+
+const char ECDSA_version[]="ECDSA" OPENSSL_VERSION_PTEXT;
+
+static const ECDSA_METHOD *default_ECDSA_method = NULL;
+
+static void *ecdsa_data_new(void);
+static void *ecdsa_data_dup(void *);
+static void  ecdsa_data_free(void *);
+
+void ECDSA_set_default_method(const ECDSA_METHOD *meth)
+{
+	default_ECDSA_method = meth;
+}
+
+const ECDSA_METHOD *ECDSA_get_default_method(void)
+{
+	if(!default_ECDSA_method) 
+		default_ECDSA_method = ECDSA_OpenSSL();
+	return default_ECDSA_method;
+}
+
+int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth)
+{
+	ECDSA_DATA *ecdsa;
+
+	ecdsa = ecdsa_check(eckey);
+
+	if (ecdsa == NULL)
+		return 0;
+
+#ifndef OPENSSL_NO_ENGINE
+	if (ecdsa->engine)
+	{
+		ENGINE_finish(ecdsa->engine);
+		ecdsa->engine = NULL;
+	}
+#endif
+        ecdsa->meth = meth;
+
+        return 1;
+}
+
+static ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *engine)
+{
+	ECDSA_DATA *ret;
+
+	ret=(ECDSA_DATA *)OPENSSL_malloc(sizeof(ECDSA_DATA));
+	if (ret == NULL)
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+		return(NULL);
+	}
+
+	ret->init = NULL;
+
+	ret->meth = ECDSA_get_default_method();
+	ret->engine = engine;
+#ifndef OPENSSL_NO_ENGINE
+	if (!ret->engine)
+		ret->engine = ENGINE_get_default_ECDSA();
+	if (ret->engine)
+	{
+		ret->meth = ENGINE_get_ECDSA(ret->engine);
+		if (!ret->meth)
+		{
+			ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_ENGINE_LIB);
+			ENGINE_finish(ret->engine);
+			OPENSSL_free(ret);
+			return NULL;
+		}
+	}
+#endif
+
+	ret->flags = ret->meth->flags;
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data);
+#if 0
+	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
+	{
+		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data);
+		OPENSSL_free(ret);
+		ret=NULL;
+	}
+#endif	
+	return(ret);
+}
+
+static void *ecdsa_data_new(void)
+{
+	return (void *)ECDSA_DATA_new_method(NULL);
+}
+
+static void *ecdsa_data_dup(void *data)
+{
+	ECDSA_DATA *r = (ECDSA_DATA *)data;
+
+	/* XXX: dummy operation */
+	if (r == NULL)
+		return NULL;
+
+	return ecdsa_data_new();
+}
+
+static void ecdsa_data_free(void *data)
+{
+	ECDSA_DATA *r = (ECDSA_DATA *)data;
+
+#ifndef OPENSSL_NO_ENGINE
+	if (r->engine)
+		ENGINE_finish(r->engine);
+#endif
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, r, &r->ex_data);
+
+	OPENSSL_cleanse((void *)r, sizeof(ECDSA_DATA));
+
+	OPENSSL_free(r);
+}
+
+ECDSA_DATA *ecdsa_check(EC_KEY *key)
+{
+	ECDSA_DATA *ecdsa_data;
+ 
+	void *data = EC_KEY_get_key_method_data(key, ecdsa_data_dup,
+					ecdsa_data_free, ecdsa_data_free);
+	if (data == NULL)
+	{
+		ecdsa_data = (ECDSA_DATA *)ecdsa_data_new();
+		if (ecdsa_data == NULL)
+			return NULL;
+		EC_KEY_insert_key_method_data(key, (void *)ecdsa_data,
+			ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free);
+	}
+	else
+		ecdsa_data = (ECDSA_DATA *)data;
+	
+
+	return ecdsa_data;
+}
+
+int ECDSA_size(const EC_KEY *r)
+{
+	int ret,i;
+	ASN1_INTEGER bs;
+	BIGNUM	*order=NULL;
+	unsigned char buf[4];
+	const EC_GROUP *group;
+
+	if (r == NULL)
+		return 0;
+	group = EC_KEY_get0_group(r);
+	if (group == NULL)
+		return 0;
+
+	if ((order = BN_new()) == NULL) return 0;
+	if (!EC_GROUP_get_order(group,order,NULL))
+	{
+		BN_clear_free(order);
+		return 0;
+	} 
+	i=BN_num_bits(order);
+	bs.length=(i+7)/8;
+	bs.data=buf;
+	bs.type=V_ASN1_INTEGER;
+	/* If the top bit is set the asn1 encoding is 1 larger. */
+	buf[0]=0xff;	
+
+	i=i2d_ASN1_INTEGER(&bs,NULL);
+	i+=i; /* r and s */
+	ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
+	BN_clear_free(order);
+	return(ret);
+}
+
+
+int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+{
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDSA, argl, argp,
+				new_func, dup_func, free_func);
+}
+
+int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg)
+{
+	ECDSA_DATA *ecdsa;
+	ecdsa = ecdsa_check(d);
+	if (ecdsa == NULL)
+		return 0;
+	return(CRYPTO_set_ex_data(&ecdsa->ex_data,idx,arg));
+}
+
+void *ECDSA_get_ex_data(EC_KEY *d, int idx)
+{
+	ECDSA_DATA *ecdsa;
+	ecdsa = ecdsa_check(d);
+	if (ecdsa == NULL)
+		return NULL;
+	return(CRYPTO_get_ex_data(&ecdsa->ex_data,idx));
+}
diff --git a/openssl/crypto/ecdsa/ecs_locl.h b/openssl/crypto/ecdsa/ecs_locl.h
new file mode 100644
index 0000000..3a69a84
--- /dev/null
+++ b/openssl/crypto/ecdsa/ecs_locl.h
@@ -0,0 +1,107 @@
+/* crypto/ecdsa/ecs_locl.h */
+/*
+ * Written by Nils Larsch for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_ECS_LOCL_H
+#define HEADER_ECS_LOCL_H
+
+#include <openssl/ecdsa.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+struct ecdsa_method 
+	{
+	const char *name;
+	ECDSA_SIG *(*ecdsa_do_sign)(const unsigned char *dgst, int dgst_len, 
+			const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey);
+	int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, 
+			BIGNUM **r);
+	int (*ecdsa_do_verify)(const unsigned char *dgst, int dgst_len, 
+			const ECDSA_SIG *sig, EC_KEY *eckey);
+#if 0
+	int (*init)(EC_KEY *eckey);
+	int (*finish)(EC_KEY *eckey);
+#endif
+	int flags;
+	char *app_data;
+	};
+
+typedef struct ecdsa_data_st {
+	/* EC_KEY_METH_DATA part */
+	int (*init)(EC_KEY *);
+	/* method (ECDSA) specific part */
+	ENGINE	*engine;
+	int	flags;
+	const ECDSA_METHOD *meth;
+	CRYPTO_EX_DATA ex_data;
+} ECDSA_DATA;
+
+/** ecdsa_check
+ * checks whether ECKEY->meth_data is a pointer to a ECDSA_DATA structure
+ * and if not it removes the old meth_data and creates a ECDSA_DATA structure.
+ * \param  eckey pointer to a EC_KEY object
+ * \return pointer to a ECDSA_DATA structure
+ */
+ECDSA_DATA *ecdsa_check(EC_KEY *eckey);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* HEADER_ECS_LOCL_H */
diff --git a/openssl/crypto/ecdsa/ecs_ossl.c b/openssl/crypto/ecdsa/ecs_ossl.c
new file mode 100644
index 0000000..1bbf328
--- /dev/null
+++ b/openssl/crypto/ecdsa/ecs_ossl.c
@@ -0,0 +1,480 @@
+/* crypto/ecdsa/ecs_ossl.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "ecs_locl.h"
+#include <openssl/err.h>
+#include <openssl/obj_mac.h>
+#include <openssl/bn.h>
+
+static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, 
+		const BIGNUM *, const BIGNUM *, EC_KEY *eckey);
+static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, 
+		BIGNUM **rp);
+static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, 
+		const ECDSA_SIG *sig, EC_KEY *eckey);
+
+static ECDSA_METHOD openssl_ecdsa_meth = {
+	"OpenSSL ECDSA method",
+	ecdsa_do_sign,
+	ecdsa_sign_setup,
+	ecdsa_do_verify,
+#if 0
+	NULL, /* init     */
+	NULL, /* finish   */
+#endif
+	0,    /* flags    */
+	NULL  /* app_data */
+};
+
+const ECDSA_METHOD *ECDSA_OpenSSL(void)
+{
+	return &openssl_ecdsa_meth;
+}
+
+static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
+		BIGNUM **rp)
+{
+	BN_CTX   *ctx = NULL;
+	BIGNUM	 *k = NULL, *r = NULL, *order = NULL, *X = NULL;
+	EC_POINT *tmp_point=NULL;
+	const EC_GROUP *group;
+	int 	 ret = 0;
+
+	if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL)
+	{
+		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+
+	if (ctx_in == NULL) 
+	{
+		if ((ctx = BN_CTX_new()) == NULL)
+		{
+			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+	}
+	else
+		ctx = ctx_in;
+
+	k     = BN_new();	/* this value is later returned in *kinvp */
+	r     = BN_new();	/* this value is later returned in *rp    */
+	order = BN_new();
+	X     = BN_new();
+	if (!k || !r || !order || !X)
+	{
+		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if ((tmp_point = EC_POINT_new(group)) == NULL)
+	{
+		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+		goto err;
+	}
+	if (!EC_GROUP_get_order(group, order, ctx))
+	{
+		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+		goto err;
+	}
+	
+	do
+	{
+		/* get random k */	
+		do
+			if (!BN_rand_range(k, order))
+			{
+				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
+				 ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);	
+				goto err;
+			}
+		while (BN_is_zero(k));
+
+		/* We do not want timing information to leak the length of k,
+		 * so we compute G*k using an equivalent scalar of fixed
+		 * bit-length. */
+
+		if (!BN_add(k, k, order)) goto err;
+		if (BN_num_bits(k) <= BN_num_bits(order))
+			if (!BN_add(k, k, order)) goto err;
+
+		/* compute r the x-coordinate of generator * k */
+		if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))
+		{
+			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+			goto err;
+		}
+		if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
+		{
+			if (!EC_POINT_get_affine_coordinates_GFp(group,
+				tmp_point, X, NULL, ctx))
+			{
+				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
+				goto err;
+			}
+		}
+		else /* NID_X9_62_characteristic_two_field */
+		{
+			if (!EC_POINT_get_affine_coordinates_GF2m(group,
+				tmp_point, X, NULL, ctx))
+			{
+				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
+				goto err;
+			}
+		}
+		if (!BN_nnmod(r, X, order, ctx))
+		{
+			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
+			goto err;
+		}
+	}
+	while (BN_is_zero(r));
+
+	/* compute the inverse of k */
+	if (!BN_mod_inverse(k, k, order, ctx))
+	{
+		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
+		goto err;	
+	}
+	/* clear old values if necessary */
+	if (*rp != NULL)
+		BN_clear_free(*rp);
+	if (*kinvp != NULL) 
+		BN_clear_free(*kinvp);
+	/* save the pre-computed values  */
+	*rp    = r;
+	*kinvp = k;
+	ret = 1;
+err:
+	if (!ret)
+	{
+		if (k != NULL) BN_clear_free(k);
+		if (r != NULL) BN_clear_free(r);
+	}
+	if (ctx_in == NULL) 
+		BN_CTX_free(ctx);
+	if (order != NULL)
+		BN_free(order);
+	if (tmp_point != NULL) 
+		EC_POINT_free(tmp_point);
+	if (X)
+		BN_clear_free(X);
+	return(ret);
+}
+
+
+static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, 
+		const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
+{
+	int     ok = 0, i;
+	BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL;
+	const BIGNUM *ckinv;
+	BN_CTX     *ctx = NULL;
+	const EC_GROUP   *group;
+	ECDSA_SIG  *ret;
+	ECDSA_DATA *ecdsa;
+	const BIGNUM *priv_key;
+
+	ecdsa    = ecdsa_check(eckey);
+	group    = EC_KEY_get0_group(eckey);
+	priv_key = EC_KEY_get0_private_key(eckey);
+	
+	if (group == NULL || priv_key == NULL || ecdsa == NULL)
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
+		return NULL;
+	}
+
+	ret = ECDSA_SIG_new();
+	if (!ret)
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	s = ret->s;
+
+	if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
+		(tmp = BN_new()) == NULL || (m = BN_new()) == NULL)
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (!EC_GROUP_get_order(group, order, ctx))
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
+		goto err;
+	}
+	i = BN_num_bits(order);
+	/* Need to truncate digest if it is too long: first truncate whole
+	 * bytes.
+	 */
+	if (8 * dgst_len > i)
+		dgst_len = (i + 7)/8;
+	if (!BN_bin2bn(dgst, dgst_len, m))
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+		goto err;
+	}
+	/* If still too long truncate remaining bits with a shift */
+	if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+		goto err;
+	}
+	do
+	{
+		if (in_kinv == NULL || in_r == NULL)
+		{
+			if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r))
+			{
+				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB);
+				goto err;
+			}
+			ckinv = kinv;
+		}
+		else
+		{
+			ckinv  = in_kinv;
+			if (BN_copy(ret->r, in_r) == NULL)
+			{
+				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+		}
+
+		if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx))
+		{
+			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+			goto err;
+		}
+		if (!BN_mod_add_quick(s, tmp, m, order))
+		{
+			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+			goto err;
+		}
+		if (!BN_mod_mul(s, s, ckinv, order, ctx))
+		{
+			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+			goto err;
+		}
+		if (BN_is_zero(s))
+		{
+			/* if kinv and r have been supplied by the caller
+			 * don't to generate new kinv and r values */
+			if (in_kinv != NULL && in_r != NULL)
+			{
+				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES);
+				goto err;
+			}
+		}
+		else
+			/* s != 0 => we have a valid signature */
+			break;
+	}
+	while (1);
+
+	ok = 1;
+err:
+	if (!ok)
+	{
+		ECDSA_SIG_free(ret);
+		ret = NULL;
+	}
+	if (ctx)
+		BN_CTX_free(ctx);
+	if (m)
+		BN_clear_free(m);
+	if (tmp)
+		BN_clear_free(tmp);
+	if (order)
+		BN_free(order);
+	if (kinv)
+		BN_clear_free(kinv);
+	return ret;
+}
+
+static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
+		const ECDSA_SIG *sig, EC_KEY *eckey)
+{
+	int ret = -1, i;
+	BN_CTX   *ctx;
+	BIGNUM   *order, *u1, *u2, *m, *X;
+	EC_POINT *point = NULL;
+	const EC_GROUP *group;
+	const EC_POINT *pub_key;
+
+	/* check input values */
+	if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
+	    (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL)
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
+		return -1;
+	}
+
+	ctx = BN_CTX_new();
+	if (!ctx)
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
+		return -1;
+	}
+	BN_CTX_start(ctx);
+	order = BN_CTX_get(ctx);	
+	u1    = BN_CTX_get(ctx);
+	u2    = BN_CTX_get(ctx);
+	m     = BN_CTX_get(ctx);
+	X     = BN_CTX_get(ctx);
+	if (!X)
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+		goto err;
+	}
+	
+	if (!EC_GROUP_get_order(group, order, ctx))
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
+		goto err;
+	}
+
+	if (BN_is_zero(sig->r)          || BN_is_negative(sig->r) || 
+	    BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s)  ||
+	    BN_is_negative(sig->s)      || BN_ucmp(sig->s, order) >= 0)
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
+		ret = 0;	/* signature is invalid */
+		goto err;
+	}
+	/* calculate tmp1 = inv(S) mod order */
+	if (!BN_mod_inverse(u2, sig->s, order, ctx))
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+		goto err;
+	}
+	/* digest -> m */
+	i = BN_num_bits(order);
+	/* Need to truncate digest if it is too long: first truncate whole
+	 * bytes.
+	 */
+	if (8 * dgst_len > i)
+		dgst_len = (i + 7)/8;
+	if (!BN_bin2bn(dgst, dgst_len, m))
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+		goto err;
+	}
+	/* If still too long truncate remaining bits with a shift */
+	if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+		goto err;
+	}
+	/* u1 = m * tmp mod order */
+	if (!BN_mod_mul(u1, m, u2, order, ctx))
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+		goto err;
+	}
+	/* u2 = r * w mod q */
+	if (!BN_mod_mul(u2, sig->r, u2, order, ctx))
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+		goto err;
+	}
+
+	if ((point = EC_POINT_new(group)) == NULL)
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx))
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
+		goto err;
+	}
+	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
+	{
+		if (!EC_POINT_get_affine_coordinates_GFp(group,
+			point, X, NULL, ctx))
+		{
+			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
+			goto err;
+		}
+	}
+	else /* NID_X9_62_characteristic_two_field */
+	{
+		if (!EC_POINT_get_affine_coordinates_GF2m(group,
+			point, X, NULL, ctx))
+		{
+			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
+			goto err;
+		}
+	}
+	
+	if (!BN_nnmod(u1, X, order, ctx))
+	{
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+		goto err;
+	}
+	/*  if the signature is correct u1 is equal to sig->r */
+	ret = (BN_ucmp(u1, sig->r) == 0);
+err:
+	BN_CTX_end(ctx);
+	BN_CTX_free(ctx);
+	if (point)
+		EC_POINT_free(point);
+	return ret;
+}
diff --git a/openssl/crypto/ecdsa/ecs_sign.c b/openssl/crypto/ecdsa/ecs_sign.c
new file mode 100644
index 0000000..353d5af
--- /dev/null
+++ b/openssl/crypto/ecdsa/ecs_sign.c
@@ -0,0 +1,106 @@
+/* crypto/ecdsa/ecdsa_sign.c */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "ecs_locl.h"
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/rand.h>
+
+ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
+{
+	return ECDSA_do_sign_ex(dgst, dlen, NULL, NULL, eckey);
+}
+
+ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dlen,
+	const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey)
+{
+	ECDSA_DATA *ecdsa = ecdsa_check(eckey);
+	if (ecdsa == NULL)
+		return NULL;
+	return ecdsa->meth->ecdsa_do_sign(dgst, dlen, kinv, rp, eckey);
+}
+
+int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char 
+		*sig, unsigned int *siglen, EC_KEY *eckey)
+{
+	return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey);
+}
+
+int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char 
+	*sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, 
+	EC_KEY *eckey)
+{
+	ECDSA_SIG *s;
+	RAND_seed(dgst, dlen);
+	s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
+	if (s == NULL)
+	{
+		*siglen=0;
+		return 0;
+	}
+	*siglen = i2d_ECDSA_SIG(s, &sig);
+	ECDSA_SIG_free(s);
+	return 1;
+}
+
+int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, 
+		BIGNUM **rp)
+{
+	ECDSA_DATA *ecdsa = ecdsa_check(eckey);
+	if (ecdsa == NULL)
+		return 0;
+	return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp); 
+}
diff --git a/openssl/crypto/ecdsa/ecs_vrf.c b/openssl/crypto/ecdsa/ecs_vrf.c
new file mode 100644
index 0000000..ef9acf7
--- /dev/null
+++ b/openssl/crypto/ecdsa/ecs_vrf.c
@@ -0,0 +1,96 @@
+/* crypto/ecdsa/ecdsa_vrf.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "ecs_locl.h"
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+/* returns
+ *      1: correct signature
+ *      0: incorrect signature
+ *     -1: error
+ */
+int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, 
+		const ECDSA_SIG *sig, EC_KEY *eckey)
+	{
+	ECDSA_DATA *ecdsa = ecdsa_check(eckey);
+	if (ecdsa == NULL)
+		return 0;
+	return ecdsa->meth->ecdsa_do_verify(dgst, dgst_len, sig, eckey);
+	}
+
+/* returns
+ *      1: correct signature
+ *      0: incorrect signature
+ *     -1: error
+ */
+int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
+		const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
+ 	{
+	ECDSA_SIG *s;
+	int ret=-1;
+
+	s = ECDSA_SIG_new();
+	if (s == NULL) return(ret);
+	if (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err;
+	ret=ECDSA_do_verify(dgst, dgst_len, s, eckey);
+err:
+	ECDSA_SIG_free(s);
+	return(ret);
+	}
diff --git a/openssl/crypto/engine/Makefile b/openssl/crypto/engine/Makefile
new file mode 100644
index 0000000..9c21482
--- /dev/null
+++ b/openssl/crypto/engine/Makefile
@@ -0,0 +1,417 @@
+#
+# OpenSSL/crypto/engine/Makefile
+#
+
+DIR=	engine
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST= enginetest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= eng_err.c eng_lib.c eng_list.c eng_init.c eng_ctrl.c \
+	eng_table.c eng_pkey.c eng_fat.c eng_all.c \
+	tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
+	tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c \
+	eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c
+LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
+	eng_table.o eng_pkey.o eng_fat.o eng_all.o \
+	tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
+	tb_cipher.o tb_digest.o tb_pkmeth.o tb_asnmth.o \
+	eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= engine.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+eng_all.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_all.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_all.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+eng_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+eng_all.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+eng_all.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+eng_all.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+eng_all.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+eng_all.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+eng_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_all.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_all.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_all.c eng_int.h
+eng_cnf.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_cnf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_cnf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+eng_cnf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+eng_cnf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+eng_cnf.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+eng_cnf.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+eng_cnf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+eng_cnf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+eng_cnf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+eng_cnf.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+eng_cnf.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+eng_cnf.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+eng_cnf.o: ../cryptlib.h eng_cnf.c eng_int.h
+eng_cryptodev.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+eng_cryptodev.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+eng_cryptodev.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_cryptodev.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+eng_cryptodev.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+eng_cryptodev.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+eng_cryptodev.o: ../../include/openssl/obj_mac.h
+eng_cryptodev.o: ../../include/openssl/objects.h
+eng_cryptodev.o: ../../include/openssl/opensslconf.h
+eng_cryptodev.o: ../../include/openssl/opensslv.h
+eng_cryptodev.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+eng_cryptodev.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+eng_cryptodev.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+eng_cryptodev.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+eng_cryptodev.o: eng_cryptodev.c
+eng_ctrl.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_ctrl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_ctrl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_ctrl.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+eng_ctrl.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+eng_ctrl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+eng_ctrl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+eng_ctrl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+eng_ctrl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+eng_ctrl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+eng_ctrl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_ctrl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_ctrl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_ctrl.c eng_int.h
+eng_dyn.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_dyn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_dyn.o: ../../include/openssl/crypto.h ../../include/openssl/dso.h
+eng_dyn.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+eng_dyn.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+eng_dyn.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+eng_dyn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+eng_dyn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+eng_dyn.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+eng_dyn.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+eng_dyn.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+eng_dyn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+eng_dyn.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+eng_dyn.o: ../cryptlib.h eng_dyn.c eng_int.h
+eng_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+eng_err.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+eng_err.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+eng_err.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+eng_err.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+eng_err.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+eng_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+eng_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+eng_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+eng_err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+eng_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+eng_err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+eng_err.o: eng_err.c
+eng_fat.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_fat.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_fat.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+eng_fat.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+eng_fat.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+eng_fat.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+eng_fat.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+eng_fat.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+eng_fat.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+eng_fat.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+eng_fat.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+eng_fat.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+eng_fat.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+eng_fat.o: ../cryptlib.h eng_fat.c eng_int.h
+eng_init.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_init.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_init.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_init.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+eng_init.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+eng_init.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+eng_init.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+eng_init.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+eng_init.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+eng_init.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+eng_init.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_init.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_init.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_init.c eng_int.h
+eng_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+eng_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+eng_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+eng_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+eng_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+eng_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+eng_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+eng_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+eng_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+eng_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+eng_lib.o: ../cryptlib.h eng_int.h eng_lib.c
+eng_list.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_list.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_list.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_list.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+eng_list.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+eng_list.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+eng_list.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+eng_list.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+eng_list.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+eng_list.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+eng_list.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_list.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_list.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h eng_list.c
+eng_openssl.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_openssl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_openssl.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+eng_openssl.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
+eng_openssl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+eng_openssl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+eng_openssl.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+eng_openssl.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+eng_openssl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+eng_openssl.o: ../../include/openssl/opensslconf.h
+eng_openssl.o: ../../include/openssl/opensslv.h
+eng_openssl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
+eng_openssl.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
+eng_openssl.o: ../../include/openssl/rand.h ../../include/openssl/rc4.h
+eng_openssl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+eng_openssl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_openssl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_openssl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_openssl.c
+eng_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_pkey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_pkey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_pkey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+eng_pkey.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+eng_pkey.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+eng_pkey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+eng_pkey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+eng_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+eng_pkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+eng_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h eng_pkey.c
+eng_table.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_table.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_table.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_table.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+eng_table.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+eng_table.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+eng_table.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+eng_table.o: ../../include/openssl/objects.h
+eng_table.o: ../../include/openssl/opensslconf.h
+eng_table.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+eng_table.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+eng_table.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_table.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_table.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
+eng_table.o: eng_table.c
+tb_asnmth.o: ../../e_os.h ../../include/openssl/asn1.h
+tb_asnmth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+tb_asnmth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+tb_asnmth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+tb_asnmth.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+tb_asnmth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+tb_asnmth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+tb_asnmth.o: ../../include/openssl/objects.h
+tb_asnmth.o: ../../include/openssl/opensslconf.h
+tb_asnmth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tb_asnmth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+tb_asnmth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+tb_asnmth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+tb_asnmth.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
+tb_asnmth.o: eng_int.h tb_asnmth.c
+tb_cipher.o: ../../e_os.h ../../include/openssl/asn1.h
+tb_cipher.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+tb_cipher.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+tb_cipher.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+tb_cipher.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+tb_cipher.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+tb_cipher.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+tb_cipher.o: ../../include/openssl/objects.h
+tb_cipher.o: ../../include/openssl/opensslconf.h
+tb_cipher.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tb_cipher.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+tb_cipher.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+tb_cipher.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+tb_cipher.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
+tb_cipher.o: tb_cipher.c
+tb_dh.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+tb_dh.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+tb_dh.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+tb_dh.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+tb_dh.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+tb_dh.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+tb_dh.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+tb_dh.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+tb_dh.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+tb_dh.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+tb_dh.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+tb_dh.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+tb_dh.o: ../cryptlib.h eng_int.h tb_dh.c
+tb_digest.o: ../../e_os.h ../../include/openssl/asn1.h
+tb_digest.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+tb_digest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+tb_digest.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+tb_digest.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+tb_digest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+tb_digest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+tb_digest.o: ../../include/openssl/objects.h
+tb_digest.o: ../../include/openssl/opensslconf.h
+tb_digest.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tb_digest.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+tb_digest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+tb_digest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+tb_digest.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
+tb_digest.o: tb_digest.c
+tb_dsa.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+tb_dsa.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+tb_dsa.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+tb_dsa.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+tb_dsa.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+tb_dsa.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+tb_dsa.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+tb_dsa.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+tb_dsa.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+tb_dsa.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+tb_dsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+tb_dsa.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+tb_dsa.o: ../cryptlib.h eng_int.h tb_dsa.c
+tb_ecdh.o: ../../e_os.h ../../include/openssl/asn1.h
+tb_ecdh.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+tb_ecdh.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+tb_ecdh.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+tb_ecdh.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+tb_ecdh.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+tb_ecdh.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+tb_ecdh.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+tb_ecdh.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tb_ecdh.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+tb_ecdh.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+tb_ecdh.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+tb_ecdh.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_ecdh.c
+tb_ecdsa.o: ../../e_os.h ../../include/openssl/asn1.h
+tb_ecdsa.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+tb_ecdsa.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+tb_ecdsa.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+tb_ecdsa.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+tb_ecdsa.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+tb_ecdsa.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+tb_ecdsa.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+tb_ecdsa.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tb_ecdsa.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+tb_ecdsa.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+tb_ecdsa.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+tb_ecdsa.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_ecdsa.c
+tb_pkmeth.o: ../../e_os.h ../../include/openssl/asn1.h
+tb_pkmeth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+tb_pkmeth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+tb_pkmeth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+tb_pkmeth.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+tb_pkmeth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+tb_pkmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+tb_pkmeth.o: ../../include/openssl/objects.h
+tb_pkmeth.o: ../../include/openssl/opensslconf.h
+tb_pkmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tb_pkmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+tb_pkmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+tb_pkmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+tb_pkmeth.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
+tb_pkmeth.o: tb_pkmeth.c
+tb_rand.o: ../../e_os.h ../../include/openssl/asn1.h
+tb_rand.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+tb_rand.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+tb_rand.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+tb_rand.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+tb_rand.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+tb_rand.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+tb_rand.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+tb_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tb_rand.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+tb_rand.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+tb_rand.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+tb_rand.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_rand.c
+tb_rsa.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+tb_rsa.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+tb_rsa.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+tb_rsa.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+tb_rsa.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+tb_rsa.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+tb_rsa.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+tb_rsa.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+tb_rsa.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+tb_rsa.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+tb_rsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+tb_rsa.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+tb_rsa.o: ../cryptlib.h eng_int.h tb_rsa.c
+tb_store.o: ../../e_os.h ../../include/openssl/asn1.h
+tb_store.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+tb_store.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+tb_store.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+tb_store.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+tb_store.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+tb_store.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+tb_store.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+tb_store.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tb_store.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+tb_store.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+tb_store.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+tb_store.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_store.c
diff --git a/openssl/crypto/engine/README b/openssl/crypto/engine/README
new file mode 100644
index 0000000..6b69b70
--- /dev/null
+++ b/openssl/crypto/engine/README
@@ -0,0 +1,211 @@
+Notes: 2001-09-24
+-----------------
+
+This "description" (if one chooses to call it that) needed some major updating
+so here goes. This update addresses a change being made at the same time to
+OpenSSL, and it pretty much completely restructures the underlying mechanics of
+the "ENGINE" code. So it serves a double purpose of being a "ENGINE internals
+for masochists" document *and* a rather extensive commit log message. (I'd get
+lynched for sticking all this in CHANGES or the commit mails :-).
+
+ENGINE_TABLE underlies this restructuring, as described in the internal header
+"eng_int.h", implemented in eng_table.c, and used in each of the "class" files;
+tb_rsa.c, tb_dsa.c, etc.
+
+However, "EVP_CIPHER" underlies the motivation and design of ENGINE_TABLE so
+I'll mention a bit about that first. EVP_CIPHER (and most of this applies
+equally to EVP_MD for digests) is both a "method" and a algorithm/mode
+identifier that, in the current API, "lingers". These cipher description +
+implementation structures can be defined or obtained directly by applications,
+or can be loaded "en masse" into EVP storage so that they can be catalogued and
+searched in various ways, ie. two ways of encrypting with the "des_cbc"
+algorithm/mode pair are;
+
+(i) directly;
+     const EVP_CIPHER *cipher = EVP_des_cbc();
+     EVP_EncryptInit(&ctx, cipher, key, iv);
+     [ ... use EVP_EncryptUpdate() and EVP_EncryptFinal() ...]
+
+(ii) indirectly; 
+     OpenSSL_add_all_ciphers();
+     cipher = EVP_get_cipherbyname("des_cbc");
+     EVP_EncryptInit(&ctx, cipher, key, iv);
+     [ ... etc ... ]
+
+The latter is more generally used because it also allows ciphers/digests to be
+looked up based on other identifiers which can be useful for automatic cipher
+selection, eg. in SSL/TLS, or by user-controllable configuration.
+
+The important point about this is that EVP_CIPHER definitions and structures are
+passed around with impunity and there is no safe way, without requiring massive
+rewrites of many applications, to assume that EVP_CIPHERs can be reference
+counted. One an EVP_CIPHER is exposed to the caller, neither it nor anything it
+comes from can "safely" be destroyed. Unless of course the way of getting to
+such ciphers is via entirely distinct API calls that didn't exist before.
+However existing API usage cannot be made to understand when an EVP_CIPHER
+pointer, that has been passed to the caller, is no longer being used.
+
+The other problem with the existing API w.r.t. to hooking EVP_CIPHER support
+into ENGINE is storage - the OBJ_NAME-based storage used by EVP to register
+ciphers simultaneously registers cipher *types* and cipher *implementations* -
+they are effectively the same thing, an "EVP_CIPHER" pointer. The problem with
+hooking in ENGINEs is that multiple ENGINEs may implement the same ciphers. The
+solution is necessarily that ENGINE-provided ciphers simply are not registered,
+stored, or exposed to the caller in the same manner as existing ciphers. This is
+especially necessary considering the fact ENGINE uses reference counts to allow
+for cleanup, modularity, and DSO support - yet EVP_CIPHERs, as exposed to
+callers in the current API, support no such controls.
+
+Another sticking point for integrating cipher support into ENGINE is linkage.
+Already there is a problem with the way ENGINE supports RSA, DSA, etc whereby
+they are available *because* they're part of a giant ENGINE called "openssl".
+Ie. all implementations *have* to come from an ENGINE, but we get round that by
+having a giant ENGINE with all the software support encapsulated. This creates
+linker hassles if nothing else - linking a 1-line application that calls 2 basic
+RSA functions (eg. "RSA_free(RSA_new());") will result in large quantities of
+ENGINE code being linked in *and* because of that DSA, DH, and RAND also. If we
+continue with this approach for EVP_CIPHER support (even if it *was* possible)
+we would lose our ability to link selectively by selectively loading certain
+implementations of certain functionality. Touching any part of any kind of
+crypto would result in massive static linkage of everything else. So the
+solution is to change the way ENGINE feeds existing "classes", ie. how the
+hooking to ENGINE works from RSA, DSA, DH, RAND, as well as adding new hooking
+for EVP_CIPHER, and EVP_MD.
+
+The way this is now being done is by mostly reverting back to how things used to
+work prior to ENGINE :-). Ie. RSA now has a "RSA_METHOD" pointer again - this
+was previously replaced by an "ENGINE" pointer and all RSA code that required
+the RSA_METHOD would call ENGINE_get_RSA() each time on its ENGINE handle to
+temporarily get and use the ENGINE's RSA implementation. Apart from being more
+efficient, switching back to each RSA having an RSA_METHOD pointer also allows
+us to conceivably operate with *no* ENGINE. As we'll see, this removes any need
+for a fallback ENGINE that encapsulates default implementations - we can simply
+have our RSA structure pointing its RSA_METHOD pointer to the software
+implementation and have its ENGINE pointer set to NULL.
+
+A look at the EVP_CIPHER hooking is most explanatory, the RSA, DSA (etc) cases
+turn out to be degenerate forms of the same thing. The EVP storage of ciphers,
+and the existing EVP API functions that return "software" implementations and
+descriptions remain untouched. However, the storage takes more meaning in terms
+of "cipher description" and less meaning in terms of "implementation". When an
+EVP_CIPHER_CTX is actually initialised with an EVP_CIPHER method and is about to
+begin en/decryption, the hooking to ENGINE comes into play. What happens is that
+cipher-specific ENGINE code is asked for an ENGINE pointer (a functional
+reference) for any ENGINE that is registered to perform the algo/mode that the
+provided EVP_CIPHER structure represents. Under normal circumstances, that
+ENGINE code will return NULL because no ENGINEs will have had any cipher
+implementations *registered*. As such, a NULL ENGINE pointer is stored in the
+EVP_CIPHER_CTX context, and the EVP_CIPHER structure is left hooked into the
+context and so is used as the implementation. Pretty much how things work now
+except we'd have a redundant ENGINE pointer set to NULL and doing nothing.
+
+Conversely, if an ENGINE *has* been registered to perform the algorithm/mode
+combination represented by the provided EVP_CIPHER, then a functional reference
+to that ENGINE will be returned to the EVP_CIPHER_CTX during initialisation.
+That functional reference will be stored in the context (and released on
+cleanup) - and having that reference provides a *safe* way to use an EVP_CIPHER
+definition that is private to the ENGINE. Ie. the EVP_CIPHER provided by the
+application will actually be replaced by an EVP_CIPHER from the registered
+ENGINE - it will support the same algorithm/mode as the original but will be a
+completely different implementation. Because this EVP_CIPHER isn't stored in the
+EVP storage, nor is it returned to applications from traditional API functions,
+there is no associated problem with it not having reference counts. And of
+course, when one of these "private" cipher implementations is hooked into
+EVP_CIPHER_CTX, it is done whilst the EVP_CIPHER_CTX holds a functional
+reference to the ENGINE that owns it, thus the use of the ENGINE's EVP_CIPHER is
+safe.
+
+The "cipher-specific ENGINE code" I mentioned is implemented in tb_cipher.c but
+in essence it is simply an instantiation of "ENGINE_TABLE" code for use by
+EVP_CIPHER code. tb_digest.c is virtually identical but, of course, it is for
+use by EVP_MD code. Ditto for tb_rsa.c, tb_dsa.c, etc. These instantiations of
+ENGINE_TABLE essentially provide linker-separation of the classes so that even
+if ENGINEs implement *all* possible algorithms, an application using only
+EVP_CIPHER code will link at most code relating to EVP_CIPHER, tb_cipher.c, core
+ENGINE code that is independant of class, and of course the ENGINE
+implementation that the application loaded. It will *not* however link any
+class-specific ENGINE code for digests, RSA, etc nor will it bleed over into
+other APIs, such as the RSA/DSA/etc library code.
+
+ENGINE_TABLE is a little more complicated than may seem necessary but this is
+mostly to avoid a lot of "init()"-thrashing on ENGINEs (that may have to load
+DSOs, and other expensive setup that shouldn't be thrashed unnecessarily) *and*
+to duplicate "default" behaviour. Basically an ENGINE_TABLE instantiation, for
+example tb_cipher.c, implements a hash-table keyed by integer "nid" values.
+These nids provide the uniquenness of an algorithm/mode - and each nid will hash
+to a potentially NULL "ENGINE_PILE". An ENGINE_PILE is essentially a list of
+pointers to ENGINEs that implement that particular 'nid'. Each "pile" uses some
+caching tricks such that requests on that 'nid' will be cached and all future
+requests will return immediately (well, at least with minimal operation) unless
+a change is made to the pile, eg. perhaps an ENGINE was unloaded. The reason is
+that an application could have support for 10 ENGINEs statically linked
+in, and the machine in question may not have any of the hardware those 10
+ENGINEs support. If each of those ENGINEs has a "des_cbc" implementation, we
+want to avoid every EVP_CIPHER_CTX setup from trying (and failing) to initialise
+each of those 10 ENGINEs. Instead, the first such request will try to do that
+and will either return (and cache) a NULL ENGINE pointer or will return a
+functional reference to the first that successfully initialised. In the latter
+case it will also cache an extra functional reference to the ENGINE as a
+"default" for that 'nid'. The caching is acknowledged by a 'uptodate' variable
+that is unset only if un/registration takes place on that pile. Ie. if
+implementations of "des_cbc" are added or removed. This behaviour can be
+tweaked; the ENGINE_TABLE_FLAG_NOINIT value can be passed to
+ENGINE_set_table_flags(), in which case the only ENGINEs that tb_cipher.c will
+try to initialise from the "pile" will be those that are already initialised
+(ie. it's simply an increment of the functional reference count, and no real
+"initialisation" will take place).
+
+RSA, DSA, DH, and RAND all have their own ENGINE_TABLE code as well, and the
+difference is that they all use an implicit 'nid' of 1. Whereas EVP_CIPHERs are
+actually qualitatively different depending on 'nid' (the "des_cbc" EVP_CIPHER is
+not an interoperable implementation of "aes_256_cbc"), RSA_METHODs are
+necessarily interoperable and don't have different flavours, only different
+implementations. In other words, the ENGINE_TABLE for RSA will either be empty,
+or will have a single ENGING_PILE hashed to by the 'nid' 1 and that pile
+represents ENGINEs that implement the single "type" of RSA there is.
+
+Cleanup - the registration and unregistration may pose questions about how
+cleanup works with the ENGINE_PILE doing all this caching nonsense (ie. when the
+application or EVP_CIPHER code releases its last reference to an ENGINE, the
+ENGINE_PILE code may still have references and thus those ENGINEs will stay
+hooked in forever). The way this is handled is via "unregistration". With these
+new ENGINE changes, an abstract ENGINE can be loaded and initialised, but that
+is an algorithm-agnostic process. Even if initialised, it will not have
+registered any of its implementations (to do so would link all class "table"
+code despite the fact the application may use only ciphers, for example). This
+is deliberately a distinct step. Moreover, registration and unregistration has
+nothing to do with whether an ENGINE is *functional* or not (ie. you can even
+register an ENGINE and its implementations without it being operational, you may
+not even have the drivers to make it operate). What actually happens with
+respect to cleanup is managed inside eng_lib.c with the "engine_cleanup_***"
+functions. These functions are internal-only and each part of ENGINE code that
+could require cleanup will, upon performing its first allocation, register a
+callback with the "engine_cleanup" code. The other part of this that makes it
+tick is that the ENGINE_TABLE instantiations (tb_***.c) use NULL as their
+initialised state. So if RSA code asks for an ENGINE and no ENGINE has
+registered an implementation, the code will simply return NULL and the tb_rsa.c
+state will be unchanged. Thus, no cleanup is required unless registration takes
+place. ENGINE_cleanup() will simply iterate across a list of registered cleanup
+callbacks calling each in turn, and will then internally delete its own storage
+(a STACK). When a cleanup callback is next registered (eg. if the cleanup() is
+part of a gracefull restart and the application wants to cleanup all state then
+start again), the internal STACK storage will be freshly allocated. This is much
+the same as the situation in the ENGINE_TABLE instantiations ... NULL is the
+initialised state, so only modification operations (not queries) will cause that
+code to have to register a cleanup.
+
+What else? The bignum callbacks and associated ENGINE functions have been
+removed for two obvious reasons; (i) there was no way to generalise them to the
+mechanism now used by RSA/DSA/..., because there's no such thing as a BIGNUM
+method, and (ii) because of (i), there was no meaningful way for library or
+application code to automatically hook and use ENGINE supplied bignum functions
+anyway. Also, ENGINE_cpy() has been removed (although an internal-only version
+exists) - the idea of providing an ENGINE_cpy() function probably wasn't a good
+one and now certainly doesn't make sense in any generalised way. Some of the
+RSA, DSA, DH, and RAND functions that were fiddled during the original ENGINE
+changes have now, as a consequence, been reverted back. This is because the
+hooking of ENGINE is now automatic (and passive, it can interally use a NULL
+ENGINE pointer to simply ignore ENGINE from then on).
+
+Hell, that should be enough for now ... comments welcome: geoff@openssl.org
+
diff --git a/openssl/crypto/engine/eng_all.c b/openssl/crypto/engine/eng_all.c
new file mode 100644
index 0000000..22c1204
--- /dev/null
+++ b/openssl/crypto/engine/eng_all.c
@@ -0,0 +1,126 @@
+/* crypto/engine/eng_all.c -*- mode: C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte <richard@levitte.org> for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include "eng_int.h"
+
+void ENGINE_load_builtin_engines(void)
+	{
+#if 0
+	/* There's no longer any need for an "openssl" ENGINE unless, one day,
+	 * it is the *only* way for standard builtin implementations to be be
+	 * accessed (ie. it would be possible to statically link binaries with
+	 * *no* builtin implementations). */
+	ENGINE_load_openssl();
+#endif
+#if !defined(OPENSSL_NO_HW) && (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
+	ENGINE_load_cryptodev();
+#endif
+	ENGINE_load_dynamic();
+#ifndef OPENSSL_NO_STATIC_ENGINE
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_4758_CCA
+	ENGINE_load_4758cca();
+#endif
+#ifndef OPENSSL_NO_HW_AEP
+	ENGINE_load_aep();
+#endif
+#ifndef OPENSSL_NO_HW_ATALLA
+	ENGINE_load_atalla();
+#endif
+#ifndef OPENSSL_NO_HW_CSWIFT
+	ENGINE_load_cswift();
+#endif
+#ifndef OPENSSL_NO_HW_NCIPHER
+	ENGINE_load_chil();
+#endif
+#ifndef OPENSSL_NO_HW_NURON
+	ENGINE_load_nuron();
+#endif
+#ifndef OPENSSL_NO_HW_SUREWARE
+	ENGINE_load_sureware();
+#endif
+#ifndef OPENSSL_NO_HW_UBSEC
+	ENGINE_load_ubsec();
+#endif
+#ifndef OPENSSL_NO_HW_PADLOCK
+	ENGINE_load_padlock();
+#endif
+#endif
+#ifndef OPENSSL_NO_GOST
+	ENGINE_load_gost();
+#endif
+#ifndef OPENSSL_NO_GMP
+	ENGINE_load_gmp();
+#endif
+#if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
+	ENGINE_load_capi();
+#endif
+#endif
+	}
+
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
+void ENGINE_setup_bsd_cryptodev(void) {
+	static int bsd_cryptodev_default_loaded = 0;
+	if (!bsd_cryptodev_default_loaded) {
+		ENGINE_load_cryptodev();
+		ENGINE_register_all_complete();
+	}
+	bsd_cryptodev_default_loaded=1;
+}
+#endif
diff --git a/openssl/crypto/engine/eng_cnf.c b/openssl/crypto/engine/eng_cnf.c
new file mode 100644
index 0000000..95c4070
--- /dev/null
+++ b/openssl/crypto/engine/eng_cnf.c
@@ -0,0 +1,259 @@
+/* eng_cnf.c */
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+#include <openssl/conf.h>
+
+/* #define ENGINE_CONF_DEBUG */
+
+/* ENGINE config module */
+
+static char *skip_dot(char *name)
+	{
+	char *p;
+	p = strchr(name, '.');
+	if (p)
+		return p + 1;
+	return name;
+	}
+
+static STACK_OF(ENGINE) *initialized_engines = NULL;
+
+static int int_engine_init(ENGINE *e)
+	{
+	if (!ENGINE_init(e))
+		return 0;
+	if (!initialized_engines)
+		initialized_engines = sk_ENGINE_new_null();
+	if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e))
+		{
+		ENGINE_finish(e);
+		return 0;
+		}
+	return 1;
+	}
+	
+
+static int int_engine_configure(char *name, char *value, const CONF *cnf)
+	{
+	int i;
+	int ret = 0;
+	long do_init = -1;
+	STACK_OF(CONF_VALUE) *ecmds;
+	CONF_VALUE *ecmd = NULL;
+	char *ctrlname, *ctrlvalue;
+	ENGINE *e = NULL;
+	int soft = 0;
+
+	name = skip_dot(name);
+#ifdef ENGINE_CONF_DEBUG
+	fprintf(stderr, "Configuring engine %s\n", name);
+#endif
+	/* Value is a section containing ENGINE commands */
+	ecmds = NCONF_get_section(cnf, value);
+
+	if (!ecmds)
+		{
+		ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_SECTION_ERROR);
+		return 0;
+		}
+
+	for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++)
+		{
+		ecmd = sk_CONF_VALUE_value(ecmds, i);
+		ctrlname = skip_dot(ecmd->name);
+		ctrlvalue = ecmd->value;
+#ifdef ENGINE_CONF_DEBUG
+	fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname, ctrlvalue);
+#endif
+
+		/* First handle some special pseudo ctrls */
+
+		/* Override engine name to use */
+		if (!strcmp(ctrlname, "engine_id"))
+			name = ctrlvalue;
+		else if (!strcmp(ctrlname, "soft_load"))
+			soft = 1;
+		/* Load a dynamic ENGINE */
+		else if (!strcmp(ctrlname, "dynamic_path"))
+			{
+			e = ENGINE_by_id("dynamic");
+			if (!e)
+				goto err;
+			if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0))
+				goto err;
+			if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0))
+				goto err;
+			if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
+				goto err;
+			}
+		/* ... add other pseudos here ... */
+		else
+			{
+			/* At this point we need an ENGINE structural reference
+			 * if we don't already have one.
+			 */
+			if (!e)
+				{
+				e = ENGINE_by_id(name);
+				if (!e && soft)
+					{
+					ERR_clear_error();
+					return 1;
+					}
+				if (!e)
+					goto err;
+				}
+			/* Allow "EMPTY" to mean no value: this allows a valid
+			 * "value" to be passed to ctrls of type NO_INPUT
+		 	 */
+			if (!strcmp(ctrlvalue, "EMPTY"))
+				ctrlvalue = NULL;
+			if (!strcmp(ctrlname, "init"))
+				{
+				if (!NCONF_get_number_e(cnf, value, "init", &do_init))
+					goto err;
+				if (do_init == 1)
+					{
+					if (!int_engine_init(e))
+						goto err;
+					}
+				else if (do_init != 0)
+					{
+					ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_INVALID_INIT_VALUE);
+					goto err;
+					}
+				}
+			else if (!strcmp(ctrlname, "default_algorithms"))
+				{
+				if (!ENGINE_set_default_string(e, ctrlvalue))
+					goto err;
+				}
+			else if (!ENGINE_ctrl_cmd_string(e,
+					ctrlname, ctrlvalue, 0))
+				goto err;
+			}
+
+
+
+		}
+	if (e && (do_init == -1) && !int_engine_init(e))
+		{
+		ecmd = NULL;
+		goto err;
+		}
+	ret = 1;
+	err:
+	if (ret != 1)
+		{
+		ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_CONFIGURATION_ERROR);
+		if (ecmd)
+			ERR_add_error_data(6, "section=", ecmd->section, 
+						", name=", ecmd->name,
+						", value=", ecmd->value);
+		}
+	if (e)
+		ENGINE_free(e);
+	return ret;
+	}
+
+
+static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
+	{
+	STACK_OF(CONF_VALUE) *elist;
+	CONF_VALUE *cval;
+	int i;
+#ifdef ENGINE_CONF_DEBUG
+	fprintf(stderr, "Called engine module: name %s, value %s\n",
+			CONF_imodule_get_name(md), CONF_imodule_get_value(md));
+#endif
+	/* Value is a section containing ENGINEs to configure */
+	elist = NCONF_get_section(cnf, CONF_imodule_get_value(md));
+
+	if (!elist)
+		{
+		ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT, ENGINE_R_ENGINES_SECTION_ERROR);
+		return 0;
+		}
+
+	for (i = 0; i < sk_CONF_VALUE_num(elist); i++)
+		{
+		cval = sk_CONF_VALUE_value(elist, i);
+		if (!int_engine_configure(cval->name, cval->value, cnf))
+			return 0;
+		}
+
+	return 1;
+	}
+
+static void int_engine_module_finish(CONF_IMODULE *md)
+	{
+	ENGINE *e;
+	while ((e = sk_ENGINE_pop(initialized_engines)))
+		ENGINE_finish(e);
+	sk_ENGINE_free(initialized_engines);
+	initialized_engines = NULL;
+	}
+	
+
+void ENGINE_add_conf_module(void)
+	{
+	CONF_module_add("engines",
+			int_engine_module_init,
+			int_engine_module_finish);
+	}
diff --git a/openssl/crypto/engine/eng_cryptodev.c b/openssl/crypto/engine/eng_cryptodev.c
new file mode 100644
index 0000000..52f4ca3
--- /dev/null
+++ b/openssl/crypto/engine/eng_cryptodev.c
@@ -0,0 +1,1419 @@
+/*
+ * Copyright (c) 2002 Bob Beck <beck@openbsd.org>
+ * Copyright (c) 2002 Theo de Raadt
+ * Copyright (c) 2002 Markus Friedl
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <openssl/objects.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+
+#if (defined(__unix__) || defined(unix)) && !defined(USG) && \
+	(defined(OpenBSD) || defined(__FreeBSD__))
+#include <sys/param.h>
+# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041)
+#  define HAVE_CRYPTODEV
+# endif
+# if (OpenBSD >= 200110)
+#  define HAVE_SYSLOG_R
+# endif
+#endif
+
+#ifndef HAVE_CRYPTODEV
+
+void
+ENGINE_load_cryptodev(void)
+{
+	/* This is a NOP on platforms without /dev/crypto */
+	return;
+}
+
+#else 
+ 
+#include <sys/types.h>
+#include <crypto/cryptodev.h>
+#include <crypto/dh/dh.h>
+#include <crypto/dsa/dsa.h>
+#include <crypto/err/err.h>
+#include <crypto/rsa/rsa.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <syslog.h>
+#include <errno.h>
+#include <string.h>
+
+struct dev_crypto_state {
+	struct session_op d_sess;
+	int d_fd;
+
+#ifdef USE_CRYPTODEV_DIGESTS
+	char dummy_mac_key[HASH_MAX_LEN];
+
+	unsigned char digest_res[HASH_MAX_LEN];
+	char *mac_data;
+	int mac_len;
+
+	int copy;
+#endif
+};
+
+static u_int32_t cryptodev_asymfeat = 0;
+
+static int get_asym_dev_crypto(void);
+static int open_dev_crypto(void);
+static int get_dev_crypto(void);
+static int get_cryptodev_ciphers(const int **cnids);
+#ifdef USE_CRYPTODEV_DIGESTS
+static int get_cryptodev_digests(const int **cnids);
+#endif
+static int cryptodev_usable_ciphers(const int **nids);
+static int cryptodev_usable_digests(const int **nids);
+static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl);
+static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc);
+static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx);
+static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
+    const int **nids, int nid);
+static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
+    const int **nids, int nid);
+static int bn2crparam(const BIGNUM *a, struct crparam *crp);
+static int crparam2bn(struct crparam *crp, BIGNUM *a);
+static void zapparams(struct crypt_kop *kop);
+static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r,
+    int slen, BIGNUM *s);
+
+static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
+    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I,
+    RSA *rsa, BN_CTX *ctx);
+static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
+    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
+    BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
+    BN_CTX *ctx, BN_MONT_CTX *mont);
+static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst,
+    int dlen, DSA *dsa);
+static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
+    DSA_SIG *sig, DSA *dsa);
+static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
+    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+    BN_MONT_CTX *m_ctx);
+static int cryptodev_dh_compute_key(unsigned char *key,
+    const BIGNUM *pub_key, DH *dh);
+static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
+    void (*f)(void));
+void ENGINE_load_cryptodev(void);
+
+static const ENGINE_CMD_DEFN cryptodev_defns[] = {
+	{ 0, NULL, NULL, 0 }
+};
+
+static struct {
+	int	id;
+	int	nid;
+	int	ivmax;
+	int	keylen;
+} ciphers[] = {
+	{ CRYPTO_ARC4,			NID_rc4,		0,	16, },
+	{ CRYPTO_DES_CBC,		NID_des_cbc,		8,	 8, },
+	{ CRYPTO_3DES_CBC,		NID_des_ede3_cbc,	8,	24, },
+	{ CRYPTO_AES_CBC,		NID_aes_128_cbc,	16,	16, },
+	{ CRYPTO_AES_CBC,		NID_aes_192_cbc,	16,	24, },
+	{ CRYPTO_AES_CBC,		NID_aes_256_cbc,	16,	32, },
+	{ CRYPTO_BLF_CBC,		NID_bf_cbc,		8,	16, },
+	{ CRYPTO_CAST_CBC,		NID_cast5_cbc,		8,	16, },
+	{ CRYPTO_SKIPJACK_CBC,		NID_undef,		0,	 0, },
+	{ 0,				NID_undef,		0,	 0, },
+};
+
+#ifdef USE_CRYPTODEV_DIGESTS
+static struct {
+	int	id;
+	int	nid;
+	int 	keylen;
+} digests[] = {
+	{ CRYPTO_MD5_HMAC,		NID_hmacWithMD5,	16},
+	{ CRYPTO_SHA1_HMAC,		NID_hmacWithSHA1,	20},
+	{ CRYPTO_RIPEMD160_HMAC,	NID_ripemd160,		16/*?*/},
+	{ CRYPTO_MD5_KPDK,		NID_undef,		0},
+	{ CRYPTO_SHA1_KPDK,		NID_undef,		0},
+	{ CRYPTO_MD5,			NID_md5,		16},
+	{ CRYPTO_SHA1,			NID_sha1,		20},
+	{ 0,				NID_undef,		0},
+};
+#endif
+
+/*
+ * Return a fd if /dev/crypto seems usable, 0 otherwise.
+ */
+static int
+open_dev_crypto(void)
+{
+	static int fd = -1;
+
+	if (fd == -1) {
+		if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1)
+			return (-1);
+		/* close on exec */
+		if (fcntl(fd, F_SETFD, 1) == -1) {
+			close(fd);
+			fd = -1;
+			return (-1);
+		}
+	}
+	return (fd);
+}
+
+static int
+get_dev_crypto(void)
+{
+	int fd, retfd;
+
+	if ((fd = open_dev_crypto()) == -1)
+		return (-1);
+	if (ioctl(fd, CRIOGET, &retfd) == -1)
+		return (-1);
+
+	/* close on exec */
+	if (fcntl(retfd, F_SETFD, 1) == -1) {
+		close(retfd);
+		return (-1);
+	}
+	return (retfd);
+}
+
+/* Caching version for asym operations */
+static int
+get_asym_dev_crypto(void)
+{
+	static int fd = -1;
+
+	if (fd == -1)
+		fd = get_dev_crypto();
+	return fd;
+}
+
+/*
+ * Find out what ciphers /dev/crypto will let us have a session for.
+ * XXX note, that some of these openssl doesn't deal with yet!
+ * returning them here is harmless, as long as we return NULL
+ * when asked for a handler in the cryptodev_engine_ciphers routine
+ */
+static int
+get_cryptodev_ciphers(const int **cnids)
+{
+	static int nids[CRYPTO_ALGORITHM_MAX];
+	struct session_op sess;
+	int fd, i, count = 0;
+
+	if ((fd = get_dev_crypto()) < 0) {
+		*cnids = NULL;
+		return (0);
+	}
+	memset(&sess, 0, sizeof(sess));
+	sess.key = (caddr_t)"123456789abcdefghijklmno";
+
+	for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
+		if (ciphers[i].nid == NID_undef)
+			continue;
+		sess.cipher = ciphers[i].id;
+		sess.keylen = ciphers[i].keylen;
+		sess.mac = 0;
+		if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
+		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
+			nids[count++] = ciphers[i].nid;
+	}
+	close(fd);
+
+	if (count > 0)
+		*cnids = nids;
+	else
+		*cnids = NULL;
+	return (count);
+}
+
+#ifdef USE_CRYPTODEV_DIGESTS
+/*
+ * Find out what digests /dev/crypto will let us have a session for.
+ * XXX note, that some of these openssl doesn't deal with yet!
+ * returning them here is harmless, as long as we return NULL
+ * when asked for a handler in the cryptodev_engine_digests routine
+ */
+static int
+get_cryptodev_digests(const int **cnids)
+{
+	static int nids[CRYPTO_ALGORITHM_MAX];
+	struct session_op sess;
+	int fd, i, count = 0;
+
+	if ((fd = get_dev_crypto()) < 0) {
+		*cnids = NULL;
+		return (0);
+	}
+	memset(&sess, 0, sizeof(sess));
+	sess.mackey = (caddr_t)"123456789abcdefghijklmno";
+	for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
+		if (digests[i].nid == NID_undef)
+			continue;
+		sess.mac = digests[i].id;
+		sess.mackeylen = digests[i].keylen;
+		sess.cipher = 0;
+		if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
+		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
+			nids[count++] = digests[i].nid;
+	}
+	close(fd);
+
+	if (count > 0)
+		*cnids = nids;
+	else
+		*cnids = NULL;
+	return (count);
+}
+#endif  /* 0 */
+
+/*
+ * Find the useable ciphers|digests from dev/crypto - this is the first
+ * thing called by the engine init crud which determines what it
+ * can use for ciphers from this engine. We want to return
+ * only what we can do, anythine else is handled by software.
+ *
+ * If we can't initialize the device to do anything useful for
+ * any reason, we want to return a NULL array, and 0 length,
+ * which forces everything to be done is software. By putting
+ * the initalization of the device in here, we ensure we can
+ * use this engine as the default, and if for whatever reason
+ * /dev/crypto won't do what we want it will just be done in
+ * software
+ *
+ * This can (should) be greatly expanded to perhaps take into
+ * account speed of the device, and what we want to do.
+ * (although the disabling of particular alg's could be controlled
+ * by the device driver with sysctl's.) - this is where we
+ * want most of the decisions made about what we actually want
+ * to use from /dev/crypto.
+ */
+static int
+cryptodev_usable_ciphers(const int **nids)
+{
+	return (get_cryptodev_ciphers(nids));
+}
+
+static int
+cryptodev_usable_digests(const int **nids)
+{
+#ifdef USE_CRYPTODEV_DIGESTS
+	return (get_cryptodev_digests(nids));
+#else
+	/*
+	 * XXXX just disable all digests for now, because it sucks.
+	 * we need a better way to decide this - i.e. I may not
+	 * want digests on slow cards like hifn on fast machines,
+	 * but might want them on slow or loaded machines, etc.
+	 * will also want them when using crypto cards that don't
+	 * suck moose gonads - would be nice to be able to decide something
+	 * as reasonable default without having hackery that's card dependent.
+	 * of course, the default should probably be just do everything,
+	 * with perhaps a sysctl to turn algoritms off (or have them off
+	 * by default) on cards that generally suck like the hifn.
+	 */
+	*nids = NULL;
+	return (0);
+#endif
+}
+
+static int
+cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	struct crypt_op cryp;
+	struct dev_crypto_state *state = ctx->cipher_data;
+	struct session_op *sess = &state->d_sess;
+	const void *iiv;
+	unsigned char save_iv[EVP_MAX_IV_LENGTH];
+
+	if (state->d_fd < 0)
+		return (0);
+	if (!inl)
+		return (1);
+	if ((inl % ctx->cipher->block_size) != 0)
+		return (0);
+
+	memset(&cryp, 0, sizeof(cryp));
+
+	cryp.ses = sess->ses;
+	cryp.flags = 0;
+	cryp.len = inl;
+	cryp.src = (caddr_t) in;
+	cryp.dst = (caddr_t) out;
+	cryp.mac = 0;
+
+	cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
+
+	if (ctx->cipher->iv_len) {
+		cryp.iv = (caddr_t) ctx->iv;
+		if (!ctx->encrypt) {
+			iiv = in + inl - ctx->cipher->iv_len;
+			memcpy(save_iv, iiv, ctx->cipher->iv_len);
+		}
+	} else
+		cryp.iv = NULL;
+
+	if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) {
+		/* XXX need better errror handling
+		 * this can fail for a number of different reasons.
+		 */
+		return (0);
+	}
+
+	if (ctx->cipher->iv_len) {
+		if (ctx->encrypt)
+			iiv = out + inl - ctx->cipher->iv_len;
+		else
+			iiv = save_iv;
+		memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
+	}
+	return (1);
+}
+
+static int
+cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	struct dev_crypto_state *state = ctx->cipher_data;
+	struct session_op *sess = &state->d_sess;
+	int cipher = -1, i;
+
+	for (i = 0; ciphers[i].id; i++)
+		if (ctx->cipher->nid == ciphers[i].nid &&
+		    ctx->cipher->iv_len <= ciphers[i].ivmax &&
+		    ctx->key_len == ciphers[i].keylen) {
+			cipher = ciphers[i].id;
+			break;
+		}
+
+	if (!ciphers[i].id) {
+		state->d_fd = -1;
+		return (0);
+	}
+
+	memset(sess, 0, sizeof(struct session_op));
+
+	if ((state->d_fd = get_dev_crypto()) < 0)
+		return (0);
+
+	sess->key = (caddr_t)key;
+	sess->keylen = ctx->key_len;
+	sess->cipher = cipher;
+
+	if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
+		close(state->d_fd);
+		state->d_fd = -1;
+		return (0);
+	}
+	return (1);
+}
+
+/*
+ * free anything we allocated earlier when initting a
+ * session, and close the session.
+ */
+static int
+cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
+{
+	int ret = 0;
+	struct dev_crypto_state *state = ctx->cipher_data;
+	struct session_op *sess = &state->d_sess;
+
+	if (state->d_fd < 0)
+		return (0);
+
+	/* XXX if this ioctl fails, someting's wrong. the invoker
+	 * may have called us with a bogus ctx, or we could
+	 * have a device that for whatever reason just doesn't
+	 * want to play ball - it's not clear what's right
+	 * here - should this be an error? should it just
+	 * increase a counter, hmm. For right now, we return
+	 * 0 - I don't believe that to be "right". we could
+	 * call the gorpy openssl lib error handlers that
+	 * print messages to users of the library. hmm..
+	 */
+
+	if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) {
+		ret = 0;
+	} else {
+		ret = 1;
+	}
+	close(state->d_fd);
+	state->d_fd = -1;
+
+	return (ret);
+}
+
+/*
+ * libcrypto EVP stuff - this is how we get wired to EVP so the engine
+ * gets called when libcrypto requests a cipher NID.
+ */
+
+/* RC4 */
+const EVP_CIPHER cryptodev_rc4 = {
+	NID_rc4,
+	1, 16, 0,
+	EVP_CIPH_VARIABLE_LENGTH,
+	cryptodev_init_key,
+	cryptodev_cipher,
+	cryptodev_cleanup,
+	sizeof(struct dev_crypto_state),
+	NULL,
+	NULL,
+	NULL
+};
+
+/* DES CBC EVP */
+const EVP_CIPHER cryptodev_des_cbc = {
+	NID_des_cbc,
+	8, 8, 8,
+	EVP_CIPH_CBC_MODE,
+	cryptodev_init_key,
+	cryptodev_cipher,
+	cryptodev_cleanup,
+	sizeof(struct dev_crypto_state),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+};
+
+/* 3DES CBC EVP */
+const EVP_CIPHER cryptodev_3des_cbc = {
+	NID_des_ede3_cbc,
+	8, 24, 8,
+	EVP_CIPH_CBC_MODE,
+	cryptodev_init_key,
+	cryptodev_cipher,
+	cryptodev_cleanup,
+	sizeof(struct dev_crypto_state),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+};
+
+const EVP_CIPHER cryptodev_bf_cbc = {
+	NID_bf_cbc,
+	8, 16, 8,
+	EVP_CIPH_CBC_MODE,
+	cryptodev_init_key,
+	cryptodev_cipher,
+	cryptodev_cleanup,
+	sizeof(struct dev_crypto_state),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+};
+
+const EVP_CIPHER cryptodev_cast_cbc = {
+	NID_cast5_cbc,
+	8, 16, 8,
+	EVP_CIPH_CBC_MODE,
+	cryptodev_init_key,
+	cryptodev_cipher,
+	cryptodev_cleanup,
+	sizeof(struct dev_crypto_state),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+};
+
+const EVP_CIPHER cryptodev_aes_cbc = {
+	NID_aes_128_cbc,
+	16, 16, 16,
+	EVP_CIPH_CBC_MODE,
+	cryptodev_init_key,
+	cryptodev_cipher,
+	cryptodev_cleanup,
+	sizeof(struct dev_crypto_state),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+};
+
+const EVP_CIPHER cryptodev_aes_192_cbc = {
+	NID_aes_192_cbc,
+	16, 24, 16,
+	EVP_CIPH_CBC_MODE,
+	cryptodev_init_key,
+	cryptodev_cipher,
+	cryptodev_cleanup,
+	sizeof(struct dev_crypto_state),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+};
+
+const EVP_CIPHER cryptodev_aes_256_cbc = {
+	NID_aes_256_cbc,
+	16, 32, 16,
+	EVP_CIPH_CBC_MODE,
+	cryptodev_init_key,
+	cryptodev_cipher,
+	cryptodev_cleanup,
+	sizeof(struct dev_crypto_state),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+};
+
+/*
+ * Registered by the ENGINE when used to find out how to deal with
+ * a particular NID in the ENGINE. this says what we'll do at the
+ * top level - note, that list is restricted by what we answer with
+ */
+static int
+cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
+    const int **nids, int nid)
+{
+	if (!cipher)
+		return (cryptodev_usable_ciphers(nids));
+
+	switch (nid) {
+	case NID_rc4:
+		*cipher = &cryptodev_rc4;
+		break;
+	case NID_des_ede3_cbc:
+		*cipher = &cryptodev_3des_cbc;
+		break;
+	case NID_des_cbc:
+		*cipher = &cryptodev_des_cbc;
+		break;
+	case NID_bf_cbc:
+		*cipher = &cryptodev_bf_cbc;
+		break;
+	case NID_cast5_cbc:
+		*cipher = &cryptodev_cast_cbc;
+		break;
+	case NID_aes_128_cbc:
+		*cipher = &cryptodev_aes_cbc;
+		break;
+	case NID_aes_192_cbc:
+		*cipher = &cryptodev_aes_192_cbc;
+		break;
+	case NID_aes_256_cbc:
+		*cipher = &cryptodev_aes_256_cbc;
+		break;
+	default:
+		*cipher = NULL;
+		break;
+	}
+	return (*cipher != NULL);
+}
+
+
+#ifdef USE_CRYPTODEV_DIGESTS
+
+/* convert digest type to cryptodev */
+static int
+digest_nid_to_cryptodev(int nid)
+{
+	int i;
+
+	for (i = 0; digests[i].id; i++)
+		if (digests[i].nid == nid)
+			return (digests[i].id);
+	return (0);
+}
+
+
+static int
+digest_key_length(int nid)
+{
+	int i;
+
+	for (i = 0; digests[i].id; i++)
+		if (digests[i].nid == nid)
+			return digests[i].keylen;
+	return (0);
+}
+
+
+static int cryptodev_digest_init(EVP_MD_CTX *ctx)
+{
+	struct dev_crypto_state *state = ctx->md_data;
+	struct session_op *sess = &state->d_sess;
+	int digest;
+
+	if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef){
+		printf("cryptodev_digest_init: Can't get digest \n");
+		return (0);
+	}
+
+	memset(state, 0, sizeof(struct dev_crypto_state));
+
+	if ((state->d_fd = get_dev_crypto()) < 0) {
+		printf("cryptodev_digest_init: Can't get Dev \n");
+		return (0);
+	}
+
+	sess->mackey = state->dummy_mac_key;
+	sess->mackeylen = digest_key_length(ctx->digest->type);
+	sess->mac = digest;
+
+	if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
+		close(state->d_fd);
+		state->d_fd = -1;
+		printf("cryptodev_digest_init: Open session failed\n");
+		return (0);
+	}
+
+	return (1);
+}
+
+static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data,
+		size_t count)
+{
+	struct crypt_op cryp;
+	struct dev_crypto_state *state = ctx->md_data;
+	struct session_op *sess = &state->d_sess;
+
+	if (!data || state->d_fd < 0) {
+		printf("cryptodev_digest_update: illegal inputs \n");
+		return (0);
+	}
+
+	if (!count) {
+		return (0);
+	}
+
+	if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) {
+		/* if application doesn't support one buffer */
+		state->mac_data = OPENSSL_realloc(state->mac_data, state->mac_len + count);
+
+		if (!state->mac_data) {
+			printf("cryptodev_digest_update: realloc failed\n");
+			return (0);
+		}
+
+		memcpy(state->mac_data + state->mac_len, data, count);
+   		state->mac_len += count;
+	
+		return (1);
+	}
+
+	memset(&cryp, 0, sizeof(cryp));
+
+	cryp.ses = sess->ses;
+	cryp.flags = 0;
+	cryp.len = count;
+	cryp.src = (caddr_t) data;
+	cryp.dst = NULL;
+	cryp.mac = (caddr_t) state->digest_res;
+	if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
+		printf("cryptodev_digest_update: digest failed\n");
+		return (0);
+	}
+	return (1);
+}
+
+
+static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	struct crypt_op cryp;
+	struct dev_crypto_state *state = ctx->md_data;
+	struct session_op *sess = &state->d_sess;
+
+	int ret = 1;
+
+	if (!md || state->d_fd < 0) {
+		printf("cryptodev_digest_final: illegal input\n");
+		return(0);
+	}
+
+	if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) {
+		/* if application doesn't support one buffer */
+		memset(&cryp, 0, sizeof(cryp));
+
+		cryp.ses = sess->ses;
+		cryp.flags = 0;
+		cryp.len = state->mac_len;
+		cryp.src = state->mac_data;
+		cryp.dst = NULL;
+		cryp.mac = (caddr_t)md;
+
+		if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
+			printf("cryptodev_digest_final: digest failed\n");
+			return (0);
+		}
+
+		return 1;
+	}
+
+	memcpy(md, state->digest_res, ctx->digest->md_size);
+
+	return (ret);
+}
+
+
+static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
+{
+	int ret = 1;
+	struct dev_crypto_state *state = ctx->md_data;
+	struct session_op *sess = &state->d_sess;
+
+	if (state->d_fd < 0) {
+		printf("cryptodev_digest_cleanup: illegal input\n");
+		return (0);
+	}
+
+	if (state->mac_data) {
+		OPENSSL_free(state->mac_data);
+		state->mac_data = NULL;
+		state->mac_len = 0;
+	}
+
+	if (state->copy)
+		return 1;
+
+	if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
+		printf("cryptodev_digest_cleanup: failed to close session\n");
+		ret = 0;
+	} else {
+		ret = 1;
+	}
+	close(state->d_fd);	
+	state->d_fd = -1;
+
+	return (ret);
+}
+
+static int cryptodev_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
+{
+	struct dev_crypto_state *fstate = from->md_data;
+	struct dev_crypto_state *dstate = to->md_data;
+
+	memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
+
+	if (fstate->mac_len != 0) {
+		dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
+		memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
+	}
+
+	dstate->copy = 1;
+
+	return 1;
+}
+
+
+const EVP_MD cryptodev_sha1 = {
+	NID_sha1,
+	NID_undef, 
+	SHA_DIGEST_LENGTH, 
+	EVP_MD_FLAG_ONESHOT,
+	cryptodev_digest_init,
+	cryptodev_digest_update,
+	cryptodev_digest_final,
+	cryptodev_digest_copy,
+	cryptodev_digest_cleanup,
+	EVP_PKEY_NULL_method,
+	SHA_CBLOCK,
+	sizeof(struct dev_crypto_state),
+};
+
+const EVP_MD cryptodev_md5 = {
+	NID_md5,
+	NID_undef, 
+	16 /* MD5_DIGEST_LENGTH */, 
+	EVP_MD_FLAG_ONESHOT,
+	cryptodev_digest_init,
+	cryptodev_digest_update,
+	cryptodev_digest_final,
+	cryptodev_digest_copy,
+	cryptodev_digest_cleanup,
+	EVP_PKEY_NULL_method,
+	64 /* MD5_CBLOCK */,
+	sizeof(struct dev_crypto_state),
+};
+
+#endif /* USE_CRYPTODEV_DIGESTS */
+
+
+static int
+cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
+    const int **nids, int nid)
+{
+	if (!digest)
+		return (cryptodev_usable_digests(nids));
+
+	switch (nid) {
+#ifdef USE_CRYPTODEV_DIGESTS
+	case NID_md5:
+		*digest = &cryptodev_md5; 
+		break;
+	case NID_sha1:
+		*digest = &cryptodev_sha1;
+ 		break;
+	default:
+#endif /* USE_CRYPTODEV_DIGESTS */
+		*digest = NULL;
+		break;
+	}
+	return (*digest != NULL);
+}
+
+/*
+ * Convert a BIGNUM to the representation that /dev/crypto needs.
+ * Upon completion of use, the caller is responsible for freeing
+ * crp->crp_p.
+ */
+static int
+bn2crparam(const BIGNUM *a, struct crparam *crp)
+{
+	int i, j, k;
+	ssize_t bytes, bits;
+	u_char *b;
+
+	crp->crp_p = NULL;
+	crp->crp_nbits = 0;
+
+	bits = BN_num_bits(a);
+	bytes = (bits + 7) / 8;
+
+	b = malloc(bytes);
+	if (b == NULL)
+		return (1);
+	memset(b, 0, bytes);
+
+	crp->crp_p = (caddr_t) b;
+	crp->crp_nbits = bits;
+
+	for (i = 0, j = 0; i < a->top; i++) {
+		for (k = 0; k < BN_BITS2 / 8; k++) {
+			if ((j + k) >= bytes)
+				return (0);
+			b[j + k] = a->d[i] >> (k * 8);
+		}
+		j += BN_BITS2 / 8;
+	}
+	return (0);
+}
+
+/* Convert a /dev/crypto parameter to a BIGNUM */
+static int
+crparam2bn(struct crparam *crp, BIGNUM *a)
+{
+	u_int8_t *pd;
+	int i, bytes;
+
+	bytes = (crp->crp_nbits + 7) / 8;
+
+	if (bytes == 0)
+		return (-1);
+
+	if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
+		return (-1);
+
+	for (i = 0; i < bytes; i++)
+		pd[i] = crp->crp_p[bytes - i - 1];
+
+	BN_bin2bn(pd, bytes, a);
+	free(pd);
+
+	return (0);
+}
+
+static void
+zapparams(struct crypt_kop *kop)
+{
+	int i;
+
+	for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) {
+		if (kop->crk_param[i].crp_p)
+			free(kop->crk_param[i].crp_p);
+		kop->crk_param[i].crp_p = NULL;
+		kop->crk_param[i].crp_nbits = 0;
+	}
+}
+
+static int
+cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
+{
+	int fd, ret = -1;
+
+	if ((fd = get_asym_dev_crypto()) < 0)
+		return (ret);
+
+	if (r) {
+		kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char));
+		kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
+		kop->crk_oparams++;
+	}
+	if (s) {
+		kop->crk_param[kop->crk_iparams+1].crp_p = calloc(slen, sizeof(char));
+		kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8;
+		kop->crk_oparams++;
+	}
+
+	if (ioctl(fd, CIOCKEY, kop) == 0) {
+		if (r)
+			crparam2bn(&kop->crk_param[kop->crk_iparams], r);
+		if (s)
+			crparam2bn(&kop->crk_param[kop->crk_iparams+1], s);
+		ret = 0;
+	}
+
+	return (ret);
+}
+
+static int
+cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+{
+	struct crypt_kop kop;
+	int ret = 1;
+
+	/* Currently, we know we can do mod exp iff we can do any
+	 * asymmetric operations at all.
+	 */
+	if (cryptodev_asymfeat == 0) {
+		ret = BN_mod_exp(r, a, p, m, ctx);
+		return (ret);
+	}
+
+	memset(&kop, 0, sizeof kop);
+	kop.crk_op = CRK_MOD_EXP;
+
+	/* inputs: a^p % m */
+	if (bn2crparam(a, &kop.crk_param[0]))
+		goto err;
+	if (bn2crparam(p, &kop.crk_param[1]))
+		goto err;
+	if (bn2crparam(m, &kop.crk_param[2]))
+		goto err;
+	kop.crk_iparams = 3;
+
+	if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) {
+		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+		printf("OCF asym process failed, Running in software\n");
+		ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
+
+	} else if (ECANCELED == kop.crk_status) {
+		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+		printf("OCF hardware operation cancelled. Running in Software\n");
+		ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
+	}
+	/* else cryptodev operation worked ok ==> ret = 1*/
+
+err:
+	zapparams(&kop);
+	return (ret);
+}
+
+static int
+cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+{
+	int r;
+	ctx = BN_CTX_new();
+	r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL);
+	BN_CTX_free(ctx);
+	return (r);
+}
+
+static int
+cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+{
+	struct crypt_kop kop;
+	int ret = 1;
+
+	if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
+		/* XXX 0 means failure?? */
+		return (0);
+	}
+
+	memset(&kop, 0, sizeof kop);
+	kop.crk_op = CRK_MOD_EXP_CRT;
+	/* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
+	if (bn2crparam(rsa->p, &kop.crk_param[0]))
+		goto err;
+	if (bn2crparam(rsa->q, &kop.crk_param[1]))
+		goto err;
+	if (bn2crparam(I, &kop.crk_param[2]))
+		goto err;
+	if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
+		goto err;
+	if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
+		goto err;
+	if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
+		goto err;
+	kop.crk_iparams = 6;
+
+	if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) {
+		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+		printf("OCF asym process failed, running in Software\n");
+		ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
+
+	} else if (ECANCELED == kop.crk_status) {
+		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+		printf("OCF hardware operation cancelled. Running in Software\n");
+		ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
+	}
+	/* else cryptodev operation worked ok ==> ret = 1*/
+
+err:
+	zapparams(&kop);
+	return (ret);
+}
+
+static RSA_METHOD cryptodev_rsa = {
+	"cryptodev RSA method",
+	NULL,				/* rsa_pub_enc */
+	NULL,				/* rsa_pub_dec */
+	NULL,				/* rsa_priv_enc */
+	NULL,				/* rsa_priv_dec */
+	NULL,
+	NULL,
+	NULL,				/* init */
+	NULL,				/* finish */
+	0,				/* flags */
+	NULL,				/* app_data */
+	NULL,				/* rsa_sign */
+	NULL				/* rsa_verify */
+};
+
+static int
+cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+{
+	return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
+}
+
+static int
+cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
+    BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
+    BN_CTX *ctx, BN_MONT_CTX *mont)
+{
+	BIGNUM t2;
+	int ret = 0;
+
+	BN_init(&t2);
+
+	/* v = ( g^u1 * y^u2 mod p ) mod q */
+	/* let t1 = g ^ u1 mod p */
+	ret = 0;
+
+	if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont))
+		goto err;
+
+	/* let t2 = y ^ u2 mod p */
+	if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont))
+		goto err;
+	/* let u1 = t1 * t2 mod p */
+	if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx))
+		goto err;
+
+	BN_copy(t1,u1);
+
+	ret = 1;
+err:
+	BN_free(&t2);
+	return(ret);
+}
+
+static DSA_SIG *
+cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+{
+	struct crypt_kop kop;
+	BIGNUM *r = NULL, *s = NULL;
+	DSA_SIG *dsaret = NULL;
+
+	if ((r = BN_new()) == NULL)
+		goto err;
+	if ((s = BN_new()) == NULL) {
+		BN_free(r);
+		goto err;
+	}
+
+	memset(&kop, 0, sizeof kop);
+	kop.crk_op = CRK_DSA_SIGN;
+
+	/* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
+	kop.crk_param[0].crp_p = (caddr_t)dgst;
+	kop.crk_param[0].crp_nbits = dlen * 8;
+	if (bn2crparam(dsa->p, &kop.crk_param[1]))
+		goto err;
+	if (bn2crparam(dsa->q, &kop.crk_param[2]))
+		goto err;
+	if (bn2crparam(dsa->g, &kop.crk_param[3]))
+		goto err;
+	if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
+		goto err;
+	kop.crk_iparams = 5;
+
+	if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r,
+	    BN_num_bytes(dsa->q), s) == 0) {
+		dsaret = DSA_SIG_new();
+		dsaret->r = r;
+		dsaret->s = s;
+	} else {
+		const DSA_METHOD *meth = DSA_OpenSSL();
+		BN_free(r);
+		BN_free(s);
+		dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
+	}
+err:
+	kop.crk_param[0].crp_p = NULL;
+	zapparams(&kop);
+	return (dsaret);
+}
+
+static int
+cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
+    DSA_SIG *sig, DSA *dsa)
+{
+	struct crypt_kop kop;
+	int dsaret = 1;
+
+	memset(&kop, 0, sizeof kop);
+	kop.crk_op = CRK_DSA_VERIFY;
+
+	/* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
+	kop.crk_param[0].crp_p = (caddr_t)dgst;
+	kop.crk_param[0].crp_nbits = dlen * 8;
+	if (bn2crparam(dsa->p, &kop.crk_param[1]))
+		goto err;
+	if (bn2crparam(dsa->q, &kop.crk_param[2]))
+		goto err;
+	if (bn2crparam(dsa->g, &kop.crk_param[3]))
+		goto err;
+	if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
+		goto err;
+	if (bn2crparam(sig->r, &kop.crk_param[5]))
+		goto err;
+	if (bn2crparam(sig->s, &kop.crk_param[6]))
+		goto err;
+	kop.crk_iparams = 7;
+
+	if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
+/*OCF success value is 0, if not zero, change dsaret to fail*/
+		if(0 != kop.crk_status) dsaret  = 0;
+	} else {
+		const DSA_METHOD *meth = DSA_OpenSSL();
+
+		dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
+	}
+err:
+	kop.crk_param[0].crp_p = NULL;
+	zapparams(&kop);
+	return (dsaret);
+}
+
+static DSA_METHOD cryptodev_dsa = {
+	"cryptodev DSA method",
+	NULL,
+	NULL,				/* dsa_sign_setup */
+	NULL,
+	NULL,				/* dsa_mod_exp */
+	NULL,
+	NULL,				/* init */
+	NULL,				/* finish */
+	0,	/* flags */
+	NULL	/* app_data */
+};
+
+static int
+cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
+    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+    BN_MONT_CTX *m_ctx)
+{
+	return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
+}
+
+static int
+cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+{
+	struct crypt_kop kop;
+	int dhret = 1;
+	int fd, keylen;
+
+	if ((fd = get_asym_dev_crypto()) < 0) {
+		const DH_METHOD *meth = DH_OpenSSL();
+
+		return ((meth->compute_key)(key, pub_key, dh));
+	}
+
+	keylen = BN_num_bits(dh->p);
+
+	memset(&kop, 0, sizeof kop);
+	kop.crk_op = CRK_DH_COMPUTE_KEY;
+
+	/* inputs: dh->priv_key pub_key dh->p key */
+	if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
+		goto err;
+	if (bn2crparam(pub_key, &kop.crk_param[1]))
+		goto err;
+	if (bn2crparam(dh->p, &kop.crk_param[2]))
+		goto err;
+	kop.crk_iparams = 3;
+
+	kop.crk_param[3].crp_p = (caddr_t) key;
+	kop.crk_param[3].crp_nbits = keylen * 8;
+	kop.crk_oparams = 1;
+
+	if (ioctl(fd, CIOCKEY, &kop) == -1) {
+		const DH_METHOD *meth = DH_OpenSSL();
+
+		dhret = (meth->compute_key)(key, pub_key, dh);
+	}
+err:
+	kop.crk_param[3].crp_p = NULL;
+	zapparams(&kop);
+	return (dhret);
+}
+
+static DH_METHOD cryptodev_dh = {
+	"cryptodev DH method",
+	NULL,				/* cryptodev_dh_generate_key */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	0,	/* flags */
+	NULL	/* app_data */
+};
+
+/*
+ * ctrl right now is just a wrapper that doesn't do much
+ * but I expect we'll want some options soon.
+ */
+static int
+cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+{
+#ifdef HAVE_SYSLOG_R
+	struct syslog_data sd = SYSLOG_DATA_INIT;
+#endif
+
+	switch (cmd) {
+	default:
+#ifdef HAVE_SYSLOG_R
+		syslog_r(LOG_ERR, &sd,
+		    "cryptodev_ctrl: unknown command %d", cmd);
+#else
+		syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd);
+#endif
+		break;
+	}
+	return (1);
+}
+
+void
+ENGINE_load_cryptodev(void)
+{
+	ENGINE *engine = ENGINE_new();
+	int fd;
+
+	if (engine == NULL)
+		return;
+	if ((fd = get_dev_crypto()) < 0) {
+		ENGINE_free(engine);
+		return;
+	}
+
+	/*
+	 * find out what asymmetric crypto algorithms we support
+	 */
+	if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
+		close(fd);
+		ENGINE_free(engine);
+		return;
+	}
+	close(fd);
+
+	if (!ENGINE_set_id(engine, "cryptodev") ||
+	    !ENGINE_set_name(engine, "BSD cryptodev engine") ||
+	    !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) ||
+	    !ENGINE_set_digests(engine, cryptodev_engine_digests) ||
+	    !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) ||
+	    !ENGINE_set_cmd_defns(engine, cryptodev_defns)) {
+		ENGINE_free(engine);
+		return;
+	}
+
+	if (ENGINE_set_RSA(engine, &cryptodev_rsa)) {
+		const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay();
+
+		cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp;
+		cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp;
+		cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc;
+		cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec;
+		cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc;
+		cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec;
+		if (cryptodev_asymfeat & CRF_MOD_EXP) {
+			cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp;
+			if (cryptodev_asymfeat & CRF_MOD_EXP_CRT)
+				cryptodev_rsa.rsa_mod_exp =
+				    cryptodev_rsa_mod_exp;
+			else
+				cryptodev_rsa.rsa_mod_exp =
+				    cryptodev_rsa_nocrt_mod_exp;
+		}
+	}
+
+	if (ENGINE_set_DSA(engine, &cryptodev_dsa)) {
+		const DSA_METHOD *meth = DSA_OpenSSL();
+
+		memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
+		if (cryptodev_asymfeat & CRF_DSA_SIGN)
+			cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
+		if (cryptodev_asymfeat & CRF_MOD_EXP) {
+			cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp;
+			cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp;
+		}
+		if (cryptodev_asymfeat & CRF_DSA_VERIFY)
+			cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
+	}
+
+	if (ENGINE_set_DH(engine, &cryptodev_dh)){
+		const DH_METHOD *dh_meth = DH_OpenSSL();
+
+		cryptodev_dh.generate_key = dh_meth->generate_key;
+		cryptodev_dh.compute_key = dh_meth->compute_key;
+		cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp;
+		if (cryptodev_asymfeat & CRF_MOD_EXP) {
+			cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh;
+			if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
+				cryptodev_dh.compute_key =
+				    cryptodev_dh_compute_key;
+		}
+	}
+
+	ENGINE_add(engine);
+	ENGINE_free(engine);
+	ERR_clear_error();
+}
+
+#endif /* HAVE_CRYPTODEV */
diff --git a/openssl/crypto/engine/eng_ctrl.c b/openssl/crypto/engine/eng_ctrl.c
new file mode 100644
index 0000000..5ce25d9
--- /dev/null
+++ b/openssl/crypto/engine/eng_ctrl.c
@@ -0,0 +1,389 @@
+/* crypto/engine/eng_ctrl.c */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* When querying a ENGINE-specific control command's 'description', this string
+ * is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. */
+static const char *int_no_description = "";
+
+/* These internal functions handle 'CMD'-related control commands when the
+ * ENGINE in question has asked us to take care of it (ie. the ENGINE did not
+ * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. */
+
+static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn)
+	{
+	if((defn->cmd_num == 0) || (defn->cmd_name == NULL))
+		return 1;
+	return 0;
+	}
+
+static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s)
+	{
+	int idx = 0;
+	while(!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0))
+		{
+		idx++;
+		defn++;
+		}
+	if(int_ctrl_cmd_is_null(defn))
+		/* The given name wasn't found */
+		return -1;
+	return idx;
+	}
+
+static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num)
+	{
+	int idx = 0;
+	/* NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So
+	 * our searches don't need to take any longer than necessary. */
+	while(!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num))
+		{
+		idx++;
+		defn++;
+		}
+	if(defn->cmd_num == num)
+		return idx;
+	/* The given cmd_num wasn't found */
+	return -1;
+	}
+
+static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p,
+			   void (*f)(void))
+	{
+	int idx;
+	char *s = (char *)p;
+	/* Take care of the easy one first (eg. it requires no searches) */
+	if(cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE)
+		{
+		if((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns))
+			return 0;
+		return e->cmd_defns->cmd_num;
+		}
+	/* One or two commands require that "p" be a valid string buffer */
+	if((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) ||
+			(cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) ||
+			(cmd == ENGINE_CTRL_GET_DESC_FROM_CMD))
+		{
+		if(s == NULL)
+			{
+			ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
+				ERR_R_PASSED_NULL_PARAMETER);
+			return -1;
+			}
+		}
+	/* Now handle cmd_name -> cmd_num conversion */
+	if(cmd == ENGINE_CTRL_GET_CMD_FROM_NAME)
+		{
+		if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_name(
+						e->cmd_defns, s)) < 0))
+			{
+			ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
+				ENGINE_R_INVALID_CMD_NAME);
+			return -1;
+			}
+		return e->cmd_defns[idx].cmd_num;
+		}
+	/* For the rest of the commands, the 'long' argument must specify a
+	 * valie command number - so we need to conduct a search. */
+	if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns,
+					(unsigned int)i)) < 0))
+		{
+		ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
+			ENGINE_R_INVALID_CMD_NUMBER);
+		return -1;
+		}
+	/* Now the logic splits depending on command type */
+	switch(cmd)
+		{
+	case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
+		idx++;
+		if(int_ctrl_cmd_is_null(e->cmd_defns + idx))
+			/* end-of-list */
+			return 0;
+		else
+			return e->cmd_defns[idx].cmd_num;
+	case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
+		return strlen(e->cmd_defns[idx].cmd_name);
+	case ENGINE_CTRL_GET_NAME_FROM_CMD:
+		return BIO_snprintf(s,strlen(e->cmd_defns[idx].cmd_name) + 1,
+				    "%s", e->cmd_defns[idx].cmd_name);
+	case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
+		if(e->cmd_defns[idx].cmd_desc)
+			return strlen(e->cmd_defns[idx].cmd_desc);
+		return strlen(int_no_description);
+	case ENGINE_CTRL_GET_DESC_FROM_CMD:
+		if(e->cmd_defns[idx].cmd_desc)
+			return BIO_snprintf(s,
+					    strlen(e->cmd_defns[idx].cmd_desc) + 1,
+					    "%s", e->cmd_defns[idx].cmd_desc);
+		return BIO_snprintf(s, strlen(int_no_description) + 1,"%s",
+				    int_no_description);
+	case ENGINE_CTRL_GET_CMD_FLAGS:
+		return e->cmd_defns[idx].cmd_flags;
+		}
+	/* Shouldn't really be here ... */
+	ENGINEerr(ENGINE_F_INT_CTRL_HELPER,ENGINE_R_INTERNAL_LIST_ERROR);
+	return -1;
+	}
+
+int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+	{
+	int ctrl_exists, ref_exists;
+	if(e == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	ref_exists = ((e->struct_ref > 0) ? 1 : 0);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	ctrl_exists = ((e->ctrl == NULL) ? 0 : 1);
+	if(!ref_exists)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_REFERENCE);
+		return 0;
+		}
+	/* Intercept any "root-level" commands before trying to hand them on to
+	 * ctrl() handlers. */
+	switch(cmd)
+		{
+	case ENGINE_CTRL_HAS_CTRL_FUNCTION:
+		return ctrl_exists;
+	case ENGINE_CTRL_GET_FIRST_CMD_TYPE:
+	case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
+	case ENGINE_CTRL_GET_CMD_FROM_NAME:
+	case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
+	case ENGINE_CTRL_GET_NAME_FROM_CMD:
+	case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
+	case ENGINE_CTRL_GET_DESC_FROM_CMD:
+	case ENGINE_CTRL_GET_CMD_FLAGS:
+		if(ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL))
+			return int_ctrl_helper(e,cmd,i,p,f);
+		if(!ctrl_exists)
+			{
+			ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
+			/* For these cmd-related functions, failure is indicated
+			 * by a -1 return value (because 0 is used as a valid
+			 * return in some places). */
+			return -1;
+			}
+	default:
+		break;
+		}
+	/* Anything else requires a ctrl() handler to exist. */
+	if(!ctrl_exists)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
+		return 0;
+		}
+	return e->ctrl(e, cmd, i, p, f);
+	}
+
+int ENGINE_cmd_is_executable(ENGINE *e, int cmd)
+	{
+	int flags;
+	if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE,
+			ENGINE_R_INVALID_CMD_NUMBER);
+		return 0;
+		}
+	if(!(flags & ENGINE_CMD_FLAG_NO_INPUT) &&
+			!(flags & ENGINE_CMD_FLAG_NUMERIC) &&
+			!(flags & ENGINE_CMD_FLAG_STRING))
+		return 0;
+	return 1;
+	}
+
+int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
+        long i, void *p, void (*f)(void), int cmd_optional)
+        {
+	int num;
+
+	if((e == NULL) || (cmd_name == NULL))
+		{
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
+					ENGINE_CTRL_GET_CMD_FROM_NAME,
+					0, (void *)cmd_name, NULL)) <= 0))
+		{
+		/* If the command didn't *have* to be supported, we fake
+		 * success. This allows certain settings to be specified for
+		 * multiple ENGINEs and only require a change of ENGINE id
+		 * (without having to selectively apply settings). Eg. changing
+		 * from a hardware device back to the regular software ENGINE
+		 * without editing the config file, etc. */
+		if(cmd_optional)
+			{
+			ERR_clear_error();
+			return 1;
+			}
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
+			ENGINE_R_INVALID_CMD_NAME);
+		return 0;
+		}
+	/* Force the result of the control command to 0 or 1, for the reasons
+	 * mentioned before. */
+        if (ENGINE_ctrl(e, num, i, p, f) > 0)
+                return 1;
+        return 0;
+        }
+
+int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
+				int cmd_optional)
+	{
+	int num, flags;
+	long l;
+	char *ptr;
+	if((e == NULL) || (cmd_name == NULL))
+		{
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
+					ENGINE_CTRL_GET_CMD_FROM_NAME,
+					0, (void *)cmd_name, NULL)) <= 0))
+		{
+		/* If the command didn't *have* to be supported, we fake
+		 * success. This allows certain settings to be specified for
+		 * multiple ENGINEs and only require a change of ENGINE id
+		 * (without having to selectively apply settings). Eg. changing
+		 * from a hardware device back to the regular software ENGINE
+		 * without editing the config file, etc. */
+		if(cmd_optional)
+			{
+			ERR_clear_error();
+			return 1;
+			}
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+			ENGINE_R_INVALID_CMD_NAME);
+		return 0;
+		}
+	if(!ENGINE_cmd_is_executable(e, num))
+		{
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+			ENGINE_R_CMD_NOT_EXECUTABLE);
+		return 0;
+		}
+	if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0)
+		{
+		/* Shouldn't happen, given that ENGINE_cmd_is_executable()
+		 * returned success. */
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+			ENGINE_R_INTERNAL_LIST_ERROR);
+		return 0;
+		}
+	/* If the command takes no input, there must be no input. And vice
+	 * versa. */
+	if(flags & ENGINE_CMD_FLAG_NO_INPUT)
+		{
+		if(arg != NULL)
+			{
+			ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+				ENGINE_R_COMMAND_TAKES_NO_INPUT);
+			return 0;
+			}
+		/* We deliberately force the result of ENGINE_ctrl() to 0 or 1
+		 * rather than returning it as "return data". This is to ensure
+		 * usage of these commands is consistent across applications and
+		 * that certain applications don't understand it one way, and
+		 * others another. */
+		if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
+			return 1;
+		return 0;
+		}
+	/* So, we require input */
+	if(arg == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+			ENGINE_R_COMMAND_TAKES_INPUT);
+		return 0;
+		}
+	/* If it takes string input, that's easy */
+	if(flags & ENGINE_CMD_FLAG_STRING)
+		{
+		/* Same explanation as above */
+		if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
+			return 1;
+		return 0;
+		}
+	/* If it doesn't take numeric either, then it is unsupported for use in
+	 * a config-setting situation, which is what this function is for. This
+	 * should never happen though, because ENGINE_cmd_is_executable() was
+	 * used. */
+	if(!(flags & ENGINE_CMD_FLAG_NUMERIC))
+		{
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+			ENGINE_R_INTERNAL_LIST_ERROR);
+		return 0;
+		}
+	l = strtol(arg, &ptr, 10);
+	if((arg == ptr) || (*ptr != '\0'))
+		{
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+			ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER);
+		return 0;
+		}
+	/* Force the result of the control command to 0 or 1, for the reasons
+	 * mentioned before. */
+	if(ENGINE_ctrl(e, num, l, NULL, NULL) > 0)
+		return 1;
+	return 0;
+	}
diff --git a/openssl/crypto/engine/eng_dyn.c b/openssl/crypto/engine/eng_dyn.c
new file mode 100644
index 0000000..807da7a
--- /dev/null
+++ b/openssl/crypto/engine/eng_dyn.c
@@ -0,0 +1,548 @@
+/* crypto/engine/eng_dyn.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include "eng_int.h"
+#include <openssl/dso.h>
+
+/* Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE loader
+ * should implement the hook-up functions with the following prototypes. */
+
+/* Our ENGINE handlers */
+static int dynamic_init(ENGINE *e);
+static int dynamic_finish(ENGINE *e);
+static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+/* Predeclare our context type */
+typedef struct st_dynamic_data_ctx dynamic_data_ctx;
+/* The implementation for the important control command */
+static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx);
+
+#define DYNAMIC_CMD_SO_PATH		ENGINE_CMD_BASE
+#define DYNAMIC_CMD_NO_VCHECK		(ENGINE_CMD_BASE + 1)
+#define DYNAMIC_CMD_ID			(ENGINE_CMD_BASE + 2)
+#define DYNAMIC_CMD_LIST_ADD		(ENGINE_CMD_BASE + 3)
+#define DYNAMIC_CMD_DIR_LOAD		(ENGINE_CMD_BASE + 4)
+#define DYNAMIC_CMD_DIR_ADD		(ENGINE_CMD_BASE + 5)
+#define DYNAMIC_CMD_LOAD		(ENGINE_CMD_BASE + 6)
+
+/* The constants used when creating the ENGINE */
+static const char *engine_dynamic_id = "dynamic";
+static const char *engine_dynamic_name = "Dynamic engine loading support";
+static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = {
+	{DYNAMIC_CMD_SO_PATH,
+		"SO_PATH",
+		"Specifies the path to the new ENGINE shared library",
+		ENGINE_CMD_FLAG_STRING},
+	{DYNAMIC_CMD_NO_VCHECK,
+		"NO_VCHECK",
+		"Specifies to continue even if version checking fails (boolean)",
+		ENGINE_CMD_FLAG_NUMERIC},
+	{DYNAMIC_CMD_ID,
+		"ID",
+		"Specifies an ENGINE id name for loading",
+		ENGINE_CMD_FLAG_STRING},
+	{DYNAMIC_CMD_LIST_ADD,
+		"LIST_ADD",
+		"Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)",
+		ENGINE_CMD_FLAG_NUMERIC},
+	{DYNAMIC_CMD_DIR_LOAD,
+		"DIR_LOAD",
+		"Specifies whether to load from 'DIR_ADD' directories (0=no,1=yes,2=mandatory)",
+		ENGINE_CMD_FLAG_NUMERIC},
+	{DYNAMIC_CMD_DIR_ADD,
+		"DIR_ADD",
+		"Adds a directory from which ENGINEs can be loaded",
+		ENGINE_CMD_FLAG_STRING},
+	{DYNAMIC_CMD_LOAD,
+		"LOAD",
+		"Load up the ENGINE specified by other settings",
+		ENGINE_CMD_FLAG_NO_INPUT},
+	{0, NULL, NULL, 0}
+	};
+static const ENGINE_CMD_DEFN dynamic_cmd_defns_empty[] = {
+	{0, NULL, NULL, 0}
+	};
+
+/* Loading code stores state inside the ENGINE structure via the "ex_data"
+ * element. We load all our state into a single structure and use that as a
+ * single context in the "ex_data" stack. */
+struct st_dynamic_data_ctx
+	{
+	/* The DSO object we load that supplies the ENGINE code */
+	DSO *dynamic_dso;
+	/* The function pointer to the version checking shared library function */
+	dynamic_v_check_fn v_check;
+	/* The function pointer to the engine-binding shared library function */
+	dynamic_bind_engine bind_engine;
+	/* The default name/path for loading the shared library */
+	const char *DYNAMIC_LIBNAME;
+	/* Whether to continue loading on a version check failure */
+	int no_vcheck;
+	/* If non-NULL, stipulates the 'id' of the ENGINE to be loaded */
+	const char *engine_id;
+	/* If non-zero, a successfully loaded ENGINE should be added to the internal
+	 * ENGINE list. If 2, the add must succeed or the entire load should fail. */
+	int list_add_value;
+	/* The symbol name for the version checking function */
+	const char *DYNAMIC_F1;
+	/* The symbol name for the "initialise ENGINE structure" function */
+	const char *DYNAMIC_F2;
+	/* Whether to never use 'dirs', use 'dirs' as a fallback, or only use
+	 * 'dirs' for loading. Default is to use 'dirs' as a fallback. */
+	int dir_load;
+	/* A stack of directories from which ENGINEs could be loaded */
+	STACK_OF(OPENSSL_STRING) *dirs;
+	};
+
+/* This is the "ex_data" index we obtain and reserve for use with our context
+ * structure. */
+static int dynamic_ex_data_idx = -1;
+
+static void int_free_str(char *s) { OPENSSL_free(s); }
+/* Because our ex_data element may or may not get allocated depending on whether
+ * a "first-use" occurs before the ENGINE is freed, we have a memory leak
+ * problem to solve. We can't declare a "new" handler for the ex_data as we
+ * don't want a dynamic_data_ctx in *all* ENGINE structures of all types (this
+ * is a bug in the design of CRYPTO_EX_DATA). As such, we just declare a "free"
+ * handler and that will get called if an ENGINE is being destroyed and there
+ * was an ex_data element corresponding to our context type. */
+static void dynamic_data_ctx_free_func(void *parent, void *ptr,
+			CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
+	{
+	if(ptr)
+		{
+		dynamic_data_ctx *ctx = (dynamic_data_ctx *)ptr;
+		if(ctx->dynamic_dso)
+			DSO_free(ctx->dynamic_dso);
+		if(ctx->DYNAMIC_LIBNAME)
+			OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME);
+		if(ctx->engine_id)
+			OPENSSL_free((void*)ctx->engine_id);
+		if(ctx->dirs)
+			sk_OPENSSL_STRING_pop_free(ctx->dirs, int_free_str);
+		OPENSSL_free(ctx);
+		}
+	}
+
+/* Construct the per-ENGINE context. We create it blindly and then use a lock to
+ * check for a race - if so, all but one of the threads "racing" will have
+ * wasted their time. The alternative involves creating everything inside the
+ * lock which is far worse. */
+static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
+	{
+	dynamic_data_ctx *c;
+	c = OPENSSL_malloc(sizeof(dynamic_data_ctx));
+	if(!c)
+		{
+		ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	memset(c, 0, sizeof(dynamic_data_ctx));
+	c->dynamic_dso = NULL;
+	c->v_check = NULL;
+	c->bind_engine = NULL;
+	c->DYNAMIC_LIBNAME = NULL;
+	c->no_vcheck = 0;
+	c->engine_id = NULL;
+	c->list_add_value = 0;
+	c->DYNAMIC_F1 = "v_check";
+	c->DYNAMIC_F2 = "bind_engine";
+	c->dir_load = 1;
+	c->dirs = sk_OPENSSL_STRING_new_null();
+	if(!c->dirs)
+		{
+		ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
+		OPENSSL_free(c);
+		return 0;
+		}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e,
+				dynamic_ex_data_idx)) == NULL)
+		{
+		/* Good, we're the first */
+		ENGINE_set_ex_data(e, dynamic_ex_data_idx, c);
+		*ctx = c;
+		c = NULL;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	/* If we lost the race to set the context, c is non-NULL and *ctx is the
+	 * context of the thread that won. */
+	if(c)
+		OPENSSL_free(c);
+	return 1;
+	}
+
+/* This function retrieves the context structure from an ENGINE's "ex_data", or
+ * if it doesn't exist yet, sets it up. */
+static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e)
+	{
+	dynamic_data_ctx *ctx;
+	if(dynamic_ex_data_idx < 0)
+		{
+		/* Create and register the ENGINE ex_data, and associate our
+		 * "free" function with it to ensure any allocated contexts get
+		 * freed when an ENGINE goes underground. */
+		int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL,
+					dynamic_data_ctx_free_func);
+		if(new_idx == -1)
+			{
+			ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX,ENGINE_R_NO_INDEX);
+			return NULL;
+			}
+		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+		/* Avoid a race by checking again inside this lock */
+		if(dynamic_ex_data_idx < 0)
+			{
+			/* Good, someone didn't beat us to it */
+			dynamic_ex_data_idx = new_idx;
+			new_idx = -1;
+			}
+		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		/* In theory we could "give back" the index here if
+		 * (new_idx>-1), but it's not possible and wouldn't gain us much
+		 * if it were. */
+		}
+	ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx);
+	/* Check if the context needs to be created */
+	if((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx))
+		/* "set_data" will set errors if necessary */
+		return NULL;
+	return ctx;
+	}
+
+static ENGINE *engine_dynamic(void)
+	{
+	ENGINE *ret = ENGINE_new();
+	if(!ret)
+		return NULL;
+	if(!ENGINE_set_id(ret, engine_dynamic_id) ||
+			!ENGINE_set_name(ret, engine_dynamic_name) ||
+			!ENGINE_set_init_function(ret, dynamic_init) ||
+			!ENGINE_set_finish_function(ret, dynamic_finish) ||
+			!ENGINE_set_ctrl_function(ret, dynamic_ctrl) ||
+			!ENGINE_set_flags(ret, ENGINE_FLAGS_BY_ID_COPY) ||
+			!ENGINE_set_cmd_defns(ret, dynamic_cmd_defns))
+		{
+		ENGINE_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+void ENGINE_load_dynamic(void)
+	{
+	ENGINE *toadd = engine_dynamic();
+	if(!toadd) return;
+	ENGINE_add(toadd);
+	/* If the "add" worked, it gets a structural reference. So either way,
+	 * we release our just-created reference. */
+	ENGINE_free(toadd);
+	/* If the "add" didn't work, it was probably a conflict because it was
+	 * already added (eg. someone calling ENGINE_load_blah then calling
+	 * ENGINE_load_builtin_engines() perhaps). */
+	ERR_clear_error();
+	}
+
+static int dynamic_init(ENGINE *e)
+	{
+	/* We always return failure - the "dyanamic" engine itself can't be used
+	 * for anything. */
+	return 0;
+	}
+
+static int dynamic_finish(ENGINE *e)
+	{
+	/* This should never be called on account of "dynamic_init" always
+	 * failing. */
+	return 0;
+	}
+
+static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+	{
+	dynamic_data_ctx *ctx = dynamic_get_data_ctx(e);
+	int initialised;
+	
+	if(!ctx)
+		{
+		ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_NOT_LOADED);
+		return 0;
+		}
+	initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1);
+	/* All our control commands require the ENGINE to be uninitialised */
+	if(initialised)
+		{
+		ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
+			ENGINE_R_ALREADY_LOADED);
+		return 0;
+		}
+	switch(cmd)
+		{
+	case DYNAMIC_CMD_SO_PATH:
+		/* a NULL 'p' or a string of zero-length is the same thing */
+		if(p && (strlen((const char *)p) < 1))
+			p = NULL;
+		if(ctx->DYNAMIC_LIBNAME)
+			OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME);
+		if(p)
+			ctx->DYNAMIC_LIBNAME = BUF_strdup(p);
+		else
+			ctx->DYNAMIC_LIBNAME = NULL;
+		return (ctx->DYNAMIC_LIBNAME ? 1 : 0);
+	case DYNAMIC_CMD_NO_VCHECK:
+		ctx->no_vcheck = ((i == 0) ? 0 : 1);
+		return 1;
+	case DYNAMIC_CMD_ID:
+		/* a NULL 'p' or a string of zero-length is the same thing */
+		if(p && (strlen((const char *)p) < 1))
+			p = NULL;
+		if(ctx->engine_id)
+			OPENSSL_free((void*)ctx->engine_id);
+		if(p)
+			ctx->engine_id = BUF_strdup(p);
+		else
+			ctx->engine_id = NULL;
+		return (ctx->engine_id ? 1 : 0);
+	case DYNAMIC_CMD_LIST_ADD:
+		if((i < 0) || (i > 2))
+			{
+			ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
+				ENGINE_R_INVALID_ARGUMENT);
+			return 0;
+			}
+		ctx->list_add_value = (int)i;
+		return 1;
+	case DYNAMIC_CMD_LOAD:
+		return dynamic_load(e, ctx);
+	case DYNAMIC_CMD_DIR_LOAD:
+		if((i < 0) || (i > 2))
+			{
+			ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
+				ENGINE_R_INVALID_ARGUMENT);
+			return 0;
+			}
+		ctx->dir_load = (int)i;
+		return 1;
+	case DYNAMIC_CMD_DIR_ADD:
+		/* a NULL 'p' or a string of zero-length is the same thing */
+		if(!p || (strlen((const char *)p) < 1))
+			{
+			ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
+				ENGINE_R_INVALID_ARGUMENT);
+			return 0;
+			}
+		{
+		char *tmp_str = BUF_strdup(p);
+		if(!tmp_str)
+			{
+			ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
+				ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		sk_OPENSSL_STRING_insert(ctx->dirs, tmp_str, -1);
+		}
+		return 1;
+	default:
+		break;
+		}
+	ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+	return 0;
+	}
+
+static int int_load(dynamic_data_ctx *ctx)
+	{
+	int num, loop;
+	/* Unless told not to, try a direct load */
+	if((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso,
+				ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL)
+		return 1;
+	/* If we're not allowed to use 'dirs' or we have none, fail */
+	if(!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1)
+		return 0;
+	for(loop = 0; loop < num; loop++)
+		{
+		const char *s = sk_OPENSSL_STRING_value(ctx->dirs, loop);
+		char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s);
+		if(!merge)
+			return 0;
+		if(DSO_load(ctx->dynamic_dso, merge, NULL, 0))
+			{
+			/* Found what we're looking for */
+			OPENSSL_free(merge);
+			return 1;
+			}
+		OPENSSL_free(merge);
+		}
+	return 0;
+	}
+
+static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
+	{
+	ENGINE cpy;
+	dynamic_fns fns;
+
+	if(!ctx->dynamic_dso)
+		ctx->dynamic_dso = DSO_new();
+	if(!ctx->DYNAMIC_LIBNAME)
+		{
+		if(!ctx->engine_id)
+			return 0;
+		ctx->DYNAMIC_LIBNAME =
+			DSO_convert_filename(ctx->dynamic_dso, ctx->engine_id);
+		}
+	if(!int_load(ctx))
+		{
+		ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
+			ENGINE_R_DSO_NOT_FOUND);
+		DSO_free(ctx->dynamic_dso);
+		ctx->dynamic_dso = NULL;
+		return 0;
+		}
+	/* We have to find a bind function otherwise it'll always end badly */
+	if(!(ctx->bind_engine = (dynamic_bind_engine)DSO_bind_func(
+					ctx->dynamic_dso, ctx->DYNAMIC_F2)))
+		{
+		ctx->bind_engine = NULL;
+		DSO_free(ctx->dynamic_dso);
+		ctx->dynamic_dso = NULL;
+		ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
+			ENGINE_R_DSO_FAILURE);
+		return 0;
+		}
+	/* Do we perform version checking? */
+	if(!ctx->no_vcheck)
+		{
+		unsigned long vcheck_res = 0;
+		/* Now we try to find a version checking function and decide how
+		 * to cope with failure if/when it fails. */
+		ctx->v_check = (dynamic_v_check_fn)DSO_bind_func(
+				ctx->dynamic_dso, ctx->DYNAMIC_F1);
+		if(ctx->v_check)
+			vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION);
+		/* We fail if the version checker veto'd the load *or* if it is
+		 * deferring to us (by returning its version) and we think it is
+		 * too old. */
+		if(vcheck_res < OSSL_DYNAMIC_OLDEST)
+			{
+			/* Fail */
+			ctx->bind_engine = NULL;
+			ctx->v_check = NULL;
+			DSO_free(ctx->dynamic_dso);
+			ctx->dynamic_dso = NULL;
+			ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
+				ENGINE_R_VERSION_INCOMPATIBILITY);
+			return 0;
+			}
+		}
+	/* First binary copy the ENGINE structure so that we can roll back if
+	 * the hand-over fails */
+	memcpy(&cpy, e, sizeof(ENGINE));
+	/* Provide the ERR, "ex_data", memory, and locking callbacks so the
+	 * loaded library uses our state rather than its own. FIXME: As noted in
+	 * engine.h, much of this would be simplified if each area of code
+	 * provided its own "summary" structure of all related callbacks. It
+	 * would also increase opaqueness. */
+	fns.static_state = ENGINE_get_static_state();
+	fns.err_fns = ERR_get_implementation();
+	fns.ex_data_fns = CRYPTO_get_ex_data_implementation();
+	CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb,
+				&fns.mem_fns.realloc_cb,
+				&fns.mem_fns.free_cb);
+	fns.lock_fns.lock_locking_cb = CRYPTO_get_locking_callback();
+	fns.lock_fns.lock_add_lock_cb = CRYPTO_get_add_lock_callback();
+	fns.lock_fns.dynlock_create_cb = CRYPTO_get_dynlock_create_callback();
+	fns.lock_fns.dynlock_lock_cb = CRYPTO_get_dynlock_lock_callback();
+	fns.lock_fns.dynlock_destroy_cb = CRYPTO_get_dynlock_destroy_callback();
+	/* Now that we've loaded the dynamic engine, make sure no "dynamic"
+	 * ENGINE elements will show through. */
+	engine_set_all_null(e);
+
+	/* Try to bind the ENGINE onto our own ENGINE structure */
+	if(!ctx->bind_engine(e, ctx->engine_id, &fns))
+		{
+		ctx->bind_engine = NULL;
+		ctx->v_check = NULL;
+		DSO_free(ctx->dynamic_dso);
+		ctx->dynamic_dso = NULL;
+		ENGINEerr(ENGINE_F_DYNAMIC_LOAD,ENGINE_R_INIT_FAILED);
+		/* Copy the original ENGINE structure back */
+		memcpy(e, &cpy, sizeof(ENGINE));
+		return 0;
+		}
+	/* Do we try to add this ENGINE to the internal list too? */
+	if(ctx->list_add_value > 0)
+		{
+		if(!ENGINE_add(e))
+			{
+			/* Do we tolerate this or fail? */
+			if(ctx->list_add_value > 1)
+				{
+				/* Fail - NB: By this time, it's too late to
+				 * rollback, and trying to do so allows the
+				 * bind_engine() code to have created leaks. We
+				 * just have to fail where we are, after the
+				 * ENGINE has changed. */
+				ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
+					ENGINE_R_CONFLICTING_ENGINE_ID);
+				return 0;
+				}
+			/* Tolerate */
+			ERR_clear_error();
+			}
+		}
+	return 1;
+	}
diff --git a/openssl/crypto/engine/eng_err.c b/openssl/crypto/engine/eng_err.c
new file mode 100644
index 0000000..81c70ac
--- /dev/null
+++ b/openssl/crypto/engine/eng_err.c
@@ -0,0 +1,173 @@
+/* crypto/engine/eng_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2010 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/engine.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ENGINE,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ENGINE,0,reason)
+
+static ERR_STRING_DATA ENGINE_str_functs[]=
+	{
+{ERR_FUNC(ENGINE_F_DYNAMIC_CTRL),	"DYNAMIC_CTRL"},
+{ERR_FUNC(ENGINE_F_DYNAMIC_GET_DATA_CTX),	"DYNAMIC_GET_DATA_CTX"},
+{ERR_FUNC(ENGINE_F_DYNAMIC_LOAD),	"DYNAMIC_LOAD"},
+{ERR_FUNC(ENGINE_F_DYNAMIC_SET_DATA_CTX),	"DYNAMIC_SET_DATA_CTX"},
+{ERR_FUNC(ENGINE_F_ENGINE_ADD),	"ENGINE_add"},
+{ERR_FUNC(ENGINE_F_ENGINE_BY_ID),	"ENGINE_by_id"},
+{ERR_FUNC(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE),	"ENGINE_cmd_is_executable"},
+{ERR_FUNC(ENGINE_F_ENGINE_CTRL),	"ENGINE_ctrl"},
+{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD),	"ENGINE_ctrl_cmd"},
+{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD_STRING),	"ENGINE_ctrl_cmd_string"},
+{ERR_FUNC(ENGINE_F_ENGINE_FINISH),	"ENGINE_finish"},
+{ERR_FUNC(ENGINE_F_ENGINE_FREE_UTIL),	"ENGINE_FREE_UTIL"},
+{ERR_FUNC(ENGINE_F_ENGINE_GET_CIPHER),	"ENGINE_get_cipher"},
+{ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE),	"ENGINE_GET_DEFAULT_TYPE"},
+{ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST),	"ENGINE_get_digest"},
+{ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT),	"ENGINE_get_next"},
+{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH),	"ENGINE_get_pkey_asn1_meth"},
+{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH),	"ENGINE_get_pkey_meth"},
+{ERR_FUNC(ENGINE_F_ENGINE_GET_PREV),	"ENGINE_get_prev"},
+{ERR_FUNC(ENGINE_F_ENGINE_INIT),	"ENGINE_init"},
+{ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD),	"ENGINE_LIST_ADD"},
+{ERR_FUNC(ENGINE_F_ENGINE_LIST_REMOVE),	"ENGINE_LIST_REMOVE"},
+{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY),	"ENGINE_load_private_key"},
+{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY),	"ENGINE_load_public_key"},
+{ERR_FUNC(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT),	"ENGINE_load_ssl_client_cert"},
+{ERR_FUNC(ENGINE_F_ENGINE_NEW),	"ENGINE_new"},
+{ERR_FUNC(ENGINE_F_ENGINE_REMOVE),	"ENGINE_remove"},
+{ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_STRING),	"ENGINE_set_default_string"},
+{ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_TYPE),	"ENGINE_SET_DEFAULT_TYPE"},
+{ERR_FUNC(ENGINE_F_ENGINE_SET_ID),	"ENGINE_set_id"},
+{ERR_FUNC(ENGINE_F_ENGINE_SET_NAME),	"ENGINE_set_name"},
+{ERR_FUNC(ENGINE_F_ENGINE_TABLE_REGISTER),	"ENGINE_TABLE_REGISTER"},
+{ERR_FUNC(ENGINE_F_ENGINE_UNLOAD_KEY),	"ENGINE_UNLOAD_KEY"},
+{ERR_FUNC(ENGINE_F_ENGINE_UNLOCKED_FINISH),	"ENGINE_UNLOCKED_FINISH"},
+{ERR_FUNC(ENGINE_F_ENGINE_UP_REF),	"ENGINE_up_ref"},
+{ERR_FUNC(ENGINE_F_INT_CTRL_HELPER),	"INT_CTRL_HELPER"},
+{ERR_FUNC(ENGINE_F_INT_ENGINE_CONFIGURE),	"INT_ENGINE_CONFIGURE"},
+{ERR_FUNC(ENGINE_F_INT_ENGINE_MODULE_INIT),	"INT_ENGINE_MODULE_INIT"},
+{ERR_FUNC(ENGINE_F_LOG_MESSAGE),	"LOG_MESSAGE"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA ENGINE_str_reasons[]=
+	{
+{ERR_REASON(ENGINE_R_ALREADY_LOADED)     ,"already loaded"},
+{ERR_REASON(ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER),"argument is not a number"},
+{ERR_REASON(ENGINE_R_CMD_NOT_EXECUTABLE) ,"cmd not executable"},
+{ERR_REASON(ENGINE_R_COMMAND_TAKES_INPUT),"command takes input"},
+{ERR_REASON(ENGINE_R_COMMAND_TAKES_NO_INPUT),"command takes no input"},
+{ERR_REASON(ENGINE_R_CONFLICTING_ENGINE_ID),"conflicting engine id"},
+{ERR_REASON(ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
+{ERR_REASON(ENGINE_R_DH_NOT_IMPLEMENTED) ,"dh not implemented"},
+{ERR_REASON(ENGINE_R_DSA_NOT_IMPLEMENTED),"dsa not implemented"},
+{ERR_REASON(ENGINE_R_DSO_FAILURE)        ,"DSO failure"},
+{ERR_REASON(ENGINE_R_DSO_NOT_FOUND)      ,"dso not found"},
+{ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR),"engines section error"},
+{ERR_REASON(ENGINE_R_ENGINE_CONFIGURATION_ERROR),"engine configuration error"},
+{ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST),"engine is not in the list"},
+{ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR),"engine section error"},
+{ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY),"failed loading private key"},
+{ERR_REASON(ENGINE_R_FAILED_LOADING_PUBLIC_KEY),"failed loading public key"},
+{ERR_REASON(ENGINE_R_FINISH_FAILED)      ,"finish failed"},
+{ERR_REASON(ENGINE_R_GET_HANDLE_FAILED)  ,"could not obtain hardware handle"},
+{ERR_REASON(ENGINE_R_ID_OR_NAME_MISSING) ,"'id' or 'name' missing"},
+{ERR_REASON(ENGINE_R_INIT_FAILED)        ,"init failed"},
+{ERR_REASON(ENGINE_R_INTERNAL_LIST_ERROR),"internal list error"},
+{ERR_REASON(ENGINE_R_INVALID_ARGUMENT)   ,"invalid argument"},
+{ERR_REASON(ENGINE_R_INVALID_CMD_NAME)   ,"invalid cmd name"},
+{ERR_REASON(ENGINE_R_INVALID_CMD_NUMBER) ,"invalid cmd number"},
+{ERR_REASON(ENGINE_R_INVALID_INIT_VALUE) ,"invalid init value"},
+{ERR_REASON(ENGINE_R_INVALID_STRING)     ,"invalid string"},
+{ERR_REASON(ENGINE_R_NOT_INITIALISED)    ,"not initialised"},
+{ERR_REASON(ENGINE_R_NOT_LOADED)         ,"not loaded"},
+{ERR_REASON(ENGINE_R_NO_CONTROL_FUNCTION),"no control function"},
+{ERR_REASON(ENGINE_R_NO_INDEX)           ,"no index"},
+{ERR_REASON(ENGINE_R_NO_LOAD_FUNCTION)   ,"no load function"},
+{ERR_REASON(ENGINE_R_NO_REFERENCE)       ,"no reference"},
+{ERR_REASON(ENGINE_R_NO_SUCH_ENGINE)     ,"no such engine"},
+{ERR_REASON(ENGINE_R_NO_UNLOAD_FUNCTION) ,"no unload function"},
+{ERR_REASON(ENGINE_R_PROVIDE_PARAMETERS) ,"provide parameters"},
+{ERR_REASON(ENGINE_R_RSA_NOT_IMPLEMENTED),"rsa not implemented"},
+{ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER),"unimplemented cipher"},
+{ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST),"unimplemented digest"},
+{ERR_REASON(ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD),"unimplemented public key method"},
+{ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY),"version incompatibility"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_ENGINE_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(ENGINE_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,ENGINE_str_functs);
+		ERR_load_strings(0,ENGINE_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/engine/eng_fat.c b/openssl/crypto/engine/eng_fat.c
new file mode 100644
index 0000000..db66e62
--- /dev/null
+++ b/openssl/crypto/engine/eng_fat.c
@@ -0,0 +1,181 @@
+/* crypto/engine/eng_fat.c */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include "eng_int.h"
+#include <openssl/conf.h>
+
+int ENGINE_set_default(ENGINE *e, unsigned int flags)
+	{
+	if((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e))
+		return 0;
+	if((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e))
+		return 0;
+#ifndef OPENSSL_NO_RSA
+	if((flags & ENGINE_METHOD_RSA) && !ENGINE_set_default_RSA(e))
+		return 0;
+#endif
+#ifndef OPENSSL_NO_DSA
+	if((flags & ENGINE_METHOD_DSA) && !ENGINE_set_default_DSA(e))
+		return 0;
+#endif
+#ifndef OPENSSL_NO_DH
+	if((flags & ENGINE_METHOD_DH) && !ENGINE_set_default_DH(e))
+		return 0;
+#endif
+#ifndef OPENSSL_NO_ECDH
+	if((flags & ENGINE_METHOD_ECDH) && !ENGINE_set_default_ECDH(e))
+		return 0;
+#endif
+#ifndef OPENSSL_NO_ECDSA
+	if((flags & ENGINE_METHOD_ECDSA) && !ENGINE_set_default_ECDSA(e))
+		return 0;
+#endif
+	if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e))
+		return 0;
+	if((flags & ENGINE_METHOD_PKEY_METHS)
+				&& !ENGINE_set_default_pkey_meths(e))
+		return 0;
+	if((flags & ENGINE_METHOD_PKEY_ASN1_METHS)
+				&& !ENGINE_set_default_pkey_asn1_meths(e))
+		return 0;
+	return 1;
+	}
+
+/* Set default algorithms using a string */
+
+static int int_def_cb(const char *alg, int len, void *arg)
+	{
+	unsigned int *pflags = arg;
+	if (!strncmp(alg, "ALL", len))
+		*pflags |= ENGINE_METHOD_ALL;
+	else if (!strncmp(alg, "RSA", len))
+		*pflags |= ENGINE_METHOD_RSA;
+	else if (!strncmp(alg, "DSA", len))
+		*pflags |= ENGINE_METHOD_DSA;
+	else if (!strncmp(alg, "ECDH", len))
+		*pflags |= ENGINE_METHOD_ECDH;
+	else if (!strncmp(alg, "ECDSA", len))
+		*pflags |= ENGINE_METHOD_ECDSA;
+	else if (!strncmp(alg, "DH", len))
+		*pflags |= ENGINE_METHOD_DH;
+	else if (!strncmp(alg, "RAND", len))
+		*pflags |= ENGINE_METHOD_RAND;
+	else if (!strncmp(alg, "CIPHERS", len))
+		*pflags |= ENGINE_METHOD_CIPHERS;
+	else if (!strncmp(alg, "DIGESTS", len))
+		*pflags |= ENGINE_METHOD_DIGESTS;
+	else if (!strncmp(alg, "PKEY", len))
+		*pflags |=
+			ENGINE_METHOD_PKEY_METHS|ENGINE_METHOD_PKEY_ASN1_METHS;
+	else if (!strncmp(alg, "PKEY_CRYPTO", len))
+		*pflags |= ENGINE_METHOD_PKEY_METHS;
+	else if (!strncmp(alg, "PKEY_ASN1", len))
+		*pflags |= ENGINE_METHOD_PKEY_ASN1_METHS;
+	else
+		return 0;
+	return 1;
+	}
+
+
+int ENGINE_set_default_string(ENGINE *e, const char *def_list)
+	{
+	unsigned int flags = 0;
+	if (!CONF_parse_list(def_list, ',', 1, int_def_cb, &flags))
+		{
+		ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_STRING,
+					ENGINE_R_INVALID_STRING);
+		ERR_add_error_data(2, "str=",def_list);
+		return 0;
+		}
+	return ENGINE_set_default(e, flags);
+	}
+
+int ENGINE_register_complete(ENGINE *e)
+	{
+	ENGINE_register_ciphers(e);
+	ENGINE_register_digests(e);
+#ifndef OPENSSL_NO_RSA
+	ENGINE_register_RSA(e);
+#endif
+#ifndef OPENSSL_NO_DSA
+	ENGINE_register_DSA(e);
+#endif
+#ifndef OPENSSL_NO_DH
+	ENGINE_register_DH(e);
+#endif
+#ifndef OPENSSL_NO_ECDH
+	ENGINE_register_ECDH(e);
+#endif
+#ifndef OPENSSL_NO_ECDSA
+	ENGINE_register_ECDSA(e);
+#endif
+	ENGINE_register_RAND(e);
+	ENGINE_register_pkey_meths(e);
+	return 1;
+	}
+
+int ENGINE_register_all_complete(void)
+	{
+	ENGINE *e;
+
+	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
+		ENGINE_register_complete(e);
+	return 1;
+	}
diff --git a/openssl/crypto/engine/eng_init.c b/openssl/crypto/engine/eng_init.c
new file mode 100644
index 0000000..7633cf5
--- /dev/null
+++ b/openssl/crypto/engine/eng_init.c
@@ -0,0 +1,154 @@
+/* crypto/engine/eng_init.c */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* Initialise a engine type for use (or up its functional reference count
+ * if it's already in use). This version is only used internally. */
+int engine_unlocked_init(ENGINE *e)
+	{
+	int to_return = 1;
+
+	if((e->funct_ref == 0) && e->init)
+		/* This is the first functional reference and the engine
+		 * requires initialisation so we do it now. */
+		to_return = e->init(e);
+	if(to_return)
+		{
+		/* OK, we return a functional reference which is also a
+		 * structural reference. */
+		e->struct_ref++;
+		e->funct_ref++;
+		engine_ref_debug(e, 0, 1)
+		engine_ref_debug(e, 1, 1)
+		}
+	return to_return;
+	}
+
+/* Free a functional reference to a engine type. This version is only used
+ * internally. */
+int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers)
+	{
+	int to_return = 1;
+
+	/* Reduce the functional reference count here so if it's the terminating
+	 * case, we can release the lock safely and call the finish() handler
+	 * without risk of a race. We get a race if we leave the count until
+	 * after and something else is calling "finish" at the same time -
+	 * there's a chance that both threads will together take the count from
+	 * 2 to 0 without either calling finish(). */
+	e->funct_ref--;
+	engine_ref_debug(e, 1, -1);
+	if((e->funct_ref == 0) && e->finish)
+		{
+		if(unlock_for_handlers)
+			CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		to_return = e->finish(e);
+		if(unlock_for_handlers)
+			CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+		if(!to_return)
+			return 0;
+		}
+#ifdef REF_CHECK
+	if(e->funct_ref < 0)
+		{
+		fprintf(stderr,"ENGINE_finish, bad functional reference count\n");
+		abort();
+		}
+#endif
+	/* Release the structural reference too */
+	if(!engine_free_util(e, 0))
+		{
+		ENGINEerr(ENGINE_F_ENGINE_UNLOCKED_FINISH,ENGINE_R_FINISH_FAILED);
+		return 0;
+		}
+	return to_return;
+	}
+
+/* The API (locked) version of "init" */
+int ENGINE_init(ENGINE *e)
+	{
+	int ret;
+	if(e == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_INIT,ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	ret = engine_unlocked_init(e);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	return ret;
+	}
+
+/* The API (locked) version of "finish" */
+int ENGINE_finish(ENGINE *e)
+	{
+	int to_return = 1;
+
+	if(e == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_FINISH,ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	to_return = engine_unlocked_finish(e, 1);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	if(!to_return)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_FINISH,ENGINE_R_FINISH_FAILED);
+		return 0;
+		}
+	return to_return;
+	}
diff --git a/openssl/crypto/engine/eng_int.h b/openssl/crypto/engine/eng_int.h
new file mode 100644
index 0000000..451ef8f
--- /dev/null
+++ b/openssl/crypto/engine/eng_int.h
@@ -0,0 +1,206 @@
+/* crypto/engine/eng_int.h */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_ENGINE_INT_H
+#define HEADER_ENGINE_INT_H
+
+#include "cryptlib.h"
+/* Take public definitions from engine.h */
+#include <openssl/engine.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* If we compile with this symbol defined, then both reference counts in the
+ * ENGINE structure will be monitored with a line of output on stderr for each
+ * change. This prints the engine's pointer address (truncated to unsigned int),
+ * "struct" or "funct" to indicate the reference type, the before and after
+ * reference count, and the file:line-number pair. The "engine_ref_debug"
+ * statements must come *after* the change. */
+#ifdef ENGINE_REF_COUNT_DEBUG
+
+#define engine_ref_debug(e, isfunct, diff) \
+	fprintf(stderr, "engine: %08x %s from %d to %d (%s:%d)\n", \
+		(unsigned int)(e), (isfunct ? "funct" : "struct"), \
+		((isfunct) ? ((e)->funct_ref - (diff)) : ((e)->struct_ref - (diff))), \
+		((isfunct) ? (e)->funct_ref : (e)->struct_ref), \
+		(__FILE__), (__LINE__));
+
+#else
+
+#define engine_ref_debug(e, isfunct, diff)
+
+#endif
+
+/* Any code that will need cleanup operations should use these functions to
+ * register callbacks. ENGINE_cleanup() will call all registered callbacks in
+ * order. NB: both the "add" functions assume CRYPTO_LOCK_ENGINE to already be
+ * held (in "write" mode). */
+typedef void (ENGINE_CLEANUP_CB)(void);
+typedef struct st_engine_cleanup_item
+	{
+	ENGINE_CLEANUP_CB *cb;
+	} ENGINE_CLEANUP_ITEM;
+DECLARE_STACK_OF(ENGINE_CLEANUP_ITEM)
+void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb);
+void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb);
+
+/* We need stacks of ENGINEs for use in eng_table.c */
+DECLARE_STACK_OF(ENGINE)
+
+/* If this symbol is defined then engine_table_select(), the function that is
+ * used by RSA, DSA (etc) code to select registered ENGINEs, cache defaults and
+ * functional references (etc), will display debugging summaries to stderr. */
+/* #define ENGINE_TABLE_DEBUG */
+
+/* This represents an implementation table. Dependent code should instantiate it
+ * as a (ENGINE_TABLE *) pointer value set initially to NULL. */
+typedef struct st_engine_table ENGINE_TABLE;
+int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
+		ENGINE *e, const int *nids, int num_nids, int setdefault);
+void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e);
+void engine_table_cleanup(ENGINE_TABLE **table);
+#ifndef ENGINE_TABLE_DEBUG
+ENGINE *engine_table_select(ENGINE_TABLE **table, int nid);
+#else
+ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l);
+#define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__)
+#endif
+typedef void (engine_table_doall_cb)(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg);
+void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, void *arg);
+
+/* Internal versions of API functions that have control over locking. These are
+ * used between C files when functionality needs to be shared but the caller may
+ * already be controlling of the CRYPTO_LOCK_ENGINE lock. */
+int engine_unlocked_init(ENGINE *e);
+int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers);
+int engine_free_util(ENGINE *e, int locked);
+
+/* This function will reset all "set"able values in an ENGINE to NULL. This
+ * won't touch reference counts or ex_data, but is equivalent to calling all the
+ * ENGINE_set_***() functions with a NULL value. */
+void engine_set_all_null(ENGINE *e);
+
+/* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed
+ * in engine.h. */
+
+/* Free up dynamically allocated public key methods associated with ENGINE */
+
+void engine_pkey_meths_free(ENGINE *e);
+void engine_pkey_asn1_meths_free(ENGINE *e);
+
+/* This is a structure for storing implementations of various crypto
+ * algorithms and functions. */
+struct engine_st
+	{
+	const char *id;
+	const char *name;
+	const RSA_METHOD *rsa_meth;
+	const DSA_METHOD *dsa_meth;
+	const DH_METHOD *dh_meth;
+	const ECDH_METHOD *ecdh_meth;
+	const ECDSA_METHOD *ecdsa_meth;
+	const RAND_METHOD *rand_meth;
+	const STORE_METHOD *store_meth;
+	/* Cipher handling is via this callback */
+	ENGINE_CIPHERS_PTR ciphers;
+	/* Digest handling is via this callback */
+	ENGINE_DIGESTS_PTR digests;
+	/* Public key handling via this callback */
+	ENGINE_PKEY_METHS_PTR pkey_meths;
+	/* ASN1 public key handling via this callback */
+	ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths;
+
+	ENGINE_GEN_INT_FUNC_PTR	destroy;
+
+	ENGINE_GEN_INT_FUNC_PTR init;
+	ENGINE_GEN_INT_FUNC_PTR finish;
+	ENGINE_CTRL_FUNC_PTR ctrl;
+	ENGINE_LOAD_KEY_PTR load_privkey;
+	ENGINE_LOAD_KEY_PTR load_pubkey;
+
+	ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert;
+
+	const ENGINE_CMD_DEFN *cmd_defns;
+	int flags;
+	/* reference count on the structure itself */
+	int struct_ref;
+	/* reference count on usability of the engine type. NB: This
+	 * controls the loading and initialisation of any functionlity
+	 * required by this engine, whereas the previous count is
+	 * simply to cope with (de)allocation of this structure. Hence,
+	 * running_ref <= struct_ref at all times. */
+	int funct_ref;
+	/* A place to store per-ENGINE data */
+	CRYPTO_EX_DATA ex_data;
+	/* Used to maintain the linked-list of engines. */
+	struct engine_st *prev;
+	struct engine_st *next;
+	};
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* HEADER_ENGINE_INT_H */
diff --git a/openssl/crypto/engine/eng_lib.c b/openssl/crypto/engine/eng_lib.c
new file mode 100644
index 0000000..18a6664
--- /dev/null
+++ b/openssl/crypto/engine/eng_lib.c
@@ -0,0 +1,332 @@
+/* crypto/engine/eng_lib.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+#include <openssl/rand.h>
+
+/* The "new"/"free" stuff first */
+
+ENGINE *ENGINE_new(void)
+	{
+	ENGINE *ret;
+
+	ret = (ENGINE *)OPENSSL_malloc(sizeof(ENGINE));
+	if(ret == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+	memset(ret, 0, sizeof(ENGINE));
+	ret->struct_ref = 1;
+	engine_ref_debug(ret, 0, 1)
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data);
+	return ret;
+	}
+
+/* Placed here (close proximity to ENGINE_new) so that modifications to the
+ * elements of the ENGINE structure are more likely to be caught and changed
+ * here. */
+void engine_set_all_null(ENGINE *e)
+	{
+	e->id = NULL;
+	e->name = NULL;
+	e->rsa_meth = NULL;
+	e->dsa_meth = NULL;
+	e->dh_meth = NULL;
+	e->rand_meth = NULL;
+	e->store_meth = NULL;
+	e->ciphers = NULL;
+	e->digests = NULL;
+	e->destroy = NULL;
+	e->init = NULL;
+	e->finish = NULL;
+	e->ctrl = NULL;
+	e->load_privkey = NULL;
+	e->load_pubkey = NULL;
+	e->cmd_defns = NULL;
+	e->flags = 0;
+	}
+
+int engine_free_util(ENGINE *e, int locked)
+	{
+	int i;
+
+	if(e == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_FREE_UTIL,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	if(locked)
+		i = CRYPTO_add(&e->struct_ref,-1,CRYPTO_LOCK_ENGINE);
+	else
+		i = --e->struct_ref;
+	engine_ref_debug(e, 0, -1)
+	if (i > 0) return 1;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"ENGINE_free, bad structural reference count\n");
+		abort();
+		}
+#endif
+	/* Free up any dynamically allocated public key methods */
+	engine_pkey_meths_free(e);
+	engine_pkey_asn1_meths_free(e);
+	/* Give the ENGINE a chance to do any structural cleanup corresponding
+	 * to allocation it did in its constructor (eg. unload error strings) */
+	if(e->destroy)
+		e->destroy(e);
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ENGINE, e, &e->ex_data);
+	OPENSSL_free(e);
+	return 1;
+	}
+
+int ENGINE_free(ENGINE *e)
+	{
+	return engine_free_util(e, 1);
+	}
+
+/* Cleanup stuff */
+
+/* ENGINE_cleanup() is coded such that anything that does work that will need
+ * cleanup can register a "cleanup" callback here. That way we don't get linker
+ * bloat by referring to all *possible* cleanups, but any linker bloat into code
+ * "X" will cause X's cleanup function to end up here. */
+static STACK_OF(ENGINE_CLEANUP_ITEM) *cleanup_stack = NULL;
+static int int_cleanup_check(int create)
+	{
+	if(cleanup_stack) return 1;
+	if(!create) return 0;
+	cleanup_stack = sk_ENGINE_CLEANUP_ITEM_new_null();
+	return (cleanup_stack ? 1 : 0);
+	}
+static ENGINE_CLEANUP_ITEM *int_cleanup_item(ENGINE_CLEANUP_CB *cb)
+	{
+	ENGINE_CLEANUP_ITEM *item = OPENSSL_malloc(sizeof(
+					ENGINE_CLEANUP_ITEM));
+	if(!item) return NULL;
+	item->cb = cb;
+	return item;
+	}
+void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb)
+	{
+	ENGINE_CLEANUP_ITEM *item;
+	if(!int_cleanup_check(1)) return;
+	item = int_cleanup_item(cb);
+	if(item)
+		sk_ENGINE_CLEANUP_ITEM_insert(cleanup_stack, item, 0);
+	}
+void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb)
+	{
+	ENGINE_CLEANUP_ITEM *item;
+	if(!int_cleanup_check(1)) return;
+	item = int_cleanup_item(cb);
+	if(item)
+		sk_ENGINE_CLEANUP_ITEM_push(cleanup_stack, item);
+	}
+/* The API function that performs all cleanup */
+static void engine_cleanup_cb_free(ENGINE_CLEANUP_ITEM *item)
+	{
+	(*(item->cb))();
+	OPENSSL_free(item);
+	}
+void ENGINE_cleanup(void)
+	{
+	if(int_cleanup_check(0))
+		{
+		sk_ENGINE_CLEANUP_ITEM_pop_free(cleanup_stack,
+			engine_cleanup_cb_free);
+		cleanup_stack = NULL;
+		}
+	/* FIXME: This should be handled (somehow) through RAND, eg. by it
+	 * registering a cleanup callback. */
+	RAND_set_rand_method(NULL);
+	}
+
+/* Now the "ex_data" support */
+
+int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+		CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+	{
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ENGINE, argl, argp,
+			new_func, dup_func, free_func);
+	}
+
+int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg)
+	{
+	return(CRYPTO_set_ex_data(&e->ex_data, idx, arg));
+	}
+
+void *ENGINE_get_ex_data(const ENGINE *e, int idx)
+	{
+	return(CRYPTO_get_ex_data(&e->ex_data, idx));
+	}
+
+/* Functions to get/set an ENGINE's elements - mainly to avoid exposing the
+ * ENGINE structure itself. */
+
+int ENGINE_set_id(ENGINE *e, const char *id)
+	{
+	if(id == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_SET_ID,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	e->id = id;
+	return 1;
+	}
+
+int ENGINE_set_name(ENGINE *e, const char *name)
+	{
+	if(name == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_SET_NAME,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	e->name = name;
+	return 1;
+	}
+
+int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f)
+	{
+	e->destroy = destroy_f;
+	return 1;
+	}
+
+int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f)
+	{
+	e->init = init_f;
+	return 1;
+	}
+
+int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f)
+	{
+	e->finish = finish_f;
+	return 1;
+	}
+
+int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f)
+	{
+	e->ctrl = ctrl_f;
+	return 1;
+	}
+
+int ENGINE_set_flags(ENGINE *e, int flags)
+	{
+	e->flags = flags;
+	return 1;
+	}
+
+int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns)
+	{
+	e->cmd_defns = defns;
+	return 1;
+	}
+
+const char *ENGINE_get_id(const ENGINE *e)
+	{
+	return e->id;
+	}
+
+const char *ENGINE_get_name(const ENGINE *e)
+	{
+	return e->name;
+	}
+
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e)
+	{
+	return e->destroy;
+	}
+
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e)
+	{
+	return e->init;
+	}
+
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e)
+	{
+	return e->finish;
+	}
+
+ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e)
+	{
+	return e->ctrl;
+	}
+
+int ENGINE_get_flags(const ENGINE *e)
+	{
+	return e->flags;
+	}
+
+const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e)
+	{
+	return e->cmd_defns;
+	}
+
+/* eng_lib.o is pretty much linked into anything that touches ENGINE already, so
+ * put the "static_state" hack here. */
+
+static int internal_static_hack = 0;
+
+void *ENGINE_get_static_state(void)
+	{
+	return &internal_static_hack;
+	}
diff --git a/openssl/crypto/engine/eng_list.c b/openssl/crypto/engine/eng_list.c
new file mode 100644
index 0000000..27846ed
--- /dev/null
+++ b/openssl/crypto/engine/eng_list.c
@@ -0,0 +1,433 @@
+/* crypto/engine/eng_list.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include "eng_int.h"
+
+/* The linked-list of pointers to engine types. engine_list_head
+ * incorporates an implicit structural reference but engine_list_tail
+ * does not - the latter is a computational niceity and only points
+ * to something that is already pointed to by its predecessor in the
+ * list (or engine_list_head itself). In the same way, the use of the
+ * "prev" pointer in each ENGINE is to save excessive list iteration,
+ * it doesn't correspond to an extra structural reference. Hence,
+ * engine_list_head, and each non-null "next" pointer account for
+ * the list itself assuming exactly 1 structural reference on each
+ * list member. */
+static ENGINE *engine_list_head = NULL;
+static ENGINE *engine_list_tail = NULL;
+
+/* This cleanup function is only needed internally. If it should be called, we
+ * register it with the "ENGINE_cleanup()" stack to be called during cleanup. */
+
+static void engine_list_cleanup(void)
+	{
+	ENGINE *iterator = engine_list_head;
+
+	while(iterator != NULL)
+		{
+		ENGINE_remove(iterator);
+		iterator = engine_list_head;
+		}
+	return;
+	}
+
+/* These static functions starting with a lower case "engine_" always
+ * take place when CRYPTO_LOCK_ENGINE has been locked up. */
+static int engine_list_add(ENGINE *e)
+	{
+	int conflict = 0;
+	ENGINE *iterator = NULL;
+
+	if(e == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	iterator = engine_list_head;
+	while(iterator && !conflict)
+		{
+		conflict = (strcmp(iterator->id, e->id) == 0);
+		iterator = iterator->next;
+		}
+	if(conflict)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
+			ENGINE_R_CONFLICTING_ENGINE_ID);
+		return 0;
+		}
+	if(engine_list_head == NULL)
+		{
+		/* We are adding to an empty list. */
+		if(engine_list_tail)
+			{
+			ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
+				ENGINE_R_INTERNAL_LIST_ERROR);
+			return 0;
+			}
+		engine_list_head = e;
+		e->prev = NULL;
+		/* The first time the list allocates, we should register the
+		 * cleanup. */
+		engine_cleanup_add_last(engine_list_cleanup);
+		}
+	else
+		{
+		/* We are adding to the tail of an existing list. */
+		if((engine_list_tail == NULL) ||
+				(engine_list_tail->next != NULL))
+			{
+			ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
+				ENGINE_R_INTERNAL_LIST_ERROR);
+			return 0;
+			}
+		engine_list_tail->next = e;
+		e->prev = engine_list_tail;
+		}
+	/* Having the engine in the list assumes a structural
+	 * reference. */
+	e->struct_ref++;
+	engine_ref_debug(e, 0, 1)
+	/* However it came to be, e is the last item in the list. */
+	engine_list_tail = e;
+	e->next = NULL;
+	return 1;
+	}
+
+static int engine_list_remove(ENGINE *e)
+	{
+	ENGINE *iterator;
+
+	if(e == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	/* We need to check that e is in our linked list! */
+	iterator = engine_list_head;
+	while(iterator && (iterator != e))
+		iterator = iterator->next;
+	if(iterator == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
+			ENGINE_R_ENGINE_IS_NOT_IN_LIST);
+		return 0;
+		}
+	/* un-link e from the chain. */
+	if(e->next)
+		e->next->prev = e->prev;
+	if(e->prev)
+		e->prev->next = e->next;
+	/* Correct our head/tail if necessary. */
+	if(engine_list_head == e)
+		engine_list_head = e->next;
+	if(engine_list_tail == e)
+		engine_list_tail = e->prev;
+	engine_free_util(e, 0);
+	return 1;
+	}
+
+/* Get the first/last "ENGINE" type available. */
+ENGINE *ENGINE_get_first(void)
+	{
+	ENGINE *ret;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	ret = engine_list_head;
+	if(ret)
+		{
+		ret->struct_ref++;
+		engine_ref_debug(ret, 0, 1)
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	return ret;
+	}
+
+ENGINE *ENGINE_get_last(void)
+	{
+	ENGINE *ret;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	ret = engine_list_tail;
+	if(ret)
+		{
+		ret->struct_ref++;
+		engine_ref_debug(ret, 0, 1)
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	return ret;
+	}
+
+/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
+ENGINE *ENGINE_get_next(ENGINE *e)
+	{
+	ENGINE *ret = NULL;
+	if(e == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_GET_NEXT,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	ret = e->next;
+	if(ret)
+		{
+		/* Return a valid structural refernce to the next ENGINE */
+		ret->struct_ref++;
+		engine_ref_debug(ret, 0, 1)
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	/* Release the structural reference to the previous ENGINE */
+	ENGINE_free(e);
+	return ret;
+	}
+
+ENGINE *ENGINE_get_prev(ENGINE *e)
+	{
+	ENGINE *ret = NULL;
+	if(e == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_GET_PREV,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	ret = e->prev;
+	if(ret)
+		{
+		/* Return a valid structural reference to the next ENGINE */
+		ret->struct_ref++;
+		engine_ref_debug(ret, 0, 1)
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	/* Release the structural reference to the previous ENGINE */
+	ENGINE_free(e);
+	return ret;
+	}
+
+/* Add another "ENGINE" type into the list. */
+int ENGINE_add(ENGINE *e)
+	{
+	int to_return = 1;
+	if(e == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_ADD,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	if((e->id == NULL) || (e->name == NULL))
+		{
+		ENGINEerr(ENGINE_F_ENGINE_ADD,
+			ENGINE_R_ID_OR_NAME_MISSING);
+		}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if(!engine_list_add(e))
+		{
+		ENGINEerr(ENGINE_F_ENGINE_ADD,
+			ENGINE_R_INTERNAL_LIST_ERROR);
+		to_return = 0;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	return to_return;
+	}
+
+/* Remove an existing "ENGINE" type from the array. */
+int ENGINE_remove(ENGINE *e)
+	{
+	int to_return = 1;
+	if(e == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_REMOVE,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if(!engine_list_remove(e))
+		{
+		ENGINEerr(ENGINE_F_ENGINE_REMOVE,
+			ENGINE_R_INTERNAL_LIST_ERROR);
+		to_return = 0;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	return to_return;
+	}
+
+static void engine_cpy(ENGINE *dest, const ENGINE *src)
+	{
+	dest->id = src->id;
+	dest->name = src->name;
+#ifndef OPENSSL_NO_RSA
+	dest->rsa_meth = src->rsa_meth;
+#endif
+#ifndef OPENSSL_NO_DSA
+	dest->dsa_meth = src->dsa_meth;
+#endif
+#ifndef OPENSSL_NO_DH
+	dest->dh_meth = src->dh_meth;
+#endif
+#ifndef OPENSSL_NO_ECDH
+	dest->ecdh_meth = src->ecdh_meth;
+#endif
+#ifndef OPENSSL_NO_ECDSA
+	dest->ecdsa_meth = src->ecdsa_meth;
+#endif
+	dest->rand_meth = src->rand_meth;
+	dest->store_meth = src->store_meth;
+	dest->ciphers = src->ciphers;
+	dest->digests = src->digests;
+	dest->pkey_meths = src->pkey_meths;
+	dest->destroy = src->destroy;
+	dest->init = src->init;
+	dest->finish = src->finish;
+	dest->ctrl = src->ctrl;
+	dest->load_privkey = src->load_privkey;
+	dest->load_pubkey = src->load_pubkey;
+	dest->cmd_defns = src->cmd_defns;
+	dest->flags = src->flags;
+	}
+
+ENGINE *ENGINE_by_id(const char *id)
+	{
+	ENGINE *iterator;
+	char *load_dir = NULL;
+	if(id == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_BY_ID,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return NULL;
+		}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	iterator = engine_list_head;
+	while(iterator && (strcmp(id, iterator->id) != 0))
+		iterator = iterator->next;
+	if(iterator)
+		{
+		/* We need to return a structural reference. If this is an
+		 * ENGINE type that returns copies, make a duplicate - otherwise
+		 * increment the existing ENGINE's reference count. */
+		if(iterator->flags & ENGINE_FLAGS_BY_ID_COPY)
+			{
+			ENGINE *cp = ENGINE_new();
+			if(!cp)
+				iterator = NULL;
+			else
+				{
+				engine_cpy(cp, iterator);
+				iterator = cp;
+				}
+			}
+		else
+			{
+			iterator->struct_ref++;
+			engine_ref_debug(iterator, 0, 1)
+			}
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+#if 0
+	if(iterator == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_BY_ID,
+			ENGINE_R_NO_SUCH_ENGINE);
+		ERR_add_error_data(2, "id=", id);
+		}
+	return iterator;
+#else
+	/* EEK! Experimental code starts */
+	if(iterator) return iterator;
+	/* Prevent infinite recusrion if we're looking for the dynamic engine. */
+	if (strcmp(id, "dynamic"))
+		{
+#ifdef OPENSSL_SYS_VMS
+		if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = "SSLROOT:[ENGINES]";
+#else
+		if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = ENGINESDIR;
+#endif
+		iterator = ENGINE_by_id("dynamic");
+		if(!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) ||
+				!ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||
+				!ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
+					load_dir, 0) ||
+				!ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
+				goto notfound;
+		return iterator;
+		}
+notfound:
+	ENGINE_free(iterator);
+	ENGINEerr(ENGINE_F_ENGINE_BY_ID,ENGINE_R_NO_SUCH_ENGINE);
+	ERR_add_error_data(2, "id=", id);
+	return NULL;
+	/* EEK! Experimental code ends */
+#endif
+	}
+
+int ENGINE_up_ref(ENGINE *e)
+	{
+	if (e == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_UP_REF,ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	CRYPTO_add(&e->struct_ref,1,CRYPTO_LOCK_ENGINE);
+	return 1;
+	}
diff --git a/openssl/crypto/engine/eng_openssl.c b/openssl/crypto/engine/eng_openssl.c
new file mode 100644
index 0000000..9abb95c
--- /dev/null
+++ b/openssl/crypto/engine/eng_openssl.c
@@ -0,0 +1,384 @@
+/* crypto/engine/eng_openssl.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+
+#include <stdio.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/engine.h>
+#include <openssl/dso.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+
+/* This testing gunk is implemented (and explained) lower down. It also assumes
+ * the application explicitly calls "ENGINE_load_openssl()" because this is no
+ * longer automatic in ENGINE_load_builtin_engines(). */
+#define TEST_ENG_OPENSSL_RC4
+#define TEST_ENG_OPENSSL_PKEY
+/* #define TEST_ENG_OPENSSL_RC4_OTHERS */
+#define TEST_ENG_OPENSSL_RC4_P_INIT
+/* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */
+#define TEST_ENG_OPENSSL_SHA
+/* #define TEST_ENG_OPENSSL_SHA_OTHERS */
+/* #define TEST_ENG_OPENSSL_SHA_P_INIT */
+/* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */
+/* #define TEST_ENG_OPENSSL_SHA_P_FINAL */
+
+/* Now check what of those algorithms are actually enabled */
+#ifdef OPENSSL_NO_RC4
+#undef TEST_ENG_OPENSSL_RC4
+#undef TEST_ENG_OPENSSL_RC4_OTHERS
+#undef TEST_ENG_OPENSSL_RC4_P_INIT
+#undef TEST_ENG_OPENSSL_RC4_P_CIPHER
+#endif
+#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA0) || defined(OPENSSL_NO_SHA1)
+#undef TEST_ENG_OPENSSL_SHA
+#undef TEST_ENG_OPENSSL_SHA_OTHERS
+#undef TEST_ENG_OPENSSL_SHA_P_INIT
+#undef TEST_ENG_OPENSSL_SHA_P_UPDATE
+#undef TEST_ENG_OPENSSL_SHA_P_FINAL 
+#endif
+
+#ifdef TEST_ENG_OPENSSL_RC4
+static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
+				const int **nids, int nid);
+#endif
+#ifdef TEST_ENG_OPENSSL_SHA
+static int openssl_digests(ENGINE *e, const EVP_MD **digest,
+				const int **nids, int nid);
+#endif
+
+#ifdef TEST_ENG_OPENSSL_PKEY
+static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data);
+#endif
+
+/* The constants used when creating the ENGINE */
+static const char *engine_openssl_id = "openssl";
+static const char *engine_openssl_name = "Software engine support";
+
+/* This internal function is used by ENGINE_openssl() and possibly by the
+ * "dynamic" ENGINE support too */
+static int bind_helper(ENGINE *e)
+	{
+	if(!ENGINE_set_id(e, engine_openssl_id)
+			|| !ENGINE_set_name(e, engine_openssl_name)
+#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS
+#ifndef OPENSSL_NO_RSA
+			|| !ENGINE_set_RSA(e, RSA_get_default_method())
+#endif
+#ifndef OPENSSL_NO_DSA
+			|| !ENGINE_set_DSA(e, DSA_get_default_method())
+#endif
+#ifndef OPENSSL_NO_ECDH
+			|| !ENGINE_set_ECDH(e, ECDH_OpenSSL())
+#endif
+#ifndef OPENSSL_NO_ECDSA
+			|| !ENGINE_set_ECDSA(e, ECDSA_OpenSSL())
+#endif
+#ifndef OPENSSL_NO_DH
+			|| !ENGINE_set_DH(e, DH_get_default_method())
+#endif
+			|| !ENGINE_set_RAND(e, RAND_SSLeay())
+#ifdef TEST_ENG_OPENSSL_RC4
+			|| !ENGINE_set_ciphers(e, openssl_ciphers)
+#endif
+#ifdef TEST_ENG_OPENSSL_SHA
+			|| !ENGINE_set_digests(e, openssl_digests)
+#endif
+#endif
+#ifdef TEST_ENG_OPENSSL_PKEY
+			|| !ENGINE_set_load_privkey_function(e, openssl_load_privkey)
+#endif
+			)
+		return 0;
+	/* If we add errors to this ENGINE, ensure the error handling is setup here */
+	/* openssl_load_error_strings(); */
+	return 1;
+	}
+
+static ENGINE *engine_openssl(void)
+	{
+	ENGINE *ret = ENGINE_new();
+	if(!ret)
+		return NULL;
+	if(!bind_helper(ret))
+		{
+		ENGINE_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+void ENGINE_load_openssl(void)
+	{
+	ENGINE *toadd = engine_openssl();
+	if(!toadd) return;
+	ENGINE_add(toadd);
+	/* If the "add" worked, it gets a structural reference. So either way,
+	 * we release our just-created reference. */
+	ENGINE_free(toadd);
+	ERR_clear_error();
+	}
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library. */
+#ifdef ENGINE_DYNAMIC_SUPPORT
+static int bind_fn(ENGINE *e, const char *id)
+	{
+	if(id && (strcmp(id, engine_openssl_id) != 0))
+		return 0;
+	if(!bind_helper(e))
+		return 0;
+	return 1;
+	}
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#endif /* ENGINE_DYNAMIC_SUPPORT */
+
+#ifdef TEST_ENG_OPENSSL_RC4
+/* This section of code compiles an "alternative implementation" of two modes of
+ * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4"
+ * should under normal circumstances go via this support rather than the default
+ * EVP support. There are other symbols to tweak the testing;
+ *    TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time
+ *        we're asked for a cipher we don't support (should not happen).
+ *    TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time
+ *        the "init_key" handler is called.
+ *    TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler.
+ */
+#include <openssl/rc4.h>
+#define TEST_RC4_KEY_SIZE		16
+static int test_cipher_nids[] = {NID_rc4,NID_rc4_40};
+static int test_cipher_nids_number = 2;
+typedef struct {
+	unsigned char key[TEST_RC4_KEY_SIZE];
+	RC4_KEY ks;
+	} TEST_RC4_KEY;
+#define test(ctx) ((TEST_RC4_KEY *)(ctx)->cipher_data)
+static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			const unsigned char *iv, int enc)
+	{
+#ifdef TEST_ENG_OPENSSL_RC4_P_INIT
+	fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n");
+#endif
+	memcpy(&test(ctx)->key[0],key,EVP_CIPHER_CTX_key_length(ctx));
+	RC4_set_key(&test(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),
+		test(ctx)->key);
+	return 1;
+	}
+static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+		      const unsigned char *in, size_t inl)
+	{
+#ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
+	fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
+#endif
+	RC4(&test(ctx)->ks,inl,in,out);
+	return 1;
+	}
+static const EVP_CIPHER test_r4_cipher=
+	{
+	NID_rc4,
+	1,TEST_RC4_KEY_SIZE,0,
+	EVP_CIPH_VARIABLE_LENGTH,
+	test_rc4_init_key,
+	test_rc4_cipher,
+	NULL,
+	sizeof(TEST_RC4_KEY),
+	NULL,
+	NULL,
+	NULL,
+	NULL
+	};
+static const EVP_CIPHER test_r4_40_cipher=
+	{
+	NID_rc4_40,
+	1,5 /* 40 bit */,0,
+	EVP_CIPH_VARIABLE_LENGTH,
+	test_rc4_init_key,
+	test_rc4_cipher,
+	NULL,
+	sizeof(TEST_RC4_KEY),
+	NULL, 
+	NULL,
+	NULL,
+	NULL
+	};
+static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
+			const int **nids, int nid)
+	{
+	if(!cipher)
+		{
+		/* We are returning a list of supported nids */
+		*nids = test_cipher_nids;
+		return test_cipher_nids_number;
+		}
+	/* We are being asked for a specific cipher */
+	if(nid == NID_rc4)
+		*cipher = &test_r4_cipher;
+	else if(nid == NID_rc4_40)
+		*cipher = &test_r4_40_cipher;
+	else
+		{
+#ifdef TEST_ENG_OPENSSL_RC4_OTHERS
+		fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for "
+				"nid %d\n", nid);
+#endif
+		*cipher = NULL;
+		return 0;
+		}
+	return 1;
+	}
+#endif
+
+#ifdef TEST_ENG_OPENSSL_SHA
+/* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */
+#include <openssl/sha.h>
+static int test_digest_nids[] = {NID_sha1};
+static int test_digest_nids_number = 1;
+static int test_sha1_init(EVP_MD_CTX *ctx)
+	{
+#ifdef TEST_ENG_OPENSSL_SHA_P_INIT
+	fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n");
+#endif
+	return SHA1_Init(ctx->md_data);
+	}
+static int test_sha1_update(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{
+#ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE
+	fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n");
+#endif
+	return SHA1_Update(ctx->md_data,data,count);
+	}
+static int test_sha1_final(EVP_MD_CTX *ctx,unsigned char *md)
+	{
+#ifdef TEST_ENG_OPENSSL_SHA_P_FINAL
+	fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n");
+#endif
+	return SHA1_Final(md,ctx->md_data);
+	}
+static const EVP_MD test_sha_md=
+	{
+	NID_sha1,
+	NID_sha1WithRSAEncryption,
+	SHA_DIGEST_LENGTH,
+	0,
+	test_sha1_init,
+	test_sha1_update,
+	test_sha1_final,
+	NULL,
+	NULL,
+	EVP_PKEY_RSA_method,
+	SHA_CBLOCK,
+	sizeof(EVP_MD *)+sizeof(SHA_CTX),
+	};
+static int openssl_digests(ENGINE *e, const EVP_MD **digest,
+			const int **nids, int nid)
+	{
+	if(!digest)
+		{
+		/* We are returning a list of supported nids */
+		*nids = test_digest_nids;
+		return test_digest_nids_number;
+		}
+	/* We are being asked for a specific digest */
+	if(nid == NID_sha1)
+		*digest = &test_sha_md;
+	else
+		{
+#ifdef TEST_ENG_OPENSSL_SHA_OTHERS
+		fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for "
+				"nid %d\n", nid);
+#endif
+		*digest = NULL;
+		return 0;
+		}
+	return 1;
+	}
+#endif
+
+#ifdef TEST_ENG_OPENSSL_PKEY
+static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data)
+	{
+	BIO *in;
+	EVP_PKEY *key;
+	fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n", key_id);
+	in = BIO_new_file(key_id, "r");
+	if (!in)
+		return NULL;
+	key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL);
+	BIO_free(in);
+	return key;
+	}
+#endif
diff --git a/openssl/crypto/engine/eng_pkey.c b/openssl/crypto/engine/eng_pkey.c
new file mode 100644
index 0000000..1dfa2e3
--- /dev/null
+++ b/openssl/crypto/engine/eng_pkey.c
@@ -0,0 +1,196 @@
+/* crypto/engine/eng_pkey.c */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* Basic get/set stuff */
+
+int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f)
+	{
+	e->load_privkey = loadpriv_f;
+	return 1;
+	}
+
+int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f)
+	{
+	e->load_pubkey = loadpub_f;
+	return 1;
+	}
+
+int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
+				ENGINE_SSL_CLIENT_CERT_PTR loadssl_f)
+	{
+	e->load_ssl_client_cert = loadssl_f;
+	return 1;
+	}
+
+ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e)
+	{
+	return e->load_privkey;
+	}
+
+ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e)
+	{
+	return e->load_pubkey;
+	}
+
+ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e)
+	{
+	return e->load_ssl_client_cert;
+	}
+
+/* API functions to load public/private keys */
+
+EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data)
+	{
+	EVP_PKEY *pkey;
+
+	if(e == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if(e->funct_ref == 0)
+		{
+		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
+			ENGINE_R_NOT_INITIALISED);
+		return 0;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	if (!e->load_privkey)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
+			ENGINE_R_NO_LOAD_FUNCTION);
+		return 0;
+		}
+	pkey = e->load_privkey(e, key_id, ui_method, callback_data);
+	if (!pkey)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
+			ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
+		return 0;
+		}
+	return pkey;
+	}
+
+EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data)
+	{
+	EVP_PKEY *pkey;
+
+	if(e == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if(e->funct_ref == 0)
+		{
+		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
+			ENGINE_R_NOT_INITIALISED);
+		return 0;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	if (!e->load_pubkey)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
+			ENGINE_R_NO_LOAD_FUNCTION);
+		return 0;
+		}
+	pkey = e->load_pubkey(e, key_id, ui_method, callback_data);
+	if (!pkey)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
+			ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
+		return 0;
+		}
+	return pkey;
+	}
+
+int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
+	STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey,
+	STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data)
+	{
+
+	if(e == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if(e->funct_ref == 0)
+		{
+		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
+			ENGINE_R_NOT_INITIALISED);
+		return 0;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	if (!e->load_ssl_client_cert)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
+			ENGINE_R_NO_LOAD_FUNCTION);
+		return 0;
+		}
+	return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother,
+					ui_method, callback_data);
+	}
diff --git a/openssl/crypto/engine/eng_table.c b/openssl/crypto/engine/eng_table.c
new file mode 100644
index 0000000..4fde948
--- /dev/null
+++ b/openssl/crypto/engine/eng_table.c
@@ -0,0 +1,351 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/lhash.h>
+#include "eng_int.h"
+
+/* The type of the items in the table */
+typedef struct st_engine_pile
+	{
+	/* The 'nid' of this algorithm/mode */
+	int nid;
+	/* ENGINEs that implement this algorithm/mode. */
+	STACK_OF(ENGINE) *sk;
+	/* The default ENGINE to perform this algorithm/mode. */
+	ENGINE *funct;
+	/* Zero if 'sk' is newer than the cached 'funct', non-zero otherwise */
+	int uptodate;
+	} ENGINE_PILE;
+
+DECLARE_LHASH_OF(ENGINE_PILE);
+
+/* The type exposed in eng_int.h */
+struct st_engine_table
+	{
+	LHASH_OF(ENGINE_PILE) piles;
+	}; /* ENGINE_TABLE */
+
+
+typedef struct st_engine_pile_doall
+	{
+	engine_table_doall_cb *cb;
+	void *arg;
+	} ENGINE_PILE_DOALL;
+	
+
+/* Global flags (ENGINE_TABLE_FLAG_***). */
+static unsigned int table_flags = 0;
+
+/* API function manipulating 'table_flags' */
+unsigned int ENGINE_get_table_flags(void)
+	{
+	return table_flags;
+	}
+
+void ENGINE_set_table_flags(unsigned int flags)
+	{
+	table_flags = flags;
+	}
+
+/* Internal functions for the "piles" hash table */
+static unsigned long engine_pile_hash(const ENGINE_PILE *c)
+	{
+	return c->nid;
+	}
+
+static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b)
+	{
+	return a->nid - b->nid;
+	}
+static IMPLEMENT_LHASH_HASH_FN(engine_pile, ENGINE_PILE)
+static IMPLEMENT_LHASH_COMP_FN(engine_pile, ENGINE_PILE)
+
+static int int_table_check(ENGINE_TABLE **t, int create)
+	{
+	LHASH_OF(ENGINE_PILE) *lh;
+
+	if(*t) return 1;
+	if(!create) return 0;
+	if((lh = lh_ENGINE_PILE_new()) == NULL)
+		return 0;
+	*t = (ENGINE_TABLE *)lh;
+	return 1;
+	}
+
+/* Privately exposed (via eng_int.h) functions for adding and/or removing
+ * ENGINEs from the implementation table */
+int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
+		ENGINE *e, const int *nids, int num_nids, int setdefault)
+	{
+	int ret = 0, added = 0;
+	ENGINE_PILE tmplate, *fnd;
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if(!(*table))
+		added = 1;
+	if(!int_table_check(table, 1))
+		goto end;
+	if(added)
+		/* The cleanup callback needs to be added */
+		engine_cleanup_add_first(cleanup);
+	while(num_nids--)
+		{
+		tmplate.nid = *nids;
+		fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
+		if(!fnd)
+			{
+			fnd = OPENSSL_malloc(sizeof(ENGINE_PILE));
+			if(!fnd) goto end;
+			fnd->uptodate = 1;
+			fnd->nid = *nids;
+			fnd->sk = sk_ENGINE_new_null();
+			if(!fnd->sk)
+				{
+				OPENSSL_free(fnd);
+				goto end;
+				}
+			fnd->funct = NULL;
+			(void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd);
+			}
+		/* A registration shouldn't add duplciate entries */
+		(void)sk_ENGINE_delete_ptr(fnd->sk, e);
+		/* if 'setdefault', this ENGINE goes to the head of the list */
+		if(!sk_ENGINE_push(fnd->sk, e))
+			goto end;
+		/* "touch" this ENGINE_PILE */
+		fnd->uptodate = 0;
+		if(setdefault)
+			{
+			if(!engine_unlocked_init(e))
+				{
+				ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER,
+						ENGINE_R_INIT_FAILED);
+				goto end;
+				}
+			if(fnd->funct)
+				engine_unlocked_finish(fnd->funct, 0);
+			fnd->funct = e;
+			fnd->uptodate = 1;
+			}
+		nids++;
+		}
+	ret = 1;
+end:
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	return ret;
+	}
+static void int_unregister_cb_doall_arg(ENGINE_PILE *pile, ENGINE *e)
+	{
+	int n;
+	/* Iterate the 'c->sk' stack removing any occurance of 'e' */
+	while((n = sk_ENGINE_find(pile->sk, e)) >= 0)
+		{
+		(void)sk_ENGINE_delete(pile->sk, n);
+		pile->uptodate = 0;
+		}
+	if(pile->funct == e)
+		{
+		engine_unlocked_finish(e, 0);
+		pile->funct = NULL;
+		}
+	}
+static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb, ENGINE_PILE, ENGINE)
+
+void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e)
+	{
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if(int_table_check(table, 0))
+		lh_ENGINE_PILE_doall_arg(&(*table)->piles,
+					 LHASH_DOALL_ARG_FN(int_unregister_cb),
+					 ENGINE, e);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	}
+
+static void int_cleanup_cb_doall(ENGINE_PILE *p)
+	{
+	sk_ENGINE_free(p->sk);
+	if(p->funct)
+		engine_unlocked_finish(p->funct, 0);
+	OPENSSL_free(p);
+	}
+static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb, ENGINE_PILE)
+
+void engine_table_cleanup(ENGINE_TABLE **table)
+	{
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if(*table)
+		{
+		lh_ENGINE_PILE_doall(&(*table)->piles,
+				     LHASH_DOALL_FN(int_cleanup_cb));
+		lh_ENGINE_PILE_free(&(*table)->piles);
+		*table = NULL;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	}
+
+/* return a functional reference for a given 'nid' */
+#ifndef ENGINE_TABLE_DEBUG
+ENGINE *engine_table_select(ENGINE_TABLE **table, int nid)
+#else
+ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l)
+#endif
+	{
+	ENGINE *ret = NULL;
+	ENGINE_PILE tmplate, *fnd=NULL;
+	int initres, loop = 0;
+
+	if(!(*table))
+		{
+#ifdef ENGINE_TABLE_DEBUG
+		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing "
+			"registered!\n", f, l, nid);
+#endif
+		return NULL;
+		}
+	ERR_set_mark();
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	/* Check again inside the lock otherwise we could race against cleanup
+	 * operations. But don't worry about a fprintf(stderr). */
+	if(!int_table_check(table, 0)) goto end;
+	tmplate.nid = nid;
+	fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
+	if(!fnd) goto end;
+	if(fnd->funct && engine_unlocked_init(fnd->funct))
+		{
+#ifdef ENGINE_TABLE_DEBUG
+		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
+			"ENGINE '%s' cached\n", f, l, nid, fnd->funct->id);
+#endif
+		ret = fnd->funct;
+		goto end;
+		}
+	if(fnd->uptodate)
+		{
+		ret = fnd->funct;
+		goto end;
+		}
+trynext:
+	ret = sk_ENGINE_value(fnd->sk, loop++);
+	if(!ret)
+		{
+#ifdef ENGINE_TABLE_DEBUG
+		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no "
+				"registered implementations would initialise\n",
+				f, l, nid);
+#endif
+		goto end;
+		}
+	/* Try to initialise the ENGINE? */
+	if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT))
+		initres = engine_unlocked_init(ret);
+	else
+		initres = 0;
+	if(initres)
+		{
+		/* Update 'funct' */
+		if((fnd->funct != ret) && engine_unlocked_init(ret))
+			{
+			/* If there was a previous default we release it. */
+			if(fnd->funct)
+				engine_unlocked_finish(fnd->funct, 0);
+			fnd->funct = ret;
+#ifdef ENGINE_TABLE_DEBUG
+			fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, "
+				"setting default to '%s'\n", f, l, nid, ret->id);
+#endif
+			}
+#ifdef ENGINE_TABLE_DEBUG
+		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
+				"newly initialised '%s'\n", f, l, nid, ret->id);
+#endif
+		goto end;
+		}
+	goto trynext;
+end:
+	/* If it failed, it is unlikely to succeed again until some future
+	 * registrations have taken place. In all cases, we cache. */
+	if(fnd) fnd->uptodate = 1;
+#ifdef ENGINE_TABLE_DEBUG
+	if(ret)
+		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
+				"ENGINE '%s'\n", f, l, nid, ret->id);
+	else
+		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
+				"'no matching ENGINE'\n", f, l, nid);
+#endif
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	/* Whatever happened, any failed init()s are not failures in this
+	 * context, so clear our error state. */
+	ERR_pop_to_mark();
+	return ret;
+	}
+
+/* Table enumeration */
+
+static void int_cb_doall_arg(ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall)
+	{
+	dall->cb(pile->nid, pile->sk, pile->funct, dall->arg);
+	}
+static IMPLEMENT_LHASH_DOALL_ARG_FN(int_cb, ENGINE_PILE,ENGINE_PILE_DOALL)
+
+void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,
+								void *arg)
+	{
+	ENGINE_PILE_DOALL dall;
+	dall.cb = cb;
+	dall.arg = arg;
+	lh_ENGINE_PILE_doall_arg(&table->piles, LHASH_DOALL_ARG_FN(int_cb),
+				 ENGINE_PILE_DOALL, &dall);
+	}
diff --git a/openssl/crypto/engine/engine.h b/openssl/crypto/engine/engine.h
new file mode 100644
index 0000000..943aeae
--- /dev/null
+++ b/openssl/crypto/engine/engine.h
@@ -0,0 +1,833 @@
+/* openssl/engine.h */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_ENGINE_H
+#define HEADER_ENGINE_H
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_ENGINE
+#error ENGINE is disabled.
+#endif
+
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#ifndef OPENSSL_NO_ECDH
+#include <openssl/ecdh.h>
+#endif
+#ifndef OPENSSL_NO_ECDSA
+#include <openssl/ecdsa.h>
+#endif
+#include <openssl/rand.h>
+#include <openssl/ui.h>
+#include <openssl/err.h>
+#endif
+
+#include <openssl/ossl_typ.h>
+#include <openssl/symhacks.h>
+
+#include <openssl/x509.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* These flags are used to control combinations of algorithm (methods)
+ * by bitwise "OR"ing. */
+#define ENGINE_METHOD_RSA		(unsigned int)0x0001
+#define ENGINE_METHOD_DSA		(unsigned int)0x0002
+#define ENGINE_METHOD_DH		(unsigned int)0x0004
+#define ENGINE_METHOD_RAND		(unsigned int)0x0008
+#define ENGINE_METHOD_ECDH		(unsigned int)0x0010
+#define ENGINE_METHOD_ECDSA		(unsigned int)0x0020
+#define ENGINE_METHOD_CIPHERS		(unsigned int)0x0040
+#define ENGINE_METHOD_DIGESTS		(unsigned int)0x0080
+#define ENGINE_METHOD_STORE		(unsigned int)0x0100
+#define ENGINE_METHOD_PKEY_METHS	(unsigned int)0x0200
+#define ENGINE_METHOD_PKEY_ASN1_METHS	(unsigned int)0x0400
+/* Obvious all-or-nothing cases. */
+#define ENGINE_METHOD_ALL		(unsigned int)0xFFFF
+#define ENGINE_METHOD_NONE		(unsigned int)0x0000
+
+/* This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used
+ * internally to control registration of ENGINE implementations, and can be set
+ * by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to
+ * initialise registered ENGINEs if they are not already initialised. */
+#define ENGINE_TABLE_FLAG_NOINIT	(unsigned int)0x0001
+
+/* ENGINE flags that can be set by ENGINE_set_flags(). */
+/* #define ENGINE_FLAGS_MALLOCED	0x0001 */ /* Not used */
+
+/* This flag is for ENGINEs that wish to handle the various 'CMD'-related
+ * control commands on their own. Without this flag, ENGINE_ctrl() handles these
+ * control commands on behalf of the ENGINE using their "cmd_defns" data. */
+#define ENGINE_FLAGS_MANUAL_CMD_CTRL	(int)0x0002
+
+/* This flag is for ENGINEs who return new duplicate structures when found via
+ * "ENGINE_by_id()". When an ENGINE must store state (eg. if ENGINE_ctrl()
+ * commands are called in sequence as part of some stateful process like
+ * key-generation setup and execution), it can set this flag - then each attempt
+ * to obtain the ENGINE will result in it being copied into a new structure.
+ * Normally, ENGINEs don't declare this flag so ENGINE_by_id() just increments
+ * the existing ENGINE's structural reference count. */
+#define ENGINE_FLAGS_BY_ID_COPY		(int)0x0004
+
+/* ENGINEs can support their own command types, and these flags are used in
+ * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input each
+ * command expects. Currently only numeric and string input is supported. If a
+ * control command supports none of the _NUMERIC, _STRING, or _NO_INPUT options,
+ * then it is regarded as an "internal" control command - and not for use in
+ * config setting situations. As such, they're not available to the
+ * ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() access. Changes to
+ * this list of 'command types' should be reflected carefully in
+ * ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). */
+
+/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */
+#define ENGINE_CMD_FLAG_NUMERIC		(unsigned int)0x0001
+/* accepts string input (cast from 'void*' to 'const char *', 4th parameter to
+ * ENGINE_ctrl) */
+#define ENGINE_CMD_FLAG_STRING		(unsigned int)0x0002
+/* Indicates that the control command takes *no* input. Ie. the control command
+ * is unparameterised. */
+#define ENGINE_CMD_FLAG_NO_INPUT	(unsigned int)0x0004
+/* Indicates that the control command is internal. This control command won't
+ * be shown in any output, and is only usable through the ENGINE_ctrl_cmd()
+ * function. */
+#define ENGINE_CMD_FLAG_INTERNAL	(unsigned int)0x0008
+
+/* NB: These 3 control commands are deprecated and should not be used. ENGINEs
+ * relying on these commands should compile conditional support for
+ * compatibility (eg. if these symbols are defined) but should also migrate the
+ * same functionality to their own ENGINE-specific control functions that can be
+ * "discovered" by calling applications. The fact these control commands
+ * wouldn't be "executable" (ie. usable by text-based config) doesn't change the
+ * fact that application code can find and use them without requiring per-ENGINE
+ * hacking. */
+
+/* These flags are used to tell the ctrl function what should be done.
+ * All command numbers are shared between all engines, even if some don't
+ * make sense to some engines.  In such a case, they do nothing but return
+ * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */
+#define ENGINE_CTRL_SET_LOGSTREAM		1
+#define ENGINE_CTRL_SET_PASSWORD_CALLBACK	2
+#define ENGINE_CTRL_HUP				3 /* Close and reinitialise any
+						     handles/connections etc. */
+#define ENGINE_CTRL_SET_USER_INTERFACE          4 /* Alternative to callback */
+#define ENGINE_CTRL_SET_CALLBACK_DATA           5 /* User-specific data, used
+						     when calling the password
+						     callback and the user
+						     interface */
+#define ENGINE_CTRL_LOAD_CONFIGURATION		6 /* Load a configuration, given
+						     a string that represents a
+						     file name or so */
+#define ENGINE_CTRL_LOAD_SECTION		7 /* Load data from a given
+						     section in the already loaded
+						     configuration */
+
+/* These control commands allow an application to deal with an arbitrary engine
+ * in a dynamic way. Warn: Negative return values indicate errors FOR THESE
+ * COMMANDS because zero is used to indicate 'end-of-list'. Other commands,
+ * including ENGINE-specific command types, return zero for an error.
+ *
+ * An ENGINE can choose to implement these ctrl functions, and can internally
+ * manage things however it chooses - it does so by setting the
+ * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise the
+ * ENGINE_ctrl() code handles this on the ENGINE's behalf using the cmd_defns
+ * data (set using ENGINE_set_cmd_defns()). This means an ENGINE's ctrl()
+ * handler need only implement its own commands - the above "meta" commands will
+ * be taken care of. */
+
+/* Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", then
+ * all the remaining control commands will return failure, so it is worth
+ * checking this first if the caller is trying to "discover" the engine's
+ * capabilities and doesn't want errors generated unnecessarily. */
+#define ENGINE_CTRL_HAS_CTRL_FUNCTION		10
+/* Returns a positive command number for the first command supported by the
+ * engine. Returns zero if no ctrl commands are supported. */
+#define ENGINE_CTRL_GET_FIRST_CMD_TYPE		11
+/* The 'long' argument specifies a command implemented by the engine, and the
+ * return value is the next command supported, or zero if there are no more. */
+#define ENGINE_CTRL_GET_NEXT_CMD_TYPE		12
+/* The 'void*' argument is a command name (cast from 'const char *'), and the
+ * return value is the command that corresponds to it. */
+#define ENGINE_CTRL_GET_CMD_FROM_NAME		13
+/* The next two allow a command to be converted into its corresponding string
+ * form. In each case, the 'long' argument supplies the command. In the NAME_LEN
+ * case, the return value is the length of the command name (not counting a
+ * trailing EOL). In the NAME case, the 'void*' argument must be a string buffer
+ * large enough, and it will be populated with the name of the command (WITH a
+ * trailing EOL). */
+#define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD	14
+#define ENGINE_CTRL_GET_NAME_FROM_CMD		15
+/* The next two are similar but give a "short description" of a command. */
+#define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD	16
+#define ENGINE_CTRL_GET_DESC_FROM_CMD		17
+/* With this command, the return value is the OR'd combination of
+ * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given
+ * engine-specific ctrl command expects. */
+#define ENGINE_CTRL_GET_CMD_FLAGS		18
+
+/* ENGINE implementations should start the numbering of their own control
+ * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). */
+#define ENGINE_CMD_BASE				200
+
+/* NB: These 2 nCipher "chil" control commands are deprecated, and their
+ * functionality is now available through ENGINE-specific control commands
+ * (exposed through the above-mentioned 'CMD'-handling). Code using these 2
+ * commands should be migrated to the more general command handling before these
+ * are removed. */
+
+/* Flags specific to the nCipher "chil" engine */
+#define ENGINE_CTRL_CHIL_SET_FORKCHECK		100
+	/* Depending on the value of the (long)i argument, this sets or
+	 * unsets the SimpleForkCheck flag in the CHIL API to enable or
+	 * disable checking and workarounds for applications that fork().
+	 */
+#define ENGINE_CTRL_CHIL_NO_LOCKING		101
+	/* This prevents the initialisation function from providing mutex
+	 * callbacks to the nCipher library. */
+
+/* If an ENGINE supports its own specific control commands and wishes the
+ * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on its
+ * behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN entries
+ * to ENGINE_set_cmd_defns(). It should also implement a ctrl() handler that
+ * supports the stated commands (ie. the "cmd_num" entries as described by the
+ * array). NB: The array must be ordered in increasing order of cmd_num.
+ * "null-terminated" means that the last ENGINE_CMD_DEFN element has cmd_num set
+ * to zero and/or cmd_name set to NULL. */
+typedef struct ENGINE_CMD_DEFN_st
+	{
+	unsigned int cmd_num; /* The command number */
+	const char *cmd_name; /* The command name itself */
+	const char *cmd_desc; /* A short description of the command */
+	unsigned int cmd_flags; /* The input the command expects */
+	} ENGINE_CMD_DEFN;
+
+/* Generic function pointer */
+typedef int (*ENGINE_GEN_FUNC_PTR)(void);
+/* Generic function pointer taking no arguments */
+typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *);
+/* Specific control function pointer */
+typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, void (*f)(void));
+/* Generic load_key function pointer */
+typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
+	UI_METHOD *ui_method, void *callback_data);
+typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl,
+	STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
+	STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data);
+/* These callback types are for an ENGINE's handler for cipher and digest logic.
+ * These handlers have these prototypes;
+ *   int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
+ *   int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid);
+ * Looking at how to implement these handlers in the case of cipher support, if
+ * the framework wants the EVP_CIPHER for 'nid', it will call;
+ *   foo(e, &p_evp_cipher, NULL, nid);    (return zero for failure)
+ * If the framework wants a list of supported 'nid's, it will call;
+ *   foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error)
+ */
+/* Returns to a pointer to the array of supported cipher 'nid's. If the second
+ * parameter is non-NULL it is set to the size of the returned array. */
+typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int);
+typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int);
+typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, const int **, int);
+typedef int (*ENGINE_PKEY_ASN1_METHS_PTR)(ENGINE *, EVP_PKEY_ASN1_METHOD **, const int **, int);
+/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE
+ * structures where the pointers have a "structural reference". This means that
+ * their reference is to allowed access to the structure but it does not imply
+ * that the structure is functional. To simply increment or decrement the
+ * structural reference count, use ENGINE_by_id and ENGINE_free. NB: This is not
+ * required when iterating using ENGINE_get_next as it will automatically
+ * decrement the structural reference count of the "current" ENGINE and
+ * increment the structural reference count of the ENGINE it returns (unless it
+ * is NULL). */
+
+/* Get the first/last "ENGINE" type available. */
+ENGINE *ENGINE_get_first(void);
+ENGINE *ENGINE_get_last(void);
+/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
+ENGINE *ENGINE_get_next(ENGINE *e);
+ENGINE *ENGINE_get_prev(ENGINE *e);
+/* Add another "ENGINE" type into the array. */
+int ENGINE_add(ENGINE *e);
+/* Remove an existing "ENGINE" type from the array. */
+int ENGINE_remove(ENGINE *e);
+/* Retrieve an engine from the list by its unique "id" value. */
+ENGINE *ENGINE_by_id(const char *id);
+/* Add all the built-in engines. */
+void ENGINE_load_openssl(void);
+void ENGINE_load_dynamic(void);
+#ifndef OPENSSL_NO_STATIC_ENGINE
+void ENGINE_load_4758cca(void);
+void ENGINE_load_aep(void);
+void ENGINE_load_atalla(void);
+void ENGINE_load_chil(void);
+void ENGINE_load_cswift(void);
+void ENGINE_load_nuron(void);
+void ENGINE_load_sureware(void);
+void ENGINE_load_ubsec(void);
+void ENGINE_load_padlock(void);
+void ENGINE_load_capi(void);
+#ifndef OPENSSL_NO_GMP
+void ENGINE_load_gmp(void);
+#endif
+#ifndef OPENSSL_NO_GOST
+void ENGINE_load_gost(void);
+#endif
+#endif
+void ENGINE_load_cryptodev(void);
+void ENGINE_load_builtin_engines(void);
+
+/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
+ * "registry" handling. */
+unsigned int ENGINE_get_table_flags(void);
+void ENGINE_set_table_flags(unsigned int flags);
+
+/* Manage registration of ENGINEs per "table". For each type, there are 3
+ * functions;
+ *   ENGINE_register_***(e) - registers the implementation from 'e' (if it has one)
+ *   ENGINE_unregister_***(e) - unregister the implementation from 'e'
+ *   ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list
+ * Cleanup is automatically registered from each table when required, so
+ * ENGINE_cleanup() will reverse any "register" operations. */
+
+int ENGINE_register_RSA(ENGINE *e);
+void ENGINE_unregister_RSA(ENGINE *e);
+void ENGINE_register_all_RSA(void);
+
+int ENGINE_register_DSA(ENGINE *e);
+void ENGINE_unregister_DSA(ENGINE *e);
+void ENGINE_register_all_DSA(void);
+
+int ENGINE_register_ECDH(ENGINE *e);
+void ENGINE_unregister_ECDH(ENGINE *e);
+void ENGINE_register_all_ECDH(void);
+
+int ENGINE_register_ECDSA(ENGINE *e);
+void ENGINE_unregister_ECDSA(ENGINE *e);
+void ENGINE_register_all_ECDSA(void);
+
+int ENGINE_register_DH(ENGINE *e);
+void ENGINE_unregister_DH(ENGINE *e);
+void ENGINE_register_all_DH(void);
+
+int ENGINE_register_RAND(ENGINE *e);
+void ENGINE_unregister_RAND(ENGINE *e);
+void ENGINE_register_all_RAND(void);
+
+int ENGINE_register_STORE(ENGINE *e);
+void ENGINE_unregister_STORE(ENGINE *e);
+void ENGINE_register_all_STORE(void);
+
+int ENGINE_register_ciphers(ENGINE *e);
+void ENGINE_unregister_ciphers(ENGINE *e);
+void ENGINE_register_all_ciphers(void);
+
+int ENGINE_register_digests(ENGINE *e);
+void ENGINE_unregister_digests(ENGINE *e);
+void ENGINE_register_all_digests(void);
+
+int ENGINE_register_pkey_meths(ENGINE *e);
+void ENGINE_unregister_pkey_meths(ENGINE *e);
+void ENGINE_register_all_pkey_meths(void);
+
+int ENGINE_register_pkey_asn1_meths(ENGINE *e);
+void ENGINE_unregister_pkey_asn1_meths(ENGINE *e);
+void ENGINE_register_all_pkey_asn1_meths(void);
+
+/* These functions register all support from the above categories. Note, use of
+ * these functions can result in static linkage of code your application may not
+ * need. If you only need a subset of functionality, consider using more
+ * selective initialisation. */
+int ENGINE_register_complete(ENGINE *e);
+int ENGINE_register_all_complete(void);
+
+/* Send parametrised control commands to the engine. The possibilities to send
+ * down an integer, a pointer to data or a function pointer are provided. Any of
+ * the parameters may or may not be NULL, depending on the command number. In
+ * actuality, this function only requires a structural (rather than functional)
+ * reference to an engine, but many control commands may require the engine be
+ * functional. The caller should be aware of trying commands that require an
+ * operational ENGINE, and only use functional references in such situations. */
+int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+
+/* This function tests if an ENGINE-specific command is usable as a "setting".
+ * Eg. in an application's config file that gets processed through
+ * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to
+ * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). */
+int ENGINE_cmd_is_executable(ENGINE *e, int cmd);
+
+/* This function works like ENGINE_ctrl() with the exception of taking a
+ * command name instead of a command number, and can handle optional commands.
+ * See the comment on ENGINE_ctrl_cmd_string() for an explanation on how to
+ * use the cmd_name and cmd_optional. */
+int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
+        long i, void *p, void (*f)(void), int cmd_optional);
+
+/* This function passes a command-name and argument to an ENGINE. The cmd_name
+ * is converted to a command number and the control command is called using
+ * 'arg' as an argument (unless the ENGINE doesn't support such a command, in
+ * which case no control command is called). The command is checked for input
+ * flags, and if necessary the argument will be converted to a numeric value. If
+ * cmd_optional is non-zero, then if the ENGINE doesn't support the given
+ * cmd_name the return value will be success anyway. This function is intended
+ * for applications to use so that users (or config files) can supply
+ * engine-specific config data to the ENGINE at run-time to control behaviour of
+ * specific engines. As such, it shouldn't be used for calling ENGINE_ctrl()
+ * functions that return data, deal with binary data, or that are otherwise
+ * supposed to be used directly through ENGINE_ctrl() in application code. Any
+ * "return" data from an ENGINE_ctrl() operation in this function will be lost -
+ * the return value is interpreted as failure if the return value is zero,
+ * success otherwise, and this function returns a boolean value as a result. In
+ * other words, vendors of 'ENGINE'-enabled devices should write ENGINE
+ * implementations with parameterisations that work in this scheme, so that
+ * compliant ENGINE-based applications can work consistently with the same
+ * configuration for the same ENGINE-enabled devices, across applications. */
+int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
+				int cmd_optional);
+
+/* These functions are useful for manufacturing new ENGINE structures. They
+ * don't address reference counting at all - one uses them to populate an ENGINE
+ * structure with personalised implementations of things prior to using it
+ * directly or adding it to the builtin ENGINE list in OpenSSL. These are also
+ * here so that the ENGINE structure doesn't have to be exposed and break binary
+ * compatibility! */
+ENGINE *ENGINE_new(void);
+int ENGINE_free(ENGINE *e);
+int ENGINE_up_ref(ENGINE *e);
+int ENGINE_set_id(ENGINE *e, const char *id);
+int ENGINE_set_name(ENGINE *e, const char *name);
+int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
+int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
+int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth);
+int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth);
+int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
+int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
+int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth);
+int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
+int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
+int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
+int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
+int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f);
+int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
+int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
+				ENGINE_SSL_CLIENT_CERT_PTR loadssl_f);
+int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
+int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
+int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f);
+int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f);
+int ENGINE_set_flags(ENGINE *e, int flags);
+int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
+/* These functions allow control over any per-structure ENGINE data. */
+int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+		CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
+void *ENGINE_get_ex_data(const ENGINE *e, int idx);
+
+/* This function cleans up anything that needs it. Eg. the ENGINE_add() function
+ * automatically ensures the list cleanup function is registered to be called
+ * from ENGINE_cleanup(). Similarly, all ENGINE_register_*** functions ensure
+ * ENGINE_cleanup() will clean up after them. */
+void ENGINE_cleanup(void);
+
+/* These return values from within the ENGINE structure. These can be useful
+ * with functional references as well as structural references - it depends
+ * which you obtained. Using the result for functional purposes if you only
+ * obtained a structural reference may be problematic! */
+const char *ENGINE_get_id(const ENGINE *e);
+const char *ENGINE_get_name(const ENGINE *e);
+const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
+const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
+const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e);
+const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e);
+const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
+const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
+const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
+ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
+ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
+ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
+ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e);
+ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
+ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
+ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e);
+ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e);
+const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
+const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
+const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
+					const char *str, int len);
+const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
+					const char *str, int len);
+const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
+int ENGINE_get_flags(const ENGINE *e);
+
+/* FUNCTIONAL functions. These functions deal with ENGINE structures
+ * that have (or will) be initialised for use. Broadly speaking, the
+ * structural functions are useful for iterating the list of available
+ * engine types, creating new engine types, and other "list" operations.
+ * These functions actually deal with ENGINEs that are to be used. As
+ * such these functions can fail (if applicable) when particular
+ * engines are unavailable - eg. if a hardware accelerator is not
+ * attached or not functioning correctly. Each ENGINE has 2 reference
+ * counts; structural and functional. Every time a functional reference
+ * is obtained or released, a corresponding structural reference is
+ * automatically obtained or released too. */
+
+/* Initialise a engine type for use (or up its reference count if it's
+ * already in use). This will fail if the engine is not currently
+ * operational and cannot initialise. */
+int ENGINE_init(ENGINE *e);
+/* Free a functional reference to a engine type. This does not require
+ * a corresponding call to ENGINE_free as it also releases a structural
+ * reference. */
+int ENGINE_finish(ENGINE *e);
+
+/* The following functions handle keys that are stored in some secondary
+ * location, handled by the engine.  The storage may be on a card or
+ * whatever. */
+EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data);
+EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data);
+int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
+	STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey,
+	STACK_OF(X509) **pother,
+	UI_METHOD *ui_method, void *callback_data);
+
+/* This returns a pointer for the current ENGINE structure that
+ * is (by default) performing any RSA operations. The value returned
+ * is an incremented reference, so it should be free'd (ENGINE_finish)
+ * before it is discarded. */
+ENGINE *ENGINE_get_default_RSA(void);
+/* Same for the other "methods" */
+ENGINE *ENGINE_get_default_DSA(void);
+ENGINE *ENGINE_get_default_ECDH(void);
+ENGINE *ENGINE_get_default_ECDSA(void);
+ENGINE *ENGINE_get_default_DH(void);
+ENGINE *ENGINE_get_default_RAND(void);
+/* These functions can be used to get a functional reference to perform
+ * ciphering or digesting corresponding to "nid". */
+ENGINE *ENGINE_get_cipher_engine(int nid);
+ENGINE *ENGINE_get_digest_engine(int nid);
+ENGINE *ENGINE_get_pkey_meth_engine(int nid);
+ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid);
+
+/* This sets a new default ENGINE structure for performing RSA
+ * operations. If the result is non-zero (success) then the ENGINE
+ * structure will have had its reference count up'd so the caller
+ * should still free their own reference 'e'. */
+int ENGINE_set_default_RSA(ENGINE *e);
+int ENGINE_set_default_string(ENGINE *e, const char *def_list);
+/* Same for the other "methods" */
+int ENGINE_set_default_DSA(ENGINE *e);
+int ENGINE_set_default_ECDH(ENGINE *e);
+int ENGINE_set_default_ECDSA(ENGINE *e);
+int ENGINE_set_default_DH(ENGINE *e);
+int ENGINE_set_default_RAND(ENGINE *e);
+int ENGINE_set_default_ciphers(ENGINE *e);
+int ENGINE_set_default_digests(ENGINE *e);
+int ENGINE_set_default_pkey_meths(ENGINE *e);
+int ENGINE_set_default_pkey_asn1_meths(ENGINE *e);
+
+/* The combination "set" - the flags are bitwise "OR"d from the
+ * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
+ * function, this function can result in unnecessary static linkage. If your
+ * application requires only specific functionality, consider using more
+ * selective functions. */
+int ENGINE_set_default(ENGINE *e, unsigned int flags);
+
+void ENGINE_add_conf_module(void);
+
+/* Deprecated functions ... */
+/* int ENGINE_clear_defaults(void); */
+
+/**************************/
+/* DYNAMIC ENGINE SUPPORT */
+/**************************/
+
+/* Binary/behaviour compatibility levels */
+#define OSSL_DYNAMIC_VERSION		(unsigned long)0x00020000
+/* Binary versions older than this are too old for us (whether we're a loader or
+ * a loadee) */
+#define OSSL_DYNAMIC_OLDEST		(unsigned long)0x00020000
+
+/* When compiling an ENGINE entirely as an external shared library, loadable by
+ * the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure
+ * type provides the calling application's (or library's) error functionality
+ * and memory management function pointers to the loaded library. These should
+ * be used/set in the loaded library code so that the loading application's
+ * 'state' will be used/changed in all operations. The 'static_state' pointer
+ * allows the loaded library to know if it shares the same static data as the
+ * calling application (or library), and thus whether these callbacks need to be
+ * set or not. */
+typedef void *(*dyn_MEM_malloc_cb)(size_t);
+typedef void *(*dyn_MEM_realloc_cb)(void *, size_t);
+typedef void (*dyn_MEM_free_cb)(void *);
+typedef struct st_dynamic_MEM_fns {
+	dyn_MEM_malloc_cb			malloc_cb;
+	dyn_MEM_realloc_cb			realloc_cb;
+	dyn_MEM_free_cb				free_cb;
+	} dynamic_MEM_fns;
+/* FIXME: Perhaps the memory and locking code (crypto.h) should declare and use
+ * these types so we (and any other dependant code) can simplify a bit?? */
+typedef void (*dyn_lock_locking_cb)(int,int,const char *,int);
+typedef int (*dyn_lock_add_lock_cb)(int*,int,int,const char *,int);
+typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb)(
+						const char *,int);
+typedef void (*dyn_dynlock_lock_cb)(int,struct CRYPTO_dynlock_value *,
+						const char *,int);
+typedef void (*dyn_dynlock_destroy_cb)(struct CRYPTO_dynlock_value *,
+						const char *,int);
+typedef struct st_dynamic_LOCK_fns {
+	dyn_lock_locking_cb			lock_locking_cb;
+	dyn_lock_add_lock_cb			lock_add_lock_cb;
+	dyn_dynlock_create_cb			dynlock_create_cb;
+	dyn_dynlock_lock_cb			dynlock_lock_cb;
+	dyn_dynlock_destroy_cb			dynlock_destroy_cb;
+	} dynamic_LOCK_fns;
+/* The top-level structure */
+typedef struct st_dynamic_fns {
+	void 					*static_state;
+	const ERR_FNS				*err_fns;
+	const CRYPTO_EX_DATA_IMPL		*ex_data_fns;
+	dynamic_MEM_fns				mem_fns;
+	dynamic_LOCK_fns			lock_fns;
+	} dynamic_fns;
+
+/* The version checking function should be of this prototype. NB: The
+ * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading code.
+ * If this function returns zero, it indicates a (potential) version
+ * incompatibility and the loaded library doesn't believe it can proceed.
+ * Otherwise, the returned value is the (latest) version supported by the
+ * loading library. The loader may still decide that the loaded code's version
+ * is unsatisfactory and could veto the load. The function is expected to
+ * be implemented with the symbol name "v_check", and a default implementation
+ * can be fully instantiated with IMPLEMENT_DYNAMIC_CHECK_FN(). */
+typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version);
+#define IMPLEMENT_DYNAMIC_CHECK_FN() \
+	OPENSSL_EXPORT unsigned long v_check(unsigned long v); \
+	OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \
+		if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \
+		return 0; }
+
+/* This function is passed the ENGINE structure to initialise with its own
+ * function and command settings. It should not adjust the structural or
+ * functional reference counts. If this function returns zero, (a) the load will
+ * be aborted, (b) the previous ENGINE state will be memcpy'd back onto the
+ * structure, and (c) the shared library will be unloaded. So implementations
+ * should do their own internal cleanup in failure circumstances otherwise they
+ * could leak. The 'id' parameter, if non-NULL, represents the ENGINE id that
+ * the loader is looking for. If this is NULL, the shared library can choose to
+ * return failure or to initialise a 'default' ENGINE. If non-NULL, the shared
+ * library must initialise only an ENGINE matching the passed 'id'. The function
+ * is expected to be implemented with the symbol name "bind_engine". A standard
+ * implementation can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where
+ * the parameter 'fn' is a callback function that populates the ENGINE structure
+ * and returns an int value (zero for failure). 'fn' should have prototype;
+ *    [static] int fn(ENGINE *e, const char *id); */
+typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
+				const dynamic_fns *fns);
+#define IMPLEMENT_DYNAMIC_BIND_FN(fn) \
+	OPENSSL_EXPORT \
+	int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \
+	OPENSSL_EXPORT \
+	int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \
+		if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \
+		if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
+			fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \
+			return 0; \
+		CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \
+		CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \
+		CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \
+		CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \
+		CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \
+		if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \
+			return 0; \
+		if(!ERR_set_implementation(fns->err_fns)) return 0; \
+	skip_cbs: \
+		if(!fn(e,id)) return 0; \
+		return 1; }
+
+/* If the loading application (or library) and the loaded ENGINE library share
+ * the same static data (eg. they're both dynamically linked to the same
+ * libcrypto.so) we need a way to avoid trying to set system callbacks - this
+ * would fail, and for the same reason that it's unnecessary to try. If the
+ * loaded ENGINE has (or gets from through the loader) its own copy of the
+ * libcrypto static data, we will need to set the callbacks. The easiest way to
+ * detect this is to have a function that returns a pointer to some static data
+ * and let the loading application and loaded ENGINE compare their respective
+ * values. */
+void *ENGINE_get_static_state(void);
+
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
+void ENGINE_setup_bsd_cryptodev(void);
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_ENGINE_strings(void);
+
+/* Error codes for the ENGINE functions. */
+
+/* Function codes. */
+#define ENGINE_F_DYNAMIC_CTRL				 180
+#define ENGINE_F_DYNAMIC_GET_DATA_CTX			 181
+#define ENGINE_F_DYNAMIC_LOAD				 182
+#define ENGINE_F_DYNAMIC_SET_DATA_CTX			 183
+#define ENGINE_F_ENGINE_ADD				 105
+#define ENGINE_F_ENGINE_BY_ID				 106
+#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE		 170
+#define ENGINE_F_ENGINE_CTRL				 142
+#define ENGINE_F_ENGINE_CTRL_CMD			 178
+#define ENGINE_F_ENGINE_CTRL_CMD_STRING			 171
+#define ENGINE_F_ENGINE_FINISH				 107
+#define ENGINE_F_ENGINE_FREE_UTIL			 108
+#define ENGINE_F_ENGINE_GET_CIPHER			 185
+#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE		 177
+#define ENGINE_F_ENGINE_GET_DIGEST			 186
+#define ENGINE_F_ENGINE_GET_NEXT			 115
+#define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH		 193
+#define ENGINE_F_ENGINE_GET_PKEY_METH			 192
+#define ENGINE_F_ENGINE_GET_PREV			 116
+#define ENGINE_F_ENGINE_INIT				 119
+#define ENGINE_F_ENGINE_LIST_ADD			 120
+#define ENGINE_F_ENGINE_LIST_REMOVE			 121
+#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY		 150
+#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY			 151
+#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT		 194
+#define ENGINE_F_ENGINE_NEW				 122
+#define ENGINE_F_ENGINE_REMOVE				 123
+#define ENGINE_F_ENGINE_SET_DEFAULT_STRING		 189
+#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE		 126
+#define ENGINE_F_ENGINE_SET_ID				 129
+#define ENGINE_F_ENGINE_SET_NAME			 130
+#define ENGINE_F_ENGINE_TABLE_REGISTER			 184
+#define ENGINE_F_ENGINE_UNLOAD_KEY			 152
+#define ENGINE_F_ENGINE_UNLOCKED_FINISH			 191
+#define ENGINE_F_ENGINE_UP_REF				 190
+#define ENGINE_F_INT_CTRL_HELPER			 172
+#define ENGINE_F_INT_ENGINE_CONFIGURE			 188
+#define ENGINE_F_INT_ENGINE_MODULE_INIT			 187
+#define ENGINE_F_LOG_MESSAGE				 141
+
+/* Reason codes. */
+#define ENGINE_R_ALREADY_LOADED				 100
+#define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER		 133
+#define ENGINE_R_CMD_NOT_EXECUTABLE			 134
+#define ENGINE_R_COMMAND_TAKES_INPUT			 135
+#define ENGINE_R_COMMAND_TAKES_NO_INPUT			 136
+#define ENGINE_R_CONFLICTING_ENGINE_ID			 103
+#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED		 119
+#define ENGINE_R_DH_NOT_IMPLEMENTED			 139
+#define ENGINE_R_DSA_NOT_IMPLEMENTED			 140
+#define ENGINE_R_DSO_FAILURE				 104
+#define ENGINE_R_DSO_NOT_FOUND				 132
+#define ENGINE_R_ENGINES_SECTION_ERROR			 148
+#define ENGINE_R_ENGINE_CONFIGURATION_ERROR		 102
+#define ENGINE_R_ENGINE_IS_NOT_IN_LIST			 105
+#define ENGINE_R_ENGINE_SECTION_ERROR			 149
+#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY		 128
+#define ENGINE_R_FAILED_LOADING_PUBLIC_KEY		 129
+#define ENGINE_R_FINISH_FAILED				 106
+#define ENGINE_R_GET_HANDLE_FAILED			 107
+#define ENGINE_R_ID_OR_NAME_MISSING			 108
+#define ENGINE_R_INIT_FAILED				 109
+#define ENGINE_R_INTERNAL_LIST_ERROR			 110
+#define ENGINE_R_INVALID_ARGUMENT			 143
+#define ENGINE_R_INVALID_CMD_NAME			 137
+#define ENGINE_R_INVALID_CMD_NUMBER			 138
+#define ENGINE_R_INVALID_INIT_VALUE			 151
+#define ENGINE_R_INVALID_STRING				 150
+#define ENGINE_R_NOT_INITIALISED			 117
+#define ENGINE_R_NOT_LOADED				 112
+#define ENGINE_R_NO_CONTROL_FUNCTION			 120
+#define ENGINE_R_NO_INDEX				 144
+#define ENGINE_R_NO_LOAD_FUNCTION			 125
+#define ENGINE_R_NO_REFERENCE				 130
+#define ENGINE_R_NO_SUCH_ENGINE				 116
+#define ENGINE_R_NO_UNLOAD_FUNCTION			 126
+#define ENGINE_R_PROVIDE_PARAMETERS			 113
+#define ENGINE_R_RSA_NOT_IMPLEMENTED			 141
+#define ENGINE_R_UNIMPLEMENTED_CIPHER			 146
+#define ENGINE_R_UNIMPLEMENTED_DIGEST			 147
+#define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD	 101
+#define ENGINE_R_VERSION_INCOMPATIBILITY		 145
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/engine/enginetest.c b/openssl/crypto/engine/enginetest.c
new file mode 100644
index 0000000..f4d70e7
--- /dev/null
+++ b/openssl/crypto/engine/enginetest.c
@@ -0,0 +1,283 @@
+/* crypto/engine/enginetest.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/e_os2.h>
+
+#ifdef OPENSSL_NO_ENGINE
+int main(int argc, char *argv[])
+{
+    printf("No ENGINE support\n");
+    return(0);
+}
+#else
+#include <openssl/buffer.h>
+#include <openssl/crypto.h>
+#include <openssl/engine.h>
+#include <openssl/err.h>
+
+static void display_engine_list(void)
+	{
+	ENGINE *h;
+	int loop;
+
+	h = ENGINE_get_first();
+	loop = 0;
+	printf("listing available engine types\n");
+	while(h)
+		{
+		printf("engine %i, id = \"%s\", name = \"%s\"\n",
+			loop++, ENGINE_get_id(h), ENGINE_get_name(h));
+		h = ENGINE_get_next(h);
+		}
+	printf("end of list\n");
+	/* ENGINE_get_first() increases the struct_ref counter, so we 
+           must call ENGINE_free() to decrease it again */
+	ENGINE_free(h);
+	}
+
+int main(int argc, char *argv[])
+	{
+	ENGINE *block[512];
+	char buf[256];
+	const char *id, *name;
+	ENGINE *ptr;
+	int loop;
+	int to_return = 1;
+	ENGINE *new_h1 = NULL;
+	ENGINE *new_h2 = NULL;
+	ENGINE *new_h3 = NULL;
+	ENGINE *new_h4 = NULL;
+
+	/* enable memory leak checking unless explicitly disabled */
+	if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
+		{
+		CRYPTO_malloc_debug_init();
+		CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+		}
+	else
+		{
+		/* OPENSSL_DEBUG_MEMORY=off */
+		CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
+		}
+	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+	ERR_load_crypto_strings();
+
+	memset(block, 0, 512 * sizeof(ENGINE *));
+	if(((new_h1 = ENGINE_new()) == NULL) ||
+			!ENGINE_set_id(new_h1, "test_id0") ||
+			!ENGINE_set_name(new_h1, "First test item") ||
+			((new_h2 = ENGINE_new()) == NULL) ||
+			!ENGINE_set_id(new_h2, "test_id1") ||
+			!ENGINE_set_name(new_h2, "Second test item") ||
+			((new_h3 = ENGINE_new()) == NULL) ||
+			!ENGINE_set_id(new_h3, "test_id2") ||
+			!ENGINE_set_name(new_h3, "Third test item") ||
+			((new_h4 = ENGINE_new()) == NULL) ||
+			!ENGINE_set_id(new_h4, "test_id3") ||
+			!ENGINE_set_name(new_h4, "Fourth test item"))
+		{
+		printf("Couldn't set up test ENGINE structures\n");
+		goto end;
+		}
+	printf("\nenginetest beginning\n\n");
+	display_engine_list();
+	if(!ENGINE_add(new_h1))
+		{
+		printf("Add failed!\n");
+		goto end;
+		}
+	display_engine_list();
+	ptr = ENGINE_get_first();
+	if(!ENGINE_remove(ptr))
+		{
+		printf("Remove failed!\n");
+		goto end;
+		}
+	if (ptr)
+		ENGINE_free(ptr);
+	display_engine_list();
+	if(!ENGINE_add(new_h3) || !ENGINE_add(new_h2))
+		{
+		printf("Add failed!\n");
+		goto end;
+		}
+	display_engine_list();
+	if(!ENGINE_remove(new_h2))
+		{
+		printf("Remove failed!\n");
+		goto end;
+		}
+	display_engine_list();
+	if(!ENGINE_add(new_h4))
+		{
+		printf("Add failed!\n");
+		goto end;
+		}
+	display_engine_list();
+	if(ENGINE_add(new_h3))
+		{
+		printf("Add *should* have failed but didn't!\n");
+		goto end;
+		}
+	else
+		printf("Add that should fail did.\n");
+	ERR_clear_error();
+	if(ENGINE_remove(new_h2))
+		{
+		printf("Remove *should* have failed but didn't!\n");
+		goto end;
+		}
+	else
+		printf("Remove that should fail did.\n");
+	ERR_clear_error();
+	if(!ENGINE_remove(new_h3))
+		{
+		printf("Remove failed!\n");
+		goto end;
+		}
+	display_engine_list();
+	if(!ENGINE_remove(new_h4))
+		{
+		printf("Remove failed!\n");
+		goto end;
+		}
+	display_engine_list();
+	/* Depending on whether there's any hardware support compiled
+	 * in, this remove may be destined to fail. */
+	ptr = ENGINE_get_first();
+	if(ptr)
+		if(!ENGINE_remove(ptr))
+			printf("Remove failed!i - probably no hardware "
+				"support present.\n");
+	if (ptr)
+		ENGINE_free(ptr);
+	display_engine_list();
+	if(!ENGINE_add(new_h1) || !ENGINE_remove(new_h1))
+		{
+		printf("Couldn't add and remove to an empty list!\n");
+		goto end;
+		}
+	else
+		printf("Successfully added and removed to an empty list!\n");
+	printf("About to beef up the engine-type list\n");
+	for(loop = 0; loop < 512; loop++)
+		{
+		sprintf(buf, "id%i", loop);
+		id = BUF_strdup(buf);
+		sprintf(buf, "Fake engine type %i", loop);
+		name = BUF_strdup(buf);
+		if(((block[loop] = ENGINE_new()) == NULL) ||
+				!ENGINE_set_id(block[loop], id) ||
+				!ENGINE_set_name(block[loop], name))
+			{
+			printf("Couldn't create block of ENGINE structures.\n"
+				"I'll probably also core-dump now, damn.\n");
+			goto end;
+			}
+		}
+	for(loop = 0; loop < 512; loop++)
+		{
+		if(!ENGINE_add(block[loop]))
+			{
+			printf("\nAdding stopped at %i, (%s,%s)\n",
+				loop, ENGINE_get_id(block[loop]),
+				ENGINE_get_name(block[loop]));
+			goto cleanup_loop;
+			}
+		else
+			printf("."); fflush(stdout);
+		}
+cleanup_loop:
+	printf("\nAbout to empty the engine-type list\n");
+	while((ptr = ENGINE_get_first()) != NULL)
+		{
+		if(!ENGINE_remove(ptr))
+			{
+			printf("\nRemove failed!\n");
+			goto end;
+			}
+		ENGINE_free(ptr);
+		printf("."); fflush(stdout);
+		}
+	for(loop = 0; loop < 512; loop++)
+		{
+		OPENSSL_free((void *)ENGINE_get_id(block[loop]));
+		OPENSSL_free((void *)ENGINE_get_name(block[loop]));
+		}
+	printf("\nTests completed happily\n");
+	to_return = 0;
+end:
+	if(to_return)
+		ERR_print_errors_fp(stderr);
+	if(new_h1) ENGINE_free(new_h1);
+	if(new_h2) ENGINE_free(new_h2);
+	if(new_h3) ENGINE_free(new_h3);
+	if(new_h4) ENGINE_free(new_h4);
+	for(loop = 0; loop < 512; loop++)
+		if(block[loop])
+			ENGINE_free(block[loop]);
+	ENGINE_cleanup();
+	CRYPTO_cleanup_all_ex_data();
+	ERR_free_strings();
+	ERR_remove_thread_state(NULL);
+	CRYPTO_mem_leaks_fp(stderr);
+	return to_return;
+	}
+#endif
diff --git a/openssl/crypto/engine/tb_asnmth.c b/openssl/crypto/engine/tb_asnmth.c
new file mode 100644
index 0000000..7509033
--- /dev/null
+++ b/openssl/crypto/engine/tb_asnmth.c
@@ -0,0 +1,246 @@
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+#include "asn1_locl.h"
+#include <openssl/evp.h>
+
+/* If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the
+ * function that is used by EVP to hook in pkey_asn1_meth code and cache
+ * defaults (etc), will display brief debugging summaries to stderr with the
+ * 'nid'. */
+/* #define ENGINE_PKEY_ASN1_METH_DEBUG */
+
+static ENGINE_TABLE *pkey_asn1_meth_table = NULL;
+
+void ENGINE_unregister_pkey_asn1_meths(ENGINE *e)
+	{
+	engine_table_unregister(&pkey_asn1_meth_table, e);
+	}
+
+static void engine_unregister_all_pkey_asn1_meths(void)
+	{
+	engine_table_cleanup(&pkey_asn1_meth_table);
+	}
+
+int ENGINE_register_pkey_asn1_meths(ENGINE *e)
+	{
+	if(e->pkey_asn1_meths)
+		{
+		const int *nids;
+		int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
+		if(num_nids > 0)
+			return engine_table_register(&pkey_asn1_meth_table,
+				engine_unregister_all_pkey_asn1_meths, e, nids,
+					num_nids, 0);
+		}
+	return 1;
+	}
+
+void ENGINE_register_all_pkey_asn1_meths(void)
+	{
+	ENGINE *e;
+
+	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
+		ENGINE_register_pkey_asn1_meths(e);
+	}
+
+int ENGINE_set_default_pkey_asn1_meths(ENGINE *e)
+	{
+	if(e->pkey_asn1_meths)
+		{
+		const int *nids;
+		int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
+		if(num_nids > 0)
+			return engine_table_register(&pkey_asn1_meth_table,
+				engine_unregister_all_pkey_asn1_meths, e, nids,
+					num_nids, 1);
+		}
+	return 1;
+	}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references) for a given pkey_asn1_meth 'nid' */
+ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid)
+	{
+	return engine_table_select(&pkey_asn1_meth_table, nid);
+	}
+
+/* Obtains a pkey_asn1_meth implementation from an ENGINE functional reference */
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid)
+	{
+	EVP_PKEY_ASN1_METHOD *ret;
+	ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e);
+	if(!fn || !fn(e, &ret, NULL, nid))
+		{
+		ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH,
+				ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
+		return NULL;
+		}
+	return ret;
+	}
+
+/* Gets the pkey_asn1_meth callback from an ENGINE structure */
+ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e)
+	{
+	return e->pkey_asn1_meths;
+	}
+
+/* Sets the pkey_asn1_meth callback in an ENGINE structure */
+int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f)
+	{
+	e->pkey_asn1_meths = f;
+	return 1;
+	}
+
+/* Internal function to free up EVP_PKEY_ASN1_METHOD structures before an
+ * ENGINE is destroyed
+ */
+
+void engine_pkey_asn1_meths_free(ENGINE *e)
+	{
+	int i;
+	EVP_PKEY_ASN1_METHOD *pkm;
+	if (e->pkey_asn1_meths)
+		{
+		const int *pknids;
+		int npknids;
+		npknids = e->pkey_asn1_meths(e, NULL, &pknids, 0);
+		for (i = 0; i < npknids; i++)
+			{
+			if (e->pkey_asn1_meths(e, &pkm, NULL, pknids[i]))
+				{
+				EVP_PKEY_asn1_free(pkm);
+				}
+			}
+		}
+	}
+
+/* Find a method based on a string. This does a linear search through
+ * all implemented algorithms. This is OK in practice because only
+ * a small number of algorithms are likely to be implemented in an engine
+ * and it is not used for speed critical operations.
+ */
+
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
+					const char *str, int len)
+	{
+	int i, nidcount;
+	const int *nids;
+	EVP_PKEY_ASN1_METHOD *ameth;
+	if (!e->pkey_asn1_meths)
+		return NULL;
+	if (len == -1)
+		len = strlen(str);
+	nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0);
+	for (i = 0; i < nidcount; i++)
+		{
+		e->pkey_asn1_meths(e, &ameth, NULL, nids[i]);
+		if (((int)strlen(ameth->pem_str) == len) && 
+					!strncasecmp(ameth->pem_str, str, len))
+			return ameth;
+		}
+	return NULL;
+	}
+
+typedef struct 
+	{
+	ENGINE *e;
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	const char *str;
+	int len;
+	} ENGINE_FIND_STR;
+
+static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg)
+	{
+	ENGINE_FIND_STR *lk = arg;
+	int i;
+	if (lk->ameth)
+		return;
+	for (i = 0; i < sk_ENGINE_num(sk); i++)
+		{
+		ENGINE *e = sk_ENGINE_value(sk, i);
+		EVP_PKEY_ASN1_METHOD *ameth;
+		e->pkey_asn1_meths(e, &ameth, NULL, nid);
+		if (((int)strlen(ameth->pem_str) == lk->len) && 
+				!strncasecmp(ameth->pem_str, lk->str, lk->len))
+			{
+			lk->e = e;
+			lk->ameth = ameth;
+			return;
+			}
+		}
+	}
+
+const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
+					const char *str, int len)
+	{
+	ENGINE_FIND_STR fstr;
+	fstr.e = NULL;
+	fstr.ameth = NULL;
+	fstr.str = str;
+	fstr.len = len;
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr);
+	/* If found obtain a structural reference to engine */
+	if (fstr.e)
+		{
+		fstr.e->struct_ref++;
+		engine_ref_debug(fstr.e, 0, 1)
+		}
+	*pe = fstr.e;
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	return fstr.ameth;
+	}
diff --git a/openssl/crypto/engine/tb_cipher.c b/openssl/crypto/engine/tb_cipher.c
new file mode 100644
index 0000000..177fc1f
--- /dev/null
+++ b/openssl/crypto/engine/tb_cipher.c
@@ -0,0 +1,143 @@
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_cipher_engine(), the function that
+ * is used by EVP to hook in cipher code and cache defaults (etc), will display
+ * brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_CIPHER_DEBUG */
+
+static ENGINE_TABLE *cipher_table = NULL;
+
+void ENGINE_unregister_ciphers(ENGINE *e)
+	{
+	engine_table_unregister(&cipher_table, e);
+	}
+
+static void engine_unregister_all_ciphers(void)
+	{
+	engine_table_cleanup(&cipher_table);
+	}
+
+int ENGINE_register_ciphers(ENGINE *e)
+	{
+	if(e->ciphers)
+		{
+		const int *nids;
+		int num_nids = e->ciphers(e, NULL, &nids, 0);
+		if(num_nids > 0)
+			return engine_table_register(&cipher_table,
+					engine_unregister_all_ciphers, e, nids,
+					num_nids, 0);
+		}
+	return 1;
+	}
+
+void ENGINE_register_all_ciphers()
+	{
+	ENGINE *e;
+
+	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
+		ENGINE_register_ciphers(e);
+	}
+
+int ENGINE_set_default_ciphers(ENGINE *e)
+	{
+	if(e->ciphers)
+		{
+		const int *nids;
+		int num_nids = e->ciphers(e, NULL, &nids, 0);
+		if(num_nids > 0)
+			return engine_table_register(&cipher_table,
+					engine_unregister_all_ciphers, e, nids,
+					num_nids, 1);
+		}
+	return 1;
+	}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references) for a given cipher 'nid' */
+ENGINE *ENGINE_get_cipher_engine(int nid)
+	{
+	return engine_table_select(&cipher_table, nid);
+	}
+
+/* Obtains a cipher implementation from an ENGINE functional reference */
+const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid)
+	{
+	const EVP_CIPHER *ret;
+	ENGINE_CIPHERS_PTR fn = ENGINE_get_ciphers(e);
+	if(!fn || !fn(e, &ret, NULL, nid))
+		{
+		ENGINEerr(ENGINE_F_ENGINE_GET_CIPHER,
+				ENGINE_R_UNIMPLEMENTED_CIPHER);
+		return NULL;
+		}
+	return ret;
+	}
+
+/* Gets the cipher callback from an ENGINE structure */
+ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e)
+	{
+	return e->ciphers;
+	}
+
+/* Sets the cipher callback in an ENGINE structure */
+int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f)
+	{
+	e->ciphers = f;
+	return 1;
+	}
diff --git a/openssl/crypto/engine/tb_dh.c b/openssl/crypto/engine/tb_dh.c
new file mode 100644
index 0000000..6e9d428
--- /dev/null
+++ b/openssl/crypto/engine/tb_dh.c
@@ -0,0 +1,118 @@
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_default_DH(), the function that is
+ * used by DH to hook in implementation code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_DH_DEBUG */
+
+static ENGINE_TABLE *dh_table = NULL;
+static const int dummy_nid = 1;
+
+void ENGINE_unregister_DH(ENGINE *e)
+	{
+	engine_table_unregister(&dh_table, e);
+	}
+
+static void engine_unregister_all_DH(void)
+	{
+	engine_table_cleanup(&dh_table);
+	}
+
+int ENGINE_register_DH(ENGINE *e)
+	{
+	if(e->dh_meth)
+		return engine_table_register(&dh_table,
+				engine_unregister_all_DH, e, &dummy_nid, 1, 0);
+	return 1;
+	}
+
+void ENGINE_register_all_DH()
+	{
+	ENGINE *e;
+
+	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
+		ENGINE_register_DH(e);
+	}
+
+int ENGINE_set_default_DH(ENGINE *e)
+	{
+	if(e->dh_meth)
+		return engine_table_register(&dh_table,
+				engine_unregister_all_DH, e, &dummy_nid, 1, 1);
+	return 1;
+	}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references). */
+ENGINE *ENGINE_get_default_DH(void)
+	{
+	return engine_table_select(&dh_table, dummy_nid);
+	}
+
+/* Obtains an DH implementation from an ENGINE functional reference */
+const DH_METHOD *ENGINE_get_DH(const ENGINE *e)
+	{
+	return e->dh_meth;
+	}
+
+/* Sets an DH implementation in an ENGINE structure */
+int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth)
+	{
+	e->dh_meth = dh_meth;
+	return 1;
+	}
diff --git a/openssl/crypto/engine/tb_digest.c b/openssl/crypto/engine/tb_digest.c
new file mode 100644
index 0000000..d3f4bb2
--- /dev/null
+++ b/openssl/crypto/engine/tb_digest.c
@@ -0,0 +1,143 @@
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_digest_engine(), the function that
+ * is used by EVP to hook in digest code and cache defaults (etc), will display
+ * brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_DIGEST_DEBUG */
+
+static ENGINE_TABLE *digest_table = NULL;
+
+void ENGINE_unregister_digests(ENGINE *e)
+	{
+	engine_table_unregister(&digest_table, e);
+	}
+
+static void engine_unregister_all_digests(void)
+	{
+	engine_table_cleanup(&digest_table);
+	}
+
+int ENGINE_register_digests(ENGINE *e)
+	{
+	if(e->digests)
+		{
+		const int *nids;
+		int num_nids = e->digests(e, NULL, &nids, 0);
+		if(num_nids > 0)
+			return engine_table_register(&digest_table,
+					engine_unregister_all_digests, e, nids,
+					num_nids, 0);
+		}
+	return 1;
+	}
+
+void ENGINE_register_all_digests()
+	{
+	ENGINE *e;
+
+	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
+		ENGINE_register_digests(e);
+	}
+
+int ENGINE_set_default_digests(ENGINE *e)
+	{
+	if(e->digests)
+		{
+		const int *nids;
+		int num_nids = e->digests(e, NULL, &nids, 0);
+		if(num_nids > 0)
+			return engine_table_register(&digest_table,
+					engine_unregister_all_digests, e, nids,
+					num_nids, 1);
+		}
+	return 1;
+	}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references) for a given digest 'nid' */
+ENGINE *ENGINE_get_digest_engine(int nid)
+	{
+	return engine_table_select(&digest_table, nid);
+	}
+
+/* Obtains a digest implementation from an ENGINE functional reference */
+const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid)
+	{
+	const EVP_MD *ret;
+	ENGINE_DIGESTS_PTR fn = ENGINE_get_digests(e);
+	if(!fn || !fn(e, &ret, NULL, nid))
+		{
+		ENGINEerr(ENGINE_F_ENGINE_GET_DIGEST,
+				ENGINE_R_UNIMPLEMENTED_DIGEST);
+		return NULL;
+		}
+	return ret;
+	}
+
+/* Gets the digest callback from an ENGINE structure */
+ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e)
+	{
+	return e->digests;
+	}
+
+/* Sets the digest callback in an ENGINE structure */
+int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f)
+	{
+	e->digests = f;
+	return 1;
+	}
diff --git a/openssl/crypto/engine/tb_dsa.c b/openssl/crypto/engine/tb_dsa.c
new file mode 100644
index 0000000..e4674f5
--- /dev/null
+++ b/openssl/crypto/engine/tb_dsa.c
@@ -0,0 +1,118 @@
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_default_DSA(), the function that is
+ * used by DSA to hook in implementation code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_DSA_DEBUG */
+
+static ENGINE_TABLE *dsa_table = NULL;
+static const int dummy_nid = 1;
+
+void ENGINE_unregister_DSA(ENGINE *e)
+	{
+	engine_table_unregister(&dsa_table, e);
+	}
+
+static void engine_unregister_all_DSA(void)
+	{
+	engine_table_cleanup(&dsa_table);
+	}
+
+int ENGINE_register_DSA(ENGINE *e)
+	{
+	if(e->dsa_meth)
+		return engine_table_register(&dsa_table,
+				engine_unregister_all_DSA, e, &dummy_nid, 1, 0);
+	return 1;
+	}
+
+void ENGINE_register_all_DSA()
+	{
+	ENGINE *e;
+
+	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
+		ENGINE_register_DSA(e);
+	}
+
+int ENGINE_set_default_DSA(ENGINE *e)
+	{
+	if(e->dsa_meth)
+		return engine_table_register(&dsa_table,
+				engine_unregister_all_DSA, e, &dummy_nid, 1, 1);
+	return 1;
+	}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references). */
+ENGINE *ENGINE_get_default_DSA(void)
+	{
+	return engine_table_select(&dsa_table, dummy_nid);
+	}
+
+/* Obtains an DSA implementation from an ENGINE functional reference */
+const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e)
+	{
+	return e->dsa_meth;
+	}
+
+/* Sets an DSA implementation in an ENGINE structure */
+int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth)
+	{
+	e->dsa_meth = dsa_meth;
+	return 1;
+	}
diff --git a/openssl/crypto/engine/tb_ecdh.c b/openssl/crypto/engine/tb_ecdh.c
new file mode 100644
index 0000000..c8ec781
--- /dev/null
+++ b/openssl/crypto/engine/tb_ecdh.c
@@ -0,0 +1,133 @@
+/* crypto/engine/tb_ecdh.c */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The ECDH engine software is originally written by Nils Gura and
+ * Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_default_ECDH(), the function that is
+ * used by ECDH to hook in implementation code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_ECDH_DEBUG */
+
+static ENGINE_TABLE *ecdh_table = NULL;
+static const int dummy_nid = 1;
+
+void ENGINE_unregister_ECDH(ENGINE *e)
+	{
+	engine_table_unregister(&ecdh_table, e);
+	}
+
+static void engine_unregister_all_ECDH(void)
+	{
+	engine_table_cleanup(&ecdh_table);
+	}
+
+int ENGINE_register_ECDH(ENGINE *e)
+	{
+	if(e->ecdh_meth)
+		return engine_table_register(&ecdh_table,
+				engine_unregister_all_ECDH, e, &dummy_nid, 1, 0);
+	return 1;
+	}
+
+void ENGINE_register_all_ECDH()
+	{
+	ENGINE *e;
+
+	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
+		ENGINE_register_ECDH(e);
+	}
+
+int ENGINE_set_default_ECDH(ENGINE *e)
+	{
+	if(e->ecdh_meth)
+		return engine_table_register(&ecdh_table,
+				engine_unregister_all_ECDH, e, &dummy_nid, 1, 1);
+	return 1;
+	}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references). */
+ENGINE *ENGINE_get_default_ECDH(void)
+	{
+	return engine_table_select(&ecdh_table, dummy_nid);
+	}
+
+/* Obtains an ECDH implementation from an ENGINE functional reference */
+const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e)
+	{
+	return e->ecdh_meth;
+	}
+
+/* Sets an ECDH implementation in an ENGINE structure */
+int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth)
+	{
+	e->ecdh_meth = ecdh_meth;
+	return 1;
+	}
diff --git a/openssl/crypto/engine/tb_ecdsa.c b/openssl/crypto/engine/tb_ecdsa.c
new file mode 100644
index 0000000..005ecb6
--- /dev/null
+++ b/openssl/crypto/engine/tb_ecdsa.c
@@ -0,0 +1,118 @@
+/* ====================================================================
+ * Copyright (c) 2000-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_default_ECDSA(), the function that is
+ * used by ECDSA to hook in implementation code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_ECDSA_DEBUG */
+
+static ENGINE_TABLE *ecdsa_table = NULL;
+static const int dummy_nid = 1;
+
+void ENGINE_unregister_ECDSA(ENGINE *e)
+	{
+	engine_table_unregister(&ecdsa_table, e);
+	}
+
+static void engine_unregister_all_ECDSA(void)
+	{
+	engine_table_cleanup(&ecdsa_table);
+	}
+
+int ENGINE_register_ECDSA(ENGINE *e)
+	{
+	if(e->ecdsa_meth)
+		return engine_table_register(&ecdsa_table,
+				engine_unregister_all_ECDSA, e, &dummy_nid, 1, 0);
+	return 1;
+	}
+
+void ENGINE_register_all_ECDSA()
+	{
+	ENGINE *e;
+
+	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
+		ENGINE_register_ECDSA(e);
+	}
+
+int ENGINE_set_default_ECDSA(ENGINE *e)
+	{
+	if(e->ecdsa_meth)
+		return engine_table_register(&ecdsa_table,
+				engine_unregister_all_ECDSA, e, &dummy_nid, 1, 1);
+	return 1;
+	}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references). */
+ENGINE *ENGINE_get_default_ECDSA(void)
+	{
+	return engine_table_select(&ecdsa_table, dummy_nid);
+	}
+
+/* Obtains an ECDSA implementation from an ENGINE functional reference */
+const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e)
+	{
+	return e->ecdsa_meth;
+	}
+
+/* Sets an ECDSA implementation in an ENGINE structure */
+int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth)
+	{
+	e->ecdsa_meth = ecdsa_meth;
+	return 1;
+	}
diff --git a/openssl/crypto/engine/tb_pkmeth.c b/openssl/crypto/engine/tb_pkmeth.c
new file mode 100644
index 0000000..1cdb967
--- /dev/null
+++ b/openssl/crypto/engine/tb_pkmeth.c
@@ -0,0 +1,167 @@
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+#include <openssl/evp.h>
+
+/* If this symbol is defined then ENGINE_get_pkey_meth_engine(), the function
+ * that is used by EVP to hook in pkey_meth code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_PKEY_METH_DEBUG */
+
+static ENGINE_TABLE *pkey_meth_table = NULL;
+
+void ENGINE_unregister_pkey_meths(ENGINE *e)
+	{
+	engine_table_unregister(&pkey_meth_table, e);
+	}
+
+static void engine_unregister_all_pkey_meths(void)
+	{
+	engine_table_cleanup(&pkey_meth_table);
+	}
+
+int ENGINE_register_pkey_meths(ENGINE *e)
+	{
+	if(e->pkey_meths)
+		{
+		const int *nids;
+		int num_nids = e->pkey_meths(e, NULL, &nids, 0);
+		if(num_nids > 0)
+			return engine_table_register(&pkey_meth_table,
+				engine_unregister_all_pkey_meths, e, nids,
+					num_nids, 0);
+		}
+	return 1;
+	}
+
+void ENGINE_register_all_pkey_meths()
+	{
+	ENGINE *e;
+
+	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
+		ENGINE_register_pkey_meths(e);
+	}
+
+int ENGINE_set_default_pkey_meths(ENGINE *e)
+	{
+	if(e->pkey_meths)
+		{
+		const int *nids;
+		int num_nids = e->pkey_meths(e, NULL, &nids, 0);
+		if(num_nids > 0)
+			return engine_table_register(&pkey_meth_table,
+				engine_unregister_all_pkey_meths, e, nids,
+					num_nids, 1);
+		}
+	return 1;
+	}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references) for a given pkey_meth 'nid' */
+ENGINE *ENGINE_get_pkey_meth_engine(int nid)
+	{
+	return engine_table_select(&pkey_meth_table, nid);
+	}
+
+/* Obtains a pkey_meth implementation from an ENGINE functional reference */
+const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid)
+	{
+	EVP_PKEY_METHOD *ret;
+	ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e);
+	if(!fn || !fn(e, &ret, NULL, nid))
+		{
+		ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH,
+				ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
+		return NULL;
+		}
+	return ret;
+	}
+
+/* Gets the pkey_meth callback from an ENGINE structure */
+ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e)
+	{
+	return e->pkey_meths;
+	}
+
+/* Sets the pkey_meth callback in an ENGINE structure */
+int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f)
+	{
+	e->pkey_meths = f;
+	return 1;
+	}
+
+/* Internal function to free up EVP_PKEY_METHOD structures before an
+ * ENGINE is destroyed
+ */
+
+void engine_pkey_meths_free(ENGINE *e)
+	{
+	int i;
+	EVP_PKEY_METHOD *pkm;
+	if (e->pkey_meths)
+		{
+		const int *pknids;
+		int npknids;
+		npknids = e->pkey_meths(e, NULL, &pknids, 0);
+		for (i = 0; i < npknids; i++)
+			{
+			if (e->pkey_meths(e, &pkm, NULL, pknids[i]))
+				{
+				EVP_PKEY_meth_free(pkm);
+				}
+			}
+		}
+	}
diff --git a/openssl/crypto/engine/tb_rand.c b/openssl/crypto/engine/tb_rand.c
new file mode 100644
index 0000000..f36f67c
--- /dev/null
+++ b/openssl/crypto/engine/tb_rand.c
@@ -0,0 +1,118 @@
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_default_RAND(), the function that is
+ * used by RAND to hook in implementation code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_RAND_DEBUG */
+
+static ENGINE_TABLE *rand_table = NULL;
+static const int dummy_nid = 1;
+
+void ENGINE_unregister_RAND(ENGINE *e)
+	{
+	engine_table_unregister(&rand_table, e);
+	}
+
+static void engine_unregister_all_RAND(void)
+	{
+	engine_table_cleanup(&rand_table);
+	}
+
+int ENGINE_register_RAND(ENGINE *e)
+	{
+	if(e->rand_meth)
+		return engine_table_register(&rand_table,
+				engine_unregister_all_RAND, e, &dummy_nid, 1, 0);
+	return 1;
+	}
+
+void ENGINE_register_all_RAND()
+	{
+	ENGINE *e;
+
+	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
+		ENGINE_register_RAND(e);
+	}
+
+int ENGINE_set_default_RAND(ENGINE *e)
+	{
+	if(e->rand_meth)
+		return engine_table_register(&rand_table,
+				engine_unregister_all_RAND, e, &dummy_nid, 1, 1);
+	return 1;
+	}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references). */
+ENGINE *ENGINE_get_default_RAND(void)
+	{
+	return engine_table_select(&rand_table, dummy_nid);
+	}
+
+/* Obtains an RAND implementation from an ENGINE functional reference */
+const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e)
+	{
+	return e->rand_meth;
+	}
+
+/* Sets an RAND implementation in an ENGINE structure */
+int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth)
+	{
+	e->rand_meth = rand_meth;
+	return 1;
+	}
diff --git a/openssl/crypto/engine/tb_rsa.c b/openssl/crypto/engine/tb_rsa.c
new file mode 100644
index 0000000..fbc707f
--- /dev/null
+++ b/openssl/crypto/engine/tb_rsa.c
@@ -0,0 +1,118 @@
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_default_RSA(), the function that is
+ * used by RSA to hook in implementation code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_RSA_DEBUG */
+
+static ENGINE_TABLE *rsa_table = NULL;
+static const int dummy_nid = 1;
+
+void ENGINE_unregister_RSA(ENGINE *e)
+	{
+	engine_table_unregister(&rsa_table, e);
+	}
+
+static void engine_unregister_all_RSA(void)
+	{
+	engine_table_cleanup(&rsa_table);
+	}
+
+int ENGINE_register_RSA(ENGINE *e)
+	{
+	if(e->rsa_meth)
+		return engine_table_register(&rsa_table,
+				engine_unregister_all_RSA, e, &dummy_nid, 1, 0);
+	return 1;
+	}
+
+void ENGINE_register_all_RSA()
+	{
+	ENGINE *e;
+
+	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
+		ENGINE_register_RSA(e);
+	}
+
+int ENGINE_set_default_RSA(ENGINE *e)
+	{
+	if(e->rsa_meth)
+		return engine_table_register(&rsa_table,
+				engine_unregister_all_RSA, e, &dummy_nid, 1, 1);
+	return 1;
+	}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references). */
+ENGINE *ENGINE_get_default_RSA(void)
+	{
+	return engine_table_select(&rsa_table, dummy_nid);
+	}
+
+/* Obtains an RSA implementation from an ENGINE functional reference */
+const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e)
+	{
+	return e->rsa_meth;
+	}
+
+/* Sets an RSA implementation in an ENGINE structure */
+int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth)
+	{
+	e->rsa_meth = rsa_meth;
+	return 1;
+	}
diff --git a/openssl/crypto/engine/tb_store.c b/openssl/crypto/engine/tb_store.c
new file mode 100644
index 0000000..8cc435c
--- /dev/null
+++ b/openssl/crypto/engine/tb_store.c
@@ -0,0 +1,123 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_default_STORE(), the function that is
+ * used by STORE to hook in implementation code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_STORE_DEBUG */
+
+static ENGINE_TABLE *store_table = NULL;
+static const int dummy_nid = 1;
+
+void ENGINE_unregister_STORE(ENGINE *e)
+	{
+	engine_table_unregister(&store_table, e);
+	}
+
+static void engine_unregister_all_STORE(void)
+	{
+	engine_table_cleanup(&store_table);
+	}
+
+int ENGINE_register_STORE(ENGINE *e)
+	{
+	if(e->store_meth)
+		return engine_table_register(&store_table,
+				engine_unregister_all_STORE, e, &dummy_nid, 1, 0);
+	return 1;
+	}
+
+void ENGINE_register_all_STORE()
+	{
+	ENGINE *e;
+
+	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
+		ENGINE_register_STORE(e);
+	}
+
+/* The following two functions are removed because they're useless. */
+#if 0
+int ENGINE_set_default_STORE(ENGINE *e)
+	{
+	if(e->store_meth)
+		return engine_table_register(&store_table,
+				engine_unregister_all_STORE, e, &dummy_nid, 1, 1);
+	return 1;
+	}
+#endif
+
+#if 0
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references). */
+ENGINE *ENGINE_get_default_STORE(void)
+	{
+	return engine_table_select(&store_table, dummy_nid);
+	}
+#endif
+
+/* Obtains an STORE implementation from an ENGINE functional reference */
+const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e)
+	{
+	return e->store_meth;
+	}
+
+/* Sets an STORE implementation in an ENGINE structure */
+int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth)
+	{
+	e->store_meth = store_meth;
+	return 1;
+	}
diff --git a/openssl/crypto/err/Makefile b/openssl/crypto/err/Makefile
new file mode 100644
index 0000000..862b23b
--- /dev/null
+++ b/openssl/crypto/err/Makefile
@@ -0,0 +1,110 @@
+#
+# OpenSSL/crypto/err/Makefile
+#
+
+DIR=	err
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=err.c err_all.c err_prn.c
+LIBOBJ=err.o err_all.o err_prn.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= err.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+err.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/buffer.h
+err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+err.o: ../cryptlib.h err.c
+err_all.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+err_all.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+err_all.o: ../../include/openssl/cms.h ../../include/openssl/comp.h
+err_all.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+err_all.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+err_all.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+err_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+err_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+err_all.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+err_all.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+err_all.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
+err_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+err_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem2.h
+err_all.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+err_all.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+err_all.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+err_all.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+err_all.o: ../../include/openssl/ts.h ../../include/openssl/ui.h
+err_all.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+err_all.o: ../../include/openssl/x509v3.h err_all.c
+err_prn.o: ../../e_os.h ../../include/openssl/bio.h
+err_prn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+err_prn.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+err_prn.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+err_prn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+err_prn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+err_prn.o: ../../include/openssl/symhacks.h ../cryptlib.h err_prn.c
diff --git a/openssl/crypto/err/err.c b/openssl/crypto/err/err.c
new file mode 100644
index 0000000..69713a6
--- /dev/null
+++ b/openssl/crypto/err/err.c
@@ -0,0 +1,1135 @@
+/* crypto/err/err.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+DECLARE_LHASH_OF(ERR_STRING_DATA);
+DECLARE_LHASH_OF(ERR_STATE);
+
+static void err_load_strings(int lib, ERR_STRING_DATA *str);
+
+static void ERR_STATE_free(ERR_STATE *s);
+#ifndef OPENSSL_NO_ERR
+static ERR_STRING_DATA ERR_str_libraries[]=
+	{
+{ERR_PACK(ERR_LIB_NONE,0,0)		,"unknown library"},
+{ERR_PACK(ERR_LIB_SYS,0,0)		,"system library"},
+{ERR_PACK(ERR_LIB_BN,0,0)		,"bignum routines"},
+{ERR_PACK(ERR_LIB_RSA,0,0)		,"rsa routines"},
+{ERR_PACK(ERR_LIB_DH,0,0)		,"Diffie-Hellman routines"},
+{ERR_PACK(ERR_LIB_EVP,0,0)		,"digital envelope routines"},
+{ERR_PACK(ERR_LIB_BUF,0,0)		,"memory buffer routines"},
+{ERR_PACK(ERR_LIB_OBJ,0,0)		,"object identifier routines"},
+{ERR_PACK(ERR_LIB_PEM,0,0)		,"PEM routines"},
+{ERR_PACK(ERR_LIB_DSA,0,0)		,"dsa routines"},
+{ERR_PACK(ERR_LIB_X509,0,0)		,"x509 certificate routines"},
+{ERR_PACK(ERR_LIB_ASN1,0,0)		,"asn1 encoding routines"},
+{ERR_PACK(ERR_LIB_CONF,0,0)		,"configuration file routines"},
+{ERR_PACK(ERR_LIB_CRYPTO,0,0)		,"common libcrypto routines"},
+{ERR_PACK(ERR_LIB_EC,0,0)		,"elliptic curve routines"},
+{ERR_PACK(ERR_LIB_SSL,0,0)		,"SSL routines"},
+{ERR_PACK(ERR_LIB_BIO,0,0)		,"BIO routines"},
+{ERR_PACK(ERR_LIB_PKCS7,0,0)		,"PKCS7 routines"},
+{ERR_PACK(ERR_LIB_X509V3,0,0)		,"X509 V3 routines"},
+{ERR_PACK(ERR_LIB_PKCS12,0,0)		,"PKCS12 routines"},
+{ERR_PACK(ERR_LIB_RAND,0,0)		,"random number generator"},
+{ERR_PACK(ERR_LIB_DSO,0,0)		,"DSO support routines"},
+{ERR_PACK(ERR_LIB_TS,0,0)		,"time stamp routines"},
+{ERR_PACK(ERR_LIB_ENGINE,0,0)		,"engine routines"},
+{ERR_PACK(ERR_LIB_OCSP,0,0)		,"OCSP routines"},
+{ERR_PACK(ERR_LIB_FIPS,0,0)		,"FIPS routines"},
+{ERR_PACK(ERR_LIB_CMS,0,0)		,"CMS routines"},
+{ERR_PACK(ERR_LIB_HMAC,0,0)		,"HMAC routines"},
+{0,NULL},
+	};
+
+static ERR_STRING_DATA ERR_str_functs[]=
+	{
+	{ERR_PACK(0,SYS_F_FOPEN,0),     	"fopen"},
+	{ERR_PACK(0,SYS_F_CONNECT,0),		"connect"},
+	{ERR_PACK(0,SYS_F_GETSERVBYNAME,0),	"getservbyname"},
+	{ERR_PACK(0,SYS_F_SOCKET,0),		"socket"}, 
+	{ERR_PACK(0,SYS_F_IOCTLSOCKET,0),	"ioctlsocket"},
+	{ERR_PACK(0,SYS_F_BIND,0),		"bind"},
+	{ERR_PACK(0,SYS_F_LISTEN,0),		"listen"},
+	{ERR_PACK(0,SYS_F_ACCEPT,0),		"accept"},
+#ifdef OPENSSL_SYS_WINDOWS
+	{ERR_PACK(0,SYS_F_WSASTARTUP,0),	"WSAstartup"},
+#endif
+	{ERR_PACK(0,SYS_F_OPENDIR,0),		"opendir"},
+	{ERR_PACK(0,SYS_F_FREAD,0),		"fread"},
+	{0,NULL},
+	};
+
+static ERR_STRING_DATA ERR_str_reasons[]=
+	{
+{ERR_R_SYS_LIB				,"system lib"},
+{ERR_R_BN_LIB				,"BN lib"},
+{ERR_R_RSA_LIB				,"RSA lib"},
+{ERR_R_DH_LIB				,"DH lib"},
+{ERR_R_EVP_LIB				,"EVP lib"},
+{ERR_R_BUF_LIB				,"BUF lib"},
+{ERR_R_OBJ_LIB				,"OBJ lib"},
+{ERR_R_PEM_LIB				,"PEM lib"},
+{ERR_R_DSA_LIB				,"DSA lib"},
+{ERR_R_X509_LIB				,"X509 lib"},
+{ERR_R_ASN1_LIB				,"ASN1 lib"},
+{ERR_R_CONF_LIB				,"CONF lib"},
+{ERR_R_CRYPTO_LIB			,"CRYPTO lib"},
+{ERR_R_EC_LIB				,"EC lib"},
+{ERR_R_SSL_LIB				,"SSL lib"},
+{ERR_R_BIO_LIB				,"BIO lib"},
+{ERR_R_PKCS7_LIB			,"PKCS7 lib"},
+{ERR_R_X509V3_LIB			,"X509V3 lib"},
+{ERR_R_PKCS12_LIB			,"PKCS12 lib"},
+{ERR_R_RAND_LIB				,"RAND lib"},
+{ERR_R_DSO_LIB				,"DSO lib"},
+{ERR_R_ENGINE_LIB			,"ENGINE lib"},
+{ERR_R_OCSP_LIB				,"OCSP lib"},
+{ERR_R_TS_LIB				,"TS lib"},
+
+{ERR_R_NESTED_ASN1_ERROR		,"nested asn1 error"},
+{ERR_R_BAD_ASN1_OBJECT_HEADER		,"bad asn1 object header"},
+{ERR_R_BAD_GET_ASN1_OBJECT_CALL		,"bad get asn1 object call"},
+{ERR_R_EXPECTING_AN_ASN1_SEQUENCE	,"expecting an asn1 sequence"},
+{ERR_R_ASN1_LENGTH_MISMATCH		,"asn1 length mismatch"},
+{ERR_R_MISSING_ASN1_EOS			,"missing asn1 eos"},
+
+{ERR_R_FATAL                            ,"fatal"},
+{ERR_R_MALLOC_FAILURE			,"malloc failure"},
+{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED	,"called a function you should not call"},
+{ERR_R_PASSED_NULL_PARAMETER		,"passed a null parameter"},
+{ERR_R_INTERNAL_ERROR			,"internal error"},
+{ERR_R_DISABLED				,"called a function that was disabled at compile-time"},
+
+{0,NULL},
+	};
+#endif
+
+
+/* Define the predeclared (but externally opaque) "ERR_FNS" type */
+struct st_ERR_FNS
+	{
+	/* Works on the "error_hash" string table */
+	LHASH_OF(ERR_STRING_DATA) *(*cb_err_get)(int create);
+	void (*cb_err_del)(void);
+	ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *);
+	ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *);
+	ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *);
+	/* Works on the "thread_hash" error-state table */
+	LHASH_OF(ERR_STATE) *(*cb_thread_get)(int create);
+	void (*cb_thread_release)(LHASH_OF(ERR_STATE) **hash);
+	ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *);
+	ERR_STATE *(*cb_thread_set_item)(ERR_STATE *);
+	void (*cb_thread_del_item)(const ERR_STATE *);
+	/* Returns the next available error "library" numbers */
+	int (*cb_get_next_lib)(void);
+	};
+
+/* Predeclarations of the "err_defaults" functions */
+static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create);
+static void int_err_del(void);
+static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
+static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *);
+static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *);
+static LHASH_OF(ERR_STATE) *int_thread_get(int create);
+static void int_thread_release(LHASH_OF(ERR_STATE) **hash);
+static ERR_STATE *int_thread_get_item(const ERR_STATE *);
+static ERR_STATE *int_thread_set_item(ERR_STATE *);
+static void int_thread_del_item(const ERR_STATE *);
+static int int_err_get_next_lib(void);
+/* The static ERR_FNS table using these defaults functions */
+static const ERR_FNS err_defaults =
+	{
+	int_err_get,
+	int_err_del,
+	int_err_get_item,
+	int_err_set_item,
+	int_err_del_item,
+	int_thread_get,
+	int_thread_release,
+	int_thread_get_item,
+	int_thread_set_item,
+	int_thread_del_item,
+	int_err_get_next_lib
+	};
+
+/* The replacable table of ERR_FNS functions we use at run-time */
+static const ERR_FNS *err_fns = NULL;
+
+/* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */
+#define ERRFN(a) err_fns->cb_##a
+
+/* The internal state used by "err_defaults" - as such, the setting, reading,
+ * creating, and deleting of this data should only be permitted via the
+ * "err_defaults" functions. This way, a linked module can completely defer all
+ * ERR state operation (together with requisite locking) to the implementations
+ * and state in the loading application. */
+static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL;
+static LHASH_OF(ERR_STATE) *int_thread_hash = NULL;
+static int int_thread_hash_references = 0;
+static int int_err_library_number= ERR_LIB_USER;
+
+/* Internal function that checks whether "err_fns" is set and if not, sets it to
+ * the defaults. */
+static void err_fns_check(void)
+	{
+	if (err_fns) return;
+	
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	if (!err_fns)
+		err_fns = &err_defaults;
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+	}
+
+/* API functions to get or set the underlying ERR functions. */
+
+const ERR_FNS *ERR_get_implementation(void)
+	{
+	err_fns_check();
+	return err_fns;
+	}
+
+int ERR_set_implementation(const ERR_FNS *fns)
+	{
+	int ret = 0;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	/* It's too late if 'err_fns' is non-NULL. BTW: not much point setting
+	 * an error is there?! */
+	if (!err_fns)
+		{
+		err_fns = fns;
+		ret = 1;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+	return ret;
+	}
+
+/* These are the callbacks provided to "lh_new()" when creating the LHASH tables
+ * internal to the "err_defaults" implementation. */
+
+static unsigned long get_error_values(int inc,int top,const char **file,int *line,
+				      const char **data,int *flags);
+
+/* The internal functions used in the "err_defaults" implementation */
+
+static unsigned long err_string_data_hash(const ERR_STRING_DATA *a)
+	{
+	unsigned long ret,l;
+
+	l=a->error;
+	ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
+	return(ret^ret%19*13);
+	}
+static IMPLEMENT_LHASH_HASH_FN(err_string_data, ERR_STRING_DATA)
+
+static int err_string_data_cmp(const ERR_STRING_DATA *a,
+			       const ERR_STRING_DATA *b)
+	{
+	return (int)(a->error - b->error);
+	}
+static IMPLEMENT_LHASH_COMP_FN(err_string_data, ERR_STRING_DATA)
+
+static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create)
+	{
+	LHASH_OF(ERR_STRING_DATA) *ret = NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	if (!int_error_hash && create)
+		{
+		CRYPTO_push_info("int_err_get (err.c)");
+		int_error_hash = lh_ERR_STRING_DATA_new();
+		CRYPTO_pop_info();
+		}
+	if (int_error_hash)
+		ret = int_error_hash;
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	return ret;
+	}
+
+static void int_err_del(void)
+	{
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	if (int_error_hash)
+		{
+		lh_ERR_STRING_DATA_free(int_error_hash);
+		int_error_hash = NULL;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+	}
+
+static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
+	{
+	ERR_STRING_DATA *p;
+	LHASH_OF(ERR_STRING_DATA) *hash;
+
+	err_fns_check();
+	hash = ERRFN(err_get)(0);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STRING_DATA_retrieve(hash, d);
+	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+
+	return p;
+	}
+
+static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d)
+	{
+	ERR_STRING_DATA *p;
+	LHASH_OF(ERR_STRING_DATA) *hash;
+
+	err_fns_check();
+	hash = ERRFN(err_get)(1);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STRING_DATA_insert(hash, d);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	return p;
+	}
+
+static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d)
+	{
+	ERR_STRING_DATA *p;
+	LHASH_OF(ERR_STRING_DATA) *hash;
+
+	err_fns_check();
+	hash = ERRFN(err_get)(0);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STRING_DATA_delete(hash, d);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	return p;
+	}
+
+static unsigned long err_state_hash(const ERR_STATE *a)
+	{
+	return CRYPTO_THREADID_hash(&a->tid) * 13;
+	}
+static IMPLEMENT_LHASH_HASH_FN(err_state, ERR_STATE)
+
+static int err_state_cmp(const ERR_STATE *a, const ERR_STATE *b)
+	{
+	return CRYPTO_THREADID_cmp(&a->tid, &b->tid);
+	}
+static IMPLEMENT_LHASH_COMP_FN(err_state, ERR_STATE)
+
+static LHASH_OF(ERR_STATE) *int_thread_get(int create)
+	{
+	LHASH_OF(ERR_STATE) *ret = NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	if (!int_thread_hash && create)
+		{
+		CRYPTO_push_info("int_thread_get (err.c)");
+		int_thread_hash = lh_ERR_STATE_new();
+		CRYPTO_pop_info();
+		}
+	if (int_thread_hash)
+		{
+		int_thread_hash_references++;
+		ret = int_thread_hash;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+	return ret;
+	}
+
+static void int_thread_release(LHASH_OF(ERR_STATE) **hash)
+	{
+	int i;
+
+	if (hash == NULL || *hash == NULL)
+		return;
+
+	i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR);
+
+#ifdef REF_PRINT
+	fprintf(stderr,"%4d:%s\n",int_thread_hash_references,"ERR");
+#endif
+	if (i > 0) return;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"int_thread_release, bad reference count\n");
+		abort(); /* ok */
+		}
+#endif
+	*hash = NULL;
+	}
+
+static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
+	{
+	ERR_STATE *p;
+	LHASH_OF(ERR_STATE) *hash;
+
+	err_fns_check();
+	hash = ERRFN(thread_get)(0);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STATE_retrieve(hash, d);
+	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+
+	ERRFN(thread_release)(&hash);
+	return p;
+	}
+
+static ERR_STATE *int_thread_set_item(ERR_STATE *d)
+	{
+	ERR_STATE *p;
+	LHASH_OF(ERR_STATE) *hash;
+
+	err_fns_check();
+	hash = ERRFN(thread_get)(1);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STATE_insert(hash, d);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	ERRFN(thread_release)(&hash);
+	return p;
+	}
+
+static void int_thread_del_item(const ERR_STATE *d)
+	{
+	ERR_STATE *p;
+	LHASH_OF(ERR_STATE) *hash;
+
+	err_fns_check();
+	hash = ERRFN(thread_get)(0);
+	if (!hash)
+		return;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STATE_delete(hash, d);
+	/* make sure we don't leak memory */
+	if (int_thread_hash_references == 1
+	    && int_thread_hash && lh_ERR_STATE_num_items(int_thread_hash) == 0)
+		{
+		lh_ERR_STATE_free(int_thread_hash);
+		int_thread_hash = NULL;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	ERRFN(thread_release)(&hash);
+	if (p)
+		ERR_STATE_free(p);
+	}
+
+static int int_err_get_next_lib(void)
+	{
+	int ret;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	ret = int_err_library_number++;
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	return ret;
+	}
+
+
+#ifndef OPENSSL_NO_ERR
+#define NUM_SYS_STR_REASONS 127
+#define LEN_SYS_STR_REASON 32
+
+static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
+/* SYS_str_reasons is filled with copies of strerror() results at
+ * initialization.
+ * 'errno' values up to 127 should cover all usual errors,
+ * others will be displayed numerically by ERR_error_string.
+ * It is crucial that we have something for each reason code
+ * that occurs in ERR_str_reasons, or bogus reason strings
+ * will be returned for SYSerr(), which always gets an errno
+ * value and never one of those 'standard' reason codes. */
+
+static void build_SYS_str_reasons(void)
+	{
+	/* OPENSSL_malloc cannot be used here, use static storage instead */
+	static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
+	int i;
+	static int init = 1;
+
+	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
+	if (!init)
+		{
+		CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+		return;
+		}
+	
+	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	if (!init)
+		{
+		CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+		return;
+		}
+
+	for (i = 1; i <= NUM_SYS_STR_REASONS; i++)
+		{
+		ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
+
+		str->error = (unsigned long)i;
+		if (str->string == NULL)
+			{
+			char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]);
+			char *src = strerror(i);
+			if (src != NULL)
+				{
+				strncpy(*dest, src, sizeof *dest);
+				(*dest)[sizeof *dest - 1] = '\0';
+				str->string = *dest;
+				}
+			}
+		if (str->string == NULL)
+			str->string = "unknown";
+		}
+
+	/* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL},
+	 * as required by ERR_load_strings. */
+
+	init = 0;
+	
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+	}
+#endif
+
+#define err_clear_data(p,i) \
+	do { \
+	if (((p)->err_data[i] != NULL) && \
+		(p)->err_data_flags[i] & ERR_TXT_MALLOCED) \
+		{  \
+		OPENSSL_free((p)->err_data[i]); \
+		(p)->err_data[i]=NULL; \
+		} \
+	(p)->err_data_flags[i]=0; \
+	} while(0)
+
+#define err_clear(p,i) \
+	do { \
+	(p)->err_flags[i]=0; \
+	(p)->err_buffer[i]=0; \
+	err_clear_data(p,i); \
+	(p)->err_file[i]=NULL; \
+	(p)->err_line[i]= -1; \
+	} while(0)
+
+static void ERR_STATE_free(ERR_STATE *s)
+	{
+	int i;
+
+	if (s == NULL)
+	    return;
+
+	for (i=0; i<ERR_NUM_ERRORS; i++)
+		{
+		err_clear_data(s,i);
+		}
+	OPENSSL_free(s);
+	}
+
+void ERR_load_ERR_strings(void)
+	{
+	err_fns_check();
+#ifndef OPENSSL_NO_ERR
+	err_load_strings(0,ERR_str_libraries);
+	err_load_strings(0,ERR_str_reasons);
+	err_load_strings(ERR_LIB_SYS,ERR_str_functs);
+	build_SYS_str_reasons();
+	err_load_strings(ERR_LIB_SYS,SYS_str_reasons);
+#endif
+	}
+
+static void err_load_strings(int lib, ERR_STRING_DATA *str)
+	{
+	while (str->error)
+		{
+		if (lib)
+			str->error|=ERR_PACK(lib,0,0);
+		ERRFN(err_set_item)(str);
+		str++;
+		}
+	}
+
+void ERR_load_strings(int lib, ERR_STRING_DATA *str)
+	{
+	ERR_load_ERR_strings();
+	err_load_strings(lib, str);
+	}
+
+void ERR_unload_strings(int lib, ERR_STRING_DATA *str)
+	{
+	while (str->error)
+		{
+		if (lib)
+			str->error|=ERR_PACK(lib,0,0);
+		ERRFN(err_del_item)(str);
+		str++;
+		}
+	}
+
+void ERR_free_strings(void)
+	{
+	err_fns_check();
+	ERRFN(err_del)();
+	}
+
+/********************************************************/
+
+void ERR_put_error(int lib, int func, int reason, const char *file,
+	     int line)
+	{
+	ERR_STATE *es;
+
+#ifdef _OSD_POSIX
+	/* In the BS2000-OSD POSIX subsystem, the compiler generates
+	 * path names in the form "*POSIX(/etc/passwd)".
+	 * This dirty hack strips them to something sensible.
+	 * @@@ We shouldn't modify a const string, though.
+	 */
+	if (strncmp(file,"*POSIX(", sizeof("*POSIX(")-1) == 0) {
+		char *end;
+
+		/* Skip the "*POSIX(" prefix */
+		file += sizeof("*POSIX(")-1;
+		end = &file[strlen(file)-1];
+		if (*end == ')')
+			*end = '\0';
+		/* Optional: use the basename of the path only. */
+		if ((end = strrchr(file, '/')) != NULL)
+			file = &end[1];
+	}
+#endif
+	es=ERR_get_state();
+
+	es->top=(es->top+1)%ERR_NUM_ERRORS;
+	if (es->top == es->bottom)
+		es->bottom=(es->bottom+1)%ERR_NUM_ERRORS;
+	es->err_flags[es->top]=0;
+	es->err_buffer[es->top]=ERR_PACK(lib,func,reason);
+	es->err_file[es->top]=file;
+	es->err_line[es->top]=line;
+	err_clear_data(es,es->top);
+	}
+
+void ERR_clear_error(void)
+	{
+	int i;
+	ERR_STATE *es;
+
+	es=ERR_get_state();
+
+	for (i=0; i<ERR_NUM_ERRORS; i++)
+		{
+		err_clear(es,i);
+		}
+	es->top=es->bottom=0;
+	}
+
+
+unsigned long ERR_get_error(void)
+	{ return(get_error_values(1,0,NULL,NULL,NULL,NULL)); }
+
+unsigned long ERR_get_error_line(const char **file,
+	     int *line)
+	{ return(get_error_values(1,0,file,line,NULL,NULL)); }
+
+unsigned long ERR_get_error_line_data(const char **file, int *line,
+	     const char **data, int *flags)
+	{ return(get_error_values(1,0,file,line,data,flags)); }
+
+
+unsigned long ERR_peek_error(void)
+	{ return(get_error_values(0,0,NULL,NULL,NULL,NULL)); }
+
+unsigned long ERR_peek_error_line(const char **file, int *line)
+	{ return(get_error_values(0,0,file,line,NULL,NULL)); }
+
+unsigned long ERR_peek_error_line_data(const char **file, int *line,
+	     const char **data, int *flags)
+	{ return(get_error_values(0,0,file,line,data,flags)); }
+
+
+unsigned long ERR_peek_last_error(void)
+	{ return(get_error_values(0,1,NULL,NULL,NULL,NULL)); }
+
+unsigned long ERR_peek_last_error_line(const char **file, int *line)
+	{ return(get_error_values(0,1,file,line,NULL,NULL)); }
+
+unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
+	     const char **data, int *flags)
+	{ return(get_error_values(0,1,file,line,data,flags)); }
+
+
+static unsigned long get_error_values(int inc, int top, const char **file, int *line,
+	     const char **data, int *flags)
+	{	
+	int i=0;
+	ERR_STATE *es;
+	unsigned long ret;
+
+	es=ERR_get_state();
+
+	if (inc && top)
+		{
+		if (file) *file = "";
+		if (line) *line = 0;
+		if (data) *data = "";
+		if (flags) *flags = 0;
+			
+		return ERR_R_INTERNAL_ERROR;
+		}
+
+	if (es->bottom == es->top) return 0;
+	if (top)
+		i=es->top;			 /* last error */
+	else
+		i=(es->bottom+1)%ERR_NUM_ERRORS; /* first error */
+
+	ret=es->err_buffer[i];
+	if (inc)
+		{
+		es->bottom=i;
+		es->err_buffer[i]=0;
+		}
+
+	if ((file != NULL) && (line != NULL))
+		{
+		if (es->err_file[i] == NULL)
+			{
+			*file="NA";
+			if (line != NULL) *line=0;
+			}
+		else
+			{
+			*file=es->err_file[i];
+			if (line != NULL) *line=es->err_line[i];
+			}
+		}
+
+	if (data == NULL)
+		{
+		if (inc)
+			{
+			err_clear_data(es, i);
+			}
+		}
+	else
+		{
+		if (es->err_data[i] == NULL)
+			{
+			*data="";
+			if (flags != NULL) *flags=0;
+			}
+		else
+			{
+			*data=es->err_data[i];
+			if (flags != NULL) *flags=es->err_data_flags[i];
+			}
+		}
+	return ret;
+	}
+
+void ERR_error_string_n(unsigned long e, char *buf, size_t len)
+	{
+	char lsbuf[64], fsbuf[64], rsbuf[64];
+	const char *ls,*fs,*rs;
+	unsigned long l,f,r;
+
+	l=ERR_GET_LIB(e);
+	f=ERR_GET_FUNC(e);
+	r=ERR_GET_REASON(e);
+
+	ls=ERR_lib_error_string(e);
+	fs=ERR_func_error_string(e);
+	rs=ERR_reason_error_string(e);
+
+	if (ls == NULL) 
+		BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
+	if (fs == NULL)
+		BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
+	if (rs == NULL)
+		BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);
+
+	BIO_snprintf(buf, len,"error:%08lX:%s:%s:%s", e, ls?ls:lsbuf, 
+		fs?fs:fsbuf, rs?rs:rsbuf);
+	if (strlen(buf) == len-1)
+		{
+		/* output may be truncated; make sure we always have 5 
+		 * colon-separated fields, i.e. 4 colons ... */
+#define NUM_COLONS 4
+		if (len > NUM_COLONS) /* ... if possible */
+			{
+			int i;
+			char *s = buf;
+			
+			for (i = 0; i < NUM_COLONS; i++)
+				{
+				char *colon = strchr(s, ':');
+				if (colon == NULL || colon > &buf[len-1] - NUM_COLONS + i)
+					{
+					/* set colon no. i at last possible position
+					 * (buf[len-1] is the terminating 0)*/
+					colon = &buf[len-1] - NUM_COLONS + i;
+					*colon = ':';
+					}
+				s = colon + 1;
+				}
+			}
+		}
+	}
+
+/* BAD for multi-threading: uses a local buffer if ret == NULL */
+/* ERR_error_string_n should be used instead for ret != NULL
+ * as ERR_error_string cannot know how large the buffer is */
+char *ERR_error_string(unsigned long e, char *ret)
+	{
+	static char buf[256];
+
+	if (ret == NULL) ret=buf;
+	ERR_error_string_n(e, ret, 256);
+
+	return ret;
+	}
+
+LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void)
+	{
+	err_fns_check();
+	return ERRFN(err_get)(0);
+	}
+
+LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void)
+	{
+	err_fns_check();
+	return ERRFN(thread_get)(0);
+	}
+
+void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash)
+	{
+	err_fns_check();
+	ERRFN(thread_release)(hash);
+	}
+
+const char *ERR_lib_error_string(unsigned long e)
+	{
+	ERR_STRING_DATA d,*p;
+	unsigned long l;
+
+	err_fns_check();
+	l=ERR_GET_LIB(e);
+	d.error=ERR_PACK(l,0,0);
+	p=ERRFN(err_get_item)(&d);
+	return((p == NULL)?NULL:p->string);
+	}
+
+const char *ERR_func_error_string(unsigned long e)
+	{
+	ERR_STRING_DATA d,*p;
+	unsigned long l,f;
+
+	err_fns_check();
+	l=ERR_GET_LIB(e);
+	f=ERR_GET_FUNC(e);
+	d.error=ERR_PACK(l,f,0);
+	p=ERRFN(err_get_item)(&d);
+	return((p == NULL)?NULL:p->string);
+	}
+
+const char *ERR_reason_error_string(unsigned long e)
+	{
+	ERR_STRING_DATA d,*p=NULL;
+	unsigned long l,r;
+
+	err_fns_check();
+	l=ERR_GET_LIB(e);
+	r=ERR_GET_REASON(e);
+	d.error=ERR_PACK(l,0,r);
+	p=ERRFN(err_get_item)(&d);
+	if (!p)
+		{
+		d.error=ERR_PACK(0,0,r);
+		p=ERRFN(err_get_item)(&d);
+		}
+	return((p == NULL)?NULL:p->string);
+	}
+
+void ERR_remove_thread_state(const CRYPTO_THREADID *id)
+	{
+	ERR_STATE tmp;
+
+	if (id)
+		CRYPTO_THREADID_cpy(&tmp.tid, id);
+	else
+		CRYPTO_THREADID_current(&tmp.tid);
+	err_fns_check();
+	/* thread_del_item automatically destroys the LHASH if the number of
+	 * items reaches zero. */
+	ERRFN(thread_del_item)(&tmp);
+	}
+
+#ifndef OPENSSL_NO_DEPRECATED
+void ERR_remove_state(unsigned long pid)
+	{
+	ERR_remove_thread_state(NULL);
+	}
+#endif
+
+ERR_STATE *ERR_get_state(void)
+	{
+	static ERR_STATE fallback;
+	ERR_STATE *ret,tmp,*tmpp=NULL;
+	int i;
+	CRYPTO_THREADID tid;
+
+	err_fns_check();
+	CRYPTO_THREADID_current(&tid);
+	CRYPTO_THREADID_cpy(&tmp.tid, &tid);
+	ret=ERRFN(thread_get_item)(&tmp);
+
+	/* ret == the error state, if NULL, make a new one */
+	if (ret == NULL)
+		{
+		ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
+		if (ret == NULL) return(&fallback);
+		CRYPTO_THREADID_cpy(&ret->tid, &tid);
+		ret->top=0;
+		ret->bottom=0;
+		for (i=0; i<ERR_NUM_ERRORS; i++)
+			{
+			ret->err_data[i]=NULL;
+			ret->err_data_flags[i]=0;
+			}
+		tmpp = ERRFN(thread_set_item)(ret);
+		/* To check if insertion failed, do a get. */
+		if (ERRFN(thread_get_item)(ret) != ret)
+			{
+			ERR_STATE_free(ret); /* could not insert it */
+			return(&fallback);
+			}
+		/* If a race occured in this function and we came second, tmpp
+		 * is the first one that we just replaced. */
+		if (tmpp)
+			ERR_STATE_free(tmpp);
+		}
+	return ret;
+	}
+
+int ERR_get_next_error_library(void)
+	{
+	err_fns_check();
+	return ERRFN(get_next_lib)();
+	}
+
+void ERR_set_error_data(char *data, int flags)
+	{
+	ERR_STATE *es;
+	int i;
+
+	es=ERR_get_state();
+
+	i=es->top;
+	if (i == 0)
+		i=ERR_NUM_ERRORS-1;
+
+	err_clear_data(es,i);
+	es->err_data[i]=data;
+	es->err_data_flags[i]=flags;
+	}
+
+void ERR_add_error_data(int num, ...)
+	{
+	va_list args;
+	int i,n,s;
+	char *str,*p,*a;
+
+	s=80;
+	str=OPENSSL_malloc(s+1);
+	if (str == NULL) return;
+	str[0]='\0';
+
+	va_start(args, num);
+	n=0;
+	for (i=0; i<num; i++)
+		{
+		a=va_arg(args, char*);
+		/* ignore NULLs, thanks to Bob Beck <beck@obtuse.com> */
+		if (a != NULL)
+			{
+			n+=strlen(a);
+			if (n > s)
+				{
+				s=n+20;
+				p=OPENSSL_realloc(str,s+1);
+				if (p == NULL)
+					{
+					OPENSSL_free(str);
+					goto err;
+					}
+				else
+					str=p;
+				}
+			BUF_strlcat(str,a,(size_t)s+1);
+			}
+		}
+	ERR_set_error_data(str,ERR_TXT_MALLOCED|ERR_TXT_STRING);
+
+err:
+	va_end(args);
+	}
+
+int ERR_set_mark(void)
+	{
+	ERR_STATE *es;
+
+	es=ERR_get_state();
+
+	if (es->bottom == es->top) return 0;
+	es->err_flags[es->top]|=ERR_FLAG_MARK;
+	return 1;
+	}
+
+int ERR_pop_to_mark(void)
+	{
+	ERR_STATE *es;
+
+	es=ERR_get_state();
+
+	while(es->bottom != es->top
+		&& (es->err_flags[es->top] & ERR_FLAG_MARK) == 0)
+		{
+		err_clear(es,es->top);
+		es->top-=1;
+		if (es->top == -1) es->top=ERR_NUM_ERRORS-1;
+		}
+		
+	if (es->bottom == es->top) return 0;
+	es->err_flags[es->top]&=~ERR_FLAG_MARK;
+	return 1;
+	}
diff --git a/openssl/crypto/err/err.h b/openssl/crypto/err/err.h
new file mode 100644
index 0000000..b9f8c16
--- /dev/null
+++ b/openssl/crypto/err/err.h
@@ -0,0 +1,385 @@
+/* crypto/err/err.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_ERR_H
+#define HEADER_ERR_H
+
+#include <openssl/e_os2.h>
+
+#ifndef OPENSSL_NO_FP_API
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
+#include <openssl/ossl_typ.h>
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#ifndef OPENSSL_NO_LHASH
+#include <openssl/lhash.h>
+#endif
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#ifndef OPENSSL_NO_ERR
+#define ERR_PUT_error(a,b,c,d,e)	ERR_put_error(a,b,c,d,e)
+#else
+#define ERR_PUT_error(a,b,c,d,e)	ERR_put_error(a,b,c,NULL,0)
+#endif
+
+#include <errno.h>
+
+#define ERR_TXT_MALLOCED	0x01
+#define ERR_TXT_STRING		0x02
+
+#define ERR_FLAG_MARK		0x01
+
+#define ERR_NUM_ERRORS	16
+typedef struct err_state_st
+	{
+	CRYPTO_THREADID tid;
+	int err_flags[ERR_NUM_ERRORS];
+	unsigned long err_buffer[ERR_NUM_ERRORS];
+	char *err_data[ERR_NUM_ERRORS];
+	int err_data_flags[ERR_NUM_ERRORS];
+	const char *err_file[ERR_NUM_ERRORS];
+	int err_line[ERR_NUM_ERRORS];
+	int top,bottom;
+	} ERR_STATE;
+
+/* library */
+#define ERR_LIB_NONE		1
+#define ERR_LIB_SYS		2
+#define ERR_LIB_BN		3
+#define ERR_LIB_RSA		4
+#define ERR_LIB_DH		5
+#define ERR_LIB_EVP		6
+#define ERR_LIB_BUF		7
+#define ERR_LIB_OBJ		8
+#define ERR_LIB_PEM		9
+#define ERR_LIB_DSA		10
+#define ERR_LIB_X509		11
+/* #define ERR_LIB_METH         12 */
+#define ERR_LIB_ASN1		13
+#define ERR_LIB_CONF		14
+#define ERR_LIB_CRYPTO		15
+#define ERR_LIB_EC		16
+#define ERR_LIB_SSL		20
+/* #define ERR_LIB_SSL23        21 */
+/* #define ERR_LIB_SSL2         22 */
+/* #define ERR_LIB_SSL3         23 */
+/* #define ERR_LIB_RSAREF       30 */
+/* #define ERR_LIB_PROXY        31 */
+#define ERR_LIB_BIO		32
+#define ERR_LIB_PKCS7		33
+#define ERR_LIB_X509V3		34
+#define ERR_LIB_PKCS12		35
+#define ERR_LIB_RAND		36
+#define ERR_LIB_DSO		37
+#define ERR_LIB_ENGINE		38
+#define ERR_LIB_OCSP            39
+#define ERR_LIB_UI              40
+#define ERR_LIB_COMP            41
+#define ERR_LIB_ECDSA		42
+#define ERR_LIB_ECDH		43
+#define ERR_LIB_STORE           44
+#define ERR_LIB_FIPS		45
+#define ERR_LIB_CMS		46
+#define ERR_LIB_TS		47
+#define ERR_LIB_HMAC		48
+#define ERR_LIB_JPAKE		49
+
+#define ERR_LIB_USER		128
+
+#define SYSerr(f,r)  ERR_PUT_error(ERR_LIB_SYS,(f),(r),__FILE__,__LINE__)
+#define BNerr(f,r)   ERR_PUT_error(ERR_LIB_BN,(f),(r),__FILE__,__LINE__)
+#define RSAerr(f,r)  ERR_PUT_error(ERR_LIB_RSA,(f),(r),__FILE__,__LINE__)
+#define DHerr(f,r)   ERR_PUT_error(ERR_LIB_DH,(f),(r),__FILE__,__LINE__)
+#define EVPerr(f,r)  ERR_PUT_error(ERR_LIB_EVP,(f),(r),__FILE__,__LINE__)
+#define BUFerr(f,r)  ERR_PUT_error(ERR_LIB_BUF,(f),(r),__FILE__,__LINE__)
+#define OBJerr(f,r)  ERR_PUT_error(ERR_LIB_OBJ,(f),(r),__FILE__,__LINE__)
+#define PEMerr(f,r)  ERR_PUT_error(ERR_LIB_PEM,(f),(r),__FILE__,__LINE__)
+#define DSAerr(f,r)  ERR_PUT_error(ERR_LIB_DSA,(f),(r),__FILE__,__LINE__)
+#define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),__FILE__,__LINE__)
+#define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),__FILE__,__LINE__)
+#define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),__FILE__,__LINE__)
+#define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),__FILE__,__LINE__)
+#define ECerr(f,r)   ERR_PUT_error(ERR_LIB_EC,(f),(r),__FILE__,__LINE__)
+#define SSLerr(f,r)  ERR_PUT_error(ERR_LIB_SSL,(f),(r),__FILE__,__LINE__)
+#define BIOerr(f,r)  ERR_PUT_error(ERR_LIB_BIO,(f),(r),__FILE__,__LINE__)
+#define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),__FILE__,__LINE__)
+#define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),__FILE__,__LINE__)
+#define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),__FILE__,__LINE__)
+#define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),__FILE__,__LINE__)
+#define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),__FILE__,__LINE__)
+#define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),__FILE__,__LINE__)
+#define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),__FILE__,__LINE__)
+#define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),__FILE__,__LINE__)
+#define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),__FILE__,__LINE__)
+#define ECDSAerr(f,r)  ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__)
+#define ECDHerr(f,r)  ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__)
+#define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__)
+#define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),__FILE__,__LINE__)
+#define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__)
+#define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),__FILE__,__LINE__)
+#define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),__FILE__,__LINE__)
+#define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__)
+
+/* Borland C seems too stupid to be able to shift and do longs in
+ * the pre-processor :-( */
+#define ERR_PACK(l,f,r)		(((((unsigned long)l)&0xffL)*0x1000000)| \
+				((((unsigned long)f)&0xfffL)*0x1000)| \
+				((((unsigned long)r)&0xfffL)))
+#define ERR_GET_LIB(l)		(int)((((unsigned long)l)>>24L)&0xffL)
+#define ERR_GET_FUNC(l)		(int)((((unsigned long)l)>>12L)&0xfffL)
+#define ERR_GET_REASON(l)	(int)((l)&0xfffL)
+#define ERR_FATAL_ERROR(l)	(int)((l)&ERR_R_FATAL)
+
+
+/* OS functions */
+#define SYS_F_FOPEN		1
+#define SYS_F_CONNECT		2
+#define SYS_F_GETSERVBYNAME	3
+#define SYS_F_SOCKET		4
+#define SYS_F_IOCTLSOCKET	5
+#define SYS_F_BIND		6
+#define SYS_F_LISTEN		7
+#define SYS_F_ACCEPT		8
+#define SYS_F_WSASTARTUP	9 /* Winsock stuff */
+#define SYS_F_OPENDIR		10
+#define SYS_F_FREAD		11
+
+
+/* reasons */
+#define ERR_R_SYS_LIB	ERR_LIB_SYS       /* 2 */
+#define ERR_R_BN_LIB	ERR_LIB_BN        /* 3 */
+#define ERR_R_RSA_LIB	ERR_LIB_RSA       /* 4 */
+#define ERR_R_DH_LIB	ERR_LIB_DH        /* 5 */
+#define ERR_R_EVP_LIB	ERR_LIB_EVP       /* 6 */
+#define ERR_R_BUF_LIB	ERR_LIB_BUF       /* 7 */
+#define ERR_R_OBJ_LIB	ERR_LIB_OBJ       /* 8 */
+#define ERR_R_PEM_LIB	ERR_LIB_PEM       /* 9 */
+#define ERR_R_DSA_LIB	ERR_LIB_DSA      /* 10 */
+#define ERR_R_X509_LIB	ERR_LIB_X509     /* 11 */
+#define ERR_R_ASN1_LIB	ERR_LIB_ASN1     /* 13 */
+#define ERR_R_CONF_LIB	ERR_LIB_CONF     /* 14 */
+#define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO  /* 15 */
+#define ERR_R_EC_LIB	ERR_LIB_EC       /* 16 */
+#define ERR_R_SSL_LIB	ERR_LIB_SSL      /* 20 */
+#define ERR_R_BIO_LIB	ERR_LIB_BIO      /* 32 */
+#define ERR_R_PKCS7_LIB	ERR_LIB_PKCS7    /* 33 */
+#define ERR_R_X509V3_LIB ERR_LIB_X509V3  /* 34 */
+#define ERR_R_PKCS12_LIB ERR_LIB_PKCS12  /* 35 */
+#define ERR_R_RAND_LIB	ERR_LIB_RAND     /* 36 */
+#define ERR_R_DSO_LIB	ERR_LIB_DSO      /* 37 */
+#define ERR_R_ENGINE_LIB ERR_LIB_ENGINE  /* 38 */
+#define ERR_R_OCSP_LIB  ERR_LIB_OCSP     /* 39 */
+#define ERR_R_UI_LIB    ERR_LIB_UI       /* 40 */
+#define ERR_R_COMP_LIB	ERR_LIB_COMP     /* 41 */
+#define ERR_R_ECDSA_LIB ERR_LIB_ECDSA	 /* 42 */
+#define ERR_R_ECDH_LIB  ERR_LIB_ECDH	 /* 43 */
+#define ERR_R_STORE_LIB ERR_LIB_STORE    /* 44 */
+#define ERR_R_TS_LIB	ERR_LIB_TS       /* 45 */
+
+#define ERR_R_NESTED_ASN1_ERROR			58
+#define ERR_R_BAD_ASN1_OBJECT_HEADER		59
+#define ERR_R_BAD_GET_ASN1_OBJECT_CALL		60
+#define ERR_R_EXPECTING_AN_ASN1_SEQUENCE	61
+#define ERR_R_ASN1_LENGTH_MISMATCH		62
+#define ERR_R_MISSING_ASN1_EOS			63
+
+/* fatal error */
+#define ERR_R_FATAL				64
+#define	ERR_R_MALLOC_FAILURE			(1|ERR_R_FATAL)
+#define	ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED	(2|ERR_R_FATAL)
+#define	ERR_R_PASSED_NULL_PARAMETER		(3|ERR_R_FATAL)
+#define	ERR_R_INTERNAL_ERROR			(4|ERR_R_FATAL)
+#define	ERR_R_DISABLED				(5|ERR_R_FATAL)
+
+/* 99 is the maximum possible ERR_R_... code, higher values
+ * are reserved for the individual libraries */
+
+
+typedef struct ERR_string_data_st
+	{
+	unsigned long error;
+	const char *string;
+	} ERR_STRING_DATA;
+
+void ERR_put_error(int lib, int func,int reason,const char *file,int line);
+void ERR_set_error_data(char *data,int flags);
+
+unsigned long ERR_get_error(void);
+unsigned long ERR_get_error_line(const char **file,int *line);
+unsigned long ERR_get_error_line_data(const char **file,int *line,
+				      const char **data, int *flags);
+unsigned long ERR_peek_error(void);
+unsigned long ERR_peek_error_line(const char **file,int *line);
+unsigned long ERR_peek_error_line_data(const char **file,int *line,
+				       const char **data,int *flags);
+unsigned long ERR_peek_last_error(void);
+unsigned long ERR_peek_last_error_line(const char **file,int *line);
+unsigned long ERR_peek_last_error_line_data(const char **file,int *line,
+				       const char **data,int *flags);
+void ERR_clear_error(void );
+char *ERR_error_string(unsigned long e,char *buf);
+void ERR_error_string_n(unsigned long e, char *buf, size_t len);
+const char *ERR_lib_error_string(unsigned long e);
+const char *ERR_func_error_string(unsigned long e);
+const char *ERR_reason_error_string(unsigned long e);
+void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u),
+			 void *u);
+#ifndef OPENSSL_NO_FP_API
+void ERR_print_errors_fp(FILE *fp);
+#endif
+#ifndef OPENSSL_NO_BIO
+void ERR_print_errors(BIO *bp);
+void ERR_add_error_data(int num, ...);
+#endif
+void ERR_load_strings(int lib,ERR_STRING_DATA str[]);
+void ERR_unload_strings(int lib,ERR_STRING_DATA str[]);
+void ERR_load_ERR_strings(void);
+void ERR_load_crypto_strings(void);
+void ERR_free_strings(void);
+
+void ERR_remove_thread_state(const CRYPTO_THREADID *tid);
+#ifndef OPENSSL_NO_DEPRECATED
+void ERR_remove_state(unsigned long pid); /* if zero we look it up */
+#endif
+ERR_STATE *ERR_get_state(void);
+
+#ifndef OPENSSL_NO_LHASH
+LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void);
+LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void);
+void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash);
+#endif
+
+int ERR_get_next_error_library(void);
+
+int ERR_set_mark(void);
+int ERR_pop_to_mark(void);
+
+/* Already defined in ossl_typ.h */
+/* typedef struct st_ERR_FNS ERR_FNS; */
+/* An application can use this function and provide the return value to loaded
+ * modules that should use the application's ERR state/functionality */
+const ERR_FNS *ERR_get_implementation(void);
+/* A loaded module should call this function prior to any ERR operations using
+ * the application's "ERR_FNS". */
+int ERR_set_implementation(const ERR_FNS *fns);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/err/err_all.c b/openssl/crypto/err/err_all.c
new file mode 100644
index 0000000..fc049e8
--- /dev/null
+++ b/openssl/crypto/err/err_all.c
@@ -0,0 +1,160 @@
+/* crypto/err/err_all.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/asn1.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_EC
+#include <openssl/ec.h>
+#endif
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#include <openssl/comp.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_ECDSA
+#include <openssl/ecdsa.h>
+#endif
+#ifndef OPENSSL_NO_ECDH
+#include <openssl/ecdh.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/pem2.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/conf.h>
+#include <openssl/pkcs12.h>
+#include <openssl/rand.h>
+#include <openssl/dso.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/ui.h>
+#include <openssl/ocsp.h>
+#include <openssl/err.h>
+#include <openssl/ts.h>
+#ifndef OPENSSL_NO_CMS
+#include <openssl/cms.h>
+#endif
+#ifndef OPENSSL_NO_JPAKE
+#include <openssl/jpake.h>
+#endif
+#include <openssl/comp.h>
+
+void ERR_load_crypto_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+	ERR_load_ERR_strings(); /* include error strings for SYSerr */
+	ERR_load_BN_strings();
+#ifndef OPENSSL_NO_RSA
+	ERR_load_RSA_strings();
+#endif
+#ifndef OPENSSL_NO_DH
+	ERR_load_DH_strings();
+#endif
+	ERR_load_EVP_strings();
+	ERR_load_BUF_strings();
+	ERR_load_OBJ_strings();
+	ERR_load_PEM_strings();
+#ifndef OPENSSL_NO_DSA
+	ERR_load_DSA_strings();
+#endif
+	ERR_load_X509_strings();
+	ERR_load_ASN1_strings();
+	ERR_load_CONF_strings();
+	ERR_load_CRYPTO_strings();
+	ERR_load_COMP_strings();
+#ifndef OPENSSL_NO_EC
+	ERR_load_EC_strings();
+#endif
+#ifndef OPENSSL_NO_ECDSA
+	ERR_load_ECDSA_strings();
+#endif
+#ifndef OPENSSL_NO_ECDH
+	ERR_load_ECDH_strings();
+#endif
+	/* skip ERR_load_SSL_strings() because it is not in this library */
+	ERR_load_BIO_strings();
+	ERR_load_PKCS7_strings();	
+	ERR_load_X509V3_strings();
+	ERR_load_PKCS12_strings();
+	ERR_load_RAND_strings();
+	ERR_load_DSO_strings();
+	ERR_load_TS_strings();
+#ifndef OPENSSL_NO_ENGINE
+	ERR_load_ENGINE_strings();
+#endif
+	ERR_load_OCSP_strings();
+	ERR_load_UI_strings();
+#ifndef OPENSSL_NO_CMS
+	ERR_load_CMS_strings();
+#endif
+#ifndef OPENSSL_NO_JPAKE
+	ERR_load_JPAKE_strings();
+#endif
+	ERR_load_COMP_strings();
+#endif
+	}
diff --git a/openssl/crypto/err/err_prn.c b/openssl/crypto/err/err_prn.c
new file mode 100644
index 0000000..a0168ac
--- /dev/null
+++ b/openssl/crypto/err/err_prn.c
@@ -0,0 +1,114 @@
+/* crypto/err/err_prn.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+
+void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u),
+			 void *u)
+	{
+	unsigned long l;
+	char buf[256];
+	char buf2[4096];
+	const char *file,*data;
+	int line,flags;
+	unsigned long es;
+	CRYPTO_THREADID cur;
+
+	CRYPTO_THREADID_current(&cur);
+	es=CRYPTO_THREADID_hash(&cur);
+	while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
+		{
+		ERR_error_string_n(l, buf, sizeof buf);
+		BIO_snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", es, buf,
+			file, line, (flags & ERR_TXT_STRING) ? data : "");
+		if (cb(buf2, strlen(buf2), u) <= 0)
+			break; /* abort outputting the error report */
+		}
+	}
+
+#ifndef OPENSSL_NO_FP_API
+static int print_fp(const char *str, size_t len, void *fp)
+	{
+	BIO bio;
+
+	BIO_set(&bio,BIO_s_file());
+	BIO_set_fp(&bio,fp,BIO_NOCLOSE);
+
+	return BIO_printf(&bio, "%s", str);
+	}
+void ERR_print_errors_fp(FILE *fp)
+	{
+	ERR_print_errors_cb(print_fp, fp);
+	}
+#endif
+
+static int print_bio(const char *str, size_t len, void *bp)
+	{
+	return BIO_write((BIO *)bp, str, len);
+	}
+void ERR_print_errors(BIO *bp)
+	{
+	ERR_print_errors_cb(print_bio, bp);
+	}
+
+	
diff --git a/openssl/crypto/err/openssl.ec b/openssl/crypto/err/openssl.ec
new file mode 100644
index 0000000..e0554b4
--- /dev/null
+++ b/openssl/crypto/err/openssl.ec
@@ -0,0 +1,96 @@
+# crypto/err/openssl.ec
+
+# configuration file for util/mkerr.pl
+
+# files that may have to be rewritten by util/mkerr.pl
+L ERR		NONE				NONE
+L BN		crypto/bn/bn.h			crypto/bn/bn_err.c
+L RSA		crypto/rsa/rsa.h		crypto/rsa/rsa_err.c
+L DH		crypto/dh/dh.h			crypto/dh/dh_err.c
+L EVP		crypto/evp/evp.h		crypto/evp/evp_err.c
+L BUF		crypto/buffer/buffer.h		crypto/buffer/buf_err.c
+L OBJ		crypto/objects/objects.h	crypto/objects/obj_err.c
+L PEM		crypto/pem/pem.h		crypto/pem/pem_err.c
+L DSA		crypto/dsa/dsa.h		crypto/dsa/dsa_err.c
+L X509		crypto/x509/x509.h		crypto/x509/x509_err.c
+L ASN1		crypto/asn1/asn1.h		crypto/asn1/asn1_err.c
+L CONF		crypto/conf/conf.h		crypto/conf/conf_err.c
+L CRYPTO	crypto/crypto.h			crypto/cpt_err.c
+L EC		crypto/ec/ec.h			crypto/ec/ec_err.c
+L SSL		ssl/ssl.h			ssl/ssl_err.c
+L BIO		crypto/bio/bio.h		crypto/bio/bio_err.c
+L PKCS7		crypto/pkcs7/pkcs7.h		crypto/pkcs7/pkcs7err.c
+L X509V3	crypto/x509v3/x509v3.h		crypto/x509v3/v3err.c
+L PKCS12	crypto/pkcs12/pkcs12.h		crypto/pkcs12/pk12err.c
+L RAND		crypto/rand/rand.h		crypto/rand/rand_err.c
+L DSO		crypto/dso/dso.h		crypto/dso/dso_err.c
+L ENGINE	crypto/engine/engine.h		crypto/engine/eng_err.c
+L OCSP		crypto/ocsp/ocsp.h		crypto/ocsp/ocsp_err.c
+L UI		crypto/ui/ui.h			crypto/ui/ui_err.c
+L COMP		crypto/comp/comp.h		crypto/comp/comp_err.c
+L ECDSA		crypto/ecdsa/ecdsa.h		crypto/ecdsa/ecs_err.c
+L ECDH		crypto/ecdh/ecdh.h		crypto/ecdh/ech_err.c
+L STORE		crypto/store/store.h		crypto/store/str_err.c
+L TS		crypto/ts/ts.h			crypto/ts/ts_err.c
+L HMAC		crypto/hmac/hmac.h		crypto/hmac/hmac_err.c
+L CMS		crypto/cms/cms.h		crypto/cms/cms_err.c
+L JPAKE		crypto/jpake/jpake.h		crypto/jpake/jpake_err.c
+
+# additional header files to be scanned for function names
+L NONE		crypto/x509/x509_vfy.h		NONE
+L NONE		crypto/ec/ec_lcl.h		NONE
+L NONE		crypto/asn1/asn_lcl.h		NONE
+L NONE		crypto/cms/cms_lcl.h		NONE
+
+
+F RSAREF_F_RSA_BN2BIN
+F RSAREF_F_RSA_PRIVATE_DECRYPT
+F RSAREF_F_RSA_PRIVATE_ENCRYPT
+F RSAREF_F_RSA_PUBLIC_DECRYPT
+F RSAREF_F_RSA_PUBLIC_ENCRYPT
+#F SSL_F_CLIENT_CERTIFICATE
+
+R SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE		1010
+R SSL_R_SSLV3_ALERT_BAD_RECORD_MAC		1020
+R SSL_R_TLSV1_ALERT_DECRYPTION_FAILED		1021
+R SSL_R_TLSV1_ALERT_RECORD_OVERFLOW		1022
+R SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE	1030
+R SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE		1040
+R SSL_R_SSLV3_ALERT_NO_CERTIFICATE		1041
+R SSL_R_SSLV3_ALERT_BAD_CERTIFICATE		1042
+R SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE	1043
+R SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED		1044
+R SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED		1045
+R SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN		1046
+R SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER		1047
+R SSL_R_TLSV1_ALERT_UNKNOWN_CA			1048
+R SSL_R_TLSV1_ALERT_ACCESS_DENIED		1049
+R SSL_R_TLSV1_ALERT_DECODE_ERROR		1050
+R SSL_R_TLSV1_ALERT_DECRYPT_ERROR		1051
+R SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION		1060
+R SSL_R_TLSV1_ALERT_PROTOCOL_VERSION		1070
+R SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY	1071
+R SSL_R_TLSV1_ALERT_INTERNAL_ERROR		1080
+R SSL_R_TLSV1_ALERT_USER_CANCELLED		1090
+R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION		1100
+R SSL_R_TLSV1_UNSUPPORTED_EXTENSION		1110
+R SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE		1111
+R SSL_R_TLSV1_UNRECOGNIZED_NAME			1112
+R SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE	1113
+R SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE	1114
+
+R RSAREF_R_CONTENT_ENCODING			0x0400
+R RSAREF_R_DATA					0x0401
+R RSAREF_R_DIGEST_ALGORITHM			0x0402
+R RSAREF_R_ENCODING				0x0403
+R RSAREF_R_KEY					0x0404
+R RSAREF_R_KEY_ENCODING				0x0405
+R RSAREF_R_LEN					0x0406
+R RSAREF_R_MODULUS_LEN				0x0407
+R RSAREF_R_NEED_RANDOM				0x0408
+R RSAREF_R_PRIVATE_KEY				0x0409
+R RSAREF_R_PUBLIC_KEY				0x040a
+R RSAREF_R_SIGNATURE				0x040b
+R RSAREF_R_SIGNATURE_ENCODING			0x040c
+R RSAREF_R_ENCRYPTION_ALGORITHM			0x040d
+
diff --git a/openssl/crypto/evp/Makefile b/openssl/crypto/evp/Makefile
new file mode 100644
index 0000000..82825e5
--- /dev/null
+++ b/openssl/crypto/evp/Makefile
@@ -0,0 +1,733 @@
+#
+# OpenSSL/crypto/evp/Makefile
+#
+
+DIR=	evp
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=evp_test.c
+TESTDATA=evptests.txt
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= encode.c digest.c evp_enc.c evp_key.c evp_acnf.c \
+	e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\
+	e_rc4.c e_aes.c names.c e_seed.c \
+	e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c \
+	m_null.c m_md2.c m_md4.c m_md5.c m_sha.c m_sha1.c m_wp.c \
+	m_dss.c m_dss1.c m_mdc2.c m_ripemd.c m_ecdsa.c\
+	p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \
+	bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \
+	c_all.c c_allc.c c_alld.c evp_lib.c bio_ok.c \
+	evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c \
+	e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c
+
+LIBOBJ=	encode.o digest.o evp_enc.o evp_key.o evp_acnf.o \
+	e_des.o e_bf.o e_idea.o e_des3.o e_camellia.o\
+	e_rc4.o e_aes.o names.o e_seed.o \
+	e_xcbc_d.o e_rc2.o e_cast.o e_rc5.o \
+	m_null.o m_md2.o m_md4.o m_md5.o m_sha.o m_sha1.o m_wp.o \
+	m_dss.o m_dss1.o m_mdc2.o m_ripemd.o m_ecdsa.o\
+	p_open.o p_seal.o p_sign.o p_verify.o p_lib.o p_enc.o p_dec.o \
+	bio_md.o bio_b64.o bio_enc.o evp_err.o e_null.o \
+	c_all.o c_allc.o c_alld.o evp_lib.o bio_ok.o \
+	evp_pkey.o evp_pbe.o p5_crpt.o p5_crpt2.o \
+	e_old.o pmeth_lib.o pmeth_fn.o pmeth_gn.o m_sigver.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= evp.h
+HEADER=	evp_locl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	cp $(TESTDATA) ../../test
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+bio_b64.o: ../../e_os.h ../../include/openssl/asn1.h
+bio_b64.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+bio_b64.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+bio_b64.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+bio_b64.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+bio_b64.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+bio_b64.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bio_b64.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bio_b64.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_b64.c
+bio_enc.o: ../../e_os.h ../../include/openssl/asn1.h
+bio_enc.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+bio_enc.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+bio_enc.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+bio_enc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+bio_enc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+bio_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bio_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bio_enc.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_enc.c
+bio_md.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+bio_md.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bio_md.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bio_md.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+bio_md.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+bio_md.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+bio_md.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+bio_md.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+bio_md.o: ../cryptlib.h bio_md.c
+bio_ok.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+bio_ok.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bio_ok.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bio_ok.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+bio_ok.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+bio_ok.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+bio_ok.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+bio_ok.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bio_ok.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_ok.c
+c_all.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+c_all.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+c_all.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+c_all.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+c_all.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+c_all.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+c_all.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+c_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+c_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+c_all.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+c_all.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+c_all.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+c_all.o: ../cryptlib.h c_all.c
+c_allc.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+c_allc.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+c_allc.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+c_allc.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+c_allc.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+c_allc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+c_allc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+c_allc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+c_allc.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+c_allc.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+c_allc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+c_allc.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+c_allc.o: ../cryptlib.h c_allc.c
+c_alld.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+c_alld.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+c_alld.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+c_alld.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+c_alld.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+c_alld.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+c_alld.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+c_alld.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+c_alld.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+c_alld.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+c_alld.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+c_alld.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+c_alld.o: ../cryptlib.h c_alld.c
+digest.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+digest.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+digest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+digest.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+digest.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+digest.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+digest.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+digest.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+digest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+digest.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+digest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+digest.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+digest.o: ../cryptlib.h digest.c
+e_aes.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+e_aes.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+e_aes.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+e_aes.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+e_aes.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+e_aes.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+e_aes.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+e_aes.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h e_aes.c
+e_aes.o: evp_locl.h
+e_bf.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+e_bf.o: ../../include/openssl/blowfish.h ../../include/openssl/buffer.h
+e_bf.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+e_bf.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+e_bf.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+e_bf.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+e_bf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+e_bf.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+e_bf.o: ../../include/openssl/symhacks.h ../cryptlib.h e_bf.c evp_locl.h
+e_camellia.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+e_camellia.o: ../../include/openssl/camellia.h ../../include/openssl/crypto.h
+e_camellia.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+e_camellia.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+e_camellia.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+e_camellia.o: ../../include/openssl/opensslconf.h
+e_camellia.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+e_camellia.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+e_camellia.o: ../../include/openssl/symhacks.h e_camellia.c evp_locl.h
+e_cast.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+e_cast.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+e_cast.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+e_cast.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+e_cast.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+e_cast.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+e_cast.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+e_cast.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+e_cast.o: ../../include/openssl/symhacks.h ../cryptlib.h e_cast.c evp_locl.h
+e_des.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+e_des.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+e_des.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+e_des.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+e_des.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+e_des.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+e_des.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+e_des.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+e_des.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+e_des.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+e_des.o: ../../include/openssl/ui_compat.h ../cryptlib.h e_des.c evp_locl.h
+e_des3.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+e_des3.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+e_des3.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+e_des3.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+e_des3.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+e_des3.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+e_des3.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+e_des3.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+e_des3.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+e_des3.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+e_des3.o: ../../include/openssl/ui_compat.h ../cryptlib.h e_des3.c evp_locl.h
+e_idea.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+e_idea.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+e_idea.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+e_idea.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+e_idea.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+e_idea.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+e_idea.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+e_idea.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+e_idea.o: ../../include/openssl/symhacks.h ../cryptlib.h e_idea.c evp_locl.h
+e_null.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+e_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+e_null.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+e_null.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+e_null.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+e_null.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+e_null.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+e_null.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+e_null.o: ../cryptlib.h e_null.c
+e_old.o: e_old.c
+e_rc2.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+e_rc2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+e_rc2.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+e_rc2.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+e_rc2.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+e_rc2.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+e_rc2.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rc2.h
+e_rc2.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+e_rc2.o: ../../include/openssl/symhacks.h ../cryptlib.h e_rc2.c evp_locl.h
+e_rc4.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+e_rc4.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+e_rc4.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+e_rc4.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+e_rc4.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+e_rc4.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+e_rc4.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rc4.h
+e_rc4.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+e_rc4.o: ../../include/openssl/symhacks.h ../cryptlib.h e_rc4.c
+e_rc5.o: ../../e_os.h ../../include/openssl/bio.h
+e_rc5.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+e_rc5.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+e_rc5.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+e_rc5.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+e_rc5.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+e_rc5.o: ../../include/openssl/symhacks.h ../cryptlib.h e_rc5.c
+e_seed.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+e_seed.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+e_seed.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+e_seed.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+e_seed.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+e_seed.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+e_seed.o: ../../include/openssl/safestack.h ../../include/openssl/seed.h
+e_seed.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+e_seed.o: e_seed.c evp_locl.h
+e_xcbc_d.o: ../../e_os.h ../../include/openssl/asn1.h
+e_xcbc_d.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+e_xcbc_d.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+e_xcbc_d.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
+e_xcbc_d.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+e_xcbc_d.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+e_xcbc_d.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+e_xcbc_d.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+e_xcbc_d.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+e_xcbc_d.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+e_xcbc_d.o: ../../include/openssl/ui_compat.h ../cryptlib.h e_xcbc_d.c
+e_xcbc_d.o: evp_locl.h
+encode.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+encode.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+encode.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+encode.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+encode.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+encode.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+encode.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+encode.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+encode.o: ../cryptlib.h encode.c
+evp_acnf.o: ../../e_os.h ../../include/openssl/asn1.h
+evp_acnf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+evp_acnf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+evp_acnf.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+evp_acnf.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+evp_acnf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+evp_acnf.o: ../../include/openssl/opensslconf.h
+evp_acnf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+evp_acnf.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+evp_acnf.o: ../../include/openssl/symhacks.h ../cryptlib.h evp_acnf.c
+evp_enc.o: ../../e_os.h ../../include/openssl/asn1.h
+evp_enc.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+evp_enc.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+evp_enc.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+evp_enc.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+evp_enc.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+evp_enc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+evp_enc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+evp_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+evp_enc.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+evp_enc.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+evp_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+evp_enc.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+evp_enc.o: ../cryptlib.h evp_enc.c evp_locl.h
+evp_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+evp_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+evp_err.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+evp_err.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+evp_err.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+evp_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+evp_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+evp_err.o: ../../include/openssl/symhacks.h evp_err.c
+evp_key.o: ../../e_os.h ../../include/openssl/asn1.h
+evp_key.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+evp_key.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+evp_key.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+evp_key.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+evp_key.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+evp_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+evp_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+evp_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+evp_key.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+evp_key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+evp_key.o: ../../include/openssl/ui.h ../../include/openssl/x509.h
+evp_key.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_key.c
+evp_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+evp_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+evp_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+evp_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+evp_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+evp_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+evp_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+evp_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+evp_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h evp_lib.c
+evp_pbe.o: ../../e_os.h ../../include/openssl/asn1.h
+evp_pbe.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+evp_pbe.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+evp_pbe.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+evp_pbe.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+evp_pbe.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+evp_pbe.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+evp_pbe.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+evp_pbe.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
+evp_pbe.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+evp_pbe.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+evp_pbe.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+evp_pbe.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_pbe.c
+evp_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
+evp_pkey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+evp_pkey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+evp_pkey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+evp_pkey.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+evp_pkey.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+evp_pkey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+evp_pkey.o: ../../include/openssl/opensslconf.h
+evp_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+evp_pkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+evp_pkey.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+evp_pkey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+evp_pkey.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+evp_pkey.o: ../asn1/asn1_locl.h ../cryptlib.h evp_pkey.c
+m_dss.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+m_dss.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+m_dss.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+m_dss.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+m_dss.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+m_dss.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+m_dss.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+m_dss.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+m_dss.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+m_dss.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+m_dss.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+m_dss.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+m_dss.o: ../cryptlib.h m_dss.c
+m_dss1.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+m_dss1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+m_dss1.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+m_dss1.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+m_dss1.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+m_dss1.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+m_dss1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+m_dss1.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+m_dss1.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+m_dss1.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+m_dss1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+m_dss1.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+m_dss1.o: ../cryptlib.h m_dss1.c
+m_ecdsa.o: ../../e_os.h ../../include/openssl/asn1.h
+m_ecdsa.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+m_ecdsa.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+m_ecdsa.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+m_ecdsa.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+m_ecdsa.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+m_ecdsa.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+m_ecdsa.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+m_ecdsa.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+m_ecdsa.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+m_ecdsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+m_ecdsa.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+m_ecdsa.o: ../cryptlib.h m_ecdsa.c
+m_md2.o: ../../e_os.h ../../include/openssl/bio.h
+m_md2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+m_md2.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+m_md2.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+m_md2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+m_md2.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+m_md2.o: ../../include/openssl/symhacks.h ../cryptlib.h m_md2.c
+m_md4.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+m_md4.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+m_md4.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+m_md4.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+m_md4.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+m_md4.o: ../../include/openssl/lhash.h ../../include/openssl/md4.h
+m_md4.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+m_md4.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+m_md4.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+m_md4.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+m_md4.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+m_md4.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+m_md4.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_md4.c
+m_md5.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+m_md5.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+m_md5.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+m_md5.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+m_md5.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+m_md5.o: ../../include/openssl/lhash.h ../../include/openssl/md5.h
+m_md5.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+m_md5.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+m_md5.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+m_md5.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+m_md5.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+m_md5.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+m_md5.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_md5.c
+m_mdc2.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+m_mdc2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+m_mdc2.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+m_mdc2.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+m_mdc2.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+m_mdc2.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+m_mdc2.o: ../../include/openssl/lhash.h ../../include/openssl/mdc2.h
+m_mdc2.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+m_mdc2.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+m_mdc2.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+m_mdc2.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+m_mdc2.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+m_mdc2.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+m_mdc2.o: ../../include/openssl/ui_compat.h ../../include/openssl/x509.h
+m_mdc2.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_mdc2.c
+m_null.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+m_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+m_null.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+m_null.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+m_null.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+m_null.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+m_null.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+m_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+m_null.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+m_null.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+m_null.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+m_null.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_null.c
+m_ripemd.o: ../../e_os.h ../../include/openssl/asn1.h
+m_ripemd.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+m_ripemd.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+m_ripemd.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+m_ripemd.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+m_ripemd.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+m_ripemd.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+m_ripemd.o: ../../include/openssl/opensslconf.h
+m_ripemd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+m_ripemd.o: ../../include/openssl/pkcs7.h ../../include/openssl/ripemd.h
+m_ripemd.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+m_ripemd.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+m_ripemd.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+m_ripemd.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_ripemd.c
+m_sha.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+m_sha.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+m_sha.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+m_sha.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+m_sha.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+m_sha.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+m_sha.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+m_sha.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+m_sha.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+m_sha.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+m_sha.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+m_sha.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+m_sha.o: ../cryptlib.h m_sha.c
+m_sha1.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+m_sha1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+m_sha1.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+m_sha1.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+m_sha1.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+m_sha1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+m_sha1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+m_sha1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+m_sha1.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+m_sha1.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+m_sha1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+m_sha1.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+m_sha1.o: ../cryptlib.h m_sha1.c
+m_sigver.o: ../../e_os.h ../../include/openssl/asn1.h
+m_sigver.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+m_sigver.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+m_sigver.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+m_sigver.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+m_sigver.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+m_sigver.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+m_sigver.o: ../../include/openssl/opensslconf.h
+m_sigver.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+m_sigver.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+m_sigver.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+m_sigver.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+m_sigver.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_locl.h
+m_sigver.o: m_sigver.c
+m_wp.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+m_wp.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+m_wp.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+m_wp.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+m_wp.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+m_wp.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+m_wp.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+m_wp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+m_wp.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+m_wp.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+m_wp.o: ../../include/openssl/symhacks.h ../../include/openssl/whrlpool.h
+m_wp.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+m_wp.o: ../cryptlib.h m_wp.c
+names.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+names.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+names.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+names.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+names.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+names.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+names.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+names.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+names.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+names.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+names.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+names.o: ../../include/openssl/x509_vfy.h ../cryptlib.h names.c
+p5_crpt.o: ../../e_os.h ../../include/openssl/asn1.h
+p5_crpt.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+p5_crpt.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+p5_crpt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+p5_crpt.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+p5_crpt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+p5_crpt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p5_crpt.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+p5_crpt.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+p5_crpt.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p5_crpt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p5_crpt.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p5_crpt.o: ../cryptlib.h p5_crpt.c
+p5_crpt2.o: ../../e_os.h ../../include/openssl/asn1.h
+p5_crpt2.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+p5_crpt2.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+p5_crpt2.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+p5_crpt2.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+p5_crpt2.o: ../../include/openssl/evp.h ../../include/openssl/hmac.h
+p5_crpt2.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p5_crpt2.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p5_crpt2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p5_crpt2.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+p5_crpt2.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p5_crpt2.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p5_crpt2.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p5_crpt2.c
+p_dec.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+p_dec.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+p_dec.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+p_dec.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+p_dec.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+p_dec.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p_dec.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p_dec.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p_dec.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+p_dec.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+p_dec.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p_dec.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p_dec.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p_dec.c
+p_enc.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+p_enc.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+p_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+p_enc.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+p_enc.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+p_enc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p_enc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p_enc.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+p_enc.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+p_enc.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p_enc.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p_enc.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p_enc.c
+p_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+p_lib.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
+p_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+p_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+p_lib.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+p_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+p_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+p_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+p_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+p_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p_lib.o: ../asn1/asn1_locl.h ../cryptlib.h p_lib.c
+p_open.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+p_open.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+p_open.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+p_open.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+p_open.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+p_open.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p_open.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p_open.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p_open.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+p_open.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p_open.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p_open.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p_open.o: ../cryptlib.h p_open.c
+p_seal.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+p_seal.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+p_seal.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+p_seal.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+p_seal.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+p_seal.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p_seal.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p_seal.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p_seal.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+p_seal.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+p_seal.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p_seal.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p_seal.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p_seal.c
+p_sign.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+p_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+p_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+p_sign.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+p_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+p_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p_sign.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+p_sign.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p_sign.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p_sign.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p_sign.c
+p_verify.o: ../../e_os.h ../../include/openssl/asn1.h
+p_verify.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+p_verify.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+p_verify.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+p_verify.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+p_verify.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+p_verify.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p_verify.o: ../../include/openssl/opensslconf.h
+p_verify.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p_verify.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+p_verify.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p_verify.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p_verify.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p_verify.c
+pmeth_fn.o: ../../e_os.h ../../include/openssl/asn1.h
+pmeth_fn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pmeth_fn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+pmeth_fn.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+pmeth_fn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pmeth_fn.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pmeth_fn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pmeth_fn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+pmeth_fn.o: ../../include/openssl/symhacks.h ../cryptlib.h evp_locl.h
+pmeth_fn.o: pmeth_fn.c
+pmeth_gn.o: ../../e_os.h ../../include/openssl/asn1.h
+pmeth_gn.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+pmeth_gn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+pmeth_gn.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+pmeth_gn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+pmeth_gn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pmeth_gn.o: ../../include/openssl/opensslconf.h
+pmeth_gn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pmeth_gn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+pmeth_gn.o: ../../include/openssl/symhacks.h ../cryptlib.h evp_locl.h
+pmeth_gn.o: pmeth_gn.c
+pmeth_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+pmeth_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pmeth_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+pmeth_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+pmeth_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+pmeth_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+pmeth_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pmeth_lib.o: ../../include/openssl/objects.h
+pmeth_lib.o: ../../include/openssl/opensslconf.h
+pmeth_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pmeth_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+pmeth_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pmeth_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pmeth_lib.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
+pmeth_lib.o: evp_locl.h pmeth_lib.c
diff --git a/openssl/crypto/evp/bio_b64.c b/openssl/crypto/evp/bio_b64.c
new file mode 100644
index 0000000..72a2a67
--- /dev/null
+++ b/openssl/crypto/evp/bio_b64.c
@@ -0,0 +1,598 @@
+/* crypto/evp/bio_b64.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+
+static int b64_write(BIO *h, const char *buf, int num);
+static int b64_read(BIO *h, char *buf, int size);
+static int b64_puts(BIO *h, const char *str);
+/*static int b64_gets(BIO *h, char *str, int size); */
+static long b64_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int b64_new(BIO *h);
+static int b64_free(BIO *data);
+static long b64_callback_ctrl(BIO *h,int cmd,bio_info_cb *fp);
+#define B64_BLOCK_SIZE	1024
+#define B64_BLOCK_SIZE2	768
+#define B64_NONE	0
+#define B64_ENCODE	1
+#define B64_DECODE	2
+
+typedef struct b64_struct
+	{
+	/*BIO *bio; moved to the BIO structure */
+	int buf_len;
+	int buf_off;
+	int tmp_len;		/* used to find the start when decoding */
+	int tmp_nl;		/* If true, scan until '\n' */
+	int encode;
+	int start;		/* have we started decoding yet? */
+	int cont;		/* <= 0 when finished */
+	EVP_ENCODE_CTX base64;
+	char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE)+10];
+	char tmp[B64_BLOCK_SIZE];
+	} BIO_B64_CTX;
+
+static BIO_METHOD methods_b64=
+	{
+	BIO_TYPE_BASE64,"base64 encoding",
+	b64_write,
+	b64_read,
+	b64_puts,
+	NULL, /* b64_gets, */
+	b64_ctrl,
+	b64_new,
+	b64_free,
+	b64_callback_ctrl,
+	};
+
+BIO_METHOD *BIO_f_base64(void)
+	{
+	return(&methods_b64);
+	}
+
+static int b64_new(BIO *bi)
+	{
+	BIO_B64_CTX *ctx;
+
+	ctx=(BIO_B64_CTX *)OPENSSL_malloc(sizeof(BIO_B64_CTX));
+	if (ctx == NULL) return(0);
+
+	ctx->buf_len=0;
+	ctx->tmp_len=0;
+	ctx->tmp_nl=0;
+	ctx->buf_off=0;
+	ctx->cont=1;
+	ctx->start=1;
+	ctx->encode=0;
+
+	bi->init=1;
+	bi->ptr=(char *)ctx;
+	bi->flags=0;
+	bi->num = 0;
+	return(1);
+	}
+
+static int b64_free(BIO *a)
+	{
+	if (a == NULL) return(0);
+	OPENSSL_free(a->ptr);
+	a->ptr=NULL;
+	a->init=0;
+	a->flags=0;
+	return(1);
+	}
+	
+static int b64_read(BIO *b, char *out, int outl)
+	{
+	int ret=0,i,ii,j,k,x,n,num,ret_code=0;
+	BIO_B64_CTX *ctx;
+	unsigned char *p,*q;
+
+	if (out == NULL) return(0);
+	ctx=(BIO_B64_CTX *)b->ptr;
+
+	if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
+
+	BIO_clear_retry_flags(b);
+
+	if (ctx->encode != B64_DECODE)
+		{
+		ctx->encode=B64_DECODE;
+		ctx->buf_len=0;
+		ctx->buf_off=0;
+		ctx->tmp_len=0;
+		EVP_DecodeInit(&(ctx->base64));
+		}
+
+	/* First check if there are bytes decoded/encoded */
+	if (ctx->buf_len > 0)
+		{
+		OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+		i=ctx->buf_len-ctx->buf_off;
+		if (i > outl) i=outl;
+		OPENSSL_assert(ctx->buf_off+i < (int)sizeof(ctx->buf));
+		memcpy(out,&(ctx->buf[ctx->buf_off]),i);
+		ret=i;
+		out+=i;
+		outl-=i;
+		ctx->buf_off+=i;
+		if (ctx->buf_len == ctx->buf_off)
+			{
+			ctx->buf_len=0;
+			ctx->buf_off=0;
+			}
+		}
+
+	/* At this point, we have room of outl bytes and an empty
+	 * buffer, so we should read in some more. */
+
+	ret_code=0;
+	while (outl > 0)
+		{
+		if (ctx->cont <= 0)
+			break;
+
+		i=BIO_read(b->next_bio,&(ctx->tmp[ctx->tmp_len]),
+			B64_BLOCK_SIZE-ctx->tmp_len);
+
+		if (i <= 0)
+			{
+			ret_code=i;
+
+			/* Should we continue next time we are called? */
+			if (!BIO_should_retry(b->next_bio))
+				{
+				ctx->cont=i;
+				/* If buffer empty break */
+				if(ctx->tmp_len == 0)
+					break;
+				/* Fall through and process what we have */
+				else
+					i = 0;
+				}
+			/* else we retry and add more data to buffer */
+			else
+				break;
+			}
+		i+=ctx->tmp_len;
+		ctx->tmp_len = i;
+
+		/* We need to scan, a line at a time until we
+		 * have a valid line if we are starting. */
+		if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL))
+			{
+			/* ctx->start=1; */
+			ctx->tmp_len=0;
+			}
+		else if (ctx->start)
+			{
+			q=p=(unsigned char *)ctx->tmp;
+			for (j=0; j<i; j++)
+				{
+				if (*(q++) != '\n') continue;
+
+				/* due to a previous very long line,
+				 * we need to keep on scanning for a '\n'
+				 * before we even start looking for
+				 * base64 encoded stuff. */
+				if (ctx->tmp_nl)
+					{
+					p=q;
+					ctx->tmp_nl=0;
+					continue;
+					}
+
+				k=EVP_DecodeUpdate(&(ctx->base64),
+					(unsigned char *)ctx->buf,
+					&num,p,q-p);
+				if ((k <= 0) && (num == 0) && (ctx->start))
+					EVP_DecodeInit(&ctx->base64);
+				else 
+					{
+					if (p != (unsigned char *)
+						&(ctx->tmp[0]))
+						{
+						i-=(p- (unsigned char *)
+							&(ctx->tmp[0]));
+						for (x=0; x < i; x++)
+							ctx->tmp[x]=p[x];
+						}
+					EVP_DecodeInit(&ctx->base64);
+					ctx->start=0;
+					break;
+					}
+				p=q;
+				}
+
+			/* we fell off the end without starting */
+			if (j == i)
+				{
+				/* Is this is one long chunk?, if so, keep on
+				 * reading until a new line. */
+				if (p == (unsigned char *)&(ctx->tmp[0]))
+					{
+					/* Check buffer full */
+					if (i == B64_BLOCK_SIZE)
+						{
+						ctx->tmp_nl=1;
+						ctx->tmp_len=0;
+						}
+					}
+				else if (p != q) /* finished on a '\n' */
+					{
+					n=q-p;
+					for (ii=0; ii<n; ii++)
+						ctx->tmp[ii]=p[ii];
+					ctx->tmp_len=n;
+					}
+				/* else finished on a '\n' */
+				continue;
+				}
+			else
+			{
+				ctx->tmp_len=0;
+			}
+		}
+		else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0))
+		{
+			/* If buffer isn't full and we can retry then
+			 * restart to read in more data.
+			 */
+			continue;
+		}
+
+		if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)
+			{
+			int z,jj;
+
+#if 0
+			jj=(i>>2)<<2;
+#else
+			jj = i & ~3; /* process per 4 */
+#endif
+			z=EVP_DecodeBlock((unsigned char *)ctx->buf,
+				(unsigned char *)ctx->tmp,jj);
+			if (jj > 2)
+				{
+				if (ctx->tmp[jj-1] == '=')
+					{
+					z--;
+					if (ctx->tmp[jj-2] == '=')
+						z--;
+					}
+				}
+			/* z is now number of output bytes and jj is the
+			 * number consumed */
+			if (jj != i)
+				{
+				memmove(ctx->tmp, &ctx->tmp[jj], i-jj);
+				ctx->tmp_len=i-jj;
+				}
+			ctx->buf_len=0;
+			if (z > 0)
+				{
+				ctx->buf_len=z;
+				}
+			i=z;
+			}
+		else
+			{
+			i=EVP_DecodeUpdate(&(ctx->base64),
+				(unsigned char *)ctx->buf,&ctx->buf_len,
+				(unsigned char *)ctx->tmp,i);
+			ctx->tmp_len = 0;
+			}
+		ctx->buf_off=0;
+		if (i < 0)
+			{
+			ret_code=0;
+			ctx->buf_len=0;
+			break;
+			}
+
+		if (ctx->buf_len <= outl)
+			i=ctx->buf_len;
+		else
+			i=outl;
+
+		memcpy(out,ctx->buf,i);
+		ret+=i;
+		ctx->buf_off=i;
+		if (ctx->buf_off == ctx->buf_len)
+			{
+			ctx->buf_len=0;
+			ctx->buf_off=0;
+			}
+		outl-=i;
+		out+=i;
+		}
+	/* BIO_clear_retry_flags(b); */
+	BIO_copy_next_retry(b);
+	return((ret == 0)?ret_code:ret);
+	}
+
+static int b64_write(BIO *b, const char *in, int inl)
+	{
+	int ret=0;
+	int n;
+	int i;
+	BIO_B64_CTX *ctx;
+
+	ctx=(BIO_B64_CTX *)b->ptr;
+	BIO_clear_retry_flags(b);
+
+	if (ctx->encode != B64_ENCODE)
+		{
+		ctx->encode=B64_ENCODE;
+		ctx->buf_len=0;
+		ctx->buf_off=0;
+		ctx->tmp_len=0;
+		EVP_EncodeInit(&(ctx->base64));
+		}
+
+	OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf));
+	OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+	OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+	n=ctx->buf_len-ctx->buf_off;
+	while (n > 0)
+		{
+		i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
+		if (i <= 0)
+			{
+			BIO_copy_next_retry(b);
+			return(i);
+			}
+		OPENSSL_assert(i <= n);
+		ctx->buf_off+=i;
+		OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
+		OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+		n-=i;
+		}
+	/* at this point all pending data has been written */
+	ctx->buf_off=0;
+	ctx->buf_len=0;
+
+	if ((in == NULL) || (inl <= 0)) return(0);
+
+	while (inl > 0)
+		{
+		n=(inl > B64_BLOCK_SIZE)?B64_BLOCK_SIZE:inl;
+
+		if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)
+			{
+			if (ctx->tmp_len > 0)
+				{
+				OPENSSL_assert(ctx->tmp_len <= 3);
+				n=3-ctx->tmp_len;
+				/* There's a theoretical possibility for this */
+				if (n > inl) 
+					n=inl;
+				memcpy(&(ctx->tmp[ctx->tmp_len]),in,n);
+				ctx->tmp_len+=n;
+				ret += n;
+				if (ctx->tmp_len < 3)
+					break;
+				ctx->buf_len=EVP_EncodeBlock((unsigned char *)ctx->buf,(unsigned char *)ctx->tmp,ctx->tmp_len);
+				OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+				OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+				/* Since we're now done using the temporary
+				   buffer, the length should be 0'd */
+				ctx->tmp_len=0;
+				}
+			else
+				{
+				if (n < 3)
+					{
+					memcpy(ctx->tmp,in,n);
+					ctx->tmp_len=n;
+					ret += n;
+					break;
+					}
+				n-=n%3;
+				ctx->buf_len=EVP_EncodeBlock((unsigned char *)ctx->buf,(const unsigned char *)in,n);
+				OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+				OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+				ret += n;
+				}
+			}
+		else
+			{
+			EVP_EncodeUpdate(&(ctx->base64),
+				(unsigned char *)ctx->buf,&ctx->buf_len,
+				(unsigned char *)in,n);
+			OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+			OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+			ret += n;
+			}
+		inl-=n;
+		in+=n;
+
+		ctx->buf_off=0;
+		n=ctx->buf_len;
+		while (n > 0)
+			{
+			i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
+			if (i <= 0)
+				{
+				BIO_copy_next_retry(b);
+				return((ret == 0)?i:ret);
+				}
+			OPENSSL_assert(i <= n);
+			n-=i;
+			ctx->buf_off+=i;
+			OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
+			OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+			}
+		ctx->buf_len=0;
+		ctx->buf_off=0;
+		}
+	return(ret);
+	}
+
+static long b64_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	BIO_B64_CTX *ctx;
+	long ret=1;
+	int i;
+
+	ctx=(BIO_B64_CTX *)b->ptr;
+
+	switch (cmd)
+		{
+	case BIO_CTRL_RESET:
+		ctx->cont=1;
+		ctx->start=1;
+		ctx->encode=B64_NONE;
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_EOF:	/* More to read */
+		if (ctx->cont <= 0)
+			ret=1;
+		else
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_WPENDING: /* More to write in buffer */
+		OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+		ret=ctx->buf_len-ctx->buf_off;
+		if ((ret == 0) && (ctx->encode != B64_NONE)
+			&& (ctx->base64.num != 0))
+			ret=1;
+		else if (ret <= 0)
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_PENDING: /* More to read in buffer */
+		OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+		ret=ctx->buf_len-ctx->buf_off;
+		if (ret <= 0)
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_FLUSH:
+		/* do a final write */
+again:
+		while (ctx->buf_len != ctx->buf_off)
+			{
+			i=b64_write(b,NULL,0);
+			if (i < 0)
+				return i;
+			}
+		if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)
+			{
+			if (ctx->tmp_len != 0)
+				{
+				ctx->buf_len=EVP_EncodeBlock(
+					(unsigned char *)ctx->buf,
+					(unsigned char *)ctx->tmp,
+					ctx->tmp_len);
+				ctx->buf_off=0;
+				ctx->tmp_len=0;
+				goto again;
+				}
+			}
+		else if (ctx->encode != B64_NONE && ctx->base64.num != 0)
+			{
+			ctx->buf_off=0;
+			EVP_EncodeFinal(&(ctx->base64),
+				(unsigned char *)ctx->buf,
+				&(ctx->buf_len));
+			/* push out the bytes */
+			goto again;
+			}
+		/* Finally flush the underlying BIO */
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+
+	case BIO_C_DO_STATE_MACHINE:
+		BIO_clear_retry_flags(b);
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		BIO_copy_next_retry(b);
+		break;
+
+	case BIO_CTRL_DUP:
+		break;
+	case BIO_CTRL_INFO:
+	case BIO_CTRL_GET:
+	case BIO_CTRL_SET:
+	default:
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+		}
+	return(ret);
+	}
+
+static long b64_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+	{
+	long ret=1;
+
+	if (b->next_bio == NULL) return(0);
+	switch (cmd)
+		{
+	default:
+		ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+		break;
+		}
+	return(ret);
+	}
+
+static int b64_puts(BIO *b, const char *str)
+	{
+	return b64_write(b,str,strlen(str));
+	}
diff --git a/openssl/crypto/evp/bio_enc.c b/openssl/crypto/evp/bio_enc.c
new file mode 100644
index 0000000..b6efb5f
--- /dev/null
+++ b/openssl/crypto/evp/bio_enc.c
@@ -0,0 +1,428 @@
+/* crypto/evp/bio_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+
+static int enc_write(BIO *h, const char *buf, int num);
+static int enc_read(BIO *h, char *buf, int size);
+/*static int enc_puts(BIO *h, const char *str); */
+/*static int enc_gets(BIO *h, char *str, int size); */
+static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int enc_new(BIO *h);
+static int enc_free(BIO *data);
+static long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps);
+#define ENC_BLOCK_SIZE	(1024*4)
+#define BUF_OFFSET	(EVP_MAX_BLOCK_LENGTH*2)
+
+typedef struct enc_struct
+	{
+	int buf_len;
+	int buf_off;
+	int cont;		/* <= 0 when finished */
+	int finished;
+	int ok;			/* bad decrypt */
+	EVP_CIPHER_CTX cipher;
+	/* buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate
+	 * can return up to a block more data than is presented to it
+	 */
+	char buf[ENC_BLOCK_SIZE+BUF_OFFSET+2];
+	} BIO_ENC_CTX;
+
+static BIO_METHOD methods_enc=
+	{
+	BIO_TYPE_CIPHER,"cipher",
+	enc_write,
+	enc_read,
+	NULL, /* enc_puts, */
+	NULL, /* enc_gets, */
+	enc_ctrl,
+	enc_new,
+	enc_free,
+	enc_callback_ctrl,
+	};
+
+BIO_METHOD *BIO_f_cipher(void)
+	{
+	return(&methods_enc);
+	}
+
+static int enc_new(BIO *bi)
+	{
+	BIO_ENC_CTX *ctx;
+
+	ctx=(BIO_ENC_CTX *)OPENSSL_malloc(sizeof(BIO_ENC_CTX));
+	if (ctx == NULL) return(0);
+	EVP_CIPHER_CTX_init(&ctx->cipher);
+
+	ctx->buf_len=0;
+	ctx->buf_off=0;
+	ctx->cont=1;
+	ctx->finished=0;
+	ctx->ok=1;
+
+	bi->init=0;
+	bi->ptr=(char *)ctx;
+	bi->flags=0;
+	return(1);
+	}
+
+static int enc_free(BIO *a)
+	{
+	BIO_ENC_CTX *b;
+
+	if (a == NULL) return(0);
+	b=(BIO_ENC_CTX *)a->ptr;
+	EVP_CIPHER_CTX_cleanup(&(b->cipher));
+	OPENSSL_cleanse(a->ptr,sizeof(BIO_ENC_CTX));
+	OPENSSL_free(a->ptr);
+	a->ptr=NULL;
+	a->init=0;
+	a->flags=0;
+	return(1);
+	}
+	
+static int enc_read(BIO *b, char *out, int outl)
+	{
+	int ret=0,i;
+	BIO_ENC_CTX *ctx;
+
+	if (out == NULL) return(0);
+	ctx=(BIO_ENC_CTX *)b->ptr;
+
+	if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
+
+	/* First check if there are bytes decoded/encoded */
+	if (ctx->buf_len > 0)
+		{
+		i=ctx->buf_len-ctx->buf_off;
+		if (i > outl) i=outl;
+		memcpy(out,&(ctx->buf[ctx->buf_off]),i);
+		ret=i;
+		out+=i;
+		outl-=i;
+		ctx->buf_off+=i;
+		if (ctx->buf_len == ctx->buf_off)
+			{
+			ctx->buf_len=0;
+			ctx->buf_off=0;
+			}
+		}
+
+	/* At this point, we have room of outl bytes and an empty
+	 * buffer, so we should read in some more. */
+
+	while (outl > 0)
+		{
+		if (ctx->cont <= 0) break;
+
+		/* read in at IV offset, read the EVP_Cipher
+		 * documentation about why */
+		i=BIO_read(b->next_bio,&(ctx->buf[BUF_OFFSET]),ENC_BLOCK_SIZE);
+
+		if (i <= 0)
+			{
+			/* Should be continue next time we are called? */
+			if (!BIO_should_retry(b->next_bio))
+				{
+				ctx->cont=i;
+				i=EVP_CipherFinal_ex(&(ctx->cipher),
+					(unsigned char *)ctx->buf,
+					&(ctx->buf_len));
+				ctx->ok=i;
+				ctx->buf_off=0;
+				}
+			else 
+				{
+				ret=(ret == 0)?i:ret;
+				break;
+				}
+			}
+		else
+			{
+			EVP_CipherUpdate(&(ctx->cipher),
+				(unsigned char *)ctx->buf,&ctx->buf_len,
+				(unsigned char *)&(ctx->buf[BUF_OFFSET]),i);
+			ctx->cont=1;
+			/* Note: it is possible for EVP_CipherUpdate to
+			 * decrypt zero bytes because this is or looks like
+			 * the final block: if this happens we should retry
+			 * and either read more data or decrypt the final
+			 * block
+			 */
+			if(ctx->buf_len == 0) continue;
+			}
+
+		if (ctx->buf_len <= outl)
+			i=ctx->buf_len;
+		else
+			i=outl;
+		if (i <= 0) break;
+		memcpy(out,ctx->buf,i);
+		ret+=i;
+		ctx->buf_off=i;
+		outl-=i;
+		out+=i;
+		}
+
+	BIO_clear_retry_flags(b);
+	BIO_copy_next_retry(b);
+	return((ret == 0)?ctx->cont:ret);
+	}
+
+static int enc_write(BIO *b, const char *in, int inl)
+	{
+	int ret=0,n,i;
+	BIO_ENC_CTX *ctx;
+
+	ctx=(BIO_ENC_CTX *)b->ptr;
+	ret=inl;
+
+	BIO_clear_retry_flags(b);
+	n=ctx->buf_len-ctx->buf_off;
+	while (n > 0)
+		{
+		i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
+		if (i <= 0)
+			{
+			BIO_copy_next_retry(b);
+			return(i);
+			}
+		ctx->buf_off+=i;
+		n-=i;
+		}
+	/* at this point all pending data has been written */
+
+	if ((in == NULL) || (inl <= 0)) return(0);
+
+	ctx->buf_off=0;
+	while (inl > 0)
+		{
+		n=(inl > ENC_BLOCK_SIZE)?ENC_BLOCK_SIZE:inl;
+		EVP_CipherUpdate(&(ctx->cipher),
+			(unsigned char *)ctx->buf,&ctx->buf_len,
+			(unsigned char *)in,n);
+		inl-=n;
+		in+=n;
+
+		ctx->buf_off=0;
+		n=ctx->buf_len;
+		while (n > 0)
+			{
+			i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
+			if (i <= 0)
+				{
+				BIO_copy_next_retry(b);
+				return (ret == inl) ? i : ret - inl;
+				}
+			n-=i;
+			ctx->buf_off+=i;
+			}
+		ctx->buf_len=0;
+		ctx->buf_off=0;
+		}
+	BIO_copy_next_retry(b);
+	return(ret);
+	}
+
+static long enc_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	BIO *dbio;
+	BIO_ENC_CTX *ctx,*dctx;
+	long ret=1;
+	int i;
+	EVP_CIPHER_CTX **c_ctx;
+
+	ctx=(BIO_ENC_CTX *)b->ptr;
+
+	switch (cmd)
+		{
+	case BIO_CTRL_RESET:
+		ctx->ok=1;
+		ctx->finished=0;
+		EVP_CipherInit_ex(&(ctx->cipher),NULL,NULL,NULL,NULL,
+			ctx->cipher.encrypt);
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_EOF:	/* More to read */
+		if (ctx->cont <= 0)
+			ret=1;
+		else
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_WPENDING:
+		ret=ctx->buf_len-ctx->buf_off;
+		if (ret <= 0)
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_PENDING: /* More to read in buffer */
+		ret=ctx->buf_len-ctx->buf_off;
+		if (ret <= 0)
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_FLUSH:
+		/* do a final write */
+again:
+		while (ctx->buf_len != ctx->buf_off)
+			{
+			i=enc_write(b,NULL,0);
+			if (i < 0)
+				return i;
+			}
+
+		if (!ctx->finished)
+			{
+			ctx->finished=1;
+			ctx->buf_off=0;
+			ret=EVP_CipherFinal_ex(&(ctx->cipher),
+				(unsigned char *)ctx->buf,
+				&(ctx->buf_len));
+			ctx->ok=(int)ret;
+			if (ret <= 0) break;
+
+			/* push out the bytes */
+			goto again;
+			}
+		
+		/* Finally flush the underlying BIO */
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_C_GET_CIPHER_STATUS:
+		ret=(long)ctx->ok;
+		break;
+	case BIO_C_DO_STATE_MACHINE:
+		BIO_clear_retry_flags(b);
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		BIO_copy_next_retry(b);
+		break;
+	case BIO_C_GET_CIPHER_CTX:
+		c_ctx=(EVP_CIPHER_CTX **)ptr;
+		(*c_ctx)= &(ctx->cipher);
+		b->init=1;
+		break;
+	case BIO_CTRL_DUP:
+		dbio=(BIO *)ptr;
+		dctx=(BIO_ENC_CTX *)dbio->ptr;
+		EVP_CIPHER_CTX_init(&dctx->cipher);
+		ret = EVP_CIPHER_CTX_copy(&dctx->cipher,&ctx->cipher);
+		if (ret)
+			dbio->init=1;
+		break;
+	default:
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+		}
+	return(ret);
+	}
+
+static long enc_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+	{
+	long ret=1;
+
+	if (b->next_bio == NULL) return(0);
+	switch (cmd)
+		{
+	default:
+		ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+		break;
+		}
+	return(ret);
+	}
+
+/*
+void BIO_set_cipher_ctx(b,c)
+BIO *b;
+EVP_CIPHER_ctx *c;
+	{
+	if (b == NULL) return;
+
+	if ((b->callback != NULL) &&
+		(b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
+		return;
+
+	b->init=1;
+	ctx=(BIO_ENC_CTX *)b->ptr;
+	memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX));
+	
+	if (b->callback != NULL)
+		b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
+	}
+*/
+
+void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
+	     const unsigned char *i, int e)
+	{
+	BIO_ENC_CTX *ctx;
+
+	if (b == NULL) return;
+
+	if ((b->callback != NULL) &&
+		(b->callback(b,BIO_CB_CTRL,(const char *)c,BIO_CTRL_SET,e,0L) <= 0))
+		return;
+
+	b->init=1;
+	ctx=(BIO_ENC_CTX *)b->ptr;
+	EVP_CipherInit_ex(&(ctx->cipher),c,NULL, k,i,e);
+	
+	if (b->callback != NULL)
+		b->callback(b,BIO_CB_CTRL,(const char *)c,BIO_CTRL_SET,e,1L);
+	}
+
diff --git a/openssl/crypto/evp/bio_md.c b/openssl/crypto/evp/bio_md.c
new file mode 100644
index 0000000..9841e32
--- /dev/null
+++ b/openssl/crypto/evp/bio_md.c
@@ -0,0 +1,270 @@
+/* crypto/evp/bio_md.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+
+/* BIO_put and BIO_get both add to the digest,
+ * BIO_gets returns the digest */
+
+static int md_write(BIO *h, char const *buf, int num);
+static int md_read(BIO *h, char *buf, int size);
+/*static int md_puts(BIO *h, const char *str); */
+static int md_gets(BIO *h, char *str, int size);
+static long md_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int md_new(BIO *h);
+static int md_free(BIO *data);
+static long md_callback_ctrl(BIO *h,int cmd,bio_info_cb *fp);
+
+static BIO_METHOD methods_md=
+	{
+	BIO_TYPE_MD,"message digest",
+	md_write,
+	md_read,
+	NULL, /* md_puts, */
+	md_gets,
+	md_ctrl,
+	md_new,
+	md_free,
+	md_callback_ctrl,
+	};
+
+BIO_METHOD *BIO_f_md(void)
+	{
+	return(&methods_md);
+	}
+
+static int md_new(BIO *bi)
+	{
+	EVP_MD_CTX *ctx;
+
+	ctx=EVP_MD_CTX_create();
+	if (ctx == NULL) return(0);
+
+	bi->init=0;
+	bi->ptr=(char *)ctx;
+	bi->flags=0;
+	return(1);
+	}
+
+static int md_free(BIO *a)
+	{
+	if (a == NULL) return(0);
+	EVP_MD_CTX_destroy(a->ptr);
+	a->ptr=NULL;
+	a->init=0;
+	a->flags=0;
+	return(1);
+	}
+	
+static int md_read(BIO *b, char *out, int outl)
+	{
+	int ret=0;
+	EVP_MD_CTX *ctx;
+
+	if (out == NULL) return(0);
+	ctx=b->ptr;
+
+	if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
+
+	ret=BIO_read(b->next_bio,out,outl);
+	if (b->init)
+		{
+		if (ret > 0)
+			{
+			if (EVP_DigestUpdate(ctx,(unsigned char *)out,
+				(unsigned int)ret)<=0) return (-1);
+			}
+		}
+	BIO_clear_retry_flags(b);
+	BIO_copy_next_retry(b);
+	return(ret);
+	}
+
+static int md_write(BIO *b, const char *in, int inl)
+	{
+	int ret=0;
+	EVP_MD_CTX *ctx;
+
+	if ((in == NULL) || (inl <= 0)) return(0);
+	ctx=b->ptr;
+
+	if ((ctx != NULL) && (b->next_bio != NULL))
+		ret=BIO_write(b->next_bio,in,inl);
+	if (b->init)
+		{
+		if (ret > 0)
+			{
+			EVP_DigestUpdate(ctx,(const unsigned char *)in,
+				(unsigned int)ret);
+			}
+		}
+	if(b->next_bio != NULL)
+		{
+		BIO_clear_retry_flags(b);
+		BIO_copy_next_retry(b);
+		}
+	return(ret);
+	}
+
+static long md_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	EVP_MD_CTX *ctx,*dctx,**pctx;
+	const EVP_MD **ppmd;
+	EVP_MD *md;
+	long ret=1;
+	BIO *dbio;
+
+	ctx=b->ptr;
+
+	switch (cmd)
+		{
+	case BIO_CTRL_RESET:
+		if (b->init)
+			ret = EVP_DigestInit_ex(ctx,ctx->digest, NULL);
+		else
+			ret=0;
+		if (ret > 0)
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_C_GET_MD:
+		if (b->init)
+			{
+			ppmd=ptr;
+			*ppmd=ctx->digest;
+			}
+		else
+			ret=0;
+		break;
+	case BIO_C_GET_MD_CTX:
+		pctx=ptr;
+		*pctx=ctx;
+		b->init = 1;
+		break;
+	case BIO_C_SET_MD_CTX:
+		if (b->init)
+			b->ptr=ptr;
+		else
+			ret=0;
+		break;
+	case BIO_C_DO_STATE_MACHINE:
+		BIO_clear_retry_flags(b);
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		BIO_copy_next_retry(b);
+		break;
+
+	case BIO_C_SET_MD:
+		md=ptr;
+		ret = EVP_DigestInit_ex(ctx,md, NULL);
+		if (ret > 0)
+			b->init=1;
+		break;
+	case BIO_CTRL_DUP:
+		dbio=ptr;
+		dctx=dbio->ptr;
+		EVP_MD_CTX_copy_ex(dctx,ctx);
+		b->init=1;
+		break;
+	default:
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+		}
+	return(ret);
+	}
+
+static long md_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+	{
+	long ret=1;
+
+	if (b->next_bio == NULL) return(0);
+	switch (cmd)
+		{
+	default:
+		ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+		break;
+		}
+	return(ret);
+	}
+
+static int md_gets(BIO *bp, char *buf, int size)
+	{
+	EVP_MD_CTX *ctx;
+	unsigned int ret;
+
+
+	ctx=bp->ptr;
+	if (size < ctx->digest->md_size)
+		return(0);
+	if (EVP_DigestFinal_ex(ctx,(unsigned char *)buf,&ret)<=0) 
+		return -1;
+		
+	return((int)ret);
+	}
+
+/*
+static int md_puts(bp,str)
+BIO *bp;
+char *str;
+	{
+	return(-1);
+	}
+*/
+
diff --git a/openssl/crypto/evp/bio_ok.c b/openssl/crypto/evp/bio_ok.c
new file mode 100644
index 0000000..98bc1ab
--- /dev/null
+++ b/openssl/crypto/evp/bio_ok.c
@@ -0,0 +1,575 @@
+/* crypto/evp/bio_ok.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*
+	From: Arne Ansper <arne@cyber.ee>
+
+	Why BIO_f_reliable?
+
+	I wrote function which took BIO* as argument, read data from it
+	and processed it. Then I wanted to store the input file in 
+	encrypted form. OK I pushed BIO_f_cipher to the BIO stack
+	and everything was OK. BUT if user types wrong password 
+	BIO_f_cipher outputs only garbage and my function crashes. Yes
+	I can and I should fix my function, but BIO_f_cipher is 
+	easy way to add encryption support to many existing applications
+	and it's hard to debug and fix them all. 
+
+	So I wanted another BIO which would catch the incorrect passwords and
+	file damages which cause garbage on BIO_f_cipher's output. 
+
+	The easy way is to push the BIO_f_md and save the checksum at 
+	the end of the file. However there are several problems with this
+	approach:
+
+	1) you must somehow separate checksum from actual data. 
+	2) you need lot's of memory when reading the file, because you 
+	must read to the end of the file and verify the checksum before
+	letting the application to read the data. 
+	
+	BIO_f_reliable tries to solve both problems, so that you can 
+	read and write arbitrary long streams using only fixed amount
+	of memory.
+
+	BIO_f_reliable splits data stream into blocks. Each block is prefixed
+	with it's length and suffixed with it's digest. So you need only 
+	several Kbytes of memory to buffer single block before verifying 
+	it's digest. 
+
+	BIO_f_reliable goes further and adds several important capabilities:
+
+	1) the digest of the block is computed over the whole stream 
+	-- so nobody can rearrange the blocks or remove or replace them.
+
+	2) to detect invalid passwords right at the start BIO_f_reliable 
+	adds special prefix to the stream. In order to avoid known plain-text
+	attacks this prefix is generated as follows:
+
+		*) digest is initialized with random seed instead of 
+		standardized one.
+		*) same seed is written to output
+		*) well-known text is then hashed and the output 
+		of the digest is also written to output.
+
+	reader can now read the seed from stream, hash the same string
+	and then compare the digest output.
+
+	Bad things: BIO_f_reliable knows what's going on in EVP_Digest. I 
+	initially wrote and tested this code on x86 machine and wrote the
+	digests out in machine-dependent order :( There are people using
+	this code and I cannot change this easily without making existing
+	data files unreadable.
+
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <assert.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+
+static int ok_write(BIO *h, const char *buf, int num);
+static int ok_read(BIO *h, char *buf, int size);
+static long ok_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int ok_new(BIO *h);
+static int ok_free(BIO *data);
+static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+static void sig_out(BIO* b);
+static void sig_in(BIO* b);
+static void block_out(BIO* b);
+static void block_in(BIO* b);
+#define OK_BLOCK_SIZE	(1024*4)
+#define OK_BLOCK_BLOCK	4
+#define IOBS		(OK_BLOCK_SIZE+ OK_BLOCK_BLOCK+ 3*EVP_MAX_MD_SIZE)
+#define WELLKNOWN "The quick brown fox jumped over the lazy dog's back."
+
+typedef struct ok_struct
+	{
+	size_t buf_len;
+	size_t buf_off;
+	size_t buf_len_save;
+	size_t buf_off_save;
+	int cont;		/* <= 0 when finished */
+	int finished;
+	EVP_MD_CTX md;
+	int blockout;		/* output block is ready */ 
+	int sigio;		/* must process signature */
+	unsigned char buf[IOBS];
+	} BIO_OK_CTX;
+
+static BIO_METHOD methods_ok=
+	{
+	BIO_TYPE_CIPHER,"reliable",
+	ok_write,
+	ok_read,
+	NULL, /* ok_puts, */
+	NULL, /* ok_gets, */
+	ok_ctrl,
+	ok_new,
+	ok_free,
+	ok_callback_ctrl,
+	};
+
+BIO_METHOD *BIO_f_reliable(void)
+	{
+	return(&methods_ok);
+	}
+
+static int ok_new(BIO *bi)
+	{
+	BIO_OK_CTX *ctx;
+
+	ctx=(BIO_OK_CTX *)OPENSSL_malloc(sizeof(BIO_OK_CTX));
+	if (ctx == NULL) return(0);
+
+	ctx->buf_len=0;
+	ctx->buf_off=0;
+	ctx->buf_len_save=0;
+	ctx->buf_off_save=0;
+	ctx->cont=1;
+	ctx->finished=0;
+	ctx->blockout= 0;
+	ctx->sigio=1;
+
+	EVP_MD_CTX_init(&ctx->md);
+
+	bi->init=0;
+	bi->ptr=(char *)ctx;
+	bi->flags=0;
+	return(1);
+	}
+
+static int ok_free(BIO *a)
+	{
+	if (a == NULL) return(0);
+	EVP_MD_CTX_cleanup(&((BIO_OK_CTX *)a->ptr)->md);
+	OPENSSL_cleanse(a->ptr,sizeof(BIO_OK_CTX));
+	OPENSSL_free(a->ptr);
+	a->ptr=NULL;
+	a->init=0;
+	a->flags=0;
+	return(1);
+	}
+	
+static int ok_read(BIO *b, char *out, int outl)
+	{
+	int ret=0,i,n;
+	BIO_OK_CTX *ctx;
+
+	if (out == NULL) return(0);
+	ctx=(BIO_OK_CTX *)b->ptr;
+
+	if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) return(0);
+
+	while(outl > 0)
+		{
+
+		/* copy clean bytes to output buffer */
+		if (ctx->blockout)
+			{
+			i=ctx->buf_len-ctx->buf_off;
+			if (i > outl) i=outl;
+			memcpy(out,&(ctx->buf[ctx->buf_off]),i);
+			ret+=i;
+			out+=i;
+			outl-=i;
+			ctx->buf_off+=i;
+
+			/* all clean bytes are out */
+			if (ctx->buf_len == ctx->buf_off)
+				{
+				ctx->buf_off=0;
+
+				/* copy start of the next block into proper place */
+				if(ctx->buf_len_save- ctx->buf_off_save > 0)
+					{
+					ctx->buf_len= ctx->buf_len_save- ctx->buf_off_save;
+					memmove(ctx->buf, &(ctx->buf[ctx->buf_off_save]),
+							ctx->buf_len);
+					}
+				else
+					{
+					ctx->buf_len=0;
+					}
+				ctx->blockout= 0;
+				}
+			}
+	
+		/* output buffer full -- cancel */
+		if (outl == 0) break;
+
+		/* no clean bytes in buffer -- fill it */
+		n=IOBS- ctx->buf_len;
+		i=BIO_read(b->next_bio,&(ctx->buf[ctx->buf_len]),n);
+
+		if (i <= 0) break;	/* nothing new */
+
+		ctx->buf_len+= i;
+
+		/* no signature yet -- check if we got one */
+		if (ctx->sigio == 1) sig_in(b);
+
+		/* signature ok -- check if we got block */
+		if (ctx->sigio == 0) block_in(b);
+
+		/* invalid block -- cancel */
+		if (ctx->cont <= 0) break;
+
+		}
+
+	BIO_clear_retry_flags(b);
+	BIO_copy_next_retry(b);
+	return(ret);
+	}
+
+static int ok_write(BIO *b, const char *in, int inl)
+	{
+	int ret=0,n,i;
+	BIO_OK_CTX *ctx;
+
+	if (inl <= 0) return inl;
+
+	ctx=(BIO_OK_CTX *)b->ptr;
+	ret=inl;
+
+	if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) return(0);
+
+	if(ctx->sigio) sig_out(b);
+
+	do{
+		BIO_clear_retry_flags(b);
+		n=ctx->buf_len-ctx->buf_off;
+		while (ctx->blockout && n > 0)
+			{
+			i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
+			if (i <= 0)
+				{
+				BIO_copy_next_retry(b);
+				if(!BIO_should_retry(b))
+					ctx->cont= 0;
+				return(i);
+				}
+			ctx->buf_off+=i;
+			n-=i;
+			}
+
+		/* at this point all pending data has been written */
+		ctx->blockout= 0;
+		if (ctx->buf_len == ctx->buf_off)
+			{
+			ctx->buf_len=OK_BLOCK_BLOCK;
+			ctx->buf_off=0;
+			}
+	
+		if ((in == NULL) || (inl <= 0)) return(0);
+
+		n= (inl+ ctx->buf_len > OK_BLOCK_SIZE+ OK_BLOCK_BLOCK) ? 
+			(int)(OK_BLOCK_SIZE+OK_BLOCK_BLOCK-ctx->buf_len) : inl;
+
+		memcpy((unsigned char *)(&(ctx->buf[ctx->buf_len])),(unsigned char *)in,n);
+		ctx->buf_len+= n;
+		inl-=n;
+		in+=n;
+
+		if(ctx->buf_len >= OK_BLOCK_SIZE+ OK_BLOCK_BLOCK)
+			{
+			block_out(b);
+			}
+	}while(inl > 0);
+
+	BIO_clear_retry_flags(b);
+	BIO_copy_next_retry(b);
+	return(ret);
+	}
+
+static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	BIO_OK_CTX *ctx;
+	EVP_MD *md;
+	const EVP_MD **ppmd;
+	long ret=1;
+	int i;
+
+	ctx=b->ptr;
+
+	switch (cmd)
+		{
+	case BIO_CTRL_RESET:
+		ctx->buf_len=0;
+		ctx->buf_off=0;
+		ctx->buf_len_save=0;
+		ctx->buf_off_save=0;
+		ctx->cont=1;
+		ctx->finished=0;
+		ctx->blockout= 0;
+		ctx->sigio=1;
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_EOF:	/* More to read */
+		if (ctx->cont <= 0)
+			ret=1;
+		else
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_PENDING: /* More to read in buffer */
+	case BIO_CTRL_WPENDING: /* More to read in buffer */
+		ret=ctx->blockout ? ctx->buf_len-ctx->buf_off : 0;
+		if (ret <= 0)
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_FLUSH:
+		/* do a final write */
+		if(ctx->blockout == 0)
+			block_out(b);
+
+		while (ctx->blockout)
+			{
+			i=ok_write(b,NULL,0);
+			if (i < 0)
+				{
+				ret=i;
+				break;
+				}
+			}
+
+		ctx->finished=1;
+		ctx->buf_off=ctx->buf_len=0;
+		ctx->cont=(int)ret;
+		
+		/* Finally flush the underlying BIO */
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_C_DO_STATE_MACHINE:
+		BIO_clear_retry_flags(b);
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		BIO_copy_next_retry(b);
+		break;
+	case BIO_CTRL_INFO:
+		ret=(long)ctx->cont;
+		break;
+	case BIO_C_SET_MD:
+		md=ptr;
+		EVP_DigestInit_ex(&ctx->md, md, NULL);
+		b->init=1;
+		break;
+	case BIO_C_GET_MD:
+		if (b->init)
+			{
+			ppmd=ptr;
+			*ppmd=ctx->md.digest;
+			}
+		else
+			ret=0;
+		break;
+	default:
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+		}
+	return(ret);
+	}
+
+static long ok_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+	{
+	long ret=1;
+
+	if (b->next_bio == NULL) return(0);
+	switch (cmd)
+		{
+	default:
+		ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+		break;
+		}
+	return(ret);
+	}
+
+static void longswap(void *_ptr, size_t len)
+{	const union { long one; char little; } is_endian = {1};
+
+	if (is_endian.little) {
+		size_t i;
+		unsigned char *p=_ptr,c;
+
+		for(i= 0;i < len;i+= 4) {
+			c=p[0],p[0]=p[3],p[3]=c;
+			c=p[1],p[1]=p[2],p[2]=c;
+		}
+	}
+}
+
+static void sig_out(BIO* b)
+	{
+	BIO_OK_CTX *ctx;
+	EVP_MD_CTX *md;
+
+	ctx=b->ptr;
+	md=&ctx->md;
+
+	if(ctx->buf_len+ 2* md->digest->md_size > OK_BLOCK_SIZE) return;
+
+	EVP_DigestInit_ex(md, md->digest, NULL);
+	/* FIXME: there's absolutely no guarantee this makes any sense at all,
+	 * particularly now EVP_MD_CTX has been restructured.
+	 */
+	RAND_pseudo_bytes(md->md_data, md->digest->md_size);
+	memcpy(&(ctx->buf[ctx->buf_len]), md->md_data, md->digest->md_size);
+	longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size);
+	ctx->buf_len+= md->digest->md_size;
+
+	EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN));
+	EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL);
+	ctx->buf_len+= md->digest->md_size;
+	ctx->blockout= 1;
+	ctx->sigio= 0;
+	}
+
+static void sig_in(BIO* b)
+	{
+	BIO_OK_CTX *ctx;
+	EVP_MD_CTX *md;
+	unsigned char tmp[EVP_MAX_MD_SIZE];
+	int ret= 0;
+
+	ctx=b->ptr;
+	md=&ctx->md;
+
+	if((int)(ctx->buf_len-ctx->buf_off) < 2*md->digest->md_size) return;
+
+	EVP_DigestInit_ex(md, md->digest, NULL);
+	memcpy(md->md_data, &(ctx->buf[ctx->buf_off]), md->digest->md_size);
+	longswap(md->md_data, md->digest->md_size);
+	ctx->buf_off+= md->digest->md_size;
+
+	EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN));
+	EVP_DigestFinal_ex(md, tmp, NULL);
+	ret= memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0;
+	ctx->buf_off+= md->digest->md_size;
+	if(ret == 1)
+		{
+		ctx->sigio= 0;
+		if(ctx->buf_len != ctx->buf_off)
+			{
+			memmove(ctx->buf, &(ctx->buf[ctx->buf_off]), ctx->buf_len- ctx->buf_off);
+			}
+		ctx->buf_len-= ctx->buf_off;
+		ctx->buf_off= 0;
+		}
+	else
+		{
+		ctx->cont= 0;
+		}
+	}
+
+static void block_out(BIO* b)
+	{
+	BIO_OK_CTX *ctx;
+	EVP_MD_CTX *md;
+	unsigned long tl;
+
+	ctx=b->ptr;
+	md=&ctx->md;
+
+	tl= ctx->buf_len- OK_BLOCK_BLOCK;
+	ctx->buf[0]=(unsigned char)(tl>>24);
+	ctx->buf[1]=(unsigned char)(tl>>16);
+	ctx->buf[2]=(unsigned char)(tl>>8);
+	ctx->buf[3]=(unsigned char)(tl);
+	EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl);
+	EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL);
+	ctx->buf_len+= md->digest->md_size;
+	ctx->blockout= 1;
+	}
+
+static void block_in(BIO* b)
+	{
+	BIO_OK_CTX *ctx;
+	EVP_MD_CTX *md;
+	unsigned long tl= 0;
+	unsigned char tmp[EVP_MAX_MD_SIZE];
+
+	ctx=b->ptr;
+	md=&ctx->md;
+
+	assert(sizeof(tl)>=OK_BLOCK_BLOCK);	/* always true */
+	tl =ctx->buf[0]; tl<<=8;
+	tl|=ctx->buf[1]; tl<<=8;
+	tl|=ctx->buf[2]; tl<<=8;
+	tl|=ctx->buf[3];
+
+	if (ctx->buf_len < tl+ OK_BLOCK_BLOCK+ md->digest->md_size) return;
+ 
+	EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl);
+	EVP_DigestFinal_ex(md, tmp, NULL);
+	if(memcmp(&(ctx->buf[tl+ OK_BLOCK_BLOCK]), tmp, md->digest->md_size) == 0)
+		{
+		/* there might be parts from next block lurking around ! */
+		ctx->buf_off_save= tl+ OK_BLOCK_BLOCK+ md->digest->md_size;
+		ctx->buf_len_save= ctx->buf_len;
+		ctx->buf_off= OK_BLOCK_BLOCK;
+		ctx->buf_len= tl+ OK_BLOCK_BLOCK;
+		ctx->blockout= 1;
+		}
+	else
+		{
+		ctx->cont= 0;
+		}
+	}
+
diff --git a/openssl/crypto/evp/c_all.c b/openssl/crypto/evp/c_all.c
new file mode 100644
index 0000000..766c4ce
--- /dev/null
+++ b/openssl/crypto/evp/c_all.c
@@ -0,0 +1,90 @@
+/* crypto/evp/c_all.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+#if 0
+#undef OpenSSL_add_all_algorithms
+
+void OpenSSL_add_all_algorithms(void)
+	{
+	OPENSSL_add_all_algorithms_noconf();
+	}
+#endif
+
+void OPENSSL_add_all_algorithms_noconf(void)
+	{
+	/*
+	 * For the moment OPENSSL_cpuid_setup does something
+	 * only on IA-32, but we reserve the option for all
+	 * platforms...
+	 */
+	OPENSSL_cpuid_setup();
+	OpenSSL_add_all_ciphers();
+	OpenSSL_add_all_digests();
+#ifndef OPENSSL_NO_ENGINE
+# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
+	ENGINE_setup_bsd_cryptodev();
+# endif
+#endif
+	}
diff --git a/openssl/crypto/evp/c_allc.c b/openssl/crypto/evp/c_allc.c
new file mode 100644
index 0000000..c5f9268
--- /dev/null
+++ b/openssl/crypto/evp/c_allc.c
@@ -0,0 +1,224 @@
+/* crypto/evp/c_allc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/pkcs12.h>
+#include <openssl/objects.h>
+
+void OpenSSL_add_all_ciphers(void)
+	{
+
+#ifndef OPENSSL_NO_DES
+	EVP_add_cipher(EVP_des_cfb());
+	EVP_add_cipher(EVP_des_cfb1());
+	EVP_add_cipher(EVP_des_cfb8());
+	EVP_add_cipher(EVP_des_ede_cfb());
+	EVP_add_cipher(EVP_des_ede3_cfb());
+	EVP_add_cipher(EVP_des_ede3_cfb1());
+	EVP_add_cipher(EVP_des_ede3_cfb8());
+
+	EVP_add_cipher(EVP_des_ofb());
+	EVP_add_cipher(EVP_des_ede_ofb());
+	EVP_add_cipher(EVP_des_ede3_ofb());
+
+	EVP_add_cipher(EVP_desx_cbc());
+	EVP_add_cipher_alias(SN_desx_cbc,"DESX");
+	EVP_add_cipher_alias(SN_desx_cbc,"desx");
+
+	EVP_add_cipher(EVP_des_cbc());
+	EVP_add_cipher_alias(SN_des_cbc,"DES");
+	EVP_add_cipher_alias(SN_des_cbc,"des");
+	EVP_add_cipher(EVP_des_ede_cbc());
+	EVP_add_cipher(EVP_des_ede3_cbc());
+	EVP_add_cipher_alias(SN_des_ede3_cbc,"DES3");
+	EVP_add_cipher_alias(SN_des_ede3_cbc,"des3");
+
+	EVP_add_cipher(EVP_des_ecb());
+	EVP_add_cipher(EVP_des_ede());
+	EVP_add_cipher(EVP_des_ede3());
+#endif
+
+#ifndef OPENSSL_NO_RC4
+	EVP_add_cipher(EVP_rc4());
+	EVP_add_cipher(EVP_rc4_40());
+#endif
+
+#ifndef OPENSSL_NO_IDEA
+	EVP_add_cipher(EVP_idea_ecb());
+	EVP_add_cipher(EVP_idea_cfb());
+	EVP_add_cipher(EVP_idea_ofb());
+	EVP_add_cipher(EVP_idea_cbc());
+	EVP_add_cipher_alias(SN_idea_cbc,"IDEA");
+	EVP_add_cipher_alias(SN_idea_cbc,"idea");
+#endif
+
+#ifndef OPENSSL_NO_SEED
+	EVP_add_cipher(EVP_seed_ecb());
+	EVP_add_cipher(EVP_seed_cfb());
+	EVP_add_cipher(EVP_seed_ofb());
+	EVP_add_cipher(EVP_seed_cbc());
+	EVP_add_cipher_alias(SN_seed_cbc,"SEED");
+	EVP_add_cipher_alias(SN_seed_cbc,"seed");
+#endif
+
+#ifndef OPENSSL_NO_RC2
+	EVP_add_cipher(EVP_rc2_ecb());
+	EVP_add_cipher(EVP_rc2_cfb());
+	EVP_add_cipher(EVP_rc2_ofb());
+	EVP_add_cipher(EVP_rc2_cbc());
+	EVP_add_cipher(EVP_rc2_40_cbc());
+	EVP_add_cipher(EVP_rc2_64_cbc());
+	EVP_add_cipher_alias(SN_rc2_cbc,"RC2");
+	EVP_add_cipher_alias(SN_rc2_cbc,"rc2");
+#endif
+
+#ifndef OPENSSL_NO_BF
+	EVP_add_cipher(EVP_bf_ecb());
+	EVP_add_cipher(EVP_bf_cfb());
+	EVP_add_cipher(EVP_bf_ofb());
+	EVP_add_cipher(EVP_bf_cbc());
+	EVP_add_cipher_alias(SN_bf_cbc,"BF");
+	EVP_add_cipher_alias(SN_bf_cbc,"bf");
+	EVP_add_cipher_alias(SN_bf_cbc,"blowfish");
+#endif
+
+#ifndef OPENSSL_NO_CAST
+	EVP_add_cipher(EVP_cast5_ecb());
+	EVP_add_cipher(EVP_cast5_cfb());
+	EVP_add_cipher(EVP_cast5_ofb());
+	EVP_add_cipher(EVP_cast5_cbc());
+	EVP_add_cipher_alias(SN_cast5_cbc,"CAST");
+	EVP_add_cipher_alias(SN_cast5_cbc,"cast");
+	EVP_add_cipher_alias(SN_cast5_cbc,"CAST-cbc");
+	EVP_add_cipher_alias(SN_cast5_cbc,"cast-cbc");
+#endif
+
+#ifndef OPENSSL_NO_RC5
+	EVP_add_cipher(EVP_rc5_32_12_16_ecb());
+	EVP_add_cipher(EVP_rc5_32_12_16_cfb());
+	EVP_add_cipher(EVP_rc5_32_12_16_ofb());
+	EVP_add_cipher(EVP_rc5_32_12_16_cbc());
+	EVP_add_cipher_alias(SN_rc5_cbc,"rc5");
+	EVP_add_cipher_alias(SN_rc5_cbc,"RC5");
+#endif
+
+#ifndef OPENSSL_NO_AES
+	EVP_add_cipher(EVP_aes_128_ecb());
+	EVP_add_cipher(EVP_aes_128_cbc());
+	EVP_add_cipher(EVP_aes_128_cfb());
+	EVP_add_cipher(EVP_aes_128_cfb1());
+	EVP_add_cipher(EVP_aes_128_cfb8());
+	EVP_add_cipher(EVP_aes_128_ofb());
+#if 0
+	EVP_add_cipher(EVP_aes_128_ctr());
+#endif
+	EVP_add_cipher_alias(SN_aes_128_cbc,"AES128");
+	EVP_add_cipher_alias(SN_aes_128_cbc,"aes128");
+	EVP_add_cipher(EVP_aes_192_ecb());
+	EVP_add_cipher(EVP_aes_192_cbc());
+	EVP_add_cipher(EVP_aes_192_cfb());
+	EVP_add_cipher(EVP_aes_192_cfb1());
+	EVP_add_cipher(EVP_aes_192_cfb8());
+	EVP_add_cipher(EVP_aes_192_ofb());
+#if 0
+	EVP_add_cipher(EVP_aes_192_ctr());
+#endif
+	EVP_add_cipher_alias(SN_aes_192_cbc,"AES192");
+	EVP_add_cipher_alias(SN_aes_192_cbc,"aes192");
+	EVP_add_cipher(EVP_aes_256_ecb());
+	EVP_add_cipher(EVP_aes_256_cbc());
+	EVP_add_cipher(EVP_aes_256_cfb());
+	EVP_add_cipher(EVP_aes_256_cfb1());
+	EVP_add_cipher(EVP_aes_256_cfb8());
+	EVP_add_cipher(EVP_aes_256_ofb());
+#if 0
+	EVP_add_cipher(EVP_aes_256_ctr());
+#endif
+	EVP_add_cipher_alias(SN_aes_256_cbc,"AES256");
+	EVP_add_cipher_alias(SN_aes_256_cbc,"aes256");
+#endif
+
+#ifndef OPENSSL_NO_CAMELLIA
+	EVP_add_cipher(EVP_camellia_128_ecb());
+	EVP_add_cipher(EVP_camellia_128_cbc());
+	EVP_add_cipher(EVP_camellia_128_cfb());
+	EVP_add_cipher(EVP_camellia_128_cfb1());
+	EVP_add_cipher(EVP_camellia_128_cfb8());
+	EVP_add_cipher(EVP_camellia_128_ofb());
+	EVP_add_cipher_alias(SN_camellia_128_cbc,"CAMELLIA128");
+	EVP_add_cipher_alias(SN_camellia_128_cbc,"camellia128");
+	EVP_add_cipher(EVP_camellia_192_ecb());
+	EVP_add_cipher(EVP_camellia_192_cbc());
+	EVP_add_cipher(EVP_camellia_192_cfb());
+	EVP_add_cipher(EVP_camellia_192_cfb1());
+	EVP_add_cipher(EVP_camellia_192_cfb8());
+	EVP_add_cipher(EVP_camellia_192_ofb());
+	EVP_add_cipher_alias(SN_camellia_192_cbc,"CAMELLIA192");
+	EVP_add_cipher_alias(SN_camellia_192_cbc,"camellia192");
+	EVP_add_cipher(EVP_camellia_256_ecb());
+	EVP_add_cipher(EVP_camellia_256_cbc());
+	EVP_add_cipher(EVP_camellia_256_cfb());
+	EVP_add_cipher(EVP_camellia_256_cfb1());
+	EVP_add_cipher(EVP_camellia_256_cfb8());
+	EVP_add_cipher(EVP_camellia_256_ofb());
+	EVP_add_cipher_alias(SN_camellia_256_cbc,"CAMELLIA256");
+	EVP_add_cipher_alias(SN_camellia_256_cbc,"camellia256");
+#endif
+	}
diff --git a/openssl/crypto/evp/c_alld.c b/openssl/crypto/evp/c_alld.c
new file mode 100644
index 0000000..311e1fe
--- /dev/null
+++ b/openssl/crypto/evp/c_alld.c
@@ -0,0 +1,114 @@
+/* crypto/evp/c_alld.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/pkcs12.h>
+#include <openssl/objects.h>
+
+void OpenSSL_add_all_digests(void)
+	{
+#ifndef OPENSSL_NO_MD4
+	EVP_add_digest(EVP_md4());
+#endif
+#ifndef OPENSSL_NO_MD5
+	EVP_add_digest(EVP_md5());
+	EVP_add_digest_alias(SN_md5,"ssl2-md5");
+	EVP_add_digest_alias(SN_md5,"ssl3-md5");
+#endif
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0)
+	EVP_add_digest(EVP_sha());
+#ifndef OPENSSL_NO_DSA
+	EVP_add_digest(EVP_dss());
+#endif
+#endif
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+	EVP_add_digest(EVP_sha1());
+	EVP_add_digest_alias(SN_sha1,"ssl3-sha1");
+	EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA);
+#ifndef OPENSSL_NO_DSA
+	EVP_add_digest(EVP_dss1());
+	EVP_add_digest_alias(SN_dsaWithSHA1,SN_dsaWithSHA1_2);
+	EVP_add_digest_alias(SN_dsaWithSHA1,"DSS1");
+	EVP_add_digest_alias(SN_dsaWithSHA1,"dss1");
+#endif
+#ifndef OPENSSL_NO_ECDSA
+	EVP_add_digest(EVP_ecdsa());
+#endif
+#endif
+#if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES)
+	EVP_add_digest(EVP_mdc2());
+#endif
+#ifndef OPENSSL_NO_RIPEMD
+	EVP_add_digest(EVP_ripemd160());
+	EVP_add_digest_alias(SN_ripemd160,"ripemd");
+	EVP_add_digest_alias(SN_ripemd160,"rmd160");
+#endif
+#ifndef OPENSSL_NO_SHA256
+	EVP_add_digest(EVP_sha224());
+	EVP_add_digest(EVP_sha256());
+#endif
+#ifndef OPENSSL_NO_SHA512
+	EVP_add_digest(EVP_sha384());
+	EVP_add_digest(EVP_sha512());
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+	EVP_add_digest(EVP_whirlpool());
+#endif
+	}
diff --git a/openssl/crypto/evp/digest.c b/openssl/crypto/evp/digest.c
new file mode 100644
index 0000000..982ba2b
--- /dev/null
+++ b/openssl/crypto/evp/digest.c
@@ -0,0 +1,377 @@
+/* crypto/evp/digest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
+	{
+	memset(ctx,'\0',sizeof *ctx);
+	}
+
+EVP_MD_CTX *EVP_MD_CTX_create(void)
+	{
+	EVP_MD_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
+
+	if (ctx)
+		EVP_MD_CTX_init(ctx);
+
+	return ctx;
+	}
+
+int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
+	{
+	EVP_MD_CTX_init(ctx);
+	return EVP_DigestInit_ex(ctx, type, NULL);
+	}
+
+int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
+	{
+	EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
+#ifndef OPENSSL_NO_ENGINE
+	/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
+	 * so this context may already have an ENGINE! Try to avoid releasing
+	 * the previous handle, re-querying for an ENGINE, and having a
+	 * reinitialisation, when it may all be unecessary. */
+	if (ctx->engine && ctx->digest && (!type ||
+			(type && (type->type == ctx->digest->type))))
+		goto skip_to_init;
+	if (type)
+		{
+		/* Ensure an ENGINE left lying around from last time is cleared
+		 * (the previous check attempted to avoid this if the same
+		 * ENGINE and EVP_MD could be used). */
+		if(ctx->engine)
+			ENGINE_finish(ctx->engine);
+		if(impl)
+			{
+			if (!ENGINE_init(impl))
+				{
+				EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR);
+				return 0;
+				}
+			}
+		else
+			/* Ask if an ENGINE is reserved for this job */
+			impl = ENGINE_get_digest_engine(type->type);
+		if(impl)
+			{
+			/* There's an ENGINE for this job ... (apparently) */
+			const EVP_MD *d = ENGINE_get_digest(impl, type->type);
+			if(!d)
+				{
+				/* Same comment from evp_enc.c */
+				EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR);
+				ENGINE_finish(impl);
+				return 0;
+				}
+			/* We'll use the ENGINE's private digest definition */
+			type = d;
+			/* Store the ENGINE functional reference so we know
+			 * 'type' came from an ENGINE and we need to release
+			 * it when done. */
+			ctx->engine = impl;
+			}
+		else
+			ctx->engine = NULL;
+		}
+	else
+	if(!ctx->digest)
+		{
+		EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_NO_DIGEST_SET);
+		return 0;
+		}
+#endif
+	if (ctx->digest != type)
+		{
+		if (ctx->digest && ctx->digest->ctx_size)
+			OPENSSL_free(ctx->md_data);
+		ctx->digest=type;
+		if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size)
+			{
+			ctx->update = type->update;
+			ctx->md_data=OPENSSL_malloc(type->ctx_size);
+			if (ctx->md_data == NULL)
+				{
+				EVPerr(EVP_F_EVP_DIGESTINIT_EX,
+							ERR_R_MALLOC_FAILURE);
+				return 0;
+				}
+			}
+		}
+#ifndef OPENSSL_NO_ENGINE
+skip_to_init:
+#endif
+	if (ctx->pctx)
+		{
+		int r;
+		r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
+					EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
+		if (r <= 0 && (r != -2))
+			return 0;
+		}
+	if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
+		return 1;
+	return ctx->digest->init(ctx);
+	}
+
+int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
+	{
+	return ctx->update(ctx,data,count);
+	}
+
+/* The caller can assume that this removes any secret data from the context */
+int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
+	{
+	int ret;
+	ret = EVP_DigestFinal_ex(ctx, md, size);
+	EVP_MD_CTX_cleanup(ctx);
+	return ret;
+	}
+
+/* The caller can assume that this removes any secret data from the context */
+int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
+	{
+	int ret;
+
+	OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
+	ret=ctx->digest->final(ctx,md);
+	if (size != NULL)
+		*size=ctx->digest->md_size;
+	if (ctx->digest->cleanup)
+		{
+		ctx->digest->cleanup(ctx);
+		EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
+		}
+	memset(ctx->md_data,0,ctx->digest->ctx_size);
+	return ret;
+	}
+
+int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
+	{
+	EVP_MD_CTX_init(out);
+	return EVP_MD_CTX_copy_ex(out, in);
+	}
+
+int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
+	{
+	unsigned char *tmp_buf;
+	if ((in == NULL) || (in->digest == NULL))
+		{
+		EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,EVP_R_INPUT_NOT_INITIALIZED);
+		return 0;
+		}
+#ifndef OPENSSL_NO_ENGINE
+	/* Make sure it's safe to copy a digest context using an ENGINE */
+	if (in->engine && !ENGINE_init(in->engine))
+		{
+		EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_ENGINE_LIB);
+		return 0;
+		}
+#endif
+
+	if (out->digest == in->digest)
+		{
+		tmp_buf = out->md_data;
+	    	EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE);
+		}
+	else tmp_buf = NULL;
+	EVP_MD_CTX_cleanup(out);
+	memcpy(out,in,sizeof *out);
+
+	if (in->md_data && out->digest->ctx_size)
+		{
+		if (tmp_buf)
+			out->md_data = tmp_buf;
+		else
+			{
+			out->md_data=OPENSSL_malloc(out->digest->ctx_size);
+			if (!out->md_data)
+				{
+				EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_MALLOC_FAILURE);
+				return 0;
+				}
+			}
+		memcpy(out->md_data,in->md_data,out->digest->ctx_size);
+		}
+
+	out->update = in->update;
+
+	if (in->pctx)
+		{
+		out->pctx = EVP_PKEY_CTX_dup(in->pctx);
+		if (!out->pctx)
+			{
+			EVP_MD_CTX_cleanup(out);
+			return 0;
+			}
+		}
+
+	if (out->digest->copy)
+		return out->digest->copy(out,in);
+	
+	return 1;
+	}
+
+int EVP_Digest(const void *data, size_t count,
+		unsigned char *md, unsigned int *size, const EVP_MD *type, ENGINE *impl)
+	{
+	EVP_MD_CTX ctx;
+	int ret;
+
+	EVP_MD_CTX_init(&ctx);
+	EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT);
+	ret=EVP_DigestInit_ex(&ctx, type, impl)
+	  && EVP_DigestUpdate(&ctx, data, count)
+	  && EVP_DigestFinal_ex(&ctx, md, size);
+	EVP_MD_CTX_cleanup(&ctx);
+
+	return ret;
+	}
+
+void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
+	{
+	EVP_MD_CTX_cleanup(ctx);
+	OPENSSL_free(ctx);
+	}
+
+/* This call frees resources associated with the context */
+int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
+	{
+	/* Don't assume ctx->md_data was cleaned in EVP_Digest_Final,
+	 * because sometimes only copies of the context are ever finalised.
+	 */
+	if (ctx->digest && ctx->digest->cleanup
+	    && !EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED))
+		ctx->digest->cleanup(ctx);
+	if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
+	    && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE))
+		{
+		OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size);
+		OPENSSL_free(ctx->md_data);
+		}
+	if (ctx->pctx)
+		EVP_PKEY_CTX_free(ctx->pctx);
+#ifndef OPENSSL_NO_ENGINE
+	if(ctx->engine)
+		/* The EVP_MD we used belongs to an ENGINE, release the
+		 * functional reference we held for this reason. */
+		ENGINE_finish(ctx->engine);
+#endif
+	memset(ctx,'\0',sizeof *ctx);
+
+	return 1;
+	}
diff --git a/openssl/crypto/evp/e_aes.c b/openssl/crypto/evp/e_aes.c
new file mode 100644
index 0000000..bd6c0a3
--- /dev/null
+++ b/openssl/crypto/evp/e_aes.c
@@ -0,0 +1,120 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_AES
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <string.h>
+#include <assert.h>
+#include <openssl/aes.h>
+#include "evp_locl.h"
+
+static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+					const unsigned char *iv, int enc);
+
+typedef struct
+	{
+	AES_KEY ks;
+	} EVP_AES_KEY;
+
+#define data(ctx)	EVP_C_DATA(EVP_AES_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(aes_128, ks, AES, EVP_AES_KEY,
+		       NID_aes_128, 16, 16, 16, 128,
+		       0, aes_init_key, NULL, 
+		       EVP_CIPHER_set_asn1_iv,
+		       EVP_CIPHER_get_asn1_iv,
+		       NULL)
+IMPLEMENT_BLOCK_CIPHER(aes_192, ks, AES, EVP_AES_KEY,
+		       NID_aes_192, 16, 24, 16, 128,
+		       0, aes_init_key, NULL, 
+		       EVP_CIPHER_set_asn1_iv,
+		       EVP_CIPHER_get_asn1_iv,
+		       NULL)
+IMPLEMENT_BLOCK_CIPHER(aes_256, ks, AES, EVP_AES_KEY,
+		       NID_aes_256, 16, 32, 16, 128,
+		       0, aes_init_key, NULL, 
+		       EVP_CIPHER_set_asn1_iv,
+		       EVP_CIPHER_get_asn1_iv,
+		       NULL)
+
+#define IMPLEMENT_AES_CFBR(ksize,cbits)	IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16)
+
+IMPLEMENT_AES_CFBR(128,1)
+IMPLEMENT_AES_CFBR(192,1)
+IMPLEMENT_AES_CFBR(256,1)
+
+IMPLEMENT_AES_CFBR(128,8)
+IMPLEMENT_AES_CFBR(192,8)
+IMPLEMENT_AES_CFBR(256,8)
+
+static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+		   const unsigned char *iv, int enc)
+	{
+	int ret;
+
+	if ((ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_CFB_MODE
+	    || (ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_OFB_MODE
+	    || enc) 
+		ret=AES_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
+	else
+		ret=AES_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
+
+	if(ret < 0)
+		{
+		EVPerr(EVP_F_AES_INIT_KEY,EVP_R_AES_KEY_SETUP_FAILED);
+		return 0;
+		}
+
+	return 1;
+	}
+
+#endif
diff --git a/openssl/crypto/evp/e_bf.c b/openssl/crypto/evp/e_bf.c
new file mode 100644
index 0000000..cc224e5
--- /dev/null
+++ b/openssl/crypto/evp/e_bf.c
@@ -0,0 +1,88 @@
+/* crypto/evp/e_bf.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#ifndef OPENSSL_NO_BF
+#include <openssl/evp.h>
+#include "evp_locl.h"
+#include <openssl/objects.h>
+#include <openssl/blowfish.h>
+
+static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+		       const unsigned char *iv, int enc);
+
+typedef struct
+	{
+	BF_KEY ks;
+	} EVP_BF_KEY;
+
+#define data(ctx)	EVP_C_DATA(EVP_BF_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(bf, ks, BF, EVP_BF_KEY, NID_bf, 8, 16, 8, 64,
+			EVP_CIPH_VARIABLE_LENGTH, bf_init_key, NULL, 
+			EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
+	
+static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+		       const unsigned char *iv, int enc)
+	{
+	BF_set_key(&data(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),key);
+	return 1;
+	}
+
+#endif
diff --git a/openssl/crypto/evp/e_camellia.c b/openssl/crypto/evp/e_camellia.c
new file mode 100644
index 0000000..a7b40d1
--- /dev/null
+++ b/openssl/crypto/evp/e_camellia.c
@@ -0,0 +1,131 @@
+/* crypto/evp/e_camellia.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_CAMELLIA
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <string.h>
+#include <assert.h>
+#include <openssl/camellia.h>
+#include "evp_locl.h"
+
+static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+	const unsigned char *iv, int enc);
+
+/* Camellia subkey Structure */
+typedef struct
+	{
+	CAMELLIA_KEY ks;
+	} EVP_CAMELLIA_KEY;
+
+/* Attribute operation for Camellia */
+#define data(ctx)	EVP_C_DATA(EVP_CAMELLIA_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(camellia_128, ks, Camellia, EVP_CAMELLIA_KEY,
+	NID_camellia_128, 16, 16, 16, 128,
+	0, camellia_init_key, NULL, 
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL)
+IMPLEMENT_BLOCK_CIPHER(camellia_192, ks, Camellia, EVP_CAMELLIA_KEY,
+	NID_camellia_192, 16, 24, 16, 128,
+	0, camellia_init_key, NULL, 
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL)
+IMPLEMENT_BLOCK_CIPHER(camellia_256, ks, Camellia, EVP_CAMELLIA_KEY,
+	NID_camellia_256, 16, 32, 16, 128,
+	0, camellia_init_key, NULL, 
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL)
+
+#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits)	IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16)
+
+IMPLEMENT_CAMELLIA_CFBR(128,1)
+IMPLEMENT_CAMELLIA_CFBR(192,1)
+IMPLEMENT_CAMELLIA_CFBR(256,1)
+
+IMPLEMENT_CAMELLIA_CFBR(128,8)
+IMPLEMENT_CAMELLIA_CFBR(192,8)
+IMPLEMENT_CAMELLIA_CFBR(256,8)
+
+
+
+/* The subkey for Camellia is generated. */ 
+static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+	const unsigned char *iv, int enc)
+	{
+	int ret;
+
+	ret=Camellia_set_key(key, ctx->key_len * 8, ctx->cipher_data);
+
+	if(ret < 0)
+		{
+		EVPerr(EVP_F_CAMELLIA_INIT_KEY,EVP_R_CAMELLIA_KEY_SETUP_FAILED);
+		return 0;
+		}
+
+	return 1;
+	}
+
+#else
+
+# ifdef PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/crypto/evp/e_cast.c b/openssl/crypto/evp/e_cast.c
new file mode 100644
index 0000000..d77bcd9
--- /dev/null
+++ b/openssl/crypto/evp/e_cast.c
@@ -0,0 +1,90 @@
+/* crypto/evp/e_cast.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_CAST
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include "evp_locl.h"
+#include <openssl/cast.h>
+
+static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			 const unsigned char *iv,int enc);
+
+typedef struct
+	{
+	CAST_KEY ks;
+	} EVP_CAST_KEY;
+
+#define data(ctx)	EVP_C_DATA(EVP_CAST_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(cast5, ks, CAST, EVP_CAST_KEY, 
+			NID_cast5, 8, CAST_KEY_LENGTH, 8, 64,
+			EVP_CIPH_VARIABLE_LENGTH, cast_init_key, NULL,
+			EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
+			
+static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			 const unsigned char *iv, int enc)
+	{
+	CAST_set_key(&data(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),key);
+	return 1;
+	}
+
+#endif
diff --git a/openssl/crypto/evp/e_des.c b/openssl/crypto/evp/e_des.c
new file mode 100644
index 0000000..ca009f2
--- /dev/null
+++ b/openssl/crypto/evp/e_des.c
@@ -0,0 +1,224 @@
+/* crypto/evp/e_des.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#ifndef OPENSSL_NO_DES
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include "evp_locl.h"
+#include <openssl/des.h>
+#include <openssl/rand.h>
+
+static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			const unsigned char *iv, int enc);
+static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+/* Because of various casts and different names can't use IMPLEMENT_BLOCK_CIPHER */
+
+static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			  const unsigned char *in, size_t inl)
+{
+	BLOCK_CIPHER_ecb_loop()
+		DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), ctx->cipher_data, ctx->encrypt);
+	return 1;
+}
+
+static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			  const unsigned char *in, size_t inl)
+{
+	while(inl>=EVP_MAXCHUNK)
+		{
+		DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
+				(DES_cblock *)ctx->iv, &ctx->num);
+		inl-=EVP_MAXCHUNK;
+		in +=EVP_MAXCHUNK;
+		out+=EVP_MAXCHUNK;
+		}
+	if (inl)
+		DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data,
+				(DES_cblock *)ctx->iv, &ctx->num);
+	return 1;
+}
+
+static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			  const unsigned char *in, size_t inl)
+{
+	while(inl>=EVP_MAXCHUNK)
+		{
+		DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
+				(DES_cblock *)ctx->iv, ctx->encrypt);
+		inl-=EVP_MAXCHUNK;
+		in +=EVP_MAXCHUNK;
+		out+=EVP_MAXCHUNK;
+		}
+	if (inl)
+		DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data,
+				(DES_cblock *)ctx->iv, ctx->encrypt);
+	return 1;
+}
+
+static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			    const unsigned char *in, size_t inl)
+{
+	while(inl>=EVP_MAXCHUNK)
+		{
+		DES_cfb64_encrypt(in,out, (long)EVP_MAXCHUNK, ctx->cipher_data,
+				(DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
+		inl-=EVP_MAXCHUNK;
+		in +=EVP_MAXCHUNK;
+		out+=EVP_MAXCHUNK;
+		}
+	if (inl)
+		DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data,
+			  (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
+	return 1;
+}
+
+/* Although we have a CFB-r implementation for DES, it doesn't pack the right
+   way, so wrap it here */
+static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			   const unsigned char *in, size_t inl)
+    {
+    size_t n,chunk=EVP_MAXCHUNK/8;
+    unsigned char c[1],d[1];
+
+    if (inl<chunk) chunk=inl;
+
+    while (inl && inl>=chunk)
+	{
+	for(n=0 ; n < chunk*8; ++n)
+	    {
+	    c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
+	    DES_cfb_encrypt(c,d,1,1,ctx->cipher_data,(DES_cblock *)ctx->iv,
+			ctx->encrypt);
+	    out[n/8]=(out[n/8]&~(0x80 >> (unsigned int)(n%8))) |
+		     ((d[0]&0x80) >> (unsigned int)(n%8));
+	    }
+	inl-=chunk;
+	in +=chunk;
+	out+=chunk;
+	if (inl<chunk) chunk=inl;
+	}
+
+    return 1;
+    }
+
+static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			   const unsigned char *in, size_t inl)
+    {
+    while (inl>=EVP_MAXCHUNK)
+	{
+	DES_cfb_encrypt(in,out,8,(long)EVP_MAXCHUNK,ctx->cipher_data,
+			(DES_cblock *)ctx->iv,ctx->encrypt);
+	inl-=EVP_MAXCHUNK;
+	in +=EVP_MAXCHUNK;
+	out+=EVP_MAXCHUNK;
+	}
+    if (inl)
+	DES_cfb_encrypt(in,out,8,(long)inl,ctx->cipher_data,
+			(DES_cblock *)ctx->iv,ctx->encrypt);
+    return 1;
+    }
+
+BLOCK_CIPHER_defs(des, DES_key_schedule, NID_des, 8, 8, 8, 64,
+			EVP_CIPH_RAND_KEY, des_init_key, NULL,
+			EVP_CIPHER_set_asn1_iv,
+			EVP_CIPHER_get_asn1_iv,
+			des_ctrl)
+
+BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,1,
+		     EVP_CIPH_RAND_KEY, des_init_key,NULL,
+		     EVP_CIPHER_set_asn1_iv,
+		     EVP_CIPHER_get_asn1_iv,des_ctrl)
+
+BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,8,
+		     EVP_CIPH_RAND_KEY,des_init_key,NULL,
+		     EVP_CIPHER_set_asn1_iv,
+		     EVP_CIPHER_get_asn1_iv,des_ctrl)
+
+static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			const unsigned char *iv, int enc)
+	{
+	DES_cblock *deskey = (DES_cblock *)key;
+#ifdef EVP_CHECK_DES_KEY
+	if(DES_set_key_checked(deskey,ctx->cipher_data) != 0)
+		return 0;
+#else
+	DES_set_key_unchecked(deskey,ctx->cipher_data);
+#endif
+	return 1;
+	}
+
+static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+	{
+	
+	switch(type)
+		{
+	case EVP_CTRL_RAND_KEY:
+		if (RAND_bytes(ptr, 8) <= 0)
+			return 0;
+		DES_set_odd_parity((DES_cblock *)ptr);
+		return 1;
+
+	default:
+		return -1;
+		}
+	}
+
+#endif
diff --git a/openssl/crypto/evp/e_des3.c b/openssl/crypto/evp/e_des3.c
new file mode 100644
index 0000000..3232cfe
--- /dev/null
+++ b/openssl/crypto/evp/e_des3.c
@@ -0,0 +1,313 @@
+/* crypto/evp/e_des3.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#ifndef OPENSSL_NO_DES
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include "evp_locl.h"
+#include <openssl/des.h>
+#include <openssl/rand.h>
+
+static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			    const unsigned char *iv,int enc);
+
+static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			     const unsigned char *iv,int enc);
+
+static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+typedef struct
+    {
+    DES_key_schedule ks1;/* key schedule */
+    DES_key_schedule ks2;/* key schedule (for ede) */
+    DES_key_schedule ks3;/* key schedule (for ede3) */
+    } DES_EDE_KEY;
+
+#define data(ctx) ((DES_EDE_KEY *)(ctx)->cipher_data)
+
+/* Because of various casts and different args can't use IMPLEMENT_BLOCK_CIPHER */
+
+static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			      const unsigned char *in, size_t inl)
+{
+	BLOCK_CIPHER_ecb_loop()
+		DES_ecb3_encrypt((const_DES_cblock *)(in + i),
+				 (DES_cblock *)(out + i),
+				 &data(ctx)->ks1, &data(ctx)->ks2,
+				 &data(ctx)->ks3,
+				 ctx->encrypt);
+	return 1;
+}
+
+static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			      const unsigned char *in, size_t inl)
+{
+	if (inl>=EVP_MAXCHUNK)
+		{
+		DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
+			       &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+			       (DES_cblock *)ctx->iv, &ctx->num);
+		inl-=EVP_MAXCHUNK;
+		in +=EVP_MAXCHUNK;
+		out+=EVP_MAXCHUNK;
+		}
+	if (inl)
+		DES_ede3_ofb64_encrypt(in, out, (long)inl,
+				&data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+                               (DES_cblock *)ctx->iv, &ctx->num);
+
+	return 1;
+}
+
+static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			      const unsigned char *in, size_t inl)
+{
+#ifdef KSSL_DEBUG
+	{
+        int i;
+        char *cp;
+	printf("des_ede_cbc_cipher(ctx=%lx, buflen=%d)\n", ctx, ctx->buf_len);
+	printf("\t iv= ");
+        for(i=0;i<8;i++)
+                printf("%02X",ctx->iv[i]);
+	printf("\n");
+	}
+#endif    /* KSSL_DEBUG */
+	if (inl>=EVP_MAXCHUNK)
+		{
+		DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK,
+			     &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+			     (DES_cblock *)ctx->iv, ctx->encrypt);
+		inl-=EVP_MAXCHUNK;
+		in +=EVP_MAXCHUNK;
+		out+=EVP_MAXCHUNK;
+		}
+	if (inl)
+		DES_ede3_cbc_encrypt(in, out, (long)inl,
+			     &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+                             (DES_cblock *)ctx->iv, ctx->encrypt);
+	return 1;
+}
+
+static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			      const unsigned char *in, size_t inl)
+{
+	if (inl>=EVP_MAXCHUNK)
+		{
+		DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, 
+			       &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+			       (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
+		inl-=EVP_MAXCHUNK;
+		in +=EVP_MAXCHUNK;
+		out+=EVP_MAXCHUNK;
+		}
+	if (inl)
+		DES_ede3_cfb64_encrypt(in, out, (long)inl,
+			       &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+                               (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
+	return 1;
+}
+
+/* Although we have a CFB-r implementation for 3-DES, it doesn't pack the right
+   way, so wrap it here */
+static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+				const unsigned char *in, size_t inl)
+    {
+    size_t n;
+    unsigned char c[1],d[1];
+
+    for(n=0 ; n < inl ; ++n)
+	{
+	c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
+	DES_ede3_cfb_encrypt(c,d,1,1,
+			     &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3,
+			     (DES_cblock *)ctx->iv,ctx->encrypt);
+	out[n/8]=(out[n/8]&~(0x80 >> (unsigned int)(n%8))) |
+		 ((d[0]&0x80) >> (unsigned int)(n%8));
+	}
+
+    return 1;
+    }
+
+static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+				const unsigned char *in, size_t inl)
+    {
+    while (inl>=EVP_MAXCHUNK)
+	{
+	DES_ede3_cfb_encrypt(in,out,8,(long)EVP_MAXCHUNK,
+			 &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3,
+			 (DES_cblock *)ctx->iv,ctx->encrypt);
+	inl-=EVP_MAXCHUNK;
+	in +=EVP_MAXCHUNK;
+	out+=EVP_MAXCHUNK;
+	}
+    if (inl)
+	DES_ede3_cfb_encrypt(in,out,8,(long)inl,
+			&data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3,
+			(DES_cblock *)ctx->iv,ctx->encrypt);
+    return 1;
+    }
+
+BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64,
+			EVP_CIPH_RAND_KEY, des_ede_init_key, NULL, 
+			EVP_CIPHER_set_asn1_iv,
+			EVP_CIPHER_get_asn1_iv,
+			des3_ctrl)
+
+#define des_ede3_cfb64_cipher des_ede_cfb64_cipher
+#define des_ede3_ofb_cipher des_ede_ofb_cipher
+#define des_ede3_cbc_cipher des_ede_cbc_cipher
+#define des_ede3_ecb_cipher des_ede_ecb_cipher
+
+BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64,
+			EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, 
+			EVP_CIPHER_set_asn1_iv,
+			EVP_CIPHER_get_asn1_iv,
+			des3_ctrl)
+
+BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1,
+		     EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL,
+		     EVP_CIPHER_set_asn1_iv,
+		     EVP_CIPHER_get_asn1_iv,
+		     des3_ctrl)
+
+BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,8,
+		     EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL,
+		     EVP_CIPHER_set_asn1_iv,
+		     EVP_CIPHER_get_asn1_iv,
+		     des3_ctrl)
+
+static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			    const unsigned char *iv, int enc)
+	{
+	DES_cblock *deskey = (DES_cblock *)key;
+#ifdef EVP_CHECK_DES_KEY
+	if (DES_set_key_checked(&deskey[0],&data(ctx)->ks1)
+		!! DES_set_key_checked(&deskey[1],&data(ctx)->ks2))
+		return 0;
+#else
+	DES_set_key_unchecked(&deskey[0],&data(ctx)->ks1);
+	DES_set_key_unchecked(&deskey[1],&data(ctx)->ks2);
+#endif
+	memcpy(&data(ctx)->ks3,&data(ctx)->ks1,
+	       sizeof(data(ctx)->ks1));
+	return 1;
+	}
+
+static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			     const unsigned char *iv, int enc)
+	{
+	DES_cblock *deskey = (DES_cblock *)key;
+#ifdef KSSL_DEBUG
+	{
+        int i;
+        printf("des_ede3_init_key(ctx=%lx)\n", ctx);
+	printf("\tKEY= ");
+        for(i=0;i<24;i++) printf("%02X",key[i]); printf("\n");
+	printf("\t IV= ");
+        for(i=0;i<8;i++) printf("%02X",iv[i]); printf("\n");
+	}
+#endif	/* KSSL_DEBUG */
+
+#ifdef EVP_CHECK_DES_KEY
+	if (DES_set_key_checked(&deskey[0],&data(ctx)->ks1)
+		|| DES_set_key_checked(&deskey[1],&data(ctx)->ks2)
+		|| DES_set_key_checked(&deskey[2],&data(ctx)->ks3))
+		return 0;
+#else
+	DES_set_key_unchecked(&deskey[0],&data(ctx)->ks1);
+	DES_set_key_unchecked(&deskey[1],&data(ctx)->ks2);
+	DES_set_key_unchecked(&deskey[2],&data(ctx)->ks3);
+#endif
+	return 1;
+	}
+
+static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+	{
+
+	DES_cblock *deskey = ptr;
+
+	switch(type)
+		{
+	case EVP_CTRL_RAND_KEY:
+		if (RAND_bytes(ptr, c->key_len) <= 0)
+			return 0;
+		DES_set_odd_parity(deskey);
+		if (c->key_len >= 16)
+			DES_set_odd_parity(deskey + 1);
+		if (c->key_len >= 24)
+			DES_set_odd_parity(deskey + 2);
+		return 1;
+
+	default:
+		return -1;
+		}
+	}
+
+const EVP_CIPHER *EVP_des_ede(void)
+{
+	return &des_ede_ecb;
+}
+
+const EVP_CIPHER *EVP_des_ede3(void)
+{
+	return &des_ede3_ecb;
+}
+#endif
diff --git a/openssl/crypto/evp/e_dsa.c b/openssl/crypto/evp/e_dsa.c
new file mode 100644
index 0000000..b96f273
--- /dev/null
+++ b/openssl/crypto/evp/e_dsa.c
@@ -0,0 +1,71 @@
+/* crypto/evp/e_dsa.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+static EVP_PKEY_METHOD dss_method=
+	{
+	DSA_sign,
+	DSA_verify,
+	{EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3,NULL},
+	};
+
diff --git a/openssl/crypto/evp/e_idea.c b/openssl/crypto/evp/e_idea.c
new file mode 100644
index 0000000..806b080
--- /dev/null
+++ b/openssl/crypto/evp/e_idea.c
@@ -0,0 +1,118 @@
+/* crypto/evp/e_idea.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_IDEA
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include "evp_locl.h"
+#include <openssl/idea.h>
+
+static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			 const unsigned char *iv,int enc);
+
+/* NB idea_ecb_encrypt doesn't take an 'encrypt' argument so we treat it as a special
+ * case 
+ */
+
+static int idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			   const unsigned char *in, size_t inl)
+{
+	BLOCK_CIPHER_ecb_loop()
+		idea_ecb_encrypt(in + i, out + i, ctx->cipher_data);
+	return 1;
+}
+
+/* Can't use IMPLEMENT_BLOCK_CIPHER because idea_ecb_encrypt is different */
+
+typedef struct
+	{
+	IDEA_KEY_SCHEDULE ks;
+	} EVP_IDEA_KEY;
+
+BLOCK_CIPHER_func_cbc(idea, idea, EVP_IDEA_KEY, ks)
+BLOCK_CIPHER_func_ofb(idea, idea, 64, EVP_IDEA_KEY, ks)
+BLOCK_CIPHER_func_cfb(idea, idea, 64, EVP_IDEA_KEY, ks)
+
+BLOCK_CIPHER_defs(idea, IDEA_KEY_SCHEDULE, NID_idea, 8, 16, 8, 64,
+			0, idea_init_key, NULL, 
+			EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
+
+static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			 const unsigned char *iv, int enc)
+	{
+	if(!enc) {
+		if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE) enc = 1;
+		else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE) enc = 1;
+	}
+	if (enc) idea_set_encrypt_key(key,ctx->cipher_data);
+	else
+		{
+		IDEA_KEY_SCHEDULE tmp;
+
+		idea_set_encrypt_key(key,&tmp);
+		idea_set_decrypt_key(&tmp,ctx->cipher_data);
+		OPENSSL_cleanse((unsigned char *)&tmp,
+				sizeof(IDEA_KEY_SCHEDULE));
+		}
+	return 1;
+	}
+
+#endif
diff --git a/openssl/crypto/evp/e_null.c b/openssl/crypto/evp/e_null.c
new file mode 100644
index 0000000..7cf50e1
--- /dev/null
+++ b/openssl/crypto/evp/e_null.c
@@ -0,0 +1,102 @@
+/* crypto/evp/e_null.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+
+static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+	const unsigned char *iv,int enc);
+static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+	const unsigned char *in, size_t inl);
+static const EVP_CIPHER n_cipher=
+	{
+	NID_undef,
+	1,0,0,
+	0,
+	null_init_key,
+	null_cipher,
+	NULL,
+	0,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+	};
+
+const EVP_CIPHER *EVP_enc_null(void)
+	{
+	return(&n_cipher);
+	}
+
+static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+	     const unsigned char *iv, int enc)
+	{
+	/*	memset(&(ctx->c),0,sizeof(ctx->c));*/
+	return 1;
+	}
+
+static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+	     const unsigned char *in, size_t inl)
+	{
+	if (in != out)
+		memcpy((char *)out,(const char *)in,inl);
+	return 1;
+	}
+
diff --git a/openssl/crypto/evp/e_old.c b/openssl/crypto/evp/e_old.c
new file mode 100644
index 0000000..1642af4
--- /dev/null
+++ b/openssl/crypto/evp/e_old.c
@@ -0,0 +1,125 @@
+/* crypto/evp/e_old.c -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifdef OPENSSL_NO_DEPRECATED
+static void *dummy = &dummy;
+#else
+
+#include <openssl/evp.h>
+
+/* Define some deprecated functions, so older programs
+   don't crash and burn too quickly.  On Windows and VMS,
+   these will never be used, since functions and variables
+   in shared libraries are selected by entry point location,
+   not by name.  */
+
+#ifndef OPENSSL_NO_BF
+#undef EVP_bf_cfb
+const EVP_CIPHER *EVP_bf_cfb(void);
+const EVP_CIPHER *EVP_bf_cfb(void) { return EVP_bf_cfb64(); }
+#endif
+
+#ifndef OPENSSL_NO_DES
+#undef EVP_des_cfb
+const EVP_CIPHER *EVP_des_cfb(void);
+const EVP_CIPHER *EVP_des_cfb(void) { return EVP_des_cfb64(); }
+#undef EVP_des_ede3_cfb
+const EVP_CIPHER *EVP_des_ede3_cfb(void);
+const EVP_CIPHER *EVP_des_ede3_cfb(void) { return EVP_des_ede3_cfb64(); }
+#undef EVP_des_ede_cfb
+const EVP_CIPHER *EVP_des_ede_cfb(void);
+const EVP_CIPHER *EVP_des_ede_cfb(void) { return EVP_des_ede_cfb64(); }
+#endif
+
+#ifndef OPENSSL_NO_IDEA
+#undef EVP_idea_cfb
+const EVP_CIPHER *EVP_idea_cfb(void);
+const EVP_CIPHER *EVP_idea_cfb(void) { return EVP_idea_cfb64(); }
+#endif
+
+#ifndef OPENSSL_NO_RC2
+#undef EVP_rc2_cfb
+const EVP_CIPHER *EVP_rc2_cfb(void);
+const EVP_CIPHER *EVP_rc2_cfb(void) { return EVP_rc2_cfb64(); }
+#endif
+
+#ifndef OPENSSL_NO_CAST
+#undef EVP_cast5_cfb
+const EVP_CIPHER *EVP_cast5_cfb(void);
+const EVP_CIPHER *EVP_cast5_cfb(void) { return EVP_cast5_cfb64(); }
+#endif
+
+#ifndef OPENSSL_NO_RC5
+#undef EVP_rc5_32_12_16_cfb
+const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void);
+const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void) { return EVP_rc5_32_12_16_cfb64(); }
+#endif
+
+#ifndef OPENSSL_NO_AES
+#undef EVP_aes_128_cfb
+const EVP_CIPHER *EVP_aes_128_cfb(void);
+const EVP_CIPHER *EVP_aes_128_cfb(void) { return EVP_aes_128_cfb128(); }
+#undef EVP_aes_192_cfb
+const EVP_CIPHER *EVP_aes_192_cfb(void);
+const EVP_CIPHER *EVP_aes_192_cfb(void) { return EVP_aes_192_cfb128(); }
+#undef EVP_aes_256_cfb
+const EVP_CIPHER *EVP_aes_256_cfb(void);
+const EVP_CIPHER *EVP_aes_256_cfb(void) { return EVP_aes_256_cfb128(); }
+#endif
+
+#endif
diff --git a/openssl/crypto/evp/e_rc2.c b/openssl/crypto/evp/e_rc2.c
new file mode 100644
index 0000000..f78d781
--- /dev/null
+++ b/openssl/crypto/evp/e_rc2.c
@@ -0,0 +1,237 @@
+/* crypto/evp/e_rc2.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_RC2
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include "evp_locl.h"
+#include <openssl/rc2.h>
+
+static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			const unsigned char *iv,int enc);
+static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx);
+static int rc2_magic_to_meth(int i);
+static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+typedef struct
+	{
+	int key_bits;	/* effective key bits */
+	RC2_KEY ks;	/* key schedule */
+	} EVP_RC2_KEY;
+
+#define data(ctx)	((EVP_RC2_KEY *)(ctx)->cipher_data)
+
+IMPLEMENT_BLOCK_CIPHER(rc2, ks, RC2, EVP_RC2_KEY, NID_rc2,
+			8,
+			RC2_KEY_LENGTH, 8, 64,
+			EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+			rc2_init_key, NULL,
+			rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv, 
+			rc2_ctrl)
+
+#define RC2_40_MAGIC	0xa0
+#define RC2_64_MAGIC	0x78
+#define RC2_128_MAGIC	0x3a
+
+static const EVP_CIPHER r2_64_cbc_cipher=
+	{
+	NID_rc2_64_cbc,
+	8,8 /* 64 bit */,8,
+	EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+	rc2_init_key,
+	rc2_cbc_cipher,
+	NULL,
+	sizeof(EVP_RC2_KEY),
+	rc2_set_asn1_type_and_iv,
+	rc2_get_asn1_type_and_iv,
+	rc2_ctrl,
+	NULL
+	};
+
+static const EVP_CIPHER r2_40_cbc_cipher=
+	{
+	NID_rc2_40_cbc,
+	8,5 /* 40 bit */,8,
+	EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+	rc2_init_key,
+	rc2_cbc_cipher,
+	NULL,
+	sizeof(EVP_RC2_KEY),
+	rc2_set_asn1_type_and_iv,
+	rc2_get_asn1_type_and_iv,
+	rc2_ctrl,
+	NULL
+	};
+
+const EVP_CIPHER *EVP_rc2_64_cbc(void)
+	{
+	return(&r2_64_cbc_cipher);
+	}
+
+const EVP_CIPHER *EVP_rc2_40_cbc(void)
+	{
+	return(&r2_40_cbc_cipher);
+	}
+	
+static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			const unsigned char *iv, int enc)
+	{
+	RC2_set_key(&data(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),
+		    key,data(ctx)->key_bits);
+	return 1;
+	}
+
+static int rc2_meth_to_magic(EVP_CIPHER_CTX *e)
+	{
+	int i;
+
+	EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i);
+	if 	(i == 128) return(RC2_128_MAGIC);
+	else if (i == 64)  return(RC2_64_MAGIC);
+	else if (i == 40)  return(RC2_40_MAGIC);
+	else return(0);
+	}
+
+static int rc2_magic_to_meth(int i)
+	{
+	if      (i == RC2_128_MAGIC) return 128;
+	else if (i == RC2_64_MAGIC)  return 64;
+	else if (i == RC2_40_MAGIC)  return 40;
+	else
+		{
+		EVPerr(EVP_F_RC2_MAGIC_TO_METH,EVP_R_UNSUPPORTED_KEY_SIZE);
+		return(0);
+		}
+	}
+
+static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+	{
+	long num=0;
+	int i=0;
+	int key_bits;
+	unsigned int l;
+	unsigned char iv[EVP_MAX_IV_LENGTH];
+
+	if (type != NULL)
+		{
+		l=EVP_CIPHER_CTX_iv_length(c);
+		OPENSSL_assert(l <= sizeof(iv));
+		i=ASN1_TYPE_get_int_octetstring(type,&num,iv,l);
+		if (i != (int)l)
+			return(-1);
+		key_bits =rc2_magic_to_meth((int)num);
+		if (!key_bits)
+			return(-1);
+		if(i > 0) EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1);
+		EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
+		EVP_CIPHER_CTX_set_key_length(c, key_bits / 8);
+		}
+	return(i);
+	}
+
+static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+	{
+	long num;
+	int i=0,j;
+
+	if (type != NULL)
+		{
+		num=rc2_meth_to_magic(c);
+		j=EVP_CIPHER_CTX_iv_length(c);
+		i=ASN1_TYPE_set_int_octetstring(type,num,c->oiv,j);
+		}
+	return(i);
+	}
+
+static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+	{
+	switch(type)
+		{
+	case EVP_CTRL_INIT:
+		data(c)->key_bits = EVP_CIPHER_CTX_key_length(c) * 8;
+		return 1;
+
+	case EVP_CTRL_GET_RC2_KEY_BITS:
+		*(int *)ptr = data(c)->key_bits;
+		return 1;
+			
+	case EVP_CTRL_SET_RC2_KEY_BITS:
+		if(arg > 0)
+			{
+			data(c)->key_bits = arg;
+			return 1;
+			}
+		return 0;
+#ifdef PBE_PRF_TEST
+	case EVP_CTRL_PBE_PRF_NID:
+		*(int *)ptr = NID_hmacWithMD5;
+		return 1;
+#endif
+
+	default:
+		return -1;
+		}
+	}
+
+#endif
diff --git a/openssl/crypto/evp/e_rc4.c b/openssl/crypto/evp/e_rc4.c
new file mode 100644
index 0000000..8b5175e
--- /dev/null
+++ b/openssl/crypto/evp/e_rc4.c
@@ -0,0 +1,136 @@
+/* crypto/evp/e_rc4.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_RC4
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/rc4.h>
+
+/* FIXME: surely this is available elsewhere? */
+#define EVP_RC4_KEY_SIZE		16
+
+typedef struct
+    {
+    RC4_KEY ks;	/* working key */
+    } EVP_RC4_KEY;
+
+#define data(ctx) ((EVP_RC4_KEY *)(ctx)->cipher_data)
+
+static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			const unsigned char *iv,int enc);
+static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+		      const unsigned char *in, size_t inl);
+static const EVP_CIPHER r4_cipher=
+	{
+	NID_rc4,
+	1,EVP_RC4_KEY_SIZE,0,
+	EVP_CIPH_VARIABLE_LENGTH,
+	rc4_init_key,
+	rc4_cipher,
+	NULL,
+	sizeof(EVP_RC4_KEY),
+	NULL,
+	NULL,
+	NULL,
+	NULL
+	};
+
+static const EVP_CIPHER r4_40_cipher=
+	{
+	NID_rc4_40,
+	1,5 /* 40 bit */,0,
+	EVP_CIPH_VARIABLE_LENGTH,
+	rc4_init_key,
+	rc4_cipher,
+	NULL,
+	sizeof(EVP_RC4_KEY),
+	NULL, 
+	NULL,
+	NULL,
+	NULL
+	};
+
+const EVP_CIPHER *EVP_rc4(void)
+	{
+	return(&r4_cipher);
+	}
+
+const EVP_CIPHER *EVP_rc4_40(void)
+	{
+	return(&r4_40_cipher);
+	}
+
+static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			const unsigned char *iv, int enc)
+	{
+	RC4_set_key(&data(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),
+		    key);
+	return 1;
+	}
+
+static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+		      const unsigned char *in, size_t inl)
+	{
+	RC4(&data(ctx)->ks,inl,in,out);
+	return 1;
+	}
+#endif
diff --git a/openssl/crypto/evp/e_rc5.c b/openssl/crypto/evp/e_rc5.c
new file mode 100644
index 0000000..19a10c6
--- /dev/null
+++ b/openssl/crypto/evp/e_rc5.c
@@ -0,0 +1,126 @@
+/* crypto/evp/e_rc5.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_RC5
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include "evp_locl.h"
+#include <openssl/rc5.h>
+
+static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			       const unsigned char *iv,int enc);
+static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+typedef struct
+	{
+	int rounds;	/* number of rounds */
+	RC5_32_KEY ks;	/* key schedule */
+	} EVP_RC5_KEY;
+
+#define data(ctx)	EVP_C_DATA(EVP_RC5_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(rc5_32_12_16, ks, RC5_32, EVP_RC5_KEY, NID_rc5,
+		       8, RC5_32_KEY_LENGTH, 8, 64,
+		       EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+		       r_32_12_16_init_key, NULL,
+		       NULL, NULL, rc5_ctrl)
+
+static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+	{
+	switch(type)
+		{
+	case EVP_CTRL_INIT:
+		data(c)->rounds = RC5_12_ROUNDS;
+		return 1;
+
+	case EVP_CTRL_GET_RC5_ROUNDS:
+		*(int *)ptr = data(c)->rounds;
+		return 1;
+			
+	case EVP_CTRL_SET_RC5_ROUNDS:
+		switch(arg)
+			{
+		case RC5_8_ROUNDS:
+		case RC5_12_ROUNDS:
+		case RC5_16_ROUNDS:
+			data(c)->rounds = arg;
+			return 1;
+
+		default:
+			EVPerr(EVP_F_RC5_CTRL, EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS);
+			return 0;
+			}
+
+	default:
+		return -1;
+		}
+	}
+
+static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			       const unsigned char *iv, int enc)
+	{
+	RC5_32_set_key(&data(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),
+		       key,data(ctx)->rounds);
+	return 1;
+	}
+
+#endif
diff --git a/openssl/crypto/evp/e_seed.c b/openssl/crypto/evp/e_seed.c
new file mode 100644
index 0000000..2d1759d
--- /dev/null
+++ b/openssl/crypto/evp/e_seed.c
@@ -0,0 +1,83 @@
+/* crypto/evp/e_seed.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_SEED
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <string.h>
+#include <assert.h>
+#include <openssl/seed.h>
+#include "evp_locl.h"
+
+static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,	const unsigned char *iv, int enc);
+
+typedef struct
+	{
+	SEED_KEY_SCHEDULE ks;
+	} EVP_SEED_KEY;
+
+IMPLEMENT_BLOCK_CIPHER(seed, ks, SEED, EVP_SEED_KEY, NID_seed,
+                       16, 16, 16, 128,
+                       0, seed_init_key, 0, 0, 0, 0)
+
+static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                         const unsigned char *iv, int enc)
+	{
+	SEED_set_key(key, ctx->cipher_data);
+	return 1;
+	}
+
+#endif
diff --git a/openssl/crypto/evp/e_xcbc_d.c b/openssl/crypto/evp/e_xcbc_d.c
new file mode 100644
index 0000000..250e88c
--- /dev/null
+++ b/openssl/crypto/evp/e_xcbc_d.c
@@ -0,0 +1,138 @@
+/* crypto/evp/e_xcbc_d.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_DES
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include "evp_locl.h"
+#include <openssl/des.h>
+
+static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			     const unsigned char *iv,int enc);
+static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			   const unsigned char *in, size_t inl);
+
+
+typedef struct
+    {
+    DES_key_schedule ks;/* key schedule */
+    DES_cblock inw;
+    DES_cblock outw;
+    } DESX_CBC_KEY;
+
+#define data(ctx) ((DESX_CBC_KEY *)(ctx)->cipher_data)
+
+static const EVP_CIPHER d_xcbc_cipher=
+	{
+	NID_desx_cbc,
+	8,24,8,
+	EVP_CIPH_CBC_MODE,
+	desx_cbc_init_key,
+	desx_cbc_cipher,
+	NULL,
+	sizeof(DESX_CBC_KEY),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL,
+	NULL
+	};
+
+const EVP_CIPHER *EVP_desx_cbc(void)
+	{
+	return(&d_xcbc_cipher);
+	}
+	
+static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+			     const unsigned char *iv, int enc)
+	{
+	DES_cblock *deskey = (DES_cblock *)key;
+
+	DES_set_key_unchecked(deskey,&data(ctx)->ks);
+	memcpy(&data(ctx)->inw[0],&key[8],8);
+	memcpy(&data(ctx)->outw[0],&key[16],8);
+
+	return 1;
+	}
+
+static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			   const unsigned char *in, size_t inl)
+	{
+	while (inl>=EVP_MAXCHUNK)
+		{
+		DES_xcbc_encrypt(in,out,(long)EVP_MAXCHUNK,&data(ctx)->ks,
+			 (DES_cblock *)&(ctx->iv[0]),
+			 &data(ctx)->inw,
+			 &data(ctx)->outw,
+			 ctx->encrypt);
+		inl-=EVP_MAXCHUNK;
+		in +=EVP_MAXCHUNK;
+		out+=EVP_MAXCHUNK;
+		}
+	if (inl)
+		DES_xcbc_encrypt(in,out,(long)inl,&data(ctx)->ks,
+			(DES_cblock *)&(ctx->iv[0]),
+			&data(ctx)->inw,
+			&data(ctx)->outw,
+			ctx->encrypt);
+	return 1;
+	}
+#endif
diff --git a/openssl/crypto/evp/encode.c b/openssl/crypto/evp/encode.c
new file mode 100644
index 0000000..28546a8
--- /dev/null
+++ b/openssl/crypto/evp/encode.c
@@ -0,0 +1,445 @@
+/* crypto/evp/encode.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+
+#ifndef CHARSET_EBCDIC
+#define conv_bin2ascii(a)	(data_bin2ascii[(a)&0x3f])
+#define conv_ascii2bin(a)	(data_ascii2bin[(a)&0x7f])
+#else
+/* We assume that PEM encoded files are EBCDIC files
+ * (i.e., printable text files). Convert them here while decoding.
+ * When encoding, output is EBCDIC (text) format again.
+ * (No need for conversion in the conv_bin2ascii macro, as the
+ * underlying textstring data_bin2ascii[] is already EBCDIC)
+ */
+#define conv_bin2ascii(a)	(data_bin2ascii[(a)&0x3f])
+#define conv_ascii2bin(a)	(data_ascii2bin[os_toascii[a]&0x7f])
+#endif
+
+/* 64 char lines
+ * pad input with 0
+ * left over chars are set to =
+ * 1 byte  => xx==
+ * 2 bytes => xxx=
+ * 3 bytes => xxxx
+ */
+#define BIN_PER_LINE    (64/4*3)
+#define CHUNKS_PER_LINE (64/4)
+#define CHAR_PER_LINE   (64+1)
+
+static const unsigned char data_bin2ascii[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+abcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/* 0xF0 is a EOLN
+ * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
+ * 0xF2 is EOF
+ * 0xE0 is ignore at start of line.
+ * 0xFF is error
+ */
+
+#define B64_EOLN		0xF0
+#define B64_CR			0xF1
+#define B64_EOF			0xF2
+#define B64_WS			0xE0
+#define B64_ERROR       	0xFF
+#define B64_NOT_BASE64(a)	(((a)|0x13) == 0xF3)
+
+static const unsigned char data_ascii2bin[128]={
+	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	0xFF,0xE0,0xF0,0xFF,0xFF,0xF1,0xFF,0xFF,
+	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	0xFF,0xFF,0xFF,0x3E,0xFF,0xF2,0xFF,0x3F,
+	0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,
+	0x3C,0x3D,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,
+	0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
+	0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,
+	0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
+	0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF,
+	0xFF,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,
+	0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
+	0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,
+	0x31,0x32,0x33,0xFF,0xFF,0xFF,0xFF,0xFF,
+	};
+
+void EVP_EncodeInit(EVP_ENCODE_CTX *ctx)
+	{
+	ctx->length=48;
+	ctx->num=0;
+	ctx->line_num=0;
+	}
+
+void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
+	     const unsigned char *in, int inl)
+	{
+	int i,j;
+	unsigned int total=0;
+
+	*outl=0;
+	if (inl == 0) return;
+	OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
+	if ((ctx->num+inl) < ctx->length)
+		{
+		memcpy(&(ctx->enc_data[ctx->num]),in,inl);
+		ctx->num+=inl;
+		return;
+		}
+	if (ctx->num != 0)
+		{
+		i=ctx->length-ctx->num;
+		memcpy(&(ctx->enc_data[ctx->num]),in,i);
+		in+=i;
+		inl-=i;
+		j=EVP_EncodeBlock(out,ctx->enc_data,ctx->length);
+		ctx->num=0;
+		out+=j;
+		*(out++)='\n';
+		*out='\0';
+		total=j+1;
+		}
+	while (inl >= ctx->length)
+		{
+		j=EVP_EncodeBlock(out,in,ctx->length);
+		in+=ctx->length;
+		inl-=ctx->length;
+		out+=j;
+		*(out++)='\n';
+		*out='\0';
+		total+=j+1;
+		}
+	if (inl != 0)
+		memcpy(&(ctx->enc_data[0]),in,inl);
+	ctx->num=inl;
+	*outl=total;
+	}
+
+void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
+	{
+	unsigned int ret=0;
+
+	if (ctx->num != 0)
+		{
+		ret=EVP_EncodeBlock(out,ctx->enc_data,ctx->num);
+		out[ret++]='\n';
+		out[ret]='\0';
+		ctx->num=0;
+		}
+	*outl=ret;
+	}
+
+int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)
+	{
+	int i,ret=0;
+	unsigned long l;
+
+	for (i=dlen; i > 0; i-=3)
+		{
+		if (i >= 3)
+			{
+			l=	(((unsigned long)f[0])<<16L)|
+				(((unsigned long)f[1])<< 8L)|f[2];
+			*(t++)=conv_bin2ascii(l>>18L);
+			*(t++)=conv_bin2ascii(l>>12L);
+			*(t++)=conv_bin2ascii(l>> 6L);
+			*(t++)=conv_bin2ascii(l     );
+			}
+		else
+			{
+			l=((unsigned long)f[0])<<16L;
+			if (i == 2) l|=((unsigned long)f[1]<<8L);
+
+			*(t++)=conv_bin2ascii(l>>18L);
+			*(t++)=conv_bin2ascii(l>>12L);
+			*(t++)=(i == 1)?'=':conv_bin2ascii(l>> 6L);
+			*(t++)='=';
+			}
+		ret+=4;
+		f+=3;
+		}
+
+	*t='\0';
+	return(ret);
+	}
+
+void EVP_DecodeInit(EVP_ENCODE_CTX *ctx)
+	{
+	ctx->length=30;
+	ctx->num=0;
+	ctx->line_num=0;
+	ctx->expect_nl=0;
+	}
+
+/* -1 for error
+ *  0 for last line
+ *  1 for full line
+ */
+int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
+	     const unsigned char *in, int inl)
+	{
+	int seof= -1,eof=0,rv= -1,ret=0,i,v,tmp,n,ln,exp_nl;
+	unsigned char *d;
+
+	n=ctx->num;
+	d=ctx->enc_data;
+	ln=ctx->line_num;
+	exp_nl=ctx->expect_nl;
+
+	/* last line of input. */
+	if ((inl == 0) || ((n == 0) && (conv_ascii2bin(in[0]) == B64_EOF)))
+		{ rv=0; goto end; }
+		
+	/* We parse the input data */
+	for (i=0; i<inl; i++)
+		{
+		/* If the current line is > 80 characters, scream alot */
+		if (ln >= 80) { rv= -1; goto end; }
+
+		/* Get char and put it into the buffer */
+		tmp= *(in++);
+		v=conv_ascii2bin(tmp);
+		/* only save the good data :-) */
+		if (!B64_NOT_BASE64(v))
+			{
+			OPENSSL_assert(n < (int)sizeof(ctx->enc_data));
+			d[n++]=tmp;
+			ln++;
+			}
+		else if (v == B64_ERROR)
+			{
+			rv= -1;
+			goto end;
+			}
+
+		/* have we seen a '=' which is 'definitly' the last
+		 * input line.  seof will point to the character that
+		 * holds it. and eof will hold how many characters to
+		 * chop off. */
+		if (tmp == '=')
+			{
+			if (seof == -1) seof=n;
+			eof++;
+			}
+
+		if (v == B64_CR)
+			{
+			ln = 0;
+			if (exp_nl)
+				continue;
+			}
+
+		/* eoln */
+		if (v == B64_EOLN)
+			{
+			ln=0;
+			if (exp_nl)
+				{
+				exp_nl=0;
+				continue;
+				}
+			}
+		exp_nl=0;
+
+		/* If we are at the end of input and it looks like a
+		 * line, process it. */
+		if (((i+1) == inl) && (((n&3) == 0) || eof))
+			{
+			v=B64_EOF;
+			/* In case things were given us in really small
+			   records (so two '=' were given in separate
+			   updates), eof may contain the incorrect number
+			   of ending bytes to skip, so let's redo the count */
+			eof = 0;
+			if (d[n-1] == '=') eof++;
+			if (d[n-2] == '=') eof++;
+			/* There will never be more than two '=' */
+			}
+
+		if ((v == B64_EOF && (n&3) == 0) || (n >= 64))
+			{
+			/* This is needed to work correctly on 64 byte input
+			 * lines.  We process the line and then need to
+			 * accept the '\n' */
+			if ((v != B64_EOF) && (n >= 64)) exp_nl=1;
+			if (n > 0)
+				{
+				v=EVP_DecodeBlock(out,d,n);
+				n=0;
+				if (v < 0) { rv=0; goto end; }
+				ret+=(v-eof);
+				}
+			else
+				{
+				eof=1;
+				v=0;
+				}
+
+			/* This is the case where we have had a short
+			 * but valid input line */
+			if ((v < ctx->length) && eof)
+				{
+				rv=0;
+				goto end;
+				}
+			else
+				ctx->length=v;
+
+			if (seof >= 0) { rv=0; goto end; }
+			out+=v;
+			}
+		}
+	rv=1;
+end:
+	*outl=ret;
+	ctx->num=n;
+	ctx->line_num=ln;
+	ctx->expect_nl=exp_nl;
+	return(rv);
+	}
+
+int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n)
+	{
+	int i,ret=0,a,b,c,d;
+	unsigned long l;
+
+	/* trim white space from the start of the line. */
+	while ((conv_ascii2bin(*f) == B64_WS) && (n > 0))
+		{
+		f++;
+		n--;
+		}
+
+	/* strip off stuff at the end of the line
+	 * ascii2bin values B64_WS, B64_EOLN, B64_EOLN and B64_EOF */
+	while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n-1]))))
+		n--;
+
+	if (n%4 != 0) return(-1);
+
+	for (i=0; i<n; i+=4)
+		{
+		a=conv_ascii2bin(*(f++));
+		b=conv_ascii2bin(*(f++));
+		c=conv_ascii2bin(*(f++));
+		d=conv_ascii2bin(*(f++));
+		if (	(a & 0x80) || (b & 0x80) ||
+			(c & 0x80) || (d & 0x80))
+			return(-1);
+		l=(	(((unsigned long)a)<<18L)|
+			(((unsigned long)b)<<12L)|
+			(((unsigned long)c)<< 6L)|
+			(((unsigned long)d)     ));
+		*(t++)=(unsigned char)(l>>16L)&0xff;
+		*(t++)=(unsigned char)(l>> 8L)&0xff;
+		*(t++)=(unsigned char)(l     )&0xff;
+		ret+=3;
+		}
+	return(ret);
+	}
+
+int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
+	{
+	int i;
+
+	*outl=0;
+	if (ctx->num != 0)
+		{
+		i=EVP_DecodeBlock(out,ctx->enc_data,ctx->num);
+		if (i < 0) return(-1);
+		ctx->num=0;
+		*outl=i;
+		return(1);
+		}
+	else
+		return(1);
+	}
+
+#ifdef undef
+int EVP_DecodeValid(unsigned char *buf, int len)
+	{
+	int i,num=0,bad=0;
+
+	if (len == 0) return(-1);
+	while (conv_ascii2bin(*buf) == B64_WS)
+		{
+		buf++;
+		len--;
+		if (len == 0) return(-1);
+		}
+
+	for (i=len; i >= 4; i-=4)
+		{
+		if (	(conv_ascii2bin(buf[0]) >= 0x40) ||
+			(conv_ascii2bin(buf[1]) >= 0x40) ||
+			(conv_ascii2bin(buf[2]) >= 0x40) ||
+			(conv_ascii2bin(buf[3]) >= 0x40))
+			return(-1);
+		buf+=4;
+		num+=1+(buf[2] != '=')+(buf[3] != '=');
+		}
+	if ((i == 1) && (conv_ascii2bin(buf[0]) == B64_EOLN))
+		return(num);
+	if ((i == 2) && (conv_ascii2bin(buf[0]) == B64_EOLN) &&
+		(conv_ascii2bin(buf[0]) == B64_EOLN))
+		return(num);
+	return(1);
+	}
+#endif
diff --git a/openssl/crypto/evp/evp.h b/openssl/crypto/evp/evp.h
new file mode 100644
index 0000000..9f9795e
--- /dev/null
+++ b/openssl/crypto/evp/evp.h
@@ -0,0 +1,1324 @@
+/* crypto/evp/evp.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ENVELOPE_H
+#define HEADER_ENVELOPE_H
+
+#ifdef OPENSSL_ALGORITHM_DEFINES
+# include <openssl/opensslconf.h>
+#else
+# define OPENSSL_ALGORITHM_DEFINES
+# include <openssl/opensslconf.h>
+# undef OPENSSL_ALGORITHM_DEFINES
+#endif
+
+#include <openssl/ossl_typ.h>
+
+#include <openssl/symhacks.h>
+
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+
+/*
+#define EVP_RC2_KEY_SIZE		16
+#define EVP_RC4_KEY_SIZE		16
+#define EVP_BLOWFISH_KEY_SIZE		16
+#define EVP_CAST5_KEY_SIZE		16
+#define EVP_RC5_32_12_16_KEY_SIZE	16
+*/
+#define EVP_MAX_MD_SIZE			64	/* longest known is SHA512 */
+#define EVP_MAX_KEY_LENGTH		32
+#define EVP_MAX_IV_LENGTH		16
+#define EVP_MAX_BLOCK_LENGTH		32
+
+#define PKCS5_SALT_LEN			8
+/* Default PKCS#5 iteration count */
+#define PKCS5_DEFAULT_ITER		2048
+
+#include <openssl/objects.h>
+
+#define EVP_PK_RSA	0x0001
+#define EVP_PK_DSA	0x0002
+#define EVP_PK_DH	0x0004
+#define EVP_PK_EC	0x0008
+#define EVP_PKT_SIGN	0x0010
+#define EVP_PKT_ENC	0x0020
+#define EVP_PKT_EXCH	0x0040
+#define EVP_PKS_RSA	0x0100
+#define EVP_PKS_DSA	0x0200
+#define EVP_PKS_EC	0x0400
+#define EVP_PKT_EXP	0x1000 /* <= 512 bit key */
+
+#define EVP_PKEY_NONE	NID_undef
+#define EVP_PKEY_RSA	NID_rsaEncryption
+#define EVP_PKEY_RSA2	NID_rsa
+#define EVP_PKEY_DSA	NID_dsa
+#define EVP_PKEY_DSA1	NID_dsa_2
+#define EVP_PKEY_DSA2	NID_dsaWithSHA
+#define EVP_PKEY_DSA3	NID_dsaWithSHA1
+#define EVP_PKEY_DSA4	NID_dsaWithSHA1_2
+#define EVP_PKEY_DH	NID_dhKeyAgreement
+#define EVP_PKEY_EC	NID_X9_62_id_ecPublicKey
+#define EVP_PKEY_HMAC	NID_hmac
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* Type needs to be a bit field
+ * Sub-type needs to be for variations on the method, as in, can it do
+ * arbitrary encryption.... */
+struct evp_pkey_st
+	{
+	int type;
+	int save_type;
+	int references;
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	ENGINE *engine;
+	union	{
+		char *ptr;
+#ifndef OPENSSL_NO_RSA
+		struct rsa_st *rsa;	/* RSA */
+#endif
+#ifndef OPENSSL_NO_DSA
+		struct dsa_st *dsa;	/* DSA */
+#endif
+#ifndef OPENSSL_NO_DH
+		struct dh_st *dh;	/* DH */
+#endif
+#ifndef OPENSSL_NO_EC
+		struct ec_key_st *ec;	/* ECC */
+#endif
+		} pkey;
+	int save_parameters;
+	STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+	} /* EVP_PKEY */;
+
+#define EVP_PKEY_MO_SIGN	0x0001
+#define EVP_PKEY_MO_VERIFY	0x0002
+#define EVP_PKEY_MO_ENCRYPT	0x0004
+#define EVP_PKEY_MO_DECRYPT	0x0008
+
+#ifndef EVP_MD
+struct env_md_st
+	{
+	int type;
+	int pkey_type;
+	int md_size;
+	unsigned long flags;
+	int (*init)(EVP_MD_CTX *ctx);
+	int (*update)(EVP_MD_CTX *ctx,const void *data,size_t count);
+	int (*final)(EVP_MD_CTX *ctx,unsigned char *md);
+	int (*copy)(EVP_MD_CTX *to,const EVP_MD_CTX *from);
+	int (*cleanup)(EVP_MD_CTX *ctx);
+
+	/* FIXME: prototype these some day */
+	int (*sign)(int type, const unsigned char *m, unsigned int m_length,
+		    unsigned char *sigret, unsigned int *siglen, void *key);
+	int (*verify)(int type, const unsigned char *m, unsigned int m_length,
+		      const unsigned char *sigbuf, unsigned int siglen,
+		      void *key);
+	int required_pkey_type[5]; /*EVP_PKEY_xxx */
+	int block_size;
+	int ctx_size; /* how big does the ctx->md_data need to be */
+	/* control function */
+	int (*md_ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
+	} /* EVP_MD */;
+
+typedef int evp_sign_method(int type,const unsigned char *m,
+			    unsigned int m_length,unsigned char *sigret,
+			    unsigned int *siglen, void *key);
+typedef int evp_verify_method(int type,const unsigned char *m,
+			    unsigned int m_length,const unsigned char *sigbuf,
+			    unsigned int siglen, void *key);
+
+#define EVP_MD_FLAG_ONESHOT	0x0001 /* digest can only handle a single
+					* block */
+
+#define EVP_MD_FLAG_PKEY_DIGEST	0x0002 /* digest is a "clone" digest used
+					* which is a copy of an existing
+					* one for a specific public key type.
+					* EVP_dss1() etc */
+
+/* Digest uses EVP_PKEY_METHOD for signing instead of MD specific signing */
+
+#define EVP_MD_FLAG_PKEY_METHOD_SIGNATURE	0x0004
+
+/* DigestAlgorithmIdentifier flags... */
+
+#define EVP_MD_FLAG_DIGALGID_MASK		0x0018
+
+/* NULL or absent parameter accepted. Use NULL */
+
+#define EVP_MD_FLAG_DIGALGID_NULL		0x0000
+
+/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */
+
+#define EVP_MD_FLAG_DIGALGID_ABSENT		0x0008
+
+/* Custom handling via ctrl */
+
+#define EVP_MD_FLAG_DIGALGID_CUSTOM		0x0018
+
+/* Digest ctrls */
+
+#define	EVP_MD_CTRL_DIGALGID			0x1
+#define	EVP_MD_CTRL_MICALG			0x2
+
+/* Minimum Algorithm specific ctrl value */
+
+#define	EVP_MD_CTRL_ALG_CTRL			0x1000
+
+#define EVP_PKEY_NULL_method	NULL,NULL,{0,0,0,0}
+
+#ifndef OPENSSL_NO_DSA
+#define EVP_PKEY_DSA_method	(evp_sign_method *)DSA_sign, \
+				(evp_verify_method *)DSA_verify, \
+				{EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, \
+					EVP_PKEY_DSA4,0}
+#else
+#define EVP_PKEY_DSA_method	EVP_PKEY_NULL_method
+#endif
+
+#ifndef OPENSSL_NO_ECDSA
+#define EVP_PKEY_ECDSA_method   (evp_sign_method *)ECDSA_sign, \
+				(evp_verify_method *)ECDSA_verify, \
+                                 {EVP_PKEY_EC,0,0,0}
+#else   
+#define EVP_PKEY_ECDSA_method   EVP_PKEY_NULL_method
+#endif
+
+#ifndef OPENSSL_NO_RSA
+#define EVP_PKEY_RSA_method	(evp_sign_method *)RSA_sign, \
+				(evp_verify_method *)RSA_verify, \
+				{EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
+#define EVP_PKEY_RSA_ASN1_OCTET_STRING_method \
+				(evp_sign_method *)RSA_sign_ASN1_OCTET_STRING, \
+				(evp_verify_method *)RSA_verify_ASN1_OCTET_STRING, \
+				{EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
+#else
+#define EVP_PKEY_RSA_method	EVP_PKEY_NULL_method
+#define EVP_PKEY_RSA_ASN1_OCTET_STRING_method EVP_PKEY_NULL_method
+#endif
+
+#endif /* !EVP_MD */
+
+struct env_md_ctx_st
+	{
+	const EVP_MD *digest;
+	ENGINE *engine; /* functional reference if 'digest' is ENGINE-provided */
+	unsigned long flags;
+	void *md_data;
+	/* Public key context for sign/verify */
+	EVP_PKEY_CTX *pctx;
+	/* Update function: usually copied from EVP_MD */
+	int (*update)(EVP_MD_CTX *ctx,const void *data,size_t count);
+	} /* EVP_MD_CTX */;
+
+/* values for EVP_MD_CTX flags */
+
+#define EVP_MD_CTX_FLAG_ONESHOT		0x0001 /* digest update will be called
+						* once only */
+#define EVP_MD_CTX_FLAG_CLEANED		0x0002 /* context has already been
+						* cleaned */
+#define EVP_MD_CTX_FLAG_REUSE		0x0004 /* Don't free up ctx->md_data
+						* in EVP_MD_CTX_cleanup */
+/* FIPS and pad options are ignored in 1.0.0, definitions are here
+ * so we don't accidentally reuse the values for other purposes.
+ */
+
+#define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW	0x0008	/* Allow use of non FIPS digest
+						 * in FIPS mode */
+
+/* The following PAD options are also currently ignored in 1.0.0, digest
+ * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*()
+ * instead.
+ */
+#define EVP_MD_CTX_FLAG_PAD_MASK	0xF0	/* RSA mode to use */
+#define EVP_MD_CTX_FLAG_PAD_PKCS1	0x00	/* PKCS#1 v1.5 mode */
+#define EVP_MD_CTX_FLAG_PAD_X931	0x10	/* X9.31 mode */
+#define EVP_MD_CTX_FLAG_PAD_PSS		0x20	/* PSS mode */
+
+#define EVP_MD_CTX_FLAG_NO_INIT		0x0100 /* Don't initialize md_data */
+
+struct evp_cipher_st
+	{
+	int nid;
+	int block_size;
+	int key_len;		/* Default value for variable length ciphers */
+	int iv_len;
+	unsigned long flags;	/* Various flags */
+	int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+		    const unsigned char *iv, int enc);	/* init key */
+	int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			 const unsigned char *in, size_t inl);/* encrypt/decrypt data */
+	int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */
+	int ctx_size;		/* how big ctx->cipher_data needs to be */
+	int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */
+	int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */
+	int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscellaneous operations */
+	void *app_data;		/* Application data */
+	} /* EVP_CIPHER */;
+
+/* Values for cipher flags */
+
+/* Modes for ciphers */
+
+#define		EVP_CIPH_STREAM_CIPHER		0x0
+#define		EVP_CIPH_ECB_MODE		0x1
+#define		EVP_CIPH_CBC_MODE		0x2
+#define		EVP_CIPH_CFB_MODE		0x3
+#define		EVP_CIPH_OFB_MODE		0x4
+#define 	EVP_CIPH_MODE			0xF0007
+/* Set if variable length cipher */
+#define 	EVP_CIPH_VARIABLE_LENGTH	0x8
+/* Set if the iv handling should be done by the cipher itself */
+#define 	EVP_CIPH_CUSTOM_IV		0x10
+/* Set if the cipher's init() function should be called if key is NULL */
+#define 	EVP_CIPH_ALWAYS_CALL_INIT	0x20
+/* Call ctrl() to init cipher parameters */
+#define 	EVP_CIPH_CTRL_INIT		0x40
+/* Don't use standard key length function */
+#define 	EVP_CIPH_CUSTOM_KEY_LENGTH	0x80
+/* Don't use standard block padding */
+#define 	EVP_CIPH_NO_PADDING		0x100
+/* cipher handles random key generation */
+#define 	EVP_CIPH_RAND_KEY		0x200
+/* cipher has its own additional copying logic */
+#define 	EVP_CIPH_CUSTOM_COPY		0x400
+/* Allow use default ASN1 get/set iv */
+#define		EVP_CIPH_FLAG_DEFAULT_ASN1	0x1000
+/* Buffer length in bits not bytes: CFB1 mode only */
+#define		EVP_CIPH_FLAG_LENGTH_BITS	0x2000
+
+/* ctrl() values */
+
+#define		EVP_CTRL_INIT			0x0
+#define 	EVP_CTRL_SET_KEY_LENGTH		0x1
+#define 	EVP_CTRL_GET_RC2_KEY_BITS	0x2
+#define 	EVP_CTRL_SET_RC2_KEY_BITS	0x3
+#define 	EVP_CTRL_GET_RC5_ROUNDS		0x4
+#define 	EVP_CTRL_SET_RC5_ROUNDS		0x5
+#define 	EVP_CTRL_RAND_KEY		0x6
+#define 	EVP_CTRL_PBE_PRF_NID		0x7
+#define 	EVP_CTRL_COPY			0x8
+
+typedef struct evp_cipher_info_st
+	{
+	const EVP_CIPHER *cipher;
+	unsigned char iv[EVP_MAX_IV_LENGTH];
+	} EVP_CIPHER_INFO;
+
+struct evp_cipher_ctx_st
+	{
+	const EVP_CIPHER *cipher;
+	ENGINE *engine;	/* functional reference if 'cipher' is ENGINE-provided */
+	int encrypt;		/* encrypt or decrypt */
+	int buf_len;		/* number we have left */
+
+	unsigned char  oiv[EVP_MAX_IV_LENGTH];	/* original iv */
+	unsigned char  iv[EVP_MAX_IV_LENGTH];	/* working iv */
+	unsigned char buf[EVP_MAX_BLOCK_LENGTH];/* saved partial block */
+	int num;				/* used by cfb/ofb mode */
+
+	void *app_data;		/* application stuff */
+	int key_len;		/* May change for variable length cipher */
+	unsigned long flags;	/* Various flags */
+	void *cipher_data; /* per EVP data */
+	int final_used;
+	int block_mask;
+	unsigned char final[EVP_MAX_BLOCK_LENGTH];/* possible final block */
+	} /* EVP_CIPHER_CTX */;
+
+typedef struct evp_Encode_Ctx_st
+	{
+	int num;	/* number saved in a partial encode/decode */
+	int length;	/* The length is either the output line length
+			 * (in input bytes) or the shortest input line
+			 * length that is ok.  Once decoding begins,
+			 * the length is adjusted up each time a longer
+			 * line is decoded */
+	unsigned char enc_data[80];	/* data to encode */
+	int line_num;	/* number read on current line */
+	int expect_nl;
+	} EVP_ENCODE_CTX;
+
+/* Password based encryption function */
+typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+		ASN1_TYPE *param, const EVP_CIPHER *cipher,
+                const EVP_MD *md, int en_de);
+
+#ifndef OPENSSL_NO_RSA
+#define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
+					(char *)(rsa))
+#endif
+
+#ifndef OPENSSL_NO_DSA
+#define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
+					(char *)(dsa))
+#endif
+
+#ifndef OPENSSL_NO_DH
+#define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\
+					(char *)(dh))
+#endif
+
+#ifndef OPENSSL_NO_EC
+#define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\
+                                        (char *)(eckey))
+#endif
+
+/* Add some extra combinations */
+#define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a))
+#define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a))
+#define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))
+#define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))
+
+int EVP_MD_type(const EVP_MD *md);
+#define EVP_MD_nid(e)			EVP_MD_type(e)
+#define EVP_MD_name(e)			OBJ_nid2sn(EVP_MD_nid(e))
+int EVP_MD_pkey_type(const EVP_MD *md);	
+int EVP_MD_size(const EVP_MD *md);
+int EVP_MD_block_size(const EVP_MD *md);
+unsigned long EVP_MD_flags(const EVP_MD *md);
+
+const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
+#define EVP_MD_CTX_size(e)		EVP_MD_size(EVP_MD_CTX_md(e))
+#define EVP_MD_CTX_block_size(e)	EVP_MD_block_size(EVP_MD_CTX_md(e))
+#define EVP_MD_CTX_type(e)		EVP_MD_type(EVP_MD_CTX_md(e))
+
+int EVP_CIPHER_nid(const EVP_CIPHER *cipher);
+#define EVP_CIPHER_name(e)		OBJ_nid2sn(EVP_CIPHER_nid(e))
+int EVP_CIPHER_block_size(const EVP_CIPHER *cipher);
+int EVP_CIPHER_key_length(const EVP_CIPHER *cipher);
+int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher);
+unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher);
+#define EVP_CIPHER_mode(e)		(EVP_CIPHER_flags(e) & EVP_CIPH_MODE)
+
+const EVP_CIPHER * EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in);
+void * EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx);
+void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data);
+#define EVP_CIPHER_CTX_type(c)         EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c))
+unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx);
+#define EVP_CIPHER_CTX_mode(e)		(EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE)
+
+#define EVP_ENCODE_LENGTH(l)	(((l+2)/3*4)+(l/48+1)*2+80)
+#define EVP_DECODE_LENGTH(l)	((l+3)/4*3+80)
+
+#define EVP_SignInit_ex(a,b,c)		EVP_DigestInit_ex(a,b,c)
+#define EVP_SignInit(a,b)		EVP_DigestInit(a,b)
+#define EVP_SignUpdate(a,b,c)		EVP_DigestUpdate(a,b,c)
+#define	EVP_VerifyInit_ex(a,b,c)	EVP_DigestInit_ex(a,b,c)
+#define	EVP_VerifyInit(a,b)		EVP_DigestInit(a,b)
+#define	EVP_VerifyUpdate(a,b,c)		EVP_DigestUpdate(a,b,c)
+#define EVP_OpenUpdate(a,b,c,d,e)	EVP_DecryptUpdate(a,b,c,d,e)
+#define EVP_SealUpdate(a,b,c,d,e)	EVP_EncryptUpdate(a,b,c,d,e)	
+#define EVP_DigestSignUpdate(a,b,c)	EVP_DigestUpdate(a,b,c)
+#define EVP_DigestVerifyUpdate(a,b,c)	EVP_DigestUpdate(a,b,c)
+
+#ifdef CONST_STRICT
+void BIO_set_md(BIO *,const EVP_MD *md);
+#else
+# define BIO_set_md(b,md)		BIO_ctrl(b,BIO_C_SET_MD,0,(char *)md)
+#endif
+#define BIO_get_md(b,mdp)		BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp)
+#define BIO_get_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp)
+#define BIO_set_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_SET_MD_CTX,0,(char *)mdcp)
+#define BIO_get_cipher_status(b)	BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL)
+#define BIO_get_cipher_ctx(b,c_pp)	BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp)
+
+int EVP_Cipher(EVP_CIPHER_CTX *c,
+		unsigned char *out,
+		const unsigned char *in,
+		unsigned int inl);
+
+#define EVP_add_cipher_alias(n,alias) \
+	OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n))
+#define EVP_add_digest_alias(n,alias) \
+	OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n))
+#define EVP_delete_cipher_alias(alias) \
+	OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS);
+#define EVP_delete_digest_alias(alias) \
+	OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS);
+
+void	EVP_MD_CTX_init(EVP_MD_CTX *ctx);
+int	EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
+EVP_MD_CTX *EVP_MD_CTX_create(void);
+void	EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
+int     EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in);  
+void	EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags);
+void	EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags);
+int 	EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx,int flags);
+int	EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
+int	EVP_DigestUpdate(EVP_MD_CTX *ctx,const void *d,
+			 size_t cnt);
+int	EVP_DigestFinal_ex(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
+int	EVP_Digest(const void *data, size_t count,
+		unsigned char *md, unsigned int *size, const EVP_MD *type, ENGINE *impl);
+
+int     EVP_MD_CTX_copy(EVP_MD_CTX *out,const EVP_MD_CTX *in);  
+int	EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
+int	EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
+
+int	EVP_read_pw_string(char *buf,int length,const char *prompt,int verify);
+int	EVP_read_pw_string_min(char *buf,int minlen,int maxlen,const char *prompt,int verify);
+void	EVP_set_pw_prompt(const char *prompt);
+char *	EVP_get_pw_prompt(void);
+
+int	EVP_BytesToKey(const EVP_CIPHER *type,const EVP_MD *md,
+		const unsigned char *salt, const unsigned char *data,
+		int datal, int count, unsigned char *key,unsigned char *iv);
+
+void	EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags);
+void	EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags);
+int 	EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx,int flags);
+
+int	EVP_EncryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher,
+		const unsigned char *key, const unsigned char *iv);
+int	EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
+		const unsigned char *key, const unsigned char *iv);
+int	EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+		int *outl, const unsigned char *in, int inl);
+int	EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+int	EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+
+int	EVP_DecryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher,
+		const unsigned char *key, const unsigned char *iv);
+int	EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
+		const unsigned char *key, const unsigned char *iv);
+int	EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+		int *outl, const unsigned char *in, int inl);
+int	EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+int	EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+
+int	EVP_CipherInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher,
+		       const unsigned char *key,const unsigned char *iv,
+		       int enc);
+int	EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
+		       const unsigned char *key,const unsigned char *iv,
+		       int enc);
+int	EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+		int *outl, const unsigned char *in, int inl);
+int	EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+int	EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+
+int	EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s,
+		EVP_PKEY *pkey);
+
+int	EVP_VerifyFinal(EVP_MD_CTX *ctx,const unsigned char *sigbuf,
+		unsigned int siglen,EVP_PKEY *pkey);
+
+int	EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
+int	EVP_DigestSignFinal(EVP_MD_CTX *ctx,
+			unsigned char *sigret, size_t *siglen);
+
+int	EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
+int	EVP_DigestVerifyFinal(EVP_MD_CTX *ctx,
+			unsigned char *sig, size_t siglen);
+
+int	EVP_OpenInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type,
+		const unsigned char *ek, int ekl, const unsigned char *iv,
+		EVP_PKEY *priv);
+int	EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+
+int	EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+		 unsigned char **ek, int *ekl, unsigned char *iv,
+		EVP_PKEY **pubk, int npubk);
+int	EVP_SealFinal(EVP_CIPHER_CTX *ctx,unsigned char *out,int *outl);
+
+void	EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
+void	EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl,
+		const unsigned char *in,int inl);
+void	EVP_EncodeFinal(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl);
+int	EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n);
+
+void	EVP_DecodeInit(EVP_ENCODE_CTX *ctx);
+int	EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl,
+		const unsigned char *in, int inl);
+int	EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned
+		char *out, int *outl);
+int	EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n);
+
+void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
+int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
+EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
+void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a);
+int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
+int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad);
+int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
+int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key);
+
+#ifndef OPENSSL_NO_BIO
+BIO_METHOD *BIO_f_md(void);
+BIO_METHOD *BIO_f_base64(void);
+BIO_METHOD *BIO_f_cipher(void);
+BIO_METHOD *BIO_f_reliable(void);
+void BIO_set_cipher(BIO *b,const EVP_CIPHER *c,const unsigned char *k,
+		const unsigned char *i, int enc);
+#endif
+
+const EVP_MD *EVP_md_null(void);
+#ifndef OPENSSL_NO_MD2
+const EVP_MD *EVP_md2(void);
+#endif
+#ifndef OPENSSL_NO_MD4
+const EVP_MD *EVP_md4(void);
+#endif
+#ifndef OPENSSL_NO_MD5
+const EVP_MD *EVP_md5(void);
+#endif
+#ifndef OPENSSL_NO_SHA
+const EVP_MD *EVP_sha(void);
+const EVP_MD *EVP_sha1(void);
+const EVP_MD *EVP_dss(void);
+const EVP_MD *EVP_dss1(void);
+const EVP_MD *EVP_ecdsa(void);
+#endif
+#ifndef OPENSSL_NO_SHA256
+const EVP_MD *EVP_sha224(void);
+const EVP_MD *EVP_sha256(void);
+#endif
+#ifndef OPENSSL_NO_SHA512
+const EVP_MD *EVP_sha384(void);
+const EVP_MD *EVP_sha512(void);
+#endif
+#ifndef OPENSSL_NO_MDC2
+const EVP_MD *EVP_mdc2(void);
+#endif
+#ifndef OPENSSL_NO_RIPEMD
+const EVP_MD *EVP_ripemd160(void);
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+const EVP_MD *EVP_whirlpool(void);
+#endif
+const EVP_CIPHER *EVP_enc_null(void);		/* does nothing :-) */
+#ifndef OPENSSL_NO_DES
+const EVP_CIPHER *EVP_des_ecb(void);
+const EVP_CIPHER *EVP_des_ede(void);
+const EVP_CIPHER *EVP_des_ede3(void);
+const EVP_CIPHER *EVP_des_ede_ecb(void);
+const EVP_CIPHER *EVP_des_ede3_ecb(void);
+const EVP_CIPHER *EVP_des_cfb64(void);
+# define EVP_des_cfb EVP_des_cfb64
+const EVP_CIPHER *EVP_des_cfb1(void);
+const EVP_CIPHER *EVP_des_cfb8(void);
+const EVP_CIPHER *EVP_des_ede_cfb64(void);
+# define EVP_des_ede_cfb EVP_des_ede_cfb64
+#if 0
+const EVP_CIPHER *EVP_des_ede_cfb1(void);
+const EVP_CIPHER *EVP_des_ede_cfb8(void);
+#endif
+const EVP_CIPHER *EVP_des_ede3_cfb64(void);
+# define EVP_des_ede3_cfb EVP_des_ede3_cfb64
+const EVP_CIPHER *EVP_des_ede3_cfb1(void);
+const EVP_CIPHER *EVP_des_ede3_cfb8(void);
+const EVP_CIPHER *EVP_des_ofb(void);
+const EVP_CIPHER *EVP_des_ede_ofb(void);
+const EVP_CIPHER *EVP_des_ede3_ofb(void);
+const EVP_CIPHER *EVP_des_cbc(void);
+const EVP_CIPHER *EVP_des_ede_cbc(void);
+const EVP_CIPHER *EVP_des_ede3_cbc(void);
+const EVP_CIPHER *EVP_desx_cbc(void);
+/* This should now be supported through the dev_crypto ENGINE. But also, why are
+ * rc4 and md5 declarations made here inside a "NO_DES" precompiler branch? */
+#if 0
+# ifdef OPENSSL_OPENBSD_DEV_CRYPTO
+const EVP_CIPHER *EVP_dev_crypto_des_ede3_cbc(void);
+const EVP_CIPHER *EVP_dev_crypto_rc4(void);
+const EVP_MD *EVP_dev_crypto_md5(void);
+# endif
+#endif
+#endif
+#ifndef OPENSSL_NO_RC4
+const EVP_CIPHER *EVP_rc4(void);
+const EVP_CIPHER *EVP_rc4_40(void);
+#endif
+#ifndef OPENSSL_NO_IDEA
+const EVP_CIPHER *EVP_idea_ecb(void);
+const EVP_CIPHER *EVP_idea_cfb64(void);
+# define EVP_idea_cfb EVP_idea_cfb64
+const EVP_CIPHER *EVP_idea_ofb(void);
+const EVP_CIPHER *EVP_idea_cbc(void);
+#endif
+#ifndef OPENSSL_NO_RC2
+const EVP_CIPHER *EVP_rc2_ecb(void);
+const EVP_CIPHER *EVP_rc2_cbc(void);
+const EVP_CIPHER *EVP_rc2_40_cbc(void);
+const EVP_CIPHER *EVP_rc2_64_cbc(void);
+const EVP_CIPHER *EVP_rc2_cfb64(void);
+# define EVP_rc2_cfb EVP_rc2_cfb64
+const EVP_CIPHER *EVP_rc2_ofb(void);
+#endif
+#ifndef OPENSSL_NO_BF
+const EVP_CIPHER *EVP_bf_ecb(void);
+const EVP_CIPHER *EVP_bf_cbc(void);
+const EVP_CIPHER *EVP_bf_cfb64(void);
+# define EVP_bf_cfb EVP_bf_cfb64
+const EVP_CIPHER *EVP_bf_ofb(void);
+#endif
+#ifndef OPENSSL_NO_CAST
+const EVP_CIPHER *EVP_cast5_ecb(void);
+const EVP_CIPHER *EVP_cast5_cbc(void);
+const EVP_CIPHER *EVP_cast5_cfb64(void);
+# define EVP_cast5_cfb EVP_cast5_cfb64
+const EVP_CIPHER *EVP_cast5_ofb(void);
+#endif
+#ifndef OPENSSL_NO_RC5
+const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void);
+const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void);
+const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void);
+# define EVP_rc5_32_12_16_cfb EVP_rc5_32_12_16_cfb64
+const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void);
+#endif
+#ifndef OPENSSL_NO_AES
+const EVP_CIPHER *EVP_aes_128_ecb(void);
+const EVP_CIPHER *EVP_aes_128_cbc(void);
+const EVP_CIPHER *EVP_aes_128_cfb1(void);
+const EVP_CIPHER *EVP_aes_128_cfb8(void);
+const EVP_CIPHER *EVP_aes_128_cfb128(void);
+# define EVP_aes_128_cfb EVP_aes_128_cfb128
+const EVP_CIPHER *EVP_aes_128_ofb(void);
+#if 0
+const EVP_CIPHER *EVP_aes_128_ctr(void);
+#endif
+const EVP_CIPHER *EVP_aes_192_ecb(void);
+const EVP_CIPHER *EVP_aes_192_cbc(void);
+const EVP_CIPHER *EVP_aes_192_cfb1(void);
+const EVP_CIPHER *EVP_aes_192_cfb8(void);
+const EVP_CIPHER *EVP_aes_192_cfb128(void);
+# define EVP_aes_192_cfb EVP_aes_192_cfb128
+const EVP_CIPHER *EVP_aes_192_ofb(void);
+#if 0
+const EVP_CIPHER *EVP_aes_192_ctr(void);
+#endif
+const EVP_CIPHER *EVP_aes_256_ecb(void);
+const EVP_CIPHER *EVP_aes_256_cbc(void);
+const EVP_CIPHER *EVP_aes_256_cfb1(void);
+const EVP_CIPHER *EVP_aes_256_cfb8(void);
+const EVP_CIPHER *EVP_aes_256_cfb128(void);
+# define EVP_aes_256_cfb EVP_aes_256_cfb128
+const EVP_CIPHER *EVP_aes_256_ofb(void);
+#if 0
+const EVP_CIPHER *EVP_aes_256_ctr(void);
+#endif
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+const EVP_CIPHER *EVP_camellia_128_ecb(void);
+const EVP_CIPHER *EVP_camellia_128_cbc(void);
+const EVP_CIPHER *EVP_camellia_128_cfb1(void);
+const EVP_CIPHER *EVP_camellia_128_cfb8(void);
+const EVP_CIPHER *EVP_camellia_128_cfb128(void);
+# define EVP_camellia_128_cfb EVP_camellia_128_cfb128
+const EVP_CIPHER *EVP_camellia_128_ofb(void);
+const EVP_CIPHER *EVP_camellia_192_ecb(void);
+const EVP_CIPHER *EVP_camellia_192_cbc(void);
+const EVP_CIPHER *EVP_camellia_192_cfb1(void);
+const EVP_CIPHER *EVP_camellia_192_cfb8(void);
+const EVP_CIPHER *EVP_camellia_192_cfb128(void);
+# define EVP_camellia_192_cfb EVP_camellia_192_cfb128
+const EVP_CIPHER *EVP_camellia_192_ofb(void);
+const EVP_CIPHER *EVP_camellia_256_ecb(void);
+const EVP_CIPHER *EVP_camellia_256_cbc(void);
+const EVP_CIPHER *EVP_camellia_256_cfb1(void);
+const EVP_CIPHER *EVP_camellia_256_cfb8(void);
+const EVP_CIPHER *EVP_camellia_256_cfb128(void);
+# define EVP_camellia_256_cfb EVP_camellia_256_cfb128
+const EVP_CIPHER *EVP_camellia_256_ofb(void);
+#endif
+
+#ifndef OPENSSL_NO_SEED
+const EVP_CIPHER *EVP_seed_ecb(void);
+const EVP_CIPHER *EVP_seed_cbc(void);
+const EVP_CIPHER *EVP_seed_cfb128(void);
+# define EVP_seed_cfb EVP_seed_cfb128
+const EVP_CIPHER *EVP_seed_ofb(void);
+#endif
+
+void OPENSSL_add_all_algorithms_noconf(void);
+void OPENSSL_add_all_algorithms_conf(void);
+
+#ifdef OPENSSL_LOAD_CONF
+#define OpenSSL_add_all_algorithms() \
+		OPENSSL_add_all_algorithms_conf()
+#else
+#define OpenSSL_add_all_algorithms() \
+		OPENSSL_add_all_algorithms_noconf()
+#endif
+
+void OpenSSL_add_all_ciphers(void);
+void OpenSSL_add_all_digests(void);
+#define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms()
+#define SSLeay_add_all_ciphers() OpenSSL_add_all_ciphers()
+#define SSLeay_add_all_digests() OpenSSL_add_all_digests()
+
+int EVP_add_cipher(const EVP_CIPHER *cipher);
+int EVP_add_digest(const EVP_MD *digest);
+
+const EVP_CIPHER *EVP_get_cipherbyname(const char *name);
+const EVP_MD *EVP_get_digestbyname(const char *name);
+void EVP_cleanup(void);
+
+void EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph,
+		const char *from, const char *to, void *x), void *arg);
+void EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph,
+		const char *from, const char *to, void *x), void *arg);
+
+void EVP_MD_do_all(void (*fn)(const EVP_MD *ciph,
+		const char *from, const char *to, void *x), void *arg);
+void EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *ciph,
+		const char *from, const char *to, void *x), void *arg);
+
+int		EVP_PKEY_decrypt_old(unsigned char *dec_key,
+			const unsigned char *enc_key,int enc_key_len,
+			EVP_PKEY *private_key);
+int		EVP_PKEY_encrypt_old(unsigned char *enc_key,
+			const unsigned char *key,int key_len,
+			EVP_PKEY *pub_key);
+int		EVP_PKEY_type(int type);
+int		EVP_PKEY_id(const EVP_PKEY *pkey);
+int		EVP_PKEY_base_id(const EVP_PKEY *pkey);
+int		EVP_PKEY_bits(EVP_PKEY *pkey);
+int		EVP_PKEY_size(EVP_PKEY *pkey);
+int 		EVP_PKEY_set_type(EVP_PKEY *pkey,int type);
+int		EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len);
+int 		EVP_PKEY_assign(EVP_PKEY *pkey,int type,void *key);
+void *		EVP_PKEY_get0(EVP_PKEY *pkey);
+
+#ifndef OPENSSL_NO_RSA
+struct rsa_st;
+int EVP_PKEY_set1_RSA(EVP_PKEY *pkey,struct rsa_st *key);
+struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey);
+#endif
+#ifndef OPENSSL_NO_DSA
+struct dsa_st;
+int EVP_PKEY_set1_DSA(EVP_PKEY *pkey,struct dsa_st *key);
+struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
+#endif
+#ifndef OPENSSL_NO_DH
+struct dh_st;
+int EVP_PKEY_set1_DH(EVP_PKEY *pkey,struct dh_st *key);
+struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
+#endif
+#ifndef OPENSSL_NO_EC
+struct ec_key_st;
+int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey,struct ec_key_st *key);
+struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
+#endif
+
+EVP_PKEY *	EVP_PKEY_new(void);
+void		EVP_PKEY_free(EVP_PKEY *pkey);
+
+EVP_PKEY *	d2i_PublicKey(int type,EVP_PKEY **a, const unsigned char **pp,
+			long length);
+int		i2d_PublicKey(EVP_PKEY *a, unsigned char **pp);
+
+EVP_PKEY *	d2i_PrivateKey(int type,EVP_PKEY **a, const unsigned char **pp,
+			long length);
+EVP_PKEY *	d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
+			long length);
+int		i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp);
+
+int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from);
+int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey);
+int EVP_PKEY_save_parameters(EVP_PKEY *pkey,int mode);
+int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b);
+
+int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
+
+int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx);
+int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx);
+int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx);
+
+int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
+
+int EVP_CIPHER_type(const EVP_CIPHER *ctx);
+
+/* calls methods */
+int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+
+/* These are used by EVP_CIPHER methods */
+int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c,ASN1_TYPE *type);
+int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c,ASN1_TYPE *type);
+
+/* PKCS5 password based encryption */
+int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+			 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md,
+			 int en_de);
+int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
+			   const unsigned char *salt, int saltlen, int iter,
+			   int keylen, unsigned char *out);
+int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
+			   const unsigned char *salt, int saltlen, int iter,
+			   const EVP_MD *digest,
+		      int keylen, unsigned char *out);
+int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+			 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md,
+			 int en_de);
+
+void PKCS5_PBE_add(void);
+
+int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
+	     ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de);
+
+/* PBE type */
+
+/* Can appear as the outermost AlgorithmIdentifier */
+#define EVP_PBE_TYPE_OUTER	0x0
+/* Is an PRF type OID */
+#define EVP_PBE_TYPE_PRF	0x1
+
+int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid,
+	     EVP_PBE_KEYGEN *keygen);
+int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
+		    EVP_PBE_KEYGEN *keygen);
+int EVP_PBE_find(int type, int pbe_nid,
+			int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen);
+void EVP_PBE_cleanup(void);
+
+#define ASN1_PKEY_ALIAS		0x1
+#define ASN1_PKEY_DYNAMIC	0x2
+#define ASN1_PKEY_SIGPARAM_NULL	0x4
+
+#define ASN1_PKEY_CTRL_PKCS7_SIGN	0x1
+#define ASN1_PKEY_CTRL_PKCS7_ENCRYPT	0x2
+#define ASN1_PKEY_CTRL_DEFAULT_MD_NID	0x3
+#define ASN1_PKEY_CTRL_CMS_SIGN		0x5
+#define ASN1_PKEY_CTRL_CMS_ENVELOPE	0x7
+
+int EVP_PKEY_asn1_get_count(void);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
+					const char *str, int len);
+int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth);
+int EVP_PKEY_asn1_add_alias(int to, int from);
+int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, int *ppkey_flags,
+				const char **pinfo, const char **ppem_str,
+					const EVP_PKEY_ASN1_METHOD *ameth);
+
+const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey);
+EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
+					const char *pem_str, const char *info);
+void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, 
+			const EVP_PKEY_ASN1_METHOD *src);
+void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth);
+void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
+		int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub),
+		int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk),
+		int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
+		int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx),
+		int (*pkey_size)(const EVP_PKEY *pk),
+		int (*pkey_bits)(const EVP_PKEY *pk));
+void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
+		int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf),
+		int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk),
+		int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx));
+void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
+		int (*param_decode)(EVP_PKEY *pkey,
+				const unsigned char **pder, int derlen),
+		int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder),
+		int (*param_missing)(const EVP_PKEY *pk),
+		int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from),
+		int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
+		int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx));
+
+void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
+		void (*pkey_free)(EVP_PKEY *pkey));
+void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
+		int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
+							long arg1, void *arg2));
+
+
+#define EVP_PKEY_OP_UNDEFINED		0
+#define EVP_PKEY_OP_PARAMGEN		(1<<1)
+#define EVP_PKEY_OP_KEYGEN		(1<<2)
+#define EVP_PKEY_OP_SIGN		(1<<3)
+#define EVP_PKEY_OP_VERIFY		(1<<4)
+#define EVP_PKEY_OP_VERIFYRECOVER	(1<<5)
+#define EVP_PKEY_OP_SIGNCTX		(1<<6)
+#define EVP_PKEY_OP_VERIFYCTX		(1<<7)
+#define EVP_PKEY_OP_ENCRYPT		(1<<8)
+#define EVP_PKEY_OP_DECRYPT		(1<<9)
+#define EVP_PKEY_OP_DERIVE		(1<<10)
+
+#define EVP_PKEY_OP_TYPE_SIG	\
+	(EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \
+		| EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX)
+
+#define EVP_PKEY_OP_TYPE_CRYPT \
+	(EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT)
+
+#define EVP_PKEY_OP_TYPE_NOGEN \
+	(EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE)
+
+#define EVP_PKEY_OP_TYPE_GEN \
+		(EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
+
+#define	 EVP_PKEY_CTX_set_signature_md(ctx, md)	\
+		EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,  \
+					EVP_PKEY_CTRL_MD, 0, (void *)md)
+
+#define EVP_PKEY_CTRL_MD		1
+#define EVP_PKEY_CTRL_PEER_KEY		2
+
+#define EVP_PKEY_CTRL_PKCS7_ENCRYPT	3
+#define EVP_PKEY_CTRL_PKCS7_DECRYPT	4
+
+#define EVP_PKEY_CTRL_PKCS7_SIGN	5
+
+#define EVP_PKEY_CTRL_SET_MAC_KEY	6
+
+#define EVP_PKEY_CTRL_DIGESTINIT	7
+
+/* Used by GOST key encryption in TLS */
+#define EVP_PKEY_CTRL_SET_IV 		8
+
+#define EVP_PKEY_CTRL_CMS_ENCRYPT	9
+#define EVP_PKEY_CTRL_CMS_DECRYPT	10
+#define EVP_PKEY_CTRL_CMS_SIGN		11
+
+#define EVP_PKEY_ALG_CTRL		0x1000
+
+
+#define EVP_PKEY_FLAG_AUTOARGLEN	2
+
+const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type);
+EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags);
+void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth);
+int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth);
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
+EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx);
+void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
+				int cmd, int p1, void *p2);
+int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
+						const char *value);
+
+int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx);
+void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen);
+
+EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
+				unsigned char *key, int keylen);
+
+void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);
+void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx);
+EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx);
+
+EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx);
+
+void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
+void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
+			unsigned char *sig, size_t *siglen,
+			const unsigned char *tbs, size_t tbslen);
+int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
+			const unsigned char *sig, size_t siglen,
+			const unsigned char *tbs, size_t tbslen);
+int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
+			unsigned char *rout, size_t *routlen,
+			const unsigned char *sig, size_t siglen);
+int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
+			unsigned char *out, size_t *outlen,
+			const unsigned char *in, size_t inlen);
+int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
+			unsigned char *out, size_t *outlen,
+			const unsigned char *in, size_t inlen);
+
+int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
+int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
+
+typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
+int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
+
+void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb);
+EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx);
+
+void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
+	int (*init)(EVP_PKEY_CTX *ctx));
+
+void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
+	int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src));
+
+void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
+	void (*cleanup)(EVP_PKEY_CTX *ctx));
+
+void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
+	int (*paramgen_init)(EVP_PKEY_CTX *ctx),
+	int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey));
+
+void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
+	int (*keygen_init)(EVP_PKEY_CTX *ctx),
+	int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey));
+
+void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
+	int (*sign_init)(EVP_PKEY_CTX *ctx),
+	int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					const unsigned char *tbs, size_t tbslen));
+
+void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
+	int (*verify_init)(EVP_PKEY_CTX *ctx),
+	int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
+					const unsigned char *tbs, size_t tbslen));
+
+void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
+	int (*verify_recover_init)(EVP_PKEY_CTX *ctx),
+	int (*verify_recover)(EVP_PKEY_CTX *ctx,
+					unsigned char *sig, size_t *siglen,
+					const unsigned char *tbs, size_t tbslen));
+
+void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
+	int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
+	int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					EVP_MD_CTX *mctx));
+
+void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
+	int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
+	int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,int siglen,
+					EVP_MD_CTX *mctx));
+
+void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
+	int (*encrypt_init)(EVP_PKEY_CTX *ctx),
+	int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen));
+
+void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
+	int (*decrypt_init)(EVP_PKEY_CTX *ctx),
+	int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen));
+
+void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
+	int (*derive_init)(EVP_PKEY_CTX *ctx),
+	int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen));
+
+void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
+	int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2),
+	int (*ctrl_str)(EVP_PKEY_CTX *ctx,
+					const char *type, const char *value));
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_EVP_strings(void);
+
+/* Error codes for the EVP functions. */
+
+/* Function codes. */
+#define EVP_F_AES_INIT_KEY				 133
+#define EVP_F_CAMELLIA_INIT_KEY				 159
+#define EVP_F_D2I_PKEY					 100
+#define EVP_F_DO_SIGVER_INIT				 161
+#define EVP_F_DSAPKEY2PKCS8				 134
+#define EVP_F_DSA_PKEY2PKCS8				 135
+#define EVP_F_ECDSA_PKEY2PKCS8				 129
+#define EVP_F_ECKEY_PKEY2PKCS8				 132
+#define EVP_F_EVP_CIPHERINIT_EX				 123
+#define EVP_F_EVP_CIPHER_CTX_COPY			 163
+#define EVP_F_EVP_CIPHER_CTX_CTRL			 124
+#define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH		 122
+#define EVP_F_EVP_DECRYPTFINAL_EX			 101
+#define EVP_F_EVP_DIGESTINIT_EX				 128
+#define EVP_F_EVP_ENCRYPTFINAL_EX			 127
+#define EVP_F_EVP_MD_CTX_COPY_EX			 110
+#define EVP_F_EVP_MD_SIZE				 162
+#define EVP_F_EVP_OPENINIT				 102
+#define EVP_F_EVP_PBE_ALG_ADD				 115
+#define EVP_F_EVP_PBE_ALG_ADD_TYPE			 160
+#define EVP_F_EVP_PBE_CIPHERINIT			 116
+#define EVP_F_EVP_PKCS82PKEY				 111
+#define EVP_F_EVP_PKCS82PKEY_BROKEN			 136
+#define EVP_F_EVP_PKEY2PKCS8_BROKEN			 113
+#define EVP_F_EVP_PKEY_COPY_PARAMETERS			 103
+#define EVP_F_EVP_PKEY_CTX_CTRL				 137
+#define EVP_F_EVP_PKEY_CTX_CTRL_STR			 150
+#define EVP_F_EVP_PKEY_CTX_DUP				 156
+#define EVP_F_EVP_PKEY_DECRYPT				 104
+#define EVP_F_EVP_PKEY_DECRYPT_INIT			 138
+#define EVP_F_EVP_PKEY_DECRYPT_OLD			 151
+#define EVP_F_EVP_PKEY_DERIVE				 153
+#define EVP_F_EVP_PKEY_DERIVE_INIT			 154
+#define EVP_F_EVP_PKEY_DERIVE_SET_PEER			 155
+#define EVP_F_EVP_PKEY_ENCRYPT				 105
+#define EVP_F_EVP_PKEY_ENCRYPT_INIT			 139
+#define EVP_F_EVP_PKEY_ENCRYPT_OLD			 152
+#define EVP_F_EVP_PKEY_GET1_DH				 119
+#define EVP_F_EVP_PKEY_GET1_DSA				 120
+#define EVP_F_EVP_PKEY_GET1_ECDSA			 130
+#define EVP_F_EVP_PKEY_GET1_EC_KEY			 131
+#define EVP_F_EVP_PKEY_GET1_RSA				 121
+#define EVP_F_EVP_PKEY_KEYGEN				 146
+#define EVP_F_EVP_PKEY_KEYGEN_INIT			 147
+#define EVP_F_EVP_PKEY_NEW				 106
+#define EVP_F_EVP_PKEY_PARAMGEN				 148
+#define EVP_F_EVP_PKEY_PARAMGEN_INIT			 149
+#define EVP_F_EVP_PKEY_SIGN				 140
+#define EVP_F_EVP_PKEY_SIGN_INIT			 141
+#define EVP_F_EVP_PKEY_VERIFY				 142
+#define EVP_F_EVP_PKEY_VERIFY_INIT			 143
+#define EVP_F_EVP_PKEY_VERIFY_RECOVER			 144
+#define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT		 145
+#define EVP_F_EVP_RIJNDAEL				 126
+#define EVP_F_EVP_SIGNFINAL				 107
+#define EVP_F_EVP_VERIFYFINAL				 108
+#define EVP_F_INT_CTX_NEW				 157
+#define EVP_F_PKCS5_PBE_KEYIVGEN			 117
+#define EVP_F_PKCS5_V2_PBE_KEYIVGEN			 118
+#define EVP_F_PKCS8_SET_BROKEN				 112
+#define EVP_F_PKEY_SET_TYPE				 158
+#define EVP_F_RC2_MAGIC_TO_METH				 109
+#define EVP_F_RC5_CTRL					 125
+
+/* Reason codes. */
+#define EVP_R_AES_KEY_SETUP_FAILED			 143
+#define EVP_R_ASN1_LIB					 140
+#define EVP_R_BAD_BLOCK_LENGTH				 136
+#define EVP_R_BAD_DECRYPT				 100
+#define EVP_R_BAD_KEY_LENGTH				 137
+#define EVP_R_BN_DECODE_ERROR				 112
+#define EVP_R_BN_PUBKEY_ERROR				 113
+#define EVP_R_BUFFER_TOO_SMALL				 155
+#define EVP_R_CAMELLIA_KEY_SETUP_FAILED			 157
+#define EVP_R_CIPHER_PARAMETER_ERROR			 122
+#define EVP_R_COMMAND_NOT_SUPPORTED			 147
+#define EVP_R_CTRL_NOT_IMPLEMENTED			 132
+#define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED		 133
+#define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH		 138
+#define EVP_R_DECODE_ERROR				 114
+#define EVP_R_DIFFERENT_KEY_TYPES			 101
+#define EVP_R_DIFFERENT_PARAMETERS			 153
+#define EVP_R_ENCODE_ERROR				 115
+#define EVP_R_EVP_PBE_CIPHERINIT_ERROR			 119
+#define EVP_R_EXPECTING_AN_RSA_KEY			 127
+#define EVP_R_EXPECTING_A_DH_KEY			 128
+#define EVP_R_EXPECTING_A_DSA_KEY			 129
+#define EVP_R_EXPECTING_A_ECDSA_KEY			 141
+#define EVP_R_EXPECTING_A_EC_KEY			 142
+#define EVP_R_INITIALIZATION_ERROR			 134
+#define EVP_R_INPUT_NOT_INITIALIZED			 111
+#define EVP_R_INVALID_DIGEST				 152
+#define EVP_R_INVALID_KEY_LENGTH			 130
+#define EVP_R_INVALID_OPERATION				 148
+#define EVP_R_IV_TOO_LARGE				 102
+#define EVP_R_KEYGEN_FAILURE				 120
+#define EVP_R_MESSAGE_DIGEST_IS_NULL			 159
+#define EVP_R_METHOD_NOT_SUPPORTED			 144
+#define EVP_R_MISSING_PARAMETERS			 103
+#define EVP_R_NO_CIPHER_SET				 131
+#define EVP_R_NO_DEFAULT_DIGEST				 158
+#define EVP_R_NO_DIGEST_SET				 139
+#define EVP_R_NO_DSA_PARAMETERS				 116
+#define EVP_R_NO_KEY_SET				 154
+#define EVP_R_NO_OPERATION_SET				 149
+#define EVP_R_NO_SIGN_FUNCTION_CONFIGURED		 104
+#define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED		 105
+#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE	 150
+#define EVP_R_OPERATON_NOT_INITIALIZED			 151
+#define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE			 117
+#define EVP_R_PRIVATE_KEY_DECODE_ERROR			 145
+#define EVP_R_PRIVATE_KEY_ENCODE_ERROR			 146
+#define EVP_R_PUBLIC_KEY_NOT_RSA			 106
+#define EVP_R_UNKNOWN_CIPHER				 160
+#define EVP_R_UNKNOWN_DIGEST				 161
+#define EVP_R_UNKNOWN_PBE_ALGORITHM			 121
+#define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS		 135
+#define EVP_R_UNSUPPORTED_ALGORITHM			 156
+#define EVP_R_UNSUPPORTED_CIPHER			 107
+#define EVP_R_UNSUPPORTED_KEYLENGTH			 123
+#define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION	 124
+#define EVP_R_UNSUPPORTED_KEY_SIZE			 108
+#define EVP_R_UNSUPPORTED_PRF				 125
+#define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM		 118
+#define EVP_R_UNSUPPORTED_SALT_TYPE			 126
+#define EVP_R_WRONG_FINAL_BLOCK_LENGTH			 109
+#define EVP_R_WRONG_PUBLIC_KEY_TYPE			 110
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/evp/evp_acnf.c b/openssl/crypto/evp/evp_acnf.c
new file mode 100644
index 0000000..643a186
--- /dev/null
+++ b/openssl/crypto/evp/evp_acnf.c
@@ -0,0 +1,73 @@
+/* evp_acnf.c */
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/conf.h>
+
+
+/* Load all algorithms and configure OpenSSL.
+ * This function is called automatically when
+ * OPENSSL_LOAD_CONF is set.
+ */
+
+void OPENSSL_add_all_algorithms_conf(void)
+	{
+	OPENSSL_add_all_algorithms_noconf();
+	OPENSSL_config(NULL);
+	}
diff --git a/openssl/crypto/evp/evp_enc.c b/openssl/crypto/evp/evp_enc.c
new file mode 100644
index 0000000..c268d25
--- /dev/null
+++ b/openssl/crypto/evp/evp_enc.c
@@ -0,0 +1,604 @@
+/* crypto/evp/evp_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include "evp_locl.h"
+
+const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
+
+void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
+	{
+	memset(ctx,0,sizeof(EVP_CIPHER_CTX));
+	/* ctx->cipher=NULL; */
+	}
+
+EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
+	{
+	EVP_CIPHER_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
+	if (ctx)
+		EVP_CIPHER_CTX_init(ctx);
+	return ctx;
+	}
+
+int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+	     const unsigned char *key, const unsigned char *iv, int enc)
+	{
+	if (cipher)
+		EVP_CIPHER_CTX_init(ctx);
+	return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc);
+	}
+
+int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
+	     const unsigned char *key, const unsigned char *iv, int enc)
+	{
+	if (enc == -1)
+		enc = ctx->encrypt;
+	else
+		{
+		if (enc)
+			enc = 1;
+		ctx->encrypt = enc;
+		}
+#ifndef OPENSSL_NO_ENGINE
+	/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
+	 * so this context may already have an ENGINE! Try to avoid releasing
+	 * the previous handle, re-querying for an ENGINE, and having a
+	 * reinitialisation, when it may all be unecessary. */
+	if (ctx->engine && ctx->cipher && (!cipher ||
+			(cipher && (cipher->nid == ctx->cipher->nid))))
+		goto skip_to_init;
+#endif
+	if (cipher)
+		{
+		/* Ensure a context left lying around from last time is cleared
+		 * (the previous check attempted to avoid this if the same
+		 * ENGINE and EVP_CIPHER could be used). */
+		EVP_CIPHER_CTX_cleanup(ctx);
+
+		/* Restore encrypt field: it is zeroed by cleanup */
+		ctx->encrypt = enc;
+#ifndef OPENSSL_NO_ENGINE
+		if(impl)
+			{
+			if (!ENGINE_init(impl))
+				{
+				EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
+				return 0;
+				}
+			}
+		else
+			/* Ask if an ENGINE is reserved for this job */
+			impl = ENGINE_get_cipher_engine(cipher->nid);
+		if(impl)
+			{
+			/* There's an ENGINE for this job ... (apparently) */
+			const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
+			if(!c)
+				{
+				/* One positive side-effect of US's export
+				 * control history, is that we should at least
+				 * be able to avoid using US mispellings of
+				 * "initialisation"? */
+				EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
+				return 0;
+				}
+			/* We'll use the ENGINE's private cipher definition */
+			cipher = c;
+			/* Store the ENGINE functional reference so we know
+			 * 'cipher' came from an ENGINE and we need to release
+			 * it when done. */
+			ctx->engine = impl;
+			}
+		else
+			ctx->engine = NULL;
+#endif
+
+		ctx->cipher=cipher;
+		if (ctx->cipher->ctx_size)
+			{
+			ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
+			if (!ctx->cipher_data)
+				{
+				EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
+				return 0;
+				}
+			}
+		else
+			{
+			ctx->cipher_data = NULL;
+			}
+		ctx->key_len = cipher->key_len;
+		ctx->flags = 0;
+		if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
+			{
+			if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
+				{
+				EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
+				return 0;
+				}
+			}
+		}
+	else if(!ctx->cipher)
+		{
+		EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
+		return 0;
+		}
+#ifndef OPENSSL_NO_ENGINE
+skip_to_init:
+#endif
+	/* we assume block size is a power of 2 in *cryptUpdate */
+	OPENSSL_assert(ctx->cipher->block_size == 1
+	    || ctx->cipher->block_size == 8
+	    || ctx->cipher->block_size == 16);
+
+	if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
+		switch(EVP_CIPHER_CTX_mode(ctx)) {
+
+			case EVP_CIPH_STREAM_CIPHER:
+			case EVP_CIPH_ECB_MODE:
+			break;
+
+			case EVP_CIPH_CFB_MODE:
+			case EVP_CIPH_OFB_MODE:
+
+			ctx->num = 0;
+			/* fall-through */
+
+			case EVP_CIPH_CBC_MODE:
+
+			OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <=
+					(int)sizeof(ctx->iv));
+			if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+			memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
+			break;
+
+			default:
+			return 0;
+			break;
+		}
+	}
+
+	if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
+		if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
+	}
+	ctx->buf_len=0;
+	ctx->final_used=0;
+	ctx->block_mask=ctx->cipher->block_size-1;
+	return 1;
+	}
+
+int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+	     const unsigned char *in, int inl)
+	{
+	if (ctx->encrypt)
+		return EVP_EncryptUpdate(ctx,out,outl,in,inl);
+	else	return EVP_DecryptUpdate(ctx,out,outl,in,inl);
+	}
+
+int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+	{
+	if (ctx->encrypt)
+		return EVP_EncryptFinal_ex(ctx,out,outl);
+	else	return EVP_DecryptFinal_ex(ctx,out,outl);
+	}
+
+int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+	{
+	if (ctx->encrypt)
+		return EVP_EncryptFinal(ctx,out,outl);
+	else	return EVP_DecryptFinal(ctx,out,outl);
+	}
+
+int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+	     const unsigned char *key, const unsigned char *iv)
+	{
+	return EVP_CipherInit(ctx, cipher, key, iv, 1);
+	}
+
+int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
+		const unsigned char *key, const unsigned char *iv)
+	{
+	return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1);
+	}
+
+int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+	     const unsigned char *key, const unsigned char *iv)
+	{
+	return EVP_CipherInit(ctx, cipher, key, iv, 0);
+	}
+
+int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
+	     const unsigned char *key, const unsigned char *iv)
+	{
+	return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0);
+	}
+
+int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+	     const unsigned char *in, int inl)
+	{
+	int i,j,bl;
+
+	if (inl <= 0)
+		{
+		*outl = 0;
+		return inl == 0;
+		}
+
+	if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
+		{
+		if(ctx->cipher->do_cipher(ctx,out,in,inl))
+			{
+			*outl=inl;
+			return 1;
+			}
+		else
+			{
+			*outl=0;
+			return 0;
+			}
+		}
+	i=ctx->buf_len;
+	bl=ctx->cipher->block_size;
+	OPENSSL_assert(bl <= (int)sizeof(ctx->buf));
+	if (i != 0)
+		{
+		if (i+inl < bl)
+			{
+			memcpy(&(ctx->buf[i]),in,inl);
+			ctx->buf_len+=inl;
+			*outl=0;
+			return 1;
+			}
+		else
+			{
+			j=bl-i;
+			memcpy(&(ctx->buf[i]),in,j);
+			if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0;
+			inl-=j;
+			in+=j;
+			out+=bl;
+			*outl=bl;
+			}
+		}
+	else
+		*outl = 0;
+	i=inl&(bl-1);
+	inl-=i;
+	if (inl > 0)
+		{
+		if(!ctx->cipher->do_cipher(ctx,out,in,inl)) return 0;
+		*outl+=inl;
+		}
+
+	if (i != 0)
+		memcpy(ctx->buf,&(in[inl]),i);
+	ctx->buf_len=i;
+	return 1;
+	}
+
+int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+	{
+	int ret;
+	ret = EVP_EncryptFinal_ex(ctx, out, outl);
+	return ret;
+	}
+
+int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+	{
+	int n,ret;
+	unsigned int i, b, bl;
+
+	b=ctx->cipher->block_size;
+	OPENSSL_assert(b <= sizeof ctx->buf);
+	if (b == 1)
+		{
+		*outl=0;
+		return 1;
+		}
+	bl=ctx->buf_len;
+	if (ctx->flags & EVP_CIPH_NO_PADDING)
+		{
+		if(bl)
+			{
+			EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+			return 0;
+			}
+		*outl = 0;
+		return 1;
+		}
+
+	n=b-bl;
+	for (i=bl; i<b; i++)
+		ctx->buf[i]=n;
+	ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b);
+
+
+	if(ret)
+		*outl=b;
+
+	return ret;
+	}
+
+int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+	     const unsigned char *in, int inl)
+	{
+	int fix_len;
+	unsigned int b;
+
+	if (inl <= 0)
+		{
+		*outl = 0;
+		return inl == 0;
+		}
+
+	if (ctx->flags & EVP_CIPH_NO_PADDING)
+		return EVP_EncryptUpdate(ctx, out, outl, in, inl);
+
+	b=ctx->cipher->block_size;
+	OPENSSL_assert(b <= sizeof ctx->final);
+
+	if(ctx->final_used)
+		{
+		memcpy(out,ctx->final,b);
+		out+=b;
+		fix_len = 1;
+		}
+	else
+		fix_len = 0;
+
+
+	if(!EVP_EncryptUpdate(ctx,out,outl,in,inl))
+		return 0;
+
+	/* if we have 'decrypted' a multiple of block size, make sure
+	 * we have a copy of this last block */
+	if (b > 1 && !ctx->buf_len)
+		{
+		*outl-=b;
+		ctx->final_used=1;
+		memcpy(ctx->final,&out[*outl],b);
+		}
+	else
+		ctx->final_used = 0;
+
+	if (fix_len)
+		*outl += b;
+		
+	return 1;
+	}
+
+int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+	{
+	int ret;
+	ret = EVP_DecryptFinal_ex(ctx, out, outl);
+	return ret;
+	}
+
+int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+	{
+	int i,n;
+	unsigned int b;
+
+	*outl=0;
+	b=ctx->cipher->block_size;
+	if (ctx->flags & EVP_CIPH_NO_PADDING)
+		{
+		if(ctx->buf_len)
+			{
+			EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+			return 0;
+			}
+		*outl = 0;
+		return 1;
+		}
+	if (b > 1)
+		{
+		if (ctx->buf_len || !ctx->final_used)
+			{
+			EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
+			return(0);
+			}
+		OPENSSL_assert(b <= sizeof ctx->final);
+		n=ctx->final[b-1];
+		if (n == 0 || n > (int)b)
+			{
+			EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
+			return(0);
+			}
+		for (i=0; i<n; i++)
+			{
+			if (ctx->final[--b] != n)
+				{
+				EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
+				return(0);
+				}
+			}
+		n=ctx->cipher->block_size-n;
+		for (i=0; i<n; i++)
+			out[i]=ctx->final[i];
+		*outl=n;
+		}
+	else
+		*outl=0;
+	return(1);
+	}
+
+void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
+	{
+	if (ctx)
+		{
+		EVP_CIPHER_CTX_cleanup(ctx);
+		OPENSSL_free(ctx);
+		}
+	}
+
+int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
+	{
+	if (c->cipher != NULL)
+		{
+		if(c->cipher->cleanup && !c->cipher->cleanup(c))
+			return 0;
+		/* Cleanse cipher context data */
+		if (c->cipher_data)
+			OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
+		}
+	if (c->cipher_data)
+		OPENSSL_free(c->cipher_data);
+#ifndef OPENSSL_NO_ENGINE
+	if (c->engine)
+		/* The EVP_CIPHER we used belongs to an ENGINE, release the
+		 * functional reference we held for this reason. */
+		ENGINE_finish(c->engine);
+#endif
+	memset(c,0,sizeof(EVP_CIPHER_CTX));
+	return 1;
+	}
+
+int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
+	{
+	if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) 
+		return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
+	if(c->key_len == keylen) return 1;
+	if((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH))
+		{
+		c->key_len = keylen;
+		return 1;
+		}
+	EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH,EVP_R_INVALID_KEY_LENGTH);
+	return 0;
+	}
+
+int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
+	{
+	if (pad) ctx->flags &= ~EVP_CIPH_NO_PADDING;
+	else ctx->flags |= EVP_CIPH_NO_PADDING;
+	return 1;
+	}
+
+int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+	int ret;
+	if(!ctx->cipher) {
+		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
+		return 0;
+	}
+
+	if(!ctx->cipher->ctrl) {
+		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
+		return 0;
+	}
+
+	ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
+	if(ret == -1) {
+		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
+		return 0;
+	}
+	return ret;
+}
+
+int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
+	{
+	if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
+		return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key);
+	if (RAND_bytes(key, ctx->key_len) <= 0)
+		return 0;
+	return 1;
+	}
+
+int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
+	{
+	if ((in == NULL) || (in->cipher == NULL))
+		{
+		EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED);
+		return 0;
+		}
+#ifndef OPENSSL_NO_ENGINE
+	/* Make sure it's safe to copy a cipher context using an ENGINE */
+	if (in->engine && !ENGINE_init(in->engine))
+		{
+		EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_ENGINE_LIB);
+		return 0;
+		}
+#endif
+
+	EVP_CIPHER_CTX_cleanup(out);
+	memcpy(out,in,sizeof *out);
+
+	if (in->cipher_data && in->cipher->ctx_size)
+		{
+		out->cipher_data=OPENSSL_malloc(in->cipher->ctx_size);
+		if (!out->cipher_data)
+			{
+			EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		memcpy(out->cipher_data,in->cipher_data,in->cipher->ctx_size);
+		}
+
+	if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY)
+		return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out);
+	return 1;
+	}
+
diff --git a/openssl/crypto/evp/evp_err.c b/openssl/crypto/evp/evp_err.c
new file mode 100644
index 0000000..d8bfec0
--- /dev/null
+++ b/openssl/crypto/evp/evp_err.c
@@ -0,0 +1,218 @@
+/* crypto/evp/evp_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_EVP,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_EVP,0,reason)
+
+static ERR_STRING_DATA EVP_str_functs[]=
+	{
+{ERR_FUNC(EVP_F_AES_INIT_KEY),	"AES_INIT_KEY"},
+{ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY),	"CAMELLIA_INIT_KEY"},
+{ERR_FUNC(EVP_F_D2I_PKEY),	"D2I_PKEY"},
+{ERR_FUNC(EVP_F_DO_SIGVER_INIT),	"DO_SIGVER_INIT"},
+{ERR_FUNC(EVP_F_DSAPKEY2PKCS8),	"DSAPKEY2PKCS8"},
+{ERR_FUNC(EVP_F_DSA_PKEY2PKCS8),	"DSA_PKEY2PKCS8"},
+{ERR_FUNC(EVP_F_ECDSA_PKEY2PKCS8),	"ECDSA_PKEY2PKCS8"},
+{ERR_FUNC(EVP_F_ECKEY_PKEY2PKCS8),	"ECKEY_PKEY2PKCS8"},
+{ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX),	"EVP_CipherInit_ex"},
+{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_COPY),	"EVP_CIPHER_CTX_copy"},
+{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_CTRL),	"EVP_CIPHER_CTX_ctrl"},
+{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH),	"EVP_CIPHER_CTX_set_key_length"},
+{ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX),	"EVP_DecryptFinal_ex"},
+{ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX),	"EVP_DigestInit_ex"},
+{ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX),	"EVP_EncryptFinal_ex"},
+{ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX),	"EVP_MD_CTX_copy_ex"},
+{ERR_FUNC(EVP_F_EVP_MD_SIZE),	"EVP_MD_SIZE"},
+{ERR_FUNC(EVP_F_EVP_OPENINIT),	"EVP_OpenInit"},
+{ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD),	"EVP_PBE_alg_add"},
+{ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD_TYPE),	"EVP_PBE_alg_add_type"},
+{ERR_FUNC(EVP_F_EVP_PBE_CIPHERINIT),	"EVP_PBE_CipherInit"},
+{ERR_FUNC(EVP_F_EVP_PKCS82PKEY),	"EVP_PKCS82PKEY"},
+{ERR_FUNC(EVP_F_EVP_PKCS82PKEY_BROKEN),	"EVP_PKCS82PKEY_BROKEN"},
+{ERR_FUNC(EVP_F_EVP_PKEY2PKCS8_BROKEN),	"EVP_PKEY2PKCS8_broken"},
+{ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS),	"EVP_PKEY_copy_parameters"},
+{ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL),	"EVP_PKEY_CTX_ctrl"},
+{ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL_STR),	"EVP_PKEY_CTX_ctrl_str"},
+{ERR_FUNC(EVP_F_EVP_PKEY_CTX_DUP),	"EVP_PKEY_CTX_dup"},
+{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT),	"EVP_PKEY_decrypt"},
+{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_INIT),	"EVP_PKEY_decrypt_init"},
+{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_OLD),	"EVP_PKEY_decrypt_old"},
+{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE),	"EVP_PKEY_derive"},
+{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_INIT),	"EVP_PKEY_derive_init"},
+{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_SET_PEER),	"EVP_PKEY_derive_set_peer"},
+{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT),	"EVP_PKEY_encrypt"},
+{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_INIT),	"EVP_PKEY_encrypt_init"},
+{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_OLD),	"EVP_PKEY_encrypt_old"},
+{ERR_FUNC(EVP_F_EVP_PKEY_GET1_DH),	"EVP_PKEY_get1_DH"},
+{ERR_FUNC(EVP_F_EVP_PKEY_GET1_DSA),	"EVP_PKEY_get1_DSA"},
+{ERR_FUNC(EVP_F_EVP_PKEY_GET1_ECDSA),	"EVP_PKEY_GET1_ECDSA"},
+{ERR_FUNC(EVP_F_EVP_PKEY_GET1_EC_KEY),	"EVP_PKEY_get1_EC_KEY"},
+{ERR_FUNC(EVP_F_EVP_PKEY_GET1_RSA),	"EVP_PKEY_get1_RSA"},
+{ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN),	"EVP_PKEY_keygen"},
+{ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN_INIT),	"EVP_PKEY_keygen_init"},
+{ERR_FUNC(EVP_F_EVP_PKEY_NEW),	"EVP_PKEY_new"},
+{ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN),	"EVP_PKEY_paramgen"},
+{ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN_INIT),	"EVP_PKEY_paramgen_init"},
+{ERR_FUNC(EVP_F_EVP_PKEY_SIGN),	"EVP_PKEY_sign"},
+{ERR_FUNC(EVP_F_EVP_PKEY_SIGN_INIT),	"EVP_PKEY_sign_init"},
+{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY),	"EVP_PKEY_verify"},
+{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_INIT),	"EVP_PKEY_verify_init"},
+{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER),	"EVP_PKEY_verify_recover"},
+{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT),	"EVP_PKEY_verify_recover_init"},
+{ERR_FUNC(EVP_F_EVP_RIJNDAEL),	"EVP_RIJNDAEL"},
+{ERR_FUNC(EVP_F_EVP_SIGNFINAL),	"EVP_SignFinal"},
+{ERR_FUNC(EVP_F_EVP_VERIFYFINAL),	"EVP_VerifyFinal"},
+{ERR_FUNC(EVP_F_INT_CTX_NEW),	"INT_CTX_NEW"},
+{ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN),	"PKCS5_PBE_keyivgen"},
+{ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN),	"PKCS5_v2_PBE_keyivgen"},
+{ERR_FUNC(EVP_F_PKCS8_SET_BROKEN),	"PKCS8_set_broken"},
+{ERR_FUNC(EVP_F_PKEY_SET_TYPE),	"PKEY_SET_TYPE"},
+{ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH),	"RC2_MAGIC_TO_METH"},
+{ERR_FUNC(EVP_F_RC5_CTRL),	"RC5_CTRL"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA EVP_str_reasons[]=
+	{
+{ERR_REASON(EVP_R_AES_KEY_SETUP_FAILED)  ,"aes key setup failed"},
+{ERR_REASON(EVP_R_ASN1_LIB)              ,"asn1 lib"},
+{ERR_REASON(EVP_R_BAD_BLOCK_LENGTH)      ,"bad block length"},
+{ERR_REASON(EVP_R_BAD_DECRYPT)           ,"bad decrypt"},
+{ERR_REASON(EVP_R_BAD_KEY_LENGTH)        ,"bad key length"},
+{ERR_REASON(EVP_R_BN_DECODE_ERROR)       ,"bn decode error"},
+{ERR_REASON(EVP_R_BN_PUBKEY_ERROR)       ,"bn pubkey error"},
+{ERR_REASON(EVP_R_BUFFER_TOO_SMALL)      ,"buffer too small"},
+{ERR_REASON(EVP_R_CAMELLIA_KEY_SETUP_FAILED),"camellia key setup failed"},
+{ERR_REASON(EVP_R_CIPHER_PARAMETER_ERROR),"cipher parameter error"},
+{ERR_REASON(EVP_R_COMMAND_NOT_SUPPORTED) ,"command not supported"},
+{ERR_REASON(EVP_R_CTRL_NOT_IMPLEMENTED)  ,"ctrl not implemented"},
+{ERR_REASON(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED),"ctrl operation not implemented"},
+{ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH),"data not multiple of block length"},
+{ERR_REASON(EVP_R_DECODE_ERROR)          ,"decode error"},
+{ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES)   ,"different key types"},
+{ERR_REASON(EVP_R_DIFFERENT_PARAMETERS)  ,"different parameters"},
+{ERR_REASON(EVP_R_ENCODE_ERROR)          ,"encode error"},
+{ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR),"evp pbe cipherinit error"},
+{ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY)  ,"expecting an rsa key"},
+{ERR_REASON(EVP_R_EXPECTING_A_DH_KEY)    ,"expecting a dh key"},
+{ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY)   ,"expecting a dsa key"},
+{ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) ,"expecting a ecdsa key"},
+{ERR_REASON(EVP_R_EXPECTING_A_EC_KEY)    ,"expecting a ec key"},
+{ERR_REASON(EVP_R_INITIALIZATION_ERROR)  ,"initialization error"},
+{ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) ,"input not initialized"},
+{ERR_REASON(EVP_R_INVALID_DIGEST)        ,"invalid digest"},
+{ERR_REASON(EVP_R_INVALID_KEY_LENGTH)    ,"invalid key length"},
+{ERR_REASON(EVP_R_INVALID_OPERATION)     ,"invalid operation"},
+{ERR_REASON(EVP_R_IV_TOO_LARGE)          ,"iv too large"},
+{ERR_REASON(EVP_R_KEYGEN_FAILURE)        ,"keygen failure"},
+{ERR_REASON(EVP_R_MESSAGE_DIGEST_IS_NULL),"message digest is null"},
+{ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED)  ,"method not supported"},
+{ERR_REASON(EVP_R_MISSING_PARAMETERS)    ,"missing parameters"},
+{ERR_REASON(EVP_R_NO_CIPHER_SET)         ,"no cipher set"},
+{ERR_REASON(EVP_R_NO_DEFAULT_DIGEST)     ,"no default digest"},
+{ERR_REASON(EVP_R_NO_DIGEST_SET)         ,"no digest set"},
+{ERR_REASON(EVP_R_NO_DSA_PARAMETERS)     ,"no dsa parameters"},
+{ERR_REASON(EVP_R_NO_KEY_SET)            ,"no key set"},
+{ERR_REASON(EVP_R_NO_OPERATION_SET)      ,"no operation set"},
+{ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED),"no sign function configured"},
+{ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED),"no verify function configured"},
+{ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supported for this keytype"},
+{ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED),"operaton not initialized"},
+{ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE),"pkcs8 unknown broken type"},
+{ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR),"private key decode error"},
+{ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR),"private key encode error"},
+{ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA)    ,"public key not rsa"},
+{ERR_REASON(EVP_R_UNKNOWN_CIPHER)        ,"unknown cipher"},
+{ERR_REASON(EVP_R_UNKNOWN_DIGEST)        ,"unknown digest"},
+{ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"},
+{ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"},
+{ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM) ,"unsupported algorithm"},
+{ERR_REASON(EVP_R_UNSUPPORTED_CIPHER)    ,"unsupported cipher"},
+{ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH) ,"unsupported keylength"},
+{ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION),"unsupported key derivation function"},
+{ERR_REASON(EVP_R_UNSUPPORTED_KEY_SIZE)  ,"unsupported key size"},
+{ERR_REASON(EVP_R_UNSUPPORTED_PRF)       ,"unsupported prf"},
+{ERR_REASON(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM),"unsupported private key algorithm"},
+{ERR_REASON(EVP_R_UNSUPPORTED_SALT_TYPE) ,"unsupported salt type"},
+{ERR_REASON(EVP_R_WRONG_FINAL_BLOCK_LENGTH),"wrong final block length"},
+{ERR_REASON(EVP_R_WRONG_PUBLIC_KEY_TYPE) ,"wrong public key type"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_EVP_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(EVP_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,EVP_str_functs);
+		ERR_load_strings(0,EVP_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/evp/evp_key.c b/openssl/crypto/evp/evp_key.c
new file mode 100644
index 0000000..839d6a3
--- /dev/null
+++ b/openssl/crypto/evp/evp_key.c
@@ -0,0 +1,180 @@
+/* crypto/evp/evp_key.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/ui.h>
+
+/* should be init to zeros. */
+static char prompt_string[80];
+
+void EVP_set_pw_prompt(const char *prompt)
+	{
+	if (prompt == NULL)
+		prompt_string[0]='\0';
+	else
+		{
+		strncpy(prompt_string,prompt,79);
+		prompt_string[79]='\0';
+		}
+	}
+
+char *EVP_get_pw_prompt(void)
+	{
+	if (prompt_string[0] == '\0')
+		return(NULL);
+	else
+		return(prompt_string);
+	}
+
+/* For historical reasons, the standard function for reading passwords is
+ * in the DES library -- if someone ever wants to disable DES,
+ * this function will fail */
+int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify)
+	{
+	return EVP_read_pw_string_min(buf, 0, len, prompt, verify);
+	}
+
+int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, int verify)
+	{
+	int ret;
+	char buff[BUFSIZ];
+	UI *ui;
+
+	if ((prompt == NULL) && (prompt_string[0] != '\0'))
+		prompt=prompt_string;
+	ui = UI_new();
+	UI_add_input_string(ui,prompt,0,buf,min,(len>=BUFSIZ)?BUFSIZ-1:len);
+	if (verify)
+		UI_add_verify_string(ui,prompt,0,
+			buff,min,(len>=BUFSIZ)?BUFSIZ-1:len,buf);
+	ret = UI_process(ui);
+	UI_free(ui);
+	OPENSSL_cleanse(buff,BUFSIZ);
+	return ret;
+	}
+
+int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, 
+	     const unsigned char *salt, const unsigned char *data, int datal,
+	     int count, unsigned char *key, unsigned char *iv)
+	{
+	EVP_MD_CTX c;
+	unsigned char md_buf[EVP_MAX_MD_SIZE];
+	int niv,nkey,addmd=0;
+	unsigned int mds=0,i;
+
+	nkey=type->key_len;
+	niv=type->iv_len;
+	OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH);
+	OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH);
+
+	if (data == NULL) return(nkey);
+
+	EVP_MD_CTX_init(&c);
+	for (;;)
+		{
+		if (!EVP_DigestInit_ex(&c,md, NULL))
+			return 0;
+		if (addmd++)
+			EVP_DigestUpdate(&c,&(md_buf[0]),mds);
+		EVP_DigestUpdate(&c,data,datal);
+		if (salt != NULL)
+			EVP_DigestUpdate(&c,salt,PKCS5_SALT_LEN);
+		EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds);
+
+		for (i=1; i<(unsigned int)count; i++)
+			{
+			EVP_DigestInit_ex(&c,md, NULL);
+			EVP_DigestUpdate(&c,&(md_buf[0]),mds);
+			EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds);
+			}
+		i=0;
+		if (nkey)
+			{
+			for (;;)
+				{
+				if (nkey == 0) break;
+				if (i == mds) break;
+				if (key != NULL)
+					*(key++)=md_buf[i];
+				nkey--;
+				i++;
+				}
+			}
+		if (niv && (i != mds))
+			{
+			for (;;)
+				{
+				if (niv == 0) break;
+				if (i == mds) break;
+				if (iv != NULL)
+					*(iv++)=md_buf[i];
+				niv--;
+				i++;
+				}
+			}
+		if ((nkey == 0) && (niv == 0)) break;
+		}
+	EVP_MD_CTX_cleanup(&c);
+	OPENSSL_cleanse(&(md_buf[0]),EVP_MAX_MD_SIZE);
+	return(type->key_len);
+	}
+
diff --git a/openssl/crypto/evp/evp_lib.c b/openssl/crypto/evp/evp_lib.c
new file mode 100644
index 0000000..40951a0
--- /dev/null
+++ b/openssl/crypto/evp/evp_lib.c
@@ -0,0 +1,312 @@
+/* crypto/evp/evp_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+
+int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+	{
+	int ret;
+
+	if (c->cipher->set_asn1_parameters != NULL)
+		ret=c->cipher->set_asn1_parameters(c,type);
+	else
+		ret=-1;
+	return(ret);
+	}
+
+int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+	{
+	int ret;
+
+	if (c->cipher->get_asn1_parameters != NULL)
+		ret=c->cipher->get_asn1_parameters(c,type);
+	else
+		ret=-1;
+	return(ret);
+	}
+
+int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+	{
+	int i=0;
+	unsigned int l;
+
+	if (type != NULL) 
+		{
+		l=EVP_CIPHER_CTX_iv_length(c);
+		OPENSSL_assert(l <= sizeof(c->iv));
+		i=ASN1_TYPE_get_octetstring(type,c->oiv,l);
+		if (i != (int)l)
+			return(-1);
+		else if (i > 0)
+			memcpy(c->iv,c->oiv,l);
+		}
+	return(i);
+	}
+
+int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+	{
+	int i=0;
+	unsigned int j;
+
+	if (type != NULL)
+		{
+		j=EVP_CIPHER_CTX_iv_length(c);
+		OPENSSL_assert(j <= sizeof(c->iv));
+		i=ASN1_TYPE_set_octetstring(type,c->oiv,j);
+		}
+	return(i);
+	}
+
+/* Convert the various cipher NIDs and dummies to a proper OID NID */
+int EVP_CIPHER_type(const EVP_CIPHER *ctx)
+{
+	int nid;
+	ASN1_OBJECT *otmp;
+	nid = EVP_CIPHER_nid(ctx);
+
+	switch(nid) {
+
+		case NID_rc2_cbc:
+		case NID_rc2_64_cbc:
+		case NID_rc2_40_cbc:
+
+		return NID_rc2_cbc;
+
+		case NID_rc4:
+		case NID_rc4_40:
+
+		return NID_rc4;
+
+		case NID_aes_128_cfb128:
+		case NID_aes_128_cfb8:
+		case NID_aes_128_cfb1:
+
+		return NID_aes_128_cfb128;
+
+		case NID_aes_192_cfb128:
+		case NID_aes_192_cfb8:
+		case NID_aes_192_cfb1:
+
+		return NID_aes_192_cfb128;
+
+		case NID_aes_256_cfb128:
+		case NID_aes_256_cfb8:
+		case NID_aes_256_cfb1:
+
+		return NID_aes_256_cfb128;
+
+		case NID_des_cfb64:
+		case NID_des_cfb8:
+		case NID_des_cfb1:
+
+		return NID_des_cfb64;
+
+		case NID_des_ede3_cfb64:
+		case NID_des_ede3_cfb8:
+		case NID_des_ede3_cfb1:
+
+		return NID_des_cfb64;
+
+		default:
+		/* Check it has an OID and it is valid */
+		otmp = OBJ_nid2obj(nid);
+		if(!otmp || !otmp->data) nid = NID_undef;
+		ASN1_OBJECT_free(otmp);
+		return nid;
+	}
+}
+
+int EVP_CIPHER_block_size(const EVP_CIPHER *e)
+	{
+	return e->block_size;
+	}
+
+int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
+	{
+	return ctx->cipher->block_size;
+	}
+
+int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl)
+	{
+	return ctx->cipher->do_cipher(ctx,out,in,inl);
+	}
+
+const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx)
+	{
+	return ctx->cipher;
+	}
+
+unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher)
+	{
+	return cipher->flags;
+	}
+
+unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
+	{
+	return ctx->cipher->flags;
+	}
+
+void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
+	{
+	return ctx->app_data;
+	}
+
+void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data)
+	{
+	ctx->app_data = data;
+	}
+
+int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
+	{
+	return cipher->iv_len;
+	}
+
+int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
+	{
+	return ctx->cipher->iv_len;
+	}
+
+int EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
+	{
+	return cipher->key_len;
+	}
+
+int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
+	{
+	return ctx->key_len;
+	}
+
+int EVP_CIPHER_nid(const EVP_CIPHER *cipher)
+	{
+	return cipher->nid;
+	}
+
+int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
+	{
+	return ctx->cipher->nid;
+	}
+
+int EVP_MD_block_size(const EVP_MD *md) 
+	{
+	return md->block_size;
+	}
+
+int EVP_MD_type(const EVP_MD *md)
+	{
+	return md->type;
+	}
+
+int EVP_MD_pkey_type(const EVP_MD *md)
+	{
+	return md->pkey_type;
+	}
+
+int EVP_MD_size(const EVP_MD *md)
+	{
+	if (!md)
+		{
+		EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL);
+		return -1;
+		}
+	return md->md_size;
+	}
+
+unsigned long EVP_MD_flags(const EVP_MD *md)
+	{
+	return md->flags;
+	}
+
+const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx)
+	{
+	if (!ctx)
+		return NULL;
+	return ctx->digest;
+	}
+
+void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags)
+	{
+	ctx->flags |= flags;
+	}
+
+void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags)
+	{
+	ctx->flags &= ~flags;
+	}
+
+int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags)
+	{
+	return (ctx->flags & flags);
+	}
+
+void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags)
+	{
+	ctx->flags |= flags;
+	}
+
+void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags)
+	{
+	ctx->flags &= ~flags;
+	}
+
+int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags)
+	{
+	return (ctx->flags & flags);
+	}
diff --git a/openssl/crypto/evp/evp_locl.h b/openssl/crypto/evp/evp_locl.h
new file mode 100644
index 0000000..292d74c
--- /dev/null
+++ b/openssl/crypto/evp/evp_locl.h
@@ -0,0 +1,345 @@
+/* evp_locl.h */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Macros to code block cipher wrappers */
+
+/* Wrapper functions for each cipher mode */
+
+#define BLOCK_CIPHER_ecb_loop() \
+	size_t i, bl; \
+	bl = ctx->cipher->block_size;\
+	if(inl < bl) return 1;\
+	inl -= bl; \
+	for(i=0; i <= inl; i+=bl) 
+
+#define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
+static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+	BLOCK_CIPHER_ecb_loop() \
+		cprefix##_ecb_encrypt(in + i, out + i, &((kstruct *)ctx->cipher_data)->ksched, ctx->encrypt);\
+	return 1;\
+}
+
+#define EVP_MAXCHUNK ((size_t)1<<(sizeof(long)*8-2))
+
+#define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \
+static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+	while(inl>=EVP_MAXCHUNK)\
+	    {\
+	    cprefix##_ofb##cbits##_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
+	    inl-=EVP_MAXCHUNK;\
+	    in +=EVP_MAXCHUNK;\
+	    out+=EVP_MAXCHUNK;\
+	    }\
+	if (inl)\
+	    cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
+	return 1;\
+}
+
+#define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
+static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+	while(inl>=EVP_MAXCHUNK) \
+	    {\
+	    cprefix##_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
+	    inl-=EVP_MAXCHUNK;\
+	    in +=EVP_MAXCHUNK;\
+	    out+=EVP_MAXCHUNK;\
+	    }\
+	if (inl)\
+	    cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
+	return 1;\
+}
+
+#define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
+static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+	size_t chunk=EVP_MAXCHUNK;\
+	if (cbits==1)  chunk>>=3;\
+	if (inl<chunk) chunk=inl;\
+	while(inl && inl>=chunk)\
+	    {\
+            cprefix##_cfb##cbits##_encrypt(in, out, (long)((cbits==1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\
+	    inl-=chunk;\
+	    in +=chunk;\
+	    out+=chunk;\
+	    if(inl<chunk) chunk=inl;\
+	    }\
+	return 1;\
+}
+
+#define BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
+	BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
+	BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
+	BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
+	BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched)
+
+#define BLOCK_CIPHER_def1(cname, nmode, mode, MODE, kstruct, nid, block_size, \
+			  key_len, iv_len, flags, init_key, cleanup, \
+			  set_asn1, get_asn1, ctrl) \
+static const EVP_CIPHER cname##_##mode = { \
+	nid##_##nmode, block_size, key_len, iv_len, \
+	flags | EVP_CIPH_##MODE##_MODE, \
+	init_key, \
+	cname##_##mode##_cipher, \
+	cleanup, \
+	sizeof(kstruct), \
+	set_asn1, get_asn1,\
+	ctrl, \
+	NULL \
+}; \
+const EVP_CIPHER *EVP_##cname##_##mode(void) { return &cname##_##mode; }
+
+#define BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, \
+			     iv_len, flags, init_key, cleanup, set_asn1, \
+			     get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, cbc, cbc, CBC, kstruct, nid, block_size, key_len, \
+		  iv_len, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, \
+			     iv_len, cbits, flags, init_key, cleanup, \
+			     set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, cfb##cbits, cfb##cbits, CFB, kstruct, nid, 1, \
+		  key_len, iv_len, flags, init_key, cleanup, set_asn1, \
+		  get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, \
+			     iv_len, cbits, flags, init_key, cleanup, \
+			     set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, ofb##cbits, ofb, OFB, kstruct, nid, 1, \
+		  key_len, iv_len, flags, init_key, cleanup, set_asn1, \
+		  get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, \
+			     flags, init_key, cleanup, set_asn1, \
+			     get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, ecb, ecb, ECB, kstruct, nid, block_size, key_len, \
+		  0, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+#define BLOCK_CIPHER_defs(cname, kstruct, \
+			  nid, block_size, key_len, iv_len, cbits, flags, \
+			  init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, iv_len, flags, \
+		     init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, iv_len, cbits, \
+		     flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, iv_len, cbits, \
+		     flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, flags, \
+		     init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+
+/*
+#define BLOCK_CIPHER_defs(cname, kstruct, \
+				nid, block_size, key_len, iv_len, flags,\
+				 init_key, cleanup, set_asn1, get_asn1, ctrl)\
+static const EVP_CIPHER cname##_cbc = {\
+	nid##_cbc, block_size, key_len, iv_len, \
+	flags | EVP_CIPH_CBC_MODE,\
+	init_key,\
+	cname##_cbc_cipher,\
+	cleanup,\
+	sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+		sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+	set_asn1, get_asn1,\
+	ctrl, \
+	NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_cbc(void) { return &cname##_cbc; }\
+static const EVP_CIPHER cname##_cfb = {\
+	nid##_cfb64, 1, key_len, iv_len, \
+	flags | EVP_CIPH_CFB_MODE,\
+	init_key,\
+	cname##_cfb_cipher,\
+	cleanup,\
+	sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+		sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+	set_asn1, get_asn1,\
+	ctrl,\
+	NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_cfb(void) { return &cname##_cfb; }\
+static const EVP_CIPHER cname##_ofb = {\
+	nid##_ofb64, 1, key_len, iv_len, \
+	flags | EVP_CIPH_OFB_MODE,\
+	init_key,\
+	cname##_ofb_cipher,\
+	cleanup,\
+	sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+		sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+	set_asn1, get_asn1,\
+	ctrl,\
+	NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_ofb(void) { return &cname##_ofb; }\
+static const EVP_CIPHER cname##_ecb = {\
+	nid##_ecb, block_size, key_len, iv_len, \
+	flags | EVP_CIPH_ECB_MODE,\
+	init_key,\
+	cname##_ecb_cipher,\
+	cleanup,\
+	sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+		sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+	set_asn1, get_asn1,\
+	ctrl,\
+	NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; }
+*/
+
+#define IMPLEMENT_BLOCK_CIPHER(cname, ksched, cprefix, kstruct, nid, \
+			       block_size, key_len, iv_len, cbits, \
+			       flags, init_key, \
+			       cleanup, set_asn1, get_asn1, ctrl) \
+	BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
+	BLOCK_CIPHER_defs(cname, kstruct, nid, block_size, key_len, iv_len, \
+			  cbits, flags, init_key, cleanup, set_asn1, \
+			  get_asn1, ctrl)
+
+#define EVP_C_DATA(kstruct, ctx)	((kstruct *)(ctx)->cipher_data)
+
+#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len) \
+	BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \
+	BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \
+			     NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \
+			     0, cipher##_init_key, NULL, \
+			     EVP_CIPHER_set_asn1_iv, \
+			     EVP_CIPHER_get_asn1_iv, \
+			     NULL)
+
+struct evp_pkey_ctx_st
+	{
+	/* Method associated with this operation */
+	const EVP_PKEY_METHOD *pmeth;
+	/* Engine that implements this method or NULL if builtin */
+	ENGINE *engine;
+	/* Key: may be NULL */
+	EVP_PKEY *pkey;
+	/* Peer key for key agreement, may be NULL */
+	EVP_PKEY *peerkey;
+	/* Actual operation */
+	int operation;
+	/* Algorithm specific data */
+	void *data;
+	/* Application specific data */
+	void *app_data;
+	/* Keygen callback */
+	EVP_PKEY_gen_cb *pkey_gencb;
+	/* implementation specific keygen data */
+	int *keygen_info;
+	int keygen_info_count;
+	} /* EVP_PKEY_CTX */;
+
+#define EVP_PKEY_FLAG_DYNAMIC	1
+
+struct evp_pkey_method_st
+	{
+	int pkey_id;
+	int flags;
+
+	int (*init)(EVP_PKEY_CTX *ctx);
+	int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src);
+	void (*cleanup)(EVP_PKEY_CTX *ctx);
+
+	int (*paramgen_init)(EVP_PKEY_CTX *ctx);
+	int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
+
+	int (*keygen_init)(EVP_PKEY_CTX *ctx);
+	int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
+
+	int (*sign_init)(EVP_PKEY_CTX *ctx);
+	int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+				const unsigned char *tbs, size_t tbslen);
+
+	int (*verify_init)(EVP_PKEY_CTX *ctx);
+	int (*verify)(EVP_PKEY_CTX *ctx,
+				const unsigned char *sig, size_t siglen,
+				const unsigned char *tbs, size_t tbslen);
+
+	int (*verify_recover_init)(EVP_PKEY_CTX *ctx);
+	int (*verify_recover)(EVP_PKEY_CTX *ctx,
+				unsigned char *rout, size_t *routlen,
+				const unsigned char *sig, size_t siglen);
+
+	int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
+	int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					EVP_MD_CTX *mctx);
+
+	int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
+	int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,int siglen,
+					EVP_MD_CTX *mctx);
+
+	int (*encrypt_init)(EVP_PKEY_CTX *ctx);
+	int (*encrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen);
+
+	int (*decrypt_init)(EVP_PKEY_CTX *ctx);
+	int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen);
+
+	int (*derive_init)(EVP_PKEY_CTX *ctx);
+	int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
+
+	int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
+	int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value);
+
+
+	} /* EVP_PKEY_METHOD */;
+
+void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx);
diff --git a/openssl/crypto/evp/evp_pbe.c b/openssl/crypto/evp/evp_pbe.c
new file mode 100644
index 0000000..c9d932d
--- /dev/null
+++ b/openssl/crypto/evp/evp_pbe.c
@@ -0,0 +1,311 @@
+/* evp_pbe.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/pkcs12.h>
+#include <openssl/x509.h>
+
+/* Password based encryption (PBE) functions */
+
+DECLARE_STACK_OF(EVP_PBE_CTL)
+static STACK_OF(EVP_PBE_CTL) *pbe_algs;
+
+/* Setup a cipher context from a PBE algorithm */
+
+typedef struct
+	{
+	int pbe_type;
+	int pbe_nid;
+	int cipher_nid;
+	int md_nid;
+	EVP_PBE_KEYGEN *keygen;
+	} EVP_PBE_CTL;
+
+static const EVP_PBE_CTL builtin_pbe[] = 
+	{
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC,
+			NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC,
+			NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC,
+			NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen},
+
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4,
+			NID_rc4, NID_sha1, PKCS12_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4,
+			NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
+		 	NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC, 
+			NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC,
+			NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC,
+			NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+
+#ifndef OPENSSL_NO_HMAC
+	{EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen},
+#endif
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC,
+			NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC,
+			NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC,
+			NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen},
+
+
+	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0},
+	{EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0},
+	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0},
+	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0},
+	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0},
+	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0},
+	{EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0},
+	};
+
+#ifdef TEST
+int main(int argc, char **argv)
+	{
+	int i, nid_md, nid_cipher;
+	EVP_PBE_CTL *tpbe, *tpbe2;
+	/*OpenSSL_add_all_algorithms();*/
+
+	for (i = 0; i < sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL); i++)
+		{
+		tpbe = builtin_pbe + i;
+		fprintf(stderr, "%d %d %s ", tpbe->pbe_type, tpbe->pbe_nid,
+						OBJ_nid2sn(tpbe->pbe_nid));
+		if (EVP_PBE_find(tpbe->pbe_type, tpbe->pbe_nid,
+					&nid_cipher ,&nid_md,0))
+			fprintf(stderr, "Found %s %s\n",
+					OBJ_nid2sn(nid_cipher),
+					OBJ_nid2sn(nid_md));
+		else
+			fprintf(stderr, "Find ERROR!!\n");
+		}
+
+	return 0;
+	}
+#endif
+		
+
+
+int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
+		       ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
+	{
+	const EVP_CIPHER *cipher;
+	const EVP_MD *md;
+	int cipher_nid, md_nid;
+	EVP_PBE_KEYGEN *keygen;
+
+	if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj),
+					&cipher_nid, &md_nid, &keygen))
+		{
+		char obj_tmp[80];
+		EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_PBE_ALGORITHM);
+		if (!pbe_obj) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
+		else i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj);
+		ERR_add_error_data(2, "TYPE=", obj_tmp);
+		return 0;
+		}
+
+	if(!pass)
+		passlen = 0;
+	else if (passlen == -1)
+		passlen = strlen(pass);
+
+	if (cipher_nid == -1)
+		cipher = NULL;
+	else
+		{
+		cipher = EVP_get_cipherbynid(cipher_nid);
+		if (!cipher)
+			{
+			EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_CIPHER);
+			return 0;
+			}
+		}
+
+	if (md_nid == -1)
+		md = NULL;
+	else
+		{
+		md = EVP_get_digestbynid(md_nid);
+		if (!md)
+			{
+			EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_DIGEST);
+			return 0;
+			}
+		}
+
+	if (!keygen(ctx, pass, passlen, param, cipher, md, en_de))
+		{
+		EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_KEYGEN_FAILURE);
+		return 0;
+		}
+	return 1;	
+}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
+
+static int pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2)
+	{
+	int ret = pbe1->pbe_type - pbe2->pbe_type;
+	if (ret)
+		return ret;
+	else
+		return pbe1->pbe_nid - pbe2->pbe_nid;
+	}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
+
+static int pbe_cmp(const EVP_PBE_CTL * const *a, const EVP_PBE_CTL * const *b)
+	{
+	int ret = (*a)->pbe_type - (*b)->pbe_type;
+	if (ret)
+		return ret;
+	else
+		return (*a)->pbe_nid - (*b)->pbe_nid;
+	}
+
+/* Add a PBE algorithm */
+
+int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid,
+			 EVP_PBE_KEYGEN *keygen)
+	{
+	EVP_PBE_CTL *pbe_tmp;
+	if (!pbe_algs)
+		pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp);
+	if (!(pbe_tmp = (EVP_PBE_CTL*) OPENSSL_malloc (sizeof(EVP_PBE_CTL))))
+		{
+		EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	pbe_tmp->pbe_type = pbe_type;
+	pbe_tmp->pbe_nid = pbe_nid;
+	pbe_tmp->cipher_nid = cipher_nid;
+	pbe_tmp->md_nid = md_nid;
+	pbe_tmp->keygen = keygen;
+
+
+	sk_EVP_PBE_CTL_push (pbe_algs, pbe_tmp);
+	return 1;
+	}
+
+int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
+		    EVP_PBE_KEYGEN *keygen)
+	{
+	int cipher_nid, md_nid;
+	if (cipher)
+		cipher_nid = EVP_CIPHER_type(cipher);
+	else
+		cipher_nid = -1;
+	if (md)
+		md_nid = EVP_MD_type(md);
+	else
+		md_nid = -1;
+
+	return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid,
+					cipher_nid, md_nid, keygen);
+	}
+
+int EVP_PBE_find(int type, int pbe_nid,
+		 int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen)
+	{
+	EVP_PBE_CTL *pbetmp = NULL, pbelu;
+	int i;
+	if (pbe_nid == NID_undef)
+		return 0;
+
+	pbelu.pbe_type = type;
+	pbelu.pbe_nid = pbe_nid;
+
+	if (pbe_algs)
+		{
+		i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu);
+		if (i != -1)
+			pbetmp = sk_EVP_PBE_CTL_value (pbe_algs, i);
+		}
+	if (pbetmp == NULL)
+		{
+		pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe,
+				     sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL));
+		}
+	if (pbetmp == NULL)
+		return 0;
+	if (pcnid)
+		*pcnid = pbetmp->cipher_nid;
+	if (pmnid)
+		*pmnid = pbetmp->md_nid;
+	if (pkeygen)
+		*pkeygen = pbetmp->keygen;
+	return 1;
+	}
+
+static void free_evp_pbe_ctl(EVP_PBE_CTL *pbe)
+	 {
+	 OPENSSL_freeFunc(pbe);
+	 }
+
+void EVP_PBE_cleanup(void)
+	{
+	sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl);
+	pbe_algs = NULL;
+	}
diff --git a/openssl/crypto/evp/evp_pkey.c b/openssl/crypto/evp/evp_pkey.c
new file mode 100644
index 0000000..ceebf69
--- /dev/null
+++ b/openssl/crypto/evp/evp_pkey.c
@@ -0,0 +1,242 @@
+/* evp_pkey.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/rand.h>
+#include "asn1_locl.h"
+
+/* Extract a private key from a PKCS8 structure */
+
+EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
+{
+	EVP_PKEY *pkey = NULL;
+	ASN1_OBJECT *algoid;
+	char obj_tmp[80];
+
+	if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8))
+		return NULL;
+
+	if (!(pkey = EVP_PKEY_new())) {
+		EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid)))
+		{
+		EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
+		i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
+		ERR_add_error_data(2, "TYPE=", obj_tmp);
+		goto error;
+		}
+
+	if (pkey->ameth->priv_decode)
+		{
+		if (!pkey->ameth->priv_decode(pkey, p8))
+			{
+			EVPerr(EVP_F_EVP_PKCS82PKEY,
+					EVP_R_PRIVATE_KEY_DECODE_ERROR);
+			goto error;
+			}
+		}
+	else
+		{
+		EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED);
+		goto error;
+		}
+
+	return pkey;
+
+	error:
+	EVP_PKEY_free (pkey);
+	return NULL;
+}
+
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
+{
+	return EVP_PKEY2PKCS8_broken(pkey, PKCS8_OK);
+}
+
+/* Turn a private key into a PKCS8 structure */
+
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
+{
+	PKCS8_PRIV_KEY_INFO *p8;
+
+	if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {	
+		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	p8->broken = broken;
+
+	if (pkey->ameth)
+		{
+		if (pkey->ameth->priv_encode)
+			{
+			if (!pkey->ameth->priv_encode(p8, pkey))
+				{
+				EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
+					EVP_R_PRIVATE_KEY_ENCODE_ERROR);
+				goto error;
+				}
+			}
+		else
+			{
+			EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
+					EVP_R_METHOD_NOT_SUPPORTED);
+			goto error;
+			}
+		}
+	else
+		{
+		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
+				EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
+		goto error;
+		}
+	RAND_add(p8->pkey->value.octet_string->data,
+		 p8->pkey->value.octet_string->length, 0.0);
+	return p8;
+	error:
+	PKCS8_PRIV_KEY_INFO_free(p8);
+	return NULL;
+}
+
+PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
+{
+	switch (broken) {
+
+		case PKCS8_OK:
+		p8->broken = PKCS8_OK;
+		return p8;
+		break;
+
+		case PKCS8_NO_OCTET:
+		p8->broken = PKCS8_NO_OCTET;
+		p8->pkey->type = V_ASN1_SEQUENCE;
+		return p8;
+		break;
+
+		default:
+		EVPerr(EVP_F_PKCS8_SET_BROKEN,EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE);
+		return NULL;
+	}
+}
+
+/* EVP_PKEY attribute functions */
+
+int EVP_PKEY_get_attr_count(const EVP_PKEY *key)
+{
+	return X509at_get_attr_count(key->attributes);
+}
+
+int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid,
+			  int lastpos)
+{
+	return X509at_get_attr_by_NID(key->attributes, nid, lastpos);
+}
+
+int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
+			  int lastpos)
+{
+	return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos);
+}
+
+X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc)
+{
+	return X509at_get_attr(key->attributes, loc);
+}
+
+X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc)
+{
+	return X509at_delete_attr(key->attributes, loc);
+}
+
+int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr)
+{
+	if(X509at_add1_attr(&key->attributes, attr)) return 1;
+	return 0;
+}
+
+int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
+			const ASN1_OBJECT *obj, int type,
+			const unsigned char *bytes, int len)
+{
+	if(X509at_add1_attr_by_OBJ(&key->attributes, obj,
+				type, bytes, len)) return 1;
+	return 0;
+}
+
+int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
+			int nid, int type,
+			const unsigned char *bytes, int len)
+{
+	if(X509at_add1_attr_by_NID(&key->attributes, nid,
+				type, bytes, len)) return 1;
+	return 0;
+}
+
+int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
+			const char *attrname, int type,
+			const unsigned char *bytes, int len)
+{
+	if(X509at_add1_attr_by_txt(&key->attributes, attrname,
+				type, bytes, len)) return 1;
+	return 0;
+}
diff --git a/openssl/crypto/evp/evp_test.c b/openssl/crypto/evp/evp_test.c
new file mode 100644
index 0000000..55c7cdf
--- /dev/null
+++ b/openssl/crypto/evp/evp_test.c
@@ -0,0 +1,450 @@
+/* Written by Ben Laurie, 2001 */
+/*
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "../e_os.h"
+
+#include <openssl/opensslconf.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/err.h>
+#include <openssl/conf.h>
+
+static void hexdump(FILE *f,const char *title,const unsigned char *s,int l)
+    {
+    int n=0;
+
+    fprintf(f,"%s",title);
+    for( ; n < l ; ++n)
+	{
+	if((n%16) == 0)
+	    fprintf(f,"\n%04x",n);
+	fprintf(f," %02x",s[n]);
+	}
+    fprintf(f,"\n");
+    }
+
+static int convert(unsigned char *s)
+    {
+    unsigned char *d;
+
+    for(d=s ; *s ; s+=2,++d)
+	{
+	unsigned int n;
+
+	if(!s[1])
+	    {
+	    fprintf(stderr,"Odd number of hex digits!");
+	    EXIT(4);
+	    }
+	sscanf((char *)s,"%2x",&n);
+	*d=(unsigned char)n;
+	}
+    return s-d;
+    }
+
+static char *sstrsep(char **string, const char *delim)
+    {
+    char isdelim[256];
+    char *token = *string;
+
+    if (**string == 0)
+        return NULL;
+
+    memset(isdelim, 0, 256);
+    isdelim[0] = 1;
+
+    while (*delim)
+        {
+        isdelim[(unsigned char)(*delim)] = 1;
+        delim++;
+        }
+
+    while (!isdelim[(unsigned char)(**string)])
+        {
+        (*string)++;
+        }
+
+    if (**string)
+        {
+        **string = 0;
+        (*string)++;
+        }
+
+    return token;
+    }
+
+static unsigned char *ustrsep(char **p,const char *sep)
+    { return (unsigned char *)sstrsep(p,sep); }
+
+static int test1_exit(int ec)
+	{
+	EXIT(ec);
+	return(0);		/* To keep some compilers quiet */
+	}
+
+static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn,
+		  const unsigned char *iv,int in,
+		  const unsigned char *plaintext,int pn,
+		  const unsigned char *ciphertext,int cn,
+		  int encdec)
+    {
+    EVP_CIPHER_CTX ctx;
+    unsigned char out[4096];
+    int outl,outl2;
+
+    printf("Testing cipher %s%s\n",EVP_CIPHER_name(c),
+	   (encdec == 1 ? "(encrypt)" : (encdec == 0 ? "(decrypt)" : "(encrypt/decrypt)")));
+    hexdump(stdout,"Key",key,kn);
+    if(in)
+	hexdump(stdout,"IV",iv,in);
+    hexdump(stdout,"Plaintext",plaintext,pn);
+    hexdump(stdout,"Ciphertext",ciphertext,cn);
+    
+    if(kn != c->key_len)
+	{
+	fprintf(stderr,"Key length doesn't match, got %d expected %lu\n",kn,
+		(unsigned long)c->key_len);
+	test1_exit(5);
+	}
+    EVP_CIPHER_CTX_init(&ctx);
+    if (encdec != 0)
+        {
+	if(!EVP_EncryptInit_ex(&ctx,c,NULL,key,iv))
+	    {
+	    fprintf(stderr,"EncryptInit failed\n");
+	    ERR_print_errors_fp(stderr);
+	    test1_exit(10);
+	    }
+	EVP_CIPHER_CTX_set_padding(&ctx,0);
+
+	if(!EVP_EncryptUpdate(&ctx,out,&outl,plaintext,pn))
+	    {
+	    fprintf(stderr,"Encrypt failed\n");
+	    ERR_print_errors_fp(stderr);
+	    test1_exit(6);
+	    }
+	if(!EVP_EncryptFinal_ex(&ctx,out+outl,&outl2))
+	    {
+	    fprintf(stderr,"EncryptFinal failed\n");
+	    ERR_print_errors_fp(stderr);
+	    test1_exit(7);
+	    }
+
+	if(outl+outl2 != cn)
+	    {
+	    fprintf(stderr,"Ciphertext length mismatch got %d expected %d\n",
+		    outl+outl2,cn);
+	    test1_exit(8);
+	    }
+
+	if(memcmp(out,ciphertext,cn))
+	    {
+	    fprintf(stderr,"Ciphertext mismatch\n");
+	    hexdump(stderr,"Got",out,cn);
+	    hexdump(stderr,"Expected",ciphertext,cn);
+	    test1_exit(9);
+	    }
+	}
+
+    if (encdec <= 0)
+        {
+	if(!EVP_DecryptInit_ex(&ctx,c,NULL,key,iv))
+	    {
+	    fprintf(stderr,"DecryptInit failed\n");
+	    ERR_print_errors_fp(stderr);
+	    test1_exit(11);
+	    }
+	EVP_CIPHER_CTX_set_padding(&ctx,0);
+
+	if(!EVP_DecryptUpdate(&ctx,out,&outl,ciphertext,cn))
+	    {
+	    fprintf(stderr,"Decrypt failed\n");
+	    ERR_print_errors_fp(stderr);
+	    test1_exit(6);
+	    }
+	if(!EVP_DecryptFinal_ex(&ctx,out+outl,&outl2))
+	    {
+	    fprintf(stderr,"DecryptFinal failed\n");
+	    ERR_print_errors_fp(stderr);
+	    test1_exit(7);
+	    }
+
+	if(outl+outl2 != pn)
+	    {
+	    fprintf(stderr,"Plaintext length mismatch got %d expected %d\n",
+		    outl+outl2,pn);
+	    test1_exit(8);
+	    }
+
+	if(memcmp(out,plaintext,pn))
+	    {
+	    fprintf(stderr,"Plaintext mismatch\n");
+	    hexdump(stderr,"Got",out,pn);
+	    hexdump(stderr,"Expected",plaintext,pn);
+	    test1_exit(9);
+	    }
+	}
+
+    EVP_CIPHER_CTX_cleanup(&ctx);
+
+    printf("\n");
+    }
+
+static int test_cipher(const char *cipher,const unsigned char *key,int kn,
+		       const unsigned char *iv,int in,
+		       const unsigned char *plaintext,int pn,
+		       const unsigned char *ciphertext,int cn,
+		       int encdec)
+    {
+    const EVP_CIPHER *c;
+
+    c=EVP_get_cipherbyname(cipher);
+    if(!c)
+	return 0;
+
+    test1(c,key,kn,iv,in,plaintext,pn,ciphertext,cn,encdec);
+
+    return 1;
+    }
+
+static int test_digest(const char *digest,
+		       const unsigned char *plaintext,int pn,
+		       const unsigned char *ciphertext, unsigned int cn)
+    {
+    const EVP_MD *d;
+    EVP_MD_CTX ctx;
+    unsigned char md[EVP_MAX_MD_SIZE];
+    unsigned int mdn;
+
+    d=EVP_get_digestbyname(digest);
+    if(!d)
+	return 0;
+
+    printf("Testing digest %s\n",EVP_MD_name(d));
+    hexdump(stdout,"Plaintext",plaintext,pn);
+    hexdump(stdout,"Digest",ciphertext,cn);
+
+    EVP_MD_CTX_init(&ctx);
+    if(!EVP_DigestInit_ex(&ctx,d, NULL))
+	{
+	fprintf(stderr,"DigestInit failed\n");
+	ERR_print_errors_fp(stderr);
+	EXIT(100);
+	}
+    if(!EVP_DigestUpdate(&ctx,plaintext,pn))
+	{
+	fprintf(stderr,"DigestUpdate failed\n");
+	ERR_print_errors_fp(stderr);
+	EXIT(101);
+	}
+    if(!EVP_DigestFinal_ex(&ctx,md,&mdn))
+	{
+	fprintf(stderr,"DigestFinal failed\n");
+	ERR_print_errors_fp(stderr);
+	EXIT(101);
+	}
+    EVP_MD_CTX_cleanup(&ctx);
+
+    if(mdn != cn)
+	{
+	fprintf(stderr,"Digest length mismatch, got %d expected %d\n",mdn,cn);
+	EXIT(102);
+	}
+
+    if(memcmp(md,ciphertext,cn))
+	{
+	fprintf(stderr,"Digest mismatch\n");
+	hexdump(stderr,"Got",md,cn);
+	hexdump(stderr,"Expected",ciphertext,cn);
+	EXIT(103);
+	}
+
+    printf("\n");
+
+    EVP_MD_CTX_cleanup(&ctx);
+
+    return 1;
+    }
+
+int main(int argc,char **argv)
+    {
+    const char *szTestFile;
+    FILE *f;
+
+    if(argc != 2)
+	{
+	fprintf(stderr,"%s <test file>\n",argv[0]);
+	EXIT(1);
+	}
+    CRYPTO_malloc_debug_init();
+    CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+    szTestFile=argv[1];
+
+    f=fopen(szTestFile,"r");
+    if(!f)
+	{
+	perror(szTestFile);
+	EXIT(2);
+	}
+
+    /* Load up the software EVP_CIPHER and EVP_MD definitions */
+    OpenSSL_add_all_ciphers();
+    OpenSSL_add_all_digests();
+#ifndef OPENSSL_NO_ENGINE
+    /* Load all compiled-in ENGINEs */
+    ENGINE_load_builtin_engines();
+#endif
+#if 0
+    OPENSSL_config();
+#endif
+#ifndef OPENSSL_NO_ENGINE
+    /* Register all available ENGINE implementations of ciphers and digests.
+     * This could perhaps be changed to "ENGINE_register_all_complete()"? */
+    ENGINE_register_all_ciphers();
+    ENGINE_register_all_digests();
+    /* If we add command-line options, this statement should be switchable.
+     * It'll prevent ENGINEs being ENGINE_init()ialised for cipher/digest use if
+     * they weren't already initialised. */
+    /* ENGINE_set_cipher_flags(ENGINE_CIPHER_FLAG_NOINIT); */
+#endif
+
+    for( ; ; )
+	{
+	char line[4096];
+	char *p;
+	char *cipher;
+	unsigned char *iv,*key,*plaintext,*ciphertext;
+	int encdec;
+	int kn,in,pn,cn;
+
+	if(!fgets((char *)line,sizeof line,f))
+	    break;
+	if(line[0] == '#' || line[0] == '\n')
+	    continue;
+	p=line;
+	cipher=sstrsep(&p,":");	
+	key=ustrsep(&p,":");
+	iv=ustrsep(&p,":");
+	plaintext=ustrsep(&p,":");
+	ciphertext=ustrsep(&p,":");
+	if (p[-1] == '\n') {
+	    p[-1] = '\0';
+	    encdec = -1;
+	} else {
+	    encdec = atoi(sstrsep(&p,"\n"));
+	}
+	      
+
+	kn=convert(key);
+	in=convert(iv);
+	pn=convert(plaintext);
+	cn=convert(ciphertext);
+
+	if(!test_cipher(cipher,key,kn,iv,in,plaintext,pn,ciphertext,cn,encdec)
+	   && !test_digest(cipher,plaintext,pn,ciphertext,cn))
+	    {
+#ifdef OPENSSL_NO_AES
+	    if (strstr(cipher, "AES") == cipher)
+		{
+		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
+		continue;
+		}
+#endif
+#ifdef OPENSSL_NO_DES
+	    if (strstr(cipher, "DES") == cipher)
+		{
+		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
+		continue;
+		}
+#endif
+#ifdef OPENSSL_NO_RC4
+	    if (strstr(cipher, "RC4") == cipher)
+		{
+		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
+		continue;
+		}
+#endif
+#ifdef OPENSSL_NO_CAMELLIA
+	    if (strstr(cipher, "CAMELLIA") == cipher)
+		{
+		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
+		continue;
+		}
+#endif
+#ifdef OPENSSL_NO_SEED
+	    if (strstr(cipher, "SEED") == cipher)
+		{
+		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
+		continue;
+		}
+#endif
+	    fprintf(stderr,"Can't find %s\n",cipher);
+	    EXIT(3);
+	    }
+	}
+	fclose(f);
+
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_cleanup();
+#endif
+    EVP_cleanup();
+    CRYPTO_cleanup_all_ex_data();
+    ERR_remove_thread_state(NULL);
+    ERR_free_strings();
+    CRYPTO_mem_leaks_fp(stderr);
+
+    return 0;
+    }
diff --git a/openssl/crypto/evp/evptests.txt b/openssl/crypto/evp/evptests.txt
new file mode 100644
index 0000000..beb1214
--- /dev/null
+++ b/openssl/crypto/evp/evptests.txt
@@ -0,0 +1,321 @@
+#cipher:key:iv:plaintext:ciphertext:0/1(decrypt/encrypt)
+#digest:::input:output
+
+# SHA(1) tests (from shatest.c)
+SHA1:::616263:a9993e364706816aba3e25717850c26c9cd0d89d
+
+# MD5 tests (from md5test.c)
+MD5::::d41d8cd98f00b204e9800998ecf8427e
+MD5:::61:0cc175b9c0f1b6a831c399e269772661
+MD5:::616263:900150983cd24fb0d6963f7d28e17f72
+MD5:::6d65737361676520646967657374:f96b697d7cb7938d525a2f31aaf161d0
+MD5:::6162636465666768696a6b6c6d6e6f707172737475767778797a:c3fcd3d76192e4007dfb496cca67e13b
+MD5:::4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a30313233343536373839:d174ab98d277d9f5a5611c2c9f419d9f
+MD5:::3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930:57edf4a22be3c955ac49da2e2107b67a
+
+# AES 128 ECB tests (from FIPS-197 test vectors, encrypt)
+
+AES-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:69C4E0D86A7B0430D8CDB78070B4C55A:1
+
+# AES 192 ECB tests (from FIPS-197 test vectors, encrypt)
+
+AES-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:DDA97CA4864CDFE06EAF70A0EC0D7191:1
+
+# AES 256 ECB tests (from FIPS-197 test vectors, encrypt)
+
+AES-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:8EA2B7CA516745BFEAFC49904B496089:1
+
+# AES 128 ECB tests (from NIST test vectors, encrypt)
+
+#AES-128-ECB:00000000000000000000000000000000::00000000000000000000000000000000:C34C052CC0DA8D73451AFE5F03BE297F:1
+
+# AES 128 ECB tests (from NIST test vectors, decrypt)
+
+#AES-128-ECB:00000000000000000000000000000000::44416AC2D1F53C583303917E6BE9EBE0:00000000000000000000000000000000:0
+
+# AES 192 ECB tests (from NIST test vectors, decrypt)
+
+#AES-192-ECB:000000000000000000000000000000000000000000000000::48E31E9E256718F29229319C19F15BA4:00000000000000000000000000000000:0
+
+# AES 256 ECB tests (from NIST test vectors, decrypt)
+
+#AES-256-ECB:0000000000000000000000000000000000000000000000000000000000000000::058CCFFDBBCB382D1F6F56585D8A4ADE:00000000000000000000000000000000:0
+
+# AES 128 CBC tests (from NIST test vectors, encrypt)
+
+#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:8A05FC5E095AF4848A08D328D3688E3D:1
+
+# AES 192 CBC tests (from NIST test vectors, encrypt)
+
+#AES-192-CBC:000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:7BD966D53AD8C1BB85D2ADFAE87BB104:1
+
+# AES 256 CBC tests (from NIST test vectors, encrypt)
+
+#AES-256-CBC:0000000000000000000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:FE3C53653E2F45B56FCD88B2CC898FF0:1
+
+# AES 128 CBC tests (from NIST test vectors, decrypt)
+
+#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:FACA37E0B0C85373DF706E73F7C9AF86:00000000000000000000000000000000:0
+
+# AES tests from NIST document SP800-38A
+# For all ECB encrypts and decrypts, the transformed sequence is
+#   AES-bits-ECB:key::plaintext:ciphertext:encdec
+# ECB-AES128.Encrypt and ECB-AES128.Decrypt
+AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:3AD77BB40D7A3660A89ECAF32466EF97
+AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:F5D3D58503B9699DE785895A96FDBAAF
+AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:43B1CD7F598ECE23881B00E3ED030688
+AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:7B0C785E27E8AD3F8223207104725DD4
+# ECB-AES192.Encrypt and ECB-AES192.Decrypt 
+AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:BD334F1D6E45F25FF712A214571FA5CC
+AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:974104846D0AD3AD7734ECB3ECEE4EEF
+AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:EF7AFD2270E2E60ADCE0BA2FACE6444E
+AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:9A4B41BA738D6C72FB16691603C18E0E
+# ECB-AES256.Encrypt and ECB-AES256.Decrypt 
+AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:F3EED1BDB5D2A03C064B5A7E3DB181F8
+AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:591CCB10D410ED26DC5BA74A31362870
+AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:B6ED21B99CA6F4F9F153E7B1BEAFED1D
+AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:23304B7A39F9F3FF067D8D8F9E24ECC7
+# For all CBC encrypts and decrypts, the transformed sequence is
+#   AES-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec
+# CBC-AES128.Encrypt and CBC-AES128.Decrypt 
+AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:7649ABAC8119B246CEE98E9B12E9197D
+AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:7649ABAC8119B246CEE98E9B12E9197D:AE2D8A571E03AC9C9EB76FAC45AF8E51:5086CB9B507219EE95DB113A917678B2
+AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:5086CB9B507219EE95DB113A917678B2:30C81C46A35CE411E5FBC1191A0A52EF:73BED6B8E3C1743B7116E69E22229516
+AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:73BED6B8E3C1743B7116E69E22229516:F69F2445DF4F9B17AD2B417BE66C3710:3FF1CAA1681FAC09120ECA307586E1A7
+# CBC-AES192.Encrypt and CBC-AES192.Decrypt 
+AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:4F021DB243BC633D7178183A9FA071E8
+AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:4F021DB243BC633D7178183A9FA071E8:AE2D8A571E03AC9C9EB76FAC45AF8E51:B4D9ADA9AD7DEDF4E5E738763F69145A
+AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:B4D9ADA9AD7DEDF4E5E738763F69145A:30C81C46A35CE411E5FBC1191A0A52EF:571B242012FB7AE07FA9BAAC3DF102E0
+AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:571B242012FB7AE07FA9BAAC3DF102E0:F69F2445DF4F9B17AD2B417BE66C3710:08B0E27988598881D920A9E64F5615CD
+# CBC-AES256.Encrypt and CBC-AES256.Decrypt 
+AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:F58C4C04D6E5F1BA779EABFB5F7BFBD6
+AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:F58C4C04D6E5F1BA779EABFB5F7BFBD6:AE2D8A571E03AC9C9EB76FAC45AF8E51:9CFC4E967EDB808D679F777BC6702C7D
+AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:9CFC4E967EDB808D679F777BC6702C7D:30C81C46A35CE411E5FBC1191A0A52EF:39F23369A9D9BACFA530E26304231461
+AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39F23369A9D9BACFA530E26304231461:F69F2445DF4F9B17AD2B417BE66C3710:B2EB05E2C39BE9FCDA6C19078C6A9D1B
+# We don't support CFB{1,8}-AESxxx.{En,De}crypt
+# For all CFB128 encrypts and decrypts, the transformed sequence is
+#   AES-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec
+# CFB128-AES128.Encrypt 
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:1
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:1
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:1
+# CFB128-AES128.Decrypt 
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:0
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:0
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:0
+# CFB128-AES192.Encrypt
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:1
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:1
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:1
+# CFB128-AES192.Decrypt
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:0
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:0
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:0
+# CFB128-AES256.Encrypt 
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:1
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:1
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:1
+# CFB128-AES256.Decrypt 
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:0
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:0
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:0
+# For all OFB encrypts and decrypts, the transformed sequence is
+#   AES-bits-CFB:key:IV/output':plaintext:ciphertext:encdec
+# OFB-AES128.Encrypt 
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1 
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:1 
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:1 
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:1 
+# OFB-AES128.Decrypt 
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:0
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:0
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:0
+# OFB-AES192.Encrypt 
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1 
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:1 
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:1 
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:1 
+# OFB-AES192.Decrypt 
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0 
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:0 
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:0 
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:0 
+# OFB-AES256.Encrypt 
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:1
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:1
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:1
+# OFB-AES256.Decrypt 
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:0
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:0
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:0
+
+# DES ECB tests (from destest)
+
+DES-ECB:0000000000000000::0000000000000000:8CA64DE9C1B123A7
+DES-ECB:FFFFFFFFFFFFFFFF::FFFFFFFFFFFFFFFF:7359B2163E4EDC58
+DES-ECB:3000000000000000::1000000000000001:958E6E627A05557B
+DES-ECB:1111111111111111::1111111111111111:F40379AB9E0EC533
+DES-ECB:0123456789ABCDEF::1111111111111111:17668DFC7292532D
+DES-ECB:1111111111111111::0123456789ABCDEF:8A5AE1F81AB8F2DD
+DES-ECB:FEDCBA9876543210::0123456789ABCDEF:ED39D950FA74BCC4
+
+# DESX-CBC tests (from destest)
+DESX-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:846B2914851E9A2954732F8AA0A611C115CDC2D7951B1053A63C5E03B21AA3C4
+
+# DES EDE3 CBC tests (from destest)
+DES-EDE3-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675
+
+# RC4 tests (from rc4test)
+RC4:0123456789abcdef0123456789abcdef::0123456789abcdef:75b7878099e0c596
+RC4:0123456789abcdef0123456789abcdef::0000000000000000:7494c2e7104b0879
+RC4:00000000000000000000000000000000::0000000000000000:de188941a3375d3a
+RC4:ef012345ef012345ef012345ef012345::0000000000000000000000000000000000000000:d6a141a7ec3c38dfbd615a1162e1c7ba36b67858
+RC4:0123456789abcdef0123456789abcdef::123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345678:66a0949f8af7d6891f7f832ba833c00c892ebe30143ce28740011ecf
+RC4:ef012345ef012345ef012345ef012345::00000000000000000000:d6a141a7ec3c38dfbd61
+
+
+# Camellia tests from RFC3713
+# For all ECB encrypts and decrypts, the transformed sequence is
+#   CAMELLIA-bits-ECB:key::plaintext:ciphertext:encdec
+CAMELLIA-128-ECB:0123456789abcdeffedcba9876543210::0123456789abcdeffedcba9876543210:67673138549669730857065648eabe43
+CAMELLIA-192-ECB:0123456789abcdeffedcba98765432100011223344556677::0123456789abcdeffedcba9876543210:b4993401b3e996f84ee5cee7d79b09b9
+CAMELLIA-256-ECB:0123456789abcdeffedcba987654321000112233445566778899aabbccddeeff::0123456789abcdeffedcba9876543210:9acc237dff16d76c20ef7c919e3a7509
+
+# ECB-CAMELLIA128.Encrypt
+CAMELLIA-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:77CF412067AF8270613529149919546F:1
+CAMELLIA-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:B22F3C36B72D31329EEE8ADDC2906C68:1
+CAMELLIA-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:2EDF1F3418D53B88841FC8985FB1ECF2:1
+
+# ECB-CAMELLIA128.Encrypt and ECB-CAMELLIA128.Decrypt 
+CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:432FC5DCD628115B7C388D770B270C96
+CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:0BE1F14023782A22E8384C5ABB7FAB2B
+CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:A0A1ABCD1893AB6FE0FE5B65DF5F8636
+CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:E61925E0D5DFAA9BB29F815B3076E51A
+
+# ECB-CAMELLIA192.Encrypt and ECB-CAMELLIA192.Decrypt 
+CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:CCCC6C4E138B45848514D48D0D3439D3
+CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:5713C62C14B2EC0F8393B6AFD6F5785A
+CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:B40ED2B60EB54D09D030CF511FEEF366
+CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:909DBD95799096748CB27357E73E1D26
+
+# ECB-CAMELLIA256.Encrypt and ECB-CAMELLIA256.Decrypt 
+CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:BEFD219B112FA00098919CD101C9CCFA
+CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:C91D3A8F1AEA08A9386CF4B66C0169EA
+CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:A623D711DC5F25A51BB8A80D56397D28
+CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:7960109FB6DC42947FCFE59EA3C5EB6B
+
+# For all CBC encrypts and decrypts, the transformed sequence is
+#   CAMELLIA-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec
+# CBC-CAMELLIA128.Encrypt and CBC-CAMELLIA128.Decrypt 
+CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:1607CF494B36BBF00DAEB0B503C831AB
+CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:1607CF494B36BBF00DAEB0B503C831AB:AE2D8A571E03AC9C9EB76FAC45AF8E51:A2F2CF671629EF7840C5A5DFB5074887
+CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:A2F2CF671629EF7840C5A5DFB5074887:30C81C46A35CE411E5FBC1191A0A52EF:0F06165008CF8B8B5A63586362543E54
+CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:36A84CDAFD5F9A85ADA0F0A993D6D577:F69F2445DF4F9B17AD2B417BE66C3710:74C64268CDB8B8FAF5B34E8AF3732980
+
+# CBC-CAMELLIA192.Encrypt and CBC-CAMELLIA192.Decrypt 
+CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:2A4830AB5AC4A1A2405955FD2195CF93
+CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2A4830AB5AC4A1A2405955FD2195CF93:AE2D8A571E03AC9C9EB76FAC45AF8E51:5D5A869BD14CE54264F892A6DD2EC3D5
+CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:5D5A869BD14CE54264F892A6DD2EC3D5:30C81C46A35CE411E5FBC1191A0A52EF:37D359C3349836D884E310ADDF68C449
+CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:37D359C3349836D884E310ADDF68C449:F69F2445DF4F9B17AD2B417BE66C3710:01FAAA930B4AB9916E9668E1428C6B08
+
+# CBC-CAMELLIA256.Encrypt and CBC-CAMELLIA256.Decrypt 
+CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:E6CFA35FC02B134A4D2C0B6737AC3EDA
+CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E6CFA35FC02B134A4D2C0B6737AC3EDA:AE2D8A571E03AC9C9EB76FAC45AF8E51:36CBEB73BD504B4070B1B7DE2B21EB50
+CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:36CBEB73BD504B4070B1B7DE2B21EB50:30C81C46A35CE411E5FBC1191A0A52EF:E31A6055297D96CA3330CDF1B1860A83
+CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E31A6055297D96CA3330CDF1B1860A83:F69F2445DF4F9B17AD2B417BE66C3710:5D563F6D1CCCF236051C0C5C1C58F28F
+
+# We don't support CFB{1,8}-CAMELLIAxxx.{En,De}crypt
+# For all CFB128 encrypts and decrypts, the transformed sequence is
+#   CAMELLIA-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec
+# CFB128-CAMELLIA128.Encrypt 
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:1
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:1
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:1
+
+# CFB128-CAMELLIA128.Decrypt 
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:0
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:0
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:0
+
+# CFB128-CAMELLIA192.Encrypt
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:1
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:1
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:1
+
+# CFB128-CAMELLIA192.Decrypt
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:0
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:0
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:0
+
+# CFB128-CAMELLIA256.Encrypt 
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:1
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:1
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:1
+
+# CFB128-CAMELLIA256.Decrypt 
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:0
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:0
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:0
+
+# For all OFB encrypts and decrypts, the transformed sequence is
+#   CAMELLIA-bits-OFB:key:IV/output':plaintext:ciphertext:encdec
+# OFB-CAMELLIA128.Encrypt 
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:1
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:1
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:1
+
+# OFB-CAMELLIA128.Decrypt 
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:0
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:0
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:0
+
+# OFB-CAMELLIA192.Encrypt 
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:1
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:1
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:1
+
+# OFB-CAMELLIA192.Decrypt 
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:0
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:0
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:0
+
+# OFB-CAMELLIA256.Encrypt 
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:1
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:1
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:1
+
+# OFB-CAMELLIA256.Decrypt 
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:0
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:0
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:0
+
+# SEED test vectors from RFC4269
+SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:0
+SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:0
+SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:0
+SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:0
+SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:1
+SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:1
+SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:1
+SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:1
diff --git a/openssl/crypto/evp/m_dss.c b/openssl/crypto/evp/m_dss.c
new file mode 100644
index 0000000..48c2689
--- /dev/null
+++ b/openssl/crypto/evp/m_dss.c
@@ -0,0 +1,99 @@
+/* crypto/evp/m_dss.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+
+#ifndef OPENSSL_NO_SHA
+
+static int init(EVP_MD_CTX *ctx)
+	{ return SHA1_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{ return SHA1_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+	{ return SHA1_Final(md,ctx->md_data); }
+
+static const EVP_MD dsa_md=
+	{
+	NID_dsaWithSHA,
+	NID_dsaWithSHA,
+	SHA_DIGEST_LENGTH,
+	EVP_MD_FLAG_PKEY_DIGEST,
+	init,
+	update,
+	final,
+	NULL,
+	NULL,
+	EVP_PKEY_DSA_method,
+	SHA_CBLOCK,
+	sizeof(EVP_MD *)+sizeof(SHA_CTX),
+	};
+
+const EVP_MD *EVP_dss(void)
+	{
+	return(&dsa_md);
+	}
+#endif
diff --git a/openssl/crypto/evp/m_dss1.c b/openssl/crypto/evp/m_dss1.c
new file mode 100644
index 0000000..4f03fb7
--- /dev/null
+++ b/openssl/crypto/evp/m_dss1.c
@@ -0,0 +1,100 @@
+/* crypto/evp/m_dss1.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_SHA
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+
+static int init(EVP_MD_CTX *ctx)
+	{ return SHA1_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{ return SHA1_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+	{ return SHA1_Final(md,ctx->md_data); }
+
+static const EVP_MD dss1_md=
+	{
+	NID_dsa,
+	NID_dsaWithSHA1,
+	SHA_DIGEST_LENGTH,
+	EVP_MD_FLAG_PKEY_DIGEST,
+	init,
+	update,
+	final,
+	NULL,
+	NULL,
+	EVP_PKEY_DSA_method,
+	SHA_CBLOCK,
+	sizeof(EVP_MD *)+sizeof(SHA_CTX),
+	};
+
+const EVP_MD *EVP_dss1(void)
+	{
+	return(&dss1_md);
+	}
+#endif
diff --git a/openssl/crypto/evp/m_ecdsa.c b/openssl/crypto/evp/m_ecdsa.c
new file mode 100644
index 0000000..8d87a49
--- /dev/null
+++ b/openssl/crypto/evp/m_ecdsa.c
@@ -0,0 +1,148 @@
+/* crypto/evp/m_ecdsa.c */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+#ifndef OPENSSL_NO_SHA
+static int init(EVP_MD_CTX *ctx)
+	{ return SHA1_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{ return SHA1_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+	{ return SHA1_Final(md,ctx->md_data); }
+
+static const EVP_MD ecdsa_md=
+	{
+	NID_ecdsa_with_SHA1,
+	NID_ecdsa_with_SHA1,
+	SHA_DIGEST_LENGTH,
+	EVP_MD_FLAG_PKEY_DIGEST,
+	init,
+	update,
+	final,
+	NULL,
+	NULL,
+	EVP_PKEY_ECDSA_method,
+	SHA_CBLOCK,
+	sizeof(EVP_MD *)+sizeof(SHA_CTX),
+	};
+
+const EVP_MD *EVP_ecdsa(void)
+	{
+	return(&ecdsa_md);
+	}
+#endif
diff --git a/openssl/crypto/evp/m_md2.c b/openssl/crypto/evp/m_md2.c
new file mode 100644
index 0000000..5ce849f
--- /dev/null
+++ b/openssl/crypto/evp/m_md2.c
@@ -0,0 +1,101 @@
+/* crypto/evp/m_md2.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_MD2
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/md2.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+
+static int init(EVP_MD_CTX *ctx)
+	{ return MD2_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{ return MD2_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+	{ return MD2_Final(md,ctx->md_data); }
+
+static const EVP_MD md2_md=
+	{
+	NID_md2,
+	NID_md2WithRSAEncryption,
+	MD2_DIGEST_LENGTH,
+	0,
+	init,
+	update,
+	final,
+	NULL,
+	NULL,
+	EVP_PKEY_RSA_method,
+	MD2_BLOCK,
+	sizeof(EVP_MD *)+sizeof(MD2_CTX),
+	};
+
+const EVP_MD *EVP_md2(void)
+	{
+	return(&md2_md);
+	}
+#endif
diff --git a/openssl/crypto/evp/m_md4.c b/openssl/crypto/evp/m_md4.c
new file mode 100644
index 0000000..1e0b7c5
--- /dev/null
+++ b/openssl/crypto/evp/m_md4.c
@@ -0,0 +1,101 @@
+/* crypto/evp/m_md4.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_MD4
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/md4.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+
+static int init(EVP_MD_CTX *ctx)
+	{ return MD4_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{ return MD4_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+	{ return MD4_Final(md,ctx->md_data); }
+
+static const EVP_MD md4_md=
+	{
+	NID_md4,
+	NID_md4WithRSAEncryption,
+	MD4_DIGEST_LENGTH,
+	0,
+	init,
+	update,
+	final,
+	NULL,
+	NULL,
+	EVP_PKEY_RSA_method,
+	MD4_CBLOCK,
+	sizeof(EVP_MD *)+sizeof(MD4_CTX),
+	};
+
+const EVP_MD *EVP_md4(void)
+	{
+	return(&md4_md);
+	}
+#endif
diff --git a/openssl/crypto/evp/m_md5.c b/openssl/crypto/evp/m_md5.c
new file mode 100644
index 0000000..63c1421
--- /dev/null
+++ b/openssl/crypto/evp/m_md5.c
@@ -0,0 +1,101 @@
+/* crypto/evp/m_md5.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_MD5
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/md5.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+
+static int init(EVP_MD_CTX *ctx)
+	{ return MD5_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{ return MD5_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+	{ return MD5_Final(md,ctx->md_data); }
+
+static const EVP_MD md5_md=
+	{
+	NID_md5,
+	NID_md5WithRSAEncryption,
+	MD5_DIGEST_LENGTH,
+	0,
+	init,
+	update,
+	final,
+	NULL,
+	NULL,
+	EVP_PKEY_RSA_method,
+	MD5_CBLOCK,
+	sizeof(EVP_MD *)+sizeof(MD5_CTX),
+	};
+
+const EVP_MD *EVP_md5(void)
+	{
+	return(&md5_md);
+	}
+#endif
diff --git a/openssl/crypto/evp/m_mdc2.c b/openssl/crypto/evp/m_mdc2.c
new file mode 100644
index 0000000..b08d559
--- /dev/null
+++ b/openssl/crypto/evp/m_mdc2.c
@@ -0,0 +1,101 @@
+/* crypto/evp/m_mdc2.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_MDC2
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/mdc2.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+
+static int init(EVP_MD_CTX *ctx)
+	{ return MDC2_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{ return MDC2_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+	{ return MDC2_Final(md,ctx->md_data); }
+
+static const EVP_MD mdc2_md=
+	{
+	NID_mdc2,
+	NID_mdc2WithRSA,
+	MDC2_DIGEST_LENGTH,
+	0,
+	init,
+	update,
+	final,
+	NULL,
+	NULL,
+	EVP_PKEY_RSA_ASN1_OCTET_STRING_method,
+	MDC2_BLOCK,
+	sizeof(EVP_MD *)+sizeof(MDC2_CTX),
+	};
+
+const EVP_MD *EVP_mdc2(void)
+	{
+	return(&mdc2_md);
+	}
+#endif
diff --git a/openssl/crypto/evp/m_null.c b/openssl/crypto/evp/m_null.c
new file mode 100644
index 0000000..cb07216
--- /dev/null
+++ b/openssl/crypto/evp/m_null.c
@@ -0,0 +1,95 @@
+/* crypto/evp/m_null.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+static int init(EVP_MD_CTX *ctx)
+	{ return 1; }
+
+static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{ return 1; }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+	{ return 1; }
+
+static const EVP_MD null_md=
+	{
+	NID_undef,
+	NID_undef,
+	0,
+	0,
+	init,
+	update,
+	final,
+	NULL,
+	NULL,
+	EVP_PKEY_NULL_method,
+	0,
+	sizeof(EVP_MD *),
+	};
+
+const EVP_MD *EVP_md_null(void)
+	{
+	return(&null_md);
+	}
+
+
diff --git a/openssl/crypto/evp/m_ripemd.c b/openssl/crypto/evp/m_ripemd.c
new file mode 100644
index 0000000..a1d60ee
--- /dev/null
+++ b/openssl/crypto/evp/m_ripemd.c
@@ -0,0 +1,101 @@
+/* crypto/evp/m_ripemd.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_RIPEMD
+
+#include <openssl/ripemd.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+
+static int init(EVP_MD_CTX *ctx)
+	{ return RIPEMD160_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{ return RIPEMD160_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+	{ return RIPEMD160_Final(md,ctx->md_data); }
+
+static const EVP_MD ripemd160_md=
+	{
+	NID_ripemd160,
+	NID_ripemd160WithRSA,
+	RIPEMD160_DIGEST_LENGTH,
+	0,
+	init,
+	update,
+	final,
+	NULL,
+	NULL,
+	EVP_PKEY_RSA_method,
+	RIPEMD160_CBLOCK,
+	sizeof(EVP_MD *)+sizeof(RIPEMD160_CTX),
+	};
+
+const EVP_MD *EVP_ripemd160(void)
+	{
+	return(&ripemd160_md);
+	}
+#endif
diff --git a/openssl/crypto/evp/m_sha.c b/openssl/crypto/evp/m_sha.c
new file mode 100644
index 0000000..acccc8f
--- /dev/null
+++ b/openssl/crypto/evp/m_sha.c
@@ -0,0 +1,100 @@
+/* crypto/evp/m_sha.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0)
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+
+static int init(EVP_MD_CTX *ctx)
+	{ return SHA_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{ return SHA_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+	{ return SHA_Final(md,ctx->md_data); }
+
+static const EVP_MD sha_md=
+	{
+	NID_sha,
+	NID_shaWithRSAEncryption,
+	SHA_DIGEST_LENGTH,
+	0,
+	init,
+	update,
+	final,
+	NULL,
+	NULL,
+	EVP_PKEY_RSA_method,
+	SHA_CBLOCK,
+	sizeof(EVP_MD *)+sizeof(SHA_CTX),
+	};
+
+const EVP_MD *EVP_sha(void)
+	{
+	return(&sha_md);
+	}
+#endif
diff --git a/openssl/crypto/evp/m_sha1.c b/openssl/crypto/evp/m_sha1.c
new file mode 100644
index 0000000..9a2790f
--- /dev/null
+++ b/openssl/crypto/evp/m_sha1.c
@@ -0,0 +1,204 @@
+/* crypto/evp/m_sha1.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_SHA
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+
+static int init(EVP_MD_CTX *ctx)
+	{ return SHA1_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{ return SHA1_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+	{ return SHA1_Final(md,ctx->md_data); }
+
+static const EVP_MD sha1_md=
+	{
+	NID_sha1,
+	NID_sha1WithRSAEncryption,
+	SHA_DIGEST_LENGTH,
+	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
+	init,
+	update,
+	final,
+	NULL,
+	NULL,
+	EVP_PKEY_RSA_method,
+	SHA_CBLOCK,
+	sizeof(EVP_MD *)+sizeof(SHA_CTX),
+	};
+
+const EVP_MD *EVP_sha1(void)
+	{
+	return(&sha1_md);
+	}
+#endif
+
+#ifndef OPENSSL_NO_SHA256
+static int init224(EVP_MD_CTX *ctx)
+	{ return SHA224_Init(ctx->md_data); }
+static int init256(EVP_MD_CTX *ctx)
+	{ return SHA256_Init(ctx->md_data); }
+/*
+ * Even though there're separate SHA224_[Update|Final], we call
+ * SHA256 functions even in SHA224 context. This is what happens
+ * there anyway, so we can spare few CPU cycles:-)
+ */
+static int update256(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{ return SHA256_Update(ctx->md_data,data,count); }
+static int final256(EVP_MD_CTX *ctx,unsigned char *md)
+	{ return SHA256_Final(md,ctx->md_data); }
+
+static const EVP_MD sha224_md=
+	{
+	NID_sha224,
+	NID_sha224WithRSAEncryption,
+	SHA224_DIGEST_LENGTH,
+	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
+	init224,
+	update256,
+	final256,
+	NULL,
+	NULL,
+	EVP_PKEY_RSA_method,
+	SHA256_CBLOCK,
+	sizeof(EVP_MD *)+sizeof(SHA256_CTX),
+	};
+
+const EVP_MD *EVP_sha224(void)
+	{ return(&sha224_md); }
+
+static const EVP_MD sha256_md=
+	{
+	NID_sha256,
+	NID_sha256WithRSAEncryption,
+	SHA256_DIGEST_LENGTH,
+	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
+	init256,
+	update256,
+	final256,
+	NULL,
+	NULL,
+	EVP_PKEY_RSA_method,
+	SHA256_CBLOCK,
+	sizeof(EVP_MD *)+sizeof(SHA256_CTX),
+	};
+
+const EVP_MD *EVP_sha256(void)
+	{ return(&sha256_md); }
+#endif	/* ifndef OPENSSL_NO_SHA256 */
+
+#ifndef OPENSSL_NO_SHA512
+static int init384(EVP_MD_CTX *ctx)
+	{ return SHA384_Init(ctx->md_data); }
+static int init512(EVP_MD_CTX *ctx)
+	{ return SHA512_Init(ctx->md_data); }
+/* See comment in SHA224/256 section */
+static int update512(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{ return SHA512_Update(ctx->md_data,data,count); }
+static int final512(EVP_MD_CTX *ctx,unsigned char *md)
+	{ return SHA512_Final(md,ctx->md_data); }
+
+static const EVP_MD sha384_md=
+	{
+	NID_sha384,
+	NID_sha384WithRSAEncryption,
+	SHA384_DIGEST_LENGTH,
+	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
+	init384,
+	update512,
+	final512,
+	NULL,
+	NULL,
+	EVP_PKEY_RSA_method,
+	SHA512_CBLOCK,
+	sizeof(EVP_MD *)+sizeof(SHA512_CTX),
+	};
+
+const EVP_MD *EVP_sha384(void)
+	{ return(&sha384_md); }
+
+static const EVP_MD sha512_md=
+	{
+	NID_sha512,
+	NID_sha512WithRSAEncryption,
+	SHA512_DIGEST_LENGTH,
+	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
+	init512,
+	update512,
+	final512,
+	NULL,
+	NULL,
+	EVP_PKEY_RSA_method,
+	SHA512_CBLOCK,
+	sizeof(EVP_MD *)+sizeof(SHA512_CTX),
+	};
+
+const EVP_MD *EVP_sha512(void)
+	{ return(&sha512_md); }
+#endif	/* ifndef OPENSSL_NO_SHA512 */
diff --git a/openssl/crypto/evp/m_sigver.c b/openssl/crypto/evp/m_sigver.c
new file mode 100644
index 0000000..7e2731f
--- /dev/null
+++ b/openssl/crypto/evp/m_sigver.c
@@ -0,0 +1,200 @@
+/* m_sigver.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006,2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include "evp_locl.h"
+
+static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+			  const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,
+			  int ver)
+	{
+	if (ctx->pctx == NULL)
+		ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
+	if (ctx->pctx == NULL)
+		return 0;
+
+	if (type == NULL)
+		{
+		int def_nid;
+		if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
+			type = EVP_get_digestbynid(def_nid);
+		}
+
+	if (type == NULL)
+		{
+		EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST);
+		return 0;
+		}
+
+	if (ver)
+		{
+		if (ctx->pctx->pmeth->verifyctx_init)
+			{
+			if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <=0)
+				return 0;
+			ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
+			}
+		else if (EVP_PKEY_verify_init(ctx->pctx) <= 0)
+			return 0;
+		}
+	else
+		{
+		if (ctx->pctx->pmeth->signctx_init)
+			{
+			if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0)
+				return 0;
+			ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
+			}
+		else if (EVP_PKEY_sign_init(ctx->pctx) <= 0)
+			return 0;
+		}
+	if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
+		return 0;
+	if (pctx)
+		*pctx = ctx->pctx;
+	if (!EVP_DigestInit_ex(ctx, type, e))
+		return 0;
+	return 1;
+	}
+
+int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
+	{
+	return do_sigver_init(ctx, pctx, type, e, pkey, 0);
+	}
+
+int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
+	{
+	return do_sigver_init(ctx, pctx, type, e, pkey, 1);
+	}
+
+int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen)
+	{
+	int sctx, r = 0;
+	if (ctx->pctx->pmeth->signctx)
+		sctx = 1;
+	else
+		sctx = 0;
+	if (sigret)
+		{
+		EVP_MD_CTX tmp_ctx;
+		unsigned char md[EVP_MAX_MD_SIZE];
+		unsigned int mdlen;
+		EVP_MD_CTX_init(&tmp_ctx);
+		if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
+		     	return 0;
+		if (sctx)
+			r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx,
+					sigret, siglen, &tmp_ctx);
+		else
+			r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen);
+		EVP_MD_CTX_cleanup(&tmp_ctx);
+		if (sctx || !r)
+			return r;
+		if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0)
+			return 0;
+		}
+	else
+		{
+		if (sctx)
+			{
+			if (ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx) <= 0)
+				return 0;
+			}
+		else
+			{
+			int s = EVP_MD_size(ctx->digest);
+			if (s < 0 || EVP_PKEY_sign(ctx->pctx, sigret, siglen, NULL, s) <= 0)
+				return 0;
+			}
+		}
+	return 1;
+	}
+
+int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen)
+	{
+	EVP_MD_CTX tmp_ctx;
+	unsigned char md[EVP_MAX_MD_SIZE];
+	int r;
+	unsigned int mdlen;
+	int vctx;
+
+	if (ctx->pctx->pmeth->verifyctx)
+		vctx = 1;
+	else
+		vctx = 0;
+	EVP_MD_CTX_init(&tmp_ctx);
+	if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
+		return -1;	
+	if (vctx)
+		{
+		r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx,
+					sig, siglen, &tmp_ctx);
+		}
+	else
+		r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen);
+	EVP_MD_CTX_cleanup(&tmp_ctx);
+	if (vctx || !r)
+		return r;
+	return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);
+	}
diff --git a/openssl/crypto/evp/m_wp.c b/openssl/crypto/evp/m_wp.c
new file mode 100644
index 0000000..1ce47c0
--- /dev/null
+++ b/openssl/crypto/evp/m_wp.c
@@ -0,0 +1,42 @@
+/* crypto/evp/m_wp.c */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_WHIRLPOOL
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/whrlpool.h>
+
+static int init(EVP_MD_CTX *ctx)
+	{ return WHIRLPOOL_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{ return WHIRLPOOL_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+	{ return WHIRLPOOL_Final(md,ctx->md_data); }
+
+static const EVP_MD whirlpool_md=
+	{
+	NID_whirlpool,
+	0,
+	WHIRLPOOL_DIGEST_LENGTH,
+	0,
+	init,
+	update,
+	final,
+	NULL,
+	NULL,
+	EVP_PKEY_NULL_method,
+	WHIRLPOOL_BBLOCK/8,
+	sizeof(EVP_MD *)+sizeof(WHIRLPOOL_CTX),
+	};
+
+const EVP_MD *EVP_whirlpool(void)
+	{
+	return(&whirlpool_md);
+	}
+#endif
diff --git a/openssl/crypto/evp/names.c b/openssl/crypto/evp/names.c
new file mode 100644
index 0000000..f2869f5
--- /dev/null
+++ b/openssl/crypto/evp/names.c
@@ -0,0 +1,201 @@
+/* crypto/evp/names.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_add_cipher(const EVP_CIPHER *c)
+	{
+	int r;
+
+	r=OBJ_NAME_add(OBJ_nid2sn(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c);
+	if (r == 0) return(0);
+	check_defer(c->nid);
+	r=OBJ_NAME_add(OBJ_nid2ln(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c);
+	return(r);
+	}
+
+
+int EVP_add_digest(const EVP_MD *md)
+	{
+	int r;
+	const char *name;
+
+	name=OBJ_nid2sn(md->type);
+	r=OBJ_NAME_add(name,OBJ_NAME_TYPE_MD_METH,(const char *)md);
+	if (r == 0) return(0);
+	check_defer(md->type);
+	r=OBJ_NAME_add(OBJ_nid2ln(md->type),OBJ_NAME_TYPE_MD_METH,(const char *)md);
+	if (r == 0) return(0);
+
+	if (md->pkey_type && md->type != md->pkey_type)
+		{
+		r=OBJ_NAME_add(OBJ_nid2sn(md->pkey_type),
+			OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name);
+		if (r == 0) return(0);
+		check_defer(md->pkey_type);
+		r=OBJ_NAME_add(OBJ_nid2ln(md->pkey_type),
+			OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name);
+		}
+	return(r);
+	}
+
+const EVP_CIPHER *EVP_get_cipherbyname(const char *name)
+	{
+	const EVP_CIPHER *cp;
+
+	cp=(const EVP_CIPHER *)OBJ_NAME_get(name,OBJ_NAME_TYPE_CIPHER_METH);
+	return(cp);
+	}
+
+const EVP_MD *EVP_get_digestbyname(const char *name)
+	{
+	const EVP_MD *cp;
+
+	cp=(const EVP_MD *)OBJ_NAME_get(name,OBJ_NAME_TYPE_MD_METH);
+	return(cp);
+	}
+
+void EVP_cleanup(void)
+	{
+	OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH);
+	OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH);
+	/* The above calls will only clean out the contents of the name
+	   hash table, but not the hash table itself.  The following line
+	   does that part.  -- Richard Levitte */
+	OBJ_NAME_cleanup(-1);
+
+	EVP_PBE_cleanup();
+	if (obj_cleanup_defer == 2)
+		{
+		obj_cleanup_defer = 0;
+		OBJ_cleanup();
+		}
+	OBJ_sigid_free();
+	}
+
+struct doall_cipher
+	{
+	void *arg;
+	void (*fn)(const EVP_CIPHER *ciph,
+			const char *from, const char *to, void *arg);
+	};
+
+static void do_all_cipher_fn(const OBJ_NAME *nm, void *arg)
+	{
+	struct doall_cipher *dc = arg;
+	if (nm->alias)
+		dc->fn(NULL, nm->name, nm->data, dc->arg);
+	else
+		dc->fn((const EVP_CIPHER *)nm->data, nm->name, NULL, dc->arg);
+	}
+
+void EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph,
+		const char *from, const char *to, void *x), void *arg)
+	{
+	struct doall_cipher dc;
+	dc.fn = fn;
+	dc.arg = arg;
+	OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc);
+	}
+
+void EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph,
+		const char *from, const char *to, void *x), void *arg)
+	{
+	struct doall_cipher dc;
+	dc.fn = fn;
+	dc.arg = arg;
+	OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn,&dc);
+	}
+
+struct doall_md
+	{
+	void *arg;
+	void (*fn)(const EVP_MD *ciph,
+			const char *from, const char *to, void *arg);
+	};
+
+static void do_all_md_fn(const OBJ_NAME *nm, void *arg)
+	{
+	struct doall_md *dc = arg;
+	if (nm->alias)
+		dc->fn(NULL, nm->name, nm->data, dc->arg);
+	else
+		dc->fn((const EVP_MD *)nm->data, nm->name, NULL, dc->arg);
+	}
+
+void EVP_MD_do_all(void (*fn)(const EVP_MD *md,
+		const char *from, const char *to, void *x), void *arg)
+	{
+	struct doall_md dc;
+	dc.fn = fn;
+	dc.arg = arg;
+	OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
+	}
+
+void EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *md,
+		const char *from, const char *to, void *x), void *arg)
+	{
+	struct doall_md dc;
+	dc.fn = fn;
+	dc.arg = arg;
+	OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
+	}
diff --git a/openssl/crypto/evp/openbsd_hw.c b/openssl/crypto/evp/openbsd_hw.c
new file mode 100644
index 0000000..3831a57
--- /dev/null
+++ b/openssl/crypto/evp/openbsd_hw.c
@@ -0,0 +1,446 @@
+/* Written by Ben Laurie, 2001 */
+/*
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/rsa.h>
+#include "evp_locl.h"
+
+/* This stuff should now all be supported through
+ * crypto/engine/hw_openbsd_dev_crypto.c unless I botched it up */
+static void *dummy=&dummy;
+
+#if 0
+
+/* check flag after OpenSSL headers to ensure make depend works */
+#ifdef OPENSSL_OPENBSD_DEV_CRYPTO
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <crypto/cryptodev.h>
+#include <unistd.h>
+#include <assert.h>
+
+/* longest key supported in hardware */
+#define MAX_HW_KEY	24
+#define MAX_HW_IV	8
+
+#define MD5_DIGEST_LENGTH	16
+#define MD5_CBLOCK		64
+
+static int fd;
+static int dev_failed;
+
+typedef struct session_op session_op;
+
+#define CDATA(ctx) EVP_C_DATA(session_op,ctx)
+
+static void err(const char *str)
+    {
+    fprintf(stderr,"%s: errno %d\n",str,errno);
+    }
+
+static int dev_crypto_init(session_op *ses)
+    {
+    if(dev_failed)
+	return 0;
+    if(!fd)
+	{
+	int cryptodev_fd;
+
+        if ((cryptodev_fd=open("/dev/crypto",O_RDWR,0)) < 0)
+	    {
+	    err("/dev/crypto");
+	    dev_failed=1;
+	    return 0;
+	    }
+        if (ioctl(cryptodev_fd,CRIOGET,&fd) == -1)
+	    {
+	    err("CRIOGET failed");
+	    close(cryptodev_fd);
+	    dev_failed=1;
+	    return 0;
+	    }
+	close(cryptodev_fd);
+	}
+    assert(ses);
+    memset(ses,'\0',sizeof *ses);
+
+    return 1;
+    }
+
+static int dev_crypto_cleanup(EVP_CIPHER_CTX *ctx)
+    {
+    if(ioctl(fd,CIOCFSESSION,&CDATA(ctx)->ses) == -1)
+	err("CIOCFSESSION failed");
+
+    OPENSSL_free(CDATA(ctx)->key);
+
+    return 1;
+    }
+
+static int dev_crypto_init_key(EVP_CIPHER_CTX *ctx,int cipher,
+			       const unsigned char *key,int klen)
+    {
+    if(!dev_crypto_init(CDATA(ctx)))
+	return 0;
+
+    CDATA(ctx)->key=OPENSSL_malloc(MAX_HW_KEY);
+
+    assert(ctx->cipher->iv_len <= MAX_HW_IV);
+
+    memcpy(CDATA(ctx)->key,key,klen);
+    
+    CDATA(ctx)->cipher=cipher;
+    CDATA(ctx)->keylen=klen;
+
+    if (ioctl(fd,CIOCGSESSION,CDATA(ctx)) == -1)
+	{
+	err("CIOCGSESSION failed");
+	return 0;
+	}
+    return 1;
+    }
+
+static int dev_crypto_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+			     const unsigned char *in,unsigned int inl)
+    {
+    struct crypt_op cryp;
+    unsigned char lb[MAX_HW_IV];
+
+    if(!inl)
+	return 1;
+
+    assert(CDATA(ctx));
+    assert(!dev_failed);
+
+    memset(&cryp,'\0',sizeof cryp);
+    cryp.ses=CDATA(ctx)->ses;
+    cryp.op=ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
+    cryp.flags=0;
+    cryp.len=inl;
+    assert((inl&(ctx->cipher->block_size-1)) == 0);
+    cryp.src=(caddr_t)in;
+    cryp.dst=(caddr_t)out;
+    cryp.mac=0;
+    if(ctx->cipher->iv_len)
+	cryp.iv=(caddr_t)ctx->iv;
+
+    if(!ctx->encrypt)
+	memcpy(lb,&in[cryp.len-ctx->cipher->iv_len],ctx->cipher->iv_len);
+
+    if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
+	{
+	if(errno == EINVAL) /* buffers are misaligned */
+	    {
+	    unsigned int cinl=0;
+	    char *cin=NULL;
+	    char *cout=NULL;
+
+	    /* NB: this can only make cinl != inl with stream ciphers */
+	    cinl=(inl+3)/4*4;
+
+	    if(((unsigned long)in&3) || cinl != inl)
+		{
+		cin=OPENSSL_malloc(cinl);
+		memcpy(cin,in,inl);
+		cryp.src=cin;
+		}
+
+	    if(((unsigned long)out&3) || cinl != inl)
+		{
+		cout=OPENSSL_malloc(cinl);
+		cryp.dst=cout;
+		}
+
+	    cryp.len=cinl;
+
+	    if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
+		{
+		err("CIOCCRYPT(2) failed");
+		printf("src=%p dst=%p\n",cryp.src,cryp.dst);
+		abort();
+		return 0;
+		}
+		
+	    if(cout)
+		{
+		memcpy(out,cout,inl);
+		OPENSSL_free(cout);
+		}
+	    if(cin)
+		OPENSSL_free(cin);
+	    }
+	else 
+	    {	    
+	    err("CIOCCRYPT failed");
+	    abort();
+	    return 0;
+	    }
+	}
+
+    if(ctx->encrypt)
+	memcpy(ctx->iv,&out[cryp.len-ctx->cipher->iv_len],ctx->cipher->iv_len);
+    else
+	memcpy(ctx->iv,lb,ctx->cipher->iv_len);
+
+    return 1;
+    }
+
+static int dev_crypto_des_ede3_init_key(EVP_CIPHER_CTX *ctx,
+					const unsigned char *key,
+					const unsigned char *iv, int enc)
+    { return dev_crypto_init_key(ctx,CRYPTO_3DES_CBC,key,24); }
+
+#define dev_crypto_des_ede3_cbc_cipher dev_crypto_cipher
+
+BLOCK_CIPHER_def_cbc(dev_crypto_des_ede3, session_op, NID_des_ede3, 8, 24, 8,
+		     0, dev_crypto_des_ede3_init_key,
+		     dev_crypto_cleanup, 
+		     EVP_CIPHER_set_asn1_iv,
+		     EVP_CIPHER_get_asn1_iv,
+		     NULL)
+
+static int dev_crypto_rc4_init_key(EVP_CIPHER_CTX *ctx,
+					const unsigned char *key,
+					const unsigned char *iv, int enc)
+    { return dev_crypto_init_key(ctx,CRYPTO_ARC4,key,16); }
+
+static const EVP_CIPHER r4_cipher=
+    {
+    NID_rc4,
+    1,16,0,	/* FIXME: key should be up to 256 bytes */
+    EVP_CIPH_VARIABLE_LENGTH,
+    dev_crypto_rc4_init_key,
+    dev_crypto_cipher,
+    dev_crypto_cleanup,
+    sizeof(session_op),
+    NULL,
+    NULL,
+    NULL
+    };
+
+const EVP_CIPHER *EVP_dev_crypto_rc4(void)
+    { return &r4_cipher; }
+
+typedef struct
+    {
+    session_op sess;
+    char *data;
+    int len;
+    unsigned char md[EVP_MAX_MD_SIZE];
+    } MD_DATA;
+
+static int dev_crypto_init_digest(MD_DATA *md_data,int mac)
+    {
+    if(!dev_crypto_init(&md_data->sess))
+	return 0;
+
+    md_data->len=0;
+    md_data->data=NULL;
+
+    md_data->sess.mac=mac;
+
+    if (ioctl(fd,CIOCGSESSION,&md_data->sess) == -1)
+	{
+	err("CIOCGSESSION failed");
+	return 0;
+	}
+    return 1;
+    }
+
+static int dev_crypto_cleanup_digest(MD_DATA *md_data)
+    {
+    if (ioctl(fd,CIOCFSESSION,&md_data->sess.ses) == -1)
+	{
+	err("CIOCFSESSION failed");
+	return 0;
+	}
+
+    return 1;
+    }
+
+/* FIXME: if device can do chained MACs, then don't accumulate */
+/* FIXME: move accumulation to the framework */
+static int dev_crypto_md5_init(EVP_MD_CTX *ctx)
+    { return dev_crypto_init_digest(ctx->md_data,CRYPTO_MD5); }
+
+static int do_digest(int ses,unsigned char *md,const void *data,int len)
+    {
+    struct crypt_op cryp;
+    static unsigned char md5zero[16]=
+	{
+	0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,
+	0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,0x7e
+	};
+
+    /* some cards can't do zero length */
+    if(!len)
+	{
+	memcpy(md,md5zero,16);
+	return 1;
+	}
+
+    memset(&cryp,'\0',sizeof cryp);
+    cryp.ses=ses;
+    cryp.op=COP_ENCRYPT;/* required to do the MAC rather than check it */
+    cryp.len=len;
+    cryp.src=(caddr_t)data;
+    cryp.dst=(caddr_t)data; // FIXME!!!
+    cryp.mac=(caddr_t)md;
+
+    if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
+	{
+	if(errno == EINVAL) /* buffer is misaligned */
+	    {
+	    char *dcopy;
+
+	    dcopy=OPENSSL_malloc(len);
+	    memcpy(dcopy,data,len);
+	    cryp.src=dcopy;
+	    cryp.dst=cryp.src; // FIXME!!!
+
+	    if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
+		{
+		err("CIOCCRYPT(MAC2) failed");
+		abort();
+		return 0;
+		}
+	    OPENSSL_free(dcopy);
+	    }
+	else
+	    {
+	    err("CIOCCRYPT(MAC) failed");
+	    abort();
+	    return 0;
+	    }
+	}
+    //    printf("done\n");
+
+    return 1;
+    }
+
+static int dev_crypto_md5_update(EVP_MD_CTX *ctx,const void *data,
+				 unsigned long len)
+    {
+    MD_DATA *md_data=ctx->md_data;
+
+    if(ctx->flags&EVP_MD_CTX_FLAG_ONESHOT)
+	return do_digest(md_data->sess.ses,md_data->md,data,len);
+
+    md_data->data=OPENSSL_realloc(md_data->data,md_data->len+len);
+    memcpy(md_data->data+md_data->len,data,len);
+    md_data->len+=len;
+
+    return 1;
+    }	
+
+static int dev_crypto_md5_final(EVP_MD_CTX *ctx,unsigned char *md)
+    {
+    int ret;
+    MD_DATA *md_data=ctx->md_data;
+
+    if(ctx->flags&EVP_MD_CTX_FLAG_ONESHOT)
+	{
+	memcpy(md,md_data->md,MD5_DIGEST_LENGTH);
+	ret=1;
+	}
+    else
+	{
+	ret=do_digest(md_data->sess.ses,md,md_data->data,md_data->len);
+	OPENSSL_free(md_data->data);
+	md_data->data=NULL;
+	md_data->len=0;
+	}
+
+    return ret;
+    }
+
+static int dev_crypto_md5_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
+    {
+    const MD_DATA *from_md=from->md_data;
+    MD_DATA *to_md=to->md_data;
+
+    // How do we copy sessions?
+    assert(from->digest->flags&EVP_MD_FLAG_ONESHOT);
+
+    to_md->data=OPENSSL_malloc(from_md->len);
+    memcpy(to_md->data,from_md->data,from_md->len);
+
+    return 1;
+    }
+
+static int dev_crypto_md5_cleanup(EVP_MD_CTX *ctx)
+    {
+    return dev_crypto_cleanup_digest(ctx->md_data);
+    }
+
+static const EVP_MD md5_md=
+    {
+    NID_md5,
+    NID_md5WithRSAEncryption,
+    MD5_DIGEST_LENGTH,
+    EVP_MD_FLAG_ONESHOT,	// XXX: set according to device info...
+    dev_crypto_md5_init,
+    dev_crypto_md5_update,
+    dev_crypto_md5_final,
+    dev_crypto_md5_copy,
+    dev_crypto_md5_cleanup,
+    EVP_PKEY_RSA_method,
+    MD5_CBLOCK,
+    sizeof(MD_DATA),
+    };
+
+const EVP_MD *EVP_dev_crypto_md5(void)
+    { return &md5_md; }
+
+#endif
+#endif
diff --git a/openssl/crypto/evp/p5_crpt.c b/openssl/crypto/evp/p5_crpt.c
new file mode 100644
index 0000000..7ecfa8d
--- /dev/null
+++ b/openssl/crypto/evp/p5_crpt.c
@@ -0,0 +1,132 @@
+/* p5_crpt.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/evp.h>
+
+/* Doesn't do anything now: Builtin PBE algorithms in static table.
+ */
+
+void PKCS5_PBE_add(void)
+{
+}
+
+int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
+			 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md,
+			 int en_de)
+{
+	EVP_MD_CTX ctx;
+	unsigned char md_tmp[EVP_MAX_MD_SIZE];
+	unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
+	int i;
+	PBEPARAM *pbe;
+	int saltlen, iter;
+	unsigned char *salt;
+	const unsigned char *pbuf;
+	int mdsize;
+
+	/* Extract useful info from parameter */
+	if (param == NULL || param->type != V_ASN1_SEQUENCE ||
+	    param->value.sequence == NULL) {
+		EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
+		return 0;
+	}
+
+	pbuf = param->value.sequence->data;
+	if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) {
+		EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
+		return 0;
+	}
+
+	if (!pbe->iter) iter = 1;
+	else iter = ASN1_INTEGER_get (pbe->iter);
+	salt = pbe->salt->data;
+	saltlen = pbe->salt->length;
+
+	if(!pass) passlen = 0;
+	else if(passlen == -1) passlen = strlen(pass);
+
+	EVP_MD_CTX_init(&ctx);
+	EVP_DigestInit_ex(&ctx, md, NULL);
+	EVP_DigestUpdate(&ctx, pass, passlen);
+	EVP_DigestUpdate(&ctx, salt, saltlen);
+	PBEPARAM_free(pbe);
+	EVP_DigestFinal_ex(&ctx, md_tmp, NULL);
+	mdsize = EVP_MD_size(md);
+	if (mdsize < 0)
+	    return 0;
+	for (i = 1; i < iter; i++) {
+		EVP_DigestInit_ex(&ctx, md, NULL);
+		EVP_DigestUpdate(&ctx, md_tmp, mdsize);
+		EVP_DigestFinal_ex (&ctx, md_tmp, NULL);
+	}
+	EVP_MD_CTX_cleanup(&ctx);
+	OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp));
+	memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher));
+	OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16);
+	memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)),
+						 EVP_CIPHER_iv_length(cipher));
+	EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de);
+	OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE);
+	OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
+	OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
+	return 1;
+}
diff --git a/openssl/crypto/evp/p5_crpt2.c b/openssl/crypto/evp/p5_crpt2.c
new file mode 100644
index 0000000..334379f
--- /dev/null
+++ b/openssl/crypto/evp/p5_crpt2.c
@@ -0,0 +1,299 @@
+/* p5_crpt2.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#if !defined(OPENSSL_NO_HMAC) && !defined(OPENSSL_NO_SHA)
+#include <openssl/x509.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+
+/* set this to print out info about the keygen algorithm */
+/* #define DEBUG_PKCS5V2 */
+
+#ifdef DEBUG_PKCS5V2
+	static void h__dump (const unsigned char *p, int len);
+#endif
+
+/* This is an implementation of PKCS#5 v2.0 password based encryption key
+ * derivation function PBKDF2.
+ * SHA1 version verified against test vectors posted by Peter Gutmann
+ * <pgut001@cs.auckland.ac.nz> to the PKCS-TNG <pkcs-tng@rsa.com> mailing list.
+ */
+
+int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
+			   const unsigned char *salt, int saltlen, int iter,
+			   const EVP_MD *digest,
+			   int keylen, unsigned char *out)
+	{
+	unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
+	int cplen, j, k, tkeylen, mdlen;
+	unsigned long i = 1;
+	HMAC_CTX hctx;
+
+	mdlen = EVP_MD_size(digest);
+	if (mdlen < 0)
+		return 0;
+
+	HMAC_CTX_init(&hctx);
+	p = out;
+	tkeylen = keylen;
+	if(!pass)
+		passlen = 0;
+	else if(passlen == -1)
+		passlen = strlen(pass);
+	while(tkeylen)
+		{
+		if(tkeylen > mdlen)
+			cplen = mdlen;
+		else
+			cplen = tkeylen;
+		/* We are unlikely to ever use more than 256 blocks (5120 bits!)
+		 * but just in case...
+		 */
+		itmp[0] = (unsigned char)((i >> 24) & 0xff);
+		itmp[1] = (unsigned char)((i >> 16) & 0xff);
+		itmp[2] = (unsigned char)((i >> 8) & 0xff);
+		itmp[3] = (unsigned char)(i & 0xff);
+		HMAC_Init_ex(&hctx, pass, passlen, digest, NULL);
+		HMAC_Update(&hctx, salt, saltlen);
+		HMAC_Update(&hctx, itmp, 4);
+		HMAC_Final(&hctx, digtmp, NULL);
+		memcpy(p, digtmp, cplen);
+		for(j = 1; j < iter; j++)
+			{
+			HMAC(digest, pass, passlen,
+				 digtmp, mdlen, digtmp, NULL);
+			for(k = 0; k < cplen; k++)
+				p[k] ^= digtmp[k];
+			}
+		tkeylen-= cplen;
+		i++;
+		p+= cplen;
+		}
+	HMAC_CTX_cleanup(&hctx);
+#ifdef DEBUG_PKCS5V2
+	fprintf(stderr, "Password:\n");
+	h__dump (pass, passlen);
+	fprintf(stderr, "Salt:\n");
+	h__dump (salt, saltlen);
+	fprintf(stderr, "Iteration count %d\n", iter);
+	fprintf(stderr, "Key:\n");
+	h__dump (out, keylen);
+#endif
+	return 1;
+	}
+
+int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
+			   const unsigned char *salt, int saltlen, int iter,
+			   int keylen, unsigned char *out)
+	{
+	return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(),
+					keylen, out);
+	}
+
+#ifdef DO_TEST
+main()
+{
+	unsigned char out[4];
+	unsigned char salt[] = {0x12, 0x34, 0x56, 0x78};
+	PKCS5_PBKDF2_HMAC_SHA1("password", -1, salt, 4, 5, 4, out);
+	fprintf(stderr, "Out %02X %02X %02X %02X\n",
+					 out[0], out[1], out[2], out[3]);
+}
+
+#endif
+
+/* Now the key derivation function itself. This is a bit evil because
+ * it has to check the ASN1 parameters are valid: and there are quite a
+ * few of them...
+ */
+
+int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+                         ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md,
+                         int en_de)
+{
+	unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
+	const unsigned char *pbuf;
+	int saltlen, iter, plen;
+	unsigned int keylen;
+	PBE2PARAM *pbe2 = NULL;
+	const EVP_CIPHER *cipher;
+	PBKDF2PARAM *kdf = NULL;
+	const EVP_MD *prfmd;
+	int prf_nid, hmac_md_nid;
+
+	if (param == NULL || param->type != V_ASN1_SEQUENCE ||
+	    param->value.sequence == NULL) {
+		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
+		return 0;
+	}
+
+	pbuf = param->value.sequence->data;
+	plen = param->value.sequence->length;
+	if(!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) {
+		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
+		return 0;
+	}
+
+	/* See if we recognise the key derivation function */
+
+	if(OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) {
+		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
+				EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION);
+		goto err;
+	}
+
+	/* lets see if we recognise the encryption algorithm.
+	 */
+
+	cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm);
+
+	if(!cipher) {
+		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
+						EVP_R_UNSUPPORTED_CIPHER);
+		goto err;
+	}
+
+	/* Fixup cipher based on AlgorithmIdentifier */
+	EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de);
+	if(EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) {
+		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
+					EVP_R_CIPHER_PARAMETER_ERROR);
+		goto err;
+	}
+	keylen = EVP_CIPHER_CTX_key_length(ctx);
+	OPENSSL_assert(keylen <= sizeof key);
+
+	/* Now decode key derivation function */
+
+	if(!pbe2->keyfunc->parameter ||
+		 (pbe2->keyfunc->parameter->type != V_ASN1_SEQUENCE))
+		{
+		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
+		goto err;
+		}
+
+	pbuf = pbe2->keyfunc->parameter->value.sequence->data;
+	plen = pbe2->keyfunc->parameter->value.sequence->length;
+	if(!(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen)) ) {
+		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
+		goto err;
+	}
+
+	PBE2PARAM_free(pbe2);
+	pbe2 = NULL;
+
+	/* Now check the parameters of the kdf */
+
+	if(kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)){
+		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
+						EVP_R_UNSUPPORTED_KEYLENGTH);
+		goto err;
+	}
+
+	if (kdf->prf)
+		prf_nid = OBJ_obj2nid(kdf->prf->algorithm);
+	else
+		prf_nid = NID_hmacWithSHA1;
+
+	if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0))
+		{
+		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
+		goto err;
+		}
+
+	prfmd = EVP_get_digestbynid(hmac_md_nid);
+	if (prfmd == NULL)
+		{
+		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
+		goto err;
+		}
+
+	if(kdf->salt->type != V_ASN1_OCTET_STRING) {
+		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
+						EVP_R_UNSUPPORTED_SALT_TYPE);
+		goto err;
+	}
+
+	/* it seems that its all OK */
+	salt = kdf->salt->value.octet_string->data;
+	saltlen = kdf->salt->value.octet_string->length;
+	iter = ASN1_INTEGER_get(kdf->iter);
+	if(!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,
+						   keylen, key))
+		goto err;
+	EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
+	OPENSSL_cleanse(key, keylen);
+	PBKDF2PARAM_free(kdf);
+	return 1;
+
+	err:
+	PBE2PARAM_free(pbe2);
+	PBKDF2PARAM_free(kdf);
+	return 0;
+}
+
+#ifdef DEBUG_PKCS5V2
+static void h__dump (const unsigned char *p, int len)
+{
+        for (; len --; p++) fprintf(stderr, "%02X ", *p);
+        fprintf(stderr, "\n");
+}
+#endif
+#endif
diff --git a/openssl/crypto/evp/p_dec.c b/openssl/crypto/evp/p_dec.c
new file mode 100644
index 0000000..4201dcb
--- /dev/null
+++ b/openssl/crypto/evp/p_dec.c
@@ -0,0 +1,87 @@
+/* crypto/evp/p_dec.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl,
+	     EVP_PKEY *priv)
+	{
+	int ret= -1;
+	
+#ifndef OPENSSL_NO_RSA
+	if (priv->type != EVP_PKEY_RSA)
+		{
+#endif
+		EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD,EVP_R_PUBLIC_KEY_NOT_RSA);
+#ifndef OPENSSL_NO_RSA
+		goto err;
+                }
+
+	ret=RSA_private_decrypt(ekl,ek,key,priv->pkey.rsa,RSA_PKCS1_PADDING);
+err:
+#endif
+	return(ret);
+	}
diff --git a/openssl/crypto/evp/p_enc.c b/openssl/crypto/evp/p_enc.c
new file mode 100644
index 0000000..b5a3a84
--- /dev/null
+++ b/openssl/crypto/evp/p_enc.c
@@ -0,0 +1,86 @@
+/* crypto/evp/p_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key, int key_len,
+	     EVP_PKEY *pubk)
+	{
+	int ret=0;
+	
+#ifndef OPENSSL_NO_RSA
+	if (pubk->type != EVP_PKEY_RSA)
+		{
+#endif
+		EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD,EVP_R_PUBLIC_KEY_NOT_RSA);
+#ifndef OPENSSL_NO_RSA
+		goto err;
+		}
+	ret=RSA_public_encrypt(key_len,key,ek,pubk->pkey.rsa,RSA_PKCS1_PADDING);
+err:
+#endif
+	return(ret);
+	}
diff --git a/openssl/crypto/evp/p_lib.c b/openssl/crypto/evp/p_lib.c
new file mode 100644
index 0000000..e26ccd0
--- /dev/null
+++ b/openssl/crypto/evp/p_lib.c
@@ -0,0 +1,469 @@
+/* crypto/evp/p_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/asn1_mac.h>
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+#include "asn1_locl.h"
+
+static void EVP_PKEY_free_it(EVP_PKEY *x);
+
+int EVP_PKEY_bits(EVP_PKEY *pkey)
+	{
+	if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
+		return pkey->ameth->pkey_bits(pkey);
+	return 0;
+	}
+
+int EVP_PKEY_size(EVP_PKEY *pkey)
+	{
+	if (pkey && pkey->ameth && pkey->ameth->pkey_size)
+		return pkey->ameth->pkey_size(pkey);
+	return 0;
+	}
+
+int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
+	{
+#ifndef OPENSSL_NO_DSA
+	if (pkey->type == EVP_PKEY_DSA)
+		{
+		int ret=pkey->save_parameters;
+
+		if (mode >= 0)
+			pkey->save_parameters=mode;
+		return(ret);
+		}
+#endif
+#ifndef OPENSSL_NO_EC
+	if (pkey->type == EVP_PKEY_EC)
+		{
+		int ret = pkey->save_parameters;
+
+		if (mode >= 0)
+			pkey->save_parameters = mode;
+		return(ret);
+		}
+#endif
+	return(0);
+	}
+
+int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+	{
+	if (to->type != from->type)
+		{
+		EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_DIFFERENT_KEY_TYPES);
+		goto err;
+		}
+
+	if (EVP_PKEY_missing_parameters(from))
+		{
+		EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_MISSING_PARAMETERS);
+		goto err;
+		}
+	if (from->ameth && from->ameth->param_copy)
+		return from->ameth->param_copy(to, from);
+err:
+	return 0;
+	}
+
+int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
+	{
+	if (pkey->ameth && pkey->ameth->param_missing)
+		return pkey->ameth->param_missing(pkey);
+	return 0;
+	}
+
+int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+	{
+	if (a->type != b->type)
+		return -1;
+	if (a->ameth && a->ameth->param_cmp)
+		return a->ameth->param_cmp(a, b);
+	return -2;
+	}
+
+int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+	{
+	if (a->type != b->type)
+		return -1;
+
+	if (a->ameth)
+		{
+		int ret;
+		/* Compare parameters if the algorithm has them */
+		if (a->ameth->param_cmp)
+			{
+			ret = a->ameth->param_cmp(a, b);
+			if (ret <= 0)
+				return ret;
+			}
+
+		if (a->ameth->pub_cmp)
+			return a->ameth->pub_cmp(a, b);
+		}
+
+	return -2;
+	}
+
+EVP_PKEY *EVP_PKEY_new(void)
+	{
+	EVP_PKEY *ret;
+
+	ret=(EVP_PKEY *)OPENSSL_malloc(sizeof(EVP_PKEY));
+	if (ret == NULL)
+		{
+		EVPerr(EVP_F_EVP_PKEY_NEW,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	ret->type=EVP_PKEY_NONE;
+	ret->save_type=EVP_PKEY_NONE;
+	ret->references=1;
+	ret->ameth=NULL;
+	ret->engine=NULL;
+	ret->pkey.ptr=NULL;
+	ret->attributes=NULL;
+	ret->save_parameters=1;
+	return(ret);
+	}
+
+/* Setup a public key ASN1 method and ENGINE from a NID or a string.
+ * If pkey is NULL just return 1 or 0 if the algorithm exists.
+ */
+
+static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
+	{
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	ENGINE *e = NULL;
+	if (pkey)
+		{
+		if (pkey->pkey.ptr)
+			EVP_PKEY_free_it(pkey);
+		/* If key type matches and a method exists then this
+		 * lookup has succeeded once so just indicate success.
+		 */
+		if ((type == pkey->save_type) && pkey->ameth)
+			return 1;
+#ifndef OPENSSL_NO_ENGINE
+		/* If we have an ENGINE release it */
+		if (pkey->engine)
+			{
+			ENGINE_finish(pkey->engine);
+			pkey->engine = NULL;
+			}
+#endif
+		}
+	if (str)
+		ameth = EVP_PKEY_asn1_find_str(&e, str, len);
+	else
+		ameth = EVP_PKEY_asn1_find(&e, type);
+#ifndef OPENSSL_NO_ENGINE
+	if (!pkey && e)
+		ENGINE_finish(e);
+#endif
+	if (!ameth)
+		{
+		EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
+		return 0;
+		}
+	if (pkey)
+		{
+		pkey->ameth = ameth;
+		pkey->engine = e;
+
+		pkey->type = pkey->ameth->pkey_id;
+		pkey->save_type=type;
+		}
+	return 1;
+	}
+
+int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
+	{
+	return pkey_set_type(pkey, type, NULL, -1);
+	}
+
+int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
+	{
+	return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
+	}
+
+int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
+	{
+	if (!EVP_PKEY_set_type(pkey, type))
+		return 0;
+	pkey->pkey.ptr=key;
+	return (key != NULL);
+	}
+
+void *EVP_PKEY_get0(EVP_PKEY *pkey)
+	{
+	return pkey->pkey.ptr;
+	}
+
+#ifndef OPENSSL_NO_RSA
+int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
+{
+	int ret = EVP_PKEY_assign_RSA(pkey, key);
+	if(ret)
+		RSA_up_ref(key);
+	return ret;
+}
+
+RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
+	{
+	if(pkey->type != EVP_PKEY_RSA) {
+		EVPerr(EVP_F_EVP_PKEY_GET1_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
+		return NULL;
+	}
+	RSA_up_ref(pkey->pkey.rsa);
+	return pkey->pkey.rsa;
+}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
+{
+	int ret = EVP_PKEY_assign_DSA(pkey, key);
+	if(ret)
+		DSA_up_ref(key);
+	return ret;
+}
+
+DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
+	{
+	if(pkey->type != EVP_PKEY_DSA) {
+		EVPerr(EVP_F_EVP_PKEY_GET1_DSA, EVP_R_EXPECTING_A_DSA_KEY);
+		return NULL;
+	}
+	DSA_up_ref(pkey->pkey.dsa);
+	return pkey->pkey.dsa;
+}
+#endif
+
+#ifndef OPENSSL_NO_EC
+
+int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
+{
+	int ret = EVP_PKEY_assign_EC_KEY(pkey,key);
+	if (ret)
+		EC_KEY_up_ref(key);
+	return ret;
+}
+
+EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
+{
+	if (pkey->type != EVP_PKEY_EC)
+	{
+		EVPerr(EVP_F_EVP_PKEY_GET1_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
+		return NULL;
+	}
+	EC_KEY_up_ref(pkey->pkey.ec);
+	return pkey->pkey.ec;
+}
+#endif
+
+
+#ifndef OPENSSL_NO_DH
+
+int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
+{
+	int ret = EVP_PKEY_assign_DH(pkey, key);
+	if(ret)
+		DH_up_ref(key);
+	return ret;
+}
+
+DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
+	{
+	if(pkey->type != EVP_PKEY_DH) {
+		EVPerr(EVP_F_EVP_PKEY_GET1_DH, EVP_R_EXPECTING_A_DH_KEY);
+		return NULL;
+	}
+	DH_up_ref(pkey->pkey.dh);
+	return pkey->pkey.dh;
+}
+#endif
+
+int EVP_PKEY_type(int type)
+	{
+	int ret;
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	ENGINE *e;
+	ameth = EVP_PKEY_asn1_find(&e, type);
+	if (ameth)
+		ret = ameth->pkey_id;
+	else
+		ret = NID_undef;
+#ifndef OPENSSL_NO_ENGINE
+	if (e)
+		ENGINE_finish(e);
+#endif
+	return ret;
+	}
+
+int EVP_PKEY_id(const EVP_PKEY *pkey)
+	{
+	return pkey->type;
+	}
+
+int EVP_PKEY_base_id(const EVP_PKEY *pkey)
+	{
+	return EVP_PKEY_type(pkey->type);
+	}
+
+void EVP_PKEY_free(EVP_PKEY *x)
+	{
+	int i;
+
+	if (x == NULL) return;
+
+	i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_EVP_PKEY);
+#ifdef REF_PRINT
+	REF_PRINT("EVP_PKEY",x);
+#endif
+	if (i > 0) return;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"EVP_PKEY_free, bad reference count\n");
+		abort();
+		}
+#endif
+	EVP_PKEY_free_it(x);
+	if (x->attributes)
+		sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
+	OPENSSL_free(x);
+	}
+
+static void EVP_PKEY_free_it(EVP_PKEY *x)
+	{
+	if (x->ameth && x->ameth->pkey_free)
+		{
+		x->ameth->pkey_free(x);
+		x->pkey.ptr = NULL;
+		}
+#ifndef OPENSSL_NO_ENGINE
+	if (x->engine)
+		{
+		ENGINE_finish(x->engine);
+		x->engine = NULL;
+		}
+#endif
+	}
+
+static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
+				const char *kstr)
+	{
+	BIO_indent(out, indent, 128);
+	BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
+						kstr, OBJ_nid2ln(pkey->type));
+	return 1;
+	}
+
+int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx)
+	{
+	if (pkey->ameth && pkey->ameth->pub_print)
+		return pkey->ameth->pub_print(out, pkey, indent, pctx);
+	
+	return unsup_alg(out, pkey, indent, "Public Key");
+	}
+
+int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx)
+	{
+	if (pkey->ameth && pkey->ameth->priv_print)
+		return pkey->ameth->priv_print(out, pkey, indent, pctx);
+	
+	return unsup_alg(out, pkey, indent, "Private Key");
+	}
+
+int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx)
+	{
+	if (pkey->ameth && pkey->ameth->param_print)
+		return pkey->ameth->param_print(out, pkey, indent, pctx);
+	return unsup_alg(out, pkey, indent, "Parameters");
+	}
+
+int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
+	{
+	if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
+		return -2;
+	return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
+						0, pnid);
+	}
+
diff --git a/openssl/crypto/evp/p_open.c b/openssl/crypto/evp/p_open.c
new file mode 100644
index 0000000..53a59a2
--- /dev/null
+++ b/openssl/crypto/evp/p_open.c
@@ -0,0 +1,127 @@
+/* crypto/evp/p_open.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_RSA
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/rsa.h>
+
+int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+	const unsigned char *ek, int ekl, const unsigned char *iv,
+	EVP_PKEY *priv)
+	{
+	unsigned char *key=NULL;
+	int i,size=0,ret=0;
+
+	if(type) {	
+		EVP_CIPHER_CTX_init(ctx);
+		if(!EVP_DecryptInit_ex(ctx,type,NULL, NULL,NULL)) return 0;
+	}
+
+	if(!priv) return 1;
+
+	if (priv->type != EVP_PKEY_RSA)
+		{
+		EVPerr(EVP_F_EVP_OPENINIT,EVP_R_PUBLIC_KEY_NOT_RSA);
+		goto err;
+                }
+
+	size=RSA_size(priv->pkey.rsa);
+	key=(unsigned char *)OPENSSL_malloc(size+2);
+	if (key == NULL)
+		{
+		/* ERROR */
+		EVPerr(EVP_F_EVP_OPENINIT,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	i=EVP_PKEY_decrypt_old(key,ek,ekl,priv);
+	if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i))
+		{
+		/* ERROR */
+		goto err;
+		}
+	if(!EVP_DecryptInit_ex(ctx,NULL,NULL,key,iv)) goto err;
+
+	ret=1;
+err:
+	if (key != NULL) OPENSSL_cleanse(key,size);
+	OPENSSL_free(key);
+	return(ret);
+	}
+
+int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+	{
+	int i;
+
+	i=EVP_DecryptFinal_ex(ctx,out,outl);
+	EVP_DecryptInit_ex(ctx,NULL,NULL,NULL,NULL);
+	return(i);
+	}
+#else /* !OPENSSL_NO_RSA */
+
+# ifdef PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/crypto/evp/p_seal.c b/openssl/crypto/evp/p_seal.c
new file mode 100644
index 0000000..d832452
--- /dev/null
+++ b/openssl/crypto/evp/p_seal.c
@@ -0,0 +1,115 @@
+/* crypto/evp/p_seal.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char **ek,
+	     int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk)
+	{
+	unsigned char key[EVP_MAX_KEY_LENGTH];
+	int i;
+	
+	if(type) {
+		EVP_CIPHER_CTX_init(ctx);
+		if(!EVP_EncryptInit_ex(ctx,type,NULL,NULL,NULL)) return 0;
+	}
+	if ((npubk <= 0) || !pubk)
+		return 1;
+	if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
+		return 0;
+	if (EVP_CIPHER_CTX_iv_length(ctx))
+		RAND_pseudo_bytes(iv,EVP_CIPHER_CTX_iv_length(ctx));
+
+	if(!EVP_EncryptInit_ex(ctx,NULL,NULL,key,iv)) return 0;
+
+	for (i=0; i<npubk; i++)
+		{
+		ekl[i]=EVP_PKEY_encrypt_old(ek[i],key,EVP_CIPHER_CTX_key_length(ctx),
+			pubk[i]);
+		if (ekl[i] <= 0) return(-1);
+		}
+	return(npubk);
+	}
+
+/* MACRO
+void EVP_SealUpdate(ctx,out,outl,in,inl)
+EVP_CIPHER_CTX *ctx;
+unsigned char *out;
+int *outl;
+unsigned char *in;
+int inl;
+	{
+	EVP_EncryptUpdate(ctx,out,outl,in,inl);
+	}
+*/
+
+int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+	{
+	int i;
+	i = EVP_EncryptFinal_ex(ctx,out,outl);
+	EVP_EncryptInit_ex(ctx,NULL,NULL,NULL,NULL);
+	return i;
+	}
diff --git a/openssl/crypto/evp/p_sign.c b/openssl/crypto/evp/p_sign.c
new file mode 100644
index 0000000..bb893f5
--- /dev/null
+++ b/openssl/crypto/evp/p_sign.c
@@ -0,0 +1,137 @@
+/* crypto/evp/p_sign.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+#ifdef undef
+void EVP_SignInit(EVP_MD_CTX *ctx, EVP_MD *type)
+	{
+	EVP_DigestInit_ex(ctx,type);
+	}
+
+void EVP_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data,
+	     unsigned int count)
+	{
+	EVP_DigestUpdate(ctx,data,count);
+	}
+#endif
+
+int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
+	     EVP_PKEY *pkey)
+	{
+	unsigned char m[EVP_MAX_MD_SIZE];
+	unsigned int m_len;
+	int i,ok=0,v;
+	EVP_MD_CTX tmp_ctx;
+
+	*siglen=0;
+	EVP_MD_CTX_init(&tmp_ctx);
+	EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);   
+	EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
+	EVP_MD_CTX_cleanup(&tmp_ctx);
+
+	if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
+		{
+		EVP_PKEY_CTX *pkctx = NULL;
+		size_t sltmp = (size_t)EVP_PKEY_size(pkey);
+		i = 0;
+		pkctx = EVP_PKEY_CTX_new(pkey, NULL);
+		if (!pkctx)
+			goto err;
+		if (EVP_PKEY_sign_init(pkctx) <= 0)
+			goto err;
+		if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
+			goto err;
+		if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0)
+			goto err;
+		*siglen = sltmp;
+		i = 1;
+		err:
+		EVP_PKEY_CTX_free(pkctx);
+		return i;
+		}
+
+	for (i=0; i<4; i++)
+		{
+		v=ctx->digest->required_pkey_type[i];
+		if (v == 0) break;
+		if (pkey->type == v)
+			{
+			ok=1;
+			break;
+			}
+		}
+	if (!ok)
+		{
+		EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE);
+		return(0);
+		}
+
+	if (ctx->digest->sign == NULL)
+		{
+		EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_NO_SIGN_FUNCTION_CONFIGURED);
+		return(0);
+		}
+	return(ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen,
+		pkey->pkey.ptr));
+	}
+
diff --git a/openssl/crypto/evp/p_verify.c b/openssl/crypto/evp/p_verify.c
new file mode 100644
index 0000000..41d4b67
--- /dev/null
+++ b/openssl/crypto/evp/p_verify.c
@@ -0,0 +1,119 @@
+/* crypto/evp/p_verify.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
+	     unsigned int siglen, EVP_PKEY *pkey)
+	{
+	unsigned char m[EVP_MAX_MD_SIZE];
+	unsigned int m_len;
+	int i,ok=0,v;
+	EVP_MD_CTX tmp_ctx;
+
+	EVP_MD_CTX_init(&tmp_ctx);
+	EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);     
+	EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
+	EVP_MD_CTX_cleanup(&tmp_ctx);
+
+	if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
+		{
+		EVP_PKEY_CTX *pkctx = NULL;
+		i = -1;
+		pkctx = EVP_PKEY_CTX_new(pkey, NULL);
+		if (!pkctx)
+			goto err;
+		if (EVP_PKEY_verify_init(pkctx) <= 0)
+			goto err;
+		if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
+			goto err;
+		i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len);
+		err:
+		EVP_PKEY_CTX_free(pkctx);
+		return i;
+		}
+
+	for (i=0; i<4; i++)
+		{
+		v=ctx->digest->required_pkey_type[i];
+		if (v == 0) break;
+		if (pkey->type == v)
+			{
+			ok=1;
+			break;
+			}
+		}
+	if (!ok)
+		{
+		EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE);
+		return(-1);
+		}
+        if (ctx->digest->verify == NULL)
+                {
+		EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_NO_VERIFY_FUNCTION_CONFIGURED);
+		return(0);
+		}
+
+	return(ctx->digest->verify(ctx->digest->type,m,m_len,
+		sigbuf,siglen,pkey->pkey.ptr));
+	}
+
diff --git a/openssl/crypto/evp/pmeth_fn.c b/openssl/crypto/evp/pmeth_fn.c
new file mode 100644
index 0000000..c4676f2
--- /dev/null
+++ b/openssl/crypto/evp/pmeth_fn.c
@@ -0,0 +1,368 @@
+/* pmeth_fn.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include "evp_locl.h"
+
+#define M_check_autoarg(ctx, arg, arglen, err) \
+	if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \
+		{ \
+		size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
+		if (!arg) \
+			{ \
+			*arglen = pksize; \
+			return 1; \
+			} \
+		else if (*arglen < pksize) \
+			{ \
+			EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\
+			return 0; \
+			} \
+		}
+
+int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
+		{
+		EVPerr(EVP_F_EVP_PKEY_SIGN_INIT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	ctx->operation = EVP_PKEY_OP_SIGN;
+	if (!ctx->pmeth->sign_init)
+		return 1;
+	ret = ctx->pmeth->sign_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+	}
+
+int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
+			unsigned char *sig, size_t *siglen,
+			const unsigned char *tbs, size_t tbslen)
+	{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
+		{
+		EVPerr(EVP_F_EVP_PKEY_SIGN,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	if (ctx->operation != EVP_PKEY_OP_SIGN)
+		{
+		EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+	M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
+	return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
+	}
+
+int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
+		{
+		EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	ctx->operation = EVP_PKEY_OP_VERIFY;
+	if (!ctx->pmeth->verify_init)
+		return 1;
+	ret = ctx->pmeth->verify_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+	}
+
+int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
+			const unsigned char *sig, size_t siglen,
+			const unsigned char *tbs, size_t tbslen)
+	{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
+		{
+		EVPerr(EVP_F_EVP_PKEY_VERIFY,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	if (ctx->operation != EVP_PKEY_OP_VERIFY)
+		{
+		EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+	return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
+	}
+
+int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
+		{
+		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
+	if (!ctx->pmeth->verify_recover_init)
+		return 1;
+	ret = ctx->pmeth->verify_recover_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+	}
+
+int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
+			unsigned char *rout, size_t *routlen,
+			const unsigned char *sig, size_t siglen)
+	{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
+		{
+		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER)
+		{
+		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+	M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
+	return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
+	}
+
+int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
+		{
+		EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	ctx->operation = EVP_PKEY_OP_ENCRYPT;
+	if (!ctx->pmeth->encrypt_init)
+		return 1;
+	ret = ctx->pmeth->encrypt_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+	}
+
+int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
+			unsigned char *out, size_t *outlen,
+			const unsigned char *in, size_t inlen)
+	{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
+		{
+		EVPerr(EVP_F_EVP_PKEY_ENCRYPT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	if (ctx->operation != EVP_PKEY_OP_ENCRYPT)
+		{
+		EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
+	return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
+	}
+
+int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	ctx->operation = EVP_PKEY_OP_DECRYPT;
+	if (!ctx->pmeth->decrypt_init)
+		return 1;
+	ret = ctx->pmeth->decrypt_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+	}
+
+int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
+			unsigned char *out, size_t *outlen,
+			const unsigned char *in, size_t inlen)
+	{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DECRYPT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	if (ctx->operation != EVP_PKEY_OP_DECRYPT)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
+	return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
+	}
+
+
+int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	ctx->operation = EVP_PKEY_OP_DERIVE;
+	if (!ctx->pmeth->derive_init)
+		return 1;
+	ret = ctx->pmeth->derive_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+	}
+
+int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive||ctx->pmeth->encrypt||ctx->pmeth->decrypt) || !ctx->pmeth->ctrl)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	if (ctx->operation != EVP_PKEY_OP_DERIVE && ctx->operation != EVP_PKEY_OP_ENCRYPT && ctx->operation != EVP_PKEY_OP_DECRYPT)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
+					EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+
+	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
+
+	if (ret <= 0)
+		return ret;
+
+	if (ret == 2)
+		return 1;
+
+	if (!ctx->pkey)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
+		return -1;
+		}
+
+	if (ctx->pkey->type != peer->type)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
+						EVP_R_DIFFERENT_KEY_TYPES);
+		return -1;
+		}
+
+	/* ran@cryptocom.ru: For clarity.  The error is if parameters in peer are
+	 * present (!missing) but don't match.  EVP_PKEY_cmp_parameters may return
+	 * 1 (match), 0 (don't match) and -2 (comparison is not defined).  -1
+	 * (different key types) is impossible here because it is checked earlier.
+	 * -2 is OK for us here, as well as 1, so we can check for 0 only. */
+	if (!EVP_PKEY_missing_parameters(peer) &&
+		!EVP_PKEY_cmp_parameters(ctx->pkey, peer))
+		{
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
+						EVP_R_DIFFERENT_PARAMETERS);
+		return -1;
+		}
+
+	if (ctx->peerkey)
+		EVP_PKEY_free(ctx->peerkey);
+	ctx->peerkey = peer;
+
+	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
+
+	if (ret <= 0)
+		{
+		ctx->peerkey = NULL;
+		return ret;
+		}
+
+	CRYPTO_add(&peer->references,1,CRYPTO_LOCK_EVP_PKEY);
+	return 1;
+	}
+
+
+int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
+	{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DERIVE,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	if (ctx->operation != EVP_PKEY_OP_DERIVE)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+	M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
+	return ctx->pmeth->derive(ctx, key, pkeylen);
+	}
+
diff --git a/openssl/crypto/evp/pmeth_gn.c b/openssl/crypto/evp/pmeth_gn.c
new file mode 100644
index 0000000..5d74161
--- /dev/null
+++ b/openssl/crypto/evp/pmeth_gn.c
@@ -0,0 +1,220 @@
+/* pmeth_gn.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include "evp_locl.h"
+
+int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen)
+		{
+		EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	ctx->operation = EVP_PKEY_OP_PARAMGEN;
+	if (!ctx->pmeth->paramgen_init)
+		return 1;
+	ret = ctx->pmeth->paramgen_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+	}
+
+int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen)
+		{
+		EVPerr(EVP_F_EVP_PKEY_PARAMGEN,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+
+	if (ctx->operation != EVP_PKEY_OP_PARAMGEN)
+		{
+		EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+
+	if (!ppkey)
+		return -1;
+
+	if (!*ppkey)
+		*ppkey = EVP_PKEY_new();
+
+	ret = ctx->pmeth->paramgen(ctx, *ppkey);
+	if (ret <= 0)
+		{
+		EVP_PKEY_free(*ppkey);
+		*ppkey = NULL;
+		}
+	return ret;
+	}
+
+int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen)
+		{
+		EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	ctx->operation = EVP_PKEY_OP_KEYGEN;
+	if (!ctx->pmeth->keygen_init)
+		return 1;
+	ret = ctx->pmeth->keygen_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+	}
+
+int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
+	{
+	int ret;
+
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen)
+		{
+		EVPerr(EVP_F_EVP_PKEY_KEYGEN,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	if (ctx->operation != EVP_PKEY_OP_KEYGEN)
+		{
+		EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+
+	if (!ppkey)
+		return -1;
+
+	if (!*ppkey)
+		*ppkey = EVP_PKEY_new();
+
+	ret = ctx->pmeth->keygen(ctx, *ppkey);
+	if (ret <= 0)
+		{
+		EVP_PKEY_free(*ppkey);
+		*ppkey = NULL;
+		}
+	return ret;
+	}
+
+void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb)
+	{
+	ctx->pkey_gencb = cb;
+	}
+
+EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx)
+	{
+	return ctx->pkey_gencb;
+	}
+
+/* "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB
+ * style callbacks.
+ */
+
+static int trans_cb(int a, int b, BN_GENCB *gcb)
+	{
+	EVP_PKEY_CTX *ctx = gcb->arg;
+	ctx->keygen_info[0] = a;
+	ctx->keygen_info[1] = b;
+	return ctx->pkey_gencb(ctx);
+	}	
+
+void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx)
+	{
+	BN_GENCB_set(cb, trans_cb, ctx)
+	}
+
+int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx)
+	{
+	if (idx == -1)
+		return ctx->keygen_info_count; 
+	if (idx < 0 || idx > ctx->keygen_info_count)
+		return 0;
+	return ctx->keygen_info[idx];
+	}
+
+EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
+				unsigned char *key, int keylen)
+	{
+	EVP_PKEY_CTX *mac_ctx = NULL;
+	EVP_PKEY *mac_key = NULL;
+	mac_ctx = EVP_PKEY_CTX_new_id(type, e);
+	if (!mac_ctx)
+		return NULL;
+	if (EVP_PKEY_keygen_init(mac_ctx) <= 0)
+		goto merr;
+	if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
+				EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key) <= 0)
+		goto merr;
+	if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0)
+		goto merr;
+	merr:
+	if (mac_ctx)
+		EVP_PKEY_CTX_free(mac_ctx);
+	return mac_key;
+	}
diff --git a/openssl/crypto/evp/pmeth_lib.c b/openssl/crypto/evp/pmeth_lib.c
new file mode 100644
index 0000000..5481d4b
--- /dev/null
+++ b/openssl/crypto/evp/pmeth_lib.c
@@ -0,0 +1,540 @@
+/* pmeth_lib.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include "asn1_locl.h"
+#include "evp_locl.h"
+
+typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
+
+DECLARE_STACK_OF(EVP_PKEY_METHOD)
+STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
+
+extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth;
+extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth;
+
+static const EVP_PKEY_METHOD *standard_methods[] =
+	{
+#ifndef OPENSSL_NO_RSA
+	&rsa_pkey_meth,
+#endif
+#ifndef OPENSSL_NO_DH
+	&dh_pkey_meth,
+#endif
+#ifndef OPENSSL_NO_DSA
+	&dsa_pkey_meth,
+#endif
+#ifndef OPENSSL_NO_EC
+	&ec_pkey_meth,
+#endif
+	&hmac_pkey_meth,
+	};
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
+			   pmeth);
+
+static int pmeth_cmp(const EVP_PKEY_METHOD * const *a,
+		     const EVP_PKEY_METHOD * const *b)
+	{
+        return ((*a)->pkey_id - (*b)->pkey_id);
+	}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
+			     pmeth);
+
+const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type)
+	{
+	EVP_PKEY_METHOD tmp;
+	const EVP_PKEY_METHOD *t = &tmp, **ret;
+	tmp.pkey_id = type;
+	if (app_pkey_methods)
+		{
+		int idx;
+		idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp);
+		if (idx >= 0)
+			return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
+		}
+	ret = OBJ_bsearch_pmeth(&t, standard_methods,
+			  sizeof(standard_methods)/sizeof(EVP_PKEY_METHOD *));
+	if (!ret || !*ret)
+		return NULL;
+	return *ret;
+	}
+
+static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
+	{
+	EVP_PKEY_CTX *ret;
+	const EVP_PKEY_METHOD *pmeth;
+	if (id == -1)
+		{
+		if (!pkey || !pkey->ameth)
+			return NULL;
+		id = pkey->ameth->pkey_id;
+		}
+#ifndef OPENSSL_NO_ENGINE
+	if (pkey && pkey->engine)
+		e = pkey->engine;
+	/* Try to find an ENGINE which implements this method */
+	if (e)
+		{
+		if (!ENGINE_init(e))
+			{
+			EVPerr(EVP_F_INT_CTX_NEW,ERR_R_ENGINE_LIB);
+			return NULL;
+			}
+		}
+	else
+		e = ENGINE_get_pkey_meth_engine(id);
+
+	/* If an ENGINE handled this method look it up. Othewise
+	 * use internal tables.
+	 */
+
+	if (e)
+		pmeth = ENGINE_get_pkey_meth(e, id);
+	else
+#endif
+		pmeth = EVP_PKEY_meth_find(id);
+
+	if (pmeth == NULL)
+		{
+		EVPerr(EVP_F_INT_CTX_NEW,EVP_R_UNSUPPORTED_ALGORITHM);
+		return NULL;
+		}
+
+	ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
+	if (!ret)
+		{
+#ifndef OPENSSL_NO_ENGINE
+		if (e)
+			ENGINE_finish(e);
+#endif
+		EVPerr(EVP_F_INT_CTX_NEW,ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+	ret->engine = e;
+	ret->pmeth = pmeth;
+	ret->operation = EVP_PKEY_OP_UNDEFINED;
+	ret->pkey = pkey;
+	ret->peerkey = NULL;
+	ret->pkey_gencb = 0;
+	if (pkey)
+		CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
+	ret->data = NULL;
+
+	if (pmeth->init)
+		{
+		if (pmeth->init(ret) <= 0)
+			{
+			EVP_PKEY_CTX_free(ret);
+			return NULL;
+			}
+		}
+
+	return ret;
+	}
+
+EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags)
+	{
+	EVP_PKEY_METHOD *pmeth;
+	pmeth = OPENSSL_malloc(sizeof(EVP_PKEY_METHOD));
+	if (!pmeth)
+		return NULL;
+
+	pmeth->pkey_id = id;
+	pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
+
+	pmeth->init = 0;
+	pmeth->copy = 0;
+	pmeth->cleanup = 0;
+	pmeth->paramgen_init = 0;
+	pmeth->paramgen = 0;
+	pmeth->keygen_init = 0;
+	pmeth->keygen = 0;
+	pmeth->sign_init = 0;
+	pmeth->sign = 0;
+	pmeth->verify_init = 0;
+	pmeth->verify = 0;
+	pmeth->verify_recover_init = 0;
+	pmeth->verify_recover = 0;
+	pmeth->signctx_init = 0;
+	pmeth->signctx = 0;
+	pmeth->verifyctx_init = 0;
+	pmeth->verifyctx = 0;
+	pmeth->encrypt_init = 0;
+	pmeth->encrypt = 0;
+	pmeth->decrypt_init = 0;
+	pmeth->decrypt = 0;
+	pmeth->derive_init = 0;
+	pmeth->derive = 0;
+	pmeth->ctrl = 0;
+	pmeth->ctrl_str = 0;
+
+	return pmeth;
+	}
+
+void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
+	{
+	if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))
+		OPENSSL_free(pmeth);
+	}
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
+	{
+	return int_ctx_new(pkey, e, -1);
+	}
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
+	{
+	return int_ctx_new(NULL, e, id);
+	}
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
+	{
+	EVP_PKEY_CTX *rctx;
+	if (!pctx->pmeth || !pctx->pmeth->copy)
+		return NULL;
+#ifndef OPENSSL_NO_ENGINE
+	/* Make sure it's safe to copy a pkey context using an ENGINE */
+	if (pctx->engine && !ENGINE_init(pctx->engine))
+		{
+		EVPerr(EVP_F_EVP_PKEY_CTX_DUP,ERR_R_ENGINE_LIB);
+		return 0;
+		}
+#endif
+	rctx = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
+	if (!rctx)
+		return NULL;
+
+	rctx->pmeth = pctx->pmeth;
+#ifndef OPENSSL_NO_ENGINE
+	rctx->engine = pctx->engine;
+#endif
+
+	if (pctx->pkey)
+		CRYPTO_add(&pctx->pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
+
+	rctx->pkey = pctx->pkey;
+
+	if (pctx->peerkey)
+		CRYPTO_add(&pctx->peerkey->references,1,CRYPTO_LOCK_EVP_PKEY);
+
+	rctx->peerkey = pctx->peerkey;
+
+	rctx->data = NULL;
+	rctx->app_data = NULL;
+	rctx->operation = pctx->operation;
+
+	if (pctx->pmeth->copy(rctx, pctx) > 0)
+		return rctx;
+
+	EVP_PKEY_CTX_free(rctx);
+	return NULL;
+
+	}
+
+int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
+	{
+	if (app_pkey_methods == NULL)
+		{
+		app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp);
+		if (!app_pkey_methods)
+			return 0;
+		}
+	if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth))
+		return 0;
+	sk_EVP_PKEY_METHOD_sort(app_pkey_methods);
+	return 1;
+	}
+
+void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
+	{
+	if (ctx == NULL)
+		return;
+	if (ctx->pmeth && ctx->pmeth->cleanup)
+		ctx->pmeth->cleanup(ctx);
+	if (ctx->pkey)
+		EVP_PKEY_free(ctx->pkey);
+	if (ctx->peerkey)
+		EVP_PKEY_free(ctx->peerkey);
+#ifndef OPENSSL_NO_ENGINE
+	if(ctx->engine)
+		/* The EVP_PKEY_CTX we used belongs to an ENGINE, release the
+		 * functional reference we held for this reason. */
+		ENGINE_finish(ctx->engine);
+#endif
+	OPENSSL_free(ctx);
+	}
+
+int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
+				int cmd, int p1, void *p2)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl)
+		{
+		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
+		return -2;
+		}
+	if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype))
+		return -1;
+
+	if (ctx->operation == EVP_PKEY_OP_UNDEFINED)
+		{
+		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET);
+		return -1;
+		}
+
+	if ((optype != -1) && !(ctx->operation & optype))
+		{
+		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION);
+		return -1;
+		}
+
+	ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);
+
+	if (ret == -2)
+		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
+
+	return ret;
+
+	}
+
+int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
+					const char *name, const char *value)
+	{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str)
+		{
+		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR,
+						EVP_R_COMMAND_NOT_SUPPORTED);
+		return -2;
+		}
+	if (!strcmp(name, "digest"))
+		{
+		const EVP_MD *md;
+		if (!value || !(md = EVP_get_digestbyname(value)))
+			{
+			EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR,
+						EVP_R_INVALID_DIGEST);
+			return 0;
+			}
+		return EVP_PKEY_CTX_set_signature_md(ctx, md);
+		}
+	return ctx->pmeth->ctrl_str(ctx, name, value);
+	}
+
+int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx)
+	{
+	return ctx->operation;
+	}
+
+void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen)
+	{
+	ctx->keygen_info = dat;
+	ctx->keygen_info_count = datlen;
+	}
+
+void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
+	{
+	ctx->data = data;
+	}
+
+void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
+	{
+	return ctx->data;
+	}
+
+EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
+	{
+	return ctx->pkey;
+	}
+
+EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
+	{
+	return ctx->peerkey;
+	}
+	
+void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
+	{
+	ctx->app_data = data;
+	}
+
+void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
+	{
+	return ctx->app_data;
+	}
+
+void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
+	int (*init)(EVP_PKEY_CTX *ctx))
+	{
+	pmeth->init = init;
+	}
+
+void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
+	int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src))
+	{
+	pmeth->copy = copy;
+	}
+
+void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
+	void (*cleanup)(EVP_PKEY_CTX *ctx))
+	{
+	pmeth->cleanup = cleanup;
+	}
+
+void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
+	int (*paramgen_init)(EVP_PKEY_CTX *ctx),
+	int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey))
+	{
+	pmeth->paramgen_init = paramgen_init;
+	pmeth->paramgen = paramgen;
+	}
+
+void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
+	int (*keygen_init)(EVP_PKEY_CTX *ctx),
+	int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey))
+	{
+	pmeth->keygen_init = keygen_init;
+	pmeth->keygen = keygen;
+	}
+
+void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
+	int (*sign_init)(EVP_PKEY_CTX *ctx),
+	int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					const unsigned char *tbs, size_t tbslen))
+	{
+	pmeth->sign_init = sign_init;
+	pmeth->sign = sign;
+	}
+
+void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
+	int (*verify_init)(EVP_PKEY_CTX *ctx),
+	int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
+					const unsigned char *tbs, size_t tbslen))
+	{
+	pmeth->verify_init = verify_init;
+	pmeth->verify = verify;
+	}
+
+void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
+	int (*verify_recover_init)(EVP_PKEY_CTX *ctx),
+	int (*verify_recover)(EVP_PKEY_CTX *ctx,
+					unsigned char *sig, size_t *siglen,
+					const unsigned char *tbs, size_t tbslen))
+	{
+	pmeth->verify_recover_init = verify_recover_init;
+	pmeth->verify_recover = verify_recover;
+	}
+
+void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
+	int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
+	int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					EVP_MD_CTX *mctx))
+	{
+	pmeth->signctx_init = signctx_init;
+	pmeth->signctx = signctx;
+	}
+
+void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
+	int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
+	int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,int siglen,
+					EVP_MD_CTX *mctx))
+	{
+	pmeth->verifyctx_init = verifyctx_init;
+	pmeth->verifyctx = verifyctx;
+	}
+
+void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
+	int (*encrypt_init)(EVP_PKEY_CTX *ctx),
+	int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen))
+	{
+	pmeth->encrypt_init = encrypt_init;
+	pmeth->encrypt = encryptfn;
+	}
+
+void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
+	int (*decrypt_init)(EVP_PKEY_CTX *ctx),
+	int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen))
+	{
+	pmeth->decrypt_init = decrypt_init;
+	pmeth->decrypt = decrypt;
+	}
+
+void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
+	int (*derive_init)(EVP_PKEY_CTX *ctx),
+	int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen))
+	{
+	pmeth->derive_init = derive_init;
+	pmeth->derive = derive;
+	}
+
+void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
+	int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2),
+	int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value))
+	{
+	pmeth->ctrl = ctrl;
+	pmeth->ctrl_str = ctrl_str;
+	}
diff --git a/openssl/crypto/ex_data.c b/openssl/crypto/ex_data.c
new file mode 100644
index 0000000..e2bc829
--- /dev/null
+++ b/openssl/crypto/ex_data.c
@@ -0,0 +1,636 @@
+/* crypto/ex_data.c */
+
+/*
+ * Overhaul notes;
+ *
+ * This code is now *mostly* thread-safe. It is now easier to understand in what
+ * ways it is safe and in what ways it is not, which is an improvement. Firstly,
+ * all per-class stacks and index-counters for ex_data are stored in the same
+ * global LHASH table (keyed by class). This hash table uses locking for all
+ * access with the exception of CRYPTO_cleanup_all_ex_data(), which must only be
+ * called when no other threads can possibly race against it (even if it was
+ * locked, the race would mean it's possible the hash table might have been
+ * recreated after the cleanup). As classes can only be added to the hash table,
+ * and within each class, the stack of methods can only be incremented, the
+ * locking mechanics are simpler than they would otherwise be. For example, the
+ * new/dup/free ex_data functions will lock the hash table, copy the method
+ * pointers it needs from the relevant class, then unlock the hash table before
+ * actually applying those method pointers to the task of the new/dup/free
+ * operations. As they can't be removed from the method-stack, only
+ * supplemented, there's no race conditions associated with using them outside
+ * the lock. The get/set_ex_data functions are not locked because they do not
+ * involve this global state at all - they operate directly with a previously
+ * obtained per-class method index and a particular "ex_data" variable. These
+ * variables are usually instantiated per-context (eg. each RSA structure has
+ * one) so locking on read/write access to that variable can be locked locally
+ * if required (eg. using the "RSA" lock to synchronise access to a
+ * per-RSA-structure ex_data variable if required).
+ * [Geoff]
+ */
+
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+
+/* What an "implementation of ex_data functionality" looks like */
+struct st_CRYPTO_EX_DATA_IMPL
+	{
+	/*********************/
+	/* GLOBAL OPERATIONS */
+	/* Return a new class index */
+	int (*cb_new_class)(void);
+	/* Cleanup all state used by the implementation */
+	void (*cb_cleanup)(void);
+	/************************/
+	/* PER-CLASS OPERATIONS */
+	/* Get a new method index within a class */
+	int (*cb_get_new_index)(int class_index, long argl, void *argp,
+			CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+			CRYPTO_EX_free *free_func);
+	/* Initialise a new CRYPTO_EX_DATA of a given class */
+	int (*cb_new_ex_data)(int class_index, void *obj,
+			CRYPTO_EX_DATA *ad);
+	/* Duplicate a CRYPTO_EX_DATA of a given class onto a copy */
+	int (*cb_dup_ex_data)(int class_index, CRYPTO_EX_DATA *to,
+			CRYPTO_EX_DATA *from);
+	/* Cleanup a CRYPTO_EX_DATA of a given class */
+	void (*cb_free_ex_data)(int class_index, void *obj,
+			CRYPTO_EX_DATA *ad);
+	};
+
+/* The implementation we use at run-time */
+static const CRYPTO_EX_DATA_IMPL *impl = NULL;
+
+/* To call "impl" functions, use this macro rather than referring to 'impl' directly, eg.
+ * EX_IMPL(get_new_index)(...); */
+#define EX_IMPL(a) impl->cb_##a
+
+/* Predeclare the "default" ex_data implementation */
+static int int_new_class(void);
+static void int_cleanup(void);
+static int int_get_new_index(int class_index, long argl, void *argp,
+		CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+		CRYPTO_EX_free *free_func);
+static int int_new_ex_data(int class_index, void *obj,
+		CRYPTO_EX_DATA *ad);
+static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+		CRYPTO_EX_DATA *from);
+static void int_free_ex_data(int class_index, void *obj,
+		CRYPTO_EX_DATA *ad);
+static CRYPTO_EX_DATA_IMPL impl_default =
+	{
+	int_new_class,
+	int_cleanup,
+	int_get_new_index,
+	int_new_ex_data,
+	int_dup_ex_data,
+	int_free_ex_data
+	};
+
+/* Internal function that checks whether "impl" is set and if not, sets it to
+ * the default. */
+static void impl_check(void)
+	{
+	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+	if(!impl)
+		impl = &impl_default;
+	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+	}
+/* A macro wrapper for impl_check that first uses a non-locked test before
+ * invoking the function (which checks again inside a lock). */
+#define IMPL_CHECK if(!impl) impl_check();
+
+/* API functions to get/set the "ex_data" implementation */
+const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void)
+	{
+	IMPL_CHECK
+	return impl;
+	}
+int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i)
+	{
+	int toret = 0;
+	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+	if(!impl)
+		{
+		impl = i;
+		toret = 1;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+	return toret;
+	}
+
+/****************************************************************************/
+/* Interal (default) implementation of "ex_data" support. API functions are
+ * further down. */
+
+/* The type that represents what each "class" used to implement locally. A STACK
+ * of CRYPTO_EX_DATA_FUNCS plus a index-counter. The 'class_index' is the global
+ * value representing the class that is used to distinguish these items. */
+typedef struct st_ex_class_item {
+	int class_index;
+	STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth;
+	int meth_num;
+} EX_CLASS_ITEM;
+
+/* When assigning new class indexes, this is our counter */
+static int ex_class = CRYPTO_EX_INDEX_USER;
+
+/* The global hash table of EX_CLASS_ITEM items */
+DECLARE_LHASH_OF(EX_CLASS_ITEM);
+static LHASH_OF(EX_CLASS_ITEM) *ex_data = NULL;
+
+/* The callbacks required in the "ex_data" hash table */
+static unsigned long ex_class_item_hash(const EX_CLASS_ITEM *a)
+	{
+	return a->class_index;
+	}
+static IMPLEMENT_LHASH_HASH_FN(ex_class_item, EX_CLASS_ITEM)
+
+static int ex_class_item_cmp(const EX_CLASS_ITEM *a, const EX_CLASS_ITEM *b)
+	{
+	return a->class_index - b->class_index;
+	}
+static IMPLEMENT_LHASH_COMP_FN(ex_class_item, EX_CLASS_ITEM)
+
+/* Internal functions used by the "impl_default" implementation to access the
+ * state */
+
+static int ex_data_check(void)
+	{
+	int toret = 1;
+	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+	if(!ex_data
+	   && (ex_data = lh_EX_CLASS_ITEM_new()) == NULL)
+		toret = 0;
+	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+	return toret;
+	}
+/* This macros helps reduce the locking from repeated checks because the
+ * ex_data_check() function checks ex_data again inside a lock. */
+#define EX_DATA_CHECK(iffail) if(!ex_data && !ex_data_check()) {iffail}
+
+/* This "inner" callback is used by the callback function that follows it */
+static void def_cleanup_util_cb(CRYPTO_EX_DATA_FUNCS *funcs)
+	{
+	OPENSSL_free(funcs);
+	}
+
+/* This callback is used in lh_doall to destroy all EX_CLASS_ITEM values from
+ * "ex_data" prior to the ex_data hash table being itself destroyed. Doesn't do
+ * any locking. */
+static void def_cleanup_cb(void *a_void)
+	{
+	EX_CLASS_ITEM *item = (EX_CLASS_ITEM *)a_void;
+	sk_CRYPTO_EX_DATA_FUNCS_pop_free(item->meth, def_cleanup_util_cb);
+	OPENSSL_free(item);
+	}
+
+/* Return the EX_CLASS_ITEM from the "ex_data" hash table that corresponds to a
+ * given class. Handles locking. */
+static EX_CLASS_ITEM *def_get_class(int class_index)
+	{
+	EX_CLASS_ITEM d, *p, *gen;
+	EX_DATA_CHECK(return NULL;)
+	d.class_index = class_index;
+	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+	p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d);
+	if(!p)
+		{
+		gen = OPENSSL_malloc(sizeof(EX_CLASS_ITEM));
+		if(gen)
+			{
+			gen->class_index = class_index;
+			gen->meth_num = 0;
+			gen->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null();
+			if(!gen->meth)
+				OPENSSL_free(gen);
+			else
+				{
+				/* Because we're inside the ex_data lock, the
+				 * return value from the insert will be NULL */
+				(void)lh_EX_CLASS_ITEM_insert(ex_data, gen);
+				p = gen;
+				}
+			}
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+	if(!p)
+		CRYPTOerr(CRYPTO_F_DEF_GET_CLASS,ERR_R_MALLOC_FAILURE);
+	return p;
+	}
+
+/* Add a new method to the given EX_CLASS_ITEM and return the corresponding
+ * index (or -1 for error). Handles locking. */
+static int def_add_index(EX_CLASS_ITEM *item, long argl, void *argp,
+		CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+		CRYPTO_EX_free *free_func)
+	{
+	int toret = -1;
+	CRYPTO_EX_DATA_FUNCS *a = (CRYPTO_EX_DATA_FUNCS *)OPENSSL_malloc(
+					sizeof(CRYPTO_EX_DATA_FUNCS));
+	if(!a)
+		{
+		CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX,ERR_R_MALLOC_FAILURE);
+		return -1;
+		}
+	a->argl=argl;
+	a->argp=argp;
+	a->new_func=new_func;
+	a->dup_func=dup_func;
+	a->free_func=free_func;
+	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+	while (sk_CRYPTO_EX_DATA_FUNCS_num(item->meth) <= item->meth_num)
+		{
+		if (!sk_CRYPTO_EX_DATA_FUNCS_push(item->meth, NULL))
+			{
+			CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX,ERR_R_MALLOC_FAILURE);
+			OPENSSL_free(a);
+			goto err;
+			}
+		}
+	toret = item->meth_num++;
+	(void)sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a);
+err:
+	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+	return toret;
+	}
+
+/**************************************************************/
+/* The functions in the default CRYPTO_EX_DATA_IMPL structure */
+
+static int int_new_class(void)
+	{
+	int toret;
+	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+	toret = ex_class++;
+	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+	return toret;
+	}
+
+static void int_cleanup(void)
+	{
+	EX_DATA_CHECK(return;)
+	lh_EX_CLASS_ITEM_doall(ex_data, def_cleanup_cb);
+	lh_EX_CLASS_ITEM_free(ex_data);
+	ex_data = NULL;
+	impl = NULL;
+	}
+
+static int int_get_new_index(int class_index, long argl, void *argp,
+		CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+		CRYPTO_EX_free *free_func)
+	{
+	EX_CLASS_ITEM *item = def_get_class(class_index);
+	if(!item)
+		return -1;
+	return def_add_index(item, argl, argp, new_func, dup_func, free_func);
+	}
+
+/* Thread-safe by copying a class's array of "CRYPTO_EX_DATA_FUNCS" entries in
+ * the lock, then using them outside the lock. NB: Thread-safety only applies to
+ * the global "ex_data" state (ie. class definitions), not thread-safe on 'ad'
+ * itself. */
+static int int_new_ex_data(int class_index, void *obj,
+		CRYPTO_EX_DATA *ad)
+	{
+	int mx,i;
+	void *ptr;
+	CRYPTO_EX_DATA_FUNCS **storage = NULL;
+	EX_CLASS_ITEM *item = def_get_class(class_index);
+	if(!item)
+		/* error is already set */
+		return 0;
+	ad->sk = NULL;
+	CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
+	mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
+	if(mx > 0)
+		{
+		storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*));
+		if(!storage)
+			goto skip;
+		for(i = 0; i < mx; i++)
+			storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth,i);
+		}
+skip:
+	CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
+	if((mx > 0) && !storage)
+		{
+		CRYPTOerr(CRYPTO_F_INT_NEW_EX_DATA,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	for(i = 0; i < mx; i++)
+		{
+		if(storage[i] && storage[i]->new_func)
+			{
+			ptr = CRYPTO_get_ex_data(ad, i);
+			storage[i]->new_func(obj,ptr,ad,i,
+				storage[i]->argl,storage[i]->argp);
+			}
+		}
+	if(storage)
+		OPENSSL_free(storage);
+	return 1;
+	}
+
+/* Same thread-safety notes as for "int_new_ex_data" */
+static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+		CRYPTO_EX_DATA *from)
+	{
+	int mx, j, i;
+	char *ptr;
+	CRYPTO_EX_DATA_FUNCS **storage = NULL;
+	EX_CLASS_ITEM *item;
+	if(!from->sk)
+		/* 'to' should be "blank" which *is* just like 'from' */
+		return 1;
+	if((item = def_get_class(class_index)) == NULL)
+		return 0;
+	CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
+	mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
+	j = sk_void_num(from->sk);
+	if(j < mx)
+		mx = j;
+	if(mx > 0)
+		{
+		storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*));
+		if(!storage)
+			goto skip;
+		for(i = 0; i < mx; i++)
+			storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth,i);
+		}
+skip:
+	CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
+	if((mx > 0) && !storage)
+		{
+		CRYPTOerr(CRYPTO_F_INT_DUP_EX_DATA,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	for(i = 0; i < mx; i++)
+		{
+		ptr = CRYPTO_get_ex_data(from, i);
+		if(storage[i] && storage[i]->dup_func)
+			storage[i]->dup_func(to,from,&ptr,i,
+				storage[i]->argl,storage[i]->argp);
+		CRYPTO_set_ex_data(to,i,ptr);
+		}
+	if(storage)
+		OPENSSL_free(storage);
+	return 1;
+	}
+
+/* Same thread-safety notes as for "int_new_ex_data" */
+static void int_free_ex_data(int class_index, void *obj,
+		CRYPTO_EX_DATA *ad)
+	{
+	int mx,i;
+	EX_CLASS_ITEM *item;
+	void *ptr;
+	CRYPTO_EX_DATA_FUNCS **storage = NULL;
+	if((item = def_get_class(class_index)) == NULL)
+		return;
+	CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
+	mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
+	if(mx > 0)
+		{
+		storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*));
+		if(!storage)
+			goto skip;
+		for(i = 0; i < mx; i++)
+			storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth,i);
+		}
+skip:
+	CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
+	if((mx > 0) && !storage)
+		{
+		CRYPTOerr(CRYPTO_F_INT_FREE_EX_DATA,ERR_R_MALLOC_FAILURE);
+		return;
+		}
+	for(i = 0; i < mx; i++)
+		{
+		if(storage[i] && storage[i]->free_func)
+			{
+			ptr = CRYPTO_get_ex_data(ad,i);
+			storage[i]->free_func(obj,ptr,ad,i,
+				storage[i]->argl,storage[i]->argp);
+			}
+		}
+	if(storage)
+		OPENSSL_free(storage);
+	if(ad->sk)
+		{
+		sk_void_free(ad->sk);
+		ad->sk=NULL;
+		}
+	}
+
+/********************************************************************/
+/* API functions that defer all "state" operations to the "ex_data"
+ * implementation we have set. */
+
+/* Obtain an index for a new class (not the same as getting a new index within
+ * an existing class - this is actually getting a new *class*) */
+int CRYPTO_ex_data_new_class(void)
+	{
+	IMPL_CHECK
+	return EX_IMPL(new_class)();
+	}
+
+/* Release all "ex_data" state to prevent memory leaks. This can't be made
+ * thread-safe without overhauling a lot of stuff, and shouldn't really be
+ * called under potential race-conditions anyway (it's for program shutdown
+ * after all). */
+void CRYPTO_cleanup_all_ex_data(void)
+	{
+	IMPL_CHECK
+	EX_IMPL(cleanup)();
+	}
+
+/* Inside an existing class, get/register a new index. */
+int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
+		CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+		CRYPTO_EX_free *free_func)
+	{
+	int ret = -1;
+
+	IMPL_CHECK
+	ret = EX_IMPL(get_new_index)(class_index,
+			argl, argp, new_func, dup_func, free_func);
+	return ret;
+	}
+
+/* Initialise a new CRYPTO_EX_DATA for use in a particular class - including
+ * calling new() callbacks for each index in the class used by this variable */
+int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+	{
+	IMPL_CHECK
+	return EX_IMPL(new_ex_data)(class_index, obj, ad);
+	}
+
+/* Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks for
+ * each index in the class used by this variable */
+int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+	     CRYPTO_EX_DATA *from)
+	{
+	IMPL_CHECK
+	return EX_IMPL(dup_ex_data)(class_index, to, from);
+	}
+
+/* Cleanup a CRYPTO_EX_DATA variable - including calling free() callbacks for
+ * each index in the class used by this variable */
+void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+	{
+	IMPL_CHECK
+	EX_IMPL(free_ex_data)(class_index, obj, ad);
+	}
+
+/* For a given CRYPTO_EX_DATA variable, set the value corresponding to a
+ * particular index in the class used by this variable */
+int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val)
+	{
+	int i;
+
+	if (ad->sk == NULL)
+		{
+		if ((ad->sk=sk_void_new_null()) == NULL)
+			{
+			CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE);
+			return(0);
+			}
+		}
+	i=sk_void_num(ad->sk);
+
+	while (i <= idx)
+		{
+		if (!sk_void_push(ad->sk,NULL))
+			{
+			CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE);
+			return(0);
+			}
+		i++;
+		}
+	sk_void_set(ad->sk,idx,val);
+	return(1);
+	}
+
+/* For a given CRYPTO_EX_DATA_ variable, get the value corresponding to a
+ * particular index in the class used by this variable */
+void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
+	{
+	if (ad->sk == NULL)
+		return(0);
+	else if (idx >= sk_void_num(ad->sk))
+		return(0);
+	else
+		return(sk_void_value(ad->sk,idx));
+	}
+
+IMPLEMENT_STACK_OF(CRYPTO_EX_DATA_FUNCS)
diff --git a/openssl/crypto/hmac/Makefile b/openssl/crypto/hmac/Makefile
new file mode 100644
index 0000000..0e91709
--- /dev/null
+++ b/openssl/crypto/hmac/Makefile
@@ -0,0 +1,110 @@
+#
+# OpenSSL/crypto/md/Makefile
+#
+
+DIR=	hmac
+TOP=	../..
+CC=	cc
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=hmactest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=hmac.c hm_ameth.c hm_pmeth.c
+LIBOBJ=hmac.o hm_ameth.o hm_pmeth.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= hmac.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+hm_ameth.o: ../../e_os.h ../../include/openssl/asn1.h
+hm_ameth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+hm_ameth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+hm_ameth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+hm_ameth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+hm_ameth.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+hm_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+hm_ameth.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+hm_ameth.o: ../../include/openssl/symhacks.h ../asn1/asn1_locl.h ../cryptlib.h
+hm_ameth.o: hm_ameth.c
+hm_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
+hm_pmeth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+hm_pmeth.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+hm_pmeth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+hm_pmeth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+hm_pmeth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+hm_pmeth.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+hm_pmeth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+hm_pmeth.o: ../../include/openssl/opensslconf.h
+hm_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+hm_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+hm_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+hm_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+hm_pmeth.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+hm_pmeth.o: ../cryptlib.h ../evp/evp_locl.h hm_pmeth.c
+hmac.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+hmac.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+hmac.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+hmac.o: ../../include/openssl/evp.h ../../include/openssl/hmac.h
+hmac.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+hmac.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+hmac.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+hmac.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+hmac.o: ../../include/openssl/symhacks.h ../cryptlib.h hmac.c
diff --git a/openssl/crypto/hmac/hm_ameth.c b/openssl/crypto/hmac/hm_ameth.c
new file mode 100644
index 0000000..6d8a891
--- /dev/null
+++ b/openssl/crypto/hmac/hm_ameth.c
@@ -0,0 +1,167 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include "asn1_locl.h"
+
+#define HMAC_TEST_PRIVATE_KEY_FORMAT
+
+/* HMAC "ASN1" method. This is just here to indicate the
+ * maximum HMAC output length and to free up an HMAC
+ * key.
+ */
+
+static int hmac_size(const EVP_PKEY *pkey)
+	{
+	return EVP_MAX_MD_SIZE;
+	}
+
+static void hmac_key_free(EVP_PKEY *pkey)
+	{
+	ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
+	if (os)
+		{
+		if (os->data)
+			OPENSSL_cleanse(os->data, os->length);
+		ASN1_OCTET_STRING_free(os);
+		}
+	}
+
+
+static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+	{
+	switch (op)
+		{
+		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+		*(int *)arg2 = NID_sha1;
+		return 1;
+
+		default:
+		return -2;
+		}
+	}
+
+#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT
+/* A bogus private key format for test purposes. This is simply the
+ * HMAC key with "HMAC PRIVATE KEY" in the headers. When enabled the
+ * genpkey utility can be used to "generate" HMAC keys.
+ */
+
+static int old_hmac_decode(EVP_PKEY *pkey,
+					const unsigned char **pder, int derlen)
+	{
+	ASN1_OCTET_STRING *os;
+	os = ASN1_OCTET_STRING_new();
+	if (!os || !ASN1_OCTET_STRING_set(os, *pder, derlen))
+		return 0;
+	EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, os);
+	return 1;
+	}
+
+static int old_hmac_encode(const EVP_PKEY *pkey, unsigned char **pder)
+	{
+	int inc;
+	ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
+	if (pder)
+		{
+		if (!*pder)
+			{
+			*pder = OPENSSL_malloc(os->length);
+			inc = 0;
+			}
+		else inc = 1;
+
+		memcpy(*pder, os->data, os->length);
+
+		if (inc)
+			*pder += os->length;
+		}
+			
+	return os->length;
+	}
+
+#endif
+
+const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = 
+	{
+	EVP_PKEY_HMAC,
+	EVP_PKEY_HMAC,
+	0,
+
+	"HMAC",
+	"OpenSSL HMAC method",
+
+	0,0,0,0,
+
+	0,0,0,
+
+	hmac_size,
+	0,
+	0,0,0,0,0,0,
+
+	hmac_key_free,
+	hmac_pkey_ctrl,
+#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT
+	old_hmac_decode,
+	old_hmac_encode
+#else
+	0,0
+#endif
+	};
+
diff --git a/openssl/crypto/hmac/hm_pmeth.c b/openssl/crypto/hmac/hm_pmeth.c
new file mode 100644
index 0000000..71e8567
--- /dev/null
+++ b/openssl/crypto/hmac/hm_pmeth.c
@@ -0,0 +1,267 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include "evp_locl.h"
+
+/* HMAC pkey context structure */
+
+typedef struct
+	{
+	const EVP_MD *md;	/* MD for HMAC use */
+	ASN1_OCTET_STRING ktmp; /* Temp storage for key */
+	HMAC_CTX ctx;
+	} HMAC_PKEY_CTX;
+
+static int pkey_hmac_init(EVP_PKEY_CTX *ctx)
+	{
+	HMAC_PKEY_CTX *hctx;
+	hctx = OPENSSL_malloc(sizeof(HMAC_PKEY_CTX));
+	if (!hctx)
+		return 0;
+	hctx->md = NULL;
+	hctx->ktmp.data = NULL;
+	hctx->ktmp.length = 0;
+	hctx->ktmp.flags = 0;
+	hctx->ktmp.type = V_ASN1_OCTET_STRING;
+	HMAC_CTX_init(&hctx->ctx);
+
+	ctx->data = hctx;
+	ctx->keygen_info_count = 0;
+
+	return 1;
+	}
+
+static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+	{
+	HMAC_PKEY_CTX *sctx, *dctx;
+	if (!pkey_hmac_init(dst))
+		return 0;
+       	sctx = src->data;
+	dctx = dst->data;
+	dctx->md = sctx->md;
+	HMAC_CTX_init(&dctx->ctx);
+	HMAC_CTX_copy(&dctx->ctx, &sctx->ctx);
+	if (sctx->ktmp.data)
+		{
+		if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
+					sctx->ktmp.data, sctx->ktmp.length))
+			return 0;
+		}
+	return 1;
+	}
+
+static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx)
+	{
+	HMAC_PKEY_CTX *hctx = ctx->data;
+	HMAC_CTX_cleanup(&hctx->ctx);
+	if (hctx->ktmp.data)
+		{
+		if (hctx->ktmp.length)
+			OPENSSL_cleanse(hctx->ktmp.data, hctx->ktmp.length);
+		OPENSSL_free(hctx->ktmp.data);
+		hctx->ktmp.data = NULL;
+		}
+	OPENSSL_free(hctx);
+	}
+
+static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+	ASN1_OCTET_STRING *hkey = NULL;
+	HMAC_PKEY_CTX *hctx = ctx->data;
+	if (!hctx->ktmp.data)
+		return 0;
+	hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp);
+	if (!hkey)
+		return 0;
+	EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey);
+	
+	return 1;
+	}
+
+static int int_update(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{
+	HMAC_PKEY_CTX *hctx = ctx->pctx->data;
+	HMAC_Update(&hctx->ctx, data, count);
+	return 1;
+	}
+
+static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
+	{
+	HMAC_PKEY_CTX *hctx = ctx->data;
+	HMAC_CTX_set_flags(&hctx->ctx, mctx->flags & ~EVP_MD_CTX_FLAG_NO_INIT);
+	EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
+	mctx->update = int_update;
+	return 1;
+	}
+
+static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					EVP_MD_CTX *mctx)
+	{
+	unsigned int hlen;
+	HMAC_PKEY_CTX *hctx = ctx->data;
+	int l = EVP_MD_CTX_size(mctx);
+
+	if (l < 0)
+		return 0;
+	*siglen = l;
+	if (!sig)
+		return 1;
+
+	HMAC_Final(&hctx->ctx, sig, &hlen);
+	*siglen = (size_t)hlen;
+	return 1;
+	}
+
+static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+	{
+	HMAC_PKEY_CTX *hctx = ctx->data;
+	ASN1_OCTET_STRING *key;
+	switch (type)
+		{
+
+		case EVP_PKEY_CTRL_SET_MAC_KEY:
+		if ((!p2 && p1 > 0) || (p1 < -1))
+			return 0;
+		if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1))
+			return 0;
+		break;
+
+		case EVP_PKEY_CTRL_MD:
+		hctx->md = p2;
+		break;
+
+		case EVP_PKEY_CTRL_DIGESTINIT:
+		key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
+		HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md,
+				ctx->engine);
+		break;
+
+		default:
+		return -2;
+
+		}
+	return 1;
+	}
+
+static int pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx,
+			const char *type, const char *value)
+	{
+	if (!value)
+		{
+		return 0;
+		}
+	if (!strcmp(type, "key"))
+		{
+		void *p = (void *)value;
+		return pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
+				-1, p);
+		}
+	if (!strcmp(type, "hexkey"))
+		{
+		unsigned char *key;
+		int r;
+		long keylen;
+		key = string_to_hex(value, &keylen);
+		if (!key)
+			return 0;
+		r = pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
+		OPENSSL_free(key);
+		return r;
+		}
+	return -2;
+	}
+
+const EVP_PKEY_METHOD hmac_pkey_meth = 
+	{
+	EVP_PKEY_HMAC,
+	0,
+	pkey_hmac_init,
+	pkey_hmac_copy,
+	pkey_hmac_cleanup,
+
+	0, 0,
+
+	0,
+	pkey_hmac_keygen,
+
+	0, 0,
+
+	0, 0,
+
+	0,0,
+
+	hmac_signctx_init,
+	hmac_signctx,
+
+	0,0,
+
+	0,0,
+
+	0,0,
+
+	0,0,
+
+	pkey_hmac_ctrl,
+	pkey_hmac_ctrl_str
+
+	};
diff --git a/openssl/crypto/hmac/hmac.c b/openssl/crypto/hmac/hmac.c
new file mode 100644
index 0000000..6c98fc4
--- /dev/null
+++ b/openssl/crypto/hmac/hmac.c
@@ -0,0 +1,214 @@
+/* crypto/hmac/hmac.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/hmac.h>
+
+int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
+		  const EVP_MD *md, ENGINE *impl)
+	{
+	int i,j,reset=0;
+	unsigned char pad[HMAC_MAX_MD_CBLOCK];
+
+	if (md != NULL)
+		{
+		reset=1;
+		ctx->md=md;
+		}
+	else
+		md=ctx->md;
+
+	if (key != NULL)
+		{
+		reset=1;
+		j=EVP_MD_block_size(md);
+		OPENSSL_assert(j <= (int)sizeof(ctx->key));
+		if (j < len)
+			{
+			if (!EVP_DigestInit_ex(&ctx->md_ctx,md, impl))
+				goto err;
+			if (!EVP_DigestUpdate(&ctx->md_ctx,key,len))
+				goto err;
+			if (!EVP_DigestFinal_ex(&(ctx->md_ctx),ctx->key,
+				&ctx->key_length))
+				goto err;
+			}
+		else
+			{
+			OPENSSL_assert(len>=0 && len<=(int)sizeof(ctx->key));
+			memcpy(ctx->key,key,len);
+			ctx->key_length=len;
+			}
+		if(ctx->key_length != HMAC_MAX_MD_CBLOCK)
+			memset(&ctx->key[ctx->key_length], 0,
+				HMAC_MAX_MD_CBLOCK - ctx->key_length);
+		}
+
+	if (reset)	
+		{
+		for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
+			pad[i]=0x36^ctx->key[i];
+		if (!EVP_DigestInit_ex(&ctx->i_ctx,md, impl))
+			goto err;
+		if (!EVP_DigestUpdate(&ctx->i_ctx,pad,EVP_MD_block_size(md)))
+			goto err;
+
+		for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
+			pad[i]=0x5c^ctx->key[i];
+		if (!EVP_DigestInit_ex(&ctx->o_ctx,md, impl))
+			goto err;
+		if (!EVP_DigestUpdate(&ctx->o_ctx,pad,EVP_MD_block_size(md)))
+			goto err;
+		}
+	if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->i_ctx))
+			goto err;
+	return 1;
+	err:
+	return 0;
+	}
+
+int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md)
+	{
+	if(key && md)
+	    HMAC_CTX_init(ctx);
+	return HMAC_Init_ex(ctx,key,len,md, NULL);
+	}
+
+int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
+	{
+	return EVP_DigestUpdate(&ctx->md_ctx,data,len);
+	}
+
+int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
+	{
+	unsigned int i;
+	unsigned char buf[EVP_MAX_MD_SIZE];
+
+	if (!EVP_DigestFinal_ex(&ctx->md_ctx,buf,&i))
+		goto err;
+	if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->o_ctx))
+		goto err;
+	if (!EVP_DigestUpdate(&ctx->md_ctx,buf,i))
+		goto err;
+	if (!EVP_DigestFinal_ex(&ctx->md_ctx,md,len))
+		goto err;
+	return 1;
+	err:
+	return 0;
+	}
+
+void HMAC_CTX_init(HMAC_CTX *ctx)
+	{
+	EVP_MD_CTX_init(&ctx->i_ctx);
+	EVP_MD_CTX_init(&ctx->o_ctx);
+	EVP_MD_CTX_init(&ctx->md_ctx);
+	}
+
+int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
+	{
+	if (!EVP_MD_CTX_copy(&dctx->i_ctx, &sctx->i_ctx))
+		goto err;
+	if (!EVP_MD_CTX_copy(&dctx->o_ctx, &sctx->o_ctx))
+		goto err;
+	if (!EVP_MD_CTX_copy(&dctx->md_ctx, &sctx->md_ctx))
+		goto err;
+	memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK);
+	dctx->key_length = sctx->key_length;
+	dctx->md = sctx->md;
+	return 1;
+	err:
+	return 0;
+	}
+
+void HMAC_CTX_cleanup(HMAC_CTX *ctx)
+	{
+	EVP_MD_CTX_cleanup(&ctx->i_ctx);
+	EVP_MD_CTX_cleanup(&ctx->o_ctx);
+	EVP_MD_CTX_cleanup(&ctx->md_ctx);
+	memset(ctx,0,sizeof *ctx);
+	}
+
+unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
+		    const unsigned char *d, size_t n, unsigned char *md,
+		    unsigned int *md_len)
+	{
+	HMAC_CTX c;
+	static unsigned char m[EVP_MAX_MD_SIZE];
+
+	if (md == NULL) md=m;
+	HMAC_CTX_init(&c);
+	if (!HMAC_Init(&c,key,key_len,evp_md))
+		goto err;
+	if (!HMAC_Update(&c,d,n))
+		goto err;
+	if (!HMAC_Final(&c,md,md_len))
+		goto err;
+	HMAC_CTX_cleanup(&c);
+	return md;
+	err:
+	return NULL;
+	}
+
+void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
+	{
+	EVP_MD_CTX_set_flags(&ctx->i_ctx, flags);
+	EVP_MD_CTX_set_flags(&ctx->o_ctx, flags);
+	EVP_MD_CTX_set_flags(&ctx->md_ctx, flags);
+	}
diff --git a/openssl/crypto/hmac/hmac.h b/openssl/crypto/hmac/hmac.h
new file mode 100644
index 0000000..1be0022
--- /dev/null
+++ b/openssl/crypto/hmac/hmac.h
@@ -0,0 +1,110 @@
+/* crypto/hmac/hmac.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+#ifndef HEADER_HMAC_H
+#define HEADER_HMAC_H
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_HMAC
+#error HMAC is disabled.
+#endif
+
+#include <openssl/evp.h>
+
+#define HMAC_MAX_MD_CBLOCK	128	/* largest known is SHA512 */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct hmac_ctx_st
+	{
+	const EVP_MD *md;
+	EVP_MD_CTX md_ctx;
+	EVP_MD_CTX i_ctx;
+	EVP_MD_CTX o_ctx;
+	unsigned int key_length;
+	unsigned char key[HMAC_MAX_MD_CBLOCK];
+	} HMAC_CTX;
+
+#define HMAC_size(e)	(EVP_MD_size((e)->md))
+
+
+void HMAC_CTX_init(HMAC_CTX *ctx);
+void HMAC_CTX_cleanup(HMAC_CTX *ctx);
+
+#define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx) /* deprecated */
+
+int HMAC_Init(HMAC_CTX *ctx, const void *key, int len,
+	       const EVP_MD *md); /* deprecated */
+int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
+		  const EVP_MD *md, ENGINE *impl);
+int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len);
+int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
+unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
+		    const unsigned char *d, size_t n, unsigned char *md,
+		    unsigned int *md_len);
+int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx);
+
+void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/hmac/hmactest.c b/openssl/crypto/hmac/hmactest.c
new file mode 100644
index 0000000..1b906b8
--- /dev/null
+++ b/openssl/crypto/hmac/hmactest.c
@@ -0,0 +1,175 @@
+/* crypto/hmac/hmactest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_HMAC
+int main(int argc, char *argv[])
+{
+    printf("No HMAC support\n");
+    return(0);
+}
+#else
+#include <openssl/hmac.h>
+#ifndef OPENSSL_NO_MD5
+#include <openssl/md5.h>
+#endif
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+#ifndef OPENSSL_NO_MD5
+static struct test_st
+	{
+	unsigned char key[16];
+	int key_len;
+	unsigned char data[64];
+	int data_len;
+	unsigned char *digest;
+	} test[4]={
+	{	"",
+		0,
+		"More text test vectors to stuff up EBCDIC machines :-)",
+		54,
+		(unsigned char *)"e9139d1e6ee064ef8cf514fc7dc83e86",
+	},{	{0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+		 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,},
+		16,
+		"Hi There",
+		8,
+		(unsigned char *)"9294727a3638bb1c13f48ef8158bfc9d",
+	},{	"Jefe",
+		4,
+		"what do ya want for nothing?",
+		28,
+		(unsigned char *)"750c783e6ab0b503eaa86e310a5db738",
+	},{
+		{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+		 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,},
+		16,
+		{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
+		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
+		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
+		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
+		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
+		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
+		 0xdd,0xdd},
+		50,
+		(unsigned char *)"56be34521d144c88dbb8c733f0e8b3f6",
+	},
+	};
+#endif
+
+static char *pt(unsigned char *md);
+int main(int argc, char *argv[])
+	{
+#ifndef OPENSSL_NO_MD5
+	int i;
+	char *p;
+#endif
+	int err=0;
+
+#ifdef OPENSSL_NO_MD5
+	printf("test skipped: MD5 disabled\n");
+#else
+
+#ifdef CHARSET_EBCDIC
+	ebcdic2ascii(test[0].data, test[0].data, test[0].data_len);
+	ebcdic2ascii(test[1].data, test[1].data, test[1].data_len);
+	ebcdic2ascii(test[2].key,  test[2].key,  test[2].key_len);
+	ebcdic2ascii(test[2].data, test[2].data, test[2].data_len);
+#endif
+
+	for (i=0; i<4; i++)
+		{
+		p=pt(HMAC(EVP_md5(),
+			test[i].key, test[i].key_len,
+			test[i].data, test[i].data_len,
+			NULL,NULL));
+
+		if (strcmp(p,(char *)test[i].digest) != 0)
+			{
+			printf("error calculating HMAC on %d entry'\n",i);
+			printf("got %s instead of %s\n",p,test[i].digest);
+			err++;
+			}
+		else
+			printf("test %d ok\n",i);
+		}
+#endif /* OPENSSL_NO_MD5 */
+	EXIT(err);
+	return(0);
+	}
+
+#ifndef OPENSSL_NO_MD5
+static char *pt(unsigned char *md)
+	{
+	int i;
+	static char buf[80];
+
+	for (i=0; i<MD5_DIGEST_LENGTH; i++)
+		sprintf(&(buf[i*2]),"%02x",md[i]);
+	return(buf);
+	}
+#endif
+#endif
diff --git a/openssl/crypto/ia64cpuid.S b/openssl/crypto/ia64cpuid.S
new file mode 100644
index 0000000..d705fff
--- /dev/null
+++ b/openssl/crypto/ia64cpuid.S
@@ -0,0 +1,167 @@
+// Works on all IA-64 platforms: Linux, HP-UX, Win64i...
+// On Win64i compile with ias.exe.
+.text
+
+.global	OPENSSL_cpuid_setup#
+.proc	OPENSSL_cpuid_setup#
+OPENSSL_cpuid_setup:
+{ .mib;	br.ret.sptk.many	b0		};;
+.endp	OPENSSL_cpuid_setup#
+
+.global	OPENSSL_rdtsc#
+.proc	OPENSSL_rdtsc#
+OPENSSL_rdtsc:
+{ .mib;	mov			r8=ar.itc
+	br.ret.sptk.many	b0		};;
+.endp   OPENSSL_rdtsc#
+
+.global	OPENSSL_atomic_add#
+.proc	OPENSSL_atomic_add#
+.align	32
+OPENSSL_atomic_add:
+{ .mii;	ld4		r2=[r32]
+	nop.i		0
+	nop.i		0		};;
+.Lspin:
+{ .mii;	mov		ar.ccv=r2
+	add		r8=r2,r33
+	mov		r3=r2		};;
+{ .mmi;	mf
+	cmpxchg4.acq	r2=[r32],r8,ar.ccv
+	nop.i		0		};;
+{ .mib;	cmp.ne		p6,p0=r2,r3
+	nop.i		0
+(p6)	br.dpnt		.Lspin		};;
+{ .mib;	nop.m		0
+	sxt4		r8=r8
+	br.ret.sptk.many	b0	};;
+.endp	OPENSSL_atomic_add#
+
+// Returns a structure comprising pointer to the top of stack of
+// the caller and pointer beyond backing storage for the current
+// register frame. The latter is required, because it might be
+// insufficient to wipe backing storage for the current frame
+// (as this procedure does), one might have to go further, toward
+// higher addresses to reach for whole "retroactively" saved
+// context...
+.global	OPENSSL_wipe_cpu#
+.proc	OPENSSL_wipe_cpu#
+.align	32
+OPENSSL_wipe_cpu:
+	.prologue
+	.fframe	0
+	.save	ar.pfs,r2
+	.save	ar.lc,r3
+{ .mib;	alloc		r2=ar.pfs,0,96,0,96
+	mov		r3=ar.lc
+	brp.loop.imp	.L_wipe_top,.L_wipe_end-16
+					};;
+{ .mii;	mov		r9=ar.bsp
+	mov		r8=pr
+	mov		ar.lc=96	};;
+	.body
+{ .mii;	add		r9=96*8-8,r9
+	mov		ar.ec=1		};;
+
+// One can sweep double as fast, but then we can't quarantee
+// that backing storage is wiped...
+.L_wipe_top:
+{ .mfi;	st8		[r9]=r0,-8
+	mov		f127=f0
+	mov		r127=r0		}
+{ .mfb;	nop.m		0
+	nop.f		0
+	br.ctop.sptk	.L_wipe_top	};;
+.L_wipe_end:
+
+{ .mfi;	mov		r11=r0
+	mov		f6=f0
+	mov		r14=r0		}
+{ .mfi;	mov		r15=r0
+	mov		f7=f0
+	mov		r16=r0		}
+{ .mfi;	mov		r17=r0
+	mov		f8=f0
+	mov		r18=r0		}
+{ .mfi;	mov		r19=r0
+	mov		f9=f0
+	mov		r20=r0		}
+{ .mfi;	mov		r21=r0
+	mov		f10=f0
+	mov		r22=r0		}
+{ .mfi;	mov		r23=r0
+	mov		f11=f0
+	mov		r24=r0		}
+{ .mfi;	mov		r25=r0
+	mov		f12=f0
+	mov		r26=r0		}
+{ .mfi;	mov		r27=r0
+	mov		f13=f0
+	mov		r28=r0		}
+{ .mfi;	mov		r29=r0
+	mov		f14=f0
+	mov		r30=r0		}
+{ .mfi;	mov		r31=r0
+	mov		f15=f0
+	nop.i		0		}
+{ .mfi;	mov		f16=f0		}
+{ .mfi;	mov		f17=f0		}
+{ .mfi;	mov		f18=f0		}
+{ .mfi;	mov		f19=f0		}
+{ .mfi;	mov		f20=f0		}
+{ .mfi;	mov		f21=f0		}
+{ .mfi;	mov		f22=f0		}
+{ .mfi;	mov		f23=f0		}
+{ .mfi;	mov		f24=f0		}
+{ .mfi;	mov		f25=f0		}
+{ .mfi;	mov		f26=f0		}
+{ .mfi;	mov		f27=f0		}
+{ .mfi;	mov		f28=f0		}
+{ .mfi;	mov		f29=f0		}
+{ .mfi;	mov		f30=f0		}
+{ .mfi;	add		r9=96*8+8,r9
+	mov		f31=f0
+	mov		pr=r8,0x1ffff	}
+{ .mib;	mov		r8=sp
+	mov		ar.lc=r3
+	br.ret.sptk	b0		};;
+.endp	OPENSSL_wipe_cpu#
+
+.global	OPENSSL_cleanse#
+.proc	OPENSSL_cleanse#
+OPENSSL_cleanse:
+{ .mib;	cmp.eq		p6,p0=0,r33	    // len==0
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+	addp4		r32=0,r32
+#endif
+(p6)	br.ret.spnt	b0		};;
+{ .mib;	and		r2=7,r32
+	cmp.leu		p6,p0=15,r33	    // len>=15
+(p6)	br.cond.dptk	.Lot		};;
+
+.Little:
+{ .mib;	st1		[r32]=r0,1
+	cmp.ltu		p6,p7=1,r33	}  // len>1
+{ .mbb;	add		r33=-1,r33	   // len--
+(p6)	br.cond.dptk	.Little
+(p7)	br.ret.sptk.many	b0	};;
+
+.Lot:
+{ .mib;	cmp.eq		p6,p0=0,r2
+(p6)	br.cond.dptk	.Laligned	};;
+{ .mmi;	st1		[r32]=r0,1;;
+	and		r2=7,r32	}
+{ .mib;	add		r33=-1,r33
+	br		.Lot		};;
+
+.Laligned:
+{ .mmi;	st8		[r32]=r0,8
+	and		r2=-8,r33	    // len&~7
+	add		r33=-8,r33	};; // len-=8
+{ .mib;	cmp.ltu		p6,p0=8,r2	    // ((len+8)&~7)>8
+(p6)	br.cond.dptk	.Laligned	};;
+
+{ .mbb;	cmp.eq		p6,p7=r0,r33
+(p7)	br.cond.dpnt	.Little
+(p6)	br.ret.sptk.many	b0	};;
+.endp	OPENSSL_cleanse#
diff --git a/openssl/crypto/idea/Makefile b/openssl/crypto/idea/Makefile
new file mode 100644
index 0000000..b2e7add
--- /dev/null
+++ b/openssl/crypto/idea/Makefile
@@ -0,0 +1,86 @@
+#
+# OpenSSL/crypto/idea/Makefile
+#
+
+DIR=	idea
+TOP=	../..
+CC=	cc
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=ideatest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=i_cbc.c i_cfb64.c i_ofb64.c i_ecb.c i_skey.c
+LIBOBJ=i_cbc.o i_cfb64.o i_ofb64.o i_ecb.o i_skey.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= idea.h
+HEADER=	idea_lcl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+i_cbc.o: ../../include/openssl/idea.h ../../include/openssl/opensslconf.h
+i_cbc.o: i_cbc.c idea_lcl.h
+i_cfb64.o: ../../include/openssl/idea.h ../../include/openssl/opensslconf.h
+i_cfb64.o: i_cfb64.c idea_lcl.h
+i_ecb.o: ../../include/openssl/idea.h ../../include/openssl/opensslconf.h
+i_ecb.o: ../../include/openssl/opensslv.h i_ecb.c idea_lcl.h
+i_ofb64.o: ../../include/openssl/idea.h ../../include/openssl/opensslconf.h
+i_ofb64.o: i_ofb64.c idea_lcl.h
+i_skey.o: ../../include/openssl/idea.h ../../include/openssl/opensslconf.h
+i_skey.o: i_skey.c idea_lcl.h
diff --git a/openssl/crypto/idea/i_cbc.c b/openssl/crypto/idea/i_cbc.c
new file mode 100644
index 0000000..ecb9cb8
--- /dev/null
+++ b/openssl/crypto/idea/i_cbc.c
@@ -0,0 +1,168 @@
+/* crypto/idea/i_cbc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/idea.h>
+#include "idea_lcl.h"
+
+void idea_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+	     IDEA_KEY_SCHEDULE *ks, unsigned char *iv, int encrypt)
+	{
+	register unsigned long tin0,tin1;
+	register unsigned long tout0,tout1,xor0,xor1;
+	register long l=length;
+	unsigned long tin[2];
+
+	if (encrypt)
+		{
+		n2l(iv,tout0);
+		n2l(iv,tout1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			n2l(in,tin0);
+			n2l(in,tin1);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			idea_encrypt(tin,ks);
+			tout0=tin[0]; l2n(tout0,out);
+			tout1=tin[1]; l2n(tout1,out);
+			}
+		if (l != -8)
+			{
+			n2ln(in,tin0,tin1,l+8);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			idea_encrypt(tin,ks);
+			tout0=tin[0]; l2n(tout0,out);
+			tout1=tin[1]; l2n(tout1,out);
+			}
+		l2n(tout0,iv);
+		l2n(tout1,iv);
+		}
+	else
+		{
+		n2l(iv,xor0);
+		n2l(iv,xor1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			n2l(in,tin0); tin[0]=tin0;
+			n2l(in,tin1); tin[1]=tin1;
+			idea_encrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2n(tout0,out);
+			l2n(tout1,out);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		if (l != -8)
+			{
+			n2l(in,tin0); tin[0]=tin0;
+			n2l(in,tin1); tin[1]=tin1;
+			idea_encrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2nn(tout0,tout1,out,l+8);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		l2n(xor0,iv);
+		l2n(xor1,iv);
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	tin[0]=tin[1]=0;
+	}
+
+void idea_encrypt(unsigned long *d, IDEA_KEY_SCHEDULE *key)
+	{
+	register IDEA_INT *p;
+	register unsigned long x1,x2,x3,x4,t0,t1,ul;
+
+	x2=d[0];
+	x1=(x2>>16);
+	x4=d[1];
+	x3=(x4>>16);
+
+	p= &(key->data[0][0]);
+
+	E_IDEA(0);
+	E_IDEA(1);
+	E_IDEA(2);
+	E_IDEA(3);
+	E_IDEA(4);
+	E_IDEA(5);
+	E_IDEA(6);
+	E_IDEA(7);
+
+	x1&=0xffff;
+	idea_mul(x1,x1,*p,ul); p++;
+
+	t0= x3+ *(p++);
+	t1= x2+ *(p++);
+
+	x4&=0xffff;
+	idea_mul(x4,x4,*p,ul);
+
+	d[0]=(t0&0xffff)|((x1&0xffff)<<16);
+	d[1]=(x4&0xffff)|((t1&0xffff)<<16);
+	}
diff --git a/openssl/crypto/idea/i_cfb64.c b/openssl/crypto/idea/i_cfb64.c
new file mode 100644
index 0000000..66d49d5
--- /dev/null
+++ b/openssl/crypto/idea/i_cfb64.c
@@ -0,0 +1,122 @@
+/* crypto/idea/i_cfb64.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/idea.h>
+#include "idea_lcl.h"
+
+/* The input and output encrypted as though 64bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+
+void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+			long length, IDEA_KEY_SCHEDULE *schedule,
+			unsigned char *ivec, int *num, int encrypt)
+	{
+	register unsigned long v0,v1,t;
+	register int n= *num;
+	register long l=length;
+	unsigned long ti[2];
+	unsigned char *iv,c,cc;
+
+	iv=(unsigned char *)ivec;
+	if (encrypt)
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				n2l(iv,v0); ti[0]=v0;
+				n2l(iv,v1); ti[1]=v1;
+				idea_encrypt((unsigned long *)ti,schedule);
+				iv=(unsigned char *)ivec;
+				t=ti[0]; l2n(t,iv);
+				t=ti[1]; l2n(t,iv);
+				iv=(unsigned char *)ivec;
+				}
+			c= *(in++)^iv[n];
+			*(out++)=c;
+			iv[n]=c;
+			n=(n+1)&0x07;
+			}
+		}
+	else
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				n2l(iv,v0); ti[0]=v0;
+				n2l(iv,v1); ti[1]=v1;
+				idea_encrypt((unsigned long *)ti,schedule);
+				iv=(unsigned char *)ivec;
+				t=ti[0]; l2n(t,iv);
+				t=ti[1]; l2n(t,iv);
+				iv=(unsigned char *)ivec;
+				}
+			cc= *(in++);
+			c=iv[n];
+			iv[n]=cc;
+			*(out++)=c^cc;
+			n=(n+1)&0x07;
+			}
+		}
+	v0=v1=ti[0]=ti[1]=t=c=cc=0;
+	*num=n;
+	}
+
diff --git a/openssl/crypto/idea/i_ecb.c b/openssl/crypto/idea/i_ecb.c
new file mode 100644
index 0000000..fef3823
--- /dev/null
+++ b/openssl/crypto/idea/i_ecb.c
@@ -0,0 +1,85 @@
+/* crypto/idea/i_ecb.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/idea.h>
+#include "idea_lcl.h"
+#include <openssl/opensslv.h>
+
+const char IDEA_version[]="IDEA" OPENSSL_VERSION_PTEXT;
+
+const char *idea_options(void)
+	{
+	if (sizeof(short) != sizeof(IDEA_INT))
+		return("idea(int)");
+	else
+		return("idea(short)");
+	}
+
+void idea_ecb_encrypt(const unsigned char *in, unsigned char *out,
+	     IDEA_KEY_SCHEDULE *ks)
+	{
+	unsigned long l0,l1,d[2];
+
+	n2l(in,l0); d[0]=l0;
+	n2l(in,l1); d[1]=l1;
+	idea_encrypt(d,ks);
+	l0=d[0]; l2n(l0,out);
+	l1=d[1]; l2n(l1,out);
+	l0=l1=d[0]=d[1]=0;
+	}
+
diff --git a/openssl/crypto/idea/i_ofb64.c b/openssl/crypto/idea/i_ofb64.c
new file mode 100644
index 0000000..e749e88
--- /dev/null
+++ b/openssl/crypto/idea/i_ofb64.c
@@ -0,0 +1,111 @@
+/* crypto/idea/i_ofb64.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/idea.h>
+#include "idea_lcl.h"
+
+/* The input and output encrypted as though 64bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+			long length, IDEA_KEY_SCHEDULE *schedule,
+			unsigned char *ivec, int *num)
+	{
+	register unsigned long v0,v1,t;
+	register int n= *num;
+	register long l=length;
+	unsigned char d[8];
+	register char *dp;
+	unsigned long ti[2];
+	unsigned char *iv;
+	int save=0;
+
+	iv=(unsigned char *)ivec;
+	n2l(iv,v0);
+	n2l(iv,v1);
+	ti[0]=v0;
+	ti[1]=v1;
+	dp=(char *)d;
+	l2n(v0,dp);
+	l2n(v1,dp);
+	while (l--)
+		{
+		if (n == 0)
+			{
+			idea_encrypt((unsigned long *)ti,schedule);
+			dp=(char *)d;
+			t=ti[0]; l2n(t,dp);
+			t=ti[1]; l2n(t,dp);
+			save++;
+			}
+		*(out++)= *(in++)^d[n];
+		n=(n+1)&0x07;
+		}
+	if (save)
+		{
+		v0=ti[0];
+		v1=ti[1];
+		iv=(unsigned char *)ivec;
+		l2n(v0,iv);
+		l2n(v1,iv);
+		}
+	t=v0=v1=ti[0]=ti[1]=0;
+	*num=n;
+	}
+
diff --git a/openssl/crypto/idea/i_skey.c b/openssl/crypto/idea/i_skey.c
new file mode 100644
index 0000000..1c95bc9
--- /dev/null
+++ b/openssl/crypto/idea/i_skey.c
@@ -0,0 +1,156 @@
+/* crypto/idea/i_skey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/idea.h>
+#include "idea_lcl.h"
+
+static IDEA_INT inverse(unsigned int xin);
+void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks)
+	{
+	int i;
+	register IDEA_INT *kt,*kf,r0,r1,r2;
+
+	kt= &(ks->data[0][0]);
+	n2s(key,kt[0]); n2s(key,kt[1]); n2s(key,kt[2]); n2s(key,kt[3]);
+	n2s(key,kt[4]); n2s(key,kt[5]); n2s(key,kt[6]); n2s(key,kt[7]);
+
+	kf=kt;
+	kt+=8;
+	for (i=0; i<6; i++)
+		{
+		r2= kf[1];
+		r1= kf[2];
+		*(kt++)= ((r2<<9) | (r1>>7))&0xffff;
+		r0= kf[3];
+		*(kt++)= ((r1<<9) | (r0>>7))&0xffff;
+		r1= kf[4];
+		*(kt++)= ((r0<<9) | (r1>>7))&0xffff;
+		r0= kf[5];
+		*(kt++)= ((r1<<9) | (r0>>7))&0xffff;
+		r1= kf[6];
+		*(kt++)= ((r0<<9) | (r1>>7))&0xffff;
+		r0= kf[7];
+		*(kt++)= ((r1<<9) | (r0>>7))&0xffff;
+		r1= kf[0];
+		if (i >= 5) break;
+		*(kt++)= ((r0<<9) | (r1>>7))&0xffff;
+		*(kt++)= ((r1<<9) | (r2>>7))&0xffff;
+		kf+=8;
+		}
+	}
+
+void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk)
+	{
+	int r;
+	register IDEA_INT *fp,*tp,t;
+
+	tp= &(dk->data[0][0]);
+	fp= &(ek->data[8][0]);
+	for (r=0; r<9; r++)
+		{
+		*(tp++)=inverse(fp[0]);
+		*(tp++)=((int)(0x10000L-fp[2])&0xffff);
+		*(tp++)=((int)(0x10000L-fp[1])&0xffff);
+		*(tp++)=inverse(fp[3]);
+		if (r == 8) break;
+		fp-=6;
+		*(tp++)=fp[4];
+		*(tp++)=fp[5];
+		}
+
+	tp= &(dk->data[0][0]);
+	t=tp[1];
+	tp[1]=tp[2];
+	tp[2]=t;
+
+	t=tp[49];
+	tp[49]=tp[50];
+	tp[50]=t;
+	}
+
+/* taken directly from the 'paper' I'll have a look at it later */
+static IDEA_INT inverse(unsigned int xin)
+	{
+	long n1,n2,q,r,b1,b2,t;
+
+	if (xin == 0)
+		b2=0;
+	else
+		{
+		n1=0x10001;
+		n2=xin;
+		b2=1;
+		b1=0;
+
+		do	{
+			r=(n1%n2);
+			q=(n1-r)/n2;
+			if (r == 0)
+				{ if (b2 < 0) b2=0x10001+b2; }
+			else
+				{
+				n1=n2;
+				n2=r;
+				t=b2;
+				b2=b1-q*b2;
+				b1=t;
+				}
+			} while (r != 0);
+		}
+	return((IDEA_INT)b2);
+	}
diff --git a/openssl/crypto/idea/idea.h b/openssl/crypto/idea/idea.h
new file mode 100644
index 0000000..5782e54
--- /dev/null
+++ b/openssl/crypto/idea/idea.h
@@ -0,0 +1,100 @@
+/* crypto/idea/idea.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_IDEA_H
+#define HEADER_IDEA_H
+
+#include <openssl/opensslconf.h> /* IDEA_INT, OPENSSL_NO_IDEA */
+
+#ifdef OPENSSL_NO_IDEA
+#error IDEA is disabled.
+#endif
+
+#define IDEA_ENCRYPT	1
+#define IDEA_DECRYPT	0
+
+#define IDEA_BLOCK	8
+#define IDEA_KEY_LENGTH	16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct idea_key_st
+	{
+	IDEA_INT data[9][6];
+	} IDEA_KEY_SCHEDULE;
+
+const char *idea_options(void);
+void idea_ecb_encrypt(const unsigned char *in, unsigned char *out,
+	IDEA_KEY_SCHEDULE *ks);
+void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks);
+void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk);
+void idea_cbc_encrypt(const unsigned char *in, unsigned char *out,
+	long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,int enc);
+void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+	long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,
+	int *num,int enc);
+void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+	long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, int *num);
+void idea_encrypt(unsigned long *in, IDEA_KEY_SCHEDULE *ks);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/idea/idea_lcl.h b/openssl/crypto/idea/idea_lcl.h
new file mode 100644
index 0000000..f3dbfa6
--- /dev/null
+++ b/openssl/crypto/idea/idea_lcl.h
@@ -0,0 +1,215 @@
+/* crypto/idea/idea_lcl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* The new form of this macro (check if the a*b == 0) was suggested by 
+ * Colin Plumb <colin@nyx10.cs.du.edu> */
+/* Removal of the inner if from from Wei Dai 24/4/96 */
+#define idea_mul(r,a,b,ul) \
+ul=(unsigned long)a*b; \
+if (ul != 0) \
+	{ \
+	r=(ul&0xffff)-(ul>>16); \
+	r-=((r)>>16); \
+	} \
+else \
+	r=(-(int)a-b+1); /* assuming a or b is 0 and in range */ 
+
+#ifdef undef
+#define idea_mul(r,a,b,ul,sl) \
+if (a == 0) r=(0x10001-b)&0xffff; \
+else if (b == 0) r=(0x10001-a)&0xffff; \
+else	{ \
+	ul=(unsigned long)a*b; \
+	sl=(ul&0xffff)-(ul>>16); \
+	if (sl <= 0) sl+=0x10001; \
+	r=sl; \
+	} 
+#endif
+
+/*  7/12/95 - Many thanks to Rhys Weatherley <rweather@us.oracle.com>
+ * for pointing out that I was assuming little endian
+ * byte order for all quantities what idea
+ * actually used bigendian.  No where in the spec does it mention
+ * this, it is all in terms of 16 bit numbers and even the example
+ * does not use byte streams for the input example :-(.
+ * If you byte swap each pair of input, keys and iv, the functions
+ * would produce the output as the old version :-(.
+ */
+
+/* NOTE - c is not incremented as per n2l */
+#define n2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))    ; \
+			case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
+			case 6: l2|=((unsigned long)(*(--(c))))<<16; \
+			case 5: l2|=((unsigned long)(*(--(c))))<<24; \
+			case 4: l1 =((unsigned long)(*(--(c))))    ; \
+			case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
+			case 2: l1|=((unsigned long)(*(--(c))))<<16; \
+			case 1: l1|=((unsigned long)(*(--(c))))<<24; \
+				} \
+			}
+
+/* NOTE - c is not incremented as per l2n */
+#define l2nn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+				} \
+			}
+
+#undef n2l
+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++))))
+
+#undef l2n
+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)     )&0xff))
+
+#undef s2n
+#define s2n(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff))
+
+#undef n2s
+#define n2s(c,l)	(l =((IDEA_INT)(*((c)++)))<< 8L, \
+			 l|=((IDEA_INT)(*((c)++)))      )
+
+#ifdef undef
+/* NOTE - c is not incremented as per c2l */
+#define c2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))<<24; \
+			case 7: l2|=((unsigned long)(*(--(c))))<<16; \
+			case 6: l2|=((unsigned long)(*(--(c))))<< 8; \
+			case 5: l2|=((unsigned long)(*(--(c))));     \
+			case 4: l1 =((unsigned long)(*(--(c))))<<24; \
+			case 3: l1|=((unsigned long)(*(--(c))))<<16; \
+			case 2: l1|=((unsigned long)(*(--(c))))<< 8; \
+			case 1: l1|=((unsigned long)(*(--(c))));     \
+				} \
+			}
+
+/* NOTE - c is not incremented as per l2c */
+#define l2cn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+				} \
+			}
+
+#undef c2s
+#define c2s(c,l)	(l =((unsigned long)(*((c)++)))    , \
+			 l|=((unsigned long)(*((c)++)))<< 8L)
+
+#undef s2c
+#define s2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff))
+
+#undef c2l
+#define c2l(c,l)	(l =((unsigned long)(*((c)++)))     , \
+			 l|=((unsigned long)(*((c)++)))<< 8L, \
+			 l|=((unsigned long)(*((c)++)))<<16L, \
+			 l|=((unsigned long)(*((c)++)))<<24L)
+
+#undef l2c
+#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+#endif
+
+#define E_IDEA(num) \
+	x1&=0xffff; \
+	idea_mul(x1,x1,*p,ul); p++; \
+	x2+= *(p++); \
+	x3+= *(p++); \
+	x4&=0xffff; \
+	idea_mul(x4,x4,*p,ul); p++; \
+	t0=(x1^x3)&0xffff; \
+	idea_mul(t0,t0,*p,ul); p++; \
+	t1=(t0+(x2^x4))&0xffff; \
+	idea_mul(t1,t1,*p,ul); p++; \
+	t0+=t1; \
+	x1^=t1; \
+	x4^=t0; \
+	ul=x2^t0; /* do the swap to x3 */ \
+	x2=x3^t1; \
+	x3=ul;
+
diff --git a/openssl/crypto/idea/idea_spd.c b/openssl/crypto/idea/idea_spd.c
new file mode 100644
index 0000000..699353e
--- /dev/null
+++ b/openssl/crypto/idea/idea_spd.c
@@ -0,0 +1,299 @@
+/* crypto/idea/idea_spd.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
+/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
+
+#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
+#define TIMES
+#endif
+
+#include <stdio.h>
+
+#include <openssl/e_os2.h>
+#include OPENSSL_UNISTD_IO
+OPENSSL_DECLARE_EXIT
+
+#ifndef OPENSSL_SYS_NETWARE
+#include <signal.h>
+#endif
+
+#ifndef _IRIX
+#include <time.h>
+#endif
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+#endif
+
+/* Depending on the VMS version, the tms structure is perhaps defined.
+   The __TMS macro will show if it was.  If it wasn't defined, we should
+   undefine TIMES, since that tells the rest of the program how things
+   should be handled.				-- Richard Levitte */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
+#undef TIMES
+#endif
+
+#ifndef TIMES
+#include <sys/timeb.h>
+#endif
+
+#if defined(sun) || defined(__ultrix)
+#define _POSIX_SOURCE
+#include <limits.h>
+#include <sys/param.h>
+#endif
+
+#include <openssl/idea.h>
+
+/* The following if from times(3) man page.  It may need to be changed */
+#ifndef HZ
+#ifndef CLK_TCK
+#define HZ	100.0
+#else /* CLK_TCK */
+#define HZ ((double)CLK_TCK)
+#endif
+#endif
+
+#define BUFSIZE	((long)1024)
+long run=0;
+
+double Time_F(int s);
+#ifdef SIGALRM
+#if defined(__STDC__) || defined(sgi) || defined(_AIX)
+#define SIGRETTYPE void
+#else
+#define SIGRETTYPE int
+#endif
+
+SIGRETTYPE sig_done(int sig);
+SIGRETTYPE sig_done(int sig)
+	{
+	signal(SIGALRM,sig_done);
+	run=0;
+#ifdef LINT
+	sig=sig;
+#endif
+	}
+#endif
+
+#define START	0
+#define STOP	1
+
+double Time_F(int s)
+	{
+	double ret;
+#ifdef TIMES
+	static struct tms tstart,tend;
+
+	if (s == START)
+		{
+		times(&tstart);
+		return(0);
+		}
+	else
+		{
+		times(&tend);
+		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#else /* !times() */
+	static struct timeb tstart,tend;
+	long i;
+
+	if (s == START)
+		{
+		ftime(&tstart);
+		return(0);
+		}
+	else
+		{
+		ftime(&tend);
+		i=(long)tend.millitm-(long)tstart.millitm;
+		ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#endif
+	}
+
+int main(int argc, char **argv)
+	{
+	long count;
+	static unsigned char buf[BUFSIZE];
+	static unsigned char key[] ={
+			0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+			0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
+			};
+	IDEA_KEY_SCHEDULE sch;
+	double a,aa,b,c,d;
+#ifndef SIGALRM
+	long ca,cca,cb,cc;
+#endif
+
+#ifndef TIMES
+	printf("To get the most accurate results, try to run this\n");
+	printf("program when this computer is idle.\n");
+#endif
+
+#ifndef SIGALRM
+	printf("First we calculate the approximate speed ...\n");
+	idea_set_encrypt_key(key,&sch);
+	count=10;
+	do	{
+		long i;
+		IDEA_INT data[2];
+
+		count*=2;
+		Time_F(START);
+		for (i=count; i; i--)
+			idea_encrypt(data,&sch);
+		d=Time_F(STOP);
+		} while (d < 3.0);
+	ca=count/4;
+	cca=count/200;
+	cb=count;
+	cc=count*8/BUFSIZE+1;
+	printf("idea_set_encrypt_key %ld times\n",ca);
+#define COND(d)	(count <= (d))
+#define COUNT(d) (d)
+#else
+#define COND(c)	(run)
+#define COUNT(d) (count)
+	signal(SIGALRM,sig_done);
+	printf("Doing idea_set_encrypt_key for 10 seconds\n");
+	alarm(10);
+#endif
+
+	Time_F(START);
+	for (count=0,run=1; COND(ca); count+=4)
+		{
+		idea_set_encrypt_key(key,&sch);
+		idea_set_encrypt_key(key,&sch);
+		idea_set_encrypt_key(key,&sch);
+		idea_set_encrypt_key(key,&sch);
+		}
+	d=Time_F(STOP);
+	printf("%ld idea idea_set_encrypt_key's in %.2f seconds\n",count,d);
+	a=((double)COUNT(ca))/d;
+
+#ifdef SIGALRM
+	printf("Doing idea_set_decrypt_key for 10 seconds\n");
+	alarm(10);
+#else
+	printf("Doing idea_set_decrypt_key %ld times\n",cca);
+#endif
+
+	Time_F(START);
+	for (count=0,run=1; COND(cca); count+=4)
+		{
+		idea_set_decrypt_key(&sch,&sch);
+		idea_set_decrypt_key(&sch,&sch);
+		idea_set_decrypt_key(&sch,&sch);
+		idea_set_decrypt_key(&sch,&sch);
+		}
+	d=Time_F(STOP);
+	printf("%ld idea idea_set_decrypt_key's in %.2f seconds\n",count,d);
+	aa=((double)COUNT(cca))/d;
+
+#ifdef SIGALRM
+	printf("Doing idea_encrypt's for 10 seconds\n");
+	alarm(10);
+#else
+	printf("Doing idea_encrypt %ld times\n",cb);
+#endif
+	Time_F(START);
+	for (count=0,run=1; COND(cb); count+=4)
+		{
+		unsigned long data[2];
+
+		idea_encrypt(data,&sch);
+		idea_encrypt(data,&sch);
+		idea_encrypt(data,&sch);
+		idea_encrypt(data,&sch);
+		}
+	d=Time_F(STOP);
+	printf("%ld idea_encrypt's in %.2f second\n",count,d);
+	b=((double)COUNT(cb)*8)/d;
+
+#ifdef SIGALRM
+	printf("Doing idea_cbc_encrypt on %ld byte blocks for 10 seconds\n",
+		BUFSIZE);
+	alarm(10);
+#else
+	printf("Doing idea_cbc_encrypt %ld times on %ld byte blocks\n",cc,
+		BUFSIZE);
+#endif
+	Time_F(START);
+	for (count=0,run=1; COND(cc); count++)
+		idea_cbc_encrypt(buf,buf,BUFSIZE,&sch,
+			&(key[0]),IDEA_ENCRYPT);
+	d=Time_F(STOP);
+	printf("%ld idea_cbc_encrypt's of %ld byte blocks in %.2f second\n",
+		count,BUFSIZE,d);
+	c=((double)COUNT(cc)*BUFSIZE)/d;
+
+	printf("IDEA set_encrypt_key per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a);
+	printf("IDEA set_decrypt_key per sec = %12.2f (%9.3fuS)\n",aa,1.0e6/aa);
+	printf("IDEA raw ecb bytes   per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b);
+	printf("IDEA cbc     bytes   per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c);
+	exit(0);
+#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
+	return(0);
+#endif
+	}
+
diff --git a/openssl/crypto/idea/ideatest.c b/openssl/crypto/idea/ideatest.c
new file mode 100644
index 0000000..e6ffc70
--- /dev/null
+++ b/openssl/crypto/idea/ideatest.c
@@ -0,0 +1,235 @@
+/* crypto/idea/ideatest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_IDEA
+int main(int argc, char *argv[])
+{
+    printf("No IDEA support\n");
+    return(0);
+}
+#else
+#include <openssl/idea.h>
+
+unsigned char k[16]={
+	0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,
+	0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08};
+
+unsigned char in[8]={0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x03};
+unsigned char  c[8]={0x11,0xFB,0xED,0x2B,0x01,0x98,0x6D,0xE5};
+unsigned char out[80];
+
+char *text="Hello to all people out there";
+
+static unsigned char cfb_key[16]={
+	0xe1,0xf0,0xc3,0xd2,0xa5,0xb4,0x87,0x96,
+	0x69,0x78,0x4b,0x5a,0x2d,0x3c,0x0f,0x1e,
+	};
+static unsigned char cfb_iv[80]={0x34,0x12,0x78,0x56,0xab,0x90,0xef,0xcd};
+static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
+#define CFB_TEST_SIZE 24
+static unsigned char plain[CFB_TEST_SIZE]=
+        {
+        0x4e,0x6f,0x77,0x20,0x69,0x73,
+        0x20,0x74,0x68,0x65,0x20,0x74,
+        0x69,0x6d,0x65,0x20,0x66,0x6f,
+        0x72,0x20,0x61,0x6c,0x6c,0x20
+        };
+static unsigned char cfb_cipher64[CFB_TEST_SIZE]={
+	0x59,0xD8,0xE2,0x65,0x00,0x58,0x6C,0x3F,
+	0x2C,0x17,0x25,0xD0,0x1A,0x38,0xB7,0x2A,
+	0x39,0x61,0x37,0xDC,0x79,0xFB,0x9F,0x45
+
+/*	0xF9,0x78,0x32,0xB5,0x42,0x1A,0x6B,0x38,
+	0x9A,0x44,0xD6,0x04,0x19,0x43,0xC4,0xD9,
+	0x3D,0x1E,0xAE,0x47,0xFC,0xCF,0x29,0x0B,*/
+	}; 
+
+static int cfb64_test(unsigned char *cfb_cipher);
+static char *pt(unsigned char *p);
+int main(int argc, char *argv[])
+	{
+	int i,err=0;
+	IDEA_KEY_SCHEDULE key,dkey; 
+	unsigned char iv[8];
+
+	idea_set_encrypt_key(k,&key);
+	idea_ecb_encrypt(in,out,&key);
+	if (memcmp(out,c,8) != 0)
+		{
+		printf("ecb idea error encrypting\n");
+		printf("got     :");
+		for (i=0; i<8; i++)
+			printf("%02X ",out[i]);
+		printf("\n");
+		printf("expected:");
+		for (i=0; i<8; i++)
+			printf("%02X ",c[i]);
+		err=20;
+		printf("\n");
+		}
+
+	idea_set_decrypt_key(&key,&dkey);
+	idea_ecb_encrypt(c,out,&dkey);
+	if (memcmp(out,in,8) != 0)
+		{
+		printf("ecb idea error decrypting\n");
+		printf("got     :");
+		for (i=0; i<8; i++)
+			printf("%02X ",out[i]);
+		printf("\n");
+		printf("expected:");
+		for (i=0; i<8; i++)
+			printf("%02X ",in[i]);
+		printf("\n");
+		err=3;
+		}
+
+	if (err == 0) printf("ecb idea ok\n");
+
+	memcpy(iv,k,8);
+	idea_cbc_encrypt((unsigned char *)text,out,strlen(text)+1,&key,iv,1);
+	memcpy(iv,k,8);
+	idea_cbc_encrypt(out,out,8,&dkey,iv,0);
+	idea_cbc_encrypt(&(out[8]),&(out[8]),strlen(text)+1-8,&dkey,iv,0);
+	if (memcmp(text,out,strlen(text)+1) != 0)
+		{
+		printf("cbc idea bad\n");
+		err=4;
+		}
+	else
+		printf("cbc idea ok\n");
+
+	printf("cfb64 idea ");
+	if (cfb64_test(cfb_cipher64))
+		{
+		printf("bad\n");
+		err=5;
+		}
+	else
+		printf("ok\n");
+
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
+	EXIT(err);
+	return(err);
+	}
+
+static int cfb64_test(unsigned char *cfb_cipher)
+        {
+        IDEA_KEY_SCHEDULE eks,dks;
+        int err=0,i,n;
+
+        idea_set_encrypt_key(cfb_key,&eks);
+        idea_set_decrypt_key(&eks,&dks);
+        memcpy(cfb_tmp,cfb_iv,8);
+        n=0;
+        idea_cfb64_encrypt(plain,cfb_buf1,(long)12,&eks,
+                cfb_tmp,&n,IDEA_ENCRYPT);
+        idea_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
+                (long)CFB_TEST_SIZE-12,&eks,
+                cfb_tmp,&n,IDEA_ENCRYPT);
+        if (memcmp(cfb_cipher,cfb_buf1,CFB_TEST_SIZE) != 0)
+                {
+                err=1;
+                printf("idea_cfb64_encrypt encrypt error\n");
+                for (i=0; i<CFB_TEST_SIZE; i+=8)
+                        printf("%s\n",pt(&(cfb_buf1[i])));
+                }
+        memcpy(cfb_tmp,cfb_iv,8);
+        n=0;
+        idea_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,&eks,
+                cfb_tmp,&n,IDEA_DECRYPT);
+        idea_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
+                (long)CFB_TEST_SIZE-17,&dks,
+                cfb_tmp,&n,IDEA_DECRYPT);
+        if (memcmp(plain,cfb_buf2,CFB_TEST_SIZE) != 0)
+                {
+                err=1;
+                printf("idea_cfb_encrypt decrypt error\n");
+                for (i=0; i<24; i+=8)
+                        printf("%s\n",pt(&(cfb_buf2[i])));
+                }
+        return(err);
+        }
+
+static char *pt(unsigned char *p)
+	{
+	static char bufs[10][20];
+	static int bnum=0;
+	char *ret;
+	int i;
+	static char *f="0123456789ABCDEF";
+
+	ret= &(bufs[bnum++][0]);
+	bnum%=10;
+	for (i=0; i<8; i++)
+		{
+		ret[i*2]=f[(p[i]>>4)&0xf];
+		ret[i*2+1]=f[p[i]&0xf];
+		}
+	ret[16]='\0';
+	return(ret);
+	}
+#endif
diff --git a/openssl/crypto/idea/version b/openssl/crypto/idea/version
new file mode 100644
index 0000000..3f22293
--- /dev/null
+++ b/openssl/crypto/idea/version
@@ -0,0 +1,12 @@
+1.1 07/12/95 - eay
+	Many thanks to Rhys Weatherley <rweather@us.oracle.com>
+	for pointing out that I was assuming little endian byte
+	order for all quantities what idea actually used
+	bigendian.  No where in the spec does it mention
+	this, it is all in terms of 16 bit numbers and even the example
+	does not use byte streams for the input example :-(.
+	If you byte swap each pair of input, keys and iv, the functions
+	would produce the output as the old version :-(.
+
+1.0 ??/??/95 - eay
+	First version.
diff --git a/openssl/crypto/install-crypto.com b/openssl/crypto/install-crypto.com
new file mode 100644
index 0000000..85b3d58
--- /dev/null
+++ b/openssl/crypto/install-crypto.com
@@ -0,0 +1,196 @@
+$! INSTALL.COM -- Installs the files in a given directory tree
+$!
+$! Author: Richard Levitte <richard@levitte.org>
+$! Time of creation: 22-MAY-1998 10:13
+$!
+$! Changes by Zoltan Arpadffy <zoli@polarhome.com>
+$!
+$! P1  root of the directory tree
+$! P2  "64" for 64-bit pointers.
+$!
+$!
+$! Announce/identify.
+$!
+$ proc = f$environment( "procedure")
+$ write sys$output "@@@ "+ -
+   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
+$!
+$ on error then goto tidy
+$ on control_c then goto tidy
+$!
+$ if (p1 .eqs. "")
+$ then
+$   write sys$output "First argument missing."
+$   write sys$output -
+     "It should be the directory where you want things installed."
+$     exit
+$ endif
+$!
+$ if (f$getsyi( "cpu") .lt. 128)
+$ then
+$   arch = "VAX"
+$ else
+$   arch = f$edit( f$getsyi( "arch_name"), "upcase")
+$   if (arch .eqs. "") then arch = "UNK"
+$ endif
+$!
+$ archd = arch
+$ lib32 = "32"
+$ shr = "_SHR32"
+$!
+$ if (p2 .nes. "")
+$ then
+$   if (p2 .eqs. "64")
+$   then
+$     archd = arch+ "_64"
+$     lib32 = ""
+$     shr = "_SHR"
+$   else
+$     if (p2 .nes. "32")
+$     then
+$       write sys$output "Second argument invalid."
+$       write sys$output "It should be "32", "64", or nothing."
+$       exit
+$     endif
+$   endif
+$ endif
+$!
+$ root = f$parse( p1, "[]A.;0", , , "syntax_only, no_conceal") - "A.;0"
+$ root_dev = f$parse( root, , , "device", "syntax_only")
+$ root_dir = f$parse( root, , , "directory", "syntax_only") - -
+   "[000000." - "][" - "[" - "]"
+$ root = root_dev + "[" + root_dir
+$!
+$ define /nolog wrk_sslroot 'root'.] /trans=conc
+$ define /nolog wrk_sslinclude wrk_sslroot:[include]
+$ define /nolog wrk_sslxlib wrk_sslroot:['arch'_lib]
+$!
+$ if f$parse("wrk_sslroot:[000000]") .eqs. "" then -
+   create /directory /log wrk_sslroot:[000000]
+$ if f$parse("wrk_sslinclude:") .eqs. "" then -
+   create /directory /log wrk_sslinclude:
+$ if f$parse("wrk_sslxlib:") .eqs. "" then -
+   create /directory /log wrk_sslxlib:
+$!
+$ sdirs := , -
+   'archd', -
+   objects, -
+   md2, md4, md5, sha, mdc2, hmac, ripemd, whrlpool, -
+   des, aes, rc2, rc4, rc5, idea, bf, cast, camellia, seed, -
+   bn, ec, rsa, dsa, ecdsa, dh, ecdh, dso, engine, -
+   buffer, bio, stack, lhash, rand, err, -
+   evp, asn1, pem, x509, x509v3, conf, txt_db, pkcs7, pkcs12, comp, ocsp, -
+   ui, krb5, -
+   store, cms, pqueue, ts, jpake
+$!
+$ exheader_ := crypto.h, opensslv.h, ebcdic.h, symhacks.h, ossl_typ.h
+$ exheader_'archd' := opensslconf.h
+$ exheader_objects := objects.h, obj_mac.h
+$ exheader_md2 := md2.h
+$ exheader_md4 := md4.h
+$ exheader_md5 := md5.h
+$ exheader_sha := sha.h
+$ exheader_mdc2 := mdc2.h
+$ exheader_hmac := hmac.h
+$ exheader_ripemd := ripemd.h
+$ exheader_whrlpool := whrlpool.h
+$ exheader_des := des.h, des_old.h
+$ exheader_aes := aes.h
+$ exheader_rc2 := rc2.h
+$ exheader_rc4 := rc4.h
+$ exheader_rc5 := rc5.h
+$ exheader_idea := idea.h
+$ exheader_bf := blowfish.h
+$ exheader_cast := cast.h
+$ exheader_camellia := camellia.h
+$ exheader_seed := seed.h
+$ exheader_modes := modes.h
+$ exheader_bn := bn.h
+$ exheader_ec := ec.h
+$ exheader_rsa := rsa.h
+$ exheader_dsa := dsa.h
+$ exheader_ecdsa := ecdsa.h
+$ exheader_dh := dh.h
+$ exheader_ecdh := ecdh.h
+$ exheader_dso := dso.h
+$ exheader_engine := engine.h
+$ exheader_buffer := buffer.h
+$ exheader_bio := bio.h
+$ exheader_stack := stack.h, safestack.h
+$ exheader_lhash := lhash.h
+$ exheader_rand := rand.h
+$ exheader_err := err.h
+$ exheader_evp := evp.h
+$ exheader_asn1 := asn1.h, asn1_mac.h, asn1t.h
+$ exheader_pem := pem.h, pem2.h
+$ exheader_x509 := x509.h, x509_vfy.h
+$ exheader_x509v3 := x509v3.h
+$ exheader_conf := conf.h, conf_api.h
+$ exheader_txt_db := txt_db.h
+$ exheader_pkcs7 := pkcs7.h
+$ exheader_pkcs12 := pkcs12.h
+$ exheader_comp := comp.h
+$ exheader_ocsp := ocsp.h
+$ exheader_ui := ui.h, ui_compat.h
+$ exheader_krb5 := krb5_asn.h
+$! exheader_store := store.h, str_compat.h
+$ exheader_store := store.h
+$ exheader_cms := cms.h
+$ exheader_pqueue := pqueue.h
+$ exheader_ts := ts.h
+$ exheader_jpake := jpake.h
+$ libs := ssl_libcrypto
+$!
+$ exe_dir := [-.'archd'.exe.crypto]
+$!
+$! Header files.
+$!
+$ i = 0
+$ loop_sdirs: 
+$   d = f$edit( f$element( i, ",", sdirs), "trim")
+$   i = i + 1
+$   if d .eqs. "," then goto loop_sdirs_end
+$   tmp = exheader_'d'
+$   if (d .nes. "") then d = "."+ d
+$   copy /protection = w:re ['d']'tmp' wrk_sslinclude: /log
+$ goto loop_sdirs
+$ loop_sdirs_end:
+$!
+$! Object libraries, shareable images.
+$!
+$ i = 0
+$ loop_lib: 
+$   e = f$edit( f$element( i, ",", libs), "trim")
+$   i = i + 1
+$   if e .eqs. "," then goto loop_lib_end
+$   set noon
+$   file = exe_dir+ e+ lib32+ ".olb"
+$   if f$search( file) .nes. ""
+$   then
+$     copy /protection = w:re 'file' wrk_sslxlib: /log
+$   endif
+$!
+$   file = exe_dir+ e+ shr+ ".exe"
+$   if f$search( file) .nes. ""
+$   then
+$     copy /protection = w:re 'file' wrk_sslxlib: /log
+$   endif
+$   set on
+$ goto loop_lib
+$ loop_lib_end:
+$!
+$ tidy:
+$!
+$ call deass wrk_sslroot
+$ call deass wrk_sslinclude
+$ call deass wrk_sslxlib
+$!
+$ exit
+$!
+$ deass: subroutine
+$ if (f$trnlnm( p1, "LNM$PROCESS") .nes. "")
+$ then
+$   deassign /process 'p1'
+$ endif
+$ endsubroutine
+$!
diff --git a/openssl/crypto/jpake/Makefile b/openssl/crypto/jpake/Makefile
new file mode 100644
index 0000000..110c49c
--- /dev/null
+++ b/openssl/crypto/jpake/Makefile
@@ -0,0 +1,64 @@
+DIR=jpake
+TOP=../..
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+LIB=$(TOP)/libcrypto.a
+LIBOBJ=jpake.o jpake_err.o
+LIBSRC=jpake.c jpake_err.c
+
+EXHEADER=jpake.h
+TEST=jpaketest.c
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.s *.o *.obj des lib tags core .pure .nfs* *.old *.bak fluff
+
+jpaketest: top jpaketest.c $(LIB)
+	$(CC) $(CFLAGS) -Wall -Werror -g -o jpaketest jpaketest.c $(LIB)
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+jpake.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+jpake.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+jpake.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+jpake.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+jpake.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+jpake.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+jpake.o: ../../include/openssl/symhacks.h jpake.c jpake.h
+jpake_err.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+jpake_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+jpake_err.o: ../../include/openssl/err.h ../../include/openssl/jpake.h
+jpake_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+jpake_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+jpake_err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+jpake_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+jpake_err.o: jpake_err.c
diff --git a/openssl/crypto/jpake/jpake.c b/openssl/crypto/jpake/jpake.c
new file mode 100644
index 0000000..8e4b633
--- /dev/null
+++ b/openssl/crypto/jpake/jpake.c
@@ -0,0 +1,511 @@
+#include "jpake.h"
+
+#include <openssl/crypto.h>
+#include <openssl/sha.h>
+#include <openssl/err.h>
+#include <memory.h>
+
+/*
+ * In the definition, (xa, xb, xc, xd) are Alice's (x1, x2, x3, x4) or
+ * Bob's (x3, x4, x1, x2). If you see what I mean.
+ */
+
+typedef struct
+    {
+    char *name;  /* Must be unique */
+    char *peer_name;
+    BIGNUM *p;
+    BIGNUM *g;
+    BIGNUM *q;
+    BIGNUM *gxc; /* Alice's g^{x3} or Bob's g^{x1} */
+    BIGNUM *gxd; /* Alice's g^{x4} or Bob's g^{x2} */
+    } JPAKE_CTX_PUBLIC;
+
+struct JPAKE_CTX
+    {
+    JPAKE_CTX_PUBLIC p;
+    BIGNUM *secret;   /* The shared secret */
+    BN_CTX *ctx;
+    BIGNUM *xa;       /* Alice's x1 or Bob's x3 */
+    BIGNUM *xb;       /* Alice's x2 or Bob's x4 */
+    BIGNUM *key;      /* The calculated (shared) key */
+    };
+
+static void JPAKE_ZKP_init(JPAKE_ZKP *zkp)
+    {
+    zkp->gr = BN_new();
+    zkp->b = BN_new();
+    }
+
+static void JPAKE_ZKP_release(JPAKE_ZKP *zkp)
+    {
+    BN_free(zkp->b);
+    BN_free(zkp->gr);
+    }
+
+/* Two birds with one stone - make the global name as expected */
+#define JPAKE_STEP_PART_init	JPAKE_STEP2_init
+#define JPAKE_STEP_PART_release	JPAKE_STEP2_release
+
+void JPAKE_STEP_PART_init(JPAKE_STEP_PART *p)
+    {
+    p->gx = BN_new();
+    JPAKE_ZKP_init(&p->zkpx);
+    }
+
+void JPAKE_STEP_PART_release(JPAKE_STEP_PART *p)
+    {
+    JPAKE_ZKP_release(&p->zkpx);
+    BN_free(p->gx);
+    }
+
+void JPAKE_STEP1_init(JPAKE_STEP1 *s1)
+    {
+    JPAKE_STEP_PART_init(&s1->p1);
+    JPAKE_STEP_PART_init(&s1->p2);
+    }
+
+void JPAKE_STEP1_release(JPAKE_STEP1 *s1)
+    {
+    JPAKE_STEP_PART_release(&s1->p2);
+    JPAKE_STEP_PART_release(&s1->p1);
+    }
+
+static void JPAKE_CTX_init(JPAKE_CTX *ctx, const char *name,
+			   const char *peer_name, const BIGNUM *p,
+			   const BIGNUM *g, const BIGNUM *q,
+			   const BIGNUM *secret)
+    {
+    ctx->p.name = OPENSSL_strdup(name);
+    ctx->p.peer_name = OPENSSL_strdup(peer_name);
+    ctx->p.p = BN_dup(p);
+    ctx->p.g = BN_dup(g);
+    ctx->p.q = BN_dup(q);
+    ctx->secret = BN_dup(secret);
+
+    ctx->p.gxc = BN_new();
+    ctx->p.gxd = BN_new();
+
+    ctx->xa = BN_new();
+    ctx->xb = BN_new();
+    ctx->key = BN_new();
+    ctx->ctx = BN_CTX_new();
+    }
+    
+static void JPAKE_CTX_release(JPAKE_CTX *ctx)
+    {
+    BN_CTX_free(ctx->ctx);
+    BN_clear_free(ctx->key);
+    BN_clear_free(ctx->xb);
+    BN_clear_free(ctx->xa);
+
+    BN_free(ctx->p.gxd);
+    BN_free(ctx->p.gxc);
+
+    BN_clear_free(ctx->secret);
+    BN_free(ctx->p.q);
+    BN_free(ctx->p.g);
+    BN_free(ctx->p.p);
+    OPENSSL_free(ctx->p.peer_name);
+    OPENSSL_free(ctx->p.name);
+
+    memset(ctx, '\0', sizeof *ctx);
+    }
+    
+JPAKE_CTX *JPAKE_CTX_new(const char *name, const char *peer_name,
+			 const BIGNUM *p, const BIGNUM *g, const BIGNUM *q,
+			 const BIGNUM *secret)
+    {
+    JPAKE_CTX *ctx = OPENSSL_malloc(sizeof *ctx);
+
+    JPAKE_CTX_init(ctx, name, peer_name, p, g, q, secret);
+
+    return ctx;
+    }
+
+void JPAKE_CTX_free(JPAKE_CTX *ctx)
+    {
+    JPAKE_CTX_release(ctx);
+    OPENSSL_free(ctx);
+    }
+
+static void hashlength(SHA_CTX *sha, size_t l)
+    {
+    unsigned char b[2];
+
+    OPENSSL_assert(l <= 0xffff);
+    b[0] = l >> 8;
+    b[1] = l&0xff;
+    SHA1_Update(sha, b, 2);
+    }
+
+static void hashstring(SHA_CTX *sha, const char *string)
+    {
+    size_t l = strlen(string);
+
+    hashlength(sha, l);
+    SHA1_Update(sha, string, l);
+    }
+
+static void hashbn(SHA_CTX *sha, const BIGNUM *bn)
+    {
+    size_t l = BN_num_bytes(bn);
+    unsigned char *bin = OPENSSL_malloc(l);
+
+    hashlength(sha, l);
+    BN_bn2bin(bn, bin);
+    SHA1_Update(sha, bin, l);
+    OPENSSL_free(bin);
+    }
+
+/* h=hash(g, g^r, g^x, name) */
+static void zkp_hash(BIGNUM *h, const BIGNUM *zkpg, const JPAKE_STEP_PART *p,
+		     const char *proof_name)
+    {
+    unsigned char md[SHA_DIGEST_LENGTH];
+    SHA_CTX sha;
+
+   /*
+    * XXX: hash should not allow moving of the boundaries - Java code
+    * is flawed in this respect. Length encoding seems simplest.
+    */
+    SHA1_Init(&sha);
+    hashbn(&sha, zkpg);
+    OPENSSL_assert(!BN_is_zero(p->zkpx.gr));
+    hashbn(&sha, p->zkpx.gr);
+    hashbn(&sha, p->gx);
+    hashstring(&sha, proof_name);
+    SHA1_Final(md, &sha);
+    BN_bin2bn(md, SHA_DIGEST_LENGTH, h);
+    }
+
+/*
+ * Prove knowledge of x
+ * Note that p->gx has already been calculated
+ */
+static void generate_zkp(JPAKE_STEP_PART *p, const BIGNUM *x,
+			 const BIGNUM *zkpg, JPAKE_CTX *ctx)
+    {
+    BIGNUM *r = BN_new();
+    BIGNUM *h = BN_new();
+    BIGNUM *t = BN_new();
+
+   /*
+    * r in [0,q)
+    * XXX: Java chooses r in [0, 2^160) - i.e. distribution not uniform
+    */
+    BN_rand_range(r, ctx->p.q);
+   /* g^r */
+    BN_mod_exp(p->zkpx.gr, zkpg, r, ctx->p.p, ctx->ctx);
+
+   /* h=hash... */
+    zkp_hash(h, zkpg, p, ctx->p.name);
+
+   /* b = r - x*h */
+    BN_mod_mul(t, x, h, ctx->p.q, ctx->ctx);
+    BN_mod_sub(p->zkpx.b, r, t, ctx->p.q, ctx->ctx);
+
+   /* cleanup */
+    BN_free(t);
+    BN_free(h);
+    BN_free(r);
+    }
+
+static int verify_zkp(const JPAKE_STEP_PART *p, const BIGNUM *zkpg,
+		      JPAKE_CTX *ctx)
+    {
+    BIGNUM *h = BN_new();
+    BIGNUM *t1 = BN_new();
+    BIGNUM *t2 = BN_new();
+    BIGNUM *t3 = BN_new();
+    int ret = 0;
+
+    zkp_hash(h, zkpg, p, ctx->p.peer_name);
+
+   /* t1 = g^b */
+    BN_mod_exp(t1, zkpg, p->zkpx.b, ctx->p.p, ctx->ctx);
+   /* t2 = (g^x)^h = g^{hx} */
+    BN_mod_exp(t2, p->gx, h, ctx->p.p, ctx->ctx);
+   /* t3 = t1 * t2 = g^{hx} * g^b = g^{hx+b} = g^r (allegedly) */
+    BN_mod_mul(t3, t1, t2, ctx->p.p, ctx->ctx);
+
+   /* verify t3 == g^r */
+    if(BN_cmp(t3, p->zkpx.gr) == 0)
+	ret = 1;
+    else
+	JPAKEerr(JPAKE_F_VERIFY_ZKP, JPAKE_R_ZKP_VERIFY_FAILED);
+
+   /* cleanup */
+    BN_free(t3);
+    BN_free(t2);
+    BN_free(t1);
+    BN_free(h);
+
+    return ret;
+    }    
+
+static void generate_step_part(JPAKE_STEP_PART *p, const BIGNUM *x,
+			       const BIGNUM *g, JPAKE_CTX *ctx)
+    {
+    BN_mod_exp(p->gx, g, x, ctx->p.p, ctx->ctx);
+    generate_zkp(p, x, g, ctx);
+    }
+
+/* Generate each party's random numbers. xa is in [0, q), xb is in [1, q). */
+static void genrand(JPAKE_CTX *ctx)
+    {
+    BIGNUM *qm1;
+
+   /* xa in [0, q) */
+    BN_rand_range(ctx->xa, ctx->p.q);
+
+   /* q-1 */
+    qm1 = BN_new();
+    BN_copy(qm1, ctx->p.q);
+    BN_sub_word(qm1, 1);
+
+   /* ... and xb in [0, q-1) */
+    BN_rand_range(ctx->xb, qm1);
+   /* [1, q) */
+    BN_add_word(ctx->xb, 1);
+
+   /* cleanup */
+    BN_free(qm1);
+    }
+
+int JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx)
+    {
+    genrand(ctx);
+    generate_step_part(&send->p1, ctx->xa, ctx->p.g, ctx);
+    generate_step_part(&send->p2, ctx->xb, ctx->p.g, ctx);
+
+    return 1;
+    }
+
+/* g^x is a legal value */
+static int is_legal(const BIGNUM *gx, const JPAKE_CTX *ctx)
+    {
+    BIGNUM *t;
+    int res;
+    
+    if(BN_is_negative(gx) || BN_is_zero(gx) || BN_cmp(gx, ctx->p.p) >= 0)
+	return 0;
+
+    t = BN_new();
+    BN_mod_exp(t, gx, ctx->p.q, ctx->p.p, ctx->ctx);
+    res = BN_is_one(t);
+    BN_free(t);
+
+    return res;
+    }
+
+int JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received)
+    {
+    if(!is_legal(received->p1.gx, ctx))
+	{
+	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL);
+	return 0;
+	}
+
+    if(!is_legal(received->p2.gx, ctx))
+	{
+	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL);
+	return 0;
+	}
+
+   /* verify their ZKP(xc) */
+    if(!verify_zkp(&received->p1, ctx->p.g, ctx))
+	{
+	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X3_FAILED);
+	return 0;
+	}
+
+   /* verify their ZKP(xd) */
+    if(!verify_zkp(&received->p2, ctx->p.g, ctx))
+	{
+	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X4_FAILED);
+	return 0;
+	}
+
+   /* g^xd != 1 */
+    if(BN_is_one(received->p2.gx))
+	{
+	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_ONE);
+	return 0;
+	}
+
+   /* Save the bits we need for later */
+    BN_copy(ctx->p.gxc, received->p1.gx);
+    BN_copy(ctx->p.gxd, received->p2.gx);
+
+    return 1;
+    }
+
+
+int JPAKE_STEP2_generate(JPAKE_STEP2 *send, JPAKE_CTX *ctx)
+    {
+    BIGNUM *t1 = BN_new();
+    BIGNUM *t2 = BN_new();
+
+   /*
+    * X = g^{(xa + xc + xd) * xb * s}
+    * t1 = g^xa
+    */
+    BN_mod_exp(t1, ctx->p.g, ctx->xa, ctx->p.p, ctx->ctx);
+   /* t2 = t1 * g^{xc} = g^{xa} * g^{xc} = g^{xa + xc} */
+    BN_mod_mul(t2, t1, ctx->p.gxc, ctx->p.p, ctx->ctx);
+   /* t1 = t2 * g^{xd} = g^{xa + xc + xd} */
+    BN_mod_mul(t1, t2, ctx->p.gxd, ctx->p.p, ctx->ctx);
+   /* t2 = xb * s */
+    BN_mod_mul(t2, ctx->xb, ctx->secret, ctx->p.q, ctx->ctx);
+
+   /*
+    * ZKP(xb * s)
+    * XXX: this is kinda funky, because we're using
+    *
+    * g' = g^{xa + xc + xd}
+    *
+    * as the generator, which means X is g'^{xb * s}
+    * X = t1^{t2} = t1^{xb * s} = g^{(xa + xc + xd) * xb * s}
+    */
+    generate_step_part(send, t2, t1, ctx);
+
+   /* cleanup */
+    BN_free(t1);
+    BN_free(t2);
+
+    return 1;
+    }
+
+/* gx = g^{xc + xa + xb} * xd * s */
+static int compute_key(JPAKE_CTX *ctx, const BIGNUM *gx)
+    {
+    BIGNUM *t1 = BN_new();
+    BIGNUM *t2 = BN_new();
+    BIGNUM *t3 = BN_new();
+
+   /*
+    * K = (gx/g^{xb * xd * s})^{xb}
+    *   = (g^{(xc + xa + xb) * xd * s - xb * xd *s})^{xb}
+    *   = (g^{(xa + xc) * xd * s})^{xb}
+    *   = g^{(xa + xc) * xb * xd * s}
+    * [which is the same regardless of who calculates it]
+    */
+
+   /* t1 = (g^{xd})^{xb} = g^{xb * xd} */
+    BN_mod_exp(t1, ctx->p.gxd, ctx->xb, ctx->p.p, ctx->ctx);
+   /* t2 = -s = q-s */
+    BN_sub(t2, ctx->p.q, ctx->secret);
+   /* t3 = t1^t2 = g^{-xb * xd * s} */
+    BN_mod_exp(t3, t1, t2, ctx->p.p, ctx->ctx);
+   /* t1 = gx * t3 = X/g^{xb * xd * s} */
+    BN_mod_mul(t1, gx, t3, ctx->p.p, ctx->ctx);
+   /* K = t1^{xb} */
+    BN_mod_exp(ctx->key, t1, ctx->xb, ctx->p.p, ctx->ctx);
+
+   /* cleanup */
+    BN_free(t3);
+    BN_free(t2);
+    BN_free(t1);
+
+    return 1;
+    }
+
+int JPAKE_STEP2_process(JPAKE_CTX *ctx, const JPAKE_STEP2 *received)
+    {
+    BIGNUM *t1 = BN_new();
+    BIGNUM *t2 = BN_new();
+    int ret = 0;
+
+   /*
+    * g' = g^{xc + xa + xb} [from our POV]
+    * t1 = xa + xb
+    */
+    BN_mod_add(t1, ctx->xa, ctx->xb, ctx->p.q, ctx->ctx);
+   /* t2 = g^{t1} = g^{xa+xb} */
+    BN_mod_exp(t2, ctx->p.g, t1, ctx->p.p, ctx->ctx);
+   /* t1 = g^{xc} * t2 = g^{xc + xa + xb} */
+    BN_mod_mul(t1, ctx->p.gxc, t2, ctx->p.p, ctx->ctx);
+
+    if(verify_zkp(received, t1, ctx))
+	ret = 1;
+    else
+	JPAKEerr(JPAKE_F_JPAKE_STEP2_PROCESS, JPAKE_R_VERIFY_B_FAILED);
+
+    compute_key(ctx, received->gx);
+
+   /* cleanup */
+    BN_free(t2);
+    BN_free(t1);
+
+    return ret;
+    }
+
+static void quickhashbn(unsigned char *md, const BIGNUM *bn)
+    {
+    SHA_CTX sha;
+
+    SHA1_Init(&sha);
+    hashbn(&sha, bn);
+    SHA1_Final(md, &sha);
+    }
+
+void JPAKE_STEP3A_init(JPAKE_STEP3A *s3a)
+    {}
+
+int JPAKE_STEP3A_generate(JPAKE_STEP3A *send, JPAKE_CTX *ctx)
+    {
+    quickhashbn(send->hhk, ctx->key);
+    SHA1(send->hhk, sizeof send->hhk, send->hhk);
+
+    return 1;
+    }
+
+int JPAKE_STEP3A_process(JPAKE_CTX *ctx, const JPAKE_STEP3A *received)
+    {
+    unsigned char hhk[SHA_DIGEST_LENGTH];
+
+    quickhashbn(hhk, ctx->key);
+    SHA1(hhk, sizeof hhk, hhk);
+    if(memcmp(hhk, received->hhk, sizeof hhk))
+	{
+	JPAKEerr(JPAKE_F_JPAKE_STEP3A_PROCESS, JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH);
+	return 0;
+	}
+    return 1;
+    }
+
+void JPAKE_STEP3A_release(JPAKE_STEP3A *s3a)
+    {}
+
+void JPAKE_STEP3B_init(JPAKE_STEP3B *s3b)
+    {}
+
+int JPAKE_STEP3B_generate(JPAKE_STEP3B *send, JPAKE_CTX *ctx)
+    {
+    quickhashbn(send->hk, ctx->key);
+
+    return 1;
+    }
+
+int JPAKE_STEP3B_process(JPAKE_CTX *ctx, const JPAKE_STEP3B *received)
+    {
+    unsigned char hk[SHA_DIGEST_LENGTH];
+
+    quickhashbn(hk, ctx->key);
+    if(memcmp(hk, received->hk, sizeof hk))
+	{
+	JPAKEerr(JPAKE_F_JPAKE_STEP3B_PROCESS, JPAKE_R_HASH_OF_KEY_MISMATCH);
+	return 0;
+	}
+    return 1;
+    }
+
+void JPAKE_STEP3B_release(JPAKE_STEP3B *s3b)
+    {}
+
+const BIGNUM *JPAKE_get_shared_key(JPAKE_CTX *ctx)
+    {
+    return ctx->key;
+    }
+
diff --git a/openssl/crypto/jpake/jpake.h b/openssl/crypto/jpake/jpake.h
new file mode 100644
index 0000000..fd143b4
--- /dev/null
+++ b/openssl/crypto/jpake/jpake.h
@@ -0,0 +1,131 @@
+/*
+ * Implement J-PAKE, as described in
+ * http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf
+ * 
+ * With hints from http://www.cl.cam.ac.uk/~fh240/software/JPAKE2.java.
+ */
+
+#ifndef HEADER_JPAKE_H
+#define HEADER_JPAKE_H
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_JPAKE
+#error JPAKE is disabled.
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <openssl/bn.h>
+#include <openssl/sha.h>
+
+typedef struct JPAKE_CTX JPAKE_CTX;
+
+/* Note that "g" in the ZKPs is not necessarily the J-PAKE g. */
+typedef struct
+    {
+    BIGNUM *gr; /* g^r (r random) */
+    BIGNUM *b;  /* b = r - x*h, h=hash(g, g^r, g^x, name) */
+    } JPAKE_ZKP;
+
+typedef struct
+    {
+    BIGNUM *gx;       /* g^x in step 1, g^(xa + xc + xd) * xb * s in step 2 */
+    JPAKE_ZKP zkpx;   /* ZKP(x) or ZKP(xb * s) */
+    } JPAKE_STEP_PART;
+
+typedef struct
+    {
+    JPAKE_STEP_PART p1;   /* g^x3, ZKP(x3) or g^x1, ZKP(x1) */
+    JPAKE_STEP_PART p2;   /* g^x4, ZKP(x4) or g^x2, ZKP(x2) */
+    } JPAKE_STEP1;
+
+typedef JPAKE_STEP_PART JPAKE_STEP2;
+
+typedef struct
+    {
+    unsigned char hhk[SHA_DIGEST_LENGTH];
+    } JPAKE_STEP3A;
+
+typedef struct
+    {
+    unsigned char hk[SHA_DIGEST_LENGTH];
+    } JPAKE_STEP3B;
+
+/* Parameters are copied */
+JPAKE_CTX *JPAKE_CTX_new(const char *name, const char *peer_name,
+			 const BIGNUM *p, const BIGNUM *g, const BIGNUM *q,
+			 const BIGNUM *secret);
+void JPAKE_CTX_free(JPAKE_CTX *ctx);
+
+/*
+ * Note that JPAKE_STEP1 can be used multiple times before release
+ * without another init.
+ */
+void JPAKE_STEP1_init(JPAKE_STEP1 *s1);
+int JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx);
+int JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received);
+void JPAKE_STEP1_release(JPAKE_STEP1 *s1);
+
+/*
+ * Note that JPAKE_STEP2 can be used multiple times before release
+ * without another init.
+ */
+void JPAKE_STEP2_init(JPAKE_STEP2 *s2);
+int JPAKE_STEP2_generate(JPAKE_STEP2 *send, JPAKE_CTX *ctx);
+int JPAKE_STEP2_process(JPAKE_CTX *ctx, const JPAKE_STEP2 *received);
+void JPAKE_STEP2_release(JPAKE_STEP2 *s2);
+
+/*
+ * Optionally verify the shared key. If the shared secrets do not
+ * match, the two ends will disagree about the shared key, but
+ * otherwise the protocol will succeed.
+ */
+void JPAKE_STEP3A_init(JPAKE_STEP3A *s3a);
+int JPAKE_STEP3A_generate(JPAKE_STEP3A *send, JPAKE_CTX *ctx);
+int JPAKE_STEP3A_process(JPAKE_CTX *ctx, const JPAKE_STEP3A *received);
+void JPAKE_STEP3A_release(JPAKE_STEP3A *s3a);
+
+void JPAKE_STEP3B_init(JPAKE_STEP3B *s3b);
+int JPAKE_STEP3B_generate(JPAKE_STEP3B *send, JPAKE_CTX *ctx);
+int JPAKE_STEP3B_process(JPAKE_CTX *ctx, const JPAKE_STEP3B *received);
+void JPAKE_STEP3B_release(JPAKE_STEP3B *s3b);
+
+/*
+ * the return value belongs to the library and will be released when
+ * ctx is released, and will change when a new handshake is performed.
+ */
+const BIGNUM *JPAKE_get_shared_key(JPAKE_CTX *ctx);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_JPAKE_strings(void);
+
+/* Error codes for the JPAKE functions. */
+
+/* Function codes. */
+#define JPAKE_F_JPAKE_STEP1_PROCESS			 101
+#define JPAKE_F_JPAKE_STEP2_PROCESS			 102
+#define JPAKE_F_JPAKE_STEP3A_PROCESS			 103
+#define JPAKE_F_JPAKE_STEP3B_PROCESS			 104
+#define JPAKE_F_VERIFY_ZKP				 100
+
+/* Reason codes. */
+#define JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL		 108
+#define JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL		 109
+#define JPAKE_R_G_TO_THE_X4_IS_ONE			 105
+#define JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH		 106
+#define JPAKE_R_HASH_OF_KEY_MISMATCH			 107
+#define JPAKE_R_VERIFY_B_FAILED				 102
+#define JPAKE_R_VERIFY_X3_FAILED			 103
+#define JPAKE_R_VERIFY_X4_FAILED			 104
+#define JPAKE_R_ZKP_VERIFY_FAILED			 100
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/jpake/jpake_err.c b/openssl/crypto/jpake/jpake_err.c
new file mode 100644
index 0000000..a9a9dee
--- /dev/null
+++ b/openssl/crypto/jpake/jpake_err.c
@@ -0,0 +1,107 @@
+/* crypto/jpake/jpake_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2010 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/jpake.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_JPAKE,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_JPAKE,0,reason)
+
+static ERR_STRING_DATA JPAKE_str_functs[]=
+	{
+{ERR_FUNC(JPAKE_F_JPAKE_STEP1_PROCESS),	"JPAKE_STEP1_process"},
+{ERR_FUNC(JPAKE_F_JPAKE_STEP2_PROCESS),	"JPAKE_STEP2_process"},
+{ERR_FUNC(JPAKE_F_JPAKE_STEP3A_PROCESS),	"JPAKE_STEP3A_process"},
+{ERR_FUNC(JPAKE_F_JPAKE_STEP3B_PROCESS),	"JPAKE_STEP3B_process"},
+{ERR_FUNC(JPAKE_F_VERIFY_ZKP),	"VERIFY_ZKP"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA JPAKE_str_reasons[]=
+	{
+{ERR_REASON(JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL),"g to the x3 is not legal"},
+{ERR_REASON(JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL),"g to the x4 is not legal"},
+{ERR_REASON(JPAKE_R_G_TO_THE_X4_IS_ONE)  ,"g to the x4 is one"},
+{ERR_REASON(JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH),"hash of hash of key mismatch"},
+{ERR_REASON(JPAKE_R_HASH_OF_KEY_MISMATCH),"hash of key mismatch"},
+{ERR_REASON(JPAKE_R_VERIFY_B_FAILED)     ,"verify b failed"},
+{ERR_REASON(JPAKE_R_VERIFY_X3_FAILED)    ,"verify x3 failed"},
+{ERR_REASON(JPAKE_R_VERIFY_X4_FAILED)    ,"verify x4 failed"},
+{ERR_REASON(JPAKE_R_ZKP_VERIFY_FAILED)   ,"zkp verify failed"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_JPAKE_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(JPAKE_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,JPAKE_str_functs);
+		ERR_load_strings(0,JPAKE_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/jpake/jpaketest.c b/openssl/crypto/jpake/jpaketest.c
new file mode 100644
index 0000000..eaba75e
--- /dev/null
+++ b/openssl/crypto/jpake/jpaketest.c
@@ -0,0 +1,192 @@
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_JPAKE
+
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+    printf("No J-PAKE support\n");
+    return(0);
+}
+
+#else
+
+#include <openssl/jpake.h>
+#include <openssl/err.h>
+
+static void showbn(const char *name, const BIGNUM *bn)
+    {
+    fputs(name, stdout);
+    fputs(" = ", stdout);
+    BN_print_fp(stdout, bn);
+    putc('\n', stdout);
+    }
+
+static int run_jpake(JPAKE_CTX *alice, JPAKE_CTX *bob)
+    {
+    JPAKE_STEP1 alice_s1;
+    JPAKE_STEP1 bob_s1;
+    JPAKE_STEP2 alice_s2;
+    JPAKE_STEP2 bob_s2;
+    JPAKE_STEP3A alice_s3a;
+    JPAKE_STEP3B bob_s3b;
+
+   /* Alice -> Bob: step 1 */
+    puts("A->B s1");
+    JPAKE_STEP1_init(&alice_s1);
+    JPAKE_STEP1_generate(&alice_s1, alice);
+    if(!JPAKE_STEP1_process(bob, &alice_s1))
+	{
+	printf("Bob fails to process Alice's step 1\n");
+	ERR_print_errors_fp(stdout);
+	return 1;
+	}
+    JPAKE_STEP1_release(&alice_s1);
+
+   /* Bob -> Alice: step 1 */
+    puts("B->A s1");
+    JPAKE_STEP1_init(&bob_s1);
+    JPAKE_STEP1_generate(&bob_s1, bob);
+    if(!JPAKE_STEP1_process(alice, &bob_s1))
+	{
+	printf("Alice fails to process Bob's step 1\n");
+	ERR_print_errors_fp(stdout);
+	return 2;
+	}
+    JPAKE_STEP1_release(&bob_s1);
+
+   /* Alice -> Bob: step 2 */
+    puts("A->B s2");
+    JPAKE_STEP2_init(&alice_s2);
+    JPAKE_STEP2_generate(&alice_s2, alice);
+    if(!JPAKE_STEP2_process(bob, &alice_s2))
+	{
+	printf("Bob fails to process Alice's step 2\n");
+	ERR_print_errors_fp(stdout);
+	return 3;
+	}
+    JPAKE_STEP2_release(&alice_s2);
+
+   /* Bob -> Alice: step 2 */
+    puts("B->A s2");
+    JPAKE_STEP2_init(&bob_s2);
+    JPAKE_STEP2_generate(&bob_s2, bob);
+    if(!JPAKE_STEP2_process(alice, &bob_s2))
+	{
+	printf("Alice fails to process Bob's step 2\n");
+	ERR_print_errors_fp(stdout);
+	return 4;
+	}
+    JPAKE_STEP2_release(&bob_s2);
+
+    showbn("Alice's key", JPAKE_get_shared_key(alice));
+    showbn("Bob's key  ", JPAKE_get_shared_key(bob));
+
+   /* Alice -> Bob: step 3a */
+    puts("A->B s3a");
+    JPAKE_STEP3A_init(&alice_s3a);
+    JPAKE_STEP3A_generate(&alice_s3a, alice);
+    if(!JPAKE_STEP3A_process(bob, &alice_s3a))
+	{
+	printf("Bob fails to process Alice's step 3a\n");
+	ERR_print_errors_fp(stdout);
+	return 5;
+	}
+    JPAKE_STEP3A_release(&alice_s3a);
+    
+   /* Bob -> Alice: step 3b */
+    puts("B->A s3b");
+    JPAKE_STEP3B_init(&bob_s3b);
+    JPAKE_STEP3B_generate(&bob_s3b, bob);
+    if(!JPAKE_STEP3B_process(alice, &bob_s3b))
+	{
+	printf("Alice fails to process Bob's step 3b\n");
+	ERR_print_errors_fp(stdout);
+	return 6;
+	}
+    JPAKE_STEP3B_release(&bob_s3b);
+
+    return 0;
+    }
+
+int main(int argc, char **argv)
+    {
+    JPAKE_CTX *alice;
+    JPAKE_CTX *bob;
+    BIGNUM *p = NULL;
+    BIGNUM *g = NULL;
+    BIGNUM *q = NULL;
+    BIGNUM *secret = BN_new();
+    BIO *bio_err;
+
+    bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+    CRYPTO_malloc_debug_init();
+    CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+    ERR_load_crypto_strings();
+
+    /*
+    BN_hex2bn(&p, "fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7");
+    BN_hex2bn(&g, "f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a");
+    BN_hex2bn(&q, "9760508f15230bccb292b982a2eb840bf0581cf5");
+    */
+    /*
+    p = BN_new();
+    BN_generate_prime(p, 1024, 1, NULL, NULL, NULL, NULL);
+    */
+   /* Use a safe prime for p (that we found earlier) */
+    BN_hex2bn(&p, "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F");
+    showbn("p", p);
+    g = BN_new();
+    BN_set_word(g, 2);
+    showbn("g", g);
+    q = BN_new();
+    BN_rshift1(q, p);
+    showbn("q", q);
+
+    BN_rand(secret, 32, -1, 0);
+
+   /* A normal run, expect this to work... */
+    alice = JPAKE_CTX_new("Alice", "Bob", p, g, q, secret);
+    bob = JPAKE_CTX_new("Bob", "Alice", p, g, q, secret);
+
+    if(run_jpake(alice, bob) != 0)
+	{
+	fprintf(stderr, "Plain JPAKE run failed\n");
+	return 1;
+	}
+
+    JPAKE_CTX_free(bob);
+    JPAKE_CTX_free(alice);
+
+   /* Now give Alice and Bob different secrets */
+    alice = JPAKE_CTX_new("Alice", "Bob", p, g, q, secret);
+    BN_add_word(secret, 1);
+    bob = JPAKE_CTX_new("Bob", "Alice", p, g, q, secret);
+
+    if(run_jpake(alice, bob) != 5)
+	{
+	fprintf(stderr, "Mismatched secret JPAKE run failed\n");
+	return 1;
+	}
+
+    JPAKE_CTX_free(bob);
+    JPAKE_CTX_free(alice);
+
+    BN_free(secret);
+    BN_free(q);
+    BN_free(g);
+    BN_free(p);
+
+    CRYPTO_cleanup_all_ex_data();
+    ERR_remove_thread_state(NULL);
+    ERR_free_strings();
+    CRYPTO_mem_leaks(bio_err);
+
+    return 0;
+    }
+
+#endif
diff --git a/openssl/crypto/krb5/Makefile b/openssl/crypto/krb5/Makefile
new file mode 100644
index 0000000..1407739
--- /dev/null
+++ b/openssl/crypto/krb5/Makefile
@@ -0,0 +1,84 @@
+#
+# OpenSSL/krb5/Makefile
+#
+
+DIR=	krb5
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile README
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= krb5_asn.c
+
+LIBOBJ= krb5_asn.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= krb5_asn.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+krb5_asn.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+krb5_asn.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+krb5_asn.o: ../../include/openssl/e_os2.h ../../include/openssl/krb5_asn.h
+krb5_asn.o: ../../include/openssl/opensslconf.h
+krb5_asn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+krb5_asn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+krb5_asn.o: ../../include/openssl/symhacks.h krb5_asn.c
diff --git a/openssl/crypto/krb5/krb5_asn.c b/openssl/crypto/krb5/krb5_asn.c
new file mode 100644
index 0000000..1fb741d
--- /dev/null
+++ b/openssl/crypto/krb5/krb5_asn.c
@@ -0,0 +1,167 @@
+/* krb5_asn.c */
+/* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project,
+** using ocsp/{*.h,*asn*.c} as a starting point
+*/
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/krb5_asn.h>
+
+
+ASN1_SEQUENCE(KRB5_ENCDATA) = {
+	ASN1_EXP(KRB5_ENCDATA, etype,		ASN1_INTEGER,	  0),
+	ASN1_EXP_OPT(KRB5_ENCDATA, kvno,	ASN1_INTEGER,	  1),
+	ASN1_EXP(KRB5_ENCDATA, cipher,		ASN1_OCTET_STRING,2)
+} ASN1_SEQUENCE_END(KRB5_ENCDATA)
+
+IMPLEMENT_ASN1_FUNCTIONS(KRB5_ENCDATA)
+
+
+ASN1_SEQUENCE(KRB5_PRINCNAME) = {
+	ASN1_EXP(KRB5_PRINCNAME, nametype,	ASN1_INTEGER,	  0),
+	ASN1_EXP_SEQUENCE_OF(KRB5_PRINCNAME, namestring, ASN1_GENERALSTRING, 1)
+} ASN1_SEQUENCE_END(KRB5_PRINCNAME)
+
+IMPLEMENT_ASN1_FUNCTIONS(KRB5_PRINCNAME)
+
+
+/* [APPLICATION 1] = 0x61 */
+ASN1_SEQUENCE(KRB5_TKTBODY) = {
+	ASN1_EXP(KRB5_TKTBODY, tktvno,		ASN1_INTEGER,	  0),
+	ASN1_EXP(KRB5_TKTBODY, realm, 		ASN1_GENERALSTRING, 1),
+	ASN1_EXP(KRB5_TKTBODY, sname,		KRB5_PRINCNAME,	  2),
+	ASN1_EXP(KRB5_TKTBODY, encdata,		KRB5_ENCDATA,	  3)
+} ASN1_SEQUENCE_END(KRB5_TKTBODY)
+
+IMPLEMENT_ASN1_FUNCTIONS(KRB5_TKTBODY)
+
+
+ASN1_ITEM_TEMPLATE(KRB5_TICKET) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 1,
+			KRB5_TICKET, KRB5_TKTBODY)
+ASN1_ITEM_TEMPLATE_END(KRB5_TICKET)
+
+IMPLEMENT_ASN1_FUNCTIONS(KRB5_TICKET)
+
+
+/* [APPLICATION 14] = 0x6e */
+ASN1_SEQUENCE(KRB5_APREQBODY) = {
+	ASN1_EXP(KRB5_APREQBODY, pvno,		ASN1_INTEGER,	  0),
+	ASN1_EXP(KRB5_APREQBODY, msgtype,	ASN1_INTEGER,	  1),
+	ASN1_EXP(KRB5_APREQBODY, apoptions,	ASN1_BIT_STRING,  2),
+	ASN1_EXP(KRB5_APREQBODY, ticket, 	KRB5_TICKET,	  3),
+	ASN1_EXP(KRB5_APREQBODY, authenticator,	KRB5_ENCDATA,	  4),
+} ASN1_SEQUENCE_END(KRB5_APREQBODY)
+
+IMPLEMENT_ASN1_FUNCTIONS(KRB5_APREQBODY)
+
+ASN1_ITEM_TEMPLATE(KRB5_APREQ) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 14,
+			KRB5_APREQ, KRB5_APREQBODY)
+ASN1_ITEM_TEMPLATE_END(KRB5_APREQ)
+
+IMPLEMENT_ASN1_FUNCTIONS(KRB5_APREQ)
+
+
+/*  Authenticator stuff 	*/
+
+ASN1_SEQUENCE(KRB5_CHECKSUM) = {
+	ASN1_EXP(KRB5_CHECKSUM, ctype,		ASN1_INTEGER,	  0),
+	ASN1_EXP(KRB5_CHECKSUM, checksum,	ASN1_OCTET_STRING,1)
+} ASN1_SEQUENCE_END(KRB5_CHECKSUM)
+
+IMPLEMENT_ASN1_FUNCTIONS(KRB5_CHECKSUM)
+
+
+ASN1_SEQUENCE(KRB5_ENCKEY) = {
+	ASN1_EXP(KRB5_ENCKEY,	ktype,		ASN1_INTEGER,	  0),
+	ASN1_EXP(KRB5_ENCKEY,	keyvalue,	ASN1_OCTET_STRING,1)
+} ASN1_SEQUENCE_END(KRB5_ENCKEY)
+
+IMPLEMENT_ASN1_FUNCTIONS(KRB5_ENCKEY)
+
+
+/* SEQ OF SEQ; see ASN1_EXP_SEQUENCE_OF_OPT() below */
+ASN1_SEQUENCE(KRB5_AUTHDATA) = {
+	ASN1_EXP(KRB5_AUTHDATA,	adtype,		ASN1_INTEGER,	  0),
+	ASN1_EXP(KRB5_AUTHDATA,	addata, 	ASN1_OCTET_STRING,1)
+} ASN1_SEQUENCE_END(KRB5_AUTHDATA)
+
+IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHDATA)
+
+
+/* [APPLICATION 2] = 0x62 */
+ASN1_SEQUENCE(KRB5_AUTHENTBODY) = {
+	ASN1_EXP(KRB5_AUTHENTBODY,	avno,	ASN1_INTEGER,	  0),
+	ASN1_EXP(KRB5_AUTHENTBODY,	crealm,	ASN1_GENERALSTRING, 1),
+	ASN1_EXP(KRB5_AUTHENTBODY,	cname,	KRB5_PRINCNAME,	  2),
+	ASN1_EXP_OPT(KRB5_AUTHENTBODY,	cksum,	KRB5_CHECKSUM,	  3),
+	ASN1_EXP(KRB5_AUTHENTBODY,	cusec,	ASN1_INTEGER,	  4),
+	ASN1_EXP(KRB5_AUTHENTBODY,	ctime,	ASN1_GENERALIZEDTIME, 5),
+	ASN1_EXP_OPT(KRB5_AUTHENTBODY,	subkey,	KRB5_ENCKEY,	  6),
+	ASN1_EXP_OPT(KRB5_AUTHENTBODY,	seqnum,	ASN1_INTEGER,	  7),
+	ASN1_EXP_SEQUENCE_OF_OPT
+		    (KRB5_AUTHENTBODY,	authorization,	KRB5_AUTHDATA, 8),
+} ASN1_SEQUENCE_END(KRB5_AUTHENTBODY)
+
+IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHENTBODY)
+
+ASN1_ITEM_TEMPLATE(KRB5_AUTHENT) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 2,
+			KRB5_AUTHENT, KRB5_AUTHENTBODY)
+ASN1_ITEM_TEMPLATE_END(KRB5_AUTHENT)
+
+IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHENT)
+
diff --git a/openssl/crypto/krb5/krb5_asn.h b/openssl/crypto/krb5/krb5_asn.h
new file mode 100644
index 0000000..41725d0
--- /dev/null
+++ b/openssl/crypto/krb5/krb5_asn.h
@@ -0,0 +1,256 @@
+/* krb5_asn.h */
+/* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project,
+** using ocsp/{*.h,*asn*.c} as a starting point
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_KRB5_ASN_H
+#define HEADER_KRB5_ASN_H
+
+/*
+#include <krb5.h>
+*/
+#include <openssl/safestack.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+/*	ASN.1 from Kerberos RFC 1510
+*/
+
+/*	EncryptedData ::=   SEQUENCE {
+**		etype[0]                      INTEGER, -- EncryptionType
+**		kvno[1]                       INTEGER OPTIONAL,
+**		cipher[2]                     OCTET STRING -- ciphertext
+**	}
+*/
+typedef	struct	krb5_encdata_st
+	{
+	ASN1_INTEGER			*etype;
+	ASN1_INTEGER			*kvno;
+	ASN1_OCTET_STRING		*cipher;
+	}	KRB5_ENCDATA;
+
+DECLARE_STACK_OF(KRB5_ENCDATA)
+
+/*	PrincipalName ::=   SEQUENCE {
+**		name-type[0]                  INTEGER,
+**		name-string[1]                SEQUENCE OF GeneralString
+**	}
+*/
+typedef	struct	krb5_princname_st
+	{
+	ASN1_INTEGER			*nametype;
+	STACK_OF(ASN1_GENERALSTRING)	*namestring;
+	}	KRB5_PRINCNAME;
+
+DECLARE_STACK_OF(KRB5_PRINCNAME)
+
+
+/*	Ticket ::=	[APPLICATION 1] SEQUENCE {
+**		tkt-vno[0]                    INTEGER,
+**		realm[1]                      Realm,
+**		sname[2]                      PrincipalName,
+**		enc-part[3]                   EncryptedData
+**	}
+*/
+typedef	struct	krb5_tktbody_st
+	{
+	ASN1_INTEGER			*tktvno;
+	ASN1_GENERALSTRING		*realm;
+	KRB5_PRINCNAME			*sname;
+	KRB5_ENCDATA			*encdata;
+	}	KRB5_TKTBODY;
+
+typedef STACK_OF(KRB5_TKTBODY) KRB5_TICKET;
+DECLARE_STACK_OF(KRB5_TKTBODY)
+
+
+/*	AP-REQ ::=      [APPLICATION 14] SEQUENCE {
+**		pvno[0]                       INTEGER,
+**		msg-type[1]                   INTEGER,
+**		ap-options[2]                 APOptions,
+**		ticket[3]                     Ticket,
+**		authenticator[4]              EncryptedData
+**	}
+**
+**	APOptions ::=   BIT STRING {
+**		reserved(0), use-session-key(1), mutual-required(2) }
+*/
+typedef	struct	krb5_ap_req_st
+	{
+	ASN1_INTEGER			*pvno;
+	ASN1_INTEGER			*msgtype;
+	ASN1_BIT_STRING			*apoptions;
+	KRB5_TICKET			*ticket;
+	KRB5_ENCDATA			*authenticator;
+	}	KRB5_APREQBODY;
+
+typedef STACK_OF(KRB5_APREQBODY) KRB5_APREQ;
+DECLARE_STACK_OF(KRB5_APREQBODY)
+
+
+/*	Authenticator Stuff	*/
+
+
+/*	Checksum ::=   SEQUENCE {
+**		cksumtype[0]                  INTEGER,
+**		checksum[1]                   OCTET STRING
+**	}
+*/
+typedef	struct	krb5_checksum_st
+	{
+	ASN1_INTEGER			*ctype;
+	ASN1_OCTET_STRING		*checksum;
+	}	KRB5_CHECKSUM;
+
+DECLARE_STACK_OF(KRB5_CHECKSUM)
+
+
+/*	EncryptionKey ::=   SEQUENCE {
+**		keytype[0]                    INTEGER,
+**		keyvalue[1]                   OCTET STRING
+**	}
+*/
+typedef struct  krb5_encryptionkey_st
+	{
+	ASN1_INTEGER			*ktype;
+	ASN1_OCTET_STRING		*keyvalue;
+	}	KRB5_ENCKEY;
+
+DECLARE_STACK_OF(KRB5_ENCKEY)
+
+
+/*	AuthorizationData ::=   SEQUENCE OF SEQUENCE {
+**		ad-type[0]                    INTEGER,
+**              ad-data[1]                    OCTET STRING
+**	}
+*/
+typedef struct	krb5_authorization_st
+	{
+	ASN1_INTEGER			*adtype;
+	ASN1_OCTET_STRING		*addata;
+	}	KRB5_AUTHDATA;
+
+DECLARE_STACK_OF(KRB5_AUTHDATA)
+
+			
+/*	-- Unencrypted authenticator
+**	Authenticator ::=    [APPLICATION 2] SEQUENCE    {
+**		authenticator-vno[0]          INTEGER,
+**		crealm[1]                     Realm,
+**		cname[2]                      PrincipalName,
+**		cksum[3]                      Checksum OPTIONAL,
+**		cusec[4]                      INTEGER,
+**		ctime[5]                      KerberosTime,
+**		subkey[6]                     EncryptionKey OPTIONAL,
+**		seq-number[7]                 INTEGER OPTIONAL,
+**		authorization-data[8]         AuthorizationData OPTIONAL
+**	}
+*/
+typedef struct	krb5_authenticator_st
+	{
+	ASN1_INTEGER			*avno;
+	ASN1_GENERALSTRING		*crealm;
+	KRB5_PRINCNAME			*cname;
+	KRB5_CHECKSUM			*cksum;
+	ASN1_INTEGER			*cusec;
+	ASN1_GENERALIZEDTIME		*ctime;
+	KRB5_ENCKEY			*subkey;
+	ASN1_INTEGER			*seqnum;
+	KRB5_AUTHDATA			*authorization;
+	}	KRB5_AUTHENTBODY;
+
+typedef STACK_OF(KRB5_AUTHENTBODY) KRB5_AUTHENT;
+DECLARE_STACK_OF(KRB5_AUTHENTBODY)
+
+
+/*  DECLARE_ASN1_FUNCTIONS(type) = DECLARE_ASN1_FUNCTIONS_name(type, type) =
+**	type *name##_new(void);
+**	void name##_free(type *a);
+**	DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) =
+**	 DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) =
+**	  type *d2i_##name(type **a, const unsigned char **in, long len);
+**	  int i2d_##name(type *a, unsigned char **out);
+**	  DECLARE_ASN1_ITEM(itname) = OPENSSL_EXTERN const ASN1_ITEM itname##_it
+*/
+
+DECLARE_ASN1_FUNCTIONS(KRB5_ENCDATA)
+DECLARE_ASN1_FUNCTIONS(KRB5_PRINCNAME)
+DECLARE_ASN1_FUNCTIONS(KRB5_TKTBODY)
+DECLARE_ASN1_FUNCTIONS(KRB5_APREQBODY)
+DECLARE_ASN1_FUNCTIONS(KRB5_TICKET)
+DECLARE_ASN1_FUNCTIONS(KRB5_APREQ)
+
+DECLARE_ASN1_FUNCTIONS(KRB5_CHECKSUM)
+DECLARE_ASN1_FUNCTIONS(KRB5_ENCKEY)
+DECLARE_ASN1_FUNCTIONS(KRB5_AUTHDATA)
+DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENTBODY)
+DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENT)
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/openssl/crypto/lhash/Makefile b/openssl/crypto/lhash/Makefile
new file mode 100644
index 0000000..82bddac
--- /dev/null
+++ b/openssl/crypto/lhash/Makefile
@@ -0,0 +1,88 @@
+#
+# OpenSSL/crypto/lhash/Makefile
+#
+
+DIR=	lhash
+TOP=	../..
+CC=	cc
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=lhash.c lh_stats.c
+LIBOBJ=lhash.o lh_stats.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= lhash.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+lh_stats.o: ../../e_os.h ../../include/openssl/bio.h
+lh_stats.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+lh_stats.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+lh_stats.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+lh_stats.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+lh_stats.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+lh_stats.o: ../../include/openssl/symhacks.h ../cryptlib.h lh_stats.c
+lhash.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+lhash.o: ../../include/openssl/e_os2.h ../../include/openssl/lhash.h
+lhash.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+lhash.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+lhash.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h lhash.c
diff --git a/openssl/crypto/lhash/lh_stats.c b/openssl/crypto/lhash/lh_stats.c
new file mode 100644
index 0000000..815615e
--- /dev/null
+++ b/openssl/crypto/lhash/lh_stats.c
@@ -0,0 +1,248 @@
+/* crypto/lhash/lh_stats.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+/* If you wish to build this outside of SSLeay, remove the following lines
+ * and things should work as expected */
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#include <openssl/lhash.h>
+
+#ifdef OPENSSL_NO_BIO
+
+void lh_stats(LHASH *lh, FILE *out)
+	{
+	fprintf(out,"num_items             = %lu\n",lh->num_items);
+	fprintf(out,"num_nodes             = %u\n",lh->num_nodes);
+	fprintf(out,"num_alloc_nodes       = %u\n",lh->num_alloc_nodes);
+	fprintf(out,"num_expands           = %lu\n",lh->num_expands);
+	fprintf(out,"num_expand_reallocs   = %lu\n",lh->num_expand_reallocs);
+	fprintf(out,"num_contracts         = %lu\n",lh->num_contracts);
+	fprintf(out,"num_contract_reallocs = %lu\n",lh->num_contract_reallocs);
+	fprintf(out,"num_hash_calls        = %lu\n",lh->num_hash_calls);
+	fprintf(out,"num_comp_calls        = %lu\n",lh->num_comp_calls);
+	fprintf(out,"num_insert            = %lu\n",lh->num_insert);
+	fprintf(out,"num_replace           = %lu\n",lh->num_replace);
+	fprintf(out,"num_delete            = %lu\n",lh->num_delete);
+	fprintf(out,"num_no_delete         = %lu\n",lh->num_no_delete);
+	fprintf(out,"num_retrieve          = %lu\n",lh->num_retrieve);
+	fprintf(out,"num_retrieve_miss     = %lu\n",lh->num_retrieve_miss);
+	fprintf(out,"num_hash_comps        = %lu\n",lh->num_hash_comps);
+#if 0
+	fprintf(out,"p                     = %u\n",lh->p);
+	fprintf(out,"pmax                  = %u\n",lh->pmax);
+	fprintf(out,"up_load               = %lu\n",lh->up_load);
+	fprintf(out,"down_load             = %lu\n",lh->down_load);
+#endif
+	}
+
+void lh_node_stats(LHASH *lh, FILE *out)
+	{
+	LHASH_NODE *n;
+	unsigned int i,num;
+
+	for (i=0; i<lh->num_nodes; i++)
+		{
+		for (n=lh->b[i],num=0; n != NULL; n=n->next)
+			num++;
+		fprintf(out,"node %6u -> %3u\n",i,num);
+		}
+	}
+
+void lh_node_usage_stats(LHASH *lh, FILE *out)
+	{
+	LHASH_NODE *n;
+	unsigned long num;
+	unsigned int i;
+	unsigned long total=0,n_used=0;
+
+	for (i=0; i<lh->num_nodes; i++)
+		{
+		for (n=lh->b[i],num=0; n != NULL; n=n->next)
+			num++;
+		if (num != 0)
+			{
+			n_used++;
+			total+=num;
+			}
+		}
+	fprintf(out,"%lu nodes used out of %u\n",n_used,lh->num_nodes);
+	fprintf(out,"%lu items\n",total);
+	if (n_used == 0) return;
+	fprintf(out,"load %d.%02d  actual load %d.%02d\n",
+		(int)(total/lh->num_nodes),
+		(int)((total%lh->num_nodes)*100/lh->num_nodes),
+		(int)(total/n_used),
+		(int)((total%n_used)*100/n_used));
+	}
+
+#else
+
+#ifndef OPENSSL_NO_FP_API
+void lh_stats(const _LHASH *lh, FILE *fp)
+	{
+	BIO *bp;
+
+	bp=BIO_new(BIO_s_file());
+	if (bp == NULL) goto end;
+	BIO_set_fp(bp,fp,BIO_NOCLOSE);
+	lh_stats_bio(lh,bp);
+	BIO_free(bp);
+end:;
+	}
+
+void lh_node_stats(const _LHASH *lh, FILE *fp)
+	{
+	BIO *bp;
+
+	bp=BIO_new(BIO_s_file());
+	if (bp == NULL) goto end;
+	BIO_set_fp(bp,fp,BIO_NOCLOSE);
+	lh_node_stats_bio(lh,bp);
+	BIO_free(bp);
+end:;
+	}
+
+void lh_node_usage_stats(const _LHASH *lh, FILE *fp)
+	{
+	BIO *bp;
+
+	bp=BIO_new(BIO_s_file());
+	if (bp == NULL) goto end;
+	BIO_set_fp(bp,fp,BIO_NOCLOSE);
+	lh_node_usage_stats_bio(lh,bp);
+	BIO_free(bp);
+end:;
+	}
+
+#endif
+
+void lh_stats_bio(const _LHASH *lh, BIO *out)
+	{
+	BIO_printf(out,"num_items             = %lu\n",lh->num_items);
+	BIO_printf(out,"num_nodes             = %u\n",lh->num_nodes);
+	BIO_printf(out,"num_alloc_nodes       = %u\n",lh->num_alloc_nodes);
+	BIO_printf(out,"num_expands           = %lu\n",lh->num_expands);
+	BIO_printf(out,"num_expand_reallocs   = %lu\n",
+		   lh->num_expand_reallocs);
+	BIO_printf(out,"num_contracts         = %lu\n",lh->num_contracts);
+	BIO_printf(out,"num_contract_reallocs = %lu\n",
+		   lh->num_contract_reallocs);
+	BIO_printf(out,"num_hash_calls        = %lu\n",lh->num_hash_calls);
+	BIO_printf(out,"num_comp_calls        = %lu\n",lh->num_comp_calls);
+	BIO_printf(out,"num_insert            = %lu\n",lh->num_insert);
+	BIO_printf(out,"num_replace           = %lu\n",lh->num_replace);
+	BIO_printf(out,"num_delete            = %lu\n",lh->num_delete);
+	BIO_printf(out,"num_no_delete         = %lu\n",lh->num_no_delete);
+	BIO_printf(out,"num_retrieve          = %lu\n",lh->num_retrieve);
+	BIO_printf(out,"num_retrieve_miss     = %lu\n",lh->num_retrieve_miss);
+	BIO_printf(out,"num_hash_comps        = %lu\n",lh->num_hash_comps);
+#if 0
+	BIO_printf(out,"p                     = %u\n",lh->p);
+	BIO_printf(out,"pmax                  = %u\n",lh->pmax);
+	BIO_printf(out,"up_load               = %lu\n",lh->up_load);
+	BIO_printf(out,"down_load             = %lu\n",lh->down_load);
+#endif
+	}
+
+void lh_node_stats_bio(const _LHASH *lh, BIO *out)
+	{
+	LHASH_NODE *n;
+	unsigned int i,num;
+
+	for (i=0; i<lh->num_nodes; i++)
+		{
+		for (n=lh->b[i],num=0; n != NULL; n=n->next)
+			num++;
+		BIO_printf(out,"node %6u -> %3u\n",i,num);
+		}
+	}
+
+void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out)
+	{
+	LHASH_NODE *n;
+	unsigned long num;
+	unsigned int i;
+	unsigned long total=0,n_used=0;
+
+	for (i=0; i<lh->num_nodes; i++)
+		{
+		for (n=lh->b[i],num=0; n != NULL; n=n->next)
+			num++;
+		if (num != 0)
+			{
+			n_used++;
+			total+=num;
+			}
+		}
+	BIO_printf(out,"%lu nodes used out of %u\n",n_used,lh->num_nodes);
+	BIO_printf(out,"%lu items\n",total);
+	if (n_used == 0) return;
+	BIO_printf(out,"load %d.%02d  actual load %d.%02d\n",
+		   (int)(total/lh->num_nodes),
+		   (int)((total%lh->num_nodes)*100/lh->num_nodes),
+		   (int)(total/n_used),
+		   (int)((total%n_used)*100/n_used));
+	}
+
+#endif
diff --git a/openssl/crypto/lhash/lh_test.c b/openssl/crypto/lhash/lh_test.c
new file mode 100644
index 0000000..85700c8
--- /dev/null
+++ b/openssl/crypto/lhash/lh_test.c
@@ -0,0 +1,88 @@
+/* crypto/lhash/lh_test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/lhash.h>
+
+main()
+	{
+	LHASH *conf;
+	char buf[256];
+	int i;
+
+	conf=lh_new(lh_strhash,strcmp);
+	for (;;)
+		{
+		char *p;
+
+		buf[0]='\0';
+		fgets(buf,256,stdin);
+		if (buf[0] == '\0') break;
+		i=strlen(buf);
+		p=OPENSSL_malloc(i+1);
+		memcpy(p,buf,i+1);
+		lh_insert(conf,p);
+		}
+
+	lh_node_stats(conf,stdout);
+	lh_stats(conf,stdout);
+	lh_node_usage_stats(conf,stdout);
+	exit(0);
+	}
diff --git a/openssl/crypto/lhash/lhash.c b/openssl/crypto/lhash/lhash.c
new file mode 100644
index 0000000..47f7480
--- /dev/null
+++ b/openssl/crypto/lhash/lhash.c
@@ -0,0 +1,475 @@
+/* crypto/lhash/lhash.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Code for dynamic hash table routines
+ * Author - Eric Young v 2.0
+ *
+ * 2.2 eay - added #include "crypto.h" so the memory leak checking code is
+ *	     present. eay 18-Jun-98
+ *
+ * 2.1 eay - Added an 'error in last operation' flag. eay 6-May-98
+ *
+ * 2.0 eay - Fixed a bug that occurred when using lh_delete
+ *	     from inside lh_doall().  As entries were deleted,
+ *	     the 'table' was 'contract()ed', making some entries
+ *	     jump from the end of the table to the start, there by
+ *	     skipping the lh_doall() processing. eay - 4/12/95
+ *
+ * 1.9 eay - Fixed a memory leak in lh_free, the LHASH_NODEs
+ *	     were not being free()ed. 21/11/95
+ *
+ * 1.8 eay - Put the stats routines into a separate file, lh_stats.c
+ *	     19/09/95
+ *
+ * 1.7 eay - Removed the fputs() for realloc failures - the code
+ *           should silently tolerate them.  I have also fixed things
+ *           lint complained about 04/05/95
+ *
+ * 1.6 eay - Fixed an invalid pointers in contract/expand 27/07/92
+ *
+ * 1.5 eay - Fixed a misuse of realloc in expand 02/03/1992
+ *
+ * 1.4 eay - Fixed lh_doall so the function can call lh_delete 28/05/91
+ *
+ * 1.3 eay - Fixed a few lint problems 19/3/1991
+ *
+ * 1.2 eay - Fixed lh_doall problem 13/3/1991
+ *
+ * 1.1 eay - Added lh_doall
+ *
+ * 1.0 eay - First version
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+
+const char lh_version[]="lhash" OPENSSL_VERSION_PTEXT;
+
+#undef MIN_NODES 
+#define MIN_NODES	16
+#define UP_LOAD		(2*LH_LOAD_MULT) /* load times 256  (default 2) */
+#define DOWN_LOAD	(LH_LOAD_MULT)   /* load times 256  (default 1) */
+
+static void expand(_LHASH *lh);
+static void contract(_LHASH *lh);
+static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash);
+
+_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c)
+	{
+	_LHASH *ret;
+	int i;
+
+	if ((ret=OPENSSL_malloc(sizeof(_LHASH))) == NULL)
+		goto err0;
+	if ((ret->b=OPENSSL_malloc(sizeof(LHASH_NODE *)*MIN_NODES)) == NULL)
+		goto err1;
+	for (i=0; i<MIN_NODES; i++)
+		ret->b[i]=NULL;
+	ret->comp=((c == NULL)?(LHASH_COMP_FN_TYPE)strcmp:c);
+	ret->hash=((h == NULL)?(LHASH_HASH_FN_TYPE)lh_strhash:h);
+	ret->num_nodes=MIN_NODES/2;
+	ret->num_alloc_nodes=MIN_NODES;
+	ret->p=0;
+	ret->pmax=MIN_NODES/2;
+	ret->up_load=UP_LOAD;
+	ret->down_load=DOWN_LOAD;
+	ret->num_items=0;
+
+	ret->num_expands=0;
+	ret->num_expand_reallocs=0;
+	ret->num_contracts=0;
+	ret->num_contract_reallocs=0;
+	ret->num_hash_calls=0;
+	ret->num_comp_calls=0;
+	ret->num_insert=0;
+	ret->num_replace=0;
+	ret->num_delete=0;
+	ret->num_no_delete=0;
+	ret->num_retrieve=0;
+	ret->num_retrieve_miss=0;
+	ret->num_hash_comps=0;
+
+	ret->error=0;
+	return(ret);
+err1:
+	OPENSSL_free(ret);
+err0:
+	return(NULL);
+	}
+
+void lh_free(_LHASH *lh)
+	{
+	unsigned int i;
+	LHASH_NODE *n,*nn;
+
+	if (lh == NULL)
+	    return;
+
+	for (i=0; i<lh->num_nodes; i++)
+		{
+		n=lh->b[i];
+		while (n != NULL)
+			{
+			nn=n->next;
+			OPENSSL_free(n);
+			n=nn;
+			}
+		}
+	OPENSSL_free(lh->b);
+	OPENSSL_free(lh);
+	}
+
+void *lh_insert(_LHASH *lh, void *data)
+	{
+	unsigned long hash;
+	LHASH_NODE *nn,**rn;
+	void *ret;
+
+	lh->error=0;
+	if (lh->up_load <= (lh->num_items*LH_LOAD_MULT/lh->num_nodes))
+		expand(lh);
+
+	rn=getrn(lh,data,&hash);
+
+	if (*rn == NULL)
+		{
+		if ((nn=(LHASH_NODE *)OPENSSL_malloc(sizeof(LHASH_NODE))) == NULL)
+			{
+			lh->error++;
+			return(NULL);
+			}
+		nn->data=data;
+		nn->next=NULL;
+#ifndef OPENSSL_NO_HASH_COMP
+		nn->hash=hash;
+#endif
+		*rn=nn;
+		ret=NULL;
+		lh->num_insert++;
+		lh->num_items++;
+		}
+	else /* replace same key */
+		{
+		ret= (*rn)->data;
+		(*rn)->data=data;
+		lh->num_replace++;
+		}
+	return(ret);
+	}
+
+void *lh_delete(_LHASH *lh, const void *data)
+	{
+	unsigned long hash;
+	LHASH_NODE *nn,**rn;
+	void *ret;
+
+	lh->error=0;
+	rn=getrn(lh,data,&hash);
+
+	if (*rn == NULL)
+		{
+		lh->num_no_delete++;
+		return(NULL);
+		}
+	else
+		{
+		nn= *rn;
+		*rn=nn->next;
+		ret=nn->data;
+		OPENSSL_free(nn);
+		lh->num_delete++;
+		}
+
+	lh->num_items--;
+	if ((lh->num_nodes > MIN_NODES) &&
+		(lh->down_load >= (lh->num_items*LH_LOAD_MULT/lh->num_nodes)))
+		contract(lh);
+
+	return(ret);
+	}
+
+void *lh_retrieve(_LHASH *lh, const void *data)
+	{
+	unsigned long hash;
+	LHASH_NODE **rn;
+	void *ret;
+
+	lh->error=0;
+	rn=getrn(lh,data,&hash);
+
+	if (*rn == NULL)
+		{
+		lh->num_retrieve_miss++;
+		return(NULL);
+		}
+	else
+		{
+		ret= (*rn)->data;
+		lh->num_retrieve++;
+		}
+	return(ret);
+	}
+
+static void doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func,
+			  LHASH_DOALL_ARG_FN_TYPE func_arg, void *arg)
+	{
+	int i;
+	LHASH_NODE *a,*n;
+
+	if (lh == NULL)
+		return;
+
+	/* reverse the order so we search from 'top to bottom'
+	 * We were having memory leaks otherwise */
+	for (i=lh->num_nodes-1; i>=0; i--)
+		{
+		a=lh->b[i];
+		while (a != NULL)
+			{
+			/* 28/05/91 - eay - n added so items can be deleted
+			 * via lh_doall */
+			/* 22/05/08 - ben - eh? since a is not passed,
+			 * this should not be needed */
+			n=a->next;
+			if(use_arg)
+				func_arg(a->data,arg);
+			else
+				func(a->data);
+			a=n;
+			}
+		}
+	}
+
+void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func)
+	{
+	doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)0, NULL);
+	}
+
+void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg)
+	{
+	doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg);
+	}
+
+static void expand(_LHASH *lh)
+	{
+	LHASH_NODE **n,**n1,**n2,*np;
+	unsigned int p,i,j;
+	unsigned long hash,nni;
+
+	lh->num_nodes++;
+	lh->num_expands++;
+	p=(int)lh->p++;
+	n1= &(lh->b[p]);
+	n2= &(lh->b[p+(int)lh->pmax]);
+	*n2=NULL;        /* 27/07/92 - eay - undefined pointer bug */
+	nni=lh->num_alloc_nodes;
+	
+	for (np= *n1; np != NULL; )
+		{
+#ifndef OPENSSL_NO_HASH_COMP
+		hash=np->hash;
+#else
+		hash=lh->hash(np->data);
+		lh->num_hash_calls++;
+#endif
+		if ((hash%nni) != p)
+			{ /* move it */
+			*n1= (*n1)->next;
+			np->next= *n2;
+			*n2=np;
+			}
+		else
+			n1= &((*n1)->next);
+		np= *n1;
+		}
+
+	if ((lh->p) >= lh->pmax)
+		{
+		j=(int)lh->num_alloc_nodes*2;
+		n=(LHASH_NODE **)OPENSSL_realloc(lh->b,
+			(int)(sizeof(LHASH_NODE *)*j));
+		if (n == NULL)
+			{
+/*			fputs("realloc error in lhash",stderr); */
+			lh->error++;
+			lh->p=0;
+			return;
+			}
+		/* else */
+		for (i=(int)lh->num_alloc_nodes; i<j; i++)/* 26/02/92 eay */
+			n[i]=NULL;			  /* 02/03/92 eay */
+		lh->pmax=lh->num_alloc_nodes;
+		lh->num_alloc_nodes=j;
+		lh->num_expand_reallocs++;
+		lh->p=0;
+		lh->b=n;
+		}
+	}
+
+static void contract(_LHASH *lh)
+	{
+	LHASH_NODE **n,*n1,*np;
+
+	np=lh->b[lh->p+lh->pmax-1];
+	lh->b[lh->p+lh->pmax-1]=NULL; /* 24/07-92 - eay - weird but :-( */
+	if (lh->p == 0)
+		{
+		n=(LHASH_NODE **)OPENSSL_realloc(lh->b,
+			(unsigned int)(sizeof(LHASH_NODE *)*lh->pmax));
+		if (n == NULL)
+			{
+/*			fputs("realloc error in lhash",stderr); */
+			lh->error++;
+			return;
+			}
+		lh->num_contract_reallocs++;
+		lh->num_alloc_nodes/=2;
+		lh->pmax/=2;
+		lh->p=lh->pmax-1;
+		lh->b=n;
+		}
+	else
+		lh->p--;
+
+	lh->num_nodes--;
+	lh->num_contracts++;
+
+	n1=lh->b[(int)lh->p];
+	if (n1 == NULL)
+		lh->b[(int)lh->p]=np;
+	else
+		{
+		while (n1->next != NULL)
+			n1=n1->next;
+		n1->next=np;
+		}
+	}
+
+static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash)
+	{
+	LHASH_NODE **ret,*n1;
+	unsigned long hash,nn;
+	LHASH_COMP_FN_TYPE cf;
+
+	hash=(*(lh->hash))(data);
+	lh->num_hash_calls++;
+	*rhash=hash;
+
+	nn=hash%lh->pmax;
+	if (nn < lh->p)
+		nn=hash%lh->num_alloc_nodes;
+
+	cf=lh->comp;
+	ret= &(lh->b[(int)nn]);
+	for (n1= *ret; n1 != NULL; n1=n1->next)
+		{
+#ifndef OPENSSL_NO_HASH_COMP
+		lh->num_hash_comps++;
+		if (n1->hash != hash)
+			{
+			ret= &(n1->next);
+			continue;
+			}
+#endif
+		lh->num_comp_calls++;
+		if(cf(n1->data,data) == 0)
+			break;
+		ret= &(n1->next);
+		}
+	return(ret);
+	}
+
+/* The following hash seems to work very well on normal text strings
+ * no collisions on /usr/dict/words and it distributes on %2^n quite
+ * well, not as good as MD5, but still good.
+ */
+unsigned long lh_strhash(const char *c)
+	{
+	unsigned long ret=0;
+	long n;
+	unsigned long v;
+	int r;
+
+	if ((c == NULL) || (*c == '\0'))
+		return(ret);
+/*
+	unsigned char b[16];
+	MD5(c,strlen(c),b);
+	return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24)); 
+*/
+
+	n=0x100;
+	while (*c)
+		{
+		v=n|(*c);
+		n+=0x100;
+		r= (int)((v>>2)^v)&0x0f;
+		ret=(ret<<r)|(ret>>(32-r));
+		ret&=0xFFFFFFFFL;
+		ret^=v*v;
+		c++;
+		}
+	return((ret>>16)^ret);
+	}
+
+unsigned long lh_num_items(const _LHASH *lh)
+	{
+	return lh ? lh->num_items : 0;
+	}
diff --git a/openssl/crypto/lhash/lhash.h b/openssl/crypto/lhash/lhash.h
new file mode 100644
index 0000000..e7d8763
--- /dev/null
+++ b/openssl/crypto/lhash/lhash.h
@@ -0,0 +1,241 @@
+/* crypto/lhash/lhash.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Header for dynamic hash table routines
+ * Author - Eric Young
+ */
+
+#ifndef HEADER_LHASH_H
+#define HEADER_LHASH_H
+
+#include <openssl/e_os2.h>
+#ifndef OPENSSL_NO_FP_API
+#include <stdio.h>
+#endif
+
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct lhash_node_st
+	{
+	void *data;
+	struct lhash_node_st *next;
+#ifndef OPENSSL_NO_HASH_COMP
+	unsigned long hash;
+#endif
+	} LHASH_NODE;
+
+typedef int (*LHASH_COMP_FN_TYPE)(const void *, const void *);
+typedef unsigned long (*LHASH_HASH_FN_TYPE)(const void *);
+typedef void (*LHASH_DOALL_FN_TYPE)(void *);
+typedef void (*LHASH_DOALL_ARG_FN_TYPE)(void *, void *);
+
+/* Macros for declaring and implementing type-safe wrappers for LHASH callbacks.
+ * This way, callbacks can be provided to LHASH structures without function
+ * pointer casting and the macro-defined callbacks provide per-variable casting
+ * before deferring to the underlying type-specific callbacks. NB: It is
+ * possible to place a "static" in front of both the DECLARE and IMPLEMENT
+ * macros if the functions are strictly internal. */
+
+/* First: "hash" functions */
+#define DECLARE_LHASH_HASH_FN(name, o_type) \
+	unsigned long name##_LHASH_HASH(const void *);
+#define IMPLEMENT_LHASH_HASH_FN(name, o_type) \
+	unsigned long name##_LHASH_HASH(const void *arg) { \
+		const o_type *a = arg; \
+		return name##_hash(a); }
+#define LHASH_HASH_FN(name) name##_LHASH_HASH
+
+/* Second: "compare" functions */
+#define DECLARE_LHASH_COMP_FN(name, o_type) \
+	int name##_LHASH_COMP(const void *, const void *);
+#define IMPLEMENT_LHASH_COMP_FN(name, o_type) \
+	int name##_LHASH_COMP(const void *arg1, const void *arg2) { \
+		const o_type *a = arg1;		    \
+		const o_type *b = arg2; \
+		return name##_cmp(a,b); }
+#define LHASH_COMP_FN(name) name##_LHASH_COMP
+
+/* Third: "doall" functions */
+#define DECLARE_LHASH_DOALL_FN(name, o_type) \
+	void name##_LHASH_DOALL(void *);
+#define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \
+	void name##_LHASH_DOALL(void *arg) { \
+		o_type *a = arg; \
+		name##_doall(a); }
+#define LHASH_DOALL_FN(name) name##_LHASH_DOALL
+
+/* Fourth: "doall_arg" functions */
+#define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
+	void name##_LHASH_DOALL_ARG(void *, void *);
+#define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
+	void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
+		o_type *a = arg1; \
+		a_type *b = arg2; \
+		name##_doall_arg(a, b); }
+#define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG
+
+typedef struct lhash_st
+	{
+	LHASH_NODE **b;
+	LHASH_COMP_FN_TYPE comp;
+	LHASH_HASH_FN_TYPE hash;
+	unsigned int num_nodes;
+	unsigned int num_alloc_nodes;
+	unsigned int p;
+	unsigned int pmax;
+	unsigned long up_load; /* load times 256 */
+	unsigned long down_load; /* load times 256 */
+	unsigned long num_items;
+
+	unsigned long num_expands;
+	unsigned long num_expand_reallocs;
+	unsigned long num_contracts;
+	unsigned long num_contract_reallocs;
+	unsigned long num_hash_calls;
+	unsigned long num_comp_calls;
+	unsigned long num_insert;
+	unsigned long num_replace;
+	unsigned long num_delete;
+	unsigned long num_no_delete;
+	unsigned long num_retrieve;
+	unsigned long num_retrieve_miss;
+	unsigned long num_hash_comps;
+
+	int error;
+	} _LHASH;	/* Do not use _LHASH directly, use LHASH_OF
+			 * and friends */
+
+#define LH_LOAD_MULT	256
+
+/* Indicates a malloc() error in the last call, this is only bad
+ * in lh_insert(). */
+#define lh_error(lh)	((lh)->error)
+
+_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c);
+void lh_free(_LHASH *lh);
+void *lh_insert(_LHASH *lh, void *data);
+void *lh_delete(_LHASH *lh, const void *data);
+void *lh_retrieve(_LHASH *lh, const void *data);
+void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func);
+void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg);
+unsigned long lh_strhash(const char *c);
+unsigned long lh_num_items(const _LHASH *lh);
+
+#ifndef OPENSSL_NO_FP_API
+void lh_stats(const _LHASH *lh, FILE *out);
+void lh_node_stats(const _LHASH *lh, FILE *out);
+void lh_node_usage_stats(const _LHASH *lh, FILE *out);
+#endif
+
+#ifndef OPENSSL_NO_BIO
+void lh_stats_bio(const _LHASH *lh, BIO *out);
+void lh_node_stats_bio(const _LHASH *lh, BIO *out);
+void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out);
+#endif
+
+/* Type checking... */
+
+#define LHASH_OF(type) struct lhash_st_##type
+
+#define DECLARE_LHASH_OF(type) LHASH_OF(type) { int dummy; }
+
+#define CHECKED_LHASH_OF(type,lh) \
+  ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh))
+
+/* Define wrapper functions. */
+#define LHM_lh_new(type, name) \
+  ((LHASH_OF(type) *)lh_new(LHASH_HASH_FN(name), LHASH_COMP_FN(name)))
+#define LHM_lh_error(type, lh) \
+  lh_error(CHECKED_LHASH_OF(type,lh))
+#define LHM_lh_insert(type, lh, inst) \
+  ((type *)lh_insert(CHECKED_LHASH_OF(type, lh), \
+		     CHECKED_PTR_OF(type, inst)))
+#define LHM_lh_retrieve(type, lh, inst) \
+  ((type *)lh_retrieve(CHECKED_LHASH_OF(type, lh), \
+		       CHECKED_PTR_OF(type, inst)))
+#define LHM_lh_delete(type, lh, inst) \
+  ((type *)lh_delete(CHECKED_LHASH_OF(type, lh),			\
+		     CHECKED_PTR_OF(type, inst)))
+#define LHM_lh_doall(type, lh,fn) lh_doall(CHECKED_LHASH_OF(type, lh), fn)
+#define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \
+  lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg))
+#define LHM_lh_num_items(type, lh) lh_num_items(CHECKED_LHASH_OF(type, lh))
+#define LHM_lh_down_load(type, lh) (CHECKED_LHASH_OF(type, lh)->down_load)
+#define LHM_lh_node_stats_bio(type, lh, out) \
+  lh_node_stats_bio(CHECKED_LHASH_OF(type, lh), out)
+#define LHM_lh_node_usage_stats_bio(type, lh, out) \
+  lh_node_usage_stats_bio(CHECKED_LHASH_OF(type, lh), out)
+#define LHM_lh_stats_bio(type, lh, out) \
+  lh_stats_bio(CHECKED_LHASH_OF(type, lh), out)
+#define LHM_lh_free(type, lh) lh_free(CHECKED_LHASH_OF(type, lh))
+
+DECLARE_LHASH_OF(OPENSSL_STRING);
+DECLARE_LHASH_OF(OPENSSL_CSTRING);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/openssl/crypto/lhash/num.pl b/openssl/crypto/lhash/num.pl
new file mode 100644
index 0000000..30fedf9
--- /dev/null
+++ b/openssl/crypto/lhash/num.pl
@@ -0,0 +1,17 @@
+#!/usr/local/bin/perl
+
+#node     10 ->   4
+
+while (<>)
+	{
+	next unless /^node/;
+	chop;
+	@a=split;
+	$num{$a[3]}++;
+	}
+
+@a=sort {$a <=> $b } keys %num;
+foreach (0 .. $a[$#a])
+	{
+	printf "%4d:%4d\n",$_,$num{$_};
+	}
diff --git a/openssl/crypto/md2/Makefile b/openssl/crypto/md2/Makefile
new file mode 100644
index 0000000..17f878a
--- /dev/null
+++ b/openssl/crypto/md2/Makefile
@@ -0,0 +1,89 @@
+#
+# OpenSSL/crypto/md/Makefile
+#
+
+DIR=	md2
+TOP=	../..
+CC=	cc
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=md2test.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=md2_dgst.c md2_one.c
+LIBOBJ=md2_dgst.o md2_one.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= md2.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+md2_dgst.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+md2_dgst.o: ../../include/openssl/md2.h ../../include/openssl/opensslconf.h
+md2_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+md2_dgst.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+md2_dgst.o: ../../include/openssl/symhacks.h md2_dgst.c
+md2_one.o: ../../e_os.h ../../include/openssl/bio.h
+md2_one.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+md2_one.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+md2_one.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
+md2_one.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+md2_one.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+md2_one.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+md2_one.o: ../cryptlib.h md2_one.c
diff --git a/openssl/crypto/md2/md2.c b/openssl/crypto/md2/md2.c
new file mode 100644
index 0000000..f4d6f62
--- /dev/null
+++ b/openssl/crypto/md2/md2.c
@@ -0,0 +1,124 @@
+/* crypto/md2/md2.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/md2.h>
+
+#define BUFSIZE	1024*16
+
+void do_fp(FILE *f);
+void pt(unsigned char *md);
+int read(int, void *, unsigned int);
+void exit(int);
+int main(int argc, char *argv[])
+	{
+	int i,err=0;
+	FILE *IN;
+
+	if (argc == 1)
+		{
+		do_fp(stdin);
+		}
+	else
+		{
+		for (i=1; i<argc; i++)
+			{
+			IN=fopen(argv[i],"r");
+			if (IN == NULL)
+				{
+				perror(argv[i]);
+				err++;
+				continue;
+				}
+			printf("MD2(%s)= ",argv[i]);
+			do_fp(IN);
+			fclose(IN);
+			}
+		}
+	exit(err);
+	return(err);
+	}
+
+void do_fp(FILE *f)
+	{
+	MD2_CTX c;
+	unsigned char md[MD2_DIGEST_LENGTH];
+	int fd,i;
+	static unsigned char buf[BUFSIZE];
+
+	fd=fileno(f);
+	MD2_Init(&c);
+	for (;;)
+		{
+		i=read(fd,buf,BUFSIZE);
+		if (i <= 0) break;
+		MD2_Update(&c,buf,(unsigned long)i);
+		}
+	MD2_Final(&(md[0]),&c);
+	pt(md);
+	}
+
+void pt(unsigned char *md)
+	{
+	int i;
+
+	for (i=0; i<MD2_DIGEST_LENGTH; i++)
+		printf("%02x",md[i]);
+	printf("\n");
+	}
diff --git a/openssl/crypto/md2/md2.h b/openssl/crypto/md2/md2.h
new file mode 100644
index 0000000..a46120e
--- /dev/null
+++ b/openssl/crypto/md2/md2.h
@@ -0,0 +1,92 @@
+/* crypto/md/md2.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_MD2_H
+#define HEADER_MD2_H
+
+#include <openssl/opensslconf.h> /* OPENSSL_NO_MD2, MD2_INT */
+#ifdef OPENSSL_NO_MD2
+#error MD2 is disabled.
+#endif
+#include <stddef.h>
+
+#define MD2_DIGEST_LENGTH	16
+#define MD2_BLOCK       	16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct MD2state_st
+	{
+	unsigned int num;
+	unsigned char data[MD2_BLOCK];
+	MD2_INT cksm[MD2_BLOCK];
+	MD2_INT state[MD2_BLOCK];
+	} MD2_CTX;
+
+const char *MD2_options(void);
+int MD2_Init(MD2_CTX *c);
+int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len);
+int MD2_Final(unsigned char *md, MD2_CTX *c);
+unsigned char *MD2(const unsigned char *d, size_t n,unsigned char *md);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/md2/md2_dgst.c b/openssl/crypto/md2/md2_dgst.c
new file mode 100644
index 0000000..c57b3da
--- /dev/null
+++ b/openssl/crypto/md2/md2_dgst.c
@@ -0,0 +1,227 @@
+/* crypto/md2/md2_dgst.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/md2.h>
+#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
+
+const char MD2_version[]="MD2" OPENSSL_VERSION_PTEXT;
+
+/* Implemented from RFC1319 The MD2 Message-Digest Algorithm
+ */
+
+#define UCHAR	unsigned char
+
+static void md2_block(MD2_CTX *c, const unsigned char *d);
+/* The magic S table - I have converted it to hex since it is
+ * basically just a random byte string. */
+static const MD2_INT S[256]={
+	0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01,
+	0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
+	0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C,
+	0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
+	0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
+	0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
+	0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49,
+	0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
+	0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F,
+	0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
+	0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27,
+	0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
+	0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1,
+	0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
+	0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
+	0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
+	0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20,
+	0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
+	0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6,
+	0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
+	0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A,
+	0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
+	0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09,
+	0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
+	0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
+	0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
+	0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D,
+	0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
+	0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4,
+	0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
+	0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A,
+	0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14,
+	};
+
+const char *MD2_options(void)
+	{
+	if (sizeof(MD2_INT) == 1)
+		return("md2(char)");
+	else
+		return("md2(int)");
+	}
+
+int MD2_Init(MD2_CTX *c)
+	{
+	c->num=0;
+	memset(c->state,0,sizeof c->state);
+	memset(c->cksm,0,sizeof c->cksm);
+	memset(c->data,0,sizeof c->data);
+	return 1;
+	}
+
+int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len)
+	{
+	register UCHAR *p;
+
+	if (len == 0) return 1;
+
+	p=c->data;
+	if (c->num != 0)
+		{
+		if ((c->num+len) >= MD2_BLOCK)
+			{
+			memcpy(&(p[c->num]),data,MD2_BLOCK-c->num);
+			md2_block(c,c->data);
+			data+=(MD2_BLOCK - c->num);
+			len-=(MD2_BLOCK - c->num);
+			c->num=0;
+			/* drop through and do the rest */
+			}
+		else
+			{
+			memcpy(&(p[c->num]),data,len);
+			/* data+=len; */
+			c->num+=(int)len;
+			return 1;
+			}
+		}
+	/* we now can process the input data in blocks of MD2_BLOCK
+	 * chars and save the leftovers to c->data. */
+	while (len >= MD2_BLOCK)
+		{
+		md2_block(c,data);
+		data+=MD2_BLOCK;
+		len-=MD2_BLOCK;
+		}
+	memcpy(p,data,len);
+	c->num=(int)len;
+	return 1;
+	}
+
+static void md2_block(MD2_CTX *c, const unsigned char *d)
+	{
+	register MD2_INT t,*sp1,*sp2;
+	register int i,j;
+	MD2_INT state[48];
+
+	sp1=c->state;
+	sp2=c->cksm;
+	j=sp2[MD2_BLOCK-1];
+	for (i=0; i<16; i++)
+		{
+		state[i]=sp1[i];
+		state[i+16]=t=d[i];
+		state[i+32]=(t^sp1[i]);
+		j=sp2[i]^=S[t^j];
+		}
+	t=0;
+	for (i=0; i<18; i++)
+		{
+		for (j=0; j<48; j+=8)
+			{
+			t= state[j+ 0]^=S[t];
+			t= state[j+ 1]^=S[t];
+			t= state[j+ 2]^=S[t];
+			t= state[j+ 3]^=S[t];
+			t= state[j+ 4]^=S[t];
+			t= state[j+ 5]^=S[t];
+			t= state[j+ 6]^=S[t];
+			t= state[j+ 7]^=S[t];
+			}
+		t=(t+i)&0xff;
+		}
+	memcpy(sp1,state,16*sizeof(MD2_INT));
+	OPENSSL_cleanse(state,48*sizeof(MD2_INT));
+	}
+
+int MD2_Final(unsigned char *md, MD2_CTX *c)
+	{
+	int i,v;
+	register UCHAR *cp;
+	register MD2_INT *p1,*p2;
+
+	cp=c->data;
+	p1=c->state;
+	p2=c->cksm;
+	v=MD2_BLOCK-c->num;
+	for (i=c->num; i<MD2_BLOCK; i++)
+		cp[i]=(UCHAR)v;
+
+	md2_block(c,cp);
+
+	for (i=0; i<MD2_BLOCK; i++)
+		cp[i]=(UCHAR)p2[i];
+	md2_block(c,cp);
+
+	for (i=0; i<16; i++)
+		md[i]=(UCHAR)(p1[i]&0xff);
+	memset((char *)&c,0,sizeof(c));
+	return 1;
+	}
+
diff --git a/openssl/crypto/md2/md2_one.c b/openssl/crypto/md2/md2_one.c
new file mode 100644
index 0000000..f7fef5c
--- /dev/null
+++ b/openssl/crypto/md2/md2_one.c
@@ -0,0 +1,94 @@
+/* crypto/md2/md2_one.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/md2.h>
+
+/* This is a separate file so that #defines in cryptlib.h can
+ * map my MD functions to different names */
+
+unsigned char *MD2(const unsigned char *d, size_t n, unsigned char *md)
+	{
+	MD2_CTX c;
+	static unsigned char m[MD2_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	if (!MD2_Init(&c))
+		return NULL;
+#ifndef CHARSET_EBCDIC
+	MD2_Update(&c,d,n);
+#else
+	{
+		char temp[1024];
+		unsigned long chunk;
+
+		while (n > 0)
+		{
+			chunk = (n > sizeof(temp)) ? sizeof(temp) : n;
+			ebcdic2ascii(temp, d, chunk);
+			MD2_Update(&c,temp,chunk);
+			n -= chunk;
+			d += chunk;
+		}
+	}
+#endif
+	MD2_Final(md,&c);
+	OPENSSL_cleanse(&c,sizeof(c));	/* Security consideration */
+	return(md);
+	}
diff --git a/openssl/crypto/md2/md2test.c b/openssl/crypto/md2/md2test.c
new file mode 100644
index 0000000..db5f5bc
--- /dev/null
+++ b/openssl/crypto/md2/md2test.c
@@ -0,0 +1,143 @@
+/* crypto/md2/md2test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_MD2
+int main(int argc, char *argv[])
+{
+    printf("No MD2 support\n");
+    return(0);
+}
+#else
+#include <openssl/evp.h>
+#include <openssl/md2.h>
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+static char *test[]={
+	"",
+	"a",
+	"abc",
+	"message digest",
+	"abcdefghijklmnopqrstuvwxyz",
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+	"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+	NULL,
+	};
+
+static char *ret[]={
+	"8350e5a3e24c153df2275c9f80692773",
+	"32ec01ec4a6dac72c0ab96fb34c0b5d1",
+	"da853b0d3f88d99b30283a69e6ded6bb",
+	"ab4f496bfb2a530b219ff33031fe06b0",
+	"4e8ddff3650292ab5a4108c3aa47940b",
+	"da33def2a42df13975352846c30338cd",
+	"d5976f79d83d3a0dc9806c3c66f3efd8",
+	};
+
+static char *pt(unsigned char *md);
+int main(int argc, char *argv[])
+	{
+	int i,err=0;
+	char **P,**R;
+	char *p;
+	unsigned char md[MD2_DIGEST_LENGTH];
+
+	P=test;
+	R=ret;
+	i=1;
+	while (*P != NULL)
+		{
+		EVP_Digest((unsigned char *)*P,strlen(*P),md,NULL,EVP_md2(), NULL);
+		p=pt(md);
+		if (strcmp(p,*R) != 0)
+			{
+			printf("error calculating MD2 on '%s'\n",*P);
+			printf("got %s instead of %s\n",p,*R);
+			err++;
+			}
+		else
+			printf("test %d ok\n",i);
+		i++;
+		R++;
+		P++;
+		}
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
+	EXIT(err);
+	return err;
+	}
+
+static char *pt(unsigned char *md)
+	{
+	int i;
+	static char buf[80];
+
+	for (i=0; i<MD2_DIGEST_LENGTH; i++)
+		sprintf(&(buf[i*2]),"%02x",md[i]);
+	return(buf);
+	}
+#endif
diff --git a/openssl/crypto/md32_common.h b/openssl/crypto/md32_common.h
new file mode 100644
index 0000000..bb73819
--- /dev/null
+++ b/openssl/crypto/md32_common.h
@@ -0,0 +1,415 @@
+/* crypto/md32_common.h */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+/*
+ * This is a generic 32 bit "collector" for message digest algorithms.
+ * Whenever needed it collects input character stream into chunks of
+ * 32 bit values and invokes a block function that performs actual hash
+ * calculations.
+ *
+ * Porting guide.
+ *
+ * Obligatory macros:
+ *
+ * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
+ *	this macro defines byte order of input stream.
+ * HASH_CBLOCK
+ *	size of a unit chunk HASH_BLOCK operates on.
+ * HASH_LONG
+ *	has to be at lest 32 bit wide, if it's wider, then
+ *	HASH_LONG_LOG2 *has to* be defined along
+ * HASH_CTX
+ *	context structure that at least contains following
+ *	members:
+ *		typedef struct {
+ *			...
+ *			HASH_LONG	Nl,Nh;
+ *			either {
+ *			HASH_LONG	data[HASH_LBLOCK];
+ *			unsigned char	data[HASH_CBLOCK];
+ *			};
+ *			unsigned int	num;
+ *			...
+ *			} HASH_CTX;
+ *	data[] vector is expected to be zeroed upon first call to
+ *	HASH_UPDATE.
+ * HASH_UPDATE
+ *	name of "Update" function, implemented here.
+ * HASH_TRANSFORM
+ *	name of "Transform" function, implemented here.
+ * HASH_FINAL
+ *	name of "Final" function, implemented here.
+ * HASH_BLOCK_DATA_ORDER
+ *	name of "block" function capable of treating *unaligned* input
+ *	message in original (data) byte order, implemented externally.
+ * HASH_MAKE_STRING
+ *	macro convering context variables to an ASCII hash string.
+ *
+ * MD5 example:
+ *
+ *	#define DATA_ORDER_IS_LITTLE_ENDIAN
+ *
+ *	#define HASH_LONG		MD5_LONG
+ *	#define HASH_LONG_LOG2		MD5_LONG_LOG2
+ *	#define HASH_CTX		MD5_CTX
+ *	#define HASH_CBLOCK		MD5_CBLOCK
+ *	#define HASH_UPDATE		MD5_Update
+ *	#define HASH_TRANSFORM		MD5_Transform
+ *	#define HASH_FINAL		MD5_Final
+ *	#define HASH_BLOCK_DATA_ORDER	md5_block_data_order
+ *
+ *					<appro@fy.chalmers.se>
+ */
+
+#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+#error "DATA_ORDER must be defined!"
+#endif
+
+#ifndef HASH_CBLOCK
+#error "HASH_CBLOCK must be defined!"
+#endif
+#ifndef HASH_LONG
+#error "HASH_LONG must be defined!"
+#endif
+#ifndef HASH_CTX
+#error "HASH_CTX must be defined!"
+#endif
+
+#ifndef HASH_UPDATE
+#error "HASH_UPDATE must be defined!"
+#endif
+#ifndef HASH_TRANSFORM
+#error "HASH_TRANSFORM must be defined!"
+#endif
+#ifndef HASH_FINAL
+#error "HASH_FINAL must be defined!"
+#endif
+
+#ifndef HASH_BLOCK_DATA_ORDER
+#error "HASH_BLOCK_DATA_ORDER must be defined!"
+#endif
+
+/*
+ * Engage compiler specific rotate intrinsic function if available.
+ */
+#undef ROTATE
+#ifndef PEDANTIC
+# if defined(_MSC_VER) || defined(__ICC)
+#  define ROTATE(a,n)	_lrotl(a,n)
+# elif defined(__MWERKS__)
+#  if defined(__POWERPC__)
+#   define ROTATE(a,n)	__rlwinm(a,n,0,31)
+#  elif defined(__MC68K__)
+    /* Motorola specific tweak. <appro@fy.chalmers.se> */
+#   define ROTATE(a,n)	( n<24 ? __rol(a,n) : __ror(a,32-n) )
+#  else
+#   define ROTATE(a,n)	__rol(a,n)
+#  endif
+# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+  /*
+   * Some GNU C inline assembler templates. Note that these are
+   * rotates by *constant* number of bits! But that's exactly
+   * what we need here...
+   * 					<appro@fy.chalmers.se>
+   */
+#  if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+#   define ROTATE(a,n)	({ register unsigned int ret;	\
+				asm (			\
+				"roll %1,%0"		\
+				: "=r"(ret)		\
+				: "I"(n), "0"((unsigned int)(a))	\
+				: "cc");		\
+			   ret;				\
+			})
+#  elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
+	defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
+#   define ROTATE(a,n)	({ register unsigned int ret;	\
+				asm (			\
+				"rlwinm %0,%1,%2,0,31"	\
+				: "=r"(ret)		\
+				: "r"(a), "I"(n));	\
+			   ret;				\
+			})
+#  elif defined(__s390x__)
+#   define ROTATE(a,n) ({ register unsigned int ret;	\
+				asm ("rll %0,%1,%2"	\
+				: "=r"(ret)		\
+				: "r"(a), "I"(n));	\
+			  ret;				\
+			})
+#  endif
+# endif
+#endif /* PEDANTIC */
+
+#ifndef ROTATE
+#define ROTATE(a,n)     (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
+#endif
+
+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
+
+#ifndef PEDANTIC
+# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+#  if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \
+      (defined(__x86_64) || defined(__x86_64__))
+#   if !defined(B_ENDIAN)
+    /*
+     * This gives ~30-40% performance improvement in SHA-256 compiled
+     * with gcc [on P4]. Well, first macro to be frank. We can pull
+     * this trick on x86* platforms only, because these CPUs can fetch
+     * unaligned data without raising an exception.
+     */
+#   define HOST_c2l(c,l)	({ unsigned int r=*((const unsigned int *)(c));	\
+				   asm ("bswapl %0":"=r"(r):"0"(r));	\
+				   (c)+=4; (l)=r;			})
+#   define HOST_l2c(l,c)	({ unsigned int r=(l);			\
+				   asm ("bswapl %0":"=r"(r):"0"(r));	\
+				   *((unsigned int *)(c))=r; (c)+=4; r;	})
+#   endif
+#  endif
+# endif
+#endif
+#if defined(__s390__) || defined(__s390x__)
+# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l))
+# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l))
+#endif
+
+#ifndef HOST_c2l
+#define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))<<24),		\
+			 l|=(((unsigned long)(*((c)++)))<<16),		\
+			 l|=(((unsigned long)(*((c)++)))<< 8),		\
+			 l|=(((unsigned long)(*((c)++)))    ),		\
+			 l)
+#endif
+#ifndef HOST_l2c
+#define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)>>24)&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
+			 *((c)++)=(unsigned char)(((l)    )&0xff),	\
+			 l)
+#endif
+
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+
+#ifndef PEDANTIC
+# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+#  if defined(__s390x__)
+#   define HOST_c2l(c,l)	({ asm ("lrv	%0,%1"			\
+				   :"=d"(l) :"m"(*(const unsigned int *)(c)));\
+				   (c)+=4; (l);				})
+#   define HOST_l2c(l,c)	({ asm ("strv	%1,%0"			\
+				   :"=m"(*(unsigned int *)(c)) :"d"(l));\
+				   (c)+=4; (l);				})
+#  endif
+# endif
+#endif
+#if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+# ifndef B_ENDIAN
+   /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
+#  define HOST_c2l(c,l)	((l)=*((const unsigned int *)(c)), (c)+=4, l)
+#  define HOST_l2c(l,c)	(*((unsigned int *)(c))=(l), (c)+=4, l)
+# endif
+#endif
+
+#ifndef HOST_c2l
+#define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))    ),		\
+			 l|=(((unsigned long)(*((c)++)))<< 8),		\
+			 l|=(((unsigned long)(*((c)++)))<<16),		\
+			 l|=(((unsigned long)(*((c)++)))<<24),		\
+			 l)
+#endif
+#ifndef HOST_l2c
+#define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)    )&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>>24)&0xff),	\
+			 l)
+#endif
+
+#endif
+
+/*
+ * Time for some action:-)
+ */
+
+int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len)
+	{
+	const unsigned char *data=data_;
+	unsigned char *p;
+	HASH_LONG l;
+	size_t n;
+
+	if (len==0) return 1;
+
+	l=(c->Nl+(((HASH_LONG)len)<<3))&0xffffffffUL;
+	/* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
+	 * Wei Dai <weidai@eskimo.com> for pointing it out. */
+	if (l < c->Nl) /* overflow */
+		c->Nh++;
+	c->Nh+=(HASH_LONG)(len>>29);	/* might cause compiler warning on 16-bit */
+	c->Nl=l;
+
+	n = c->num;
+	if (n != 0)
+		{
+		p=(unsigned char *)c->data;
+
+		if (len >= HASH_CBLOCK || len+n >= HASH_CBLOCK)
+			{
+			memcpy (p+n,data,HASH_CBLOCK-n);
+			HASH_BLOCK_DATA_ORDER (c,p,1);
+			n      = HASH_CBLOCK-n;
+			data  += n;
+			len   -= n;
+			c->num = 0;
+			memset (p,0,HASH_CBLOCK);	/* keep it zeroed */
+			}
+		else
+			{
+			memcpy (p+n,data,len);
+			c->num += (unsigned int)len;
+			return 1;
+			}
+		}
+
+	n = len/HASH_CBLOCK;
+	if (n > 0)
+		{
+		HASH_BLOCK_DATA_ORDER (c,data,n);
+		n    *= HASH_CBLOCK;
+		data += n;
+		len  -= n;
+		}
+
+	if (len != 0)
+		{
+		p = (unsigned char *)c->data;
+		c->num = (unsigned int)len;
+		memcpy (p,data,len);
+		}
+	return 1;
+	}
+
+
+void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data)
+	{
+	HASH_BLOCK_DATA_ORDER (c,data,1);
+	}
+
+
+int HASH_FINAL (unsigned char *md, HASH_CTX *c)
+	{
+	unsigned char *p = (unsigned char *)c->data;
+	size_t n = c->num;
+
+	p[n] = 0x80; /* there is always room for one */
+	n++;
+
+	if (n > (HASH_CBLOCK-8))
+		{
+		memset (p+n,0,HASH_CBLOCK-n);
+		n=0;
+		HASH_BLOCK_DATA_ORDER (c,p,1);
+		}
+	memset (p+n,0,HASH_CBLOCK-8-n);
+
+	p += HASH_CBLOCK-8;
+#if   defined(DATA_ORDER_IS_BIG_ENDIAN)
+	(void)HOST_l2c(c->Nh,p);
+	(void)HOST_l2c(c->Nl,p);
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+	(void)HOST_l2c(c->Nl,p);
+	(void)HOST_l2c(c->Nh,p);
+#endif
+	p -= HASH_CBLOCK;
+	HASH_BLOCK_DATA_ORDER (c,p,1);
+	c->num=0;
+	memset (p,0,HASH_CBLOCK);
+
+#ifndef HASH_MAKE_STRING
+#error "HASH_MAKE_STRING must be defined!"
+#else
+	HASH_MAKE_STRING(c,md);
+#endif
+
+	return 1;
+	}
+
+#ifndef MD32_REG_T
+#if defined(__alpha) || defined(__sparcv9) || defined(__mips)
+#define MD32_REG_T long
+/*
+ * This comment was originaly written for MD5, which is why it
+ * discusses A-D. But it basically applies to all 32-bit digests,
+ * which is why it was moved to common header file.
+ *
+ * In case you wonder why A-D are declared as long and not
+ * as MD5_LONG. Doing so results in slight performance
+ * boost on LP64 architectures. The catch is we don't
+ * really care if 32 MSBs of a 64-bit register get polluted
+ * with eventual overflows as we *save* only 32 LSBs in
+ * *either* case. Now declaring 'em long excuses the compiler
+ * from keeping 32 MSBs zeroed resulting in 13% performance
+ * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
+ * Well, to be honest it should say that this *prevents* 
+ * performance degradation.
+ *				<appro@fy.chalmers.se>
+ */
+#else
+/*
+ * Above is not absolute and there are LP64 compilers that
+ * generate better code if MD32_REG_T is defined int. The above
+ * pre-processor condition reflects the circumstances under which
+ * the conclusion was made and is subject to further extension.
+ *				<appro@fy.chalmers.se>
+ */
+#define MD32_REG_T int
+#endif
+#endif
diff --git a/openssl/crypto/md4/Makefile b/openssl/crypto/md4/Makefile
new file mode 100644
index 0000000..c94a139
--- /dev/null
+++ b/openssl/crypto/md4/Makefile
@@ -0,0 +1,87 @@
+#
+# OpenSSL/crypto/md4/Makefile
+#
+
+DIR=    md4
+TOP=    ../..
+CC=     cc
+CPP=    $(CC) -E
+INCLUDES=
+CFLAG=-g
+MAKEFILE=       Makefile
+AR=             ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=md4test.c
+APPS=md4.c
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=md4_dgst.c md4_one.c
+LIBOBJ=md4_dgst.o md4_one.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= md4.h
+HEADER= md4_locl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:    lib
+
+lib:    $(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+	rm -f ../../include/openssl/$(EXHEADER) ../../test/$(TEST) ../../apps/$(APPS)
+
+clean:
+	rm -f asm/mx86unix.cpp *.o asm/*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+md4_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/md4.h
+md4_dgst.o: ../../include/openssl/opensslconf.h
+md4_dgst.o: ../../include/openssl/opensslv.h ../md32_common.h md4_dgst.c
+md4_dgst.o: md4_locl.h
+md4_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+md4_one.o: ../../include/openssl/md4.h ../../include/openssl/opensslconf.h
+md4_one.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+md4_one.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+md4_one.o: ../../include/openssl/symhacks.h md4_one.c
diff --git a/openssl/crypto/md4/md4.c b/openssl/crypto/md4/md4.c
new file mode 100644
index 0000000..141415a
--- /dev/null
+++ b/openssl/crypto/md4/md4.c
@@ -0,0 +1,127 @@
+/* crypto/md4/md4.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/md4.h>
+
+#define BUFSIZE	1024*16
+
+void do_fp(FILE *f);
+void pt(unsigned char *md);
+#if !defined(_OSD_POSIX) && !defined(__DJGPP__)
+int read(int, void *, unsigned int);
+#endif
+
+int main(int argc, char **argv)
+	{
+	int i,err=0;
+	FILE *IN;
+
+	if (argc == 1)
+		{
+		do_fp(stdin);
+		}
+	else
+		{
+		for (i=1; i<argc; i++)
+			{
+			IN=fopen(argv[i],"r");
+			if (IN == NULL)
+				{
+				perror(argv[i]);
+				err++;
+				continue;
+				}
+			printf("MD4(%s)= ",argv[i]);
+			do_fp(IN);
+			fclose(IN);
+			}
+		}
+	exit(err);
+	}
+
+void do_fp(FILE *f)
+	{
+	MD4_CTX c;
+	unsigned char md[MD4_DIGEST_LENGTH];
+	int fd;
+	int i;
+	static unsigned char buf[BUFSIZE];
+
+	fd=fileno(f);
+	MD4_Init(&c);
+	for (;;)
+		{
+		i=read(fd,buf,sizeof buf);
+		if (i <= 0) break;
+		MD4_Update(&c,buf,(unsigned long)i);
+		}
+	MD4_Final(&(md[0]),&c);
+	pt(md);
+	}
+
+void pt(unsigned char *md)
+	{
+	int i;
+
+	for (i=0; i<MD4_DIGEST_LENGTH; i++)
+		printf("%02x",md[i]);
+	printf("\n");
+	}
+
diff --git a/openssl/crypto/md4/md4.h b/openssl/crypto/md4/md4.h
new file mode 100644
index 0000000..c3ed9b3
--- /dev/null
+++ b/openssl/crypto/md4/md4.h
@@ -0,0 +1,117 @@
+/* crypto/md4/md4.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_MD4_H
+#define HEADER_MD4_H
+
+#include <openssl/e_os2.h>
+#include <stddef.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_MD4
+#error MD4 is disabled.
+#endif
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! MD4_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! MD4_LONG_LOG2 has to be defined along.			   !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#if defined(__LP32__)
+#define MD4_LONG unsigned long
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#define MD4_LONG unsigned long
+#define MD4_LONG_LOG2 3
+/*
+ * _CRAY note. I could declare short, but I have no idea what impact
+ * does it have on performance on none-T3E machines. I could declare
+ * int, but at least on C90 sizeof(int) can be chosen at compile time.
+ * So I've chosen long...
+ *					<appro@fy.chalmers.se>
+ */
+#else
+#define MD4_LONG unsigned int
+#endif
+
+#define MD4_CBLOCK	64
+#define MD4_LBLOCK	(MD4_CBLOCK/4)
+#define MD4_DIGEST_LENGTH 16
+
+typedef struct MD4state_st
+	{
+	MD4_LONG A,B,C,D;
+	MD4_LONG Nl,Nh;
+	MD4_LONG data[MD4_LBLOCK];
+	unsigned int num;
+	} MD4_CTX;
+
+int MD4_Init(MD4_CTX *c);
+int MD4_Update(MD4_CTX *c, const void *data, size_t len);
+int MD4_Final(unsigned char *md, MD4_CTX *c);
+unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md);
+void MD4_Transform(MD4_CTX *c, const unsigned char *b);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/md4/md4_dgst.c b/openssl/crypto/md4/md4_dgst.c
new file mode 100644
index 0000000..e0c42e8
--- /dev/null
+++ b/openssl/crypto/md4/md4_dgst.c
@@ -0,0 +1,167 @@
+/* crypto/md4/md4_dgst.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "md4_locl.h"
+#include <openssl/opensslv.h>
+
+const char MD4_version[]="MD4" OPENSSL_VERSION_PTEXT;
+
+/* Implemented from RFC1186 The MD4 Message-Digest Algorithm
+ */
+
+#define INIT_DATA_A (unsigned long)0x67452301L
+#define INIT_DATA_B (unsigned long)0xefcdab89L
+#define INIT_DATA_C (unsigned long)0x98badcfeL
+#define INIT_DATA_D (unsigned long)0x10325476L
+
+int MD4_Init(MD4_CTX *c)
+	{
+	memset (c,0,sizeof(*c));
+	c->A=INIT_DATA_A;
+	c->B=INIT_DATA_B;
+	c->C=INIT_DATA_C;
+	c->D=INIT_DATA_D;
+	return 1;
+	}
+
+#ifndef md4_block_data_order
+#ifdef X
+#undef X
+#endif
+void md4_block_data_order (MD4_CTX *c, const void *data_, size_t num)
+	{
+	const unsigned char *data=data_;
+	register unsigned MD32_REG_T A,B,C,D,l;
+#ifndef MD32_XARRAY
+	/* See comment in crypto/sha/sha_locl.h for details. */
+	unsigned MD32_REG_T	XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+				XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
+# define X(i)	XX##i
+#else
+	MD4_LONG XX[MD4_LBLOCK];
+# define X(i)	XX[i]
+#endif
+
+	A=c->A;
+	B=c->B;
+	C=c->C;
+	D=c->D;
+
+	for (;num--;)
+		{
+	HOST_c2l(data,l); X( 0)=l;		HOST_c2l(data,l); X( 1)=l;
+	/* Round 0 */
+	R0(A,B,C,D,X( 0), 3,0);	HOST_c2l(data,l); X( 2)=l;
+	R0(D,A,B,C,X( 1), 7,0);	HOST_c2l(data,l); X( 3)=l;
+	R0(C,D,A,B,X( 2),11,0);	HOST_c2l(data,l); X( 4)=l;
+	R0(B,C,D,A,X( 3),19,0);	HOST_c2l(data,l); X( 5)=l;
+	R0(A,B,C,D,X( 4), 3,0);	HOST_c2l(data,l); X( 6)=l;
+	R0(D,A,B,C,X( 5), 7,0);	HOST_c2l(data,l); X( 7)=l;
+	R0(C,D,A,B,X( 6),11,0);	HOST_c2l(data,l); X( 8)=l;
+	R0(B,C,D,A,X( 7),19,0);	HOST_c2l(data,l); X( 9)=l;
+	R0(A,B,C,D,X( 8), 3,0);	HOST_c2l(data,l); X(10)=l;
+	R0(D,A,B,C,X( 9), 7,0);	HOST_c2l(data,l); X(11)=l;
+	R0(C,D,A,B,X(10),11,0);	HOST_c2l(data,l); X(12)=l;
+	R0(B,C,D,A,X(11),19,0);	HOST_c2l(data,l); X(13)=l;
+	R0(A,B,C,D,X(12), 3,0);	HOST_c2l(data,l); X(14)=l;
+	R0(D,A,B,C,X(13), 7,0);	HOST_c2l(data,l); X(15)=l;
+	R0(C,D,A,B,X(14),11,0);
+	R0(B,C,D,A,X(15),19,0);
+	/* Round 1 */
+	R1(A,B,C,D,X( 0), 3,0x5A827999L);
+	R1(D,A,B,C,X( 4), 5,0x5A827999L);
+	R1(C,D,A,B,X( 8), 9,0x5A827999L);
+	R1(B,C,D,A,X(12),13,0x5A827999L);
+	R1(A,B,C,D,X( 1), 3,0x5A827999L);
+	R1(D,A,B,C,X( 5), 5,0x5A827999L);
+	R1(C,D,A,B,X( 9), 9,0x5A827999L);
+	R1(B,C,D,A,X(13),13,0x5A827999L);
+	R1(A,B,C,D,X( 2), 3,0x5A827999L);
+	R1(D,A,B,C,X( 6), 5,0x5A827999L);
+	R1(C,D,A,B,X(10), 9,0x5A827999L);
+	R1(B,C,D,A,X(14),13,0x5A827999L);
+	R1(A,B,C,D,X( 3), 3,0x5A827999L);
+	R1(D,A,B,C,X( 7), 5,0x5A827999L);
+	R1(C,D,A,B,X(11), 9,0x5A827999L);
+	R1(B,C,D,A,X(15),13,0x5A827999L);
+	/* Round 2 */
+	R2(A,B,C,D,X( 0), 3,0x6ED9EBA1L);
+	R2(D,A,B,C,X( 8), 9,0x6ED9EBA1L);
+	R2(C,D,A,B,X( 4),11,0x6ED9EBA1L);
+	R2(B,C,D,A,X(12),15,0x6ED9EBA1L);
+	R2(A,B,C,D,X( 2), 3,0x6ED9EBA1L);
+	R2(D,A,B,C,X(10), 9,0x6ED9EBA1L);
+	R2(C,D,A,B,X( 6),11,0x6ED9EBA1L);
+	R2(B,C,D,A,X(14),15,0x6ED9EBA1L);
+	R2(A,B,C,D,X( 1), 3,0x6ED9EBA1L);
+	R2(D,A,B,C,X( 9), 9,0x6ED9EBA1L);
+	R2(C,D,A,B,X( 5),11,0x6ED9EBA1L);
+	R2(B,C,D,A,X(13),15,0x6ED9EBA1L);
+	R2(A,B,C,D,X( 3), 3,0x6ED9EBA1L);
+	R2(D,A,B,C,X(11), 9,0x6ED9EBA1L);
+	R2(C,D,A,B,X( 7),11,0x6ED9EBA1L);
+	R2(B,C,D,A,X(15),15,0x6ED9EBA1L);
+
+	A = c->A += A;
+	B = c->B += B;
+	C = c->C += C;
+	D = c->D += D;
+		}
+	}
+#endif
diff --git a/openssl/crypto/md4/md4_locl.h b/openssl/crypto/md4/md4_locl.h
new file mode 100644
index 0000000..c8085b0
--- /dev/null
+++ b/openssl/crypto/md4/md4_locl.h
@@ -0,0 +1,112 @@
+/* crypto/md4/md4_locl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/opensslconf.h>
+#include <openssl/md4.h>
+
+#ifndef MD4_LONG_LOG2
+#define MD4_LONG_LOG2 2 /* default to 32 bits */
+#endif
+
+void md4_block_data_order (MD4_CTX *c, const void *p,size_t num);
+
+#define DATA_ORDER_IS_LITTLE_ENDIAN
+
+#define HASH_LONG		MD4_LONG
+#define HASH_CTX		MD4_CTX
+#define HASH_CBLOCK		MD4_CBLOCK
+#define HASH_UPDATE		MD4_Update
+#define HASH_TRANSFORM		MD4_Transform
+#define HASH_FINAL		MD4_Final
+#define	HASH_MAKE_STRING(c,s)	do {	\
+	unsigned long ll;		\
+	ll=(c)->A; HOST_l2c(ll,(s));	\
+	ll=(c)->B; HOST_l2c(ll,(s));	\
+	ll=(c)->C; HOST_l2c(ll,(s));	\
+	ll=(c)->D; HOST_l2c(ll,(s));	\
+	} while (0)
+#define	HASH_BLOCK_DATA_ORDER	md4_block_data_order
+
+#include "md32_common.h"
+
+/*
+#define	F(x,y,z)	(((x) & (y))  |  ((~(x)) & (z)))
+#define	G(x,y,z)	(((x) & (y))  |  ((x) & ((z))) | ((y) & ((z))))
+*/
+
+/* As pointed out by Wei Dai <weidai@eskimo.com>, the above can be
+ * simplified to the code below.  Wei attributes these optimizations
+ * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
+ */
+#define	F(b,c,d)	((((c) ^ (d)) & (b)) ^ (d))
+#define G(b,c,d)	(((b) & (c)) | ((b) & (d)) | ((c) & (d)))
+#define	H(b,c,d)	((b) ^ (c) ^ (d))
+
+#define R0(a,b,c,d,k,s,t) { \
+	a+=((k)+(t)+F((b),(c),(d))); \
+	a=ROTATE(a,s); };
+
+#define R1(a,b,c,d,k,s,t) { \
+	a+=((k)+(t)+G((b),(c),(d))); \
+	a=ROTATE(a,s); };\
+
+#define R2(a,b,c,d,k,s,t) { \
+	a+=((k)+(t)+H((b),(c),(d))); \
+	a=ROTATE(a,s); };
diff --git a/openssl/crypto/md4/md4_one.c b/openssl/crypto/md4/md4_one.c
new file mode 100644
index 0000000..bb64362
--- /dev/null
+++ b/openssl/crypto/md4/md4_one.c
@@ -0,0 +1,97 @@
+/* crypto/md4/md4_one.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/md4.h>
+#include <openssl/crypto.h>
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md)
+	{
+	MD4_CTX c;
+	static unsigned char m[MD4_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	if (!MD4_Init(&c))
+		return NULL;
+#ifndef CHARSET_EBCDIC
+	MD4_Update(&c,d,n);
+#else
+	{
+		char temp[1024];
+		unsigned long chunk;
+
+		while (n > 0)
+		{
+			chunk = (n > sizeof(temp)) ? sizeof(temp) : n;
+			ebcdic2ascii(temp, d, chunk);
+			MD4_Update(&c,temp,chunk);
+			n -= chunk;
+			d += chunk;
+		}
+	}
+#endif
+	MD4_Final(md,&c);
+	OPENSSL_cleanse(&c,sizeof(c)); /* security consideration */
+	return(md);
+	}
+
diff --git a/openssl/crypto/md4/md4s.cpp b/openssl/crypto/md4/md4s.cpp
new file mode 100644
index 0000000..c0ec97f
--- /dev/null
+++ b/openssl/crypto/md4/md4s.cpp
@@ -0,0 +1,78 @@
+//
+// gettsc.inl
+//
+// gives access to the Pentium's (secret) cycle counter
+//
+// This software was written by Leonard Janke (janke@unixg.ubc.ca)
+// in 1996-7 and is entered, by him, into the public domain.
+
+#if defined(__WATCOMC__)
+void GetTSC(unsigned long&);
+#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
+#elif defined(__GNUC__)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  asm volatile(".byte 15, 49\n\t"
+	       : "=eax" (tsc)
+	       :
+	       : "%edx", "%eax");
+}
+#elif defined(_MSC_VER)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  unsigned long a;
+  __asm _emit 0fh
+  __asm _emit 31h
+  __asm mov a, eax;
+  tsc=a;
+}
+#endif      
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/md4.h>
+
+extern "C" {
+void md4_block_x86(MD4_CTX *ctx, unsigned char *buffer,int num);
+}
+
+void main(int argc,char *argv[])
+	{
+	unsigned char buffer[64*256];
+	MD4_CTX ctx;
+	unsigned long s1,s2,e1,e2;
+	unsigned char k[16];
+	unsigned long data[2];
+	unsigned char iv[8];
+	int i,num=0,numm;
+	int j=0;
+
+	if (argc >= 2)
+		num=atoi(argv[1]);
+
+	if (num == 0) num=16;
+	if (num > 250) num=16;
+	numm=num+2;
+	num*=64;
+	numm*=64;
+
+	for (j=0; j<6; j++)
+		{
+		for (i=0; i<10; i++) /**/
+			{
+			md4_block_x86(&ctx,buffer,numm);
+			GetTSC(s1);
+			md4_block_x86(&ctx,buffer,numm);
+			GetTSC(e1);
+			GetTSC(s2);
+			md4_block_x86(&ctx,buffer,num);
+			GetTSC(e2);
+			md4_block_x86(&ctx,buffer,num);
+			}
+		printf("md4 (%d bytes) %d %d (%.2f)\n",num,
+			e1-s1,e2-s2,(double)((e1-s1)-(e2-s2))/2);
+		}
+	}
+
diff --git a/openssl/crypto/md4/md4test.c b/openssl/crypto/md4/md4test.c
new file mode 100644
index 0000000..5659172
--- /dev/null
+++ b/openssl/crypto/md4/md4test.c
@@ -0,0 +1,136 @@
+/* crypto/md4/md4test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_MD4
+int main(int argc, char *argv[])
+{
+    printf("No MD4 support\n");
+    return(0);
+}
+#else
+#include <openssl/evp.h>
+#include <openssl/md4.h>
+
+static char *test[]={
+	"",
+	"a",
+	"abc",
+	"message digest",
+	"abcdefghijklmnopqrstuvwxyz",
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+	"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+	NULL,
+	};
+
+static char *ret[]={
+"31d6cfe0d16ae931b73c59d7e0c089c0",
+"bde52cb31de33e46245e05fbdbd6fb24",
+"a448017aaf21d8525fc10ae87aa6729d",
+"d9130a8164549fe818874806e1c7014b",
+"d79e1c308aa5bbcdeea8ed63df412da9",
+"043f8582f241db351ce627e153e7f0e4",
+"e33b4ddc9c38f2199c3e7b164fcc0536",
+};
+
+static char *pt(unsigned char *md);
+int main(int argc, char *argv[])
+	{
+	int i,err=0;
+	char **P,**R;
+	char *p;
+	unsigned char md[MD4_DIGEST_LENGTH];
+
+	P=test;
+	R=ret;
+	i=1;
+	while (*P != NULL)
+		{
+		EVP_Digest(&(P[0][0]),strlen((char *)*P),md,NULL,EVP_md4(), NULL);
+		p=pt(md);
+		if (strcmp(p,(char *)*R) != 0)
+			{
+			printf("error calculating MD4 on '%s'\n",*P);
+			printf("got %s instead of %s\n",p,*R);
+			err++;
+			}
+		else
+			printf("test %d ok\n",i);
+		i++;
+		R++;
+		P++;
+		}
+	EXIT(err);
+	return(0);
+	}
+
+static char *pt(unsigned char *md)
+	{
+	int i;
+	static char buf[80];
+
+	for (i=0; i<MD4_DIGEST_LENGTH; i++)
+		sprintf(&(buf[i*2]),"%02x",md[i]);
+	return(buf);
+	}
+#endif
diff --git a/openssl/crypto/md5/Makefile b/openssl/crypto/md5/Makefile
new file mode 100644
index 0000000..9858d53
--- /dev/null
+++ b/openssl/crypto/md5/Makefile
@@ -0,0 +1,100 @@
+#
+# OpenSSL/crypto/md5/Makefile
+#
+
+DIR=    md5
+TOP=    ../..
+CC=     cc
+CPP=    $(CC) -E
+INCLUDES=-I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=       Makefile
+AR=             ar r
+
+MD5_ASM_OBJ=
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+ASFLAGS= $(INCLUDES) $(ASFLAG)
+AFLAGS= $(ASFLAGS)
+
+GENERAL=Makefile
+TEST=md5test.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=md5_dgst.c md5_one.c
+LIBOBJ=md5_dgst.o md5_one.o $(MD5_ASM_OBJ)
+
+SRC= $(LIBSRC)
+
+EXHEADER= md5.h
+HEADER= md5_locl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:    lib
+
+lib:    $(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+md5-586.s:	asm/md5-586.pl ../perlasm/x86asm.pl
+	$(PERL) asm/md5-586.pl $(PERLASM_SCHEME) $(CFLAGS) > $@
+
+md5-x86_64.s:	asm/md5-x86_64.pl
+	$(PERL) asm/md5-x86_64.pl $(PERLASM_SCHEME) > $@
+
+md5-ia64.s: asm/md5-ia64.S
+	$(CC) $(CFLAGS) -E asm/md5-ia64.S | \
+	$(PERL) -ne 's/;\s+/;\n/g; print;' > $@
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+md5_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/md5.h
+md5_dgst.o: ../../include/openssl/opensslconf.h
+md5_dgst.o: ../../include/openssl/opensslv.h ../md32_common.h md5_dgst.c
+md5_dgst.o: md5_locl.h
+md5_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+md5_one.o: ../../include/openssl/md5.h ../../include/openssl/opensslconf.h
+md5_one.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+md5_one.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+md5_one.o: ../../include/openssl/symhacks.h md5_one.c
diff --git a/openssl/crypto/md5/asm/md5-586.pl b/openssl/crypto/md5/asm/md5-586.pl
new file mode 100644
index 0000000..6cb66bb
--- /dev/null
+++ b/openssl/crypto/md5/asm/md5-586.pl
@@ -0,0 +1,307 @@
+#!/usr/local/bin/perl
+
+# Normal is the
+# md5_block_x86(MD5_CTX *c, ULONG *X);
+# version, non-normal is the
+# md5_block_x86(MD5_CTX *c, ULONG *X,int blocks);
+
+$normal=0;
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],$0);
+
+$A="eax";
+$B="ebx";
+$C="ecx";
+$D="edx";
+$tmp1="edi";
+$tmp2="ebp";
+$X="esi";
+
+# What we need to load into $tmp for the next round
+%Ltmp1=("R0",&Np($C), "R1",&Np($C), "R2",&Np($C), "R3",&Np($D));
+@xo=(
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,	# R0
+ 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12,	# R1
+ 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2,	# R2
+ 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9,	# R3
+ );
+
+&md5_block("md5_block_asm_data_order");
+&asm_finish();
+
+sub Np
+	{
+	local($p)=@_;
+	local(%n)=($A,$D,$B,$A,$C,$B,$D,$C);
+	return($n{$p});
+	}
+
+sub R0
+	{
+	local($pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_;
+
+	&mov($tmp1,$C)  if $pos < 0;
+	&mov($tmp2,&DWP($xo[$ki]*4,$K,"",0)) if $pos < 0; # very first one 
+
+	# body proper
+
+	&comment("R0 $ki");
+	&xor($tmp1,$d); # F function - part 2
+
+	&and($tmp1,$b); # F function - part 3
+	&lea($a,&DWP($t,$a,$tmp2,1));
+
+	&xor($tmp1,$d); # F function - part 4
+
+	&add($a,$tmp1);
+	&mov($tmp1,&Np($c)) if $pos < 1;	# next tmp1 for R0
+	&mov($tmp1,&Np($c)) if $pos == 1;	# next tmp1 for R1
+
+	&rotl($a,$s);
+
+	&mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2);
+
+	&add($a,$b);
+	}
+
+sub R1
+	{
+	local($pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_;
+
+	&comment("R1 $ki");
+
+	&lea($a,&DWP($t,$a,$tmp2,1));
+
+	&xor($tmp1,$b); # G function - part 2
+	&and($tmp1,$d); # G function - part 3
+
+	&mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2);
+	&xor($tmp1,$c);			# G function - part 4
+
+	&add($a,$tmp1);
+	&mov($tmp1,&Np($c)) if $pos < 1;	# G function - part 1
+	&mov($tmp1,&Np($c)) if $pos == 1;	# G function - part 1
+
+	&rotl($a,$s);
+
+	&add($a,$b);
+	}
+
+sub R2
+	{
+	local($n,$pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_;
+	# This one is different, only 3 logical operations
+
+if (($n & 1) == 0)
+	{
+	&comment("R2 $ki");
+	# make sure to do 'D' first, not 'B', else we clash with
+	# the last add from the previous round.
+
+	&xor($tmp1,$d); # H function - part 2
+
+	&xor($tmp1,$b); # H function - part 3
+	&lea($a,&DWP($t,$a,$tmp2,1));
+
+	&add($a,$tmp1);
+
+	&rotl($a,$s);
+
+	&mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0));
+	&mov($tmp1,&Np($c));
+	}
+else
+	{
+	&comment("R2 $ki");
+	# make sure to do 'D' first, not 'B', else we clash with
+	# the last add from the previous round.
+
+	&lea($a,&DWP($t,$a,$tmp2,1));
+
+	&add($b,$c);			# MOVED FORWARD
+	&xor($tmp1,$d); # H function - part 2
+
+	&xor($tmp1,$b); # H function - part 3
+	&mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2);
+
+	&add($a,$tmp1);
+	&mov($tmp1,&Np($c)) if $pos < 1;	# H function - part 1
+	&mov($tmp1,-1) if $pos == 1;		# I function - part 1
+
+	&rotl($a,$s);
+
+	&add($a,$b);
+	}
+	}
+
+sub R3
+	{
+	local($pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_;
+
+	&comment("R3 $ki");
+
+	# &not($tmp1)
+	&xor($tmp1,$d) if $pos < 0; 	# I function - part 2
+
+	&or($tmp1,$b);				# I function - part 3
+	&lea($a,&DWP($t,$a,$tmp2,1));
+
+	&xor($tmp1,$c); 			# I function - part 4
+	&mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0))	if $pos != 2; # load X/k value
+	&mov($tmp2,&wparam(0)) if $pos == 2;
+
+	&add($a,$tmp1);
+	&mov($tmp1,-1) if $pos < 1;	# H function - part 1
+	&add($K,64) if $pos >=1 && !$normal;
+
+	&rotl($a,$s);
+
+	&xor($tmp1,&Np($d)) if $pos <= 0; 	# I function - part = first time
+	&mov($tmp1,&DWP( 0,$tmp2,"",0)) if $pos > 0;
+	&add($a,$b);
+	}
+
+
+sub md5_block
+	{
+	local($name)=@_;
+
+	&function_begin_B($name,"",3);
+
+	# parameter 1 is the MD5_CTX structure.
+	# A	0
+	# B	4
+	# C	8
+	# D 	12
+
+	&push("esi");
+	 &push("edi");
+	&mov($tmp1,	&wparam(0)); # edi
+	 &mov($X,	&wparam(1)); # esi
+	&mov($C,	&wparam(2));
+	 &push("ebp");
+	&shl($C,	6);
+	&push("ebx");
+	 &add($C,	$X); # offset we end at
+	&sub($C,	64);
+	 &mov($A,	&DWP( 0,$tmp1,"",0));
+	&push($C);	# Put on the TOS
+	 &mov($B,	&DWP( 4,$tmp1,"",0));
+	&mov($C,	&DWP( 8,$tmp1,"",0));
+	 &mov($D,	&DWP(12,$tmp1,"",0));
+
+	&set_label("start") unless $normal;
+	&comment("");
+	&comment("R0 section");
+
+	&R0(-2,$A,$B,$C,$D,$X, 0, 7,0xd76aa478);
+	&R0( 0,$D,$A,$B,$C,$X, 1,12,0xe8c7b756);
+	&R0( 0,$C,$D,$A,$B,$X, 2,17,0x242070db);
+	&R0( 0,$B,$C,$D,$A,$X, 3,22,0xc1bdceee);
+	&R0( 0,$A,$B,$C,$D,$X, 4, 7,0xf57c0faf);
+	&R0( 0,$D,$A,$B,$C,$X, 5,12,0x4787c62a);
+	&R0( 0,$C,$D,$A,$B,$X, 6,17,0xa8304613);
+	&R0( 0,$B,$C,$D,$A,$X, 7,22,0xfd469501);
+	&R0( 0,$A,$B,$C,$D,$X, 8, 7,0x698098d8);
+	&R0( 0,$D,$A,$B,$C,$X, 9,12,0x8b44f7af);
+	&R0( 0,$C,$D,$A,$B,$X,10,17,0xffff5bb1);
+	&R0( 0,$B,$C,$D,$A,$X,11,22,0x895cd7be);
+	&R0( 0,$A,$B,$C,$D,$X,12, 7,0x6b901122);
+	&R0( 0,$D,$A,$B,$C,$X,13,12,0xfd987193);
+	&R0( 0,$C,$D,$A,$B,$X,14,17,0xa679438e);
+	&R0( 1,$B,$C,$D,$A,$X,15,22,0x49b40821);
+
+	&comment("");
+	&comment("R1 section");
+	&R1(-1,$A,$B,$C,$D,$X,16, 5,0xf61e2562);
+	&R1( 0,$D,$A,$B,$C,$X,17, 9,0xc040b340);
+	&R1( 0,$C,$D,$A,$B,$X,18,14,0x265e5a51);
+	&R1( 0,$B,$C,$D,$A,$X,19,20,0xe9b6c7aa);
+	&R1( 0,$A,$B,$C,$D,$X,20, 5,0xd62f105d);
+	&R1( 0,$D,$A,$B,$C,$X,21, 9,0x02441453);
+	&R1( 0,$C,$D,$A,$B,$X,22,14,0xd8a1e681);
+	&R1( 0,$B,$C,$D,$A,$X,23,20,0xe7d3fbc8);
+	&R1( 0,$A,$B,$C,$D,$X,24, 5,0x21e1cde6);
+	&R1( 0,$D,$A,$B,$C,$X,25, 9,0xc33707d6);
+	&R1( 0,$C,$D,$A,$B,$X,26,14,0xf4d50d87);
+	&R1( 0,$B,$C,$D,$A,$X,27,20,0x455a14ed);
+	&R1( 0,$A,$B,$C,$D,$X,28, 5,0xa9e3e905);
+	&R1( 0,$D,$A,$B,$C,$X,29, 9,0xfcefa3f8);
+	&R1( 0,$C,$D,$A,$B,$X,30,14,0x676f02d9);
+	&R1( 1,$B,$C,$D,$A,$X,31,20,0x8d2a4c8a);
+
+	&comment("");
+	&comment("R2 section");
+	&R2( 0,-1,$A,$B,$C,$D,$X,32, 4,0xfffa3942);
+	&R2( 1, 0,$D,$A,$B,$C,$X,33,11,0x8771f681);
+	&R2( 2, 0,$C,$D,$A,$B,$X,34,16,0x6d9d6122);
+	&R2( 3, 0,$B,$C,$D,$A,$X,35,23,0xfde5380c);
+	&R2( 4, 0,$A,$B,$C,$D,$X,36, 4,0xa4beea44);
+	&R2( 5, 0,$D,$A,$B,$C,$X,37,11,0x4bdecfa9);
+	&R2( 6, 0,$C,$D,$A,$B,$X,38,16,0xf6bb4b60);
+	&R2( 7, 0,$B,$C,$D,$A,$X,39,23,0xbebfbc70);
+	&R2( 8, 0,$A,$B,$C,$D,$X,40, 4,0x289b7ec6);
+	&R2( 9, 0,$D,$A,$B,$C,$X,41,11,0xeaa127fa);
+	&R2(10, 0,$C,$D,$A,$B,$X,42,16,0xd4ef3085);
+	&R2(11, 0,$B,$C,$D,$A,$X,43,23,0x04881d05);
+	&R2(12, 0,$A,$B,$C,$D,$X,44, 4,0xd9d4d039);
+	&R2(13, 0,$D,$A,$B,$C,$X,45,11,0xe6db99e5);
+	&R2(14, 0,$C,$D,$A,$B,$X,46,16,0x1fa27cf8);
+	&R2(15, 1,$B,$C,$D,$A,$X,47,23,0xc4ac5665);
+
+	&comment("");
+	&comment("R3 section");
+	&R3(-1,$A,$B,$C,$D,$X,48, 6,0xf4292244);
+	&R3( 0,$D,$A,$B,$C,$X,49,10,0x432aff97);
+	&R3( 0,$C,$D,$A,$B,$X,50,15,0xab9423a7);
+	&R3( 0,$B,$C,$D,$A,$X,51,21,0xfc93a039);
+	&R3( 0,$A,$B,$C,$D,$X,52, 6,0x655b59c3);
+	&R3( 0,$D,$A,$B,$C,$X,53,10,0x8f0ccc92);
+	&R3( 0,$C,$D,$A,$B,$X,54,15,0xffeff47d);
+	&R3( 0,$B,$C,$D,$A,$X,55,21,0x85845dd1);
+	&R3( 0,$A,$B,$C,$D,$X,56, 6,0x6fa87e4f);
+	&R3( 0,$D,$A,$B,$C,$X,57,10,0xfe2ce6e0);
+	&R3( 0,$C,$D,$A,$B,$X,58,15,0xa3014314);
+	&R3( 0,$B,$C,$D,$A,$X,59,21,0x4e0811a1);
+	&R3( 0,$A,$B,$C,$D,$X,60, 6,0xf7537e82);
+	&R3( 0,$D,$A,$B,$C,$X,61,10,0xbd3af235);
+	&R3( 0,$C,$D,$A,$B,$X,62,15,0x2ad7d2bb);
+	&R3( 2,$B,$C,$D,$A,$X,63,21,0xeb86d391);
+
+	# &mov($tmp2,&wparam(0));	# done in the last R3
+	# &mov($tmp1,	&DWP( 0,$tmp2,"",0)); # done is the last R3
+
+	&add($A,$tmp1);
+	 &mov($tmp1,	&DWP( 4,$tmp2,"",0));
+
+	&add($B,$tmp1);
+	&mov($tmp1,	&DWP( 8,$tmp2,"",0));
+
+	&add($C,$tmp1);
+	&mov($tmp1,	&DWP(12,$tmp2,"",0));
+
+	&add($D,$tmp1);
+	&mov(&DWP( 0,$tmp2,"",0),$A);
+
+	&mov(&DWP( 4,$tmp2,"",0),$B);
+	&mov($tmp1,&swtmp(0)) unless $normal;
+
+	&mov(&DWP( 8,$tmp2,"",0),$C);
+	 &mov(&DWP(12,$tmp2,"",0),$D);
+
+	&cmp($tmp1,$X) unless $normal;			# check count
+	 &jae(&label("start")) unless $normal;
+
+	&pop("eax"); # pop the temp variable off the stack
+	 &pop("ebx");
+	&pop("ebp");
+	 &pop("edi");
+	&pop("esi");
+	 &ret();
+	&function_end_B($name);
+	}
+
diff --git a/openssl/crypto/md5/asm/md5-ia64.S b/openssl/crypto/md5/asm/md5-ia64.S
new file mode 100644
index 0000000..e7de08d
--- /dev/null
+++ b/openssl/crypto/md5/asm/md5-ia64.S
@@ -0,0 +1,992 @@
+/* Copyright (c) 2005 Hewlett-Packard Development Company, L.P.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+//	Common registers are assigned as follows:
+//
+//	COMMON
+//
+//	t0		Const Tbl Ptr	TPtr
+//	t1		Round Constant	TRound
+//	t4		Block residual	LenResid
+//	t5		Residual Data	DTmp
+//
+//	{in,out}0	Block 0 Cycle	RotateM0
+//	{in,out}1	Block Value 12	M12
+//	{in,out}2	Block Value 8	M8
+//	{in,out}3	Block Value 4	M4
+//	{in,out}4	Block Value 0	M0
+//	{in,out}5	Block 1 Cycle	RotateM1
+//	{in,out}6	Block Value 13	M13
+//	{in,out}7	Block Value 9	M9
+//	{in,out}8	Block Value 5	M5
+//	{in,out}9	Block Value 1	M1
+//	{in,out}10	Block 2 Cycle	RotateM2
+//	{in,out}11	Block Value 14	M14
+//	{in,out}12	Block Value 10	M10
+//	{in,out}13	Block Value 6	M6
+//	{in,out}14	Block Value 2	M2
+//	{in,out}15	Block 3 Cycle	RotateM3
+//	{in,out}16	Block Value 15	M15
+//	{in,out}17	Block Value 11	M11
+//	{in,out}18	Block Value 7	M7
+//	{in,out}19	Block Value 3	M3
+//	{in,out}20	Scratch			Z
+//	{in,out}21	Scratch			Y
+//	{in,out}22	Scratch			X
+//	{in,out}23	Scratch			W
+//	{in,out}24	Digest A		A
+//	{in,out}25	Digest B		B
+//	{in,out}26	Digest C		C
+//	{in,out}27	Digest D		D
+//	{in,out}28	Active Data Ptr	DPtr
+//	in28		Dummy Value		-
+//	out28		Dummy Value		-
+//	bt0			Coroutine Link	QUICK_RTN
+//
+///	These predicates are used for computing the padding block(s) and
+///	are shared between the driver and digest co-routines
+//
+//	pt0			Extra Pad Block	pExtra
+//	pt1			Load next word	pLoad
+//	pt2			Skip next word	pSkip
+//	pt3			Search for Pad	pNoPad
+//	pt4			Pad Word 0		pPad0
+//	pt5			Pad Word 1		pPad1
+//	pt6			Pad Word 2		pPad2
+//	pt7			Pad Word 3		pPad3
+
+#define	DTmp		r19
+#define	LenResid	r18
+#define	QUICK_RTN	b6
+#define	TPtr		r14
+#define	TRound		r15
+#define	pExtra		p6
+#define	pLoad		p7
+#define	pNoPad		p9
+#define	pPad0		p10
+#define	pPad1		p11
+#define	pPad2		p12
+#define	pPad3		p13
+#define	pSkip		p8
+
+#define	A_		out24
+#define	B_		out25
+#define	C_		out26
+#define	D_		out27
+#define	DPtr_		out28
+#define	M0_		out4
+#define	M1_		out9
+#define	M10_		out12
+#define	M11_		out17
+#define	M12_		out1
+#define	M13_		out6
+#define	M14_		out11
+#define	M15_		out16
+#define	M2_		out14
+#define	M3_		out19
+#define	M4_		out3
+#define	M5_		out8
+#define	M6_		out13
+#define	M7_		out18
+#define	M8_		out2
+#define	M9_		out7
+#define	RotateM0_	out0
+#define	RotateM1_	out5
+#define	RotateM2_	out10
+#define	RotateM3_	out15
+#define	W_		out23
+#define	X_		out22
+#define	Y_		out21
+#define	Z_		out20
+
+#define	A		in24
+#define	B		in25
+#define	C		in26
+#define	D		in27
+#define	DPtr		in28
+#define	M0		in4
+#define	M1		in9
+#define	M10		in12
+#define	M11		in17
+#define	M12		in1
+#define	M13		in6
+#define	M14		in11
+#define	M15		in16
+#define	M2		in14
+#define	M3		in19
+#define	M4		in3
+#define	M5		in8
+#define	M6		in13
+#define	M7		in18
+#define	M8		in2
+#define	M9		in7
+#define	RotateM0	in0
+#define	RotateM1	in5
+#define	RotateM2	in10
+#define	RotateM3	in15
+#define	W		in23
+#define	X		in22
+#define	Y		in21
+#define	Z		in20
+
+/* register stack configuration for md5_block_asm_data_order(): */
+#define	MD5_NINP	3
+#define	MD5_NLOC	0
+#define MD5_NOUT	29
+#define MD5_NROT	0
+
+/* register stack configuration for helpers: */
+#define	_NINPUTS	MD5_NOUT
+#define	_NLOCALS	0
+#define _NOUTPUT	0
+#define	_NROTATE	24	/* this must be <= _NINPUTS */
+
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+#define	ADDP	addp4
+#else
+#define	ADDP	add
+#endif
+
+#if defined(_HPUX_SOURCE) || defined(B_ENDIAN)
+#define HOST_IS_BIG_ENDIAN
+#endif
+
+//	Macros for getting the left and right portions of little-endian words
+
+#define	GETLW(dst, src, align)	dep.z dst = src, 32 - 8 * align, 8 * align
+#define	GETRW(dst, src, align)	extr.u dst = src, 8 * align, 32 - 8 * align
+
+//	MD5 driver
+//
+//		Reads an input block, then calls the digest block
+//		subroutine and adds the results to the accumulated
+//		digest.  It allocates 32 outs which the subroutine
+//		uses as it's inputs and rotating
+//		registers. Initializes the round constant pointer and
+//		takes care of saving/restoring ar.lc
+//
+///	INPUT
+//
+//	in0		Context Ptr		CtxPtr0
+//	in1		Input Data Ptr		DPtrIn
+//	in2		Integral Blocks		BlockCount
+//	rp		Return Address		-
+//
+///	CODE
+//
+//	v2		Input Align		InAlign
+//	t0		Shared w/digest		-
+//	t1		Shared w/digest		-
+//	t2		Shared w/digest		-
+//	t3		Shared w/digest		-
+//	t4		Shared w/digest		-
+//	t5		Shared w/digest		-
+//	t6		PFS Save		PFSSave
+//	t7		ar.lc Save		LCSave
+//	t8		Saved PR		PRSave
+//	t9		2nd CtxPtr		CtxPtr1
+//	t10		Table Base		CTable
+//	t11		Table[0]		CTable0
+//	t13		Accumulator A		AccumA
+//	t14		Accumulator B		AccumB
+//	t15		Accumulator C		AccumC
+//	t16		Accumulator D		AccumD
+//	pt0		Shared w/digest		-
+//	pt1		Shared w/digest		-
+//	pt2		Shared w/digest		-
+//	pt3		Shared w/digest		-
+//	pt4		Shared w/digest		-
+//	pt5		Shared w/digest		-
+//	pt6		Shared w/digest		-
+//	pt7		Shared w/digest		-
+//	pt8		Not Aligned		pOff
+//	pt8		Blocks Left		pAgain
+
+#define	AccumA		r27
+#define	AccumB		r28
+#define	AccumC		r29
+#define	AccumD		r30
+#define	CTable		r24
+#define	CTable0		r25
+#define	CtxPtr0		in0
+#define	CtxPtr1		r23
+#define	DPtrIn		in1
+#define	BlockCount	in2
+#define	InAlign		r10
+#define	LCSave		r21
+#define	PFSSave		r20
+#define	PRSave		r22
+#define	pAgain		p63
+#define	pOff		p63
+
+	.text
+
+/* md5_block_asm_data_order(MD5_CTX *c, const void *data, size_t num)
+
+     where:
+      c: a pointer to a structure of this type:
+
+	   typedef struct MD5state_st
+	     {
+	       MD5_LONG A,B,C,D;
+	       MD5_LONG Nl,Nh;
+	       MD5_LONG data[MD5_LBLOCK];
+	       unsigned int num;
+	     }
+	   MD5_CTX;
+
+      data: a pointer to the input data (may be misaligned)
+      num:  the number of 16-byte blocks to hash (i.e., the length
+            of DATA is 16*NUM.
+
+   */
+
+	.type	md5_block_asm_data_order, @function
+	.global	md5_block_asm_data_order
+	.align	32
+	.proc	md5_block_asm_data_order
+md5_block_asm_data_order:
+.md5_block:
+	.prologue
+{	.mmi
+	.save	ar.pfs, PFSSave
+	alloc	PFSSave = ar.pfs, MD5_NINP, MD5_NLOC, MD5_NOUT, MD5_NROT
+	ADDP	CtxPtr1 = 8, CtxPtr0
+	mov	CTable = ip
+}
+{	.mmi
+	ADDP	DPtrIn = 0, DPtrIn
+	ADDP	CtxPtr0 = 0, CtxPtr0
+	.save	ar.lc, LCSave
+	mov	LCSave = ar.lc
+}
+;;
+{	.mmi
+	add	CTable = .md5_tbl_data_order#-.md5_block#, CTable
+	and	InAlign = 0x3, DPtrIn
+}
+
+{	.mmi
+	ld4	AccumA = [CtxPtr0], 4
+	ld4	AccumC = [CtxPtr1], 4
+	.save pr, PRSave
+	mov	PRSave = pr
+	.body
+}
+;;
+{	.mmi
+	ld4	AccumB = [CtxPtr0]
+	ld4	AccumD = [CtxPtr1]
+	dep	DPtr_ = 0, DPtrIn, 0, 2
+} ;;
+#ifdef HOST_IS_BIG_ENDIAN
+	rum	psr.be;;	// switch to little-endian
+#endif
+{	.mmb
+	ld4	CTable0 = [CTable], 4
+	cmp.ne	pOff, p0 = 0, InAlign
+(pOff)	br.cond.spnt.many .md5_unaligned
+} ;;
+
+//	The FF load/compute loop rotates values three times, so that
+//	loading into M12 here produces the M0 value, M13 -> M1, etc.
+
+.md5_block_loop0:
+{	.mmi
+	ld4	M12_ = [DPtr_], 4
+	mov	TPtr = CTable
+	mov	TRound = CTable0
+} ;;
+{	.mmi
+	ld4	M13_ = [DPtr_], 4
+	mov	A_ = AccumA
+	mov	B_ = AccumB
+} ;;
+{	.mmi
+	ld4	M14_ = [DPtr_], 4
+	mov	C_ = AccumC
+	mov	D_ = AccumD
+} ;;
+{	.mmb
+	ld4	M15_ = [DPtr_], 4
+	add	BlockCount = -1, BlockCount
+	br.call.sptk.many QUICK_RTN = md5_digest_block0
+} ;;
+
+//	Now, we add the new digest values and do some clean-up
+//	before checking if there's another full block to process
+
+{	.mmi
+	add	AccumA = AccumA, A_
+	add	AccumB = AccumB, B_
+	cmp.ne	pAgain, p0 = 0, BlockCount
+}
+{	.mib
+	add	AccumC = AccumC, C_
+	add	AccumD = AccumD, D_
+(pAgain) br.cond.dptk.many .md5_block_loop0
+} ;;
+
+.md5_exit:
+#ifdef HOST_IS_BIG_ENDIAN
+	sum	psr.be;;	// switch back to big-endian mode
+#endif
+{	.mmi
+	st4	[CtxPtr0] = AccumB, -4
+	st4	[CtxPtr1] = AccumD, -4
+	mov	pr = PRSave, 0x1ffff ;;
+}
+{	.mmi
+	st4	[CtxPtr0] = AccumA
+	st4	[CtxPtr1] = AccumC
+	mov	ar.lc = LCSave
+} ;;
+{	.mib
+	mov	ar.pfs = PFSSave
+	br.ret.sptk.few	rp
+} ;;
+
+#define	MD5UNALIGNED(offset)						\
+.md5_process##offset:							\
+{	.mib ;								\
+	nop	0x0	;						\
+	GETRW(DTmp, DTmp, offset) ;					\
+} ;;									\
+.md5_block_loop##offset:						\
+{	.mmi ;								\
+	ld4	Y_ = [DPtr_], 4 ;					\
+	mov	TPtr = CTable ;						\
+	mov	TRound = CTable0 ;					\
+} ;;									\
+{	.mmi ;								\
+	ld4	M13_ = [DPtr_], 4 ;					\
+	mov	A_ = AccumA ;						\
+	mov	B_ = AccumB ;						\
+} ;;									\
+{	.mii ;								\
+	ld4	M14_ = [DPtr_], 4 ;					\
+	GETLW(W_, Y_, offset) ;						\
+	mov	C_ = AccumC ;						\
+}									\
+{	.mmi ;								\
+	mov	D_ = AccumD ;;						\
+	or	M12_ = W_, DTmp ;					\
+	GETRW(DTmp, Y_, offset) ;					\
+}									\
+{	.mib ;								\
+	ld4	M15_ = [DPtr_], 4 ;					\
+	add	BlockCount = -1, BlockCount ;				\
+	br.call.sptk.many QUICK_RTN = md5_digest_block##offset;		\
+} ;;									\
+{	.mmi ;								\
+	add	AccumA = AccumA, A_ ;					\
+	add	AccumB = AccumB, B_ ;					\
+	cmp.ne	pAgain, p0 = 0, BlockCount ;				\
+}									\
+{	.mib ;								\
+	add	AccumC = AccumC, C_ ;					\
+	add	AccumD = AccumD, D_ ;					\
+(pAgain) br.cond.dptk.many .md5_block_loop##offset ;			\
+} ;;									\
+{	.mib ;								\
+	nop	0x0 ;							\
+	nop	0x0 ;							\
+	br.cond.sptk.many .md5_exit ;					\
+} ;;
+
+	.align	32
+.md5_unaligned:
+//
+//	Because variable shifts are expensive, we special case each of
+//	the four alignements. In practice, this won't hurt too much
+//	since only one working set of code will be loaded.
+//
+{	.mib
+	ld4	DTmp = [DPtr_], 4
+	cmp.eq	pOff, p0 = 1, InAlign
+(pOff)	br.cond.dpnt.many .md5_process1
+} ;;
+{	.mib
+	cmp.eq	pOff, p0 = 2, InAlign
+	nop	0x0
+(pOff)	br.cond.dpnt.many .md5_process2
+} ;;
+	MD5UNALIGNED(3)
+	MD5UNALIGNED(1)
+	MD5UNALIGNED(2)
+
+	.endp md5_block_asm_data_order
+
+
+// MD5 Perform the F function and load
+//
+// Passed the first 4 words (M0 - M3) and initial (A, B, C, D) values,
+// computes the FF() round of functions, then branches to the common
+// digest code to finish up with GG(), HH, and II().
+//
+// INPUT
+//
+// rp Return Address -
+//
+// CODE
+//
+// v0 PFS bit bucket PFS
+// v1 Loop Trip Count LTrip
+// pt0 Load next word pMore
+
+/* For F round: */
+#define LTrip	r9
+#define PFS	r8
+#define pMore	p6
+
+/* For GHI rounds: */
+#define T	r9
+#define U	r10
+#define V	r11
+
+#define COMPUTE(a, b, s, M, R)			\
+{						\
+	.mii ;					\
+	ld4 TRound = [TPtr], 4 ;		\
+	dep.z Y = Z, 32, 32 ;;			\
+	shrp Z = Z, Y, 64 - s ;			\
+} ;;						\
+{						\
+	.mmi ;					\
+	add a = Z, b ;				\
+	mov R = M ;				\
+	nop 0x0 ;				\
+} ;;
+
+#define LOOP(a, b, s, M, R, label)		\
+{	.mii ;					\
+	ld4 TRound = [TPtr], 4 ;		\
+	dep.z Y = Z, 32, 32 ;;			\
+	shrp Z = Z, Y, 64 - s ;			\
+} ;;						\
+{	.mib ;					\
+	add a = Z, b ;				\
+	mov R = M ;				\
+	br.ctop.sptk.many label ;		\
+} ;;
+
+// G(B, C, D) = (B & D) | (C & ~D)
+
+#define G(a, b, c, d, M)			\
+{	.mmi ;					\
+	add Z = M, TRound ;			\
+	and Y = b, d ;				\
+	andcm X = c, d ;			\
+} ;;						\
+{	.mii ;					\
+	add Z = Z, a ;				\
+	or Y = Y, X ;;				\
+	add Z = Z, Y ;				\
+} ;;
+
+// H(B, C, D) = B ^ C ^ D
+
+#define H(a, b, c, d, M)			\
+{	.mmi ;					\
+	add Z = M, TRound ;			\
+	xor Y = b, c ;				\
+	nop 0x0 ;				\
+} ;;						\
+{	.mii ;					\
+	add Z = Z, a ;				\
+	xor Y = Y, d ;;				\
+	add Z = Z, Y ;				\
+} ;;
+
+// I(B, C, D) = C ^ (B | ~D)
+//
+// However, since we have an andcm operator, we use the fact that
+//
+// Y ^ Z == ~Y ^ ~Z
+//
+// to rewrite the expression as
+//
+// I(B, C, D) = ~C ^ (~B & D)
+
+#define I(a, b, c, d, M)			\
+{	.mmi ;					\
+	add Z = M, TRound ;			\
+	andcm Y = d, b ;			\
+	andcm X = -1, c ;			\
+} ;;						\
+{	.mii ;					\
+	add Z = Z, a ;				\
+	xor Y = Y, X ;;				\
+	add Z = Z, Y ;				\
+} ;;
+
+#define GG4(label)				\
+	G(A, B, C, D, M0)			\
+	COMPUTE(A, B, 5, M0, RotateM0)		\
+	G(D, A, B, C, M1)			\
+	COMPUTE(D, A, 9, M1, RotateM1)		\
+	G(C, D, A, B, M2)			\
+	COMPUTE(C, D, 14, M2, RotateM2)		\
+	G(B, C, D, A, M3)			\
+	LOOP(B, C, 20, M3, RotateM3, label)
+
+#define HH4(label)				\
+	H(A, B, C, D, M0)			\
+	COMPUTE(A, B, 4, M0, RotateM0)		\
+	H(D, A, B, C, M1)			\
+	COMPUTE(D, A, 11, M1, RotateM1)		\
+	H(C, D, A, B, M2)			\
+	COMPUTE(C, D, 16, M2, RotateM2)		\
+	H(B, C, D, A, M3)			\
+	LOOP(B, C, 23, M3, RotateM3, label)
+
+#define II4(label)				\
+	I(A, B, C, D, M0)			\
+	COMPUTE(A, B, 6, M0, RotateM0)		\
+	I(D, A, B, C, M1)			\
+	COMPUTE(D, A, 10, M1, RotateM1)		\
+	I(C, D, A, B, M2)			\
+	COMPUTE(C, D, 15, M2, RotateM2)		\
+	I(B, C, D, A, M3)			\
+	LOOP(B, C, 21, M3, RotateM3, label)
+
+#define FFLOAD(a, b, c, d, M, N, s)		\
+{	.mii ;					\
+(pMore) ld4 N = [DPtr], 4 ;			\
+	add Z = M, TRound ;			\
+	and Y = c, b ;				\
+}						\
+{	.mmi ;					\
+	andcm X = d, b ;;			\
+	add Z = Z, a ;				\
+	or Y = Y, X ;				\
+} ;;						\
+{	.mii ;					\
+	ld4 TRound = [TPtr], 4 ;		\
+	add Z = Z, Y ;;				\
+	dep.z Y = Z, 32, 32 ;			\
+} ;;						\
+{	.mii ;					\
+	nop 0x0 ;				\
+	shrp Z = Z, Y, 64 - s ;;		\
+	add a = Z, b ;				\
+} ;;
+
+#define FFLOOP(a, b, c, d, M, N, s, dest)	\
+{	.mii ;					\
+(pMore)	ld4 N = [DPtr], 4 ;			\
+	add Z = M, TRound ;			\
+	and Y = c, b ;				\
+}						\
+{	.mmi ;					\
+	andcm X = d, b ;;			\
+	add Z = Z, a ;				\
+	or Y = Y, X ;				\
+} ;;						\
+{	.mii ;					\
+	ld4 TRound = [TPtr], 4 ;		\
+	add Z = Z, Y ;;				\
+	dep.z Y = Z, 32, 32 ;			\
+} ;;						\
+{	.mii ;					\
+	nop 0x0 ;				\
+	shrp Z = Z, Y, 64 - s ;;		\
+	add a = Z, b ;				\
+}						\
+{	.mib ;					\
+	cmp.ne pMore, p0 = 0, LTrip ;		\
+	add LTrip = -1, LTrip ;			\
+	br.ctop.dptk.many dest ;		\
+} ;;
+
+	.type md5_digest_block0, @function
+	.align 32
+
+	.proc md5_digest_block0
+	.prologue
+md5_digest_block0:
+	.altrp QUICK_RTN
+	.body
+{	.mmi
+	alloc PFS = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE
+	mov LTrip = 2
+	mov ar.lc = 3
+} ;;
+{	.mii
+	cmp.eq pMore, p0 = r0, r0
+	mov ar.ec = 0
+	nop 0x0
+} ;;
+
+.md5_FF_round0:
+	FFLOAD(A, B, C, D, M12, RotateM0, 7)
+	FFLOAD(D, A, B, C, M13, RotateM1, 12)
+	FFLOAD(C, D, A, B, M14, RotateM2, 17)
+	FFLOOP(B, C, D, A, M15, RotateM3, 22, .md5_FF_round0)
+	//
+	// !!! Fall through to md5_digest_GHI
+	//
+	.endp md5_digest_block0
+
+	.type md5_digest_GHI, @function
+	.align 32
+
+	.proc md5_digest_GHI
+	.prologue
+	.regstk _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE
+md5_digest_GHI:
+	.altrp QUICK_RTN
+	.body
+//
+// The following sequence shuffles the block counstants round for the
+// next round:
+//
+// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+// 1 6 11 0 5 10 14 4 9 14 3 8 13 2 7 12
+//
+{	.mmi
+	mov Z = M0
+	mov Y = M15
+	mov ar.lc = 3
+}
+{	.mmi
+	mov X = M2
+	mov W = M9
+	mov V = M4
+} ;;
+
+{	.mmi
+	mov M0 = M1
+	mov M15 = M12
+	mov ar.ec = 1
+}
+{	.mmi
+	mov M2 = M11
+	mov M9 = M14
+	mov M4 = M5
+} ;;
+
+{	.mmi
+	mov M1 = M6
+	mov M12 = M13
+	mov U = M3
+}
+{	.mmi
+	mov M11 = M8
+	mov M14 = M7
+	mov M5 = M10
+} ;;
+
+{	.mmi
+	mov M6 = Y
+	mov M13 = X
+	mov M3 = Z
+}
+{	.mmi
+	mov M8 = W
+	mov M7 = V
+	mov M10 = U
+} ;;
+
+.md5_GG_round:
+	GG4(.md5_GG_round)
+
+// The following sequence shuffles the block constants round for the
+// next round:
+//
+// 1 6 11 0 5 10 14 4 9 14 3 8 13 2 7 12
+// 5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2
+
+{	.mmi
+	mov Z = M0
+	mov Y = M1
+	mov ar.lc = 3
+}
+{	.mmi
+	mov X = M3
+	mov W = M5
+	mov V = M6
+} ;;
+
+{	.mmi
+	mov M0 = M4
+	mov M1 = M11
+	mov ar.ec = 1
+}
+{	.mmi
+	mov M3 = M9
+	mov U = M8
+	mov T = M13
+} ;;
+
+{	.mmi
+	mov M4 = Z
+	mov M11 = Y
+	mov M5 = M7
+}
+{	.mmi
+	mov M6 = M14
+	mov M8 = M12
+	mov M13 = M15
+} ;;
+
+{	.mmi
+	mov M7 = W
+	mov M14 = V
+	nop 0x0
+}
+{	.mmi
+	mov M9 = X
+	mov M12 = U
+	mov M15 = T
+} ;;
+
+.md5_HH_round:
+	HH4(.md5_HH_round)
+
+// The following sequence shuffles the block constants round for the
+// next round:
+//
+// 5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2
+// 0 7 14 5 12 3 10 1 8 15 6 13 4 11 2 9
+
+{	.mmi
+	mov Z = M0
+	mov Y = M15
+	mov ar.lc = 3
+}
+{	.mmi
+	mov X = M10
+	mov W = M1
+	mov V = M4
+} ;;
+
+{	.mmi
+	mov M0 = M9
+	mov M15 = M12
+	mov ar.ec = 1
+}
+{	.mmi
+	mov M10 = M11
+	mov M1 = M6
+	mov M4 = M13
+} ;;
+
+{	.mmi
+	mov M9 = M14
+	mov M12 = M5
+	mov U = M3
+}
+{	.mmi
+	mov M11 = M8
+	mov M6 = M7
+	mov M13 = M2
+} ;;
+
+{	.mmi
+	mov M14 = Y
+	mov M5 = X
+	mov M3 = Z
+}
+{	.mmi
+	mov M8 = W
+	mov M7 = V
+	mov M2 = U
+} ;;
+
+.md5_II_round:
+	II4(.md5_II_round)
+
+{	.mib
+	nop 0x0
+	nop 0x0
+	br.ret.sptk.many QUICK_RTN
+} ;;
+
+	.endp md5_digest_GHI
+
+#define FFLOADU(a, b, c, d, M, P, N, s, offset)	\
+{	.mii ;					\
+(pMore) ld4 N = [DPtr], 4 ;			\
+	add Z = M, TRound ;			\
+	and Y = c, b ;				\
+}						\
+{	.mmi ;					\
+	andcm X = d, b ;;			\
+	add Z = Z, a ;				\
+	or Y = Y, X ;				\
+} ;;						\
+{	.mii ;					\
+	ld4 TRound = [TPtr], 4 ;		\
+	GETLW(W, P, offset) ;			\
+	add Z = Z, Y ;				\
+} ;;						\
+{	.mii ;					\
+	or W = W, DTmp ;			\
+	dep.z Y = Z, 32, 32 ;;			\
+	shrp Z = Z, Y, 64 - s ;			\
+} ;;						\
+{	.mii ;					\
+	add a = Z, b ;				\
+	GETRW(DTmp, P, offset) ;		\
+	mov P = W ;				\
+} ;;
+
+#define FFLOOPU(a, b, c, d, M, P, N, s, offset)		\
+{	.mii ;						\
+(pMore) ld4 N = [DPtr], 4 ;				\
+	add Z = M, TRound ;				\
+	and Y = c, b ;					\
+}							\
+{	.mmi ;						\
+	andcm X = d, b ;;				\
+	add Z = Z, a ;					\
+	or Y = Y, X ;					\
+} ;;							\
+{	.mii ;						\
+	ld4 TRound = [TPtr], 4 ;			\
+(pMore) GETLW(W, P, offset) 	;			\
+	add Z = Z, Y ;					\
+} ;;							\
+{	.mii ;						\
+(pMore) or W = W, DTmp ;				\
+	dep.z Y = Z, 32, 32 ;;				\
+	shrp Z = Z, Y, 64 - s ;				\
+} ;;							\
+{	.mii ;						\
+	add a = Z, b ;					\
+(pMore) GETRW(DTmp, P, offset) 	;			\
+(pMore) mov P = W ;					\
+}							\
+{	.mib ;						\
+	cmp.ne pMore, p0 = 0, LTrip ;			\
+	add LTrip = -1, LTrip ;				\
+	br.ctop.sptk.many .md5_FF_round##offset ;	\
+} ;;
+
+#define MD5FBLOCK(offset)						\
+	.type md5_digest_block##offset, @function ;			\
+									\
+	.align 32 ;							\
+	.proc md5_digest_block##offset ;				\
+	.prologue ;							\
+	.altrp QUICK_RTN ;						\
+	.body ;								\
+md5_digest_block##offset:						\
+{	.mmi ;								\
+	alloc PFS = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE ;	\
+	mov LTrip = 2 ;							\
+	mov ar.lc = 3 ;							\
+} ;;									\
+{	.mii ;								\
+	cmp.eq pMore, p0 = r0, r0 ;					\
+	mov ar.ec = 0 ;							\
+	nop 0x0 ;							\
+} ;;									\
+									\
+	.pred.rel "mutex", pLoad, pSkip ;				\
+.md5_FF_round##offset:							\
+	FFLOADU(A, B, C, D, M12, M13, RotateM0, 7, offset)		\
+	FFLOADU(D, A, B, C, M13, M14, RotateM1, 12, offset)		\
+	FFLOADU(C, D, A, B, M14, M15, RotateM2, 17, offset)		\
+	FFLOOPU(B, C, D, A, M15, RotateM0, RotateM3, 22, offset)	\
+									\
+{	.mib ;								\
+	nop 0x0 ;							\
+	nop 0x0 ;							\
+	br.cond.sptk.many md5_digest_GHI ;				\
+} ;;									\
+	.endp md5_digest_block##offset
+
+MD5FBLOCK(1)
+MD5FBLOCK(2)
+MD5FBLOCK(3)
+
+	.align 64
+	.type md5_constants, @object
+md5_constants:
+.md5_tbl_data_order:			// To ensure little-endian data
+					// order, code as bytes.
+	data1 0x78, 0xa4, 0x6a, 0xd7	//     0
+	data1 0x56, 0xb7, 0xc7, 0xe8	//     1
+	data1 0xdb, 0x70, 0x20, 0x24	//     2
+	data1 0xee, 0xce, 0xbd, 0xc1	//     3
+	data1 0xaf, 0x0f, 0x7c, 0xf5	//     4
+	data1 0x2a, 0xc6, 0x87, 0x47	//     5
+	data1 0x13, 0x46, 0x30, 0xa8	//     6
+	data1 0x01, 0x95, 0x46, 0xfd	//     7
+	data1 0xd8, 0x98, 0x80, 0x69	//     8
+	data1 0xaf, 0xf7, 0x44, 0x8b	//     9
+	data1 0xb1, 0x5b, 0xff, 0xff	//    10
+	data1 0xbe, 0xd7, 0x5c, 0x89	//    11
+	data1 0x22, 0x11, 0x90, 0x6b	//    12
+	data1 0x93, 0x71, 0x98, 0xfd	//    13
+	data1 0x8e, 0x43, 0x79, 0xa6	//    14
+	data1 0x21, 0x08, 0xb4, 0x49	//    15
+	data1 0x62, 0x25, 0x1e, 0xf6	//    16
+	data1 0x40, 0xb3, 0x40, 0xc0	//    17
+	data1 0x51, 0x5a, 0x5e, 0x26	//    18
+	data1 0xaa, 0xc7, 0xb6, 0xe9	//    19
+	data1 0x5d, 0x10, 0x2f, 0xd6	//    20
+	data1 0x53, 0x14, 0x44, 0x02	//    21
+	data1 0x81, 0xe6, 0xa1, 0xd8	//    22
+	data1 0xc8, 0xfb, 0xd3, 0xe7	//    23
+	data1 0xe6, 0xcd, 0xe1, 0x21	//    24
+	data1 0xd6, 0x07, 0x37, 0xc3	//    25
+	data1 0x87, 0x0d, 0xd5, 0xf4	//    26
+	data1 0xed, 0x14, 0x5a, 0x45	//    27
+	data1 0x05, 0xe9, 0xe3, 0xa9	//    28
+	data1 0xf8, 0xa3, 0xef, 0xfc	//    29
+	data1 0xd9, 0x02, 0x6f, 0x67	//    30
+	data1 0x8a, 0x4c, 0x2a, 0x8d	//    31
+	data1 0x42, 0x39, 0xfa, 0xff	//    32
+	data1 0x81, 0xf6, 0x71, 0x87	//    33
+	data1 0x22, 0x61, 0x9d, 0x6d	//    34
+	data1 0x0c, 0x38, 0xe5, 0xfd	//    35
+	data1 0x44, 0xea, 0xbe, 0xa4	//    36
+	data1 0xa9, 0xcf, 0xde, 0x4b	//    37
+	data1 0x60, 0x4b, 0xbb, 0xf6	//    38
+	data1 0x70, 0xbc, 0xbf, 0xbe	//    39
+	data1 0xc6, 0x7e, 0x9b, 0x28	//    40
+	data1 0xfa, 0x27, 0xa1, 0xea	//    41
+	data1 0x85, 0x30, 0xef, 0xd4	//    42
+	data1 0x05, 0x1d, 0x88, 0x04	//    43
+	data1 0x39, 0xd0, 0xd4, 0xd9	//    44
+	data1 0xe5, 0x99, 0xdb, 0xe6	//    45
+	data1 0xf8, 0x7c, 0xa2, 0x1f	//    46
+	data1 0x65, 0x56, 0xac, 0xc4	//    47
+	data1 0x44, 0x22, 0x29, 0xf4	//    48
+	data1 0x97, 0xff, 0x2a, 0x43	//    49
+	data1 0xa7, 0x23, 0x94, 0xab	//    50
+	data1 0x39, 0xa0, 0x93, 0xfc	//    51
+	data1 0xc3, 0x59, 0x5b, 0x65	//    52
+	data1 0x92, 0xcc, 0x0c, 0x8f	//    53
+	data1 0x7d, 0xf4, 0xef, 0xff	//    54
+	data1 0xd1, 0x5d, 0x84, 0x85	//    55
+	data1 0x4f, 0x7e, 0xa8, 0x6f	//    56
+	data1 0xe0, 0xe6, 0x2c, 0xfe	//    57
+	data1 0x14, 0x43, 0x01, 0xa3	//    58
+	data1 0xa1, 0x11, 0x08, 0x4e	//    59
+	data1 0x82, 0x7e, 0x53, 0xf7	//    60
+	data1 0x35, 0xf2, 0x3a, 0xbd	//    61
+	data1 0xbb, 0xd2, 0xd7, 0x2a	//    62
+	data1 0x91, 0xd3, 0x86, 0xeb	//    63
+.size	md5_constants#,64*4
diff --git a/openssl/crypto/md5/asm/md5-x86_64.pl b/openssl/crypto/md5/asm/md5-x86_64.pl
new file mode 100755
index 0000000..8678854
--- /dev/null
+++ b/openssl/crypto/md5/asm/md5-x86_64.pl
@@ -0,0 +1,369 @@
+#!/usr/bin/perl -w
+#
+# MD5 optimized for AMD64.
+#
+# Author: Marc Bevand <bevand_m (at) epita.fr>
+# Licence: I hereby disclaim the copyright on this code and place it
+# in the public domain.
+#
+
+use strict;
+
+my $code;
+
+# round1_step() does:
+#   dst = x + ((dst + F(x,y,z) + X[k] + T_i) <<< s)
+#   %r10d = X[k_next]
+#   %r11d = z' (copy of z for the next step)
+# Each round1_step() takes about 5.3 clocks (9 instructions, 1.7 IPC)
+sub round1_step
+{
+    my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
+    $code .= " mov	0*4(%rsi),	%r10d		/* (NEXT STEP) X[0] */\n" if ($pos == -1);
+    $code .= " mov	%edx,		%r11d		/* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
+    $code .= <<EOF;
+	xor	$y,		%r11d		/* y ^ ... */
+	lea	$T_i($dst,%r10d),$dst		/* Const + dst + ... */
+	and	$x,		%r11d		/* x & ... */
+	xor	$z,		%r11d		/* z ^ ... */
+	mov	$k_next*4(%rsi),%r10d		/* (NEXT STEP) X[$k_next] */
+	add	%r11d,		$dst		/* dst += ... */
+	rol	\$$s,		$dst		/* dst <<< s */
+	mov	$y,		%r11d		/* (NEXT STEP) z' = $y */
+	add	$x,		$dst		/* dst += x */
+EOF
+}
+
+# round2_step() does:
+#   dst = x + ((dst + G(x,y,z) + X[k] + T_i) <<< s)
+#   %r10d = X[k_next]
+#   %r11d = z' (copy of z for the next step)
+#   %r12d = z' (copy of z for the next step)
+# Each round2_step() takes about 5.4 clocks (11 instructions, 2.0 IPC)
+sub round2_step
+{
+    my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
+    $code .= " mov	1*4(%rsi),	%r10d		/* (NEXT STEP) X[1] */\n" if ($pos == -1);
+    $code .= " mov	%edx,		%r11d		/* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
+    $code .= " mov	%edx,		%r12d		/* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
+    $code .= <<EOF;
+	not	%r11d				/* not z */
+	lea	$T_i($dst,%r10d),$dst		/* Const + dst + ... */
+	and	$x,		%r12d		/* x & z */
+	and	$y,		%r11d		/* y & (not z) */
+	mov	$k_next*4(%rsi),%r10d		/* (NEXT STEP) X[$k_next] */
+	or	%r11d,		%r12d		/* (y & (not z)) | (x & z) */
+	mov	$y,		%r11d		/* (NEXT STEP) z' = $y */
+	add	%r12d,		$dst		/* dst += ... */
+	mov	$y,		%r12d		/* (NEXT STEP) z' = $y */
+	rol	\$$s,		$dst		/* dst <<< s */
+	add	$x,		$dst		/* dst += x */
+EOF
+}
+
+# round3_step() does:
+#   dst = x + ((dst + H(x,y,z) + X[k] + T_i) <<< s)
+#   %r10d = X[k_next]
+#   %r11d = y' (copy of y for the next step)
+# Each round3_step() takes about 4.2 clocks (8 instructions, 1.9 IPC)
+sub round3_step
+{
+    my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
+    $code .= " mov	5*4(%rsi),	%r10d		/* (NEXT STEP) X[5] */\n" if ($pos == -1);
+    $code .= " mov	%ecx,		%r11d		/* (NEXT STEP) y' = %ecx */\n" if ($pos == -1);
+    $code .= <<EOF;
+	lea	$T_i($dst,%r10d),$dst		/* Const + dst + ... */
+	mov	$k_next*4(%rsi),%r10d		/* (NEXT STEP) X[$k_next] */
+	xor	$z,		%r11d		/* z ^ ... */
+	xor	$x,		%r11d		/* x ^ ... */
+	add	%r11d,		$dst		/* dst += ... */
+	rol	\$$s,		$dst		/* dst <<< s */
+	mov	$x,		%r11d		/* (NEXT STEP) y' = $x */
+	add	$x,		$dst		/* dst += x */
+EOF
+}
+
+# round4_step() does:
+#   dst = x + ((dst + I(x,y,z) + X[k] + T_i) <<< s)
+#   %r10d = X[k_next]
+#   %r11d = not z' (copy of not z for the next step)
+# Each round4_step() takes about 5.2 clocks (9 instructions, 1.7 IPC)
+sub round4_step
+{
+    my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
+    $code .= " mov	0*4(%rsi),	%r10d		/* (NEXT STEP) X[0] */\n" if ($pos == -1);
+    $code .= " mov	\$0xffffffff,	%r11d\n" if ($pos == -1);
+    $code .= " xor	%edx,		%r11d		/* (NEXT STEP) not z' = not %edx*/\n"
+    if ($pos == -1);
+    $code .= <<EOF;
+	lea	$T_i($dst,%r10d),$dst		/* Const + dst + ... */
+	or	$x,		%r11d		/* x | ... */
+	xor	$y,		%r11d		/* y ^ ... */
+	add	%r11d,		$dst		/* dst += ... */
+	mov	$k_next*4(%rsi),%r10d		/* (NEXT STEP) X[$k_next] */
+	mov	\$0xffffffff,	%r11d
+	rol	\$$s,		$dst		/* dst <<< s */
+	xor	$y,		%r11d		/* (NEXT STEP) not z' = not $y */
+	add	$x,		$dst		/* dst += x */
+EOF
+}
+
+my $flavour = shift;
+my $output  = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+no warnings qw(uninitialized);
+open STDOUT,"| $^X $xlate $flavour $output";
+
+$code .= <<EOF;
+.text
+.align 16
+
+.globl md5_block_asm_data_order
+.type md5_block_asm_data_order,\@function,3
+md5_block_asm_data_order:
+	push	%rbp
+	push	%rbx
+	push	%r12
+	push	%r14
+	push	%r15
+.Lprologue:
+
+	# rdi = arg #1 (ctx, MD5_CTX pointer)
+	# rsi = arg #2 (ptr, data pointer)
+	# rdx = arg #3 (nbr, number of 16-word blocks to process)
+	mov	%rdi,		%rbp	# rbp = ctx
+	shl	\$6,		%rdx	# rdx = nbr in bytes
+	lea	(%rsi,%rdx),	%rdi	# rdi = end
+	mov	0*4(%rbp),	%eax	# eax = ctx->A
+	mov	1*4(%rbp),	%ebx	# ebx = ctx->B
+	mov	2*4(%rbp),	%ecx	# ecx = ctx->C
+	mov	3*4(%rbp),	%edx	# edx = ctx->D
+	# end is 'rdi'
+	# ptr is 'rsi'
+	# A is 'eax'
+	# B is 'ebx'
+	# C is 'ecx'
+	# D is 'edx'
+
+	cmp	%rdi,		%rsi		# cmp end with ptr
+	je	.Lend				# jmp if ptr == end
+
+	# BEGIN of loop over 16-word blocks
+.Lloop:	# save old values of A, B, C, D
+	mov	%eax,		%r8d
+	mov	%ebx,		%r9d
+	mov	%ecx,		%r14d
+	mov	%edx,		%r15d
+EOF
+round1_step(-1,'%eax','%ebx','%ecx','%edx', '1','0xd76aa478', '7');
+round1_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xe8c7b756','12');
+round1_step( 0,'%ecx','%edx','%eax','%ebx', '3','0x242070db','17');
+round1_step( 0,'%ebx','%ecx','%edx','%eax', '4','0xc1bdceee','22');
+round1_step( 0,'%eax','%ebx','%ecx','%edx', '5','0xf57c0faf', '7');
+round1_step( 0,'%edx','%eax','%ebx','%ecx', '6','0x4787c62a','12');
+round1_step( 0,'%ecx','%edx','%eax','%ebx', '7','0xa8304613','17');
+round1_step( 0,'%ebx','%ecx','%edx','%eax', '8','0xfd469501','22');
+round1_step( 0,'%eax','%ebx','%ecx','%edx', '9','0x698098d8', '7');
+round1_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8b44f7af','12');
+round1_step( 0,'%ecx','%edx','%eax','%ebx','11','0xffff5bb1','17');
+round1_step( 0,'%ebx','%ecx','%edx','%eax','12','0x895cd7be','22');
+round1_step( 0,'%eax','%ebx','%ecx','%edx','13','0x6b901122', '7');
+round1_step( 0,'%edx','%eax','%ebx','%ecx','14','0xfd987193','12');
+round1_step( 0,'%ecx','%edx','%eax','%ebx','15','0xa679438e','17');
+round1_step( 1,'%ebx','%ecx','%edx','%eax', '0','0x49b40821','22');
+
+round2_step(-1,'%eax','%ebx','%ecx','%edx', '6','0xf61e2562', '5');
+round2_step( 0,'%edx','%eax','%ebx','%ecx','11','0xc040b340', '9');
+round2_step( 0,'%ecx','%edx','%eax','%ebx', '0','0x265e5a51','14');
+round2_step( 0,'%ebx','%ecx','%edx','%eax', '5','0xe9b6c7aa','20');
+round2_step( 0,'%eax','%ebx','%ecx','%edx','10','0xd62f105d', '5');
+round2_step( 0,'%edx','%eax','%ebx','%ecx','15', '0x2441453', '9');
+round2_step( 0,'%ecx','%edx','%eax','%ebx', '4','0xd8a1e681','14');
+round2_step( 0,'%ebx','%ecx','%edx','%eax', '9','0xe7d3fbc8','20');
+round2_step( 0,'%eax','%ebx','%ecx','%edx','14','0x21e1cde6', '5');
+round2_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xc33707d6', '9');
+round2_step( 0,'%ecx','%edx','%eax','%ebx', '8','0xf4d50d87','14');
+round2_step( 0,'%ebx','%ecx','%edx','%eax','13','0x455a14ed','20');
+round2_step( 0,'%eax','%ebx','%ecx','%edx', '2','0xa9e3e905', '5');
+round2_step( 0,'%edx','%eax','%ebx','%ecx', '7','0xfcefa3f8', '9');
+round2_step( 0,'%ecx','%edx','%eax','%ebx','12','0x676f02d9','14');
+round2_step( 1,'%ebx','%ecx','%edx','%eax', '0','0x8d2a4c8a','20');
+
+round3_step(-1,'%eax','%ebx','%ecx','%edx', '8','0xfffa3942', '4');
+round3_step( 0,'%edx','%eax','%ebx','%ecx','11','0x8771f681','11');
+round3_step( 0,'%ecx','%edx','%eax','%ebx','14','0x6d9d6122','16');
+round3_step( 0,'%ebx','%ecx','%edx','%eax', '1','0xfde5380c','23');
+round3_step( 0,'%eax','%ebx','%ecx','%edx', '4','0xa4beea44', '4');
+round3_step( 0,'%edx','%eax','%ebx','%ecx', '7','0x4bdecfa9','11');
+round3_step( 0,'%ecx','%edx','%eax','%ebx','10','0xf6bb4b60','16');
+round3_step( 0,'%ebx','%ecx','%edx','%eax','13','0xbebfbc70','23');
+round3_step( 0,'%eax','%ebx','%ecx','%edx', '0','0x289b7ec6', '4');
+round3_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xeaa127fa','11');
+round3_step( 0,'%ecx','%edx','%eax','%ebx', '6','0xd4ef3085','16');
+round3_step( 0,'%ebx','%ecx','%edx','%eax', '9', '0x4881d05','23');
+round3_step( 0,'%eax','%ebx','%ecx','%edx','12','0xd9d4d039', '4');
+round3_step( 0,'%edx','%eax','%ebx','%ecx','15','0xe6db99e5','11');
+round3_step( 0,'%ecx','%edx','%eax','%ebx', '2','0x1fa27cf8','16');
+round3_step( 1,'%ebx','%ecx','%edx','%eax', '0','0xc4ac5665','23');
+
+round4_step(-1,'%eax','%ebx','%ecx','%edx', '7','0xf4292244', '6');
+round4_step( 0,'%edx','%eax','%ebx','%ecx','14','0x432aff97','10');
+round4_step( 0,'%ecx','%edx','%eax','%ebx', '5','0xab9423a7','15');
+round4_step( 0,'%ebx','%ecx','%edx','%eax','12','0xfc93a039','21');
+round4_step( 0,'%eax','%ebx','%ecx','%edx', '3','0x655b59c3', '6');
+round4_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8f0ccc92','10');
+round4_step( 0,'%ecx','%edx','%eax','%ebx', '1','0xffeff47d','15');
+round4_step( 0,'%ebx','%ecx','%edx','%eax', '8','0x85845dd1','21');
+round4_step( 0,'%eax','%ebx','%ecx','%edx','15','0x6fa87e4f', '6');
+round4_step( 0,'%edx','%eax','%ebx','%ecx', '6','0xfe2ce6e0','10');
+round4_step( 0,'%ecx','%edx','%eax','%ebx','13','0xa3014314','15');
+round4_step( 0,'%ebx','%ecx','%edx','%eax', '4','0x4e0811a1','21');
+round4_step( 0,'%eax','%ebx','%ecx','%edx','11','0xf7537e82', '6');
+round4_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xbd3af235','10');
+round4_step( 0,'%ecx','%edx','%eax','%ebx', '9','0x2ad7d2bb','15');
+round4_step( 1,'%ebx','%ecx','%edx','%eax', '0','0xeb86d391','21');
+$code .= <<EOF;
+	# add old values of A, B, C, D
+	add	%r8d,	%eax
+	add	%r9d,	%ebx
+	add	%r14d,	%ecx
+	add	%r15d,	%edx
+
+	# loop control
+	add	\$64,		%rsi		# ptr += 64
+	cmp	%rdi,		%rsi		# cmp end with ptr
+	jb	.Lloop				# jmp if ptr < end
+	# END of loop over 16-word blocks
+
+.Lend:
+	mov	%eax,		0*4(%rbp)	# ctx->A = A
+	mov	%ebx,		1*4(%rbp)	# ctx->B = B
+	mov	%ecx,		2*4(%rbp)	# ctx->C = C
+	mov	%edx,		3*4(%rbp)	# ctx->D = D
+
+	mov	(%rsp),%r15
+	mov	8(%rsp),%r14
+	mov	16(%rsp),%r12
+	mov	24(%rsp),%rbx
+	mov	32(%rsp),%rbp
+	add	\$40,%rsp
+.Lepilogue:
+	ret
+.size md5_block_asm_data_order,.-md5_block_asm_data_order
+EOF
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+my $rec="%rcx";
+my $frame="%rdx";
+my $context="%r8";
+my $disp="%r9";
+
+$code.=<<___;
+.extern	__imp_RtlVirtualUnwind
+.type	se_handler,\@abi-omnipotent
+.align	16
+se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	lea	.Lprologue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lprologue
+	jb	.Lin_prologue
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	lea	.Lepilogue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
+	jae	.Lin_prologue
+
+	lea	40(%rax),%rax
+
+	mov	-8(%rax),%rbp
+	mov	-16(%rax),%rbx
+	mov	-24(%rax),%r12
+	mov	-32(%rax),%r14
+	mov	-40(%rax),%r15
+	mov	%rbx,144($context)	# restore context->Rbx
+	mov	%rbp,160($context)	# restore context->Rbp
+	mov	%r12,216($context)	# restore context->R12
+	mov	%r14,232($context)	# restore context->R14
+	mov	%r15,240($context)	# restore context->R15
+
+.Lin_prologue:
+	mov	8(%rax),%rdi
+	mov	16(%rax),%rsi
+	mov	%rax,152($context)	# restore context->Rsp
+	mov	%rsi,168($context)	# restore context->Rsi
+	mov	%rdi,176($context)	# restore context->Rdi
+
+	mov	40($disp),%rdi		# disp->ContextRecord
+	mov	$context,%rsi		# context
+	mov	\$154,%ecx		# sizeof(CONTEXT)
+	.long	0xa548f3fc		# cld; rep movsq
+
+	mov	$disp,%rsi
+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
+	mov	40(%rsi),%r10		# disp->ContextRecord
+	lea	56(%rsi),%r11		# &disp->HandlerData
+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
+	mov	%r10,32(%rsp)		# arg5
+	mov	%r11,40(%rsp)		# arg6
+	mov	%r12,48(%rsp)		# arg7
+	mov	%rcx,56(%rsp)		# arg8, (NULL)
+	call	*__imp_RtlVirtualUnwind(%rip)
+
+	mov	\$1,%eax		# ExceptionContinueSearch
+	add	\$64,%rsp
+	popfq
+	pop	%r15
+	pop	%r14
+	pop	%r13
+	pop	%r12
+	pop	%rbp
+	pop	%rbx
+	pop	%rdi
+	pop	%rsi
+	ret
+.size	se_handler,.-se_handler
+
+.section	.pdata
+.align	4
+	.rva	.LSEH_begin_md5_block_asm_data_order
+	.rva	.LSEH_end_md5_block_asm_data_order
+	.rva	.LSEH_info_md5_block_asm_data_order
+
+.section	.xdata
+.align	8
+.LSEH_info_md5_block_asm_data_order:
+	.byte	9,0,0,0
+	.rva	se_handler
+___
+}
+
+print $code;
+
+close STDOUT;
diff --git a/openssl/crypto/md5/md5.c b/openssl/crypto/md5/md5.c
new file mode 100644
index 0000000..563733a
--- /dev/null
+++ b/openssl/crypto/md5/md5.c
@@ -0,0 +1,127 @@
+/* crypto/md5/md5.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/md5.h>
+
+#define BUFSIZE	1024*16
+
+void do_fp(FILE *f);
+void pt(unsigned char *md);
+#if !defined(_OSD_POSIX) && !defined(__DJGPP__)
+int read(int, void *, unsigned int);
+#endif
+
+int main(int argc, char **argv)
+	{
+	int i,err=0;
+	FILE *IN;
+
+	if (argc == 1)
+		{
+		do_fp(stdin);
+		}
+	else
+		{
+		for (i=1; i<argc; i++)
+			{
+			IN=fopen(argv[i],"r");
+			if (IN == NULL)
+				{
+				perror(argv[i]);
+				err++;
+				continue;
+				}
+			printf("MD5(%s)= ",argv[i]);
+			do_fp(IN);
+			fclose(IN);
+			}
+		}
+	exit(err);
+	}
+
+void do_fp(FILE *f)
+	{
+	MD5_CTX c;
+	unsigned char md[MD5_DIGEST_LENGTH];
+	int fd;
+	int i;
+	static unsigned char buf[BUFSIZE];
+
+	fd=fileno(f);
+	MD5_Init(&c);
+	for (;;)
+		{
+		i=read(fd,buf,BUFSIZE);
+		if (i <= 0) break;
+		MD5_Update(&c,buf,(unsigned long)i);
+		}
+	MD5_Final(&(md[0]),&c);
+	pt(md);
+	}
+
+void pt(unsigned char *md)
+	{
+	int i;
+
+	for (i=0; i<MD5_DIGEST_LENGTH; i++)
+		printf("%02x",md[i]);
+	printf("\n");
+	}
+
diff --git a/openssl/crypto/md5/md5.h b/openssl/crypto/md5/md5.h
new file mode 100644
index 0000000..4cbf843
--- /dev/null
+++ b/openssl/crypto/md5/md5.h
@@ -0,0 +1,117 @@
+/* crypto/md5/md5.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_MD5_H
+#define HEADER_MD5_H
+
+#include <openssl/e_os2.h>
+#include <stddef.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_MD5
+#error MD5 is disabled.
+#endif
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! MD5_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! MD5_LONG_LOG2 has to be defined along.			   !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#if defined(__LP32__)
+#define MD5_LONG unsigned long
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#define MD5_LONG unsigned long
+#define MD5_LONG_LOG2 3
+/*
+ * _CRAY note. I could declare short, but I have no idea what impact
+ * does it have on performance on none-T3E machines. I could declare
+ * int, but at least on C90 sizeof(int) can be chosen at compile time.
+ * So I've chosen long...
+ *					<appro@fy.chalmers.se>
+ */
+#else
+#define MD5_LONG unsigned int
+#endif
+
+#define MD5_CBLOCK	64
+#define MD5_LBLOCK	(MD5_CBLOCK/4)
+#define MD5_DIGEST_LENGTH 16
+
+typedef struct MD5state_st
+	{
+	MD5_LONG A,B,C,D;
+	MD5_LONG Nl,Nh;
+	MD5_LONG data[MD5_LBLOCK];
+	unsigned int num;
+	} MD5_CTX;
+
+int MD5_Init(MD5_CTX *c);
+int MD5_Update(MD5_CTX *c, const void *data, size_t len);
+int MD5_Final(unsigned char *md, MD5_CTX *c);
+unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
+void MD5_Transform(MD5_CTX *c, const unsigned char *b);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/md5/md5_dgst.c b/openssl/crypto/md5/md5_dgst.c
new file mode 100644
index 0000000..beace63
--- /dev/null
+++ b/openssl/crypto/md5/md5_dgst.c
@@ -0,0 +1,184 @@
+/* crypto/md5/md5_dgst.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "md5_locl.h"
+#include <openssl/opensslv.h>
+
+const char MD5_version[]="MD5" OPENSSL_VERSION_PTEXT;
+
+/* Implemented from RFC1321 The MD5 Message-Digest Algorithm
+ */
+
+#define INIT_DATA_A (unsigned long)0x67452301L
+#define INIT_DATA_B (unsigned long)0xefcdab89L
+#define INIT_DATA_C (unsigned long)0x98badcfeL
+#define INIT_DATA_D (unsigned long)0x10325476L
+
+int MD5_Init(MD5_CTX *c)
+	{
+	memset (c,0,sizeof(*c));
+	c->A=INIT_DATA_A;
+	c->B=INIT_DATA_B;
+	c->C=INIT_DATA_C;
+	c->D=INIT_DATA_D;
+	return 1;
+	}
+
+#ifndef md5_block_data_order
+#ifdef X
+#undef X
+#endif
+void md5_block_data_order (MD5_CTX *c, const void *data_, size_t num)
+	{
+	const unsigned char *data=data_;
+	register unsigned MD32_REG_T A,B,C,D,l;
+#ifndef MD32_XARRAY
+	/* See comment in crypto/sha/sha_locl.h for details. */
+	unsigned MD32_REG_T	XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+				XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
+# define X(i)	XX##i
+#else
+	MD5_LONG XX[MD5_LBLOCK];
+# define X(i)	XX[i]
+#endif
+
+	A=c->A;
+	B=c->B;
+	C=c->C;
+	D=c->D;
+
+	for (;num--;)
+		{
+	HOST_c2l(data,l); X( 0)=l;		HOST_c2l(data,l); X( 1)=l;
+	/* Round 0 */
+	R0(A,B,C,D,X( 0), 7,0xd76aa478L);	HOST_c2l(data,l); X( 2)=l;
+	R0(D,A,B,C,X( 1),12,0xe8c7b756L);	HOST_c2l(data,l); X( 3)=l;
+	R0(C,D,A,B,X( 2),17,0x242070dbL);	HOST_c2l(data,l); X( 4)=l;
+	R0(B,C,D,A,X( 3),22,0xc1bdceeeL);	HOST_c2l(data,l); X( 5)=l;
+	R0(A,B,C,D,X( 4), 7,0xf57c0fafL);	HOST_c2l(data,l); X( 6)=l;
+	R0(D,A,B,C,X( 5),12,0x4787c62aL);	HOST_c2l(data,l); X( 7)=l;
+	R0(C,D,A,B,X( 6),17,0xa8304613L);	HOST_c2l(data,l); X( 8)=l;
+	R0(B,C,D,A,X( 7),22,0xfd469501L);	HOST_c2l(data,l); X( 9)=l;
+	R0(A,B,C,D,X( 8), 7,0x698098d8L);	HOST_c2l(data,l); X(10)=l;
+	R0(D,A,B,C,X( 9),12,0x8b44f7afL);	HOST_c2l(data,l); X(11)=l;
+	R0(C,D,A,B,X(10),17,0xffff5bb1L);	HOST_c2l(data,l); X(12)=l;
+	R0(B,C,D,A,X(11),22,0x895cd7beL);	HOST_c2l(data,l); X(13)=l;
+	R0(A,B,C,D,X(12), 7,0x6b901122L);	HOST_c2l(data,l); X(14)=l;
+	R0(D,A,B,C,X(13),12,0xfd987193L);	HOST_c2l(data,l); X(15)=l;
+	R0(C,D,A,B,X(14),17,0xa679438eL);
+	R0(B,C,D,A,X(15),22,0x49b40821L);
+	/* Round 1 */
+	R1(A,B,C,D,X( 1), 5,0xf61e2562L);
+	R1(D,A,B,C,X( 6), 9,0xc040b340L);
+	R1(C,D,A,B,X(11),14,0x265e5a51L);
+	R1(B,C,D,A,X( 0),20,0xe9b6c7aaL);
+	R1(A,B,C,D,X( 5), 5,0xd62f105dL);
+	R1(D,A,B,C,X(10), 9,0x02441453L);
+	R1(C,D,A,B,X(15),14,0xd8a1e681L);
+	R1(B,C,D,A,X( 4),20,0xe7d3fbc8L);
+	R1(A,B,C,D,X( 9), 5,0x21e1cde6L);
+	R1(D,A,B,C,X(14), 9,0xc33707d6L);
+	R1(C,D,A,B,X( 3),14,0xf4d50d87L);
+	R1(B,C,D,A,X( 8),20,0x455a14edL);
+	R1(A,B,C,D,X(13), 5,0xa9e3e905L);
+	R1(D,A,B,C,X( 2), 9,0xfcefa3f8L);
+	R1(C,D,A,B,X( 7),14,0x676f02d9L);
+	R1(B,C,D,A,X(12),20,0x8d2a4c8aL);
+	/* Round 2 */
+	R2(A,B,C,D,X( 5), 4,0xfffa3942L);
+	R2(D,A,B,C,X( 8),11,0x8771f681L);
+	R2(C,D,A,B,X(11),16,0x6d9d6122L);
+	R2(B,C,D,A,X(14),23,0xfde5380cL);
+	R2(A,B,C,D,X( 1), 4,0xa4beea44L);
+	R2(D,A,B,C,X( 4),11,0x4bdecfa9L);
+	R2(C,D,A,B,X( 7),16,0xf6bb4b60L);
+	R2(B,C,D,A,X(10),23,0xbebfbc70L);
+	R2(A,B,C,D,X(13), 4,0x289b7ec6L);
+	R2(D,A,B,C,X( 0),11,0xeaa127faL);
+	R2(C,D,A,B,X( 3),16,0xd4ef3085L);
+	R2(B,C,D,A,X( 6),23,0x04881d05L);
+	R2(A,B,C,D,X( 9), 4,0xd9d4d039L);
+	R2(D,A,B,C,X(12),11,0xe6db99e5L);
+	R2(C,D,A,B,X(15),16,0x1fa27cf8L);
+	R2(B,C,D,A,X( 2),23,0xc4ac5665L);
+	/* Round 3 */
+	R3(A,B,C,D,X( 0), 6,0xf4292244L);
+	R3(D,A,B,C,X( 7),10,0x432aff97L);
+	R3(C,D,A,B,X(14),15,0xab9423a7L);
+	R3(B,C,D,A,X( 5),21,0xfc93a039L);
+	R3(A,B,C,D,X(12), 6,0x655b59c3L);
+	R3(D,A,B,C,X( 3),10,0x8f0ccc92L);
+	R3(C,D,A,B,X(10),15,0xffeff47dL);
+	R3(B,C,D,A,X( 1),21,0x85845dd1L);
+	R3(A,B,C,D,X( 8), 6,0x6fa87e4fL);
+	R3(D,A,B,C,X(15),10,0xfe2ce6e0L);
+	R3(C,D,A,B,X( 6),15,0xa3014314L);
+	R3(B,C,D,A,X(13),21,0x4e0811a1L);
+	R3(A,B,C,D,X( 4), 6,0xf7537e82L);
+	R3(D,A,B,C,X(11),10,0xbd3af235L);
+	R3(C,D,A,B,X( 2),15,0x2ad7d2bbL);
+	R3(B,C,D,A,X( 9),21,0xeb86d391L);
+
+	A = c->A += A;
+	B = c->B += B;
+	C = c->C += C;
+	D = c->D += D;
+		}
+	}
+#endif
diff --git a/openssl/crypto/md5/md5_locl.h b/openssl/crypto/md5/md5_locl.h
new file mode 100644
index 0000000..968d577
--- /dev/null
+++ b/openssl/crypto/md5/md5_locl.h
@@ -0,0 +1,130 @@
+/* crypto/md5/md5_locl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/e_os2.h>
+#include <openssl/md5.h>
+
+#ifndef MD5_LONG_LOG2
+#define MD5_LONG_LOG2 2 /* default to 32 bits */
+#endif
+
+#ifdef MD5_ASM
+# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) || \
+     defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
+#  define md5_block_data_order md5_block_asm_data_order
+# elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
+#  define md5_block_data_order md5_block_asm_data_order
+# endif
+#endif
+
+void md5_block_data_order (MD5_CTX *c, const void *p,size_t num);
+
+#define DATA_ORDER_IS_LITTLE_ENDIAN
+
+#define HASH_LONG		MD5_LONG
+#define HASH_CTX		MD5_CTX
+#define HASH_CBLOCK		MD5_CBLOCK
+#define HASH_UPDATE		MD5_Update
+#define HASH_TRANSFORM		MD5_Transform
+#define HASH_FINAL		MD5_Final
+#define	HASH_MAKE_STRING(c,s)	do {	\
+	unsigned long ll;		\
+	ll=(c)->A; HOST_l2c(ll,(s));	\
+	ll=(c)->B; HOST_l2c(ll,(s));	\
+	ll=(c)->C; HOST_l2c(ll,(s));	\
+	ll=(c)->D; HOST_l2c(ll,(s));	\
+	} while (0)
+#define	HASH_BLOCK_DATA_ORDER	md5_block_data_order
+
+#include "md32_common.h"
+
+/*
+#define	F(x,y,z)	(((x) & (y))  |  ((~(x)) & (z)))
+#define	G(x,y,z)	(((x) & (z))  |  ((y) & (~(z))))
+*/
+
+/* As pointed out by Wei Dai <weidai@eskimo.com>, the above can be
+ * simplified to the code below.  Wei attributes these optimizations
+ * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
+ */
+#define	F(b,c,d)	((((c) ^ (d)) & (b)) ^ (d))
+#define	G(b,c,d)	((((b) ^ (c)) & (d)) ^ (c))
+#define	H(b,c,d)	((b) ^ (c) ^ (d))
+#define	I(b,c,d)	(((~(d)) | (b)) ^ (c))
+
+#define R0(a,b,c,d,k,s,t) { \
+	a+=((k)+(t)+F((b),(c),(d))); \
+	a=ROTATE(a,s); \
+	a+=b; };\
+
+#define R1(a,b,c,d,k,s,t) { \
+	a+=((k)+(t)+G((b),(c),(d))); \
+	a=ROTATE(a,s); \
+	a+=b; };
+
+#define R2(a,b,c,d,k,s,t) { \
+	a+=((k)+(t)+H((b),(c),(d))); \
+	a=ROTATE(a,s); \
+	a+=b; };
+
+#define R3(a,b,c,d,k,s,t) { \
+	a+=((k)+(t)+I((b),(c),(d))); \
+	a=ROTATE(a,s); \
+	a+=b; };
diff --git a/openssl/crypto/md5/md5_one.c b/openssl/crypto/md5/md5_one.c
new file mode 100644
index 0000000..43fee89
--- /dev/null
+++ b/openssl/crypto/md5/md5_one.c
@@ -0,0 +1,97 @@
+/* crypto/md5/md5_one.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/md5.h>
+#include <openssl/crypto.h>
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md)
+	{
+	MD5_CTX c;
+	static unsigned char m[MD5_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	if (!MD5_Init(&c))
+		return NULL;
+#ifndef CHARSET_EBCDIC
+	MD5_Update(&c,d,n);
+#else
+	{
+		char temp[1024];
+		unsigned long chunk;
+
+		while (n > 0)
+		{
+			chunk = (n > sizeof(temp)) ? sizeof(temp) : n;
+			ebcdic2ascii(temp, d, chunk);
+			MD5_Update(&c,temp,chunk);
+			n -= chunk;
+			d += chunk;
+		}
+	}
+#endif
+	MD5_Final(md,&c);
+	OPENSSL_cleanse(&c,sizeof(c)); /* security consideration */
+	return(md);
+	}
+
diff --git a/openssl/crypto/md5/md5s.cpp b/openssl/crypto/md5/md5s.cpp
new file mode 100644
index 0000000..dd343fd
--- /dev/null
+++ b/openssl/crypto/md5/md5s.cpp
@@ -0,0 +1,78 @@
+//
+// gettsc.inl
+//
+// gives access to the Pentium's (secret) cycle counter
+//
+// This software was written by Leonard Janke (janke@unixg.ubc.ca)
+// in 1996-7 and is entered, by him, into the public domain.
+
+#if defined(__WATCOMC__)
+void GetTSC(unsigned long&);
+#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
+#elif defined(__GNUC__)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  asm volatile(".byte 15, 49\n\t"
+	       : "=eax" (tsc)
+	       :
+	       : "%edx", "%eax");
+}
+#elif defined(_MSC_VER)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  unsigned long a;
+  __asm _emit 0fh
+  __asm _emit 31h
+  __asm mov a, eax;
+  tsc=a;
+}
+#endif      
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/md5.h>
+
+extern "C" {
+void md5_block_x86(MD5_CTX *ctx, unsigned char *buffer,int num);
+}
+
+void main(int argc,char *argv[])
+	{
+	unsigned char buffer[64*256];
+	MD5_CTX ctx;
+	unsigned long s1,s2,e1,e2;
+	unsigned char k[16];
+	unsigned long data[2];
+	unsigned char iv[8];
+	int i,num=0,numm;
+	int j=0;
+
+	if (argc >= 2)
+		num=atoi(argv[1]);
+
+	if (num == 0) num=16;
+	if (num > 250) num=16;
+	numm=num+2;
+	num*=64;
+	numm*=64;
+
+	for (j=0; j<6; j++)
+		{
+		for (i=0; i<10; i++) /**/
+			{
+			md5_block_x86(&ctx,buffer,numm);
+			GetTSC(s1);
+			md5_block_x86(&ctx,buffer,numm);
+			GetTSC(e1);
+			GetTSC(s2);
+			md5_block_x86(&ctx,buffer,num);
+			GetTSC(e2);
+			md5_block_x86(&ctx,buffer,num);
+			}
+		printf("md5 (%d bytes) %d %d (%.2f)\n",num,
+			e1-s1,e2-s2,(double)((e1-s1)-(e2-s2))/2);
+		}
+	}
+
diff --git a/openssl/crypto/md5/md5test.c b/openssl/crypto/md5/md5test.c
new file mode 100644
index 0000000..2b37190
--- /dev/null
+++ b/openssl/crypto/md5/md5test.c
@@ -0,0 +1,140 @@
+/* crypto/md5/md5test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_MD5
+int main(int argc, char *argv[])
+{
+    printf("No MD5 support\n");
+    return(0);
+}
+#else
+#include <openssl/evp.h>
+#include <openssl/md5.h>
+
+static char *test[]={
+	"",
+	"a",
+	"abc",
+	"message digest",
+	"abcdefghijklmnopqrstuvwxyz",
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+	"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+	NULL,
+	};
+
+static char *ret[]={
+	"d41d8cd98f00b204e9800998ecf8427e",
+	"0cc175b9c0f1b6a831c399e269772661",
+	"900150983cd24fb0d6963f7d28e17f72",
+	"f96b697d7cb7938d525a2f31aaf161d0",
+	"c3fcd3d76192e4007dfb496cca67e13b",
+	"d174ab98d277d9f5a5611c2c9f419d9f",
+	"57edf4a22be3c955ac49da2e2107b67a",
+	};
+
+static char *pt(unsigned char *md);
+int main(int argc, char *argv[])
+	{
+	int i,err=0;
+	char **P,**R;
+	char *p;
+	unsigned char md[MD5_DIGEST_LENGTH];
+
+	P=test;
+	R=ret;
+	i=1;
+	while (*P != NULL)
+		{
+		EVP_Digest(&(P[0][0]),strlen((char *)*P),md,NULL,EVP_md5(), NULL);
+		p=pt(md);
+		if (strcmp(p,(char *)*R) != 0)
+			{
+			printf("error calculating MD5 on '%s'\n",*P);
+			printf("got %s instead of %s\n",p,*R);
+			err++;
+			}
+		else
+			printf("test %d ok\n",i);
+		i++;
+		R++;
+		P++;
+		}
+
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
+	EXIT(err);
+	return(0);
+	}
+
+static char *pt(unsigned char *md)
+	{
+	int i;
+	static char buf[80];
+
+	for (i=0; i<MD5_DIGEST_LENGTH; i++)
+		sprintf(&(buf[i*2]),"%02x",md[i]);
+	return(buf);
+	}
+#endif
diff --git a/openssl/crypto/mdc2/Makefile b/openssl/crypto/mdc2/Makefile
new file mode 100644
index 0000000..1d064f1
--- /dev/null
+++ b/openssl/crypto/mdc2/Makefile
@@ -0,0 +1,93 @@
+#
+# OpenSSL/crypto/mdc2/Makefile
+#
+
+DIR=	mdc2
+TOP=	../..
+CC=	cc
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST= mdc2test.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=mdc2dgst.c mdc2_one.c
+LIBOBJ=mdc2dgst.o mdc2_one.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= mdc2.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+mdc2_one.o: ../../e_os.h ../../include/openssl/bio.h
+mdc2_one.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+mdc2_one.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+mdc2_one.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+mdc2_one.o: ../../include/openssl/lhash.h ../../include/openssl/mdc2.h
+mdc2_one.o: ../../include/openssl/opensslconf.h
+mdc2_one.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+mdc2_one.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+mdc2_one.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+mdc2_one.o: ../../include/openssl/ui_compat.h ../cryptlib.h mdc2_one.c
+mdc2dgst.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+mdc2dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/mdc2.h
+mdc2dgst.o: ../../include/openssl/opensslconf.h
+mdc2dgst.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+mdc2dgst.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+mdc2dgst.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+mdc2dgst.o: mdc2dgst.c
diff --git a/openssl/crypto/mdc2/mdc2.h b/openssl/crypto/mdc2/mdc2.h
new file mode 100644
index 0000000..72778a5
--- /dev/null
+++ b/openssl/crypto/mdc2/mdc2.h
@@ -0,0 +1,95 @@
+/* crypto/mdc2/mdc2.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_MDC2_H
+#define HEADER_MDC2_H
+
+#include <openssl/des.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_MDC2
+#error MDC2 is disabled.
+#endif
+
+#define MDC2_BLOCK              8
+#define MDC2_DIGEST_LENGTH      16
+ 
+typedef struct mdc2_ctx_st
+	{
+	unsigned int num;
+	unsigned char data[MDC2_BLOCK];
+	DES_cblock h,hh;
+	int pad_type; /* either 1 or 2, default 1 */
+	} MDC2_CTX;
+
+
+int MDC2_Init(MDC2_CTX *c);
+int MDC2_Update(MDC2_CTX *c, const unsigned char *data, size_t len);
+int MDC2_Final(unsigned char *md, MDC2_CTX *c);
+unsigned char *MDC2(const unsigned char *d, size_t n,
+	unsigned char *md);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/openssl/crypto/mdc2/mdc2_one.c b/openssl/crypto/mdc2/mdc2_one.c
new file mode 100644
index 0000000..72647f6
--- /dev/null
+++ b/openssl/crypto/mdc2/mdc2_one.c
@@ -0,0 +1,76 @@
+/* crypto/mdc2/mdc2_one.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/mdc2.h>
+
+unsigned char *MDC2(const unsigned char *d, size_t n, unsigned char *md)
+	{
+	MDC2_CTX c;
+	static unsigned char m[MDC2_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	if (!MDC2_Init(&c))
+		return NULL;
+	MDC2_Update(&c,d,n);
+        MDC2_Final(md,&c);
+	OPENSSL_cleanse(&c,sizeof(c)); /* security consideration */
+	return(md);
+	}
+
diff --git a/openssl/crypto/mdc2/mdc2dgst.c b/openssl/crypto/mdc2/mdc2dgst.c
new file mode 100644
index 0000000..4aa406e
--- /dev/null
+++ b/openssl/crypto/mdc2/mdc2dgst.c
@@ -0,0 +1,199 @@
+/* crypto/mdc2/mdc2dgst.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/des.h>
+#include <openssl/mdc2.h>
+
+#undef c2l
+#define c2l(c,l)	(l =((DES_LONG)(*((c)++)))    , \
+			 l|=((DES_LONG)(*((c)++)))<< 8L, \
+			 l|=((DES_LONG)(*((c)++)))<<16L, \
+			 l|=((DES_LONG)(*((c)++)))<<24L)
+
+#undef l2c
+#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
+			*((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+			*((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+			*((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len);
+int MDC2_Init(MDC2_CTX *c)
+	{
+	c->num=0;
+	c->pad_type=1;
+	memset(&(c->h[0]),0x52,MDC2_BLOCK);
+	memset(&(c->hh[0]),0x25,MDC2_BLOCK);
+	return 1;
+	}
+
+int MDC2_Update(MDC2_CTX *c, const unsigned char *in, size_t len)
+	{
+	size_t i,j;
+
+	i=c->num;
+	if (i != 0)
+		{
+		if (i+len < MDC2_BLOCK)
+			{
+			/* partial block */
+			memcpy(&(c->data[i]),in,len);
+			c->num+=(int)len;
+			return 1;
+			}
+		else
+			{
+			/* filled one */
+			j=MDC2_BLOCK-i;
+			memcpy(&(c->data[i]),in,j);
+			len-=j;
+			in+=j;
+			c->num=0;
+			mdc2_body(c,&(c->data[0]),MDC2_BLOCK);
+			}
+		}
+	i=len&~((size_t)MDC2_BLOCK-1);
+	if (i > 0) mdc2_body(c,in,i);
+	j=len-i;
+	if (j > 0)
+		{
+		memcpy(&(c->data[0]),&(in[i]),j);
+		c->num=(int)j;
+		}
+	return 1;
+	}
+
+static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len)
+	{
+	register DES_LONG tin0,tin1;
+	register DES_LONG ttin0,ttin1;
+	DES_LONG d[2],dd[2];
+	DES_key_schedule k;
+	unsigned char *p;
+	size_t i;
+
+	for (i=0; i<len; i+=8)
+		{
+		c2l(in,tin0); d[0]=dd[0]=tin0;
+		c2l(in,tin1); d[1]=dd[1]=tin1;
+		c->h[0]=(c->h[0]&0x9f)|0x40;
+		c->hh[0]=(c->hh[0]&0x9f)|0x20;
+
+		DES_set_odd_parity(&c->h);
+		DES_set_key_unchecked(&c->h,&k);
+		DES_encrypt1(d,&k,1);
+
+		DES_set_odd_parity(&c->hh);
+		DES_set_key_unchecked(&c->hh,&k);
+		DES_encrypt1(dd,&k,1);
+
+		ttin0=tin0^dd[0];
+		ttin1=tin1^dd[1];
+		tin0^=d[0];
+		tin1^=d[1];
+
+		p=c->h;
+		l2c(tin0,p);
+		l2c(ttin1,p);
+		p=c->hh;
+		l2c(ttin0,p);
+		l2c(tin1,p);
+		}
+	}
+
+int MDC2_Final(unsigned char *md, MDC2_CTX *c)
+	{
+	unsigned int i;
+	int j;
+
+	i=c->num;
+	j=c->pad_type;
+	if ((i > 0) || (j == 2))
+		{
+		if (j == 2)
+			c->data[i++]=0x80;
+		memset(&(c->data[i]),0,MDC2_BLOCK-i);
+		mdc2_body(c,c->data,MDC2_BLOCK);
+		}
+	memcpy(md,(char *)c->h,MDC2_BLOCK);
+	memcpy(&(md[MDC2_BLOCK]),(char *)c->hh,MDC2_BLOCK);
+	return 1;
+	}
+
+#undef TEST
+
+#ifdef TEST
+main()
+	{
+	unsigned char md[MDC2_DIGEST_LENGTH];
+	int i;
+	MDC2_CTX c;
+	static char *text="Now is the time for all ";
+
+	MDC2_Init(&c);
+	MDC2_Update(&c,text,strlen(text));
+	MDC2_Final(&(md[0]),&c);
+
+	for (i=0; i<MDC2_DIGEST_LENGTH; i++)
+		printf("%02X",md[i]);
+	printf("\n");
+	}
+
+#endif
diff --git a/openssl/crypto/mdc2/mdc2test.c b/openssl/crypto/mdc2/mdc2test.c
new file mode 100644
index 0000000..017b31a
--- /dev/null
+++ b/openssl/crypto/mdc2/mdc2test.c
@@ -0,0 +1,149 @@
+/* crypto/mdc2/mdc2test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../e_os.h"
+
+#if defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_MDC2)
+#define OPENSSL_NO_MDC2
+#endif
+
+#ifdef OPENSSL_NO_MDC2
+int main(int argc, char *argv[])
+{
+    printf("No MDC2 support\n");
+    return(0);
+}
+#else
+#include <openssl/evp.h>
+#include <openssl/mdc2.h>
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+static unsigned char pad1[16]={
+	0x42,0xE5,0x0C,0xD2,0x24,0xBA,0xCE,0xBA,
+	0x76,0x0B,0xDD,0x2B,0xD4,0x09,0x28,0x1A
+	};
+
+static unsigned char pad2[16]={
+	0x2E,0x46,0x79,0xB5,0xAD,0xD9,0xCA,0x75,
+	0x35,0xD8,0x7A,0xFE,0xAB,0x33,0xBE,0xE2
+	};
+
+int main(int argc, char *argv[])
+	{
+	int ret=0;
+	unsigned char md[MDC2_DIGEST_LENGTH];
+	int i;
+	EVP_MD_CTX c;
+	static char *text="Now is the time for all ";
+
+#ifdef CHARSET_EBCDIC
+	ebcdic2ascii(text,text,strlen(text));
+#endif
+
+	EVP_MD_CTX_init(&c);
+	EVP_DigestInit_ex(&c,EVP_mdc2(), NULL);
+	EVP_DigestUpdate(&c,(unsigned char *)text,strlen(text));
+	EVP_DigestFinal_ex(&c,&(md[0]),NULL);
+
+	if (memcmp(md,pad1,MDC2_DIGEST_LENGTH) != 0)
+		{
+		for (i=0; i<MDC2_DIGEST_LENGTH; i++)
+			printf("%02X",md[i]);
+		printf(" <- generated\n");
+		for (i=0; i<MDC2_DIGEST_LENGTH; i++)
+			printf("%02X",pad1[i]);
+		printf(" <- correct\n");
+		ret=1;
+		}
+	else
+		printf("pad1 - ok\n");
+
+	EVP_DigestInit_ex(&c,EVP_mdc2(), NULL);
+	/* FIXME: use a ctl function? */
+	((MDC2_CTX *)c.md_data)->pad_type=2;
+	EVP_DigestUpdate(&c,(unsigned char *)text,strlen(text));
+	EVP_DigestFinal_ex(&c,&(md[0]),NULL);
+
+	if (memcmp(md,pad2,MDC2_DIGEST_LENGTH) != 0)
+		{
+		for (i=0; i<MDC2_DIGEST_LENGTH; i++)
+			printf("%02X",md[i]);
+		printf(" <- generated\n");
+		for (i=0; i<MDC2_DIGEST_LENGTH; i++)
+			printf("%02X",pad2[i]);
+		printf(" <- correct\n");
+		ret=1;
+		}
+	else
+		printf("pad2 - ok\n");
+
+	EVP_MD_CTX_cleanup(&c);
+#ifdef OPENSSL_SYS_NETWARE
+    if (ret) printf("ERROR: %d\n", ret);
+#endif
+	EXIT(ret);
+	return(ret);
+	}
+#endif
diff --git a/openssl/crypto/mem.c b/openssl/crypto/mem.c
new file mode 100644
index 0000000..6f80dd3
--- /dev/null
+++ b/openssl/crypto/mem.c
@@ -0,0 +1,414 @@
+/* crypto/mem.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+
+
+static int allow_customize = 1;      /* we provide flexible functions for */
+static int allow_customize_debug = 1;/* exchanging memory-related functions at
+                                      * run-time, but this must be done
+                                      * before any blocks are actually
+                                      * allocated; or we'll run into huge
+                                      * problems when malloc/free pairs
+                                      * don't match etc. */
+
+
+
+/* the following pointers may be changed as long as 'allow_customize' is set */
+
+static void *(*malloc_func)(size_t)         = malloc;
+static void *default_malloc_ex(size_t num, const char *file, int line)
+	{ return malloc_func(num); }
+static void *(*malloc_ex_func)(size_t, const char *file, int line)
+        = default_malloc_ex;
+
+static void *(*realloc_func)(void *, size_t)= realloc;
+static void *default_realloc_ex(void *str, size_t num,
+        const char *file, int line)
+	{ return realloc_func(str,num); }
+static void *(*realloc_ex_func)(void *, size_t, const char *file, int line)
+        = default_realloc_ex;
+
+static void (*free_func)(void *)            = free;
+
+static void *(*malloc_locked_func)(size_t)  = malloc;
+static void *default_malloc_locked_ex(size_t num, const char *file, int line)
+	{ return malloc_locked_func(num); }
+static void *(*malloc_locked_ex_func)(size_t, const char *file, int line)
+        = default_malloc_locked_ex;
+
+static void (*free_locked_func)(void *)     = free;
+
+
+
+/* may be changed as long as 'allow_customize_debug' is set */
+/* XXX use correct function pointer types */
+#ifdef CRYPTO_MDEBUG
+/* use default functions from mem_dbg.c */
+static void (*malloc_debug_func)(void *,int,const char *,int,int)
+	= CRYPTO_dbg_malloc;
+static void (*realloc_debug_func)(void *,void *,int,const char *,int,int)
+	= CRYPTO_dbg_realloc;
+static void (*free_debug_func)(void *,int) = CRYPTO_dbg_free;
+static void (*set_debug_options_func)(long) = CRYPTO_dbg_set_options;
+static long (*get_debug_options_func)(void) = CRYPTO_dbg_get_options;
+#else
+/* applications can use CRYPTO_malloc_debug_init() to select above case
+ * at run-time */
+static void (*malloc_debug_func)(void *,int,const char *,int,int) = NULL;
+static void (*realloc_debug_func)(void *,void *,int,const char *,int,int)
+	= NULL;
+static void (*free_debug_func)(void *,int) = NULL;
+static void (*set_debug_options_func)(long) = NULL;
+static long (*get_debug_options_func)(void) = NULL;
+#endif
+
+
+int CRYPTO_set_mem_functions(void *(*m)(size_t), void *(*r)(void *, size_t),
+	void (*f)(void *))
+	{
+	if (!allow_customize)
+		return 0;
+	if ((m == 0) || (r == 0) || (f == 0))
+		return 0;
+	malloc_func=m; malloc_ex_func=default_malloc_ex;
+	realloc_func=r; realloc_ex_func=default_realloc_ex;
+	free_func=f;
+	malloc_locked_func=m; malloc_locked_ex_func=default_malloc_locked_ex;
+	free_locked_func=f;
+	return 1;
+	}
+
+int CRYPTO_set_mem_ex_functions(
+        void *(*m)(size_t,const char *,int),
+        void *(*r)(void *, size_t,const char *,int),
+	void (*f)(void *))
+	{
+	if (!allow_customize)
+		return 0;
+	if ((m == 0) || (r == 0) || (f == 0))
+		return 0;
+	malloc_func=0; malloc_ex_func=m;
+	realloc_func=0; realloc_ex_func=r;
+	free_func=f;
+	malloc_locked_func=0; malloc_locked_ex_func=m;
+	free_locked_func=f;
+	return 1;
+	}
+
+int CRYPTO_set_locked_mem_functions(void *(*m)(size_t), void (*f)(void *))
+	{
+	if (!allow_customize)
+		return 0;
+	if ((m == NULL) || (f == NULL))
+		return 0;
+	malloc_locked_func=m; malloc_locked_ex_func=default_malloc_locked_ex;
+	free_locked_func=f;
+	return 1;
+	}
+
+int CRYPTO_set_locked_mem_ex_functions(
+        void *(*m)(size_t,const char *,int),
+        void (*f)(void *))
+	{
+	if (!allow_customize)
+		return 0;
+	if ((m == NULL) || (f == NULL))
+		return 0;
+	malloc_locked_func=0; malloc_locked_ex_func=m;
+	free_func=f;
+	return 1;
+	}
+
+int CRYPTO_set_mem_debug_functions(void (*m)(void *,int,const char *,int,int),
+				   void (*r)(void *,void *,int,const char *,int,int),
+				   void (*f)(void *,int),
+				   void (*so)(long),
+				   long (*go)(void))
+	{
+	if (!allow_customize_debug)
+		return 0;
+	malloc_debug_func=m;
+	realloc_debug_func=r;
+	free_debug_func=f;
+	set_debug_options_func=so;
+	get_debug_options_func=go;
+	return 1;
+	}
+
+
+void CRYPTO_get_mem_functions(void *(**m)(size_t), void *(**r)(void *, size_t),
+	void (**f)(void *))
+	{
+	if (m != NULL) *m = (malloc_ex_func == default_malloc_ex) ? 
+	                     malloc_func : 0;
+	if (r != NULL) *r = (realloc_ex_func == default_realloc_ex) ? 
+	                     realloc_func : 0;
+	if (f != NULL) *f=free_func;
+	}
+
+void CRYPTO_get_mem_ex_functions(
+        void *(**m)(size_t,const char *,int),
+        void *(**r)(void *, size_t,const char *,int),
+	void (**f)(void *))
+	{
+	if (m != NULL) *m = (malloc_ex_func != default_malloc_ex) ?
+	                    malloc_ex_func : 0;
+	if (r != NULL) *r = (realloc_ex_func != default_realloc_ex) ?
+	                    realloc_ex_func : 0;
+	if (f != NULL) *f=free_func;
+	}
+
+void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *))
+	{
+	if (m != NULL) *m = (malloc_locked_ex_func == default_malloc_locked_ex) ? 
+	                     malloc_locked_func : 0;
+	if (f != NULL) *f=free_locked_func;
+	}
+
+void CRYPTO_get_locked_mem_ex_functions(
+        void *(**m)(size_t,const char *,int),
+        void (**f)(void *))
+	{
+	if (m != NULL) *m = (malloc_locked_ex_func != default_malloc_locked_ex) ?
+	                    malloc_locked_ex_func : 0;
+	if (f != NULL) *f=free_locked_func;
+	}
+
+void CRYPTO_get_mem_debug_functions(void (**m)(void *,int,const char *,int,int),
+				    void (**r)(void *,void *,int,const char *,int,int),
+				    void (**f)(void *,int),
+				    void (**so)(long),
+				    long (**go)(void))
+	{
+	if (m != NULL) *m=malloc_debug_func;
+	if (r != NULL) *r=realloc_debug_func;
+	if (f != NULL) *f=free_debug_func;
+	if (so != NULL) *so=set_debug_options_func;
+	if (go != NULL) *go=get_debug_options_func;
+	}
+
+
+void *CRYPTO_malloc_locked(int num, const char *file, int line)
+	{
+	void *ret = NULL;
+
+	if (num <= 0) return NULL;
+
+	allow_customize = 0;
+	if (malloc_debug_func != NULL)
+		{
+		allow_customize_debug = 0;
+		malloc_debug_func(NULL, num, file, line, 0);
+		}
+	ret = malloc_locked_ex_func(num,file,line);
+#ifdef LEVITTE_DEBUG_MEM
+	fprintf(stderr, "LEVITTE_DEBUG_MEM:         > 0x%p (%d)\n", ret, num);
+#endif
+	if (malloc_debug_func != NULL)
+		malloc_debug_func(ret, num, file, line, 1);
+
+#ifndef OPENSSL_CPUID_OBJ
+        /* Create a dependency on the value of 'cleanse_ctr' so our memory
+         * sanitisation function can't be optimised out. NB: We only do
+         * this for >2Kb so the overhead doesn't bother us. */
+        if(ret && (num > 2048))
+	{	extern unsigned char cleanse_ctr;
+		((unsigned char *)ret)[0] = cleanse_ctr;
+	}
+#endif
+
+	return ret;
+	}
+
+void CRYPTO_free_locked(void *str)
+	{
+	if (free_debug_func != NULL)
+		free_debug_func(str, 0);
+#ifdef LEVITTE_DEBUG_MEM
+	fprintf(stderr, "LEVITTE_DEBUG_MEM:         < 0x%p\n", str);
+#endif
+	free_locked_func(str);
+	if (free_debug_func != NULL)
+		free_debug_func(NULL, 1);
+	}
+
+void *CRYPTO_malloc(int num, const char *file, int line)
+	{
+	void *ret = NULL;
+
+	if (num <= 0) return NULL;
+
+	allow_customize = 0;
+	if (malloc_debug_func != NULL)
+		{
+		allow_customize_debug = 0;
+		malloc_debug_func(NULL, num, file, line, 0);
+		}
+	ret = malloc_ex_func(num,file,line);
+#ifdef LEVITTE_DEBUG_MEM
+	fprintf(stderr, "LEVITTE_DEBUG_MEM:         > 0x%p (%d)\n", ret, num);
+#endif
+	if (malloc_debug_func != NULL)
+		malloc_debug_func(ret, num, file, line, 1);
+
+#ifndef OPENSSL_CPUID_OBJ
+        /* Create a dependency on the value of 'cleanse_ctr' so our memory
+         * sanitisation function can't be optimised out. NB: We only do
+         * this for >2Kb so the overhead doesn't bother us. */
+        if(ret && (num > 2048))
+	{	extern unsigned char cleanse_ctr;
+                ((unsigned char *)ret)[0] = cleanse_ctr;
+	}
+#endif
+
+	return ret;
+	}
+char *CRYPTO_strdup(const char *str, const char *file, int line)
+	{
+	char *ret = CRYPTO_malloc(strlen(str)+1, file, line);
+
+	strcpy(ret, str);
+	return ret;
+	}
+
+void *CRYPTO_realloc(void *str, int num, const char *file, int line)
+	{
+	void *ret = NULL;
+
+	if (str == NULL)
+		return CRYPTO_malloc(num, file, line);
+
+	if (num <= 0) return NULL;
+
+	if (realloc_debug_func != NULL)
+		realloc_debug_func(str, NULL, num, file, line, 0);
+	ret = realloc_ex_func(str,num,file,line);
+#ifdef LEVITTE_DEBUG_MEM
+	fprintf(stderr, "LEVITTE_DEBUG_MEM:         | 0x%p -> 0x%p (%d)\n", str, ret, num);
+#endif
+	if (realloc_debug_func != NULL)
+		realloc_debug_func(str, ret, num, file, line, 1);
+
+	return ret;
+	}
+
+void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file,
+			   int line)
+	{
+	void *ret = NULL;
+
+	if (str == NULL)
+		return CRYPTO_malloc(num, file, line);
+
+	if (num <= 0) return NULL;
+
+	if (realloc_debug_func != NULL)
+		realloc_debug_func(str, NULL, num, file, line, 0);
+	ret=malloc_ex_func(num,file,line);
+	if(ret)
+		{
+		memcpy(ret,str,old_len);
+		OPENSSL_cleanse(str,old_len);
+		free_func(str);
+		}
+#ifdef LEVITTE_DEBUG_MEM
+	fprintf(stderr,
+		"LEVITTE_DEBUG_MEM:         | 0x%p -> 0x%p (%d)\n",
+		str, ret, num);
+#endif
+	if (realloc_debug_func != NULL)
+		realloc_debug_func(str, ret, num, file, line, 1);
+
+	return ret;
+	}
+
+void CRYPTO_free(void *str)
+	{
+	if (free_debug_func != NULL)
+		free_debug_func(str, 0);
+#ifdef LEVITTE_DEBUG_MEM
+	fprintf(stderr, "LEVITTE_DEBUG_MEM:         < 0x%p\n", str);
+#endif
+	free_func(str);
+	if (free_debug_func != NULL)
+		free_debug_func(NULL, 1);
+	}
+
+void *CRYPTO_remalloc(void *a, int num, const char *file, int line)
+	{
+	if (a != NULL) OPENSSL_free(a);
+	a=(char *)OPENSSL_malloc(num);
+	return(a);
+	}
+
+void CRYPTO_set_mem_debug_options(long bits)
+	{
+	if (set_debug_options_func != NULL)
+		set_debug_options_func(bits);
+	}
+
+long CRYPTO_get_mem_debug_options(void)
+	{
+	if (get_debug_options_func != NULL)
+		return get_debug_options_func();
+	return 0;
+	}
diff --git a/openssl/crypto/mem_clr.c b/openssl/crypto/mem_clr.c
new file mode 100644
index 0000000..add1f78
--- /dev/null
+++ b/openssl/crypto/mem_clr.c
@@ -0,0 +1,77 @@
+/* crypto/mem_clr.c -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+#include <openssl/crypto.h>
+
+unsigned char cleanse_ctr = 0;
+
+void OPENSSL_cleanse(void *ptr, size_t len)
+	{
+	unsigned char *p = ptr;
+	size_t loop = len, ctr = cleanse_ctr;
+	while(loop--)
+		{
+		*(p++) = (unsigned char)ctr;
+		ctr += (17 + ((size_t)p & 0xF));
+		}
+	p=memchr(ptr, (unsigned char)ctr, len);
+	if(p)
+		ctr += (63 + (size_t)p);
+	cleanse_ctr = (unsigned char)ctr;
+	}
diff --git a/openssl/crypto/mem_dbg.c b/openssl/crypto/mem_dbg.c
new file mode 100644
index 0000000..ac79339
--- /dev/null
+++ b/openssl/crypto/mem_dbg.c
@@ -0,0 +1,874 @@
+/* crypto/mem_dbg.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>	
+#include "cryptlib.h"
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#include <openssl/lhash.h>
+
+static int mh_mode=CRYPTO_MEM_CHECK_OFF;
+/* The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE
+ * when the application asks for it (usually after library initialisation
+ * for which no book-keeping is desired).
+ *
+ * State CRYPTO_MEM_CHECK_ON exists only temporarily when the library
+ * thinks that certain allocations should not be checked (e.g. the data
+ * structures used for memory checking).  It is not suitable as an initial
+ * state: the library will unexpectedly enable memory checking when it
+ * executes one of those sections that want to disable checking
+ * temporarily.
+ *
+ * State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes no sense whatsoever.
+ */
+
+static unsigned long order = 0; /* number of memory requests */
+
+DECLARE_LHASH_OF(MEM);
+static LHASH_OF(MEM) *mh=NULL; /* hash-table of memory requests
+				* (address as key); access requires
+				* MALLOC2 lock */
+
+
+typedef struct app_mem_info_st
+/* For application-defined information (static C-string `info')
+ * to be displayed in memory leak list.
+ * Each thread has its own stack.  For applications, there is
+ *   CRYPTO_push_info("...")     to push an entry,
+ *   CRYPTO_pop_info()           to pop an entry,
+ *   CRYPTO_remove_all_info()    to pop all entries.
+ */
+	{
+	CRYPTO_THREADID threadid;
+	const char *file;
+	int line;
+	const char *info;
+	struct app_mem_info_st *next; /* tail of thread's stack */
+	int references;
+	} APP_INFO;
+
+static void app_info_free(APP_INFO *);
+
+DECLARE_LHASH_OF(APP_INFO);
+static LHASH_OF(APP_INFO) *amih=NULL; /* hash-table with those
+				       * app_mem_info_st's that are at
+				       * the top of their thread's
+				       * stack (with `thread' as key);
+				       * access requires MALLOC2
+				       * lock */
+
+typedef struct mem_st
+/* memory-block description */
+	{
+	void *addr;
+	int num;
+	const char *file;
+	int line;
+	CRYPTO_THREADID threadid;
+	unsigned long order;
+	time_t time;
+	APP_INFO *app_info;
+	} MEM;
+
+static long options =             /* extra information to be recorded */
+#if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL)
+	V_CRYPTO_MDEBUG_TIME |
+#endif
+#if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL)
+	V_CRYPTO_MDEBUG_THREAD |
+#endif
+	0;
+
+
+static unsigned int num_disable = 0; /* num_disable > 0
+                                      *     iff
+                                      * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE)
+                                      */
+
+/* Valid iff num_disable > 0.  CRYPTO_LOCK_MALLOC2 is locked exactly in this
+ * case (by the thread named in disabling_thread).
+ */
+static CRYPTO_THREADID disabling_threadid;
+
+static void app_info_free(APP_INFO *inf)
+	{
+	if (--(inf->references) <= 0)
+		{
+		if (inf->next != NULL)
+			{
+			app_info_free(inf->next);
+			}
+		OPENSSL_free(inf);
+		}
+	}
+
+int CRYPTO_mem_ctrl(int mode)
+	{
+	int ret=mh_mode;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
+	switch (mode)
+		{
+	/* for applications (not to be called while multiple threads
+	 * use the library): */
+	case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */
+		mh_mode = CRYPTO_MEM_CHECK_ON|CRYPTO_MEM_CHECK_ENABLE;
+		num_disable = 0;
+		break;
+	case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
+		mh_mode = 0;
+		num_disable = 0; /* should be true *before* MemCheck_stop is used,
+		                    or there'll be a lot of confusion */
+		break;
+
+	/* switch off temporarily (for library-internal use): */
+	case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
+		if (mh_mode & CRYPTO_MEM_CHECK_ON)
+			{
+			CRYPTO_THREADID cur;
+			CRYPTO_THREADID_current(&cur);
+			if (!num_disable || CRYPTO_THREADID_cmp(&disabling_threadid, &cur)) /* otherwise we already have the MALLOC2 lock */
+				{
+				/* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
+				 * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
+				 * somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot release
+				 * it because we block entry to this function).
+				 * Give them a chance, first, and then claim the locks in
+				 * appropriate order (long-time lock first).
+				 */
+				CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
+				/* Note that after we have waited for CRYPTO_LOCK_MALLOC2
+				 * and CRYPTO_LOCK_MALLOC, we'll still be in the right
+				 * "case" and "if" branch because MemCheck_start and
+				 * MemCheck_stop may never be used while there are multiple
+				 * OpenSSL threads. */
+				CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
+				CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
+				mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
+				CRYPTO_THREADID_cpy(&disabling_threadid, &cur);
+				}
+			num_disable++;
+			}
+		break;
+	case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
+		if (mh_mode & CRYPTO_MEM_CHECK_ON)
+			{
+			if (num_disable) /* always true, or something is going wrong */
+				{
+				num_disable--;
+				if (num_disable == 0)
+					{
+					mh_mode|=CRYPTO_MEM_CHECK_ENABLE;
+					CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
+					}
+				}
+			}
+		break;
+
+	default:
+		break;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
+	return(ret);
+	}
+
+int CRYPTO_is_mem_check_on(void)
+	{
+	int ret = 0;
+
+	if (mh_mode & CRYPTO_MEM_CHECK_ON)
+		{
+		CRYPTO_THREADID cur;
+		CRYPTO_THREADID_current(&cur);
+		CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
+
+		ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
+		        || CRYPTO_THREADID_cmp(&disabling_threadid, &cur);
+
+		CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
+		}
+	return(ret);
+	}	
+
+
+void CRYPTO_dbg_set_options(long bits)
+	{
+	options = bits;
+	}
+
+long CRYPTO_dbg_get_options(void)
+	{
+	return options;
+	}
+
+static int mem_cmp(const MEM *a, const MEM *b)
+	{
+#ifdef _WIN64
+	const char *ap=(const char *)a->addr,
+		   *bp=(const char *)b->addr;
+	if (ap==bp)	return 0;
+	else if (ap>bp)	return 1;
+	else		return -1;
+#else
+	return (const char *)a->addr - (const char *)b->addr;
+#endif
+	}
+static IMPLEMENT_LHASH_COMP_FN(mem, MEM)
+
+static unsigned long mem_hash(const MEM *a)
+	{
+	unsigned long ret;
+
+	ret=(unsigned long)a->addr;
+
+	ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
+	return(ret);
+	}
+static IMPLEMENT_LHASH_HASH_FN(mem, MEM)
+
+/* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
+static int app_info_cmp(const void *a_void, const void *b_void)
+	{
+	return CRYPTO_THREADID_cmp(&((const APP_INFO *)a_void)->threadid,
+				&((const APP_INFO *)b_void)->threadid);
+	}
+static IMPLEMENT_LHASH_COMP_FN(app_info, APP_INFO)
+
+static unsigned long app_info_hash(const APP_INFO *a)
+	{
+	unsigned long ret;
+
+	ret = CRYPTO_THREADID_hash(&a->threadid);
+	/* This is left in as a "who am I to question legacy?" measure */
+	ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
+	return(ret);
+	}
+static IMPLEMENT_LHASH_HASH_FN(app_info, APP_INFO)
+
+static APP_INFO *pop_info(void)
+	{
+	APP_INFO tmp;
+	APP_INFO *ret = NULL;
+
+	if (amih != NULL)
+		{
+		CRYPTO_THREADID_current(&tmp.threadid);
+		if ((ret=lh_APP_INFO_delete(amih,&tmp)) != NULL)
+			{
+			APP_INFO *next=ret->next;
+
+			if (next != NULL)
+				{
+				next->references++;
+				(void)lh_APP_INFO_insert(amih,next);
+				}
+#ifdef LEVITTE_DEBUG_MEM
+			if (CRYPTO_THREADID_cmp(&ret->threadid, &tmp.threadid))
+				{
+				fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
+					CRYPTO_THREADID_hash(&ret->threadid),
+					CRYPTO_THREADID_hash(&tmp.threadid));
+				abort();
+				}
+#endif
+			if (--(ret->references) <= 0)
+				{
+				ret->next = NULL;
+				if (next != NULL)
+					next->references--;
+				OPENSSL_free(ret);
+				}
+			}
+		}
+	return(ret);
+	}
+
+int CRYPTO_push_info_(const char *info, const char *file, int line)
+	{
+	APP_INFO *ami, *amim;
+	int ret=0;
+
+	if (is_MemCheck_on())
+		{
+		MemCheck_off(); /* obtain MALLOC2 lock */
+
+		if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL)
+			{
+			ret=0;
+			goto err;
+			}
+		if (amih == NULL)
+			{
+			if ((amih=lh_APP_INFO_new()) == NULL)
+				{
+				OPENSSL_free(ami);
+				ret=0;
+				goto err;
+				}
+			}
+
+		CRYPTO_THREADID_current(&ami->threadid);
+		ami->file=file;
+		ami->line=line;
+		ami->info=info;
+		ami->references=1;
+		ami->next=NULL;
+
+		if ((amim=lh_APP_INFO_insert(amih,ami)) != NULL)
+			{
+#ifdef LEVITTE_DEBUG_MEM
+			if (CRYPTO_THREADID_cmp(&ami->threadid, &amim->threadid))
+				{
+				fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
+					CRYPTO_THREADID_hash(&amim->threadid),
+					CRYPTO_THREADID_hash(&ami->threadid));
+				abort();
+				}
+#endif
+			ami->next=amim;
+			}
+ err:
+		MemCheck_on(); /* release MALLOC2 lock */
+		}
+
+	return(ret);
+	}
+
+int CRYPTO_pop_info(void)
+	{
+	int ret=0;
+
+	if (is_MemCheck_on()) /* _must_ be true, or something went severely wrong */
+		{
+		MemCheck_off(); /* obtain MALLOC2 lock */
+
+		ret=(pop_info() != NULL);
+
+		MemCheck_on(); /* release MALLOC2 lock */
+		}
+	return(ret);
+	}
+
+int CRYPTO_remove_all_info(void)
+	{
+	int ret=0;
+
+	if (is_MemCheck_on()) /* _must_ be true */
+		{
+		MemCheck_off(); /* obtain MALLOC2 lock */
+
+		while(pop_info() != NULL)
+			ret++;
+
+		MemCheck_on(); /* release MALLOC2 lock */
+		}
+	return(ret);
+	}
+
+
+static unsigned long break_order_num=0;
+void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
+	int before_p)
+	{
+	MEM *m,*mm;
+	APP_INFO tmp,*amim;
+
+	switch(before_p & 127)
+		{
+	case 0:
+		break;
+	case 1:
+		if (addr == NULL)
+			break;
+
+		if (is_MemCheck_on())
+			{
+			MemCheck_off(); /* make sure we hold MALLOC2 lock */
+			if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL)
+				{
+				OPENSSL_free(addr);
+				MemCheck_on(); /* release MALLOC2 lock
+				                * if num_disabled drops to 0 */
+				return;
+				}
+			if (mh == NULL)
+				{
+				if ((mh=lh_MEM_new()) == NULL)
+					{
+					OPENSSL_free(addr);
+					OPENSSL_free(m);
+					addr=NULL;
+					goto err;
+					}
+				}
+
+			m->addr=addr;
+			m->file=file;
+			m->line=line;
+			m->num=num;
+			if (options & V_CRYPTO_MDEBUG_THREAD)
+				CRYPTO_THREADID_current(&m->threadid);
+			else
+				memset(&m->threadid, 0, sizeof(m->threadid));
+
+			if (order == break_order_num)
+				{
+				/* BREAK HERE */
+				m->order=order;
+				}
+			m->order=order++;
+#ifdef LEVITTE_DEBUG_MEM
+			fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n",
+				m->order,
+				(before_p & 128) ? '*' : '+',
+				m->addr, m->num);
+#endif
+			if (options & V_CRYPTO_MDEBUG_TIME)
+				m->time=time(NULL);
+			else
+				m->time=0;
+
+			CRYPTO_THREADID_current(&tmp.threadid);
+			m->app_info=NULL;
+			if (amih != NULL
+			    && (amim=lh_APP_INFO_retrieve(amih,&tmp)) != NULL)
+				{
+				m->app_info = amim;
+				amim->references++;
+				}
+
+			if ((mm=lh_MEM_insert(mh, m)) != NULL)
+				{
+				/* Not good, but don't sweat it */
+				if (mm->app_info != NULL)
+					{
+					mm->app_info->references--;
+					}
+				OPENSSL_free(mm);
+				}
+		err:
+			MemCheck_on(); /* release MALLOC2 lock
+			                * if num_disabled drops to 0 */
+			}
+		break;
+		}
+	return;
+	}
+
+void CRYPTO_dbg_free(void *addr, int before_p)
+	{
+	MEM m,*mp;
+
+	switch(before_p)
+		{
+	case 0:
+		if (addr == NULL)
+			break;
+
+		if (is_MemCheck_on() && (mh != NULL))
+			{
+			MemCheck_off(); /* make sure we hold MALLOC2 lock */
+
+			m.addr=addr;
+			mp=lh_MEM_delete(mh,&m);
+			if (mp != NULL)
+				{
+#ifdef LEVITTE_DEBUG_MEM
+			fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n",
+				mp->order, mp->addr, mp->num);
+#endif
+				if (mp->app_info != NULL)
+					app_info_free(mp->app_info);
+				OPENSSL_free(mp);
+				}
+
+			MemCheck_on(); /* release MALLOC2 lock
+			                * if num_disabled drops to 0 */
+			}
+		break;
+	case 1:
+		break;
+		}
+	}
+
+void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
+	const char *file, int line, int before_p)
+	{
+	MEM m,*mp;
+
+#ifdef LEVITTE_DEBUG_MEM
+	fprintf(stderr, "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n",
+		addr1, addr2, num, file, line, before_p);
+#endif
+
+	switch(before_p)
+		{
+	case 0:
+		break;
+	case 1:
+		if (addr2 == NULL)
+			break;
+
+		if (addr1 == NULL)
+			{
+			CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p);
+			break;
+			}
+
+		if (is_MemCheck_on())
+			{
+			MemCheck_off(); /* make sure we hold MALLOC2 lock */
+
+			m.addr=addr1;
+			mp=lh_MEM_delete(mh,&m);
+			if (mp != NULL)
+				{
+#ifdef LEVITTE_DEBUG_MEM
+				fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] * 0x%p (%d) -> 0x%p (%d)\n",
+					mp->order,
+					mp->addr, mp->num,
+					addr2, num);
+#endif
+				mp->addr=addr2;
+				mp->num=num;
+				(void)lh_MEM_insert(mh,mp);
+				}
+
+			MemCheck_on(); /* release MALLOC2 lock
+			                * if num_disabled drops to 0 */
+			}
+		break;
+		}
+	return;
+	}
+
+
+typedef struct mem_leak_st
+	{
+	BIO *bio;
+	int chunks;
+	long bytes;
+	} MEM_LEAK;
+
+static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
+	{
+	char buf[1024];
+	char *bufp = buf;
+	APP_INFO *amip;
+	int ami_cnt;
+	struct tm *lcl = NULL;
+	CRYPTO_THREADID ti;
+
+#define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
+
+	if(m->addr == (char *)l->bio)
+	    return;
+
+	if (options & V_CRYPTO_MDEBUG_TIME)
+		{
+		lcl = localtime(&m->time);
+	
+		BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
+			lcl->tm_hour,lcl->tm_min,lcl->tm_sec);
+		bufp += strlen(bufp);
+		}
+
+	BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
+		m->order,m->file,m->line);
+	bufp += strlen(bufp);
+
+	if (options & V_CRYPTO_MDEBUG_THREAD)
+		{
+		BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ",
+			CRYPTO_THREADID_hash(&m->threadid));
+		bufp += strlen(bufp);
+		}
+
+	BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%08lX\n",
+		m->num,(unsigned long)m->addr);
+	bufp += strlen(bufp);
+
+	BIO_puts(l->bio,buf);
+	
+	l->chunks++;
+	l->bytes+=m->num;
+
+	amip=m->app_info;
+	ami_cnt=0;
+	if (!amip)
+		return;
+	CRYPTO_THREADID_cpy(&ti, &amip->threadid);
+
+	do
+		{
+		int buf_len;
+		int info_len;
+
+		ami_cnt++;
+		memset(buf,'>',ami_cnt);
+		BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
+			" thread=%lu, file=%s, line=%d, info=\"",
+			CRYPTO_THREADID_hash(&amip->threadid), amip->file,
+			amip->line);
+		buf_len=strlen(buf);
+		info_len=strlen(amip->info);
+		if (128 - buf_len - 3 < info_len)
+			{
+			memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
+			buf_len = 128 - 3;
+			}
+		else
+			{
+			BUF_strlcpy(buf + buf_len, amip->info,
+				    sizeof buf - buf_len);
+			buf_len = strlen(buf);
+			}
+		BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
+		
+		BIO_puts(l->bio,buf);
+
+		amip = amip->next;
+		}
+	while(amip && !CRYPTO_THREADID_cmp(&amip->threadid, &ti));
+
+#ifdef LEVITTE_DEBUG_MEM
+	if (amip)
+		{
+		fprintf(stderr, "Thread switch detected in backtrace!!!!\n");
+		abort();
+		}
+#endif
+	}
+
+static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM, MEM_LEAK)
+
+void CRYPTO_mem_leaks(BIO *b)
+	{
+	MEM_LEAK ml;
+
+	if (mh == NULL && amih == NULL)
+		return;
+
+	MemCheck_off(); /* obtain MALLOC2 lock */
+
+	ml.bio=b;
+	ml.bytes=0;
+	ml.chunks=0;
+	if (mh != NULL)
+		lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak), MEM_LEAK,
+				 &ml);
+	if (ml.chunks != 0)
+		{
+		BIO_printf(b,"%ld bytes leaked in %d chunks\n",
+			   ml.bytes,ml.chunks);
+#ifdef CRYPTO_MDEBUG_ABORT
+		abort();
+#endif
+		}
+	else
+		{
+		/* Make sure that, if we found no leaks, memory-leak debugging itself
+		 * does not introduce memory leaks (which might irritate
+		 * external debugging tools).
+		 * (When someone enables leak checking, but does not call
+		 * this function, we declare it to be their fault.)
+		 *
+		 * XXX    This should be in CRYPTO_mem_leaks_cb,
+		 * and CRYPTO_mem_leaks should be implemented by
+		 * using CRYPTO_mem_leaks_cb.
+		 * (Also there should be a variant of lh_doall_arg
+		 * that takes a function pointer instead of a void *;
+		 * this would obviate the ugly and illegal
+		 * void_fn_to_char kludge in CRYPTO_mem_leaks_cb.
+		 * Otherwise the code police will come and get us.)
+		 */
+		int old_mh_mode;
+
+		CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
+
+		/* avoid deadlock when lh_free() uses CRYPTO_dbg_free(),
+		 * which uses CRYPTO_is_mem_check_on */
+		old_mh_mode = mh_mode;
+		mh_mode = CRYPTO_MEM_CHECK_OFF;
+
+		if (mh != NULL)
+			{
+			lh_MEM_free(mh);
+			mh = NULL;
+			}
+		if (amih != NULL)
+			{
+			if (lh_APP_INFO_num_items(amih) == 0) 
+				{
+				lh_APP_INFO_free(amih);
+				amih = NULL;
+				}
+			}
+
+		mh_mode = old_mh_mode;
+		CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
+		}
+	MemCheck_on(); /* release MALLOC2 lock */
+	}
+
+#ifndef OPENSSL_NO_FP_API
+void CRYPTO_mem_leaks_fp(FILE *fp)
+	{
+	BIO *b;
+
+	if (mh == NULL) return;
+	/* Need to turn off memory checking when allocated BIOs ... especially
+	 * as we're creating them at a time when we're trying to check we've not
+	 * left anything un-free()'d!! */
+	MemCheck_off();
+	b = BIO_new(BIO_s_file());
+	MemCheck_on();
+	if(!b) return;
+	BIO_set_fp(b,fp,BIO_NOCLOSE);
+	CRYPTO_mem_leaks(b);
+	BIO_free(b);
+	}
+#endif
+
+
+
+/* FIXME: We really don't allow much to the callback.  For example, it has
+   no chance of reaching the info stack for the item it processes.  Should
+   it really be this way?  -- Richard Levitte */
+/* NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside crypto.h
+ * If this code is restructured, remove the callback type if it is no longer
+ * needed. -- Geoff Thorpe */
+
+/* Can't pass CRYPTO_MEM_LEAK_CB directly to lh_MEM_doall_arg because it
+ * is a function pointer and conversion to void * is prohibited. Instead
+ * pass its address
+ */
+
+typedef CRYPTO_MEM_LEAK_CB *PCRYPTO_MEM_LEAK_CB;
+
+static void cb_leak_doall_arg(const MEM *m, PCRYPTO_MEM_LEAK_CB *cb)
+	{
+	(*cb)(m->order,m->file,m->line,m->num,m->addr);
+	}
+
+static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM, PCRYPTO_MEM_LEAK_CB)
+
+void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb)
+	{
+	if (mh == NULL) return;
+	CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
+	lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), PCRYPTO_MEM_LEAK_CB,
+			 &cb);
+	CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
+	}
diff --git a/openssl/crypto/modes/Makefile b/openssl/crypto/modes/Makefile
new file mode 100644
index 0000000..6c85861
--- /dev/null
+++ b/openssl/crypto/modes/Makefile
@@ -0,0 +1,82 @@
+#
+# OpenSSL/crypto/modes/Makefile
+#
+
+DIR=	modes
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= cbc128.c ctr128.c cts128.c cfb128.c ofb128.c
+LIBOBJ= cbc128.o ctr128.o cts128.o cfb128.o ofb128.o
+
+SRC= $(LIBSRC)
+
+#EXHEADER= store.h str_compat.h
+EXHEADER= modes.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+cbc128.o: cbc128.c modes.h
+cfb128.o: cfb128.c modes.h
+ctr128.o: ctr128.c modes.h
+cts128.o: cts128.c modes.h
+ofb128.o: modes.h ofb128.c
diff --git a/openssl/crypto/modes/cbc128.c b/openssl/crypto/modes/cbc128.c
new file mode 100644
index 0000000..8f8bd56
--- /dev/null
+++ b/openssl/crypto/modes/cbc128.c
@@ -0,0 +1,206 @@
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include "modes.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+#define STRICT_ALIGNMENT 1
+#if defined(__i386) || defined(__i386__) || \
+    defined(__x86_64) || defined(__x86_64__) || \
+    defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
+    defined(__s390__) || defined(__s390x__)
+#  undef STRICT_ALIGNMENT
+#  define STRICT_ALIGNMENT 0
+#endif
+
+void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], block128_f block)
+{
+	size_t n;
+	const unsigned char *iv = ivec;
+
+	assert(in && out && key && ivec);
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (STRICT_ALIGNMENT &&
+	    ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
+		while (len>=16) {
+			for(n=0; n<16; ++n)
+				out[n] = in[n] ^ iv[n];
+			(*block)(out, out, key);
+			iv = out;
+			len -= 16;
+			in  += 16;
+			out += 16;
+		}
+	} else {
+		while (len>=16) {
+			for(n=0; n<16; n+=sizeof(size_t))
+				*(size_t*)(out+n) =
+				*(size_t*)(in+n) ^ *(size_t*)(iv+n);
+			(*block)(out, out, key);
+			iv = out;
+			len -= 16;
+			in  += 16;
+			out += 16;
+		}
+	}
+#endif
+	while (len) {
+		for(n=0; n<16 && n<len; ++n)
+			out[n] = in[n] ^ iv[n];
+		for(; n<16; ++n)
+			out[n] = iv[n];
+		(*block)(out, out, key);
+		iv = out;
+		if (len<=16) break;
+		len -= 16;
+		in  += 16;
+		out += 16;
+	}
+	memcpy(ivec,iv,16);
+}
+
+void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], block128_f block)
+{
+	size_t n;
+	union { size_t align; unsigned char c[16]; } tmp;
+
+	assert(in && out && key && ivec);
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (in != out) {
+		const unsigned char *iv = ivec;
+
+		if (STRICT_ALIGNMENT &&
+		    ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
+			while (len>=16) {
+				(*block)(in, out, key);
+				for(n=0; n<16; ++n)
+					out[n] ^= iv[n];
+				iv = in;
+				len -= 16;
+				in  += 16;
+				out += 16;
+			}
+		}
+		else {
+			while (len>=16) {
+				(*block)(in, out, key);
+				for(n=0; n<16; n+=sizeof(size_t))
+					*(size_t *)(out+n) ^= *(size_t *)(iv+n);
+				iv = in;
+				len -= 16;
+				in  += 16;
+				out += 16;
+			}
+		}
+		memcpy(ivec,iv,16);
+	} else {
+		if (STRICT_ALIGNMENT &&
+		    ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
+			unsigned char c;
+			while (len>=16) {
+				(*block)(in, tmp.c, key);
+				for(n=0; n<16; ++n) {
+					c = in[n];
+					out[n] = tmp.c[n] ^ ivec[n];
+					ivec[n] = c;
+				}
+				len -= 16;
+				in  += 16;
+				out += 16;
+			}
+		}
+		else {
+			size_t c;
+			while (len>=16) {
+				(*block)(in, tmp.c, key);
+				for(n=0; n<16; n+=sizeof(size_t)) {
+					c = *(size_t *)(in+n);
+					*(size_t *)(out+n) =
+					*(size_t *)(tmp.c+n) ^ *(size_t *)(ivec+n);
+					*(size_t *)(ivec+n) = c;
+				}
+				len -= 16;
+				in  += 16;
+				out += 16;
+			}
+		}
+	}
+#endif
+	while (len) {
+		unsigned char c;
+		(*block)(in, tmp.c, key);
+		for(n=0; n<16 && n<len; ++n) {
+			c = in[n];
+			out[n] = tmp.c[n] ^ ivec[n];
+			ivec[n] = c;
+		}
+		if (len<=16) {
+			for (; n<16; ++n)
+				ivec[n] = in[n];
+			break;
+		}
+		len -= 16;
+		in  += 16;
+		out += 16;
+	}
+}
diff --git a/openssl/crypto/modes/cfb128.c b/openssl/crypto/modes/cfb128.c
new file mode 100644
index 0000000..e5938c6
--- /dev/null
+++ b/openssl/crypto/modes/cfb128.c
@@ -0,0 +1,249 @@
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include "modes.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+#define STRICT_ALIGNMENT
+#if defined(__i386) || defined(__i386__) || \
+    defined(__x86_64) || defined(__x86_64__) || \
+    defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
+    defined(__s390__) || defined(__s390x__)
+#  undef STRICT_ALIGNMENT
+#endif
+
+/* The input and output encrypted as though 128bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 128bit block we have used is contained in *num;
+ */
+void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], int *num,
+			int enc, block128_f block)
+{
+    unsigned int n;
+    size_t l = 0;
+
+    assert(in && out && key && ivec && num);
+
+    n = *num;
+
+    if (enc) {
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (16%sizeof(size_t) == 0) do {	/* always true actually */
+		while (n && len) {
+			*(out++) = ivec[n] ^= *(in++);
+			--len;
+			n = (n+1) % 16;
+		}
+#if defined(STRICT_ALIGNMENT)
+		if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
+			break;
+#endif
+		while (len>=16) {
+			(*block)(ivec, ivec, key);
+			for (; n<16; n+=sizeof(size_t)) {
+				*(size_t*)(out+n) =
+				*(size_t*)(ivec+n) ^= *(size_t*)(in+n);
+			}
+			len -= 16;
+			out += 16;
+			in  += 16;
+			n = 0;
+		}
+		if (len) {
+			(*block)(ivec, ivec, key);
+			while (len--) {
+				out[n] = ivec[n] ^= in[n];
+				++n;
+			}
+		}
+		*num = n;
+		return;
+	} while (0);
+	/* the rest would be commonly eliminated by x86* compiler */
+#endif
+	while (l<len) {
+		if (n == 0) {
+			(*block)(ivec, ivec, key);
+		}
+		out[l] = ivec[n] ^= in[l];
+		++l;
+		n = (n+1) % 16;
+	}
+	*num = n;
+    } else {
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (16%sizeof(size_t) == 0) do {	/* always true actually */
+		while (n && len) {
+			unsigned char c;
+			*(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c;
+			--len;
+			n = (n+1) % 16;
+ 		}
+#if defined(STRICT_ALIGNMENT)
+		if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
+			break;
+#endif
+		while (len>=16) {
+			(*block)(ivec, ivec, key);
+			for (; n<16; n+=sizeof(size_t)) {
+				size_t t = *(size_t*)(in+n);
+				*(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t;
+				*(size_t*)(ivec+n) = t;
+			}
+			len -= 16;
+			out += 16;
+			in  += 16;
+			n = 0;
+		}
+		if (len) {
+			(*block)(ivec, ivec, key);
+			while (len--) {
+				unsigned char c;
+				out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c;
+				++n;
+			}
+ 		}
+		*num = n;
+		return;
+	} while (0);
+	/* the rest would be commonly eliminated by x86* compiler */
+#endif
+	while (l<len) {
+		unsigned char c;
+		if (n == 0) {
+			(*block)(ivec, ivec, key);
+		}
+		out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c;
+		++l;
+		n = (n+1) % 16;
+	}
+	*num=n;
+    }
+}
+
+/* This expects a single block of size nbits for both in and out. Note that
+   it corrupts any extra bits in the last byte of out */
+static void cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
+			    int nbits,const void *key,
+			    unsigned char ivec[16],int enc,
+			    block128_f block)
+{
+    int n,rem,num;
+    unsigned char ovec[16*2 + 1];  /* +1 because we dererefence (but don't use) one byte off the end */
+
+    if (nbits<=0 || nbits>128) return;
+
+	/* fill in the first half of the new IV with the current IV */
+	memcpy(ovec,ivec,16);
+	/* construct the new IV */
+	(*block)(ivec,ivec,key);
+	num = (nbits+7)/8;
+	if (enc)	/* encrypt the input */
+	    for(n=0 ; n < num ; ++n)
+		out[n] = (ovec[16+n] = in[n] ^ ivec[n]);
+	else		/* decrypt the input */
+	    for(n=0 ; n < num ; ++n)
+		out[n] = (ovec[16+n] = in[n]) ^ ivec[n];
+	/* shift ovec left... */
+	rem = nbits%8;
+	num = nbits/8;
+	if(rem==0)
+	    memcpy(ivec,ovec+num,16);
+	else
+	    for(n=0 ; n < 16 ; ++n)
+		ivec[n] = ovec[n+num]<<rem | ovec[n+num+1]>>(8-rem);
+
+    /* it is not necessary to cleanse ovec, since the IV is not secret */
+}
+
+/* N.B. This expects the input to be packed, MS bit first */
+void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
+		 	size_t bits, const void *key,
+			unsigned char ivec[16], int *num,
+			int enc, block128_f block)
+{
+    size_t n;
+    unsigned char c[1],d[1];
+
+    assert(in && out && key && ivec && num);
+    assert(*num == 0);
+
+    for(n=0 ; n<bits ; ++n)
+	{
+	c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
+	cfbr_encrypt_block(c,d,1,key,ivec,enc,block);
+	out[n/8]=(out[n/8]&~(1 << (unsigned int)(7-n%8))) |
+		 ((d[0]&0x80) >> (unsigned int)(n%8));
+	}
+}
+
+void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
+			size_t length, const void *key,
+			unsigned char ivec[16], int *num,
+			int enc, block128_f block)
+{
+    size_t n;
+
+    assert(in && out && key && ivec && num);
+    assert(*num == 0);
+
+    for(n=0 ; n<length ; ++n)
+	cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc,block);
+}
+
diff --git a/openssl/crypto/modes/ctr128.c b/openssl/crypto/modes/ctr128.c
new file mode 100644
index 0000000..932037f
--- /dev/null
+++ b/openssl/crypto/modes/ctr128.c
@@ -0,0 +1,184 @@
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include "modes.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+typedef unsigned int u32;
+typedef unsigned char u8;
+
+#define STRICT_ALIGNMENT
+#if defined(__i386)	|| defined(__i386__)	|| \
+    defined(__x86_64)	|| defined(__x86_64__)	|| \
+    defined(_M_IX86)	|| defined(_M_AMD64)	|| defined(_M_X64) || \
+    defined(__s390__)	|| defined(__s390x__)
+#  undef STRICT_ALIGNMENT
+#endif
+
+/* NOTE: the IV/counter CTR mode is big-endian.  The code itself
+ * is endian-neutral. */
+
+/* increment counter (128-bit int) by 1 */
+static void ctr128_inc(unsigned char *counter) {
+	u32 n=16;
+	u8  c;
+
+	do {
+		--n;
+		c = counter[n];
+		++c;
+		counter[n] = c;
+		if (c) return;
+	} while (n);
+}
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+static void ctr128_inc_aligned(unsigned char *counter) {
+	size_t *data,c,n;
+	const union { long one; char little; } is_endian = {1};
+
+	if (is_endian.little) {
+		ctr128_inc(counter);
+		return;
+	}
+
+	data = (size_t *)counter;
+	n = 16/sizeof(size_t);
+	do {
+		--n;
+		c = data[n];
+		++c;
+		data[n] = c;
+		if (c) return;
+	} while (n);
+}
+#endif
+
+/* The input encrypted as though 128bit counter mode is being
+ * used.  The extra state information to record how much of the
+ * 128bit block we have used is contained in *num, and the
+ * encrypted counter is kept in ecount_buf.  Both *num and
+ * ecount_buf must be initialised with zeros before the first
+ * call to CRYPTO_ctr128_encrypt().
+ *
+ * This algorithm assumes that the counter is in the x lower bits
+ * of the IV (ivec), and that the application has full control over
+ * overflow and the rest of the IV.  This implementation takes NO
+ * responsability for checking that the counter doesn't overflow
+ * into the rest of the IV when incremented.
+ */
+void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], unsigned char ecount_buf[16],
+			unsigned int *num, block128_f block)
+{
+	unsigned int n;
+	size_t l=0;
+
+	assert(in && out && key && ecount_buf && num);
+	assert(*num < 16);
+
+	n = *num;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (16%sizeof(size_t) == 0) do { /* always true actually */
+		while (n && len) {
+			*(out++) = *(in++) ^ ecount_buf[n];
+			--len;
+			n = (n+1) % 16;
+		}
+
+#if defined(STRICT_ALIGNMENT)
+		if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
+			break;
+#endif
+		while (len>=16) {
+			(*block)(ivec, ecount_buf, key);
+			ctr128_inc_aligned(ivec);
+			for (; n<16; n+=sizeof(size_t))
+				*(size_t *)(out+n) =
+				*(size_t *)(in+n) ^ *(size_t *)(ecount_buf+n);
+			len -= 16;
+			out += 16;
+			in  += 16;
+			n = 0;
+		}
+		if (len) {
+			(*block)(ivec, ecount_buf, key);
+ 			ctr128_inc_aligned(ivec);
+			while (len--) {
+				out[n] = in[n] ^ ecount_buf[n];
+				++n;
+			}
+		}
+		*num = n;
+		return;
+	} while(0);
+	/* the rest would be commonly eliminated by x86* compiler */
+#endif
+	while (l<len) {
+		if (n==0) {
+			(*block)(ivec, ecount_buf, key);
+ 			ctr128_inc(ivec);
+		}
+		out[l] = in[l] ^ ecount_buf[n];
+		++l;
+		n = (n+1) % 16;
+	}
+
+	*num=n;
+}
diff --git a/openssl/crypto/modes/cts128.c b/openssl/crypto/modes/cts128.c
new file mode 100644
index 0000000..e0430f9
--- /dev/null
+++ b/openssl/crypto/modes/cts128.c
@@ -0,0 +1,259 @@
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
+ *
+ * Rights for redistribution and usage in source and binary
+ * forms are granted according to the OpenSSL license.
+ */
+
+#include "modes.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+/*
+ * Trouble with Ciphertext Stealing, CTS, mode is that there is no
+ * common official specification, but couple of cipher/application
+ * specific ones: RFC2040 and RFC3962. Then there is 'Proposal to
+ * Extend CBC Mode By "Ciphertext Stealing"' at NIST site, which
+ * deviates from mentioned RFCs. Most notably it allows input to be
+ * of block length and it doesn't flip the order of the last two
+ * blocks. CTS is being discussed even in ECB context, but it's not
+ * adopted for any known application. This implementation complies
+ * with mentioned RFCs and [as such] extends CBC mode.
+ */
+
+size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], block128_f block)
+{	size_t residue, n;
+
+	assert (in && out && key && ivec);
+
+	if (len <= 16) return 0;
+
+	if ((residue=len%16) == 0) residue = 16;
+
+	len -= residue;
+
+	CRYPTO_cbc128_encrypt(in,out,len,key,ivec,block);
+
+	in  += len;
+	out += len;
+
+	for (n=0; n<residue; ++n)
+		ivec[n] ^= in[n];
+	(*block)(ivec,ivec,key);
+	memcpy(out,out-16,residue);
+	memcpy(out-16,ivec,16); 
+
+	return len+residue;
+}
+
+size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], cbc128_f cbc)
+{	size_t residue;
+	union { size_t align; unsigned char c[16]; } tmp;
+
+	assert (in && out && key && ivec);
+
+	if (len <= 16) return 0;
+
+	if ((residue=len%16) == 0) residue = 16;
+
+	len -= residue;
+
+	(*cbc)(in,out,len,key,ivec,1);
+
+	in  += len;
+	out += len;
+
+#if defined(CBC_HANDLES_TRUNCATED_IO)
+	memcpy(tmp.c,out-16,16);
+	(*cbc)(in,out-16,residue,key,ivec,1);
+	memcpy(out,tmp.c,residue);
+#else
+	{
+	size_t n;
+	for (n=0; n<16; n+=sizeof(size_t))
+		*(size_t *)(tmp.c+n) = 0;
+	memcpy(tmp.c,in,residue);
+	}
+	memcpy(out,out-16,residue);
+	(*cbc)(tmp.c,out-16,16,key,ivec,1);
+#endif
+	return len+residue;
+}
+
+size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], block128_f block)
+{	size_t residue, n;
+	union { size_t align; unsigned char c[32]; } tmp;
+
+	assert (in && out && key && ivec);
+
+	if (len<=16) return 0;
+
+	if ((residue=len%16) == 0) residue = 16;
+
+	len -= 16+residue;
+
+	if (len) {
+		CRYPTO_cbc128_decrypt(in,out,len,key,ivec,block);
+		in  += len;
+		out += len;
+	}
+
+	(*block)(in,tmp.c+16,key);
+
+	for (n=0; n<16; n+=sizeof(size_t))
+		*(size_t *)(tmp.c+n) = *(size_t *)(tmp.c+16+n);
+	memcpy(tmp.c,in+16,residue);
+	(*block)(tmp.c,tmp.c,key);
+
+	for(n=0; n<16; ++n) {
+		unsigned char c = in[n];
+		out[n] = tmp.c[n] ^ ivec[n];
+		ivec[n] = c;
+	}
+	for(residue+=16; n<residue; ++n)
+		out[n] = tmp.c[n] ^ in[n];
+
+	return len+residue-16;
+}
+
+size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], cbc128_f cbc)
+{	size_t residue, n;
+	union { size_t align; unsigned char c[32]; } tmp;
+
+	assert (in && out && key && ivec);
+
+	if (len<=16) return 0;
+
+	if ((residue=len%16) == 0) residue = 16;
+
+	len -= 16+residue;
+
+	if (len) {
+		(*cbc)(in,out,len,key,ivec,0);
+		in  += len;
+		out += len;
+	}
+
+	for (n=16; n<32; n+=sizeof(size_t))
+		*(size_t *)(tmp.c+n) = 0;
+	/* this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0] */
+	(*cbc)(in,tmp.c,16,key,tmp.c+16,0);
+
+	memcpy(tmp.c,in+16,residue);
+#if defined(CBC_HANDLES_TRUNCATED_IO)
+	(*cbc)(tmp.c,out,16+residue,key,ivec,0);
+#else
+	(*cbc)(tmp.c,tmp.c,32,key,ivec,0);
+	memcpy(out,tmp.c,16+residue);
+#endif
+	return len+residue;
+}
+
+#if defined(SELFTEST)
+#include <stdio.h>
+#include <openssl/aes.h>
+
+/* test vectors from RFC 3962 */
+static const unsigned char test_key[16] = "chicken teriyaki";
+static const unsigned char test_input[64] =
+		"I would like the" " General Gau's C"
+		"hicken, please, " "and wonton soup.";
+static const unsigned char test_iv[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+static const unsigned char vector_17[17] =
+{0xc6,0x35,0x35,0x68,0xf2,0xbf,0x8c,0xb4, 0xd8,0xa5,0x80,0x36,0x2d,0xa7,0xff,0x7f,
+ 0x97};
+static const unsigned char vector_31[31] =
+{0xfc,0x00,0x78,0x3e,0x0e,0xfd,0xb2,0xc1, 0xd4,0x45,0xd4,0xc8,0xef,0xf7,0xed,0x22,
+ 0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5};
+static const unsigned char vector_32[32] =
+{0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8,
+ 0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84};
+static const unsigned char vector_47[47] =
+{0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84,
+ 0xb3,0xff,0xfd,0x94,0x0c,0x16,0xa1,0x8c, 0x1b,0x55,0x49,0xd2,0xf8,0x38,0x02,0x9e,
+ 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5};
+static const unsigned char vector_48[48] =
+{0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84,
+ 0x9d,0xad,0x8b,0xbb,0x96,0xc4,0xcd,0xc0, 0x3b,0xc1,0x03,0xe1,0xa1,0x94,0xbb,0xd8,
+ 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8};
+static const unsigned char vector_64[64] =
+{0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84,
+ 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8,
+ 0x48,0x07,0xef,0xe8,0x36,0xee,0x89,0xa5, 0x26,0x73,0x0d,0xbc,0x2f,0x7b,0xc8,0x40,
+ 0x9d,0xad,0x8b,0xbb,0x96,0xc4,0xcd,0xc0, 0x3b,0xc1,0x03,0xe1,0xa1,0x94,0xbb,0xd8};
+
+static AES_KEY encks, decks;
+
+void test_vector(const unsigned char *vector,size_t len)
+{	unsigned char cleartext[64];
+	unsigned char iv[sizeof(test_iv)];
+	unsigned char ciphertext[64];
+	size_t tail;
+
+	printf("vector_%d\n",len); fflush(stdout);
+
+	if ((tail=len%16) == 0) tail = 16;
+	tail += 16;
+
+	/* test block-based encryption */
+	memcpy(iv,test_iv,sizeof(test_iv));
+	CRYPTO_cts128_encrypt_block(test_input,ciphertext,len,&encks,iv,(block128_f)AES_encrypt);
+	if (memcmp(ciphertext,vector,len))
+		fprintf(stderr,"output_%d mismatch\n",len), exit(1);
+	if (memcmp(iv,vector+len-tail,sizeof(iv)))
+		fprintf(stderr,"iv_%d mismatch\n",len), exit(1);
+
+	/* test block-based decryption */
+	memcpy(iv,test_iv,sizeof(test_iv));
+	CRYPTO_cts128_decrypt_block(ciphertext,cleartext,len,&decks,iv,(block128_f)AES_decrypt);
+	if (memcmp(cleartext,test_input,len))
+		fprintf(stderr,"input_%d mismatch\n",len), exit(2);
+	if (memcmp(iv,vector+len-tail,sizeof(iv)))
+		fprintf(stderr,"iv_%d mismatch\n",len), exit(2);
+
+	/* test streamed encryption */
+	memcpy(iv,test_iv,sizeof(test_iv));
+	CRYPTO_cts128_encrypt(test_input,ciphertext,len,&encks,iv,(cbc128_f)AES_cbc_encrypt);
+	if (memcmp(ciphertext,vector,len))
+		fprintf(stderr,"output_%d mismatch\n",len), exit(3);
+	if (memcmp(iv,vector+len-tail,sizeof(iv)))
+		fprintf(stderr,"iv_%d mismatch\n",len), exit(3);
+
+	/* test streamed decryption */
+	memcpy(iv,test_iv,sizeof(test_iv));
+	CRYPTO_cts128_decrypt(ciphertext,cleartext,len,&decks,iv,(cbc128_f)AES_cbc_encrypt);
+	if (memcmp(cleartext,test_input,len))
+		fprintf(stderr,"input_%d mismatch\n",len), exit(4);
+	if (memcmp(iv,vector+len-tail,sizeof(iv)))
+		fprintf(stderr,"iv_%d mismatch\n",len), exit(4);
+}
+
+main()
+{
+	AES_set_encrypt_key(test_key,128,&encks);
+	AES_set_decrypt_key(test_key,128,&decks);
+
+	test_vector(vector_17,sizeof(vector_17));
+	test_vector(vector_31,sizeof(vector_31));
+	test_vector(vector_32,sizeof(vector_32));
+	test_vector(vector_47,sizeof(vector_47));
+	test_vector(vector_48,sizeof(vector_48));
+	test_vector(vector_64,sizeof(vector_64));
+	exit(0);
+}
+#endif
diff --git a/openssl/crypto/modes/modes.h b/openssl/crypto/modes/modes.h
new file mode 100644
index 0000000..af8d97d
--- /dev/null
+++ b/openssl/crypto/modes/modes.h
@@ -0,0 +1,59 @@
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
+ *
+ * Rights for redistribution and usage in source and binary
+ * forms are granted according to the OpenSSL license.
+ */
+
+#include <stddef.h>
+
+typedef void (*block128_f)(const unsigned char in[16],
+			unsigned char out[16],
+			const void *key);
+
+typedef void (*cbc128_f)(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], int enc);
+
+void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], block128_f block);
+void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], block128_f block);
+
+void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], unsigned char ecount_buf[16],
+			unsigned int *num, block128_f block);
+
+void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], int *num,
+			block128_f block);
+
+void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], int *num,
+			int enc, block128_f block);
+void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
+			size_t length, const void *key,
+			unsigned char ivec[16], int *num,
+			int enc, block128_f block);
+void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
+			size_t bits, const void *key,
+			unsigned char ivec[16], int *num,
+			int enc, block128_f block);
+
+size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], block128_f block);
+size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], cbc128_f cbc);
+size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], block128_f block);
+size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], cbc128_f cbc);
diff --git a/openssl/crypto/modes/ofb128.c b/openssl/crypto/modes/ofb128.c
new file mode 100644
index 0000000..c732e2e
--- /dev/null
+++ b/openssl/crypto/modes/ofb128.c
@@ -0,0 +1,128 @@
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include "modes.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+#define STRICT_ALIGNMENT
+#if defined(__i386) || defined(__i386__) || \
+    defined(__x86_64) || defined(__x86_64__) || \
+    defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
+    defined(__s390__) || defined(__s390x__)
+#  undef STRICT_ALIGNMENT
+#endif
+
+/* The input and output encrypted as though 128bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 128bit block we have used is contained in *num;
+ */
+void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], int *num,
+			block128_f block)
+{
+	unsigned int n;
+	size_t l=0;
+
+	assert(in && out && key && ivec && num);
+
+	n = *num;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (16%sizeof(size_t) == 0) do { /* always true actually */
+		while (n && len) {
+			*(out++) = *(in++) ^ ivec[n];
+			--len;
+			n = (n+1) % 16;
+		}
+#if defined(STRICT_ALIGNMENT)
+		if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
+			break;
+#endif
+		while (len>=16) {
+			(*block)(ivec, ivec, key);
+			for (; n<16; n+=sizeof(size_t))
+				*(size_t*)(out+n) =
+				*(size_t*)(in+n) ^ *(size_t*)(ivec+n);
+			len -= 16;
+			out += 16;
+			in  += 16;
+			n = 0;
+		}
+		if (len) {
+			(*block)(ivec, ivec, key);
+			while (len--) {
+				out[n] = in[n] ^ ivec[n];
+				++n;
+			}
+		}
+		*num = n;
+		return;
+	} while(0);
+	/* the rest would be commonly eliminated by x86* compiler */
+#endif
+	while (l<len) {
+		if (n==0) {
+			(*block)(ivec, ivec, key);
+		}
+		out[l] = in[l] ^ ivec[n];
+		++l;
+		n = (n+1) % 16;
+	}
+
+	*num=n;
+}
diff --git a/openssl/crypto/o_dir.c b/openssl/crypto/o_dir.c
new file mode 100644
index 0000000..42891ea
--- /dev/null
+++ b/openssl/crypto/o_dir.c
@@ -0,0 +1,83 @@
+/* crypto/o_dir.c -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <errno.h>
+#include <e_os.h>
+
+/* The routines really come from the Levitte Programming, so to make
+   life simple, let's just use the raw files and hack the symbols to
+   fit our namespace.  */
+#define LP_DIR_CTX OPENSSL_DIR_CTX
+#define LP_dir_context_st OPENSSL_dir_context_st
+#define LP_find_file OPENSSL_DIR_read
+#define LP_find_file_end OPENSSL_DIR_end
+
+#include "o_dir.h"
+
+#define LPDIR_H
+#if defined OPENSSL_SYS_UNIX || defined DJGPP
+#include "LPdir_unix.c"
+#elif defined OPENSSL_SYS_VMS
+#include "LPdir_vms.c"
+#elif defined OPENSSL_SYS_WIN32
+#include "LPdir_win32.c"
+#elif defined OPENSSL_SYS_WINCE
+#include "LPdir_wince.c"
+#else
+#include "LPdir_nyi.c"
+#endif
diff --git a/openssl/crypto/o_dir.h b/openssl/crypto/o_dir.h
new file mode 100644
index 0000000..4b725c0
--- /dev/null
+++ b/openssl/crypto/o_dir.h
@@ -0,0 +1,53 @@
+/* crypto/o_dir.h -*- mode:C; c-file-style: "eay" -*- */
+/* Copied from Richard Levitte's (richard@levitte.org) LP library.  All
+ * symbol names have been changed, with permission from the author.
+ */
+
+/* $LP: LPlib/source/LPdir.h,v 1.1 2004/06/14 08:56:04 _cvs_levitte Exp $ */
+/*
+ * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#ifndef O_DIR_H
+#define O_DIR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  typedef struct OPENSSL_dir_context_st OPENSSL_DIR_CTX;
+
+  /* returns NULL on error or end-of-directory.
+     If it is end-of-directory, errno will be zero */
+  const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory);
+  /* returns 1 on success, 0 on error */
+  int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LPDIR_H */
diff --git a/openssl/crypto/o_dir_test.c b/openssl/crypto/o_dir_test.c
new file mode 100644
index 0000000..3d75ecb
--- /dev/null
+++ b/openssl/crypto/o_dir_test.c
@@ -0,0 +1,70 @@
+/* crypto/o_dir.h -*- mode:C; c-file-style: "eay" -*- */
+/* Copied from Richard Levitte's (richard@levitte.org) LP library.  All
+ * symbol names have been changed, with permission from the author.
+ */
+
+/* $LP: LPlib/test/test_dir.c,v 1.1 2004/06/16 22:59:47 _cvs_levitte Exp $ */
+/*
+ * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include "e_os2.h"
+#include "o_dir.h"
+
+#if defined OPENSSL_SYS_UNIX || defined OPENSSL_SYS_WIN32 || defined OPENSSL_SYS_WINCE
+#define CURRDIR "."
+#elif defined OPENSSL_SYS_VMS
+#define CURRDIR "SYS$DISK:[]"
+#else
+#error "No supported platform defined!"
+#endif
+
+int main()
+{
+  OPENSSL_DIR_CTX *ctx = NULL;
+  const char *result;
+
+  while((result = OPENSSL_DIR_read(&ctx, CURRDIR)) != NULL)
+    {
+      printf("%s\n", result);
+    }
+
+  if (errno)
+    {
+      perror("test_dir");
+      exit(1);
+    }
+
+  if (!OPENSSL_DIR_end(&ctx))
+    {
+      perror("test_dir");
+      exit(2);
+    }
+  exit(0);
+}
diff --git a/openssl/crypto/o_str.c b/openssl/crypto/o_str.c
new file mode 100644
index 0000000..56104a6
--- /dev/null
+++ b/openssl/crypto/o_str.c
@@ -0,0 +1,111 @@
+/* crypto/o_str.c -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2003.
+ */
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <ctype.h>
+#include <e_os.h>
+#include "o_str.h"
+
+#if !defined(OPENSSL_IMPLEMENTS_strncasecmp) && \
+    !defined(OPENSSL_SYSNAME_WIN32) && \
+    !defined(NETWARE_CLIB)
+# include <strings.h>
+#endif
+
+int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n)
+	{
+#if defined(OPENSSL_IMPLEMENTS_strncasecmp)
+	while (*str1 && *str2 && n)
+		{
+		int res = toupper(*str1) - toupper(*str2);
+		if (res) return res < 0 ? -1 : 1;
+		str1++;
+		str2++;
+		n--;
+		}
+	if (n == 0)
+		return 0;
+	if (*str1)
+		return 1;
+	if (*str2)
+		return -1;
+	return 0;
+#else
+	/* Recursion hazard warning! Whenever strncasecmp is #defined as
+	 * OPENSSL_strncasecmp, OPENSSL_IMPLEMENTS_strncasecmp must be
+	 * defined as well. */
+	return strncasecmp(str1, str2, n);
+#endif
+	}
+int OPENSSL_strcasecmp(const char *str1, const char *str2)
+	{
+#if defined(OPENSSL_IMPLEMENTS_strncasecmp)
+	return OPENSSL_strncasecmp(str1, str2, (size_t)-1);
+#else
+	return strcasecmp(str1, str2);
+#endif
+	}
+
+int OPENSSL_memcmp(const void *v1,const void *v2,size_t n)
+	{
+	const unsigned char *c1=v1,*c2=v2;
+	int ret=0;
+
+	while(n && (ret=*c1-*c2)==0) n--,c1++,c2++;
+
+	return ret;
+	}
diff --git a/openssl/crypto/o_str.h b/openssl/crypto/o_str.h
new file mode 100644
index 0000000..dfc9849
--- /dev/null
+++ b/openssl/crypto/o_str.h
@@ -0,0 +1,68 @@
+/* crypto/o_str.h -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2003.
+ */
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_O_STR_H
+#define HEADER_O_STR_H
+
+#include <stddef.h>		/* to get size_t */
+
+int OPENSSL_strcasecmp(const char *str1, const char *str2);
+int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n);
+int OPENSSL_memcmp(const void *p1,const void *p2,size_t n);
+
+#endif
diff --git a/openssl/crypto/o_time.c b/openssl/crypto/o_time.c
new file mode 100644
index 0000000..9030fde
--- /dev/null
+++ b/openssl/crypto/o_time.c
@@ -0,0 +1,372 @@
+/* crypto/o_time.c -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2008.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/e_os2.h>
+#include <string.h>
+#include "o_time.h"
+
+#ifdef OPENSSL_SYS_VMS
+# if __CRTL_VER >= 70000000 && \
+     (defined _POSIX_C_SOURCE || !defined _ANSI_C_SOURCE)
+#  define VMS_GMTIME_OK
+# endif
+# ifndef VMS_GMTIME_OK
+#  include <libdtdef.h>
+#  include <lib$routines.h>
+#  include <lnmdef.h>
+#  include <starlet.h>
+#  include <descrip.h>
+#  include <stdlib.h>
+# endif /* ndef VMS_GMTIME_OK */
+#endif
+
+struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result)
+	{
+	struct tm *ts = NULL;
+
+#if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_OS2) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_MACOSX) && !defined(OPENSSL_SYS_SUNOS)
+	/* should return &data, but doesn't on some systems,
+	   so we don't even look at the return value */
+	gmtime_r(timer,result);
+	ts = result;
+#elif !defined(OPENSSL_SYS_VMS) || defined(VMS_GMTIME_OK)
+	ts = gmtime(timer);
+	if (ts == NULL)
+		return NULL;
+
+	memcpy(result, ts, sizeof(struct tm));
+	ts = result;
+#endif
+#if defined( OPENSSL_SYS_VMS) && !defined( VMS_GMTIME_OK)
+	if (ts == NULL)
+		{
+		static $DESCRIPTOR(tabnam,"LNM$DCL_LOGICAL");
+		static $DESCRIPTOR(lognam,"SYS$TIMEZONE_DIFFERENTIAL");
+		char logvalue[256];
+		unsigned int reslen = 0;
+		struct {
+			short buflen;
+			short code;
+			void *bufaddr;
+			unsigned int *reslen;
+		} itemlist[] = {
+			{ 0, LNM$_STRING, 0, 0 },
+			{ 0, 0, 0, 0 },
+		};
+		int status;
+		time_t t;
+
+		/* Get the value for SYS$TIMEZONE_DIFFERENTIAL */
+		itemlist[0].buflen = sizeof(logvalue);
+		itemlist[0].bufaddr = logvalue;
+		itemlist[0].reslen = &reslen;
+		status = sys$trnlnm(0, &tabnam, &lognam, 0, itemlist);
+		if (!(status & 1))
+			return NULL;
+		logvalue[reslen] = '\0';
+
+		t = *timer;
+
+/* The following is extracted from the DEC C header time.h */
+/*
+**  Beginning in OpenVMS Version 7.0 mktime, time, ctime, strftime
+**  have two implementations.  One implementation is provided
+**  for compatibility and deals with time in terms of local time,
+**  the other __utc_* deals with time in terms of UTC.
+*/
+/* We use the same conditions as in said time.h to check if we should
+   assume that t contains local time (and should therefore be adjusted)
+   or UTC (and should therefore be left untouched). */
+#if __CRTL_VER < 70000000 || defined _VMS_V6_SOURCE
+		/* Get the numerical value of the equivalence string */
+		status = atoi(logvalue);
+
+		/* and use it to move time to GMT */
+		t -= status;
+#endif
+
+		/* then convert the result to the time structure */
+
+		/* Since there was no gmtime_r() to do this stuff for us,
+		   we have to do it the hard way. */
+		{
+		/* The VMS epoch is the astronomical Smithsonian date,
+		   if I remember correctly, which is November 17, 1858.
+		   Furthermore, time is measure in thenths of microseconds
+		   and stored in quadwords (64 bit integers).  unix_epoch
+		   below is January 1st 1970 expressed as a VMS time.  The
+		   following code was used to get this number:
+
+		   #include <stdio.h>
+		   #include <stdlib.h>
+		   #include <lib$routines.h>
+		   #include <starlet.h>
+
+		   main()
+		   {
+		     unsigned long systime[2];
+		     unsigned short epoch_values[7] =
+		       { 1970, 1, 1, 0, 0, 0, 0 };
+
+		     lib$cvt_vectim(epoch_values, systime);
+
+		     printf("%u %u", systime[0], systime[1]);
+		   }
+		*/
+		unsigned long unix_epoch[2] = { 1273708544, 8164711 };
+		unsigned long deltatime[2];
+		unsigned long systime[2];
+		struct vms_vectime
+			{
+			short year, month, day, hour, minute, second,
+				centi_second;
+			} time_values;
+		long operation;
+
+		/* Turn the number of seconds since January 1st 1970 to
+		   an internal delta time.
+		   Note that lib$cvt_to_internal_time() will assume
+		   that t is signed, and will therefore break on 32-bit
+		   systems some time in 2038.
+		*/
+		operation = LIB$K_DELTA_SECONDS;
+		status = lib$cvt_to_internal_time(&operation,
+			&t, deltatime);
+
+		/* Add the delta time with the Unix epoch and we have
+		   the current UTC time in internal format */
+		status = lib$add_times(unix_epoch, deltatime, systime);
+
+		/* Turn the internal time into a time vector */
+		status = sys$numtim(&time_values, systime);
+
+		/* Fill in the struct tm with the result */
+		result->tm_sec = time_values.second;
+		result->tm_min = time_values.minute;
+		result->tm_hour = time_values.hour;
+		result->tm_mday = time_values.day;
+		result->tm_mon = time_values.month - 1;
+		result->tm_year = time_values.year - 1900;
+
+		operation = LIB$K_DAY_OF_WEEK;
+		status = lib$cvt_from_internal_time(&operation,
+			&result->tm_wday, systime);
+		result->tm_wday %= 7;
+
+		operation = LIB$K_DAY_OF_YEAR;
+		status = lib$cvt_from_internal_time(&operation,
+			&result->tm_yday, systime);
+		result->tm_yday--;
+
+		result->tm_isdst = 0; /* There's no way to know... */
+
+		ts = result;
+		}
+		}
+#endif
+	return ts;
+	}
+
+/* Take a tm structure and add an offset to it. This avoids any OS issues
+ * with restricted date types and overflows which cause the year 2038
+ * problem.
+ */
+
+#define SECS_PER_DAY (24 * 60 * 60)
+
+static long date_to_julian(int y, int m, int d);
+static void julian_to_date(long jd, int *y, int *m, int *d);
+
+int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec)
+	{
+	int offset_hms, offset_day;
+	long time_jd;
+	int time_year, time_month, time_day;
+	/* split offset into days and day seconds */
+	offset_day = offset_sec / SECS_PER_DAY;
+	/* Avoid sign issues with % operator */
+	offset_hms  = offset_sec - (offset_day * SECS_PER_DAY);
+	offset_day += off_day;
+	/* Add current time seconds to offset */
+	offset_hms += tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec;
+	/* Adjust day seconds if overflow */
+	if (offset_hms >= SECS_PER_DAY)
+		{
+		offset_day++;
+		offset_hms -= SECS_PER_DAY;
+		}
+	else if (offset_hms < 0)
+		{
+		offset_day--;
+		offset_hms += SECS_PER_DAY;
+		}
+
+	/* Convert date of time structure into a Julian day number.
+	 */
+
+	time_year = tm->tm_year + 1900;
+	time_month = tm->tm_mon + 1;
+	time_day = tm->tm_mday;
+
+	time_jd = date_to_julian(time_year, time_month, time_day);
+
+	/* Work out Julian day of new date */
+	time_jd += offset_day;
+
+	if (time_jd < 0)
+		return 0;
+
+	/* Convert Julian day back to date */
+
+	julian_to_date(time_jd, &time_year, &time_month, &time_day);
+
+	if (time_year < 1900 || time_year > 9999)
+		return 0;
+
+	/* Update tm structure */
+
+	tm->tm_year = time_year - 1900;
+	tm->tm_mon = time_month - 1;
+	tm->tm_mday = time_day;
+
+	tm->tm_hour = offset_hms / 3600;
+	tm->tm_min = (offset_hms / 60) % 60;
+	tm->tm_sec = offset_hms % 60;
+
+	return 1;
+		
+}
+
+/* Convert date to and from julian day
+ * Uses Fliegel & Van Flandern algorithm
+ */
+static long date_to_julian(int y, int m, int d)
+{
+	return (1461 * (y + 4800 + (m - 14) / 12)) / 4 +
+		(367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 -
+		(3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 +
+		d - 32075;
+}
+
+static void julian_to_date(long jd, int *y, int *m, int *d)
+	{
+	long  L = jd + 68569;
+	long  n = (4 * L) / 146097;
+	long  i, j;
+
+	L = L - (146097 * n + 3) / 4;
+	i = (4000 * (L + 1)) / 1461001;
+	L = L - (1461 * i) / 4 + 31;
+	j = (80 * L) / 2447;
+	*d = L - (2447 * j) / 80;
+	L = j / 11;
+	*m = j + 2 - (12 * L);
+	*y = 100 * (n - 49) + i + L;
+	}
+
+#ifdef OPENSSL_TIME_TEST
+
+#include <stdio.h>
+
+/* Time checking test code. Check times are identical for a wide range of
+ * offsets. This should be run on a machine with 64 bit time_t or it will
+ * trigger the very errors the routines fix.
+ */
+
+int main(int argc, char **argv)
+	{
+	long offset;
+	for (offset = 0; offset < 1000000; offset++)
+		{
+		check_time(offset);
+		check_time(-offset);
+		check_time(offset * 1000);
+		check_time(-offset * 1000);
+		}
+	}
+
+int check_time(long offset)
+	{
+	struct tm tm1, tm2;
+	time_t t1, t2;
+	time(&t1);
+	t2 = t1 + offset;
+	OPENSSL_gmtime(&t2, &tm2);
+	OPENSSL_gmtime(&t1, &tm1);
+	OPENSSL_gmtime_adj(&tm1, 0, offset);
+	if ((tm1.tm_year == tm2.tm_year) &&
+	    (tm1.tm_mon == tm2.tm_mon) &&
+	    (tm1.tm_mday == tm2.tm_mday) &&
+	    (tm1.tm_hour == tm2.tm_hour) &&
+	    (tm1.tm_min == tm2.tm_min) &&
+	    (tm1.tm_sec == tm2.tm_sec))
+		return 1;
+	fprintf(stderr, "TIME ERROR!!\n");
+	fprintf(stderr, "Time1: %d/%d/%d, %d:%02d:%02d\n",
+			tm2.tm_mday, tm2.tm_mon + 1, tm2.tm_year + 1900,
+			tm2.tm_hour, tm2.tm_min, tm2.tm_sec);
+	fprintf(stderr, "Time2: %d/%d/%d, %d:%02d:%02d\n",
+			tm1.tm_mday, tm1.tm_mon + 1, tm1.tm_year + 1900,
+			tm1.tm_hour, tm1.tm_min, tm1.tm_sec);
+	return 0;
+	}
+
+#endif
diff --git a/openssl/crypto/o_time.h b/openssl/crypto/o_time.h
new file mode 100644
index 0000000..e391da7
--- /dev/null
+++ b/openssl/crypto/o_time.h
@@ -0,0 +1,67 @@
+/* crypto/o_time.h -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_O_TIME_H
+#define HEADER_O_TIME_H
+
+#include <time.h>
+
+struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result);
+int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec);
+
+#endif
diff --git a/openssl/crypto/objects/Makefile b/openssl/crypto/objects/Makefile
new file mode 100644
index 0000000..a8aedbd
--- /dev/null
+++ b/openssl/crypto/objects/Makefile
@@ -0,0 +1,130 @@
+#
+# OpenSSL/crypto/objects/Makefile
+#
+
+DIR=	objects
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+PERL=		perl
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile README
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=	o_names.c obj_dat.c obj_lib.c obj_err.c obj_xref.c
+LIBOBJ= o_names.o obj_dat.o obj_lib.o obj_err.o obj_xref.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= objects.h obj_mac.h
+HEADER=	$(EXHEADER) obj_dat.h obj_xref.h
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	obj_dat.h obj_xref.h lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+obj_dat.h: obj_dat.pl obj_mac.h
+	$(PERL) obj_dat.pl obj_mac.h obj_dat.h
+
+# objects.pl both reads and writes obj_mac.num
+obj_mac.h: objects.pl objects.txt obj_mac.num
+	$(PERL) objects.pl objects.txt obj_mac.num obj_mac.h
+	@sleep 1; touch obj_mac.h; sleep 1
+
+obj_xref.h: objxref.pl obj_xref.txt obj_mac.num
+	$(PERL) objxref.pl obj_mac.num obj_xref.txt > obj_xref.h
+	@sleep 1; touch obj_xref.h; sleep 1
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+o_names.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+o_names.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+o_names.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+o_names.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+o_names.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+o_names.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+o_names.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+o_names.o: o_names.c
+obj_dat.o: ../../e_os.h ../../include/openssl/asn1.h
+obj_dat.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+obj_dat.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+obj_dat.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+obj_dat.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+obj_dat.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+obj_dat.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+obj_dat.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+obj_dat.o: ../../include/openssl/symhacks.h ../cryptlib.h obj_dat.c obj_dat.h
+obj_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+obj_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+obj_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+obj_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+obj_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+obj_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+obj_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+obj_err.o: obj_err.c
+obj_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+obj_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+obj_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+obj_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+obj_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+obj_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+obj_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+obj_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+obj_lib.o: ../cryptlib.h obj_lib.c
+obj_xref.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+obj_xref.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+obj_xref.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+obj_xref.o: ../../include/openssl/opensslconf.h
+obj_xref.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+obj_xref.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+obj_xref.o: ../../include/openssl/symhacks.h obj_xref.c obj_xref.h
diff --git a/openssl/crypto/objects/o_names.c b/openssl/crypto/objects/o_names.c
new file mode 100644
index 0000000..84380a9
--- /dev/null
+++ b/openssl/crypto/objects/o_names.c
@@ -0,0 +1,372 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/err.h>
+#include <openssl/lhash.h>
+#include <openssl/objects.h>
+#include <openssl/safestack.h>
+#include <openssl/e_os2.h>
+
+/* Later versions of DEC C has started to add lnkage information to certain
+ * functions, which makes it tricky to use them as values to regular function
+ * pointers.  One way is to define a macro that takes care of casting them
+ * correctly.
+ */
+#ifdef OPENSSL_SYS_VMS_DECC
+# define OPENSSL_strcmp (int (*)(const char *,const char *))strcmp
+#else
+# define OPENSSL_strcmp strcmp
+#endif
+
+/* I use the ex_data stuff to manage the identifiers for the obj_name_types
+ * that applications may define.  I only really use the free function field.
+ */
+DECLARE_LHASH_OF(OBJ_NAME);
+static LHASH_OF(OBJ_NAME) *names_lh=NULL;
+static int names_type_num=OBJ_NAME_TYPE_NUM;
+
+typedef struct name_funcs_st
+	{
+	unsigned long (*hash_func)(const char *name);
+	int (*cmp_func)(const char *a,const char *b);
+	void (*free_func)(const char *, int, const char *);
+	} NAME_FUNCS;
+
+DECLARE_STACK_OF(NAME_FUNCS)
+IMPLEMENT_STACK_OF(NAME_FUNCS)
+
+static STACK_OF(NAME_FUNCS) *name_funcs_stack;
+
+/* The LHASH callbacks now use the raw "void *" prototypes and do per-variable
+ * casting in the functions. This prevents function pointer casting without the
+ * need for macro-generated wrapper functions. */
+
+/* static unsigned long obj_name_hash(OBJ_NAME *a); */
+static unsigned long obj_name_hash(const void *a_void);
+/* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */
+static int obj_name_cmp(const void *a_void,const void *b_void);
+
+static IMPLEMENT_LHASH_HASH_FN(obj_name, OBJ_NAME)
+static IMPLEMENT_LHASH_COMP_FN(obj_name, OBJ_NAME)
+
+int OBJ_NAME_init(void)
+	{
+	if (names_lh != NULL) return(1);
+	MemCheck_off();
+	names_lh=lh_OBJ_NAME_new();
+	MemCheck_on();
+	return(names_lh != NULL);
+	}
+
+int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *),
+	int (*cmp_func)(const char *, const char *),
+	void (*free_func)(const char *, int, const char *))
+	{
+	int ret;
+	int i;
+	NAME_FUNCS *name_funcs;
+
+	if (name_funcs_stack == NULL)
+		{
+		MemCheck_off();
+		name_funcs_stack=sk_NAME_FUNCS_new_null();
+		MemCheck_on();
+		}
+	if ((name_funcs_stack == NULL))
+		{
+		/* ERROR */
+		return(0);
+		}
+	ret=names_type_num;
+	names_type_num++;
+	for (i=sk_NAME_FUNCS_num(name_funcs_stack); i<names_type_num; i++)
+		{
+		MemCheck_off();
+		name_funcs = OPENSSL_malloc(sizeof(NAME_FUNCS));
+		MemCheck_on();
+		if (!name_funcs)
+			{
+			OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX,ERR_R_MALLOC_FAILURE);
+			return(0);
+			}
+		name_funcs->hash_func = lh_strhash;
+		name_funcs->cmp_func = OPENSSL_strcmp;
+		name_funcs->free_func = 0; /* NULL is often declared to
+						* ((void *)0), which according
+						* to Compaq C is not really
+						* compatible with a function
+						* pointer.	-- Richard Levitte*/
+		MemCheck_off();
+		sk_NAME_FUNCS_push(name_funcs_stack,name_funcs);
+		MemCheck_on();
+		}
+	name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret);
+	if (hash_func != NULL)
+		name_funcs->hash_func = hash_func;
+	if (cmp_func != NULL)
+		name_funcs->cmp_func = cmp_func;
+	if (free_func != NULL)
+		name_funcs->free_func = free_func;
+	return(ret);
+	}
+
+/* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */
+static int obj_name_cmp(const void *a_void, const void *b_void)
+	{
+	int ret;
+	const OBJ_NAME *a = (const OBJ_NAME *)a_void;
+	const OBJ_NAME *b = (const OBJ_NAME *)b_void;
+
+	ret=a->type-b->type;
+	if (ret == 0)
+		{
+		if ((name_funcs_stack != NULL)
+			&& (sk_NAME_FUNCS_num(name_funcs_stack) > a->type))
+			{
+			ret=sk_NAME_FUNCS_value(name_funcs_stack,
+				a->type)->cmp_func(a->name,b->name);
+			}
+		else
+			ret=strcmp(a->name,b->name);
+		}
+	return(ret);
+	}
+
+/* static unsigned long obj_name_hash(OBJ_NAME *a) */
+static unsigned long obj_name_hash(const void *a_void)
+	{
+	unsigned long ret;
+	const OBJ_NAME *a = (const OBJ_NAME *)a_void;
+
+	if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type))
+		{
+		ret=sk_NAME_FUNCS_value(name_funcs_stack,
+			a->type)->hash_func(a->name);
+		}
+	else
+		{
+		ret=lh_strhash(a->name);
+		}
+	ret^=a->type;
+	return(ret);
+	}
+
+const char *OBJ_NAME_get(const char *name, int type)
+	{
+	OBJ_NAME on,*ret;
+	int num=0,alias;
+
+	if (name == NULL) return(NULL);
+	if ((names_lh == NULL) && !OBJ_NAME_init()) return(NULL);
+
+	alias=type&OBJ_NAME_ALIAS;
+	type&= ~OBJ_NAME_ALIAS;
+
+	on.name=name;
+	on.type=type;
+
+	for (;;)
+	{
+		ret=lh_OBJ_NAME_retrieve(names_lh,&on);
+		if (ret == NULL) return(NULL);
+		if ((ret->alias) && !alias)
+			{
+			if (++num > 10) return(NULL);
+			on.name=ret->data;
+			}
+		else
+			{
+			return(ret->data);
+			}
+		}
+	}
+
+int OBJ_NAME_add(const char *name, int type, const char *data)
+	{
+	OBJ_NAME *onp,*ret;
+	int alias;
+
+	if ((names_lh == NULL) && !OBJ_NAME_init()) return(0);
+
+	alias=type&OBJ_NAME_ALIAS;
+	type&= ~OBJ_NAME_ALIAS;
+
+	onp=(OBJ_NAME *)OPENSSL_malloc(sizeof(OBJ_NAME));
+	if (onp == NULL)
+		{
+		/* ERROR */
+		return(0);
+		}
+
+	onp->name=name;
+	onp->alias=alias;
+	onp->type=type;
+	onp->data=data;
+
+	ret=lh_OBJ_NAME_insert(names_lh,onp);
+	if (ret != NULL)
+		{
+		/* free things */
+		if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type))
+			{
+			/* XXX: I'm not sure I understand why the free
+			 * function should get three arguments...
+			 * -- Richard Levitte
+			 */
+			sk_NAME_FUNCS_value(name_funcs_stack,
+				ret->type)->free_func(ret->name,ret->type,ret->data);
+			}
+		OPENSSL_free(ret);
+		}
+	else
+		{
+		if (lh_OBJ_NAME_error(names_lh))
+			{
+			/* ERROR */
+			return(0);
+			}
+		}
+	return(1);
+	}
+
+int OBJ_NAME_remove(const char *name, int type)
+	{
+	OBJ_NAME on,*ret;
+
+	if (names_lh == NULL) return(0);
+
+	type&= ~OBJ_NAME_ALIAS;
+	on.name=name;
+	on.type=type;
+	ret=lh_OBJ_NAME_delete(names_lh,&on);
+	if (ret != NULL)
+		{
+		/* free things */
+		if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type))
+			{
+			/* XXX: I'm not sure I understand why the free
+			 * function should get three arguments...
+			 * -- Richard Levitte
+			 */
+			sk_NAME_FUNCS_value(name_funcs_stack,
+				ret->type)->free_func(ret->name,ret->type,ret->data);
+			}
+		OPENSSL_free(ret);
+		return(1);
+		}
+	else
+		return(0);
+	}
+
+struct doall
+	{
+	int type;
+	void (*fn)(const OBJ_NAME *,void *arg);
+	void *arg;
+	};
+
+static void do_all_fn_doall_arg(const OBJ_NAME *name,struct doall *d)
+	{
+	if(name->type == d->type)
+		d->fn(name,d->arg);
+	}
+
+static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME, struct doall)
+
+void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),void *arg)
+	{
+	struct doall d;
+
+	d.type=type;
+	d.fn=fn;
+	d.arg=arg;
+
+	lh_OBJ_NAME_doall_arg(names_lh, LHASH_DOALL_ARG_FN(do_all_fn),
+			      struct doall, &d);
+	}
+
+struct doall_sorted
+	{
+	int type;
+	int n;
+	const OBJ_NAME **names;
+	};
+
+static void do_all_sorted_fn(const OBJ_NAME *name,void *d_)
+	{
+	struct doall_sorted *d=d_;
+
+	if(name->type != d->type)
+		return;
+
+	d->names[d->n++]=name;
+	}
+
+static int do_all_sorted_cmp(const void *n1_,const void *n2_)
+	{
+	const OBJ_NAME * const *n1=n1_;
+	const OBJ_NAME * const *n2=n2_;
+
+	return strcmp((*n1)->name,(*n2)->name);
+	}
+
+void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg),
+				void *arg)
+	{
+	struct doall_sorted d;
+	int n;
+
+	d.type=type;
+	d.names=OPENSSL_malloc(lh_OBJ_NAME_num_items(names_lh)*sizeof *d.names);
+	d.n=0;
+	OBJ_NAME_do_all(type,do_all_sorted_fn,&d);
+
+	qsort((void *)d.names,d.n,sizeof *d.names,do_all_sorted_cmp);
+
+	for(n=0 ; n < d.n ; ++n)
+		fn(d.names[n],arg);
+
+	OPENSSL_free((void *)d.names);
+	}
+
+static int free_type;
+
+static void names_lh_free_doall(OBJ_NAME *onp)
+	{
+	if (onp == NULL)
+		return;
+
+	if (free_type < 0 || free_type == onp->type)
+		OBJ_NAME_remove(onp->name,onp->type);
+	}
+
+static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME)
+
+static void name_funcs_free(NAME_FUNCS *ptr)
+	{
+	OPENSSL_free(ptr);
+	}
+
+void OBJ_NAME_cleanup(int type)
+	{
+	unsigned long down_load;
+
+	if (names_lh == NULL) return;
+
+	free_type=type;
+	down_load=lh_OBJ_NAME_down_load(names_lh);
+	lh_OBJ_NAME_down_load(names_lh)=0;
+
+	lh_OBJ_NAME_doall(names_lh,LHASH_DOALL_FN(names_lh_free));
+	if (type < 0)
+		{
+		lh_OBJ_NAME_free(names_lh);
+		sk_NAME_FUNCS_pop_free(name_funcs_stack,name_funcs_free);
+		names_lh=NULL;
+		name_funcs_stack = NULL;
+		}
+	else
+		lh_OBJ_NAME_down_load(names_lh)=down_load;
+	}
+
diff --git a/openssl/crypto/objects/obj_dat.c b/openssl/crypto/objects/obj_dat.c
new file mode 100644
index 0000000..8a342ba
--- /dev/null
+++ b/openssl/crypto/objects/obj_dat.c
@@ -0,0 +1,810 @@
+/* crypto/objects/obj_dat.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <limits.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/bn.h>
+
+/* obj_dat.h is generated from objects.h by obj_dat.pl */
+#ifndef OPENSSL_NO_OBJECT
+#include "obj_dat.h"
+#else
+/* You will have to load all the objects needed manually in the application */
+#define NUM_NID 0
+#define NUM_SN 0
+#define NUM_LN 0
+#define NUM_OBJ 0
+static const unsigned char lvalues[1];
+static const ASN1_OBJECT nid_objs[1];
+static const unsigned int sn_objs[1];
+static const unsigned int ln_objs[1];
+static const unsigned int obj_objs[1];
+#endif
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
+DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
+DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
+
+#define ADDED_DATA	0
+#define ADDED_SNAME	1
+#define ADDED_LNAME	2
+#define ADDED_NID	3
+
+typedef struct added_obj_st
+	{
+	int type;
+	ASN1_OBJECT *obj;
+	} ADDED_OBJ;
+DECLARE_LHASH_OF(ADDED_OBJ);
+
+static int new_nid=NUM_NID;
+static LHASH_OF(ADDED_OBJ) *added=NULL;
+
+static int sn_cmp(const ASN1_OBJECT * const *a, const unsigned int *b)
+	{ return(strcmp((*a)->sn,nid_objs[*b].sn)); }
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
+
+static int ln_cmp(const ASN1_OBJECT * const *a, const unsigned int *b)
+	{ return(strcmp((*a)->ln,nid_objs[*b].ln)); }
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
+
+static unsigned long added_obj_hash(const ADDED_OBJ *ca)
+	{
+	const ASN1_OBJECT *a;
+	int i;
+	unsigned long ret=0;
+	unsigned char *p;
+
+	a=ca->obj;
+	switch (ca->type)
+		{
+	case ADDED_DATA:
+		ret=a->length<<20L;
+		p=(unsigned char *)a->data;
+		for (i=0; i<a->length; i++)
+			ret^=p[i]<<((i*3)%24);
+		break;
+	case ADDED_SNAME:
+		ret=lh_strhash(a->sn);
+		break;
+	case ADDED_LNAME:
+		ret=lh_strhash(a->ln);
+		break;
+	case ADDED_NID:
+		ret=a->nid;
+		break;
+	default:
+		/* abort(); */
+		return 0;
+		}
+	ret&=0x3fffffffL;
+	ret|=ca->type<<30L;
+	return(ret);
+	}
+static IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ)
+
+static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb)
+	{
+	ASN1_OBJECT *a,*b;
+	int i;
+
+	i=ca->type-cb->type;
+	if (i) return(i);
+	a=ca->obj;
+	b=cb->obj;
+	switch (ca->type)
+		{
+	case ADDED_DATA:
+		i=(a->length - b->length);
+		if (i) return(i);
+		return(memcmp(a->data,b->data,(size_t)a->length));
+	case ADDED_SNAME:
+		if (a->sn == NULL) return(-1);
+		else if (b->sn == NULL) return(1);
+		else return(strcmp(a->sn,b->sn));
+	case ADDED_LNAME:
+		if (a->ln == NULL) return(-1);
+		else if (b->ln == NULL) return(1);
+		else return(strcmp(a->ln,b->ln));
+	case ADDED_NID:
+		return(a->nid-b->nid);
+	default:
+		/* abort(); */
+		return 0;
+		}
+	}
+static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ)
+
+static int init_added(void)
+	{
+	if (added != NULL) return(1);
+	added=lh_ADDED_OBJ_new();
+	return(added != NULL);
+	}
+
+static void cleanup1_doall(ADDED_OBJ *a)
+	{
+	a->obj->nid=0;
+	a->obj->flags|=ASN1_OBJECT_FLAG_DYNAMIC|
+	                ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
+			ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+	}
+
+static void cleanup2_doall(ADDED_OBJ *a)
+	{ a->obj->nid++; }
+
+static void cleanup3_doall(ADDED_OBJ *a)
+	{
+	if (--a->obj->nid == 0)
+		ASN1_OBJECT_free(a->obj);
+	OPENSSL_free(a);
+	}
+
+static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ)
+static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ)
+static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ)
+
+/* The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting
+ * to use freed up OIDs. If neccessary the actual freeing up of OIDs is
+ * delayed.
+ */
+
+int obj_cleanup_defer = 0;
+
+void check_defer(int nid)
+	{
+	if (!obj_cleanup_defer && nid >= NUM_NID)
+			obj_cleanup_defer = 1;
+	}
+
+void OBJ_cleanup(void)
+	{
+	if (obj_cleanup_defer)
+		{
+		obj_cleanup_defer = 2;
+		return ;
+		}
+	if (added == NULL) return;
+	lh_ADDED_OBJ_down_load(added) = 0;
+	lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */
+	lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup2)); /* set counters */
+	lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup3)); /* free objects */
+	lh_ADDED_OBJ_free(added);
+	added=NULL;
+	}
+
+int OBJ_new_nid(int num)
+	{
+	int i;
+
+	i=new_nid;
+	new_nid+=num;
+	return(i);
+	}
+
+int OBJ_add_object(const ASN1_OBJECT *obj)
+	{
+	ASN1_OBJECT *o;
+	ADDED_OBJ *ao[4]={NULL,NULL,NULL,NULL},*aop;
+	int i;
+
+	if (added == NULL)
+		if (!init_added()) return(0);
+	if ((o=OBJ_dup(obj)) == NULL) goto err;
+	if (!(ao[ADDED_NID]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2;
+	if ((o->length != 0) && (obj->data != NULL))
+		if (!(ao[ADDED_DATA]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2;
+	if (o->sn != NULL)
+		if (!(ao[ADDED_SNAME]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2;
+	if (o->ln != NULL)
+		if (!(ao[ADDED_LNAME]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2;
+
+	for (i=ADDED_DATA; i<=ADDED_NID; i++)
+		{
+		if (ao[i] != NULL)
+			{
+			ao[i]->type=i;
+			ao[i]->obj=o;
+			aop=lh_ADDED_OBJ_insert(added,ao[i]);
+			/* memory leak, buit should not normally matter */
+			if (aop != NULL)
+				OPENSSL_free(aop);
+			}
+		}
+	o->flags&= ~(ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
+			ASN1_OBJECT_FLAG_DYNAMIC_DATA);
+
+	return(o->nid);
+err2:
+	OBJerr(OBJ_F_OBJ_ADD_OBJECT,ERR_R_MALLOC_FAILURE);
+err:
+	for (i=ADDED_DATA; i<=ADDED_NID; i++)
+		if (ao[i] != NULL) OPENSSL_free(ao[i]);
+	if (o != NULL) OPENSSL_free(o);
+	return(NID_undef);
+	}
+
+ASN1_OBJECT *OBJ_nid2obj(int n)
+	{
+	ADDED_OBJ ad,*adp;
+	ASN1_OBJECT ob;
+
+	if ((n >= 0) && (n < NUM_NID))
+		{
+		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef))
+			{
+			OBJerr(OBJ_F_OBJ_NID2OBJ,OBJ_R_UNKNOWN_NID);
+			return(NULL);
+			}
+		return((ASN1_OBJECT *)&(nid_objs[n]));
+		}
+	else if (added == NULL)
+		return(NULL);
+	else
+		{
+		ad.type=ADDED_NID;
+		ad.obj= &ob;
+		ob.nid=n;
+		adp=lh_ADDED_OBJ_retrieve(added,&ad);
+		if (adp != NULL)
+			return(adp->obj);
+		else
+			{
+			OBJerr(OBJ_F_OBJ_NID2OBJ,OBJ_R_UNKNOWN_NID);
+			return(NULL);
+			}
+		}
+	}
+
+const char *OBJ_nid2sn(int n)
+	{
+	ADDED_OBJ ad,*adp;
+	ASN1_OBJECT ob;
+
+	if ((n >= 0) && (n < NUM_NID))
+		{
+		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef))
+			{
+			OBJerr(OBJ_F_OBJ_NID2SN,OBJ_R_UNKNOWN_NID);
+			return(NULL);
+			}
+		return(nid_objs[n].sn);
+		}
+	else if (added == NULL)
+		return(NULL);
+	else
+		{
+		ad.type=ADDED_NID;
+		ad.obj= &ob;
+		ob.nid=n;
+		adp=lh_ADDED_OBJ_retrieve(added,&ad);
+		if (adp != NULL)
+			return(adp->obj->sn);
+		else
+			{
+			OBJerr(OBJ_F_OBJ_NID2SN,OBJ_R_UNKNOWN_NID);
+			return(NULL);
+			}
+		}
+	}
+
+const char *OBJ_nid2ln(int n)
+	{
+	ADDED_OBJ ad,*adp;
+	ASN1_OBJECT ob;
+
+	if ((n >= 0) && (n < NUM_NID))
+		{
+		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef))
+			{
+			OBJerr(OBJ_F_OBJ_NID2LN,OBJ_R_UNKNOWN_NID);
+			return(NULL);
+			}
+		return(nid_objs[n].ln);
+		}
+	else if (added == NULL)
+		return(NULL);
+	else
+		{
+		ad.type=ADDED_NID;
+		ad.obj= &ob;
+		ob.nid=n;
+		adp=lh_ADDED_OBJ_retrieve(added,&ad);
+		if (adp != NULL)
+			return(adp->obj->ln);
+		else
+			{
+			OBJerr(OBJ_F_OBJ_NID2LN,OBJ_R_UNKNOWN_NID);
+			return(NULL);
+			}
+		}
+	}
+
+static int obj_cmp(const ASN1_OBJECT * const *ap, const unsigned int *bp)
+	{
+	int j;
+	const ASN1_OBJECT *a= *ap;
+	const ASN1_OBJECT *b= &nid_objs[*bp];
+
+	j=(a->length - b->length);
+        if (j) return(j);
+	return(memcmp(a->data,b->data,a->length));
+	}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
+
+int OBJ_obj2nid(const ASN1_OBJECT *a)
+	{
+	const unsigned int *op;
+	ADDED_OBJ ad,*adp;
+
+	if (a == NULL)
+		return(NID_undef);
+	if (a->nid != 0)
+		return(a->nid);
+
+	if (added != NULL)
+		{
+		ad.type=ADDED_DATA;
+		ad.obj=(ASN1_OBJECT *)a; /* XXX: ugly but harmless */
+		adp=lh_ADDED_OBJ_retrieve(added,&ad);
+		if (adp != NULL) return (adp->obj->nid);
+		}
+	op=OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ);
+	if (op == NULL)
+		return(NID_undef);
+	return(nid_objs[*op].nid);
+	}
+
+/* Convert an object name into an ASN1_OBJECT
+ * if "noname" is not set then search for short and long names first.
+ * This will convert the "dotted" form into an object: unlike OBJ_txt2nid
+ * it can be used with any objects, not just registered ones.
+ */
+
+ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name)
+	{
+	int nid = NID_undef;
+	ASN1_OBJECT *op=NULL;
+	unsigned char *buf;
+	unsigned char *p;
+	const unsigned char *cp;
+	int i, j;
+
+	if(!no_name) {
+		if( ((nid = OBJ_sn2nid(s)) != NID_undef) ||
+			((nid = OBJ_ln2nid(s)) != NID_undef) ) 
+					return OBJ_nid2obj(nid);
+	}
+
+	/* Work out size of content octets */
+	i=a2d_ASN1_OBJECT(NULL,0,s,-1);
+	if (i <= 0) {
+		/* Don't clear the error */
+		/*ERR_clear_error();*/
+		return NULL;
+	}
+	/* Work out total size */
+	j = ASN1_object_size(0,i,V_ASN1_OBJECT);
+
+	if((buf=(unsigned char *)OPENSSL_malloc(j)) == NULL) return NULL;
+
+	p = buf;
+	/* Write out tag+length */
+	ASN1_put_object(&p,0,i,V_ASN1_OBJECT,V_ASN1_UNIVERSAL);
+	/* Write out contents */
+	a2d_ASN1_OBJECT(p,i,s,-1);
+
+	cp=buf;
+	op=d2i_ASN1_OBJECT(NULL,&cp,j);
+	OPENSSL_free(buf);
+	return op;
+	}
+
+int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
+{
+	int i,n=0,len,nid, first, use_bn;
+	BIGNUM *bl;
+	unsigned long l;
+	const unsigned char *p;
+	char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2];
+
+	if ((a == NULL) || (a->data == NULL)) {
+		buf[0]='\0';
+		return(0);
+	}
+
+
+	if (!no_name && (nid=OBJ_obj2nid(a)) != NID_undef)
+		{
+		const char *s;
+		s=OBJ_nid2ln(nid);
+		if (s == NULL)
+			s=OBJ_nid2sn(nid);
+		if (s)
+			{
+			if (buf)
+				BUF_strlcpy(buf,s,buf_len);
+			n=strlen(s);
+			return n;
+			}
+		}
+
+
+	len=a->length;
+	p=a->data;
+
+	first = 1;
+	bl = NULL;
+
+	while (len > 0)
+		{
+		l=0;
+		use_bn = 0;
+		for (;;)
+			{
+			unsigned char c = *p++;
+			len--;
+			if ((len == 0) && (c & 0x80))
+				goto err;
+			if (use_bn)
+				{
+				if (!BN_add_word(bl, c & 0x7f))
+					goto err;
+				}
+			else
+				l |= c  & 0x7f;
+			if (!(c & 0x80))
+				break;
+			if (!use_bn && (l > (ULONG_MAX >> 7L)))
+				{
+				if (!bl && !(bl = BN_new()))
+					goto err;
+				if (!BN_set_word(bl, l))
+					goto err;
+				use_bn = 1;
+				}
+			if (use_bn)
+				{
+				if (!BN_lshift(bl, bl, 7))
+					goto err;
+				}
+			else
+				l<<=7L;
+			}
+
+		if (first)
+			{
+			first = 0;
+			if (l >= 80)
+				{
+				i = 2;
+				if (use_bn)
+					{
+					if (!BN_sub_word(bl, 80))
+						goto err;
+					}
+				else
+					l -= 80;
+				}
+			else
+				{
+				i=(int)(l/40);
+				l-=(long)(i*40);
+				}
+			if (buf && (buf_len > 0))
+				{
+				*buf++ = i + '0';
+				buf_len--;
+				}
+			n++;
+			}
+
+		if (use_bn)
+			{
+			char *bndec;
+			bndec = BN_bn2dec(bl);
+			if (!bndec)
+				goto err;
+			i = strlen(bndec);
+			if (buf)
+				{
+				if (buf_len > 0)
+					{
+					*buf++ = '.';
+					buf_len--;
+					}
+				BUF_strlcpy(buf,bndec,buf_len);
+				if (i > buf_len)
+					{
+					buf += buf_len;
+					buf_len = 0;
+					}
+				else
+					{
+					buf+=i;
+					buf_len-=i;
+					}
+				}
+			n++;
+			n += i;
+			OPENSSL_free(bndec);
+			}
+		else
+			{
+			BIO_snprintf(tbuf,sizeof tbuf,".%lu",l);
+			i=strlen(tbuf);
+			if (buf && (buf_len > 0))
+				{
+				BUF_strlcpy(buf,tbuf,buf_len);
+				if (i > buf_len)
+					{
+					buf += buf_len;
+					buf_len = 0;
+					}
+				else
+					{
+					buf+=i;
+					buf_len-=i;
+					}
+				}
+			n+=i;
+			l=0;
+			}
+		}
+
+	if (bl)
+		BN_free(bl);
+	return n;
+
+	err:
+	if (bl)
+		BN_free(bl);
+	return -1;
+}
+
+int OBJ_txt2nid(const char *s)
+{
+	ASN1_OBJECT *obj;
+	int nid;
+	obj = OBJ_txt2obj(s, 0);
+	nid = OBJ_obj2nid(obj);
+	ASN1_OBJECT_free(obj);
+	return nid;
+}
+
+int OBJ_ln2nid(const char *s)
+	{
+	ASN1_OBJECT o;
+	const ASN1_OBJECT *oo= &o;
+	ADDED_OBJ ad,*adp;
+	const unsigned int *op;
+
+	o.ln=s;
+	if (added != NULL)
+		{
+		ad.type=ADDED_LNAME;
+		ad.obj= &o;
+		adp=lh_ADDED_OBJ_retrieve(added,&ad);
+		if (adp != NULL) return (adp->obj->nid);
+		}
+	op=OBJ_bsearch_ln(&oo, ln_objs, NUM_LN);
+	if (op == NULL) return(NID_undef);
+	return(nid_objs[*op].nid);
+	}
+
+int OBJ_sn2nid(const char *s)
+	{
+	ASN1_OBJECT o;
+	const ASN1_OBJECT *oo= &o;
+	ADDED_OBJ ad,*adp;
+	const unsigned int *op;
+
+	o.sn=s;
+	if (added != NULL)
+		{
+		ad.type=ADDED_SNAME;
+		ad.obj= &o;
+		adp=lh_ADDED_OBJ_retrieve(added,&ad);
+		if (adp != NULL) return (adp->obj->nid);
+		}
+	op=OBJ_bsearch_sn(&oo, sn_objs, NUM_SN);
+	if (op == NULL) return(NID_undef);
+	return(nid_objs[*op].nid);
+	}
+
+const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
+			 int (*cmp)(const void *, const void *))
+	{
+	return OBJ_bsearch_ex_(key, base, num, size, cmp, 0);
+	}
+
+const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num,
+			    int size,
+			    int (*cmp)(const void *, const void *),
+			    int flags)
+	{
+	const char *base=base_;
+	int l,h,i=0,c=0;
+	const char *p = NULL;
+
+	if (num == 0) return(NULL);
+	l=0;
+	h=num;
+	while (l < h)
+		{
+		i=(l+h)/2;
+		p= &(base[i*size]);
+		c=(*cmp)(key,p);
+		if (c < 0)
+			h=i;
+		else if (c > 0)
+			l=i+1;
+		else
+			break;
+		}
+#ifdef CHARSET_EBCDIC
+/* THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and
+ * I don't have perl (yet), we revert to a *LINEAR* search
+ * when the object wasn't found in the binary search.
+ */
+	if (c != 0)
+		{
+		for (i=0; i<num; ++i)
+			{
+			p= &(base[i*size]);
+			c = (*cmp)(key,p);
+			if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
+				return p;
+			}
+		}
+#endif
+	if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))
+		p = NULL;
+	else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH))
+		{
+		while(i > 0 && (*cmp)(key,&(base[(i-1)*size])) == 0)
+			i--;
+		p = &(base[i*size]);
+		}
+	return(p);
+	}
+
+int OBJ_create_objects(BIO *in)
+	{
+	MS_STATIC char buf[512];
+	int i,num=0;
+	char *o,*s,*l=NULL;
+
+	for (;;)
+		{
+		s=o=NULL;
+		i=BIO_gets(in,buf,512);
+		if (i <= 0) return(num);
+		buf[i-1]='\0';
+		if (!isalnum((unsigned char)buf[0])) return(num);
+		o=s=buf;
+		while (isdigit((unsigned char)*s) || (*s == '.'))
+			s++;
+		if (*s != '\0')
+			{
+			*(s++)='\0';
+			while (isspace((unsigned char)*s))
+				s++;
+			if (*s == '\0')
+				s=NULL;
+			else
+				{
+				l=s;
+				while ((*l != '\0') && !isspace((unsigned char)*l))
+					l++;
+				if (*l != '\0')
+					{
+					*(l++)='\0';
+					while (isspace((unsigned char)*l))
+						l++;
+					if (*l == '\0') l=NULL;
+					}
+				else
+					l=NULL;
+				}
+			}
+		else
+			s=NULL;
+		if ((o == NULL) || (*o == '\0')) return(num);
+		if (!OBJ_create(o,s,l)) return(num);
+		num++;
+		}
+	/* return(num); */
+	}
+
+int OBJ_create(const char *oid, const char *sn, const char *ln)
+	{
+	int ok=0;
+	ASN1_OBJECT *op=NULL;
+	unsigned char *buf;
+	int i;
+
+	i=a2d_ASN1_OBJECT(NULL,0,oid,-1);
+	if (i <= 0) return(0);
+
+	if ((buf=(unsigned char *)OPENSSL_malloc(i)) == NULL)
+		{
+		OBJerr(OBJ_F_OBJ_CREATE,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	i=a2d_ASN1_OBJECT(buf,i,oid,-1);
+	if (i == 0)
+		goto err;
+	op=(ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1),buf,i,sn,ln);
+	if (op == NULL) 
+		goto err;
+	ok=OBJ_add_object(op);
+err:
+	ASN1_OBJECT_free(op);
+	OPENSSL_free(buf);
+	return(ok);
+	}
+
diff --git a/openssl/crypto/objects/obj_dat.h b/openssl/crypto/objects/obj_dat.h
new file mode 100644
index 0000000..6449be6
--- /dev/null
+++ b/openssl/crypto/objects/obj_dat.h
@@ -0,0 +1,4976 @@
+/* crypto/objects/obj_dat.h */
+
+/* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the
+ * following command:
+ * perl obj_dat.pl obj_mac.h obj_dat.h
+ */
+
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#define NUM_NID 893
+#define NUM_SN 886
+#define NUM_LN 886
+#define NUM_OBJ 840
+
+static const unsigned char lvalues[5824]={
+0x00,                                        /* [  0] OBJ_undef */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,               /* [  1] OBJ_rsadsi */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,          /* [  7] OBJ_pkcs */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02,     /* [ 14] OBJ_md2 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x05,     /* [ 22] OBJ_md5 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x04,     /* [ 30] OBJ_rc4 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,/* [ 38] OBJ_rsaEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x02,/* [ 47] OBJ_md2WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,/* [ 56] OBJ_md5WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x01,/* [ 65] OBJ_pbeWithMD2AndDES_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x03,/* [ 74] OBJ_pbeWithMD5AndDES_CBC */
+0x55,                                        /* [ 83] OBJ_X500 */
+0x55,0x04,                                   /* [ 84] OBJ_X509 */
+0x55,0x04,0x03,                              /* [ 86] OBJ_commonName */
+0x55,0x04,0x06,                              /* [ 89] OBJ_countryName */
+0x55,0x04,0x07,                              /* [ 92] OBJ_localityName */
+0x55,0x04,0x08,                              /* [ 95] OBJ_stateOrProvinceName */
+0x55,0x04,0x0A,                              /* [ 98] OBJ_organizationName */
+0x55,0x04,0x0B,                              /* [101] OBJ_organizationalUnitName */
+0x55,0x08,0x01,0x01,                         /* [104] OBJ_rsa */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,     /* [108] OBJ_pkcs7 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x01,/* [116] OBJ_pkcs7_data */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x02,/* [125] OBJ_pkcs7_signed */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x03,/* [134] OBJ_pkcs7_enveloped */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x04,/* [143] OBJ_pkcs7_signedAndEnveloped */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x05,/* [152] OBJ_pkcs7_digest */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x06,/* [161] OBJ_pkcs7_encrypted */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03,     /* [170] OBJ_pkcs3 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03,0x01,/* [178] OBJ_dhKeyAgreement */
+0x2B,0x0E,0x03,0x02,0x06,                    /* [187] OBJ_des_ecb */
+0x2B,0x0E,0x03,0x02,0x09,                    /* [192] OBJ_des_cfb64 */
+0x2B,0x0E,0x03,0x02,0x07,                    /* [197] OBJ_des_cbc */
+0x2B,0x0E,0x03,0x02,0x11,                    /* [202] OBJ_des_ede_ecb */
+0x2B,0x06,0x01,0x04,0x01,0x81,0x3C,0x07,0x01,0x01,0x02,/* [207] OBJ_idea_cbc */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x02,     /* [218] OBJ_rc2_cbc */
+0x2B,0x0E,0x03,0x02,0x12,                    /* [226] OBJ_sha */
+0x2B,0x0E,0x03,0x02,0x0F,                    /* [231] OBJ_shaWithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x07,     /* [236] OBJ_des_ede3_cbc */
+0x2B,0x0E,0x03,0x02,0x08,                    /* [244] OBJ_des_ofb64 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,     /* [249] OBJ_pkcs9 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,/* [257] OBJ_pkcs9_emailAddress */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x02,/* [266] OBJ_pkcs9_unstructuredName */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x03,/* [275] OBJ_pkcs9_contentType */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x04,/* [284] OBJ_pkcs9_messageDigest */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x05,/* [293] OBJ_pkcs9_signingTime */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x06,/* [302] OBJ_pkcs9_countersignature */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x07,/* [311] OBJ_pkcs9_challengePassword */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x08,/* [320] OBJ_pkcs9_unstructuredAddress */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x09,/* [329] OBJ_pkcs9_extCertAttributes */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,          /* [338] OBJ_netscape */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,     /* [345] OBJ_netscape_cert_extension */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02,     /* [353] OBJ_netscape_data_type */
+0x2B,0x0E,0x03,0x02,0x1A,                    /* [361] OBJ_sha1 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,/* [366] OBJ_sha1WithRSAEncryption */
+0x2B,0x0E,0x03,0x02,0x0D,                    /* [375] OBJ_dsaWithSHA */
+0x2B,0x0E,0x03,0x02,0x0C,                    /* [380] OBJ_dsa_2 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0B,/* [385] OBJ_pbeWithSHA1AndRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0C,/* [394] OBJ_id_pbkdf2 */
+0x2B,0x0E,0x03,0x02,0x1B,                    /* [403] OBJ_dsaWithSHA1_2 */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,/* [408] OBJ_netscape_cert_type */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x02,/* [417] OBJ_netscape_base_url */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x03,/* [426] OBJ_netscape_revocation_url */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x04,/* [435] OBJ_netscape_ca_revocation_url */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x07,/* [444] OBJ_netscape_renewal_url */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x08,/* [453] OBJ_netscape_ca_policy_url */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0C,/* [462] OBJ_netscape_ssl_server_name */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0D,/* [471] OBJ_netscape_comment */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02,0x05,/* [480] OBJ_netscape_cert_sequence */
+0x55,0x1D,                                   /* [489] OBJ_id_ce */
+0x55,0x1D,0x0E,                              /* [491] OBJ_subject_key_identifier */
+0x55,0x1D,0x0F,                              /* [494] OBJ_key_usage */
+0x55,0x1D,0x10,                              /* [497] OBJ_private_key_usage_period */
+0x55,0x1D,0x11,                              /* [500] OBJ_subject_alt_name */
+0x55,0x1D,0x12,                              /* [503] OBJ_issuer_alt_name */
+0x55,0x1D,0x13,                              /* [506] OBJ_basic_constraints */
+0x55,0x1D,0x14,                              /* [509] OBJ_crl_number */
+0x55,0x1D,0x20,                              /* [512] OBJ_certificate_policies */
+0x55,0x1D,0x23,                              /* [515] OBJ_authority_key_identifier */
+0x2B,0x06,0x01,0x04,0x01,0x97,0x55,0x01,0x02,/* [518] OBJ_bf_cbc */
+0x55,0x08,0x03,0x65,                         /* [527] OBJ_mdc2 */
+0x55,0x08,0x03,0x64,                         /* [531] OBJ_mdc2WithRSA */
+0x55,0x04,0x2A,                              /* [535] OBJ_givenName */
+0x55,0x04,0x04,                              /* [538] OBJ_surname */
+0x55,0x04,0x2B,                              /* [541] OBJ_initials */
+0x55,0x1D,0x1F,                              /* [544] OBJ_crl_distribution_points */
+0x2B,0x0E,0x03,0x02,0x03,                    /* [547] OBJ_md5WithRSA */
+0x55,0x04,0x05,                              /* [552] OBJ_serialNumber */
+0x55,0x04,0x0C,                              /* [555] OBJ_title */
+0x55,0x04,0x0D,                              /* [558] OBJ_description */
+0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0A,/* [561] OBJ_cast5_cbc */
+0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0C,/* [570] OBJ_pbeWithMD5AndCast5_CBC */
+0x2A,0x86,0x48,0xCE,0x38,0x04,0x03,          /* [579] OBJ_dsaWithSHA1 */
+0x2B,0x0E,0x03,0x02,0x1D,                    /* [586] OBJ_sha1WithRSA */
+0x2A,0x86,0x48,0xCE,0x38,0x04,0x01,          /* [591] OBJ_dsa */
+0x2B,0x24,0x03,0x02,0x01,                    /* [598] OBJ_ripemd160 */
+0x2B,0x24,0x03,0x03,0x01,0x02,               /* [603] OBJ_ripemd160WithRSA */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x08,     /* [609] OBJ_rc5_cbc */
+0x29,0x01,0x01,0x85,0x1A,0x01,               /* [617] OBJ_rle_compression */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x08,/* [623] OBJ_zlib_compression */
+0x55,0x1D,0x25,                              /* [634] OBJ_ext_key_usage */
+0x2B,0x06,0x01,0x05,0x05,0x07,               /* [637] OBJ_id_pkix */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,          /* [643] OBJ_id_kp */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,     /* [650] OBJ_server_auth */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,     /* [658] OBJ_client_auth */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03,     /* [666] OBJ_code_sign */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x04,     /* [674] OBJ_email_protect */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x08,     /* [682] OBJ_time_stamp */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x15,/* [690] OBJ_ms_code_ind */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x16,/* [700] OBJ_ms_code_com */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x01,/* [710] OBJ_ms_ctl_sign */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x03,/* [720] OBJ_ms_sgc */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x04,/* [730] OBJ_ms_efs */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,/* [740] OBJ_ns_sgc */
+0x55,0x1D,0x1B,                              /* [749] OBJ_delta_crl */
+0x55,0x1D,0x15,                              /* [752] OBJ_crl_reason */
+0x55,0x1D,0x18,                              /* [755] OBJ_invalidity_date */
+0x2B,0x65,0x01,0x04,0x01,                    /* [758] OBJ_sxnet */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x01,/* [763] OBJ_pbe_WithSHA1And128BitRC4 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x02,/* [773] OBJ_pbe_WithSHA1And40BitRC4 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x03,/* [783] OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x04,/* [793] OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x05,/* [803] OBJ_pbe_WithSHA1And128BitRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x06,/* [813] OBJ_pbe_WithSHA1And40BitRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x01,/* [823] OBJ_keyBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x02,/* [834] OBJ_pkcs8ShroudedKeyBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x03,/* [845] OBJ_certBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x04,/* [856] OBJ_crlBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x05,/* [867] OBJ_secretBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x06,/* [878] OBJ_safeContentsBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x14,/* [889] OBJ_friendlyName */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x15,/* [898] OBJ_localKeyID */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x01,/* [907] OBJ_x509Certificate */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x02,/* [917] OBJ_sdsiCertificate */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x17,0x01,/* [927] OBJ_x509Crl */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0D,/* [937] OBJ_pbes2 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0E,/* [946] OBJ_pbmac1 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x07,     /* [955] OBJ_hmacWithSHA1 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,     /* [963] OBJ_id_qt_cps */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,     /* [971] OBJ_id_qt_unotice */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0F,/* [979] OBJ_SMIMECapabilities */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x04,/* [988] OBJ_pbeWithMD2AndRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x06,/* [997] OBJ_pbeWithMD5AndRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0A,/* [1006] OBJ_pbeWithSHA1AndDES_CBC */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x0E,/* [1015] OBJ_ms_ext_req */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0E,/* [1025] OBJ_ext_req */
+0x55,0x04,0x29,                              /* [1034] OBJ_name */
+0x55,0x04,0x2E,                              /* [1037] OBJ_dnQualifier */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,          /* [1040] OBJ_id_pe */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,          /* [1047] OBJ_id_ad */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,     /* [1054] OBJ_info_access */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,     /* [1062] OBJ_ad_OCSP */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,     /* [1070] OBJ_ad_ca_issuers */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09,     /* [1078] OBJ_OCSP_sign */
+0x28,                                        /* [1086] OBJ_iso */
+0x2A,                                        /* [1087] OBJ_member_body */
+0x2A,0x86,0x48,                              /* [1088] OBJ_ISO_US */
+0x2A,0x86,0x48,0xCE,0x38,                    /* [1091] OBJ_X9_57 */
+0x2A,0x86,0x48,0xCE,0x38,0x04,               /* [1096] OBJ_X9cm */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,     /* [1102] OBJ_pkcs1 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,     /* [1110] OBJ_pkcs5 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,/* [1118] OBJ_SMIME */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,/* [1127] OBJ_id_smime_mod */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,/* [1137] OBJ_id_smime_ct */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,/* [1147] OBJ_id_smime_aa */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,/* [1157] OBJ_id_smime_alg */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,/* [1167] OBJ_id_smime_cd */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,/* [1177] OBJ_id_smime_spq */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,/* [1187] OBJ_id_smime_cti */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x01,/* [1197] OBJ_id_smime_mod_cms */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x02,/* [1208] OBJ_id_smime_mod_ess */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x03,/* [1219] OBJ_id_smime_mod_oid */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x04,/* [1230] OBJ_id_smime_mod_msg_v3 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x05,/* [1241] OBJ_id_smime_mod_ets_eSignature_88 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x06,/* [1252] OBJ_id_smime_mod_ets_eSignature_97 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x07,/* [1263] OBJ_id_smime_mod_ets_eSigPolicy_88 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x08,/* [1274] OBJ_id_smime_mod_ets_eSigPolicy_97 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x01,/* [1285] OBJ_id_smime_ct_receipt */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x02,/* [1296] OBJ_id_smime_ct_authData */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x03,/* [1307] OBJ_id_smime_ct_publishCert */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x04,/* [1318] OBJ_id_smime_ct_TSTInfo */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x05,/* [1329] OBJ_id_smime_ct_TDTInfo */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x06,/* [1340] OBJ_id_smime_ct_contentInfo */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x07,/* [1351] OBJ_id_smime_ct_DVCSRequestData */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x08,/* [1362] OBJ_id_smime_ct_DVCSResponseData */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x01,/* [1373] OBJ_id_smime_aa_receiptRequest */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x02,/* [1384] OBJ_id_smime_aa_securityLabel */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x03,/* [1395] OBJ_id_smime_aa_mlExpandHistory */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x04,/* [1406] OBJ_id_smime_aa_contentHint */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x05,/* [1417] OBJ_id_smime_aa_msgSigDigest */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x06,/* [1428] OBJ_id_smime_aa_encapContentType */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x07,/* [1439] OBJ_id_smime_aa_contentIdentifier */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x08,/* [1450] OBJ_id_smime_aa_macValue */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x09,/* [1461] OBJ_id_smime_aa_equivalentLabels */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0A,/* [1472] OBJ_id_smime_aa_contentReference */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0B,/* [1483] OBJ_id_smime_aa_encrypKeyPref */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0C,/* [1494] OBJ_id_smime_aa_signingCertificate */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0D,/* [1505] OBJ_id_smime_aa_smimeEncryptCerts */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0E,/* [1516] OBJ_id_smime_aa_timeStampToken */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0F,/* [1527] OBJ_id_smime_aa_ets_sigPolicyId */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x10,/* [1538] OBJ_id_smime_aa_ets_commitmentType */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x11,/* [1549] OBJ_id_smime_aa_ets_signerLocation */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x12,/* [1560] OBJ_id_smime_aa_ets_signerAttr */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x13,/* [1571] OBJ_id_smime_aa_ets_otherSigCert */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x14,/* [1582] OBJ_id_smime_aa_ets_contentTimestamp */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x15,/* [1593] OBJ_id_smime_aa_ets_CertificateRefs */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x16,/* [1604] OBJ_id_smime_aa_ets_RevocationRefs */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x17,/* [1615] OBJ_id_smime_aa_ets_certValues */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x18,/* [1626] OBJ_id_smime_aa_ets_revocationValues */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x19,/* [1637] OBJ_id_smime_aa_ets_escTimeStamp */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1A,/* [1648] OBJ_id_smime_aa_ets_certCRLTimestamp */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1B,/* [1659] OBJ_id_smime_aa_ets_archiveTimeStamp */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1C,/* [1670] OBJ_id_smime_aa_signatureType */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1D,/* [1681] OBJ_id_smime_aa_dvcs_dvc */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x01,/* [1692] OBJ_id_smime_alg_ESDHwith3DES */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x02,/* [1703] OBJ_id_smime_alg_ESDHwithRC2 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x03,/* [1714] OBJ_id_smime_alg_3DESwrap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x04,/* [1725] OBJ_id_smime_alg_RC2wrap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x05,/* [1736] OBJ_id_smime_alg_ESDH */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x06,/* [1747] OBJ_id_smime_alg_CMS3DESwrap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x07,/* [1758] OBJ_id_smime_alg_CMSRC2wrap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,0x01,/* [1769] OBJ_id_smime_cd_ldap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x01,/* [1780] OBJ_id_smime_spq_ets_sqt_uri */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x02,/* [1791] OBJ_id_smime_spq_ets_sqt_unotice */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x01,/* [1802] OBJ_id_smime_cti_ets_proofOfOrigin */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x02,/* [1813] OBJ_id_smime_cti_ets_proofOfReceipt */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x03,/* [1824] OBJ_id_smime_cti_ets_proofOfDelivery */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x04,/* [1835] OBJ_id_smime_cti_ets_proofOfSender */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x05,/* [1846] OBJ_id_smime_cti_ets_proofOfApproval */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x06,/* [1857] OBJ_id_smime_cti_ets_proofOfCreation */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x04,     /* [1868] OBJ_md4 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,          /* [1876] OBJ_id_pkix_mod */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x02,          /* [1883] OBJ_id_qt */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,          /* [1890] OBJ_id_it */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,          /* [1897] OBJ_id_pkip */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,          /* [1904] OBJ_id_alg */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,          /* [1911] OBJ_id_cmc */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x08,          /* [1918] OBJ_id_on */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,          /* [1925] OBJ_id_pda */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,          /* [1932] OBJ_id_aca */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,          /* [1939] OBJ_id_qcs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,          /* [1946] OBJ_id_cct */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x01,     /* [1953] OBJ_id_pkix1_explicit_88 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x02,     /* [1961] OBJ_id_pkix1_implicit_88 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x03,     /* [1969] OBJ_id_pkix1_explicit_93 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x04,     /* [1977] OBJ_id_pkix1_implicit_93 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x05,     /* [1985] OBJ_id_mod_crmf */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x06,     /* [1993] OBJ_id_mod_cmc */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x07,     /* [2001] OBJ_id_mod_kea_profile_88 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x08,     /* [2009] OBJ_id_mod_kea_profile_93 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x09,     /* [2017] OBJ_id_mod_cmp */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0A,     /* [2025] OBJ_id_mod_qualified_cert_88 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0B,     /* [2033] OBJ_id_mod_qualified_cert_93 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0C,     /* [2041] OBJ_id_mod_attribute_cert */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0D,     /* [2049] OBJ_id_mod_timestamp_protocol */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0E,     /* [2057] OBJ_id_mod_ocsp */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0F,     /* [2065] OBJ_id_mod_dvcs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x10,     /* [2073] OBJ_id_mod_cmp2000 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x02,     /* [2081] OBJ_biometricInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x03,     /* [2089] OBJ_qcStatements */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x04,     /* [2097] OBJ_ac_auditEntity */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x05,     /* [2105] OBJ_ac_targeting */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x06,     /* [2113] OBJ_aaControls */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x07,     /* [2121] OBJ_sbgp_ipAddrBlock */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x08,     /* [2129] OBJ_sbgp_autonomousSysNum */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x09,     /* [2137] OBJ_sbgp_routerIdentifier */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x03,     /* [2145] OBJ_textNotice */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x05,     /* [2153] OBJ_ipsecEndSystem */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x06,     /* [2161] OBJ_ipsecTunnel */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x07,     /* [2169] OBJ_ipsecUser */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x0A,     /* [2177] OBJ_dvcs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x01,     /* [2185] OBJ_id_it_caProtEncCert */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x02,     /* [2193] OBJ_id_it_signKeyPairTypes */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x03,     /* [2201] OBJ_id_it_encKeyPairTypes */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x04,     /* [2209] OBJ_id_it_preferredSymmAlg */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x05,     /* [2217] OBJ_id_it_caKeyUpdateInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x06,     /* [2225] OBJ_id_it_currentCRL */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x07,     /* [2233] OBJ_id_it_unsupportedOIDs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x08,     /* [2241] OBJ_id_it_subscriptionRequest */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x09,     /* [2249] OBJ_id_it_subscriptionResponse */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0A,     /* [2257] OBJ_id_it_keyPairParamReq */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0B,     /* [2265] OBJ_id_it_keyPairParamRep */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0C,     /* [2273] OBJ_id_it_revPassphrase */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0D,     /* [2281] OBJ_id_it_implicitConfirm */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0E,     /* [2289] OBJ_id_it_confirmWaitTime */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0F,     /* [2297] OBJ_id_it_origPKIMessage */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,     /* [2305] OBJ_id_regCtrl */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,     /* [2313] OBJ_id_regInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x01,/* [2321] OBJ_id_regCtrl_regToken */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x02,/* [2330] OBJ_id_regCtrl_authenticator */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x03,/* [2339] OBJ_id_regCtrl_pkiPublicationInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x04,/* [2348] OBJ_id_regCtrl_pkiArchiveOptions */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x05,/* [2357] OBJ_id_regCtrl_oldCertID */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x06,/* [2366] OBJ_id_regCtrl_protocolEncrKey */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x01,/* [2375] OBJ_id_regInfo_utf8Pairs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x02,/* [2384] OBJ_id_regInfo_certReq */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x01,     /* [2393] OBJ_id_alg_des40 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x02,     /* [2401] OBJ_id_alg_noSignature */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x03,     /* [2409] OBJ_id_alg_dh_sig_hmac_sha1 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x04,     /* [2417] OBJ_id_alg_dh_pop */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x01,     /* [2425] OBJ_id_cmc_statusInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x02,     /* [2433] OBJ_id_cmc_identification */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x03,     /* [2441] OBJ_id_cmc_identityProof */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x04,     /* [2449] OBJ_id_cmc_dataReturn */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x05,     /* [2457] OBJ_id_cmc_transactionId */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x06,     /* [2465] OBJ_id_cmc_senderNonce */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x07,     /* [2473] OBJ_id_cmc_recipientNonce */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x08,     /* [2481] OBJ_id_cmc_addExtensions */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x09,     /* [2489] OBJ_id_cmc_encryptedPOP */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0A,     /* [2497] OBJ_id_cmc_decryptedPOP */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0B,     /* [2505] OBJ_id_cmc_lraPOPWitness */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0F,     /* [2513] OBJ_id_cmc_getCert */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x10,     /* [2521] OBJ_id_cmc_getCRL */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x11,     /* [2529] OBJ_id_cmc_revokeRequest */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x12,     /* [2537] OBJ_id_cmc_regInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x13,     /* [2545] OBJ_id_cmc_responseInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x15,     /* [2553] OBJ_id_cmc_queryPending */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x16,     /* [2561] OBJ_id_cmc_popLinkRandom */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x17,     /* [2569] OBJ_id_cmc_popLinkWitness */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x18,     /* [2577] OBJ_id_cmc_confirmCertAcceptance */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x01,     /* [2585] OBJ_id_on_personalData */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x01,     /* [2593] OBJ_id_pda_dateOfBirth */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x02,     /* [2601] OBJ_id_pda_placeOfBirth */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x03,     /* [2609] OBJ_id_pda_gender */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x04,     /* [2617] OBJ_id_pda_countryOfCitizenship */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x05,     /* [2625] OBJ_id_pda_countryOfResidence */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x01,     /* [2633] OBJ_id_aca_authenticationInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x02,     /* [2641] OBJ_id_aca_accessIdentity */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x03,     /* [2649] OBJ_id_aca_chargingIdentity */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x04,     /* [2657] OBJ_id_aca_group */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x05,     /* [2665] OBJ_id_aca_role */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,0x01,     /* [2673] OBJ_id_qcs_pkixQCSyntax_v1 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x01,     /* [2681] OBJ_id_cct_crs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x02,     /* [2689] OBJ_id_cct_PKIData */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x03,     /* [2697] OBJ_id_cct_PKIResponse */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x03,     /* [2705] OBJ_ad_timeStamping */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x04,     /* [2713] OBJ_ad_dvcs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x01,/* [2721] OBJ_id_pkix_OCSP_basic */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x02,/* [2730] OBJ_id_pkix_OCSP_Nonce */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x03,/* [2739] OBJ_id_pkix_OCSP_CrlID */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x04,/* [2748] OBJ_id_pkix_OCSP_acceptableResponses */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05,/* [2757] OBJ_id_pkix_OCSP_noCheck */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x06,/* [2766] OBJ_id_pkix_OCSP_archiveCutoff */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x07,/* [2775] OBJ_id_pkix_OCSP_serviceLocator */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x08,/* [2784] OBJ_id_pkix_OCSP_extendedStatus */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x09,/* [2793] OBJ_id_pkix_OCSP_valid */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0A,/* [2802] OBJ_id_pkix_OCSP_path */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0B,/* [2811] OBJ_id_pkix_OCSP_trustRoot */
+0x2B,0x0E,0x03,0x02,                         /* [2820] OBJ_algorithm */
+0x2B,0x0E,0x03,0x02,0x0B,                    /* [2824] OBJ_rsaSignature */
+0x55,0x08,                                   /* [2829] OBJ_X500algorithms */
+0x2B,                                        /* [2831] OBJ_org */
+0x2B,0x06,                                   /* [2832] OBJ_dod */
+0x2B,0x06,0x01,                              /* [2834] OBJ_iana */
+0x2B,0x06,0x01,0x01,                         /* [2837] OBJ_Directory */
+0x2B,0x06,0x01,0x02,                         /* [2841] OBJ_Management */
+0x2B,0x06,0x01,0x03,                         /* [2845] OBJ_Experimental */
+0x2B,0x06,0x01,0x04,                         /* [2849] OBJ_Private */
+0x2B,0x06,0x01,0x05,                         /* [2853] OBJ_Security */
+0x2B,0x06,0x01,0x06,                         /* [2857] OBJ_SNMPv2 */
+0x2B,0x06,0x01,0x07,                         /* [2861] OBJ_Mail */
+0x2B,0x06,0x01,0x04,0x01,                    /* [2865] OBJ_Enterprises */
+0x2B,0x06,0x01,0x04,0x01,0x8B,0x3A,0x82,0x58,/* [2870] OBJ_dcObject */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,/* [2879] OBJ_domainComponent */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0D,/* [2889] OBJ_Domain */
+0x00,                                        /* [2899] OBJ_joint_iso_ccitt */
+0x55,0x01,0x05,                              /* [2900] OBJ_selected_attribute_types */
+0x55,0x01,0x05,0x37,                         /* [2903] OBJ_clearance */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x03,/* [2907] OBJ_md4WithRSAEncryption */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0A,     /* [2916] OBJ_ac_proxying */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0B,     /* [2924] OBJ_sinfo_access */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x06,     /* [2932] OBJ_id_aca_encAttrs */
+0x55,0x04,0x48,                              /* [2940] OBJ_role */
+0x55,0x1D,0x24,                              /* [2943] OBJ_policy_constraints */
+0x55,0x1D,0x37,                              /* [2946] OBJ_target_information */
+0x55,0x1D,0x38,                              /* [2949] OBJ_no_rev_avail */
+0x00,                                        /* [2952] OBJ_ccitt */
+0x2A,0x86,0x48,0xCE,0x3D,                    /* [2953] OBJ_ansi_X9_62 */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x01,          /* [2958] OBJ_X9_62_prime_field */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,          /* [2965] OBJ_X9_62_characteristic_two_field */
+0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,          /* [2972] OBJ_X9_62_id_ecPublicKey */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01,     /* [2979] OBJ_X9_62_prime192v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02,     /* [2987] OBJ_X9_62_prime192v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03,     /* [2995] OBJ_X9_62_prime192v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04,     /* [3003] OBJ_X9_62_prime239v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05,     /* [3011] OBJ_X9_62_prime239v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06,     /* [3019] OBJ_X9_62_prime239v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,     /* [3027] OBJ_X9_62_prime256v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,          /* [3035] OBJ_ecdsa_with_SHA1 */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x01,/* [3042] OBJ_ms_csp_name */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x01,/* [3051] OBJ_aes_128_ecb */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x02,/* [3060] OBJ_aes_128_cbc */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x03,/* [3069] OBJ_aes_128_ofb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x04,/* [3078] OBJ_aes_128_cfb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x15,/* [3087] OBJ_aes_192_ecb */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x16,/* [3096] OBJ_aes_192_cbc */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x17,/* [3105] OBJ_aes_192_ofb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x18,/* [3114] OBJ_aes_192_cfb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x29,/* [3123] OBJ_aes_256_ecb */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2A,/* [3132] OBJ_aes_256_cbc */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2B,/* [3141] OBJ_aes_256_ofb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2C,/* [3150] OBJ_aes_256_cfb128 */
+0x55,0x1D,0x17,                              /* [3159] OBJ_hold_instruction_code */
+0x2A,0x86,0x48,0xCE,0x38,0x02,0x01,          /* [3162] OBJ_hold_instruction_none */
+0x2A,0x86,0x48,0xCE,0x38,0x02,0x02,          /* [3169] OBJ_hold_instruction_call_issuer */
+0x2A,0x86,0x48,0xCE,0x38,0x02,0x03,          /* [3176] OBJ_hold_instruction_reject */
+0x09,                                        /* [3183] OBJ_data */
+0x09,0x92,0x26,                              /* [3184] OBJ_pss */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,          /* [3187] OBJ_ucl */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,     /* [3194] OBJ_pilot */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,/* [3202] OBJ_pilotAttributeType */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,/* [3211] OBJ_pilotAttributeSyntax */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,/* [3220] OBJ_pilotObjectClass */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x0A,/* [3229] OBJ_pilotGroups */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x04,/* [3238] OBJ_iA5StringSyntax */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x05,/* [3248] OBJ_caseIgnoreIA5StringSyntax */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x03,/* [3258] OBJ_pilotObject */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x04,/* [3268] OBJ_pilotPerson */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x05,/* [3278] OBJ_account */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x06,/* [3288] OBJ_document */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x07,/* [3298] OBJ_room */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x09,/* [3308] OBJ_documentSeries */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0E,/* [3318] OBJ_rFC822localPart */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0F,/* [3328] OBJ_dNSDomain */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x11,/* [3338] OBJ_domainRelatedObject */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x12,/* [3348] OBJ_friendlyCountry */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x13,/* [3358] OBJ_simpleSecurityObject */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x14,/* [3368] OBJ_pilotOrganization */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x15,/* [3378] OBJ_pilotDSA */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x16,/* [3388] OBJ_qualityLabelledData */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01,/* [3398] OBJ_userId */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x02,/* [3408] OBJ_textEncodedORAddress */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x03,/* [3418] OBJ_rfc822Mailbox */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x04,/* [3428] OBJ_info */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x05,/* [3438] OBJ_favouriteDrink */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x06,/* [3448] OBJ_roomNumber */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x07,/* [3458] OBJ_photo */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x08,/* [3468] OBJ_userClass */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x09,/* [3478] OBJ_host */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0A,/* [3488] OBJ_manager */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0B,/* [3498] OBJ_documentIdentifier */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0C,/* [3508] OBJ_documentTitle */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0D,/* [3518] OBJ_documentVersion */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0E,/* [3528] OBJ_documentAuthor */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0F,/* [3538] OBJ_documentLocation */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x14,/* [3548] OBJ_homeTelephoneNumber */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x15,/* [3558] OBJ_secretary */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x16,/* [3568] OBJ_otherMailbox */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x17,/* [3578] OBJ_lastModifiedTime */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x18,/* [3588] OBJ_lastModifiedBy */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1A,/* [3598] OBJ_aRecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1B,/* [3608] OBJ_pilotAttributeType27 */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1C,/* [3618] OBJ_mXRecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1D,/* [3628] OBJ_nSRecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1E,/* [3638] OBJ_sOARecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1F,/* [3648] OBJ_cNAMERecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x25,/* [3658] OBJ_associatedDomain */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x26,/* [3668] OBJ_associatedName */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x27,/* [3678] OBJ_homePostalAddress */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x28,/* [3688] OBJ_personalTitle */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x29,/* [3698] OBJ_mobileTelephoneNumber */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2A,/* [3708] OBJ_pagerTelephoneNumber */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2B,/* [3718] OBJ_friendlyCountryName */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2D,/* [3728] OBJ_organizationalStatus */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2E,/* [3738] OBJ_janetMailbox */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2F,/* [3748] OBJ_mailPreferenceOption */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x30,/* [3758] OBJ_buildingName */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x31,/* [3768] OBJ_dSAQuality */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x32,/* [3778] OBJ_singleLevelQuality */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x33,/* [3788] OBJ_subtreeMinimumQuality */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x34,/* [3798] OBJ_subtreeMaximumQuality */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x35,/* [3808] OBJ_personalSignature */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x36,/* [3818] OBJ_dITRedirect */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x37,/* [3828] OBJ_audio */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x38,/* [3838] OBJ_documentPublisher */
+0x55,0x04,0x2D,                              /* [3848] OBJ_x500UniqueIdentifier */
+0x2B,0x06,0x01,0x07,0x01,                    /* [3851] OBJ_mime_mhs */
+0x2B,0x06,0x01,0x07,0x01,0x01,               /* [3856] OBJ_mime_mhs_headings */
+0x2B,0x06,0x01,0x07,0x01,0x02,               /* [3862] OBJ_mime_mhs_bodies */
+0x2B,0x06,0x01,0x07,0x01,0x01,0x01,          /* [3868] OBJ_id_hex_partial_message */
+0x2B,0x06,0x01,0x07,0x01,0x01,0x02,          /* [3875] OBJ_id_hex_multipart_message */
+0x55,0x04,0x2C,                              /* [3882] OBJ_generationQualifier */
+0x55,0x04,0x41,                              /* [3885] OBJ_pseudonym */
+0x67,0x2A,                                   /* [3888] OBJ_id_set */
+0x67,0x2A,0x00,                              /* [3890] OBJ_set_ctype */
+0x67,0x2A,0x01,                              /* [3893] OBJ_set_msgExt */
+0x67,0x2A,0x03,                              /* [3896] OBJ_set_attr */
+0x67,0x2A,0x05,                              /* [3899] OBJ_set_policy */
+0x67,0x2A,0x07,                              /* [3902] OBJ_set_certExt */
+0x67,0x2A,0x08,                              /* [3905] OBJ_set_brand */
+0x67,0x2A,0x00,0x00,                         /* [3908] OBJ_setct_PANData */
+0x67,0x2A,0x00,0x01,                         /* [3912] OBJ_setct_PANToken */
+0x67,0x2A,0x00,0x02,                         /* [3916] OBJ_setct_PANOnly */
+0x67,0x2A,0x00,0x03,                         /* [3920] OBJ_setct_OIData */
+0x67,0x2A,0x00,0x04,                         /* [3924] OBJ_setct_PI */
+0x67,0x2A,0x00,0x05,                         /* [3928] OBJ_setct_PIData */
+0x67,0x2A,0x00,0x06,                         /* [3932] OBJ_setct_PIDataUnsigned */
+0x67,0x2A,0x00,0x07,                         /* [3936] OBJ_setct_HODInput */
+0x67,0x2A,0x00,0x08,                         /* [3940] OBJ_setct_AuthResBaggage */
+0x67,0x2A,0x00,0x09,                         /* [3944] OBJ_setct_AuthRevReqBaggage */
+0x67,0x2A,0x00,0x0A,                         /* [3948] OBJ_setct_AuthRevResBaggage */
+0x67,0x2A,0x00,0x0B,                         /* [3952] OBJ_setct_CapTokenSeq */
+0x67,0x2A,0x00,0x0C,                         /* [3956] OBJ_setct_PInitResData */
+0x67,0x2A,0x00,0x0D,                         /* [3960] OBJ_setct_PI_TBS */
+0x67,0x2A,0x00,0x0E,                         /* [3964] OBJ_setct_PResData */
+0x67,0x2A,0x00,0x10,                         /* [3968] OBJ_setct_AuthReqTBS */
+0x67,0x2A,0x00,0x11,                         /* [3972] OBJ_setct_AuthResTBS */
+0x67,0x2A,0x00,0x12,                         /* [3976] OBJ_setct_AuthResTBSX */
+0x67,0x2A,0x00,0x13,                         /* [3980] OBJ_setct_AuthTokenTBS */
+0x67,0x2A,0x00,0x14,                         /* [3984] OBJ_setct_CapTokenData */
+0x67,0x2A,0x00,0x15,                         /* [3988] OBJ_setct_CapTokenTBS */
+0x67,0x2A,0x00,0x16,                         /* [3992] OBJ_setct_AcqCardCodeMsg */
+0x67,0x2A,0x00,0x17,                         /* [3996] OBJ_setct_AuthRevReqTBS */
+0x67,0x2A,0x00,0x18,                         /* [4000] OBJ_setct_AuthRevResData */
+0x67,0x2A,0x00,0x19,                         /* [4004] OBJ_setct_AuthRevResTBS */
+0x67,0x2A,0x00,0x1A,                         /* [4008] OBJ_setct_CapReqTBS */
+0x67,0x2A,0x00,0x1B,                         /* [4012] OBJ_setct_CapReqTBSX */
+0x67,0x2A,0x00,0x1C,                         /* [4016] OBJ_setct_CapResData */
+0x67,0x2A,0x00,0x1D,                         /* [4020] OBJ_setct_CapRevReqTBS */
+0x67,0x2A,0x00,0x1E,                         /* [4024] OBJ_setct_CapRevReqTBSX */
+0x67,0x2A,0x00,0x1F,                         /* [4028] OBJ_setct_CapRevResData */
+0x67,0x2A,0x00,0x20,                         /* [4032] OBJ_setct_CredReqTBS */
+0x67,0x2A,0x00,0x21,                         /* [4036] OBJ_setct_CredReqTBSX */
+0x67,0x2A,0x00,0x22,                         /* [4040] OBJ_setct_CredResData */
+0x67,0x2A,0x00,0x23,                         /* [4044] OBJ_setct_CredRevReqTBS */
+0x67,0x2A,0x00,0x24,                         /* [4048] OBJ_setct_CredRevReqTBSX */
+0x67,0x2A,0x00,0x25,                         /* [4052] OBJ_setct_CredRevResData */
+0x67,0x2A,0x00,0x26,                         /* [4056] OBJ_setct_PCertReqData */
+0x67,0x2A,0x00,0x27,                         /* [4060] OBJ_setct_PCertResTBS */
+0x67,0x2A,0x00,0x28,                         /* [4064] OBJ_setct_BatchAdminReqData */
+0x67,0x2A,0x00,0x29,                         /* [4068] OBJ_setct_BatchAdminResData */
+0x67,0x2A,0x00,0x2A,                         /* [4072] OBJ_setct_CardCInitResTBS */
+0x67,0x2A,0x00,0x2B,                         /* [4076] OBJ_setct_MeAqCInitResTBS */
+0x67,0x2A,0x00,0x2C,                         /* [4080] OBJ_setct_RegFormResTBS */
+0x67,0x2A,0x00,0x2D,                         /* [4084] OBJ_setct_CertReqData */
+0x67,0x2A,0x00,0x2E,                         /* [4088] OBJ_setct_CertReqTBS */
+0x67,0x2A,0x00,0x2F,                         /* [4092] OBJ_setct_CertResData */
+0x67,0x2A,0x00,0x30,                         /* [4096] OBJ_setct_CertInqReqTBS */
+0x67,0x2A,0x00,0x31,                         /* [4100] OBJ_setct_ErrorTBS */
+0x67,0x2A,0x00,0x32,                         /* [4104] OBJ_setct_PIDualSignedTBE */
+0x67,0x2A,0x00,0x33,                         /* [4108] OBJ_setct_PIUnsignedTBE */
+0x67,0x2A,0x00,0x34,                         /* [4112] OBJ_setct_AuthReqTBE */
+0x67,0x2A,0x00,0x35,                         /* [4116] OBJ_setct_AuthResTBE */
+0x67,0x2A,0x00,0x36,                         /* [4120] OBJ_setct_AuthResTBEX */
+0x67,0x2A,0x00,0x37,                         /* [4124] OBJ_setct_AuthTokenTBE */
+0x67,0x2A,0x00,0x38,                         /* [4128] OBJ_setct_CapTokenTBE */
+0x67,0x2A,0x00,0x39,                         /* [4132] OBJ_setct_CapTokenTBEX */
+0x67,0x2A,0x00,0x3A,                         /* [4136] OBJ_setct_AcqCardCodeMsgTBE */
+0x67,0x2A,0x00,0x3B,                         /* [4140] OBJ_setct_AuthRevReqTBE */
+0x67,0x2A,0x00,0x3C,                         /* [4144] OBJ_setct_AuthRevResTBE */
+0x67,0x2A,0x00,0x3D,                         /* [4148] OBJ_setct_AuthRevResTBEB */
+0x67,0x2A,0x00,0x3E,                         /* [4152] OBJ_setct_CapReqTBE */
+0x67,0x2A,0x00,0x3F,                         /* [4156] OBJ_setct_CapReqTBEX */
+0x67,0x2A,0x00,0x40,                         /* [4160] OBJ_setct_CapResTBE */
+0x67,0x2A,0x00,0x41,                         /* [4164] OBJ_setct_CapRevReqTBE */
+0x67,0x2A,0x00,0x42,                         /* [4168] OBJ_setct_CapRevReqTBEX */
+0x67,0x2A,0x00,0x43,                         /* [4172] OBJ_setct_CapRevResTBE */
+0x67,0x2A,0x00,0x44,                         /* [4176] OBJ_setct_CredReqTBE */
+0x67,0x2A,0x00,0x45,                         /* [4180] OBJ_setct_CredReqTBEX */
+0x67,0x2A,0x00,0x46,                         /* [4184] OBJ_setct_CredResTBE */
+0x67,0x2A,0x00,0x47,                         /* [4188] OBJ_setct_CredRevReqTBE */
+0x67,0x2A,0x00,0x48,                         /* [4192] OBJ_setct_CredRevReqTBEX */
+0x67,0x2A,0x00,0x49,                         /* [4196] OBJ_setct_CredRevResTBE */
+0x67,0x2A,0x00,0x4A,                         /* [4200] OBJ_setct_BatchAdminReqTBE */
+0x67,0x2A,0x00,0x4B,                         /* [4204] OBJ_setct_BatchAdminResTBE */
+0x67,0x2A,0x00,0x4C,                         /* [4208] OBJ_setct_RegFormReqTBE */
+0x67,0x2A,0x00,0x4D,                         /* [4212] OBJ_setct_CertReqTBE */
+0x67,0x2A,0x00,0x4E,                         /* [4216] OBJ_setct_CertReqTBEX */
+0x67,0x2A,0x00,0x4F,                         /* [4220] OBJ_setct_CertResTBE */
+0x67,0x2A,0x00,0x50,                         /* [4224] OBJ_setct_CRLNotificationTBS */
+0x67,0x2A,0x00,0x51,                         /* [4228] OBJ_setct_CRLNotificationResTBS */
+0x67,0x2A,0x00,0x52,                         /* [4232] OBJ_setct_BCIDistributionTBS */
+0x67,0x2A,0x01,0x01,                         /* [4236] OBJ_setext_genCrypt */
+0x67,0x2A,0x01,0x03,                         /* [4240] OBJ_setext_miAuth */
+0x67,0x2A,0x01,0x04,                         /* [4244] OBJ_setext_pinSecure */
+0x67,0x2A,0x01,0x05,                         /* [4248] OBJ_setext_pinAny */
+0x67,0x2A,0x01,0x07,                         /* [4252] OBJ_setext_track2 */
+0x67,0x2A,0x01,0x08,                         /* [4256] OBJ_setext_cv */
+0x67,0x2A,0x05,0x00,                         /* [4260] OBJ_set_policy_root */
+0x67,0x2A,0x07,0x00,                         /* [4264] OBJ_setCext_hashedRoot */
+0x67,0x2A,0x07,0x01,                         /* [4268] OBJ_setCext_certType */
+0x67,0x2A,0x07,0x02,                         /* [4272] OBJ_setCext_merchData */
+0x67,0x2A,0x07,0x03,                         /* [4276] OBJ_setCext_cCertRequired */
+0x67,0x2A,0x07,0x04,                         /* [4280] OBJ_setCext_tunneling */
+0x67,0x2A,0x07,0x05,                         /* [4284] OBJ_setCext_setExt */
+0x67,0x2A,0x07,0x06,                         /* [4288] OBJ_setCext_setQualf */
+0x67,0x2A,0x07,0x07,                         /* [4292] OBJ_setCext_PGWYcapabilities */
+0x67,0x2A,0x07,0x08,                         /* [4296] OBJ_setCext_TokenIdentifier */
+0x67,0x2A,0x07,0x09,                         /* [4300] OBJ_setCext_Track2Data */
+0x67,0x2A,0x07,0x0A,                         /* [4304] OBJ_setCext_TokenType */
+0x67,0x2A,0x07,0x0B,                         /* [4308] OBJ_setCext_IssuerCapabilities */
+0x67,0x2A,0x03,0x00,                         /* [4312] OBJ_setAttr_Cert */
+0x67,0x2A,0x03,0x01,                         /* [4316] OBJ_setAttr_PGWYcap */
+0x67,0x2A,0x03,0x02,                         /* [4320] OBJ_setAttr_TokenType */
+0x67,0x2A,0x03,0x03,                         /* [4324] OBJ_setAttr_IssCap */
+0x67,0x2A,0x03,0x00,0x00,                    /* [4328] OBJ_set_rootKeyThumb */
+0x67,0x2A,0x03,0x00,0x01,                    /* [4333] OBJ_set_addPolicy */
+0x67,0x2A,0x03,0x02,0x01,                    /* [4338] OBJ_setAttr_Token_EMV */
+0x67,0x2A,0x03,0x02,0x02,                    /* [4343] OBJ_setAttr_Token_B0Prime */
+0x67,0x2A,0x03,0x03,0x03,                    /* [4348] OBJ_setAttr_IssCap_CVM */
+0x67,0x2A,0x03,0x03,0x04,                    /* [4353] OBJ_setAttr_IssCap_T2 */
+0x67,0x2A,0x03,0x03,0x05,                    /* [4358] OBJ_setAttr_IssCap_Sig */
+0x67,0x2A,0x03,0x03,0x03,0x01,               /* [4363] OBJ_setAttr_GenCryptgrm */
+0x67,0x2A,0x03,0x03,0x04,0x01,               /* [4369] OBJ_setAttr_T2Enc */
+0x67,0x2A,0x03,0x03,0x04,0x02,               /* [4375] OBJ_setAttr_T2cleartxt */
+0x67,0x2A,0x03,0x03,0x05,0x01,               /* [4381] OBJ_setAttr_TokICCsig */
+0x67,0x2A,0x03,0x03,0x05,0x02,               /* [4387] OBJ_setAttr_SecDevSig */
+0x67,0x2A,0x08,0x01,                         /* [4393] OBJ_set_brand_IATA_ATA */
+0x67,0x2A,0x08,0x1E,                         /* [4397] OBJ_set_brand_Diners */
+0x67,0x2A,0x08,0x22,                         /* [4401] OBJ_set_brand_AmericanExpress */
+0x67,0x2A,0x08,0x23,                         /* [4405] OBJ_set_brand_JCB */
+0x67,0x2A,0x08,0x04,                         /* [4409] OBJ_set_brand_Visa */
+0x67,0x2A,0x08,0x05,                         /* [4413] OBJ_set_brand_MasterCard */
+0x67,0x2A,0x08,0xAE,0x7B,                    /* [4417] OBJ_set_brand_Novus */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x0A,     /* [4422] OBJ_des_cdmf */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x06,/* [4430] OBJ_rsaOAEPEncryptionSET */
+0x00,                                        /* [4439] OBJ_itu_t */
+0x50,                                        /* [4440] OBJ_joint_iso_itu_t */
+0x67,                                        /* [4441] OBJ_international_organizations */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x02,/* [4442] OBJ_ms_smartcard_login */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x03,/* [4452] OBJ_ms_upn */
+0x55,0x04,0x09,                              /* [4462] OBJ_streetAddress */
+0x55,0x04,0x11,                              /* [4465] OBJ_postalCode */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,          /* [4468] OBJ_id_ppl */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0E,     /* [4475] OBJ_proxyCertInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x00,     /* [4483] OBJ_id_ppl_anyLanguage */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x01,     /* [4491] OBJ_id_ppl_inheritAll */
+0x55,0x1D,0x1E,                              /* [4499] OBJ_name_constraints */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x02,     /* [4502] OBJ_Independent */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,/* [4510] OBJ_sha256WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,/* [4519] OBJ_sha384WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0D,/* [4528] OBJ_sha512WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0E,/* [4537] OBJ_sha224WithRSAEncryption */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,/* [4546] OBJ_sha256 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,/* [4555] OBJ_sha384 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,/* [4564] OBJ_sha512 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,/* [4573] OBJ_sha224 */
+0x2B,                                        /* [4582] OBJ_identified_organization */
+0x2B,0x81,0x04,                              /* [4583] OBJ_certicom_arc */
+0x67,0x2B,                                   /* [4586] OBJ_wap */
+0x67,0x2B,0x01,                              /* [4588] OBJ_wap_wsg */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,     /* [4591] OBJ_X9_62_id_characteristic_two_basis */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x01,/* [4599] OBJ_X9_62_onBasis */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x02,/* [4608] OBJ_X9_62_tpBasis */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x03,/* [4617] OBJ_X9_62_ppBasis */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x01,     /* [4626] OBJ_X9_62_c2pnb163v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x02,     /* [4634] OBJ_X9_62_c2pnb163v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x03,     /* [4642] OBJ_X9_62_c2pnb163v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x04,     /* [4650] OBJ_X9_62_c2pnb176v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x05,     /* [4658] OBJ_X9_62_c2tnb191v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x06,     /* [4666] OBJ_X9_62_c2tnb191v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x07,     /* [4674] OBJ_X9_62_c2tnb191v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x08,     /* [4682] OBJ_X9_62_c2onb191v4 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x09,     /* [4690] OBJ_X9_62_c2onb191v5 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0A,     /* [4698] OBJ_X9_62_c2pnb208w1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0B,     /* [4706] OBJ_X9_62_c2tnb239v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0C,     /* [4714] OBJ_X9_62_c2tnb239v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0D,     /* [4722] OBJ_X9_62_c2tnb239v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0E,     /* [4730] OBJ_X9_62_c2onb239v4 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0F,     /* [4738] OBJ_X9_62_c2onb239v5 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x10,     /* [4746] OBJ_X9_62_c2pnb272w1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x11,     /* [4754] OBJ_X9_62_c2pnb304w1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x12,     /* [4762] OBJ_X9_62_c2tnb359v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x13,     /* [4770] OBJ_X9_62_c2pnb368w1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x14,     /* [4778] OBJ_X9_62_c2tnb431r1 */
+0x2B,0x81,0x04,0x00,0x06,                    /* [4786] OBJ_secp112r1 */
+0x2B,0x81,0x04,0x00,0x07,                    /* [4791] OBJ_secp112r2 */
+0x2B,0x81,0x04,0x00,0x1C,                    /* [4796] OBJ_secp128r1 */
+0x2B,0x81,0x04,0x00,0x1D,                    /* [4801] OBJ_secp128r2 */
+0x2B,0x81,0x04,0x00,0x09,                    /* [4806] OBJ_secp160k1 */
+0x2B,0x81,0x04,0x00,0x08,                    /* [4811] OBJ_secp160r1 */
+0x2B,0x81,0x04,0x00,0x1E,                    /* [4816] OBJ_secp160r2 */
+0x2B,0x81,0x04,0x00,0x1F,                    /* [4821] OBJ_secp192k1 */
+0x2B,0x81,0x04,0x00,0x20,                    /* [4826] OBJ_secp224k1 */
+0x2B,0x81,0x04,0x00,0x21,                    /* [4831] OBJ_secp224r1 */
+0x2B,0x81,0x04,0x00,0x0A,                    /* [4836] OBJ_secp256k1 */
+0x2B,0x81,0x04,0x00,0x22,                    /* [4841] OBJ_secp384r1 */
+0x2B,0x81,0x04,0x00,0x23,                    /* [4846] OBJ_secp521r1 */
+0x2B,0x81,0x04,0x00,0x04,                    /* [4851] OBJ_sect113r1 */
+0x2B,0x81,0x04,0x00,0x05,                    /* [4856] OBJ_sect113r2 */
+0x2B,0x81,0x04,0x00,0x16,                    /* [4861] OBJ_sect131r1 */
+0x2B,0x81,0x04,0x00,0x17,                    /* [4866] OBJ_sect131r2 */
+0x2B,0x81,0x04,0x00,0x01,                    /* [4871] OBJ_sect163k1 */
+0x2B,0x81,0x04,0x00,0x02,                    /* [4876] OBJ_sect163r1 */
+0x2B,0x81,0x04,0x00,0x0F,                    /* [4881] OBJ_sect163r2 */
+0x2B,0x81,0x04,0x00,0x18,                    /* [4886] OBJ_sect193r1 */
+0x2B,0x81,0x04,0x00,0x19,                    /* [4891] OBJ_sect193r2 */
+0x2B,0x81,0x04,0x00,0x1A,                    /* [4896] OBJ_sect233k1 */
+0x2B,0x81,0x04,0x00,0x1B,                    /* [4901] OBJ_sect233r1 */
+0x2B,0x81,0x04,0x00,0x03,                    /* [4906] OBJ_sect239k1 */
+0x2B,0x81,0x04,0x00,0x10,                    /* [4911] OBJ_sect283k1 */
+0x2B,0x81,0x04,0x00,0x11,                    /* [4916] OBJ_sect283r1 */
+0x2B,0x81,0x04,0x00,0x24,                    /* [4921] OBJ_sect409k1 */
+0x2B,0x81,0x04,0x00,0x25,                    /* [4926] OBJ_sect409r1 */
+0x2B,0x81,0x04,0x00,0x26,                    /* [4931] OBJ_sect571k1 */
+0x2B,0x81,0x04,0x00,0x27,                    /* [4936] OBJ_sect571r1 */
+0x67,0x2B,0x01,0x04,0x01,                    /* [4941] OBJ_wap_wsg_idm_ecid_wtls1 */
+0x67,0x2B,0x01,0x04,0x03,                    /* [4946] OBJ_wap_wsg_idm_ecid_wtls3 */
+0x67,0x2B,0x01,0x04,0x04,                    /* [4951] OBJ_wap_wsg_idm_ecid_wtls4 */
+0x67,0x2B,0x01,0x04,0x05,                    /* [4956] OBJ_wap_wsg_idm_ecid_wtls5 */
+0x67,0x2B,0x01,0x04,0x06,                    /* [4961] OBJ_wap_wsg_idm_ecid_wtls6 */
+0x67,0x2B,0x01,0x04,0x07,                    /* [4966] OBJ_wap_wsg_idm_ecid_wtls7 */
+0x67,0x2B,0x01,0x04,0x08,                    /* [4971] OBJ_wap_wsg_idm_ecid_wtls8 */
+0x67,0x2B,0x01,0x04,0x09,                    /* [4976] OBJ_wap_wsg_idm_ecid_wtls9 */
+0x67,0x2B,0x01,0x04,0x0A,                    /* [4981] OBJ_wap_wsg_idm_ecid_wtls10 */
+0x67,0x2B,0x01,0x04,0x0B,                    /* [4986] OBJ_wap_wsg_idm_ecid_wtls11 */
+0x67,0x2B,0x01,0x04,0x0C,                    /* [4991] OBJ_wap_wsg_idm_ecid_wtls12 */
+0x55,0x1D,0x20,0x00,                         /* [4996] OBJ_any_policy */
+0x55,0x1D,0x21,                              /* [5000] OBJ_policy_mappings */
+0x55,0x1D,0x36,                              /* [5003] OBJ_inhibit_any_policy */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x02,/* [5006] OBJ_camellia_128_cbc */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x03,/* [5017] OBJ_camellia_192_cbc */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x04,/* [5028] OBJ_camellia_256_cbc */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x01,     /* [5039] OBJ_camellia_128_ecb */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x15,     /* [5047] OBJ_camellia_192_ecb */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x29,     /* [5055] OBJ_camellia_256_ecb */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x04,     /* [5063] OBJ_camellia_128_cfb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x18,     /* [5071] OBJ_camellia_192_cfb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2C,     /* [5079] OBJ_camellia_256_cfb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x03,     /* [5087] OBJ_camellia_128_ofb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x17,     /* [5095] OBJ_camellia_192_ofb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2B,     /* [5103] OBJ_camellia_256_ofb128 */
+0x55,0x1D,0x09,                              /* [5111] OBJ_subject_directory_attributes */
+0x55,0x1D,0x1C,                              /* [5114] OBJ_issuing_distribution_point */
+0x55,0x1D,0x1D,                              /* [5117] OBJ_certificate_issuer */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,               /* [5120] OBJ_kisa */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x03,     /* [5126] OBJ_seed_ecb */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x04,     /* [5134] OBJ_seed_cbc */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x06,     /* [5142] OBJ_seed_ofb128 */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x05,     /* [5150] OBJ_seed_cfb128 */
+0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x01,     /* [5158] OBJ_hmac_md5 */
+0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x02,     /* [5166] OBJ_hmac_sha1 */
+0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0D,/* [5174] OBJ_id_PasswordBasedMAC */
+0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x1E,/* [5183] OBJ_id_DHBasedMac */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x10,     /* [5192] OBJ_id_it_suppLangTags */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x05,     /* [5200] OBJ_caRepository */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x09,/* [5208] OBJ_id_smime_ct_compressedData */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1B,/* [5219] OBJ_id_ct_asciiTextWithCRLF */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x05,/* [5230] OBJ_id_aes128_wrap */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x19,/* [5239] OBJ_id_aes192_wrap */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2D,/* [5248] OBJ_id_aes256_wrap */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x02,          /* [5257] OBJ_ecdsa_with_Recommended */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,          /* [5264] OBJ_ecdsa_with_Specified */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x01,     /* [5271] OBJ_ecdsa_with_SHA224 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,     /* [5279] OBJ_ecdsa_with_SHA256 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,     /* [5287] OBJ_ecdsa_with_SHA384 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04,     /* [5295] OBJ_ecdsa_with_SHA512 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x06,     /* [5303] OBJ_hmacWithMD5 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x08,     /* [5311] OBJ_hmacWithSHA224 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x09,     /* [5319] OBJ_hmacWithSHA256 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0A,     /* [5327] OBJ_hmacWithSHA384 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0B,     /* [5335] OBJ_hmacWithSHA512 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x01,/* [5343] OBJ_dsa_with_SHA224 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x02,/* [5352] OBJ_dsa_with_SHA256 */
+0x28,0xCF,0x06,0x03,0x00,0x37,               /* [5361] OBJ_whirlpool */
+0x2A,0x85,0x03,0x02,0x02,                    /* [5367] OBJ_cryptopro */
+0x2A,0x85,0x03,0x02,0x09,                    /* [5372] OBJ_cryptocom */
+0x2A,0x85,0x03,0x02,0x02,0x03,               /* [5377] OBJ_id_GostR3411_94_with_GostR3410_2001 */
+0x2A,0x85,0x03,0x02,0x02,0x04,               /* [5383] OBJ_id_GostR3411_94_with_GostR3410_94 */
+0x2A,0x85,0x03,0x02,0x02,0x09,               /* [5389] OBJ_id_GostR3411_94 */
+0x2A,0x85,0x03,0x02,0x02,0x0A,               /* [5395] OBJ_id_HMACGostR3411_94 */
+0x2A,0x85,0x03,0x02,0x02,0x13,               /* [5401] OBJ_id_GostR3410_2001 */
+0x2A,0x85,0x03,0x02,0x02,0x14,               /* [5407] OBJ_id_GostR3410_94 */
+0x2A,0x85,0x03,0x02,0x02,0x15,               /* [5413] OBJ_id_Gost28147_89 */
+0x2A,0x85,0x03,0x02,0x02,0x16,               /* [5419] OBJ_id_Gost28147_89_MAC */
+0x2A,0x85,0x03,0x02,0x02,0x17,               /* [5425] OBJ_id_GostR3411_94_prf */
+0x2A,0x85,0x03,0x02,0x02,0x62,               /* [5431] OBJ_id_GostR3410_2001DH */
+0x2A,0x85,0x03,0x02,0x02,0x63,               /* [5437] OBJ_id_GostR3410_94DH */
+0x2A,0x85,0x03,0x02,0x02,0x0E,0x01,          /* [5443] OBJ_id_Gost28147_89_CryptoPro_KeyMeshing */
+0x2A,0x85,0x03,0x02,0x02,0x0E,0x00,          /* [5450] OBJ_id_Gost28147_89_None_KeyMeshing */
+0x2A,0x85,0x03,0x02,0x02,0x1E,0x00,          /* [5457] OBJ_id_GostR3411_94_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1E,0x01,          /* [5464] OBJ_id_GostR3411_94_CryptoProParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x00,          /* [5471] OBJ_id_Gost28147_89_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x01,          /* [5478] OBJ_id_Gost28147_89_CryptoPro_A_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x02,          /* [5485] OBJ_id_Gost28147_89_CryptoPro_B_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x03,          /* [5492] OBJ_id_Gost28147_89_CryptoPro_C_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x04,          /* [5499] OBJ_id_Gost28147_89_CryptoPro_D_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x05,          /* [5506] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x06,          /* [5513] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x07,          /* [5520] OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x00,          /* [5527] OBJ_id_GostR3410_94_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x02,          /* [5534] OBJ_id_GostR3410_94_CryptoPro_A_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x03,          /* [5541] OBJ_id_GostR3410_94_CryptoPro_B_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x04,          /* [5548] OBJ_id_GostR3410_94_CryptoPro_C_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x05,          /* [5555] OBJ_id_GostR3410_94_CryptoPro_D_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x21,0x01,          /* [5562] OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x21,0x02,          /* [5569] OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x21,0x03,          /* [5576] OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x00,          /* [5583] OBJ_id_GostR3410_2001_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x01,          /* [5590] OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x02,          /* [5597] OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x03,          /* [5604] OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x24,0x00,          /* [5611] OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x24,0x01,          /* [5618] OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x01,          /* [5625] OBJ_id_GostR3410_94_a */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x02,          /* [5632] OBJ_id_GostR3410_94_aBis */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x03,          /* [5639] OBJ_id_GostR3410_94_b */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x04,          /* [5646] OBJ_id_GostR3410_94_bBis */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x06,0x01,     /* [5653] OBJ_id_Gost28147_89_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x03,     /* [5661] OBJ_id_GostR3410_94_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x04,     /* [5669] OBJ_id_GostR3410_2001_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x03,     /* [5677] OBJ_id_GostR3411_94_with_GostR3410_94_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x04,     /* [5685] OBJ_id_GostR3411_94_with_GostR3410_2001_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x08,0x01,     /* [5693] OBJ_id_GostR3410_2001_ParamSet_cc */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x02,/* [5701] OBJ_LocalKeySet */
+0x55,0x1D,0x2E,                              /* [5710] OBJ_freshest_crl */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x03,     /* [5713] OBJ_id_on_permanentIdentifier */
+0x55,0x04,0x0E,                              /* [5721] OBJ_searchGuide */
+0x55,0x04,0x0F,                              /* [5724] OBJ_businessCategory */
+0x55,0x04,0x10,                              /* [5727] OBJ_postalAddress */
+0x55,0x04,0x12,                              /* [5730] OBJ_postOfficeBox */
+0x55,0x04,0x13,                              /* [5733] OBJ_physicalDeliveryOfficeName */
+0x55,0x04,0x14,                              /* [5736] OBJ_telephoneNumber */
+0x55,0x04,0x15,                              /* [5739] OBJ_telexNumber */
+0x55,0x04,0x16,                              /* [5742] OBJ_teletexTerminalIdentifier */
+0x55,0x04,0x17,                              /* [5745] OBJ_facsimileTelephoneNumber */
+0x55,0x04,0x18,                              /* [5748] OBJ_x121Address */
+0x55,0x04,0x19,                              /* [5751] OBJ_internationaliSDNNumber */
+0x55,0x04,0x1A,                              /* [5754] OBJ_registeredAddress */
+0x55,0x04,0x1B,                              /* [5757] OBJ_destinationIndicator */
+0x55,0x04,0x1C,                              /* [5760] OBJ_preferredDeliveryMethod */
+0x55,0x04,0x1D,                              /* [5763] OBJ_presentationAddress */
+0x55,0x04,0x1E,                              /* [5766] OBJ_supportedApplicationContext */
+0x55,0x04,0x1F,                              /* [5769] OBJ_member */
+0x55,0x04,0x20,                              /* [5772] OBJ_owner */
+0x55,0x04,0x21,                              /* [5775] OBJ_roleOccupant */
+0x55,0x04,0x22,                              /* [5778] OBJ_seeAlso */
+0x55,0x04,0x23,                              /* [5781] OBJ_userPassword */
+0x55,0x04,0x24,                              /* [5784] OBJ_userCertificate */
+0x55,0x04,0x25,                              /* [5787] OBJ_cACertificate */
+0x55,0x04,0x26,                              /* [5790] OBJ_authorityRevocationList */
+0x55,0x04,0x27,                              /* [5793] OBJ_certificateRevocationList */
+0x55,0x04,0x28,                              /* [5796] OBJ_crossCertificatePair */
+0x55,0x04,0x2F,                              /* [5799] OBJ_enhancedSearchGuide */
+0x55,0x04,0x30,                              /* [5802] OBJ_protocolInformation */
+0x55,0x04,0x31,                              /* [5805] OBJ_distinguishedName */
+0x55,0x04,0x32,                              /* [5808] OBJ_uniqueMember */
+0x55,0x04,0x33,                              /* [5811] OBJ_houseIdentifier */
+0x55,0x04,0x34,                              /* [5814] OBJ_supportedAlgorithms */
+0x55,0x04,0x35,                              /* [5817] OBJ_deltaRevocationList */
+0x55,0x04,0x36,                              /* [5820] OBJ_dmdName */
+};
+
+static const ASN1_OBJECT nid_objs[NUM_NID]={
+{"UNDEF","undefined",NID_undef,1,&(lvalues[0]),0},
+{"rsadsi","RSA Data Security, Inc.",NID_rsadsi,6,&(lvalues[1]),0},
+{"pkcs","RSA Data Security, Inc. PKCS",NID_pkcs,7,&(lvalues[7]),0},
+{"MD2","md2",NID_md2,8,&(lvalues[14]),0},
+{"MD5","md5",NID_md5,8,&(lvalues[22]),0},
+{"RC4","rc4",NID_rc4,8,&(lvalues[30]),0},
+{"rsaEncryption","rsaEncryption",NID_rsaEncryption,9,&(lvalues[38]),0},
+{"RSA-MD2","md2WithRSAEncryption",NID_md2WithRSAEncryption,9,
+	&(lvalues[47]),0},
+{"RSA-MD5","md5WithRSAEncryption",NID_md5WithRSAEncryption,9,
+	&(lvalues[56]),0},
+{"PBE-MD2-DES","pbeWithMD2AndDES-CBC",NID_pbeWithMD2AndDES_CBC,9,
+	&(lvalues[65]),0},
+{"PBE-MD5-DES","pbeWithMD5AndDES-CBC",NID_pbeWithMD5AndDES_CBC,9,
+	&(lvalues[74]),0},
+{"X500","directory services (X.500)",NID_X500,1,&(lvalues[83]),0},
+{"X509","X509",NID_X509,2,&(lvalues[84]),0},
+{"CN","commonName",NID_commonName,3,&(lvalues[86]),0},
+{"C","countryName",NID_countryName,3,&(lvalues[89]),0},
+{"L","localityName",NID_localityName,3,&(lvalues[92]),0},
+{"ST","stateOrProvinceName",NID_stateOrProvinceName,3,&(lvalues[95]),0},
+{"O","organizationName",NID_organizationName,3,&(lvalues[98]),0},
+{"OU","organizationalUnitName",NID_organizationalUnitName,3,
+	&(lvalues[101]),0},
+{"RSA","rsa",NID_rsa,4,&(lvalues[104]),0},
+{"pkcs7","pkcs7",NID_pkcs7,8,&(lvalues[108]),0},
+{"pkcs7-data","pkcs7-data",NID_pkcs7_data,9,&(lvalues[116]),0},
+{"pkcs7-signedData","pkcs7-signedData",NID_pkcs7_signed,9,
+	&(lvalues[125]),0},
+{"pkcs7-envelopedData","pkcs7-envelopedData",NID_pkcs7_enveloped,9,
+	&(lvalues[134]),0},
+{"pkcs7-signedAndEnvelopedData","pkcs7-signedAndEnvelopedData",
+	NID_pkcs7_signedAndEnveloped,9,&(lvalues[143]),0},
+{"pkcs7-digestData","pkcs7-digestData",NID_pkcs7_digest,9,
+	&(lvalues[152]),0},
+{"pkcs7-encryptedData","pkcs7-encryptedData",NID_pkcs7_encrypted,9,
+	&(lvalues[161]),0},
+{"pkcs3","pkcs3",NID_pkcs3,8,&(lvalues[170]),0},
+{"dhKeyAgreement","dhKeyAgreement",NID_dhKeyAgreement,9,
+	&(lvalues[178]),0},
+{"DES-ECB","des-ecb",NID_des_ecb,5,&(lvalues[187]),0},
+{"DES-CFB","des-cfb",NID_des_cfb64,5,&(lvalues[192]),0},
+{"DES-CBC","des-cbc",NID_des_cbc,5,&(lvalues[197]),0},
+{"DES-EDE","des-ede",NID_des_ede_ecb,5,&(lvalues[202]),0},
+{"DES-EDE3","des-ede3",NID_des_ede3_ecb,0,NULL,0},
+{"IDEA-CBC","idea-cbc",NID_idea_cbc,11,&(lvalues[207]),0},
+{"IDEA-CFB","idea-cfb",NID_idea_cfb64,0,NULL,0},
+{"IDEA-ECB","idea-ecb",NID_idea_ecb,0,NULL,0},
+{"RC2-CBC","rc2-cbc",NID_rc2_cbc,8,&(lvalues[218]),0},
+{"RC2-ECB","rc2-ecb",NID_rc2_ecb,0,NULL,0},
+{"RC2-CFB","rc2-cfb",NID_rc2_cfb64,0,NULL,0},
+{"RC2-OFB","rc2-ofb",NID_rc2_ofb64,0,NULL,0},
+{"SHA","sha",NID_sha,5,&(lvalues[226]),0},
+{"RSA-SHA","shaWithRSAEncryption",NID_shaWithRSAEncryption,5,
+	&(lvalues[231]),0},
+{"DES-EDE-CBC","des-ede-cbc",NID_des_ede_cbc,0,NULL,0},
+{"DES-EDE3-CBC","des-ede3-cbc",NID_des_ede3_cbc,8,&(lvalues[236]),0},
+{"DES-OFB","des-ofb",NID_des_ofb64,5,&(lvalues[244]),0},
+{"IDEA-OFB","idea-ofb",NID_idea_ofb64,0,NULL,0},
+{"pkcs9","pkcs9",NID_pkcs9,8,&(lvalues[249]),0},
+{"emailAddress","emailAddress",NID_pkcs9_emailAddress,9,
+	&(lvalues[257]),0},
+{"unstructuredName","unstructuredName",NID_pkcs9_unstructuredName,9,
+	&(lvalues[266]),0},
+{"contentType","contentType",NID_pkcs9_contentType,9,&(lvalues[275]),0},
+{"messageDigest","messageDigest",NID_pkcs9_messageDigest,9,
+	&(lvalues[284]),0},
+{"signingTime","signingTime",NID_pkcs9_signingTime,9,&(lvalues[293]),0},
+{"countersignature","countersignature",NID_pkcs9_countersignature,9,
+	&(lvalues[302]),0},
+{"challengePassword","challengePassword",NID_pkcs9_challengePassword,
+	9,&(lvalues[311]),0},
+{"unstructuredAddress","unstructuredAddress",
+	NID_pkcs9_unstructuredAddress,9,&(lvalues[320]),0},
+{"extendedCertificateAttributes","extendedCertificateAttributes",
+	NID_pkcs9_extCertAttributes,9,&(lvalues[329]),0},
+{"Netscape","Netscape Communications Corp.",NID_netscape,7,
+	&(lvalues[338]),0},
+{"nsCertExt","Netscape Certificate Extension",
+	NID_netscape_cert_extension,8,&(lvalues[345]),0},
+{"nsDataType","Netscape Data Type",NID_netscape_data_type,8,
+	&(lvalues[353]),0},
+{"DES-EDE-CFB","des-ede-cfb",NID_des_ede_cfb64,0,NULL,0},
+{"DES-EDE3-CFB","des-ede3-cfb",NID_des_ede3_cfb64,0,NULL,0},
+{"DES-EDE-OFB","des-ede-ofb",NID_des_ede_ofb64,0,NULL,0},
+{"DES-EDE3-OFB","des-ede3-ofb",NID_des_ede3_ofb64,0,NULL,0},
+{"SHA1","sha1",NID_sha1,5,&(lvalues[361]),0},
+{"RSA-SHA1","sha1WithRSAEncryption",NID_sha1WithRSAEncryption,9,
+	&(lvalues[366]),0},
+{"DSA-SHA","dsaWithSHA",NID_dsaWithSHA,5,&(lvalues[375]),0},
+{"DSA-old","dsaEncryption-old",NID_dsa_2,5,&(lvalues[380]),0},
+{"PBE-SHA1-RC2-64","pbeWithSHA1AndRC2-CBC",NID_pbeWithSHA1AndRC2_CBC,
+	9,&(lvalues[385]),0},
+{"PBKDF2","PBKDF2",NID_id_pbkdf2,9,&(lvalues[394]),0},
+{"DSA-SHA1-old","dsaWithSHA1-old",NID_dsaWithSHA1_2,5,&(lvalues[403]),0},
+{"nsCertType","Netscape Cert Type",NID_netscape_cert_type,9,
+	&(lvalues[408]),0},
+{"nsBaseUrl","Netscape Base Url",NID_netscape_base_url,9,
+	&(lvalues[417]),0},
+{"nsRevocationUrl","Netscape Revocation Url",
+	NID_netscape_revocation_url,9,&(lvalues[426]),0},
+{"nsCaRevocationUrl","Netscape CA Revocation Url",
+	NID_netscape_ca_revocation_url,9,&(lvalues[435]),0},
+{"nsRenewalUrl","Netscape Renewal Url",NID_netscape_renewal_url,9,
+	&(lvalues[444]),0},
+{"nsCaPolicyUrl","Netscape CA Policy Url",NID_netscape_ca_policy_url,
+	9,&(lvalues[453]),0},
+{"nsSslServerName","Netscape SSL Server Name",
+	NID_netscape_ssl_server_name,9,&(lvalues[462]),0},
+{"nsComment","Netscape Comment",NID_netscape_comment,9,&(lvalues[471]),0},
+{"nsCertSequence","Netscape Certificate Sequence",
+	NID_netscape_cert_sequence,9,&(lvalues[480]),0},
+{"DESX-CBC","desx-cbc",NID_desx_cbc,0,NULL,0},
+{"id-ce","id-ce",NID_id_ce,2,&(lvalues[489]),0},
+{"subjectKeyIdentifier","X509v3 Subject Key Identifier",
+	NID_subject_key_identifier,3,&(lvalues[491]),0},
+{"keyUsage","X509v3 Key Usage",NID_key_usage,3,&(lvalues[494]),0},
+{"privateKeyUsagePeriod","X509v3 Private Key Usage Period",
+	NID_private_key_usage_period,3,&(lvalues[497]),0},
+{"subjectAltName","X509v3 Subject Alternative Name",
+	NID_subject_alt_name,3,&(lvalues[500]),0},
+{"issuerAltName","X509v3 Issuer Alternative Name",NID_issuer_alt_name,
+	3,&(lvalues[503]),0},
+{"basicConstraints","X509v3 Basic Constraints",NID_basic_constraints,
+	3,&(lvalues[506]),0},
+{"crlNumber","X509v3 CRL Number",NID_crl_number,3,&(lvalues[509]),0},
+{"certificatePolicies","X509v3 Certificate Policies",
+	NID_certificate_policies,3,&(lvalues[512]),0},
+{"authorityKeyIdentifier","X509v3 Authority Key Identifier",
+	NID_authority_key_identifier,3,&(lvalues[515]),0},
+{"BF-CBC","bf-cbc",NID_bf_cbc,9,&(lvalues[518]),0},
+{"BF-ECB","bf-ecb",NID_bf_ecb,0,NULL,0},
+{"BF-CFB","bf-cfb",NID_bf_cfb64,0,NULL,0},
+{"BF-OFB","bf-ofb",NID_bf_ofb64,0,NULL,0},
+{"MDC2","mdc2",NID_mdc2,4,&(lvalues[527]),0},
+{"RSA-MDC2","mdc2WithRSA",NID_mdc2WithRSA,4,&(lvalues[531]),0},
+{"RC4-40","rc4-40",NID_rc4_40,0,NULL,0},
+{"RC2-40-CBC","rc2-40-cbc",NID_rc2_40_cbc,0,NULL,0},
+{"GN","givenName",NID_givenName,3,&(lvalues[535]),0},
+{"SN","surname",NID_surname,3,&(lvalues[538]),0},
+{"initials","initials",NID_initials,3,&(lvalues[541]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"crlDistributionPoints","X509v3 CRL Distribution Points",
+	NID_crl_distribution_points,3,&(lvalues[544]),0},
+{"RSA-NP-MD5","md5WithRSA",NID_md5WithRSA,5,&(lvalues[547]),0},
+{"serialNumber","serialNumber",NID_serialNumber,3,&(lvalues[552]),0},
+{"title","title",NID_title,3,&(lvalues[555]),0},
+{"description","description",NID_description,3,&(lvalues[558]),0},
+{"CAST5-CBC","cast5-cbc",NID_cast5_cbc,9,&(lvalues[561]),0},
+{"CAST5-ECB","cast5-ecb",NID_cast5_ecb,0,NULL,0},
+{"CAST5-CFB","cast5-cfb",NID_cast5_cfb64,0,NULL,0},
+{"CAST5-OFB","cast5-ofb",NID_cast5_ofb64,0,NULL,0},
+{"pbeWithMD5AndCast5CBC","pbeWithMD5AndCast5CBC",
+	NID_pbeWithMD5AndCast5_CBC,9,&(lvalues[570]),0},
+{"DSA-SHA1","dsaWithSHA1",NID_dsaWithSHA1,7,&(lvalues[579]),0},
+{"MD5-SHA1","md5-sha1",NID_md5_sha1,0,NULL,0},
+{"RSA-SHA1-2","sha1WithRSA",NID_sha1WithRSA,5,&(lvalues[586]),0},
+{"DSA","dsaEncryption",NID_dsa,7,&(lvalues[591]),0},
+{"RIPEMD160","ripemd160",NID_ripemd160,5,&(lvalues[598]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"RSA-RIPEMD160","ripemd160WithRSA",NID_ripemd160WithRSA,6,
+	&(lvalues[603]),0},
+{"RC5-CBC","rc5-cbc",NID_rc5_cbc,8,&(lvalues[609]),0},
+{"RC5-ECB","rc5-ecb",NID_rc5_ecb,0,NULL,0},
+{"RC5-CFB","rc5-cfb",NID_rc5_cfb64,0,NULL,0},
+{"RC5-OFB","rc5-ofb",NID_rc5_ofb64,0,NULL,0},
+{"RLE","run length compression",NID_rle_compression,6,&(lvalues[617]),0},
+{"ZLIB","zlib compression",NID_zlib_compression,11,&(lvalues[623]),0},
+{"extendedKeyUsage","X509v3 Extended Key Usage",NID_ext_key_usage,3,
+	&(lvalues[634]),0},
+{"PKIX","PKIX",NID_id_pkix,6,&(lvalues[637]),0},
+{"id-kp","id-kp",NID_id_kp,7,&(lvalues[643]),0},
+{"serverAuth","TLS Web Server Authentication",NID_server_auth,8,
+	&(lvalues[650]),0},
+{"clientAuth","TLS Web Client Authentication",NID_client_auth,8,
+	&(lvalues[658]),0},
+{"codeSigning","Code Signing",NID_code_sign,8,&(lvalues[666]),0},
+{"emailProtection","E-mail Protection",NID_email_protect,8,
+	&(lvalues[674]),0},
+{"timeStamping","Time Stamping",NID_time_stamp,8,&(lvalues[682]),0},
+{"msCodeInd","Microsoft Individual Code Signing",NID_ms_code_ind,10,
+	&(lvalues[690]),0},
+{"msCodeCom","Microsoft Commercial Code Signing",NID_ms_code_com,10,
+	&(lvalues[700]),0},
+{"msCTLSign","Microsoft Trust List Signing",NID_ms_ctl_sign,10,
+	&(lvalues[710]),0},
+{"msSGC","Microsoft Server Gated Crypto",NID_ms_sgc,10,&(lvalues[720]),0},
+{"msEFS","Microsoft Encrypted File System",NID_ms_efs,10,
+	&(lvalues[730]),0},
+{"nsSGC","Netscape Server Gated Crypto",NID_ns_sgc,9,&(lvalues[740]),0},
+{"deltaCRL","X509v3 Delta CRL Indicator",NID_delta_crl,3,
+	&(lvalues[749]),0},
+{"CRLReason","X509v3 CRL Reason Code",NID_crl_reason,3,&(lvalues[752]),0},
+{"invalidityDate","Invalidity Date",NID_invalidity_date,3,
+	&(lvalues[755]),0},
+{"SXNetID","Strong Extranet ID",NID_sxnet,5,&(lvalues[758]),0},
+{"PBE-SHA1-RC4-128","pbeWithSHA1And128BitRC4",
+	NID_pbe_WithSHA1And128BitRC4,10,&(lvalues[763]),0},
+{"PBE-SHA1-RC4-40","pbeWithSHA1And40BitRC4",
+	NID_pbe_WithSHA1And40BitRC4,10,&(lvalues[773]),0},
+{"PBE-SHA1-3DES","pbeWithSHA1And3-KeyTripleDES-CBC",
+	NID_pbe_WithSHA1And3_Key_TripleDES_CBC,10,&(lvalues[783]),0},
+{"PBE-SHA1-2DES","pbeWithSHA1And2-KeyTripleDES-CBC",
+	NID_pbe_WithSHA1And2_Key_TripleDES_CBC,10,&(lvalues[793]),0},
+{"PBE-SHA1-RC2-128","pbeWithSHA1And128BitRC2-CBC",
+	NID_pbe_WithSHA1And128BitRC2_CBC,10,&(lvalues[803]),0},
+{"PBE-SHA1-RC2-40","pbeWithSHA1And40BitRC2-CBC",
+	NID_pbe_WithSHA1And40BitRC2_CBC,10,&(lvalues[813]),0},
+{"keyBag","keyBag",NID_keyBag,11,&(lvalues[823]),0},
+{"pkcs8ShroudedKeyBag","pkcs8ShroudedKeyBag",NID_pkcs8ShroudedKeyBag,
+	11,&(lvalues[834]),0},
+{"certBag","certBag",NID_certBag,11,&(lvalues[845]),0},
+{"crlBag","crlBag",NID_crlBag,11,&(lvalues[856]),0},
+{"secretBag","secretBag",NID_secretBag,11,&(lvalues[867]),0},
+{"safeContentsBag","safeContentsBag",NID_safeContentsBag,11,
+	&(lvalues[878]),0},
+{"friendlyName","friendlyName",NID_friendlyName,9,&(lvalues[889]),0},
+{"localKeyID","localKeyID",NID_localKeyID,9,&(lvalues[898]),0},
+{"x509Certificate","x509Certificate",NID_x509Certificate,10,
+	&(lvalues[907]),0},
+{"sdsiCertificate","sdsiCertificate",NID_sdsiCertificate,10,
+	&(lvalues[917]),0},
+{"x509Crl","x509Crl",NID_x509Crl,10,&(lvalues[927]),0},
+{"PBES2","PBES2",NID_pbes2,9,&(lvalues[937]),0},
+{"PBMAC1","PBMAC1",NID_pbmac1,9,&(lvalues[946]),0},
+{"hmacWithSHA1","hmacWithSHA1",NID_hmacWithSHA1,8,&(lvalues[955]),0},
+{"id-qt-cps","Policy Qualifier CPS",NID_id_qt_cps,8,&(lvalues[963]),0},
+{"id-qt-unotice","Policy Qualifier User Notice",NID_id_qt_unotice,8,
+	&(lvalues[971]),0},
+{"RC2-64-CBC","rc2-64-cbc",NID_rc2_64_cbc,0,NULL,0},
+{"SMIME-CAPS","S/MIME Capabilities",NID_SMIMECapabilities,9,
+	&(lvalues[979]),0},
+{"PBE-MD2-RC2-64","pbeWithMD2AndRC2-CBC",NID_pbeWithMD2AndRC2_CBC,9,
+	&(lvalues[988]),0},
+{"PBE-MD5-RC2-64","pbeWithMD5AndRC2-CBC",NID_pbeWithMD5AndRC2_CBC,9,
+	&(lvalues[997]),0},
+{"PBE-SHA1-DES","pbeWithSHA1AndDES-CBC",NID_pbeWithSHA1AndDES_CBC,9,
+	&(lvalues[1006]),0},
+{"msExtReq","Microsoft Extension Request",NID_ms_ext_req,10,
+	&(lvalues[1015]),0},
+{"extReq","Extension Request",NID_ext_req,9,&(lvalues[1025]),0},
+{"name","name",NID_name,3,&(lvalues[1034]),0},
+{"dnQualifier","dnQualifier",NID_dnQualifier,3,&(lvalues[1037]),0},
+{"id-pe","id-pe",NID_id_pe,7,&(lvalues[1040]),0},
+{"id-ad","id-ad",NID_id_ad,7,&(lvalues[1047]),0},
+{"authorityInfoAccess","Authority Information Access",NID_info_access,
+	8,&(lvalues[1054]),0},
+{"OCSP","OCSP",NID_ad_OCSP,8,&(lvalues[1062]),0},
+{"caIssuers","CA Issuers",NID_ad_ca_issuers,8,&(lvalues[1070]),0},
+{"OCSPSigning","OCSP Signing",NID_OCSP_sign,8,&(lvalues[1078]),0},
+{"ISO","iso",NID_iso,1,&(lvalues[1086]),0},
+{"member-body","ISO Member Body",NID_member_body,1,&(lvalues[1087]),0},
+{"ISO-US","ISO US Member Body",NID_ISO_US,3,&(lvalues[1088]),0},
+{"X9-57","X9.57",NID_X9_57,5,&(lvalues[1091]),0},
+{"X9cm","X9.57 CM ?",NID_X9cm,6,&(lvalues[1096]),0},
+{"pkcs1","pkcs1",NID_pkcs1,8,&(lvalues[1102]),0},
+{"pkcs5","pkcs5",NID_pkcs5,8,&(lvalues[1110]),0},
+{"SMIME","S/MIME",NID_SMIME,9,&(lvalues[1118]),0},
+{"id-smime-mod","id-smime-mod",NID_id_smime_mod,10,&(lvalues[1127]),0},
+{"id-smime-ct","id-smime-ct",NID_id_smime_ct,10,&(lvalues[1137]),0},
+{"id-smime-aa","id-smime-aa",NID_id_smime_aa,10,&(lvalues[1147]),0},
+{"id-smime-alg","id-smime-alg",NID_id_smime_alg,10,&(lvalues[1157]),0},
+{"id-smime-cd","id-smime-cd",NID_id_smime_cd,10,&(lvalues[1167]),0},
+{"id-smime-spq","id-smime-spq",NID_id_smime_spq,10,&(lvalues[1177]),0},
+{"id-smime-cti","id-smime-cti",NID_id_smime_cti,10,&(lvalues[1187]),0},
+{"id-smime-mod-cms","id-smime-mod-cms",NID_id_smime_mod_cms,11,
+	&(lvalues[1197]),0},
+{"id-smime-mod-ess","id-smime-mod-ess",NID_id_smime_mod_ess,11,
+	&(lvalues[1208]),0},
+{"id-smime-mod-oid","id-smime-mod-oid",NID_id_smime_mod_oid,11,
+	&(lvalues[1219]),0},
+{"id-smime-mod-msg-v3","id-smime-mod-msg-v3",NID_id_smime_mod_msg_v3,
+	11,&(lvalues[1230]),0},
+{"id-smime-mod-ets-eSignature-88","id-smime-mod-ets-eSignature-88",
+	NID_id_smime_mod_ets_eSignature_88,11,&(lvalues[1241]),0},
+{"id-smime-mod-ets-eSignature-97","id-smime-mod-ets-eSignature-97",
+	NID_id_smime_mod_ets_eSignature_97,11,&(lvalues[1252]),0},
+{"id-smime-mod-ets-eSigPolicy-88","id-smime-mod-ets-eSigPolicy-88",
+	NID_id_smime_mod_ets_eSigPolicy_88,11,&(lvalues[1263]),0},
+{"id-smime-mod-ets-eSigPolicy-97","id-smime-mod-ets-eSigPolicy-97",
+	NID_id_smime_mod_ets_eSigPolicy_97,11,&(lvalues[1274]),0},
+{"id-smime-ct-receipt","id-smime-ct-receipt",NID_id_smime_ct_receipt,
+	11,&(lvalues[1285]),0},
+{"id-smime-ct-authData","id-smime-ct-authData",
+	NID_id_smime_ct_authData,11,&(lvalues[1296]),0},
+{"id-smime-ct-publishCert","id-smime-ct-publishCert",
+	NID_id_smime_ct_publishCert,11,&(lvalues[1307]),0},
+{"id-smime-ct-TSTInfo","id-smime-ct-TSTInfo",NID_id_smime_ct_TSTInfo,
+	11,&(lvalues[1318]),0},
+{"id-smime-ct-TDTInfo","id-smime-ct-TDTInfo",NID_id_smime_ct_TDTInfo,
+	11,&(lvalues[1329]),0},
+{"id-smime-ct-contentInfo","id-smime-ct-contentInfo",
+	NID_id_smime_ct_contentInfo,11,&(lvalues[1340]),0},
+{"id-smime-ct-DVCSRequestData","id-smime-ct-DVCSRequestData",
+	NID_id_smime_ct_DVCSRequestData,11,&(lvalues[1351]),0},
+{"id-smime-ct-DVCSResponseData","id-smime-ct-DVCSResponseData",
+	NID_id_smime_ct_DVCSResponseData,11,&(lvalues[1362]),0},
+{"id-smime-aa-receiptRequest","id-smime-aa-receiptRequest",
+	NID_id_smime_aa_receiptRequest,11,&(lvalues[1373]),0},
+{"id-smime-aa-securityLabel","id-smime-aa-securityLabel",
+	NID_id_smime_aa_securityLabel,11,&(lvalues[1384]),0},
+{"id-smime-aa-mlExpandHistory","id-smime-aa-mlExpandHistory",
+	NID_id_smime_aa_mlExpandHistory,11,&(lvalues[1395]),0},
+{"id-smime-aa-contentHint","id-smime-aa-contentHint",
+	NID_id_smime_aa_contentHint,11,&(lvalues[1406]),0},
+{"id-smime-aa-msgSigDigest","id-smime-aa-msgSigDigest",
+	NID_id_smime_aa_msgSigDigest,11,&(lvalues[1417]),0},
+{"id-smime-aa-encapContentType","id-smime-aa-encapContentType",
+	NID_id_smime_aa_encapContentType,11,&(lvalues[1428]),0},
+{"id-smime-aa-contentIdentifier","id-smime-aa-contentIdentifier",
+	NID_id_smime_aa_contentIdentifier,11,&(lvalues[1439]),0},
+{"id-smime-aa-macValue","id-smime-aa-macValue",
+	NID_id_smime_aa_macValue,11,&(lvalues[1450]),0},
+{"id-smime-aa-equivalentLabels","id-smime-aa-equivalentLabels",
+	NID_id_smime_aa_equivalentLabels,11,&(lvalues[1461]),0},
+{"id-smime-aa-contentReference","id-smime-aa-contentReference",
+	NID_id_smime_aa_contentReference,11,&(lvalues[1472]),0},
+{"id-smime-aa-encrypKeyPref","id-smime-aa-encrypKeyPref",
+	NID_id_smime_aa_encrypKeyPref,11,&(lvalues[1483]),0},
+{"id-smime-aa-signingCertificate","id-smime-aa-signingCertificate",
+	NID_id_smime_aa_signingCertificate,11,&(lvalues[1494]),0},
+{"id-smime-aa-smimeEncryptCerts","id-smime-aa-smimeEncryptCerts",
+	NID_id_smime_aa_smimeEncryptCerts,11,&(lvalues[1505]),0},
+{"id-smime-aa-timeStampToken","id-smime-aa-timeStampToken",
+	NID_id_smime_aa_timeStampToken,11,&(lvalues[1516]),0},
+{"id-smime-aa-ets-sigPolicyId","id-smime-aa-ets-sigPolicyId",
+	NID_id_smime_aa_ets_sigPolicyId,11,&(lvalues[1527]),0},
+{"id-smime-aa-ets-commitmentType","id-smime-aa-ets-commitmentType",
+	NID_id_smime_aa_ets_commitmentType,11,&(lvalues[1538]),0},
+{"id-smime-aa-ets-signerLocation","id-smime-aa-ets-signerLocation",
+	NID_id_smime_aa_ets_signerLocation,11,&(lvalues[1549]),0},
+{"id-smime-aa-ets-signerAttr","id-smime-aa-ets-signerAttr",
+	NID_id_smime_aa_ets_signerAttr,11,&(lvalues[1560]),0},
+{"id-smime-aa-ets-otherSigCert","id-smime-aa-ets-otherSigCert",
+	NID_id_smime_aa_ets_otherSigCert,11,&(lvalues[1571]),0},
+{"id-smime-aa-ets-contentTimestamp",
+	"id-smime-aa-ets-contentTimestamp",
+	NID_id_smime_aa_ets_contentTimestamp,11,&(lvalues[1582]),0},
+{"id-smime-aa-ets-CertificateRefs","id-smime-aa-ets-CertificateRefs",
+	NID_id_smime_aa_ets_CertificateRefs,11,&(lvalues[1593]),0},
+{"id-smime-aa-ets-RevocationRefs","id-smime-aa-ets-RevocationRefs",
+	NID_id_smime_aa_ets_RevocationRefs,11,&(lvalues[1604]),0},
+{"id-smime-aa-ets-certValues","id-smime-aa-ets-certValues",
+	NID_id_smime_aa_ets_certValues,11,&(lvalues[1615]),0},
+{"id-smime-aa-ets-revocationValues",
+	"id-smime-aa-ets-revocationValues",
+	NID_id_smime_aa_ets_revocationValues,11,&(lvalues[1626]),0},
+{"id-smime-aa-ets-escTimeStamp","id-smime-aa-ets-escTimeStamp",
+	NID_id_smime_aa_ets_escTimeStamp,11,&(lvalues[1637]),0},
+{"id-smime-aa-ets-certCRLTimestamp",
+	"id-smime-aa-ets-certCRLTimestamp",
+	NID_id_smime_aa_ets_certCRLTimestamp,11,&(lvalues[1648]),0},
+{"id-smime-aa-ets-archiveTimeStamp",
+	"id-smime-aa-ets-archiveTimeStamp",
+	NID_id_smime_aa_ets_archiveTimeStamp,11,&(lvalues[1659]),0},
+{"id-smime-aa-signatureType","id-smime-aa-signatureType",
+	NID_id_smime_aa_signatureType,11,&(lvalues[1670]),0},
+{"id-smime-aa-dvcs-dvc","id-smime-aa-dvcs-dvc",
+	NID_id_smime_aa_dvcs_dvc,11,&(lvalues[1681]),0},
+{"id-smime-alg-ESDHwith3DES","id-smime-alg-ESDHwith3DES",
+	NID_id_smime_alg_ESDHwith3DES,11,&(lvalues[1692]),0},
+{"id-smime-alg-ESDHwithRC2","id-smime-alg-ESDHwithRC2",
+	NID_id_smime_alg_ESDHwithRC2,11,&(lvalues[1703]),0},
+{"id-smime-alg-3DESwrap","id-smime-alg-3DESwrap",
+	NID_id_smime_alg_3DESwrap,11,&(lvalues[1714]),0},
+{"id-smime-alg-RC2wrap","id-smime-alg-RC2wrap",
+	NID_id_smime_alg_RC2wrap,11,&(lvalues[1725]),0},
+{"id-smime-alg-ESDH","id-smime-alg-ESDH",NID_id_smime_alg_ESDH,11,
+	&(lvalues[1736]),0},
+{"id-smime-alg-CMS3DESwrap","id-smime-alg-CMS3DESwrap",
+	NID_id_smime_alg_CMS3DESwrap,11,&(lvalues[1747]),0},
+{"id-smime-alg-CMSRC2wrap","id-smime-alg-CMSRC2wrap",
+	NID_id_smime_alg_CMSRC2wrap,11,&(lvalues[1758]),0},
+{"id-smime-cd-ldap","id-smime-cd-ldap",NID_id_smime_cd_ldap,11,
+	&(lvalues[1769]),0},
+{"id-smime-spq-ets-sqt-uri","id-smime-spq-ets-sqt-uri",
+	NID_id_smime_spq_ets_sqt_uri,11,&(lvalues[1780]),0},
+{"id-smime-spq-ets-sqt-unotice","id-smime-spq-ets-sqt-unotice",
+	NID_id_smime_spq_ets_sqt_unotice,11,&(lvalues[1791]),0},
+{"id-smime-cti-ets-proofOfOrigin","id-smime-cti-ets-proofOfOrigin",
+	NID_id_smime_cti_ets_proofOfOrigin,11,&(lvalues[1802]),0},
+{"id-smime-cti-ets-proofOfReceipt","id-smime-cti-ets-proofOfReceipt",
+	NID_id_smime_cti_ets_proofOfReceipt,11,&(lvalues[1813]),0},
+{"id-smime-cti-ets-proofOfDelivery",
+	"id-smime-cti-ets-proofOfDelivery",
+	NID_id_smime_cti_ets_proofOfDelivery,11,&(lvalues[1824]),0},
+{"id-smime-cti-ets-proofOfSender","id-smime-cti-ets-proofOfSender",
+	NID_id_smime_cti_ets_proofOfSender,11,&(lvalues[1835]),0},
+{"id-smime-cti-ets-proofOfApproval",
+	"id-smime-cti-ets-proofOfApproval",
+	NID_id_smime_cti_ets_proofOfApproval,11,&(lvalues[1846]),0},
+{"id-smime-cti-ets-proofOfCreation",
+	"id-smime-cti-ets-proofOfCreation",
+	NID_id_smime_cti_ets_proofOfCreation,11,&(lvalues[1857]),0},
+{"MD4","md4",NID_md4,8,&(lvalues[1868]),0},
+{"id-pkix-mod","id-pkix-mod",NID_id_pkix_mod,7,&(lvalues[1876]),0},
+{"id-qt","id-qt",NID_id_qt,7,&(lvalues[1883]),0},
+{"id-it","id-it",NID_id_it,7,&(lvalues[1890]),0},
+{"id-pkip","id-pkip",NID_id_pkip,7,&(lvalues[1897]),0},
+{"id-alg","id-alg",NID_id_alg,7,&(lvalues[1904]),0},
+{"id-cmc","id-cmc",NID_id_cmc,7,&(lvalues[1911]),0},
+{"id-on","id-on",NID_id_on,7,&(lvalues[1918]),0},
+{"id-pda","id-pda",NID_id_pda,7,&(lvalues[1925]),0},
+{"id-aca","id-aca",NID_id_aca,7,&(lvalues[1932]),0},
+{"id-qcs","id-qcs",NID_id_qcs,7,&(lvalues[1939]),0},
+{"id-cct","id-cct",NID_id_cct,7,&(lvalues[1946]),0},
+{"id-pkix1-explicit-88","id-pkix1-explicit-88",
+	NID_id_pkix1_explicit_88,8,&(lvalues[1953]),0},
+{"id-pkix1-implicit-88","id-pkix1-implicit-88",
+	NID_id_pkix1_implicit_88,8,&(lvalues[1961]),0},
+{"id-pkix1-explicit-93","id-pkix1-explicit-93",
+	NID_id_pkix1_explicit_93,8,&(lvalues[1969]),0},
+{"id-pkix1-implicit-93","id-pkix1-implicit-93",
+	NID_id_pkix1_implicit_93,8,&(lvalues[1977]),0},
+{"id-mod-crmf","id-mod-crmf",NID_id_mod_crmf,8,&(lvalues[1985]),0},
+{"id-mod-cmc","id-mod-cmc",NID_id_mod_cmc,8,&(lvalues[1993]),0},
+{"id-mod-kea-profile-88","id-mod-kea-profile-88",
+	NID_id_mod_kea_profile_88,8,&(lvalues[2001]),0},
+{"id-mod-kea-profile-93","id-mod-kea-profile-93",
+	NID_id_mod_kea_profile_93,8,&(lvalues[2009]),0},
+{"id-mod-cmp","id-mod-cmp",NID_id_mod_cmp,8,&(lvalues[2017]),0},
+{"id-mod-qualified-cert-88","id-mod-qualified-cert-88",
+	NID_id_mod_qualified_cert_88,8,&(lvalues[2025]),0},
+{"id-mod-qualified-cert-93","id-mod-qualified-cert-93",
+	NID_id_mod_qualified_cert_93,8,&(lvalues[2033]),0},
+{"id-mod-attribute-cert","id-mod-attribute-cert",
+	NID_id_mod_attribute_cert,8,&(lvalues[2041]),0},
+{"id-mod-timestamp-protocol","id-mod-timestamp-protocol",
+	NID_id_mod_timestamp_protocol,8,&(lvalues[2049]),0},
+{"id-mod-ocsp","id-mod-ocsp",NID_id_mod_ocsp,8,&(lvalues[2057]),0},
+{"id-mod-dvcs","id-mod-dvcs",NID_id_mod_dvcs,8,&(lvalues[2065]),0},
+{"id-mod-cmp2000","id-mod-cmp2000",NID_id_mod_cmp2000,8,
+	&(lvalues[2073]),0},
+{"biometricInfo","Biometric Info",NID_biometricInfo,8,&(lvalues[2081]),0},
+{"qcStatements","qcStatements",NID_qcStatements,8,&(lvalues[2089]),0},
+{"ac-auditEntity","ac-auditEntity",NID_ac_auditEntity,8,
+	&(lvalues[2097]),0},
+{"ac-targeting","ac-targeting",NID_ac_targeting,8,&(lvalues[2105]),0},
+{"aaControls","aaControls",NID_aaControls,8,&(lvalues[2113]),0},
+{"sbgp-ipAddrBlock","sbgp-ipAddrBlock",NID_sbgp_ipAddrBlock,8,
+	&(lvalues[2121]),0},
+{"sbgp-autonomousSysNum","sbgp-autonomousSysNum",
+	NID_sbgp_autonomousSysNum,8,&(lvalues[2129]),0},
+{"sbgp-routerIdentifier","sbgp-routerIdentifier",
+	NID_sbgp_routerIdentifier,8,&(lvalues[2137]),0},
+{"textNotice","textNotice",NID_textNotice,8,&(lvalues[2145]),0},
+{"ipsecEndSystem","IPSec End System",NID_ipsecEndSystem,8,
+	&(lvalues[2153]),0},
+{"ipsecTunnel","IPSec Tunnel",NID_ipsecTunnel,8,&(lvalues[2161]),0},
+{"ipsecUser","IPSec User",NID_ipsecUser,8,&(lvalues[2169]),0},
+{"DVCS","dvcs",NID_dvcs,8,&(lvalues[2177]),0},
+{"id-it-caProtEncCert","id-it-caProtEncCert",NID_id_it_caProtEncCert,
+	8,&(lvalues[2185]),0},
+{"id-it-signKeyPairTypes","id-it-signKeyPairTypes",
+	NID_id_it_signKeyPairTypes,8,&(lvalues[2193]),0},
+{"id-it-encKeyPairTypes","id-it-encKeyPairTypes",
+	NID_id_it_encKeyPairTypes,8,&(lvalues[2201]),0},
+{"id-it-preferredSymmAlg","id-it-preferredSymmAlg",
+	NID_id_it_preferredSymmAlg,8,&(lvalues[2209]),0},
+{"id-it-caKeyUpdateInfo","id-it-caKeyUpdateInfo",
+	NID_id_it_caKeyUpdateInfo,8,&(lvalues[2217]),0},
+{"id-it-currentCRL","id-it-currentCRL",NID_id_it_currentCRL,8,
+	&(lvalues[2225]),0},
+{"id-it-unsupportedOIDs","id-it-unsupportedOIDs",
+	NID_id_it_unsupportedOIDs,8,&(lvalues[2233]),0},
+{"id-it-subscriptionRequest","id-it-subscriptionRequest",
+	NID_id_it_subscriptionRequest,8,&(lvalues[2241]),0},
+{"id-it-subscriptionResponse","id-it-subscriptionResponse",
+	NID_id_it_subscriptionResponse,8,&(lvalues[2249]),0},
+{"id-it-keyPairParamReq","id-it-keyPairParamReq",
+	NID_id_it_keyPairParamReq,8,&(lvalues[2257]),0},
+{"id-it-keyPairParamRep","id-it-keyPairParamRep",
+	NID_id_it_keyPairParamRep,8,&(lvalues[2265]),0},
+{"id-it-revPassphrase","id-it-revPassphrase",NID_id_it_revPassphrase,
+	8,&(lvalues[2273]),0},
+{"id-it-implicitConfirm","id-it-implicitConfirm",
+	NID_id_it_implicitConfirm,8,&(lvalues[2281]),0},
+{"id-it-confirmWaitTime","id-it-confirmWaitTime",
+	NID_id_it_confirmWaitTime,8,&(lvalues[2289]),0},
+{"id-it-origPKIMessage","id-it-origPKIMessage",
+	NID_id_it_origPKIMessage,8,&(lvalues[2297]),0},
+{"id-regCtrl","id-regCtrl",NID_id_regCtrl,8,&(lvalues[2305]),0},
+{"id-regInfo","id-regInfo",NID_id_regInfo,8,&(lvalues[2313]),0},
+{"id-regCtrl-regToken","id-regCtrl-regToken",NID_id_regCtrl_regToken,
+	9,&(lvalues[2321]),0},
+{"id-regCtrl-authenticator","id-regCtrl-authenticator",
+	NID_id_regCtrl_authenticator,9,&(lvalues[2330]),0},
+{"id-regCtrl-pkiPublicationInfo","id-regCtrl-pkiPublicationInfo",
+	NID_id_regCtrl_pkiPublicationInfo,9,&(lvalues[2339]),0},
+{"id-regCtrl-pkiArchiveOptions","id-regCtrl-pkiArchiveOptions",
+	NID_id_regCtrl_pkiArchiveOptions,9,&(lvalues[2348]),0},
+{"id-regCtrl-oldCertID","id-regCtrl-oldCertID",
+	NID_id_regCtrl_oldCertID,9,&(lvalues[2357]),0},
+{"id-regCtrl-protocolEncrKey","id-regCtrl-protocolEncrKey",
+	NID_id_regCtrl_protocolEncrKey,9,&(lvalues[2366]),0},
+{"id-regInfo-utf8Pairs","id-regInfo-utf8Pairs",
+	NID_id_regInfo_utf8Pairs,9,&(lvalues[2375]),0},
+{"id-regInfo-certReq","id-regInfo-certReq",NID_id_regInfo_certReq,9,
+	&(lvalues[2384]),0},
+{"id-alg-des40","id-alg-des40",NID_id_alg_des40,8,&(lvalues[2393]),0},
+{"id-alg-noSignature","id-alg-noSignature",NID_id_alg_noSignature,8,
+	&(lvalues[2401]),0},
+{"id-alg-dh-sig-hmac-sha1","id-alg-dh-sig-hmac-sha1",
+	NID_id_alg_dh_sig_hmac_sha1,8,&(lvalues[2409]),0},
+{"id-alg-dh-pop","id-alg-dh-pop",NID_id_alg_dh_pop,8,&(lvalues[2417]),0},
+{"id-cmc-statusInfo","id-cmc-statusInfo",NID_id_cmc_statusInfo,8,
+	&(lvalues[2425]),0},
+{"id-cmc-identification","id-cmc-identification",
+	NID_id_cmc_identification,8,&(lvalues[2433]),0},
+{"id-cmc-identityProof","id-cmc-identityProof",
+	NID_id_cmc_identityProof,8,&(lvalues[2441]),0},
+{"id-cmc-dataReturn","id-cmc-dataReturn",NID_id_cmc_dataReturn,8,
+	&(lvalues[2449]),0},
+{"id-cmc-transactionId","id-cmc-transactionId",
+	NID_id_cmc_transactionId,8,&(lvalues[2457]),0},
+{"id-cmc-senderNonce","id-cmc-senderNonce",NID_id_cmc_senderNonce,8,
+	&(lvalues[2465]),0},
+{"id-cmc-recipientNonce","id-cmc-recipientNonce",
+	NID_id_cmc_recipientNonce,8,&(lvalues[2473]),0},
+{"id-cmc-addExtensions","id-cmc-addExtensions",
+	NID_id_cmc_addExtensions,8,&(lvalues[2481]),0},
+{"id-cmc-encryptedPOP","id-cmc-encryptedPOP",NID_id_cmc_encryptedPOP,
+	8,&(lvalues[2489]),0},
+{"id-cmc-decryptedPOP","id-cmc-decryptedPOP",NID_id_cmc_decryptedPOP,
+	8,&(lvalues[2497]),0},
+{"id-cmc-lraPOPWitness","id-cmc-lraPOPWitness",
+	NID_id_cmc_lraPOPWitness,8,&(lvalues[2505]),0},
+{"id-cmc-getCert","id-cmc-getCert",NID_id_cmc_getCert,8,
+	&(lvalues[2513]),0},
+{"id-cmc-getCRL","id-cmc-getCRL",NID_id_cmc_getCRL,8,&(lvalues[2521]),0},
+{"id-cmc-revokeRequest","id-cmc-revokeRequest",
+	NID_id_cmc_revokeRequest,8,&(lvalues[2529]),0},
+{"id-cmc-regInfo","id-cmc-regInfo",NID_id_cmc_regInfo,8,
+	&(lvalues[2537]),0},
+{"id-cmc-responseInfo","id-cmc-responseInfo",NID_id_cmc_responseInfo,
+	8,&(lvalues[2545]),0},
+{"id-cmc-queryPending","id-cmc-queryPending",NID_id_cmc_queryPending,
+	8,&(lvalues[2553]),0},
+{"id-cmc-popLinkRandom","id-cmc-popLinkRandom",
+	NID_id_cmc_popLinkRandom,8,&(lvalues[2561]),0},
+{"id-cmc-popLinkWitness","id-cmc-popLinkWitness",
+	NID_id_cmc_popLinkWitness,8,&(lvalues[2569]),0},
+{"id-cmc-confirmCertAcceptance","id-cmc-confirmCertAcceptance",
+	NID_id_cmc_confirmCertAcceptance,8,&(lvalues[2577]),0},
+{"id-on-personalData","id-on-personalData",NID_id_on_personalData,8,
+	&(lvalues[2585]),0},
+{"id-pda-dateOfBirth","id-pda-dateOfBirth",NID_id_pda_dateOfBirth,8,
+	&(lvalues[2593]),0},
+{"id-pda-placeOfBirth","id-pda-placeOfBirth",NID_id_pda_placeOfBirth,
+	8,&(lvalues[2601]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"id-pda-gender","id-pda-gender",NID_id_pda_gender,8,&(lvalues[2609]),0},
+{"id-pda-countryOfCitizenship","id-pda-countryOfCitizenship",
+	NID_id_pda_countryOfCitizenship,8,&(lvalues[2617]),0},
+{"id-pda-countryOfResidence","id-pda-countryOfResidence",
+	NID_id_pda_countryOfResidence,8,&(lvalues[2625]),0},
+{"id-aca-authenticationInfo","id-aca-authenticationInfo",
+	NID_id_aca_authenticationInfo,8,&(lvalues[2633]),0},
+{"id-aca-accessIdentity","id-aca-accessIdentity",
+	NID_id_aca_accessIdentity,8,&(lvalues[2641]),0},
+{"id-aca-chargingIdentity","id-aca-chargingIdentity",
+	NID_id_aca_chargingIdentity,8,&(lvalues[2649]),0},
+{"id-aca-group","id-aca-group",NID_id_aca_group,8,&(lvalues[2657]),0},
+{"id-aca-role","id-aca-role",NID_id_aca_role,8,&(lvalues[2665]),0},
+{"id-qcs-pkixQCSyntax-v1","id-qcs-pkixQCSyntax-v1",
+	NID_id_qcs_pkixQCSyntax_v1,8,&(lvalues[2673]),0},
+{"id-cct-crs","id-cct-crs",NID_id_cct_crs,8,&(lvalues[2681]),0},
+{"id-cct-PKIData","id-cct-PKIData",NID_id_cct_PKIData,8,
+	&(lvalues[2689]),0},
+{"id-cct-PKIResponse","id-cct-PKIResponse",NID_id_cct_PKIResponse,8,
+	&(lvalues[2697]),0},
+{"ad_timestamping","AD Time Stamping",NID_ad_timeStamping,8,
+	&(lvalues[2705]),0},
+{"AD_DVCS","ad dvcs",NID_ad_dvcs,8,&(lvalues[2713]),0},
+{"basicOCSPResponse","Basic OCSP Response",NID_id_pkix_OCSP_basic,9,
+	&(lvalues[2721]),0},
+{"Nonce","OCSP Nonce",NID_id_pkix_OCSP_Nonce,9,&(lvalues[2730]),0},
+{"CrlID","OCSP CRL ID",NID_id_pkix_OCSP_CrlID,9,&(lvalues[2739]),0},
+{"acceptableResponses","Acceptable OCSP Responses",
+	NID_id_pkix_OCSP_acceptableResponses,9,&(lvalues[2748]),0},
+{"noCheck","OCSP No Check",NID_id_pkix_OCSP_noCheck,9,&(lvalues[2757]),0},
+{"archiveCutoff","OCSP Archive Cutoff",NID_id_pkix_OCSP_archiveCutoff,
+	9,&(lvalues[2766]),0},
+{"serviceLocator","OCSP Service Locator",
+	NID_id_pkix_OCSP_serviceLocator,9,&(lvalues[2775]),0},
+{"extendedStatus","Extended OCSP Status",
+	NID_id_pkix_OCSP_extendedStatus,9,&(lvalues[2784]),0},
+{"valid","valid",NID_id_pkix_OCSP_valid,9,&(lvalues[2793]),0},
+{"path","path",NID_id_pkix_OCSP_path,9,&(lvalues[2802]),0},
+{"trustRoot","Trust Root",NID_id_pkix_OCSP_trustRoot,9,
+	&(lvalues[2811]),0},
+{"algorithm","algorithm",NID_algorithm,4,&(lvalues[2820]),0},
+{"rsaSignature","rsaSignature",NID_rsaSignature,5,&(lvalues[2824]),0},
+{"X500algorithms","directory services - algorithms",
+	NID_X500algorithms,2,&(lvalues[2829]),0},
+{"ORG","org",NID_org,1,&(lvalues[2831]),0},
+{"DOD","dod",NID_dod,2,&(lvalues[2832]),0},
+{"IANA","iana",NID_iana,3,&(lvalues[2834]),0},
+{"directory","Directory",NID_Directory,4,&(lvalues[2837]),0},
+{"mgmt","Management",NID_Management,4,&(lvalues[2841]),0},
+{"experimental","Experimental",NID_Experimental,4,&(lvalues[2845]),0},
+{"private","Private",NID_Private,4,&(lvalues[2849]),0},
+{"security","Security",NID_Security,4,&(lvalues[2853]),0},
+{"snmpv2","SNMPv2",NID_SNMPv2,4,&(lvalues[2857]),0},
+{"Mail","Mail",NID_Mail,4,&(lvalues[2861]),0},
+{"enterprises","Enterprises",NID_Enterprises,5,&(lvalues[2865]),0},
+{"dcobject","dcObject",NID_dcObject,9,&(lvalues[2870]),0},
+{"DC","domainComponent",NID_domainComponent,10,&(lvalues[2879]),0},
+{"domain","Domain",NID_Domain,10,&(lvalues[2889]),0},
+{"NULL","NULL",NID_joint_iso_ccitt,1,&(lvalues[2899]),0},
+{"selected-attribute-types","Selected Attribute Types",
+	NID_selected_attribute_types,3,&(lvalues[2900]),0},
+{"clearance","clearance",NID_clearance,4,&(lvalues[2903]),0},
+{"RSA-MD4","md4WithRSAEncryption",NID_md4WithRSAEncryption,9,
+	&(lvalues[2907]),0},
+{"ac-proxying","ac-proxying",NID_ac_proxying,8,&(lvalues[2916]),0},
+{"subjectInfoAccess","Subject Information Access",NID_sinfo_access,8,
+	&(lvalues[2924]),0},
+{"id-aca-encAttrs","id-aca-encAttrs",NID_id_aca_encAttrs,8,
+	&(lvalues[2932]),0},
+{"role","role",NID_role,3,&(lvalues[2940]),0},
+{"policyConstraints","X509v3 Policy Constraints",
+	NID_policy_constraints,3,&(lvalues[2943]),0},
+{"targetInformation","X509v3 AC Targeting",NID_target_information,3,
+	&(lvalues[2946]),0},
+{"noRevAvail","X509v3 No Revocation Available",NID_no_rev_avail,3,
+	&(lvalues[2949]),0},
+{"NULL","NULL",NID_ccitt,1,&(lvalues[2952]),0},
+{"ansi-X9-62","ANSI X9.62",NID_ansi_X9_62,5,&(lvalues[2953]),0},
+{"prime-field","prime-field",NID_X9_62_prime_field,7,&(lvalues[2958]),0},
+{"characteristic-two-field","characteristic-two-field",
+	NID_X9_62_characteristic_two_field,7,&(lvalues[2965]),0},
+{"id-ecPublicKey","id-ecPublicKey",NID_X9_62_id_ecPublicKey,7,
+	&(lvalues[2972]),0},
+{"prime192v1","prime192v1",NID_X9_62_prime192v1,8,&(lvalues[2979]),0},
+{"prime192v2","prime192v2",NID_X9_62_prime192v2,8,&(lvalues[2987]),0},
+{"prime192v3","prime192v3",NID_X9_62_prime192v3,8,&(lvalues[2995]),0},
+{"prime239v1","prime239v1",NID_X9_62_prime239v1,8,&(lvalues[3003]),0},
+{"prime239v2","prime239v2",NID_X9_62_prime239v2,8,&(lvalues[3011]),0},
+{"prime239v3","prime239v3",NID_X9_62_prime239v3,8,&(lvalues[3019]),0},
+{"prime256v1","prime256v1",NID_X9_62_prime256v1,8,&(lvalues[3027]),0},
+{"ecdsa-with-SHA1","ecdsa-with-SHA1",NID_ecdsa_with_SHA1,7,
+	&(lvalues[3035]),0},
+{"CSPName","Microsoft CSP Name",NID_ms_csp_name,9,&(lvalues[3042]),0},
+{"AES-128-ECB","aes-128-ecb",NID_aes_128_ecb,9,&(lvalues[3051]),0},
+{"AES-128-CBC","aes-128-cbc",NID_aes_128_cbc,9,&(lvalues[3060]),0},
+{"AES-128-OFB","aes-128-ofb",NID_aes_128_ofb128,9,&(lvalues[3069]),0},
+{"AES-128-CFB","aes-128-cfb",NID_aes_128_cfb128,9,&(lvalues[3078]),0},
+{"AES-192-ECB","aes-192-ecb",NID_aes_192_ecb,9,&(lvalues[3087]),0},
+{"AES-192-CBC","aes-192-cbc",NID_aes_192_cbc,9,&(lvalues[3096]),0},
+{"AES-192-OFB","aes-192-ofb",NID_aes_192_ofb128,9,&(lvalues[3105]),0},
+{"AES-192-CFB","aes-192-cfb",NID_aes_192_cfb128,9,&(lvalues[3114]),0},
+{"AES-256-ECB","aes-256-ecb",NID_aes_256_ecb,9,&(lvalues[3123]),0},
+{"AES-256-CBC","aes-256-cbc",NID_aes_256_cbc,9,&(lvalues[3132]),0},
+{"AES-256-OFB","aes-256-ofb",NID_aes_256_ofb128,9,&(lvalues[3141]),0},
+{"AES-256-CFB","aes-256-cfb",NID_aes_256_cfb128,9,&(lvalues[3150]),0},
+{"holdInstructionCode","Hold Instruction Code",
+	NID_hold_instruction_code,3,&(lvalues[3159]),0},
+{"holdInstructionNone","Hold Instruction None",
+	NID_hold_instruction_none,7,&(lvalues[3162]),0},
+{"holdInstructionCallIssuer","Hold Instruction Call Issuer",
+	NID_hold_instruction_call_issuer,7,&(lvalues[3169]),0},
+{"holdInstructionReject","Hold Instruction Reject",
+	NID_hold_instruction_reject,7,&(lvalues[3176]),0},
+{"data","data",NID_data,1,&(lvalues[3183]),0},
+{"pss","pss",NID_pss,3,&(lvalues[3184]),0},
+{"ucl","ucl",NID_ucl,7,&(lvalues[3187]),0},
+{"pilot","pilot",NID_pilot,8,&(lvalues[3194]),0},
+{"pilotAttributeType","pilotAttributeType",NID_pilotAttributeType,9,
+	&(lvalues[3202]),0},
+{"pilotAttributeSyntax","pilotAttributeSyntax",
+	NID_pilotAttributeSyntax,9,&(lvalues[3211]),0},
+{"pilotObjectClass","pilotObjectClass",NID_pilotObjectClass,9,
+	&(lvalues[3220]),0},
+{"pilotGroups","pilotGroups",NID_pilotGroups,9,&(lvalues[3229]),0},
+{"iA5StringSyntax","iA5StringSyntax",NID_iA5StringSyntax,10,
+	&(lvalues[3238]),0},
+{"caseIgnoreIA5StringSyntax","caseIgnoreIA5StringSyntax",
+	NID_caseIgnoreIA5StringSyntax,10,&(lvalues[3248]),0},
+{"pilotObject","pilotObject",NID_pilotObject,10,&(lvalues[3258]),0},
+{"pilotPerson","pilotPerson",NID_pilotPerson,10,&(lvalues[3268]),0},
+{"account","account",NID_account,10,&(lvalues[3278]),0},
+{"document","document",NID_document,10,&(lvalues[3288]),0},
+{"room","room",NID_room,10,&(lvalues[3298]),0},
+{"documentSeries","documentSeries",NID_documentSeries,10,
+	&(lvalues[3308]),0},
+{"rFC822localPart","rFC822localPart",NID_rFC822localPart,10,
+	&(lvalues[3318]),0},
+{"dNSDomain","dNSDomain",NID_dNSDomain,10,&(lvalues[3328]),0},
+{"domainRelatedObject","domainRelatedObject",NID_domainRelatedObject,
+	10,&(lvalues[3338]),0},
+{"friendlyCountry","friendlyCountry",NID_friendlyCountry,10,
+	&(lvalues[3348]),0},
+{"simpleSecurityObject","simpleSecurityObject",
+	NID_simpleSecurityObject,10,&(lvalues[3358]),0},
+{"pilotOrganization","pilotOrganization",NID_pilotOrganization,10,
+	&(lvalues[3368]),0},
+{"pilotDSA","pilotDSA",NID_pilotDSA,10,&(lvalues[3378]),0},
+{"qualityLabelledData","qualityLabelledData",NID_qualityLabelledData,
+	10,&(lvalues[3388]),0},
+{"UID","userId",NID_userId,10,&(lvalues[3398]),0},
+{"textEncodedORAddress","textEncodedORAddress",
+	NID_textEncodedORAddress,10,&(lvalues[3408]),0},
+{"mail","rfc822Mailbox",NID_rfc822Mailbox,10,&(lvalues[3418]),0},
+{"info","info",NID_info,10,&(lvalues[3428]),0},
+{"favouriteDrink","favouriteDrink",NID_favouriteDrink,10,
+	&(lvalues[3438]),0},
+{"roomNumber","roomNumber",NID_roomNumber,10,&(lvalues[3448]),0},
+{"photo","photo",NID_photo,10,&(lvalues[3458]),0},
+{"userClass","userClass",NID_userClass,10,&(lvalues[3468]),0},
+{"host","host",NID_host,10,&(lvalues[3478]),0},
+{"manager","manager",NID_manager,10,&(lvalues[3488]),0},
+{"documentIdentifier","documentIdentifier",NID_documentIdentifier,10,
+	&(lvalues[3498]),0},
+{"documentTitle","documentTitle",NID_documentTitle,10,&(lvalues[3508]),0},
+{"documentVersion","documentVersion",NID_documentVersion,10,
+	&(lvalues[3518]),0},
+{"documentAuthor","documentAuthor",NID_documentAuthor,10,
+	&(lvalues[3528]),0},
+{"documentLocation","documentLocation",NID_documentLocation,10,
+	&(lvalues[3538]),0},
+{"homeTelephoneNumber","homeTelephoneNumber",NID_homeTelephoneNumber,
+	10,&(lvalues[3548]),0},
+{"secretary","secretary",NID_secretary,10,&(lvalues[3558]),0},
+{"otherMailbox","otherMailbox",NID_otherMailbox,10,&(lvalues[3568]),0},
+{"lastModifiedTime","lastModifiedTime",NID_lastModifiedTime,10,
+	&(lvalues[3578]),0},
+{"lastModifiedBy","lastModifiedBy",NID_lastModifiedBy,10,
+	&(lvalues[3588]),0},
+{"aRecord","aRecord",NID_aRecord,10,&(lvalues[3598]),0},
+{"pilotAttributeType27","pilotAttributeType27",
+	NID_pilotAttributeType27,10,&(lvalues[3608]),0},
+{"mXRecord","mXRecord",NID_mXRecord,10,&(lvalues[3618]),0},
+{"nSRecord","nSRecord",NID_nSRecord,10,&(lvalues[3628]),0},
+{"sOARecord","sOARecord",NID_sOARecord,10,&(lvalues[3638]),0},
+{"cNAMERecord","cNAMERecord",NID_cNAMERecord,10,&(lvalues[3648]),0},
+{"associatedDomain","associatedDomain",NID_associatedDomain,10,
+	&(lvalues[3658]),0},
+{"associatedName","associatedName",NID_associatedName,10,
+	&(lvalues[3668]),0},
+{"homePostalAddress","homePostalAddress",NID_homePostalAddress,10,
+	&(lvalues[3678]),0},
+{"personalTitle","personalTitle",NID_personalTitle,10,&(lvalues[3688]),0},
+{"mobileTelephoneNumber","mobileTelephoneNumber",
+	NID_mobileTelephoneNumber,10,&(lvalues[3698]),0},
+{"pagerTelephoneNumber","pagerTelephoneNumber",
+	NID_pagerTelephoneNumber,10,&(lvalues[3708]),0},
+{"friendlyCountryName","friendlyCountryName",NID_friendlyCountryName,
+	10,&(lvalues[3718]),0},
+{"organizationalStatus","organizationalStatus",
+	NID_organizationalStatus,10,&(lvalues[3728]),0},
+{"janetMailbox","janetMailbox",NID_janetMailbox,10,&(lvalues[3738]),0},
+{"mailPreferenceOption","mailPreferenceOption",
+	NID_mailPreferenceOption,10,&(lvalues[3748]),0},
+{"buildingName","buildingName",NID_buildingName,10,&(lvalues[3758]),0},
+{"dSAQuality","dSAQuality",NID_dSAQuality,10,&(lvalues[3768]),0},
+{"singleLevelQuality","singleLevelQuality",NID_singleLevelQuality,10,
+	&(lvalues[3778]),0},
+{"subtreeMinimumQuality","subtreeMinimumQuality",
+	NID_subtreeMinimumQuality,10,&(lvalues[3788]),0},
+{"subtreeMaximumQuality","subtreeMaximumQuality",
+	NID_subtreeMaximumQuality,10,&(lvalues[3798]),0},
+{"personalSignature","personalSignature",NID_personalSignature,10,
+	&(lvalues[3808]),0},
+{"dITRedirect","dITRedirect",NID_dITRedirect,10,&(lvalues[3818]),0},
+{"audio","audio",NID_audio,10,&(lvalues[3828]),0},
+{"documentPublisher","documentPublisher",NID_documentPublisher,10,
+	&(lvalues[3838]),0},
+{"x500UniqueIdentifier","x500UniqueIdentifier",
+	NID_x500UniqueIdentifier,3,&(lvalues[3848]),0},
+{"mime-mhs","MIME MHS",NID_mime_mhs,5,&(lvalues[3851]),0},
+{"mime-mhs-headings","mime-mhs-headings",NID_mime_mhs_headings,6,
+	&(lvalues[3856]),0},
+{"mime-mhs-bodies","mime-mhs-bodies",NID_mime_mhs_bodies,6,
+	&(lvalues[3862]),0},
+{"id-hex-partial-message","id-hex-partial-message",
+	NID_id_hex_partial_message,7,&(lvalues[3868]),0},
+{"id-hex-multipart-message","id-hex-multipart-message",
+	NID_id_hex_multipart_message,7,&(lvalues[3875]),0},
+{"generationQualifier","generationQualifier",NID_generationQualifier,
+	3,&(lvalues[3882]),0},
+{"pseudonym","pseudonym",NID_pseudonym,3,&(lvalues[3885]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"id-set","Secure Electronic Transactions",NID_id_set,2,
+	&(lvalues[3888]),0},
+{"set-ctype","content types",NID_set_ctype,3,&(lvalues[3890]),0},
+{"set-msgExt","message extensions",NID_set_msgExt,3,&(lvalues[3893]),0},
+{"set-attr","set-attr",NID_set_attr,3,&(lvalues[3896]),0},
+{"set-policy","set-policy",NID_set_policy,3,&(lvalues[3899]),0},
+{"set-certExt","certificate extensions",NID_set_certExt,3,
+	&(lvalues[3902]),0},
+{"set-brand","set-brand",NID_set_brand,3,&(lvalues[3905]),0},
+{"setct-PANData","setct-PANData",NID_setct_PANData,4,&(lvalues[3908]),0},
+{"setct-PANToken","setct-PANToken",NID_setct_PANToken,4,
+	&(lvalues[3912]),0},
+{"setct-PANOnly","setct-PANOnly",NID_setct_PANOnly,4,&(lvalues[3916]),0},
+{"setct-OIData","setct-OIData",NID_setct_OIData,4,&(lvalues[3920]),0},
+{"setct-PI","setct-PI",NID_setct_PI,4,&(lvalues[3924]),0},
+{"setct-PIData","setct-PIData",NID_setct_PIData,4,&(lvalues[3928]),0},
+{"setct-PIDataUnsigned","setct-PIDataUnsigned",
+	NID_setct_PIDataUnsigned,4,&(lvalues[3932]),0},
+{"setct-HODInput","setct-HODInput",NID_setct_HODInput,4,
+	&(lvalues[3936]),0},
+{"setct-AuthResBaggage","setct-AuthResBaggage",
+	NID_setct_AuthResBaggage,4,&(lvalues[3940]),0},
+{"setct-AuthRevReqBaggage","setct-AuthRevReqBaggage",
+	NID_setct_AuthRevReqBaggage,4,&(lvalues[3944]),0},
+{"setct-AuthRevResBaggage","setct-AuthRevResBaggage",
+	NID_setct_AuthRevResBaggage,4,&(lvalues[3948]),0},
+{"setct-CapTokenSeq","setct-CapTokenSeq",NID_setct_CapTokenSeq,4,
+	&(lvalues[3952]),0},
+{"setct-PInitResData","setct-PInitResData",NID_setct_PInitResData,4,
+	&(lvalues[3956]),0},
+{"setct-PI-TBS","setct-PI-TBS",NID_setct_PI_TBS,4,&(lvalues[3960]),0},
+{"setct-PResData","setct-PResData",NID_setct_PResData,4,
+	&(lvalues[3964]),0},
+{"setct-AuthReqTBS","setct-AuthReqTBS",NID_setct_AuthReqTBS,4,
+	&(lvalues[3968]),0},
+{"setct-AuthResTBS","setct-AuthResTBS",NID_setct_AuthResTBS,4,
+	&(lvalues[3972]),0},
+{"setct-AuthResTBSX","setct-AuthResTBSX",NID_setct_AuthResTBSX,4,
+	&(lvalues[3976]),0},
+{"setct-AuthTokenTBS","setct-AuthTokenTBS",NID_setct_AuthTokenTBS,4,
+	&(lvalues[3980]),0},
+{"setct-CapTokenData","setct-CapTokenData",NID_setct_CapTokenData,4,
+	&(lvalues[3984]),0},
+{"setct-CapTokenTBS","setct-CapTokenTBS",NID_setct_CapTokenTBS,4,
+	&(lvalues[3988]),0},
+{"setct-AcqCardCodeMsg","setct-AcqCardCodeMsg",
+	NID_setct_AcqCardCodeMsg,4,&(lvalues[3992]),0},
+{"setct-AuthRevReqTBS","setct-AuthRevReqTBS",NID_setct_AuthRevReqTBS,
+	4,&(lvalues[3996]),0},
+{"setct-AuthRevResData","setct-AuthRevResData",
+	NID_setct_AuthRevResData,4,&(lvalues[4000]),0},
+{"setct-AuthRevResTBS","setct-AuthRevResTBS",NID_setct_AuthRevResTBS,
+	4,&(lvalues[4004]),0},
+{"setct-CapReqTBS","setct-CapReqTBS",NID_setct_CapReqTBS,4,
+	&(lvalues[4008]),0},
+{"setct-CapReqTBSX","setct-CapReqTBSX",NID_setct_CapReqTBSX,4,
+	&(lvalues[4012]),0},
+{"setct-CapResData","setct-CapResData",NID_setct_CapResData,4,
+	&(lvalues[4016]),0},
+{"setct-CapRevReqTBS","setct-CapRevReqTBS",NID_setct_CapRevReqTBS,4,
+	&(lvalues[4020]),0},
+{"setct-CapRevReqTBSX","setct-CapRevReqTBSX",NID_setct_CapRevReqTBSX,
+	4,&(lvalues[4024]),0},
+{"setct-CapRevResData","setct-CapRevResData",NID_setct_CapRevResData,
+	4,&(lvalues[4028]),0},
+{"setct-CredReqTBS","setct-CredReqTBS",NID_setct_CredReqTBS,4,
+	&(lvalues[4032]),0},
+{"setct-CredReqTBSX","setct-CredReqTBSX",NID_setct_CredReqTBSX,4,
+	&(lvalues[4036]),0},
+{"setct-CredResData","setct-CredResData",NID_setct_CredResData,4,
+	&(lvalues[4040]),0},
+{"setct-CredRevReqTBS","setct-CredRevReqTBS",NID_setct_CredRevReqTBS,
+	4,&(lvalues[4044]),0},
+{"setct-CredRevReqTBSX","setct-CredRevReqTBSX",
+	NID_setct_CredRevReqTBSX,4,&(lvalues[4048]),0},
+{"setct-CredRevResData","setct-CredRevResData",
+	NID_setct_CredRevResData,4,&(lvalues[4052]),0},
+{"setct-PCertReqData","setct-PCertReqData",NID_setct_PCertReqData,4,
+	&(lvalues[4056]),0},
+{"setct-PCertResTBS","setct-PCertResTBS",NID_setct_PCertResTBS,4,
+	&(lvalues[4060]),0},
+{"setct-BatchAdminReqData","setct-BatchAdminReqData",
+	NID_setct_BatchAdminReqData,4,&(lvalues[4064]),0},
+{"setct-BatchAdminResData","setct-BatchAdminResData",
+	NID_setct_BatchAdminResData,4,&(lvalues[4068]),0},
+{"setct-CardCInitResTBS","setct-CardCInitResTBS",
+	NID_setct_CardCInitResTBS,4,&(lvalues[4072]),0},
+{"setct-MeAqCInitResTBS","setct-MeAqCInitResTBS",
+	NID_setct_MeAqCInitResTBS,4,&(lvalues[4076]),0},
+{"setct-RegFormResTBS","setct-RegFormResTBS",NID_setct_RegFormResTBS,
+	4,&(lvalues[4080]),0},
+{"setct-CertReqData","setct-CertReqData",NID_setct_CertReqData,4,
+	&(lvalues[4084]),0},
+{"setct-CertReqTBS","setct-CertReqTBS",NID_setct_CertReqTBS,4,
+	&(lvalues[4088]),0},
+{"setct-CertResData","setct-CertResData",NID_setct_CertResData,4,
+	&(lvalues[4092]),0},
+{"setct-CertInqReqTBS","setct-CertInqReqTBS",NID_setct_CertInqReqTBS,
+	4,&(lvalues[4096]),0},
+{"setct-ErrorTBS","setct-ErrorTBS",NID_setct_ErrorTBS,4,
+	&(lvalues[4100]),0},
+{"setct-PIDualSignedTBE","setct-PIDualSignedTBE",
+	NID_setct_PIDualSignedTBE,4,&(lvalues[4104]),0},
+{"setct-PIUnsignedTBE","setct-PIUnsignedTBE",NID_setct_PIUnsignedTBE,
+	4,&(lvalues[4108]),0},
+{"setct-AuthReqTBE","setct-AuthReqTBE",NID_setct_AuthReqTBE,4,
+	&(lvalues[4112]),0},
+{"setct-AuthResTBE","setct-AuthResTBE",NID_setct_AuthResTBE,4,
+	&(lvalues[4116]),0},
+{"setct-AuthResTBEX","setct-AuthResTBEX",NID_setct_AuthResTBEX,4,
+	&(lvalues[4120]),0},
+{"setct-AuthTokenTBE","setct-AuthTokenTBE",NID_setct_AuthTokenTBE,4,
+	&(lvalues[4124]),0},
+{"setct-CapTokenTBE","setct-CapTokenTBE",NID_setct_CapTokenTBE,4,
+	&(lvalues[4128]),0},
+{"setct-CapTokenTBEX","setct-CapTokenTBEX",NID_setct_CapTokenTBEX,4,
+	&(lvalues[4132]),0},
+{"setct-AcqCardCodeMsgTBE","setct-AcqCardCodeMsgTBE",
+	NID_setct_AcqCardCodeMsgTBE,4,&(lvalues[4136]),0},
+{"setct-AuthRevReqTBE","setct-AuthRevReqTBE",NID_setct_AuthRevReqTBE,
+	4,&(lvalues[4140]),0},
+{"setct-AuthRevResTBE","setct-AuthRevResTBE",NID_setct_AuthRevResTBE,
+	4,&(lvalues[4144]),0},
+{"setct-AuthRevResTBEB","setct-AuthRevResTBEB",
+	NID_setct_AuthRevResTBEB,4,&(lvalues[4148]),0},
+{"setct-CapReqTBE","setct-CapReqTBE",NID_setct_CapReqTBE,4,
+	&(lvalues[4152]),0},
+{"setct-CapReqTBEX","setct-CapReqTBEX",NID_setct_CapReqTBEX,4,
+	&(lvalues[4156]),0},
+{"setct-CapResTBE","setct-CapResTBE",NID_setct_CapResTBE,4,
+	&(lvalues[4160]),0},
+{"setct-CapRevReqTBE","setct-CapRevReqTBE",NID_setct_CapRevReqTBE,4,
+	&(lvalues[4164]),0},
+{"setct-CapRevReqTBEX","setct-CapRevReqTBEX",NID_setct_CapRevReqTBEX,
+	4,&(lvalues[4168]),0},
+{"setct-CapRevResTBE","setct-CapRevResTBE",NID_setct_CapRevResTBE,4,
+	&(lvalues[4172]),0},
+{"setct-CredReqTBE","setct-CredReqTBE",NID_setct_CredReqTBE,4,
+	&(lvalues[4176]),0},
+{"setct-CredReqTBEX","setct-CredReqTBEX",NID_setct_CredReqTBEX,4,
+	&(lvalues[4180]),0},
+{"setct-CredResTBE","setct-CredResTBE",NID_setct_CredResTBE,4,
+	&(lvalues[4184]),0},
+{"setct-CredRevReqTBE","setct-CredRevReqTBE",NID_setct_CredRevReqTBE,
+	4,&(lvalues[4188]),0},
+{"setct-CredRevReqTBEX","setct-CredRevReqTBEX",
+	NID_setct_CredRevReqTBEX,4,&(lvalues[4192]),0},
+{"setct-CredRevResTBE","setct-CredRevResTBE",NID_setct_CredRevResTBE,
+	4,&(lvalues[4196]),0},
+{"setct-BatchAdminReqTBE","setct-BatchAdminReqTBE",
+	NID_setct_BatchAdminReqTBE,4,&(lvalues[4200]),0},
+{"setct-BatchAdminResTBE","setct-BatchAdminResTBE",
+	NID_setct_BatchAdminResTBE,4,&(lvalues[4204]),0},
+{"setct-RegFormReqTBE","setct-RegFormReqTBE",NID_setct_RegFormReqTBE,
+	4,&(lvalues[4208]),0},
+{"setct-CertReqTBE","setct-CertReqTBE",NID_setct_CertReqTBE,4,
+	&(lvalues[4212]),0},
+{"setct-CertReqTBEX","setct-CertReqTBEX",NID_setct_CertReqTBEX,4,
+	&(lvalues[4216]),0},
+{"setct-CertResTBE","setct-CertResTBE",NID_setct_CertResTBE,4,
+	&(lvalues[4220]),0},
+{"setct-CRLNotificationTBS","setct-CRLNotificationTBS",
+	NID_setct_CRLNotificationTBS,4,&(lvalues[4224]),0},
+{"setct-CRLNotificationResTBS","setct-CRLNotificationResTBS",
+	NID_setct_CRLNotificationResTBS,4,&(lvalues[4228]),0},
+{"setct-BCIDistributionTBS","setct-BCIDistributionTBS",
+	NID_setct_BCIDistributionTBS,4,&(lvalues[4232]),0},
+{"setext-genCrypt","generic cryptogram",NID_setext_genCrypt,4,
+	&(lvalues[4236]),0},
+{"setext-miAuth","merchant initiated auth",NID_setext_miAuth,4,
+	&(lvalues[4240]),0},
+{"setext-pinSecure","setext-pinSecure",NID_setext_pinSecure,4,
+	&(lvalues[4244]),0},
+{"setext-pinAny","setext-pinAny",NID_setext_pinAny,4,&(lvalues[4248]),0},
+{"setext-track2","setext-track2",NID_setext_track2,4,&(lvalues[4252]),0},
+{"setext-cv","additional verification",NID_setext_cv,4,
+	&(lvalues[4256]),0},
+{"set-policy-root","set-policy-root",NID_set_policy_root,4,
+	&(lvalues[4260]),0},
+{"setCext-hashedRoot","setCext-hashedRoot",NID_setCext_hashedRoot,4,
+	&(lvalues[4264]),0},
+{"setCext-certType","setCext-certType",NID_setCext_certType,4,
+	&(lvalues[4268]),0},
+{"setCext-merchData","setCext-merchData",NID_setCext_merchData,4,
+	&(lvalues[4272]),0},
+{"setCext-cCertRequired","setCext-cCertRequired",
+	NID_setCext_cCertRequired,4,&(lvalues[4276]),0},
+{"setCext-tunneling","setCext-tunneling",NID_setCext_tunneling,4,
+	&(lvalues[4280]),0},
+{"setCext-setExt","setCext-setExt",NID_setCext_setExt,4,
+	&(lvalues[4284]),0},
+{"setCext-setQualf","setCext-setQualf",NID_setCext_setQualf,4,
+	&(lvalues[4288]),0},
+{"setCext-PGWYcapabilities","setCext-PGWYcapabilities",
+	NID_setCext_PGWYcapabilities,4,&(lvalues[4292]),0},
+{"setCext-TokenIdentifier","setCext-TokenIdentifier",
+	NID_setCext_TokenIdentifier,4,&(lvalues[4296]),0},
+{"setCext-Track2Data","setCext-Track2Data",NID_setCext_Track2Data,4,
+	&(lvalues[4300]),0},
+{"setCext-TokenType","setCext-TokenType",NID_setCext_TokenType,4,
+	&(lvalues[4304]),0},
+{"setCext-IssuerCapabilities","setCext-IssuerCapabilities",
+	NID_setCext_IssuerCapabilities,4,&(lvalues[4308]),0},
+{"setAttr-Cert","setAttr-Cert",NID_setAttr_Cert,4,&(lvalues[4312]),0},
+{"setAttr-PGWYcap","payment gateway capabilities",NID_setAttr_PGWYcap,
+	4,&(lvalues[4316]),0},
+{"setAttr-TokenType","setAttr-TokenType",NID_setAttr_TokenType,4,
+	&(lvalues[4320]),0},
+{"setAttr-IssCap","issuer capabilities",NID_setAttr_IssCap,4,
+	&(lvalues[4324]),0},
+{"set-rootKeyThumb","set-rootKeyThumb",NID_set_rootKeyThumb,5,
+	&(lvalues[4328]),0},
+{"set-addPolicy","set-addPolicy",NID_set_addPolicy,5,&(lvalues[4333]),0},
+{"setAttr-Token-EMV","setAttr-Token-EMV",NID_setAttr_Token_EMV,5,
+	&(lvalues[4338]),0},
+{"setAttr-Token-B0Prime","setAttr-Token-B0Prime",
+	NID_setAttr_Token_B0Prime,5,&(lvalues[4343]),0},
+{"setAttr-IssCap-CVM","setAttr-IssCap-CVM",NID_setAttr_IssCap_CVM,5,
+	&(lvalues[4348]),0},
+{"setAttr-IssCap-T2","setAttr-IssCap-T2",NID_setAttr_IssCap_T2,5,
+	&(lvalues[4353]),0},
+{"setAttr-IssCap-Sig","setAttr-IssCap-Sig",NID_setAttr_IssCap_Sig,5,
+	&(lvalues[4358]),0},
+{"setAttr-GenCryptgrm","generate cryptogram",NID_setAttr_GenCryptgrm,
+	6,&(lvalues[4363]),0},
+{"setAttr-T2Enc","encrypted track 2",NID_setAttr_T2Enc,6,
+	&(lvalues[4369]),0},
+{"setAttr-T2cleartxt","cleartext track 2",NID_setAttr_T2cleartxt,6,
+	&(lvalues[4375]),0},
+{"setAttr-TokICCsig","ICC or token signature",NID_setAttr_TokICCsig,6,
+	&(lvalues[4381]),0},
+{"setAttr-SecDevSig","secure device signature",NID_setAttr_SecDevSig,
+	6,&(lvalues[4387]),0},
+{"set-brand-IATA-ATA","set-brand-IATA-ATA",NID_set_brand_IATA_ATA,4,
+	&(lvalues[4393]),0},
+{"set-brand-Diners","set-brand-Diners",NID_set_brand_Diners,4,
+	&(lvalues[4397]),0},
+{"set-brand-AmericanExpress","set-brand-AmericanExpress",
+	NID_set_brand_AmericanExpress,4,&(lvalues[4401]),0},
+{"set-brand-JCB","set-brand-JCB",NID_set_brand_JCB,4,&(lvalues[4405]),0},
+{"set-brand-Visa","set-brand-Visa",NID_set_brand_Visa,4,
+	&(lvalues[4409]),0},
+{"set-brand-MasterCard","set-brand-MasterCard",
+	NID_set_brand_MasterCard,4,&(lvalues[4413]),0},
+{"set-brand-Novus","set-brand-Novus",NID_set_brand_Novus,5,
+	&(lvalues[4417]),0},
+{"DES-CDMF","des-cdmf",NID_des_cdmf,8,&(lvalues[4422]),0},
+{"rsaOAEPEncryptionSET","rsaOAEPEncryptionSET",
+	NID_rsaOAEPEncryptionSET,9,&(lvalues[4430]),0},
+{"ITU-T","itu-t",NID_itu_t,1,&(lvalues[4439]),0},
+{"JOINT-ISO-ITU-T","joint-iso-itu-t",NID_joint_iso_itu_t,1,
+	&(lvalues[4440]),0},
+{"international-organizations","International Organizations",
+	NID_international_organizations,1,&(lvalues[4441]),0},
+{"msSmartcardLogin","Microsoft Smartcardlogin",NID_ms_smartcard_login,
+	10,&(lvalues[4442]),0},
+{"msUPN","Microsoft Universal Principal Name",NID_ms_upn,10,
+	&(lvalues[4452]),0},
+{"AES-128-CFB1","aes-128-cfb1",NID_aes_128_cfb1,0,NULL,0},
+{"AES-192-CFB1","aes-192-cfb1",NID_aes_192_cfb1,0,NULL,0},
+{"AES-256-CFB1","aes-256-cfb1",NID_aes_256_cfb1,0,NULL,0},
+{"AES-128-CFB8","aes-128-cfb8",NID_aes_128_cfb8,0,NULL,0},
+{"AES-192-CFB8","aes-192-cfb8",NID_aes_192_cfb8,0,NULL,0},
+{"AES-256-CFB8","aes-256-cfb8",NID_aes_256_cfb8,0,NULL,0},
+{"DES-CFB1","des-cfb1",NID_des_cfb1,0,NULL,0},
+{"DES-CFB8","des-cfb8",NID_des_cfb8,0,NULL,0},
+{"DES-EDE3-CFB1","des-ede3-cfb1",NID_des_ede3_cfb1,0,NULL,0},
+{"DES-EDE3-CFB8","des-ede3-cfb8",NID_des_ede3_cfb8,0,NULL,0},
+{"street","streetAddress",NID_streetAddress,3,&(lvalues[4462]),0},
+{"postalCode","postalCode",NID_postalCode,3,&(lvalues[4465]),0},
+{"id-ppl","id-ppl",NID_id_ppl,7,&(lvalues[4468]),0},
+{"proxyCertInfo","Proxy Certificate Information",NID_proxyCertInfo,8,
+	&(lvalues[4475]),0},
+{"id-ppl-anyLanguage","Any language",NID_id_ppl_anyLanguage,8,
+	&(lvalues[4483]),0},
+{"id-ppl-inheritAll","Inherit all",NID_id_ppl_inheritAll,8,
+	&(lvalues[4491]),0},
+{"nameConstraints","X509v3 Name Constraints",NID_name_constraints,3,
+	&(lvalues[4499]),0},
+{"id-ppl-independent","Independent",NID_Independent,8,&(lvalues[4502]),0},
+{"RSA-SHA256","sha256WithRSAEncryption",NID_sha256WithRSAEncryption,9,
+	&(lvalues[4510]),0},
+{"RSA-SHA384","sha384WithRSAEncryption",NID_sha384WithRSAEncryption,9,
+	&(lvalues[4519]),0},
+{"RSA-SHA512","sha512WithRSAEncryption",NID_sha512WithRSAEncryption,9,
+	&(lvalues[4528]),0},
+{"RSA-SHA224","sha224WithRSAEncryption",NID_sha224WithRSAEncryption,9,
+	&(lvalues[4537]),0},
+{"SHA256","sha256",NID_sha256,9,&(lvalues[4546]),0},
+{"SHA384","sha384",NID_sha384,9,&(lvalues[4555]),0},
+{"SHA512","sha512",NID_sha512,9,&(lvalues[4564]),0},
+{"SHA224","sha224",NID_sha224,9,&(lvalues[4573]),0},
+{"identified-organization","identified-organization",
+	NID_identified_organization,1,&(lvalues[4582]),0},
+{"certicom-arc","certicom-arc",NID_certicom_arc,3,&(lvalues[4583]),0},
+{"wap","wap",NID_wap,2,&(lvalues[4586]),0},
+{"wap-wsg","wap-wsg",NID_wap_wsg,3,&(lvalues[4588]),0},
+{"id-characteristic-two-basis","id-characteristic-two-basis",
+	NID_X9_62_id_characteristic_two_basis,8,&(lvalues[4591]),0},
+{"onBasis","onBasis",NID_X9_62_onBasis,9,&(lvalues[4599]),0},
+{"tpBasis","tpBasis",NID_X9_62_tpBasis,9,&(lvalues[4608]),0},
+{"ppBasis","ppBasis",NID_X9_62_ppBasis,9,&(lvalues[4617]),0},
+{"c2pnb163v1","c2pnb163v1",NID_X9_62_c2pnb163v1,8,&(lvalues[4626]),0},
+{"c2pnb163v2","c2pnb163v2",NID_X9_62_c2pnb163v2,8,&(lvalues[4634]),0},
+{"c2pnb163v3","c2pnb163v3",NID_X9_62_c2pnb163v3,8,&(lvalues[4642]),0},
+{"c2pnb176v1","c2pnb176v1",NID_X9_62_c2pnb176v1,8,&(lvalues[4650]),0},
+{"c2tnb191v1","c2tnb191v1",NID_X9_62_c2tnb191v1,8,&(lvalues[4658]),0},
+{"c2tnb191v2","c2tnb191v2",NID_X9_62_c2tnb191v2,8,&(lvalues[4666]),0},
+{"c2tnb191v3","c2tnb191v3",NID_X9_62_c2tnb191v3,8,&(lvalues[4674]),0},
+{"c2onb191v4","c2onb191v4",NID_X9_62_c2onb191v4,8,&(lvalues[4682]),0},
+{"c2onb191v5","c2onb191v5",NID_X9_62_c2onb191v5,8,&(lvalues[4690]),0},
+{"c2pnb208w1","c2pnb208w1",NID_X9_62_c2pnb208w1,8,&(lvalues[4698]),0},
+{"c2tnb239v1","c2tnb239v1",NID_X9_62_c2tnb239v1,8,&(lvalues[4706]),0},
+{"c2tnb239v2","c2tnb239v2",NID_X9_62_c2tnb239v2,8,&(lvalues[4714]),0},
+{"c2tnb239v3","c2tnb239v3",NID_X9_62_c2tnb239v3,8,&(lvalues[4722]),0},
+{"c2onb239v4","c2onb239v4",NID_X9_62_c2onb239v4,8,&(lvalues[4730]),0},
+{"c2onb239v5","c2onb239v5",NID_X9_62_c2onb239v5,8,&(lvalues[4738]),0},
+{"c2pnb272w1","c2pnb272w1",NID_X9_62_c2pnb272w1,8,&(lvalues[4746]),0},
+{"c2pnb304w1","c2pnb304w1",NID_X9_62_c2pnb304w1,8,&(lvalues[4754]),0},
+{"c2tnb359v1","c2tnb359v1",NID_X9_62_c2tnb359v1,8,&(lvalues[4762]),0},
+{"c2pnb368w1","c2pnb368w1",NID_X9_62_c2pnb368w1,8,&(lvalues[4770]),0},
+{"c2tnb431r1","c2tnb431r1",NID_X9_62_c2tnb431r1,8,&(lvalues[4778]),0},
+{"secp112r1","secp112r1",NID_secp112r1,5,&(lvalues[4786]),0},
+{"secp112r2","secp112r2",NID_secp112r2,5,&(lvalues[4791]),0},
+{"secp128r1","secp128r1",NID_secp128r1,5,&(lvalues[4796]),0},
+{"secp128r2","secp128r2",NID_secp128r2,5,&(lvalues[4801]),0},
+{"secp160k1","secp160k1",NID_secp160k1,5,&(lvalues[4806]),0},
+{"secp160r1","secp160r1",NID_secp160r1,5,&(lvalues[4811]),0},
+{"secp160r2","secp160r2",NID_secp160r2,5,&(lvalues[4816]),0},
+{"secp192k1","secp192k1",NID_secp192k1,5,&(lvalues[4821]),0},
+{"secp224k1","secp224k1",NID_secp224k1,5,&(lvalues[4826]),0},
+{"secp224r1","secp224r1",NID_secp224r1,5,&(lvalues[4831]),0},
+{"secp256k1","secp256k1",NID_secp256k1,5,&(lvalues[4836]),0},
+{"secp384r1","secp384r1",NID_secp384r1,5,&(lvalues[4841]),0},
+{"secp521r1","secp521r1",NID_secp521r1,5,&(lvalues[4846]),0},
+{"sect113r1","sect113r1",NID_sect113r1,5,&(lvalues[4851]),0},
+{"sect113r2","sect113r2",NID_sect113r2,5,&(lvalues[4856]),0},
+{"sect131r1","sect131r1",NID_sect131r1,5,&(lvalues[4861]),0},
+{"sect131r2","sect131r2",NID_sect131r2,5,&(lvalues[4866]),0},
+{"sect163k1","sect163k1",NID_sect163k1,5,&(lvalues[4871]),0},
+{"sect163r1","sect163r1",NID_sect163r1,5,&(lvalues[4876]),0},
+{"sect163r2","sect163r2",NID_sect163r2,5,&(lvalues[4881]),0},
+{"sect193r1","sect193r1",NID_sect193r1,5,&(lvalues[4886]),0},
+{"sect193r2","sect193r2",NID_sect193r2,5,&(lvalues[4891]),0},
+{"sect233k1","sect233k1",NID_sect233k1,5,&(lvalues[4896]),0},
+{"sect233r1","sect233r1",NID_sect233r1,5,&(lvalues[4901]),0},
+{"sect239k1","sect239k1",NID_sect239k1,5,&(lvalues[4906]),0},
+{"sect283k1","sect283k1",NID_sect283k1,5,&(lvalues[4911]),0},
+{"sect283r1","sect283r1",NID_sect283r1,5,&(lvalues[4916]),0},
+{"sect409k1","sect409k1",NID_sect409k1,5,&(lvalues[4921]),0},
+{"sect409r1","sect409r1",NID_sect409r1,5,&(lvalues[4926]),0},
+{"sect571k1","sect571k1",NID_sect571k1,5,&(lvalues[4931]),0},
+{"sect571r1","sect571r1",NID_sect571r1,5,&(lvalues[4936]),0},
+{"wap-wsg-idm-ecid-wtls1","wap-wsg-idm-ecid-wtls1",
+	NID_wap_wsg_idm_ecid_wtls1,5,&(lvalues[4941]),0},
+{"wap-wsg-idm-ecid-wtls3","wap-wsg-idm-ecid-wtls3",
+	NID_wap_wsg_idm_ecid_wtls3,5,&(lvalues[4946]),0},
+{"wap-wsg-idm-ecid-wtls4","wap-wsg-idm-ecid-wtls4",
+	NID_wap_wsg_idm_ecid_wtls4,5,&(lvalues[4951]),0},
+{"wap-wsg-idm-ecid-wtls5","wap-wsg-idm-ecid-wtls5",
+	NID_wap_wsg_idm_ecid_wtls5,5,&(lvalues[4956]),0},
+{"wap-wsg-idm-ecid-wtls6","wap-wsg-idm-ecid-wtls6",
+	NID_wap_wsg_idm_ecid_wtls6,5,&(lvalues[4961]),0},
+{"wap-wsg-idm-ecid-wtls7","wap-wsg-idm-ecid-wtls7",
+	NID_wap_wsg_idm_ecid_wtls7,5,&(lvalues[4966]),0},
+{"wap-wsg-idm-ecid-wtls8","wap-wsg-idm-ecid-wtls8",
+	NID_wap_wsg_idm_ecid_wtls8,5,&(lvalues[4971]),0},
+{"wap-wsg-idm-ecid-wtls9","wap-wsg-idm-ecid-wtls9",
+	NID_wap_wsg_idm_ecid_wtls9,5,&(lvalues[4976]),0},
+{"wap-wsg-idm-ecid-wtls10","wap-wsg-idm-ecid-wtls10",
+	NID_wap_wsg_idm_ecid_wtls10,5,&(lvalues[4981]),0},
+{"wap-wsg-idm-ecid-wtls11","wap-wsg-idm-ecid-wtls11",
+	NID_wap_wsg_idm_ecid_wtls11,5,&(lvalues[4986]),0},
+{"wap-wsg-idm-ecid-wtls12","wap-wsg-idm-ecid-wtls12",
+	NID_wap_wsg_idm_ecid_wtls12,5,&(lvalues[4991]),0},
+{"anyPolicy","X509v3 Any Policy",NID_any_policy,4,&(lvalues[4996]),0},
+{"policyMappings","X509v3 Policy Mappings",NID_policy_mappings,3,
+	&(lvalues[5000]),0},
+{"inhibitAnyPolicy","X509v3 Inhibit Any Policy",
+	NID_inhibit_any_policy,3,&(lvalues[5003]),0},
+{"Oakley-EC2N-3","ipsec3",NID_ipsec3,0,NULL,0},
+{"Oakley-EC2N-4","ipsec4",NID_ipsec4,0,NULL,0},
+{"CAMELLIA-128-CBC","camellia-128-cbc",NID_camellia_128_cbc,11,
+	&(lvalues[5006]),0},
+{"CAMELLIA-192-CBC","camellia-192-cbc",NID_camellia_192_cbc,11,
+	&(lvalues[5017]),0},
+{"CAMELLIA-256-CBC","camellia-256-cbc",NID_camellia_256_cbc,11,
+	&(lvalues[5028]),0},
+{"CAMELLIA-128-ECB","camellia-128-ecb",NID_camellia_128_ecb,8,
+	&(lvalues[5039]),0},
+{"CAMELLIA-192-ECB","camellia-192-ecb",NID_camellia_192_ecb,8,
+	&(lvalues[5047]),0},
+{"CAMELLIA-256-ECB","camellia-256-ecb",NID_camellia_256_ecb,8,
+	&(lvalues[5055]),0},
+{"CAMELLIA-128-CFB","camellia-128-cfb",NID_camellia_128_cfb128,8,
+	&(lvalues[5063]),0},
+{"CAMELLIA-192-CFB","camellia-192-cfb",NID_camellia_192_cfb128,8,
+	&(lvalues[5071]),0},
+{"CAMELLIA-256-CFB","camellia-256-cfb",NID_camellia_256_cfb128,8,
+	&(lvalues[5079]),0},
+{"CAMELLIA-128-CFB1","camellia-128-cfb1",NID_camellia_128_cfb1,0,NULL,0},
+{"CAMELLIA-192-CFB1","camellia-192-cfb1",NID_camellia_192_cfb1,0,NULL,0},
+{"CAMELLIA-256-CFB1","camellia-256-cfb1",NID_camellia_256_cfb1,0,NULL,0},
+{"CAMELLIA-128-CFB8","camellia-128-cfb8",NID_camellia_128_cfb8,0,NULL,0},
+{"CAMELLIA-192-CFB8","camellia-192-cfb8",NID_camellia_192_cfb8,0,NULL,0},
+{"CAMELLIA-256-CFB8","camellia-256-cfb8",NID_camellia_256_cfb8,0,NULL,0},
+{"CAMELLIA-128-OFB","camellia-128-ofb",NID_camellia_128_ofb128,8,
+	&(lvalues[5087]),0},
+{"CAMELLIA-192-OFB","camellia-192-ofb",NID_camellia_192_ofb128,8,
+	&(lvalues[5095]),0},
+{"CAMELLIA-256-OFB","camellia-256-ofb",NID_camellia_256_ofb128,8,
+	&(lvalues[5103]),0},
+{"subjectDirectoryAttributes","X509v3 Subject Directory Attributes",
+	NID_subject_directory_attributes,3,&(lvalues[5111]),0},
+{"issuingDistributionPoint","X509v3 Issuing Distrubution Point",
+	NID_issuing_distribution_point,3,&(lvalues[5114]),0},
+{"certificateIssuer","X509v3 Certificate Issuer",
+	NID_certificate_issuer,3,&(lvalues[5117]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"KISA","kisa",NID_kisa,6,&(lvalues[5120]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"SEED-ECB","seed-ecb",NID_seed_ecb,8,&(lvalues[5126]),0},
+{"SEED-CBC","seed-cbc",NID_seed_cbc,8,&(lvalues[5134]),0},
+{"SEED-OFB","seed-ofb",NID_seed_ofb128,8,&(lvalues[5142]),0},
+{"SEED-CFB","seed-cfb",NID_seed_cfb128,8,&(lvalues[5150]),0},
+{"HMAC-MD5","hmac-md5",NID_hmac_md5,8,&(lvalues[5158]),0},
+{"HMAC-SHA1","hmac-sha1",NID_hmac_sha1,8,&(lvalues[5166]),0},
+{"id-PasswordBasedMAC","password based MAC",NID_id_PasswordBasedMAC,9,
+	&(lvalues[5174]),0},
+{"id-DHBasedMac","Diffie-Hellman based MAC",NID_id_DHBasedMac,9,
+	&(lvalues[5183]),0},
+{"id-it-suppLangTags","id-it-suppLangTags",NID_id_it_suppLangTags,8,
+	&(lvalues[5192]),0},
+{"caRepository","CA Repository",NID_caRepository,8,&(lvalues[5200]),0},
+{"id-smime-ct-compressedData","id-smime-ct-compressedData",
+	NID_id_smime_ct_compressedData,11,&(lvalues[5208]),0},
+{"id-ct-asciiTextWithCRLF","id-ct-asciiTextWithCRLF",
+	NID_id_ct_asciiTextWithCRLF,11,&(lvalues[5219]),0},
+{"id-aes128-wrap","id-aes128-wrap",NID_id_aes128_wrap,9,
+	&(lvalues[5230]),0},
+{"id-aes192-wrap","id-aes192-wrap",NID_id_aes192_wrap,9,
+	&(lvalues[5239]),0},
+{"id-aes256-wrap","id-aes256-wrap",NID_id_aes256_wrap,9,
+	&(lvalues[5248]),0},
+{"ecdsa-with-Recommended","ecdsa-with-Recommended",
+	NID_ecdsa_with_Recommended,7,&(lvalues[5257]),0},
+{"ecdsa-with-Specified","ecdsa-with-Specified",
+	NID_ecdsa_with_Specified,7,&(lvalues[5264]),0},
+{"ecdsa-with-SHA224","ecdsa-with-SHA224",NID_ecdsa_with_SHA224,8,
+	&(lvalues[5271]),0},
+{"ecdsa-with-SHA256","ecdsa-with-SHA256",NID_ecdsa_with_SHA256,8,
+	&(lvalues[5279]),0},
+{"ecdsa-with-SHA384","ecdsa-with-SHA384",NID_ecdsa_with_SHA384,8,
+	&(lvalues[5287]),0},
+{"ecdsa-with-SHA512","ecdsa-with-SHA512",NID_ecdsa_with_SHA512,8,
+	&(lvalues[5295]),0},
+{"hmacWithMD5","hmacWithMD5",NID_hmacWithMD5,8,&(lvalues[5303]),0},
+{"hmacWithSHA224","hmacWithSHA224",NID_hmacWithSHA224,8,
+	&(lvalues[5311]),0},
+{"hmacWithSHA256","hmacWithSHA256",NID_hmacWithSHA256,8,
+	&(lvalues[5319]),0},
+{"hmacWithSHA384","hmacWithSHA384",NID_hmacWithSHA384,8,
+	&(lvalues[5327]),0},
+{"hmacWithSHA512","hmacWithSHA512",NID_hmacWithSHA512,8,
+	&(lvalues[5335]),0},
+{"dsa_with_SHA224","dsa_with_SHA224",NID_dsa_with_SHA224,9,
+	&(lvalues[5343]),0},
+{"dsa_with_SHA256","dsa_with_SHA256",NID_dsa_with_SHA256,9,
+	&(lvalues[5352]),0},
+{"whirlpool","whirlpool",NID_whirlpool,6,&(lvalues[5361]),0},
+{"cryptopro","cryptopro",NID_cryptopro,5,&(lvalues[5367]),0},
+{"cryptocom","cryptocom",NID_cryptocom,5,&(lvalues[5372]),0},
+{"id-GostR3411-94-with-GostR3410-2001",
+	"GOST R 34.11-94 with GOST R 34.10-2001",
+	NID_id_GostR3411_94_with_GostR3410_2001,6,&(lvalues[5377]),0},
+{"id-GostR3411-94-with-GostR3410-94",
+	"GOST R 34.11-94 with GOST R 34.10-94",
+	NID_id_GostR3411_94_with_GostR3410_94,6,&(lvalues[5383]),0},
+{"md_gost94","GOST R 34.11-94",NID_id_GostR3411_94,6,&(lvalues[5389]),0},
+{"id-HMACGostR3411-94","HMAC GOST 34.11-94",NID_id_HMACGostR3411_94,6,
+	&(lvalues[5395]),0},
+{"gost2001","GOST R 34.10-2001",NID_id_GostR3410_2001,6,
+	&(lvalues[5401]),0},
+{"gost94","GOST R 34.10-94",NID_id_GostR3410_94,6,&(lvalues[5407]),0},
+{"gost89","GOST 28147-89",NID_id_Gost28147_89,6,&(lvalues[5413]),0},
+{"gost89-cnt","gost89-cnt",NID_gost89_cnt,0,NULL,0},
+{"gost-mac","GOST 28147-89 MAC",NID_id_Gost28147_89_MAC,6,
+	&(lvalues[5419]),0},
+{"prf-gostr3411-94","GOST R 34.11-94 PRF",NID_id_GostR3411_94_prf,6,
+	&(lvalues[5425]),0},
+{"id-GostR3410-2001DH","GOST R 34.10-2001 DH",NID_id_GostR3410_2001DH,
+	6,&(lvalues[5431]),0},
+{"id-GostR3410-94DH","GOST R 34.10-94 DH",NID_id_GostR3410_94DH,6,
+	&(lvalues[5437]),0},
+{"id-Gost28147-89-CryptoPro-KeyMeshing",
+	"id-Gost28147-89-CryptoPro-KeyMeshing",
+	NID_id_Gost28147_89_CryptoPro_KeyMeshing,7,&(lvalues[5443]),0},
+{"id-Gost28147-89-None-KeyMeshing","id-Gost28147-89-None-KeyMeshing",
+	NID_id_Gost28147_89_None_KeyMeshing,7,&(lvalues[5450]),0},
+{"id-GostR3411-94-TestParamSet","id-GostR3411-94-TestParamSet",
+	NID_id_GostR3411_94_TestParamSet,7,&(lvalues[5457]),0},
+{"id-GostR3411-94-CryptoProParamSet",
+	"id-GostR3411-94-CryptoProParamSet",
+	NID_id_GostR3411_94_CryptoProParamSet,7,&(lvalues[5464]),0},
+{"id-Gost28147-89-TestParamSet","id-Gost28147-89-TestParamSet",
+	NID_id_Gost28147_89_TestParamSet,7,&(lvalues[5471]),0},
+{"id-Gost28147-89-CryptoPro-A-ParamSet",
+	"id-Gost28147-89-CryptoPro-A-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_A_ParamSet,7,&(lvalues[5478]),0},
+{"id-Gost28147-89-CryptoPro-B-ParamSet",
+	"id-Gost28147-89-CryptoPro-B-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_B_ParamSet,7,&(lvalues[5485]),0},
+{"id-Gost28147-89-CryptoPro-C-ParamSet",
+	"id-Gost28147-89-CryptoPro-C-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_C_ParamSet,7,&(lvalues[5492]),0},
+{"id-Gost28147-89-CryptoPro-D-ParamSet",
+	"id-Gost28147-89-CryptoPro-D-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_D_ParamSet,7,&(lvalues[5499]),0},
+{"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet",
+	"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet,7,&(lvalues[5506]),
+	0},
+{"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet",
+	"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet,7,&(lvalues[5513]),
+	0},
+{"id-Gost28147-89-CryptoPro-RIC-1-ParamSet",
+	"id-Gost28147-89-CryptoPro-RIC-1-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet,7,&(lvalues[5520]),0},
+{"id-GostR3410-94-TestParamSet","id-GostR3410-94-TestParamSet",
+	NID_id_GostR3410_94_TestParamSet,7,&(lvalues[5527]),0},
+{"id-GostR3410-94-CryptoPro-A-ParamSet",
+	"id-GostR3410-94-CryptoPro-A-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_A_ParamSet,7,&(lvalues[5534]),0},
+{"id-GostR3410-94-CryptoPro-B-ParamSet",
+	"id-GostR3410-94-CryptoPro-B-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_B_ParamSet,7,&(lvalues[5541]),0},
+{"id-GostR3410-94-CryptoPro-C-ParamSet",
+	"id-GostR3410-94-CryptoPro-C-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_C_ParamSet,7,&(lvalues[5548]),0},
+{"id-GostR3410-94-CryptoPro-D-ParamSet",
+	"id-GostR3410-94-CryptoPro-D-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_D_ParamSet,7,&(lvalues[5555]),0},
+{"id-GostR3410-94-CryptoPro-XchA-ParamSet",
+	"id-GostR3410-94-CryptoPro-XchA-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_XchA_ParamSet,7,&(lvalues[5562]),0},
+{"id-GostR3410-94-CryptoPro-XchB-ParamSet",
+	"id-GostR3410-94-CryptoPro-XchB-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_XchB_ParamSet,7,&(lvalues[5569]),0},
+{"id-GostR3410-94-CryptoPro-XchC-ParamSet",
+	"id-GostR3410-94-CryptoPro-XchC-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_XchC_ParamSet,7,&(lvalues[5576]),0},
+{"id-GostR3410-2001-TestParamSet","id-GostR3410-2001-TestParamSet",
+	NID_id_GostR3410_2001_TestParamSet,7,&(lvalues[5583]),0},
+{"id-GostR3410-2001-CryptoPro-A-ParamSet",
+	"id-GostR3410-2001-CryptoPro-A-ParamSet",
+	NID_id_GostR3410_2001_CryptoPro_A_ParamSet,7,&(lvalues[5590]),0},
+{"id-GostR3410-2001-CryptoPro-B-ParamSet",
+	"id-GostR3410-2001-CryptoPro-B-ParamSet",
+	NID_id_GostR3410_2001_CryptoPro_B_ParamSet,7,&(lvalues[5597]),0},
+{"id-GostR3410-2001-CryptoPro-C-ParamSet",
+	"id-GostR3410-2001-CryptoPro-C-ParamSet",
+	NID_id_GostR3410_2001_CryptoPro_C_ParamSet,7,&(lvalues[5604]),0},
+{"id-GostR3410-2001-CryptoPro-XchA-ParamSet",
+	"id-GostR3410-2001-CryptoPro-XchA-ParamSet",
+	NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet,7,&(lvalues[5611]),0},
+	
+{"id-GostR3410-2001-CryptoPro-XchB-ParamSet",
+	"id-GostR3410-2001-CryptoPro-XchB-ParamSet",
+	NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet,7,&(lvalues[5618]),0},
+	
+{"id-GostR3410-94-a","id-GostR3410-94-a",NID_id_GostR3410_94_a,7,
+	&(lvalues[5625]),0},
+{"id-GostR3410-94-aBis","id-GostR3410-94-aBis",
+	NID_id_GostR3410_94_aBis,7,&(lvalues[5632]),0},
+{"id-GostR3410-94-b","id-GostR3410-94-b",NID_id_GostR3410_94_b,7,
+	&(lvalues[5639]),0},
+{"id-GostR3410-94-bBis","id-GostR3410-94-bBis",
+	NID_id_GostR3410_94_bBis,7,&(lvalues[5646]),0},
+{"id-Gost28147-89-cc","GOST 28147-89 Cryptocom ParamSet",
+	NID_id_Gost28147_89_cc,8,&(lvalues[5653]),0},
+{"gost94cc","GOST 34.10-94 Cryptocom",NID_id_GostR3410_94_cc,8,
+	&(lvalues[5661]),0},
+{"gost2001cc","GOST 34.10-2001 Cryptocom",NID_id_GostR3410_2001_cc,8,
+	&(lvalues[5669]),0},
+{"id-GostR3411-94-with-GostR3410-94-cc",
+	"GOST R 34.11-94 with GOST R 34.10-94 Cryptocom",
+	NID_id_GostR3411_94_with_GostR3410_94_cc,8,&(lvalues[5677]),0},
+{"id-GostR3411-94-with-GostR3410-2001-cc",
+	"GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom",
+	NID_id_GostR3411_94_with_GostR3410_2001_cc,8,&(lvalues[5685]),0},
+{"id-GostR3410-2001-ParamSet-cc",
+	"GOST R 3410-2001 Parameter Set Cryptocom",
+	NID_id_GostR3410_2001_ParamSet_cc,8,&(lvalues[5693]),0},
+{"HMAC","hmac",NID_hmac,0,NULL,0},
+{"LocalKeySet","Microsoft Local Key set",NID_LocalKeySet,9,
+	&(lvalues[5701]),0},
+{"freshestCRL","X509v3 Freshest CRL",NID_freshest_crl,3,
+	&(lvalues[5710]),0},
+{"id-on-permanentIdentifier","Permanent Identifier",
+	NID_id_on_permanentIdentifier,8,&(lvalues[5713]),0},
+{"searchGuide","searchGuide",NID_searchGuide,3,&(lvalues[5721]),0},
+{"businessCategory","businessCategory",NID_businessCategory,3,
+	&(lvalues[5724]),0},
+{"postalAddress","postalAddress",NID_postalAddress,3,&(lvalues[5727]),0},
+{"postOfficeBox","postOfficeBox",NID_postOfficeBox,3,&(lvalues[5730]),0},
+{"physicalDeliveryOfficeName","physicalDeliveryOfficeName",
+	NID_physicalDeliveryOfficeName,3,&(lvalues[5733]),0},
+{"telephoneNumber","telephoneNumber",NID_telephoneNumber,3,
+	&(lvalues[5736]),0},
+{"telexNumber","telexNumber",NID_telexNumber,3,&(lvalues[5739]),0},
+{"teletexTerminalIdentifier","teletexTerminalIdentifier",
+	NID_teletexTerminalIdentifier,3,&(lvalues[5742]),0},
+{"facsimileTelephoneNumber","facsimileTelephoneNumber",
+	NID_facsimileTelephoneNumber,3,&(lvalues[5745]),0},
+{"x121Address","x121Address",NID_x121Address,3,&(lvalues[5748]),0},
+{"internationaliSDNNumber","internationaliSDNNumber",
+	NID_internationaliSDNNumber,3,&(lvalues[5751]),0},
+{"registeredAddress","registeredAddress",NID_registeredAddress,3,
+	&(lvalues[5754]),0},
+{"destinationIndicator","destinationIndicator",
+	NID_destinationIndicator,3,&(lvalues[5757]),0},
+{"preferredDeliveryMethod","preferredDeliveryMethod",
+	NID_preferredDeliveryMethod,3,&(lvalues[5760]),0},
+{"presentationAddress","presentationAddress",NID_presentationAddress,
+	3,&(lvalues[5763]),0},
+{"supportedApplicationContext","supportedApplicationContext",
+	NID_supportedApplicationContext,3,&(lvalues[5766]),0},
+{"member","member",NID_member,3,&(lvalues[5769]),0},
+{"owner","owner",NID_owner,3,&(lvalues[5772]),0},
+{"roleOccupant","roleOccupant",NID_roleOccupant,3,&(lvalues[5775]),0},
+{"seeAlso","seeAlso",NID_seeAlso,3,&(lvalues[5778]),0},
+{"userPassword","userPassword",NID_userPassword,3,&(lvalues[5781]),0},
+{"userCertificate","userCertificate",NID_userCertificate,3,
+	&(lvalues[5784]),0},
+{"cACertificate","cACertificate",NID_cACertificate,3,&(lvalues[5787]),0},
+{"authorityRevocationList","authorityRevocationList",
+	NID_authorityRevocationList,3,&(lvalues[5790]),0},
+{"certificateRevocationList","certificateRevocationList",
+	NID_certificateRevocationList,3,&(lvalues[5793]),0},
+{"crossCertificatePair","crossCertificatePair",
+	NID_crossCertificatePair,3,&(lvalues[5796]),0},
+{"enhancedSearchGuide","enhancedSearchGuide",NID_enhancedSearchGuide,
+	3,&(lvalues[5799]),0},
+{"protocolInformation","protocolInformation",NID_protocolInformation,
+	3,&(lvalues[5802]),0},
+{"distinguishedName","distinguishedName",NID_distinguishedName,3,
+	&(lvalues[5805]),0},
+{"uniqueMember","uniqueMember",NID_uniqueMember,3,&(lvalues[5808]),0},
+{"houseIdentifier","houseIdentifier",NID_houseIdentifier,3,
+	&(lvalues[5811]),0},
+{"supportedAlgorithms","supportedAlgorithms",NID_supportedAlgorithms,
+	3,&(lvalues[5814]),0},
+{"deltaRevocationList","deltaRevocationList",NID_deltaRevocationList,
+	3,&(lvalues[5817]),0},
+{"dmdName","dmdName",NID_dmdName,3,&(lvalues[5820]),0},
+};
+
+static const unsigned int sn_objs[NUM_SN]={
+364,	/* "AD_DVCS" */
+419,	/* "AES-128-CBC" */
+421,	/* "AES-128-CFB" */
+650,	/* "AES-128-CFB1" */
+653,	/* "AES-128-CFB8" */
+418,	/* "AES-128-ECB" */
+420,	/* "AES-128-OFB" */
+423,	/* "AES-192-CBC" */
+425,	/* "AES-192-CFB" */
+651,	/* "AES-192-CFB1" */
+654,	/* "AES-192-CFB8" */
+422,	/* "AES-192-ECB" */
+424,	/* "AES-192-OFB" */
+427,	/* "AES-256-CBC" */
+429,	/* "AES-256-CFB" */
+652,	/* "AES-256-CFB1" */
+655,	/* "AES-256-CFB8" */
+426,	/* "AES-256-ECB" */
+428,	/* "AES-256-OFB" */
+91,	/* "BF-CBC" */
+93,	/* "BF-CFB" */
+92,	/* "BF-ECB" */
+94,	/* "BF-OFB" */
+14,	/* "C" */
+751,	/* "CAMELLIA-128-CBC" */
+757,	/* "CAMELLIA-128-CFB" */
+760,	/* "CAMELLIA-128-CFB1" */
+763,	/* "CAMELLIA-128-CFB8" */
+754,	/* "CAMELLIA-128-ECB" */
+766,	/* "CAMELLIA-128-OFB" */
+752,	/* "CAMELLIA-192-CBC" */
+758,	/* "CAMELLIA-192-CFB" */
+761,	/* "CAMELLIA-192-CFB1" */
+764,	/* "CAMELLIA-192-CFB8" */
+755,	/* "CAMELLIA-192-ECB" */
+767,	/* "CAMELLIA-192-OFB" */
+753,	/* "CAMELLIA-256-CBC" */
+759,	/* "CAMELLIA-256-CFB" */
+762,	/* "CAMELLIA-256-CFB1" */
+765,	/* "CAMELLIA-256-CFB8" */
+756,	/* "CAMELLIA-256-ECB" */
+768,	/* "CAMELLIA-256-OFB" */
+108,	/* "CAST5-CBC" */
+110,	/* "CAST5-CFB" */
+109,	/* "CAST5-ECB" */
+111,	/* "CAST5-OFB" */
+13,	/* "CN" */
+141,	/* "CRLReason" */
+417,	/* "CSPName" */
+367,	/* "CrlID" */
+391,	/* "DC" */
+31,	/* "DES-CBC" */
+643,	/* "DES-CDMF" */
+30,	/* "DES-CFB" */
+656,	/* "DES-CFB1" */
+657,	/* "DES-CFB8" */
+29,	/* "DES-ECB" */
+32,	/* "DES-EDE" */
+43,	/* "DES-EDE-CBC" */
+60,	/* "DES-EDE-CFB" */
+62,	/* "DES-EDE-OFB" */
+33,	/* "DES-EDE3" */
+44,	/* "DES-EDE3-CBC" */
+61,	/* "DES-EDE3-CFB" */
+658,	/* "DES-EDE3-CFB1" */
+659,	/* "DES-EDE3-CFB8" */
+63,	/* "DES-EDE3-OFB" */
+45,	/* "DES-OFB" */
+80,	/* "DESX-CBC" */
+380,	/* "DOD" */
+116,	/* "DSA" */
+66,	/* "DSA-SHA" */
+113,	/* "DSA-SHA1" */
+70,	/* "DSA-SHA1-old" */
+67,	/* "DSA-old" */
+297,	/* "DVCS" */
+99,	/* "GN" */
+855,	/* "HMAC" */
+780,	/* "HMAC-MD5" */
+781,	/* "HMAC-SHA1" */
+381,	/* "IANA" */
+34,	/* "IDEA-CBC" */
+35,	/* "IDEA-CFB" */
+36,	/* "IDEA-ECB" */
+46,	/* "IDEA-OFB" */
+181,	/* "ISO" */
+183,	/* "ISO-US" */
+645,	/* "ITU-T" */
+646,	/* "JOINT-ISO-ITU-T" */
+773,	/* "KISA" */
+15,	/* "L" */
+856,	/* "LocalKeySet" */
+ 3,	/* "MD2" */
+257,	/* "MD4" */
+ 4,	/* "MD5" */
+114,	/* "MD5-SHA1" */
+95,	/* "MDC2" */
+388,	/* "Mail" */
+393,	/* "NULL" */
+404,	/* "NULL" */
+57,	/* "Netscape" */
+366,	/* "Nonce" */
+17,	/* "O" */
+178,	/* "OCSP" */
+180,	/* "OCSPSigning" */
+379,	/* "ORG" */
+18,	/* "OU" */
+749,	/* "Oakley-EC2N-3" */
+750,	/* "Oakley-EC2N-4" */
+ 9,	/* "PBE-MD2-DES" */
+168,	/* "PBE-MD2-RC2-64" */
+10,	/* "PBE-MD5-DES" */
+169,	/* "PBE-MD5-RC2-64" */
+147,	/* "PBE-SHA1-2DES" */
+146,	/* "PBE-SHA1-3DES" */
+170,	/* "PBE-SHA1-DES" */
+148,	/* "PBE-SHA1-RC2-128" */
+149,	/* "PBE-SHA1-RC2-40" */
+68,	/* "PBE-SHA1-RC2-64" */
+144,	/* "PBE-SHA1-RC4-128" */
+145,	/* "PBE-SHA1-RC4-40" */
+161,	/* "PBES2" */
+69,	/* "PBKDF2" */
+162,	/* "PBMAC1" */
+127,	/* "PKIX" */
+98,	/* "RC2-40-CBC" */
+166,	/* "RC2-64-CBC" */
+37,	/* "RC2-CBC" */
+39,	/* "RC2-CFB" */
+38,	/* "RC2-ECB" */
+40,	/* "RC2-OFB" */
+ 5,	/* "RC4" */
+97,	/* "RC4-40" */
+120,	/* "RC5-CBC" */
+122,	/* "RC5-CFB" */
+121,	/* "RC5-ECB" */
+123,	/* "RC5-OFB" */
+117,	/* "RIPEMD160" */
+124,	/* "RLE" */
+19,	/* "RSA" */
+ 7,	/* "RSA-MD2" */
+396,	/* "RSA-MD4" */
+ 8,	/* "RSA-MD5" */
+96,	/* "RSA-MDC2" */
+104,	/* "RSA-NP-MD5" */
+119,	/* "RSA-RIPEMD160" */
+42,	/* "RSA-SHA" */
+65,	/* "RSA-SHA1" */
+115,	/* "RSA-SHA1-2" */
+671,	/* "RSA-SHA224" */
+668,	/* "RSA-SHA256" */
+669,	/* "RSA-SHA384" */
+670,	/* "RSA-SHA512" */
+777,	/* "SEED-CBC" */
+779,	/* "SEED-CFB" */
+776,	/* "SEED-ECB" */
+778,	/* "SEED-OFB" */
+41,	/* "SHA" */
+64,	/* "SHA1" */
+675,	/* "SHA224" */
+672,	/* "SHA256" */
+673,	/* "SHA384" */
+674,	/* "SHA512" */
+188,	/* "SMIME" */
+167,	/* "SMIME-CAPS" */
+100,	/* "SN" */
+16,	/* "ST" */
+143,	/* "SXNetID" */
+458,	/* "UID" */
+ 0,	/* "UNDEF" */
+11,	/* "X500" */
+378,	/* "X500algorithms" */
+12,	/* "X509" */
+184,	/* "X9-57" */
+185,	/* "X9cm" */
+125,	/* "ZLIB" */
+478,	/* "aRecord" */
+289,	/* "aaControls" */
+287,	/* "ac-auditEntity" */
+397,	/* "ac-proxying" */
+288,	/* "ac-targeting" */
+368,	/* "acceptableResponses" */
+446,	/* "account" */
+363,	/* "ad_timestamping" */
+376,	/* "algorithm" */
+405,	/* "ansi-X9-62" */
+746,	/* "anyPolicy" */
+370,	/* "archiveCutoff" */
+484,	/* "associatedDomain" */
+485,	/* "associatedName" */
+501,	/* "audio" */
+177,	/* "authorityInfoAccess" */
+90,	/* "authorityKeyIdentifier" */
+882,	/* "authorityRevocationList" */
+87,	/* "basicConstraints" */
+365,	/* "basicOCSPResponse" */
+285,	/* "biometricInfo" */
+494,	/* "buildingName" */
+860,	/* "businessCategory" */
+691,	/* "c2onb191v4" */
+692,	/* "c2onb191v5" */
+697,	/* "c2onb239v4" */
+698,	/* "c2onb239v5" */
+684,	/* "c2pnb163v1" */
+685,	/* "c2pnb163v2" */
+686,	/* "c2pnb163v3" */
+687,	/* "c2pnb176v1" */
+693,	/* "c2pnb208w1" */
+699,	/* "c2pnb272w1" */
+700,	/* "c2pnb304w1" */
+702,	/* "c2pnb368w1" */
+688,	/* "c2tnb191v1" */
+689,	/* "c2tnb191v2" */
+690,	/* "c2tnb191v3" */
+694,	/* "c2tnb239v1" */
+695,	/* "c2tnb239v2" */
+696,	/* "c2tnb239v3" */
+701,	/* "c2tnb359v1" */
+703,	/* "c2tnb431r1" */
+881,	/* "cACertificate" */
+483,	/* "cNAMERecord" */
+179,	/* "caIssuers" */
+785,	/* "caRepository" */
+443,	/* "caseIgnoreIA5StringSyntax" */
+152,	/* "certBag" */
+677,	/* "certicom-arc" */
+771,	/* "certificateIssuer" */
+89,	/* "certificatePolicies" */
+883,	/* "certificateRevocationList" */
+54,	/* "challengePassword" */
+407,	/* "characteristic-two-field" */
+395,	/* "clearance" */
+130,	/* "clientAuth" */
+131,	/* "codeSigning" */
+50,	/* "contentType" */
+53,	/* "countersignature" */
+153,	/* "crlBag" */
+103,	/* "crlDistributionPoints" */
+88,	/* "crlNumber" */
+884,	/* "crossCertificatePair" */
+806,	/* "cryptocom" */
+805,	/* "cryptopro" */
+500,	/* "dITRedirect" */
+451,	/* "dNSDomain" */
+495,	/* "dSAQuality" */
+434,	/* "data" */
+390,	/* "dcobject" */
+140,	/* "deltaCRL" */
+891,	/* "deltaRevocationList" */
+107,	/* "description" */
+871,	/* "destinationIndicator" */
+28,	/* "dhKeyAgreement" */
+382,	/* "directory" */
+887,	/* "distinguishedName" */
+892,	/* "dmdName" */
+174,	/* "dnQualifier" */
+447,	/* "document" */
+471,	/* "documentAuthor" */
+468,	/* "documentIdentifier" */
+472,	/* "documentLocation" */
+502,	/* "documentPublisher" */
+449,	/* "documentSeries" */
+469,	/* "documentTitle" */
+470,	/* "documentVersion" */
+392,	/* "domain" */
+452,	/* "domainRelatedObject" */
+802,	/* "dsa_with_SHA224" */
+803,	/* "dsa_with_SHA256" */
+791,	/* "ecdsa-with-Recommended" */
+416,	/* "ecdsa-with-SHA1" */
+793,	/* "ecdsa-with-SHA224" */
+794,	/* "ecdsa-with-SHA256" */
+795,	/* "ecdsa-with-SHA384" */
+796,	/* "ecdsa-with-SHA512" */
+792,	/* "ecdsa-with-Specified" */
+48,	/* "emailAddress" */
+132,	/* "emailProtection" */
+885,	/* "enhancedSearchGuide" */
+389,	/* "enterprises" */
+384,	/* "experimental" */
+172,	/* "extReq" */
+56,	/* "extendedCertificateAttributes" */
+126,	/* "extendedKeyUsage" */
+372,	/* "extendedStatus" */
+867,	/* "facsimileTelephoneNumber" */
+462,	/* "favouriteDrink" */
+857,	/* "freshestCRL" */
+453,	/* "friendlyCountry" */
+490,	/* "friendlyCountryName" */
+156,	/* "friendlyName" */
+509,	/* "generationQualifier" */
+815,	/* "gost-mac" */
+811,	/* "gost2001" */
+851,	/* "gost2001cc" */
+813,	/* "gost89" */
+814,	/* "gost89-cnt" */
+812,	/* "gost94" */
+850,	/* "gost94cc" */
+797,	/* "hmacWithMD5" */
+163,	/* "hmacWithSHA1" */
+798,	/* "hmacWithSHA224" */
+799,	/* "hmacWithSHA256" */
+800,	/* "hmacWithSHA384" */
+801,	/* "hmacWithSHA512" */
+432,	/* "holdInstructionCallIssuer" */
+430,	/* "holdInstructionCode" */
+431,	/* "holdInstructionNone" */
+433,	/* "holdInstructionReject" */
+486,	/* "homePostalAddress" */
+473,	/* "homeTelephoneNumber" */
+466,	/* "host" */
+889,	/* "houseIdentifier" */
+442,	/* "iA5StringSyntax" */
+783,	/* "id-DHBasedMac" */
+824,	/* "id-Gost28147-89-CryptoPro-A-ParamSet" */
+825,	/* "id-Gost28147-89-CryptoPro-B-ParamSet" */
+826,	/* "id-Gost28147-89-CryptoPro-C-ParamSet" */
+827,	/* "id-Gost28147-89-CryptoPro-D-ParamSet" */
+819,	/* "id-Gost28147-89-CryptoPro-KeyMeshing" */
+829,	/* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */
+828,	/* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */
+830,	/* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */
+820,	/* "id-Gost28147-89-None-KeyMeshing" */
+823,	/* "id-Gost28147-89-TestParamSet" */
+849,	/* "id-Gost28147-89-cc" */
+840,	/* "id-GostR3410-2001-CryptoPro-A-ParamSet" */
+841,	/* "id-GostR3410-2001-CryptoPro-B-ParamSet" */
+842,	/* "id-GostR3410-2001-CryptoPro-C-ParamSet" */
+843,	/* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */
+844,	/* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */
+854,	/* "id-GostR3410-2001-ParamSet-cc" */
+839,	/* "id-GostR3410-2001-TestParamSet" */
+817,	/* "id-GostR3410-2001DH" */
+832,	/* "id-GostR3410-94-CryptoPro-A-ParamSet" */
+833,	/* "id-GostR3410-94-CryptoPro-B-ParamSet" */
+834,	/* "id-GostR3410-94-CryptoPro-C-ParamSet" */
+835,	/* "id-GostR3410-94-CryptoPro-D-ParamSet" */
+836,	/* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */
+837,	/* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */
+838,	/* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */
+831,	/* "id-GostR3410-94-TestParamSet" */
+845,	/* "id-GostR3410-94-a" */
+846,	/* "id-GostR3410-94-aBis" */
+847,	/* "id-GostR3410-94-b" */
+848,	/* "id-GostR3410-94-bBis" */
+818,	/* "id-GostR3410-94DH" */
+822,	/* "id-GostR3411-94-CryptoProParamSet" */
+821,	/* "id-GostR3411-94-TestParamSet" */
+807,	/* "id-GostR3411-94-with-GostR3410-2001" */
+853,	/* "id-GostR3411-94-with-GostR3410-2001-cc" */
+808,	/* "id-GostR3411-94-with-GostR3410-94" */
+852,	/* "id-GostR3411-94-with-GostR3410-94-cc" */
+810,	/* "id-HMACGostR3411-94" */
+782,	/* "id-PasswordBasedMAC" */
+266,	/* "id-aca" */
+355,	/* "id-aca-accessIdentity" */
+354,	/* "id-aca-authenticationInfo" */
+356,	/* "id-aca-chargingIdentity" */
+399,	/* "id-aca-encAttrs" */
+357,	/* "id-aca-group" */
+358,	/* "id-aca-role" */
+176,	/* "id-ad" */
+788,	/* "id-aes128-wrap" */
+789,	/* "id-aes192-wrap" */
+790,	/* "id-aes256-wrap" */
+262,	/* "id-alg" */
+323,	/* "id-alg-des40" */
+326,	/* "id-alg-dh-pop" */
+325,	/* "id-alg-dh-sig-hmac-sha1" */
+324,	/* "id-alg-noSignature" */
+268,	/* "id-cct" */
+361,	/* "id-cct-PKIData" */
+362,	/* "id-cct-PKIResponse" */
+360,	/* "id-cct-crs" */
+81,	/* "id-ce" */
+680,	/* "id-characteristic-two-basis" */
+263,	/* "id-cmc" */
+334,	/* "id-cmc-addExtensions" */
+346,	/* "id-cmc-confirmCertAcceptance" */
+330,	/* "id-cmc-dataReturn" */
+336,	/* "id-cmc-decryptedPOP" */
+335,	/* "id-cmc-encryptedPOP" */
+339,	/* "id-cmc-getCRL" */
+338,	/* "id-cmc-getCert" */
+328,	/* "id-cmc-identification" */
+329,	/* "id-cmc-identityProof" */
+337,	/* "id-cmc-lraPOPWitness" */
+344,	/* "id-cmc-popLinkRandom" */
+345,	/* "id-cmc-popLinkWitness" */
+343,	/* "id-cmc-queryPending" */
+333,	/* "id-cmc-recipientNonce" */
+341,	/* "id-cmc-regInfo" */
+342,	/* "id-cmc-responseInfo" */
+340,	/* "id-cmc-revokeRequest" */
+332,	/* "id-cmc-senderNonce" */
+327,	/* "id-cmc-statusInfo" */
+331,	/* "id-cmc-transactionId" */
+787,	/* "id-ct-asciiTextWithCRLF" */
+408,	/* "id-ecPublicKey" */
+508,	/* "id-hex-multipart-message" */
+507,	/* "id-hex-partial-message" */
+260,	/* "id-it" */
+302,	/* "id-it-caKeyUpdateInfo" */
+298,	/* "id-it-caProtEncCert" */
+311,	/* "id-it-confirmWaitTime" */
+303,	/* "id-it-currentCRL" */
+300,	/* "id-it-encKeyPairTypes" */
+310,	/* "id-it-implicitConfirm" */
+308,	/* "id-it-keyPairParamRep" */
+307,	/* "id-it-keyPairParamReq" */
+312,	/* "id-it-origPKIMessage" */
+301,	/* "id-it-preferredSymmAlg" */
+309,	/* "id-it-revPassphrase" */
+299,	/* "id-it-signKeyPairTypes" */
+305,	/* "id-it-subscriptionRequest" */
+306,	/* "id-it-subscriptionResponse" */
+784,	/* "id-it-suppLangTags" */
+304,	/* "id-it-unsupportedOIDs" */
+128,	/* "id-kp" */
+280,	/* "id-mod-attribute-cert" */
+274,	/* "id-mod-cmc" */
+277,	/* "id-mod-cmp" */
+284,	/* "id-mod-cmp2000" */
+273,	/* "id-mod-crmf" */
+283,	/* "id-mod-dvcs" */
+275,	/* "id-mod-kea-profile-88" */
+276,	/* "id-mod-kea-profile-93" */
+282,	/* "id-mod-ocsp" */
+278,	/* "id-mod-qualified-cert-88" */
+279,	/* "id-mod-qualified-cert-93" */
+281,	/* "id-mod-timestamp-protocol" */
+264,	/* "id-on" */
+858,	/* "id-on-permanentIdentifier" */
+347,	/* "id-on-personalData" */
+265,	/* "id-pda" */
+352,	/* "id-pda-countryOfCitizenship" */
+353,	/* "id-pda-countryOfResidence" */
+348,	/* "id-pda-dateOfBirth" */
+351,	/* "id-pda-gender" */
+349,	/* "id-pda-placeOfBirth" */
+175,	/* "id-pe" */
+261,	/* "id-pkip" */
+258,	/* "id-pkix-mod" */
+269,	/* "id-pkix1-explicit-88" */
+271,	/* "id-pkix1-explicit-93" */
+270,	/* "id-pkix1-implicit-88" */
+272,	/* "id-pkix1-implicit-93" */
+662,	/* "id-ppl" */
+664,	/* "id-ppl-anyLanguage" */
+667,	/* "id-ppl-independent" */
+665,	/* "id-ppl-inheritAll" */
+267,	/* "id-qcs" */
+359,	/* "id-qcs-pkixQCSyntax-v1" */
+259,	/* "id-qt" */
+164,	/* "id-qt-cps" */
+165,	/* "id-qt-unotice" */
+313,	/* "id-regCtrl" */
+316,	/* "id-regCtrl-authenticator" */
+319,	/* "id-regCtrl-oldCertID" */
+318,	/* "id-regCtrl-pkiArchiveOptions" */
+317,	/* "id-regCtrl-pkiPublicationInfo" */
+320,	/* "id-regCtrl-protocolEncrKey" */
+315,	/* "id-regCtrl-regToken" */
+314,	/* "id-regInfo" */
+322,	/* "id-regInfo-certReq" */
+321,	/* "id-regInfo-utf8Pairs" */
+512,	/* "id-set" */
+191,	/* "id-smime-aa" */
+215,	/* "id-smime-aa-contentHint" */
+218,	/* "id-smime-aa-contentIdentifier" */
+221,	/* "id-smime-aa-contentReference" */
+240,	/* "id-smime-aa-dvcs-dvc" */
+217,	/* "id-smime-aa-encapContentType" */
+222,	/* "id-smime-aa-encrypKeyPref" */
+220,	/* "id-smime-aa-equivalentLabels" */
+232,	/* "id-smime-aa-ets-CertificateRefs" */
+233,	/* "id-smime-aa-ets-RevocationRefs" */
+238,	/* "id-smime-aa-ets-archiveTimeStamp" */
+237,	/* "id-smime-aa-ets-certCRLTimestamp" */
+234,	/* "id-smime-aa-ets-certValues" */
+227,	/* "id-smime-aa-ets-commitmentType" */
+231,	/* "id-smime-aa-ets-contentTimestamp" */
+236,	/* "id-smime-aa-ets-escTimeStamp" */
+230,	/* "id-smime-aa-ets-otherSigCert" */
+235,	/* "id-smime-aa-ets-revocationValues" */
+226,	/* "id-smime-aa-ets-sigPolicyId" */
+229,	/* "id-smime-aa-ets-signerAttr" */
+228,	/* "id-smime-aa-ets-signerLocation" */
+219,	/* "id-smime-aa-macValue" */
+214,	/* "id-smime-aa-mlExpandHistory" */
+216,	/* "id-smime-aa-msgSigDigest" */
+212,	/* "id-smime-aa-receiptRequest" */
+213,	/* "id-smime-aa-securityLabel" */
+239,	/* "id-smime-aa-signatureType" */
+223,	/* "id-smime-aa-signingCertificate" */
+224,	/* "id-smime-aa-smimeEncryptCerts" */
+225,	/* "id-smime-aa-timeStampToken" */
+192,	/* "id-smime-alg" */
+243,	/* "id-smime-alg-3DESwrap" */
+246,	/* "id-smime-alg-CMS3DESwrap" */
+247,	/* "id-smime-alg-CMSRC2wrap" */
+245,	/* "id-smime-alg-ESDH" */
+241,	/* "id-smime-alg-ESDHwith3DES" */
+242,	/* "id-smime-alg-ESDHwithRC2" */
+244,	/* "id-smime-alg-RC2wrap" */
+193,	/* "id-smime-cd" */
+248,	/* "id-smime-cd-ldap" */
+190,	/* "id-smime-ct" */
+210,	/* "id-smime-ct-DVCSRequestData" */
+211,	/* "id-smime-ct-DVCSResponseData" */
+208,	/* "id-smime-ct-TDTInfo" */
+207,	/* "id-smime-ct-TSTInfo" */
+205,	/* "id-smime-ct-authData" */
+786,	/* "id-smime-ct-compressedData" */
+209,	/* "id-smime-ct-contentInfo" */
+206,	/* "id-smime-ct-publishCert" */
+204,	/* "id-smime-ct-receipt" */
+195,	/* "id-smime-cti" */
+255,	/* "id-smime-cti-ets-proofOfApproval" */
+256,	/* "id-smime-cti-ets-proofOfCreation" */
+253,	/* "id-smime-cti-ets-proofOfDelivery" */
+251,	/* "id-smime-cti-ets-proofOfOrigin" */
+252,	/* "id-smime-cti-ets-proofOfReceipt" */
+254,	/* "id-smime-cti-ets-proofOfSender" */
+189,	/* "id-smime-mod" */
+196,	/* "id-smime-mod-cms" */
+197,	/* "id-smime-mod-ess" */
+202,	/* "id-smime-mod-ets-eSigPolicy-88" */
+203,	/* "id-smime-mod-ets-eSigPolicy-97" */
+200,	/* "id-smime-mod-ets-eSignature-88" */
+201,	/* "id-smime-mod-ets-eSignature-97" */
+199,	/* "id-smime-mod-msg-v3" */
+198,	/* "id-smime-mod-oid" */
+194,	/* "id-smime-spq" */
+250,	/* "id-smime-spq-ets-sqt-unotice" */
+249,	/* "id-smime-spq-ets-sqt-uri" */
+676,	/* "identified-organization" */
+461,	/* "info" */
+748,	/* "inhibitAnyPolicy" */
+101,	/* "initials" */
+647,	/* "international-organizations" */
+869,	/* "internationaliSDNNumber" */
+142,	/* "invalidityDate" */
+294,	/* "ipsecEndSystem" */
+295,	/* "ipsecTunnel" */
+296,	/* "ipsecUser" */
+86,	/* "issuerAltName" */
+770,	/* "issuingDistributionPoint" */
+492,	/* "janetMailbox" */
+150,	/* "keyBag" */
+83,	/* "keyUsage" */
+477,	/* "lastModifiedBy" */
+476,	/* "lastModifiedTime" */
+157,	/* "localKeyID" */
+480,	/* "mXRecord" */
+460,	/* "mail" */
+493,	/* "mailPreferenceOption" */
+467,	/* "manager" */
+809,	/* "md_gost94" */
+875,	/* "member" */
+182,	/* "member-body" */
+51,	/* "messageDigest" */
+383,	/* "mgmt" */
+504,	/* "mime-mhs" */
+506,	/* "mime-mhs-bodies" */
+505,	/* "mime-mhs-headings" */
+488,	/* "mobileTelephoneNumber" */
+136,	/* "msCTLSign" */
+135,	/* "msCodeCom" */
+134,	/* "msCodeInd" */
+138,	/* "msEFS" */
+171,	/* "msExtReq" */
+137,	/* "msSGC" */
+648,	/* "msSmartcardLogin" */
+649,	/* "msUPN" */
+481,	/* "nSRecord" */
+173,	/* "name" */
+666,	/* "nameConstraints" */
+369,	/* "noCheck" */
+403,	/* "noRevAvail" */
+72,	/* "nsBaseUrl" */
+76,	/* "nsCaPolicyUrl" */
+74,	/* "nsCaRevocationUrl" */
+58,	/* "nsCertExt" */
+79,	/* "nsCertSequence" */
+71,	/* "nsCertType" */
+78,	/* "nsComment" */
+59,	/* "nsDataType" */
+75,	/* "nsRenewalUrl" */
+73,	/* "nsRevocationUrl" */
+139,	/* "nsSGC" */
+77,	/* "nsSslServerName" */
+681,	/* "onBasis" */
+491,	/* "organizationalStatus" */
+475,	/* "otherMailbox" */
+876,	/* "owner" */
+489,	/* "pagerTelephoneNumber" */
+374,	/* "path" */
+112,	/* "pbeWithMD5AndCast5CBC" */
+499,	/* "personalSignature" */
+487,	/* "personalTitle" */
+464,	/* "photo" */
+863,	/* "physicalDeliveryOfficeName" */
+437,	/* "pilot" */
+439,	/* "pilotAttributeSyntax" */
+438,	/* "pilotAttributeType" */
+479,	/* "pilotAttributeType27" */
+456,	/* "pilotDSA" */
+441,	/* "pilotGroups" */
+444,	/* "pilotObject" */
+440,	/* "pilotObjectClass" */
+455,	/* "pilotOrganization" */
+445,	/* "pilotPerson" */
+ 2,	/* "pkcs" */
+186,	/* "pkcs1" */
+27,	/* "pkcs3" */
+187,	/* "pkcs5" */
+20,	/* "pkcs7" */
+21,	/* "pkcs7-data" */
+25,	/* "pkcs7-digestData" */
+26,	/* "pkcs7-encryptedData" */
+23,	/* "pkcs7-envelopedData" */
+24,	/* "pkcs7-signedAndEnvelopedData" */
+22,	/* "pkcs7-signedData" */
+151,	/* "pkcs8ShroudedKeyBag" */
+47,	/* "pkcs9" */
+401,	/* "policyConstraints" */
+747,	/* "policyMappings" */
+862,	/* "postOfficeBox" */
+861,	/* "postalAddress" */
+661,	/* "postalCode" */
+683,	/* "ppBasis" */
+872,	/* "preferredDeliveryMethod" */
+873,	/* "presentationAddress" */
+816,	/* "prf-gostr3411-94" */
+406,	/* "prime-field" */
+409,	/* "prime192v1" */
+410,	/* "prime192v2" */
+411,	/* "prime192v3" */
+412,	/* "prime239v1" */
+413,	/* "prime239v2" */
+414,	/* "prime239v3" */
+415,	/* "prime256v1" */
+385,	/* "private" */
+84,	/* "privateKeyUsagePeriod" */
+886,	/* "protocolInformation" */
+663,	/* "proxyCertInfo" */
+510,	/* "pseudonym" */
+435,	/* "pss" */
+286,	/* "qcStatements" */
+457,	/* "qualityLabelledData" */
+450,	/* "rFC822localPart" */
+870,	/* "registeredAddress" */
+400,	/* "role" */
+877,	/* "roleOccupant" */
+448,	/* "room" */
+463,	/* "roomNumber" */
+ 6,	/* "rsaEncryption" */
+644,	/* "rsaOAEPEncryptionSET" */
+377,	/* "rsaSignature" */
+ 1,	/* "rsadsi" */
+482,	/* "sOARecord" */
+155,	/* "safeContentsBag" */
+291,	/* "sbgp-autonomousSysNum" */
+290,	/* "sbgp-ipAddrBlock" */
+292,	/* "sbgp-routerIdentifier" */
+159,	/* "sdsiCertificate" */
+859,	/* "searchGuide" */
+704,	/* "secp112r1" */
+705,	/* "secp112r2" */
+706,	/* "secp128r1" */
+707,	/* "secp128r2" */
+708,	/* "secp160k1" */
+709,	/* "secp160r1" */
+710,	/* "secp160r2" */
+711,	/* "secp192k1" */
+712,	/* "secp224k1" */
+713,	/* "secp224r1" */
+714,	/* "secp256k1" */
+715,	/* "secp384r1" */
+716,	/* "secp521r1" */
+154,	/* "secretBag" */
+474,	/* "secretary" */
+717,	/* "sect113r1" */
+718,	/* "sect113r2" */
+719,	/* "sect131r1" */
+720,	/* "sect131r2" */
+721,	/* "sect163k1" */
+722,	/* "sect163r1" */
+723,	/* "sect163r2" */
+724,	/* "sect193r1" */
+725,	/* "sect193r2" */
+726,	/* "sect233k1" */
+727,	/* "sect233r1" */
+728,	/* "sect239k1" */
+729,	/* "sect283k1" */
+730,	/* "sect283r1" */
+731,	/* "sect409k1" */
+732,	/* "sect409r1" */
+733,	/* "sect571k1" */
+734,	/* "sect571r1" */
+386,	/* "security" */
+878,	/* "seeAlso" */
+394,	/* "selected-attribute-types" */
+105,	/* "serialNumber" */
+129,	/* "serverAuth" */
+371,	/* "serviceLocator" */
+625,	/* "set-addPolicy" */
+515,	/* "set-attr" */
+518,	/* "set-brand" */
+638,	/* "set-brand-AmericanExpress" */
+637,	/* "set-brand-Diners" */
+636,	/* "set-brand-IATA-ATA" */
+639,	/* "set-brand-JCB" */
+641,	/* "set-brand-MasterCard" */
+642,	/* "set-brand-Novus" */
+640,	/* "set-brand-Visa" */
+517,	/* "set-certExt" */
+513,	/* "set-ctype" */
+514,	/* "set-msgExt" */
+516,	/* "set-policy" */
+607,	/* "set-policy-root" */
+624,	/* "set-rootKeyThumb" */
+620,	/* "setAttr-Cert" */
+631,	/* "setAttr-GenCryptgrm" */
+623,	/* "setAttr-IssCap" */
+628,	/* "setAttr-IssCap-CVM" */
+630,	/* "setAttr-IssCap-Sig" */
+629,	/* "setAttr-IssCap-T2" */
+621,	/* "setAttr-PGWYcap" */
+635,	/* "setAttr-SecDevSig" */
+632,	/* "setAttr-T2Enc" */
+633,	/* "setAttr-T2cleartxt" */
+634,	/* "setAttr-TokICCsig" */
+627,	/* "setAttr-Token-B0Prime" */
+626,	/* "setAttr-Token-EMV" */
+622,	/* "setAttr-TokenType" */
+619,	/* "setCext-IssuerCapabilities" */
+615,	/* "setCext-PGWYcapabilities" */
+616,	/* "setCext-TokenIdentifier" */
+618,	/* "setCext-TokenType" */
+617,	/* "setCext-Track2Data" */
+611,	/* "setCext-cCertRequired" */
+609,	/* "setCext-certType" */
+608,	/* "setCext-hashedRoot" */
+610,	/* "setCext-merchData" */
+613,	/* "setCext-setExt" */
+614,	/* "setCext-setQualf" */
+612,	/* "setCext-tunneling" */
+540,	/* "setct-AcqCardCodeMsg" */
+576,	/* "setct-AcqCardCodeMsgTBE" */
+570,	/* "setct-AuthReqTBE" */
+534,	/* "setct-AuthReqTBS" */
+527,	/* "setct-AuthResBaggage" */
+571,	/* "setct-AuthResTBE" */
+572,	/* "setct-AuthResTBEX" */
+535,	/* "setct-AuthResTBS" */
+536,	/* "setct-AuthResTBSX" */
+528,	/* "setct-AuthRevReqBaggage" */
+577,	/* "setct-AuthRevReqTBE" */
+541,	/* "setct-AuthRevReqTBS" */
+529,	/* "setct-AuthRevResBaggage" */
+542,	/* "setct-AuthRevResData" */
+578,	/* "setct-AuthRevResTBE" */
+579,	/* "setct-AuthRevResTBEB" */
+543,	/* "setct-AuthRevResTBS" */
+573,	/* "setct-AuthTokenTBE" */
+537,	/* "setct-AuthTokenTBS" */
+600,	/* "setct-BCIDistributionTBS" */
+558,	/* "setct-BatchAdminReqData" */
+592,	/* "setct-BatchAdminReqTBE" */
+559,	/* "setct-BatchAdminResData" */
+593,	/* "setct-BatchAdminResTBE" */
+599,	/* "setct-CRLNotificationResTBS" */
+598,	/* "setct-CRLNotificationTBS" */
+580,	/* "setct-CapReqTBE" */
+581,	/* "setct-CapReqTBEX" */
+544,	/* "setct-CapReqTBS" */
+545,	/* "setct-CapReqTBSX" */
+546,	/* "setct-CapResData" */
+582,	/* "setct-CapResTBE" */
+583,	/* "setct-CapRevReqTBE" */
+584,	/* "setct-CapRevReqTBEX" */
+547,	/* "setct-CapRevReqTBS" */
+548,	/* "setct-CapRevReqTBSX" */
+549,	/* "setct-CapRevResData" */
+585,	/* "setct-CapRevResTBE" */
+538,	/* "setct-CapTokenData" */
+530,	/* "setct-CapTokenSeq" */
+574,	/* "setct-CapTokenTBE" */
+575,	/* "setct-CapTokenTBEX" */
+539,	/* "setct-CapTokenTBS" */
+560,	/* "setct-CardCInitResTBS" */
+566,	/* "setct-CertInqReqTBS" */
+563,	/* "setct-CertReqData" */
+595,	/* "setct-CertReqTBE" */
+596,	/* "setct-CertReqTBEX" */
+564,	/* "setct-CertReqTBS" */
+565,	/* "setct-CertResData" */
+597,	/* "setct-CertResTBE" */
+586,	/* "setct-CredReqTBE" */
+587,	/* "setct-CredReqTBEX" */
+550,	/* "setct-CredReqTBS" */
+551,	/* "setct-CredReqTBSX" */
+552,	/* "setct-CredResData" */
+588,	/* "setct-CredResTBE" */
+589,	/* "setct-CredRevReqTBE" */
+590,	/* "setct-CredRevReqTBEX" */
+553,	/* "setct-CredRevReqTBS" */
+554,	/* "setct-CredRevReqTBSX" */
+555,	/* "setct-CredRevResData" */
+591,	/* "setct-CredRevResTBE" */
+567,	/* "setct-ErrorTBS" */
+526,	/* "setct-HODInput" */
+561,	/* "setct-MeAqCInitResTBS" */
+522,	/* "setct-OIData" */
+519,	/* "setct-PANData" */
+521,	/* "setct-PANOnly" */
+520,	/* "setct-PANToken" */
+556,	/* "setct-PCertReqData" */
+557,	/* "setct-PCertResTBS" */
+523,	/* "setct-PI" */
+532,	/* "setct-PI-TBS" */
+524,	/* "setct-PIData" */
+525,	/* "setct-PIDataUnsigned" */
+568,	/* "setct-PIDualSignedTBE" */
+569,	/* "setct-PIUnsignedTBE" */
+531,	/* "setct-PInitResData" */
+533,	/* "setct-PResData" */
+594,	/* "setct-RegFormReqTBE" */
+562,	/* "setct-RegFormResTBS" */
+606,	/* "setext-cv" */
+601,	/* "setext-genCrypt" */
+602,	/* "setext-miAuth" */
+604,	/* "setext-pinAny" */
+603,	/* "setext-pinSecure" */
+605,	/* "setext-track2" */
+52,	/* "signingTime" */
+454,	/* "simpleSecurityObject" */
+496,	/* "singleLevelQuality" */
+387,	/* "snmpv2" */
+660,	/* "street" */
+85,	/* "subjectAltName" */
+769,	/* "subjectDirectoryAttributes" */
+398,	/* "subjectInfoAccess" */
+82,	/* "subjectKeyIdentifier" */
+498,	/* "subtreeMaximumQuality" */
+497,	/* "subtreeMinimumQuality" */
+890,	/* "supportedAlgorithms" */
+874,	/* "supportedApplicationContext" */
+402,	/* "targetInformation" */
+864,	/* "telephoneNumber" */
+866,	/* "teletexTerminalIdentifier" */
+865,	/* "telexNumber" */
+459,	/* "textEncodedORAddress" */
+293,	/* "textNotice" */
+133,	/* "timeStamping" */
+106,	/* "title" */
+682,	/* "tpBasis" */
+375,	/* "trustRoot" */
+436,	/* "ucl" */
+888,	/* "uniqueMember" */
+55,	/* "unstructuredAddress" */
+49,	/* "unstructuredName" */
+880,	/* "userCertificate" */
+465,	/* "userClass" */
+879,	/* "userPassword" */
+373,	/* "valid" */
+678,	/* "wap" */
+679,	/* "wap-wsg" */
+735,	/* "wap-wsg-idm-ecid-wtls1" */
+743,	/* "wap-wsg-idm-ecid-wtls10" */
+744,	/* "wap-wsg-idm-ecid-wtls11" */
+745,	/* "wap-wsg-idm-ecid-wtls12" */
+736,	/* "wap-wsg-idm-ecid-wtls3" */
+737,	/* "wap-wsg-idm-ecid-wtls4" */
+738,	/* "wap-wsg-idm-ecid-wtls5" */
+739,	/* "wap-wsg-idm-ecid-wtls6" */
+740,	/* "wap-wsg-idm-ecid-wtls7" */
+741,	/* "wap-wsg-idm-ecid-wtls8" */
+742,	/* "wap-wsg-idm-ecid-wtls9" */
+804,	/* "whirlpool" */
+868,	/* "x121Address" */
+503,	/* "x500UniqueIdentifier" */
+158,	/* "x509Certificate" */
+160,	/* "x509Crl" */
+};
+
+static const unsigned int ln_objs[NUM_LN]={
+363,	/* "AD Time Stamping" */
+405,	/* "ANSI X9.62" */
+368,	/* "Acceptable OCSP Responses" */
+664,	/* "Any language" */
+177,	/* "Authority Information Access" */
+365,	/* "Basic OCSP Response" */
+285,	/* "Biometric Info" */
+179,	/* "CA Issuers" */
+785,	/* "CA Repository" */
+131,	/* "Code Signing" */
+783,	/* "Diffie-Hellman based MAC" */
+382,	/* "Directory" */
+392,	/* "Domain" */
+132,	/* "E-mail Protection" */
+389,	/* "Enterprises" */
+384,	/* "Experimental" */
+372,	/* "Extended OCSP Status" */
+172,	/* "Extension Request" */
+813,	/* "GOST 28147-89" */
+849,	/* "GOST 28147-89 Cryptocom ParamSet" */
+815,	/* "GOST 28147-89 MAC" */
+851,	/* "GOST 34.10-2001 Cryptocom" */
+850,	/* "GOST 34.10-94 Cryptocom" */
+811,	/* "GOST R 34.10-2001" */
+817,	/* "GOST R 34.10-2001 DH" */
+812,	/* "GOST R 34.10-94" */
+818,	/* "GOST R 34.10-94 DH" */
+809,	/* "GOST R 34.11-94" */
+816,	/* "GOST R 34.11-94 PRF" */
+807,	/* "GOST R 34.11-94 with GOST R 34.10-2001" */
+853,	/* "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" */
+808,	/* "GOST R 34.11-94 with GOST R 34.10-94" */
+852,	/* "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" */
+854,	/* "GOST R 3410-2001 Parameter Set Cryptocom" */
+810,	/* "HMAC GOST 34.11-94" */
+432,	/* "Hold Instruction Call Issuer" */
+430,	/* "Hold Instruction Code" */
+431,	/* "Hold Instruction None" */
+433,	/* "Hold Instruction Reject" */
+634,	/* "ICC or token signature" */
+294,	/* "IPSec End System" */
+295,	/* "IPSec Tunnel" */
+296,	/* "IPSec User" */
+182,	/* "ISO Member Body" */
+183,	/* "ISO US Member Body" */
+667,	/* "Independent" */
+665,	/* "Inherit all" */
+647,	/* "International Organizations" */
+142,	/* "Invalidity Date" */
+504,	/* "MIME MHS" */
+388,	/* "Mail" */
+383,	/* "Management" */
+417,	/* "Microsoft CSP Name" */
+135,	/* "Microsoft Commercial Code Signing" */
+138,	/* "Microsoft Encrypted File System" */
+171,	/* "Microsoft Extension Request" */
+134,	/* "Microsoft Individual Code Signing" */
+856,	/* "Microsoft Local Key set" */
+137,	/* "Microsoft Server Gated Crypto" */
+648,	/* "Microsoft Smartcardlogin" */
+136,	/* "Microsoft Trust List Signing" */
+649,	/* "Microsoft Universal Principal Name" */
+393,	/* "NULL" */
+404,	/* "NULL" */
+72,	/* "Netscape Base Url" */
+76,	/* "Netscape CA Policy Url" */
+74,	/* "Netscape CA Revocation Url" */
+71,	/* "Netscape Cert Type" */
+58,	/* "Netscape Certificate Extension" */
+79,	/* "Netscape Certificate Sequence" */
+78,	/* "Netscape Comment" */
+57,	/* "Netscape Communications Corp." */
+59,	/* "Netscape Data Type" */
+75,	/* "Netscape Renewal Url" */
+73,	/* "Netscape Revocation Url" */
+77,	/* "Netscape SSL Server Name" */
+139,	/* "Netscape Server Gated Crypto" */
+178,	/* "OCSP" */
+370,	/* "OCSP Archive Cutoff" */
+367,	/* "OCSP CRL ID" */
+369,	/* "OCSP No Check" */
+366,	/* "OCSP Nonce" */
+371,	/* "OCSP Service Locator" */
+180,	/* "OCSP Signing" */
+161,	/* "PBES2" */
+69,	/* "PBKDF2" */
+162,	/* "PBMAC1" */
+127,	/* "PKIX" */
+858,	/* "Permanent Identifier" */
+164,	/* "Policy Qualifier CPS" */
+165,	/* "Policy Qualifier User Notice" */
+385,	/* "Private" */
+663,	/* "Proxy Certificate Information" */
+ 1,	/* "RSA Data Security, Inc." */
+ 2,	/* "RSA Data Security, Inc. PKCS" */
+188,	/* "S/MIME" */
+167,	/* "S/MIME Capabilities" */
+387,	/* "SNMPv2" */
+512,	/* "Secure Electronic Transactions" */
+386,	/* "Security" */
+394,	/* "Selected Attribute Types" */
+143,	/* "Strong Extranet ID" */
+398,	/* "Subject Information Access" */
+130,	/* "TLS Web Client Authentication" */
+129,	/* "TLS Web Server Authentication" */
+133,	/* "Time Stamping" */
+375,	/* "Trust Root" */
+12,	/* "X509" */
+402,	/* "X509v3 AC Targeting" */
+746,	/* "X509v3 Any Policy" */
+90,	/* "X509v3 Authority Key Identifier" */
+87,	/* "X509v3 Basic Constraints" */
+103,	/* "X509v3 CRL Distribution Points" */
+88,	/* "X509v3 CRL Number" */
+141,	/* "X509v3 CRL Reason Code" */
+771,	/* "X509v3 Certificate Issuer" */
+89,	/* "X509v3 Certificate Policies" */
+140,	/* "X509v3 Delta CRL Indicator" */
+126,	/* "X509v3 Extended Key Usage" */
+857,	/* "X509v3 Freshest CRL" */
+748,	/* "X509v3 Inhibit Any Policy" */
+86,	/* "X509v3 Issuer Alternative Name" */
+770,	/* "X509v3 Issuing Distrubution Point" */
+83,	/* "X509v3 Key Usage" */
+666,	/* "X509v3 Name Constraints" */
+403,	/* "X509v3 No Revocation Available" */
+401,	/* "X509v3 Policy Constraints" */
+747,	/* "X509v3 Policy Mappings" */
+84,	/* "X509v3 Private Key Usage Period" */
+85,	/* "X509v3 Subject Alternative Name" */
+769,	/* "X509v3 Subject Directory Attributes" */
+82,	/* "X509v3 Subject Key Identifier" */
+184,	/* "X9.57" */
+185,	/* "X9.57 CM ?" */
+478,	/* "aRecord" */
+289,	/* "aaControls" */
+287,	/* "ac-auditEntity" */
+397,	/* "ac-proxying" */
+288,	/* "ac-targeting" */
+446,	/* "account" */
+364,	/* "ad dvcs" */
+606,	/* "additional verification" */
+419,	/* "aes-128-cbc" */
+421,	/* "aes-128-cfb" */
+650,	/* "aes-128-cfb1" */
+653,	/* "aes-128-cfb8" */
+418,	/* "aes-128-ecb" */
+420,	/* "aes-128-ofb" */
+423,	/* "aes-192-cbc" */
+425,	/* "aes-192-cfb" */
+651,	/* "aes-192-cfb1" */
+654,	/* "aes-192-cfb8" */
+422,	/* "aes-192-ecb" */
+424,	/* "aes-192-ofb" */
+427,	/* "aes-256-cbc" */
+429,	/* "aes-256-cfb" */
+652,	/* "aes-256-cfb1" */
+655,	/* "aes-256-cfb8" */
+426,	/* "aes-256-ecb" */
+428,	/* "aes-256-ofb" */
+376,	/* "algorithm" */
+484,	/* "associatedDomain" */
+485,	/* "associatedName" */
+501,	/* "audio" */
+882,	/* "authorityRevocationList" */
+91,	/* "bf-cbc" */
+93,	/* "bf-cfb" */
+92,	/* "bf-ecb" */
+94,	/* "bf-ofb" */
+494,	/* "buildingName" */
+860,	/* "businessCategory" */
+691,	/* "c2onb191v4" */
+692,	/* "c2onb191v5" */
+697,	/* "c2onb239v4" */
+698,	/* "c2onb239v5" */
+684,	/* "c2pnb163v1" */
+685,	/* "c2pnb163v2" */
+686,	/* "c2pnb163v3" */
+687,	/* "c2pnb176v1" */
+693,	/* "c2pnb208w1" */
+699,	/* "c2pnb272w1" */
+700,	/* "c2pnb304w1" */
+702,	/* "c2pnb368w1" */
+688,	/* "c2tnb191v1" */
+689,	/* "c2tnb191v2" */
+690,	/* "c2tnb191v3" */
+694,	/* "c2tnb239v1" */
+695,	/* "c2tnb239v2" */
+696,	/* "c2tnb239v3" */
+701,	/* "c2tnb359v1" */
+703,	/* "c2tnb431r1" */
+881,	/* "cACertificate" */
+483,	/* "cNAMERecord" */
+751,	/* "camellia-128-cbc" */
+757,	/* "camellia-128-cfb" */
+760,	/* "camellia-128-cfb1" */
+763,	/* "camellia-128-cfb8" */
+754,	/* "camellia-128-ecb" */
+766,	/* "camellia-128-ofb" */
+752,	/* "camellia-192-cbc" */
+758,	/* "camellia-192-cfb" */
+761,	/* "camellia-192-cfb1" */
+764,	/* "camellia-192-cfb8" */
+755,	/* "camellia-192-ecb" */
+767,	/* "camellia-192-ofb" */
+753,	/* "camellia-256-cbc" */
+759,	/* "camellia-256-cfb" */
+762,	/* "camellia-256-cfb1" */
+765,	/* "camellia-256-cfb8" */
+756,	/* "camellia-256-ecb" */
+768,	/* "camellia-256-ofb" */
+443,	/* "caseIgnoreIA5StringSyntax" */
+108,	/* "cast5-cbc" */
+110,	/* "cast5-cfb" */
+109,	/* "cast5-ecb" */
+111,	/* "cast5-ofb" */
+152,	/* "certBag" */
+677,	/* "certicom-arc" */
+517,	/* "certificate extensions" */
+883,	/* "certificateRevocationList" */
+54,	/* "challengePassword" */
+407,	/* "characteristic-two-field" */
+395,	/* "clearance" */
+633,	/* "cleartext track 2" */
+13,	/* "commonName" */
+513,	/* "content types" */
+50,	/* "contentType" */
+53,	/* "countersignature" */
+14,	/* "countryName" */
+153,	/* "crlBag" */
+884,	/* "crossCertificatePair" */
+806,	/* "cryptocom" */
+805,	/* "cryptopro" */
+500,	/* "dITRedirect" */
+451,	/* "dNSDomain" */
+495,	/* "dSAQuality" */
+434,	/* "data" */
+390,	/* "dcObject" */
+891,	/* "deltaRevocationList" */
+31,	/* "des-cbc" */
+643,	/* "des-cdmf" */
+30,	/* "des-cfb" */
+656,	/* "des-cfb1" */
+657,	/* "des-cfb8" */
+29,	/* "des-ecb" */
+32,	/* "des-ede" */
+43,	/* "des-ede-cbc" */
+60,	/* "des-ede-cfb" */
+62,	/* "des-ede-ofb" */
+33,	/* "des-ede3" */
+44,	/* "des-ede3-cbc" */
+61,	/* "des-ede3-cfb" */
+658,	/* "des-ede3-cfb1" */
+659,	/* "des-ede3-cfb8" */
+63,	/* "des-ede3-ofb" */
+45,	/* "des-ofb" */
+107,	/* "description" */
+871,	/* "destinationIndicator" */
+80,	/* "desx-cbc" */
+28,	/* "dhKeyAgreement" */
+11,	/* "directory services (X.500)" */
+378,	/* "directory services - algorithms" */
+887,	/* "distinguishedName" */
+892,	/* "dmdName" */
+174,	/* "dnQualifier" */
+447,	/* "document" */
+471,	/* "documentAuthor" */
+468,	/* "documentIdentifier" */
+472,	/* "documentLocation" */
+502,	/* "documentPublisher" */
+449,	/* "documentSeries" */
+469,	/* "documentTitle" */
+470,	/* "documentVersion" */
+380,	/* "dod" */
+391,	/* "domainComponent" */
+452,	/* "domainRelatedObject" */
+116,	/* "dsaEncryption" */
+67,	/* "dsaEncryption-old" */
+66,	/* "dsaWithSHA" */
+113,	/* "dsaWithSHA1" */
+70,	/* "dsaWithSHA1-old" */
+802,	/* "dsa_with_SHA224" */
+803,	/* "dsa_with_SHA256" */
+297,	/* "dvcs" */
+791,	/* "ecdsa-with-Recommended" */
+416,	/* "ecdsa-with-SHA1" */
+793,	/* "ecdsa-with-SHA224" */
+794,	/* "ecdsa-with-SHA256" */
+795,	/* "ecdsa-with-SHA384" */
+796,	/* "ecdsa-with-SHA512" */
+792,	/* "ecdsa-with-Specified" */
+48,	/* "emailAddress" */
+632,	/* "encrypted track 2" */
+885,	/* "enhancedSearchGuide" */
+56,	/* "extendedCertificateAttributes" */
+867,	/* "facsimileTelephoneNumber" */
+462,	/* "favouriteDrink" */
+453,	/* "friendlyCountry" */
+490,	/* "friendlyCountryName" */
+156,	/* "friendlyName" */
+631,	/* "generate cryptogram" */
+509,	/* "generationQualifier" */
+601,	/* "generic cryptogram" */
+99,	/* "givenName" */
+814,	/* "gost89-cnt" */
+855,	/* "hmac" */
+780,	/* "hmac-md5" */
+781,	/* "hmac-sha1" */
+797,	/* "hmacWithMD5" */
+163,	/* "hmacWithSHA1" */
+798,	/* "hmacWithSHA224" */
+799,	/* "hmacWithSHA256" */
+800,	/* "hmacWithSHA384" */
+801,	/* "hmacWithSHA512" */
+486,	/* "homePostalAddress" */
+473,	/* "homeTelephoneNumber" */
+466,	/* "host" */
+889,	/* "houseIdentifier" */
+442,	/* "iA5StringSyntax" */
+381,	/* "iana" */
+824,	/* "id-Gost28147-89-CryptoPro-A-ParamSet" */
+825,	/* "id-Gost28147-89-CryptoPro-B-ParamSet" */
+826,	/* "id-Gost28147-89-CryptoPro-C-ParamSet" */
+827,	/* "id-Gost28147-89-CryptoPro-D-ParamSet" */
+819,	/* "id-Gost28147-89-CryptoPro-KeyMeshing" */
+829,	/* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */
+828,	/* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */
+830,	/* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */
+820,	/* "id-Gost28147-89-None-KeyMeshing" */
+823,	/* "id-Gost28147-89-TestParamSet" */
+840,	/* "id-GostR3410-2001-CryptoPro-A-ParamSet" */
+841,	/* "id-GostR3410-2001-CryptoPro-B-ParamSet" */
+842,	/* "id-GostR3410-2001-CryptoPro-C-ParamSet" */
+843,	/* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */
+844,	/* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */
+839,	/* "id-GostR3410-2001-TestParamSet" */
+832,	/* "id-GostR3410-94-CryptoPro-A-ParamSet" */
+833,	/* "id-GostR3410-94-CryptoPro-B-ParamSet" */
+834,	/* "id-GostR3410-94-CryptoPro-C-ParamSet" */
+835,	/* "id-GostR3410-94-CryptoPro-D-ParamSet" */
+836,	/* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */
+837,	/* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */
+838,	/* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */
+831,	/* "id-GostR3410-94-TestParamSet" */
+845,	/* "id-GostR3410-94-a" */
+846,	/* "id-GostR3410-94-aBis" */
+847,	/* "id-GostR3410-94-b" */
+848,	/* "id-GostR3410-94-bBis" */
+822,	/* "id-GostR3411-94-CryptoProParamSet" */
+821,	/* "id-GostR3411-94-TestParamSet" */
+266,	/* "id-aca" */
+355,	/* "id-aca-accessIdentity" */
+354,	/* "id-aca-authenticationInfo" */
+356,	/* "id-aca-chargingIdentity" */
+399,	/* "id-aca-encAttrs" */
+357,	/* "id-aca-group" */
+358,	/* "id-aca-role" */
+176,	/* "id-ad" */
+788,	/* "id-aes128-wrap" */
+789,	/* "id-aes192-wrap" */
+790,	/* "id-aes256-wrap" */
+262,	/* "id-alg" */
+323,	/* "id-alg-des40" */
+326,	/* "id-alg-dh-pop" */
+325,	/* "id-alg-dh-sig-hmac-sha1" */
+324,	/* "id-alg-noSignature" */
+268,	/* "id-cct" */
+361,	/* "id-cct-PKIData" */
+362,	/* "id-cct-PKIResponse" */
+360,	/* "id-cct-crs" */
+81,	/* "id-ce" */
+680,	/* "id-characteristic-two-basis" */
+263,	/* "id-cmc" */
+334,	/* "id-cmc-addExtensions" */
+346,	/* "id-cmc-confirmCertAcceptance" */
+330,	/* "id-cmc-dataReturn" */
+336,	/* "id-cmc-decryptedPOP" */
+335,	/* "id-cmc-encryptedPOP" */
+339,	/* "id-cmc-getCRL" */
+338,	/* "id-cmc-getCert" */
+328,	/* "id-cmc-identification" */
+329,	/* "id-cmc-identityProof" */
+337,	/* "id-cmc-lraPOPWitness" */
+344,	/* "id-cmc-popLinkRandom" */
+345,	/* "id-cmc-popLinkWitness" */
+343,	/* "id-cmc-queryPending" */
+333,	/* "id-cmc-recipientNonce" */
+341,	/* "id-cmc-regInfo" */
+342,	/* "id-cmc-responseInfo" */
+340,	/* "id-cmc-revokeRequest" */
+332,	/* "id-cmc-senderNonce" */
+327,	/* "id-cmc-statusInfo" */
+331,	/* "id-cmc-transactionId" */
+787,	/* "id-ct-asciiTextWithCRLF" */
+408,	/* "id-ecPublicKey" */
+508,	/* "id-hex-multipart-message" */
+507,	/* "id-hex-partial-message" */
+260,	/* "id-it" */
+302,	/* "id-it-caKeyUpdateInfo" */
+298,	/* "id-it-caProtEncCert" */
+311,	/* "id-it-confirmWaitTime" */
+303,	/* "id-it-currentCRL" */
+300,	/* "id-it-encKeyPairTypes" */
+310,	/* "id-it-implicitConfirm" */
+308,	/* "id-it-keyPairParamRep" */
+307,	/* "id-it-keyPairParamReq" */
+312,	/* "id-it-origPKIMessage" */
+301,	/* "id-it-preferredSymmAlg" */
+309,	/* "id-it-revPassphrase" */
+299,	/* "id-it-signKeyPairTypes" */
+305,	/* "id-it-subscriptionRequest" */
+306,	/* "id-it-subscriptionResponse" */
+784,	/* "id-it-suppLangTags" */
+304,	/* "id-it-unsupportedOIDs" */
+128,	/* "id-kp" */
+280,	/* "id-mod-attribute-cert" */
+274,	/* "id-mod-cmc" */
+277,	/* "id-mod-cmp" */
+284,	/* "id-mod-cmp2000" */
+273,	/* "id-mod-crmf" */
+283,	/* "id-mod-dvcs" */
+275,	/* "id-mod-kea-profile-88" */
+276,	/* "id-mod-kea-profile-93" */
+282,	/* "id-mod-ocsp" */
+278,	/* "id-mod-qualified-cert-88" */
+279,	/* "id-mod-qualified-cert-93" */
+281,	/* "id-mod-timestamp-protocol" */
+264,	/* "id-on" */
+347,	/* "id-on-personalData" */
+265,	/* "id-pda" */
+352,	/* "id-pda-countryOfCitizenship" */
+353,	/* "id-pda-countryOfResidence" */
+348,	/* "id-pda-dateOfBirth" */
+351,	/* "id-pda-gender" */
+349,	/* "id-pda-placeOfBirth" */
+175,	/* "id-pe" */
+261,	/* "id-pkip" */
+258,	/* "id-pkix-mod" */
+269,	/* "id-pkix1-explicit-88" */
+271,	/* "id-pkix1-explicit-93" */
+270,	/* "id-pkix1-implicit-88" */
+272,	/* "id-pkix1-implicit-93" */
+662,	/* "id-ppl" */
+267,	/* "id-qcs" */
+359,	/* "id-qcs-pkixQCSyntax-v1" */
+259,	/* "id-qt" */
+313,	/* "id-regCtrl" */
+316,	/* "id-regCtrl-authenticator" */
+319,	/* "id-regCtrl-oldCertID" */
+318,	/* "id-regCtrl-pkiArchiveOptions" */
+317,	/* "id-regCtrl-pkiPublicationInfo" */
+320,	/* "id-regCtrl-protocolEncrKey" */
+315,	/* "id-regCtrl-regToken" */
+314,	/* "id-regInfo" */
+322,	/* "id-regInfo-certReq" */
+321,	/* "id-regInfo-utf8Pairs" */
+191,	/* "id-smime-aa" */
+215,	/* "id-smime-aa-contentHint" */
+218,	/* "id-smime-aa-contentIdentifier" */
+221,	/* "id-smime-aa-contentReference" */
+240,	/* "id-smime-aa-dvcs-dvc" */
+217,	/* "id-smime-aa-encapContentType" */
+222,	/* "id-smime-aa-encrypKeyPref" */
+220,	/* "id-smime-aa-equivalentLabels" */
+232,	/* "id-smime-aa-ets-CertificateRefs" */
+233,	/* "id-smime-aa-ets-RevocationRefs" */
+238,	/* "id-smime-aa-ets-archiveTimeStamp" */
+237,	/* "id-smime-aa-ets-certCRLTimestamp" */
+234,	/* "id-smime-aa-ets-certValues" */
+227,	/* "id-smime-aa-ets-commitmentType" */
+231,	/* "id-smime-aa-ets-contentTimestamp" */
+236,	/* "id-smime-aa-ets-escTimeStamp" */
+230,	/* "id-smime-aa-ets-otherSigCert" */
+235,	/* "id-smime-aa-ets-revocationValues" */
+226,	/* "id-smime-aa-ets-sigPolicyId" */
+229,	/* "id-smime-aa-ets-signerAttr" */
+228,	/* "id-smime-aa-ets-signerLocation" */
+219,	/* "id-smime-aa-macValue" */
+214,	/* "id-smime-aa-mlExpandHistory" */
+216,	/* "id-smime-aa-msgSigDigest" */
+212,	/* "id-smime-aa-receiptRequest" */
+213,	/* "id-smime-aa-securityLabel" */
+239,	/* "id-smime-aa-signatureType" */
+223,	/* "id-smime-aa-signingCertificate" */
+224,	/* "id-smime-aa-smimeEncryptCerts" */
+225,	/* "id-smime-aa-timeStampToken" */
+192,	/* "id-smime-alg" */
+243,	/* "id-smime-alg-3DESwrap" */
+246,	/* "id-smime-alg-CMS3DESwrap" */
+247,	/* "id-smime-alg-CMSRC2wrap" */
+245,	/* "id-smime-alg-ESDH" */
+241,	/* "id-smime-alg-ESDHwith3DES" */
+242,	/* "id-smime-alg-ESDHwithRC2" */
+244,	/* "id-smime-alg-RC2wrap" */
+193,	/* "id-smime-cd" */
+248,	/* "id-smime-cd-ldap" */
+190,	/* "id-smime-ct" */
+210,	/* "id-smime-ct-DVCSRequestData" */
+211,	/* "id-smime-ct-DVCSResponseData" */
+208,	/* "id-smime-ct-TDTInfo" */
+207,	/* "id-smime-ct-TSTInfo" */
+205,	/* "id-smime-ct-authData" */
+786,	/* "id-smime-ct-compressedData" */
+209,	/* "id-smime-ct-contentInfo" */
+206,	/* "id-smime-ct-publishCert" */
+204,	/* "id-smime-ct-receipt" */
+195,	/* "id-smime-cti" */
+255,	/* "id-smime-cti-ets-proofOfApproval" */
+256,	/* "id-smime-cti-ets-proofOfCreation" */
+253,	/* "id-smime-cti-ets-proofOfDelivery" */
+251,	/* "id-smime-cti-ets-proofOfOrigin" */
+252,	/* "id-smime-cti-ets-proofOfReceipt" */
+254,	/* "id-smime-cti-ets-proofOfSender" */
+189,	/* "id-smime-mod" */
+196,	/* "id-smime-mod-cms" */
+197,	/* "id-smime-mod-ess" */
+202,	/* "id-smime-mod-ets-eSigPolicy-88" */
+203,	/* "id-smime-mod-ets-eSigPolicy-97" */
+200,	/* "id-smime-mod-ets-eSignature-88" */
+201,	/* "id-smime-mod-ets-eSignature-97" */
+199,	/* "id-smime-mod-msg-v3" */
+198,	/* "id-smime-mod-oid" */
+194,	/* "id-smime-spq" */
+250,	/* "id-smime-spq-ets-sqt-unotice" */
+249,	/* "id-smime-spq-ets-sqt-uri" */
+34,	/* "idea-cbc" */
+35,	/* "idea-cfb" */
+36,	/* "idea-ecb" */
+46,	/* "idea-ofb" */
+676,	/* "identified-organization" */
+461,	/* "info" */
+101,	/* "initials" */
+869,	/* "internationaliSDNNumber" */
+749,	/* "ipsec3" */
+750,	/* "ipsec4" */
+181,	/* "iso" */
+623,	/* "issuer capabilities" */
+645,	/* "itu-t" */
+492,	/* "janetMailbox" */
+646,	/* "joint-iso-itu-t" */
+150,	/* "keyBag" */
+773,	/* "kisa" */
+477,	/* "lastModifiedBy" */
+476,	/* "lastModifiedTime" */
+157,	/* "localKeyID" */
+15,	/* "localityName" */
+480,	/* "mXRecord" */
+493,	/* "mailPreferenceOption" */
+467,	/* "manager" */
+ 3,	/* "md2" */
+ 7,	/* "md2WithRSAEncryption" */
+257,	/* "md4" */
+396,	/* "md4WithRSAEncryption" */
+ 4,	/* "md5" */
+114,	/* "md5-sha1" */
+104,	/* "md5WithRSA" */
+ 8,	/* "md5WithRSAEncryption" */
+95,	/* "mdc2" */
+96,	/* "mdc2WithRSA" */
+875,	/* "member" */
+602,	/* "merchant initiated auth" */
+514,	/* "message extensions" */
+51,	/* "messageDigest" */
+506,	/* "mime-mhs-bodies" */
+505,	/* "mime-mhs-headings" */
+488,	/* "mobileTelephoneNumber" */
+481,	/* "nSRecord" */
+173,	/* "name" */
+681,	/* "onBasis" */
+379,	/* "org" */
+17,	/* "organizationName" */
+491,	/* "organizationalStatus" */
+18,	/* "organizationalUnitName" */
+475,	/* "otherMailbox" */
+876,	/* "owner" */
+489,	/* "pagerTelephoneNumber" */
+782,	/* "password based MAC" */
+374,	/* "path" */
+621,	/* "payment gateway capabilities" */
+ 9,	/* "pbeWithMD2AndDES-CBC" */
+168,	/* "pbeWithMD2AndRC2-CBC" */
+112,	/* "pbeWithMD5AndCast5CBC" */
+10,	/* "pbeWithMD5AndDES-CBC" */
+169,	/* "pbeWithMD5AndRC2-CBC" */
+148,	/* "pbeWithSHA1And128BitRC2-CBC" */
+144,	/* "pbeWithSHA1And128BitRC4" */
+147,	/* "pbeWithSHA1And2-KeyTripleDES-CBC" */
+146,	/* "pbeWithSHA1And3-KeyTripleDES-CBC" */
+149,	/* "pbeWithSHA1And40BitRC2-CBC" */
+145,	/* "pbeWithSHA1And40BitRC4" */
+170,	/* "pbeWithSHA1AndDES-CBC" */
+68,	/* "pbeWithSHA1AndRC2-CBC" */
+499,	/* "personalSignature" */
+487,	/* "personalTitle" */
+464,	/* "photo" */
+863,	/* "physicalDeliveryOfficeName" */
+437,	/* "pilot" */
+439,	/* "pilotAttributeSyntax" */
+438,	/* "pilotAttributeType" */
+479,	/* "pilotAttributeType27" */
+456,	/* "pilotDSA" */
+441,	/* "pilotGroups" */
+444,	/* "pilotObject" */
+440,	/* "pilotObjectClass" */
+455,	/* "pilotOrganization" */
+445,	/* "pilotPerson" */
+186,	/* "pkcs1" */
+27,	/* "pkcs3" */
+187,	/* "pkcs5" */
+20,	/* "pkcs7" */
+21,	/* "pkcs7-data" */
+25,	/* "pkcs7-digestData" */
+26,	/* "pkcs7-encryptedData" */
+23,	/* "pkcs7-envelopedData" */
+24,	/* "pkcs7-signedAndEnvelopedData" */
+22,	/* "pkcs7-signedData" */
+151,	/* "pkcs8ShroudedKeyBag" */
+47,	/* "pkcs9" */
+862,	/* "postOfficeBox" */
+861,	/* "postalAddress" */
+661,	/* "postalCode" */
+683,	/* "ppBasis" */
+872,	/* "preferredDeliveryMethod" */
+873,	/* "presentationAddress" */
+406,	/* "prime-field" */
+409,	/* "prime192v1" */
+410,	/* "prime192v2" */
+411,	/* "prime192v3" */
+412,	/* "prime239v1" */
+413,	/* "prime239v2" */
+414,	/* "prime239v3" */
+415,	/* "prime256v1" */
+886,	/* "protocolInformation" */
+510,	/* "pseudonym" */
+435,	/* "pss" */
+286,	/* "qcStatements" */
+457,	/* "qualityLabelledData" */
+450,	/* "rFC822localPart" */
+98,	/* "rc2-40-cbc" */
+166,	/* "rc2-64-cbc" */
+37,	/* "rc2-cbc" */
+39,	/* "rc2-cfb" */
+38,	/* "rc2-ecb" */
+40,	/* "rc2-ofb" */
+ 5,	/* "rc4" */
+97,	/* "rc4-40" */
+120,	/* "rc5-cbc" */
+122,	/* "rc5-cfb" */
+121,	/* "rc5-ecb" */
+123,	/* "rc5-ofb" */
+870,	/* "registeredAddress" */
+460,	/* "rfc822Mailbox" */
+117,	/* "ripemd160" */
+119,	/* "ripemd160WithRSA" */
+400,	/* "role" */
+877,	/* "roleOccupant" */
+448,	/* "room" */
+463,	/* "roomNumber" */
+19,	/* "rsa" */
+ 6,	/* "rsaEncryption" */
+644,	/* "rsaOAEPEncryptionSET" */
+377,	/* "rsaSignature" */
+124,	/* "run length compression" */
+482,	/* "sOARecord" */
+155,	/* "safeContentsBag" */
+291,	/* "sbgp-autonomousSysNum" */
+290,	/* "sbgp-ipAddrBlock" */
+292,	/* "sbgp-routerIdentifier" */
+159,	/* "sdsiCertificate" */
+859,	/* "searchGuide" */
+704,	/* "secp112r1" */
+705,	/* "secp112r2" */
+706,	/* "secp128r1" */
+707,	/* "secp128r2" */
+708,	/* "secp160k1" */
+709,	/* "secp160r1" */
+710,	/* "secp160r2" */
+711,	/* "secp192k1" */
+712,	/* "secp224k1" */
+713,	/* "secp224r1" */
+714,	/* "secp256k1" */
+715,	/* "secp384r1" */
+716,	/* "secp521r1" */
+154,	/* "secretBag" */
+474,	/* "secretary" */
+717,	/* "sect113r1" */
+718,	/* "sect113r2" */
+719,	/* "sect131r1" */
+720,	/* "sect131r2" */
+721,	/* "sect163k1" */
+722,	/* "sect163r1" */
+723,	/* "sect163r2" */
+724,	/* "sect193r1" */
+725,	/* "sect193r2" */
+726,	/* "sect233k1" */
+727,	/* "sect233r1" */
+728,	/* "sect239k1" */
+729,	/* "sect283k1" */
+730,	/* "sect283r1" */
+731,	/* "sect409k1" */
+732,	/* "sect409r1" */
+733,	/* "sect571k1" */
+734,	/* "sect571r1" */
+635,	/* "secure device signature" */
+878,	/* "seeAlso" */
+777,	/* "seed-cbc" */
+779,	/* "seed-cfb" */
+776,	/* "seed-ecb" */
+778,	/* "seed-ofb" */
+105,	/* "serialNumber" */
+625,	/* "set-addPolicy" */
+515,	/* "set-attr" */
+518,	/* "set-brand" */
+638,	/* "set-brand-AmericanExpress" */
+637,	/* "set-brand-Diners" */
+636,	/* "set-brand-IATA-ATA" */
+639,	/* "set-brand-JCB" */
+641,	/* "set-brand-MasterCard" */
+642,	/* "set-brand-Novus" */
+640,	/* "set-brand-Visa" */
+516,	/* "set-policy" */
+607,	/* "set-policy-root" */
+624,	/* "set-rootKeyThumb" */
+620,	/* "setAttr-Cert" */
+628,	/* "setAttr-IssCap-CVM" */
+630,	/* "setAttr-IssCap-Sig" */
+629,	/* "setAttr-IssCap-T2" */
+627,	/* "setAttr-Token-B0Prime" */
+626,	/* "setAttr-Token-EMV" */
+622,	/* "setAttr-TokenType" */
+619,	/* "setCext-IssuerCapabilities" */
+615,	/* "setCext-PGWYcapabilities" */
+616,	/* "setCext-TokenIdentifier" */
+618,	/* "setCext-TokenType" */
+617,	/* "setCext-Track2Data" */
+611,	/* "setCext-cCertRequired" */
+609,	/* "setCext-certType" */
+608,	/* "setCext-hashedRoot" */
+610,	/* "setCext-merchData" */
+613,	/* "setCext-setExt" */
+614,	/* "setCext-setQualf" */
+612,	/* "setCext-tunneling" */
+540,	/* "setct-AcqCardCodeMsg" */
+576,	/* "setct-AcqCardCodeMsgTBE" */
+570,	/* "setct-AuthReqTBE" */
+534,	/* "setct-AuthReqTBS" */
+527,	/* "setct-AuthResBaggage" */
+571,	/* "setct-AuthResTBE" */
+572,	/* "setct-AuthResTBEX" */
+535,	/* "setct-AuthResTBS" */
+536,	/* "setct-AuthResTBSX" */
+528,	/* "setct-AuthRevReqBaggage" */
+577,	/* "setct-AuthRevReqTBE" */
+541,	/* "setct-AuthRevReqTBS" */
+529,	/* "setct-AuthRevResBaggage" */
+542,	/* "setct-AuthRevResData" */
+578,	/* "setct-AuthRevResTBE" */
+579,	/* "setct-AuthRevResTBEB" */
+543,	/* "setct-AuthRevResTBS" */
+573,	/* "setct-AuthTokenTBE" */
+537,	/* "setct-AuthTokenTBS" */
+600,	/* "setct-BCIDistributionTBS" */
+558,	/* "setct-BatchAdminReqData" */
+592,	/* "setct-BatchAdminReqTBE" */
+559,	/* "setct-BatchAdminResData" */
+593,	/* "setct-BatchAdminResTBE" */
+599,	/* "setct-CRLNotificationResTBS" */
+598,	/* "setct-CRLNotificationTBS" */
+580,	/* "setct-CapReqTBE" */
+581,	/* "setct-CapReqTBEX" */
+544,	/* "setct-CapReqTBS" */
+545,	/* "setct-CapReqTBSX" */
+546,	/* "setct-CapResData" */
+582,	/* "setct-CapResTBE" */
+583,	/* "setct-CapRevReqTBE" */
+584,	/* "setct-CapRevReqTBEX" */
+547,	/* "setct-CapRevReqTBS" */
+548,	/* "setct-CapRevReqTBSX" */
+549,	/* "setct-CapRevResData" */
+585,	/* "setct-CapRevResTBE" */
+538,	/* "setct-CapTokenData" */
+530,	/* "setct-CapTokenSeq" */
+574,	/* "setct-CapTokenTBE" */
+575,	/* "setct-CapTokenTBEX" */
+539,	/* "setct-CapTokenTBS" */
+560,	/* "setct-CardCInitResTBS" */
+566,	/* "setct-CertInqReqTBS" */
+563,	/* "setct-CertReqData" */
+595,	/* "setct-CertReqTBE" */
+596,	/* "setct-CertReqTBEX" */
+564,	/* "setct-CertReqTBS" */
+565,	/* "setct-CertResData" */
+597,	/* "setct-CertResTBE" */
+586,	/* "setct-CredReqTBE" */
+587,	/* "setct-CredReqTBEX" */
+550,	/* "setct-CredReqTBS" */
+551,	/* "setct-CredReqTBSX" */
+552,	/* "setct-CredResData" */
+588,	/* "setct-CredResTBE" */
+589,	/* "setct-CredRevReqTBE" */
+590,	/* "setct-CredRevReqTBEX" */
+553,	/* "setct-CredRevReqTBS" */
+554,	/* "setct-CredRevReqTBSX" */
+555,	/* "setct-CredRevResData" */
+591,	/* "setct-CredRevResTBE" */
+567,	/* "setct-ErrorTBS" */
+526,	/* "setct-HODInput" */
+561,	/* "setct-MeAqCInitResTBS" */
+522,	/* "setct-OIData" */
+519,	/* "setct-PANData" */
+521,	/* "setct-PANOnly" */
+520,	/* "setct-PANToken" */
+556,	/* "setct-PCertReqData" */
+557,	/* "setct-PCertResTBS" */
+523,	/* "setct-PI" */
+532,	/* "setct-PI-TBS" */
+524,	/* "setct-PIData" */
+525,	/* "setct-PIDataUnsigned" */
+568,	/* "setct-PIDualSignedTBE" */
+569,	/* "setct-PIUnsignedTBE" */
+531,	/* "setct-PInitResData" */
+533,	/* "setct-PResData" */
+594,	/* "setct-RegFormReqTBE" */
+562,	/* "setct-RegFormResTBS" */
+604,	/* "setext-pinAny" */
+603,	/* "setext-pinSecure" */
+605,	/* "setext-track2" */
+41,	/* "sha" */
+64,	/* "sha1" */
+115,	/* "sha1WithRSA" */
+65,	/* "sha1WithRSAEncryption" */
+675,	/* "sha224" */
+671,	/* "sha224WithRSAEncryption" */
+672,	/* "sha256" */
+668,	/* "sha256WithRSAEncryption" */
+673,	/* "sha384" */
+669,	/* "sha384WithRSAEncryption" */
+674,	/* "sha512" */
+670,	/* "sha512WithRSAEncryption" */
+42,	/* "shaWithRSAEncryption" */
+52,	/* "signingTime" */
+454,	/* "simpleSecurityObject" */
+496,	/* "singleLevelQuality" */
+16,	/* "stateOrProvinceName" */
+660,	/* "streetAddress" */
+498,	/* "subtreeMaximumQuality" */
+497,	/* "subtreeMinimumQuality" */
+890,	/* "supportedAlgorithms" */
+874,	/* "supportedApplicationContext" */
+100,	/* "surname" */
+864,	/* "telephoneNumber" */
+866,	/* "teletexTerminalIdentifier" */
+865,	/* "telexNumber" */
+459,	/* "textEncodedORAddress" */
+293,	/* "textNotice" */
+106,	/* "title" */
+682,	/* "tpBasis" */
+436,	/* "ucl" */
+ 0,	/* "undefined" */
+888,	/* "uniqueMember" */
+55,	/* "unstructuredAddress" */
+49,	/* "unstructuredName" */
+880,	/* "userCertificate" */
+465,	/* "userClass" */
+458,	/* "userId" */
+879,	/* "userPassword" */
+373,	/* "valid" */
+678,	/* "wap" */
+679,	/* "wap-wsg" */
+735,	/* "wap-wsg-idm-ecid-wtls1" */
+743,	/* "wap-wsg-idm-ecid-wtls10" */
+744,	/* "wap-wsg-idm-ecid-wtls11" */
+745,	/* "wap-wsg-idm-ecid-wtls12" */
+736,	/* "wap-wsg-idm-ecid-wtls3" */
+737,	/* "wap-wsg-idm-ecid-wtls4" */
+738,	/* "wap-wsg-idm-ecid-wtls5" */
+739,	/* "wap-wsg-idm-ecid-wtls6" */
+740,	/* "wap-wsg-idm-ecid-wtls7" */
+741,	/* "wap-wsg-idm-ecid-wtls8" */
+742,	/* "wap-wsg-idm-ecid-wtls9" */
+804,	/* "whirlpool" */
+868,	/* "x121Address" */
+503,	/* "x500UniqueIdentifier" */
+158,	/* "x509Certificate" */
+160,	/* "x509Crl" */
+125,	/* "zlib compression" */
+};
+
+static const unsigned int obj_objs[NUM_OBJ]={
+ 0,	/* OBJ_undef                        0 */
+393,	/* OBJ_joint_iso_ccitt              OBJ_joint_iso_itu_t */
+404,	/* OBJ_ccitt                        OBJ_itu_t */
+645,	/* OBJ_itu_t                        0 */
+434,	/* OBJ_data                         0 9 */
+181,	/* OBJ_iso                          1 */
+182,	/* OBJ_member_body                  1 2 */
+379,	/* OBJ_org                          1 3 */
+676,	/* OBJ_identified_organization      1 3 */
+646,	/* OBJ_joint_iso_itu_t              2 */
+11,	/* OBJ_X500                         2 5 */
+647,	/* OBJ_international_organizations  2 23 */
+380,	/* OBJ_dod                          1 3 6 */
+12,	/* OBJ_X509                         2 5 4 */
+378,	/* OBJ_X500algorithms               2 5 8 */
+81,	/* OBJ_id_ce                        2 5 29 */
+512,	/* OBJ_id_set                       2 23 42 */
+678,	/* OBJ_wap                          2 23 43 */
+435,	/* OBJ_pss                          0 9 2342 */
+183,	/* OBJ_ISO_US                       1 2 840 */
+381,	/* OBJ_iana                         1 3 6 1 */
+677,	/* OBJ_certicom_arc                 1 3 132 */
+394,	/* OBJ_selected_attribute_types     2 5 1 5 */
+13,	/* OBJ_commonName                   2 5 4 3 */
+100,	/* OBJ_surname                      2 5 4 4 */
+105,	/* OBJ_serialNumber                 2 5 4 5 */
+14,	/* OBJ_countryName                  2 5 4 6 */
+15,	/* OBJ_localityName                 2 5 4 7 */
+16,	/* OBJ_stateOrProvinceName          2 5 4 8 */
+660,	/* OBJ_streetAddress                2 5 4 9 */
+17,	/* OBJ_organizationName             2 5 4 10 */
+18,	/* OBJ_organizationalUnitName       2 5 4 11 */
+106,	/* OBJ_title                        2 5 4 12 */
+107,	/* OBJ_description                  2 5 4 13 */
+859,	/* OBJ_searchGuide                  2 5 4 14 */
+860,	/* OBJ_businessCategory             2 5 4 15 */
+861,	/* OBJ_postalAddress                2 5 4 16 */
+661,	/* OBJ_postalCode                   2 5 4 17 */
+862,	/* OBJ_postOfficeBox                2 5 4 18 */
+863,	/* OBJ_physicalDeliveryOfficeName   2 5 4 19 */
+864,	/* OBJ_telephoneNumber              2 5 4 20 */
+865,	/* OBJ_telexNumber                  2 5 4 21 */
+866,	/* OBJ_teletexTerminalIdentifier    2 5 4 22 */
+867,	/* OBJ_facsimileTelephoneNumber     2 5 4 23 */
+868,	/* OBJ_x121Address                  2 5 4 24 */
+869,	/* OBJ_internationaliSDNNumber      2 5 4 25 */
+870,	/* OBJ_registeredAddress            2 5 4 26 */
+871,	/* OBJ_destinationIndicator         2 5 4 27 */
+872,	/* OBJ_preferredDeliveryMethod      2 5 4 28 */
+873,	/* OBJ_presentationAddress          2 5 4 29 */
+874,	/* OBJ_supportedApplicationContext  2 5 4 30 */
+875,	/* OBJ_member                       2 5 4 31 */
+876,	/* OBJ_owner                        2 5 4 32 */
+877,	/* OBJ_roleOccupant                 2 5 4 33 */
+878,	/* OBJ_seeAlso                      2 5 4 34 */
+879,	/* OBJ_userPassword                 2 5 4 35 */
+880,	/* OBJ_userCertificate              2 5 4 36 */
+881,	/* OBJ_cACertificate                2 5 4 37 */
+882,	/* OBJ_authorityRevocationList      2 5 4 38 */
+883,	/* OBJ_certificateRevocationList    2 5 4 39 */
+884,	/* OBJ_crossCertificatePair         2 5 4 40 */
+173,	/* OBJ_name                         2 5 4 41 */
+99,	/* OBJ_givenName                    2 5 4 42 */
+101,	/* OBJ_initials                     2 5 4 43 */
+509,	/* OBJ_generationQualifier          2 5 4 44 */
+503,	/* OBJ_x500UniqueIdentifier         2 5 4 45 */
+174,	/* OBJ_dnQualifier                  2 5 4 46 */
+885,	/* OBJ_enhancedSearchGuide          2 5 4 47 */
+886,	/* OBJ_protocolInformation          2 5 4 48 */
+887,	/* OBJ_distinguishedName            2 5 4 49 */
+888,	/* OBJ_uniqueMember                 2 5 4 50 */
+889,	/* OBJ_houseIdentifier              2 5 4 51 */
+890,	/* OBJ_supportedAlgorithms          2 5 4 52 */
+891,	/* OBJ_deltaRevocationList          2 5 4 53 */
+892,	/* OBJ_dmdName                      2 5 4 54 */
+510,	/* OBJ_pseudonym                    2 5 4 65 */
+400,	/* OBJ_role                         2 5 4 72 */
+769,	/* OBJ_subject_directory_attributes 2 5 29 9 */
+82,	/* OBJ_subject_key_identifier       2 5 29 14 */
+83,	/* OBJ_key_usage                    2 5 29 15 */
+84,	/* OBJ_private_key_usage_period     2 5 29 16 */
+85,	/* OBJ_subject_alt_name             2 5 29 17 */
+86,	/* OBJ_issuer_alt_name              2 5 29 18 */
+87,	/* OBJ_basic_constraints            2 5 29 19 */
+88,	/* OBJ_crl_number                   2 5 29 20 */
+141,	/* OBJ_crl_reason                   2 5 29 21 */
+430,	/* OBJ_hold_instruction_code        2 5 29 23 */
+142,	/* OBJ_invalidity_date              2 5 29 24 */
+140,	/* OBJ_delta_crl                    2 5 29 27 */
+770,	/* OBJ_issuing_distribution_point   2 5 29 28 */
+771,	/* OBJ_certificate_issuer           2 5 29 29 */
+666,	/* OBJ_name_constraints             2 5 29 30 */
+103,	/* OBJ_crl_distribution_points      2 5 29 31 */
+89,	/* OBJ_certificate_policies         2 5 29 32 */
+747,	/* OBJ_policy_mappings              2 5 29 33 */
+90,	/* OBJ_authority_key_identifier     2 5 29 35 */
+401,	/* OBJ_policy_constraints           2 5 29 36 */
+126,	/* OBJ_ext_key_usage                2 5 29 37 */
+857,	/* OBJ_freshest_crl                 2 5 29 46 */
+748,	/* OBJ_inhibit_any_policy           2 5 29 54 */
+402,	/* OBJ_target_information           2 5 29 55 */
+403,	/* OBJ_no_rev_avail                 2 5 29 56 */
+513,	/* OBJ_set_ctype                    2 23 42 0 */
+514,	/* OBJ_set_msgExt                   2 23 42 1 */
+515,	/* OBJ_set_attr                     2 23 42 3 */
+516,	/* OBJ_set_policy                   2 23 42 5 */
+517,	/* OBJ_set_certExt                  2 23 42 7 */
+518,	/* OBJ_set_brand                    2 23 42 8 */
+679,	/* OBJ_wap_wsg                      2 23 43 1 */
+382,	/* OBJ_Directory                    1 3 6 1 1 */
+383,	/* OBJ_Management                   1 3 6 1 2 */
+384,	/* OBJ_Experimental                 1 3 6 1 3 */
+385,	/* OBJ_Private                      1 3 6 1 4 */
+386,	/* OBJ_Security                     1 3 6 1 5 */
+387,	/* OBJ_SNMPv2                       1 3 6 1 6 */
+388,	/* OBJ_Mail                         1 3 6 1 7 */
+376,	/* OBJ_algorithm                    1 3 14 3 2 */
+395,	/* OBJ_clearance                    2 5 1 5 55 */
+19,	/* OBJ_rsa                          2 5 8 1 1 */
+96,	/* OBJ_mdc2WithRSA                  2 5 8 3 100 */
+95,	/* OBJ_mdc2                         2 5 8 3 101 */
+746,	/* OBJ_any_policy                   2 5 29 32 0 */
+519,	/* OBJ_setct_PANData                2 23 42 0 0 */
+520,	/* OBJ_setct_PANToken               2 23 42 0 1 */
+521,	/* OBJ_setct_PANOnly                2 23 42 0 2 */
+522,	/* OBJ_setct_OIData                 2 23 42 0 3 */
+523,	/* OBJ_setct_PI                     2 23 42 0 4 */
+524,	/* OBJ_setct_PIData                 2 23 42 0 5 */
+525,	/* OBJ_setct_PIDataUnsigned         2 23 42 0 6 */
+526,	/* OBJ_setct_HODInput               2 23 42 0 7 */
+527,	/* OBJ_setct_AuthResBaggage         2 23 42 0 8 */
+528,	/* OBJ_setct_AuthRevReqBaggage      2 23 42 0 9 */
+529,	/* OBJ_setct_AuthRevResBaggage      2 23 42 0 10 */
+530,	/* OBJ_setct_CapTokenSeq            2 23 42 0 11 */
+531,	/* OBJ_setct_PInitResData           2 23 42 0 12 */
+532,	/* OBJ_setct_PI_TBS                 2 23 42 0 13 */
+533,	/* OBJ_setct_PResData               2 23 42 0 14 */
+534,	/* OBJ_setct_AuthReqTBS             2 23 42 0 16 */
+535,	/* OBJ_setct_AuthResTBS             2 23 42 0 17 */
+536,	/* OBJ_setct_AuthResTBSX            2 23 42 0 18 */
+537,	/* OBJ_setct_AuthTokenTBS           2 23 42 0 19 */
+538,	/* OBJ_setct_CapTokenData           2 23 42 0 20 */
+539,	/* OBJ_setct_CapTokenTBS            2 23 42 0 21 */
+540,	/* OBJ_setct_AcqCardCodeMsg         2 23 42 0 22 */
+541,	/* OBJ_setct_AuthRevReqTBS          2 23 42 0 23 */
+542,	/* OBJ_setct_AuthRevResData         2 23 42 0 24 */
+543,	/* OBJ_setct_AuthRevResTBS          2 23 42 0 25 */
+544,	/* OBJ_setct_CapReqTBS              2 23 42 0 26 */
+545,	/* OBJ_setct_CapReqTBSX             2 23 42 0 27 */
+546,	/* OBJ_setct_CapResData             2 23 42 0 28 */
+547,	/* OBJ_setct_CapRevReqTBS           2 23 42 0 29 */
+548,	/* OBJ_setct_CapRevReqTBSX          2 23 42 0 30 */
+549,	/* OBJ_setct_CapRevResData          2 23 42 0 31 */
+550,	/* OBJ_setct_CredReqTBS             2 23 42 0 32 */
+551,	/* OBJ_setct_CredReqTBSX            2 23 42 0 33 */
+552,	/* OBJ_setct_CredResData            2 23 42 0 34 */
+553,	/* OBJ_setct_CredRevReqTBS          2 23 42 0 35 */
+554,	/* OBJ_setct_CredRevReqTBSX         2 23 42 0 36 */
+555,	/* OBJ_setct_CredRevResData         2 23 42 0 37 */
+556,	/* OBJ_setct_PCertReqData           2 23 42 0 38 */
+557,	/* OBJ_setct_PCertResTBS            2 23 42 0 39 */
+558,	/* OBJ_setct_BatchAdminReqData      2 23 42 0 40 */
+559,	/* OBJ_setct_BatchAdminResData      2 23 42 0 41 */
+560,	/* OBJ_setct_CardCInitResTBS        2 23 42 0 42 */
+561,	/* OBJ_setct_MeAqCInitResTBS        2 23 42 0 43 */
+562,	/* OBJ_setct_RegFormResTBS          2 23 42 0 44 */
+563,	/* OBJ_setct_CertReqData            2 23 42 0 45 */
+564,	/* OBJ_setct_CertReqTBS             2 23 42 0 46 */
+565,	/* OBJ_setct_CertResData            2 23 42 0 47 */
+566,	/* OBJ_setct_CertInqReqTBS          2 23 42 0 48 */
+567,	/* OBJ_setct_ErrorTBS               2 23 42 0 49 */
+568,	/* OBJ_setct_PIDualSignedTBE        2 23 42 0 50 */
+569,	/* OBJ_setct_PIUnsignedTBE          2 23 42 0 51 */
+570,	/* OBJ_setct_AuthReqTBE             2 23 42 0 52 */
+571,	/* OBJ_setct_AuthResTBE             2 23 42 0 53 */
+572,	/* OBJ_setct_AuthResTBEX            2 23 42 0 54 */
+573,	/* OBJ_setct_AuthTokenTBE           2 23 42 0 55 */
+574,	/* OBJ_setct_CapTokenTBE            2 23 42 0 56 */
+575,	/* OBJ_setct_CapTokenTBEX           2 23 42 0 57 */
+576,	/* OBJ_setct_AcqCardCodeMsgTBE      2 23 42 0 58 */
+577,	/* OBJ_setct_AuthRevReqTBE          2 23 42 0 59 */
+578,	/* OBJ_setct_AuthRevResTBE          2 23 42 0 60 */
+579,	/* OBJ_setct_AuthRevResTBEB         2 23 42 0 61 */
+580,	/* OBJ_setct_CapReqTBE              2 23 42 0 62 */
+581,	/* OBJ_setct_CapReqTBEX             2 23 42 0 63 */
+582,	/* OBJ_setct_CapResTBE              2 23 42 0 64 */
+583,	/* OBJ_setct_CapRevReqTBE           2 23 42 0 65 */
+584,	/* OBJ_setct_CapRevReqTBEX          2 23 42 0 66 */
+585,	/* OBJ_setct_CapRevResTBE           2 23 42 0 67 */
+586,	/* OBJ_setct_CredReqTBE             2 23 42 0 68 */
+587,	/* OBJ_setct_CredReqTBEX            2 23 42 0 69 */
+588,	/* OBJ_setct_CredResTBE             2 23 42 0 70 */
+589,	/* OBJ_setct_CredRevReqTBE          2 23 42 0 71 */
+590,	/* OBJ_setct_CredRevReqTBEX         2 23 42 0 72 */
+591,	/* OBJ_setct_CredRevResTBE          2 23 42 0 73 */
+592,	/* OBJ_setct_BatchAdminReqTBE       2 23 42 0 74 */
+593,	/* OBJ_setct_BatchAdminResTBE       2 23 42 0 75 */
+594,	/* OBJ_setct_RegFormReqTBE          2 23 42 0 76 */
+595,	/* OBJ_setct_CertReqTBE             2 23 42 0 77 */
+596,	/* OBJ_setct_CertReqTBEX            2 23 42 0 78 */
+597,	/* OBJ_setct_CertResTBE             2 23 42 0 79 */
+598,	/* OBJ_setct_CRLNotificationTBS     2 23 42 0 80 */
+599,	/* OBJ_setct_CRLNotificationResTBS  2 23 42 0 81 */
+600,	/* OBJ_setct_BCIDistributionTBS     2 23 42 0 82 */
+601,	/* OBJ_setext_genCrypt              2 23 42 1 1 */
+602,	/* OBJ_setext_miAuth                2 23 42 1 3 */
+603,	/* OBJ_setext_pinSecure             2 23 42 1 4 */
+604,	/* OBJ_setext_pinAny                2 23 42 1 5 */
+605,	/* OBJ_setext_track2                2 23 42 1 7 */
+606,	/* OBJ_setext_cv                    2 23 42 1 8 */
+620,	/* OBJ_setAttr_Cert                 2 23 42 3 0 */
+621,	/* OBJ_setAttr_PGWYcap              2 23 42 3 1 */
+622,	/* OBJ_setAttr_TokenType            2 23 42 3 2 */
+623,	/* OBJ_setAttr_IssCap               2 23 42 3 3 */
+607,	/* OBJ_set_policy_root              2 23 42 5 0 */
+608,	/* OBJ_setCext_hashedRoot           2 23 42 7 0 */
+609,	/* OBJ_setCext_certType             2 23 42 7 1 */
+610,	/* OBJ_setCext_merchData            2 23 42 7 2 */
+611,	/* OBJ_setCext_cCertRequired        2 23 42 7 3 */
+612,	/* OBJ_setCext_tunneling            2 23 42 7 4 */
+613,	/* OBJ_setCext_setExt               2 23 42 7 5 */
+614,	/* OBJ_setCext_setQualf             2 23 42 7 6 */
+615,	/* OBJ_setCext_PGWYcapabilities     2 23 42 7 7 */
+616,	/* OBJ_setCext_TokenIdentifier      2 23 42 7 8 */
+617,	/* OBJ_setCext_Track2Data           2 23 42 7 9 */
+618,	/* OBJ_setCext_TokenType            2 23 42 7 10 */
+619,	/* OBJ_setCext_IssuerCapabilities   2 23 42 7 11 */
+636,	/* OBJ_set_brand_IATA_ATA           2 23 42 8 1 */
+640,	/* OBJ_set_brand_Visa               2 23 42 8 4 */
+641,	/* OBJ_set_brand_MasterCard         2 23 42 8 5 */
+637,	/* OBJ_set_brand_Diners             2 23 42 8 30 */
+638,	/* OBJ_set_brand_AmericanExpress    2 23 42 8 34 */
+639,	/* OBJ_set_brand_JCB                2 23 42 8 35 */
+805,	/* OBJ_cryptopro                    1 2 643 2 2 */
+806,	/* OBJ_cryptocom                    1 2 643 2 9 */
+184,	/* OBJ_X9_57                        1 2 840 10040 */
+405,	/* OBJ_ansi_X9_62                   1 2 840 10045 */
+389,	/* OBJ_Enterprises                  1 3 6 1 4 1 */
+504,	/* OBJ_mime_mhs                     1 3 6 1 7 1 */
+104,	/* OBJ_md5WithRSA                   1 3 14 3 2 3 */
+29,	/* OBJ_des_ecb                      1 3 14 3 2 6 */
+31,	/* OBJ_des_cbc                      1 3 14 3 2 7 */
+45,	/* OBJ_des_ofb64                    1 3 14 3 2 8 */
+30,	/* OBJ_des_cfb64                    1 3 14 3 2 9 */
+377,	/* OBJ_rsaSignature                 1 3 14 3 2 11 */
+67,	/* OBJ_dsa_2                        1 3 14 3 2 12 */
+66,	/* OBJ_dsaWithSHA                   1 3 14 3 2 13 */
+42,	/* OBJ_shaWithRSAEncryption         1 3 14 3 2 15 */
+32,	/* OBJ_des_ede_ecb                  1 3 14 3 2 17 */
+41,	/* OBJ_sha                          1 3 14 3 2 18 */
+64,	/* OBJ_sha1                         1 3 14 3 2 26 */
+70,	/* OBJ_dsaWithSHA1_2                1 3 14 3 2 27 */
+115,	/* OBJ_sha1WithRSA                  1 3 14 3 2 29 */
+117,	/* OBJ_ripemd160                    1 3 36 3 2 1 */
+143,	/* OBJ_sxnet                        1 3 101 1 4 1 */
+721,	/* OBJ_sect163k1                    1 3 132 0 1 */
+722,	/* OBJ_sect163r1                    1 3 132 0 2 */
+728,	/* OBJ_sect239k1                    1 3 132 0 3 */
+717,	/* OBJ_sect113r1                    1 3 132 0 4 */
+718,	/* OBJ_sect113r2                    1 3 132 0 5 */
+704,	/* OBJ_secp112r1                    1 3 132 0 6 */
+705,	/* OBJ_secp112r2                    1 3 132 0 7 */
+709,	/* OBJ_secp160r1                    1 3 132 0 8 */
+708,	/* OBJ_secp160k1                    1 3 132 0 9 */
+714,	/* OBJ_secp256k1                    1 3 132 0 10 */
+723,	/* OBJ_sect163r2                    1 3 132 0 15 */
+729,	/* OBJ_sect283k1                    1 3 132 0 16 */
+730,	/* OBJ_sect283r1                    1 3 132 0 17 */
+719,	/* OBJ_sect131r1                    1 3 132 0 22 */
+720,	/* OBJ_sect131r2                    1 3 132 0 23 */
+724,	/* OBJ_sect193r1                    1 3 132 0 24 */
+725,	/* OBJ_sect193r2                    1 3 132 0 25 */
+726,	/* OBJ_sect233k1                    1 3 132 0 26 */
+727,	/* OBJ_sect233r1                    1 3 132 0 27 */
+706,	/* OBJ_secp128r1                    1 3 132 0 28 */
+707,	/* OBJ_secp128r2                    1 3 132 0 29 */
+710,	/* OBJ_secp160r2                    1 3 132 0 30 */
+711,	/* OBJ_secp192k1                    1 3 132 0 31 */
+712,	/* OBJ_secp224k1                    1 3 132 0 32 */
+713,	/* OBJ_secp224r1                    1 3 132 0 33 */
+715,	/* OBJ_secp384r1                    1 3 132 0 34 */
+716,	/* OBJ_secp521r1                    1 3 132 0 35 */
+731,	/* OBJ_sect409k1                    1 3 132 0 36 */
+732,	/* OBJ_sect409r1                    1 3 132 0 37 */
+733,	/* OBJ_sect571k1                    1 3 132 0 38 */
+734,	/* OBJ_sect571r1                    1 3 132 0 39 */
+624,	/* OBJ_set_rootKeyThumb             2 23 42 3 0 0 */
+625,	/* OBJ_set_addPolicy                2 23 42 3 0 1 */
+626,	/* OBJ_setAttr_Token_EMV            2 23 42 3 2 1 */
+627,	/* OBJ_setAttr_Token_B0Prime        2 23 42 3 2 2 */
+628,	/* OBJ_setAttr_IssCap_CVM           2 23 42 3 3 3 */
+629,	/* OBJ_setAttr_IssCap_T2            2 23 42 3 3 4 */
+630,	/* OBJ_setAttr_IssCap_Sig           2 23 42 3 3 5 */
+642,	/* OBJ_set_brand_Novus              2 23 42 8 6011 */
+735,	/* OBJ_wap_wsg_idm_ecid_wtls1       2 23 43 1 4 1 */
+736,	/* OBJ_wap_wsg_idm_ecid_wtls3       2 23 43 1 4 3 */
+737,	/* OBJ_wap_wsg_idm_ecid_wtls4       2 23 43 1 4 4 */
+738,	/* OBJ_wap_wsg_idm_ecid_wtls5       2 23 43 1 4 5 */
+739,	/* OBJ_wap_wsg_idm_ecid_wtls6       2 23 43 1 4 6 */
+740,	/* OBJ_wap_wsg_idm_ecid_wtls7       2 23 43 1 4 7 */
+741,	/* OBJ_wap_wsg_idm_ecid_wtls8       2 23 43 1 4 8 */
+742,	/* OBJ_wap_wsg_idm_ecid_wtls9       2 23 43 1 4 9 */
+743,	/* OBJ_wap_wsg_idm_ecid_wtls10      2 23 43 1 4 10 */
+744,	/* OBJ_wap_wsg_idm_ecid_wtls11      2 23 43 1 4 11 */
+745,	/* OBJ_wap_wsg_idm_ecid_wtls12      2 23 43 1 4 12 */
+804,	/* OBJ_whirlpool                    1 0 10118 3 0 55 */
+124,	/* OBJ_rle_compression              1 1 1 1 666 1 */
+773,	/* OBJ_kisa                         1 2 410 200004 */
+807,	/* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */
+808,	/* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */
+809,	/* OBJ_id_GostR3411_94              1 2 643 2 2 9 */
+810,	/* OBJ_id_HMACGostR3411_94          1 2 643 2 2 10 */
+811,	/* OBJ_id_GostR3410_2001            1 2 643 2 2 19 */
+812,	/* OBJ_id_GostR3410_94              1 2 643 2 2 20 */
+813,	/* OBJ_id_Gost28147_89              1 2 643 2 2 21 */
+815,	/* OBJ_id_Gost28147_89_MAC          1 2 643 2 2 22 */
+816,	/* OBJ_id_GostR3411_94_prf          1 2 643 2 2 23 */
+817,	/* OBJ_id_GostR3410_2001DH          1 2 643 2 2 98 */
+818,	/* OBJ_id_GostR3410_94DH            1 2 643 2 2 99 */
+ 1,	/* OBJ_rsadsi                       1 2 840 113549 */
+185,	/* OBJ_X9cm                         1 2 840 10040 4 */
+127,	/* OBJ_id_pkix                      1 3 6 1 5 5 7 */
+505,	/* OBJ_mime_mhs_headings            1 3 6 1 7 1 1 */
+506,	/* OBJ_mime_mhs_bodies              1 3 6 1 7 1 2 */
+119,	/* OBJ_ripemd160WithRSA             1 3 36 3 3 1 2 */
+631,	/* OBJ_setAttr_GenCryptgrm          2 23 42 3 3 3 1 */
+632,	/* OBJ_setAttr_T2Enc                2 23 42 3 3 4 1 */
+633,	/* OBJ_setAttr_T2cleartxt           2 23 42 3 3 4 2 */
+634,	/* OBJ_setAttr_TokICCsig            2 23 42 3 3 5 1 */
+635,	/* OBJ_setAttr_SecDevSig            2 23 42 3 3 5 2 */
+436,	/* OBJ_ucl                          0 9 2342 19200300 */
+820,	/* OBJ_id_Gost28147_89_None_KeyMeshing 1 2 643 2 2 14 0 */
+819,	/* OBJ_id_Gost28147_89_CryptoPro_KeyMeshing 1 2 643 2 2 14 1 */
+845,	/* OBJ_id_GostR3410_94_a            1 2 643 2 2 20 1 */
+846,	/* OBJ_id_GostR3410_94_aBis         1 2 643 2 2 20 2 */
+847,	/* OBJ_id_GostR3410_94_b            1 2 643 2 2 20 3 */
+848,	/* OBJ_id_GostR3410_94_bBis         1 2 643 2 2 20 4 */
+821,	/* OBJ_id_GostR3411_94_TestParamSet 1 2 643 2 2 30 0 */
+822,	/* OBJ_id_GostR3411_94_CryptoProParamSet 1 2 643 2 2 30 1 */
+823,	/* OBJ_id_Gost28147_89_TestParamSet 1 2 643 2 2 31 0 */
+824,	/* OBJ_id_Gost28147_89_CryptoPro_A_ParamSet 1 2 643 2 2 31 1 */
+825,	/* OBJ_id_Gost28147_89_CryptoPro_B_ParamSet 1 2 643 2 2 31 2 */
+826,	/* OBJ_id_Gost28147_89_CryptoPro_C_ParamSet 1 2 643 2 2 31 3 */
+827,	/* OBJ_id_Gost28147_89_CryptoPro_D_ParamSet 1 2 643 2 2 31 4 */
+828,	/* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 1 2 643 2 2 31 5 */
+829,	/* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 1 2 643 2 2 31 6 */
+830,	/* OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 1 2 643 2 2 31 7 */
+831,	/* OBJ_id_GostR3410_94_TestParamSet 1 2 643 2 2 32 0 */
+832,	/* OBJ_id_GostR3410_94_CryptoPro_A_ParamSet 1 2 643 2 2 32 2 */
+833,	/* OBJ_id_GostR3410_94_CryptoPro_B_ParamSet 1 2 643 2 2 32 3 */
+834,	/* OBJ_id_GostR3410_94_CryptoPro_C_ParamSet 1 2 643 2 2 32 4 */
+835,	/* OBJ_id_GostR3410_94_CryptoPro_D_ParamSet 1 2 643 2 2 32 5 */
+836,	/* OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet 1 2 643 2 2 33 1 */
+837,	/* OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet 1 2 643 2 2 33 2 */
+838,	/* OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet 1 2 643 2 2 33 3 */
+839,	/* OBJ_id_GostR3410_2001_TestParamSet 1 2 643 2 2 35 0 */
+840,	/* OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet 1 2 643 2 2 35 1 */
+841,	/* OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet 1 2 643 2 2 35 2 */
+842,	/* OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet 1 2 643 2 2 35 3 */
+843,	/* OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet 1 2 643 2 2 36 0 */
+844,	/* OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet 1 2 643 2 2 36 1 */
+ 2,	/* OBJ_pkcs                         1 2 840 113549 1 */
+431,	/* OBJ_hold_instruction_none        1 2 840 10040 2 1 */
+432,	/* OBJ_hold_instruction_call_issuer 1 2 840 10040 2 2 */
+433,	/* OBJ_hold_instruction_reject      1 2 840 10040 2 3 */
+116,	/* OBJ_dsa                          1 2 840 10040 4 1 */
+113,	/* OBJ_dsaWithSHA1                  1 2 840 10040 4 3 */
+406,	/* OBJ_X9_62_prime_field            1 2 840 10045 1 1 */
+407,	/* OBJ_X9_62_characteristic_two_field 1 2 840 10045 1 2 */
+408,	/* OBJ_X9_62_id_ecPublicKey         1 2 840 10045 2 1 */
+416,	/* OBJ_ecdsa_with_SHA1              1 2 840 10045 4 1 */
+791,	/* OBJ_ecdsa_with_Recommended       1 2 840 10045 4 2 */
+792,	/* OBJ_ecdsa_with_Specified         1 2 840 10045 4 3 */
+258,	/* OBJ_id_pkix_mod                  1 3 6 1 5 5 7 0 */
+175,	/* OBJ_id_pe                        1 3 6 1 5 5 7 1 */
+259,	/* OBJ_id_qt                        1 3 6 1 5 5 7 2 */
+128,	/* OBJ_id_kp                        1 3 6 1 5 5 7 3 */
+260,	/* OBJ_id_it                        1 3 6 1 5 5 7 4 */
+261,	/* OBJ_id_pkip                      1 3 6 1 5 5 7 5 */
+262,	/* OBJ_id_alg                       1 3 6 1 5 5 7 6 */
+263,	/* OBJ_id_cmc                       1 3 6 1 5 5 7 7 */
+264,	/* OBJ_id_on                        1 3 6 1 5 5 7 8 */
+265,	/* OBJ_id_pda                       1 3 6 1 5 5 7 9 */
+266,	/* OBJ_id_aca                       1 3 6 1 5 5 7 10 */
+267,	/* OBJ_id_qcs                       1 3 6 1 5 5 7 11 */
+268,	/* OBJ_id_cct                       1 3 6 1 5 5 7 12 */
+662,	/* OBJ_id_ppl                       1 3 6 1 5 5 7 21 */
+176,	/* OBJ_id_ad                        1 3 6 1 5 5 7 48 */
+507,	/* OBJ_id_hex_partial_message       1 3 6 1 7 1 1 1 */
+508,	/* OBJ_id_hex_multipart_message     1 3 6 1 7 1 1 2 */
+57,	/* OBJ_netscape                     2 16 840 1 113730 */
+754,	/* OBJ_camellia_128_ecb             0 3 4401 5 3 1 9 1 */
+766,	/* OBJ_camellia_128_ofb128          0 3 4401 5 3 1 9 3 */
+757,	/* OBJ_camellia_128_cfb128          0 3 4401 5 3 1 9 4 */
+755,	/* OBJ_camellia_192_ecb             0 3 4401 5 3 1 9 21 */
+767,	/* OBJ_camellia_192_ofb128          0 3 4401 5 3 1 9 23 */
+758,	/* OBJ_camellia_192_cfb128          0 3 4401 5 3 1 9 24 */
+756,	/* OBJ_camellia_256_ecb             0 3 4401 5 3 1 9 41 */
+768,	/* OBJ_camellia_256_ofb128          0 3 4401 5 3 1 9 43 */
+759,	/* OBJ_camellia_256_cfb128          0 3 4401 5 3 1 9 44 */
+437,	/* OBJ_pilot                        0 9 2342 19200300 100 */
+776,	/* OBJ_seed_ecb                     1 2 410 200004 1 3 */
+777,	/* OBJ_seed_cbc                     1 2 410 200004 1 4 */
+779,	/* OBJ_seed_cfb128                  1 2 410 200004 1 5 */
+778,	/* OBJ_seed_ofb128                  1 2 410 200004 1 6 */
+852,	/* OBJ_id_GostR3411_94_with_GostR3410_94_cc 1 2 643 2 9 1 3 3 */
+853,	/* OBJ_id_GostR3411_94_with_GostR3410_2001_cc 1 2 643 2 9 1 3 4 */
+850,	/* OBJ_id_GostR3410_94_cc           1 2 643 2 9 1 5 3 */
+851,	/* OBJ_id_GostR3410_2001_cc         1 2 643 2 9 1 5 4 */
+849,	/* OBJ_id_Gost28147_89_cc           1 2 643 2 9 1 6 1 */
+854,	/* OBJ_id_GostR3410_2001_ParamSet_cc 1 2 643 2 9 1 8 1 */
+186,	/* OBJ_pkcs1                        1 2 840 113549 1 1 */
+27,	/* OBJ_pkcs3                        1 2 840 113549 1 3 */
+187,	/* OBJ_pkcs5                        1 2 840 113549 1 5 */
+20,	/* OBJ_pkcs7                        1 2 840 113549 1 7 */
+47,	/* OBJ_pkcs9                        1 2 840 113549 1 9 */
+ 3,	/* OBJ_md2                          1 2 840 113549 2 2 */
+257,	/* OBJ_md4                          1 2 840 113549 2 4 */
+ 4,	/* OBJ_md5                          1 2 840 113549 2 5 */
+797,	/* OBJ_hmacWithMD5                  1 2 840 113549 2 6 */
+163,	/* OBJ_hmacWithSHA1                 1 2 840 113549 2 7 */
+798,	/* OBJ_hmacWithSHA224               1 2 840 113549 2 8 */
+799,	/* OBJ_hmacWithSHA256               1 2 840 113549 2 9 */
+800,	/* OBJ_hmacWithSHA384               1 2 840 113549 2 10 */
+801,	/* OBJ_hmacWithSHA512               1 2 840 113549 2 11 */
+37,	/* OBJ_rc2_cbc                      1 2 840 113549 3 2 */
+ 5,	/* OBJ_rc4                          1 2 840 113549 3 4 */
+44,	/* OBJ_des_ede3_cbc                 1 2 840 113549 3 7 */
+120,	/* OBJ_rc5_cbc                      1 2 840 113549 3 8 */
+643,	/* OBJ_des_cdmf                     1 2 840 113549 3 10 */
+680,	/* OBJ_X9_62_id_characteristic_two_basis 1 2 840 10045 1 2 3 */
+684,	/* OBJ_X9_62_c2pnb163v1             1 2 840 10045 3 0 1 */
+685,	/* OBJ_X9_62_c2pnb163v2             1 2 840 10045 3 0 2 */
+686,	/* OBJ_X9_62_c2pnb163v3             1 2 840 10045 3 0 3 */
+687,	/* OBJ_X9_62_c2pnb176v1             1 2 840 10045 3 0 4 */
+688,	/* OBJ_X9_62_c2tnb191v1             1 2 840 10045 3 0 5 */
+689,	/* OBJ_X9_62_c2tnb191v2             1 2 840 10045 3 0 6 */
+690,	/* OBJ_X9_62_c2tnb191v3             1 2 840 10045 3 0 7 */
+691,	/* OBJ_X9_62_c2onb191v4             1 2 840 10045 3 0 8 */
+692,	/* OBJ_X9_62_c2onb191v5             1 2 840 10045 3 0 9 */
+693,	/* OBJ_X9_62_c2pnb208w1             1 2 840 10045 3 0 10 */
+694,	/* OBJ_X9_62_c2tnb239v1             1 2 840 10045 3 0 11 */
+695,	/* OBJ_X9_62_c2tnb239v2             1 2 840 10045 3 0 12 */
+696,	/* OBJ_X9_62_c2tnb239v3             1 2 840 10045 3 0 13 */
+697,	/* OBJ_X9_62_c2onb239v4             1 2 840 10045 3 0 14 */
+698,	/* OBJ_X9_62_c2onb239v5             1 2 840 10045 3 0 15 */
+699,	/* OBJ_X9_62_c2pnb272w1             1 2 840 10045 3 0 16 */
+700,	/* OBJ_X9_62_c2pnb304w1             1 2 840 10045 3 0 17 */
+701,	/* OBJ_X9_62_c2tnb359v1             1 2 840 10045 3 0 18 */
+702,	/* OBJ_X9_62_c2pnb368w1             1 2 840 10045 3 0 19 */
+703,	/* OBJ_X9_62_c2tnb431r1             1 2 840 10045 3 0 20 */
+409,	/* OBJ_X9_62_prime192v1             1 2 840 10045 3 1 1 */
+410,	/* OBJ_X9_62_prime192v2             1 2 840 10045 3 1 2 */
+411,	/* OBJ_X9_62_prime192v3             1 2 840 10045 3 1 3 */
+412,	/* OBJ_X9_62_prime239v1             1 2 840 10045 3 1 4 */
+413,	/* OBJ_X9_62_prime239v2             1 2 840 10045 3 1 5 */
+414,	/* OBJ_X9_62_prime239v3             1 2 840 10045 3 1 6 */
+415,	/* OBJ_X9_62_prime256v1             1 2 840 10045 3 1 7 */
+793,	/* OBJ_ecdsa_with_SHA224            1 2 840 10045 4 3 1 */
+794,	/* OBJ_ecdsa_with_SHA256            1 2 840 10045 4 3 2 */
+795,	/* OBJ_ecdsa_with_SHA384            1 2 840 10045 4 3 3 */
+796,	/* OBJ_ecdsa_with_SHA512            1 2 840 10045 4 3 4 */
+269,	/* OBJ_id_pkix1_explicit_88         1 3 6 1 5 5 7 0 1 */
+270,	/* OBJ_id_pkix1_implicit_88         1 3 6 1 5 5 7 0 2 */
+271,	/* OBJ_id_pkix1_explicit_93         1 3 6 1 5 5 7 0 3 */
+272,	/* OBJ_id_pkix1_implicit_93         1 3 6 1 5 5 7 0 4 */
+273,	/* OBJ_id_mod_crmf                  1 3 6 1 5 5 7 0 5 */
+274,	/* OBJ_id_mod_cmc                   1 3 6 1 5 5 7 0 6 */
+275,	/* OBJ_id_mod_kea_profile_88        1 3 6 1 5 5 7 0 7 */
+276,	/* OBJ_id_mod_kea_profile_93        1 3 6 1 5 5 7 0 8 */
+277,	/* OBJ_id_mod_cmp                   1 3 6 1 5 5 7 0 9 */
+278,	/* OBJ_id_mod_qualified_cert_88     1 3 6 1 5 5 7 0 10 */
+279,	/* OBJ_id_mod_qualified_cert_93     1 3 6 1 5 5 7 0 11 */
+280,	/* OBJ_id_mod_attribute_cert        1 3 6 1 5 5 7 0 12 */
+281,	/* OBJ_id_mod_timestamp_protocol    1 3 6 1 5 5 7 0 13 */
+282,	/* OBJ_id_mod_ocsp                  1 3 6 1 5 5 7 0 14 */
+283,	/* OBJ_id_mod_dvcs                  1 3 6 1 5 5 7 0 15 */
+284,	/* OBJ_id_mod_cmp2000               1 3 6 1 5 5 7 0 16 */
+177,	/* OBJ_info_access                  1 3 6 1 5 5 7 1 1 */
+285,	/* OBJ_biometricInfo                1 3 6 1 5 5 7 1 2 */
+286,	/* OBJ_qcStatements                 1 3 6 1 5 5 7 1 3 */
+287,	/* OBJ_ac_auditEntity               1 3 6 1 5 5 7 1 4 */
+288,	/* OBJ_ac_targeting                 1 3 6 1 5 5 7 1 5 */
+289,	/* OBJ_aaControls                   1 3 6 1 5 5 7 1 6 */
+290,	/* OBJ_sbgp_ipAddrBlock             1 3 6 1 5 5 7 1 7 */
+291,	/* OBJ_sbgp_autonomousSysNum        1 3 6 1 5 5 7 1 8 */
+292,	/* OBJ_sbgp_routerIdentifier        1 3 6 1 5 5 7 1 9 */
+397,	/* OBJ_ac_proxying                  1 3 6 1 5 5 7 1 10 */
+398,	/* OBJ_sinfo_access                 1 3 6 1 5 5 7 1 11 */
+663,	/* OBJ_proxyCertInfo                1 3 6 1 5 5 7 1 14 */
+164,	/* OBJ_id_qt_cps                    1 3 6 1 5 5 7 2 1 */
+165,	/* OBJ_id_qt_unotice                1 3 6 1 5 5 7 2 2 */
+293,	/* OBJ_textNotice                   1 3 6 1 5 5 7 2 3 */
+129,	/* OBJ_server_auth                  1 3 6 1 5 5 7 3 1 */
+130,	/* OBJ_client_auth                  1 3 6 1 5 5 7 3 2 */
+131,	/* OBJ_code_sign                    1 3 6 1 5 5 7 3 3 */
+132,	/* OBJ_email_protect                1 3 6 1 5 5 7 3 4 */
+294,	/* OBJ_ipsecEndSystem               1 3 6 1 5 5 7 3 5 */
+295,	/* OBJ_ipsecTunnel                  1 3 6 1 5 5 7 3 6 */
+296,	/* OBJ_ipsecUser                    1 3 6 1 5 5 7 3 7 */
+133,	/* OBJ_time_stamp                   1 3 6 1 5 5 7 3 8 */
+180,	/* OBJ_OCSP_sign                    1 3 6 1 5 5 7 3 9 */
+297,	/* OBJ_dvcs                         1 3 6 1 5 5 7 3 10 */
+298,	/* OBJ_id_it_caProtEncCert          1 3 6 1 5 5 7 4 1 */
+299,	/* OBJ_id_it_signKeyPairTypes       1 3 6 1 5 5 7 4 2 */
+300,	/* OBJ_id_it_encKeyPairTypes        1 3 6 1 5 5 7 4 3 */
+301,	/* OBJ_id_it_preferredSymmAlg       1 3 6 1 5 5 7 4 4 */
+302,	/* OBJ_id_it_caKeyUpdateInfo        1 3 6 1 5 5 7 4 5 */
+303,	/* OBJ_id_it_currentCRL             1 3 6 1 5 5 7 4 6 */
+304,	/* OBJ_id_it_unsupportedOIDs        1 3 6 1 5 5 7 4 7 */
+305,	/* OBJ_id_it_subscriptionRequest    1 3 6 1 5 5 7 4 8 */
+306,	/* OBJ_id_it_subscriptionResponse   1 3 6 1 5 5 7 4 9 */
+307,	/* OBJ_id_it_keyPairParamReq        1 3 6 1 5 5 7 4 10 */
+308,	/* OBJ_id_it_keyPairParamRep        1 3 6 1 5 5 7 4 11 */
+309,	/* OBJ_id_it_revPassphrase          1 3 6 1 5 5 7 4 12 */
+310,	/* OBJ_id_it_implicitConfirm        1 3 6 1 5 5 7 4 13 */
+311,	/* OBJ_id_it_confirmWaitTime        1 3 6 1 5 5 7 4 14 */
+312,	/* OBJ_id_it_origPKIMessage         1 3 6 1 5 5 7 4 15 */
+784,	/* OBJ_id_it_suppLangTags           1 3 6 1 5 5 7 4 16 */
+313,	/* OBJ_id_regCtrl                   1 3 6 1 5 5 7 5 1 */
+314,	/* OBJ_id_regInfo                   1 3 6 1 5 5 7 5 2 */
+323,	/* OBJ_id_alg_des40                 1 3 6 1 5 5 7 6 1 */
+324,	/* OBJ_id_alg_noSignature           1 3 6 1 5 5 7 6 2 */
+325,	/* OBJ_id_alg_dh_sig_hmac_sha1      1 3 6 1 5 5 7 6 3 */
+326,	/* OBJ_id_alg_dh_pop                1 3 6 1 5 5 7 6 4 */
+327,	/* OBJ_id_cmc_statusInfo            1 3 6 1 5 5 7 7 1 */
+328,	/* OBJ_id_cmc_identification        1 3 6 1 5 5 7 7 2 */
+329,	/* OBJ_id_cmc_identityProof         1 3 6 1 5 5 7 7 3 */
+330,	/* OBJ_id_cmc_dataReturn            1 3 6 1 5 5 7 7 4 */
+331,	/* OBJ_id_cmc_transactionId         1 3 6 1 5 5 7 7 5 */
+332,	/* OBJ_id_cmc_senderNonce           1 3 6 1 5 5 7 7 6 */
+333,	/* OBJ_id_cmc_recipientNonce        1 3 6 1 5 5 7 7 7 */
+334,	/* OBJ_id_cmc_addExtensions         1 3 6 1 5 5 7 7 8 */
+335,	/* OBJ_id_cmc_encryptedPOP          1 3 6 1 5 5 7 7 9 */
+336,	/* OBJ_id_cmc_decryptedPOP          1 3 6 1 5 5 7 7 10 */
+337,	/* OBJ_id_cmc_lraPOPWitness         1 3 6 1 5 5 7 7 11 */
+338,	/* OBJ_id_cmc_getCert               1 3 6 1 5 5 7 7 15 */
+339,	/* OBJ_id_cmc_getCRL                1 3 6 1 5 5 7 7 16 */
+340,	/* OBJ_id_cmc_revokeRequest         1 3 6 1 5 5 7 7 17 */
+341,	/* OBJ_id_cmc_regInfo               1 3 6 1 5 5 7 7 18 */
+342,	/* OBJ_id_cmc_responseInfo          1 3 6 1 5 5 7 7 19 */
+343,	/* OBJ_id_cmc_queryPending          1 3 6 1 5 5 7 7 21 */
+344,	/* OBJ_id_cmc_popLinkRandom         1 3 6 1 5 5 7 7 22 */
+345,	/* OBJ_id_cmc_popLinkWitness        1 3 6 1 5 5 7 7 23 */
+346,	/* OBJ_id_cmc_confirmCertAcceptance 1 3 6 1 5 5 7 7 24 */
+347,	/* OBJ_id_on_personalData           1 3 6 1 5 5 7 8 1 */
+858,	/* OBJ_id_on_permanentIdentifier    1 3 6 1 5 5 7 8 3 */
+348,	/* OBJ_id_pda_dateOfBirth           1 3 6 1 5 5 7 9 1 */
+349,	/* OBJ_id_pda_placeOfBirth          1 3 6 1 5 5 7 9 2 */
+351,	/* OBJ_id_pda_gender                1 3 6 1 5 5 7 9 3 */
+352,	/* OBJ_id_pda_countryOfCitizenship  1 3 6 1 5 5 7 9 4 */
+353,	/* OBJ_id_pda_countryOfResidence    1 3 6 1 5 5 7 9 5 */
+354,	/* OBJ_id_aca_authenticationInfo    1 3 6 1 5 5 7 10 1 */
+355,	/* OBJ_id_aca_accessIdentity        1 3 6 1 5 5 7 10 2 */
+356,	/* OBJ_id_aca_chargingIdentity      1 3 6 1 5 5 7 10 3 */
+357,	/* OBJ_id_aca_group                 1 3 6 1 5 5 7 10 4 */
+358,	/* OBJ_id_aca_role                  1 3 6 1 5 5 7 10 5 */
+399,	/* OBJ_id_aca_encAttrs              1 3 6 1 5 5 7 10 6 */
+359,	/* OBJ_id_qcs_pkixQCSyntax_v1       1 3 6 1 5 5 7 11 1 */
+360,	/* OBJ_id_cct_crs                   1 3 6 1 5 5 7 12 1 */
+361,	/* OBJ_id_cct_PKIData               1 3 6 1 5 5 7 12 2 */
+362,	/* OBJ_id_cct_PKIResponse           1 3 6 1 5 5 7 12 3 */
+664,	/* OBJ_id_ppl_anyLanguage           1 3 6 1 5 5 7 21 0 */
+665,	/* OBJ_id_ppl_inheritAll            1 3 6 1 5 5 7 21 1 */
+667,	/* OBJ_Independent                  1 3 6 1 5 5 7 21 2 */
+178,	/* OBJ_ad_OCSP                      1 3 6 1 5 5 7 48 1 */
+179,	/* OBJ_ad_ca_issuers                1 3 6 1 5 5 7 48 2 */
+363,	/* OBJ_ad_timeStamping              1 3 6 1 5 5 7 48 3 */
+364,	/* OBJ_ad_dvcs                      1 3 6 1 5 5 7 48 4 */
+785,	/* OBJ_caRepository                 1 3 6 1 5 5 7 48 5 */
+780,	/* OBJ_hmac_md5                     1 3 6 1 5 5 8 1 1 */
+781,	/* OBJ_hmac_sha1                    1 3 6 1 5 5 8 1 2 */
+58,	/* OBJ_netscape_cert_extension      2 16 840 1 113730 1 */
+59,	/* OBJ_netscape_data_type           2 16 840 1 113730 2 */
+438,	/* OBJ_pilotAttributeType           0 9 2342 19200300 100 1 */
+439,	/* OBJ_pilotAttributeSyntax         0 9 2342 19200300 100 3 */
+440,	/* OBJ_pilotObjectClass             0 9 2342 19200300 100 4 */
+441,	/* OBJ_pilotGroups                  0 9 2342 19200300 100 10 */
+108,	/* OBJ_cast5_cbc                    1 2 840 113533 7 66 10 */
+112,	/* OBJ_pbeWithMD5AndCast5_CBC       1 2 840 113533 7 66 12 */
+782,	/* OBJ_id_PasswordBasedMAC          1 2 840 113533 7 66 13 */
+783,	/* OBJ_id_DHBasedMac                1 2 840 113533 7 66 30 */
+ 6,	/* OBJ_rsaEncryption                1 2 840 113549 1 1 1 */
+ 7,	/* OBJ_md2WithRSAEncryption         1 2 840 113549 1 1 2 */
+396,	/* OBJ_md4WithRSAEncryption         1 2 840 113549 1 1 3 */
+ 8,	/* OBJ_md5WithRSAEncryption         1 2 840 113549 1 1 4 */
+65,	/* OBJ_sha1WithRSAEncryption        1 2 840 113549 1 1 5 */
+644,	/* OBJ_rsaOAEPEncryptionSET         1 2 840 113549 1 1 6 */
+668,	/* OBJ_sha256WithRSAEncryption      1 2 840 113549 1 1 11 */
+669,	/* OBJ_sha384WithRSAEncryption      1 2 840 113549 1 1 12 */
+670,	/* OBJ_sha512WithRSAEncryption      1 2 840 113549 1 1 13 */
+671,	/* OBJ_sha224WithRSAEncryption      1 2 840 113549 1 1 14 */
+28,	/* OBJ_dhKeyAgreement               1 2 840 113549 1 3 1 */
+ 9,	/* OBJ_pbeWithMD2AndDES_CBC         1 2 840 113549 1 5 1 */
+10,	/* OBJ_pbeWithMD5AndDES_CBC         1 2 840 113549 1 5 3 */
+168,	/* OBJ_pbeWithMD2AndRC2_CBC         1 2 840 113549 1 5 4 */
+169,	/* OBJ_pbeWithMD5AndRC2_CBC         1 2 840 113549 1 5 6 */
+170,	/* OBJ_pbeWithSHA1AndDES_CBC        1 2 840 113549 1 5 10 */
+68,	/* OBJ_pbeWithSHA1AndRC2_CBC        1 2 840 113549 1 5 11 */
+69,	/* OBJ_id_pbkdf2                    1 2 840 113549 1 5 12 */
+161,	/* OBJ_pbes2                        1 2 840 113549 1 5 13 */
+162,	/* OBJ_pbmac1                       1 2 840 113549 1 5 14 */
+21,	/* OBJ_pkcs7_data                   1 2 840 113549 1 7 1 */
+22,	/* OBJ_pkcs7_signed                 1 2 840 113549 1 7 2 */
+23,	/* OBJ_pkcs7_enveloped              1 2 840 113549 1 7 3 */
+24,	/* OBJ_pkcs7_signedAndEnveloped     1 2 840 113549 1 7 4 */
+25,	/* OBJ_pkcs7_digest                 1 2 840 113549 1 7 5 */
+26,	/* OBJ_pkcs7_encrypted              1 2 840 113549 1 7 6 */
+48,	/* OBJ_pkcs9_emailAddress           1 2 840 113549 1 9 1 */
+49,	/* OBJ_pkcs9_unstructuredName       1 2 840 113549 1 9 2 */
+50,	/* OBJ_pkcs9_contentType            1 2 840 113549 1 9 3 */
+51,	/* OBJ_pkcs9_messageDigest          1 2 840 113549 1 9 4 */
+52,	/* OBJ_pkcs9_signingTime            1 2 840 113549 1 9 5 */
+53,	/* OBJ_pkcs9_countersignature       1 2 840 113549 1 9 6 */
+54,	/* OBJ_pkcs9_challengePassword      1 2 840 113549 1 9 7 */
+55,	/* OBJ_pkcs9_unstructuredAddress    1 2 840 113549 1 9 8 */
+56,	/* OBJ_pkcs9_extCertAttributes      1 2 840 113549 1 9 9 */
+172,	/* OBJ_ext_req                      1 2 840 113549 1 9 14 */
+167,	/* OBJ_SMIMECapabilities            1 2 840 113549 1 9 15 */
+188,	/* OBJ_SMIME                        1 2 840 113549 1 9 16 */
+156,	/* OBJ_friendlyName                 1 2 840 113549 1 9 20 */
+157,	/* OBJ_localKeyID                   1 2 840 113549 1 9 21 */
+681,	/* OBJ_X9_62_onBasis                1 2 840 10045 1 2 3 1 */
+682,	/* OBJ_X9_62_tpBasis                1 2 840 10045 1 2 3 2 */
+683,	/* OBJ_X9_62_ppBasis                1 2 840 10045 1 2 3 3 */
+417,	/* OBJ_ms_csp_name                  1 3 6 1 4 1 311 17 1 */
+856,	/* OBJ_LocalKeySet                  1 3 6 1 4 1 311 17 2 */
+390,	/* OBJ_dcObject                     1 3 6 1 4 1 1466 344 */
+91,	/* OBJ_bf_cbc                       1 3 6 1 4 1 3029 1 2 */
+315,	/* OBJ_id_regCtrl_regToken          1 3 6 1 5 5 7 5 1 1 */
+316,	/* OBJ_id_regCtrl_authenticator     1 3 6 1 5 5 7 5 1 2 */
+317,	/* OBJ_id_regCtrl_pkiPublicationInfo 1 3 6 1 5 5 7 5 1 3 */
+318,	/* OBJ_id_regCtrl_pkiArchiveOptions 1 3 6 1 5 5 7 5 1 4 */
+319,	/* OBJ_id_regCtrl_oldCertID         1 3 6 1 5 5 7 5 1 5 */
+320,	/* OBJ_id_regCtrl_protocolEncrKey   1 3 6 1 5 5 7 5 1 6 */
+321,	/* OBJ_id_regInfo_utf8Pairs         1 3 6 1 5 5 7 5 2 1 */
+322,	/* OBJ_id_regInfo_certReq           1 3 6 1 5 5 7 5 2 2 */
+365,	/* OBJ_id_pkix_OCSP_basic           1 3 6 1 5 5 7 48 1 1 */
+366,	/* OBJ_id_pkix_OCSP_Nonce           1 3 6 1 5 5 7 48 1 2 */
+367,	/* OBJ_id_pkix_OCSP_CrlID           1 3 6 1 5 5 7 48 1 3 */
+368,	/* OBJ_id_pkix_OCSP_acceptableResponses 1 3 6 1 5 5 7 48 1 4 */
+369,	/* OBJ_id_pkix_OCSP_noCheck         1 3 6 1 5 5 7 48 1 5 */
+370,	/* OBJ_id_pkix_OCSP_archiveCutoff   1 3 6 1 5 5 7 48 1 6 */
+371,	/* OBJ_id_pkix_OCSP_serviceLocator  1 3 6 1 5 5 7 48 1 7 */
+372,	/* OBJ_id_pkix_OCSP_extendedStatus  1 3 6 1 5 5 7 48 1 8 */
+373,	/* OBJ_id_pkix_OCSP_valid           1 3 6 1 5 5 7 48 1 9 */
+374,	/* OBJ_id_pkix_OCSP_path            1 3 6 1 5 5 7 48 1 10 */
+375,	/* OBJ_id_pkix_OCSP_trustRoot       1 3 6 1 5 5 7 48 1 11 */
+418,	/* OBJ_aes_128_ecb                  2 16 840 1 101 3 4 1 1 */
+419,	/* OBJ_aes_128_cbc                  2 16 840 1 101 3 4 1 2 */
+420,	/* OBJ_aes_128_ofb128               2 16 840 1 101 3 4 1 3 */
+421,	/* OBJ_aes_128_cfb128               2 16 840 1 101 3 4 1 4 */
+788,	/* OBJ_id_aes128_wrap               2 16 840 1 101 3 4 1 5 */
+422,	/* OBJ_aes_192_ecb                  2 16 840 1 101 3 4 1 21 */
+423,	/* OBJ_aes_192_cbc                  2 16 840 1 101 3 4 1 22 */
+424,	/* OBJ_aes_192_ofb128               2 16 840 1 101 3 4 1 23 */
+425,	/* OBJ_aes_192_cfb128               2 16 840 1 101 3 4 1 24 */
+789,	/* OBJ_id_aes192_wrap               2 16 840 1 101 3 4 1 25 */
+426,	/* OBJ_aes_256_ecb                  2 16 840 1 101 3 4 1 41 */
+427,	/* OBJ_aes_256_cbc                  2 16 840 1 101 3 4 1 42 */
+428,	/* OBJ_aes_256_ofb128               2 16 840 1 101 3 4 1 43 */
+429,	/* OBJ_aes_256_cfb128               2 16 840 1 101 3 4 1 44 */
+790,	/* OBJ_id_aes256_wrap               2 16 840 1 101 3 4 1 45 */
+672,	/* OBJ_sha256                       2 16 840 1 101 3 4 2 1 */
+673,	/* OBJ_sha384                       2 16 840 1 101 3 4 2 2 */
+674,	/* OBJ_sha512                       2 16 840 1 101 3 4 2 3 */
+675,	/* OBJ_sha224                       2 16 840 1 101 3 4 2 4 */
+802,	/* OBJ_dsa_with_SHA224              2 16 840 1 101 3 4 3 1 */
+803,	/* OBJ_dsa_with_SHA256              2 16 840 1 101 3 4 3 2 */
+71,	/* OBJ_netscape_cert_type           2 16 840 1 113730 1 1 */
+72,	/* OBJ_netscape_base_url            2 16 840 1 113730 1 2 */
+73,	/* OBJ_netscape_revocation_url      2 16 840 1 113730 1 3 */
+74,	/* OBJ_netscape_ca_revocation_url   2 16 840 1 113730 1 4 */
+75,	/* OBJ_netscape_renewal_url         2 16 840 1 113730 1 7 */
+76,	/* OBJ_netscape_ca_policy_url       2 16 840 1 113730 1 8 */
+77,	/* OBJ_netscape_ssl_server_name     2 16 840 1 113730 1 12 */
+78,	/* OBJ_netscape_comment             2 16 840 1 113730 1 13 */
+79,	/* OBJ_netscape_cert_sequence       2 16 840 1 113730 2 5 */
+139,	/* OBJ_ns_sgc                       2 16 840 1 113730 4 1 */
+458,	/* OBJ_userId                       0 9 2342 19200300 100 1 1 */
+459,	/* OBJ_textEncodedORAddress         0 9 2342 19200300 100 1 2 */
+460,	/* OBJ_rfc822Mailbox                0 9 2342 19200300 100 1 3 */
+461,	/* OBJ_info                         0 9 2342 19200300 100 1 4 */
+462,	/* OBJ_favouriteDrink               0 9 2342 19200300 100 1 5 */
+463,	/* OBJ_roomNumber                   0 9 2342 19200300 100 1 6 */
+464,	/* OBJ_photo                        0 9 2342 19200300 100 1 7 */
+465,	/* OBJ_userClass                    0 9 2342 19200300 100 1 8 */
+466,	/* OBJ_host                         0 9 2342 19200300 100 1 9 */
+467,	/* OBJ_manager                      0 9 2342 19200300 100 1 10 */
+468,	/* OBJ_documentIdentifier           0 9 2342 19200300 100 1 11 */
+469,	/* OBJ_documentTitle                0 9 2342 19200300 100 1 12 */
+470,	/* OBJ_documentVersion              0 9 2342 19200300 100 1 13 */
+471,	/* OBJ_documentAuthor               0 9 2342 19200300 100 1 14 */
+472,	/* OBJ_documentLocation             0 9 2342 19200300 100 1 15 */
+473,	/* OBJ_homeTelephoneNumber          0 9 2342 19200300 100 1 20 */
+474,	/* OBJ_secretary                    0 9 2342 19200300 100 1 21 */
+475,	/* OBJ_otherMailbox                 0 9 2342 19200300 100 1 22 */
+476,	/* OBJ_lastModifiedTime             0 9 2342 19200300 100 1 23 */
+477,	/* OBJ_lastModifiedBy               0 9 2342 19200300 100 1 24 */
+391,	/* OBJ_domainComponent              0 9 2342 19200300 100 1 25 */
+478,	/* OBJ_aRecord                      0 9 2342 19200300 100 1 26 */
+479,	/* OBJ_pilotAttributeType27         0 9 2342 19200300 100 1 27 */
+480,	/* OBJ_mXRecord                     0 9 2342 19200300 100 1 28 */
+481,	/* OBJ_nSRecord                     0 9 2342 19200300 100 1 29 */
+482,	/* OBJ_sOARecord                    0 9 2342 19200300 100 1 30 */
+483,	/* OBJ_cNAMERecord                  0 9 2342 19200300 100 1 31 */
+484,	/* OBJ_associatedDomain             0 9 2342 19200300 100 1 37 */
+485,	/* OBJ_associatedName               0 9 2342 19200300 100 1 38 */
+486,	/* OBJ_homePostalAddress            0 9 2342 19200300 100 1 39 */
+487,	/* OBJ_personalTitle                0 9 2342 19200300 100 1 40 */
+488,	/* OBJ_mobileTelephoneNumber        0 9 2342 19200300 100 1 41 */
+489,	/* OBJ_pagerTelephoneNumber         0 9 2342 19200300 100 1 42 */
+490,	/* OBJ_friendlyCountryName          0 9 2342 19200300 100 1 43 */
+491,	/* OBJ_organizationalStatus         0 9 2342 19200300 100 1 45 */
+492,	/* OBJ_janetMailbox                 0 9 2342 19200300 100 1 46 */
+493,	/* OBJ_mailPreferenceOption         0 9 2342 19200300 100 1 47 */
+494,	/* OBJ_buildingName                 0 9 2342 19200300 100 1 48 */
+495,	/* OBJ_dSAQuality                   0 9 2342 19200300 100 1 49 */
+496,	/* OBJ_singleLevelQuality           0 9 2342 19200300 100 1 50 */
+497,	/* OBJ_subtreeMinimumQuality        0 9 2342 19200300 100 1 51 */
+498,	/* OBJ_subtreeMaximumQuality        0 9 2342 19200300 100 1 52 */
+499,	/* OBJ_personalSignature            0 9 2342 19200300 100 1 53 */
+500,	/* OBJ_dITRedirect                  0 9 2342 19200300 100 1 54 */
+501,	/* OBJ_audio                        0 9 2342 19200300 100 1 55 */
+502,	/* OBJ_documentPublisher            0 9 2342 19200300 100 1 56 */
+442,	/* OBJ_iA5StringSyntax              0 9 2342 19200300 100 3 4 */
+443,	/* OBJ_caseIgnoreIA5StringSyntax    0 9 2342 19200300 100 3 5 */
+444,	/* OBJ_pilotObject                  0 9 2342 19200300 100 4 3 */
+445,	/* OBJ_pilotPerson                  0 9 2342 19200300 100 4 4 */
+446,	/* OBJ_account                      0 9 2342 19200300 100 4 5 */
+447,	/* OBJ_document                     0 9 2342 19200300 100 4 6 */
+448,	/* OBJ_room                         0 9 2342 19200300 100 4 7 */
+449,	/* OBJ_documentSeries               0 9 2342 19200300 100 4 9 */
+392,	/* OBJ_Domain                       0 9 2342 19200300 100 4 13 */
+450,	/* OBJ_rFC822localPart              0 9 2342 19200300 100 4 14 */
+451,	/* OBJ_dNSDomain                    0 9 2342 19200300 100 4 15 */
+452,	/* OBJ_domainRelatedObject          0 9 2342 19200300 100 4 17 */
+453,	/* OBJ_friendlyCountry              0 9 2342 19200300 100 4 18 */
+454,	/* OBJ_simpleSecurityObject         0 9 2342 19200300 100 4 19 */
+455,	/* OBJ_pilotOrganization            0 9 2342 19200300 100 4 20 */
+456,	/* OBJ_pilotDSA                     0 9 2342 19200300 100 4 21 */
+457,	/* OBJ_qualityLabelledData          0 9 2342 19200300 100 4 22 */
+189,	/* OBJ_id_smime_mod                 1 2 840 113549 1 9 16 0 */
+190,	/* OBJ_id_smime_ct                  1 2 840 113549 1 9 16 1 */
+191,	/* OBJ_id_smime_aa                  1 2 840 113549 1 9 16 2 */
+192,	/* OBJ_id_smime_alg                 1 2 840 113549 1 9 16 3 */
+193,	/* OBJ_id_smime_cd                  1 2 840 113549 1 9 16 4 */
+194,	/* OBJ_id_smime_spq                 1 2 840 113549 1 9 16 5 */
+195,	/* OBJ_id_smime_cti                 1 2 840 113549 1 9 16 6 */
+158,	/* OBJ_x509Certificate              1 2 840 113549 1 9 22 1 */
+159,	/* OBJ_sdsiCertificate              1 2 840 113549 1 9 22 2 */
+160,	/* OBJ_x509Crl                      1 2 840 113549 1 9 23 1 */
+144,	/* OBJ_pbe_WithSHA1And128BitRC4     1 2 840 113549 1 12 1 1 */
+145,	/* OBJ_pbe_WithSHA1And40BitRC4      1 2 840 113549 1 12 1 2 */
+146,	/* OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC 1 2 840 113549 1 12 1 3 */
+147,	/* OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC 1 2 840 113549 1 12 1 4 */
+148,	/* OBJ_pbe_WithSHA1And128BitRC2_CBC 1 2 840 113549 1 12 1 5 */
+149,	/* OBJ_pbe_WithSHA1And40BitRC2_CBC  1 2 840 113549 1 12 1 6 */
+171,	/* OBJ_ms_ext_req                   1 3 6 1 4 1 311 2 1 14 */
+134,	/* OBJ_ms_code_ind                  1 3 6 1 4 1 311 2 1 21 */
+135,	/* OBJ_ms_code_com                  1 3 6 1 4 1 311 2 1 22 */
+136,	/* OBJ_ms_ctl_sign                  1 3 6 1 4 1 311 10 3 1 */
+137,	/* OBJ_ms_sgc                       1 3 6 1 4 1 311 10 3 3 */
+138,	/* OBJ_ms_efs                       1 3 6 1 4 1 311 10 3 4 */
+648,	/* OBJ_ms_smartcard_login           1 3 6 1 4 1 311 20 2 2 */
+649,	/* OBJ_ms_upn                       1 3 6 1 4 1 311 20 2 3 */
+751,	/* OBJ_camellia_128_cbc             1 2 392 200011 61 1 1 1 2 */
+752,	/* OBJ_camellia_192_cbc             1 2 392 200011 61 1 1 1 3 */
+753,	/* OBJ_camellia_256_cbc             1 2 392 200011 61 1 1 1 4 */
+196,	/* OBJ_id_smime_mod_cms             1 2 840 113549 1 9 16 0 1 */
+197,	/* OBJ_id_smime_mod_ess             1 2 840 113549 1 9 16 0 2 */
+198,	/* OBJ_id_smime_mod_oid             1 2 840 113549 1 9 16 0 3 */
+199,	/* OBJ_id_smime_mod_msg_v3          1 2 840 113549 1 9 16 0 4 */
+200,	/* OBJ_id_smime_mod_ets_eSignature_88 1 2 840 113549 1 9 16 0 5 */
+201,	/* OBJ_id_smime_mod_ets_eSignature_97 1 2 840 113549 1 9 16 0 6 */
+202,	/* OBJ_id_smime_mod_ets_eSigPolicy_88 1 2 840 113549 1 9 16 0 7 */
+203,	/* OBJ_id_smime_mod_ets_eSigPolicy_97 1 2 840 113549 1 9 16 0 8 */
+204,	/* OBJ_id_smime_ct_receipt          1 2 840 113549 1 9 16 1 1 */
+205,	/* OBJ_id_smime_ct_authData         1 2 840 113549 1 9 16 1 2 */
+206,	/* OBJ_id_smime_ct_publishCert      1 2 840 113549 1 9 16 1 3 */
+207,	/* OBJ_id_smime_ct_TSTInfo          1 2 840 113549 1 9 16 1 4 */
+208,	/* OBJ_id_smime_ct_TDTInfo          1 2 840 113549 1 9 16 1 5 */
+209,	/* OBJ_id_smime_ct_contentInfo      1 2 840 113549 1 9 16 1 6 */
+210,	/* OBJ_id_smime_ct_DVCSRequestData  1 2 840 113549 1 9 16 1 7 */
+211,	/* OBJ_id_smime_ct_DVCSResponseData 1 2 840 113549 1 9 16 1 8 */
+786,	/* OBJ_id_smime_ct_compressedData   1 2 840 113549 1 9 16 1 9 */
+787,	/* OBJ_id_ct_asciiTextWithCRLF      1 2 840 113549 1 9 16 1 27 */
+212,	/* OBJ_id_smime_aa_receiptRequest   1 2 840 113549 1 9 16 2 1 */
+213,	/* OBJ_id_smime_aa_securityLabel    1 2 840 113549 1 9 16 2 2 */
+214,	/* OBJ_id_smime_aa_mlExpandHistory  1 2 840 113549 1 9 16 2 3 */
+215,	/* OBJ_id_smime_aa_contentHint      1 2 840 113549 1 9 16 2 4 */
+216,	/* OBJ_id_smime_aa_msgSigDigest     1 2 840 113549 1 9 16 2 5 */
+217,	/* OBJ_id_smime_aa_encapContentType 1 2 840 113549 1 9 16 2 6 */
+218,	/* OBJ_id_smime_aa_contentIdentifier 1 2 840 113549 1 9 16 2 7 */
+219,	/* OBJ_id_smime_aa_macValue         1 2 840 113549 1 9 16 2 8 */
+220,	/* OBJ_id_smime_aa_equivalentLabels 1 2 840 113549 1 9 16 2 9 */
+221,	/* OBJ_id_smime_aa_contentReference 1 2 840 113549 1 9 16 2 10 */
+222,	/* OBJ_id_smime_aa_encrypKeyPref    1 2 840 113549 1 9 16 2 11 */
+223,	/* OBJ_id_smime_aa_signingCertificate 1 2 840 113549 1 9 16 2 12 */
+224,	/* OBJ_id_smime_aa_smimeEncryptCerts 1 2 840 113549 1 9 16 2 13 */
+225,	/* OBJ_id_smime_aa_timeStampToken   1 2 840 113549 1 9 16 2 14 */
+226,	/* OBJ_id_smime_aa_ets_sigPolicyId  1 2 840 113549 1 9 16 2 15 */
+227,	/* OBJ_id_smime_aa_ets_commitmentType 1 2 840 113549 1 9 16 2 16 */
+228,	/* OBJ_id_smime_aa_ets_signerLocation 1 2 840 113549 1 9 16 2 17 */
+229,	/* OBJ_id_smime_aa_ets_signerAttr   1 2 840 113549 1 9 16 2 18 */
+230,	/* OBJ_id_smime_aa_ets_otherSigCert 1 2 840 113549 1 9 16 2 19 */
+231,	/* OBJ_id_smime_aa_ets_contentTimestamp 1 2 840 113549 1 9 16 2 20 */
+232,	/* OBJ_id_smime_aa_ets_CertificateRefs 1 2 840 113549 1 9 16 2 21 */
+233,	/* OBJ_id_smime_aa_ets_RevocationRefs 1 2 840 113549 1 9 16 2 22 */
+234,	/* OBJ_id_smime_aa_ets_certValues   1 2 840 113549 1 9 16 2 23 */
+235,	/* OBJ_id_smime_aa_ets_revocationValues 1 2 840 113549 1 9 16 2 24 */
+236,	/* OBJ_id_smime_aa_ets_escTimeStamp 1 2 840 113549 1 9 16 2 25 */
+237,	/* OBJ_id_smime_aa_ets_certCRLTimestamp 1 2 840 113549 1 9 16 2 26 */
+238,	/* OBJ_id_smime_aa_ets_archiveTimeStamp 1 2 840 113549 1 9 16 2 27 */
+239,	/* OBJ_id_smime_aa_signatureType    1 2 840 113549 1 9 16 2 28 */
+240,	/* OBJ_id_smime_aa_dvcs_dvc         1 2 840 113549 1 9 16 2 29 */
+241,	/* OBJ_id_smime_alg_ESDHwith3DES    1 2 840 113549 1 9 16 3 1 */
+242,	/* OBJ_id_smime_alg_ESDHwithRC2     1 2 840 113549 1 9 16 3 2 */
+243,	/* OBJ_id_smime_alg_3DESwrap        1 2 840 113549 1 9 16 3 3 */
+244,	/* OBJ_id_smime_alg_RC2wrap         1 2 840 113549 1 9 16 3 4 */
+245,	/* OBJ_id_smime_alg_ESDH            1 2 840 113549 1 9 16 3 5 */
+246,	/* OBJ_id_smime_alg_CMS3DESwrap     1 2 840 113549 1 9 16 3 6 */
+247,	/* OBJ_id_smime_alg_CMSRC2wrap      1 2 840 113549 1 9 16 3 7 */
+125,	/* OBJ_zlib_compression             1 2 840 113549 1 9 16 3 8 */
+248,	/* OBJ_id_smime_cd_ldap             1 2 840 113549 1 9 16 4 1 */
+249,	/* OBJ_id_smime_spq_ets_sqt_uri     1 2 840 113549 1 9 16 5 1 */
+250,	/* OBJ_id_smime_spq_ets_sqt_unotice 1 2 840 113549 1 9 16 5 2 */
+251,	/* OBJ_id_smime_cti_ets_proofOfOrigin 1 2 840 113549 1 9 16 6 1 */
+252,	/* OBJ_id_smime_cti_ets_proofOfReceipt 1 2 840 113549 1 9 16 6 2 */
+253,	/* OBJ_id_smime_cti_ets_proofOfDelivery 1 2 840 113549 1 9 16 6 3 */
+254,	/* OBJ_id_smime_cti_ets_proofOfSender 1 2 840 113549 1 9 16 6 4 */
+255,	/* OBJ_id_smime_cti_ets_proofOfApproval 1 2 840 113549 1 9 16 6 5 */
+256,	/* OBJ_id_smime_cti_ets_proofOfCreation 1 2 840 113549 1 9 16 6 6 */
+150,	/* OBJ_keyBag                       1 2 840 113549 1 12 10 1 1 */
+151,	/* OBJ_pkcs8ShroudedKeyBag          1 2 840 113549 1 12 10 1 2 */
+152,	/* OBJ_certBag                      1 2 840 113549 1 12 10 1 3 */
+153,	/* OBJ_crlBag                       1 2 840 113549 1 12 10 1 4 */
+154,	/* OBJ_secretBag                    1 2 840 113549 1 12 10 1 5 */
+155,	/* OBJ_safeContentsBag              1 2 840 113549 1 12 10 1 6 */
+34,	/* OBJ_idea_cbc                     1 3 6 1 4 1 188 7 1 1 2 */
+};
+
diff --git a/openssl/crypto/objects/obj_dat.pl b/openssl/crypto/objects/obj_dat.pl
new file mode 100644
index 0000000..c67f71c
--- /dev/null
+++ b/openssl/crypto/objects/obj_dat.pl
@@ -0,0 +1,307 @@
+#!/usr/local/bin/perl
+
+# fixes bug in floating point emulation on sparc64 when
+# this script produces off-by-one output on sparc64
+use integer;
+
+sub obj_cmp
+	{
+	local(@a,@b,$_,$r);
+
+	$A=$obj_len{$obj{$nid{$a}}};
+	$B=$obj_len{$obj{$nid{$b}}};
+
+	$r=($A-$B);
+	return($r) if $r != 0;
+
+	$A=$obj_der{$obj{$nid{$a}}};
+	$B=$obj_der{$obj{$nid{$b}}};
+
+	return($A cmp $B);
+	}
+
+sub expand_obj
+	{
+	local(*v)=@_;
+	local($k,$d);
+	local($i);
+
+	do	{
+		$i=0;
+		foreach $k (keys %v)
+			{
+			if (($v{$k} =~ s/(OBJ_[^,]+),/$v{$1},/))
+				{ $i++; }
+			}
+		} while($i);
+	foreach $k (keys %v)
+		{
+		@a=split(/,/,$v{$k});
+		$objn{$k}=$#a+1;
+		}
+	return(%objn);
+	}
+
+open (IN,"$ARGV[0]") || die "Can't open input file $ARGV[0]";
+open (OUT,">$ARGV[1]") || die "Can't open output file $ARGV[1]";
+
+while (<IN>)
+	{
+	next unless /^\#define\s+(\S+)\s+(.*)$/;
+	$v=$1;
+	$d=$2;
+	$d =~ s/^\"//;
+	$d =~ s/\"$//;
+	if ($v =~ /^SN_(.*)$/)
+		{
+		if(defined $snames{$d})
+			{
+			print "WARNING: Duplicate short name \"$d\"\n";
+			}
+		else 
+			{ $snames{$d} = "X"; }
+		$sn{$1}=$d;
+		}
+	elsif ($v =~ /^LN_(.*)$/)
+		{
+		if(defined $lnames{$d})
+			{
+			print "WARNING: Duplicate long name \"$d\"\n";
+			}
+		else 
+			{ $lnames{$d} = "X"; }
+		$ln{$1}=$d;
+		}
+	elsif ($v =~ /^NID_(.*)$/)
+		{ $nid{$d}=$1; }
+	elsif ($v =~ /^OBJ_(.*)$/)
+		{
+		$obj{$1}=$v;
+		$objd{$v}=$d;
+		}
+	}
+close IN;
+
+%ob=&expand_obj(*objd);
+
+@a=sort { $a <=> $b } keys %nid;
+$n=$a[$#a]+1;
+
+@lvalues=();
+$lvalues=0;
+
+for ($i=0; $i<$n; $i++)
+	{
+	if (!defined($nid{$i}))
+		{
+		push(@out,"{NULL,NULL,NID_undef,0,NULL,0},\n");
+		}
+	else
+		{
+		$sn=defined($sn{$nid{$i}})?"$sn{$nid{$i}}":"NULL";
+		$ln=defined($ln{$nid{$i}})?"$ln{$nid{$i}}":"NULL";
+
+		if ($sn eq "NULL") {
+			$sn=$ln;
+			$sn{$nid{$i}} = $ln;
+		}
+
+		if ($ln eq "NULL") {
+			$ln=$sn;
+			$ln{$nid{$i}} = $sn;
+		}
+			
+		$out ="{";
+		$out.="\"$sn\"";
+		$out.=","."\"$ln\"";
+		$out.=",NID_$nid{$i},";
+		if (defined($obj{$nid{$i}}))
+			{
+			$v=$objd{$obj{$nid{$i}}};
+			$v =~ s/L//g;
+			$v =~ s/,/ /g;
+			$r=&der_it($v);
+			$z="";
+			$length=0;
+			foreach (unpack("C*",$r))
+				{
+				$z.=sprintf("0x%02X,",$_);
+				$length++;
+				}
+			$obj_der{$obj{$nid{$i}}}=$z;
+			$obj_len{$obj{$nid{$i}}}=$length;
+
+			push(@lvalues,sprintf("%-45s/* [%3d] %s */\n",
+				$z,$lvalues,$obj{$nid{$i}}));
+			$out.="$length,&(lvalues[$lvalues]),0";
+			$lvalues+=$length;
+			}
+		else
+			{
+			$out.="0,NULL,0";
+			}
+		$out.="},\n";
+		push(@out,$out);
+		}
+	}
+
+@a=grep(defined($sn{$nid{$_}}),0 .. $n);
+foreach (sort { $sn{$nid{$a}} cmp $sn{$nid{$b}} } @a)
+	{
+	push(@sn,sprintf("%2d,\t/* \"$sn{$nid{$_}}\" */\n",$_));
+	}
+
+@a=grep(defined($ln{$nid{$_}}),0 .. $n);
+foreach (sort { $ln{$nid{$a}} cmp $ln{$nid{$b}} } @a)
+	{
+	push(@ln,sprintf("%2d,\t/* \"$ln{$nid{$_}}\" */\n",$_));
+	}
+
+@a=grep(defined($obj{$nid{$_}}),0 .. $n);
+foreach (sort obj_cmp @a)
+	{
+	$m=$obj{$nid{$_}};
+	$v=$objd{$m};
+	$v =~ s/L//g;
+	$v =~ s/,/ /g;
+	push(@ob,sprintf("%2d,\t/* %-32s %s */\n",$_,$m,$v));
+	}
+
+print OUT <<'EOF';
+/* crypto/objects/obj_dat.h */
+
+/* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the
+ * following command:
+ * perl obj_dat.pl obj_mac.h obj_dat.h
+ */
+
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+EOF
+
+printf OUT "#define NUM_NID %d\n",$n;
+printf OUT "#define NUM_SN %d\n",$#sn+1;
+printf OUT "#define NUM_LN %d\n",$#ln+1;
+printf OUT "#define NUM_OBJ %d\n\n",$#ob+1;
+
+printf OUT "static const unsigned char lvalues[%d]={\n",$lvalues+1;
+print OUT @lvalues;
+print OUT "};\n\n";
+
+printf OUT "static const ASN1_OBJECT nid_objs[NUM_NID]={\n";
+foreach (@out)
+	{
+	if (length($_) > 75)
+		{
+		$out="";
+		foreach (split(/,/))
+			{
+			$t=$out.$_.",";
+			if (length($t) > 70)
+				{
+				print OUT "$out\n";
+				$t="\t$_,";
+				}
+			$out=$t;
+			}
+		chop $out;
+		print OUT "$out";
+		}
+	else
+		{ print OUT $_; }
+	}
+print  OUT "};\n\n";
+
+printf OUT "static const unsigned int sn_objs[NUM_SN]={\n";
+print  OUT @sn;
+print  OUT "};\n\n";
+
+printf OUT "static const unsigned int ln_objs[NUM_LN]={\n";
+print  OUT @ln;
+print  OUT "};\n\n";
+
+printf OUT "static const unsigned int obj_objs[NUM_OBJ]={\n";
+print  OUT @ob;
+print  OUT "};\n\n";
+
+close OUT;
+
+sub der_it
+	{
+	local($v)=@_;
+	local(@a,$i,$ret,@r);
+
+	@a=split(/\s+/,$v);
+	$ret.=pack("C*",$a[0]*40+$a[1]);
+	shift @a;
+	shift @a;
+	foreach (@a)
+		{
+		@r=();
+		$t=0;
+		while ($_ >= 128)
+			{
+			$x=$_%128;
+			$_/=128;
+			push(@r,((($t++)?0x80:0)|$x));
+			}
+		push(@r,((($t++)?0x80:0)|$_));
+		$ret.=pack("C*",reverse(@r));
+		}
+	return($ret);
+	}
diff --git a/openssl/crypto/objects/obj_err.c b/openssl/crypto/objects/obj_err.c
new file mode 100644
index 0000000..2e7a034
--- /dev/null
+++ b/openssl/crypto/objects/obj_err.c
@@ -0,0 +1,102 @@
+/* crypto/objects/obj_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/objects.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_OBJ,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_OBJ,0,reason)
+
+static ERR_STRING_DATA OBJ_str_functs[]=
+	{
+{ERR_FUNC(OBJ_F_OBJ_ADD_OBJECT),	"OBJ_add_object"},
+{ERR_FUNC(OBJ_F_OBJ_CREATE),	"OBJ_create"},
+{ERR_FUNC(OBJ_F_OBJ_DUP),	"OBJ_dup"},
+{ERR_FUNC(OBJ_F_OBJ_NAME_NEW_INDEX),	"OBJ_NAME_new_index"},
+{ERR_FUNC(OBJ_F_OBJ_NID2LN),	"OBJ_nid2ln"},
+{ERR_FUNC(OBJ_F_OBJ_NID2OBJ),	"OBJ_nid2obj"},
+{ERR_FUNC(OBJ_F_OBJ_NID2SN),	"OBJ_nid2sn"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA OBJ_str_reasons[]=
+	{
+{ERR_REASON(OBJ_R_MALLOC_FAILURE)        ,"malloc failure"},
+{ERR_REASON(OBJ_R_UNKNOWN_NID)           ,"unknown nid"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_OBJ_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(OBJ_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,OBJ_str_functs);
+		ERR_load_strings(0,OBJ_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/objects/obj_lib.c b/openssl/crypto/objects/obj_lib.c
new file mode 100644
index 0000000..23e9d48
--- /dev/null
+++ b/openssl/crypto/objects/obj_lib.c
@@ -0,0 +1,129 @@
+/* crypto/objects/obj_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+
+ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o)
+	{
+	ASN1_OBJECT *r;
+	int i;
+	char *ln=NULL,*sn=NULL;
+	unsigned char *data=NULL;
+
+	if (o == NULL) return(NULL);
+	if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC))
+		return((ASN1_OBJECT *)o); /* XXX: ugh! Why? What kind of
+					     duplication is this??? */
+
+	r=ASN1_OBJECT_new();
+	if (r == NULL)
+		{
+		OBJerr(OBJ_F_OBJ_DUP,ERR_R_ASN1_LIB);
+		return(NULL);
+		}
+	data=OPENSSL_malloc(o->length);
+	if (data == NULL)
+		goto err;
+	if (o->data != NULL)
+		memcpy(data,o->data,o->length);
+	/* once data attached to object it remains const */
+	r->data = data;
+	r->length=o->length;
+	r->nid=o->nid;
+	r->ln=r->sn=NULL;
+	if (o->ln != NULL)
+		{
+		i=strlen(o->ln)+1;
+		ln=OPENSSL_malloc(i);
+		if (ln == NULL) goto err;
+		memcpy(ln,o->ln,i);
+		r->ln=ln;
+		}
+
+	if (o->sn != NULL)
+		{
+		i=strlen(o->sn)+1;
+		sn=OPENSSL_malloc(i);
+		if (sn == NULL) goto err;
+		memcpy(sn,o->sn,i);
+		r->sn=sn;
+		}
+	r->flags=o->flags|(ASN1_OBJECT_FLAG_DYNAMIC|
+		ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|ASN1_OBJECT_FLAG_DYNAMIC_DATA);
+	return(r);
+err:
+	OBJerr(OBJ_F_OBJ_DUP,ERR_R_MALLOC_FAILURE);
+	if (ln != NULL)		OPENSSL_free(ln);
+	if (sn != NULL)		OPENSSL_free(sn);
+	if (data != NULL)	OPENSSL_free(data);
+	if (r != NULL)		OPENSSL_free(r);
+	return(NULL);
+	}
+
+int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b)
+	{
+	int ret;
+
+	ret=(a->length-b->length);
+	if (ret) return(ret);
+	return(memcmp(a->data,b->data,a->length));
+	}
diff --git a/openssl/crypto/objects/obj_mac.h b/openssl/crypto/objects/obj_mac.h
new file mode 100644
index 0000000..282f11a
--- /dev/null
+++ b/openssl/crypto/objects/obj_mac.h
@@ -0,0 +1,3914 @@
+/* crypto/objects/obj_mac.h */
+
+/* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the
+ * following command:
+ * perl objects.pl objects.txt obj_mac.num obj_mac.h
+ */
+
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#define SN_undef			"UNDEF"
+#define LN_undef			"undefined"
+#define NID_undef			0
+#define OBJ_undef			0L
+
+#define SN_itu_t		"ITU-T"
+#define LN_itu_t		"itu-t"
+#define NID_itu_t		645
+#define OBJ_itu_t		0L
+
+#define NID_ccitt		404
+#define OBJ_ccitt		OBJ_itu_t
+
+#define SN_iso		"ISO"
+#define LN_iso		"iso"
+#define NID_iso		181
+#define OBJ_iso		1L
+
+#define SN_joint_iso_itu_t		"JOINT-ISO-ITU-T"
+#define LN_joint_iso_itu_t		"joint-iso-itu-t"
+#define NID_joint_iso_itu_t		646
+#define OBJ_joint_iso_itu_t		2L
+
+#define NID_joint_iso_ccitt		393
+#define OBJ_joint_iso_ccitt		OBJ_joint_iso_itu_t
+
+#define SN_member_body		"member-body"
+#define LN_member_body		"ISO Member Body"
+#define NID_member_body		182
+#define OBJ_member_body		OBJ_iso,2L
+
+#define SN_identified_organization		"identified-organization"
+#define NID_identified_organization		676
+#define OBJ_identified_organization		OBJ_iso,3L
+
+#define SN_hmac_md5		"HMAC-MD5"
+#define LN_hmac_md5		"hmac-md5"
+#define NID_hmac_md5		780
+#define OBJ_hmac_md5		OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L
+
+#define SN_hmac_sha1		"HMAC-SHA1"
+#define LN_hmac_sha1		"hmac-sha1"
+#define NID_hmac_sha1		781
+#define OBJ_hmac_sha1		OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L
+
+#define SN_certicom_arc		"certicom-arc"
+#define NID_certicom_arc		677
+#define OBJ_certicom_arc		OBJ_identified_organization,132L
+
+#define SN_international_organizations		"international-organizations"
+#define LN_international_organizations		"International Organizations"
+#define NID_international_organizations		647
+#define OBJ_international_organizations		OBJ_joint_iso_itu_t,23L
+
+#define SN_wap		"wap"
+#define NID_wap		678
+#define OBJ_wap		OBJ_international_organizations,43L
+
+#define SN_wap_wsg		"wap-wsg"
+#define NID_wap_wsg		679
+#define OBJ_wap_wsg		OBJ_wap,1L
+
+#define SN_selected_attribute_types		"selected-attribute-types"
+#define LN_selected_attribute_types		"Selected Attribute Types"
+#define NID_selected_attribute_types		394
+#define OBJ_selected_attribute_types		OBJ_joint_iso_itu_t,5L,1L,5L
+
+#define SN_clearance		"clearance"
+#define NID_clearance		395
+#define OBJ_clearance		OBJ_selected_attribute_types,55L
+
+#define SN_ISO_US		"ISO-US"
+#define LN_ISO_US		"ISO US Member Body"
+#define NID_ISO_US		183
+#define OBJ_ISO_US		OBJ_member_body,840L
+
+#define SN_X9_57		"X9-57"
+#define LN_X9_57		"X9.57"
+#define NID_X9_57		184
+#define OBJ_X9_57		OBJ_ISO_US,10040L
+
+#define SN_X9cm		"X9cm"
+#define LN_X9cm		"X9.57 CM ?"
+#define NID_X9cm		185
+#define OBJ_X9cm		OBJ_X9_57,4L
+
+#define SN_dsa		"DSA"
+#define LN_dsa		"dsaEncryption"
+#define NID_dsa		116
+#define OBJ_dsa		OBJ_X9cm,1L
+
+#define SN_dsaWithSHA1		"DSA-SHA1"
+#define LN_dsaWithSHA1		"dsaWithSHA1"
+#define NID_dsaWithSHA1		113
+#define OBJ_dsaWithSHA1		OBJ_X9cm,3L
+
+#define SN_ansi_X9_62		"ansi-X9-62"
+#define LN_ansi_X9_62		"ANSI X9.62"
+#define NID_ansi_X9_62		405
+#define OBJ_ansi_X9_62		OBJ_ISO_US,10045L
+
+#define OBJ_X9_62_id_fieldType		OBJ_ansi_X9_62,1L
+
+#define SN_X9_62_prime_field		"prime-field"
+#define NID_X9_62_prime_field		406
+#define OBJ_X9_62_prime_field		OBJ_X9_62_id_fieldType,1L
+
+#define SN_X9_62_characteristic_two_field		"characteristic-two-field"
+#define NID_X9_62_characteristic_two_field		407
+#define OBJ_X9_62_characteristic_two_field		OBJ_X9_62_id_fieldType,2L
+
+#define SN_X9_62_id_characteristic_two_basis		"id-characteristic-two-basis"
+#define NID_X9_62_id_characteristic_two_basis		680
+#define OBJ_X9_62_id_characteristic_two_basis		OBJ_X9_62_characteristic_two_field,3L
+
+#define SN_X9_62_onBasis		"onBasis"
+#define NID_X9_62_onBasis		681
+#define OBJ_X9_62_onBasis		OBJ_X9_62_id_characteristic_two_basis,1L
+
+#define SN_X9_62_tpBasis		"tpBasis"
+#define NID_X9_62_tpBasis		682
+#define OBJ_X9_62_tpBasis		OBJ_X9_62_id_characteristic_two_basis,2L
+
+#define SN_X9_62_ppBasis		"ppBasis"
+#define NID_X9_62_ppBasis		683
+#define OBJ_X9_62_ppBasis		OBJ_X9_62_id_characteristic_two_basis,3L
+
+#define OBJ_X9_62_id_publicKeyType		OBJ_ansi_X9_62,2L
+
+#define SN_X9_62_id_ecPublicKey		"id-ecPublicKey"
+#define NID_X9_62_id_ecPublicKey		408
+#define OBJ_X9_62_id_ecPublicKey		OBJ_X9_62_id_publicKeyType,1L
+
+#define OBJ_X9_62_ellipticCurve		OBJ_ansi_X9_62,3L
+
+#define OBJ_X9_62_c_TwoCurve		OBJ_X9_62_ellipticCurve,0L
+
+#define SN_X9_62_c2pnb163v1		"c2pnb163v1"
+#define NID_X9_62_c2pnb163v1		684
+#define OBJ_X9_62_c2pnb163v1		OBJ_X9_62_c_TwoCurve,1L
+
+#define SN_X9_62_c2pnb163v2		"c2pnb163v2"
+#define NID_X9_62_c2pnb163v2		685
+#define OBJ_X9_62_c2pnb163v2		OBJ_X9_62_c_TwoCurve,2L
+
+#define SN_X9_62_c2pnb163v3		"c2pnb163v3"
+#define NID_X9_62_c2pnb163v3		686
+#define OBJ_X9_62_c2pnb163v3		OBJ_X9_62_c_TwoCurve,3L
+
+#define SN_X9_62_c2pnb176v1		"c2pnb176v1"
+#define NID_X9_62_c2pnb176v1		687
+#define OBJ_X9_62_c2pnb176v1		OBJ_X9_62_c_TwoCurve,4L
+
+#define SN_X9_62_c2tnb191v1		"c2tnb191v1"
+#define NID_X9_62_c2tnb191v1		688
+#define OBJ_X9_62_c2tnb191v1		OBJ_X9_62_c_TwoCurve,5L
+
+#define SN_X9_62_c2tnb191v2		"c2tnb191v2"
+#define NID_X9_62_c2tnb191v2		689
+#define OBJ_X9_62_c2tnb191v2		OBJ_X9_62_c_TwoCurve,6L
+
+#define SN_X9_62_c2tnb191v3		"c2tnb191v3"
+#define NID_X9_62_c2tnb191v3		690
+#define OBJ_X9_62_c2tnb191v3		OBJ_X9_62_c_TwoCurve,7L
+
+#define SN_X9_62_c2onb191v4		"c2onb191v4"
+#define NID_X9_62_c2onb191v4		691
+#define OBJ_X9_62_c2onb191v4		OBJ_X9_62_c_TwoCurve,8L
+
+#define SN_X9_62_c2onb191v5		"c2onb191v5"
+#define NID_X9_62_c2onb191v5		692
+#define OBJ_X9_62_c2onb191v5		OBJ_X9_62_c_TwoCurve,9L
+
+#define SN_X9_62_c2pnb208w1		"c2pnb208w1"
+#define NID_X9_62_c2pnb208w1		693
+#define OBJ_X9_62_c2pnb208w1		OBJ_X9_62_c_TwoCurve,10L
+
+#define SN_X9_62_c2tnb239v1		"c2tnb239v1"
+#define NID_X9_62_c2tnb239v1		694
+#define OBJ_X9_62_c2tnb239v1		OBJ_X9_62_c_TwoCurve,11L
+
+#define SN_X9_62_c2tnb239v2		"c2tnb239v2"
+#define NID_X9_62_c2tnb239v2		695
+#define OBJ_X9_62_c2tnb239v2		OBJ_X9_62_c_TwoCurve,12L
+
+#define SN_X9_62_c2tnb239v3		"c2tnb239v3"
+#define NID_X9_62_c2tnb239v3		696
+#define OBJ_X9_62_c2tnb239v3		OBJ_X9_62_c_TwoCurve,13L
+
+#define SN_X9_62_c2onb239v4		"c2onb239v4"
+#define NID_X9_62_c2onb239v4		697
+#define OBJ_X9_62_c2onb239v4		OBJ_X9_62_c_TwoCurve,14L
+
+#define SN_X9_62_c2onb239v5		"c2onb239v5"
+#define NID_X9_62_c2onb239v5		698
+#define OBJ_X9_62_c2onb239v5		OBJ_X9_62_c_TwoCurve,15L
+
+#define SN_X9_62_c2pnb272w1		"c2pnb272w1"
+#define NID_X9_62_c2pnb272w1		699
+#define OBJ_X9_62_c2pnb272w1		OBJ_X9_62_c_TwoCurve,16L
+
+#define SN_X9_62_c2pnb304w1		"c2pnb304w1"
+#define NID_X9_62_c2pnb304w1		700
+#define OBJ_X9_62_c2pnb304w1		OBJ_X9_62_c_TwoCurve,17L
+
+#define SN_X9_62_c2tnb359v1		"c2tnb359v1"
+#define NID_X9_62_c2tnb359v1		701
+#define OBJ_X9_62_c2tnb359v1		OBJ_X9_62_c_TwoCurve,18L
+
+#define SN_X9_62_c2pnb368w1		"c2pnb368w1"
+#define NID_X9_62_c2pnb368w1		702
+#define OBJ_X9_62_c2pnb368w1		OBJ_X9_62_c_TwoCurve,19L
+
+#define SN_X9_62_c2tnb431r1		"c2tnb431r1"
+#define NID_X9_62_c2tnb431r1		703
+#define OBJ_X9_62_c2tnb431r1		OBJ_X9_62_c_TwoCurve,20L
+
+#define OBJ_X9_62_primeCurve		OBJ_X9_62_ellipticCurve,1L
+
+#define SN_X9_62_prime192v1		"prime192v1"
+#define NID_X9_62_prime192v1		409
+#define OBJ_X9_62_prime192v1		OBJ_X9_62_primeCurve,1L
+
+#define SN_X9_62_prime192v2		"prime192v2"
+#define NID_X9_62_prime192v2		410
+#define OBJ_X9_62_prime192v2		OBJ_X9_62_primeCurve,2L
+
+#define SN_X9_62_prime192v3		"prime192v3"
+#define NID_X9_62_prime192v3		411
+#define OBJ_X9_62_prime192v3		OBJ_X9_62_primeCurve,3L
+
+#define SN_X9_62_prime239v1		"prime239v1"
+#define NID_X9_62_prime239v1		412
+#define OBJ_X9_62_prime239v1		OBJ_X9_62_primeCurve,4L
+
+#define SN_X9_62_prime239v2		"prime239v2"
+#define NID_X9_62_prime239v2		413
+#define OBJ_X9_62_prime239v2		OBJ_X9_62_primeCurve,5L
+
+#define SN_X9_62_prime239v3		"prime239v3"
+#define NID_X9_62_prime239v3		414
+#define OBJ_X9_62_prime239v3		OBJ_X9_62_primeCurve,6L
+
+#define SN_X9_62_prime256v1		"prime256v1"
+#define NID_X9_62_prime256v1		415
+#define OBJ_X9_62_prime256v1		OBJ_X9_62_primeCurve,7L
+
+#define OBJ_X9_62_id_ecSigType		OBJ_ansi_X9_62,4L
+
+#define SN_ecdsa_with_SHA1		"ecdsa-with-SHA1"
+#define NID_ecdsa_with_SHA1		416
+#define OBJ_ecdsa_with_SHA1		OBJ_X9_62_id_ecSigType,1L
+
+#define SN_ecdsa_with_Recommended		"ecdsa-with-Recommended"
+#define NID_ecdsa_with_Recommended		791
+#define OBJ_ecdsa_with_Recommended		OBJ_X9_62_id_ecSigType,2L
+
+#define SN_ecdsa_with_Specified		"ecdsa-with-Specified"
+#define NID_ecdsa_with_Specified		792
+#define OBJ_ecdsa_with_Specified		OBJ_X9_62_id_ecSigType,3L
+
+#define SN_ecdsa_with_SHA224		"ecdsa-with-SHA224"
+#define NID_ecdsa_with_SHA224		793
+#define OBJ_ecdsa_with_SHA224		OBJ_ecdsa_with_Specified,1L
+
+#define SN_ecdsa_with_SHA256		"ecdsa-with-SHA256"
+#define NID_ecdsa_with_SHA256		794
+#define OBJ_ecdsa_with_SHA256		OBJ_ecdsa_with_Specified,2L
+
+#define SN_ecdsa_with_SHA384		"ecdsa-with-SHA384"
+#define NID_ecdsa_with_SHA384		795
+#define OBJ_ecdsa_with_SHA384		OBJ_ecdsa_with_Specified,3L
+
+#define SN_ecdsa_with_SHA512		"ecdsa-with-SHA512"
+#define NID_ecdsa_with_SHA512		796
+#define OBJ_ecdsa_with_SHA512		OBJ_ecdsa_with_Specified,4L
+
+#define OBJ_secg_ellipticCurve		OBJ_certicom_arc,0L
+
+#define SN_secp112r1		"secp112r1"
+#define NID_secp112r1		704
+#define OBJ_secp112r1		OBJ_secg_ellipticCurve,6L
+
+#define SN_secp112r2		"secp112r2"
+#define NID_secp112r2		705
+#define OBJ_secp112r2		OBJ_secg_ellipticCurve,7L
+
+#define SN_secp128r1		"secp128r1"
+#define NID_secp128r1		706
+#define OBJ_secp128r1		OBJ_secg_ellipticCurve,28L
+
+#define SN_secp128r2		"secp128r2"
+#define NID_secp128r2		707
+#define OBJ_secp128r2		OBJ_secg_ellipticCurve,29L
+
+#define SN_secp160k1		"secp160k1"
+#define NID_secp160k1		708
+#define OBJ_secp160k1		OBJ_secg_ellipticCurve,9L
+
+#define SN_secp160r1		"secp160r1"
+#define NID_secp160r1		709
+#define OBJ_secp160r1		OBJ_secg_ellipticCurve,8L
+
+#define SN_secp160r2		"secp160r2"
+#define NID_secp160r2		710
+#define OBJ_secp160r2		OBJ_secg_ellipticCurve,30L
+
+#define SN_secp192k1		"secp192k1"
+#define NID_secp192k1		711
+#define OBJ_secp192k1		OBJ_secg_ellipticCurve,31L
+
+#define SN_secp224k1		"secp224k1"
+#define NID_secp224k1		712
+#define OBJ_secp224k1		OBJ_secg_ellipticCurve,32L
+
+#define SN_secp224r1		"secp224r1"
+#define NID_secp224r1		713
+#define OBJ_secp224r1		OBJ_secg_ellipticCurve,33L
+
+#define SN_secp256k1		"secp256k1"
+#define NID_secp256k1		714
+#define OBJ_secp256k1		OBJ_secg_ellipticCurve,10L
+
+#define SN_secp384r1		"secp384r1"
+#define NID_secp384r1		715
+#define OBJ_secp384r1		OBJ_secg_ellipticCurve,34L
+
+#define SN_secp521r1		"secp521r1"
+#define NID_secp521r1		716
+#define OBJ_secp521r1		OBJ_secg_ellipticCurve,35L
+
+#define SN_sect113r1		"sect113r1"
+#define NID_sect113r1		717
+#define OBJ_sect113r1		OBJ_secg_ellipticCurve,4L
+
+#define SN_sect113r2		"sect113r2"
+#define NID_sect113r2		718
+#define OBJ_sect113r2		OBJ_secg_ellipticCurve,5L
+
+#define SN_sect131r1		"sect131r1"
+#define NID_sect131r1		719
+#define OBJ_sect131r1		OBJ_secg_ellipticCurve,22L
+
+#define SN_sect131r2		"sect131r2"
+#define NID_sect131r2		720
+#define OBJ_sect131r2		OBJ_secg_ellipticCurve,23L
+
+#define SN_sect163k1		"sect163k1"
+#define NID_sect163k1		721
+#define OBJ_sect163k1		OBJ_secg_ellipticCurve,1L
+
+#define SN_sect163r1		"sect163r1"
+#define NID_sect163r1		722
+#define OBJ_sect163r1		OBJ_secg_ellipticCurve,2L
+
+#define SN_sect163r2		"sect163r2"
+#define NID_sect163r2		723
+#define OBJ_sect163r2		OBJ_secg_ellipticCurve,15L
+
+#define SN_sect193r1		"sect193r1"
+#define NID_sect193r1		724
+#define OBJ_sect193r1		OBJ_secg_ellipticCurve,24L
+
+#define SN_sect193r2		"sect193r2"
+#define NID_sect193r2		725
+#define OBJ_sect193r2		OBJ_secg_ellipticCurve,25L
+
+#define SN_sect233k1		"sect233k1"
+#define NID_sect233k1		726
+#define OBJ_sect233k1		OBJ_secg_ellipticCurve,26L
+
+#define SN_sect233r1		"sect233r1"
+#define NID_sect233r1		727
+#define OBJ_sect233r1		OBJ_secg_ellipticCurve,27L
+
+#define SN_sect239k1		"sect239k1"
+#define NID_sect239k1		728
+#define OBJ_sect239k1		OBJ_secg_ellipticCurve,3L
+
+#define SN_sect283k1		"sect283k1"
+#define NID_sect283k1		729
+#define OBJ_sect283k1		OBJ_secg_ellipticCurve,16L
+
+#define SN_sect283r1		"sect283r1"
+#define NID_sect283r1		730
+#define OBJ_sect283r1		OBJ_secg_ellipticCurve,17L
+
+#define SN_sect409k1		"sect409k1"
+#define NID_sect409k1		731
+#define OBJ_sect409k1		OBJ_secg_ellipticCurve,36L
+
+#define SN_sect409r1		"sect409r1"
+#define NID_sect409r1		732
+#define OBJ_sect409r1		OBJ_secg_ellipticCurve,37L
+
+#define SN_sect571k1		"sect571k1"
+#define NID_sect571k1		733
+#define OBJ_sect571k1		OBJ_secg_ellipticCurve,38L
+
+#define SN_sect571r1		"sect571r1"
+#define NID_sect571r1		734
+#define OBJ_sect571r1		OBJ_secg_ellipticCurve,39L
+
+#define OBJ_wap_wsg_idm_ecid		OBJ_wap_wsg,4L
+
+#define SN_wap_wsg_idm_ecid_wtls1		"wap-wsg-idm-ecid-wtls1"
+#define NID_wap_wsg_idm_ecid_wtls1		735
+#define OBJ_wap_wsg_idm_ecid_wtls1		OBJ_wap_wsg_idm_ecid,1L
+
+#define SN_wap_wsg_idm_ecid_wtls3		"wap-wsg-idm-ecid-wtls3"
+#define NID_wap_wsg_idm_ecid_wtls3		736
+#define OBJ_wap_wsg_idm_ecid_wtls3		OBJ_wap_wsg_idm_ecid,3L
+
+#define SN_wap_wsg_idm_ecid_wtls4		"wap-wsg-idm-ecid-wtls4"
+#define NID_wap_wsg_idm_ecid_wtls4		737
+#define OBJ_wap_wsg_idm_ecid_wtls4		OBJ_wap_wsg_idm_ecid,4L
+
+#define SN_wap_wsg_idm_ecid_wtls5		"wap-wsg-idm-ecid-wtls5"
+#define NID_wap_wsg_idm_ecid_wtls5		738
+#define OBJ_wap_wsg_idm_ecid_wtls5		OBJ_wap_wsg_idm_ecid,5L
+
+#define SN_wap_wsg_idm_ecid_wtls6		"wap-wsg-idm-ecid-wtls6"
+#define NID_wap_wsg_idm_ecid_wtls6		739
+#define OBJ_wap_wsg_idm_ecid_wtls6		OBJ_wap_wsg_idm_ecid,6L
+
+#define SN_wap_wsg_idm_ecid_wtls7		"wap-wsg-idm-ecid-wtls7"
+#define NID_wap_wsg_idm_ecid_wtls7		740
+#define OBJ_wap_wsg_idm_ecid_wtls7		OBJ_wap_wsg_idm_ecid,7L
+
+#define SN_wap_wsg_idm_ecid_wtls8		"wap-wsg-idm-ecid-wtls8"
+#define NID_wap_wsg_idm_ecid_wtls8		741
+#define OBJ_wap_wsg_idm_ecid_wtls8		OBJ_wap_wsg_idm_ecid,8L
+
+#define SN_wap_wsg_idm_ecid_wtls9		"wap-wsg-idm-ecid-wtls9"
+#define NID_wap_wsg_idm_ecid_wtls9		742
+#define OBJ_wap_wsg_idm_ecid_wtls9		OBJ_wap_wsg_idm_ecid,9L
+
+#define SN_wap_wsg_idm_ecid_wtls10		"wap-wsg-idm-ecid-wtls10"
+#define NID_wap_wsg_idm_ecid_wtls10		743
+#define OBJ_wap_wsg_idm_ecid_wtls10		OBJ_wap_wsg_idm_ecid,10L
+
+#define SN_wap_wsg_idm_ecid_wtls11		"wap-wsg-idm-ecid-wtls11"
+#define NID_wap_wsg_idm_ecid_wtls11		744
+#define OBJ_wap_wsg_idm_ecid_wtls11		OBJ_wap_wsg_idm_ecid,11L
+
+#define SN_wap_wsg_idm_ecid_wtls12		"wap-wsg-idm-ecid-wtls12"
+#define NID_wap_wsg_idm_ecid_wtls12		745
+#define OBJ_wap_wsg_idm_ecid_wtls12		OBJ_wap_wsg_idm_ecid,12L
+
+#define SN_cast5_cbc		"CAST5-CBC"
+#define LN_cast5_cbc		"cast5-cbc"
+#define NID_cast5_cbc		108
+#define OBJ_cast5_cbc		OBJ_ISO_US,113533L,7L,66L,10L
+
+#define SN_cast5_ecb		"CAST5-ECB"
+#define LN_cast5_ecb		"cast5-ecb"
+#define NID_cast5_ecb		109
+
+#define SN_cast5_cfb64		"CAST5-CFB"
+#define LN_cast5_cfb64		"cast5-cfb"
+#define NID_cast5_cfb64		110
+
+#define SN_cast5_ofb64		"CAST5-OFB"
+#define LN_cast5_ofb64		"cast5-ofb"
+#define NID_cast5_ofb64		111
+
+#define LN_pbeWithMD5AndCast5_CBC		"pbeWithMD5AndCast5CBC"
+#define NID_pbeWithMD5AndCast5_CBC		112
+#define OBJ_pbeWithMD5AndCast5_CBC		OBJ_ISO_US,113533L,7L,66L,12L
+
+#define SN_id_PasswordBasedMAC		"id-PasswordBasedMAC"
+#define LN_id_PasswordBasedMAC		"password based MAC"
+#define NID_id_PasswordBasedMAC		782
+#define OBJ_id_PasswordBasedMAC		OBJ_ISO_US,113533L,7L,66L,13L
+
+#define SN_id_DHBasedMac		"id-DHBasedMac"
+#define LN_id_DHBasedMac		"Diffie-Hellman based MAC"
+#define NID_id_DHBasedMac		783
+#define OBJ_id_DHBasedMac		OBJ_ISO_US,113533L,7L,66L,30L
+
+#define SN_rsadsi		"rsadsi"
+#define LN_rsadsi		"RSA Data Security, Inc."
+#define NID_rsadsi		1
+#define OBJ_rsadsi		OBJ_ISO_US,113549L
+
+#define SN_pkcs		"pkcs"
+#define LN_pkcs		"RSA Data Security, Inc. PKCS"
+#define NID_pkcs		2
+#define OBJ_pkcs		OBJ_rsadsi,1L
+
+#define SN_pkcs1		"pkcs1"
+#define NID_pkcs1		186
+#define OBJ_pkcs1		OBJ_pkcs,1L
+
+#define LN_rsaEncryption		"rsaEncryption"
+#define NID_rsaEncryption		6
+#define OBJ_rsaEncryption		OBJ_pkcs1,1L
+
+#define SN_md2WithRSAEncryption		"RSA-MD2"
+#define LN_md2WithRSAEncryption		"md2WithRSAEncryption"
+#define NID_md2WithRSAEncryption		7
+#define OBJ_md2WithRSAEncryption		OBJ_pkcs1,2L
+
+#define SN_md4WithRSAEncryption		"RSA-MD4"
+#define LN_md4WithRSAEncryption		"md4WithRSAEncryption"
+#define NID_md4WithRSAEncryption		396
+#define OBJ_md4WithRSAEncryption		OBJ_pkcs1,3L
+
+#define SN_md5WithRSAEncryption		"RSA-MD5"
+#define LN_md5WithRSAEncryption		"md5WithRSAEncryption"
+#define NID_md5WithRSAEncryption		8
+#define OBJ_md5WithRSAEncryption		OBJ_pkcs1,4L
+
+#define SN_sha1WithRSAEncryption		"RSA-SHA1"
+#define LN_sha1WithRSAEncryption		"sha1WithRSAEncryption"
+#define NID_sha1WithRSAEncryption		65
+#define OBJ_sha1WithRSAEncryption		OBJ_pkcs1,5L
+
+#define SN_sha256WithRSAEncryption		"RSA-SHA256"
+#define LN_sha256WithRSAEncryption		"sha256WithRSAEncryption"
+#define NID_sha256WithRSAEncryption		668
+#define OBJ_sha256WithRSAEncryption		OBJ_pkcs1,11L
+
+#define SN_sha384WithRSAEncryption		"RSA-SHA384"
+#define LN_sha384WithRSAEncryption		"sha384WithRSAEncryption"
+#define NID_sha384WithRSAEncryption		669
+#define OBJ_sha384WithRSAEncryption		OBJ_pkcs1,12L
+
+#define SN_sha512WithRSAEncryption		"RSA-SHA512"
+#define LN_sha512WithRSAEncryption		"sha512WithRSAEncryption"
+#define NID_sha512WithRSAEncryption		670
+#define OBJ_sha512WithRSAEncryption		OBJ_pkcs1,13L
+
+#define SN_sha224WithRSAEncryption		"RSA-SHA224"
+#define LN_sha224WithRSAEncryption		"sha224WithRSAEncryption"
+#define NID_sha224WithRSAEncryption		671
+#define OBJ_sha224WithRSAEncryption		OBJ_pkcs1,14L
+
+#define SN_pkcs3		"pkcs3"
+#define NID_pkcs3		27
+#define OBJ_pkcs3		OBJ_pkcs,3L
+
+#define LN_dhKeyAgreement		"dhKeyAgreement"
+#define NID_dhKeyAgreement		28
+#define OBJ_dhKeyAgreement		OBJ_pkcs3,1L
+
+#define SN_pkcs5		"pkcs5"
+#define NID_pkcs5		187
+#define OBJ_pkcs5		OBJ_pkcs,5L
+
+#define SN_pbeWithMD2AndDES_CBC		"PBE-MD2-DES"
+#define LN_pbeWithMD2AndDES_CBC		"pbeWithMD2AndDES-CBC"
+#define NID_pbeWithMD2AndDES_CBC		9
+#define OBJ_pbeWithMD2AndDES_CBC		OBJ_pkcs5,1L
+
+#define SN_pbeWithMD5AndDES_CBC		"PBE-MD5-DES"
+#define LN_pbeWithMD5AndDES_CBC		"pbeWithMD5AndDES-CBC"
+#define NID_pbeWithMD5AndDES_CBC		10
+#define OBJ_pbeWithMD5AndDES_CBC		OBJ_pkcs5,3L
+
+#define SN_pbeWithMD2AndRC2_CBC		"PBE-MD2-RC2-64"
+#define LN_pbeWithMD2AndRC2_CBC		"pbeWithMD2AndRC2-CBC"
+#define NID_pbeWithMD2AndRC2_CBC		168
+#define OBJ_pbeWithMD2AndRC2_CBC		OBJ_pkcs5,4L
+
+#define SN_pbeWithMD5AndRC2_CBC		"PBE-MD5-RC2-64"
+#define LN_pbeWithMD5AndRC2_CBC		"pbeWithMD5AndRC2-CBC"
+#define NID_pbeWithMD5AndRC2_CBC		169
+#define OBJ_pbeWithMD5AndRC2_CBC		OBJ_pkcs5,6L
+
+#define SN_pbeWithSHA1AndDES_CBC		"PBE-SHA1-DES"
+#define LN_pbeWithSHA1AndDES_CBC		"pbeWithSHA1AndDES-CBC"
+#define NID_pbeWithSHA1AndDES_CBC		170
+#define OBJ_pbeWithSHA1AndDES_CBC		OBJ_pkcs5,10L
+
+#define SN_pbeWithSHA1AndRC2_CBC		"PBE-SHA1-RC2-64"
+#define LN_pbeWithSHA1AndRC2_CBC		"pbeWithSHA1AndRC2-CBC"
+#define NID_pbeWithSHA1AndRC2_CBC		68
+#define OBJ_pbeWithSHA1AndRC2_CBC		OBJ_pkcs5,11L
+
+#define LN_id_pbkdf2		"PBKDF2"
+#define NID_id_pbkdf2		69
+#define OBJ_id_pbkdf2		OBJ_pkcs5,12L
+
+#define LN_pbes2		"PBES2"
+#define NID_pbes2		161
+#define OBJ_pbes2		OBJ_pkcs5,13L
+
+#define LN_pbmac1		"PBMAC1"
+#define NID_pbmac1		162
+#define OBJ_pbmac1		OBJ_pkcs5,14L
+
+#define SN_pkcs7		"pkcs7"
+#define NID_pkcs7		20
+#define OBJ_pkcs7		OBJ_pkcs,7L
+
+#define LN_pkcs7_data		"pkcs7-data"
+#define NID_pkcs7_data		21
+#define OBJ_pkcs7_data		OBJ_pkcs7,1L
+
+#define LN_pkcs7_signed		"pkcs7-signedData"
+#define NID_pkcs7_signed		22
+#define OBJ_pkcs7_signed		OBJ_pkcs7,2L
+
+#define LN_pkcs7_enveloped		"pkcs7-envelopedData"
+#define NID_pkcs7_enveloped		23
+#define OBJ_pkcs7_enveloped		OBJ_pkcs7,3L
+
+#define LN_pkcs7_signedAndEnveloped		"pkcs7-signedAndEnvelopedData"
+#define NID_pkcs7_signedAndEnveloped		24
+#define OBJ_pkcs7_signedAndEnveloped		OBJ_pkcs7,4L
+
+#define LN_pkcs7_digest		"pkcs7-digestData"
+#define NID_pkcs7_digest		25
+#define OBJ_pkcs7_digest		OBJ_pkcs7,5L
+
+#define LN_pkcs7_encrypted		"pkcs7-encryptedData"
+#define NID_pkcs7_encrypted		26
+#define OBJ_pkcs7_encrypted		OBJ_pkcs7,6L
+
+#define SN_pkcs9		"pkcs9"
+#define NID_pkcs9		47
+#define OBJ_pkcs9		OBJ_pkcs,9L
+
+#define LN_pkcs9_emailAddress		"emailAddress"
+#define NID_pkcs9_emailAddress		48
+#define OBJ_pkcs9_emailAddress		OBJ_pkcs9,1L
+
+#define LN_pkcs9_unstructuredName		"unstructuredName"
+#define NID_pkcs9_unstructuredName		49
+#define OBJ_pkcs9_unstructuredName		OBJ_pkcs9,2L
+
+#define LN_pkcs9_contentType		"contentType"
+#define NID_pkcs9_contentType		50
+#define OBJ_pkcs9_contentType		OBJ_pkcs9,3L
+
+#define LN_pkcs9_messageDigest		"messageDigest"
+#define NID_pkcs9_messageDigest		51
+#define OBJ_pkcs9_messageDigest		OBJ_pkcs9,4L
+
+#define LN_pkcs9_signingTime		"signingTime"
+#define NID_pkcs9_signingTime		52
+#define OBJ_pkcs9_signingTime		OBJ_pkcs9,5L
+
+#define LN_pkcs9_countersignature		"countersignature"
+#define NID_pkcs9_countersignature		53
+#define OBJ_pkcs9_countersignature		OBJ_pkcs9,6L
+
+#define LN_pkcs9_challengePassword		"challengePassword"
+#define NID_pkcs9_challengePassword		54
+#define OBJ_pkcs9_challengePassword		OBJ_pkcs9,7L
+
+#define LN_pkcs9_unstructuredAddress		"unstructuredAddress"
+#define NID_pkcs9_unstructuredAddress		55
+#define OBJ_pkcs9_unstructuredAddress		OBJ_pkcs9,8L
+
+#define LN_pkcs9_extCertAttributes		"extendedCertificateAttributes"
+#define NID_pkcs9_extCertAttributes		56
+#define OBJ_pkcs9_extCertAttributes		OBJ_pkcs9,9L
+
+#define SN_ext_req		"extReq"
+#define LN_ext_req		"Extension Request"
+#define NID_ext_req		172
+#define OBJ_ext_req		OBJ_pkcs9,14L
+
+#define SN_SMIMECapabilities		"SMIME-CAPS"
+#define LN_SMIMECapabilities		"S/MIME Capabilities"
+#define NID_SMIMECapabilities		167
+#define OBJ_SMIMECapabilities		OBJ_pkcs9,15L
+
+#define SN_SMIME		"SMIME"
+#define LN_SMIME		"S/MIME"
+#define NID_SMIME		188
+#define OBJ_SMIME		OBJ_pkcs9,16L
+
+#define SN_id_smime_mod		"id-smime-mod"
+#define NID_id_smime_mod		189
+#define OBJ_id_smime_mod		OBJ_SMIME,0L
+
+#define SN_id_smime_ct		"id-smime-ct"
+#define NID_id_smime_ct		190
+#define OBJ_id_smime_ct		OBJ_SMIME,1L
+
+#define SN_id_smime_aa		"id-smime-aa"
+#define NID_id_smime_aa		191
+#define OBJ_id_smime_aa		OBJ_SMIME,2L
+
+#define SN_id_smime_alg		"id-smime-alg"
+#define NID_id_smime_alg		192
+#define OBJ_id_smime_alg		OBJ_SMIME,3L
+
+#define SN_id_smime_cd		"id-smime-cd"
+#define NID_id_smime_cd		193
+#define OBJ_id_smime_cd		OBJ_SMIME,4L
+
+#define SN_id_smime_spq		"id-smime-spq"
+#define NID_id_smime_spq		194
+#define OBJ_id_smime_spq		OBJ_SMIME,5L
+
+#define SN_id_smime_cti		"id-smime-cti"
+#define NID_id_smime_cti		195
+#define OBJ_id_smime_cti		OBJ_SMIME,6L
+
+#define SN_id_smime_mod_cms		"id-smime-mod-cms"
+#define NID_id_smime_mod_cms		196
+#define OBJ_id_smime_mod_cms		OBJ_id_smime_mod,1L
+
+#define SN_id_smime_mod_ess		"id-smime-mod-ess"
+#define NID_id_smime_mod_ess		197
+#define OBJ_id_smime_mod_ess		OBJ_id_smime_mod,2L
+
+#define SN_id_smime_mod_oid		"id-smime-mod-oid"
+#define NID_id_smime_mod_oid		198
+#define OBJ_id_smime_mod_oid		OBJ_id_smime_mod,3L
+
+#define SN_id_smime_mod_msg_v3		"id-smime-mod-msg-v3"
+#define NID_id_smime_mod_msg_v3		199
+#define OBJ_id_smime_mod_msg_v3		OBJ_id_smime_mod,4L
+
+#define SN_id_smime_mod_ets_eSignature_88		"id-smime-mod-ets-eSignature-88"
+#define NID_id_smime_mod_ets_eSignature_88		200
+#define OBJ_id_smime_mod_ets_eSignature_88		OBJ_id_smime_mod,5L
+
+#define SN_id_smime_mod_ets_eSignature_97		"id-smime-mod-ets-eSignature-97"
+#define NID_id_smime_mod_ets_eSignature_97		201
+#define OBJ_id_smime_mod_ets_eSignature_97		OBJ_id_smime_mod,6L
+
+#define SN_id_smime_mod_ets_eSigPolicy_88		"id-smime-mod-ets-eSigPolicy-88"
+#define NID_id_smime_mod_ets_eSigPolicy_88		202
+#define OBJ_id_smime_mod_ets_eSigPolicy_88		OBJ_id_smime_mod,7L
+
+#define SN_id_smime_mod_ets_eSigPolicy_97		"id-smime-mod-ets-eSigPolicy-97"
+#define NID_id_smime_mod_ets_eSigPolicy_97		203
+#define OBJ_id_smime_mod_ets_eSigPolicy_97		OBJ_id_smime_mod,8L
+
+#define SN_id_smime_ct_receipt		"id-smime-ct-receipt"
+#define NID_id_smime_ct_receipt		204
+#define OBJ_id_smime_ct_receipt		OBJ_id_smime_ct,1L
+
+#define SN_id_smime_ct_authData		"id-smime-ct-authData"
+#define NID_id_smime_ct_authData		205
+#define OBJ_id_smime_ct_authData		OBJ_id_smime_ct,2L
+
+#define SN_id_smime_ct_publishCert		"id-smime-ct-publishCert"
+#define NID_id_smime_ct_publishCert		206
+#define OBJ_id_smime_ct_publishCert		OBJ_id_smime_ct,3L
+
+#define SN_id_smime_ct_TSTInfo		"id-smime-ct-TSTInfo"
+#define NID_id_smime_ct_TSTInfo		207
+#define OBJ_id_smime_ct_TSTInfo		OBJ_id_smime_ct,4L
+
+#define SN_id_smime_ct_TDTInfo		"id-smime-ct-TDTInfo"
+#define NID_id_smime_ct_TDTInfo		208
+#define OBJ_id_smime_ct_TDTInfo		OBJ_id_smime_ct,5L
+
+#define SN_id_smime_ct_contentInfo		"id-smime-ct-contentInfo"
+#define NID_id_smime_ct_contentInfo		209
+#define OBJ_id_smime_ct_contentInfo		OBJ_id_smime_ct,6L
+
+#define SN_id_smime_ct_DVCSRequestData		"id-smime-ct-DVCSRequestData"
+#define NID_id_smime_ct_DVCSRequestData		210
+#define OBJ_id_smime_ct_DVCSRequestData		OBJ_id_smime_ct,7L
+
+#define SN_id_smime_ct_DVCSResponseData		"id-smime-ct-DVCSResponseData"
+#define NID_id_smime_ct_DVCSResponseData		211
+#define OBJ_id_smime_ct_DVCSResponseData		OBJ_id_smime_ct,8L
+
+#define SN_id_smime_ct_compressedData		"id-smime-ct-compressedData"
+#define NID_id_smime_ct_compressedData		786
+#define OBJ_id_smime_ct_compressedData		OBJ_id_smime_ct,9L
+
+#define SN_id_ct_asciiTextWithCRLF		"id-ct-asciiTextWithCRLF"
+#define NID_id_ct_asciiTextWithCRLF		787
+#define OBJ_id_ct_asciiTextWithCRLF		OBJ_id_smime_ct,27L
+
+#define SN_id_smime_aa_receiptRequest		"id-smime-aa-receiptRequest"
+#define NID_id_smime_aa_receiptRequest		212
+#define OBJ_id_smime_aa_receiptRequest		OBJ_id_smime_aa,1L
+
+#define SN_id_smime_aa_securityLabel		"id-smime-aa-securityLabel"
+#define NID_id_smime_aa_securityLabel		213
+#define OBJ_id_smime_aa_securityLabel		OBJ_id_smime_aa,2L
+
+#define SN_id_smime_aa_mlExpandHistory		"id-smime-aa-mlExpandHistory"
+#define NID_id_smime_aa_mlExpandHistory		214
+#define OBJ_id_smime_aa_mlExpandHistory		OBJ_id_smime_aa,3L
+
+#define SN_id_smime_aa_contentHint		"id-smime-aa-contentHint"
+#define NID_id_smime_aa_contentHint		215
+#define OBJ_id_smime_aa_contentHint		OBJ_id_smime_aa,4L
+
+#define SN_id_smime_aa_msgSigDigest		"id-smime-aa-msgSigDigest"
+#define NID_id_smime_aa_msgSigDigest		216
+#define OBJ_id_smime_aa_msgSigDigest		OBJ_id_smime_aa,5L
+
+#define SN_id_smime_aa_encapContentType		"id-smime-aa-encapContentType"
+#define NID_id_smime_aa_encapContentType		217
+#define OBJ_id_smime_aa_encapContentType		OBJ_id_smime_aa,6L
+
+#define SN_id_smime_aa_contentIdentifier		"id-smime-aa-contentIdentifier"
+#define NID_id_smime_aa_contentIdentifier		218
+#define OBJ_id_smime_aa_contentIdentifier		OBJ_id_smime_aa,7L
+
+#define SN_id_smime_aa_macValue		"id-smime-aa-macValue"
+#define NID_id_smime_aa_macValue		219
+#define OBJ_id_smime_aa_macValue		OBJ_id_smime_aa,8L
+
+#define SN_id_smime_aa_equivalentLabels		"id-smime-aa-equivalentLabels"
+#define NID_id_smime_aa_equivalentLabels		220
+#define OBJ_id_smime_aa_equivalentLabels		OBJ_id_smime_aa,9L
+
+#define SN_id_smime_aa_contentReference		"id-smime-aa-contentReference"
+#define NID_id_smime_aa_contentReference		221
+#define OBJ_id_smime_aa_contentReference		OBJ_id_smime_aa,10L
+
+#define SN_id_smime_aa_encrypKeyPref		"id-smime-aa-encrypKeyPref"
+#define NID_id_smime_aa_encrypKeyPref		222
+#define OBJ_id_smime_aa_encrypKeyPref		OBJ_id_smime_aa,11L
+
+#define SN_id_smime_aa_signingCertificate		"id-smime-aa-signingCertificate"
+#define NID_id_smime_aa_signingCertificate		223
+#define OBJ_id_smime_aa_signingCertificate		OBJ_id_smime_aa,12L
+
+#define SN_id_smime_aa_smimeEncryptCerts		"id-smime-aa-smimeEncryptCerts"
+#define NID_id_smime_aa_smimeEncryptCerts		224
+#define OBJ_id_smime_aa_smimeEncryptCerts		OBJ_id_smime_aa,13L
+
+#define SN_id_smime_aa_timeStampToken		"id-smime-aa-timeStampToken"
+#define NID_id_smime_aa_timeStampToken		225
+#define OBJ_id_smime_aa_timeStampToken		OBJ_id_smime_aa,14L
+
+#define SN_id_smime_aa_ets_sigPolicyId		"id-smime-aa-ets-sigPolicyId"
+#define NID_id_smime_aa_ets_sigPolicyId		226
+#define OBJ_id_smime_aa_ets_sigPolicyId		OBJ_id_smime_aa,15L
+
+#define SN_id_smime_aa_ets_commitmentType		"id-smime-aa-ets-commitmentType"
+#define NID_id_smime_aa_ets_commitmentType		227
+#define OBJ_id_smime_aa_ets_commitmentType		OBJ_id_smime_aa,16L
+
+#define SN_id_smime_aa_ets_signerLocation		"id-smime-aa-ets-signerLocation"
+#define NID_id_smime_aa_ets_signerLocation		228
+#define OBJ_id_smime_aa_ets_signerLocation		OBJ_id_smime_aa,17L
+
+#define SN_id_smime_aa_ets_signerAttr		"id-smime-aa-ets-signerAttr"
+#define NID_id_smime_aa_ets_signerAttr		229
+#define OBJ_id_smime_aa_ets_signerAttr		OBJ_id_smime_aa,18L
+
+#define SN_id_smime_aa_ets_otherSigCert		"id-smime-aa-ets-otherSigCert"
+#define NID_id_smime_aa_ets_otherSigCert		230
+#define OBJ_id_smime_aa_ets_otherSigCert		OBJ_id_smime_aa,19L
+
+#define SN_id_smime_aa_ets_contentTimestamp		"id-smime-aa-ets-contentTimestamp"
+#define NID_id_smime_aa_ets_contentTimestamp		231
+#define OBJ_id_smime_aa_ets_contentTimestamp		OBJ_id_smime_aa,20L
+
+#define SN_id_smime_aa_ets_CertificateRefs		"id-smime-aa-ets-CertificateRefs"
+#define NID_id_smime_aa_ets_CertificateRefs		232
+#define OBJ_id_smime_aa_ets_CertificateRefs		OBJ_id_smime_aa,21L
+
+#define SN_id_smime_aa_ets_RevocationRefs		"id-smime-aa-ets-RevocationRefs"
+#define NID_id_smime_aa_ets_RevocationRefs		233
+#define OBJ_id_smime_aa_ets_RevocationRefs		OBJ_id_smime_aa,22L
+
+#define SN_id_smime_aa_ets_certValues		"id-smime-aa-ets-certValues"
+#define NID_id_smime_aa_ets_certValues		234
+#define OBJ_id_smime_aa_ets_certValues		OBJ_id_smime_aa,23L
+
+#define SN_id_smime_aa_ets_revocationValues		"id-smime-aa-ets-revocationValues"
+#define NID_id_smime_aa_ets_revocationValues		235
+#define OBJ_id_smime_aa_ets_revocationValues		OBJ_id_smime_aa,24L
+
+#define SN_id_smime_aa_ets_escTimeStamp		"id-smime-aa-ets-escTimeStamp"
+#define NID_id_smime_aa_ets_escTimeStamp		236
+#define OBJ_id_smime_aa_ets_escTimeStamp		OBJ_id_smime_aa,25L
+
+#define SN_id_smime_aa_ets_certCRLTimestamp		"id-smime-aa-ets-certCRLTimestamp"
+#define NID_id_smime_aa_ets_certCRLTimestamp		237
+#define OBJ_id_smime_aa_ets_certCRLTimestamp		OBJ_id_smime_aa,26L
+
+#define SN_id_smime_aa_ets_archiveTimeStamp		"id-smime-aa-ets-archiveTimeStamp"
+#define NID_id_smime_aa_ets_archiveTimeStamp		238
+#define OBJ_id_smime_aa_ets_archiveTimeStamp		OBJ_id_smime_aa,27L
+
+#define SN_id_smime_aa_signatureType		"id-smime-aa-signatureType"
+#define NID_id_smime_aa_signatureType		239
+#define OBJ_id_smime_aa_signatureType		OBJ_id_smime_aa,28L
+
+#define SN_id_smime_aa_dvcs_dvc		"id-smime-aa-dvcs-dvc"
+#define NID_id_smime_aa_dvcs_dvc		240
+#define OBJ_id_smime_aa_dvcs_dvc		OBJ_id_smime_aa,29L
+
+#define SN_id_smime_alg_ESDHwith3DES		"id-smime-alg-ESDHwith3DES"
+#define NID_id_smime_alg_ESDHwith3DES		241
+#define OBJ_id_smime_alg_ESDHwith3DES		OBJ_id_smime_alg,1L
+
+#define SN_id_smime_alg_ESDHwithRC2		"id-smime-alg-ESDHwithRC2"
+#define NID_id_smime_alg_ESDHwithRC2		242
+#define OBJ_id_smime_alg_ESDHwithRC2		OBJ_id_smime_alg,2L
+
+#define SN_id_smime_alg_3DESwrap		"id-smime-alg-3DESwrap"
+#define NID_id_smime_alg_3DESwrap		243
+#define OBJ_id_smime_alg_3DESwrap		OBJ_id_smime_alg,3L
+
+#define SN_id_smime_alg_RC2wrap		"id-smime-alg-RC2wrap"
+#define NID_id_smime_alg_RC2wrap		244
+#define OBJ_id_smime_alg_RC2wrap		OBJ_id_smime_alg,4L
+
+#define SN_id_smime_alg_ESDH		"id-smime-alg-ESDH"
+#define NID_id_smime_alg_ESDH		245
+#define OBJ_id_smime_alg_ESDH		OBJ_id_smime_alg,5L
+
+#define SN_id_smime_alg_CMS3DESwrap		"id-smime-alg-CMS3DESwrap"
+#define NID_id_smime_alg_CMS3DESwrap		246
+#define OBJ_id_smime_alg_CMS3DESwrap		OBJ_id_smime_alg,6L
+
+#define SN_id_smime_alg_CMSRC2wrap		"id-smime-alg-CMSRC2wrap"
+#define NID_id_smime_alg_CMSRC2wrap		247
+#define OBJ_id_smime_alg_CMSRC2wrap		OBJ_id_smime_alg,7L
+
+#define SN_id_smime_cd_ldap		"id-smime-cd-ldap"
+#define NID_id_smime_cd_ldap		248
+#define OBJ_id_smime_cd_ldap		OBJ_id_smime_cd,1L
+
+#define SN_id_smime_spq_ets_sqt_uri		"id-smime-spq-ets-sqt-uri"
+#define NID_id_smime_spq_ets_sqt_uri		249
+#define OBJ_id_smime_spq_ets_sqt_uri		OBJ_id_smime_spq,1L
+
+#define SN_id_smime_spq_ets_sqt_unotice		"id-smime-spq-ets-sqt-unotice"
+#define NID_id_smime_spq_ets_sqt_unotice		250
+#define OBJ_id_smime_spq_ets_sqt_unotice		OBJ_id_smime_spq,2L
+
+#define SN_id_smime_cti_ets_proofOfOrigin		"id-smime-cti-ets-proofOfOrigin"
+#define NID_id_smime_cti_ets_proofOfOrigin		251
+#define OBJ_id_smime_cti_ets_proofOfOrigin		OBJ_id_smime_cti,1L
+
+#define SN_id_smime_cti_ets_proofOfReceipt		"id-smime-cti-ets-proofOfReceipt"
+#define NID_id_smime_cti_ets_proofOfReceipt		252
+#define OBJ_id_smime_cti_ets_proofOfReceipt		OBJ_id_smime_cti,2L
+
+#define SN_id_smime_cti_ets_proofOfDelivery		"id-smime-cti-ets-proofOfDelivery"
+#define NID_id_smime_cti_ets_proofOfDelivery		253
+#define OBJ_id_smime_cti_ets_proofOfDelivery		OBJ_id_smime_cti,3L
+
+#define SN_id_smime_cti_ets_proofOfSender		"id-smime-cti-ets-proofOfSender"
+#define NID_id_smime_cti_ets_proofOfSender		254
+#define OBJ_id_smime_cti_ets_proofOfSender		OBJ_id_smime_cti,4L
+
+#define SN_id_smime_cti_ets_proofOfApproval		"id-smime-cti-ets-proofOfApproval"
+#define NID_id_smime_cti_ets_proofOfApproval		255
+#define OBJ_id_smime_cti_ets_proofOfApproval		OBJ_id_smime_cti,5L
+
+#define SN_id_smime_cti_ets_proofOfCreation		"id-smime-cti-ets-proofOfCreation"
+#define NID_id_smime_cti_ets_proofOfCreation		256
+#define OBJ_id_smime_cti_ets_proofOfCreation		OBJ_id_smime_cti,6L
+
+#define LN_friendlyName		"friendlyName"
+#define NID_friendlyName		156
+#define OBJ_friendlyName		OBJ_pkcs9,20L
+
+#define LN_localKeyID		"localKeyID"
+#define NID_localKeyID		157
+#define OBJ_localKeyID		OBJ_pkcs9,21L
+
+#define SN_ms_csp_name		"CSPName"
+#define LN_ms_csp_name		"Microsoft CSP Name"
+#define NID_ms_csp_name		417
+#define OBJ_ms_csp_name		1L,3L,6L,1L,4L,1L,311L,17L,1L
+
+#define SN_LocalKeySet		"LocalKeySet"
+#define LN_LocalKeySet		"Microsoft Local Key set"
+#define NID_LocalKeySet		856
+#define OBJ_LocalKeySet		1L,3L,6L,1L,4L,1L,311L,17L,2L
+
+#define OBJ_certTypes		OBJ_pkcs9,22L
+
+#define LN_x509Certificate		"x509Certificate"
+#define NID_x509Certificate		158
+#define OBJ_x509Certificate		OBJ_certTypes,1L
+
+#define LN_sdsiCertificate		"sdsiCertificate"
+#define NID_sdsiCertificate		159
+#define OBJ_sdsiCertificate		OBJ_certTypes,2L
+
+#define OBJ_crlTypes		OBJ_pkcs9,23L
+
+#define LN_x509Crl		"x509Crl"
+#define NID_x509Crl		160
+#define OBJ_x509Crl		OBJ_crlTypes,1L
+
+#define OBJ_pkcs12		OBJ_pkcs,12L
+
+#define OBJ_pkcs12_pbeids		OBJ_pkcs12,1L
+
+#define SN_pbe_WithSHA1And128BitRC4		"PBE-SHA1-RC4-128"
+#define LN_pbe_WithSHA1And128BitRC4		"pbeWithSHA1And128BitRC4"
+#define NID_pbe_WithSHA1And128BitRC4		144
+#define OBJ_pbe_WithSHA1And128BitRC4		OBJ_pkcs12_pbeids,1L
+
+#define SN_pbe_WithSHA1And40BitRC4		"PBE-SHA1-RC4-40"
+#define LN_pbe_WithSHA1And40BitRC4		"pbeWithSHA1And40BitRC4"
+#define NID_pbe_WithSHA1And40BitRC4		145
+#define OBJ_pbe_WithSHA1And40BitRC4		OBJ_pkcs12_pbeids,2L
+
+#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC		"PBE-SHA1-3DES"
+#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC		"pbeWithSHA1And3-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC		146
+#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC		OBJ_pkcs12_pbeids,3L
+
+#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC		"PBE-SHA1-2DES"
+#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC		"pbeWithSHA1And2-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC		147
+#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC		OBJ_pkcs12_pbeids,4L
+
+#define SN_pbe_WithSHA1And128BitRC2_CBC		"PBE-SHA1-RC2-128"
+#define LN_pbe_WithSHA1And128BitRC2_CBC		"pbeWithSHA1And128BitRC2-CBC"
+#define NID_pbe_WithSHA1And128BitRC2_CBC		148
+#define OBJ_pbe_WithSHA1And128BitRC2_CBC		OBJ_pkcs12_pbeids,5L
+
+#define SN_pbe_WithSHA1And40BitRC2_CBC		"PBE-SHA1-RC2-40"
+#define LN_pbe_WithSHA1And40BitRC2_CBC		"pbeWithSHA1And40BitRC2-CBC"
+#define NID_pbe_WithSHA1And40BitRC2_CBC		149
+#define OBJ_pbe_WithSHA1And40BitRC2_CBC		OBJ_pkcs12_pbeids,6L
+
+#define OBJ_pkcs12_Version1		OBJ_pkcs12,10L
+
+#define OBJ_pkcs12_BagIds		OBJ_pkcs12_Version1,1L
+
+#define LN_keyBag		"keyBag"
+#define NID_keyBag		150
+#define OBJ_keyBag		OBJ_pkcs12_BagIds,1L
+
+#define LN_pkcs8ShroudedKeyBag		"pkcs8ShroudedKeyBag"
+#define NID_pkcs8ShroudedKeyBag		151
+#define OBJ_pkcs8ShroudedKeyBag		OBJ_pkcs12_BagIds,2L
+
+#define LN_certBag		"certBag"
+#define NID_certBag		152
+#define OBJ_certBag		OBJ_pkcs12_BagIds,3L
+
+#define LN_crlBag		"crlBag"
+#define NID_crlBag		153
+#define OBJ_crlBag		OBJ_pkcs12_BagIds,4L
+
+#define LN_secretBag		"secretBag"
+#define NID_secretBag		154
+#define OBJ_secretBag		OBJ_pkcs12_BagIds,5L
+
+#define LN_safeContentsBag		"safeContentsBag"
+#define NID_safeContentsBag		155
+#define OBJ_safeContentsBag		OBJ_pkcs12_BagIds,6L
+
+#define SN_md2		"MD2"
+#define LN_md2		"md2"
+#define NID_md2		3
+#define OBJ_md2		OBJ_rsadsi,2L,2L
+
+#define SN_md4		"MD4"
+#define LN_md4		"md4"
+#define NID_md4		257
+#define OBJ_md4		OBJ_rsadsi,2L,4L
+
+#define SN_md5		"MD5"
+#define LN_md5		"md5"
+#define NID_md5		4
+#define OBJ_md5		OBJ_rsadsi,2L,5L
+
+#define SN_md5_sha1		"MD5-SHA1"
+#define LN_md5_sha1		"md5-sha1"
+#define NID_md5_sha1		114
+
+#define LN_hmacWithMD5		"hmacWithMD5"
+#define NID_hmacWithMD5		797
+#define OBJ_hmacWithMD5		OBJ_rsadsi,2L,6L
+
+#define LN_hmacWithSHA1		"hmacWithSHA1"
+#define NID_hmacWithSHA1		163
+#define OBJ_hmacWithSHA1		OBJ_rsadsi,2L,7L
+
+#define LN_hmacWithSHA224		"hmacWithSHA224"
+#define NID_hmacWithSHA224		798
+#define OBJ_hmacWithSHA224		OBJ_rsadsi,2L,8L
+
+#define LN_hmacWithSHA256		"hmacWithSHA256"
+#define NID_hmacWithSHA256		799
+#define OBJ_hmacWithSHA256		OBJ_rsadsi,2L,9L
+
+#define LN_hmacWithSHA384		"hmacWithSHA384"
+#define NID_hmacWithSHA384		800
+#define OBJ_hmacWithSHA384		OBJ_rsadsi,2L,10L
+
+#define LN_hmacWithSHA512		"hmacWithSHA512"
+#define NID_hmacWithSHA512		801
+#define OBJ_hmacWithSHA512		OBJ_rsadsi,2L,11L
+
+#define SN_rc2_cbc		"RC2-CBC"
+#define LN_rc2_cbc		"rc2-cbc"
+#define NID_rc2_cbc		37
+#define OBJ_rc2_cbc		OBJ_rsadsi,3L,2L
+
+#define SN_rc2_ecb		"RC2-ECB"
+#define LN_rc2_ecb		"rc2-ecb"
+#define NID_rc2_ecb		38
+
+#define SN_rc2_cfb64		"RC2-CFB"
+#define LN_rc2_cfb64		"rc2-cfb"
+#define NID_rc2_cfb64		39
+
+#define SN_rc2_ofb64		"RC2-OFB"
+#define LN_rc2_ofb64		"rc2-ofb"
+#define NID_rc2_ofb64		40
+
+#define SN_rc2_40_cbc		"RC2-40-CBC"
+#define LN_rc2_40_cbc		"rc2-40-cbc"
+#define NID_rc2_40_cbc		98
+
+#define SN_rc2_64_cbc		"RC2-64-CBC"
+#define LN_rc2_64_cbc		"rc2-64-cbc"
+#define NID_rc2_64_cbc		166
+
+#define SN_rc4		"RC4"
+#define LN_rc4		"rc4"
+#define NID_rc4		5
+#define OBJ_rc4		OBJ_rsadsi,3L,4L
+
+#define SN_rc4_40		"RC4-40"
+#define LN_rc4_40		"rc4-40"
+#define NID_rc4_40		97
+
+#define SN_des_ede3_cbc		"DES-EDE3-CBC"
+#define LN_des_ede3_cbc		"des-ede3-cbc"
+#define NID_des_ede3_cbc		44
+#define OBJ_des_ede3_cbc		OBJ_rsadsi,3L,7L
+
+#define SN_rc5_cbc		"RC5-CBC"
+#define LN_rc5_cbc		"rc5-cbc"
+#define NID_rc5_cbc		120
+#define OBJ_rc5_cbc		OBJ_rsadsi,3L,8L
+
+#define SN_rc5_ecb		"RC5-ECB"
+#define LN_rc5_ecb		"rc5-ecb"
+#define NID_rc5_ecb		121
+
+#define SN_rc5_cfb64		"RC5-CFB"
+#define LN_rc5_cfb64		"rc5-cfb"
+#define NID_rc5_cfb64		122
+
+#define SN_rc5_ofb64		"RC5-OFB"
+#define LN_rc5_ofb64		"rc5-ofb"
+#define NID_rc5_ofb64		123
+
+#define SN_ms_ext_req		"msExtReq"
+#define LN_ms_ext_req		"Microsoft Extension Request"
+#define NID_ms_ext_req		171
+#define OBJ_ms_ext_req		1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+#define SN_ms_code_ind		"msCodeInd"
+#define LN_ms_code_ind		"Microsoft Individual Code Signing"
+#define NID_ms_code_ind		134
+#define OBJ_ms_code_ind		1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
+
+#define SN_ms_code_com		"msCodeCom"
+#define LN_ms_code_com		"Microsoft Commercial Code Signing"
+#define NID_ms_code_com		135
+#define OBJ_ms_code_com		1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
+
+#define SN_ms_ctl_sign		"msCTLSign"
+#define LN_ms_ctl_sign		"Microsoft Trust List Signing"
+#define NID_ms_ctl_sign		136
+#define OBJ_ms_ctl_sign		1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
+
+#define SN_ms_sgc		"msSGC"
+#define LN_ms_sgc		"Microsoft Server Gated Crypto"
+#define NID_ms_sgc		137
+#define OBJ_ms_sgc		1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
+
+#define SN_ms_efs		"msEFS"
+#define LN_ms_efs		"Microsoft Encrypted File System"
+#define NID_ms_efs		138
+#define OBJ_ms_efs		1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
+
+#define SN_ms_smartcard_login		"msSmartcardLogin"
+#define LN_ms_smartcard_login		"Microsoft Smartcardlogin"
+#define NID_ms_smartcard_login		648
+#define OBJ_ms_smartcard_login		1L,3L,6L,1L,4L,1L,311L,20L,2L,2L
+
+#define SN_ms_upn		"msUPN"
+#define LN_ms_upn		"Microsoft Universal Principal Name"
+#define NID_ms_upn		649
+#define OBJ_ms_upn		1L,3L,6L,1L,4L,1L,311L,20L,2L,3L
+
+#define SN_idea_cbc		"IDEA-CBC"
+#define LN_idea_cbc		"idea-cbc"
+#define NID_idea_cbc		34
+#define OBJ_idea_cbc		1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
+
+#define SN_idea_ecb		"IDEA-ECB"
+#define LN_idea_ecb		"idea-ecb"
+#define NID_idea_ecb		36
+
+#define SN_idea_cfb64		"IDEA-CFB"
+#define LN_idea_cfb64		"idea-cfb"
+#define NID_idea_cfb64		35
+
+#define SN_idea_ofb64		"IDEA-OFB"
+#define LN_idea_ofb64		"idea-ofb"
+#define NID_idea_ofb64		46
+
+#define SN_bf_cbc		"BF-CBC"
+#define LN_bf_cbc		"bf-cbc"
+#define NID_bf_cbc		91
+#define OBJ_bf_cbc		1L,3L,6L,1L,4L,1L,3029L,1L,2L
+
+#define SN_bf_ecb		"BF-ECB"
+#define LN_bf_ecb		"bf-ecb"
+#define NID_bf_ecb		92
+
+#define SN_bf_cfb64		"BF-CFB"
+#define LN_bf_cfb64		"bf-cfb"
+#define NID_bf_cfb64		93
+
+#define SN_bf_ofb64		"BF-OFB"
+#define LN_bf_ofb64		"bf-ofb"
+#define NID_bf_ofb64		94
+
+#define SN_id_pkix		"PKIX"
+#define NID_id_pkix		127
+#define OBJ_id_pkix		1L,3L,6L,1L,5L,5L,7L
+
+#define SN_id_pkix_mod		"id-pkix-mod"
+#define NID_id_pkix_mod		258
+#define OBJ_id_pkix_mod		OBJ_id_pkix,0L
+
+#define SN_id_pe		"id-pe"
+#define NID_id_pe		175
+#define OBJ_id_pe		OBJ_id_pkix,1L
+
+#define SN_id_qt		"id-qt"
+#define NID_id_qt		259
+#define OBJ_id_qt		OBJ_id_pkix,2L
+
+#define SN_id_kp		"id-kp"
+#define NID_id_kp		128
+#define OBJ_id_kp		OBJ_id_pkix,3L
+
+#define SN_id_it		"id-it"
+#define NID_id_it		260
+#define OBJ_id_it		OBJ_id_pkix,4L
+
+#define SN_id_pkip		"id-pkip"
+#define NID_id_pkip		261
+#define OBJ_id_pkip		OBJ_id_pkix,5L
+
+#define SN_id_alg		"id-alg"
+#define NID_id_alg		262
+#define OBJ_id_alg		OBJ_id_pkix,6L
+
+#define SN_id_cmc		"id-cmc"
+#define NID_id_cmc		263
+#define OBJ_id_cmc		OBJ_id_pkix,7L
+
+#define SN_id_on		"id-on"
+#define NID_id_on		264
+#define OBJ_id_on		OBJ_id_pkix,8L
+
+#define SN_id_pda		"id-pda"
+#define NID_id_pda		265
+#define OBJ_id_pda		OBJ_id_pkix,9L
+
+#define SN_id_aca		"id-aca"
+#define NID_id_aca		266
+#define OBJ_id_aca		OBJ_id_pkix,10L
+
+#define SN_id_qcs		"id-qcs"
+#define NID_id_qcs		267
+#define OBJ_id_qcs		OBJ_id_pkix,11L
+
+#define SN_id_cct		"id-cct"
+#define NID_id_cct		268
+#define OBJ_id_cct		OBJ_id_pkix,12L
+
+#define SN_id_ppl		"id-ppl"
+#define NID_id_ppl		662
+#define OBJ_id_ppl		OBJ_id_pkix,21L
+
+#define SN_id_ad		"id-ad"
+#define NID_id_ad		176
+#define OBJ_id_ad		OBJ_id_pkix,48L
+
+#define SN_id_pkix1_explicit_88		"id-pkix1-explicit-88"
+#define NID_id_pkix1_explicit_88		269
+#define OBJ_id_pkix1_explicit_88		OBJ_id_pkix_mod,1L
+
+#define SN_id_pkix1_implicit_88		"id-pkix1-implicit-88"
+#define NID_id_pkix1_implicit_88		270
+#define OBJ_id_pkix1_implicit_88		OBJ_id_pkix_mod,2L
+
+#define SN_id_pkix1_explicit_93		"id-pkix1-explicit-93"
+#define NID_id_pkix1_explicit_93		271
+#define OBJ_id_pkix1_explicit_93		OBJ_id_pkix_mod,3L
+
+#define SN_id_pkix1_implicit_93		"id-pkix1-implicit-93"
+#define NID_id_pkix1_implicit_93		272
+#define OBJ_id_pkix1_implicit_93		OBJ_id_pkix_mod,4L
+
+#define SN_id_mod_crmf		"id-mod-crmf"
+#define NID_id_mod_crmf		273
+#define OBJ_id_mod_crmf		OBJ_id_pkix_mod,5L
+
+#define SN_id_mod_cmc		"id-mod-cmc"
+#define NID_id_mod_cmc		274
+#define OBJ_id_mod_cmc		OBJ_id_pkix_mod,6L
+
+#define SN_id_mod_kea_profile_88		"id-mod-kea-profile-88"
+#define NID_id_mod_kea_profile_88		275
+#define OBJ_id_mod_kea_profile_88		OBJ_id_pkix_mod,7L
+
+#define SN_id_mod_kea_profile_93		"id-mod-kea-profile-93"
+#define NID_id_mod_kea_profile_93		276
+#define OBJ_id_mod_kea_profile_93		OBJ_id_pkix_mod,8L
+
+#define SN_id_mod_cmp		"id-mod-cmp"
+#define NID_id_mod_cmp		277
+#define OBJ_id_mod_cmp		OBJ_id_pkix_mod,9L
+
+#define SN_id_mod_qualified_cert_88		"id-mod-qualified-cert-88"
+#define NID_id_mod_qualified_cert_88		278
+#define OBJ_id_mod_qualified_cert_88		OBJ_id_pkix_mod,10L
+
+#define SN_id_mod_qualified_cert_93		"id-mod-qualified-cert-93"
+#define NID_id_mod_qualified_cert_93		279
+#define OBJ_id_mod_qualified_cert_93		OBJ_id_pkix_mod,11L
+
+#define SN_id_mod_attribute_cert		"id-mod-attribute-cert"
+#define NID_id_mod_attribute_cert		280
+#define OBJ_id_mod_attribute_cert		OBJ_id_pkix_mod,12L
+
+#define SN_id_mod_timestamp_protocol		"id-mod-timestamp-protocol"
+#define NID_id_mod_timestamp_protocol		281
+#define OBJ_id_mod_timestamp_protocol		OBJ_id_pkix_mod,13L
+
+#define SN_id_mod_ocsp		"id-mod-ocsp"
+#define NID_id_mod_ocsp		282
+#define OBJ_id_mod_ocsp		OBJ_id_pkix_mod,14L
+
+#define SN_id_mod_dvcs		"id-mod-dvcs"
+#define NID_id_mod_dvcs		283
+#define OBJ_id_mod_dvcs		OBJ_id_pkix_mod,15L
+
+#define SN_id_mod_cmp2000		"id-mod-cmp2000"
+#define NID_id_mod_cmp2000		284
+#define OBJ_id_mod_cmp2000		OBJ_id_pkix_mod,16L
+
+#define SN_info_access		"authorityInfoAccess"
+#define LN_info_access		"Authority Information Access"
+#define NID_info_access		177
+#define OBJ_info_access		OBJ_id_pe,1L
+
+#define SN_biometricInfo		"biometricInfo"
+#define LN_biometricInfo		"Biometric Info"
+#define NID_biometricInfo		285
+#define OBJ_biometricInfo		OBJ_id_pe,2L
+
+#define SN_qcStatements		"qcStatements"
+#define NID_qcStatements		286
+#define OBJ_qcStatements		OBJ_id_pe,3L
+
+#define SN_ac_auditEntity		"ac-auditEntity"
+#define NID_ac_auditEntity		287
+#define OBJ_ac_auditEntity		OBJ_id_pe,4L
+
+#define SN_ac_targeting		"ac-targeting"
+#define NID_ac_targeting		288
+#define OBJ_ac_targeting		OBJ_id_pe,5L
+
+#define SN_aaControls		"aaControls"
+#define NID_aaControls		289
+#define OBJ_aaControls		OBJ_id_pe,6L
+
+#define SN_sbgp_ipAddrBlock		"sbgp-ipAddrBlock"
+#define NID_sbgp_ipAddrBlock		290
+#define OBJ_sbgp_ipAddrBlock		OBJ_id_pe,7L
+
+#define SN_sbgp_autonomousSysNum		"sbgp-autonomousSysNum"
+#define NID_sbgp_autonomousSysNum		291
+#define OBJ_sbgp_autonomousSysNum		OBJ_id_pe,8L
+
+#define SN_sbgp_routerIdentifier		"sbgp-routerIdentifier"
+#define NID_sbgp_routerIdentifier		292
+#define OBJ_sbgp_routerIdentifier		OBJ_id_pe,9L
+
+#define SN_ac_proxying		"ac-proxying"
+#define NID_ac_proxying		397
+#define OBJ_ac_proxying		OBJ_id_pe,10L
+
+#define SN_sinfo_access		"subjectInfoAccess"
+#define LN_sinfo_access		"Subject Information Access"
+#define NID_sinfo_access		398
+#define OBJ_sinfo_access		OBJ_id_pe,11L
+
+#define SN_proxyCertInfo		"proxyCertInfo"
+#define LN_proxyCertInfo		"Proxy Certificate Information"
+#define NID_proxyCertInfo		663
+#define OBJ_proxyCertInfo		OBJ_id_pe,14L
+
+#define SN_id_qt_cps		"id-qt-cps"
+#define LN_id_qt_cps		"Policy Qualifier CPS"
+#define NID_id_qt_cps		164
+#define OBJ_id_qt_cps		OBJ_id_qt,1L
+
+#define SN_id_qt_unotice		"id-qt-unotice"
+#define LN_id_qt_unotice		"Policy Qualifier User Notice"
+#define NID_id_qt_unotice		165
+#define OBJ_id_qt_unotice		OBJ_id_qt,2L
+
+#define SN_textNotice		"textNotice"
+#define NID_textNotice		293
+#define OBJ_textNotice		OBJ_id_qt,3L
+
+#define SN_server_auth		"serverAuth"
+#define LN_server_auth		"TLS Web Server Authentication"
+#define NID_server_auth		129
+#define OBJ_server_auth		OBJ_id_kp,1L
+
+#define SN_client_auth		"clientAuth"
+#define LN_client_auth		"TLS Web Client Authentication"
+#define NID_client_auth		130
+#define OBJ_client_auth		OBJ_id_kp,2L
+
+#define SN_code_sign		"codeSigning"
+#define LN_code_sign		"Code Signing"
+#define NID_code_sign		131
+#define OBJ_code_sign		OBJ_id_kp,3L
+
+#define SN_email_protect		"emailProtection"
+#define LN_email_protect		"E-mail Protection"
+#define NID_email_protect		132
+#define OBJ_email_protect		OBJ_id_kp,4L
+
+#define SN_ipsecEndSystem		"ipsecEndSystem"
+#define LN_ipsecEndSystem		"IPSec End System"
+#define NID_ipsecEndSystem		294
+#define OBJ_ipsecEndSystem		OBJ_id_kp,5L
+
+#define SN_ipsecTunnel		"ipsecTunnel"
+#define LN_ipsecTunnel		"IPSec Tunnel"
+#define NID_ipsecTunnel		295
+#define OBJ_ipsecTunnel		OBJ_id_kp,6L
+
+#define SN_ipsecUser		"ipsecUser"
+#define LN_ipsecUser		"IPSec User"
+#define NID_ipsecUser		296
+#define OBJ_ipsecUser		OBJ_id_kp,7L
+
+#define SN_time_stamp		"timeStamping"
+#define LN_time_stamp		"Time Stamping"
+#define NID_time_stamp		133
+#define OBJ_time_stamp		OBJ_id_kp,8L
+
+#define SN_OCSP_sign		"OCSPSigning"
+#define LN_OCSP_sign		"OCSP Signing"
+#define NID_OCSP_sign		180
+#define OBJ_OCSP_sign		OBJ_id_kp,9L
+
+#define SN_dvcs		"DVCS"
+#define LN_dvcs		"dvcs"
+#define NID_dvcs		297
+#define OBJ_dvcs		OBJ_id_kp,10L
+
+#define SN_id_it_caProtEncCert		"id-it-caProtEncCert"
+#define NID_id_it_caProtEncCert		298
+#define OBJ_id_it_caProtEncCert		OBJ_id_it,1L
+
+#define SN_id_it_signKeyPairTypes		"id-it-signKeyPairTypes"
+#define NID_id_it_signKeyPairTypes		299
+#define OBJ_id_it_signKeyPairTypes		OBJ_id_it,2L
+
+#define SN_id_it_encKeyPairTypes		"id-it-encKeyPairTypes"
+#define NID_id_it_encKeyPairTypes		300
+#define OBJ_id_it_encKeyPairTypes		OBJ_id_it,3L
+
+#define SN_id_it_preferredSymmAlg		"id-it-preferredSymmAlg"
+#define NID_id_it_preferredSymmAlg		301
+#define OBJ_id_it_preferredSymmAlg		OBJ_id_it,4L
+
+#define SN_id_it_caKeyUpdateInfo		"id-it-caKeyUpdateInfo"
+#define NID_id_it_caKeyUpdateInfo		302
+#define OBJ_id_it_caKeyUpdateInfo		OBJ_id_it,5L
+
+#define SN_id_it_currentCRL		"id-it-currentCRL"
+#define NID_id_it_currentCRL		303
+#define OBJ_id_it_currentCRL		OBJ_id_it,6L
+
+#define SN_id_it_unsupportedOIDs		"id-it-unsupportedOIDs"
+#define NID_id_it_unsupportedOIDs		304
+#define OBJ_id_it_unsupportedOIDs		OBJ_id_it,7L
+
+#define SN_id_it_subscriptionRequest		"id-it-subscriptionRequest"
+#define NID_id_it_subscriptionRequest		305
+#define OBJ_id_it_subscriptionRequest		OBJ_id_it,8L
+
+#define SN_id_it_subscriptionResponse		"id-it-subscriptionResponse"
+#define NID_id_it_subscriptionResponse		306
+#define OBJ_id_it_subscriptionResponse		OBJ_id_it,9L
+
+#define SN_id_it_keyPairParamReq		"id-it-keyPairParamReq"
+#define NID_id_it_keyPairParamReq		307
+#define OBJ_id_it_keyPairParamReq		OBJ_id_it,10L
+
+#define SN_id_it_keyPairParamRep		"id-it-keyPairParamRep"
+#define NID_id_it_keyPairParamRep		308
+#define OBJ_id_it_keyPairParamRep		OBJ_id_it,11L
+
+#define SN_id_it_revPassphrase		"id-it-revPassphrase"
+#define NID_id_it_revPassphrase		309
+#define OBJ_id_it_revPassphrase		OBJ_id_it,12L
+
+#define SN_id_it_implicitConfirm		"id-it-implicitConfirm"
+#define NID_id_it_implicitConfirm		310
+#define OBJ_id_it_implicitConfirm		OBJ_id_it,13L
+
+#define SN_id_it_confirmWaitTime		"id-it-confirmWaitTime"
+#define NID_id_it_confirmWaitTime		311
+#define OBJ_id_it_confirmWaitTime		OBJ_id_it,14L
+
+#define SN_id_it_origPKIMessage		"id-it-origPKIMessage"
+#define NID_id_it_origPKIMessage		312
+#define OBJ_id_it_origPKIMessage		OBJ_id_it,15L
+
+#define SN_id_it_suppLangTags		"id-it-suppLangTags"
+#define NID_id_it_suppLangTags		784
+#define OBJ_id_it_suppLangTags		OBJ_id_it,16L
+
+#define SN_id_regCtrl		"id-regCtrl"
+#define NID_id_regCtrl		313
+#define OBJ_id_regCtrl		OBJ_id_pkip,1L
+
+#define SN_id_regInfo		"id-regInfo"
+#define NID_id_regInfo		314
+#define OBJ_id_regInfo		OBJ_id_pkip,2L
+
+#define SN_id_regCtrl_regToken		"id-regCtrl-regToken"
+#define NID_id_regCtrl_regToken		315
+#define OBJ_id_regCtrl_regToken		OBJ_id_regCtrl,1L
+
+#define SN_id_regCtrl_authenticator		"id-regCtrl-authenticator"
+#define NID_id_regCtrl_authenticator		316
+#define OBJ_id_regCtrl_authenticator		OBJ_id_regCtrl,2L
+
+#define SN_id_regCtrl_pkiPublicationInfo		"id-regCtrl-pkiPublicationInfo"
+#define NID_id_regCtrl_pkiPublicationInfo		317
+#define OBJ_id_regCtrl_pkiPublicationInfo		OBJ_id_regCtrl,3L
+
+#define SN_id_regCtrl_pkiArchiveOptions		"id-regCtrl-pkiArchiveOptions"
+#define NID_id_regCtrl_pkiArchiveOptions		318
+#define OBJ_id_regCtrl_pkiArchiveOptions		OBJ_id_regCtrl,4L
+
+#define SN_id_regCtrl_oldCertID		"id-regCtrl-oldCertID"
+#define NID_id_regCtrl_oldCertID		319
+#define OBJ_id_regCtrl_oldCertID		OBJ_id_regCtrl,5L
+
+#define SN_id_regCtrl_protocolEncrKey		"id-regCtrl-protocolEncrKey"
+#define NID_id_regCtrl_protocolEncrKey		320
+#define OBJ_id_regCtrl_protocolEncrKey		OBJ_id_regCtrl,6L
+
+#define SN_id_regInfo_utf8Pairs		"id-regInfo-utf8Pairs"
+#define NID_id_regInfo_utf8Pairs		321
+#define OBJ_id_regInfo_utf8Pairs		OBJ_id_regInfo,1L
+
+#define SN_id_regInfo_certReq		"id-regInfo-certReq"
+#define NID_id_regInfo_certReq		322
+#define OBJ_id_regInfo_certReq		OBJ_id_regInfo,2L
+
+#define SN_id_alg_des40		"id-alg-des40"
+#define NID_id_alg_des40		323
+#define OBJ_id_alg_des40		OBJ_id_alg,1L
+
+#define SN_id_alg_noSignature		"id-alg-noSignature"
+#define NID_id_alg_noSignature		324
+#define OBJ_id_alg_noSignature		OBJ_id_alg,2L
+
+#define SN_id_alg_dh_sig_hmac_sha1		"id-alg-dh-sig-hmac-sha1"
+#define NID_id_alg_dh_sig_hmac_sha1		325
+#define OBJ_id_alg_dh_sig_hmac_sha1		OBJ_id_alg,3L
+
+#define SN_id_alg_dh_pop		"id-alg-dh-pop"
+#define NID_id_alg_dh_pop		326
+#define OBJ_id_alg_dh_pop		OBJ_id_alg,4L
+
+#define SN_id_cmc_statusInfo		"id-cmc-statusInfo"
+#define NID_id_cmc_statusInfo		327
+#define OBJ_id_cmc_statusInfo		OBJ_id_cmc,1L
+
+#define SN_id_cmc_identification		"id-cmc-identification"
+#define NID_id_cmc_identification		328
+#define OBJ_id_cmc_identification		OBJ_id_cmc,2L
+
+#define SN_id_cmc_identityProof		"id-cmc-identityProof"
+#define NID_id_cmc_identityProof		329
+#define OBJ_id_cmc_identityProof		OBJ_id_cmc,3L
+
+#define SN_id_cmc_dataReturn		"id-cmc-dataReturn"
+#define NID_id_cmc_dataReturn		330
+#define OBJ_id_cmc_dataReturn		OBJ_id_cmc,4L
+
+#define SN_id_cmc_transactionId		"id-cmc-transactionId"
+#define NID_id_cmc_transactionId		331
+#define OBJ_id_cmc_transactionId		OBJ_id_cmc,5L
+
+#define SN_id_cmc_senderNonce		"id-cmc-senderNonce"
+#define NID_id_cmc_senderNonce		332
+#define OBJ_id_cmc_senderNonce		OBJ_id_cmc,6L
+
+#define SN_id_cmc_recipientNonce		"id-cmc-recipientNonce"
+#define NID_id_cmc_recipientNonce		333
+#define OBJ_id_cmc_recipientNonce		OBJ_id_cmc,7L
+
+#define SN_id_cmc_addExtensions		"id-cmc-addExtensions"
+#define NID_id_cmc_addExtensions		334
+#define OBJ_id_cmc_addExtensions		OBJ_id_cmc,8L
+
+#define SN_id_cmc_encryptedPOP		"id-cmc-encryptedPOP"
+#define NID_id_cmc_encryptedPOP		335
+#define OBJ_id_cmc_encryptedPOP		OBJ_id_cmc,9L
+
+#define SN_id_cmc_decryptedPOP		"id-cmc-decryptedPOP"
+#define NID_id_cmc_decryptedPOP		336
+#define OBJ_id_cmc_decryptedPOP		OBJ_id_cmc,10L
+
+#define SN_id_cmc_lraPOPWitness		"id-cmc-lraPOPWitness"
+#define NID_id_cmc_lraPOPWitness		337
+#define OBJ_id_cmc_lraPOPWitness		OBJ_id_cmc,11L
+
+#define SN_id_cmc_getCert		"id-cmc-getCert"
+#define NID_id_cmc_getCert		338
+#define OBJ_id_cmc_getCert		OBJ_id_cmc,15L
+
+#define SN_id_cmc_getCRL		"id-cmc-getCRL"
+#define NID_id_cmc_getCRL		339
+#define OBJ_id_cmc_getCRL		OBJ_id_cmc,16L
+
+#define SN_id_cmc_revokeRequest		"id-cmc-revokeRequest"
+#define NID_id_cmc_revokeRequest		340
+#define OBJ_id_cmc_revokeRequest		OBJ_id_cmc,17L
+
+#define SN_id_cmc_regInfo		"id-cmc-regInfo"
+#define NID_id_cmc_regInfo		341
+#define OBJ_id_cmc_regInfo		OBJ_id_cmc,18L
+
+#define SN_id_cmc_responseInfo		"id-cmc-responseInfo"
+#define NID_id_cmc_responseInfo		342
+#define OBJ_id_cmc_responseInfo		OBJ_id_cmc,19L
+
+#define SN_id_cmc_queryPending		"id-cmc-queryPending"
+#define NID_id_cmc_queryPending		343
+#define OBJ_id_cmc_queryPending		OBJ_id_cmc,21L
+
+#define SN_id_cmc_popLinkRandom		"id-cmc-popLinkRandom"
+#define NID_id_cmc_popLinkRandom		344
+#define OBJ_id_cmc_popLinkRandom		OBJ_id_cmc,22L
+
+#define SN_id_cmc_popLinkWitness		"id-cmc-popLinkWitness"
+#define NID_id_cmc_popLinkWitness		345
+#define OBJ_id_cmc_popLinkWitness		OBJ_id_cmc,23L
+
+#define SN_id_cmc_confirmCertAcceptance		"id-cmc-confirmCertAcceptance"
+#define NID_id_cmc_confirmCertAcceptance		346
+#define OBJ_id_cmc_confirmCertAcceptance		OBJ_id_cmc,24L
+
+#define SN_id_on_personalData		"id-on-personalData"
+#define NID_id_on_personalData		347
+#define OBJ_id_on_personalData		OBJ_id_on,1L
+
+#define SN_id_on_permanentIdentifier		"id-on-permanentIdentifier"
+#define LN_id_on_permanentIdentifier		"Permanent Identifier"
+#define NID_id_on_permanentIdentifier		858
+#define OBJ_id_on_permanentIdentifier		OBJ_id_on,3L
+
+#define SN_id_pda_dateOfBirth		"id-pda-dateOfBirth"
+#define NID_id_pda_dateOfBirth		348
+#define OBJ_id_pda_dateOfBirth		OBJ_id_pda,1L
+
+#define SN_id_pda_placeOfBirth		"id-pda-placeOfBirth"
+#define NID_id_pda_placeOfBirth		349
+#define OBJ_id_pda_placeOfBirth		OBJ_id_pda,2L
+
+#define SN_id_pda_gender		"id-pda-gender"
+#define NID_id_pda_gender		351
+#define OBJ_id_pda_gender		OBJ_id_pda,3L
+
+#define SN_id_pda_countryOfCitizenship		"id-pda-countryOfCitizenship"
+#define NID_id_pda_countryOfCitizenship		352
+#define OBJ_id_pda_countryOfCitizenship		OBJ_id_pda,4L
+
+#define SN_id_pda_countryOfResidence		"id-pda-countryOfResidence"
+#define NID_id_pda_countryOfResidence		353
+#define OBJ_id_pda_countryOfResidence		OBJ_id_pda,5L
+
+#define SN_id_aca_authenticationInfo		"id-aca-authenticationInfo"
+#define NID_id_aca_authenticationInfo		354
+#define OBJ_id_aca_authenticationInfo		OBJ_id_aca,1L
+
+#define SN_id_aca_accessIdentity		"id-aca-accessIdentity"
+#define NID_id_aca_accessIdentity		355
+#define OBJ_id_aca_accessIdentity		OBJ_id_aca,2L
+
+#define SN_id_aca_chargingIdentity		"id-aca-chargingIdentity"
+#define NID_id_aca_chargingIdentity		356
+#define OBJ_id_aca_chargingIdentity		OBJ_id_aca,3L
+
+#define SN_id_aca_group		"id-aca-group"
+#define NID_id_aca_group		357
+#define OBJ_id_aca_group		OBJ_id_aca,4L
+
+#define SN_id_aca_role		"id-aca-role"
+#define NID_id_aca_role		358
+#define OBJ_id_aca_role		OBJ_id_aca,5L
+
+#define SN_id_aca_encAttrs		"id-aca-encAttrs"
+#define NID_id_aca_encAttrs		399
+#define OBJ_id_aca_encAttrs		OBJ_id_aca,6L
+
+#define SN_id_qcs_pkixQCSyntax_v1		"id-qcs-pkixQCSyntax-v1"
+#define NID_id_qcs_pkixQCSyntax_v1		359
+#define OBJ_id_qcs_pkixQCSyntax_v1		OBJ_id_qcs,1L
+
+#define SN_id_cct_crs		"id-cct-crs"
+#define NID_id_cct_crs		360
+#define OBJ_id_cct_crs		OBJ_id_cct,1L
+
+#define SN_id_cct_PKIData		"id-cct-PKIData"
+#define NID_id_cct_PKIData		361
+#define OBJ_id_cct_PKIData		OBJ_id_cct,2L
+
+#define SN_id_cct_PKIResponse		"id-cct-PKIResponse"
+#define NID_id_cct_PKIResponse		362
+#define OBJ_id_cct_PKIResponse		OBJ_id_cct,3L
+
+#define SN_id_ppl_anyLanguage		"id-ppl-anyLanguage"
+#define LN_id_ppl_anyLanguage		"Any language"
+#define NID_id_ppl_anyLanguage		664
+#define OBJ_id_ppl_anyLanguage		OBJ_id_ppl,0L
+
+#define SN_id_ppl_inheritAll		"id-ppl-inheritAll"
+#define LN_id_ppl_inheritAll		"Inherit all"
+#define NID_id_ppl_inheritAll		665
+#define OBJ_id_ppl_inheritAll		OBJ_id_ppl,1L
+
+#define SN_Independent		"id-ppl-independent"
+#define LN_Independent		"Independent"
+#define NID_Independent		667
+#define OBJ_Independent		OBJ_id_ppl,2L
+
+#define SN_ad_OCSP		"OCSP"
+#define LN_ad_OCSP		"OCSP"
+#define NID_ad_OCSP		178
+#define OBJ_ad_OCSP		OBJ_id_ad,1L
+
+#define SN_ad_ca_issuers		"caIssuers"
+#define LN_ad_ca_issuers		"CA Issuers"
+#define NID_ad_ca_issuers		179
+#define OBJ_ad_ca_issuers		OBJ_id_ad,2L
+
+#define SN_ad_timeStamping		"ad_timestamping"
+#define LN_ad_timeStamping		"AD Time Stamping"
+#define NID_ad_timeStamping		363
+#define OBJ_ad_timeStamping		OBJ_id_ad,3L
+
+#define SN_ad_dvcs		"AD_DVCS"
+#define LN_ad_dvcs		"ad dvcs"
+#define NID_ad_dvcs		364
+#define OBJ_ad_dvcs		OBJ_id_ad,4L
+
+#define SN_caRepository		"caRepository"
+#define LN_caRepository		"CA Repository"
+#define NID_caRepository		785
+#define OBJ_caRepository		OBJ_id_ad,5L
+
+#define OBJ_id_pkix_OCSP		OBJ_ad_OCSP
+
+#define SN_id_pkix_OCSP_basic		"basicOCSPResponse"
+#define LN_id_pkix_OCSP_basic		"Basic OCSP Response"
+#define NID_id_pkix_OCSP_basic		365
+#define OBJ_id_pkix_OCSP_basic		OBJ_id_pkix_OCSP,1L
+
+#define SN_id_pkix_OCSP_Nonce		"Nonce"
+#define LN_id_pkix_OCSP_Nonce		"OCSP Nonce"
+#define NID_id_pkix_OCSP_Nonce		366
+#define OBJ_id_pkix_OCSP_Nonce		OBJ_id_pkix_OCSP,2L
+
+#define SN_id_pkix_OCSP_CrlID		"CrlID"
+#define LN_id_pkix_OCSP_CrlID		"OCSP CRL ID"
+#define NID_id_pkix_OCSP_CrlID		367
+#define OBJ_id_pkix_OCSP_CrlID		OBJ_id_pkix_OCSP,3L
+
+#define SN_id_pkix_OCSP_acceptableResponses		"acceptableResponses"
+#define LN_id_pkix_OCSP_acceptableResponses		"Acceptable OCSP Responses"
+#define NID_id_pkix_OCSP_acceptableResponses		368
+#define OBJ_id_pkix_OCSP_acceptableResponses		OBJ_id_pkix_OCSP,4L
+
+#define SN_id_pkix_OCSP_noCheck		"noCheck"
+#define LN_id_pkix_OCSP_noCheck		"OCSP No Check"
+#define NID_id_pkix_OCSP_noCheck		369
+#define OBJ_id_pkix_OCSP_noCheck		OBJ_id_pkix_OCSP,5L
+
+#define SN_id_pkix_OCSP_archiveCutoff		"archiveCutoff"
+#define LN_id_pkix_OCSP_archiveCutoff		"OCSP Archive Cutoff"
+#define NID_id_pkix_OCSP_archiveCutoff		370
+#define OBJ_id_pkix_OCSP_archiveCutoff		OBJ_id_pkix_OCSP,6L
+
+#define SN_id_pkix_OCSP_serviceLocator		"serviceLocator"
+#define LN_id_pkix_OCSP_serviceLocator		"OCSP Service Locator"
+#define NID_id_pkix_OCSP_serviceLocator		371
+#define OBJ_id_pkix_OCSP_serviceLocator		OBJ_id_pkix_OCSP,7L
+
+#define SN_id_pkix_OCSP_extendedStatus		"extendedStatus"
+#define LN_id_pkix_OCSP_extendedStatus		"Extended OCSP Status"
+#define NID_id_pkix_OCSP_extendedStatus		372
+#define OBJ_id_pkix_OCSP_extendedStatus		OBJ_id_pkix_OCSP,8L
+
+#define SN_id_pkix_OCSP_valid		"valid"
+#define NID_id_pkix_OCSP_valid		373
+#define OBJ_id_pkix_OCSP_valid		OBJ_id_pkix_OCSP,9L
+
+#define SN_id_pkix_OCSP_path		"path"
+#define NID_id_pkix_OCSP_path		374
+#define OBJ_id_pkix_OCSP_path		OBJ_id_pkix_OCSP,10L
+
+#define SN_id_pkix_OCSP_trustRoot		"trustRoot"
+#define LN_id_pkix_OCSP_trustRoot		"Trust Root"
+#define NID_id_pkix_OCSP_trustRoot		375
+#define OBJ_id_pkix_OCSP_trustRoot		OBJ_id_pkix_OCSP,11L
+
+#define SN_algorithm		"algorithm"
+#define LN_algorithm		"algorithm"
+#define NID_algorithm		376
+#define OBJ_algorithm		1L,3L,14L,3L,2L
+
+#define SN_md5WithRSA		"RSA-NP-MD5"
+#define LN_md5WithRSA		"md5WithRSA"
+#define NID_md5WithRSA		104
+#define OBJ_md5WithRSA		OBJ_algorithm,3L
+
+#define SN_des_ecb		"DES-ECB"
+#define LN_des_ecb		"des-ecb"
+#define NID_des_ecb		29
+#define OBJ_des_ecb		OBJ_algorithm,6L
+
+#define SN_des_cbc		"DES-CBC"
+#define LN_des_cbc		"des-cbc"
+#define NID_des_cbc		31
+#define OBJ_des_cbc		OBJ_algorithm,7L
+
+#define SN_des_ofb64		"DES-OFB"
+#define LN_des_ofb64		"des-ofb"
+#define NID_des_ofb64		45
+#define OBJ_des_ofb64		OBJ_algorithm,8L
+
+#define SN_des_cfb64		"DES-CFB"
+#define LN_des_cfb64		"des-cfb"
+#define NID_des_cfb64		30
+#define OBJ_des_cfb64		OBJ_algorithm,9L
+
+#define SN_rsaSignature		"rsaSignature"
+#define NID_rsaSignature		377
+#define OBJ_rsaSignature		OBJ_algorithm,11L
+
+#define SN_dsa_2		"DSA-old"
+#define LN_dsa_2		"dsaEncryption-old"
+#define NID_dsa_2		67
+#define OBJ_dsa_2		OBJ_algorithm,12L
+
+#define SN_dsaWithSHA		"DSA-SHA"
+#define LN_dsaWithSHA		"dsaWithSHA"
+#define NID_dsaWithSHA		66
+#define OBJ_dsaWithSHA		OBJ_algorithm,13L
+
+#define SN_shaWithRSAEncryption		"RSA-SHA"
+#define LN_shaWithRSAEncryption		"shaWithRSAEncryption"
+#define NID_shaWithRSAEncryption		42
+#define OBJ_shaWithRSAEncryption		OBJ_algorithm,15L
+
+#define SN_des_ede_ecb		"DES-EDE"
+#define LN_des_ede_ecb		"des-ede"
+#define NID_des_ede_ecb		32
+#define OBJ_des_ede_ecb		OBJ_algorithm,17L
+
+#define SN_des_ede3_ecb		"DES-EDE3"
+#define LN_des_ede3_ecb		"des-ede3"
+#define NID_des_ede3_ecb		33
+
+#define SN_des_ede_cbc		"DES-EDE-CBC"
+#define LN_des_ede_cbc		"des-ede-cbc"
+#define NID_des_ede_cbc		43
+
+#define SN_des_ede_cfb64		"DES-EDE-CFB"
+#define LN_des_ede_cfb64		"des-ede-cfb"
+#define NID_des_ede_cfb64		60
+
+#define SN_des_ede3_cfb64		"DES-EDE3-CFB"
+#define LN_des_ede3_cfb64		"des-ede3-cfb"
+#define NID_des_ede3_cfb64		61
+
+#define SN_des_ede_ofb64		"DES-EDE-OFB"
+#define LN_des_ede_ofb64		"des-ede-ofb"
+#define NID_des_ede_ofb64		62
+
+#define SN_des_ede3_ofb64		"DES-EDE3-OFB"
+#define LN_des_ede3_ofb64		"des-ede3-ofb"
+#define NID_des_ede3_ofb64		63
+
+#define SN_desx_cbc		"DESX-CBC"
+#define LN_desx_cbc		"desx-cbc"
+#define NID_desx_cbc		80
+
+#define SN_sha		"SHA"
+#define LN_sha		"sha"
+#define NID_sha		41
+#define OBJ_sha		OBJ_algorithm,18L
+
+#define SN_sha1		"SHA1"
+#define LN_sha1		"sha1"
+#define NID_sha1		64
+#define OBJ_sha1		OBJ_algorithm,26L
+
+#define SN_dsaWithSHA1_2		"DSA-SHA1-old"
+#define LN_dsaWithSHA1_2		"dsaWithSHA1-old"
+#define NID_dsaWithSHA1_2		70
+#define OBJ_dsaWithSHA1_2		OBJ_algorithm,27L
+
+#define SN_sha1WithRSA		"RSA-SHA1-2"
+#define LN_sha1WithRSA		"sha1WithRSA"
+#define NID_sha1WithRSA		115
+#define OBJ_sha1WithRSA		OBJ_algorithm,29L
+
+#define SN_ripemd160		"RIPEMD160"
+#define LN_ripemd160		"ripemd160"
+#define NID_ripemd160		117
+#define OBJ_ripemd160		1L,3L,36L,3L,2L,1L
+
+#define SN_ripemd160WithRSA		"RSA-RIPEMD160"
+#define LN_ripemd160WithRSA		"ripemd160WithRSA"
+#define NID_ripemd160WithRSA		119
+#define OBJ_ripemd160WithRSA		1L,3L,36L,3L,3L,1L,2L
+
+#define SN_sxnet		"SXNetID"
+#define LN_sxnet		"Strong Extranet ID"
+#define NID_sxnet		143
+#define OBJ_sxnet		1L,3L,101L,1L,4L,1L
+
+#define SN_X500		"X500"
+#define LN_X500		"directory services (X.500)"
+#define NID_X500		11
+#define OBJ_X500		2L,5L
+
+#define SN_X509		"X509"
+#define NID_X509		12
+#define OBJ_X509		OBJ_X500,4L
+
+#define SN_commonName		"CN"
+#define LN_commonName		"commonName"
+#define NID_commonName		13
+#define OBJ_commonName		OBJ_X509,3L
+
+#define SN_surname		"SN"
+#define LN_surname		"surname"
+#define NID_surname		100
+#define OBJ_surname		OBJ_X509,4L
+
+#define LN_serialNumber		"serialNumber"
+#define NID_serialNumber		105
+#define OBJ_serialNumber		OBJ_X509,5L
+
+#define SN_countryName		"C"
+#define LN_countryName		"countryName"
+#define NID_countryName		14
+#define OBJ_countryName		OBJ_X509,6L
+
+#define SN_localityName		"L"
+#define LN_localityName		"localityName"
+#define NID_localityName		15
+#define OBJ_localityName		OBJ_X509,7L
+
+#define SN_stateOrProvinceName		"ST"
+#define LN_stateOrProvinceName		"stateOrProvinceName"
+#define NID_stateOrProvinceName		16
+#define OBJ_stateOrProvinceName		OBJ_X509,8L
+
+#define SN_streetAddress		"street"
+#define LN_streetAddress		"streetAddress"
+#define NID_streetAddress		660
+#define OBJ_streetAddress		OBJ_X509,9L
+
+#define SN_organizationName		"O"
+#define LN_organizationName		"organizationName"
+#define NID_organizationName		17
+#define OBJ_organizationName		OBJ_X509,10L
+
+#define SN_organizationalUnitName		"OU"
+#define LN_organizationalUnitName		"organizationalUnitName"
+#define NID_organizationalUnitName		18
+#define OBJ_organizationalUnitName		OBJ_X509,11L
+
+#define SN_title		"title"
+#define LN_title		"title"
+#define NID_title		106
+#define OBJ_title		OBJ_X509,12L
+
+#define LN_description		"description"
+#define NID_description		107
+#define OBJ_description		OBJ_X509,13L
+
+#define LN_searchGuide		"searchGuide"
+#define NID_searchGuide		859
+#define OBJ_searchGuide		OBJ_X509,14L
+
+#define LN_businessCategory		"businessCategory"
+#define NID_businessCategory		860
+#define OBJ_businessCategory		OBJ_X509,15L
+
+#define LN_postalAddress		"postalAddress"
+#define NID_postalAddress		861
+#define OBJ_postalAddress		OBJ_X509,16L
+
+#define LN_postalCode		"postalCode"
+#define NID_postalCode		661
+#define OBJ_postalCode		OBJ_X509,17L
+
+#define LN_postOfficeBox		"postOfficeBox"
+#define NID_postOfficeBox		862
+#define OBJ_postOfficeBox		OBJ_X509,18L
+
+#define LN_physicalDeliveryOfficeName		"physicalDeliveryOfficeName"
+#define NID_physicalDeliveryOfficeName		863
+#define OBJ_physicalDeliveryOfficeName		OBJ_X509,19L
+
+#define LN_telephoneNumber		"telephoneNumber"
+#define NID_telephoneNumber		864
+#define OBJ_telephoneNumber		OBJ_X509,20L
+
+#define LN_telexNumber		"telexNumber"
+#define NID_telexNumber		865
+#define OBJ_telexNumber		OBJ_X509,21L
+
+#define LN_teletexTerminalIdentifier		"teletexTerminalIdentifier"
+#define NID_teletexTerminalIdentifier		866
+#define OBJ_teletexTerminalIdentifier		OBJ_X509,22L
+
+#define LN_facsimileTelephoneNumber		"facsimileTelephoneNumber"
+#define NID_facsimileTelephoneNumber		867
+#define OBJ_facsimileTelephoneNumber		OBJ_X509,23L
+
+#define LN_x121Address		"x121Address"
+#define NID_x121Address		868
+#define OBJ_x121Address		OBJ_X509,24L
+
+#define LN_internationaliSDNNumber		"internationaliSDNNumber"
+#define NID_internationaliSDNNumber		869
+#define OBJ_internationaliSDNNumber		OBJ_X509,25L
+
+#define LN_registeredAddress		"registeredAddress"
+#define NID_registeredAddress		870
+#define OBJ_registeredAddress		OBJ_X509,26L
+
+#define LN_destinationIndicator		"destinationIndicator"
+#define NID_destinationIndicator		871
+#define OBJ_destinationIndicator		OBJ_X509,27L
+
+#define LN_preferredDeliveryMethod		"preferredDeliveryMethod"
+#define NID_preferredDeliveryMethod		872
+#define OBJ_preferredDeliveryMethod		OBJ_X509,28L
+
+#define LN_presentationAddress		"presentationAddress"
+#define NID_presentationAddress		873
+#define OBJ_presentationAddress		OBJ_X509,29L
+
+#define LN_supportedApplicationContext		"supportedApplicationContext"
+#define NID_supportedApplicationContext		874
+#define OBJ_supportedApplicationContext		OBJ_X509,30L
+
+#define SN_member		"member"
+#define NID_member		875
+#define OBJ_member		OBJ_X509,31L
+
+#define SN_owner		"owner"
+#define NID_owner		876
+#define OBJ_owner		OBJ_X509,32L
+
+#define LN_roleOccupant		"roleOccupant"
+#define NID_roleOccupant		877
+#define OBJ_roleOccupant		OBJ_X509,33L
+
+#define SN_seeAlso		"seeAlso"
+#define NID_seeAlso		878
+#define OBJ_seeAlso		OBJ_X509,34L
+
+#define LN_userPassword		"userPassword"
+#define NID_userPassword		879
+#define OBJ_userPassword		OBJ_X509,35L
+
+#define LN_userCertificate		"userCertificate"
+#define NID_userCertificate		880
+#define OBJ_userCertificate		OBJ_X509,36L
+
+#define LN_cACertificate		"cACertificate"
+#define NID_cACertificate		881
+#define OBJ_cACertificate		OBJ_X509,37L
+
+#define LN_authorityRevocationList		"authorityRevocationList"
+#define NID_authorityRevocationList		882
+#define OBJ_authorityRevocationList		OBJ_X509,38L
+
+#define LN_certificateRevocationList		"certificateRevocationList"
+#define NID_certificateRevocationList		883
+#define OBJ_certificateRevocationList		OBJ_X509,39L
+
+#define LN_crossCertificatePair		"crossCertificatePair"
+#define NID_crossCertificatePair		884
+#define OBJ_crossCertificatePair		OBJ_X509,40L
+
+#define SN_name		"name"
+#define LN_name		"name"
+#define NID_name		173
+#define OBJ_name		OBJ_X509,41L
+
+#define SN_givenName		"GN"
+#define LN_givenName		"givenName"
+#define NID_givenName		99
+#define OBJ_givenName		OBJ_X509,42L
+
+#define SN_initials		"initials"
+#define LN_initials		"initials"
+#define NID_initials		101
+#define OBJ_initials		OBJ_X509,43L
+
+#define LN_generationQualifier		"generationQualifier"
+#define NID_generationQualifier		509
+#define OBJ_generationQualifier		OBJ_X509,44L
+
+#define LN_x500UniqueIdentifier		"x500UniqueIdentifier"
+#define NID_x500UniqueIdentifier		503
+#define OBJ_x500UniqueIdentifier		OBJ_X509,45L
+
+#define SN_dnQualifier		"dnQualifier"
+#define LN_dnQualifier		"dnQualifier"
+#define NID_dnQualifier		174
+#define OBJ_dnQualifier		OBJ_X509,46L
+
+#define LN_enhancedSearchGuide		"enhancedSearchGuide"
+#define NID_enhancedSearchGuide		885
+#define OBJ_enhancedSearchGuide		OBJ_X509,47L
+
+#define LN_protocolInformation		"protocolInformation"
+#define NID_protocolInformation		886
+#define OBJ_protocolInformation		OBJ_X509,48L
+
+#define LN_distinguishedName		"distinguishedName"
+#define NID_distinguishedName		887
+#define OBJ_distinguishedName		OBJ_X509,49L
+
+#define LN_uniqueMember		"uniqueMember"
+#define NID_uniqueMember		888
+#define OBJ_uniqueMember		OBJ_X509,50L
+
+#define LN_houseIdentifier		"houseIdentifier"
+#define NID_houseIdentifier		889
+#define OBJ_houseIdentifier		OBJ_X509,51L
+
+#define LN_supportedAlgorithms		"supportedAlgorithms"
+#define NID_supportedAlgorithms		890
+#define OBJ_supportedAlgorithms		OBJ_X509,52L
+
+#define LN_deltaRevocationList		"deltaRevocationList"
+#define NID_deltaRevocationList		891
+#define OBJ_deltaRevocationList		OBJ_X509,53L
+
+#define SN_dmdName		"dmdName"
+#define NID_dmdName		892
+#define OBJ_dmdName		OBJ_X509,54L
+
+#define LN_pseudonym		"pseudonym"
+#define NID_pseudonym		510
+#define OBJ_pseudonym		OBJ_X509,65L
+
+#define SN_role		"role"
+#define LN_role		"role"
+#define NID_role		400
+#define OBJ_role		OBJ_X509,72L
+
+#define SN_X500algorithms		"X500algorithms"
+#define LN_X500algorithms		"directory services - algorithms"
+#define NID_X500algorithms		378
+#define OBJ_X500algorithms		OBJ_X500,8L
+
+#define SN_rsa		"RSA"
+#define LN_rsa		"rsa"
+#define NID_rsa		19
+#define OBJ_rsa		OBJ_X500algorithms,1L,1L
+
+#define SN_mdc2WithRSA		"RSA-MDC2"
+#define LN_mdc2WithRSA		"mdc2WithRSA"
+#define NID_mdc2WithRSA		96
+#define OBJ_mdc2WithRSA		OBJ_X500algorithms,3L,100L
+
+#define SN_mdc2		"MDC2"
+#define LN_mdc2		"mdc2"
+#define NID_mdc2		95
+#define OBJ_mdc2		OBJ_X500algorithms,3L,101L
+
+#define SN_id_ce		"id-ce"
+#define NID_id_ce		81
+#define OBJ_id_ce		OBJ_X500,29L
+
+#define SN_subject_directory_attributes		"subjectDirectoryAttributes"
+#define LN_subject_directory_attributes		"X509v3 Subject Directory Attributes"
+#define NID_subject_directory_attributes		769
+#define OBJ_subject_directory_attributes		OBJ_id_ce,9L
+
+#define SN_subject_key_identifier		"subjectKeyIdentifier"
+#define LN_subject_key_identifier		"X509v3 Subject Key Identifier"
+#define NID_subject_key_identifier		82
+#define OBJ_subject_key_identifier		OBJ_id_ce,14L
+
+#define SN_key_usage		"keyUsage"
+#define LN_key_usage		"X509v3 Key Usage"
+#define NID_key_usage		83
+#define OBJ_key_usage		OBJ_id_ce,15L
+
+#define SN_private_key_usage_period		"privateKeyUsagePeriod"
+#define LN_private_key_usage_period		"X509v3 Private Key Usage Period"
+#define NID_private_key_usage_period		84
+#define OBJ_private_key_usage_period		OBJ_id_ce,16L
+
+#define SN_subject_alt_name		"subjectAltName"
+#define LN_subject_alt_name		"X509v3 Subject Alternative Name"
+#define NID_subject_alt_name		85
+#define OBJ_subject_alt_name		OBJ_id_ce,17L
+
+#define SN_issuer_alt_name		"issuerAltName"
+#define LN_issuer_alt_name		"X509v3 Issuer Alternative Name"
+#define NID_issuer_alt_name		86
+#define OBJ_issuer_alt_name		OBJ_id_ce,18L
+
+#define SN_basic_constraints		"basicConstraints"
+#define LN_basic_constraints		"X509v3 Basic Constraints"
+#define NID_basic_constraints		87
+#define OBJ_basic_constraints		OBJ_id_ce,19L
+
+#define SN_crl_number		"crlNumber"
+#define LN_crl_number		"X509v3 CRL Number"
+#define NID_crl_number		88
+#define OBJ_crl_number		OBJ_id_ce,20L
+
+#define SN_crl_reason		"CRLReason"
+#define LN_crl_reason		"X509v3 CRL Reason Code"
+#define NID_crl_reason		141
+#define OBJ_crl_reason		OBJ_id_ce,21L
+
+#define SN_invalidity_date		"invalidityDate"
+#define LN_invalidity_date		"Invalidity Date"
+#define NID_invalidity_date		142
+#define OBJ_invalidity_date		OBJ_id_ce,24L
+
+#define SN_delta_crl		"deltaCRL"
+#define LN_delta_crl		"X509v3 Delta CRL Indicator"
+#define NID_delta_crl		140
+#define OBJ_delta_crl		OBJ_id_ce,27L
+
+#define SN_issuing_distribution_point		"issuingDistributionPoint"
+#define LN_issuing_distribution_point		"X509v3 Issuing Distrubution Point"
+#define NID_issuing_distribution_point		770
+#define OBJ_issuing_distribution_point		OBJ_id_ce,28L
+
+#define SN_certificate_issuer		"certificateIssuer"
+#define LN_certificate_issuer		"X509v3 Certificate Issuer"
+#define NID_certificate_issuer		771
+#define OBJ_certificate_issuer		OBJ_id_ce,29L
+
+#define SN_name_constraints		"nameConstraints"
+#define LN_name_constraints		"X509v3 Name Constraints"
+#define NID_name_constraints		666
+#define OBJ_name_constraints		OBJ_id_ce,30L
+
+#define SN_crl_distribution_points		"crlDistributionPoints"
+#define LN_crl_distribution_points		"X509v3 CRL Distribution Points"
+#define NID_crl_distribution_points		103
+#define OBJ_crl_distribution_points		OBJ_id_ce,31L
+
+#define SN_certificate_policies		"certificatePolicies"
+#define LN_certificate_policies		"X509v3 Certificate Policies"
+#define NID_certificate_policies		89
+#define OBJ_certificate_policies		OBJ_id_ce,32L
+
+#define SN_any_policy		"anyPolicy"
+#define LN_any_policy		"X509v3 Any Policy"
+#define NID_any_policy		746
+#define OBJ_any_policy		OBJ_certificate_policies,0L
+
+#define SN_policy_mappings		"policyMappings"
+#define LN_policy_mappings		"X509v3 Policy Mappings"
+#define NID_policy_mappings		747
+#define OBJ_policy_mappings		OBJ_id_ce,33L
+
+#define SN_authority_key_identifier		"authorityKeyIdentifier"
+#define LN_authority_key_identifier		"X509v3 Authority Key Identifier"
+#define NID_authority_key_identifier		90
+#define OBJ_authority_key_identifier		OBJ_id_ce,35L
+
+#define SN_policy_constraints		"policyConstraints"
+#define LN_policy_constraints		"X509v3 Policy Constraints"
+#define NID_policy_constraints		401
+#define OBJ_policy_constraints		OBJ_id_ce,36L
+
+#define SN_ext_key_usage		"extendedKeyUsage"
+#define LN_ext_key_usage		"X509v3 Extended Key Usage"
+#define NID_ext_key_usage		126
+#define OBJ_ext_key_usage		OBJ_id_ce,37L
+
+#define SN_freshest_crl		"freshestCRL"
+#define LN_freshest_crl		"X509v3 Freshest CRL"
+#define NID_freshest_crl		857
+#define OBJ_freshest_crl		OBJ_id_ce,46L
+
+#define SN_inhibit_any_policy		"inhibitAnyPolicy"
+#define LN_inhibit_any_policy		"X509v3 Inhibit Any Policy"
+#define NID_inhibit_any_policy		748
+#define OBJ_inhibit_any_policy		OBJ_id_ce,54L
+
+#define SN_target_information		"targetInformation"
+#define LN_target_information		"X509v3 AC Targeting"
+#define NID_target_information		402
+#define OBJ_target_information		OBJ_id_ce,55L
+
+#define SN_no_rev_avail		"noRevAvail"
+#define LN_no_rev_avail		"X509v3 No Revocation Available"
+#define NID_no_rev_avail		403
+#define OBJ_no_rev_avail		OBJ_id_ce,56L
+
+#define SN_netscape		"Netscape"
+#define LN_netscape		"Netscape Communications Corp."
+#define NID_netscape		57
+#define OBJ_netscape		2L,16L,840L,1L,113730L
+
+#define SN_netscape_cert_extension		"nsCertExt"
+#define LN_netscape_cert_extension		"Netscape Certificate Extension"
+#define NID_netscape_cert_extension		58
+#define OBJ_netscape_cert_extension		OBJ_netscape,1L
+
+#define SN_netscape_data_type		"nsDataType"
+#define LN_netscape_data_type		"Netscape Data Type"
+#define NID_netscape_data_type		59
+#define OBJ_netscape_data_type		OBJ_netscape,2L
+
+#define SN_netscape_cert_type		"nsCertType"
+#define LN_netscape_cert_type		"Netscape Cert Type"
+#define NID_netscape_cert_type		71
+#define OBJ_netscape_cert_type		OBJ_netscape_cert_extension,1L
+
+#define SN_netscape_base_url		"nsBaseUrl"
+#define LN_netscape_base_url		"Netscape Base Url"
+#define NID_netscape_base_url		72
+#define OBJ_netscape_base_url		OBJ_netscape_cert_extension,2L
+
+#define SN_netscape_revocation_url		"nsRevocationUrl"
+#define LN_netscape_revocation_url		"Netscape Revocation Url"
+#define NID_netscape_revocation_url		73
+#define OBJ_netscape_revocation_url		OBJ_netscape_cert_extension,3L
+
+#define SN_netscape_ca_revocation_url		"nsCaRevocationUrl"
+#define LN_netscape_ca_revocation_url		"Netscape CA Revocation Url"
+#define NID_netscape_ca_revocation_url		74
+#define OBJ_netscape_ca_revocation_url		OBJ_netscape_cert_extension,4L
+
+#define SN_netscape_renewal_url		"nsRenewalUrl"
+#define LN_netscape_renewal_url		"Netscape Renewal Url"
+#define NID_netscape_renewal_url		75
+#define OBJ_netscape_renewal_url		OBJ_netscape_cert_extension,7L
+
+#define SN_netscape_ca_policy_url		"nsCaPolicyUrl"
+#define LN_netscape_ca_policy_url		"Netscape CA Policy Url"
+#define NID_netscape_ca_policy_url		76
+#define OBJ_netscape_ca_policy_url		OBJ_netscape_cert_extension,8L
+
+#define SN_netscape_ssl_server_name		"nsSslServerName"
+#define LN_netscape_ssl_server_name		"Netscape SSL Server Name"
+#define NID_netscape_ssl_server_name		77
+#define OBJ_netscape_ssl_server_name		OBJ_netscape_cert_extension,12L
+
+#define SN_netscape_comment		"nsComment"
+#define LN_netscape_comment		"Netscape Comment"
+#define NID_netscape_comment		78
+#define OBJ_netscape_comment		OBJ_netscape_cert_extension,13L
+
+#define SN_netscape_cert_sequence		"nsCertSequence"
+#define LN_netscape_cert_sequence		"Netscape Certificate Sequence"
+#define NID_netscape_cert_sequence		79
+#define OBJ_netscape_cert_sequence		OBJ_netscape_data_type,5L
+
+#define SN_ns_sgc		"nsSGC"
+#define LN_ns_sgc		"Netscape Server Gated Crypto"
+#define NID_ns_sgc		139
+#define OBJ_ns_sgc		OBJ_netscape,4L,1L
+
+#define SN_org		"ORG"
+#define LN_org		"org"
+#define NID_org		379
+#define OBJ_org		OBJ_iso,3L
+
+#define SN_dod		"DOD"
+#define LN_dod		"dod"
+#define NID_dod		380
+#define OBJ_dod		OBJ_org,6L
+
+#define SN_iana		"IANA"
+#define LN_iana		"iana"
+#define NID_iana		381
+#define OBJ_iana		OBJ_dod,1L
+
+#define OBJ_internet		OBJ_iana
+
+#define SN_Directory		"directory"
+#define LN_Directory		"Directory"
+#define NID_Directory		382
+#define OBJ_Directory		OBJ_internet,1L
+
+#define SN_Management		"mgmt"
+#define LN_Management		"Management"
+#define NID_Management		383
+#define OBJ_Management		OBJ_internet,2L
+
+#define SN_Experimental		"experimental"
+#define LN_Experimental		"Experimental"
+#define NID_Experimental		384
+#define OBJ_Experimental		OBJ_internet,3L
+
+#define SN_Private		"private"
+#define LN_Private		"Private"
+#define NID_Private		385
+#define OBJ_Private		OBJ_internet,4L
+
+#define SN_Security		"security"
+#define LN_Security		"Security"
+#define NID_Security		386
+#define OBJ_Security		OBJ_internet,5L
+
+#define SN_SNMPv2		"snmpv2"
+#define LN_SNMPv2		"SNMPv2"
+#define NID_SNMPv2		387
+#define OBJ_SNMPv2		OBJ_internet,6L
+
+#define LN_Mail		"Mail"
+#define NID_Mail		388
+#define OBJ_Mail		OBJ_internet,7L
+
+#define SN_Enterprises		"enterprises"
+#define LN_Enterprises		"Enterprises"
+#define NID_Enterprises		389
+#define OBJ_Enterprises		OBJ_Private,1L
+
+#define SN_dcObject		"dcobject"
+#define LN_dcObject		"dcObject"
+#define NID_dcObject		390
+#define OBJ_dcObject		OBJ_Enterprises,1466L,344L
+
+#define SN_mime_mhs		"mime-mhs"
+#define LN_mime_mhs		"MIME MHS"
+#define NID_mime_mhs		504
+#define OBJ_mime_mhs		OBJ_Mail,1L
+
+#define SN_mime_mhs_headings		"mime-mhs-headings"
+#define LN_mime_mhs_headings		"mime-mhs-headings"
+#define NID_mime_mhs_headings		505
+#define OBJ_mime_mhs_headings		OBJ_mime_mhs,1L
+
+#define SN_mime_mhs_bodies		"mime-mhs-bodies"
+#define LN_mime_mhs_bodies		"mime-mhs-bodies"
+#define NID_mime_mhs_bodies		506
+#define OBJ_mime_mhs_bodies		OBJ_mime_mhs,2L
+
+#define SN_id_hex_partial_message		"id-hex-partial-message"
+#define LN_id_hex_partial_message		"id-hex-partial-message"
+#define NID_id_hex_partial_message		507
+#define OBJ_id_hex_partial_message		OBJ_mime_mhs_headings,1L
+
+#define SN_id_hex_multipart_message		"id-hex-multipart-message"
+#define LN_id_hex_multipart_message		"id-hex-multipart-message"
+#define NID_id_hex_multipart_message		508
+#define OBJ_id_hex_multipart_message		OBJ_mime_mhs_headings,2L
+
+#define SN_rle_compression		"RLE"
+#define LN_rle_compression		"run length compression"
+#define NID_rle_compression		124
+#define OBJ_rle_compression		1L,1L,1L,1L,666L,1L
+
+#define SN_zlib_compression		"ZLIB"
+#define LN_zlib_compression		"zlib compression"
+#define NID_zlib_compression		125
+#define OBJ_zlib_compression		OBJ_id_smime_alg,8L
+
+#define OBJ_csor		2L,16L,840L,1L,101L,3L
+
+#define OBJ_nistAlgorithms		OBJ_csor,4L
+
+#define OBJ_aes		OBJ_nistAlgorithms,1L
+
+#define SN_aes_128_ecb		"AES-128-ECB"
+#define LN_aes_128_ecb		"aes-128-ecb"
+#define NID_aes_128_ecb		418
+#define OBJ_aes_128_ecb		OBJ_aes,1L
+
+#define SN_aes_128_cbc		"AES-128-CBC"
+#define LN_aes_128_cbc		"aes-128-cbc"
+#define NID_aes_128_cbc		419
+#define OBJ_aes_128_cbc		OBJ_aes,2L
+
+#define SN_aes_128_ofb128		"AES-128-OFB"
+#define LN_aes_128_ofb128		"aes-128-ofb"
+#define NID_aes_128_ofb128		420
+#define OBJ_aes_128_ofb128		OBJ_aes,3L
+
+#define SN_aes_128_cfb128		"AES-128-CFB"
+#define LN_aes_128_cfb128		"aes-128-cfb"
+#define NID_aes_128_cfb128		421
+#define OBJ_aes_128_cfb128		OBJ_aes,4L
+
+#define SN_aes_192_ecb		"AES-192-ECB"
+#define LN_aes_192_ecb		"aes-192-ecb"
+#define NID_aes_192_ecb		422
+#define OBJ_aes_192_ecb		OBJ_aes,21L
+
+#define SN_aes_192_cbc		"AES-192-CBC"
+#define LN_aes_192_cbc		"aes-192-cbc"
+#define NID_aes_192_cbc		423
+#define OBJ_aes_192_cbc		OBJ_aes,22L
+
+#define SN_aes_192_ofb128		"AES-192-OFB"
+#define LN_aes_192_ofb128		"aes-192-ofb"
+#define NID_aes_192_ofb128		424
+#define OBJ_aes_192_ofb128		OBJ_aes,23L
+
+#define SN_aes_192_cfb128		"AES-192-CFB"
+#define LN_aes_192_cfb128		"aes-192-cfb"
+#define NID_aes_192_cfb128		425
+#define OBJ_aes_192_cfb128		OBJ_aes,24L
+
+#define SN_aes_256_ecb		"AES-256-ECB"
+#define LN_aes_256_ecb		"aes-256-ecb"
+#define NID_aes_256_ecb		426
+#define OBJ_aes_256_ecb		OBJ_aes,41L
+
+#define SN_aes_256_cbc		"AES-256-CBC"
+#define LN_aes_256_cbc		"aes-256-cbc"
+#define NID_aes_256_cbc		427
+#define OBJ_aes_256_cbc		OBJ_aes,42L
+
+#define SN_aes_256_ofb128		"AES-256-OFB"
+#define LN_aes_256_ofb128		"aes-256-ofb"
+#define NID_aes_256_ofb128		428
+#define OBJ_aes_256_ofb128		OBJ_aes,43L
+
+#define SN_aes_256_cfb128		"AES-256-CFB"
+#define LN_aes_256_cfb128		"aes-256-cfb"
+#define NID_aes_256_cfb128		429
+#define OBJ_aes_256_cfb128		OBJ_aes,44L
+
+#define SN_aes_128_cfb1		"AES-128-CFB1"
+#define LN_aes_128_cfb1		"aes-128-cfb1"
+#define NID_aes_128_cfb1		650
+
+#define SN_aes_192_cfb1		"AES-192-CFB1"
+#define LN_aes_192_cfb1		"aes-192-cfb1"
+#define NID_aes_192_cfb1		651
+
+#define SN_aes_256_cfb1		"AES-256-CFB1"
+#define LN_aes_256_cfb1		"aes-256-cfb1"
+#define NID_aes_256_cfb1		652
+
+#define SN_aes_128_cfb8		"AES-128-CFB8"
+#define LN_aes_128_cfb8		"aes-128-cfb8"
+#define NID_aes_128_cfb8		653
+
+#define SN_aes_192_cfb8		"AES-192-CFB8"
+#define LN_aes_192_cfb8		"aes-192-cfb8"
+#define NID_aes_192_cfb8		654
+
+#define SN_aes_256_cfb8		"AES-256-CFB8"
+#define LN_aes_256_cfb8		"aes-256-cfb8"
+#define NID_aes_256_cfb8		655
+
+#define SN_des_cfb1		"DES-CFB1"
+#define LN_des_cfb1		"des-cfb1"
+#define NID_des_cfb1		656
+
+#define SN_des_cfb8		"DES-CFB8"
+#define LN_des_cfb8		"des-cfb8"
+#define NID_des_cfb8		657
+
+#define SN_des_ede3_cfb1		"DES-EDE3-CFB1"
+#define LN_des_ede3_cfb1		"des-ede3-cfb1"
+#define NID_des_ede3_cfb1		658
+
+#define SN_des_ede3_cfb8		"DES-EDE3-CFB8"
+#define LN_des_ede3_cfb8		"des-ede3-cfb8"
+#define NID_des_ede3_cfb8		659
+
+#define SN_id_aes128_wrap		"id-aes128-wrap"
+#define NID_id_aes128_wrap		788
+#define OBJ_id_aes128_wrap		OBJ_aes,5L
+
+#define SN_id_aes192_wrap		"id-aes192-wrap"
+#define NID_id_aes192_wrap		789
+#define OBJ_id_aes192_wrap		OBJ_aes,25L
+
+#define SN_id_aes256_wrap		"id-aes256-wrap"
+#define NID_id_aes256_wrap		790
+#define OBJ_id_aes256_wrap		OBJ_aes,45L
+
+#define OBJ_nist_hashalgs		OBJ_nistAlgorithms,2L
+
+#define SN_sha256		"SHA256"
+#define LN_sha256		"sha256"
+#define NID_sha256		672
+#define OBJ_sha256		OBJ_nist_hashalgs,1L
+
+#define SN_sha384		"SHA384"
+#define LN_sha384		"sha384"
+#define NID_sha384		673
+#define OBJ_sha384		OBJ_nist_hashalgs,2L
+
+#define SN_sha512		"SHA512"
+#define LN_sha512		"sha512"
+#define NID_sha512		674
+#define OBJ_sha512		OBJ_nist_hashalgs,3L
+
+#define SN_sha224		"SHA224"
+#define LN_sha224		"sha224"
+#define NID_sha224		675
+#define OBJ_sha224		OBJ_nist_hashalgs,4L
+
+#define OBJ_dsa_with_sha2		OBJ_nistAlgorithms,3L
+
+#define SN_dsa_with_SHA224		"dsa_with_SHA224"
+#define NID_dsa_with_SHA224		802
+#define OBJ_dsa_with_SHA224		OBJ_dsa_with_sha2,1L
+
+#define SN_dsa_with_SHA256		"dsa_with_SHA256"
+#define NID_dsa_with_SHA256		803
+#define OBJ_dsa_with_SHA256		OBJ_dsa_with_sha2,2L
+
+#define SN_hold_instruction_code		"holdInstructionCode"
+#define LN_hold_instruction_code		"Hold Instruction Code"
+#define NID_hold_instruction_code		430
+#define OBJ_hold_instruction_code		OBJ_id_ce,23L
+
+#define OBJ_holdInstruction		OBJ_X9_57,2L
+
+#define SN_hold_instruction_none		"holdInstructionNone"
+#define LN_hold_instruction_none		"Hold Instruction None"
+#define NID_hold_instruction_none		431
+#define OBJ_hold_instruction_none		OBJ_holdInstruction,1L
+
+#define SN_hold_instruction_call_issuer		"holdInstructionCallIssuer"
+#define LN_hold_instruction_call_issuer		"Hold Instruction Call Issuer"
+#define NID_hold_instruction_call_issuer		432
+#define OBJ_hold_instruction_call_issuer		OBJ_holdInstruction,2L
+
+#define SN_hold_instruction_reject		"holdInstructionReject"
+#define LN_hold_instruction_reject		"Hold Instruction Reject"
+#define NID_hold_instruction_reject		433
+#define OBJ_hold_instruction_reject		OBJ_holdInstruction,3L
+
+#define SN_data		"data"
+#define NID_data		434
+#define OBJ_data		OBJ_itu_t,9L
+
+#define SN_pss		"pss"
+#define NID_pss		435
+#define OBJ_pss		OBJ_data,2342L
+
+#define SN_ucl		"ucl"
+#define NID_ucl		436
+#define OBJ_ucl		OBJ_pss,19200300L
+
+#define SN_pilot		"pilot"
+#define NID_pilot		437
+#define OBJ_pilot		OBJ_ucl,100L
+
+#define LN_pilotAttributeType		"pilotAttributeType"
+#define NID_pilotAttributeType		438
+#define OBJ_pilotAttributeType		OBJ_pilot,1L
+
+#define LN_pilotAttributeSyntax		"pilotAttributeSyntax"
+#define NID_pilotAttributeSyntax		439
+#define OBJ_pilotAttributeSyntax		OBJ_pilot,3L
+
+#define LN_pilotObjectClass		"pilotObjectClass"
+#define NID_pilotObjectClass		440
+#define OBJ_pilotObjectClass		OBJ_pilot,4L
+
+#define LN_pilotGroups		"pilotGroups"
+#define NID_pilotGroups		441
+#define OBJ_pilotGroups		OBJ_pilot,10L
+
+#define LN_iA5StringSyntax		"iA5StringSyntax"
+#define NID_iA5StringSyntax		442
+#define OBJ_iA5StringSyntax		OBJ_pilotAttributeSyntax,4L
+
+#define LN_caseIgnoreIA5StringSyntax		"caseIgnoreIA5StringSyntax"
+#define NID_caseIgnoreIA5StringSyntax		443
+#define OBJ_caseIgnoreIA5StringSyntax		OBJ_pilotAttributeSyntax,5L
+
+#define LN_pilotObject		"pilotObject"
+#define NID_pilotObject		444
+#define OBJ_pilotObject		OBJ_pilotObjectClass,3L
+
+#define LN_pilotPerson		"pilotPerson"
+#define NID_pilotPerson		445
+#define OBJ_pilotPerson		OBJ_pilotObjectClass,4L
+
+#define SN_account		"account"
+#define NID_account		446
+#define OBJ_account		OBJ_pilotObjectClass,5L
+
+#define SN_document		"document"
+#define NID_document		447
+#define OBJ_document		OBJ_pilotObjectClass,6L
+
+#define SN_room		"room"
+#define NID_room		448
+#define OBJ_room		OBJ_pilotObjectClass,7L
+
+#define LN_documentSeries		"documentSeries"
+#define NID_documentSeries		449
+#define OBJ_documentSeries		OBJ_pilotObjectClass,9L
+
+#define SN_Domain		"domain"
+#define LN_Domain		"Domain"
+#define NID_Domain		392
+#define OBJ_Domain		OBJ_pilotObjectClass,13L
+
+#define LN_rFC822localPart		"rFC822localPart"
+#define NID_rFC822localPart		450
+#define OBJ_rFC822localPart		OBJ_pilotObjectClass,14L
+
+#define LN_dNSDomain		"dNSDomain"
+#define NID_dNSDomain		451
+#define OBJ_dNSDomain		OBJ_pilotObjectClass,15L
+
+#define LN_domainRelatedObject		"domainRelatedObject"
+#define NID_domainRelatedObject		452
+#define OBJ_domainRelatedObject		OBJ_pilotObjectClass,17L
+
+#define LN_friendlyCountry		"friendlyCountry"
+#define NID_friendlyCountry		453
+#define OBJ_friendlyCountry		OBJ_pilotObjectClass,18L
+
+#define LN_simpleSecurityObject		"simpleSecurityObject"
+#define NID_simpleSecurityObject		454
+#define OBJ_simpleSecurityObject		OBJ_pilotObjectClass,19L
+
+#define LN_pilotOrganization		"pilotOrganization"
+#define NID_pilotOrganization		455
+#define OBJ_pilotOrganization		OBJ_pilotObjectClass,20L
+
+#define LN_pilotDSA		"pilotDSA"
+#define NID_pilotDSA		456
+#define OBJ_pilotDSA		OBJ_pilotObjectClass,21L
+
+#define LN_qualityLabelledData		"qualityLabelledData"
+#define NID_qualityLabelledData		457
+#define OBJ_qualityLabelledData		OBJ_pilotObjectClass,22L
+
+#define SN_userId		"UID"
+#define LN_userId		"userId"
+#define NID_userId		458
+#define OBJ_userId		OBJ_pilotAttributeType,1L
+
+#define LN_textEncodedORAddress		"textEncodedORAddress"
+#define NID_textEncodedORAddress		459
+#define OBJ_textEncodedORAddress		OBJ_pilotAttributeType,2L
+
+#define SN_rfc822Mailbox		"mail"
+#define LN_rfc822Mailbox		"rfc822Mailbox"
+#define NID_rfc822Mailbox		460
+#define OBJ_rfc822Mailbox		OBJ_pilotAttributeType,3L
+
+#define SN_info		"info"
+#define NID_info		461
+#define OBJ_info		OBJ_pilotAttributeType,4L
+
+#define LN_favouriteDrink		"favouriteDrink"
+#define NID_favouriteDrink		462
+#define OBJ_favouriteDrink		OBJ_pilotAttributeType,5L
+
+#define LN_roomNumber		"roomNumber"
+#define NID_roomNumber		463
+#define OBJ_roomNumber		OBJ_pilotAttributeType,6L
+
+#define SN_photo		"photo"
+#define NID_photo		464
+#define OBJ_photo		OBJ_pilotAttributeType,7L
+
+#define LN_userClass		"userClass"
+#define NID_userClass		465
+#define OBJ_userClass		OBJ_pilotAttributeType,8L
+
+#define SN_host		"host"
+#define NID_host		466
+#define OBJ_host		OBJ_pilotAttributeType,9L
+
+#define SN_manager		"manager"
+#define NID_manager		467
+#define OBJ_manager		OBJ_pilotAttributeType,10L
+
+#define LN_documentIdentifier		"documentIdentifier"
+#define NID_documentIdentifier		468
+#define OBJ_documentIdentifier		OBJ_pilotAttributeType,11L
+
+#define LN_documentTitle		"documentTitle"
+#define NID_documentTitle		469
+#define OBJ_documentTitle		OBJ_pilotAttributeType,12L
+
+#define LN_documentVersion		"documentVersion"
+#define NID_documentVersion		470
+#define OBJ_documentVersion		OBJ_pilotAttributeType,13L
+
+#define LN_documentAuthor		"documentAuthor"
+#define NID_documentAuthor		471
+#define OBJ_documentAuthor		OBJ_pilotAttributeType,14L
+
+#define LN_documentLocation		"documentLocation"
+#define NID_documentLocation		472
+#define OBJ_documentLocation		OBJ_pilotAttributeType,15L
+
+#define LN_homeTelephoneNumber		"homeTelephoneNumber"
+#define NID_homeTelephoneNumber		473
+#define OBJ_homeTelephoneNumber		OBJ_pilotAttributeType,20L
+
+#define SN_secretary		"secretary"
+#define NID_secretary		474
+#define OBJ_secretary		OBJ_pilotAttributeType,21L
+
+#define LN_otherMailbox		"otherMailbox"
+#define NID_otherMailbox		475
+#define OBJ_otherMailbox		OBJ_pilotAttributeType,22L
+
+#define LN_lastModifiedTime		"lastModifiedTime"
+#define NID_lastModifiedTime		476
+#define OBJ_lastModifiedTime		OBJ_pilotAttributeType,23L
+
+#define LN_lastModifiedBy		"lastModifiedBy"
+#define NID_lastModifiedBy		477
+#define OBJ_lastModifiedBy		OBJ_pilotAttributeType,24L
+
+#define SN_domainComponent		"DC"
+#define LN_domainComponent		"domainComponent"
+#define NID_domainComponent		391
+#define OBJ_domainComponent		OBJ_pilotAttributeType,25L
+
+#define LN_aRecord		"aRecord"
+#define NID_aRecord		478
+#define OBJ_aRecord		OBJ_pilotAttributeType,26L
+
+#define LN_pilotAttributeType27		"pilotAttributeType27"
+#define NID_pilotAttributeType27		479
+#define OBJ_pilotAttributeType27		OBJ_pilotAttributeType,27L
+
+#define LN_mXRecord		"mXRecord"
+#define NID_mXRecord		480
+#define OBJ_mXRecord		OBJ_pilotAttributeType,28L
+
+#define LN_nSRecord		"nSRecord"
+#define NID_nSRecord		481
+#define OBJ_nSRecord		OBJ_pilotAttributeType,29L
+
+#define LN_sOARecord		"sOARecord"
+#define NID_sOARecord		482
+#define OBJ_sOARecord		OBJ_pilotAttributeType,30L
+
+#define LN_cNAMERecord		"cNAMERecord"
+#define NID_cNAMERecord		483
+#define OBJ_cNAMERecord		OBJ_pilotAttributeType,31L
+
+#define LN_associatedDomain		"associatedDomain"
+#define NID_associatedDomain		484
+#define OBJ_associatedDomain		OBJ_pilotAttributeType,37L
+
+#define LN_associatedName		"associatedName"
+#define NID_associatedName		485
+#define OBJ_associatedName		OBJ_pilotAttributeType,38L
+
+#define LN_homePostalAddress		"homePostalAddress"
+#define NID_homePostalAddress		486
+#define OBJ_homePostalAddress		OBJ_pilotAttributeType,39L
+
+#define LN_personalTitle		"personalTitle"
+#define NID_personalTitle		487
+#define OBJ_personalTitle		OBJ_pilotAttributeType,40L
+
+#define LN_mobileTelephoneNumber		"mobileTelephoneNumber"
+#define NID_mobileTelephoneNumber		488
+#define OBJ_mobileTelephoneNumber		OBJ_pilotAttributeType,41L
+
+#define LN_pagerTelephoneNumber		"pagerTelephoneNumber"
+#define NID_pagerTelephoneNumber		489
+#define OBJ_pagerTelephoneNumber		OBJ_pilotAttributeType,42L
+
+#define LN_friendlyCountryName		"friendlyCountryName"
+#define NID_friendlyCountryName		490
+#define OBJ_friendlyCountryName		OBJ_pilotAttributeType,43L
+
+#define LN_organizationalStatus		"organizationalStatus"
+#define NID_organizationalStatus		491
+#define OBJ_organizationalStatus		OBJ_pilotAttributeType,45L
+
+#define LN_janetMailbox		"janetMailbox"
+#define NID_janetMailbox		492
+#define OBJ_janetMailbox		OBJ_pilotAttributeType,46L
+
+#define LN_mailPreferenceOption		"mailPreferenceOption"
+#define NID_mailPreferenceOption		493
+#define OBJ_mailPreferenceOption		OBJ_pilotAttributeType,47L
+
+#define LN_buildingName		"buildingName"
+#define NID_buildingName		494
+#define OBJ_buildingName		OBJ_pilotAttributeType,48L
+
+#define LN_dSAQuality		"dSAQuality"
+#define NID_dSAQuality		495
+#define OBJ_dSAQuality		OBJ_pilotAttributeType,49L
+
+#define LN_singleLevelQuality		"singleLevelQuality"
+#define NID_singleLevelQuality		496
+#define OBJ_singleLevelQuality		OBJ_pilotAttributeType,50L
+
+#define LN_subtreeMinimumQuality		"subtreeMinimumQuality"
+#define NID_subtreeMinimumQuality		497
+#define OBJ_subtreeMinimumQuality		OBJ_pilotAttributeType,51L
+
+#define LN_subtreeMaximumQuality		"subtreeMaximumQuality"
+#define NID_subtreeMaximumQuality		498
+#define OBJ_subtreeMaximumQuality		OBJ_pilotAttributeType,52L
+
+#define LN_personalSignature		"personalSignature"
+#define NID_personalSignature		499
+#define OBJ_personalSignature		OBJ_pilotAttributeType,53L
+
+#define LN_dITRedirect		"dITRedirect"
+#define NID_dITRedirect		500
+#define OBJ_dITRedirect		OBJ_pilotAttributeType,54L
+
+#define SN_audio		"audio"
+#define NID_audio		501
+#define OBJ_audio		OBJ_pilotAttributeType,55L
+
+#define LN_documentPublisher		"documentPublisher"
+#define NID_documentPublisher		502
+#define OBJ_documentPublisher		OBJ_pilotAttributeType,56L
+
+#define SN_id_set		"id-set"
+#define LN_id_set		"Secure Electronic Transactions"
+#define NID_id_set		512
+#define OBJ_id_set		OBJ_international_organizations,42L
+
+#define SN_set_ctype		"set-ctype"
+#define LN_set_ctype		"content types"
+#define NID_set_ctype		513
+#define OBJ_set_ctype		OBJ_id_set,0L
+
+#define SN_set_msgExt		"set-msgExt"
+#define LN_set_msgExt		"message extensions"
+#define NID_set_msgExt		514
+#define OBJ_set_msgExt		OBJ_id_set,1L
+
+#define SN_set_attr		"set-attr"
+#define NID_set_attr		515
+#define OBJ_set_attr		OBJ_id_set,3L
+
+#define SN_set_policy		"set-policy"
+#define NID_set_policy		516
+#define OBJ_set_policy		OBJ_id_set,5L
+
+#define SN_set_certExt		"set-certExt"
+#define LN_set_certExt		"certificate extensions"
+#define NID_set_certExt		517
+#define OBJ_set_certExt		OBJ_id_set,7L
+
+#define SN_set_brand		"set-brand"
+#define NID_set_brand		518
+#define OBJ_set_brand		OBJ_id_set,8L
+
+#define SN_setct_PANData		"setct-PANData"
+#define NID_setct_PANData		519
+#define OBJ_setct_PANData		OBJ_set_ctype,0L
+
+#define SN_setct_PANToken		"setct-PANToken"
+#define NID_setct_PANToken		520
+#define OBJ_setct_PANToken		OBJ_set_ctype,1L
+
+#define SN_setct_PANOnly		"setct-PANOnly"
+#define NID_setct_PANOnly		521
+#define OBJ_setct_PANOnly		OBJ_set_ctype,2L
+
+#define SN_setct_OIData		"setct-OIData"
+#define NID_setct_OIData		522
+#define OBJ_setct_OIData		OBJ_set_ctype,3L
+
+#define SN_setct_PI		"setct-PI"
+#define NID_setct_PI		523
+#define OBJ_setct_PI		OBJ_set_ctype,4L
+
+#define SN_setct_PIData		"setct-PIData"
+#define NID_setct_PIData		524
+#define OBJ_setct_PIData		OBJ_set_ctype,5L
+
+#define SN_setct_PIDataUnsigned		"setct-PIDataUnsigned"
+#define NID_setct_PIDataUnsigned		525
+#define OBJ_setct_PIDataUnsigned		OBJ_set_ctype,6L
+
+#define SN_setct_HODInput		"setct-HODInput"
+#define NID_setct_HODInput		526
+#define OBJ_setct_HODInput		OBJ_set_ctype,7L
+
+#define SN_setct_AuthResBaggage		"setct-AuthResBaggage"
+#define NID_setct_AuthResBaggage		527
+#define OBJ_setct_AuthResBaggage		OBJ_set_ctype,8L
+
+#define SN_setct_AuthRevReqBaggage		"setct-AuthRevReqBaggage"
+#define NID_setct_AuthRevReqBaggage		528
+#define OBJ_setct_AuthRevReqBaggage		OBJ_set_ctype,9L
+
+#define SN_setct_AuthRevResBaggage		"setct-AuthRevResBaggage"
+#define NID_setct_AuthRevResBaggage		529
+#define OBJ_setct_AuthRevResBaggage		OBJ_set_ctype,10L
+
+#define SN_setct_CapTokenSeq		"setct-CapTokenSeq"
+#define NID_setct_CapTokenSeq		530
+#define OBJ_setct_CapTokenSeq		OBJ_set_ctype,11L
+
+#define SN_setct_PInitResData		"setct-PInitResData"
+#define NID_setct_PInitResData		531
+#define OBJ_setct_PInitResData		OBJ_set_ctype,12L
+
+#define SN_setct_PI_TBS		"setct-PI-TBS"
+#define NID_setct_PI_TBS		532
+#define OBJ_setct_PI_TBS		OBJ_set_ctype,13L
+
+#define SN_setct_PResData		"setct-PResData"
+#define NID_setct_PResData		533
+#define OBJ_setct_PResData		OBJ_set_ctype,14L
+
+#define SN_setct_AuthReqTBS		"setct-AuthReqTBS"
+#define NID_setct_AuthReqTBS		534
+#define OBJ_setct_AuthReqTBS		OBJ_set_ctype,16L
+
+#define SN_setct_AuthResTBS		"setct-AuthResTBS"
+#define NID_setct_AuthResTBS		535
+#define OBJ_setct_AuthResTBS		OBJ_set_ctype,17L
+
+#define SN_setct_AuthResTBSX		"setct-AuthResTBSX"
+#define NID_setct_AuthResTBSX		536
+#define OBJ_setct_AuthResTBSX		OBJ_set_ctype,18L
+
+#define SN_setct_AuthTokenTBS		"setct-AuthTokenTBS"
+#define NID_setct_AuthTokenTBS		537
+#define OBJ_setct_AuthTokenTBS		OBJ_set_ctype,19L
+
+#define SN_setct_CapTokenData		"setct-CapTokenData"
+#define NID_setct_CapTokenData		538
+#define OBJ_setct_CapTokenData		OBJ_set_ctype,20L
+
+#define SN_setct_CapTokenTBS		"setct-CapTokenTBS"
+#define NID_setct_CapTokenTBS		539
+#define OBJ_setct_CapTokenTBS		OBJ_set_ctype,21L
+
+#define SN_setct_AcqCardCodeMsg		"setct-AcqCardCodeMsg"
+#define NID_setct_AcqCardCodeMsg		540
+#define OBJ_setct_AcqCardCodeMsg		OBJ_set_ctype,22L
+
+#define SN_setct_AuthRevReqTBS		"setct-AuthRevReqTBS"
+#define NID_setct_AuthRevReqTBS		541
+#define OBJ_setct_AuthRevReqTBS		OBJ_set_ctype,23L
+
+#define SN_setct_AuthRevResData		"setct-AuthRevResData"
+#define NID_setct_AuthRevResData		542
+#define OBJ_setct_AuthRevResData		OBJ_set_ctype,24L
+
+#define SN_setct_AuthRevResTBS		"setct-AuthRevResTBS"
+#define NID_setct_AuthRevResTBS		543
+#define OBJ_setct_AuthRevResTBS		OBJ_set_ctype,25L
+
+#define SN_setct_CapReqTBS		"setct-CapReqTBS"
+#define NID_setct_CapReqTBS		544
+#define OBJ_setct_CapReqTBS		OBJ_set_ctype,26L
+
+#define SN_setct_CapReqTBSX		"setct-CapReqTBSX"
+#define NID_setct_CapReqTBSX		545
+#define OBJ_setct_CapReqTBSX		OBJ_set_ctype,27L
+
+#define SN_setct_CapResData		"setct-CapResData"
+#define NID_setct_CapResData		546
+#define OBJ_setct_CapResData		OBJ_set_ctype,28L
+
+#define SN_setct_CapRevReqTBS		"setct-CapRevReqTBS"
+#define NID_setct_CapRevReqTBS		547
+#define OBJ_setct_CapRevReqTBS		OBJ_set_ctype,29L
+
+#define SN_setct_CapRevReqTBSX		"setct-CapRevReqTBSX"
+#define NID_setct_CapRevReqTBSX		548
+#define OBJ_setct_CapRevReqTBSX		OBJ_set_ctype,30L
+
+#define SN_setct_CapRevResData		"setct-CapRevResData"
+#define NID_setct_CapRevResData		549
+#define OBJ_setct_CapRevResData		OBJ_set_ctype,31L
+
+#define SN_setct_CredReqTBS		"setct-CredReqTBS"
+#define NID_setct_CredReqTBS		550
+#define OBJ_setct_CredReqTBS		OBJ_set_ctype,32L
+
+#define SN_setct_CredReqTBSX		"setct-CredReqTBSX"
+#define NID_setct_CredReqTBSX		551
+#define OBJ_setct_CredReqTBSX		OBJ_set_ctype,33L
+
+#define SN_setct_CredResData		"setct-CredResData"
+#define NID_setct_CredResData		552
+#define OBJ_setct_CredResData		OBJ_set_ctype,34L
+
+#define SN_setct_CredRevReqTBS		"setct-CredRevReqTBS"
+#define NID_setct_CredRevReqTBS		553
+#define OBJ_setct_CredRevReqTBS		OBJ_set_ctype,35L
+
+#define SN_setct_CredRevReqTBSX		"setct-CredRevReqTBSX"
+#define NID_setct_CredRevReqTBSX		554
+#define OBJ_setct_CredRevReqTBSX		OBJ_set_ctype,36L
+
+#define SN_setct_CredRevResData		"setct-CredRevResData"
+#define NID_setct_CredRevResData		555
+#define OBJ_setct_CredRevResData		OBJ_set_ctype,37L
+
+#define SN_setct_PCertReqData		"setct-PCertReqData"
+#define NID_setct_PCertReqData		556
+#define OBJ_setct_PCertReqData		OBJ_set_ctype,38L
+
+#define SN_setct_PCertResTBS		"setct-PCertResTBS"
+#define NID_setct_PCertResTBS		557
+#define OBJ_setct_PCertResTBS		OBJ_set_ctype,39L
+
+#define SN_setct_BatchAdminReqData		"setct-BatchAdminReqData"
+#define NID_setct_BatchAdminReqData		558
+#define OBJ_setct_BatchAdminReqData		OBJ_set_ctype,40L
+
+#define SN_setct_BatchAdminResData		"setct-BatchAdminResData"
+#define NID_setct_BatchAdminResData		559
+#define OBJ_setct_BatchAdminResData		OBJ_set_ctype,41L
+
+#define SN_setct_CardCInitResTBS		"setct-CardCInitResTBS"
+#define NID_setct_CardCInitResTBS		560
+#define OBJ_setct_CardCInitResTBS		OBJ_set_ctype,42L
+
+#define SN_setct_MeAqCInitResTBS		"setct-MeAqCInitResTBS"
+#define NID_setct_MeAqCInitResTBS		561
+#define OBJ_setct_MeAqCInitResTBS		OBJ_set_ctype,43L
+
+#define SN_setct_RegFormResTBS		"setct-RegFormResTBS"
+#define NID_setct_RegFormResTBS		562
+#define OBJ_setct_RegFormResTBS		OBJ_set_ctype,44L
+
+#define SN_setct_CertReqData		"setct-CertReqData"
+#define NID_setct_CertReqData		563
+#define OBJ_setct_CertReqData		OBJ_set_ctype,45L
+
+#define SN_setct_CertReqTBS		"setct-CertReqTBS"
+#define NID_setct_CertReqTBS		564
+#define OBJ_setct_CertReqTBS		OBJ_set_ctype,46L
+
+#define SN_setct_CertResData		"setct-CertResData"
+#define NID_setct_CertResData		565
+#define OBJ_setct_CertResData		OBJ_set_ctype,47L
+
+#define SN_setct_CertInqReqTBS		"setct-CertInqReqTBS"
+#define NID_setct_CertInqReqTBS		566
+#define OBJ_setct_CertInqReqTBS		OBJ_set_ctype,48L
+
+#define SN_setct_ErrorTBS		"setct-ErrorTBS"
+#define NID_setct_ErrorTBS		567
+#define OBJ_setct_ErrorTBS		OBJ_set_ctype,49L
+
+#define SN_setct_PIDualSignedTBE		"setct-PIDualSignedTBE"
+#define NID_setct_PIDualSignedTBE		568
+#define OBJ_setct_PIDualSignedTBE		OBJ_set_ctype,50L
+
+#define SN_setct_PIUnsignedTBE		"setct-PIUnsignedTBE"
+#define NID_setct_PIUnsignedTBE		569
+#define OBJ_setct_PIUnsignedTBE		OBJ_set_ctype,51L
+
+#define SN_setct_AuthReqTBE		"setct-AuthReqTBE"
+#define NID_setct_AuthReqTBE		570
+#define OBJ_setct_AuthReqTBE		OBJ_set_ctype,52L
+
+#define SN_setct_AuthResTBE		"setct-AuthResTBE"
+#define NID_setct_AuthResTBE		571
+#define OBJ_setct_AuthResTBE		OBJ_set_ctype,53L
+
+#define SN_setct_AuthResTBEX		"setct-AuthResTBEX"
+#define NID_setct_AuthResTBEX		572
+#define OBJ_setct_AuthResTBEX		OBJ_set_ctype,54L
+
+#define SN_setct_AuthTokenTBE		"setct-AuthTokenTBE"
+#define NID_setct_AuthTokenTBE		573
+#define OBJ_setct_AuthTokenTBE		OBJ_set_ctype,55L
+
+#define SN_setct_CapTokenTBE		"setct-CapTokenTBE"
+#define NID_setct_CapTokenTBE		574
+#define OBJ_setct_CapTokenTBE		OBJ_set_ctype,56L
+
+#define SN_setct_CapTokenTBEX		"setct-CapTokenTBEX"
+#define NID_setct_CapTokenTBEX		575
+#define OBJ_setct_CapTokenTBEX		OBJ_set_ctype,57L
+
+#define SN_setct_AcqCardCodeMsgTBE		"setct-AcqCardCodeMsgTBE"
+#define NID_setct_AcqCardCodeMsgTBE		576
+#define OBJ_setct_AcqCardCodeMsgTBE		OBJ_set_ctype,58L
+
+#define SN_setct_AuthRevReqTBE		"setct-AuthRevReqTBE"
+#define NID_setct_AuthRevReqTBE		577
+#define OBJ_setct_AuthRevReqTBE		OBJ_set_ctype,59L
+
+#define SN_setct_AuthRevResTBE		"setct-AuthRevResTBE"
+#define NID_setct_AuthRevResTBE		578
+#define OBJ_setct_AuthRevResTBE		OBJ_set_ctype,60L
+
+#define SN_setct_AuthRevResTBEB		"setct-AuthRevResTBEB"
+#define NID_setct_AuthRevResTBEB		579
+#define OBJ_setct_AuthRevResTBEB		OBJ_set_ctype,61L
+
+#define SN_setct_CapReqTBE		"setct-CapReqTBE"
+#define NID_setct_CapReqTBE		580
+#define OBJ_setct_CapReqTBE		OBJ_set_ctype,62L
+
+#define SN_setct_CapReqTBEX		"setct-CapReqTBEX"
+#define NID_setct_CapReqTBEX		581
+#define OBJ_setct_CapReqTBEX		OBJ_set_ctype,63L
+
+#define SN_setct_CapResTBE		"setct-CapResTBE"
+#define NID_setct_CapResTBE		582
+#define OBJ_setct_CapResTBE		OBJ_set_ctype,64L
+
+#define SN_setct_CapRevReqTBE		"setct-CapRevReqTBE"
+#define NID_setct_CapRevReqTBE		583
+#define OBJ_setct_CapRevReqTBE		OBJ_set_ctype,65L
+
+#define SN_setct_CapRevReqTBEX		"setct-CapRevReqTBEX"
+#define NID_setct_CapRevReqTBEX		584
+#define OBJ_setct_CapRevReqTBEX		OBJ_set_ctype,66L
+
+#define SN_setct_CapRevResTBE		"setct-CapRevResTBE"
+#define NID_setct_CapRevResTBE		585
+#define OBJ_setct_CapRevResTBE		OBJ_set_ctype,67L
+
+#define SN_setct_CredReqTBE		"setct-CredReqTBE"
+#define NID_setct_CredReqTBE		586
+#define OBJ_setct_CredReqTBE		OBJ_set_ctype,68L
+
+#define SN_setct_CredReqTBEX		"setct-CredReqTBEX"
+#define NID_setct_CredReqTBEX		587
+#define OBJ_setct_CredReqTBEX		OBJ_set_ctype,69L
+
+#define SN_setct_CredResTBE		"setct-CredResTBE"
+#define NID_setct_CredResTBE		588
+#define OBJ_setct_CredResTBE		OBJ_set_ctype,70L
+
+#define SN_setct_CredRevReqTBE		"setct-CredRevReqTBE"
+#define NID_setct_CredRevReqTBE		589
+#define OBJ_setct_CredRevReqTBE		OBJ_set_ctype,71L
+
+#define SN_setct_CredRevReqTBEX		"setct-CredRevReqTBEX"
+#define NID_setct_CredRevReqTBEX		590
+#define OBJ_setct_CredRevReqTBEX		OBJ_set_ctype,72L
+
+#define SN_setct_CredRevResTBE		"setct-CredRevResTBE"
+#define NID_setct_CredRevResTBE		591
+#define OBJ_setct_CredRevResTBE		OBJ_set_ctype,73L
+
+#define SN_setct_BatchAdminReqTBE		"setct-BatchAdminReqTBE"
+#define NID_setct_BatchAdminReqTBE		592
+#define OBJ_setct_BatchAdminReqTBE		OBJ_set_ctype,74L
+
+#define SN_setct_BatchAdminResTBE		"setct-BatchAdminResTBE"
+#define NID_setct_BatchAdminResTBE		593
+#define OBJ_setct_BatchAdminResTBE		OBJ_set_ctype,75L
+
+#define SN_setct_RegFormReqTBE		"setct-RegFormReqTBE"
+#define NID_setct_RegFormReqTBE		594
+#define OBJ_setct_RegFormReqTBE		OBJ_set_ctype,76L
+
+#define SN_setct_CertReqTBE		"setct-CertReqTBE"
+#define NID_setct_CertReqTBE		595
+#define OBJ_setct_CertReqTBE		OBJ_set_ctype,77L
+
+#define SN_setct_CertReqTBEX		"setct-CertReqTBEX"
+#define NID_setct_CertReqTBEX		596
+#define OBJ_setct_CertReqTBEX		OBJ_set_ctype,78L
+
+#define SN_setct_CertResTBE		"setct-CertResTBE"
+#define NID_setct_CertResTBE		597
+#define OBJ_setct_CertResTBE		OBJ_set_ctype,79L
+
+#define SN_setct_CRLNotificationTBS		"setct-CRLNotificationTBS"
+#define NID_setct_CRLNotificationTBS		598
+#define OBJ_setct_CRLNotificationTBS		OBJ_set_ctype,80L
+
+#define SN_setct_CRLNotificationResTBS		"setct-CRLNotificationResTBS"
+#define NID_setct_CRLNotificationResTBS		599
+#define OBJ_setct_CRLNotificationResTBS		OBJ_set_ctype,81L
+
+#define SN_setct_BCIDistributionTBS		"setct-BCIDistributionTBS"
+#define NID_setct_BCIDistributionTBS		600
+#define OBJ_setct_BCIDistributionTBS		OBJ_set_ctype,82L
+
+#define SN_setext_genCrypt		"setext-genCrypt"
+#define LN_setext_genCrypt		"generic cryptogram"
+#define NID_setext_genCrypt		601
+#define OBJ_setext_genCrypt		OBJ_set_msgExt,1L
+
+#define SN_setext_miAuth		"setext-miAuth"
+#define LN_setext_miAuth		"merchant initiated auth"
+#define NID_setext_miAuth		602
+#define OBJ_setext_miAuth		OBJ_set_msgExt,3L
+
+#define SN_setext_pinSecure		"setext-pinSecure"
+#define NID_setext_pinSecure		603
+#define OBJ_setext_pinSecure		OBJ_set_msgExt,4L
+
+#define SN_setext_pinAny		"setext-pinAny"
+#define NID_setext_pinAny		604
+#define OBJ_setext_pinAny		OBJ_set_msgExt,5L
+
+#define SN_setext_track2		"setext-track2"
+#define NID_setext_track2		605
+#define OBJ_setext_track2		OBJ_set_msgExt,7L
+
+#define SN_setext_cv		"setext-cv"
+#define LN_setext_cv		"additional verification"
+#define NID_setext_cv		606
+#define OBJ_setext_cv		OBJ_set_msgExt,8L
+
+#define SN_set_policy_root		"set-policy-root"
+#define NID_set_policy_root		607
+#define OBJ_set_policy_root		OBJ_set_policy,0L
+
+#define SN_setCext_hashedRoot		"setCext-hashedRoot"
+#define NID_setCext_hashedRoot		608
+#define OBJ_setCext_hashedRoot		OBJ_set_certExt,0L
+
+#define SN_setCext_certType		"setCext-certType"
+#define NID_setCext_certType		609
+#define OBJ_setCext_certType		OBJ_set_certExt,1L
+
+#define SN_setCext_merchData		"setCext-merchData"
+#define NID_setCext_merchData		610
+#define OBJ_setCext_merchData		OBJ_set_certExt,2L
+
+#define SN_setCext_cCertRequired		"setCext-cCertRequired"
+#define NID_setCext_cCertRequired		611
+#define OBJ_setCext_cCertRequired		OBJ_set_certExt,3L
+
+#define SN_setCext_tunneling		"setCext-tunneling"
+#define NID_setCext_tunneling		612
+#define OBJ_setCext_tunneling		OBJ_set_certExt,4L
+
+#define SN_setCext_setExt		"setCext-setExt"
+#define NID_setCext_setExt		613
+#define OBJ_setCext_setExt		OBJ_set_certExt,5L
+
+#define SN_setCext_setQualf		"setCext-setQualf"
+#define NID_setCext_setQualf		614
+#define OBJ_setCext_setQualf		OBJ_set_certExt,6L
+
+#define SN_setCext_PGWYcapabilities		"setCext-PGWYcapabilities"
+#define NID_setCext_PGWYcapabilities		615
+#define OBJ_setCext_PGWYcapabilities		OBJ_set_certExt,7L
+
+#define SN_setCext_TokenIdentifier		"setCext-TokenIdentifier"
+#define NID_setCext_TokenIdentifier		616
+#define OBJ_setCext_TokenIdentifier		OBJ_set_certExt,8L
+
+#define SN_setCext_Track2Data		"setCext-Track2Data"
+#define NID_setCext_Track2Data		617
+#define OBJ_setCext_Track2Data		OBJ_set_certExt,9L
+
+#define SN_setCext_TokenType		"setCext-TokenType"
+#define NID_setCext_TokenType		618
+#define OBJ_setCext_TokenType		OBJ_set_certExt,10L
+
+#define SN_setCext_IssuerCapabilities		"setCext-IssuerCapabilities"
+#define NID_setCext_IssuerCapabilities		619
+#define OBJ_setCext_IssuerCapabilities		OBJ_set_certExt,11L
+
+#define SN_setAttr_Cert		"setAttr-Cert"
+#define NID_setAttr_Cert		620
+#define OBJ_setAttr_Cert		OBJ_set_attr,0L
+
+#define SN_setAttr_PGWYcap		"setAttr-PGWYcap"
+#define LN_setAttr_PGWYcap		"payment gateway capabilities"
+#define NID_setAttr_PGWYcap		621
+#define OBJ_setAttr_PGWYcap		OBJ_set_attr,1L
+
+#define SN_setAttr_TokenType		"setAttr-TokenType"
+#define NID_setAttr_TokenType		622
+#define OBJ_setAttr_TokenType		OBJ_set_attr,2L
+
+#define SN_setAttr_IssCap		"setAttr-IssCap"
+#define LN_setAttr_IssCap		"issuer capabilities"
+#define NID_setAttr_IssCap		623
+#define OBJ_setAttr_IssCap		OBJ_set_attr,3L
+
+#define SN_set_rootKeyThumb		"set-rootKeyThumb"
+#define NID_set_rootKeyThumb		624
+#define OBJ_set_rootKeyThumb		OBJ_setAttr_Cert,0L
+
+#define SN_set_addPolicy		"set-addPolicy"
+#define NID_set_addPolicy		625
+#define OBJ_set_addPolicy		OBJ_setAttr_Cert,1L
+
+#define SN_setAttr_Token_EMV		"setAttr-Token-EMV"
+#define NID_setAttr_Token_EMV		626
+#define OBJ_setAttr_Token_EMV		OBJ_setAttr_TokenType,1L
+
+#define SN_setAttr_Token_B0Prime		"setAttr-Token-B0Prime"
+#define NID_setAttr_Token_B0Prime		627
+#define OBJ_setAttr_Token_B0Prime		OBJ_setAttr_TokenType,2L
+
+#define SN_setAttr_IssCap_CVM		"setAttr-IssCap-CVM"
+#define NID_setAttr_IssCap_CVM		628
+#define OBJ_setAttr_IssCap_CVM		OBJ_setAttr_IssCap,3L
+
+#define SN_setAttr_IssCap_T2		"setAttr-IssCap-T2"
+#define NID_setAttr_IssCap_T2		629
+#define OBJ_setAttr_IssCap_T2		OBJ_setAttr_IssCap,4L
+
+#define SN_setAttr_IssCap_Sig		"setAttr-IssCap-Sig"
+#define NID_setAttr_IssCap_Sig		630
+#define OBJ_setAttr_IssCap_Sig		OBJ_setAttr_IssCap,5L
+
+#define SN_setAttr_GenCryptgrm		"setAttr-GenCryptgrm"
+#define LN_setAttr_GenCryptgrm		"generate cryptogram"
+#define NID_setAttr_GenCryptgrm		631
+#define OBJ_setAttr_GenCryptgrm		OBJ_setAttr_IssCap_CVM,1L
+
+#define SN_setAttr_T2Enc		"setAttr-T2Enc"
+#define LN_setAttr_T2Enc		"encrypted track 2"
+#define NID_setAttr_T2Enc		632
+#define OBJ_setAttr_T2Enc		OBJ_setAttr_IssCap_T2,1L
+
+#define SN_setAttr_T2cleartxt		"setAttr-T2cleartxt"
+#define LN_setAttr_T2cleartxt		"cleartext track 2"
+#define NID_setAttr_T2cleartxt		633
+#define OBJ_setAttr_T2cleartxt		OBJ_setAttr_IssCap_T2,2L
+
+#define SN_setAttr_TokICCsig		"setAttr-TokICCsig"
+#define LN_setAttr_TokICCsig		"ICC or token signature"
+#define NID_setAttr_TokICCsig		634
+#define OBJ_setAttr_TokICCsig		OBJ_setAttr_IssCap_Sig,1L
+
+#define SN_setAttr_SecDevSig		"setAttr-SecDevSig"
+#define LN_setAttr_SecDevSig		"secure device signature"
+#define NID_setAttr_SecDevSig		635
+#define OBJ_setAttr_SecDevSig		OBJ_setAttr_IssCap_Sig,2L
+
+#define SN_set_brand_IATA_ATA		"set-brand-IATA-ATA"
+#define NID_set_brand_IATA_ATA		636
+#define OBJ_set_brand_IATA_ATA		OBJ_set_brand,1L
+
+#define SN_set_brand_Diners		"set-brand-Diners"
+#define NID_set_brand_Diners		637
+#define OBJ_set_brand_Diners		OBJ_set_brand,30L
+
+#define SN_set_brand_AmericanExpress		"set-brand-AmericanExpress"
+#define NID_set_brand_AmericanExpress		638
+#define OBJ_set_brand_AmericanExpress		OBJ_set_brand,34L
+
+#define SN_set_brand_JCB		"set-brand-JCB"
+#define NID_set_brand_JCB		639
+#define OBJ_set_brand_JCB		OBJ_set_brand,35L
+
+#define SN_set_brand_Visa		"set-brand-Visa"
+#define NID_set_brand_Visa		640
+#define OBJ_set_brand_Visa		OBJ_set_brand,4L
+
+#define SN_set_brand_MasterCard		"set-brand-MasterCard"
+#define NID_set_brand_MasterCard		641
+#define OBJ_set_brand_MasterCard		OBJ_set_brand,5L
+
+#define SN_set_brand_Novus		"set-brand-Novus"
+#define NID_set_brand_Novus		642
+#define OBJ_set_brand_Novus		OBJ_set_brand,6011L
+
+#define SN_des_cdmf		"DES-CDMF"
+#define LN_des_cdmf		"des-cdmf"
+#define NID_des_cdmf		643
+#define OBJ_des_cdmf		OBJ_rsadsi,3L,10L
+
+#define SN_rsaOAEPEncryptionSET		"rsaOAEPEncryptionSET"
+#define NID_rsaOAEPEncryptionSET		644
+#define OBJ_rsaOAEPEncryptionSET		OBJ_rsadsi,1L,1L,6L
+
+#define SN_ipsec3		"Oakley-EC2N-3"
+#define LN_ipsec3		"ipsec3"
+#define NID_ipsec3		749
+
+#define SN_ipsec4		"Oakley-EC2N-4"
+#define LN_ipsec4		"ipsec4"
+#define NID_ipsec4		750
+
+#define SN_whirlpool		"whirlpool"
+#define NID_whirlpool		804
+#define OBJ_whirlpool		OBJ_iso,0L,10118L,3L,0L,55L
+
+#define SN_cryptopro		"cryptopro"
+#define NID_cryptopro		805
+#define OBJ_cryptopro		OBJ_member_body,643L,2L,2L
+
+#define SN_cryptocom		"cryptocom"
+#define NID_cryptocom		806
+#define OBJ_cryptocom		OBJ_member_body,643L,2L,9L
+
+#define SN_id_GostR3411_94_with_GostR3410_2001		"id-GostR3411-94-with-GostR3410-2001"
+#define LN_id_GostR3411_94_with_GostR3410_2001		"GOST R 34.11-94 with GOST R 34.10-2001"
+#define NID_id_GostR3411_94_with_GostR3410_2001		807
+#define OBJ_id_GostR3411_94_with_GostR3410_2001		OBJ_cryptopro,3L
+
+#define SN_id_GostR3411_94_with_GostR3410_94		"id-GostR3411-94-with-GostR3410-94"
+#define LN_id_GostR3411_94_with_GostR3410_94		"GOST R 34.11-94 with GOST R 34.10-94"
+#define NID_id_GostR3411_94_with_GostR3410_94		808
+#define OBJ_id_GostR3411_94_with_GostR3410_94		OBJ_cryptopro,4L
+
+#define SN_id_GostR3411_94		"md_gost94"
+#define LN_id_GostR3411_94		"GOST R 34.11-94"
+#define NID_id_GostR3411_94		809
+#define OBJ_id_GostR3411_94		OBJ_cryptopro,9L
+
+#define SN_id_HMACGostR3411_94		"id-HMACGostR3411-94"
+#define LN_id_HMACGostR3411_94		"HMAC GOST 34.11-94"
+#define NID_id_HMACGostR3411_94		810
+#define OBJ_id_HMACGostR3411_94		OBJ_cryptopro,10L
+
+#define SN_id_GostR3410_2001		"gost2001"
+#define LN_id_GostR3410_2001		"GOST R 34.10-2001"
+#define NID_id_GostR3410_2001		811
+#define OBJ_id_GostR3410_2001		OBJ_cryptopro,19L
+
+#define SN_id_GostR3410_94		"gost94"
+#define LN_id_GostR3410_94		"GOST R 34.10-94"
+#define NID_id_GostR3410_94		812
+#define OBJ_id_GostR3410_94		OBJ_cryptopro,20L
+
+#define SN_id_Gost28147_89		"gost89"
+#define LN_id_Gost28147_89		"GOST 28147-89"
+#define NID_id_Gost28147_89		813
+#define OBJ_id_Gost28147_89		OBJ_cryptopro,21L
+
+#define SN_gost89_cnt		"gost89-cnt"
+#define NID_gost89_cnt		814
+
+#define SN_id_Gost28147_89_MAC		"gost-mac"
+#define LN_id_Gost28147_89_MAC		"GOST 28147-89 MAC"
+#define NID_id_Gost28147_89_MAC		815
+#define OBJ_id_Gost28147_89_MAC		OBJ_cryptopro,22L
+
+#define SN_id_GostR3411_94_prf		"prf-gostr3411-94"
+#define LN_id_GostR3411_94_prf		"GOST R 34.11-94 PRF"
+#define NID_id_GostR3411_94_prf		816
+#define OBJ_id_GostR3411_94_prf		OBJ_cryptopro,23L
+
+#define SN_id_GostR3410_2001DH		"id-GostR3410-2001DH"
+#define LN_id_GostR3410_2001DH		"GOST R 34.10-2001 DH"
+#define NID_id_GostR3410_2001DH		817
+#define OBJ_id_GostR3410_2001DH		OBJ_cryptopro,98L
+
+#define SN_id_GostR3410_94DH		"id-GostR3410-94DH"
+#define LN_id_GostR3410_94DH		"GOST R 34.10-94 DH"
+#define NID_id_GostR3410_94DH		818
+#define OBJ_id_GostR3410_94DH		OBJ_cryptopro,99L
+
+#define SN_id_Gost28147_89_CryptoPro_KeyMeshing		"id-Gost28147-89-CryptoPro-KeyMeshing"
+#define NID_id_Gost28147_89_CryptoPro_KeyMeshing		819
+#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing		OBJ_cryptopro,14L,1L
+
+#define SN_id_Gost28147_89_None_KeyMeshing		"id-Gost28147-89-None-KeyMeshing"
+#define NID_id_Gost28147_89_None_KeyMeshing		820
+#define OBJ_id_Gost28147_89_None_KeyMeshing		OBJ_cryptopro,14L,0L
+
+#define SN_id_GostR3411_94_TestParamSet		"id-GostR3411-94-TestParamSet"
+#define NID_id_GostR3411_94_TestParamSet		821
+#define OBJ_id_GostR3411_94_TestParamSet		OBJ_cryptopro,30L,0L
+
+#define SN_id_GostR3411_94_CryptoProParamSet		"id-GostR3411-94-CryptoProParamSet"
+#define NID_id_GostR3411_94_CryptoProParamSet		822
+#define OBJ_id_GostR3411_94_CryptoProParamSet		OBJ_cryptopro,30L,1L
+
+#define SN_id_Gost28147_89_TestParamSet		"id-Gost28147-89-TestParamSet"
+#define NID_id_Gost28147_89_TestParamSet		823
+#define OBJ_id_Gost28147_89_TestParamSet		OBJ_cryptopro,31L,0L
+
+#define SN_id_Gost28147_89_CryptoPro_A_ParamSet		"id-Gost28147-89-CryptoPro-A-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_A_ParamSet		824
+#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet		OBJ_cryptopro,31L,1L
+
+#define SN_id_Gost28147_89_CryptoPro_B_ParamSet		"id-Gost28147-89-CryptoPro-B-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_B_ParamSet		825
+#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet		OBJ_cryptopro,31L,2L
+
+#define SN_id_Gost28147_89_CryptoPro_C_ParamSet		"id-Gost28147-89-CryptoPro-C-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_C_ParamSet		826
+#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet		OBJ_cryptopro,31L,3L
+
+#define SN_id_Gost28147_89_CryptoPro_D_ParamSet		"id-Gost28147-89-CryptoPro-D-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_D_ParamSet		827
+#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet		OBJ_cryptopro,31L,4L
+
+#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet		"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet		828
+#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet		OBJ_cryptopro,31L,5L
+
+#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet		"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet		829
+#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet		OBJ_cryptopro,31L,6L
+
+#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet		"id-Gost28147-89-CryptoPro-RIC-1-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet		830
+#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet		OBJ_cryptopro,31L,7L
+
+#define SN_id_GostR3410_94_TestParamSet		"id-GostR3410-94-TestParamSet"
+#define NID_id_GostR3410_94_TestParamSet		831
+#define OBJ_id_GostR3410_94_TestParamSet		OBJ_cryptopro,32L,0L
+
+#define SN_id_GostR3410_94_CryptoPro_A_ParamSet		"id-GostR3410-94-CryptoPro-A-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_A_ParamSet		832
+#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet		OBJ_cryptopro,32L,2L
+
+#define SN_id_GostR3410_94_CryptoPro_B_ParamSet		"id-GostR3410-94-CryptoPro-B-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_B_ParamSet		833
+#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet		OBJ_cryptopro,32L,3L
+
+#define SN_id_GostR3410_94_CryptoPro_C_ParamSet		"id-GostR3410-94-CryptoPro-C-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_C_ParamSet		834
+#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet		OBJ_cryptopro,32L,4L
+
+#define SN_id_GostR3410_94_CryptoPro_D_ParamSet		"id-GostR3410-94-CryptoPro-D-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_D_ParamSet		835
+#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet		OBJ_cryptopro,32L,5L
+
+#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet		"id-GostR3410-94-CryptoPro-XchA-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet		836
+#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet		OBJ_cryptopro,33L,1L
+
+#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet		"id-GostR3410-94-CryptoPro-XchB-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet		837
+#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet		OBJ_cryptopro,33L,2L
+
+#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet		"id-GostR3410-94-CryptoPro-XchC-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet		838
+#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet		OBJ_cryptopro,33L,3L
+
+#define SN_id_GostR3410_2001_TestParamSet		"id-GostR3410-2001-TestParamSet"
+#define NID_id_GostR3410_2001_TestParamSet		839
+#define OBJ_id_GostR3410_2001_TestParamSet		OBJ_cryptopro,35L,0L
+
+#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet		"id-GostR3410-2001-CryptoPro-A-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet		840
+#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet		OBJ_cryptopro,35L,1L
+
+#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet		"id-GostR3410-2001-CryptoPro-B-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet		841
+#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet		OBJ_cryptopro,35L,2L
+
+#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet		"id-GostR3410-2001-CryptoPro-C-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet		842
+#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet		OBJ_cryptopro,35L,3L
+
+#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet		"id-GostR3410-2001-CryptoPro-XchA-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet		843
+#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet		OBJ_cryptopro,36L,0L
+
+#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet		"id-GostR3410-2001-CryptoPro-XchB-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet		844
+#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet		OBJ_cryptopro,36L,1L
+
+#define SN_id_GostR3410_94_a		"id-GostR3410-94-a"
+#define NID_id_GostR3410_94_a		845
+#define OBJ_id_GostR3410_94_a		OBJ_id_GostR3410_94,1L
+
+#define SN_id_GostR3410_94_aBis		"id-GostR3410-94-aBis"
+#define NID_id_GostR3410_94_aBis		846
+#define OBJ_id_GostR3410_94_aBis		OBJ_id_GostR3410_94,2L
+
+#define SN_id_GostR3410_94_b		"id-GostR3410-94-b"
+#define NID_id_GostR3410_94_b		847
+#define OBJ_id_GostR3410_94_b		OBJ_id_GostR3410_94,3L
+
+#define SN_id_GostR3410_94_bBis		"id-GostR3410-94-bBis"
+#define NID_id_GostR3410_94_bBis		848
+#define OBJ_id_GostR3410_94_bBis		OBJ_id_GostR3410_94,4L
+
+#define SN_id_Gost28147_89_cc		"id-Gost28147-89-cc"
+#define LN_id_Gost28147_89_cc		"GOST 28147-89 Cryptocom ParamSet"
+#define NID_id_Gost28147_89_cc		849
+#define OBJ_id_Gost28147_89_cc		OBJ_cryptocom,1L,6L,1L
+
+#define SN_id_GostR3410_94_cc		"gost94cc"
+#define LN_id_GostR3410_94_cc		"GOST 34.10-94 Cryptocom"
+#define NID_id_GostR3410_94_cc		850
+#define OBJ_id_GostR3410_94_cc		OBJ_cryptocom,1L,5L,3L
+
+#define SN_id_GostR3410_2001_cc		"gost2001cc"
+#define LN_id_GostR3410_2001_cc		"GOST 34.10-2001 Cryptocom"
+#define NID_id_GostR3410_2001_cc		851
+#define OBJ_id_GostR3410_2001_cc		OBJ_cryptocom,1L,5L,4L
+
+#define SN_id_GostR3411_94_with_GostR3410_94_cc		"id-GostR3411-94-with-GostR3410-94-cc"
+#define LN_id_GostR3411_94_with_GostR3410_94_cc		"GOST R 34.11-94 with GOST R 34.10-94 Cryptocom"
+#define NID_id_GostR3411_94_with_GostR3410_94_cc		852
+#define OBJ_id_GostR3411_94_with_GostR3410_94_cc		OBJ_cryptocom,1L,3L,3L
+
+#define SN_id_GostR3411_94_with_GostR3410_2001_cc		"id-GostR3411-94-with-GostR3410-2001-cc"
+#define LN_id_GostR3411_94_with_GostR3410_2001_cc		"GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom"
+#define NID_id_GostR3411_94_with_GostR3410_2001_cc		853
+#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc		OBJ_cryptocom,1L,3L,4L
+
+#define SN_id_GostR3410_2001_ParamSet_cc		"id-GostR3410-2001-ParamSet-cc"
+#define LN_id_GostR3410_2001_ParamSet_cc		"GOST R 3410-2001 Parameter Set Cryptocom"
+#define NID_id_GostR3410_2001_ParamSet_cc		854
+#define OBJ_id_GostR3410_2001_ParamSet_cc		OBJ_cryptocom,1L,8L,1L
+
+#define SN_camellia_128_cbc		"CAMELLIA-128-CBC"
+#define LN_camellia_128_cbc		"camellia-128-cbc"
+#define NID_camellia_128_cbc		751
+#define OBJ_camellia_128_cbc		1L,2L,392L,200011L,61L,1L,1L,1L,2L
+
+#define SN_camellia_192_cbc		"CAMELLIA-192-CBC"
+#define LN_camellia_192_cbc		"camellia-192-cbc"
+#define NID_camellia_192_cbc		752
+#define OBJ_camellia_192_cbc		1L,2L,392L,200011L,61L,1L,1L,1L,3L
+
+#define SN_camellia_256_cbc		"CAMELLIA-256-CBC"
+#define LN_camellia_256_cbc		"camellia-256-cbc"
+#define NID_camellia_256_cbc		753
+#define OBJ_camellia_256_cbc		1L,2L,392L,200011L,61L,1L,1L,1L,4L
+
+#define OBJ_ntt_ds		0L,3L,4401L,5L
+
+#define OBJ_camellia		OBJ_ntt_ds,3L,1L,9L
+
+#define SN_camellia_128_ecb		"CAMELLIA-128-ECB"
+#define LN_camellia_128_ecb		"camellia-128-ecb"
+#define NID_camellia_128_ecb		754
+#define OBJ_camellia_128_ecb		OBJ_camellia,1L
+
+#define SN_camellia_128_ofb128		"CAMELLIA-128-OFB"
+#define LN_camellia_128_ofb128		"camellia-128-ofb"
+#define NID_camellia_128_ofb128		766
+#define OBJ_camellia_128_ofb128		OBJ_camellia,3L
+
+#define SN_camellia_128_cfb128		"CAMELLIA-128-CFB"
+#define LN_camellia_128_cfb128		"camellia-128-cfb"
+#define NID_camellia_128_cfb128		757
+#define OBJ_camellia_128_cfb128		OBJ_camellia,4L
+
+#define SN_camellia_192_ecb		"CAMELLIA-192-ECB"
+#define LN_camellia_192_ecb		"camellia-192-ecb"
+#define NID_camellia_192_ecb		755
+#define OBJ_camellia_192_ecb		OBJ_camellia,21L
+
+#define SN_camellia_192_ofb128		"CAMELLIA-192-OFB"
+#define LN_camellia_192_ofb128		"camellia-192-ofb"
+#define NID_camellia_192_ofb128		767
+#define OBJ_camellia_192_ofb128		OBJ_camellia,23L
+
+#define SN_camellia_192_cfb128		"CAMELLIA-192-CFB"
+#define LN_camellia_192_cfb128		"camellia-192-cfb"
+#define NID_camellia_192_cfb128		758
+#define OBJ_camellia_192_cfb128		OBJ_camellia,24L
+
+#define SN_camellia_256_ecb		"CAMELLIA-256-ECB"
+#define LN_camellia_256_ecb		"camellia-256-ecb"
+#define NID_camellia_256_ecb		756
+#define OBJ_camellia_256_ecb		OBJ_camellia,41L
+
+#define SN_camellia_256_ofb128		"CAMELLIA-256-OFB"
+#define LN_camellia_256_ofb128		"camellia-256-ofb"
+#define NID_camellia_256_ofb128		768
+#define OBJ_camellia_256_ofb128		OBJ_camellia,43L
+
+#define SN_camellia_256_cfb128		"CAMELLIA-256-CFB"
+#define LN_camellia_256_cfb128		"camellia-256-cfb"
+#define NID_camellia_256_cfb128		759
+#define OBJ_camellia_256_cfb128		OBJ_camellia,44L
+
+#define SN_camellia_128_cfb1		"CAMELLIA-128-CFB1"
+#define LN_camellia_128_cfb1		"camellia-128-cfb1"
+#define NID_camellia_128_cfb1		760
+
+#define SN_camellia_192_cfb1		"CAMELLIA-192-CFB1"
+#define LN_camellia_192_cfb1		"camellia-192-cfb1"
+#define NID_camellia_192_cfb1		761
+
+#define SN_camellia_256_cfb1		"CAMELLIA-256-CFB1"
+#define LN_camellia_256_cfb1		"camellia-256-cfb1"
+#define NID_camellia_256_cfb1		762
+
+#define SN_camellia_128_cfb8		"CAMELLIA-128-CFB8"
+#define LN_camellia_128_cfb8		"camellia-128-cfb8"
+#define NID_camellia_128_cfb8		763
+
+#define SN_camellia_192_cfb8		"CAMELLIA-192-CFB8"
+#define LN_camellia_192_cfb8		"camellia-192-cfb8"
+#define NID_camellia_192_cfb8		764
+
+#define SN_camellia_256_cfb8		"CAMELLIA-256-CFB8"
+#define LN_camellia_256_cfb8		"camellia-256-cfb8"
+#define NID_camellia_256_cfb8		765
+
+#define SN_kisa		"KISA"
+#define LN_kisa		"kisa"
+#define NID_kisa		773
+#define OBJ_kisa		OBJ_member_body,410L,200004L
+
+#define SN_seed_ecb		"SEED-ECB"
+#define LN_seed_ecb		"seed-ecb"
+#define NID_seed_ecb		776
+#define OBJ_seed_ecb		OBJ_kisa,1L,3L
+
+#define SN_seed_cbc		"SEED-CBC"
+#define LN_seed_cbc		"seed-cbc"
+#define NID_seed_cbc		777
+#define OBJ_seed_cbc		OBJ_kisa,1L,4L
+
+#define SN_seed_cfb128		"SEED-CFB"
+#define LN_seed_cfb128		"seed-cfb"
+#define NID_seed_cfb128		779
+#define OBJ_seed_cfb128		OBJ_kisa,1L,5L
+
+#define SN_seed_ofb128		"SEED-OFB"
+#define LN_seed_ofb128		"seed-ofb"
+#define NID_seed_ofb128		778
+#define OBJ_seed_ofb128		OBJ_kisa,1L,6L
+
+#define SN_hmac		"HMAC"
+#define LN_hmac		"hmac"
+#define NID_hmac		855
+
diff --git a/openssl/crypto/objects/obj_mac.num b/openssl/crypto/objects/obj_mac.num
new file mode 100644
index 0000000..8c50aac
--- /dev/null
+++ b/openssl/crypto/objects/obj_mac.num
@@ -0,0 +1,892 @@
+undef		0
+rsadsi		1
+pkcs		2
+md2		3
+md5		4
+rc4		5
+rsaEncryption		6
+md2WithRSAEncryption		7
+md5WithRSAEncryption		8
+pbeWithMD2AndDES_CBC		9
+pbeWithMD5AndDES_CBC		10
+X500		11
+X509		12
+commonName		13
+countryName		14
+localityName		15
+stateOrProvinceName		16
+organizationName		17
+organizationalUnitName		18
+rsa		19
+pkcs7		20
+pkcs7_data		21
+pkcs7_signed		22
+pkcs7_enveloped		23
+pkcs7_signedAndEnveloped		24
+pkcs7_digest		25
+pkcs7_encrypted		26
+pkcs3		27
+dhKeyAgreement		28
+des_ecb		29
+des_cfb64		30
+des_cbc		31
+des_ede_ecb		32
+des_ede3_ecb		33
+idea_cbc		34
+idea_cfb64		35
+idea_ecb		36
+rc2_cbc		37
+rc2_ecb		38
+rc2_cfb64		39
+rc2_ofb64		40
+sha		41
+shaWithRSAEncryption		42
+des_ede_cbc		43
+des_ede3_cbc		44
+des_ofb64		45
+idea_ofb64		46
+pkcs9		47
+pkcs9_emailAddress		48
+pkcs9_unstructuredName		49
+pkcs9_contentType		50
+pkcs9_messageDigest		51
+pkcs9_signingTime		52
+pkcs9_countersignature		53
+pkcs9_challengePassword		54
+pkcs9_unstructuredAddress		55
+pkcs9_extCertAttributes		56
+netscape		57
+netscape_cert_extension		58
+netscape_data_type		59
+des_ede_cfb64		60
+des_ede3_cfb64		61
+des_ede_ofb64		62
+des_ede3_ofb64		63
+sha1		64
+sha1WithRSAEncryption		65
+dsaWithSHA		66
+dsa_2		67
+pbeWithSHA1AndRC2_CBC		68
+id_pbkdf2		69
+dsaWithSHA1_2		70
+netscape_cert_type		71
+netscape_base_url		72
+netscape_revocation_url		73
+netscape_ca_revocation_url		74
+netscape_renewal_url		75
+netscape_ca_policy_url		76
+netscape_ssl_server_name		77
+netscape_comment		78
+netscape_cert_sequence		79
+desx_cbc		80
+id_ce		81
+subject_key_identifier		82
+key_usage		83
+private_key_usage_period		84
+subject_alt_name		85
+issuer_alt_name		86
+basic_constraints		87
+crl_number		88
+certificate_policies		89
+authority_key_identifier		90
+bf_cbc		91
+bf_ecb		92
+bf_cfb64		93
+bf_ofb64		94
+mdc2		95
+mdc2WithRSA		96
+rc4_40		97
+rc2_40_cbc		98
+givenName		99
+surname		100
+initials		101
+uniqueIdentifier		102
+crl_distribution_points		103
+md5WithRSA		104
+serialNumber		105
+title		106
+description		107
+cast5_cbc		108
+cast5_ecb		109
+cast5_cfb64		110
+cast5_ofb64		111
+pbeWithMD5AndCast5_CBC		112
+dsaWithSHA1		113
+md5_sha1		114
+sha1WithRSA		115
+dsa		116
+ripemd160		117
+ripemd160WithRSA		119
+rc5_cbc		120
+rc5_ecb		121
+rc5_cfb64		122
+rc5_ofb64		123
+rle_compression		124
+zlib_compression		125
+ext_key_usage		126
+id_pkix		127
+id_kp		128
+server_auth		129
+client_auth		130
+code_sign		131
+email_protect		132
+time_stamp		133
+ms_code_ind		134
+ms_code_com		135
+ms_ctl_sign		136
+ms_sgc		137
+ms_efs		138
+ns_sgc		139
+delta_crl		140
+crl_reason		141
+invalidity_date		142
+sxnet		143
+pbe_WithSHA1And128BitRC4		144
+pbe_WithSHA1And40BitRC4		145
+pbe_WithSHA1And3_Key_TripleDES_CBC		146
+pbe_WithSHA1And2_Key_TripleDES_CBC		147
+pbe_WithSHA1And128BitRC2_CBC		148
+pbe_WithSHA1And40BitRC2_CBC		149
+keyBag		150
+pkcs8ShroudedKeyBag		151
+certBag		152
+crlBag		153
+secretBag		154
+safeContentsBag		155
+friendlyName		156
+localKeyID		157
+x509Certificate		158
+sdsiCertificate		159
+x509Crl		160
+pbes2		161
+pbmac1		162
+hmacWithSHA1		163
+id_qt_cps		164
+id_qt_unotice		165
+rc2_64_cbc		166
+SMIMECapabilities		167
+pbeWithMD2AndRC2_CBC		168
+pbeWithMD5AndRC2_CBC		169
+pbeWithSHA1AndDES_CBC		170
+ms_ext_req		171
+ext_req		172
+name		173
+dnQualifier		174
+id_pe		175
+id_ad		176
+info_access		177
+ad_OCSP		178
+ad_ca_issuers		179
+OCSP_sign		180
+iso		181
+member_body		182
+ISO_US		183
+X9_57		184
+X9cm		185
+pkcs1		186
+pkcs5		187
+SMIME		188
+id_smime_mod		189
+id_smime_ct		190
+id_smime_aa		191
+id_smime_alg		192
+id_smime_cd		193
+id_smime_spq		194
+id_smime_cti		195
+id_smime_mod_cms		196
+id_smime_mod_ess		197
+id_smime_mod_oid		198
+id_smime_mod_msg_v3		199
+id_smime_mod_ets_eSignature_88		200
+id_smime_mod_ets_eSignature_97		201
+id_smime_mod_ets_eSigPolicy_88		202
+id_smime_mod_ets_eSigPolicy_97		203
+id_smime_ct_receipt		204
+id_smime_ct_authData		205
+id_smime_ct_publishCert		206
+id_smime_ct_TSTInfo		207
+id_smime_ct_TDTInfo		208
+id_smime_ct_contentInfo		209
+id_smime_ct_DVCSRequestData		210
+id_smime_ct_DVCSResponseData		211
+id_smime_aa_receiptRequest		212
+id_smime_aa_securityLabel		213
+id_smime_aa_mlExpandHistory		214
+id_smime_aa_contentHint		215
+id_smime_aa_msgSigDigest		216
+id_smime_aa_encapContentType		217
+id_smime_aa_contentIdentifier		218
+id_smime_aa_macValue		219
+id_smime_aa_equivalentLabels		220
+id_smime_aa_contentReference		221
+id_smime_aa_encrypKeyPref		222
+id_smime_aa_signingCertificate		223
+id_smime_aa_smimeEncryptCerts		224
+id_smime_aa_timeStampToken		225
+id_smime_aa_ets_sigPolicyId		226
+id_smime_aa_ets_commitmentType		227
+id_smime_aa_ets_signerLocation		228
+id_smime_aa_ets_signerAttr		229
+id_smime_aa_ets_otherSigCert		230
+id_smime_aa_ets_contentTimestamp		231
+id_smime_aa_ets_CertificateRefs		232
+id_smime_aa_ets_RevocationRefs		233
+id_smime_aa_ets_certValues		234
+id_smime_aa_ets_revocationValues		235
+id_smime_aa_ets_escTimeStamp		236
+id_smime_aa_ets_certCRLTimestamp		237
+id_smime_aa_ets_archiveTimeStamp		238
+id_smime_aa_signatureType		239
+id_smime_aa_dvcs_dvc		240
+id_smime_alg_ESDHwith3DES		241
+id_smime_alg_ESDHwithRC2		242
+id_smime_alg_3DESwrap		243
+id_smime_alg_RC2wrap		244
+id_smime_alg_ESDH		245
+id_smime_alg_CMS3DESwrap		246
+id_smime_alg_CMSRC2wrap		247
+id_smime_cd_ldap		248
+id_smime_spq_ets_sqt_uri		249
+id_smime_spq_ets_sqt_unotice		250
+id_smime_cti_ets_proofOfOrigin		251
+id_smime_cti_ets_proofOfReceipt		252
+id_smime_cti_ets_proofOfDelivery		253
+id_smime_cti_ets_proofOfSender		254
+id_smime_cti_ets_proofOfApproval		255
+id_smime_cti_ets_proofOfCreation		256
+md4		257
+id_pkix_mod		258
+id_qt		259
+id_it		260
+id_pkip		261
+id_alg		262
+id_cmc		263
+id_on		264
+id_pda		265
+id_aca		266
+id_qcs		267
+id_cct		268
+id_pkix1_explicit_88		269
+id_pkix1_implicit_88		270
+id_pkix1_explicit_93		271
+id_pkix1_implicit_93		272
+id_mod_crmf		273
+id_mod_cmc		274
+id_mod_kea_profile_88		275
+id_mod_kea_profile_93		276
+id_mod_cmp		277
+id_mod_qualified_cert_88		278
+id_mod_qualified_cert_93		279
+id_mod_attribute_cert		280
+id_mod_timestamp_protocol		281
+id_mod_ocsp		282
+id_mod_dvcs		283
+id_mod_cmp2000		284
+biometricInfo		285
+qcStatements		286
+ac_auditEntity		287
+ac_targeting		288
+aaControls		289
+sbgp_ipAddrBlock		290
+sbgp_autonomousSysNum		291
+sbgp_routerIdentifier		292
+textNotice		293
+ipsecEndSystem		294
+ipsecTunnel		295
+ipsecUser		296
+dvcs		297
+id_it_caProtEncCert		298
+id_it_signKeyPairTypes		299
+id_it_encKeyPairTypes		300
+id_it_preferredSymmAlg		301
+id_it_caKeyUpdateInfo		302
+id_it_currentCRL		303
+id_it_unsupportedOIDs		304
+id_it_subscriptionRequest		305
+id_it_subscriptionResponse		306
+id_it_keyPairParamReq		307
+id_it_keyPairParamRep		308
+id_it_revPassphrase		309
+id_it_implicitConfirm		310
+id_it_confirmWaitTime		311
+id_it_origPKIMessage		312
+id_regCtrl		313
+id_regInfo		314
+id_regCtrl_regToken		315
+id_regCtrl_authenticator		316
+id_regCtrl_pkiPublicationInfo		317
+id_regCtrl_pkiArchiveOptions		318
+id_regCtrl_oldCertID		319
+id_regCtrl_protocolEncrKey		320
+id_regInfo_utf8Pairs		321
+id_regInfo_certReq		322
+id_alg_des40		323
+id_alg_noSignature		324
+id_alg_dh_sig_hmac_sha1		325
+id_alg_dh_pop		326
+id_cmc_statusInfo		327
+id_cmc_identification		328
+id_cmc_identityProof		329
+id_cmc_dataReturn		330
+id_cmc_transactionId		331
+id_cmc_senderNonce		332
+id_cmc_recipientNonce		333
+id_cmc_addExtensions		334
+id_cmc_encryptedPOP		335
+id_cmc_decryptedPOP		336
+id_cmc_lraPOPWitness		337
+id_cmc_getCert		338
+id_cmc_getCRL		339
+id_cmc_revokeRequest		340
+id_cmc_regInfo		341
+id_cmc_responseInfo		342
+id_cmc_queryPending		343
+id_cmc_popLinkRandom		344
+id_cmc_popLinkWitness		345
+id_cmc_confirmCertAcceptance		346
+id_on_personalData		347
+id_pda_dateOfBirth		348
+id_pda_placeOfBirth		349
+id_pda_pseudonym		350
+id_pda_gender		351
+id_pda_countryOfCitizenship		352
+id_pda_countryOfResidence		353
+id_aca_authenticationInfo		354
+id_aca_accessIdentity		355
+id_aca_chargingIdentity		356
+id_aca_group		357
+id_aca_role		358
+id_qcs_pkixQCSyntax_v1		359
+id_cct_crs		360
+id_cct_PKIData		361
+id_cct_PKIResponse		362
+ad_timeStamping		363
+ad_dvcs		364
+id_pkix_OCSP_basic		365
+id_pkix_OCSP_Nonce		366
+id_pkix_OCSP_CrlID		367
+id_pkix_OCSP_acceptableResponses		368
+id_pkix_OCSP_noCheck		369
+id_pkix_OCSP_archiveCutoff		370
+id_pkix_OCSP_serviceLocator		371
+id_pkix_OCSP_extendedStatus		372
+id_pkix_OCSP_valid		373
+id_pkix_OCSP_path		374
+id_pkix_OCSP_trustRoot		375
+algorithm		376
+rsaSignature		377
+X500algorithms		378
+org		379
+dod		380
+iana		381
+Directory		382
+Management		383
+Experimental		384
+Private		385
+Security		386
+SNMPv2		387
+Mail		388
+Enterprises		389
+dcObject		390
+domainComponent		391
+Domain		392
+joint_iso_ccitt		393
+selected_attribute_types		394
+clearance		395
+md4WithRSAEncryption		396
+ac_proxying		397
+sinfo_access		398
+id_aca_encAttrs		399
+role		400
+policy_constraints		401
+target_information		402
+no_rev_avail		403
+ccitt		404
+ansi_X9_62		405
+X9_62_prime_field		406
+X9_62_characteristic_two_field		407
+X9_62_id_ecPublicKey		408
+X9_62_prime192v1		409
+X9_62_prime192v2		410
+X9_62_prime192v3		411
+X9_62_prime239v1		412
+X9_62_prime239v2		413
+X9_62_prime239v3		414
+X9_62_prime256v1		415
+ecdsa_with_SHA1		416
+ms_csp_name		417
+aes_128_ecb		418
+aes_128_cbc		419
+aes_128_ofb128		420
+aes_128_cfb128		421
+aes_192_ecb		422
+aes_192_cbc		423
+aes_192_ofb128		424
+aes_192_cfb128		425
+aes_256_ecb		426
+aes_256_cbc		427
+aes_256_ofb128		428
+aes_256_cfb128		429
+hold_instruction_code		430
+hold_instruction_none		431
+hold_instruction_call_issuer		432
+hold_instruction_reject		433
+data		434
+pss		435
+ucl		436
+pilot		437
+pilotAttributeType		438
+pilotAttributeSyntax		439
+pilotObjectClass		440
+pilotGroups		441
+iA5StringSyntax		442
+caseIgnoreIA5StringSyntax		443
+pilotObject		444
+pilotPerson		445
+account		446
+document		447
+room		448
+documentSeries		449
+rFC822localPart		450
+dNSDomain		451
+domainRelatedObject		452
+friendlyCountry		453
+simpleSecurityObject		454
+pilotOrganization		455
+pilotDSA		456
+qualityLabelledData		457
+userId		458
+textEncodedORAddress		459
+rfc822Mailbox		460
+info		461
+favouriteDrink		462
+roomNumber		463
+photo		464
+userClass		465
+host		466
+manager		467
+documentIdentifier		468
+documentTitle		469
+documentVersion		470
+documentAuthor		471
+documentLocation		472
+homeTelephoneNumber		473
+secretary		474
+otherMailbox		475
+lastModifiedTime		476
+lastModifiedBy		477
+aRecord		478
+pilotAttributeType27		479
+mXRecord		480
+nSRecord		481
+sOARecord		482
+cNAMERecord		483
+associatedDomain		484
+associatedName		485
+homePostalAddress		486
+personalTitle		487
+mobileTelephoneNumber		488
+pagerTelephoneNumber		489
+friendlyCountryName		490
+organizationalStatus		491
+janetMailbox		492
+mailPreferenceOption		493
+buildingName		494
+dSAQuality		495
+singleLevelQuality		496
+subtreeMinimumQuality		497
+subtreeMaximumQuality		498
+personalSignature		499
+dITRedirect		500
+audio		501
+documentPublisher		502
+x500UniqueIdentifier		503
+mime_mhs		504
+mime_mhs_headings		505
+mime_mhs_bodies		506
+id_hex_partial_message		507
+id_hex_multipart_message		508
+generationQualifier		509
+pseudonym		510
+InternationalRA		511
+id_set		512
+set_ctype		513
+set_msgExt		514
+set_attr		515
+set_policy		516
+set_certExt		517
+set_brand		518
+setct_PANData		519
+setct_PANToken		520
+setct_PANOnly		521
+setct_OIData		522
+setct_PI		523
+setct_PIData		524
+setct_PIDataUnsigned		525
+setct_HODInput		526
+setct_AuthResBaggage		527
+setct_AuthRevReqBaggage		528
+setct_AuthRevResBaggage		529
+setct_CapTokenSeq		530
+setct_PInitResData		531
+setct_PI_TBS		532
+setct_PResData		533
+setct_AuthReqTBS		534
+setct_AuthResTBS		535
+setct_AuthResTBSX		536
+setct_AuthTokenTBS		537
+setct_CapTokenData		538
+setct_CapTokenTBS		539
+setct_AcqCardCodeMsg		540
+setct_AuthRevReqTBS		541
+setct_AuthRevResData		542
+setct_AuthRevResTBS		543
+setct_CapReqTBS		544
+setct_CapReqTBSX		545
+setct_CapResData		546
+setct_CapRevReqTBS		547
+setct_CapRevReqTBSX		548
+setct_CapRevResData		549
+setct_CredReqTBS		550
+setct_CredReqTBSX		551
+setct_CredResData		552
+setct_CredRevReqTBS		553
+setct_CredRevReqTBSX		554
+setct_CredRevResData		555
+setct_PCertReqData		556
+setct_PCertResTBS		557
+setct_BatchAdminReqData		558
+setct_BatchAdminResData		559
+setct_CardCInitResTBS		560
+setct_MeAqCInitResTBS		561
+setct_RegFormResTBS		562
+setct_CertReqData		563
+setct_CertReqTBS		564
+setct_CertResData		565
+setct_CertInqReqTBS		566
+setct_ErrorTBS		567
+setct_PIDualSignedTBE		568
+setct_PIUnsignedTBE		569
+setct_AuthReqTBE		570
+setct_AuthResTBE		571
+setct_AuthResTBEX		572
+setct_AuthTokenTBE		573
+setct_CapTokenTBE		574
+setct_CapTokenTBEX		575
+setct_AcqCardCodeMsgTBE		576
+setct_AuthRevReqTBE		577
+setct_AuthRevResTBE		578
+setct_AuthRevResTBEB		579
+setct_CapReqTBE		580
+setct_CapReqTBEX		581
+setct_CapResTBE		582
+setct_CapRevReqTBE		583
+setct_CapRevReqTBEX		584
+setct_CapRevResTBE		585
+setct_CredReqTBE		586
+setct_CredReqTBEX		587
+setct_CredResTBE		588
+setct_CredRevReqTBE		589
+setct_CredRevReqTBEX		590
+setct_CredRevResTBE		591
+setct_BatchAdminReqTBE		592
+setct_BatchAdminResTBE		593
+setct_RegFormReqTBE		594
+setct_CertReqTBE		595
+setct_CertReqTBEX		596
+setct_CertResTBE		597
+setct_CRLNotificationTBS		598
+setct_CRLNotificationResTBS		599
+setct_BCIDistributionTBS		600
+setext_genCrypt		601
+setext_miAuth		602
+setext_pinSecure		603
+setext_pinAny		604
+setext_track2		605
+setext_cv		606
+set_policy_root		607
+setCext_hashedRoot		608
+setCext_certType		609
+setCext_merchData		610
+setCext_cCertRequired		611
+setCext_tunneling		612
+setCext_setExt		613
+setCext_setQualf		614
+setCext_PGWYcapabilities		615
+setCext_TokenIdentifier		616
+setCext_Track2Data		617
+setCext_TokenType		618
+setCext_IssuerCapabilities		619
+setAttr_Cert		620
+setAttr_PGWYcap		621
+setAttr_TokenType		622
+setAttr_IssCap		623
+set_rootKeyThumb		624
+set_addPolicy		625
+setAttr_Token_EMV		626
+setAttr_Token_B0Prime		627
+setAttr_IssCap_CVM		628
+setAttr_IssCap_T2		629
+setAttr_IssCap_Sig		630
+setAttr_GenCryptgrm		631
+setAttr_T2Enc		632
+setAttr_T2cleartxt		633
+setAttr_TokICCsig		634
+setAttr_SecDevSig		635
+set_brand_IATA_ATA		636
+set_brand_Diners		637
+set_brand_AmericanExpress		638
+set_brand_JCB		639
+set_brand_Visa		640
+set_brand_MasterCard		641
+set_brand_Novus		642
+des_cdmf		643
+rsaOAEPEncryptionSET		644
+itu_t		645
+joint_iso_itu_t		646
+international_organizations		647
+ms_smartcard_login		648
+ms_upn		649
+aes_128_cfb1		650
+aes_192_cfb1		651
+aes_256_cfb1		652
+aes_128_cfb8		653
+aes_192_cfb8		654
+aes_256_cfb8		655
+des_cfb1		656
+des_cfb8		657
+des_ede3_cfb1		658
+des_ede3_cfb8		659
+streetAddress		660
+postalCode		661
+id_ppl		662
+proxyCertInfo		663
+id_ppl_anyLanguage		664
+id_ppl_inheritAll		665
+name_constraints		666
+Independent		667
+sha256WithRSAEncryption		668
+sha384WithRSAEncryption		669
+sha512WithRSAEncryption		670
+sha224WithRSAEncryption		671
+sha256		672
+sha384		673
+sha512		674
+sha224		675
+identified_organization		676
+certicom_arc		677
+wap		678
+wap_wsg		679
+X9_62_id_characteristic_two_basis		680
+X9_62_onBasis		681
+X9_62_tpBasis		682
+X9_62_ppBasis		683
+X9_62_c2pnb163v1		684
+X9_62_c2pnb163v2		685
+X9_62_c2pnb163v3		686
+X9_62_c2pnb176v1		687
+X9_62_c2tnb191v1		688
+X9_62_c2tnb191v2		689
+X9_62_c2tnb191v3		690
+X9_62_c2onb191v4		691
+X9_62_c2onb191v5		692
+X9_62_c2pnb208w1		693
+X9_62_c2tnb239v1		694
+X9_62_c2tnb239v2		695
+X9_62_c2tnb239v3		696
+X9_62_c2onb239v4		697
+X9_62_c2onb239v5		698
+X9_62_c2pnb272w1		699
+X9_62_c2pnb304w1		700
+X9_62_c2tnb359v1		701
+X9_62_c2pnb368w1		702
+X9_62_c2tnb431r1		703
+secp112r1		704
+secp112r2		705
+secp128r1		706
+secp128r2		707
+secp160k1		708
+secp160r1		709
+secp160r2		710
+secp192k1		711
+secp224k1		712
+secp224r1		713
+secp256k1		714
+secp384r1		715
+secp521r1		716
+sect113r1		717
+sect113r2		718
+sect131r1		719
+sect131r2		720
+sect163k1		721
+sect163r1		722
+sect163r2		723
+sect193r1		724
+sect193r2		725
+sect233k1		726
+sect233r1		727
+sect239k1		728
+sect283k1		729
+sect283r1		730
+sect409k1		731
+sect409r1		732
+sect571k1		733
+sect571r1		734
+wap_wsg_idm_ecid_wtls1		735
+wap_wsg_idm_ecid_wtls3		736
+wap_wsg_idm_ecid_wtls4		737
+wap_wsg_idm_ecid_wtls5		738
+wap_wsg_idm_ecid_wtls6		739
+wap_wsg_idm_ecid_wtls7		740
+wap_wsg_idm_ecid_wtls8		741
+wap_wsg_idm_ecid_wtls9		742
+wap_wsg_idm_ecid_wtls10		743
+wap_wsg_idm_ecid_wtls11		744
+wap_wsg_idm_ecid_wtls12		745
+any_policy		746
+policy_mappings		747
+inhibit_any_policy		748
+ipsec3		749
+ipsec4		750
+camellia_128_cbc		751
+camellia_192_cbc		752
+camellia_256_cbc		753
+camellia_128_ecb		754
+camellia_192_ecb		755
+camellia_256_ecb		756
+camellia_128_cfb128		757
+camellia_192_cfb128		758
+camellia_256_cfb128		759
+camellia_128_cfb1		760
+camellia_192_cfb1		761
+camellia_256_cfb1		762
+camellia_128_cfb8		763
+camellia_192_cfb8		764
+camellia_256_cfb8		765
+camellia_128_ofb128		766
+camellia_192_ofb128		767
+camellia_256_ofb128		768
+subject_directory_attributes		769
+issuing_distribution_point		770
+certificate_issuer		771
+korea		772
+kisa		773
+kftc		774
+npki_alg		775
+seed_ecb		776
+seed_cbc		777
+seed_ofb128		778
+seed_cfb128		779
+hmac_md5		780
+hmac_sha1		781
+id_PasswordBasedMAC		782
+id_DHBasedMac		783
+id_it_suppLangTags		784
+caRepository		785
+id_smime_ct_compressedData		786
+id_ct_asciiTextWithCRLF		787
+id_aes128_wrap		788
+id_aes192_wrap		789
+id_aes256_wrap		790
+ecdsa_with_Recommended		791
+ecdsa_with_Specified		792
+ecdsa_with_SHA224		793
+ecdsa_with_SHA256		794
+ecdsa_with_SHA384		795
+ecdsa_with_SHA512		796
+hmacWithMD5		797
+hmacWithSHA224		798
+hmacWithSHA256		799
+hmacWithSHA384		800
+hmacWithSHA512		801
+dsa_with_SHA224		802
+dsa_with_SHA256		803
+whirlpool		804
+cryptopro		805
+cryptocom		806
+id_GostR3411_94_with_GostR3410_2001		807
+id_GostR3411_94_with_GostR3410_94		808
+id_GostR3411_94		809
+id_HMACGostR3411_94		810
+id_GostR3410_2001		811
+id_GostR3410_94		812
+id_Gost28147_89		813
+gost89_cnt		814
+id_Gost28147_89_MAC		815
+id_GostR3411_94_prf		816
+id_GostR3410_2001DH		817
+id_GostR3410_94DH		818
+id_Gost28147_89_CryptoPro_KeyMeshing		819
+id_Gost28147_89_None_KeyMeshing		820
+id_GostR3411_94_TestParamSet		821
+id_GostR3411_94_CryptoProParamSet		822
+id_Gost28147_89_TestParamSet		823
+id_Gost28147_89_CryptoPro_A_ParamSet		824
+id_Gost28147_89_CryptoPro_B_ParamSet		825
+id_Gost28147_89_CryptoPro_C_ParamSet		826
+id_Gost28147_89_CryptoPro_D_ParamSet		827
+id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet		828
+id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet		829
+id_Gost28147_89_CryptoPro_RIC_1_ParamSet		830
+id_GostR3410_94_TestParamSet		831
+id_GostR3410_94_CryptoPro_A_ParamSet		832
+id_GostR3410_94_CryptoPro_B_ParamSet		833
+id_GostR3410_94_CryptoPro_C_ParamSet		834
+id_GostR3410_94_CryptoPro_D_ParamSet		835
+id_GostR3410_94_CryptoPro_XchA_ParamSet		836
+id_GostR3410_94_CryptoPro_XchB_ParamSet		837
+id_GostR3410_94_CryptoPro_XchC_ParamSet		838
+id_GostR3410_2001_TestParamSet		839
+id_GostR3410_2001_CryptoPro_A_ParamSet		840
+id_GostR3410_2001_CryptoPro_B_ParamSet		841
+id_GostR3410_2001_CryptoPro_C_ParamSet		842
+id_GostR3410_2001_CryptoPro_XchA_ParamSet		843
+id_GostR3410_2001_CryptoPro_XchB_ParamSet		844
+id_GostR3410_94_a		845
+id_GostR3410_94_aBis		846
+id_GostR3410_94_b		847
+id_GostR3410_94_bBis		848
+id_Gost28147_89_cc		849
+id_GostR3410_94_cc		850
+id_GostR3410_2001_cc		851
+id_GostR3411_94_with_GostR3410_94_cc		852
+id_GostR3411_94_with_GostR3410_2001_cc		853
+id_GostR3410_2001_ParamSet_cc		854
+hmac		855
+LocalKeySet		856
+freshest_crl		857
+id_on_permanentIdentifier		858
+searchGuide		859
+businessCategory		860
+postalAddress		861
+postOfficeBox		862
+physicalDeliveryOfficeName		863
+telephoneNumber		864
+telexNumber		865
+teletexTerminalIdentifier		866
+facsimileTelephoneNumber		867
+x121Address		868
+internationaliSDNNumber		869
+registeredAddress		870
+destinationIndicator		871
+preferredDeliveryMethod		872
+presentationAddress		873
+supportedApplicationContext		874
+member		875
+owner		876
+roleOccupant		877
+seeAlso		878
+userPassword		879
+userCertificate		880
+cACertificate		881
+authorityRevocationList		882
+certificateRevocationList		883
+crossCertificatePair		884
+enhancedSearchGuide		885
+protocolInformation		886
+distinguishedName		887
+uniqueMember		888
+houseIdentifier		889
+supportedAlgorithms		890
+deltaRevocationList		891
+dmdName		892
diff --git a/openssl/crypto/objects/obj_xref.c b/openssl/crypto/objects/obj_xref.c
new file mode 100644
index 0000000..152eca5
--- /dev/null
+++ b/openssl/crypto/objects/obj_xref.c
@@ -0,0 +1,231 @@
+/* crypto/objects/obj_xref.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/objects.h>
+#include "obj_xref.h"
+
+DECLARE_STACK_OF(nid_triple)
+STACK_OF(nid_triple) *sig_app, *sigx_app;
+
+static int sig_cmp(const nid_triple *a, const nid_triple *b)
+	{
+	return a->sign_id - b->sign_id;
+	}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig);
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig);
+
+static int sig_sk_cmp(const nid_triple * const *a, const nid_triple * const *b)
+	{
+	return (*a)->sign_id - (*b)->sign_id;
+	}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx);
+
+static int sigx_cmp(const nid_triple * const *a, const nid_triple * const *b)
+	{
+	int ret;
+	ret = (*a)->hash_id - (*b)->hash_id;
+	if (ret)
+		return ret;
+	return (*a)->pkey_id - (*b)->pkey_id;
+	}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx);
+
+int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid)
+	{
+	nid_triple tmp;
+	const nid_triple *rv = NULL;
+	tmp.sign_id = signid;
+
+	if (sig_app)
+		{
+		int idx = sk_nid_triple_find(sig_app, &tmp);
+		if (idx >= 0)
+			rv = sk_nid_triple_value(sig_app, idx);
+		}
+
+#ifndef OBJ_XREF_TEST2
+	if (rv == NULL)
+		{
+		rv = OBJ_bsearch_sig(&tmp, sigoid_srt,
+				 sizeof(sigoid_srt) / sizeof(nid_triple));
+		}
+#endif
+	if (rv == NULL)
+		return 0;
+	*pdig_nid = rv->hash_id;
+	*ppkey_nid = rv->pkey_id;
+	return 1;
+	}
+
+int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid)
+	{
+	nid_triple tmp;
+	const nid_triple *t=&tmp;
+	const nid_triple **rv = NULL;
+
+	tmp.hash_id = dig_nid;
+	tmp.pkey_id = pkey_nid;
+
+	if (sigx_app)
+		{
+		int idx = sk_nid_triple_find(sigx_app, &tmp);
+		if (idx >= 0)
+			{
+			t = sk_nid_triple_value(sigx_app, idx);
+			rv = &t;
+			}
+		}
+
+#ifndef OBJ_XREF_TEST2
+	if (rv == NULL)
+		{
+		rv = OBJ_bsearch_sigx(&t, sigoid_srt_xref,
+				 sizeof(sigoid_srt_xref) / sizeof(nid_triple *)
+				 );
+		}
+#endif
+	if (rv == NULL)
+		return 0;
+	*psignid = (*rv)->sign_id;
+	return 1;
+	}
+
+int OBJ_add_sigid(int signid, int dig_id, int pkey_id)
+	{
+	nid_triple *ntr;
+	if (!sig_app)
+		sig_app = sk_nid_triple_new(sig_sk_cmp);
+	if (!sig_app)
+		return 0;
+	if (!sigx_app)
+		sigx_app = sk_nid_triple_new(sigx_cmp);
+	if (!sigx_app)
+		return 0;
+	ntr = OPENSSL_malloc(sizeof(int) * 3);
+	if (!ntr)
+		return 0;
+	ntr->sign_id = signid;
+	ntr->hash_id = dig_id;
+	ntr->pkey_id = pkey_id;
+
+	if (!sk_nid_triple_push(sig_app, ntr))
+		{
+		OPENSSL_free(ntr);
+		return 0;
+		}
+
+	if (!sk_nid_triple_push(sigx_app, ntr))
+		return 0;
+
+	sk_nid_triple_sort(sig_app);
+	sk_nid_triple_sort(sigx_app);
+
+	return 1;
+	}
+
+static void sid_free(nid_triple *tt)
+	{
+	OPENSSL_free(tt);
+	}
+
+void OBJ_sigid_free(void)
+	{
+	if (sig_app)
+		{
+		sk_nid_triple_pop_free(sig_app, sid_free);
+		sig_app = NULL;
+		}
+	if (sigx_app)
+		{
+		sk_nid_triple_free(sigx_app);
+		sigx_app = NULL;
+		}
+	}
+		
+#ifdef OBJ_XREF_TEST
+
+main()
+	{
+	int n1, n2, n3;
+
+	int i, rv;
+#ifdef OBJ_XREF_TEST2
+	for (i = 0; i <	sizeof(sigoid_srt) / sizeof(nid_triple); i++)
+		{
+		OBJ_add_sigid(sigoid_srt[i][0], sigoid_srt[i][1],
+				sigoid_srt[i][2]);
+		}
+#endif
+
+	for (i = 0; i <	sizeof(sigoid_srt) / sizeof(nid_triple); i++)
+		{
+		n1 = sigoid_srt[i][0];
+		rv = OBJ_find_sigid_algs(n1, &n2, &n3);
+		printf("Forward: %d, %s %s %s\n", rv,
+			OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3));
+		n1=0;
+		rv = OBJ_find_sigid_by_algs(&n1, n2, n3);
+		printf("Reverse: %d, %s %s %s\n", rv,
+			OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3));
+		}
+	}
+	
+#endif
diff --git a/openssl/crypto/objects/obj_xref.h b/openssl/crypto/objects/obj_xref.h
new file mode 100644
index 0000000..d5b9b8e
--- /dev/null
+++ b/openssl/crypto/objects/obj_xref.h
@@ -0,0 +1,75 @@
+/* AUTOGENERATED BY objxref.pl, DO NOT EDIT */
+
+typedef struct
+	{
+	int sign_id;
+	int hash_id;
+	int pkey_id;
+	} nid_triple;
+
+static const nid_triple sigoid_srt[] =
+	{
+	{NID_md2WithRSAEncryption, NID_md2, NID_rsaEncryption},
+	{NID_md5WithRSAEncryption, NID_md5, NID_rsaEncryption},
+	{NID_shaWithRSAEncryption, NID_sha, NID_rsaEncryption},
+	{NID_sha1WithRSAEncryption, NID_sha1, NID_rsaEncryption},
+	{NID_dsaWithSHA, NID_sha, NID_dsa},
+	{NID_dsaWithSHA1_2, NID_sha1, NID_dsa_2},
+	{NID_mdc2WithRSA, NID_mdc2, NID_rsaEncryption},
+	{NID_md5WithRSA, NID_md5, NID_rsa},
+	{NID_dsaWithSHA1, NID_sha1, NID_dsa},
+	{NID_sha1WithRSA, NID_sha1, NID_rsa},
+	{NID_ripemd160WithRSA, NID_ripemd160, NID_rsaEncryption},
+	{NID_md4WithRSAEncryption, NID_md4, NID_rsaEncryption},
+	{NID_ecdsa_with_SHA1, NID_sha1, NID_X9_62_id_ecPublicKey},
+	{NID_sha256WithRSAEncryption, NID_sha256, NID_rsaEncryption},
+	{NID_sha384WithRSAEncryption, NID_sha384, NID_rsaEncryption},
+	{NID_sha512WithRSAEncryption, NID_sha512, NID_rsaEncryption},
+	{NID_sha224WithRSAEncryption, NID_sha224, NID_rsaEncryption},
+	{NID_ecdsa_with_Recommended, NID_undef, NID_X9_62_id_ecPublicKey},
+	{NID_ecdsa_with_Specified, NID_undef, NID_X9_62_id_ecPublicKey},
+	{NID_ecdsa_with_SHA224, NID_sha224, NID_X9_62_id_ecPublicKey},
+	{NID_ecdsa_with_SHA256, NID_sha256, NID_X9_62_id_ecPublicKey},
+	{NID_ecdsa_with_SHA384, NID_sha384, NID_X9_62_id_ecPublicKey},
+	{NID_ecdsa_with_SHA512, NID_sha512, NID_X9_62_id_ecPublicKey},
+	{NID_dsa_with_SHA224, NID_sha224, NID_dsa},
+	{NID_dsa_with_SHA256, NID_sha256, NID_dsa},
+	{NID_id_GostR3411_94_with_GostR3410_2001, NID_id_GostR3411_94, NID_id_GostR3410_2001},
+	{NID_id_GostR3411_94_with_GostR3410_94, NID_id_GostR3411_94, NID_id_GostR3410_94},
+	{NID_id_GostR3411_94_with_GostR3410_94_cc, NID_id_GostR3411_94, NID_id_GostR3410_94_cc},
+	{NID_id_GostR3411_94_with_GostR3410_2001_cc, NID_id_GostR3411_94, NID_id_GostR3410_2001_cc},
+	};
+
+static const nid_triple * const sigoid_srt_xref[] =
+	{
+	&sigoid_srt[17],
+	&sigoid_srt[18],
+	&sigoid_srt[0],
+	&sigoid_srt[1],
+	&sigoid_srt[7],
+	&sigoid_srt[2],
+	&sigoid_srt[4],
+	&sigoid_srt[3],
+	&sigoid_srt[9],
+	&sigoid_srt[5],
+	&sigoid_srt[8],
+	&sigoid_srt[12],
+	&sigoid_srt[6],
+	&sigoid_srt[10],
+	&sigoid_srt[11],
+	&sigoid_srt[13],
+	&sigoid_srt[24],
+	&sigoid_srt[20],
+	&sigoid_srt[14],
+	&sigoid_srt[21],
+	&sigoid_srt[15],
+	&sigoid_srt[22],
+	&sigoid_srt[16],
+	&sigoid_srt[23],
+	&sigoid_srt[19],
+	&sigoid_srt[25],
+	&sigoid_srt[26],
+	&sigoid_srt[27],
+	&sigoid_srt[28],
+	};
+
diff --git a/openssl/crypto/objects/obj_xref.txt b/openssl/crypto/objects/obj_xref.txt
new file mode 100644
index 0000000..e45b3d3
--- /dev/null
+++ b/openssl/crypto/objects/obj_xref.txt
@@ -0,0 +1,42 @@
+# OID cross reference table.
+# Links signatures OIDs to their corresponding public key algorithms
+# and digests.
+
+md2WithRSAEncryption	md2	rsaEncryption
+md5WithRSAEncryption	md5	rsaEncryption
+shaWithRSAEncryption	sha	rsaEncryption
+sha1WithRSAEncryption	sha1	rsaEncryption
+md4WithRSAEncryption	md4	rsaEncryption
+sha256WithRSAEncryption sha256	rsaEncryption
+sha384WithRSAEncryption	sha384	rsaEncryption
+sha512WithRSAEncryption	sha512	rsaEncryption
+sha224WithRSAEncryption	sha224	rsaEncryption
+mdc2WithRSA		mdc2	rsaEncryption
+ripemd160WithRSA	ripemd160 rsaEncryption
+
+# Alternative deprecated OIDs. By using the older "rsa" OID this
+# type will be recognized by not normally used.
+
+md5WithRSA		md5	rsa
+sha1WithRSA		sha1	rsa
+
+dsaWithSHA		sha	dsa
+dsaWithSHA1		sha1	dsa
+
+dsaWithSHA1_2		sha1	dsa_2
+
+ecdsa_with_SHA1		sha1	X9_62_id_ecPublicKey
+ecdsa_with_SHA224	sha224	X9_62_id_ecPublicKey
+ecdsa_with_SHA256	sha256	X9_62_id_ecPublicKey
+ecdsa_with_SHA384	sha384	X9_62_id_ecPublicKey
+ecdsa_with_SHA512	sha512	X9_62_id_ecPublicKey
+ecdsa_with_Recommended	undef	X9_62_id_ecPublicKey
+ecdsa_with_Specified	undef	X9_62_id_ecPublicKey
+
+dsa_with_SHA224		sha224	dsa
+dsa_with_SHA256		sha256	dsa
+
+id_GostR3411_94_with_GostR3410_2001	id_GostR3411_94 id_GostR3410_2001
+id_GostR3411_94_with_GostR3410_94	id_GostR3411_94 id_GostR3410_94
+id_GostR3411_94_with_GostR3410_94_cc	id_GostR3411_94 id_GostR3410_94_cc
+id_GostR3411_94_with_GostR3410_2001_cc	id_GostR3411_94 id_GostR3410_2001_cc
diff --git a/openssl/crypto/objects/objects.README b/openssl/crypto/objects/objects.README
new file mode 100644
index 0000000..4d74550
--- /dev/null
+++ b/openssl/crypto/objects/objects.README
@@ -0,0 +1,44 @@
+objects.txt syntax
+------------------
+
+To cover all the naming hacks that were previously in objects.h needed some
+kind of hacks in objects.txt.
+
+The basic syntax for adding an object is as follows:
+
+	1 2 3 4		: shortName	: Long Name
+
+		If the long name doesn't contain spaces, or no short name
+		exists, the long name is used as basis for the base name
+		in C.  Otherwise, the short name is used.
+
+		The base name (let's call it 'base') will then be used to
+		create the C macros SN_base, LN_base, NID_base and OBJ_base.
+
+		Note that if the base name contains spaces, dashes or periods,
+		those will be converte to underscore.
+
+Then there are some extra commands:
+
+	!Alias foo 1 2 3 4
+
+		This juts makes a name foo for an OID.  The C macro
+		OBJ_foo will be created as a result.
+
+	!Cname foo
+
+		This makes sure that the name foo will be used as base name
+		in C.
+
+	!module foo
+	1 2 3 4		: shortName	: Long Name
+	!global
+
+		The !module command was meant to define a kind of modularity.
+		What it does is to make sure the module name is prepended
+		to the base name.  !global turns this off.  This construction
+		is not recursive.
+
+Lines starting with # are treated as comments, as well as any line starting
+with ! and not matching the commands above.
+
diff --git a/openssl/crypto/objects/objects.h b/openssl/crypto/objects/objects.h
new file mode 100644
index 0000000..bd0ee52
--- /dev/null
+++ b/openssl/crypto/objects/objects.h
@@ -0,0 +1,1138 @@
+/* crypto/objects/objects.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_OBJECTS_H
+#define HEADER_OBJECTS_H
+
+#define USE_OBJ_MAC
+
+#ifdef USE_OBJ_MAC
+#include <openssl/obj_mac.h>
+#else
+#define SN_undef			"UNDEF"
+#define LN_undef			"undefined"
+#define NID_undef			0
+#define OBJ_undef			0L
+
+#define SN_Algorithm			"Algorithm"
+#define LN_algorithm			"algorithm"
+#define NID_algorithm			38
+#define OBJ_algorithm			1L,3L,14L,3L,2L
+
+#define LN_rsadsi			"rsadsi"
+#define NID_rsadsi			1
+#define OBJ_rsadsi			1L,2L,840L,113549L
+
+#define LN_pkcs				"pkcs"
+#define NID_pkcs			2
+#define OBJ_pkcs			OBJ_rsadsi,1L
+
+#define SN_md2				"MD2"
+#define LN_md2				"md2"
+#define NID_md2				3
+#define OBJ_md2				OBJ_rsadsi,2L,2L
+
+#define SN_md5				"MD5"
+#define LN_md5				"md5"
+#define NID_md5				4
+#define OBJ_md5				OBJ_rsadsi,2L,5L
+
+#define SN_rc4				"RC4"
+#define LN_rc4				"rc4"
+#define NID_rc4				5
+#define OBJ_rc4				OBJ_rsadsi,3L,4L
+
+#define LN_rsaEncryption		"rsaEncryption"
+#define NID_rsaEncryption		6
+#define OBJ_rsaEncryption		OBJ_pkcs,1L,1L
+
+#define SN_md2WithRSAEncryption		"RSA-MD2"
+#define LN_md2WithRSAEncryption		"md2WithRSAEncryption"
+#define NID_md2WithRSAEncryption	7
+#define OBJ_md2WithRSAEncryption	OBJ_pkcs,1L,2L
+
+#define SN_md5WithRSAEncryption		"RSA-MD5"
+#define LN_md5WithRSAEncryption		"md5WithRSAEncryption"
+#define NID_md5WithRSAEncryption	8
+#define OBJ_md5WithRSAEncryption	OBJ_pkcs,1L,4L
+
+#define SN_pbeWithMD2AndDES_CBC		"PBE-MD2-DES"
+#define LN_pbeWithMD2AndDES_CBC		"pbeWithMD2AndDES-CBC"
+#define NID_pbeWithMD2AndDES_CBC	9
+#define OBJ_pbeWithMD2AndDES_CBC	OBJ_pkcs,5L,1L
+
+#define SN_pbeWithMD5AndDES_CBC		"PBE-MD5-DES"
+#define LN_pbeWithMD5AndDES_CBC		"pbeWithMD5AndDES-CBC"
+#define NID_pbeWithMD5AndDES_CBC	10
+#define OBJ_pbeWithMD5AndDES_CBC	OBJ_pkcs,5L,3L
+
+#define LN_X500				"X500"
+#define NID_X500			11
+#define OBJ_X500			2L,5L
+
+#define LN_X509				"X509"
+#define NID_X509			12
+#define OBJ_X509			OBJ_X500,4L
+
+#define SN_commonName			"CN"
+#define LN_commonName			"commonName"
+#define NID_commonName			13
+#define OBJ_commonName			OBJ_X509,3L
+
+#define SN_countryName			"C"
+#define LN_countryName			"countryName"
+#define NID_countryName			14
+#define OBJ_countryName			OBJ_X509,6L
+
+#define SN_localityName			"L"
+#define LN_localityName			"localityName"
+#define NID_localityName		15
+#define OBJ_localityName		OBJ_X509,7L
+
+/* Postal Address? PA */
+
+/* should be "ST" (rfc1327) but MS uses 'S' */
+#define SN_stateOrProvinceName		"ST"
+#define LN_stateOrProvinceName		"stateOrProvinceName"
+#define NID_stateOrProvinceName		16
+#define OBJ_stateOrProvinceName		OBJ_X509,8L
+
+#define SN_organizationName		"O"
+#define LN_organizationName		"organizationName"
+#define NID_organizationName		17
+#define OBJ_organizationName		OBJ_X509,10L
+
+#define SN_organizationalUnitName	"OU"
+#define LN_organizationalUnitName	"organizationalUnitName"
+#define NID_organizationalUnitName	18
+#define OBJ_organizationalUnitName	OBJ_X509,11L
+
+#define SN_rsa				"RSA"
+#define LN_rsa				"rsa"
+#define NID_rsa				19
+#define OBJ_rsa				OBJ_X500,8L,1L,1L
+
+#define LN_pkcs7			"pkcs7"
+#define NID_pkcs7			20
+#define OBJ_pkcs7			OBJ_pkcs,7L
+
+#define LN_pkcs7_data			"pkcs7-data"
+#define NID_pkcs7_data			21
+#define OBJ_pkcs7_data			OBJ_pkcs7,1L
+
+#define LN_pkcs7_signed			"pkcs7-signedData"
+#define NID_pkcs7_signed		22
+#define OBJ_pkcs7_signed		OBJ_pkcs7,2L
+
+#define LN_pkcs7_enveloped		"pkcs7-envelopedData"
+#define NID_pkcs7_enveloped		23
+#define OBJ_pkcs7_enveloped		OBJ_pkcs7,3L
+
+#define LN_pkcs7_signedAndEnveloped	"pkcs7-signedAndEnvelopedData"
+#define NID_pkcs7_signedAndEnveloped	24
+#define OBJ_pkcs7_signedAndEnveloped	OBJ_pkcs7,4L
+
+#define LN_pkcs7_digest			"pkcs7-digestData"
+#define NID_pkcs7_digest		25
+#define OBJ_pkcs7_digest		OBJ_pkcs7,5L
+
+#define LN_pkcs7_encrypted		"pkcs7-encryptedData"
+#define NID_pkcs7_encrypted		26
+#define OBJ_pkcs7_encrypted		OBJ_pkcs7,6L
+
+#define LN_pkcs3			"pkcs3"
+#define NID_pkcs3			27
+#define OBJ_pkcs3			OBJ_pkcs,3L
+
+#define LN_dhKeyAgreement		"dhKeyAgreement"
+#define NID_dhKeyAgreement		28
+#define OBJ_dhKeyAgreement		OBJ_pkcs3,1L
+
+#define SN_des_ecb			"DES-ECB"
+#define LN_des_ecb			"des-ecb"
+#define NID_des_ecb			29
+#define OBJ_des_ecb			OBJ_algorithm,6L
+
+#define SN_des_cfb64			"DES-CFB"
+#define LN_des_cfb64			"des-cfb"
+#define NID_des_cfb64			30
+/* IV + num */
+#define OBJ_des_cfb64			OBJ_algorithm,9L
+
+#define SN_des_cbc			"DES-CBC"
+#define LN_des_cbc			"des-cbc"
+#define NID_des_cbc			31
+/* IV */
+#define OBJ_des_cbc			OBJ_algorithm,7L
+
+#define SN_des_ede			"DES-EDE"
+#define LN_des_ede			"des-ede"
+#define NID_des_ede			32
+/* ?? */
+#define OBJ_des_ede			OBJ_algorithm,17L
+
+#define SN_des_ede3			"DES-EDE3"
+#define LN_des_ede3			"des-ede3"
+#define NID_des_ede3			33
+
+#define SN_idea_cbc			"IDEA-CBC"
+#define LN_idea_cbc			"idea-cbc"
+#define NID_idea_cbc			34
+#define OBJ_idea_cbc			1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
+
+#define SN_idea_cfb64			"IDEA-CFB"
+#define LN_idea_cfb64			"idea-cfb"
+#define NID_idea_cfb64			35
+
+#define SN_idea_ecb			"IDEA-ECB"
+#define LN_idea_ecb			"idea-ecb"
+#define NID_idea_ecb			36
+
+#define SN_rc2_cbc			"RC2-CBC"
+#define LN_rc2_cbc			"rc2-cbc"
+#define NID_rc2_cbc			37
+#define OBJ_rc2_cbc			OBJ_rsadsi,3L,2L
+
+#define SN_rc2_ecb			"RC2-ECB"
+#define LN_rc2_ecb			"rc2-ecb"
+#define NID_rc2_ecb			38
+
+#define SN_rc2_cfb64			"RC2-CFB"
+#define LN_rc2_cfb64			"rc2-cfb"
+#define NID_rc2_cfb64			39
+
+#define SN_rc2_ofb64			"RC2-OFB"
+#define LN_rc2_ofb64			"rc2-ofb"
+#define NID_rc2_ofb64			40
+
+#define SN_sha				"SHA"
+#define LN_sha				"sha"
+#define NID_sha				41
+#define OBJ_sha				OBJ_algorithm,18L
+
+#define SN_shaWithRSAEncryption		"RSA-SHA"
+#define LN_shaWithRSAEncryption		"shaWithRSAEncryption"
+#define NID_shaWithRSAEncryption	42
+#define OBJ_shaWithRSAEncryption	OBJ_algorithm,15L
+
+#define SN_des_ede_cbc			"DES-EDE-CBC"
+#define LN_des_ede_cbc			"des-ede-cbc"
+#define NID_des_ede_cbc			43
+
+#define SN_des_ede3_cbc			"DES-EDE3-CBC"
+#define LN_des_ede3_cbc			"des-ede3-cbc"
+#define NID_des_ede3_cbc		44
+#define OBJ_des_ede3_cbc		OBJ_rsadsi,3L,7L
+
+#define SN_des_ofb64			"DES-OFB"
+#define LN_des_ofb64			"des-ofb"
+#define NID_des_ofb64			45
+#define OBJ_des_ofb64			OBJ_algorithm,8L
+
+#define SN_idea_ofb64			"IDEA-OFB"
+#define LN_idea_ofb64			"idea-ofb"
+#define NID_idea_ofb64			46
+
+#define LN_pkcs9			"pkcs9"
+#define NID_pkcs9			47
+#define OBJ_pkcs9			OBJ_pkcs,9L
+
+#define SN_pkcs9_emailAddress		"Email"
+#define LN_pkcs9_emailAddress		"emailAddress"
+#define NID_pkcs9_emailAddress		48
+#define OBJ_pkcs9_emailAddress		OBJ_pkcs9,1L
+
+#define LN_pkcs9_unstructuredName	"unstructuredName"
+#define NID_pkcs9_unstructuredName	49
+#define OBJ_pkcs9_unstructuredName	OBJ_pkcs9,2L
+
+#define LN_pkcs9_contentType		"contentType"
+#define NID_pkcs9_contentType		50
+#define OBJ_pkcs9_contentType		OBJ_pkcs9,3L
+
+#define LN_pkcs9_messageDigest		"messageDigest"
+#define NID_pkcs9_messageDigest		51
+#define OBJ_pkcs9_messageDigest		OBJ_pkcs9,4L
+
+#define LN_pkcs9_signingTime		"signingTime"
+#define NID_pkcs9_signingTime		52
+#define OBJ_pkcs9_signingTime		OBJ_pkcs9,5L
+
+#define LN_pkcs9_countersignature	"countersignature"
+#define NID_pkcs9_countersignature	53
+#define OBJ_pkcs9_countersignature	OBJ_pkcs9,6L
+
+#define LN_pkcs9_challengePassword	"challengePassword"
+#define NID_pkcs9_challengePassword	54
+#define OBJ_pkcs9_challengePassword	OBJ_pkcs9,7L
+
+#define LN_pkcs9_unstructuredAddress	"unstructuredAddress"
+#define NID_pkcs9_unstructuredAddress	55
+#define OBJ_pkcs9_unstructuredAddress	OBJ_pkcs9,8L
+
+#define LN_pkcs9_extCertAttributes	"extendedCertificateAttributes"
+#define NID_pkcs9_extCertAttributes	56
+#define OBJ_pkcs9_extCertAttributes	OBJ_pkcs9,9L
+
+#define SN_netscape			"Netscape"
+#define LN_netscape			"Netscape Communications Corp."
+#define NID_netscape			57
+#define OBJ_netscape			2L,16L,840L,1L,113730L
+
+#define SN_netscape_cert_extension	"nsCertExt"
+#define LN_netscape_cert_extension	"Netscape Certificate Extension"
+#define NID_netscape_cert_extension	58
+#define OBJ_netscape_cert_extension	OBJ_netscape,1L
+
+#define SN_netscape_data_type		"nsDataType"
+#define LN_netscape_data_type		"Netscape Data Type"
+#define NID_netscape_data_type		59
+#define OBJ_netscape_data_type		OBJ_netscape,2L
+
+#define SN_des_ede_cfb64		"DES-EDE-CFB"
+#define LN_des_ede_cfb64		"des-ede-cfb"
+#define NID_des_ede_cfb64		60
+
+#define SN_des_ede3_cfb64		"DES-EDE3-CFB"
+#define LN_des_ede3_cfb64		"des-ede3-cfb"
+#define NID_des_ede3_cfb64		61
+
+#define SN_des_ede_ofb64		"DES-EDE-OFB"
+#define LN_des_ede_ofb64		"des-ede-ofb"
+#define NID_des_ede_ofb64		62
+
+#define SN_des_ede3_ofb64		"DES-EDE3-OFB"
+#define LN_des_ede3_ofb64		"des-ede3-ofb"
+#define NID_des_ede3_ofb64		63
+
+/* I'm not sure about the object ID */
+#define SN_sha1				"SHA1"
+#define LN_sha1				"sha1"
+#define NID_sha1			64
+#define OBJ_sha1			OBJ_algorithm,26L
+/* 28 Jun 1996 - eay */
+/* #define OBJ_sha1			1L,3L,14L,2L,26L,05L <- wrong */
+
+#define SN_sha1WithRSAEncryption	"RSA-SHA1"
+#define LN_sha1WithRSAEncryption	"sha1WithRSAEncryption"
+#define NID_sha1WithRSAEncryption	65
+#define OBJ_sha1WithRSAEncryption	OBJ_pkcs,1L,5L
+
+#define SN_dsaWithSHA			"DSA-SHA"
+#define LN_dsaWithSHA			"dsaWithSHA"
+#define NID_dsaWithSHA			66
+#define OBJ_dsaWithSHA			OBJ_algorithm,13L
+
+#define SN_dsa_2			"DSA-old"
+#define LN_dsa_2			"dsaEncryption-old"
+#define NID_dsa_2			67
+#define OBJ_dsa_2			OBJ_algorithm,12L
+
+/* proposed by microsoft to RSA */
+#define SN_pbeWithSHA1AndRC2_CBC	"PBE-SHA1-RC2-64"
+#define LN_pbeWithSHA1AndRC2_CBC	"pbeWithSHA1AndRC2-CBC"
+#define NID_pbeWithSHA1AndRC2_CBC	68
+#define OBJ_pbeWithSHA1AndRC2_CBC	OBJ_pkcs,5L,11L 
+
+/* proposed by microsoft to RSA as pbeWithSHA1AndRC4: it is now
+ * defined explicitly in PKCS#5 v2.0 as id-PBKDF2 which is something
+ * completely different.
+ */
+#define LN_id_pbkdf2			"PBKDF2"
+#define NID_id_pbkdf2			69
+#define OBJ_id_pbkdf2			OBJ_pkcs,5L,12L 
+
+#define SN_dsaWithSHA1_2		"DSA-SHA1-old"
+#define LN_dsaWithSHA1_2		"dsaWithSHA1-old"
+#define NID_dsaWithSHA1_2		70
+/* Got this one from 'sdn706r20.pdf' which is actually an NSA document :-) */
+#define OBJ_dsaWithSHA1_2		OBJ_algorithm,27L
+
+#define SN_netscape_cert_type		"nsCertType"
+#define LN_netscape_cert_type		"Netscape Cert Type"
+#define NID_netscape_cert_type		71
+#define OBJ_netscape_cert_type		OBJ_netscape_cert_extension,1L
+
+#define SN_netscape_base_url		"nsBaseUrl"
+#define LN_netscape_base_url		"Netscape Base Url"
+#define NID_netscape_base_url		72
+#define OBJ_netscape_base_url		OBJ_netscape_cert_extension,2L
+
+#define SN_netscape_revocation_url	"nsRevocationUrl"
+#define LN_netscape_revocation_url	"Netscape Revocation Url"
+#define NID_netscape_revocation_url	73
+#define OBJ_netscape_revocation_url	OBJ_netscape_cert_extension,3L
+
+#define SN_netscape_ca_revocation_url	"nsCaRevocationUrl"
+#define LN_netscape_ca_revocation_url	"Netscape CA Revocation Url"
+#define NID_netscape_ca_revocation_url	74
+#define OBJ_netscape_ca_revocation_url	OBJ_netscape_cert_extension,4L
+
+#define SN_netscape_renewal_url		"nsRenewalUrl"
+#define LN_netscape_renewal_url		"Netscape Renewal Url"
+#define NID_netscape_renewal_url	75
+#define OBJ_netscape_renewal_url	OBJ_netscape_cert_extension,7L
+
+#define SN_netscape_ca_policy_url	"nsCaPolicyUrl"
+#define LN_netscape_ca_policy_url	"Netscape CA Policy Url"
+#define NID_netscape_ca_policy_url	76
+#define OBJ_netscape_ca_policy_url	OBJ_netscape_cert_extension,8L
+
+#define SN_netscape_ssl_server_name	"nsSslServerName"
+#define LN_netscape_ssl_server_name	"Netscape SSL Server Name"
+#define NID_netscape_ssl_server_name	77
+#define OBJ_netscape_ssl_server_name	OBJ_netscape_cert_extension,12L
+
+#define SN_netscape_comment		"nsComment"
+#define LN_netscape_comment		"Netscape Comment"
+#define NID_netscape_comment		78
+#define OBJ_netscape_comment		OBJ_netscape_cert_extension,13L
+
+#define SN_netscape_cert_sequence	"nsCertSequence"
+#define LN_netscape_cert_sequence	"Netscape Certificate Sequence"
+#define NID_netscape_cert_sequence	79
+#define OBJ_netscape_cert_sequence	OBJ_netscape_data_type,5L
+
+#define SN_desx_cbc			"DESX-CBC"
+#define LN_desx_cbc			"desx-cbc"
+#define NID_desx_cbc			80
+
+#define SN_id_ce			"id-ce"
+#define NID_id_ce			81
+#define OBJ_id_ce			2L,5L,29L
+
+#define SN_subject_key_identifier	"subjectKeyIdentifier"
+#define LN_subject_key_identifier	"X509v3 Subject Key Identifier"
+#define NID_subject_key_identifier	82
+#define OBJ_subject_key_identifier	OBJ_id_ce,14L
+
+#define SN_key_usage			"keyUsage"
+#define LN_key_usage			"X509v3 Key Usage"
+#define NID_key_usage			83
+#define OBJ_key_usage			OBJ_id_ce,15L
+
+#define SN_private_key_usage_period	"privateKeyUsagePeriod"
+#define LN_private_key_usage_period	"X509v3 Private Key Usage Period"
+#define NID_private_key_usage_period	84
+#define OBJ_private_key_usage_period	OBJ_id_ce,16L
+
+#define SN_subject_alt_name		"subjectAltName"
+#define LN_subject_alt_name		"X509v3 Subject Alternative Name"
+#define NID_subject_alt_name		85
+#define OBJ_subject_alt_name		OBJ_id_ce,17L
+
+#define SN_issuer_alt_name		"issuerAltName"
+#define LN_issuer_alt_name		"X509v3 Issuer Alternative Name"
+#define NID_issuer_alt_name		86
+#define OBJ_issuer_alt_name		OBJ_id_ce,18L
+
+#define SN_basic_constraints		"basicConstraints"
+#define LN_basic_constraints		"X509v3 Basic Constraints"
+#define NID_basic_constraints		87
+#define OBJ_basic_constraints		OBJ_id_ce,19L
+
+#define SN_crl_number			"crlNumber"
+#define LN_crl_number			"X509v3 CRL Number"
+#define NID_crl_number			88
+#define OBJ_crl_number			OBJ_id_ce,20L
+
+#define SN_certificate_policies		"certificatePolicies"
+#define LN_certificate_policies		"X509v3 Certificate Policies"
+#define NID_certificate_policies	89
+#define OBJ_certificate_policies	OBJ_id_ce,32L
+
+#define SN_authority_key_identifier	"authorityKeyIdentifier"
+#define LN_authority_key_identifier	"X509v3 Authority Key Identifier"
+#define NID_authority_key_identifier	90
+#define OBJ_authority_key_identifier	OBJ_id_ce,35L
+
+#define SN_bf_cbc			"BF-CBC"
+#define LN_bf_cbc			"bf-cbc"
+#define NID_bf_cbc			91
+#define OBJ_bf_cbc			1L,3L,6L,1L,4L,1L,3029L,1L,2L
+
+#define SN_bf_ecb			"BF-ECB"
+#define LN_bf_ecb			"bf-ecb"
+#define NID_bf_ecb			92
+
+#define SN_bf_cfb64			"BF-CFB"
+#define LN_bf_cfb64			"bf-cfb"
+#define NID_bf_cfb64			93
+
+#define SN_bf_ofb64			"BF-OFB"
+#define LN_bf_ofb64			"bf-ofb"
+#define NID_bf_ofb64			94
+
+#define SN_mdc2				"MDC2"
+#define LN_mdc2				"mdc2"
+#define NID_mdc2			95
+#define OBJ_mdc2			2L,5L,8L,3L,101L
+/* An alternative?			1L,3L,14L,3L,2L,19L */
+
+#define SN_mdc2WithRSA			"RSA-MDC2"
+#define LN_mdc2WithRSA			"mdc2withRSA"
+#define NID_mdc2WithRSA			96
+#define OBJ_mdc2WithRSA			2L,5L,8L,3L,100L
+
+#define SN_rc4_40			"RC4-40"
+#define LN_rc4_40			"rc4-40"
+#define NID_rc4_40			97
+
+#define SN_rc2_40_cbc			"RC2-40-CBC"
+#define LN_rc2_40_cbc			"rc2-40-cbc"
+#define NID_rc2_40_cbc			98
+
+#define SN_givenName			"G"
+#define LN_givenName			"givenName"
+#define NID_givenName			99
+#define OBJ_givenName			OBJ_X509,42L
+
+#define SN_surname			"S"
+#define LN_surname			"surname"
+#define NID_surname			100
+#define OBJ_surname			OBJ_X509,4L
+
+#define SN_initials			"I"
+#define LN_initials			"initials"
+#define NID_initials			101
+#define OBJ_initials			OBJ_X509,43L
+
+#define SN_uniqueIdentifier		"UID"
+#define LN_uniqueIdentifier		"uniqueIdentifier"
+#define NID_uniqueIdentifier		102
+#define OBJ_uniqueIdentifier		OBJ_X509,45L
+
+#define SN_crl_distribution_points	"crlDistributionPoints"
+#define LN_crl_distribution_points	"X509v3 CRL Distribution Points"
+#define NID_crl_distribution_points	103
+#define OBJ_crl_distribution_points	OBJ_id_ce,31L
+
+#define SN_md5WithRSA			"RSA-NP-MD5"
+#define LN_md5WithRSA			"md5WithRSA"
+#define NID_md5WithRSA			104
+#define OBJ_md5WithRSA			OBJ_algorithm,3L
+
+#define SN_serialNumber			"SN"
+#define LN_serialNumber			"serialNumber"
+#define NID_serialNumber		105
+#define OBJ_serialNumber		OBJ_X509,5L
+
+#define SN_title			"T"
+#define LN_title			"title"
+#define NID_title			106
+#define OBJ_title			OBJ_X509,12L
+
+#define SN_description			"D"
+#define LN_description			"description"
+#define NID_description			107
+#define OBJ_description			OBJ_X509,13L
+
+/* CAST5 is CAST-128, I'm just sticking with the documentation */
+#define SN_cast5_cbc			"CAST5-CBC"
+#define LN_cast5_cbc			"cast5-cbc"
+#define NID_cast5_cbc			108
+#define OBJ_cast5_cbc			1L,2L,840L,113533L,7L,66L,10L
+
+#define SN_cast5_ecb			"CAST5-ECB"
+#define LN_cast5_ecb			"cast5-ecb"
+#define NID_cast5_ecb			109
+
+#define SN_cast5_cfb64			"CAST5-CFB"
+#define LN_cast5_cfb64			"cast5-cfb"
+#define NID_cast5_cfb64			110
+
+#define SN_cast5_ofb64			"CAST5-OFB"
+#define LN_cast5_ofb64			"cast5-ofb"
+#define NID_cast5_ofb64			111
+
+#define LN_pbeWithMD5AndCast5_CBC	"pbeWithMD5AndCast5CBC"
+#define NID_pbeWithMD5AndCast5_CBC	112
+#define OBJ_pbeWithMD5AndCast5_CBC	1L,2L,840L,113533L,7L,66L,12L
+
+/* This is one sun will soon be using :-(
+ * id-dsa-with-sha1 ID  ::= {
+ *   iso(1) member-body(2) us(840) x9-57 (10040) x9cm(4) 3 }
+ */
+#define SN_dsaWithSHA1			"DSA-SHA1"
+#define LN_dsaWithSHA1			"dsaWithSHA1"
+#define NID_dsaWithSHA1			113
+#define OBJ_dsaWithSHA1			1L,2L,840L,10040L,4L,3L
+
+#define NID_md5_sha1			114
+#define SN_md5_sha1			"MD5-SHA1"
+#define LN_md5_sha1			"md5-sha1"
+
+#define SN_sha1WithRSA			"RSA-SHA1-2"
+#define LN_sha1WithRSA			"sha1WithRSA"
+#define NID_sha1WithRSA			115
+#define OBJ_sha1WithRSA			OBJ_algorithm,29L
+
+#define SN_dsa				"DSA"
+#define LN_dsa				"dsaEncryption"
+#define NID_dsa				116
+#define OBJ_dsa				1L,2L,840L,10040L,4L,1L
+
+#define SN_ripemd160			"RIPEMD160"
+#define LN_ripemd160			"ripemd160"
+#define NID_ripemd160			117
+#define OBJ_ripemd160			1L,3L,36L,3L,2L,1L
+
+/* The name should actually be rsaSignatureWithripemd160, but I'm going
+ * to continue using the convention I'm using with the other ciphers */
+#define SN_ripemd160WithRSA		"RSA-RIPEMD160"
+#define LN_ripemd160WithRSA		"ripemd160WithRSA"
+#define NID_ripemd160WithRSA		119
+#define OBJ_ripemd160WithRSA		1L,3L,36L,3L,3L,1L,2L
+
+/* Taken from rfc2040
+ *  RC5_CBC_Parameters ::= SEQUENCE {
+ *	version           INTEGER (v1_0(16)),
+ *	rounds            INTEGER (8..127),
+ *	blockSizeInBits   INTEGER (64, 128),
+ *	iv                OCTET STRING OPTIONAL
+ *	}
+ */
+#define SN_rc5_cbc			"RC5-CBC"
+#define LN_rc5_cbc			"rc5-cbc"
+#define NID_rc5_cbc			120
+#define OBJ_rc5_cbc			OBJ_rsadsi,3L,8L
+
+#define SN_rc5_ecb			"RC5-ECB"
+#define LN_rc5_ecb			"rc5-ecb"
+#define NID_rc5_ecb			121
+
+#define SN_rc5_cfb64			"RC5-CFB"
+#define LN_rc5_cfb64			"rc5-cfb"
+#define NID_rc5_cfb64			122
+
+#define SN_rc5_ofb64			"RC5-OFB"
+#define LN_rc5_ofb64			"rc5-ofb"
+#define NID_rc5_ofb64			123
+
+#define SN_rle_compression		"RLE"
+#define LN_rle_compression		"run length compression"
+#define NID_rle_compression		124
+#define OBJ_rle_compression		1L,1L,1L,1L,666L,1L
+
+#define SN_zlib_compression		"ZLIB"
+#define LN_zlib_compression		"zlib compression"
+#define NID_zlib_compression		125
+#define OBJ_zlib_compression		1L,1L,1L,1L,666L,2L
+
+#define SN_ext_key_usage		"extendedKeyUsage"
+#define LN_ext_key_usage		"X509v3 Extended Key Usage"
+#define NID_ext_key_usage		126
+#define OBJ_ext_key_usage		OBJ_id_ce,37
+
+#define SN_id_pkix			"PKIX"
+#define NID_id_pkix			127
+#define OBJ_id_pkix			1L,3L,6L,1L,5L,5L,7L
+
+#define SN_id_kp			"id-kp"
+#define NID_id_kp			128
+#define OBJ_id_kp			OBJ_id_pkix,3L
+
+/* PKIX extended key usage OIDs */
+
+#define SN_server_auth			"serverAuth"
+#define LN_server_auth			"TLS Web Server Authentication"
+#define NID_server_auth			129
+#define OBJ_server_auth			OBJ_id_kp,1L
+
+#define SN_client_auth			"clientAuth"
+#define LN_client_auth			"TLS Web Client Authentication"
+#define NID_client_auth			130
+#define OBJ_client_auth			OBJ_id_kp,2L
+
+#define SN_code_sign			"codeSigning"
+#define LN_code_sign			"Code Signing"
+#define NID_code_sign			131
+#define OBJ_code_sign			OBJ_id_kp,3L
+
+#define SN_email_protect		"emailProtection"
+#define LN_email_protect		"E-mail Protection"
+#define NID_email_protect		132
+#define OBJ_email_protect		OBJ_id_kp,4L
+
+#define SN_time_stamp			"timeStamping"
+#define LN_time_stamp			"Time Stamping"
+#define NID_time_stamp			133
+#define OBJ_time_stamp			OBJ_id_kp,8L
+
+/* Additional extended key usage OIDs: Microsoft */
+
+#define SN_ms_code_ind			"msCodeInd"
+#define LN_ms_code_ind			"Microsoft Individual Code Signing"
+#define NID_ms_code_ind			134
+#define OBJ_ms_code_ind			1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
+
+#define SN_ms_code_com			"msCodeCom"
+#define LN_ms_code_com			"Microsoft Commercial Code Signing"
+#define NID_ms_code_com			135
+#define OBJ_ms_code_com			1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
+
+#define SN_ms_ctl_sign			"msCTLSign"
+#define LN_ms_ctl_sign			"Microsoft Trust List Signing"
+#define NID_ms_ctl_sign			136
+#define OBJ_ms_ctl_sign			1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
+
+#define SN_ms_sgc			"msSGC"
+#define LN_ms_sgc			"Microsoft Server Gated Crypto"
+#define NID_ms_sgc			137
+#define OBJ_ms_sgc			1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
+
+#define SN_ms_efs			"msEFS"
+#define LN_ms_efs			"Microsoft Encrypted File System"
+#define NID_ms_efs			138
+#define OBJ_ms_efs			1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
+
+/* Additional usage: Netscape */
+
+#define SN_ns_sgc			"nsSGC"
+#define LN_ns_sgc			"Netscape Server Gated Crypto"
+#define NID_ns_sgc			139
+#define OBJ_ns_sgc			OBJ_netscape,4L,1L
+
+#define SN_delta_crl			"deltaCRL"
+#define LN_delta_crl			"X509v3 Delta CRL Indicator"
+#define NID_delta_crl			140
+#define OBJ_delta_crl			OBJ_id_ce,27L
+
+#define SN_crl_reason			"CRLReason"
+#define LN_crl_reason			"CRL Reason Code"
+#define NID_crl_reason			141
+#define OBJ_crl_reason			OBJ_id_ce,21L
+
+#define SN_invalidity_date		"invalidityDate"
+#define LN_invalidity_date		"Invalidity Date"
+#define NID_invalidity_date		142
+#define OBJ_invalidity_date		OBJ_id_ce,24L
+
+#define SN_sxnet			"SXNetID"
+#define LN_sxnet			"Strong Extranet ID"
+#define NID_sxnet			143
+#define OBJ_sxnet			1L,3L,101L,1L,4L,1L
+
+/* PKCS12 and related OBJECT IDENTIFIERS */
+
+#define OBJ_pkcs12			OBJ_pkcs,12L
+#define OBJ_pkcs12_pbeids		OBJ_pkcs12, 1
+
+#define SN_pbe_WithSHA1And128BitRC4	"PBE-SHA1-RC4-128"
+#define LN_pbe_WithSHA1And128BitRC4	"pbeWithSHA1And128BitRC4"
+#define NID_pbe_WithSHA1And128BitRC4	144
+#define OBJ_pbe_WithSHA1And128BitRC4	OBJ_pkcs12_pbeids, 1L
+
+#define SN_pbe_WithSHA1And40BitRC4	"PBE-SHA1-RC4-40"
+#define LN_pbe_WithSHA1And40BitRC4	"pbeWithSHA1And40BitRC4"
+#define NID_pbe_WithSHA1And40BitRC4	145
+#define OBJ_pbe_WithSHA1And40BitRC4	OBJ_pkcs12_pbeids, 2L
+
+#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC	"PBE-SHA1-3DES"
+#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC	"pbeWithSHA1And3-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC	146
+#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC	OBJ_pkcs12_pbeids, 3L
+
+#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC	"PBE-SHA1-2DES"
+#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC	"pbeWithSHA1And2-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC	147
+#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC	OBJ_pkcs12_pbeids, 4L
+
+#define SN_pbe_WithSHA1And128BitRC2_CBC		"PBE-SHA1-RC2-128"
+#define LN_pbe_WithSHA1And128BitRC2_CBC		"pbeWithSHA1And128BitRC2-CBC"
+#define NID_pbe_WithSHA1And128BitRC2_CBC	148
+#define OBJ_pbe_WithSHA1And128BitRC2_CBC	OBJ_pkcs12_pbeids, 5L
+
+#define SN_pbe_WithSHA1And40BitRC2_CBC	"PBE-SHA1-RC2-40"
+#define LN_pbe_WithSHA1And40BitRC2_CBC	"pbeWithSHA1And40BitRC2-CBC"
+#define NID_pbe_WithSHA1And40BitRC2_CBC	149
+#define OBJ_pbe_WithSHA1And40BitRC2_CBC	OBJ_pkcs12_pbeids, 6L
+
+#define OBJ_pkcs12_Version1	OBJ_pkcs12, 10L
+
+#define OBJ_pkcs12_BagIds	OBJ_pkcs12_Version1, 1L
+
+#define LN_keyBag		"keyBag"
+#define NID_keyBag		150
+#define OBJ_keyBag		OBJ_pkcs12_BagIds, 1L
+
+#define LN_pkcs8ShroudedKeyBag	"pkcs8ShroudedKeyBag"
+#define NID_pkcs8ShroudedKeyBag	151
+#define OBJ_pkcs8ShroudedKeyBag	OBJ_pkcs12_BagIds, 2L
+
+#define LN_certBag		"certBag"
+#define NID_certBag		152
+#define OBJ_certBag		OBJ_pkcs12_BagIds, 3L
+
+#define LN_crlBag		"crlBag"
+#define NID_crlBag		153
+#define OBJ_crlBag		OBJ_pkcs12_BagIds, 4L
+
+#define LN_secretBag		"secretBag"
+#define NID_secretBag		154
+#define OBJ_secretBag		OBJ_pkcs12_BagIds, 5L
+
+#define LN_safeContentsBag	"safeContentsBag"
+#define NID_safeContentsBag	155
+#define OBJ_safeContentsBag	OBJ_pkcs12_BagIds, 6L
+
+#define LN_friendlyName		"friendlyName"
+#define	NID_friendlyName	156
+#define OBJ_friendlyName	OBJ_pkcs9, 20L
+
+#define LN_localKeyID		"localKeyID"
+#define	NID_localKeyID		157
+#define OBJ_localKeyID		OBJ_pkcs9, 21L
+
+#define OBJ_certTypes		OBJ_pkcs9, 22L
+
+#define LN_x509Certificate	"x509Certificate"
+#define	NID_x509Certificate	158
+#define OBJ_x509Certificate	OBJ_certTypes, 1L
+
+#define LN_sdsiCertificate	"sdsiCertificate"
+#define	NID_sdsiCertificate	159
+#define OBJ_sdsiCertificate	OBJ_certTypes, 2L
+
+#define OBJ_crlTypes		OBJ_pkcs9, 23L
+
+#define LN_x509Crl		"x509Crl"
+#define	NID_x509Crl		160
+#define OBJ_x509Crl		OBJ_crlTypes, 1L
+
+/* PKCS#5 v2 OIDs */
+
+#define LN_pbes2		"PBES2"
+#define NID_pbes2		161
+#define OBJ_pbes2		OBJ_pkcs,5L,13L
+
+#define LN_pbmac1		"PBMAC1"
+#define NID_pbmac1		162
+#define OBJ_pbmac1		OBJ_pkcs,5L,14L
+
+#define LN_hmacWithSHA1		"hmacWithSHA1"
+#define NID_hmacWithSHA1	163
+#define OBJ_hmacWithSHA1	OBJ_rsadsi,2L,7L
+
+/* Policy Qualifier Ids */
+
+#define LN_id_qt_cps		"Policy Qualifier CPS"
+#define SN_id_qt_cps		"id-qt-cps"
+#define NID_id_qt_cps		164
+#define OBJ_id_qt_cps		OBJ_id_pkix,2L,1L
+
+#define LN_id_qt_unotice	"Policy Qualifier User Notice"
+#define SN_id_qt_unotice	"id-qt-unotice"
+#define NID_id_qt_unotice	165
+#define OBJ_id_qt_unotice	OBJ_id_pkix,2L,2L
+
+#define SN_rc2_64_cbc			"RC2-64-CBC"
+#define LN_rc2_64_cbc			"rc2-64-cbc"
+#define NID_rc2_64_cbc			166
+
+#define SN_SMIMECapabilities		"SMIME-CAPS"
+#define LN_SMIMECapabilities		"S/MIME Capabilities"
+#define NID_SMIMECapabilities		167
+#define OBJ_SMIMECapabilities		OBJ_pkcs9,15L
+
+#define SN_pbeWithMD2AndRC2_CBC		"PBE-MD2-RC2-64"
+#define LN_pbeWithMD2AndRC2_CBC		"pbeWithMD2AndRC2-CBC"
+#define NID_pbeWithMD2AndRC2_CBC	168
+#define OBJ_pbeWithMD2AndRC2_CBC	OBJ_pkcs,5L,4L
+
+#define SN_pbeWithMD5AndRC2_CBC		"PBE-MD5-RC2-64"
+#define LN_pbeWithMD5AndRC2_CBC		"pbeWithMD5AndRC2-CBC"
+#define NID_pbeWithMD5AndRC2_CBC	169
+#define OBJ_pbeWithMD5AndRC2_CBC	OBJ_pkcs,5L,6L
+
+#define SN_pbeWithSHA1AndDES_CBC	"PBE-SHA1-DES"
+#define LN_pbeWithSHA1AndDES_CBC	"pbeWithSHA1AndDES-CBC"
+#define NID_pbeWithSHA1AndDES_CBC	170
+#define OBJ_pbeWithSHA1AndDES_CBC	OBJ_pkcs,5L,10L
+
+/* Extension request OIDs */
+
+#define LN_ms_ext_req			"Microsoft Extension Request"
+#define SN_ms_ext_req			"msExtReq"
+#define NID_ms_ext_req			171
+#define OBJ_ms_ext_req			1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+#define LN_ext_req			"Extension Request"
+#define SN_ext_req			"extReq"
+#define NID_ext_req			172
+#define OBJ_ext_req			OBJ_pkcs9,14L
+
+#define SN_name				"name"
+#define LN_name				"name"
+#define NID_name			173
+#define OBJ_name			OBJ_X509,41L
+
+#define SN_dnQualifier			"dnQualifier"
+#define LN_dnQualifier			"dnQualifier"
+#define NID_dnQualifier			174
+#define OBJ_dnQualifier			OBJ_X509,46L
+
+#define SN_id_pe			"id-pe"
+#define NID_id_pe			175
+#define OBJ_id_pe			OBJ_id_pkix,1L
+
+#define SN_id_ad			"id-ad"
+#define NID_id_ad			176
+#define OBJ_id_ad			OBJ_id_pkix,48L
+
+#define SN_info_access			"authorityInfoAccess"
+#define LN_info_access			"Authority Information Access"
+#define NID_info_access			177
+#define OBJ_info_access			OBJ_id_pe,1L
+
+#define SN_ad_OCSP			"OCSP"
+#define LN_ad_OCSP			"OCSP"
+#define NID_ad_OCSP			178
+#define OBJ_ad_OCSP			OBJ_id_ad,1L
+
+#define SN_ad_ca_issuers		"caIssuers"
+#define LN_ad_ca_issuers		"CA Issuers"
+#define NID_ad_ca_issuers		179
+#define OBJ_ad_ca_issuers		OBJ_id_ad,2L
+
+#define SN_OCSP_sign			"OCSPSigning"
+#define LN_OCSP_sign			"OCSP Signing"
+#define NID_OCSP_sign			180
+#define OBJ_OCSP_sign			OBJ_id_kp,9L
+#endif /* USE_OBJ_MAC */
+
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+
+#define	OBJ_NAME_TYPE_UNDEF		0x00
+#define	OBJ_NAME_TYPE_MD_METH		0x01
+#define	OBJ_NAME_TYPE_CIPHER_METH	0x02
+#define	OBJ_NAME_TYPE_PKEY_METH		0x03
+#define	OBJ_NAME_TYPE_COMP_METH		0x04
+#define	OBJ_NAME_TYPE_NUM		0x05
+
+#define	OBJ_NAME_ALIAS			0x8000
+
+#define OBJ_BSEARCH_VALUE_ON_NOMATCH		0x01
+#define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH	0x02
+
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct obj_name_st
+	{
+	int type;
+	int alias;
+	const char *name;
+	const char *data;
+	} OBJ_NAME;
+
+#define		OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c)
+
+
+int OBJ_NAME_init(void);
+int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *),
+		       int (*cmp_func)(const char *, const char *),
+		       void (*free_func)(const char *, int, const char *));
+const char *OBJ_NAME_get(const char *name,int type);
+int OBJ_NAME_add(const char *name,int type,const char *data);
+int OBJ_NAME_remove(const char *name,int type);
+void OBJ_NAME_cleanup(int type); /* -1 for everything */
+void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),
+		     void *arg);
+void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg),
+			    void *arg);
+
+ASN1_OBJECT *	OBJ_dup(const ASN1_OBJECT *o);
+ASN1_OBJECT *	OBJ_nid2obj(int n);
+const char *	OBJ_nid2ln(int n);
+const char *	OBJ_nid2sn(int n);
+int		OBJ_obj2nid(const ASN1_OBJECT *o);
+ASN1_OBJECT *	OBJ_txt2obj(const char *s, int no_name);
+int	OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name);
+int		OBJ_txt2nid(const char *s);
+int		OBJ_ln2nid(const char *s);
+int		OBJ_sn2nid(const char *s);
+int		OBJ_cmp(const ASN1_OBJECT *a,const ASN1_OBJECT *b);
+const void *	OBJ_bsearch_(const void *key,const void *base,int num,int size,
+			     int (*cmp)(const void *, const void *));
+const void *	OBJ_bsearch_ex_(const void *key,const void *base,int num,
+				int size,
+				int (*cmp)(const void *, const void *),
+				int flags);
+
+#define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm)	\
+  static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \
+  static int nm##_cmp(type1 const *, type2 const *); \
+  scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)
+
+#define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp)	\
+  _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp)
+#define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm)	\
+  type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)
+
+/*
+ * Unsolved problem: if a type is actually a pointer type, like
+ * nid_triple is, then its impossible to get a const where you need
+ * it. Consider:
+ *
+ * typedef int nid_triple[3];
+ * const void *a_;
+ * const nid_triple const *a = a_;
+ *
+ * The assignement discards a const because what you really want is:
+ *
+ * const int const * const *a = a_;
+ *
+ * But if you do that, you lose the fact that a is an array of 3 ints,
+ * which breaks comparison functions.
+ *
+ * Thus we end up having to cast, sadly, or unpack the
+ * declarations. Or, as I finally did in this case, delcare nid_triple
+ * to be a struct, which it should have been in the first place.
+ *
+ * Ben, August 2008.
+ *
+ * Also, strictly speaking not all types need be const, but handling
+ * the non-constness means a lot of complication, and in practice
+ * comparison routines do always not touch their arguments.
+ */
+
+#define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm)	\
+  static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)	\
+      { \
+      type1 const *a = a_; \
+      type2 const *b = b_; \
+      return nm##_cmp(a,b); \
+      } \
+  static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
+      { \
+      return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
+					nm##_cmp_BSEARCH_CMP_FN); \
+      } \
+      extern void dummy_prototype(void)
+
+#define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm)	\
+  static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)	\
+      { \
+      type1 const *a = a_; \
+      type2 const *b = b_; \
+      return nm##_cmp(a,b); \
+      } \
+  type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
+      { \
+      return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
+					nm##_cmp_BSEARCH_CMP_FN); \
+      } \
+      extern void dummy_prototype(void)
+
+#define OBJ_bsearch(type1,key,type2,base,num,cmp)			       \
+  ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
+			 num,sizeof(type2),				\
+			 ((void)CHECKED_PTR_OF(type1,cmp##_type_1),	\
+			  (void)CHECKED_PTR_OF(type2,cmp##_type_2),	\
+			  cmp##_BSEARCH_CMP_FN)))
+
+#define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags)			\
+  ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
+			 num,sizeof(type2),				\
+			 ((void)CHECKED_PTR_OF(type1,cmp##_type_1),	\
+			  (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \
+			  cmp##_BSEARCH_CMP_FN)),flags)
+
+int		OBJ_new_nid(int num);
+int		OBJ_add_object(const ASN1_OBJECT *obj);
+int		OBJ_create(const char *oid,const char *sn,const char *ln);
+void		OBJ_cleanup(void );
+int		OBJ_create_objects(BIO *in);
+
+int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid);
+int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid);
+int OBJ_add_sigid(int signid, int dig_id, int pkey_id);
+void OBJ_sigid_free(void);
+
+extern int obj_cleanup_defer;
+void check_defer(int nid);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_OBJ_strings(void);
+
+/* Error codes for the OBJ functions. */
+
+/* Function codes. */
+#define OBJ_F_OBJ_ADD_OBJECT				 105
+#define OBJ_F_OBJ_CREATE				 100
+#define OBJ_F_OBJ_DUP					 101
+#define OBJ_F_OBJ_NAME_NEW_INDEX			 106
+#define OBJ_F_OBJ_NID2LN				 102
+#define OBJ_F_OBJ_NID2OBJ				 103
+#define OBJ_F_OBJ_NID2SN				 104
+
+/* Reason codes. */
+#define OBJ_R_MALLOC_FAILURE				 100
+#define OBJ_R_UNKNOWN_NID				 101
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/objects/objects.pl b/openssl/crypto/objects/objects.pl
new file mode 100644
index 0000000..15c00bb
--- /dev/null
+++ b/openssl/crypto/objects/objects.pl
@@ -0,0 +1,232 @@
+#!/usr/local/bin/perl
+
+open (NUMIN,"$ARGV[1]") || die "Can't open number file $ARGV[1]";
+$max_nid=0;
+$o=0;
+while(<NUMIN>)
+	{
+	chop;
+	$o++;
+	s/#.*$//;
+	next if /^\s*$/;
+	$_ = 'X'.$_;
+	($Cname,$mynum) = split;
+	$Cname =~ s/^X//;
+	if (defined($nidn{$mynum}))
+		{ die "$ARGV[1]:$o:There's already an object with NID ",$mynum," on line ",$order{$mynum},"\n"; }
+	if (defined($nid{$Cname}))
+		{ die "$ARGV[1]:$o:There's already an object with name ",$Cname," on line ",$order{$nid{$Cname}},"\n"; }
+	$nid{$Cname} = $mynum;
+	$nidn{$mynum} = $Cname;
+	$order{$mynum} = $o;
+	$max_nid = $mynum if $mynum > $max_nid;
+	}
+close NUMIN;
+
+open (IN,"$ARGV[0]") || die "Can't open input file $ARGV[0]";
+$Cname="";
+$o=0;
+while (<IN>)
+	{
+	chop;
+	$o++;
+        if (/^!module\s+(.*)$/)
+		{
+		$module = $1."-";
+		$module =~ s/\./_/g;
+		$module =~ s/-/_/g;
+		}
+        if (/^!global$/)
+		{ $module = ""; }
+	if (/^!Cname\s+(.*)$/)
+		{ $Cname = $1; }
+	if (/^!Alias\s+(.+?)\s+(.*)$/)
+		{
+		$Cname = $module.$1;
+		$myoid = $2;
+		$myoid = &process_oid($myoid);
+		$Cname =~ s/-/_/g;
+		$ordern{$o} = $Cname;
+		$order{$Cname} = $o;
+		$obj{$Cname} = $myoid;
+		$_ = "";
+		$Cname = "";
+		}
+	s/!.*$//;
+	s/#.*$//;
+	next if /^\s*$/;
+	($myoid,$mysn,$myln) = split ':';
+	$mysn =~ s/^\s*//;
+	$mysn =~ s/\s*$//;
+	$myln =~ s/^\s*//;
+	$myln =~ s/\s*$//;
+	$myoid =~ s/^\s*//;
+	$myoid =~ s/\s*$//;
+	if ($myoid ne "")
+		{
+		$myoid = &process_oid($myoid);
+		}
+
+	if ($Cname eq "" && !($myln =~ / /))
+		{
+		$Cname = $myln;
+		$Cname =~ s/\./_/g;
+		$Cname =~ s/-/_/g;
+		if ($Cname ne "" && defined($ln{$module.$Cname}))
+			{ die "objects.txt:$o:There's already an object with long name ",$ln{$module.$Cname}," on line ",$order{$module.$Cname},"\n"; }
+		}
+	if ($Cname eq "")
+		{
+		$Cname = $mysn;
+		$Cname =~ s/-/_/g;
+		if ($Cname ne "" && defined($sn{$module.$Cname}))
+			{ die "objects.txt:$o:There's already an object with short name ",$sn{$module.$Cname}," on line ",$order{$module.$Cname},"\n"; }
+		}
+	if ($Cname eq "")
+		{
+		$Cname = $myln;
+		$Cname =~ s/-/_/g;
+		$Cname =~ s/\./_/g;
+		$Cname =~ s/ /_/g;
+		if ($Cname ne "" && defined($ln{$module.$Cname}))
+			{ die "objects.txt:$o:There's already an object with long name ",$ln{$module.$Cname}," on line ",$order{$module.$Cname},"\n"; }
+		}
+	$Cname =~ s/\./_/g;
+	$Cname =~ s/-/_/g;
+	$Cname = $module.$Cname;
+	$ordern{$o} = $Cname;
+	$order{$Cname} = $o;
+	$sn{$Cname} = $mysn;
+	$ln{$Cname} = $myln;
+	$obj{$Cname} = $myoid;
+	if (!defined($nid{$Cname}))
+		{
+		$max_nid++;
+		$nid{$Cname} = $max_nid;
+		$nidn{$max_nid} = $Cname;
+print STDERR "Added OID $Cname\n";
+		}
+	$Cname="";
+	}
+close IN;
+
+open (NUMOUT,">$ARGV[1]") || die "Can't open output file $ARGV[1]";
+foreach (sort { $a <=> $b } keys %nidn)
+	{
+	print NUMOUT $nidn{$_},"\t\t",$_,"\n";
+	}
+close NUMOUT;
+
+open (OUT,">$ARGV[2]") || die "Can't open output file $ARGV[2]";
+print OUT <<'EOF';
+/* crypto/objects/obj_mac.h */
+
+/* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the
+ * following command:
+ * perl objects.pl objects.txt obj_mac.num obj_mac.h
+ */
+
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#define SN_undef			"UNDEF"
+#define LN_undef			"undefined"
+#define NID_undef			0
+#define OBJ_undef			0L
+
+EOF
+
+foreach (sort { $a <=> $b } keys %ordern)
+	{
+	$Cname=$ordern{$_};
+	print OUT "#define SN_",$Cname,"\t\t\"",$sn{$Cname},"\"\n" if $sn{$Cname} ne "";
+	print OUT "#define LN_",$Cname,"\t\t\"",$ln{$Cname},"\"\n" if $ln{$Cname} ne "";
+	print OUT "#define NID_",$Cname,"\t\t",$nid{$Cname},"\n" if $nid{$Cname} ne "";
+	print OUT "#define OBJ_",$Cname,"\t\t",$obj{$Cname},"\n" if $obj{$Cname} ne "";
+	print OUT "\n";
+	}
+
+close OUT;
+
+sub process_oid
+	{
+	local($oid)=@_;
+	local(@a,$oid_pref);
+
+	@a = split(/\s+/,$myoid);
+	$pref_oid = "";
+	$pref_sep = "";
+	if (!($a[0] =~ /^[0-9]+$/))
+		{
+		$a[0] =~ s/-/_/g;
+		if (!defined($obj{$a[0]}))
+			{ die "$ARGV[0]:$o:Undefined identifier ",$a[0],"\n"; }
+		$pref_oid = "OBJ_" . $a[0];
+		$pref_sep = ",";
+		shift @a;
+		}
+	$oids = join('L,',@a) . "L";
+	if ($oids ne "L")
+		{
+		$oids = $pref_oid . $pref_sep . $oids;
+		}
+	else
+		{
+		$oids = $pref_oid;
+		}
+	return($oids);
+	}
diff --git a/openssl/crypto/objects/objects.txt b/openssl/crypto/objects/objects.txt
new file mode 100644
index 0000000..e61fe60
--- /dev/null
+++ b/openssl/crypto/objects/objects.txt
@@ -0,0 +1,1259 @@
+# CCITT was renamed to ITU-T quite some time ago
+0			: ITU-T			: itu-t
+!Alias ccitt itu-t
+
+1			: ISO			: iso
+
+2			: JOINT-ISO-ITU-T	: joint-iso-itu-t
+!Alias joint-iso-ccitt joint-iso-itu-t
+
+iso 2			: member-body		: ISO Member Body
+
+iso 3			: identified-organization
+
+# HMAC OIDs
+identified-organization 6 1 5 5 8 1 1	: HMAC-MD5	: hmac-md5
+identified-organization 6 1 5 5 8 1 2	: HMAC-SHA1	: hmac-sha1
+
+identified-organization 132	: certicom-arc
+
+joint-iso-itu-t 23	: international-organizations	: International Organizations
+
+international-organizations 43	: wap
+wap 1			: wap-wsg
+
+joint-iso-itu-t 5 1 5	: selected-attribute-types	: Selected Attribute Types
+
+selected-attribute-types 55	: clearance
+
+member-body 840		: ISO-US		: ISO US Member Body
+ISO-US 10040		: X9-57			: X9.57
+X9-57 4			: X9cm			: X9.57 CM ?
+
+!Cname dsa
+X9cm 1			: DSA			: dsaEncryption
+X9cm 3			: DSA-SHA1		: dsaWithSHA1
+
+
+ISO-US 10045		: ansi-X9-62		: ANSI X9.62
+!module X9-62
+!Alias id-fieldType ansi-X9-62 1
+X9-62_id-fieldType 1		: prime-field
+X9-62_id-fieldType 2		: characteristic-two-field
+X9-62_characteristic-two-field 3 : id-characteristic-two-basis
+X9-62_id-characteristic-two-basis 1 : onBasis
+X9-62_id-characteristic-two-basis 2 : tpBasis
+X9-62_id-characteristic-two-basis 3 : ppBasis
+!Alias id-publicKeyType ansi-X9-62 2
+X9-62_id-publicKeyType 1	: id-ecPublicKey
+!Alias ellipticCurve ansi-X9-62 3
+!Alias c-TwoCurve X9-62_ellipticCurve 0
+X9-62_c-TwoCurve 1		: c2pnb163v1
+X9-62_c-TwoCurve 2		: c2pnb163v2
+X9-62_c-TwoCurve 3		: c2pnb163v3
+X9-62_c-TwoCurve 4		: c2pnb176v1
+X9-62_c-TwoCurve 5		: c2tnb191v1
+X9-62_c-TwoCurve 6		: c2tnb191v2
+X9-62_c-TwoCurve 7		: c2tnb191v3
+X9-62_c-TwoCurve 8		: c2onb191v4
+X9-62_c-TwoCurve 9		: c2onb191v5
+X9-62_c-TwoCurve 10		: c2pnb208w1
+X9-62_c-TwoCurve 11		: c2tnb239v1
+X9-62_c-TwoCurve 12		: c2tnb239v2
+X9-62_c-TwoCurve 13		: c2tnb239v3
+X9-62_c-TwoCurve 14		: c2onb239v4
+X9-62_c-TwoCurve 15		: c2onb239v5
+X9-62_c-TwoCurve 16		: c2pnb272w1
+X9-62_c-TwoCurve 17		: c2pnb304w1
+X9-62_c-TwoCurve 18		: c2tnb359v1
+X9-62_c-TwoCurve 19		: c2pnb368w1
+X9-62_c-TwoCurve 20		: c2tnb431r1
+!Alias primeCurve X9-62_ellipticCurve 1
+X9-62_primeCurve 1	 	: prime192v1
+X9-62_primeCurve 2	 	: prime192v2
+X9-62_primeCurve 3	 	: prime192v3
+X9-62_primeCurve 4	 	: prime239v1
+X9-62_primeCurve 5	 	: prime239v2
+X9-62_primeCurve 6	 	: prime239v3
+X9-62_primeCurve 7	 	: prime256v1
+!Alias id-ecSigType ansi-X9-62 4
+!global
+X9-62_id-ecSigType 1		: ecdsa-with-SHA1
+X9-62_id-ecSigType 2		: ecdsa-with-Recommended
+X9-62_id-ecSigType 3		: ecdsa-with-Specified
+ecdsa-with-Specified 1		: ecdsa-with-SHA224
+ecdsa-with-Specified 2		: ecdsa-with-SHA256
+ecdsa-with-Specified 3		: ecdsa-with-SHA384
+ecdsa-with-Specified 4		: ecdsa-with-SHA512
+
+# SECG curve OIDs from "SEC 2: Recommended Elliptic Curve Domain Parameters"
+# (http://www.secg.org/)
+!Alias secg_ellipticCurve certicom-arc 0
+# SECG prime curves OIDs
+secg-ellipticCurve 6		: secp112r1
+secg-ellipticCurve 7		: secp112r2
+secg-ellipticCurve 28		: secp128r1
+secg-ellipticCurve 29		: secp128r2
+secg-ellipticCurve 9		: secp160k1
+secg-ellipticCurve 8		: secp160r1
+secg-ellipticCurve 30		: secp160r2
+secg-ellipticCurve 31		: secp192k1
+# NOTE: the curve secp192r1 is the same as prime192v1 defined above
+#       and is therefore omitted
+secg-ellipticCurve 32		: secp224k1
+secg-ellipticCurve 33		: secp224r1
+secg-ellipticCurve 10		: secp256k1
+# NOTE: the curve secp256r1 is the same as prime256v1 defined above
+#       and is therefore omitted
+secg-ellipticCurve 34		: secp384r1
+secg-ellipticCurve 35		: secp521r1
+# SECG characteristic two curves OIDs
+secg-ellipticCurve 4		: sect113r1
+secg-ellipticCurve 5		: sect113r2
+secg-ellipticCurve 22		: sect131r1
+secg-ellipticCurve 23		: sect131r2
+secg-ellipticCurve 1		: sect163k1
+secg-ellipticCurve 2		: sect163r1
+secg-ellipticCurve 15		: sect163r2
+secg-ellipticCurve 24		: sect193r1
+secg-ellipticCurve 25		: sect193r2
+secg-ellipticCurve 26		: sect233k1
+secg-ellipticCurve 27		: sect233r1
+secg-ellipticCurve 3		: sect239k1
+secg-ellipticCurve 16		: sect283k1
+secg-ellipticCurve 17		: sect283r1
+secg-ellipticCurve 36		: sect409k1
+secg-ellipticCurve 37		: sect409r1
+secg-ellipticCurve 38		: sect571k1
+secg-ellipticCurve 39		: sect571r1
+
+# WAP/TLS curve OIDs (http://www.wapforum.org/)
+!Alias wap-wsg-idm-ecid wap-wsg 4
+wap-wsg-idm-ecid 1	: wap-wsg-idm-ecid-wtls1
+wap-wsg-idm-ecid 3	: wap-wsg-idm-ecid-wtls3
+wap-wsg-idm-ecid 4	: wap-wsg-idm-ecid-wtls4
+wap-wsg-idm-ecid 5	: wap-wsg-idm-ecid-wtls5
+wap-wsg-idm-ecid 6	: wap-wsg-idm-ecid-wtls6
+wap-wsg-idm-ecid 7	: wap-wsg-idm-ecid-wtls7
+wap-wsg-idm-ecid 8	: wap-wsg-idm-ecid-wtls8
+wap-wsg-idm-ecid 9	: wap-wsg-idm-ecid-wtls9
+wap-wsg-idm-ecid 10	: wap-wsg-idm-ecid-wtls10
+wap-wsg-idm-ecid 11	: wap-wsg-idm-ecid-wtls11
+wap-wsg-idm-ecid 12	: wap-wsg-idm-ecid-wtls12
+
+
+ISO-US 113533 7 66 10	: CAST5-CBC		: cast5-cbc
+			: CAST5-ECB		: cast5-ecb
+!Cname cast5-cfb64
+			: CAST5-CFB		: cast5-cfb
+!Cname cast5-ofb64
+			: CAST5-OFB		: cast5-ofb
+!Cname pbeWithMD5AndCast5-CBC
+ISO-US 113533 7 66 12	:			: pbeWithMD5AndCast5CBC
+
+# Macs for CMP and CRMF
+ISO-US 113533 7 66 13	: id-PasswordBasedMAC	: password based MAC
+ISO-US 113533 7 66 30	: id-DHBasedMac		: Diffie-Hellman based MAC
+
+ISO-US 113549		: rsadsi		: RSA Data Security, Inc.
+
+rsadsi 1		: pkcs			: RSA Data Security, Inc. PKCS
+
+pkcs 1			: pkcs1
+pkcs1 1			:			: rsaEncryption
+pkcs1 2			: RSA-MD2		: md2WithRSAEncryption
+pkcs1 3			: RSA-MD4		: md4WithRSAEncryption
+pkcs1 4			: RSA-MD5		: md5WithRSAEncryption
+pkcs1 5			: RSA-SHA1		: sha1WithRSAEncryption
+# According to PKCS #1 version 2.1
+pkcs1 11		: RSA-SHA256		: sha256WithRSAEncryption
+pkcs1 12		: RSA-SHA384		: sha384WithRSAEncryption
+pkcs1 13		: RSA-SHA512		: sha512WithRSAEncryption
+pkcs1 14		: RSA-SHA224		: sha224WithRSAEncryption
+
+pkcs 3			: pkcs3
+pkcs3 1			:			: dhKeyAgreement
+
+pkcs 5			: pkcs5
+pkcs5 1			: PBE-MD2-DES		: pbeWithMD2AndDES-CBC
+pkcs5 3			: PBE-MD5-DES		: pbeWithMD5AndDES-CBC
+pkcs5 4			: PBE-MD2-RC2-64	: pbeWithMD2AndRC2-CBC
+pkcs5 6			: PBE-MD5-RC2-64	: pbeWithMD5AndRC2-CBC
+pkcs5 10		: PBE-SHA1-DES		: pbeWithSHA1AndDES-CBC
+pkcs5 11		: PBE-SHA1-RC2-64	: pbeWithSHA1AndRC2-CBC
+!Cname id_pbkdf2
+pkcs5 12		:			: PBKDF2
+!Cname pbes2
+pkcs5 13		:			: PBES2
+!Cname pbmac1
+pkcs5 14		:			: PBMAC1
+
+pkcs 7			: pkcs7
+pkcs7 1			:			: pkcs7-data
+!Cname pkcs7-signed
+pkcs7 2			:			: pkcs7-signedData
+!Cname pkcs7-enveloped
+pkcs7 3			:			: pkcs7-envelopedData
+!Cname pkcs7-signedAndEnveloped
+pkcs7 4			:			: pkcs7-signedAndEnvelopedData
+!Cname pkcs7-digest
+pkcs7 5			:			: pkcs7-digestData
+!Cname pkcs7-encrypted
+pkcs7 6			:			: pkcs7-encryptedData
+
+pkcs 9			: pkcs9
+!module pkcs9
+pkcs9 1			: 			: emailAddress
+pkcs9 2			:			: unstructuredName
+pkcs9 3			:			: contentType
+pkcs9 4			:			: messageDigest
+pkcs9 5			:			: signingTime
+pkcs9 6			:			: countersignature
+pkcs9 7			:			: challengePassword
+pkcs9 8			:			: unstructuredAddress
+!Cname extCertAttributes
+pkcs9 9			:			: extendedCertificateAttributes
+!global
+
+!Cname ext-req
+pkcs9 14		: extReq		: Extension Request
+
+!Cname SMIMECapabilities
+pkcs9 15		: SMIME-CAPS		: S/MIME Capabilities
+
+# S/MIME
+!Cname SMIME
+pkcs9 16		: SMIME			: S/MIME
+SMIME 0			: id-smime-mod
+SMIME 1			: id-smime-ct
+SMIME 2			: id-smime-aa
+SMIME 3			: id-smime-alg
+SMIME 4			: id-smime-cd
+SMIME 5			: id-smime-spq
+SMIME 6			: id-smime-cti
+
+# S/MIME Modules
+id-smime-mod 1		: id-smime-mod-cms
+id-smime-mod 2		: id-smime-mod-ess
+id-smime-mod 3		: id-smime-mod-oid
+id-smime-mod 4		: id-smime-mod-msg-v3
+id-smime-mod 5		: id-smime-mod-ets-eSignature-88
+id-smime-mod 6		: id-smime-mod-ets-eSignature-97
+id-smime-mod 7		: id-smime-mod-ets-eSigPolicy-88
+id-smime-mod 8		: id-smime-mod-ets-eSigPolicy-97
+
+# S/MIME Content Types
+id-smime-ct 1		: id-smime-ct-receipt
+id-smime-ct 2		: id-smime-ct-authData
+id-smime-ct 3		: id-smime-ct-publishCert
+id-smime-ct 4		: id-smime-ct-TSTInfo
+id-smime-ct 5		: id-smime-ct-TDTInfo
+id-smime-ct 6		: id-smime-ct-contentInfo
+id-smime-ct 7		: id-smime-ct-DVCSRequestData
+id-smime-ct 8		: id-smime-ct-DVCSResponseData
+id-smime-ct 9		: id-smime-ct-compressedData
+id-smime-ct 27		: id-ct-asciiTextWithCRLF
+
+# S/MIME Attributes
+id-smime-aa 1		: id-smime-aa-receiptRequest
+id-smime-aa 2		: id-smime-aa-securityLabel
+id-smime-aa 3		: id-smime-aa-mlExpandHistory
+id-smime-aa 4		: id-smime-aa-contentHint
+id-smime-aa 5		: id-smime-aa-msgSigDigest
+# obsolete
+id-smime-aa 6		: id-smime-aa-encapContentType
+id-smime-aa 7		: id-smime-aa-contentIdentifier
+# obsolete
+id-smime-aa 8		: id-smime-aa-macValue
+id-smime-aa 9		: id-smime-aa-equivalentLabels
+id-smime-aa 10		: id-smime-aa-contentReference
+id-smime-aa 11		: id-smime-aa-encrypKeyPref
+id-smime-aa 12		: id-smime-aa-signingCertificate
+id-smime-aa 13		: id-smime-aa-smimeEncryptCerts
+id-smime-aa 14		: id-smime-aa-timeStampToken
+id-smime-aa 15		: id-smime-aa-ets-sigPolicyId
+id-smime-aa 16		: id-smime-aa-ets-commitmentType
+id-smime-aa 17		: id-smime-aa-ets-signerLocation
+id-smime-aa 18		: id-smime-aa-ets-signerAttr
+id-smime-aa 19		: id-smime-aa-ets-otherSigCert
+id-smime-aa 20		: id-smime-aa-ets-contentTimestamp
+id-smime-aa 21		: id-smime-aa-ets-CertificateRefs
+id-smime-aa 22		: id-smime-aa-ets-RevocationRefs
+id-smime-aa 23		: id-smime-aa-ets-certValues
+id-smime-aa 24		: id-smime-aa-ets-revocationValues
+id-smime-aa 25		: id-smime-aa-ets-escTimeStamp
+id-smime-aa 26		: id-smime-aa-ets-certCRLTimestamp
+id-smime-aa 27		: id-smime-aa-ets-archiveTimeStamp
+id-smime-aa 28		: id-smime-aa-signatureType
+id-smime-aa 29		: id-smime-aa-dvcs-dvc
+
+# S/MIME Algorithm Identifiers
+# obsolete
+id-smime-alg 1		: id-smime-alg-ESDHwith3DES
+# obsolete
+id-smime-alg 2		: id-smime-alg-ESDHwithRC2
+# obsolete
+id-smime-alg 3		: id-smime-alg-3DESwrap
+# obsolete
+id-smime-alg 4		: id-smime-alg-RC2wrap
+id-smime-alg 5		: id-smime-alg-ESDH
+id-smime-alg 6		: id-smime-alg-CMS3DESwrap
+id-smime-alg 7		: id-smime-alg-CMSRC2wrap
+
+# S/MIME Certificate Distribution
+id-smime-cd 1		: id-smime-cd-ldap
+
+# S/MIME Signature Policy Qualifier
+id-smime-spq 1		: id-smime-spq-ets-sqt-uri
+id-smime-spq 2		: id-smime-spq-ets-sqt-unotice
+
+# S/MIME Commitment Type Identifier
+id-smime-cti 1		: id-smime-cti-ets-proofOfOrigin
+id-smime-cti 2		: id-smime-cti-ets-proofOfReceipt
+id-smime-cti 3		: id-smime-cti-ets-proofOfDelivery
+id-smime-cti 4		: id-smime-cti-ets-proofOfSender
+id-smime-cti 5		: id-smime-cti-ets-proofOfApproval
+id-smime-cti 6		: id-smime-cti-ets-proofOfCreation
+
+pkcs9 20		:			: friendlyName
+pkcs9 21		:			: localKeyID
+!Cname ms-csp-name
+1 3 6 1 4 1 311 17 1	: CSPName		: Microsoft CSP Name
+1 3 6 1 4 1 311 17 2	: LocalKeySet		: Microsoft Local Key set
+!Alias certTypes pkcs9 22
+certTypes 1		:			: x509Certificate
+certTypes 2		:			: sdsiCertificate
+!Alias crlTypes pkcs9 23
+crlTypes 1		:			: x509Crl
+
+!Alias pkcs12 pkcs 12
+!Alias pkcs12-pbeids pkcs12 1
+
+!Cname pbe-WithSHA1And128BitRC4
+pkcs12-pbeids 1		: PBE-SHA1-RC4-128	: pbeWithSHA1And128BitRC4
+!Cname pbe-WithSHA1And40BitRC4
+pkcs12-pbeids 2		: PBE-SHA1-RC4-40	: pbeWithSHA1And40BitRC4
+!Cname pbe-WithSHA1And3_Key_TripleDES-CBC
+pkcs12-pbeids 3		: PBE-SHA1-3DES		: pbeWithSHA1And3-KeyTripleDES-CBC
+!Cname pbe-WithSHA1And2_Key_TripleDES-CBC
+pkcs12-pbeids 4		: PBE-SHA1-2DES		: pbeWithSHA1And2-KeyTripleDES-CBC
+!Cname pbe-WithSHA1And128BitRC2-CBC
+pkcs12-pbeids 5		: PBE-SHA1-RC2-128	: pbeWithSHA1And128BitRC2-CBC
+!Cname pbe-WithSHA1And40BitRC2-CBC
+pkcs12-pbeids 6		: PBE-SHA1-RC2-40	: pbeWithSHA1And40BitRC2-CBC
+
+!Alias pkcs12-Version1 pkcs12 10
+!Alias pkcs12-BagIds pkcs12-Version1 1
+pkcs12-BagIds 1		:			: keyBag
+pkcs12-BagIds 2		:			: pkcs8ShroudedKeyBag
+pkcs12-BagIds 3		:			: certBag
+pkcs12-BagIds 4		:			: crlBag
+pkcs12-BagIds 5		:			: secretBag
+pkcs12-BagIds 6		:			: safeContentsBag
+
+rsadsi 2 2		: MD2			: md2
+rsadsi 2 4		: MD4			: md4
+rsadsi 2 5		: MD5			: md5
+			: MD5-SHA1		: md5-sha1
+rsadsi 2 6		:			: hmacWithMD5
+rsadsi 2 7		:			: hmacWithSHA1
+
+# From RFC4231
+rsadsi 2 8		:			: hmacWithSHA224
+rsadsi 2 9		:			: hmacWithSHA256
+rsadsi 2 10		:			: hmacWithSHA384
+rsadsi 2 11		:			: hmacWithSHA512
+
+rsadsi 3 2		: RC2-CBC		: rc2-cbc
+			: RC2-ECB		: rc2-ecb
+!Cname rc2-cfb64
+			: RC2-CFB		: rc2-cfb
+!Cname rc2-ofb64
+			: RC2-OFB		: rc2-ofb
+			: RC2-40-CBC		: rc2-40-cbc
+			: RC2-64-CBC		: rc2-64-cbc
+rsadsi 3 4		: RC4			: rc4
+			: RC4-40		: rc4-40
+rsadsi 3 7		: DES-EDE3-CBC		: des-ede3-cbc
+rsadsi 3 8		: RC5-CBC		: rc5-cbc
+			: RC5-ECB		: rc5-ecb
+!Cname rc5-cfb64
+			: RC5-CFB		: rc5-cfb
+!Cname rc5-ofb64
+			: RC5-OFB		: rc5-ofb
+
+!Cname ms-ext-req
+1 3 6 1 4 1 311 2 1 14	: msExtReq		: Microsoft Extension Request
+!Cname ms-code-ind
+1 3 6 1 4 1 311 2 1 21	: msCodeInd		: Microsoft Individual Code Signing
+!Cname ms-code-com
+1 3 6 1 4 1 311 2 1 22	: msCodeCom		: Microsoft Commercial Code Signing
+!Cname ms-ctl-sign
+1 3 6 1 4 1 311 10 3 1	: msCTLSign		: Microsoft Trust List Signing
+!Cname ms-sgc
+1 3 6 1 4 1 311 10 3 3	: msSGC			: Microsoft Server Gated Crypto
+!Cname ms-efs
+1 3 6 1 4 1 311 10 3 4	: msEFS			: Microsoft Encrypted File System
+!Cname ms-smartcard-login
+1 3 6 1 4 1 311 20 2 2	: msSmartcardLogin	: Microsoft Smartcardlogin
+!Cname ms-upn
+1 3 6 1 4 1 311 20 2 3	: msUPN			: Microsoft Universal Principal Name
+
+1 3 6 1 4 1 188 7 1 1 2	: IDEA-CBC		: idea-cbc
+			: IDEA-ECB		: idea-ecb
+!Cname idea-cfb64
+			: IDEA-CFB		: idea-cfb
+!Cname idea-ofb64
+			: IDEA-OFB		: idea-ofb
+
+1 3 6 1 4 1 3029 1 2	: BF-CBC		: bf-cbc
+			: BF-ECB		: bf-ecb
+!Cname bf-cfb64
+			: BF-CFB		: bf-cfb
+!Cname bf-ofb64
+			: BF-OFB		: bf-ofb
+
+!Cname id-pkix
+1 3 6 1 5 5 7		: PKIX
+
+# PKIX Arcs
+id-pkix 0		: id-pkix-mod
+id-pkix 1		: id-pe
+id-pkix 2		: id-qt
+id-pkix 3		: id-kp
+id-pkix 4		: id-it
+id-pkix 5		: id-pkip
+id-pkix 6		: id-alg
+id-pkix 7		: id-cmc
+id-pkix 8		: id-on
+id-pkix 9		: id-pda
+id-pkix 10		: id-aca
+id-pkix 11		: id-qcs
+id-pkix 12		: id-cct
+id-pkix 21		: id-ppl
+id-pkix 48		: id-ad
+
+# PKIX Modules
+id-pkix-mod 1		: id-pkix1-explicit-88
+id-pkix-mod 2		: id-pkix1-implicit-88
+id-pkix-mod 3		: id-pkix1-explicit-93
+id-pkix-mod 4		: id-pkix1-implicit-93
+id-pkix-mod 5		: id-mod-crmf
+id-pkix-mod 6		: id-mod-cmc
+id-pkix-mod 7		: id-mod-kea-profile-88
+id-pkix-mod 8		: id-mod-kea-profile-93
+id-pkix-mod 9		: id-mod-cmp
+id-pkix-mod 10		: id-mod-qualified-cert-88
+id-pkix-mod 11		: id-mod-qualified-cert-93
+id-pkix-mod 12		: id-mod-attribute-cert
+id-pkix-mod 13		: id-mod-timestamp-protocol
+id-pkix-mod 14		: id-mod-ocsp
+id-pkix-mod 15		: id-mod-dvcs
+id-pkix-mod 16		: id-mod-cmp2000
+
+# PKIX Private Extensions
+!Cname info-access
+id-pe 1			: authorityInfoAccess	: Authority Information Access
+id-pe 2			: biometricInfo		: Biometric Info
+id-pe 3			: qcStatements
+id-pe 4			: ac-auditEntity
+id-pe 5			: ac-targeting
+id-pe 6			: aaControls
+id-pe 7			: sbgp-ipAddrBlock
+id-pe 8			: sbgp-autonomousSysNum
+id-pe 9			: sbgp-routerIdentifier
+id-pe 10		: ac-proxying
+!Cname sinfo-access
+id-pe 11		: subjectInfoAccess	: Subject Information Access
+id-pe 14		: proxyCertInfo		: Proxy Certificate Information
+
+# PKIX policyQualifiers for Internet policy qualifiers
+id-qt 1			: id-qt-cps		: Policy Qualifier CPS
+id-qt 2			: id-qt-unotice		: Policy Qualifier User Notice
+id-qt 3			: textNotice
+
+# PKIX key purpose identifiers
+!Cname server-auth
+id-kp 1			: serverAuth		: TLS Web Server Authentication
+!Cname client-auth
+id-kp 2			: clientAuth		: TLS Web Client Authentication
+!Cname code-sign
+id-kp 3			: codeSigning		: Code Signing
+!Cname email-protect
+id-kp 4			: emailProtection	: E-mail Protection
+id-kp 5			: ipsecEndSystem	: IPSec End System
+id-kp 6			: ipsecTunnel		: IPSec Tunnel
+id-kp 7			: ipsecUser		: IPSec User
+!Cname time-stamp
+id-kp 8			: timeStamping		: Time Stamping
+# From OCSP spec RFC2560
+!Cname OCSP-sign
+id-kp 9			: OCSPSigning		: OCSP Signing
+id-kp 10		: DVCS			: dvcs
+
+# CMP information types
+id-it 1			: id-it-caProtEncCert
+id-it 2			: id-it-signKeyPairTypes
+id-it 3			: id-it-encKeyPairTypes
+id-it 4			: id-it-preferredSymmAlg
+id-it 5			: id-it-caKeyUpdateInfo
+id-it 6			: id-it-currentCRL
+id-it 7			: id-it-unsupportedOIDs
+# obsolete
+id-it 8			: id-it-subscriptionRequest
+# obsolete
+id-it 9			: id-it-subscriptionResponse
+id-it 10		: id-it-keyPairParamReq
+id-it 11		: id-it-keyPairParamRep
+id-it 12		: id-it-revPassphrase
+id-it 13		: id-it-implicitConfirm
+id-it 14		: id-it-confirmWaitTime
+id-it 15		: id-it-origPKIMessage
+id-it 16		: id-it-suppLangTags
+
+# CRMF registration
+id-pkip 1		: id-regCtrl
+id-pkip 2		: id-regInfo
+
+# CRMF registration controls
+id-regCtrl 1		: id-regCtrl-regToken
+id-regCtrl 2		: id-regCtrl-authenticator
+id-regCtrl 3		: id-regCtrl-pkiPublicationInfo
+id-regCtrl 4		: id-regCtrl-pkiArchiveOptions
+id-regCtrl 5		: id-regCtrl-oldCertID
+id-regCtrl 6		: id-regCtrl-protocolEncrKey
+
+# CRMF registration information
+id-regInfo 1		: id-regInfo-utf8Pairs
+id-regInfo 2		: id-regInfo-certReq
+
+# algorithms
+id-alg 1		: id-alg-des40
+id-alg 2		: id-alg-noSignature
+id-alg 3		: id-alg-dh-sig-hmac-sha1
+id-alg 4		: id-alg-dh-pop
+
+# CMC controls
+id-cmc 1		: id-cmc-statusInfo
+id-cmc 2		: id-cmc-identification
+id-cmc 3		: id-cmc-identityProof
+id-cmc 4		: id-cmc-dataReturn
+id-cmc 5		: id-cmc-transactionId
+id-cmc 6		: id-cmc-senderNonce
+id-cmc 7		: id-cmc-recipientNonce
+id-cmc 8		: id-cmc-addExtensions
+id-cmc 9		: id-cmc-encryptedPOP
+id-cmc 10		: id-cmc-decryptedPOP
+id-cmc 11		: id-cmc-lraPOPWitness
+id-cmc 15		: id-cmc-getCert
+id-cmc 16		: id-cmc-getCRL
+id-cmc 17		: id-cmc-revokeRequest
+id-cmc 18		: id-cmc-regInfo
+id-cmc 19		: id-cmc-responseInfo
+id-cmc 21		: id-cmc-queryPending
+id-cmc 22		: id-cmc-popLinkRandom
+id-cmc 23		: id-cmc-popLinkWitness
+id-cmc 24		: id-cmc-confirmCertAcceptance 
+
+# other names
+id-on 1			: id-on-personalData
+id-on 3			: id-on-permanentIdentifier : Permanent Identifier
+
+# personal data attributes
+id-pda 1		: id-pda-dateOfBirth
+id-pda 2		: id-pda-placeOfBirth
+id-pda 3		: id-pda-gender
+id-pda 4		: id-pda-countryOfCitizenship
+id-pda 5		: id-pda-countryOfResidence
+
+# attribute certificate attributes
+id-aca 1		: id-aca-authenticationInfo
+id-aca 2		: id-aca-accessIdentity
+id-aca 3		: id-aca-chargingIdentity
+id-aca 4		: id-aca-group
+# attention : the following seems to be obsolete, replace by 'role'
+id-aca 5		: id-aca-role
+id-aca 6		: id-aca-encAttrs
+
+# qualified certificate statements
+id-qcs 1		: id-qcs-pkixQCSyntax-v1
+
+# CMC content types
+id-cct 1		: id-cct-crs
+id-cct 2		: id-cct-PKIData
+id-cct 3		: id-cct-PKIResponse
+
+# Predefined Proxy Certificate policy languages
+id-ppl 0		: id-ppl-anyLanguage	: Any language
+id-ppl 1		: id-ppl-inheritAll	: Inherit all
+id-ppl 2		: id-ppl-independent	: Independent
+
+# access descriptors for authority info access extension
+!Cname ad-OCSP
+id-ad 1			: OCSP			: OCSP
+!Cname ad-ca-issuers
+id-ad 2			: caIssuers		: CA Issuers
+!Cname ad-timeStamping
+id-ad 3			: ad_timestamping	: AD Time Stamping
+!Cname ad-dvcs
+id-ad 4			: AD_DVCS		: ad dvcs
+id-ad 5			: caRepository		: CA Repository
+
+
+!Alias id-pkix-OCSP ad-OCSP
+!module id-pkix-OCSP
+!Cname basic
+id-pkix-OCSP 1		: basicOCSPResponse	: Basic OCSP Response
+id-pkix-OCSP 2		: Nonce			: OCSP Nonce
+id-pkix-OCSP 3		: CrlID			: OCSP CRL ID
+id-pkix-OCSP 4		: acceptableResponses	: Acceptable OCSP Responses
+id-pkix-OCSP 5		: noCheck		: OCSP No Check
+id-pkix-OCSP 6		: archiveCutoff		: OCSP Archive Cutoff
+id-pkix-OCSP 7		: serviceLocator	: OCSP Service Locator
+id-pkix-OCSP 8		: extendedStatus	: Extended OCSP Status
+id-pkix-OCSP 9		: valid
+id-pkix-OCSP 10		: path
+id-pkix-OCSP 11		: trustRoot		: Trust Root
+!global
+
+1 3 14 3 2		: algorithm		: algorithm
+algorithm 3		: RSA-NP-MD5		: md5WithRSA
+algorithm 6		: DES-ECB		: des-ecb
+algorithm 7		: DES-CBC		: des-cbc
+!Cname des-ofb64
+algorithm 8		: DES-OFB		: des-ofb
+!Cname des-cfb64
+algorithm 9		: DES-CFB		: des-cfb
+algorithm 11		: rsaSignature
+!Cname dsa-2
+algorithm 12		: DSA-old		: dsaEncryption-old
+algorithm 13		: DSA-SHA		: dsaWithSHA
+algorithm 15		: RSA-SHA		: shaWithRSAEncryption
+!Cname des-ede-ecb
+algorithm 17		: DES-EDE		: des-ede
+!Cname des-ede3-ecb
+			: DES-EDE3		: des-ede3
+			: DES-EDE-CBC		: des-ede-cbc
+!Cname des-ede-cfb64
+			: DES-EDE-CFB		: des-ede-cfb
+!Cname des-ede3-cfb64
+			: DES-EDE3-CFB		: des-ede3-cfb
+!Cname des-ede-ofb64
+			: DES-EDE-OFB		: des-ede-ofb
+!Cname des-ede3-ofb64
+			: DES-EDE3-OFB		: des-ede3-ofb
+			: DESX-CBC		: desx-cbc
+algorithm 18		: SHA			: sha
+algorithm 26		: SHA1			: sha1
+!Cname dsaWithSHA1-2
+algorithm 27		: DSA-SHA1-old		: dsaWithSHA1-old
+algorithm 29		: RSA-SHA1-2		: sha1WithRSA
+
+1 3 36 3 2 1		: RIPEMD160		: ripemd160
+1 3 36 3 3 1 2		: RSA-RIPEMD160		: ripemd160WithRSA
+
+!Cname sxnet
+1 3 101 1 4 1		: SXNetID		: Strong Extranet ID
+
+2 5			: X500			: directory services (X.500)
+
+X500 4			: X509
+X509 3			: CN			: commonName
+X509 4			: SN			: surname
+X509 5			: 			: serialNumber
+X509 6			: C			: countryName
+X509 7			: L			: localityName
+X509 8			: ST			: stateOrProvinceName
+X509 9			: street		: streetAddress
+X509 10			: O			: organizationName
+X509 11			: OU			: organizationalUnitName
+X509 12			: title			: title
+X509 13			: 			: description
+X509 14			: 			: searchGuide
+X509 15			: 			: businessCategory
+X509 16			: 			: postalAddress
+X509 17			: 			: postalCode
+X509 18			: 			: postOfficeBox
+X509 19			: 			: physicalDeliveryOfficeName
+X509 20			: 			: telephoneNumber
+X509 21			: 			: telexNumber
+X509 22			: 			: teletexTerminalIdentifier
+X509 23			: 			: facsimileTelephoneNumber
+X509 24			: 			: x121Address
+X509 25			: 			: internationaliSDNNumber
+X509 26			: 			: registeredAddress
+X509 27			: 			: destinationIndicator
+X509 28			: 			: preferredDeliveryMethod
+X509 29			: 			: presentationAddress
+X509 30			: 			: supportedApplicationContext
+X509 31			: member		:
+X509 32			: owner			:
+X509 33			: 			: roleOccupant
+X509 34			: seeAlso		:
+X509 35			: 			: userPassword
+X509 36			: 			: userCertificate
+X509 37			: 			: cACertificate
+X509 38			: 			: authorityRevocationList
+X509 39			: 			: certificateRevocationList
+X509 40			: 			: crossCertificatePair
+X509 41			: name			: name
+X509 42			: GN			: givenName
+X509 43			: initials		: initials
+X509 44			: 			: generationQualifier
+X509 45			: 			: x500UniqueIdentifier
+X509 46			: dnQualifier		: dnQualifier
+X509 47			: 			: enhancedSearchGuide
+X509 48			: 			: protocolInformation
+X509 49			: 			: distinguishedName
+X509 50			: 			: uniqueMember
+X509 51			: 			: houseIdentifier
+X509 52			: 			: supportedAlgorithms
+X509 53			: 			: deltaRevocationList
+X509 54			: dmdName		:
+X509 65			:			: pseudonym
+X509 72			: role			: role
+
+X500 8			: X500algorithms	: directory services - algorithms
+X500algorithms 1 1	: RSA			: rsa
+X500algorithms 3 100	: RSA-MDC2		: mdc2WithRSA
+X500algorithms 3 101	: MDC2			: mdc2
+
+X500 29			: id-ce
+!Cname subject-directory-attributes
+id-ce 9			: subjectDirectoryAttributes : X509v3 Subject Directory Attributes
+!Cname subject-key-identifier
+id-ce 14		: subjectKeyIdentifier	: X509v3 Subject Key Identifier
+!Cname key-usage
+id-ce 15		: keyUsage		: X509v3 Key Usage
+!Cname private-key-usage-period
+id-ce 16		: privateKeyUsagePeriod	: X509v3 Private Key Usage Period
+!Cname subject-alt-name
+id-ce 17		: subjectAltName	: X509v3 Subject Alternative Name
+!Cname issuer-alt-name
+id-ce 18		: issuerAltName		: X509v3 Issuer Alternative Name
+!Cname basic-constraints
+id-ce 19		: basicConstraints	: X509v3 Basic Constraints
+!Cname crl-number
+id-ce 20		: crlNumber		: X509v3 CRL Number
+!Cname crl-reason
+id-ce 21		: CRLReason		: X509v3 CRL Reason Code
+!Cname invalidity-date
+id-ce 24		: invalidityDate	: Invalidity Date
+!Cname delta-crl
+id-ce 27		: deltaCRL		: X509v3 Delta CRL Indicator
+!Cname issuing-distribution-point
+id-ce 28		: issuingDistributionPoint : X509v3 Issuing Distrubution Point
+!Cname certificate-issuer
+id-ce 29		: certificateIssuer	: X509v3 Certificate Issuer
+!Cname name-constraints
+id-ce 30		: nameConstraints	: X509v3 Name Constraints
+!Cname crl-distribution-points
+id-ce 31		: crlDistributionPoints	: X509v3 CRL Distribution Points
+!Cname certificate-policies
+id-ce 32		: certificatePolicies	: X509v3 Certificate Policies
+!Cname any-policy
+certificate-policies 0	: anyPolicy		: X509v3 Any Policy
+!Cname policy-mappings
+id-ce 33		: policyMappings	: X509v3 Policy Mappings
+!Cname authority-key-identifier
+id-ce 35		: authorityKeyIdentifier : X509v3 Authority Key Identifier
+!Cname policy-constraints
+id-ce 36		: policyConstraints	: X509v3 Policy Constraints
+!Cname ext-key-usage
+id-ce 37		: extendedKeyUsage	: X509v3 Extended Key Usage
+!Cname freshest-crl
+id-ce 46		: freshestCRL		: X509v3 Freshest CRL
+!Cname inhibit-any-policy
+id-ce 54		: inhibitAnyPolicy	: X509v3 Inhibit Any Policy
+!Cname target-information
+id-ce 55		: targetInformation	: X509v3 AC Targeting
+!Cname no-rev-avail
+id-ce 56		: noRevAvail		: X509v3 No Revocation Available
+
+!Cname netscape
+2 16 840 1 113730	: Netscape		: Netscape Communications Corp.
+!Cname netscape-cert-extension
+netscape 1		: nsCertExt		: Netscape Certificate Extension
+!Cname netscape-data-type
+netscape 2		: nsDataType		: Netscape Data Type
+!Cname netscape-cert-type
+netscape-cert-extension 1 : nsCertType		: Netscape Cert Type
+!Cname netscape-base-url
+netscape-cert-extension 2 : nsBaseUrl		: Netscape Base Url
+!Cname netscape-revocation-url
+netscape-cert-extension 3 : nsRevocationUrl	: Netscape Revocation Url
+!Cname netscape-ca-revocation-url
+netscape-cert-extension 4 : nsCaRevocationUrl	: Netscape CA Revocation Url
+!Cname netscape-renewal-url
+netscape-cert-extension 7 : nsRenewalUrl	: Netscape Renewal Url
+!Cname netscape-ca-policy-url
+netscape-cert-extension 8 : nsCaPolicyUrl	: Netscape CA Policy Url
+!Cname netscape-ssl-server-name
+netscape-cert-extension 12 : nsSslServerName	: Netscape SSL Server Name
+!Cname netscape-comment
+netscape-cert-extension 13 : nsComment		: Netscape Comment
+!Cname netscape-cert-sequence
+netscape-data-type 5	: nsCertSequence	: Netscape Certificate Sequence
+!Cname ns-sgc
+netscape 4 1		: nsSGC			: Netscape Server Gated Crypto
+
+# iso(1)
+iso 3			: ORG			: org
+org 6			: DOD			: dod
+dod 1			: IANA			: iana
+!Alias internet iana
+
+internet 1		: directory		: Directory
+internet 2		: mgmt			: Management
+internet 3		: experimental		: Experimental
+internet 4		: private		: Private
+internet 5		: security		: Security
+internet 6		: snmpv2		: SNMPv2
+# Documents refer to "internet 7" as "mail". This however leads to ambiguities
+# with RFC2798, Section 9.1.3, where "mail" is defined as the short name for
+# rfc822Mailbox. The short name is therefore here left out for a reason.
+# Subclasses of "mail", e.g. "MIME MHS" don't consitute a problem, as
+# references are realized via long name "Mail" (with capital M).
+internet 7		:			: Mail
+
+Private 1		: enterprises		: Enterprises
+
+# RFC 2247
+Enterprises 1466 344	: dcobject		: dcObject
+
+# RFC 1495
+Mail 1			: mime-mhs		: MIME MHS
+mime-mhs 1		: mime-mhs-headings	: mime-mhs-headings
+mime-mhs 2		: mime-mhs-bodies	: mime-mhs-bodies
+mime-mhs-headings 1	: id-hex-partial-message : id-hex-partial-message
+mime-mhs-headings 2	: id-hex-multipart-message : id-hex-multipart-message
+
+# What the hell are these OIDs, really?
+!Cname rle-compression
+1 1 1 1 666 1		: RLE			: run length compression
+!Cname zlib-compression
+id-smime-alg 8		: ZLIB			: zlib compression
+
+# AES aka Rijndael
+
+!Alias csor 2 16 840 1 101 3
+!Alias nistAlgorithms csor 4
+!Alias aes nistAlgorithms 1
+
+aes 1			: AES-128-ECB		: aes-128-ecb
+aes 2			: AES-128-CBC		: aes-128-cbc
+!Cname aes-128-ofb128
+aes 3			: AES-128-OFB		: aes-128-ofb
+!Cname aes-128-cfb128
+aes 4			: AES-128-CFB		: aes-128-cfb
+
+aes 21			: AES-192-ECB		: aes-192-ecb
+aes 22			: AES-192-CBC		: aes-192-cbc
+!Cname aes-192-ofb128
+aes 23			: AES-192-OFB		: aes-192-ofb
+!Cname aes-192-cfb128
+aes 24			: AES-192-CFB		: aes-192-cfb
+
+aes 41			: AES-256-ECB		: aes-256-ecb
+aes 42			: AES-256-CBC		: aes-256-cbc
+!Cname aes-256-ofb128
+aes 43			: AES-256-OFB		: aes-256-ofb
+!Cname aes-256-cfb128
+aes 44			: AES-256-CFB		: aes-256-cfb
+
+# There are no OIDs for these modes...
+
+			: AES-128-CFB1		: aes-128-cfb1
+			: AES-192-CFB1		: aes-192-cfb1
+			: AES-256-CFB1		: aes-256-cfb1
+			: AES-128-CFB8		: aes-128-cfb8
+			: AES-192-CFB8		: aes-192-cfb8
+			: AES-256-CFB8		: aes-256-cfb8
+			: DES-CFB1		: des-cfb1
+			: DES-CFB8		: des-cfb8
+			: DES-EDE3-CFB1		: des-ede3-cfb1
+			: DES-EDE3-CFB8		: des-ede3-cfb8
+
+aes 5			: id-aes128-wrap 
+aes 25			: id-aes192-wrap 
+aes 45			: id-aes256-wrap 
+
+# OIDs for SHA224, SHA256, SHA385 and SHA512, according to x9.84.
+!Alias nist_hashalgs nistAlgorithms 2
+nist_hashalgs 1		: SHA256		: sha256
+nist_hashalgs 2		: SHA384		: sha384
+nist_hashalgs 3		: SHA512		: sha512
+nist_hashalgs 4		: SHA224		: sha224
+
+# OIDs for dsa-with-sha224 and dsa-with-sha256
+!Alias dsa_with_sha2 nistAlgorithms 3
+dsa_with_sha2 1		: dsa_with_SHA224
+dsa_with_sha2 2		: dsa_with_SHA256
+
+# Hold instruction CRL entry extension
+!Cname hold-instruction-code
+id-ce 23		: holdInstructionCode	: Hold Instruction Code
+!Alias holdInstruction	X9-57 2
+!Cname hold-instruction-none
+holdInstruction 1	: holdInstructionNone	: Hold Instruction None
+!Cname hold-instruction-call-issuer
+holdInstruction 2	: holdInstructionCallIssuer : Hold Instruction Call Issuer
+!Cname hold-instruction-reject
+holdInstruction 3	: holdInstructionReject	: Hold Instruction Reject
+
+# OID's from ITU-T.  Most of this is defined in RFC 1274.  A couple of
+# them are also mentioned in RFC 2247
+itu-t 9			: data
+data 2342		: pss
+pss 19200300		: ucl
+ucl 100			: pilot
+pilot 1			:			: pilotAttributeType
+pilot 3			:			: pilotAttributeSyntax
+pilot 4			:			: pilotObjectClass
+pilot 10		:			: pilotGroups
+pilotAttributeSyntax 4	:			: iA5StringSyntax
+pilotAttributeSyntax 5	:			: caseIgnoreIA5StringSyntax
+pilotObjectClass 3	:			: pilotObject
+pilotObjectClass 4	:			: pilotPerson
+pilotObjectClass 5	: account
+pilotObjectClass 6	: document
+pilotObjectClass 7	: room
+pilotObjectClass 9	:			: documentSeries
+pilotObjectClass 13	: domain		: Domain
+pilotObjectClass 14	:			: rFC822localPart
+pilotObjectClass 15	:			: dNSDomain
+pilotObjectClass 17	:			: domainRelatedObject
+pilotObjectClass 18	:			: friendlyCountry
+pilotObjectClass 19	:			: simpleSecurityObject
+pilotObjectClass 20	:			: pilotOrganization
+pilotObjectClass 21	:			: pilotDSA
+pilotObjectClass 22	:			: qualityLabelledData
+pilotAttributeType 1	: UID			: userId
+pilotAttributeType 2	:			: textEncodedORAddress
+pilotAttributeType 3	: mail			: rfc822Mailbox
+pilotAttributeType 4	: info
+pilotAttributeType 5	:			: favouriteDrink
+pilotAttributeType 6	:			: roomNumber
+pilotAttributeType 7	: photo
+pilotAttributeType 8	:			: userClass
+pilotAttributeType 9	: host
+pilotAttributeType 10	: manager
+pilotAttributeType 11	:			: documentIdentifier
+pilotAttributeType 12	:			: documentTitle
+pilotAttributeType 13	:			: documentVersion
+pilotAttributeType 14	:			: documentAuthor
+pilotAttributeType 15	:			: documentLocation
+pilotAttributeType 20	:			: homeTelephoneNumber
+pilotAttributeType 21	: secretary
+pilotAttributeType 22	:			: otherMailbox
+pilotAttributeType 23	:			: lastModifiedTime
+pilotAttributeType 24	:			: lastModifiedBy
+pilotAttributeType 25	: DC			: domainComponent
+pilotAttributeType 26	:			: aRecord
+pilotAttributeType 27	:			: pilotAttributeType27
+pilotAttributeType 28	:			: mXRecord
+pilotAttributeType 29	:			: nSRecord
+pilotAttributeType 30	:			: sOARecord
+pilotAttributeType 31	:			: cNAMERecord
+pilotAttributeType 37	:			: associatedDomain
+pilotAttributeType 38	:			: associatedName
+pilotAttributeType 39	:			: homePostalAddress
+pilotAttributeType 40	:			: personalTitle
+pilotAttributeType 41	:			: mobileTelephoneNumber
+pilotAttributeType 42	:			: pagerTelephoneNumber
+pilotAttributeType 43	:			: friendlyCountryName
+# The following clashes with 2.5.4.45, so commented away
+#pilotAttributeType 44	: uid			: uniqueIdentifier
+pilotAttributeType 45	:			: organizationalStatus
+pilotAttributeType 46	:			: janetMailbox
+pilotAttributeType 47	:			: mailPreferenceOption
+pilotAttributeType 48	:			: buildingName
+pilotAttributeType 49	:			: dSAQuality
+pilotAttributeType 50	:			: singleLevelQuality
+pilotAttributeType 51	:			: subtreeMinimumQuality
+pilotAttributeType 52	:			: subtreeMaximumQuality
+pilotAttributeType 53	:			: personalSignature
+pilotAttributeType 54	:			: dITRedirect
+pilotAttributeType 55	: audio
+pilotAttributeType 56	:			: documentPublisher
+
+international-organizations 42	: id-set	: Secure Electronic Transactions
+
+id-set 0		: set-ctype		: content types
+id-set 1		: set-msgExt		: message extensions
+id-set 3		: set-attr
+id-set 5		: set-policy
+id-set 7		: set-certExt		: certificate extensions
+id-set 8		: set-brand
+
+set-ctype 0		: setct-PANData
+set-ctype 1		: setct-PANToken
+set-ctype 2		: setct-PANOnly
+set-ctype 3		: setct-OIData
+set-ctype 4		: setct-PI
+set-ctype 5		: setct-PIData
+set-ctype 6		: setct-PIDataUnsigned
+set-ctype 7		: setct-HODInput
+set-ctype 8		: setct-AuthResBaggage
+set-ctype 9		: setct-AuthRevReqBaggage
+set-ctype 10		: setct-AuthRevResBaggage
+set-ctype 11		: setct-CapTokenSeq
+set-ctype 12		: setct-PInitResData
+set-ctype 13		: setct-PI-TBS
+set-ctype 14		: setct-PResData
+set-ctype 16		: setct-AuthReqTBS
+set-ctype 17		: setct-AuthResTBS
+set-ctype 18		: setct-AuthResTBSX
+set-ctype 19		: setct-AuthTokenTBS
+set-ctype 20		: setct-CapTokenData
+set-ctype 21		: setct-CapTokenTBS
+set-ctype 22		: setct-AcqCardCodeMsg
+set-ctype 23		: setct-AuthRevReqTBS
+set-ctype 24		: setct-AuthRevResData
+set-ctype 25		: setct-AuthRevResTBS
+set-ctype 26		: setct-CapReqTBS
+set-ctype 27		: setct-CapReqTBSX
+set-ctype 28		: setct-CapResData
+set-ctype 29		: setct-CapRevReqTBS
+set-ctype 30		: setct-CapRevReqTBSX
+set-ctype 31		: setct-CapRevResData
+set-ctype 32		: setct-CredReqTBS
+set-ctype 33		: setct-CredReqTBSX
+set-ctype 34		: setct-CredResData
+set-ctype 35		: setct-CredRevReqTBS
+set-ctype 36		: setct-CredRevReqTBSX
+set-ctype 37		: setct-CredRevResData
+set-ctype 38		: setct-PCertReqData
+set-ctype 39		: setct-PCertResTBS
+set-ctype 40		: setct-BatchAdminReqData
+set-ctype 41		: setct-BatchAdminResData
+set-ctype 42		: setct-CardCInitResTBS
+set-ctype 43		: setct-MeAqCInitResTBS
+set-ctype 44		: setct-RegFormResTBS
+set-ctype 45		: setct-CertReqData
+set-ctype 46		: setct-CertReqTBS
+set-ctype 47		: setct-CertResData
+set-ctype 48		: setct-CertInqReqTBS
+set-ctype 49		: setct-ErrorTBS
+set-ctype 50		: setct-PIDualSignedTBE
+set-ctype 51		: setct-PIUnsignedTBE
+set-ctype 52		: setct-AuthReqTBE
+set-ctype 53		: setct-AuthResTBE
+set-ctype 54		: setct-AuthResTBEX
+set-ctype 55		: setct-AuthTokenTBE
+set-ctype 56		: setct-CapTokenTBE
+set-ctype 57		: setct-CapTokenTBEX
+set-ctype 58		: setct-AcqCardCodeMsgTBE
+set-ctype 59		: setct-AuthRevReqTBE
+set-ctype 60		: setct-AuthRevResTBE
+set-ctype 61		: setct-AuthRevResTBEB
+set-ctype 62		: setct-CapReqTBE
+set-ctype 63		: setct-CapReqTBEX
+set-ctype 64		: setct-CapResTBE
+set-ctype 65		: setct-CapRevReqTBE
+set-ctype 66		: setct-CapRevReqTBEX
+set-ctype 67		: setct-CapRevResTBE
+set-ctype 68		: setct-CredReqTBE
+set-ctype 69		: setct-CredReqTBEX
+set-ctype 70		: setct-CredResTBE
+set-ctype 71		: setct-CredRevReqTBE
+set-ctype 72		: setct-CredRevReqTBEX
+set-ctype 73		: setct-CredRevResTBE
+set-ctype 74		: setct-BatchAdminReqTBE
+set-ctype 75		: setct-BatchAdminResTBE
+set-ctype 76		: setct-RegFormReqTBE
+set-ctype 77		: setct-CertReqTBE
+set-ctype 78		: setct-CertReqTBEX
+set-ctype 79		: setct-CertResTBE
+set-ctype 80		: setct-CRLNotificationTBS
+set-ctype 81		: setct-CRLNotificationResTBS
+set-ctype 82		: setct-BCIDistributionTBS
+
+set-msgExt 1		: setext-genCrypt	: generic cryptogram
+set-msgExt 3		: setext-miAuth		: merchant initiated auth
+set-msgExt 4		: setext-pinSecure
+set-msgExt 5		: setext-pinAny
+set-msgExt 7		: setext-track2
+set-msgExt 8		: setext-cv		: additional verification
+
+set-policy 0		: set-policy-root
+
+set-certExt 0		: setCext-hashedRoot
+set-certExt 1		: setCext-certType
+set-certExt 2		: setCext-merchData
+set-certExt 3		: setCext-cCertRequired
+set-certExt 4		: setCext-tunneling
+set-certExt 5		: setCext-setExt
+set-certExt 6		: setCext-setQualf
+set-certExt 7		: setCext-PGWYcapabilities
+set-certExt 8		: setCext-TokenIdentifier
+set-certExt 9		: setCext-Track2Data
+set-certExt 10		: setCext-TokenType
+set-certExt 11		: setCext-IssuerCapabilities
+
+set-attr 0		: setAttr-Cert
+set-attr 1		: setAttr-PGWYcap	: payment gateway capabilities
+set-attr 2		: setAttr-TokenType
+set-attr 3		: setAttr-IssCap	: issuer capabilities
+
+setAttr-Cert 0		: set-rootKeyThumb
+setAttr-Cert 1		: set-addPolicy
+
+setAttr-TokenType 1	: setAttr-Token-EMV
+setAttr-TokenType 2	: setAttr-Token-B0Prime
+
+setAttr-IssCap 3	: setAttr-IssCap-CVM
+setAttr-IssCap 4	: setAttr-IssCap-T2
+setAttr-IssCap 5	: setAttr-IssCap-Sig
+
+setAttr-IssCap-CVM 1	: setAttr-GenCryptgrm	: generate cryptogram
+setAttr-IssCap-T2 1	: setAttr-T2Enc		: encrypted track 2
+setAttr-IssCap-T2 2	: setAttr-T2cleartxt	: cleartext track 2
+
+setAttr-IssCap-Sig 1	: setAttr-TokICCsig	: ICC or token signature
+setAttr-IssCap-Sig 2	: setAttr-SecDevSig	: secure device signature
+
+set-brand 1		: set-brand-IATA-ATA
+set-brand 30		: set-brand-Diners
+set-brand 34		: set-brand-AmericanExpress
+set-brand 35		: set-brand-JCB
+set-brand 4		: set-brand-Visa
+set-brand 5		: set-brand-MasterCard
+set-brand 6011		: set-brand-Novus
+
+rsadsi 3 10		: DES-CDMF		: des-cdmf
+rsadsi 1 1 6		: rsaOAEPEncryptionSET
+
+			: Oakley-EC2N-3		: ipsec3
+			: Oakley-EC2N-4		: ipsec4
+
+iso 0 10118 3 0 55	: whirlpool
+
+# GOST OIDs
+
+member-body 643 2 2	: cryptopro
+member-body 643 2 9	: cryptocom
+
+cryptopro 3		: id-GostR3411-94-with-GostR3410-2001 : GOST R 34.11-94 with GOST R 34.10-2001
+cryptopro 4		: id-GostR3411-94-with-GostR3410-94 : GOST R 34.11-94 with GOST R 34.10-94
+!Cname id-GostR3411-94
+cryptopro 9		: md_gost94		: GOST R 34.11-94
+cryptopro 10		: id-HMACGostR3411-94	: HMAC GOST 34.11-94
+!Cname id-GostR3410-2001
+cryptopro 19		: gost2001	: GOST R 34.10-2001
+!Cname id-GostR3410-94
+cryptopro 20		: gost94	: GOST R 34.10-94
+!Cname id-Gost28147-89
+cryptopro 21		: gost89 		: GOST 28147-89
+			: gost89-cnt
+!Cname id-Gost28147-89-MAC
+cryptopro 22		: gost-mac	: GOST 28147-89 MAC
+!Cname id-GostR3411-94-prf
+cryptopro 23		: prf-gostr3411-94	: GOST R 34.11-94 PRF
+cryptopro 98		: id-GostR3410-2001DH	: GOST R 34.10-2001 DH
+cryptopro 99		: id-GostR3410-94DH	: GOST R 34.10-94 DH
+
+cryptopro 14 1		: id-Gost28147-89-CryptoPro-KeyMeshing
+cryptopro 14 0		: id-Gost28147-89-None-KeyMeshing
+
+# GOST parameter set OIDs
+
+cryptopro 30 0		: id-GostR3411-94-TestParamSet
+cryptopro 30 1		: id-GostR3411-94-CryptoProParamSet
+
+cryptopro 31 0		: id-Gost28147-89-TestParamSet
+cryptopro 31 1		: id-Gost28147-89-CryptoPro-A-ParamSet
+cryptopro 31 2		: id-Gost28147-89-CryptoPro-B-ParamSet
+cryptopro 31 3		: id-Gost28147-89-CryptoPro-C-ParamSet
+cryptopro 31 4		: id-Gost28147-89-CryptoPro-D-ParamSet
+cryptopro 31 5		: id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet
+cryptopro 31 6		: id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet
+cryptopro 31 7		: id-Gost28147-89-CryptoPro-RIC-1-ParamSet
+
+cryptopro 32 0		: id-GostR3410-94-TestParamSet
+cryptopro 32 2		: id-GostR3410-94-CryptoPro-A-ParamSet
+cryptopro 32 3		: id-GostR3410-94-CryptoPro-B-ParamSet
+cryptopro 32 4		: id-GostR3410-94-CryptoPro-C-ParamSet
+cryptopro 32 5		: id-GostR3410-94-CryptoPro-D-ParamSet
+
+cryptopro 33 1		: id-GostR3410-94-CryptoPro-XchA-ParamSet
+cryptopro 33 2		: id-GostR3410-94-CryptoPro-XchB-ParamSet
+cryptopro 33 3		: id-GostR3410-94-CryptoPro-XchC-ParamSet
+
+cryptopro 35 0		: id-GostR3410-2001-TestParamSet
+cryptopro 35 1		: id-GostR3410-2001-CryptoPro-A-ParamSet
+cryptopro 35 2		: id-GostR3410-2001-CryptoPro-B-ParamSet
+cryptopro 35 3		: id-GostR3410-2001-CryptoPro-C-ParamSet
+
+cryptopro 36 0		: id-GostR3410-2001-CryptoPro-XchA-ParamSet
+cryptopro 36 1		: id-GostR3410-2001-CryptoPro-XchB-ParamSet
+
+id-GostR3410-94 1	: id-GostR3410-94-a
+id-GostR3410-94 2	: id-GostR3410-94-aBis
+id-GostR3410-94 3	: id-GostR3410-94-b
+id-GostR3410-94 4	: id-GostR3410-94-bBis
+
+# Cryptocom LTD GOST OIDs
+
+cryptocom 1 6 1		: id-Gost28147-89-cc	: GOST 28147-89 Cryptocom ParamSet
+!Cname id-GostR3410-94-cc
+cryptocom 1 5 3		: gost94cc	: GOST 34.10-94 Cryptocom
+!Cname id-GostR3410-2001-cc
+cryptocom 1 5 4		: gost2001cc	: GOST 34.10-2001 Cryptocom
+
+cryptocom 1 3 3		: id-GostR3411-94-with-GostR3410-94-cc : GOST R 34.11-94 with GOST R 34.10-94 Cryptocom
+cryptocom 1 3 4		: id-GostR3411-94-with-GostR3410-2001-cc : GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom
+
+cryptocom 1 8 1		: id-GostR3410-2001-ParamSet-cc : GOST R 3410-2001 Parameter Set Cryptocom
+
+# Definitions for Camellia cipher - CBC MODE
+
+1 2 392 200011 61 1 1 1 2 : CAMELLIA-128-CBC		: camellia-128-cbc
+1 2 392 200011 61 1 1 1 3 : CAMELLIA-192-CBC		: camellia-192-cbc
+1 2 392 200011 61 1 1 1 4 : CAMELLIA-256-CBC		: camellia-256-cbc
+
+# Definitions for Camellia cipher - ECB, CFB, OFB MODE
+
+!Alias ntt-ds 0 3 4401 5
+!Alias camellia ntt-ds 3 1 9 
+
+camellia 1		: CAMELLIA-128-ECB		: camellia-128-ecb
+!Cname camellia-128-ofb128
+camellia 3		: CAMELLIA-128-OFB		: camellia-128-ofb
+!Cname camellia-128-cfb128
+camellia 4		: CAMELLIA-128-CFB		: camellia-128-cfb
+
+camellia 21		: CAMELLIA-192-ECB		: camellia-192-ecb
+!Cname camellia-192-ofb128
+camellia 23		: CAMELLIA-192-OFB		: camellia-192-ofb
+!Cname camellia-192-cfb128
+camellia 24		: CAMELLIA-192-CFB		: camellia-192-cfb
+
+camellia 41		: CAMELLIA-256-ECB		: camellia-256-ecb
+!Cname camellia-256-ofb128
+camellia 43		: CAMELLIA-256-OFB		: camellia-256-ofb
+!Cname camellia-256-cfb128
+camellia 44		: CAMELLIA-256-CFB		: camellia-256-cfb
+
+# There are no OIDs for these modes...
+
+			: CAMELLIA-128-CFB1		: camellia-128-cfb1
+			: CAMELLIA-192-CFB1		: camellia-192-cfb1
+			: CAMELLIA-256-CFB1		: camellia-256-cfb1
+			: CAMELLIA-128-CFB8		: camellia-128-cfb8
+			: CAMELLIA-192-CFB8		: camellia-192-cfb8
+			: CAMELLIA-256-CFB8		: camellia-256-cfb8
+
+# Definitions for SEED cipher - ECB, CBC, OFB mode
+
+member-body 410 200004  : KISA          : kisa
+kisa 1 3                : SEED-ECB      : seed-ecb
+kisa 1 4                : SEED-CBC      : seed-cbc
+!Cname seed-cfb128
+kisa 1 5                : SEED-CFB      : seed-cfb
+!Cname seed-ofb128
+kisa 1 6                : SEED-OFB      : seed-ofb
+
+# There is no OID that just denotes "HMAC" oddly enough...
+
+			: HMAC				: hmac
diff --git a/openssl/crypto/objects/objxref.pl b/openssl/crypto/objects/objxref.pl
new file mode 100644
index 0000000..731d3ae
--- /dev/null
+++ b/openssl/crypto/objects/objxref.pl
@@ -0,0 +1,107 @@
+#!/usr/local/bin/perl
+
+use strict;
+
+my %xref_tbl;
+my %oid_tbl;
+
+my ($mac_file, $xref_file) = @ARGV;
+
+open(IN, $mac_file) || die "Can't open $mac_file";
+
+# Read in OID nid values for a lookup table.
+
+while (<IN>)
+	{
+	chomp;
+	my ($name, $num) = /^(\S+)\s+(\S+)$/;
+	$oid_tbl{$name} = $num;
+	}
+close IN;
+
+open(IN, $xref_file) || die "Can't open $xref_file";
+
+my $ln = 1;
+
+while (<IN>)
+	{
+	chomp;
+	s/#.*$//;
+	next if (/^\S*$/);
+	my ($xr, $p1, $p2) = /^(\S+)\s+(\S+)\s+(\S+)/;
+	check_oid($xr);
+	check_oid($p1);
+	check_oid($p2);
+	$xref_tbl{$xr} = [$p1, $p2, $ln];
+	}
+
+my @xrkeys = keys %xref_tbl;
+
+my @srt1 = sort { $oid_tbl{$a} <=> $oid_tbl{$b}} @xrkeys;
+
+for(my $i = 0; $i <= $#srt1; $i++)
+	{
+	$xref_tbl{$srt1[$i]}[2] = $i;
+	}
+
+my @srt2 = sort
+	{
+	my$ap1 = $oid_tbl{$xref_tbl{$a}[0]};
+	my$bp1 = $oid_tbl{$xref_tbl{$b}[0]};
+	return $ap1 - $bp1 if ($ap1 != $bp1);
+	my$ap2 = $oid_tbl{$xref_tbl{$a}[1]};
+	my$bp2 = $oid_tbl{$xref_tbl{$b}[1]};
+
+	return $ap2 - $bp2;
+	} @xrkeys;
+
+my $pname = $0;
+
+$pname =~ s|^.[^/]/||;
+
+print <<EOF;
+/* AUTOGENERATED BY $pname, DO NOT EDIT */
+
+typedef struct
+	{
+	int sign_id;
+	int hash_id;
+	int pkey_id;
+	} nid_triple;
+
+static const nid_triple sigoid_srt[] =
+	{
+EOF
+
+foreach (@srt1)
+	{
+	my $xr = $_;
+	my ($p1, $p2) = @{$xref_tbl{$_}};
+	print "\t{NID_$xr, NID_$p1, NID_$p2},\n";
+	}
+
+print "\t};";
+print <<EOF;
+
+
+static const nid_triple * const sigoid_srt_xref[] =
+	{
+EOF
+
+foreach (@srt2)
+	{
+	my $x = $xref_tbl{$_}[2];
+	print "\t\&sigoid_srt\[$x\],\n";
+	}
+
+print "\t};\n\n";
+
+sub check_oid
+	{
+	my ($chk) = @_;
+	if (!exists $oid_tbl{$chk})
+		{
+		die "Not Found \"$chk\"\n";
+		}
+	}
+
diff --git a/openssl/crypto/ocsp/Makefile b/openssl/crypto/ocsp/Makefile
new file mode 100644
index 0000000..60c414c
--- /dev/null
+++ b/openssl/crypto/ocsp/Makefile
@@ -0,0 +1,213 @@
+#
+# OpenSSL/ocsp/Makefile
+#
+
+DIR=	ocsp
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile README
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= ocsp_asn.c ocsp_ext.c ocsp_ht.c ocsp_lib.c ocsp_cl.c \
+	ocsp_srv.c ocsp_prn.c ocsp_vfy.c ocsp_err.c
+
+LIBOBJ= ocsp_asn.o ocsp_ext.o ocsp_ht.o ocsp_lib.o ocsp_cl.o \
+	ocsp_srv.o ocsp_prn.o ocsp_vfy.o ocsp_err.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= ocsp.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+ocsp_asn.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+ocsp_asn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+ocsp_asn.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+ocsp_asn.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ocsp_asn.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ocsp_asn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+ocsp_asn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ocsp_asn.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
+ocsp_asn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ocsp_asn.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+ocsp_asn.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ocsp_asn.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+ocsp_asn.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+ocsp_asn.o: ocsp_asn.c
+ocsp_cl.o: ../../e_os.h ../../include/openssl/asn1.h
+ocsp_cl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+ocsp_cl.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+ocsp_cl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ocsp_cl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ocsp_cl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+ocsp_cl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ocsp_cl.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
+ocsp_cl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+ocsp_cl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
+ocsp_cl.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
+ocsp_cl.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+ocsp_cl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ocsp_cl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+ocsp_cl.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+ocsp_cl.o: ../cryptlib.h ocsp_cl.c
+ocsp_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ocsp_err.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+ocsp_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+ocsp_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+ocsp_err.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+ocsp_err.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+ocsp_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ocsp_err.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
+ocsp_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ocsp_err.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+ocsp_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ocsp_err.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+ocsp_err.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+ocsp_err.o: ocsp_err.c
+ocsp_ext.o: ../../e_os.h ../../include/openssl/asn1.h
+ocsp_ext.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+ocsp_ext.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+ocsp_ext.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ocsp_ext.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ocsp_ext.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+ocsp_ext.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ocsp_ext.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
+ocsp_ext.o: ../../include/openssl/opensslconf.h
+ocsp_ext.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ocsp_ext.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+ocsp_ext.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+ocsp_ext.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ocsp_ext.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ocsp_ext.o: ../../include/openssl/x509v3.h ../cryptlib.h ocsp_ext.c
+ocsp_ht.o: ../../e_os.h ../../include/openssl/asn1.h
+ocsp_ht.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+ocsp_ht.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+ocsp_ht.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ocsp_ht.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ocsp_ht.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+ocsp_ht.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ocsp_ht.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
+ocsp_ht.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+ocsp_ht.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+ocsp_ht.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+ocsp_ht.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ocsp_ht.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ocsp_ht.o: ../../include/openssl/x509v3.h ocsp_ht.c
+ocsp_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+ocsp_lib.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+ocsp_lib.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+ocsp_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+ocsp_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+ocsp_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+ocsp_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+ocsp_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ocsp_lib.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
+ocsp_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ocsp_lib.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+ocsp_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+ocsp_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+ocsp_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ocsp_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ocsp_lib.o: ../../include/openssl/x509v3.h ../cryptlib.h ocsp_lib.c
+ocsp_prn.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ocsp_prn.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+ocsp_prn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+ocsp_prn.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+ocsp_prn.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+ocsp_prn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+ocsp_prn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ocsp_prn.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
+ocsp_prn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ocsp_prn.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+ocsp_prn.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+ocsp_prn.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ocsp_prn.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+ocsp_prn.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+ocsp_prn.o: ocsp_prn.c
+ocsp_srv.o: ../../e_os.h ../../include/openssl/asn1.h
+ocsp_srv.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+ocsp_srv.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+ocsp_srv.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ocsp_srv.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ocsp_srv.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+ocsp_srv.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ocsp_srv.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
+ocsp_srv.o: ../../include/openssl/opensslconf.h
+ocsp_srv.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ocsp_srv.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+ocsp_srv.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+ocsp_srv.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+ocsp_srv.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ocsp_srv.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ocsp_srv.o: ../../include/openssl/x509v3.h ../cryptlib.h ocsp_srv.c
+ocsp_vfy.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ocsp_vfy.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+ocsp_vfy.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+ocsp_vfy.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+ocsp_vfy.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+ocsp_vfy.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+ocsp_vfy.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ocsp_vfy.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
+ocsp_vfy.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ocsp_vfy.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+ocsp_vfy.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ocsp_vfy.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+ocsp_vfy.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+ocsp_vfy.o: ocsp_vfy.c
diff --git a/openssl/crypto/ocsp/ocsp.h b/openssl/crypto/ocsp/ocsp.h
new file mode 100644
index 0000000..31e4574
--- /dev/null
+++ b/openssl/crypto/ocsp/ocsp.h
@@ -0,0 +1,623 @@
+/* ocsp.h */
+/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
+ * project. */
+
+/* History:
+   This file was transfered to Richard Levitte from CertCo by Kathy
+   Weinhold in mid-spring 2000 to be included in OpenSSL or released
+   as a patch kit. */
+
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_OCSP_H
+#define HEADER_OCSP_H
+
+#include <openssl/ossl_typ.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/safestack.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Various flags and values */
+
+#define OCSP_DEFAULT_NONCE_LENGTH	16
+
+#define OCSP_NOCERTS			0x1
+#define OCSP_NOINTERN			0x2
+#define OCSP_NOSIGS			0x4
+#define OCSP_NOCHAIN			0x8
+#define OCSP_NOVERIFY			0x10
+#define OCSP_NOEXPLICIT			0x20
+#define OCSP_NOCASIGN			0x40
+#define OCSP_NODELEGATED		0x80
+#define OCSP_NOCHECKS			0x100
+#define OCSP_TRUSTOTHER			0x200
+#define OCSP_RESPID_KEY			0x400
+#define OCSP_NOTIME			0x800
+
+/*   CertID ::= SEQUENCE {
+ *       hashAlgorithm            AlgorithmIdentifier,
+ *       issuerNameHash     OCTET STRING, -- Hash of Issuer's DN
+ *       issuerKeyHash      OCTET STRING, -- Hash of Issuers public key (excluding the tag & length fields)
+ *       serialNumber       CertificateSerialNumber }
+ */
+typedef struct ocsp_cert_id_st
+	{
+	X509_ALGOR *hashAlgorithm;
+	ASN1_OCTET_STRING *issuerNameHash;
+	ASN1_OCTET_STRING *issuerKeyHash;
+	ASN1_INTEGER *serialNumber;
+	} OCSP_CERTID;
+
+DECLARE_STACK_OF(OCSP_CERTID)
+
+/*   Request ::=     SEQUENCE {
+ *       reqCert                    CertID,
+ *       singleRequestExtensions    [0] EXPLICIT Extensions OPTIONAL }
+ */
+typedef struct ocsp_one_request_st
+	{
+	OCSP_CERTID *reqCert;
+	STACK_OF(X509_EXTENSION) *singleRequestExtensions;
+	} OCSP_ONEREQ;
+
+DECLARE_STACK_OF(OCSP_ONEREQ)
+DECLARE_ASN1_SET_OF(OCSP_ONEREQ)
+
+
+/*   TBSRequest      ::=     SEQUENCE {
+ *       version             [0] EXPLICIT Version DEFAULT v1,
+ *       requestorName       [1] EXPLICIT GeneralName OPTIONAL,
+ *       requestList             SEQUENCE OF Request,
+ *       requestExtensions   [2] EXPLICIT Extensions OPTIONAL }
+ */
+typedef struct ocsp_req_info_st
+	{
+	ASN1_INTEGER *version;
+	GENERAL_NAME *requestorName;
+	STACK_OF(OCSP_ONEREQ) *requestList;
+	STACK_OF(X509_EXTENSION) *requestExtensions;
+	} OCSP_REQINFO;
+
+/*   Signature       ::=     SEQUENCE {
+ *       signatureAlgorithm   AlgorithmIdentifier,
+ *       signature            BIT STRING,
+ *       certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ */
+typedef struct ocsp_signature_st
+	{
+	X509_ALGOR *signatureAlgorithm;
+	ASN1_BIT_STRING *signature;
+	STACK_OF(X509) *certs;
+	} OCSP_SIGNATURE;
+
+/*   OCSPRequest     ::=     SEQUENCE {
+ *       tbsRequest                  TBSRequest,
+ *       optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
+ */
+typedef struct ocsp_request_st
+	{
+	OCSP_REQINFO *tbsRequest;
+	OCSP_SIGNATURE *optionalSignature; /* OPTIONAL */
+	} OCSP_REQUEST;
+
+/*   OCSPResponseStatus ::= ENUMERATED {
+ *       successful            (0),      --Response has valid confirmations
+ *       malformedRequest      (1),      --Illegal confirmation request
+ *       internalError         (2),      --Internal error in issuer
+ *       tryLater              (3),      --Try again later
+ *                                       --(4) is not used
+ *       sigRequired           (5),      --Must sign the request
+ *       unauthorized          (6)       --Request unauthorized
+ *   }
+ */
+#define OCSP_RESPONSE_STATUS_SUCCESSFUL          0
+#define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST     1
+#define OCSP_RESPONSE_STATUS_INTERNALERROR        2
+#define OCSP_RESPONSE_STATUS_TRYLATER             3
+#define OCSP_RESPONSE_STATUS_SIGREQUIRED          5
+#define OCSP_RESPONSE_STATUS_UNAUTHORIZED         6
+
+/*   ResponseBytes ::=       SEQUENCE {
+ *       responseType   OBJECT IDENTIFIER,
+ *       response       OCTET STRING }
+ */
+typedef struct ocsp_resp_bytes_st
+	{
+	ASN1_OBJECT *responseType;
+	ASN1_OCTET_STRING *response;
+	} OCSP_RESPBYTES;
+
+/*   OCSPResponse ::= SEQUENCE {
+ *      responseStatus         OCSPResponseStatus,
+ *      responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
+ */
+struct ocsp_response_st
+	{
+	ASN1_ENUMERATED *responseStatus;
+	OCSP_RESPBYTES  *responseBytes;
+	};
+
+/*   ResponderID ::= CHOICE {
+ *      byName   [1] Name,
+ *      byKey    [2] KeyHash }
+ */
+#define V_OCSP_RESPID_NAME 0
+#define V_OCSP_RESPID_KEY  1
+struct ocsp_responder_id_st
+	{
+	int type;
+	union   {
+		X509_NAME* byName;
+        	ASN1_OCTET_STRING *byKey;
+		} value;
+	};
+
+DECLARE_STACK_OF(OCSP_RESPID)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPID)
+
+/*   KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key
+ *                            --(excluding the tag and length fields)
+ */
+
+/*   RevokedInfo ::= SEQUENCE {
+ *       revocationTime              GeneralizedTime,
+ *       revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
+ */
+typedef struct ocsp_revoked_info_st
+	{
+	ASN1_GENERALIZEDTIME *revocationTime;
+	ASN1_ENUMERATED *revocationReason;
+	} OCSP_REVOKEDINFO;
+
+/*   CertStatus ::= CHOICE {
+ *       good                [0]     IMPLICIT NULL,
+ *       revoked             [1]     IMPLICIT RevokedInfo,
+ *       unknown             [2]     IMPLICIT UnknownInfo }
+ */
+#define V_OCSP_CERTSTATUS_GOOD    0
+#define V_OCSP_CERTSTATUS_REVOKED 1
+#define V_OCSP_CERTSTATUS_UNKNOWN 2
+typedef struct ocsp_cert_status_st
+	{
+	int type;
+	union	{
+		ASN1_NULL *good;
+		OCSP_REVOKEDINFO *revoked;
+		ASN1_NULL *unknown;
+		} value;
+	} OCSP_CERTSTATUS;
+
+/*   SingleResponse ::= SEQUENCE {
+ *      certID                       CertID,
+ *      certStatus                   CertStatus,
+ *      thisUpdate                   GeneralizedTime,
+ *      nextUpdate           [0]     EXPLICIT GeneralizedTime OPTIONAL,
+ *      singleExtensions     [1]     EXPLICIT Extensions OPTIONAL }
+ */
+typedef struct ocsp_single_response_st
+	{
+	OCSP_CERTID *certId;
+	OCSP_CERTSTATUS *certStatus;
+	ASN1_GENERALIZEDTIME *thisUpdate;
+	ASN1_GENERALIZEDTIME *nextUpdate;
+	STACK_OF(X509_EXTENSION) *singleExtensions;
+	} OCSP_SINGLERESP;
+
+DECLARE_STACK_OF(OCSP_SINGLERESP)
+DECLARE_ASN1_SET_OF(OCSP_SINGLERESP)
+
+/*   ResponseData ::= SEQUENCE {
+ *      version              [0] EXPLICIT Version DEFAULT v1,
+ *      responderID              ResponderID,
+ *      producedAt               GeneralizedTime,
+ *      responses                SEQUENCE OF SingleResponse,
+ *      responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
+ */
+typedef struct ocsp_response_data_st
+	{
+	ASN1_INTEGER *version;
+	OCSP_RESPID  *responderId;
+	ASN1_GENERALIZEDTIME *producedAt;
+	STACK_OF(OCSP_SINGLERESP) *responses;
+	STACK_OF(X509_EXTENSION) *responseExtensions;
+	} OCSP_RESPDATA;
+
+/*   BasicOCSPResponse       ::= SEQUENCE {
+ *      tbsResponseData      ResponseData,
+ *      signatureAlgorithm   AlgorithmIdentifier,
+ *      signature            BIT STRING,
+ *      certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ */
+  /* Note 1:
+     The value for "signature" is specified in the OCSP rfc2560 as follows:
+     "The value for the signature SHALL be computed on the hash of the DER
+     encoding ResponseData."  This means that you must hash the DER-encoded
+     tbsResponseData, and then run it through a crypto-signing function, which
+     will (at least w/RSA) do a hash-'n'-private-encrypt operation.  This seems
+     a bit odd, but that's the spec.  Also note that the data structures do not
+     leave anywhere to independently specify the algorithm used for the initial
+     hash. So, we look at the signature-specification algorithm, and try to do
+     something intelligent.	-- Kathy Weinhold, CertCo */
+  /* Note 2:
+     It seems that the mentioned passage from RFC 2560 (section 4.2.1) is open
+     for interpretation.  I've done tests against another responder, and found
+     that it doesn't do the double hashing that the RFC seems to say one
+     should.  Therefore, all relevant functions take a flag saying which
+     variant should be used.	-- Richard Levitte, OpenSSL team and CeloCom */
+typedef struct ocsp_basic_response_st
+	{
+	OCSP_RESPDATA *tbsResponseData;
+	X509_ALGOR *signatureAlgorithm;
+	ASN1_BIT_STRING *signature;
+	STACK_OF(X509) *certs;
+	} OCSP_BASICRESP;
+
+/*
+ *   CRLReason ::= ENUMERATED {
+ *        unspecified             (0),
+ *        keyCompromise           (1),
+ *        cACompromise            (2),
+ *        affiliationChanged      (3),
+ *        superseded              (4),
+ *        cessationOfOperation    (5),
+ *        certificateHold         (6),
+ *        removeFromCRL           (8) }
+ */
+#define OCSP_REVOKED_STATUS_NOSTATUS               -1
+#define OCSP_REVOKED_STATUS_UNSPECIFIED             0
+#define OCSP_REVOKED_STATUS_KEYCOMPROMISE           1
+#define OCSP_REVOKED_STATUS_CACOMPROMISE            2
+#define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED      3
+#define OCSP_REVOKED_STATUS_SUPERSEDED              4
+#define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION    5
+#define OCSP_REVOKED_STATUS_CERTIFICATEHOLD         6
+#define OCSP_REVOKED_STATUS_REMOVEFROMCRL           8
+
+/* CrlID ::= SEQUENCE {
+ *     crlUrl               [0]     EXPLICIT IA5String OPTIONAL,
+ *     crlNum               [1]     EXPLICIT INTEGER OPTIONAL,
+ *     crlTime              [2]     EXPLICIT GeneralizedTime OPTIONAL }
+ */
+typedef struct ocsp_crl_id_st
+        {
+	ASN1_IA5STRING *crlUrl;
+	ASN1_INTEGER *crlNum;
+	ASN1_GENERALIZEDTIME *crlTime;
+        } OCSP_CRLID;
+
+/* ServiceLocator ::= SEQUENCE {
+ *      issuer    Name,
+ *      locator   AuthorityInfoAccessSyntax OPTIONAL }
+ */
+typedef struct ocsp_service_locator_st
+        {
+	X509_NAME* issuer;
+	STACK_OF(ACCESS_DESCRIPTION) *locator;
+        } OCSP_SERVICELOC;
+ 
+#define PEM_STRING_OCSP_REQUEST	"OCSP REQUEST"
+#define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE"
+
+#define d2i_OCSP_REQUEST_bio(bp,p) ASN1_d2i_bio_of(OCSP_REQUEST,OCSP_REQUEST_new,d2i_OCSP_REQUEST,bp,p)
+
+#define d2i_OCSP_RESPONSE_bio(bp,p) ASN1_d2i_bio_of(OCSP_RESPONSE,OCSP_RESPONSE_new,d2i_OCSP_RESPONSE,bp,p)
+
+#define	PEM_read_bio_OCSP_REQUEST(bp,x,cb) (OCSP_REQUEST *)PEM_ASN1_read_bio( \
+     (char *(*)())d2i_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,bp,(char **)x,cb,NULL)
+
+#define	PEM_read_bio_OCSP_RESPONSE(bp,x,cb)(OCSP_RESPONSE *)PEM_ASN1_read_bio(\
+     (char *(*)())d2i_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,bp,(char **)x,cb,NULL)
+
+#define PEM_write_bio_OCSP_REQUEST(bp,o) \
+    PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\
+			bp,(char *)o, NULL,NULL,0,NULL,NULL)
+
+#define PEM_write_bio_OCSP_RESPONSE(bp,o) \
+    PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\
+			bp,(char *)o, NULL,NULL,0,NULL,NULL)
+
+#define i2d_OCSP_RESPONSE_bio(bp,o) ASN1_i2d_bio_of(OCSP_RESPONSE,i2d_OCSP_RESPONSE,bp,o)
+
+#define i2d_OCSP_REQUEST_bio(bp,o) ASN1_i2d_bio_of(OCSP_REQUEST,i2d_OCSP_REQUEST,bp,o)
+
+#define OCSP_REQUEST_sign(o,pkey,md) \
+	ASN1_item_sign(ASN1_ITEM_rptr(OCSP_REQINFO),\
+		o->optionalSignature->signatureAlgorithm,NULL,\
+	        o->optionalSignature->signature,o->tbsRequest,pkey,md)
+
+#define OCSP_BASICRESP_sign(o,pkey,md,d) \
+	ASN1_item_sign(ASN1_ITEM_rptr(OCSP_RESPDATA),o->signatureAlgorithm,NULL,\
+		o->signature,o->tbsResponseData,pkey,md)
+
+#define OCSP_REQUEST_verify(a,r) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_REQINFO),\
+        a->optionalSignature->signatureAlgorithm,\
+	a->optionalSignature->signature,a->tbsRequest,r)
+
+#define OCSP_BASICRESP_verify(a,r,d) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_RESPDATA),\
+	a->signatureAlgorithm,a->signature,a->tbsResponseData,r)
+
+#define ASN1_BIT_STRING_digest(data,type,md,len) \
+	ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len)
+
+#define OCSP_CERTSTATUS_dup(cs)\
+                (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\
+		(char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs))
+
+OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id);
+
+OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, char *path, OCSP_REQUEST *req);
+OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req,
+								int maxline);
+int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx);
+void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx);
+int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req);
+int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
+		const char *name, const char *value);
+
+OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer);
+
+OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, 
+			      X509_NAME *issuerName, 
+			      ASN1_BIT_STRING* issuerKey, 
+			      ASN1_INTEGER *serialNumber);
+
+OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid);
+
+int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len);
+int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len);
+int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs);
+int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req);
+
+int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm);
+int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert);
+
+int OCSP_request_sign(OCSP_REQUEST   *req,
+		      X509           *signer,
+		      EVP_PKEY       *key,
+		      const EVP_MD   *dgst,
+		      STACK_OF(X509) *certs,
+		      unsigned long flags);
+
+int OCSP_response_status(OCSP_RESPONSE *resp);
+OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp);
+
+int OCSP_resp_count(OCSP_BASICRESP *bs);
+OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx);
+int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last);
+int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
+				ASN1_GENERALIZEDTIME **revtime,
+				ASN1_GENERALIZEDTIME **thisupd,
+				ASN1_GENERALIZEDTIME **nextupd);
+int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
+				int *reason,
+				ASN1_GENERALIZEDTIME **revtime,
+				ASN1_GENERALIZEDTIME **thisupd,
+				ASN1_GENERALIZEDTIME **nextupd);
+int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
+			ASN1_GENERALIZEDTIME *nextupd,
+			long sec, long maxsec);
+
+int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store, unsigned long flags);
+
+int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, int *pssl);
+
+int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
+int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
+
+int OCSP_request_onereq_count(OCSP_REQUEST *req);
+OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i);
+OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one);
+int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd,
+			ASN1_OCTET_STRING **pikeyHash,
+			ASN1_INTEGER **pserial, OCSP_CERTID *cid);
+int OCSP_request_is_signed(OCSP_REQUEST *req);
+OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs);
+OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp,
+						OCSP_CERTID *cid,
+						int status, int reason,
+						ASN1_TIME *revtime,
+					ASN1_TIME *thisupd, ASN1_TIME *nextupd);
+int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert);
+int OCSP_basic_sign(OCSP_BASICRESP *brsp, 
+			X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
+			STACK_OF(X509) *certs, unsigned long flags);
+
+X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim);
+
+X509_EXTENSION *OCSP_accept_responses_new(char **oids);
+
+X509_EXTENSION *OCSP_archive_cutoff_new(char* tim);
+
+X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME* issuer, char **urls);
+
+int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x);
+int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos);
+int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, int lastpos);
+int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos);
+X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc);
+X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc);
+void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx);
+int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
+							unsigned long flags);
+int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc);
+
+int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x);
+int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos);
+int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos);
+int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos);
+X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc);
+X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc);
+void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx);
+int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
+							unsigned long flags);
+int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc);
+
+int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x);
+int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos);
+int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, int lastpos);
+int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, int lastpos);
+X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc);
+X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc);
+void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, int *idx);
+int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, int crit,
+							unsigned long flags);
+int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc);
+
+int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x);
+int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos);
+int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, int lastpos);
+int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, int lastpos);
+X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc);
+X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc);
+void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, int *idx);
+int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, int crit,
+							unsigned long flags);
+int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc);
+
+DECLARE_ASN1_FUNCTIONS(OCSP_SINGLERESP)
+DECLARE_ASN1_FUNCTIONS(OCSP_CERTSTATUS)
+DECLARE_ASN1_FUNCTIONS(OCSP_REVOKEDINFO)
+DECLARE_ASN1_FUNCTIONS(OCSP_BASICRESP)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPDATA)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPID)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPONSE)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPBYTES)
+DECLARE_ASN1_FUNCTIONS(OCSP_ONEREQ)
+DECLARE_ASN1_FUNCTIONS(OCSP_CERTID)
+DECLARE_ASN1_FUNCTIONS(OCSP_REQUEST)
+DECLARE_ASN1_FUNCTIONS(OCSP_SIGNATURE)
+DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO)
+DECLARE_ASN1_FUNCTIONS(OCSP_CRLID)
+DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC)
+
+const char *OCSP_response_status_str(long s);
+const char *OCSP_cert_status_str(long s);
+const char *OCSP_crl_reason_str(long s);
+
+int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* a, unsigned long flags);
+int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags);
+
+int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
+				X509_STORE *st, unsigned long flags);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_OCSP_strings(void);
+
+/* Error codes for the OCSP functions. */
+
+/* Function codes. */
+#define OCSP_F_ASN1_STRING_ENCODE			 100
+#define OCSP_F_D2I_OCSP_NONCE				 102
+#define OCSP_F_OCSP_BASIC_ADD1_STATUS			 103
+#define OCSP_F_OCSP_BASIC_SIGN				 104
+#define OCSP_F_OCSP_BASIC_VERIFY			 105
+#define OCSP_F_OCSP_CERT_ID_NEW				 101
+#define OCSP_F_OCSP_CHECK_DELEGATED			 106
+#define OCSP_F_OCSP_CHECK_IDS				 107
+#define OCSP_F_OCSP_CHECK_ISSUER			 108
+#define OCSP_F_OCSP_CHECK_VALIDITY			 115
+#define OCSP_F_OCSP_MATCH_ISSUERID			 109
+#define OCSP_F_OCSP_PARSE_URL				 114
+#define OCSP_F_OCSP_REQUEST_SIGN			 110
+#define OCSP_F_OCSP_REQUEST_VERIFY			 116
+#define OCSP_F_OCSP_RESPONSE_GET1_BASIC			 111
+#define OCSP_F_OCSP_SENDREQ_BIO				 112
+#define OCSP_F_OCSP_SENDREQ_NBIO			 117
+#define OCSP_F_PARSE_HTTP_LINE1				 118
+#define OCSP_F_REQUEST_VERIFY				 113
+
+/* Reason codes. */
+#define OCSP_R_BAD_DATA					 100
+#define OCSP_R_CERTIFICATE_VERIFY_ERROR			 101
+#define OCSP_R_DIGEST_ERR				 102
+#define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD		 122
+#define OCSP_R_ERROR_IN_THISUPDATE_FIELD		 123
+#define OCSP_R_ERROR_PARSING_URL			 121
+#define OCSP_R_MISSING_OCSPSIGNING_USAGE		 103
+#define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE		 124
+#define OCSP_R_NOT_BASIC_RESPONSE			 104
+#define OCSP_R_NO_CERTIFICATES_IN_CHAIN			 105
+#define OCSP_R_NO_CONTENT				 106
+#define OCSP_R_NO_PUBLIC_KEY				 107
+#define OCSP_R_NO_RESPONSE_DATA				 108
+#define OCSP_R_NO_REVOKED_TIME				 109
+#define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 110
+#define OCSP_R_REQUEST_NOT_SIGNED			 128
+#define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA	 111
+#define OCSP_R_ROOT_CA_NOT_TRUSTED			 112
+#define OCSP_R_SERVER_READ_ERROR			 113
+#define OCSP_R_SERVER_RESPONSE_ERROR			 114
+#define OCSP_R_SERVER_RESPONSE_PARSE_ERROR		 115
+#define OCSP_R_SERVER_WRITE_ERROR			 116
+#define OCSP_R_SIGNATURE_FAILURE			 117
+#define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND		 118
+#define OCSP_R_STATUS_EXPIRED				 125
+#define OCSP_R_STATUS_NOT_YET_VALID			 126
+#define OCSP_R_STATUS_TOO_OLD				 127
+#define OCSP_R_UNKNOWN_MESSAGE_DIGEST			 119
+#define OCSP_R_UNKNOWN_NID				 120
+#define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE		 129
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/ocsp/ocsp_asn.c b/openssl/crypto/ocsp/ocsp_asn.c
new file mode 100644
index 0000000..bfe892a
--- /dev/null
+++ b/openssl/crypto/ocsp/ocsp_asn.c
@@ -0,0 +1,182 @@
+/* ocsp_asn.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/ocsp.h>
+
+ASN1_SEQUENCE(OCSP_SIGNATURE) = {
+	ASN1_SIMPLE(OCSP_SIGNATURE, signatureAlgorithm, X509_ALGOR),
+	ASN1_SIMPLE(OCSP_SIGNATURE, signature, ASN1_BIT_STRING),
+	ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SIGNATURE, certs, X509, 0)
+} ASN1_SEQUENCE_END(OCSP_SIGNATURE)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_SIGNATURE)
+
+ASN1_SEQUENCE(OCSP_CERTID) = {
+	ASN1_SIMPLE(OCSP_CERTID, hashAlgorithm, X509_ALGOR),
+	ASN1_SIMPLE(OCSP_CERTID, issuerNameHash, ASN1_OCTET_STRING),
+	ASN1_SIMPLE(OCSP_CERTID, issuerKeyHash, ASN1_OCTET_STRING),
+	ASN1_SIMPLE(OCSP_CERTID, serialNumber, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(OCSP_CERTID)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTID)
+
+ASN1_SEQUENCE(OCSP_ONEREQ) = {
+	ASN1_SIMPLE(OCSP_ONEREQ, reqCert, OCSP_CERTID),
+	ASN1_EXP_SEQUENCE_OF_OPT(OCSP_ONEREQ, singleRequestExtensions, X509_EXTENSION, 0)
+} ASN1_SEQUENCE_END(OCSP_ONEREQ)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_ONEREQ)
+
+ASN1_SEQUENCE(OCSP_REQINFO) = {
+	ASN1_EXP_OPT(OCSP_REQINFO, version, ASN1_INTEGER, 0),
+	ASN1_EXP_OPT(OCSP_REQINFO, requestorName, GENERAL_NAME, 1),
+	ASN1_SEQUENCE_OF(OCSP_REQINFO, requestList, OCSP_ONEREQ),
+	ASN1_EXP_SEQUENCE_OF_OPT(OCSP_REQINFO, requestExtensions, X509_EXTENSION, 2)
+} ASN1_SEQUENCE_END(OCSP_REQINFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQINFO)
+
+ASN1_SEQUENCE(OCSP_REQUEST) = {
+	ASN1_SIMPLE(OCSP_REQUEST, tbsRequest, OCSP_REQINFO),
+	ASN1_EXP_OPT(OCSP_REQUEST, optionalSignature, OCSP_SIGNATURE, 0)
+} ASN1_SEQUENCE_END(OCSP_REQUEST)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQUEST)
+
+/* OCSP_RESPONSE templates */
+
+ASN1_SEQUENCE(OCSP_RESPBYTES) = {
+	    ASN1_SIMPLE(OCSP_RESPBYTES, responseType, ASN1_OBJECT),
+	    ASN1_SIMPLE(OCSP_RESPBYTES, response, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(OCSP_RESPBYTES)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPBYTES)
+
+ASN1_SEQUENCE(OCSP_RESPONSE) = {
+	ASN1_SIMPLE(OCSP_RESPONSE, responseStatus, ASN1_ENUMERATED),
+	ASN1_EXP_OPT(OCSP_RESPONSE, responseBytes, OCSP_RESPBYTES, 0)
+} ASN1_SEQUENCE_END(OCSP_RESPONSE)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPONSE)
+
+ASN1_CHOICE(OCSP_RESPID) = {
+	   ASN1_EXP(OCSP_RESPID, value.byName, X509_NAME, 1),
+	   ASN1_EXP(OCSP_RESPID, value.byKey, ASN1_OCTET_STRING, 2)
+} ASN1_CHOICE_END(OCSP_RESPID)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPID)
+
+ASN1_SEQUENCE(OCSP_REVOKEDINFO) = {
+	ASN1_SIMPLE(OCSP_REVOKEDINFO, revocationTime, ASN1_GENERALIZEDTIME),
+  	ASN1_EXP_OPT(OCSP_REVOKEDINFO, revocationReason, ASN1_ENUMERATED, 0)
+} ASN1_SEQUENCE_END(OCSP_REVOKEDINFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_REVOKEDINFO)
+
+ASN1_CHOICE(OCSP_CERTSTATUS) = {
+	ASN1_IMP(OCSP_CERTSTATUS, value.good, ASN1_NULL, 0),
+	ASN1_IMP(OCSP_CERTSTATUS, value.revoked, OCSP_REVOKEDINFO, 1),
+	ASN1_IMP(OCSP_CERTSTATUS, value.unknown, ASN1_NULL, 2)
+} ASN1_CHOICE_END(OCSP_CERTSTATUS)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTSTATUS)
+
+ASN1_SEQUENCE(OCSP_SINGLERESP) = {
+	   ASN1_SIMPLE(OCSP_SINGLERESP, certId, OCSP_CERTID),
+	   ASN1_SIMPLE(OCSP_SINGLERESP, certStatus, OCSP_CERTSTATUS),
+	   ASN1_SIMPLE(OCSP_SINGLERESP, thisUpdate, ASN1_GENERALIZEDTIME),
+	   ASN1_EXP_OPT(OCSP_SINGLERESP, nextUpdate, ASN1_GENERALIZEDTIME, 0),
+	   ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SINGLERESP, singleExtensions, X509_EXTENSION, 1)
+} ASN1_SEQUENCE_END(OCSP_SINGLERESP)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_SINGLERESP)
+
+ASN1_SEQUENCE(OCSP_RESPDATA) = {
+	   ASN1_EXP_OPT(OCSP_RESPDATA, version, ASN1_INTEGER, 0),
+	   ASN1_SIMPLE(OCSP_RESPDATA, responderId, OCSP_RESPID),
+	   ASN1_SIMPLE(OCSP_RESPDATA, producedAt, ASN1_GENERALIZEDTIME),
+	   ASN1_SEQUENCE_OF(OCSP_RESPDATA, responses, OCSP_SINGLERESP),
+	   ASN1_EXP_SEQUENCE_OF_OPT(OCSP_RESPDATA, responseExtensions, X509_EXTENSION, 1)
+} ASN1_SEQUENCE_END(OCSP_RESPDATA)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPDATA)
+
+ASN1_SEQUENCE(OCSP_BASICRESP) = {
+	   ASN1_SIMPLE(OCSP_BASICRESP, tbsResponseData, OCSP_RESPDATA),
+	   ASN1_SIMPLE(OCSP_BASICRESP, signatureAlgorithm, X509_ALGOR),
+	   ASN1_SIMPLE(OCSP_BASICRESP, signature, ASN1_BIT_STRING),
+	   ASN1_EXP_SEQUENCE_OF_OPT(OCSP_BASICRESP, certs, X509, 0)
+} ASN1_SEQUENCE_END(OCSP_BASICRESP)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_BASICRESP)
+
+ASN1_SEQUENCE(OCSP_CRLID) = {
+	   ASN1_EXP_OPT(OCSP_CRLID, crlUrl, ASN1_IA5STRING, 0),
+	   ASN1_EXP_OPT(OCSP_CRLID, crlNum, ASN1_INTEGER, 1),
+	   ASN1_EXP_OPT(OCSP_CRLID, crlTime, ASN1_GENERALIZEDTIME, 2)
+} ASN1_SEQUENCE_END(OCSP_CRLID)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_CRLID)
+
+ASN1_SEQUENCE(OCSP_SERVICELOC) = {
+	ASN1_SIMPLE(OCSP_SERVICELOC, issuer, X509_NAME),
+	ASN1_SEQUENCE_OF_OPT(OCSP_SERVICELOC, locator, ACCESS_DESCRIPTION)
+} ASN1_SEQUENCE_END(OCSP_SERVICELOC)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_SERVICELOC)
diff --git a/openssl/crypto/ocsp/ocsp_cl.c b/openssl/crypto/ocsp/ocsp_cl.c
new file mode 100644
index 0000000..9c14d9d
--- /dev/null
+++ b/openssl/crypto/ocsp/ocsp_cl.c
@@ -0,0 +1,371 @@
+/* ocsp_cl.c */
+/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
+ * project. */
+
+/* History:
+   This file was transfered to Richard Levitte from CertCo by Kathy
+   Weinhold in mid-spring 2000 to be included in OpenSSL or released
+   as a patch kit. */
+
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <cryptlib.h>
+#include <openssl/objects.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/ocsp.h>
+
+/* Utility functions related to sending OCSP requests and extracting
+ * relevant information from the response.
+ */
+
+/* Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ 
+ * pointer: useful if we want to add extensions.
+ */
+
+OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid)
+        {
+	OCSP_ONEREQ *one = NULL;
+
+	if (!(one = OCSP_ONEREQ_new())) goto err;
+	if (one->reqCert) OCSP_CERTID_free(one->reqCert);
+	one->reqCert = cid;
+	if (req &&
+		!sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one))
+				goto err;
+	return one;
+err:
+	OCSP_ONEREQ_free(one);
+	return NULL;
+        }
+
+/* Set requestorName from an X509_NAME structure */
+
+int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm)
+	{
+	GENERAL_NAME *gen;
+	gen = GENERAL_NAME_new();
+	if (gen == NULL)
+		return 0;
+	if (!X509_NAME_set(&gen->d.directoryName, nm))
+		{
+		GENERAL_NAME_free(gen);
+		return 0;
+		}
+	gen->type = GEN_DIRNAME;
+	if (req->tbsRequest->requestorName)
+		GENERAL_NAME_free(req->tbsRequest->requestorName);
+	req->tbsRequest->requestorName = gen;
+	return 1;
+	}
+	
+
+/* Add a certificate to an OCSP request */
+
+int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert)
+	{
+	OCSP_SIGNATURE *sig;
+	if (!req->optionalSignature)
+		req->optionalSignature = OCSP_SIGNATURE_new();
+	sig = req->optionalSignature;
+	if (!sig) return 0;
+	if (!cert) return 1;
+	if (!sig->certs && !(sig->certs = sk_X509_new_null()))
+		return 0;
+
+	if(!sk_X509_push(sig->certs, cert)) return 0;
+	CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
+	return 1;
+	}
+
+/* Sign an OCSP request set the requestorName to the subjec
+ * name of an optional signers certificate and include one
+ * or more optional certificates in the request. Behaves
+ * like PKCS7_sign().
+ */
+
+int OCSP_request_sign(OCSP_REQUEST   *req,
+		      X509           *signer,
+		      EVP_PKEY       *key,
+		      const EVP_MD   *dgst,
+		      STACK_OF(X509) *certs,
+		      unsigned long flags)
+        {
+	int i;
+	OCSP_SIGNATURE *sig;
+	X509 *x;
+
+	if (!OCSP_request_set1_name(req, X509_get_subject_name(signer)))
+			goto err;
+
+	if (!(req->optionalSignature = sig = OCSP_SIGNATURE_new())) goto err;
+	if (key)
+		{
+		if (!X509_check_private_key(signer, key))
+			{
+			OCSPerr(OCSP_F_OCSP_REQUEST_SIGN, OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+			goto err;
+			}
+		if (!OCSP_REQUEST_sign(req, key, dgst)) goto err;
+		}
+
+	if (!(flags & OCSP_NOCERTS))
+		{
+		if(!OCSP_request_add1_cert(req, signer)) goto err;
+		for (i = 0; i < sk_X509_num(certs); i++)
+			{
+			x = sk_X509_value(certs, i);
+			if (!OCSP_request_add1_cert(req, x)) goto err;
+			}
+		}
+
+	return 1;
+err:
+	OCSP_SIGNATURE_free(req->optionalSignature);
+	req->optionalSignature = NULL;
+	return 0;
+	}
+
+/* Get response status */
+
+int OCSP_response_status(OCSP_RESPONSE *resp)
+	{
+	return ASN1_ENUMERATED_get(resp->responseStatus);
+	}
+
+/* Extract basic response from OCSP_RESPONSE or NULL if
+ * no basic response present.
+ */
+ 
+
+OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp)
+	{
+	OCSP_RESPBYTES *rb;
+	rb = resp->responseBytes;
+	if (!rb)
+		{
+		OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NO_RESPONSE_DATA);
+		return NULL;
+		}
+	if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic)
+		{
+		OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NOT_BASIC_RESPONSE);
+		return NULL;
+		}
+
+	return ASN1_item_unpack(rb->response, ASN1_ITEM_rptr(OCSP_BASICRESP));
+	}
+
+/* Return number of OCSP_SINGLERESP reponses present in
+ * a basic response.
+ */
+
+int OCSP_resp_count(OCSP_BASICRESP *bs)
+	{
+	if (!bs) return -1;
+	return sk_OCSP_SINGLERESP_num(bs->tbsResponseData->responses);
+	}
+
+/* Extract an OCSP_SINGLERESP response with a given index */
+
+OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx)
+	{
+	if (!bs) return NULL;
+	return sk_OCSP_SINGLERESP_value(bs->tbsResponseData->responses, idx);
+	}
+
+/* Look single response matching a given certificate ID */
+
+int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last)
+	{
+	int i;
+	STACK_OF(OCSP_SINGLERESP) *sresp;
+	OCSP_SINGLERESP *single;
+	if (!bs) return -1;
+	if (last < 0) last = 0;
+	else last++;
+	sresp = bs->tbsResponseData->responses;
+	for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++)
+		{
+		single = sk_OCSP_SINGLERESP_value(sresp, i);
+		if (!OCSP_id_cmp(id, single->certId)) return i;
+		}
+	return -1;
+	}
+
+/* Extract status information from an OCSP_SINGLERESP structure.
+ * Note: the revtime and reason values are only set if the 
+ * certificate status is revoked. Returns numerical value of
+ * status.
+ */
+
+int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
+				ASN1_GENERALIZEDTIME **revtime,
+				ASN1_GENERALIZEDTIME **thisupd,
+				ASN1_GENERALIZEDTIME **nextupd)
+	{
+	int ret;
+	OCSP_CERTSTATUS *cst;
+	if(!single) return -1;
+	cst = single->certStatus;
+	ret = cst->type;
+	if (ret == V_OCSP_CERTSTATUS_REVOKED)
+		{
+		OCSP_REVOKEDINFO *rev = cst->value.revoked;
+		if (revtime) *revtime = rev->revocationTime;
+		if (reason) 
+			{
+			if(rev->revocationReason)
+				*reason = ASN1_ENUMERATED_get(rev->revocationReason);
+			else *reason = -1;
+			}
+		}
+	if(thisupd) *thisupd = single->thisUpdate;
+	if(nextupd) *nextupd = single->nextUpdate;
+	return ret;
+	}
+
+/* This function combines the previous ones: look up a certificate ID and
+ * if found extract status information. Return 0 is successful.
+ */
+
+int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
+				int *reason,
+				ASN1_GENERALIZEDTIME **revtime,
+				ASN1_GENERALIZEDTIME **thisupd,
+				ASN1_GENERALIZEDTIME **nextupd)
+	{
+	int i;
+	OCSP_SINGLERESP *single;
+	i = OCSP_resp_find(bs, id, -1);
+	/* Maybe check for multiple responses and give an error? */
+	if(i < 0) return 0;
+	single = OCSP_resp_get0(bs, i);
+	i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd);
+	if(status) *status = i;
+	return 1;
+	}
+
+/* Check validity of thisUpdate and nextUpdate fields. It is possible that the request will
+ * take a few seconds to process and/or the time wont be totally accurate. Therefore to avoid
+ * rejecting otherwise valid time we allow the times to be within 'nsec' of the current time.
+ * Also to avoid accepting very old responses without a nextUpdate field an optional maxage
+ * parameter specifies the maximum age the thisUpdate field can be.
+ */
+
+int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec)
+	{
+	int ret = 1;
+	time_t t_now, t_tmp;
+	time(&t_now);
+	/* Check thisUpdate is valid and not more than nsec in the future */
+	if (!ASN1_GENERALIZEDTIME_check(thisupd))
+		{
+		OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_THISUPDATE_FIELD);
+		ret = 0;
+		}
+	else 
+		{
+			t_tmp = t_now + nsec;
+			if (X509_cmp_time(thisupd, &t_tmp) > 0)
+			{
+			OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_NOT_YET_VALID);
+			ret = 0;
+			}
+
+		/* If maxsec specified check thisUpdate is not more than maxsec in the past */
+		if (maxsec >= 0)
+			{
+			t_tmp = t_now - maxsec;
+			if (X509_cmp_time(thisupd, &t_tmp) < 0)
+				{
+				OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_TOO_OLD);
+				ret = 0;
+				}
+			}
+		}
+		
+
+	if (!nextupd) return ret;
+
+	/* Check nextUpdate is valid and not more than nsec in the past */
+	if (!ASN1_GENERALIZEDTIME_check(nextupd))
+		{
+		OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD);
+		ret = 0;
+		}
+	else 
+		{
+		t_tmp = t_now - nsec;
+		if (X509_cmp_time(nextupd, &t_tmp) < 0)
+			{
+			OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_EXPIRED);
+			ret = 0;
+			}
+		}
+
+	/* Also don't allow nextUpdate to precede thisUpdate */
+	if (ASN1_STRING_cmp(nextupd, thisupd) < 0)
+		{
+		OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE);
+		ret = 0;
+		}
+
+	return ret;
+	}
diff --git a/openssl/crypto/ocsp/ocsp_err.c b/openssl/crypto/ocsp/ocsp_err.c
new file mode 100644
index 0000000..0cedcea
--- /dev/null
+++ b/openssl/crypto/ocsp/ocsp_err.c
@@ -0,0 +1,142 @@
+/* crypto/ocsp/ocsp_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ocsp.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_OCSP,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_OCSP,0,reason)
+
+static ERR_STRING_DATA OCSP_str_functs[]=
+	{
+{ERR_FUNC(OCSP_F_ASN1_STRING_ENCODE),	"ASN1_STRING_encode"},
+{ERR_FUNC(OCSP_F_D2I_OCSP_NONCE),	"D2I_OCSP_NONCE"},
+{ERR_FUNC(OCSP_F_OCSP_BASIC_ADD1_STATUS),	"OCSP_basic_add1_status"},
+{ERR_FUNC(OCSP_F_OCSP_BASIC_SIGN),	"OCSP_basic_sign"},
+{ERR_FUNC(OCSP_F_OCSP_BASIC_VERIFY),	"OCSP_basic_verify"},
+{ERR_FUNC(OCSP_F_OCSP_CERT_ID_NEW),	"OCSP_cert_id_new"},
+{ERR_FUNC(OCSP_F_OCSP_CHECK_DELEGATED),	"OCSP_CHECK_DELEGATED"},
+{ERR_FUNC(OCSP_F_OCSP_CHECK_IDS),	"OCSP_CHECK_IDS"},
+{ERR_FUNC(OCSP_F_OCSP_CHECK_ISSUER),	"OCSP_CHECK_ISSUER"},
+{ERR_FUNC(OCSP_F_OCSP_CHECK_VALIDITY),	"OCSP_check_validity"},
+{ERR_FUNC(OCSP_F_OCSP_MATCH_ISSUERID),	"OCSP_MATCH_ISSUERID"},
+{ERR_FUNC(OCSP_F_OCSP_PARSE_URL),	"OCSP_parse_url"},
+{ERR_FUNC(OCSP_F_OCSP_REQUEST_SIGN),	"OCSP_request_sign"},
+{ERR_FUNC(OCSP_F_OCSP_REQUEST_VERIFY),	"OCSP_request_verify"},
+{ERR_FUNC(OCSP_F_OCSP_RESPONSE_GET1_BASIC),	"OCSP_response_get1_basic"},
+{ERR_FUNC(OCSP_F_OCSP_SENDREQ_BIO),	"OCSP_sendreq_bio"},
+{ERR_FUNC(OCSP_F_OCSP_SENDREQ_NBIO),	"OCSP_sendreq_nbio"},
+{ERR_FUNC(OCSP_F_PARSE_HTTP_LINE1),	"PARSE_HTTP_LINE1"},
+{ERR_FUNC(OCSP_F_REQUEST_VERIFY),	"REQUEST_VERIFY"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA OCSP_str_reasons[]=
+	{
+{ERR_REASON(OCSP_R_BAD_DATA)             ,"bad data"},
+{ERR_REASON(OCSP_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"},
+{ERR_REASON(OCSP_R_DIGEST_ERR)           ,"digest err"},
+{ERR_REASON(OCSP_R_ERROR_IN_NEXTUPDATE_FIELD),"error in nextupdate field"},
+{ERR_REASON(OCSP_R_ERROR_IN_THISUPDATE_FIELD),"error in thisupdate field"},
+{ERR_REASON(OCSP_R_ERROR_PARSING_URL)    ,"error parsing url"},
+{ERR_REASON(OCSP_R_MISSING_OCSPSIGNING_USAGE),"missing ocspsigning usage"},
+{ERR_REASON(OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE),"nextupdate before thisupdate"},
+{ERR_REASON(OCSP_R_NOT_BASIC_RESPONSE)   ,"not basic response"},
+{ERR_REASON(OCSP_R_NO_CERTIFICATES_IN_CHAIN),"no certificates in chain"},
+{ERR_REASON(OCSP_R_NO_CONTENT)           ,"no content"},
+{ERR_REASON(OCSP_R_NO_PUBLIC_KEY)        ,"no public key"},
+{ERR_REASON(OCSP_R_NO_RESPONSE_DATA)     ,"no response data"},
+{ERR_REASON(OCSP_R_NO_REVOKED_TIME)      ,"no revoked time"},
+{ERR_REASON(OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
+{ERR_REASON(OCSP_R_REQUEST_NOT_SIGNED)   ,"request not signed"},
+{ERR_REASON(OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA),"response contains no revocation data"},
+{ERR_REASON(OCSP_R_ROOT_CA_NOT_TRUSTED)  ,"root ca not trusted"},
+{ERR_REASON(OCSP_R_SERVER_READ_ERROR)    ,"server read error"},
+{ERR_REASON(OCSP_R_SERVER_RESPONSE_ERROR),"server response error"},
+{ERR_REASON(OCSP_R_SERVER_RESPONSE_PARSE_ERROR),"server response parse error"},
+{ERR_REASON(OCSP_R_SERVER_WRITE_ERROR)   ,"server write error"},
+{ERR_REASON(OCSP_R_SIGNATURE_FAILURE)    ,"signature failure"},
+{ERR_REASON(OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
+{ERR_REASON(OCSP_R_STATUS_EXPIRED)       ,"status expired"},
+{ERR_REASON(OCSP_R_STATUS_NOT_YET_VALID) ,"status not yet valid"},
+{ERR_REASON(OCSP_R_STATUS_TOO_OLD)       ,"status too old"},
+{ERR_REASON(OCSP_R_UNKNOWN_MESSAGE_DIGEST),"unknown message digest"},
+{ERR_REASON(OCSP_R_UNKNOWN_NID)          ,"unknown nid"},
+{ERR_REASON(OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE),"unsupported requestorname type"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_OCSP_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(OCSP_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,OCSP_str_functs);
+		ERR_load_strings(0,OCSP_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/ocsp/ocsp_ext.c b/openssl/crypto/ocsp/ocsp_ext.c
new file mode 100644
index 0000000..ec884cb
--- /dev/null
+++ b/openssl/crypto/ocsp/ocsp_ext.c
@@ -0,0 +1,518 @@
+/* ocsp_ext.c */
+/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
+ * project. */
+
+/* History:
+   This file was transfered to Richard Levitte from CertCo by Kathy
+   Weinhold in mid-spring 2000 to be included in OpenSSL or released
+   as a patch kit. */
+
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <cryptlib.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/ocsp.h>
+#include <openssl/rand.h>
+#include <openssl/x509v3.h>
+
+/* Standard wrapper functions for extensions */
+
+/* OCSP request extensions */
+
+int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x)
+	{
+	return(X509v3_get_ext_count(x->tbsRequest->requestExtensions));
+	}
+
+int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos)
+	{
+	return(X509v3_get_ext_by_NID(x->tbsRequest->requestExtensions,nid,lastpos));
+	}
+
+int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, int lastpos)
+	{
+	return(X509v3_get_ext_by_OBJ(x->tbsRequest->requestExtensions,obj,lastpos));
+	}
+
+int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos)
+	{
+	return(X509v3_get_ext_by_critical(x->tbsRequest->requestExtensions,crit,lastpos));
+	}
+
+X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc)
+	{
+	return(X509v3_get_ext(x->tbsRequest->requestExtensions,loc));
+	}
+
+X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc)
+	{
+	return(X509v3_delete_ext(x->tbsRequest->requestExtensions,loc));
+	}
+
+void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx)
+	{
+	return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx);
+	}
+
+int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
+							unsigned long flags)
+	{
+	return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value, crit, flags);
+	}
+
+int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc)
+	{
+	return(X509v3_add_ext(&(x->tbsRequest->requestExtensions),ex,loc) != NULL);
+	}
+
+/* Single extensions */
+
+int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x)
+	{
+	return(X509v3_get_ext_count(x->singleRequestExtensions));
+	}
+
+int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos)
+	{
+	return(X509v3_get_ext_by_NID(x->singleRequestExtensions,nid,lastpos));
+	}
+
+int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos)
+	{
+	return(X509v3_get_ext_by_OBJ(x->singleRequestExtensions,obj,lastpos));
+	}
+
+int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos)
+	{
+	return(X509v3_get_ext_by_critical(x->singleRequestExtensions,crit,lastpos));
+	}
+
+X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc)
+	{
+	return(X509v3_get_ext(x->singleRequestExtensions,loc));
+	}
+
+X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc)
+	{
+	return(X509v3_delete_ext(x->singleRequestExtensions,loc));
+	}
+
+void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx)
+	{
+	return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx);
+	}
+
+int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
+							unsigned long flags)
+	{
+	return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit, flags);
+	}
+
+int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc)
+	{
+	return(X509v3_add_ext(&(x->singleRequestExtensions),ex,loc) != NULL);
+	}
+
+/* OCSP Basic response */
+
+int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x)
+	{
+	return(X509v3_get_ext_count(x->tbsResponseData->responseExtensions));
+	}
+
+int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos)
+	{
+	return(X509v3_get_ext_by_NID(x->tbsResponseData->responseExtensions,nid,lastpos));
+	}
+
+int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, int lastpos)
+	{
+	return(X509v3_get_ext_by_OBJ(x->tbsResponseData->responseExtensions,obj,lastpos));
+	}
+
+int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, int lastpos)
+	{
+	return(X509v3_get_ext_by_critical(x->tbsResponseData->responseExtensions,crit,lastpos));
+	}
+
+X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc)
+	{
+	return(X509v3_get_ext(x->tbsResponseData->responseExtensions,loc));
+	}
+
+X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc)
+	{
+	return(X509v3_delete_ext(x->tbsResponseData->responseExtensions,loc));
+	}
+
+void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, int *idx)
+	{
+	return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid, crit, idx);
+	}
+
+int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, int crit,
+							unsigned long flags)
+	{
+	return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid, value, crit, flags);
+	}
+
+int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc)
+	{
+	return(X509v3_add_ext(&(x->tbsResponseData->responseExtensions),ex,loc) != NULL);
+	}
+
+/* OCSP single response extensions */
+
+int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x)
+	{
+	return(X509v3_get_ext_count(x->singleExtensions));
+	}
+
+int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos)
+	{
+	return(X509v3_get_ext_by_NID(x->singleExtensions,nid,lastpos));
+	}
+
+int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, int lastpos)
+	{
+	return(X509v3_get_ext_by_OBJ(x->singleExtensions,obj,lastpos));
+	}
+
+int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, int lastpos)
+	{
+	return(X509v3_get_ext_by_critical(x->singleExtensions,crit,lastpos));
+	}
+
+X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc)
+	{
+	return(X509v3_get_ext(x->singleExtensions,loc));
+	}
+
+X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc)
+	{
+	return(X509v3_delete_ext(x->singleExtensions,loc));
+	}
+
+void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, int *idx)
+	{
+	return X509V3_get_d2i(x->singleExtensions, nid, crit, idx);
+	}
+
+int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, int crit,
+							unsigned long flags)
+	{
+	return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags);
+	}
+
+int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc)
+	{
+	return(X509v3_add_ext(&(x->singleExtensions),ex,loc) != NULL);
+	}
+
+/* also CRL Entry Extensions */
+#if 0
+ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d,
+				void *data, STACK_OF(ASN1_OBJECT) *sk)
+        {
+	int i;
+	unsigned char *p, *b = NULL;
+
+	if (data)
+	        {
+		if ((i=i2d(data,NULL)) <= 0) goto err;
+		if (!(b=p=OPENSSL_malloc((unsigned int)i)))
+			goto err;
+	        if (i2d(data, &p) <= 0) goto err;
+		}
+	else if (sk)
+	        {
+		if ((i=i2d_ASN1_SET_OF_ASN1_OBJECT(sk,NULL,
+						   (I2D_OF(ASN1_OBJECT))i2d,
+						   V_ASN1_SEQUENCE,
+						   V_ASN1_UNIVERSAL,
+						   IS_SEQUENCE))<=0) goto err;
+		if (!(b=p=OPENSSL_malloc((unsigned int)i)))
+			goto err;
+		if (i2d_ASN1_SET_OF_ASN1_OBJECT(sk,&p,(I2D_OF(ASN1_OBJECT))i2d,
+						V_ASN1_SEQUENCE,
+						V_ASN1_UNIVERSAL,
+						IS_SEQUENCE)<=0) goto err;
+		}
+	else
+		{
+		OCSPerr(OCSP_F_ASN1_STRING_ENCODE,OCSP_R_BAD_DATA);
+		goto err;
+		}
+	if (!s && !(s = ASN1_STRING_new())) goto err;
+	if (!(ASN1_STRING_set(s, b, i))) goto err;
+	OPENSSL_free(b);
+	return s;
+err:
+	if (b) OPENSSL_free(b);
+	return NULL;
+	}
+#endif
+
+/* Nonce handling functions */
+
+/* Add a nonce to an extension stack. A nonce can be specificed or if NULL
+ * a random nonce will be generated.
+ * Note: OpenSSL 0.9.7d and later create an OCTET STRING containing the 
+ * nonce, previous versions used the raw nonce.
+ */
+
+static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, unsigned char *val, int len)
+	{
+	unsigned char *tmpval;
+	ASN1_OCTET_STRING os;
+	int ret = 0;
+	if (len <= 0) len = OCSP_DEFAULT_NONCE_LENGTH;
+	/* Create the OCTET STRING manually by writing out the header and
+	 * appending the content octets. This avoids an extra memory allocation
+	 * operation in some cases. Applications should *NOT* do this because
+         * it relies on library internals.
+	 */
+	os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING);
+	os.data = OPENSSL_malloc(os.length);
+	if (os.data == NULL)
+		goto err;
+	tmpval = os.data;
+	ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL);
+	if (val)
+		memcpy(tmpval, val, len);
+	else
+		RAND_pseudo_bytes(tmpval, len);
+	if(!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce,
+			&os, 0, X509V3_ADD_REPLACE))
+				goto err;
+	ret = 1;
+	err:
+	if (os.data)
+		OPENSSL_free(os.data);
+	return ret;
+	}
+
+
+/* Add nonce to an OCSP request */
+
+int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len)
+	{
+	return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len);
+	}
+
+/* Same as above but for a response */
+
+int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len)
+	{
+	return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val, len);
+	}
+
+/* Check nonce validity in a request and response.
+ * Return value reflects result:
+ *  1: nonces present and equal.
+ *  2: nonces both absent.
+ *  3: nonce present in response only.
+ *  0: nonces both present and not equal.
+ * -1: nonce in request only.
+ *
+ *  For most responders clients can check return > 0.
+ *  If responder doesn't handle nonces return != 0 may be
+ *  necessary. return == 0 is always an error.
+ */
+
+int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs)
+	{
+	/*
+	 * Since we are only interested in the presence or absence of
+	 * the nonce and comparing its value there is no need to use
+	 * the X509V3 routines: this way we can avoid them allocating an
+	 * ASN1_OCTET_STRING structure for the value which would be
+	 * freed immediately anyway.
+	 */
+
+	int req_idx, resp_idx;
+	X509_EXTENSION *req_ext, *resp_ext;
+	req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
+	resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1);
+	/* Check both absent */
+	if((req_idx < 0) && (resp_idx < 0))
+		return 2;
+	/* Check in request only */
+	if((req_idx >= 0) && (resp_idx < 0))
+		return -1;
+	/* Check in response but not request */
+	if((req_idx < 0) && (resp_idx >= 0))
+		return 3;
+	/* Otherwise nonce in request and response so retrieve the extensions */
+	req_ext = OCSP_REQUEST_get_ext(req, req_idx);
+	resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx);
+	if(ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value))
+		return 0;
+	return 1;
+	}
+
+/* Copy the nonce value (if any) from an OCSP request to 
+ * a response.
+ */
+
+int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req)
+	{
+	X509_EXTENSION *req_ext;
+	int req_idx;
+	/* Check for nonce in request */
+	req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
+	/* If no nonce that's OK */
+	if (req_idx < 0) return 2;
+	req_ext = OCSP_REQUEST_get_ext(req, req_idx);
+	return OCSP_BASICRESP_add_ext(resp, req_ext, -1);
+	}
+
+X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim)
+        {
+	X509_EXTENSION *x = NULL;
+	OCSP_CRLID *cid = NULL;
+	
+	if (!(cid = OCSP_CRLID_new())) goto err;
+	if (url)
+	        {
+		if (!(cid->crlUrl = ASN1_IA5STRING_new())) goto err;
+		if (!(ASN1_STRING_set(cid->crlUrl, url, -1))) goto err;
+		}
+	if (n)
+	        {
+		if (!(cid->crlNum = ASN1_INTEGER_new())) goto err;
+		if (!(ASN1_INTEGER_set(cid->crlNum, *n))) goto err;
+		}
+	if (tim)
+	        {
+		if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new())) goto err;
+		if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) 
+		        goto err;
+		}
+	x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid);
+err:
+	if (cid) OCSP_CRLID_free(cid);
+	return x;
+	}
+
+/*   AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */
+X509_EXTENSION *OCSP_accept_responses_new(char **oids)
+        {
+	int nid;
+	STACK_OF(ASN1_OBJECT) *sk = NULL;
+	ASN1_OBJECT *o = NULL;
+        X509_EXTENSION *x = NULL;
+
+	if (!(sk = sk_ASN1_OBJECT_new_null())) goto err;
+	while (oids && *oids)
+	        {
+		if ((nid=OBJ_txt2nid(*oids))!=NID_undef&&(o=OBJ_nid2obj(nid))) 
+		        sk_ASN1_OBJECT_push(sk, o);
+		oids++;
+		}
+	x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk);
+err:
+	if (sk) sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
+	return x;
+        }
+
+/*  ArchiveCutoff ::= GeneralizedTime */
+X509_EXTENSION *OCSP_archive_cutoff_new(char* tim)
+        {
+	X509_EXTENSION *x=NULL;
+	ASN1_GENERALIZEDTIME *gt = NULL;
+
+	if (!(gt = ASN1_GENERALIZEDTIME_new())) goto err;
+	if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) goto err;
+	x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt);
+err:
+	if (gt) ASN1_GENERALIZEDTIME_free(gt);
+	return x;
+	}
+
+/* per ACCESS_DESCRIPTION parameter are oids, of which there are currently
+ * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value.  This
+ * method forces NID_ad_ocsp and uniformResourceLocator [6] IA5String.
+ */
+X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME* issuer, char **urls)
+        {
+	X509_EXTENSION *x = NULL;
+	ASN1_IA5STRING *ia5 = NULL;
+	OCSP_SERVICELOC *sloc = NULL;
+	ACCESS_DESCRIPTION *ad = NULL;
+	
+	if (!(sloc = OCSP_SERVICELOC_new())) goto err;
+	if (!(sloc->issuer = X509_NAME_dup(issuer))) goto err;
+	if (urls && *urls && !(sloc->locator = sk_ACCESS_DESCRIPTION_new_null())) goto err;
+	while (urls && *urls)
+	        {
+		if (!(ad = ACCESS_DESCRIPTION_new())) goto err;
+		if (!(ad->method=OBJ_nid2obj(NID_ad_OCSP))) goto err;
+		if (!(ad->location = GENERAL_NAME_new())) goto err;
+	        if (!(ia5 = ASN1_IA5STRING_new())) goto err;
+		if (!ASN1_STRING_set((ASN1_STRING*)ia5, *urls, -1)) goto err;
+		ad->location->type = GEN_URI;
+		ad->location->d.ia5 = ia5;
+		if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) goto err;
+		urls++;
+		}
+	x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc);
+err:
+	if (sloc) OCSP_SERVICELOC_free(sloc);
+	return x;
+	}
+
diff --git a/openssl/crypto/ocsp/ocsp_ht.c b/openssl/crypto/ocsp/ocsp_ht.c
new file mode 100644
index 0000000..af5fc16
--- /dev/null
+++ b/openssl/crypto/ocsp/ocsp_ht.c
@@ -0,0 +1,504 @@
+/* ocsp_ht.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include "e_os.h"
+#include <openssl/asn1.h>
+#include <openssl/ocsp.h>
+#include <openssl/err.h>
+#include <openssl/buffer.h>
+#ifdef OPENSSL_SYS_SUNOS
+#define strtoul (unsigned long)strtol
+#endif /* OPENSSL_SYS_SUNOS */
+
+/* Stateful OCSP request code, supporting non-blocking I/O */
+
+/* Opaque OCSP request status structure */
+
+struct ocsp_req_ctx_st {
+	int state;		/* Current I/O state */
+	unsigned char *iobuf;	/* Line buffer */
+	int iobuflen;		/* Line buffer length */
+	BIO *io;		/* BIO to perform I/O with */
+	BIO *mem;		/* Memory BIO response is built into */
+	unsigned long asn1_len;	/* ASN1 length of response */
+	};
+
+#define OCSP_MAX_REQUEST_LENGTH	(100 * 1024)
+#define OCSP_MAX_LINE_LEN	4096;
+
+/* OCSP states */
+
+/* If set no reading should be performed */
+#define OHS_NOREAD		0x1000
+/* Error condition */
+#define OHS_ERROR		(0 | OHS_NOREAD)
+/* First line being read */
+#define OHS_FIRSTLINE		1
+/* MIME headers being read */
+#define OHS_HEADERS		2
+/* OCSP initial header (tag + length) being read */
+#define OHS_ASN1_HEADER		3
+/* OCSP content octets being read */
+#define OHS_ASN1_CONTENT	4
+/* Request being sent */
+#define OHS_ASN1_WRITE		(6 | OHS_NOREAD)
+/* Request being flushed */
+#define OHS_ASN1_FLUSH		(7 | OHS_NOREAD)
+/* Completed */
+#define OHS_DONE		(8 | OHS_NOREAD)
+
+
+static int parse_http_line1(char *line);
+
+void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx)
+	{
+	if (rctx->mem)
+		BIO_free(rctx->mem);
+	if (rctx->iobuf)
+		OPENSSL_free(rctx->iobuf);
+	OPENSSL_free(rctx);
+	}
+
+int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req)
+	{
+	static const char req_hdr[] =
+	"Content-Type: application/ocsp-request\r\n"
+	"Content-Length: %d\r\n\r\n";
+        if (BIO_printf(rctx->mem, req_hdr, i2d_OCSP_REQUEST(req, NULL)) <= 0)
+		return 0;
+        if (i2d_OCSP_REQUEST_bio(rctx->mem, req) <= 0)
+		return 0;
+	rctx->state = OHS_ASN1_WRITE;
+	rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL);
+	return 1;
+	}
+
+int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
+		const char *name, const char *value)
+	{
+	if (!name)
+		return 0;
+	if (BIO_puts(rctx->mem, name) <= 0)
+		return 0;
+	if (value)
+		{
+		if (BIO_write(rctx->mem, ": ", 2) != 2)
+			return 0;
+		if (BIO_puts(rctx->mem, value) <= 0)
+			return 0;
+		}
+	if (BIO_write(rctx->mem, "\r\n", 2) != 2)
+		return 0;
+	return 1;
+	}
+
+OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req,
+								int maxline)
+	{
+	static const char post_hdr[] = "POST %s HTTP/1.0\r\n";
+
+	OCSP_REQ_CTX *rctx;
+	rctx = OPENSSL_malloc(sizeof(OCSP_REQ_CTX));
+	rctx->state = OHS_ERROR;
+	rctx->mem = BIO_new(BIO_s_mem());
+	rctx->io = io;
+	rctx->asn1_len = 0;
+	if (maxline > 0)
+		rctx->iobuflen = maxline;
+	else
+		rctx->iobuflen = OCSP_MAX_LINE_LEN;
+	rctx->iobuf = OPENSSL_malloc(rctx->iobuflen);
+	if (!rctx->iobuf)
+		return 0;
+	if (!path)
+		path = "/";
+
+        if (BIO_printf(rctx->mem, post_hdr, path) <= 0)
+		return 0;
+
+	if (req && !OCSP_REQ_CTX_set1_req(rctx, req))
+		return 0;
+
+	return rctx;
+	}
+
+/* Parse the HTTP response. This will look like this:
+ * "HTTP/1.0 200 OK". We need to obtain the numeric code and
+ * (optional) informational message.
+ */
+
+static int parse_http_line1(char *line)
+	{
+	int retcode;
+	char *p, *q, *r;
+	/* Skip to first white space (passed protocol info) */
+
+	for(p = line; *p && !isspace((unsigned char)*p); p++)
+		continue;
+	if(!*p)
+		{
+		OCSPerr(OCSP_F_PARSE_HTTP_LINE1,
+					OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
+		return 0;
+		}
+
+	/* Skip past white space to start of response code */
+	while(*p && isspace((unsigned char)*p))
+		p++;
+
+	if(!*p)
+		{
+		OCSPerr(OCSP_F_PARSE_HTTP_LINE1,
+					OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
+		return 0;
+		}
+
+	/* Find end of response code: first whitespace after start of code */
+	for(q = p; *q && !isspace((unsigned char)*q); q++)
+		continue;
+
+	if(!*q)
+		{
+		OCSPerr(OCSP_F_PARSE_HTTP_LINE1,
+					OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
+		return 0;
+		}
+
+	/* Set end of response code and start of message */ 
+	*q++ = 0;
+
+	/* Attempt to parse numeric code */
+	retcode = strtoul(p, &r, 10);
+
+	if(*r)
+		return 0;
+
+	/* Skip over any leading white space in message */
+	while(*q && isspace((unsigned char)*q))
+		q++;
+
+	if(*q)
+		{
+		/* Finally zap any trailing white space in message (include
+		 * CRLF) */
+
+		/* We know q has a non white space character so this is OK */
+		for(r = q + strlen(q) - 1; isspace((unsigned char)*r); r--)
+			*r = 0;
+		}
+	if(retcode != 200)
+		{
+		OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_ERROR);
+		if(!*q)
+			ERR_add_error_data(2, "Code=", p);
+		else
+			ERR_add_error_data(4, "Code=", p, ",Reason=", q);
+		return 0;
+		}
+
+
+	return 1;
+
+	}
+
+int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx)
+	{
+	int i, n;
+	const unsigned char *p;
+	next_io:
+	if (!(rctx->state & OHS_NOREAD))
+		{
+		n = BIO_read(rctx->io, rctx->iobuf, rctx->iobuflen);
+
+		if (n <= 0)
+			{
+			if (BIO_should_retry(rctx->io))
+				return -1;
+			return 0;
+			}
+
+		/* Write data to memory BIO */
+
+		if (BIO_write(rctx->mem, rctx->iobuf, n) != n)
+			return 0;
+		}
+
+	switch(rctx->state)
+		{
+
+		case OHS_ASN1_WRITE:
+		n = BIO_get_mem_data(rctx->mem, &p);
+
+		i = BIO_write(rctx->io,
+			p + (n - rctx->asn1_len), rctx->asn1_len);
+
+		if (i <= 0)
+			{
+			if (BIO_should_retry(rctx->io))
+				return -1;
+			rctx->state = OHS_ERROR;
+			return 0;
+			}
+
+		rctx->asn1_len -= i;
+
+		if (rctx->asn1_len > 0)
+			goto next_io;
+
+		rctx->state = OHS_ASN1_FLUSH;
+
+		(void)BIO_reset(rctx->mem);
+
+		case OHS_ASN1_FLUSH:
+
+		i = BIO_flush(rctx->io);
+
+		if (i > 0)
+			{
+			rctx->state = OHS_FIRSTLINE;
+			goto next_io;
+			}
+
+		if (BIO_should_retry(rctx->io))
+			return -1;
+
+		rctx->state = OHS_ERROR;
+		return 0;
+
+		case OHS_ERROR:
+		return 0;
+
+		case OHS_FIRSTLINE:
+		case OHS_HEADERS:
+
+		/* Attempt to read a line in */
+
+		next_line:
+		/* Due to &%^*$" memory BIO behaviour with BIO_gets we
+		 * have to check there's a complete line in there before
+		 * calling BIO_gets or we'll just get a partial read.
+		 */
+		n = BIO_get_mem_data(rctx->mem, &p);
+		if ((n <= 0) || !memchr(p, '\n', n))
+			{
+			if (n >= rctx->iobuflen)
+				{
+				rctx->state = OHS_ERROR;
+				return 0;
+				}
+			goto next_io;
+			}
+		n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen);
+
+		if (n <= 0)
+			{
+			if (BIO_should_retry(rctx->mem))
+				goto next_io;
+			rctx->state = OHS_ERROR;
+			return 0;
+			}
+
+		/* Don't allow excessive lines */
+		if (n == rctx->iobuflen)
+			{
+			rctx->state = OHS_ERROR;
+			return 0;
+			}
+
+		/* First line */
+		if (rctx->state == OHS_FIRSTLINE)
+			{
+			if (parse_http_line1((char *)rctx->iobuf))
+				{
+				rctx->state = OHS_HEADERS;
+				goto next_line;
+				}
+			else
+				{
+				rctx->state = OHS_ERROR;
+				return 0;
+				}
+			}
+		else
+			{
+			/* Look for blank line: end of headers */
+			for (p = rctx->iobuf; *p; p++)
+				{
+				if ((*p != '\r') && (*p != '\n'))
+					break;
+				}
+			if (*p)
+				goto next_line;
+
+			rctx->state = OHS_ASN1_HEADER;
+
+			}
+ 
+		/* Fall thru */
+
+
+		case OHS_ASN1_HEADER:
+		/* Now reading ASN1 header: can read at least 2 bytes which
+		 * is enough for ASN1 SEQUENCE header and either length field
+		 * or at least the length of the length field.
+		 */
+		n = BIO_get_mem_data(rctx->mem, &p);
+		if (n < 2)
+			goto next_io;
+
+		/* Check it is an ASN1 SEQUENCE */
+		if (*p++ != (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED))
+			{
+			rctx->state = OHS_ERROR;
+			return 0;
+			}
+
+		/* Check out length field */
+		if (*p & 0x80)
+			{
+			/* If MSB set on initial length octet we can now
+			 * always read 6 octets: make sure we have them.
+			 */
+			if (n < 6)
+				goto next_io;
+			n = *p & 0x7F;
+			/* Not NDEF or excessive length */
+			if (!n || (n > 4))
+				{
+				rctx->state = OHS_ERROR;
+				return 0;
+				}
+			p++;
+			rctx->asn1_len = 0;
+			for (i = 0; i < n; i++)
+				{
+				rctx->asn1_len <<= 8;
+				rctx->asn1_len |= *p++;
+				}
+
+			if (rctx->asn1_len > OCSP_MAX_REQUEST_LENGTH)
+				{
+				rctx->state = OHS_ERROR;
+				return 0;
+				}
+
+			rctx->asn1_len += n + 2;
+			}
+		else
+			rctx->asn1_len = *p + 2;
+
+		rctx->state = OHS_ASN1_CONTENT;
+
+		/* Fall thru */
+		
+		case OHS_ASN1_CONTENT:
+		n = BIO_get_mem_data(rctx->mem, &p);
+		if (n < (int)rctx->asn1_len)
+			goto next_io;
+
+
+		*presp = d2i_OCSP_RESPONSE(NULL, &p, rctx->asn1_len);
+		if (*presp)
+			{
+			rctx->state = OHS_DONE;
+			return 1;
+			}
+
+		rctx->state = OHS_ERROR;
+		return 0;
+
+		break;
+
+		case OHS_DONE:
+		return 1;
+
+		}
+
+
+
+	return 0;
+
+
+	}
+
+/* Blocking OCSP request handler: now a special case of non-blocking I/O */
+
+OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, char *path, OCSP_REQUEST *req)
+	{
+	OCSP_RESPONSE *resp = NULL;
+	OCSP_REQ_CTX *ctx;
+	int rv;
+
+	ctx = OCSP_sendreq_new(b, path, req, -1);
+
+	do
+		{
+		rv = OCSP_sendreq_nbio(&resp, ctx);
+		} while ((rv == -1) && BIO_should_retry(b));
+
+	OCSP_REQ_CTX_free(ctx);
+
+	if (rv)
+		return resp;
+
+	return NULL;
+	}
diff --git a/openssl/crypto/ocsp/ocsp_lib.c b/openssl/crypto/ocsp/ocsp_lib.c
new file mode 100644
index 0000000..e92b86c
--- /dev/null
+++ b/openssl/crypto/ocsp/ocsp_lib.c
@@ -0,0 +1,265 @@
+/* ocsp_lib.c */
+/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
+ * project. */
+
+/* History:
+   This file was transfered to Richard Levitte from CertCo by Kathy
+   Weinhold in mid-spring 2000 to be included in OpenSSL or released
+   as a patch kit. */
+
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <cryptlib.h>
+#include <openssl/objects.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/ocsp.h>
+#include <openssl/asn1t.h>
+
+/* Convert a certificate and its issuer to an OCSP_CERTID */
+
+OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer)
+{
+	X509_NAME *iname;
+	ASN1_INTEGER *serial;
+	ASN1_BIT_STRING *ikey;
+#ifndef OPENSSL_NO_SHA1
+	if(!dgst) dgst = EVP_sha1();
+#endif
+	if (subject)
+		{
+		iname = X509_get_issuer_name(subject);
+		serial = X509_get_serialNumber(subject);
+		}
+	else
+		{
+		iname = X509_get_subject_name(issuer);
+		serial = NULL;
+		}
+	ikey = X509_get0_pubkey_bitstr(issuer);
+	return OCSP_cert_id_new(dgst, iname, ikey, serial);
+}
+
+
+OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, 
+			      X509_NAME *issuerName, 
+			      ASN1_BIT_STRING* issuerKey, 
+			      ASN1_INTEGER *serialNumber)
+        {
+	int nid;
+        unsigned int i;
+	X509_ALGOR *alg;
+	OCSP_CERTID *cid = NULL;
+	unsigned char md[EVP_MAX_MD_SIZE];
+
+	if (!(cid = OCSP_CERTID_new())) goto err;
+
+	alg = cid->hashAlgorithm;
+	if (alg->algorithm != NULL) ASN1_OBJECT_free(alg->algorithm);
+	if ((nid = EVP_MD_type(dgst)) == NID_undef)
+	        {
+		OCSPerr(OCSP_F_OCSP_CERT_ID_NEW,OCSP_R_UNKNOWN_NID);
+		goto err;
+		}
+	if (!(alg->algorithm=OBJ_nid2obj(nid))) goto err;
+	if ((alg->parameter=ASN1_TYPE_new()) == NULL) goto err;
+	alg->parameter->type=V_ASN1_NULL;
+
+	if (!X509_NAME_digest(issuerName, dgst, md, &i)) goto digerr;
+	if (!(ASN1_OCTET_STRING_set(cid->issuerNameHash, md, i))) goto err;
+
+	/* Calculate the issuerKey hash, excluding tag and length */
+	EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL);
+
+	if (!(ASN1_OCTET_STRING_set(cid->issuerKeyHash, md, i))) goto err;
+
+	if (serialNumber)
+		{
+		ASN1_INTEGER_free(cid->serialNumber);
+		if (!(cid->serialNumber = ASN1_INTEGER_dup(serialNumber))) goto err;
+		}
+	return cid;
+digerr:
+	OCSPerr(OCSP_F_OCSP_CERT_ID_NEW,OCSP_R_DIGEST_ERR);
+err:
+	if (cid) OCSP_CERTID_free(cid);
+	return NULL;
+	}
+
+int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
+	{
+	int ret;
+	ret = OBJ_cmp(a->hashAlgorithm->algorithm, b->hashAlgorithm->algorithm);
+	if (ret) return ret;
+	ret = ASN1_OCTET_STRING_cmp(a->issuerNameHash, b->issuerNameHash);
+	if (ret) return ret;
+	return ASN1_OCTET_STRING_cmp(a->issuerKeyHash, b->issuerKeyHash);
+	}
+
+int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
+	{
+	int ret;
+	ret = OCSP_id_issuer_cmp(a, b);
+	if (ret) return ret;
+	return ASN1_INTEGER_cmp(a->serialNumber, b->serialNumber);
+	}
+
+
+/* Parse a URL and split it up into host, port and path components and whether
+ * it is SSL.
+ */
+
+int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, int *pssl)
+	{
+	char *p, *buf;
+
+	char *host, *port;
+
+	*phost = NULL;
+	*pport = NULL;
+	*ppath = NULL;
+
+	/* dup the buffer since we are going to mess with it */
+	buf = BUF_strdup(url);
+	if (!buf) goto mem_err;
+
+	/* Check for initial colon */
+	p = strchr(buf, ':');
+
+	if (!p) goto parse_err;
+
+	*(p++) = '\0';
+
+	if (!strcmp(buf, "http"))
+		{
+		*pssl = 0;
+		port = "80";
+		}
+	else if (!strcmp(buf, "https"))
+		{
+		*pssl = 1;
+		port = "443";
+		}
+	else
+		goto parse_err;
+
+	/* Check for double slash */
+	if ((p[0] != '/') || (p[1] != '/'))
+		goto parse_err;
+
+	p += 2;
+
+	host = p;
+
+	/* Check for trailing part of path */
+
+	p = strchr(p, '/');
+
+	if (!p) 
+		*ppath = BUF_strdup("/");
+	else
+		{
+		*ppath = BUF_strdup(p);
+		/* Set start of path to 0 so hostname is valid */
+		*p = '\0';
+		}
+
+	if (!*ppath) goto mem_err;
+
+	/* Look for optional ':' for port number */
+	if ((p = strchr(host, ':')))
+		{
+		*p = 0;
+		port = p + 1;
+		}
+	else
+		{
+		/* Not found: set default port */
+		if (*pssl) port = "443";
+		else port = "80";
+		}
+
+	*pport = BUF_strdup(port);
+	if (!*pport) goto mem_err;
+
+	*phost = BUF_strdup(host);
+
+	if (!*phost) goto mem_err;
+
+	OPENSSL_free(buf);
+
+	return 1;
+
+	mem_err:
+	OCSPerr(OCSP_F_OCSP_PARSE_URL, ERR_R_MALLOC_FAILURE);
+	goto err;
+
+	parse_err:
+	OCSPerr(OCSP_F_OCSP_PARSE_URL, OCSP_R_ERROR_PARSING_URL);
+
+
+	err:
+	if (buf) OPENSSL_free(buf);
+	if (*ppath) OPENSSL_free(*ppath);
+	if (*pport) OPENSSL_free(*pport);
+	if (*phost) OPENSSL_free(*phost);
+	return 0;
+
+	}
+
+IMPLEMENT_ASN1_DUP_FUNCTION(OCSP_CERTID)
diff --git a/openssl/crypto/ocsp/ocsp_prn.c b/openssl/crypto/ocsp/ocsp_prn.c
new file mode 100644
index 0000000..87608ff
--- /dev/null
+++ b/openssl/crypto/ocsp/ocsp_prn.c
@@ -0,0 +1,290 @@
+/* ocsp_prn.c */
+/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
+ * project. */
+
+/* History:
+   This file was originally part of ocsp.c and was transfered to Richard
+   Levitte from CertCo by Kathy Weinhold in mid-spring 2000 to be included
+   in OpenSSL or released as a patch kit. */
+
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/ocsp.h>
+#include <openssl/pem.h>
+
+static int ocsp_certid_print(BIO *bp, OCSP_CERTID* a, int indent)
+        {
+	BIO_printf(bp, "%*sCertificate ID:\n", indent, "");
+	indent += 2;
+	BIO_printf(bp, "%*sHash Algorithm: ", indent, "");
+	i2a_ASN1_OBJECT(bp, a->hashAlgorithm->algorithm);
+	BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, "");
+	i2a_ASN1_STRING(bp, a->issuerNameHash, V_ASN1_OCTET_STRING);
+	BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, "");
+	i2a_ASN1_STRING(bp, a->issuerKeyHash, V_ASN1_OCTET_STRING);
+	BIO_printf(bp, "\n%*sSerial Number: ", indent, "");
+	i2a_ASN1_INTEGER(bp, a->serialNumber);
+	BIO_printf(bp, "\n");
+	return 1;
+	}
+
+typedef struct
+	{
+	long t;
+	const char *m;
+	} OCSP_TBLSTR;
+
+static const char *table2string(long s, const OCSP_TBLSTR *ts, int len)
+{
+	const OCSP_TBLSTR *p;
+	for (p=ts; p < ts + len; p++)
+	        if (p->t == s)
+		         return p->m;
+	return "(UNKNOWN)";
+}
+
+const char *OCSP_response_status_str(long s)
+        {
+	static const OCSP_TBLSTR rstat_tbl[] = {
+	        { OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful" },
+	        { OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest" },
+	        { OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror" },
+	        { OCSP_RESPONSE_STATUS_TRYLATER, "trylater" },
+	        { OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired" },
+	        { OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized" } };
+	return table2string(s, rstat_tbl, 6);
+	} 
+
+const char *OCSP_cert_status_str(long s)
+        {
+	static const OCSP_TBLSTR cstat_tbl[] = {
+	        { V_OCSP_CERTSTATUS_GOOD, "good" },
+	        { V_OCSP_CERTSTATUS_REVOKED, "revoked" },
+	        { V_OCSP_CERTSTATUS_UNKNOWN, "unknown" } };
+	return table2string(s, cstat_tbl, 3);
+	} 
+
+const char *OCSP_crl_reason_str(long s)
+        {
+	static const OCSP_TBLSTR reason_tbl[] = {
+	  { OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified" },
+          { OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise" },
+          { OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise" },
+          { OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged" },
+          { OCSP_REVOKED_STATUS_SUPERSEDED, "superseded" },
+          { OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation" },
+          { OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold" },
+          { OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL" } };
+	return table2string(s, reason_tbl, 8);
+	} 
+
+int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* o, unsigned long flags)
+        {
+	int i;
+	long l;
+	OCSP_CERTID* cid = NULL;
+	OCSP_ONEREQ *one = NULL;
+	OCSP_REQINFO *inf = o->tbsRequest;
+	OCSP_SIGNATURE *sig = o->optionalSignature;
+
+	if (BIO_write(bp,"OCSP Request Data:\n",19) <= 0) goto err;
+	l=ASN1_INTEGER_get(inf->version);
+	if (BIO_printf(bp,"    Version: %lu (0x%lx)",l+1,l) <= 0) goto err;
+	if (inf->requestorName != NULL)
+	        {
+		if (BIO_write(bp,"\n    Requestor Name: ",21) <= 0) 
+		        goto err;
+		GENERAL_NAME_print(bp, inf->requestorName);
+		}
+	if (BIO_write(bp,"\n    Requestor List:\n",21) <= 0) goto err;
+	for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++)
+	        {
+		one = sk_OCSP_ONEREQ_value(inf->requestList, i);
+		cid = one->reqCert;
+		ocsp_certid_print(bp, cid, 8);
+		if (!X509V3_extensions_print(bp,
+					"Request Single Extensions",
+					one->singleRequestExtensions, flags, 8))
+							goto err;
+		}
+	if (!X509V3_extensions_print(bp, "Request Extensions",
+			inf->requestExtensions, flags, 4))
+							goto err;
+	if (sig)
+	        {
+		X509_signature_print(bp, sig->signatureAlgorithm, sig->signature);
+		for (i=0; i<sk_X509_num(sig->certs); i++)
+			{
+			X509_print(bp, sk_X509_value(sig->certs,i));
+			PEM_write_bio_X509(bp,sk_X509_value(sig->certs,i));
+			}
+		}
+	return 1;
+err:
+	return 0;
+	}
+
+int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags)
+        {
+	int i, ret = 0;
+	long l;
+	OCSP_CERTID *cid = NULL;
+	OCSP_BASICRESP *br = NULL;
+	OCSP_RESPID *rid = NULL;
+	OCSP_RESPDATA  *rd = NULL;
+	OCSP_CERTSTATUS *cst = NULL;
+	OCSP_REVOKEDINFO *rev = NULL;
+	OCSP_SINGLERESP *single = NULL;
+	OCSP_RESPBYTES *rb = o->responseBytes;
+
+	if (BIO_puts(bp,"OCSP Response Data:\n") <= 0) goto err;
+	l=ASN1_ENUMERATED_get(o->responseStatus);
+	if (BIO_printf(bp,"    OCSP Response Status: %s (0x%lx)\n",
+		       OCSP_response_status_str(l), l) <= 0) goto err;
+	if (rb == NULL) return 1;
+        if (BIO_puts(bp,"    Response Type: ") <= 0)
+	        goto err;
+	if(i2a_ASN1_OBJECT(bp, rb->responseType) <= 0)
+	        goto err;
+	if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) 
+	        {
+		BIO_puts(bp," (unknown response type)\n");
+		return 1;
+		}
+
+	i = ASN1_STRING_length(rb->response);
+	if (!(br = OCSP_response_get1_basic(o))) goto err;
+	rd = br->tbsResponseData;
+	l=ASN1_INTEGER_get(rd->version);
+	if (BIO_printf(bp,"\n    Version: %lu (0x%lx)\n",
+		       l+1,l) <= 0) goto err;
+	if (BIO_puts(bp,"    Responder Id: ") <= 0) goto err;
+
+	rid =  rd->responderId;
+	switch (rid->type)
+		{
+		case V_OCSP_RESPID_NAME:
+		        X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE);
+		        break;
+		case V_OCSP_RESPID_KEY:
+		        i2a_ASN1_STRING(bp, rid->value.byKey, V_ASN1_OCTET_STRING);
+		        break;
+		}
+
+	if (BIO_printf(bp,"\n    Produced At: ")<=0) goto err;
+	if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt)) goto err;
+	if (BIO_printf(bp,"\n    Responses:\n") <= 0) goto err;
+	for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++)
+	        {
+		if (! sk_OCSP_SINGLERESP_value(rd->responses, i)) continue;
+		single = sk_OCSP_SINGLERESP_value(rd->responses, i);
+		cid = single->certId;
+		if(ocsp_certid_print(bp, cid, 4) <= 0) goto err;
+		cst = single->certStatus;
+		if (BIO_printf(bp,"    Cert Status: %s",
+			       OCSP_cert_status_str(cst->type)) <= 0)
+		        goto err;
+		if (cst->type == V_OCSP_CERTSTATUS_REVOKED)
+		        {
+		        rev = cst->value.revoked;
+			if (BIO_printf(bp, "\n    Revocation Time: ") <= 0) 
+			        goto err;
+			if (!ASN1_GENERALIZEDTIME_print(bp, 
+							rev->revocationTime)) 
+				goto err;
+			if (rev->revocationReason) 
+			        {
+				l=ASN1_ENUMERATED_get(rev->revocationReason);
+				if (BIO_printf(bp, 
+					 "\n    Revocation Reason: %s (0x%lx)",
+					       OCSP_crl_reason_str(l), l) <= 0)
+				        goto err;
+				}
+			}
+		if (BIO_printf(bp,"\n    This Update: ") <= 0) goto err;
+		if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate)) 
+			goto err;
+		if (single->nextUpdate)
+		        {
+			if (BIO_printf(bp,"\n    Next Update: ") <= 0)goto err;
+			if (!ASN1_GENERALIZEDTIME_print(bp,single->nextUpdate))
+				goto err;
+			}
+		if (BIO_write(bp,"\n",1) <= 0) goto err;
+		if (!X509V3_extensions_print(bp,
+					"Response Single Extensions",
+					single->singleExtensions, flags, 8))
+							goto err;
+		if (BIO_write(bp,"\n",1) <= 0) goto err;
+		}
+	if (!X509V3_extensions_print(bp, "Response Extensions",
+					rd->responseExtensions, flags, 4))
+							goto err;
+	if(X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 0)
+							goto err;
+
+	for (i=0; i<sk_X509_num(br->certs); i++)
+		{
+		X509_print(bp, sk_X509_value(br->certs,i));
+		PEM_write_bio_X509(bp,sk_X509_value(br->certs,i));
+		}
+
+	ret = 1;
+err:
+	OCSP_BASICRESP_free(br);
+	return ret;
+	}
diff --git a/openssl/crypto/ocsp/ocsp_srv.c b/openssl/crypto/ocsp/ocsp_srv.c
new file mode 100644
index 0000000..1c606dd
--- /dev/null
+++ b/openssl/crypto/ocsp/ocsp_srv.c
@@ -0,0 +1,264 @@
+/* ocsp_srv.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <cryptlib.h>
+#include <openssl/objects.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/ocsp.h>
+
+/* Utility functions related to sending OCSP responses and extracting
+ * relevant information from the request.
+ */
+
+int OCSP_request_onereq_count(OCSP_REQUEST *req)
+	{
+	return sk_OCSP_ONEREQ_num(req->tbsRequest->requestList);
+	}
+
+OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i)
+	{
+	return sk_OCSP_ONEREQ_value(req->tbsRequest->requestList, i);
+	}
+
+OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one)
+	{
+	return one->reqCert;
+	}
+
+int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd,
+			ASN1_OCTET_STRING **pikeyHash,
+			ASN1_INTEGER **pserial, OCSP_CERTID *cid)
+	{
+	if (!cid) return 0;
+	if (pmd) *pmd = cid->hashAlgorithm->algorithm;
+	if(piNameHash) *piNameHash = cid->issuerNameHash;
+	if (pikeyHash) *pikeyHash = cid->issuerKeyHash;
+	if (pserial) *pserial = cid->serialNumber;
+	return 1;
+	}
+
+int OCSP_request_is_signed(OCSP_REQUEST *req)
+	{
+	if(req->optionalSignature) return 1;
+	return 0;
+	}
+
+/* Create an OCSP response and encode an optional basic response */
+OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs)
+        {
+        OCSP_RESPONSE *rsp = NULL;
+
+	if (!(rsp = OCSP_RESPONSE_new())) goto err;
+	if (!(ASN1_ENUMERATED_set(rsp->responseStatus, status))) goto err;
+	if (!bs) return rsp;
+	if (!(rsp->responseBytes = OCSP_RESPBYTES_new())) goto err;
+	rsp->responseBytes->responseType = OBJ_nid2obj(NID_id_pkix_OCSP_basic);
+	if (!ASN1_item_pack(bs, ASN1_ITEM_rptr(OCSP_BASICRESP), &rsp->responseBytes->response))
+				goto err;
+	return rsp;
+err:
+	if (rsp) OCSP_RESPONSE_free(rsp);
+	return NULL;
+	}
+
+
+OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp,
+						OCSP_CERTID *cid,
+						int status, int reason,
+						ASN1_TIME *revtime,
+					ASN1_TIME *thisupd, ASN1_TIME *nextupd)
+	{
+	OCSP_SINGLERESP *single = NULL;
+	OCSP_CERTSTATUS *cs;
+	OCSP_REVOKEDINFO *ri;
+
+	if(!rsp->tbsResponseData->responses &&
+	    !(rsp->tbsResponseData->responses = sk_OCSP_SINGLERESP_new_null()))
+		goto err;
+
+	if (!(single = OCSP_SINGLERESP_new()))
+		goto err;
+
+
+
+	if (!ASN1_TIME_to_generalizedtime(thisupd, &single->thisUpdate))
+		goto err;
+	if (nextupd &&
+		!ASN1_TIME_to_generalizedtime(nextupd, &single->nextUpdate))
+		goto err;
+
+	OCSP_CERTID_free(single->certId);
+
+	if(!(single->certId = OCSP_CERTID_dup(cid)))
+		goto err;
+
+	cs = single->certStatus;
+	switch(cs->type = status)
+		{
+	case V_OCSP_CERTSTATUS_REVOKED:
+		if (!revtime)
+		        {
+		        OCSPerr(OCSP_F_OCSP_BASIC_ADD1_STATUS,OCSP_R_NO_REVOKED_TIME);
+			goto err;
+		        }
+		if (!(cs->value.revoked = ri = OCSP_REVOKEDINFO_new())) goto err;
+		if (!ASN1_TIME_to_generalizedtime(revtime, &ri->revocationTime))
+			goto err;	
+		if (reason != OCSP_REVOKED_STATUS_NOSTATUS)
+		        {
+			if (!(ri->revocationReason = ASN1_ENUMERATED_new())) 
+			        goto err;
+			if (!(ASN1_ENUMERATED_set(ri->revocationReason, 
+						  reason)))
+			        goto err;	
+			}
+		break;
+
+	case V_OCSP_CERTSTATUS_GOOD:
+		cs->value.good = ASN1_NULL_new();
+		break;
+
+	case V_OCSP_CERTSTATUS_UNKNOWN:
+		cs->value.unknown = ASN1_NULL_new();
+		break;
+
+	default:
+		goto err;
+
+		}
+	if (!(sk_OCSP_SINGLERESP_push(rsp->tbsResponseData->responses, single)))
+		goto err;
+	return single;
+err:
+	OCSP_SINGLERESP_free(single);
+	return NULL;
+	}
+
+/* Add a certificate to an OCSP request */
+
+int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert)
+	{
+	if (!resp->certs && !(resp->certs = sk_X509_new_null()))
+		return 0;
+
+	if(!sk_X509_push(resp->certs, cert)) return 0;
+	CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
+	return 1;
+	}
+
+int OCSP_basic_sign(OCSP_BASICRESP *brsp, 
+			X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
+			STACK_OF(X509) *certs, unsigned long flags)
+        {
+	int i;
+	OCSP_RESPID *rid;
+
+	if (!X509_check_private_key(signer, key))
+		{
+		OCSPerr(OCSP_F_OCSP_BASIC_SIGN, OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+		goto err;
+		}
+
+	if(!(flags & OCSP_NOCERTS))
+		{
+		if(!OCSP_basic_add1_cert(brsp, signer))
+			goto err;
+		for (i = 0; i < sk_X509_num(certs); i++)
+			{
+			X509 *tmpcert = sk_X509_value(certs, i);
+			if(!OCSP_basic_add1_cert(brsp, tmpcert))
+				goto err;
+			}
+		}
+
+	rid = brsp->tbsResponseData->responderId;
+	if (flags & OCSP_RESPID_KEY)
+		{
+		unsigned char md[SHA_DIGEST_LENGTH];
+		X509_pubkey_digest(signer, EVP_sha1(), md, NULL);
+		if (!(rid->value.byKey = ASN1_OCTET_STRING_new()))
+			goto err;
+		if (!(ASN1_OCTET_STRING_set(rid->value.byKey, md, SHA_DIGEST_LENGTH)))
+				goto err;
+		rid->type = V_OCSP_RESPID_KEY;
+		}
+	else
+		{
+		if (!X509_NAME_set(&rid->value.byName,
+					X509_get_subject_name(signer)))
+				goto err;
+		rid->type = V_OCSP_RESPID_NAME;
+		}
+
+	if (!(flags & OCSP_NOTIME) &&
+		!X509_gmtime_adj(brsp->tbsResponseData->producedAt, 0))
+		goto err;
+
+	/* Right now, I think that not doing double hashing is the right
+	   thing.	-- Richard Levitte */
+
+	if (!OCSP_BASICRESP_sign(brsp, key, dgst, 0)) goto err;
+
+	return 1;
+err:
+	return 0;
+	}
diff --git a/openssl/crypto/ocsp/ocsp_vfy.c b/openssl/crypto/ocsp/ocsp_vfy.c
new file mode 100644
index 0000000..415d67e
--- /dev/null
+++ b/openssl/crypto/ocsp/ocsp_vfy.c
@@ -0,0 +1,446 @@
+/* ocsp_vfy.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/ocsp.h>
+#include <openssl/err.h>
+#include <string.h>
+
+static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
+				X509_STORE *st, unsigned long flags);
+static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id);
+static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, unsigned long flags);
+static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret);
+static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, STACK_OF(OCSP_SINGLERESP) *sresp);
+static int ocsp_check_delegated(X509 *x, int flags);
+static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, X509_NAME *nm, STACK_OF(X509) *certs,
+				X509_STORE *st, unsigned long flags);
+
+/* Verify a basic response message */
+
+int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
+				X509_STORE *st, unsigned long flags)
+	{
+	X509 *signer, *x;
+	STACK_OF(X509) *chain = NULL;
+	X509_STORE_CTX ctx;
+	int i, ret = 0;
+	ret = ocsp_find_signer(&signer, bs, certs, st, flags);
+	if (!ret)
+		{
+		OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
+		goto end;
+		}
+	if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
+		flags |= OCSP_NOVERIFY;
+	if (!(flags & OCSP_NOSIGS))
+		{
+		EVP_PKEY *skey;
+		skey = X509_get_pubkey(signer);
+		ret = OCSP_BASICRESP_verify(bs, skey, 0);
+		EVP_PKEY_free(skey);
+		if(ret <= 0)
+			{
+			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE);
+			goto end;
+			}
+		}
+	if (!(flags & OCSP_NOVERIFY))
+		{
+		int init_res;
+		if(flags & OCSP_NOCHAIN)
+			init_res = X509_STORE_CTX_init(&ctx, st, signer, NULL);
+		else
+			init_res = X509_STORE_CTX_init(&ctx, st, signer, bs->certs);
+		if(!init_res)
+			{
+			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,ERR_R_X509_LIB);
+			goto end;
+			}
+
+		X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER);
+		ret = X509_verify_cert(&ctx);
+		chain = X509_STORE_CTX_get1_chain(&ctx);
+		X509_STORE_CTX_cleanup(&ctx);
+                if (ret <= 0)
+			{
+			i = X509_STORE_CTX_get_error(&ctx);	
+			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,OCSP_R_CERTIFICATE_VERIFY_ERROR);
+			ERR_add_error_data(2, "Verify error:",
+					X509_verify_cert_error_string(i));
+                        goto end;
+                	}
+		if(flags & OCSP_NOCHECKS)
+			{
+			ret = 1;
+			goto end;
+			}
+		/* At this point we have a valid certificate chain
+		 * need to verify it against the OCSP issuer criteria.
+		 */
+		ret = ocsp_check_issuer(bs, chain, flags);
+
+		/* If fatal error or valid match then finish */
+		if (ret != 0) goto end;
+
+		/* Easy case: explicitly trusted. Get root CA and
+		 * check for explicit trust
+		 */
+		if(flags & OCSP_NOEXPLICIT) goto end;
+
+		x = sk_X509_value(chain, sk_X509_num(chain) - 1);
+		if(X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED)
+			{
+			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,OCSP_R_ROOT_CA_NOT_TRUSTED);
+			goto end;
+			}
+		ret = 1;
+		}
+
+
+
+	end:
+	if(chain) sk_X509_pop_free(chain, X509_free);
+	return ret;
+	}
+
+
+static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
+				X509_STORE *st, unsigned long flags)
+	{
+	X509 *signer;
+	OCSP_RESPID *rid = bs->tbsResponseData->responderId;
+	if ((signer = ocsp_find_signer_sk(certs, rid)))
+		{
+		*psigner = signer;
+		return 2;
+		}
+	if(!(flags & OCSP_NOINTERN) &&
+	    (signer = ocsp_find_signer_sk(bs->certs, rid)))
+		{
+		*psigner = signer;
+		return 1;
+		}
+	/* Maybe lookup from store if by subject name */
+
+	*psigner = NULL;
+	return 0;
+	}
+
+
+static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
+	{
+	int i;
+	unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
+	X509 *x;
+
+	/* Easy if lookup by name */
+	if (id->type == V_OCSP_RESPID_NAME)
+		return X509_find_by_subject(certs, id->value.byName);
+
+	/* Lookup by key hash */
+
+	/* If key hash isn't SHA1 length then forget it */
+	if (id->value.byKey->length != SHA_DIGEST_LENGTH) return NULL;
+	keyhash = id->value.byKey->data;
+	/* Calculate hash of each key and compare */
+	for (i = 0; i < sk_X509_num(certs); i++)
+		{
+		x = sk_X509_value(certs, i);
+		X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
+		if(!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
+			return x;
+		}
+	return NULL;
+	}
+
+
+static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, unsigned long flags)
+	{
+	STACK_OF(OCSP_SINGLERESP) *sresp;
+	X509 *signer, *sca;
+	OCSP_CERTID *caid = NULL;
+	int i;
+	sresp = bs->tbsResponseData->responses;
+
+	if (sk_X509_num(chain) <= 0)
+		{
+		OCSPerr(OCSP_F_OCSP_CHECK_ISSUER, OCSP_R_NO_CERTIFICATES_IN_CHAIN);
+		return -1;
+		}
+
+	/* See if the issuer IDs match. */
+	i = ocsp_check_ids(sresp, &caid);
+
+	/* If ID mismatch or other error then return */
+	if (i <= 0) return i;
+
+	signer = sk_X509_value(chain, 0);
+	/* Check to see if OCSP responder CA matches request CA */
+	if (sk_X509_num(chain) > 1)
+		{
+		sca = sk_X509_value(chain, 1);
+		i = ocsp_match_issuerid(sca, caid, sresp);
+		if (i < 0) return i;
+		if (i)
+			{
+			/* We have a match, if extensions OK then success */
+			if (ocsp_check_delegated(signer, flags)) return 1;
+			return 0;
+			}
+		}
+
+	/* Otherwise check if OCSP request signed directly by request CA */
+	return ocsp_match_issuerid(signer, caid, sresp);
+	}
+
+
+/* Check the issuer certificate IDs for equality. If there is a mismatch with the same
+ * algorithm then there's no point trying to match any certificates against the issuer.
+ * If the issuer IDs all match then we just need to check equality against one of them.
+ */
+	
+static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret)
+	{
+	OCSP_CERTID *tmpid, *cid;
+	int i, idcount;
+
+	idcount = sk_OCSP_SINGLERESP_num(sresp);
+	if (idcount <= 0)
+		{
+		OCSPerr(OCSP_F_OCSP_CHECK_IDS, OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA);
+		return -1;
+		}
+
+	cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId;
+
+	*ret = NULL;
+
+	for (i = 1; i < idcount; i++)
+		{
+		tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
+		/* Check to see if IDs match */
+		if (OCSP_id_issuer_cmp(cid, tmpid))
+			{
+			/* If algoritm mismatch let caller deal with it */
+			if (OBJ_cmp(tmpid->hashAlgorithm->algorithm,
+					cid->hashAlgorithm->algorithm))
+					return 2;
+			/* Else mismatch */
+			return 0;
+			}
+		}
+
+	/* All IDs match: only need to check one ID */
+	*ret = cid;
+	return 1;
+	}
+
+
+static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
+			STACK_OF(OCSP_SINGLERESP) *sresp)
+	{
+	/* If only one ID to match then do it */
+	if(cid)
+		{
+		const EVP_MD *dgst;
+		X509_NAME *iname;
+		int mdlen;
+		unsigned char md[EVP_MAX_MD_SIZE];
+		if (!(dgst = EVP_get_digestbyobj(cid->hashAlgorithm->algorithm)))
+			{
+			OCSPerr(OCSP_F_OCSP_MATCH_ISSUERID, OCSP_R_UNKNOWN_MESSAGE_DIGEST);
+			return -1;
+			}
+
+		mdlen = EVP_MD_size(dgst);
+		if (mdlen < 0)
+		    return -1;
+		if ((cid->issuerNameHash->length != mdlen) ||
+		   (cid->issuerKeyHash->length != mdlen))
+			return 0;
+		iname = X509_get_subject_name(cert);
+		if (!X509_NAME_digest(iname, dgst, md, NULL))
+			return -1;
+		if (memcmp(md, cid->issuerNameHash->data, mdlen))
+			return 0;
+		X509_pubkey_digest(cert, dgst, md, NULL);
+		if (memcmp(md, cid->issuerKeyHash->data, mdlen))
+			return 0;
+
+		return 1;
+
+		}
+	else
+		{
+		/* We have to match the whole lot */
+		int i, ret;
+		OCSP_CERTID *tmpid;
+		for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++)
+			{
+			tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
+			ret = ocsp_match_issuerid(cert, tmpid, NULL);
+			if (ret <= 0) return ret;
+			}
+		return 1;
+		}
+			
+	}
+
+static int ocsp_check_delegated(X509 *x, int flags)
+	{
+	X509_check_purpose(x, -1, 0);
+	if ((x->ex_flags & EXFLAG_XKUSAGE) &&
+	    (x->ex_xkusage & XKU_OCSP_SIGN))
+		return 1;
+	OCSPerr(OCSP_F_OCSP_CHECK_DELEGATED, OCSP_R_MISSING_OCSPSIGNING_USAGE);
+	return 0;
+	}
+
+/* Verify an OCSP request. This is fortunately much easier than OCSP
+ * response verify. Just find the signers certificate and verify it
+ * against a given trust value.
+ */
+
+int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store, unsigned long flags)
+        {
+	X509 *signer;
+	X509_NAME *nm;
+	GENERAL_NAME *gen;
+	int ret;
+	X509_STORE_CTX ctx;
+	if (!req->optionalSignature) 
+		{
+		OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED);
+		return 0;
+		}
+	gen = req->tbsRequest->requestorName;
+	if (!gen || gen->type != GEN_DIRNAME)
+		{
+		OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE);
+		return 0;
+		}
+	nm = gen->d.directoryName;
+	ret = ocsp_req_find_signer(&signer, req, nm, certs, store, flags);
+	if (ret <= 0)
+		{
+		OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
+		return 0;
+		}
+	if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
+		flags |= OCSP_NOVERIFY;
+	if (!(flags & OCSP_NOSIGS))
+		{
+		EVP_PKEY *skey;
+		skey = X509_get_pubkey(signer);
+		ret = OCSP_REQUEST_verify(req, skey);
+		EVP_PKEY_free(skey);
+		if(ret <= 0)
+			{
+			OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNATURE_FAILURE);
+			return 0;
+			}
+		}
+	if (!(flags & OCSP_NOVERIFY))
+		{
+		int init_res;
+		if(flags & OCSP_NOCHAIN)
+			init_res = X509_STORE_CTX_init(&ctx, store, signer, NULL);
+		else
+			init_res = X509_STORE_CTX_init(&ctx, store, signer,
+					req->optionalSignature->certs);
+		if(!init_res)
+			{
+			OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,ERR_R_X509_LIB);
+			return 0;
+			}
+
+		X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER);
+		X509_STORE_CTX_set_trust(&ctx, X509_TRUST_OCSP_REQUEST);
+		ret = X509_verify_cert(&ctx);
+		X509_STORE_CTX_cleanup(&ctx);
+                if (ret <= 0)
+			{
+			ret = X509_STORE_CTX_get_error(&ctx);	
+			OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,OCSP_R_CERTIFICATE_VERIFY_ERROR);
+			ERR_add_error_data(2, "Verify error:",
+					X509_verify_cert_error_string(ret));
+                        return 0;
+                	}
+		}
+	return 1;
+        }
+
+static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, X509_NAME *nm, STACK_OF(X509) *certs,
+				X509_STORE *st, unsigned long flags)
+	{
+	X509 *signer;
+	if(!(flags & OCSP_NOINTERN))
+		{
+		signer = X509_find_by_subject(req->optionalSignature->certs, nm);
+		*psigner = signer;
+		return 1;
+		}
+
+	signer = X509_find_by_subject(certs, nm);
+	if (signer)
+		{
+		*psigner = signer;
+		return 2;
+		}
+	return 0;
+	}
diff --git a/openssl/crypto/opensslconf.h.in b/openssl/crypto/opensslconf.h.in
new file mode 100644
index 0000000..97e3745
--- /dev/null
+++ b/openssl/crypto/opensslconf.h.in
@@ -0,0 +1,154 @@
+/* crypto/opensslconf.h.in */
+
+/* Generate 80386 code? */
+#undef I386_ONLY
+
+#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
+#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
+#define ENGINESDIR "/usr/local/lib/engines"
+#define OPENSSLDIR "/usr/local/ssl"
+#endif
+#endif
+
+#undef OPENSSL_UNISTD
+#define OPENSSL_UNISTD <unistd.h>
+
+#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
+#define IDEA_INT unsigned int
+#endif
+
+#if defined(HEADER_MD2_H) && !defined(MD2_INT)
+#define MD2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC2_H) && !defined(RC2_INT)
+/* I need to put in a mod for the alpha - eay */
+#define RC2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC4_H)
+#if !defined(RC4_INT)
+/* using int types make the structure larger but make the code faster
+ * on most boxes I have tested - up to %20 faster. */
+/*
+ * I don't know what does "most" mean, but declaring "int" is a must on:
+ * - Intel P6 because partial register stalls are very expensive;
+ * - elder Alpha because it lacks byte load/store instructions;
+ */
+#define RC4_INT unsigned int
+#endif
+#if !defined(RC4_CHUNK)
+/*
+ * This enables code handling data aligned at natural CPU word
+ * boundary. See crypto/rc4/rc4_enc.c for further details.
+ */
+#undef RC4_CHUNK
+#endif
+#endif
+
+#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+#ifndef DES_LONG
+#define DES_LONG unsigned long
+#endif
+#endif
+
+#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
+#define CONFIG_HEADER_BN_H
+#undef BN_LLONG
+
+/* Should we define BN_DIV2W here? */
+
+/* Only one for the following should be defined */
+#undef SIXTY_FOUR_BIT_LONG
+#undef SIXTY_FOUR_BIT
+#define THIRTY_TWO_BIT
+#endif
+
+#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
+#define CONFIG_HEADER_RC4_LOCL_H
+/* if this is defined data[i] is used instead of *data, this is a %20
+ * speedup on x86 */
+#undef RC4_INDEX
+#endif
+
+#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
+#define CONFIG_HEADER_BF_LOCL_H
+#undef BF_PTR
+#endif /* HEADER_BF_LOCL_H */
+
+#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
+#define CONFIG_HEADER_DES_LOCL_H
+#ifndef DES_DEFAULT_OPTIONS
+/* the following is tweaked from a config script, that is why it is a
+ * protected undef/define */
+#ifndef DES_PTR
+#undef DES_PTR
+#endif
+
+/* This helps C compiler generate the correct code for multiple functional
+ * units.  It reduces register dependancies at the expense of 2 more
+ * registers */
+#ifndef DES_RISC1
+#undef DES_RISC1
+#endif
+
+#ifndef DES_RISC2
+#undef DES_RISC2
+#endif
+
+#if defined(DES_RISC1) && defined(DES_RISC2)
+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
+#endif
+
+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
+ * Very mucy CPU dependant */
+#ifndef DES_UNROLL
+#undef DES_UNROLL
+#endif
+
+/* These default values were supplied by
+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
+ * They are only used if nothing else has been defined */
+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
+/* Special defines which change the way the code is built depending on the
+   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
+   even newer MIPS CPU's, but at the moment one size fits all for
+   optimization options.  Older Sparc's work better with only UNROLL, but
+   there's no way to tell at compile time what it is you're running on */
+ 
+#if defined( sun )		/* Newer Sparc's */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#elif defined( __ultrix )	/* Older MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined( __osf1__ )	/* Alpha */
+#  define DES_PTR
+#  define DES_RISC2
+#elif defined ( _AIX )		/* RS6000 */
+  /* Unknown */
+#elif defined( __hpux )		/* HP-PA */
+  /* Unknown */
+#elif defined( __aux )		/* 68K */
+  /* Unknown */
+#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
+#  define DES_UNROLL
+#elif defined( __sgi )		/* Newer MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined(i386) || defined(__i386__)	/* x86 boxes, should be gcc */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#endif /* Systems-specific speed defines */
+#endif
+
+#endif /* DES_DEFAULT_OPTIONS */
+#endif /* HEADER_DES_LOCL_H */
diff --git a/openssl/crypto/opensslv.h b/openssl/crypto/opensslv.h
new file mode 100644
index 0000000..d6d61a0
--- /dev/null
+++ b/openssl/crypto/opensslv.h
@@ -0,0 +1,89 @@
+#ifndef HEADER_OPENSSLV_H
+#define HEADER_OPENSSLV_H
+
+/* Numeric release version identifier:
+ * MNNFFPPS: major minor fix patch status
+ * The status nibble has one of the values 0 for development, 1 to e for betas
+ * 1 to 14, and f for release.  The patch level is exactly that.
+ * For example:
+ * 0.9.3-dev	  0x00903000
+ * 0.9.3-beta1	  0x00903001
+ * 0.9.3-beta2-dev 0x00903002
+ * 0.9.3-beta2    0x00903002 (same as ...beta2-dev)
+ * 0.9.3	  0x0090300f
+ * 0.9.3a	  0x0090301f
+ * 0.9.4 	  0x0090400f
+ * 1.2.3z	  0x102031af
+ *
+ * For continuity reasons (because 0.9.5 is already out, and is coded
+ * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level
+ * part is slightly different, by setting the highest bit.  This means
+ * that 0.9.5a looks like this: 0x0090581f.  At 0.9.6, we can start
+ * with 0x0090600S...
+ *
+ * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.)
+ * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
+ *  major minor fix final patch/beta)
+ */
+#define OPENSSL_VERSION_NUMBER	0x1000006fL
+#ifdef OPENSSL_FIPS
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.0f-fips 4 Jan 2012"
+#else
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.0f 4 Jan 2012"
+#endif
+#define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
+
+
+/* The macros below are to be used for shared library (.so, .dll, ...)
+ * versioning.  That kind of versioning works a bit differently between
+ * operating systems.  The most usual scheme is to set a major and a minor
+ * number, and have the runtime loader check that the major number is equal
+ * to what it was at application link time, while the minor number has to
+ * be greater or equal to what it was at application link time.  With this
+ * scheme, the version number is usually part of the file name, like this:
+ *
+ *	libcrypto.so.0.9
+ *
+ * Some unixen also make a softlink with the major verson number only:
+ *
+ *	libcrypto.so.0
+ *
+ * On Tru64 and IRIX 6.x it works a little bit differently.  There, the
+ * shared library version is stored in the file, and is actually a series
+ * of versions, separated by colons.  The rightmost version present in the
+ * library when linking an application is stored in the application to be
+ * matched at run time.  When the application is run, a check is done to
+ * see if the library version stored in the application matches any of the
+ * versions in the version string of the library itself.
+ * This version string can be constructed in any way, depending on what
+ * kind of matching is desired.  However, to implement the same scheme as
+ * the one used in the other unixen, all compatible versions, from lowest
+ * to highest, should be part of the string.  Consecutive builds would
+ * give the following versions strings:
+ *
+ *	3.0
+ *	3.0:3.1
+ *	3.0:3.1:3.2
+ *	4.0
+ *	4.0:4.1
+ *
+ * Notice how version 4 is completely incompatible with version, and
+ * therefore give the breach you can see.
+ *
+ * There may be other schemes as well that I haven't yet discovered.
+ *
+ * So, here's the way it works here: first of all, the library version
+ * number doesn't need at all to match the overall OpenSSL version.
+ * However, it's nice and more understandable if it actually does.
+ * The current library version is stored in the macro SHLIB_VERSION_NUMBER,
+ * which is just a piece of text in the format "M.m.e" (Major, minor, edit).
+ * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways,
+ * we need to keep a history of version numbers, which is done in the
+ * macro SHLIB_VERSION_HISTORY.  The numbers are separated by colons and
+ * should only keep the versions that are binary compatible with the current.
+ */
+#define SHLIB_VERSION_HISTORY ""
+#define SHLIB_VERSION_NUMBER "1.0.0"
+
+
+#endif /* HEADER_OPENSSLV_H */
diff --git a/openssl/crypto/ossl_typ.h b/openssl/crypto/ossl_typ.h
new file mode 100644
index 0000000..12bd701
--- /dev/null
+++ b/openssl/crypto/ossl_typ.h
@@ -0,0 +1,200 @@
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_OPENSSL_TYPES_H
+#define HEADER_OPENSSL_TYPES_H
+
+#include <openssl/e_os2.h>
+
+#ifdef NO_ASN1_TYPEDEFS
+#define ASN1_INTEGER		ASN1_STRING
+#define ASN1_ENUMERATED		ASN1_STRING
+#define ASN1_BIT_STRING		ASN1_STRING
+#define ASN1_OCTET_STRING	ASN1_STRING
+#define ASN1_PRINTABLESTRING	ASN1_STRING
+#define ASN1_T61STRING		ASN1_STRING
+#define ASN1_IA5STRING		ASN1_STRING
+#define ASN1_UTCTIME		ASN1_STRING
+#define ASN1_GENERALIZEDTIME	ASN1_STRING
+#define ASN1_TIME		ASN1_STRING
+#define ASN1_GENERALSTRING	ASN1_STRING
+#define ASN1_UNIVERSALSTRING	ASN1_STRING
+#define ASN1_BMPSTRING		ASN1_STRING
+#define ASN1_VISIBLESTRING	ASN1_STRING
+#define ASN1_UTF8STRING		ASN1_STRING
+#define ASN1_BOOLEAN		int
+#define ASN1_NULL		int
+#else
+typedef struct asn1_string_st ASN1_INTEGER;
+typedef struct asn1_string_st ASN1_ENUMERATED;
+typedef struct asn1_string_st ASN1_BIT_STRING;
+typedef struct asn1_string_st ASN1_OCTET_STRING;
+typedef struct asn1_string_st ASN1_PRINTABLESTRING;
+typedef struct asn1_string_st ASN1_T61STRING;
+typedef struct asn1_string_st ASN1_IA5STRING;
+typedef struct asn1_string_st ASN1_GENERALSTRING;
+typedef struct asn1_string_st ASN1_UNIVERSALSTRING;
+typedef struct asn1_string_st ASN1_BMPSTRING;
+typedef struct asn1_string_st ASN1_UTCTIME;
+typedef struct asn1_string_st ASN1_TIME;
+typedef struct asn1_string_st ASN1_GENERALIZEDTIME;
+typedef struct asn1_string_st ASN1_VISIBLESTRING;
+typedef struct asn1_string_st ASN1_UTF8STRING;
+typedef int ASN1_BOOLEAN;
+typedef int ASN1_NULL;
+#endif
+
+typedef struct asn1_pctx_st ASN1_PCTX;
+
+#ifdef OPENSSL_SYS_WIN32
+#undef X509_NAME
+#undef X509_EXTENSIONS
+#undef X509_CERT_PAIR
+#undef PKCS7_ISSUER_AND_SERIAL
+#undef OCSP_REQUEST
+#undef OCSP_RESPONSE
+#endif
+
+#ifdef BIGNUM
+#undef BIGNUM
+#endif
+typedef struct bignum_st BIGNUM;
+typedef struct bignum_ctx BN_CTX;
+typedef struct bn_blinding_st BN_BLINDING;
+typedef struct bn_mont_ctx_st BN_MONT_CTX;
+typedef struct bn_recp_ctx_st BN_RECP_CTX;
+typedef struct bn_gencb_st BN_GENCB;
+
+typedef struct buf_mem_st BUF_MEM;
+
+typedef struct evp_cipher_st EVP_CIPHER;
+typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
+typedef struct env_md_st EVP_MD;
+typedef struct env_md_ctx_st EVP_MD_CTX;
+typedef struct evp_pkey_st EVP_PKEY;
+
+typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;
+
+typedef struct evp_pkey_method_st EVP_PKEY_METHOD;
+typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
+
+typedef struct dh_st DH;
+typedef struct dh_method DH_METHOD;
+
+typedef struct dsa_st DSA;
+typedef struct dsa_method DSA_METHOD;
+
+typedef struct rsa_st RSA;
+typedef struct rsa_meth_st RSA_METHOD;
+
+typedef struct rand_meth_st RAND_METHOD;
+
+typedef struct ecdh_method ECDH_METHOD;
+typedef struct ecdsa_method ECDSA_METHOD;
+
+typedef struct x509_st X509;
+typedef struct X509_algor_st X509_ALGOR;
+typedef struct X509_crl_st X509_CRL;
+typedef struct x509_crl_method_st X509_CRL_METHOD;
+typedef struct x509_revoked_st X509_REVOKED;
+typedef struct X509_name_st X509_NAME;
+typedef struct X509_pubkey_st X509_PUBKEY;
+typedef struct x509_store_st X509_STORE;
+typedef struct x509_store_ctx_st X509_STORE_CTX;
+
+typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;
+
+typedef struct v3_ext_ctx X509V3_CTX;
+typedef struct conf_st CONF;
+
+typedef struct store_st STORE;
+typedef struct store_method_st STORE_METHOD;
+
+typedef struct ui_st UI;
+typedef struct ui_method_st UI_METHOD;
+
+typedef struct st_ERR_FNS ERR_FNS;
+
+typedef struct engine_st ENGINE;
+typedef struct ssl_st SSL;
+typedef struct ssl_ctx_st SSL_CTX;
+
+typedef struct X509_POLICY_NODE_st X509_POLICY_NODE;
+typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL;
+typedef struct X509_POLICY_TREE_st X509_POLICY_TREE;
+typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE;
+
+typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID;
+typedef struct DIST_POINT_st DIST_POINT;
+typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT;
+typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS;
+
+  /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */
+#define DECLARE_PKCS12_STACK_OF(type) /* Nothing */
+#define IMPLEMENT_PKCS12_STACK_OF(type) /* Nothing */
+
+typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
+/* Callback types for crypto.h */
+typedef int CRYPTO_EX_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+					int idx, long argl, void *argp);
+typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+					int idx, long argl, void *argp);
+typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, 
+					int idx, long argl, void *argp);
+
+typedef struct ocsp_req_ctx_st OCSP_REQ_CTX;
+typedef struct ocsp_response_st OCSP_RESPONSE;
+typedef struct ocsp_responder_id_st OCSP_RESPID;
+
+#endif /* def HEADER_OPENSSL_TYPES_H */
diff --git a/openssl/crypto/pem/Makefile b/openssl/crypto/pem/Makefile
new file mode 100644
index 0000000..2cc7801
--- /dev/null
+++ b/openssl/crypto/pem/Makefile
@@ -0,0 +1,258 @@
+#
+# OpenSSL/crypto/pem/Makefile
+#
+
+DIR=	pem
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= pem_sign.c pem_seal.c pem_info.c pem_lib.c pem_all.c pem_err.c \
+	pem_x509.c pem_xaux.c pem_oth.c pem_pk8.c pem_pkey.c pvkfmt.c
+
+LIBOBJ=	pem_sign.o pem_seal.o pem_info.o pem_lib.o pem_all.o pem_err.o \
+	pem_x509.o pem_xaux.o pem_oth.o pem_pk8.o pem_pkey.o pvkfmt.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= pem.h pem2.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links: $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+pem_all.o: ../../e_os.h ../../include/openssl/asn1.h
+pem_all.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pem_all.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+pem_all.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+pem_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+pem_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+pem_all.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+pem_all.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pem_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+pem_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
+pem_all.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
+pem_all.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+pem_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pem_all.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pem_all.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_all.c
+pem_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+pem_err.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+pem_err.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+pem_err.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+pem_err.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+pem_err.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pem_err.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pem_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pem_err.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+pem_err.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+pem_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pem_err.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pem_err.o: ../../include/openssl/x509_vfy.h pem_err.c
+pem_info.o: ../../e_os.h ../../include/openssl/asn1.h
+pem_info.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pem_info.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+pem_info.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+pem_info.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+pem_info.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+pem_info.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pem_info.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pem_info.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pem_info.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+pem_info.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+pem_info.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+pem_info.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+pem_info.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+pem_info.o: ../cryptlib.h pem_info.c
+pem_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+pem_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pem_lib.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+pem_lib.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
+pem_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+pem_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+pem_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+pem_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pem_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pem_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pem_lib.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+pem_lib.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+pem_lib.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+pem_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pem_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+pem_lib.o: ../../include/openssl/ui_compat.h ../../include/openssl/x509.h
+pem_lib.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
+pem_lib.o: pem_lib.c
+pem_oth.o: ../../e_os.h ../../include/openssl/asn1.h
+pem_oth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pem_oth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+pem_oth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+pem_oth.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+pem_oth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+pem_oth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pem_oth.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+pem_oth.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
+pem_oth.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
+pem_oth.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+pem_oth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pem_oth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pem_oth.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_oth.c
+pem_pk8.o: ../../e_os.h ../../include/openssl/asn1.h
+pem_pk8.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pem_pk8.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+pem_pk8.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+pem_pk8.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+pem_pk8.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+pem_pk8.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pem_pk8.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+pem_pk8.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
+pem_pk8.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs12.h
+pem_pk8.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+pem_pk8.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+pem_pk8.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+pem_pk8.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+pem_pk8.o: ../cryptlib.h pem_pk8.c
+pem_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
+pem_pkey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pem_pkey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+pem_pkey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+pem_pkey.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+pem_pkey.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+pem_pkey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pem_pkey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pem_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pem_pkey.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+pem_pkey.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+pem_pkey.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+pem_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pem_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pem_pkey.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
+pem_pkey.o: pem_pkey.c
+pem_seal.o: ../../e_os.h ../../include/openssl/asn1.h
+pem_seal.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pem_seal.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+pem_seal.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+pem_seal.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+pem_seal.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+pem_seal.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pem_seal.o: ../../include/openssl/opensslconf.h
+pem_seal.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pem_seal.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+pem_seal.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+pem_seal.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+pem_seal.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pem_seal.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pem_seal.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_seal.c
+pem_sign.o: ../../e_os.h ../../include/openssl/asn1.h
+pem_sign.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pem_sign.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+pem_sign.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+pem_sign.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+pem_sign.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+pem_sign.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pem_sign.o: ../../include/openssl/opensslconf.h
+pem_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pem_sign.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+pem_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+pem_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+pem_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+pem_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+pem_sign.o: ../cryptlib.h pem_sign.c
+pem_x509.o: ../../e_os.h ../../include/openssl/asn1.h
+pem_x509.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pem_x509.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+pem_x509.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+pem_x509.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+pem_x509.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+pem_x509.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pem_x509.o: ../../include/openssl/opensslconf.h
+pem_x509.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pem_x509.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+pem_x509.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+pem_x509.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pem_x509.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pem_x509.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_x509.c
+pem_xaux.o: ../../e_os.h ../../include/openssl/asn1.h
+pem_xaux.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pem_xaux.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+pem_xaux.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+pem_xaux.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+pem_xaux.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+pem_xaux.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pem_xaux.o: ../../include/openssl/opensslconf.h
+pem_xaux.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pem_xaux.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+pem_xaux.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+pem_xaux.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pem_xaux.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pem_xaux.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_xaux.c
+pvkfmt.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+pvkfmt.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+pvkfmt.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+pvkfmt.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+pvkfmt.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+pvkfmt.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+pvkfmt.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pvkfmt.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pvkfmt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pvkfmt.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+pvkfmt.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+pvkfmt.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+pvkfmt.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pvkfmt.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pvkfmt.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pvkfmt.c
diff --git a/openssl/crypto/pem/message b/openssl/crypto/pem/message
new file mode 100644
index 0000000..e8bf9d7
--- /dev/null
+++ b/openssl/crypto/pem/message
@@ -0,0 +1,16 @@
+-----BEGIN PRIVACY-ENHANCED MESSAGE-----
+Proc-Type: 4,ENCRYPTED
+Proc-Type: 4,MIC-ONLY
+Proc-Type: 4,MIC-CLEAR
+Content-Domain: RFC822
+DEK-Info: DES-CBC,0123456789abcdef
+Originator-Certificate
+ xxxx
+Issuer-Certificate
+ xxxx
+MIC-Info: RSA-MD5,RSA,
+ xxxx
+
+
+-----END PRIVACY-ENHANCED MESSAGE-----
+
diff --git a/openssl/crypto/pem/pem.h b/openssl/crypto/pem/pem.h
new file mode 100644
index 0000000..8a6abab
--- /dev/null
+++ b/openssl/crypto/pem/pem.h
@@ -0,0 +1,641 @@
+/* crypto/pem/pem.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_PEM_H
+#define HEADER_PEM_H
+
+#include <openssl/e_os2.h>
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#ifndef OPENSSL_NO_STACK
+#include <openssl/stack.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem2.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define PEM_BUFSIZE		1024
+
+#define PEM_OBJ_UNDEF		0
+#define PEM_OBJ_X509		1
+#define PEM_OBJ_X509_REQ	2
+#define PEM_OBJ_CRL		3
+#define PEM_OBJ_SSL_SESSION	4
+#define PEM_OBJ_PRIV_KEY	10
+#define PEM_OBJ_PRIV_RSA	11
+#define PEM_OBJ_PRIV_DSA	12
+#define PEM_OBJ_PRIV_DH		13
+#define PEM_OBJ_PUB_RSA		14
+#define PEM_OBJ_PUB_DSA		15
+#define PEM_OBJ_PUB_DH		16
+#define PEM_OBJ_DHPARAMS	17
+#define PEM_OBJ_DSAPARAMS	18
+#define PEM_OBJ_PRIV_RSA_PUBLIC	19
+#define PEM_OBJ_PRIV_ECDSA	20
+#define PEM_OBJ_PUB_ECDSA	21
+#define PEM_OBJ_ECPARAMETERS	22
+
+#define PEM_ERROR		30
+#define PEM_DEK_DES_CBC         40
+#define PEM_DEK_IDEA_CBC        45
+#define PEM_DEK_DES_EDE         50
+#define PEM_DEK_DES_ECB         60
+#define PEM_DEK_RSA             70
+#define PEM_DEK_RSA_MD2         80
+#define PEM_DEK_RSA_MD5         90
+
+#define PEM_MD_MD2		NID_md2
+#define PEM_MD_MD5		NID_md5
+#define PEM_MD_SHA		NID_sha
+#define PEM_MD_MD2_RSA		NID_md2WithRSAEncryption
+#define PEM_MD_MD5_RSA		NID_md5WithRSAEncryption
+#define PEM_MD_SHA_RSA		NID_sha1WithRSAEncryption
+
+#define PEM_STRING_X509_OLD	"X509 CERTIFICATE"
+#define PEM_STRING_X509		"CERTIFICATE"
+#define PEM_STRING_X509_PAIR	"CERTIFICATE PAIR"
+#define PEM_STRING_X509_TRUSTED	"TRUSTED CERTIFICATE"
+#define PEM_STRING_X509_REQ_OLD	"NEW CERTIFICATE REQUEST"
+#define PEM_STRING_X509_REQ	"CERTIFICATE REQUEST"
+#define PEM_STRING_X509_CRL	"X509 CRL"
+#define PEM_STRING_EVP_PKEY	"ANY PRIVATE KEY"
+#define PEM_STRING_PUBLIC	"PUBLIC KEY"
+#define PEM_STRING_RSA		"RSA PRIVATE KEY"
+#define PEM_STRING_RSA_PUBLIC	"RSA PUBLIC KEY"
+#define PEM_STRING_DSA		"DSA PRIVATE KEY"
+#define PEM_STRING_DSA_PUBLIC	"DSA PUBLIC KEY"
+#define PEM_STRING_PKCS7	"PKCS7"
+#define PEM_STRING_PKCS7_SIGNED	"PKCS #7 SIGNED DATA"
+#define PEM_STRING_PKCS8	"ENCRYPTED PRIVATE KEY"
+#define PEM_STRING_PKCS8INF	"PRIVATE KEY"
+#define PEM_STRING_DHPARAMS	"DH PARAMETERS"
+#define PEM_STRING_SSL_SESSION	"SSL SESSION PARAMETERS"
+#define PEM_STRING_DSAPARAMS	"DSA PARAMETERS"
+#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
+#define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
+#define PEM_STRING_ECPRIVATEKEY	"EC PRIVATE KEY"
+#define PEM_STRING_PARAMETERS	"PARAMETERS"
+#define PEM_STRING_CMS		"CMS"
+
+  /* Note that this structure is initialised by PEM_SealInit and cleaned up
+     by PEM_SealFinal (at least for now) */
+typedef struct PEM_Encode_Seal_st
+	{
+	EVP_ENCODE_CTX encode;
+	EVP_MD_CTX md;
+	EVP_CIPHER_CTX cipher;
+	} PEM_ENCODE_SEAL_CTX;
+
+/* enc_type is one off */
+#define PEM_TYPE_ENCRYPTED      10
+#define PEM_TYPE_MIC_ONLY       20
+#define PEM_TYPE_MIC_CLEAR      30
+#define PEM_TYPE_CLEAR		40
+
+typedef struct pem_recip_st
+	{
+	char *name;
+	X509_NAME *dn;
+
+	int cipher;
+	int key_enc;
+	/*	char iv[8]; unused and wrong size */
+	} PEM_USER;
+
+typedef struct pem_ctx_st
+	{
+	int type;		/* what type of object */
+
+	struct	{
+		int version;	
+		int mode;		
+		} proc_type;
+
+	char *domain;
+
+	struct	{
+		int cipher;
+	/* unused, and wrong size
+	   unsigned char iv[8]; */
+		} DEK_info;
+		
+	PEM_USER *originator;
+
+	int num_recipient;
+	PEM_USER **recipient;
+
+	/* XXX(ben): don#t think this is used! 
+		STACK *x509_chain;	/ * certificate chain */
+	EVP_MD *md;		/* signature type */
+
+	int md_enc;		/* is the md encrypted or not? */
+	int md_len;		/* length of md_data */
+	char *md_data;		/* message digest, could be pkey encrypted */
+
+	EVP_CIPHER *dec;	/* date encryption cipher */
+	int key_len;		/* key length */
+	unsigned char *key;	/* key */
+	/* unused, and wrong size
+	   unsigned char iv[8]; */
+
+	
+	int  data_enc;		/* is the data encrypted */
+	int data_len;
+	unsigned char *data;
+	} PEM_CTX;
+
+/* These macros make the PEM_read/PEM_write functions easier to maintain and
+ * write. Now they are all implemented with either:
+ * IMPLEMENT_PEM_rw(...) or IMPLEMENT_PEM_rw_cb(...)
+ */
+
+#ifdef OPENSSL_NO_FP_API
+
+#define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/
+#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/
+#define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) /**/
+#define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/
+#define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) /**/
+
+#else
+
+#define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \
+type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\
+{ \
+return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \
+} 
+
+#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, type *x) \
+{ \
+return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \
+}
+
+#define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, const type *x) \
+{ \
+return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \
+}
+
+#define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, \
+		  void *u) \
+	{ \
+	return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
+	}
+
+#define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, \
+		  void *u) \
+	{ \
+	return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
+	}
+
+#endif
+
+#define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
+type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\
+{ \
+return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \
+}
+
+#define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, type *x) \
+{ \
+return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \
+}
+
+#define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, const type *x) \
+{ \
+return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \
+}
+
+#define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
+	{ \
+	return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \
+	}
+
+#define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
+	{ \
+	return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \
+	}
+
+#define IMPLEMENT_PEM_write(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_fp(name, type, str, asn1) 
+
+#define IMPLEMENT_PEM_write_const(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) 
+
+#define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) 
+
+#define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) 
+
+#define IMPLEMENT_PEM_read(name, type, str, asn1) \
+	IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
+	IMPLEMENT_PEM_read_fp(name, type, str, asn1) 
+
+#define IMPLEMENT_PEM_rw(name, type, str, asn1) \
+	IMPLEMENT_PEM_read(name, type, str, asn1) \
+	IMPLEMENT_PEM_write(name, type, str, asn1)
+
+#define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \
+	IMPLEMENT_PEM_read(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_const(name, type, str, asn1)
+
+#define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \
+	IMPLEMENT_PEM_read(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_cb(name, type, str, asn1)
+
+/* These are the same except they are for the declarations */
+
+#if defined(OPENSSL_NO_FP_API)
+
+#define DECLARE_PEM_read_fp(name, type) /**/
+#define DECLARE_PEM_write_fp(name, type) /**/
+#define DECLARE_PEM_write_cb_fp(name, type) /**/
+
+#else
+
+#define DECLARE_PEM_read_fp(name, type) \
+	type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u);
+
+#define DECLARE_PEM_write_fp(name, type) \
+	int PEM_write_##name(FILE *fp, type *x);
+
+#define DECLARE_PEM_write_fp_const(name, type) \
+	int PEM_write_##name(FILE *fp, const type *x);
+
+#define DECLARE_PEM_write_cb_fp(name, type) \
+	int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
+
+#endif
+
+#ifndef OPENSSL_NO_BIO
+#define DECLARE_PEM_read_bio(name, type) \
+	type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u);
+
+#define DECLARE_PEM_write_bio(name, type) \
+	int PEM_write_bio_##name(BIO *bp, type *x);
+
+#define DECLARE_PEM_write_bio_const(name, type) \
+	int PEM_write_bio_##name(BIO *bp, const type *x);
+
+#define DECLARE_PEM_write_cb_bio(name, type) \
+	int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
+
+#else
+
+#define DECLARE_PEM_read_bio(name, type) /**/
+#define DECLARE_PEM_write_bio(name, type) /**/
+#define DECLARE_PEM_write_bio_const(name, type) /**/
+#define DECLARE_PEM_write_cb_bio(name, type) /**/
+
+#endif
+
+#define DECLARE_PEM_write(name, type) \
+	DECLARE_PEM_write_bio(name, type) \
+	DECLARE_PEM_write_fp(name, type) 
+
+#define DECLARE_PEM_write_const(name, type) \
+	DECLARE_PEM_write_bio_const(name, type) \
+	DECLARE_PEM_write_fp_const(name, type)
+
+#define DECLARE_PEM_write_cb(name, type) \
+	DECLARE_PEM_write_cb_bio(name, type) \
+	DECLARE_PEM_write_cb_fp(name, type) 
+
+#define DECLARE_PEM_read(name, type) \
+	DECLARE_PEM_read_bio(name, type) \
+	DECLARE_PEM_read_fp(name, type)
+
+#define DECLARE_PEM_rw(name, type) \
+	DECLARE_PEM_read(name, type) \
+	DECLARE_PEM_write(name, type)
+
+#define DECLARE_PEM_rw_const(name, type) \
+	DECLARE_PEM_read(name, type) \
+	DECLARE_PEM_write_const(name, type)
+
+#define DECLARE_PEM_rw_cb(name, type) \
+	DECLARE_PEM_read(name, type) \
+	DECLARE_PEM_write_cb(name, type)
+
+#if 1
+/* "userdata": new with OpenSSL 0.9.4 */
+typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata);
+#else
+/* OpenSSL 0.9.3, 0.9.3a */
+typedef int pem_password_cb(char *buf, int size, int rwflag);
+#endif
+
+int	PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher);
+int	PEM_do_header (EVP_CIPHER_INFO *cipher, unsigned char *data,long *len,
+	pem_password_cb *callback,void *u);
+
+#ifndef OPENSSL_NO_BIO
+int	PEM_read_bio(BIO *bp, char **name, char **header,
+		unsigned char **data,long *len);
+int	PEM_write_bio(BIO *bp,const char *name,char *hdr,unsigned char *data,
+		long len);
+int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp,
+	     pem_password_cb *cb, void *u);
+void *	PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp,
+			  void **x, pem_password_cb *cb, void *u);
+int	PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp, void *x,
+			   const EVP_CIPHER *enc,unsigned char *kstr,int klen,
+			   pem_password_cb *cb, void *u);
+
+STACK_OF(X509_INFO) *	PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u);
+int	PEM_X509_INFO_write_bio(BIO *bp,X509_INFO *xi, EVP_CIPHER *enc,
+		unsigned char *kstr, int klen, pem_password_cb *cd, void *u);
+#endif
+
+int	PEM_read(FILE *fp, char **name, char **header,
+		unsigned char **data,long *len);
+int	PEM_write(FILE *fp,char *name,char *hdr,unsigned char *data,long len);
+void *  PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
+		      pem_password_cb *cb, void *u);
+int	PEM_ASN1_write(i2d_of_void *i2d,const char *name,FILE *fp,
+		       void *x,const EVP_CIPHER *enc,unsigned char *kstr,
+		       int klen,pem_password_cb *callback, void *u);
+STACK_OF(X509_INFO) *	PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
+	pem_password_cb *cb, void *u);
+
+int	PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type,
+		EVP_MD *md_type, unsigned char **ek, int *ekl,
+		unsigned char *iv, EVP_PKEY **pubk, int npubk);
+void	PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl,
+		unsigned char *in, int inl);
+int	PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig,int *sigl,
+		unsigned char *out, int *outl, EVP_PKEY *priv);
+
+void    PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type);
+void    PEM_SignUpdate(EVP_MD_CTX *ctx,unsigned char *d,unsigned int cnt);
+int	PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
+		unsigned int *siglen, EVP_PKEY *pkey);
+
+int	PEM_def_callback(char *buf, int num, int w, void *key);
+void	PEM_proc_type(char *buf, int type);
+void	PEM_dek_info(char *buf, const char *type, int len, char *str);
+
+
+#include <openssl/symhacks.h>
+
+DECLARE_PEM_rw(X509, X509)
+
+DECLARE_PEM_rw(X509_AUX, X509)
+
+DECLARE_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR)
+
+DECLARE_PEM_rw(X509_REQ, X509_REQ)
+DECLARE_PEM_write(X509_REQ_NEW, X509_REQ)
+
+DECLARE_PEM_rw(X509_CRL, X509_CRL)
+
+DECLARE_PEM_rw(PKCS7, PKCS7)
+
+DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE)
+
+DECLARE_PEM_rw(PKCS8, X509_SIG)
+
+DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
+
+#ifndef OPENSSL_NO_RSA
+
+DECLARE_PEM_rw_cb(RSAPrivateKey, RSA)
+
+DECLARE_PEM_rw_const(RSAPublicKey, RSA)
+DECLARE_PEM_rw(RSA_PUBKEY, RSA)
+
+#endif
+
+#ifndef OPENSSL_NO_DSA
+
+DECLARE_PEM_rw_cb(DSAPrivateKey, DSA)
+
+DECLARE_PEM_rw(DSA_PUBKEY, DSA)
+
+DECLARE_PEM_rw_const(DSAparams, DSA)
+
+#endif
+
+#ifndef OPENSSL_NO_EC
+DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP)
+DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY)
+DECLARE_PEM_rw(EC_PUBKEY, EC_KEY)
+#endif
+
+#ifndef OPENSSL_NO_DH
+
+DECLARE_PEM_rw_const(DHparams, DH)
+
+#endif
+
+DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY)
+
+DECLARE_PEM_rw(PUBKEY, EVP_PKEY)
+
+int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
+                                  char *, int, pem_password_cb *, void *);
+int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u);
+
+int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+
+EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u);
+
+int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc,
+			      char *kstr,int klen, pem_password_cb *cd, void *u);
+
+EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x);
+int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x);
+
+
+EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length);
+EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length);
+EVP_PKEY *b2i_PrivateKey_bio(BIO *in);
+EVP_PKEY *b2i_PublicKey_bio(BIO *in);
+int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk);
+int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk);
+#ifndef OPENSSL_NO_RC4
+EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u);
+int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
+		pem_password_cb *cb, void *u);
+#endif
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_PEM_strings(void);
+
+/* Error codes for the PEM functions. */
+
+/* Function codes. */
+#define PEM_F_B2I_DSS					 127
+#define PEM_F_B2I_PVK_BIO				 128
+#define PEM_F_B2I_RSA					 129
+#define PEM_F_CHECK_BITLEN_DSA				 130
+#define PEM_F_CHECK_BITLEN_RSA				 131
+#define PEM_F_D2I_PKCS8PRIVATEKEY_BIO			 120
+#define PEM_F_D2I_PKCS8PRIVATEKEY_FP			 121
+#define PEM_F_DO_B2I					 132
+#define PEM_F_DO_B2I_BIO				 133
+#define PEM_F_DO_BLOB_HEADER				 134
+#define PEM_F_DO_PK8PKEY				 126
+#define PEM_F_DO_PK8PKEY_FP				 125
+#define PEM_F_DO_PVK_BODY				 135
+#define PEM_F_DO_PVK_HEADER				 136
+#define PEM_F_I2B_PVK					 137
+#define PEM_F_I2B_PVK_BIO				 138
+#define PEM_F_LOAD_IV					 101
+#define PEM_F_PEM_ASN1_READ				 102
+#define PEM_F_PEM_ASN1_READ_BIO				 103
+#define PEM_F_PEM_ASN1_WRITE				 104
+#define PEM_F_PEM_ASN1_WRITE_BIO			 105
+#define PEM_F_PEM_DEF_CALLBACK				 100
+#define PEM_F_PEM_DO_HEADER				 106
+#define PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY		 118
+#define PEM_F_PEM_GET_EVP_CIPHER_INFO			 107
+#define PEM_F_PEM_PK8PKEY				 119
+#define PEM_F_PEM_READ					 108
+#define PEM_F_PEM_READ_BIO				 109
+#define PEM_F_PEM_READ_BIO_PARAMETERS			 140
+#define PEM_F_PEM_READ_BIO_PRIVATEKEY			 123
+#define PEM_F_PEM_READ_PRIVATEKEY			 124
+#define PEM_F_PEM_SEALFINAL				 110
+#define PEM_F_PEM_SEALINIT				 111
+#define PEM_F_PEM_SIGNFINAL				 112
+#define PEM_F_PEM_WRITE					 113
+#define PEM_F_PEM_WRITE_BIO				 114
+#define PEM_F_PEM_WRITE_PRIVATEKEY			 139
+#define PEM_F_PEM_X509_INFO_READ			 115
+#define PEM_F_PEM_X509_INFO_READ_BIO			 116
+#define PEM_F_PEM_X509_INFO_WRITE_BIO			 117
+
+/* Reason codes. */
+#define PEM_R_BAD_BASE64_DECODE				 100
+#define PEM_R_BAD_DECRYPT				 101
+#define PEM_R_BAD_END_LINE				 102
+#define PEM_R_BAD_IV_CHARS				 103
+#define PEM_R_BAD_MAGIC_NUMBER				 116
+#define PEM_R_BAD_PASSWORD_READ				 104
+#define PEM_R_BAD_VERSION_NUMBER			 117
+#define PEM_R_BIO_WRITE_FAILURE				 118
+#define PEM_R_CIPHER_IS_NULL				 127
+#define PEM_R_ERROR_CONVERTING_PRIVATE_KEY		 115
+#define PEM_R_EXPECTING_PRIVATE_KEY_BLOB		 119
+#define PEM_R_EXPECTING_PUBLIC_KEY_BLOB			 120
+#define PEM_R_INCONSISTENT_HEADER			 121
+#define PEM_R_KEYBLOB_HEADER_PARSE_ERROR		 122
+#define PEM_R_KEYBLOB_TOO_SHORT				 123
+#define PEM_R_NOT_DEK_INFO				 105
+#define PEM_R_NOT_ENCRYPTED				 106
+#define PEM_R_NOT_PROC_TYPE				 107
+#define PEM_R_NO_START_LINE				 108
+#define PEM_R_PROBLEMS_GETTING_PASSWORD			 109
+#define PEM_R_PUBLIC_KEY_NO_RSA				 110
+#define PEM_R_PVK_DATA_TOO_SHORT			 124
+#define PEM_R_PVK_TOO_SHORT				 125
+#define PEM_R_READ_KEY					 111
+#define PEM_R_SHORT_HEADER				 112
+#define PEM_R_UNSUPPORTED_CIPHER			 113
+#define PEM_R_UNSUPPORTED_ENCRYPTION			 114
+#define PEM_R_UNSUPPORTED_KEY_COMPONENTS		 126
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/pem/pem2.h b/openssl/crypto/pem/pem2.h
new file mode 100644
index 0000000..f31790d
--- /dev/null
+++ b/openssl/crypto/pem/pem2.h
@@ -0,0 +1,70 @@
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+ * This header only exists to break a circular dependency between pem and err
+ * Ben 30 Jan 1999.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef HEADER_PEM_H
+void ERR_load_PEM_strings(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/openssl/crypto/pem/pem_all.c b/openssl/crypto/pem/pem_all.c
new file mode 100644
index 0000000..3e7a609
--- /dev/null
+++ b/openssl/crypto/pem/pem_all.c
@@ -0,0 +1,296 @@
+/* crypto/pem/pem_all.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pem.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+
+#ifndef OPENSSL_NO_RSA
+static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa);
+#endif
+#ifndef OPENSSL_NO_DSA
+static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa);
+#endif
+
+#ifndef OPENSSL_NO_EC
+static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey);
+#endif
+
+IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ)
+
+IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ)
+
+IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL)
+
+IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7)
+
+IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE,
+					PEM_STRING_X509, NETSCAPE_CERT_SEQUENCE)
+
+
+#ifndef OPENSSL_NO_RSA
+
+/* We treat RSA or DSA private keys as a special case.
+ *
+ * For private keys we read in an EVP_PKEY structure with
+ * PEM_read_bio_PrivateKey() and extract the relevant private
+ * key: this means can handle "traditional" and PKCS#8 formats
+ * transparently.
+ */
+
+static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa)
+{
+	RSA *rtmp;
+	if(!key) return NULL;
+	rtmp = EVP_PKEY_get1_RSA(key);
+	EVP_PKEY_free(key);
+	if(!rtmp) return NULL;
+	if(rsa) {
+		RSA_free(*rsa);
+		*rsa = rtmp;
+	}
+	return rtmp;
+}
+
+RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb,
+								void *u)
+{
+	EVP_PKEY *pktmp;
+	pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+	return pkey_get_rsa(pktmp, rsa);
+}
+
+#ifndef OPENSSL_NO_FP_API
+
+RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb,
+								void *u)
+{
+	EVP_PKEY *pktmp;
+	pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+	return pkey_get_rsa(pktmp, rsa);
+}
+
+#endif
+
+IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey)
+IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey)
+IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY)
+
+#endif
+
+#ifndef OPENSSL_NO_DSA
+
+static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa)
+{
+	DSA *dtmp;
+	if(!key) return NULL;
+	dtmp = EVP_PKEY_get1_DSA(key);
+	EVP_PKEY_free(key);
+	if(!dtmp) return NULL;
+	if(dsa) {
+		DSA_free(*dsa);
+		*dsa = dtmp;
+	}
+	return dtmp;
+}
+
+DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb,
+								void *u)
+{
+	EVP_PKEY *pktmp;
+	pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+	return pkey_get_dsa(pktmp, dsa);	/* will free pktmp */
+}
+
+IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey)
+IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
+
+#ifndef OPENSSL_NO_FP_API
+
+DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb,
+								void *u)
+{
+	EVP_PKEY *pktmp;
+	pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+	return pkey_get_dsa(pktmp, dsa);	/* will free pktmp */
+}
+
+#endif
+
+IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams)
+
+#endif
+
+
+#ifndef OPENSSL_NO_EC
+static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey)
+{
+	EC_KEY *dtmp;
+	if(!key) return NULL;
+	dtmp = EVP_PKEY_get1_EC_KEY(key);
+	EVP_PKEY_free(key);
+	if(!dtmp) return NULL;
+	if(eckey) 
+	{
+ 		EC_KEY_free(*eckey);
+		*eckey = dtmp;
+	}
+	return dtmp;
+}
+
+EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
+							void *u)
+{
+	EVP_PKEY *pktmp;
+	pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+	return pkey_get_eckey(pktmp, key);	/* will free pktmp */
+}
+
+IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, ECPKParameters)
+
+IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey)
+
+IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
+
+#ifndef OPENSSL_NO_FP_API
+ 
+EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb,
+ 								void *u)
+{
+	EVP_PKEY *pktmp;
+	pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+	return pkey_get_eckey(pktmp, eckey);	/* will free pktmp */
+}
+
+#endif
+
+#endif
+
+#ifndef OPENSSL_NO_DH
+
+IMPLEMENT_PEM_rw_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
+
+#endif
+
+IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
diff --git a/openssl/crypto/pem/pem_err.c b/openssl/crypto/pem/pem_err.c
new file mode 100644
index 0000000..d644aee
--- /dev/null
+++ b/openssl/crypto/pem/pem_err.c
@@ -0,0 +1,161 @@
+/* crypto/pem/pem_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_PEM,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_PEM,0,reason)
+
+static ERR_STRING_DATA PEM_str_functs[]=
+	{
+{ERR_FUNC(PEM_F_B2I_DSS),	"B2I_DSS"},
+{ERR_FUNC(PEM_F_B2I_PVK_BIO),	"b2i_PVK_bio"},
+{ERR_FUNC(PEM_F_B2I_RSA),	"B2I_RSA"},
+{ERR_FUNC(PEM_F_CHECK_BITLEN_DSA),	"CHECK_BITLEN_DSA"},
+{ERR_FUNC(PEM_F_CHECK_BITLEN_RSA),	"CHECK_BITLEN_RSA"},
+{ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_BIO),	"d2i_PKCS8PrivateKey_bio"},
+{ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_FP),	"d2i_PKCS8PrivateKey_fp"},
+{ERR_FUNC(PEM_F_DO_B2I),	"DO_B2I"},
+{ERR_FUNC(PEM_F_DO_B2I_BIO),	"DO_B2I_BIO"},
+{ERR_FUNC(PEM_F_DO_BLOB_HEADER),	"DO_BLOB_HEADER"},
+{ERR_FUNC(PEM_F_DO_PK8PKEY),	"DO_PK8PKEY"},
+{ERR_FUNC(PEM_F_DO_PK8PKEY_FP),	"DO_PK8PKEY_FP"},
+{ERR_FUNC(PEM_F_DO_PVK_BODY),	"DO_PVK_BODY"},
+{ERR_FUNC(PEM_F_DO_PVK_HEADER),	"DO_PVK_HEADER"},
+{ERR_FUNC(PEM_F_I2B_PVK),	"I2B_PVK"},
+{ERR_FUNC(PEM_F_I2B_PVK_BIO),	"i2b_PVK_bio"},
+{ERR_FUNC(PEM_F_LOAD_IV),	"LOAD_IV"},
+{ERR_FUNC(PEM_F_PEM_ASN1_READ),	"PEM_ASN1_read"},
+{ERR_FUNC(PEM_F_PEM_ASN1_READ_BIO),	"PEM_ASN1_read_bio"},
+{ERR_FUNC(PEM_F_PEM_ASN1_WRITE),	"PEM_ASN1_write"},
+{ERR_FUNC(PEM_F_PEM_ASN1_WRITE_BIO),	"PEM_ASN1_write_bio"},
+{ERR_FUNC(PEM_F_PEM_DEF_CALLBACK),	"PEM_def_callback"},
+{ERR_FUNC(PEM_F_PEM_DO_HEADER),	"PEM_do_header"},
+{ERR_FUNC(PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY),	"PEM_F_PEM_WRITE_PKCS8PRIVATEKEY"},
+{ERR_FUNC(PEM_F_PEM_GET_EVP_CIPHER_INFO),	"PEM_get_EVP_CIPHER_INFO"},
+{ERR_FUNC(PEM_F_PEM_PK8PKEY),	"PEM_PK8PKEY"},
+{ERR_FUNC(PEM_F_PEM_READ),	"PEM_read"},
+{ERR_FUNC(PEM_F_PEM_READ_BIO),	"PEM_read_bio"},
+{ERR_FUNC(PEM_F_PEM_READ_BIO_PARAMETERS),	"PEM_read_bio_Parameters"},
+{ERR_FUNC(PEM_F_PEM_READ_BIO_PRIVATEKEY),	"PEM_READ_BIO_PRIVATEKEY"},
+{ERR_FUNC(PEM_F_PEM_READ_PRIVATEKEY),	"PEM_READ_PRIVATEKEY"},
+{ERR_FUNC(PEM_F_PEM_SEALFINAL),	"PEM_SealFinal"},
+{ERR_FUNC(PEM_F_PEM_SEALINIT),	"PEM_SealInit"},
+{ERR_FUNC(PEM_F_PEM_SIGNFINAL),	"PEM_SignFinal"},
+{ERR_FUNC(PEM_F_PEM_WRITE),	"PEM_write"},
+{ERR_FUNC(PEM_F_PEM_WRITE_BIO),	"PEM_write_bio"},
+{ERR_FUNC(PEM_F_PEM_WRITE_PRIVATEKEY),	"PEM_WRITE_PRIVATEKEY"},
+{ERR_FUNC(PEM_F_PEM_X509_INFO_READ),	"PEM_X509_INFO_read"},
+{ERR_FUNC(PEM_F_PEM_X509_INFO_READ_BIO),	"PEM_X509_INFO_read_bio"},
+{ERR_FUNC(PEM_F_PEM_X509_INFO_WRITE_BIO),	"PEM_X509_INFO_write_bio"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA PEM_str_reasons[]=
+	{
+{ERR_REASON(PEM_R_BAD_BASE64_DECODE)     ,"bad base64 decode"},
+{ERR_REASON(PEM_R_BAD_DECRYPT)           ,"bad decrypt"},
+{ERR_REASON(PEM_R_BAD_END_LINE)          ,"bad end line"},
+{ERR_REASON(PEM_R_BAD_IV_CHARS)          ,"bad iv chars"},
+{ERR_REASON(PEM_R_BAD_MAGIC_NUMBER)      ,"bad magic number"},
+{ERR_REASON(PEM_R_BAD_PASSWORD_READ)     ,"bad password read"},
+{ERR_REASON(PEM_R_BAD_VERSION_NUMBER)    ,"bad version number"},
+{ERR_REASON(PEM_R_BIO_WRITE_FAILURE)     ,"bio write failure"},
+{ERR_REASON(PEM_R_CIPHER_IS_NULL)        ,"cipher is null"},
+{ERR_REASON(PEM_R_ERROR_CONVERTING_PRIVATE_KEY),"error converting private key"},
+{ERR_REASON(PEM_R_EXPECTING_PRIVATE_KEY_BLOB),"expecting private key blob"},
+{ERR_REASON(PEM_R_EXPECTING_PUBLIC_KEY_BLOB),"expecting public key blob"},
+{ERR_REASON(PEM_R_INCONSISTENT_HEADER)   ,"inconsistent header"},
+{ERR_REASON(PEM_R_KEYBLOB_HEADER_PARSE_ERROR),"keyblob header parse error"},
+{ERR_REASON(PEM_R_KEYBLOB_TOO_SHORT)     ,"keyblob too short"},
+{ERR_REASON(PEM_R_NOT_DEK_INFO)          ,"not dek info"},
+{ERR_REASON(PEM_R_NOT_ENCRYPTED)         ,"not encrypted"},
+{ERR_REASON(PEM_R_NOT_PROC_TYPE)         ,"not proc type"},
+{ERR_REASON(PEM_R_NO_START_LINE)         ,"no start line"},
+{ERR_REASON(PEM_R_PROBLEMS_GETTING_PASSWORD),"problems getting password"},
+{ERR_REASON(PEM_R_PUBLIC_KEY_NO_RSA)     ,"public key no rsa"},
+{ERR_REASON(PEM_R_PVK_DATA_TOO_SHORT)    ,"pvk data too short"},
+{ERR_REASON(PEM_R_PVK_TOO_SHORT)         ,"pvk too short"},
+{ERR_REASON(PEM_R_READ_KEY)              ,"read key"},
+{ERR_REASON(PEM_R_SHORT_HEADER)          ,"short header"},
+{ERR_REASON(PEM_R_UNSUPPORTED_CIPHER)    ,"unsupported cipher"},
+{ERR_REASON(PEM_R_UNSUPPORTED_ENCRYPTION),"unsupported encryption"},
+{ERR_REASON(PEM_R_UNSUPPORTED_KEY_COMPONENTS),"unsupported key components"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_PEM_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(PEM_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,PEM_str_functs);
+		ERR_load_strings(0,PEM_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/pem/pem_info.c b/openssl/crypto/pem/pem_info.c
new file mode 100644
index 0000000..1b2be52
--- /dev/null
+++ b/openssl/crypto/pem/pem_info.c
@@ -0,0 +1,405 @@
+/* crypto/pem/pem_info.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+
+#ifndef OPENSSL_NO_FP_API
+STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u)
+	{
+        BIO *b;
+        STACK_OF(X509_INFO) *ret;
+
+        if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		PEMerr(PEM_F_PEM_X509_INFO_READ,ERR_R_BUF_LIB);
+                return(0);
+		}
+        BIO_set_fp(b,fp,BIO_NOCLOSE);
+        ret=PEM_X509_INFO_read_bio(b,sk,cb,u);
+        BIO_free(b);
+        return(ret);
+	}
+#endif
+
+STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u)
+	{
+	X509_INFO *xi=NULL;
+	char *name=NULL,*header=NULL;
+	void *pp;
+	unsigned char *data=NULL;
+	const unsigned char *p;
+	long len,error=0;
+	int ok=0;
+	STACK_OF(X509_INFO) *ret=NULL;
+	unsigned int i,raw,ptype;
+	d2i_of_void *d2i = 0;
+
+	if (sk == NULL)
+		{
+		if ((ret=sk_X509_INFO_new_null()) == NULL)
+			{
+			PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+	else
+		ret=sk;
+
+	if ((xi=X509_INFO_new()) == NULL) goto err;
+	for (;;)
+		{
+		raw=0;
+		ptype = 0;
+		i=PEM_read_bio(bp,&name,&header,&data,&len);
+		if (i == 0)
+			{
+			error=ERR_GET_REASON(ERR_peek_last_error());
+			if (error == PEM_R_NO_START_LINE)
+				{
+				ERR_clear_error();
+				break;
+				}
+			goto err;
+			}
+start:
+		if (	(strcmp(name,PEM_STRING_X509) == 0) ||
+			(strcmp(name,PEM_STRING_X509_OLD) == 0))
+			{
+			d2i=(D2I_OF(void))d2i_X509;
+			if (xi->x509 != NULL)
+				{
+				if (!sk_X509_INFO_push(ret,xi)) goto err;
+				if ((xi=X509_INFO_new()) == NULL) goto err;
+				goto start;
+				}
+			pp=&(xi->x509);
+			}
+		else if ((strcmp(name,PEM_STRING_X509_TRUSTED) == 0))
+			{
+			d2i=(D2I_OF(void))d2i_X509_AUX;
+			if (xi->x509 != NULL)
+				{
+				if (!sk_X509_INFO_push(ret,xi)) goto err;
+				if ((xi=X509_INFO_new()) == NULL) goto err;
+				goto start;
+				}
+			pp=&(xi->x509);
+			}
+		else if (strcmp(name,PEM_STRING_X509_CRL) == 0)
+			{
+			d2i=(D2I_OF(void))d2i_X509_CRL;
+			if (xi->crl != NULL)
+				{
+				if (!sk_X509_INFO_push(ret,xi)) goto err;
+				if ((xi=X509_INFO_new()) == NULL) goto err;
+				goto start;
+				}
+			pp=&(xi->crl);
+			}
+		else
+#ifndef OPENSSL_NO_RSA
+			if (strcmp(name,PEM_STRING_RSA) == 0)
+			{
+			if (xi->x_pkey != NULL) 
+				{
+				if (!sk_X509_INFO_push(ret,xi)) goto err;
+				if ((xi=X509_INFO_new()) == NULL) goto err;
+				goto start;
+				}
+
+			xi->enc_data=NULL;
+			xi->enc_len=0;
+
+			xi->x_pkey=X509_PKEY_new();
+			ptype=EVP_PKEY_RSA;
+			pp=&xi->x_pkey->dec_pkey;
+			if ((int)strlen(header) > 10) /* assume encrypted */
+				raw=1;
+			}
+		else
+#endif
+#ifndef OPENSSL_NO_DSA
+			if (strcmp(name,PEM_STRING_DSA) == 0)
+			{
+			d2i=(D2I_OF(void))d2i_DSAPrivateKey;
+			if (xi->x_pkey != NULL) 
+				{
+				if (!sk_X509_INFO_push(ret,xi)) goto err;
+				if ((xi=X509_INFO_new()) == NULL) goto err;
+				goto start;
+				}
+
+			xi->enc_data=NULL;
+			xi->enc_len=0;
+
+			xi->x_pkey=X509_PKEY_new();
+			ptype = EVP_PKEY_DSA;
+			pp=&xi->x_pkey->dec_pkey;
+			if ((int)strlen(header) > 10) /* assume encrypted */
+				raw=1;
+			}
+		else
+#endif
+#ifndef OPENSSL_NO_EC
+ 			if (strcmp(name,PEM_STRING_ECPRIVATEKEY) == 0)
+ 			{
+ 				d2i=(D2I_OF(void))d2i_ECPrivateKey;
+ 				if (xi->x_pkey != NULL) 
+ 				{
+ 					if (!sk_X509_INFO_push(ret,xi)) goto err;
+ 					if ((xi=X509_INFO_new()) == NULL) goto err;
+ 						goto start;
+ 				}
+ 
+ 			xi->enc_data=NULL;
+ 			xi->enc_len=0;
+ 
+ 			xi->x_pkey=X509_PKEY_new();
+			ptype = EVP_PKEY_EC;
+ 			pp=&xi->x_pkey->dec_pkey;
+ 			if ((int)strlen(header) > 10) /* assume encrypted */
+ 				raw=1;
+			}
+		else
+#endif
+			{
+			d2i=NULL;
+			pp=NULL;
+			}
+
+		if (d2i != NULL)
+			{
+			if (!raw)
+				{
+				EVP_CIPHER_INFO cipher;
+
+				if (!PEM_get_EVP_CIPHER_INFO(header,&cipher))
+					goto err;
+				if (!PEM_do_header(&cipher,data,&len,cb,u))
+					goto err;
+				p=data;
+				if (ptype)
+					{
+					if (!d2i_PrivateKey(ptype, pp, &p, len))
+						{
+						PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_ASN1_LIB);
+						goto err;
+						}
+					}
+				else if (d2i(pp,&p,len) == NULL)
+					{
+					PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_ASN1_LIB);
+					goto err;
+					}
+				}
+			else
+				{ /* encrypted RSA data */
+				if (!PEM_get_EVP_CIPHER_INFO(header,
+					&xi->enc_cipher)) goto err;
+				xi->enc_data=(char *)data;
+				xi->enc_len=(int)len;
+				data=NULL;
+				}
+			}
+		else	{
+			/* unknown */
+			}
+		if (name != NULL) OPENSSL_free(name);
+		if (header != NULL) OPENSSL_free(header);
+		if (data != NULL) OPENSSL_free(data);
+		name=NULL;
+		header=NULL;
+		data=NULL;
+		}
+
+	/* if the last one hasn't been pushed yet and there is anything
+	 * in it then add it to the stack ... 
+	 */
+	if ((xi->x509 != NULL) || (xi->crl != NULL) ||
+		(xi->x_pkey != NULL) || (xi->enc_data != NULL))
+		{
+		if (!sk_X509_INFO_push(ret,xi)) goto err;
+		xi=NULL;
+		}
+	ok=1;
+err:
+	if (xi != NULL) X509_INFO_free(xi);
+	if (!ok)
+		{
+		for (i=0; ((int)i)<sk_X509_INFO_num(ret); i++)
+			{
+			xi=sk_X509_INFO_value(ret,i);
+			X509_INFO_free(xi);
+			}
+		if (ret != sk) sk_X509_INFO_free(ret);
+		ret=NULL;
+		}
+		
+	if (name != NULL) OPENSSL_free(name);
+	if (header != NULL) OPENSSL_free(header);
+	if (data != NULL) OPENSSL_free(data);
+	return(ret);
+	}
+
+
+/* A TJH addition */
+int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
+	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u)
+	{
+	EVP_CIPHER_CTX ctx;
+	int i,ret=0;
+	unsigned char *data=NULL;
+	const char *objstr=NULL;
+	char buf[PEM_BUFSIZE];
+	unsigned char *iv=NULL;
+	
+	if (enc != NULL)
+		{
+		objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
+		if (objstr == NULL)
+			{
+			PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER);
+			goto err;
+			}
+		}
+
+	/* now for the fun part ... if we have a private key then 
+	 * we have to be able to handle a not-yet-decrypted key
+	 * being written out correctly ... if it is decrypted or
+	 * it is non-encrypted then we use the base code
+	 */
+	if (xi->x_pkey!=NULL)
+		{
+		if ( (xi->enc_data!=NULL) && (xi->enc_len>0) )
+			{
+			if (enc == NULL)
+				{
+				PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,PEM_R_CIPHER_IS_NULL);
+				goto err;
+				}
+
+			/* copy from weirdo names into more normal things */
+			iv=xi->enc_cipher.iv;
+			data=(unsigned char *)xi->enc_data;
+			i=xi->enc_len;
+
+			/* we take the encryption data from the
+			 * internal stuff rather than what the
+			 * user has passed us ... as we have to 
+			 * match exactly for some strange reason
+			 */
+			objstr=OBJ_nid2sn(
+				EVP_CIPHER_nid(xi->enc_cipher.cipher));
+			if (objstr == NULL)
+				{
+				PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER);
+				goto err;
+				}
+
+			/* create the right magic header stuff */
+			OPENSSL_assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf);
+			buf[0]='\0';
+			PEM_proc_type(buf,PEM_TYPE_ENCRYPTED);
+			PEM_dek_info(buf,objstr,enc->iv_len,(char *)iv);
+
+			/* use the normal code to write things out */
+			i=PEM_write_bio(bp,PEM_STRING_RSA,buf,data,i);
+			if (i <= 0) goto err;
+			}
+		else
+			{
+			/* Add DSA/DH */
+#ifndef OPENSSL_NO_RSA
+			/* normal optionally encrypted stuff */
+			if (PEM_write_bio_RSAPrivateKey(bp,
+				xi->x_pkey->dec_pkey->pkey.rsa,
+				enc,kstr,klen,cb,u)<=0)
+				goto err;
+#endif
+			}
+		}
+
+	/* if we have a certificate then write it out now */
+	if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp,xi->x509) <= 0))
+		goto err;
+
+	/* we are ignoring anything else that is loaded into the X509_INFO
+	 * structure for the moment ... as I don't need it so I'm not
+	 * coding it here and Eric can do it when this makes it into the
+	 * base library --tjh
+	 */
+
+	ret=1;
+
+err:
+	OPENSSL_cleanse((char *)&ctx,sizeof(ctx));
+	OPENSSL_cleanse(buf,PEM_BUFSIZE);
+	return(ret);
+	}
diff --git a/openssl/crypto/pem/pem_lib.c b/openssl/crypto/pem/pem_lib.c
new file mode 100644
index 0000000..cfc89a9
--- /dev/null
+++ b/openssl/crypto/pem/pem_lib.c
@@ -0,0 +1,852 @@
+/* crypto/pem/pem_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/pkcs12.h>
+#include "asn1_locl.h"
+#ifndef OPENSSL_NO_DES
+#include <openssl/des.h>
+#endif
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+const char PEM_version[]="PEM" OPENSSL_VERSION_PTEXT;
+
+#define MIN_LENGTH	4
+
+static int load_iv(char **fromp,unsigned char *to, int num);
+static int check_pem(const char *nm, const char *name);
+int pem_check_suffix(const char *pem_str, const char *suffix);
+
+int PEM_def_callback(char *buf, int num, int w, void *key)
+	{
+#ifdef OPENSSL_NO_FP_API
+	/* We should not ever call the default callback routine from
+	 * windows. */
+	PEMerr(PEM_F_PEM_DEF_CALLBACK,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+	return(-1);
+#else
+	int i,j;
+	const char *prompt;
+	if(key) {
+		i=strlen(key);
+		i=(i > num)?num:i;
+		memcpy(buf,key,i);
+		return(i);
+	}
+
+	prompt=EVP_get_pw_prompt();
+	if (prompt == NULL)
+		prompt="Enter PEM pass phrase:";
+
+	for (;;)
+		{
+		i=EVP_read_pw_string_min(buf,MIN_LENGTH,num,prompt,w);
+		if (i != 0)
+			{
+			PEMerr(PEM_F_PEM_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD);
+			memset(buf,0,(unsigned int)num);
+			return(-1);
+			}
+		j=strlen(buf);
+		if (j < MIN_LENGTH)
+			{
+			fprintf(stderr,"phrase is too short, needs to be at least %d chars\n",MIN_LENGTH);
+			}
+		else
+			break;
+		}
+	return(j);
+#endif
+	}
+
+void PEM_proc_type(char *buf, int type)
+	{
+	const char *str;
+
+	if (type == PEM_TYPE_ENCRYPTED)
+		str="ENCRYPTED";
+	else if (type == PEM_TYPE_MIC_CLEAR)
+		str="MIC-CLEAR";
+	else if (type == PEM_TYPE_MIC_ONLY)
+		str="MIC-ONLY";
+	else
+		str="BAD-TYPE";
+		
+	BUF_strlcat(buf,"Proc-Type: 4,",PEM_BUFSIZE);
+	BUF_strlcat(buf,str,PEM_BUFSIZE);
+	BUF_strlcat(buf,"\n",PEM_BUFSIZE);
+	}
+
+void PEM_dek_info(char *buf, const char *type, int len, char *str)
+	{
+	static const unsigned char map[17]="0123456789ABCDEF";
+	long i;
+	int j;
+
+	BUF_strlcat(buf,"DEK-Info: ",PEM_BUFSIZE);
+	BUF_strlcat(buf,type,PEM_BUFSIZE);
+	BUF_strlcat(buf,",",PEM_BUFSIZE);
+	j=strlen(buf);
+	if (j + (len * 2) + 1 > PEM_BUFSIZE)
+        	return;
+	for (i=0; i<len; i++)
+		{
+		buf[j+i*2]  =map[(str[i]>>4)&0x0f];
+		buf[j+i*2+1]=map[(str[i]   )&0x0f];
+		}
+	buf[j+i*2]='\n';
+	buf[j+i*2+1]='\0';
+	}
+
+#ifndef OPENSSL_NO_FP_API
+void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
+		    pem_password_cb *cb, void *u)
+	{
+        BIO *b;
+        void *ret;
+
+        if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		PEMerr(PEM_F_PEM_ASN1_READ,ERR_R_BUF_LIB);
+                return(0);
+		}
+        BIO_set_fp(b,fp,BIO_NOCLOSE);
+        ret=PEM_ASN1_read_bio(d2i,name,b,x,cb,u);
+        BIO_free(b);
+        return(ret);
+	}
+#endif
+
+static int check_pem(const char *nm, const char *name)
+{
+	/* Normal matching nm and name */
+	if (!strcmp(nm,name)) return 1;
+
+	/* Make PEM_STRING_EVP_PKEY match any private key */
+
+	if(!strcmp(name,PEM_STRING_EVP_PKEY))
+		{
+		int slen;
+		const EVP_PKEY_ASN1_METHOD *ameth;
+		if(!strcmp(nm,PEM_STRING_PKCS8))
+			return 1;
+		if(!strcmp(nm,PEM_STRING_PKCS8INF))
+			return 1;
+		slen = pem_check_suffix(nm, "PRIVATE KEY"); 
+		if (slen > 0)
+			{
+			/* NB: ENGINE implementations wont contain
+			 * a deprecated old private key decode function
+			 * so don't look for them.
+			 */
+			ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
+			if (ameth && ameth->old_priv_decode)
+				return 1;
+			}
+		return 0;
+		}
+
+	if(!strcmp(name,PEM_STRING_PARAMETERS))
+		{
+		int slen;
+		const EVP_PKEY_ASN1_METHOD *ameth;
+		slen = pem_check_suffix(nm, "PARAMETERS"); 
+		if (slen > 0)
+			{
+			ENGINE *e;
+			ameth = EVP_PKEY_asn1_find_str(&e, nm, slen);
+			if (ameth)
+				{
+				int r;
+				if (ameth->param_decode)
+					r = 1;
+				else
+					r = 0;
+#ifndef OPENSSL_NO_ENGINE
+				if (e)
+					ENGINE_finish(e);
+#endif
+				return r;
+				}
+			}
+		return 0;
+		}
+
+	/* Permit older strings */
+
+	if(!strcmp(nm,PEM_STRING_X509_OLD) &&
+		!strcmp(name,PEM_STRING_X509)) return 1;
+
+	if(!strcmp(nm,PEM_STRING_X509_REQ_OLD) &&
+		!strcmp(name,PEM_STRING_X509_REQ)) return 1;
+
+	/* Allow normal certs to be read as trusted certs */
+	if(!strcmp(nm,PEM_STRING_X509) &&
+		!strcmp(name,PEM_STRING_X509_TRUSTED)) return 1;
+
+	if(!strcmp(nm,PEM_STRING_X509_OLD) &&
+		!strcmp(name,PEM_STRING_X509_TRUSTED)) return 1;
+
+	/* Some CAs use PKCS#7 with CERTIFICATE headers */
+	if(!strcmp(nm, PEM_STRING_X509) &&
+		!strcmp(name, PEM_STRING_PKCS7)) return 1;
+
+	if(!strcmp(nm, PEM_STRING_PKCS7_SIGNED) &&
+		!strcmp(name, PEM_STRING_PKCS7)) return 1;
+
+#ifndef OPENSSL_NO_CMS
+	if(!strcmp(nm, PEM_STRING_X509) &&
+		!strcmp(name, PEM_STRING_CMS)) return 1;
+	/* Allow CMS to be read from PKCS#7 headers */
+	if(!strcmp(nm, PEM_STRING_PKCS7) &&
+		!strcmp(name, PEM_STRING_CMS)) return 1;
+#endif
+
+	return 0;
+}
+
+int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp,
+	     pem_password_cb *cb, void *u)
+	{
+	EVP_CIPHER_INFO cipher;
+	char *nm=NULL,*header=NULL;
+	unsigned char *data=NULL;
+	long len;
+	int ret = 0;
+
+	for (;;)
+		{
+		if (!PEM_read_bio(bp,&nm,&header,&data,&len)) {
+			if(ERR_GET_REASON(ERR_peek_error()) ==
+				PEM_R_NO_START_LINE)
+				ERR_add_error_data(2, "Expecting: ", name);
+			return 0;
+		}
+		if(check_pem(nm, name)) break;
+		OPENSSL_free(nm);
+		OPENSSL_free(header);
+		OPENSSL_free(data);
+		}
+	if (!PEM_get_EVP_CIPHER_INFO(header,&cipher)) goto err;
+	if (!PEM_do_header(&cipher,data,&len,cb,u)) goto err;
+
+	*pdata = data;
+	*plen = len;
+
+	if (pnm)
+		*pnm = nm;
+
+	ret = 1;
+
+err:
+	if (!ret || !pnm) OPENSSL_free(nm);
+	OPENSSL_free(header);
+	if (!ret) OPENSSL_free(data);
+	return ret;
+	}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
+		   void *x, const EVP_CIPHER *enc, unsigned char *kstr,
+		   int klen, pem_password_cb *callback, void *u)
+        {
+        BIO *b;
+        int ret;
+
+        if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		PEMerr(PEM_F_PEM_ASN1_WRITE,ERR_R_BUF_LIB);
+                return(0);
+		}
+        BIO_set_fp(b,fp,BIO_NOCLOSE);
+        ret=PEM_ASN1_write_bio(i2d,name,b,x,enc,kstr,klen,callback,u);
+        BIO_free(b);
+        return(ret);
+        }
+#endif
+
+int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
+		       void *x, const EVP_CIPHER *enc, unsigned char *kstr,
+		       int klen, pem_password_cb *callback, void *u)
+	{
+	EVP_CIPHER_CTX ctx;
+	int dsize=0,i,j,ret=0;
+	unsigned char *p,*data=NULL;
+	const char *objstr=NULL;
+	char buf[PEM_BUFSIZE];
+	unsigned char key[EVP_MAX_KEY_LENGTH];
+	unsigned char iv[EVP_MAX_IV_LENGTH];
+	
+	if (enc != NULL)
+		{
+		objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
+		if (objstr == NULL)
+			{
+			PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER);
+			goto err;
+			}
+		}
+
+	if ((dsize=i2d(x,NULL)) < 0)
+		{
+		PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_ASN1_LIB);
+		dsize=0;
+		goto err;
+		}
+	/* dzise + 8 bytes are needed */
+	/* actually it needs the cipher block size extra... */
+	data=(unsigned char *)OPENSSL_malloc((unsigned int)dsize+20);
+	if (data == NULL)
+		{
+		PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	p=data;
+	i=i2d(x,&p);
+
+	if (enc != NULL)
+		{
+		if (kstr == NULL)
+			{
+			if (callback == NULL)
+				klen=PEM_def_callback(buf,PEM_BUFSIZE,1,u);
+			else
+				klen=(*callback)(buf,PEM_BUFSIZE,1,u);
+			if (klen <= 0)
+				{
+				PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_READ_KEY);
+				goto err;
+				}
+#ifdef CHARSET_EBCDIC
+			/* Convert the pass phrase from EBCDIC */
+			ebcdic2ascii(buf, buf, klen);
+#endif
+			kstr=(unsigned char *)buf;
+			}
+		RAND_add(data,i,0);/* put in the RSA key. */
+		OPENSSL_assert(enc->iv_len <= (int)sizeof(iv));
+		if (RAND_pseudo_bytes(iv,enc->iv_len) < 0) /* Generate a salt */
+			goto err;
+		/* The 'iv' is used as the iv and as a salt.  It is
+		 * NOT taken from the BytesToKey function */
+		EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL);
+
+		if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf,PEM_BUFSIZE);
+
+		OPENSSL_assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf);
+
+		buf[0]='\0';
+		PEM_proc_type(buf,PEM_TYPE_ENCRYPTED);
+		PEM_dek_info(buf,objstr,enc->iv_len,(char *)iv);
+		/* k=strlen(buf); */
+
+		EVP_CIPHER_CTX_init(&ctx);
+		EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv);
+		EVP_EncryptUpdate(&ctx,data,&j,data,i);
+		EVP_EncryptFinal_ex(&ctx,&(data[j]),&i);
+		EVP_CIPHER_CTX_cleanup(&ctx);
+		i+=j;
+		ret=1;
+		}
+	else
+		{
+		ret=1;
+		buf[0]='\0';
+		}
+	i=PEM_write_bio(bp,name,buf,data,i);
+	if (i <= 0) ret=0;
+err:
+	OPENSSL_cleanse(key,sizeof(key));
+	OPENSSL_cleanse(iv,sizeof(iv));
+	OPENSSL_cleanse((char *)&ctx,sizeof(ctx));
+	OPENSSL_cleanse(buf,PEM_BUFSIZE);
+	if (data != NULL)
+		{
+		OPENSSL_cleanse(data,(unsigned int)dsize);
+		OPENSSL_free(data);
+		}
+	return(ret);
+	}
+
+int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
+	     pem_password_cb *callback,void *u)
+	{
+	int i,j,o,klen;
+	long len;
+	EVP_CIPHER_CTX ctx;
+	unsigned char key[EVP_MAX_KEY_LENGTH];
+	char buf[PEM_BUFSIZE];
+
+	len= *plen;
+
+	if (cipher->cipher == NULL) return(1);
+	if (callback == NULL)
+		klen=PEM_def_callback(buf,PEM_BUFSIZE,0,u);
+	else
+		klen=callback(buf,PEM_BUFSIZE,0,u);
+	if (klen <= 0)
+		{
+		PEMerr(PEM_F_PEM_DO_HEADER,PEM_R_BAD_PASSWORD_READ);
+		return(0);
+		}
+#ifdef CHARSET_EBCDIC
+	/* Convert the pass phrase from EBCDIC */
+	ebcdic2ascii(buf, buf, klen);
+#endif
+
+	EVP_BytesToKey(cipher->cipher,EVP_md5(),&(cipher->iv[0]),
+		(unsigned char *)buf,klen,1,key,NULL);
+
+	j=(int)len;
+	EVP_CIPHER_CTX_init(&ctx);
+	EVP_DecryptInit_ex(&ctx,cipher->cipher,NULL, key,&(cipher->iv[0]));
+	EVP_DecryptUpdate(&ctx,data,&i,data,j);
+	o=EVP_DecryptFinal_ex(&ctx,&(data[i]),&j);
+	EVP_CIPHER_CTX_cleanup(&ctx);
+	OPENSSL_cleanse((char *)buf,sizeof(buf));
+	OPENSSL_cleanse((char *)key,sizeof(key));
+	j+=i;
+	if (!o)
+		{
+		PEMerr(PEM_F_PEM_DO_HEADER,PEM_R_BAD_DECRYPT);
+		return(0);
+		}
+	*plen=j;
+	return(1);
+	}
+
+int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
+	{
+	const EVP_CIPHER *enc=NULL;
+	char *p,c;
+	char **header_pp = &header;
+
+	cipher->cipher=NULL;
+	if ((header == NULL) || (*header == '\0') || (*header == '\n'))
+		return(1);
+	if (strncmp(header,"Proc-Type: ",11) != 0)
+		{ PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_NOT_PROC_TYPE); return(0); }
+	header+=11;
+	if (*header != '4') return(0); header++;
+	if (*header != ',') return(0); header++;
+	if (strncmp(header,"ENCRYPTED",9) != 0)
+		{ PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_NOT_ENCRYPTED); return(0); }
+	for (; (*header != '\n') && (*header != '\0'); header++)
+		;
+	if (*header == '\0')
+		{ PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_SHORT_HEADER); return(0); }
+	header++;
+	if (strncmp(header,"DEK-Info: ",10) != 0)
+		{ PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_NOT_DEK_INFO); return(0); }
+	header+=10;
+
+	p=header;
+	for (;;)
+		{
+		c= *header;
+#ifndef CHARSET_EBCDIC
+		if (!(	((c >= 'A') && (c <= 'Z')) || (c == '-') ||
+			((c >= '0') && (c <= '9'))))
+			break;
+#else
+		if (!(	isupper(c) || (c == '-') ||
+			isdigit(c)))
+			break;
+#endif
+		header++;
+		}
+	*header='\0';
+	cipher->cipher=enc=EVP_get_cipherbyname(p);
+	*header=c;
+	header++;
+
+	if (enc == NULL)
+		{
+		PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_UNSUPPORTED_ENCRYPTION);
+		return(0);
+		}
+	if (!load_iv(header_pp,&(cipher->iv[0]),enc->iv_len))
+		return(0);
+
+	return(1);
+	}
+
+static int load_iv(char **fromp, unsigned char *to, int num)
+	{
+	int v,i;
+	char *from;
+
+	from= *fromp;
+	for (i=0; i<num; i++) to[i]=0;
+	num*=2;
+	for (i=0; i<num; i++)
+		{
+		if ((*from >= '0') && (*from <= '9'))
+			v= *from-'0';
+		else if ((*from >= 'A') && (*from <= 'F'))
+			v= *from-'A'+10;
+		else if ((*from >= 'a') && (*from <= 'f'))
+			v= *from-'a'+10;
+		else
+			{
+			PEMerr(PEM_F_LOAD_IV,PEM_R_BAD_IV_CHARS);
+			return(0);
+			}
+		from++;
+		to[i/2]|=v<<(long)((!(i&1))*4);
+		}
+
+	*fromp=from;
+	return(1);
+	}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write(FILE *fp, char *name, char *header, unsigned char *data,
+	     long len)
+        {
+        BIO *b;
+        int ret;
+
+        if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		PEMerr(PEM_F_PEM_WRITE,ERR_R_BUF_LIB);
+                return(0);
+		}
+        BIO_set_fp(b,fp,BIO_NOCLOSE);
+        ret=PEM_write_bio(b, name, header, data,len);
+        BIO_free(b);
+        return(ret);
+        }
+#endif
+
+int PEM_write_bio(BIO *bp, const char *name, char *header, unsigned char *data,
+	     long len)
+	{
+	int nlen,n,i,j,outl;
+	unsigned char *buf = NULL;
+	EVP_ENCODE_CTX ctx;
+	int reason=ERR_R_BUF_LIB;
+	
+	EVP_EncodeInit(&ctx);
+	nlen=strlen(name);
+
+	if (	(BIO_write(bp,"-----BEGIN ",11) != 11) ||
+		(BIO_write(bp,name,nlen) != nlen) ||
+		(BIO_write(bp,"-----\n",6) != 6))
+		goto err;
+		
+	i=strlen(header);
+	if (i > 0)
+		{
+		if (	(BIO_write(bp,header,i) != i) ||
+			(BIO_write(bp,"\n",1) != 1))
+			goto err;
+		}
+
+	buf = OPENSSL_malloc(PEM_BUFSIZE*8);
+	if (buf == NULL)
+		{
+		reason=ERR_R_MALLOC_FAILURE;
+		goto err;
+		}
+
+	i=j=0;
+	while (len > 0)
+		{
+		n=(int)((len>(PEM_BUFSIZE*5))?(PEM_BUFSIZE*5):len);
+		EVP_EncodeUpdate(&ctx,buf,&outl,&(data[j]),n);
+		if ((outl) && (BIO_write(bp,(char *)buf,outl) != outl))
+			goto err;
+		i+=outl;
+		len-=n;
+		j+=n;
+		}
+	EVP_EncodeFinal(&ctx,buf,&outl);
+	if ((outl > 0) && (BIO_write(bp,(char *)buf,outl) != outl)) goto err;
+	OPENSSL_cleanse(buf, PEM_BUFSIZE*8);
+	OPENSSL_free(buf);
+	buf = NULL;
+	if (	(BIO_write(bp,"-----END ",9) != 9) ||
+		(BIO_write(bp,name,nlen) != nlen) ||
+		(BIO_write(bp,"-----\n",6) != 6))
+		goto err;
+	return(i+outl);
+err:
+	if (buf) {
+		OPENSSL_cleanse(buf, PEM_BUFSIZE*8);
+		OPENSSL_free(buf);
+	}
+	PEMerr(PEM_F_PEM_WRITE_BIO,reason);
+	return(0);
+	}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,
+	     long *len)
+        {
+        BIO *b;
+        int ret;
+
+        if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		PEMerr(PEM_F_PEM_READ,ERR_R_BUF_LIB);
+                return(0);
+		}
+        BIO_set_fp(b,fp,BIO_NOCLOSE);
+        ret=PEM_read_bio(b, name, header, data,len);
+        BIO_free(b);
+        return(ret);
+        }
+#endif
+
+int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
+	     long *len)
+	{
+	EVP_ENCODE_CTX ctx;
+	int end=0,i,k,bl=0,hl=0,nohead=0;
+	char buf[256];
+	BUF_MEM *nameB;
+	BUF_MEM *headerB;
+	BUF_MEM *dataB,*tmpB;
+	
+	nameB=BUF_MEM_new();
+	headerB=BUF_MEM_new();
+	dataB=BUF_MEM_new();
+	if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL))
+		{
+		BUF_MEM_free(nameB);
+		BUF_MEM_free(headerB);
+		BUF_MEM_free(dataB);
+		PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+
+	buf[254]='\0';
+	for (;;)
+		{
+		i=BIO_gets(bp,buf,254);
+
+		if (i <= 0)
+			{
+			PEMerr(PEM_F_PEM_READ_BIO,PEM_R_NO_START_LINE);
+			goto err;
+			}
+
+		while ((i >= 0) && (buf[i] <= ' ')) i--;
+		buf[++i]='\n'; buf[++i]='\0';
+
+		if (strncmp(buf,"-----BEGIN ",11) == 0)
+			{
+			i=strlen(&(buf[11]));
+
+			if (strncmp(&(buf[11+i-6]),"-----\n",6) != 0)
+				continue;
+			if (!BUF_MEM_grow(nameB,i+9))
+				{
+				PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			memcpy(nameB->data,&(buf[11]),i-6);
+			nameB->data[i-6]='\0';
+			break;
+			}
+		}
+	hl=0;
+	if (!BUF_MEM_grow(headerB,256))
+		{ PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }
+	headerB->data[0]='\0';
+	for (;;)
+		{
+		i=BIO_gets(bp,buf,254);
+		if (i <= 0) break;
+
+		while ((i >= 0) && (buf[i] <= ' ')) i--;
+		buf[++i]='\n'; buf[++i]='\0';
+
+		if (buf[0] == '\n') break;
+		if (!BUF_MEM_grow(headerB,hl+i+9))
+			{ PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }
+		if (strncmp(buf,"-----END ",9) == 0)
+			{
+			nohead=1;
+			break;
+			}
+		memcpy(&(headerB->data[hl]),buf,i);
+		headerB->data[hl+i]='\0';
+		hl+=i;
+		}
+
+	bl=0;
+	if (!BUF_MEM_grow(dataB,1024))
+		{ PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }
+	dataB->data[0]='\0';
+	if (!nohead)
+		{
+		for (;;)
+			{
+			i=BIO_gets(bp,buf,254);
+			if (i <= 0) break;
+
+			while ((i >= 0) && (buf[i] <= ' ')) i--;
+			buf[++i]='\n'; buf[++i]='\0';
+
+			if (i != 65) end=1;
+			if (strncmp(buf,"-----END ",9) == 0)
+				break;
+			if (i > 65) break;
+			if (!BUF_MEM_grow_clean(dataB,i+bl+9))
+				{
+				PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			memcpy(&(dataB->data[bl]),buf,i);
+			dataB->data[bl+i]='\0';
+			bl+=i;
+			if (end)
+				{
+				buf[0]='\0';
+				i=BIO_gets(bp,buf,254);
+				if (i <= 0) break;
+
+				while ((i >= 0) && (buf[i] <= ' ')) i--;
+				buf[++i]='\n'; buf[++i]='\0';
+
+				break;
+				}
+			}
+		}
+	else
+		{
+		tmpB=headerB;
+		headerB=dataB;
+		dataB=tmpB;
+		bl=hl;
+		}
+	i=strlen(nameB->data);
+	if (	(strncmp(buf,"-----END ",9) != 0) ||
+		(strncmp(nameB->data,&(buf[9]),i) != 0) ||
+		(strncmp(&(buf[9+i]),"-----\n",6) != 0))
+		{
+		PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_END_LINE);
+		goto err;
+		}
+
+	EVP_DecodeInit(&ctx);
+	i=EVP_DecodeUpdate(&ctx,
+		(unsigned char *)dataB->data,&bl,
+		(unsigned char *)dataB->data,bl);
+	if (i < 0)
+		{
+		PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_BASE64_DECODE);
+		goto err;
+		}
+	i=EVP_DecodeFinal(&ctx,(unsigned char *)&(dataB->data[bl]),&k);
+	if (i < 0)
+		{
+		PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_BASE64_DECODE);
+		goto err;
+		}
+	bl+=k;
+
+	if (bl == 0) goto err;
+	*name=nameB->data;
+	*header=headerB->data;
+	*data=(unsigned char *)dataB->data;
+	*len=bl;
+	OPENSSL_free(nameB);
+	OPENSSL_free(headerB);
+	OPENSSL_free(dataB);
+	return(1);
+err:
+	BUF_MEM_free(nameB);
+	BUF_MEM_free(headerB);
+	BUF_MEM_free(dataB);
+	return(0);
+	}
+
+/* Check pem string and return prefix length.
+ * If for example the pem_str == "RSA PRIVATE KEY" and suffix = "PRIVATE KEY"
+ * the return value is 3 for the string "RSA".
+ */
+
+int pem_check_suffix(const char *pem_str, const char *suffix)
+	{
+	int pem_len = strlen(pem_str);
+	int suffix_len = strlen(suffix);
+	const char *p;
+	if (suffix_len + 1 >= pem_len)
+		return 0;
+	p = pem_str + pem_len - suffix_len;
+	if (strcmp(p, suffix))
+		return 0;
+	p--;
+	if (*p != ' ')
+		return 0;
+	return p - pem_str;
+	}
+
diff --git a/openssl/crypto/pem/pem_oth.c b/openssl/crypto/pem/pem_oth.c
new file mode 100644
index 0000000..b33868d
--- /dev/null
+++ b/openssl/crypto/pem/pem_oth.c
@@ -0,0 +1,86 @@
+/* crypto/pem/pem_oth.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+/* Handle 'other' PEMs: not private keys */
+
+void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x,
+			pem_password_cb *cb, void *u)
+	{
+	const unsigned char *p=NULL;
+	unsigned char *data=NULL;
+	long len;
+	char *ret=NULL;
+
+	if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u))
+		return NULL;
+	p = data;
+	ret=d2i(x,&p,len);
+	if (ret == NULL)
+		PEMerr(PEM_F_PEM_ASN1_READ_BIO,ERR_R_ASN1_LIB);
+	OPENSSL_free(data);
+	return(ret);
+	}
diff --git a/openssl/crypto/pem/pem_pk8.c b/openssl/crypto/pem/pem_pk8.c
new file mode 100644
index 0000000..6deab8c
--- /dev/null
+++ b/openssl/crypto/pem/pem_pk8.c
@@ -0,0 +1,242 @@
+/* crypto/pem/pem_pkey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs12.h>
+#include <openssl/pem.h>
+
+static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder,
+				int nid, const EVP_CIPHER *enc,
+				char *kstr, int klen,
+				pem_password_cb *cb, void *u);
+static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder,
+				int nid, const EVP_CIPHER *enc,
+				char *kstr, int klen,
+				pem_password_cb *cb, void *u);
+
+/* These functions write a private key in PKCS#8 format: it is a "drop in"
+ * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc'
+ * is NULL then it uses the unencrypted private key form. The 'nid' versions
+ * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0.
+ */
+
+int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u)
+{
+	return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u);
+}
+
+int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u)
+{
+	return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u);
+}
+
+int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u)
+{
+	return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u);
+}
+
+int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u)
+{
+	return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u);
+}
+
+static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u)
+{
+	X509_SIG *p8;
+	PKCS8_PRIV_KEY_INFO *p8inf;
+	char buf[PEM_BUFSIZE];
+	int ret;
+	if(!(p8inf = EVP_PKEY2PKCS8(x))) {
+		PEMerr(PEM_F_DO_PK8PKEY,
+					PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
+		return 0;
+	}
+	if(enc || (nid != -1)) {
+		if(!kstr) {
+			if(!cb) klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u);
+			else klen = cb(buf, PEM_BUFSIZE, 1, u);
+			if(klen <= 0) {
+				PEMerr(PEM_F_DO_PK8PKEY,PEM_R_READ_KEY);
+				PKCS8_PRIV_KEY_INFO_free(p8inf);
+				return 0;
+			}
+				
+			kstr = buf;
+		}
+		p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf);
+		if(kstr == buf) OPENSSL_cleanse(buf, klen);
+		PKCS8_PRIV_KEY_INFO_free(p8inf);
+		if(isder) ret = i2d_PKCS8_bio(bp, p8);
+		else ret = PEM_write_bio_PKCS8(bp, p8);
+		X509_SIG_free(p8);
+		return ret;
+	} else {
+		if(isder) ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
+		else ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf);
+		PKCS8_PRIV_KEY_INFO_free(p8inf);
+		return ret;
+	}
+}
+
+EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
+{
+	PKCS8_PRIV_KEY_INFO *p8inf = NULL;
+	X509_SIG *p8 = NULL;
+	int klen;
+	EVP_PKEY *ret;
+	char psbuf[PEM_BUFSIZE];
+	p8 = d2i_PKCS8_bio(bp, NULL);
+	if(!p8) return NULL;
+	if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u);
+	else klen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u);
+	if (klen <= 0) {
+		PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ);
+		X509_SIG_free(p8);
+		return NULL;	
+	}
+	p8inf = PKCS8_decrypt(p8, psbuf, klen);
+	X509_SIG_free(p8);
+	if(!p8inf) return NULL;
+	ret = EVP_PKCS82PKEY(p8inf);
+	PKCS8_PRIV_KEY_INFO_free(p8inf);
+	if(!ret) return NULL;
+	if(x) {
+		if(*x) EVP_PKEY_free(*x);
+		*x = ret;
+	}
+	return ret;
+}
+
+#ifndef OPENSSL_NO_FP_API
+
+int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u)
+{
+	return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u);
+}
+
+int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u)
+{
+	return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u);
+}
+
+int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u)
+{
+	return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u);
+}
+
+int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+			      char *kstr, int klen, pem_password_cb *cb, void *u)
+{
+	return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u);
+}
+
+static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u)
+{
+	BIO *bp;
+	int ret;
+	if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
+		PEMerr(PEM_F_DO_PK8PKEY_FP,ERR_R_BUF_LIB);
+                return(0);
+	}
+	ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u);
+	BIO_free(bp);
+	return ret;
+}
+
+EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
+{
+	BIO *bp;
+	EVP_PKEY *ret;
+	if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
+		PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_FP,ERR_R_BUF_LIB);
+                return NULL;
+	}
+	ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u);
+	BIO_free(bp);
+	return ret;
+}
+
+#endif
+
+IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG)
+IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF,
+							 PKCS8_PRIV_KEY_INFO)
diff --git a/openssl/crypto/pem/pem_pkey.c b/openssl/crypto/pem/pem_pkey.c
new file mode 100644
index 0000000..8ecf249
--- /dev/null
+++ b/openssl/crypto/pem/pem_pkey.c
@@ -0,0 +1,242 @@
+/* crypto/pem/pem_pkey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs12.h>
+#include <openssl/pem.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include "asn1_locl.h"
+
+int pem_check_suffix(const char *pem_str, const char *suffix);
+
+EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
+	{
+	char *nm=NULL;
+	const unsigned char *p=NULL;
+	unsigned char *data=NULL;
+	long len;
+	int slen;
+	EVP_PKEY *ret=NULL;
+
+	if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u))
+		return NULL;
+	p = data;
+
+	if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) {
+		PKCS8_PRIV_KEY_INFO *p8inf;
+		p8inf=d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
+		if(!p8inf) goto p8err;
+		ret = EVP_PKCS82PKEY(p8inf);
+		if(x) {
+			if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
+			*x = ret;
+		}
+		PKCS8_PRIV_KEY_INFO_free(p8inf);
+	} else if (strcmp(nm,PEM_STRING_PKCS8) == 0) {
+		PKCS8_PRIV_KEY_INFO *p8inf;
+		X509_SIG *p8;
+		int klen;
+		char psbuf[PEM_BUFSIZE];
+		p8 = d2i_X509_SIG(NULL, &p, len);
+		if(!p8) goto p8err;
+		if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u);
+		else klen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u);
+		if (klen <= 0) {
+			PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,
+					PEM_R_BAD_PASSWORD_READ);
+			X509_SIG_free(p8);
+			goto err;
+		}
+		p8inf = PKCS8_decrypt(p8, psbuf, klen);
+		X509_SIG_free(p8);
+		if(!p8inf) goto p8err;
+		ret = EVP_PKCS82PKEY(p8inf);
+		if(x) {
+			if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
+			*x = ret;
+		}
+		PKCS8_PRIV_KEY_INFO_free(p8inf);
+	} else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0)
+		{
+		const EVP_PKEY_ASN1_METHOD *ameth;
+		ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
+		if (!ameth || !ameth->old_priv_decode)
+			goto p8err;
+		ret=d2i_PrivateKey(ameth->pkey_id,x,&p,len);
+		}
+p8err:
+	if (ret == NULL)
+		PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,ERR_R_ASN1_LIB);
+err:
+	OPENSSL_free(nm);
+	OPENSSL_cleanse(data, len);
+	OPENSSL_free(data);
+	return(ret);
+	}
+
+int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+	{
+	char pem_str[80];
+	if (!x->ameth || x->ameth->priv_encode)
+		return PEM_write_bio_PKCS8PrivateKey(bp, x, enc,
+							(char *)kstr, klen,
+							cb, u);
+
+	BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str);
+	return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey,
+				pem_str,bp,x,enc,kstr,klen,cb,u);
+	}
+
+EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
+	{
+	char *nm=NULL;
+	const unsigned char *p=NULL;
+	unsigned char *data=NULL;
+	long len;
+	int slen;
+	EVP_PKEY *ret=NULL;
+
+	if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS,
+								bp, 0, NULL))
+		return NULL;
+	p = data;
+
+	if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0)
+		{
+		ret = EVP_PKEY_new();
+		if (!ret)
+			goto err;
+		if (!EVP_PKEY_set_type_str(ret, nm, slen)
+			|| !ret->ameth->param_decode
+			|| !ret->ameth->param_decode(ret, &p, len))
+			{
+			EVP_PKEY_free(ret);
+			ret = NULL;
+			goto err;
+			}
+		if(x)
+			{
+			if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
+			*x = ret;
+			}
+		}
+err:
+	if (ret == NULL)
+		PEMerr(PEM_F_PEM_READ_BIO_PARAMETERS,ERR_R_ASN1_LIB);
+	OPENSSL_free(nm);
+	OPENSSL_free(data);
+	return(ret);
+	}
+
+int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x)
+	{
+	char pem_str[80];
+	if (!x->ameth || !x->ameth->param_encode)
+		return 0;
+
+	BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str);
+	return PEM_ASN1_write_bio(
+		(i2d_of_void *)x->ameth->param_encode,
+				pem_str,bp,x,NULL,NULL,0,0,NULL);
+	}
+
+#ifndef OPENSSL_NO_FP_API
+EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
+	{
+        BIO *b;
+        EVP_PKEY *ret;
+
+        if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		PEMerr(PEM_F_PEM_READ_PRIVATEKEY,ERR_R_BUF_LIB);
+                return(0);
+		}
+        BIO_set_fp(b,fp,BIO_NOCLOSE);
+        ret=PEM_read_bio_PrivateKey(b,x,cb,u);
+        BIO_free(b);
+        return(ret);
+	}
+
+int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+	{
+        BIO *b;
+        int ret;
+
+        if ((b=BIO_new_fp(fp, BIO_NOCLOSE)) == NULL)
+		{
+		PEMerr(PEM_F_PEM_WRITE_PRIVATEKEY,ERR_R_BUF_LIB);
+                return 0;
+		}
+        ret=PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u);
+        BIO_free(b);
+        return ret;
+	}
+
+#endif
diff --git a/openssl/crypto/pem/pem_seal.c b/openssl/crypto/pem/pem_seal.c
new file mode 100644
index 0000000..59690b5
--- /dev/null
+++ b/openssl/crypto/pem/pem_seal.c
@@ -0,0 +1,189 @@
+/* crypto/pem/pem_seal.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/opensslconf.h>	/* for OPENSSL_NO_RSA */
+#ifndef OPENSSL_NO_RSA
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/rsa.h>
+
+int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type,
+	     unsigned char **ek, int *ekl, unsigned char *iv, EVP_PKEY **pubk,
+	     int npubk)
+	{
+	unsigned char key[EVP_MAX_KEY_LENGTH];
+	int ret= -1;
+	int i,j,max=0;
+	char *s=NULL;
+
+	for (i=0; i<npubk; i++)
+		{
+		if (pubk[i]->type != EVP_PKEY_RSA)
+			{
+			PEMerr(PEM_F_PEM_SEALINIT,PEM_R_PUBLIC_KEY_NO_RSA);
+			goto err;
+			}
+		j=RSA_size(pubk[i]->pkey.rsa);
+		if (j > max) max=j;
+		}
+	s=(char *)OPENSSL_malloc(max*2);
+	if (s == NULL)
+		{
+		PEMerr(PEM_F_PEM_SEALINIT,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	EVP_EncodeInit(&ctx->encode);
+
+	EVP_MD_CTX_init(&ctx->md);
+	EVP_SignInit(&ctx->md,md_type);
+
+	EVP_CIPHER_CTX_init(&ctx->cipher);
+	ret=EVP_SealInit(&ctx->cipher,type,ek,ekl,iv,pubk,npubk);
+	if (ret <= 0) goto err;
+
+	/* base64 encode the keys */
+	for (i=0; i<npubk; i++)
+		{
+		j=EVP_EncodeBlock((unsigned char *)s,ek[i],
+			RSA_size(pubk[i]->pkey.rsa));
+		ekl[i]=j;
+		memcpy(ek[i],s,j+1);
+		}
+
+	ret=npubk;
+err:
+	if (s != NULL) OPENSSL_free(s);
+	OPENSSL_cleanse(key,EVP_MAX_KEY_LENGTH);
+	return(ret);
+	}
+
+void PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl,
+	     unsigned char *in, int inl)
+	{
+	unsigned char buffer[1600];
+	int i,j;
+
+	*outl=0;
+	EVP_SignUpdate(&ctx->md,in,inl);
+	for (;;)
+		{
+		if (inl <= 0) break;
+		if (inl > 1200)
+			i=1200;
+		else
+			i=inl;
+		EVP_EncryptUpdate(&ctx->cipher,buffer,&j,in,i);
+		EVP_EncodeUpdate(&ctx->encode,out,&j,buffer,j);
+		*outl+=j;
+		out+=j;
+		in+=i;
+		inl-=i;
+		}
+	}
+
+int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl,
+	     unsigned char *out, int *outl, EVP_PKEY *priv)
+	{
+	unsigned char *s=NULL;
+	int ret=0,j;
+	unsigned int i;
+
+	if (priv->type != EVP_PKEY_RSA)
+		{
+		PEMerr(PEM_F_PEM_SEALFINAL,PEM_R_PUBLIC_KEY_NO_RSA);
+		goto err;
+		}
+	i=RSA_size(priv->pkey.rsa);
+	if (i < 100) i=100;
+	s=(unsigned char *)OPENSSL_malloc(i*2);
+	if (s == NULL)
+		{
+		PEMerr(PEM_F_PEM_SEALFINAL,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	EVP_EncryptFinal_ex(&ctx->cipher,s,(int *)&i);
+	EVP_EncodeUpdate(&ctx->encode,out,&j,s,i);
+	*outl=j;
+	out+=j;
+	EVP_EncodeFinal(&ctx->encode,out,&j);
+	*outl+=j;
+
+	if (!EVP_SignFinal(&ctx->md,s,&i,priv)) goto err;
+	*sigl=EVP_EncodeBlock(sig,s,i);
+
+	ret=1;
+err:
+	EVP_MD_CTX_cleanup(&ctx->md);
+	EVP_CIPHER_CTX_cleanup(&ctx->cipher);
+	if (s != NULL) OPENSSL_free(s);
+	return(ret);
+	}
+#else /* !OPENSSL_NO_RSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/crypto/pem/pem_sign.c b/openssl/crypto/pem/pem_sign.c
new file mode 100644
index 0000000..c3b9808
--- /dev/null
+++ b/openssl/crypto/pem/pem_sign.c
@@ -0,0 +1,102 @@
+/* crypto/pem/pem_sign.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type)
+	{
+	EVP_DigestInit_ex(ctx, type, NULL);
+	}
+
+void PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data,
+	     unsigned int count)
+	{
+	EVP_DigestUpdate(ctx,data,count);
+	}
+
+int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
+	     EVP_PKEY *pkey)
+	{
+	unsigned char *m;
+	int i,ret=0;
+	unsigned int m_len;
+
+	m=(unsigned char *)OPENSSL_malloc(EVP_PKEY_size(pkey)+2);
+	if (m == NULL)
+		{
+		PEMerr(PEM_F_PEM_SIGNFINAL,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (EVP_SignFinal(ctx,m,&m_len,pkey) <= 0) goto err;
+
+	i=EVP_EncodeBlock(sigret,m,m_len);
+	*siglen=i;
+	ret=1;
+err:
+	/* ctx has been zeroed by EVP_SignFinal() */
+	if (m != NULL) OPENSSL_free(m);
+	return(ret);
+	}
+
diff --git a/openssl/crypto/pem/pem_x509.c b/openssl/crypto/pem/pem_x509.c
new file mode 100644
index 0000000..b531057
--- /dev/null
+++ b/openssl/crypto/pem/pem_x509.c
@@ -0,0 +1,68 @@
+/* pem_x509.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pem.h>
+
+IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509)
+
diff --git a/openssl/crypto/pem/pem_xaux.c b/openssl/crypto/pem/pem_xaux.c
new file mode 100644
index 0000000..328f796
--- /dev/null
+++ b/openssl/crypto/pem/pem_xaux.c
@@ -0,0 +1,68 @@
+/* pem_xaux.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pem.h>
+
+IMPLEMENT_PEM_rw(X509_AUX, X509, PEM_STRING_X509_TRUSTED, X509_AUX)
+IMPLEMENT_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR, PEM_STRING_X509_PAIR, X509_CERT_PAIR)
diff --git a/openssl/crypto/pem/pkcs7.lis b/openssl/crypto/pem/pkcs7.lis
new file mode 100644
index 0000000..be90c5d
--- /dev/null
+++ b/openssl/crypto/pem/pkcs7.lis
@@ -0,0 +1,22 @@
+21     0:d=0 hl=2 l=  0 cons: univ: SEQUENCE          
+ 00     2:d=0 hl=2 l=  9 prim: univ: OBJECT_IDENTIFIER :pkcs-7-signedData
+ 21    13:d=0 hl=2 l=  0 cons: cont: 00			# explicit tag
+  21    15:d=0 hl=2 l=  0 cons: univ: SEQUENCE          
+   00    17:d=0 hl=2 l=  1 prim: univ: INTEGER          # version 
+   20    20:d=0 hl=2 l=  0 cons: univ: SET               
+   21    22:d=0 hl=2 l=  0 cons: univ: SEQUENCE          
+    00    24:d=0 hl=2 l=  9 prim: univ: OBJECT_IDENTIFIER :pkcs-7-data
+    00    35:d=0 hl=2 l=  0 prim: univ: EOC               
+   21    37:d=0 hl=2 l=  0 cons: cont: 00               # cert tag
+    20    39:d=0 hl=4 l=545 cons: univ: SEQUENCE          
+    20   588:d=0 hl=4 l=524 cons: univ: SEQUENCE          
+    00  1116:d=0 hl=2 l=  0 prim: univ: EOC               
+   21  1118:d=0 hl=2 l=  0 cons: cont: 01		# crl tag
+    20  1120:d=0 hl=4 l=653 cons: univ: SEQUENCE          
+    20  1777:d=0 hl=4 l=285 cons: univ: SEQUENCE          
+    00  2066:d=0 hl=2 l=  0 prim: univ: EOC               
+   21  2068:d=0 hl=2 l=  0 cons: univ: SET              # signers 
+    00  2070:d=0 hl=2 l=  0 prim: univ: EOC               
+  00  2072:d=0 hl=2 l=  0 prim: univ: EOC               
+ 00  2074:d=0 hl=2 l=  0 prim: univ: EOC               
+00  2076:d=0 hl=2 l=  0 prim: univ: EOC               
diff --git a/openssl/crypto/pem/pvkfmt.c b/openssl/crypto/pem/pvkfmt.c
new file mode 100644
index 0000000..5f130c4
--- /dev/null
+++ b/openssl/crypto/pem/pvkfmt.c
@@ -0,0 +1,938 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Support for PVK format keys and related structures (such a PUBLICKEYBLOB
+ * and PRIVATEKEYBLOB).
+ */
+
+#include "cryptlib.h"
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
+#include <openssl/dsa.h>
+#include <openssl/rsa.h>
+
+/* Utility function: read a DWORD (4 byte unsigned integer) in little endian
+ * format
+ */
+
+static unsigned int read_ledword(const unsigned char **in)
+	{
+	const unsigned char *p = *in;
+	unsigned int ret;
+	ret = *p++;
+	ret |= (*p++ << 8);
+	ret |= (*p++ << 16);
+	ret |= (*p++ << 24);
+	*in = p;
+	return ret;
+	}
+
+/* Read a BIGNUM in little endian format. The docs say that this should take up 
+ * bitlen/8 bytes.
+ */
+
+static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r)
+	{
+	const unsigned char *p;
+	unsigned char *tmpbuf, *q;
+	unsigned int i;
+	p = *in + nbyte - 1;
+	tmpbuf = OPENSSL_malloc(nbyte);
+	if (!tmpbuf)
+		return 0;
+	q = tmpbuf;
+	for (i = 0; i < nbyte; i++)
+		*q++ = *p--;
+	*r = BN_bin2bn(tmpbuf, nbyte, NULL);
+	OPENSSL_free(tmpbuf);
+	if (*r)
+		{
+		*in += nbyte;
+		return 1;
+		}
+	else
+		return 0;
+	}
+
+
+/* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */
+
+#define MS_PUBLICKEYBLOB	0x6
+#define MS_PRIVATEKEYBLOB	0x7
+#define MS_RSA1MAGIC		0x31415352L
+#define MS_RSA2MAGIC		0x32415352L
+#define MS_DSS1MAGIC		0x31535344L
+#define MS_DSS2MAGIC		0x32535344L
+
+#define MS_KEYALG_RSA_KEYX	0xa400
+#define MS_KEYALG_DSS_SIGN	0x2200
+
+#define MS_KEYTYPE_KEYX		0x1
+#define MS_KEYTYPE_SIGN		0x2
+
+/* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */
+#define MS_PVKMAGIC		0xb0b5f11eL
+/* Salt length for PVK files */
+#define PVK_SALTLEN		0x10
+
+static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length,
+						unsigned int bitlen, int ispub);
+static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length,
+						unsigned int bitlen, int ispub);
+
+static int do_blob_header(const unsigned char **in, unsigned int length,
+				unsigned int *pmagic, unsigned int *pbitlen,
+				int *pisdss, int *pispub)
+	{
+	const unsigned char *p = *in;
+	if (length < 16)
+		return 0;
+	/* bType */
+	if (*p == MS_PUBLICKEYBLOB)
+		{
+		if (*pispub == 0)
+			{
+			PEMerr(PEM_F_DO_BLOB_HEADER,
+					PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
+			return 0;
+			}
+		*pispub = 1;
+		}
+	else if (*p == MS_PRIVATEKEYBLOB)
+		{
+		if (*pispub == 1)
+			{
+			PEMerr(PEM_F_DO_BLOB_HEADER,
+					PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
+			return 0;
+			}
+		*pispub = 0;
+		}
+	else
+		return 0;
+	p++;
+	/* Version */
+	if (*p++ != 0x2)
+		{
+		PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER);
+		return 0;
+		}
+	/* Ignore reserved, aiKeyAlg */
+	p+= 6;
+	*pmagic = read_ledword(&p);
+	*pbitlen = read_ledword(&p);
+	*pisdss = 0;
+	switch (*pmagic)
+		{
+
+		case MS_DSS1MAGIC:
+		*pisdss = 1;
+		case MS_RSA1MAGIC:
+		if (*pispub == 0)
+			{
+			PEMerr(PEM_F_DO_BLOB_HEADER,
+					PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
+			return 0;
+			}
+		break;
+
+		case MS_DSS2MAGIC:
+		*pisdss = 1;
+		case MS_RSA2MAGIC:
+		if (*pispub == 1)
+			{
+			PEMerr(PEM_F_DO_BLOB_HEADER,
+					PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
+			return 0;
+			}
+		break;
+
+		default:
+		PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER);
+		return -1;
+		}
+	*in = p;
+	return 1;
+	}
+
+static unsigned int blob_length(unsigned bitlen, int isdss, int ispub)
+	{
+	unsigned int nbyte, hnbyte;
+	nbyte = (bitlen + 7) >> 3;
+	hnbyte = (bitlen + 15) >> 4;
+	if (isdss)
+		{
+
+		/* Expected length: 20 for q + 3 components bitlen each + 24
+		 * for seed structure.
+		 */
+		if (ispub)
+			return  44 + 3 * nbyte;
+		/* Expected length: 20 for q, priv, 2 bitlen components + 24
+		 * for seed structure.
+		 */
+		else
+			return 64 + 2 * nbyte;
+		}
+	else
+		{
+		/* Expected length: 4 for 'e' + 'n' */
+		if (ispub)
+			return 4 + nbyte;
+		else
+		/* Expected length: 4 for 'e' and 7 other components.
+		 * 2 components are bitlen size, 5 are bitlen/2
+		 */
+			return 4 + 2*nbyte + 5*hnbyte;
+		}
+
+	}
+
+static EVP_PKEY *do_b2i(const unsigned char **in, unsigned int length,
+								int ispub)
+	{
+	const unsigned char *p = *in;
+	unsigned int bitlen, magic;
+	int isdss;
+	if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0)
+		{
+		PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_HEADER_PARSE_ERROR);
+		return NULL;
+		}
+	length -= 16;
+	if (length < blob_length(bitlen, isdss, ispub))
+		{
+		PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_TOO_SHORT);
+		return NULL;
+		}
+	if (isdss)
+		return b2i_dss(&p, length, bitlen, ispub);
+	else
+		return b2i_rsa(&p, length, bitlen, ispub);
+	}
+
+static EVP_PKEY *do_b2i_bio(BIO *in, int ispub)
+	{
+	const unsigned char *p;
+	unsigned char hdr_buf[16], *buf = NULL;
+	unsigned int bitlen, magic, length;
+	int isdss;
+	EVP_PKEY *ret = NULL;
+	if (BIO_read(in, hdr_buf, 16) != 16)
+		{
+		PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
+		return NULL;
+		}
+	p = hdr_buf;
+	if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0)
+		return NULL;
+
+	length = blob_length(bitlen, isdss, ispub);
+	buf = OPENSSL_malloc(length);
+	if (!buf)
+		{
+		PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	p = buf;
+	if (BIO_read(in, buf, length) != (int)length)
+		{
+		PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
+		goto err;
+		}
+
+	if (isdss)
+		ret = b2i_dss(&p, length, bitlen, ispub);
+	else
+		ret = b2i_rsa(&p, length, bitlen, ispub);
+
+	err:
+	if (buf)
+		OPENSSL_free(buf);
+	return ret;
+	}
+
+static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length,
+						unsigned int bitlen, int ispub)
+	{
+	const unsigned char *p = *in;
+	EVP_PKEY *ret = NULL;
+	DSA *dsa = NULL;
+	BN_CTX *ctx = NULL;
+	unsigned int nbyte;
+	nbyte = (bitlen + 7) >> 3;
+
+	dsa = DSA_new();
+	ret = EVP_PKEY_new();
+	if (!dsa || !ret)
+		goto memerr;
+	if (!read_lebn(&p, nbyte, &dsa->p))
+		goto memerr;
+	if (!read_lebn(&p, 20, &dsa->q))
+		goto memerr;
+	if (!read_lebn(&p, nbyte, &dsa->g))
+		goto memerr;
+	if (ispub)
+		{
+		if (!read_lebn(&p, nbyte, &dsa->pub_key))
+			goto memerr;
+		}
+	else
+		{
+		if (!read_lebn(&p, 20, &dsa->priv_key))
+			goto memerr;
+		/* Calculate public key */
+		if (!(dsa->pub_key = BN_new()))
+			goto memerr;
+		if (!(ctx = BN_CTX_new()))
+			goto memerr;
+			
+		if (!BN_mod_exp(dsa->pub_key, dsa->g,
+						 dsa->priv_key, dsa->p, ctx))
+			
+			goto memerr;
+		BN_CTX_free(ctx);
+		}
+
+	EVP_PKEY_set1_DSA(ret, dsa);
+	DSA_free(dsa);
+	*in = p;
+	return ret;
+
+	memerr:
+	PEMerr(PEM_F_B2I_DSS, ERR_R_MALLOC_FAILURE);
+	if (dsa)
+		DSA_free(dsa);
+	if (ret)
+		EVP_PKEY_free(ret);
+	if (ctx)
+		BN_CTX_free(ctx);
+	return NULL;
+	}
+
+static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length,
+						unsigned int bitlen, int ispub)
+		
+	{
+	const unsigned char *p = *in;
+	EVP_PKEY *ret = NULL;
+	RSA *rsa = NULL;
+	unsigned int nbyte, hnbyte;
+	nbyte = (bitlen + 7) >> 3;
+	hnbyte = (bitlen + 15) >> 4;
+	rsa = RSA_new();
+	ret = EVP_PKEY_new();
+	if (!rsa || !ret)
+		goto memerr;
+	rsa->e = BN_new();
+	if (!rsa->e)
+		goto memerr;
+	if (!BN_set_word(rsa->e, read_ledword(&p)))
+		goto memerr;
+	if (!read_lebn(&p, nbyte, &rsa->n))
+		goto memerr;
+	if (!ispub)
+		{
+		if (!read_lebn(&p, hnbyte, &rsa->p))
+			goto memerr;
+		if (!read_lebn(&p, hnbyte, &rsa->q))
+			goto memerr;
+		if (!read_lebn(&p, hnbyte, &rsa->dmp1))
+			goto memerr;
+		if (!read_lebn(&p, hnbyte, &rsa->dmq1))
+			goto memerr;
+		if (!read_lebn(&p, hnbyte, &rsa->iqmp))
+			goto memerr;
+		if (!read_lebn(&p, nbyte, &rsa->d))
+			goto memerr;
+		}
+
+	EVP_PKEY_set1_RSA(ret, rsa);
+	RSA_free(rsa);
+	*in = p;
+	return ret;
+	memerr:
+	PEMerr(PEM_F_B2I_RSA, ERR_R_MALLOC_FAILURE);
+	if (rsa)
+		RSA_free(rsa);
+	if (ret)
+		EVP_PKEY_free(ret);
+	return NULL;
+	}
+
+EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length)
+	{
+	return do_b2i(in, length, 0);
+	}
+
+EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length)
+	{
+	return do_b2i(in, length, 1);
+	}
+
+
+EVP_PKEY *b2i_PrivateKey_bio(BIO *in)
+	{
+	return do_b2i_bio(in, 0);
+	}
+
+EVP_PKEY *b2i_PublicKey_bio(BIO *in)
+	{
+	return do_b2i_bio(in, 1);
+	}
+
+static void write_ledword(unsigned char **out, unsigned int dw)
+	{
+	unsigned char *p = *out;
+	*p++ = dw & 0xff;
+	*p++ = (dw>>8) & 0xff;
+	*p++ = (dw>>16) & 0xff;
+	*p++ = (dw>>24) & 0xff;
+	*out = p;
+	}
+
+static void write_lebn(unsigned char **out, const BIGNUM *bn, int len)
+	{
+	int nb, i;
+	unsigned char *p = *out, *q, c;
+	nb = BN_num_bytes(bn);
+	BN_bn2bin(bn, p);
+	q = p + nb - 1;
+	/* In place byte order reversal */
+	for (i = 0; i < nb/2; i++)
+		{
+		c = *p;
+		*p++ = *q;
+		*q-- = c;
+		}
+	*out += nb;
+	/* Pad with zeroes if we have to */
+	if (len > 0)
+		{
+		len -= nb;
+		if (len > 0)
+			{
+			memset(*out, 0, len);
+			*out += len;
+			}
+		}
+	}
+
+
+static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic);
+static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic);
+
+static void write_rsa(unsigned char **out, RSA *rsa, int ispub);
+static void write_dsa(unsigned char **out, DSA *dsa, int ispub);
+	
+static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub)
+	{
+	unsigned char *p;
+	unsigned int bitlen, magic = 0, keyalg;
+	int outlen, noinc = 0;
+	if (pk->type == EVP_PKEY_DSA)
+		{
+		bitlen = check_bitlen_dsa(pk->pkey.dsa, ispub, &magic);
+		keyalg = MS_KEYALG_DSS_SIGN;
+		}
+	else if (pk->type == EVP_PKEY_RSA)
+		{
+		bitlen = check_bitlen_rsa(pk->pkey.rsa, ispub, &magic);
+		keyalg = MS_KEYALG_RSA_KEYX;
+		}
+	else
+		return -1;
+	if (bitlen == 0)
+		return -1;
+	outlen = 16 + blob_length(bitlen,
+			keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub);
+	if (out == NULL)
+		return outlen;
+	if (*out)
+		p = *out;
+	else
+		{
+		p = OPENSSL_malloc(outlen);
+		if (!p)
+			return -1;
+		*out = p;
+		noinc = 1;
+		}
+	if (ispub)
+		*p++ = MS_PUBLICKEYBLOB;
+	else
+		*p++ = MS_PRIVATEKEYBLOB;
+	*p++ = 0x2;
+	*p++ = 0;
+	*p++ = 0;
+	write_ledword(&p, keyalg);
+	write_ledword(&p, magic);
+	write_ledword(&p, bitlen);
+	if (keyalg == MS_KEYALG_DSS_SIGN)
+		write_dsa(&p, pk->pkey.dsa, ispub);
+	else
+		write_rsa(&p, pk->pkey.rsa, ispub);
+	if (!noinc)
+		*out += outlen;
+	return outlen;
+	}
+
+static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub)
+	{
+	unsigned char *tmp = NULL;
+	int outlen, wrlen;
+	outlen = do_i2b(&tmp, pk, ispub);
+	if (outlen < 0)
+		return -1;
+	wrlen = BIO_write(out, tmp, outlen);
+	OPENSSL_free(tmp);
+	if (wrlen == outlen)
+		return outlen;
+	return -1;
+	}
+
+static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic)
+	{
+	int bitlen;
+	bitlen = BN_num_bits(dsa->p);
+	if ((bitlen & 7) || (BN_num_bits(dsa->q) != 160)
+		|| (BN_num_bits(dsa->g) > bitlen))
+		goto badkey;
+	if (ispub)
+		{
+		if (BN_num_bits(dsa->pub_key) > bitlen)
+			goto badkey;
+		*pmagic = MS_DSS1MAGIC;
+		}
+	else
+		{
+		if (BN_num_bits(dsa->priv_key) > 160)
+			goto badkey;
+		*pmagic = MS_DSS2MAGIC;
+		}
+	
+	return bitlen;
+	badkey:
+	PEMerr(PEM_F_CHECK_BITLEN_DSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
+	return 0;
+	}
+
+static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic)
+	{
+	int nbyte, hnbyte, bitlen;
+	if (BN_num_bits(rsa->e) > 32)
+		goto badkey;
+	bitlen = BN_num_bits(rsa->n);
+	nbyte = BN_num_bytes(rsa->n);
+	hnbyte = (BN_num_bits(rsa->n) + 15) >> 4;
+	if (ispub)
+		{
+		*pmagic = MS_RSA1MAGIC;
+		return bitlen;
+		}
+	else
+	{
+		*pmagic = MS_RSA2MAGIC;
+		/* For private key each component must fit within nbyte or
+		 * hnbyte.
+		 */
+		if (BN_num_bytes(rsa->d) > nbyte)
+			goto badkey;
+		if ((BN_num_bytes(rsa->iqmp) > hnbyte)
+			|| (BN_num_bytes(rsa->p) > hnbyte)
+			|| (BN_num_bytes(rsa->q) > hnbyte)
+			|| (BN_num_bytes(rsa->dmp1) > hnbyte)
+			|| (BN_num_bytes(rsa->dmq1) > hnbyte))
+			goto badkey;
+	}
+	return bitlen;
+	badkey:
+	PEMerr(PEM_F_CHECK_BITLEN_RSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
+	return 0;
+	}
+
+
+static void write_rsa(unsigned char **out, RSA *rsa, int ispub)
+	{
+	int nbyte, hnbyte;
+	nbyte = BN_num_bytes(rsa->n);
+	hnbyte = (BN_num_bits(rsa->n) + 15) >> 4;
+	write_lebn(out, rsa->e, 4);
+	write_lebn(out, rsa->n, -1);
+	if (ispub)
+		return;
+	write_lebn(out, rsa->p, hnbyte);
+	write_lebn(out, rsa->q, hnbyte);
+	write_lebn(out, rsa->dmp1, hnbyte);
+	write_lebn(out, rsa->dmq1, hnbyte);
+	write_lebn(out, rsa->iqmp, hnbyte);
+	write_lebn(out, rsa->d, nbyte);
+	}
+
+	
+static void write_dsa(unsigned char **out, DSA *dsa, int ispub)
+	{
+	int nbyte;
+	nbyte = BN_num_bytes(dsa->p);
+	write_lebn(out, dsa->p, nbyte);
+	write_lebn(out, dsa->q, 20);
+	write_lebn(out, dsa->g, nbyte);
+	if (ispub)
+		write_lebn(out, dsa->pub_key, nbyte);
+	else
+		write_lebn(out, dsa->priv_key, 20);
+	/* Set "invalid" for seed structure values */
+	memset(*out, 0xff, 24);
+	*out += 24;
+	return;
+	}
+	
+
+int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk)
+	{
+	return do_i2b_bio(out, pk, 0);
+	}
+
+int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk)
+	{
+	return do_i2b_bio(out, pk, 1);
+	}
+
+#ifndef OPENSSL_NO_RC4
+
+static int do_PVK_header(const unsigned char **in, unsigned int length,
+		int skip_magic,
+	       	unsigned int *psaltlen, unsigned int *pkeylen)
+		
+	{
+	const unsigned char *p = *in;
+	unsigned int pvk_magic, is_encrypted;
+	if (skip_magic)
+		{
+		if (length < 20)
+			{
+			PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
+			return 0;
+			}
+		length -= 20;
+		}
+	else
+		{
+		if (length < 24)
+			{
+			PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
+			return 0;
+			}
+		length -= 24;
+		pvk_magic = read_ledword(&p);
+		if (pvk_magic != MS_PVKMAGIC)
+			{
+			PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER);
+			return 0;
+			}
+		}
+	/* Skip reserved */
+	p += 4;
+	/*keytype = */read_ledword(&p);
+	is_encrypted = read_ledword(&p);
+	*psaltlen = read_ledword(&p);
+	*pkeylen = read_ledword(&p);
+
+	if (is_encrypted && !*psaltlen)
+		{
+		PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER);
+		return 0;
+		}
+
+	*in = p;
+	return 1;
+	}
+
+static int derive_pvk_key(unsigned char *key, 
+			const unsigned char *salt, unsigned int saltlen,
+			const unsigned char *pass, int passlen)
+	{
+	EVP_MD_CTX mctx;
+	EVP_MD_CTX_init(&mctx);
+	EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL);
+	EVP_DigestUpdate(&mctx, salt, saltlen);
+	EVP_DigestUpdate(&mctx, pass, passlen);
+	EVP_DigestFinal_ex(&mctx, key, NULL);
+	EVP_MD_CTX_cleanup(&mctx);
+	return 1;
+	}
+	
+
+static EVP_PKEY *do_PVK_body(const unsigned char **in,
+		unsigned int saltlen, unsigned int keylen,
+		pem_password_cb *cb, void *u)
+	{
+	EVP_PKEY *ret = NULL;
+	const unsigned char *p = *in;
+	unsigned int magic;
+	unsigned char *enctmp = NULL, *q;
+	if (saltlen)
+		{
+		char psbuf[PEM_BUFSIZE];
+		unsigned char keybuf[20];
+		EVP_CIPHER_CTX cctx;
+		int enctmplen, inlen;
+		if (cb)
+			inlen=cb(psbuf,PEM_BUFSIZE,0,u);
+		else
+			inlen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u);
+		if (inlen <= 0)
+			{
+			PEMerr(PEM_F_DO_PVK_BODY,PEM_R_BAD_PASSWORD_READ);
+			return NULL;
+			}
+		enctmp = OPENSSL_malloc(keylen + 8);
+		if (!enctmp)
+			{
+			PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE);
+			return NULL;
+			}
+		if (!derive_pvk_key(keybuf, p, saltlen,
+			    (unsigned char *)psbuf, inlen))
+			return NULL;
+		p += saltlen;
+		/* Copy BLOBHEADER across, decrypt rest */
+		memcpy(enctmp, p, 8);
+		p += 8;
+		inlen = keylen - 8;
+		q = enctmp + 8;
+		EVP_CIPHER_CTX_init(&cctx);
+		EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL);
+		EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen);
+		EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen);
+		magic = read_ledword((const unsigned char **)&q);
+		if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC)
+			{
+			q = enctmp + 8;
+			memset(keybuf + 5, 0, 11);
+			EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf,
+								NULL);
+			OPENSSL_cleanse(keybuf, 20);
+			EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen);
+			EVP_DecryptFinal_ex(&cctx, q + enctmplen,
+								&enctmplen);
+			magic = read_ledword((const unsigned char **)&q);
+			if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC)
+				{
+				EVP_CIPHER_CTX_cleanup(&cctx);
+				PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT);
+				goto err;
+				}
+			}
+		else
+			OPENSSL_cleanse(keybuf, 20);
+		EVP_CIPHER_CTX_cleanup(&cctx);
+		p = enctmp;
+		}
+
+	ret = b2i_PrivateKey(&p, keylen);
+	err:
+	if (enctmp && saltlen)
+		OPENSSL_free(enctmp);
+	return ret;
+	}
+
+
+EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
+	{
+	unsigned char pvk_hdr[24], *buf = NULL;
+	const unsigned char *p;
+	int buflen;
+	EVP_PKEY *ret = NULL;
+	unsigned int saltlen, keylen;
+	if (BIO_read(in, pvk_hdr, 24) != 24)
+		{
+		PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT);
+		return NULL;
+		}
+	p = pvk_hdr;
+
+	if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen))
+		return 0;
+	buflen = (int) keylen + saltlen;
+	buf = OPENSSL_malloc(buflen);
+	if (!buf)
+		{
+		PEMerr(PEM_F_B2I_PVK_BIO, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	p = buf;
+	if (BIO_read(in, buf, buflen) != buflen)
+		{
+		PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT);
+		goto err;
+		}
+	ret = do_PVK_body(&p, saltlen, keylen, cb, u);
+
+	err:
+	if (buf)
+		{
+		OPENSSL_cleanse(buf, buflen);
+		OPENSSL_free(buf);
+		}
+	return ret;
+	}
+
+	
+	
+static int i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel,
+		pem_password_cb *cb, void *u)
+	{
+	int outlen = 24, pklen;
+	unsigned char *p, *salt = NULL;
+	if (enclevel)
+		outlen += PVK_SALTLEN;
+	pklen = do_i2b(NULL, pk, 0);
+	if (pklen < 0)
+		return -1;
+	outlen += pklen;
+	if (!out)
+		return outlen;
+	if (*out)
+		p = *out;
+	else
+		{
+		p = OPENSSL_malloc(outlen);
+		if (!p)
+			{
+			PEMerr(PEM_F_I2B_PVK,ERR_R_MALLOC_FAILURE);
+			return -1;
+			}
+		*out = p;
+		}
+
+	write_ledword(&p, MS_PVKMAGIC);
+	write_ledword(&p, 0);
+	if (pk->type == EVP_PKEY_DSA)
+		write_ledword(&p, MS_KEYTYPE_SIGN);
+	else
+		write_ledword(&p, MS_KEYTYPE_KEYX);
+	write_ledword(&p, enclevel ? 1 : 0);
+	write_ledword(&p, enclevel ? PVK_SALTLEN: 0);
+	write_ledword(&p, pklen);
+	if (enclevel)
+		{
+		if (RAND_bytes(p, PVK_SALTLEN) <= 0)
+			goto error;
+		salt = p;
+		p += PVK_SALTLEN;
+		}
+	do_i2b(&p, pk, 0);
+	if (enclevel == 0)
+		return outlen;
+	else
+		{
+		char psbuf[PEM_BUFSIZE];
+		unsigned char keybuf[20];
+		EVP_CIPHER_CTX cctx;
+		int enctmplen, inlen;
+		if (cb)
+			inlen=cb(psbuf,PEM_BUFSIZE,1,u);
+		else
+			inlen=PEM_def_callback(psbuf,PEM_BUFSIZE,1,u);
+		if (inlen <= 0)
+			{
+			PEMerr(PEM_F_I2B_PVK,PEM_R_BAD_PASSWORD_READ);
+			goto error;
+			}
+		if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN,
+			    (unsigned char *)psbuf, inlen))
+			goto error;
+		if (enclevel == 1)
+			memset(keybuf + 5, 0, 11);
+		p = salt + PVK_SALTLEN + 8;
+		EVP_CIPHER_CTX_init(&cctx);
+		EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL);
+		OPENSSL_cleanse(keybuf, 20);
+		EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8);
+		EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen);
+		EVP_CIPHER_CTX_cleanup(&cctx);
+		}
+	return outlen;
+
+	error:
+	return -1;
+	}
+
+int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
+		pem_password_cb *cb, void *u)
+	{
+	unsigned char *tmp = NULL;
+	int outlen, wrlen;
+	outlen = i2b_PVK(&tmp, pk, enclevel, cb, u);
+	if (outlen < 0)
+		return -1;
+	wrlen = BIO_write(out, tmp, outlen);
+	OPENSSL_free(tmp);
+	if (wrlen == outlen)
+		{
+		PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE);
+		return outlen;
+		}
+	return -1;
+	}
+
+#endif
+
+#endif
diff --git a/openssl/crypto/perlasm/cbc.pl b/openssl/crypto/perlasm/cbc.pl
new file mode 100644
index 0000000..6fc2510
--- /dev/null
+++ b/openssl/crypto/perlasm/cbc.pl
@@ -0,0 +1,349 @@
+#!/usr/local/bin/perl
+
+# void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
+# des_cblock (*input);
+# des_cblock (*output);
+# long length;
+# des_key_schedule schedule;
+# des_cblock (*ivec);
+# int enc;
+#
+# calls 
+# des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
+#
+
+#&cbc("des_ncbc_encrypt","des_encrypt",0);
+#&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",
+#	1,4,5,3,5,-1);
+#&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",
+#	0,4,5,3,5,-1);
+#&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",
+#	0,6,7,3,4,5);
+#
+# When doing a cipher that needs bigendian order,
+# for encrypt, the iv is kept in bigendian form,
+# while for decrypt, it is kept in little endian.
+sub cbc
+	{
+	local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_;
+	# name is the function name
+	# enc_func and dec_func and the functions to call for encrypt/decrypt
+	# swap is true if byte order needs to be reversed
+	# iv_off is parameter number for the iv 
+	# enc_off is parameter number for the encrypt/decrypt flag
+	# p1,p2,p3 are the offsets for parameters to be passed to the
+	# underlying calls.
+
+	&function_begin_B($name,"");
+	&comment("");
+
+	$in="esi";
+	$out="edi";
+	$count="ebp";
+
+	&push("ebp");
+	&push("ebx");
+	&push("esi");
+	&push("edi");
+
+	$data_off=4;
+	$data_off+=4 if ($p1 > 0);
+	$data_off+=4 if ($p2 > 0);
+	$data_off+=4 if ($p3 > 0);
+
+	&mov($count,	&wparam(2));	# length
+
+	&comment("getting iv ptr from parameter $iv_off");
+	&mov("ebx",	&wparam($iv_off));	# Get iv ptr
+
+	&mov($in,	&DWP(0,"ebx","",0));#	iv[0]
+	&mov($out,	&DWP(4,"ebx","",0));#	iv[1]
+
+	&push($out);
+	&push($in);
+	&push($out);	# used in decrypt for iv[1]
+	&push($in);	# used in decrypt for iv[0]
+
+	&mov("ebx",	"esp");		# This is the address of tin[2]
+
+	&mov($in,	&wparam(0));	# in
+	&mov($out,	&wparam(1));	# out
+
+	# We have loaded them all, how lets push things
+	&comment("getting encrypt flag from parameter $enc_off");
+	&mov("ecx",	&wparam($enc_off));	# Get enc flag
+	if ($p3 > 0)
+		{
+		&comment("get and push parameter $p3");
+		if ($enc_off != $p3)
+			{ &mov("eax",	&wparam($p3)); &push("eax"); }
+		else	{ &push("ecx"); }
+		}
+	if ($p2 > 0)
+		{
+		&comment("get and push parameter $p2");
+		if ($enc_off != $p2)
+			{ &mov("eax",	&wparam($p2)); &push("eax"); }
+		else	{ &push("ecx"); }
+		}
+	if ($p1 > 0)
+		{
+		&comment("get and push parameter $p1");
+		if ($enc_off != $p1)
+			{ &mov("eax",	&wparam($p1)); &push("eax"); }
+		else	{ &push("ecx"); }
+		}
+	&push("ebx");		# push data/iv
+
+	&cmp("ecx",0);
+	&jz(&label("decrypt"));
+
+	&and($count,0xfffffff8);
+	&mov("eax",	&DWP($data_off,"esp","",0));	# load iv[0]
+	&mov("ebx",	&DWP($data_off+4,"esp","",0));	# load iv[1]
+
+	&jz(&label("encrypt_finish"));
+
+	#############################################################
+
+	&set_label("encrypt_loop");
+	# encrypt start 
+	# "eax" and "ebx" hold iv (or the last cipher text)
+
+	&mov("ecx",	&DWP(0,$in,"",0));	# load first 4 bytes
+	&mov("edx",	&DWP(4,$in,"",0));	# second 4 bytes
+
+	&xor("eax",	"ecx");
+	&xor("ebx",	"edx");
+
+	&bswap("eax")	if $swap;
+	&bswap("ebx")	if $swap;
+
+	&mov(&DWP($data_off,"esp","",0),	"eax");	# put in array for call
+	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
+
+	&call($enc_func);
+
+	&mov("eax",	&DWP($data_off,"esp","",0));
+	&mov("ebx",	&DWP($data_off+4,"esp","",0));
+
+	&bswap("eax")	if $swap;
+	&bswap("ebx")	if $swap;
+
+	&mov(&DWP(0,$out,"",0),"eax");
+	&mov(&DWP(4,$out,"",0),"ebx");
+
+	# eax and ebx are the next iv.
+
+	&add($in,	8);
+	&add($out,	8);
+
+	&sub($count,	8);
+	&jnz(&label("encrypt_loop"));
+
+###################################################################3
+	&set_label("encrypt_finish");
+	&mov($count,	&wparam(2));	# length
+	&and($count,	7);
+	&jz(&label("finish"));
+	&call(&label("PIC_point"));
+&set_label("PIC_point");
+	&blindpop("edx");
+	&lea("ecx",&DWP(&label("cbc_enc_jmp_table")."-".&label("PIC_point"),"edx"));
+	&mov($count,&DWP(0,"ecx",$count,4))
+	&add($count,"edx");
+	&xor("ecx","ecx");
+	&xor("edx","edx");
+	#&mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4));
+	&jmp_ptr($count);
+
+&set_label("ej7");
+	&movb(&HB("edx"),	&BP(6,$in,"",0));
+	&shl("edx",8);
+&set_label("ej6");
+	&movb(&HB("edx"),	&BP(5,$in,"",0));
+&set_label("ej5");
+	&movb(&LB("edx"),	&BP(4,$in,"",0));
+&set_label("ej4");
+	&mov("ecx",		&DWP(0,$in,"",0));
+	&jmp(&label("ejend"));
+&set_label("ej3");
+	&movb(&HB("ecx"),	&BP(2,$in,"",0));
+	&shl("ecx",8);
+&set_label("ej2");
+	&movb(&HB("ecx"),	&BP(1,$in,"",0));
+&set_label("ej1");
+	&movb(&LB("ecx"),	&BP(0,$in,"",0));
+&set_label("ejend");
+
+	&xor("eax",	"ecx");
+	&xor("ebx",	"edx");
+
+	&bswap("eax")	if $swap;
+	&bswap("ebx")	if $swap;
+
+	&mov(&DWP($data_off,"esp","",0),	"eax");	# put in array for call
+	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
+
+	&call($enc_func);
+
+	&mov("eax",	&DWP($data_off,"esp","",0));
+	&mov("ebx",	&DWP($data_off+4,"esp","",0));
+
+	&bswap("eax")	if $swap;
+	&bswap("ebx")	if $swap;
+
+	&mov(&DWP(0,$out,"",0),"eax");
+	&mov(&DWP(4,$out,"",0),"ebx");
+
+	&jmp(&label("finish"));
+
+	#############################################################
+	#############################################################
+	&set_label("decrypt",1);
+	# decrypt start 
+	&and($count,0xfffffff8);
+	# The next 2 instructions are only for if the jz is taken
+	&mov("eax",	&DWP($data_off+8,"esp","",0));	# get iv[0]
+	&mov("ebx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
+	&jz(&label("decrypt_finish"));
+
+	&set_label("decrypt_loop");
+	&mov("eax",	&DWP(0,$in,"",0));	# load first 4 bytes
+	&mov("ebx",	&DWP(4,$in,"",0));	# second 4 bytes
+
+	&bswap("eax")	if $swap;
+	&bswap("ebx")	if $swap;
+
+	&mov(&DWP($data_off,"esp","",0),	"eax");	# put back
+	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
+
+	&call($dec_func);
+
+	&mov("eax",	&DWP($data_off,"esp","",0));	# get return
+	&mov("ebx",	&DWP($data_off+4,"esp","",0));	#
+
+	&bswap("eax")	if $swap;
+	&bswap("ebx")	if $swap;
+
+	&mov("ecx",	&DWP($data_off+8,"esp","",0));	# get iv[0]
+	&mov("edx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
+
+	&xor("ecx",	"eax");
+	&xor("edx",	"ebx");
+
+	&mov("eax",	&DWP(0,$in,"",0));	# get old cipher text,
+	&mov("ebx",	&DWP(4,$in,"",0));	# next iv actually
+
+	&mov(&DWP(0,$out,"",0),"ecx");
+	&mov(&DWP(4,$out,"",0),"edx");
+
+	&mov(&DWP($data_off+8,"esp","",0),	"eax");	# save iv
+	&mov(&DWP($data_off+12,"esp","",0),	"ebx");	#
+
+	&add($in,	8);
+	&add($out,	8);
+
+	&sub($count,	8);
+	&jnz(&label("decrypt_loop"));
+############################ ENDIT #######################3
+	&set_label("decrypt_finish");
+	&mov($count,	&wparam(2));	# length
+	&and($count,	7);
+	&jz(&label("finish"));
+
+	&mov("eax",	&DWP(0,$in,"",0));	# load first 4 bytes
+	&mov("ebx",	&DWP(4,$in,"",0));	# second 4 bytes
+
+	&bswap("eax")	if $swap;
+	&bswap("ebx")	if $swap;
+
+	&mov(&DWP($data_off,"esp","",0),	"eax");	# put back
+	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
+
+	&call($dec_func);
+
+	&mov("eax",	&DWP($data_off,"esp","",0));	# get return
+	&mov("ebx",	&DWP($data_off+4,"esp","",0));	#
+
+	&bswap("eax")	if $swap;
+	&bswap("ebx")	if $swap;
+
+	&mov("ecx",	&DWP($data_off+8,"esp","",0));	# get iv[0]
+	&mov("edx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
+
+	&xor("ecx",	"eax");
+	&xor("edx",	"ebx");
+
+	# this is for when we exit
+	&mov("eax",	&DWP(0,$in,"",0));	# get old cipher text,
+	&mov("ebx",	&DWP(4,$in,"",0));	# next iv actually
+
+&set_label("dj7");
+	&rotr("edx",	16);
+	&movb(&BP(6,$out,"",0),	&LB("edx"));
+	&shr("edx",16);
+&set_label("dj6");
+	&movb(&BP(5,$out,"",0),	&HB("edx"));
+&set_label("dj5");
+	&movb(&BP(4,$out,"",0),	&LB("edx"));
+&set_label("dj4");
+	&mov(&DWP(0,$out,"",0),	"ecx");
+	&jmp(&label("djend"));
+&set_label("dj3");
+	&rotr("ecx",	16);
+	&movb(&BP(2,$out,"",0),	&LB("ecx"));
+	&shl("ecx",16);
+&set_label("dj2");
+	&movb(&BP(1,$in,"",0),	&HB("ecx"));
+&set_label("dj1");
+	&movb(&BP(0,$in,"",0),	&LB("ecx"));
+&set_label("djend");
+
+	# final iv is still in eax:ebx
+	&jmp(&label("finish"));
+
+
+############################ FINISH #######################3
+	&set_label("finish",1);
+	&mov("ecx",	&wparam($iv_off));	# Get iv ptr
+
+	#################################################
+	$total=16+4;
+	$total+=4 if ($p1 > 0);
+	$total+=4 if ($p2 > 0);
+	$total+=4 if ($p3 > 0);
+	&add("esp",$total);
+
+	&mov(&DWP(0,"ecx","",0),	"eax");	# save iv
+	&mov(&DWP(4,"ecx","",0),	"ebx");	# save iv
+
+	&function_end_A($name);
+
+	&align(64);
+	&set_label("cbc_enc_jmp_table");
+	&data_word("0");
+	&data_word(&label("ej1")."-".&label("PIC_point"));
+	&data_word(&label("ej2")."-".&label("PIC_point"));
+	&data_word(&label("ej3")."-".&label("PIC_point"));
+	&data_word(&label("ej4")."-".&label("PIC_point"));
+	&data_word(&label("ej5")."-".&label("PIC_point"));
+	&data_word(&label("ej6")."-".&label("PIC_point"));
+	&data_word(&label("ej7")."-".&label("PIC_point"));
+	# not used
+	#&set_label("cbc_dec_jmp_table",1);
+	#&data_word("0");
+	#&data_word(&label("dj1")."-".&label("PIC_point"));
+	#&data_word(&label("dj2")."-".&label("PIC_point"));
+	#&data_word(&label("dj3")."-".&label("PIC_point"));
+	#&data_word(&label("dj4")."-".&label("PIC_point"));
+	#&data_word(&label("dj5")."-".&label("PIC_point"));
+	#&data_word(&label("dj6")."-".&label("PIC_point"));
+	#&data_word(&label("dj7")."-".&label("PIC_point"));
+	&align(64);
+
+	&function_end_B($name);
+	
+	}
+
+1;
diff --git a/openssl/crypto/perlasm/ppc-xlate.pl b/openssl/crypto/perlasm/ppc-xlate.pl
new file mode 100644
index 0000000..4579671
--- /dev/null
+++ b/openssl/crypto/perlasm/ppc-xlate.pl
@@ -0,0 +1,152 @@
+#!/usr/bin/env perl
+
+# PowerPC assembler distiller by <appro>.
+
+my $flavour = shift;
+my $output = shift;
+open STDOUT,">$output" || die "can't open $output: $!";
+
+my %GLOBALS;
+my $dotinlocallabels=($flavour=~/linux/)?1:0;
+
+################################################################
+# directives which need special treatment on different platforms
+################################################################
+my $globl = sub {
+    my $junk = shift;
+    my $name = shift;
+    my $global = \$GLOBALS{$name};
+    my $ret;
+
+    $name =~ s|^[\.\_]||;
+ 
+    SWITCH: for ($flavour) {
+	/aix/		&& do { $name = ".$name";
+				last;
+			      };
+	/osx/		&& do { $name = "_$name";
+				last;
+			      };
+	/linux.*32/	&& do {	$ret .= ".globl	$name\n";
+				$ret .= ".type	$name,\@function";
+				last;
+			      };
+	/linux.*64/	&& do {	$ret .= ".globl	.$name\n";
+				$ret .= ".type	.$name,\@function\n";
+				$ret .= ".section	\".opd\",\"aw\"\n";
+				$ret .= ".globl	$name\n";
+				$ret .= ".align	3\n";
+				$ret .= "$name:\n";
+				$ret .= ".quad	.$name,.TOC.\@tocbase,0\n";
+				$ret .= ".size	$name,24\n";
+				$ret .= ".previous\n";
+
+				$name = ".$name";
+				last;
+			      };
+    }
+
+    $ret = ".globl	$name" if (!$ret);
+    $$global = $name;
+    $ret;
+};
+my $text = sub {
+    ($flavour =~ /aix/) ? ".csect" : ".text";
+};
+my $machine = sub {
+    my $junk = shift;
+    my $arch = shift;
+    if ($flavour =~ /osx/)
+    {	$arch =~ s/\"//g;
+	$arch = ($flavour=~/64/) ? "ppc970-64" : "ppc970" if ($arch eq "any");
+    }
+    ".machine	$arch";
+};
+my $asciz = sub {
+    shift;
+    my $line = join(",",@_);
+    if ($line =~ /^"(.*)"$/)
+    {	".byte	" . join(",",unpack("C*",$1),0) . "\n.align	2";	}
+    else
+    {	"";	}
+};
+
+################################################################
+# simplified mnemonics not handled by at least one assembler
+################################################################
+my $cmplw = sub {
+    my $f = shift;
+    my $cr = 0; $cr = shift if ($#_>1);
+    # Some out-of-date 32-bit GNU assembler just can't handle cmplw...
+    ($flavour =~ /linux.*32/) ?
+	"	.long	".sprintf "0x%x",31<<26|$cr<<23|$_[0]<<16|$_[1]<<11|64 :
+	"	cmplw	".join(',',$cr,@_);
+};
+my $bdnz = sub {
+    my $f = shift;
+    my $bo = $f=~/[\+\-]/ ? 16+9 : 16;	# optional "to be taken" hint
+    "	bc	$bo,0,".shift;
+} if ($flavour!~/linux/);
+my $bltlr = sub {
+    my $f = shift;
+    my $bo = $f=~/\-/ ? 12+2 : 12;	# optional "not to be taken" hint
+    ($flavour =~ /linux/) ?		# GNU as doesn't allow most recent hints
+	"	.long	".sprintf "0x%x",19<<26|$bo<<21|16<<1 :
+	"	bclr	$bo,0";
+};
+my $bnelr = sub {
+    my $f = shift;
+    my $bo = $f=~/\-/ ? 4+2 : 4;	# optional "not to be taken" hint
+    ($flavour =~ /linux/) ?		# GNU as doesn't allow most recent hints
+	"	.long	".sprintf "0x%x",19<<26|$bo<<21|2<<16|16<<1 :
+	"	bclr	$bo,2";
+};
+my $beqlr = sub {
+    my $f = shift;
+    my $bo = $f=~/-/ ? 12+2 : 12;	# optional "not to be taken" hint
+    ($flavour =~ /linux/) ?		# GNU as doesn't allow most recent hints
+	"	.long	".sprintf "0x%X",19<<26|$bo<<21|2<<16|16<<1 :
+	"	bclr	$bo,2";
+};
+# GNU assembler can't handle extrdi rA,rS,16,48, or when sum of last two
+# arguments is 64, with "operand out of range" error.
+my $extrdi = sub {
+    my ($f,$ra,$rs,$n,$b) = @_;
+    $b = ($b+$n)&63; $n = 64-$n;
+    "	rldicl	$ra,$rs,$b,$n";
+};
+
+while($line=<>) {
+
+    $line =~ s|[#!;].*$||;	# get rid of asm-style comments...
+    $line =~ s|/\*.*\*/||;	# ... and C-style comments...
+    $line =~ s|^\s+||;		# ... and skip white spaces in beginning...
+    $line =~ s|\s+$||;		# ... and at the end
+
+    {
+	$line =~ s|\b\.L(\w+)|L$1|g;	# common denominator for Locallabel
+	$line =~ s|\bL(\w+)|\.L$1|g	if ($dotinlocallabels);
+    }
+
+    {
+	$line =~ s|(^[\.\w]+)\:\s*||;
+	my $label = $1;
+	printf "%s:",($GLOBALS{$label} or $label) if ($label);
+    }
+
+    {
+	$line =~ s|^\s*(\.?)(\w+)([\.\+\-]?)\s*||;
+	my $c = $1; $c = "\t" if ($c eq "");
+	my $mnemonic = $2;
+	my $f = $3;
+	my $opcode = eval("\$$mnemonic");
+	$line =~ s|\bc?[rf]([0-9]+)\b|$1|g if ($c ne "." and $flavour !~ /osx/);
+	if (ref($opcode) eq 'CODE') { $line = &$opcode($f,split(',',$line)); }
+	elsif ($mnemonic)           { $line = $c.$mnemonic.$f."\t".$line; }
+    }
+
+    print $line if ($line);
+    print "\n";
+}
+
+close STDOUT;
diff --git a/openssl/crypto/perlasm/readme b/openssl/crypto/perlasm/readme
new file mode 100644
index 0000000..f02bbee
--- /dev/null
+++ b/openssl/crypto/perlasm/readme
@@ -0,0 +1,124 @@
+The perl scripts in this directory are my 'hack' to generate
+multiple different assembler formats via the one origional script.
+
+The way to use this library is to start with adding the path to this directory
+and then include it.
+
+push(@INC,"perlasm","../../perlasm");
+require "x86asm.pl";
+
+The first thing we do is setup the file and type of assember
+
+&asm_init($ARGV[0],$0);
+
+The first argument is the 'type'.  Currently
+'cpp', 'sol', 'a.out', 'elf' or 'win32'.
+Argument 2 is the file name.
+
+The reciprocal function is
+&asm_finish() which should be called at the end.
+
+There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler,
+and x86unix.pl which is the unix (gas) version.
+
+Functions of interest are:
+&external_label("des_SPtrans");	declare and external variable
+&LB(reg);			Low byte for a register
+&HB(reg);			High byte for a register
+&BP(off,base,index,scale)	Byte pointer addressing
+&DWP(off,base,index,scale)	Word pointer addressing
+&stack_push(num)		Basically a 'sub esp, num*4' with extra
+&stack_pop(num)			inverse of stack_push
+&function_begin(name,extra)	Start a function with pushing of
+				edi, esi, ebx and ebp.  extra is extra win32
+				external info that may be required.
+&function_begin_B(name,extra)	Same as norma function_begin but no pushing.
+&function_end(name)		Call at end of function.
+&function_end_A(name)		Standard pop and ret, for use inside functions
+&function_end_B(name)		Call at end but with poping or 'ret'.
+&swtmp(num)			Address on stack temp word.
+&wparam(num)			Parameter number num, that was push
+				in C convention.  This all works over pushes
+				and pops.
+&comment("hello there")		Put in a comment.
+&label("loop")			Refer to a label, normally a jmp target.
+&set_label("loop")		Set a label at this point.
+&data_word(word)		Put in a word of data.
+
+So how does this all hold together?  Given
+
+int calc(int len, int *data)
+	{
+	int i,j=0;
+
+	for (i=0; i<len; i++)
+		{
+		j+=other(data[i]);
+		}
+	}
+
+So a very simple version of this function could be coded as
+
+	push(@INC,"perlasm","../../perlasm");
+	require "x86asm.pl";
+	
+	&asm_init($ARGV[0],"cacl.pl");
+
+	&external_label("other");
+
+	$tmp1=	"eax";
+	$j=	"edi";
+	$data=	"esi";
+	$i=	"ebp";
+
+	&comment("a simple function");
+	&function_begin("calc");
+	&mov(	$data,		&wparam(1)); # data
+	&xor(	$j,		$j);
+	&xor(	$i,		$i);
+
+	&set_label("loop");
+	&cmp(	$i,		&wparam(0));
+	&jge(	&label("end"));
+
+	&mov(	$tmp1,		&DWP(0,$data,$i,4));
+	&push(	$tmp1);
+	&call(	"other");
+	&add(	$j,		"eax");
+	&pop(	$tmp1);
+	&inc(	$i);
+	&jmp(	&label("loop"));
+
+	&set_label("end");
+	&mov(	"eax",		$j);
+
+	&function_end("calc");
+
+	&asm_finish();
+
+The above example is very very unoptimised but gives an idea of how
+things work.
+
+There is also a cbc mode function generator in cbc.pl
+
+&cbc(	$name,
+	$encrypt_function_name,
+	$decrypt_function_name,
+	$true_if_byte_swap_needed,
+	$parameter_number_for_iv,
+	$parameter_number_for_encrypt_flag,
+	$first_parameter_to_pass,
+	$second_parameter_to_pass,
+	$third_parameter_to_pass);
+
+So for example, given
+void BF_encrypt(BF_LONG *data,BF_KEY *key);
+void BF_decrypt(BF_LONG *data,BF_KEY *key);
+void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
+        BF_KEY *ks, unsigned char *iv, int enc);
+
+&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1);
+
+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
+
diff --git a/openssl/crypto/perlasm/x86_64-xlate.pl b/openssl/crypto/perlasm/x86_64-xlate.pl
new file mode 100755
index 0000000..e47116b
--- /dev/null
+++ b/openssl/crypto/perlasm/x86_64-xlate.pl
@@ -0,0 +1,917 @@
+#!/usr/bin/env perl
+
+# Ascetic x86_64 AT&T to MASM/NASM assembler translator by <appro>.
+#
+# Why AT&T to MASM and not vice versa? Several reasons. Because AT&T
+# format is way easier to parse. Because it's simpler to "gear" from
+# Unix ABI to Windows one [see cross-reference "card" at the end of
+# file]. Because Linux targets were available first...
+#
+# In addition the script also "distills" code suitable for GNU
+# assembler, so that it can be compiled with more rigid assemblers,
+# such as Solaris /usr/ccs/bin/as.
+#
+# This translator is not designed to convert *arbitrary* assembler
+# code from AT&T format to MASM one. It's designed to convert just
+# enough to provide for dual-ABI OpenSSL modules development...
+# There *are* limitations and you might have to modify your assembler
+# code or this script to achieve the desired result...
+#
+# Currently recognized limitations:
+#
+# - can't use multiple ops per line;
+#
+# Dual-ABI styling rules.
+#
+# 1. Adhere to Unix register and stack layout [see cross-reference
+#    ABI "card" at the end for explanation].
+# 2. Forget about "red zone," stick to more traditional blended
+#    stack frame allocation. If volatile storage is actually required
+#    that is. If not, just leave the stack as is.
+# 3. Functions tagged with ".type name,@function" get crafted with
+#    unified Win64 prologue and epilogue automatically. If you want
+#    to take care of ABI differences yourself, tag functions as
+#    ".type name,@abi-omnipotent" instead.
+# 4. To optimize the Win64 prologue you can specify number of input
+#    arguments as ".type name,@function,N." Keep in mind that if N is
+#    larger than 6, then you *have to* write "abi-omnipotent" code,
+#    because >6 cases can't be addressed with unified prologue.
+# 5. Name local labels as .L*, do *not* use dynamic labels such as 1:
+#    (sorry about latter).
+# 6. Don't use [or hand-code with .byte] "rep ret." "ret" mnemonic is
+#    required to identify the spots, where to inject Win64 epilogue!
+#    But on the pros, it's then prefixed with rep automatically:-)
+# 7. Stick to explicit ip-relative addressing. If you have to use
+#    GOTPCREL addressing, stick to mov symbol@GOTPCREL(%rip),%r??.
+#    Both are recognized and translated to proper Win64 addressing
+#    modes. To support legacy code a synthetic directive, .picmeup,
+#    is implemented. It puts address of the *next* instruction into
+#    target register, e.g.:
+#
+#		.picmeup	%rax
+#		lea		.Label-.(%rax),%rax
+#
+# 8. In order to provide for structured exception handling unified
+#    Win64 prologue copies %rsp value to %rax. For further details
+#    see SEH paragraph at the end.
+# 9. .init segment is allowed to contain calls to functions only.
+# a. If function accepts more than 4 arguments *and* >4th argument
+#    is declared as non 64-bit value, do clear its upper part.
+
+my $flavour = shift;
+my $output  = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+{ my ($stddev,$stdino,@junk)=stat(STDOUT);
+  my ($outdev,$outino,@junk)=stat($output);
+
+    open STDOUT,">$output" || die "can't open $output: $!"
+	if ($stddev!=$outdev || $stdino!=$outino);
+}
+
+my $gas=1;	$gas=0 if ($output =~ /\.asm$/);
+my $elf=1;	$elf=0 if (!$gas);
+my $win64=0;
+my $prefix="";
+my $decor=".L";
+
+my $masmref=8 + 50727*2**-32;	# 8.00.50727 shipped with VS2005
+my $masm=0;
+my $PTR=" PTR";
+
+my $nasmref=2.03;
+my $nasm=0;
+
+if    ($flavour eq "mingw64")	{ $gas=1; $elf=0; $win64=1;
+				  $prefix=`echo __USER_LABEL_PREFIX__ | $ENV{CC} -E -P -`;
+				  chomp($prefix);
+				}
+elsif ($flavour eq "macosx")	{ $gas=1; $elf=0; $prefix="_"; $decor="L\$"; }
+elsif ($flavour eq "masm")	{ $gas=0; $elf=0; $masm=$masmref; $win64=1; $decor="\$L\$"; }
+elsif ($flavour eq "nasm")	{ $gas=0; $elf=0; $nasm=$nasmref; $win64=1; $decor="\$L\$"; $PTR=""; }
+elsif (!$gas)
+{   if ($ENV{ASM} =~ m/nasm/ && `nasm -v` =~ m/version ([0-9]+)\.([0-9]+)/i)
+    {	$nasm = $1 + $2*0.01; $PTR="";  }
+    elsif (`ml64 2>&1` =~ m/Version ([0-9]+)\.([0-9]+)(\.([0-9]+))?/)
+    {	$masm = $1 + $2*2**-16 + $4*2**-32;   }
+    die "no assembler found on %PATH" if (!($nasm || $masm));
+    $win64=1;
+    $elf=0;
+    $decor="\$L\$";
+}
+
+my $current_segment;
+my $current_function;
+my %globals;
+
+{ package opcode;	# pick up opcodes
+    sub re {
+	my	$self = shift;	# single instance in enough...
+	local	*line = shift;
+	undef	$ret;
+
+	if ($line =~ /^([a-z][a-z0-9]*)/i) {
+	    $self->{op} = $1;
+	    $ret = $self;
+	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
+
+	    undef $self->{sz};
+	    if ($self->{op} =~ /^(movz)b.*/) {	# movz is pain...
+		$self->{op} = $1;
+		$self->{sz} = "b";
+	    } elsif ($self->{op} =~ /call|jmp/) {
+		$self->{sz} = "";
+	    } elsif ($self->{op} =~ /^p/ && $' !~ /^(ush|op)/) { # SSEn
+		$self->{sz} = "";
+	    } elsif ($self->{op} =~ /([a-z]{3,})([qlwb])$/) {
+		$self->{op} = $1;
+		$self->{sz} = $2;
+	    }
+	}
+	$ret;
+    }
+    sub size {
+	my $self = shift;
+	my $sz   = shift;
+	$self->{sz} = $sz if (defined($sz) && !defined($self->{sz}));
+	$self->{sz};
+    }
+    sub out {
+	my $self = shift;
+	if ($gas) {
+	    if ($self->{op} eq "movz") {	# movz is pain...
+		sprintf "%s%s%s",$self->{op},$self->{sz},shift;
+	    } elsif ($self->{op} =~ /^set/) { 
+		"$self->{op}";
+	    } elsif ($self->{op} eq "ret") {
+		my $epilogue = "";
+		if ($win64 && $current_function->{abi} eq "svr4") {
+		    $epilogue = "movq	8(%rsp),%rdi\n\t" .
+				"movq	16(%rsp),%rsi\n\t";
+		}
+	    	$epilogue . ".byte	0xf3,0xc3";
+	    } elsif ($self->{op} eq "call" && !$elf && $current_segment eq ".init") {
+		".p2align\t3\n\t.quad";
+	    } else {
+		"$self->{op}$self->{sz}";
+	    }
+	} else {
+	    $self->{op} =~ s/^movz/movzx/;
+	    if ($self->{op} eq "ret") {
+		$self->{op} = "";
+		if ($win64 && $current_function->{abi} eq "svr4") {
+		    $self->{op} = "mov	rdi,QWORD${PTR}[8+rsp]\t;WIN64 epilogue\n\t".
+				  "mov	rsi,QWORD${PTR}[16+rsp]\n\t";
+	    	}
+		$self->{op} .= "DB\t0F3h,0C3h\t\t;repret";
+	    } elsif ($self->{op} =~ /^(pop|push)f/) {
+		$self->{op} .= $self->{sz};
+	    } elsif ($self->{op} eq "call" && $current_segment eq ".CRT\$XCU") {
+		$self->{op} = "\tDQ";
+	    } 
+	    $self->{op};
+	}
+    }
+    sub mnemonic {
+	my $self=shift;
+	my $op=shift;
+	$self->{op}=$op if (defined($op));
+	$self->{op};
+    }
+}
+{ package const;	# pick up constants, which start with $
+    sub re {
+	my	$self = shift;	# single instance in enough...
+	local	*line = shift;
+	undef	$ret;
+
+	if ($line =~ /^\$([^,]+)/) {
+	    $self->{value} = $1;
+	    $ret = $self;
+	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
+	}
+	$ret;
+    }
+    sub out {
+    	my $self = shift;
+
+	if ($gas) {
+	    # Solaris /usr/ccs/bin/as can't handle multiplications
+	    # in $self->{value}
+	    $self->{value} =~ s/(?<![\w\$\.])(0x?[0-9a-f]+)/oct($1)/egi;
+	    $self->{value} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg;
+	    sprintf "\$%s",$self->{value};
+	} else {
+	    $self->{value} =~ s/(0b[0-1]+)/oct($1)/eig;
+	    $self->{value} =~ s/0x([0-9a-f]+)/0$1h/ig if ($masm);
+	    sprintf "%s",$self->{value};
+	}
+    }
+}
+{ package ea;		# pick up effective addresses: expr(%reg,%reg,scale)
+    sub re {
+	my	$self = shift;	# single instance in enough...
+	local	*line = shift;
+	undef	$ret;
+
+	# optional * ---vvv--- appears in indirect jmp/call
+	if ($line =~ /^(\*?)([^\(,]*)\(([%\w,]+)\)/) {
+	    $self->{asterisk} = $1;
+	    $self->{label} = $2;
+	    ($self->{base},$self->{index},$self->{scale})=split(/,/,$3);
+	    $self->{scale} = 1 if (!defined($self->{scale}));
+	    $ret = $self;
+	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
+
+	    if ($win64 && $self->{label} =~ s/\@GOTPCREL//) {
+		die if (opcode->mnemonic() ne "mov");
+		opcode->mnemonic("lea");
+	    }
+	    $self->{base}  =~ s/^%//;
+	    $self->{index} =~ s/^%// if (defined($self->{index}));
+	}
+	$ret;
+    }
+    sub size {}
+    sub out {
+    	my $self = shift;
+	my $sz = shift;
+
+	$self->{label} =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
+	$self->{label} =~ s/\.L/$decor/g;
+
+	# Silently convert all EAs to 64-bit. This is required for
+	# elder GNU assembler and results in more compact code,
+	# *but* most importantly AES module depends on this feature!
+	$self->{index} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/;
+	$self->{base}  =~ s/^[er](.?[0-9xpi])[d]?$/r\1/;
+
+	if ($gas) {
+	    # Solaris /usr/ccs/bin/as can't handle multiplications
+	    # in $self->{label}, new gas requires sign extension...
+	    use integer;
+	    $self->{label} =~ s/(?<![\w\$\.])(0x?[0-9a-f]+)/oct($1)/egi;
+	    $self->{label} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg;
+	    $self->{label} =~ s/([0-9]+)/$1<<32>>32/eg;
+	    $self->{label} =~ s/^___imp_/__imp__/   if ($flavour eq "mingw64");
+
+	    if (defined($self->{index})) {
+		sprintf "%s%s(%%%s,%%%s,%d)",$self->{asterisk},
+					$self->{label},$self->{base},
+					$self->{index},$self->{scale};
+	    } else {
+		sprintf "%s%s(%%%s)",	$self->{asterisk},$self->{label},$self->{base};
+	    }
+	} else {
+	    %szmap = ( b=>"BYTE$PTR", w=>"WORD$PTR", l=>"DWORD$PTR", q=>"QWORD$PTR" );
+
+	    $self->{label} =~ s/\./\$/g;
+	    $self->{label} =~ s/(?<![\w\$\.])0x([0-9a-f]+)/0$1h/ig;
+	    $self->{label} = "($self->{label})" if ($self->{label} =~ /[\*\+\-\/]/);
+	    $sz="q" if ($self->{asterisk});
+
+	    if (defined($self->{index})) {
+		sprintf "%s[%s%s*%d+%s]",$szmap{$sz},
+					$self->{label}?"$self->{label}+":"",
+					$self->{index},$self->{scale},
+					$self->{base};
+	    } elsif ($self->{base} eq "rip") {
+		sprintf "%s[%s]",$szmap{$sz},$self->{label};
+	    } else {
+		sprintf "%s[%s%s]",$szmap{$sz},
+					$self->{label}?"$self->{label}+":"",
+					$self->{base};
+	    }
+	}
+    }
+}
+{ package register;	# pick up registers, which start with %.
+    sub re {
+	my	$class = shift;	# muliple instances...
+	my	$self = {};
+	local	*line = shift;
+	undef	$ret;
+
+	# optional * ---vvv--- appears in indirect jmp/call
+	if ($line =~ /^(\*?)%(\w+)/) {
+	    bless $self,$class;
+	    $self->{asterisk} = $1;
+	    $self->{value} = $2;
+	    $ret = $self;
+	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
+	}
+	$ret;
+    }
+    sub size {
+	my	$self = shift;
+	undef	$ret;
+
+	if    ($self->{value} =~ /^r[\d]+b$/i)	{ $ret="b"; }
+	elsif ($self->{value} =~ /^r[\d]+w$/i)	{ $ret="w"; }
+	elsif ($self->{value} =~ /^r[\d]+d$/i)	{ $ret="l"; }
+	elsif ($self->{value} =~ /^r[\w]+$/i)	{ $ret="q"; }
+	elsif ($self->{value} =~ /^[a-d][hl]$/i){ $ret="b"; }
+	elsif ($self->{value} =~ /^[\w]{2}l$/i)	{ $ret="b"; }
+	elsif ($self->{value} =~ /^[\w]{2}$/i)	{ $ret="w"; }
+	elsif ($self->{value} =~ /^e[a-z]{2}$/i){ $ret="l"; }
+
+	$ret;
+    }
+    sub out {
+    	my $self = shift;
+	if ($gas)	{ sprintf "%s%%%s",$self->{asterisk},$self->{value}; }
+	else		{ $self->{value}; }
+    }
+}
+{ package label;	# pick up labels, which end with :
+    sub re {
+	my	$self = shift;	# single instance is enough...
+	local	*line = shift;
+	undef	$ret;
+
+	if ($line =~ /(^[\.\w]+)\:/) {
+	    $self->{value} = $1;
+	    $ret = $self;
+	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
+
+	    $self->{value} =~ s/^\.L/$decor/;
+	}
+	$ret;
+    }
+    sub out {
+	my $self = shift;
+
+	if ($gas) {
+	    my $func = ($globals{$self->{value}} or $self->{value}) . ":";
+	    if ($win64	&&
+			$current_function->{name} eq $self->{value} &&
+			$current_function->{abi} eq "svr4") {
+		$func .= "\n";
+		$func .= "	movq	%rdi,8(%rsp)\n";
+		$func .= "	movq	%rsi,16(%rsp)\n";
+		$func .= "	movq	%rsp,%rax\n";
+		$func .= "${decor}SEH_begin_$current_function->{name}:\n";
+		my $narg = $current_function->{narg};
+		$narg=6 if (!defined($narg));
+		$func .= "	movq	%rcx,%rdi\n" if ($narg>0);
+		$func .= "	movq	%rdx,%rsi\n" if ($narg>1);
+		$func .= "	movq	%r8,%rdx\n"  if ($narg>2);
+		$func .= "	movq	%r9,%rcx\n"  if ($narg>3);
+		$func .= "	movq	40(%rsp),%r8\n" if ($narg>4);
+		$func .= "	movq	48(%rsp),%r9\n" if ($narg>5);
+	    }
+	    $func;
+	} elsif ($self->{value} ne "$current_function->{name}") {
+	    $self->{value} .= ":" if ($masm && $ret!~m/^\$/);
+	    $self->{value} . ":";
+	} elsif ($win64 && $current_function->{abi} eq "svr4") {
+	    my $func =	"$current_function->{name}" .
+			($nasm ? ":" : "\tPROC $current_function->{scope}") .
+			"\n";
+	    $func .= "	mov	QWORD${PTR}[8+rsp],rdi\t;WIN64 prologue\n";
+	    $func .= "	mov	QWORD${PTR}[16+rsp],rsi\n";
+	    $func .= "	mov	rax,rsp\n";
+	    $func .= "${decor}SEH_begin_$current_function->{name}:";
+	    $func .= ":" if ($masm);
+	    $func .= "\n";
+	    my $narg = $current_function->{narg};
+	    $narg=6 if (!defined($narg));
+	    $func .= "	mov	rdi,rcx\n" if ($narg>0);
+	    $func .= "	mov	rsi,rdx\n" if ($narg>1);
+	    $func .= "	mov	rdx,r8\n"  if ($narg>2);
+	    $func .= "	mov	rcx,r9\n"  if ($narg>3);
+	    $func .= "	mov	r8,QWORD${PTR}[40+rsp]\n" if ($narg>4);
+	    $func .= "	mov	r9,QWORD${PTR}[48+rsp]\n" if ($narg>5);
+	    $func .= "\n";
+	} else {
+	   "$current_function->{name}".
+			($nasm ? ":" : "\tPROC $current_function->{scope}");
+	}
+    }
+}
+{ package expr;		# pick up expressioins
+    sub re {
+	my	$self = shift;	# single instance is enough...
+	local	*line = shift;
+	undef	$ret;
+
+	if ($line =~ /(^[^,]+)/) {
+	    $self->{value} = $1;
+	    $ret = $self;
+	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
+
+	    $self->{value} =~ s/\@PLT// if (!$elf);
+	    $self->{value} =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
+	    $self->{value} =~ s/\.L/$decor/g;
+	}
+	$ret;
+    }
+    sub out {
+	my $self = shift;
+	if ($nasm && opcode->mnemonic()=~m/^j/) {
+	    "NEAR ".$self->{value};
+	} else {
+	    $self->{value};
+	}
+    }
+}
+{ package directive;	# pick up directives, which start with .
+    sub re {
+	my	$self = shift;	# single instance is enough...
+	local	*line = shift;
+	undef	$ret;
+	my	$dir;
+	my	%opcode =	# lea 2f-1f(%rip),%dst; 1: nop; 2:
+		(	"%rax"=>0x01058d48,	"%rcx"=>0x010d8d48,
+			"%rdx"=>0x01158d48,	"%rbx"=>0x011d8d48,
+			"%rsp"=>0x01258d48,	"%rbp"=>0x012d8d48,
+			"%rsi"=>0x01358d48,	"%rdi"=>0x013d8d48,
+			"%r8" =>0x01058d4c,	"%r9" =>0x010d8d4c,
+			"%r10"=>0x01158d4c,	"%r11"=>0x011d8d4c,
+			"%r12"=>0x01258d4c,	"%r13"=>0x012d8d4c,
+			"%r14"=>0x01358d4c,	"%r15"=>0x013d8d4c	);
+
+	if ($line =~ /^\s*(\.\w+)/) {
+	    $dir = $1;
+	    $ret = $self;
+	    undef $self->{value};
+	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
+
+	    SWITCH: for ($dir) {
+		/\.picmeup/ && do { if ($line =~ /(%r[\w]+)/i) {
+			    		$dir="\t.long";
+					$line=sprintf "0x%x,0x90000000",$opcode{$1};
+				    }
+				    last;
+				  };
+		/\.global|\.globl|\.extern/
+			    && do { $globals{$line} = $prefix . $line;
+				    $line = $globals{$line} if ($prefix);
+				    last;
+				  };
+		/\.type/    && do { ($sym,$type,$narg) = split(',',$line);
+				    if ($type eq "\@function") {
+					undef $current_function;
+					$current_function->{name} = $sym;
+					$current_function->{abi}  = "svr4";
+					$current_function->{narg} = $narg;
+					$current_function->{scope} = defined($globals{$sym})?"PUBLIC":"PRIVATE";
+				    } elsif ($type eq "\@abi-omnipotent") {
+					undef $current_function;
+					$current_function->{name} = $sym;
+					$current_function->{scope} = defined($globals{$sym})?"PUBLIC":"PRIVATE";
+				    }
+				    $line =~ s/\@abi\-omnipotent/\@function/;
+				    $line =~ s/\@function.*/\@function/;
+				    last;
+				  };
+		/\.asciz/   && do { if ($line =~ /^"(.*)"$/) {
+					$dir  = ".byte";
+					$line = join(",",unpack("C*",$1),0);
+				    }
+				    last;
+				  };
+		/\.rva|\.long|\.quad/
+			    && do { $line =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
+				    $line =~ s/\.L/$decor/g;
+				    last;
+				  };
+	    }
+
+	    if ($gas) {
+		$self->{value} = $dir . "\t" . $line;
+
+		if ($dir =~ /\.extern/) {
+		    $self->{value} = ""; # swallow extern
+		} elsif (!$elf && $dir =~ /\.type/) {
+		    $self->{value} = "";
+		    $self->{value} = ".def\t" . ($globals{$1} or $1) . ";\t" .
+				(defined($globals{$1})?".scl 2;":".scl 3;") .
+				"\t.type 32;\t.endef"
+				if ($win64 && $line =~ /([^,]+),\@function/);
+		} elsif (!$elf && $dir =~ /\.size/) {
+		    $self->{value} = "";
+		    if (defined($current_function)) {
+			$self->{value} .= "${decor}SEH_end_$current_function->{name}:"
+				if ($win64 && $current_function->{abi} eq "svr4");
+			undef $current_function;
+		    }
+		} elsif (!$elf && $dir =~ /\.align/) {
+		    $self->{value} = ".p2align\t" . (log($line)/log(2));
+		} elsif ($dir eq ".section") {
+		    $current_segment=$line;
+		    if (!$elf && $current_segment eq ".init") {
+			if	($flavour eq "macosx")	{ $self->{value} = ".mod_init_func"; }
+			elsif	($flavour eq "mingw64")	{ $self->{value} = ".section\t.ctors"; }
+		    }
+		} elsif ($dir =~ /\.(text|data)/) {
+		    $current_segment=".$1";
+		}
+		$line = "";
+		return $self;
+	    }
+
+	    # non-gas case or nasm/masm
+	    SWITCH: for ($dir) {
+		/\.text/    && do { my $v=undef;
+				    if ($nasm) {
+					$v="section	.text code align=64\n";
+				    } else {
+					$v="$current_segment\tENDS\n" if ($current_segment);
+					$current_segment = ".text\$";
+					$v.="$current_segment\tSEGMENT ";
+					$v.=$masm>=$masmref ? "ALIGN(64)" : "PAGE";
+					$v.=" 'CODE'";
+				    }
+				    $self->{value} = $v;
+				    last;
+				  };
+		/\.data/    && do { my $v=undef;
+				    if ($nasm) {
+					$v="section	.data data align=8\n";
+				    } else {
+					$v="$current_segment\tENDS\n" if ($current_segment);
+					$current_segment = "_DATA";
+					$v.="$current_segment\tSEGMENT";
+				    }
+				    $self->{value} = $v;
+				    last;
+				  };
+		/\.section/ && do { my $v=undef;
+				    $line =~ s/([^,]*).*/$1/;
+				    $line = ".CRT\$XCU" if ($line eq ".init");
+				    if ($nasm) {
+					$v="section	$line";
+					if ($line=~/\.([px])data/) {
+					    $v.=" rdata align=";
+					    $v.=$1 eq "p"? 4 : 8;
+					} elsif ($line=~/\.CRT\$/i) {
+					    $v.=" rdata align=8";
+					}
+				    } else {
+					$v="$current_segment\tENDS\n" if ($current_segment);
+					$v.="$line\tSEGMENT";
+					if ($line=~/\.([px])data/) {
+					    $v.=" READONLY";
+					    $v.=" ALIGN(".($1 eq "p" ? 4 : 8).")" if ($masm>=$masmref);
+					} elsif ($line=~/\.CRT\$/i) {
+					    $v.=" READONLY DWORD";
+					}
+				    }
+				    $current_segment = $line;
+				    $self->{value} = $v;
+				    last;
+				  };
+		/\.extern/  && do { $self->{value}  = "EXTERN\t".$line;
+				    $self->{value} .= ":NEAR" if ($masm);
+				    last;
+				  };
+		/\.globl|.global/
+			    && do { $self->{value}  = $masm?"PUBLIC":"global";
+				    $self->{value} .= "\t".$line;
+				    last;
+				  };
+		/\.size/    && do { if (defined($current_function)) {
+					undef $self->{value};
+					if ($current_function->{abi} eq "svr4") {
+					    $self->{value}="${decor}SEH_end_$current_function->{name}:";
+					    $self->{value}.=":\n" if($masm);
+					}
+					$self->{value}.="$current_function->{name}\tENDP" if($masm);
+					undef $current_function;
+				    }
+				    last;
+				  };
+		/\.align/   && do { $self->{value} = "ALIGN\t".$line; last; };
+		/\.(value|long|rva|quad)/
+			    && do { my $sz  = substr($1,0,1);
+				    my @arr = split(/,\s*/,$line);
+				    my $last = pop(@arr);
+				    my $conv = sub  {	my $var=shift;
+							$var=~s/^(0b[0-1]+)/oct($1)/eig;
+							$var=~s/^0x([0-9a-f]+)/0$1h/ig if ($masm);
+							if ($sz eq "D" && ($current_segment=~/.[px]data/ || $dir eq ".rva"))
+							{ $var=~s/([_a-z\$\@][_a-z0-9\$\@]*)/$nasm?"$1 wrt ..imagebase":"imagerel $1"/egi; }
+							$var;
+						    };  
+
+				    $sz =~ tr/bvlrq/BWDDQ/;
+				    $self->{value} = "\tD$sz\t";
+				    for (@arr) { $self->{value} .= &$conv($_).","; }
+				    $self->{value} .= &$conv($last);
+				    last;
+				  };
+		/\.byte/    && do { my @str=split(/,\s*/,$line);
+				    map(s/(0b[0-1]+)/oct($1)/eig,@str);
+				    map(s/0x([0-9a-f]+)/0$1h/ig,@str) if ($masm);	
+				    while ($#str>15) {
+					$self->{value}.="DB\t"
+						.join(",",@str[0..15])."\n";
+					foreach (0..15) { shift @str; }
+				    }
+				    $self->{value}.="DB\t"
+						.join(",",@str) if (@str);
+				    last;
+				  };
+	    }
+	    $line = "";
+	}
+
+	$ret;
+    }
+    sub out {
+	my $self = shift;
+	$self->{value};
+    }
+}
+
+if ($nasm) {
+    print <<___;
+default	rel
+___
+} elsif ($masm) {
+    print <<___;
+OPTION	DOTNAME
+___
+}
+while($line=<>) {
+
+    chomp($line);
+
+    $line =~ s|[#!].*$||;	# get rid of asm-style comments...
+    $line =~ s|/\*.*\*/||;	# ... and C-style comments...
+    $line =~ s|^\s+||;		# ... and skip white spaces in beginning
+
+    undef $label;
+    undef $opcode;
+    undef $sz;
+    undef @args;
+
+    if ($label=label->re(\$line))	{ print $label->out(); }
+
+    if (directive->re(\$line)) {
+	printf "%s",directive->out();
+    } elsif ($opcode=opcode->re(\$line)) { ARGUMENT: while (1) {
+	my $arg;
+
+	if ($arg=register->re(\$line))	{ opcode->size($arg->size()); }
+	elsif ($arg=const->re(\$line))	{ }
+	elsif ($arg=ea->re(\$line))	{ }
+	elsif ($arg=expr->re(\$line))	{ }
+	else				{ last ARGUMENT; }
+
+	push @args,$arg;
+
+	last ARGUMENT if ($line !~ /^,/);
+
+	$line =~ s/^,\s*//;
+	} # ARGUMENT:
+
+	$sz=opcode->size();
+
+	if ($#args>=0) {
+	    my $insn;
+	    if ($gas) {
+		$insn = $opcode->out($#args>=1?$args[$#args]->size():$sz);
+	    } else {
+		$insn = $opcode->out();
+		$insn .= $sz if (map($_->out() =~ /x?mm/,@args));
+		@args = reverse(@args);
+		undef $sz if ($nasm && $opcode->mnemonic() eq "lea");
+	    }
+	    printf "\t%s\t%s",$insn,join(",",map($_->out($sz),@args));
+	} else {
+	    printf "\t%s",$opcode->out();
+	}
+    }
+
+    print $line,"\n";
+}
+
+print "\n$current_segment\tENDS\n"	if ($current_segment && $masm);
+print "END\n"				if ($masm);
+
+close STDOUT;
+
+#################################################
+# Cross-reference x86_64 ABI "card"
+#
+# 		Unix		Win64
+# %rax		*		*
+# %rbx		-		-
+# %rcx		#4		#1
+# %rdx		#3		#2
+# %rsi		#2		-
+# %rdi		#1		-
+# %rbp		-		-
+# %rsp		-		-
+# %r8		#5		#3
+# %r9		#6		#4
+# %r10		*		*
+# %r11		*		*
+# %r12		-		-
+# %r13		-		-
+# %r14		-		-
+# %r15		-		-
+# 
+# (*)	volatile register
+# (-)	preserved by callee
+# (#)	Nth argument, volatile
+#
+# In Unix terms top of stack is argument transfer area for arguments
+# which could not be accomodated in registers. Or in other words 7th
+# [integer] argument resides at 8(%rsp) upon function entry point.
+# 128 bytes above %rsp constitute a "red zone" which is not touched
+# by signal handlers and can be used as temporal storage without
+# allocating a frame.
+#
+# In Win64 terms N*8 bytes on top of stack is argument transfer area,
+# which belongs to/can be overwritten by callee. N is the number of
+# arguments passed to callee, *but* not less than 4! This means that
+# upon function entry point 5th argument resides at 40(%rsp), as well
+# as that 32 bytes from 8(%rsp) can always be used as temporal
+# storage [without allocating a frame]. One can actually argue that
+# one can assume a "red zone" above stack pointer under Win64 as well.
+# Point is that at apparently no occasion Windows kernel would alter
+# the area above user stack pointer in true asynchronous manner...
+#
+# All the above means that if assembler programmer adheres to Unix
+# register and stack layout, but disregards the "red zone" existense,
+# it's possible to use following prologue and epilogue to "gear" from
+# Unix to Win64 ABI in leaf functions with not more than 6 arguments.
+#
+# omnipotent_function:
+# ifdef WIN64
+#	movq	%rdi,8(%rsp)
+#	movq	%rsi,16(%rsp)
+#	movq	%rcx,%rdi	; if 1st argument is actually present
+#	movq	%rdx,%rsi	; if 2nd argument is actually ...
+#	movq	%r8,%rdx	; if 3rd argument is ...
+#	movq	%r9,%rcx	; if 4th argument ...
+#	movq	40(%rsp),%r8	; if 5th ...
+#	movq	48(%rsp),%r9	; if 6th ...
+# endif
+#	...
+# ifdef WIN64
+#	movq	8(%rsp),%rdi
+#	movq	16(%rsp),%rsi
+# endif
+#	ret
+#
+#################################################
+# Win64 SEH, Structured Exception Handling.
+#
+# Unlike on Unix systems(*) lack of Win64 stack unwinding information
+# has undesired side-effect at run-time: if an exception is raised in
+# assembler subroutine such as those in question (basically we're
+# referring to segmentation violations caused by malformed input
+# parameters), the application is briskly terminated without invoking
+# any exception handlers, most notably without generating memory dump
+# or any user notification whatsoever. This poses a problem. It's
+# possible to address it by registering custom language-specific
+# handler that would restore processor context to the state at
+# subroutine entry point and return "exception is not handled, keep
+# unwinding" code. Writing such handler can be a challenge... But it's
+# doable, though requires certain coding convention. Consider following
+# snippet:
+#
+# .type	function,@function
+# function:
+#	movq	%rsp,%rax	# copy rsp to volatile register
+#	pushq	%r15		# save non-volatile registers
+#	pushq	%rbx
+#	pushq	%rbp
+#	movq	%rsp,%r11
+#	subq	%rdi,%r11	# prepare [variable] stack frame
+#	andq	$-64,%r11
+#	movq	%rax,0(%r11)	# check for exceptions
+#	movq	%r11,%rsp	# allocate [variable] stack frame
+#	movq	%rax,0(%rsp)	# save original rsp value
+# magic_point:
+#	...
+#	movq	0(%rsp),%rcx	# pull original rsp value
+#	movq	-24(%rcx),%rbp	# restore non-volatile registers
+#	movq	-16(%rcx),%rbx
+#	movq	-8(%rcx),%r15
+#	movq	%rcx,%rsp	# restore original rsp
+#	ret
+# .size function,.-function
+#
+# The key is that up to magic_point copy of original rsp value remains
+# in chosen volatile register and no non-volatile register, except for
+# rsp, is modified. While past magic_point rsp remains constant till
+# the very end of the function. In this case custom language-specific
+# exception handler would look like this:
+#
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
+# {	ULONG64 *rsp = (ULONG64 *)context->Rax;
+#	if (context->Rip >= magic_point)
+#	{   rsp = ((ULONG64 **)context->Rsp)[0];
+#	    context->Rbp = rsp[-3];
+#	    context->Rbx = rsp[-2];
+#	    context->R15 = rsp[-1];
+#	}
+#	context->Rsp = (ULONG64)rsp;
+#	context->Rdi = rsp[1];
+#	context->Rsi = rsp[2];
+#
+#	memcpy (disp->ContextRecord,context,sizeof(CONTEXT));
+#	RtlVirtualUnwind(UNW_FLAG_NHANDLER,disp->ImageBase,
+#		dips->ControlPc,disp->FunctionEntry,disp->ContextRecord,
+#		&disp->HandlerData,&disp->EstablisherFrame,NULL);
+#	return ExceptionContinueSearch;
+# }
+#
+# It's appropriate to implement this handler in assembler, directly in
+# function's module. In order to do that one has to know members'
+# offsets in CONTEXT and DISPATCHER_CONTEXT structures and some constant
+# values. Here they are:
+#
+#	CONTEXT.Rax				120
+#	CONTEXT.Rcx				128
+#	CONTEXT.Rdx				136
+#	CONTEXT.Rbx				144
+#	CONTEXT.Rsp				152
+#	CONTEXT.Rbp				160
+#	CONTEXT.Rsi				168
+#	CONTEXT.Rdi				176
+#	CONTEXT.R8				184
+#	CONTEXT.R9				192
+#	CONTEXT.R10				200
+#	CONTEXT.R11				208
+#	CONTEXT.R12				216
+#	CONTEXT.R13				224
+#	CONTEXT.R14				232
+#	CONTEXT.R15				240
+#	CONTEXT.Rip				248
+#	CONTEXT.Xmm6				512
+#	sizeof(CONTEXT)				1232
+#	DISPATCHER_CONTEXT.ControlPc		0
+#	DISPATCHER_CONTEXT.ImageBase		8
+#	DISPATCHER_CONTEXT.FunctionEntry	16
+#	DISPATCHER_CONTEXT.EstablisherFrame	24
+#	DISPATCHER_CONTEXT.TargetIp		32
+#	DISPATCHER_CONTEXT.ContextRecord	40
+#	DISPATCHER_CONTEXT.LanguageHandler	48
+#	DISPATCHER_CONTEXT.HandlerData		56
+#	UNW_FLAG_NHANDLER			0
+#	ExceptionContinueSearch			1
+#
+# In order to tie the handler to the function one has to compose
+# couple of structures: one for .xdata segment and one for .pdata.
+#
+# UNWIND_INFO structure for .xdata segment would be
+#
+# function_unwind_info:
+#	.byte	9,0,0,0
+#	.rva	handler
+#
+# This structure designates exception handler for a function with
+# zero-length prologue, no stack frame or frame register.
+#
+# To facilitate composing of .pdata structures, auto-generated "gear"
+# prologue copies rsp value to rax and denotes next instruction with
+# .LSEH_begin_{function_name} label. This essentially defines the SEH
+# styling rule mentioned in the beginning. Position of this label is
+# chosen in such manner that possible exceptions raised in the "gear"
+# prologue would be accounted to caller and unwound from latter's frame.
+# End of function is marked with respective .LSEH_end_{function_name}
+# label. To summarize, .pdata segment would contain
+#
+#	.rva	.LSEH_begin_function
+#	.rva	.LSEH_end_function
+#	.rva	function_unwind_info
+#
+# Reference to functon_unwind_info from .xdata segment is the anchor.
+# In case you wonder why references are 32-bit .rvas and not 64-bit
+# .quads. References put into these two segments are required to be
+# *relative* to the base address of the current binary module, a.k.a.
+# image base. No Win64 module, be it .exe or .dll, can be larger than
+# 2GB and thus such relative references can be and are accommodated in
+# 32 bits.
+#
+# Having reviewed the example function code, one can argue that "movq
+# %rsp,%rax" above is redundant. It is not! Keep in mind that on Unix
+# rax would contain an undefined value. If this "offends" you, use
+# another register and refrain from modifying rax till magic_point is
+# reached, i.e. as if it was a non-volatile register. If more registers
+# are required prior [variable] frame setup is completed, note that
+# nobody says that you can have only one "magic point." You can
+# "liberate" non-volatile registers by denoting last stack off-load
+# instruction and reflecting it in finer grade unwind logic in handler.
+# After all, isn't it why it's called *language-specific* handler...
+#
+# Attentive reader can notice that exceptions would be mishandled in
+# auto-generated "gear" epilogue. Well, exception effectively can't
+# occur there, because if memory area used by it was subject to
+# segmentation violation, then it would be raised upon call to the
+# function (and as already mentioned be accounted to caller, which is
+# not a problem). If you're still not comfortable, then define tail
+# "magic point" just prior ret instruction and have handler treat it...
+#
+# (*)	Note that we're talking about run-time, not debug-time. Lack of
+#	unwind information makes debugging hard on both Windows and
+#	Unix. "Unlike" referes to the fact that on Unix signal handler
+#	will always be invoked, core dumped and appropriate exit code
+#	returned to parent (for user notification).
diff --git a/openssl/crypto/perlasm/x86asm.pl b/openssl/crypto/perlasm/x86asm.pl
new file mode 100644
index 0000000..28080ca
--- /dev/null
+++ b/openssl/crypto/perlasm/x86asm.pl
@@ -0,0 +1,207 @@
+#!/usr/bin/env perl
+
+# require 'x86asm.pl';
+# &asm_init(<flavor>,"des-586.pl"[,$i386only]);
+# &function_begin("foo");
+# ...
+# &function_end("foo");
+# &asm_finish
+
+$out=();
+$i386=0;
+
+# AUTOLOAD is this context has quite unpleasant side effect, namely
+# that typos in function calls effectively go to assembler output,
+# but on the pros side we don't have to implement one subroutine per
+# each opcode...
+sub ::AUTOLOAD
+{ my $opcode = $AUTOLOAD;
+
+    die "more than 4 arguments passed to $opcode" if ($#_>3);
+
+    $opcode =~ s/.*:://;
+    if    ($opcode =~ /^push/) { $stack+=4; }
+    elsif ($opcode =~ /^pop/)  { $stack-=4; }
+
+    &generic($opcode,@_) or die "undefined subroutine \&$AUTOLOAD";
+}
+
+sub ::emit
+{ my $opcode=shift;
+
+    if ($#_==-1)    { push(@out,"\t$opcode\n");				}
+    else            { push(@out,"\t$opcode\t".join(',',@_)."\n");	}
+}
+
+sub ::LB
+{   $_[0] =~ m/^e?([a-d])x$/o or die "$_[0] does not have a 'low byte'";
+  $1."l";
+}
+sub ::HB
+{   $_[0] =~ m/^e?([a-d])x$/o or die "$_[0] does not have a 'high byte'";
+  $1."h";
+}
+sub ::stack_push{ my $num=$_[0]*4; $stack+=$num; &sub("esp",$num);	}
+sub ::stack_pop	{ my $num=$_[0]*4; $stack-=$num; &add("esp",$num);	}
+sub ::blindpop	{ &pop($_[0]); $stack+=4;				}
+sub ::wparam	{ &DWP($stack+4*$_[0],"esp");				}
+sub ::swtmp	{ &DWP(4*$_[0],"esp");					}
+
+sub ::bswap
+{   if ($i386)	# emulate bswap for i386
+    {	&comment("bswap @_");
+	&xchg(&HB(@_),&LB(@_));
+	&ror (@_,16);
+	&xchg(&HB(@_),&LB(@_));
+    }
+    else
+    {	&generic("bswap",@_);	}
+}
+# These are made-up opcodes introduced over the years essentially
+# by ignorance, just alias them to real ones...
+sub ::movb	{ &mov(@_);	}
+sub ::xorb	{ &xor(@_);	}
+sub ::rotl	{ &rol(@_);	}
+sub ::rotr	{ &ror(@_);	}
+sub ::exch	{ &xchg(@_);	}
+sub ::halt	{ &hlt;		}
+sub ::movz	{ &movzx(@_);	}
+sub ::pushf	{ &pushfd;	}
+sub ::popf	{ &popfd;	}
+
+# 3 argument instructions
+sub ::movq
+{ my($p1,$p2,$optimize)=@_;
+
+    if ($optimize && $p1=~/^mm[0-7]$/ && $p2=~/^mm[0-7]$/)
+    # movq between mmx registers can sink Intel CPUs
+    {	&::pshufw($p1,$p2,0xe4);		}
+    else
+    {	&::generic("movq",@_);			}
+}
+
+# label management
+$lbdecor="L";		# local label decoration, set by package
+$label="000";
+
+sub ::islabel		# see is argument is a known label
+{ my $i;
+    foreach $i (values %label) { return $i if ($i eq $_[0]); }
+  $label{$_[0]};	# can be undef
+}
+
+sub ::label		# instantiate a function-scope label
+{   if (!defined($label{$_[0]}))
+    {	$label{$_[0]}="${lbdecor}${label}${_[0]}"; $label++;   }
+  $label{$_[0]};
+}
+
+sub ::LABEL		# instantiate a file-scope label
+{   $label{$_[0]}=$_[1] if (!defined($label{$_[0]}));
+  $label{$_[0]};
+}
+
+sub ::static_label	{ &::LABEL($_[0],$lbdecor.$_[0]); }
+
+sub ::set_label_B	{ push(@out,"@_:\n"); }
+sub ::set_label
+{ my $label=&::label($_[0]);
+    &::align($_[1]) if ($_[1]>1);
+    &::set_label_B($label);
+  $label;
+}
+
+sub ::wipe_labels	# wipes function-scope labels
+{   foreach $i (keys %label)
+    {	delete $label{$i} if ($label{$i} =~ /^\Q${lbdecor}\E[0-9]{3}/);	}
+}
+
+# subroutine management
+sub ::function_begin
+{   &function_begin_B(@_);
+    $stack=4;
+    &push("ebp");
+    &push("ebx");
+    &push("esi");
+    &push("edi");
+}
+
+sub ::function_end
+{   &pop("edi");
+    &pop("esi");
+    &pop("ebx");
+    &pop("ebp");
+    &ret();
+    &function_end_B(@_);
+    $stack=0;
+    &wipe_labels();
+}
+
+sub ::function_end_A
+{   &pop("edi");
+    &pop("esi");
+    &pop("ebx");
+    &pop("ebp");
+    &ret();
+    $stack+=16;	# readjust esp as if we didn't pop anything
+}
+
+sub ::asciz
+{ my @str=unpack("C*",shift);
+    push @str,0;
+    while ($#str>15) {
+	&data_byte(@str[0..15]);
+	foreach (0..15) { shift @str; }
+    }
+    &data_byte(@str) if (@str);
+}
+
+sub ::asm_finish
+{   &file_end();
+    print @out;
+}
+
+sub ::asm_init
+{ my ($type,$fn,$cpu)=@_;
+
+    $filename=$fn;
+    $i386=$cpu;
+
+    $elf=$cpp=$coff=$aout=$macosx=$win32=$netware=$mwerks=0;
+    if    (($type eq "elf"))
+    {	$elf=1;			require "x86gas.pl";	}
+    elsif (($type eq "a\.out"))
+    {	$aout=1;		require "x86gas.pl";	}
+    elsif (($type eq "coff" or $type eq "gaswin"))
+    {	$coff=1;		require "x86gas.pl";	}
+    elsif (($type eq "win32n"))
+    {	$win32=1;		require "x86nasm.pl";	}
+    elsif (($type eq "nw-nasm"))
+    {	$netware=1;		require "x86nasm.pl";	}
+    #elsif (($type eq "nw-mwasm"))
+    #{	$netware=1; $mwerks=1;	require "x86nasm.pl";	}
+    elsif (($type eq "win32"))
+    {	$win32=1;		require "x86masm.pl";	}
+    elsif (($type eq "macosx"))
+    {	$aout=1; $macosx=1;	require "x86gas.pl";	}
+    else
+    {	print STDERR <<"EOF";
+Pick one target type from
+	elf	- Linux, FreeBSD, Solaris x86, etc.
+	a.out	- DJGPP, elder OpenBSD, etc.
+	coff	- GAS/COFF such as Win32 targets
+	win32n	- Windows 95/Windows NT NASM format
+	nw-nasm - NetWare NASM format
+	macosx	- Mac OS X
+EOF
+	exit(1);
+    }
+
+    $pic=0;
+    for (@ARGV) { $pic=1 if (/\-[fK]PIC/i); }
+
+    $filename =~ s/\.pl$//;
+    &file($filename);
+}
+
+1;
diff --git a/openssl/crypto/perlasm/x86gas.pl b/openssl/crypto/perlasm/x86gas.pl
new file mode 100644
index 0000000..6eab727
--- /dev/null
+++ b/openssl/crypto/perlasm/x86gas.pl
@@ -0,0 +1,247 @@
+#!/usr/bin/env perl
+
+package x86gas;
+
+*out=\@::out;
+
+$::lbdecor=$::aout?"L":".L";		# local label decoration
+$nmdecor=($::aout or $::coff)?"_":"";	# external name decoration
+
+$initseg="";
+
+$align=16;
+$align=log($align)/log(2) if ($::aout);
+$com_start="#" if ($::aout or $::coff);
+
+sub opsize()
+{ my $reg=shift;
+    if    ($reg =~ m/^%e/o)		{ "l"; }
+    elsif ($reg =~ m/^%[a-d][hl]$/o)	{ "b"; }
+    elsif ($reg =~ m/^%[xm]/o)		{ undef; }
+    else				{ "w"; }
+}
+
+# swap arguments;
+# expand opcode with size suffix;
+# prefix numeric constants with $;
+sub ::generic
+{ my($opcode,@arg)=@_;
+  my($suffix,$dst,$src);
+
+    @arg=reverse(@arg);
+
+    for (@arg)
+    {	s/^(\*?)(e?[a-dsixphl]{2})$/$1%$2/o;	# gp registers
+	s/^([xy]?mm[0-7])$/%$1/o;		# xmm/mmx registers
+	s/^(\-?[0-9]+)$/\$$1/o;			# constants
+	s/^(\-?0x[0-9a-f]+)$/\$$1/o;		# constants
+    }
+
+    $dst = $arg[$#arg]		if ($#arg>=0);
+    $src = $arg[$#arg-1]	if ($#arg>=1);
+    if    ($dst =~ m/^%/o)	{ $suffix=&opsize($dst); }
+    elsif ($src =~ m/^%/o)	{ $suffix=&opsize($src); }
+    else			{ $suffix="l";           }
+    undef $suffix if ($dst =~ m/^%[xm]/o || $src =~ m/^%[xm]/o);
+
+    if ($#_==0)				{ &::emit($opcode);		}
+    elsif ($opcode =~ m/^j/o && $#_==1)	{ &::emit($opcode,@arg);	}
+    elsif ($opcode eq "call" && $#_==1)	{ &::emit($opcode,@arg);	}
+    elsif ($opcode =~ m/^set/&& $#_==1)	{ &::emit($opcode,@arg);	}
+    else				{ &::emit($opcode.$suffix,@arg);}
+
+  1;
+}
+#
+# opcodes not covered by ::generic above, mostly inconsistent namings...
+#
+sub ::movzx	{ &::movzb(@_);			}
+sub ::pushfd	{ &::pushfl;			}
+sub ::popfd	{ &::popfl;			}
+sub ::cpuid	{ &::emit(".byte\t0x0f,0xa2");	}
+sub ::rdtsc	{ &::emit(".byte\t0x0f,0x31");	}
+
+sub ::call	{ &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); }
+sub ::call_ptr	{ &::generic("call","*$_[0]");	}
+sub ::jmp_ptr	{ &::generic("jmp","*$_[0]");	}
+
+*::bswap = sub	{ &::emit("bswap","%$_[0]");	} if (!$::i386);
+
+sub ::DWP
+{ my($addr,$reg1,$reg2,$idx)=@_;
+  my $ret="";
+
+    $addr =~ s/^\s+//;
+    # prepend global references with optional underscore
+    $addr =~ s/^([^\+\-0-9][^\+\-]*)/&::islabel($1) or "$nmdecor$1"/ige;
+
+    $reg1 = "%$reg1" if ($reg1);
+    $reg2 = "%$reg2" if ($reg2);
+
+    $ret .= $addr if (($addr ne "") && ($addr ne 0));
+
+    if ($reg2)
+    {	$idx!= 0 or $idx=1;
+	$ret .= "($reg1,$reg2,$idx)";
+    }
+    elsif ($reg1)
+    {	$ret .= "($reg1)";	}
+
+  $ret;
+}
+sub ::QWP	{ &::DWP(@_);	}
+sub ::BP	{ &::DWP(@_);	}
+sub ::BC	{ @_;		}
+sub ::DWC	{ @_;		}
+
+sub ::file
+{   push(@out,".file\t\"$_[0].s\"\n.text\n");	}
+
+sub ::function_begin_B
+{ my $func=shift;
+  my $global=($func !~ /^_/);
+  my $begin="${::lbdecor}_${func}_begin";
+
+    &::LABEL($func,$global?"$begin":"$nmdecor$func");
+    $func=$nmdecor.$func;
+
+    push(@out,".globl\t$func\n")	if ($global);
+    if ($::coff)
+    {	push(@out,".def\t$func;\t.scl\t".(3-$global).";\t.type\t32;\t.endef\n"); }
+    elsif (($::aout and !$::pic) or $::macosx)
+    { }
+    else
+    {	push(@out,".type	$func,\@function\n"); }
+    push(@out,".align\t$align\n");
+    push(@out,"$func:\n");
+    push(@out,"$begin:\n")		if ($global);
+    $::stack=4;
+}
+
+sub ::function_end_B
+{ my $func=shift;
+    push(@out,".size\t$nmdecor$func,.-".&::LABEL($func)."\n") if ($::elf);
+    $::stack=0;
+    &::wipe_labels();
+}
+
+sub ::comment
+	{
+	if (!defined($com_start) or $::elf)
+		{	# Regarding $::elf above...
+			# GNU and SVR4 as'es use different comment delimiters,
+		push(@out,"\n");	# so we just skip ELF comments...
+		return;
+		}
+	foreach (@_)
+		{
+		if (/^\s*$/)
+			{ push(@out,"\n"); }
+		else
+			{ push(@out,"\t$com_start $_ $com_end\n"); }
+		}
+	}
+
+sub ::external_label
+{   foreach(@_) { &::LABEL($_,$nmdecor.$_); }   }
+
+sub ::public_label
+{   push(@out,".globl\t".&::LABEL($_[0],$nmdecor.$_[0])."\n");   }
+
+sub ::file_end
+{   if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out) {
+	my $tmp=".comm\t${nmdecor}OPENSSL_ia32cap_P,4";
+	if ($::elf)	{ push (@out,"$tmp,4\n"); }
+	else		{ push (@out,"$tmp\n"); }
+    }
+    if ($::macosx)
+    {	if (%non_lazy_ptr)
+    	{   push(@out,".section __IMPORT,__pointers,non_lazy_symbol_pointers\n");
+	    foreach $i (keys %non_lazy_ptr)
+	    {	push(@out,"$non_lazy_ptr{$i}:\n.indirect_symbol\t$i\n.long\t0\n");   }
+	}
+    }
+    push(@out,$initseg) if ($initseg);
+}
+
+sub ::data_byte	{   push(@out,".byte\t".join(',',@_)."\n");   }
+sub ::data_word {   push(@out,".long\t".join(',',@_)."\n");   }
+
+sub ::align
+{ my $val=$_[0],$p2,$i;
+    if ($::aout)
+    {	for ($p2=0;$val!=0;$val>>=1) { $p2++; }
+	$val=$p2-1;
+	$val.=",0x90";
+    }
+    push(@out,".align\t$val\n");
+}
+
+sub ::picmeup
+{ my($dst,$sym,$base,$reflabel)=@_;
+
+    if ($::pic && ($::elf || $::aout))
+    {	if (!defined($base))
+	{   &::call(&::label("PIC_me_up"));
+	    &::set_label("PIC_me_up");
+	    &::blindpop($dst);
+	    $base=$dst;
+	    $reflabel=&::label("PIC_me_up");
+	}
+	if ($::macosx)
+	{   my $indirect=&::static_label("$nmdecor$sym\$non_lazy_ptr");
+	    &::mov($dst,&::DWP("$indirect-$reflabel",$base));
+	    $non_lazy_ptr{"$nmdecor$sym"}=$indirect;
+	}
+	else
+	{   &::lea($dst,&::DWP("_GLOBAL_OFFSET_TABLE_+[.-$reflabel]",
+			    $base));
+	    &::mov($dst,&::DWP("$sym\@GOT",$dst));
+	}
+    }
+    else
+    {	&::lea($dst,&::DWP($sym));	}
+}
+
+sub ::initseg
+{ my $f=$nmdecor.shift;
+
+    if ($::elf)
+    {	$initseg.=<<___;
+.section	.init
+	call	$f
+	jmp	.Linitalign
+.align	$align
+.Linitalign:
+___
+    }
+    elsif ($::coff)
+    {   $initseg.=<<___;	# applies to both Cygwin and Mingw
+.section	.ctors
+.long	$f
+___
+    }
+    elsif ($::macosx)
+    {	$initseg.=<<___;
+.mod_init_func
+.align 2
+.long   $f
+___
+    }
+    elsif ($::aout)
+    {	my $ctor="${nmdecor}_GLOBAL_\$I\$$f";
+	$initseg.=".text\n";
+	$initseg.=".type	$ctor,\@function\n" if ($::pic);
+	$initseg.=<<___;	# OpenBSD way...
+.globl	$ctor
+.align	2
+$ctor:
+	jmp	$f
+___
+    }
+}
+
+sub ::dataseg
+{   push(@out,".data\n");   }
+
+1;
diff --git a/openssl/crypto/perlasm/x86masm.pl b/openssl/crypto/perlasm/x86masm.pl
new file mode 100644
index 0000000..3d50e4a
--- /dev/null
+++ b/openssl/crypto/perlasm/x86masm.pl
@@ -0,0 +1,184 @@
+#!/usr/bin/env perl
+
+package x86masm;
+
+*out=\@::out;
+
+$::lbdecor="\$L";	# local label decoration
+$nmdecor="_";		# external name decoration
+
+$initseg="";
+$segment="";
+
+sub ::generic
+{ my ($opcode,@arg)=@_;
+
+    # fix hexadecimal constants
+    for (@arg) { s/0x([0-9a-f]+)/0$1h/oi; }
+
+    if ($opcode !~ /movq/)
+    {	# fix xmm references
+	$arg[0] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[1]=~/\bxmm[0-7]\b/i);
+	$arg[1] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[0]=~/\bxmm[0-7]\b/i);
+    }
+
+    &::emit($opcode,@arg);
+  1;
+}
+#
+# opcodes not covered by ::generic above, mostly inconsistent namings...
+#
+sub ::call	{ &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); }
+sub ::call_ptr	{ &::emit("call",@_);	}
+sub ::jmp_ptr	{ &::emit("jmp",@_);	}
+
+sub get_mem
+{ my($size,$addr,$reg1,$reg2,$idx)=@_;
+  my($post,$ret);
+
+    $ret .= "$size PTR " if ($size ne "");
+
+    $addr =~ s/^\s+//;
+    # prepend global references with optional underscore
+    $addr =~ s/^([^\+\-0-9][^\+\-]*)/&::islabel($1) or "$nmdecor$1"/ige;
+    # put address arithmetic expression in parenthesis
+    $addr="($addr)" if ($addr =~ /^.+[\-\+].+$/);
+
+    if (($addr ne "") && ($addr ne 0))
+    {	if ($addr !~ /^-/)	{ $ret .= "$addr";  }
+	else			{ $post=$addr;      }
+    }
+    $ret .= "[";
+
+    if ($reg2 ne "")
+    {	$idx!=0 or $idx=1;
+	$ret .= "$reg2*$idx";
+	$ret .= "+$reg1" if ($reg1 ne "");
+    }
+    else
+    {	$ret .= "$reg1";   }
+
+    $ret .= "$post]";
+    $ret =~ s/\+\]/]/; # in case $addr was the only argument
+    $ret =~ s/\[\s*\]//;
+
+  $ret;
+}
+sub ::BP	{ &get_mem("BYTE",@_);  }
+sub ::DWP	{ &get_mem("DWORD",@_); }
+sub ::QWP	{ &get_mem("QWORD",@_); }
+sub ::BC	{ "@_";  }
+sub ::DWC	{ "@_"; }
+
+sub ::file
+{ my $tmp=<<___;
+TITLE	$_[0].asm
+IF \@Version LT 800
+ECHO MASM version 8.00 or later is strongly recommended.
+ENDIF
+.486
+.MODEL	FLAT
+OPTION	DOTNAME
+IF \@Version LT 800
+.text\$	SEGMENT PAGE 'CODE'
+ELSE
+.text\$	SEGMENT ALIGN(64) 'CODE'
+ENDIF
+___
+    push(@out,$tmp);
+    $segment = ".text\$";
+}
+
+sub ::function_begin_B
+{ my $func=shift;
+  my $global=($func !~ /^_/);
+  my $begin="${::lbdecor}_${func}_begin";
+
+    &::LABEL($func,$global?"$begin":"$nmdecor$func");
+    $func="ALIGN\t16\n".$nmdecor.$func."\tPROC";
+
+    if ($global)    { $func.=" PUBLIC\n${begin}::\n"; }
+    else	    { $func.=" PRIVATE\n";            }
+    push(@out,$func);
+    $::stack=4;
+}
+sub ::function_end_B
+{ my $func=shift;
+
+    push(@out,"$nmdecor$func ENDP\n");
+    $::stack=0;
+    &::wipe_labels();
+}
+
+sub ::file_end
+{ my $xmmheader=<<___;
+.686
+.XMM
+IF \@Version LT 800
+XMMWORD STRUCT 16
+DQ	2 dup (?)
+XMMWORD	ENDS
+ENDIF
+___
+    if (grep {/\b[x]?mm[0-7]\b/i} @out) {
+	grep {s/\.[3-7]86/$xmmheader/} @out;
+    }
+
+    push(@out,"$segment	ENDS\n");
+
+    if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out)
+    {	my $comm=<<___;
+.bss	SEGMENT 'BSS'
+COMM	${nmdecor}OPENSSL_ia32cap_P:DWORD
+.bss	ENDS
+___
+	# comment out OPENSSL_ia32cap_P declarations
+	grep {s/(^EXTERN\s+${nmdecor}OPENSSL_ia32cap_P)/\;$1/} @out;
+	push (@out,$comm);
+    }
+    push (@out,$initseg) if ($initseg);
+    push (@out,"END\n");
+}
+
+sub ::comment {   foreach (@_) { push(@out,"\t; $_\n"); }   }
+
+*::set_label_B = sub
+{ my $l=shift; push(@out,$l.($l=~/^\Q${::lbdecor}\E[0-9]{3}/?":\n":"::\n")); };
+
+sub ::external_label
+{   foreach(@_)
+    {	push(@out, "EXTERN\t".&::LABEL($_,$nmdecor.$_).":NEAR\n");   }
+}
+
+sub ::public_label
+{   push(@out,"PUBLIC\t".&::LABEL($_[0],$nmdecor.$_[0])."\n");   }
+
+sub ::data_byte
+{   push(@out,("DB\t").join(',',@_)."\n");	}
+
+sub ::data_word
+{   push(@out,("DD\t").join(',',@_)."\n");	}
+
+sub ::align
+{   push(@out,"ALIGN\t$_[0]\n");	}
+
+sub ::picmeup
+{ my($dst,$sym)=@_;
+    &::lea($dst,&::DWP($sym));
+}
+
+sub ::initseg
+{ my $f=$nmdecor.shift;
+
+    $initseg.=<<___;
+.CRT\$XCU	SEGMENT DWORD PUBLIC 'DATA'
+EXTERN	$f:NEAR
+DD	$f
+.CRT\$XCU	ENDS
+___
+}
+
+sub ::dataseg
+{   push(@out,"$segment\tENDS\n_DATA\tSEGMENT\n"); $segment="_DATA";   }
+
+1;
diff --git a/openssl/crypto/perlasm/x86nasm.pl b/openssl/crypto/perlasm/x86nasm.pl
new file mode 100644
index 0000000..ce2bed9
--- /dev/null
+++ b/openssl/crypto/perlasm/x86nasm.pl
@@ -0,0 +1,166 @@
+#!/usr/bin/env perl
+
+package x86nasm;
+
+*out=\@::out;
+
+$::lbdecor="L\$";		# local label decoration
+$nmdecor=$::netware?"":"_";	# external name decoration
+$drdecor=$::mwerks?".":"";	# directive decoration
+
+$initseg="";
+
+sub ::generic
+{ my $opcode=shift;
+  my $tmp;
+
+    if (!$::mwerks)
+    {   if    ($opcode =~ m/^j/o && $#_==0) # optimize jumps
+	{   $_[0] = "NEAR $_[0]";   	}
+	elsif ($opcode eq "lea" && $#_==1)  # wipe storage qualifier from lea
+	{   $_[1] =~ s/^[^\[]*\[/\[/o;	}
+    }
+    &::emit($opcode,@_);
+  1;
+}
+#
+# opcodes not covered by ::generic above, mostly inconsistent namings...
+#
+sub ::call	{ &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); }
+sub ::call_ptr	{ &::emit("call",@_);	}
+sub ::jmp_ptr	{ &::emit("jmp",@_);	}
+
+sub get_mem
+{ my($size,$addr,$reg1,$reg2,$idx)=@_;
+  my($post,$ret);
+
+    if ($size ne "")
+    {	$ret .= "$size";
+	$ret .= " PTR" if ($::mwerks);
+	$ret .= " ";
+    }
+    $ret .= "[";
+
+    $addr =~ s/^\s+//;
+    # prepend global references with optional underscore
+    $addr =~ s/^([^\+\-0-9][^\+\-]*)/::islabel($1) or "$nmdecor$1"/ige;
+    # put address arithmetic expression in parenthesis
+    $addr="($addr)" if ($addr =~ /^.+[\-\+].+$/);
+
+    if (($addr ne "") && ($addr ne 0))
+    {	if ($addr !~ /^-/)	{ $ret .= "$addr+"; }
+	else			{ $post=$addr;      }
+    }
+
+    if ($reg2 ne "")
+    {	$idx!=0 or $idx=1;
+	$ret .= "$reg2*$idx";
+	$ret .= "+$reg1" if ($reg1 ne "");
+    }
+    else
+    {	$ret .= "$reg1";   }
+
+    $ret .= "$post]";
+    $ret =~ s/\+\]/]/; # in case $addr was the only argument
+
+  $ret;
+}
+sub ::BP	{ &get_mem("BYTE",@_);  }
+sub ::DWP	{ &get_mem("DWORD",@_); }
+sub ::QWP	{ &get_mem("",@_);      }
+sub ::BC	{ (($::mwerks)?"":"BYTE ")."@_";  }
+sub ::DWC	{ (($::mwerks)?"":"DWORD ")."@_"; }
+
+sub ::file
+{   if ($::mwerks)	{ push(@out,".section\t.text,64\n"); }
+    else
+    { my $tmp=<<___;
+%ifidn __OUTPUT_FORMAT__,obj
+section	code	use32 class=code align=64
+%elifidn __OUTPUT_FORMAT__,win32
+\$\@feat.00 equ 1
+section	.text	code align=64
+%else
+section	.text	code
+%endif
+___
+	push(@out,$tmp);
+    }
+}
+
+sub ::function_begin_B
+{ my $func=shift;
+  my $global=($func !~ /^_/);
+  my $begin="${::lbdecor}_${func}_begin";
+
+    $begin =~ s/^\@/./ if ($::mwerks);	# the torture never stops
+
+    &::LABEL($func,$global?"$begin":"$nmdecor$func");
+    $func=$nmdecor.$func;
+
+    push(@out,"${drdecor}global	$func\n")	if ($global);
+    push(@out,"${drdecor}align	16\n");
+    push(@out,"$func:\n");
+    push(@out,"$begin:\n")			if ($global);
+    $::stack=4;
+}
+
+sub ::function_end_B
+{   $::stack=0;
+    &::wipe_labels();
+}
+
+sub ::file_end
+{   if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out)
+    {	my $comm=<<___;
+${drdecor}segment	.bss
+${drdecor}common	${nmdecor}OPENSSL_ia32cap_P 4
+___
+	# comment out OPENSSL_ia32cap_P declarations
+	grep {s/(^extern\s+${nmdecor}OPENSSL_ia32cap_P)/\;$1/} @out;
+	push (@out,$comm)
+    }
+    push (@out,$initseg) if ($initseg);		
+}
+
+sub ::comment {   foreach (@_) { push(@out,"\t; $_\n"); }   }
+
+sub ::external_label
+{   foreach(@_)
+    {	push(@out,"${drdecor}extern\t".&::LABEL($_,$nmdecor.$_)."\n");   }
+}
+
+sub ::public_label
+{   push(@out,"${drdecor}global\t".&::LABEL($_[0],$nmdecor.$_[0])."\n");  }
+
+sub ::data_byte
+{   push(@out,(($::mwerks)?".byte\t":"db\t").join(',',@_)."\n");	}
+
+sub ::data_word
+{   push(@out,(($::mwerks)?".long\t":"dd\t").join(',',@_)."\n");	}
+
+sub ::align
+{   push(@out,"${drdecor}align\t$_[0]\n");	}
+
+sub ::picmeup
+{ my($dst,$sym)=@_;
+    &::lea($dst,&::DWP($sym));
+}
+
+sub ::initseg
+{ my $f=$nmdecor.shift;
+    if ($::win32)
+    {	$initseg=<<___;
+segment	.CRT\$XCU data align=4
+extern	$f
+dd	$f
+___
+    }
+}
+
+sub ::dataseg
+{   if ($mwerks)	{ push(@out,".section\t.data,4\n");   }
+    else		{ push(@out,"section\t.data align=4\n"); }
+}
+
+1;
diff --git a/openssl/crypto/pkcs12/Makefile b/openssl/crypto/pkcs12/Makefile
new file mode 100644
index 0000000..3a7498f
--- /dev/null
+++ b/openssl/crypto/pkcs12/Makefile
@@ -0,0 +1,286 @@
+#
+# OpenSSL/crypto/pkcs12/Makefile
+#
+
+DIR=	pkcs12
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= p12_add.c p12_asn.c p12_attr.c p12_crpt.c p12_crt.c p12_decr.c \
+	p12_init.c p12_key.c p12_kiss.c p12_mutl.c\
+	p12_utl.c p12_npas.c pk12err.c p12_p8d.c p12_p8e.c
+LIBOBJ= p12_add.o p12_asn.o p12_attr.o p12_crpt.o p12_crt.o p12_decr.o \
+	p12_init.o p12_key.o p12_kiss.o p12_mutl.o\
+	p12_utl.o p12_npas.o pk12err.o p12_p8d.o p12_p8e.o
+
+SRC= $(LIBSRC)
+
+EXHEADER=  pkcs12.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+test:
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+p12_add.o: ../../e_os.h ../../include/openssl/asn1.h
+p12_add.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+p12_add.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+p12_add.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+p12_add.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+p12_add.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+p12_add.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p12_add.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+p12_add.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
+p12_add.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+p12_add.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p12_add.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p12_add.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_add.c
+p12_asn.o: ../../e_os.h ../../include/openssl/asn1.h
+p12_asn.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+p12_asn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+p12_asn.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+p12_asn.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+p12_asn.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+p12_asn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p12_asn.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p12_asn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p12_asn.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+p12_asn.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p12_asn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p12_asn.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p12_asn.o: ../cryptlib.h p12_asn.c
+p12_attr.o: ../../e_os.h ../../include/openssl/asn1.h
+p12_attr.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+p12_attr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+p12_attr.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+p12_attr.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+p12_attr.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+p12_attr.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p12_attr.o: ../../include/openssl/opensslconf.h
+p12_attr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p12_attr.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+p12_attr.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p12_attr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p12_attr.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p12_attr.o: ../cryptlib.h p12_attr.c
+p12_crpt.o: ../../e_os.h ../../include/openssl/asn1.h
+p12_crpt.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+p12_crpt.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+p12_crpt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+p12_crpt.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+p12_crpt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+p12_crpt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p12_crpt.o: ../../include/openssl/opensslconf.h
+p12_crpt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p12_crpt.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+p12_crpt.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p12_crpt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p12_crpt.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p12_crpt.o: ../cryptlib.h p12_crpt.c
+p12_crt.o: ../../e_os.h ../../include/openssl/asn1.h
+p12_crt.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+p12_crt.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+p12_crt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+p12_crt.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+p12_crt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+p12_crt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p12_crt.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+p12_crt.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
+p12_crt.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+p12_crt.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p12_crt.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p12_crt.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_crt.c
+p12_decr.o: ../../e_os.h ../../include/openssl/asn1.h
+p12_decr.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+p12_decr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+p12_decr.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+p12_decr.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+p12_decr.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+p12_decr.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p12_decr.o: ../../include/openssl/opensslconf.h
+p12_decr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p12_decr.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+p12_decr.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p12_decr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p12_decr.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p12_decr.o: ../cryptlib.h p12_decr.c
+p12_init.o: ../../e_os.h ../../include/openssl/asn1.h
+p12_init.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+p12_init.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+p12_init.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+p12_init.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+p12_init.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+p12_init.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p12_init.o: ../../include/openssl/opensslconf.h
+p12_init.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p12_init.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+p12_init.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p12_init.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p12_init.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p12_init.o: ../cryptlib.h p12_init.c
+p12_key.o: ../../e_os.h ../../include/openssl/asn1.h
+p12_key.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+p12_key.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+p12_key.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+p12_key.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+p12_key.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+p12_key.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p12_key.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p12_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p12_key.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+p12_key.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p12_key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p12_key.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p12_key.o: ../cryptlib.h p12_key.c
+p12_kiss.o: ../../e_os.h ../../include/openssl/asn1.h
+p12_kiss.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+p12_kiss.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+p12_kiss.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+p12_kiss.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+p12_kiss.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+p12_kiss.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p12_kiss.o: ../../include/openssl/opensslconf.h
+p12_kiss.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p12_kiss.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+p12_kiss.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p12_kiss.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p12_kiss.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p12_kiss.o: ../cryptlib.h p12_kiss.c
+p12_mutl.o: ../../e_os.h ../../include/openssl/asn1.h
+p12_mutl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+p12_mutl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+p12_mutl.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+p12_mutl.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+p12_mutl.o: ../../include/openssl/evp.h ../../include/openssl/hmac.h
+p12_mutl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p12_mutl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p12_mutl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p12_mutl.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+p12_mutl.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+p12_mutl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p12_mutl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p12_mutl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_mutl.c
+p12_npas.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+p12_npas.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+p12_npas.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+p12_npas.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+p12_npas.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+p12_npas.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p12_npas.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p12_npas.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p12_npas.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+p12_npas.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+p12_npas.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p12_npas.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p12_npas.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p12_npas.o: p12_npas.c
+p12_p8d.o: ../../e_os.h ../../include/openssl/asn1.h
+p12_p8d.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+p12_p8d.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+p12_p8d.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+p12_p8d.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+p12_p8d.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+p12_p8d.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p12_p8d.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+p12_p8d.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
+p12_p8d.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+p12_p8d.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p12_p8d.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p12_p8d.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_p8d.c
+p12_p8e.o: ../../e_os.h ../../include/openssl/asn1.h
+p12_p8e.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+p12_p8e.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+p12_p8e.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+p12_p8e.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+p12_p8e.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+p12_p8e.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p12_p8e.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+p12_p8e.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
+p12_p8e.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+p12_p8e.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p12_p8e.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p12_p8e.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_p8e.c
+p12_utl.o: ../../e_os.h ../../include/openssl/asn1.h
+p12_utl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+p12_utl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+p12_utl.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+p12_utl.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+p12_utl.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+p12_utl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p12_utl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+p12_utl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
+p12_utl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+p12_utl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p12_utl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p12_utl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_utl.c
+pk12err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+pk12err.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+pk12err.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+pk12err.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+pk12err.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+pk12err.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pk12err.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pk12err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pk12err.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+pk12err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+pk12err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+pk12err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+pk12err.o: pk12err.c
diff --git a/openssl/crypto/pkcs12/p12_add.c b/openssl/crypto/pkcs12/p12_add.c
new file mode 100644
index 0000000..27ac5fa
--- /dev/null
+++ b/openssl/crypto/pkcs12/p12_add.c
@@ -0,0 +1,240 @@
+/* p12_add.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* Pack an object into an OCTET STRING and turn into a safebag */
+
+PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, int nid1,
+	     int nid2)
+{
+	PKCS12_BAGS *bag;
+	PKCS12_SAFEBAG *safebag;
+	if (!(bag = PKCS12_BAGS_new())) {
+		PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	bag->type = OBJ_nid2obj(nid1);
+	if (!ASN1_item_pack(obj, it, &bag->value.octet)) {
+		PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	if (!(safebag = PKCS12_SAFEBAG_new())) {
+		PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	safebag->value.bag = bag;
+	safebag->type = OBJ_nid2obj(nid2);
+	return safebag;
+}
+
+/* Turn PKCS8 object into a keybag */
+
+PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8)
+{
+	PKCS12_SAFEBAG *bag;
+	if (!(bag = PKCS12_SAFEBAG_new())) {
+		PKCS12err(PKCS12_F_PKCS12_MAKE_KEYBAG,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	bag->type = OBJ_nid2obj(NID_keyBag);
+	bag->value.keybag = p8;
+	return bag;
+}
+
+/* Turn PKCS8 object into a shrouded keybag */
+
+PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
+	     int passlen, unsigned char *salt, int saltlen, int iter,
+	     PKCS8_PRIV_KEY_INFO *p8)
+{
+	PKCS12_SAFEBAG *bag;
+	const EVP_CIPHER *pbe_ciph;
+
+	/* Set up the safe bag */
+	if (!(bag = PKCS12_SAFEBAG_new())) {
+		PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
+
+	pbe_ciph = EVP_get_cipherbynid(pbe_nid);
+
+	if (pbe_ciph)
+		pbe_nid = -1;
+
+	if (!(bag->value.shkeybag = 
+	  PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter,
+									 p8))) {
+		PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	return bag;
+}
+
+/* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */
+PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk)
+{
+	PKCS7 *p7;
+	if (!(p7 = PKCS7_new())) {
+		PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	p7->type = OBJ_nid2obj(NID_pkcs7_data);
+	if (!(p7->d.data = M_ASN1_OCTET_STRING_new())) {
+		PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	
+	if (!ASN1_item_pack(sk, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), &p7->d.data)) {
+		PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, PKCS12_R_CANT_PACK_STRUCTURE);
+		return NULL;
+	}
+	return p7;
+}
+
+/* Unpack SAFEBAGS from PKCS#7 data ContentInfo */
+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7)
+{
+	if(!PKCS7_type_is_data(p7))
+		{
+		PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA,PKCS12_R_CONTENT_TYPE_NOT_DATA);
+		return NULL;
+		}
+	return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS));
+}
+
+/* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */
+
+PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
+			      unsigned char *salt, int saltlen, int iter,
+			      STACK_OF(PKCS12_SAFEBAG) *bags)
+{
+	PKCS7 *p7;
+	X509_ALGOR *pbe;
+	const EVP_CIPHER *pbe_ciph;
+	if (!(p7 = PKCS7_new())) {
+		PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	if(!PKCS7_set_type(p7, NID_pkcs7_encrypted)) {
+		PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA,
+				PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE);
+		return NULL;
+	}
+
+	pbe_ciph = EVP_get_cipherbynid(pbe_nid);
+
+	if (pbe_ciph)
+		pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen);
+	else
+		pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
+
+	if (!pbe) {
+		PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm);
+	p7->d.encrypted->enc_data->algorithm = pbe;
+	M_ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data);
+	if (!(p7->d.encrypted->enc_data->enc_data =
+	PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass, passlen,
+				 bags, 1))) {
+		PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, PKCS12_R_ENCRYPT_ERROR);
+		return NULL;
+	}
+
+	return p7;
+}
+
+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, int passlen)
+{
+	if(!PKCS7_type_is_encrypted(p7)) return NULL;
+	return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm,
+			           ASN1_ITEM_rptr(PKCS12_SAFEBAGS),
+				   pass, passlen,
+			           p7->d.encrypted->enc_data->enc_data, 1);
+}
+
+PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, const char *pass,
+								int passlen)
+{
+	return PKCS8_decrypt(bag->value.shkeybag, pass, passlen);
+}
+
+int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes) 
+{
+	if(ASN1_item_pack(safes, ASN1_ITEM_rptr(PKCS12_AUTHSAFES),
+		&p12->authsafes->d.data)) 
+			return 1;
+	return 0;
+}
+
+STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12)
+{
+	if (!PKCS7_type_is_data(p12->authsafes))
+		{
+		PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES,PKCS12_R_CONTENT_TYPE_NOT_DATA);
+		return NULL;
+		}
+	return ASN1_item_unpack(p12->authsafes->d.data, ASN1_ITEM_rptr(PKCS12_AUTHSAFES));
+}
diff --git a/openssl/crypto/pkcs12/p12_asn.c b/openssl/crypto/pkcs12/p12_asn.c
new file mode 100644
index 0000000..6e27633
--- /dev/null
+++ b/openssl/crypto/pkcs12/p12_asn.c
@@ -0,0 +1,125 @@
+/* p12_asn.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pkcs12.h>
+
+/* PKCS#12 ASN1 module */
+
+ASN1_SEQUENCE(PKCS12) = {
+	ASN1_SIMPLE(PKCS12, version, ASN1_INTEGER),
+	ASN1_SIMPLE(PKCS12, authsafes, PKCS7),
+	ASN1_OPT(PKCS12, mac, PKCS12_MAC_DATA)
+} ASN1_SEQUENCE_END(PKCS12)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS12)
+
+ASN1_SEQUENCE(PKCS12_MAC_DATA) = {
+	ASN1_SIMPLE(PKCS12_MAC_DATA, dinfo, X509_SIG),
+	ASN1_SIMPLE(PKCS12_MAC_DATA, salt, ASN1_OCTET_STRING),
+	ASN1_OPT(PKCS12_MAC_DATA, iter, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(PKCS12_MAC_DATA)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS12_MAC_DATA)
+
+ASN1_ADB_TEMPLATE(bag_default) = ASN1_EXP(PKCS12_BAGS, value.other, ASN1_ANY, 0);
+
+ASN1_ADB(PKCS12_BAGS) = {
+	ADB_ENTRY(NID_x509Certificate, ASN1_EXP(PKCS12_BAGS, value.x509cert, ASN1_OCTET_STRING, 0)),
+	ADB_ENTRY(NID_x509Crl, ASN1_EXP(PKCS12_BAGS, value.x509crl, ASN1_OCTET_STRING, 0)),
+	ADB_ENTRY(NID_sdsiCertificate, ASN1_EXP(PKCS12_BAGS, value.sdsicert, ASN1_IA5STRING, 0)),
+} ASN1_ADB_END(PKCS12_BAGS, 0, type, 0, &bag_default_tt, NULL);
+
+ASN1_SEQUENCE(PKCS12_BAGS) = {
+	ASN1_SIMPLE(PKCS12_BAGS, type, ASN1_OBJECT),
+	ASN1_ADB_OBJECT(PKCS12_BAGS),
+} ASN1_SEQUENCE_END(PKCS12_BAGS)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS12_BAGS)
+
+ASN1_ADB_TEMPLATE(safebag_default) = ASN1_EXP(PKCS12_SAFEBAG, value.other, ASN1_ANY, 0);
+
+ASN1_ADB(PKCS12_SAFEBAG) = {
+	ADB_ENTRY(NID_keyBag, ASN1_EXP(PKCS12_SAFEBAG, value.keybag, PKCS8_PRIV_KEY_INFO, 0)),
+	ADB_ENTRY(NID_pkcs8ShroudedKeyBag, ASN1_EXP(PKCS12_SAFEBAG, value.shkeybag, X509_SIG, 0)),
+	ADB_ENTRY(NID_safeContentsBag, ASN1_EXP_SET_OF(PKCS12_SAFEBAG, value.safes, PKCS12_SAFEBAG, 0)),
+	ADB_ENTRY(NID_certBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)),
+	ADB_ENTRY(NID_crlBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)),
+	ADB_ENTRY(NID_secretBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0))
+} ASN1_ADB_END(PKCS12_SAFEBAG, 0, type, 0, &safebag_default_tt, NULL);
+
+ASN1_SEQUENCE(PKCS12_SAFEBAG) = {
+	ASN1_SIMPLE(PKCS12_SAFEBAG, type, ASN1_OBJECT),
+	ASN1_ADB_OBJECT(PKCS12_SAFEBAG),
+	ASN1_SET_OF_OPT(PKCS12_SAFEBAG, attrib, X509_ATTRIBUTE)
+} ASN1_SEQUENCE_END(PKCS12_SAFEBAG)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS12_SAFEBAG)
+
+/* SEQUENCE OF SafeBag */
+ASN1_ITEM_TEMPLATE(PKCS12_SAFEBAGS) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_SAFEBAGS, PKCS12_SAFEBAG)
+ASN1_ITEM_TEMPLATE_END(PKCS12_SAFEBAGS)
+
+/* Authsafes: SEQUENCE OF PKCS7 */
+ASN1_ITEM_TEMPLATE(PKCS12_AUTHSAFES) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_AUTHSAFES, PKCS7)
+ASN1_ITEM_TEMPLATE_END(PKCS12_AUTHSAFES)
+
diff --git a/openssl/crypto/pkcs12/p12_attr.c b/openssl/crypto/pkcs12/p12_attr.c
new file mode 100644
index 0000000..e4d9c25
--- /dev/null
+++ b/openssl/crypto/pkcs12/p12_attr.c
@@ -0,0 +1,145 @@
+/* p12_attr.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* Add a local keyid to a safebag */
+
+int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name,
+	     int namelen)
+{
+	if (X509at_add1_attr_by_NID(&bag->attrib, NID_localKeyID,
+				V_ASN1_OCTET_STRING, name, namelen))
+		return 1;
+	else 
+		return 0;
+}
+
+/* Add key usage to PKCS#8 structure */
+
+int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage)
+{
+	unsigned char us_val;
+	us_val = (unsigned char) usage;
+	if (X509at_add1_attr_by_NID(&p8->attributes, NID_key_usage,
+				V_ASN1_BIT_STRING, &us_val, 1))
+		return 1;
+	else
+		return 0;
+}
+
+/* Add a friendlyname to a safebag */
+
+int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name,
+				 int namelen)
+{
+	if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName,
+				MBSTRING_ASC, (unsigned char *)name, namelen))
+		return 1;
+	else
+		return 0;
+}
+
+
+int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag,
+				 const unsigned char *name, int namelen)
+{
+	if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName,
+				MBSTRING_BMP, name, namelen))
+		return 1;
+	else
+		return 0;
+}
+
+int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name,
+				 int namelen)
+{
+	if (X509at_add1_attr_by_NID(&bag->attrib, NID_ms_csp_name,
+				MBSTRING_ASC, (unsigned char *)name, namelen))
+		return 1;
+	else
+		return 0;
+}
+
+ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid)
+{
+	X509_ATTRIBUTE *attrib;
+	int i;
+	if (!attrs) return NULL;
+	for (i = 0; i < sk_X509_ATTRIBUTE_num (attrs); i++) {
+		attrib = sk_X509_ATTRIBUTE_value (attrs, i);
+		if (OBJ_obj2nid (attrib->object) == attr_nid) {
+			if (sk_ASN1_TYPE_num (attrib->value.set))
+			    return sk_ASN1_TYPE_value(attrib->value.set, 0);
+			else return NULL;
+		}
+	}
+	return NULL;
+}
+
+char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag)
+{
+	ASN1_TYPE *atype;
+	if (!(atype = PKCS12_get_attr(bag, NID_friendlyName))) return NULL;
+	if (atype->type != V_ASN1_BMPSTRING) return NULL;
+	return OPENSSL_uni2asc(atype->value.bmpstring->data,
+				 atype->value.bmpstring->length);
+}
+
diff --git a/openssl/crypto/pkcs12/p12_crpt.c b/openssl/crypto/pkcs12/p12_crpt.c
new file mode 100644
index 0000000..b71d07b
--- /dev/null
+++ b/openssl/crypto/pkcs12/p12_crpt.c
@@ -0,0 +1,112 @@
+/* p12_crpt.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* PKCS#12 PBE algorithms now in static table */
+
+void PKCS12_PBE_add(void)
+{
+}
+
+int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+		ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, int en_de)
+{
+	PBEPARAM *pbe;
+	int saltlen, iter, ret;
+	unsigned char *salt;
+	const unsigned char *pbuf;
+	unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
+
+	/* Extract useful info from parameter */
+	if (param == NULL || param->type != V_ASN1_SEQUENCE ||
+	    param->value.sequence == NULL) {
+		PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN,PKCS12_R_DECODE_ERROR);
+		return 0;
+	}
+
+	pbuf = param->value.sequence->data;
+	if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) {
+		PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN,PKCS12_R_DECODE_ERROR);
+		return 0;
+	}
+
+	if (!pbe->iter) iter = 1;
+	else iter = ASN1_INTEGER_get (pbe->iter);
+	salt = pbe->salt->data;
+	saltlen = pbe->salt->length;
+	if (!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_KEY_ID,
+			     iter, EVP_CIPHER_key_length(cipher), key, md)) {
+		PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN,PKCS12_R_KEY_GEN_ERROR);
+		PBEPARAM_free(pbe);
+		return 0;
+	}
+	if (!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_IV_ID,
+				iter, EVP_CIPHER_iv_length(cipher), iv, md)) {
+		PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN,PKCS12_R_IV_GEN_ERROR);
+		PBEPARAM_free(pbe);
+		return 0;
+	}
+	PBEPARAM_free(pbe);
+	ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, en_de);
+	OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
+	OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
+	return ret;
+}
diff --git a/openssl/crypto/pkcs12/p12_crt.c b/openssl/crypto/pkcs12/p12_crt.c
new file mode 100644
index 0000000..96b131d
--- /dev/null
+++ b/openssl/crypto/pkcs12/p12_crt.c
@@ -0,0 +1,359 @@
+/* p12_crt.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+
+static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag);
+
+static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid)
+	{
+	int idx;
+	X509_ATTRIBUTE *attr;
+	idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1);
+	if (idx < 0)
+		return 1;
+	attr = EVP_PKEY_get_attr(pkey, idx);
+	if (!X509at_add1_attr(&bag->attrib, attr))
+		return 0;
+	return 1;
+	}
+
+PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
+	     STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter,
+	     int keytype)
+{
+	PKCS12 *p12 = NULL;
+	STACK_OF(PKCS7) *safes = NULL;
+	STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
+	PKCS12_SAFEBAG *bag = NULL;
+	int i;
+	unsigned char keyid[EVP_MAX_MD_SIZE];
+	unsigned int keyidlen = 0;
+
+	/* Set defaults */
+	if (!nid_cert)
+		nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
+	if (!nid_key)
+		nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+	if (!iter)
+		iter = PKCS12_DEFAULT_ITER;
+	if (!mac_iter)
+		mac_iter = 1;
+
+	if(!pkey && !cert && !ca)
+		{
+		PKCS12err(PKCS12_F_PKCS12_CREATE,PKCS12_R_INVALID_NULL_ARGUMENT);
+		return NULL;
+		}
+
+	if (pkey && cert)
+		{
+		if(!X509_check_private_key(cert, pkey))
+			return NULL;
+		X509_digest(cert, EVP_sha1(), keyid, &keyidlen);
+		}
+
+	if (cert)
+		{
+		bag = PKCS12_add_cert(&bags, cert);
+		if(name && !PKCS12_add_friendlyname(bag, name, -1))
+			goto err;
+		if(keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
+			goto err;
+		}
+
+	/* Add all other certificates */
+	for(i = 0; i < sk_X509_num(ca); i++)
+		{
+		if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i)))
+			goto err;
+		}
+
+	if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass))
+			goto err;
+
+	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+	bags = NULL;
+
+	if (pkey)
+		{
+		bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass);
+
+		if (!bag)
+			goto err;
+
+		if (!copy_bag_attr(bag, pkey, NID_ms_csp_name))
+			goto err;
+		if (!copy_bag_attr(bag, pkey, NID_LocalKeySet))
+			goto err;
+
+		if(name && !PKCS12_add_friendlyname(bag, name, -1))
+			goto err;
+		if(keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
+			goto err;
+		}
+
+	if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL))
+			goto err;
+
+	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+	bags = NULL;
+
+	p12 = PKCS12_add_safes(safes, 0);
+
+	if (!p12)
+		goto err;
+
+	sk_PKCS7_pop_free(safes, PKCS7_free);
+
+	safes = NULL;
+
+	if ((mac_iter != -1) &&
+		!PKCS12_set_mac(p12, pass, -1, NULL, 0, mac_iter, NULL))
+	    goto err;
+
+	return p12;
+
+	err:
+
+	if (p12)
+		PKCS12_free(p12);
+	if (safes)
+		sk_PKCS7_pop_free(safes, PKCS7_free);
+	if (bags)
+		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+	return NULL;
+
+}
+
+PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert)
+	{
+	PKCS12_SAFEBAG *bag = NULL;
+	char *name;
+	int namelen = -1;
+	unsigned char *keyid;
+	int keyidlen = -1;
+
+	/* Add user certificate */
+	if(!(bag = PKCS12_x5092certbag(cert)))
+		goto err;
+
+	/* Use friendlyName and localKeyID in certificate.
+	 * (if present)
+	 */
+
+	name = (char *)X509_alias_get0(cert, &namelen);
+
+	if(name && !PKCS12_add_friendlyname(bag, name, namelen))
+		goto err;
+
+	keyid = X509_keyid_get0(cert, &keyidlen);
+
+	if(keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
+		goto err;
+
+	if (!pkcs12_add_bag(pbags, bag))
+		goto err;
+
+	return bag;
+
+	err:
+
+	if (bag)
+		PKCS12_SAFEBAG_free(bag);
+
+	return NULL;
+
+	}
+
+PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, EVP_PKEY *key,
+						int key_usage, int iter,
+						int nid_key, char *pass)
+	{
+
+	PKCS12_SAFEBAG *bag = NULL;
+	PKCS8_PRIV_KEY_INFO *p8 = NULL;
+
+	/* Make a PKCS#8 structure */
+	if(!(p8 = EVP_PKEY2PKCS8(key)))
+		goto err;
+	if(key_usage && !PKCS8_add_keyusage(p8, key_usage))
+		goto err;
+	if (nid_key != -1)
+		{
+		bag = PKCS12_MAKE_SHKEYBAG(nid_key, pass, -1, NULL, 0, iter, p8);
+		PKCS8_PRIV_KEY_INFO_free(p8);
+		}
+	else
+		bag = PKCS12_MAKE_KEYBAG(p8);
+
+	if(!bag)
+		goto err;
+
+	if (!pkcs12_add_bag(pbags, bag))
+		goto err;
+
+	return bag;
+
+	err:
+
+	if (bag)
+		PKCS12_SAFEBAG_free(bag);
+
+	return NULL;
+
+	}
+
+int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
+						int nid_safe, int iter, char *pass)
+	{
+	PKCS7 *p7 = NULL;
+	int free_safes = 0;
+
+	if (!*psafes)
+		{
+		*psafes = sk_PKCS7_new_null();
+		if (!*psafes)
+			return 0;
+		free_safes = 1;
+		}
+	else
+		free_safes = 0;
+
+	if (nid_safe == 0)
+		nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC;
+
+	if (nid_safe == -1)
+		p7 = PKCS12_pack_p7data(bags);
+	else
+		p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0,
+					  iter, bags);
+	if (!p7)
+		goto err;
+
+	if (!sk_PKCS7_push(*psafes, p7))
+		goto err;
+
+	return 1;
+
+	err:
+	if (free_safes)
+		{
+		sk_PKCS7_free(*psafes);
+		*psafes = NULL;
+		}
+
+	if (p7)
+		PKCS7_free(p7);
+
+	return 0;
+
+	}
+
+static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag)
+	{
+	int free_bags;
+	if (!pbags)
+		return 1;
+	if (!*pbags)
+		{
+		*pbags = sk_PKCS12_SAFEBAG_new_null();
+		if (!*pbags)
+			return 0;
+		free_bags = 1;
+		}
+	else 
+		free_bags = 0;
+
+	if (!sk_PKCS12_SAFEBAG_push(*pbags, bag))
+		{
+		if (free_bags)
+			{
+			sk_PKCS12_SAFEBAG_free(*pbags);
+			*pbags = NULL;
+			}
+		return 0;
+		}
+
+	return 1;
+
+	}
+		
+
+PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7)
+	{
+	PKCS12 *p12;
+	if (nid_p7 <= 0)
+		nid_p7 = NID_pkcs7_data;
+	p12 = PKCS12_init(nid_p7);
+
+	if (!p12)
+		return NULL;
+
+	if(!PKCS12_pack_authsafes(p12, safes))
+		{
+		PKCS12_free(p12);
+		return NULL;
+		}
+
+	return p12;
+
+	}
diff --git a/openssl/crypto/pkcs12/p12_decr.c b/openssl/crypto/pkcs12/p12_decr.c
new file mode 100644
index 0000000..ba77dbb
--- /dev/null
+++ b/openssl/crypto/pkcs12/p12_decr.c
@@ -0,0 +1,177 @@
+/* p12_decr.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* Define this to dump decrypted output to files called DERnnn */
+/*#define DEBUG_DECRYPT*/
+
+
+/* Encrypt/Decrypt a buffer based on password and algor, result in a
+ * OPENSSL_malloc'ed buffer
+ */
+
+unsigned char * PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass,
+	     int passlen, unsigned char *in, int inlen, unsigned char **data,
+	     int *datalen, int en_de)
+{
+	unsigned char *out;
+	int outlen, i;
+	EVP_CIPHER_CTX ctx;
+
+	EVP_CIPHER_CTX_init(&ctx);
+	/* Decrypt data */
+        if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen,
+					 algor->parameter, &ctx, en_de)) {
+		PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR);
+		return NULL;
+	}
+
+	if(!(out = OPENSSL_malloc(inlen + EVP_CIPHER_CTX_block_size(&ctx)))) {
+		PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	EVP_CipherUpdate(&ctx, out, &i, in, inlen);
+	outlen = i;
+	if(!EVP_CipherFinal_ex(&ctx, out + i, &i)) {
+		OPENSSL_free(out);
+		out = NULL;
+		PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,PKCS12_R_PKCS12_CIPHERFINAL_ERROR);
+		goto err;
+	}
+	outlen += i;
+	if (datalen) *datalen = outlen;
+	if (data) *data = out;
+	err:
+	EVP_CIPHER_CTX_cleanup(&ctx);
+	return out;
+
+}
+
+/* Decrypt an OCTET STRING and decode ASN1 structure 
+ * if zbuf set zero buffer after use.
+ */
+
+void * PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it,
+	     const char *pass, int passlen, ASN1_OCTET_STRING *oct, int zbuf)
+{
+	unsigned char *out;
+	const unsigned char *p;
+	void *ret;
+	int outlen;
+
+	if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length,
+			       &out, &outlen, 0)) {
+		PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I,PKCS12_R_PKCS12_PBE_CRYPT_ERROR);
+		return NULL;
+	}
+	p = out;
+#ifdef DEBUG_DECRYPT
+	{
+		FILE *op;
+
+		char fname[30];
+		static int fnm = 1;
+		sprintf(fname, "DER%d", fnm++);
+		op = fopen(fname, "wb");
+		fwrite (p, 1, outlen, op);
+		fclose(op);
+	}
+#endif
+	ret = ASN1_item_d2i(NULL, &p, outlen, it);
+	if (zbuf) OPENSSL_cleanse(out, outlen);
+	if(!ret) PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I,PKCS12_R_DECODE_ERROR);
+	OPENSSL_free(out);
+	return ret;
+}
+
+/* Encode ASN1 structure and encrypt, return OCTET STRING 
+ * if zbuf set zero encoding.
+ */
+
+ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, const ASN1_ITEM *it,
+				       const char *pass, int passlen,
+				       void *obj, int zbuf)
+{
+	ASN1_OCTET_STRING *oct;
+	unsigned char *in = NULL;
+	int inlen;
+	if (!(oct = M_ASN1_OCTET_STRING_new ())) {
+		PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	inlen = ASN1_item_i2d(obj, &in, it);
+	if (!in) {
+		PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT,PKCS12_R_ENCODE_ERROR);
+		return NULL;
+	}
+	if (!PKCS12_pbe_crypt(algor, pass, passlen, in, inlen, &oct->data,
+				 &oct->length, 1)) {
+		PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT,PKCS12_R_ENCRYPT_ERROR);
+		OPENSSL_free(in);
+		return NULL;
+	}
+	if (zbuf) OPENSSL_cleanse(in, inlen);
+	OPENSSL_free(in);
+	return oct;
+}
+
+IMPLEMENT_PKCS12_STACK_OF(PKCS7)
diff --git a/openssl/crypto/pkcs12/p12_init.c b/openssl/crypto/pkcs12/p12_init.c
new file mode 100644
index 0000000..d4d84b0
--- /dev/null
+++ b/openssl/crypto/pkcs12/p12_init.c
@@ -0,0 +1,92 @@
+/* p12_init.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* Initialise a PKCS12 structure to take data */
+
+PKCS12 *PKCS12_init(int mode)
+{
+	PKCS12 *pkcs12;
+	if (!(pkcs12 = PKCS12_new())) {
+		PKCS12err(PKCS12_F_PKCS12_INIT,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	ASN1_INTEGER_set(pkcs12->version, 3);
+	pkcs12->authsafes->type = OBJ_nid2obj(mode);
+	switch (mode) {
+		case NID_pkcs7_data:
+			if (!(pkcs12->authsafes->d.data =
+				 M_ASN1_OCTET_STRING_new())) {
+			PKCS12err(PKCS12_F_PKCS12_INIT,ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		break;
+		default:
+			PKCS12err(PKCS12_F_PKCS12_INIT,
+				PKCS12_R_UNSUPPORTED_PKCS12_MODE);
+			goto err;
+	}
+		
+	return pkcs12;
+err:
+	if (pkcs12 != NULL) PKCS12_free(pkcs12);
+	return NULL;
+}
diff --git a/openssl/crypto/pkcs12/p12_key.c b/openssl/crypto/pkcs12/p12_key.c
new file mode 100644
index 0000000..424203f
--- /dev/null
+++ b/openssl/crypto/pkcs12/p12_key.c
@@ -0,0 +1,217 @@
+/* p12_key.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+#include <openssl/bn.h>
+
+/* Uncomment out this line to get debugging info about key generation */
+/*#define DEBUG_KEYGEN*/
+#ifdef DEBUG_KEYGEN
+#include <openssl/bio.h>
+extern BIO *bio_err;
+void h__dump (unsigned char *p, int len);
+#endif
+
+/* PKCS12 compatible key/IV generation */
+#ifndef min
+#define min(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
+	     int saltlen, int id, int iter, int n, unsigned char *out,
+	     const EVP_MD *md_type)
+{
+	int ret;
+	unsigned char *unipass;
+	int uniplen;
+
+	if(!pass) {
+		unipass = NULL;
+		uniplen = 0;
+	} else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) {
+		PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC,ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen,
+						 id, iter, n, out, md_type);
+	if (ret <= 0)
+	    return 0;
+	if(unipass) {
+		OPENSSL_cleanse(unipass, uniplen);	/* Clear password from memory */
+		OPENSSL_free(unipass);
+	}
+	return ret;
+}
+
+int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
+	     int saltlen, int id, int iter, int n, unsigned char *out,
+	     const EVP_MD *md_type)
+{
+	unsigned char *B, *D, *I, *p, *Ai;
+	int Slen, Plen, Ilen, Ijlen;
+	int i, j, u, v;
+	int ret = 0;
+	BIGNUM *Ij, *Bpl1;	/* These hold Ij and B + 1 */
+	EVP_MD_CTX ctx;
+#ifdef  DEBUG_KEYGEN
+	unsigned char *tmpout = out;
+	int tmpn = n;
+#endif
+
+#if 0
+	if (!pass) {
+		PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI,ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+#endif
+
+	EVP_MD_CTX_init(&ctx);
+#ifdef  DEBUG_KEYGEN
+	fprintf(stderr, "KEYGEN DEBUG\n");
+	fprintf(stderr, "ID %d, ITER %d\n", id, iter);
+	fprintf(stderr, "Password (length %d):\n", passlen);
+	h__dump(pass, passlen);
+	fprintf(stderr, "Salt (length %d):\n", saltlen);
+	h__dump(salt, saltlen);
+#endif
+	v = EVP_MD_block_size (md_type);
+	u = EVP_MD_size (md_type);
+	if (u < 0)
+	    return 0;
+	D = OPENSSL_malloc (v);
+	Ai = OPENSSL_malloc (u);
+	B = OPENSSL_malloc (v + 1);
+	Slen = v * ((saltlen+v-1)/v);
+	if(passlen) Plen = v * ((passlen+v-1)/v);
+	else Plen = 0;
+	Ilen = Slen + Plen;
+	I = OPENSSL_malloc (Ilen);
+	Ij = BN_new();
+	Bpl1 = BN_new();
+	if (!D || !Ai || !B || !I || !Ij || !Bpl1)
+		goto err;
+	for (i = 0; i < v; i++) D[i] = id;
+	p = I;
+	for (i = 0; i < Slen; i++) *p++ = salt[i % saltlen];
+	for (i = 0; i < Plen; i++) *p++ = pass[i % passlen];
+	for (;;) {
+		EVP_DigestInit_ex(&ctx, md_type, NULL);
+		EVP_DigestUpdate(&ctx, D, v);
+		EVP_DigestUpdate(&ctx, I, Ilen);
+		EVP_DigestFinal_ex(&ctx, Ai, NULL);
+		for (j = 1; j < iter; j++) {
+			EVP_DigestInit_ex(&ctx, md_type, NULL);
+			EVP_DigestUpdate(&ctx, Ai, u);
+			EVP_DigestFinal_ex(&ctx, Ai, NULL);
+		}
+		memcpy (out, Ai, min (n, u));
+		if (u >= n) {
+#ifdef DEBUG_KEYGEN
+			fprintf(stderr, "Output KEY (length %d)\n", tmpn);
+			h__dump(tmpout, tmpn);
+#endif
+			ret = 1;
+			goto end;
+		}
+		n -= u;
+		out += u;
+		for (j = 0; j < v; j++) B[j] = Ai[j % u];
+		/* Work out B + 1 first then can use B as tmp space */
+		if (!BN_bin2bn (B, v, Bpl1)) goto err;
+		if (!BN_add_word (Bpl1, 1)) goto err;
+		for (j = 0; j < Ilen ; j+=v) {
+			if (!BN_bin2bn (I + j, v, Ij)) goto err;
+			if (!BN_add (Ij, Ij, Bpl1)) goto err;
+			BN_bn2bin (Ij, B);
+			Ijlen = BN_num_bytes (Ij);
+			/* If more than 2^(v*8) - 1 cut off MSB */
+			if (Ijlen > v) {
+				BN_bn2bin (Ij, B);
+				memcpy (I + j, B + 1, v);
+#ifndef PKCS12_BROKEN_KEYGEN
+			/* If less than v bytes pad with zeroes */
+			} else if (Ijlen < v) {
+				memset(I + j, 0, v - Ijlen);
+				BN_bn2bin(Ij, I + j + v - Ijlen); 
+#endif
+			} else BN_bn2bin (Ij, I + j);
+		}
+	}
+
+err:
+	PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI,ERR_R_MALLOC_FAILURE);
+
+end:
+	OPENSSL_free (Ai);
+	OPENSSL_free (B);
+	OPENSSL_free (D);
+	OPENSSL_free (I);
+	BN_free (Ij);
+	BN_free (Bpl1);
+	EVP_MD_CTX_cleanup(&ctx);
+	return ret;
+}
+#ifdef DEBUG_KEYGEN
+void h__dump (unsigned char *p, int len)
+{
+	for (; len --; p++) fprintf(stderr, "%02X", *p);
+	fprintf(stderr, "\n");	
+}
+#endif
diff --git a/openssl/crypto/pkcs12/p12_kiss.c b/openssl/crypto/pkcs12/p12_kiss.c
new file mode 100644
index 0000000..292cc3e
--- /dev/null
+++ b/openssl/crypto/pkcs12/p12_kiss.c
@@ -0,0 +1,302 @@
+/* p12_kiss.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* Simplified PKCS#12 routines */
+
+static int parse_pk12( PKCS12 *p12, const char *pass, int passlen,
+		EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
+
+static int parse_bags( STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
+		       int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
+
+static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen,
+			EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
+
+/* Parse and decrypt a PKCS#12 structure returning user key, user cert
+ * and other (CA) certs. Note either ca should be NULL, *ca should be NULL,
+ * or it should point to a valid STACK structure. pkey and cert can be
+ * passed unitialised.
+ */
+
+int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
+	     STACK_OF(X509) **ca)
+{
+	STACK_OF(X509) *ocerts = NULL;
+	X509 *x = NULL;
+	/* Check for NULL PKCS12 structure */
+
+	if(!p12)
+		{
+		PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER);
+		return 0;
+		}
+
+	if(pkey)
+		*pkey = NULL;
+	if(cert)
+		*cert = NULL;
+
+	/* Check the mac */
+
+	/* If password is zero length or NULL then try verifying both cases
+	 * to determine which password is correct. The reason for this is that
+	 * under PKCS#12 password based encryption no password and a zero length
+	 * password are two different things...
+	 */
+
+	if(!pass || !*pass) {
+		if(PKCS12_verify_mac(p12, NULL, 0)) pass = NULL;
+		else if(PKCS12_verify_mac(p12, "", 0)) pass = "";
+		else {
+			PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE);
+			goto err;
+		}
+	} else if (!PKCS12_verify_mac(p12, pass, -1)) {
+		PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE);
+		goto err;
+	}
+
+	/* Allocate stack for other certificates */
+	ocerts = sk_X509_new_null();
+
+	if (!ocerts)
+		{
+		PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+
+	if (!parse_pk12 (p12, pass, -1, pkey, ocerts))
+		{
+		PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_PARSE_ERROR);
+		goto err;
+		}
+
+	while ((x = sk_X509_pop(ocerts)))
+		{
+		if (pkey && *pkey && cert && !*cert)
+			{
+			if (X509_check_private_key(x, *pkey))
+				{
+				*cert = x;
+				x = NULL;
+				}
+			}
+
+		if (ca && x)
+			{
+			if (!*ca)
+				*ca = sk_X509_new_null();
+			if (!*ca)
+				goto err;
+			if (!sk_X509_push(*ca, x))
+				goto err;
+			x = NULL;
+			}
+		if (x)
+			X509_free(x);
+		}
+
+	if (ocerts)
+		sk_X509_pop_free(ocerts, X509_free);
+
+	return 1;
+
+ err:
+
+	if (pkey && *pkey)
+		EVP_PKEY_free(*pkey);
+	if (cert && *cert)
+		X509_free(*cert);
+	if (x)
+		X509_free(*cert);
+	if (ocerts)
+		sk_X509_pop_free(ocerts, X509_free);
+	return 0;
+
+}
+
+/* Parse the outer PKCS#12 structure */
+
+static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
+	     EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
+{
+	STACK_OF(PKCS7) *asafes;
+	STACK_OF(PKCS12_SAFEBAG) *bags;
+	int i, bagnid;
+	PKCS7 *p7;
+
+	if (!(asafes = PKCS12_unpack_authsafes (p12))) return 0;
+	for (i = 0; i < sk_PKCS7_num (asafes); i++) {
+		p7 = sk_PKCS7_value (asafes, i);
+		bagnid = OBJ_obj2nid (p7->type);
+		if (bagnid == NID_pkcs7_data) {
+			bags = PKCS12_unpack_p7data(p7);
+		} else if (bagnid == NID_pkcs7_encrypted) {
+			bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
+		} else continue;
+		if (!bags) {
+			sk_PKCS7_pop_free(asafes, PKCS7_free);
+			return 0;
+		}
+	    	if (!parse_bags(bags, pass, passlen, pkey, ocerts)) {
+			sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+			sk_PKCS7_pop_free(asafes, PKCS7_free);
+			return 0;
+		}
+		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+	}
+	sk_PKCS7_pop_free(asafes, PKCS7_free);
+	return 1;
+}
+
+
+static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
+		      int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
+{
+	int i;
+	for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
+		if (!parse_bag(sk_PKCS12_SAFEBAG_value (bags, i),
+				 pass, passlen, pkey, ocerts))
+			return 0;
+	}
+	return 1;
+}
+
+static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
+		     EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
+{
+	PKCS8_PRIV_KEY_INFO *p8;
+	X509 *x509;
+	ASN1_TYPE *attrib;
+	ASN1_BMPSTRING *fname = NULL;
+	ASN1_OCTET_STRING *lkid = NULL;
+
+	if ((attrib = PKCS12_get_attr (bag, NID_friendlyName)))
+		fname = attrib->value.bmpstring;
+
+	if ((attrib = PKCS12_get_attr (bag, NID_localKeyID)))
+		lkid = attrib->value.octet_string;
+
+	switch (M_PKCS12_bag_type(bag))
+	{
+	case NID_keyBag:
+		if (!pkey || *pkey)
+			return 1;	
+		if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag)))
+			return 0;
+	break;
+
+	case NID_pkcs8ShroudedKeyBag:
+		if (!pkey || *pkey)
+			return 1;	
+		if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
+				return 0;
+		*pkey = EVP_PKCS82PKEY(p8);
+		PKCS8_PRIV_KEY_INFO_free(p8);
+		if (!(*pkey)) return 0;
+	break;
+
+	case NID_certBag:
+		if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )
+			return 1;
+		if (!(x509 = PKCS12_certbag2x509(bag)))
+			return 0;
+		if(lkid && !X509_keyid_set1(x509, lkid->data, lkid->length))
+			{
+			X509_free(x509);
+			return 0;
+			}
+		if(fname) {
+			int len, r;
+			unsigned char *data;
+			len = ASN1_STRING_to_UTF8(&data, fname);
+			if(len > 0) {
+				r = X509_alias_set1(x509, data, len);
+				OPENSSL_free(data);
+				if (!r)
+					{
+					X509_free(x509);
+					return 0;
+					}
+			}
+		}
+
+		if(!sk_X509_push(ocerts, x509))
+			{
+			X509_free(x509);
+			return 0;
+			}
+
+	break;
+
+	case NID_safeContentsBag:
+		return parse_bags(bag->value.safes, pass, passlen,
+			 		pkey, ocerts);
+	break;
+
+	default:
+		return 1;
+	break;
+	}
+	return 1;
+}
+
diff --git a/openssl/crypto/pkcs12/p12_mutl.c b/openssl/crypto/pkcs12/p12_mutl.c
new file mode 100644
index 0000000..9ab740d
--- /dev/null
+++ b/openssl/crypto/pkcs12/p12_mutl.c
@@ -0,0 +1,186 @@
+/* p12_mutl.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef OPENSSL_NO_HMAC
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/hmac.h>
+#include <openssl/rand.h>
+#include <openssl/pkcs12.h>
+
+/* Generate a MAC */
+int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
+		   unsigned char *mac, unsigned int *maclen)
+{
+	const EVP_MD *md_type;
+	HMAC_CTX hmac;
+	unsigned char key[EVP_MAX_MD_SIZE], *salt;
+	int saltlen, iter;
+	int md_size;
+
+	if (!PKCS7_type_is_data(p12->authsafes))
+		{
+		PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_CONTENT_TYPE_NOT_DATA);
+		return 0;
+		}
+
+	salt = p12->mac->salt->data;
+	saltlen = p12->mac->salt->length;
+	if (!p12->mac->iter) iter = 1;
+	else iter = ASN1_INTEGER_get (p12->mac->iter);
+    	if(!(md_type =
+		 EVP_get_digestbyobj (p12->mac->dinfo->algor->algorithm))) {
+		PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_UNKNOWN_DIGEST_ALGORITHM);
+		return 0;
+	}
+	md_size = EVP_MD_size(md_type);
+	if (md_size < 0)
+	    return 0;
+	if(!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter,
+				 md_size, key, md_type)) {
+		PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_KEY_GEN_ERROR);
+		return 0;
+	}
+	HMAC_CTX_init(&hmac);
+	HMAC_Init_ex(&hmac, key, md_size, md_type, NULL);
+    	HMAC_Update(&hmac, p12->authsafes->d.data->data,
+					 p12->authsafes->d.data->length);
+    	HMAC_Final(&hmac, mac, maclen);
+    	HMAC_CTX_cleanup(&hmac);
+	return 1;
+}
+
+/* Verify the mac */
+int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen)
+{
+	unsigned char mac[EVP_MAX_MD_SIZE];
+	unsigned int maclen;
+	if(p12->mac == NULL) {
+		PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC,PKCS12_R_MAC_ABSENT);
+		return 0;
+	}
+	if (!PKCS12_gen_mac (p12, pass, passlen, mac, &maclen)) {
+		PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC,PKCS12_R_MAC_GENERATION_ERROR);
+		return 0;
+	}
+	if ((maclen != (unsigned int)p12->mac->dinfo->digest->length)
+	|| memcmp (mac, p12->mac->dinfo->digest->data, maclen)) return 0;
+	return 1;
+}
+
+/* Set a mac */
+
+int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
+	     unsigned char *salt, int saltlen, int iter, const EVP_MD *md_type)
+{
+	unsigned char mac[EVP_MAX_MD_SIZE];
+	unsigned int maclen;
+
+	if (!md_type) md_type = EVP_sha1();
+	if (PKCS12_setup_mac (p12, iter, salt, saltlen, md_type) ==
+				 	PKCS12_ERROR) {
+		PKCS12err(PKCS12_F_PKCS12_SET_MAC,PKCS12_R_MAC_SETUP_ERROR);
+		return 0;
+	}
+	if (!PKCS12_gen_mac (p12, pass, passlen, mac, &maclen)) {
+		PKCS12err(PKCS12_F_PKCS12_SET_MAC,PKCS12_R_MAC_GENERATION_ERROR);
+		return 0;
+	}
+	if (!(M_ASN1_OCTET_STRING_set (p12->mac->dinfo->digest, mac, maclen))) {
+		PKCS12err(PKCS12_F_PKCS12_SET_MAC,PKCS12_R_MAC_STRING_SET_ERROR);
+						return 0;
+	}
+	return 1;
+}
+
+/* Set up a mac structure */
+int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen,
+	     const EVP_MD *md_type)
+{
+	if (!(p12->mac = PKCS12_MAC_DATA_new())) return PKCS12_ERROR;
+	if (iter > 1) {
+		if(!(p12->mac->iter = M_ASN1_INTEGER_new())) {
+			PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		if (!ASN1_INTEGER_set(p12->mac->iter, iter)) {
+			PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+	}
+	if (!saltlen) saltlen = PKCS12_SALT_LEN;
+	p12->mac->salt->length = saltlen;
+	if (!(p12->mac->salt->data = OPENSSL_malloc (saltlen))) {
+		PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	if (!salt) {
+		if (RAND_pseudo_bytes (p12->mac->salt->data, saltlen) < 0)
+			return 0;
+	}
+	else memcpy (p12->mac->salt->data, salt, saltlen);
+	p12->mac->dinfo->algor->algorithm = OBJ_nid2obj(EVP_MD_type(md_type));
+	if (!(p12->mac->dinfo->algor->parameter = ASN1_TYPE_new())) {
+		PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	p12->mac->dinfo->algor->parameter->type = V_ASN1_NULL;
+	
+	return 1;
+}
+#endif
diff --git a/openssl/crypto/pkcs12/p12_npas.c b/openssl/crypto/pkcs12/p12_npas.c
new file mode 100644
index 0000000..2f71355
--- /dev/null
+++ b/openssl/crypto/pkcs12/p12_npas.c
@@ -0,0 +1,225 @@
+/* p12_npas.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/pkcs12.h>
+
+/* PKCS#12 password change routine */
+
+static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass);
+static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass,
+			char *newpass);
+static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass);
+static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen);
+
+/* 
+ * Change the password on a PKCS#12 structure.
+ */
+
+int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass)
+{
+	/* Check for NULL PKCS12 structure */
+
+	if(!p12) {
+		PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_INVALID_NULL_PKCS12_POINTER);
+		return 0;
+	}
+
+	/* Check the mac */
+	
+	if (!PKCS12_verify_mac(p12, oldpass, -1)) {
+		PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_MAC_VERIFY_FAILURE);
+		return 0;
+	}
+
+	if (!newpass_p12(p12, oldpass, newpass)) {
+		PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_PARSE_ERROR);
+		return 0;
+	}
+
+	return 1;
+}
+
+/* Parse the outer PKCS#12 structure */
+
+static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass)
+{
+	STACK_OF(PKCS7) *asafes, *newsafes;
+	STACK_OF(PKCS12_SAFEBAG) *bags;
+	int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0;
+	PKCS7 *p7, *p7new;
+	ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL;
+	unsigned char mac[EVP_MAX_MD_SIZE];
+	unsigned int maclen;
+
+	if (!(asafes = PKCS12_unpack_authsafes(p12))) return 0;
+	if(!(newsafes = sk_PKCS7_new_null())) return 0;
+	for (i = 0; i < sk_PKCS7_num (asafes); i++) {
+		p7 = sk_PKCS7_value(asafes, i);
+		bagnid = OBJ_obj2nid(p7->type);
+		if (bagnid == NID_pkcs7_data) {
+			bags = PKCS12_unpack_p7data(p7);
+		} else if (bagnid == NID_pkcs7_encrypted) {
+			bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
+			if (!alg_get(p7->d.encrypted->enc_data->algorithm,
+				&pbe_nid, &pbe_iter, &pbe_saltlen))
+				{
+				sk_PKCS12_SAFEBAG_pop_free(bags,
+						PKCS12_SAFEBAG_free);
+				bags = NULL;
+				}
+		} else continue;
+		if (!bags) {
+			sk_PKCS7_pop_free(asafes, PKCS7_free);
+			return 0;
+		}
+	    	if (!newpass_bags(bags, oldpass, newpass)) {
+			sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+			sk_PKCS7_pop_free(asafes, PKCS7_free);
+			return 0;
+		}
+		/* Repack bag in same form with new password */
+		if (bagnid == NID_pkcs7_data) p7new = PKCS12_pack_p7data(bags);
+		else p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL,
+						 pbe_saltlen, pbe_iter, bags);
+		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+		if(!p7new) {
+			sk_PKCS7_pop_free(asafes, PKCS7_free);
+			return 0;
+		}
+		sk_PKCS7_push(newsafes, p7new);
+	}
+	sk_PKCS7_pop_free(asafes, PKCS7_free);
+
+	/* Repack safe: save old safe in case of error */
+
+	p12_data_tmp = p12->authsafes->d.data;
+	if(!(p12->authsafes->d.data = ASN1_OCTET_STRING_new())) goto saferr;
+	if(!PKCS12_pack_authsafes(p12, newsafes)) goto saferr;
+
+	if(!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen)) goto saferr;
+	if(!(macnew = ASN1_OCTET_STRING_new())) goto saferr;
+	if(!ASN1_OCTET_STRING_set(macnew, mac, maclen)) goto saferr;
+	ASN1_OCTET_STRING_free(p12->mac->dinfo->digest);
+	p12->mac->dinfo->digest = macnew;
+	ASN1_OCTET_STRING_free(p12_data_tmp);
+
+	return 1;
+
+	saferr:
+	/* Restore old safe */
+	ASN1_OCTET_STRING_free(p12->authsafes->d.data);
+	ASN1_OCTET_STRING_free(macnew);
+	p12->authsafes->d.data = p12_data_tmp;
+	return 0;
+
+}
+
+
+static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass,
+			char *newpass)
+{
+	int i;
+	for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
+		if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i),
+				 oldpass, newpass))
+		    return 0;
+	}
+	return 1;
+}
+
+/* Change password of safebag: only needs handle shrouded keybags */
+
+static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass)
+{
+	PKCS8_PRIV_KEY_INFO *p8;
+	X509_SIG *p8new;
+	int p8_nid, p8_saltlen, p8_iter;
+
+	if(M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag) return 1;
+
+	if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1))) return 0;
+	if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter,
+							&p8_saltlen))
+		return 0;
+	if(!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen,
+						     p8_iter, p8))) return 0;
+	X509_SIG_free(bag->value.shkeybag);
+	bag->value.shkeybag = p8new;
+	return 1;
+}
+
+static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen)
+{
+        PBEPARAM *pbe;
+        const unsigned char *p;
+
+        p = alg->parameter->value.sequence->data;
+        pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length);
+	if (!pbe)
+		return 0;
+        *pnid = OBJ_obj2nid(alg->algorithm);
+	*piter = ASN1_INTEGER_get(pbe->iter);
+	*psaltlen = pbe->salt->length;
+        PBEPARAM_free(pbe);
+        return 1;
+}
diff --git a/openssl/crypto/pkcs12/p12_p8d.c b/openssl/crypto/pkcs12/p12_p8d.c
new file mode 100644
index 0000000..deba81e
--- /dev/null
+++ b/openssl/crypto/pkcs12/p12_p8d.c
@@ -0,0 +1,68 @@
+/* p12_p8d.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass, int passlen)
+{
+	return PKCS12_item_decrypt_d2i(p8->algor, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass,
+					passlen, p8->digest, 1);
+}
+
diff --git a/openssl/crypto/pkcs12/p12_p8e.c b/openssl/crypto/pkcs12/p12_p8e.c
new file mode 100644
index 0000000..bf20a77
--- /dev/null
+++ b/openssl/crypto/pkcs12/p12_p8e.c
@@ -0,0 +1,97 @@
+/* p12_p8e.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
+			 const char *pass, int passlen,
+			 unsigned char *salt, int saltlen, int iter,
+						PKCS8_PRIV_KEY_INFO *p8inf)
+{
+	X509_SIG *p8 = NULL;
+	X509_ALGOR *pbe;
+
+	if (!(p8 = X509_SIG_new())) {
+		PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if(pbe_nid == -1) pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen);
+	else pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
+	if(!pbe) {
+		PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_ASN1_LIB);
+		goto err;
+	}
+	X509_ALGOR_free(p8->algor);
+	p8->algor = pbe;
+	M_ASN1_OCTET_STRING_free(p8->digest);
+	p8->digest = PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO),
+					pass, passlen, p8inf, 1);
+	if(!p8->digest) {
+		PKCS12err(PKCS12_F_PKCS8_ENCRYPT, PKCS12_R_ENCRYPT_ERROR);
+		goto err;
+	}
+
+	return p8;
+
+	err:
+	X509_SIG_free(p8);
+	return NULL;
+}
diff --git a/openssl/crypto/pkcs12/p12_utl.c b/openssl/crypto/pkcs12/p12_utl.c
new file mode 100644
index 0000000..59c6f45
--- /dev/null
+++ b/openssl/crypto/pkcs12/p12_utl.c
@@ -0,0 +1,146 @@
+/* p12_utl.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* Cheap and nasty Unicode stuff */
+
+unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen)
+{
+	int ulen, i;
+	unsigned char *unitmp;
+	if (asclen == -1) asclen = strlen(asc);
+	ulen = asclen*2  + 2;
+	if (!(unitmp = OPENSSL_malloc(ulen))) return NULL;
+	for (i = 0; i < ulen - 2; i+=2) {
+		unitmp[i] = 0;
+		unitmp[i + 1] = asc[i>>1];
+	}
+	/* Make result double null terminated */
+	unitmp[ulen - 2] = 0;
+	unitmp[ulen - 1] = 0;
+	if (unilen) *unilen = ulen;
+	if (uni) *uni = unitmp;
+	return unitmp;
+}
+
+char *OPENSSL_uni2asc(unsigned char *uni, int unilen)
+{
+	int asclen, i;
+	char *asctmp;
+	asclen = unilen / 2;
+	/* If no terminating zero allow for one */
+	if (!unilen || uni[unilen - 1]) asclen++;
+	uni++;
+	if (!(asctmp = OPENSSL_malloc(asclen))) return NULL;
+	for (i = 0; i < unilen; i+=2) asctmp[i>>1] = uni[i];
+	asctmp[asclen - 1] = 0;
+	return asctmp;
+}
+
+int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12)
+{
+	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS12), bp, p12);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12)
+{
+	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS12), fp, p12);
+}
+#endif
+
+PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12)
+{
+	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS12), bp, p12);
+}
+#ifndef OPENSSL_NO_FP_API
+PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12)
+{
+        return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS12), fp, p12);
+}
+#endif
+
+PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509)
+{
+	return PKCS12_item_pack_safebag(x509, ASN1_ITEM_rptr(X509),
+			NID_x509Certificate, NID_certBag);
+}
+
+PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl)
+{
+	return PKCS12_item_pack_safebag(crl, ASN1_ITEM_rptr(X509_CRL),
+			NID_x509Crl, NID_crlBag);
+}
+
+X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag)
+{
+	if(M_PKCS12_bag_type(bag) != NID_certBag) return NULL;
+	if(M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) return NULL;
+	return ASN1_item_unpack(bag->value.bag->value.octet, ASN1_ITEM_rptr(X509));
+}
+
+X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag)
+{
+	if(M_PKCS12_bag_type(bag) != NID_crlBag) return NULL;
+	if(M_PKCS12_cert_bag_type(bag) != NID_x509Crl) return NULL;
+	return ASN1_item_unpack(bag->value.bag->value.octet,
+							ASN1_ITEM_rptr(X509_CRL));
+}
diff --git a/openssl/crypto/pkcs12/pk12err.c b/openssl/crypto/pkcs12/pk12err.c
new file mode 100644
index 0000000..f6ddf2d
--- /dev/null
+++ b/openssl/crypto/pkcs12/pk12err.c
@@ -0,0 +1,144 @@
+/* crypto/pkcs12/pk12err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/pkcs12.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS12,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS12,0,reason)
+
+static ERR_STRING_DATA PKCS12_str_functs[]=
+	{
+{ERR_FUNC(PKCS12_F_PARSE_BAG),	"PARSE_BAG"},
+{ERR_FUNC(PKCS12_F_PARSE_BAGS),	"PARSE_BAGS"},
+{ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME),	"PKCS12_ADD_FRIENDLYNAME"},
+{ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC),	"PKCS12_add_friendlyname_asc"},
+{ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI),	"PKCS12_add_friendlyname_uni"},
+{ERR_FUNC(PKCS12_F_PKCS12_ADD_LOCALKEYID),	"PKCS12_add_localkeyid"},
+{ERR_FUNC(PKCS12_F_PKCS12_CREATE),	"PKCS12_create"},
+{ERR_FUNC(PKCS12_F_PKCS12_GEN_MAC),	"PKCS12_gen_mac"},
+{ERR_FUNC(PKCS12_F_PKCS12_INIT),	"PKCS12_init"},
+{ERR_FUNC(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I),	"PKCS12_item_decrypt_d2i"},
+{ERR_FUNC(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT),	"PKCS12_item_i2d_encrypt"},
+{ERR_FUNC(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG),	"PKCS12_item_pack_safebag"},
+{ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_ASC),	"PKCS12_key_gen_asc"},
+{ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_UNI),	"PKCS12_key_gen_uni"},
+{ERR_FUNC(PKCS12_F_PKCS12_MAKE_KEYBAG),	"PKCS12_MAKE_KEYBAG"},
+{ERR_FUNC(PKCS12_F_PKCS12_MAKE_SHKEYBAG),	"PKCS12_MAKE_SHKEYBAG"},
+{ERR_FUNC(PKCS12_F_PKCS12_NEWPASS),	"PKCS12_newpass"},
+{ERR_FUNC(PKCS12_F_PKCS12_PACK_P7DATA),	"PKCS12_pack_p7data"},
+{ERR_FUNC(PKCS12_F_PKCS12_PACK_P7ENCDATA),	"PKCS12_pack_p7encdata"},
+{ERR_FUNC(PKCS12_F_PKCS12_PARSE),	"PKCS12_parse"},
+{ERR_FUNC(PKCS12_F_PKCS12_PBE_CRYPT),	"PKCS12_pbe_crypt"},
+{ERR_FUNC(PKCS12_F_PKCS12_PBE_KEYIVGEN),	"PKCS12_PBE_keyivgen"},
+{ERR_FUNC(PKCS12_F_PKCS12_SETUP_MAC),	"PKCS12_setup_mac"},
+{ERR_FUNC(PKCS12_F_PKCS12_SET_MAC),	"PKCS12_set_mac"},
+{ERR_FUNC(PKCS12_F_PKCS12_UNPACK_AUTHSAFES),	"PKCS12_unpack_authsafes"},
+{ERR_FUNC(PKCS12_F_PKCS12_UNPACK_P7DATA),	"PKCS12_unpack_p7data"},
+{ERR_FUNC(PKCS12_F_PKCS12_VERIFY_MAC),	"PKCS12_verify_mac"},
+{ERR_FUNC(PKCS12_F_PKCS8_ADD_KEYUSAGE),	"PKCS8_add_keyusage"},
+{ERR_FUNC(PKCS12_F_PKCS8_ENCRYPT),	"PKCS8_encrypt"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA PKCS12_str_reasons[]=
+	{
+{ERR_REASON(PKCS12_R_CANT_PACK_STRUCTURE),"cant pack structure"},
+{ERR_REASON(PKCS12_R_CONTENT_TYPE_NOT_DATA),"content type not data"},
+{ERR_REASON(PKCS12_R_DECODE_ERROR)       ,"decode error"},
+{ERR_REASON(PKCS12_R_ENCODE_ERROR)       ,"encode error"},
+{ERR_REASON(PKCS12_R_ENCRYPT_ERROR)      ,"encrypt error"},
+{ERR_REASON(PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE),"error setting encrypted data type"},
+{ERR_REASON(PKCS12_R_INVALID_NULL_ARGUMENT),"invalid null argument"},
+{ERR_REASON(PKCS12_R_INVALID_NULL_PKCS12_POINTER),"invalid null pkcs12 pointer"},
+{ERR_REASON(PKCS12_R_IV_GEN_ERROR)       ,"iv gen error"},
+{ERR_REASON(PKCS12_R_KEY_GEN_ERROR)      ,"key gen error"},
+{ERR_REASON(PKCS12_R_MAC_ABSENT)         ,"mac absent"},
+{ERR_REASON(PKCS12_R_MAC_GENERATION_ERROR),"mac generation error"},
+{ERR_REASON(PKCS12_R_MAC_SETUP_ERROR)    ,"mac setup error"},
+{ERR_REASON(PKCS12_R_MAC_STRING_SET_ERROR),"mac string set error"},
+{ERR_REASON(PKCS12_R_MAC_VERIFY_ERROR)   ,"mac verify error"},
+{ERR_REASON(PKCS12_R_MAC_VERIFY_FAILURE) ,"mac verify failure"},
+{ERR_REASON(PKCS12_R_PARSE_ERROR)        ,"parse error"},
+{ERR_REASON(PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR),"pkcs12 algor cipherinit error"},
+{ERR_REASON(PKCS12_R_PKCS12_CIPHERFINAL_ERROR),"pkcs12 cipherfinal error"},
+{ERR_REASON(PKCS12_R_PKCS12_PBE_CRYPT_ERROR),"pkcs12 pbe crypt error"},
+{ERR_REASON(PKCS12_R_UNKNOWN_DIGEST_ALGORITHM),"unknown digest algorithm"},
+{ERR_REASON(PKCS12_R_UNSUPPORTED_PKCS12_MODE),"unsupported pkcs12 mode"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_PKCS12_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(PKCS12_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,PKCS12_str_functs);
+		ERR_load_strings(0,PKCS12_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/pkcs12/pkcs12.h b/openssl/crypto/pkcs12/pkcs12.h
new file mode 100644
index 0000000..b17eb9f
--- /dev/null
+++ b/openssl/crypto/pkcs12/pkcs12.h
@@ -0,0 +1,331 @@
+/* pkcs12.h */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_PKCS12_H
+#define HEADER_PKCS12_H
+
+#include <openssl/bio.h>
+#include <openssl/x509.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PKCS12_KEY_ID	1
+#define PKCS12_IV_ID	2
+#define PKCS12_MAC_ID	3
+
+/* Default iteration count */
+#ifndef PKCS12_DEFAULT_ITER
+#define PKCS12_DEFAULT_ITER	PKCS5_DEFAULT_ITER
+#endif
+
+#define PKCS12_MAC_KEY_LENGTH 20
+
+#define PKCS12_SALT_LEN	8
+
+/* Uncomment out next line for unicode password and names, otherwise ASCII */
+
+/*#define PBE_UNICODE*/
+
+#ifdef PBE_UNICODE
+#define PKCS12_key_gen PKCS12_key_gen_uni
+#define PKCS12_add_friendlyname PKCS12_add_friendlyname_uni
+#else
+#define PKCS12_key_gen PKCS12_key_gen_asc
+#define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc
+#endif
+
+/* MS key usage constants */
+
+#define KEY_EX	0x10
+#define KEY_SIG 0x80
+
+typedef struct {
+X509_SIG *dinfo;
+ASN1_OCTET_STRING *salt;
+ASN1_INTEGER *iter;	/* defaults to 1 */
+} PKCS12_MAC_DATA;
+
+typedef struct {
+ASN1_INTEGER *version;
+PKCS12_MAC_DATA *mac;
+PKCS7 *authsafes;
+} PKCS12;
+
+typedef struct {
+ASN1_OBJECT *type;
+union {
+	struct pkcs12_bag_st *bag; /* secret, crl and certbag */
+	struct pkcs8_priv_key_info_st	*keybag; /* keybag */
+	X509_SIG *shkeybag; /* shrouded key bag */
+	STACK_OF(PKCS12_SAFEBAG) *safes;
+	ASN1_TYPE *other;
+}value;
+STACK_OF(X509_ATTRIBUTE) *attrib;
+} PKCS12_SAFEBAG;
+
+DECLARE_STACK_OF(PKCS12_SAFEBAG)
+DECLARE_ASN1_SET_OF(PKCS12_SAFEBAG)
+DECLARE_PKCS12_STACK_OF(PKCS12_SAFEBAG)
+
+typedef struct pkcs12_bag_st {
+ASN1_OBJECT *type;
+union {
+	ASN1_OCTET_STRING *x509cert;
+	ASN1_OCTET_STRING *x509crl;
+	ASN1_OCTET_STRING *octet;
+	ASN1_IA5STRING *sdsicert;
+	ASN1_TYPE *other; /* Secret or other bag */
+}value;
+} PKCS12_BAGS;
+
+#define PKCS12_ERROR	0
+#define PKCS12_OK	1
+
+/* Compatibility macros */
+
+#define M_PKCS12_x5092certbag PKCS12_x5092certbag
+#define M_PKCS12_x509crl2certbag PKCS12_x509crl2certbag
+
+#define M_PKCS12_certbag2x509 PKCS12_certbag2x509
+#define M_PKCS12_certbag2x509crl PKCS12_certbag2x509crl 
+
+#define M_PKCS12_unpack_p7data PKCS12_unpack_p7data
+#define M_PKCS12_pack_authsafes PKCS12_pack_authsafes
+#define M_PKCS12_unpack_authsafes PKCS12_unpack_authsafes
+#define M_PKCS12_unpack_p7encdata PKCS12_unpack_p7encdata
+
+#define M_PKCS12_decrypt_skey PKCS12_decrypt_skey
+#define M_PKCS8_decrypt PKCS8_decrypt
+
+#define M_PKCS12_bag_type(bg) OBJ_obj2nid((bg)->type)
+#define M_PKCS12_cert_bag_type(bg) OBJ_obj2nid((bg)->value.bag->type)
+#define M_PKCS12_crl_bag_type M_PKCS12_cert_bag_type
+
+#define PKCS12_get_attr(bag, attr_nid) \
+			 PKCS12_get_attr_gen(bag->attrib, attr_nid)
+
+#define PKCS8_get_attr(p8, attr_nid) \
+		PKCS12_get_attr_gen(p8->attributes, attr_nid)
+
+#define PKCS12_mac_present(p12) ((p12)->mac ? 1 : 0)
+
+
+PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509);
+PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl);
+X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag);
+X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag);
+
+PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, int nid1,
+	     int nid2);
+PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8);
+PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass, int passlen);
+PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, const char *pass,
+								int passlen);
+X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, 
+			const char *pass, int passlen,
+			unsigned char *salt, int saltlen, int iter,
+			PKCS8_PRIV_KEY_INFO *p8);
+PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
+				     int passlen, unsigned char *salt,
+				     int saltlen, int iter,
+				     PKCS8_PRIV_KEY_INFO *p8);
+PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk);
+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7);
+PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
+			     unsigned char *salt, int saltlen, int iter,
+			     STACK_OF(PKCS12_SAFEBAG) *bags);
+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, int passlen);
+
+int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes);
+STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12);
+
+int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen);
+int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name,
+				int namelen);
+int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name,
+				int namelen);
+int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, const unsigned char *name,
+				int namelen);
+int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage);
+ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid);
+char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag);
+unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass,
+				int passlen, unsigned char *in, int inlen,
+				unsigned char **data, int *datalen, int en_de);
+void * PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it,
+	     const char *pass, int passlen, ASN1_OCTET_STRING *oct, int zbuf);
+ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, const ASN1_ITEM *it,
+				       const char *pass, int passlen,
+				       void *obj, int zbuf);
+PKCS12 *PKCS12_init(int mode);
+int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
+		       int saltlen, int id, int iter, int n,
+		       unsigned char *out, const EVP_MD *md_type);
+int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int id, int iter, int n, unsigned char *out, const EVP_MD *md_type);
+int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+			 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md_type,
+			 int en_de);
+int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
+			 unsigned char *mac, unsigned int *maclen);
+int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen);
+int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
+		   unsigned char *salt, int saltlen, int iter,
+		   const EVP_MD *md_type);
+int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt,
+					 int saltlen, const EVP_MD *md_type);
+unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen);
+char *OPENSSL_uni2asc(unsigned char *uni, int unilen);
+
+DECLARE_ASN1_FUNCTIONS(PKCS12)
+DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA)
+DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG)
+DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS)
+
+DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS)
+DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES)
+
+void PKCS12_PBE_add(void);
+int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
+		 STACK_OF(X509) **ca);
+PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
+			 STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter,
+						 int mac_iter, int keytype);
+
+PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert);
+PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, EVP_PKEY *key,
+						int key_usage, int iter,
+						int key_nid, char *pass);
+int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
+					int safe_nid, int iter, char *pass);
+PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid);
+
+int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12);
+int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12);
+PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12);
+PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12);
+int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_PKCS12_strings(void);
+
+/* Error codes for the PKCS12 functions. */
+
+/* Function codes. */
+#define PKCS12_F_PARSE_BAG				 129
+#define PKCS12_F_PARSE_BAGS				 103
+#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME		 100
+#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC		 127
+#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI		 102
+#define PKCS12_F_PKCS12_ADD_LOCALKEYID			 104
+#define PKCS12_F_PKCS12_CREATE				 105
+#define PKCS12_F_PKCS12_GEN_MAC				 107
+#define PKCS12_F_PKCS12_INIT				 109
+#define PKCS12_F_PKCS12_ITEM_DECRYPT_D2I		 106
+#define PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT		 108
+#define PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG		 117
+#define PKCS12_F_PKCS12_KEY_GEN_ASC			 110
+#define PKCS12_F_PKCS12_KEY_GEN_UNI			 111
+#define PKCS12_F_PKCS12_MAKE_KEYBAG			 112
+#define PKCS12_F_PKCS12_MAKE_SHKEYBAG			 113
+#define PKCS12_F_PKCS12_NEWPASS				 128
+#define PKCS12_F_PKCS12_PACK_P7DATA			 114
+#define PKCS12_F_PKCS12_PACK_P7ENCDATA			 115
+#define PKCS12_F_PKCS12_PARSE				 118
+#define PKCS12_F_PKCS12_PBE_CRYPT			 119
+#define PKCS12_F_PKCS12_PBE_KEYIVGEN			 120
+#define PKCS12_F_PKCS12_SETUP_MAC			 122
+#define PKCS12_F_PKCS12_SET_MAC				 123
+#define PKCS12_F_PKCS12_UNPACK_AUTHSAFES		 130
+#define PKCS12_F_PKCS12_UNPACK_P7DATA			 131
+#define PKCS12_F_PKCS12_VERIFY_MAC			 126
+#define PKCS12_F_PKCS8_ADD_KEYUSAGE			 124
+#define PKCS12_F_PKCS8_ENCRYPT				 125
+
+/* Reason codes. */
+#define PKCS12_R_CANT_PACK_STRUCTURE			 100
+#define PKCS12_R_CONTENT_TYPE_NOT_DATA			 121
+#define PKCS12_R_DECODE_ERROR				 101
+#define PKCS12_R_ENCODE_ERROR				 102
+#define PKCS12_R_ENCRYPT_ERROR				 103
+#define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE	 120
+#define PKCS12_R_INVALID_NULL_ARGUMENT			 104
+#define PKCS12_R_INVALID_NULL_PKCS12_POINTER		 105
+#define PKCS12_R_IV_GEN_ERROR				 106
+#define PKCS12_R_KEY_GEN_ERROR				 107
+#define PKCS12_R_MAC_ABSENT				 108
+#define PKCS12_R_MAC_GENERATION_ERROR			 109
+#define PKCS12_R_MAC_SETUP_ERROR			 110
+#define PKCS12_R_MAC_STRING_SET_ERROR			 111
+#define PKCS12_R_MAC_VERIFY_ERROR			 112
+#define PKCS12_R_MAC_VERIFY_FAILURE			 113
+#define PKCS12_R_PARSE_ERROR				 114
+#define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR		 115
+#define PKCS12_R_PKCS12_CIPHERFINAL_ERROR		 116
+#define PKCS12_R_PKCS12_PBE_CRYPT_ERROR			 117
+#define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM		 118
+#define PKCS12_R_UNSUPPORTED_PKCS12_MODE		 119
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/pkcs7/Makefile b/openssl/crypto/pkcs7/Makefile
new file mode 100644
index 0000000..56dc682
--- /dev/null
+++ b/openssl/crypto/pkcs7/Makefile
@@ -0,0 +1,194 @@
+#
+# OpenSSL/crypto/pkcs7/Makefile
+#
+
+DIR=	pkcs7
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+PEX_LIBS=
+EX_LIBS=
+ 
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile README
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=	pk7_asn1.c pk7_lib.c pkcs7err.c pk7_doit.c pk7_smime.c pk7_attr.c \
+	pk7_mime.c bio_pk7.c
+LIBOBJ= pk7_asn1.o pk7_lib.o pkcs7err.o pk7_doit.o pk7_smime.o pk7_attr.o \
+	pk7_mime.o bio_pk7.o
+
+SRC= $(LIBSRC)
+
+EXHEADER=  pkcs7.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+test:
+
+all:	lib
+
+testapps: enc dec sign verify
+
+enc: enc.o lib
+	$(CC) $(CFLAGS) -o enc enc.o $(PEX_LIBS) $(LIB) $(EX_LIBS)
+
+dec: dec.o lib
+	$(CC) $(CFLAGS) -o dec dec.o $(PEX_LIBS) $(LIB) $(EX_LIBS)
+
+sign: sign.o lib
+	$(CC) $(CFLAGS) -o sign sign.o $(PEX_LIBS) $(LIB) $(EX_LIBS)
+
+verify: verify.o example.o lib
+	$(CC) $(CFLAGS) -o verify verify.o $(PEX_LIBS) example.o $(LIB) $(EX_LIBS)
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff enc dec sign verify
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+bio_pk7.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+bio_pk7.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+bio_pk7.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+bio_pk7.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+bio_pk7.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bio_pk7.o: ../../include/openssl/symhacks.h bio_pk7.c
+pk7_asn1.o: ../../e_os.h ../../include/openssl/asn1.h
+pk7_asn1.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+pk7_asn1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+pk7_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+pk7_asn1.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+pk7_asn1.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+pk7_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pk7_asn1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pk7_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pk7_asn1.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+pk7_asn1.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pk7_asn1.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pk7_asn1.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pk7_asn1.c
+pk7_attr.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+pk7_attr.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pk7_attr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+pk7_attr.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+pk7_attr.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+pk7_attr.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+pk7_attr.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pk7_attr.o: ../../include/openssl/opensslconf.h
+pk7_attr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pk7_attr.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+pk7_attr.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+pk7_attr.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pk7_attr.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pk7_attr.o: ../../include/openssl/x509_vfy.h pk7_attr.c
+pk7_doit.o: ../../e_os.h ../../include/openssl/asn1.h
+pk7_doit.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pk7_doit.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+pk7_doit.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+pk7_doit.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+pk7_doit.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+pk7_doit.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pk7_doit.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pk7_doit.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pk7_doit.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+pk7_doit.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+pk7_doit.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+pk7_doit.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+pk7_doit.o: ../../include/openssl/x509v3.h ../cryptlib.h pk7_doit.c
+pk7_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+pk7_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pk7_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+pk7_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+pk7_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+pk7_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+pk7_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pk7_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+pk7_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+pk7_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+pk7_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+pk7_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+pk7_lib.o: ../asn1/asn1_locl.h ../cryptlib.h pk7_lib.c
+pk7_mime.o: ../../e_os.h ../../include/openssl/asn1.h
+pk7_mime.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pk7_mime.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+pk7_mime.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+pk7_mime.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+pk7_mime.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+pk7_mime.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pk7_mime.o: ../../include/openssl/opensslconf.h
+pk7_mime.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pk7_mime.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+pk7_mime.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+pk7_mime.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+pk7_mime.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+pk7_mime.o: ../cryptlib.h pk7_mime.c
+pk7_smime.o: ../../e_os.h ../../include/openssl/asn1.h
+pk7_smime.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pk7_smime.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+pk7_smime.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+pk7_smime.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+pk7_smime.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+pk7_smime.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pk7_smime.o: ../../include/openssl/objects.h
+pk7_smime.o: ../../include/openssl/opensslconf.h
+pk7_smime.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pk7_smime.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+pk7_smime.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pk7_smime.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pk7_smime.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+pk7_smime.o: ../cryptlib.h pk7_smime.c
+pkcs7err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+pkcs7err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+pkcs7err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+pkcs7err.o: ../../include/openssl/opensslconf.h
+pkcs7err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pkcs7err.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+pkcs7err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+pkcs7err.o: pkcs7err.c
diff --git a/openssl/crypto/pkcs7/bio_ber.c b/openssl/crypto/pkcs7/bio_ber.c
new file mode 100644
index 0000000..31973fc
--- /dev/null
+++ b/openssl/crypto/pkcs7/bio_ber.c
@@ -0,0 +1,466 @@
+/* crypto/evp/bio_ber.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+
+static int ber_write(BIO *h,char *buf,int num);
+static int ber_read(BIO *h,char *buf,int size);
+/*static int ber_puts(BIO *h,char *str); */
+/*static int ber_gets(BIO *h,char *str,int size); */
+static long ber_ctrl(BIO *h,int cmd,long arg1,char *arg2);
+static int ber_new(BIO *h);
+static int ber_free(BIO *data);
+static long ber_callback_ctrl(BIO *h,int cmd,void *(*fp)());
+#define BER_BUF_SIZE	(32)
+
+/* This is used to hold the state of the BER objects being read. */
+typedef struct ber_struct
+	{
+	int tag;
+	int class;
+	long length;
+	int inf;
+	int num_left;
+	int depth;
+	} BER_CTX;
+
+typedef struct bio_ber_struct
+	{
+	int tag;
+	int class;
+	long length;
+	int inf;
+
+	/* most of the following are used when doing non-blocking IO */
+	/* reading */
+	long num_left;	/* number of bytes still to read/write in block */
+	int depth;	/* used with indefinite encoding. */
+	int finished;	/* No more read data */
+
+	/* writting */ 
+	char *w_addr;
+	int w_offset;
+	int w_left;
+
+	int buf_len;
+	int buf_off;
+	unsigned char buf[BER_BUF_SIZE];
+	} BIO_BER_CTX;
+
+static BIO_METHOD methods_ber=
+	{
+	BIO_TYPE_CIPHER,"cipher",
+	ber_write,
+	ber_read,
+	NULL, /* ber_puts, */
+	NULL, /* ber_gets, */
+	ber_ctrl,
+	ber_new,
+	ber_free,
+	ber_callback_ctrl,
+	};
+
+BIO_METHOD *BIO_f_ber(void)
+	{
+	return(&methods_ber);
+	}
+
+static int ber_new(BIO *bi)
+	{
+	BIO_BER_CTX *ctx;
+
+	ctx=(BIO_BER_CTX *)OPENSSL_malloc(sizeof(BIO_BER_CTX));
+	if (ctx == NULL) return(0);
+
+	memset((char *)ctx,0,sizeof(BIO_BER_CTX));
+
+	bi->init=0;
+	bi->ptr=(char *)ctx;
+	bi->flags=0;
+	return(1);
+	}
+
+static int ber_free(BIO *a)
+	{
+	BIO_BER_CTX *b;
+
+	if (a == NULL) return(0);
+	b=(BIO_BER_CTX *)a->ptr;
+	OPENSSL_cleanse(a->ptr,sizeof(BIO_BER_CTX));
+	OPENSSL_free(a->ptr);
+	a->ptr=NULL;
+	a->init=0;
+	a->flags=0;
+	return(1);
+	}
+
+int bio_ber_get_header(BIO *bio, BIO_BER_CTX *ctx)
+	{
+	char buf[64];
+	int i,j,n;
+	int ret;
+	unsigned char *p;
+	unsigned long length
+	int tag;
+	int class;
+	long max;
+
+	BIO_clear_retry_flags(b);
+
+	/* Pack the buffer down if there is a hole at the front */
+	if (ctx->buf_off != 0)
+		{
+		p=ctx->buf;
+		j=ctx->buf_off;
+		n=ctx->buf_len-j;
+		for (i=0; i<n; i++)
+			{
+			p[0]=p[j];
+			p++;
+			}
+		ctx->buf_len-j;
+		ctx->buf_off=0;
+		}
+
+	/* If there is more room, read some more data */
+	i=BER_BUF_SIZE-ctx->buf_len;
+	if (i)
+		{
+		i=BIO_read(bio->next_bio,&(ctx->buf[ctx->buf_len]),i);
+		if (i <= 0)
+			{
+			BIO_copy_next_retry(b);
+			return(i);
+			}
+		else
+			ctx->buf_len+=i;
+		}
+
+	max=ctx->buf_len;
+	p=ctx->buf;
+	ret=ASN1_get_object(&p,&length,&tag,&class,max);
+
+	if (ret & 0x80)
+		{
+		if ((ctx->buf_len < BER_BUF_SIZE) &&
+			(ERR_GET_REASON(ERR_peek_error()) == ASN1_R_TOO_LONG))
+			{
+			ERR_clear_error(); /* clear the error */
+			BIO_set_retry_read(b);
+			}
+		return(-1);
+		}
+
+	/* We have no error, we have a header, so make use of it */
+
+	if ((ctx->tag  >= 0) && (ctx->tag != tag))
+		{
+		BIOerr(BIO_F_BIO_BER_GET_HEADER,BIO_R_TAG_MISMATCH);
+		sprintf(buf,"tag=%d, got %d",ctx->tag,tag);
+		ERR_add_error_data(1,buf);
+		return(-1);
+		}
+	if (ret & 0x01)
+	if (ret & V_ASN1_CONSTRUCTED)
+	}
+	
+static int ber_read(BIO *b, char *out, int outl)
+	{
+	int ret=0,i,n;
+	BIO_BER_CTX *ctx;
+
+	BIO_clear_retry_flags(b);
+
+	if (out == NULL) return(0);
+	ctx=(BIO_BER_CTX *)b->ptr;
+
+	if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
+
+	if (ctx->finished) return(0);
+
+again:
+	/* First see if we are half way through reading a block */
+	if (ctx->num_left > 0)
+		{
+		if (ctx->num_left < outl)
+			n=ctx->num_left;
+		else
+			n=outl;
+		i=BIO_read(b->next_bio,out,n);
+		if (i <= 0)
+			{
+			BIO_copy_next_retry(b);
+			return(i);
+			}
+		ctx->num_left-=i;
+		outl-=i;
+		ret+=i;
+		if (ctx->num_left <= 0)
+			{
+			ctx->depth--;
+			if (ctx->depth <= 0)
+				ctx->finished=1;
+			}
+		if (outl <= 0)
+			return(ret);
+		else
+			goto again;
+		}
+	else	/* we need to read another BER header */
+		{
+		}
+	}
+
+static int ber_write(BIO *b, char *in, int inl)
+	{
+	int ret=0,n,i;
+	BIO_ENC_CTX *ctx;
+
+	ctx=(BIO_ENC_CTX *)b->ptr;
+	ret=inl;
+
+	BIO_clear_retry_flags(b);
+	n=ctx->buf_len-ctx->buf_off;
+	while (n > 0)
+		{
+		i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
+		if (i <= 0)
+			{
+			BIO_copy_next_retry(b);
+			return(i);
+			}
+		ctx->buf_off+=i;
+		n-=i;
+		}
+	/* at this point all pending data has been written */
+
+	if ((in == NULL) || (inl <= 0)) return(0);
+
+	ctx->buf_off=0;
+	while (inl > 0)
+		{
+		n=(inl > ENC_BLOCK_SIZE)?ENC_BLOCK_SIZE:inl;
+		EVP_CipherUpdate(&(ctx->cipher),
+			(unsigned char *)ctx->buf,&ctx->buf_len,
+			(unsigned char *)in,n);
+		inl-=n;
+		in+=n;
+
+		ctx->buf_off=0;
+		n=ctx->buf_len;
+		while (n > 0)
+			{
+			i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
+			if (i <= 0)
+				{
+				BIO_copy_next_retry(b);
+				return(i);
+				}
+			n-=i;
+			ctx->buf_off+=i;
+			}
+		ctx->buf_len=0;
+		ctx->buf_off=0;
+		}
+	BIO_copy_next_retry(b);
+	return(ret);
+	}
+
+static long ber_ctrl(BIO *b, int cmd, long num, char *ptr)
+	{
+	BIO *dbio;
+	BIO_ENC_CTX *ctx,*dctx;
+	long ret=1;
+	int i;
+
+	ctx=(BIO_ENC_CTX *)b->ptr;
+
+	switch (cmd)
+		{
+	case BIO_CTRL_RESET:
+		ctx->ok=1;
+		ctx->finished=0;
+		EVP_CipherInit_ex(&(ctx->cipher),NULL,NULL,NULL,NULL,
+			ctx->cipher.berrypt);
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_EOF:	/* More to read */
+		if (ctx->cont <= 0)
+			ret=1;
+		else
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_WPENDING:
+		ret=ctx->buf_len-ctx->buf_off;
+		if (ret <= 0)
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_PENDING: /* More to read in buffer */
+		ret=ctx->buf_len-ctx->buf_off;
+		if (ret <= 0)
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_FLUSH:
+		/* do a final write */
+again:
+		while (ctx->buf_len != ctx->buf_off)
+			{
+			i=ber_write(b,NULL,0);
+			if (i < 0)
+				{
+				ret=i;
+				break;
+				}
+			}
+
+		if (!ctx->finished)
+			{
+			ctx->finished=1;
+			ctx->buf_off=0;
+			ret=EVP_CipherFinal_ex(&(ctx->cipher),
+				(unsigned char *)ctx->buf,
+				&(ctx->buf_len));
+			ctx->ok=(int)ret;
+			if (ret <= 0) break;
+
+			/* push out the bytes */
+			goto again;
+			}
+		
+		/* Finally flush the underlying BIO */
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+	case BIO_C_GET_CIPHER_STATUS:
+		ret=(long)ctx->ok;
+		break;
+	case BIO_C_DO_STATE_MACHINE:
+		BIO_clear_retry_flags(b);
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		BIO_copy_next_retry(b);
+		break;
+
+	case BIO_CTRL_DUP:
+		dbio=(BIO *)ptr;
+		dctx=(BIO_ENC_CTX *)dbio->ptr;
+		memcpy(&(dctx->cipher),&(ctx->cipher),sizeof(ctx->cipher));
+		dbio->init=1;
+		break;
+	default:
+		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		break;
+		}
+	return(ret);
+	}
+
+static long ber_callback_ctrl(BIO *b, int cmd, void *(*fp)())
+	{
+	long ret=1;
+
+	if (b->next_bio == NULL) return(0);
+	switch (cmd)
+		{
+	default:
+		ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+		break;
+		}
+	return(ret);
+	}
+
+/*
+void BIO_set_cipher_ctx(b,c)
+BIO *b;
+EVP_CIPHER_ctx *c;
+	{
+	if (b == NULL) return;
+
+	if ((b->callback != NULL) &&
+		(b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
+		return;
+
+	b->init=1;
+	ctx=(BIO_ENC_CTX *)b->ptr;
+	memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX));
+	
+	if (b->callback != NULL)
+		b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
+	}
+*/
+
+void BIO_set_cipher(BIO *b, EVP_CIPHER *c, unsigned char *k, unsigned char *i,
+	     int e)
+	{
+	BIO_ENC_CTX *ctx;
+
+	if (b == NULL) return;
+
+	if ((b->callback != NULL) &&
+		(b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
+		return;
+
+	b->init=1;
+	ctx=(BIO_ENC_CTX *)b->ptr;
+	EVP_CipherInit_ex(&(ctx->cipher),c,NULL,k,i,e);
+	
+	if (b->callback != NULL)
+		b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
+	}
+
diff --git a/openssl/crypto/pkcs7/bio_pk7.c b/openssl/crypto/pkcs7/bio_pk7.c
new file mode 100644
index 0000000..c8d06d6
--- /dev/null
+++ b/openssl/crypto/pkcs7/bio_pk7.c
@@ -0,0 +1,69 @@
+/* bio_pk7.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/asn1.h>
+#include <openssl/pkcs7.h>
+#include <openssl/bio.h>
+
+#ifndef OPENSSL_SYSNAME_NETWARE
+#include <memory.h>
+#endif
+#include <stdio.h>
+
+/* Streaming encode support for PKCS#7 */
+
+BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7) 
+	{
+	return BIO_new_NDEF(out, (ASN1_VALUE *)p7, ASN1_ITEM_rptr(PKCS7));
+	}
diff --git a/openssl/crypto/pkcs7/dec.c b/openssl/crypto/pkcs7/dec.c
new file mode 100644
index 0000000..6752ec5
--- /dev/null
+++ b/openssl/crypto/pkcs7/dec.c
@@ -0,0 +1,248 @@
+/* crypto/pkcs7/verify.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/asn1.h>
+
+int verify_callback(int ok, X509_STORE_CTX *ctx);
+
+BIO *bio_err=NULL;
+
+int main(argc,argv)
+int argc;
+char *argv[];
+	{
+	char *keyfile=NULL;
+	BIO *in;
+	EVP_PKEY *pkey;
+	X509 *x509;
+	PKCS7 *p7;
+	PKCS7_SIGNER_INFO *si;
+	X509_STORE_CTX cert_ctx;
+	X509_STORE *cert_store=NULL;
+	BIO *data,*detached=NULL,*p7bio=NULL;
+	char buf[1024*4];
+	unsigned char *pp;
+	int i,printit=0;
+	STACK_OF(PKCS7_SIGNER_INFO) *sk;
+
+	OpenSSL_add_all_algorithms();
+	bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+
+	data=BIO_new(BIO_s_file());
+	pp=NULL;
+	while (argc > 1)
+		{
+		argc--;
+		argv++;
+		if (strcmp(argv[0],"-p") == 0)
+			{
+			printit=1;
+			}
+		else if ((strcmp(argv[0],"-k") == 0) && (argc >= 2)) {
+			keyfile = argv[1];
+			argc-=1;
+			argv+=1;
+		} else if ((strcmp(argv[0],"-d") == 0) && (argc >= 2))
+			{
+			detached=BIO_new(BIO_s_file());
+			if (!BIO_read_filename(detached,argv[1]))
+				goto err;
+			argc-=1;
+			argv+=1;
+			}
+		else break;
+		}
+
+	 if (!BIO_read_filename(data,argv[0])) goto err; 
+
+	if(!keyfile) {
+		fprintf(stderr, "No private key file specified\n");
+		goto err;
+	}
+
+        if ((in=BIO_new_file(keyfile,"r")) == NULL) goto err;
+        if ((x509=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL) goto err;
+        BIO_reset(in);
+        if ((pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,NULL)) == NULL)
+		goto err;
+        BIO_free(in);
+
+	if (pp == NULL)
+		BIO_set_fp(data,stdin,BIO_NOCLOSE);
+
+
+	/* Load the PKCS7 object from a file */
+	if ((p7=PEM_read_bio_PKCS7(data,NULL,NULL,NULL)) == NULL) goto err;
+
+
+
+	/* This stuff is being setup for certificate verification.
+	 * When using SSL, it could be replaced with a 
+	 * cert_stre=SSL_CTX_get_cert_store(ssl_ctx); */
+	cert_store=X509_STORE_new();
+	X509_STORE_set_default_paths(cert_store);
+	X509_STORE_load_locations(cert_store,NULL,"../../certs");
+	X509_STORE_set_verify_cb_func(cert_store,verify_callback);
+
+	ERR_clear_error();
+
+	/* We need to process the data */
+	/* We cannot support detached encryption */
+	p7bio=PKCS7_dataDecode(p7,pkey,detached,x509);
+
+	if (p7bio == NULL)
+		{
+		printf("problems decoding\n");
+		goto err;
+		}
+
+	/* We now have to 'read' from p7bio to calculate digests etc. */
+	for (;;)
+		{
+		i=BIO_read(p7bio,buf,sizeof(buf));
+		/* print it? */
+		if (i <= 0) break;
+		fwrite(buf,1, i, stdout);
+		}
+
+	/* We can now verify signatures */
+	sk=PKCS7_get_signer_info(p7);
+	if (sk == NULL)
+		{
+		fprintf(stderr, "there are no signatures on this data\n");
+		}
+	else
+		{
+		/* Ok, first we need to, for each subject entry,
+		 * see if we can verify */
+		ERR_clear_error();
+		for (i=0; i<sk_PKCS7_SIGNER_INFO_num(sk); i++)
+			{
+			si=sk_PKCS7_SIGNER_INFO_value(sk,i);
+			i=PKCS7_dataVerify(cert_store,&cert_ctx,p7bio,p7,si);
+			if (i <= 0)
+				goto err;
+			else
+				fprintf(stderr,"Signature verified\n");
+			}
+		}
+	X509_STORE_free(cert_store);
+
+	exit(0);
+err:
+	ERR_load_crypto_strings();
+	ERR_print_errors_fp(stderr);
+	exit(1);
+	}
+
+/* should be X509 * but we can just have them as char *. */
+int verify_callback(int ok, X509_STORE_CTX *ctx)
+	{
+	char buf[256];
+	X509 *err_cert;
+	int err,depth;
+
+	err_cert=X509_STORE_CTX_get_current_cert(ctx);
+	err=	X509_STORE_CTX_get_error(ctx);
+	depth=	X509_STORE_CTX_get_error_depth(ctx);
+
+	X509_NAME_oneline(X509_get_subject_name(err_cert),buf,256);
+	BIO_printf(bio_err,"depth=%d %s\n",depth,buf);
+	if (!ok)
+		{
+		BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
+			X509_verify_cert_error_string(err));
+		if (depth < 6)
+			{
+			ok=1;
+			X509_STORE_CTX_set_error(ctx,X509_V_OK);
+			}
+		else
+			{
+			ok=0;
+			X509_STORE_CTX_set_error(ctx,X509_V_ERR_CERT_CHAIN_TOO_LONG);
+			}
+		}
+	switch (ctx->error)
+		{
+	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+		X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
+		BIO_printf(bio_err,"issuer= %s\n",buf);
+		break;
+	case X509_V_ERR_CERT_NOT_YET_VALID:
+	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+		BIO_printf(bio_err,"notBefore=");
+		ASN1_UTCTIME_print(bio_err,X509_get_notBefore(ctx->current_cert));
+		BIO_printf(bio_err,"\n");
+		break;
+	case X509_V_ERR_CERT_HAS_EXPIRED:
+	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+		BIO_printf(bio_err,"notAfter=");
+		ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ctx->current_cert));
+		BIO_printf(bio_err,"\n");
+		break;
+		}
+	BIO_printf(bio_err,"verify return:%d\n",ok);
+	return(ok);
+	}
diff --git a/openssl/crypto/pkcs7/des.pem b/openssl/crypto/pkcs7/des.pem
new file mode 100644
index 0000000..62d1657
--- /dev/null
+++ b/openssl/crypto/pkcs7/des.pem
@@ -0,0 +1,15 @@
+
+MIAGCSqGSIb3DQEHA6CAMIACAQAxggHmMIHwAgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEG
+A1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
+dCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNUUkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQD
+ExJERU1PIFpFUk8gVkFMVUUgQ0ECAgR+MA0GCSqGSIb3DQEBAQUABEC2vXI1xQDW6lUHM3zQ
+/9uBEBOO5A3TtkrklAXq7v01gsIC21t52qSk36REXY+slhNZ0OQ349tgkTsoETHFLoEwMIHw
+AgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMI
+QnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29mdCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNU
+UkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQDExJERU1PIFpFUk8gVkFMVUUgQ0ECAgR9MA0G
+CSqGSIb3DQEBAQUABEB8ujxbabxXUYJhopuDm3oDq4JNqX6Io4p3ro+ShqfIndsXTZ1v5a2N
+WtLLCWlHn/habjBwZ/DgQgcKASbZ7QxNMIAGCSqGSIb3DQEHATAaBggqhkiG9w0DAjAOAgIA
+oAQIbsL5v1wX98KggAQoAaJ4WHm68fXY1WE5OIjfVBIDpO1K+i8dmKhjnAjrjoyZ9Bwc8rDL
+lgQg4CXb805h5xl+GfvSwUaHJayte1m2mcOhs3J2YyqbQ+MEIMIiJQccmhO3oDKm36CFvYR8
+5PjpclVcZyX2ngbwPFMnBAgy0clOAE6UKAAAAAAAAAAAAAA=
+
diff --git a/openssl/crypto/pkcs7/doc b/openssl/crypto/pkcs7/doc
new file mode 100644
index 0000000..d2e8b7b
--- /dev/null
+++ b/openssl/crypto/pkcs7/doc
@@ -0,0 +1,24 @@
+int PKCS7_set_content_type(PKCS7 *p7, int type);
+Call to set the type of PKCS7 object we are working on
+
+int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
+	EVP_MD *dgst);
+Use this to setup a signer info
+There will also be functions to add signed and unsigned attributes.
+
+int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
+Add a signer info to the content.
+
+int PKCS7_add_certificae(PKCS7 *p7, X509 *x509);
+int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
+
+----
+
+p7=PKCS7_new();
+PKCS7_set_content_type(p7,NID_pkcs7_signed);
+
+signer=PKCS7_SINGNER_INFO_new();
+PKCS7_SIGNER_INFO_set(signer,x509,pkey,EVP_md5());
+PKCS7_add_signer(py,signer);
+
+we are now setup.
diff --git a/openssl/crypto/pkcs7/enc.c b/openssl/crypto/pkcs7/enc.c
new file mode 100644
index 0000000..7417f8a
--- /dev/null
+++ b/openssl/crypto/pkcs7/enc.c
@@ -0,0 +1,174 @@
+/* crypto/pkcs7/enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+#include <stdio.h>
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+
+int main(argc,argv)
+int argc;
+char *argv[];
+	{
+	X509 *x509;
+	PKCS7 *p7;
+	BIO *in;
+	BIO *data,*p7bio;
+	char buf[1024*4];
+	int i;
+	int nodetach=1;
+	char *keyfile = NULL;
+	const EVP_CIPHER *cipher=NULL;
+	STACK_OF(X509) *recips=NULL;
+
+	OpenSSL_add_all_algorithms();
+
+	data=BIO_new(BIO_s_file());
+	while(argc > 1)
+		{
+		if (strcmp(argv[1],"-nd") == 0)
+			{
+			nodetach=1;
+			argv++; argc--;
+			}
+		else if ((strcmp(argv[1],"-c") == 0) && (argc >= 2)) {
+			if(!(cipher = EVP_get_cipherbyname(argv[2]))) {
+				fprintf(stderr, "Unknown cipher %s\n", argv[2]);
+				goto err;
+			}
+			argc-=2;
+			argv+=2;
+		} else if ((strcmp(argv[1],"-k") == 0) && (argc >= 2)) {
+			keyfile = argv[2];
+			argc-=2;
+			argv+=2;
+			if (!(in=BIO_new_file(keyfile,"r"))) goto err;
+			if (!(x509=PEM_read_bio_X509(in,NULL,NULL,NULL)))
+				goto err;
+			if(!recips) recips = sk_X509_new_null();
+			sk_X509_push(recips, x509);
+			BIO_free(in);
+		} else break;
+	}
+
+	if(!recips) {
+		fprintf(stderr, "No recipients\n");
+		goto err;
+	}
+
+	if (!BIO_read_filename(data,argv[1])) goto err;
+
+	p7=PKCS7_new();
+#if 0
+	BIO_reset(in);
+	if ((pkey=PEM_read_bio_PrivateKey(in,NULL,NULL)) == NULL) goto err;
+	BIO_free(in);
+	PKCS7_set_type(p7,NID_pkcs7_signedAndEnveloped);
+	 
+	if (PKCS7_add_signature(p7,x509,pkey,EVP_sha1()) == NULL) goto err;
+	/* we may want to add more */
+	PKCS7_add_certificate(p7,x509);
+#else
+	PKCS7_set_type(p7,NID_pkcs7_enveloped);
+#endif
+	if(!cipher)	{
+#ifndef OPENSSL_NO_DES
+		cipher = EVP_des_ede3_cbc();
+#else
+		fprintf(stderr, "No cipher selected\n");
+		goto err;
+#endif
+	}
+
+	if (!PKCS7_set_cipher(p7,cipher)) goto err;
+	for(i = 0; i < sk_X509_num(recips); i++) {
+		if (!PKCS7_add_recipient(p7,sk_X509_value(recips, i))) goto err;
+	}
+	sk_X509_pop_free(recips, X509_free);
+
+	/* Set the content of the signed to 'data' */
+	/* PKCS7_content_new(p7,NID_pkcs7_data); not used in envelope */
+
+	/* could be used, but not in this version :-)
+	if (!nodetach) PKCS7_set_detached(p7,1);
+	*/
+
+	if ((p7bio=PKCS7_dataInit(p7,NULL)) == NULL) goto err;
+
+	for (;;)
+		{
+		i=BIO_read(data,buf,sizeof(buf));
+		if (i <= 0) break;
+		BIO_write(p7bio,buf,i);
+		}
+	BIO_flush(p7bio);
+
+	if (!PKCS7_dataFinal(p7,p7bio)) goto err;
+	BIO_free(p7bio);
+
+	PEM_write_PKCS7(stdout,p7);
+	PKCS7_free(p7);
+
+	exit(0);
+err:
+	ERR_load_crypto_strings();
+	ERR_print_errors_fp(stderr);
+	exit(1);
+	}
+
diff --git a/openssl/crypto/pkcs7/es1.pem b/openssl/crypto/pkcs7/es1.pem
new file mode 100644
index 0000000..47112a2
--- /dev/null
+++ b/openssl/crypto/pkcs7/es1.pem
@@ -0,0 +1,66 @@
+-----BEGIN PKCS7-----
+MIAGCSqGSIb3DQEHA6CAMIACAQAxggHmMIHwAgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEG
+A1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
+dCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNUUkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQD
+ExJERU1PIFpFUk8gVkFMVUUgQ0ECAgRuMA0GCSqGSIb3DQEBAQUABEDWak0y/5XZJhQJeCLo
+KECcHXkTEbjzYkYNHIinbiPmRK4QbNfs9z2mA3z/c2ykQ4eAqFR2jyNrUMN/+I5XEiv6MIHw
+AgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMI
+QnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29mdCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNU
+UkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQDExJERU1PIFpFUk8gVkFMVUUgQ0ECAgR9MA0G
+CSqGSIb3DQEBAQUABEAWg9+KgtCjc77Jdj1Ve4wGgHjVHbbSYEA1ZqKFDoi15vSr9hfpHmC4
+ycZzcRo16JkTfolefiHZzmyjVz94vSN6MIAGCSqGSIb3DQEHATAaBggqhkiG9w0DAjAOAgIA
+oAQI7X4Tk4mcbV6ggASBsHl1mCaJ3RhXWlNPCgCRU53d7M5x6TDZRkvwdtdvW96m1lupT03F
+XtonkBqk7oMkH7kGfs5/REQOPjx0QE2Ixmgt1W3szum82EZwA7pZNppcraK7W/odw/7bYZO+
+II3HPmRklE2N9qiu1LPaPUsnYogkO6SennyeL5tZ382vBweL/8pnG0qsbT1OBb65v+llnsjT
+pa1T/p+fIx/iJJGE6K9fYFokC6gXLQ6ozXRdOu5oBDB8mPCYYvAqKycidM/MrGGUkpEtS4f0
+lS31PwQi5YTim8Ig3/TOwVpPX32i46FTuEIEIMHkD/OvpfwCCzXUHHJnKnKUAUvIsSY3vGBs
+8ezpUDfBBBj9LHDy32hZ2tQilkDefP5VM2LLdrWgamYEgfiyITQvn08Ul5lQOQxbFKBheFq5
+otCCN4MR+w5eq12xQu6y+f9z0159ag2ru87D0lLtUtXXtCELbO1nUkT2sJ0k/iDs9TOXr6Cx
+go1XKYho83hlkXYiCteVizdAbgVGNsNRD4wtIdajsorET/LuJECgp11YeL9w1dlDB0HLEZfi
+XCsUphH4jGagba3hDeUSibnjSiJlN0ukfuQurBBbI2UkBAujiEAubKPn7C1FZJRSw6CPPX5t
+KEpmcqT1JNk6LO8Js6/1sCmmBh1VGCy1+EuTI9J1p7Dagf4nQ8cHitoCRpHuKZlFHnZyv7tw
+Rn/KOhHaYP2VzAh40gQIvKMAAWh9oFsEEIMwIoOmLwLH5wf+8QdbDhoECH8HwZt9a12dBAjL
+r4j2zlvtfgQIt7nmEM3wz1EECKlc3EIy1irCBBCAKINcermK3A+jI6ISN2RzBFA3dsh/xwMu
+l61aWMBBZzEz/SF92k6n35KZhCC0d6fIVC/1WMv0fnCwQ8oEDynSre216VEFiYKBaQLJe5o/
+mTAxC7Ht3goXnuc+i1FItOkLrgRI/wyvTICEn2WsNZiMADnGaee2bqPnUopo+VMGexJEtCPk
+l0ZNlDJGquPDkpUwaEtecVZzCNyVPYyyF4J/l8rmGDhDdYUIC8IKBEg/ip/E0BuubBLWVbv+
+HRl4QrnGpyCyeXRXXK603QP3sT1Zbbm1v5pI/loOhVHi724LmtXHSyp5qv9MDcxE1PoX10LY
+gBRtlwwESPeCF8bK5jk4xIQMhK5NMHj1Y1KQWTZ9NGITBL4hjRq2qp4Qk5GIpGgOVPopAuCo
+TIyPikpqBRNtLSPRSsDs6QPUPzWBh6JgxwRQblnDKKUkxUcnJiD4i9QtGa/ZabMn4KxtNOBL
+5JSh1nJkaLXCZY070131WWPAByLcd5TiXq8x84pmzV5NNk4tiMpoXhJNsx8e4rskQQlKd6ME
+SCe2eYDHKcKPX3WJbUzhrJSQ92/aWnI2iUY8WQ+kSNyiZ2QUjyuUg9Z66g/0d2STlvPOBHT/
+y5ODP2CwbcWX4QmCbUc9TT66fQRIrRVuwvtOfnUueyGgYhJ3HpAJfVaB/7kap5bj7Fi/azW4
+9JDfd1bC/W9h0Kyk7RO2gxvE0hIHc26mZJHTm9MNP5D328MnM2MdBEjKjQBtgrp+lFIii7MP
+nGHFTKUkG4WAIZJCf/CsT+p6/SW0qG71Me/YcSw5STB24j+a+HgMV8RVIeUlkP4z0IWWrSoB
+Gh4d/Z0EUMCVHs/HZ/bWgiyhtHpvuVAzidm8D81p1LJ5BQX5/5f/m+q5+fS/npL27dTEbNqs
+LSB6ij3MZAi7LwHWpTn9zWnDajCMEj9vlaV7mcKtHK5iBEg85agFi1h3MvicqLtoFe5hVv9T
+tG0j6CRkjkixPzivltlrf44KHv14gLM0XJxCGyq7vd3l8QYr3+9at0zNnX/yqTiBnsnE5dUE
+SIgrYuz87M2gi/ER9PcDoTtONH3+CkcqVy03q/Sj8cVWD/b1KgEhqnNOfc8Ak9PctyR/ItcR
+8Me5XVn1GJKkQJk4O29fxvgNoAQIrIESvUWGshAEQByXiFoFTDUByjTlgjcy77H1lrH+y3P/
+wAInJjJAut9kCNyGJV0PA4kdPB5USWltuO6t8gk4Pd2YBMl09zqUWkAEUCjFrtZ3mapjcGZI
+uQTASKR5LSjXoWxTT5gae/+64MerF/oCEeO3ehRTpjnPrsiRDo0rWIQTaj9+Nro8Z2xtWstw
+RnfoAHIxV1lEamPwjsceBEi2SD9hiifFeO5ECiVoaE1FdXUXhU+jwYAMx6jHWO9hMkYzS9pM
+Y3IyWR5ybtOjiQgkUdvRJPUPGf5DVVMPnymGX25aDh5PYpIESPbsM9akCpOOVuscywcUswmU
+o7dXvlB48WWCfg/al3BQKAZbn5ZXtWNwpUZkrEdHsrxAVv3rxRcdkT3Z1fzUbIuYkLJN200o
+WgRIJvn6RO8KEj7/HOg2sYuuM8nz1kR0TSgwX7/0y/7JfjBa0JIlP7o75sNJscE8oyoIMzuy
+Dvn6/U9g3BCDXn83A/s+ke60qn9gBFC6NAeLOlXal1YVWYhMQNOqCyUfAjiXBTawaysQb1Mk
+YgeNlF8xuEFcUQWIP+vNG7FJ5JPMaMRL4YEoaQ3sVFhYOERJR1cSb+8xt4QCYtBKQgRIUOmJ
+CHW5o1hXJWJiTkZK2qWFcEMzTINSj5EpYFySr8aVBjkRnI7vxegRT/+XZZXoYedQ3UNsnGI3
+DdkWii5VzX0PNF6C60pfBEiVpausYuX7Wjb3Lfm8cBj7GgN69i6Pm2gxtobVcmpo2nS4D714
+ePyhlX9n8kJ6QAcqWMRj22smDPrHVGNTizfzHBh5zNllK9gESJizILOWI327og3ZWp+qUht5
+kNDJCzMK7Z09UAy+h+vq0VTQuEo3FgLzVdqkJujjSL4Nx97lXg51AovrEn3nd4evydwcjKLX
+1wRIo72NaeWuUEQ+rt1SlCsOJ7k1ioJSqhrPOfvwcaFcb4beVet1JWiy4yvowTjLDGbUje2s
+xjrlVt4BJWI/uA6jbQsrxSe89ADZBAi5YAlR4qszeAQIXD3VSBVKbRUECNTtyvw9vvqXBAhb
+IZNn4H4cxgQI+XW7GkfL+ekECCCCg2reMyGDBAh1PYqkg3lw3gQQkNlggEPU+BH8eh7Gm7n7
+7AQIjC5EWbkil5cEEKcpuqwTWww/X89KnQAg8TcECJPomqHvrlZFBBiRSuIiHpmN+PaujXpv
+qZV2VhjkB2j09GEECOIdv8AVOJgKBAjlHgIqAD9jZQQIXHbs44+wogcEIGGqTACRJxrhMcMG
+X8drNjksIPt+snxTXUBIkTVpZWoABAh6unXPTyIr8QQgBF8xKoX27MWk7iTNmkSNZggZXa2a
+DWCGHSYLngbSOHIECD9XmO6VsvTgBAjfqB70CEW4WwQIVIBkbCocznUEEHB/zFXy/sR4OYHe
+UfbNPnIEEDWBB/NTCLMGE+o8BfyujcAECFik7GQnnF9VBBAhLXExQeWAofZNc6NtN7qZBCC1
+gVIS3ruTwKltmcrgx3heT3M8ZJhCfWa+6KzchnmKygQQ+1NL5sSzR4m/fdrqxHFyUAQYCT2x
+PamQr3wK3h0lyZER+4H0zPM86AhFBBC3CkmvL2vjflMfujnzPBVpBBge9rMbI5+0q9DLrTiT
+5F3AIgXLpD8PQWAECHkHVo6RomV3BAgMbi8E271UeAQIqtS8wnI3XngECG3TWmOMb3/iBEha
+y+mvCS6I3n3JfL8e1B5P4qX9/czJRaERLuKpGNjLiL4A+zxN0LZ0UHd0qfmJjwOTxAx3iJAC
+lGXX4nB9ATYPUT5EU+o1Y4sECN01pP6vWNIdBDAsiE0Ts8/9ltJlqX2B3AoOM4qOt9EaCjXf
+lB+aEmrhtjUwuZ6GqS5Ke7P6XnakTk4ECCLIMatNdootAAAAAAAAAAAAAA==
+-----END PKCS7-----
diff --git a/openssl/crypto/pkcs7/example.c b/openssl/crypto/pkcs7/example.c
new file mode 100644
index 0000000..2953d04
--- /dev/null
+++ b/openssl/crypto/pkcs7/example.c
@@ -0,0 +1,329 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/pkcs7.h>
+#include <openssl/asn1_mac.h>
+#include <openssl/x509.h>
+
+int add_signed_time(PKCS7_SIGNER_INFO *si)
+	{
+	ASN1_UTCTIME *sign_time;
+
+	/* The last parameter is the amount to add/subtract from the current
+	 * time (in seconds) */
+	sign_time=X509_gmtime_adj(NULL,0);
+	PKCS7_add_signed_attribute(si,NID_pkcs9_signingTime,
+		V_ASN1_UTCTIME,(char *)sign_time);
+	return(1);
+	}
+
+ASN1_UTCTIME *get_signed_time(PKCS7_SIGNER_INFO *si)
+	{
+	ASN1_TYPE *so;
+
+	so=PKCS7_get_signed_attribute(si,NID_pkcs9_signingTime);
+	if (so->type == V_ASN1_UTCTIME)
+	    return so->value.utctime;
+	return NULL;
+	}
+	
+static int signed_string_nid= -1;
+
+void add_signed_string(PKCS7_SIGNER_INFO *si, char *str)
+	{
+	ASN1_OCTET_STRING *os;
+
+	/* To a an object of OID 1.2.3.4.5, which is an octet string */
+	if (signed_string_nid == -1)
+		signed_string_nid=
+			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
+	os=ASN1_OCTET_STRING_new();
+	ASN1_OCTET_STRING_set(os,(unsigned char*)str,strlen(str));
+	/* When we add, we do not free */
+	PKCS7_add_signed_attribute(si,signed_string_nid,
+		V_ASN1_OCTET_STRING,(char *)os);
+	}
+
+int get_signed_string(PKCS7_SIGNER_INFO *si, char *buf, int len)
+	{
+	ASN1_TYPE *so;
+	ASN1_OCTET_STRING *os;
+	int i;
+
+	if (signed_string_nid == -1)
+		signed_string_nid=
+			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
+	/* To retrieve */
+	so=PKCS7_get_signed_attribute(si,signed_string_nid);
+	if (so != NULL)
+		{
+		if (so->type == V_ASN1_OCTET_STRING)
+			{
+			os=so->value.octet_string;
+			i=os->length;
+			if ((i+1) > len)
+				i=len-1;
+			memcpy(buf,os->data,i);
+			return(i);
+			}
+		}
+	return(0);
+	}
+
+static int signed_seq2string_nid= -1;
+/* ########################################### */
+int add_signed_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2)
+	{
+	/* To add an object of OID 1.9.999, which is a sequence containing
+	 * 2 octet strings */
+	unsigned char *p;
+	ASN1_OCTET_STRING *os1,*os2;
+	ASN1_STRING *seq;
+	unsigned char *data;
+	int i,total;
+
+	if (signed_seq2string_nid == -1)
+		signed_seq2string_nid=
+			OBJ_create("1.9.9999","OID_example","Our example OID");
+
+	os1=ASN1_OCTET_STRING_new();
+	os2=ASN1_OCTET_STRING_new();
+	ASN1_OCTET_STRING_set(os1,(unsigned char*)str1,strlen(str1));
+	ASN1_OCTET_STRING_set(os2,(unsigned char*)str1,strlen(str1));
+	i =i2d_ASN1_OCTET_STRING(os1,NULL);
+	i+=i2d_ASN1_OCTET_STRING(os2,NULL);
+	total=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
+
+	data=malloc(total);
+	p=data;
+	ASN1_put_object(&p,1,i,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
+	i2d_ASN1_OCTET_STRING(os1,&p);
+	i2d_ASN1_OCTET_STRING(os2,&p);
+
+	seq=ASN1_STRING_new();
+	ASN1_STRING_set(seq,data,total);
+	free(data);
+	ASN1_OCTET_STRING_free(os1);
+	ASN1_OCTET_STRING_free(os2);
+
+	PKCS7_add_signed_attribute(si,signed_seq2string_nid,
+		V_ASN1_SEQUENCE,(char *)seq);
+	return(1);
+	}
+
+/* For this case, I will malloc the return strings */
+int get_signed_seq2string(PKCS7_SIGNER_INFO *si, char **str1, char **str2)
+	{
+	ASN1_TYPE *so;
+
+	if (signed_seq2string_nid == -1)
+		signed_seq2string_nid=
+			OBJ_create("1.9.9999","OID_example","Our example OID");
+	/* To retrieve */
+	so=PKCS7_get_signed_attribute(si,signed_seq2string_nid);
+	if (so && (so->type == V_ASN1_SEQUENCE))
+		{
+		ASN1_const_CTX c;
+		ASN1_STRING *s;
+		long length;
+		ASN1_OCTET_STRING *os1,*os2;
+
+		s=so->value.sequence;
+		c.p=ASN1_STRING_data(s);
+		c.max=c.p+ASN1_STRING_length(s);
+		if (!asn1_GetSequence(&c,&length)) goto err;
+		/* Length is the length of the seqence */
+
+		c.q=c.p;
+		if ((os1=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) 
+			goto err;
+		c.slen-=(c.p-c.q);
+
+		c.q=c.p;
+		if ((os2=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) 
+			goto err;
+		c.slen-=(c.p-c.q);
+
+		if (!asn1_const_Finish(&c)) goto err;
+		*str1=malloc(os1->length+1);
+		*str2=malloc(os2->length+1);
+		memcpy(*str1,os1->data,os1->length);
+		memcpy(*str2,os2->data,os2->length);
+		(*str1)[os1->length]='\0';
+		(*str2)[os2->length]='\0';
+		ASN1_OCTET_STRING_free(os1);
+		ASN1_OCTET_STRING_free(os2);
+		return(1);
+		}
+err:
+	return(0);
+	}
+
+
+/* #######################################
+ * THE OTHER WAY TO DO THINGS
+ * #######################################
+ */
+X509_ATTRIBUTE *create_time(void)
+	{
+	ASN1_UTCTIME *sign_time;
+	X509_ATTRIBUTE *ret;
+
+	/* The last parameter is the amount to add/subtract from the current
+	 * time (in seconds) */
+	sign_time=X509_gmtime_adj(NULL,0);
+	ret=X509_ATTRIBUTE_create(NID_pkcs9_signingTime,
+		V_ASN1_UTCTIME,(char *)sign_time);
+	return(ret);
+	}
+
+ASN1_UTCTIME *sk_get_time(STACK_OF(X509_ATTRIBUTE) *sk)
+	{
+	ASN1_TYPE *so;
+	PKCS7_SIGNER_INFO si;
+
+	si.auth_attr=sk;
+	so=PKCS7_get_signed_attribute(&si,NID_pkcs9_signingTime);
+	if (so->type == V_ASN1_UTCTIME)
+	    return so->value.utctime;
+	return NULL;
+	}
+	
+X509_ATTRIBUTE *create_string(char *str)
+	{
+	ASN1_OCTET_STRING *os;
+	X509_ATTRIBUTE *ret;
+
+	/* To a an object of OID 1.2.3.4.5, which is an octet string */
+	if (signed_string_nid == -1)
+		signed_string_nid=
+			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
+	os=ASN1_OCTET_STRING_new();
+	ASN1_OCTET_STRING_set(os,(unsigned char*)str,strlen(str));
+	/* When we add, we do not free */
+	ret=X509_ATTRIBUTE_create(signed_string_nid,
+		V_ASN1_OCTET_STRING,(char *)os);
+	return(ret);
+	}
+
+int sk_get_string(STACK_OF(X509_ATTRIBUTE) *sk, char *buf, int len)
+	{
+	ASN1_TYPE *so;
+	ASN1_OCTET_STRING *os;
+	int i;
+	PKCS7_SIGNER_INFO si;
+
+	si.auth_attr=sk;
+
+	if (signed_string_nid == -1)
+		signed_string_nid=
+			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
+	/* To retrieve */
+	so=PKCS7_get_signed_attribute(&si,signed_string_nid);
+	if (so != NULL)
+		{
+		if (so->type == V_ASN1_OCTET_STRING)
+			{
+			os=so->value.octet_string;
+			i=os->length;
+			if ((i+1) > len)
+				i=len-1;
+			memcpy(buf,os->data,i);
+			return(i);
+			}
+		}
+	return(0);
+	}
+
+X509_ATTRIBUTE *add_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2)
+	{
+	/* To add an object of OID 1.9.999, which is a sequence containing
+	 * 2 octet strings */
+	unsigned char *p;
+	ASN1_OCTET_STRING *os1,*os2;
+	ASN1_STRING *seq;
+	X509_ATTRIBUTE *ret;
+	unsigned char *data;
+	int i,total;
+
+	if (signed_seq2string_nid == -1)
+		signed_seq2string_nid=
+			OBJ_create("1.9.9999","OID_example","Our example OID");
+
+	os1=ASN1_OCTET_STRING_new();
+	os2=ASN1_OCTET_STRING_new();
+	ASN1_OCTET_STRING_set(os1,(unsigned char*)str1,strlen(str1));
+	ASN1_OCTET_STRING_set(os2,(unsigned char*)str1,strlen(str1));
+	i =i2d_ASN1_OCTET_STRING(os1,NULL);
+	i+=i2d_ASN1_OCTET_STRING(os2,NULL);
+	total=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
+
+	data=malloc(total);
+	p=data;
+	ASN1_put_object(&p,1,i,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
+	i2d_ASN1_OCTET_STRING(os1,&p);
+	i2d_ASN1_OCTET_STRING(os2,&p);
+
+	seq=ASN1_STRING_new();
+	ASN1_STRING_set(seq,data,total);
+	free(data);
+	ASN1_OCTET_STRING_free(os1);
+	ASN1_OCTET_STRING_free(os2);
+
+	ret=X509_ATTRIBUTE_create(signed_seq2string_nid,
+		V_ASN1_SEQUENCE,(char *)seq);
+	return(ret);
+	}
+
+/* For this case, I will malloc the return strings */
+int sk_get_seq2string(STACK_OF(X509_ATTRIBUTE) *sk, char **str1, char **str2)
+	{
+	ASN1_TYPE *so;
+	PKCS7_SIGNER_INFO si;
+
+	if (signed_seq2string_nid == -1)
+		signed_seq2string_nid=
+			OBJ_create("1.9.9999","OID_example","Our example OID");
+
+	si.auth_attr=sk;
+	/* To retrieve */
+	so=PKCS7_get_signed_attribute(&si,signed_seq2string_nid);
+	if (so->type == V_ASN1_SEQUENCE)
+		{
+		ASN1_const_CTX c;
+		ASN1_STRING *s;
+		long length;
+		ASN1_OCTET_STRING *os1,*os2;
+
+		s=so->value.sequence;
+		c.p=ASN1_STRING_data(s);
+		c.max=c.p+ASN1_STRING_length(s);
+		if (!asn1_GetSequence(&c,&length)) goto err;
+		/* Length is the length of the seqence */
+
+		c.q=c.p;
+		if ((os1=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) 
+			goto err;
+		c.slen-=(c.p-c.q);
+
+		c.q=c.p;
+		if ((os2=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) 
+			goto err;
+		c.slen-=(c.p-c.q);
+
+		if (!asn1_const_Finish(&c)) goto err;
+		*str1=malloc(os1->length+1);
+		*str2=malloc(os2->length+1);
+		memcpy(*str1,os1->data,os1->length);
+		memcpy(*str2,os2->data,os2->length);
+		(*str1)[os1->length]='\0';
+		(*str2)[os2->length]='\0';
+		ASN1_OCTET_STRING_free(os1);
+		ASN1_OCTET_STRING_free(os2);
+		return(1);
+		}
+err:
+	return(0);
+	}
+
+
diff --git a/openssl/crypto/pkcs7/example.h b/openssl/crypto/pkcs7/example.h
new file mode 100644
index 0000000..96167de
--- /dev/null
+++ b/openssl/crypto/pkcs7/example.h
@@ -0,0 +1,57 @@
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+int add_signed_time(PKCS7_SIGNER_INFO *si);
+ASN1_UTCTIME *get_signed_time(PKCS7_SIGNER_INFO *si);
+int get_signed_seq2string(PKCS7_SIGNER_INFO *si, char **str1, char **str2);
diff --git a/openssl/crypto/pkcs7/info.pem b/openssl/crypto/pkcs7/info.pem
new file mode 100644
index 0000000..989baf8
--- /dev/null
+++ b/openssl/crypto/pkcs7/info.pem
@@ -0,0 +1,57 @@
+issuer :/C=AU/SP=Queensland/L=Brisbane/O=Cryptsoft Pty Ltd/OU=DEMONSTRATION AND TESTING/CN=DEMO ZERO VALUE CA
+subject:/C=AU/SP=Queensland/L=Brisbane/O=Cryptsoft Pty Ltd/OU=SMIME 003/CN=Information/Email=info@cryptsoft.com
+serial :047D
+
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1149 (0x47d)
+        Signature Algorithm: md5withRSAEncryption
+        Issuer: C=AU, SP=Queensland, L=Brisbane, O=Cryptsoft Pty Ltd, OU=DEMONSTRATION AND TESTING, CN=DEMO ZERO VALUE CA
+        Validity
+            Not Before: May 13 05:40:58 1998 GMT
+            Not After : May 12 05:40:58 2000 GMT
+        Subject: C=AU, SP=Queensland, L=Brisbane, O=Cryptsoft Pty Ltd, OU=SMIME 003, CN=Information/Email=info@cryptsoft.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Modulus:
+                    00:ad:e7:23:89:ee:0d:87:b7:9c:32:44:4b:95:81:
+                    73:dd:22:80:4b:2d:c5:60:b8:fe:1e:18:63:ef:dc:
+                    89:89:22:df:95:3c:7a:db:3d:9a:06:a8:08:d6:29:
+                    fd:ef:41:09:91:ed:bc:ad:98:f9:f6:28:90:62:6f:
+                    e7:e7:0c:4d:0b
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            Netscape Comment: 
+                Generated with SSLeay
+    Signature Algorithm: md5withRSAEncryption
+        52:15:ea:88:f4:f0:f9:0b:ef:ce:d5:f8:83:40:61:16:5e:55:
+        f9:ce:2d:d1:8b:31:5c:03:c6:2d:10:7c:61:d5:5c:0a:42:97:
+        d1:fd:65:b6:b6:84:a5:39:ec:46:ec:fc:e0:0d:d9:22:da:1b:
+        50:74:ad:92:cb:4e:90:e5:fa:7d
+
+-----BEGIN CERTIFICATE-----
+MIICTDCCAfagAwIBAgICBH0wDQYJKoZIhvcNAQEEBQAwgZIxCzAJBgNVBAYTAkFV
+MRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UE
+ChMRQ3J5cHRzb2Z0IFB0eSBMdGQxIjAgBgNVBAsTGURFTU9OU1RSQVRJT04gQU5E
+IFRFU1RJTkcxGzAZBgNVBAMTEkRFTU8gWkVSTyBWQUxVRSBDQTAeFw05ODA1MTMw
+NTQwNThaFw0wMDA1MTIwNTQwNThaMIGeMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
+UXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
+dCBQdHkgTHRkMRIwEAYDVQQLEwlTTUlNRSAwMDMxFDASBgNVBAMTC0luZm9ybWF0
+aW9uMSEwHwYJKoZIhvcNAQkBFhJpbmZvQGNyeXB0c29mdC5jb20wXDANBgkqhkiG
+9w0BAQEFAANLADBIAkEArecjie4Nh7ecMkRLlYFz3SKASy3FYLj+Hhhj79yJiSLf
+lTx62z2aBqgI1in970EJke28rZj59iiQYm/n5wxNCwIDAQABoygwJjAkBglghkgB
+hvhCAQ0EFxYVR2VuZXJhdGVkIHdpdGggU1NMZWF5MA0GCSqGSIb3DQEBBAUAA0EA
+UhXqiPTw+QvvztX4g0BhFl5V+c4t0YsxXAPGLRB8YdVcCkKX0f1ltraEpTnsRuz8
+4A3ZItobUHStkstOkOX6fQ==
+-----END CERTIFICATE-----
+
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOgIBAAJBAK3nI4nuDYe3nDJES5WBc90igEstxWC4/h4YY+/ciYki35U8ets9
+mgaoCNYp/e9BCZHtvK2Y+fYokGJv5+cMTQsCAwEAAQJBAIHpvXvqEcOEoDRRHuIG
+fkcB4jPHcr9KE9TpxabH6xs9beN6OJnkePXAHwaz5MnUgSnbpOKq+cw8miKjXwe/
+zVECIQDVLwncT2lRmXarEYHzb+q/0uaSvKhWKKt3kJasLNTrAwIhANDUc/ghut29
+p3jJYjurzUKuG774/5eLjPLsxPPIZzNZAiA/10hSq41UnGqHLEUIS9m2/EeEZe7b
+bm567dfRU9OnVQIgDo8ROrZXSchEGbaog5J5r/Fle83uO8l93R3GqVxKXZkCIFfk
+IPD5PIYQAyyod3hyKKza7ZP4CGY4oOfZetbkSGGG
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/crypto/pkcs7/infokey.pem b/openssl/crypto/pkcs7/infokey.pem
new file mode 100644
index 0000000..1e2acc9
--- /dev/null
+++ b/openssl/crypto/pkcs7/infokey.pem
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOgIBAAJBAK3nI4nuDYe3nDJES5WBc90igEstxWC4/h4YY+/ciYki35U8ets9
+mgaoCNYp/e9BCZHtvK2Y+fYokGJv5+cMTQsCAwEAAQJBAIHpvXvqEcOEoDRRHuIG
+fkcB4jPHcr9KE9TpxabH6xs9beN6OJnkePXAHwaz5MnUgSnbpOKq+cw8miKjXwe/
+zVECIQDVLwncT2lRmXarEYHzb+q/0uaSvKhWKKt3kJasLNTrAwIhANDUc/ghut29
+p3jJYjurzUKuG774/5eLjPLsxPPIZzNZAiA/10hSq41UnGqHLEUIS9m2/EeEZe7b
+bm567dfRU9OnVQIgDo8ROrZXSchEGbaog5J5r/Fle83uO8l93R3GqVxKXZkCIFfk
+IPD5PIYQAyyod3hyKKza7ZP4CGY4oOfZetbkSGGG
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/crypto/pkcs7/p7/a1 b/openssl/crypto/pkcs7/p7/a1
new file mode 100644
index 0000000..56ca943
--- /dev/null
+++ b/openssl/crypto/pkcs7/p7/a1
@@ -0,0 +1,2 @@
+j,H>_æá_­DôzEîLœ	VJ³ß觬¤””E3ûáYäx%_Àk
+3ê)DLScñ8%ôM
\ No newline at end of file
diff --git a/openssl/crypto/pkcs7/p7/a2 b/openssl/crypto/pkcs7/p7/a2
new file mode 100644
index 0000000..23d8fb5
--- /dev/null
+++ b/openssl/crypto/pkcs7/p7/a2
@@ -0,0 +1 @@
+k~@a”,NâM͹¼	<O( KP—騠¤K²>­×U¿o_½BqrmÎ?Ù t?t÷ÏéId2‰Š
\ No newline at end of file
diff --git a/openssl/crypto/pkcs7/p7/cert.p7c b/openssl/crypto/pkcs7/p7/cert.p7c
new file mode 100644
index 0000000..2b75ec0
--- /dev/null
+++ b/openssl/crypto/pkcs7/p7/cert.p7c
Binary files differ
diff --git a/openssl/crypto/pkcs7/p7/smime.p7m b/openssl/crypto/pkcs7/p7/smime.p7m
new file mode 100644
index 0000000..2b6e6f8
--- /dev/null
+++ b/openssl/crypto/pkcs7/p7/smime.p7m
Binary files differ
diff --git a/openssl/crypto/pkcs7/p7/smime.p7s b/openssl/crypto/pkcs7/p7/smime.p7s
new file mode 100644
index 0000000..2b5d4fb
--- /dev/null
+++ b/openssl/crypto/pkcs7/p7/smime.p7s
Binary files differ
diff --git a/openssl/crypto/pkcs7/pk7_asn1.c b/openssl/crypto/pkcs7/pk7_asn1.c
new file mode 100644
index 0000000..b7ec288
--- /dev/null
+++ b/openssl/crypto/pkcs7/pk7_asn1.c
@@ -0,0 +1,247 @@
+/* pk7_asn.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pkcs7.h>
+#include <openssl/x509.h>
+
+/* PKCS#7 ASN1 module */
+
+/* This is the ANY DEFINED BY table for the top level PKCS#7 structure */
+
+ASN1_ADB_TEMPLATE(p7default) = ASN1_EXP_OPT(PKCS7, d.other, ASN1_ANY, 0);
+
+ASN1_ADB(PKCS7) = {
+	ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP_OPT(PKCS7, d.data, ASN1_OCTET_STRING_NDEF, 0)),
+	ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP_OPT(PKCS7, d.sign, PKCS7_SIGNED, 0)),
+	ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.enveloped, PKCS7_ENVELOPE, 0)),
+	ADB_ENTRY(NID_pkcs7_signedAndEnveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.signed_and_enveloped, PKCS7_SIGN_ENVELOPE, 0)),
+	ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP_OPT(PKCS7, d.digest, PKCS7_DIGEST, 0)),
+	ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0))
+} ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL);
+
+/* PKCS#7 streaming support */
+static int pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
+{
+	ASN1_STREAM_ARG *sarg = exarg;
+	PKCS7 **pp7 = (PKCS7 **)pval;
+
+	switch(operation)
+		{
+
+		case ASN1_OP_STREAM_PRE:
+		if (PKCS7_stream(&sarg->boundary, *pp7) <= 0)
+			return 0;
+		case ASN1_OP_DETACHED_PRE:
+		sarg->ndef_bio = PKCS7_dataInit(*pp7, sarg->out);
+		if (!sarg->ndef_bio)
+			return 0;
+		break;
+
+		case ASN1_OP_STREAM_POST:
+		case ASN1_OP_DETACHED_POST:
+		if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0)
+			return 0;
+		break;
+
+		}
+	return 1;
+}
+
+ASN1_NDEF_SEQUENCE_cb(PKCS7, pk7_cb) = {
+	ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT),
+	ASN1_ADB_OBJECT(PKCS7)
+}ASN1_NDEF_SEQUENCE_END_cb(PKCS7, PKCS7)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7)
+IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7)
+IMPLEMENT_ASN1_DUP_FUNCTION(PKCS7)
+
+ASN1_NDEF_SEQUENCE(PKCS7_SIGNED) = {
+	ASN1_SIMPLE(PKCS7_SIGNED, version, ASN1_INTEGER),
+	ASN1_SET_OF(PKCS7_SIGNED, md_algs, X509_ALGOR),
+	ASN1_SIMPLE(PKCS7_SIGNED, contents, PKCS7),
+	ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNED, cert, X509, 0),
+	ASN1_IMP_SET_OF_OPT(PKCS7_SIGNED, crl, X509_CRL, 1),
+	ASN1_SET_OF(PKCS7_SIGNED, signer_info, PKCS7_SIGNER_INFO)
+} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGNED)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED)
+
+/* Minor tweak to operation: free up EVP_PKEY */
+static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
+{
+	if(operation == ASN1_OP_FREE_POST) {
+		PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval;
+		EVP_PKEY_free(si->pkey);
+	}
+	return 1;
+}
+
+ASN1_SEQUENCE_cb(PKCS7_SIGNER_INFO, si_cb) = {
+	ASN1_SIMPLE(PKCS7_SIGNER_INFO, version, ASN1_INTEGER),
+	ASN1_SIMPLE(PKCS7_SIGNER_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL),
+	ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_alg, X509_ALGOR),
+	/* NB this should be a SET OF but we use a SEQUENCE OF so the
+	 * original order * is retained when the structure is reencoded.
+	 * Since the attributes are implicitly tagged this will not affect
+	 * the encoding.
+	 */
+	ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNER_INFO, auth_attr, X509_ATTRIBUTE, 0),
+	ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_enc_alg, X509_ALGOR),
+	ASN1_SIMPLE(PKCS7_SIGNER_INFO, enc_digest, ASN1_OCTET_STRING),
+	ASN1_IMP_SET_OF_OPT(PKCS7_SIGNER_INFO, unauth_attr, X509_ATTRIBUTE, 1)
+} ASN1_SEQUENCE_END_cb(PKCS7_SIGNER_INFO, PKCS7_SIGNER_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
+
+ASN1_SEQUENCE(PKCS7_ISSUER_AND_SERIAL) = {
+	ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, issuer, X509_NAME),
+	ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, serial, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(PKCS7_ISSUER_AND_SERIAL)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
+
+ASN1_NDEF_SEQUENCE(PKCS7_ENVELOPE) = {
+	ASN1_SIMPLE(PKCS7_ENVELOPE, version, ASN1_INTEGER),
+	ASN1_SET_OF(PKCS7_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO),
+	ASN1_SIMPLE(PKCS7_ENVELOPE, enc_data, PKCS7_ENC_CONTENT)
+} ASN1_NDEF_SEQUENCE_END(PKCS7_ENVELOPE)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
+
+/* Minor tweak to operation: free up X509 */
+static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+								void *exarg)
+{
+	if(operation == ASN1_OP_FREE_POST) {
+		PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval;
+		X509_free(ri->cert);
+	}
+	return 1;
+}
+
+ASN1_SEQUENCE_cb(PKCS7_RECIP_INFO, ri_cb) = {
+	ASN1_SIMPLE(PKCS7_RECIP_INFO, version, ASN1_INTEGER),
+	ASN1_SIMPLE(PKCS7_RECIP_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL),
+	ASN1_SIMPLE(PKCS7_RECIP_INFO, key_enc_algor, X509_ALGOR),
+	ASN1_SIMPLE(PKCS7_RECIP_INFO, enc_key, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END_cb(PKCS7_RECIP_INFO, PKCS7_RECIP_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
+
+ASN1_NDEF_SEQUENCE(PKCS7_ENC_CONTENT) = {
+	ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT),
+	ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR),
+	ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING_NDEF, 0)
+} ASN1_NDEF_SEQUENCE_END(PKCS7_ENC_CONTENT)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
+
+ASN1_NDEF_SEQUENCE(PKCS7_SIGN_ENVELOPE) = {
+	ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, version, ASN1_INTEGER),
+	ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO),
+	ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, md_algs, X509_ALGOR),
+	ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, enc_data, PKCS7_ENC_CONTENT),
+	ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, cert, X509, 0),
+	ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, crl, X509_CRL, 1),
+	ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, signer_info, PKCS7_SIGNER_INFO)
+} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGN_ENVELOPE)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
+
+ASN1_NDEF_SEQUENCE(PKCS7_ENCRYPT) = {
+	ASN1_SIMPLE(PKCS7_ENCRYPT, version, ASN1_INTEGER),
+	ASN1_SIMPLE(PKCS7_ENCRYPT, enc_data, PKCS7_ENC_CONTENT)
+} ASN1_NDEF_SEQUENCE_END(PKCS7_ENCRYPT)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
+
+ASN1_NDEF_SEQUENCE(PKCS7_DIGEST) = {
+	ASN1_SIMPLE(PKCS7_DIGEST, version, ASN1_INTEGER),
+	ASN1_SIMPLE(PKCS7_DIGEST, md, X509_ALGOR),
+	ASN1_SIMPLE(PKCS7_DIGEST, contents, PKCS7),
+	ASN1_SIMPLE(PKCS7_DIGEST, digest, ASN1_OCTET_STRING)
+} ASN1_NDEF_SEQUENCE_END(PKCS7_DIGEST)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_DIGEST)
+
+/* Specials for authenticated attributes */
+
+/* When signing attributes we want to reorder them to match the sorted
+ * encoding.
+ */
+
+ASN1_ITEM_TEMPLATE(PKCS7_ATTR_SIGN) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, PKCS7_ATTRIBUTES, X509_ATTRIBUTE)
+ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_SIGN)
+
+/* When verifying attributes we need to use the received order. So 
+ * we use SEQUENCE OF and tag it to SET OF
+ */
+
+ASN1_ITEM_TEMPLATE(PKCS7_ATTR_VERIFY) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
+				V_ASN1_SET, PKCS7_ATTRIBUTES, X509_ATTRIBUTE)
+ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_VERIFY)
+
+IMPLEMENT_ASN1_PRINT_FUNCTION(PKCS7)
diff --git a/openssl/crypto/pkcs7/pk7_attr.c b/openssl/crypto/pkcs7/pk7_attr.c
new file mode 100644
index 0000000..a97db51
--- /dev/null
+++ b/openssl/crypto/pkcs7/pk7_attr.c
@@ -0,0 +1,165 @@
+/* pk7_attr.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/pkcs7.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+
+int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK_OF(X509_ALGOR) *cap)
+{
+	ASN1_STRING *seq;
+	if(!(seq = ASN1_STRING_new())) {
+		PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	seq->length = ASN1_item_i2d((ASN1_VALUE *)cap,&seq->data,
+				ASN1_ITEM_rptr(X509_ALGORS));
+        return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
+							V_ASN1_SEQUENCE, seq);
+}
+
+STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)
+	{
+	ASN1_TYPE *cap;
+	const unsigned char *p;
+
+	cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities);
+	if (!cap || (cap->type != V_ASN1_SEQUENCE))
+		return NULL;
+	p = cap->value.sequence->data;
+	return (STACK_OF(X509_ALGOR) *)
+		ASN1_item_d2i(NULL, &p, cap->value.sequence->length,
+				ASN1_ITEM_rptr(X509_ALGORS));
+	}
+
+/* Basic smime-capabilities OID and optional integer arg */
+int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
+{
+	X509_ALGOR *alg;
+
+	if(!(alg = X509_ALGOR_new())) {
+		PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	ASN1_OBJECT_free(alg->algorithm);
+	alg->algorithm = OBJ_nid2obj (nid);
+	if (arg > 0) {
+		ASN1_INTEGER *nbit;
+		if(!(alg->parameter = ASN1_TYPE_new())) {
+			PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		if(!(nbit = ASN1_INTEGER_new())) {
+			PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		if(!ASN1_INTEGER_set (nbit, arg)) {
+			PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		alg->parameter->value.integer = nbit;
+		alg->parameter->type = V_ASN1_INTEGER;
+	}
+	sk_X509_ALGOR_push (sk, alg);
+	return 1;
+}
+
+int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid)
+	{
+	if (PKCS7_get_signed_attribute(si, NID_pkcs9_contentType))
+		return 0;
+	if (!coid)
+		coid = OBJ_nid2obj(NID_pkcs7_data);
+	return PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
+				V_ASN1_OBJECT, coid);
+	}
+
+int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t)
+	{
+	if (!t && !(t=X509_gmtime_adj(NULL,0)))
+		{
+		PKCS7err(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME,
+				ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime,
+						V_ASN1_UTCTIME, t);
+	}
+
+int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
+				const unsigned char *md, int mdlen)
+	{
+	ASN1_OCTET_STRING *os;
+	os = ASN1_OCTET_STRING_new();
+	if (!os)
+		return 0;
+	if (!ASN1_STRING_set(os, md, mdlen)
+		|| !PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest,
+						V_ASN1_OCTET_STRING, os))
+		{
+		ASN1_OCTET_STRING_free(os);
+		return 0;
+		}
+	return 1;
+	}
diff --git a/openssl/crypto/pkcs7/pk7_dgst.c b/openssl/crypto/pkcs7/pk7_dgst.c
new file mode 100644
index 0000000..90edfa5
--- /dev/null
+++ b/openssl/crypto/pkcs7/pk7_dgst.c
@@ -0,0 +1,66 @@
+/* crypto/pkcs7/pk7_dgst.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+
diff --git a/openssl/crypto/pkcs7/pk7_doit.c b/openssl/crypto/pkcs7/pk7_doit.c
new file mode 100644
index 0000000..3bf1a36
--- /dev/null
+++ b/openssl/crypto/pkcs7/pk7_doit.c
@@ -0,0 +1,1248 @@
+/* crypto/pkcs7/pk7_doit.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+
+static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
+			 void *value);
+static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid);
+
+static int PKCS7_type_is_other(PKCS7* p7)
+	{
+	int isOther=1;
+	
+	int nid=OBJ_obj2nid(p7->type);
+
+	switch( nid )
+		{
+	case NID_pkcs7_data:
+	case NID_pkcs7_signed:
+	case NID_pkcs7_enveloped:
+	case NID_pkcs7_signedAndEnveloped:
+	case NID_pkcs7_digest:
+	case NID_pkcs7_encrypted:
+		isOther=0;
+		break;
+	default:
+		isOther=1;
+		}
+
+	return isOther;
+
+	}
+
+static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7)
+	{
+	if ( PKCS7_type_is_data(p7))
+		return p7->d.data;
+	if ( PKCS7_type_is_other(p7) && p7->d.other
+		&& (p7->d.other->type == V_ASN1_OCTET_STRING))
+		return p7->d.other->value.octet_string;
+	return NULL;
+	}
+
+static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
+	{
+	BIO *btmp;
+	const EVP_MD *md;
+	if ((btmp=BIO_new(BIO_f_md())) == NULL)
+		{
+		PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB);
+		goto err;
+		}
+
+	md=EVP_get_digestbyobj(alg->algorithm);
+	if (md == NULL)
+		{
+		PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,PKCS7_R_UNKNOWN_DIGEST_TYPE);
+		goto err;
+		}
+
+	BIO_set_md(btmp,md);
+	if (*pbio == NULL)
+		*pbio=btmp;
+	else if (!BIO_push(*pbio,btmp))
+		{
+		PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB);
+		goto err;
+		}
+	btmp=NULL;
+
+	return 1;
+
+	err:
+	if (btmp)
+		BIO_free(btmp);
+	return 0;
+
+	}
+
+static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
+					unsigned char *key, int keylen)
+	{
+	EVP_PKEY_CTX *pctx = NULL;
+	EVP_PKEY *pkey = NULL;
+	unsigned char *ek = NULL;
+	int ret = 0;
+	size_t eklen;
+
+	pkey = X509_get_pubkey(ri->cert);
+
+	if (!pkey)
+		return 0;
+
+	pctx = EVP_PKEY_CTX_new(pkey, NULL);
+	if (!pctx)
+		return 0;
+
+	if (EVP_PKEY_encrypt_init(pctx) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
+				EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0)
+		{
+		PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR);
+		goto err;
+		}
+
+	if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0)
+		goto err;
+
+	ek = OPENSSL_malloc(eklen);
+
+	if (ek == NULL)
+		{
+		PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0)
+		goto err;
+
+	ASN1_STRING_set0(ri->enc_key, ek, eklen);
+	ek = NULL;
+
+	ret = 1;
+
+	err:
+	if (pkey)
+		EVP_PKEY_free(pkey);
+	if (pctx)
+		EVP_PKEY_CTX_free(pctx);
+	if (ek)
+		OPENSSL_free(ek);
+	return ret;
+
+	}
+
+
+static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
+			       PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey)
+	{
+	EVP_PKEY_CTX *pctx = NULL;
+	unsigned char *ek = NULL;
+	size_t eklen;
+
+	int ret = 0;
+
+	pctx = EVP_PKEY_CTX_new(pkey, NULL);
+	if (!pctx)
+		return 0;
+
+	if (EVP_PKEY_decrypt_init(pctx) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
+				EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0)
+		{
+		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR);
+		goto err;
+		}
+
+	if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
+				ri->enc_key->data, ri->enc_key->length) <= 0)
+		goto err;
+
+	ek = OPENSSL_malloc(eklen);
+
+	if (ek == NULL)
+		{
+		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (EVP_PKEY_decrypt(pctx, ek, &eklen,
+				ri->enc_key->data, ri->enc_key->length) <= 0)
+		{
+		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
+		goto err;
+		}
+
+	ret = 1;
+
+	*pek = ek;
+	*peklen = eklen;
+
+	err:
+	if (pctx)
+		EVP_PKEY_CTX_free(pctx);
+	if (!ret && ek)
+		OPENSSL_free(ek);
+
+	return ret;
+	}
+
+BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
+	{
+	int i;
+	BIO *out=NULL,*btmp=NULL;
+	X509_ALGOR *xa = NULL;
+	const EVP_CIPHER *evp_cipher=NULL;
+	STACK_OF(X509_ALGOR) *md_sk=NULL;
+	STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
+	X509_ALGOR *xalg=NULL;
+	PKCS7_RECIP_INFO *ri=NULL;
+	ASN1_OCTET_STRING *os=NULL;
+
+	i=OBJ_obj2nid(p7->type);
+	p7->state=PKCS7_S_HEADER;
+
+	switch (i)
+		{
+	case NID_pkcs7_signed:
+		md_sk=p7->d.sign->md_algs;
+		os = PKCS7_get_octet_string(p7->d.sign->contents);
+		break;
+	case NID_pkcs7_signedAndEnveloped:
+		rsk=p7->d.signed_and_enveloped->recipientinfo;
+		md_sk=p7->d.signed_and_enveloped->md_algs;
+		xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
+		evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher;
+		if (evp_cipher == NULL)
+			{
+			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
+						PKCS7_R_CIPHER_NOT_INITIALIZED);
+			goto err;
+			}
+		break;
+	case NID_pkcs7_enveloped:
+		rsk=p7->d.enveloped->recipientinfo;
+		xalg=p7->d.enveloped->enc_data->algorithm;
+		evp_cipher=p7->d.enveloped->enc_data->cipher;
+		if (evp_cipher == NULL)
+			{
+			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
+						PKCS7_R_CIPHER_NOT_INITIALIZED);
+			goto err;
+			}
+		break;
+	case NID_pkcs7_digest:
+		xa = p7->d.digest->md;
+		os = PKCS7_get_octet_string(p7->d.digest->contents);
+		break;
+	case NID_pkcs7_data:
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+	        goto err;
+		}
+
+	for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
+		if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
+			goto err;
+
+	if (xa && !PKCS7_bio_add_digest(&out, xa))
+			goto err;
+
+	if (evp_cipher != NULL)
+		{
+		unsigned char key[EVP_MAX_KEY_LENGTH];
+		unsigned char iv[EVP_MAX_IV_LENGTH];
+		int keylen,ivlen;
+		EVP_CIPHER_CTX *ctx;
+
+		if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
+			{
+			PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
+			goto err;
+			}
+		BIO_get_cipher_ctx(btmp, &ctx);
+		keylen=EVP_CIPHER_key_length(evp_cipher);
+		ivlen=EVP_CIPHER_iv_length(evp_cipher);
+		xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
+		if (ivlen > 0)
+			if (RAND_pseudo_bytes(iv,ivlen) <= 0)
+				goto err;
+		if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1)<=0)
+			goto err;
+		if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
+			goto err;
+		if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
+			goto err;
+
+		if (ivlen > 0) {
+			if (xalg->parameter == NULL) {
+				xalg->parameter = ASN1_TYPE_new();
+				if (xalg->parameter == NULL)
+					goto err;
+			}
+			if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
+				goto err;
+		}
+
+		/* Lets do the pub key stuff :-) */
+		for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
+			{
+			ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
+			if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
+				goto err;
+			}
+		OPENSSL_cleanse(key, keylen);
+
+		if (out == NULL)
+			out=btmp;
+		else
+			BIO_push(out,btmp);
+		btmp=NULL;
+		}
+
+	if (bio == NULL)
+		{
+		if (PKCS7_is_detached(p7))
+			bio=BIO_new(BIO_s_null());
+		else if (os && os->length > 0)
+			bio = BIO_new_mem_buf(os->data, os->length);
+		if(bio == NULL)
+			{
+			bio=BIO_new(BIO_s_mem());
+			if (bio == NULL)
+				goto err;
+			BIO_set_mem_eof_return(bio,0);
+			}
+		}
+	if (out)
+		BIO_push(out,bio);
+	else
+		out = bio;
+	bio=NULL;
+	if (0)
+		{
+err:
+		if (out != NULL)
+			BIO_free_all(out);
+		if (btmp != NULL)
+			BIO_free_all(btmp);
+		out=NULL;
+		}
+	return(out);
+	}
+
+static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert)
+	{
+	int ret;
+	ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
+				pcert->cert_info->issuer);
+	if (ret)
+		return ret;
+	return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,
+					ri->issuer_and_serial->serial);
+	}
+
+/* int */
+BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
+	{
+	int i,j;
+	BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL;
+	X509_ALGOR *xa;
+	ASN1_OCTET_STRING *data_body=NULL;
+	const EVP_MD *evp_md;
+	const EVP_CIPHER *evp_cipher=NULL;
+	EVP_CIPHER_CTX *evp_ctx=NULL;
+	X509_ALGOR *enc_alg=NULL;
+	STACK_OF(X509_ALGOR) *md_sk=NULL;
+	STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
+	PKCS7_RECIP_INFO *ri=NULL;
+
+	i=OBJ_obj2nid(p7->type);
+	p7->state=PKCS7_S_HEADER;
+
+	switch (i)
+		{
+	case NID_pkcs7_signed:
+		data_body=PKCS7_get_octet_string(p7->d.sign->contents);
+		md_sk=p7->d.sign->md_algs;
+		break;
+	case NID_pkcs7_signedAndEnveloped:
+		rsk=p7->d.signed_and_enveloped->recipientinfo;
+		md_sk=p7->d.signed_and_enveloped->md_algs;
+		data_body=p7->d.signed_and_enveloped->enc_data->enc_data;
+		enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm;
+		evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
+		if (evp_cipher == NULL)
+			{
+			PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
+			goto err;
+			}
+		break;
+	case NID_pkcs7_enveloped:
+		rsk=p7->d.enveloped->recipientinfo;
+		enc_alg=p7->d.enveloped->enc_data->algorithm;
+		data_body=p7->d.enveloped->enc_data->enc_data;
+		evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
+		if (evp_cipher == NULL)
+			{
+			PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
+			goto err;
+			}
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+	        goto err;
+		}
+
+	/* We will be checking the signature */
+	if (md_sk != NULL)
+		{
+		for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
+			{
+			xa=sk_X509_ALGOR_value(md_sk,i);
+			if ((btmp=BIO_new(BIO_f_md())) == NULL)
+				{
+				PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
+				goto err;
+				}
+
+			j=OBJ_obj2nid(xa->algorithm);
+			evp_md=EVP_get_digestbynid(j);
+			if (evp_md == NULL)
+				{
+				PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE);
+				goto err;
+				}
+
+			BIO_set_md(btmp,evp_md);
+			if (out == NULL)
+				out=btmp;
+			else
+				BIO_push(out,btmp);
+			btmp=NULL;
+			}
+		}
+
+	if (evp_cipher != NULL)
+		{
+#if 0
+		unsigned char key[EVP_MAX_KEY_LENGTH];
+		unsigned char iv[EVP_MAX_IV_LENGTH];
+		unsigned char *p;
+		int keylen,ivlen;
+		int max;
+		X509_OBJECT ret;
+#endif
+		unsigned char *ek = NULL;
+		int eklen;
+
+		if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
+			{
+			PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
+			goto err;
+			}
+
+		/* It was encrypted, we need to decrypt the secret key
+		 * with the private key */
+
+		/* Find the recipientInfo which matches the passed certificate
+		 * (if any)
+		 */
+
+		if (pcert)
+			{
+			for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
+				{
+				ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
+				if (!pkcs7_cmp_ri(ri, pcert))
+					break;
+				ri=NULL;
+				}
+			if (ri == NULL)
+				{
+				PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+				      PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
+				goto err;
+				}
+			}
+
+		/* If we haven't got a certificate try each ri in turn */
+
+		if (pcert == NULL)
+			{
+			for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
+				{
+				ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
+				if (pkcs7_decrypt_rinfo(&ek, &eklen,
+							ri, pkey) > 0)
+					break;
+				ERR_clear_error();
+				ri = NULL;
+				}
+			if (ri == NULL)
+				{
+				PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+				      PKCS7_R_NO_RECIPIENT_MATCHES_KEY);
+				goto err;
+				}
+			}
+		else
+			{
+			if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) <= 0)
+				goto err;
+			}
+
+		evp_ctx=NULL;
+		BIO_get_cipher_ctx(etmp,&evp_ctx);
+		if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0)
+			goto err;
+		if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
+			goto err;
+
+		if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) {
+			/* Some S/MIME clients don't use the same key
+			 * and effective key length. The key length is
+			 * determined by the size of the decrypted RSA key.
+			 */
+			if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen))
+				{
+				PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+					PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
+				goto err;
+				}
+		} 
+		if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,ek,NULL,0) <= 0)
+			goto err;
+
+		if (ek)
+			{
+			OPENSSL_cleanse(ek,eklen);
+			OPENSSL_free(ek);
+			}
+
+		if (out == NULL)
+			out=etmp;
+		else
+			BIO_push(out,etmp);
+		etmp=NULL;
+		}
+
+#if 1
+	if (PKCS7_is_detached(p7) || (in_bio != NULL))
+		{
+		bio=in_bio;
+		}
+	else 
+		{
+#if 0
+		bio=BIO_new(BIO_s_mem());
+		/* We need to set this so that when we have read all
+		 * the data, the encrypt BIO, if present, will read
+		 * EOF and encode the last few bytes */
+		BIO_set_mem_eof_return(bio,0);
+
+		if (data_body->length > 0)
+			BIO_write(bio,(char *)data_body->data,data_body->length);
+#else
+		if (data_body->length > 0)
+		      bio = BIO_new_mem_buf(data_body->data,data_body->length);
+		else {
+			bio=BIO_new(BIO_s_mem());
+			BIO_set_mem_eof_return(bio,0);
+		}
+		if (bio == NULL)
+			goto err;
+#endif
+		}
+	BIO_push(out,bio);
+	bio=NULL;
+#endif
+	if (0)
+		{
+err:
+		if (out != NULL) BIO_free_all(out);
+		if (btmp != NULL) BIO_free_all(btmp);
+		if (etmp != NULL) BIO_free_all(etmp);
+		if (bio != NULL) BIO_free_all(bio);
+		out=NULL;
+		}
+	return(out);
+	}
+
+static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
+	{
+	for (;;)
+		{
+		bio=BIO_find_type(bio,BIO_TYPE_MD);
+		if (bio == NULL)
+			{
+			PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
+			return NULL;	
+			}
+		BIO_get_md_ctx(bio,pmd);
+		if (*pmd == NULL)
+			{
+			PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,ERR_R_INTERNAL_ERROR);
+			return NULL;
+			}	
+		if (EVP_MD_CTX_type(*pmd) == nid)
+			return bio;
+		bio=BIO_next(bio);
+		}
+	return NULL;
+	}
+
+static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx)
+	{
+	unsigned char md_data[EVP_MAX_MD_SIZE];
+	unsigned int md_len;
+
+	/* Add signing time if not already present */
+	if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime))
+		{
+		if (!PKCS7_add0_attrib_signing_time(si, NULL))
+			{
+			PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB,
+					ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		}
+
+	/* Add digest */
+	EVP_DigestFinal_ex(mctx, md_data,&md_len);
+	if (!PKCS7_add1_attrib_digest(si, md_data, md_len))
+		{
+		PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+
+	/* Now sign the attributes */
+	if (!PKCS7_SIGNER_INFO_sign(si))
+			return 0;
+
+	return 1;
+	}
+	
+				
+int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
+	{
+	int ret=0;
+	int i,j;
+	BIO *btmp;
+	PKCS7_SIGNER_INFO *si;
+	EVP_MD_CTX *mdc,ctx_tmp;
+	STACK_OF(X509_ATTRIBUTE) *sk;
+	STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
+	ASN1_OCTET_STRING *os=NULL;
+
+	EVP_MD_CTX_init(&ctx_tmp);
+	i=OBJ_obj2nid(p7->type);
+	p7->state=PKCS7_S_HEADER;
+
+	switch (i)
+		{
+	case NID_pkcs7_data:
+		os = p7->d.data;
+		break;
+	case NID_pkcs7_signedAndEnveloped:
+		/* XXXXXXXXXXXXXXXX */
+		si_sk=p7->d.signed_and_enveloped->signer_info;
+		os = p7->d.signed_and_enveloped->enc_data->enc_data;
+		if (!os)
+			{
+			os=M_ASN1_OCTET_STRING_new();
+			if (!os)
+				{
+				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			p7->d.signed_and_enveloped->enc_data->enc_data=os;
+			}
+		break;
+	case NID_pkcs7_enveloped:
+		/* XXXXXXXXXXXXXXXX */
+		os = p7->d.enveloped->enc_data->enc_data;
+		if (!os)
+			{
+			os=M_ASN1_OCTET_STRING_new();
+			if (!os)
+				{
+				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			p7->d.enveloped->enc_data->enc_data=os;
+			}
+		break;
+	case NID_pkcs7_signed:
+		si_sk=p7->d.sign->signer_info;
+		os=PKCS7_get_octet_string(p7->d.sign->contents);
+		/* If detached data then the content is excluded */
+		if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
+			M_ASN1_OCTET_STRING_free(os);
+			p7->d.sign->contents->d.data = NULL;
+		}
+		break;
+
+	case NID_pkcs7_digest:
+		os=PKCS7_get_octet_string(p7->d.digest->contents);
+		/* If detached data then the content is excluded */
+		if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached)
+			{
+			M_ASN1_OCTET_STRING_free(os);
+			p7->d.digest->contents->d.data = NULL;
+			}
+		break;
+
+	default:
+		PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+	        goto err;
+		}
+
+	if (si_sk != NULL)
+		{
+		for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
+			{
+			si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
+			if (si->pkey == NULL)
+				continue;
+
+			j = OBJ_obj2nid(si->digest_alg->algorithm);
+
+			btmp=bio;
+
+			btmp = PKCS7_find_digest(&mdc, btmp, j);
+
+			if (btmp == NULL)
+				goto err;
+
+			/* We now have the EVP_MD_CTX, lets do the
+			 * signing. */
+			EVP_MD_CTX_copy_ex(&ctx_tmp,mdc);
+
+			sk=si->auth_attr;
+
+			/* If there are attributes, we add the digest
+			 * attribute and only sign the attributes */
+			if (sk_X509_ATTRIBUTE_num(sk) > 0)
+				{
+				if (!do_pkcs7_signed_attrib(si, &ctx_tmp))
+					goto err;
+				}
+			else
+				{
+				unsigned char *abuf = NULL;
+				unsigned int abuflen;
+				abuflen = EVP_PKEY_size(si->pkey);
+				abuf = OPENSSL_malloc(abuflen);
+				if (!abuf)
+					goto err;
+
+				if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen,
+							si->pkey))
+					{
+					PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
+							ERR_R_EVP_LIB);
+					goto err;
+					}
+				ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
+				}
+			}
+		}
+	else if (i == NID_pkcs7_digest)
+		{
+		unsigned char md_data[EVP_MAX_MD_SIZE];
+		unsigned int md_len;
+		if (!PKCS7_find_digest(&mdc, bio,
+				OBJ_obj2nid(p7->d.digest->md->algorithm)))
+			goto err;
+		EVP_DigestFinal_ex(mdc,md_data,&md_len);
+		M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
+		}
+
+	if (!PKCS7_is_detached(p7) && !(os->flags & ASN1_STRING_FLAG_NDEF))
+		{
+		char *cont;
+		long contlen;
+		btmp=BIO_find_type(bio,BIO_TYPE_MEM);
+		if (btmp == NULL)
+			{
+			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
+			goto err;
+			}
+		contlen = BIO_get_mem_data(btmp, &cont);
+		/* Mark the BIO read only then we can use its copy of the data
+		 * instead of making an extra copy.
+		 */
+		BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
+		BIO_set_mem_eof_return(btmp, 0);
+		ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
+		}
+	ret=1;
+err:
+	EVP_MD_CTX_cleanup(&ctx_tmp);
+	return(ret);
+	}
+
+int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
+	{
+	EVP_MD_CTX mctx;
+	EVP_PKEY_CTX *pctx;
+	unsigned char *abuf = NULL;
+	int alen;
+	size_t siglen;
+	const EVP_MD *md = NULL;
+
+	md = EVP_get_digestbyobj(si->digest_alg->algorithm);
+	if (md == NULL)
+		return 0;
+
+	EVP_MD_CTX_init(&mctx);
+	if (EVP_DigestSignInit(&mctx, &pctx, md,NULL, si->pkey) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
+				EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0)
+		{
+		PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
+		goto err;
+		}
+
+	alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr,&abuf,
+				ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
+	if(!abuf)
+		goto err;
+	if (EVP_DigestSignUpdate(&mctx,abuf,alen) <= 0)
+		goto err;
+	OPENSSL_free(abuf);
+	if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
+		goto err;
+	abuf = OPENSSL_malloc(siglen);
+	if(!abuf)
+		goto err;
+	if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
+				EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0)
+		{
+		PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
+		goto err;
+		}
+
+	EVP_MD_CTX_cleanup(&mctx);
+
+	ASN1_STRING_set0(si->enc_digest, abuf, siglen);
+
+	return 1;
+
+	err:
+	if (abuf)
+		OPENSSL_free(abuf);
+	EVP_MD_CTX_cleanup(&mctx);
+	return 0;
+
+	}
+
+int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
+	     PKCS7 *p7, PKCS7_SIGNER_INFO *si)
+	{
+	PKCS7_ISSUER_AND_SERIAL *ias;
+	int ret=0,i;
+	STACK_OF(X509) *cert;
+	X509 *x509;
+
+	if (PKCS7_type_is_signed(p7))
+		{
+		cert=p7->d.sign->cert;
+		}
+	else if (PKCS7_type_is_signedAndEnveloped(p7))
+		{
+		cert=p7->d.signed_and_enveloped->cert;
+		}
+	else
+		{
+		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_WRONG_PKCS7_TYPE);
+		goto err;
+		}
+	/* XXXXXXXXXXXXXXXXXXXXXXX */
+	ias=si->issuer_and_serial;
+
+	x509=X509_find_by_issuer_and_serial(cert,ias->issuer,ias->serial);
+
+	/* were we able to find the cert in passed to us */
+	if (x509 == NULL)
+		{
+		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
+		goto err;
+		}
+
+	/* Lets verify */
+	if(!X509_STORE_CTX_init(ctx,cert_store,x509,cert))
+		{
+		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB);
+		goto err;
+		}
+	X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
+	i=X509_verify_cert(ctx);
+	if (i <= 0) 
+		{
+		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB);
+		X509_STORE_CTX_cleanup(ctx);
+		goto err;
+		}
+	X509_STORE_CTX_cleanup(ctx);
+
+	return PKCS7_signatureVerify(bio, p7, si, x509);
+	err:
+	return ret;
+	}
+
+int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
+								X509 *x509)
+	{
+	ASN1_OCTET_STRING *os;
+	EVP_MD_CTX mdc_tmp,*mdc;
+	int ret=0,i;
+	int md_type;
+	STACK_OF(X509_ATTRIBUTE) *sk;
+	BIO *btmp;
+	EVP_PKEY *pkey;
+
+	EVP_MD_CTX_init(&mdc_tmp);
+
+	if (!PKCS7_type_is_signed(p7) && 
+				!PKCS7_type_is_signedAndEnveloped(p7)) {
+		PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+						PKCS7_R_WRONG_PKCS7_TYPE);
+		goto err;
+	}
+
+	md_type=OBJ_obj2nid(si->digest_alg->algorithm);
+
+	btmp=bio;
+	for (;;)
+		{
+		if ((btmp == NULL) ||
+			((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL))
+			{
+			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+					PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
+			goto err;
+			}
+		BIO_get_md_ctx(btmp,&mdc);
+		if (mdc == NULL)
+			{
+			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+							ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+		if (EVP_MD_CTX_type(mdc) == md_type)
+			break;
+		/* Workaround for some broken clients that put the signature
+		 * OID instead of the digest OID in digest_alg->algorithm
+		 */
+		if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
+			break;
+		btmp=BIO_next(btmp);
+		}
+
+	/* mdc is the digest ctx that we want, unless there are attributes,
+	 * in which case the digest is the signed attributes */
+	EVP_MD_CTX_copy_ex(&mdc_tmp,mdc);
+
+	sk=si->auth_attr;
+	if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
+		{
+		unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
+                unsigned int md_len;
+		int alen;
+		ASN1_OCTET_STRING *message_digest;
+
+		EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len);
+		message_digest=PKCS7_digest_from_attributes(sk);
+		if (!message_digest)
+			{
+			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+					PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
+			goto err;
+			}
+		if ((message_digest->length != (int)md_len) ||
+			(memcmp(message_digest->data,md_dat,md_len)))
+			{
+#if 0
+{
+int ii;
+for (ii=0; ii<message_digest->length; ii++)
+	printf("%02X",message_digest->data[ii]); printf(" sent\n");
+for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
+}
+#endif
+			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+							PKCS7_R_DIGEST_FAILURE);
+			ret= -1;
+			goto err;
+			}
+
+		EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL);
+
+		alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
+						ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
+		if (alen <= 0) 
+			{
+			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,ERR_R_ASN1_LIB);
+			ret = -1;
+			goto err;
+			}
+		EVP_VerifyUpdate(&mdc_tmp, abuf, alen);
+
+		OPENSSL_free(abuf);
+		}
+
+	os=si->enc_digest;
+	pkey = X509_get_pubkey(x509);
+	if (!pkey)
+		{
+		ret = -1;
+		goto err;
+		}
+
+	i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
+	EVP_PKEY_free(pkey);
+	if (i <= 0)
+		{
+		PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+						PKCS7_R_SIGNATURE_FAILURE);
+		ret= -1;
+		goto err;
+		}
+	else
+		ret=1;
+err:
+	EVP_MD_CTX_cleanup(&mdc_tmp);
+	return(ret);
+	}
+
+PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
+	{
+	STACK_OF(PKCS7_RECIP_INFO) *rsk;
+	PKCS7_RECIP_INFO *ri;
+	int i;
+
+	i=OBJ_obj2nid(p7->type);
+	if (i != NID_pkcs7_signedAndEnveloped)
+		return NULL;
+	if (p7->d.signed_and_enveloped == NULL)
+		return NULL;
+	rsk=p7->d.signed_and_enveloped->recipientinfo;
+	if (rsk == NULL)
+		return NULL;
+	ri=sk_PKCS7_RECIP_INFO_value(rsk,0);
+	if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) return(NULL);
+	ri=sk_PKCS7_RECIP_INFO_value(rsk,idx);
+	return(ri->issuer_and_serial);
+	}
+
+ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
+	{
+	return(get_attribute(si->auth_attr,nid));
+	}
+
+ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
+	{
+	return(get_attribute(si->unauth_attr,nid));
+	}
+
+static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
+	{
+	int i;
+	X509_ATTRIBUTE *xa;
+	ASN1_OBJECT *o;
+
+	o=OBJ_nid2obj(nid);
+	if (!o || !sk) return(NULL);
+	for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
+		{
+		xa=sk_X509_ATTRIBUTE_value(sk,i);
+		if (OBJ_cmp(xa->object,o) == 0)
+			{
+			if (!xa->single && sk_ASN1_TYPE_num(xa->value.set))
+				return(sk_ASN1_TYPE_value(xa->value.set,0));
+			else
+				return(NULL);
+			}
+		}
+	return(NULL);
+	}
+
+ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
+{
+	ASN1_TYPE *astype;
+	if(!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) return NULL;
+	return astype->value.octet_string;
+}
+
+int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
+				STACK_OF(X509_ATTRIBUTE) *sk)
+	{
+	int i;
+
+	if (p7si->auth_attr != NULL)
+		sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free);
+	p7si->auth_attr=sk_X509_ATTRIBUTE_dup(sk);
+	if (p7si->auth_attr == NULL)
+		return 0;
+	for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
+		{
+		if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr,i,
+			X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i))))
+		    == NULL)
+			return(0);
+		}
+	return(1);
+	}
+
+int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk)
+	{
+	int i;
+
+	if (p7si->unauth_attr != NULL)
+		sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr,
+					   X509_ATTRIBUTE_free);
+	p7si->unauth_attr=sk_X509_ATTRIBUTE_dup(sk);
+	if (p7si->unauth_attr == NULL)
+		return 0;
+	for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
+		{
+		if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr,i,
+                        X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i))))
+		    == NULL)
+			return(0);
+		}
+	return(1);
+	}
+
+int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
+	     void *value)
+	{
+	return(add_attribute(&(p7si->auth_attr),nid,atrtype,value));
+	}
+
+int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
+	     void *value)
+	{
+	return(add_attribute(&(p7si->unauth_attr),nid,atrtype,value));
+	}
+
+static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
+			 void *value)
+	{
+	X509_ATTRIBUTE *attr=NULL;
+
+	if (*sk == NULL)
+		{
+		*sk = sk_X509_ATTRIBUTE_new_null();
+		if (*sk == NULL)
+			return 0;	
+new_attrib:
+		if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value)))
+			return 0;
+		if (!sk_X509_ATTRIBUTE_push(*sk,attr))
+			{
+			X509_ATTRIBUTE_free(attr);
+			return 0;
+			}
+		}
+	else
+		{
+		int i;
+
+		for (i=0; i<sk_X509_ATTRIBUTE_num(*sk); i++)
+			{
+			attr=sk_X509_ATTRIBUTE_value(*sk,i);
+			if (OBJ_obj2nid(attr->object) == nid)
+				{
+				X509_ATTRIBUTE_free(attr);
+				attr=X509_ATTRIBUTE_create(nid,atrtype,value);
+				if (attr == NULL)
+					return 0;
+				if (!sk_X509_ATTRIBUTE_set(*sk,i,attr))
+					{
+					X509_ATTRIBUTE_free(attr);
+					return 0;
+					}
+				goto end;
+				}
+			}
+		goto new_attrib;
+		}
+end:
+	return(1);
+	}
+
diff --git a/openssl/crypto/pkcs7/pk7_enc.c b/openssl/crypto/pkcs7/pk7_enc.c
new file mode 100644
index 0000000..acbb189
--- /dev/null
+++ b/openssl/crypto/pkcs7/pk7_enc.c
@@ -0,0 +1,76 @@
+/* crypto/pkcs7/pk7_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+
+PKCS7_in_bio(PKCS7 *p7,BIO *in);
+PKCS7_out_bio(PKCS7 *p7,BIO *out);
+
+PKCS7_add_signer(PKCS7 *p7,X509 *cert,EVP_PKEY *key);
+PKCS7_cipher(PKCS7 *p7,EVP_CIPHER *cipher);
+
+PKCS7_Init(PKCS7 *p7);
+PKCS7_Update(PKCS7 *p7);
+PKCS7_Finish(PKCS7 *p7);
+
diff --git a/openssl/crypto/pkcs7/pk7_lib.c b/openssl/crypto/pkcs7/pk7_lib.c
new file mode 100644
index 0000000..d411269
--- /dev/null
+++ b/openssl/crypto/pkcs7/pk7_lib.c
@@ -0,0 +1,665 @@
+/* crypto/pkcs7/pk7_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include "asn1_locl.h"
+
+long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
+	{
+	int nid;
+	long ret;
+
+	nid=OBJ_obj2nid(p7->type);
+
+	switch (cmd)
+		{
+	case PKCS7_OP_SET_DETACHED_SIGNATURE:
+		if (nid == NID_pkcs7_signed)
+			{
+			ret=p7->detached=(int)larg;
+			if (ret && PKCS7_type_is_data(p7->d.sign->contents))
+					{
+					ASN1_OCTET_STRING *os;
+					os=p7->d.sign->contents->d.data;
+					ASN1_OCTET_STRING_free(os);
+					p7->d.sign->contents->d.data = NULL;
+					}
+			}
+		else
+			{
+			PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
+			ret=0;
+			}
+		break;
+	case PKCS7_OP_GET_DETACHED_SIGNATURE:
+		if (nid == NID_pkcs7_signed)
+			{
+			if(!p7->d.sign  || !p7->d.sign->contents->d.ptr)
+				ret = 1;
+			else ret = 0;
+				
+			p7->detached = ret;
+			}
+		else
+			{
+			PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
+			ret=0;
+			}
+			
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_UNKNOWN_OPERATION);
+		ret=0;
+		}
+	return(ret);
+	}
+
+int PKCS7_content_new(PKCS7 *p7, int type)
+	{
+	PKCS7 *ret=NULL;
+
+	if ((ret=PKCS7_new()) == NULL) goto err;
+	if (!PKCS7_set_type(ret,type)) goto err;
+	if (!PKCS7_set_content(p7,ret)) goto err;
+
+	return(1);
+err:
+	if (ret != NULL) PKCS7_free(ret);
+	return(0);
+	}
+
+int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
+	{
+	int i;
+
+	i=OBJ_obj2nid(p7->type);
+	switch (i)
+		{
+	case NID_pkcs7_signed:
+		if (p7->d.sign->contents != NULL)
+			PKCS7_free(p7->d.sign->contents);
+		p7->d.sign->contents=p7_data;
+		break;
+	case NID_pkcs7_digest:
+		if (p7->d.digest->contents != NULL)
+			PKCS7_free(p7->d.digest->contents);
+		p7->d.digest->contents=p7_data;
+		break;
+	case NID_pkcs7_data:
+	case NID_pkcs7_enveloped:
+	case NID_pkcs7_signedAndEnveloped:
+	case NID_pkcs7_encrypted:
+	default:
+		PKCS7err(PKCS7_F_PKCS7_SET_CONTENT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+		goto err;
+		}
+	return(1);
+err:
+	return(0);
+	}
+
+int PKCS7_set_type(PKCS7 *p7, int type)
+	{
+	ASN1_OBJECT *obj;
+
+	/*PKCS7_content_free(p7);*/
+	obj=OBJ_nid2obj(type); /* will not fail */
+
+	switch (type)
+		{
+	case NID_pkcs7_signed:
+		p7->type=obj;
+		if ((p7->d.sign=PKCS7_SIGNED_new()) == NULL)
+			goto err;
+		if (!ASN1_INTEGER_set(p7->d.sign->version,1))
+			{
+			PKCS7_SIGNED_free(p7->d.sign);
+			p7->d.sign=NULL;
+			goto err;
+			}
+		break;
+	case NID_pkcs7_data:
+		p7->type=obj;
+		if ((p7->d.data=M_ASN1_OCTET_STRING_new()) == NULL)
+			goto err;
+		break;
+	case NID_pkcs7_signedAndEnveloped:
+		p7->type=obj;
+		if ((p7->d.signed_and_enveloped=PKCS7_SIGN_ENVELOPE_new())
+			== NULL) goto err;
+		ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1);
+		if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1))
+			goto err;
+		p7->d.signed_and_enveloped->enc_data->content_type
+						= OBJ_nid2obj(NID_pkcs7_data);
+		break;
+	case NID_pkcs7_enveloped:
+		p7->type=obj;
+		if ((p7->d.enveloped=PKCS7_ENVELOPE_new())
+			== NULL) goto err;
+		if (!ASN1_INTEGER_set(p7->d.enveloped->version,0))
+			goto err;
+		p7->d.enveloped->enc_data->content_type
+						= OBJ_nid2obj(NID_pkcs7_data);
+		break;
+	case NID_pkcs7_encrypted:
+		p7->type=obj;
+		if ((p7->d.encrypted=PKCS7_ENCRYPT_new())
+			== NULL) goto err;
+		if (!ASN1_INTEGER_set(p7->d.encrypted->version,0))
+			goto err;
+		p7->d.encrypted->enc_data->content_type
+						= OBJ_nid2obj(NID_pkcs7_data);
+		break;
+
+	case NID_pkcs7_digest:
+		p7->type=obj;
+		if ((p7->d.digest=PKCS7_DIGEST_new())
+			== NULL) goto err;
+		if (!ASN1_INTEGER_set(p7->d.digest->version,0))
+			goto err;
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_SET_TYPE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+		goto err;
+		}
+	return(1);
+err:
+	return(0);
+	}
+
+int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other)
+	{
+	p7->type = OBJ_nid2obj(type);
+	p7->d.other = other;
+	return 1;
+	}
+
+int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
+	{
+	int i,j,nid;
+	X509_ALGOR *alg;
+	STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
+	STACK_OF(X509_ALGOR) *md_sk;
+
+	i=OBJ_obj2nid(p7->type);
+	switch (i)
+		{
+	case NID_pkcs7_signed:
+		signer_sk=	p7->d.sign->signer_info;
+		md_sk=		p7->d.sign->md_algs;
+		break;
+	case NID_pkcs7_signedAndEnveloped:
+		signer_sk=	p7->d.signed_and_enveloped->signer_info;
+		md_sk=		p7->d.signed_and_enveloped->md_algs;
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,PKCS7_R_WRONG_CONTENT_TYPE);
+		return(0);
+		}
+
+	nid=OBJ_obj2nid(psi->digest_alg->algorithm);
+
+	/* If the digest is not currently listed, add it */
+	j=0;
+	for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
+		{
+		alg=sk_X509_ALGOR_value(md_sk,i);
+		if (OBJ_obj2nid(alg->algorithm) == nid)
+			{
+			j=1;
+			break;
+			}
+		}
+	if (!j) /* we need to add another algorithm */
+		{
+		if(!(alg=X509_ALGOR_new())
+			|| !(alg->parameter = ASN1_TYPE_new()))
+			{
+			X509_ALGOR_free(alg);
+			PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,ERR_R_MALLOC_FAILURE);
+			return(0);
+			}
+		alg->algorithm=OBJ_nid2obj(nid);
+		alg->parameter->type = V_ASN1_NULL;
+		if (!sk_X509_ALGOR_push(md_sk,alg))
+			{
+			X509_ALGOR_free(alg);
+			return 0;
+			}
+		}
+
+	if (!sk_PKCS7_SIGNER_INFO_push(signer_sk,psi))
+		return 0;
+	return(1);
+	}
+
+int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
+	{
+	int i;
+	STACK_OF(X509) **sk;
+
+	i=OBJ_obj2nid(p7->type);
+	switch (i)
+		{
+	case NID_pkcs7_signed:
+		sk= &(p7->d.sign->cert);
+		break;
+	case NID_pkcs7_signedAndEnveloped:
+		sk= &(p7->d.signed_and_enveloped->cert);
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,PKCS7_R_WRONG_CONTENT_TYPE);
+		return(0);
+		}
+
+	if (*sk == NULL)
+		*sk=sk_X509_new_null();
+	if (*sk == NULL)
+		{
+		PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
+	if (!sk_X509_push(*sk,x509))
+		{
+		X509_free(x509);
+		return 0;
+		}
+	return(1);
+	}
+
+int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
+	{
+	int i;
+	STACK_OF(X509_CRL) **sk;
+
+	i=OBJ_obj2nid(p7->type);
+	switch (i)
+		{
+	case NID_pkcs7_signed:
+		sk= &(p7->d.sign->crl);
+		break;
+	case NID_pkcs7_signedAndEnveloped:
+		sk= &(p7->d.signed_and_enveloped->crl);
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_ADD_CRL,PKCS7_R_WRONG_CONTENT_TYPE);
+		return(0);
+		}
+
+	if (*sk == NULL)
+		*sk=sk_X509_CRL_new_null();
+	if (*sk == NULL)
+		{
+		PKCS7err(PKCS7_F_PKCS7_ADD_CRL,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+
+	CRYPTO_add(&crl->references,1,CRYPTO_LOCK_X509_CRL);
+	if (!sk_X509_CRL_push(*sk,crl))
+		{
+		X509_CRL_free(crl);
+		return 0;
+		}
+	return(1);
+	}
+
+int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
+	     const EVP_MD *dgst)
+	{
+	int ret;
+
+	/* We now need to add another PKCS7_SIGNER_INFO entry */
+	if (!ASN1_INTEGER_set(p7i->version,1))
+		goto err;
+	if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
+			X509_get_issuer_name(x509)))
+		goto err;
+
+	/* because ASN1_INTEGER_set is used to set a 'long' we will do
+	 * things the ugly way. */
+	M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
+	if (!(p7i->issuer_and_serial->serial=
+			M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
+		goto err;
+
+	/* lets keep the pkey around for a while */
+	CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
+	p7i->pkey=pkey;
+
+	/* Set the algorithms */
+
+	X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)),
+				V_ASN1_NULL, NULL);
+
+	if (pkey->ameth && pkey->ameth->pkey_ctrl)
+		{
+		ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN,
+						0, p7i);
+		if (ret > 0)
+			return 1;
+		if (ret != -2)
+			{
+			PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
+					PKCS7_R_SIGNING_CTRL_FAILURE);
+			return 0;
+			}
+		}
+	PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
+			PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+err:
+	return 0;
+	}
+
+PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
+	     const EVP_MD *dgst)
+	{
+	PKCS7_SIGNER_INFO *si = NULL;
+
+	if (dgst == NULL)
+		{
+		int def_nid;
+		if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
+			goto err;
+		dgst = EVP_get_digestbynid(def_nid);
+		if (dgst == NULL)
+			{
+			PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE,
+						PKCS7_R_NO_DEFAULT_DIGEST);
+			goto err;
+			}
+		}
+
+	if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err;
+	if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err;
+	if (!PKCS7_add_signer(p7,si)) goto err;
+	return(si);
+err:
+	if (si)
+		PKCS7_SIGNER_INFO_free(si);
+	return(NULL);
+	}
+
+int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
+	{
+	if (PKCS7_type_is_digest(p7))
+		{
+		if(!(p7->d.digest->md->parameter = ASN1_TYPE_new()))
+			{
+			PKCS7err(PKCS7_F_PKCS7_SET_DIGEST,ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		p7->d.digest->md->parameter->type = V_ASN1_NULL;
+		p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
+		return 1;
+		}
+		
+	PKCS7err(PKCS7_F_PKCS7_SET_DIGEST,PKCS7_R_WRONG_CONTENT_TYPE);
+	return 1;
+	}
+
+STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
+	{
+	if (PKCS7_type_is_signed(p7))
+		{
+		return(p7->d.sign->signer_info);
+		}
+	else if (PKCS7_type_is_signedAndEnveloped(p7))
+		{
+		return(p7->d.signed_and_enveloped->signer_info);
+		}
+	else
+		return(NULL);
+	}
+
+void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
+					X509_ALGOR **pdig, X509_ALGOR **psig)
+	{
+	if (pk)
+		*pk = si->pkey;
+	if (pdig)
+		*pdig = si->digest_alg;
+	if (psig)
+		*psig = si->digest_enc_alg;
+	}
+
+void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
+	{
+	if (penc)
+		*penc = ri->key_enc_algor;
+	}
+
+PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
+	{
+	PKCS7_RECIP_INFO *ri;
+
+	if ((ri=PKCS7_RECIP_INFO_new()) == NULL) goto err;
+	if (!PKCS7_RECIP_INFO_set(ri,x509)) goto err;
+	if (!PKCS7_add_recipient_info(p7,ri)) goto err;
+	return ri;
+err:
+	if (ri)
+		PKCS7_RECIP_INFO_free(ri);
+	return NULL;
+	}
+
+int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
+	{
+	int i;
+	STACK_OF(PKCS7_RECIP_INFO) *sk;
+
+	i=OBJ_obj2nid(p7->type);
+	switch (i)
+		{
+	case NID_pkcs7_signedAndEnveloped:
+		sk=	p7->d.signed_and_enveloped->recipientinfo;
+		break;
+	case NID_pkcs7_enveloped:
+		sk=	p7->d.enveloped->recipientinfo;
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,PKCS7_R_WRONG_CONTENT_TYPE);
+		return(0);
+		}
+
+	if (!sk_PKCS7_RECIP_INFO_push(sk,ri))
+		return 0;
+	return(1);
+	}
+
+int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
+	{
+	int ret;
+	EVP_PKEY *pkey = NULL;
+	if (!ASN1_INTEGER_set(p7i->version,0))
+		return 0;
+	if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
+		X509_get_issuer_name(x509)))
+		return 0;
+
+	M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
+	if (!(p7i->issuer_and_serial->serial=
+		M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
+		return 0;
+
+	pkey = X509_get_pubkey(x509);
+
+	if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl)
+		{
+		PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
+			PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+		goto err;
+		}
+
+	ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT,
+						0, p7i);
+	if (ret == -2)
+		{
+		PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
+			PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+		goto err;
+		}
+	if (ret <= 0)
+		{
+		PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
+				PKCS7_R_ENCRYPTION_CTRL_FAILURE);
+		goto err;
+		}
+
+	EVP_PKEY_free(pkey);
+
+	CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
+	p7i->cert=x509;
+
+	return 1;
+
+	err:
+	if (pkey)
+		EVP_PKEY_free(pkey);
+	return 0;
+	}
+
+X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
+	{
+	if (PKCS7_type_is_signed(p7))
+		return(X509_find_by_issuer_and_serial(p7->d.sign->cert,
+			si->issuer_and_serial->issuer,
+			si->issuer_and_serial->serial));
+	else
+		return(NULL);
+	}
+
+int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
+	{
+	int i;
+	PKCS7_ENC_CONTENT *ec;
+
+	i=OBJ_obj2nid(p7->type);
+	switch (i)
+		{
+	case NID_pkcs7_signedAndEnveloped:
+		ec=p7->d.signed_and_enveloped->enc_data;
+		break;
+	case NID_pkcs7_enveloped:
+		ec=p7->d.enveloped->enc_data;
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_WRONG_CONTENT_TYPE);
+		return(0);
+		}
+
+	/* Check cipher OID exists and has data in it*/
+	i = EVP_CIPHER_type(cipher);
+	if(i == NID_undef) {
+		PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
+		return(0);
+	}
+
+	ec->cipher = cipher;
+	return 1;
+	}
+
+int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
+	{
+	ASN1_OCTET_STRING *os = NULL;
+
+	switch (OBJ_obj2nid(p7->type))
+		{
+		case NID_pkcs7_data:
+		os = p7->d.data;
+		break;
+
+		case NID_pkcs7_signedAndEnveloped:
+		os = p7->d.signed_and_enveloped->enc_data->enc_data;
+		if (os == NULL)
+			{
+			os=M_ASN1_OCTET_STRING_new();
+			p7->d.signed_and_enveloped->enc_data->enc_data=os;
+			}
+		break;
+
+		case NID_pkcs7_enveloped:
+		os = p7->d.enveloped->enc_data->enc_data;
+		if (os == NULL)
+			{
+			os=M_ASN1_OCTET_STRING_new();
+			p7->d.enveloped->enc_data->enc_data=os;
+			}
+		break;
+
+		case NID_pkcs7_signed:
+		os=p7->d.sign->contents->d.data;
+		break;
+
+		default:
+		os = NULL;
+		break;
+		}
+	
+	if (os == NULL)
+		return 0;
+
+	os->flags |= ASN1_STRING_FLAG_NDEF;
+	*boundary = &os->data;
+
+	return 1;
+	}
diff --git a/openssl/crypto/pkcs7/pk7_mime.c b/openssl/crypto/pkcs7/pk7_mime.c
new file mode 100644
index 0000000..938f79a
--- /dev/null
+++ b/openssl/crypto/pkcs7/pk7_mime.c
@@ -0,0 +1,97 @@
+/* pk7_mime.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+
+/* PKCS#7 wrappers round generalised stream and MIME routines */
+
+int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
+	{
+	return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)p7, in, flags,
+					ASN1_ITEM_rptr(PKCS7));
+	}
+
+int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
+	{
+	return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *) p7, in, flags,
+						"PKCS7",
+						ASN1_ITEM_rptr(PKCS7));
+	}
+
+int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
+	{
+	STACK_OF(X509_ALGOR) *mdalgs;
+	int ctype_nid = OBJ_obj2nid(p7->type);
+	if (ctype_nid == NID_pkcs7_signed)
+		mdalgs = p7->d.sign->md_algs;
+	else
+		mdalgs = NULL;
+
+	flags ^= SMIME_OLDMIME;
+
+
+	return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags,
+					ctype_nid, NID_undef, mdalgs,
+					ASN1_ITEM_rptr(PKCS7));	
+	}
+
+PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont)
+	{
+	return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7));
+	}
diff --git a/openssl/crypto/pkcs7/pk7_smime.c b/openssl/crypto/pkcs7/pk7_smime.c
new file mode 100644
index 0000000..86742d0
--- /dev/null
+++ b/openssl/crypto/pkcs7/pk7_smime.c
@@ -0,0 +1,587 @@
+/* pk7_smime.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Simple PKCS#7 processing functions */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
+
+PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
+		  BIO *data, int flags)
+{
+	PKCS7 *p7;
+	int i;
+
+	if(!(p7 = PKCS7_new()))
+		{
+		PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+
+	if (!PKCS7_set_type(p7, NID_pkcs7_signed))
+		goto err;
+
+	if (!PKCS7_content_new(p7, NID_pkcs7_data))
+		goto err;
+
+    	if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags))
+		{
+		PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNER_ERROR);
+		goto err;
+		}
+
+	if(!(flags & PKCS7_NOCERTS))
+		{
+		for(i = 0; i < sk_X509_num(certs); i++)
+			{
+			if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
+				goto err;
+			}
+		}
+
+	if(flags & PKCS7_DETACHED)
+		PKCS7_set_detached(p7, 1);
+
+	if (flags & (PKCS7_STREAM|PKCS7_PARTIAL))
+		return p7;
+
+	if (PKCS7_final(p7, data, flags))
+		return p7;
+
+	err:
+	PKCS7_free(p7);
+	return NULL;
+}
+
+int PKCS7_final(PKCS7 *p7, BIO *data, int flags)
+	{
+	BIO *p7bio;
+	int ret = 0;
+	if (!(p7bio = PKCS7_dataInit(p7, NULL)))
+		{
+		PKCS7err(PKCS7_F_PKCS7_FINAL,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+
+	SMIME_crlf_copy(data, p7bio, flags);
+
+	(void)BIO_flush(p7bio);
+
+
+        if (!PKCS7_dataFinal(p7,p7bio))
+		{
+		PKCS7err(PKCS7_F_PKCS7_FINAL,PKCS7_R_PKCS7_DATASIGN);
+		goto err;
+		}
+
+	ret = 1;
+
+	err:
+	BIO_free_all(p7bio);
+
+	return ret;
+
+	}
+
+/* Check to see if a cipher exists and if so add S/MIME capabilities */
+
+static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
+	{
+	if (EVP_get_cipherbynid(nid))
+		return PKCS7_simple_smimecap(sk, nid, arg);
+	return 1;
+	}
+
+static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
+	{
+	if (EVP_get_digestbynid(nid))
+		return PKCS7_simple_smimecap(sk, nid, arg);
+	return 1;
+	}
+
+PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert,
+					EVP_PKEY *pkey, const EVP_MD *md,
+					int flags)
+	{
+	PKCS7_SIGNER_INFO *si = NULL;
+	STACK_OF(X509_ALGOR) *smcap = NULL;
+	if(!X509_check_private_key(signcert, pkey))
+		{
+		PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
+			PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+                return NULL;
+		}
+
+    	if (!(si = PKCS7_add_signature(p7,signcert,pkey, md)))
+		{
+		PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
+				PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
+		return NULL;
+		}
+
+	if(!(flags & PKCS7_NOCERTS))
+		{
+		if (!PKCS7_add_certificate(p7, signcert))
+			goto err;
+		}
+
+	if(!(flags & PKCS7_NOATTR))
+		{
+		if (!PKCS7_add_attrib_content_type(si, NULL))
+			goto err;
+		/* Add SMIMECapabilities */
+		if(!(flags & PKCS7_NOSMIMECAP))
+			{
+			if(!(smcap = sk_X509_ALGOR_new_null()))
+				{
+				PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
+					ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
+			|| !add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
+			|| !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
+				|| !add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
+				|| !add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
+			|| !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
+				|| !add_cipher_smcap(smcap, NID_rc2_cbc, 128)
+				|| !add_cipher_smcap(smcap, NID_rc2_cbc, 64)
+				|| !add_cipher_smcap(smcap, NID_des_cbc, -1)
+				|| !add_cipher_smcap(smcap, NID_rc2_cbc, 40)
+				|| !PKCS7_add_attrib_smimecap (si, smcap))
+				goto err;
+			sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
+			smcap = NULL;
+			}
+		if (flags & PKCS7_REUSE_DIGEST)
+			{
+			if (!pkcs7_copy_existing_digest(p7, si))
+				goto err;
+			if (!(flags & PKCS7_PARTIAL) &&
+					!PKCS7_SIGNER_INFO_sign(si))
+				goto err;
+			}
+		}
+	return si;
+	err:
+	if (smcap)
+		sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
+	return NULL;
+	}
+
+/* Search for a digest matching SignerInfo digest type and if found
+ * copy across.
+ */
+
+static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
+	{
+	int i;
+	STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
+	PKCS7_SIGNER_INFO *sitmp;
+	ASN1_OCTET_STRING *osdig = NULL;
+	sinfos = PKCS7_get_signer_info(p7);
+	for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
+		{
+		sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
+		if (si == sitmp)
+			break;
+		if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0)
+			continue;
+		if (!OBJ_cmp(si->digest_alg->algorithm,
+				sitmp->digest_alg->algorithm))
+			{
+			osdig = PKCS7_digest_from_attributes(sitmp->auth_attr);
+			break;
+			}
+
+		}
+
+	if (osdig)
+		return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length);
+
+	PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST,
+			PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND);
+	return 0;
+	}
+
+int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
+					BIO *indata, BIO *out, int flags)
+{
+	STACK_OF(X509) *signers;
+	X509 *signer;
+	STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
+	PKCS7_SIGNER_INFO *si;
+	X509_STORE_CTX cert_ctx;
+	char buf[4096];
+	int i, j=0, k, ret = 0;
+	BIO *p7bio;
+	BIO *tmpin, *tmpout;
+
+	if(!p7) {
+		PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_INVALID_NULL_POINTER);
+		return 0;
+	}
+
+	if(!PKCS7_type_is_signed(p7)) {
+		PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_WRONG_CONTENT_TYPE);
+		return 0;
+	}
+
+	/* Check for no data and no content: no data to verify signature */
+	if(PKCS7_get_detached(p7) && !indata) {
+		PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_CONTENT);
+		return 0;
+	}
+#if 0
+	/* NB: this test commented out because some versions of Netscape
+	 * illegally include zero length content when signing data.
+	 */
+
+	/* Check for data and content: two sets of data */
+	if(!PKCS7_get_detached(p7) && indata) {
+				PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_CONTENT_AND_DATA_PRESENT);
+		return 0;
+	}
+#endif
+
+	sinfos = PKCS7_get_signer_info(p7);
+
+	if(!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) {
+		PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_SIGNATURES_ON_DATA);
+		return 0;
+	}
+
+
+	signers = PKCS7_get0_signers(p7, certs, flags);
+
+	if(!signers) return 0;
+
+	/* Now verify the certificates */
+
+	if (!(flags & PKCS7_NOVERIFY)) for (k = 0; k < sk_X509_num(signers); k++) {
+		signer = sk_X509_value (signers, k);
+		if (!(flags & PKCS7_NOCHAIN)) {
+			if(!X509_STORE_CTX_init(&cert_ctx, store, signer,
+							p7->d.sign->cert))
+				{
+				PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_X509_LIB);
+				sk_X509_free(signers);
+				return 0;
+				}
+			X509_STORE_CTX_set_default(&cert_ctx, "smime_sign");
+		} else if(!X509_STORE_CTX_init (&cert_ctx, store, signer, NULL)) {
+			PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_X509_LIB);
+			sk_X509_free(signers);
+			return 0;
+		}
+		if (!(flags & PKCS7_NOCRL))
+			X509_STORE_CTX_set0_crls(&cert_ctx, p7->d.sign->crl);
+		i = X509_verify_cert(&cert_ctx);
+		if (i <= 0) j = X509_STORE_CTX_get_error(&cert_ctx);
+		X509_STORE_CTX_cleanup(&cert_ctx);
+		if (i <= 0) {
+			PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_CERTIFICATE_VERIFY_ERROR);
+			ERR_add_error_data(2, "Verify error:",
+					 X509_verify_cert_error_string(j));
+			sk_X509_free(signers);
+			return 0;
+		}
+		/* Check for revocation status here */
+	}
+
+	/* Performance optimization: if the content is a memory BIO then
+	 * store its contents in a temporary read only memory BIO. This
+	 * avoids potentially large numbers of slow copies of data which will
+	 * occur when reading from a read write memory BIO when signatures
+	 * are calculated.
+	 */
+
+	if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM))
+		{
+		char *ptr;
+		long len;
+		len = BIO_get_mem_data(indata, &ptr);
+		tmpin = BIO_new_mem_buf(ptr, len);
+		if (tmpin == NULL)
+			{
+			PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		}
+	else
+		tmpin = indata;
+		
+
+	if (!(p7bio=PKCS7_dataInit(p7,tmpin)))
+		goto err;
+
+	if(flags & PKCS7_TEXT) {
+		if(!(tmpout = BIO_new(BIO_s_mem()))) {
+			PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		BIO_set_mem_eof_return(tmpout, 0);
+	} else tmpout = out;
+
+	/* We now have to 'read' from p7bio to calculate digests etc. */
+	for (;;)
+	{
+		i=BIO_read(p7bio,buf,sizeof(buf));
+		if (i <= 0) break;
+		if (tmpout) BIO_write(tmpout, buf, i);
+	}
+
+	if(flags & PKCS7_TEXT) {
+		if(!SMIME_text(tmpout, out)) {
+			PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_SMIME_TEXT_ERROR);
+			BIO_free(tmpout);
+			goto err;
+		}
+		BIO_free(tmpout);
+	}
+
+	/* Now Verify All Signatures */
+	if (!(flags & PKCS7_NOSIGS))
+	    for (i=0; i<sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
+		{
+		si=sk_PKCS7_SIGNER_INFO_value(sinfos,i);
+		signer = sk_X509_value (signers, i);
+		j=PKCS7_signatureVerify(p7bio,p7,si, signer);
+		if (j <= 0) {
+			PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_SIGNATURE_FAILURE);
+			goto err;
+		}
+	}
+
+	ret = 1;
+
+	err:
+	
+	if (tmpin == indata)
+		{
+		if (indata) BIO_pop(p7bio);
+		}
+	BIO_free_all(p7bio);
+
+	sk_X509_free(signers);
+
+	return ret;
+}
+
+STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags)
+{
+	STACK_OF(X509) *signers;
+	STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
+	PKCS7_SIGNER_INFO *si;
+	PKCS7_ISSUER_AND_SERIAL *ias;
+	X509 *signer;
+	int i;
+
+	if(!p7) {
+		PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_INVALID_NULL_POINTER);
+		return NULL;
+	}
+
+	if(!PKCS7_type_is_signed(p7)) {
+		PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_WRONG_CONTENT_TYPE);
+		return NULL;
+	}
+
+	/* Collect all the signers together */
+
+	sinfos = PKCS7_get_signer_info(p7);
+
+	if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
+		PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS);
+		return 0;
+	}
+
+	if(!(signers = sk_X509_new_null())) {
+		PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
+	{
+	    si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
+	    ias = si->issuer_and_serial;
+	    signer = NULL;
+		/* If any certificates passed they take priority */
+	    if (certs) signer = X509_find_by_issuer_and_serial (certs,
+					 	ias->issuer, ias->serial);
+	    if (!signer && !(flags & PKCS7_NOINTERN)
+			&& p7->d.sign->cert) signer =
+		              X509_find_by_issuer_and_serial (p7->d.sign->cert,
+					      	ias->issuer, ias->serial);
+	    if (!signer) {
+			PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND);
+			sk_X509_free(signers);
+			return 0;
+	    }
+
+	    if (!sk_X509_push(signers, signer)) {
+		sk_X509_free(signers);
+		return NULL;
+	    }
+	}
+	return signers;
+}
+
+
+/* Build a complete PKCS#7 enveloped data */
+
+PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
+								int flags)
+{
+	PKCS7 *p7;
+	BIO *p7bio = NULL;
+	int i;
+	X509 *x509;
+	if(!(p7 = PKCS7_new())) {
+		PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	if (!PKCS7_set_type(p7, NID_pkcs7_enveloped))
+		goto err;
+	if (!PKCS7_set_cipher(p7, cipher)) {
+		PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER);
+		goto err;
+	}
+
+	for(i = 0; i < sk_X509_num(certs); i++) {
+		x509 = sk_X509_value(certs, i);
+		if(!PKCS7_add_recipient(p7, x509)) {
+			PKCS7err(PKCS7_F_PKCS7_ENCRYPT,
+					PKCS7_R_ERROR_ADDING_RECIPIENT);
+			goto err;
+		}
+	}
+
+	if (flags & PKCS7_STREAM)
+		return p7;
+
+	if (PKCS7_final(p7, in, flags))
+		return p7;
+
+	err:
+
+	BIO_free_all(p7bio);
+	PKCS7_free(p7);
+	return NULL;
+
+}
+
+int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
+{
+	BIO *tmpmem;
+	int ret, i;
+	char buf[4096];
+
+	if(!p7) {
+		PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_INVALID_NULL_POINTER);
+		return 0;
+	}
+
+	if(!PKCS7_type_is_enveloped(p7)) {
+		PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_WRONG_CONTENT_TYPE);
+		return 0;
+	}
+
+	if(cert && !X509_check_private_key(cert, pkey)) {
+		PKCS7err(PKCS7_F_PKCS7_DECRYPT,
+				PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+		return 0;
+	}
+
+	if(!(tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert))) {
+		PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR);
+		return 0;
+	}
+
+	if (flags & PKCS7_TEXT) {
+		BIO *tmpbuf, *bread;
+		/* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */
+		if(!(tmpbuf = BIO_new(BIO_f_buffer()))) {
+			PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
+			BIO_free_all(tmpmem);
+			return 0;
+		}
+		if(!(bread = BIO_push(tmpbuf, tmpmem))) {
+			PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
+			BIO_free_all(tmpbuf);
+			BIO_free_all(tmpmem);
+			return 0;
+		}
+		ret = SMIME_text(bread, data);
+		BIO_free_all(bread);
+		return ret;
+	} else {
+		for(;;) {
+			i = BIO_read(tmpmem, buf, sizeof(buf));
+			if(i <= 0) break;
+			BIO_write(data, buf, i);
+		}
+		BIO_free_all(tmpmem);
+		return 1;
+	}
+}
diff --git a/openssl/crypto/pkcs7/pkcs7.h b/openssl/crypto/pkcs7/pkcs7.h
new file mode 100644
index 0000000..e4d4431
--- /dev/null
+++ b/openssl/crypto/pkcs7/pkcs7.h
@@ -0,0 +1,499 @@
+/* crypto/pkcs7/pkcs7.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_PKCS7_H
+#define HEADER_PKCS7_H
+
+#include <openssl/asn1.h>
+#include <openssl/bio.h>
+#include <openssl/e_os2.h>
+
+#include <openssl/symhacks.h>
+#include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_SYS_WIN32
+/* Under Win32 thes are defined in wincrypt.h */
+#undef PKCS7_ISSUER_AND_SERIAL
+#undef PKCS7_SIGNER_INFO
+#endif
+
+/*
+Encryption_ID		DES-CBC
+Digest_ID		MD5
+Digest_Encryption_ID	rsaEncryption
+Key_Encryption_ID	rsaEncryption
+*/
+
+typedef struct pkcs7_issuer_and_serial_st
+	{
+	X509_NAME *issuer;
+	ASN1_INTEGER *serial;
+	} PKCS7_ISSUER_AND_SERIAL;
+
+typedef struct pkcs7_signer_info_st
+	{
+	ASN1_INTEGER 			*version;	/* version 1 */
+	PKCS7_ISSUER_AND_SERIAL		*issuer_and_serial;
+	X509_ALGOR			*digest_alg;
+	STACK_OF(X509_ATTRIBUTE)	*auth_attr;	/* [ 0 ] */
+	X509_ALGOR			*digest_enc_alg;
+	ASN1_OCTET_STRING		*enc_digest;
+	STACK_OF(X509_ATTRIBUTE)	*unauth_attr;	/* [ 1 ] */
+
+	/* The private key to sign with */
+	EVP_PKEY			*pkey;
+	} PKCS7_SIGNER_INFO;
+
+DECLARE_STACK_OF(PKCS7_SIGNER_INFO)
+DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO)
+
+typedef struct pkcs7_recip_info_st
+	{
+	ASN1_INTEGER			*version;	/* version 0 */
+	PKCS7_ISSUER_AND_SERIAL		*issuer_and_serial;
+	X509_ALGOR			*key_enc_algor;
+	ASN1_OCTET_STRING		*enc_key;
+	X509				*cert; /* get the pub-key from this */
+	} PKCS7_RECIP_INFO;
+
+DECLARE_STACK_OF(PKCS7_RECIP_INFO)
+DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO)
+
+typedef struct pkcs7_signed_st
+	{
+	ASN1_INTEGER			*version;	/* version 1 */
+	STACK_OF(X509_ALGOR)		*md_algs;	/* md used */
+	STACK_OF(X509)			*cert;		/* [ 0 ] */
+	STACK_OF(X509_CRL)		*crl;		/* [ 1 ] */
+	STACK_OF(PKCS7_SIGNER_INFO)	*signer_info;
+
+	struct pkcs7_st			*contents;
+	} PKCS7_SIGNED;
+/* The above structure is very very similar to PKCS7_SIGN_ENVELOPE.
+ * How about merging the two */
+
+typedef struct pkcs7_enc_content_st
+	{
+	ASN1_OBJECT			*content_type;
+	X509_ALGOR			*algorithm;
+	ASN1_OCTET_STRING		*enc_data;	/* [ 0 ] */
+	const EVP_CIPHER		*cipher;
+	} PKCS7_ENC_CONTENT;
+
+typedef struct pkcs7_enveloped_st
+	{
+	ASN1_INTEGER			*version;	/* version 0 */
+	STACK_OF(PKCS7_RECIP_INFO)	*recipientinfo;
+	PKCS7_ENC_CONTENT		*enc_data;
+	} PKCS7_ENVELOPE;
+
+typedef struct pkcs7_signedandenveloped_st
+	{
+	ASN1_INTEGER			*version;	/* version 1 */
+	STACK_OF(X509_ALGOR)		*md_algs;	/* md used */
+	STACK_OF(X509)			*cert;		/* [ 0 ] */
+	STACK_OF(X509_CRL)		*crl;		/* [ 1 ] */
+	STACK_OF(PKCS7_SIGNER_INFO)	*signer_info;
+
+	PKCS7_ENC_CONTENT		*enc_data;
+	STACK_OF(PKCS7_RECIP_INFO)	*recipientinfo;
+	} PKCS7_SIGN_ENVELOPE;
+
+typedef struct pkcs7_digest_st
+	{
+	ASN1_INTEGER			*version;	/* version 0 */
+	X509_ALGOR			*md;		/* md used */
+	struct pkcs7_st 		*contents;
+	ASN1_OCTET_STRING		*digest;
+	} PKCS7_DIGEST;
+
+typedef struct pkcs7_encrypted_st
+	{
+	ASN1_INTEGER			*version;	/* version 0 */
+	PKCS7_ENC_CONTENT		*enc_data;
+	} PKCS7_ENCRYPT;
+
+typedef struct pkcs7_st
+	{
+	/* The following is non NULL if it contains ASN1 encoding of
+	 * this structure */
+	unsigned char *asn1;
+	long length;
+
+#define PKCS7_S_HEADER	0
+#define PKCS7_S_BODY	1
+#define PKCS7_S_TAIL	2
+	int state; /* used during processing */
+
+	int detached;
+
+	ASN1_OBJECT *type;
+	/* content as defined by the type */
+	/* all encryption/message digests are applied to the 'contents',
+	 * leaving out the 'type' field. */
+	union	{
+		char *ptr;
+
+		/* NID_pkcs7_data */
+		ASN1_OCTET_STRING *data;
+
+		/* NID_pkcs7_signed */
+		PKCS7_SIGNED *sign;
+
+		/* NID_pkcs7_enveloped */
+		PKCS7_ENVELOPE *enveloped;
+
+		/* NID_pkcs7_signedAndEnveloped */
+		PKCS7_SIGN_ENVELOPE *signed_and_enveloped;
+
+		/* NID_pkcs7_digest */
+		PKCS7_DIGEST *digest;
+
+		/* NID_pkcs7_encrypted */
+		PKCS7_ENCRYPT *encrypted;
+
+		/* Anything else */
+		ASN1_TYPE *other;
+		} d;
+	} PKCS7;
+
+DECLARE_STACK_OF(PKCS7)
+DECLARE_ASN1_SET_OF(PKCS7)
+DECLARE_PKCS12_STACK_OF(PKCS7)
+
+#define PKCS7_OP_SET_DETACHED_SIGNATURE	1
+#define PKCS7_OP_GET_DETACHED_SIGNATURE	2
+
+#define PKCS7_get_signed_attributes(si)	((si)->auth_attr)
+#define PKCS7_get_attributes(si)	((si)->unauth_attr)
+
+#define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed)
+#define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
+#define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped)
+#define PKCS7_type_is_signedAndEnveloped(a) \
+		(OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
+#define PKCS7_type_is_data(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
+#define PKCS7_type_is_digest(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
+#define PKCS7_type_is_encrypted(a) \
+		(OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
+
+#define PKCS7_type_is_digest(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
+
+#define PKCS7_set_detached(p,v) \
+		PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL)
+#define PKCS7_get_detached(p) \
+		PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL)
+
+#define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7))
+
+/* S/MIME related flags */
+
+#define PKCS7_TEXT		0x1
+#define PKCS7_NOCERTS		0x2
+#define PKCS7_NOSIGS		0x4
+#define PKCS7_NOCHAIN		0x8
+#define PKCS7_NOINTERN		0x10
+#define PKCS7_NOVERIFY		0x20
+#define PKCS7_DETACHED		0x40
+#define PKCS7_BINARY		0x80
+#define PKCS7_NOATTR		0x100
+#define	PKCS7_NOSMIMECAP	0x200
+#define PKCS7_NOOLDMIMETYPE	0x400
+#define PKCS7_CRLFEOL		0x800
+#define PKCS7_STREAM		0x1000
+#define PKCS7_NOCRL		0x2000
+#define PKCS7_PARTIAL		0x4000
+#define PKCS7_REUSE_DIGEST	0x8000
+
+/* Flags: for compatibility with older code */
+
+#define SMIME_TEXT	PKCS7_TEXT
+#define SMIME_NOCERTS	PKCS7_NOCERTS
+#define SMIME_NOSIGS	PKCS7_NOSIGS
+#define SMIME_NOCHAIN	PKCS7_NOCHAIN
+#define SMIME_NOINTERN	PKCS7_NOINTERN
+#define SMIME_NOVERIFY	PKCS7_NOVERIFY
+#define SMIME_DETACHED	PKCS7_DETACHED
+#define SMIME_BINARY	PKCS7_BINARY
+#define SMIME_NOATTR	PKCS7_NOATTR
+
+DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
+
+int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,const EVP_MD *type,
+	unsigned char *md,unsigned int *len);
+#ifndef OPENSSL_NO_FP_API
+PKCS7 *d2i_PKCS7_fp(FILE *fp,PKCS7 **p7);
+int i2d_PKCS7_fp(FILE *fp,PKCS7 *p7);
+#endif
+PKCS7 *PKCS7_dup(PKCS7 *p7);
+PKCS7 *d2i_PKCS7_bio(BIO *bp,PKCS7 **p7);
+int i2d_PKCS7_bio(BIO *bp,PKCS7 *p7);
+int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
+int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
+
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
+DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
+DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
+DECLARE_ASN1_FUNCTIONS(PKCS7)
+
+DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN)
+DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY)
+
+DECLARE_ASN1_NDEF_FUNCTION(PKCS7)
+DECLARE_ASN1_PRINT_FUNCTION(PKCS7)
+
+long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg);
+
+int PKCS7_set_type(PKCS7 *p7, int type);
+int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other);
+int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data);
+int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
+	const EVP_MD *dgst);
+int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si);
+int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
+int PKCS7_add_certificate(PKCS7 *p7, X509 *x509);
+int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
+int PKCS7_content_new(PKCS7 *p7, int nid);
+int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx,
+	BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); 
+int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
+								X509 *x509);
+
+BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio);
+int PKCS7_dataFinal(PKCS7 *p7, BIO *bio);
+BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert);
+
+
+PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509,
+	EVP_PKEY *pkey, const EVP_MD *dgst);
+X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
+int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md);
+STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7);
+
+PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
+void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
+					X509_ALGOR **pdig, X509_ALGOR **psig);
+void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc);
+int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri);
+int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509);
+int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
+int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7);
+
+PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx);
+ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk);
+int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si,int nid,int type,
+	void *data);
+int PKCS7_add_attribute (PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
+	void *value);
+ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid);
+ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid);
+int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
+				STACK_OF(X509_ATTRIBUTE) *sk);
+int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,STACK_OF(X509_ATTRIBUTE) *sk);
+
+
+PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
+							BIO *data, int flags);
+
+PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7,
+			X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md,
+			int flags);
+
+int PKCS7_final(PKCS7 *p7, BIO *data, int flags);
+int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
+					BIO *indata, BIO *out, int flags);
+STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags);
+PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
+								int flags);
+int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags);
+
+int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
+			      STACK_OF(X509_ALGOR) *cap);
+STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si);
+int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg);
+
+int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid);
+int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t);
+int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
+				const unsigned char *md, int mdlen);
+
+int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags);
+PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont);
+
+BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7);
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_PKCS7_strings(void);
+
+/* Error codes for the PKCS7 functions. */
+
+/* Function codes. */
+#define PKCS7_F_B64_READ_PKCS7				 120
+#define PKCS7_F_B64_WRITE_PKCS7				 121
+#define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB			 136
+#define PKCS7_F_I2D_PKCS7_BIO_STREAM			 140
+#define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME		 135
+#define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP		 118
+#define PKCS7_F_PKCS7_ADD_CERTIFICATE			 100
+#define PKCS7_F_PKCS7_ADD_CRL				 101
+#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO		 102
+#define PKCS7_F_PKCS7_ADD_SIGNATURE			 131
+#define PKCS7_F_PKCS7_ADD_SIGNER			 103
+#define PKCS7_F_PKCS7_BIO_ADD_DIGEST			 125
+#define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST		 138
+#define PKCS7_F_PKCS7_CTRL				 104
+#define PKCS7_F_PKCS7_DATADECODE			 112
+#define PKCS7_F_PKCS7_DATAFINAL				 128
+#define PKCS7_F_PKCS7_DATAINIT				 105
+#define PKCS7_F_PKCS7_DATASIGN				 106
+#define PKCS7_F_PKCS7_DATAVERIFY			 107
+#define PKCS7_F_PKCS7_DECRYPT				 114
+#define PKCS7_F_PKCS7_DECRYPT_RINFO			 133
+#define PKCS7_F_PKCS7_ENCODE_RINFO			 132
+#define PKCS7_F_PKCS7_ENCRYPT				 115
+#define PKCS7_F_PKCS7_FINAL				 134
+#define PKCS7_F_PKCS7_FIND_DIGEST			 127
+#define PKCS7_F_PKCS7_GET0_SIGNERS			 124
+#define PKCS7_F_PKCS7_RECIP_INFO_SET			 130
+#define PKCS7_F_PKCS7_SET_CIPHER			 108
+#define PKCS7_F_PKCS7_SET_CONTENT			 109
+#define PKCS7_F_PKCS7_SET_DIGEST			 126
+#define PKCS7_F_PKCS7_SET_TYPE				 110
+#define PKCS7_F_PKCS7_SIGN				 116
+#define PKCS7_F_PKCS7_SIGNATUREVERIFY			 113
+#define PKCS7_F_PKCS7_SIGNER_INFO_SET			 129
+#define PKCS7_F_PKCS7_SIGNER_INFO_SIGN			 139
+#define PKCS7_F_PKCS7_SIGN_ADD_SIGNER			 137
+#define PKCS7_F_PKCS7_SIMPLE_SMIMECAP			 119
+#define PKCS7_F_PKCS7_VERIFY				 117
+#define PKCS7_F_SMIME_READ_PKCS7			 122
+#define PKCS7_F_SMIME_TEXT				 123
+
+/* Reason codes. */
+#define PKCS7_R_CERTIFICATE_VERIFY_ERROR		 117
+#define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER		 144
+#define PKCS7_R_CIPHER_NOT_INITIALIZED			 116
+#define PKCS7_R_CONTENT_AND_DATA_PRESENT		 118
+#define PKCS7_R_CTRL_ERROR				 152
+#define PKCS7_R_DECODE_ERROR				 130
+#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH		 100
+#define PKCS7_R_DECRYPT_ERROR				 119
+#define PKCS7_R_DIGEST_FAILURE				 101
+#define PKCS7_R_ENCRYPTION_CTRL_FAILURE			 149
+#define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150
+#define PKCS7_R_ERROR_ADDING_RECIPIENT			 120
+#define PKCS7_R_ERROR_SETTING_CIPHER			 121
+#define PKCS7_R_INVALID_MIME_TYPE			 131
+#define PKCS7_R_INVALID_NULL_POINTER			 143
+#define PKCS7_R_MIME_NO_CONTENT_TYPE			 132
+#define PKCS7_R_MIME_PARSE_ERROR			 133
+#define PKCS7_R_MIME_SIG_PARSE_ERROR			 134
+#define PKCS7_R_MISSING_CERIPEND_INFO			 103
+#define PKCS7_R_NO_CONTENT				 122
+#define PKCS7_R_NO_CONTENT_TYPE				 135
+#define PKCS7_R_NO_DEFAULT_DIGEST			 151
+#define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND		 154
+#define PKCS7_R_NO_MULTIPART_BODY_FAILURE		 136
+#define PKCS7_R_NO_MULTIPART_BOUNDARY			 137
+#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE	 115
+#define PKCS7_R_NO_RECIPIENT_MATCHES_KEY		 146
+#define PKCS7_R_NO_SIGNATURES_ON_DATA			 123
+#define PKCS7_R_NO_SIGNERS				 142
+#define PKCS7_R_NO_SIG_CONTENT_TYPE			 138
+#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE	 104
+#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR		 124
+#define PKCS7_R_PKCS7_ADD_SIGNER_ERROR			 153
+#define PKCS7_R_PKCS7_DATAFINAL				 126
+#define PKCS7_R_PKCS7_DATAFINAL_ERROR			 125
+#define PKCS7_R_PKCS7_DATASIGN				 145
+#define PKCS7_R_PKCS7_PARSE_ERROR			 139
+#define PKCS7_R_PKCS7_SIG_PARSE_ERROR			 140
+#define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 127
+#define PKCS7_R_SIGNATURE_FAILURE			 105
+#define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND		 128
+#define PKCS7_R_SIGNING_CTRL_FAILURE			 147
+#define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE	 148
+#define PKCS7_R_SIG_INVALID_MIME_TYPE			 141
+#define PKCS7_R_SMIME_TEXT_ERROR			 129
+#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE		 106
+#define PKCS7_R_UNABLE_TO_FIND_MEM_BIO			 107
+#define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST		 108
+#define PKCS7_R_UNKNOWN_DIGEST_TYPE			 109
+#define PKCS7_R_UNKNOWN_OPERATION			 110
+#define PKCS7_R_UNSUPPORTED_CIPHER_TYPE			 111
+#define PKCS7_R_UNSUPPORTED_CONTENT_TYPE		 112
+#define PKCS7_R_WRONG_CONTENT_TYPE			 113
+#define PKCS7_R_WRONG_PKCS7_TYPE			 114
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/pkcs7/pkcs7err.c b/openssl/crypto/pkcs7/pkcs7err.c
new file mode 100644
index 0000000..d0af32a
--- /dev/null
+++ b/openssl/crypto/pkcs7/pkcs7err.c
@@ -0,0 +1,187 @@
+/* crypto/pkcs7/pkcs7err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/pkcs7.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS7,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS7,0,reason)
+
+static ERR_STRING_DATA PKCS7_str_functs[]=
+	{
+{ERR_FUNC(PKCS7_F_B64_READ_PKCS7),	"B64_READ_PKCS7"},
+{ERR_FUNC(PKCS7_F_B64_WRITE_PKCS7),	"B64_WRITE_PKCS7"},
+{ERR_FUNC(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB),	"DO_PKCS7_SIGNED_ATTRIB"},
+{ERR_FUNC(PKCS7_F_I2D_PKCS7_BIO_STREAM),	"i2d_PKCS7_bio_stream"},
+{ERR_FUNC(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME),	"PKCS7_add0_attrib_signing_time"},
+{ERR_FUNC(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP),	"PKCS7_add_attrib_smimecap"},
+{ERR_FUNC(PKCS7_F_PKCS7_ADD_CERTIFICATE),	"PKCS7_add_certificate"},
+{ERR_FUNC(PKCS7_F_PKCS7_ADD_CRL),	"PKCS7_add_crl"},
+{ERR_FUNC(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO),	"PKCS7_add_recipient_info"},
+{ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNATURE),	"PKCS7_add_signature"},
+{ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER),	"PKCS7_add_signer"},
+{ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST),	"PKCS7_BIO_ADD_DIGEST"},
+{ERR_FUNC(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST),	"PKCS7_COPY_EXISTING_DIGEST"},
+{ERR_FUNC(PKCS7_F_PKCS7_CTRL),	"PKCS7_ctrl"},
+{ERR_FUNC(PKCS7_F_PKCS7_DATADECODE),	"PKCS7_dataDecode"},
+{ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL),	"PKCS7_dataFinal"},
+{ERR_FUNC(PKCS7_F_PKCS7_DATAINIT),	"PKCS7_dataInit"},
+{ERR_FUNC(PKCS7_F_PKCS7_DATASIGN),	"PKCS7_DATASIGN"},
+{ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY),	"PKCS7_dataVerify"},
+{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT),	"PKCS7_decrypt"},
+{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT_RINFO),	"PKCS7_DECRYPT_RINFO"},
+{ERR_FUNC(PKCS7_F_PKCS7_ENCODE_RINFO),	"PKCS7_ENCODE_RINFO"},
+{ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT),	"PKCS7_encrypt"},
+{ERR_FUNC(PKCS7_F_PKCS7_FINAL),	"PKCS7_final"},
+{ERR_FUNC(PKCS7_F_PKCS7_FIND_DIGEST),	"PKCS7_FIND_DIGEST"},
+{ERR_FUNC(PKCS7_F_PKCS7_GET0_SIGNERS),	"PKCS7_get0_signers"},
+{ERR_FUNC(PKCS7_F_PKCS7_RECIP_INFO_SET),	"PKCS7_RECIP_INFO_set"},
+{ERR_FUNC(PKCS7_F_PKCS7_SET_CIPHER),	"PKCS7_set_cipher"},
+{ERR_FUNC(PKCS7_F_PKCS7_SET_CONTENT),	"PKCS7_set_content"},
+{ERR_FUNC(PKCS7_F_PKCS7_SET_DIGEST),	"PKCS7_set_digest"},
+{ERR_FUNC(PKCS7_F_PKCS7_SET_TYPE),	"PKCS7_set_type"},
+{ERR_FUNC(PKCS7_F_PKCS7_SIGN),	"PKCS7_sign"},
+{ERR_FUNC(PKCS7_F_PKCS7_SIGNATUREVERIFY),	"PKCS7_signatureVerify"},
+{ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SET),	"PKCS7_SIGNER_INFO_set"},
+{ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SIGN),	"PKCS7_SIGNER_INFO_sign"},
+{ERR_FUNC(PKCS7_F_PKCS7_SIGN_ADD_SIGNER),	"PKCS7_sign_add_signer"},
+{ERR_FUNC(PKCS7_F_PKCS7_SIMPLE_SMIMECAP),	"PKCS7_simple_smimecap"},
+{ERR_FUNC(PKCS7_F_PKCS7_VERIFY),	"PKCS7_verify"},
+{ERR_FUNC(PKCS7_F_SMIME_READ_PKCS7),	"SMIME_read_PKCS7"},
+{ERR_FUNC(PKCS7_F_SMIME_TEXT),	"SMIME_text"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA PKCS7_str_reasons[]=
+	{
+{ERR_REASON(PKCS7_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"},
+{ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"},
+{ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED),"cipher not initialized"},
+{ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT),"content and data present"},
+{ERR_REASON(PKCS7_R_CTRL_ERROR)          ,"ctrl error"},
+{ERR_REASON(PKCS7_R_DECODE_ERROR)        ,"decode error"},
+{ERR_REASON(PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH),"decrypted key is wrong length"},
+{ERR_REASON(PKCS7_R_DECRYPT_ERROR)       ,"decrypt error"},
+{ERR_REASON(PKCS7_R_DIGEST_FAILURE)      ,"digest failure"},
+{ERR_REASON(PKCS7_R_ENCRYPTION_CTRL_FAILURE),"encryption ctrl failure"},
+{ERR_REASON(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"encryption not supported for this key type"},
+{ERR_REASON(PKCS7_R_ERROR_ADDING_RECIPIENT),"error adding recipient"},
+{ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER),"error setting cipher"},
+{ERR_REASON(PKCS7_R_INVALID_MIME_TYPE)   ,"invalid mime type"},
+{ERR_REASON(PKCS7_R_INVALID_NULL_POINTER),"invalid null pointer"},
+{ERR_REASON(PKCS7_R_MIME_NO_CONTENT_TYPE),"mime no content type"},
+{ERR_REASON(PKCS7_R_MIME_PARSE_ERROR)    ,"mime parse error"},
+{ERR_REASON(PKCS7_R_MIME_SIG_PARSE_ERROR),"mime sig parse error"},
+{ERR_REASON(PKCS7_R_MISSING_CERIPEND_INFO),"missing ceripend info"},
+{ERR_REASON(PKCS7_R_NO_CONTENT)          ,"no content"},
+{ERR_REASON(PKCS7_R_NO_CONTENT_TYPE)     ,"no content type"},
+{ERR_REASON(PKCS7_R_NO_DEFAULT_DIGEST)   ,"no default digest"},
+{ERR_REASON(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND),"no matching digest type found"},
+{ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"},
+{ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"},
+{ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE),"no recipient matches certificate"},
+{ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_KEY),"no recipient matches key"},
+{ERR_REASON(PKCS7_R_NO_SIGNATURES_ON_DATA),"no signatures on data"},
+{ERR_REASON(PKCS7_R_NO_SIGNERS)          ,"no signers"},
+{ERR_REASON(PKCS7_R_NO_SIG_CONTENT_TYPE) ,"no sig content type"},
+{ERR_REASON(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE),"operation not supported on this type"},
+{ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR),"pkcs7 add signature error"},
+{ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNER_ERROR),"pkcs7 add signer error"},
+{ERR_REASON(PKCS7_R_PKCS7_DATAFINAL)     ,"pkcs7 datafinal"},
+{ERR_REASON(PKCS7_R_PKCS7_DATAFINAL_ERROR),"pkcs7 datafinal error"},
+{ERR_REASON(PKCS7_R_PKCS7_DATASIGN)      ,"pkcs7 datasign"},
+{ERR_REASON(PKCS7_R_PKCS7_PARSE_ERROR)   ,"pkcs7 parse error"},
+{ERR_REASON(PKCS7_R_PKCS7_SIG_PARSE_ERROR),"pkcs7 sig parse error"},
+{ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
+{ERR_REASON(PKCS7_R_SIGNATURE_FAILURE)   ,"signature failure"},
+{ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
+{ERR_REASON(PKCS7_R_SIGNING_CTRL_FAILURE),"signing ctrl failure"},
+{ERR_REASON(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"signing not supported for this key type"},
+{ERR_REASON(PKCS7_R_SIG_INVALID_MIME_TYPE),"sig invalid mime type"},
+{ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR)    ,"smime text error"},
+{ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE),"unable to find certificate"},
+{ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MEM_BIO),"unable to find mem bio"},
+{ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST),"unable to find message digest"},
+{ERR_REASON(PKCS7_R_UNKNOWN_DIGEST_TYPE) ,"unknown digest type"},
+{ERR_REASON(PKCS7_R_UNKNOWN_OPERATION)   ,"unknown operation"},
+{ERR_REASON(PKCS7_R_UNSUPPORTED_CIPHER_TYPE),"unsupported cipher type"},
+{ERR_REASON(PKCS7_R_UNSUPPORTED_CONTENT_TYPE),"unsupported content type"},
+{ERR_REASON(PKCS7_R_WRONG_CONTENT_TYPE)  ,"wrong content type"},
+{ERR_REASON(PKCS7_R_WRONG_PKCS7_TYPE)    ,"wrong pkcs7 type"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_PKCS7_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(PKCS7_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,PKCS7_str_functs);
+		ERR_load_strings(0,PKCS7_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/pkcs7/server.pem b/openssl/crypto/pkcs7/server.pem
new file mode 100644
index 0000000..750aac2
--- /dev/null
+++ b/openssl/crypto/pkcs7/server.pem
@@ -0,0 +1,24 @@
+issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit)
+subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Server test cert (512 bit)
+-----BEGIN CERTIFICATE-----
+MIIB6TCCAVICAQAwDQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCQVUxEzARBgNV
+BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYD
+VQQDExJUZXN0IENBICgxMDI0IGJpdCkwHhcNOTcwNjA5MTM1NzQ2WhcNOTgwNjA5
+MTM1NzQ2WjBjMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEaMBgG
+A1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxIzAhBgNVBAMTGlNlcnZlciB0ZXN0IGNl
+cnQgKDUxMiBiaXQpMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ+zw4Qnlf8SMVIP
+Fe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVDTGiXav6ooKXfX3j/7tdkuD8Ey2//
+Kv7+ue0CAwEAATANBgkqhkiG9w0BAQQFAAOBgQB4TMR2CvacKE9wAsu9jyCX8YiW
+mgCM+YoP6kt4Zkj2z5IRfm7WrycKsnpnOR+tGeqAjkCeZ6/36o9l91RvPnN1VJ/i
+xQv2df0KFeMr00IkDdTNAdIWqFkSsZTAY2QAdgenb7MB1joejquYzO2DQIO7+wpH
+irObpESxAZLySCmPPg==
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIBPAIBAAJBAJ+zw4Qnlf8SMVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVD
+TGiXav6ooKXfX3j/7tdkuD8Ey2//Kv7+ue0CAwEAAQJAN6W31vDEP2DjdqhzCDDu
+OA4NACqoiFqyblo7yc2tM4h4xMbC3Yx5UKMN9ZkCtX0gzrz6DyF47bdKcWBzNWCj
+gQIhANEoojVt7hq+SQ6MCN6FTAysGgQf56Q3TYoJMoWvdiXVAiEAw3e3rc+VJpOz
+rHuDo6bgpjUAAXM+v3fcpsfZSNO6V7kCIQCtbVjanpUwvZkMI9by02oUk9taki3b
+PzPfAfNPYAbCJQIhAJXNQDWyqwn/lGmR11cqY2y9nZ1+5w3yHGatLrcDnQHxAiEA
+vnlEGo8K85u+KwIOimM48ZG8oTk7iFdkqLJR1utT3aU=
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/crypto/pkcs7/sign.c b/openssl/crypto/pkcs7/sign.c
new file mode 100644
index 0000000..8b59885
--- /dev/null
+++ b/openssl/crypto/pkcs7/sign.c
@@ -0,0 +1,154 @@
+/* crypto/pkcs7/sign.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+#include <stdio.h>
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+
+int main(argc,argv)
+int argc;
+char *argv[];
+	{
+	X509 *x509;
+	EVP_PKEY *pkey;
+	PKCS7 *p7;
+	PKCS7_SIGNER_INFO *si;
+	BIO *in;
+	BIO *data,*p7bio;
+	char buf[1024*4];
+	int i;
+	int nodetach=0;
+
+#ifndef OPENSSL_NO_MD2
+	EVP_add_digest(EVP_md2());
+#endif
+#ifndef OPENSSL_NO_MD5
+	EVP_add_digest(EVP_md5());
+#endif
+#ifndef OPENSSL_NO_SHA1
+	EVP_add_digest(EVP_sha1());
+#endif
+#ifndef OPENSSL_NO_MDC2
+	EVP_add_digest(EVP_mdc2());
+#endif
+
+	data=BIO_new(BIO_s_file());
+again:
+	if (argc > 1)
+		{
+		if (strcmp(argv[1],"-nd") == 0)
+			{
+			nodetach=1;
+			argv++; argc--;
+			goto again;
+			}
+		if (!BIO_read_filename(data,argv[1]))
+			goto err;
+		}
+	else
+		BIO_set_fp(data,stdin,BIO_NOCLOSE);
+
+	if ((in=BIO_new_file("server.pem","r")) == NULL) goto err;
+	if ((x509=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL) goto err;
+	BIO_reset(in);
+	if ((pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,NULL)) == NULL) goto err;
+	BIO_free(in);
+
+	p7=PKCS7_new();
+	PKCS7_set_type(p7,NID_pkcs7_signed);
+	 
+	si=PKCS7_add_signature(p7,x509,pkey,EVP_sha1());
+	if (si == NULL) goto err;
+
+	/* If you do this then you get signing time automatically added */
+	PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT,
+						OBJ_nid2obj(NID_pkcs7_data));
+
+	/* we may want to add more */
+	PKCS7_add_certificate(p7,x509);
+
+	/* Set the content of the signed to 'data' */
+	PKCS7_content_new(p7,NID_pkcs7_data);
+
+	if (!nodetach)
+		PKCS7_set_detached(p7,1);
+
+	if ((p7bio=PKCS7_dataInit(p7,NULL)) == NULL) goto err;
+
+	for (;;)
+		{
+		i=BIO_read(data,buf,sizeof(buf));
+		if (i <= 0) break;
+		BIO_write(p7bio,buf,i);
+		}
+
+	if (!PKCS7_dataFinal(p7,p7bio)) goto err;
+	BIO_free(p7bio);
+
+	PEM_write_PKCS7(stdout,p7);
+	PKCS7_free(p7);
+
+	exit(0);
+err:
+	ERR_load_crypto_strings();
+	ERR_print_errors_fp(stderr);
+	exit(1);
+	}
+
diff --git a/openssl/crypto/pkcs7/t/3des.pem b/openssl/crypto/pkcs7/t/3des.pem
new file mode 100644
index 0000000..b2b5081
--- /dev/null
+++ b/openssl/crypto/pkcs7/t/3des.pem
@@ -0,0 +1,16 @@
+-----BEGIN PKCS7-----
+MIAGCSqGSIb3DQEHA6CAMIACAQAxggHmMIHwAgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEG
+A1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
+dCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNUUkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQD
+ExJERU1PIFpFUk8gVkFMVUUgQ0ECAgR+MA0GCSqGSIb3DQEBAQUABEC2vXI1xQDW6lUHM3zQ
+/9uBEBOO5A3TtkrklAXq7v01gsIC21t52qSk36REXY+slhNZ0OQ349tgkTsoETHFLoEwMIHw
+AgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMI
+QnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29mdCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNU
+UkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQDExJERU1PIFpFUk8gVkFMVUUgQ0ECAgR9MA0G
+CSqGSIb3DQEBAQUABEB8ujxbabxXUYJhopuDm3oDq4JNqX6Io4p3ro+ShqfIndsXTZ1v5a2N
+WtLLCWlHn/habjBwZ/DgQgcKASbZ7QxNMIAGCSqGSIb3DQEHATAaBggqhkiG9w0DAjAOAgIA
+oAQIbsL5v1wX98KggAQoAaJ4WHm68fXY1WE5OIjfVBIDpO1K+i8dmKhjnAjrjoyZ9Bwc8rDL
+lgQg4CXb805h5xl+GfvSwUaHJayte1m2mcOhs3J2YyqbQ+MEIMIiJQccmhO3oDKm36CFvYR8
+5PjpclVcZyX2ngbwPFMnBAgy0clOAE6UKAAAAAAAAAAAAAA=
+-----END PKCS7-----
+
diff --git a/openssl/crypto/pkcs7/t/3dess.pem b/openssl/crypto/pkcs7/t/3dess.pem
new file mode 100644
index 0000000..23f0135
--- /dev/null
+++ b/openssl/crypto/pkcs7/t/3dess.pem
@@ -0,0 +1,32 @@
+-----BEGIN PKCS7-----
+MIIGHgYJKoZIhvcNAQcCoIIGDzCCBgsCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCC
+BGswggJTMIIB/aADAgECAgIEfjANBgkqhkiG9w0BAQQFADCBkjELMAkGA1UEBhMCQVUxEzAR
+BgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5lMRowGAYDVQQKExFDcnlwdHNv
+ZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBBTkQgVEVTVElORzEbMBkGA1UE
+AxMSREVNTyBaRVJPIFZBTFVFIENBMB4XDTk4MDUxMzA2MjY1NloXDTAwMDUxMjA2MjY1Nlow
+gaUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFu
+ZTEaMBgGA1UEChMRQ3J5cHRzb2Z0IFB0eSBMdGQxEjAQBgNVBAsTCVNNSU1FIDAwMzEZMBcG
+A1UEAxMQQW5nZWxhIHZhbiBMZWVudDEjMCEGCSqGSIb3DQEJARYUYW5nZWxhQGNyeXB0c29m
+dC5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAuC3+7dAb2LhuO7gt2cTM8vsNjhG5JfDh
+hX1Vl/wVGbKEEj0MA6vWEolvefQlxB+EzwCtR0YZ7eEC/T/4JoCyeQIDAQABoygwJjAkBglg
+hkgBhvhCAQ0EFxYVR2VuZXJhdGVkIHdpdGggU1NMZWF5MA0GCSqGSIb3DQEBBAUAA0EAUnSP
+igs6TMFISTjw8cBtJYb98czgAVkVFjKyJQwYMH8FbDnCyx6NocM555nsyDstaw8fKR11Khds
+syd3ikkrhDCCAhAwggG6AgEDMA0GCSqGSIb3DQEBBAUAMIGSMQswCQYDVQQGEwJBVTETMBEG
+A1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
+dCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNUUkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQD
+ExJERU1PIFpFUk8gVkFMVUUgQ0EwHhcNOTgwMzAzMDc0MTMyWhcNMDgwMjI5MDc0MTMyWjCB
+kjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5l
+MRowGAYDVQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBB
+TkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENBMFwwDQYJKoZIhvcNAQEB
+BQADSwAwSAJBAL+0E2fLej3FSCwe2A2iRnMuC3z12qHIp6Ky1wo2zZcxft7AI+RfkrWrSGtf
+mfzBEuPrLdfulncC5Y1pNcM8RTUCAwEAATANBgkqhkiG9w0BAQQFAANBAGSbLMphL6F5pp3s
+8o0Xyh86FHFdpVOwYx09ELLkuG17V/P9pgIc0Eo/gDMbN+KT3IdgECf8S//pCRA6RrNjcXIx
+ggF7MIIBdwIBATCBmTCBkjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAP
+BgNVBAcTCEJyaXNiYW5lMRowGAYDVQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZ
+REVNT05TVFJBVElPTiBBTkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENB
+AgIEfjAJBgUrDgMCGgUAoHowGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAbBgkqhkiG9w0B
+CQ8xDjAMMAoGCCqGSIb3DQMHMBwGCSqGSIb3DQEJBTEPFw05ODA1MTQwMzM5MzdaMCMGCSqG
+SIb3DQEJBDEWBBQstNMnSV26ba8PapQEDhO21yNFrjANBgkqhkiG9w0BAQEFAARAW9Xb9YXv
+BfcNkutgFX9Gr8iXhBVsNtGEVrjrpkQwpKa7jHI8SjAlLhk/4RFwDHf+ISB9Np3Z1WDWnLcA
+9CWR6g==
+-----END PKCS7-----
diff --git a/openssl/crypto/pkcs7/t/c.pem b/openssl/crypto/pkcs7/t/c.pem
new file mode 100644
index 0000000..a4b55e3
--- /dev/null
+++ b/openssl/crypto/pkcs7/t/c.pem
@@ -0,0 +1,48 @@
+issuer :/C=AU/SP=Queensland/L=Brisbane/O=Cryptsoft Pty Ltd/OU=DEMONSTRATION AND TESTING/CN=DEMO ZERO VALUE CA
+subject:/C=AU/SP=Queensland/L=Brisbane/O=Cryptsoft Pty Ltd/OU=SMIME 003/CN=Information/Email=info@cryptsoft.com
+serial :047D
+
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1149 (0x47d)
+        Signature Algorithm: md5withRSAEncryption
+        Issuer: C=AU, SP=Queensland, L=Brisbane, O=Cryptsoft Pty Ltd, OU=DEMONSTRATION AND TESTING, CN=DEMO ZERO VALUE CA
+        Validity
+            Not Before: May 13 05:40:58 1998 GMT
+            Not After : May 12 05:40:58 2000 GMT
+        Subject: C=AU, SP=Queensland, L=Brisbane, O=Cryptsoft Pty Ltd, OU=SMIME 003, CN=Information/Email=info@cryptsoft.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Modulus:
+                    00:ad:e7:23:89:ee:0d:87:b7:9c:32:44:4b:95:81:
+                    73:dd:22:80:4b:2d:c5:60:b8:fe:1e:18:63:ef:dc:
+                    89:89:22:df:95:3c:7a:db:3d:9a:06:a8:08:d6:29:
+                    fd:ef:41:09:91:ed:bc:ad:98:f9:f6:28:90:62:6f:
+                    e7:e7:0c:4d:0b
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            Netscape Comment: 
+                Generated with SSLeay
+    Signature Algorithm: md5withRSAEncryption
+        52:15:ea:88:f4:f0:f9:0b:ef:ce:d5:f8:83:40:61:16:5e:55:
+        f9:ce:2d:d1:8b:31:5c:03:c6:2d:10:7c:61:d5:5c:0a:42:97:
+        d1:fd:65:b6:b6:84:a5:39:ec:46:ec:fc:e0:0d:d9:22:da:1b:
+        50:74:ad:92:cb:4e:90:e5:fa:7d
+
+-----BEGIN CERTIFICATE-----
+MIICTDCCAfagAwIBAgICBH0wDQYJKoZIhvcNAQEEBQAwgZIxCzAJBgNVBAYTAkFV
+MRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UE
+ChMRQ3J5cHRzb2Z0IFB0eSBMdGQxIjAgBgNVBAsTGURFTU9OU1RSQVRJT04gQU5E
+IFRFU1RJTkcxGzAZBgNVBAMTEkRFTU8gWkVSTyBWQUxVRSBDQTAeFw05ODA1MTMw
+NTQwNThaFw0wMDA1MTIwNTQwNThaMIGeMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
+UXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
+dCBQdHkgTHRkMRIwEAYDVQQLEwlTTUlNRSAwMDMxFDASBgNVBAMTC0luZm9ybWF0
+aW9uMSEwHwYJKoZIhvcNAQkBFhJpbmZvQGNyeXB0c29mdC5jb20wXDANBgkqhkiG
+9w0BAQEFAANLADBIAkEArecjie4Nh7ecMkRLlYFz3SKASy3FYLj+Hhhj79yJiSLf
+lTx62z2aBqgI1in970EJke28rZj59iiQYm/n5wxNCwIDAQABoygwJjAkBglghkgB
+hvhCAQ0EFxYVR2VuZXJhdGVkIHdpdGggU1NMZWF5MA0GCSqGSIb3DQEBBAUAA0EA
+UhXqiPTw+QvvztX4g0BhFl5V+c4t0YsxXAPGLRB8YdVcCkKX0f1ltraEpTnsRuz8
+4A3ZItobUHStkstOkOX6fQ==
+-----END CERTIFICATE-----
+
diff --git a/openssl/crypto/pkcs7/t/ff b/openssl/crypto/pkcs7/t/ff
new file mode 100644
index 0000000..23f0135
--- /dev/null
+++ b/openssl/crypto/pkcs7/t/ff
@@ -0,0 +1,32 @@
+-----BEGIN PKCS7-----
+MIIGHgYJKoZIhvcNAQcCoIIGDzCCBgsCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCC
+BGswggJTMIIB/aADAgECAgIEfjANBgkqhkiG9w0BAQQFADCBkjELMAkGA1UEBhMCQVUxEzAR
+BgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5lMRowGAYDVQQKExFDcnlwdHNv
+ZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBBTkQgVEVTVElORzEbMBkGA1UE
+AxMSREVNTyBaRVJPIFZBTFVFIENBMB4XDTk4MDUxMzA2MjY1NloXDTAwMDUxMjA2MjY1Nlow
+gaUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFu
+ZTEaMBgGA1UEChMRQ3J5cHRzb2Z0IFB0eSBMdGQxEjAQBgNVBAsTCVNNSU1FIDAwMzEZMBcG
+A1UEAxMQQW5nZWxhIHZhbiBMZWVudDEjMCEGCSqGSIb3DQEJARYUYW5nZWxhQGNyeXB0c29m
+dC5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAuC3+7dAb2LhuO7gt2cTM8vsNjhG5JfDh
+hX1Vl/wVGbKEEj0MA6vWEolvefQlxB+EzwCtR0YZ7eEC/T/4JoCyeQIDAQABoygwJjAkBglg
+hkgBhvhCAQ0EFxYVR2VuZXJhdGVkIHdpdGggU1NMZWF5MA0GCSqGSIb3DQEBBAUAA0EAUnSP
+igs6TMFISTjw8cBtJYb98czgAVkVFjKyJQwYMH8FbDnCyx6NocM555nsyDstaw8fKR11Khds
+syd3ikkrhDCCAhAwggG6AgEDMA0GCSqGSIb3DQEBBAUAMIGSMQswCQYDVQQGEwJBVTETMBEG
+A1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
+dCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNUUkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQD
+ExJERU1PIFpFUk8gVkFMVUUgQ0EwHhcNOTgwMzAzMDc0MTMyWhcNMDgwMjI5MDc0MTMyWjCB
+kjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5l
+MRowGAYDVQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBB
+TkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENBMFwwDQYJKoZIhvcNAQEB
+BQADSwAwSAJBAL+0E2fLej3FSCwe2A2iRnMuC3z12qHIp6Ky1wo2zZcxft7AI+RfkrWrSGtf
+mfzBEuPrLdfulncC5Y1pNcM8RTUCAwEAATANBgkqhkiG9w0BAQQFAANBAGSbLMphL6F5pp3s
+8o0Xyh86FHFdpVOwYx09ELLkuG17V/P9pgIc0Eo/gDMbN+KT3IdgECf8S//pCRA6RrNjcXIx
+ggF7MIIBdwIBATCBmTCBkjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAP
+BgNVBAcTCEJyaXNiYW5lMRowGAYDVQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZ
+REVNT05TVFJBVElPTiBBTkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENB
+AgIEfjAJBgUrDgMCGgUAoHowGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAbBgkqhkiG9w0B
+CQ8xDjAMMAoGCCqGSIb3DQMHMBwGCSqGSIb3DQEJBTEPFw05ODA1MTQwMzM5MzdaMCMGCSqG
+SIb3DQEJBDEWBBQstNMnSV26ba8PapQEDhO21yNFrjANBgkqhkiG9w0BAQEFAARAW9Xb9YXv
+BfcNkutgFX9Gr8iXhBVsNtGEVrjrpkQwpKa7jHI8SjAlLhk/4RFwDHf+ISB9Np3Z1WDWnLcA
+9CWR6g==
+-----END PKCS7-----
diff --git a/openssl/crypto/pkcs7/t/msie-e b/openssl/crypto/pkcs7/t/msie-e
new file mode 100644
index 0000000..aafae69
--- /dev/null
+++ b/openssl/crypto/pkcs7/t/msie-e
@@ -0,0 +1,20 @@
+
+MIAGCSqGSIb3DQEHA6CAMIACAQAxggHCMIHMAgEAMHYwYjERMA8GA1UEBxMISW50ZXJuZXQxFzAV
+BgNVBAoTDlZlcmlTaWduLCBJbmMuMTQwMgYDVQQLEytWZXJpU2lnbiBDbGFzcyAxIENBIC0gSW5k
+aXZpZHVhbCBTdWJzY3JpYmVyAhBgQJiC3qfbCbjdj5INYLnKMA0GCSqGSIb3DQEBAQUABECMzu8y
+wQ/qZbO8cAGMRBF+mPruv3+Dvb9aWNZ2k8njUgqF6mcdhVB2MkGcsG3memRXJBixvMYWVkU3qK4Z
+VuKsMIHwAgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDERMA8GA1UE
+BxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29mdCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNU
+UkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQDExJERU1PIFpFUk8gVkFMVUUgQ0ECAgRuMA0GCSqG
+SIb3DQEBAQUABEBcWwYFHJbJGhiztt7lzue3Lc9CH5WAbyR+2BZ3uv+JxZfRs1PuaWPOwRa0Vgs3
+YwSJoRfxQj2Gk0wFqG1qt6d1MIAGCSqGSIb3DQEHATAaBggqhkiG9w0DAjAOAgIAoAQI8vRlP/Nx
+2iSggASCAZhR5srxyspy7DfomRJ9ff8eMCtaNwEoEx7G25PZRonC57hBvGoScLtEPU3Wp9FEbPN7
+oJESeC+AqMTyTLNy8aQsyC5s53E9UkoIvg62ekYZBbXZqXsrxx4PhiiX3NH8GVh42phB0Chjw0nK
+HZeRDmxGY3Cmk+J+l0uVKxbNIfJIKOguLBnhqmnKH/PrnzDt591u0ULy2aTLqRm+4/1Yat/QPb6J
+eoKGwNPBbS9ogBdrCNCp9ZFg3Xar2AtQHzyTQIfYeH3SRQUpKmRm5U5o9p5emgEdT+ZfJm/J4tSH
+OmbgAFsbHQakA4MBZ4J5qfDJhOA2g5lWk1hIeu5Dn/AaLRZd0yz3oY0Ieo/erPWx/bCqtBzYbMe9
+qSFTedKlbc9EGe3opOTdBZVzK8KH3w3zsy5luxKdOUG59YYb5F1IZiWGiDyuo/HuacX+griu5LeD
+bEzOtZnko+TZXvWIko30fD79j3T4MRRhWXbgj2HKza+4vJ0mzcC/1+GPsJjAEAA/JgIEDU4w6/DI
+/HQHhLAO3G+9xKD7MvmrzkoAAAAAAAAAAAAA
+
+
diff --git a/openssl/crypto/pkcs7/t/msie-e.pem b/openssl/crypto/pkcs7/t/msie-e.pem
new file mode 100644
index 0000000..a2a5e24
--- /dev/null
+++ b/openssl/crypto/pkcs7/t/msie-e.pem
@@ -0,0 +1,22 @@
+-----BEGIN PKCS7-----
+MIAGCSqGSIb3DQEHA6CAMIIDkAIBADGCAcIwgcwCAQAwdjBiMREwDwYDVQQHEwhJ
+bnRlcm5ldDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNDAyBgNVBAsTK1ZlcmlT
+aWduIENsYXNzIDEgQ0EgLSBJbmRpdmlkdWFsIFN1YnNjcmliZXICEGBAmILep9sJ
+uN2Pkg1gucowDQYJKoZIhvcNAQEBBQAEQIzO7zLBD+pls7xwAYxEEX6Y+u6/f4O9
+v1pY1naTyeNSCoXqZx2FUHYyQZywbeZ6ZFckGLG8xhZWRTeorhlW4qwwgfACAQAw
+gZkwgZIxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQH
+EwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRzb2Z0IFB0eSBMdGQxIjAgBgNVBAsT
+GURFTU9OU1RSQVRJT04gQU5EIFRFU1RJTkcxGzAZBgNVBAMTEkRFTU8gWkVSTyBW
+QUxVRSBDQQICBG4wDQYJKoZIhvcNAQEBBQAEQFxbBgUclskaGLO23uXO57ctz0If
+lYBvJH7YFne6/4nFl9GzU+5pY87BFrRWCzdjBImhF/FCPYaTTAWobWq3p3UwggHD
+BgkqhkiG9w0BBwEwGgYIKoZIhvcNAwIwDgICAKAECPL0ZT/zcdokgIIBmFHmyvHK
+ynLsN+iZEn19/x4wK1o3ASgTHsbbk9lGicLnuEG8ahJwu0Q9Tdan0URs83ugkRJ4
+L4CoxPJMs3LxpCzILmzncT1SSgi+DrZ6RhkFtdmpeyvHHg+GKJfc0fwZWHjamEHQ
+KGPDScodl5EObEZjcKaT4n6XS5UrFs0h8kgo6C4sGeGqacof8+ufMO3n3W7RQvLZ
+pMupGb7j/Vhq39A9vol6gobA08FtL2iAF2sI0Kn1kWDddqvYC1AfPJNAh9h4fdJF
+BSkqZGblTmj2nl6aAR1P5l8mb8ni1Ic6ZuAAWxsdBqQDgwFngnmp8MmE4DaDmVaT
+WEh67kOf8BotFl3TLPehjQh6j96s9bH9sKq0HNhsx72pIVN50qVtz0QZ7eik5N0F
+lXMrwoffDfOzLmW7Ep05Qbn1hhvkXUhmJYaIPK6j8e5pxf6CuK7kt4NsTM61meSj
+5Nle9YiSjfR8Pv2PdPgxFGFZduCPYcrNr7i8nSbNwL/X4Y+wmMAQAD8mAgQNTjDr
+8Mj8dAeEsA7cb73EoPsy+avOSgAAAAA=
+-----END PKCS7-----
diff --git a/openssl/crypto/pkcs7/t/msie-enc-01 b/openssl/crypto/pkcs7/t/msie-enc-01
new file mode 100644
index 0000000..2c93ab6
--- /dev/null
+++ b/openssl/crypto/pkcs7/t/msie-enc-01
@@ -0,0 +1,62 @@
+
+MIAGCSqGSIb3DQEHA6CAMIACAQAxgfMwgfACAQAwgZkwgZIxCzAJBgNVBAYTAkFVMRMwEQYD
+VQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRzb2Z0
+IFB0eSBMdGQxIjAgBgNVBAsTGURFTU9OU1RSQVRJT04gQU5EIFRFU1RJTkcxGzAZBgNVBAMT
+EkRFTU8gWkVSTyBWQUxVRSBDQQICBG4wDQYJKoZIhvcNAQEBBQAEQKvMaW8xh6oF/X+CJivz
+IZV7yHxlp4O3NHQtWG0A8MOZB+CtKlU7/6g5e/a9Du/TOqxRMqtYRp63pa2Q/mM4IYMwgAYJ
+KoZIhvcNAQcBMBoGCCqGSIb3DQMCMA4CAgCgBAifz6RvzOPYlKCABIGwxtGA/FLBBRs1wbBP
+gDCbSG0yCwjJNsFg89/k6xuXo8c5YTwsw8+XlIVq03navpew6XxxzY090rD2OJ0t6HA6GqrI
+pd8WiSh/Atqn0yfLFmkLqgIAPRfzxUxqUocxLpQsLIFp2YNUGE+yps+UZmIjw/WHfdqrcWTm
+STSvKuy3UkIJZCkGDBpTvqk4BFaHh4oTXEpgpNY+GKxjf9TDN9GQPqQZR7sgQki4t2g4/Saq
+Kl4EMISgluk6swdND0tiHY7v5d6YR29ePCl2/STJ98eJpWkEEC22GNNvOy7ru/Rv2He4MgQg
+optd7sk9MMd9xhJppg7CcH/yDx//HrtgpOcWmn6VxpgECFqon4uXkQtIBIH4PaNclFn7/hLx
+Pw2VmBGaC0SYF3U1jyN96EBxdjqy8Aa6ByMXYDW5BcfqniD5mYXfw+b81lh1kutxaPaV4YJ9
+ZlRUW752N7VHo/fG0/fukoe5W9a8kIhgLpygllb/GP4oSF4wM6n1/OgRzZj2IWFiobKO4d/t
+Mnh+C+PoEVAuFZcxQwi9GqvsK5OoIjVwNx0XcVSOl1TTYS9SwC7ugMBCab73JiruC24pL78Y
+M+NaIpIQ3On4DokJA2ZHtjBjZIxF4tKA144RvFN6pBd6TVE5XM6KD/Vh9bjSmujtEAfdQ3Te
+dvKJsbZuu0stErbvWcRy11I328l557EECAJT7d44OJ3rBBBj6bnnx6dDU2SRqp2CEoQaBAhK
+RBuyhNxkygQIOY9/NhwqAJAECOvX0Zd0DqgoBAjobPpMHhVV3gQQWLU2vEoZ51BwzxdzCmxO
+wwQI4oKfudaNqoAESKzBNAqv5kGumHOlMKsRfrs7jZCcSaOuEj97pYx08FLEgF23cav39MOQ
+NUEM1dNU+EYslL4o3RoSHRjUgPU+2t9c0prS9A/bPARIEOP94PynaTNxwHi3VTK7SzuQmgzA
+4n942E9joSiqsQPlsKAb3sPUaLC3SuUxSjNBgfpvD0bmrA/5h+WZoYXvIogFpwjkSmnFBEie
+0lh5Ov1aRrvCw5/j3Q/W/4ZtN5U+aeVBJMtA8n0Mxd5kPxHbNVh4oGprZ6wEegV8ht3voyZa
+mZ5Cyxc8ffMYnM/JJI6/oEYEUEMyyiS5FnYyvxKzfMtyn2lZ2st9nZGNNgMc9N62r5HgNbdD
+FHuRdKKzV+8kQfuMc3mOPpK1t9TFY+QgrxiB5p6S7VooI97YtP3PbfknszCEBEh4PdXYbbaR
+3AacN3Q5kYYmWsq3WW6xgrg0mmEGosGvwSQxBBuiXZrxScCa4ivEq05UZwyShePvKduOvnUE
+2zDO6IXFLZxhTZAESEm9/FovLgGAiJ7iMGmYvsISLJScwG4n+wrSaQNQXizs9N3ykys54wBN
+d/+BQ4F7pncHhDQ2Dyt5MekB8Y8iNOocUTFCu524vQRIaWCXmXP3vU7D21dp0XnAMzRQJ565
+JV3aHRoY7XDa4LePa7PP9ywyafOE5yCW7ndqx3J+2JhTDvSFsW8/q3H3iyeFhykuJVS6BFDK
+6CmKbnyyjOfE2iLGJmTFa905V2KrVDCmlEu/xyGMs80yTyZC+ySzM83FMVvLEQmSzcTNUZVp
+DfA1kNXbXkPouBXXT6g8r8JCRljaKKABmgRIlMheOJQRUUU4cgvhMreXPayhq5Ao4VMSCkA5
+hYRCBczm4Di/MMohF0SxIsdRY6gY9CPnrBXAsY6h1RbR7Tw0iQZmeXi52DCiBEj0by+SYMAa
+9z0CReIzl8JLL6EVIFz8kFxlkGWjr4dnOzhhPOq/mCpp0WxbavDfdhE87MdXJZBnLwoT62QG
+955HlAoEQBOGJbcESCgd5XSirZ9Y3AbCfuKOqoMBvEUGn+w/pMaqnGvnr5FZhuBDKrhRXqtx
+QsxA//drGUxsrZOuSL/0+fbvo7n2h1Z8Ny86jOvVZAQIAjw2l1Yc5RAESNc9i3I8pKEOVQf/
+UBczJ0NR9aTEF80dRg2lpXwD0ho4N0AvSiVbgxC7cPZHQwIqvq9LHRUs/4n+Vu3SVYU3cAxo
+lUTiCGUSlARIF+TD57SI5+RI+MNtnD9rs4E1ml51YoHGWFj3UPriDmY0FKEwIgqtMXMY3fZ9
+Kq8d83bjDzxwbDX7WwR7KbSeJWT42pCz7kM+BEjjPsOnZHuusXT3x2rrsBnYtYsbt98mSFiS
+KzTtFmXfkOBbCQdit1P76QnYJ1aXMGs6zP6GypQTadK/zYWvlm38QkVwueaJ0woESKW2pqKA
+70h2UMDHOrpepU1lj0YMzmotDHSTU3L909VvUMNg9uqfrQ6mSkb9j5Tl8oF2otOw5EzA1Yda
+KPmgsv62RWLYl80wXQRQwG0e/mgG75jp9lOhJdVXqcYbQpS9viwVaVkwH+69mu/bQI4gjoEs
+UYX6O71Re2z+cYhcm9UrK+DXuSFBXQOIlAFxKMW4B0apd6fU84FsZLMESOorXE5OE0A2B2ji
+J8QI0Exk4hUvWrMNJfUZwFyS7E05xV9ORuX1xmsKqkT4tVR5Nqln4vhvAY860VBoloz0CDkd
+8seSBEjeMgRI9FvpYuflIeHg9urkwp6N+1f0DrJJhJY9ZQ0HTQhziJmIfvbEjNqCl7hEC28+
+F8I5tuViLgfSwcFFCvnS6WFoN4X6QdFdqMCbBEjdlI1c+IQGA/IuTDMJYCuQ/v+8BG5ZeWVH
+icPZmXfRat9eFK1dGKAJef6+Tf9HPuDjSpDyffrifsp7Dc34lmm7GN1+ON3ZMtwEUNm6epb8
+1RKWjoI7jIKUV/M2p/0eeGSqs4b06KF/VR6dBwsJVL5DpnTsp3MV4j/CAOlRdSPZ5++tsKbM
+aplk+ceqQtpEFz1MYTtVV4+rlrWaBEA1okJyNZ5/tNOwM7B+XfOZ0xw+uyVi9v4byTZM2Qds
+J+d3YGYLAugTGHISLqQEerD8/gGK+/SL06b2gNedXPHtBAiBKX+Mdy3wFQQIqE9gVgvrFNUE
+CKKoTFoMGqnPBAjDPgLCklNfrwQI3Ek1vSq68w8ECBodu2FOZJVkBAgzwjfSr2N9WQQQTCoQ
+KkAbrS9tnjXn1I3+ZwQIrPx3eINo/YUECIeYWCFskxlYBAiDUdvZXwD3vgQIkEyZbbZWbUUE
+CH4+odl1Isk3BBj68fkqJ0fKJRWVLWuW/O3VE4BOPKwFlaIECFseVTdDUho8BAj+cOKvV2WA
+hgQgaXr+wwq+ItblG0Qxz8IVUXX6PV2mIdHwz4SCCvnCsaIECJhBYxdfLI/XBCDswamPn9MR
+yXi2HVQBineV+GtWVkIoZ2dCLFB9mQRMoAQI0nUR5a5AOJoECA+AunKlAlx8BAi5RtFeF4g1
+FQQIz/ie+16LlQcECOmNuVg5DXjMBAjH2nkfpXZgWwQIVdLuO/+kuHAECO/5rEHmyI9vBBD4
+16BU4Rd3YerDQnHtrwOQBCCkho1XxK5Maz8KLCNi20wvcGt8wsIXlj2h5q9ITBq7IgQQvKVY
+4OfJ7bKbItP2dylwQgQYPIGxwkkbRXNraONYvN19G8UdF35rFOuIBAjf0sKz/618ZQQIxObr
+xJkRe0sECIC+ssnjEb2NBBBI+XM4OntVWGsRV9Td3sFgBAinGwIroo8O0gQQMGAwgc9PaLaG
+gBCiwSTrYQQIVHjfCQgOtygEUIoraFoANfhZgIShpOd/RRxFU4/7xZR5tMdGoYz/g0thR0lM
++Hi88FtFD4mAh/Oat4Ri8B7bv04aokjN2UHz6nPbHHjZ8zIqpbYTCy043GNZBAhOqjyB2JbD
+NwQoR23XCYD9x6E20ChHJRXmaHwyMdYXKl5CUxypl7ois+sy2D7jDukS3wQIsTyyPgJi0GsA
+AAAAAAAAAAAA
+
diff --git a/openssl/crypto/pkcs7/t/msie-enc-01.pem b/openssl/crypto/pkcs7/t/msie-enc-01.pem
new file mode 100644
index 0000000..9abf00b
--- /dev/null
+++ b/openssl/crypto/pkcs7/t/msie-enc-01.pem
@@ -0,0 +1,66 @@
+-----BEGIN PKCS7-----
+MIAGCSqGSIb3DQEHA6CAMIILyAIBADGB8zCB8AIBADCBmTCBkjELMAkGA1UEBhMC
+QVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5lMRowGAYD
+VQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBB
+TkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENBAgIEbjANBgkq
+hkiG9w0BAQEFAARAq8xpbzGHqgX9f4ImK/MhlXvIfGWng7c0dC1YbQDww5kH4K0q
+VTv/qDl79r0O79M6rFEyq1hGnrelrZD+YzghgzCCCssGCSqGSIb3DQEHATAaBggq
+hkiG9w0DAjAOAgIAoAQIn8+kb8zj2JSAggqgxtGA/FLBBRs1wbBPgDCbSG0yCwjJ
+NsFg89/k6xuXo8c5YTwsw8+XlIVq03navpew6XxxzY090rD2OJ0t6HA6GqrIpd8W
+iSh/Atqn0yfLFmkLqgIAPRfzxUxqUocxLpQsLIFp2YNUGE+yps+UZmIjw/WHfdqr
+cWTmSTSvKuy3UkIJZCkGDBpTvqk4BFaHh4oTXEpgpNY+GKxjf9TDN9GQPqQZR7sg
+Qki4t2g4/SaqKl6EoJbpOrMHTQ9LYh2O7+XemEdvXjwpdv0kyffHiaVpBBAtthjT
+bzsu67v0b9h3uDKim13uyT0wx33GEmmmDsJwf/IPH/8eu2Ck5xaafpXGmFqon4uX
+kQtIPaNclFn7/hLxPw2VmBGaC0SYF3U1jyN96EBxdjqy8Aa6ByMXYDW5BcfqniD5
+mYXfw+b81lh1kutxaPaV4YJ9ZlRUW752N7VHo/fG0/fukoe5W9a8kIhgLpygllb/
+GP4oSF4wM6n1/OgRzZj2IWFiobKO4d/tMnh+C+PoEVAuFZcxQwi9GqvsK5OoIjVw
+Nx0XcVSOl1TTYS9SwC7ugMBCab73JiruC24pL78YM+NaIpIQ3On4DokJA2ZHtjBj
+ZIxF4tKA144RvFN6pBd6TVE5XM6KD/Vh9bjSmujtEAfdQ3TedvKJsbZuu0stErbv
+WcRy11I328l557ECU+3eODid62PpuefHp0NTZJGqnYIShBpKRBuyhNxkyjmPfzYc
+KgCQ69fRl3QOqCjobPpMHhVV3li1NrxKGedQcM8XcwpsTsPigp+51o2qgKzBNAqv
+5kGumHOlMKsRfrs7jZCcSaOuEj97pYx08FLEgF23cav39MOQNUEM1dNU+EYslL4o
+3RoSHRjUgPU+2t9c0prS9A/bPBDj/eD8p2kzccB4t1Uyu0s7kJoMwOJ/eNhPY6Eo
+qrED5bCgG97D1Giwt0rlMUozQYH6bw9G5qwP+YflmaGF7yKIBacI5EppxZ7SWHk6
+/VpGu8LDn+PdD9b/hm03lT5p5UEky0DyfQzF3mQ/Eds1WHigamtnrAR6BXyG3e+j
+JlqZnkLLFzx98xicz8kkjr+gRkMyyiS5FnYyvxKzfMtyn2lZ2st9nZGNNgMc9N62
+r5HgNbdDFHuRdKKzV+8kQfuMc3mOPpK1t9TFY+QgrxiB5p6S7VooI97YtP3Pbfkn
+szCEeD3V2G22kdwGnDd0OZGGJlrKt1lusYK4NJphBqLBr8EkMQQbol2a8UnAmuIr
+xKtOVGcMkoXj7ynbjr51BNswzuiFxS2cYU2QSb38Wi8uAYCInuIwaZi+whIslJzA
+bif7CtJpA1BeLOz03fKTKznjAE13/4FDgXumdweENDYPK3kx6QHxjyI06hxRMUK7
+nbi9aWCXmXP3vU7D21dp0XnAMzRQJ565JV3aHRoY7XDa4LePa7PP9ywyafOE5yCW
+7ndqx3J+2JhTDvSFsW8/q3H3iyeFhykuJVS6yugpim58soznxNoixiZkxWvdOVdi
+q1QwppRLv8chjLPNMk8mQvskszPNxTFbyxEJks3EzVGVaQ3wNZDV215D6LgV10+o
+PK/CQkZY2iigAZqUyF44lBFRRThyC+Eyt5c9rKGrkCjhUxIKQDmFhEIFzObgOL8w
+yiEXRLEix1FjqBj0I+esFcCxjqHVFtHtPDSJBmZ5eLnYMKL0by+SYMAa9z0CReIz
+l8JLL6EVIFz8kFxlkGWjr4dnOzhhPOq/mCpp0WxbavDfdhE87MdXJZBnLwoT62QG
+955HlAoEQBOGJbcoHeV0oq2fWNwGwn7ijqqDAbxFBp/sP6TGqpxr56+RWYbgQyq4
+UV6rcULMQP/3axlMbK2Trki/9Pn276O59odWfDcvOozr1WQCPDaXVhzlENc9i3I8
+pKEOVQf/UBczJ0NR9aTEF80dRg2lpXwD0ho4N0AvSiVbgxC7cPZHQwIqvq9LHRUs
+/4n+Vu3SVYU3cAxolUTiCGUSlBfkw+e0iOfkSPjDbZw/a7OBNZpedWKBxlhY91D6
+4g5mNBShMCIKrTFzGN32fSqvHfN24w88cGw1+1sEeym0niVk+NqQs+5DPuM+w6dk
+e66xdPfHauuwGdi1ixu33yZIWJIrNO0WZd+Q4FsJB2K3U/vpCdgnVpcwazrM/obK
+lBNp0r/Nha+WbfxCRXC55onTCqW2pqKA70h2UMDHOrpepU1lj0YMzmotDHSTU3L9
+09VvUMNg9uqfrQ6mSkb9j5Tl8oF2otOw5EzA1YdaKPmgsv62RWLYl80wXcBtHv5o
+Bu+Y6fZToSXVV6nGG0KUvb4sFWlZMB/uvZrv20COII6BLFGF+ju9UXts/nGIXJvV
+Kyvg17khQV0DiJQBcSjFuAdGqXen1POBbGSz6itcTk4TQDYHaOInxAjQTGTiFS9a
+sw0l9RnAXJLsTTnFX05G5fXGawqqRPi1VHk2qWfi+G8BjzrRUGiWjPQIOR3yx5IE
+SN4y9FvpYuflIeHg9urkwp6N+1f0DrJJhJY9ZQ0HTQhziJmIfvbEjNqCl7hEC28+
+F8I5tuViLgfSwcFFCvnS6WFoN4X6QdFdqMCb3ZSNXPiEBgPyLkwzCWArkP7/vARu
+WXllR4nD2Zl30WrfXhStXRigCXn+vk3/Rz7g40qQ8n364n7Kew3N+JZpuxjdfjjd
+2TLc2bp6lvzVEpaOgjuMgpRX8zan/R54ZKqzhvTooX9VHp0HCwlUvkOmdOyncxXi
+P8IA6VF1I9nn762wpsxqmWT5x6pC2kQXPUxhO1VXj6uWtZo1okJyNZ5/tNOwM7B+
+XfOZ0xw+uyVi9v4byTZM2QdsJ+d3YGYLAugTGHISLqQEerD8/gGK+/SL06b2gNed
+XPHtgSl/jHct8BWoT2BWC+sU1aKoTFoMGqnPwz4CwpJTX6/cSTW9KrrzDxodu2FO
+ZJVkM8I30q9jfVlMKhAqQButL22eNefUjf5nrPx3eINo/YWHmFghbJMZWINR29lf
+APe+kEyZbbZWbUV+PqHZdSLJN/rx+SonR8olFZUta5b87dUTgE48rAWVolseVTdD
+Uho8/nDir1dlgIZpev7DCr4i1uUbRDHPwhVRdfo9XaYh0fDPhIIK+cKxophBYxdf
+LI/X7MGpj5/TEcl4th1UAYp3lfhrVlZCKGdnQixQfZkETKDSdRHlrkA4mg+AunKl
+Alx8uUbRXheINRXP+J77XouVB+mNuVg5DXjMx9p5H6V2YFtV0u47/6S4cO/5rEHm
+yI9v+NegVOEXd2Hqw0Jx7a8DkKSGjVfErkxrPwosI2LbTC9wa3zCwheWPaHmr0hM
+GrsivKVY4OfJ7bKbItP2dylwQjyBscJJG0Vza2jjWLzdfRvFHRd+axTriN/SwrP/
+rXxlxObrxJkRe0uAvrLJ4xG9jUj5czg6e1VYaxFX1N3ewWCnGwIroo8O0jBgMIHP
+T2i2hoAQosEk62FUeN8JCA63KIoraFoANfhZgIShpOd/RRxFU4/7xZR5tMdGoYz/
+g0thR0lM+Hi88FtFD4mAh/Oat4Ri8B7bv04aokjN2UHz6nPbHHjZ8zIqpbYTCy04
+3GNZTqo8gdiWwzdHbdcJgP3HoTbQKEclFeZofDIx1hcqXkJTHKmXuiKz6zLYPuMO
+6RLfsTyyPgJi0GsAAAAA
+-----END PKCS7-----
diff --git a/openssl/crypto/pkcs7/t/msie-enc-02 b/openssl/crypto/pkcs7/t/msie-enc-02
new file mode 100644
index 0000000..7017055
--- /dev/null
+++ b/openssl/crypto/pkcs7/t/msie-enc-02
@@ -0,0 +1,90 @@
+
+MIAGCSqGSIb3DQEHA6CAMIACAQAxggHCMIHMAgEAMHYwYjERMA8GA1UEBxMISW50ZXJuZXQxFzAV
+BgNVBAoTDlZlcmlTaWduLCBJbmMuMTQwMgYDVQQLEytWZXJpU2lnbiBDbGFzcyAxIENBIC0gSW5k
+aXZpZHVhbCBTdWJzY3JpYmVyAhBgQJiC3qfbCbjdj5INYLnKMA0GCSqGSIb3DQEBAQUABEACr4tn
+kSzvo3aIlHfJLGbfokNCV6FjdDP1vQhL+kdXONqcFCEf9ReETCvaHslIr/Wepc5j2hjZselzgqLn
+rM1ZMIHwAgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDERMA8GA1UE
+BxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29mdCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNU
+UkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQDExJERU1PIFpFUk8gVkFMVUUgQ0ECAgRuMA0GCSqG
+SIb3DQEBAQUABEBanBxKOvUoRn3DiFY55lly2TPu2Cv+dI/GLrzW6qvnUMZPWGPGaUlPyWLMZrXJ
+xGXZUiRJKTBwDu91fnodUEK9MIAGCSqGSIb3DQEHATAaBggqhkiG9w0DAjAOAgIAoAQImxKZEDWP
+EuOggASCBACBi1bX/qc3geqFyfRpX7JyIo/g4CDr62GlwvassAGlIO8zJ5Z/UDIIooeV6QS4D4OW
+PymKd0WXhwcJI0yBcJTWEoxND27LM7CWFJpA07AoxVCRHTOPgm794NynLecNUOqVTFyS4CRuLhVG
+PAk0nFZG/RE2yMtx4rAkSiVgOexES7wq/xWuoDSSmuTMNQOTbKfkEKqdFLkM/d62gD2wnaph7vKk
+PPK82wdZP8rF3nUUC5c4ahbNoa8g+5B3tIF/Jz3ZZK3vGLU0IWO+i7W451dna13MglDDjXOeikNl
+XLsQdAVo0nsjfGu+f66besJojPzysNA+IEZl6gNWUetl9lim4SqrxubUExdS2rmXnXXmEuEW/HC7
+dlTAeYq5Clqx5id6slhC2C2oegMww3XH9yxHw6OqzvXY6pVPEScEtBMQLgaKFQT+m2SRtbTVFG7c
+QcnUODyVB1IbpQTF1DHeeOX1W/HfpWZym8dzkti6SCyeumHmqO406xDiIMVKtHOqM86nEHuAMZsr
+cLy+ey6TEJvR6S4N8QRzng8JJDZDTJXQN6q84aEudsnOrw2KyOVwPpI6ey4qBsHUgQ8kAFy5lsQa
+WV45h6exgUwbBcKLgPZGFj+OdD2RKJsTb83/UqbJS5Q/lGXhzBlnaYucyJxEprRxbntmcnOEPFJe
++tRDUwOTd7qlJljdhIJL+uDcooL9Ahgo6Cwep6tduekv2cSEohJeTE8Dvy34YRhMbLvnFNdmnpNy
+rNZDYVVxxaKoyd2AfB8NPFZh1VdAYfI3R1QAQ2kXEef5NNIfVQfMzD9akJn4RP+Kv32Qaxm4FrnK
+xmwRyGJShavIBc2ax+F1r1+NZXuSBHn5vfoRTxOk0ST4dXsw74dnlYUMRaSu4qqUdM9jsXSyeX4Z
+gQgkR2bkaYO6ezFgenFIa7QWVw8rXZAEZ5aibCxbnY1VE41PYIvhlLdbFJhH9gY22s+fFAuwnzyA
+SRjC40A9aAEItRlaPStWSGiqlLRgNkBBwdpv2l2YPBd2QzHx6ek6XGrvRJuAC+Nh62rtQKwpNH54
+YAOHW55maBFW2SQ3TF+cZ6NbbqhCmHTyyR7mcSYc9sXSVDWEhYKQ1iyU870zhHWVpvglZizZetJC
+ZFjYex3b1ngVdcgargOvpPq9urCKKi2mbkqv/EFpzSWGXkKSpfCG/XfMnEOtkNrB8S06vnk2JcJB
+OBqJot+uuSH5hOg0vTpxX2DuONJSiWSWyfRE/lTfJJFXwhod7SXclUyXPeSyibcSic2hVAzDmwjD
+31js/j2k02PI/agPhr3UQ8cMgcNAiaoCKbNaWfn6BGbCAbTchxzUlo2cSJiLlrX2IDZmfXbXmZCo
+m1smWIG+BIIEALiuAxDb6dWLAYyVBoN9hYI4AiPeZAY9MtvQ6AV8o2/EFm6PvYGXy3Hei5830CH0
+PBeX7Kdd6ff1y33TW/l5qSkIL1ULTGR7okFfJePHDmq1dFt6/JOMptiQ8WSu7CsJQvZ9VTFXeYFc
+ZqCPPZc1NrPegNK70Zf9QxWIbDAevJ5KLBf1c6j8pU2/6LnvDY6VjaTvYSgr7vTR8eVzH4Rm77W0
+iOHxg5VcODv6cGSVyuvbX8UAGo8Cmb58ERDtBDJBQXVpWKLNAuDJ9GX8n2zNkpjZLbPSkcmuhqGa
+BJBE/BaCTkUQWlY9dIbRtEnxIU1mfbPPdx1Ppa8DqGDjSOsQdKcKYNNZtayEw++EIpmpdBNsKphC
+fB8UEK2Wkk4ZVW+qyGoi/r0MFsvO1NmSOOZ0o/jy/YHmoeURHhPy97AO3eVTkEAa5CfJEJybmo56
+7CDw/FwoGAUCgsoz7rlxzMudr/IhHIH+APinncxXlHO2ecvHD9i8DaHGA8tVifgsUhqQoZieULut
+eF94O5UAxOkv41UZssYTwN4nYrN1QkesZl3BX4ORS4EE30/PQ23ARf3WZptZrCJevGm2ZYzGeh8x
+g17mCDfiLO+bff4qP/4mC96Pu4ia6j4to5BwKIJS/+DCuoD8WeSKF4pugXQkMUiHdQnNnVP9Sp2O
+/4ly5mO8JzrQC59V2bnTNBqPhpno8kfJvK5TypPSVC+bTzern3rJ6UceB3srcn9zxKx9GdNydJQj
+yWjv8ec3n3d1nuQwhz5Q053NBhIjwoGg3Go7LO6i78ZOlpF7dcoAO13NfHLyNjnyHCaiWtVRTct9
+rLf5vN00urSn8YJngHk1eTKK8nHGIcOg6YdYDOD2nE5XwRijKmieG8Xa3eKRzfbL06GrBQENle6J
+mC131bp3cRVxpjq+o6RAbGoMm4yICsL4eTarCQrsyHmoPHqr91UHo91avyxU7knWmEhX27ybmsrs
+8aeZwPHixL14TeyhruCqRVvkf1Ks7P+z8MPUboGNqQe2WLN8ktCGEr15O8MJR/em86G03Jfo4oaw
+/DVUH5RwLT6acedOGuzMh/2r8BcmemhVQ8/cWvV4YJ0tOW4hzyVHC5hQf8sZ3LzxXLH6Ohnrbprh
+xvrdbaSdChWZDDP0bCCbxEhkwuBkBeKZrMbwRTP+TPTPYLVTH/CmKLzKh/114tkGkyO3hHS4qExU
+V39F2Sj4mylx+hD0+20D9pntpNi7htccGlOm6yNM69at/3+kLgJJyoIlaxLcCUYHNMifDt+T3p/t
+5U4XmD53uUQ6M8dvj/udqPekNSUfse15yrd9pjOt5PcJuqW28q0sFHf9pHIgz3XZFMe5PD7ppw6r
+S+C6Ir4PrYIEggQA7ZDVtiCm+BbtNNB/UJm79/OQ5mp5bTI0kPmDeycaWTa0Ojpum+c/dpG/iJOB
+DICj7jHOXSHT7JlGyX6aSFJUltucAnZvwzhPDmdDaIDiKSk85GqgdDWVfGosSCX9Ph/T3WpIxnwf
+WSDRtIHkWTjly+pe4yy5K6/XISy/L5Zh/fhiI5fjHjgzmlibs2ru4nVw6hBhUvlSSe2BEs5d9h/y
+NH8Wy3qvb2D3jh7hkepFtZJGNTHp8ZUC7Ns2JIpQYObsaxdI65i3mMOu7fRwI+0/4ejsWhP6KCEi
+LgwvLg0qM82ma6YB7qHAHboaczRVEffDcJUG4a5uycB0DoZFn+uEaEFyili20hCn4hVfsqUQk2PT
+8Mo1tSl5e30xI1YJZrRgiJm9nHRX6fLizngP+ILJLPHZsPvlSVIfY+/v/FR8feKOjaGhyGF51BAx
+aM2NIQ4jMP5/X+U5gQybi0E6u7rroDhaHsKmCMgXqszwXWCpedA/sEbeHpiTC59YlPPSlIOMc9vP
+Ko/mQCfWy/9icUaIfKQldvkllUxxNkqu6AbIpHVscbAEzSPs5xbQXU8EZNNCDisFnnpY3nQ3eLnl
+m89saTJxRb7NWHRMlmPv7qgD7uMIq3vdOGA7i5wT9MeoNIgK1/DsgH30s6RWjJy4YyyLmRTXPzbj
+hbQVpEmiMRbEidIvUx2OjKVxVQIcgtLsa2lvHQ4XL1cpLr5GVtOgy0fMg5OCDUUDsvjgjgLQ3P2U
+p2nVY5FM6/QpPc5DTLuuR9ekI2/c9Biz09RtcYDUQK2ajdo8h1IyKqHFoB7h48OXxXKKY94DY0TG
+x6PonB/epj8orAw4QKmm5M0vXYwBOqRymCTHTqOJGObdLx1euFFyqguzHJOU2gAGZI0z9Lg1yRuF
+yhdPZyuniIcmtLNxRZ1duYHErcAyX56qndmLXt7UVkATai/rIMuoJLfAsUnVuTUS5p7tJM754UZT
+7lTcXvDJgOUNnBRaIcxC3pxvbrYDJ2iFJ72xkxUP2p74gucqg25XnCVmQuLg6zDDxF6CLuw9isxy
+Xg4pkneMN//7fpp8GYl9nyZm2yqYYM+jcw0fcVc64L+X4w/gL3H2UMGgxIHSJp7HIG7VKHtXrNyj
+dPXXPVUsMsAAimqOr0Lr2sZWirfuivLaPTqhbkvG5PF7K3gT80AOIcd/6EIHBy2hZ7ukfjHmdP4L
+yQOhTQklaKzGHI0mypq0uFLWJOUlZnVrMiLP1xrWkpC8Ro9eo6mfjjQ45z8adC43a47klwTEzvod
+3rNEFIGJJUEjAN3mbqie7IxoSJknBBJK0D9lZEQ8lZWlq7vuN8JdqPM6xh155jMVsPwjLK6Tzkj5
+BpRD9Tgm3u6HPQSCBADgkWEN75Mu9TGosXY0xm1k6K6sPv8L949CrLWo4r1I2LA072bTGvQP28Vs
+hUA76jgcT1ocC++9PoktIK10YCq5w+FfMAQ04KeCXuAdmiY2iAT4Slea61PMCMta3mVGyLUZCLEm
+P+I0UKR5mlO0fGEcjU9j8TmbjZqxNFqloLsU7oSi7Os0EtYHkdAVrExUyOc/ZDie6fBjdLTmLdCm
+bE9JNwjlbXypdTZupGgLNhKGDIskUAAMwZYayI6YfSIMkNCeAYTnjOuGZZ1msCXGXsfMBR1sfUIj
+9UeGjwD8gq+UVVHX/oeoH/m0eJ5ppqi3+nUlgc9DvpYsC/Fg0G2KuYb9B+VJ+a4GMzQSPREoFtQp
+B9dtLkBb7Ha/hpGWTIdqzW0eAo5llyN8FNvl2Fu2IcLaNmWFO69gLjRKQopp0dvFOuwAVI6fvGDj
+p1WigoNbFZl8N+iiWmzKOjoG2ZLbez1clZCms/JPJrXhEMMOxWpVzkQyN336VWHmGgMcjaKCGSeA
+2nnESIGuiCXMrkHlGfabYIsKcHFCo2t13uXyZPf0zSPTkuD0Eh92wqC9pvA3gvrrCUfo9Mn3bs+e
+KWKmDlpcs8mDn032oIg+zrQhIduMqXVn3evzeVM3B5MBOGMvg51/SXg7R+MC/463juQQEb9IVe/I
+YGnO//oWm9lw/377Af/qH+FnN02obJw1FvesQIs9e5RHNQykKbO+vmVJQl1nd9DZWrHDNO7/80Yz
+2hCm7Tws5nSRN2iFlyRaYJHr7ypxkU2rCak2r6ua7XDwu1qU2RT3+qPjT1RuxQ2oTlHyGkKPMZGC
+Rc+CSWz5aeeCmHZVwdb3nC8YpfsujMiYqygLeuQ82pjKuR7DIKGmnfcOLdv5F+Ek2Wyy0D98iSgk
++aoQGYLhL9llU13pn21uRsDY5uGcXiIw1IETFlTdgENEv8futZuJsegrp7fmFXyNoNyFNyypeDrM
+6ZqR4vKxFjg3tKKeVpkw/W4EAklzMxmNiazGNDBHsnYV3rwPlKa+HeeE2YxnsKwGLCNgRYUXTaJk
+461vS160z3dvh/mLfdZ7MYCkmO3bNE3ELUDAw7YQkSuo9ujzdFKte9LC34sjg9fOex3ThAg5Y50n
+wYm4zBmGM7yEqL8O6QgnM6tIDFS9XryDaLNzcGhMWqMvhzO6sC/AA2WfLgwS517Cp03IkJQWqG9q
+w52+E+GAtpioJfczEhlv9BrhjttdugRSjJrG8SYVYE4zG3Aur5eNBoGaALIOHOtPw8+JovQmIWcF
+oaJ/WQuglFrWtew51IK6F8RiHAOBVavZOuZcO7tV+5enVfreOd0rX8ZOy4hYmHhmF1hOrrWOn+Ee
+E0SYKonXN01BM9xMBIIBSLCvNAppnGPTUGjwbMJRg1VJ2KMiBWH5oJp8tyfIAxMuWFdtaLYbRSOD
+XbOAshPVK8JAY8DQDkzqaCTAkLTfSRAt9yY6SbUpMsRv7xa8nMZNJBJzJT9b/wNjgiOJgaGuJMkV
+2g/DX2jfP3PrMM/Sbnz7edORXHj1Pa5XTT8nG5MS0FuZgvevdq3o/gVVAz+ZCKOH3ShMzZvfp01l
+SX5gaJTflmU6cdNwtn2yZ6IScF7OrjUeA9iEoSVR9dQcA+4lB3RAG3LMwcnxXY35D7+PMJzHIZdF
+cSnq+n03ACY2/E/T31iijRH29rvYHGI+mP/ieYs45iq4fTWo6i1HofeWLdP0fX7xW3XO0/hWYFiw
+BxKu66whAbRhaib3XJNvetVs25ToYXyiDpjG+cd5rCMei8sGQwTBj9Zeh0URoeMW1inTP0JvCmMU
+rZgAAAAAAAAAAAAA
+
diff --git a/openssl/crypto/pkcs7/t/msie-enc-02.pem b/openssl/crypto/pkcs7/t/msie-enc-02.pem
new file mode 100644
index 0000000..279c5d8
--- /dev/null
+++ b/openssl/crypto/pkcs7/t/msie-enc-02.pem
@@ -0,0 +1,106 @@
+-----BEGIN PKCS7-----
+MIAGCSqGSIb3DQEHA6CAMIITQAIBADGCAcIwgcwCAQAwdjBiMREwDwYDVQQHEwhJ
+bnRlcm5ldDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNDAyBgNVBAsTK1ZlcmlT
+aWduIENsYXNzIDEgQ0EgLSBJbmRpdmlkdWFsIFN1YnNjcmliZXICEGBAmILep9sJ
+uN2Pkg1gucowDQYJKoZIhvcNAQEBBQAEQAKvi2eRLO+jdoiUd8ksZt+iQ0JXoWN0
+M/W9CEv6R1c42pwUIR/1F4RMK9oeyUiv9Z6lzmPaGNmx6XOCoueszVkwgfACAQAw
+gZkwgZIxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQH
+EwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRzb2Z0IFB0eSBMdGQxIjAgBgNVBAsT
+GURFTU9OU1RSQVRJT04gQU5EIFRFU1RJTkcxGzAZBgNVBAMTEkRFTU8gWkVSTyBW
+QUxVRSBDQQICBG4wDQYJKoZIhvcNAQEBBQAEQFqcHEo69ShGfcOIVjnmWXLZM+7Y
+K/50j8YuvNbqq+dQxk9YY8ZpSU/JYsxmtcnEZdlSJEkpMHAO73V+eh1QQr0wghFz
+BgkqhkiG9w0BBwEwGgYIKoZIhvcNAwIwDgICAKAECJsSmRA1jxLjgIIRSIGLVtf+
+pzeB6oXJ9GlfsnIij+DgIOvrYaXC9qywAaUg7zMnln9QMgiih5XpBLgPg5Y/KYp3
+RZeHBwkjTIFwlNYSjE0PbsszsJYUmkDTsCjFUJEdM4+Cbv3g3Kct5w1Q6pVMXJLg
+JG4uFUY8CTScVkb9ETbIy3HisCRKJWA57ERLvCr/Fa6gNJKa5Mw1A5Nsp+QQqp0U
+uQz93raAPbCdqmHu8qQ88rzbB1k/ysXedRQLlzhqFs2hryD7kHe0gX8nPdlkre8Y
+tTQhY76LtbjnV2drXcyCUMONc56KQ2VcuxB0BWjSeyN8a75/rpt6wmiM/PKw0D4g
+RmXqA1ZR62X2WKbhKqvG5tQTF1LauZeddeYS4Rb8cLt2VMB5irkKWrHmJ3qyWELY
+Lah6AzDDdcf3LEfDo6rO9djqlU8RJwS0ExAuBooVBP6bZJG1tNUUbtxBydQ4PJUH
+UhulBMXUMd545fVb8d+lZnKbx3OS2LpILJ66Yeao7jTrEOIgxUq0c6ozzqcQe4Ax
+mytwvL57LpMQm9HpLg3xBHOeDwkkNkNMldA3qrzhoS52yc6vDYrI5XA+kjp7LioG
+wdSBDyQAXLmWxBpZXjmHp7GBTBsFwouA9kYWP450PZEomxNvzf9SpslLlD+UZeHM
+GWdpi5zInESmtHFue2Zyc4Q8Ul761ENTA5N3uqUmWN2Egkv64Nyigv0CGCjoLB6n
+q1256S/ZxISiEl5MTwO/LfhhGExsu+cU12aek3Ks1kNhVXHFoqjJ3YB8Hw08VmHV
+V0Bh8jdHVABDaRcR5/k00h9VB8zMP1qQmfhE/4q/fZBrGbgWucrGbBHIYlKFq8gF
+zZrH4XWvX41le5IEefm9+hFPE6TRJPh1ezDvh2eVhQxFpK7iqpR0z2OxdLJ5fhmB
+CCRHZuRpg7p7MWB6cUhrtBZXDytdkARnlqJsLFudjVUTjU9gi+GUt1sUmEf2Bjba
+z58UC7CfPIBJGMLjQD1oAQi1GVo9K1ZIaKqUtGA2QEHB2m/aXZg8F3ZDMfHp6Tpc
+au9Em4AL42Hrau1ArCk0fnhgA4dbnmZoEVbZJDdMX5xno1tuqEKYdPLJHuZxJhz2
+xdJUNYSFgpDWLJTzvTOEdZWm+CVmLNl60kJkWNh7HdvWeBV1yBquA6+k+r26sIoq
+LaZuSq/8QWnNJYZeQpKl8Ib9d8ycQ62Q2sHxLTq+eTYlwkE4Gomi3665IfmE6DS9
+OnFfYO440lKJZJbJ9ET+VN8kkVfCGh3tJdyVTJc95LKJtxKJzaFUDMObCMPfWOz+
+PaTTY8j9qA+GvdRDxwyBw0CJqgIps1pZ+foEZsIBtNyHHNSWjZxImIuWtfYgNmZ9
+dteZkKibWyZYgb64rgMQ2+nViwGMlQaDfYWCOAIj3mQGPTLb0OgFfKNvxBZuj72B
+l8tx3oufN9Ah9DwXl+ynXen39ct901v5eakpCC9VC0xke6JBXyXjxw5qtXRbevyT
+jKbYkPFkruwrCUL2fVUxV3mBXGagjz2XNTaz3oDSu9GX/UMViGwwHryeSiwX9XOo
+/KVNv+i57w2OlY2k72EoK+700fHlcx+EZu+1tIjh8YOVXDg7+nBklcrr21/FABqP
+Apm+fBEQ7QQyQUF1aViizQLgyfRl/J9szZKY2S2z0pHJroahmgSQRPwWgk5FEFpW
+PXSG0bRJ8SFNZn2zz3cdT6WvA6hg40jrEHSnCmDTWbWshMPvhCKZqXQTbCqYQnwf
+FBCtlpJOGVVvqshqIv69DBbLztTZkjjmdKP48v2B5qHlER4T8vewDt3lU5BAGuQn
+yRCcm5qOeuwg8PxcKBgFAoLKM+65cczLna/yIRyB/gD4p53MV5RztnnLxw/YvA2h
+xgPLVYn4LFIakKGYnlC7rXhfeDuVAMTpL+NVGbLGE8DeJ2KzdUJHrGZdwV+DkUuB
+BN9Pz0NtwEX91mabWawiXrxptmWMxnofMYNe5gg34izvm33+Kj/+Jgvej7uImuo+
+LaOQcCiCUv/gwrqA/FnkiheKboF0JDFIh3UJzZ1T/Uqdjv+JcuZjvCc60AufVdm5
+0zQaj4aZ6PJHybyuU8qT0lQvm083q596yelHHgd7K3J/c8SsfRnTcnSUI8lo7/Hn
+N593dZ7kMIc+UNOdzQYSI8KBoNxqOyzuou/GTpaRe3XKADtdzXxy8jY58hwmolrV
+UU3Lfay3+bzdNLq0p/GCZ4B5NXkyivJxxiHDoOmHWAzg9pxOV8EYoyponhvF2t3i
+kc32y9OhqwUBDZXuiZgtd9W6d3EVcaY6vqOkQGxqDJuMiArC+Hk2qwkK7Mh5qDx6
+q/dVB6PdWr8sVO5J1phIV9u8m5rK7PGnmcDx4sS9eE3soa7gqkVb5H9SrOz/s/DD
+1G6BjakHtlizfJLQhhK9eTvDCUf3pvOhtNyX6OKGsPw1VB+UcC0+mnHnThrszIf9
+q/AXJnpoVUPP3Fr1eGCdLTluIc8lRwuYUH/LGdy88Vyx+joZ626a4cb63W2knQoV
+mQwz9Gwgm8RIZMLgZAXimazG8EUz/kz0z2C1Ux/wpii8yof9deLZBpMjt4R0uKhM
+VFd/Rdko+JspcfoQ9PttA/aZ7aTYu4bXHBpTpusjTOvWrf9/pC4CScqCJWsS3AlG
+BzTInw7fk96f7eVOF5g+d7lEOjPHb4/7naj3pDUlH7Htecq3faYzreT3CbqltvKt
+LBR3/aRyIM912RTHuTw+6acOq0vguiK+D62C7ZDVtiCm+BbtNNB/UJm79/OQ5mp5
+bTI0kPmDeycaWTa0Ojpum+c/dpG/iJOBDICj7jHOXSHT7JlGyX6aSFJUltucAnZv
+wzhPDmdDaIDiKSk85GqgdDWVfGosSCX9Ph/T3WpIxnwfWSDRtIHkWTjly+pe4yy5
+K6/XISy/L5Zh/fhiI5fjHjgzmlibs2ru4nVw6hBhUvlSSe2BEs5d9h/yNH8Wy3qv
+b2D3jh7hkepFtZJGNTHp8ZUC7Ns2JIpQYObsaxdI65i3mMOu7fRwI+0/4ejsWhP6
+KCEiLgwvLg0qM82ma6YB7qHAHboaczRVEffDcJUG4a5uycB0DoZFn+uEaEFyili2
+0hCn4hVfsqUQk2PT8Mo1tSl5e30xI1YJZrRgiJm9nHRX6fLizngP+ILJLPHZsPvl
+SVIfY+/v/FR8feKOjaGhyGF51BAxaM2NIQ4jMP5/X+U5gQybi0E6u7rroDhaHsKm
+CMgXqszwXWCpedA/sEbeHpiTC59YlPPSlIOMc9vPKo/mQCfWy/9icUaIfKQldvkl
+lUxxNkqu6AbIpHVscbAEzSPs5xbQXU8EZNNCDisFnnpY3nQ3eLnlm89saTJxRb7N
+WHRMlmPv7qgD7uMIq3vdOGA7i5wT9MeoNIgK1/DsgH30s6RWjJy4YyyLmRTXPzbj
+hbQVpEmiMRbEidIvUx2OjKVxVQIcgtLsa2lvHQ4XL1cpLr5GVtOgy0fMg5OCDUUD
+svjgjgLQ3P2Up2nVY5FM6/QpPc5DTLuuR9ekI2/c9Biz09RtcYDUQK2ajdo8h1Iy
+KqHFoB7h48OXxXKKY94DY0TGx6PonB/epj8orAw4QKmm5M0vXYwBOqRymCTHTqOJ
+GObdLx1euFFyqguzHJOU2gAGZI0z9Lg1yRuFyhdPZyuniIcmtLNxRZ1duYHErcAy
+X56qndmLXt7UVkATai/rIMuoJLfAsUnVuTUS5p7tJM754UZT7lTcXvDJgOUNnBRa
+IcxC3pxvbrYDJ2iFJ72xkxUP2p74gucqg25XnCVmQuLg6zDDxF6CLuw9isxyXg4p
+kneMN//7fpp8GYl9nyZm2yqYYM+jcw0fcVc64L+X4w/gL3H2UMGgxIHSJp7HIG7V
+KHtXrNyjdPXXPVUsMsAAimqOr0Lr2sZWirfuivLaPTqhbkvG5PF7K3gT80AOIcd/
+6EIHBy2hZ7ukfjHmdP4LyQOhTQklaKzGHI0mypq0uFLWJOUlZnVrMiLP1xrWkpC8
+Ro9eo6mfjjQ45z8adC43a47klwTEzvod3rNEFIGJJUEjAN3mbqie7IxoSJknBBJK
+0D9lZEQ8lZWlq7vuN8JdqPM6xh155jMVsPwjLK6Tzkj5BpRD9Tgm3u6HPeCRYQ3v
+ky71MaixdjTGbWTorqw+/wv3j0KstajivUjYsDTvZtMa9A/bxWyFQDvqOBxPWhwL
+770+iS0grXRgKrnD4V8wBDTgp4Je4B2aJjaIBPhKV5rrU8wIy1reZUbItRkIsSY/
+4jRQpHmaU7R8YRyNT2PxOZuNmrE0WqWguxTuhKLs6zQS1geR0BWsTFTI5z9kOJ7p
+8GN0tOYt0KZsT0k3COVtfKl1Nm6kaAs2EoYMiyRQAAzBlhrIjph9IgyQ0J4BhOeM
+64ZlnWawJcZex8wFHWx9QiP1R4aPAPyCr5RVUdf+h6gf+bR4nmmmqLf6dSWBz0O+
+liwL8WDQbYq5hv0H5Un5rgYzNBI9ESgW1CkH120uQFvsdr+GkZZMh2rNbR4CjmWX
+I3wU2+XYW7Yhwto2ZYU7r2AuNEpCimnR28U67ABUjp+8YOOnVaKCg1sVmXw36KJa
+bMo6OgbZktt7PVyVkKaz8k8mteEQww7FalXORDI3ffpVYeYaAxyNooIZJ4DaecRI
+ga6IJcyuQeUZ9ptgiwpwcUKja3Xe5fJk9/TNI9OS4PQSH3bCoL2m8DeC+usJR+j0
+yfduz54pYqYOWlyzyYOfTfagiD7OtCEh24ypdWfd6/N5UzcHkwE4Yy+DnX9JeDtH
+4wL/jreO5BARv0hV78hgac7/+hab2XD/fvsB/+of4Wc3TahsnDUW96xAiz17lEc1
+DKQps76+ZUlCXWd30NlascM07v/zRjPaEKbtPCzmdJE3aIWXJFpgkevvKnGRTasJ
+qTavq5rtcPC7WpTZFPf6o+NPVG7FDahOUfIaQo8xkYJFz4JJbPlp54KYdlXB1vec
+Lxil+y6MyJirKAt65DzamMq5HsMgoaad9w4t2/kX4STZbLLQP3yJKCT5qhAZguEv
+2WVTXemfbW5GwNjm4ZxeIjDUgRMWVN2AQ0S/x+61m4mx6Cunt+YVfI2g3IU3LKl4
+OszpmpHi8rEWODe0op5WmTD9bgQCSXMzGY2JrMY0MEeydhXevA+Upr4d54TZjGew
+rAYsI2BFhRdNomTjrW9LXrTPd2+H+Yt91nsxgKSY7ds0TcQtQMDDthCRK6j26PN0
+Uq170sLfiyOD1857HdOECDljnSfBibjMGYYzvISovw7pCCczq0gMVL1evINos3Nw
+aExaoy+HM7qwL8ADZZ8uDBLnXsKnTciQlBaob2rDnb4T4YC2mKgl9zMSGW/0GuGO
+2126BFKMmsbxJhVgTjMbcC6vl40GgZoAsg4c60/Dz4mi9CYhZwWhon9ZC6CUWta1
+7DnUgroXxGIcA4FVq9k65lw7u1X7l6dV+t453Stfxk7LiFiYeGYXWE6utY6f4R4T
+RJgqidc3TUEz3EywrzQKaZxj01Bo8GzCUYNVSdijIgVh+aCafLcnyAMTLlhXbWi2
+G0Ujg12zgLIT1SvCQGPA0A5M6mgkwJC030kQLfcmOkm1KTLEb+8WvJzGTSQScyU/
+W/8DY4IjiYGhriTJFdoPw19o3z9z6zDP0m58+3nTkVx49T2uV00/JxuTEtBbmYL3
+r3at6P4FVQM/mQijh90oTM2b36dNZUl+YGiU35ZlOnHTcLZ9smeiEnBezq41HgPY
+hKElUfXUHAPuJQd0QBtyzMHJ8V2N+Q+/jzCcxyGXRXEp6vp9NwAmNvxP099Yoo0R
+9va72BxiPpj/4nmLOOYquH01qOotR6H3li3T9H1+8Vt1ztP4VmBYsAcSruusIQG0
+YWom91yTb3rVbNuU6GF8og6YxvnHeawjHovLBkMEwY/WXodFEaHjFtYp0z9Cbwpj
+FK2YAAAAAA==
+-----END PKCS7-----
diff --git a/openssl/crypto/pkcs7/t/msie-s-a-e b/openssl/crypto/pkcs7/t/msie-s-a-e
new file mode 100644
index 0000000..0067794
--- /dev/null
+++ b/openssl/crypto/pkcs7/t/msie-s-a-e
@@ -0,0 +1,91 @@
+
+MIAGCSqGSIb3DQEHA6CAMIACAQAxggHCMIHMAgEAMHYwYjERMA8GA1UEBxMISW50ZXJuZXQxFzAV
+BgNVBAoTDlZlcmlTaWduLCBJbmMuMTQwMgYDVQQLEytWZXJpU2lnbiBDbGFzcyAxIENBIC0gSW5k
+aXZpZHVhbCBTdWJzY3JpYmVyAhBgQJiC3qfbCbjdj5INYLnKMA0GCSqGSIb3DQEBAQUABECjscaS
+G0U299fqiEAgTqTFQBp8Ai6zzjl557cVb3k6z4QZ7CbqBjSXAjLbh5e7S5Hd/FrFcDnxl1Ka06ha
+VHGPMIHwAgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDERMA8GA1UE
+BxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29mdCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNU
+UkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQDExJERU1PIFpFUk8gVkFMVUUgQ0ECAgRuMA0GCSqG
+SIb3DQEBAQUABECsyHXZ1xaiv0UQRvOmVYsaF38AL2XX75wxbCsz5/wOg7g3RP4aicZxaR4sBog0
+f2G1o9om/hu+A0rIYF/L4/GUMIAGCSqGSIb3DQEHATAaBggqhkiG9w0DAjAOAgIAoAQIsozQrnwj
+cc2ggASCBAAQz/LPoJe/+iYWeTwSebz6Q9UeKZzQ2UWm7GLtEM3s3c9SCvpmkwIRdEhLjWaBJMyI
+DiL7t1I1vMf9inB8LXgAcIEYkpNScjS8ERA9Ebb7ieNKSBg7w7B8ATHFxLSlDADqRgoZrB1Ctfgf
+ximp3EgxTgnhtyQhZxXW7kBQyFRwumplrJXOp7albP7IothrOKncw30IJT1fwPxWNMItI9juXF0U
+CbWVSjPzGBo4+XNXMvUO6MplOQEz/ywEQ9E8OZAQex1Zw9qq5ppsXB2pMsYV5sLJGikukMYKquiz
+3YK+tN6J8ahLcDUs+VGwqvZi17gpBTlbEP+ZmXJpnO63t1yTEB0V5AZcRKWUOhzlCBM5YUagqNoY
+cpsmSvOK6bYzkUKOrzWpDCAtGZ/Dvul5dTZZmxs2WpM+iyeHXMxO3huy8K1brPTqt1f1sHhuq1jD
+1eXedaCjIgUW9qV18vNAQCof/Yb6T/1fxztf/jD7pPLQJ+7LJkKCAEHGcaizpoKqhYcttaEhLq1G
+O+Ohqf7yFegMdTJ3wwP324w5ZYSU5fLo2Z34/Edf6EGvXyTIqVfAmEBALd6JGVdN5GlYYTxrL+eO
+P80Z4ao4YKoxwEmRp5bmQsQ8B29QhOFKmC6eiG5B96qLMtp7Zmu1grDNxTd6OXShWVwYARD0/B1P
+Sy0PAfk9Gb4fAkO9fZJDQYZ7s0mM5iOPEeSR7820TolOb+KfRabLA9d714jsc2jEykKlpP66Bh4j
+aCsyqJ0uUQcE8SnzrKAqGwgWiCGQpiTa+HBiP6eRlRGOKQj5Y06vcNx6Ija4cGe6+yCN8HV8tCY0
+okZK98NQCl5t79R/ZB2c3NvBJH+/g3ulU48ikT3tVmDxE3mOZofZyGFEM99P+YCMScLDxTl3hzGy
+0YkI8U855P7qOAbcFfh2T5n+LSELwLhbkymEfZT917GWTfmypBWMvJx0WHeDhKwQYPdzbKgWETnc
+yeKasaCW+oLdhBwrd6Ws2r4MA8cwiYXDLbwYmCxJA8VF++8kubF2HJOjSyMBS+QT2PSV/0D9UWoi
+Vfk7R4OvWBJVvq7nV+lXS0O5igjExxlmx1OaBfg7+Cr/MbK4zVNrKSJn82NnKKt6LC6RaTmvFYay
+0sDFxQ7Xo+Th6tDNKmKWJt6Kegfjc+qTWJTKb3kL+UI8vS0zTLy1+M/rZ4ekos/JiS5rYIcAswvg
+58kBgp/0rc6upBeWjBaK5O0aLAeBQfLulo1axWX04OSVKmYeoAltyR6UO9ME3acurQyg7Ta24yqO
+whi/PrIaEiO7dsWvFtzsshVzBLic02NlAkPkMUzliPYnZHWQglDAVxL5K2qhvK1OFCkQpIgBsBDM
+6KYRL/mkBIIEALIl927rIkaN37/BQIcxLcSa05YfC0Hl3mxWESt1A0D4lA37A9S8EbYmDfAYlMc0
+3HhZGdZEtawfpJFyDHzNZceNWBch6nxeNZCY4YFdsbzuGS0RKpwNA9S/czOJ4p9ymBCxuhGepI3U
+PKbC8C749Www1/wMdAot1n+K7M/PBGR8hWmaH5SS7U3yMwAB1fq2NDjx4ur+Um+MclSdN01MDXzG
+EO+eAo1pdAY8479234l8dB2YVAhZ1ZlJ4KmbqMKJrGJXnQUEYS6/cTDRjsUocsoW7uGg1ci2GiHa
+qjlkfpBfie3SdhFW/K8hwAH0HALs56oFN66wUkP/AaJAPfIUNhR6RpHKzZ9zCC42oB2mNawQRMnF
+ETBl1s/SwMxLKRp7jAfKs4NZxSY6I9z/2dTpzS3tsHMjxVDuxkolvRNWBILEMeL1CBvip2HhmoUw
+/Sz5NDgyzk1aQLV6DQNJ2RZLMZDRCtSwZSBu6lhhSgTJGazP0+NbqXXC5aQTrqrFIcWyDXz+ADle
+kszzYM/gSaQTCALTwfDDaU9Ek3xVgW+XBtExtJ3U+0AN3l0j86rUIdIvp6eWdxWQqv9LtpoorKMD
+KfUc5PYV09Z1JgsT4X51Zzq+74l5dz7udIM7UNbdTpmRm9PDj3TUbGCvNR9hqOEGTLbkvb1ZR24a
+h6uGRl2znB25IpDAGRhNRb9is/pO2tvHwHTDMOjrgvZG/pNvXgSUxz0pRjUjXIcqBe2X2gcQfeal
+r8gY76o83WEGL6ODryV9vTQVHt52+izgpYoBZaVlpgqbZl54c+OE0Zxf9RwXwDbcYu5Ku5E0MPL0
+qUjc0y2+Y6E4P5bAWaZGMGT+ORkyVUzcaWmM/+XlO7PER5wrWlCIMZCX1L/nvioY0q0CKqALn7DJ
+QU+qenbwrb6uwS7uNZY6V86s0aDYpU7yRyqxC5SbuyNJb02gdxUCgpIscFaMUjMVRml4M4BIjX/b
+U+HgHoVMUm8SnN9gRcT2izPrgOGVcMTJjfenzoCKoCPo9RjgGMctgB4DvKamErNU7OrilIfuoqzE
+PNSeP9SPw/zkDmNvMebM499We9CVnsHUWqF00/ZJWoua77+0f1bLS/tmci1JBvIcMo/4SJvgH+KF
+o0gijP9gqAPd5iCOnpnJlHUqRIym42SmyKEDuzdSwXKjAR6j7uXda39JyMJr8gGzEsu0jYRkAmj1
+YdiqwKXUcLMkcj1AKeU/PxTUVw0YKsv/rowrPYww3xQUWqNivrXB7GCHE3BzsYNdHsmziaGIXQbA
++EBHdkuKrM8BcC+fxhF/l/KUxngsD1E75IcUv8zFDF+sk4CBYHqks9S4JYlcubuizqsILbdGzIMN
+Z7w34k0XT+sEggQAyzr8MHeIJGsT+AYnZr08PeTbyr01JEoT7lPYT6PzX4F63QKKDl+mB+PwLMzY
+CXrxZcUmuay6/MV8w/f5T6vQXdoSw5puWodBYwVReYh1IaEN+jiTapm9YBVmcIsJPO6abHowknSV
+OWSvST0AtAX57fFOTckm+facfBK9s9T1lUUgF44Bh5e8f9qKqfOV44nqdCOEyUm0Dao497ieN4Eg
+XBLNvOZY9+irMiXjp0lcyFvhrJOczfyCr9EiiaiH1TfSzKGKsf2W84iKn/JH6x2eOo7xjwJ40BQD
+c6S1cUNEuqBhP6by0FioOXYOKVyifpxk84Eb+F/4CNdTJTvCPwsiegdfsX/Q53DvKVtXp9Ycam5J
+TmKRHXK/bMHF4ONv3p/O/kn/BqRx+fbbP2eMX8Z1F/ltHKfp6B+06HljUwQLBJs9XtCfqH5Zgdz9
+gad5WZF5ykFArmHDgeFlgggvbZ7z9vqnjN/TH68TxJzauYQ5vLHQ6wGXik4/4uq7/TqNmhxlQEM4
+zVkwsn203bUmKLyz+yl1zItDpn5zy1uXfGo99rBdUzdbdE9LmEFPMaFsaHd4a8oDaUroD7FgCbeD
+JJVld3ac6F8+3QbExPs48OrgA1kI3/UwXr52ldjiYzTLfAGR9BjqNFTw45FUHuMf8TEM5hcHx56w
+95eKAqraDk28o9k+M2UKpcmrdlWoWzdqVVFeWGpM8x9Y9Nt0lf/4VUQgrXjqTkUCQkJyqTeTeGgH
+rn3QBk2XAgpxZhaJs3InW0BkAlBmK99cMinUiJeFt5a4p5wPeXrVuh6V9m7Mpl9hzpogg++EZqah
+fzzNnDgxOZfW342DX052PdgXo0NnkhCk005LvFt6M2mRn0fLgNVfyUZZoOp8cO5ZWbhXXlrhrgUt
+j2zKPK6Q94Zj4kdXHBGpAkrB8ZQ4EGGODE0Dqusm8WPXzB+9236IMHPU7lFbyjBrFNI7O4jg+qRI
+Ipi+7tX0FsilqEbmjG+OPwhZXrdqUqyF+rjKQuSRq7lOeDB4c6S2dq4OOny01i5HCbbyc9UvSHRm
+hOhGqUlzHyHLo3W7j+26V/MhkDXJ+Tx+qfylv4pbliwTteJJj+CZwzjv29qb6lxYi+38Bw10ERap
+m8UCRFBecVN7xXlcIfyeAl666Vi7EBJZv3EdFNrx1nlLwM65nYya7uj6L7IwJWotIUx8E0XH0/cU
+xS/dG8bxf9L/8652h5gq3LI+wTNGuEX0DMuz7BGQG+NtgabrZ6SsKGthGa7eULTpz0McWTLRU0y/
+/tkckpm5pDnXSFbIMskwwjECz82UZBSPpigdN/Pjg5d+0yWu7s3VJxw4ENWPPpzZ+j7sOXmdvn9P
+O1tQd60EO+3awASCBAAZQvWV3/yJ6FxPttbP+qeURpJoPEZfpN2UYZmd8HqtR0YbaOZ6Rln9nvpd
+K9fylXdw9z2xeCbjDWUttJB4VqZxGJM8eCTC1VDVyAOsQ5n7SY55dMkQbU+o4Z/4J5m8+wz50BBI
+LfruL1eZ6/CF6CdvxVRiJ10sXc0Tn2sVMXqkw7Adp1GYoCI9c6VFSFK74+n+y7LVFQ5HBnbQyKJc
+dvdLOXwZOPaFHC5UNXRmOpcwdPqyXUe+xIsOMYbzdlAnI9eGDNeRDktUa/Rh0CbZCxjmJzoZEYOE
+ZjsYZlEfp1Kb61t8z4m28hGLEg88T1Ihmxa2HeUWes1RpmgIOP+/2Lb3smj/l/fpSu4gabFgyCAV
+H5HdCYMScUv8SVu55+tpeO8ELoHHQUXV4rr084O4budzhgNSOPyLGDl5sfDUXiyusPCxS4JVO/KY
+6V2Qrtg/q2wtmXpEkZnGT+Qi3WDzwt4W81alztnYMP17oGLmxX71KV9OEiMZjI4WaaGt+OOINLtR
+qefioZ1NI2L1s5M0tybwTsyU9WERM+3pUwXIfJVsbMZRlNaO2OogcHbaR4UWvhOj+3CTG1sThiYQ
+MxMnp1Rpqx3nhyzqLO3TRrkYvxnA3cdPBn9EeqpgBMg7X3hCiMV3Fl5cj/WOMhtHYgY7BgeCXo46
+EFVZ4+WroGZ46xGiRDiIblo8bzLd7QCxvukzxy3mUDgsZQ8pds4N28weSUhBk5MAPbfBpRvXUVJx
+MhKqXucQU1Md1qSGLbuuIQuz9pAGp1JFUx/vEkCgm74daSoVWCZuB+1ZE4f48clvrBj51xMNf8CP
+EFE7vySzVb6X2H1i5X3Z+Y3DdIcWw4Y2FClfcJk4Mwq8Cq2GALGFEge9YSEE9YmyuU6OFeU0ICon
+iXAgZ72SM8fBwJPruLFbdsNYKW+oAfmPisXSWMcZmdSbfk0GYv+vKtu3eegSbWw1UsCVtZOh9E5Z
+uQ83l59CBqO9sV/SFU3WrrJ0qNWxrmXu9nJn5Qf5iCRoFGYNHYHkIG5FS6N00GEDZxGkxmro2d++
+Adj5LVHc/b1cYWmrux+jEqI8ZK8cyTB0XMbBA/HYbx9NXazr7znP4/Mlv3pZToEcYt+lgLHAArtU
+AdhybhbLIwNMq0gr6EwtDklBa3ns4Wx/rJU8H7LGs6gV8uqeaSketv+nz+sQhfctxZ1rx+5qzXfy
+FOQVpO23KDQunBi1Bl9k61Di4q9JWcyADBXPHXJzp7mL8Fk7zdvMAEfuED1phdRm6GgDYoYUs4yQ
+IrhSjFlWyk7hT8475xk3BIv++obvWSAv/3+pF6A6U2RXDChVmnG0JnPa9wYYtdzBmLfZKBjX+DjD
+yEMsuhPsCzuN4R6tBIIBWCVRKmKwdkatmpsQBgDw48u0/Arffl5/DRlS9ee+QffFecUitDdCK+kt
+X5L2fGYrL5g6SltncMIeV1ptx4nuSjC/O944q1KYtqvQiPFWJqEXIRMNbbYOC47sjLza0tEFrimN
+wxcrWGSzsy5R9beFQ1aHPcMrDWfCoviNRk2qPtxuKIC5Qk2ZuOmJLjCiLwUGEb0/1Mpzv3MqQa7d
+mRayXg3DZWJPajxNZv6eS357ElMvwGQmqafb2mlQJwWLsg9m9PG7uqEoyrqSc6MiuY+icLEFib9j
+OfRQrx70rTSKUfTr4MtP0aZZAefjCrpVIyTekhFDOk0Nmx057eonlyGgmGpl5/Uo+t1J1Z11Ya/l
+bNbfmebRISJeTVW0I8FhseAZMI1GSwp/ludJxSLYOgyRkh+GX134MexNo7O9F1SxLCfWaSG9Fc3s
+5ify04ua9/t8SGrYZPm/l3MkAAAAAAAAAAAAAA==
+
+
diff --git a/openssl/crypto/pkcs7/t/msie-s-a-e.pem b/openssl/crypto/pkcs7/t/msie-s-a-e.pem
new file mode 100644
index 0000000..55dbd8f
--- /dev/null
+++ b/openssl/crypto/pkcs7/t/msie-s-a-e.pem
@@ -0,0 +1,106 @@
+-----BEGIN PKCS7-----
+MIAGCSqGSIb3DQEHA6CAMIITUAIBADGCAcIwgcwCAQAwdjBiMREwDwYDVQQHEwhJ
+bnRlcm5ldDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNDAyBgNVBAsTK1ZlcmlT
+aWduIENsYXNzIDEgQ0EgLSBJbmRpdmlkdWFsIFN1YnNjcmliZXICEGBAmILep9sJ
+uN2Pkg1gucowDQYJKoZIhvcNAQEBBQAEQKOxxpIbRTb31+qIQCBOpMVAGnwCLrPO
+OXnntxVveTrPhBnsJuoGNJcCMtuHl7tLkd38WsVwOfGXUprTqFpUcY8wgfACAQAw
+gZkwgZIxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQH
+EwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRzb2Z0IFB0eSBMdGQxIjAgBgNVBAsT
+GURFTU9OU1RSQVRJT04gQU5EIFRFU1RJTkcxGzAZBgNVBAMTEkRFTU8gWkVSTyBW
+QUxVRSBDQQICBG4wDQYJKoZIhvcNAQEBBQAEQKzIddnXFqK/RRBG86ZVixoXfwAv
+ZdfvnDFsKzPn/A6DuDdE/hqJxnFpHiwGiDR/YbWj2ib+G74DSshgX8vj8ZQwghGD
+BgkqhkiG9w0BBwEwGgYIKoZIhvcNAwIwDgICAKAECLKM0K58I3HNgIIRWBDP8s+g
+l7/6JhZ5PBJ5vPpD1R4pnNDZRabsYu0Qzezdz1IK+maTAhF0SEuNZoEkzIgOIvu3
+UjW8x/2KcHwteABwgRiSk1JyNLwRED0RtvuJ40pIGDvDsHwBMcXEtKUMAOpGChms
+HUK1+B/GKancSDFOCeG3JCFnFdbuQFDIVHC6amWslc6ntqVs/sii2Gs4qdzDfQgl
+PV/A/FY0wi0j2O5cXRQJtZVKM/MYGjj5c1cy9Q7oymU5ATP/LARD0Tw5kBB7HVnD
+2qrmmmxcHakyxhXmwskaKS6Qxgqq6LPdgr603onxqEtwNSz5UbCq9mLXuCkFOVsQ
+/5mZcmmc7re3XJMQHRXkBlxEpZQ6HOUIEzlhRqCo2hhymyZK84rptjORQo6vNakM
+IC0Zn8O+6Xl1NlmbGzZakz6LJ4dczE7eG7LwrVus9Oq3V/WweG6rWMPV5d51oKMi
+BRb2pXXy80BAKh/9hvpP/V/HO1/+MPuk8tAn7ssmQoIAQcZxqLOmgqqFhy21oSEu
+rUY746Gp/vIV6Ax1MnfDA/fbjDllhJTl8ujZnfj8R1/oQa9fJMipV8CYQEAt3okZ
+V03kaVhhPGsv544/zRnhqjhgqjHASZGnluZCxDwHb1CE4UqYLp6IbkH3qosy2ntm
+a7WCsM3FN3o5dKFZXBgBEPT8HU9LLQ8B+T0Zvh8CQ719kkNBhnuzSYzmI48R5JHv
+zbROiU5v4p9FpssD13vXiOxzaMTKQqWk/roGHiNoKzKonS5RBwTxKfOsoCobCBaI
+IZCmJNr4cGI/p5GVEY4pCPljTq9w3HoiNrhwZ7r7II3wdXy0JjSiRkr3w1AKXm3v
+1H9kHZzc28Ekf7+De6VTjyKRPe1WYPETeY5mh9nIYUQz30/5gIxJwsPFOXeHMbLR
+iQjxTznk/uo4BtwV+HZPmf4tIQvAuFuTKYR9lP3XsZZN+bKkFYy8nHRYd4OErBBg
+93NsqBYROdzJ4pqxoJb6gt2EHCt3pazavgwDxzCJhcMtvBiYLEkDxUX77yS5sXYc
+k6NLIwFL5BPY9JX/QP1RaiJV+TtHg69YElW+rudX6VdLQ7mKCMTHGWbHU5oF+Dv4
+Kv8xsrjNU2spImfzY2coq3osLpFpOa8VhrLSwMXFDtej5OHq0M0qYpYm3op6B+Nz
+6pNYlMpveQv5Qjy9LTNMvLX4z+tnh6Siz8mJLmtghwCzC+DnyQGCn/Stzq6kF5aM
+Fork7RosB4FB8u6WjVrFZfTg5JUqZh6gCW3JHpQ70wTdpy6tDKDtNrbjKo7CGL8+
+shoSI7t2xa8W3OyyFXMEuJzTY2UCQ+QxTOWI9idkdZCCUMBXEvkraqG8rU4UKRCk
+iAGwEMzophEv+aSyJfdu6yJGjd+/wUCHMS3EmtOWHwtB5d5sVhErdQNA+JQN+wPU
+vBG2Jg3wGJTHNNx4WRnWRLWsH6SRcgx8zWXHjVgXIep8XjWQmOGBXbG87hktESqc
+DQPUv3MzieKfcpgQsboRnqSN1DymwvAu+PVsMNf8DHQKLdZ/iuzPzwRkfIVpmh+U
+ku1N8jMAAdX6tjQ48eLq/lJvjHJUnTdNTA18xhDvngKNaXQGPOO/dt+JfHQdmFQI
+WdWZSeCpm6jCiaxiV50FBGEuv3Ew0Y7FKHLKFu7hoNXIthoh2qo5ZH6QX4nt0nYR
+VvyvIcAB9BwC7OeqBTeusFJD/wGiQD3yFDYUekaRys2fcwguNqAdpjWsEETJxREw
+ZdbP0sDMSykae4wHyrODWcUmOiPc/9nU6c0t7bBzI8VQ7sZKJb0TVgSCxDHi9Qgb
+4qdh4ZqFMP0s+TQ4Ms5NWkC1eg0DSdkWSzGQ0QrUsGUgbupYYUoEyRmsz9PjW6l1
+wuWkE66qxSHFsg18/gA5XpLM82DP4EmkEwgC08Hww2lPRJN8VYFvlwbRMbSd1PtA
+Dd5dI/Oq1CHSL6enlncVkKr/S7aaKKyjAyn1HOT2FdPWdSYLE+F+dWc6vu+JeXc+
+7nSDO1DW3U6ZkZvTw4901GxgrzUfYajhBky25L29WUduGoerhkZds5wduSKQwBkY
+TUW/YrP6Ttrbx8B0wzDo64L2Rv6Tb14ElMc9KUY1I1yHKgXtl9oHEH3mpa/IGO+q
+PN1hBi+jg68lfb00FR7edvos4KWKAWWlZaYKm2ZeeHPjhNGcX/UcF8A23GLuSruR
+NDDy9KlI3NMtvmOhOD+WwFmmRjBk/jkZMlVM3GlpjP/l5TuzxEecK1pQiDGQl9S/
+574qGNKtAiqgC5+wyUFPqnp28K2+rsEu7jWWOlfOrNGg2KVO8kcqsQuUm7sjSW9N
+oHcVAoKSLHBWjFIzFUZpeDOASI1/21Ph4B6FTFJvEpzfYEXE9osz64DhlXDEyY33
+p86AiqAj6PUY4BjHLYAeA7ymphKzVOzq4pSH7qKsxDzUnj/Uj8P85A5jbzHmzOPf
+VnvQlZ7B1FqhdNP2SVqLmu+/tH9Wy0v7ZnItSQbyHDKP+Eib4B/ihaNIIoz/YKgD
+3eYgjp6ZyZR1KkSMpuNkpsihA7s3UsFyowEeo+7l3Wt/ScjCa/IBsxLLtI2EZAJo
+9WHYqsCl1HCzJHI9QCnlPz8U1FcNGCrL/66MKz2MMN8UFFqjYr61wexghxNwc7GD
+XR7Js4mhiF0GwPhAR3ZLiqzPAXAvn8YRf5fylMZ4LA9RO+SHFL/MxQxfrJOAgWB6
+pLPUuCWJXLm7os6rCC23RsyDDWe8N+JNF0/ryzr8MHeIJGsT+AYnZr08PeTbyr01
+JEoT7lPYT6PzX4F63QKKDl+mB+PwLMzYCXrxZcUmuay6/MV8w/f5T6vQXdoSw5pu
+WodBYwVReYh1IaEN+jiTapm9YBVmcIsJPO6abHowknSVOWSvST0AtAX57fFOTckm
++facfBK9s9T1lUUgF44Bh5e8f9qKqfOV44nqdCOEyUm0Dao497ieN4EgXBLNvOZY
+9+irMiXjp0lcyFvhrJOczfyCr9EiiaiH1TfSzKGKsf2W84iKn/JH6x2eOo7xjwJ4
+0BQDc6S1cUNEuqBhP6by0FioOXYOKVyifpxk84Eb+F/4CNdTJTvCPwsiegdfsX/Q
+53DvKVtXp9Ycam5JTmKRHXK/bMHF4ONv3p/O/kn/BqRx+fbbP2eMX8Z1F/ltHKfp
+6B+06HljUwQLBJs9XtCfqH5Zgdz9gad5WZF5ykFArmHDgeFlgggvbZ7z9vqnjN/T
+H68TxJzauYQ5vLHQ6wGXik4/4uq7/TqNmhxlQEM4zVkwsn203bUmKLyz+yl1zItD
+pn5zy1uXfGo99rBdUzdbdE9LmEFPMaFsaHd4a8oDaUroD7FgCbeDJJVld3ac6F8+
+3QbExPs48OrgA1kI3/UwXr52ldjiYzTLfAGR9BjqNFTw45FUHuMf8TEM5hcHx56w
+95eKAqraDk28o9k+M2UKpcmrdlWoWzdqVVFeWGpM8x9Y9Nt0lf/4VUQgrXjqTkUC
+QkJyqTeTeGgHrn3QBk2XAgpxZhaJs3InW0BkAlBmK99cMinUiJeFt5a4p5wPeXrV
+uh6V9m7Mpl9hzpogg++EZqahfzzNnDgxOZfW342DX052PdgXo0NnkhCk005LvFt6
+M2mRn0fLgNVfyUZZoOp8cO5ZWbhXXlrhrgUtj2zKPK6Q94Zj4kdXHBGpAkrB8ZQ4
+EGGODE0Dqusm8WPXzB+9236IMHPU7lFbyjBrFNI7O4jg+qRIIpi+7tX0FsilqEbm
+jG+OPwhZXrdqUqyF+rjKQuSRq7lOeDB4c6S2dq4OOny01i5HCbbyc9UvSHRmhOhG
+qUlzHyHLo3W7j+26V/MhkDXJ+Tx+qfylv4pbliwTteJJj+CZwzjv29qb6lxYi+38
+Bw10ERapm8UCRFBecVN7xXlcIfyeAl666Vi7EBJZv3EdFNrx1nlLwM65nYya7uj6
+L7IwJWotIUx8E0XH0/cUxS/dG8bxf9L/8652h5gq3LI+wTNGuEX0DMuz7BGQG+Nt
+gabrZ6SsKGthGa7eULTpz0McWTLRU0y//tkckpm5pDnXSFbIMskwwjECz82UZBSP
+pigdN/Pjg5d+0yWu7s3VJxw4ENWPPpzZ+j7sOXmdvn9PO1tQd60EO+3awBlC9ZXf
+/InoXE+21s/6p5RGkmg8Rl+k3ZRhmZ3weq1HRhto5npGWf2e+l0r1/KVd3D3PbF4
+JuMNZS20kHhWpnEYkzx4JMLVUNXIA6xDmftJjnl0yRBtT6jhn/gnmbz7DPnQEEgt
++u4vV5nr8IXoJ2/FVGInXSxdzROfaxUxeqTDsB2nUZigIj1zpUVIUrvj6f7LstUV
+DkcGdtDIolx290s5fBk49oUcLlQ1dGY6lzB0+rJdR77Eiw4xhvN2UCcj14YM15EO
+S1Rr9GHQJtkLGOYnOhkRg4RmOxhmUR+nUpvrW3zPibbyEYsSDzxPUiGbFrYd5RZ6
+zVGmaAg4/7/YtveyaP+X9+lK7iBpsWDIIBUfkd0JgxJxS/xJW7nn62l47wQugcdB
+RdXiuvTzg7hu53OGA1I4/IsYOXmx8NReLK6w8LFLglU78pjpXZCu2D+rbC2ZekSR
+mcZP5CLdYPPC3hbzVqXO2dgw/XugYubFfvUpX04SIxmMjhZpoa3444g0u1Gp5+Kh
+nU0jYvWzkzS3JvBOzJT1YREz7elTBch8lWxsxlGU1o7Y6iBwdtpHhRa+E6P7cJMb
+WxOGJhAzEyenVGmrHeeHLOos7dNGuRi/GcDdx08Gf0R6qmAEyDtfeEKIxXcWXlyP
+9Y4yG0diBjsGB4JejjoQVVnj5augZnjrEaJEOIhuWjxvMt3tALG+6TPHLeZQOCxl
+Dyl2zg3bzB5JSEGTkwA9t8GlG9dRUnEyEqpe5xBTUx3WpIYtu64hC7P2kAanUkVT
+H+8SQKCbvh1pKhVYJm4H7VkTh/jxyW+sGPnXEw1/wI8QUTu/JLNVvpfYfWLlfdn5
+jcN0hxbDhjYUKV9wmTgzCrwKrYYAsYUSB71hIQT1ibK5To4V5TQgKieJcCBnvZIz
+x8HAk+u4sVt2w1gpb6gB+Y+KxdJYxxmZ1Jt+TQZi/68q27d56BJtbDVSwJW1k6H0
+Tlm5DzeXn0IGo72xX9IVTdausnSo1bGuZe72cmflB/mIJGgUZg0dgeQgbkVLo3TQ
+YQNnEaTGaujZ374B2PktUdz9vVxhaau7H6MSojxkrxzJMHRcxsED8dhvH01drOvv
+Oc/j8yW/ellOgRxi36WAscACu1QB2HJuFssjA0yrSCvoTC0OSUFreezhbH+slTwf
+ssazqBXy6p5pKR62/6fP6xCF9y3FnWvH7mrNd/IU5BWk7bcoNC6cGLUGX2TrUOLi
+r0lZzIAMFc8dcnOnuYvwWTvN28wAR+4QPWmF1GboaANihhSzjJAiuFKMWVbKTuFP
+zjvnGTcEi/76hu9ZIC//f6kXoDpTZFcMKFWacbQmc9r3Bhi13MGYt9koGNf4OMPI
+Qyy6E+wLO43hHq0lUSpisHZGrZqbEAYA8OPLtPwK335efw0ZUvXnvkH3xXnFIrQ3
+QivpLV+S9nxmKy+YOkpbZ3DCHldabceJ7kowvzveOKtSmLar0IjxViahFyETDW22
+DguO7Iy82tLRBa4pjcMXK1hks7MuUfW3hUNWhz3DKw1nwqL4jUZNqj7cbiiAuUJN
+mbjpiS4woi8FBhG9P9TKc79zKkGu3ZkWsl4Nw2ViT2o8TWb+nkt+exJTL8BkJqmn
+29ppUCcFi7IPZvTxu7qhKMq6knOjIrmPonCxBYm/Yzn0UK8e9K00ilH06+DLT9Gm
+WQHn4wq6VSMk3pIRQzpNDZsdOe3qJ5choJhqZef1KPrdSdWddWGv5WzW35nm0SEi
+Xk1VtCPBYbHgGTCNRksKf5bnScUi2DoMkZIfhl9d+DHsTaOzvRdUsSwn1mkhvRXN
+7OYn8tOLmvf7fEhq2GT5v5dzJAAAAAA=
+-----END PKCS7-----
diff --git a/openssl/crypto/pkcs7/t/nav-smime b/openssl/crypto/pkcs7/t/nav-smime
new file mode 100644
index 0000000..6ee4b59
--- /dev/null
+++ b/openssl/crypto/pkcs7/t/nav-smime
@@ -0,0 +1,157 @@
+From angela@c2.net.au Thu May 14 13:32:27 1998
+X-UIDL: 83c94dd550e54329bf9571b72038b8c8
+Return-Path: angela@c2.net.au
+Received: from cryptsoft.com (play.cryptsoft.com [203.56.44.3]) by pandora.cryptsoft.com (8.8.3/8.7.3) with ESMTP id NAA27838 for <tjh@cryptsoft.com>; Thu, 14 May 1998 13:32:26 +1000 (EST)
+Message-ID: <355A6779.4B63E64C@cryptsoft.com>
+Date: Thu, 14 May 1998 13:39:37 +1000
+From: Angela van Lent <angela@c2.net.au>
+X-Mailer: Mozilla 4.03 [en] (Win95; U)
+MIME-Version: 1.0
+To: tjh@cryptsoft.com
+Subject: signed
+Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg=sha1; boundary="------------ms9A58844C95949ECC78A1C54C"
+Content-Length: 2604
+Status: OR
+
+This is a cryptographically signed message in MIME format.
+
+--------------ms9A58844C95949ECC78A1C54C
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+
+signed body
+
+--------------ms9A58844C95949ECC78A1C54C
+Content-Type: application/x-pkcs7-signature; name="smime.p7s"
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment; filename="smime.p7s"
+Content-Description: S/MIME Cryptographic Signature
+
+MIIGHgYJKoZIhvcNAQcCoIIGDzCCBgsCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCC
+BGswggJTMIIB/aADAgECAgIEfjANBgkqhkiG9w0BAQQFADCBkjELMAkGA1UEBhMCQVUxEzAR
+BgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5lMRowGAYDVQQKExFDcnlwdHNv
+ZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBBTkQgVEVTVElORzEbMBkGA1UE
+AxMSREVNTyBaRVJPIFZBTFVFIENBMB4XDTk4MDUxMzA2MjY1NloXDTAwMDUxMjA2MjY1Nlow
+gaUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFu
+ZTEaMBgGA1UEChMRQ3J5cHRzb2Z0IFB0eSBMdGQxEjAQBgNVBAsTCVNNSU1FIDAwMzEZMBcG
+A1UEAxMQQW5nZWxhIHZhbiBMZWVudDEjMCEGCSqGSIb3DQEJARYUYW5nZWxhQGNyeXB0c29m
+dC5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAuC3+7dAb2LhuO7gt2cTM8vsNjhG5JfDh
+hX1Vl/wVGbKEEj0MA6vWEolvefQlxB+EzwCtR0YZ7eEC/T/4JoCyeQIDAQABoygwJjAkBglg
+hkgBhvhCAQ0EFxYVR2VuZXJhdGVkIHdpdGggU1NMZWF5MA0GCSqGSIb3DQEBBAUAA0EAUnSP
+igs6TMFISTjw8cBtJYb98czgAVkVFjKyJQwYMH8FbDnCyx6NocM555nsyDstaw8fKR11Khds
+syd3ikkrhDCCAhAwggG6AgEDMA0GCSqGSIb3DQEBBAUAMIGSMQswCQYDVQQGEwJBVTETMBEG
+A1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
+dCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNUUkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQD
+ExJERU1PIFpFUk8gVkFMVUUgQ0EwHhcNOTgwMzAzMDc0MTMyWhcNMDgwMjI5MDc0MTMyWjCB
+kjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5l
+MRowGAYDVQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBB
+TkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENBMFwwDQYJKoZIhvcNAQEB
+BQADSwAwSAJBAL+0E2fLej3FSCwe2A2iRnMuC3z12qHIp6Ky1wo2zZcxft7AI+RfkrWrSGtf
+mfzBEuPrLdfulncC5Y1pNcM8RTUCAwEAATANBgkqhkiG9w0BAQQFAANBAGSbLMphL6F5pp3s
+8o0Xyh86FHFdpVOwYx09ELLkuG17V/P9pgIc0Eo/gDMbN+KT3IdgECf8S//pCRA6RrNjcXIx
+ggF7MIIBdwIBATCBmTCBkjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAP
+BgNVBAcTCEJyaXNiYW5lMRowGAYDVQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZ
+REVNT05TVFJBVElPTiBBTkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENB
+AgIEfjAJBgUrDgMCGgUAoHowGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAbBgkqhkiG9w0B
+CQ8xDjAMMAoGCCqGSIb3DQMHMBwGCSqGSIb3DQEJBTEPFw05ODA1MTQwMzM5MzdaMCMGCSqG
+SIb3DQEJBDEWBBQstNMnSV26ba8PapQEDhO21yNFrjANBgkqhkiG9w0BAQEFAARAW9Xb9YXv
+BfcNkutgFX9Gr8iXhBVsNtGEVrjrpkQwpKa7jHI8SjAlLhk/4RFwDHf+ISB9Np3Z1WDWnLcA
+9CWR6g==
+--------------ms9A58844C95949ECC78A1C54C--
+
+
+From angela@c2.net.au Thu May 14 13:33:16 1998
+X-UIDL: 8f076c44ff7c5967fd5b00c4588a8731
+Return-Path: angela@c2.net.au
+Received: from cryptsoft.com (play.cryptsoft.com [203.56.44.3]) by pandora.cryptsoft.com (8.8.3/8.7.3) with ESMTP id NAA27847 for <tjh@cryptsoft.com>; Thu, 14 May 1998 13:33:15 +1000 (EST)
+Message-ID: <355A67AB.2AF38806@cryptsoft.com>
+Date: Thu, 14 May 1998 13:40:27 +1000
+From: Angela van Lent <angela@c2.net.au>
+X-Mailer: Mozilla 4.03 [en] (Win95; U)
+MIME-Version: 1.0
+To: tjh@cryptsoft.com
+Subject: signed
+Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg=sha1; boundary="------------msD7863B84BD61E02C407F2F5E"
+Content-Length: 2679
+Status: OR
+
+This is a cryptographically signed message in MIME format.
+
+--------------msD7863B84BD61E02C407F2F5E
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+
+signed body 2
+
+--------------msD7863B84BD61E02C407F2F5E
+Content-Type: application/x-pkcs7-signature; name="smime.p7s"
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment; filename="smime.p7s"
+Content-Description: S/MIME Cryptographic Signature
+
+MIIGVgYJKoZIhvcNAQcCoIIGRzCCBkMCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCC
+BGswggJTMIIB/aADAgECAgIEfjANBgkqhkiG9w0BAQQFADCBkjELMAkGA1UEBhMCQVUxEzAR
+BgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5lMRowGAYDVQQKExFDcnlwdHNv
+ZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBBTkQgVEVTVElORzEbMBkGA1UE
+AxMSREVNTyBaRVJPIFZBTFVFIENBMB4XDTk4MDUxMzA2MjY1NloXDTAwMDUxMjA2MjY1Nlow
+gaUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFu
+ZTEaMBgGA1UEChMRQ3J5cHRzb2Z0IFB0eSBMdGQxEjAQBgNVBAsTCVNNSU1FIDAwMzEZMBcG
+A1UEAxMQQW5nZWxhIHZhbiBMZWVudDEjMCEGCSqGSIb3DQEJARYUYW5nZWxhQGNyeXB0c29m
+dC5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAuC3+7dAb2LhuO7gt2cTM8vsNjhG5JfDh
+hX1Vl/wVGbKEEj0MA6vWEolvefQlxB+EzwCtR0YZ7eEC/T/4JoCyeQIDAQABoygwJjAkBglg
+hkgBhvhCAQ0EFxYVR2VuZXJhdGVkIHdpdGggU1NMZWF5MA0GCSqGSIb3DQEBBAUAA0EAUnSP
+igs6TMFISTjw8cBtJYb98czgAVkVFjKyJQwYMH8FbDnCyx6NocM555nsyDstaw8fKR11Khds
+syd3ikkrhDCCAhAwggG6AgEDMA0GCSqGSIb3DQEBBAUAMIGSMQswCQYDVQQGEwJBVTETMBEG
+A1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
+dCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNUUkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQD
+ExJERU1PIFpFUk8gVkFMVUUgQ0EwHhcNOTgwMzAzMDc0MTMyWhcNMDgwMjI5MDc0MTMyWjCB
+kjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5l
+MRowGAYDVQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBB
+TkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENBMFwwDQYJKoZIhvcNAQEB
+BQADSwAwSAJBAL+0E2fLej3FSCwe2A2iRnMuC3z12qHIp6Ky1wo2zZcxft7AI+RfkrWrSGtf
+mfzBEuPrLdfulncC5Y1pNcM8RTUCAwEAATANBgkqhkiG9w0BAQQFAANBAGSbLMphL6F5pp3s
+8o0Xyh86FHFdpVOwYx09ELLkuG17V/P9pgIc0Eo/gDMbN+KT3IdgECf8S//pCRA6RrNjcXIx
+ggGzMIIBrwIBATCBmTCBkjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAP
+BgNVBAcTCEJyaXNiYW5lMRowGAYDVQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZ
+REVNT05TVFJBVElPTiBBTkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENB
+AgIEfjAJBgUrDgMCGgUAoIGxMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcN
+AQkFMQ8XDTk4MDUxNDAzNDAyN1owIwYJKoZIhvcNAQkEMRYEFOKcV8mNYJnM8rHQajcSEqJN
+rwdDMFIGCSqGSIb3DQEJDzFFMEMwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMAcGBSsO
+AwIHMA0GCCqGSIb3DQMCAgFAMA0GCCqGSIb3DQMCAgEoMA0GCSqGSIb3DQEBAQUABEADPE/N
+coH+zTFuX5YpolupTKxKK8eEjc48TuADuO8bIHHDE/fEYaWunlwDuTlcFJl1ig0idffPB1qC
+Zp8SSVVY
+--------------msD7863B84BD61E02C407F2F5E--
+
+
+From angela@c2.net.au Thu May 14 14:05:32 1998
+X-UIDL: a7d629b4b9acacaee8b39371b860a32a
+Return-Path: angela@c2.net.au
+Received: from cryptsoft.com (play.cryptsoft.com [203.56.44.3]) by pandora.cryptsoft.com (8.8.3/8.7.3) with ESMTP id OAA28033 for <tjh@cryptsoft.com>; Thu, 14 May 1998 14:05:32 +1000 (EST)
+Message-ID: <355A6F3B.AC385981@cryptsoft.com>
+Date: Thu, 14 May 1998 14:12:43 +1000
+From: Angela van Lent <angela@c2.net.au>
+X-Mailer: Mozilla 4.03 [en] (Win95; U)
+MIME-Version: 1.0
+To: tjh@cryptsoft.com
+Subject: encrypted
+Content-Type: application/x-pkcs7-mime; name="smime.p7m"
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment; filename="smime.p7m"
+Content-Description: S/MIME Encrypted Message
+Content-Length: 905
+Status: OR
+
+MIAGCSqGSIb3DQEHA6CAMIACAQAxggHmMIHwAgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEG
+A1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
+dCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNUUkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQD
+ExJERU1PIFpFUk8gVkFMVUUgQ0ECAgR+MA0GCSqGSIb3DQEBAQUABEA92N29Yk39RUY2tIVd
+exGT2MFX3J6H8LB8aDRJjw7843ALgJ5zXpM5+f80QkAWwEN2A6Pl3VxiCeKLi435zXVyMIHw
+AgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMI
+QnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29mdCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNU
+UkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQDExJERU1PIFpFUk8gVkFMVUUgQ0ECAgRuMA0G
+CSqGSIb3DQEBAQUABECR9IfyHtvnjFmZ8B2oUCEs1vxMsG0u1kxKE4RMPFyDqDCEARq7zXMg
+nzSUI7Wgv5USSKDqcLRJeW+jvYURv/nJMIAGCSqGSIb3DQEHATAaBggqhkiG9w0DAjAOAgIA
+oAQIrLqrij2ZMpeggAQoibtn6reRZWuWk5Iv5IAhgitr8EYE4w4ySQ7EMB6mTlBoFpccUMWX
+BwQgQn1UoWCvYAlhDzURdbui64Dc0rS2wtj+kE/InS6y25EEEPe4NUKaF8/UlE+lo3LtILQE
+CL3uV8k7m0iqAAAAAAAAAAAAAA==
+
diff --git a/openssl/crypto/pkcs7/t/s.pem b/openssl/crypto/pkcs7/t/s.pem
new file mode 100644
index 0000000..4fa925b
--- /dev/null
+++ b/openssl/crypto/pkcs7/t/s.pem
@@ -0,0 +1,57 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOgIBAAJBAK3nI4nuDYe3nDJES5WBc90igEstxWC4/h4YY+/ciYki35U8ets9
+mgaoCNYp/e9BCZHtvK2Y+fYokGJv5+cMTQsCAwEAAQJBAIHpvXvqEcOEoDRRHuIG
+fkcB4jPHcr9KE9TpxabH6xs9beN6OJnkePXAHwaz5MnUgSnbpOKq+cw8miKjXwe/
+zVECIQDVLwncT2lRmXarEYHzb+q/0uaSvKhWKKt3kJasLNTrAwIhANDUc/ghut29
+p3jJYjurzUKuG774/5eLjPLsxPPIZzNZAiA/10hSq41UnGqHLEUIS9m2/EeEZe7b
+bm567dfRU9OnVQIgDo8ROrZXSchEGbaog5J5r/Fle83uO8l93R3GqVxKXZkCIFfk
+IPD5PIYQAyyod3hyKKza7ZP4CGY4oOfZetbkSGGG
+-----END RSA PRIVATE KEY-----
+issuer :/C=AU/SP=Queensland/L=Brisbane/O=Cryptsoft Pty Ltd/OU=DEMONSTRATION AND TESTING/CN=DEMO ZERO VALUE CA
+subject:/C=AU/SP=Queensland/L=Brisbane/O=Cryptsoft Pty Ltd/OU=SMIME 003/CN=Information/Email=info@cryptsoft.com
+serial :047D
+
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1149 (0x47d)
+        Signature Algorithm: md5withRSAEncryption
+        Issuer: C=AU, SP=Queensland, L=Brisbane, O=Cryptsoft Pty Ltd, OU=DEMONSTRATION AND TESTING, CN=DEMO ZERO VALUE CA
+        Validity
+            Not Before: May 13 05:40:58 1998 GMT
+            Not After : May 12 05:40:58 2000 GMT
+        Subject: C=AU, SP=Queensland, L=Brisbane, O=Cryptsoft Pty Ltd, OU=SMIME 003, CN=Information/Email=info@cryptsoft.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Modulus:
+                    00:ad:e7:23:89:ee:0d:87:b7:9c:32:44:4b:95:81:
+                    73:dd:22:80:4b:2d:c5:60:b8:fe:1e:18:63:ef:dc:
+                    89:89:22:df:95:3c:7a:db:3d:9a:06:a8:08:d6:29:
+                    fd:ef:41:09:91:ed:bc:ad:98:f9:f6:28:90:62:6f:
+                    e7:e7:0c:4d:0b
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            Netscape Comment: 
+                Generated with SSLeay
+    Signature Algorithm: md5withRSAEncryption
+        52:15:ea:88:f4:f0:f9:0b:ef:ce:d5:f8:83:40:61:16:5e:55:
+        f9:ce:2d:d1:8b:31:5c:03:c6:2d:10:7c:61:d5:5c:0a:42:97:
+        d1:fd:65:b6:b6:84:a5:39:ec:46:ec:fc:e0:0d:d9:22:da:1b:
+        50:74:ad:92:cb:4e:90:e5:fa:7d
+
+-----BEGIN CERTIFICATE-----
+MIICTDCCAfagAwIBAgICBH0wDQYJKoZIhvcNAQEEBQAwgZIxCzAJBgNVBAYTAkFV
+MRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UE
+ChMRQ3J5cHRzb2Z0IFB0eSBMdGQxIjAgBgNVBAsTGURFTU9OU1RSQVRJT04gQU5E
+IFRFU1RJTkcxGzAZBgNVBAMTEkRFTU8gWkVSTyBWQUxVRSBDQTAeFw05ODA1MTMw
+NTQwNThaFw0wMDA1MTIwNTQwNThaMIGeMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
+UXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
+dCBQdHkgTHRkMRIwEAYDVQQLEwlTTUlNRSAwMDMxFDASBgNVBAMTC0luZm9ybWF0
+aW9uMSEwHwYJKoZIhvcNAQkBFhJpbmZvQGNyeXB0c29mdC5jb20wXDANBgkqhkiG
+9w0BAQEFAANLADBIAkEArecjie4Nh7ecMkRLlYFz3SKASy3FYLj+Hhhj79yJiSLf
+lTx62z2aBqgI1in970EJke28rZj59iiQYm/n5wxNCwIDAQABoygwJjAkBglghkgB
+hvhCAQ0EFxYVR2VuZXJhdGVkIHdpdGggU1NMZWF5MA0GCSqGSIb3DQEBBAUAA0EA
+UhXqiPTw+QvvztX4g0BhFl5V+c4t0YsxXAPGLRB8YdVcCkKX0f1ltraEpTnsRuz8
+4A3ZItobUHStkstOkOX6fQ==
+-----END CERTIFICATE-----
+
diff --git a/openssl/crypto/pkcs7/t/server.pem b/openssl/crypto/pkcs7/t/server.pem
new file mode 100644
index 0000000..989baf8
--- /dev/null
+++ b/openssl/crypto/pkcs7/t/server.pem
@@ -0,0 +1,57 @@
+issuer :/C=AU/SP=Queensland/L=Brisbane/O=Cryptsoft Pty Ltd/OU=DEMONSTRATION AND TESTING/CN=DEMO ZERO VALUE CA
+subject:/C=AU/SP=Queensland/L=Brisbane/O=Cryptsoft Pty Ltd/OU=SMIME 003/CN=Information/Email=info@cryptsoft.com
+serial :047D
+
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1149 (0x47d)
+        Signature Algorithm: md5withRSAEncryption
+        Issuer: C=AU, SP=Queensland, L=Brisbane, O=Cryptsoft Pty Ltd, OU=DEMONSTRATION AND TESTING, CN=DEMO ZERO VALUE CA
+        Validity
+            Not Before: May 13 05:40:58 1998 GMT
+            Not After : May 12 05:40:58 2000 GMT
+        Subject: C=AU, SP=Queensland, L=Brisbane, O=Cryptsoft Pty Ltd, OU=SMIME 003, CN=Information/Email=info@cryptsoft.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Modulus:
+                    00:ad:e7:23:89:ee:0d:87:b7:9c:32:44:4b:95:81:
+                    73:dd:22:80:4b:2d:c5:60:b8:fe:1e:18:63:ef:dc:
+                    89:89:22:df:95:3c:7a:db:3d:9a:06:a8:08:d6:29:
+                    fd:ef:41:09:91:ed:bc:ad:98:f9:f6:28:90:62:6f:
+                    e7:e7:0c:4d:0b
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            Netscape Comment: 
+                Generated with SSLeay
+    Signature Algorithm: md5withRSAEncryption
+        52:15:ea:88:f4:f0:f9:0b:ef:ce:d5:f8:83:40:61:16:5e:55:
+        f9:ce:2d:d1:8b:31:5c:03:c6:2d:10:7c:61:d5:5c:0a:42:97:
+        d1:fd:65:b6:b6:84:a5:39:ec:46:ec:fc:e0:0d:d9:22:da:1b:
+        50:74:ad:92:cb:4e:90:e5:fa:7d
+
+-----BEGIN CERTIFICATE-----
+MIICTDCCAfagAwIBAgICBH0wDQYJKoZIhvcNAQEEBQAwgZIxCzAJBgNVBAYTAkFV
+MRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UE
+ChMRQ3J5cHRzb2Z0IFB0eSBMdGQxIjAgBgNVBAsTGURFTU9OU1RSQVRJT04gQU5E
+IFRFU1RJTkcxGzAZBgNVBAMTEkRFTU8gWkVSTyBWQUxVRSBDQTAeFw05ODA1MTMw
+NTQwNThaFw0wMDA1MTIwNTQwNThaMIGeMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
+UXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
+dCBQdHkgTHRkMRIwEAYDVQQLEwlTTUlNRSAwMDMxFDASBgNVBAMTC0luZm9ybWF0
+aW9uMSEwHwYJKoZIhvcNAQkBFhJpbmZvQGNyeXB0c29mdC5jb20wXDANBgkqhkiG
+9w0BAQEFAANLADBIAkEArecjie4Nh7ecMkRLlYFz3SKASy3FYLj+Hhhj79yJiSLf
+lTx62z2aBqgI1in970EJke28rZj59iiQYm/n5wxNCwIDAQABoygwJjAkBglghkgB
+hvhCAQ0EFxYVR2VuZXJhdGVkIHdpdGggU1NMZWF5MA0GCSqGSIb3DQEBBAUAA0EA
+UhXqiPTw+QvvztX4g0BhFl5V+c4t0YsxXAPGLRB8YdVcCkKX0f1ltraEpTnsRuz8
+4A3ZItobUHStkstOkOX6fQ==
+-----END CERTIFICATE-----
+
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOgIBAAJBAK3nI4nuDYe3nDJES5WBc90igEstxWC4/h4YY+/ciYki35U8ets9
+mgaoCNYp/e9BCZHtvK2Y+fYokGJv5+cMTQsCAwEAAQJBAIHpvXvqEcOEoDRRHuIG
+fkcB4jPHcr9KE9TpxabH6xs9beN6OJnkePXAHwaz5MnUgSnbpOKq+cw8miKjXwe/
+zVECIQDVLwncT2lRmXarEYHzb+q/0uaSvKhWKKt3kJasLNTrAwIhANDUc/ghut29
+p3jJYjurzUKuG774/5eLjPLsxPPIZzNZAiA/10hSq41UnGqHLEUIS9m2/EeEZe7b
+bm567dfRU9OnVQIgDo8ROrZXSchEGbaog5J5r/Fle83uO8l93R3GqVxKXZkCIFfk
+IPD5PIYQAyyod3hyKKza7ZP4CGY4oOfZetbkSGGG
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/crypto/pkcs7/verify.c b/openssl/crypto/pkcs7/verify.c
new file mode 100644
index 0000000..b40f260
--- /dev/null
+++ b/openssl/crypto/pkcs7/verify.c
@@ -0,0 +1,263 @@
+/* crypto/pkcs7/verify.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+#include <stdio.h>
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include "example.h"
+
+int verify_callback(int ok, X509_STORE_CTX *ctx);
+
+BIO *bio_err=NULL;
+BIO *bio_out=NULL;
+
+int main(argc,argv)
+int argc;
+char *argv[];
+	{
+	PKCS7 *p7;
+	PKCS7_SIGNER_INFO *si;
+	X509_STORE_CTX cert_ctx;
+	X509_STORE *cert_store=NULL;
+	BIO *data,*detached=NULL,*p7bio=NULL;
+	char buf[1024*4];
+	char *pp;
+	int i,printit=0;
+	STACK_OF(PKCS7_SIGNER_INFO) *sk;
+
+	bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+	bio_out=BIO_new_fp(stdout,BIO_NOCLOSE);
+#ifndef OPENSSL_NO_MD2
+	EVP_add_digest(EVP_md2());
+#endif
+#ifndef OPENSSL_NO_MD5
+	EVP_add_digest(EVP_md5());
+#endif
+#ifndef OPENSSL_NO_SHA1
+	EVP_add_digest(EVP_sha1());
+#endif
+#ifndef OPENSSL_NO_MDC2
+	EVP_add_digest(EVP_mdc2());
+#endif
+
+	data=BIO_new(BIO_s_file());
+
+	pp=NULL;
+	while (argc > 1)
+		{
+		argc--;
+		argv++;
+		if (strcmp(argv[0],"-p") == 0)
+			{
+			printit=1;
+			}
+		else if ((strcmp(argv[0],"-d") == 0) && (argc >= 2))
+			{
+			detached=BIO_new(BIO_s_file());
+			if (!BIO_read_filename(detached,argv[1]))
+				goto err;
+			argc--;
+			argv++;
+			}
+		else
+			{
+			pp=argv[0];
+			if (!BIO_read_filename(data,argv[0]))
+				goto err;
+			}
+		}
+
+	if (pp == NULL)
+		BIO_set_fp(data,stdin,BIO_NOCLOSE);
+
+
+	/* Load the PKCS7 object from a file */
+	if ((p7=PEM_read_bio_PKCS7(data,NULL,NULL,NULL)) == NULL) goto err;
+
+	/* This stuff is being setup for certificate verification.
+	 * When using SSL, it could be replaced with a 
+	 * cert_stre=SSL_CTX_get_cert_store(ssl_ctx); */
+	cert_store=X509_STORE_new();
+	X509_STORE_set_default_paths(cert_store);
+	X509_STORE_load_locations(cert_store,NULL,"../../certs");
+	X509_STORE_set_verify_cb_func(cert_store,verify_callback);
+
+	ERR_clear_error();
+
+	/* We need to process the data */
+	if ((PKCS7_get_detached(p7) || detached))
+		{
+		if (detached == NULL)
+			{
+			printf("no data to verify the signature on\n");
+			exit(1);
+			}
+		else
+			p7bio=PKCS7_dataInit(p7,detached);
+		}
+	else
+		{
+		p7bio=PKCS7_dataInit(p7,NULL);
+		}
+
+	/* We now have to 'read' from p7bio to calculate digests etc. */
+	for (;;)
+		{
+		i=BIO_read(p7bio,buf,sizeof(buf));
+		/* print it? */
+		if (i <= 0) break;
+		}
+
+	/* We can now verify signatures */
+	sk=PKCS7_get_signer_info(p7);
+	if (sk == NULL)
+		{
+		printf("there are no signatures on this data\n");
+		exit(1);
+		}
+
+	/* Ok, first we need to, for each subject entry, see if we can verify */
+	for (i=0; i<sk_PKCS7_SIGNER_INFO_num(sk); i++)
+		{
+		ASN1_UTCTIME *tm;
+		char *str1,*str2;
+		int rc;
+
+		si=sk_PKCS7_SIGNER_INFO_value(sk,i);
+		rc=PKCS7_dataVerify(cert_store,&cert_ctx,p7bio,p7,si);
+		if (rc <= 0)
+			goto err;
+		printf("signer info\n");
+		if ((tm=get_signed_time(si)) != NULL)
+			{
+			BIO_printf(bio_out,"Signed time:");
+			ASN1_UTCTIME_print(bio_out,tm);
+			ASN1_UTCTIME_free(tm);
+			BIO_printf(bio_out,"\n");
+			}
+		if (get_signed_seq2string(si,&str1,&str2))
+			{
+			BIO_printf(bio_out,"String 1 is %s\n",str1);
+			BIO_printf(bio_out,"String 2 is %s\n",str2);
+			}
+
+		}
+
+	X509_STORE_free(cert_store);
+
+	printf("done\n");
+	exit(0);
+err:
+	ERR_load_crypto_strings();
+	ERR_print_errors_fp(stderr);
+	exit(1);
+	}
+
+/* should be X509 * but we can just have them as char *. */
+int verify_callback(int ok, X509_STORE_CTX *ctx)
+	{
+	char buf[256];
+	X509 *err_cert;
+	int err,depth;
+
+	err_cert=X509_STORE_CTX_get_current_cert(ctx);
+	err=	X509_STORE_CTX_get_error(ctx);
+	depth=	X509_STORE_CTX_get_error_depth(ctx);
+
+	X509_NAME_oneline(X509_get_subject_name(err_cert),buf,256);
+	BIO_printf(bio_err,"depth=%d %s\n",depth,buf);
+	if (!ok)
+		{
+		BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
+			X509_verify_cert_error_string(err));
+		if (depth < 6)
+			{
+			ok=1;
+			X509_STORE_CTX_set_error(ctx,X509_V_OK);
+			}
+		else
+			{
+			ok=0;
+			X509_STORE_CTX_set_error(ctx,X509_V_ERR_CERT_CHAIN_TOO_LONG);
+			}
+		}
+	switch (ctx->error)
+		{
+	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+		X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
+		BIO_printf(bio_err,"issuer= %s\n",buf);
+		break;
+	case X509_V_ERR_CERT_NOT_YET_VALID:
+	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+		BIO_printf(bio_err,"notBefore=");
+		ASN1_UTCTIME_print(bio_err,X509_get_notBefore(ctx->current_cert));
+		BIO_printf(bio_err,"\n");
+		break;
+	case X509_V_ERR_CERT_HAS_EXPIRED:
+	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+		BIO_printf(bio_err,"notAfter=");
+		ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ctx->current_cert));
+		BIO_printf(bio_err,"\n");
+		break;
+		}
+	BIO_printf(bio_err,"verify return:%d\n",ok);
+	return(ok);
+	}
diff --git a/openssl/crypto/ppccpuid.pl b/openssl/crypto/ppccpuid.pl
new file mode 100644
index 0000000..369e1d0
--- /dev/null
+++ b/openssl/crypto/ppccpuid.pl
@@ -0,0 +1,96 @@
+#!/usr/bin/env perl
+
+$flavour = shift;
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
+
+if ($flavour=~/64/) {
+    $CMPLI="cmpldi";
+    $SHRLI="srdi";
+    $SIGNX="extsw";
+} else {
+    $CMPLI="cmplwi";
+    $SHRLI="srwi";
+    $SIGNX="mr";
+}
+
+$code=<<___;
+.machine	"any"
+.text
+
+.globl	.OPENSSL_cpuid_setup
+.align	4
+.OPENSSL_cpuid_setup:
+	blr
+
+.globl	.OPENSSL_wipe_cpu
+.align	4
+.OPENSSL_wipe_cpu:
+	xor	r0,r0,r0
+	mr	r3,r1
+	xor	r4,r4,r4
+	xor	r5,r5,r5
+	xor	r6,r6,r6
+	xor	r7,r7,r7
+	xor	r8,r8,r8
+	xor	r9,r9,r9
+	xor	r10,r10,r10
+	xor	r11,r11,r11
+	xor	r12,r12,r12
+	blr
+
+.globl	.OPENSSL_atomic_add
+.align	4
+.OPENSSL_atomic_add:
+Loop:	lwarx	r5,0,r3
+	add	r0,r4,r5
+	stwcx.	r0,0,r3
+	bne-	Loop
+	$SIGNX	r3,r0
+	blr
+
+.globl	.OPENSSL_rdtsc
+.align	4
+.OPENSSL_rdtsc:
+	mftb	r3
+	mftbu	r4
+	blr
+
+.globl	.OPENSSL_cleanse
+.align	4
+.OPENSSL_cleanse:
+	$CMPLI	r4,7
+	li	r0,0
+	bge	Lot
+	$CMPLI	r4,0
+	beqlr-
+Little:	mtctr	r4
+	stb	r0,0(r3)
+	addi	r3,r3,1
+	bdnz-	\$-8
+	blr
+Lot:	andi.	r5,r3,3
+	beq	Laligned
+	stb	r0,0(r3)
+	subi	r4,r4,1
+	addi	r3,r3,1
+	b	Lot
+Laligned:
+	$SHRLI	r5,r4,2
+	mtctr	r5
+	stw	r0,0(r3)
+	addi	r3,r3,4
+	bdnz-	\$-8
+	andi.	r4,r4,3
+	bne	Little
+	blr
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/pqueue/Makefile b/openssl/crypto/pqueue/Makefile
new file mode 100644
index 0000000..fb36a0c
--- /dev/null
+++ b/openssl/crypto/pqueue/Makefile
@@ -0,0 +1,83 @@
+#
+# OpenSSL/crypto/pqueue/Makefile
+#
+
+DIR=	pqueue
+TOP=	../..
+CC=	cc
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=pqueue.c
+LIBOBJ=pqueue.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= pqueue.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+pqueue.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+pqueue.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+pqueue.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+pqueue.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+pqueue.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pqueue.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+pqueue.o: ../../include/openssl/symhacks.h ../cryptlib.h pqueue.c pqueue.h
diff --git a/openssl/crypto/pqueue/pq_test.c b/openssl/crypto/pqueue/pq_test.c
new file mode 100644
index 0000000..8d496df
--- /dev/null
+++ b/openssl/crypto/pqueue/pq_test.c
@@ -0,0 +1,95 @@
+/* crypto/pqueue/pq_test.c */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "pqueue.h"
+
+int
+main(void)
+	{
+	pitem *item;
+	pqueue pq;
+
+	pq = pqueue_new();
+
+	item = pitem_new(3, NULL);
+	pqueue_insert(pq, item);
+
+	item = pitem_new(1, NULL);
+	pqueue_insert(pq, item);
+
+	item = pitem_new(2, NULL);
+	pqueue_insert(pq, item);
+
+	item = pqueue_find(pq, 1);
+	fprintf(stderr, "found %ld\n", item->priority);
+
+	item = pqueue_find(pq, 2);
+	fprintf(stderr, "found %ld\n", item->priority);
+
+	item = pqueue_find(pq, 3);
+	fprintf(stderr, "found %ld\n", item ? item->priority: 0);
+
+	pqueue_print(pq);
+
+	for(item = pqueue_pop(pq); item != NULL; item = pqueue_pop(pq))
+		pitem_free(item);
+
+	pqueue_free(pq);
+	return 0;
+	}
diff --git a/openssl/crypto/pqueue/pqueue.c b/openssl/crypto/pqueue/pqueue.c
new file mode 100644
index 0000000..eab13a1
--- /dev/null
+++ b/openssl/crypto/pqueue/pqueue.c
@@ -0,0 +1,252 @@
+/* crypto/pqueue/pqueue.c */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include "pqueue.h"
+
+typedef struct _pqueue
+	{
+	pitem *items;
+	int count;
+	} pqueue_s;
+
+pitem *
+pitem_new(unsigned char *prio64be, void *data)
+	{
+	pitem *item = (pitem *) OPENSSL_malloc(sizeof(pitem));
+	if (item == NULL) return NULL;
+
+	memcpy(item->priority,prio64be,sizeof(item->priority));
+
+	item->data = data;
+	item->next = NULL;
+
+	return item;
+	}
+
+void
+pitem_free(pitem *item)
+	{
+	if (item == NULL) return;
+
+	OPENSSL_free(item);
+	}
+
+pqueue_s *
+pqueue_new()
+	{
+	pqueue_s *pq = (pqueue_s *) OPENSSL_malloc(sizeof(pqueue_s));
+	if (pq == NULL) return NULL;
+
+	memset(pq, 0x00, sizeof(pqueue_s));
+	return pq;
+	}
+
+void
+pqueue_free(pqueue_s *pq)
+	{
+	if (pq == NULL) return;
+
+	OPENSSL_free(pq);
+	}
+
+pitem *
+pqueue_insert(pqueue_s *pq, pitem *item)
+	{
+	pitem *curr, *next;
+
+	if (pq->items == NULL)
+		{
+		pq->items = item;
+		return item;
+		}
+
+	for(curr = NULL, next = pq->items; 
+		next != NULL;
+		curr = next, next = next->next)
+		{
+		/* we can compare 64-bit value in big-endian encoding
+		 * with memcmp:-) */
+		int cmp = memcmp(next->priority, item->priority,8);
+		if (cmp > 0)		/* next > item */
+			{
+			item->next = next;
+
+			if (curr == NULL) 
+				pq->items = item;
+			else  
+				curr->next = item;
+
+			return item;
+			}
+		
+		else if (cmp == 0)	/* duplicates not allowed */
+			return NULL;
+		}
+
+	item->next = NULL;
+	curr->next = item;
+
+	return item;
+	}
+
+pitem *
+pqueue_peek(pqueue_s *pq)
+	{
+	return pq->items;
+	}
+
+pitem *
+pqueue_pop(pqueue_s *pq)
+	{
+	pitem *item = pq->items;
+
+	if (pq->items != NULL)
+		pq->items = pq->items->next;
+
+	return item;
+	}
+
+pitem *
+pqueue_find(pqueue_s *pq, unsigned char *prio64be)
+	{
+	pitem *next;
+	pitem *found = NULL;
+
+	if ( pq->items == NULL)
+		return NULL;
+
+	for ( next = pq->items; next->next != NULL; next = next->next)
+		{
+		if ( memcmp(next->priority, prio64be,8) == 0)
+			{
+			found = next;
+			break;
+			}
+		}
+	
+	/* check the one last node */
+	if ( memcmp(next->priority, prio64be,8) ==0)
+		found = next;
+
+	if ( ! found)
+		return NULL;
+
+#if 0 /* find works in peek mode */
+	if ( prev == NULL)
+		pq->items = next->next;
+	else
+		prev->next = next->next;
+#endif
+
+	return found;
+	}
+
+void
+pqueue_print(pqueue_s *pq)
+	{
+	pitem *item = pq->items;
+
+	while(item != NULL)
+		{
+		printf("item\t%02x%02x%02x%02x%02x%02x%02x%02x\n",
+			item->priority[0],item->priority[1],
+			item->priority[2],item->priority[3],
+			item->priority[4],item->priority[5],
+			item->priority[6],item->priority[7]);
+		item = item->next;
+		}
+	}
+
+pitem *
+pqueue_iterator(pqueue_s *pq)
+	{
+	return pqueue_peek(pq);
+	}
+
+pitem *
+pqueue_next(pitem **item)
+	{
+	pitem *ret;
+
+	if ( item == NULL || *item == NULL)
+		return NULL;
+
+
+	/* *item != NULL */
+	ret = *item;
+	*item = (*item)->next;
+
+	return ret;
+	}
+
+int
+pqueue_size(pqueue_s *pq)
+{
+	pitem *item = pq->items;
+	int count = 0;
+	
+	while(item != NULL)
+	{
+		count++;
+		item = item->next;
+	}
+	return count;
+}
diff --git a/openssl/crypto/pqueue/pqueue.h b/openssl/crypto/pqueue/pqueue.h
new file mode 100644
index 0000000..87fc903
--- /dev/null
+++ b/openssl/crypto/pqueue/pqueue.h
@@ -0,0 +1,94 @@
+/* crypto/pqueue/pqueue.h */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_PQUEUE_H
+#define HEADER_PQUEUE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct _pqueue *pqueue;
+
+typedef struct _pitem
+	{
+	unsigned char priority[8]; /* 64-bit value in big-endian encoding */
+	void *data;
+	struct _pitem *next;
+	} pitem;
+
+typedef struct _pitem *piterator;
+
+pitem *pitem_new(unsigned char *prio64be, void *data);
+void   pitem_free(pitem *item);
+
+pqueue pqueue_new(void);
+void   pqueue_free(pqueue pq);
+
+pitem *pqueue_insert(pqueue pq, pitem *item);
+pitem *pqueue_peek(pqueue pq);
+pitem *pqueue_pop(pqueue pq);
+pitem *pqueue_find(pqueue pq, unsigned char *prio64be);
+pitem *pqueue_iterator(pqueue pq);
+pitem *pqueue_next(piterator *iter);
+
+void   pqueue_print(pqueue pq);
+int    pqueue_size(pqueue pq);
+
+#endif /* ! HEADER_PQUEUE_H */
diff --git a/openssl/crypto/rand/Makefile b/openssl/crypto/rand/Makefile
new file mode 100644
index 0000000..27694aa
--- /dev/null
+++ b/openssl/crypto/rand/Makefile
@@ -0,0 +1,164 @@
+#
+# OpenSSL/crypto/rand/Makefile
+#
+
+DIR=	rand
+TOP=	../..
+CC=	cc
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST= randtest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=md_rand.c randfile.c rand_lib.c rand_err.c rand_egd.c \
+	rand_win.c rand_unix.c rand_os2.c rand_nw.c
+LIBOBJ=md_rand.o randfile.o rand_lib.o rand_err.o rand_egd.o \
+	rand_win.o rand_unix.o rand_os2.o rand_nw.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= rand.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+md_rand.o: ../../e_os.h ../../include/openssl/asn1.h
+md_rand.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+md_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+md_rand.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+md_rand.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+md_rand.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+md_rand.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+md_rand.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+md_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+md_rand.o: md_rand.c rand_lcl.h
+rand_egd.o: ../../include/openssl/buffer.h ../../include/openssl/e_os2.h
+rand_egd.o: ../../include/openssl/opensslconf.h
+rand_egd.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+rand_egd.o: rand_egd.c
+rand_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+rand_err.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+rand_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+rand_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rand_err.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+rand_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rand_err.o: rand_err.c
+rand_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+rand_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+rand_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+rand_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+rand_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+rand_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+rand_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rand_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rand_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rand_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+rand_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+rand_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rand_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+rand_lib.o: ../cryptlib.h rand_lib.c
+rand_nw.o: ../../e_os.h ../../include/openssl/asn1.h
+rand_nw.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+rand_nw.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+rand_nw.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+rand_nw.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rand_nw.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rand_nw.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rand_nw.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+rand_nw.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+rand_nw.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h rand_nw.c
+rand_os2.o: ../../e_os.h ../../include/openssl/asn1.h
+rand_os2.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+rand_os2.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+rand_os2.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+rand_os2.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rand_os2.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rand_os2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rand_os2.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+rand_os2.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+rand_os2.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h
+rand_os2.o: rand_os2.c
+rand_unix.o: ../../e_os.h ../../include/openssl/asn1.h
+rand_unix.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+rand_unix.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+rand_unix.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+rand_unix.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rand_unix.o: ../../include/openssl/objects.h
+rand_unix.o: ../../include/openssl/opensslconf.h
+rand_unix.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rand_unix.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+rand_unix.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+rand_unix.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h
+rand_unix.o: rand_unix.c
+rand_win.o: ../../e_os.h ../../include/openssl/asn1.h
+rand_win.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+rand_win.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+rand_win.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+rand_win.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rand_win.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rand_win.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rand_win.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+rand_win.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+rand_win.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h
+rand_win.o: rand_win.c
+randfile.o: ../../e_os.h ../../include/openssl/buffer.h
+randfile.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+randfile.o: ../../include/openssl/opensslconf.h
+randfile.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+randfile.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+randfile.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+randfile.o: randfile.c
diff --git a/openssl/crypto/rand/md_rand.c b/openssl/crypto/rand/md_rand.c
new file mode 100644
index 0000000..b2f04ff
--- /dev/null
+++ b/openssl/crypto/rand/md_rand.c
@@ -0,0 +1,593 @@
+/* crypto/rand/md_rand.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifdef MD_RAND_DEBUG
+# ifndef NDEBUG
+#   define NDEBUG
+# endif
+#endif
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "e_os.h"
+
+#include <openssl/rand.h>
+#include "rand_lcl.h"
+
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+
+#ifdef BN_DEBUG
+# define PREDICT
+#endif
+
+/* #define PREDICT	1 */
+
+#define STATE_SIZE	1023
+static int state_num=0,state_index=0;
+static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH];
+static unsigned char md[MD_DIGEST_LENGTH];
+static long md_count[2]={0,0};
+static double entropy=0;
+static int initialized=0;
+
+static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
+                                           * holds CRYPTO_LOCK_RAND
+                                           * (to prevent double locking) */
+/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
+static CRYPTO_THREADID locking_threadid; /* valid iff crypto_lock_rand is set */
+
+
+#ifdef PREDICT
+int rand_predictable=0;
+#endif
+
+const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT;
+
+static void ssleay_rand_cleanup(void);
+static void ssleay_rand_seed(const void *buf, int num);
+static void ssleay_rand_add(const void *buf, int num, double add_entropy);
+static int ssleay_rand_bytes(unsigned char *buf, int num);
+static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num);
+static int ssleay_rand_status(void);
+
+RAND_METHOD rand_ssleay_meth={
+	ssleay_rand_seed,
+	ssleay_rand_bytes,
+	ssleay_rand_cleanup,
+	ssleay_rand_add,
+	ssleay_rand_pseudo_bytes,
+	ssleay_rand_status
+	}; 
+
+RAND_METHOD *RAND_SSLeay(void)
+	{
+	return(&rand_ssleay_meth);
+	}
+
+static void ssleay_rand_cleanup(void)
+	{
+	OPENSSL_cleanse(state,sizeof(state));
+	state_num=0;
+	state_index=0;
+	OPENSSL_cleanse(md,MD_DIGEST_LENGTH);
+	md_count[0]=0;
+	md_count[1]=0;
+	entropy=0;
+	initialized=0;
+	}
+
+static void ssleay_rand_add(const void *buf, int num, double add)
+	{
+	int i,j,k,st_idx;
+	long md_c[2];
+	unsigned char local_md[MD_DIGEST_LENGTH];
+	EVP_MD_CTX m;
+	int do_not_lock;
+
+	/*
+	 * (Based on the rand(3) manpage)
+	 *
+	 * The input is chopped up into units of 20 bytes (or less for
+	 * the last block).  Each of these blocks is run through the hash
+	 * function as follows:  The data passed to the hash function
+	 * is the current 'md', the same number of bytes from the 'state'
+	 * (the location determined by in incremented looping index) as
+	 * the current 'block', the new key data 'block', and 'count'
+	 * (which is incremented after each use).
+	 * The result of this is kept in 'md' and also xored into the
+	 * 'state' at the same locations that were used as input into the
+         * hash function.
+	 */
+
+	/* check if we already have the lock */
+	if (crypto_lock_rand)
+		{
+		CRYPTO_THREADID cur;
+		CRYPTO_THREADID_current(&cur);
+		CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
+		do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
+		CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
+		}
+	else
+		do_not_lock = 0;
+
+	if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+	st_idx=state_index;
+
+	/* use our own copies of the counters so that even
+	 * if a concurrent thread seeds with exactly the
+	 * same data and uses the same subarray there's _some_
+	 * difference */
+	md_c[0] = md_count[0];
+	md_c[1] = md_count[1];
+
+	memcpy(local_md, md, sizeof md);
+
+	/* state_index <= state_num <= STATE_SIZE */
+	state_index += num;
+	if (state_index >= STATE_SIZE)
+		{
+		state_index%=STATE_SIZE;
+		state_num=STATE_SIZE;
+		}
+	else if (state_num < STATE_SIZE)	
+		{
+		if (state_index > state_num)
+			state_num=state_index;
+		}
+	/* state_index <= state_num <= STATE_SIZE */
+
+	/* state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE]
+	 * are what we will use now, but other threads may use them
+	 * as well */
+
+	md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
+
+	if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+
+	EVP_MD_CTX_init(&m);
+	for (i=0; i<num; i+=MD_DIGEST_LENGTH)
+		{
+		j=(num-i);
+		j=(j > MD_DIGEST_LENGTH)?MD_DIGEST_LENGTH:j;
+
+		MD_Init(&m);
+		MD_Update(&m,local_md,MD_DIGEST_LENGTH);
+		k=(st_idx+j)-STATE_SIZE;
+		if (k > 0)
+			{
+			MD_Update(&m,&(state[st_idx]),j-k);
+			MD_Update(&m,&(state[0]),k);
+			}
+		else
+			MD_Update(&m,&(state[st_idx]),j);
+
+		/* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
+		MD_Update(&m,buf,j);
+		/* We know that line may cause programs such as
+		   purify and valgrind to complain about use of
+		   uninitialized data.  The problem is not, it's
+		   with the caller.  Removing that line will make
+		   sure you get really bad randomness and thereby
+		   other problems such as very insecure keys. */
+
+		MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
+		MD_Final(&m,local_md);
+		md_c[1]++;
+
+		buf=(const char *)buf + j;
+
+		for (k=0; k<j; k++)
+			{
+			/* Parallel threads may interfere with this,
+			 * but always each byte of the new state is
+			 * the XOR of some previous value of its
+			 * and local_md (itermediate values may be lost).
+			 * Alway using locking could hurt performance more
+			 * than necessary given that conflicts occur only
+			 * when the total seeding is longer than the random
+			 * state. */
+			state[st_idx++]^=local_md[k];
+			if (st_idx >= STATE_SIZE)
+				st_idx=0;
+			}
+		}
+	EVP_MD_CTX_cleanup(&m);
+
+	if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+	/* Don't just copy back local_md into md -- this could mean that
+	 * other thread's seeding remains without effect (except for
+	 * the incremented counter).  By XORing it we keep at least as
+	 * much entropy as fits into md. */
+	for (k = 0; k < (int)sizeof(md); k++)
+		{
+		md[k] ^= local_md[k];
+		}
+	if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
+	    entropy += add;
+	if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+	
+#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32)
+	assert(md_c[1] == md_count[1]);
+#endif
+	}
+
+static void ssleay_rand_seed(const void *buf, int num)
+	{
+	ssleay_rand_add(buf, num, (double)num);
+	}
+
+static int ssleay_rand_bytes(unsigned char *buf, int num)
+	{
+	static volatile int stirred_pool = 0;
+	int i,j,k,st_num,st_idx;
+	int num_ceil;
+	int ok;
+	long md_c[2];
+	unsigned char local_md[MD_DIGEST_LENGTH];
+	EVP_MD_CTX m;
+#ifndef GETPID_IS_MEANINGLESS
+	pid_t curr_pid = getpid();
+#endif
+	int do_stir_pool = 0;
+
+#ifdef PREDICT
+	if (rand_predictable)
+		{
+		static unsigned char val=0;
+
+		for (i=0; i<num; i++)
+			buf[i]=val++;
+		return(1);
+		}
+#endif
+
+	if (num <= 0)
+		return 1;
+
+	EVP_MD_CTX_init(&m);
+	/* round upwards to multiple of MD_DIGEST_LENGTH/2 */
+	num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2);
+
+	/*
+	 * (Based on the rand(3) manpage:)
+	 *
+	 * For each group of 10 bytes (or less), we do the following:
+	 *
+	 * Input into the hash function the local 'md' (which is initialized from
+	 * the global 'md' before any bytes are generated), the bytes that are to
+	 * be overwritten by the random bytes, and bytes from the 'state'
+	 * (incrementing looping index). From this digest output (which is kept
+	 * in 'md'), the top (up to) 10 bytes are returned to the caller and the
+	 * bottom 10 bytes are xored into the 'state'.
+	 * 
+	 * Finally, after we have finished 'num' random bytes for the
+	 * caller, 'count' (which is incremented) and the local and global 'md'
+	 * are fed into the hash function and the results are kept in the
+	 * global 'md'.
+	 */
+
+	CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+
+	/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
+	CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
+	CRYPTO_THREADID_current(&locking_threadid);
+	CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
+	crypto_lock_rand = 1;
+
+	if (!initialized)
+		{
+		RAND_poll();
+		initialized = 1;
+		}
+	
+	if (!stirred_pool)
+		do_stir_pool = 1;
+	
+	ok = (entropy >= ENTROPY_NEEDED);
+	if (!ok)
+		{
+		/* If the PRNG state is not yet unpredictable, then seeing
+		 * the PRNG output may help attackers to determine the new
+		 * state; thus we have to decrease the entropy estimate.
+		 * Once we've had enough initial seeding we don't bother to
+		 * adjust the entropy count, though, because we're not ambitious
+		 * to provide *information-theoretic* randomness.
+		 *
+		 * NOTE: This approach fails if the program forks before
+		 * we have enough entropy. Entropy should be collected
+		 * in a separate input pool and be transferred to the
+		 * output pool only when the entropy limit has been reached.
+		 */
+		entropy -= num;
+		if (entropy < 0)
+			entropy = 0;
+		}
+
+	if (do_stir_pool)
+		{
+		/* In the output function only half of 'md' remains secret,
+		 * so we better make sure that the required entropy gets
+		 * 'evenly distributed' through 'state', our randomness pool.
+		 * The input function (ssleay_rand_add) chains all of 'md',
+		 * which makes it more suitable for this purpose.
+		 */
+
+		int n = STATE_SIZE; /* so that the complete pool gets accessed */
+		while (n > 0)
+			{
+#if MD_DIGEST_LENGTH > 20
+# error "Please adjust DUMMY_SEED."
+#endif
+#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
+			/* Note that the seed does not matter, it's just that
+			 * ssleay_rand_add expects to have something to hash. */
+			ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
+			n -= MD_DIGEST_LENGTH;
+			}
+		if (ok)
+			stirred_pool = 1;
+		}
+
+	st_idx=state_index;
+	st_num=state_num;
+	md_c[0] = md_count[0];
+	md_c[1] = md_count[1];
+	memcpy(local_md, md, sizeof md);
+
+	state_index+=num_ceil;
+	if (state_index > state_num)
+		state_index %= state_num;
+
+	/* state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num]
+	 * are now ours (but other threads may use them too) */
+
+	md_count[0] += 1;
+
+	/* before unlocking, we must clear 'crypto_lock_rand' */
+	crypto_lock_rand = 0;
+	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+
+	while (num > 0)
+		{
+		/* num_ceil -= MD_DIGEST_LENGTH/2 */
+		j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num;
+		num-=j;
+		MD_Init(&m);
+#ifndef GETPID_IS_MEANINGLESS
+		if (curr_pid) /* just in the first iteration to save time */
+			{
+			MD_Update(&m,(unsigned char*)&curr_pid,sizeof curr_pid);
+			curr_pid = 0;
+			}
+#endif
+		MD_Update(&m,local_md,MD_DIGEST_LENGTH);
+		MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
+
+#ifndef PURIFY /* purify complains */
+		/* The following line uses the supplied buffer as a small
+		 * source of entropy: since this buffer is often uninitialised
+		 * it may cause programs such as purify or valgrind to
+		 * complain. So for those builds it is not used: the removal
+		 * of such a small source of entropy has negligible impact on
+		 * security.
+		 */
+		MD_Update(&m,buf,j);
+#endif
+
+		k=(st_idx+MD_DIGEST_LENGTH/2)-st_num;
+		if (k > 0)
+			{
+			MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k);
+			MD_Update(&m,&(state[0]),k);
+			}
+		else
+			MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2);
+		MD_Final(&m,local_md);
+
+		for (i=0; i<MD_DIGEST_LENGTH/2; i++)
+			{
+			state[st_idx++]^=local_md[i]; /* may compete with other threads */
+			if (st_idx >= st_num)
+				st_idx=0;
+			if (i < j)
+				*(buf++)=local_md[i+MD_DIGEST_LENGTH/2];
+			}
+		}
+
+	MD_Init(&m);
+	MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
+	MD_Update(&m,local_md,MD_DIGEST_LENGTH);
+	CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+	MD_Update(&m,md,MD_DIGEST_LENGTH);
+	MD_Final(&m,md);
+	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+
+	EVP_MD_CTX_cleanup(&m);
+	if (ok)
+		return(1);
+	else
+		{
+		RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED);
+		ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
+			"http://www.openssl.org/support/faq.html");
+		return(0);
+		}
+	}
+
+/* pseudo-random bytes that are guaranteed to be unique but not
+   unpredictable */
+static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num) 
+	{
+	int ret;
+	unsigned long err;
+
+	ret = RAND_bytes(buf, num);
+	if (ret == 0)
+		{
+		err = ERR_peek_error();
+		if (ERR_GET_LIB(err) == ERR_LIB_RAND &&
+		    ERR_GET_REASON(err) == RAND_R_PRNG_NOT_SEEDED)
+			ERR_clear_error();
+		}
+	return (ret);
+	}
+
+static int ssleay_rand_status(void)
+	{
+	CRYPTO_THREADID cur;
+	int ret;
+	int do_not_lock;
+
+	CRYPTO_THREADID_current(&cur);
+	/* check if we already have the lock
+	 * (could happen if a RAND_poll() implementation calls RAND_status()) */
+	if (crypto_lock_rand)
+		{
+		CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
+		do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
+		CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
+		}
+	else
+		do_not_lock = 0;
+	
+	if (!do_not_lock)
+		{
+		CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+		
+		/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
+		CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
+		CRYPTO_THREADID_cpy(&locking_threadid, &cur);
+		CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
+		crypto_lock_rand = 1;
+		}
+	
+	if (!initialized)
+		{
+		RAND_poll();
+		initialized = 1;
+		}
+
+	ret = entropy >= ENTROPY_NEEDED;
+
+	if (!do_not_lock)
+		{
+		/* before unlocking, we must clear 'crypto_lock_rand' */
+		crypto_lock_rand = 0;
+		
+		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+		}
+	
+	return ret;
+	}
diff --git a/openssl/crypto/rand/rand.h b/openssl/crypto/rand/rand.h
new file mode 100644
index 0000000..ac6c021
--- /dev/null
+++ b/openssl/crypto/rand/rand.h
@@ -0,0 +1,140 @@
+/* crypto/rand/rand.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RAND_H
+#define HEADER_RAND_H
+
+#include <stdlib.h>
+#include <openssl/ossl_typ.h>
+#include <openssl/e_os2.h>
+
+#if defined(OPENSSL_SYS_WINDOWS)
+#include <windows.h>
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if defined(OPENSSL_FIPS)
+#define FIPS_RAND_SIZE_T size_t
+#endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct rand_meth_st RAND_METHOD; */
+
+struct rand_meth_st
+	{
+	void (*seed)(const void *buf, int num);
+	int (*bytes)(unsigned char *buf, int num);
+	void (*cleanup)(void);
+	void (*add)(const void *buf, int num, double entropy);
+	int (*pseudorand)(unsigned char *buf, int num);
+	int (*status)(void);
+	};
+
+#ifdef BN_DEBUG
+extern int rand_predictable;
+#endif
+
+int RAND_set_rand_method(const RAND_METHOD *meth);
+const RAND_METHOD *RAND_get_rand_method(void);
+#ifndef OPENSSL_NO_ENGINE
+int RAND_set_rand_engine(ENGINE *engine);
+#endif
+RAND_METHOD *RAND_SSLeay(void);
+void RAND_cleanup(void );
+int  RAND_bytes(unsigned char *buf,int num);
+int  RAND_pseudo_bytes(unsigned char *buf,int num);
+void RAND_seed(const void *buf,int num);
+void RAND_add(const void *buf,int num,double entropy);
+int  RAND_load_file(const char *file,long max_bytes);
+int  RAND_write_file(const char *file);
+const char *RAND_file_name(char *file,size_t num);
+int RAND_status(void);
+int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes);
+int RAND_egd(const char *path);
+int RAND_egd_bytes(const char *path,int bytes);
+int RAND_poll(void);
+
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
+
+void RAND_screen(void);
+int RAND_event(UINT, WPARAM, LPARAM);
+
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_RAND_strings(void);
+
+/* Error codes for the RAND functions. */
+
+/* Function codes. */
+#define RAND_F_RAND_GET_RAND_METHOD			 101
+#define RAND_F_SSLEAY_RAND_BYTES			 100
+
+/* Reason codes. */
+#define RAND_R_PRNG_NOT_SEEDED				 100
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/rand/rand_egd.c b/openssl/crypto/rand/rand_egd.c
new file mode 100644
index 0000000..d53b916
--- /dev/null
+++ b/openssl/crypto/rand/rand_egd.c
@@ -0,0 +1,303 @@
+/* crypto/rand/rand_egd.c */
+/* Written by Ulf Moeller and Lutz Jaenicke for the OpenSSL project. */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/e_os2.h>
+#include <openssl/rand.h>
+#include <openssl/buffer.h>
+
+/*
+ * Query the EGD <URL: http://www.lothar.com/tech/crypto/>.
+ *
+ * This module supplies three routines:
+ *
+ * RAND_query_egd_bytes(path, buf, bytes)
+ *   will actually query "bytes" bytes of entropy form the egd-socket located
+ *   at path and will write them to buf (if supplied) or will directly feed
+ *   it to RAND_seed() if buf==NULL.
+ *   The number of bytes is not limited by the maximum chunk size of EGD,
+ *   which is 255 bytes. If more than 255 bytes are wanted, several chunks
+ *   of entropy bytes are requested. The connection is left open until the
+ *   query is competed.
+ *   RAND_query_egd_bytes() returns with
+ *     -1  if an error occured during connection or communication.
+ *     num the number of bytes read from the EGD socket. This number is either
+ *         the number of bytes requested or smaller, if the EGD pool is
+ *         drained and the daemon signals that the pool is empty.
+ *   This routine does not touch any RAND_status(). This is necessary, since
+ *   PRNG functions may call it during initialization.
+ *
+ * RAND_egd_bytes(path, bytes) will query "bytes" bytes and have them
+ *   used to seed the PRNG.
+ *   RAND_egd_bytes() is a wrapper for RAND_query_egd_bytes() with buf=NULL.
+ *   Unlike RAND_query_egd_bytes(), RAND_status() is used to test the
+ *   seed status so that the return value can reflect the seed state:
+ *     -1  if an error occured during connection or communication _or_
+ *         if the PRNG has still not received the required seeding.
+ *     num the number of bytes read from the EGD socket. This number is either
+ *         the number of bytes requested or smaller, if the EGD pool is
+ *         drained and the daemon signals that the pool is empty.
+ *
+ * RAND_egd(path) will query 255 bytes and use the bytes retreived to seed
+ *   the PRNG.
+ *   RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255.
+ */
+
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS)
+int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
+	{
+	return(-1);
+	}
+int RAND_egd(const char *path)
+	{
+	return(-1);
+	}
+
+int RAND_egd_bytes(const char *path,int bytes)
+	{
+	return(-1);
+	}
+#else
+#include <openssl/opensslconf.h>
+#include OPENSSL_UNISTD
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifndef NO_SYS_UN_H
+# ifdef OPENSSL_SYS_VXWORKS
+#   include <streams/un.h>
+# else
+#   include <sys/un.h>
+# endif
+#else
+struct	sockaddr_un {
+	short	sun_family;		/* AF_UNIX */
+	char	sun_path[108];		/* path name (gag) */
+};
+#endif /* NO_SYS_UN_H */
+#include <string.h>
+#include <errno.h>
+
+#ifndef offsetof
+#  define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
+	{
+	int ret = 0;
+	struct sockaddr_un addr;
+	int len, num, numbytes;
+	int fd = -1;
+	int success;
+	unsigned char egdbuf[2], tempbuf[255], *retrievebuf;
+
+	memset(&addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+	if (strlen(path) >= sizeof(addr.sun_path))
+		return (-1);
+	BUF_strlcpy(addr.sun_path,path,sizeof addr.sun_path);
+	len = offsetof(struct sockaddr_un, sun_path) + strlen(path);
+	fd = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (fd == -1) return (-1);
+	success = 0;
+	while (!success)
+	    {
+	    if (connect(fd, (struct sockaddr *)&addr, len) == 0)
+	       success = 1;
+	    else
+		{
+		switch (errno)
+		    {
+#ifdef EINTR
+		    case EINTR:
+#endif
+#ifdef EAGAIN
+		    case EAGAIN:
+#endif
+#ifdef EINPROGRESS
+		    case EINPROGRESS:
+#endif
+#ifdef EALREADY
+		    case EALREADY:
+#endif
+			/* No error, try again */
+			break;
+#ifdef EISCONN
+		    case EISCONN:
+			success = 1;
+			break;
+#endif
+		    default:
+			goto err;	/* failure */
+		    }
+		}
+	    }
+
+	while(bytes > 0)
+	    {
+	    egdbuf[0] = 1;
+	    egdbuf[1] = bytes < 255 ? bytes : 255;
+	    numbytes = 0;
+	    while (numbytes != 2)
+		{
+	        num = write(fd, egdbuf + numbytes, 2 - numbytes);
+	        if (num >= 0)
+		    numbytes += num;
+	    	else
+		    {
+		    switch (errno)
+		    	{
+#ifdef EINTR
+		    	case EINTR:
+#endif
+#ifdef EAGAIN
+		    	case EAGAIN:
+#endif
+			    /* No error, try again */
+			    break;
+		    	default:
+			    ret = -1;
+			    goto err;	/* failure */
+			}
+		    }
+		}
+	    numbytes = 0;
+	    while (numbytes != 1)
+		{
+	        num = read(fd, egdbuf, 1);
+	        if (num == 0)
+			goto err;	/* descriptor closed */
+		else if (num > 0)
+		    numbytes += num;
+	    	else
+		    {
+		    switch (errno)
+		    	{
+#ifdef EINTR
+		    	case EINTR:
+#endif
+#ifdef EAGAIN
+		    	case EAGAIN:
+#endif
+			    /* No error, try again */
+			    break;
+		    	default:
+			    ret = -1;
+			    goto err;	/* failure */
+			}
+		    }
+		}
+	    if(egdbuf[0] == 0)
+		goto err;
+	    if (buf)
+		retrievebuf = buf + ret;
+	    else
+		retrievebuf = tempbuf;
+	    numbytes = 0;
+	    while (numbytes != egdbuf[0])
+		{
+	        num = read(fd, retrievebuf + numbytes, egdbuf[0] - numbytes);
+		if (num == 0)
+			goto err;	/* descriptor closed */
+	        else if (num > 0)
+		    numbytes += num;
+	    	else
+		    {
+		    switch (errno)
+		    	{
+#ifdef EINTR
+		    	case EINTR:
+#endif
+#ifdef EAGAIN
+		    	case EAGAIN:
+#endif
+			    /* No error, try again */
+			    break;
+		    	default:
+			    ret = -1;
+			    goto err;	/* failure */
+			}
+		    }
+		}
+	    ret += egdbuf[0];
+	    bytes -= egdbuf[0];
+	    if (!buf)
+		RAND_seed(tempbuf, egdbuf[0]);
+	    }
+ err:
+	if (fd != -1) close(fd);
+	return(ret);
+	}
+
+
+int RAND_egd_bytes(const char *path, int bytes)
+	{
+	int num, ret = 0;
+
+	num = RAND_query_egd_bytes(path, NULL, bytes);
+	if (num < 1) goto err;
+	if (RAND_status() == 1)
+	    ret = num;
+ err:
+	return(ret);
+	}
+
+
+int RAND_egd(const char *path)
+	{
+	return (RAND_egd_bytes(path, 255));
+	}
+
+
+#endif
diff --git a/openssl/crypto/rand/rand_err.c b/openssl/crypto/rand/rand_err.c
new file mode 100644
index 0000000..03cda4d
--- /dev/null
+++ b/openssl/crypto/rand/rand_err.c
@@ -0,0 +1,96 @@
+/* crypto/rand/rand_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_RAND,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_RAND,0,reason)
+
+static ERR_STRING_DATA RAND_str_functs[]=
+	{
+{ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD),	"RAND_get_rand_method"},
+{ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES),	"SSLEAY_RAND_BYTES"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA RAND_str_reasons[]=
+	{
+{ERR_REASON(RAND_R_PRNG_NOT_SEEDED)      ,"PRNG not seeded"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_RAND_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(RAND_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,RAND_str_functs);
+		ERR_load_strings(0,RAND_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/rand/rand_lcl.h b/openssl/crypto/rand/rand_lcl.h
new file mode 100644
index 0000000..618a8ec
--- /dev/null
+++ b/openssl/crypto/rand/rand_lcl.h
@@ -0,0 +1,158 @@
+/* crypto/rand/rand_lcl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_RAND_LCL_H
+#define HEADER_RAND_LCL_H
+
+#define ENTROPY_NEEDED 32  /* require 256 bits = 32 bytes of randomness */
+
+
+#if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND)
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+#define USE_SHA1_RAND
+#elif !defined(OPENSSL_NO_MD5)
+#define USE_MD5_RAND
+#elif !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES)
+#define USE_MDC2_RAND
+#elif !defined(OPENSSL_NO_MD2)
+#define USE_MD2_RAND
+#else
+#error No message digest algorithm available
+#endif
+#endif
+
+#include <openssl/evp.h>
+#define MD_Update(a,b,c)	EVP_DigestUpdate(a,b,c)
+#define	MD_Final(a,b)		EVP_DigestFinal_ex(a,b,NULL)
+#if defined(USE_MD5_RAND)
+#include <openssl/md5.h>
+#define MD_DIGEST_LENGTH	MD5_DIGEST_LENGTH
+#define MD_Init(a)		EVP_DigestInit_ex(a,EVP_md5(), NULL)
+#define	MD(a,b,c)		EVP_Digest(a,b,c,NULL,EVP_md5(), NULL)
+#elif defined(USE_SHA1_RAND)
+#include <openssl/sha.h>
+#define MD_DIGEST_LENGTH	SHA_DIGEST_LENGTH
+#define MD_Init(a)		EVP_DigestInit_ex(a,EVP_sha1(), NULL)
+#define	MD(a,b,c)		EVP_Digest(a,b,c,NULL,EVP_sha1(), NULL)
+#elif defined(USE_MDC2_RAND)
+#include <openssl/mdc2.h>
+#define MD_DIGEST_LENGTH	MDC2_DIGEST_LENGTH
+#define MD_Init(a)		EVP_DigestInit_ex(a,EVP_mdc2(), NULL)
+#define	MD(a,b,c)		EVP_Digest(a,b,c,NULL,EVP_mdc2(), NULL)
+#elif defined(USE_MD2_RAND)
+#include <openssl/md2.h>
+#define MD_DIGEST_LENGTH	MD2_DIGEST_LENGTH
+#define MD_Init(a)		EVP_DigestInit_ex(a,EVP_md2(), NULL)
+#define	MD(a,b,c)		EVP_Digest(a,b,c,NULL,EVP_md2(), NULL)
+#endif
+
+
+#endif
diff --git a/openssl/crypto/rand/rand_lib.c b/openssl/crypto/rand/rand_lib.c
new file mode 100644
index 0000000..513e338
--- /dev/null
+++ b/openssl/crypto/rand/rand_lib.c
@@ -0,0 +1,176 @@
+/* crypto/rand/rand_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+#ifndef OPENSSL_NO_ENGINE
+/* non-NULL if default_RAND_meth is ENGINE-provided */
+static ENGINE *funct_ref =NULL;
+#endif
+static const RAND_METHOD *default_RAND_meth = NULL;
+
+int RAND_set_rand_method(const RAND_METHOD *meth)
+	{
+#ifndef OPENSSL_NO_ENGINE
+	if(funct_ref)
+		{
+		ENGINE_finish(funct_ref);
+		funct_ref = NULL;
+		}
+#endif
+	default_RAND_meth = meth;
+	return 1;
+	}
+
+const RAND_METHOD *RAND_get_rand_method(void)
+	{
+	if (!default_RAND_meth)
+		{
+#ifndef OPENSSL_NO_ENGINE
+		ENGINE *e = ENGINE_get_default_RAND();
+		if(e)
+			{
+			default_RAND_meth = ENGINE_get_RAND(e);
+			if(!default_RAND_meth)
+				{
+				ENGINE_finish(e);
+				e = NULL;
+				}
+			}
+		if(e)
+			funct_ref = e;
+		else
+#endif
+			default_RAND_meth = RAND_SSLeay();
+		}
+	return default_RAND_meth;
+	}
+
+#ifndef OPENSSL_NO_ENGINE
+int RAND_set_rand_engine(ENGINE *engine)
+	{
+	const RAND_METHOD *tmp_meth = NULL;
+	if(engine)
+		{
+		if(!ENGINE_init(engine))
+			return 0;
+		tmp_meth = ENGINE_get_RAND(engine);
+		if(!tmp_meth)
+			{
+			ENGINE_finish(engine);
+			return 0;
+			}
+		}
+	/* This function releases any prior ENGINE so call it first */
+	RAND_set_rand_method(tmp_meth);
+	funct_ref = engine;
+	return 1;
+	}
+#endif
+
+void RAND_cleanup(void)
+	{
+	const RAND_METHOD *meth = RAND_get_rand_method();
+	if (meth && meth->cleanup)
+		meth->cleanup();
+	RAND_set_rand_method(NULL);
+	}
+
+void RAND_seed(const void *buf, int num)
+	{
+	const RAND_METHOD *meth = RAND_get_rand_method();
+	if (meth && meth->seed)
+		meth->seed(buf,num);
+	}
+
+void RAND_add(const void *buf, int num, double entropy)
+	{
+	const RAND_METHOD *meth = RAND_get_rand_method();
+	if (meth && meth->add)
+		meth->add(buf,num,entropy);
+	}
+
+int RAND_bytes(unsigned char *buf, int num)
+	{
+	const RAND_METHOD *meth = RAND_get_rand_method();
+	if (meth && meth->bytes)
+		return meth->bytes(buf,num);
+	return(-1);
+	}
+
+int RAND_pseudo_bytes(unsigned char *buf, int num)
+	{
+	const RAND_METHOD *meth = RAND_get_rand_method();
+	if (meth && meth->pseudorand)
+		return meth->pseudorand(buf,num);
+	return(-1);
+	}
+
+int RAND_status(void)
+	{
+	const RAND_METHOD *meth = RAND_get_rand_method();
+	if (meth && meth->status)
+		return meth->status();
+	return 0;
+	}
diff --git a/openssl/crypto/rand/rand_nw.c b/openssl/crypto/rand/rand_nw.c
new file mode 100644
index 0000000..8d5b8d2
--- /dev/null
+++ b/openssl/crypto/rand/rand_nw.c
@@ -0,0 +1,183 @@
+/* crypto/rand/rand_nw.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#include "rand_lcl.h"
+
+#if defined (OPENSSL_SYS_NETWARE)
+
+#if defined(NETWARE_LIBC)
+#include <nks/thread.h>
+#else
+#include <nwthread.h>
+#endif
+
+extern int GetProcessSwitchCount(void);
+#if !defined(NETWARE_LIBC) || (CURRENT_NDK_THRESHOLD < 509220000)
+extern void *RunningProcess; /* declare here same as found in newer NDKs */
+extern unsigned long GetSuperHighResolutionTimer(void);
+#endif
+
+   /* the FAQ indicates we need to provide at least 20 bytes (160 bits) of seed
+   */
+int RAND_poll(void)
+{
+   unsigned long l;
+   unsigned long tsc;
+   int i; 
+
+      /* There are several options to gather miscellaneous data
+       * but for now we will loop checking the time stamp counter (rdtsc) and
+       * the SuperHighResolutionTimer.  Each iteration will collect 8 bytes
+       * of data but it is treated as only 1 byte of entropy.  The call to
+       * ThreadSwitchWithDelay() will introduce additional variability into
+       * the data returned by rdtsc.
+       *
+       * Applications can agument the seed material by adding additional
+       * stuff with RAND_add() and should probably do so.
+      */
+   l = GetProcessSwitchCount();
+   RAND_add(&l,sizeof(l),1);
+   
+   /* need to cast the void* to unsigned long here */
+   l = (unsigned long)RunningProcess;
+   RAND_add(&l,sizeof(l),1);
+
+   for( i=2; i<ENTROPY_NEEDED; i++)
+   {
+#ifdef __MWERKS__
+      asm 
+      {
+         rdtsc
+         mov tsc, eax        
+      }
+#elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+      asm volatile("rdtsc":"=a"(tsc)::"edx");
+#endif
+
+      RAND_add(&tsc, sizeof(tsc), 1);
+
+      l = GetSuperHighResolutionTimer();
+      RAND_add(&l, sizeof(l), 0);
+
+# if defined(NETWARE_LIBC)
+      NXThreadYield();
+# else /* NETWARE_CLIB */
+      ThreadSwitchWithDelay();
+# endif
+   }
+
+   return 1;
+}
+
+#endif 
+
diff --git a/openssl/crypto/rand/rand_os2.c b/openssl/crypto/rand/rand_os2.c
new file mode 100644
index 0000000..fc1e78b
--- /dev/null
+++ b/openssl/crypto/rand/rand_os2.c
@@ -0,0 +1,153 @@
+/* crypto/rand/rand_os2.c */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#include "rand_lcl.h"
+
+#ifdef OPENSSL_SYS_OS2
+
+#define INCL_DOSPROCESS
+#define INCL_DOSPROFILE
+#define INCL_DOSMISC
+#define INCL_DOSMODULEMGR
+#include <os2.h>
+
+#define   CMD_KI_RDCNT    (0x63)
+
+typedef struct _CPUUTIL {
+    ULONG ulTimeLow;            /* Low 32 bits of time stamp      */
+    ULONG ulTimeHigh;           /* High 32 bits of time stamp     */
+    ULONG ulIdleLow;            /* Low 32 bits of idle time       */
+    ULONG ulIdleHigh;           /* High 32 bits of idle time      */
+    ULONG ulBusyLow;            /* Low 32 bits of busy time       */
+    ULONG ulBusyHigh;           /* High 32 bits of busy time      */
+    ULONG ulIntrLow;            /* Low 32 bits of interrupt time  */
+    ULONG ulIntrHigh;           /* High 32 bits of interrupt time */
+} CPUUTIL;
+
+#ifndef __KLIBC__
+APIRET APIENTRY(*DosPerfSysCall) (ULONG ulCommand, ULONG ulParm1, ULONG ulParm2, ULONG ulParm3) = NULL;
+APIRET APIENTRY(*DosQuerySysState) (ULONG func, ULONG arg1, ULONG pid, ULONG _res_, PVOID buf, ULONG bufsz) = NULL;
+#endif
+HMODULE hDoscalls = 0;
+
+int RAND_poll(void)
+{
+    char failed_module[20];
+    QWORD qwTime;
+    ULONG SysVars[QSV_FOREGROUND_PROCESS];
+
+    if (hDoscalls == 0) {
+        ULONG rc = DosLoadModule(failed_module, sizeof(failed_module), "DOSCALLS", &hDoscalls);
+
+#ifndef __KLIBC__
+        if (rc == 0) {
+            rc = DosQueryProcAddr(hDoscalls, 976, NULL, (PFN *)&DosPerfSysCall);
+
+            if (rc)
+                DosPerfSysCall = NULL;
+
+            rc = DosQueryProcAddr(hDoscalls, 368, NULL, (PFN *)&DosQuerySysState);
+
+            if (rc)
+                DosQuerySysState = NULL;
+        }
+#endif
+    }
+
+    /* Sample the hi-res timer, runs at around 1.1 MHz */
+    DosTmrQueryTime(&qwTime);
+    RAND_add(&qwTime, sizeof(qwTime), 2);
+
+    /* Sample a bunch of system variables, includes various process & memory statistics */
+    DosQuerySysInfo(1, QSV_FOREGROUND_PROCESS, SysVars, sizeof(SysVars));
+    RAND_add(SysVars, sizeof(SysVars), 4);
+
+    /* If available, sample CPU registers that count at CPU MHz
+     * Only fairly new CPUs (PPro & K6 onwards) & OS/2 versions support this
+     */
+    if (DosPerfSysCall) {
+        CPUUTIL util;
+
+        if (DosPerfSysCall(CMD_KI_RDCNT, (ULONG)&util, 0, 0) == 0) {
+            RAND_add(&util, sizeof(util), 10);
+        }
+        else {
+#ifndef __KLIBC__
+            DosPerfSysCall = NULL;
+#endif
+        }
+    }
+
+    /* DosQuerySysState() gives us a huge quantity of process, thread, memory & handle stats */
+    if (DosQuerySysState) {
+        char *buffer = OPENSSL_malloc(256 * 1024);
+
+        if (DosQuerySysState(0x1F, 0, 0, 0, buffer, 256 * 1024) == 0) {
+            /* First 4 bytes in buffer is a pointer to the thread count
+             * there should be at least 1 byte of entropy per thread
+             */
+            RAND_add(buffer, 256 * 1024, **(ULONG **)buffer);
+        }
+
+        OPENSSL_free(buffer);
+        return 1;
+    }
+
+    return 0;
+}
+
+#endif /* OPENSSL_SYS_OS2 */
diff --git a/openssl/crypto/rand/rand_unix.c b/openssl/crypto/rand/rand_unix.c
new file mode 100644
index 0000000..e3a6557
--- /dev/null
+++ b/openssl/crypto/rand/rand_unix.c
@@ -0,0 +1,431 @@
+/* crypto/rand/rand_unix.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <stdio.h>
+
+#define USE_SOCKETS
+#include "e_os.h"
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#include "rand_lcl.h"
+
+#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE))
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <time.h>
+#if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually everywhere */
+# include <poll.h>
+#endif
+#include <limits.h>
+#ifndef FD_SETSIZE
+# define FD_SETSIZE (8*sizeof(fd_set))
+#endif
+
+#if defined(OPENSSL_SYS_VOS)
+
+/* The following algorithm repeatedly samples the real-time clock
+   (RTC) to generate a sequence of unpredictable data.  The algorithm
+   relies upon the uneven execution speed of the code (due to factors
+   such as cache misses, interrupts, bus activity, and scheduling) and
+   upon the rather large relative difference between the speed of the
+   clock and the rate at which it can be read.
+
+   If this code is ported to an environment where execution speed is
+   more constant or where the RTC ticks at a much slower rate, or the
+   clock can be read with fewer instructions, it is likely that the
+   results would be far more predictable.
+
+   As a precaution, we generate 4 times the minimum required amount of
+   seed data.  */
+
+int RAND_poll(void)
+{
+	short int code;
+	gid_t curr_gid;
+	pid_t curr_pid;
+	uid_t curr_uid;
+	int i, k;
+	struct timespec ts;
+	unsigned char v;
+
+#ifdef OPENSSL_SYS_VOS_HPPA
+	long duration;
+	extern void s$sleep (long *_duration, short int *_code);
+#else
+#ifdef OPENSSL_SYS_VOS_IA32
+	long long duration;
+	extern void s$sleep2 (long long *_duration, short int *_code);
+#else
+#error "Unsupported Platform."
+#endif /* OPENSSL_SYS_VOS_IA32 */
+#endif /* OPENSSL_SYS_VOS_HPPA */
+
+	/* Seed with the gid, pid, and uid, to ensure *some*
+	   variation between different processes.  */
+
+	curr_gid = getgid();
+	RAND_add (&curr_gid, sizeof curr_gid, 1);
+	curr_gid = 0;
+
+	curr_pid = getpid();
+	RAND_add (&curr_pid, sizeof curr_pid, 1);
+	curr_pid = 0;
+
+	curr_uid = getuid();
+	RAND_add (&curr_uid, sizeof curr_uid, 1);
+	curr_uid = 0;
+
+	for (i=0; i<(ENTROPY_NEEDED*4); i++)
+	{
+		/* burn some cpu; hope for interrupts, cache
+		   collisions, bus interference, etc.  */
+		for (k=0; k<99; k++)
+			ts.tv_nsec = random ();
+
+#ifdef OPENSSL_SYS_VOS_HPPA
+		/* sleep for 1/1024 of a second (976 us).  */
+		duration = 1;
+		s$sleep (&duration, &code);
+#else
+#ifdef OPENSSL_SYS_VOS_IA32
+		/* sleep for 1/65536 of a second (15 us).  */
+		duration = 1;
+		s$sleep2 (&duration, &code);
+#endif /* OPENSSL_SYS_VOS_IA32 */
+#endif /* OPENSSL_SYS_VOS_HPPA */
+
+		/* get wall clock time.  */
+		clock_gettime (CLOCK_REALTIME, &ts);
+
+		/* take 8 bits */
+		v = (unsigned char) (ts.tv_nsec % 256);
+		RAND_add (&v, sizeof v, 1);
+		v = 0;
+	}
+	return 1;
+}
+#elif defined __OpenBSD__
+int RAND_poll(void)
+{
+	u_int32_t rnd = 0, i;
+	unsigned char buf[ENTROPY_NEEDED];
+
+	for (i = 0; i < sizeof(buf); i++) {
+		if (i % 4 == 0)
+			rnd = arc4random();
+		buf[i] = rnd;
+		rnd >>= 8;
+	}
+	RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
+	memset(buf, 0, sizeof(buf));
+
+	return 1;
+}
+#else /* !defined(__OpenBSD__) */
+int RAND_poll(void)
+{
+	unsigned long l;
+	pid_t curr_pid = getpid();
+#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
+	unsigned char tmpbuf[ENTROPY_NEEDED];
+	int n = 0;
+#endif
+#ifdef DEVRANDOM
+	static const char *randomfiles[] = { DEVRANDOM };
+	struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])];
+	int fd;
+	unsigned int i;
+#endif
+#ifdef DEVRANDOM_EGD
+	static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
+	const char **egdsocket = NULL;
+#endif
+
+#ifdef DEVRANDOM
+	memset(randomstats,0,sizeof(randomstats));
+	/* Use a random entropy pool device. Linux, FreeBSD and OpenBSD
+	 * have this. Use /dev/urandom if you can as /dev/random may block
+	 * if it runs out of random entries.  */
+
+	for (i = 0; (i < sizeof(randomfiles)/sizeof(randomfiles[0])) &&
+			(n < ENTROPY_NEEDED); i++)
+		{
+		if ((fd = open(randomfiles[i], O_RDONLY
+#ifdef O_NONBLOCK
+			|O_NONBLOCK
+#endif
+#ifdef O_BINARY
+			|O_BINARY
+#endif
+#ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do not make it
+		   our controlling tty */
+			|O_NOCTTY
+#endif
+			)) >= 0)
+			{
+			int usec = 10*1000; /* spend 10ms on each file */
+			int r;
+			unsigned int j;
+			struct stat *st=&randomstats[i];
+
+			/* Avoid using same input... Used to be O_NOFOLLOW
+			 * above, but it's not universally appropriate... */
+			if (fstat(fd,st) != 0)	{ close(fd); continue; }
+			for (j=0;j<i;j++)
+				{
+				if (randomstats[j].st_ino==st->st_ino &&
+				    randomstats[j].st_dev==st->st_dev)
+					break;
+				}
+			if (j<i)		{ close(fd); continue; }
+
+			do
+				{
+				int try_read = 0;
+
+#if defined(OPENSSL_SYS_BEOS_R5)
+				/* select() is broken in BeOS R5, so we simply
+				 *  try to read something and snooze if we couldn't */
+				try_read = 1;
+
+#elif defined(OPENSSL_SYS_LINUX)
+				/* use poll() */
+				struct pollfd pset;
+				
+				pset.fd = fd;
+				pset.events = POLLIN;
+				pset.revents = 0;
+
+				if (poll(&pset, 1, usec / 1000) < 0)
+					usec = 0;
+				else
+					try_read = (pset.revents & POLLIN) != 0;
+
+#else
+				/* use select() */
+				fd_set fset;
+				struct timeval t;
+				
+				t.tv_sec = 0;
+				t.tv_usec = usec;
+
+				if (FD_SETSIZE > 0 && (unsigned)fd >= FD_SETSIZE)
+					{
+					/* can't use select, so just try to read once anyway */
+					try_read = 1;
+					}
+				else
+					{
+					FD_ZERO(&fset);
+					FD_SET(fd, &fset);
+					
+					if (select(fd+1,&fset,NULL,NULL,&t) >= 0)
+						{
+						usec = t.tv_usec;
+						if (FD_ISSET(fd, &fset))
+							try_read = 1;
+						}
+					else
+						usec = 0;
+					}
+#endif
+				
+				if (try_read)
+					{
+					r = read(fd,(unsigned char *)tmpbuf+n, ENTROPY_NEEDED-n);
+					if (r > 0)
+						n += r;
+#if defined(OPENSSL_SYS_BEOS_R5)
+					if (r == 0)
+						snooze(t.tv_usec);
+#endif
+					}
+				else
+					r = -1;
+				
+				/* Some Unixen will update t in select(), some
+				   won't.  For those who won't, or if we
+				   didn't use select() in the first place,
+				   give up here, otherwise, we will do
+				   this once again for the remaining
+				   time. */
+				if (usec == 10*1000)
+					usec = 0;
+				}
+			while ((r > 0 ||
+			       (errno == EINTR || errno == EAGAIN)) && usec != 0 && n < ENTROPY_NEEDED);
+
+			close(fd);
+			}
+		}
+#endif /* defined(DEVRANDOM) */
+
+#ifdef DEVRANDOM_EGD
+	/* Use an EGD socket to read entropy from an EGD or PRNGD entropy
+	 * collecting daemon. */
+
+	for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED; egdsocket++)
+		{
+		int r;
+
+		r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf+n,
+					 ENTROPY_NEEDED-n);
+		if (r > 0)
+			n += r;
+		}
+#endif /* defined(DEVRANDOM_EGD) */
+
+#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
+	if (n > 0)
+		{
+		RAND_add(tmpbuf,sizeof tmpbuf,(double)n);
+		OPENSSL_cleanse(tmpbuf,n);
+		}
+#endif
+
+	/* put in some default random data, we need more than just this */
+	l=curr_pid;
+	RAND_add(&l,sizeof(l),0.0);
+	l=getuid();
+	RAND_add(&l,sizeof(l),0.0);
+
+	l=time(NULL);
+	RAND_add(&l,sizeof(l),0.0);
+
+#if defined(OPENSSL_SYS_BEOS)
+	{
+	system_info sysInfo;
+	get_system_info(&sysInfo);
+	RAND_add(&sysInfo,sizeof(sysInfo),0);
+	}
+#endif
+
+#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
+	return 1;
+#else
+	return 0;
+#endif
+}
+
+#endif /* defined(__OpenBSD__) */
+#endif /* !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)) */
+
+
+#if defined(OPENSSL_SYS_VXWORKS)
+int RAND_poll(void)
+	{
+	return 0;
+	}
+#endif
diff --git a/openssl/crypto/rand/rand_vms.c b/openssl/crypto/rand/rand_vms.c
new file mode 100644
index 0000000..0bfd8ff
--- /dev/null
+++ b/openssl/crypto/rand/rand_vms.c
@@ -0,0 +1,148 @@
+/* crypto/rand/rand_vms.c -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte <richard@levitte.org> for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/rand.h>
+#include "rand_lcl.h"
+
+#if defined(OPENSSL_SYS_VMS)
+
+#include <descrip.h>
+#include <jpidef.h>
+#include <ssdef.h>
+#include <starlet.h>
+#ifdef __DECC
+# pragma message disable DOLLARID
+#endif
+
+/* Use 32-bit pointers almost everywhere.  Define the type to which to
+ * cast a pointer passed to an external function.
+ */
+#if __INITIAL_POINTER_SIZE == 64
+# define PTR_T __void_ptr64
+# pragma pointer_size save
+# pragma pointer_size 32
+#else /* __INITIAL_POINTER_SIZE == 64 */
+# define PTR_T void *
+#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+static struct items_data_st
+	{
+	short length, code;	/* length is amount of bytes */
+	} items_data[] =
+		{ { 4, JPI$_BUFIO },
+		  { 4, JPI$_CPUTIM },
+		  { 4, JPI$_DIRIO },
+		  { 8, JPI$_LOGINTIM },
+		  { 4, JPI$_PAGEFLTS },
+		  { 4, JPI$_PID },
+		  { 4, JPI$_WSSIZE },
+		  { 0, 0 }
+		};
+		  
+int RAND_poll(void)
+	{
+	long pid, iosb[2];
+	int status = 0;
+	struct
+		{
+		short length, code;
+		long *buffer;
+		int *retlen;
+		} item[32], *pitem;
+	unsigned char data_buffer[256];
+	short total_length = 0;
+	struct items_data_st *pitems_data;
+
+	pitems_data = items_data;
+	pitem = item;
+
+	/* Setup */
+	while (pitems_data->length
+		&& (total_length + pitems_data->length <= 256))
+		{
+		pitem->length = pitems_data->length;
+		pitem->code = pitems_data->code;
+		pitem->buffer = (long *)&data_buffer[total_length];
+		pitem->retlen = 0;
+		total_length += pitems_data->length;
+		pitems_data++;
+		pitem++;
+		}
+	pitem->length = pitem->code = 0;
+
+	/*
+	 * Scan through all the processes in the system and add entropy with
+	 * results from the processes that were possible to look at.
+	 * However, view the information as only half trustable.
+	 */
+	pid = -1;			/* search context */
+	while ((status = sys$getjpiw(0, &pid,  0, item, iosb, 0, 0))
+		!= SS$_NOMOREPROC)
+		{
+		if (status == SS$_NORMAL)
+			{
+			RAND_add( (PTR_T)data_buffer, total_length,
+			 total_length/2);
+			}
+		}
+	sys$gettim(iosb);
+	RAND_add( (PTR_T)iosb, sizeof(iosb), sizeof(iosb)/2);
+	return 1;
+}
+
+#endif
diff --git a/openssl/crypto/rand/rand_win.c b/openssl/crypto/rand/rand_win.c
new file mode 100644
index 0000000..5d134e1
--- /dev/null
+++ b/openssl/crypto/rand/rand_win.c
@@ -0,0 +1,807 @@
+/* crypto/rand/rand_win.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#include "rand_lcl.h"
+
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
+#include <windows.h>
+#ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x0400
+#endif
+#include <wincrypt.h>
+#include <tlhelp32.h>
+
+/* Limit the time spent walking through the heap, processes, threads and modules to
+   a maximum of 1000 miliseconds each, unless CryptoGenRandom failed */
+#define MAXDELAY 1000
+
+/* Intel hardware RNG CSP -- available from
+ * http://developer.intel.com/design/security/rng/redist_license.htm
+ */
+#define PROV_INTEL_SEC 22
+#define INTEL_DEF_PROV L"Intel Hardware Cryptographic Service Provider"
+
+static void readtimer(void);
+static void readscreen(void);
+
+/* It appears like CURSORINFO, PCURSORINFO and LPCURSORINFO are only defined
+   when WINVER is 0x0500 and up, which currently only happens on Win2000.
+   Unfortunately, those are typedefs, so they're a little bit difficult to
+   detect properly.  On the other hand, the macro CURSOR_SHOWING is defined
+   within the same conditional, so it can be use to detect the absence of said
+   typedefs. */
+
+#ifndef CURSOR_SHOWING
+/*
+ * Information about the global cursor.
+ */
+typedef struct tagCURSORINFO
+{
+    DWORD   cbSize;
+    DWORD   flags;
+    HCURSOR hCursor;
+    POINT   ptScreenPos;
+} CURSORINFO, *PCURSORINFO, *LPCURSORINFO;
+
+#define CURSOR_SHOWING     0x00000001
+#endif /* CURSOR_SHOWING */
+
+#if !defined(OPENSSL_SYS_WINCE)
+typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTW)(HCRYPTPROV *, LPCWSTR, LPCWSTR,
+				    DWORD, DWORD);
+typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV, DWORD, BYTE *);
+typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV, DWORD);
+
+typedef HWND (WINAPI *GETFOREGROUNDWINDOW)(VOID);
+typedef BOOL (WINAPI *GETCURSORINFO)(PCURSORINFO);
+typedef DWORD (WINAPI *GETQUEUESTATUS)(UINT);
+
+typedef HANDLE (WINAPI *CREATETOOLHELP32SNAPSHOT)(DWORD, DWORD);
+typedef BOOL (WINAPI *CLOSETOOLHELP32SNAPSHOT)(HANDLE);
+typedef BOOL (WINAPI *HEAP32FIRST)(LPHEAPENTRY32, DWORD, size_t);
+typedef BOOL (WINAPI *HEAP32NEXT)(LPHEAPENTRY32);
+typedef BOOL (WINAPI *HEAP32LIST)(HANDLE, LPHEAPLIST32);
+typedef BOOL (WINAPI *PROCESS32)(HANDLE, LPPROCESSENTRY32);
+typedef BOOL (WINAPI *THREAD32)(HANDLE, LPTHREADENTRY32);
+typedef BOOL (WINAPI *MODULE32)(HANDLE, LPMODULEENTRY32);
+
+#include <lmcons.h>
+#include <lmstats.h>
+#if 1 /* The NET API is Unicode only.  It requires the use of the UNICODE
+       * macro.  When UNICODE is defined LPTSTR becomes LPWSTR.  LMSTR was
+       * was added to the Platform SDK to allow the NET API to be used in
+       * non-Unicode applications provided that Unicode strings were still
+       * used for input.  LMSTR is defined as LPWSTR.
+       */
+typedef NET_API_STATUS (NET_API_FUNCTION * NETSTATGET)
+        (LPWSTR, LPWSTR, DWORD, DWORD, LPBYTE*);
+typedef NET_API_STATUS (NET_API_FUNCTION * NETFREE)(LPBYTE);
+#endif /* 1 */
+#endif /* !OPENSSL_SYS_WINCE */
+
+int RAND_poll(void)
+{
+	MEMORYSTATUS m;
+	HCRYPTPROV hProvider = 0;
+	DWORD w;
+	int good = 0;
+
+	/* Determine the OS version we are on so we can turn off things 
+	 * that do not work properly.
+	 */
+        OSVERSIONINFO osverinfo ;
+        osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO) ;
+        GetVersionEx( &osverinfo ) ;
+
+#if defined(OPENSSL_SYS_WINCE)
+# if defined(_WIN32_WCE) && _WIN32_WCE>=300
+/* Even though MSDN says _WIN32_WCE>=210, it doesn't seem to be available
+ * in commonly available implementations prior 300... */
+	{
+	BYTE buf[64];
+	/* poll the CryptoAPI PRNG */
+	/* The CryptoAPI returns sizeof(buf) bytes of randomness */
+	if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL,
+				CRYPT_VERIFYCONTEXT))
+		{
+		if (CryptGenRandom(hProvider, sizeof(buf), buf))
+			RAND_add(buf, sizeof(buf), sizeof(buf));
+		CryptReleaseContext(hProvider, 0); 
+		}
+	}
+# endif
+#else	/* OPENSSL_SYS_WINCE */
+	/*
+	 * None of below libraries are present on Windows CE, which is
+	 * why we #ifndef the whole section. This also excuses us from
+	 * handling the GetProcAddress issue. The trouble is that in
+	 * real Win32 API GetProcAddress is available in ANSI flavor
+	 * only. In WinCE on the other hand GetProcAddress is a macro
+	 * most commonly defined as GetProcAddressW, which accepts
+	 * Unicode argument. If we were to call GetProcAddress under
+	 * WinCE, I'd recommend to either redefine GetProcAddress as
+	 * GetProcAddressA (there seem to be one in common CE spec) or
+	 * implement own shim routine, which would accept ANSI argument
+	 * and expand it to Unicode.
+	 */
+	{
+	/* load functions dynamically - not available on all systems */
+	HMODULE advapi = LoadLibrary(TEXT("ADVAPI32.DLL"));
+	HMODULE kernel = LoadLibrary(TEXT("KERNEL32.DLL"));
+	HMODULE user = NULL;
+	HMODULE netapi = LoadLibrary(TEXT("NETAPI32.DLL"));
+	CRYPTACQUIRECONTEXTW acquire = NULL;
+	CRYPTGENRANDOM gen = NULL;
+	CRYPTRELEASECONTEXT release = NULL;
+	NETSTATGET netstatget = NULL;
+	NETFREE netfree = NULL;
+	BYTE buf[64];
+
+	if (netapi)
+		{
+		netstatget = (NETSTATGET) GetProcAddress(netapi,"NetStatisticsGet");
+		netfree = (NETFREE) GetProcAddress(netapi,"NetApiBufferFree");
+		}
+
+	if (netstatget && netfree)
+		{
+		LPBYTE outbuf;
+		/* NetStatisticsGet() is a Unicode only function
+ 		 * STAT_WORKSTATION_0 contains 45 fields and STAT_SERVER_0
+		 * contains 17 fields.  We treat each field as a source of
+		 * one byte of entropy.
+                 */
+
+		if (netstatget(NULL, L"LanmanWorkstation", 0, 0, &outbuf) == 0)
+			{
+			RAND_add(outbuf, sizeof(STAT_WORKSTATION_0), 45);
+			netfree(outbuf);
+			}
+		if (netstatget(NULL, L"LanmanServer", 0, 0, &outbuf) == 0)
+			{
+			RAND_add(outbuf, sizeof(STAT_SERVER_0), 17);
+			netfree(outbuf);
+			}
+		}
+
+	if (netapi)
+		FreeLibrary(netapi);
+
+        /* It appears like this can cause an exception deep within ADVAPI32.DLL
+         * at random times on Windows 2000.  Reported by Jeffrey Altman.  
+         * Only use it on NT.
+	 */
+	/* Wolfgang Marczy <WMarczy@topcall.co.at> reports that
+	 * the RegQueryValueEx call below can hang on NT4.0 (SP6).
+	 * So we don't use this at all for now. */
+#if 0
+        if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
+		osverinfo.dwMajorVersion < 5)
+		{
+		/* Read Performance Statistics from NT/2000 registry
+		 * The size of the performance data can vary from call
+		 * to call so we must guess the size of the buffer to use
+		 * and increase its size if we get an ERROR_MORE_DATA
+		 * return instead of ERROR_SUCCESS.
+		 */
+		LONG   rc=ERROR_MORE_DATA;
+		char * buf=NULL;
+		DWORD bufsz=0;
+		DWORD length;
+
+		while (rc == ERROR_MORE_DATA)
+			{
+			buf = realloc(buf,bufsz+8192);
+			if (!buf)
+				break;
+			bufsz += 8192;
+
+			length = bufsz;
+			rc = RegQueryValueEx(HKEY_PERFORMANCE_DATA, TEXT("Global"),
+				NULL, NULL, buf, &length);
+			}
+		if (rc == ERROR_SUCCESS)
+			{
+                        /* For entropy count assume only least significant
+			 * byte of each DWORD is random.
+			 */
+			RAND_add(&length, sizeof(length), 0);
+			RAND_add(buf, length, length / 4.0);
+
+			/* Close the Registry Key to allow Windows to cleanup/close
+			 * the open handle
+			 * Note: The 'HKEY_PERFORMANCE_DATA' key is implicitly opened
+			 *       when the RegQueryValueEx above is done.  However, if
+			 *       it is not explicitly closed, it can cause disk
+			 *       partition manipulation problems.
+			 */
+			RegCloseKey(HKEY_PERFORMANCE_DATA);
+			}
+		if (buf)
+			free(buf);
+		}
+#endif
+
+	if (advapi)
+		{
+		/*
+		 * If it's available, then it's available in both ANSI
+		 * and UNICODE flavors even in Win9x, documentation says.
+		 * We favor Unicode...
+		 */
+		acquire = (CRYPTACQUIRECONTEXTW) GetProcAddress(advapi,
+			"CryptAcquireContextW");
+		gen = (CRYPTGENRANDOM) GetProcAddress(advapi,
+			"CryptGenRandom");
+		release = (CRYPTRELEASECONTEXT) GetProcAddress(advapi,
+			"CryptReleaseContext");
+		}
+
+	if (acquire && gen && release)
+		{
+		/* poll the CryptoAPI PRNG */
+                /* The CryptoAPI returns sizeof(buf) bytes of randomness */
+		if (acquire(&hProvider, NULL, NULL, PROV_RSA_FULL,
+			CRYPT_VERIFYCONTEXT))
+			{
+			if (gen(hProvider, sizeof(buf), buf) != 0)
+				{
+				RAND_add(buf, sizeof(buf), 0);
+				good = 1;
+#if 0
+				printf("randomness from PROV_RSA_FULL\n");
+#endif
+				}
+			release(hProvider, 0); 
+			}
+		
+		/* poll the Pentium PRG with CryptoAPI */
+		if (acquire(&hProvider, 0, INTEL_DEF_PROV, PROV_INTEL_SEC, 0))
+			{
+			if (gen(hProvider, sizeof(buf), buf) != 0)
+				{
+				RAND_add(buf, sizeof(buf), sizeof(buf));
+				good = 1;
+#if 0
+				printf("randomness from PROV_INTEL_SEC\n");
+#endif
+				}
+			release(hProvider, 0);
+			}
+		}
+
+        if (advapi)
+		FreeLibrary(advapi);
+
+	if ((osverinfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
+	     !OPENSSL_isservice()) &&
+	    (user = LoadLibrary(TEXT("USER32.DLL"))))
+		{
+		GETCURSORINFO cursor;
+		GETFOREGROUNDWINDOW win;
+		GETQUEUESTATUS queue;
+
+		win = (GETFOREGROUNDWINDOW) GetProcAddress(user, "GetForegroundWindow");
+		cursor = (GETCURSORINFO) GetProcAddress(user, "GetCursorInfo");
+		queue = (GETQUEUESTATUS) GetProcAddress(user, "GetQueueStatus");
+
+		if (win)
+			{
+			/* window handle */
+			HWND h = win();
+			RAND_add(&h, sizeof(h), 0);
+			}
+		if (cursor)
+			{
+			/* unfortunately, its not safe to call GetCursorInfo()
+			 * on NT4 even though it exists in SP3 (or SP6) and
+			 * higher.
+			 */
+			if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
+				osverinfo.dwMajorVersion < 5)
+				cursor = 0;
+			}
+		if (cursor)
+			{
+			/* cursor position */
+                        /* assume 2 bytes of entropy */
+			CURSORINFO ci;
+			ci.cbSize = sizeof(CURSORINFO);
+			if (cursor(&ci))
+				RAND_add(&ci, ci.cbSize, 2);
+			}
+
+		if (queue)
+			{
+			/* message queue status */
+                        /* assume 1 byte of entropy */
+			w = queue(QS_ALLEVENTS);
+			RAND_add(&w, sizeof(w), 1);
+			}
+
+		FreeLibrary(user);
+		}
+
+	/* Toolhelp32 snapshot: enumerate processes, threads, modules and heap
+	 * http://msdn.microsoft.com/library/psdk/winbase/toolhelp_5pfd.htm
+	 * (Win 9x and 2000 only, not available on NT)
+	 *
+	 * This seeding method was proposed in Peter Gutmann, Software
+	 * Generation of Practically Strong Random Numbers,
+	 * http://www.usenix.org/publications/library/proceedings/sec98/gutmann.html
+	 * revised version at http://www.cryptoengines.com/~peter/06_random.pdf
+	 * (The assignment of entropy estimates below is arbitrary, but based
+	 * on Peter's analysis the full poll appears to be safe. Additional
+	 * interactive seeding is encouraged.)
+	 */
+
+	if (kernel)
+		{
+		CREATETOOLHELP32SNAPSHOT snap;
+		CLOSETOOLHELP32SNAPSHOT close_snap;
+		HANDLE handle;
+
+		HEAP32FIRST heap_first;
+		HEAP32NEXT heap_next;
+		HEAP32LIST heaplist_first, heaplist_next;
+		PROCESS32 process_first, process_next;
+		THREAD32 thread_first, thread_next;
+		MODULE32 module_first, module_next;
+
+		HEAPLIST32 hlist;
+		HEAPENTRY32 hentry;
+		PROCESSENTRY32 p;
+		THREADENTRY32 t;
+		MODULEENTRY32 m;
+		DWORD starttime = 0;
+
+		snap = (CREATETOOLHELP32SNAPSHOT)
+			GetProcAddress(kernel, "CreateToolhelp32Snapshot");
+		close_snap = (CLOSETOOLHELP32SNAPSHOT)
+			GetProcAddress(kernel, "CloseToolhelp32Snapshot");
+		heap_first = (HEAP32FIRST) GetProcAddress(kernel, "Heap32First");
+		heap_next = (HEAP32NEXT) GetProcAddress(kernel, "Heap32Next");
+		heaplist_first = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListFirst");
+		heaplist_next = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListNext");
+		process_first = (PROCESS32) GetProcAddress(kernel, "Process32First");
+		process_next = (PROCESS32) GetProcAddress(kernel, "Process32Next");
+		thread_first = (THREAD32) GetProcAddress(kernel, "Thread32First");
+		thread_next = (THREAD32) GetProcAddress(kernel, "Thread32Next");
+		module_first = (MODULE32) GetProcAddress(kernel, "Module32First");
+		module_next = (MODULE32) GetProcAddress(kernel, "Module32Next");
+
+		if (snap && heap_first && heap_next && heaplist_first &&
+			heaplist_next && process_first && process_next &&
+			thread_first && thread_next && module_first &&
+			module_next && (handle = snap(TH32CS_SNAPALL,0))
+			!= INVALID_HANDLE_VALUE)
+			{
+			/* heap list and heap walking */
+                        /* HEAPLIST32 contains 3 fields that will change with
+                         * each entry.  Consider each field a source of 1 byte
+                         * of entropy.
+                         * HEAPENTRY32 contains 5 fields that will change with 
+                         * each entry.  Consider each field a source of 1 byte
+                         * of entropy.
+                         */
+			ZeroMemory(&hlist, sizeof(HEAPLIST32));
+			hlist.dwSize = sizeof(HEAPLIST32);		
+			if (good) starttime = GetTickCount();
+#ifdef _MSC_VER
+			if (heaplist_first(handle, &hlist))
+				{
+				/*
+				   following discussion on dev ML, exception on WinCE (or other Win
+				   platform) is theoretically of unknown origin; prevent infinite
+				   loop here when this theoretical case occurs; otherwise cope with
+				   the expected (MSDN documented) exception-throwing behaviour of
+				   Heap32Next() on WinCE.
+
+				   based on patch in original message by Tanguy Fautré (2009/03/02)
+			           Subject: RAND_poll() and CreateToolhelp32Snapshot() stability
+			     */
+				int ex_cnt_limit = 42; 
+				do
+					{
+					RAND_add(&hlist, hlist.dwSize, 3);
+					__try
+						{
+						ZeroMemory(&hentry, sizeof(HEAPENTRY32));
+					hentry.dwSize = sizeof(HEAPENTRY32);
+					if (heap_first(&hentry,
+						hlist.th32ProcessID,
+						hlist.th32HeapID))
+						{
+						int entrycnt = 80;
+						do
+							RAND_add(&hentry,
+								hentry.dwSize, 5);
+						while (heap_next(&hentry)
+						&& (!good || (GetTickCount()-starttime)<MAXDELAY)
+							&& --entrycnt > 0);
+						}
+						}
+					__except (EXCEPTION_EXECUTE_HANDLER)
+						{
+							/* ignore access violations when walking the heap list */
+							ex_cnt_limit--;
+						}
+					} while (heaplist_next(handle, &hlist) 
+						&& (!good || (GetTickCount()-starttime)<MAXDELAY)
+						&& ex_cnt_limit > 0);
+				}
+
+#else
+			if (heaplist_first(handle, &hlist))
+				{
+				do
+					{
+					RAND_add(&hlist, hlist.dwSize, 3);
+					hentry.dwSize = sizeof(HEAPENTRY32);
+					if (heap_first(&hentry,
+						hlist.th32ProcessID,
+						hlist.th32HeapID))
+						{
+						int entrycnt = 80;
+						do
+							RAND_add(&hentry,
+								hentry.dwSize, 5);
+						while (heap_next(&hentry)
+							&& --entrycnt > 0);
+						}
+					} while (heaplist_next(handle, &hlist) 
+						&& (!good || (GetTickCount()-starttime)<MAXDELAY));
+				}
+#endif
+
+			/* process walking */
+                        /* PROCESSENTRY32 contains 9 fields that will change
+                         * with each entry.  Consider each field a source of
+                         * 1 byte of entropy.
+                         */
+			p.dwSize = sizeof(PROCESSENTRY32);
+		
+			if (good) starttime = GetTickCount();
+			if (process_first(handle, &p))
+				do
+					RAND_add(&p, p.dwSize, 9);
+				while (process_next(handle, &p) && (!good || (GetTickCount()-starttime)<MAXDELAY));
+
+			/* thread walking */
+                        /* THREADENTRY32 contains 6 fields that will change
+                         * with each entry.  Consider each field a source of
+                         * 1 byte of entropy.
+                         */
+			t.dwSize = sizeof(THREADENTRY32);
+			if (good) starttime = GetTickCount();
+			if (thread_first(handle, &t))
+				do
+					RAND_add(&t, t.dwSize, 6);
+				while (thread_next(handle, &t) && (!good || (GetTickCount()-starttime)<MAXDELAY));
+
+			/* module walking */
+                        /* MODULEENTRY32 contains 9 fields that will change
+                         * with each entry.  Consider each field a source of
+                         * 1 byte of entropy.
+                         */
+			m.dwSize = sizeof(MODULEENTRY32);
+			if (good) starttime = GetTickCount();
+			if (module_first(handle, &m))
+				do
+					RAND_add(&m, m.dwSize, 9);
+				while (module_next(handle, &m)
+					       	&& (!good || (GetTickCount()-starttime)<MAXDELAY));
+			if (close_snap)
+				close_snap(handle);
+			else
+				CloseHandle(handle);
+
+			}
+
+		FreeLibrary(kernel);
+		}
+	}
+#endif /* !OPENSSL_SYS_WINCE */
+
+	/* timer data */
+	readtimer();
+	
+	/* memory usage statistics */
+	GlobalMemoryStatus(&m);
+	RAND_add(&m, sizeof(m), 1);
+
+	/* process ID */
+	w = GetCurrentProcessId();
+	RAND_add(&w, sizeof(w), 1);
+
+#if 0
+	printf("Exiting RAND_poll\n");
+#endif
+
+	return(1);
+}
+
+int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam)
+        {
+        double add_entropy=0;
+
+        switch (iMsg)
+                {
+        case WM_KEYDOWN:
+                        {
+                        static WPARAM key;
+                        if (key != wParam)
+                                add_entropy = 0.05;
+                        key = wParam;
+                        }
+                        break;
+	case WM_MOUSEMOVE:
+                        {
+                        static int lastx,lasty,lastdx,lastdy;
+                        int x,y,dx,dy;
+
+                        x=LOWORD(lParam);
+                        y=HIWORD(lParam);
+                        dx=lastx-x;
+                        dy=lasty-y;
+                        if (dx != 0 && dy != 0 && dx-lastdx != 0 && dy-lastdy != 0)
+                                add_entropy=.2;
+                        lastx=x, lasty=y;
+                        lastdx=dx, lastdy=dy;
+                        }
+		break;
+		}
+
+	readtimer();
+        RAND_add(&iMsg, sizeof(iMsg), add_entropy);
+	RAND_add(&wParam, sizeof(wParam), 0);
+	RAND_add(&lParam, sizeof(lParam), 0);
+ 
+	return (RAND_status());
+	}
+
+
+void RAND_screen(void) /* function available for backward compatibility */
+{
+	RAND_poll();
+	readscreen();
+}
+
+
+/* feed timing information to the PRNG */
+static void readtimer(void)
+{
+	DWORD w;
+	LARGE_INTEGER l;
+	static int have_perfc = 1;
+#if defined(_MSC_VER) && defined(_M_X86)
+	static int have_tsc = 1;
+	DWORD cyclecount;
+
+	if (have_tsc) {
+	  __try {
+	    __asm {
+	      _emit 0x0f
+	      _emit 0x31
+	      mov cyclecount, eax
+	      }
+	    RAND_add(&cyclecount, sizeof(cyclecount), 1);
+	  } __except(EXCEPTION_EXECUTE_HANDLER) {
+	    have_tsc = 0;
+	  }
+	}
+#else
+# define have_tsc 0
+#endif
+
+	if (have_perfc) {
+	  if (QueryPerformanceCounter(&l) == 0)
+	    have_perfc = 0;
+	  else
+	    RAND_add(&l, sizeof(l), 0);
+	}
+
+	if (!have_tsc && !have_perfc) {
+	  w = GetTickCount();
+	  RAND_add(&w, sizeof(w), 0);
+	}
+}
+
+/* feed screen contents to PRNG */
+/*****************************************************************************
+ *
+ * Created 960901 by Gertjan van Oosten, gertjan@West.NL, West Consulting B.V.
+ *
+ * Code adapted from
+ * <URL:http://support.microsoft.com/default.aspx?scid=kb;[LN];97193>;
+ * the original copyright message is:
+ *
+ *   (C) Copyright Microsoft Corp. 1993.  All rights reserved.
+ *
+ *   You have a royalty-free right to use, modify, reproduce and
+ *   distribute the Sample Files (and/or any modified version) in
+ *   any way you find useful, provided that you agree that
+ *   Microsoft has no warranty obligations or liability for any
+ *   Sample Application Files which are modified.
+ */
+
+static void readscreen(void)
+{
+#if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN)
+  HDC		hScrDC;		/* screen DC */
+  HDC		hMemDC;		/* memory DC */
+  HBITMAP	hBitmap;	/* handle for our bitmap */
+  HBITMAP	hOldBitmap;	/* handle for previous bitmap */
+  BITMAP	bm;		/* bitmap properties */
+  unsigned int	size;		/* size of bitmap */
+  char		*bmbits;	/* contents of bitmap */
+  int		w;		/* screen width */
+  int		h;		/* screen height */
+  int		y;		/* y-coordinate of screen lines to grab */
+  int		n = 16;		/* number of screen lines to grab at a time */
+
+  if (GetVersion() < 0x80000000 && OPENSSL_isservice()>0)
+    return;
+
+  /* Create a screen DC and a memory DC compatible to screen DC */
+  hScrDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
+  hMemDC = CreateCompatibleDC(hScrDC);
+
+  /* Get screen resolution */
+  w = GetDeviceCaps(hScrDC, HORZRES);
+  h = GetDeviceCaps(hScrDC, VERTRES);
+
+  /* Create a bitmap compatible with the screen DC */
+  hBitmap = CreateCompatibleBitmap(hScrDC, w, n);
+
+  /* Select new bitmap into memory DC */
+  hOldBitmap = SelectObject(hMemDC, hBitmap);
+
+  /* Get bitmap properties */
+  GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
+  size = (unsigned int)bm.bmWidthBytes * bm.bmHeight * bm.bmPlanes;
+
+  bmbits = OPENSSL_malloc(size);
+  if (bmbits) {
+    /* Now go through the whole screen, repeatedly grabbing n lines */
+    for (y = 0; y < h-n; y += n)
+    	{
+	unsigned char md[MD_DIGEST_LENGTH];
+
+	/* Bitblt screen DC to memory DC */
+	BitBlt(hMemDC, 0, 0, w, n, hScrDC, 0, y, SRCCOPY);
+
+	/* Copy bitmap bits from memory DC to bmbits */
+	GetBitmapBits(hBitmap, size, bmbits);
+
+	/* Get the hash of the bitmap */
+	MD(bmbits,size,md);
+
+	/* Seed the random generator with the hash value */
+	RAND_add(md, MD_DIGEST_LENGTH, 0);
+	}
+
+    OPENSSL_free(bmbits);
+  }
+
+  /* Select old bitmap back into memory DC */
+  hBitmap = SelectObject(hMemDC, hOldBitmap);
+
+  /* Clean up */
+  DeleteObject(hBitmap);
+  DeleteDC(hMemDC);
+  DeleteDC(hScrDC);
+#endif /* !OPENSSL_SYS_WINCE */
+}
+
+#endif
diff --git a/openssl/crypto/rand/randfile.c b/openssl/crypto/rand/randfile.c
new file mode 100644
index 0000000..bc7d9c5
--- /dev/null
+++ b/openssl/crypto/rand/randfile.c
@@ -0,0 +1,326 @@
+/* crypto/rand/randfile.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* We need to define this to get macros like S_IFBLK and S_IFCHR */
+#define _XOPEN_SOURCE 500
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "e_os.h"
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+#include <openssl/buffer.h>
+
+#ifdef OPENSSL_SYS_VMS
+#include <unixio.h>
+#endif
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifndef OPENSSL_NO_POSIX_IO
+# include <sys/stat.h>
+#endif
+
+#ifdef _WIN32
+#define stat	_stat
+#define chmod	_chmod
+#define open	_open
+#define fdopen	_fdopen
+#endif
+
+#undef BUFSIZE
+#define BUFSIZE	1024
+#define RAND_DATA 1024
+
+#ifdef OPENSSL_SYS_VMS
+/* This declaration is a nasty hack to get around vms' extension to fopen
+ * for passing in sharing options being disabled by our /STANDARD=ANSI89 */
+static FILE *(*const vms_fopen)(const char *, const char *, ...) =
+    (FILE *(*)(const char *, const char *, ...))fopen;
+#define VMS_OPEN_ATTRS "shr=get,put,upd,del","ctx=bin,stm","rfm=stm","rat=none","mrs=0"
+#endif
+
+/* #define RFILE ".rnd" - defined in ../../e_os.h */
+
+/* Note that these functions are intended for seed files only.
+ * Entropy devices and EGD sockets are handled in rand_unix.c */
+
+int RAND_load_file(const char *file, long bytes)
+	{
+	/* If bytes >= 0, read up to 'bytes' bytes.
+	 * if bytes == -1, read complete file. */
+
+	MS_STATIC unsigned char buf[BUFSIZE];
+#ifndef OPENSSL_NO_POSIX_IO
+	struct stat sb;
+#endif
+	int i,ret=0,n;
+	FILE *in;
+
+	if (file == NULL) return(0);
+
+#ifndef OPENSSL_NO_POSIX_IO
+#ifdef PURIFY
+	/* struct stat can have padding and unused fields that may not be
+	 * initialized in the call to stat(). We need to clear the entire
+	 * structure before calling RAND_add() to avoid complaints from
+	 * applications such as Valgrind.
+	 */
+	memset(&sb, 0, sizeof(sb));
+#endif
+	if (stat(file,&sb) < 0) return(0);
+	RAND_add(&sb,sizeof(sb),0.0);
+#endif
+	if (bytes == 0) return(ret);
+
+#ifdef OPENSSL_SYS_VMS
+	in=vms_fopen(file,"rb",VMS_OPEN_ATTRS);
+#else
+	in=fopen(file,"rb");
+#endif
+	if (in == NULL) goto err;
+#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPNESSL_NO_POSIX_IO)
+	if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
+	  /* this file is a device. we don't want read an infinite number
+	   * of bytes from a random device, nor do we want to use buffered
+	   * I/O because we will waste system entropy. 
+	   */
+	  bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */
+#ifndef OPENSSL_NO_SETVBUF_IONBF
+	  setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */
+#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
+	}
+#endif
+	for (;;)
+		{
+		if (bytes > 0)
+			n = (bytes < BUFSIZE)?(int)bytes:BUFSIZE;
+		else
+			n = BUFSIZE;
+		i=fread(buf,1,n,in);
+		if (i <= 0) break;
+#ifdef PURIFY
+		RAND_add(buf,i,(double)i);
+#else
+		/* even if n != i, use the full array */
+		RAND_add(buf,n,(double)i);
+#endif
+		ret+=i;
+		if (bytes > 0)
+			{
+			bytes-=n;
+			if (bytes <= 0) break;
+			}
+		}
+	fclose(in);
+	OPENSSL_cleanse(buf,BUFSIZE);
+err:
+	return(ret);
+	}
+
+int RAND_write_file(const char *file)
+	{
+	unsigned char buf[BUFSIZE];
+	int i,ret=0,rand_err=0;
+	FILE *out = NULL;
+	int n;
+#ifndef OPENSSL_NO_POSIX_IO
+	struct stat sb;
+	
+	i=stat(file,&sb);
+	if (i != -1) { 
+#if defined(S_ISBLK) && defined(S_ISCHR)
+	  if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
+	    /* this file is a device. we don't write back to it. 
+	     * we "succeed" on the assumption this is some sort 
+	     * of random device. Otherwise attempting to write to 
+	     * and chmod the device causes problems.
+	     */
+	    return(1); 
+	  }
+#endif
+	}
+#endif
+
+#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && !defined(OPENSSL_SYS_VMS)
+	{
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+	/* chmod(..., 0600) is too late to protect the file,
+	 * permissions should be restrictive from the start */
+	int fd = open(file, O_WRONLY|O_CREAT|O_BINARY, 0600);
+	if (fd != -1)
+		out = fdopen(fd, "wb");
+	}
+#endif
+
+#ifdef OPENSSL_SYS_VMS
+	/* VMS NOTE: Prior versions of this routine created a _new_
+	 * version of the rand file for each call into this routine, then
+	 * deleted all existing versions named ;-1, and finally renamed
+	 * the current version as ';1'. Under concurrent usage, this
+	 * resulted in an RMS race condition in rename() which could
+	 * orphan files (see vms message help for RMS$_REENT). With the
+	 * fopen() calls below, openssl/VMS now shares the top-level
+	 * version of the rand file. Note that there may still be
+	 * conditions where the top-level rand file is locked. If so, this
+	 * code will then create a new version of the rand file. Without
+	 * the delete and rename code, this can result in ascending file
+	 * versions that stop at version 32767, and this routine will then
+	 * return an error. The remedy for this is to recode the calling
+	 * application to avoid concurrent use of the rand file, or
+	 * synchronize usage at the application level. Also consider
+	 * whether or not you NEED a persistent rand file in a concurrent
+	 * use situation. 
+	 */
+
+	out = vms_fopen(file,"rb+",VMS_OPEN_ATTRS);
+	if (out == NULL)
+		out = vms_fopen(file,"wb",VMS_OPEN_ATTRS);
+#else
+	if (out == NULL)
+		out = fopen(file,"wb");
+#endif
+	if (out == NULL) goto err;
+
+#ifndef NO_CHMOD
+	chmod(file,0600);
+#endif
+	n=RAND_DATA;
+	for (;;)
+		{
+		i=(n > BUFSIZE)?BUFSIZE:n;
+		n-=BUFSIZE;
+		if (RAND_bytes(buf,i) <= 0)
+			rand_err=1;
+		i=fwrite(buf,1,i,out);
+		if (i <= 0)
+			{
+			ret=0;
+			break;
+			}
+		ret+=i;
+		if (n <= 0) break;
+                }
+
+	fclose(out);
+	OPENSSL_cleanse(buf,BUFSIZE);
+err:
+	return (rand_err ? -1 : ret);
+	}
+
+const char *RAND_file_name(char *buf, size_t size)
+	{
+	char *s=NULL;
+#ifdef __OpenBSD__
+	struct stat sb;
+#endif
+
+	if (OPENSSL_issetugid() == 0)
+		s=getenv("RANDFILE");
+	if (s != NULL && *s && strlen(s) + 1 < size)
+		{
+		if (BUF_strlcpy(buf,s,size) >= size)
+			return NULL;
+		}
+	else
+		{
+		if (OPENSSL_issetugid() == 0)
+			s=getenv("HOME");
+#ifdef DEFAULT_HOME
+		if (s == NULL)
+			{
+			s = DEFAULT_HOME;
+			}
+#endif
+		if (s && *s && strlen(s)+strlen(RFILE)+2 < size)
+			{
+			BUF_strlcpy(buf,s,size);
+#ifndef OPENSSL_SYS_VMS
+			BUF_strlcat(buf,"/",size);
+#endif
+			BUF_strlcat(buf,RFILE,size);
+			}
+		else
+		  	buf[0] = '\0'; /* no file name */
+		}
+
+#ifdef __OpenBSD__
+	/* given that all random loads just fail if the file can't be 
+	 * seen on a stat, we stat the file we're returning, if it
+	 * fails, use /dev/arandom instead. this allows the user to 
+	 * use their own source for good random data, but defaults
+	 * to something hopefully decent if that isn't available. 
+	 */
+
+	if (!buf[0])
+		if (BUF_strlcpy(buf,"/dev/arandom",size) >= size) {
+			return(NULL);
+		}	
+	if (stat(buf,&sb) == -1)
+		if (BUF_strlcpy(buf,"/dev/arandom",size) >= size) {
+			return(NULL);
+		}	
+
+#endif
+	return(buf);
+	}
diff --git a/openssl/crypto/rand/randtest.c b/openssl/crypto/rand/randtest.c
new file mode 100644
index 0000000..9e92a70
--- /dev/null
+++ b/openssl/crypto/rand/randtest.c
@@ -0,0 +1,219 @@
+/* crypto/rand/randtest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/rand.h>
+
+#include "../e_os.h"
+
+/* some FIPS 140-1 random number test */
+/* some simple tests */
+
+int main(int argc,char **argv)
+	{
+	unsigned char buf[2500];
+	int i,j,k,s,sign,nsign,err=0;
+	unsigned long n1;
+	unsigned long n2[16];
+	unsigned long runs[2][34];
+	/*double d; */
+	long d;
+
+	i = RAND_pseudo_bytes(buf,2500);
+	if (i < 0)
+		{
+		printf ("init failed, the rand method is not properly installed\n");
+		err++;
+		goto err;
+		}
+
+	n1=0;
+	for (i=0; i<16; i++) n2[i]=0;
+	for (i=0; i<34; i++) runs[0][i]=runs[1][i]=0;
+
+	/* test 1 and 2 */
+	sign=0;
+	nsign=0;
+	for (i=0; i<2500; i++)
+		{
+		j=buf[i];
+
+		n2[j&0x0f]++;
+		n2[(j>>4)&0x0f]++;
+
+		for (k=0; k<8; k++)
+			{
+			s=(j&0x01);
+			if (s == sign)
+				nsign++;
+			else
+				{
+				if (nsign > 34) nsign=34;
+				if (nsign != 0)
+					{
+					runs[sign][nsign-1]++;
+					if (nsign > 6)
+						runs[sign][5]++;
+					}
+				sign=s;
+				nsign=1;
+				}
+
+			if (s) n1++;
+			j>>=1;
+			}
+		}
+		if (nsign > 34) nsign=34;
+		if (nsign != 0) runs[sign][nsign-1]++;
+
+	/* test 1 */
+	if (!((9654 < n1) && (n1 < 10346)))
+		{
+		printf("test 1 failed, X=%lu\n",n1);
+		err++;
+		}
+	printf("test 1 done\n");
+
+	/* test 2 */
+#ifdef undef
+	d=0;
+	for (i=0; i<16; i++)
+		d+=n2[i]*n2[i];
+	d=d*16.0/5000.0-5000.0;
+	if (!((1.03 < d) && (d < 57.4)))
+		{
+		printf("test 2 failed, X=%.2f\n",d);
+		err++;
+		}
+#endif
+	d=0;
+	for (i=0; i<16; i++)
+		d+=n2[i]*n2[i];
+	d=(d*8)/25-500000;
+	if (!((103 < d) && (d < 5740)))
+		{
+		printf("test 2 failed, X=%ld.%02ld\n",d/100L,d%100L);
+		err++;
+		}
+	printf("test 2 done\n");
+
+	/* test 3 */
+	for (i=0; i<2; i++)
+		{
+		if (!((2267 < runs[i][0]) && (runs[i][0] < 2733)))
+			{
+			printf("test 3 failed, bit=%d run=%d num=%lu\n",
+				i,1,runs[i][0]);
+			err++;
+			}
+		if (!((1079 < runs[i][1]) && (runs[i][1] < 1421)))
+			{
+			printf("test 3 failed, bit=%d run=%d num=%lu\n",
+				i,2,runs[i][1]);
+			err++;
+			}
+		if (!(( 502 < runs[i][2]) && (runs[i][2] <  748)))
+			{
+			printf("test 3 failed, bit=%d run=%d num=%lu\n",
+				i,3,runs[i][2]);
+			err++;
+			}
+		if (!(( 223 < runs[i][3]) && (runs[i][3] <  402)))
+			{
+			printf("test 3 failed, bit=%d run=%d num=%lu\n",
+				i,4,runs[i][3]);
+			err++;
+			}
+		if (!((  90 < runs[i][4]) && (runs[i][4] <  223)))
+			{
+			printf("test 3 failed, bit=%d run=%d num=%lu\n",
+				i,5,runs[i][4]);
+			err++;
+			}
+		if (!((  90 < runs[i][5]) && (runs[i][5] <  223)))
+			{
+			printf("test 3 failed, bit=%d run=%d num=%lu\n",
+				i,6,runs[i][5]);
+			err++;
+			}
+		}
+	printf("test 3 done\n");
+	
+	/* test 4 */
+	if (runs[0][33] != 0)
+		{
+		printf("test 4 failed, bit=%d run=%d num=%lu\n",
+			0,34,runs[0][33]);
+		err++;
+		}
+	if (runs[1][33] != 0)
+		{
+		printf("test 4 failed, bit=%d run=%d num=%lu\n",
+			1,34,runs[1][33]);
+		err++;
+		}
+	printf("test 4 done\n");
+ err:
+	err=((err)?1:0);
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
+	EXIT(err);
+	return(err);
+	}
diff --git a/openssl/crypto/rc2/Makefile b/openssl/crypto/rc2/Makefile
new file mode 100644
index 0000000..73eac34
--- /dev/null
+++ b/openssl/crypto/rc2/Makefile
@@ -0,0 +1,86 @@
+#
+# OpenSSL/crypto/rc2/Makefile
+#
+
+DIR=	rc2
+TOP=	../..
+CC=	cc
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=rc2test.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=rc2_ecb.c rc2_skey.c rc2_cbc.c rc2cfb64.c rc2ofb64.c
+LIBOBJ=rc2_ecb.o rc2_skey.o rc2_cbc.o rc2cfb64.o rc2ofb64.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= rc2.h
+HEADER=	rc2_locl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+rc2_cbc.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc2.h
+rc2_cbc.o: rc2_cbc.c rc2_locl.h
+rc2_ecb.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+rc2_ecb.o: ../../include/openssl/rc2.h rc2_ecb.c rc2_locl.h
+rc2_skey.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc2.h
+rc2_skey.o: rc2_locl.h rc2_skey.c
+rc2cfb64.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc2.h
+rc2cfb64.o: rc2_locl.h rc2cfb64.c
+rc2ofb64.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc2.h
+rc2ofb64.o: rc2_locl.h rc2ofb64.c
diff --git a/openssl/crypto/rc2/rc2.h b/openssl/crypto/rc2/rc2.h
new file mode 100644
index 0000000..34c8362
--- /dev/null
+++ b/openssl/crypto/rc2/rc2.h
@@ -0,0 +1,101 @@
+/* crypto/rc2/rc2.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RC2_H
+#define HEADER_RC2_H
+
+#include <openssl/opensslconf.h> /* OPENSSL_NO_RC2, RC2_INT */
+#ifdef OPENSSL_NO_RC2
+#error RC2 is disabled.
+#endif
+
+#define RC2_ENCRYPT	1
+#define RC2_DECRYPT	0
+
+#define RC2_BLOCK	8
+#define RC2_KEY_LENGTH	16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct rc2_key_st
+	{
+	RC2_INT data[64];
+	} RC2_KEY;
+
+ 
+void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits);
+void RC2_ecb_encrypt(const unsigned char *in,unsigned char *out,RC2_KEY *key,
+		     int enc);
+void RC2_encrypt(unsigned long *data,RC2_KEY *key);
+void RC2_decrypt(unsigned long *data,RC2_KEY *key);
+void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+	RC2_KEY *ks, unsigned char *iv, int enc);
+void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+		       long length, RC2_KEY *schedule, unsigned char *ivec,
+		       int *num, int enc);
+void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+		       long length, RC2_KEY *schedule, unsigned char *ivec,
+		       int *num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/rc2/rc2_cbc.c b/openssl/crypto/rc2/rc2_cbc.c
new file mode 100644
index 0000000..74f48d3
--- /dev/null
+++ b/openssl/crypto/rc2/rc2_cbc.c
@@ -0,0 +1,226 @@
+/* crypto/rc2/rc2_cbc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc2.h>
+#include "rc2_locl.h"
+
+void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+	     RC2_KEY *ks, unsigned char *iv, int encrypt)
+	{
+	register unsigned long tin0,tin1;
+	register unsigned long tout0,tout1,xor0,xor1;
+	register long l=length;
+	unsigned long tin[2];
+
+	if (encrypt)
+		{
+		c2l(iv,tout0);
+		c2l(iv,tout1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0);
+			c2l(in,tin1);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			RC2_encrypt(tin,ks);
+			tout0=tin[0]; l2c(tout0,out);
+			tout1=tin[1]; l2c(tout1,out);
+			}
+		if (l != -8)
+			{
+			c2ln(in,tin0,tin1,l+8);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			RC2_encrypt(tin,ks);
+			tout0=tin[0]; l2c(tout0,out);
+			tout1=tin[1]; l2c(tout1,out);
+			}
+		l2c(tout0,iv);
+		l2c(tout1,iv);
+		}
+	else
+		{
+		c2l(iv,xor0);
+		c2l(iv,xor1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0); tin[0]=tin0;
+			c2l(in,tin1); tin[1]=tin1;
+			RC2_decrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2c(tout0,out);
+			l2c(tout1,out);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		if (l != -8)
+			{
+			c2l(in,tin0); tin[0]=tin0;
+			c2l(in,tin1); tin[1]=tin1;
+			RC2_decrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2cn(tout0,tout1,out,l+8);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		l2c(xor0,iv);
+		l2c(xor1,iv);
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	tin[0]=tin[1]=0;
+	}
+
+void RC2_encrypt(unsigned long *d, RC2_KEY *key)
+	{
+	int i,n;
+	register RC2_INT *p0,*p1;
+	register RC2_INT x0,x1,x2,x3,t;
+	unsigned long l;
+
+	l=d[0];
+	x0=(RC2_INT)l&0xffff;
+	x1=(RC2_INT)(l>>16L);
+	l=d[1];
+	x2=(RC2_INT)l&0xffff;
+	x3=(RC2_INT)(l>>16L);
+
+	n=3;
+	i=5;
+
+	p0=p1= &(key->data[0]);
+	for (;;)
+		{
+		t=(x0+(x1& ~x3)+(x2&x3)+ *(p0++))&0xffff;
+		x0=(t<<1)|(t>>15);
+		t=(x1+(x2& ~x0)+(x3&x0)+ *(p0++))&0xffff;
+		x1=(t<<2)|(t>>14);
+		t=(x2+(x3& ~x1)+(x0&x1)+ *(p0++))&0xffff;
+		x2=(t<<3)|(t>>13);
+		t=(x3+(x0& ~x2)+(x1&x2)+ *(p0++))&0xffff;
+		x3=(t<<5)|(t>>11);
+
+		if (--i == 0)
+			{
+			if (--n == 0) break;
+			i=(n == 2)?6:5;
+
+			x0+=p1[x3&0x3f];
+			x1+=p1[x0&0x3f];
+			x2+=p1[x1&0x3f];
+			x3+=p1[x2&0x3f];
+			}
+		}
+
+	d[0]=(unsigned long)(x0&0xffff)|((unsigned long)(x1&0xffff)<<16L);
+	d[1]=(unsigned long)(x2&0xffff)|((unsigned long)(x3&0xffff)<<16L);
+	}
+
+void RC2_decrypt(unsigned long *d, RC2_KEY *key)
+	{
+	int i,n;
+	register RC2_INT *p0,*p1;
+	register RC2_INT x0,x1,x2,x3,t;
+	unsigned long l;
+
+	l=d[0];
+	x0=(RC2_INT)l&0xffff;
+	x1=(RC2_INT)(l>>16L);
+	l=d[1];
+	x2=(RC2_INT)l&0xffff;
+	x3=(RC2_INT)(l>>16L);
+
+	n=3;
+	i=5;
+
+	p0= &(key->data[63]);
+	p1= &(key->data[0]);
+	for (;;)
+		{
+		t=((x3<<11)|(x3>>5))&0xffff;
+		x3=(t-(x0& ~x2)-(x1&x2)- *(p0--))&0xffff;
+		t=((x2<<13)|(x2>>3))&0xffff;
+		x2=(t-(x3& ~x1)-(x0&x1)- *(p0--))&0xffff;
+		t=((x1<<14)|(x1>>2))&0xffff;
+		x1=(t-(x2& ~x0)-(x3&x0)- *(p0--))&0xffff;
+		t=((x0<<15)|(x0>>1))&0xffff;
+		x0=(t-(x1& ~x3)-(x2&x3)- *(p0--))&0xffff;
+
+		if (--i == 0)
+			{
+			if (--n == 0) break;
+			i=(n == 2)?6:5;
+
+			x3=(x3-p1[x2&0x3f])&0xffff;
+			x2=(x2-p1[x1&0x3f])&0xffff;
+			x1=(x1-p1[x0&0x3f])&0xffff;
+			x0=(x0-p1[x3&0x3f])&0xffff;
+			}
+		}
+
+	d[0]=(unsigned long)(x0&0xffff)|((unsigned long)(x1&0xffff)<<16L);
+	d[1]=(unsigned long)(x2&0xffff)|((unsigned long)(x3&0xffff)<<16L);
+	}
+
diff --git a/openssl/crypto/rc2/rc2_ecb.c b/openssl/crypto/rc2/rc2_ecb.c
new file mode 100644
index 0000000..fff86c7
--- /dev/null
+++ b/openssl/crypto/rc2/rc2_ecb.c
@@ -0,0 +1,88 @@
+/* crypto/rc2/rc2_ecb.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc2.h>
+#include "rc2_locl.h"
+#include <openssl/opensslv.h>
+
+const char RC2_version[]="RC2" OPENSSL_VERSION_PTEXT;
+
+/* RC2 as implemented frm a posting from
+ * Newsgroups: sci.crypt
+ * Sender: pgut01@cs.auckland.ac.nz (Peter Gutmann)
+ * Subject: Specification for Ron Rivests Cipher No.2
+ * Message-ID: <4fk39f$f70@net.auckland.ac.nz>
+ * Date: 11 Feb 1996 06:45:03 GMT
+ */
+
+void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, RC2_KEY *ks,
+		     int encrypt)
+	{
+	unsigned long l,d[2];
+
+	c2l(in,l); d[0]=l;
+	c2l(in,l); d[1]=l;
+	if (encrypt)
+		RC2_encrypt(d,ks);
+	else
+		RC2_decrypt(d,ks);
+	l=d[0]; l2c(l,out);
+	l=d[1]; l2c(l,out);
+	l=d[0]=d[1]=0;
+	}
+
diff --git a/openssl/crypto/rc2/rc2_locl.h b/openssl/crypto/rc2/rc2_locl.h
new file mode 100644
index 0000000..565cd17
--- /dev/null
+++ b/openssl/crypto/rc2/rc2_locl.h
@@ -0,0 +1,156 @@
+/* crypto/rc2/rc2_locl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#undef c2l
+#define c2l(c,l)	(l =((unsigned long)(*((c)++)))    , \
+			 l|=((unsigned long)(*((c)++)))<< 8L, \
+			 l|=((unsigned long)(*((c)++)))<<16L, \
+			 l|=((unsigned long)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#undef c2ln
+#define c2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
+			case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
+			case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
+			case 5: l2|=((unsigned long)(*(--(c))));     \
+			case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
+			case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
+			case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
+			case 1: l1|=((unsigned long)(*(--(c))));     \
+				} \
+			}
+
+#undef l2c
+#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#undef l2cn
+#define l2cn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
+				} \
+			}
+
+/* NOTE - c is not incremented as per n2l */
+#define n2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))    ; \
+			case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
+			case 6: l2|=((unsigned long)(*(--(c))))<<16; \
+			case 5: l2|=((unsigned long)(*(--(c))))<<24; \
+			case 4: l1 =((unsigned long)(*(--(c))))    ; \
+			case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
+			case 2: l1|=((unsigned long)(*(--(c))))<<16; \
+			case 1: l1|=((unsigned long)(*(--(c))))<<24; \
+				} \
+			}
+
+/* NOTE - c is not incremented as per l2n */
+#define l2nn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+				} \
+			}
+
+#undef n2l
+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++))))
+
+#undef l2n
+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)     )&0xff))
+
+#define C_RC2(n) \
+	t=(x0+(x1& ~x3)+(x2&x3)+ *(p0++))&0xffff; \
+	x0=(t<<1)|(t>>15); \
+	t=(x1+(x2& ~x0)+(x3&x0)+ *(p0++))&0xffff; \
+	x1=(t<<2)|(t>>14); \
+	t=(x2+(x3& ~x1)+(x0&x1)+ *(p0++))&0xffff; \
+	x2=(t<<3)|(t>>13); \
+	t=(x3+(x0& ~x2)+(x1&x2)+ *(p0++))&0xffff; \
+	x3=(t<<5)|(t>>11);
+
diff --git a/openssl/crypto/rc2/rc2_skey.c b/openssl/crypto/rc2/rc2_skey.c
new file mode 100644
index 0000000..0150b0e
--- /dev/null
+++ b/openssl/crypto/rc2/rc2_skey.c
@@ -0,0 +1,145 @@
+/* crypto/rc2/rc2_skey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc2.h>
+#include "rc2_locl.h"
+
+static const unsigned char key_table[256]={
+	0xd9,0x78,0xf9,0xc4,0x19,0xdd,0xb5,0xed,0x28,0xe9,0xfd,0x79,
+	0x4a,0xa0,0xd8,0x9d,0xc6,0x7e,0x37,0x83,0x2b,0x76,0x53,0x8e,
+	0x62,0x4c,0x64,0x88,0x44,0x8b,0xfb,0xa2,0x17,0x9a,0x59,0xf5,
+	0x87,0xb3,0x4f,0x13,0x61,0x45,0x6d,0x8d,0x09,0x81,0x7d,0x32,
+	0xbd,0x8f,0x40,0xeb,0x86,0xb7,0x7b,0x0b,0xf0,0x95,0x21,0x22,
+	0x5c,0x6b,0x4e,0x82,0x54,0xd6,0x65,0x93,0xce,0x60,0xb2,0x1c,
+	0x73,0x56,0xc0,0x14,0xa7,0x8c,0xf1,0xdc,0x12,0x75,0xca,0x1f,
+	0x3b,0xbe,0xe4,0xd1,0x42,0x3d,0xd4,0x30,0xa3,0x3c,0xb6,0x26,
+	0x6f,0xbf,0x0e,0xda,0x46,0x69,0x07,0x57,0x27,0xf2,0x1d,0x9b,
+	0xbc,0x94,0x43,0x03,0xf8,0x11,0xc7,0xf6,0x90,0xef,0x3e,0xe7,
+	0x06,0xc3,0xd5,0x2f,0xc8,0x66,0x1e,0xd7,0x08,0xe8,0xea,0xde,
+	0x80,0x52,0xee,0xf7,0x84,0xaa,0x72,0xac,0x35,0x4d,0x6a,0x2a,
+	0x96,0x1a,0xd2,0x71,0x5a,0x15,0x49,0x74,0x4b,0x9f,0xd0,0x5e,
+	0x04,0x18,0xa4,0xec,0xc2,0xe0,0x41,0x6e,0x0f,0x51,0xcb,0xcc,
+	0x24,0x91,0xaf,0x50,0xa1,0xf4,0x70,0x39,0x99,0x7c,0x3a,0x85,
+	0x23,0xb8,0xb4,0x7a,0xfc,0x02,0x36,0x5b,0x25,0x55,0x97,0x31,
+	0x2d,0x5d,0xfa,0x98,0xe3,0x8a,0x92,0xae,0x05,0xdf,0x29,0x10,
+	0x67,0x6c,0xba,0xc9,0xd3,0x00,0xe6,0xcf,0xe1,0x9e,0xa8,0x2c,
+	0x63,0x16,0x01,0x3f,0x58,0xe2,0x89,0xa9,0x0d,0x38,0x34,0x1b,
+	0xab,0x33,0xff,0xb0,0xbb,0x48,0x0c,0x5f,0xb9,0xb1,0xcd,0x2e,
+	0xc5,0xf3,0xdb,0x47,0xe5,0xa5,0x9c,0x77,0x0a,0xa6,0x20,0x68,
+	0xfe,0x7f,0xc1,0xad,
+	};
+
+#if defined(_MSC_VER) && defined(_ARM_)
+#pragma optimize("g",off)
+#endif
+
+/* It has come to my attention that there are 2 versions of the RC2
+ * key schedule.  One which is normal, and anther which has a hook to
+ * use a reduced key length.
+ * BSAFE uses the 'retarded' version.  What I previously shipped is
+ * the same as specifying 1024 for the 'bits' parameter.  Bsafe uses
+ * a version where the bits parameter is the same as len*8 */
+void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits)
+	{
+	int i,j;
+	unsigned char *k;
+	RC2_INT *ki;
+	unsigned int c,d;
+
+	k= (unsigned char *)&(key->data[0]);
+	*k=0; /* for if there is a zero length key */
+
+	if (len > 128) len=128;
+	if (bits <= 0) bits=1024;
+	if (bits > 1024) bits=1024;
+
+	for (i=0; i<len; i++)
+		k[i]=data[i];
+
+	/* expand table */
+	d=k[len-1];
+	j=0;
+	for (i=len; i < 128; i++,j++)
+		{
+		d=key_table[(k[j]+d)&0xff];
+		k[i]=d;
+		}
+
+	/* hmm.... key reduction to 'bits' bits */
+
+	j=(bits+7)>>3;
+	i=128-j;
+	c= (0xff>>(-bits & 0x07));
+
+	d=key_table[k[i]&c];
+	k[i]=d;
+	while (i--)
+		{
+		d=key_table[k[i+j]^d];
+		k[i]=d;
+		}
+
+	/* copy from bytes into RC2_INT's */
+	ki= &(key->data[63]);
+	for (i=127; i>=0; i-=2)
+		*(ki--)=((k[i]<<8)|k[i-1])&0xffff;
+	}
+
+#if defined(_MSC_VER)
+#pragma optimize("",on)
+#endif
diff --git a/openssl/crypto/rc2/rc2cfb64.c b/openssl/crypto/rc2/rc2cfb64.c
new file mode 100644
index 0000000..b3a0158
--- /dev/null
+++ b/openssl/crypto/rc2/rc2cfb64.c
@@ -0,0 +1,122 @@
+/* crypto/rc2/rc2cfb64.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc2.h>
+#include "rc2_locl.h"
+
+/* The input and output encrypted as though 64bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+
+void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+		       long length, RC2_KEY *schedule, unsigned char *ivec,
+		       int *num, int encrypt)
+	{
+	register unsigned long v0,v1,t;
+	register int n= *num;
+	register long l=length;
+	unsigned long ti[2];
+	unsigned char *iv,c,cc;
+
+	iv=(unsigned char *)ivec;
+	if (encrypt)
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				c2l(iv,v0); ti[0]=v0;
+				c2l(iv,v1); ti[1]=v1;
+				RC2_encrypt((unsigned long *)ti,schedule);
+				iv=(unsigned char *)ivec;
+				t=ti[0]; l2c(t,iv);
+				t=ti[1]; l2c(t,iv);
+				iv=(unsigned char *)ivec;
+				}
+			c= *(in++)^iv[n];
+			*(out++)=c;
+			iv[n]=c;
+			n=(n+1)&0x07;
+			}
+		}
+	else
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				c2l(iv,v0); ti[0]=v0;
+				c2l(iv,v1); ti[1]=v1;
+				RC2_encrypt((unsigned long *)ti,schedule);
+				iv=(unsigned char *)ivec;
+				t=ti[0]; l2c(t,iv);
+				t=ti[1]; l2c(t,iv);
+				iv=(unsigned char *)ivec;
+				}
+			cc= *(in++);
+			c=iv[n];
+			iv[n]=cc;
+			*(out++)=c^cc;
+			n=(n+1)&0x07;
+			}
+		}
+	v0=v1=ti[0]=ti[1]=t=c=cc=0;
+	*num=n;
+	}
+
diff --git a/openssl/crypto/rc2/rc2ofb64.c b/openssl/crypto/rc2/rc2ofb64.c
new file mode 100644
index 0000000..9e29786
--- /dev/null
+++ b/openssl/crypto/rc2/rc2ofb64.c
@@ -0,0 +1,111 @@
+/* crypto/rc2/rc2ofb64.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc2.h>
+#include "rc2_locl.h"
+
+/* The input and output encrypted as though 64bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+		       long length, RC2_KEY *schedule, unsigned char *ivec,
+		       int *num)
+	{
+	register unsigned long v0,v1,t;
+	register int n= *num;
+	register long l=length;
+	unsigned char d[8];
+	register char *dp;
+	unsigned long ti[2];
+	unsigned char *iv;
+	int save=0;
+
+	iv=(unsigned char *)ivec;
+	c2l(iv,v0);
+	c2l(iv,v1);
+	ti[0]=v0;
+	ti[1]=v1;
+	dp=(char *)d;
+	l2c(v0,dp);
+	l2c(v1,dp);
+	while (l--)
+		{
+		if (n == 0)
+			{
+			RC2_encrypt((unsigned long *)ti,schedule);
+			dp=(char *)d;
+			t=ti[0]; l2c(t,dp);
+			t=ti[1]; l2c(t,dp);
+			save++;
+			}
+		*(out++)= *(in++)^d[n];
+		n=(n+1)&0x07;
+		}
+	if (save)
+		{
+		v0=ti[0];
+		v1=ti[1];
+		iv=(unsigned char *)ivec;
+		l2c(v0,iv);
+		l2c(v1,iv);
+		}
+	t=v0=v1=ti[0]=ti[1]=0;
+	*num=n;
+	}
+
diff --git a/openssl/crypto/rc2/rc2speed.c b/openssl/crypto/rc2/rc2speed.c
new file mode 100644
index 0000000..85cf6f6
--- /dev/null
+++ b/openssl/crypto/rc2/rc2speed.c
@@ -0,0 +1,277 @@
+/* crypto/rc2/rc2speed.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
+/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
+
+#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
+#define TIMES
+#endif
+
+#include <stdio.h>
+
+#include <openssl/e_os2.h>
+#include OPENSSL_UNISTD_IO
+OPENSSL_DECLARE_EXIT
+
+#ifndef OPENSSL_SYS_NETWARE
+#include <signal.h>
+#endif
+
+#ifndef _IRIX
+#include <time.h>
+#endif
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+#endif
+
+/* Depending on the VMS version, the tms structure is perhaps defined.
+   The __TMS macro will show if it was.  If it wasn't defined, we should
+   undefine TIMES, since that tells the rest of the program how things
+   should be handled.				-- Richard Levitte */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
+#undef TIMES
+#endif
+
+#ifndef TIMES
+#include <sys/timeb.h>
+#endif
+
+#if defined(sun) || defined(__ultrix)
+#define _POSIX_SOURCE
+#include <limits.h>
+#include <sys/param.h>
+#endif
+
+#include <openssl/rc2.h>
+
+/* The following if from times(3) man page.  It may need to be changed */
+#ifndef HZ
+#ifndef CLK_TCK
+#define HZ	100.0
+#else	/* CLK_TCK */
+#define HZ ((double)CLK_TCK)
+#endif	/* CLK_TCK */
+#endif	/* HZ */
+
+#define BUFSIZE	((long)1024)
+long run=0;
+
+double Time_F(int s);
+#ifdef SIGALRM
+#if defined(__STDC__) || defined(sgi) || defined(_AIX)
+#define SIGRETTYPE void
+#else
+#define SIGRETTYPE int
+#endif
+
+SIGRETTYPE sig_done(int sig);
+SIGRETTYPE sig_done(int sig)
+	{
+	signal(SIGALRM,sig_done);
+	run=0;
+#ifdef LINT
+	sig=sig;
+#endif
+	}
+#endif
+
+#define START	0
+#define STOP	1
+
+double Time_F(int s)
+	{
+	double ret;
+#ifdef TIMES
+	static struct tms tstart,tend;
+
+	if (s == START)
+		{
+		times(&tstart);
+		return(0);
+		}
+	else
+		{
+		times(&tend);
+		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#else /* !times() */
+	static struct timeb tstart,tend;
+	long i;
+
+	if (s == START)
+		{
+		ftime(&tstart);
+		return(0);
+		}
+	else
+		{
+		ftime(&tend);
+		i=(long)tend.millitm-(long)tstart.millitm;
+		ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#endif
+	}
+
+int main(int argc, char **argv)
+	{
+	long count;
+	static unsigned char buf[BUFSIZE];
+	static unsigned char key[] ={
+			0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+			0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
+			};
+	RC2_KEY sch;
+	double a,b,c,d;
+#ifndef SIGALRM
+	long ca,cb,cc;
+#endif
+
+#ifndef TIMES
+	printf("To get the most accurate results, try to run this\n");
+	printf("program when this computer is idle.\n");
+#endif
+
+#ifndef SIGALRM
+	printf("First we calculate the approximate speed ...\n");
+	RC2_set_key(&sch,16,key,128);
+	count=10;
+	do	{
+		long i;
+		unsigned long data[2];
+
+		count*=2;
+		Time_F(START);
+		for (i=count; i; i--)
+			RC2_encrypt(data,&sch);
+		d=Time_F(STOP);
+		} while (d < 3.0);
+	ca=count/512;
+	cb=count;
+	cc=count*8/BUFSIZE+1;
+	printf("Doing RC2_set_key %ld times\n",ca);
+#define COND(d)	(count != (d))
+#define COUNT(d) (d)
+#else
+#define COND(c)	(run)
+#define COUNT(d) (count)
+	signal(SIGALRM,sig_done);
+	printf("Doing RC2_set_key for 10 seconds\n");
+	alarm(10);
+#endif
+
+	Time_F(START);
+	for (count=0,run=1; COND(ca); count+=4)
+		{
+		RC2_set_key(&sch,16,key,128);
+		RC2_set_key(&sch,16,key,128);
+		RC2_set_key(&sch,16,key,128);
+		RC2_set_key(&sch,16,key,128);
+		}
+	d=Time_F(STOP);
+	printf("%ld RC2_set_key's in %.2f seconds\n",count,d);
+	a=((double)COUNT(ca))/d;
+
+#ifdef SIGALRM
+	printf("Doing RC2_encrypt's for 10 seconds\n");
+	alarm(10);
+#else
+	printf("Doing RC2_encrypt %ld times\n",cb);
+#endif
+	Time_F(START);
+	for (count=0,run=1; COND(cb); count+=4)
+		{
+		unsigned long data[2];
+
+		RC2_encrypt(data,&sch);
+		RC2_encrypt(data,&sch);
+		RC2_encrypt(data,&sch);
+		RC2_encrypt(data,&sch);
+		}
+	d=Time_F(STOP);
+	printf("%ld RC2_encrypt's in %.2f second\n",count,d);
+	b=((double)COUNT(cb)*8)/d;
+
+#ifdef SIGALRM
+	printf("Doing RC2_cbc_encrypt on %ld byte blocks for 10 seconds\n",
+		BUFSIZE);
+	alarm(10);
+#else
+	printf("Doing RC2_cbc_encrypt %ld times on %ld byte blocks\n",cc,
+		BUFSIZE);
+#endif
+	Time_F(START);
+	for (count=0,run=1; COND(cc); count++)
+		RC2_cbc_encrypt(buf,buf,BUFSIZE,&sch,
+			&(key[0]),RC2_ENCRYPT);
+	d=Time_F(STOP);
+	printf("%ld RC2_cbc_encrypt's of %ld byte blocks in %.2f second\n",
+		count,BUFSIZE,d);
+	c=((double)COUNT(cc)*BUFSIZE)/d;
+
+	printf("RC2 set_key       per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a);
+	printf("RC2 raw ecb bytes per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b);
+	printf("RC2 cbc     bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c);
+	exit(0);
+#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
+	return(0);
+#endif
+	}
diff --git a/openssl/crypto/rc2/rc2test.c b/openssl/crypto/rc2/rc2test.c
new file mode 100644
index 0000000..0e11743
--- /dev/null
+++ b/openssl/crypto/rc2/rc2test.c
@@ -0,0 +1,274 @@
+/* crypto/rc2/rc2test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* This has been a quickly hacked 'ideatest.c'.  When I add tests for other
+ * RC2 modes, more of the code will be uncommented. */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_RC2
+int main(int argc, char *argv[])
+{
+    printf("No RC2 support\n");
+    return(0);
+}
+#else
+#include <openssl/rc2.h>
+
+static unsigned char RC2key[4][16]={
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+	 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F},
+	};
+
+static unsigned char RC2plain[4][8]={
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	};
+
+static unsigned char RC2cipher[4][8]={
+	{0x1C,0x19,0x8A,0x83,0x8D,0xF0,0x28,0xB7},
+	{0x21,0x82,0x9C,0x78,0xA9,0xF9,0xC0,0x74},
+	{0x13,0xDB,0x35,0x17,0xD3,0x21,0x86,0x9E},
+	{0x50,0xDC,0x01,0x62,0xBD,0x75,0x7F,0x31},
+	};
+/************/
+#ifdef undef
+unsigned char k[16]={
+	0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,
+	0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08};
+
+unsigned char in[8]={0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x03};
+unsigned char  c[8]={0x11,0xFB,0xED,0x2B,0x01,0x98,0x6D,0xE5};
+unsigned char out[80];
+
+char *text="Hello to all people out there";
+
+static unsigned char cfb_key[16]={
+	0xe1,0xf0,0xc3,0xd2,0xa5,0xb4,0x87,0x96,
+	0x69,0x78,0x4b,0x5a,0x2d,0x3c,0x0f,0x1e,
+	};
+static unsigned char cfb_iv[80]={0x34,0x12,0x78,0x56,0xab,0x90,0xef,0xcd};
+static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
+#define CFB_TEST_SIZE 24
+static unsigned char plain[CFB_TEST_SIZE]=
+        {
+        0x4e,0x6f,0x77,0x20,0x69,0x73,
+        0x20,0x74,0x68,0x65,0x20,0x74,
+        0x69,0x6d,0x65,0x20,0x66,0x6f,
+        0x72,0x20,0x61,0x6c,0x6c,0x20
+        };
+static unsigned char cfb_cipher64[CFB_TEST_SIZE]={
+	0x59,0xD8,0xE2,0x65,0x00,0x58,0x6C,0x3F,
+	0x2C,0x17,0x25,0xD0,0x1A,0x38,0xB7,0x2A,
+	0x39,0x61,0x37,0xDC,0x79,0xFB,0x9F,0x45
+
+/*	0xF9,0x78,0x32,0xB5,0x42,0x1A,0x6B,0x38,
+	0x9A,0x44,0xD6,0x04,0x19,0x43,0xC4,0xD9,
+	0x3D,0x1E,0xAE,0x47,0xFC,0xCF,0x29,0x0B,*/
+	}; 
+
+
+/*static int cfb64_test(unsigned char *cfb_cipher);*/
+static char *pt(unsigned char *p);
+#endif
+
+int main(int argc, char *argv[])
+	{
+	int i,n,err=0;
+	RC2_KEY key; 
+	unsigned char buf[8],buf2[8];
+
+	for (n=0; n<4; n++)
+		{
+		RC2_set_key(&key,16,&(RC2key[n][0]),0 /* or 1024 */);
+
+		RC2_ecb_encrypt(&(RC2plain[n][0]),buf,&key,RC2_ENCRYPT);
+		if (memcmp(&(RC2cipher[n][0]),buf,8) != 0)
+			{
+			printf("ecb rc2 error encrypting\n");
+			printf("got     :");
+			for (i=0; i<8; i++)
+				printf("%02X ",buf[i]);
+			printf("\n");
+			printf("expected:");
+			for (i=0; i<8; i++)
+				printf("%02X ",RC2cipher[n][i]);
+			err=20;
+			printf("\n");
+			}
+
+		RC2_ecb_encrypt(buf,buf2,&key,RC2_DECRYPT);
+		if (memcmp(&(RC2plain[n][0]),buf2,8) != 0)
+			{
+			printf("ecb RC2 error decrypting\n");
+			printf("got     :");
+			for (i=0; i<8; i++)
+				printf("%02X ",buf[i]);
+			printf("\n");
+			printf("expected:");
+			for (i=0; i<8; i++)
+				printf("%02X ",RC2plain[n][i]);
+			printf("\n");
+			err=3;
+			}
+		}
+
+	if (err == 0) printf("ecb RC2 ok\n");
+#ifdef undef
+	memcpy(iv,k,8);
+	idea_cbc_encrypt((unsigned char *)text,out,strlen(text)+1,&key,iv,1);
+	memcpy(iv,k,8);
+	idea_cbc_encrypt(out,out,8,&dkey,iv,0);
+	idea_cbc_encrypt(&(out[8]),&(out[8]),strlen(text)+1-8,&dkey,iv,0);
+	if (memcmp(text,out,strlen(text)+1) != 0)
+		{
+		printf("cbc idea bad\n");
+		err=4;
+		}
+	else
+		printf("cbc idea ok\n");
+
+	printf("cfb64 idea ");
+	if (cfb64_test(cfb_cipher64))
+		{
+		printf("bad\n");
+		err=5;
+		}
+	else
+		printf("ok\n");
+#endif
+
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
+	EXIT(err);
+	return(err);
+	}
+
+#ifdef undef
+static int cfb64_test(unsigned char *cfb_cipher)
+        {
+        IDEA_KEY_SCHEDULE eks,dks;
+        int err=0,i,n;
+
+        idea_set_encrypt_key(cfb_key,&eks);
+        idea_set_decrypt_key(&eks,&dks);
+        memcpy(cfb_tmp,cfb_iv,8);
+        n=0;
+        idea_cfb64_encrypt(plain,cfb_buf1,(long)12,&eks,
+                cfb_tmp,&n,IDEA_ENCRYPT);
+        idea_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
+                (long)CFB_TEST_SIZE-12,&eks,
+                cfb_tmp,&n,IDEA_ENCRYPT);
+        if (memcmp(cfb_cipher,cfb_buf1,CFB_TEST_SIZE) != 0)
+                {
+                err=1;
+                printf("idea_cfb64_encrypt encrypt error\n");
+                for (i=0; i<CFB_TEST_SIZE; i+=8)
+                        printf("%s\n",pt(&(cfb_buf1[i])));
+                }
+        memcpy(cfb_tmp,cfb_iv,8);
+        n=0;
+        idea_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,&eks,
+                cfb_tmp,&n,IDEA_DECRYPT);
+        idea_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
+                (long)CFB_TEST_SIZE-17,&dks,
+                cfb_tmp,&n,IDEA_DECRYPT);
+        if (memcmp(plain,cfb_buf2,CFB_TEST_SIZE) != 0)
+                {
+                err=1;
+                printf("idea_cfb_encrypt decrypt error\n");
+                for (i=0; i<24; i+=8)
+                        printf("%s\n",pt(&(cfb_buf2[i])));
+                }
+        return(err);
+        }
+
+static char *pt(unsigned char *p)
+	{
+	static char bufs[10][20];
+	static int bnum=0;
+	char *ret;
+	int i;
+	static char *f="0123456789ABCDEF";
+
+	ret= &(bufs[bnum++][0]);
+	bnum%=10;
+	for (i=0; i<8; i++)
+		{
+		ret[i*2]=f[(p[i]>>4)&0xf];
+		ret[i*2+1]=f[p[i]&0xf];
+		}
+	ret[16]='\0';
+	return(ret);
+	}
+	
+#endif
+#endif
diff --git a/openssl/crypto/rc2/rrc2.doc b/openssl/crypto/rc2/rrc2.doc
new file mode 100644
index 0000000..f93ee00
--- /dev/null
+++ b/openssl/crypto/rc2/rrc2.doc
@@ -0,0 +1,219 @@
+>From cygnus.mincom.oz.au!minbne.mincom.oz.au!bunyip.cc.uq.oz.au!munnari.OZ.AU!comp.vuw.ac.nz!waikato!auckland.ac.nz!news Mon Feb 12 18:48:17 EST 1996
+Article 23601 of sci.crypt:
+Path: cygnus.mincom.oz.au!minbne.mincom.oz.au!bunyip.cc.uq.oz.au!munnari.OZ.AU!comp.vuw.ac.nz!waikato!auckland.ac.nz!news
+>From: pgut01@cs.auckland.ac.nz (Peter Gutmann)
+Newsgroups: sci.crypt
+Subject: Specification for Ron Rivests Cipher No.2
+Date: 11 Feb 1996 06:45:03 GMT
+Organization: University of Auckland
+Lines: 203
+Sender: pgut01@cs.auckland.ac.nz (Peter Gutmann)
+Message-ID: <4fk39f$f70@net.auckland.ac.nz>
+NNTP-Posting-Host: cs26.cs.auckland.ac.nz
+X-Newsreader: NN version 6.5.0 #3 (NOV)
+
+
+
+
+                           Ron Rivest's Cipher No.2
+                           ------------------------
+ 
+Ron Rivest's Cipher No.2 (hereafter referred to as RRC.2, other people may
+refer to it by other names) is word oriented, operating on a block of 64 bits
+divided into four 16-bit words, with a key table of 64 words.  All data units
+are little-endian.  This functional description of the algorithm is based in
+the paper "The RC5 Encryption Algorithm" (RC5 is a trademark of RSADSI), using
+the same general layout, terminology, and pseudocode style.
+ 
+ 
+Notation and RRC.2 Primitive Operations
+ 
+RRC.2 uses the following primitive operations:
+ 
+1. Two's-complement addition of words, denoted by "+".  The inverse operation,
+   subtraction, is denoted by "-".
+2. Bitwise exclusive OR, denoted by "^".
+3. Bitwise AND, denoted by "&".
+4. Bitwise NOT, denoted by "~".
+5. A left-rotation of words; the rotation of word x left by y is denoted
+   x <<< y.  The inverse operation, right-rotation, is denoted x >>> y.
+ 
+These operations are directly and efficiently supported by most processors.
+ 
+ 
+The RRC.2 Algorithm
+ 
+RRC.2 consists of three components, a *key expansion* algorithm, an
+*encryption* algorithm, and a *decryption* algorithm.
+ 
+ 
+Key Expansion
+ 
+The purpose of the key-expansion routine is to expand the user's key K to fill
+the expanded key array S, so S resembles an array of random binary words
+determined by the user's secret key K.
+ 
+Initialising the S-box
+ 
+RRC.2 uses a single 256-byte S-box derived from the ciphertext contents of
+Beale Cipher No.1 XOR'd with a one-time pad.  The Beale Ciphers predate modern
+cryptography by enough time that there should be no concerns about trapdoors
+hidden in the data.  They have been published widely, and the S-box can be
+easily recreated from the one-time pad values and the Beale Cipher data taken
+from a standard source.  To initialise the S-box:
+ 
+  for i = 0 to 255 do
+    sBox[ i ] = ( beale[ i ] mod 256 ) ^ pad[ i ]
+ 
+The contents of Beale Cipher No.1 and the necessary one-time pad are given as
+an appendix at the end of this document.  For efficiency, implementors may wish
+to skip the Beale Cipher expansion and store the sBox table directly.
+ 
+Expanding the Secret Key to 128 Bytes
+ 
+The secret key is first expanded to fill 128 bytes (64 words).  The expansion
+consists of taking the sum of the first and last bytes in the user key, looking
+up the sum (modulo 256) in the S-box, and appending the result to the key.  The
+operation is repeated with the second byte and new last byte of the key until
+all 128 bytes have been generated.  Note that the following pseudocode treats
+the S array as an array of 128 bytes rather than 64 words.
+ 
+  for j = 0 to length-1 do
+    S[ j ] = K[ j ]
+  for j = length to 127 do
+    s[ j ] = sBox[ ( S[ j-length ] + S[ j-1 ] ) mod 256 ];
+ 
+At this point it is possible to perform a truncation of the effective key
+length to ease the creation of espionage-enabled software products.  However
+since the author cannot conceive why anyone would want to do this, it will not
+be considered further.
+ 
+The final phase of the key expansion involves replacing the first byte of S
+with the entry selected from the S-box:
+ 
+  S[ 0 ] = sBox[ S[ 0 ] ]
+ 
+ 
+Encryption
+ 
+The cipher has 16 full rounds, each divided into 4 subrounds.  Two of the full
+rounds perform an additional transformation on the data.  Note that the
+following pseudocode treats the S array as an array of 64 words rather than 128
+bytes.
+ 
+  for i = 0 to 15 do
+    j = i * 4;
+    word0 = ( word0 + ( word1 & ~word3 ) + ( word2 & word3 ) + S[ j+0 ] ) <<< 1
+    word1 = ( word1 + ( word2 & ~word0 ) + ( word3 & word0 ) + S[ j+1 ] ) <<< 2
+    word2 = ( word2 + ( word3 & ~word1 ) + ( word0 & word1 ) + S[ j+2 ] ) <<< 3
+    word3 = ( word3 + ( word0 & ~word2 ) + ( word1 & word2 ) + S[ j+3 ] ) <<< 5
+ 
+In addition the fifth and eleventh rounds add the contents of the S-box indexed
+by one of the data words to another of the data words following the four
+subrounds as follows:
+ 
+    word0 = word0 + S[ word3 & 63 ];
+    word1 = word1 + S[ word0 & 63 ];
+    word2 = word2 + S[ word1 & 63 ];
+    word3 = word3 + S[ word2 & 63 ];
+ 
+ 
+Decryption
+ 
+The decryption operation is simply the inverse of the encryption operation.
+Note that the following pseudocode treats the S array as an array of 64 words
+rather than 128 bytes.
+ 
+  for i = 15 downto 0 do
+    j = i * 4;
+    word3 = ( word3 >>> 5 ) - ( word0 & ~word2 ) - ( word1 & word2 ) - S[ j+3 ]
+    word2 = ( word2 >>> 3 ) - ( word3 & ~word1 ) - ( word0 & word1 ) - S[ j+2 ]
+    word1 = ( word1 >>> 2 ) - ( word2 & ~word0 ) - ( word3 & word0 ) - S[ j+1 ]
+    word0 = ( word0 >>> 1 ) - ( word1 & ~word3 ) - ( word2 & word3 ) - S[ j+0 ]
+ 
+In addition the fifth and eleventh rounds subtract the contents of the S-box
+indexed by one of the data words from another one of the data words following
+the four subrounds as follows:
+ 
+    word3 = word3 - S[ word2 & 63 ]
+    word2 = word2 - S[ word1 & 63 ]
+    word1 = word1 - S[ word0 & 63 ]
+    word0 = word0 - S[ word3 & 63 ]
+ 
+ 
+Test Vectors
+ 
+The following test vectors may be used to test the correctness of an RRC.2
+implementation:
+ 
+  Key:      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+  Plain:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+  Cipher:   0x1C, 0x19, 0x8A, 0x83, 0x8D, 0xF0, 0x28, 0xB7
+ 
+  Key:      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+  Plain:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+  Cipher:   0x21, 0x82, 0x9C, 0x78, 0xA9, 0xF9, 0xC0, 0x74
+ 
+  Key:      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+  Plain:    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+  Cipher:   0x13, 0xDB, 0x35, 0x17, 0xD3, 0x21, 0x86, 0x9E
+ 
+  Key:      0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+            0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+  Plain:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+  Cipher:   0x50, 0xDC, 0x01, 0x62, 0xBD, 0x75, 0x7F, 0x31
+ 
+ 
+Appendix: Beale Cipher No.1, "The Locality of the Vault", and One-time Pad for
+          Creating the S-Box
+ 
+Beale Cipher No.1.
+ 
+  71, 194,  38,1701,  89,  76,  11,  83,1629,  48,  94,  63, 132,  16, 111,  95,
+  84, 341, 975,  14,  40,  64,  27,  81, 139, 213,  63,  90,1120,   8,  15,   3,
+ 126,2018,  40,  74, 758, 485, 604, 230, 436, 664, 582, 150, 251, 284, 308, 231,
+ 124, 211, 486, 225, 401, 370,  11, 101, 305, 139, 189,  17,  33,  88, 208, 193,
+ 145,   1,  94,  73, 416, 918, 263,  28, 500, 538, 356, 117, 136, 219,  27, 176,
+ 130,  10, 460,  25, 485,  18, 436,  65,  84, 200, 283, 118, 320, 138,  36, 416,
+ 280,  15,  71, 224, 961,  44,  16, 401,  39,  88,  61, 304,  12,  21,  24, 283,
+ 134,  92,  63, 246, 486, 682,   7, 219, 184, 360, 780,  18,  64, 463, 474, 131,
+ 160,  79,  73, 440,  95,  18,  64, 581,  34,  69, 128, 367, 460,  17,  81,  12,
+ 103, 820,  62, 110,  97, 103, 862,  70,  60,1317, 471, 540, 208, 121, 890, 346,
+  36, 150,  59, 568, 614,  13, 120,  63, 219, 812,2160,1780,  99,  35,  18,  21,
+ 136, 872,  15,  28, 170,  88,   4,  30,  44, 112,  18, 147, 436, 195, 320,  37,
+ 122, 113,   6, 140,   8, 120, 305,  42,  58, 461,  44, 106, 301,  13, 408, 680,
+  93,  86, 116, 530,  82, 568,   9, 102,  38, 416,  89,  71, 216, 728, 965, 818,
+   2,  38, 121, 195,  14, 326, 148, 234,  18,  55, 131, 234, 361, 824,   5,  81,
+ 623,  48, 961,  19,  26,  33,  10,1101, 365,  92,  88, 181, 275, 346, 201, 206
+ 
+One-time Pad.
+ 
+ 158, 186, 223,  97,  64, 145, 190, 190, 117, 217, 163,  70, 206, 176, 183, 194,
+ 146,  43, 248, 141,   3,  54,  72, 223, 233, 153,  91, 210,  36, 131, 244, 161,
+ 105, 120, 113, 191, 113,  86,  19, 245, 213, 221,  43,  27, 242, 157,  73, 213,
+ 193,  92, 166,  10,  23, 197, 112, 110, 193,  30, 156,  51, 125,  51, 158,  67,
+ 197, 215,  59, 218, 110, 246, 181,   0, 135,  76, 164,  97,  47,  87, 234, 108,
+ 144, 127,   6,   6, 222, 172,  80, 144,  22, 245, 207,  70, 227, 182, 146, 134,
+ 119, 176,  73,  58, 135,  69,  23, 198,   0, 170,  32, 171, 176, 129,  91,  24,
+ 126,  77, 248,   0, 118,  69,  57,  60, 190, 171, 217,  61, 136, 169, 196,  84,
+ 168, 167, 163, 102, 223,  64, 174, 178, 166, 239, 242, 195, 249,  92,  59,  38,
+ 241,  46, 236,  31,  59, 114,  23,  50, 119, 186,   7,  66, 212,  97, 222, 182,
+ 230, 118, 122,  86, 105,  92, 179, 243, 255, 189, 223, 164, 194, 215,  98,  44,
+  17,  20,  53, 153, 137, 224, 176, 100, 208, 114,  36, 200, 145, 150, 215,  20,
+  87,  44, 252,  20, 235, 242, 163, 132,  63,  18,   5, 122,  74,  97,  34,  97,
+ 142,  86, 146, 221, 179, 166, 161,  74,  69, 182,  88, 120, 128,  58,  76, 155,
+  15,  30,  77, 216, 165, 117, 107,  90, 169, 127, 143, 181, 208, 137, 200, 127,
+ 170, 195,  26,  84, 255, 132, 150,  58, 103, 250, 120, 221, 237,  37,   8,  99
+ 
+ 
+Implementation
+ 
+A non-US based programmer who has never seen any encryption code before will
+shortly be implementing RRC.2 based solely on this specification and not on
+knowledge of any other encryption algorithms.  Stand by.
+
+
+
diff --git a/openssl/crypto/rc2/tab.c b/openssl/crypto/rc2/tab.c
new file mode 100644
index 0000000..25dc14e
--- /dev/null
+++ b/openssl/crypto/rc2/tab.c
@@ -0,0 +1,86 @@
+#include <stdio.h>
+
+unsigned char ebits_to_num[256]={
+	0xbd,0x56,0xea,0xf2,0xa2,0xf1,0xac,0x2a,
+	0xb0,0x93,0xd1,0x9c,0x1b,0x33,0xfd,0xd0,
+	0x30,0x04,0xb6,0xdc,0x7d,0xdf,0x32,0x4b,
+	0xf7,0xcb,0x45,0x9b,0x31,0xbb,0x21,0x5a,
+	0x41,0x9f,0xe1,0xd9,0x4a,0x4d,0x9e,0xda,
+	0xa0,0x68,0x2c,0xc3,0x27,0x5f,0x80,0x36,
+	0x3e,0xee,0xfb,0x95,0x1a,0xfe,0xce,0xa8,
+	0x34,0xa9,0x13,0xf0,0xa6,0x3f,0xd8,0x0c,
+	0x78,0x24,0xaf,0x23,0x52,0xc1,0x67,0x17,
+	0xf5,0x66,0x90,0xe7,0xe8,0x07,0xb8,0x60,
+	0x48,0xe6,0x1e,0x53,0xf3,0x92,0xa4,0x72,
+	0x8c,0x08,0x15,0x6e,0x86,0x00,0x84,0xfa,
+	0xf4,0x7f,0x8a,0x42,0x19,0xf6,0xdb,0xcd,
+	0x14,0x8d,0x50,0x12,0xba,0x3c,0x06,0x4e,
+	0xec,0xb3,0x35,0x11,0xa1,0x88,0x8e,0x2b,
+	0x94,0x99,0xb7,0x71,0x74,0xd3,0xe4,0xbf,
+	0x3a,0xde,0x96,0x0e,0xbc,0x0a,0xed,0x77,
+	0xfc,0x37,0x6b,0x03,0x79,0x89,0x62,0xc6,
+	0xd7,0xc0,0xd2,0x7c,0x6a,0x8b,0x22,0xa3,
+	0x5b,0x05,0x5d,0x02,0x75,0xd5,0x61,0xe3,
+	0x18,0x8f,0x55,0x51,0xad,0x1f,0x0b,0x5e,
+	0x85,0xe5,0xc2,0x57,0x63,0xca,0x3d,0x6c,
+	0xb4,0xc5,0xcc,0x70,0xb2,0x91,0x59,0x0d,
+	0x47,0x20,0xc8,0x4f,0x58,0xe0,0x01,0xe2,
+	0x16,0x38,0xc4,0x6f,0x3b,0x0f,0x65,0x46,
+	0xbe,0x7e,0x2d,0x7b,0x82,0xf9,0x40,0xb5,
+	0x1d,0x73,0xf8,0xeb,0x26,0xc7,0x87,0x97,
+	0x25,0x54,0xb1,0x28,0xaa,0x98,0x9d,0xa5,
+	0x64,0x6d,0x7a,0xd4,0x10,0x81,0x44,0xef,
+	0x49,0xd6,0xae,0x2e,0xdd,0x76,0x5c,0x2f,
+	0xa7,0x1c,0xc9,0x09,0x69,0x9a,0x83,0xcf,
+	0x29,0x39,0xb9,0xe9,0x4c,0xff,0x43,0xab,
+	};
+
+unsigned char num_to_ebits[256]={
+	0x5d,0xbe,0x9b,0x8b,0x11,0x99,0x6e,0x4d,
+	0x59,0xf3,0x85,0xa6,0x3f,0xb7,0x83,0xc5,
+	0xe4,0x73,0x6b,0x3a,0x68,0x5a,0xc0,0x47,
+	0xa0,0x64,0x34,0x0c,0xf1,0xd0,0x52,0xa5,
+	0xb9,0x1e,0x96,0x43,0x41,0xd8,0xd4,0x2c,
+	0xdb,0xf8,0x07,0x77,0x2a,0xca,0xeb,0xef,
+	0x10,0x1c,0x16,0x0d,0x38,0x72,0x2f,0x89,
+	0xc1,0xf9,0x80,0xc4,0x6d,0xae,0x30,0x3d,
+	0xce,0x20,0x63,0xfe,0xe6,0x1a,0xc7,0xb8,
+	0x50,0xe8,0x24,0x17,0xfc,0x25,0x6f,0xbb,
+	0x6a,0xa3,0x44,0x53,0xd9,0xa2,0x01,0xab,
+	0xbc,0xb6,0x1f,0x98,0xee,0x9a,0xa7,0x2d,
+	0x4f,0x9e,0x8e,0xac,0xe0,0xc6,0x49,0x46,
+	0x29,0xf4,0x94,0x8a,0xaf,0xe1,0x5b,0xc3,
+	0xb3,0x7b,0x57,0xd1,0x7c,0x9c,0xed,0x87,
+	0x40,0x8c,0xe2,0xcb,0x93,0x14,0xc9,0x61,
+	0x2e,0xe5,0xcc,0xf6,0x5e,0xa8,0x5c,0xd6,
+	0x75,0x8d,0x62,0x95,0x58,0x69,0x76,0xa1,
+	0x4a,0xb5,0x55,0x09,0x78,0x33,0x82,0xd7,
+	0xdd,0x79,0xf5,0x1b,0x0b,0xde,0x26,0x21,
+	0x28,0x74,0x04,0x97,0x56,0xdf,0x3c,0xf0,
+	0x37,0x39,0xdc,0xff,0x06,0xa4,0xea,0x42,
+	0x08,0xda,0xb4,0x71,0xb0,0xcf,0x12,0x7a,
+	0x4e,0xfa,0x6c,0x1d,0x84,0x00,0xc8,0x7f,
+	0x91,0x45,0xaa,0x2b,0xc2,0xb1,0x8f,0xd5,
+	0xba,0xf2,0xad,0x19,0xb2,0x67,0x36,0xf7,
+	0x0f,0x0a,0x92,0x7d,0xe3,0x9d,0xe9,0x90,
+	0x3e,0x23,0x27,0x66,0x13,0xec,0x81,0x15,
+	0xbd,0x22,0xbf,0x9f,0x7e,0xa9,0x51,0x4b,
+	0x4c,0xfb,0x02,0xd3,0x70,0x86,0x31,0xe7,
+	0x3b,0x05,0x03,0x54,0x60,0x48,0x65,0x18,
+	0xd2,0xcd,0x5f,0x32,0x88,0x0e,0x35,0xfd,
+	};
+	
+main()
+	{
+	int i,j;
+
+	for (i=0; i<256; i++)
+		{
+		for (j=0; j<256; j++)
+			if (ebits_to_num[j] == i)
+				{
+				printf("0x%02x,",j);
+				break;
+				}
+		}
+	}
diff --git a/openssl/crypto/rc2/version b/openssl/crypto/rc2/version
new file mode 100644
index 0000000..6f89d59
--- /dev/null
+++ b/openssl/crypto/rc2/version
@@ -0,0 +1,22 @@
+1.1 23/08/96 - eay
+	Changed RC2_set_key() so it now takes another argument.  Many
+	thanks to Peter Gutmann <pgut01@cs.auckland.ac.nz> for the
+	clarification and origional specification of RC2.  BSAFE uses
+	this last parameter, 'bits'.  It the key is 128 bits, BSAFE
+	also sets this parameter to 128.  The old behaviour can be
+	duplicated by setting this parameter to 1024.
+
+1.0 08/04/96 - eay
+	First version of SSLeay with rc2.  This has been written from the spec
+	posted sci.crypt.  It is in this directory under rrc2.doc
+	I have no test values for any mode other than ecb, my wrappers for the
+	other modes should be ok since they are basically the same as
+	the ones taken from idea and des :-).  I have implemented them as
+	little-endian operators.
+	While rc2 is included because it is used with SSL, I don't know how
+	far I trust it.  It is about the same speed as IDEA and DES.
+	So if you are paranoid, used Tripple DES, else IDEA.  If RC2
+	does get used more, perhaps more people will look for weaknesses in
+	it.
+	
+
diff --git a/openssl/crypto/rc4/Makefile b/openssl/crypto/rc4/Makefile
new file mode 100644
index 0000000..264451a
--- /dev/null
+++ b/openssl/crypto/rc4/Makefile
@@ -0,0 +1,115 @@
+#
+# OpenSSL/crypto/rc4/Makefile
+#
+
+DIR=	rc4
+TOP=	../..
+CC=	cc
+CPP=    $(CC) -E
+INCLUDES=
+CFLAG=-g
+AR=		ar r
+
+RC4_ENC=rc4_enc.o rc4_skey.o
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+ASFLAGS= $(INCLUDES) $(ASFLAG)
+AFLAGS= $(ASFLAGS)
+
+GENERAL=Makefile
+TEST=rc4test.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=rc4_skey.c rc4_enc.c
+LIBOBJ=$(RC4_ENC)
+
+SRC= $(LIBSRC)
+
+EXHEADER= rc4.h
+HEADER=	$(EXHEADER) rc4_locl.h
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+rc4-586.s:	asm/rc4-586.pl ../perlasm/x86asm.pl
+	$(PERL) asm/rc4-586.pl $(PERLASM_SCHEME) $(CFLAGS) > $@
+
+rc4-x86_64.s: asm/rc4-x86_64.pl
+	$(PERL) asm/rc4-x86_64.pl $(PERLASM_SCHEME) > $@
+
+rc4-ia64.S: asm/rc4-ia64.pl
+	$(PERL) asm/rc4-ia64.pl $(CFLAGS) > $@
+
+rc4-s390x.s:	asm/rc4-s390x.pl
+	$(PERL) asm/rc4-s390x.pl > $@
+
+rc4-ia64.s: rc4-ia64.S
+	@case `awk '/^#define RC4_INT/{print$$NF}' $(TOP)/include/openssl/opensslconf.h` in \
+	int)	set -x; $(CC) $(CFLAGS) -DSZ=4 -E rc4-ia64.S > $@ ;; \
+	char)	set -x; $(CC) $(CFLAGS) -DSZ=1 -E rc4-ia64.S > $@ ;; \
+	*)	exit 1 ;; \
+	esac
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+rc4_enc.o: ../../e_os.h ../../include/openssl/bio.h
+rc4_enc.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rc4_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+rc4_enc.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+rc4_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rc4_enc.o: ../../include/openssl/rc4.h ../../include/openssl/safestack.h
+rc4_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rc4_enc.o: ../cryptlib.h rc4_enc.c rc4_locl.h
+rc4_skey.o: ../../e_os.h ../../include/openssl/bio.h
+rc4_skey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rc4_skey.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+rc4_skey.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+rc4_skey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rc4_skey.o: ../../include/openssl/rc4.h ../../include/openssl/safestack.h
+rc4_skey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rc4_skey.o: ../cryptlib.h rc4_locl.h rc4_skey.c
diff --git a/openssl/crypto/rc4/asm/rc4-586.pl b/openssl/crypto/rc4/asm/rc4-586.pl
new file mode 100644
index 0000000..38a44a7
--- /dev/null
+++ b/openssl/crypto/rc4/asm/rc4-586.pl
@@ -0,0 +1,270 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# [Re]written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# At some point it became apparent that the original SSLeay RC4
+# assembler implementation performs suboptimally on latest IA-32
+# microarchitectures. After re-tuning performance has changed as
+# following:
+#
+# Pentium	-10%
+# Pentium III	+12%
+# AMD		+50%(*)
+# P4		+250%(**)
+#
+# (*)	This number is actually a trade-off:-) It's possible to
+#	achieve	+72%, but at the cost of -48% off PIII performance.
+#	In other words code performing further 13% faster on AMD
+#	would perform almost 2 times slower on Intel PIII...
+#	For reference! This code delivers ~80% of rc4-amd64.pl
+#	performance on the same Opteron machine.
+# (**)	This number requires compressed key schedule set up by
+#	RC4_set_key [see commentary below for further details].
+#
+#					<appro@fy.chalmers.se>
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"rc4-586.pl");
+
+$xx="eax";
+$yy="ebx";
+$tx="ecx";
+$ty="edx";
+$inp="esi";
+$out="ebp";
+$dat="edi";
+
+sub RC4_loop {
+  my $i=shift;
+  my $func = ($i==0)?*mov:*or;
+
+	&add	(&LB($yy),&LB($tx));
+	&mov	($ty,&DWP(0,$dat,$yy,4));
+	&mov	(&DWP(0,$dat,$yy,4),$tx);
+	&mov	(&DWP(0,$dat,$xx,4),$ty);
+	&add	($ty,$tx);
+	&inc	(&LB($xx));
+	&and	($ty,0xff);
+	&ror	($out,8)	if ($i!=0);
+	if ($i<3) {
+	  &mov	($tx,&DWP(0,$dat,$xx,4));
+	} else {
+	  &mov	($tx,&wparam(3));	# reload [re-biased] out
+	}
+	&$func	($out,&DWP(0,$dat,$ty,4));
+}
+
+# void RC4(RC4_KEY *key,size_t len,const unsigned char *inp,unsigned char *out);
+&function_begin("RC4");
+	&mov	($dat,&wparam(0));	# load key schedule pointer
+	&mov	($ty, &wparam(1));	# load len
+	&mov	($inp,&wparam(2));	# load inp
+	&mov	($out,&wparam(3));	# load out
+
+	&xor	($xx,$xx);		# avoid partial register stalls
+	&xor	($yy,$yy);
+
+	&cmp	($ty,0);		# safety net
+	&je	(&label("abort"));
+
+	&mov	(&LB($xx),&BP(0,$dat));	# load key->x
+	&mov	(&LB($yy),&BP(4,$dat));	# load key->y
+	&add	($dat,8);
+
+	&lea	($tx,&DWP(0,$inp,$ty));
+	&sub	($out,$inp);		# re-bias out
+	&mov	(&wparam(1),$tx);	# save input+len
+
+	&inc	(&LB($xx));
+
+	# detect compressed key schedule...
+	&cmp	(&DWP(256,$dat),-1);
+	&je	(&label("RC4_CHAR"));
+
+	&mov	($tx,&DWP(0,$dat,$xx,4));
+
+	&and	($ty,-4);		# how many 4-byte chunks?
+	&jz	(&label("loop1"));
+
+	&lea	($ty,&DWP(-4,$inp,$ty));
+	&mov	(&wparam(2),$ty);	# save input+(len/4)*4-4
+	&mov	(&wparam(3),$out);	# $out as accumulator in this loop
+
+	&set_label("loop4",16);
+		for ($i=0;$i<4;$i++) { RC4_loop($i); }
+		&ror	($out,8);
+		&xor	($out,&DWP(0,$inp));
+		&cmp	($inp,&wparam(2));	# compare to input+(len/4)*4-4
+		&mov	(&DWP(0,$tx,$inp),$out);# $tx holds re-biased out here
+		&lea	($inp,&DWP(4,$inp));
+		&mov	($tx,&DWP(0,$dat,$xx,4));
+	&jb	(&label("loop4"));
+
+	&cmp	($inp,&wparam(1));	# compare to input+len
+	&je	(&label("done"));
+	&mov	($out,&wparam(3));	# restore $out
+
+	&set_label("loop1",16);
+		&add	(&LB($yy),&LB($tx));
+		&mov	($ty,&DWP(0,$dat,$yy,4));
+		&mov	(&DWP(0,$dat,$yy,4),$tx);
+		&mov	(&DWP(0,$dat,$xx,4),$ty);
+		&add	($ty,$tx);
+		&inc	(&LB($xx));
+		&and	($ty,0xff);
+		&mov	($ty,&DWP(0,$dat,$ty,4));
+		&xor	(&LB($ty),&BP(0,$inp));
+		&lea	($inp,&DWP(1,$inp));
+		&mov	($tx,&DWP(0,$dat,$xx,4));
+		&cmp	($inp,&wparam(1));	# compare to input+len
+		&mov	(&BP(-1,$out,$inp),&LB($ty));
+	&jb	(&label("loop1"));
+
+	&jmp	(&label("done"));
+
+# this is essentially Intel P4 specific codepath...
+&set_label("RC4_CHAR",16);
+	&movz	($tx,&BP(0,$dat,$xx));
+	# strangely enough unrolled loop performs over 20% slower...
+	&set_label("cloop1");
+		&add	(&LB($yy),&LB($tx));
+		&movz	($ty,&BP(0,$dat,$yy));
+		&mov	(&BP(0,$dat,$yy),&LB($tx));
+		&mov	(&BP(0,$dat,$xx),&LB($ty));
+		&add	(&LB($ty),&LB($tx));
+		&movz	($ty,&BP(0,$dat,$ty));
+		&add	(&LB($xx),1);
+		&xor	(&LB($ty),&BP(0,$inp));
+		&lea	($inp,&DWP(1,$inp));
+		&movz	($tx,&BP(0,$dat,$xx));
+		&cmp	($inp,&wparam(1));
+		&mov	(&BP(-1,$out,$inp),&LB($ty));
+	&jb	(&label("cloop1"));
+
+&set_label("done");
+	&dec	(&LB($xx));
+	&mov	(&BP(-4,$dat),&LB($yy));	# save key->y
+	&mov	(&BP(-8,$dat),&LB($xx));	# save key->x
+&set_label("abort");
+&function_end("RC4");
+
+########################################################################
+
+$inp="esi";
+$out="edi";
+$idi="ebp";
+$ido="ecx";
+$idx="edx";
+
+&external_label("OPENSSL_ia32cap_P");
+
+# void RC4_set_key(RC4_KEY *key,int len,const unsigned char *data);
+&function_begin("RC4_set_key");
+	&mov	($out,&wparam(0));		# load key
+	&mov	($idi,&wparam(1));		# load len
+	&mov	($inp,&wparam(2));		# load data
+	&picmeup($idx,"OPENSSL_ia32cap_P");
+
+	&lea	($out,&DWP(2*4,$out));		# &key->data
+	&lea	($inp,&DWP(0,$inp,$idi));	# $inp to point at the end
+	&neg	($idi);
+	&xor	("eax","eax");
+	&mov	(&DWP(-4,$out),$idi);		# borrow key->y
+
+	&bt	(&DWP(0,$idx),20);		# check for bit#20
+	&jc	(&label("c1stloop"));
+
+&set_label("w1stloop",16);
+	&mov	(&DWP(0,$out,"eax",4),"eax");	# key->data[i]=i;
+	&add	(&LB("eax"),1);			# i++;
+	&jnc	(&label("w1stloop"));
+
+	&xor	($ido,$ido);
+	&xor	($idx,$idx);
+
+&set_label("w2ndloop",16);
+	&mov	("eax",&DWP(0,$out,$ido,4));
+	&add	(&LB($idx),&BP(0,$inp,$idi));
+	&add	(&LB($idx),&LB("eax"));
+	&add	($idi,1);
+	&mov	("ebx",&DWP(0,$out,$idx,4));
+	&jnz	(&label("wnowrap"));
+	  &mov	($idi,&DWP(-4,$out));
+	&set_label("wnowrap");
+	&mov	(&DWP(0,$out,$idx,4),"eax");
+	&mov	(&DWP(0,$out,$ido,4),"ebx");
+	&add	(&LB($ido),1);
+	&jnc	(&label("w2ndloop"));
+&jmp	(&label("exit"));
+
+# Unlike all other x86 [and x86_64] implementations, Intel P4 core
+# [including EM64T] was found to perform poorly with above "32-bit" key
+# schedule, a.k.a. RC4_INT. Performance improvement for IA-32 hand-coded
+# assembler turned out to be 3.5x if re-coded for compressed 8-bit one,
+# a.k.a. RC4_CHAR! It's however inappropriate to just switch to 8-bit
+# schedule for x86[_64], because non-P4 implementations suffer from
+# significant performance losses then, e.g. PIII exhibits >2x
+# deterioration, and so does Opteron. In order to assure optimal
+# all-round performance, we detect P4 at run-time and set up compressed
+# key schedule, which is recognized by RC4 procedure.
+
+&set_label("c1stloop",16);
+	&mov	(&BP(0,$out,"eax"),&LB("eax"));	# key->data[i]=i;
+	&add	(&LB("eax"),1);			# i++;
+	&jnc	(&label("c1stloop"));
+
+	&xor	($ido,$ido);
+	&xor	($idx,$idx);
+	&xor	("ebx","ebx");
+
+&set_label("c2ndloop",16);
+	&mov	(&LB("eax"),&BP(0,$out,$ido));
+	&add	(&LB($idx),&BP(0,$inp,$idi));
+	&add	(&LB($idx),&LB("eax"));
+	&add	($idi,1);
+	&mov	(&LB("ebx"),&BP(0,$out,$idx));
+	&jnz	(&label("cnowrap"));
+	  &mov	($idi,&DWP(-4,$out));
+	&set_label("cnowrap");
+	&mov	(&BP(0,$out,$idx),&LB("eax"));
+	&mov	(&BP(0,$out,$ido),&LB("ebx"));
+	&add	(&LB($ido),1);
+	&jnc	(&label("c2ndloop"));
+
+	&mov	(&DWP(256,$out),-1);		# mark schedule as compressed
+
+&set_label("exit");
+	&xor	("eax","eax");
+	&mov	(&DWP(-8,$out),"eax");		# key->x=0;
+	&mov	(&DWP(-4,$out),"eax");		# key->y=0;
+&function_end("RC4_set_key");
+
+# const char *RC4_options(void);
+&function_begin_B("RC4_options");
+	&call	(&label("pic_point"));
+&set_label("pic_point");
+	&blindpop("eax");
+	&lea	("eax",&DWP(&label("opts")."-".&label("pic_point"),"eax"));
+	&picmeup("edx","OPENSSL_ia32cap_P");
+	&bt	(&DWP(0,"edx"),20);
+	&jnc	(&label("skip"));
+	  &add	("eax",12);
+	&set_label("skip");
+	&ret	();
+&set_label("opts",64);
+&asciz	("rc4(4x,int)");
+&asciz	("rc4(1x,char)");
+&asciz	("RC4 for x86, CRYPTOGAMS by <appro\@openssl.org>");
+&align	(64);
+&function_end_B("RC4_options");
+
+&asm_finish();
+
diff --git a/openssl/crypto/rc4/asm/rc4-ia64.pl b/openssl/crypto/rc4/asm/rc4-ia64.pl
new file mode 100644
index 0000000..49cd5b5
--- /dev/null
+++ b/openssl/crypto/rc4/asm/rc4-ia64.pl
@@ -0,0 +1,755 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by David Mosberger <David.Mosberger@acm.org> based on the
+# Itanium optimized Crypto code which was released by HP Labs at
+# http://www.hpl.hp.com/research/linux/crypto/.
+#
+# Copyright (c) 2005 Hewlett-Packard Development Company, L.P.
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+
+
+# This is a little helper program which generates a software-pipelined
+# for RC4 encryption.  The basic algorithm looks like this:
+#
+#   for (counter = 0; counter < len; ++counter)
+#     {
+#       in = inp[counter];
+#       SI = S[I];
+#       J = (SI + J) & 0xff;
+#       SJ = S[J];
+#       T = (SI + SJ) & 0xff;
+#       S[I] = SJ, S[J] = SI;
+#       ST = S[T];
+#       outp[counter] = in ^ ST;
+#       I = (I + 1) & 0xff;
+#     }
+#
+# Pipelining this loop isn't easy, because the stores to the S[] array
+# need to be observed in the right order.  The loop generated by the
+# code below has the following pipeline diagram:
+#
+#      cycle
+#     | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12 |13 |14 |15 |16 |17 |
+# iter
+#   1: xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx
+#   2:             xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx
+#   3:                         xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx
+#
+#   where:
+# 	LDI = load of S[I]
+# 	LDJ = load of S[J]
+# 	SWP = swap of S[I] and S[J]
+# 	LDT = load of S[T]
+#
+# Note that in the above diagram, the major trouble-spot is that LDI
+# of the 2nd iteration is performed BEFORE the SWP of the first
+# iteration.  Fortunately, this is easy to detect (I of the 1st
+# iteration will be equal to J of the 2nd iteration) and when this
+# happens, we simply forward the proper value from the 1st iteration
+# to the 2nd one.  The proper value in this case is simply the value
+# of S[I] from the first iteration (thanks to the fact that SWP
+# simply swaps the contents of S[I] and S[J]).
+#
+# Another potential trouble-spot is in cycle 7, where SWP of the 1st
+# iteration issues at the same time as the LDI of the 3rd iteration.
+# However, thanks to IA-64 execution semantics, this can be taken
+# care of simply by placing LDI later in the instruction-group than
+# SWP.  IA-64 CPUs will automatically forward the value if they
+# detect that the SWP and LDI are accessing the same memory-location.
+
+# The core-loop that can be pipelined then looks like this (annotated
+# with McKinley/Madison issue port & latency numbers, assuming L1
+# cache hits for the most part):
+
+# operation:	    instruction:		    issue-ports:  latency
+# ------------------  -----------------------------   ------------- -------
+
+# Data = *inp++       ld1 data = [inp], 1             M0-M1         1 cyc     c0
+#                     shladd Iptr = I, KeyTable, 3    M0-M3, I0, I1 1 cyc
+# I = (I + 1) & 0xff  padd1 nextI = I, one            M0-M3, I0, I1 3 cyc
+#                     ;;
+# SI = S[I]           ld8 SI = [Iptr]                 M0-M1         1 cyc     c1 * after SWAP!
+#                     ;;
+#                     cmp.eq.unc pBypass = I, J                                  * after J is valid!
+# J = SI + J          add J = J, SI                   M0-M3, I0, I1 1 cyc     c2
+#                     (pBypass) br.cond.spnt Bypass
+#                     ;;
+# ---------------------------------------------------------------------------------------
+# J = J & 0xff        zxt1 J = J                      I0, I1, 1 cyc           c3
+#                     ;;
+#                     shladd Jptr = J, KeyTable, 3    M0-M3, I0, I1 1 cyc     c4
+#                     ;;
+# SJ = S[J]           ld8 SJ = [Jptr]                 M0-M1         1 cyc     c5
+#                     ;;
+# ---------------------------------------------------------------------------------------
+# T = (SI + SJ)       add T = SI, SJ                  M0-M3, I0, I1 1 cyc     c6
+#                     ;;
+# T = T & 0xff        zxt1 T = T                      I0, I1        1 cyc
+# S[I] = SJ           st8 [Iptr] = SJ                 M2-M3                   c7
+# S[J] = SI           st8 [Jptr] = SI                 M2-M3
+#                     ;;
+#                     shladd Tptr = T, KeyTable, 3    M0-M3, I0, I1 1 cyc     c8
+#                     ;;
+# ---------------------------------------------------------------------------------------
+# T = S[T]            ld8 T = [Tptr]                  M0-M1         1 cyc     c9
+#                     ;;
+# data ^= T           xor data = data, T              M0-M3, I0, I1 1 cyc     c10
+#                     ;;
+# *out++ = Data ^ T   dep word = word, data, 8, POS   I0, I1        1 cyc     c11
+#                     ;;
+# ---------------------------------------------------------------------------------------
+
+# There are several points worth making here:
+
+#   - Note that due to the bypass/forwarding-path, the first two
+#     phases of the loop are strangly mingled together.  In
+#     particular, note that the first stage of the pipeline is
+#     using the value of "J", as calculated by the second stage.
+#   - Each bundle-pair will have exactly 6 instructions.
+#   - Pipelined, the loop can execute in 3 cycles/iteration and
+#     4 stages.  However, McKinley/Madison can issue "st1" to
+#     the same bank at a rate of at most one per 4 cycles.  Thus,
+#     instead of storing each byte, we accumulate them in a word
+#     and then write them back at once with a single "st8" (this
+#     implies that the setup code needs to ensure that the output
+#     buffer is properly aligned, if need be, by encoding the
+#     first few bytes separately).
+#   - There is no space for a "br.ctop" instruction.  For this
+#     reason we can't use module-loop support in IA-64 and have
+#     to do a traditional, purely software-pipelined loop.
+#   - We can't replace any of the remaining "add/zxt1" pairs with
+#     "padd1" because the latency for that instruction is too high
+#     and would push the loop to the point where more bypasses
+#     would be needed, which we don't have space for.
+#   - The above loop runs at around 3.26 cycles/byte, or roughly
+#     440 MByte/sec on a 1.5GHz Madison.  This is well below the
+#     system bus bandwidth and hence with judicious use of
+#     "lfetch" this loop can run at (almost) peak speed even when
+#     the input and output data reside in memory.  The
+#     max. latency that can be tolerated is (PREFETCH_DISTANCE *
+#     L2_LINE_SIZE * 3 cyc), or about 384 cycles assuming (at
+#     least) 1-ahead prefetching of 128 byte cache-lines.  Note
+#     that we do NOT prefetch into L1, since that would only
+#     interfere with the S[] table values stored there.  This is
+#     acceptable because there is a 10 cycle latency between
+#     load and first use of the input data.
+#   - We use a branch to out-of-line bypass-code of cycle-pressure:
+#     we calculate the next J, check for the need to activate the
+#     bypass path, and activate the bypass path ALL IN THE SAME
+#     CYCLE.  If we didn't have these constraints, we could do
+#     the bypass with a simple conditional move instruction.
+#     Fortunately, the bypass paths get activated relatively
+#     infrequently, so the extra branches don't cost all that much
+#     (about 0.04 cycles/byte, measured on a 16396 byte file with
+#     random input data).
+#
+
+$phases = 4;		# number of stages/phases in the pipelined-loop
+$unroll_count = 6;	# number of times we unrolled it
+$pComI = (1 << 0);
+$pComJ = (1 << 1);
+$pComT = (1 << 2);
+$pOut  = (1 << 3);
+
+$NData = 4;
+$NIP = 3;
+$NJP = 2;
+$NI = 2;
+$NSI = 3;
+$NSJ = 2;
+$NT = 2;
+$NOutWord = 2;
+
+#
+# $threshold is the minimum length before we attempt to use the
+# big software-pipelined loop.  It MUST be greater-or-equal
+# to:
+#  		PHASES * (UNROLL_COUNT + 1) + 7
+#
+# The "+ 7" comes from the fact we may have to encode up to
+#   7 bytes separately before the output pointer is aligned.
+#
+$threshold = (3 * ($phases * ($unroll_count + 1)) + 7);
+
+sub I {
+    local *code = shift;
+    local $format = shift;
+    $code .= sprintf ("\t\t".$format."\n", @_);
+}
+
+sub P {
+    local *code = shift;
+    local $format = shift;
+    $code .= sprintf ($format."\n", @_);
+}
+
+sub STOP {
+    local *code = shift;
+    $code .=<<___;
+		;;
+___
+}
+
+sub emit_body {
+    local *c = shift;
+    local *bypass = shift;
+    local ($iteration, $p) = @_;
+
+    local $i0 = $iteration;
+    local $i1 = $iteration - 1;
+    local $i2 = $iteration - 2;
+    local $i3 = $iteration - 3;
+    local $iw0 = ($iteration - 3) / 8;
+    local $iw1 = ($iteration > 3) ? ($iteration - 4) / 8 : 1;
+    local $byte_num = ($iteration - 3) % 8;
+    local $label = $iteration + 1;
+    local $pAny = ($p & 0xf) == 0xf;
+    local $pByp = (($p & $pComI) && ($iteration > 0));
+
+    $c.=<<___;
+//////////////////////////////////////////////////
+___
+
+    if (($p & 0xf) == 0) {
+	$c.="#ifdef HOST_IS_BIG_ENDIAN\n";
+	&I(\$c,"shr.u	OutWord[%u] = OutWord[%u], 32;;",
+				$iw1 % $NOutWord, $iw1 % $NOutWord);
+	$c.="#endif\n";
+	&I(\$c, "st4 [OutPtr] = OutWord[%u], 4", $iw1 % $NOutWord);
+	return;
+    }
+
+    # Cycle 0
+    &I(\$c, "{ .mmi")					      if ($pAny);
+    &I(\$c, "ld1    Data[%u] = [InPtr], 1", $i0 % $NData)     if ($p & $pComI);
+    &I(\$c, "padd1  I[%u] = One, I[%u]", $i0 % $NI, $i1 % $NI)if ($p & $pComI);
+    &I(\$c, "zxt1   J = J")				      if ($p & $pComJ);
+    &I(\$c, "}")					      if ($pAny);
+    &I(\$c, "{ .mmi")					      if ($pAny);
+    &I(\$c, "LKEY   T[%u] = [T[%u]]", $i1 % $NT, $i1 % $NT)   if ($p & $pOut);
+    &I(\$c, "add    T[%u] = SI[%u], SJ[%u]",
+       $i0 % $NT, $i2 % $NSI, $i1 % $NSJ)		      if ($p & $pComT);
+    &I(\$c, "KEYADDR(IPr[%u], I[%u])", $i0 % $NIP, $i1 % $NI) if ($p & $pComI);
+    &I(\$c, "}")					      if ($pAny);
+    &STOP(\$c);
+
+    # Cycle 1
+    &I(\$c, "{ .mmi")					      if ($pAny);
+    &I(\$c, "SKEY   [IPr[%u]] = SJ[%u]", $i2 % $NIP, $i1%$NSJ)if ($p & $pComT);
+    &I(\$c, "SKEY   [JP[%u]] = SI[%u]", $i1 % $NJP, $i2%$NSI) if ($p & $pComT);
+    &I(\$c, "zxt1   T[%u] = T[%u]", $i0 % $NT, $i0 % $NT)     if ($p & $pComT);
+    &I(\$c, "}")					      if ($pAny);
+    &I(\$c, "{ .mmi")					      if ($pAny);
+    &I(\$c, "LKEY   SI[%u] = [IPr[%u]]", $i0 % $NSI, $i0%$NIP)if ($p & $pComI);
+    &I(\$c, "KEYADDR(JP[%u], J)", $i0 % $NJP)		      if ($p & $pComJ);
+    &I(\$c, "xor    Data[%u] = Data[%u], T[%u]",
+       $i3 % $NData, $i3 % $NData, $i1 % $NT)		      if ($p & $pOut);
+    &I(\$c, "}")					      if ($pAny);
+    &STOP(\$c);
+
+    # Cycle 2
+    &I(\$c, "{ .mmi")					      if ($pAny);
+    &I(\$c, "LKEY   SJ[%u] = [JP[%u]]", $i0 % $NSJ, $i0%$NJP) if ($p & $pComJ);
+    &I(\$c, "cmp.eq pBypass, p0 = I[%u], J", $i1 % $NI)	      if ($pByp);
+    &I(\$c, "dep OutWord[%u] = Data[%u], OutWord[%u], BYTE_POS(%u), 8",
+       $iw0%$NOutWord, $i3%$NData, $iw1%$NOutWord, $byte_num) if ($p & $pOut);
+    &I(\$c, "}")					      if ($pAny);
+    &I(\$c, "{ .mmb")					      if ($pAny);
+    &I(\$c, "add    J = J, SI[%u]", $i0 % $NSI)		      if ($p & $pComI);
+    &I(\$c, "KEYADDR(T[%u], T[%u])", $i0 % $NT, $i0 % $NT)    if ($p & $pComT);
+    &P(\$c, "(pBypass)\tbr.cond.spnt.many .rc4Bypass%u",$label)if ($pByp);
+    &I(\$c, "}") if ($pAny);
+    &STOP(\$c);
+
+    &P(\$c, ".rc4Resume%u:", $label)			      if ($pByp);
+    if ($byte_num == 0 && $iteration >= $phases) {
+	&I(\$c, "st8 [OutPtr] = OutWord[%u], 8",
+	   $iw1 % $NOutWord)				      if ($p & $pOut);
+	if ($iteration == (1 + $unroll_count) * $phases - 1) {
+	    if ($unroll_count == 6) {
+		&I(\$c, "mov OutWord[%u] = OutWord[%u]",
+		   $iw1 % $NOutWord, $iw0 % $NOutWord);
+	    }
+	    &I(\$c, "lfetch.nt1 [InPrefetch], %u",
+	       $unroll_count * $phases);
+	    &I(\$c, "lfetch.excl.nt1 [OutPrefetch], %u",
+	       $unroll_count * $phases);
+	    &I(\$c, "br.cloop.sptk.few .rc4Loop");
+	}
+    }
+
+    if ($pByp) {
+	&P(\$bypass, ".rc4Bypass%u:", $label);
+	&I(\$bypass, "sub J = J, SI[%u]", $i0 % $NSI);
+	&I(\$bypass, "nop 0");
+	&I(\$bypass, "nop 0");
+	&I(\$bypass, ";;");
+	&I(\$bypass, "add J = J, SI[%u]", $i1 % $NSI);
+	&I(\$bypass, "mov SI[%u] = SI[%u]", $i0 % $NSI, $i1 % $NSI);
+	&I(\$bypass, "br.sptk.many .rc4Resume%u\n", $label);
+	&I(\$bypass, ";;");
+    }
+}
+
+$code=<<___;
+.ident \"rc4-ia64.s, version 3.0\"
+.ident \"Copyright (c) 2005 Hewlett-Packard Development Company, L.P.\"
+
+#define LCSave		r8
+#define PRSave		r9
+
+/* Inputs become invalid once rotation begins!  */
+
+#define StateTable	in0
+#define DataLen		in1
+#define InputBuffer	in2
+#define OutputBuffer	in3
+
+#define KTable		r14
+#define J		r15
+#define InPtr		r16
+#define OutPtr		r17
+#define InPrefetch	r18
+#define OutPrefetch	r19
+#define One		r20
+#define LoopCount	r21
+#define Remainder	r22
+#define IFinal		r23
+#define EndPtr		r24
+
+#define tmp0		r25
+#define tmp1		r26
+
+#define pBypass		p6
+#define pDone		p7
+#define pSmall		p8
+#define pAligned	p9
+#define pUnaligned	p10
+
+#define pComputeI	pPhase[0]
+#define pComputeJ	pPhase[1]
+#define pComputeT	pPhase[2]
+#define pOutput		pPhase[3]
+
+#define RetVal		r8
+#define L_OK		p7
+#define L_NOK		p8
+
+#define	_NINPUTS	4
+#define	_NOUTPUT	0
+
+#define	_NROTATE	24
+#define	_NLOCALS	(_NROTATE - _NINPUTS - _NOUTPUT)
+
+#ifndef SZ
+# define SZ	4	// this must be set to sizeof(RC4_INT)
+#endif
+
+#if SZ == 1
+# define LKEY			ld1
+# define SKEY			st1
+# define KEYADDR(dst, i)	add dst = i, KTable
+#elif SZ == 2
+# define LKEY			ld2
+# define SKEY			st2
+# define KEYADDR(dst, i)	shladd dst = i, 1, KTable
+#elif SZ == 4
+# define LKEY			ld4
+# define SKEY			st4
+# define KEYADDR(dst, i)	shladd dst = i, 2, KTable
+#else
+# define LKEY			ld8
+# define SKEY			st8
+# define KEYADDR(dst, i)	shladd dst = i, 3, KTable
+#endif
+
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+# define ADDP	addp4
+#else
+# define ADDP	add
+#endif
+
+/* Define a macro for the bit number of the n-th byte: */
+
+#if defined(_HPUX_SOURCE) || defined(B_ENDIAN)
+# define HOST_IS_BIG_ENDIAN
+# define BYTE_POS(n)	(56 - (8 * (n)))
+#else
+# define BYTE_POS(n)	(8 * (n))
+#endif
+
+/*
+   We must perform the first phase of the pipeline explicitly since
+   we will always load from the stable the first time. The br.cexit
+   will never be taken since regardless of the number of bytes because
+   the epilogue count is 4.
+*/
+/* MODSCHED_RC4 macro was split to _PROLOGUE and _LOOP, because HP-UX
+   assembler failed on original macro with syntax error. <appro> */
+#define MODSCHED_RC4_PROLOGUE						   \\
+	{								   \\
+				ld1		Data[0] = [InPtr], 1;	   \\
+				add		IFinal = 1, I[1];	   \\
+				KEYADDR(IPr[0], I[1]);			   \\
+	} ;;								   \\
+	{								   \\
+				LKEY		SI[0] = [IPr[0]];	   \\
+				mov		pr.rot = 0x10000;	   \\
+				mov		ar.ec = 4;		   \\
+	} ;;								   \\
+	{								   \\
+				add		J = J, SI[0];		   \\
+				zxt1		I[0] = IFinal;		   \\
+				br.cexit.spnt.few .+16; /* never taken */  \\
+	} ;;
+#define MODSCHED_RC4_LOOP(label)					   \\
+label:									   \\
+	{	.mmi;							   \\
+		(pComputeI)	ld1		Data[0] = [InPtr], 1;	   \\
+		(pComputeI)	add		IFinal = 1, I[1];	   \\
+		(pComputeJ)	zxt1		J = J;			   \\
+	}{	.mmi;							   \\
+		(pOutput)	LKEY		T[1] = [T[1]];		   \\
+		(pComputeT)	add		T[0] = SI[2], SJ[1];	   \\
+		(pComputeI)	KEYADDR(IPr[0], I[1]);			   \\
+	} ;;								   \\
+	{	.mmi;							   \\
+		(pComputeT)	SKEY		[IPr[2]] = SJ[1];	   \\
+		(pComputeT)	SKEY		[JP[1]] = SI[2];	   \\
+		(pComputeT)	zxt1		T[0] = T[0];		   \\
+	}{	.mmi;							   \\
+		(pComputeI)	LKEY		SI[0] = [IPr[0]];	   \\
+		(pComputeJ)	KEYADDR(JP[0], J);			   \\
+		(pComputeI)	cmp.eq.unc	pBypass, p0 = I[1], J;	   \\
+	} ;;								   \\
+	{	.mmi;							   \\
+		(pComputeJ)	LKEY		SJ[0] = [JP[0]];	   \\
+		(pOutput)	xor		Data[3] = Data[3], T[1];   \\
+				nop		0x0;			   \\
+	}{	.mmi;							   \\
+		(pComputeT)	KEYADDR(T[0], T[0]);			   \\
+		(pBypass)	mov		SI[0] = SI[1];		   \\
+		(pComputeI)	zxt1		I[0] = IFinal;		   \\
+	} ;;								   \\
+	{	.mmb;							   \\
+		(pOutput)	st1		[OutPtr] = Data[3], 1;	   \\
+		(pComputeI)	add		J = J, SI[0];		   \\
+				br.ctop.sptk.few label;			   \\
+	} ;;
+
+	.text
+
+	.align	32
+
+	.type	RC4, \@function
+	.global	RC4
+
+	.proc	RC4
+	.prologue
+
+RC4:
+	{
+	  	.mmi
+		alloc	r2 = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE
+
+		.rotr Data[4], I[2], IPr[3], SI[3], JP[2], SJ[2], T[2], \\
+		      OutWord[2]
+		.rotp pPhase[4]
+
+		ADDP		InPrefetch = 0, InputBuffer
+		ADDP		KTable = 0, StateTable
+	}
+	{
+		.mmi
+		ADDP		InPtr = 0, InputBuffer
+		ADDP		OutPtr = 0, OutputBuffer
+		mov		RetVal = r0
+	}
+	;;
+	{
+		.mmi
+		lfetch.nt1	[InPrefetch], 0x80
+		ADDP		OutPrefetch = 0, OutputBuffer
+	}
+	{               // Return 0 if the input length is nonsensical
+        	.mib
+		ADDP		StateTable = 0, StateTable
+        	cmp.ge.unc  	L_NOK, L_OK = r0, DataLen
+	(L_NOK) br.ret.sptk.few rp
+	}
+	;;
+	{
+        	.mib
+        	cmp.eq.or  	L_NOK, L_OK = r0, InPtr
+        	cmp.eq.or  	L_NOK, L_OK = r0, OutPtr
+		nop		0x0
+	}
+	{
+		.mib
+        	cmp.eq.or  	L_NOK, L_OK = r0, StateTable
+		nop		0x0
+	(L_NOK) br.ret.sptk.few rp
+	}
+	;;
+		LKEY		I[1] = [KTable], SZ
+/* Prefetch the state-table. It contains 256 elements of size SZ */
+
+#if SZ == 1
+		ADDP		tmp0 = 1*128, StateTable
+#elif SZ == 2
+		ADDP		tmp0 = 3*128, StateTable
+		ADDP		tmp1 = 2*128, StateTable
+#elif SZ == 4
+		ADDP		tmp0 = 7*128, StateTable
+		ADDP		tmp1 = 6*128, StateTable
+#elif SZ == 8
+		ADDP		tmp0 = 15*128, StateTable
+		ADDP		tmp1 = 14*128, StateTable
+#endif
+		;;
+#if SZ >= 8
+		lfetch.fault.nt1		[tmp0], -256	// 15
+		lfetch.fault.nt1		[tmp1], -256;;
+		lfetch.fault.nt1		[tmp0], -256	// 13
+		lfetch.fault.nt1		[tmp1], -256;;
+		lfetch.fault.nt1		[tmp0], -256	// 11
+		lfetch.fault.nt1		[tmp1], -256;;
+		lfetch.fault.nt1		[tmp0], -256	//  9
+		lfetch.fault.nt1		[tmp1], -256;;
+#endif
+#if SZ >= 4
+		lfetch.fault.nt1		[tmp0], -256	//  7
+		lfetch.fault.nt1		[tmp1], -256;;
+		lfetch.fault.nt1		[tmp0], -256	//  5
+		lfetch.fault.nt1		[tmp1], -256;;
+#endif
+#if SZ >= 2
+		lfetch.fault.nt1		[tmp0], -256	//  3
+		lfetch.fault.nt1		[tmp1], -256;;
+#endif
+	{
+		.mii
+		lfetch.fault.nt1		[tmp0]		//  1
+		add		I[1]=1,I[1];;
+		zxt1		I[1]=I[1]
+	}
+	{
+		.mmi
+		lfetch.nt1	[InPrefetch], 0x80
+		lfetch.excl.nt1	[OutPrefetch], 0x80
+		.save		pr, PRSave
+		mov		PRSave = pr
+	} ;;
+	{
+		.mmi
+		lfetch.excl.nt1	[OutPrefetch], 0x80
+		LKEY		J = [KTable], SZ
+		ADDP		EndPtr = DataLen, InPtr
+	}  ;;
+	{
+		.mmi
+		ADDP		EndPtr = -1, EndPtr	// Make it point to
+							// last data byte.
+		mov		One = 1
+		.save		ar.lc, LCSave
+		mov		LCSave = ar.lc
+		.body
+	} ;;
+	{
+		.mmb
+		sub		Remainder = 0, OutPtr
+		cmp.gtu		pSmall, p0 = $threshold, DataLen
+(pSmall)	br.cond.dpnt	.rc4Remainder		// Data too small for
+							// big loop.
+	} ;;
+	{
+		.mmi
+		and		Remainder = 0x7, Remainder
+		;;
+		cmp.eq		pAligned, pUnaligned = Remainder, r0
+		nop		0x0
+	} ;;
+	{
+		.mmb
+.pred.rel	"mutex",pUnaligned,pAligned
+(pUnaligned)	add		Remainder = -1, Remainder
+(pAligned)	sub		Remainder = EndPtr, InPtr
+(pAligned)	br.cond.dptk.many .rc4Aligned
+	} ;;
+	{
+		.mmi
+		nop		0x0
+		nop		0x0
+		mov.i		ar.lc = Remainder
+	}
+
+/* Do the initial few bytes via the compact, modulo-scheduled loop
+   until the output pointer is 8-byte-aligned.  */
+
+		MODSCHED_RC4_PROLOGUE
+		MODSCHED_RC4_LOOP(.RC4AlignLoop)
+
+	{
+		.mib
+		sub		Remainder = EndPtr, InPtr
+		zxt1		IFinal = IFinal
+		clrrrb				// Clear CFM.rrb.pr so
+		;;				// next "mov pr.rot = N"
+						// does the right thing.
+	}
+	{
+		.mmi
+		mov		I[1] = IFinal
+		nop		0x0
+		nop		0x0
+	} ;;
+
+
+.rc4Aligned:
+
+/*
+   Unrolled loop count = (Remainder - ($unroll_count+1)*$phases)/($unroll_count*$phases)
+ */
+
+	{
+		.mlx
+		add	LoopCount = 1 - ($unroll_count + 1)*$phases, Remainder
+		movl		Remainder = 0xaaaaaaaaaaaaaaab
+	} ;;
+	{
+		.mmi
+		setf.sig	f6 = LoopCount		// M2, M3	6 cyc
+		setf.sig	f7 = Remainder		// M2, M3	6 cyc
+		nop		0x0
+	} ;;
+	{
+		.mfb
+		nop		0x0
+		xmpy.hu		f6 = f6, f7
+		nop		0x0
+	} ;;
+	{
+		.mmi
+		getf.sig	LoopCount = f6;;	// M2		5 cyc
+		nop		0x0
+		shr.u		LoopCount = LoopCount, 4
+	} ;;
+	{
+		.mmi
+		nop		0x0
+		nop		0x0
+		mov.i		ar.lc = LoopCount
+	} ;;
+
+/* Now comes the unrolled loop: */
+
+.rc4Prologue:
+___
+
+$iteration = 0;
+
+# Generate the prologue:
+$predicates = 1;
+for ($i = 0; $i < $phases; ++$i) {
+    &emit_body (\$code, \$bypass, $iteration++, $predicates);
+    $predicates = ($predicates << 1) | 1;
+}
+
+$code.=<<___;
+.rc4Loop:
+___
+
+# Generate the body:
+for ($i = 0; $i < $unroll_count*$phases; ++$i) {
+    &emit_body (\$code, \$bypass, $iteration++, $predicates);
+}
+
+$code.=<<___;
+.rc4Epilogue:
+___
+
+# Generate the epilogue:
+for ($i = 0; $i < $phases; ++$i) {
+    $predicates <<= 1;
+    &emit_body (\$code, \$bypass, $iteration++, $predicates);
+}
+
+$code.=<<___;
+	{
+		.mmi
+		lfetch.nt1	[EndPtr]	// fetch line with last byte
+		mov		IFinal = I[1]
+		nop		0x0
+	}
+
+.rc4Remainder:
+	{
+		.mmi
+		sub		Remainder = EndPtr, InPtr	// Calculate
+								// # of bytes
+								// left - 1
+		nop		0x0
+		nop		0x0
+	} ;;
+	{
+		.mib
+		cmp.eq		pDone, p0 = -1, Remainder // done already?
+		mov.i		ar.lc = Remainder
+(pDone)		br.cond.dptk.few .rc4Complete
+	}
+
+/* Do the remaining bytes via the compact, modulo-scheduled loop */
+
+		MODSCHED_RC4_PROLOGUE
+		MODSCHED_RC4_LOOP(.RC4RestLoop)
+
+.rc4Complete:
+	{
+		.mmi
+		add		KTable = -SZ, KTable
+		add		IFinal = -1, IFinal
+		mov		ar.lc = LCSave
+	} ;;
+	{
+		.mii
+		SKEY		[KTable] = J,-SZ
+		zxt1		IFinal = IFinal
+		mov		pr = PRSave, 0x1FFFF
+	} ;;
+	{
+		.mib
+		SKEY		[KTable] = IFinal
+		add		RetVal = 1, r0
+		br.ret.sptk.few	rp
+	} ;;
+___
+
+# Last but not least, emit the code for the bypass-code of the unrolled loop:
+
+$code.=$bypass;
+
+$code.=<<___;
+	.endp RC4
+___
+
+print $code;
diff --git a/openssl/crypto/rc4/asm/rc4-s390x.pl b/openssl/crypto/rc4/asm/rc4-s390x.pl
new file mode 100644
index 0000000..96681fa
--- /dev/null
+++ b/openssl/crypto/rc4/asm/rc4-s390x.pl
@@ -0,0 +1,205 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# February 2009
+#
+# Performance is 2x of gcc 3.4.6 on z10. Coding "secret" is to
+# "cluster" Address Generation Interlocks, so that one pipeline stall
+# resolves several dependencies.
+
+$rp="%r14";
+$sp="%r15";
+$code=<<___;
+.text
+
+___
+
+# void RC4(RC4_KEY *key,size_t len,const void *inp,void *out)
+{
+$acc="%r0";
+$cnt="%r1";
+$key="%r2";
+$len="%r3";
+$inp="%r4";
+$out="%r5";
+
+@XX=("%r6","%r7");
+@TX=("%r8","%r9");
+$YY="%r10";
+$TY="%r11";
+
+$code.=<<___;
+.globl	RC4
+.type	RC4,\@function
+.align	64
+RC4:
+	stmg	%r6,%r11,48($sp)
+	llgc	$XX[0],0($key)
+	llgc	$YY,1($key)
+	la	$XX[0],1($XX[0])
+	nill	$XX[0],0xff
+	srlg	$cnt,$len,3
+	ltgr	$cnt,$cnt
+	llgc	$TX[0],2($XX[0],$key)
+	jz	.Lshort
+	j	.Loop8
+
+.align	64
+.Loop8:
+___
+for ($i=0;$i<8;$i++) {
+$code.=<<___;
+	la	$YY,0($YY,$TX[0])	# $i
+	nill	$YY,255
+	la	$XX[1],1($XX[0])
+	nill	$XX[1],255
+___
+$code.=<<___ if ($i==1);
+	llgc	$acc,2($TY,$key)
+___
+$code.=<<___ if ($i>1);
+	sllg	$acc,$acc,8
+	ic	$acc,2($TY,$key)
+___
+$code.=<<___;
+	llgc	$TY,2($YY,$key)
+	stc	$TX[0],2($YY,$key)
+	llgc	$TX[1],2($XX[1],$key)
+	stc	$TY,2($XX[0],$key)
+	cr	$XX[1],$YY
+	jne	.Lcmov$i
+	la	$TX[1],0($TX[0])
+.Lcmov$i:
+	la	$TY,0($TY,$TX[0])
+	nill	$TY,255
+___
+push(@TX,shift(@TX)); push(@XX,shift(@XX));     # "rotate" registers
+}
+
+$code.=<<___;
+	lg	$TX[1],0($inp)
+	sllg	$acc,$acc,8
+	la	$inp,8($inp)
+	ic	$acc,2($TY,$key)
+	xgr	$acc,$TX[1]
+	stg	$acc,0($out)
+	la	$out,8($out)
+	brct	$cnt,.Loop8
+
+.Lshort:
+	lghi	$acc,7
+	ngr	$len,$acc
+	jz	.Lexit
+	j	.Loop1
+
+.align	16
+.Loop1:
+	la	$YY,0($YY,$TX[0])
+	nill	$YY,255
+	llgc	$TY,2($YY,$key)
+	stc	$TX[0],2($YY,$key)
+	stc	$TY,2($XX[0],$key)
+	ar	$TY,$TX[0]
+	ahi	$XX[0],1
+	nill	$TY,255
+	nill	$XX[0],255
+	llgc	$acc,0($inp)
+	la	$inp,1($inp)
+	llgc	$TY,2($TY,$key)
+	llgc	$TX[0],2($XX[0],$key)
+	xr	$acc,$TY
+	stc	$acc,0($out)
+	la	$out,1($out)
+	brct	$len,.Loop1
+
+.Lexit:
+	ahi	$XX[0],-1
+	stc	$XX[0],0($key)
+	stc	$YY,1($key)
+	lmg	%r6,%r11,48($sp)
+	br	$rp
+.size	RC4,.-RC4
+.string	"RC4 for s390x, CRYPTOGAMS by <appro\@openssl.org>"
+
+___
+}
+
+# void RC4_set_key(RC4_KEY *key,unsigned int len,const void *inp)
+{
+$cnt="%r0";
+$idx="%r1";
+$key="%r2";
+$len="%r3";
+$inp="%r4";
+$acc="%r5";
+$dat="%r6";
+$ikey="%r7";
+$iinp="%r8";
+
+$code.=<<___;
+.globl	RC4_set_key
+.type	RC4_set_key,\@function
+.align	64
+RC4_set_key:
+	stmg	%r6,%r8,48($sp)
+	lhi	$cnt,256
+	la	$idx,0(%r0)
+	sth	$idx,0($key)
+.align	4
+.L1stloop:
+	stc	$idx,2($idx,$key)
+	la	$idx,1($idx)
+	brct	$cnt,.L1stloop
+
+	lghi	$ikey,-256
+	lr	$cnt,$len
+	la	$iinp,0(%r0)
+	la	$idx,0(%r0)
+.align	16
+.L2ndloop:
+	llgc	$acc,2+256($ikey,$key)
+	llgc	$dat,0($iinp,$inp)
+	la	$idx,0($idx,$acc)
+	la	$ikey,1($ikey)
+	la	$idx,0($idx,$dat)
+	nill	$idx,255
+	la	$iinp,1($iinp)
+	tml	$ikey,255
+	llgc	$dat,2($idx,$key)
+	stc	$dat,2+256-1($ikey,$key)
+	stc	$acc,2($idx,$key)
+	jz	.Ldone
+	brct	$cnt,.L2ndloop
+	lr	$cnt,$len
+	la	$iinp,0(%r0)
+	j	.L2ndloop
+.Ldone:
+	lmg	%r6,%r8,48($sp)
+	br	$rp
+.size	RC4_set_key,.-RC4_set_key
+
+___
+}
+
+# const char *RC4_options()
+$code.=<<___;
+.globl	RC4_options
+.type	RC4_options,\@function
+.align	16
+RC4_options:
+	larl	%r2,.Loptions
+	br	%r14
+.size	RC4_options,.-RC4_options
+.section	.rodata
+.Loptions:
+.align	8
+.string	"rc4(8x,char)"
+___
+
+print $code;
diff --git a/openssl/crypto/rc4/asm/rc4-x86_64.pl b/openssl/crypto/rc4/asm/rc4-x86_64.pl
new file mode 100755
index 0000000..677be5f
--- /dev/null
+++ b/openssl/crypto/rc4/asm/rc4-x86_64.pl
@@ -0,0 +1,504 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# 2.22x RC4 tune-up:-) It should be noted though that my hand [as in
+# "hand-coded assembler"] doesn't stand for the whole improvement
+# coefficient. It turned out that eliminating RC4_CHAR from config
+# line results in ~40% improvement (yes, even for C implementation).
+# Presumably it has everything to do with AMD cache architecture and
+# RAW or whatever penalties. Once again! The module *requires* config
+# line *without* RC4_CHAR! As for coding "secret," I bet on partial
+# register arithmetics. For example instead of 'inc %r8; and $255,%r8'
+# I simply 'inc %r8b'. Even though optimization manual discourages
+# to operate on partial registers, it turned out to be the best bet.
+# At least for AMD... How IA32E would perform remains to be seen...
+
+# As was shown by Marc Bevand reordering of couple of load operations
+# results in even higher performance gain of 3.3x:-) At least on
+# Opteron... For reference, 1x in this case is RC4_CHAR C-code
+# compiled with gcc 3.3.2, which performs at ~54MBps per 1GHz clock.
+# Latter means that if you want to *estimate* what to expect from
+# *your* Opteron, then multiply 54 by 3.3 and clock frequency in GHz.
+
+# Intel P4 EM64T core was found to run the AMD64 code really slow...
+# The only way to achieve comparable performance on P4 was to keep
+# RC4_CHAR. Kind of ironic, huh? As it's apparently impossible to
+# compose blended code, which would perform even within 30% marginal
+# on either AMD and Intel platforms, I implement both cases. See
+# rc4_skey.c for further details...
+
+# P4 EM64T core appears to be "allergic" to 64-bit inc/dec. Replacing 
+# those with add/sub results in 50% performance improvement of folded
+# loop...
+
+# As was shown by Zou Nanhai loop unrolling can improve Intel EM64T
+# performance by >30% [unlike P4 32-bit case that is]. But this is
+# provided that loads are reordered even more aggressively! Both code
+# pathes, AMD64 and EM64T, reorder loads in essentially same manner
+# as my IA-64 implementation. On Opteron this resulted in modest 5%
+# improvement [I had to test it], while final Intel P4 performance
+# achieves respectful 432MBps on 2.8GHz processor now. For reference.
+# If executed on Xeon, current RC4_CHAR code-path is 2.7x faster than
+# RC4_INT code-path. While if executed on Opteron, it's only 25%
+# slower than the RC4_INT one [meaning that if CPU µ-arch detection
+# is not implemented, then this final RC4_CHAR code-path should be
+# preferred, as it provides better *all-round* performance].
+
+# Intel Core2 was observed to perform poorly on both code paths:-( It
+# apparently suffers from some kind of partial register stall, which
+# occurs in 64-bit mode only [as virtually identical 32-bit loop was
+# observed to outperform 64-bit one by almost 50%]. Adding two movzb to
+# cloop1 boosts its performance by 80%! This loop appears to be optimal
+# fit for Core2 and therefore the code was modified to skip cloop8 on
+# this CPU.
+
+$flavour = shift;
+$output  = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour $output";
+
+$dat="%rdi";	    # arg1
+$len="%rsi";	    # arg2
+$inp="%rdx";	    # arg3
+$out="%rcx";	    # arg4
+
+@XX=("%r8","%r10");
+@TX=("%r9","%r11");
+$YY="%r12";
+$TY="%r13";
+
+$code=<<___;
+.text
+
+.globl	RC4
+.type	RC4,\@function,4
+.align	16
+RC4:	or	$len,$len
+	jne	.Lentry
+	ret
+.Lentry:
+	push	%rbx
+	push	%r12
+	push	%r13
+.Lprologue:
+
+	add	\$8,$dat
+	movl	-8($dat),$XX[0]#d
+	movl	-4($dat),$YY#d
+	cmpl	\$-1,256($dat)
+	je	.LRC4_CHAR
+	inc	$XX[0]#b
+	movl	($dat,$XX[0],4),$TX[0]#d
+	test	\$-8,$len
+	jz	.Lloop1
+	jmp	.Lloop8
+.align	16
+.Lloop8:
+___
+for ($i=0;$i<8;$i++) {
+$code.=<<___;
+	add	$TX[0]#b,$YY#b
+	mov	$XX[0],$XX[1]
+	movl	($dat,$YY,4),$TY#d
+	ror	\$8,%rax			# ror is redundant when $i=0
+	inc	$XX[1]#b
+	movl	($dat,$XX[1],4),$TX[1]#d
+	cmp	$XX[1],$YY
+	movl	$TX[0]#d,($dat,$YY,4)
+	cmove	$TX[0],$TX[1]
+	movl	$TY#d,($dat,$XX[0],4)
+	add	$TX[0]#b,$TY#b
+	movb	($dat,$TY,4),%al
+___
+push(@TX,shift(@TX)); push(@XX,shift(@XX));	# "rotate" registers
+}
+$code.=<<___;
+	ror	\$8,%rax
+	sub	\$8,$len
+
+	xor	($inp),%rax
+	add	\$8,$inp
+	mov	%rax,($out)
+	add	\$8,$out
+
+	test	\$-8,$len
+	jnz	.Lloop8
+	cmp	\$0,$len
+	jne	.Lloop1
+	jmp	.Lexit
+
+.align	16
+.Lloop1:
+	add	$TX[0]#b,$YY#b
+	movl	($dat,$YY,4),$TY#d
+	movl	$TX[0]#d,($dat,$YY,4)
+	movl	$TY#d,($dat,$XX[0],4)
+	add	$TY#b,$TX[0]#b
+	inc	$XX[0]#b
+	movl	($dat,$TX[0],4),$TY#d
+	movl	($dat,$XX[0],4),$TX[0]#d
+	xorb	($inp),$TY#b
+	inc	$inp
+	movb	$TY#b,($out)
+	inc	$out
+	dec	$len
+	jnz	.Lloop1
+	jmp	.Lexit
+
+.align	16
+.LRC4_CHAR:
+	add	\$1,$XX[0]#b
+	movzb	($dat,$XX[0]),$TX[0]#d
+	test	\$-8,$len
+	jz	.Lcloop1
+	cmpl	\$0,260($dat)
+	jnz	.Lcloop1
+	jmp	.Lcloop8
+.align	16
+.Lcloop8:
+	mov	($inp),%eax
+	mov	4($inp),%ebx
+___
+# unroll 2x4-wise, because 64-bit rotates kill Intel P4...
+for ($i=0;$i<4;$i++) {
+$code.=<<___;
+	add	$TX[0]#b,$YY#b
+	lea	1($XX[0]),$XX[1]
+	movzb	($dat,$YY),$TY#d
+	movzb	$XX[1]#b,$XX[1]#d
+	movzb	($dat,$XX[1]),$TX[1]#d
+	movb	$TX[0]#b,($dat,$YY)
+	cmp	$XX[1],$YY
+	movb	$TY#b,($dat,$XX[0])
+	jne	.Lcmov$i			# Intel cmov is sloooow...
+	mov	$TX[0],$TX[1]
+.Lcmov$i:
+	add	$TX[0]#b,$TY#b
+	xor	($dat,$TY),%al
+	ror	\$8,%eax
+___
+push(@TX,shift(@TX)); push(@XX,shift(@XX));	# "rotate" registers
+}
+for ($i=4;$i<8;$i++) {
+$code.=<<___;
+	add	$TX[0]#b,$YY#b
+	lea	1($XX[0]),$XX[1]
+	movzb	($dat,$YY),$TY#d
+	movzb	$XX[1]#b,$XX[1]#d
+	movzb	($dat,$XX[1]),$TX[1]#d
+	movb	$TX[0]#b,($dat,$YY)
+	cmp	$XX[1],$YY
+	movb	$TY#b,($dat,$XX[0])
+	jne	.Lcmov$i			# Intel cmov is sloooow...
+	mov	$TX[0],$TX[1]
+.Lcmov$i:
+	add	$TX[0]#b,$TY#b
+	xor	($dat,$TY),%bl
+	ror	\$8,%ebx
+___
+push(@TX,shift(@TX)); push(@XX,shift(@XX));	# "rotate" registers
+}
+$code.=<<___;
+	lea	-8($len),$len
+	mov	%eax,($out)
+	lea	8($inp),$inp
+	mov	%ebx,4($out)
+	lea	8($out),$out
+
+	test	\$-8,$len
+	jnz	.Lcloop8
+	cmp	\$0,$len
+	jne	.Lcloop1
+	jmp	.Lexit
+___
+$code.=<<___;
+.align	16
+.Lcloop1:
+	add	$TX[0]#b,$YY#b
+	movzb	($dat,$YY),$TY#d
+	movb	$TX[0]#b,($dat,$YY)
+	movb	$TY#b,($dat,$XX[0])
+	add	$TX[0]#b,$TY#b
+	add	\$1,$XX[0]#b
+	movzb	$TY#b,$TY#d
+	movzb	$XX[0]#b,$XX[0]#d
+	movzb	($dat,$TY),$TY#d
+	movzb	($dat,$XX[0]),$TX[0]#d
+	xorb	($inp),$TY#b
+	lea	1($inp),$inp
+	movb	$TY#b,($out)
+	lea	1($out),$out
+	sub	\$1,$len
+	jnz	.Lcloop1
+	jmp	.Lexit
+
+.align	16
+.Lexit:
+	sub	\$1,$XX[0]#b
+	movl	$XX[0]#d,-8($dat)
+	movl	$YY#d,-4($dat)
+
+	mov	(%rsp),%r13
+	mov	8(%rsp),%r12
+	mov	16(%rsp),%rbx
+	add	\$24,%rsp
+.Lepilogue:
+	ret
+.size	RC4,.-RC4
+___
+
+$idx="%r8";
+$ido="%r9";
+
+$code.=<<___;
+.extern	OPENSSL_ia32cap_P
+.globl	RC4_set_key
+.type	RC4_set_key,\@function,3
+.align	16
+RC4_set_key:
+	lea	8($dat),$dat
+	lea	($inp,$len),$inp
+	neg	$len
+	mov	$len,%rcx
+	xor	%eax,%eax
+	xor	$ido,$ido
+	xor	%r10,%r10
+	xor	%r11,%r11
+
+	mov	OPENSSL_ia32cap_P(%rip),$idx#d
+	bt	\$20,$idx#d
+	jnc	.Lw1stloop
+	bt	\$30,$idx#d
+	setc	$ido#b
+	mov	$ido#d,260($dat)
+	jmp	.Lc1stloop
+
+.align	16
+.Lw1stloop:
+	mov	%eax,($dat,%rax,4)
+	add	\$1,%al
+	jnc	.Lw1stloop
+
+	xor	$ido,$ido
+	xor	$idx,$idx
+.align	16
+.Lw2ndloop:
+	mov	($dat,$ido,4),%r10d
+	add	($inp,$len,1),$idx#b
+	add	%r10b,$idx#b
+	add	\$1,$len
+	mov	($dat,$idx,4),%r11d
+	cmovz	%rcx,$len
+	mov	%r10d,($dat,$idx,4)
+	mov	%r11d,($dat,$ido,4)
+	add	\$1,$ido#b
+	jnc	.Lw2ndloop
+	jmp	.Lexit_key
+
+.align	16
+.Lc1stloop:
+	mov	%al,($dat,%rax)
+	add	\$1,%al
+	jnc	.Lc1stloop
+
+	xor	$ido,$ido
+	xor	$idx,$idx
+.align	16
+.Lc2ndloop:
+	mov	($dat,$ido),%r10b
+	add	($inp,$len),$idx#b
+	add	%r10b,$idx#b
+	add	\$1,$len
+	mov	($dat,$idx),%r11b
+	jnz	.Lcnowrap
+	mov	%rcx,$len
+.Lcnowrap:
+	mov	%r10b,($dat,$idx)
+	mov	%r11b,($dat,$ido)
+	add	\$1,$ido#b
+	jnc	.Lc2ndloop
+	movl	\$-1,256($dat)
+
+.align	16
+.Lexit_key:
+	xor	%eax,%eax
+	mov	%eax,-8($dat)
+	mov	%eax,-4($dat)
+	ret
+.size	RC4_set_key,.-RC4_set_key
+
+.globl	RC4_options
+.type	RC4_options,\@abi-omnipotent
+.align	16
+RC4_options:
+	lea	.Lopts(%rip),%rax
+	mov	OPENSSL_ia32cap_P(%rip),%edx
+	bt	\$20,%edx
+	jnc	.Ldone
+	add	\$12,%rax
+	bt	\$30,%edx
+	jnc	.Ldone
+	add	\$13,%rax
+.Ldone:
+	ret
+.align	64
+.Lopts:
+.asciz	"rc4(8x,int)"
+.asciz	"rc4(8x,char)"
+.asciz	"rc4(1x,char)"
+.asciz	"RC4 for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
+.align	64
+.size	RC4_options,.-RC4_options
+___
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern	__imp_RtlVirtualUnwind
+.type	stream_se_handler,\@abi-omnipotent
+.align	16
+stream_se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	lea	.Lprologue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<prologue label
+	jb	.Lin_prologue
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	lea	.Lepilogue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip>=epilogue label
+	jae	.Lin_prologue
+
+	lea	24(%rax),%rax
+
+	mov	-8(%rax),%rbx
+	mov	-16(%rax),%r12
+	mov	-24(%rax),%r13
+	mov	%rbx,144($context)	# restore context->Rbx
+	mov	%r12,216($context)	# restore context->R12
+	mov	%r13,224($context)	# restore context->R13
+
+.Lin_prologue:
+	mov	8(%rax),%rdi
+	mov	16(%rax),%rsi
+	mov	%rax,152($context)	# restore context->Rsp
+	mov	%rsi,168($context)	# restore context->Rsi
+	mov	%rdi,176($context)	# restore context->Rdi
+
+	jmp	.Lcommon_seh_exit
+.size	stream_se_handler,.-stream_se_handler
+
+.type	key_se_handler,\@abi-omnipotent
+.align	16
+key_se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	152($context),%rax	# pull context->Rsp
+	mov	8(%rax),%rdi
+	mov	16(%rax),%rsi
+	mov	%rsi,168($context)	# restore context->Rsi
+	mov	%rdi,176($context)	# restore context->Rdi
+
+.Lcommon_seh_exit:
+
+	mov	40($disp),%rdi		# disp->ContextRecord
+	mov	$context,%rsi		# context
+	mov	\$154,%ecx		# sizeof(CONTEXT)
+	.long	0xa548f3fc		# cld; rep movsq
+
+	mov	$disp,%rsi
+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
+	mov	40(%rsi),%r10		# disp->ContextRecord
+	lea	56(%rsi),%r11		# &disp->HandlerData
+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
+	mov	%r10,32(%rsp)		# arg5
+	mov	%r11,40(%rsp)		# arg6
+	mov	%r12,48(%rsp)		# arg7
+	mov	%rcx,56(%rsp)		# arg8, (NULL)
+	call	*__imp_RtlVirtualUnwind(%rip)
+
+	mov	\$1,%eax		# ExceptionContinueSearch
+	add	\$64,%rsp
+	popfq
+	pop	%r15
+	pop	%r14
+	pop	%r13
+	pop	%r12
+	pop	%rbp
+	pop	%rbx
+	pop	%rdi
+	pop	%rsi
+	ret
+.size	key_se_handler,.-key_se_handler
+
+.section	.pdata
+.align	4
+	.rva	.LSEH_begin_RC4
+	.rva	.LSEH_end_RC4
+	.rva	.LSEH_info_RC4
+
+	.rva	.LSEH_begin_RC4_set_key
+	.rva	.LSEH_end_RC4_set_key
+	.rva	.LSEH_info_RC4_set_key
+
+.section	.xdata
+.align	8
+.LSEH_info_RC4:
+	.byte	9,0,0,0
+	.rva	stream_se_handler
+.LSEH_info_RC4_set_key:
+	.byte	9,0,0,0
+	.rva	key_se_handler
+___
+}
+
+$code =~ s/#([bwd])/$1/gm;
+
+print $code;
+
+close STDOUT;
diff --git a/openssl/crypto/rc4/rc4.c b/openssl/crypto/rc4/rc4.c
new file mode 100644
index 0000000..c900b26
--- /dev/null
+++ b/openssl/crypto/rc4/rc4.c
@@ -0,0 +1,193 @@
+/* crypto/rc4/rc4.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/rc4.h>
+#include <openssl/evp.h>
+
+char *usage[]={
+"usage: rc4 args\n",
+"\n",
+" -in arg         - input file - default stdin\n",
+" -out arg        - output file - default stdout\n",
+" -key key        - password\n",
+NULL
+};
+
+int main(int argc, char *argv[])
+	{
+	FILE *in=NULL,*out=NULL;
+	char *infile=NULL,*outfile=NULL,*keystr=NULL;
+	RC4_KEY key;
+	char buf[BUFSIZ];
+	int badops=0,i;
+	char **pp;
+	unsigned char md[MD5_DIGEST_LENGTH];
+
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if 	(strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			infile= *(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-key") == 0)
+			{
+			if (--argc < 1) goto bad;
+			keystr= *(++argv);
+			}
+		else
+			{
+			fprintf(stderr,"unknown option %s\n",*argv);
+			badops=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (badops)
+		{
+bad:
+		for (pp=usage; (*pp != NULL); pp++)
+			fprintf(stderr,"%s",*pp);
+		exit(1);
+		}
+
+	if (infile == NULL)
+		in=stdin;
+	else
+		{
+		in=fopen(infile,"r");
+		if (in == NULL)
+			{
+			perror("open");
+			exit(1);
+			}
+
+		}
+	if (outfile == NULL)
+		out=stdout;
+	else
+		{
+		out=fopen(outfile,"w");
+		if (out == NULL)
+			{
+			perror("open");
+			exit(1);
+			}
+		}
+		
+#ifdef OPENSSL_SYS_MSDOS
+	/* This should set the file to binary mode. */
+	{
+#include <fcntl.h>
+	setmode(fileno(in),O_BINARY);
+	setmode(fileno(out),O_BINARY);
+	}
+#endif
+
+	if (keystr == NULL)
+		{ /* get key */
+		i=EVP_read_pw_string(buf,BUFSIZ,"Enter RC4 password:",0);
+		if (i != 0)
+			{
+			OPENSSL_cleanse(buf,BUFSIZ);
+			fprintf(stderr,"bad password read\n");
+			exit(1);
+			}
+		keystr=buf;
+		}
+
+	EVP_Digest((unsigned char *)keystr,strlen(keystr),md,NULL,EVP_md5(),NULL);
+	OPENSSL_cleanse(keystr,strlen(keystr));
+	RC4_set_key(&key,MD5_DIGEST_LENGTH,md);
+	
+	for(;;)
+		{
+		i=fread(buf,1,BUFSIZ,in);
+		if (i == 0) break;
+		if (i < 0)
+			{
+			perror("read");
+			exit(1);
+			}
+		RC4(&key,(unsigned int)i,(unsigned char *)buf,
+			(unsigned char *)buf);
+		i=fwrite(buf,(unsigned int)i,1,out);
+		if (i != 1)
+			{
+			perror("write");
+			exit(1);
+			}
+		}
+	fclose(out);
+	fclose(in);
+	exit(0);
+	return(1);
+	}
+
diff --git a/openssl/crypto/rc4/rc4.h b/openssl/crypto/rc4/rc4.h
new file mode 100644
index 0000000..29d1acc
--- /dev/null
+++ b/openssl/crypto/rc4/rc4.h
@@ -0,0 +1,89 @@
+/* crypto/rc4/rc4.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RC4_H
+#define HEADER_RC4_H
+
+#include <openssl/opensslconf.h> /* OPENSSL_NO_RC4, RC4_INT */
+#ifdef OPENSSL_NO_RC4
+#error RC4 is disabled.
+#endif
+
+#include <stddef.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct rc4_key_st
+	{
+	RC4_INT x,y;
+	RC4_INT data[256];
+	} RC4_KEY;
+
+ 
+const char *RC4_options(void);
+void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
+void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
+		unsigned char *outdata);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/rc4/rc4_enc.c b/openssl/crypto/rc4/rc4_enc.c
new file mode 100644
index 0000000..8c4fc6c
--- /dev/null
+++ b/openssl/crypto/rc4/rc4_enc.c
@@ -0,0 +1,315 @@
+/* crypto/rc4/rc4_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc4.h>
+#include "rc4_locl.h"
+
+/* RC4 as implemented from a posting from
+ * Newsgroups: sci.crypt
+ * From: sterndark@netcom.com (David Sterndark)
+ * Subject: RC4 Algorithm revealed.
+ * Message-ID: <sternCvKL4B.Hyy@netcom.com>
+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
+ */
+
+void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
+	     unsigned char *outdata)
+	{
+        register RC4_INT *d;
+        register RC4_INT x,y,tx,ty;
+	size_t i;
+        
+        x=key->x;     
+        y=key->y;     
+        d=key->data; 
+
+#if defined(RC4_CHUNK)
+	/*
+	 * The original reason for implementing this(*) was the fact that
+	 * pre-21164a Alpha CPUs don't have byte load/store instructions
+	 * and e.g. a byte store has to be done with 64-bit load, shift,
+	 * and, or and finally 64-bit store. Peaking data and operating
+	 * at natural word size made it possible to reduce amount of
+	 * instructions as well as to perform early read-ahead without
+	 * suffering from RAW (read-after-write) hazard. This resulted
+	 * in ~40%(**) performance improvement on 21064 box with gcc.
+	 * But it's not only Alpha users who win here:-) Thanks to the
+	 * early-n-wide read-ahead this implementation also exhibits
+	 * >40% speed-up on SPARC and 20-30% on 64-bit MIPS (depending
+	 * on sizeof(RC4_INT)).
+	 *
+	 * (*)	"this" means code which recognizes the case when input
+	 *	and output pointers appear to be aligned at natural CPU
+	 *	word boundary
+	 * (**)	i.e. according to 'apps/openssl speed rc4' benchmark,
+	 *	crypto/rc4/rc4speed.c exhibits almost 70% speed-up...
+	 *
+	 * Cavets.
+	 *
+	 * - RC4_CHUNK="unsigned long long" should be a #1 choice for
+	 *   UltraSPARC. Unfortunately gcc generates very slow code
+	 *   (2.5-3 times slower than one generated by Sun's WorkShop
+	 *   C) and therefore gcc (at least 2.95 and earlier) should
+	 *   always be told that RC4_CHUNK="unsigned long".
+	 *
+	 *					<appro@fy.chalmers.se>
+	 */
+
+# define RC4_STEP	( \
+			x=(x+1) &0xff,	\
+			tx=d[x],	\
+			y=(tx+y)&0xff,	\
+			ty=d[y],	\
+			d[y]=tx,	\
+			d[x]=ty,	\
+			(RC4_CHUNK)d[(tx+ty)&0xff]\
+			)
+
+	if ( ( ((size_t)indata  & (sizeof(RC4_CHUNK)-1)) | 
+	       ((size_t)outdata & (sizeof(RC4_CHUNK)-1)) ) == 0 )
+		{
+		RC4_CHUNK ichunk,otp;
+		const union { long one; char little; } is_endian = {1};
+
+		/*
+		 * I reckon we can afford to implement both endian
+		 * cases and to decide which way to take at run-time
+		 * because the machine code appears to be very compact
+		 * and redundant 1-2KB is perfectly tolerable (i.e.
+		 * in case the compiler fails to eliminate it:-). By
+		 * suggestion from Terrel Larson <terr@terralogic.net>
+		 * who also stands for the is_endian union:-)
+		 *
+		 * Special notes.
+		 *
+		 * - is_endian is declared automatic as doing otherwise
+		 *   (declaring static) prevents gcc from eliminating
+		 *   the redundant code;
+		 * - compilers (those I've tried) don't seem to have
+		 *   problems eliminating either the operators guarded
+		 *   by "if (sizeof(RC4_CHUNK)==8)" or the condition
+		 *   expressions themselves so I've got 'em to replace
+		 *   corresponding #ifdefs from the previous version;
+		 * - I chose to let the redundant switch cases when
+		 *   sizeof(RC4_CHUNK)!=8 be (were also #ifdefed
+		 *   before);
+		 * - in case you wonder "&(sizeof(RC4_CHUNK)*8-1)" in
+		 *   [LB]ESHFT guards against "shift is out of range"
+		 *   warnings when sizeof(RC4_CHUNK)!=8 
+		 *
+		 *			<appro@fy.chalmers.se>
+		 */
+		if (!is_endian.little)
+			{	/* BIG-ENDIAN CASE */
+# define BESHFT(c)	(((sizeof(RC4_CHUNK)-(c)-1)*8)&(sizeof(RC4_CHUNK)*8-1))
+			for (;len&(0-sizeof(RC4_CHUNK));len-=sizeof(RC4_CHUNK))
+				{
+				ichunk  = *(RC4_CHUNK *)indata;
+				otp  = RC4_STEP<<BESHFT(0);
+				otp |= RC4_STEP<<BESHFT(1);
+				otp |= RC4_STEP<<BESHFT(2);
+				otp |= RC4_STEP<<BESHFT(3);
+				if (sizeof(RC4_CHUNK)==8)
+					{
+					otp |= RC4_STEP<<BESHFT(4);
+					otp |= RC4_STEP<<BESHFT(5);
+					otp |= RC4_STEP<<BESHFT(6);
+					otp |= RC4_STEP<<BESHFT(7);
+					}
+				*(RC4_CHUNK *)outdata = otp^ichunk;
+				indata  += sizeof(RC4_CHUNK);
+				outdata += sizeof(RC4_CHUNK);
+				}
+			if (len)
+				{
+				RC4_CHUNK mask=(RC4_CHUNK)-1, ochunk;
+
+				ichunk = *(RC4_CHUNK *)indata;
+				ochunk = *(RC4_CHUNK *)outdata;
+				otp = 0;
+				i = BESHFT(0);
+				mask <<= (sizeof(RC4_CHUNK)-len)<<3;
+				switch (len&(sizeof(RC4_CHUNK)-1))
+					{
+					case 7:	otp  = RC4_STEP<<i, i-=8;
+					case 6:	otp |= RC4_STEP<<i, i-=8;
+					case 5:	otp |= RC4_STEP<<i, i-=8;
+					case 4:	otp |= RC4_STEP<<i, i-=8;
+					case 3:	otp |= RC4_STEP<<i, i-=8;
+					case 2:	otp |= RC4_STEP<<i, i-=8;
+					case 1:	otp |= RC4_STEP<<i, i-=8;
+					case 0: ; /*
+						   * it's never the case,
+						   * but it has to be here
+						   * for ultrix?
+						   */
+					}
+				ochunk &= ~mask;
+				ochunk |= (otp^ichunk) & mask;
+				*(RC4_CHUNK *)outdata = ochunk;
+				}
+			key->x=x;     
+			key->y=y;
+			return;
+			}
+		else
+			{	/* LITTLE-ENDIAN CASE */
+# define LESHFT(c)	(((c)*8)&(sizeof(RC4_CHUNK)*8-1))
+			for (;len&(0-sizeof(RC4_CHUNK));len-=sizeof(RC4_CHUNK))
+				{
+				ichunk  = *(RC4_CHUNK *)indata;
+				otp  = RC4_STEP;
+				otp |= RC4_STEP<<8;
+				otp |= RC4_STEP<<16;
+				otp |= RC4_STEP<<24;
+				if (sizeof(RC4_CHUNK)==8)
+					{
+					otp |= RC4_STEP<<LESHFT(4);
+					otp |= RC4_STEP<<LESHFT(5);
+					otp |= RC4_STEP<<LESHFT(6);
+					otp |= RC4_STEP<<LESHFT(7);
+					}
+				*(RC4_CHUNK *)outdata = otp^ichunk;
+				indata  += sizeof(RC4_CHUNK);
+				outdata += sizeof(RC4_CHUNK);
+				}
+			if (len)
+				{
+				RC4_CHUNK mask=(RC4_CHUNK)-1, ochunk;
+
+				ichunk = *(RC4_CHUNK *)indata;
+				ochunk = *(RC4_CHUNK *)outdata;
+				otp = 0;
+				i   = 0;
+				mask >>= (sizeof(RC4_CHUNK)-len)<<3;
+				switch (len&(sizeof(RC4_CHUNK)-1))
+					{
+					case 7:	otp  = RC4_STEP,    i+=8;
+					case 6:	otp |= RC4_STEP<<i, i+=8;
+					case 5:	otp |= RC4_STEP<<i, i+=8;
+					case 4:	otp |= RC4_STEP<<i, i+=8;
+					case 3:	otp |= RC4_STEP<<i, i+=8;
+					case 2:	otp |= RC4_STEP<<i, i+=8;
+					case 1:	otp |= RC4_STEP<<i, i+=8;
+					case 0: ; /*
+						   * it's never the case,
+						   * but it has to be here
+						   * for ultrix?
+						   */
+					}
+				ochunk &= ~mask;
+				ochunk |= (otp^ichunk) & mask;
+				*(RC4_CHUNK *)outdata = ochunk;
+				}
+			key->x=x;     
+			key->y=y;
+			return;
+			}
+		}
+#endif
+#define LOOP(in,out) \
+		x=((x+1)&0xff); \
+		tx=d[x]; \
+		y=(tx+y)&0xff; \
+		d[x]=ty=d[y]; \
+		d[y]=tx; \
+		(out) = d[(tx+ty)&0xff]^ (in);
+
+#ifndef RC4_INDEX
+#define RC4_LOOP(a,b,i)	LOOP(*((a)++),*((b)++))
+#else
+#define RC4_LOOP(a,b,i)	LOOP(a[i],b[i])
+#endif
+
+	i=len>>3;
+	if (i)
+		{
+		for (;;)
+			{
+			RC4_LOOP(indata,outdata,0);
+			RC4_LOOP(indata,outdata,1);
+			RC4_LOOP(indata,outdata,2);
+			RC4_LOOP(indata,outdata,3);
+			RC4_LOOP(indata,outdata,4);
+			RC4_LOOP(indata,outdata,5);
+			RC4_LOOP(indata,outdata,6);
+			RC4_LOOP(indata,outdata,7);
+#ifdef RC4_INDEX
+			indata+=8;
+			outdata+=8;
+#endif
+			if (--i == 0) break;
+			}
+		}
+	i=len&0x07;
+	if (i)
+		{
+		for (;;)
+			{
+			RC4_LOOP(indata,outdata,0); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,1); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,2); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,3); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,4); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,5); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,6); if (--i == 0) break;
+			}
+		}               
+	key->x=x;     
+	key->y=y;
+	}
diff --git a/openssl/crypto/rc4/rc4_locl.h b/openssl/crypto/rc4/rc4_locl.h
new file mode 100644
index 0000000..c712e16
--- /dev/null
+++ b/openssl/crypto/rc4/rc4_locl.h
@@ -0,0 +1,5 @@
+#ifndef HEADER_RC4_LOCL_H
+#define HEADER_RC4_LOCL_H
+#include <openssl/opensslconf.h>
+#include <cryptlib.h>
+#endif
diff --git a/openssl/crypto/rc4/rc4_skey.c b/openssl/crypto/rc4/rc4_skey.c
new file mode 100644
index 0000000..b22c40b
--- /dev/null
+++ b/openssl/crypto/rc4/rc4_skey.c
@@ -0,0 +1,150 @@
+/* crypto/rc4/rc4_skey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc4.h>
+#include "rc4_locl.h"
+#include <openssl/opensslv.h>
+
+const char RC4_version[]="RC4" OPENSSL_VERSION_PTEXT;
+
+const char *RC4_options(void)
+	{
+#ifdef RC4_INDEX
+	if (sizeof(RC4_INT) == 1)
+		return("rc4(idx,char)");
+	else
+		return("rc4(idx,int)");
+#else
+	if (sizeof(RC4_INT) == 1)
+		return("rc4(ptr,char)");
+	else
+		return("rc4(ptr,int)");
+#endif
+	}
+
+/* RC4 as implemented from a posting from
+ * Newsgroups: sci.crypt
+ * From: sterndark@netcom.com (David Sterndark)
+ * Subject: RC4 Algorithm revealed.
+ * Message-ID: <sternCvKL4B.Hyy@netcom.com>
+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
+ */
+
+void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
+	{
+        register RC4_INT tmp;
+        register int id1,id2;
+        register RC4_INT *d;
+        unsigned int i;
+        
+        d= &(key->data[0]);
+        key->x = 0;     
+        key->y = 0;     
+        id1=id2=0;     
+
+#define SK_LOOP(d,n) { \
+		tmp=d[(n)]; \
+		id2 = (data[id1] + tmp + id2) & 0xff; \
+		if (++id1 == len) id1=0; \
+		d[(n)]=d[id2]; \
+		d[id2]=tmp; }
+
+#if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM)
+# if	defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
+	defined(__INTEL__) || \
+	defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64)
+	if (sizeof(RC4_INT) > 1) {
+		/*
+		 * Unlike all other x86 [and x86_64] implementations,
+		 * Intel P4 core [including EM64T] was found to perform
+		 * poorly with wider RC4_INT. Performance improvement
+		 * for IA-32 hand-coded assembler turned out to be 2.8x
+		 * if re-coded for RC4_CHAR! It's however inappropriate
+		 * to just switch to RC4_CHAR for x86[_64], as non-P4
+		 * implementations suffer from significant performance
+		 * losses then, e.g. PIII exhibits >2x deterioration,
+		 * and so does Opteron. In order to assure optimal
+		 * all-round performance, let us [try to] detect P4 at
+		 * run-time by checking upon HTT bit in CPU capability
+		 * vector and set up compressed key schedule, which is
+		 * recognized by correspondingly updated assembler
+		 * module...
+		 *				<appro@fy.chalmers.se>
+		 */
+		if (OPENSSL_ia32cap_P & (1<<28)) {
+			unsigned char *cp=(unsigned char *)d;
+
+			for (i=0;i<256;i++) cp[i]=i;
+			for (i=0;i<256;i++) SK_LOOP(cp,i);
+			/* mark schedule as compressed! */
+			d[256/sizeof(RC4_INT)]=-1;
+			return;
+		}
+	}
+# endif
+#endif
+	for (i=0; i < 256; i++) d[i]=i;
+	for (i=0; i < 256; i+=4)
+		{
+		SK_LOOP(d,i+0);
+		SK_LOOP(d,i+1);
+		SK_LOOP(d,i+2);
+		SK_LOOP(d,i+3);
+		}
+	}
+    
diff --git a/openssl/crypto/rc4/rc4s.cpp b/openssl/crypto/rc4/rc4s.cpp
new file mode 100644
index 0000000..3814fde
--- /dev/null
+++ b/openssl/crypto/rc4/rc4s.cpp
@@ -0,0 +1,73 @@
+//
+// gettsc.inl
+//
+// gives access to the Pentium's (secret) cycle counter
+//
+// This software was written by Leonard Janke (janke@unixg.ubc.ca)
+// in 1996-7 and is entered, by him, into the public domain.
+
+#if defined(__WATCOMC__)
+void GetTSC(unsigned long&);
+#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
+#elif defined(__GNUC__)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  asm volatile(".byte 15, 49\n\t"
+	       : "=eax" (tsc)
+	       :
+	       : "%edx", "%eax");
+}
+#elif defined(_MSC_VER)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  unsigned long a;
+  __asm _emit 0fh
+  __asm _emit 31h
+  __asm mov a, eax;
+  tsc=a;
+}
+#endif      
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/rc4.h>
+
+void main(int argc,char *argv[])
+	{
+	unsigned char buffer[1024];
+	RC4_KEY ctx;
+	unsigned long s1,s2,e1,e2;
+	unsigned char k[16];
+	unsigned long data[2];
+	unsigned char iv[8];
+	int i,num=64,numm;
+	int j=0;
+
+	if (argc >= 2)
+		num=atoi(argv[1]);
+
+	if (num == 0) num=256;
+	if (num > 1024-16) num=1024-16;
+	numm=num+8;
+
+	for (j=0; j<6; j++)
+		{
+		for (i=0; i<10; i++) /**/
+			{
+			RC4(&ctx,numm,buffer,buffer);
+			GetTSC(s1);
+			RC4(&ctx,numm,buffer,buffer);
+			GetTSC(e1);
+			GetTSC(s2);
+			RC4(&ctx,num,buffer,buffer);
+			GetTSC(e2);
+			RC4(&ctx,num,buffer,buffer);
+			}
+
+		printf("RC4 (%d bytes) %d %d (%d) - 8 bytes\n",num,
+			e1-s1,e2-s2,(e1-s1)-(e2-s2));
+		}
+	}
+
diff --git a/openssl/crypto/rc4/rc4speed.c b/openssl/crypto/rc4/rc4speed.c
new file mode 100644
index 0000000..0ebd381
--- /dev/null
+++ b/openssl/crypto/rc4/rc4speed.c
@@ -0,0 +1,253 @@
+/* crypto/rc4/rc4speed.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
+/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
+
+#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
+#define TIMES
+#endif
+
+#include <stdio.h>
+
+#include <openssl/e_os2.h>
+#include OPENSSL_UNISTD_IO
+OPENSSL_DECLARE_EXIT
+
+#ifndef OPENSSL_SYS_NETWARE
+#include <signal.h>
+#endif
+
+#ifndef _IRIX
+#include <time.h>
+#endif
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+#endif
+
+/* Depending on the VMS version, the tms structure is perhaps defined.
+   The __TMS macro will show if it was.  If it wasn't defined, we should
+   undefine TIMES, since that tells the rest of the program how things
+   should be handled.				-- Richard Levitte */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
+#undef TIMES
+#endif
+
+#ifndef TIMES
+#include <sys/timeb.h>
+#endif
+
+#if defined(sun) || defined(__ultrix)
+#define _POSIX_SOURCE
+#include <limits.h>
+#include <sys/param.h>
+#endif
+
+#include <openssl/rc4.h>
+
+/* The following if from times(3) man page.  It may need to be changed */
+#ifndef HZ
+#ifndef CLK_TCK
+#define HZ	100.0
+#else /* CLK_TCK */
+#define HZ ((double)CLK_TCK)
+#endif
+#endif
+
+#define BUFSIZE	((long)1024)
+long run=0;
+
+double Time_F(int s);
+#ifdef SIGALRM
+#if defined(__STDC__) || defined(sgi) || defined(_AIX)
+#define SIGRETTYPE void
+#else
+#define SIGRETTYPE int
+#endif
+
+SIGRETTYPE sig_done(int sig);
+SIGRETTYPE sig_done(int sig)
+	{
+	signal(SIGALRM,sig_done);
+	run=0;
+#ifdef LINT
+	sig=sig;
+#endif
+	}
+#endif
+
+#define START	0
+#define STOP	1
+
+double Time_F(int s)
+	{
+	double ret;
+#ifdef TIMES
+	static struct tms tstart,tend;
+
+	if (s == START)
+		{
+		times(&tstart);
+		return(0);
+		}
+	else
+		{
+		times(&tend);
+		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#else /* !times() */
+	static struct timeb tstart,tend;
+	long i;
+
+	if (s == START)
+		{
+		ftime(&tstart);
+		return(0);
+		}
+	else
+		{
+		ftime(&tend);
+		i=(long)tend.millitm-(long)tstart.millitm;
+		ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#endif
+	}
+
+int main(int argc, char **argv)
+	{
+	long count;
+	static unsigned char buf[BUFSIZE];
+	static unsigned char key[] ={
+			0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+			0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
+			};
+	RC4_KEY sch;
+	double a,b,c,d;
+#ifndef SIGALRM
+	long ca,cb,cc;
+#endif
+
+#ifndef TIMES
+	printf("To get the most accurate results, try to run this\n");
+	printf("program when this computer is idle.\n");
+#endif
+
+#ifndef SIGALRM
+	printf("First we calculate the approximate speed ...\n");
+	RC4_set_key(&sch,16,key);
+	count=10;
+	do	{
+		long i;
+		unsigned long data[2];
+
+		count*=2;
+		Time_F(START);
+		for (i=count; i; i--)
+			RC4(&sch,8,buf,buf);
+		d=Time_F(STOP);
+		} while (d < 3.0);
+	ca=count/512;
+	cc=count*8/BUFSIZE+1;
+	printf("Doing RC4_set_key %ld times\n",ca);
+#define COND(d)	(count != (d))
+#define COUNT(d) (d)
+#else
+#define COND(c)	(run)
+#define COUNT(d) (count)
+	signal(SIGALRM,sig_done);
+	printf("Doing RC4_set_key for 10 seconds\n");
+	alarm(10);
+#endif
+
+	Time_F(START);
+	for (count=0,run=1; COND(ca); count+=4)
+		{
+		RC4_set_key(&sch,16,key);
+		RC4_set_key(&sch,16,key);
+		RC4_set_key(&sch,16,key);
+		RC4_set_key(&sch,16,key);
+		}
+	d=Time_F(STOP);
+	printf("%ld RC4_set_key's in %.2f seconds\n",count,d);
+	a=((double)COUNT(ca))/d;
+
+#ifdef SIGALRM
+	printf("Doing RC4 on %ld byte blocks for 10 seconds\n",BUFSIZE);
+	alarm(10);
+#else
+	printf("Doing RC4 %ld times on %ld byte blocks\n",cc,BUFSIZE);
+#endif
+	Time_F(START);
+	for (count=0,run=1; COND(cc); count++)
+		RC4(&sch,BUFSIZE,buf,buf);
+	d=Time_F(STOP);
+	printf("%ld RC4's of %ld byte blocks in %.2f second\n",
+		count,BUFSIZE,d);
+	c=((double)COUNT(cc)*BUFSIZE)/d;
+
+	printf("RC4 set_key per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a);
+	printf("RC4   bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c);
+	exit(0);
+#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
+	return(0);
+#endif
+	}
+
diff --git a/openssl/crypto/rc4/rc4test.c b/openssl/crypto/rc4/rc4test.c
new file mode 100644
index 0000000..633a79e
--- /dev/null
+++ b/openssl/crypto/rc4/rc4test.c
@@ -0,0 +1,236 @@
+/* crypto/rc4/rc4test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_RC4
+int main(int argc, char *argv[])
+{
+    printf("No RC4 support\n");
+    return(0);
+}
+#else
+#include <openssl/rc4.h>
+#include <openssl/sha.h>
+
+static unsigned char keys[7][30]={
+	{8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
+	{8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
+	{8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{4,0xef,0x01,0x23,0x45},
+	{8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
+	{4,0xef,0x01,0x23,0x45},
+	};
+
+static unsigned char data_len[7]={8,8,8,20,28,10};
+static unsigned char data[7][30]={
+	{0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xff},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	   0x00,0x00,0x00,0x00,0xff},
+	{0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
+	   0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
+	   0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
+	   0x12,0x34,0x56,0x78,0xff},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
+	{0},
+	};
+
+static unsigned char output[7][30]={
+	{0x75,0xb7,0x87,0x80,0x99,0xe0,0xc5,0x96,0x00},
+	{0x74,0x94,0xc2,0xe7,0x10,0x4b,0x08,0x79,0x00},
+	{0xde,0x18,0x89,0x41,0xa3,0x37,0x5d,0x3a,0x00},
+	{0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,
+	 0xbd,0x61,0x5a,0x11,0x62,0xe1,0xc7,0xba,
+	 0x36,0xb6,0x78,0x58,0x00},
+	{0x66,0xa0,0x94,0x9f,0x8a,0xf7,0xd6,0x89,
+	 0x1f,0x7f,0x83,0x2b,0xa8,0x33,0xc0,0x0c,
+	 0x89,0x2e,0xbe,0x30,0x14,0x3c,0xe2,0x87,
+	 0x40,0x01,0x1e,0xcf,0x00},
+	{0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,0xbd,0x61,0x00},
+	{0},
+	};
+
+int main(int argc, char *argv[])
+	{
+	int i,err=0;
+	int j;
+	unsigned char *p;
+	RC4_KEY key;
+	unsigned char obuf[512];
+
+	for (i=0; i<6; i++)
+		{
+		RC4_set_key(&key,keys[i][0],&(keys[i][1]));
+		memset(obuf,0x00,sizeof(obuf));
+		RC4(&key,data_len[i],&(data[i][0]),obuf);
+		if (memcmp(obuf,output[i],data_len[i]+1) != 0)
+			{
+			printf("error calculating RC4\n");
+			printf("output:");
+			for (j=0; j<data_len[i]+1; j++)
+				printf(" %02x",obuf[j]);
+			printf("\n");
+			printf("expect:");
+			p= &(output[i][0]);
+			for (j=0; j<data_len[i]+1; j++)
+				printf(" %02x",*(p++));
+			printf("\n");
+			err++;
+			}
+		else
+			printf("test %d ok\n",i);
+		}
+	printf("test end processing ");
+	for (i=0; i<data_len[3]; i++)
+		{
+		RC4_set_key(&key,keys[3][0],&(keys[3][1]));
+		memset(obuf,0x00,sizeof(obuf));
+		RC4(&key,i,&(data[3][0]),obuf);
+		if ((memcmp(obuf,output[3],i) != 0) || (obuf[i] != 0))
+			{
+			printf("error in RC4 length processing\n");
+			printf("output:");
+			for (j=0; j<i+1; j++)
+				printf(" %02x",obuf[j]);
+			printf("\n");
+			printf("expect:");
+			p= &(output[3][0]);
+			for (j=0; j<i; j++)
+				printf(" %02x",*(p++));
+			printf(" 00\n");
+			err++;
+			}
+		else
+			{
+			printf(".");
+			fflush(stdout);
+			}
+		}
+	printf("done\n");
+	printf("test multi-call ");
+	for (i=0; i<data_len[3]; i++)
+		{
+		RC4_set_key(&key,keys[3][0],&(keys[3][1]));
+		memset(obuf,0x00,sizeof(obuf));
+		RC4(&key,i,&(data[3][0]),obuf);
+		RC4(&key,data_len[3]-i,&(data[3][i]),&(obuf[i]));
+		if (memcmp(obuf,output[3],data_len[3]+1) != 0)
+			{
+			printf("error in RC4 multi-call processing\n");
+			printf("output:");
+			for (j=0; j<data_len[3]+1; j++)
+				printf(" %02x",obuf[j]);
+			printf("\n");
+			printf("expect:");
+			p= &(output[3][0]);
+			for (j=0; j<data_len[3]+1; j++)
+				printf(" %02x",*(p++));
+			err++;
+			}
+		else
+			{
+			printf(".");
+			fflush(stdout);
+			}
+		}
+	printf("done\n");
+	printf("bulk test ");
+	{   unsigned char buf[513];
+	    SHA_CTX c;
+	    unsigned char md[SHA_DIGEST_LENGTH];
+	    static unsigned char expected[]={
+		0xa4,0x7b,0xcc,0x00,0x3d,0xd0,0xbd,0xe1,0xac,0x5f,
+		0x12,0x1e,0x45,0xbc,0xfb,0x1a,0xa1,0xf2,0x7f,0xc5 };
+
+		RC4_set_key(&key,keys[0][0],&(keys[3][1]));
+		memset(buf,'\0',sizeof(buf));
+		SHA1_Init(&c);
+		for (i=0;i<2571;i++) {
+			RC4(&key,sizeof(buf),buf,buf);
+			SHA1_Update(&c,buf,sizeof(buf));
+		}
+		SHA1_Final(md,&c);
+
+		if (memcmp(md,expected,sizeof(md))) {
+			printf("error in RC4 bulk test\n");
+			printf("output:");
+			for (j=0; j<(int)sizeof(md); j++)
+				printf(" %02x",md[j]);
+			printf("\n");
+			printf("expect:");
+			for (j=0; j<(int)sizeof(md); j++)
+				printf(" %02x",expected[j]);
+			printf("\n");
+			err++;
+		}
+		else	printf("ok\n");
+	}
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
+	EXIT(err);
+	return(0);
+	}
+#endif
diff --git a/openssl/crypto/rc4/rrc4.doc b/openssl/crypto/rc4/rrc4.doc
new file mode 100644
index 0000000..2f9a953
--- /dev/null
+++ b/openssl/crypto/rc4/rrc4.doc
@@ -0,0 +1,278 @@
+Newsgroups: sci.crypt,alt.security,comp.security.misc,alt.privacy
+Path: ghost.dsi.unimi.it!univ-lyon1.fr!jussieu.fr!zaphod.crihan.fr!warwick!clyde.open.ac.uk!strath-cs!bnr.co.uk!bt!pipex!howland.reston.ans.net!europa.eng.gtefsd.com!MathWorks.Com!yeshua.marcam.com!charnel.ecst.csuchico.edu!csusac!csus.edu!netcom.com!sterndark
+From: sterndark@netcom.com (David Sterndark)
+Subject: RC4 Algorithm revealed.
+Message-ID: <sternCvKL4B.Hyy@netcom.com>
+Sender: sterndark@netcom.com 
+Organization: NETCOM On-line Communication Services (408 261-4700 guest)
+X-Newsreader: TIN [version 1.2 PL1]
+Date: Wed, 14 Sep 1994 06:35:31 GMT
+Lines: 263
+Xref: ghost.dsi.unimi.it sci.crypt:27332 alt.security:14732 comp.security.misc:11701 alt.privacy:16026
+
+I am shocked,  shocked, I tell you,  shocked, to discover
+that the cypherpunks have illegaly and criminally revealed
+a crucial RSA trade secret and harmed the security of
+America by reverse engineering the RC4 algorithm and
+publishing it to the world.
+ 
+On Saturday morning an anonymous cypherpunk wrote:
+ 
+ 
+   SUBJECT:  RC4 Source Code
+ 
+ 
+   I've tested this.  It is compatible with the RC4 object module
+   that comes in the various RSA toolkits.  
+ 
+   /* rc4.h */
+   typedef struct rc4_key
+   {      
+        unsigned char state[256];       
+        unsigned char x;        
+        unsigned char y;
+   } rc4_key;
+   void prepare_key(unsigned char *key_data_ptr,int key_data_len,
+   rc4_key *key);
+   void rc4(unsigned char *buffer_ptr,int buffer_len,rc4_key * key);
+   
+   
+   /*rc4.c */
+   #include "rc4.h"
+   static void swap_byte(unsigned char *a, unsigned char *b);
+   void prepare_key(unsigned char *key_data_ptr, int key_data_len,
+   rc4_key *key)
+   {
+        unsigned char swapByte;
+        unsigned char index1;
+        unsigned char index2;
+        unsigned char* state;
+        short counter;     
+        
+        state = &key->state[0];         
+        for(counter = 0; counter < 256; counter++)              
+        state[counter] = counter;               
+        key->x = 0;     
+        key->y = 0;     
+        index1 = 0;     
+        index2 = 0;             
+        for(counter = 0; counter < 256; counter++)      
+        {               
+             index2 = (key_data_ptr[index1] + state[counter] +
+                index2) % 256;                
+             swap_byte(&state[counter], &state[index2]);            
+   
+             index1 = (index1 + 1) % key_data_len;  
+        }       
+    }
+    
+    void rc4(unsigned char *buffer_ptr, int buffer_len, rc4_key *key)
+    { 
+        unsigned char x;
+        unsigned char y;
+        unsigned char* state;
+        unsigned char xorIndex;
+        short counter;              
+        
+        x = key->x;     
+        y = key->y;     
+        
+        state = &key->state[0];         
+        for(counter = 0; counter < buffer_len; counter ++)      
+        {               
+             x = (x + 1) % 256;                      
+             y = (state[x] + y) % 256;               
+             swap_byte(&state[x], &state[y]);                        
+                  
+             xorIndex = (state[x] + state[y]) % 256;                 
+                  
+             buffer_ptr[counter] ^= state[xorIndex];         
+         }               
+         key->x = x;     
+         key->y = y;
+    }
+    
+    static void swap_byte(unsigned char *a, unsigned char *b)
+    {
+        unsigned char swapByte; 
+        
+        swapByte = *a; 
+        *a = *b;      
+        *b = swapByte;
+    }
+ 
+ 
+ 
+Another cypherpunk, this one not anonymous, tested the
+output from this algorithm against the output from
+official RC4 object code
+ 
+ 
+   Date: Tue, 13 Sep 94 18:37:56 PDT
+   From: ekr@eit.COM (Eric Rescorla)
+   Message-Id: <9409140137.AA17743@eitech.eit.com>
+   Subject: RC4 compatibility testing
+   Cc: cypherpunks@toad.com
+   
+   One data point:
+   
+   I can't say anything about the internals of RC4 versus the
+   algorithm that Bill Sommerfeld is rightly calling 'Alleged RC4',
+   since I don't know anything about RC4's internals. 
+   
+   However, I do have a (legitimately acquired) copy of BSAFE2 and
+   so I'm able to compare the output of this algorithm to the output
+   of genuine RC4 as found in BSAFE. I chose a set of test vectors
+   and ran them through both algorithms. The algorithms appear to
+   give identical results, at least with these key/plaintext pairs.
+   
+   I note that this is the algorithm _without_ Hal Finney's
+   proposed modification
+   
+   (see <199409130605.XAA24133@jobe.shell.portal.com>).
+   
+   The vectors I used (together with the ciphertext they produce)
+   follow at the end of this message.
+   
+   -Ekr
+   
+   Disclaimer: This posting does not reflect the opinions of EIT.
+   
+   --------------------results follow--------------
+   Test vector 0
+   Key: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef 
+   Input: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef 
+   0 Output: 0x75 0xb7 0x87 0x80 0x99 0xe0 0xc5 0x96 
+   
+   Test vector 1
+   Key: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef 
+   Input: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
+   0 Output: 0x74 0x94 0xc2 0xe7 0x10 0x4b 0x08 0x79 
+   
+   Test vector 2
+   Key: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
+   Input: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
+   0 Output: 0xde 0x18 0x89 0x41 0xa3 0x37 0x5d 0x3a 
+   
+   Test vector 3
+   Key: 0xef 0x01 0x23 0x45 
+   Input: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
+   0 Output: 0xd6 0xa1 0x41 0xa7 0xec 0x3c 0x38 0xdf 0xbd 0x61 
+   
+   Test vector 4
+   Key: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef 
+   Input: 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
+   0x01 
+   0 Output: 0x75 0x95 0xc3 0xe6 0x11 0x4a 0x09 0x78 0x0c 0x4a 0xd4 
+   0x52 0x33 0x8e 0x1f 0xfd 0x9a 0x1b 0xe9 0x49 0x8f 
+   0x81 0x3d 0x76 0x53 0x34 0x49 0xb6 0x77 0x8d 0xca 
+   0xd8 0xc7 0x8a 0x8d 0x2b 0xa9 0xac 0x66 0x08 0x5d 
+   0x0e 0x53 0xd5 0x9c 0x26 0xc2 0xd1 0xc4 0x90 0xc1 
+   0xeb 0xbe 0x0c 0xe6 0x6d 0x1b 0x6b 0x1b 0x13 0xb6 
+   0xb9 0x19 0xb8 0x47 0xc2 0x5a 0x91 0x44 0x7a 0x95 
+   0xe7 0x5e 0x4e 0xf1 0x67 0x79 0xcd 0xe8 0xbf 0x0a 
+   0x95 0x85 0x0e 0x32 0xaf 0x96 0x89 0x44 0x4f 0xd3 
+   0x77 0x10 0x8f 0x98 0xfd 0xcb 0xd4 0xe7 0x26 0x56 
+   0x75 0x00 0x99 0x0b 0xcc 0x7e 0x0c 0xa3 0xc4 0xaa 
+   0xa3 0x04 0xa3 0x87 0xd2 0x0f 0x3b 0x8f 0xbb 0xcd 
+   0x42 0xa1 0xbd 0x31 0x1d 0x7a 0x43 0x03 0xdd 0xa5 
+   0xab 0x07 0x88 0x96 0xae 0x80 0xc1 0x8b 0x0a 0xf6 
+   0x6d 0xff 0x31 0x96 0x16 0xeb 0x78 0x4e 0x49 0x5a 
+   0xd2 0xce 0x90 0xd7 0xf7 0x72 0xa8 0x17 0x47 0xb6 
+   0x5f 0x62 0x09 0x3b 0x1e 0x0d 0xb9 0xe5 0xba 0x53 
+   0x2f 0xaf 0xec 0x47 0x50 0x83 0x23 0xe6 0x71 0x32 
+   0x7d 0xf9 0x44 0x44 0x32 0xcb 0x73 0x67 0xce 0xc8 
+   0x2f 0x5d 0x44 0xc0 0xd0 0x0b 0x67 0xd6 0x50 0xa0 
+   0x75 0xcd 0x4b 0x70 0xde 0xdd 0x77 0xeb 0x9b 0x10 
+   0x23 0x1b 0x6b 0x5b 0x74 0x13 0x47 0x39 0x6d 0x62 
+   0x89 0x74 0x21 0xd4 0x3d 0xf9 0xb4 0x2e 0x44 0x6e 
+   0x35 0x8e 0x9c 0x11 0xa9 0xb2 0x18 0x4e 0xcb 0xef 
+   0x0c 0xd8 0xe7 0xa8 0x77 0xef 0x96 0x8f 0x13 0x90 
+   0xec 0x9b 0x3d 0x35 0xa5 0x58 0x5c 0xb0 0x09 0x29 
+   0x0e 0x2f 0xcd 0xe7 0xb5 0xec 0x66 0xd9 0x08 0x4b 
+   0xe4 0x40 0x55 0xa6 0x19 0xd9 0xdd 0x7f 0xc3 0x16 
+   0x6f 0x94 0x87 0xf7 0xcb 0x27 0x29 0x12 0x42 0x64 
+   0x45 0x99 0x85 0x14 0xc1 0x5d 0x53 0xa1 0x8c 0x86 
+   0x4c 0xe3 0xa2 0xb7 0x55 0x57 0x93 0x98 0x81 0x26 
+   0x52 0x0e 0xac 0xf2 0xe3 0x06 0x6e 0x23 0x0c 0x91 
+   0xbe 0xe4 0xdd 0x53 0x04 0xf5 0xfd 0x04 0x05 0xb3 
+   0x5b 0xd9 0x9c 0x73 0x13 0x5d 0x3d 0x9b 0xc3 0x35 
+   0xee 0x04 0x9e 0xf6 0x9b 0x38 0x67 0xbf 0x2d 0x7b 
+   0xd1 0xea 0xa5 0x95 0xd8 0xbf 0xc0 0x06 0x6f 0xf8 
+   0xd3 0x15 0x09 0xeb 0x0c 0x6c 0xaa 0x00 0x6c 0x80 
+   0x7a 0x62 0x3e 0xf8 0x4c 0x3d 0x33 0xc1 0x95 0xd2 
+   0x3e 0xe3 0x20 0xc4 0x0d 0xe0 0x55 0x81 0x57 0xc8 
+   0x22 0xd4 0xb8 0xc5 0x69 0xd8 0x49 0xae 0xd5 0x9d 
+   0x4e 0x0f 0xd7 0xf3 0x79 0x58 0x6b 0x4b 0x7f 0xf6 
+   0x84 0xed 0x6a 0x18 0x9f 0x74 0x86 0xd4 0x9b 0x9c 
+   0x4b 0xad 0x9b 0xa2 0x4b 0x96 0xab 0xf9 0x24 0x37 
+   0x2c 0x8a 0x8f 0xff 0xb1 0x0d 0x55 0x35 0x49 0x00 
+   0xa7 0x7a 0x3d 0xb5 0xf2 0x05 0xe1 0xb9 0x9f 0xcd 
+   0x86 0x60 0x86 0x3a 0x15 0x9a 0xd4 0xab 0xe4 0x0f 
+   0xa4 0x89 0x34 0x16 0x3d 0xdd 0xe5 0x42 0xa6 0x58 
+   0x55 0x40 0xfd 0x68 0x3c 0xbf 0xd8 0xc0 0x0f 0x12 
+   0x12 0x9a 0x28 0x4d 0xea 0xcc 0x4c 0xde 0xfe 0x58 
+   0xbe 0x71 0x37 0x54 0x1c 0x04 0x71 0x26 0xc8 0xd4 
+   0x9e 0x27 0x55 0xab 0x18 0x1a 0xb7 0xe9 0x40 0xb0 
+   0xc0 
+   
+
+
+-- 
+ ---------------------------------------------------------------------
+We have the right to defend ourselves and our
+property, because of the kind of animals that we              James A. Donald
+are.  True law derives from this right, not from
+the arbitrary power of the omnipotent state.                jamesd@netcom.com
+
+
diff --git a/openssl/crypto/rc5/Makefile b/openssl/crypto/rc5/Makefile
new file mode 100644
index 0000000..8a8b00e
--- /dev/null
+++ b/openssl/crypto/rc5/Makefile
@@ -0,0 +1,94 @@
+#
+# OpenSSL/crypto/rc5/Makefile
+#
+
+DIR=	rc5
+TOP=	../..
+CC=	cc
+CPP=	$(CC) -E
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+RC5_ENC=		rc5_enc.o
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+ASFLAGS= $(INCLUDES) $(ASFLAG)
+AFLAGS= $(ASFLAGS)
+
+GENERAL=Makefile
+TEST=rc5test.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=rc5_skey.c rc5_ecb.c rc5_enc.c rc5cfb64.c rc5ofb64.c 
+LIBOBJ=rc5_skey.o rc5_ecb.o $(RC5_ENC) rc5cfb64.o rc5ofb64.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= rc5.h
+HEADER=	rc5_locl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+rc5-586.s: asm/rc5-586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
+	$(PERL) asm/rc5-586.pl $(PERLASM_SCHEME) $(CFLAGS) > $@
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+rc5_ecb.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+rc5_ecb.o: ../../include/openssl/rc5.h rc5_ecb.c rc5_locl.h
+rc5_enc.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc5.h
+rc5_enc.o: rc5_enc.c rc5_locl.h
+rc5_skey.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc5.h
+rc5_skey.o: rc5_locl.h rc5_skey.c
+rc5cfb64.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc5.h
+rc5cfb64.o: rc5_locl.h rc5cfb64.c
+rc5ofb64.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc5.h
+rc5ofb64.o: rc5_locl.h rc5ofb64.c
diff --git a/openssl/crypto/rc5/asm/rc5-586.pl b/openssl/crypto/rc5/asm/rc5-586.pl
new file mode 100644
index 0000000..61ac6ef
--- /dev/null
+++ b/openssl/crypto/rc5/asm/rc5-586.pl
@@ -0,0 +1,110 @@
+#!/usr/local/bin/perl
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+require "cbc.pl";
+
+&asm_init($ARGV[0],"rc5-586.pl");
+
+$RC5_MAX_ROUNDS=16;
+$RC5_32_OFF=($RC5_MAX_ROUNDS+2)*4;
+$A="edi";
+$B="esi";
+$S="ebp";
+$tmp1="eax";
+$r="ebx";
+$tmpc="ecx";
+$tmp4="edx";
+
+&RC5_32_encrypt("RC5_32_encrypt",1);
+&RC5_32_encrypt("RC5_32_decrypt",0);
+&cbc("RC5_32_cbc_encrypt","RC5_32_encrypt","RC5_32_decrypt",0,4,5,3,-1,-1);
+&asm_finish();
+
+sub RC5_32_encrypt
+	{
+	local($name,$enc)=@_;
+
+	&function_begin_B($name,"");
+
+	&comment("");
+
+	&push("ebp");
+	 &push("esi");
+	&push("edi");
+	 &mov($tmp4,&wparam(0));
+	&mov($S,&wparam(1));
+
+	&comment("Load the 2 words");
+	 &mov($A,&DWP(0,$tmp4,"",0));
+	&mov($B,&DWP(4,$tmp4,"",0));
+
+	&push($r);
+	 &mov($r,	&DWP(0,$S,"",0));
+
+	# encrypting part
+
+	if ($enc)
+		{
+		 &add($A,	&DWP(4+0,$S,"",0));
+		&add($B,	&DWP(4+4,$S,"",0));
+
+		for ($i=0; $i<$RC5_MAX_ROUNDS; $i++)
+			{
+			 &xor($A,	$B);
+			&mov($tmp1,	&DWP(12+$i*8,$S,"",0));
+			 &mov($tmpc,	$B);
+			&rotl($A,	&LB("ecx"));
+			&add($A,	$tmp1);
+
+			 &xor($B,	$A);
+			&mov($tmp1,	&DWP(16+$i*8,$S,"",0));
+			 &mov($tmpc,	$A);
+			&rotl($B,	&LB("ecx"));
+			&add($B,	$tmp1);
+			if (($i == 7) || ($i == 11))
+				{
+			 &cmp($r,	$i+1);
+			&je(&label("rc5_exit"));
+				}
+			}
+		}
+	else
+		{
+		 &cmp($r,	12);
+		&je(&label("rc5_dec_12"));
+		 &cmp($r,	8);
+		&je(&label("rc5_dec_8"));
+		for ($i=$RC5_MAX_ROUNDS; $i > 0; $i--)
+			{
+			&set_label("rc5_dec_$i") if ($i == 12) || ($i == 8);
+			 &mov($tmp1,	&DWP($i*8+8,$S,"",0));
+			&sub($B,	$tmp1);
+			 &mov($tmpc,	$A);
+			&rotr($B,	&LB("ecx"));
+			&xor($B,	$A);
+
+			 &mov($tmp1,	&DWP($i*8+4,$S,"",0));
+			&sub($A,	$tmp1);
+			 &mov($tmpc,	$B);
+			&rotr($A,	&LB("ecx"));
+			&xor($A,	$B);
+			}
+		 &sub($B,	&DWP(4+4,$S,"",0));
+		&sub($A,	&DWP(4+0,$S,"",0));
+		}
+
+	&set_label("rc5_exit");
+	 &mov(&DWP(0,$tmp4,"",0),$A);
+	&mov(&DWP(4,$tmp4,"",0),$B);
+
+	 &pop("ebx");
+	&pop("edi");
+	 &pop("esi");
+	&pop("ebp");
+	 &ret();
+	&function_end_B($name);
+	}
+
+
diff --git a/openssl/crypto/rc5/rc5.h b/openssl/crypto/rc5/rc5.h
new file mode 100644
index 0000000..4b3c153
--- /dev/null
+++ b/openssl/crypto/rc5/rc5.h
@@ -0,0 +1,118 @@
+/* crypto/rc5/rc5.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RC5_H
+#define HEADER_RC5_H
+
+#include <openssl/opensslconf.h> /* OPENSSL_NO_RC5 */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_RC5
+#error RC5 is disabled.
+#endif
+
+#define RC5_ENCRYPT	1
+#define RC5_DECRYPT	0
+
+/* 32 bit.  For Alpha, things may get weird */
+#define RC5_32_INT unsigned long
+
+#define RC5_32_BLOCK		8
+#define RC5_32_KEY_LENGTH	16 /* This is a default, max is 255 */
+
+/* This are the only values supported.  Tweak the code if you want more
+ * The most supported modes will be
+ * RC5-32/12/16
+ * RC5-32/16/8
+ */
+#define RC5_8_ROUNDS	8
+#define RC5_12_ROUNDS	12
+#define RC5_16_ROUNDS	16
+
+typedef struct rc5_key_st
+	{
+	/* Number of rounds */
+	int rounds;
+	RC5_32_INT data[2*(RC5_16_ROUNDS+1)];
+	} RC5_32_KEY;
+
+ 
+void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data,
+	int rounds);
+void RC5_32_ecb_encrypt(const unsigned char *in,unsigned char *out,RC5_32_KEY *key,
+	int enc);
+void RC5_32_encrypt(unsigned long *data,RC5_32_KEY *key);
+void RC5_32_decrypt(unsigned long *data,RC5_32_KEY *key);
+void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out,
+			long length, RC5_32_KEY *ks, unsigned char *iv,
+			int enc);
+void RC5_32_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+			  long length, RC5_32_KEY *schedule,
+			  unsigned char *ivec, int *num, int enc);
+void RC5_32_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+			  long length, RC5_32_KEY *schedule,
+			  unsigned char *ivec, int *num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/rc5/rc5_ecb.c b/openssl/crypto/rc5/rc5_ecb.c
new file mode 100644
index 0000000..e72b535
--- /dev/null
+++ b/openssl/crypto/rc5/rc5_ecb.c
@@ -0,0 +1,80 @@
+/* crypto/rc5/rc5_ecb.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc5.h>
+#include "rc5_locl.h"
+#include <openssl/opensslv.h>
+
+const char RC5_version[]="RC5" OPENSSL_VERSION_PTEXT;
+
+void RC5_32_ecb_encrypt(const unsigned char *in, unsigned char *out,
+			RC5_32_KEY *ks, int encrypt)
+	{
+	unsigned long l,d[2];
+
+	c2l(in,l); d[0]=l;
+	c2l(in,l); d[1]=l;
+	if (encrypt)
+		RC5_32_encrypt(d,ks);
+	else
+		RC5_32_decrypt(d,ks);
+	l=d[0]; l2c(l,out);
+	l=d[1]; l2c(l,out);
+	l=d[0]=d[1]=0;
+	}
+
diff --git a/openssl/crypto/rc5/rc5_enc.c b/openssl/crypto/rc5/rc5_enc.c
new file mode 100644
index 0000000..f327d32
--- /dev/null
+++ b/openssl/crypto/rc5/rc5_enc.c
@@ -0,0 +1,215 @@
+/* crypto/rc5/rc5_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/rc5.h>
+#include "rc5_locl.h"
+
+void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out,
+			long length, RC5_32_KEY *ks, unsigned char *iv,
+			int encrypt)
+	{
+	register unsigned long tin0,tin1;
+	register unsigned long tout0,tout1,xor0,xor1;
+	register long l=length;
+	unsigned long tin[2];
+
+	if (encrypt)
+		{
+		c2l(iv,tout0);
+		c2l(iv,tout1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0);
+			c2l(in,tin1);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			RC5_32_encrypt(tin,ks);
+			tout0=tin[0]; l2c(tout0,out);
+			tout1=tin[1]; l2c(tout1,out);
+			}
+		if (l != -8)
+			{
+			c2ln(in,tin0,tin1,l+8);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			RC5_32_encrypt(tin,ks);
+			tout0=tin[0]; l2c(tout0,out);
+			tout1=tin[1]; l2c(tout1,out);
+			}
+		l2c(tout0,iv);
+		l2c(tout1,iv);
+		}
+	else
+		{
+		c2l(iv,xor0);
+		c2l(iv,xor1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0); tin[0]=tin0;
+			c2l(in,tin1); tin[1]=tin1;
+			RC5_32_decrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2c(tout0,out);
+			l2c(tout1,out);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		if (l != -8)
+			{
+			c2l(in,tin0); tin[0]=tin0;
+			c2l(in,tin1); tin[1]=tin1;
+			RC5_32_decrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2cn(tout0,tout1,out,l+8);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		l2c(xor0,iv);
+		l2c(xor1,iv);
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	tin[0]=tin[1]=0;
+	}
+
+void RC5_32_encrypt(unsigned long *d, RC5_32_KEY *key)
+	{
+	RC5_32_INT a,b,*s;
+
+	s=key->data;
+
+	a=d[0]+s[0];
+	b=d[1]+s[1];
+	E_RC5_32(a,b,s, 2);
+	E_RC5_32(a,b,s, 4);
+	E_RC5_32(a,b,s, 6);
+	E_RC5_32(a,b,s, 8);
+	E_RC5_32(a,b,s,10);
+	E_RC5_32(a,b,s,12);
+	E_RC5_32(a,b,s,14);
+	E_RC5_32(a,b,s,16);
+	if (key->rounds == 12)
+		{
+		E_RC5_32(a,b,s,18);
+		E_RC5_32(a,b,s,20);
+		E_RC5_32(a,b,s,22);
+		E_RC5_32(a,b,s,24);
+		}
+	else if (key->rounds == 16)
+		{
+		/* Do a full expansion to avoid a jump */
+		E_RC5_32(a,b,s,18);
+		E_RC5_32(a,b,s,20);
+		E_RC5_32(a,b,s,22);
+		E_RC5_32(a,b,s,24);
+		E_RC5_32(a,b,s,26);
+		E_RC5_32(a,b,s,28);
+		E_RC5_32(a,b,s,30);
+		E_RC5_32(a,b,s,32);
+		}
+	d[0]=a;
+	d[1]=b;
+	}
+
+void RC5_32_decrypt(unsigned long *d, RC5_32_KEY *key)
+	{
+	RC5_32_INT a,b,*s;
+
+	s=key->data;
+
+	a=d[0];
+	b=d[1];
+	if (key->rounds == 16) 
+		{
+		D_RC5_32(a,b,s,32);
+		D_RC5_32(a,b,s,30);
+		D_RC5_32(a,b,s,28);
+		D_RC5_32(a,b,s,26);
+		/* Do a full expansion to avoid a jump */
+		D_RC5_32(a,b,s,24);
+		D_RC5_32(a,b,s,22);
+		D_RC5_32(a,b,s,20);
+		D_RC5_32(a,b,s,18);
+		}
+	else if (key->rounds == 12)
+		{
+		D_RC5_32(a,b,s,24);
+		D_RC5_32(a,b,s,22);
+		D_RC5_32(a,b,s,20);
+		D_RC5_32(a,b,s,18);
+		}
+	D_RC5_32(a,b,s,16);
+	D_RC5_32(a,b,s,14);
+	D_RC5_32(a,b,s,12);
+	D_RC5_32(a,b,s,10);
+	D_RC5_32(a,b,s, 8);
+	D_RC5_32(a,b,s, 6);
+	D_RC5_32(a,b,s, 4);
+	D_RC5_32(a,b,s, 2);
+	d[0]=a-s[0];
+	d[1]=b-s[1];
+	}
+
diff --git a/openssl/crypto/rc5/rc5_locl.h b/openssl/crypto/rc5/rc5_locl.h
new file mode 100644
index 0000000..d337f73
--- /dev/null
+++ b/openssl/crypto/rc5/rc5_locl.h
@@ -0,0 +1,207 @@
+/* crypto/rc5/rc5_locl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdlib.h>
+
+#undef c2l
+#define c2l(c,l)	(l =((unsigned long)(*((c)++)))    , \
+			 l|=((unsigned long)(*((c)++)))<< 8L, \
+			 l|=((unsigned long)(*((c)++)))<<16L, \
+			 l|=((unsigned long)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#undef c2ln
+#define c2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
+			case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
+			case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
+			case 5: l2|=((unsigned long)(*(--(c))));     \
+			case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
+			case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
+			case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
+			case 1: l1|=((unsigned long)(*(--(c))));     \
+				} \
+			}
+
+#undef l2c
+#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#undef l2cn
+#define l2cn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
+				} \
+			}
+
+/* NOTE - c is not incremented as per n2l */
+#define n2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))    ; \
+			case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
+			case 6: l2|=((unsigned long)(*(--(c))))<<16; \
+			case 5: l2|=((unsigned long)(*(--(c))))<<24; \
+			case 4: l1 =((unsigned long)(*(--(c))))    ; \
+			case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
+			case 2: l1|=((unsigned long)(*(--(c))))<<16; \
+			case 1: l1|=((unsigned long)(*(--(c))))<<24; \
+				} \
+			}
+
+/* NOTE - c is not incremented as per l2n */
+#define l2nn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+				} \
+			}
+
+#undef n2l
+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++))))
+
+#undef l2n
+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)     )&0xff))
+
+#if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)) || defined(__ICC)
+#define ROTATE_l32(a,n)     _lrotl(a,n)
+#define ROTATE_r32(a,n)     _lrotr(a,n)
+#elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
+# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+#  define ROTATE_l32(a,n)	({ register unsigned int ret;	\
+					asm ("roll %%cl,%0"	\
+						: "=r"(ret)	\
+						: "c"(n),"0"((unsigned int)(a))	\
+						: "cc");	\
+					ret;			\
+				})
+#  define ROTATE_r32(a,n)	({ register unsigned int ret;	\
+					asm ("rorl %%cl,%0"	\
+						: "=r"(ret)	\
+						: "c"(n),"0"((unsigned int)(a))	\
+						: "cc");	\
+					ret;			\
+				})
+# endif
+#endif
+#ifndef ROTATE_l32
+#define ROTATE_l32(a,n)     (((a)<<(n&0x1f))|(((a)&0xffffffff)>>(32-(n&0x1f))))
+#endif
+#ifndef ROTATE_r32
+#define ROTATE_r32(a,n)     (((a)<<(32-(n&0x1f)))|(((a)&0xffffffff)>>(n&0x1f)))
+#endif
+
+#define RC5_32_MASK	0xffffffffL
+
+#define RC5_16_P	0xB7E1
+#define RC5_16_Q	0x9E37
+#define RC5_32_P	0xB7E15163L
+#define RC5_32_Q	0x9E3779B9L
+#define RC5_64_P	0xB7E151628AED2A6BLL
+#define RC5_64_Q	0x9E3779B97F4A7C15LL
+
+#define E_RC5_32(a,b,s,n) \
+	a^=b; \
+	a=ROTATE_l32(a,b); \
+	a+=s[n]; \
+	a&=RC5_32_MASK; \
+	b^=a; \
+	b=ROTATE_l32(b,a); \
+	b+=s[n+1]; \
+	b&=RC5_32_MASK;
+
+#define D_RC5_32(a,b,s,n) \
+	b-=s[n+1]; \
+	b&=RC5_32_MASK; \
+	b=ROTATE_r32(b,a); \
+	b^=a; \
+	a-=s[n]; \
+	a&=RC5_32_MASK; \
+	a=ROTATE_r32(a,b); \
+	a^=b;
+
+
+
diff --git a/openssl/crypto/rc5/rc5_skey.c b/openssl/crypto/rc5/rc5_skey.c
new file mode 100644
index 0000000..a2e00a4
--- /dev/null
+++ b/openssl/crypto/rc5/rc5_skey.c
@@ -0,0 +1,113 @@
+/* crypto/rc5/rc5_skey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc5.h>
+#include "rc5_locl.h"
+
+void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data,
+		    int rounds)
+	{
+	RC5_32_INT L[64],l,ll,A,B,*S,k;
+	int i,j,m,c,t,ii,jj;
+
+	if (	(rounds != RC5_16_ROUNDS) &&
+		(rounds != RC5_12_ROUNDS) &&
+		(rounds != RC5_8_ROUNDS))
+		rounds=RC5_16_ROUNDS;
+
+	key->rounds=rounds;
+	S= &(key->data[0]);
+	j=0;
+	for (i=0; i<=(len-8); i+=8)
+		{
+		c2l(data,l);
+		L[j++]=l;
+		c2l(data,l);
+		L[j++]=l;
+		}
+	ii=len-i;
+	if (ii)
+		{
+		k=len&0x07;
+		c2ln(data,l,ll,k);
+		L[j+0]=l;
+		L[j+1]=ll;
+		}
+
+	c=(len+3)/4;
+	t=(rounds+1)*2;
+	S[0]=RC5_32_P;
+	for (i=1; i<t; i++)
+		S[i]=(S[i-1]+RC5_32_Q)&RC5_32_MASK;
+
+	j=(t>c)?t:c;
+	j*=3;
+	ii=jj=0;
+	A=B=0;
+	for (i=0; i<j; i++)
+		{
+		k=(S[ii]+A+B)&RC5_32_MASK;
+		A=S[ii]=ROTATE_l32(k,3);
+		m=(int)(A+B);
+		k=(L[jj]+A+B)&RC5_32_MASK;
+		B=L[jj]=ROTATE_l32(k,m);
+		if (++ii >= t) ii=0;
+		if (++jj >= c) jj=0;
+		}
+	}
+
diff --git a/openssl/crypto/rc5/rc5cfb64.c b/openssl/crypto/rc5/rc5cfb64.c
new file mode 100644
index 0000000..3a8b60b
--- /dev/null
+++ b/openssl/crypto/rc5/rc5cfb64.c
@@ -0,0 +1,122 @@
+/* crypto/rc5/rc5cfb64.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc5.h>
+#include "rc5_locl.h"
+
+/* The input and output encrypted as though 64bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+
+void RC5_32_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+			  long length, RC5_32_KEY *schedule,
+			  unsigned char *ivec, int *num, int encrypt)
+	{
+	register unsigned long v0,v1,t;
+	register int n= *num;
+	register long l=length;
+	unsigned long ti[2];
+	unsigned char *iv,c,cc;
+
+	iv=(unsigned char *)ivec;
+	if (encrypt)
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				c2l(iv,v0); ti[0]=v0;
+				c2l(iv,v1); ti[1]=v1;
+				RC5_32_encrypt((unsigned long *)ti,schedule);
+				iv=(unsigned char *)ivec;
+				t=ti[0]; l2c(t,iv);
+				t=ti[1]; l2c(t,iv);
+				iv=(unsigned char *)ivec;
+				}
+			c= *(in++)^iv[n];
+			*(out++)=c;
+			iv[n]=c;
+			n=(n+1)&0x07;
+			}
+		}
+	else
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				c2l(iv,v0); ti[0]=v0;
+				c2l(iv,v1); ti[1]=v1;
+				RC5_32_encrypt((unsigned long *)ti,schedule);
+				iv=(unsigned char *)ivec;
+				t=ti[0]; l2c(t,iv);
+				t=ti[1]; l2c(t,iv);
+				iv=(unsigned char *)ivec;
+				}
+			cc= *(in++);
+			c=iv[n];
+			iv[n]=cc;
+			*(out++)=c^cc;
+			n=(n+1)&0x07;
+			}
+		}
+	v0=v1=ti[0]=ti[1]=t=c=cc=0;
+	*num=n;
+	}
+
diff --git a/openssl/crypto/rc5/rc5ofb64.c b/openssl/crypto/rc5/rc5ofb64.c
new file mode 100644
index 0000000..d412215
--- /dev/null
+++ b/openssl/crypto/rc5/rc5ofb64.c
@@ -0,0 +1,111 @@
+/* crypto/rc5/rc5ofb64.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc5.h>
+#include "rc5_locl.h"
+
+/* The input and output encrypted as though 64bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+void RC5_32_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+			  long length, RC5_32_KEY *schedule,
+			  unsigned char *ivec, int *num)
+	{
+	register unsigned long v0,v1,t;
+	register int n= *num;
+	register long l=length;
+	unsigned char d[8];
+	register char *dp;
+	unsigned long ti[2];
+	unsigned char *iv;
+	int save=0;
+
+	iv=(unsigned char *)ivec;
+	c2l(iv,v0);
+	c2l(iv,v1);
+	ti[0]=v0;
+	ti[1]=v1;
+	dp=(char *)d;
+	l2c(v0,dp);
+	l2c(v1,dp);
+	while (l--)
+		{
+		if (n == 0)
+			{
+			RC5_32_encrypt((unsigned long *)ti,schedule);
+			dp=(char *)d;
+			t=ti[0]; l2c(t,dp);
+			t=ti[1]; l2c(t,dp);
+			save++;
+			}
+		*(out++)= *(in++)^d[n];
+		n=(n+1)&0x07;
+		}
+	if (save)
+		{
+		v0=ti[0];
+		v1=ti[1];
+		iv=(unsigned char *)ivec;
+		l2c(v0,iv);
+		l2c(v1,iv);
+		}
+	t=v0=v1=ti[0]=ti[1]=0;
+	*num=n;
+	}
+
diff --git a/openssl/crypto/rc5/rc5s.cpp b/openssl/crypto/rc5/rc5s.cpp
new file mode 100644
index 0000000..1c5518b
--- /dev/null
+++ b/openssl/crypto/rc5/rc5s.cpp
@@ -0,0 +1,70 @@
+//
+// gettsc.inl
+//
+// gives access to the Pentium's (secret) cycle counter
+//
+// This software was written by Leonard Janke (janke@unixg.ubc.ca)
+// in 1996-7 and is entered, by him, into the public domain.
+
+#if defined(__WATCOMC__)
+void GetTSC(unsigned long&);
+#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
+#elif defined(__GNUC__)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  asm volatile(".byte 15, 49\n\t"
+	       : "=eax" (tsc)
+	       :
+	       : "%edx", "%eax");
+}
+#elif defined(_MSC_VER)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  unsigned long a;
+  __asm _emit 0fh
+  __asm _emit 31h
+  __asm mov a, eax;
+  tsc=a;
+}
+#endif      
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/rc5.h>
+
+void main(int argc,char *argv[])
+	{
+	RC5_32_KEY key;
+	unsigned long s1,s2,e1,e2;
+	unsigned long data[2];
+	int i,j;
+	static unsigned char d[16]={0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF};
+
+	RC5_32_set_key(&key, 16,d,12);
+
+	for (j=0; j<6; j++)
+		{
+		for (i=0; i<1000; i++) /**/
+			{
+			RC5_32_encrypt(&data[0],&key);
+			GetTSC(s1);
+			RC5_32_encrypt(&data[0],&key);
+			RC5_32_encrypt(&data[0],&key);
+			RC5_32_encrypt(&data[0],&key);
+			GetTSC(e1);
+			GetTSC(s2);
+			RC5_32_encrypt(&data[0],&key);
+			RC5_32_encrypt(&data[0],&key);
+			RC5_32_encrypt(&data[0],&key);
+			RC5_32_encrypt(&data[0],&key);
+			GetTSC(e2);
+			RC5_32_encrypt(&data[0],&key);
+			}
+
+		printf("cast %d %d (%d)\n",
+			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
+		}
+	}
+
diff --git a/openssl/crypto/rc5/rc5speed.c b/openssl/crypto/rc5/rc5speed.c
new file mode 100644
index 0000000..8e363be
--- /dev/null
+++ b/openssl/crypto/rc5/rc5speed.c
@@ -0,0 +1,277 @@
+/* crypto/rc5/rc5speed.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
+/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
+
+#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
+#define TIMES
+#endif
+
+#include <stdio.h>
+
+#include <openssl/e_os2.h>
+#include OPENSSL_UNISTD_IO
+OPENSSL_DECLARE_EXIT
+
+#ifndef OPENSSL_SYS_NETWARE
+#include <signal.h>
+#endif
+
+#ifndef _IRIX
+#include <time.h>
+#endif
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+#endif
+
+/* Depending on the VMS version, the tms structure is perhaps defined.
+   The __TMS macro will show if it was.  If it wasn't defined, we should
+   undefine TIMES, since that tells the rest of the program how things
+   should be handled.				-- Richard Levitte */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
+#undef TIMES
+#endif
+
+#ifndef TIMES
+#include <sys/timeb.h>
+#endif
+
+#if defined(sun) || defined(__ultrix)
+#define _POSIX_SOURCE
+#include <limits.h>
+#include <sys/param.h>
+#endif
+
+#include <openssl/rc5.h>
+
+/* The following if from times(3) man page.  It may need to be changed */
+#ifndef HZ
+#ifndef CLK_TCK
+#define HZ	100.0
+#else /* CLK_TCK */
+#define HZ ((double)CLK_TCK)
+#endif
+#endif
+
+#define BUFSIZE	((long)1024)
+long run=0;
+
+double Time_F(int s);
+#ifdef SIGALRM
+#if defined(__STDC__) || defined(sgi) || defined(_AIX)
+#define SIGRETTYPE void
+#else
+#define SIGRETTYPE int
+#endif
+
+SIGRETTYPE sig_done(int sig);
+SIGRETTYPE sig_done(int sig)
+	{
+	signal(SIGALRM,sig_done);
+	run=0;
+#ifdef LINT
+	sig=sig;
+#endif
+	}
+#endif
+
+#define START	0
+#define STOP	1
+
+double Time_F(int s)
+	{
+	double ret;
+#ifdef TIMES
+	static struct tms tstart,tend;
+
+	if (s == START)
+		{
+		times(&tstart);
+		return(0);
+		}
+	else
+		{
+		times(&tend);
+		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#else /* !times() */
+	static struct timeb tstart,tend;
+	long i;
+
+	if (s == START)
+		{
+		ftime(&tstart);
+		return(0);
+		}
+	else
+		{
+		ftime(&tend);
+		i=(long)tend.millitm-(long)tstart.millitm;
+		ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
+		return((ret == 0.0)?1e-6:ret);
+		}
+#endif
+	}
+
+int main(int argc, char **argv)
+	{
+	long count;
+	static unsigned char buf[BUFSIZE];
+	static unsigned char key[] ={
+			0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+			0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
+			};
+	RC5_32_KEY sch;
+	double a,b,c,d;
+#ifndef SIGALRM
+	long ca,cb,cc;
+#endif
+
+#ifndef TIMES
+	printf("To get the most accurate results, try to run this\n");
+	printf("program when this computer is idle.\n");
+#endif
+
+#ifndef SIGALRM
+	printf("First we calculate the approximate speed ...\n");
+	RC5_32_set_key(&sch,16,key,12);
+	count=10;
+	do	{
+		long i;
+		unsigned long data[2];
+
+		count*=2;
+		Time_F(START);
+		for (i=count; i; i--)
+			RC5_32_encrypt(data,&sch);
+		d=Time_F(STOP);
+		} while (d < 3.0);
+	ca=count/512;
+	cb=count;
+	cc=count*8/BUFSIZE+1;
+	printf("Doing RC5_32_set_key %ld times\n",ca);
+#define COND(d)	(count != (d))
+#define COUNT(d) (d)
+#else
+#define COND(c)	(run)
+#define COUNT(d) (count)
+	signal(SIGALRM,sig_done);
+	printf("Doing RC5_32_set_key for 10 seconds\n");
+	alarm(10);
+#endif
+
+	Time_F(START);
+	for (count=0,run=1; COND(ca); count+=4)
+		{
+		RC5_32_set_key(&sch,16,key,12);
+		RC5_32_set_key(&sch,16,key,12);
+		RC5_32_set_key(&sch,16,key,12);
+		RC5_32_set_key(&sch,16,key,12);
+		}
+	d=Time_F(STOP);
+	printf("%ld RC5_32_set_key's in %.2f seconds\n",count,d);
+	a=((double)COUNT(ca))/d;
+
+#ifdef SIGALRM
+	printf("Doing RC5_32_encrypt's for 10 seconds\n");
+	alarm(10);
+#else
+	printf("Doing RC5_32_encrypt %ld times\n",cb);
+#endif
+	Time_F(START);
+	for (count=0,run=1; COND(cb); count+=4)
+		{
+		unsigned long data[2];
+
+		RC5_32_encrypt(data,&sch);
+		RC5_32_encrypt(data,&sch);
+		RC5_32_encrypt(data,&sch);
+		RC5_32_encrypt(data,&sch);
+		}
+	d=Time_F(STOP);
+	printf("%ld RC5_32_encrypt's in %.2f second\n",count,d);
+	b=((double)COUNT(cb)*8)/d;
+
+#ifdef SIGALRM
+	printf("Doing RC5_32_cbc_encrypt on %ld byte blocks for 10 seconds\n",
+		BUFSIZE);
+	alarm(10);
+#else
+	printf("Doing RC5_32_cbc_encrypt %ld times on %ld byte blocks\n",cc,
+		BUFSIZE);
+#endif
+	Time_F(START);
+	for (count=0,run=1; COND(cc); count++)
+		RC5_32_cbc_encrypt(buf,buf,BUFSIZE,&sch,
+			&(key[0]),RC5_ENCRYPT);
+	d=Time_F(STOP);
+	printf("%ld RC5_32_cbc_encrypt's of %ld byte blocks in %.2f second\n",
+		count,BUFSIZE,d);
+	c=((double)COUNT(cc)*BUFSIZE)/d;
+
+	printf("RC5_32/12/16 set_key       per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a);
+	printf("RC5_32/12/16 raw ecb bytes per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b);
+	printf("RC5_32/12/16 cbc     bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c);
+	exit(0);
+#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
+	return(0);
+#endif
+	}
diff --git a/openssl/crypto/rc5/rc5test.c b/openssl/crypto/rc5/rc5test.c
new file mode 100644
index 0000000..ce3d0cc
--- /dev/null
+++ b/openssl/crypto/rc5/rc5test.c
@@ -0,0 +1,386 @@
+/* crypto/rc5/rc5test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* This has been a quickly hacked 'ideatest.c'.  When I add tests for other
+ * RC5 modes, more of the code will be uncommented. */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_RC5
+int main(int argc, char *argv[])
+{
+    printf("No RC5 support\n");
+    return(0);
+}
+#else
+#include <openssl/rc5.h>
+
+static unsigned char RC5key[5][16]={
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x91,0x5f,0x46,0x19,0xbe,0x41,0xb2,0x51,
+	 0x63,0x55,0xa5,0x01,0x10,0xa9,0xce,0x91},
+	{0x78,0x33,0x48,0xe7,0x5a,0xeb,0x0f,0x2f,
+	 0xd7,0xb1,0x69,0xbb,0x8d,0xc1,0x67,0x87},
+	{0xdc,0x49,0xdb,0x13,0x75,0xa5,0x58,0x4f,
+	 0x64,0x85,0xb4,0x13,0xb5,0xf1,0x2b,0xaf},
+	{0x52,0x69,0xf1,0x49,0xd4,0x1b,0xa0,0x15,
+	 0x24,0x97,0x57,0x4d,0x7f,0x15,0x31,0x25},
+	};
+
+static unsigned char RC5plain[5][8]={
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x21,0xA5,0xDB,0xEE,0x15,0x4B,0x8F,0x6D},
+	{0xF7,0xC0,0x13,0xAC,0x5B,0x2B,0x89,0x52},
+	{0x2F,0x42,0xB3,0xB7,0x03,0x69,0xFC,0x92},
+	{0x65,0xC1,0x78,0xB2,0x84,0xD1,0x97,0xCC},
+	};
+
+static unsigned char RC5cipher[5][8]={
+	{0x21,0xA5,0xDB,0xEE,0x15,0x4B,0x8F,0x6D},
+	{0xF7,0xC0,0x13,0xAC,0x5B,0x2B,0x89,0x52},
+	{0x2F,0x42,0xB3,0xB7,0x03,0x69,0xFC,0x92},
+	{0x65,0xC1,0x78,0xB2,0x84,0xD1,0x97,0xCC},
+	{0xEB,0x44,0xE4,0x15,0xDA,0x31,0x98,0x24},
+	};
+
+#define RC5_CBC_NUM 27
+static unsigned char rc5_cbc_cipher[RC5_CBC_NUM][8]={
+	{0x7a,0x7b,0xba,0x4d,0x79,0x11,0x1d,0x1e},
+	{0x79,0x7b,0xba,0x4d,0x78,0x11,0x1d,0x1e},
+	{0x7a,0x7b,0xba,0x4d,0x79,0x11,0x1d,0x1f},
+	{0x7a,0x7b,0xba,0x4d,0x79,0x11,0x1d,0x1f},
+	{0x8b,0x9d,0xed,0x91,0xce,0x77,0x94,0xa6},
+	{0x2f,0x75,0x9f,0xe7,0xad,0x86,0xa3,0x78},
+	{0xdc,0xa2,0x69,0x4b,0xf4,0x0e,0x07,0x88},
+	{0xdc,0xa2,0x69,0x4b,0xf4,0x0e,0x07,0x88},
+	{0xdc,0xfe,0x09,0x85,0x77,0xec,0xa5,0xff},
+	{0x96,0x46,0xfb,0x77,0x63,0x8f,0x9c,0xa8},
+	{0xb2,0xb3,0x20,0x9d,0xb6,0x59,0x4d,0xa4},
+	{0x54,0x5f,0x7f,0x32,0xa5,0xfc,0x38,0x36},
+	{0x82,0x85,0xe7,0xc1,0xb5,0xbc,0x74,0x02},
+	{0xfc,0x58,0x6f,0x92,0xf7,0x08,0x09,0x34},
+	{0xcf,0x27,0x0e,0xf9,0x71,0x7f,0xf7,0xc4},
+	{0xe4,0x93,0xf1,0xc1,0xbb,0x4d,0x6e,0x8c},
+	{0x5c,0x4c,0x04,0x1e,0x0f,0x21,0x7a,0xc3},
+	{0x92,0x1f,0x12,0x48,0x53,0x73,0xb4,0xf7},
+	{0x5b,0xa0,0xca,0x6b,0xbe,0x7f,0x5f,0xad},
+	{0xc5,0x33,0x77,0x1c,0xd0,0x11,0x0e,0x63},
+	{0x29,0x4d,0xdb,0x46,0xb3,0x27,0x8d,0x60},
+	{0xda,0xd6,0xbd,0xa9,0xdf,0xe8,0xf7,0xe8},
+	{0x97,0xe0,0x78,0x78,0x37,0xed,0x31,0x7f},
+	{0x78,0x75,0xdb,0xf6,0x73,0x8c,0x64,0x78},
+	{0x8f,0x34,0xc3,0xc6,0x81,0xc9,0x96,0x95},
+	{0x7c,0xb3,0xf1,0xdf,0x34,0xf9,0x48,0x11},
+	{0x7f,0xd1,0xa0,0x23,0xa5,0xbb,0xa2,0x17},
+	};
+
+static unsigned char rc5_cbc_key[RC5_CBC_NUM][17]={
+	{ 1,0x00},
+	{ 1,0x00},
+	{ 1,0x00},
+	{ 1,0x00},
+	{ 1,0x00},
+	{ 1,0x11},
+	{ 1,0x00},
+	{ 4,0x00,0x00,0x00,0x00},
+	{ 1,0x00},
+	{ 1,0x00},
+	{ 1,0x00},
+	{ 1,0x00},
+	{ 4,0x01,0x02,0x03,0x04},
+	{ 4,0x01,0x02,0x03,0x04},
+	{ 4,0x01,0x02,0x03,0x04},
+	{ 8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
+	{ 8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
+	{ 8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
+	{ 8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
+	{16,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
+	    0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
+	{16,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
+	    0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
+	{16,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
+	    0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
+	{ 5,0x01,0x02,0x03,0x04,0x05},
+	{ 5,0x01,0x02,0x03,0x04,0x05},
+	{ 5,0x01,0x02,0x03,0x04,0x05},
+	{ 5,0x01,0x02,0x03,0x04,0x05},
+	{ 5,0x01,0x02,0x03,0x04,0x05},
+	};
+
+static unsigned char rc5_cbc_plain[RC5_CBC_NUM][8]={
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
+	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
+	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
+	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
+	{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
+	{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
+	{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
+	{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
+	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
+	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
+	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
+	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
+	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
+	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
+	{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
+	{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
+	{0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x01},
+	};
+
+static int rc5_cbc_rounds[RC5_CBC_NUM]={
+	 0, 0, 0, 0, 0, 1, 2, 2,
+	 8, 8,12,16, 8,12,16,12,
+	 8,12,16, 8,12,16,12, 8,
+	 8, 8, 8,
+	};
+
+static unsigned char rc5_cbc_iv[RC5_CBC_NUM][8]={
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
+	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
+	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
+	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
+	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
+	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
+	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
+	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x78,0x75,0xdb,0xf6,0x73,0x8c,0x64,0x78},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x7c,0xb3,0xf1,0xdf,0x34,0xf9,0x48,0x11},
+	};
+
+int main(int argc, char *argv[])
+	{
+	int i,n,err=0;
+	RC5_32_KEY key; 
+	unsigned char buf[8],buf2[8],ivb[8];
+
+	for (n=0; n<5; n++)
+		{
+		RC5_32_set_key(&key,16,&(RC5key[n][0]),12);
+
+		RC5_32_ecb_encrypt(&(RC5plain[n][0]),buf,&key,RC5_ENCRYPT);
+		if (memcmp(&(RC5cipher[n][0]),buf,8) != 0)
+			{
+			printf("ecb RC5 error encrypting (%d)\n",n+1);
+			printf("got     :");
+			for (i=0; i<8; i++)
+				printf("%02X ",buf[i]);
+			printf("\n");
+			printf("expected:");
+			for (i=0; i<8; i++)
+				printf("%02X ",RC5cipher[n][i]);
+			err=20;
+			printf("\n");
+			}
+
+		RC5_32_ecb_encrypt(buf,buf2,&key,RC5_DECRYPT);
+		if (memcmp(&(RC5plain[n][0]),buf2,8) != 0)
+			{
+			printf("ecb RC5 error decrypting (%d)\n",n+1);
+			printf("got     :");
+			for (i=0; i<8; i++)
+				printf("%02X ",buf2[i]);
+			printf("\n");
+			printf("expected:");
+			for (i=0; i<8; i++)
+				printf("%02X ",RC5plain[n][i]);
+			printf("\n");
+			err=3;
+			}
+		}
+	if (err == 0) printf("ecb RC5 ok\n");
+
+	for (n=0; n<RC5_CBC_NUM; n++)
+		{
+		i=rc5_cbc_rounds[n];
+		if (i < 8) continue;
+
+		RC5_32_set_key(&key,rc5_cbc_key[n][0],&(rc5_cbc_key[n][1]),i);
+
+		memcpy(ivb,&(rc5_cbc_iv[n][0]),8);
+		RC5_32_cbc_encrypt(&(rc5_cbc_plain[n][0]),buf,8,
+			&key,&(ivb[0]),RC5_ENCRYPT);
+
+		if (memcmp(&(rc5_cbc_cipher[n][0]),buf,8) != 0)
+			{
+			printf("cbc RC5 error encrypting (%d)\n",n+1);
+			printf("got     :");
+			for (i=0; i<8; i++)
+				printf("%02X ",buf[i]);
+			printf("\n");
+			printf("expected:");
+			for (i=0; i<8; i++)
+				printf("%02X ",rc5_cbc_cipher[n][i]);
+			err=30;
+			printf("\n");
+			}
+
+		memcpy(ivb,&(rc5_cbc_iv[n][0]),8);
+		RC5_32_cbc_encrypt(buf,buf2,8,
+			&key,&(ivb[0]),RC5_DECRYPT);
+		if (memcmp(&(rc5_cbc_plain[n][0]),buf2,8) != 0)
+			{
+			printf("cbc RC5 error decrypting (%d)\n",n+1);
+			printf("got     :");
+			for (i=0; i<8; i++)
+				printf("%02X ",buf2[i]);
+			printf("\n");
+			printf("expected:");
+			for (i=0; i<8; i++)
+				printf("%02X ",rc5_cbc_plain[n][i]);
+			printf("\n");
+			err=3;
+			}
+		}
+	if (err == 0) printf("cbc RC5 ok\n");
+
+	EXIT(err);
+	return(err);
+	}
+
+#ifdef undef
+static int cfb64_test(unsigned char *cfb_cipher)
+        {
+        IDEA_KEY_SCHEDULE eks,dks;
+        int err=0,i,n;
+
+        idea_set_encrypt_key(cfb_key,&eks);
+        idea_set_decrypt_key(&eks,&dks);
+        memcpy(cfb_tmp,cfb_iv,8);
+        n=0;
+        idea_cfb64_encrypt(plain,cfb_buf1,(long)12,&eks,
+                cfb_tmp,&n,IDEA_ENCRYPT);
+        idea_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
+                (long)CFB_TEST_SIZE-12,&eks,
+                cfb_tmp,&n,IDEA_ENCRYPT);
+        if (memcmp(cfb_cipher,cfb_buf1,CFB_TEST_SIZE) != 0)
+                {
+                err=1;
+                printf("idea_cfb64_encrypt encrypt error\n");
+                for (i=0; i<CFB_TEST_SIZE; i+=8)
+                        printf("%s\n",pt(&(cfb_buf1[i])));
+                }
+        memcpy(cfb_tmp,cfb_iv,8);
+        n=0;
+        idea_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,&eks,
+                cfb_tmp,&n,IDEA_DECRYPT);
+        idea_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
+                (long)CFB_TEST_SIZE-17,&dks,
+                cfb_tmp,&n,IDEA_DECRYPT);
+        if (memcmp(plain,cfb_buf2,CFB_TEST_SIZE) != 0)
+                {
+                err=1;
+                printf("idea_cfb_encrypt decrypt error\n");
+                for (i=0; i<24; i+=8)
+                        printf("%s\n",pt(&(cfb_buf2[i])));
+                }
+        return(err);
+        }
+
+static char *pt(unsigned char *p)
+	{
+	static char bufs[10][20];
+	static int bnum=0;
+	char *ret;
+	int i;
+	static char *f="0123456789ABCDEF";
+
+	ret= &(bufs[bnum++][0]);
+	bnum%=10;
+	for (i=0; i<8; i++)
+		{
+		ret[i*2]=f[(p[i]>>4)&0xf];
+		ret[i*2+1]=f[p[i]&0xf];
+		}
+	ret[16]='\0';
+	return(ret);
+	}
+	
+#endif
+#endif
diff --git a/openssl/crypto/ripemd/Makefile b/openssl/crypto/ripemd/Makefile
new file mode 100644
index 0000000..d5b1067
--- /dev/null
+++ b/openssl/crypto/ripemd/Makefile
@@ -0,0 +1,92 @@
+#
+# OpenSSL/crypto/ripemd/Makefile
+#
+
+DIR=    ripemd
+TOP=    ../..
+CC=     cc
+CPP=    $(CC) -E
+INCLUDES=
+CFLAG=-g
+MAKEFILE=       Makefile
+AR=             ar r
+
+RIP_ASM_OBJ=
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+ASFLAGS= $(INCLUDES) $(ASFLAG)
+AFLAGS= $(ASFLAGS)
+
+GENERAL=Makefile
+TEST=rmdtest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=rmd_dgst.c rmd_one.c
+LIBOBJ=rmd_dgst.o rmd_one.o $(RMD160_ASM_OBJ)
+
+SRC= $(LIBSRC)
+
+EXHEADER= ripemd.h
+HEADER= rmd_locl.h rmdconst.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:    lib
+
+lib:    $(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+rmd-586.s:	asm/rmd-586.pl ../perlasm/x86asm.pl
+	$(PERL) asm/rmd-586.pl $(PERLASM_SCHEME) $(CFLAGS) > $@
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+rmd_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+rmd_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ripemd.h
+rmd_dgst.o: ../md32_common.h rmd_dgst.c rmd_locl.h rmdconst.h
+rmd_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+rmd_one.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+rmd_one.o: ../../include/openssl/ossl_typ.h ../../include/openssl/ripemd.h
+rmd_one.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+rmd_one.o: ../../include/openssl/symhacks.h rmd_one.c
diff --git a/openssl/crypto/ripemd/README b/openssl/crypto/ripemd/README
new file mode 100644
index 0000000..f1ffc8b
--- /dev/null
+++ b/openssl/crypto/ripemd/README
@@ -0,0 +1,15 @@
+RIPEMD-160
+http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
+
+This is my implementation of RIPEMD-160.  The pentium assember is a little
+off the pace since I only get 1050 cycles, while the best is 1013.
+I have a few ideas for how to get another 20 or so cycles, but at
+this point I will not bother right now.  I believe the trick will be
+to remove my 'copy X array onto stack' until inside the RIP1() finctions the
+first time round.  To do this I need another register and will only have one
+temporary one.  A bit tricky....  I can also cleanup the saving of the 5 words
+after the first half of the calculation.  I should read the origional
+value, add then write.  Currently I just save the new and read the origioal.
+I then read both at the end.  Bad.
+
+eric (20-Jan-1998)
diff --git a/openssl/crypto/ripemd/asm/rips.cpp b/openssl/crypto/ripemd/asm/rips.cpp
new file mode 100644
index 0000000..f7a1367
--- /dev/null
+++ b/openssl/crypto/ripemd/asm/rips.cpp
@@ -0,0 +1,82 @@
+//
+// gettsc.inl
+//
+// gives access to the Pentium's (secret) cycle counter
+//
+// This software was written by Leonard Janke (janke@unixg.ubc.ca)
+// in 1996-7 and is entered, by him, into the public domain.
+
+#if defined(__WATCOMC__)
+void GetTSC(unsigned long&);
+#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
+#elif defined(__GNUC__)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  asm volatile(".byte 15, 49\n\t"
+	       : "=eax" (tsc)
+	       :
+	       : "%edx", "%eax");
+}
+#elif defined(_MSC_VER)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  unsigned long a;
+  __asm _emit 0fh
+  __asm _emit 31h
+  __asm mov a, eax;
+  tsc=a;
+}
+#endif      
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/ripemd.h>
+
+#define ripemd160_block_x86 ripemd160_block_asm_host_order
+
+extern "C" {
+void ripemd160_block_x86(RIPEMD160_CTX *ctx, unsigned char *buffer,int num);
+}
+
+void main(int argc,char *argv[])
+	{
+	unsigned char buffer[64*256];
+	RIPEMD160_CTX ctx;
+	unsigned long s1,s2,e1,e2;
+	unsigned char k[16];
+	unsigned long data[2];
+	unsigned char iv[8];
+	int i,num=0,numm;
+	int j=0;
+
+	if (argc >= 2)
+		num=atoi(argv[1]);
+
+	if (num == 0) num=16;
+	if (num > 250) num=16;
+	numm=num+2;
+#if 0
+	num*=64;
+	numm*=64;
+#endif
+
+	for (j=0; j<6; j++)
+		{
+		for (i=0; i<10; i++) /**/
+			{
+			ripemd160_block_x86(&ctx,buffer,numm);
+			GetTSC(s1);
+			ripemd160_block_x86(&ctx,buffer,numm);
+			GetTSC(e1);
+			GetTSC(s2);
+			ripemd160_block_x86(&ctx,buffer,num);
+			GetTSC(e2);
+			ripemd160_block_x86(&ctx,buffer,num);
+			}
+		printf("ripemd160 (%d bytes) %d %d (%.2f)\n",num*64,
+			e1-s1,e2-s2,(double)((e1-s1)-(e2-s2))/2);
+		}
+	}
+
diff --git a/openssl/crypto/ripemd/asm/rmd-586.pl b/openssl/crypto/ripemd/asm/rmd-586.pl
new file mode 100644
index 0000000..e8b2bc2
--- /dev/null
+++ b/openssl/crypto/ripemd/asm/rmd-586.pl
@@ -0,0 +1,591 @@
+#!/usr/local/bin/perl
+
+# Normal is the
+# ripemd160_block_asm_data_order(RIPEMD160_CTX *c, ULONG *X,int blocks);
+
+$normal=0;
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],$0);
+
+$A="ecx";
+$B="esi";
+$C="edi";
+$D="ebx";
+$E="ebp";
+$tmp1="eax";
+$tmp2="edx";
+
+$KL1=0x5A827999;
+$KL2=0x6ED9EBA1;
+$KL3=0x8F1BBCDC;
+$KL4=0xA953FD4E;
+$KR0=0x50A28BE6;
+$KR1=0x5C4DD124; 
+$KR2=0x6D703EF3;
+$KR3=0x7A6D76E9;
+
+
+@wl=(	 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
+	 7, 4,13, 1,10, 6,15, 3,12, 0, 9, 5, 2,14,11, 8,
+	 3,10,14, 4, 9,15, 8, 1, 2, 7, 0, 6,13,11, 5,12,
+	 1, 9,11,10, 0, 8,12, 4,13, 3, 7,15,14, 5, 6, 2,
+	 4, 0, 5, 9, 7,12, 2,10,14, 1, 3, 8,11, 6,15,13,
+	 );
+
+@wr=(	 5,14, 7, 0, 9, 2,11, 4,13, 6,15, 8, 1,10, 3,12,
+	 6,11, 3, 7, 0,13, 5,10,14,15, 8,12, 4, 9, 1, 2,
+	15, 5, 1, 3, 7,14, 6, 9,11, 8,12, 2,10, 0, 4,13,
+	 8, 6, 4, 1, 3,11,15, 0, 5,12, 2,13, 9, 7,10,14,
+	12,15,10, 4, 1, 5, 8, 7, 6, 2,13,14, 0, 3, 9,11,
+	);
+
+@sl=(	11,14,15,12, 5, 8, 7, 9,11,13,14,15, 6, 7, 9, 8,
+	 7, 6, 8,13,11, 9, 7,15, 7,12,15, 9,11, 7,13,12,
+	11,13, 6, 7,14, 9,13,15,14, 8,13, 6, 5,12, 7, 5,
+	11,12,14,15,14,15, 9, 8, 9,14, 5, 6, 8, 6, 5,12,
+	 9,15, 5,11, 6, 8,13,12, 5,12,13,14,11, 8, 5, 6,
+	 );
+
+@sr=(	 8, 9, 9,11,13,15,15, 5, 7, 7, 8,11,14,14,12, 6,
+	 9,13,15, 7,12, 8, 9,11, 7, 7,12, 7, 6,15,13,11,
+	 9, 7,15,11, 8, 6, 6,14,12,13, 5,14,13,13, 7, 5,
+	15, 5, 8,11,14,14, 6,14, 6, 9,12, 9,12, 5,15, 8,
+	 8, 5,12, 9,12, 5,14, 6, 8,13, 6, 5,15,13,11,11,
+ 	);
+
+&ripemd160_block("ripemd160_block_asm_data_order");
+&asm_finish();
+
+sub Xv
+	{
+	local($n)=@_;
+	return(&swtmp($n));
+	# tmp on stack
+	}
+
+sub Np
+	{
+	local($p)=@_;
+	local(%n)=($A,$E,$B,$A,$C,$B,$D,$C,$E,$D);
+	return($n{$p});
+	}
+
+sub RIP1
+	{
+	local($a,$b,$c,$d,$e,$pos,$s,$o,$pos2)=@_;
+
+	&comment($p++);
+	if ($p & 1)
+		{
+	 #&mov($tmp1,	$c) if $o == -1;
+	&xor($tmp1,	$d) if $o == -1;
+	 &mov($tmp2,	&Xv($pos));
+	&xor($tmp1,	$b);
+	 &add($a,	$tmp2);
+	&rotl($c,	10);
+	&add($a,	$tmp1);
+	 &mov($tmp1,	&Np($c));	# NEXT
+	 # XXX
+	&rotl($a,	$s);
+	&add($a,	$e);
+		}
+	else
+		{
+	 &xor($tmp1,	$d);
+	&mov($tmp2,	&Xv($pos));
+	 &xor($tmp1,	$b);
+	&add($a,	$tmp1);
+	 &mov($tmp1,	&Np($c)) if $o <= 0;
+	 &mov($tmp1,	-1) if $o == 1;
+	 # XXX if $o == 2;
+	&rotl($c,	10);
+	&add($a,	$tmp2);
+	 &xor($tmp1,	&Np($d)) if $o <= 0;
+	 &mov($tmp2,	&Xv($pos2)) if $o == 1;
+	 &mov($tmp2,	&wparam(0)) if $o == 2;
+	&rotl($a,	$s);
+	&add($a,	$e);
+		}
+	}
+
+sub RIP2
+	{
+	local($a,$b,$c,$d,$e,$pos,$pos2,$s,$K,$o)=@_;
+
+# XXXXXX
+	&comment($p++);
+	if ($p & 1)
+		{
+#	 &mov($tmp2,	&Xv($pos)) if $o < -1;
+#	&mov($tmp1,	-1) if $o < -1;
+
+	 &add($a,	$tmp2);
+	&mov($tmp2,	$c);
+	 &sub($tmp1,	$b);
+	&and($tmp2,	$b);
+	 &and($tmp1,	$d);
+	&or($tmp2,	$tmp1);
+	 &mov($tmp1,	&Xv($pos2)) if $o <= 0; # XXXXXXXXXXXXXX
+	 # XXX
+	&rotl($c,	10);
+	&lea($a,	&DWP($K,$a,$tmp2,1));
+	 &mov($tmp2,	-1) if $o <= 0;
+	 # XXX
+	&rotl($a,	$s);
+	&add($a,	$e);
+		}
+	else
+		{
+	 # XXX
+	 &add($a,	$tmp1);
+	&mov($tmp1,	$c);
+	 &sub($tmp2,	$b);
+	&and($tmp1,	$b);
+	 &and($tmp2,	$d);
+	if ($o != 2)
+		{
+	&or($tmp1,	$tmp2);
+	 &mov($tmp2,	&Xv($pos2)) if $o <= 0;
+	 &mov($tmp2,	-1) if $o == 1;
+	&rotl($c,	10);
+	&lea($a,	&DWP($K,$a,$tmp1,1));
+	 &mov($tmp1,	-1) if $o <= 0;
+	 &sub($tmp2,	&Np($c)) if $o == 1;
+		} else {
+	&or($tmp2,	$tmp1);
+	 &mov($tmp1,	&Np($c));
+	&rotl($c,	10);
+	&lea($a,	&DWP($K,$a,$tmp2,1));
+	 &xor($tmp1,	&Np($d));
+		}
+	&rotl($a,	$s);
+	&add($a,	$e);
+		}
+	}
+
+sub RIP3
+	{
+	local($a,$b,$c,$d,$e,$pos,$s,$K,$o,$pos2)=@_;
+
+	&comment($p++);
+	if ($p & 1)
+		{
+#	 &mov($tmp2,	-1) if $o < -1;
+#	&sub($tmp2,	$c) if $o < -1;
+	 &mov($tmp1,	&Xv($pos));
+	&or($tmp2,	$b);
+	 &add($a,	$tmp1);
+	&xor($tmp2,	$d);
+	 &mov($tmp1,	-1) if $o <= 0;		# NEXT
+	 # XXX
+	&rotl($c,	10);
+	&lea($a,	&DWP($K,$a,$tmp2,1));
+	 &sub($tmp1,	&Np($c)) if $o <= 0;	# NEXT
+	 # XXX
+	&rotl($a,	$s);
+	&add($a,	$e);
+		}
+	else
+		{
+	 &mov($tmp2,	&Xv($pos));
+	&or($tmp1,	$b);
+	 &add($a,	$tmp2);
+	&xor($tmp1,	$d);
+	 &mov($tmp2,	-1) if $o <= 0;		# NEXT
+	 &mov($tmp2,	-1) if $o == 1;
+	 &mov($tmp2,	&Xv($pos2)) if $o == 2;
+	&rotl($c,	10);
+	&lea($a,	&DWP($K,$a,$tmp1,1));
+	 &sub($tmp2,	&Np($c)) if $o <= 0;	# NEXT
+	 &mov($tmp1,	&Np($d)) if $o == 1;
+	 &mov($tmp1,	-1) if $o == 2;
+	&rotl($a,	$s);
+	&add($a,	$e);
+		}
+	}
+
+sub RIP4
+	{
+	local($a,$b,$c,$d,$e,$pos,$s,$K,$o)=@_;
+
+	&comment($p++);
+	if ($p & 1)
+		{
+#	 &mov($tmp2,	-1) if $o == -2;
+#	&mov($tmp1,	$d) if $o == -2;
+	 &sub($tmp2,	$d);
+	&and($tmp1,	$b);
+	 &and($tmp2,	$c);
+	&or($tmp2,	$tmp1);
+	 &mov($tmp1,	&Xv($pos));
+	&rotl($c,	10);
+	&lea($a,	&DWP($K,$a,$tmp2));
+	 &mov($tmp2,	-1) unless $o > 0;	# NEXT
+	 # XXX
+	&add($a,	$tmp1);
+	 &mov($tmp1,	&Np($d)) unless $o > 0; # NEXT
+	 # XXX
+	&rotl($a,	$s);
+	&add($a,	$e);
+		}
+	else
+		{
+	 &sub($tmp2,	$d);
+	&and($tmp1,	$b);
+	 &and($tmp2,	$c);
+	&or($tmp2,	$tmp1);
+	 &mov($tmp1,	&Xv($pos));
+	&rotl($c,	10);
+	&lea($a,	&DWP($K,$a,$tmp2));
+	 &mov($tmp2,	-1) if $o == 0;	# NEXT
+	 &mov($tmp2,	-1) if $o == 1;
+	 &mov($tmp2,	-1) if $o == 2;
+	 # XXX
+	&add($a,	$tmp1);
+	 &mov($tmp1,	&Np($d)) if $o == 0;	# NEXT
+	 &sub($tmp2,	&Np($d)) if $o == 1;
+	 &sub($tmp2,	&Np($c)) if $o == 2;
+	 # XXX
+	&rotl($a,	$s);
+	&add($a,	$e);
+		}
+	}
+
+sub RIP5
+	{
+	local($a,$b,$c,$d,$e,$pos,$s,$K,$o)=@_;
+
+	&comment($p++);
+	if ($p & 1)
+		{
+	 &mov($tmp2,	-1) if $o == -2;
+	&sub($tmp2,	$d) if $o == -2;
+	 &mov($tmp1,	&Xv($pos));
+	&or($tmp2,	$c);
+	 &add($a,	$tmp1);
+	&xor($tmp2,	$b);
+	 &mov($tmp1,	-1) if $o <= 0;
+	 # XXX
+	&rotl($c,	10);
+	&lea($a,	&DWP($K,$a,$tmp2,1));
+	 &sub($tmp1,	&Np($d)) if $o <= 0;
+	 # XXX
+	&rotl($a,	$s);
+	&add($a,	$e);
+		}
+	else
+		{
+	 &mov($tmp2,	&Xv($pos));
+	&or($tmp1,	$c);
+	 &add($a,	$tmp2);
+	&xor($tmp1,	$b);
+	 &mov($tmp2,	-1) if $o <= 0;
+	 &mov($tmp2,	&wparam(0)) if $o == 1;	# Middle code
+	 &mov($tmp2,	-1) if $o == 2;
+	&rotl($c,	10);
+	&lea($a,	&DWP($K,$a,$tmp1,1));
+	 &sub($tmp2,	&Np($d)) if $o <= 0;
+	 &mov(&swtmp(16),	$A) if $o == 1;
+	 &mov($tmp1,	&Np($d)) if $o == 2;
+	&rotl($a,	$s);
+	&add($a,	$e);
+		}
+	}
+
+sub ripemd160_block
+	{
+	local($name)=@_;
+
+	&function_begin_B($name,"",3);
+
+	# parameter 1 is the RIPEMD160_CTX structure.
+	# A	0
+	# B	4
+	# C	8
+	# D 	12
+	# E 	16
+
+	&mov($tmp2,	&wparam(0));
+	 &mov($tmp1,	&wparam(1));
+	&push("esi");
+	 &mov($A,	&DWP( 0,$tmp2,"",0));
+	&push("edi");
+	 &mov($B,	&DWP( 4,$tmp2,"",0));
+	&push("ebp");
+	 &mov($C,	&DWP( 8,$tmp2,"",0));
+	&push("ebx");
+	 &stack_push(16+5+6);
+			  # Special comment about the figure of 6.
+			  # Idea is to pad the current frame so
+			  # that the top of the stack gets fairly
+			  # aligned. Well, as you realize it would
+			  # always depend on how the frame below is
+			  # aligned. The good news are that gcc-2.95
+			  # and later does keep first argument at
+			  # least double-wise aligned.
+			  #			<appro@fy.chalmers.se>
+
+	&set_label("start") unless $normal;
+	&comment("");
+
+	# &mov($tmp1,	&wparam(1)); # Done at end of loop
+	# &mov($tmp2,	&wparam(0)); # Done at end of loop
+
+	for ($z=0; $z<16; $z+=2)
+		{
+		&mov($D,		&DWP( $z*4,$tmp1,"",0));
+		 &mov($E,		&DWP( ($z+1)*4,$tmp1,"",0));
+		&mov(&swtmp($z),	$D);
+		 &mov(&swtmp($z+1),	$E);
+		}
+	&mov($tmp1,	$C);
+	 &mov($D,	&DWP(12,$tmp2,"",0));
+	&mov($E,	&DWP(16,$tmp2,"",0));
+
+	&RIP1($A,$B,$C,$D,$E,$wl[ 0],$sl[ 0],-1);
+	&RIP1($E,$A,$B,$C,$D,$wl[ 1],$sl[ 1],0);
+	&RIP1($D,$E,$A,$B,$C,$wl[ 2],$sl[ 2],0);
+	&RIP1($C,$D,$E,$A,$B,$wl[ 3],$sl[ 3],0);
+	&RIP1($B,$C,$D,$E,$A,$wl[ 4],$sl[ 4],0);
+	&RIP1($A,$B,$C,$D,$E,$wl[ 5],$sl[ 5],0);
+	&RIP1($E,$A,$B,$C,$D,$wl[ 6],$sl[ 6],0);
+	&RIP1($D,$E,$A,$B,$C,$wl[ 7],$sl[ 7],0);
+	&RIP1($C,$D,$E,$A,$B,$wl[ 8],$sl[ 8],0);
+	&RIP1($B,$C,$D,$E,$A,$wl[ 9],$sl[ 9],0);
+	&RIP1($A,$B,$C,$D,$E,$wl[10],$sl[10],0);
+	&RIP1($E,$A,$B,$C,$D,$wl[11],$sl[11],0);
+	&RIP1($D,$E,$A,$B,$C,$wl[12],$sl[12],0);
+	&RIP1($C,$D,$E,$A,$B,$wl[13],$sl[13],0);
+	&RIP1($B,$C,$D,$E,$A,$wl[14],$sl[14],0);
+	&RIP1($A,$B,$C,$D,$E,$wl[15],$sl[15],1,$wl[16]);
+
+	&RIP2($E,$A,$B,$C,$D,$wl[16],$wl[17],$sl[16],$KL1,-1);
+	&RIP2($D,$E,$A,$B,$C,$wl[17],$wl[18],$sl[17],$KL1,0);
+	&RIP2($C,$D,$E,$A,$B,$wl[18],$wl[19],$sl[18],$KL1,0);
+	&RIP2($B,$C,$D,$E,$A,$wl[19],$wl[20],$sl[19],$KL1,0);
+	&RIP2($A,$B,$C,$D,$E,$wl[20],$wl[21],$sl[20],$KL1,0);
+	&RIP2($E,$A,$B,$C,$D,$wl[21],$wl[22],$sl[21],$KL1,0);
+	&RIP2($D,$E,$A,$B,$C,$wl[22],$wl[23],$sl[22],$KL1,0);
+	&RIP2($C,$D,$E,$A,$B,$wl[23],$wl[24],$sl[23],$KL1,0);
+	&RIP2($B,$C,$D,$E,$A,$wl[24],$wl[25],$sl[24],$KL1,0);
+	&RIP2($A,$B,$C,$D,$E,$wl[25],$wl[26],$sl[25],$KL1,0);
+	&RIP2($E,$A,$B,$C,$D,$wl[26],$wl[27],$sl[26],$KL1,0);
+	&RIP2($D,$E,$A,$B,$C,$wl[27],$wl[28],$sl[27],$KL1,0);
+	&RIP2($C,$D,$E,$A,$B,$wl[28],$wl[29],$sl[28],$KL1,0);
+	&RIP2($B,$C,$D,$E,$A,$wl[29],$wl[30],$sl[29],$KL1,0);
+	&RIP2($A,$B,$C,$D,$E,$wl[30],$wl[31],$sl[30],$KL1,0);
+	&RIP2($E,$A,$B,$C,$D,$wl[31],$wl[32],$sl[31],$KL1,1);
+
+	&RIP3($D,$E,$A,$B,$C,$wl[32],$sl[32],$KL2,-1);
+	&RIP3($C,$D,$E,$A,$B,$wl[33],$sl[33],$KL2,0);
+	&RIP3($B,$C,$D,$E,$A,$wl[34],$sl[34],$KL2,0);
+	&RIP3($A,$B,$C,$D,$E,$wl[35],$sl[35],$KL2,0);
+	&RIP3($E,$A,$B,$C,$D,$wl[36],$sl[36],$KL2,0);
+	&RIP3($D,$E,$A,$B,$C,$wl[37],$sl[37],$KL2,0);
+	&RIP3($C,$D,$E,$A,$B,$wl[38],$sl[38],$KL2,0);
+	&RIP3($B,$C,$D,$E,$A,$wl[39],$sl[39],$KL2,0);
+	&RIP3($A,$B,$C,$D,$E,$wl[40],$sl[40],$KL2,0);
+	&RIP3($E,$A,$B,$C,$D,$wl[41],$sl[41],$KL2,0);
+	&RIP3($D,$E,$A,$B,$C,$wl[42],$sl[42],$KL2,0);
+	&RIP3($C,$D,$E,$A,$B,$wl[43],$sl[43],$KL2,0);
+	&RIP3($B,$C,$D,$E,$A,$wl[44],$sl[44],$KL2,0);
+	&RIP3($A,$B,$C,$D,$E,$wl[45],$sl[45],$KL2,0);
+	&RIP3($E,$A,$B,$C,$D,$wl[46],$sl[46],$KL2,0);
+	&RIP3($D,$E,$A,$B,$C,$wl[47],$sl[47],$KL2,1);
+
+	&RIP4($C,$D,$E,$A,$B,$wl[48],$sl[48],$KL3,-1);
+	&RIP4($B,$C,$D,$E,$A,$wl[49],$sl[49],$KL3,0);
+	&RIP4($A,$B,$C,$D,$E,$wl[50],$sl[50],$KL3,0);
+	&RIP4($E,$A,$B,$C,$D,$wl[51],$sl[51],$KL3,0);
+	&RIP4($D,$E,$A,$B,$C,$wl[52],$sl[52],$KL3,0);
+	&RIP4($C,$D,$E,$A,$B,$wl[53],$sl[53],$KL3,0);
+	&RIP4($B,$C,$D,$E,$A,$wl[54],$sl[54],$KL3,0);
+	&RIP4($A,$B,$C,$D,$E,$wl[55],$sl[55],$KL3,0);
+	&RIP4($E,$A,$B,$C,$D,$wl[56],$sl[56],$KL3,0);
+	&RIP4($D,$E,$A,$B,$C,$wl[57],$sl[57],$KL3,0);
+	&RIP4($C,$D,$E,$A,$B,$wl[58],$sl[58],$KL3,0);
+	&RIP4($B,$C,$D,$E,$A,$wl[59],$sl[59],$KL3,0);
+	&RIP4($A,$B,$C,$D,$E,$wl[60],$sl[60],$KL3,0);
+	&RIP4($E,$A,$B,$C,$D,$wl[61],$sl[61],$KL3,0);
+	&RIP4($D,$E,$A,$B,$C,$wl[62],$sl[62],$KL3,0);
+	&RIP4($C,$D,$E,$A,$B,$wl[63],$sl[63],$KL3,1);
+
+	&RIP5($B,$C,$D,$E,$A,$wl[64],$sl[64],$KL4,-1);
+	&RIP5($A,$B,$C,$D,$E,$wl[65],$sl[65],$KL4,0);
+	&RIP5($E,$A,$B,$C,$D,$wl[66],$sl[66],$KL4,0);
+	&RIP5($D,$E,$A,$B,$C,$wl[67],$sl[67],$KL4,0);
+	&RIP5($C,$D,$E,$A,$B,$wl[68],$sl[68],$KL4,0);
+	&RIP5($B,$C,$D,$E,$A,$wl[69],$sl[69],$KL4,0);
+	&RIP5($A,$B,$C,$D,$E,$wl[70],$sl[70],$KL4,0);
+	&RIP5($E,$A,$B,$C,$D,$wl[71],$sl[71],$KL4,0);
+	&RIP5($D,$E,$A,$B,$C,$wl[72],$sl[72],$KL4,0);
+	&RIP5($C,$D,$E,$A,$B,$wl[73],$sl[73],$KL4,0);
+	&RIP5($B,$C,$D,$E,$A,$wl[74],$sl[74],$KL4,0);
+	&RIP5($A,$B,$C,$D,$E,$wl[75],$sl[75],$KL4,0);
+	&RIP5($E,$A,$B,$C,$D,$wl[76],$sl[76],$KL4,0);
+	&RIP5($D,$E,$A,$B,$C,$wl[77],$sl[77],$KL4,0);
+	&RIP5($C,$D,$E,$A,$B,$wl[78],$sl[78],$KL4,0);
+	&RIP5($B,$C,$D,$E,$A,$wl[79],$sl[79],$KL4,1);
+
+	# &mov($tmp2,	&wparam(0)); # moved into last RIP5
+	# &mov(&swtmp(16),	$A);
+	 &mov($A,	&DWP( 0,$tmp2,"",0));
+	&mov(&swtmp(16+1),	$B);
+	 &mov(&swtmp(16+2),	$C);
+	&mov($B,	&DWP( 4,$tmp2,"",0));
+	 &mov(&swtmp(16+3),	$D);
+	&mov($C,	&DWP( 8,$tmp2,"",0));
+	 &mov(&swtmp(16+4),	$E);
+	&mov($D,	&DWP(12,$tmp2,"",0));
+	 &mov($E,	&DWP(16,$tmp2,"",0));
+
+	&RIP5($A,$B,$C,$D,$E,$wr[ 0],$sr[ 0],$KR0,-2);
+	&RIP5($E,$A,$B,$C,$D,$wr[ 1],$sr[ 1],$KR0,0);
+	&RIP5($D,$E,$A,$B,$C,$wr[ 2],$sr[ 2],$KR0,0);
+	&RIP5($C,$D,$E,$A,$B,$wr[ 3],$sr[ 3],$KR0,0);
+	&RIP5($B,$C,$D,$E,$A,$wr[ 4],$sr[ 4],$KR0,0);
+	&RIP5($A,$B,$C,$D,$E,$wr[ 5],$sr[ 5],$KR0,0);
+	&RIP5($E,$A,$B,$C,$D,$wr[ 6],$sr[ 6],$KR0,0);
+	&RIP5($D,$E,$A,$B,$C,$wr[ 7],$sr[ 7],$KR0,0);
+	&RIP5($C,$D,$E,$A,$B,$wr[ 8],$sr[ 8],$KR0,0);
+	&RIP5($B,$C,$D,$E,$A,$wr[ 9],$sr[ 9],$KR0,0);
+	&RIP5($A,$B,$C,$D,$E,$wr[10],$sr[10],$KR0,0);
+	&RIP5($E,$A,$B,$C,$D,$wr[11],$sr[11],$KR0,0);
+	&RIP5($D,$E,$A,$B,$C,$wr[12],$sr[12],$KR0,0);
+	&RIP5($C,$D,$E,$A,$B,$wr[13],$sr[13],$KR0,0);
+	&RIP5($B,$C,$D,$E,$A,$wr[14],$sr[14],$KR0,0);
+	&RIP5($A,$B,$C,$D,$E,$wr[15],$sr[15],$KR0,2);
+
+	&RIP4($E,$A,$B,$C,$D,$wr[16],$sr[16],$KR1,-2);
+	&RIP4($D,$E,$A,$B,$C,$wr[17],$sr[17],$KR1,0);
+	&RIP4($C,$D,$E,$A,$B,$wr[18],$sr[18],$KR1,0);
+	&RIP4($B,$C,$D,$E,$A,$wr[19],$sr[19],$KR1,0);
+	&RIP4($A,$B,$C,$D,$E,$wr[20],$sr[20],$KR1,0);
+	&RIP4($E,$A,$B,$C,$D,$wr[21],$sr[21],$KR1,0);
+	&RIP4($D,$E,$A,$B,$C,$wr[22],$sr[22],$KR1,0);
+	&RIP4($C,$D,$E,$A,$B,$wr[23],$sr[23],$KR1,0);
+	&RIP4($B,$C,$D,$E,$A,$wr[24],$sr[24],$KR1,0);
+	&RIP4($A,$B,$C,$D,$E,$wr[25],$sr[25],$KR1,0);
+	&RIP4($E,$A,$B,$C,$D,$wr[26],$sr[26],$KR1,0);
+	&RIP4($D,$E,$A,$B,$C,$wr[27],$sr[27],$KR1,0);
+	&RIP4($C,$D,$E,$A,$B,$wr[28],$sr[28],$KR1,0);
+	&RIP4($B,$C,$D,$E,$A,$wr[29],$sr[29],$KR1,0);
+	&RIP4($A,$B,$C,$D,$E,$wr[30],$sr[30],$KR1,0);
+	&RIP4($E,$A,$B,$C,$D,$wr[31],$sr[31],$KR1,2);
+
+	&RIP3($D,$E,$A,$B,$C,$wr[32],$sr[32],$KR2,-2);
+	&RIP3($C,$D,$E,$A,$B,$wr[33],$sr[33],$KR2,0);
+	&RIP3($B,$C,$D,$E,$A,$wr[34],$sr[34],$KR2,0);
+	&RIP3($A,$B,$C,$D,$E,$wr[35],$sr[35],$KR2,0);
+	&RIP3($E,$A,$B,$C,$D,$wr[36],$sr[36],$KR2,0);
+	&RIP3($D,$E,$A,$B,$C,$wr[37],$sr[37],$KR2,0);
+	&RIP3($C,$D,$E,$A,$B,$wr[38],$sr[38],$KR2,0);
+	&RIP3($B,$C,$D,$E,$A,$wr[39],$sr[39],$KR2,0);
+	&RIP3($A,$B,$C,$D,$E,$wr[40],$sr[40],$KR2,0);
+	&RIP3($E,$A,$B,$C,$D,$wr[41],$sr[41],$KR2,0);
+	&RIP3($D,$E,$A,$B,$C,$wr[42],$sr[42],$KR2,0);
+	&RIP3($C,$D,$E,$A,$B,$wr[43],$sr[43],$KR2,0);
+	&RIP3($B,$C,$D,$E,$A,$wr[44],$sr[44],$KR2,0);
+	&RIP3($A,$B,$C,$D,$E,$wr[45],$sr[45],$KR2,0);
+	&RIP3($E,$A,$B,$C,$D,$wr[46],$sr[46],$KR2,0);
+	&RIP3($D,$E,$A,$B,$C,$wr[47],$sr[47],$KR2,2,$wr[48]);
+
+	&RIP2($C,$D,$E,$A,$B,$wr[48],$wr[49],$sr[48],$KR3,-2);
+	&RIP2($B,$C,$D,$E,$A,$wr[49],$wr[50],$sr[49],$KR3,0);
+	&RIP2($A,$B,$C,$D,$E,$wr[50],$wr[51],$sr[50],$KR3,0);
+	&RIP2($E,$A,$B,$C,$D,$wr[51],$wr[52],$sr[51],$KR3,0);
+	&RIP2($D,$E,$A,$B,$C,$wr[52],$wr[53],$sr[52],$KR3,0);
+	&RIP2($C,$D,$E,$A,$B,$wr[53],$wr[54],$sr[53],$KR3,0);
+	&RIP2($B,$C,$D,$E,$A,$wr[54],$wr[55],$sr[54],$KR3,0);
+	&RIP2($A,$B,$C,$D,$E,$wr[55],$wr[56],$sr[55],$KR3,0);
+	&RIP2($E,$A,$B,$C,$D,$wr[56],$wr[57],$sr[56],$KR3,0);
+	&RIP2($D,$E,$A,$B,$C,$wr[57],$wr[58],$sr[57],$KR3,0);
+	&RIP2($C,$D,$E,$A,$B,$wr[58],$wr[59],$sr[58],$KR3,0);
+	&RIP2($B,$C,$D,$E,$A,$wr[59],$wr[60],$sr[59],$KR3,0);
+	&RIP2($A,$B,$C,$D,$E,$wr[60],$wr[61],$sr[60],$KR3,0);
+	&RIP2($E,$A,$B,$C,$D,$wr[61],$wr[62],$sr[61],$KR3,0);
+	&RIP2($D,$E,$A,$B,$C,$wr[62],$wr[63],$sr[62],$KR3,0);
+	&RIP2($C,$D,$E,$A,$B,$wr[63],$wr[64],$sr[63],$KR3,2);
+
+	&RIP1($B,$C,$D,$E,$A,$wr[64],$sr[64],-2);
+	&RIP1($A,$B,$C,$D,$E,$wr[65],$sr[65],0);
+	&RIP1($E,$A,$B,$C,$D,$wr[66],$sr[66],0);
+	&RIP1($D,$E,$A,$B,$C,$wr[67],$sr[67],0);
+	&RIP1($C,$D,$E,$A,$B,$wr[68],$sr[68],0);
+	&RIP1($B,$C,$D,$E,$A,$wr[69],$sr[69],0);
+	&RIP1($A,$B,$C,$D,$E,$wr[70],$sr[70],0);
+	&RIP1($E,$A,$B,$C,$D,$wr[71],$sr[71],0);
+	&RIP1($D,$E,$A,$B,$C,$wr[72],$sr[72],0);
+	&RIP1($C,$D,$E,$A,$B,$wr[73],$sr[73],0);
+	&RIP1($B,$C,$D,$E,$A,$wr[74],$sr[74],0);
+	&RIP1($A,$B,$C,$D,$E,$wr[75],$sr[75],0);
+	&RIP1($E,$A,$B,$C,$D,$wr[76],$sr[76],0);
+	&RIP1($D,$E,$A,$B,$C,$wr[77],$sr[77],0);
+	&RIP1($C,$D,$E,$A,$B,$wr[78],$sr[78],0);
+	&RIP1($B,$C,$D,$E,$A,$wr[79],$sr[79],2);
+
+	# &mov($tmp2,	&wparam(0)); # Moved into last round
+
+	 &mov($tmp1,	&DWP( 4,$tmp2,"",0));	# ctx->B
+ 	&add($D,	$tmp1);	
+	 &mov($tmp1,	&swtmp(16+2));		# $c
+	&add($D,	$tmp1);
+
+	 &mov($tmp1,	&DWP( 8,$tmp2,"",0));	# ctx->C
+	&add($E,	$tmp1);	
+	 &mov($tmp1,	&swtmp(16+3));		# $d
+	&add($E,	$tmp1);
+
+	 &mov($tmp1,	&DWP(12,$tmp2,"",0));	# ctx->D
+	&add($A,	$tmp1);	
+	 &mov($tmp1,	&swtmp(16+4));		# $e
+	&add($A,	$tmp1);
+
+
+	 &mov($tmp1,	&DWP(16,$tmp2,"",0));	# ctx->E
+	&add($B,	$tmp1);	
+	 &mov($tmp1,	&swtmp(16+0));		# $a
+	&add($B,	$tmp1);
+
+	 &mov($tmp1,	&DWP( 0,$tmp2,"",0));	# ctx->A
+	&add($C,	$tmp1);	
+	 &mov($tmp1,	&swtmp(16+1));		# $b
+	&add($C,	$tmp1);
+
+	 &mov($tmp1,	&wparam(2));
+
+	&mov(&DWP( 0,$tmp2,"",0),	$D);
+	 &mov(&DWP( 4,$tmp2,"",0),	$E);
+	&mov(&DWP( 8,$tmp2,"",0),	$A);
+	 &sub($tmp1,1);
+	&mov(&DWP(12,$tmp2,"",0),	$B);
+	 &mov(&DWP(16,$tmp2,"",0),	$C);
+
+	&jle(&label("get_out"));
+
+	&mov(&wparam(2),$tmp1);
+	 &mov($C,	$A);
+	&mov($tmp1,	&wparam(1));
+	 &mov($A,	$D);
+	&add($tmp1,	64);
+	 &mov($B,	$E);
+	&mov(&wparam(1),$tmp1);
+
+	&jmp(&label("start"));
+
+	&set_label("get_out");
+
+	&stack_pop(16+5+6);
+
+	&pop("ebx");
+	&pop("ebp");
+	&pop("edi");
+	&pop("esi");
+	&ret();
+	&function_end_B($name);
+	}
+
diff --git a/openssl/crypto/ripemd/ripemd.h b/openssl/crypto/ripemd/ripemd.h
new file mode 100644
index 0000000..5942eb6
--- /dev/null
+++ b/openssl/crypto/ripemd/ripemd.h
@@ -0,0 +1,104 @@
+/* crypto/ripemd/ripemd.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RIPEMD_H
+#define HEADER_RIPEMD_H
+
+#include <openssl/e_os2.h>
+#include <stddef.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_RIPEMD
+#error RIPEMD is disabled.
+#endif
+
+#if defined(__LP32__)
+#define RIPEMD160_LONG unsigned long
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#define RIPEMD160_LONG unsigned long
+#define RIPEMD160_LONG_LOG2 3
+#else
+#define RIPEMD160_LONG unsigned int
+#endif
+
+#define RIPEMD160_CBLOCK	64
+#define RIPEMD160_LBLOCK	(RIPEMD160_CBLOCK/4)
+#define RIPEMD160_DIGEST_LENGTH	20
+
+typedef struct RIPEMD160state_st
+	{
+	RIPEMD160_LONG A,B,C,D,E;
+	RIPEMD160_LONG Nl,Nh;
+	RIPEMD160_LONG data[RIPEMD160_LBLOCK];
+	unsigned int   num;
+	} RIPEMD160_CTX;
+
+int RIPEMD160_Init(RIPEMD160_CTX *c);
+int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len);
+int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c);
+unsigned char *RIPEMD160(const unsigned char *d, size_t n,
+	unsigned char *md);
+void RIPEMD160_Transform(RIPEMD160_CTX *c, const unsigned char *b);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/ripemd/rmd160.c b/openssl/crypto/ripemd/rmd160.c
new file mode 100644
index 0000000..b0ec574
--- /dev/null
+++ b/openssl/crypto/ripemd/rmd160.c
@@ -0,0 +1,127 @@
+/* crypto/ripemd/rmd160.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/ripemd.h>
+
+#define BUFSIZE	1024*16
+
+void do_fp(FILE *f);
+void pt(unsigned char *md);
+#if !defined(_OSD_POSIX) && !defined(__DJGPP__)
+int read(int, void *, unsigned int);
+#endif
+
+int main(int argc, char **argv)
+	{
+	int i,err=0;
+	FILE *IN;
+
+	if (argc == 1)
+		{
+		do_fp(stdin);
+		}
+	else
+		{
+		for (i=1; i<argc; i++)
+			{
+			IN=fopen(argv[i],"r");
+			if (IN == NULL)
+				{
+				perror(argv[i]);
+				err++;
+				continue;
+				}
+			printf("RIPEMD160(%s)= ",argv[i]);
+			do_fp(IN);
+			fclose(IN);
+			}
+		}
+	exit(err);
+	}
+
+void do_fp(FILE *f)
+	{
+	RIPEMD160_CTX c;
+	unsigned char md[RIPEMD160_DIGEST_LENGTH];
+	int fd;
+	int i;
+	static unsigned char buf[BUFSIZE];
+
+	fd=fileno(f);
+	RIPEMD160_Init(&c);
+	for (;;)
+		{
+		i=read(fd,buf,BUFSIZE);
+		if (i <= 0) break;
+		RIPEMD160_Update(&c,buf,(unsigned long)i);
+		}
+	RIPEMD160_Final(&(md[0]),&c);
+	pt(md);
+	}
+
+void pt(unsigned char *md)
+	{
+	int i;
+
+	for (i=0; i<RIPEMD160_DIGEST_LENGTH; i++)
+		printf("%02x",md[i]);
+	printf("\n");
+	}
+
diff --git a/openssl/crypto/ripemd/rmd_dgst.c b/openssl/crypto/ripemd/rmd_dgst.c
new file mode 100644
index 0000000..59b017f
--- /dev/null
+++ b/openssl/crypto/ripemd/rmd_dgst.c
@@ -0,0 +1,291 @@
+/* crypto/ripemd/rmd_dgst.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "rmd_locl.h"
+#include <openssl/opensslv.h>
+
+const char RMD160_version[]="RIPE-MD160" OPENSSL_VERSION_PTEXT;
+
+#  ifdef RMD160_ASM
+     void ripemd160_block_x86(RIPEMD160_CTX *c, unsigned long *p,size_t num);
+#    define ripemd160_block ripemd160_block_x86
+#  else
+     void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p,size_t num);
+#  endif
+
+int RIPEMD160_Init(RIPEMD160_CTX *c)
+	{
+	memset (c,0,sizeof(*c));
+	c->A=RIPEMD160_A;
+	c->B=RIPEMD160_B;
+	c->C=RIPEMD160_C;
+	c->D=RIPEMD160_D;
+	c->E=RIPEMD160_E;
+	return 1;
+	}
+
+#ifndef ripemd160_block_data_order
+#ifdef X
+#undef X
+#endif
+void ripemd160_block_data_order (RIPEMD160_CTX *ctx, const void *p, size_t num)
+	{
+	const unsigned char *data=p;
+	register unsigned MD32_REG_T A,B,C,D,E;
+	unsigned MD32_REG_T a,b,c,d,e,l;
+#ifndef MD32_XARRAY
+	/* See comment in crypto/sha/sha_locl.h for details. */
+	unsigned MD32_REG_T	XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+				XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
+# define X(i)	XX##i
+#else
+	RIPEMD160_LONG	XX[16];
+# define X(i)	XX[i]
+#endif
+
+	for (;num--;)
+		{
+
+	A=ctx->A; B=ctx->B; C=ctx->C; D=ctx->D; E=ctx->E;
+
+	HOST_c2l(data,l); X( 0)=l;	HOST_c2l(data,l); X( 1)=l;
+	RIP1(A,B,C,D,E,WL00,SL00);	HOST_c2l(data,l); X( 2)=l;
+	RIP1(E,A,B,C,D,WL01,SL01);	HOST_c2l(data,l); X( 3)=l;
+	RIP1(D,E,A,B,C,WL02,SL02);	HOST_c2l(data,l); X( 4)=l;
+	RIP1(C,D,E,A,B,WL03,SL03);	HOST_c2l(data,l); X( 5)=l;
+	RIP1(B,C,D,E,A,WL04,SL04);	HOST_c2l(data,l); X( 6)=l;
+	RIP1(A,B,C,D,E,WL05,SL05);	HOST_c2l(data,l); X( 7)=l;
+	RIP1(E,A,B,C,D,WL06,SL06);	HOST_c2l(data,l); X( 8)=l;
+	RIP1(D,E,A,B,C,WL07,SL07);	HOST_c2l(data,l); X( 9)=l;
+	RIP1(C,D,E,A,B,WL08,SL08);	HOST_c2l(data,l); X(10)=l;
+	RIP1(B,C,D,E,A,WL09,SL09);	HOST_c2l(data,l); X(11)=l;
+	RIP1(A,B,C,D,E,WL10,SL10);	HOST_c2l(data,l); X(12)=l;
+	RIP1(E,A,B,C,D,WL11,SL11);	HOST_c2l(data,l); X(13)=l;
+	RIP1(D,E,A,B,C,WL12,SL12);	HOST_c2l(data,l); X(14)=l;
+	RIP1(C,D,E,A,B,WL13,SL13);	HOST_c2l(data,l); X(15)=l;
+	RIP1(B,C,D,E,A,WL14,SL14);
+	RIP1(A,B,C,D,E,WL15,SL15);
+
+	RIP2(E,A,B,C,D,WL16,SL16,KL1);
+	RIP2(D,E,A,B,C,WL17,SL17,KL1);
+	RIP2(C,D,E,A,B,WL18,SL18,KL1);
+	RIP2(B,C,D,E,A,WL19,SL19,KL1);
+	RIP2(A,B,C,D,E,WL20,SL20,KL1);
+	RIP2(E,A,B,C,D,WL21,SL21,KL1);
+	RIP2(D,E,A,B,C,WL22,SL22,KL1);
+	RIP2(C,D,E,A,B,WL23,SL23,KL1);
+	RIP2(B,C,D,E,A,WL24,SL24,KL1);
+	RIP2(A,B,C,D,E,WL25,SL25,KL1);
+	RIP2(E,A,B,C,D,WL26,SL26,KL1);
+	RIP2(D,E,A,B,C,WL27,SL27,KL1);
+	RIP2(C,D,E,A,B,WL28,SL28,KL1);
+	RIP2(B,C,D,E,A,WL29,SL29,KL1);
+	RIP2(A,B,C,D,E,WL30,SL30,KL1);
+	RIP2(E,A,B,C,D,WL31,SL31,KL1);
+
+	RIP3(D,E,A,B,C,WL32,SL32,KL2);
+	RIP3(C,D,E,A,B,WL33,SL33,KL2);
+	RIP3(B,C,D,E,A,WL34,SL34,KL2);
+	RIP3(A,B,C,D,E,WL35,SL35,KL2);
+	RIP3(E,A,B,C,D,WL36,SL36,KL2);
+	RIP3(D,E,A,B,C,WL37,SL37,KL2);
+	RIP3(C,D,E,A,B,WL38,SL38,KL2);
+	RIP3(B,C,D,E,A,WL39,SL39,KL2);
+	RIP3(A,B,C,D,E,WL40,SL40,KL2);
+	RIP3(E,A,B,C,D,WL41,SL41,KL2);
+	RIP3(D,E,A,B,C,WL42,SL42,KL2);
+	RIP3(C,D,E,A,B,WL43,SL43,KL2);
+	RIP3(B,C,D,E,A,WL44,SL44,KL2);
+	RIP3(A,B,C,D,E,WL45,SL45,KL2);
+	RIP3(E,A,B,C,D,WL46,SL46,KL2);
+	RIP3(D,E,A,B,C,WL47,SL47,KL2);
+
+	RIP4(C,D,E,A,B,WL48,SL48,KL3);
+	RIP4(B,C,D,E,A,WL49,SL49,KL3);
+	RIP4(A,B,C,D,E,WL50,SL50,KL3);
+	RIP4(E,A,B,C,D,WL51,SL51,KL3);
+	RIP4(D,E,A,B,C,WL52,SL52,KL3);
+	RIP4(C,D,E,A,B,WL53,SL53,KL3);
+	RIP4(B,C,D,E,A,WL54,SL54,KL3);
+	RIP4(A,B,C,D,E,WL55,SL55,KL3);
+	RIP4(E,A,B,C,D,WL56,SL56,KL3);
+	RIP4(D,E,A,B,C,WL57,SL57,KL3);
+	RIP4(C,D,E,A,B,WL58,SL58,KL3);
+	RIP4(B,C,D,E,A,WL59,SL59,KL3);
+	RIP4(A,B,C,D,E,WL60,SL60,KL3);
+	RIP4(E,A,B,C,D,WL61,SL61,KL3);
+	RIP4(D,E,A,B,C,WL62,SL62,KL3);
+	RIP4(C,D,E,A,B,WL63,SL63,KL3);
+
+	RIP5(B,C,D,E,A,WL64,SL64,KL4);
+	RIP5(A,B,C,D,E,WL65,SL65,KL4);
+	RIP5(E,A,B,C,D,WL66,SL66,KL4);
+	RIP5(D,E,A,B,C,WL67,SL67,KL4);
+	RIP5(C,D,E,A,B,WL68,SL68,KL4);
+	RIP5(B,C,D,E,A,WL69,SL69,KL4);
+	RIP5(A,B,C,D,E,WL70,SL70,KL4);
+	RIP5(E,A,B,C,D,WL71,SL71,KL4);
+	RIP5(D,E,A,B,C,WL72,SL72,KL4);
+	RIP5(C,D,E,A,B,WL73,SL73,KL4);
+	RIP5(B,C,D,E,A,WL74,SL74,KL4);
+	RIP5(A,B,C,D,E,WL75,SL75,KL4);
+	RIP5(E,A,B,C,D,WL76,SL76,KL4);
+	RIP5(D,E,A,B,C,WL77,SL77,KL4);
+	RIP5(C,D,E,A,B,WL78,SL78,KL4);
+	RIP5(B,C,D,E,A,WL79,SL79,KL4);
+
+	a=A; b=B; c=C; d=D; e=E;
+	/* Do other half */
+	A=ctx->A; B=ctx->B; C=ctx->C; D=ctx->D; E=ctx->E;
+
+	RIP5(A,B,C,D,E,WR00,SR00,KR0);
+	RIP5(E,A,B,C,D,WR01,SR01,KR0);
+	RIP5(D,E,A,B,C,WR02,SR02,KR0);
+	RIP5(C,D,E,A,B,WR03,SR03,KR0);
+	RIP5(B,C,D,E,A,WR04,SR04,KR0);
+	RIP5(A,B,C,D,E,WR05,SR05,KR0);
+	RIP5(E,A,B,C,D,WR06,SR06,KR0);
+	RIP5(D,E,A,B,C,WR07,SR07,KR0);
+	RIP5(C,D,E,A,B,WR08,SR08,KR0);
+	RIP5(B,C,D,E,A,WR09,SR09,KR0);
+	RIP5(A,B,C,D,E,WR10,SR10,KR0);
+	RIP5(E,A,B,C,D,WR11,SR11,KR0);
+	RIP5(D,E,A,B,C,WR12,SR12,KR0);
+	RIP5(C,D,E,A,B,WR13,SR13,KR0);
+	RIP5(B,C,D,E,A,WR14,SR14,KR0);
+	RIP5(A,B,C,D,E,WR15,SR15,KR0);
+
+	RIP4(E,A,B,C,D,WR16,SR16,KR1);
+	RIP4(D,E,A,B,C,WR17,SR17,KR1);
+	RIP4(C,D,E,A,B,WR18,SR18,KR1);
+	RIP4(B,C,D,E,A,WR19,SR19,KR1);
+	RIP4(A,B,C,D,E,WR20,SR20,KR1);
+	RIP4(E,A,B,C,D,WR21,SR21,KR1);
+	RIP4(D,E,A,B,C,WR22,SR22,KR1);
+	RIP4(C,D,E,A,B,WR23,SR23,KR1);
+	RIP4(B,C,D,E,A,WR24,SR24,KR1);
+	RIP4(A,B,C,D,E,WR25,SR25,KR1);
+	RIP4(E,A,B,C,D,WR26,SR26,KR1);
+	RIP4(D,E,A,B,C,WR27,SR27,KR1);
+	RIP4(C,D,E,A,B,WR28,SR28,KR1);
+	RIP4(B,C,D,E,A,WR29,SR29,KR1);
+	RIP4(A,B,C,D,E,WR30,SR30,KR1);
+	RIP4(E,A,B,C,D,WR31,SR31,KR1);
+
+	RIP3(D,E,A,B,C,WR32,SR32,KR2);
+	RIP3(C,D,E,A,B,WR33,SR33,KR2);
+	RIP3(B,C,D,E,A,WR34,SR34,KR2);
+	RIP3(A,B,C,D,E,WR35,SR35,KR2);
+	RIP3(E,A,B,C,D,WR36,SR36,KR2);
+	RIP3(D,E,A,B,C,WR37,SR37,KR2);
+	RIP3(C,D,E,A,B,WR38,SR38,KR2);
+	RIP3(B,C,D,E,A,WR39,SR39,KR2);
+	RIP3(A,B,C,D,E,WR40,SR40,KR2);
+	RIP3(E,A,B,C,D,WR41,SR41,KR2);
+	RIP3(D,E,A,B,C,WR42,SR42,KR2);
+	RIP3(C,D,E,A,B,WR43,SR43,KR2);
+	RIP3(B,C,D,E,A,WR44,SR44,KR2);
+	RIP3(A,B,C,D,E,WR45,SR45,KR2);
+	RIP3(E,A,B,C,D,WR46,SR46,KR2);
+	RIP3(D,E,A,B,C,WR47,SR47,KR2);
+
+	RIP2(C,D,E,A,B,WR48,SR48,KR3);
+	RIP2(B,C,D,E,A,WR49,SR49,KR3);
+	RIP2(A,B,C,D,E,WR50,SR50,KR3);
+	RIP2(E,A,B,C,D,WR51,SR51,KR3);
+	RIP2(D,E,A,B,C,WR52,SR52,KR3);
+	RIP2(C,D,E,A,B,WR53,SR53,KR3);
+	RIP2(B,C,D,E,A,WR54,SR54,KR3);
+	RIP2(A,B,C,D,E,WR55,SR55,KR3);
+	RIP2(E,A,B,C,D,WR56,SR56,KR3);
+	RIP2(D,E,A,B,C,WR57,SR57,KR3);
+	RIP2(C,D,E,A,B,WR58,SR58,KR3);
+	RIP2(B,C,D,E,A,WR59,SR59,KR3);
+	RIP2(A,B,C,D,E,WR60,SR60,KR3);
+	RIP2(E,A,B,C,D,WR61,SR61,KR3);
+	RIP2(D,E,A,B,C,WR62,SR62,KR3);
+	RIP2(C,D,E,A,B,WR63,SR63,KR3);
+
+	RIP1(B,C,D,E,A,WR64,SR64);
+	RIP1(A,B,C,D,E,WR65,SR65);
+	RIP1(E,A,B,C,D,WR66,SR66);
+	RIP1(D,E,A,B,C,WR67,SR67);
+	RIP1(C,D,E,A,B,WR68,SR68);
+	RIP1(B,C,D,E,A,WR69,SR69);
+	RIP1(A,B,C,D,E,WR70,SR70);
+	RIP1(E,A,B,C,D,WR71,SR71);
+	RIP1(D,E,A,B,C,WR72,SR72);
+	RIP1(C,D,E,A,B,WR73,SR73);
+	RIP1(B,C,D,E,A,WR74,SR74);
+	RIP1(A,B,C,D,E,WR75,SR75);
+	RIP1(E,A,B,C,D,WR76,SR76);
+	RIP1(D,E,A,B,C,WR77,SR77);
+	RIP1(C,D,E,A,B,WR78,SR78);
+	RIP1(B,C,D,E,A,WR79,SR79);
+
+	D     =ctx->B+c+D;
+	ctx->B=ctx->C+d+E;
+	ctx->C=ctx->D+e+A;
+	ctx->D=ctx->E+a+B;
+	ctx->E=ctx->A+b+C;
+	ctx->A=D;
+
+		}
+	}
+#endif
diff --git a/openssl/crypto/ripemd/rmd_locl.h b/openssl/crypto/ripemd/rmd_locl.h
new file mode 100644
index 0000000..f14b346
--- /dev/null
+++ b/openssl/crypto/ripemd/rmd_locl.h
@@ -0,0 +1,150 @@
+/* crypto/ripemd/rmd_locl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/opensslconf.h>
+#include <openssl/ripemd.h>
+
+#ifndef RIPEMD160_LONG_LOG2
+#define RIPEMD160_LONG_LOG2 2 /* default to 32 bits */
+#endif
+
+/*
+ * DO EXAMINE COMMENTS IN crypto/md5/md5_locl.h & crypto/md5/md5_dgst.c
+ * FOR EXPLANATIONS ON FOLLOWING "CODE."
+ *					<appro@fy.chalmers.se>
+ */
+#ifdef RMD160_ASM
+# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__)
+#  define ripemd160_block_data_order ripemd160_block_asm_data_order
+# endif
+#endif
+
+void ripemd160_block_data_order (RIPEMD160_CTX *c, const void *p,size_t num);
+
+#define DATA_ORDER_IS_LITTLE_ENDIAN
+
+#define HASH_LONG               RIPEMD160_LONG
+#define HASH_CTX                RIPEMD160_CTX
+#define HASH_CBLOCK             RIPEMD160_CBLOCK
+#define HASH_UPDATE             RIPEMD160_Update
+#define HASH_TRANSFORM          RIPEMD160_Transform
+#define HASH_FINAL              RIPEMD160_Final
+#define	HASH_MAKE_STRING(c,s)	do {	\
+	unsigned long ll;		\
+	ll=(c)->A; HOST_l2c(ll,(s));	\
+	ll=(c)->B; HOST_l2c(ll,(s));	\
+	ll=(c)->C; HOST_l2c(ll,(s));	\
+	ll=(c)->D; HOST_l2c(ll,(s));	\
+	ll=(c)->E; HOST_l2c(ll,(s));	\
+	} while (0)
+#define HASH_BLOCK_DATA_ORDER   ripemd160_block_data_order
+
+#include "md32_common.h"
+
+#if 0
+#define F1(x,y,z)	 ((x)^(y)^(z))
+#define F2(x,y,z)	(((x)&(y))|((~x)&z))
+#define F3(x,y,z)	(((x)|(~y))^(z))
+#define F4(x,y,z)	(((x)&(z))|((y)&(~(z))))
+#define F5(x,y,z)	 ((x)^((y)|(~(z))))
+#else
+/*
+ * Transformed F2 and F4 are courtesy of Wei Dai <weidai@eskimo.com>
+ */
+#define F1(x,y,z)	((x) ^ (y) ^ (z))
+#define F2(x,y,z)	((((y) ^ (z)) & (x)) ^ (z))
+#define F3(x,y,z)	(((~(y)) | (x)) ^ (z))
+#define F4(x,y,z)	((((x) ^ (y)) & (z)) ^ (y))
+#define F5(x,y,z)	(((~(z)) | (y)) ^ (x))
+#endif
+
+#define RIPEMD160_A	0x67452301L
+#define RIPEMD160_B	0xEFCDAB89L
+#define RIPEMD160_C	0x98BADCFEL
+#define RIPEMD160_D	0x10325476L
+#define RIPEMD160_E	0xC3D2E1F0L
+
+#include "rmdconst.h"
+
+#define RIP1(a,b,c,d,e,w,s) { \
+	a+=F1(b,c,d)+X(w); \
+        a=ROTATE(a,s)+e; \
+        c=ROTATE(c,10); }
+
+#define RIP2(a,b,c,d,e,w,s,K) { \
+	a+=F2(b,c,d)+X(w)+K; \
+        a=ROTATE(a,s)+e; \
+        c=ROTATE(c,10); }
+
+#define RIP3(a,b,c,d,e,w,s,K) { \
+	a+=F3(b,c,d)+X(w)+K; \
+        a=ROTATE(a,s)+e; \
+        c=ROTATE(c,10); }
+
+#define RIP4(a,b,c,d,e,w,s,K) { \
+	a+=F4(b,c,d)+X(w)+K; \
+        a=ROTATE(a,s)+e; \
+        c=ROTATE(c,10); }
+
+#define RIP5(a,b,c,d,e,w,s,K) { \
+	a+=F5(b,c,d)+X(w)+K; \
+        a=ROTATE(a,s)+e; \
+        c=ROTATE(c,10); }
+
diff --git a/openssl/crypto/ripemd/rmd_one.c b/openssl/crypto/ripemd/rmd_one.c
new file mode 100644
index 0000000..3efb137
--- /dev/null
+++ b/openssl/crypto/ripemd/rmd_one.c
@@ -0,0 +1,78 @@
+/* crypto/ripemd/rmd_one.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/ripemd.h>
+#include <openssl/crypto.h>
+
+unsigned char *RIPEMD160(const unsigned char *d, size_t n,
+	     unsigned char *md)
+	{
+	RIPEMD160_CTX c;
+	static unsigned char m[RIPEMD160_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	if (!RIPEMD160_Init(&c))
+		return NULL;
+	RIPEMD160_Update(&c,d,n);
+	RIPEMD160_Final(md,&c);
+	OPENSSL_cleanse(&c,sizeof(c)); /* security consideration */
+	return(md);
+	}
+
diff --git a/openssl/crypto/ripemd/rmdconst.h b/openssl/crypto/ripemd/rmdconst.h
new file mode 100644
index 0000000..59c48de
--- /dev/null
+++ b/openssl/crypto/ripemd/rmdconst.h
@@ -0,0 +1,399 @@
+/* crypto/ripemd/rmdconst.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+#define KL0 0x00000000L
+#define KL1 0x5A827999L
+#define KL2 0x6ED9EBA1L
+#define KL3 0x8F1BBCDCL
+#define KL4 0xA953FD4EL
+
+#define KR0 0x50A28BE6L
+#define KR1 0x5C4DD124L
+#define KR2 0x6D703EF3L
+#define KR3 0x7A6D76E9L
+#define KR4 0x00000000L
+
+#define WL00  0
+#define SL00 11
+#define WL01  1
+#define SL01 14
+#define WL02  2
+#define SL02 15
+#define WL03  3
+#define SL03 12
+#define WL04  4
+#define SL04  5
+#define WL05  5
+#define SL05  8
+#define WL06  6
+#define SL06  7
+#define WL07  7
+#define SL07  9
+#define WL08  8
+#define SL08 11
+#define WL09  9
+#define SL09 13
+#define WL10 10
+#define SL10 14
+#define WL11 11
+#define SL11 15
+#define WL12 12
+#define SL12  6
+#define WL13 13
+#define SL13  7
+#define WL14 14
+#define SL14  9
+#define WL15 15
+#define SL15  8
+
+#define WL16  7
+#define SL16  7
+#define WL17  4
+#define SL17  6
+#define WL18 13
+#define SL18  8
+#define WL19  1
+#define SL19 13
+#define WL20 10
+#define SL20 11
+#define WL21  6
+#define SL21  9
+#define WL22 15
+#define SL22  7
+#define WL23  3
+#define SL23 15
+#define WL24 12
+#define SL24  7
+#define WL25  0
+#define SL25 12
+#define WL26  9
+#define SL26 15
+#define WL27  5
+#define SL27  9
+#define WL28  2
+#define SL28 11
+#define WL29 14
+#define SL29  7
+#define WL30 11
+#define SL30 13
+#define WL31  8
+#define SL31 12
+
+#define WL32  3
+#define SL32 11
+#define WL33 10
+#define SL33 13
+#define WL34 14
+#define SL34  6
+#define WL35  4
+#define SL35  7
+#define WL36  9
+#define SL36 14
+#define WL37 15
+#define SL37  9
+#define WL38  8
+#define SL38 13
+#define WL39  1
+#define SL39 15
+#define WL40  2
+#define SL40 14
+#define WL41  7
+#define SL41  8
+#define WL42  0
+#define SL42 13
+#define WL43  6
+#define SL43  6
+#define WL44 13
+#define SL44  5
+#define WL45 11
+#define SL45 12
+#define WL46  5
+#define SL46  7
+#define WL47 12
+#define SL47  5
+
+#define WL48  1
+#define SL48 11
+#define WL49  9
+#define SL49 12
+#define WL50 11
+#define SL50 14
+#define WL51 10
+#define SL51 15
+#define WL52  0
+#define SL52 14
+#define WL53  8
+#define SL53 15
+#define WL54 12
+#define SL54  9
+#define WL55  4
+#define SL55  8
+#define WL56 13
+#define SL56  9
+#define WL57  3
+#define SL57 14
+#define WL58  7
+#define SL58  5
+#define WL59 15
+#define SL59  6
+#define WL60 14
+#define SL60  8
+#define WL61  5
+#define SL61  6
+#define WL62  6
+#define SL62  5
+#define WL63  2
+#define SL63 12
+
+#define WL64  4
+#define SL64  9
+#define WL65  0
+#define SL65 15
+#define WL66  5
+#define SL66  5
+#define WL67  9
+#define SL67 11
+#define WL68  7
+#define SL68  6
+#define WL69 12
+#define SL69  8
+#define WL70  2
+#define SL70 13
+#define WL71 10
+#define SL71 12
+#define WL72 14
+#define SL72  5
+#define WL73  1
+#define SL73 12
+#define WL74  3
+#define SL74 13
+#define WL75  8
+#define SL75 14
+#define WL76 11
+#define SL76 11
+#define WL77  6
+#define SL77  8
+#define WL78 15
+#define SL78  5
+#define WL79 13
+#define SL79  6
+
+#define WR00  5
+#define SR00  8
+#define WR01 14
+#define SR01  9
+#define WR02  7
+#define SR02  9
+#define WR03  0
+#define SR03 11
+#define WR04  9
+#define SR04 13
+#define WR05  2
+#define SR05 15
+#define WR06 11
+#define SR06 15
+#define WR07  4
+#define SR07  5
+#define WR08 13
+#define SR08  7
+#define WR09  6
+#define SR09  7
+#define WR10 15
+#define SR10  8
+#define WR11  8
+#define SR11 11
+#define WR12  1
+#define SR12 14
+#define WR13 10
+#define SR13 14
+#define WR14  3
+#define SR14 12
+#define WR15 12
+#define SR15  6
+
+#define WR16  6
+#define SR16  9
+#define WR17 11
+#define SR17 13
+#define WR18  3
+#define SR18 15
+#define WR19  7
+#define SR19  7
+#define WR20  0
+#define SR20 12
+#define WR21 13
+#define SR21  8
+#define WR22  5
+#define SR22  9
+#define WR23 10
+#define SR23 11
+#define WR24 14
+#define SR24  7
+#define WR25 15
+#define SR25  7
+#define WR26  8
+#define SR26 12
+#define WR27 12
+#define SR27  7
+#define WR28  4
+#define SR28  6
+#define WR29  9
+#define SR29 15
+#define WR30  1
+#define SR30 13
+#define WR31  2
+#define SR31 11
+
+#define WR32 15
+#define SR32  9
+#define WR33  5
+#define SR33  7
+#define WR34  1
+#define SR34 15
+#define WR35  3
+#define SR35 11
+#define WR36  7
+#define SR36  8
+#define WR37 14
+#define SR37  6
+#define WR38  6
+#define SR38  6
+#define WR39  9
+#define SR39 14
+#define WR40 11
+#define SR40 12
+#define WR41  8
+#define SR41 13
+#define WR42 12
+#define SR42  5
+#define WR43  2
+#define SR43 14
+#define WR44 10
+#define SR44 13
+#define WR45  0
+#define SR45 13
+#define WR46  4
+#define SR46  7
+#define WR47 13
+#define SR47  5
+
+#define WR48  8
+#define SR48 15
+#define WR49  6
+#define SR49  5
+#define WR50  4
+#define SR50  8
+#define WR51  1
+#define SR51 11
+#define WR52  3
+#define SR52 14
+#define WR53 11
+#define SR53 14
+#define WR54 15
+#define SR54  6
+#define WR55  0
+#define SR55 14
+#define WR56  5
+#define SR56  6
+#define WR57 12
+#define SR57  9
+#define WR58  2
+#define SR58 12
+#define WR59 13
+#define SR59  9
+#define WR60  9
+#define SR60 12
+#define WR61  7
+#define SR61  5
+#define WR62 10
+#define SR62 15
+#define WR63 14
+#define SR63  8
+
+#define WR64 12
+#define SR64  8
+#define WR65 15
+#define SR65  5
+#define WR66 10
+#define SR66 12
+#define WR67  4
+#define SR67  9
+#define WR68  1
+#define SR68 12
+#define WR69  5
+#define SR69  5
+#define WR70  8
+#define SR70 14
+#define WR71  7
+#define SR71  6
+#define WR72  6
+#define SR72  8
+#define WR73  2
+#define SR73 13
+#define WR74 13
+#define SR74  6
+#define WR75 14
+#define SR75  5
+#define WR76  0
+#define SR76 15
+#define WR77  3
+#define SR77 13
+#define WR78  9
+#define SR78 11
+#define WR79 11
+#define SR79 11
+
diff --git a/openssl/crypto/ripemd/rmdtest.c b/openssl/crypto/ripemd/rmdtest.c
new file mode 100644
index 0000000..fb34e0e
--- /dev/null
+++ b/openssl/crypto/ripemd/rmdtest.c
@@ -0,0 +1,145 @@
+/* crypto/ripemd/rmdtest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_RIPEMD
+int main(int argc, char *argv[])
+{
+    printf("No ripemd support\n");
+    return(0);
+}
+#else
+#include <openssl/ripemd.h>
+#include <openssl/evp.h>
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+static char *test[]={
+	"",
+	"a",
+	"abc",
+	"message digest",
+	"abcdefghijklmnopqrstuvwxyz",
+	"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+	"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+	NULL,
+	};
+
+static char *ret[]={
+	"9c1185a5c5e9fc54612808977ee8f548b2258d31",
+	"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe",
+	"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc",
+	"5d0689ef49d2fae572b881b123a85ffa21595f36",
+	"f71c27109c692c1b56bbdceb5b9d2865b3708dbc",
+	"12a053384a9c0c88e405a06c27dcf49ada62eb2b",
+	"b0e20b6e3116640286ed3a87a5713079b21f5189",
+	"9b752e45573d4b39f4dbd3323cab82bf63326bfb",
+	};
+
+static char *pt(unsigned char *md);
+int main(int argc, char *argv[])
+	{
+	int i,err=0;
+	char **P,**R;
+	char *p;
+	unsigned char md[RIPEMD160_DIGEST_LENGTH];
+
+	P=test;
+	R=ret;
+	i=1;
+	while (*P != NULL)
+		{
+#ifdef CHARSET_EBCDIC
+		ebcdic2ascii((char *)*P, (char *)*P, strlen((char *)*P));
+#endif
+		EVP_Digest(&(P[0][0]),strlen((char *)*P),md,NULL,EVP_ripemd160(), NULL);
+		p=pt(md);
+		if (strcmp(p,(char *)*R) != 0)
+			{
+			printf("error calculating RIPEMD160 on '%s'\n",*P);
+			printf("got %s instead of %s\n",p,*R);
+			err++;
+			}
+		else
+			printf("test %d ok\n",i);
+		i++;
+		R++;
+		P++;
+		}
+	EXIT(err);
+	return(0);
+	}
+
+static char *pt(unsigned char *md)
+	{
+	int i;
+	static char buf[80];
+
+	for (i=0; i<RIPEMD160_DIGEST_LENGTH; i++)
+		sprintf(&(buf[i*2]),"%02x",md[i]);
+	return(buf);
+	}
+#endif
diff --git a/openssl/crypto/rsa/Makefile b/openssl/crypto/rsa/Makefile
new file mode 100644
index 0000000..bb64223
--- /dev/null
+++ b/openssl/crypto/rsa/Makefile
@@ -0,0 +1,287 @@
+#
+# OpenSSL/crypto/rsa/Makefile
+#
+
+DIR=	rsa
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=rsa_test.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= rsa_eay.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_saos.c rsa_err.c \
+	rsa_pk1.c rsa_ssl.c rsa_none.c rsa_oaep.c rsa_chk.c rsa_null.c \
+	rsa_pss.c rsa_x931.c rsa_asn1.c rsa_depr.c rsa_ameth.c rsa_prn.c \
+	rsa_pmeth.c
+LIBOBJ= rsa_eay.o rsa_gen.o rsa_lib.o rsa_sign.o rsa_saos.o rsa_err.o \
+	rsa_pk1.o rsa_ssl.o rsa_none.o rsa_oaep.o rsa_chk.o rsa_null.o \
+	rsa_pss.o rsa_x931.o rsa_asn1.o rsa_depr.o rsa_ameth.o rsa_prn.o \
+	rsa_pmeth.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= rsa.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+rsa_ameth.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_ameth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+rsa_ameth.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+rsa_ameth.o: ../../include/openssl/cms.h ../../include/openssl/crypto.h
+rsa_ameth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+rsa_ameth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+rsa_ameth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+rsa_ameth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rsa_ameth.o: ../../include/openssl/objects.h
+rsa_ameth.o: ../../include/openssl/opensslconf.h
+rsa_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_ameth.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+rsa_ameth.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+rsa_ameth.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rsa_ameth.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+rsa_ameth.o: ../asn1/asn1_locl.h ../cryptlib.h rsa_ameth.c
+rsa_asn1.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_asn1.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+rsa_asn1.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+rsa_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+rsa_asn1.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+rsa_asn1.o: ../../include/openssl/opensslconf.h
+rsa_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_asn1.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+rsa_asn1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rsa_asn1.o: ../cryptlib.h rsa_asn1.c
+rsa_chk.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+rsa_chk.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+rsa_chk.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+rsa_chk.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+rsa_chk.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_chk.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+rsa_chk.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rsa_chk.o: rsa_chk.c
+rsa_depr.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_depr.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+rsa_depr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rsa_depr.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+rsa_depr.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+rsa_depr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_depr.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+rsa_depr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rsa_depr.o: ../cryptlib.h rsa_depr.c
+rsa_eay.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_eay.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+rsa_eay.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rsa_eay.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+rsa_eay.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+rsa_eay.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_eay.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+rsa_eay.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+rsa_eay.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_eay.c
+rsa_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+rsa_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+rsa_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+rsa_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+rsa_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
+rsa_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+rsa_err.o: ../../include/openssl/symhacks.h rsa_err.c
+rsa_gen.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_gen.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+rsa_gen.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rsa_gen.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+rsa_gen.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+rsa_gen.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_gen.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+rsa_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rsa_gen.o: ../cryptlib.h rsa_gen.c
+rsa_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+rsa_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+rsa_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+rsa_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+rsa_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+rsa_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+rsa_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+rsa_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+rsa_lib.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+rsa_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+rsa_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rsa_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+rsa_lib.o: ../cryptlib.h rsa_lib.c
+rsa_none.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_none.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+rsa_none.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rsa_none.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+rsa_none.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+rsa_none.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_none.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+rsa_none.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+rsa_none.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_none.c
+rsa_null.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_null.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+rsa_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rsa_null.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+rsa_null.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+rsa_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_null.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+rsa_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+rsa_null.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_null.c
+rsa_oaep.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_oaep.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+rsa_oaep.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rsa_oaep.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+rsa_oaep.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+rsa_oaep.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+rsa_oaep.o: ../../include/openssl/opensslconf.h
+rsa_oaep.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_oaep.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+rsa_oaep.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+rsa_oaep.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rsa_oaep.o: ../cryptlib.h rsa_oaep.c
+rsa_pk1.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_pk1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+rsa_pk1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rsa_pk1.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+rsa_pk1.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+rsa_pk1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_pk1.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+rsa_pk1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+rsa_pk1.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_pk1.c
+rsa_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_pmeth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+rsa_pmeth.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+rsa_pmeth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+rsa_pmeth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+rsa_pmeth.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+rsa_pmeth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+rsa_pmeth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+rsa_pmeth.o: ../../include/openssl/opensslconf.h
+rsa_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+rsa_pmeth.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+rsa_pmeth.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rsa_pmeth.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+rsa_pmeth.o: ../cryptlib.h ../evp/evp_locl.h rsa_locl.h rsa_pmeth.c
+rsa_prn.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_prn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+rsa_prn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+rsa_prn.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+rsa_prn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rsa_prn.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rsa_prn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_prn.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+rsa_prn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rsa_prn.o: ../cryptlib.h rsa_prn.c
+rsa_pss.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_pss.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+rsa_pss.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rsa_pss.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+rsa_pss.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+rsa_pss.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+rsa_pss.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+rsa_pss.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+rsa_pss.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+rsa_pss.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+rsa_pss.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_pss.c
+rsa_saos.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_saos.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+rsa_saos.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rsa_saos.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+rsa_saos.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+rsa_saos.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+rsa_saos.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rsa_saos.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rsa_saos.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_saos.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+rsa_saos.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+rsa_saos.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rsa_saos.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+rsa_saos.o: ../cryptlib.h rsa_saos.c
+rsa_sign.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_sign.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+rsa_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rsa_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+rsa_sign.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+rsa_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+rsa_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rsa_sign.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rsa_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+rsa_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+rsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rsa_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+rsa_sign.o: ../cryptlib.h rsa_locl.h rsa_sign.c
+rsa_ssl.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_ssl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+rsa_ssl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rsa_ssl.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+rsa_ssl.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+rsa_ssl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_ssl.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+rsa_ssl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+rsa_ssl.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_ssl.c
+rsa_x931.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_x931.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+rsa_x931.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rsa_x931.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+rsa_x931.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rsa_x931.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rsa_x931.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_x931.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+rsa_x931.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+rsa_x931.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_x931.c
diff --git a/openssl/crypto/rsa/rsa.h b/openssl/crypto/rsa/rsa.h
new file mode 100644
index 0000000..cf74343
--- /dev/null
+++ b/openssl/crypto/rsa/rsa.h
@@ -0,0 +1,503 @@
+/* crypto/rsa/rsa.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RSA_H
+#define HEADER_RSA_H
+
+#include <openssl/asn1.h>
+
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#include <openssl/crypto.h>
+#include <openssl/ossl_typ.h>
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#endif
+
+#ifdef OPENSSL_NO_RSA
+#error RSA is disabled.
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Declared already in ossl_typ.h */
+/* typedef struct rsa_st RSA; */
+/* typedef struct rsa_meth_st RSA_METHOD; */
+
+struct rsa_meth_st
+	{
+	const char *name;
+	int (*rsa_pub_enc)(int flen,const unsigned char *from,
+			   unsigned char *to,
+			   RSA *rsa,int padding);
+	int (*rsa_pub_dec)(int flen,const unsigned char *from,
+			   unsigned char *to,
+			   RSA *rsa,int padding);
+	int (*rsa_priv_enc)(int flen,const unsigned char *from,
+			    unsigned char *to,
+			    RSA *rsa,int padding);
+	int (*rsa_priv_dec)(int flen,const unsigned char *from,
+			    unsigned char *to,
+			    RSA *rsa,int padding);
+	int (*rsa_mod_exp)(BIGNUM *r0,const BIGNUM *I,RSA *rsa,BN_CTX *ctx); /* Can be null */
+	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			  const BIGNUM *m, BN_CTX *ctx,
+			  BN_MONT_CTX *m_ctx); /* Can be null */
+	int (*init)(RSA *rsa);		/* called at new */
+	int (*finish)(RSA *rsa);	/* called at free */
+	int flags;			/* RSA_METHOD_FLAG_* things */
+	char *app_data;			/* may be needed! */
+/* New sign and verify functions: some libraries don't allow arbitrary data
+ * to be signed/verified: this allows them to be used. Note: for this to work
+ * the RSA_public_decrypt() and RSA_private_encrypt() should *NOT* be used
+ * RSA_sign(), RSA_verify() should be used instead. Note: for backwards
+ * compatibility this functionality is only enabled if the RSA_FLAG_SIGN_VER
+ * option is set in 'flags'.
+ */
+	int (*rsa_sign)(int type,
+		const unsigned char *m, unsigned int m_length,
+		unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
+	int (*rsa_verify)(int dtype,
+		const unsigned char *m, unsigned int m_length,
+		const unsigned char *sigbuf, unsigned int siglen,
+								const RSA *rsa);
+/* If this callback is NULL, the builtin software RSA key-gen will be used. This
+ * is for behavioural compatibility whilst the code gets rewired, but one day
+ * it would be nice to assume there are no such things as "builtin software"
+ * implementations. */
+	int (*rsa_keygen)(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+	};
+
+struct rsa_st
+	{
+	/* The first parameter is used to pickup errors where
+	 * this is passed instead of aEVP_PKEY, it is set to 0 */
+	int pad;
+	long version;
+	const RSA_METHOD *meth;
+	/* functional reference if 'meth' is ENGINE-provided */
+	ENGINE *engine;
+	BIGNUM *n;
+	BIGNUM *e;
+	BIGNUM *d;
+	BIGNUM *p;
+	BIGNUM *q;
+	BIGNUM *dmp1;
+	BIGNUM *dmq1;
+	BIGNUM *iqmp;
+	/* be careful using this if the RSA structure is shared */
+	CRYPTO_EX_DATA ex_data;
+	int references;
+	int flags;
+
+	/* Used to cache montgomery values */
+	BN_MONT_CTX *_method_mod_n;
+	BN_MONT_CTX *_method_mod_p;
+	BN_MONT_CTX *_method_mod_q;
+
+	/* all BIGNUM values are actually in the following data, if it is not
+	 * NULL */
+	char *bignum_data;
+	BN_BLINDING *blinding;
+	BN_BLINDING *mt_blinding;
+	};
+
+#ifndef OPENSSL_RSA_MAX_MODULUS_BITS
+# define OPENSSL_RSA_MAX_MODULUS_BITS	16384
+#endif
+
+#ifndef OPENSSL_RSA_SMALL_MODULUS_BITS
+# define OPENSSL_RSA_SMALL_MODULUS_BITS	3072
+#endif
+#ifndef OPENSSL_RSA_MAX_PUBEXP_BITS
+# define OPENSSL_RSA_MAX_PUBEXP_BITS	64 /* exponent limit enforced for "large" modulus only */
+#endif
+
+#define RSA_3	0x3L
+#define RSA_F4	0x10001L
+
+#define RSA_METHOD_FLAG_NO_CHECK	0x0001 /* don't check pub/private match */
+
+#define RSA_FLAG_CACHE_PUBLIC		0x0002
+#define RSA_FLAG_CACHE_PRIVATE		0x0004
+#define RSA_FLAG_BLINDING		0x0008
+#define RSA_FLAG_THREAD_SAFE		0x0010
+/* This flag means the private key operations will be handled by rsa_mod_exp
+ * and that they do not depend on the private key components being present:
+ * for example a key stored in external hardware. Without this flag bn_mod_exp
+ * gets called when private key components are absent.
+ */
+#define RSA_FLAG_EXT_PKEY		0x0020
+
+/* This flag in the RSA_METHOD enables the new rsa_sign, rsa_verify functions.
+ */
+#define RSA_FLAG_SIGN_VER		0x0040
+
+#define RSA_FLAG_NO_BLINDING		0x0080 /* new with 0.9.6j and 0.9.7b; the built-in
+                                                * RSA implementation now uses blinding by
+                                                * default (ignoring RSA_FLAG_BLINDING),
+                                                * but other engines might not need it
+                                                */
+#define RSA_FLAG_NO_CONSTTIME		0x0100 /* new with 0.9.8f; the built-in RSA
+						* implementation now uses constant time
+						* operations by default in private key operations,
+						* e.g., constant time modular exponentiation, 
+                                                * modular inverse without leaking branches, 
+                                                * division without leaking branches. This 
+                                                * flag disables these constant time 
+                                                * operations and results in faster RSA 
+                                                * private key operations.
+                                                */ 
+#ifndef OPENSSL_NO_DEPRECATED
+#define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME /* deprecated name for the flag*/
+                                                /* new with 0.9.7h; the built-in RSA
+                                                * implementation now uses constant time
+                                                * modular exponentiation for secret exponents
+                                                * by default. This flag causes the
+                                                * faster variable sliding window method to
+                                                * be used for all exponents.
+                                                */
+#endif
+
+
+#define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \
+				pad, NULL)
+
+#define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
+				(EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \
+				EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \
+				len, NULL)
+
+#define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
+				EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL)
+
+#define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
+				EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp)
+
+#define EVP_PKEY_CTRL_RSA_PADDING	(EVP_PKEY_ALG_CTRL + 1)
+#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN	(EVP_PKEY_ALG_CTRL + 2)
+
+#define EVP_PKEY_CTRL_RSA_KEYGEN_BITS	(EVP_PKEY_ALG_CTRL + 3)
+#define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP	(EVP_PKEY_ALG_CTRL + 4)
+
+#define RSA_PKCS1_PADDING	1
+#define RSA_SSLV23_PADDING	2
+#define RSA_NO_PADDING		3
+#define RSA_PKCS1_OAEP_PADDING	4
+#define RSA_X931_PADDING	5
+/* EVP_PKEY_ only */
+#define RSA_PKCS1_PSS_PADDING	6
+
+#define RSA_PKCS1_PADDING_SIZE	11
+
+#define RSA_set_app_data(s,arg)         RSA_set_ex_data(s,0,arg)
+#define RSA_get_app_data(s)             RSA_get_ex_data(s,0)
+
+RSA *	RSA_new(void);
+RSA *	RSA_new_method(ENGINE *engine);
+int	RSA_size(const RSA *);
+
+/* Deprecated version */
+#ifndef OPENSSL_NO_DEPRECATED
+RSA *	RSA_generate_key(int bits, unsigned long e,void
+		(*callback)(int,int,void *),void *cb_arg);
+#endif /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* New version */
+int	RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+
+int	RSA_check_key(const RSA *);
+	/* next 4 return -1 on error */
+int	RSA_public_encrypt(int flen, const unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+int	RSA_private_encrypt(int flen, const unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+int	RSA_public_decrypt(int flen, const unsigned char *from, 
+		unsigned char *to, RSA *rsa,int padding);
+int	RSA_private_decrypt(int flen, const unsigned char *from, 
+		unsigned char *to, RSA *rsa,int padding);
+void	RSA_free (RSA *r);
+/* "up" the RSA object's reference count */
+int	RSA_up_ref(RSA *r);
+
+int	RSA_flags(const RSA *r);
+
+void RSA_set_default_method(const RSA_METHOD *meth);
+const RSA_METHOD *RSA_get_default_method(void);
+const RSA_METHOD *RSA_get_method(const RSA *rsa);
+int RSA_set_method(RSA *rsa, const RSA_METHOD *meth);
+
+/* This function needs the memory locking malloc callbacks to be installed */
+int RSA_memory_lock(RSA *r);
+
+/* these are the actual SSLeay RSA functions */
+const RSA_METHOD *RSA_PKCS1_SSLeay(void);
+
+const RSA_METHOD *RSA_null_method(void);
+
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey)
+
+#ifndef OPENSSL_NO_FP_API
+int	RSA_print_fp(FILE *fp, const RSA *r,int offset);
+#endif
+
+#ifndef OPENSSL_NO_BIO
+int	RSA_print(BIO *bp, const RSA *r,int offset);
+#endif
+
+#ifndef OPENSSL_NO_RC4
+int i2d_RSA_NET(const RSA *a, unsigned char **pp,
+		int (*cb)(char *buf, int len, const char *prompt, int verify),
+		int sgckey);
+RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
+		 int (*cb)(char *buf, int len, const char *prompt, int verify),
+		 int sgckey);
+
+int i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
+		     int (*cb)(char *buf, int len, const char *prompt,
+			       int verify));
+RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
+		      int (*cb)(char *buf, int len, const char *prompt,
+				int verify));
+#endif
+
+/* The following 2 functions sign and verify a X509_SIG ASN1 object
+ * inside PKCS#1 padded RSA encryption */
+int RSA_sign(int type, const unsigned char *m, unsigned int m_length,
+	unsigned char *sigret, unsigned int *siglen, RSA *rsa);
+int RSA_verify(int type, const unsigned char *m, unsigned int m_length,
+	const unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
+
+/* The following 2 function sign and verify a ASN1_OCTET_STRING
+ * object inside PKCS#1 padded RSA encryption */
+int RSA_sign_ASN1_OCTET_STRING(int type,
+	const unsigned char *m, unsigned int m_length,
+	unsigned char *sigret, unsigned int *siglen, RSA *rsa);
+int RSA_verify_ASN1_OCTET_STRING(int type,
+	const unsigned char *m, unsigned int m_length,
+	unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
+
+int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
+void RSA_blinding_off(RSA *rsa);
+BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx);
+
+int RSA_padding_add_PKCS1_type_1(unsigned char *to,int tlen,
+	const unsigned char *f,int fl);
+int RSA_padding_check_PKCS1_type_1(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len);
+int RSA_padding_add_PKCS1_type_2(unsigned char *to,int tlen,
+	const unsigned char *f,int fl);
+int RSA_padding_check_PKCS1_type_2(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len);
+int PKCS1_MGF1(unsigned char *mask, long len,
+	const unsigned char *seed, long seedlen, const EVP_MD *dgst);
+int RSA_padding_add_PKCS1_OAEP(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,
+	const unsigned char *p,int pl);
+int RSA_padding_check_PKCS1_OAEP(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len,
+	const unsigned char *p,int pl);
+int RSA_padding_add_SSLv23(unsigned char *to,int tlen,
+	const unsigned char *f,int fl);
+int RSA_padding_check_SSLv23(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len);
+int RSA_padding_add_none(unsigned char *to,int tlen,
+	const unsigned char *f,int fl);
+int RSA_padding_check_none(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len);
+int RSA_padding_add_X931(unsigned char *to,int tlen,
+	const unsigned char *f,int fl);
+int RSA_padding_check_X931(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len);
+int RSA_X931_hash_id(int nid);
+
+int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
+			const EVP_MD *Hash, const unsigned char *EM, int sLen);
+int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
+			const unsigned char *mHash,
+			const EVP_MD *Hash, int sLen);
+
+int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int RSA_set_ex_data(RSA *r,int idx,void *arg);
+void *RSA_get_ex_data(const RSA *r, int idx);
+
+RSA *RSAPublicKey_dup(RSA *rsa);
+RSA *RSAPrivateKey_dup(RSA *rsa);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_RSA_strings(void);
+
+/* Error codes for the RSA functions. */
+
+/* Function codes. */
+#define RSA_F_CHECK_PADDING_MD				 140
+#define RSA_F_DO_RSA_PRINT				 146
+#define RSA_F_INT_RSA_VERIFY				 145
+#define RSA_F_MEMORY_LOCK				 100
+#define RSA_F_OLD_RSA_PRIV_DECODE			 147
+#define RSA_F_PKEY_RSA_CTRL				 143
+#define RSA_F_PKEY_RSA_CTRL_STR				 144
+#define RSA_F_PKEY_RSA_SIGN				 142
+#define RSA_F_PKEY_RSA_VERIFYRECOVER			 141
+#define RSA_F_RSA_BUILTIN_KEYGEN			 129
+#define RSA_F_RSA_CHECK_KEY				 123
+#define RSA_F_RSA_EAY_PRIVATE_DECRYPT			 101
+#define RSA_F_RSA_EAY_PRIVATE_ENCRYPT			 102
+#define RSA_F_RSA_EAY_PUBLIC_DECRYPT			 103
+#define RSA_F_RSA_EAY_PUBLIC_ENCRYPT			 104
+#define RSA_F_RSA_GENERATE_KEY				 105
+#define RSA_F_RSA_MEMORY_LOCK				 130
+#define RSA_F_RSA_NEW_METHOD				 106
+#define RSA_F_RSA_NULL					 124
+#define RSA_F_RSA_NULL_MOD_EXP				 131
+#define RSA_F_RSA_NULL_PRIVATE_DECRYPT			 132
+#define RSA_F_RSA_NULL_PRIVATE_ENCRYPT			 133
+#define RSA_F_RSA_NULL_PUBLIC_DECRYPT			 134
+#define RSA_F_RSA_NULL_PUBLIC_ENCRYPT			 135
+#define RSA_F_RSA_PADDING_ADD_NONE			 107
+#define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP		 121
+#define RSA_F_RSA_PADDING_ADD_PKCS1_PSS			 125
+#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1		 108
+#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2		 109
+#define RSA_F_RSA_PADDING_ADD_SSLV23			 110
+#define RSA_F_RSA_PADDING_ADD_X931			 127
+#define RSA_F_RSA_PADDING_CHECK_NONE			 111
+#define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP		 122
+#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1		 112
+#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2		 113
+#define RSA_F_RSA_PADDING_CHECK_SSLV23			 114
+#define RSA_F_RSA_PADDING_CHECK_X931			 128
+#define RSA_F_RSA_PRINT					 115
+#define RSA_F_RSA_PRINT_FP				 116
+#define RSA_F_RSA_PRIV_DECODE				 137
+#define RSA_F_RSA_PRIV_ENCODE				 138
+#define RSA_F_RSA_PUB_DECODE				 139
+#define RSA_F_RSA_SETUP_BLINDING			 136
+#define RSA_F_RSA_SIGN					 117
+#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING		 118
+#define RSA_F_RSA_VERIFY				 119
+#define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING		 120
+#define RSA_F_RSA_VERIFY_PKCS1_PSS			 126
+
+/* Reason codes. */
+#define RSA_R_ALGORITHM_MISMATCH			 100
+#define RSA_R_BAD_E_VALUE				 101
+#define RSA_R_BAD_FIXED_HEADER_DECRYPT			 102
+#define RSA_R_BAD_PAD_BYTE_COUNT			 103
+#define RSA_R_BAD_SIGNATURE				 104
+#define RSA_R_BLOCK_TYPE_IS_NOT_01			 106
+#define RSA_R_BLOCK_TYPE_IS_NOT_02			 107
+#define RSA_R_DATA_GREATER_THAN_MOD_LEN			 108
+#define RSA_R_DATA_TOO_LARGE				 109
+#define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 110
+#define RSA_R_DATA_TOO_LARGE_FOR_MODULUS		 132
+#define RSA_R_DATA_TOO_SMALL				 111
+#define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE		 122
+#define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY		 112
+#define RSA_R_DMP1_NOT_CONGRUENT_TO_D			 124
+#define RSA_R_DMQ1_NOT_CONGRUENT_TO_D			 125
+#define RSA_R_D_E_NOT_CONGRUENT_TO_1			 123
+#define RSA_R_FIRST_OCTET_INVALID			 133
+#define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE	 144
+#define RSA_R_INVALID_DIGEST_LENGTH			 143
+#define RSA_R_INVALID_HEADER				 137
+#define RSA_R_INVALID_KEYBITS				 145
+#define RSA_R_INVALID_MESSAGE_LENGTH			 131
+#define RSA_R_INVALID_PADDING				 138
+#define RSA_R_INVALID_PADDING_MODE			 141
+#define RSA_R_INVALID_PSS_SALTLEN			 146
+#define RSA_R_INVALID_TRAILER				 139
+#define RSA_R_INVALID_X931_DIGEST			 142
+#define RSA_R_IQMP_NOT_INVERSE_OF_Q			 126
+#define RSA_R_KEY_SIZE_TOO_SMALL			 120
+#define RSA_R_LAST_OCTET_INVALID			 134
+#define RSA_R_MODULUS_TOO_LARGE				 105
+#define RSA_R_NO_PUBLIC_EXPONENT			 140
+#define RSA_R_NULL_BEFORE_BLOCK_MISSING			 113
+#define RSA_R_N_DOES_NOT_EQUAL_P_Q			 127
+#define RSA_R_OAEP_DECODING_ERROR			 121
+#define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE	 148
+#define RSA_R_PADDING_CHECK_FAILED			 114
+#define RSA_R_P_NOT_PRIME				 128
+#define RSA_R_Q_NOT_PRIME				 129
+#define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED		 130
+#define RSA_R_SLEN_CHECK_FAILED				 136
+#define RSA_R_SLEN_RECOVERY_FAILED			 135
+#define RSA_R_SSLV3_ROLLBACK_ATTACK			 115
+#define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116
+#define RSA_R_UNKNOWN_ALGORITHM_TYPE			 117
+#define RSA_R_UNKNOWN_PADDING_TYPE			 118
+#define RSA_R_VALUE_MISSING				 147
+#define RSA_R_WRONG_SIGNATURE_LENGTH			 119
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/rsa/rsa_ameth.c b/openssl/crypto/rsa/rsa_ameth.c
new file mode 100644
index 0000000..8c32098
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_ameth.c
@@ -0,0 +1,349 @@
+/* crypto/rsa/rsa_ameth.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rsa.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_CMS
+#include <openssl/cms.h>
+#endif
+#include "asn1_locl.h"
+
+static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+	{
+	unsigned char *penc = NULL;
+	int penclen;
+	penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc);
+	if (penclen <= 0)
+		return 0;
+	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA),
+				V_ASN1_NULL, NULL, penc, penclen))
+		return 1;
+
+	OPENSSL_free(penc);
+	return 0;
+	}
+
+static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+	{
+	const unsigned char *p;
+	int pklen;
+	RSA *rsa = NULL;
+	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey))
+		return 0;
+	if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen)))
+		{
+		RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB);
+		return 0;
+		}
+	EVP_PKEY_assign_RSA (pkey, rsa);
+	return 1;
+	}
+
+static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+	{
+	if (BN_cmp(b->pkey.rsa->n,a->pkey.rsa->n) != 0
+		|| BN_cmp(b->pkey.rsa->e,a->pkey.rsa->e) != 0)
+			return 0;
+	return 1;
+	}
+
+static int old_rsa_priv_decode(EVP_PKEY *pkey,
+					const unsigned char **pder, int derlen)
+	{
+	RSA *rsa;
+	if (!(rsa = d2i_RSAPrivateKey (NULL, pder, derlen)))
+		{
+		RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB);
+		return 0;
+		}
+	EVP_PKEY_assign_RSA(pkey, rsa);
+	return 1;
+	}
+
+static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
+	{
+	return i2d_RSAPrivateKey(pkey->pkey.rsa, pder);
+	}
+
+static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+	{
+	unsigned char *rk = NULL;
+	int rklen;
+	rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk);
+
+	if (rklen <= 0)
+		{
+		RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+
+	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0,
+				V_ASN1_NULL, NULL, rk, rklen))
+		{
+		RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+
+	return 1;
+	}
+
+static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
+	{
+	const unsigned char *p;
+	int pklen;
+	if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8))
+		return 0;
+	return old_rsa_priv_decode(pkey, &p, pklen);
+	}
+
+static int int_rsa_size(const EVP_PKEY *pkey)
+	{
+	return RSA_size(pkey->pkey.rsa);
+	}
+
+static int rsa_bits(const EVP_PKEY *pkey)
+	{
+	return BN_num_bits(pkey->pkey.rsa->n);
+	}
+
+static void int_rsa_free(EVP_PKEY *pkey)
+	{
+	RSA_free(pkey->pkey.rsa);
+	}
+
+
+static void update_buflen(const BIGNUM *b, size_t *pbuflen)
+	{
+	size_t i;
+	if (!b)
+		return;
+	if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
+			*pbuflen = i;
+	}
+
+static int do_rsa_print(BIO *bp, const RSA *x, int off, int priv)
+	{
+	char *str;
+	const char *s;
+	unsigned char *m=NULL;
+	int ret=0, mod_len = 0;
+	size_t buf_len=0;
+
+	update_buflen(x->n, &buf_len);
+	update_buflen(x->e, &buf_len);
+
+	if (priv)
+		{
+		update_buflen(x->d, &buf_len);
+		update_buflen(x->p, &buf_len);
+		update_buflen(x->q, &buf_len);
+		update_buflen(x->dmp1, &buf_len);
+		update_buflen(x->dmq1, &buf_len);
+		update_buflen(x->iqmp, &buf_len);
+		}
+
+	m=(unsigned char *)OPENSSL_malloc(buf_len+10);
+	if (m == NULL)
+		{
+		RSAerr(RSA_F_DO_RSA_PRINT,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (x->n != NULL)
+		mod_len = BN_num_bits(x->n);
+
+	if(!BIO_indent(bp,off,128))
+		goto err;
+
+	if (priv && x->d)
+		{
+		if (BIO_printf(bp,"Private-Key: (%d bit)\n", mod_len)
+			<= 0) goto err;
+		str = "modulus:";
+		s = "publicExponent:";
+		}
+	else
+		{
+		if (BIO_printf(bp,"Public-Key: (%d bit)\n", mod_len)
+			<= 0) goto err;
+		str = "Modulus:";
+		s= "Exponent:";
+		}
+	if (!ASN1_bn_print(bp,str,x->n,m,off)) goto err;
+	if (!ASN1_bn_print(bp,s,x->e,m,off))
+		goto err;
+	if (priv)
+		{
+		if (!ASN1_bn_print(bp,"privateExponent:",x->d,m,off))
+			goto err;
+		if (!ASN1_bn_print(bp,"prime1:",x->p,m,off))
+			goto err;
+		if (!ASN1_bn_print(bp,"prime2:",x->q,m,off))
+			goto err;
+		if (!ASN1_bn_print(bp,"exponent1:",x->dmp1,m,off))
+			goto err;
+		if (!ASN1_bn_print(bp,"exponent2:",x->dmq1,m,off))
+			goto err;
+		if (!ASN1_bn_print(bp,"coefficient:",x->iqmp,m,off))
+			goto err;
+		}
+	ret=1;
+err:
+	if (m != NULL) OPENSSL_free(m);
+	return(ret);
+	}
+
+static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
+	}
+
+
+static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
+	}
+
+
+static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+	{
+	X509_ALGOR *alg = NULL;
+	switch (op)
+		{
+
+		case ASN1_PKEY_CTRL_PKCS7_SIGN:
+		if (arg1 == 0)
+			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg);
+		break;
+
+		case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
+		if (arg1 == 0)
+			PKCS7_RECIP_INFO_get0_alg(arg2, &alg);
+		break;
+#ifndef OPENSSL_NO_CMS
+		case ASN1_PKEY_CTRL_CMS_SIGN:
+		if (arg1 == 0)
+			CMS_SignerInfo_get0_algs(arg2, NULL, NULL, NULL, &alg);
+		break;
+
+		case ASN1_PKEY_CTRL_CMS_ENVELOPE:
+		if (arg1 == 0)
+			CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg);
+		break;
+#endif
+
+		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+		*(int *)arg2 = NID_sha1;
+		return 1;
+
+		default:
+		return -2;
+
+		}
+
+	if (alg)
+		X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption),
+							V_ASN1_NULL, 0);
+
+	return 1;
+
+	}
+
+
+const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = 
+	{
+		{
+		EVP_PKEY_RSA,
+		EVP_PKEY_RSA,
+		ASN1_PKEY_SIGPARAM_NULL,
+
+		"RSA",
+		"OpenSSL RSA method",
+
+		rsa_pub_decode,
+		rsa_pub_encode,
+		rsa_pub_cmp,
+		rsa_pub_print,
+
+		rsa_priv_decode,
+		rsa_priv_encode,
+		rsa_priv_print,
+
+		int_rsa_size,
+		rsa_bits,
+
+		0,0,0,0,0,0,
+
+		int_rsa_free,
+		rsa_pkey_ctrl,
+		old_rsa_priv_decode,
+		old_rsa_priv_encode
+		},
+
+		{
+		EVP_PKEY_RSA2,
+		EVP_PKEY_RSA,
+		ASN1_PKEY_ALIAS
+		}
+	};
diff --git a/openssl/crypto/rsa/rsa_asn1.c b/openssl/crypto/rsa/rsa_asn1.c
new file mode 100644
index 0000000..4efca8c
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_asn1.c
@@ -0,0 +1,111 @@
+/* rsa_asn1.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/asn1t.h>
+
+/* Override the default free and new methods */
+static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+								void *exarg)
+{
+	if(operation == ASN1_OP_NEW_PRE) {
+		*pval = (ASN1_VALUE *)RSA_new();
+		if(*pval) return 2;
+		return 0;
+	} else if(operation == ASN1_OP_FREE_PRE) {
+		RSA_free((RSA *)*pval);
+		*pval = NULL;
+		return 2;
+	}
+	return 1;
+}
+
+ASN1_SEQUENCE_cb(RSAPrivateKey, rsa_cb) = {
+	ASN1_SIMPLE(RSA, version, LONG),
+	ASN1_SIMPLE(RSA, n, BIGNUM),
+	ASN1_SIMPLE(RSA, e, BIGNUM),
+	ASN1_SIMPLE(RSA, d, BIGNUM),
+	ASN1_SIMPLE(RSA, p, BIGNUM),
+	ASN1_SIMPLE(RSA, q, BIGNUM),
+	ASN1_SIMPLE(RSA, dmp1, BIGNUM),
+	ASN1_SIMPLE(RSA, dmq1, BIGNUM),
+	ASN1_SIMPLE(RSA, iqmp, BIGNUM)
+} ASN1_SEQUENCE_END_cb(RSA, RSAPrivateKey)
+
+
+ASN1_SEQUENCE_cb(RSAPublicKey, rsa_cb) = {
+	ASN1_SIMPLE(RSA, n, BIGNUM),
+	ASN1_SIMPLE(RSA, e, BIGNUM),
+} ASN1_SEQUENCE_END_cb(RSA, RSAPublicKey)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey)
+
+RSA *RSAPublicKey_dup(RSA *rsa)
+	{
+	return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), rsa);
+	}
+
+RSA *RSAPrivateKey_dup(RSA *rsa)
+	{
+	return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), rsa);
+	}
diff --git a/openssl/crypto/rsa/rsa_chk.c b/openssl/crypto/rsa/rsa_chk.c
new file mode 100644
index 0000000..9d848db
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_chk.c
@@ -0,0 +1,184 @@
+/* crypto/rsa/rsa_chk.c  -*- Mode: C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/rsa.h>
+
+
+int RSA_check_key(const RSA *key)
+	{
+	BIGNUM *i, *j, *k, *l, *m;
+	BN_CTX *ctx;
+	int r;
+	int ret=1;
+	
+	i = BN_new();
+	j = BN_new();
+	k = BN_new();
+	l = BN_new();
+	m = BN_new();
+	ctx = BN_CTX_new();
+	if (i == NULL || j == NULL || k == NULL || l == NULL ||
+		m == NULL || ctx == NULL)
+		{
+		ret = -1;
+		RSAerr(RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	
+	/* p prime? */
+	r = BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL);
+	if (r != 1)
+		{
+		ret = r;
+		if (r != 0)
+			goto err;
+		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME);
+		}
+	
+	/* q prime? */
+	r = BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL);
+	if (r != 1)
+		{
+		ret = r;
+		if (r != 0)
+			goto err;
+		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME);
+		}
+	
+	/* n = p*q? */
+	r = BN_mul(i, key->p, key->q, ctx);
+	if (!r) { ret = -1; goto err; }
+	
+	if (BN_cmp(i, key->n) != 0)
+		{
+		ret = 0;
+		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q);
+		}
+	
+	/* d*e = 1  mod lcm(p-1,q-1)? */
+
+	r = BN_sub(i, key->p, BN_value_one());
+	if (!r) { ret = -1; goto err; }
+	r = BN_sub(j, key->q, BN_value_one());
+	if (!r) { ret = -1; goto err; }
+
+	/* now compute k = lcm(i,j) */
+	r = BN_mul(l, i, j, ctx);
+	if (!r) { ret = -1; goto err; }
+	r = BN_gcd(m, i, j, ctx);
+	if (!r) { ret = -1; goto err; }
+	r = BN_div(k, NULL, l, m, ctx); /* remainder is 0 */
+	if (!r) { ret = -1; goto err; }
+
+	r = BN_mod_mul(i, key->d, key->e, k, ctx);
+	if (!r) { ret = -1; goto err; }
+
+	if (!BN_is_one(i))
+		{
+		ret = 0;
+		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_D_E_NOT_CONGRUENT_TO_1);
+		}
+	
+	if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL)
+		{
+		/* dmp1 = d mod (p-1)? */
+		r = BN_sub(i, key->p, BN_value_one());
+		if (!r) { ret = -1; goto err; }
+
+		r = BN_mod(j, key->d, i, ctx);
+		if (!r) { ret = -1; goto err; }
+
+		if (BN_cmp(j, key->dmp1) != 0)
+			{
+			ret = 0;
+			RSAerr(RSA_F_RSA_CHECK_KEY,
+				RSA_R_DMP1_NOT_CONGRUENT_TO_D);
+			}
+	
+		/* dmq1 = d mod (q-1)? */    
+		r = BN_sub(i, key->q, BN_value_one());
+		if (!r) { ret = -1; goto err; }
+	
+		r = BN_mod(j, key->d, i, ctx);
+		if (!r) { ret = -1; goto err; }
+
+		if (BN_cmp(j, key->dmq1) != 0)
+			{
+			ret = 0;
+			RSAerr(RSA_F_RSA_CHECK_KEY,
+				RSA_R_DMQ1_NOT_CONGRUENT_TO_D);
+			}
+	
+		/* iqmp = q^-1 mod p? */
+		if(!BN_mod_inverse(i, key->q, key->p, ctx))
+			{
+			ret = -1;
+			goto err;
+			}
+
+		if (BN_cmp(i, key->iqmp) != 0)
+			{
+			ret = 0;
+			RSAerr(RSA_F_RSA_CHECK_KEY,
+				RSA_R_IQMP_NOT_INVERSE_OF_Q);
+			}
+		}
+
+ err:
+	if (i != NULL) BN_free(i);
+	if (j != NULL) BN_free(j);
+	if (k != NULL) BN_free(k);
+	if (l != NULL) BN_free(l);
+	if (m != NULL) BN_free(m);
+	if (ctx != NULL) BN_CTX_free(ctx);
+	return (ret);
+	}
diff --git a/openssl/crypto/rsa/rsa_depr.c b/openssl/crypto/rsa/rsa_depr.c
new file mode 100644
index 0000000..a859ded
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_depr.c
@@ -0,0 +1,101 @@
+/* crypto/rsa/rsa_depr.c */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NB: This file contains deprecated functions (compatibility wrappers to the
+ * "new" versions). */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+
+#ifdef OPENSSL_NO_DEPRECATED
+
+static void *dummy=&dummy;
+
+#else
+
+RSA *RSA_generate_key(int bits, unsigned long e_value,
+	     void (*callback)(int,int,void *), void *cb_arg)
+	{
+	BN_GENCB cb;
+	int i;
+	RSA *rsa = RSA_new();
+	BIGNUM *e = BN_new();
+
+	if(!rsa || !e) goto err;
+
+	/* The problem is when building with 8, 16, or 32 BN_ULONG,
+	 * unsigned long can be larger */
+	for (i=0; i<(int)sizeof(unsigned long)*8; i++)
+		{
+		if (e_value & (1UL<<i))
+			if (BN_set_bit(e,i) == 0)
+				goto err;
+		}
+
+	BN_GENCB_set_old(&cb, callback, cb_arg);
+
+	if(RSA_generate_key_ex(rsa, bits, e, &cb)) {
+		BN_free(e);
+		return rsa;
+	}
+err:
+	if(e) BN_free(e);
+	if(rsa) RSA_free(rsa);
+	return 0;
+	}
+#endif
diff --git a/openssl/crypto/rsa/rsa_eay.c b/openssl/crypto/rsa/rsa_eay.c
new file mode 100644
index 0000000..2e1ddd4
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_eay.c
@@ -0,0 +1,915 @@
+/* crypto/rsa/rsa_eay.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+
+#ifndef RSA_NULL
+
+static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx);
+static int RSA_eay_init(RSA *rsa);
+static int RSA_eay_finish(RSA *rsa);
+static RSA_METHOD rsa_pkcs1_eay_meth={
+	"Eric Young's PKCS#1 RSA",
+	RSA_eay_public_encrypt,
+	RSA_eay_public_decrypt, /* signature verification */
+	RSA_eay_private_encrypt, /* signing */
+	RSA_eay_private_decrypt,
+	RSA_eay_mod_exp,
+	BN_mod_exp_mont, /* XXX probably we should not use Montgomery if  e == 3 */
+	RSA_eay_init,
+	RSA_eay_finish,
+	0, /* flags */
+	NULL,
+	0, /* rsa_sign */
+	0, /* rsa_verify */
+	NULL /* rsa_keygen */
+	};
+
+const RSA_METHOD *RSA_PKCS1_SSLeay(void)
+	{
+	return(&rsa_pkcs1_eay_meth);
+	}
+
+static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+	BIGNUM *f,*ret;
+	int i,j,k,num=0,r= -1;
+	unsigned char *buf=NULL;
+	BN_CTX *ctx=NULL;
+
+	if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS)
+		{
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE);
+		return -1;
+		}
+
+	if (BN_ucmp(rsa->n, rsa->e) <= 0)
+		{
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
+		return -1;
+		}
+
+	/* for large moduli, enforce exponent limit */
+	if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS)
+		{
+		if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS)
+			{
+			RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
+			return -1;
+			}
+		}
+	
+	if ((ctx=BN_CTX_new()) == NULL) goto err;
+	BN_CTX_start(ctx);
+	f = BN_CTX_get(ctx);
+	ret = BN_CTX_get(ctx);
+	num=BN_num_bytes(rsa->n);
+	buf = OPENSSL_malloc(num);
+	if (!f || !ret || !buf)
+		{
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	switch (padding)
+		{
+	case RSA_PKCS1_PADDING:
+		i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen);
+		break;
+#ifndef OPENSSL_NO_SHA
+	case RSA_PKCS1_OAEP_PADDING:
+	        i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0);
+		break;
+#endif
+	case RSA_SSLV23_PADDING:
+		i=RSA_padding_add_SSLv23(buf,num,from,flen);
+		break;
+	case RSA_NO_PADDING:
+		i=RSA_padding_add_none(buf,num,from,flen);
+		break;
+	default:
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+		}
+	if (i <= 0) goto err;
+
+	if (BN_bin2bn(buf,num,f) == NULL) goto err;
+	
+	if (BN_ucmp(f, rsa->n) >= 0)
+		{
+		/* usually the padding functions would catch this */
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+		goto err;
+		}
+
+	if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+		if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+			goto err;
+
+	if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
+		rsa->_method_mod_n)) goto err;
+
+	/* put in leading 0 bytes if the number is less than the
+	 * length of the modulus */
+	j=BN_num_bytes(ret);
+	i=BN_bn2bin(ret,&(to[num-j]));
+	for (k=0; k<(num-i); k++)
+		to[k]=0;
+
+	r=num;
+err:
+	if (ctx != NULL)
+		{
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+		}
+	if (buf != NULL) 
+		{
+		OPENSSL_cleanse(buf,num);
+		OPENSSL_free(buf);
+		}
+	return(r);
+	}
+
+static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
+{
+	BN_BLINDING *ret;
+	int got_write_lock = 0;
+	CRYPTO_THREADID cur;
+
+	CRYPTO_r_lock(CRYPTO_LOCK_RSA);
+
+	if (rsa->blinding == NULL)
+		{
+		CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+		CRYPTO_w_lock(CRYPTO_LOCK_RSA);
+		got_write_lock = 1;
+
+		if (rsa->blinding == NULL)
+			rsa->blinding = RSA_setup_blinding(rsa, ctx);
+		}
+
+	ret = rsa->blinding;
+	if (ret == NULL)
+		goto err;
+
+	CRYPTO_THREADID_current(&cur);
+	if (!CRYPTO_THREADID_cmp(&cur, BN_BLINDING_thread_id(ret)))
+		{
+		/* rsa->blinding is ours! */
+
+		*local = 1;
+		}
+	else
+		{
+		/* resort to rsa->mt_blinding instead */
+
+		*local = 0; /* instructs rsa_blinding_convert(), rsa_blinding_invert()
+		             * that the BN_BLINDING is shared, meaning that accesses
+		             * require locks, and that the blinding factor must be
+		             * stored outside the BN_BLINDING
+		             */
+
+		if (rsa->mt_blinding == NULL)
+			{
+			if (!got_write_lock)
+				{
+				CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+				CRYPTO_w_lock(CRYPTO_LOCK_RSA);
+				got_write_lock = 1;
+				}
+			
+			if (rsa->mt_blinding == NULL)
+				rsa->mt_blinding = RSA_setup_blinding(rsa, ctx);
+			}
+		ret = rsa->mt_blinding;
+		}
+
+ err:
+	if (got_write_lock)
+		CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
+	else
+		CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+	return ret;
+}
+
+static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind,
+	BN_CTX *ctx)
+	{
+	if (unblind == NULL)
+		/* Local blinding: store the unblinding factor
+		 * in BN_BLINDING. */
+		return BN_BLINDING_convert_ex(f, NULL, b, ctx);
+	else
+		{
+		/* Shared blinding: store the unblinding factor
+		 * outside BN_BLINDING. */
+		int ret;
+		CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
+		ret = BN_BLINDING_convert_ex(f, unblind, b, ctx);
+		CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
+		return ret;
+		}
+	}
+
+static int rsa_blinding_invert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind,
+	BN_CTX *ctx)
+	{
+	/* For local blinding, unblind is set to NULL, and BN_BLINDING_invert_ex
+	 * will use the unblinding factor stored in BN_BLINDING.
+	 * If BN_BLINDING is shared between threads, unblind must be non-null:
+	 * BN_BLINDING_invert_ex will then use the local unblinding factor,
+	 * and will only read the modulus from BN_BLINDING.
+	 * In both cases it's safe to access the blinding without a lock.
+	 */
+	return BN_BLINDING_invert_ex(f, unblind, b, ctx);
+	}
+
+/* signing */
+static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+	BIGNUM *f, *ret, *res;
+	int i,j,k,num=0,r= -1;
+	unsigned char *buf=NULL;
+	BN_CTX *ctx=NULL;
+	int local_blinding = 0;
+	/* Used only if the blinding structure is shared. A non-NULL unblind
+	 * instructs rsa_blinding_convert() and rsa_blinding_invert() to store
+	 * the unblinding factor outside the blinding structure. */
+	BIGNUM *unblind = NULL;
+	BN_BLINDING *blinding = NULL;
+
+	if ((ctx=BN_CTX_new()) == NULL) goto err;
+	BN_CTX_start(ctx);
+	f   = BN_CTX_get(ctx);
+	ret = BN_CTX_get(ctx);
+	num = BN_num_bytes(rsa->n);
+	buf = OPENSSL_malloc(num);
+	if(!f || !ret || !buf)
+		{
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	switch (padding)
+		{
+	case RSA_PKCS1_PADDING:
+		i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen);
+		break;
+	case RSA_X931_PADDING:
+		i=RSA_padding_add_X931(buf,num,from,flen);
+		break;
+	case RSA_NO_PADDING:
+		i=RSA_padding_add_none(buf,num,from,flen);
+		break;
+	case RSA_SSLV23_PADDING:
+	default:
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+		}
+	if (i <= 0) goto err;
+
+	if (BN_bin2bn(buf,num,f) == NULL) goto err;
+	
+	if (BN_ucmp(f, rsa->n) >= 0)
+		{	
+		/* usually the padding functions would catch this */
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+		goto err;
+		}
+
+	if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
+		{
+		blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
+		if (blinding == NULL)
+			{
+			RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+		}
+	
+	if (blinding != NULL)
+		{
+		if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL))
+			{
+			RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		if (!rsa_blinding_convert(blinding, f, unblind, ctx))
+			goto err;
+		}
+
+	if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
+		((rsa->p != NULL) &&
+		(rsa->q != NULL) &&
+		(rsa->dmp1 != NULL) &&
+		(rsa->dmq1 != NULL) &&
+		(rsa->iqmp != NULL)) )
+		{ 
+		if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err;
+		}
+	else
+		{
+		BIGNUM local_d;
+		BIGNUM *d = NULL;
+		
+		if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+			{
+			BN_init(&local_d);
+			d = &local_d;
+			BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+			}
+		else
+			d= rsa->d;
+
+		if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+			if(!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+				goto err;
+
+		if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
+				rsa->_method_mod_n)) goto err;
+		}
+
+	if (blinding)
+		if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
+			goto err;
+
+	if (padding == RSA_X931_PADDING)
+		{
+		BN_sub(f, rsa->n, ret);
+		if (BN_cmp(ret, f))
+			res = f;
+		else
+			res = ret;
+		}
+	else
+		res = ret;
+
+	/* put in leading 0 bytes if the number is less than the
+	 * length of the modulus */
+	j=BN_num_bytes(res);
+	i=BN_bn2bin(res,&(to[num-j]));
+	for (k=0; k<(num-i); k++)
+		to[k]=0;
+
+	r=num;
+err:
+	if (ctx != NULL)
+		{
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+		}
+	if (buf != NULL)
+		{
+		OPENSSL_cleanse(buf,num);
+		OPENSSL_free(buf);
+		}
+	return(r);
+	}
+
+static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+	BIGNUM *f, *ret;
+	int j,num=0,r= -1;
+	unsigned char *p;
+	unsigned char *buf=NULL;
+	BN_CTX *ctx=NULL;
+	int local_blinding = 0;
+	/* Used only if the blinding structure is shared. A non-NULL unblind
+	 * instructs rsa_blinding_convert() and rsa_blinding_invert() to store
+	 * the unblinding factor outside the blinding structure. */
+	BIGNUM *unblind = NULL;
+	BN_BLINDING *blinding = NULL;
+
+	if((ctx = BN_CTX_new()) == NULL) goto err;
+	BN_CTX_start(ctx);
+	f   = BN_CTX_get(ctx);
+	ret = BN_CTX_get(ctx);
+	num = BN_num_bytes(rsa->n);
+	buf = OPENSSL_malloc(num);
+	if(!f || !ret || !buf)
+		{
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	/* This check was for equality but PGP does evil things
+	 * and chops off the top '0' bytes */
+	if (flen > num)
+		{
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
+		goto err;
+		}
+
+	/* make data into a big number */
+	if (BN_bin2bn(from,(int)flen,f) == NULL) goto err;
+
+	if (BN_ucmp(f, rsa->n) >= 0)
+		{
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+		goto err;
+		}
+
+	if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
+		{
+		blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
+		if (blinding == NULL)
+			{
+			RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+		}
+	
+	if (blinding != NULL)
+		{
+		if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL))
+			{
+			RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		if (!rsa_blinding_convert(blinding, f, unblind, ctx))
+			goto err;
+		}
+
+	/* do the decrypt */
+	if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
+		((rsa->p != NULL) &&
+		(rsa->q != NULL) &&
+		(rsa->dmp1 != NULL) &&
+		(rsa->dmq1 != NULL) &&
+		(rsa->iqmp != NULL)) )
+		{
+		if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err;
+		}
+	else
+		{
+		BIGNUM local_d;
+		BIGNUM *d = NULL;
+		
+		if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+			{
+			d = &local_d;
+			BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+			}
+		else
+			d = rsa->d;
+
+		if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+			if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+				goto err;
+		if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
+				rsa->_method_mod_n))
+		  goto err;
+		}
+
+	if (blinding)
+		if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
+			goto err;
+
+	p=buf;
+	j=BN_bn2bin(ret,p); /* j is only used with no-padding mode */
+
+	switch (padding)
+		{
+	case RSA_PKCS1_PADDING:
+		r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num);
+		break;
+#ifndef OPENSSL_NO_SHA
+        case RSA_PKCS1_OAEP_PADDING:
+	        r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0);
+                break;
+#endif
+ 	case RSA_SSLV23_PADDING:
+		r=RSA_padding_check_SSLv23(to,num,buf,j,num);
+		break;
+	case RSA_NO_PADDING:
+		r=RSA_padding_check_none(to,num,buf,j,num);
+		break;
+	default:
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+		}
+	if (r < 0)
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
+
+err:
+	if (ctx != NULL)
+		{
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+		}
+	if (buf != NULL)
+		{
+		OPENSSL_cleanse(buf,num);
+		OPENSSL_free(buf);
+		}
+	return(r);
+	}
+
+/* signature verification */
+static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+	BIGNUM *f,*ret;
+	int i,num=0,r= -1;
+	unsigned char *p;
+	unsigned char *buf=NULL;
+	BN_CTX *ctx=NULL;
+
+	if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS)
+		{
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE);
+		return -1;
+		}
+
+	if (BN_ucmp(rsa->n, rsa->e) <= 0)
+		{
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
+		return -1;
+		}
+
+	/* for large moduli, enforce exponent limit */
+	if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS)
+		{
+		if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS)
+			{
+			RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
+			return -1;
+			}
+		}
+	
+	if((ctx = BN_CTX_new()) == NULL) goto err;
+	BN_CTX_start(ctx);
+	f = BN_CTX_get(ctx);
+	ret = BN_CTX_get(ctx);
+	num=BN_num_bytes(rsa->n);
+	buf = OPENSSL_malloc(num);
+	if(!f || !ret || !buf)
+		{
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	/* This check was for equality but PGP does evil things
+	 * and chops off the top '0' bytes */
+	if (flen > num)
+		{
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
+		goto err;
+		}
+
+	if (BN_bin2bn(from,flen,f) == NULL) goto err;
+
+	if (BN_ucmp(f, rsa->n) >= 0)
+		{
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+		goto err;
+		}
+
+	if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+		if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+			goto err;
+
+	if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
+		rsa->_method_mod_n)) goto err;
+
+	if ((padding == RSA_X931_PADDING) && ((ret->d[0] & 0xf) != 12))
+		if (!BN_sub(ret, rsa->n, ret)) goto err;
+
+	p=buf;
+	i=BN_bn2bin(ret,p);
+
+	switch (padding)
+		{
+	case RSA_PKCS1_PADDING:
+		r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num);
+		break;
+	case RSA_X931_PADDING:
+		r=RSA_padding_check_X931(to,num,buf,i,num);
+		break;
+	case RSA_NO_PADDING:
+		r=RSA_padding_check_none(to,num,buf,i,num);
+		break;
+	default:
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+		}
+	if (r < 0)
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
+
+err:
+	if (ctx != NULL)
+		{
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+		}
+	if (buf != NULL)
+		{
+		OPENSSL_cleanse(buf,num);
+		OPENSSL_free(buf);
+		}
+	return(r);
+	}
+
+static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+	{
+	BIGNUM *r1,*m1,*vrfy;
+	BIGNUM local_dmp1,local_dmq1,local_c,local_r1;
+	BIGNUM *dmp1,*dmq1,*c,*pr1;
+	int ret=0;
+
+	BN_CTX_start(ctx);
+	r1 = BN_CTX_get(ctx);
+	m1 = BN_CTX_get(ctx);
+	vrfy = BN_CTX_get(ctx);
+
+	{
+		BIGNUM local_p, local_q;
+		BIGNUM *p = NULL, *q = NULL;
+
+		/* Make sure BN_mod_inverse in Montgomery intialization uses the
+		 * BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set)
+		 */
+		if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+			{
+			BN_init(&local_p);
+			p = &local_p;
+			BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
+
+			BN_init(&local_q);
+			q = &local_q;
+			BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME);
+			}
+		else
+			{
+			p = rsa->p;
+			q = rsa->q;
+			}
+
+		if (rsa->flags & RSA_FLAG_CACHE_PRIVATE)
+			{
+			if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, CRYPTO_LOCK_RSA, p, ctx))
+				goto err;
+			if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx))
+				goto err;
+			}
+	}
+
+	if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+		if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+			goto err;
+
+	/* compute I mod q */
+	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+		{
+		c = &local_c;
+		BN_with_flags(c, I, BN_FLG_CONSTTIME);
+		if (!BN_mod(r1,c,rsa->q,ctx)) goto err;
+		}
+	else
+		{
+		if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
+		}
+
+	/* compute r1^dmq1 mod q */
+	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+		{
+		dmq1 = &local_dmq1;
+		BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
+		}
+	else
+		dmq1 = rsa->dmq1;
+	if (!rsa->meth->bn_mod_exp(m1,r1,dmq1,rsa->q,ctx,
+		rsa->_method_mod_q)) goto err;
+
+	/* compute I mod p */
+	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+		{
+		c = &local_c;
+		BN_with_flags(c, I, BN_FLG_CONSTTIME);
+		if (!BN_mod(r1,c,rsa->p,ctx)) goto err;
+		}
+	else
+		{
+		if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
+		}
+
+	/* compute r1^dmp1 mod p */
+	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+		{
+		dmp1 = &local_dmp1;
+		BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
+		}
+	else
+		dmp1 = rsa->dmp1;
+	if (!rsa->meth->bn_mod_exp(r0,r1,dmp1,rsa->p,ctx,
+		rsa->_method_mod_p)) goto err;
+
+	if (!BN_sub(r0,r0,m1)) goto err;
+	/* This will help stop the size of r0 increasing, which does
+	 * affect the multiply if it optimised for a power of 2 size */
+	if (BN_is_negative(r0))
+		if (!BN_add(r0,r0,rsa->p)) goto err;
+
+	if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err;
+
+	/* Turn BN_FLG_CONSTTIME flag on before division operation */
+	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+		{
+		pr1 = &local_r1;
+		BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);
+		}
+	else
+		pr1 = r1;
+	if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err;
+
+	/* If p < q it is occasionally possible for the correction of
+         * adding 'p' if r0 is negative above to leave the result still
+	 * negative. This can break the private key operations: the following
+	 * second correction should *always* correct this rare occurrence.
+	 * This will *never* happen with OpenSSL generated keys because
+         * they ensure p > q [steve]
+         */
+	if (BN_is_negative(r0))
+		if (!BN_add(r0,r0,rsa->p)) goto err;
+	if (!BN_mul(r1,r0,rsa->q,ctx)) goto err;
+	if (!BN_add(r0,r1,m1)) goto err;
+
+	if (rsa->e && rsa->n)
+		{
+		if (!rsa->meth->bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err;
+		/* If 'I' was greater than (or equal to) rsa->n, the operation
+		 * will be equivalent to using 'I mod n'. However, the result of
+		 * the verify will *always* be less than 'n' so we don't check
+		 * for absolute equality, just congruency. */
+		if (!BN_sub(vrfy, vrfy, I)) goto err;
+		if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err;
+		if (BN_is_negative(vrfy))
+			if (!BN_add(vrfy, vrfy, rsa->n)) goto err;
+		if (!BN_is_zero(vrfy))
+			{
+			/* 'I' and 'vrfy' aren't congruent mod n. Don't leak
+			 * miscalculated CRT output, just do a raw (slower)
+			 * mod_exp and return that instead. */
+
+			BIGNUM local_d;
+			BIGNUM *d = NULL;
+		
+			if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+				{
+				d = &local_d;
+				BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+				}
+			else
+				d = rsa->d;
+			if (!rsa->meth->bn_mod_exp(r0,I,d,rsa->n,ctx,
+						   rsa->_method_mod_n)) goto err;
+			}
+		}
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	return(ret);
+	}
+
+static int RSA_eay_init(RSA *rsa)
+	{
+	rsa->flags|=RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE;
+	return(1);
+	}
+
+static int RSA_eay_finish(RSA *rsa)
+	{
+	if (rsa->_method_mod_n != NULL)
+		BN_MONT_CTX_free(rsa->_method_mod_n);
+	if (rsa->_method_mod_p != NULL)
+		BN_MONT_CTX_free(rsa->_method_mod_p);
+	if (rsa->_method_mod_q != NULL)
+		BN_MONT_CTX_free(rsa->_method_mod_q);
+	return(1);
+	}
+
+#endif
diff --git a/openssl/crypto/rsa/rsa_err.c b/openssl/crypto/rsa/rsa_err.c
new file mode 100644
index 0000000..cf9f110
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_err.c
@@ -0,0 +1,190 @@
+/* crypto/rsa/rsa_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/rsa.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_RSA,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_RSA,0,reason)
+
+static ERR_STRING_DATA RSA_str_functs[]=
+	{
+{ERR_FUNC(RSA_F_CHECK_PADDING_MD),	"CHECK_PADDING_MD"},
+{ERR_FUNC(RSA_F_DO_RSA_PRINT),	"DO_RSA_PRINT"},
+{ERR_FUNC(RSA_F_INT_RSA_VERIFY),	"INT_RSA_VERIFY"},
+{ERR_FUNC(RSA_F_MEMORY_LOCK),	"MEMORY_LOCK"},
+{ERR_FUNC(RSA_F_OLD_RSA_PRIV_DECODE),	"OLD_RSA_PRIV_DECODE"},
+{ERR_FUNC(RSA_F_PKEY_RSA_CTRL),	"PKEY_RSA_CTRL"},
+{ERR_FUNC(RSA_F_PKEY_RSA_CTRL_STR),	"PKEY_RSA_CTRL_STR"},
+{ERR_FUNC(RSA_F_PKEY_RSA_SIGN),	"PKEY_RSA_SIGN"},
+{ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER),	"PKEY_RSA_VERIFYRECOVER"},
+{ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN),	"RSA_BUILTIN_KEYGEN"},
+{ERR_FUNC(RSA_F_RSA_CHECK_KEY),	"RSA_check_key"},
+{ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_DECRYPT),	"RSA_EAY_PRIVATE_DECRYPT"},
+{ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_ENCRYPT),	"RSA_EAY_PRIVATE_ENCRYPT"},
+{ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_DECRYPT),	"RSA_EAY_PUBLIC_DECRYPT"},
+{ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_ENCRYPT),	"RSA_EAY_PUBLIC_ENCRYPT"},
+{ERR_FUNC(RSA_F_RSA_GENERATE_KEY),	"RSA_generate_key"},
+{ERR_FUNC(RSA_F_RSA_MEMORY_LOCK),	"RSA_memory_lock"},
+{ERR_FUNC(RSA_F_RSA_NEW_METHOD),	"RSA_new_method"},
+{ERR_FUNC(RSA_F_RSA_NULL),	"RSA_NULL"},
+{ERR_FUNC(RSA_F_RSA_NULL_MOD_EXP),	"RSA_NULL_MOD_EXP"},
+{ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_DECRYPT),	"RSA_NULL_PRIVATE_DECRYPT"},
+{ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_ENCRYPT),	"RSA_NULL_PRIVATE_ENCRYPT"},
+{ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_DECRYPT),	"RSA_NULL_PUBLIC_DECRYPT"},
+{ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_ENCRYPT),	"RSA_NULL_PUBLIC_ENCRYPT"},
+{ERR_FUNC(RSA_F_RSA_PADDING_ADD_NONE),	"RSA_padding_add_none"},
+{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP),	"RSA_padding_add_PKCS1_OAEP"},
+{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS),	"RSA_padding_add_PKCS1_PSS"},
+{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1),	"RSA_padding_add_PKCS1_type_1"},
+{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2),	"RSA_padding_add_PKCS1_type_2"},
+{ERR_FUNC(RSA_F_RSA_PADDING_ADD_SSLV23),	"RSA_padding_add_SSLv23"},
+{ERR_FUNC(RSA_F_RSA_PADDING_ADD_X931),	"RSA_padding_add_X931"},
+{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_NONE),	"RSA_padding_check_none"},
+{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP),	"RSA_padding_check_PKCS1_OAEP"},
+{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1),	"RSA_padding_check_PKCS1_type_1"},
+{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2),	"RSA_padding_check_PKCS1_type_2"},
+{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_SSLV23),	"RSA_padding_check_SSLv23"},
+{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931),	"RSA_padding_check_X931"},
+{ERR_FUNC(RSA_F_RSA_PRINT),	"RSA_print"},
+{ERR_FUNC(RSA_F_RSA_PRINT_FP),	"RSA_print_fp"},
+{ERR_FUNC(RSA_F_RSA_PRIV_DECODE),	"RSA_PRIV_DECODE"},
+{ERR_FUNC(RSA_F_RSA_PRIV_ENCODE),	"RSA_PRIV_ENCODE"},
+{ERR_FUNC(RSA_F_RSA_PUB_DECODE),	"RSA_PUB_DECODE"},
+{ERR_FUNC(RSA_F_RSA_SETUP_BLINDING),	"RSA_setup_blinding"},
+{ERR_FUNC(RSA_F_RSA_SIGN),	"RSA_sign"},
+{ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING),	"RSA_sign_ASN1_OCTET_STRING"},
+{ERR_FUNC(RSA_F_RSA_VERIFY),	"RSA_verify"},
+{ERR_FUNC(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING),	"RSA_verify_ASN1_OCTET_STRING"},
+{ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS),	"RSA_verify_PKCS1_PSS"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA RSA_str_reasons[]=
+	{
+{ERR_REASON(RSA_R_ALGORITHM_MISMATCH)    ,"algorithm mismatch"},
+{ERR_REASON(RSA_R_BAD_E_VALUE)           ,"bad e value"},
+{ERR_REASON(RSA_R_BAD_FIXED_HEADER_DECRYPT),"bad fixed header decrypt"},
+{ERR_REASON(RSA_R_BAD_PAD_BYTE_COUNT)    ,"bad pad byte count"},
+{ERR_REASON(RSA_R_BAD_SIGNATURE)         ,"bad signature"},
+{ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_01)  ,"block type is not 01"},
+{ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_02)  ,"block type is not 02"},
+{ERR_REASON(RSA_R_DATA_GREATER_THAN_MOD_LEN),"data greater than mod len"},
+{ERR_REASON(RSA_R_DATA_TOO_LARGE)        ,"data too large"},
+{ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"},
+{ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_MODULUS),"data too large for modulus"},
+{ERR_REASON(RSA_R_DATA_TOO_SMALL)        ,"data too small"},
+{ERR_REASON(RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE),"data too small for key size"},
+{ERR_REASON(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY),"digest too big for rsa key"},
+{ERR_REASON(RSA_R_DMP1_NOT_CONGRUENT_TO_D),"dmp1 not congruent to d"},
+{ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D),"dmq1 not congruent to d"},
+{ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1),"d e not congruent to 1"},
+{ERR_REASON(RSA_R_FIRST_OCTET_INVALID)   ,"first octet invalid"},
+{ERR_REASON(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE),"illegal or unsupported padding mode"},
+{ERR_REASON(RSA_R_INVALID_DIGEST_LENGTH) ,"invalid digest length"},
+{ERR_REASON(RSA_R_INVALID_HEADER)        ,"invalid header"},
+{ERR_REASON(RSA_R_INVALID_KEYBITS)       ,"invalid keybits"},
+{ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH),"invalid message length"},
+{ERR_REASON(RSA_R_INVALID_PADDING)       ,"invalid padding"},
+{ERR_REASON(RSA_R_INVALID_PADDING_MODE)  ,"invalid padding mode"},
+{ERR_REASON(RSA_R_INVALID_PSS_SALTLEN)   ,"invalid pss saltlen"},
+{ERR_REASON(RSA_R_INVALID_TRAILER)       ,"invalid trailer"},
+{ERR_REASON(RSA_R_INVALID_X931_DIGEST)   ,"invalid x931 digest"},
+{ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q) ,"iqmp not inverse of q"},
+{ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL)    ,"key size too small"},
+{ERR_REASON(RSA_R_LAST_OCTET_INVALID)    ,"last octet invalid"},
+{ERR_REASON(RSA_R_MODULUS_TOO_LARGE)     ,"modulus too large"},
+{ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT)    ,"no public exponent"},
+{ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING),"null before block missing"},
+{ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q)  ,"n does not equal p q"},
+{ERR_REASON(RSA_R_OAEP_DECODING_ERROR)   ,"oaep decoding error"},
+{ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supported for this keytype"},
+{ERR_REASON(RSA_R_PADDING_CHECK_FAILED)  ,"padding check failed"},
+{ERR_REASON(RSA_R_P_NOT_PRIME)           ,"p not prime"},
+{ERR_REASON(RSA_R_Q_NOT_PRIME)           ,"q not prime"},
+{ERR_REASON(RSA_R_RSA_OPERATIONS_NOT_SUPPORTED),"rsa operations not supported"},
+{ERR_REASON(RSA_R_SLEN_CHECK_FAILED)     ,"salt length check failed"},
+{ERR_REASON(RSA_R_SLEN_RECOVERY_FAILED)  ,"salt length recovery failed"},
+{ERR_REASON(RSA_R_SSLV3_ROLLBACK_ATTACK) ,"sslv3 rollback attack"},
+{ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),"the asn1 object identifier is not known for this md"},
+{ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE),"unknown algorithm type"},
+{ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE)  ,"unknown padding type"},
+{ERR_REASON(RSA_R_VALUE_MISSING)         ,"value missing"},
+{ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH),"wrong signature length"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_RSA_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(RSA_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,RSA_str_functs);
+		ERR_load_strings(0,RSA_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/rsa/rsa_gen.c b/openssl/crypto/rsa/rsa_gen.c
new file mode 100644
index 0000000..767f7ab
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_gen.c
@@ -0,0 +1,219 @@
+/* crypto/rsa/rsa_gen.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+
+/* NB: these functions have been "upgraded", the deprecated versions (which are
+ * compatibility wrappers using these functions) are in rsa_depr.c.
+ * - Geoff
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+
+static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);
+
+/* NB: this wrapper would normally be placed in rsa_lib.c and the static
+ * implementation would probably be in rsa_eay.c. Nonetheless, is kept here so
+ * that we don't introduce a new linker dependency. Eg. any application that
+ * wasn't previously linking object code related to key-generation won't have to
+ * now just because key-generation is part of RSA_METHOD. */
+int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
+	{
+	if(rsa->meth->rsa_keygen)
+		return rsa->meth->rsa_keygen(rsa, bits, e_value, cb);
+	return rsa_builtin_keygen(rsa, bits, e_value, cb);
+	}
+
+static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
+	{
+	BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
+	BIGNUM local_r0,local_d,local_p;
+	BIGNUM *pr0,*d,*p;
+	int bitsp,bitsq,ok= -1,n=0;
+	BN_CTX *ctx=NULL;
+
+	ctx=BN_CTX_new();
+	if (ctx == NULL) goto err;
+	BN_CTX_start(ctx);
+	r0 = BN_CTX_get(ctx);
+	r1 = BN_CTX_get(ctx);
+	r2 = BN_CTX_get(ctx);
+	r3 = BN_CTX_get(ctx);
+	if (r3 == NULL) goto err;
+
+	bitsp=(bits+1)/2;
+	bitsq=bits-bitsp;
+
+	/* We need the RSA components non-NULL */
+	if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err;
+	if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err;
+	if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err;
+	if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err;
+	if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err;
+	if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err;
+	if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err;
+	if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err;
+
+	BN_copy(rsa->e, e_value);
+
+	/* generate p and q */
+	for (;;)
+		{
+		if(!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))
+			goto err;
+		if (!BN_sub(r2,rsa->p,BN_value_one())) goto err;
+		if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
+		if (BN_is_one(r1)) break;
+		if(!BN_GENCB_call(cb, 2, n++))
+			goto err;
+		}
+	if(!BN_GENCB_call(cb, 3, 0))
+		goto err;
+	for (;;)
+		{
+		/* When generating ridiculously small keys, we can get stuck
+		 * continually regenerating the same prime values. Check for
+		 * this and bail if it happens 3 times. */
+		unsigned int degenerate = 0;
+		do
+			{
+			if(!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb))
+				goto err;
+			} while((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
+		if(degenerate == 3)
+			{
+			ok = 0; /* we set our own err */
+			RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_KEY_SIZE_TOO_SMALL);
+			goto err;
+			}
+		if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;
+		if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
+		if (BN_is_one(r1))
+			break;
+		if(!BN_GENCB_call(cb, 2, n++))
+			goto err;
+		}
+	if(!BN_GENCB_call(cb, 3, 1))
+		goto err;
+	if (BN_cmp(rsa->p,rsa->q) < 0)
+		{
+		tmp=rsa->p;
+		rsa->p=rsa->q;
+		rsa->q=tmp;
+		}
+
+	/* calculate n */
+	if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err;
+
+	/* calculate d */
+	if (!BN_sub(r1,rsa->p,BN_value_one())) goto err;	/* p-1 */
+	if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;	/* q-1 */
+	if (!BN_mul(r0,r1,r2,ctx)) goto err;	/* (p-1)(q-1) */
+	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+		{
+		  pr0 = &local_r0;
+		  BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
+		}
+	else
+	  pr0 = r0;
+	if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err;	/* d */
+
+	/* set up d for correct BN_FLG_CONSTTIME flag */
+	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+		{
+		d = &local_d;
+		BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+		}
+	else
+		d = rsa->d;
+
+	/* calculate d mod (p-1) */
+	if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err;
+
+	/* calculate d mod (q-1) */
+	if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err;
+
+	/* calculate inverse of q mod p */
+	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+		{
+		p = &local_p;
+		BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
+		}
+	else
+		p = rsa->p;
+	if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err;
+
+	ok=1;
+err:
+	if (ok == -1)
+		{
+		RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN);
+		ok=0;
+		}
+	if (ctx != NULL)
+		{
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+		}
+
+	return ok;
+	}
+
diff --git a/openssl/crypto/rsa/rsa_lib.c b/openssl/crypto/rsa/rsa_lib.c
new file mode 100644
index 0000000..de45088
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_lib.c
@@ -0,0 +1,483 @@
+/* crypto/rsa/rsa_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT;
+
+static const RSA_METHOD *default_RSA_meth=NULL;
+
+RSA *RSA_new(void)
+	{
+	RSA *r=RSA_new_method(NULL);
+
+	return r;
+	}
+
+void RSA_set_default_method(const RSA_METHOD *meth)
+	{
+	default_RSA_meth = meth;
+	}
+
+const RSA_METHOD *RSA_get_default_method(void)
+	{
+	if (default_RSA_meth == NULL)
+		{
+#ifdef RSA_NULL
+		default_RSA_meth=RSA_null_method();
+#else
+#if 0 /* was: #ifdef RSAref */
+		default_RSA_meth=RSA_PKCS1_RSAref();
+#else
+		default_RSA_meth=RSA_PKCS1_SSLeay();
+#endif
+#endif
+		}
+
+	return default_RSA_meth;
+	}
+
+const RSA_METHOD *RSA_get_method(const RSA *rsa)
+	{
+	return rsa->meth;
+	}
+
+int RSA_set_method(RSA *rsa, const RSA_METHOD *meth)
+	{
+	/* NB: The caller is specifically setting a method, so it's not up to us
+	 * to deal with which ENGINE it comes from. */
+	const RSA_METHOD *mtmp;
+	mtmp = rsa->meth;
+	if (mtmp->finish) mtmp->finish(rsa);
+#ifndef OPENSSL_NO_ENGINE
+	if (rsa->engine)
+		{
+		ENGINE_finish(rsa->engine);
+		rsa->engine = NULL;
+		}
+#endif
+	rsa->meth = meth;
+	if (meth->init) meth->init(rsa);
+	return 1;
+	}
+
+RSA *RSA_new_method(ENGINE *engine)
+	{
+	RSA *ret;
+
+	ret=(RSA *)OPENSSL_malloc(sizeof(RSA));
+	if (ret == NULL)
+		{
+		RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+
+	ret->meth = RSA_get_default_method();
+#ifndef OPENSSL_NO_ENGINE
+	if (engine)
+		{
+		if (!ENGINE_init(engine))
+			{
+			RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB);
+			OPENSSL_free(ret);
+			return NULL;
+			}
+		ret->engine = engine;
+		}
+	else
+		ret->engine = ENGINE_get_default_RSA();
+	if(ret->engine)
+		{
+		ret->meth = ENGINE_get_RSA(ret->engine);
+		if(!ret->meth)
+			{
+			RSAerr(RSA_F_RSA_NEW_METHOD,
+				ERR_R_ENGINE_LIB);
+			ENGINE_finish(ret->engine);
+			OPENSSL_free(ret);
+			return NULL;
+			}
+		}
+#endif
+
+	ret->pad=0;
+	ret->version=0;
+	ret->n=NULL;
+	ret->e=NULL;
+	ret->d=NULL;
+	ret->p=NULL;
+	ret->q=NULL;
+	ret->dmp1=NULL;
+	ret->dmq1=NULL;
+	ret->iqmp=NULL;
+	ret->references=1;
+	ret->_method_mod_n=NULL;
+	ret->_method_mod_p=NULL;
+	ret->_method_mod_q=NULL;
+	ret->blinding=NULL;
+	ret->mt_blinding=NULL;
+	ret->bignum_data=NULL;
+	ret->flags=ret->meth->flags;
+	if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data))
+		{
+#ifndef OPENSSL_NO_ENGINE
+	if (ret->engine)
+		ENGINE_finish(ret->engine);
+#endif
+		OPENSSL_free(ret);
+		return(NULL);
+		}
+
+	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
+		{
+#ifndef OPENSSL_NO_ENGINE
+		if (ret->engine)
+			ENGINE_finish(ret->engine);
+#endif
+		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data);
+		OPENSSL_free(ret);
+		ret=NULL;
+		}
+	return(ret);
+	}
+
+void RSA_free(RSA *r)
+	{
+	int i;
+
+	if (r == NULL) return;
+
+	i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_RSA);
+#ifdef REF_PRINT
+	REF_PRINT("RSA",r);
+#endif
+	if (i > 0) return;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"RSA_free, bad reference count\n");
+		abort();
+		}
+#endif
+
+	if (r->meth->finish)
+		r->meth->finish(r);
+#ifndef OPENSSL_NO_ENGINE
+	if (r->engine)
+		ENGINE_finish(r->engine);
+#endif
+
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data);
+
+	if (r->n != NULL) BN_clear_free(r->n);
+	if (r->e != NULL) BN_clear_free(r->e);
+	if (r->d != NULL) BN_clear_free(r->d);
+	if (r->p != NULL) BN_clear_free(r->p);
+	if (r->q != NULL) BN_clear_free(r->q);
+	if (r->dmp1 != NULL) BN_clear_free(r->dmp1);
+	if (r->dmq1 != NULL) BN_clear_free(r->dmq1);
+	if (r->iqmp != NULL) BN_clear_free(r->iqmp);
+	if (r->blinding != NULL) BN_BLINDING_free(r->blinding);
+	if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding);
+	if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data);
+	OPENSSL_free(r);
+	}
+
+int RSA_up_ref(RSA *r)
+	{
+	int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA);
+#ifdef REF_PRINT
+	REF_PRINT("RSA",r);
+#endif
+#ifdef REF_CHECK
+	if (i < 2)
+		{
+		fprintf(stderr, "RSA_up_ref, bad reference count\n");
+		abort();
+		}
+#endif
+	return ((i > 1) ? 1 : 0);
+	}
+
+int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+        {
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp,
+				new_func, dup_func, free_func);
+        }
+
+int RSA_set_ex_data(RSA *r, int idx, void *arg)
+	{
+	return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
+	}
+
+void *RSA_get_ex_data(const RSA *r, int idx)
+	{
+	return(CRYPTO_get_ex_data(&r->ex_data,idx));
+	}
+
+int RSA_size(const RSA *r)
+	{
+	return(BN_num_bytes(r->n));
+	}
+
+int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
+	     RSA *rsa, int padding)
+	{
+	return(rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding));
+	}
+
+int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
+	     RSA *rsa, int padding)
+	{
+	return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding));
+	}
+
+int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
+	     RSA *rsa, int padding)
+	{
+	return(rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding));
+	}
+
+int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
+	     RSA *rsa, int padding)
+	{
+	return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding));
+	}
+
+int RSA_flags(const RSA *r)
+	{
+	return((r == NULL)?0:r->meth->flags);
+	}
+
+void RSA_blinding_off(RSA *rsa)
+	{
+	if (rsa->blinding != NULL)
+		{
+		BN_BLINDING_free(rsa->blinding);
+		rsa->blinding=NULL;
+		}
+	rsa->flags &= ~RSA_FLAG_BLINDING;
+	rsa->flags |= RSA_FLAG_NO_BLINDING;
+	}
+
+int RSA_blinding_on(RSA *rsa, BN_CTX *ctx)
+	{
+	int ret=0;
+
+	if (rsa->blinding != NULL)
+		RSA_blinding_off(rsa);
+
+	rsa->blinding = RSA_setup_blinding(rsa, ctx);
+	if (rsa->blinding == NULL)
+		goto err;
+
+	rsa->flags |= RSA_FLAG_BLINDING;
+	rsa->flags &= ~RSA_FLAG_NO_BLINDING;
+	ret=1;
+err:
+	return(ret);
+	}
+
+static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
+	const BIGNUM *q, BN_CTX *ctx)
+{
+	BIGNUM *ret = NULL, *r0, *r1, *r2;
+
+	if (d == NULL || p == NULL || q == NULL)
+		return NULL;
+
+	BN_CTX_start(ctx);
+	r0 = BN_CTX_get(ctx);
+	r1 = BN_CTX_get(ctx);
+	r2 = BN_CTX_get(ctx);
+	if (r2 == NULL)
+		goto err;
+
+	if (!BN_sub(r1, p, BN_value_one())) goto err;
+	if (!BN_sub(r2, q, BN_value_one())) goto err;
+	if (!BN_mul(r0, r1, r2, ctx)) goto err;
+
+	ret = BN_mod_inverse(NULL, d, r0, ctx);
+err:
+	BN_CTX_end(ctx);
+	return ret;
+}
+
+BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
+{
+	BIGNUM local_n;
+	BIGNUM *e,*n;
+	BN_CTX *ctx;
+	BN_BLINDING *ret = NULL;
+
+	if (in_ctx == NULL)
+		{
+		if ((ctx = BN_CTX_new()) == NULL) return 0;
+		}
+	else
+		ctx = in_ctx;
+
+	BN_CTX_start(ctx);
+	e  = BN_CTX_get(ctx);
+	if (e == NULL)
+		{
+		RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (rsa->e == NULL)
+		{
+		e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
+		if (e == NULL)
+			{
+			RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT);
+			goto err;
+			}
+		}
+	else
+		e = rsa->e;
+
+	
+	if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL)
+		{
+		/* if PRNG is not properly seeded, resort to secret
+		 * exponent as unpredictable seed */
+		RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0);
+		}
+
+	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+		{
+		/* Set BN_FLG_CONSTTIME flag */
+		n = &local_n;
+		BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
+		}
+	else
+		n = rsa->n;
+
+	ret = BN_BLINDING_create_param(NULL, e, n, ctx,
+			rsa->meth->bn_mod_exp, rsa->_method_mod_n);
+	if (ret == NULL)
+		{
+		RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
+		goto err;
+		}
+	CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret));
+err:
+	BN_CTX_end(ctx);
+	if (in_ctx == NULL)
+		BN_CTX_free(ctx);
+	if(rsa->e == NULL)
+		BN_free(e);
+
+	return ret;
+}
+
+int RSA_memory_lock(RSA *r)
+	{
+	int i,j,k,off;
+	char *p;
+	BIGNUM *bn,**t[6],*b;
+	BN_ULONG *ul;
+
+	if (r->d == NULL) return(1);
+	t[0]= &r->d;
+	t[1]= &r->p;
+	t[2]= &r->q;
+	t[3]= &r->dmp1;
+	t[4]= &r->dmq1;
+	t[5]= &r->iqmp;
+	k=sizeof(BIGNUM)*6;
+	off=k/sizeof(BN_ULONG)+1;
+	j=1;
+	for (i=0; i<6; i++)
+		j+= (*t[i])->top;
+	if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL)
+		{
+		RSAerr(RSA_F_RSA_MEMORY_LOCK,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	bn=(BIGNUM *)p;
+	ul=(BN_ULONG *)&(p[off]);
+	for (i=0; i<6; i++)
+		{
+		b= *(t[i]);
+		*(t[i])= &(bn[i]);
+		memcpy((char *)&(bn[i]),(char *)b,sizeof(BIGNUM));
+		bn[i].flags=BN_FLG_STATIC_DATA;
+		bn[i].d=ul;
+		memcpy((char *)ul,b->d,sizeof(BN_ULONG)*b->top);
+		ul+=b->top;
+		BN_clear_free(b);
+		}
+	
+	/* I should fix this so it can still be done */
+	r->flags&= ~(RSA_FLAG_CACHE_PRIVATE|RSA_FLAG_CACHE_PUBLIC);
+
+	r->bignum_data=p;
+	return(1);
+	}
diff --git a/openssl/crypto/rsa/rsa_locl.h b/openssl/crypto/rsa/rsa_locl.h
new file mode 100644
index 0000000..f5d2d56
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_locl.h
@@ -0,0 +1,4 @@
+extern int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
+		unsigned char *rm, size_t *prm_len,
+		const unsigned char *sigbuf, size_t siglen,
+		RSA *rsa);
diff --git a/openssl/crypto/rsa/rsa_none.c b/openssl/crypto/rsa/rsa_none.c
new file mode 100644
index 0000000..e6f3e62
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_none.c
@@ -0,0 +1,98 @@
+/* crypto/rsa/rsa_none.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+
+int RSA_padding_add_none(unsigned char *to, int tlen,
+	const unsigned char *from, int flen)
+	{
+	if (flen > tlen)
+		{
+		RSAerr(RSA_F_RSA_PADDING_ADD_NONE,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		return(0);
+		}
+
+	if (flen < tlen)
+		{
+		RSAerr(RSA_F_RSA_PADDING_ADD_NONE,RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE);
+		return(0);
+		}
+	
+	memcpy(to,from,(unsigned int)flen);
+	return(1);
+	}
+
+int RSA_padding_check_none(unsigned char *to, int tlen,
+	const unsigned char *from, int flen, int num)
+	{
+
+	if (flen > tlen)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_NONE,RSA_R_DATA_TOO_LARGE);
+		return(-1);
+		}
+
+	memset(to,0,tlen-flen);
+	memcpy(to+tlen-flen,from,flen);
+	return(tlen);
+	}
+
diff --git a/openssl/crypto/rsa/rsa_null.c b/openssl/crypto/rsa/rsa_null.c
new file mode 100644
index 0000000..2f2202f
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_null.c
@@ -0,0 +1,151 @@
+/* rsa_null.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+
+/* This is a dummy RSA implementation that just returns errors when called.
+ * It is designed to allow some RSA functions to work while stopping those
+ * covered by the RSA patent. That is RSA, encryption, decryption, signing
+ * and verify is not allowed but RSA key generation, key checking and other
+ * operations (like storing RSA keys) are permitted.
+ */
+
+static int RSA_null_public_encrypt(int flen, const unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+static int RSA_null_private_encrypt(int flen, const unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+static int RSA_null_public_decrypt(int flen, const unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+static int RSA_null_private_decrypt(int flen, const unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+#if 0 /* not currently used */
+static int RSA_null_mod_exp(const BIGNUM *r0, const BIGNUM *i, RSA *rsa);
+#endif
+static int RSA_null_init(RSA *rsa);
+static int RSA_null_finish(RSA *rsa);
+static RSA_METHOD rsa_null_meth={
+	"Null RSA",
+	RSA_null_public_encrypt,
+	RSA_null_public_decrypt,
+	RSA_null_private_encrypt,
+	RSA_null_private_decrypt,
+	NULL,
+	NULL,
+	RSA_null_init,
+	RSA_null_finish,
+	0,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+	};
+
+const RSA_METHOD *RSA_null_method(void)
+	{
+	return(&rsa_null_meth);
+	}
+
+static int RSA_null_public_encrypt(int flen, const unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+	RSAerr(RSA_F_RSA_NULL_PUBLIC_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+	return -1;
+	}
+
+static int RSA_null_private_encrypt(int flen, const unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+	RSAerr(RSA_F_RSA_NULL_PRIVATE_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+	return -1;
+	}
+
+static int RSA_null_private_decrypt(int flen, const unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+	RSAerr(RSA_F_RSA_NULL_PRIVATE_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+	return -1;
+	}
+
+static int RSA_null_public_decrypt(int flen, const unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+	RSAerr(RSA_F_RSA_NULL_PUBLIC_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+	return -1;
+	}
+
+#if 0 /* not currently used */
+static int RSA_null_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
+	{
+	...err(RSA_F_RSA_NULL_MOD_EXP, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+	return -1;
+	}
+#endif
+
+static int RSA_null_init(RSA *rsa)
+	{
+	return(1);
+	}
+
+static int RSA_null_finish(RSA *rsa)
+	{
+	return(1);
+	}
diff --git a/openssl/crypto/rsa/rsa_oaep.c b/openssl/crypto/rsa/rsa_oaep.c
new file mode 100644
index 0000000..18d307e
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_oaep.c
@@ -0,0 +1,233 @@
+/* crypto/rsa/rsa_oaep.c */
+/* Written by Ulf Moeller. This software is distributed on an "AS IS"
+   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. */
+
+/* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */
+
+/* See Victor Shoup, "OAEP reconsidered," Nov. 2000,
+ * <URL: http://www.shoup.net/papers/oaep.ps.Z>
+ * for problems with the security proof for the
+ * original OAEP scheme, which EME-OAEP is based on.
+ * 
+ * A new proof can be found in E. Fujisaki, T. Okamoto,
+ * D. Pointcheval, J. Stern, "RSA-OEAP is Still Alive!",
+ * Dec. 2000, <URL: http://eprint.iacr.org/2000/061/>.
+ * The new proof has stronger requirements for the
+ * underlying permutation: "partial-one-wayness" instead
+ * of one-wayness.  For the RSA function, this is
+ * an equivalent notion.
+ */
+
+
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+static int MGF1(unsigned char *mask, long len,
+	const unsigned char *seed, long seedlen);
+
+int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
+	const unsigned char *from, int flen,
+	const unsigned char *param, int plen)
+	{
+	int i, emlen = tlen - 1;
+	unsigned char *db, *seed;
+	unsigned char *dbmask, seedmask[SHA_DIGEST_LENGTH];
+
+	if (flen > emlen - 2 * SHA_DIGEST_LENGTH - 1)
+		{
+		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP,
+		   RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		return 0;
+		}
+
+	if (emlen < 2 * SHA_DIGEST_LENGTH + 1)
+		{
+		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, RSA_R_KEY_SIZE_TOO_SMALL);
+		return 0;
+		}
+
+	to[0] = 0;
+	seed = to + 1;
+	db = to + SHA_DIGEST_LENGTH + 1;
+
+	EVP_Digest((void *)param, plen, db, NULL, EVP_sha1(), NULL);
+	memset(db + SHA_DIGEST_LENGTH, 0,
+		emlen - flen - 2 * SHA_DIGEST_LENGTH - 1);
+	db[emlen - flen - SHA_DIGEST_LENGTH - 1] = 0x01;
+	memcpy(db + emlen - flen - SHA_DIGEST_LENGTH, from, (unsigned int) flen);
+	if (RAND_bytes(seed, SHA_DIGEST_LENGTH) <= 0)
+		return 0;
+#ifdef PKCS_TESTVECT
+	memcpy(seed,
+	   "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f",
+	   20);
+#endif
+
+	dbmask = OPENSSL_malloc(emlen - SHA_DIGEST_LENGTH);
+	if (dbmask == NULL)
+		{
+		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+
+	if (MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH) < 0)
+		return 0;
+	for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++)
+		db[i] ^= dbmask[i];
+
+	if (MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH) < 0)
+		return 0;
+	for (i = 0; i < SHA_DIGEST_LENGTH; i++)
+		seed[i] ^= seedmask[i];
+
+	OPENSSL_free(dbmask);
+	return 1;
+	}
+
+int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
+	const unsigned char *from, int flen, int num,
+	const unsigned char *param, int plen)
+	{
+	int i, dblen, mlen = -1;
+	const unsigned char *maskeddb;
+	int lzero;
+	unsigned char *db = NULL, seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH];
+	unsigned char *padded_from;
+	int bad = 0;
+
+	if (--num < 2 * SHA_DIGEST_LENGTH + 1)
+		/* 'num' is the length of the modulus, i.e. does not depend on the
+		 * particular ciphertext. */
+		goto decoding_err;
+
+	lzero = num - flen;
+	if (lzero < 0)
+		{
+		/* signalling this error immediately after detection might allow
+		 * for side-channel attacks (e.g. timing if 'plen' is huge
+		 * -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA Optimal
+		 * Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001),
+		 * so we use a 'bad' flag */
+		bad = 1;
+		lzero = 0;
+		flen = num; /* don't overflow the memcpy to padded_from */
+		}
+
+	dblen = num - SHA_DIGEST_LENGTH;
+	db = OPENSSL_malloc(dblen + num);
+	if (db == NULL)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
+		return -1;
+		}
+
+	/* Always do this zero-padding copy (even when lzero == 0)
+	 * to avoid leaking timing info about the value of lzero. */
+	padded_from = db + dblen;
+	memset(padded_from, 0, lzero);
+	memcpy(padded_from + lzero, from, flen);
+
+	maskeddb = padded_from + SHA_DIGEST_LENGTH;
+
+	if (MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen))
+		return -1;
+	for (i = 0; i < SHA_DIGEST_LENGTH; i++)
+		seed[i] ^= padded_from[i];
+  
+	if (MGF1(db, dblen, seed, SHA_DIGEST_LENGTH))
+		return -1;
+	for (i = 0; i < dblen; i++)
+		db[i] ^= maskeddb[i];
+
+	EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL);
+
+	if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
+		goto decoding_err;
+	else
+		{
+		for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
+			if (db[i] != 0x00)
+				break;
+		if (i == dblen || db[i] != 0x01)
+			goto decoding_err;
+		else
+			{
+			/* everything looks OK */
+
+			mlen = dblen - ++i;
+			if (tlen < mlen)
+				{
+				RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE);
+				mlen = -1;
+				}
+			else
+				memcpy(to, db + i, mlen);
+			}
+		}
+	OPENSSL_free(db);
+	return mlen;
+
+decoding_err:
+	/* to avoid chosen ciphertext attacks, the error message should not reveal
+	 * which kind of decoding error happened */
+	RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_OAEP_DECODING_ERROR);
+	if (db != NULL) OPENSSL_free(db);
+	return -1;
+	}
+
+int PKCS1_MGF1(unsigned char *mask, long len,
+	const unsigned char *seed, long seedlen, const EVP_MD *dgst)
+	{
+	long i, outlen = 0;
+	unsigned char cnt[4];
+	EVP_MD_CTX c;
+	unsigned char md[EVP_MAX_MD_SIZE];
+	int mdlen;
+	int rv = -1;
+
+	EVP_MD_CTX_init(&c);
+	mdlen = EVP_MD_size(dgst);
+	if (mdlen < 0)
+		goto err;
+	for (i = 0; outlen < len; i++)
+		{
+		cnt[0] = (unsigned char)((i >> 24) & 255);
+		cnt[1] = (unsigned char)((i >> 16) & 255);
+		cnt[2] = (unsigned char)((i >> 8)) & 255;
+		cnt[3] = (unsigned char)(i & 255);
+		if (!EVP_DigestInit_ex(&c,dgst, NULL)
+			|| !EVP_DigestUpdate(&c, seed, seedlen)
+			|| !EVP_DigestUpdate(&c, cnt, 4))
+			goto err;
+		if (outlen + mdlen <= len)
+			{
+			if (!EVP_DigestFinal_ex(&c, mask + outlen, NULL))
+				goto err;
+			outlen += mdlen;
+			}
+		else
+			{
+			if (!EVP_DigestFinal_ex(&c, md, NULL))
+				goto err;
+			memcpy(mask + outlen, md, len - outlen);
+			outlen = len;
+			}
+		}
+	rv = 0;
+	err:
+	EVP_MD_CTX_cleanup(&c);
+	return rv;
+	}
+
+static int MGF1(unsigned char *mask, long len, const unsigned char *seed,
+		 long seedlen)
+	{
+	return PKCS1_MGF1(mask, len, seed, seedlen, EVP_sha1());
+	}
+#endif
diff --git a/openssl/crypto/rsa/rsa_pk1.c b/openssl/crypto/rsa/rsa_pk1.c
new file mode 100644
index 0000000..8560755
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_pk1.c
@@ -0,0 +1,224 @@
+/* crypto/rsa/rsa_pk1.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+
+int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen,
+	     const unsigned char *from, int flen)
+	{
+	int j;
+	unsigned char *p;
+
+	if (flen > (tlen-RSA_PKCS1_PADDING_SIZE))
+		{
+		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		return(0);
+		}
+	
+	p=(unsigned char *)to;
+
+	*(p++)=0;
+	*(p++)=1; /* Private Key BT (Block Type) */
+
+	/* pad out with 0xff data */
+	j=tlen-3-flen;
+	memset(p,0xff,j);
+	p+=j;
+	*(p++)='\0';
+	memcpy(p,from,(unsigned int)flen);
+	return(1);
+	}
+
+int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen,
+	     const unsigned char *from, int flen, int num)
+	{
+	int i,j;
+	const unsigned char *p;
+
+	p=from;
+	if ((num != (flen+1)) || (*(p++) != 01))
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BLOCK_TYPE_IS_NOT_01);
+		return(-1);
+		}
+
+	/* scan over padding data */
+	j=flen-1; /* one for type. */
+	for (i=0; i<j; i++)
+		{
+		if (*p != 0xff) /* should decrypt to 0xff */
+			{
+			if (*p == 0)
+				{ p++; break; }
+			else	{
+				RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BAD_FIXED_HEADER_DECRYPT);
+				return(-1);
+				}
+			}
+		p++;
+		}
+
+	if (i == j)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_NULL_BEFORE_BLOCK_MISSING);
+		return(-1);
+		}
+
+	if (i < 8)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BAD_PAD_BYTE_COUNT);
+		return(-1);
+		}
+	i++; /* Skip over the '\0' */
+	j-=i;
+	if (j > tlen)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_DATA_TOO_LARGE);
+		return(-1);
+		}
+	memcpy(to,p,(unsigned int)j);
+
+	return(j);
+	}
+
+int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen,
+	     const unsigned char *from, int flen)
+	{
+	int i,j;
+	unsigned char *p;
+	
+	if (flen > (tlen-11))
+		{
+		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		return(0);
+		}
+	
+	p=(unsigned char *)to;
+
+	*(p++)=0;
+	*(p++)=2; /* Public Key BT (Block Type) */
+
+	/* pad out with non-zero random data */
+	j=tlen-3-flen;
+
+	if (RAND_bytes(p,j) <= 0)
+		return(0);
+	for (i=0; i<j; i++)
+		{
+		if (*p == '\0')
+			do	{
+				if (RAND_bytes(p,1) <= 0)
+					return(0);
+				} while (*p == '\0');
+		p++;
+		}
+
+	*(p++)='\0';
+
+	memcpy(p,from,(unsigned int)flen);
+	return(1);
+	}
+
+int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
+	     const unsigned char *from, int flen, int num)
+	{
+	int i,j;
+	const unsigned char *p;
+
+	p=from;
+	if ((num != (flen+1)) || (*(p++) != 02))
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_BLOCK_TYPE_IS_NOT_02);
+		return(-1);
+		}
+#ifdef PKCS1_CHECK
+	return(num-11);
+#endif
+
+	/* scan over padding data */
+	j=flen-1; /* one for type. */
+	for (i=0; i<j; i++)
+		if (*(p++) == 0) break;
+
+	if (i == j)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_NULL_BEFORE_BLOCK_MISSING);
+		return(-1);
+		}
+
+	if (i < 8)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_BAD_PAD_BYTE_COUNT);
+		return(-1);
+		}
+	i++; /* Skip over the '\0' */
+	j-=i;
+	if (j > tlen)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_DATA_TOO_LARGE);
+		return(-1);
+		}
+	memcpy(to,p,(unsigned int)j);
+
+	return(j);
+	}
+
diff --git a/openssl/crypto/rsa/rsa_pmeth.c b/openssl/crypto/rsa/rsa_pmeth.c
new file mode 100644
index 0000000..c6892ec
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_pmeth.c
@@ -0,0 +1,587 @@
+/* crypto/rsa/rsa_pmeth.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rsa.h>
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include "evp_locl.h"
+#include "rsa_locl.h"
+
+/* RSA pkey context structure */
+
+typedef struct
+	{
+	/* Key gen parameters */
+	int nbits;
+	BIGNUM *pub_exp;
+	/* Keygen callback info */
+	int gentmp[2];
+	/* RSA padding mode */
+	int pad_mode;
+	/* message digest */
+	const EVP_MD *md;
+	/* PSS/OAEP salt length */
+	int saltlen;
+	/* Temp buffer */
+	unsigned char *tbuf;
+	} RSA_PKEY_CTX;
+
+static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
+	{
+	RSA_PKEY_CTX *rctx;
+	rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX));
+	if (!rctx)
+		return 0;
+	rctx->nbits = 1024;
+	rctx->pub_exp = NULL;
+	rctx->pad_mode = RSA_PKCS1_PADDING;
+	rctx->md = NULL;
+	rctx->tbuf = NULL;
+
+	rctx->saltlen = -2;
+
+	ctx->data = rctx;
+	ctx->keygen_info = rctx->gentmp;
+	ctx->keygen_info_count = 2;
+	
+	return 1;
+	}
+
+static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+	{
+	RSA_PKEY_CTX *dctx, *sctx;
+	if (!pkey_rsa_init(dst))
+		return 0;
+       	sctx = src->data;
+	dctx = dst->data;
+	dctx->nbits = sctx->nbits;
+	if (sctx->pub_exp)
+		{
+		dctx->pub_exp = BN_dup(sctx->pub_exp);
+		if (!dctx->pub_exp)
+			return 0;
+		}
+	dctx->pad_mode = sctx->pad_mode;
+	dctx->md = sctx->md;
+	return 1;
+	}
+
+static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
+	{
+	if (ctx->tbuf)
+		return 1;
+	ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
+	if (!ctx->tbuf)
+		return 0;
+	return 1;
+	}
+
+static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx)
+	{
+	RSA_PKEY_CTX *rctx = ctx->data;
+	if (rctx)
+		{
+		if (rctx->pub_exp)
+			BN_free(rctx->pub_exp);
+		if (rctx->tbuf)
+			OPENSSL_free(rctx->tbuf);
+		OPENSSL_free(rctx);
+		}
+	}
+
+static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					const unsigned char *tbs, size_t tbslen)
+	{
+	int ret;
+	RSA_PKEY_CTX *rctx = ctx->data;
+	RSA *rsa = ctx->pkey->pkey.rsa;
+
+	if (rctx->md)
+		{
+		if (tbslen != (size_t)EVP_MD_size(rctx->md))
+			{
+			RSAerr(RSA_F_PKEY_RSA_SIGN,
+					RSA_R_INVALID_DIGEST_LENGTH);
+			return -1;
+			}
+		if (rctx->pad_mode == RSA_X931_PADDING)
+			{
+			if (!setup_tbuf(rctx, ctx))
+				return -1;
+			memcpy(rctx->tbuf, tbs, tbslen);
+			rctx->tbuf[tbslen] =
+				RSA_X931_hash_id(EVP_MD_type(rctx->md));
+			ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
+						sig, rsa, RSA_X931_PADDING);
+			}
+		else if (rctx->pad_mode == RSA_PKCS1_PADDING)
+			{
+			unsigned int sltmp;
+			ret = RSA_sign(EVP_MD_type(rctx->md),
+						tbs, tbslen, sig, &sltmp, rsa);
+			if (ret <= 0)
+				return ret;
+			ret = sltmp;
+			}
+		else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
+			{
+			if (!setup_tbuf(rctx, ctx))
+				return -1;
+			if (!RSA_padding_add_PKCS1_PSS(rsa, rctx->tbuf, tbs,
+						rctx->md, rctx->saltlen))
+				return -1;
+			ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf,
+						sig, rsa, RSA_NO_PADDING);
+			}
+		else
+			return -1;
+		}
+	else
+		ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
+							rctx->pad_mode);
+	if (ret < 0)
+		return ret;
+	*siglen = ret;
+	return 1;
+	}
+
+
+static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
+					unsigned char *rout, size_t *routlen,
+					const unsigned char *sig, size_t siglen)
+	{
+	int ret;
+	RSA_PKEY_CTX *rctx = ctx->data;
+
+	if (rctx->md)
+		{
+		if (rctx->pad_mode == RSA_X931_PADDING)
+			{
+			if (!setup_tbuf(rctx, ctx))
+				return -1;
+			ret = RSA_public_decrypt(siglen, sig,
+						rctx->tbuf, ctx->pkey->pkey.rsa,
+						RSA_X931_PADDING);
+			if (ret < 1)
+				return 0;
+			ret--;
+			if (rctx->tbuf[ret] !=
+				RSA_X931_hash_id(EVP_MD_type(rctx->md)))
+				{
+				RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
+						RSA_R_ALGORITHM_MISMATCH);
+				return 0;
+				}
+			if (ret != EVP_MD_size(rctx->md))
+				{
+				RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
+					RSA_R_INVALID_DIGEST_LENGTH);
+				return 0;
+				}
+			if (rout)
+				memcpy(rout, rctx->tbuf, ret);
+			}
+		else if (rctx->pad_mode == RSA_PKCS1_PADDING)
+			{
+			size_t sltmp;
+			ret = int_rsa_verify(EVP_MD_type(rctx->md),
+						NULL, 0, rout, &sltmp,
+					sig, siglen, ctx->pkey->pkey.rsa);
+			if (ret <= 0)
+				return 0;
+			ret = sltmp;
+			}
+		else
+			return -1;
+		}
+	else
+		ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa,
+							rctx->pad_mode);
+	if (ret < 0)
+		return ret;
+	*routlen = ret;
+	return 1;
+	}
+
+static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
+					const unsigned char *sig, size_t siglen,
+					const unsigned char *tbs, size_t tbslen)
+	{
+	RSA_PKEY_CTX *rctx = ctx->data;
+	RSA *rsa = ctx->pkey->pkey.rsa;
+	size_t rslen;
+	if (rctx->md)
+		{
+		if (rctx->pad_mode == RSA_PKCS1_PADDING)
+			return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
+					sig, siglen, rsa);
+		if (rctx->pad_mode == RSA_X931_PADDING)
+			{
+			if (pkey_rsa_verifyrecover(ctx, NULL, &rslen,
+					sig, siglen) <= 0)
+				return 0;
+			}
+		else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
+			{
+			int ret;
+			if (!setup_tbuf(rctx, ctx))
+				return -1;
+			ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
+							rsa, RSA_NO_PADDING);
+			if (ret <= 0)
+				return 0;
+			ret = RSA_verify_PKCS1_PSS(rsa, tbs, rctx->md,
+						rctx->tbuf, rctx->saltlen);
+			if (ret <= 0)
+				return 0;
+			return 1;
+			}
+		else
+			return -1;
+		}
+	else
+		{
+		if (!setup_tbuf(rctx, ctx))
+			return -1;
+		rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
+						rsa, rctx->pad_mode);
+		if (rslen == 0)
+			return 0;
+		}
+
+	if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen))
+		return 0;
+
+	return 1;
+			
+	}
+	
+
+static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx,
+					unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen)
+	{
+	int ret;
+	RSA_PKEY_CTX *rctx = ctx->data;
+	ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
+							rctx->pad_mode);
+	if (ret < 0)
+		return ret;
+	*outlen = ret;
+	return 1;
+	}
+
+static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx,
+					unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen)
+	{
+	int ret;
+	RSA_PKEY_CTX *rctx = ctx->data;
+	ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
+							rctx->pad_mode);
+	if (ret < 0)
+		return ret;
+	*outlen = ret;
+	return 1;
+	}
+
+static int check_padding_md(const EVP_MD *md, int padding)
+	{
+	if (!md)
+		return 1;
+
+	if (padding == RSA_NO_PADDING)
+		{
+		RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE);
+		return 0;
+		}
+
+	if (padding == RSA_X931_PADDING)
+		{
+		if (RSA_X931_hash_id(EVP_MD_type(md)) == -1)
+			{
+			RSAerr(RSA_F_CHECK_PADDING_MD,
+						RSA_R_INVALID_X931_DIGEST);
+			return 0;
+			}
+		return 1;
+		}
+
+	return 1;
+	}
+			
+
+static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+	{
+	RSA_PKEY_CTX *rctx = ctx->data;
+	switch (type)
+		{
+		case EVP_PKEY_CTRL_RSA_PADDING:
+		if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING))
+			{
+			if (!check_padding_md(rctx->md, p1))
+				return 0;
+			if (p1 == RSA_PKCS1_PSS_PADDING) 
+				{
+				if (!(ctx->operation &
+				     (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY)))
+					goto bad_pad;
+				if (!rctx->md)
+					rctx->md = EVP_sha1();
+				}
+			if (p1 == RSA_PKCS1_OAEP_PADDING) 
+				{
+				if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))
+					goto bad_pad;
+				if (!rctx->md)
+					rctx->md = EVP_sha1();
+				}
+			rctx->pad_mode = p1;
+			return 1;
+			}
+		bad_pad:
+		RSAerr(RSA_F_PKEY_RSA_CTRL,
+				RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
+		return -2;
+
+		case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
+		if (p1 < -2)
+			return -2;
+		if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING)
+			{
+			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN);
+			return -2;
+			}
+		rctx->saltlen = p1;
+		return 1;
+
+		case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
+		if (p1 < 256)
+			{
+			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS);
+			return -2;
+			}
+		rctx->nbits = p1;
+		return 1;
+
+		case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
+		if (!p2)
+			return -2;
+		rctx->pub_exp = p2;
+		return 1;
+
+		case EVP_PKEY_CTRL_MD:
+		if (!check_padding_md(p2, rctx->pad_mode))
+			return 0;
+		rctx->md = p2;
+		return 1;
+
+		case EVP_PKEY_CTRL_DIGESTINIT:
+		case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
+		case EVP_PKEY_CTRL_PKCS7_DECRYPT:
+		case EVP_PKEY_CTRL_PKCS7_SIGN:
+#ifndef OPENSSL_NO_CMS
+		case EVP_PKEY_CTRL_CMS_ENCRYPT:
+		case EVP_PKEY_CTRL_CMS_DECRYPT:
+		case EVP_PKEY_CTRL_CMS_SIGN:
+#endif
+		return 1;
+		case EVP_PKEY_CTRL_PEER_KEY:
+			RSAerr(RSA_F_PKEY_RSA_CTRL,
+			RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+			return -2;	
+
+		default:
+		return -2;
+
+		}
+	}
+			
+static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
+			const char *type, const char *value)
+	{
+	if (!value)
+		{
+		RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING);
+		return 0;
+		}
+	if (!strcmp(type, "rsa_padding_mode"))
+		{
+		int pm;
+		if (!strcmp(value, "pkcs1"))
+			pm = RSA_PKCS1_PADDING;
+		else if (!strcmp(value, "sslv23"))
+			pm = RSA_SSLV23_PADDING;
+		else if (!strcmp(value, "none"))
+			pm = RSA_NO_PADDING;
+		else if (!strcmp(value, "oeap"))
+			pm = RSA_PKCS1_OAEP_PADDING;
+		else if (!strcmp(value, "x931"))
+			pm = RSA_X931_PADDING;
+		else if (!strcmp(value, "pss"))
+			pm = RSA_PKCS1_PSS_PADDING;
+		else
+			{
+			RSAerr(RSA_F_PKEY_RSA_CTRL_STR,
+						RSA_R_UNKNOWN_PADDING_TYPE);
+			return -2;
+			}
+		return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
+		}
+
+	if (!strcmp(type, "rsa_pss_saltlen"))
+		{
+		int saltlen;
+		saltlen = atoi(value);
+		return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen);
+		}
+
+	if (!strcmp(type, "rsa_keygen_bits"))
+		{
+		int nbits;
+		nbits = atoi(value);
+		return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits);
+		}
+
+	if (!strcmp(type, "rsa_keygen_pubexp"))
+		{
+		int ret;
+		BIGNUM *pubexp = NULL;
+		if (!BN_asc2bn(&pubexp, value))
+			return 0;
+		ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp);
+		if (ret <= 0)
+			BN_free(pubexp);
+		return ret;
+		}
+
+	return -2;
+	}
+
+static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+	RSA *rsa = NULL;
+	RSA_PKEY_CTX *rctx = ctx->data;
+	BN_GENCB *pcb, cb;
+	int ret;
+	if (!rctx->pub_exp)
+		{
+		rctx->pub_exp = BN_new();
+		if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4))
+			return 0;
+		}
+	rsa = RSA_new();
+	if (!rsa)
+		return 0;
+	if (ctx->pkey_gencb)
+		{
+		pcb = &cb;
+		evp_pkey_set_cb_translate(pcb, ctx);
+		}
+	else
+		pcb = NULL;
+	ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb);
+	if (ret > 0)
+		EVP_PKEY_assign_RSA(pkey, rsa);
+	else
+		RSA_free(rsa);
+	return ret;
+	}
+
+const EVP_PKEY_METHOD rsa_pkey_meth = 
+	{
+	EVP_PKEY_RSA,
+	EVP_PKEY_FLAG_AUTOARGLEN,
+	pkey_rsa_init,
+	pkey_rsa_copy,
+	pkey_rsa_cleanup,
+
+	0,0,
+
+	0,
+	pkey_rsa_keygen,
+
+	0,
+	pkey_rsa_sign,
+
+	0,
+	pkey_rsa_verify,
+
+	0,
+	pkey_rsa_verifyrecover,
+
+
+	0,0,0,0,
+
+	0,
+	pkey_rsa_encrypt,
+
+	0,
+	pkey_rsa_decrypt,
+
+	0,0,
+
+	pkey_rsa_ctrl,
+	pkey_rsa_ctrl_str
+
+
+	};
diff --git a/openssl/crypto/rsa/rsa_prn.c b/openssl/crypto/rsa/rsa_prn.c
new file mode 100644
index 0000000..224db0f
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_prn.c
@@ -0,0 +1,93 @@
+/* crypto/rsa/rsa_prn.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+
+#ifndef OPENSSL_NO_FP_API
+int RSA_print_fp(FILE *fp, const RSA *x, int off)
+	{
+	BIO *b;
+	int ret;
+
+	if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB);
+		return(0);
+		}
+	BIO_set_fp(b,fp,BIO_NOCLOSE);
+	ret=RSA_print(b,x,off);
+	BIO_free(b);
+	return(ret);
+	}
+#endif
+
+int RSA_print(BIO *bp, const RSA *x, int off)
+	{
+	EVP_PKEY *pk;
+	int ret;
+	pk = EVP_PKEY_new();
+	if (!pk || !EVP_PKEY_set1_RSA(pk, (RSA *)x))
+		return 0;
+	ret = EVP_PKEY_print_private(bp, pk, off, NULL);
+	EVP_PKEY_free(pk);
+	return ret;
+	}
+
diff --git a/openssl/crypto/rsa/rsa_pss.c b/openssl/crypto/rsa/rsa_pss.c
new file mode 100644
index 0000000..ac211e2
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_pss.c
@@ -0,0 +1,275 @@
+/* rsa_pss.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+static const unsigned char zeroes[] = {0,0,0,0,0,0,0,0};
+
+#if defined(_MSC_VER) && defined(_ARM_)
+#pragma optimize("g", off)
+#endif
+
+int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
+			const EVP_MD *Hash, const unsigned char *EM, int sLen)
+	{
+	int i;
+	int ret = 0;
+	int hLen, maskedDBLen, MSBits, emLen;
+	const unsigned char *H;
+	unsigned char *DB = NULL;
+	EVP_MD_CTX ctx;
+	unsigned char H_[EVP_MAX_MD_SIZE];
+
+	hLen = EVP_MD_size(Hash);
+	if (hLen < 0)
+		goto err;
+	/*
+	 * Negative sLen has special meanings:
+	 *	-1	sLen == hLen
+	 *	-2	salt length is autorecovered from signature
+	 *	-N	reserved
+	 */
+	if      (sLen == -1)	sLen = hLen;
+	else if (sLen == -2)	sLen = -2;
+	else if (sLen < -2)
+		{
+		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED);
+		goto err;
+		}
+
+	MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
+	emLen = RSA_size(rsa);
+	if (EM[0] & (0xFF << MSBits))
+		{
+		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_FIRST_OCTET_INVALID);
+		goto err;
+		}
+	if (MSBits == 0)
+		{
+		EM++;
+		emLen--;
+		}
+	if (emLen < (hLen + sLen + 2)) /* sLen can be small negative */
+		{
+		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_DATA_TOO_LARGE);
+		goto err;
+		}
+	if (EM[emLen - 1] != 0xbc)
+		{
+		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_LAST_OCTET_INVALID);
+		goto err;
+		}
+	maskedDBLen = emLen - hLen - 1;
+	H = EM + maskedDBLen;
+	DB = OPENSSL_malloc(maskedDBLen);
+	if (!DB)
+		{
+		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash) < 0)
+		goto err;
+	for (i = 0; i < maskedDBLen; i++)
+		DB[i] ^= EM[i];
+	if (MSBits)
+		DB[0] &= 0xFF >> (8 - MSBits);
+	for (i = 0; DB[i] == 0 && i < (maskedDBLen-1); i++) ;
+	if (DB[i++] != 0x1)
+		{
+		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_RECOVERY_FAILED);
+		goto err;
+		}
+	if (sLen >= 0 && (maskedDBLen - i) != sLen)
+		{
+		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED);
+		goto err;
+		}
+	EVP_MD_CTX_init(&ctx);
+	EVP_DigestInit_ex(&ctx, Hash, NULL);
+	EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes);
+	EVP_DigestUpdate(&ctx, mHash, hLen);
+	if (maskedDBLen - i)
+		EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i);
+	EVP_DigestFinal(&ctx, H_, NULL);
+	EVP_MD_CTX_cleanup(&ctx);
+	if (memcmp(H_, H, hLen))
+		{
+		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_BAD_SIGNATURE);
+		ret = 0;
+		}
+	else 
+		ret = 1;
+
+	err:
+	if (DB)
+		OPENSSL_free(DB);
+
+	return ret;
+
+	}
+
+int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
+			const unsigned char *mHash,
+			const EVP_MD *Hash, int sLen)
+	{
+	int i;
+	int ret = 0;
+	int hLen, maskedDBLen, MSBits, emLen;
+	unsigned char *H, *salt = NULL, *p;
+	EVP_MD_CTX ctx;
+
+	hLen = EVP_MD_size(Hash);
+	if (hLen < 0)
+		goto err;
+	/*
+	 * Negative sLen has special meanings:
+	 *	-1	sLen == hLen
+	 *	-2	salt length is maximized
+	 *	-N	reserved
+	 */
+	if      (sLen == -1)	sLen = hLen;
+	else if (sLen == -2)	sLen = -2;
+	else if (sLen < -2)
+		{
+		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED);
+		goto err;
+		}
+
+	MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
+	emLen = RSA_size(rsa);
+	if (MSBits == 0)
+		{
+		*EM++ = 0;
+		emLen--;
+		}
+	if (sLen == -2)
+		{
+		sLen = emLen - hLen - 2;
+		}
+	else if (emLen < (hLen + sLen + 2))
+		{
+		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS,
+		   RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		goto err;
+		}
+	if (sLen > 0)
+		{
+		salt = OPENSSL_malloc(sLen);
+		if (!salt)
+			{
+			RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS,
+		   		ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		if (RAND_bytes(salt, sLen) <= 0)
+			goto err;
+		}
+	maskedDBLen = emLen - hLen - 1;
+	H = EM + maskedDBLen;
+	EVP_MD_CTX_init(&ctx);
+	EVP_DigestInit_ex(&ctx, Hash, NULL);
+	EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes);
+	EVP_DigestUpdate(&ctx, mHash, hLen);
+	if (sLen)
+		EVP_DigestUpdate(&ctx, salt, sLen);
+	EVP_DigestFinal(&ctx, H, NULL);
+	EVP_MD_CTX_cleanup(&ctx);
+
+	/* Generate dbMask in place then perform XOR on it */
+	if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash))
+		goto err;
+
+	p = EM;
+
+	/* Initial PS XORs with all zeroes which is a NOP so just update
+	 * pointer. Note from a test above this value is guaranteed to
+	 * be non-negative.
+	 */
+	p += emLen - sLen - hLen - 2;
+	*p++ ^= 0x1;
+	if (sLen > 0)
+		{
+		for (i = 0; i < sLen; i++)
+			*p++ ^= salt[i];
+		}
+	if (MSBits)
+		EM[0] &= 0xFF >> (8 - MSBits);
+
+	/* H is already in place so just set final 0xbc */
+
+	EM[emLen - 1] = 0xbc;
+
+	ret = 1;
+
+	err:
+	if (salt)
+		OPENSSL_free(salt);
+
+	return ret;
+
+	}
+
+#if defined(_MSC_VER)
+#pragma optimize("",on)
+#endif
diff --git a/openssl/crypto/rsa/rsa_saos.c b/openssl/crypto/rsa/rsa_saos.c
new file mode 100644
index 0000000..f98e0a8
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_saos.c
@@ -0,0 +1,150 @@
+/* crypto/rsa/rsa_saos.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int RSA_sign_ASN1_OCTET_STRING(int type,
+	const unsigned char *m, unsigned int m_len,
+	unsigned char *sigret, unsigned int *siglen, RSA *rsa)
+	{
+	ASN1_OCTET_STRING sig;
+	int i,j,ret=1;
+	unsigned char *p,*s;
+
+	sig.type=V_ASN1_OCTET_STRING;
+	sig.length=m_len;
+	sig.data=(unsigned char *)m;
+
+	i=i2d_ASN1_OCTET_STRING(&sig,NULL);
+	j=RSA_size(rsa);
+	if (i > (j-RSA_PKCS1_PADDING_SIZE))
+		{
+		RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
+		return(0);
+		}
+	s=(unsigned char *)OPENSSL_malloc((unsigned int)j+1);
+	if (s == NULL)
+		{
+		RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	p=s;
+	i2d_ASN1_OCTET_STRING(&sig,&p);
+	i=RSA_private_encrypt(i,s,sigret,rsa,RSA_PKCS1_PADDING);
+	if (i <= 0)
+		ret=0;
+	else
+		*siglen=i;
+
+	OPENSSL_cleanse(s,(unsigned int)j+1);
+	OPENSSL_free(s);
+	return(ret);
+	}
+
+int RSA_verify_ASN1_OCTET_STRING(int dtype,
+	const unsigned char *m,
+	unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
+	RSA *rsa)
+	{
+	int i,ret=0;
+	unsigned char *s;
+	const unsigned char *p;
+	ASN1_OCTET_STRING *sig=NULL;
+
+	if (siglen != (unsigned int)RSA_size(rsa))
+		{
+		RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING,RSA_R_WRONG_SIGNATURE_LENGTH);
+		return(0);
+		}
+
+	s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen);
+	if (s == NULL)
+		{
+		RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
+
+	if (i <= 0) goto err;
+
+	p=s;
+	sig=d2i_ASN1_OCTET_STRING(NULL,&p,(long)i);
+	if (sig == NULL) goto err;
+
+	if (	((unsigned int)sig->length != m_len) ||
+		(memcmp(m,sig->data,m_len) != 0))
+		{
+		RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING,RSA_R_BAD_SIGNATURE);
+		}
+	else
+		ret=1;
+err:
+	if (sig != NULL) M_ASN1_OCTET_STRING_free(sig);
+	if (s != NULL)
+		{
+		OPENSSL_cleanse(s,(unsigned int)siglen);
+		OPENSSL_free(s);
+		}
+	return(ret);
+	}
+
diff --git a/openssl/crypto/rsa/rsa_sign.c b/openssl/crypto/rsa/rsa_sign.c
new file mode 100644
index 0000000..0be4ec7
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_sign.c
@@ -0,0 +1,285 @@
+/* crypto/rsa/rsa_sign.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include "rsa_locl.h"
+
+/* Size of an SSL signature: MD5+SHA1 */
+#define SSL_SIG_LENGTH	36
+
+int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
+	     unsigned char *sigret, unsigned int *siglen, RSA *rsa)
+	{
+	X509_SIG sig;
+	ASN1_TYPE parameter;
+	int i,j,ret=1;
+	unsigned char *p, *tmps = NULL;
+	const unsigned char *s = NULL;
+	X509_ALGOR algor;
+	ASN1_OCTET_STRING digest;
+	if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign)
+		{
+		return rsa->meth->rsa_sign(type, m, m_len,
+			sigret, siglen, rsa);
+		}
+	/* Special case: SSL signature, just check the length */
+	if(type == NID_md5_sha1) {
+		if(m_len != SSL_SIG_LENGTH) {
+			RSAerr(RSA_F_RSA_SIGN,RSA_R_INVALID_MESSAGE_LENGTH);
+			return(0);
+		}
+		i = SSL_SIG_LENGTH;
+		s = m;
+	} else {
+		sig.algor= &algor;
+		sig.algor->algorithm=OBJ_nid2obj(type);
+		if (sig.algor->algorithm == NULL)
+			{
+			RSAerr(RSA_F_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);
+			return(0);
+			}
+		if (sig.algor->algorithm->length == 0)
+			{
+			RSAerr(RSA_F_RSA_SIGN,RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
+			return(0);
+			}
+		parameter.type=V_ASN1_NULL;
+		parameter.value.ptr=NULL;
+		sig.algor->parameter= &parameter;
+
+		sig.digest= &digest;
+		sig.digest->data=(unsigned char *)m; /* TMP UGLY CAST */
+		sig.digest->length=m_len;
+
+		i=i2d_X509_SIG(&sig,NULL);
+	}
+	j=RSA_size(rsa);
+	if (i > (j-RSA_PKCS1_PADDING_SIZE))
+		{
+		RSAerr(RSA_F_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
+		return(0);
+		}
+	if(type != NID_md5_sha1) {
+		tmps=(unsigned char *)OPENSSL_malloc((unsigned int)j+1);
+		if (tmps == NULL)
+			{
+			RSAerr(RSA_F_RSA_SIGN,ERR_R_MALLOC_FAILURE);
+			return(0);
+			}
+		p=tmps;
+		i2d_X509_SIG(&sig,&p);
+		s=tmps;
+	}
+	i=RSA_private_encrypt(i,s,sigret,rsa,RSA_PKCS1_PADDING);
+	if (i <= 0)
+		ret=0;
+	else
+		*siglen=i;
+
+	if(type != NID_md5_sha1) {
+		OPENSSL_cleanse(tmps,(unsigned int)j+1);
+		OPENSSL_free(tmps);
+	}
+	return(ret);
+	}
+
+int int_rsa_verify(int dtype, const unsigned char *m,
+			  unsigned int m_len,
+			  unsigned char *rm, size_t *prm_len,
+			  const unsigned char *sigbuf, size_t siglen,
+			  RSA *rsa)
+	{
+	int i,ret=0,sigtype;
+	unsigned char *s;
+	X509_SIG *sig=NULL;
+
+	if (siglen != (unsigned int)RSA_size(rsa))
+		{
+		RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH);
+		return(0);
+		}
+
+	if((dtype == NID_md5_sha1) && rm)
+		{
+		i = RSA_public_decrypt((int)siglen,
+					sigbuf,rm,rsa,RSA_PKCS1_PADDING);
+		if (i <= 0)
+			return 0;
+		*prm_len = i;
+		return 1;
+		}
+
+	s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen);
+	if (s == NULL)
+		{
+		RSAerr(RSA_F_INT_RSA_VERIFY,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) {
+			RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH);
+			goto err;
+	}
+	i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
+
+	if (i <= 0) goto err;
+
+	/* Special case: SSL signature */
+	if(dtype == NID_md5_sha1) {
+		if((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH))
+				RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+		else ret = 1;
+	} else {
+		const unsigned char *p=s;
+		sig=d2i_X509_SIG(NULL,&p,(long)i);
+
+		if (sig == NULL) goto err;
+
+		/* Excess data can be used to create forgeries */
+		if(p != s+i)
+			{
+			RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+			goto err;
+			}
+
+		/* Parameters to the signature algorithm can also be used to
+		   create forgeries */
+		if(sig->algor->parameter
+		   && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL)
+			{
+			RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+			goto err;
+			}
+
+		sigtype=OBJ_obj2nid(sig->algor->algorithm);
+
+
+	#ifdef RSA_DEBUG
+		/* put a backward compatibility flag in EAY */
+		fprintf(stderr,"in(%s) expect(%s)\n",OBJ_nid2ln(sigtype),
+			OBJ_nid2ln(dtype));
+	#endif
+		if (sigtype != dtype)
+			{
+			if (((dtype == NID_md5) &&
+				(sigtype == NID_md5WithRSAEncryption)) ||
+				((dtype == NID_md2) &&
+				(sigtype == NID_md2WithRSAEncryption)))
+				{
+				/* ok, we will let it through */
+#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
+				fprintf(stderr,"signature has problems, re-make with post SSLeay045\n");
+#endif
+				}
+			else
+				{
+				RSAerr(RSA_F_INT_RSA_VERIFY,
+						RSA_R_ALGORITHM_MISMATCH);
+				goto err;
+				}
+			}
+		if (rm)
+			{
+			const EVP_MD *md;
+			md = EVP_get_digestbynid(dtype);
+			if (md && (EVP_MD_size(md) != sig->digest->length))
+				RSAerr(RSA_F_INT_RSA_VERIFY,
+						RSA_R_INVALID_DIGEST_LENGTH);
+			else
+				{
+				memcpy(rm, sig->digest->data,
+							sig->digest->length);
+				*prm_len = sig->digest->length;
+				ret = 1;
+				}
+			}
+		else if (((unsigned int)sig->digest->length != m_len) ||
+			(memcmp(m,sig->digest->data,m_len) != 0))
+			{
+			RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+			}
+		else
+			ret=1;
+	}
+err:
+	if (sig != NULL) X509_SIG_free(sig);
+	if (s != NULL)
+		{
+		OPENSSL_cleanse(s,(unsigned int)siglen);
+		OPENSSL_free(s);
+		}
+	return(ret);
+	}
+
+int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
+		const unsigned char *sigbuf, unsigned int siglen,
+		RSA *rsa)
+	{
+
+	if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify)
+		{
+		return rsa->meth->rsa_verify(dtype, m, m_len,
+			sigbuf, siglen, rsa);
+		}
+
+	return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa);
+	}
diff --git a/openssl/crypto/rsa/rsa_ssl.c b/openssl/crypto/rsa/rsa_ssl.c
new file mode 100644
index 0000000..cfeff15
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_ssl.c
@@ -0,0 +1,154 @@
+/* crypto/rsa/rsa_ssl.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+
+int RSA_padding_add_SSLv23(unsigned char *to, int tlen,
+	const unsigned char *from, int flen)
+	{
+	int i,j;
+	unsigned char *p;
+	
+	if (flen > (tlen-11))
+		{
+		RSAerr(RSA_F_RSA_PADDING_ADD_SSLV23,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		return(0);
+		}
+	
+	p=(unsigned char *)to;
+
+	*(p++)=0;
+	*(p++)=2; /* Public Key BT (Block Type) */
+
+	/* pad out with non-zero random data */
+	j=tlen-3-8-flen;
+
+	if (RAND_bytes(p,j) <= 0)
+		return(0);
+	for (i=0; i<j; i++)
+		{
+		if (*p == '\0')
+			do	{
+				if (RAND_bytes(p,1) <= 0)
+					return(0);
+				} while (*p == '\0');
+		p++;
+		}
+
+	memset(p,3,8);
+	p+=8;
+	*(p++)='\0';
+
+	memcpy(p,from,(unsigned int)flen);
+	return(1);
+	}
+
+int RSA_padding_check_SSLv23(unsigned char *to, int tlen,
+	const unsigned char *from, int flen, int num)
+	{
+	int i,j,k;
+	const unsigned char *p;
+
+	p=from;
+	if (flen < 10)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_DATA_TOO_SMALL);
+		return(-1);
+		}
+	if ((num != (flen+1)) || (*(p++) != 02))
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_BLOCK_TYPE_IS_NOT_02);
+		return(-1);
+		}
+
+	/* scan over padding data */
+	j=flen-1; /* one for type */
+	for (i=0; i<j; i++)
+		if (*(p++) == 0) break;
+
+	if ((i == j) || (i < 8))
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_NULL_BEFORE_BLOCK_MISSING);
+		return(-1);
+		}
+	for (k = -9; k<-1; k++)
+		{
+		if (p[k] !=  0x03) break;
+		}
+	if (k == -1)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_SSLV3_ROLLBACK_ATTACK);
+		return(-1);
+		}
+
+	i++; /* Skip over the '\0' */
+	j-=i;
+	if (j > tlen)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_DATA_TOO_LARGE);
+		return(-1);
+		}
+	memcpy(to,p,(unsigned int)j);
+
+	return(j);
+	}
+
diff --git a/openssl/crypto/rsa/rsa_test.c b/openssl/crypto/rsa/rsa_test.c
new file mode 100644
index 0000000..c8705a0
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_test.c
@@ -0,0 +1,340 @@
+/* test vectors from p1ovect1.txt */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "e_os.h"
+
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#ifdef OPENSSL_NO_RSA
+int main(int argc, char *argv[])
+{
+    printf("No RSA support\n");
+    return(0);
+}
+#else
+#include <openssl/rsa.h>
+
+#define SetKey \
+  key->n = BN_bin2bn(n, sizeof(n)-1, key->n); \
+  key->e = BN_bin2bn(e, sizeof(e)-1, key->e); \
+  key->d = BN_bin2bn(d, sizeof(d)-1, key->d); \
+  key->p = BN_bin2bn(p, sizeof(p)-1, key->p); \
+  key->q = BN_bin2bn(q, sizeof(q)-1, key->q); \
+  key->dmp1 = BN_bin2bn(dmp1, sizeof(dmp1)-1, key->dmp1); \
+  key->dmq1 = BN_bin2bn(dmq1, sizeof(dmq1)-1, key->dmq1); \
+  key->iqmp = BN_bin2bn(iqmp, sizeof(iqmp)-1, key->iqmp); \
+  memcpy(c, ctext_ex, sizeof(ctext_ex) - 1); \
+  return (sizeof(ctext_ex) - 1);
+
+static int key1(RSA *key, unsigned char *c)
+    {
+    static unsigned char n[] =
+"\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
+"\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
+"\xAD\xB3\x00\xA0\x28\x5E\x53\x01\x93\x0E\x0C\x70\xFB\x68\x76\x93"
+"\x9C\xE6\x16\xCE\x62\x4A\x11\xE0\x08\x6D\x34\x1E\xBC\xAC\xA0\xA1"
+"\xF5";
+
+    static unsigned char e[] = "\x11";
+
+    static unsigned char d[] =
+"\x0A\x03\x37\x48\x62\x64\x87\x69\x5F\x5F\x30\xBC\x38\xB9\x8B\x44"
+"\xC2\xCD\x2D\xFF\x43\x40\x98\xCD\x20\xD8\xA1\x38\xD0\x90\xBF\x64"
+"\x79\x7C\x3F\xA7\xA2\xCD\xCB\x3C\xD1\xE0\xBD\xBA\x26\x54\xB4\xF9"
+"\xDF\x8E\x8A\xE5\x9D\x73\x3D\x9F\x33\xB3\x01\x62\x4A\xFD\x1D\x51";
+
+    static unsigned char p[] =
+"\x00\xD8\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
+"\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x12"
+"\x0D";
+    
+    static unsigned char q[] =
+"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
+"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
+"\x89";
+
+    static unsigned char dmp1[] =
+"\x59\x0B\x95\x72\xA2\xC2\xA9\xC4\x06\x05\x9D\xC2\xAB\x2F\x1D\xAF"
+"\xEB\x7E\x8B\x4F\x10\xA7\x54\x9E\x8E\xED\xF5\xB4\xFC\xE0\x9E\x05";
+
+    static unsigned char dmq1[] =
+"\x00\x8E\x3C\x05\x21\xFE\x15\xE0\xEA\x06\xA3\x6F\xF0\xF1\x0C\x99"
+"\x52\xC3\x5B\x7A\x75\x14\xFD\x32\x38\xB8\x0A\xAD\x52\x98\x62\x8D"
+"\x51";
+
+    static unsigned char iqmp[] =
+"\x36\x3F\xF7\x18\x9D\xA8\xE9\x0B\x1D\x34\x1F\x71\xD0\x9B\x76\xA8"
+"\xA9\x43\xE1\x1D\x10\xB2\x4D\x24\x9F\x2D\xEA\xFE\xF8\x0C\x18\x26";
+
+    static unsigned char ctext_ex[] =
+"\x1b\x8f\x05\xf9\xca\x1a\x79\x52\x6e\x53\xf3\xcc\x51\x4f\xdb\x89"
+"\x2b\xfb\x91\x93\x23\x1e\x78\xb9\x92\xe6\x8d\x50\xa4\x80\xcb\x52"
+"\x33\x89\x5c\x74\x95\x8d\x5d\x02\xab\x8c\x0f\xd0\x40\xeb\x58\x44"
+"\xb0\x05\xc3\x9e\xd8\x27\x4a\x9d\xbf\xa8\x06\x71\x40\x94\x39\xd2";
+
+    SetKey;
+    }
+
+static int key2(RSA *key, unsigned char *c)
+    {
+    static unsigned char n[] =
+"\x00\xA3\x07\x9A\x90\xDF\x0D\xFD\x72\xAC\x09\x0C\xCC\x2A\x78\xB8"
+"\x74\x13\x13\x3E\x40\x75\x9C\x98\xFA\xF8\x20\x4F\x35\x8A\x0B\x26"
+"\x3C\x67\x70\xE7\x83\xA9\x3B\x69\x71\xB7\x37\x79\xD2\x71\x7B\xE8"
+"\x34\x77\xCF";
+
+    static unsigned char e[] = "\x3";
+
+    static unsigned char d[] =
+"\x6C\xAF\xBC\x60\x94\xB3\xFE\x4C\x72\xB0\xB3\x32\xC6\xFB\x25\xA2"
+"\xB7\x62\x29\x80\x4E\x68\x65\xFC\xA4\x5A\x74\xDF\x0F\x8F\xB8\x41"
+"\x3B\x52\xC0\xD0\xE5\x3D\x9B\x59\x0F\xF1\x9B\xE7\x9F\x49\xDD\x21"
+"\xE5\xEB";
+
+    static unsigned char p[] =
+"\x00\xCF\x20\x35\x02\x8B\x9D\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92"
+"\xEA\x0D\xA3\xB4\x32\x04\xB5\xCF\xCE\x91";
+
+    static unsigned char q[] =
+"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
+"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5F";
+    
+    static unsigned char dmp1[] =
+"\x00\x8A\x15\x78\xAC\x5D\x13\xAF\x10\x2B\x22\xB9\x99\xCD\x74\x61"
+"\xF1\x5E\x6D\x22\xCC\x03\x23\xDF\xDF\x0B";
+
+    static unsigned char dmq1[] =
+"\x00\x86\x55\x21\x4A\xC5\x4D\x8D\x4E\xCD\x61\x77\xF1\xC7\x36\x90"
+"\xCE\x2A\x48\x2C\x8B\x05\x99\xCB\xE0\x3F";
+
+    static unsigned char iqmp[] =
+"\x00\x83\xEF\xEF\xB8\xA9\xA4\x0D\x1D\xB6\xED\x98\xAD\x84\xED\x13"
+"\x35\xDC\xC1\x08\xF3\x22\xD0\x57\xCF\x8D";
+
+    static unsigned char ctext_ex[] =
+"\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a"
+"\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4"
+"\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52"
+"\x62\x51";
+
+    SetKey;
+    }
+
+static int key3(RSA *key, unsigned char *c)
+    {
+    static unsigned char n[] =
+"\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71"
+"\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5"
+"\x1F\xB8\xDF\xBA\xAF\x03\x5C\x02\xAB\x61\xEA\x48\xCE\xEB\x6F\xCD"
+"\x48\x76\xED\x52\x0D\x60\xE1\xEC\x46\x19\x71\x9D\x8A\x5B\x8B\x80"
+"\x7F\xAF\xB8\xE0\xA3\xDF\xC7\x37\x72\x3E\xE6\xB4\xB7\xD9\x3A\x25"
+"\x84\xEE\x6A\x64\x9D\x06\x09\x53\x74\x88\x34\xB2\x45\x45\x98\x39"
+"\x4E\xE0\xAA\xB1\x2D\x7B\x61\xA5\x1F\x52\x7A\x9A\x41\xF6\xC1\x68"
+"\x7F\xE2\x53\x72\x98\xCA\x2A\x8F\x59\x46\xF8\xE5\xFD\x09\x1D\xBD"
+"\xCB";
+
+    static unsigned char e[] = "\x11";
+
+    static unsigned char d[] =
+"\x00\xA5\xDA\xFC\x53\x41\xFA\xF2\x89\xC4\xB9\x88\xDB\x30\xC1\xCD"
+"\xF8\x3F\x31\x25\x1E\x06\x68\xB4\x27\x84\x81\x38\x01\x57\x96\x41"
+"\xB2\x94\x10\xB3\xC7\x99\x8D\x6B\xC4\x65\x74\x5E\x5C\x39\x26\x69"
+"\xD6\x87\x0D\xA2\xC0\x82\xA9\x39\xE3\x7F\xDC\xB8\x2E\xC9\x3E\xDA"
+"\xC9\x7F\xF3\xAD\x59\x50\xAC\xCF\xBC\x11\x1C\x76\xF1\xA9\x52\x94"
+"\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A"
+"\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94"
+"\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3"
+"\xC1";
+
+    static unsigned char p[] =
+"\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60"
+"\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6"
+"\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A"
+"\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65"
+"\x99";
+
+    static unsigned char q[] =
+"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
+"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
+"\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
+"\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15"
+"\x03";
+
+    static unsigned char dmp1[] =
+"\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A"
+"\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E"
+"\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E"
+"\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81";
+
+    static unsigned char dmq1[] =
+"\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9"
+"\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7"
+"\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D"
+"\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D";
+    
+    static unsigned char iqmp[] =
+"\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23"
+"\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11"
+"\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E"
+"\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39"
+"\xF7";
+
+    static unsigned char ctext_ex[] =
+"\xb8\x24\x6b\x56\xa6\xed\x58\x81\xae\xb5\x85\xd9\xa2\x5b\x2a\xd7"
+"\x90\xc4\x17\xe0\x80\x68\x1b\xf1\xac\x2b\xc3\xde\xb6\x9d\x8b\xce"
+"\xf0\xc4\x36\x6f\xec\x40\x0a\xf0\x52\xa7\x2e\x9b\x0e\xff\xb5\xb3"
+"\xf2\xf1\x92\xdb\xea\xca\x03\xc1\x27\x40\x05\x71\x13\xbf\x1f\x06"
+"\x69\xac\x22\xe9\xf3\xa7\x85\x2e\x3c\x15\xd9\x13\xca\xb0\xb8\x86"
+"\x3a\x95\xc9\x92\x94\xce\x86\x74\x21\x49\x54\x61\x03\x46\xf4\xd4"
+"\x74\xb2\x6f\x7c\x48\xb4\x2e\xe6\x8e\x1f\x57\x2a\x1f\xc4\x02\x6a"
+"\xc4\x56\xb4\xf5\x9f\x7b\x62\x1e\xa1\xb9\xd8\x8f\x64\x20\x2f\xb1";
+
+    SetKey;
+    }
+
+static int pad_unknown(void)
+{
+    unsigned long l;
+    while ((l = ERR_get_error()) != 0)
+      if (ERR_GET_REASON(l) == RSA_R_UNKNOWN_PADDING_TYPE)
+	return(1);
+    return(0);
+}
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+int main(int argc, char *argv[])
+    {
+    int err=0;
+    int v;
+    RSA *key;
+    unsigned char ptext[256];
+    unsigned char ctext[256];
+    static unsigned char ptext_ex[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
+    unsigned char ctext_ex[256];
+    int plen;
+    int clen = 0;
+    int num;
+    int n;
+
+    CRYPTO_malloc_debug_init();
+    CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+    RAND_seed(rnd_seed, sizeof rnd_seed); /* or OAEP may fail */
+
+    plen = sizeof(ptext_ex) - 1;
+
+    for (v = 0; v < 6; v++)
+	{
+	key = RSA_new();
+	switch (v%3) {
+    case 0:
+	clen = key1(key, ctext_ex);
+	break;
+    case 1:
+	clen = key2(key, ctext_ex);
+	break;
+    case 2:
+	clen = key3(key, ctext_ex);
+	break;
+	}
+	if (v/3 >= 1) key->flags |= RSA_FLAG_NO_CONSTTIME;
+
+	num = RSA_public_encrypt(plen, ptext_ex, ctext, key,
+				 RSA_PKCS1_PADDING);
+	if (num != clen)
+	    {
+	    printf("PKCS#1 v1.5 encryption failed!\n");
+	    err=1;
+	    goto oaep;
+	    }
+  
+	num = RSA_private_decrypt(num, ctext, ptext, key,
+				  RSA_PKCS1_PADDING);
+	if (num != plen || memcmp(ptext, ptext_ex, num) != 0)
+	    {
+	    printf("PKCS#1 v1.5 decryption failed!\n");
+	    err=1;
+	    }
+	else
+	    printf("PKCS #1 v1.5 encryption/decryption ok\n");
+
+    oaep:
+	ERR_clear_error();
+	num = RSA_public_encrypt(plen, ptext_ex, ctext, key,
+				 RSA_PKCS1_OAEP_PADDING);
+	if (num == -1 && pad_unknown())
+	    {
+	    printf("No OAEP support\n");
+	    goto next;
+	    }
+	if (num != clen)
+	    {
+	    printf("OAEP encryption failed!\n");
+	    err=1;
+	    goto next;
+	    }
+
+	num = RSA_private_decrypt(num, ctext, ptext, key,
+				  RSA_PKCS1_OAEP_PADDING);
+	if (num != plen || memcmp(ptext, ptext_ex, num) != 0)
+	    {
+	    printf("OAEP decryption (encrypted data) failed!\n");
+	    err=1;
+	    }
+	else if (memcmp(ctext, ctext_ex, num) == 0)
+	    printf("OAEP test vector %d passed!\n", v);
+    
+	/* Different ciphertexts (rsa_oaep.c without -DPKCS_TESTVECT).
+	   Try decrypting ctext_ex */
+
+	num = RSA_private_decrypt(clen, ctext_ex, ptext, key,
+				  RSA_PKCS1_OAEP_PADDING);
+
+	if (num != plen || memcmp(ptext, ptext_ex, num) != 0)
+	    {
+	    printf("OAEP decryption (test vector data) failed!\n");
+	    err=1;
+	    }
+	else
+	    printf("OAEP encryption/decryption ok\n");
+
+	/* Try decrypting corrupted ciphertexts */
+	for(n = 0 ; n < clen ; ++n)
+	    {
+	    int b;
+	    unsigned char saved = ctext[n];
+	    for(b = 0 ; b < 256 ; ++b)
+		{
+		if(b == saved)
+		    continue;
+		ctext[n] = b;
+		num = RSA_private_decrypt(num, ctext, ptext, key,
+					  RSA_PKCS1_OAEP_PADDING);
+		if(num > 0)
+		    {
+		    printf("Corrupt data decrypted!\n");
+		    err = 1;
+		    }
+		}
+	    }
+    next:
+	RSA_free(key);
+	}
+
+    CRYPTO_cleanup_all_ex_data();
+    ERR_remove_thread_state(NULL);
+
+    CRYPTO_mem_leaks_fp(stderr);
+
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
+    return err;
+    }
+#endif
diff --git a/openssl/crypto/rsa/rsa_x931.c b/openssl/crypto/rsa/rsa_x931.c
new file mode 100644
index 0000000..21548e3
--- /dev/null
+++ b/openssl/crypto/rsa/rsa_x931.c
@@ -0,0 +1,177 @@
+/* rsa_x931.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+
+int RSA_padding_add_X931(unsigned char *to, int tlen,
+	     const unsigned char *from, int flen)
+	{
+	int j;
+	unsigned char *p;
+
+	/* Absolute minimum amount of padding is 1 header nibble, 1 padding
+	 * nibble and 2 trailer bytes: but 1 hash if is already in 'from'.
+	 */
+
+	j = tlen - flen - 2;
+
+	if (j < 0)
+		{
+		RSAerr(RSA_F_RSA_PADDING_ADD_X931,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		return -1;
+		}
+	
+	p=(unsigned char *)to;
+
+	/* If no padding start and end nibbles are in one byte */
+	if (j == 0)
+		*p++ = 0x6A;
+	else
+		{
+		*p++ = 0x6B;
+		if (j > 1)
+			{
+			memset(p, 0xBB, j - 1);
+			p += j - 1;
+			}
+		*p++ = 0xBA;
+		}
+	memcpy(p,from,(unsigned int)flen);
+	p += flen;
+	*p = 0xCC;
+	return(1);
+	}
+
+int RSA_padding_check_X931(unsigned char *to, int tlen,
+	     const unsigned char *from, int flen, int num)
+	{
+	int i = 0,j;
+	const unsigned char *p;
+
+	p=from;
+	if ((num != flen) || ((*p != 0x6A) && (*p != 0x6B)))
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_X931,RSA_R_INVALID_HEADER);
+		return -1;
+		}
+
+	if (*p++ == 0x6B)
+		{
+		j=flen-3;
+		for (i = 0; i < j; i++)
+			{
+			unsigned char c = *p++;
+			if (c == 0xBA)
+				break;
+			if (c != 0xBB)
+				{
+				RSAerr(RSA_F_RSA_PADDING_CHECK_X931,
+					RSA_R_INVALID_PADDING);
+				return -1;
+				}
+			}
+
+		j -= i;
+
+		if (i == 0)
+			{
+			RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING);
+			return -1;
+			}
+
+		}
+	else j = flen - 2;
+
+	if (p[j] != 0xCC)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_TRAILER);
+		return -1;
+		}
+
+	memcpy(to,p,(unsigned int)j);
+
+	return(j);
+	}
+
+/* Translate between X931 hash ids and NIDs */
+
+int RSA_X931_hash_id(int nid)
+	{
+	switch (nid)
+		{
+		case NID_sha1:
+		return 0x33;
+
+		case NID_sha256:
+		return 0x34;
+
+		case NID_sha384:
+		return 0x36;
+
+		case NID_sha512:
+		return 0x35;
+
+		}
+	return -1;
+	}
+
diff --git a/openssl/crypto/s390xcap.c b/openssl/crypto/s390xcap.c
new file mode 100644
index 0000000..ffbe023
--- /dev/null
+++ b/openssl/crypto/s390xcap.c
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <setjmp.h>
+#include <signal.h>
+
+extern unsigned long OPENSSL_s390xcap_P;
+
+static sigjmp_buf ill_jmp;
+static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
+
+unsigned long OPENSSL_s390x_facilities(void);
+
+void OPENSSL_cpuid_setup(void)
+	{
+	sigset_t oset;
+	struct sigaction ill_act,oact;
+
+	if (OPENSSL_s390xcap_P) return;
+
+	memset(&ill_act,0,sizeof(ill_act));
+	ill_act.sa_handler = ill_handler;
+	sigfillset(&ill_act.sa_mask);
+	sigdelset(&ill_act.sa_mask,SIGILL);
+	sigdelset(&ill_act.sa_mask,SIGTRAP);
+	sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset);
+	sigaction (SIGILL,&ill_act,&oact);
+
+	/* protection against missing store-facility-list-extended */
+	if (sigsetjmp(ill_jmp,0) == 0)
+		OPENSSL_s390xcap_P = OPENSSL_s390x_facilities();
+	else
+		OPENSSL_s390xcap_P = 1UL<<63;
+
+	sigaction (SIGILL,&oact,NULL);
+	sigprocmask(SIG_SETMASK,&oset,NULL);
+	}
diff --git a/openssl/crypto/s390xcpuid.S b/openssl/crypto/s390xcpuid.S
new file mode 100644
index 0000000..b053c6a
--- /dev/null
+++ b/openssl/crypto/s390xcpuid.S
@@ -0,0 +1,92 @@
+.text
+
+.globl	OPENSSL_s390x_facilities
+.type	OPENSSL_s390x_facilities,@function
+.align	16
+OPENSSL_s390x_facilities:
+	lghi	%r0,0
+	.long	0xb2b0f010	# stfle	16(%r15)
+	lg	%r2,16(%r15)
+	larl	%r1,OPENSSL_s390xcap_P
+	stg	%r2,0(%r1)
+	br	%r14
+.size	OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities
+
+.globl	OPENSSL_rdtsc
+.type	OPENSSL_rdtsc,@function
+.align	16
+OPENSSL_rdtsc:
+	stck	16(%r15)
+	lg	%r2,16(%r15)
+	br	%r14
+.size	OPENSSL_rdtsc,.-OPENSSL_rdtsc
+
+.globl	OPENSSL_atomic_add
+.type	OPENSSL_atomic_add,@function
+.align	16
+OPENSSL_atomic_add:
+	l	%r1,0(%r2)
+.Lspin:	lr	%r0,%r1
+	ar	%r0,%r3
+	cs	%r1,%r0,0(%r2)
+	brc	4,.Lspin
+	lgfr	%r2,%r0		# OpenSSL expects the new value
+	br	%r14
+.size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
+
+.globl	OPENSSL_wipe_cpu
+.type	OPENSSL_wipe_cpu,@function
+.align	16
+OPENSSL_wipe_cpu:
+	xgr	%r0,%r0
+	xgr	%r1,%r1
+	lgr	%r2,%r15
+	xgr	%r3,%r3
+	xgr	%r4,%r4
+	lzdr	%f0
+	lzdr	%f1
+	lzdr	%f2
+	lzdr	%f3
+	lzdr	%f4
+	lzdr	%f5
+	lzdr	%f6
+	lzdr	%f7
+	br	%r14
+.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
+
+.globl	OPENSSL_cleanse
+.type	OPENSSL_cleanse,@function
+.align	16
+OPENSSL_cleanse:
+	lghi	%r4,15
+	lghi	%r0,0
+	clgr	%r3,%r4
+	jh	.Lot
+	clgr	%r3,%r0
+	bcr	8,%r14
+.Little:
+	stc	%r0,0(%r2)
+	la	%r2,1(%r2)
+	brctg	%r3,.Little
+	br	%r14
+.align	4
+.Lot:	tmll	%r2,7
+	jz	.Laligned
+	stc	%r0,0(%r2)
+	la	%r2,1(%r2)
+	brctg	%r3,.Lot
+.Laligned:
+	srlg	%r4,%r3,3
+.Loop:	stg	%r0,0(%r2)
+	la	%r2,8(%r2)
+	brctg	%r4,.Loop
+	lghi	%r4,7
+	ngr	%r3,%r4
+	jnz	.Little
+	br	%r14
+.size	OPENSSL_cleanse,.-OPENSSL_cleanse
+
+.section	.init
+	brasl	%r14,OPENSSL_cpuid_setup
+
+.comm	OPENSSL_s390xcap_P,8,8
diff --git a/openssl/crypto/seed/Makefile b/openssl/crypto/seed/Makefile
new file mode 100644
index 0000000..4bc55e4
--- /dev/null
+++ b/openssl/crypto/seed/Makefile
@@ -0,0 +1,106 @@
+#
+# crypto/seed/Makefile
+#
+
+DIR=	seed
+TOP=	../..
+CC=	cc
+CPP=	$(CC) -E
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=seed.c seed_ecb.c seed_cbc.c seed_cfb.c seed_ofb.c
+LIBOBJ=seed.o seed_ecb.o seed_cbc.o seed_cfb.o seed_ofb.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= seed.h
+HEADER= seed_locl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+seed.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+seed.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+seed.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+seed.o: ../../include/openssl/seed.h ../../include/openssl/stack.h
+seed.o: ../../include/openssl/symhacks.h seed.c seed_locl.h
+seed_cbc.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+seed_cbc.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
+seed_cbc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+seed_cbc.o: ../../include/openssl/safestack.h ../../include/openssl/seed.h
+seed_cbc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+seed_cbc.o: seed_cbc.c
+seed_cfb.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+seed_cfb.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
+seed_cfb.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+seed_cfb.o: ../../include/openssl/safestack.h ../../include/openssl/seed.h
+seed_cfb.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+seed_cfb.o: seed_cfb.c
+seed_ecb.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+seed_ecb.o: ../../include/openssl/opensslconf.h
+seed_ecb.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+seed_ecb.o: ../../include/openssl/safestack.h ../../include/openssl/seed.h
+seed_ecb.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+seed_ecb.o: seed_ecb.c
+seed_ofb.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+seed_ofb.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
+seed_ofb.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+seed_ofb.o: ../../include/openssl/safestack.h ../../include/openssl/seed.h
+seed_ofb.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+seed_ofb.o: seed_ofb.c
diff --git a/openssl/crypto/seed/seed.c b/openssl/crypto/seed/seed.c
new file mode 100644
index 0000000..2bc384a
--- /dev/null
+++ b/openssl/crypto/seed/seed.c
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved.  
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Neither the name of author nor the names of its contributors may
+ *    be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#ifndef OPENSSL_NO_SEED
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef WIN32
+#include <memory.h>
+#endif
+
+#include <openssl/seed.h>
+#include "seed_locl.h"
+
+static const seed_word SS[4][256] = {	{
+	0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124,
+	0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c, 0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360,
+	0x28082028, 0x04444044, 0x20002020, 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314,
+	0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378, 0x3b8bb3b8, 0x13031310, 0x12c2d2d0, 0x2ecee2ec,
+	0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8, 0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074,
+	0x2ccce0ec, 0x15859194, 0x0b0b0308, 0x17475354, 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100,
+	0x24042024, 0x1c0c101c, 0x33437370, 0x18889098, 0x10001010, 0x0cccc0cc, 0x32c2f2f0, 0x19c9d1d8,
+	0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380, 0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8,
+	0x20406060, 0x10405050, 0x2383a3a0, 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c,
+	0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078, 0x2686a2a4, 0x12021210, 0x2f8fa3ac, 0x15c5d1d4,
+	0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140, 0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008,
+	0x1f0f131c, 0x19899198, 0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0,
+	0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324, 0x3080b0b0, 0x0b8b8388, 0x0e0e020c, 0x2b8ba3a8,
+	0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c, 0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208,
+	0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, 0x05c5c1c4, 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064,
+	0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218, 0x06060204, 0x21012120, 0x2b4b6368, 0x26466264,
+	0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288, 0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0,
+	0x3a4a7278, 0x07474344, 0x16869294, 0x25c5e1e4, 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc,
+	0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac, 0x36063234, 0x15051114, 0x22022220, 0x38083038,
+	0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c, 0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394,
+	0x35053134, 0x0bcbc3c8, 0x0ecec2cc, 0x3c0c303c, 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188,
+	0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8, 0x14849094, 0x19495158, 0x02828280, 0x04c4c0c4,
+	0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364, 0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8,
+	0x0f0f030c, 0x0e8e828c, 0x02424240, 0x23032320, 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4,
+	0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c, 0x2d0d212c, 0x00404040,
+	0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0, 0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154,
+	0x3b0b3338, 0x1cccd0dc, 0x28486068, 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254,
+	0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244, 0x3585b1b4, 0x2b0b2328, 0x25456164, 0x3acaf2f8,
+	0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c, 0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0,
+	0x31013130, 0x2acae2e8, 0x2d4d616c, 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088,
+	0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4, 0x22426260, 0x29092128, 0x07070304, 0x33033330,
+	0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178, 0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298
+},	{
+	0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2, 0xcc0fcfc3, 0xdc1eced2, 0xb03383b3, 0xb83888b0,
+	0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3, 0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53,
+	0xc003c3c3, 0x60224262, 0x30330333, 0xb43585b1, 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3,
+	0xd013c3d3, 0x90118191, 0x10110111, 0x04060602, 0x1c1c0c10, 0xbc3c8cb0, 0x34360632, 0x480b4b43,
+	0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0, 0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0,
+	0xc002c2c2, 0x44054541, 0xe021c1e1, 0xd416c6d2, 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890,
+	0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32, 0xa42585a1, 0xf839c9f1, 0x0c0d0d01, 0xdc1fcfd3,
+	0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72, 0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272,
+	0x40024242, 0xd414c4d0, 0x40014141, 0xc000c0c0, 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83,
+	0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13, 0xc80acac2, 0x2c2c0c20, 0xa82a8aa2, 0x34340430,
+	0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1, 0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0,
+	0x54174753, 0xac2e8ea2, 0x08080800, 0xc405c5c1, 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1,
+	0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131, 0xf435c5f1, 0x880a8a82, 0x682a4a62, 0xb03181b1,
+	0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202, 0x20220222, 0x04040400, 0x68284860, 0x70314171,
+	0x04070703, 0xd81bcbd3, 0x9c1d8d91, 0x98198991, 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951,
+	0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0, 0x981a8a92, 0xa02383a3, 0xa82b8ba3, 0xd010c0d0,
+	0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12, 0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3,
+	0x94168692, 0x783b4b73, 0x5c1c4c50, 0xa02282a2, 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41,
+	0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32, 0x0c0c0c00, 0x2c2e0e22, 0xb83a8ab2, 0x6c2e4e62,
+	0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292, 0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0,
+	0x14150511, 0xf83bcbf3, 0x70304070, 0x74354571, 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303,
+	0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470, 0xd415c5d1, 0xb43484b0, 0xe82acae2, 0x08090901,
+	0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040, 0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501,
+	0xf83acaf2, 0x00010101, 0xf030c0f0, 0x282a0a22, 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343,
+	0x84058581, 0x14140410, 0x88098981, 0x981b8b93, 0xb03080b0, 0xe425c5e1, 0x48084840, 0x78394971,
+	0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282, 0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53,
+	0x74374773, 0x54144450, 0xb03282b2, 0x1c1d0d11, 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642,
+	0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3, 0x7c3e4e72, 0xd81acad2, 0xc809c9c1, 0xfc3dcdf1,
+	0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30, 0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70,
+	0x0c0e0e02, 0x50104050, 0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393,
+	0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0, 0xc80bcbc3, 0x50134353, 0x080a0a02, 0x84078783,
+	0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83, 0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3
+},	{
+	0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d, 0xa0ac2c8c, 0x21242505,
+	0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e, 0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343,
+	0x20282808, 0x40440444, 0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707,
+	0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303, 0xd2d012c2, 0xe2ec2ece,
+	0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888, 0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444,
+	0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101,
+	0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc, 0xf2f032c2, 0xd1d819c9,
+	0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383, 0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9,
+	0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f,
+	0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202, 0xa3ac2f8f, 0xd1d415c5,
+	0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141, 0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808,
+	0x131c1f0f, 0x91981989, 0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1,
+	0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b, 0x020c0e0e, 0xa3a82b8b,
+	0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d, 0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a,
+	0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444,
+	0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101, 0x63682b4b, 0x62642646,
+	0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a, 0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0,
+	0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf,
+	0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505, 0x22202202, 0x30383808,
+	0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c, 0x81800181, 0xe1e829c9, 0x80840484, 0x93941787,
+	0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989,
+	0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949, 0x82800282, 0xc0c404c4,
+	0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747, 0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888,
+	0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484,
+	0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d, 0x212c2d0d, 0x40400040,
+	0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1, 0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545,
+	0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646,
+	0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b, 0x61642545, 0xf2f83aca,
+	0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f, 0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282,
+	0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888,
+	0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909, 0x03040707, 0x33303303,
+	0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949, 0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a
+},	{
+	0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838,
+	0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407, 0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b,
+	0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427,
+	0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b,
+	0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828, 0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434,
+	0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818,
+	0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f,
+	0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a, 0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032,
+	0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000, 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b,
+	0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434,
+	0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829, 0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838,
+	0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839,
+	0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031,
+	0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002, 0x02222022, 0x04000404, 0x48606828, 0x41717031,
+	0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819,
+	0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010,
+	0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a, 0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f,
+	0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d,
+	0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e,
+	0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012, 0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c,
+	0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435, 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003,
+	0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809,
+	0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000, 0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405,
+	0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003,
+	0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839,
+	0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002, 0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f,
+	0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406,
+	0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d,
+	0x00303030, 0x85919415, 0x45616425, 0x0c303c3c, 0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c,
+	0x0e020c0e, 0x40505010, 0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013,
+	0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407,
+	0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f, 0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437
+}	};
+
+/* key schedule constants - golden ratio */
+#define KC0     0x9e3779b9
+#define KC1     0x3c6ef373
+#define KC2     0x78dde6e6
+#define KC3     0xf1bbcdcc
+#define KC4     0xe3779b99
+#define KC5     0xc6ef3733
+#define KC6     0x8dde6e67
+#define KC7     0x1bbcdccf
+#define KC8     0x3779b99e
+#define KC9     0x6ef3733c
+#define KC10    0xdde6e678
+#define KC11    0xbbcdccf1
+#define KC12    0x779b99e3
+#define KC13    0xef3733c6
+#define KC14    0xde6e678d
+#define KC15    0xbcdccf1b
+
+#if defined(OPENSSL_SMALL_FOOTPRINT)
+static const seed_word KC[] = {
+	KC0,	KC1,	KC2,	KC3,	KC4,	KC5,	KC6,	KC7,
+	KC8,	KC9,	KC10,	KC11,	KC12,	KC13,	KC14,	KC15	};
+#endif
+
+void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks)
+{
+	seed_word x1, x2, x3, x4;
+	seed_word t0, t1;
+
+	char2word(rawkey   , x1);
+	char2word(rawkey+4 , x2);
+	char2word(rawkey+8 , x3);
+	char2word(rawkey+12, x4);
+
+	t0 = (x1 + x3 - KC0) & 0xffffffff;
+	t1 = (x2 - x4 + KC0) & 0xffffffff;                     KEYUPDATE_TEMP(t0, t1, &ks->data[0]);
+	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC1);      KEYUPDATE_TEMP(t0, t1, &ks->data[2]);
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC2);      KEYUPDATE_TEMP(t0, t1, &ks->data[4]);
+	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC3);      KEYUPDATE_TEMP(t0, t1, &ks->data[6]);
+	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC4);      KEYUPDATE_TEMP(t0, t1, &ks->data[8]);
+	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC5);      KEYUPDATE_TEMP(t0, t1, &ks->data[10]);
+	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC6);      KEYUPDATE_TEMP(t0, t1, &ks->data[12]);
+	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC7);      KEYUPDATE_TEMP(t0, t1, &ks->data[14]);
+	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC8);      KEYUPDATE_TEMP(t0, t1, &ks->data[16]);
+	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC9);      KEYUPDATE_TEMP(t0, t1, &ks->data[18]);
+	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC10);     KEYUPDATE_TEMP(t0, t1, &ks->data[20]);
+	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC11);     KEYUPDATE_TEMP(t0, t1, &ks->data[22]);
+	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC12);     KEYUPDATE_TEMP(t0, t1, &ks->data[24]);
+	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC13);     KEYUPDATE_TEMP(t0, t1, &ks->data[26]);
+	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC14);     KEYUPDATE_TEMP(t0, t1, &ks->data[28]);
+	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC15);     KEYUPDATE_TEMP(t0, t1, &ks->data[30]);
+#else
+	{
+	    int i;
+	    for (i=2; i<16; i+=2) {
+		KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC[i]);
+		KEYUPDATE_TEMP(t0, t1, &ks->data[i*2]);
+		KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC[i+1]);
+		KEYUPDATE_TEMP(t0, t1, &ks->data[i*2+2]);
+	    }
+	}
+#endif
+}
+
+void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], unsigned char d[SEED_BLOCK_SIZE], const SEED_KEY_SCHEDULE *ks)
+{
+	seed_word x1, x2, x3, x4;
+	seed_word t0, t1;
+
+	char2word(s,    x1);
+	char2word(s+4,  x2);
+	char2word(s+8,  x3);
+	char2word(s+12, x4);
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)	
+	E_SEED(t0, t1, x1, x2, x3, x4, 0);
+	E_SEED(t0, t1, x3, x4, x1, x2, 2);
+	E_SEED(t0, t1, x1, x2, x3, x4, 4);
+	E_SEED(t0, t1, x3, x4, x1, x2, 6);
+	E_SEED(t0, t1, x1, x2, x3, x4, 8);
+	E_SEED(t0, t1, x3, x4, x1, x2, 10);
+	E_SEED(t0, t1, x1, x2, x3, x4, 12);
+	E_SEED(t0, t1, x3, x4, x1, x2, 14);
+	E_SEED(t0, t1, x1, x2, x3, x4, 16);
+	E_SEED(t0, t1, x3, x4, x1, x2, 18);
+	E_SEED(t0, t1, x1, x2, x3, x4, 20);
+	E_SEED(t0, t1, x3, x4, x1, x2, 22);
+	E_SEED(t0, t1, x1, x2, x3, x4, 24);
+	E_SEED(t0, t1, x3, x4, x1, x2, 26);
+	E_SEED(t0, t1, x1, x2, x3, x4, 28);
+	E_SEED(t0, t1, x3, x4, x1, x2, 30);
+#else
+	{
+	    int i;
+	    for (i=0;i<30;i+=4) {
+		E_SEED(t0,t1,x1,x2,x3,x4,i);
+		E_SEED(t0,t1,x3,x4,x1,x2,i+2);
+	    }
+	}
+#endif
+
+	word2char(x3, d);
+	word2char(x4, d+4);
+	word2char(x1, d+8);
+	word2char(x2, d+12);
+}
+
+void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE], unsigned char d[SEED_BLOCK_SIZE], const SEED_KEY_SCHEDULE *ks)
+{
+	seed_word x1, x2, x3, x4;
+	seed_word t0, t1;
+
+	char2word(s,    x1);
+	char2word(s+4,  x2);
+	char2word(s+8,  x3);
+	char2word(s+12, x4);
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	E_SEED(t0, t1, x1, x2, x3, x4, 30);
+	E_SEED(t0, t1, x3, x4, x1, x2, 28);
+	E_SEED(t0, t1, x1, x2, x3, x4, 26);
+	E_SEED(t0, t1, x3, x4, x1, x2, 24);
+	E_SEED(t0, t1, x1, x2, x3, x4, 22);
+	E_SEED(t0, t1, x3, x4, x1, x2, 20);
+	E_SEED(t0, t1, x1, x2, x3, x4, 18);
+	E_SEED(t0, t1, x3, x4, x1, x2, 16);
+	E_SEED(t0, t1, x1, x2, x3, x4, 14);
+	E_SEED(t0, t1, x3, x4, x1, x2, 12);
+	E_SEED(t0, t1, x1, x2, x3, x4, 10);
+	E_SEED(t0, t1, x3, x4, x1, x2, 8);
+	E_SEED(t0, t1, x1, x2, x3, x4, 6);
+	E_SEED(t0, t1, x3, x4, x1, x2, 4);
+	E_SEED(t0, t1, x1, x2, x3, x4, 2);
+	E_SEED(t0, t1, x3, x4, x1, x2, 0);
+#else
+	{
+	    int i;
+	    for (i=30; i>0; i-=4) {
+		E_SEED(t0, t1, x1, x2, x3, x4, i);
+		E_SEED(t0, t1, x3, x4, x1, x2, i-2);
+
+	    }
+	}
+#endif
+
+	word2char(x3, d);
+	word2char(x4, d+4);
+	word2char(x1, d+8);
+	word2char(x2, d+12);
+}
+
+#endif /* OPENSSL_NO_SEED */
diff --git a/openssl/crypto/seed/seed.h b/openssl/crypto/seed/seed.h
new file mode 100644
index 0000000..6ffa5f0
--- /dev/null
+++ b/openssl/crypto/seed/seed.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved.  
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Neither the name of author nor the names of its contributors may
+ *    be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#ifndef HEADER_SEED_H
+#define HEADER_SEED_H
+
+#include <openssl/opensslconf.h>
+#include <openssl/e_os2.h>
+#include <openssl/crypto.h>
+
+#ifdef OPENSSL_NO_SEED
+#error SEED is disabled.
+#endif
+
+#ifdef AES_LONG /* look whether we need 'long' to get 32 bits */
+# ifndef SEED_LONG
+#  define SEED_LONG 1
+# endif
+#endif
+
+#if !defined(NO_SYS_TYPES_H)
+# include <sys/types.h>
+#endif
+
+#define SEED_BLOCK_SIZE 16
+#define SEED_KEY_LENGTH	16
+
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct seed_key_st {
+#ifdef SEED_LONG
+    unsigned long data[32];
+#else
+    unsigned int data[32];
+#endif
+} SEED_KEY_SCHEDULE;
+
+
+void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks);
+
+void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], unsigned char d[SEED_BLOCK_SIZE], const SEED_KEY_SCHEDULE *ks);
+void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE], unsigned char d[SEED_BLOCK_SIZE], const SEED_KEY_SCHEDULE *ks);
+
+void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, const SEED_KEY_SCHEDULE *ks, int enc);
+void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out,
+        size_t len, const SEED_KEY_SCHEDULE *ks, unsigned char ivec[SEED_BLOCK_SIZE], int enc);
+void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+        size_t len, const SEED_KEY_SCHEDULE *ks, unsigned char ivec[SEED_BLOCK_SIZE], int *num, int enc);
+void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+        size_t len, const SEED_KEY_SCHEDULE *ks, unsigned char ivec[SEED_BLOCK_SIZE], int *num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* HEADER_SEED_H */
diff --git a/openssl/crypto/seed/seed_cbc.c b/openssl/crypto/seed/seed_cbc.c
new file mode 100644
index 0000000..6c3f9b5
--- /dev/null
+++ b/openssl/crypto/seed/seed_cbc.c
@@ -0,0 +1,63 @@
+/* crypto/seed/seed_cbc.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/seed.h>
+#include <openssl/modes.h>
+
+void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                      size_t len, const SEED_KEY_SCHEDULE *ks,
+                      unsigned char ivec[SEED_BLOCK_SIZE], int enc)
+	{
+	if (enc)
+		CRYPTO_cbc128_encrypt(in,out,len,ks,ivec,(block128_f)SEED_encrypt);
+	else
+		CRYPTO_cbc128_decrypt(in,out,len,ks,ivec,(block128_f)SEED_decrypt);
+	}
diff --git a/openssl/crypto/seed/seed_cfb.c b/openssl/crypto/seed/seed_cfb.c
new file mode 100644
index 0000000..694597d
--- /dev/null
+++ b/openssl/crypto/seed/seed_cfb.c
@@ -0,0 +1,116 @@
+/* crypto/seed/seed_cfb.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/seed.h>
+#include <openssl/modes.h>
+
+void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+                         size_t len, const SEED_KEY_SCHEDULE *ks,
+                         unsigned char ivec[SEED_BLOCK_SIZE], int *num, int enc)
+	{
+	CRYPTO_cfb128_encrypt(in,out,len,ks,ivec,num,enc,(block128_f)SEED_encrypt);
+	}
diff --git a/openssl/crypto/seed/seed_ecb.c b/openssl/crypto/seed/seed_ecb.c
new file mode 100644
index 0000000..e63f5ae
--- /dev/null
+++ b/openssl/crypto/seed/seed_ecb.c
@@ -0,0 +1,60 @@
+/* crypto/seed/seed_ecb.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/seed.h>
+
+void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, const SEED_KEY_SCHEDULE *ks, int enc) 
+	{
+	if (enc)
+		SEED_encrypt(in, out, ks);
+	else
+		SEED_decrypt(in, out, ks);
+	}
diff --git a/openssl/crypto/seed/seed_locl.h b/openssl/crypto/seed/seed_locl.h
new file mode 100644
index 0000000..fd456b6
--- /dev/null
+++ b/openssl/crypto/seed/seed_locl.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved.  
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Neither the name of author nor the names of its contributors may
+ *    be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#ifndef HEADER_SEED_LOCL_H
+#define HEADER_SEED_LOCL_H
+
+#include "openssl/e_os2.h"
+#include <openssl/seed.h>
+
+
+#ifdef SEED_LONG /* need 32-bit type */
+typedef unsigned long seed_word;
+#else
+typedef unsigned int seed_word;
+#endif
+
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define G_FUNC(v)       \
+        SS[0][(unsigned char)      (v) & 0xff] ^ SS[1][(unsigned char) ((v)>>8) & 0xff] ^ \
+        SS[2][(unsigned char)((v)>>16) & 0xff] ^ SS[3][(unsigned char)((v)>>24) & 0xff]
+
+#define char2word(c, i)  \
+        (i) = ((((seed_word)(c)[0]) << 24) | (((seed_word)(c)[1]) << 16) | (((seed_word)(c)[2]) << 8) | ((seed_word)(c)[3]))
+
+#define word2char(l, c)  \
+        *((c)+0) = (unsigned char)((l)>>24) & 0xff; \
+        *((c)+1) = (unsigned char)((l)>>16) & 0xff; \
+        *((c)+2) = (unsigned char)((l)>> 8) & 0xff; \
+        *((c)+3) = (unsigned char)((l))     & 0xff
+
+#define KEYSCHEDULE_UPDATE0(T0, T1, X1, X2, X3, X4, KC)  \
+        (T0) = (X3);                                     \
+        (X3) = (((X3)<<8) ^ ((X4)>>24)) & 0xffffffff;    \
+        (X4) = (((X4)<<8) ^ ((T0)>>24)) & 0xffffffff;    \
+        (T0) = ((X1) + (X3) - (KC))     & 0xffffffff;    \
+        (T1) = ((X2) + (KC) - (X4))     & 0xffffffff
+
+#define KEYSCHEDULE_UPDATE1(T0, T1, X1, X2, X3, X4, KC)  \
+        (T0) = (X1);                                     \
+        (X1) = (((X1)>>8) ^ ((X2)<<24)) & 0xffffffff;    \
+        (X2) = (((X2)>>8) ^ ((T0)<<24)) & 0xffffffff;    \
+        (T0) = ((X1) + (X3) - (KC))     & 0xffffffff;     \
+        (T1) = ((X2) + (KC) - (X4))     & 0xffffffff
+
+#define KEYUPDATE_TEMP(T0, T1, K)   \
+        (K)[0] = G_FUNC((T0));      \
+        (K)[1] = G_FUNC((T1))
+
+#define XOR_SEEDBLOCK(DST, SRC)      \
+        ((DST))[0] ^= ((SRC))[0];    \
+        ((DST))[1] ^= ((SRC))[1];    \
+        ((DST))[2] ^= ((SRC))[2];    \
+        ((DST))[3] ^= ((SRC))[3]
+
+#define MOV_SEEDBLOCK(DST, SRC)      \
+        ((DST))[0] = ((SRC))[0];     \
+        ((DST))[1] = ((SRC))[1];     \
+        ((DST))[2] = ((SRC))[2];     \
+        ((DST))[3] = ((SRC))[3]
+
+# define CHAR2WORD(C, I)              \
+        char2word((C),    (I)[0]);    \
+        char2word((C+4),  (I)[1]);    \
+        char2word((C+8),  (I)[2]);    \
+        char2word((C+12), (I)[3])
+
+# define WORD2CHAR(I, C)              \
+        word2char((I)[0], (C));       \
+        word2char((I)[1], (C+4));     \
+        word2char((I)[2], (C+8));     \
+        word2char((I)[3], (C+12))
+
+# define E_SEED(T0, T1, X1, X2, X3, X4, rbase)   \
+        (T0) = (X3) ^ (ks->data)[(rbase)];       \
+        (T1) = (X4) ^ (ks->data)[(rbase)+1];     \
+        (T1) ^= (T0);                            \
+        (T1) = G_FUNC((T1));                     \
+        (T0) = ((T0) + (T1)) & 0xffffffff;       \
+        (T0) = G_FUNC((T0));                     \
+        (T1) = ((T1) + (T0)) & 0xffffffff;       \
+        (T1) = G_FUNC((T1));                     \
+        (T0) = ((T0) + (T1)) & 0xffffffff;       \
+        (X1) ^= (T0);                            \
+        (X2) ^= (T1)
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* HEADER_SEED_LOCL_H */
diff --git a/openssl/crypto/seed/seed_ofb.c b/openssl/crypto/seed/seed_ofb.c
new file mode 100644
index 0000000..3c8ba33
--- /dev/null
+++ b/openssl/crypto/seed/seed_ofb.c
@@ -0,0 +1,116 @@
+/* crypto/seed/seed_ofb.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/seed.h>
+#include <openssl/modes.h>
+
+void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+                         size_t len, const SEED_KEY_SCHEDULE *ks,
+                         unsigned char ivec[SEED_BLOCK_SIZE], int *num)
+	{
+	CRYPTO_ofb128_encrypt(in,out,len,ks,ivec,num,(block128_f)SEED_encrypt);
+	}
diff --git a/openssl/crypto/sha/Makefile b/openssl/crypto/sha/Makefile
new file mode 100644
index 0000000..e6eccb0
--- /dev/null
+++ b/openssl/crypto/sha/Makefile
@@ -0,0 +1,145 @@
+#
+# OpenSSL/crypto/sha/Makefile
+#
+
+DIR=    sha
+TOP=    ../..
+CC=     cc
+CPP=    $(CC) -E
+INCLUDES=
+CFLAG=-g
+MAKEFILE=       Makefile
+AR=             ar r
+
+SHA1_ASM_OBJ=
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+ASFLAGS= $(INCLUDES) $(ASFLAG)
+AFLAGS= $(ASFLAGS)
+
+GENERAL=Makefile
+TEST=shatest.c sha1test.c sha256t.c sha512t.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=sha_dgst.c sha1dgst.c sha_one.c sha1_one.c sha256.c sha512.c
+LIBOBJ=sha_dgst.o sha1dgst.o sha_one.o sha1_one.o sha256.o sha512.o $(SHA1_ASM_OBJ)
+
+SRC= $(LIBSRC)
+
+EXHEADER= sha.h
+HEADER= sha_locl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:    lib
+
+lib:    $(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+sha1-586.s:	asm/sha1-586.pl ../perlasm/x86asm.pl
+	$(PERL) asm/sha1-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
+sha256-586.s:	asm/sha256-586.pl ../perlasm/x86asm.pl
+	$(PERL) asm/sha256-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
+sha512-586.s:	asm/sha512-586.pl ../perlasm/x86asm.pl
+	$(PERL) asm/sha512-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
+
+sha1-ia64.s:   asm/sha1-ia64.pl
+	(cd asm; $(PERL) sha1-ia64.pl ../$@ $(CFLAGS))
+sha256-ia64.s: asm/sha512-ia64.pl
+	(cd asm; $(PERL) sha512-ia64.pl ../$@ $(CFLAGS))
+sha512-ia64.s: asm/sha512-ia64.pl
+	(cd asm; $(PERL) sha512-ia64.pl ../$@ $(CFLAGS))
+
+sha256-armv4.s: asm/sha256-armv4.pl
+	$(PERL) $< $@
+
+# Solaris make has to be explicitly told
+sha1-x86_64.s:	asm/sha1-x86_64.pl;	$(PERL) asm/sha1-x86_64.pl $(PERLASM_SCHEME) > $@
+sha256-x86_64.s:asm/sha512-x86_64.pl;	$(PERL) asm/sha512-x86_64.pl $(PERLASM_SCHEME) $@
+sha512-x86_64.s:asm/sha512-x86_64.pl;	$(PERL) asm/sha512-x86_64.pl $(PERLASM_SCHEME) $@
+sha1-sparcv9.s:	asm/sha1-sparcv9.pl;	$(PERL) asm/sha1-sparcv9.pl $@ $(CFLAGS)
+sha256-sparcv9.s:asm/sha512-sparcv9.pl;	$(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS)
+sha512-sparcv9.s:asm/sha512-sparcv9.pl;	$(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS)
+
+sha1-ppc.s:	asm/sha1-ppc.pl;	$(PERL) asm/sha1-ppc.pl $(PERLASM_SCHEME) $@
+sha256-ppc.s:	asm/sha512-ppc.pl;	$(PERL) asm/sha512-ppc.pl $(PERLASM_SCHEME) $@
+sha512-ppc.s:	asm/sha512-ppc.pl;	$(PERL) asm/sha512-ppc.pl $(PERLASM_SCHEME) $@
+
+# GNU make "catch all"
+sha1-%.s:	asm/sha1-%.pl;		$(PERL) $< $@
+sha256-%.s:	asm/sha512-%.pl;	$(PERL) $< $@
+sha512-%.s:	asm/sha512-%.pl;	$(PERL) $< $@
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+sha1_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+sha1_one.o: ../../include/openssl/opensslconf.h
+sha1_one.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+sha1_one.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+sha1_one.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+sha1_one.o: sha1_one.c
+sha1dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+sha1dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/sha.h
+sha1dgst.o: ../md32_common.h sha1dgst.c sha_locl.h
+sha256.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+sha256.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+sha256.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+sha256.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+sha256.o: ../../include/openssl/symhacks.h ../md32_common.h sha256.c
+sha512.o: ../../e_os.h ../../include/openssl/bio.h
+sha512.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+sha512.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+sha512.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+sha512.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+sha512.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+sha512.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+sha512.o: ../cryptlib.h sha512.c
+sha_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+sha_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/sha.h
+sha_dgst.o: ../md32_common.h sha_dgst.c sha_locl.h
+sha_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+sha_one.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+sha_one.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+sha_one.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+sha_one.o: ../../include/openssl/symhacks.h sha_one.c
diff --git a/openssl/crypto/sha/asm/README b/openssl/crypto/sha/asm/README
new file mode 100644
index 0000000..b7e7557
--- /dev/null
+++ b/openssl/crypto/sha/asm/README
@@ -0,0 +1 @@
+C2.pl works
diff --git a/openssl/crypto/sha/asm/sha1-586.pl b/openssl/crypto/sha/asm/sha1-586.pl
new file mode 100644
index 0000000..a1f8762
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha1-586.pl
@@ -0,0 +1,220 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# [Re]written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# "[Re]written" was achieved in two major overhauls. In 2004 BODY_*
+# functions were re-implemented to address P4 performance issue [see
+# commentary below], and in 2006 the rest was rewritten in order to
+# gain freedom to liberate licensing terms.
+
+# It was noted that Intel IA-32 C compiler generates code which
+# performs ~30% *faster* on P4 CPU than original *hand-coded*
+# SHA1 assembler implementation. To address this problem (and
+# prove that humans are still better than machines:-), the
+# original code was overhauled, which resulted in following
+# performance changes:
+#
+#		compared with original	compared with Intel cc
+#		assembler impl.		generated code
+# Pentium	-16%			+48%
+# PIII/AMD	+8%			+16%
+# P4		+85%(!)			+45%
+#
+# As you can see Pentium came out as looser:-( Yet I reckoned that
+# improvement on P4 outweights the loss and incorporate this
+# re-tuned code to 0.9.7 and later.
+# ----------------------------------------------------------------
+#					<appro@fy.chalmers.se>
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"sha1-586.pl",$ARGV[$#ARGV] eq "386");
+
+$A="eax";
+$B="ebx";
+$C="ecx";
+$D="edx";
+$E="edi";
+$T="esi";
+$tmp1="ebp";
+
+@V=($A,$B,$C,$D,$E,$T);
+
+sub BODY_00_15
+	{
+	local($n,$a,$b,$c,$d,$e,$f)=@_;
+
+	&comment("00_15 $n");
+
+	&mov($f,$c);			# f to hold F_00_19(b,c,d)
+	 if ($n==0)  { &mov($tmp1,$a); }
+	 else        { &mov($a,$tmp1); }
+	&rotl($tmp1,5);			# tmp1=ROTATE(a,5)
+	 &xor($f,$d);
+	&add($tmp1,$e);			# tmp1+=e;
+	 &and($f,$b);
+	&mov($e,&swtmp($n%16));		# e becomes volatile and is loaded
+	 				# with xi, also note that e becomes
+					# f in next round...
+	 &xor($f,$d);			# f holds F_00_19(b,c,d)
+	&rotr($b,2);			# b=ROTATE(b,30)
+	 &lea($tmp1,&DWP(0x5a827999,$tmp1,$e));	# tmp1+=K_00_19+xi
+
+	if ($n==15) { &add($f,$tmp1); }	# f+=tmp1
+	else        { &add($tmp1,$f); }	# f becomes a in next round
+	}
+
+sub BODY_16_19
+	{
+	local($n,$a,$b,$c,$d,$e,$f)=@_;
+
+	&comment("16_19 $n");
+
+	&mov($f,&swtmp($n%16));		# f to hold Xupdate(xi,xa,xb,xc,xd)
+	 &mov($tmp1,$c);		# tmp1 to hold F_00_19(b,c,d)
+	&xor($f,&swtmp(($n+2)%16));
+	 &xor($tmp1,$d);
+	&xor($f,&swtmp(($n+8)%16));
+	 &and($tmp1,$b);		# tmp1 holds F_00_19(b,c,d)
+	&rotr($b,2);			# b=ROTATE(b,30)
+	 &xor($f,&swtmp(($n+13)%16));	# f holds xa^xb^xc^xd
+	&rotl($f,1);			# f=ROTATE(f,1)
+	 &xor($tmp1,$d);		# tmp1=F_00_19(b,c,d)
+	&mov(&swtmp($n%16),$f);		# xi=f
+	&lea($f,&DWP(0x5a827999,$f,$e));# f+=K_00_19+e
+	 &mov($e,$a);			# e becomes volatile
+	&rotl($e,5);			# e=ROTATE(a,5)
+	 &add($f,$tmp1);		# f+=F_00_19(b,c,d)
+	&add($f,$e);			# f+=ROTATE(a,5)
+	}
+
+sub BODY_20_39
+	{
+	local($n,$a,$b,$c,$d,$e,$f)=@_;
+	local $K=($n<40)?0x6ed9eba1:0xca62c1d6;
+
+	&comment("20_39 $n");
+
+	&mov($tmp1,$b);			# tmp1 to hold F_20_39(b,c,d)
+	 &mov($f,&swtmp($n%16));	# f to hold Xupdate(xi,xa,xb,xc,xd)
+	&rotr($b,2);			# b=ROTATE(b,30)
+	 &xor($f,&swtmp(($n+2)%16));
+	&xor($tmp1,$c);
+	 &xor($f,&swtmp(($n+8)%16));
+	&xor($tmp1,$d);			# tmp1 holds F_20_39(b,c,d)
+	 &xor($f,&swtmp(($n+13)%16));	# f holds xa^xb^xc^xd
+	&rotl($f,1);			# f=ROTATE(f,1)
+	 &add($tmp1,$e);
+	&mov(&swtmp($n%16),$f);		# xi=f
+	 &mov($e,$a);			# e becomes volatile
+	&rotl($e,5);			# e=ROTATE(a,5)
+	 &lea($f,&DWP($K,$f,$tmp1));	# f+=K_20_39+e
+	&add($f,$e);			# f+=ROTATE(a,5)
+	}
+
+sub BODY_40_59
+	{
+	local($n,$a,$b,$c,$d,$e,$f)=@_;
+
+	&comment("40_59 $n");
+
+	&mov($f,&swtmp($n%16));		# f to hold Xupdate(xi,xa,xb,xc,xd)
+	 &mov($tmp1,&swtmp(($n+2)%16));
+	&xor($f,$tmp1);
+	 &mov($tmp1,&swtmp(($n+8)%16));
+	&xor($f,$tmp1);
+	 &mov($tmp1,&swtmp(($n+13)%16));
+	&xor($f,$tmp1);			# f holds xa^xb^xc^xd
+	 &mov($tmp1,$b);		# tmp1 to hold F_40_59(b,c,d)
+	&rotl($f,1);			# f=ROTATE(f,1)
+	 &or($tmp1,$c);
+	&mov(&swtmp($n%16),$f);		# xi=f
+	 &and($tmp1,$d);
+	&lea($f,&DWP(0x8f1bbcdc,$f,$e));# f+=K_40_59+e
+	 &mov($e,$b);			# e becomes volatile and is used
+					# to calculate F_40_59(b,c,d)
+	&rotr($b,2);			# b=ROTATE(b,30)
+	 &and($e,$c);
+	&or($tmp1,$e);			# tmp1 holds F_40_59(b,c,d)		
+	 &mov($e,$a);
+	&rotl($e,5);			# e=ROTATE(a,5)
+	 &add($f,$tmp1);		# f+=tmp1;
+	&add($f,$e);			# f+=ROTATE(a,5)
+	}
+
+&function_begin("sha1_block_data_order");
+	&mov($tmp1,&wparam(0));	# SHA_CTX *c
+	&mov($T,&wparam(1));	# const void *input
+	&mov($A,&wparam(2));	# size_t num
+	&stack_push(16);	# allocate X[16]
+	&shl($A,6);
+	&add($A,$T);
+	&mov(&wparam(2),$A);	# pointer beyond the end of input
+	&mov($E,&DWP(16,$tmp1));# pre-load E
+
+	&set_label("loop",16);
+
+	# copy input chunk to X, but reversing byte order!
+	for ($i=0; $i<16; $i+=4)
+		{
+		&mov($A,&DWP(4*($i+0),$T));
+		&mov($B,&DWP(4*($i+1),$T));
+		&mov($C,&DWP(4*($i+2),$T));
+		&mov($D,&DWP(4*($i+3),$T));
+		&bswap($A);
+		&bswap($B);
+		&bswap($C);
+		&bswap($D);
+		&mov(&swtmp($i+0),$A);
+		&mov(&swtmp($i+1),$B);
+		&mov(&swtmp($i+2),$C);
+		&mov(&swtmp($i+3),$D);
+		}
+	&mov(&wparam(1),$T);	# redundant in 1st spin
+
+	&mov($A,&DWP(0,$tmp1));	# load SHA_CTX
+	&mov($B,&DWP(4,$tmp1));
+	&mov($C,&DWP(8,$tmp1));
+	&mov($D,&DWP(12,$tmp1));
+	# E is pre-loaded
+
+	for($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
+	for(;$i<20;$i++)	{ &BODY_16_19($i,@V); unshift(@V,pop(@V)); }
+	for(;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+	for(;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
+	for(;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+
+	(($V[5] eq $D) and ($V[0] eq $E)) or die;	# double-check
+
+	&mov($tmp1,&wparam(0));	# re-load SHA_CTX*
+	&mov($D,&wparam(1));	# D is last "T" and is discarded
+
+	&add($E,&DWP(0,$tmp1));	# E is last "A"...
+	&add($T,&DWP(4,$tmp1));
+	&add($A,&DWP(8,$tmp1));
+	&add($B,&DWP(12,$tmp1));
+	&add($C,&DWP(16,$tmp1));
+
+	&mov(&DWP(0,$tmp1),$E);	# update SHA_CTX
+	 &add($D,64);		# advance input pointer
+	&mov(&DWP(4,$tmp1),$T);
+	 &cmp($D,&wparam(2));	# have we reached the end yet?
+	&mov(&DWP(8,$tmp1),$A);
+	 &mov($E,$C);		# C is last "E" which needs to be "pre-loaded"
+	&mov(&DWP(12,$tmp1),$B);
+	 &mov($T,$D);		# input pointer
+	&mov(&DWP(16,$tmp1),$C);
+	&jb(&label("loop"));
+
+	&stack_pop(16);
+&function_end("sha1_block_data_order");
+&asciz("SHA1 block transform for x86, CRYPTOGAMS by <appro\@openssl.org>");
+
+&asm_finish();
diff --git a/openssl/crypto/sha/asm/sha1-armv4-large.pl b/openssl/crypto/sha/asm/sha1-armv4-large.pl
new file mode 100644
index 0000000..79e3f61
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha1-armv4-large.pl
@@ -0,0 +1,229 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# sha1_block procedure for ARMv4.
+#
+# January 2007.
+
+# Size/performance trade-off
+# ====================================================================
+# impl		size in bytes	comp cycles[*]	measured performance
+# ====================================================================
+# thumb		304		3212		4420
+# armv4-small	392/+29%	1958/+64%	2250/+96%
+# armv4-compact	740/+89%	1552/+26%	1840/+22%
+# armv4-large	1420/+92%	1307/+19%	1370/+34%[***]
+# full unroll	~5100/+260%	~1260/+4%	~1300/+5%
+# ====================================================================
+# thumb		= same as 'small' but in Thumb instructions[**] and
+#		  with recurring code in two private functions;
+# small		= detached Xload/update, loops are folded;
+# compact	= detached Xload/update, 5x unroll;
+# large		= interleaved Xload/update, 5x unroll;
+# full unroll	= interleaved Xload/update, full unroll, estimated[!];
+#
+# [*]	Manually counted instructions in "grand" loop body. Measured
+#	performance is affected by prologue and epilogue overhead,
+#	i-cache availability, branch penalties, etc.
+# [**]	While each Thumb instruction is twice smaller, they are not as
+#	diverse as ARM ones: e.g., there are only two arithmetic
+#	instructions with 3 arguments, no [fixed] rotate, addressing
+#	modes are limited. As result it takes more instructions to do
+#	the same job in Thumb, therefore the code is never twice as
+#	small and always slower.
+# [***]	which is also ~35% better than compiler generated code. Dual-
+#	issue Cortex A8 core was measured to process input block in
+#	~990 cycles.
+
+# August 2010.
+#
+# Rescheduling for dual-issue pipeline resulted in 13% improvement on
+# Cortex A8 core and in absolute terms ~870 cycles per input block
+# [or 13.6 cycles per byte].
+
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
+$ctx="r0";
+$inp="r1";
+$len="r2";
+$a="r3";
+$b="r4";
+$c="r5";
+$d="r6";
+$e="r7";
+$K="r8";
+$t0="r9";
+$t1="r10";
+$t2="r11";
+$t3="r12";
+$Xi="r14";
+@V=($a,$b,$c,$d,$e);
+
+sub Xupdate {
+my ($a,$b,$c,$d,$e,$opt1,$opt2)=@_;
+$code.=<<___;
+	ldr	$t0,[$Xi,#15*4]
+	ldr	$t1,[$Xi,#13*4]
+	ldr	$t2,[$Xi,#7*4]
+	add	$e,$K,$e,ror#2			@ E+=K_xx_xx
+	ldr	$t3,[$Xi,#2*4]
+	eor	$t0,$t0,$t1
+	eor	$t2,$t2,$t3
+	eor	$t1,$c,$d			@ F_xx_xx
+	mov	$t0,$t0,ror#31
+	add	$e,$e,$a,ror#27			@ E+=ROR(A,27)
+	eor	$t0,$t0,$t2,ror#31
+	$opt1					@ F_xx_xx
+	$opt2					@ F_xx_xx
+	add	$e,$e,$t0			@ E+=X[i]
+	str	$t0,[$Xi,#-4]!
+___
+}
+
+sub BODY_00_15 {
+my ($a,$b,$c,$d,$e)=@_;
+$code.=<<___;
+	ldrb	$t0,[$inp],#4
+	ldrb	$t1,[$inp,#-1]
+	ldrb	$t2,[$inp,#-2]
+	add	$e,$K,$e,ror#2			@ E+=K_00_19
+	ldrb	$t3,[$inp,#-3]
+	add	$e,$e,$a,ror#27			@ E+=ROR(A,27)
+	orr	$t0,$t1,$t0,lsl#24
+	eor	$t1,$c,$d			@ F_xx_xx
+	orr	$t0,$t0,$t2,lsl#8
+	orr	$t0,$t0,$t3,lsl#16
+	and	$t1,$b,$t1,ror#2
+	add	$e,$e,$t0			@ E+=X[i]
+	eor	$t1,$t1,$d,ror#2		@ F_00_19(B,C,D)
+	str	$t0,[$Xi,#-4]!
+	add	$e,$e,$t1			@ E+=F_00_19(B,C,D)
+___
+}
+
+sub BODY_16_19 {
+my ($a,$b,$c,$d,$e)=@_;
+	&Xupdate(@_,"and $t1,$b,$t1,ror#2");
+$code.=<<___;
+	eor	$t1,$t1,$d,ror#2		@ F_00_19(B,C,D)
+	add	$e,$e,$t1			@ E+=F_00_19(B,C,D)
+___
+}
+
+sub BODY_20_39 {
+my ($a,$b,$c,$d,$e)=@_;
+	&Xupdate(@_,"eor $t1,$b,$t1,ror#2");
+$code.=<<___;
+	add	$e,$e,$t1			@ E+=F_20_39(B,C,D)
+___
+}
+
+sub BODY_40_59 {
+my ($a,$b,$c,$d,$e)=@_;
+	&Xupdate(@_,"and $t1,$b,$t1,ror#2","and $t2,$c,$d");
+$code.=<<___;
+	add	$e,$e,$t1			@ E+=F_40_59(B,C,D)
+	add	$e,$e,$t2,ror#2
+___
+}
+
+$code=<<___;
+.text
+
+.global	sha1_block_data_order
+.type	sha1_block_data_order,%function
+
+.align	2
+sha1_block_data_order:
+	stmdb	sp!,{r4-r12,lr}
+	add	$len,$inp,$len,lsl#6	@ $len to point at the end of $inp
+	ldmia	$ctx,{$a,$b,$c,$d,$e}
+.Lloop:
+	ldr	$K,.LK_00_19
+	mov	$Xi,sp
+	sub	sp,sp,#15*4
+	mov	$c,$c,ror#30
+	mov	$d,$d,ror#30
+	mov	$e,$e,ror#30		@ [6]
+.L_00_15:
+___
+for($i=0;$i<5;$i++) {
+	&BODY_00_15(@V);	unshift(@V,pop(@V));
+}
+$code.=<<___;
+	teq	$Xi,sp
+	bne	.L_00_15		@ [((11+4)*5+2)*3]
+	sub	sp,sp,#5*4
+___
+	&BODY_00_15(@V);	unshift(@V,pop(@V));
+	&BODY_16_19(@V);	unshift(@V,pop(@V));
+	&BODY_16_19(@V);	unshift(@V,pop(@V));
+	&BODY_16_19(@V);	unshift(@V,pop(@V));
+	&BODY_16_19(@V);	unshift(@V,pop(@V));
+$code.=<<___;
+
+	ldr	$K,.LK_20_39		@ [+15+16*4]
+	sub	sp,sp,#20*4
+	cmn	sp,#0			@ [+3], clear carry to denote 20_39
+.L_20_39_or_60_79:
+___
+for($i=0;$i<5;$i++) {
+	&BODY_20_39(@V);	unshift(@V,pop(@V));
+}
+$code.=<<___;
+	teq	$Xi,sp			@ preserve carry
+	bne	.L_20_39_or_60_79	@ [+((12+3)*5+2)*4]
+	bcs	.L_done			@ [+((12+3)*5+2)*4], spare 300 bytes
+
+	ldr	$K,.LK_40_59
+	sub	sp,sp,#20*4		@ [+2]
+.L_40_59:
+___
+for($i=0;$i<5;$i++) {
+	&BODY_40_59(@V);	unshift(@V,pop(@V));
+}
+$code.=<<___;
+	teq	$Xi,sp
+	bne	.L_40_59		@ [+((12+5)*5+2)*4]
+
+	ldr	$K,.LK_60_79
+	sub	sp,sp,#20*4
+	cmp	sp,#0			@ set carry to denote 60_79
+	b	.L_20_39_or_60_79	@ [+4], spare 300 bytes
+.L_done:
+	add	sp,sp,#80*4		@ "deallocate" stack frame
+	ldmia	$ctx,{$K,$t0,$t1,$t2,$t3}
+	add	$a,$K,$a
+	add	$b,$t0,$b
+	add	$c,$t1,$c,ror#2
+	add	$d,$t2,$d,ror#2
+	add	$e,$t3,$e,ror#2
+	stmia	$ctx,{$a,$b,$c,$d,$e}
+	teq	$inp,$len
+	bne	.Lloop			@ [+18], total 1307
+
+	ldmia	sp!,{r4-r12,lr}
+	tst	lr,#1
+	moveq	pc,lr			@ be binary compatible with V4, yet
+	bx	lr			@ interoperable with Thumb ISA:-)
+.align	2
+.LK_00_19:	.word	0x5a827999
+.LK_20_39:	.word	0x6ed9eba1
+.LK_40_59:	.word	0x8f1bbcdc
+.LK_60_79:	.word	0xca62c1d6
+.size	sha1_block_data_order,.-sha1_block_data_order
+.asciz	"SHA1 block transform for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
+.align	2
+___
+
+$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
+print $code;
+close STDOUT; # enforce flush
diff --git a/openssl/crypto/sha/asm/sha1-ia64.pl b/openssl/crypto/sha/asm/sha1-ia64.pl
new file mode 100644
index 0000000..51c4f47
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha1-ia64.pl
@@ -0,0 +1,306 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# Eternal question is what's wrong with compiler generated code? The
+# trick is that it's possible to reduce the number of shifts required
+# to perform rotations by maintaining copy of 32-bit value in upper
+# bits of 64-bit register. Just follow mux2 and shrp instructions...
+# Performance under big-endian OS such as HP-UX is 179MBps*1GHz, which
+# is >50% better than HP C and >2x better than gcc.
+
+$code=<<___;
+.ident  \"sha1-ia64.s, version 1.2\"
+.ident  \"IA-64 ISA artwork by Andy Polyakov <appro\@fy.chalmers.se>\"
+.explicit
+
+___
+
+
+if ($^O eq "hpux") {
+    $ADDP="addp4";
+    for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); }
+} else { $ADDP="add"; }
+for (@ARGV) {	$big_endian=1 if (/\-DB_ENDIAN/);
+		$big_endian=0 if (/\-DL_ENDIAN/);   }
+if (!defined($big_endian))
+	    {	$big_endian=(unpack('L',pack('N',1))==1);   }
+
+#$human=1;
+if ($human) {	# useful for visual code auditing...
+	($A,$B,$C,$D,$E,$T)   = ("A","B","C","D","E","T");
+	($h0,$h1,$h2,$h3,$h4) = ("h0","h1","h2","h3","h4");
+	($K_00_19, $K_20_39, $K_40_59, $K_60_79) =
+	    (	"K_00_19","K_20_39","K_40_59","K_60_79"	);
+	@X= (	"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7",
+		"X8", "X9","X10","X11","X12","X13","X14","X15"	);
+}
+else {
+	($A,$B,$C,$D,$E,$T)   = ("loc0","loc1","loc2","loc3","loc4","loc5");
+	($h0,$h1,$h2,$h3,$h4) = ("loc6","loc7","loc8","loc9","loc10");
+	($K_00_19, $K_20_39, $K_40_59, $K_60_79) =
+	    (	"r14", "r15", "loc11", "loc12"	);
+	@X= (	"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+		"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"	);
+}
+
+sub BODY_00_15 {
+local	*code=shift;
+local	($i,$a,$b,$c,$d,$e,$f)=@_;
+
+$code.=<<___ if ($i==0);
+{ .mmi;	ld1	$X[$i&0xf]=[inp],2	    // MSB
+	ld1	tmp2=[tmp3],2		};;
+{ .mmi;	ld1	tmp0=[inp],2
+	ld1	tmp4=[tmp3],2		    // LSB
+	dep	$X[$i&0xf]=$X[$i&0xf],tmp2,8,8	};;
+___
+if ($i<15) {
+	$code.=<<___;
+{ .mmi;	ld1	$X[($i+1)&0xf]=[inp],2	    // +1
+	dep	tmp1=tmp0,tmp4,8,8	};;
+{ .mmi;	ld1	tmp2=[tmp3],2		    // +1
+	and	tmp4=$c,$b
+	dep	$X[$i&0xf]=$X[$i&0xf],tmp1,16,16	} //;;
+{ .mmi;	andcm	tmp1=$d,$b
+	add	tmp0=$e,$K_00_19
+	dep.z	tmp5=$a,5,27		};; // a<<5
+{ .mmi;	or	tmp4=tmp4,tmp1		    // F_00_19(b,c,d)=(b&c)|(~b&d)
+	add	$f=tmp0,$X[$i&0xf]	    // f=xi+e+K_00_19
+	extr.u	tmp1=$a,27,5		};; // a>>27
+{ .mmi;	ld1	tmp0=[inp],2		    // +1
+	add	$f=$f,tmp4		    // f+=F_00_19(b,c,d)
+	shrp	$b=tmp6,tmp6,2		}   // b=ROTATE(b,30)
+{ .mmi;	ld1	tmp4=[tmp3],2		    // +1
+	or	tmp5=tmp1,tmp5		    // ROTATE(a,5)
+	mux2	tmp6=$a,0x44		};; // see b in next iteration
+{ .mii;	add	$f=$f,tmp5		    // f+=ROTATE(a,5)
+	dep	$X[($i+1)&0xf]=$X[($i+1)&0xf],tmp2,8,8	// +1
+	mux2	$X[$i&0xf]=$X[$i&0xf],0x44	} //;;
+
+___
+	}
+else	{
+	$code.=<<___;
+{ .mii;	and	tmp3=$c,$b
+	dep	tmp1=tmp0,tmp4,8,8;;
+	dep	$X[$i&0xf]=$X[$i&0xf],tmp1,16,16	} //;;
+{ .mmi;	andcm	tmp1=$d,$b
+	add	tmp0=$e,$K_00_19
+	dep.z	tmp5=$a,5,27		};; // a<<5
+{ .mmi;	or	tmp4=tmp3,tmp1		    // F_00_19(b,c,d)=(b&c)|(~b&d)
+	add	$f=tmp0,$X[$i&0xf]	    // f=xi+e+K_00_19
+	extr.u	tmp1=$a,27,5		}   // a>>27
+{ .mmi;	xor	tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf]	// +1
+	xor	tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf] // +1
+	nop.i	0			};;
+{ .mmi;	add	$f=$f,tmp4		    // f+=F_00_19(b,c,d)
+	xor	tmp2=tmp2,tmp3		    // +1
+	shrp	$b=tmp6,tmp6,2		}   // b=ROTATE(b,30)
+{ .mmi; or	tmp1=tmp1,tmp5		    // ROTATE(a,5)
+	mux2	tmp6=$a,0x44		};; // see b in next iteration
+{ .mii;	add	$f=$f,tmp1		    // f+=ROTATE(a,5)
+	shrp	$e=tmp2,tmp2,31		    // f+1=ROTATE(x[0]^x[2]^x[8]^x[13],1)
+	mux2	$X[$i&0xf]=$X[$i&0xf],0x44  };;
+
+___
+	}
+}
+
+sub BODY_16_19 {
+local	*code=shift;
+local	($i,$a,$b,$c,$d,$e,$f)=@_;
+
+$code.=<<___;
+{ .mmi;	mov	$X[$i&0xf]=$f		    // Xupdate
+	and	tmp0=$c,$b
+	dep.z	tmp5=$a,5,27		}   // a<<5
+{ .mmi;	andcm	tmp1=$d,$b
+	add	tmp4=$e,$K_00_19	};;
+{ .mmi;	or	tmp0=tmp0,tmp1		    // F_00_19(b,c,d)=(b&c)|(~b&d)
+	add	$f=$f,tmp4		    // f+=e+K_00_19
+	extr.u	tmp1=$a,27,5		}   // a>>27
+{ .mmi;	xor	tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf]	// +1
+	xor	tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf]	// +1
+	nop.i	0			};;
+{ .mmi;	add	$f=$f,tmp0		    // f+=F_00_19(b,c,d)
+	xor	tmp2=tmp2,tmp3		    // +1
+	shrp	$b=tmp6,tmp6,2		}   // b=ROTATE(b,30)
+{ .mmi;	or	tmp1=tmp1,tmp5		    // ROTATE(a,5)
+	mux2	tmp6=$a,0x44		};; // see b in next iteration
+{ .mii;	add	$f=$f,tmp1		    // f+=ROTATE(a,5)
+	shrp	$e=tmp2,tmp2,31		    // f+1=ROTATE(x[0]^x[2]^x[8]^x[13],1)
+	nop.i	0			};;
+
+___
+}
+
+sub BODY_20_39 {
+local	*code=shift;
+local	($i,$a,$b,$c,$d,$e,$f,$Konst)=@_;
+	$Konst = $K_20_39 if (!defined($Konst));
+
+if ($i<79) {
+$code.=<<___;
+{ .mib;	mov	$X[$i&0xf]=$f		    // Xupdate
+	dep.z	tmp5=$a,5,27		}   // a<<5
+{ .mib;	xor	tmp0=$c,$b
+	add	tmp4=$e,$Konst		};;
+{ .mmi;	xor	tmp0=tmp0,$d		    // F_20_39(b,c,d)=b^c^d
+	add	$f=$f,tmp4		    // f+=e+K_20_39
+	extr.u	tmp1=$a,27,5		}   // a>>27
+{ .mmi;	xor	tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf]	// +1
+	xor	tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf]	// +1
+	nop.i	0			};;
+{ .mmi;	add	$f=$f,tmp0		    // f+=F_20_39(b,c,d)
+	xor	tmp2=tmp2,tmp3		    // +1
+	shrp	$b=tmp6,tmp6,2		}   // b=ROTATE(b,30)
+{ .mmi;	or	tmp1=tmp1,tmp5		    // ROTATE(a,5)
+	mux2	tmp6=$a,0x44		};; // see b in next iteration
+{ .mii;	add	$f=$f,tmp1		    // f+=ROTATE(a,5)
+	shrp	$e=tmp2,tmp2,31		    // f+1=ROTATE(x[0]^x[2]^x[8]^x[13],1)
+	nop.i	0			};;
+
+___
+}
+else {
+$code.=<<___;
+{ .mib;	mov	$X[$i&0xf]=$f		    // Xupdate
+	dep.z	tmp5=$a,5,27		}   // a<<5
+{ .mib;	xor	tmp0=$c,$b
+	add	tmp4=$e,$Konst		};;
+{ .mib;	xor	tmp0=tmp0,$d		    // F_20_39(b,c,d)=b^c^d
+	extr.u	tmp1=$a,27,5		}   // a>>27
+{ .mib;	add	$f=$f,tmp4		    // f+=e+K_20_39
+	add	$h1=$h1,$a		};; // wrap up
+{ .mmi;	add	$f=$f,tmp0		    // f+=F_20_39(b,c,d)
+	shrp	$b=tmp6,tmp6,2		}   // b=ROTATE(b,30) ;;?
+{ .mmi;	or	tmp1=tmp1,tmp5		    // ROTATE(a,5)
+	add	$h3=$h3,$c		};; // wrap up
+{ .mib;	add	tmp3=1,inp		    // used in unaligned codepath
+	add	$f=$f,tmp1		}   // f+=ROTATE(a,5)
+{ .mib;	add	$h2=$h2,$b		    // wrap up
+	add	$h4=$h4,$d		};; // wrap up
+
+___
+}
+}
+
+sub BODY_40_59 {
+local	*code=shift;
+local	($i,$a,$b,$c,$d,$e,$f)=@_;
+
+$code.=<<___;
+{ .mmi;	mov	$X[$i&0xf]=$f		    // Xupdate
+	and	tmp0=$c,$b
+	dep.z	tmp5=$a,5,27		}   // a<<5
+{ .mmi;	and	tmp1=$d,$b
+	add	tmp4=$e,$K_40_59	};;
+{ .mmi;	or	tmp0=tmp0,tmp1		    // (b&c)|(b&d)
+	add	$f=$f,tmp4		    // f+=e+K_40_59
+	extr.u	tmp1=$a,27,5		}   // a>>27
+{ .mmi;	and	tmp4=$c,$d
+	xor	tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf]	// +1
+	xor	tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf]	// +1
+	};;
+{ .mmi;	or	tmp1=tmp1,tmp5		    // ROTATE(a,5)
+	xor	tmp2=tmp2,tmp3		    // +1
+	shrp	$b=tmp6,tmp6,2		}   // b=ROTATE(b,30)
+{ .mmi;	or	tmp0=tmp0,tmp4		    // F_40_59(b,c,d)=(b&c)|(b&d)|(c&d)
+	mux2	tmp6=$a,0x44		};; // see b in next iteration
+{ .mii;	add	$f=$f,tmp0		    // f+=F_40_59(b,c,d)
+	shrp	$e=tmp2,tmp2,31;;	    // f+1=ROTATE(x[0]^x[2]^x[8]^x[13],1)
+	add	$f=$f,tmp1		};; // f+=ROTATE(a,5)
+
+___
+}
+sub BODY_60_79	{ &BODY_20_39(@_,$K_60_79); }
+
+$code.=<<___;
+.text
+
+tmp0=r8;
+tmp1=r9;
+tmp2=r10;
+tmp3=r11;
+ctx=r32;	// in0
+inp=r33;	// in1
+
+// void sha1_block_data_order(SHA_CTX *c,const void *p,size_t num);
+.global	sha1_block_data_order#
+.proc	sha1_block_data_order#
+.align	32
+sha1_block_data_order:
+	.prologue
+{ .mmi;	alloc	tmp1=ar.pfs,3,15,0,0
+	$ADDP	tmp0=4,ctx
+	.save	ar.lc,r3
+	mov	r3=ar.lc		}
+{ .mmi;	$ADDP	ctx=0,ctx
+	$ADDP	inp=0,inp
+	mov	r2=pr			};;
+tmp4=in2;
+tmp5=loc13;
+tmp6=loc14;
+	.body
+{ .mlx;	ld4	$h0=[ctx],8
+	movl	$K_00_19=0x5a827999	}
+{ .mlx;	ld4	$h1=[tmp0],8
+	movl	$K_20_39=0x6ed9eba1	};;
+{ .mlx;	ld4	$h2=[ctx],8
+	movl	$K_40_59=0x8f1bbcdc	}
+{ .mlx;	ld4	$h3=[tmp0]
+	movl	$K_60_79=0xca62c1d6	};;
+{ .mmi;	ld4	$h4=[ctx],-16
+	add	in2=-1,in2		    // adjust num for ar.lc
+	mov	ar.ec=1			};;
+{ .mmi;	nop.m	0
+	add	tmp3=1,inp
+	mov	ar.lc=in2		};; // brp.loop.imp: too far
+
+.Ldtop:
+{ .mmi;	mov	$A=$h0
+	mov	$B=$h1
+	mux2	tmp6=$h1,0x44		}
+{ .mmi;	mov	$C=$h2
+	mov	$D=$h3
+	mov	$E=$h4			};;
+
+___
+
+{ my $i,@V=($A,$B,$C,$D,$E,$T);
+
+	for($i=0;$i<16;$i++)	{ &BODY_00_15(\$code,$i,@V); unshift(@V,pop(@V)); }
+	for(;$i<20;$i++)	{ &BODY_16_19(\$code,$i,@V); unshift(@V,pop(@V)); }
+	for(;$i<40;$i++)	{ &BODY_20_39(\$code,$i,@V); unshift(@V,pop(@V)); }
+	for(;$i<60;$i++)	{ &BODY_40_59(\$code,$i,@V); unshift(@V,pop(@V)); }
+	for(;$i<80;$i++)	{ &BODY_60_79(\$code,$i,@V); unshift(@V,pop(@V)); }
+
+	(($V[5] eq $D) and ($V[0] eq $E)) or die;	# double-check
+}
+
+$code.=<<___;
+{ .mmb;	add	$h0=$h0,$E
+	nop.m	0
+	br.ctop.dptk.many	.Ldtop	};;
+.Ldend:
+{ .mmi;	add	tmp0=4,ctx
+	mov	ar.lc=r3		};;
+{ .mmi;	st4	[ctx]=$h0,8
+	st4	[tmp0]=$h1,8		};;
+{ .mmi;	st4	[ctx]=$h2,8
+	st4	[tmp0]=$h3		};;
+{ .mib;	st4	[ctx]=$h4,-16
+	mov	pr=r2,0x1ffff
+	br.ret.sptk.many	b0	};;
+.endp	sha1_block_data_order#
+stringz	"SHA1 block transform for IA64, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+$output=shift and open STDOUT,">$output";
+print $code;
diff --git a/openssl/crypto/sha/asm/sha1-ppc.pl b/openssl/crypto/sha/asm/sha1-ppc.pl
new file mode 100644
index 0000000..dcd0fcd
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha1-ppc.pl
@@ -0,0 +1,319 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# I let hardware handle unaligned input(*), except on page boundaries
+# (see below for details). Otherwise straightforward implementation
+# with X vector in register bank. The module is big-endian [which is
+# not big deal as there're no little-endian targets left around].
+#
+# (*) this means that this module is inappropriate for PPC403? Does
+#     anybody know if pre-POWER3 can sustain unaligned load?
+
+# 			-m64	-m32
+# ----------------------------------
+# PPC970,gcc-4.0.0	+76%	+59%
+# Power6,xlc-7		+68%	+33%
+
+$flavour = shift;
+
+if ($flavour =~ /64/) {
+	$SIZE_T	=8;
+	$UCMP	="cmpld";
+	$STU	="stdu";
+	$POP	="ld";
+	$PUSH	="std";
+} elsif ($flavour =~ /32/) {
+	$SIZE_T	=4;
+	$UCMP	="cmplw";
+	$STU	="stwu";
+	$POP	="lwz";
+	$PUSH	="stw";
+} else { die "nonsense $flavour"; }
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
+
+$FRAME=24*$SIZE_T;
+
+$K  ="r0";
+$sp ="r1";
+$toc="r2";
+$ctx="r3";
+$inp="r4";
+$num="r5";
+$t0 ="r15";
+$t1 ="r6";
+
+$A  ="r7";
+$B  ="r8";
+$C  ="r9";
+$D  ="r10";
+$E  ="r11";
+$T  ="r12";
+
+@V=($A,$B,$C,$D,$E,$T);
+@X=("r16","r17","r18","r19","r20","r21","r22","r23",
+    "r24","r25","r26","r27","r28","r29","r30","r31");
+
+sub BODY_00_19 {
+my ($i,$a,$b,$c,$d,$e,$f)=@_;
+my $j=$i+1;
+$code.=<<___ if ($i==0);
+	lwz	@X[$i],`$i*4`($inp)
+___
+$code.=<<___ if ($i<15);
+	lwz	@X[$j],`$j*4`($inp)
+	add	$f,$K,$e
+	rotlwi	$e,$a,5
+	add	$f,$f,@X[$i]
+	and	$t0,$c,$b
+	add	$f,$f,$e
+	andc	$t1,$d,$b
+	rotlwi	$b,$b,30
+	or	$t0,$t0,$t1
+	add	$f,$f,$t0
+___
+$code.=<<___ if ($i>=15);
+	add	$f,$K,$e
+	rotlwi	$e,$a,5
+	xor	@X[$j%16],@X[$j%16],@X[($j+2)%16]
+	add	$f,$f,@X[$i%16]
+	and	$t0,$c,$b
+	xor	@X[$j%16],@X[$j%16],@X[($j+8)%16]
+	add	$f,$f,$e
+	andc	$t1,$d,$b
+	rotlwi	$b,$b,30
+	or	$t0,$t0,$t1
+	xor	@X[$j%16],@X[$j%16],@X[($j+13)%16]
+	add	$f,$f,$t0
+	rotlwi	@X[$j%16],@X[$j%16],1
+___
+}
+
+sub BODY_20_39 {
+my ($i,$a,$b,$c,$d,$e,$f)=@_;
+my $j=$i+1;
+$code.=<<___ if ($i<79);
+	add	$f,$K,$e
+	rotlwi	$e,$a,5
+	xor	@X[$j%16],@X[$j%16],@X[($j+2)%16]
+	add	$f,$f,@X[$i%16]
+	xor	$t0,$b,$c
+	xor	@X[$j%16],@X[$j%16],@X[($j+8)%16]
+	add	$f,$f,$e
+	rotlwi	$b,$b,30
+	xor	$t0,$t0,$d
+	xor	@X[$j%16],@X[$j%16],@X[($j+13)%16]
+	add	$f,$f,$t0
+	rotlwi	@X[$j%16],@X[$j%16],1
+___
+$code.=<<___ if ($i==79);
+	add	$f,$K,$e
+	rotlwi	$e,$a,5
+	lwz	r16,0($ctx)
+	add	$f,$f,@X[$i%16]
+	xor	$t0,$b,$c
+	lwz	r17,4($ctx)
+	add	$f,$f,$e
+	rotlwi	$b,$b,30
+	lwz	r18,8($ctx)
+	xor	$t0,$t0,$d
+	lwz	r19,12($ctx)
+	add	$f,$f,$t0
+	lwz	r20,16($ctx)
+___
+}
+
+sub BODY_40_59 {
+my ($i,$a,$b,$c,$d,$e,$f)=@_;
+my $j=$i+1;
+$code.=<<___;
+	add	$f,$K,$e
+	rotlwi	$e,$a,5
+	xor	@X[$j%16],@X[$j%16],@X[($j+2)%16]
+	add	$f,$f,@X[$i%16]
+	and	$t0,$b,$c
+	xor	@X[$j%16],@X[$j%16],@X[($j+8)%16]
+	add	$f,$f,$e
+	or	$t1,$b,$c
+	rotlwi	$b,$b,30
+	xor	@X[$j%16],@X[$j%16],@X[($j+13)%16]
+	and	$t1,$t1,$d
+	or	$t0,$t0,$t1
+	rotlwi	@X[$j%16],@X[$j%16],1
+	add	$f,$f,$t0
+___
+}
+
+$code=<<___;
+.machine	"any"
+.text
+
+.globl	.sha1_block_data_order
+.align	4
+.sha1_block_data_order:
+	mflr	r0
+	$STU	$sp,`-($FRAME+64)`($sp)
+	$PUSH	r0,`$FRAME-$SIZE_T*18`($sp)
+	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
+	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
+	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
+	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
+	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
+	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
+	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
+	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
+	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
+	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
+	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
+	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
+	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
+	lwz	$A,0($ctx)
+	lwz	$B,4($ctx)
+	lwz	$C,8($ctx)
+	lwz	$D,12($ctx)
+	lwz	$E,16($ctx)
+	andi.	r0,$inp,3
+	bne	Lunaligned
+Laligned:
+	mtctr	$num
+	bl	Lsha1_block_private
+Ldone:
+	$POP	r0,`$FRAME-$SIZE_T*18`($sp)
+	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
+	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
+	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
+	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
+	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
+	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
+	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
+	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
+	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
+	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
+	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
+	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
+	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
+	mtlr	r0
+	addi	$sp,$sp,`$FRAME+64`
+	blr
+___
+
+# PowerPC specification allows an implementation to be ill-behaved
+# upon unaligned access which crosses page boundary. "Better safe
+# than sorry" principle makes me treat it specially. But I don't
+# look for particular offending word, but rather for 64-byte input
+# block which crosses the boundary. Once found that block is aligned
+# and hashed separately...
+$code.=<<___;
+.align	4
+Lunaligned:
+	subfic	$t1,$inp,4096
+	andi.	$t1,$t1,4095	; distance to closest page boundary
+	srwi.	$t1,$t1,6	; t1/=64
+	beq	Lcross_page
+	$UCMP	$num,$t1
+	ble-	Laligned	; didn't cross the page boundary
+	mtctr	$t1
+	subfc	$num,$t1,$num
+	bl	Lsha1_block_private
+Lcross_page:
+	li	$t1,16
+	mtctr	$t1
+	addi	r20,$sp,$FRAME	; spot below the frame
+Lmemcpy:
+	lbz	r16,0($inp)
+	lbz	r17,1($inp)
+	lbz	r18,2($inp)
+	lbz	r19,3($inp)
+	addi	$inp,$inp,4
+	stb	r16,0(r20)
+	stb	r17,1(r20)
+	stb	r18,2(r20)
+	stb	r19,3(r20)
+	addi	r20,r20,4
+	bdnz	Lmemcpy
+
+	$PUSH	$inp,`$FRAME-$SIZE_T*19`($sp)
+	li	$t1,1
+	addi	$inp,$sp,$FRAME
+	mtctr	$t1
+	bl	Lsha1_block_private
+	$POP	$inp,`$FRAME-$SIZE_T*19`($sp)
+	addic.	$num,$num,-1
+	bne-	Lunaligned
+	b	Ldone
+___
+
+# This is private block function, which uses tailored calling
+# interface, namely upon entry SHA_CTX is pre-loaded to given
+# registers and counter register contains amount of chunks to
+# digest...
+$code.=<<___;
+.align	4
+Lsha1_block_private:
+___
+$code.=<<___;	# load K_00_19
+	lis	$K,0x5a82
+	ori	$K,$K,0x7999
+___
+for($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;	# load K_20_39
+	lis	$K,0x6ed9
+	ori	$K,$K,0xeba1
+___
+for(;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;	# load K_40_59
+	lis	$K,0x8f1b
+	ori	$K,$K,0xbcdc
+___
+for(;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;	# load K_60_79
+	lis	$K,0xca62
+	ori	$K,$K,0xc1d6
+___
+for(;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+	add	r16,r16,$E
+	add	r17,r17,$T
+	add	r18,r18,$A
+	add	r19,r19,$B
+	add	r20,r20,$C
+	stw	r16,0($ctx)
+	mr	$A,r16
+	stw	r17,4($ctx)
+	mr	$B,r17
+	stw	r18,8($ctx)
+	mr	$C,r18
+	stw	r19,12($ctx)
+	mr	$D,r19
+	stw	r20,16($ctx)
+	mr	$E,r20
+	addi	$inp,$inp,`16*4`
+	bdnz-	Lsha1_block_private
+	blr
+___
+$code.=<<___;
+.asciz	"SHA1 block transform for PPC, CRYPTOGAMS by <appro\@fy.chalmers.se>"
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/sha/asm/sha1-s390x.pl b/openssl/crypto/sha/asm/sha1-s390x.pl
new file mode 100644
index 0000000..4b17848
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha1-s390x.pl
@@ -0,0 +1,226 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# SHA1 block procedure for s390x.
+
+# April 2007.
+#
+# Performance is >30% better than gcc 3.3 generated code. But the real
+# twist is that SHA1 hardware support is detected and utilized. In
+# which case performance can reach further >4.5x for larger chunks.
+
+# January 2009.
+#
+# Optimize Xupdate for amount of memory references and reschedule
+# instructions to favour dual-issue z10 pipeline. On z10 hardware is
+# "only" ~2.3x faster than software.
+
+$kimdfunc=1;	# magic function code for kimd instruction
+
+$output=shift;
+open STDOUT,">$output";
+
+$K_00_39="%r0"; $K=$K_00_39;
+$K_40_79="%r1";
+$ctx="%r2";	$prefetch="%r2";
+$inp="%r3";
+$len="%r4";
+
+$A="%r5";
+$B="%r6";
+$C="%r7";
+$D="%r8";
+$E="%r9";	@V=($A,$B,$C,$D,$E);
+$t0="%r10";
+$t1="%r11";
+@X=("%r12","%r13","%r14");
+$sp="%r15";
+
+$frame=160+16*4;
+
+sub Xupdate {
+my $i=shift;
+
+$code.=<<___ if ($i==15);
+	lg	$prefetch,160($sp)	### Xupdate(16) warm-up
+	lr	$X[0],$X[2]
+___
+return if ($i&1);	# Xupdate is vectorized and executed every 2nd cycle
+$code.=<<___ if ($i<16);
+	lg	$X[0],`$i*4`($inp)	### Xload($i)
+	rllg	$X[1],$X[0],32
+___
+$code.=<<___ if ($i>=16);
+	xgr	$X[0],$prefetch		### Xupdate($i)
+	lg	$prefetch,`160+4*(($i+2)%16)`($sp)
+	xg	$X[0],`160+4*(($i+8)%16)`($sp)
+	xgr	$X[0],$prefetch
+	rll	$X[0],$X[0],1
+	rllg	$X[1],$X[0],32
+	rll	$X[1],$X[1],1
+	rllg	$X[0],$X[1],32
+	lr	$X[2],$X[1]		# feedback
+___
+$code.=<<___ if ($i<=70);
+	stg	$X[0],`160+4*($i%16)`($sp)
+___
+unshift(@X,pop(@X));
+}
+
+sub BODY_00_19 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $xi=$X[1];
+
+	&Xupdate($i);
+$code.=<<___;
+	alr	$e,$K		### $i
+	rll	$t1,$a,5
+	lr	$t0,$d
+	xr	$t0,$c
+	alr	$e,$t1
+	nr	$t0,$b
+	alr	$e,$xi
+	xr	$t0,$d
+	rll	$b,$b,30
+	alr	$e,$t0
+___
+}
+
+sub BODY_20_39 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $xi=$X[1];
+
+	&Xupdate($i);
+$code.=<<___;
+	alr	$e,$K		### $i
+	rll	$t1,$a,5
+	lr	$t0,$b
+	alr	$e,$t1
+	xr	$t0,$c
+	alr	$e,$xi
+	xr	$t0,$d
+	rll	$b,$b,30
+	alr	$e,$t0
+___
+}
+
+sub BODY_40_59 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $xi=$X[1];
+
+	&Xupdate($i);
+$code.=<<___;
+	alr	$e,$K		### $i
+	rll	$t1,$a,5
+	lr	$t0,$b
+	alr	$e,$t1
+	or	$t0,$c
+	lr	$t1,$b
+	nr	$t0,$d
+	nr	$t1,$c
+	alr	$e,$xi
+	or	$t0,$t1
+	rll	$b,$b,30
+	alr	$e,$t0
+___
+}
+
+$code.=<<___;
+.text
+.align	64
+.type	Ktable,\@object
+Ktable: .long	0x5a827999,0x6ed9eba1,0x8f1bbcdc,0xca62c1d6
+	.skip	48	#.long	0,0,0,0,0,0,0,0,0,0,0,0
+.size	Ktable,.-Ktable
+.globl	sha1_block_data_order
+.type	sha1_block_data_order,\@function
+sha1_block_data_order:
+___
+$code.=<<___ if ($kimdfunc);
+	larl	%r1,OPENSSL_s390xcap_P
+	lg	%r0,0(%r1)
+	tmhl	%r0,0x4000	# check for message-security assist
+	jz	.Lsoftware
+	lghi	%r0,0
+	la	%r1,16($sp)
+	.long	0xb93e0002	# kimd %r0,%r2
+	lg	%r0,16($sp)
+	tmhh	%r0,`0x8000>>$kimdfunc`
+	jz	.Lsoftware
+	lghi	%r0,$kimdfunc
+	lgr	%r1,$ctx
+	lgr	%r2,$inp
+	sllg	%r3,$len,6
+	.long	0xb93e0002	# kimd %r0,%r2
+	brc	1,.-4		# pay attention to "partial completion"
+	br	%r14
+.align	16
+.Lsoftware:
+___
+$code.=<<___;
+	lghi	%r1,-$frame
+	stg	$ctx,16($sp)
+	stmg	%r6,%r15,48($sp)
+	lgr	%r0,$sp
+	la	$sp,0(%r1,$sp)
+	stg	%r0,0($sp)
+
+	larl	$t0,Ktable
+	llgf	$A,0($ctx)
+	llgf	$B,4($ctx)
+	llgf	$C,8($ctx)
+	llgf	$D,12($ctx)
+	llgf	$E,16($ctx)
+
+	lg	$K_00_39,0($t0)
+	lg	$K_40_79,8($t0)
+
+.Lloop:
+	rllg	$K_00_39,$K_00_39,32
+___
+for ($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+	rllg	$K_00_39,$K_00_39,32
+___
+for (;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;	$K=$K_40_79;
+	rllg	$K_40_79,$K_40_79,32
+___
+for (;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+	rllg	$K_40_79,$K_40_79,32
+___
+for (;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+
+	lg	$ctx,`$frame+16`($sp)
+	la	$inp,64($inp)
+	al	$A,0($ctx)
+	al	$B,4($ctx)
+	al	$C,8($ctx)
+	al	$D,12($ctx)
+	al	$E,16($ctx)
+	st	$A,0($ctx)
+	st	$B,4($ctx)
+	st	$C,8($ctx)
+	st	$D,12($ctx)
+	st	$E,16($ctx)
+	brct	$len,.Lloop
+
+	lmg	%r6,%r15,`$frame+48`($sp)
+	br	%r14
+.size	sha1_block_data_order,.-sha1_block_data_order
+.string	"SHA1 block transform for s390x, CRYPTOGAMS by <appro\@openssl.org>"
+.comm	OPENSSL_s390xcap_P,8,8
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/sha/asm/sha1-sparcv9.pl b/openssl/crypto/sha/asm/sha1-sparcv9.pl
new file mode 100644
index 0000000..5c161ce
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha1-sparcv9.pl
@@ -0,0 +1,284 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# Performance improvement is not really impressive on pre-T1 CPU: +8%
+# over Sun C and +25% over gcc [3.3]. While on T1, a.k.a. Niagara, it
+# turned to be 40% faster than 64-bit code generated by Sun C 5.8 and
+# >2x than 64-bit code generated by gcc 3.4. And there is a gimmick.
+# X[16] vector is packed to 8 64-bit registers and as result nothing
+# is spilled on stack. In addition input data is loaded in compact
+# instruction sequence, thus minimizing the window when the code is
+# subject to [inter-thread] cache-thrashing hazard. The goal is to
+# ensure scalability on UltraSPARC T1, or rather to avoid decay when
+# amount of active threads exceeds the number of physical cores.
+
+$bits=32;
+for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
+if ($bits==64)	{ $bias=2047; $frame=192; }
+else		{ $bias=0;    $frame=112; }
+
+$output=shift;
+open STDOUT,">$output";
+
+@X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7");
+$rot1m="%g2";
+$tmp64="%g3";
+$Xi="%g4";
+$A="%l0";
+$B="%l1";
+$C="%l2";
+$D="%l3";
+$E="%l4";
+@V=($A,$B,$C,$D,$E);
+$K_00_19="%l5";
+$K_20_39="%l6";
+$K_40_59="%l7";
+$K_60_79="%g5";
+@K=($K_00_19,$K_20_39,$K_40_59,$K_60_79);
+
+$ctx="%i0";
+$inp="%i1";
+$len="%i2";
+$tmp0="%i3";
+$tmp1="%i4";
+$tmp2="%i5";
+
+sub BODY_00_15 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $xi=($i&1)?@X[($i/2)%8]:$Xi;
+
+$code.=<<___;
+	sll	$a,5,$tmp0		!! $i
+	add	@K[$i/20],$e,$e
+	srl	$a,27,$tmp1
+	add	$tmp0,$e,$e
+	and	$c,$b,$tmp0
+	add	$tmp1,$e,$e
+	sll	$b,30,$tmp2
+	andn	$d,$b,$tmp1
+	srl	$b,2,$b
+	or	$tmp1,$tmp0,$tmp1
+	or	$tmp2,$b,$b
+	add	$xi,$e,$e
+___
+if ($i&1 && $i<15) {
+	$code.=
+	"	srlx	@X[(($i+1)/2)%8],32,$Xi\n";
+}
+$code.=<<___;
+	add	$tmp1,$e,$e
+___
+}
+
+sub Xupdate {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i/2;
+
+if ($i&1) {
+$code.=<<___;
+	sll	$a,5,$tmp0		!! $i
+	add	@K[$i/20],$e,$e
+	srl	$a,27,$tmp1
+___
+} else {
+$code.=<<___;
+	sllx	@X[($j+6)%8],32,$Xi	! Xupdate($i)
+	xor	@X[($j+1)%8],@X[$j%8],@X[$j%8]
+	srlx	@X[($j+7)%8],32,$tmp1
+	xor	@X[($j+4)%8],@X[$j%8],@X[$j%8]
+	sll	$a,5,$tmp0		!! $i
+	or	$tmp1,$Xi,$Xi
+	add	@K[$i/20],$e,$e		!!
+	xor	$Xi,@X[$j%8],@X[$j%8]
+	srlx	@X[$j%8],31,$Xi
+	add	@X[$j%8],@X[$j%8],@X[$j%8]
+	and	$Xi,$rot1m,$Xi
+	andn	@X[$j%8],$rot1m,@X[$j%8]
+	srl	$a,27,$tmp1		!!
+	or	$Xi,@X[$j%8],@X[$j%8]
+___
+}
+}
+
+sub BODY_16_19 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+
+	&Xupdate(@_);
+    if ($i&1) {
+	$xi=@X[($i/2)%8];
+    } else {
+	$xi=$Xi;
+	$code.="\tsrlx	@X[($i/2)%8],32,$xi\n";
+    }
+$code.=<<___;
+	add	$tmp0,$e,$e		!!
+	and	$c,$b,$tmp0
+	add	$tmp1,$e,$e
+	sll	$b,30,$tmp2
+	add	$xi,$e,$e
+	andn	$d,$b,$tmp1
+	srl	$b,2,$b
+	or	$tmp1,$tmp0,$tmp1
+	or	$tmp2,$b,$b
+	add	$tmp1,$e,$e
+___
+}
+
+sub BODY_20_39 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $xi;
+	&Xupdate(@_);
+    if ($i&1) {
+	$xi=@X[($i/2)%8];
+    } else {
+	$xi=$Xi;
+	$code.="\tsrlx	@X[($i/2)%8],32,$xi\n";
+    }
+$code.=<<___;
+	add	$tmp0,$e,$e		!!
+	xor	$c,$b,$tmp0
+	add	$tmp1,$e,$e
+	sll	$b,30,$tmp2
+	xor	$d,$tmp0,$tmp1
+	srl	$b,2,$b
+	add	$tmp1,$e,$e
+	or	$tmp2,$b,$b
+	add	$xi,$e,$e
+___
+}
+
+sub BODY_40_59 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $xi;
+	&Xupdate(@_);
+    if ($i&1) {
+	$xi=@X[($i/2)%8];
+    } else {
+	$xi=$Xi;
+	$code.="\tsrlx	@X[($i/2)%8],32,$xi\n";
+    }
+$code.=<<___;
+	add	$tmp0,$e,$e		!!
+	and	$c,$b,$tmp0
+	add	$tmp1,$e,$e
+	sll	$b,30,$tmp2
+	or	$c,$b,$tmp1
+	srl	$b,2,$b
+	and	$d,$tmp1,$tmp1
+	add	$xi,$e,$e
+	or	$tmp1,$tmp0,$tmp1
+	or	$tmp2,$b,$b
+	add	$tmp1,$e,$e
+___
+}
+
+$code.=<<___ if ($bits==64);
+.register	%g2,#scratch
+.register	%g3,#scratch
+___
+$code.=<<___;
+.section	".text",#alloc,#execinstr
+
+.align	32
+.globl	sha1_block_data_order
+sha1_block_data_order:
+	save	%sp,-$frame,%sp
+	sllx	$len,6,$len
+	add	$inp,$len,$len
+
+	or	%g0,1,$rot1m
+	sllx	$rot1m,32,$rot1m
+	or	$rot1m,1,$rot1m
+
+	ld	[$ctx+0],$A
+	ld	[$ctx+4],$B
+	ld	[$ctx+8],$C
+	ld	[$ctx+12],$D
+	ld	[$ctx+16],$E
+	andn	$inp,7,$tmp0
+
+	sethi	%hi(0x5a827999),$K_00_19
+	or	$K_00_19,%lo(0x5a827999),$K_00_19
+	sethi	%hi(0x6ed9eba1),$K_20_39
+	or	$K_20_39,%lo(0x6ed9eba1),$K_20_39
+	sethi	%hi(0x8f1bbcdc),$K_40_59
+	or	$K_40_59,%lo(0x8f1bbcdc),$K_40_59
+	sethi	%hi(0xca62c1d6),$K_60_79
+	or	$K_60_79,%lo(0xca62c1d6),$K_60_79
+
+.Lloop:
+	ldx	[$tmp0+0],@X[0]
+	ldx	[$tmp0+16],@X[2]
+	ldx	[$tmp0+32],@X[4]
+	ldx	[$tmp0+48],@X[6]
+	and	$inp,7,$tmp1
+	ldx	[$tmp0+8],@X[1]
+	sll	$tmp1,3,$tmp1
+	ldx	[$tmp0+24],@X[3]
+	subcc	%g0,$tmp1,$tmp2	! should be 64-$tmp1, but -$tmp1 works too
+	ldx	[$tmp0+40],@X[5]
+	bz,pt	%icc,.Laligned
+	ldx	[$tmp0+56],@X[7]
+
+	sllx	@X[0],$tmp1,@X[0]
+	ldx	[$tmp0+64],$tmp64
+___
+for($i=0;$i<7;$i++)
+{   $code.=<<___;
+	srlx	@X[$i+1],$tmp2,$Xi
+	sllx	@X[$i+1],$tmp1,@X[$i+1]
+	or	$Xi,@X[$i],@X[$i]
+___
+}
+$code.=<<___;
+	srlx	$tmp64,$tmp2,$tmp64
+	or	$tmp64,@X[7],@X[7]
+.Laligned:
+	srlx	@X[0],32,$Xi
+___
+for ($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
+for (;$i<20;$i++)	{ &BODY_16_19($i,@V); unshift(@V,pop(@V)); }
+for (;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+for (;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
+for (;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+
+	ld	[$ctx+0],@X[0]
+	ld	[$ctx+4],@X[1]
+	ld	[$ctx+8],@X[2]
+	ld	[$ctx+12],@X[3]
+	add	$inp,64,$inp
+	ld	[$ctx+16],@X[4]
+	cmp	$inp,$len
+
+	add	$A,@X[0],$A
+	st	$A,[$ctx+0]
+	add	$B,@X[1],$B
+	st	$B,[$ctx+4]
+	add	$C,@X[2],$C
+	st	$C,[$ctx+8]
+	add	$D,@X[3],$D
+	st	$D,[$ctx+12]
+	add	$E,@X[4],$E
+	st	$E,[$ctx+16]
+
+	bne	`$bits==64?"%xcc":"%icc"`,.Lloop
+	andn	$inp,7,$tmp0
+
+	ret
+	restore
+.type	sha1_block_data_order,#function
+.size	sha1_block_data_order,(.-sha1_block_data_order)
+.asciz	"SHA1 block transform for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
+.align	4
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/sha/asm/sha1-sparcv9a.pl b/openssl/crypto/sha/asm/sha1-sparcv9a.pl
new file mode 100644
index 0000000..85e8d68
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha1-sparcv9a.pl
@@ -0,0 +1,601 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# January 2009
+#
+# Provided that UltraSPARC VIS instructions are pipe-lined(*) and
+# pairable(*) with IALU ones, offloading of Xupdate to the UltraSPARC
+# Graphic Unit would make it possible to achieve higher instruction-
+# level parallelism, ILP, and thus higher performance. It should be
+# explicitly noted that ILP is the keyword, and it means that this
+# code would be unsuitable for cores like UltraSPARC-Tx. The idea is
+# not really novel, Sun had VIS-powered implementation for a while.
+# Unlike Sun's implementation this one can process multiple unaligned
+# input blocks, and as such works as drop-in replacement for OpenSSL
+# sha1_block_data_order. Performance improvement was measured to be
+# 40% over pure IALU sha1-sparcv9.pl on UltraSPARC-IIi, but 12% on
+# UltraSPARC-III. See below for discussion...
+#
+# The module does not present direct interest for OpenSSL, because
+# it doesn't provide better performance on contemporary SPARCv9 CPUs,
+# UltraSPARC-Tx and SPARC64-V[II] to be specific. Those who feel they
+# absolutely must score on UltraSPARC-I-IV can simply replace
+# crypto/sha/asm/sha1-sparcv9.pl with this module.
+#
+# (*)	"Pipe-lined" means that even if it takes several cycles to
+#	complete, next instruction using same functional unit [but not
+#	depending on the result of the current instruction] can start
+#	execution without having to wait for the unit. "Pairable"
+#	means that two [or more] independent instructions can be
+#	issued at the very same time.
+
+$bits=32;
+for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
+if ($bits==64)	{ $bias=2047; $frame=192; }
+else		{ $bias=0;    $frame=112; }
+
+$output=shift;
+open STDOUT,">$output";
+
+$ctx="%i0";
+$inp="%i1";
+$len="%i2";
+$tmp0="%i3";
+$tmp1="%i4";
+$tmp2="%i5";
+$tmp3="%g5";
+
+$base="%g1";
+$align="%g4";
+$Xfer="%o5";
+$nXfer=$tmp3;
+$Xi="%o7";
+
+$A="%l0";
+$B="%l1";
+$C="%l2";
+$D="%l3";
+$E="%l4";
+@V=($A,$B,$C,$D,$E);
+
+$Actx="%o0";
+$Bctx="%o1";
+$Cctx="%o2";
+$Dctx="%o3";
+$Ectx="%o4";
+
+$fmul="%f32";
+$VK_00_19="%f34";
+$VK_20_39="%f36";
+$VK_40_59="%f38";
+$VK_60_79="%f40";
+@VK=($VK_00_19,$VK_20_39,$VK_40_59,$VK_60_79);
+@X=("%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
+    "%f8", "%f9","%f10","%f11","%f12","%f13","%f14","%f15","%f16");
+
+# This is reference 2x-parallelized VIS-powered Xupdate procedure. It
+# covers even K_NN_MM addition...
+sub Xupdate {
+my ($i)=@_;
+my $K=@VK[($i+16)/20];
+my $j=($i+16)%16;
+
+#	[ provided that GSR.alignaddr_offset is 5, $mul contains
+#	  0x100ULL<<32|0x100 value and K_NN_MM are pre-loaded to
+#	  chosen registers... ]
+$code.=<<___;
+	fxors		@X[($j+13)%16],@X[$j],@X[$j]	!-1/-1/-1:X[0]^=X[13]
+	fxors		@X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
+	fxor		@X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
+	fxor		%f18,@X[$j],@X[$j]		! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
+	faligndata	@X[$j],@X[$j],%f18		! 3/ 7/ 5:Tmp=X[0,1]>>>24
+	fpadd32		@X[$j],@X[$j],@X[$j]		! 4/ 8/ 6:X[0,1]<<=1
+	fmul8ulx16	%f18,$fmul,%f18			! 5/10/ 7:Tmp>>=7, Tmp&=1
+	![fxors		%f15,%f2,%f2]
+	for		%f18,@X[$j],@X[$j]		! 8/14/10:X[0,1]|=Tmp
+	![fxors		%f0,%f3,%f3]			!10/17/12:X[0] dependency
+	fpadd32		$K,@X[$j],%f20
+	std		%f20,[$Xfer+`4*$j`]
+___
+# The numbers delimited with slash are the earliest possible dispatch
+# cycles for given instruction assuming 1 cycle latency for simple VIS
+# instructions, such as on UltraSPARC-I&II, 3 cycles latency, such as
+# on UltraSPARC-III&IV, and 2 cycles latency(*), respectively. Being
+# 2x-parallelized the procedure is "worth" 5, 8.5 or 6 ticks per SHA1
+# round. As [long as] FPU/VIS instructions are perfectly pairable with
+# IALU ones, the round timing is defined by the maximum between VIS
+# and IALU timings. The latter varies from round to round and averages
+# out at 6.25 ticks. This means that USI&II should operate at IALU
+# rate, while USIII&IV - at VIS rate. This explains why performance
+# improvement varies among processors. Well, given that pure IALU
+# sha1-sparcv9.pl module exhibits virtually uniform performance of
+# ~9.3 cycles per SHA1 round. Timings mentioned above are theoretical
+# lower limits. Real-life performance was measured to be 6.6 cycles
+# per SHA1 round on USIIi and 8.3 on USIII. The latter is lower than
+# half-round VIS timing, because there are 16 Xupdate-free rounds,
+# which "push down" average theoretical timing to 8 cycles...
+
+# (*)	SPARC64-V[II] was originally believed to have 2 cycles VIS
+#	latency. Well, it might have, but it doesn't have dedicated
+#	VIS-unit. Instead, VIS instructions are executed by other
+#	functional units, ones used here - by IALU. This doesn't
+#	improve effective ILP...
+}
+
+# The reference Xupdate procedure is then "strained" over *pairs* of
+# BODY_NN_MM and kind of modulo-scheduled in respect to X[n]^=X[n+13]
+# and K_NN_MM addition. It's "running" 15 rounds ahead, which leaves
+# plenty of room to amortize for read-after-write hazard, as well as
+# to fetch and align input for the next spin. The VIS instructions are
+# scheduled for latency of 2 cycles, because there are not enough IALU
+# instructions to schedule for latency of 3, while scheduling for 1
+# would give no gain on USI&II anyway.
+
+sub BODY_00_19 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i&~1;
+my $k=($j+16+2)%16;	# ahead reference
+my $l=($j+16-2)%16;	# behind reference
+my $K=@VK[($j+16-2)/20];
+
+$j=($j+16)%16;
+
+$code.=<<___ if (!($i&1));
+	sll		$a,5,$tmp0			!! $i
+	and		$c,$b,$tmp3
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	 fxors		@X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	 fxor		@X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
+	sll		$b,30,$tmp2
+	add		$tmp1,$e,$e
+	andn		$d,$b,$tmp1
+	add		$Xi,$e,$e
+	 fxor		%f18,@X[$j],@X[$j]		! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
+	srl		$b,2,$b
+	or		$tmp1,$tmp3,$tmp1
+	or		$tmp2,$b,$b
+	add		$tmp1,$e,$e
+	 faligndata	@X[$j],@X[$j],%f18		! 3/ 7/ 5:Tmp=X[0,1]>>>24
+___
+$code.=<<___ if ($i&1);
+	sll		$a,5,$tmp0			!! $i
+	and		$c,$b,$tmp3
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	 fpadd32	@X[$j],@X[$j],@X[$j]		! 4/ 8/ 6:X[0,1]<<=1
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	 fmul8ulx16	%f18,$fmul,%f18			! 5/10/ 7:Tmp>>=7, Tmp&=1
+	sll		$b,30,$tmp2
+	add		$tmp1,$e,$e
+	 fpadd32	$K,@X[$l],%f20			!
+	andn		$d,$b,$tmp1
+	add		$Xi,$e,$e
+	 fxors		@X[($k+13)%16],@X[$k],@X[$k]	!-1/-1/-1:X[0]^=X[13]
+	srl		$b,2,$b
+	or		$tmp1,$tmp3,$tmp1
+	 fxor		%f18,@X[$j],@X[$j]		! 8/14/10:X[0,1]|=Tmp
+	or		$tmp2,$b,$b
+	add		$tmp1,$e,$e
+___
+$code.=<<___ if ($i&1 && $i>=2);
+	 std		%f20,[$Xfer+`4*$l`]		!
+___
+}
+
+sub BODY_20_39 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i&~1;
+my $k=($j+16+2)%16;	# ahead reference
+my $l=($j+16-2)%16;	# behind reference
+my $K=@VK[($j+16-2)/20];
+
+$j=($j+16)%16;
+
+$code.=<<___ if (!($i&1) && $i<64);
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	 fxors		@X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	 fxor		@X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
+	xor		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	sll		$b,30,$tmp2
+	xor		$d,$tmp0,$tmp1
+	 fxor		%f18,@X[$j],@X[$j]		! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
+	srl		$b,2,$b
+	add		$tmp1,$e,$e
+	or		$tmp2,$b,$b
+	add		$Xi,$e,$e
+	 faligndata	@X[$j],@X[$j],%f18		! 3/ 7/ 5:Tmp=X[0,1]>>>24
+___
+$code.=<<___ if ($i&1 && $i<64);
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	 fpadd32	@X[$j],@X[$j],@X[$j]		! 4/ 8/ 6:X[0,1]<<=1
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	 fmul8ulx16	%f18,$fmul,%f18			! 5/10/ 7:Tmp>>=7, Tmp&=1
+	xor		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	 fpadd32	$K,@X[$l],%f20			!
+	sll		$b,30,$tmp2
+	xor		$d,$tmp0,$tmp1
+	 fxors		@X[($k+13)%16],@X[$k],@X[$k]	!-1/-1/-1:X[0]^=X[13]
+	srl		$b,2,$b
+	add		$tmp1,$e,$e
+	 fxor		%f18,@X[$j],@X[$j]		! 8/14/10:X[0,1]|=Tmp
+	or		$tmp2,$b,$b
+	add		$Xi,$e,$e
+	 std		%f20,[$Xfer+`4*$l`]		!
+___
+$code.=<<___ if ($i==64);
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	 fpadd32	$K,@X[$l],%f20
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	xor		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	sll		$b,30,$tmp2
+	xor		$d,$tmp0,$tmp1
+	 std		%f20,[$Xfer+`4*$l`]
+	srl		$b,2,$b
+	add		$tmp1,$e,$e
+	or		$tmp2,$b,$b
+	add		$Xi,$e,$e
+___
+$code.=<<___ if ($i>64);
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	xor		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	sll		$b,30,$tmp2
+	xor		$d,$tmp0,$tmp1
+	srl		$b,2,$b
+	add		$tmp1,$e,$e
+	or		$tmp2,$b,$b
+	add		$Xi,$e,$e
+___
+}
+
+sub BODY_40_59 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i&~1;
+my $k=($j+16+2)%16;	# ahead reference
+my $l=($j+16-2)%16;	# behind reference
+my $K=@VK[($j+16-2)/20];
+
+$j=($j+16)%16;
+
+$code.=<<___ if (!($i&1));
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	 fxors		@X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	 fxor		@X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
+	and		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	sll		$b,30,$tmp2
+	or		$c,$b,$tmp1
+	 fxor		%f18,@X[$j],@X[$j]		! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
+	srl		$b,2,$b
+	and		$d,$tmp1,$tmp1
+	add		$Xi,$e,$e
+	or		$tmp1,$tmp0,$tmp1
+	 faligndata	@X[$j],@X[$j],%f18		! 3/ 7/ 5:Tmp=X[0,1]>>>24
+	or		$tmp2,$b,$b
+	add		$tmp1,$e,$e
+	 fpadd32	@X[$j],@X[$j],@X[$j]		! 4/ 8/ 6:X[0,1]<<=1
+___
+$code.=<<___ if ($i&1);
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	 fmul8ulx16	%f18,$fmul,%f18			! 5/10/ 7:Tmp>>=7, Tmp&=1
+	and		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	 fpadd32	$K,@X[$l],%f20			!
+	sll		$b,30,$tmp2
+	or		$c,$b,$tmp1
+	 fxors		@X[($k+13)%16],@X[$k],@X[$k]	!-1/-1/-1:X[0]^=X[13]
+	srl		$b,2,$b
+	and		$d,$tmp1,$tmp1
+	 fxor		%f18,@X[$j],@X[$j]		! 8/14/10:X[0,1]|=Tmp
+	add		$Xi,$e,$e
+	or		$tmp1,$tmp0,$tmp1
+	or		$tmp2,$b,$b
+	add		$tmp1,$e,$e
+	 std		%f20,[$Xfer+`4*$l`]		!
+___
+}
+
+# If there is more data to process, then we pre-fetch the data for
+# next iteration in last ten rounds...
+sub BODY_70_79 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i&~1;
+my $m=($i%8)*2;
+
+$j=($j+16)%16;
+
+$code.=<<___ if ($i==70);
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	 ldd		[$inp+64],@X[0]
+	xor		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	sll		$b,30,$tmp2
+	xor		$d,$tmp0,$tmp1
+	srl		$b,2,$b
+	add		$tmp1,$e,$e
+	or		$tmp2,$b,$b
+	add		$Xi,$e,$e
+
+	and		$inp,-64,$nXfer
+	inc		64,$inp
+	and		$nXfer,255,$nXfer
+	alignaddr	%g0,$align,%g0
+	add		$base,$nXfer,$nXfer
+___
+$code.=<<___ if ($i==71);
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	xor		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	sll		$b,30,$tmp2
+	xor		$d,$tmp0,$tmp1
+	srl		$b,2,$b
+	add		$tmp1,$e,$e
+	or		$tmp2,$b,$b
+	add		$Xi,$e,$e
+___
+$code.=<<___ if ($i>=72);
+	 faligndata	@X[$m],@X[$m+2],@X[$m]
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	xor		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	 fpadd32	$VK_00_19,@X[$m],%f20
+	sll		$b,30,$tmp2
+	xor		$d,$tmp0,$tmp1
+	srl		$b,2,$b
+	add		$tmp1,$e,$e
+	or		$tmp2,$b,$b
+	add		$Xi,$e,$e
+___
+$code.=<<___ if ($i<77);
+	 ldd		[$inp+`8*($i+1-70)`],@X[2*($i+1-70)]
+___
+$code.=<<___ if ($i==77);	# redundant if $inp was aligned
+	 add		$align,63,$tmp0
+	 and		$tmp0,-8,$tmp0
+	 ldd		[$inp+$tmp0],@X[16]
+___
+$code.=<<___ if ($i>=72);
+	 std		%f20,[$nXfer+`4*$m`]
+___
+}
+
+$code.=<<___;
+.section	".text",#alloc,#execinstr
+
+.align	64
+vis_const:
+.long	0x5a827999,0x5a827999	! K_00_19
+.long	0x6ed9eba1,0x6ed9eba1	! K_20_39
+.long	0x8f1bbcdc,0x8f1bbcdc	! K_40_59
+.long	0xca62c1d6,0xca62c1d6	! K_60_79
+.long	0x00000100,0x00000100
+.align	64
+.type	vis_const,#object
+.size	vis_const,(.-vis_const)
+
+.globl	sha1_block_data_order
+sha1_block_data_order:
+	save	%sp,-$frame,%sp
+	add	%fp,$bias-256,$base
+
+1:	call	.+8
+	add	%o7,vis_const-1b,$tmp0
+
+	ldd	[$tmp0+0],$VK_00_19
+	ldd	[$tmp0+8],$VK_20_39
+	ldd	[$tmp0+16],$VK_40_59
+	ldd	[$tmp0+24],$VK_60_79
+	ldd	[$tmp0+32],$fmul
+
+	ld	[$ctx+0],$Actx
+	and	$base,-256,$base
+	ld	[$ctx+4],$Bctx
+	sub	$base,$bias+$frame,%sp
+	ld	[$ctx+8],$Cctx
+	and	$inp,7,$align
+	ld	[$ctx+12],$Dctx
+	and	$inp,-8,$inp
+	ld	[$ctx+16],$Ectx
+
+	! X[16] is maintained in FP register bank
+	alignaddr	%g0,$align,%g0
+	ldd		[$inp+0],@X[0]
+	sub		$inp,-64,$Xfer
+	ldd		[$inp+8],@X[2]
+	and		$Xfer,-64,$Xfer
+	ldd		[$inp+16],@X[4]
+	and		$Xfer,255,$Xfer
+	ldd		[$inp+24],@X[6]
+	add		$base,$Xfer,$Xfer
+	ldd		[$inp+32],@X[8]
+	ldd		[$inp+40],@X[10]
+	ldd		[$inp+48],@X[12]
+	brz,pt		$align,.Laligned
+	ldd		[$inp+56],@X[14]
+
+	ldd		[$inp+64],@X[16]
+	faligndata	@X[0],@X[2],@X[0]
+	faligndata	@X[2],@X[4],@X[2]
+	faligndata	@X[4],@X[6],@X[4]
+	faligndata	@X[6],@X[8],@X[6]
+	faligndata	@X[8],@X[10],@X[8]
+	faligndata	@X[10],@X[12],@X[10]
+	faligndata	@X[12],@X[14],@X[12]
+	faligndata	@X[14],@X[16],@X[14]
+
+.Laligned:
+	mov		5,$tmp0
+	dec		1,$len
+	alignaddr	%g0,$tmp0,%g0
+	fpadd32		$VK_00_19,@X[0],%f16
+	fpadd32		$VK_00_19,@X[2],%f18
+	fpadd32		$VK_00_19,@X[4],%f20
+	fpadd32		$VK_00_19,@X[6],%f22
+	fpadd32		$VK_00_19,@X[8],%f24
+	fpadd32		$VK_00_19,@X[10],%f26
+	fpadd32		$VK_00_19,@X[12],%f28
+	fpadd32		$VK_00_19,@X[14],%f30
+	std		%f16,[$Xfer+0]
+	mov		$Actx,$A
+	std		%f18,[$Xfer+8]
+	mov		$Bctx,$B
+	std		%f20,[$Xfer+16]
+	mov		$Cctx,$C
+	std		%f22,[$Xfer+24]
+	mov		$Dctx,$D
+	std		%f24,[$Xfer+32]
+	mov		$Ectx,$E
+	std		%f26,[$Xfer+40]
+	fxors		@X[13],@X[0],@X[0]
+	std		%f28,[$Xfer+48]
+	ba		.Loop
+	std		%f30,[$Xfer+56]
+.align	32
+.Loop:
+___
+for ($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
+for (;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+for (;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
+for (;$i<70;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+	tst		$len
+	bz,pn		`$bits==32?"%icc":"%xcc"`,.Ltail
+	nop
+___
+for (;$i<80;$i++)	{ &BODY_70_79($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+	add		$A,$Actx,$Actx
+	add		$B,$Bctx,$Bctx
+	add		$C,$Cctx,$Cctx
+	add		$D,$Dctx,$Dctx
+	add		$E,$Ectx,$Ectx
+	mov		5,$tmp0
+	fxors		@X[13],@X[0],@X[0]
+	mov		$Actx,$A
+	mov		$Bctx,$B
+	mov		$Cctx,$C
+	mov		$Dctx,$D
+	mov		$Ectx,$E
+	alignaddr	%g0,$tmp0,%g0	
+	dec		1,$len
+	ba		.Loop
+	mov		$nXfer,$Xfer
+
+.align	32
+.Ltail:
+___
+for($i=70;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+	add	$A,$Actx,$Actx
+	add	$B,$Bctx,$Bctx
+	add	$C,$Cctx,$Cctx
+	add	$D,$Dctx,$Dctx
+	add	$E,$Ectx,$Ectx
+
+	st	$Actx,[$ctx+0]
+	st	$Bctx,[$ctx+4]
+	st	$Cctx,[$ctx+8]
+	st	$Dctx,[$ctx+12]
+	st	$Ectx,[$ctx+16]
+
+	ret
+	restore
+.type	sha1_block_data_order,#function
+.size	sha1_block_data_order,(.-sha1_block_data_order)
+.asciz	"SHA1 block transform for SPARCv9a, CRYPTOGAMS by <appro\@openssl.org>"
+.align	4
+___
+
+# Purpose of these subroutines is to explicitly encode VIS instructions,
+# so that one can compile the module without having to specify VIS
+# extentions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
+# Idea is to reserve for option to produce "universal" binary and let
+# programmer detect if current CPU is VIS capable at run-time.
+sub unvis {
+my ($mnemonic,$rs1,$rs2,$rd)=@_;
+my $ref,$opf;
+my %visopf = (	"fmul8ulx16"	=> 0x037,
+		"faligndata"	=> 0x048,
+		"fpadd32"	=> 0x052,
+		"fxor"		=> 0x06c,
+		"fxors"		=> 0x06d	);
+
+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
+
+    if ($opf=$visopf{$mnemonic}) {
+	foreach ($rs1,$rs2,$rd) {
+	    return $ref if (!/%f([0-9]{1,2})/);
+	    $_=$1;
+	    if ($1>=32) {
+		return $ref if ($1&1);
+		# re-encode for upper double register addressing
+		$_=($1|$1>>5)&31;
+	    }
+	}
+
+	return	sprintf ".word\t0x%08x !%s",
+			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
+			$ref;
+    } else {
+	return $ref;
+    }
+}
+sub unalignaddr {
+my ($mnemonic,$rs1,$rs2,$rd)=@_;
+my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
+my $ref="$mnemonic\t$rs1,$rs2,$rd";
+
+    foreach ($rs1,$rs2,$rd) {
+	if (/%([goli])([0-7])/)	{ $_=$bias{$1}+$2; }
+	else			{ return $ref; }
+    }
+    return  sprintf ".word\t0x%08x !%s",
+		    0x81b00300|$rd<<25|$rs1<<14|$rs2,
+		    $ref;
+}
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+$code =~ s/\b(f[^\s]*)\s+(%f[0-9]{1,2}),(%f[0-9]{1,2}),(%f[0-9]{1,2})/
+		&unvis($1,$2,$3,$4)
+	  /gem;
+$code =~ s/\b(alignaddr)\s+(%[goli][0-7]),(%[goli][0-7]),(%[goli][0-7])/
+		&unalignaddr($1,$2,$3,$4)
+	  /gem;
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/sha/asm/sha1-thumb.pl b/openssl/crypto/sha/asm/sha1-thumb.pl
new file mode 100644
index 0000000..7c9ea9b
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha1-thumb.pl
@@ -0,0 +1,259 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# sha1_block for Thumb.
+#
+# January 2007.
+#
+# The code does not present direct interest to OpenSSL, because of low
+# performance. Its purpose is to establish _size_ benchmark. Pretty
+# useless one I must say, because 30% or 88 bytes larger ARMv4 code
+# [avialable on demand] is almost _twice_ as fast. It should also be
+# noted that in-lining of .Lcommon and .Lrotate improves performance
+# by over 40%, while code increases by only 10% or 32 bytes. But once
+# again, the goal was to establish _size_ benchmark, not performance.
+
+$output=shift;
+open STDOUT,">$output";
+
+$inline=0;
+#$cheat_on_binutils=1;
+
+$t0="r0";
+$t1="r1";
+$t2="r2";
+$a="r3";
+$b="r4";
+$c="r5";
+$d="r6";
+$e="r7";
+$K="r8";	# "upper" registers can be used in add/sub and mov insns
+$ctx="r9";
+$inp="r10";
+$len="r11";
+$Xi="r12";
+
+sub common {
+<<___;
+	sub	$t0,#4
+	ldr	$t1,[$t0]
+	add	$e,$K			@ E+=K_xx_xx
+	lsl	$t2,$a,#5
+	add	$t2,$e
+	lsr	$e,$a,#27
+	add	$t2,$e			@ E+=ROR(A,27)
+	add	$t2,$t1			@ E+=X[i]
+___
+}
+sub rotate {
+<<___;
+	mov	$e,$d			@ E=D
+	mov	$d,$c			@ D=C
+	lsl	$c,$b,#30
+	lsr	$b,$b,#2
+	orr	$c,$b			@ C=ROR(B,2)
+	mov	$b,$a			@ B=A
+	add	$a,$t2,$t1		@ A=E+F_xx_xx(B,C,D)
+___
+}
+
+sub BODY_00_19 {
+$code.=$inline?&common():"\tbl	.Lcommon\n";
+$code.=<<___;
+	mov	$t1,$c
+	eor	$t1,$d
+	and	$t1,$b
+	eor	$t1,$d			@ F_00_19(B,C,D)
+___
+$code.=$inline?&rotate():"\tbl	.Lrotate\n";
+}
+
+sub BODY_20_39 {
+$code.=$inline?&common():"\tbl	.Lcommon\n";
+$code.=<<___;
+	mov	$t1,$b
+	eor	$t1,$c
+	eor	$t1,$d			@ F_20_39(B,C,D)
+___
+$code.=$inline?&rotate():"\tbl	.Lrotate\n";
+}
+
+sub BODY_40_59 {
+$code.=$inline?&common():"\tbl	.Lcommon\n";
+$code.=<<___;
+	mov	$t1,$b
+	and	$t1,$c
+	mov	$e,$b
+	orr	$e,$c
+	and	$e,$d
+	orr	$t1,$e			@ F_40_59(B,C,D)
+___
+$code.=$inline?&rotate():"\tbl	.Lrotate\n";
+}
+
+$code=<<___;
+.text
+.code	16
+
+.global	sha1_block_data_order
+.type	sha1_block_data_order,%function
+
+.align	2
+sha1_block_data_order:
+___
+if ($cheat_on_binutils) {
+$code.=<<___;
+.code	32
+	add	r3,pc,#1
+	bx	r3			@ switch to Thumb ISA
+.code	16
+___
+}
+$code.=<<___;
+	push	{r4-r7}
+	mov	r3,r8
+	mov	r4,r9
+	mov	r5,r10
+	mov	r6,r11
+	mov	r7,r12
+	push	{r3-r7,lr}
+	lsl	r2,#6
+	mov	$ctx,r0			@ save context
+	mov	$inp,r1			@ save inp
+	mov	$len,r2			@ save len
+	add	$len,$inp		@ $len to point at inp end
+
+.Lloop:
+	mov	$Xi,sp
+	mov	$t2,sp
+	sub	$t2,#16*4		@ [3]
+.LXload:
+	ldrb	$a,[$t1,#0]		@ $t1 is r1 and holds inp
+	ldrb	$b,[$t1,#1]
+	ldrb	$c,[$t1,#2]
+	ldrb	$d,[$t1,#3]
+	lsl	$a,#24
+	lsl	$b,#16
+	lsl	$c,#8
+	orr	$a,$b
+	orr	$a,$c
+	orr	$a,$d
+	add	$t1,#4
+	push	{$a}
+	cmp	sp,$t2
+	bne	.LXload			@ [+14*16]
+
+	mov	$inp,$t1		@ update $inp
+	sub	$t2,#32*4
+	sub	$t2,#32*4
+	mov	$e,#31			@ [+4]
+.LXupdate:
+	ldr	$a,[sp,#15*4]
+	ldr	$b,[sp,#13*4]
+	ldr	$c,[sp,#7*4]
+	ldr	$d,[sp,#2*4]
+	eor	$a,$b
+	eor	$a,$c
+	eor	$a,$d
+	ror	$a,$e
+	push	{$a}
+	cmp	sp,$t2
+	bne	.LXupdate		@ [+(11+1)*64]
+
+	ldmia	$t0!,{$a,$b,$c,$d,$e}	@ $t0 is r0 and holds ctx
+	mov	$t0,$Xi
+
+	ldr	$t2,.LK_00_19
+	mov	$t1,$t0
+	sub	$t1,#20*4
+	mov	$Xi,$t1
+	mov	$K,$t2			@ [+7+4]
+.L_00_19:
+___
+	&BODY_00_19();
+$code.=<<___;
+	cmp	$Xi,$t0
+	bne	.L_00_19		@ [+(2+9+4+2+8+2)*20]
+
+	ldr	$t2,.LK_20_39
+	mov	$t1,$t0
+	sub	$t1,#20*4
+	mov	$Xi,$t1
+	mov	$K,$t2			@ [+5]
+.L_20_39_or_60_79:
+___
+	&BODY_20_39();
+$code.=<<___;
+	cmp	$Xi,$t0
+	bne	.L_20_39_or_60_79	@ [+(2+9+3+2+8+2)*20*2]
+	cmp	sp,$t0
+	beq	.Ldone			@ [+2]
+
+	ldr	$t2,.LK_40_59
+	mov	$t1,$t0
+	sub	$t1,#20*4
+	mov	$Xi,$t1
+	mov	$K,$t2			@ [+5]
+.L_40_59:
+___
+	&BODY_40_59();
+$code.=<<___;
+	cmp	$Xi,$t0
+	bne	.L_40_59		@ [+(2+9+6+2+8+2)*20]
+
+	ldr	$t2,.LK_60_79
+	mov	$Xi,sp
+	mov	$K,$t2
+	b	.L_20_39_or_60_79	@ [+4]
+.Ldone:
+	mov	$t0,$ctx
+	ldr	$t1,[$t0,#0]
+	ldr	$t2,[$t0,#4]
+	add	$a,$t1
+	ldr	$t1,[$t0,#8]
+	add	$b,$t2
+	ldr	$t2,[$t0,#12]
+	add	$c,$t1
+	ldr	$t1,[$t0,#16]
+	add	$d,$t2
+	add	$e,$t1
+	stmia	$t0!,{$a,$b,$c,$d,$e}	@ [+20]
+
+	add	sp,#80*4		@ deallocate stack frame
+	mov	$t0,$ctx		@ restore ctx
+	mov	$t1,$inp		@ restore inp
+	cmp	$t1,$len
+	beq	.Lexit
+	b	.Lloop			@ [+6] total 3212 cycles
+.Lexit:
+	pop	{r2-r7}
+	mov	r8,r2
+	mov	r9,r3
+	mov	r10,r4
+	mov	r11,r5
+	mov	r12,r6
+	mov	lr,r7
+	pop	{r4-r7}
+	bx	lr
+.align	2
+___
+$code.=".Lcommon:\n".&common()."\tmov	pc,lr\n" if (!$inline);
+$code.=".Lrotate:\n".&rotate()."\tmov	pc,lr\n" if (!$inline);
+$code.=<<___;
+.align	2
+.LK_00_19:	.word	0x5a827999
+.LK_20_39:	.word	0x6ed9eba1
+.LK_40_59:	.word	0x8f1bbcdc
+.LK_60_79:	.word	0xca62c1d6
+.size	sha1_block_data_order,.-sha1_block_data_order
+.asciz	"SHA1 block transform for Thumb, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+print $code;
+close STDOUT; # enforce flush
diff --git a/openssl/crypto/sha/asm/sha1-x86_64.pl b/openssl/crypto/sha/asm/sha1-x86_64.pl
new file mode 100755
index 0000000..4edc5ea
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha1-x86_64.pl
@@ -0,0 +1,351 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# sha1_block procedure for x86_64.
+#
+# It was brought to my attention that on EM64T compiler-generated code
+# was far behind 32-bit assembler implementation. This is unlike on
+# Opteron where compiler-generated code was only 15% behind 32-bit
+# assembler, which originally made it hard to motivate the effort.
+# There was suggestion to mechanically translate 32-bit code, but I
+# dismissed it, reasoning that x86_64 offers enough register bank
+# capacity to fully utilize SHA-1 parallelism. Therefore this fresh
+# implementation:-) However! While 64-bit code does performs better
+# on Opteron, I failed to beat 32-bit assembler on EM64T core. Well,
+# x86_64 does offer larger *addressable* bank, but out-of-order core
+# reaches for even more registers through dynamic aliasing, and EM64T
+# core must have managed to run-time optimize even 32-bit code just as
+# good as 64-bit one. Performance improvement is summarized in the
+# following table:
+#
+#		gcc 3.4		32-bit asm	cycles/byte
+# Opteron	+45%		+20%		6.8
+# Xeon P4	+65%		+0%		9.9
+# Core2		+60%		+10%		7.0
+
+$flavour = shift;
+$output  = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour $output";
+
+$ctx="%rdi";	# 1st arg
+$inp="%rsi";	# 2nd arg
+$num="%rdx";	# 3rd arg
+
+# reassign arguments in order to produce more compact code
+$ctx="%r8";
+$inp="%r9";
+$num="%r10";
+
+$xi="%eax";
+$t0="%ebx";
+$t1="%ecx";
+$A="%edx";
+$B="%esi";
+$C="%edi";
+$D="%ebp";
+$E="%r11d";
+$T="%r12d";
+
+@V=($A,$B,$C,$D,$E,$T);
+
+sub PROLOGUE {
+my $func=shift;
+$code.=<<___;
+.globl	$func
+.type	$func,\@function,3
+.align	16
+$func:
+	push	%rbx
+	push	%rbp
+	push	%r12
+	mov	%rsp,%r11
+	mov	%rdi,$ctx	# reassigned argument
+	sub	\$`8+16*4`,%rsp
+	mov	%rsi,$inp	# reassigned argument
+	and	\$-64,%rsp
+	mov	%rdx,$num	# reassigned argument
+	mov	%r11,`16*4`(%rsp)
+.Lprologue:
+
+	mov	0($ctx),$A
+	mov	4($ctx),$B
+	mov	8($ctx),$C
+	mov	12($ctx),$D
+	mov	16($ctx),$E
+___
+}
+
+sub EPILOGUE {
+my $func=shift;
+$code.=<<___;
+	mov	`16*4`(%rsp),%rsi
+	mov	(%rsi),%r12
+	mov	8(%rsi),%rbp
+	mov	16(%rsi),%rbx
+	lea	24(%rsi),%rsp
+.Lepilogue:
+	ret
+.size	$func,.-$func
+___
+}
+
+sub BODY_00_19 {
+my ($i,$a,$b,$c,$d,$e,$f,$host)=@_;
+my $j=$i+1;
+$code.=<<___ if ($i==0);
+	mov	`4*$i`($inp),$xi	
+	`"bswap	$xi"	if(!defined($host))`
+	mov	$xi,`4*$i`(%rsp)
+___
+$code.=<<___ if ($i<15);
+	lea	0x5a827999($xi,$e),$f
+	mov	$c,$t0
+	mov	`4*$j`($inp),$xi
+	mov	$a,$e
+	xor	$d,$t0
+	`"bswap	$xi"	if(!defined($host))`	
+	rol	\$5,$e
+	and	$b,$t0
+	mov	$xi,`4*$j`(%rsp)
+	add	$e,$f
+	xor	$d,$t0
+	rol	\$30,$b
+	add	$t0,$f
+___
+$code.=<<___ if ($i>=15);
+	lea	0x5a827999($xi,$e),$f
+	mov	`4*($j%16)`(%rsp),$xi
+	mov	$c,$t0
+	mov	$a,$e
+	xor	`4*(($j+2)%16)`(%rsp),$xi
+	xor	$d,$t0
+	rol	\$5,$e
+	xor	`4*(($j+8)%16)`(%rsp),$xi
+	and	$b,$t0
+	add	$e,$f
+	xor	`4*(($j+13)%16)`(%rsp),$xi
+	xor	$d,$t0
+	rol	\$30,$b
+	add	$t0,$f
+	rol	\$1,$xi
+	mov	$xi,`4*($j%16)`(%rsp)
+___
+}
+
+sub BODY_20_39 {
+my ($i,$a,$b,$c,$d,$e,$f)=@_;
+my $j=$i+1;
+my $K=($i<40)?0x6ed9eba1:0xca62c1d6;
+$code.=<<___ if ($i<79);
+	lea	$K($xi,$e),$f
+	mov	`4*($j%16)`(%rsp),$xi
+	mov	$c,$t0
+	mov	$a,$e
+	xor	`4*(($j+2)%16)`(%rsp),$xi
+	xor	$b,$t0
+	rol	\$5,$e
+	xor	`4*(($j+8)%16)`(%rsp),$xi
+	xor	$d,$t0
+	add	$e,$f
+	xor	`4*(($j+13)%16)`(%rsp),$xi
+	rol	\$30,$b
+	add	$t0,$f
+	rol	\$1,$xi
+___
+$code.=<<___ if ($i<76);
+	mov	$xi,`4*($j%16)`(%rsp)
+___
+$code.=<<___ if ($i==79);
+	lea	$K($xi,$e),$f
+	mov	$c,$t0
+	mov	$a,$e
+	xor	$b,$t0
+	rol	\$5,$e
+	xor	$d,$t0
+	add	$e,$f
+	rol	\$30,$b
+	add	$t0,$f
+___
+}
+
+sub BODY_40_59 {
+my ($i,$a,$b,$c,$d,$e,$f)=@_;
+my $j=$i+1;
+$code.=<<___;
+	lea	0x8f1bbcdc($xi,$e),$f
+	mov	`4*($j%16)`(%rsp),$xi
+	mov	$b,$t0
+	mov	$b,$t1
+	xor	`4*(($j+2)%16)`(%rsp),$xi
+	mov	$a,$e
+	and	$c,$t0
+	xor	`4*(($j+8)%16)`(%rsp),$xi
+	or	$c,$t1
+	rol	\$5,$e
+	xor	`4*(($j+13)%16)`(%rsp),$xi
+	and	$d,$t1
+	add	$e,$f
+	rol	\$1,$xi
+	or	$t1,$t0
+	rol	\$30,$b
+	mov	$xi,`4*($j%16)`(%rsp)
+	add	$t0,$f
+___
+}
+
+$code=".text\n";
+
+&PROLOGUE("sha1_block_data_order");
+$code.=".align	4\n.Lloop:\n";
+for($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
+for(;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+for(;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
+for(;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+	add	0($ctx),$E
+	add	4($ctx),$T
+	add	8($ctx),$A
+	add	12($ctx),$B
+	add	16($ctx),$C
+	mov	$E,0($ctx)
+	mov	$T,4($ctx)
+	mov	$A,8($ctx)
+	mov	$B,12($ctx)
+	mov	$C,16($ctx)
+
+	xchg	$E,$A	# mov	$E,$A
+	xchg	$T,$B	# mov	$T,$B
+	xchg	$E,$C	# mov	$A,$C
+	xchg	$T,$D	# mov	$B,$D
+			# mov	$C,$E
+	lea	`16*4`($inp),$inp
+	sub	\$1,$num
+	jnz	.Lloop
+___
+&EPILOGUE("sha1_block_data_order");
+$code.=<<___;
+.asciz	"SHA1 block transform for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
+.align	16
+___
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern	__imp_RtlVirtualUnwind
+.type	se_handler,\@abi-omnipotent
+.align	16
+se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	lea	.Lprologue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lprologue
+	jb	.Lin_prologue
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	lea	.Lepilogue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
+	jae	.Lin_prologue
+
+	mov	`16*4`(%rax),%rax	# pull saved stack pointer
+	lea	24(%rax),%rax
+
+	mov	-8(%rax),%rbx
+	mov	-16(%rax),%rbp
+	mov	-24(%rax),%r12
+	mov	%rbx,144($context)	# restore context->Rbx
+	mov	%rbp,160($context)	# restore context->Rbp
+	mov	%r12,216($context)	# restore context->R12
+
+.Lin_prologue:
+	mov	8(%rax),%rdi
+	mov	16(%rax),%rsi
+	mov	%rax,152($context)	# restore context->Rsp
+	mov	%rsi,168($context)	# restore context->Rsi
+	mov	%rdi,176($context)	# restore context->Rdi
+
+	mov	40($disp),%rdi		# disp->ContextRecord
+	mov	$context,%rsi		# context
+	mov	\$154,%ecx		# sizeof(CONTEXT)
+	.long	0xa548f3fc		# cld; rep movsq
+
+	mov	$disp,%rsi
+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
+	mov	40(%rsi),%r10		# disp->ContextRecord
+	lea	56(%rsi),%r11		# &disp->HandlerData
+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
+	mov	%r10,32(%rsp)		# arg5
+	mov	%r11,40(%rsp)		# arg6
+	mov	%r12,48(%rsp)		# arg7
+	mov	%rcx,56(%rsp)		# arg8, (NULL)
+	call	*__imp_RtlVirtualUnwind(%rip)
+
+	mov	\$1,%eax		# ExceptionContinueSearch
+	add	\$64,%rsp
+	popfq
+	pop	%r15
+	pop	%r14
+	pop	%r13
+	pop	%r12
+	pop	%rbp
+	pop	%rbx
+	pop	%rdi
+	pop	%rsi
+	ret
+.size	se_handler,.-se_handler
+
+.section	.pdata
+.align	4
+	.rva	.LSEH_begin_sha1_block_data_order
+	.rva	.LSEH_end_sha1_block_data_order
+	.rva	.LSEH_info_sha1_block_data_order
+
+.section	.xdata
+.align	8
+.LSEH_info_sha1_block_data_order:
+	.byte	9,0,0,0
+	.rva	se_handler
+___
+}
+
+####################################################################
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/sha/asm/sha256-586.pl b/openssl/crypto/sha/asm/sha256-586.pl
new file mode 100644
index 0000000..ecc8b69
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha256-586.pl
@@ -0,0 +1,251 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# SHA256 block transform for x86. September 2007.
+#
+# Performance in clock cycles per processed byte (less is better):
+#
+#		Pentium	PIII	P4	AMD K8	Core2
+# gcc		46	36	41	27	26
+# icc		57	33	38	25	23	
+# x86 asm	40	30	35	20	20
+# x86_64 asm(*)	-	-	21	15.8	16.5
+#
+# (*) x86_64 assembler performance is presented for reference
+#     purposes.
+#
+# Performance improvement over compiler generated code varies from
+# 10% to 40% [see above]. Not very impressive on some µ-archs, but
+# it's 5 times smaller and optimizies amount of writes.
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"sha512-586.pl",$ARGV[$#ARGV] eq "386");
+
+$A="eax";
+$E="edx";
+$T="ebx";
+$Aoff=&DWP(0,"esp");
+$Boff=&DWP(4,"esp");
+$Coff=&DWP(8,"esp");
+$Doff=&DWP(12,"esp");
+$Eoff=&DWP(16,"esp");
+$Foff=&DWP(20,"esp");
+$Goff=&DWP(24,"esp");
+$Hoff=&DWP(28,"esp");
+$Xoff=&DWP(32,"esp");
+$K256="ebp";
+
+sub BODY_00_15() {
+    my $in_16_63=shift;
+
+	&mov	("ecx",$E);
+	 &add	($T,&DWP(4*(8+15+16-9),"esp"))	if ($in_16_63);	# T += X[-7]
+	&ror	("ecx",6);
+	&mov	("edi",$E);
+	&ror	("edi",11);
+	 &mov	("esi",$Foff);
+	&xor	("ecx","edi");
+	&ror	("edi",25-11);
+	 &mov	(&DWP(4*(8+15),"esp"),$T)	if ($in_16_63);	# save X[0]
+	&xor	("ecx","edi");	# Sigma1(e)
+	 &mov	("edi",$Goff);
+	&add	($T,"ecx");	# T += Sigma1(e)
+	 &mov	($Eoff,$E);	# modulo-scheduled
+
+	&xor	("esi","edi");
+	 &mov	("ecx",$A);
+	&and	("esi",$E);
+	 &mov	($E,$Doff);	# e becomes d, which is e in next iteration
+	&xor	("esi","edi");	# Ch(e,f,g)
+	 &mov	("edi",$A);
+	&add	($T,"esi");	# T += Ch(e,f,g)
+
+	&ror	("ecx",2);
+	 &add	($T,$Hoff);	# T += h
+	&ror	("edi",13);
+	 &mov	("esi",$Boff);
+	&xor	("ecx","edi");
+	&ror	("edi",22-13);
+	 &add	($E,$T);	# d += T
+	&xor	("ecx","edi");	# Sigma0(a)
+	 &mov	("edi",$Coff);
+
+	&add	($T,"ecx");	# T += Sigma0(a)
+	 &mov	($Aoff,$A);	# modulo-scheduled
+
+	&mov	("ecx",$A);
+	 &sub	("esp",4);
+	&or	($A,"esi");	# a becomes h, which is a in next iteration
+	&and	("ecx","esi");
+	&and	($A,"edi");
+	 &mov	("esi",&DWP(0,$K256));
+	&or	($A,"ecx");	# h=Maj(a,b,c)
+
+	&add	($K256,4);
+	&add	($A,$T);	# h += T
+	 &mov	($T,&DWP(4*(8+15+16-1),"esp"))	if ($in_16_63);	# preload T
+	&add	($E,"esi");	# d += K256[i]
+	&add	($A,"esi");	# h += K256[i]
+}
+
+&function_begin("sha256_block_data_order");
+	&mov	("esi",wparam(0));	# ctx
+	&mov	("edi",wparam(1));	# inp
+	&mov	("eax",wparam(2));	# num
+	&mov	("ebx","esp");		# saved sp
+
+	&call	(&label("pic_point"));	# make it PIC!
+&set_label("pic_point");
+	&blindpop($K256);
+	&lea	($K256,&DWP(&label("K256")."-".&label("pic_point"),$K256));
+
+	&sub	("esp",16);
+	&and	("esp",-64);
+
+	&shl	("eax",6);
+	&add	("eax","edi");
+	&mov	(&DWP(0,"esp"),"esi");	# ctx
+	&mov	(&DWP(4,"esp"),"edi");	# inp
+	&mov	(&DWP(8,"esp"),"eax");	# inp+num*128
+	&mov	(&DWP(12,"esp"),"ebx");	# saved sp
+
+&set_label("loop",16);
+    # copy input block to stack reversing byte and dword order
+    for($i=0;$i<4;$i++) {
+	&mov	("eax",&DWP($i*16+0,"edi"));
+	&mov	("ebx",&DWP($i*16+4,"edi"));
+	&mov	("ecx",&DWP($i*16+8,"edi"));
+	&mov	("edx",&DWP($i*16+12,"edi"));
+	&bswap	("eax");
+	&bswap	("ebx");
+	&bswap	("ecx");
+	&bswap	("edx");
+	&push	("eax");
+	&push	("ebx");
+	&push	("ecx");
+	&push	("edx");
+    }
+	&add	("edi",64);
+	&sub	("esp",4*8);		# place for A,B,C,D,E,F,G,H
+	&mov	(&DWP(4*(8+16)+4,"esp"),"edi");
+
+	# copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack
+	&mov	($A,&DWP(0,"esi"));
+	&mov	("ebx",&DWP(4,"esi"));
+	&mov	("ecx",&DWP(8,"esi"));
+	&mov	("edi",&DWP(12,"esi"));
+	# &mov	($Aoff,$A);
+	&mov	($Boff,"ebx");
+	&mov	($Coff,"ecx");
+	&mov	($Doff,"edi");
+	&mov	($E,&DWP(16,"esi"));	
+	&mov	("ebx",&DWP(20,"esi"));
+	&mov	("ecx",&DWP(24,"esi"));
+	&mov	("edi",&DWP(28,"esi"));
+	# &mov	($Eoff,$E);
+	&mov	($Foff,"ebx");
+	&mov	($Goff,"ecx");
+	&mov	($Hoff,"edi");
+
+&set_label("00_15",16);
+	&mov	($T,&DWP(4*(8+15),"esp"));
+
+	&BODY_00_15();
+
+	&cmp	("esi",0xc19bf174);
+	&jne	(&label("00_15"));
+
+	&mov	($T,&DWP(4*(8+15+16-1),"esp"));	# preloaded in BODY_00_15(1)
+&set_label("16_63",16);
+	&mov	("esi",$T);
+	 &mov	("ecx",&DWP(4*(8+15+16-14),"esp"));
+	&shr	($T,3);
+	&ror	("esi",7);
+	&xor	($T,"esi");
+	&ror	("esi",18-7);
+	 &mov	("edi","ecx");
+	&xor	($T,"esi");			# T = sigma0(X[-15])
+
+	&shr	("ecx",10);
+	 &mov	("esi",&DWP(4*(8+15+16),"esp"));
+	&ror	("edi",17);
+	&xor	("ecx","edi");
+	&ror	("edi",19-17);
+	 &add	($T,"esi");			# T += X[-16]
+	&xor	("edi","ecx")			# sigma1(X[-2])
+
+	&add	($T,"edi");			# T += sigma1(X[-2])
+	# &add	($T,&DWP(4*(8+15+16-9),"esp"));	# T += X[-7], moved to BODY_00_15(1)
+	# &mov	(&DWP(4*(8+15),"esp"),$T);	# save X[0]
+
+	&BODY_00_15(1);
+
+	&cmp	("esi",0xc67178f2);
+	&jne	(&label("16_63"));
+
+	&mov	("esi",&DWP(4*(8+16+64)+0,"esp"));#ctx
+	# &mov	($A,$Aoff);
+	&mov	("ebx",$Boff);
+	&mov	("ecx",$Coff);
+	&mov	("edi",$Doff);
+	&add	($A,&DWP(0,"esi"));
+	&add	("ebx",&DWP(4,"esi"));
+	&add	("ecx",&DWP(8,"esi"));
+	&add	("edi",&DWP(12,"esi"));
+	&mov	(&DWP(0,"esi"),$A);
+	&mov	(&DWP(4,"esi"),"ebx");
+	&mov	(&DWP(8,"esi"),"ecx");
+	&mov	(&DWP(12,"esi"),"edi");
+	# &mov	($E,$Eoff);
+	&mov	("eax",$Foff);
+	&mov	("ebx",$Goff);
+	&mov	("ecx",$Hoff);
+	&mov	("edi",&DWP(4*(8+16+64)+4,"esp"));#inp
+	&add	($E,&DWP(16,"esi"));
+	&add	("eax",&DWP(20,"esi"));
+	&add	("ebx",&DWP(24,"esi"));
+	&add	("ecx",&DWP(28,"esi"));
+	&mov	(&DWP(16,"esi"),$E);
+	&mov	(&DWP(20,"esi"),"eax");
+	&mov	(&DWP(24,"esi"),"ebx");
+	&mov	(&DWP(28,"esi"),"ecx");
+
+	&add	("esp",4*(8+16+64));		# destroy frame
+	&sub	($K256,4*64);			# rewind K
+
+	&cmp	("edi",&DWP(8,"esp"));		# are we done yet?
+	&jb	(&label("loop"));
+
+	&mov	("esp",&DWP(12,"esp"));		# restore sp
+&function_end_A();
+
+&set_label("K256",64);	# Yes! I keep it in the code segment!
+	&data_word(0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5);
+	&data_word(0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5);
+	&data_word(0xd807aa98,0x12835b01,0x243185be,0x550c7dc3);
+	&data_word(0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174);
+	&data_word(0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc);
+	&data_word(0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da);
+	&data_word(0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7);
+	&data_word(0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967);
+	&data_word(0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13);
+	&data_word(0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85);
+	&data_word(0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3);
+	&data_word(0xd192e819,0xd6990624,0xf40e3585,0x106aa070);
+	&data_word(0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5);
+	&data_word(0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3);
+	&data_word(0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208);
+	&data_word(0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2);
+&function_end_B("sha256_block_data_order");
+&asciz("SHA256 block transform for x86, CRYPTOGAMS by <appro\@openssl.org>");
+
+&asm_finish();
diff --git a/openssl/crypto/sha/asm/sha256-armv4.pl b/openssl/crypto/sha/asm/sha256-armv4.pl
new file mode 100644
index 0000000..492cb62
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha256-armv4.pl
@@ -0,0 +1,186 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# SHA256 block procedure for ARMv4. May 2007.
+
+# Performance is ~2x better than gcc 3.4 generated code and in "abso-
+# lute" terms is ~2250 cycles per 64-byte block or ~35 cycles per
+# byte [on single-issue Xscale PXA250 core].
+
+# July 2010.
+#
+# Rescheduling for dual-issue pipeline resulted in 22% improvement on
+# Cortex A8 core and ~20 cycles per processed byte.
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
+$ctx="r0";	$t0="r0";
+$inp="r1";
+$len="r2";	$t1="r2";
+$T1="r3";
+$A="r4";
+$B="r5";
+$C="r6";
+$D="r7";
+$E="r8";
+$F="r9";
+$G="r10";
+$H="r11";
+@V=($A,$B,$C,$D,$E,$F,$G,$H);
+$t2="r12";
+$Ktbl="r14";
+
+@Sigma0=( 2,13,22);
+@Sigma1=( 6,11,25);
+@sigma0=( 7,18, 3);
+@sigma1=(17,19,10);
+
+sub BODY_00_15 {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
+
+$code.=<<___ if ($i<16);
+	ldrb	$T1,[$inp,#3]			@ $i
+	ldrb	$t2,[$inp,#2]
+	ldrb	$t1,[$inp,#1]
+	ldrb	$t0,[$inp],#4
+	orr	$T1,$T1,$t2,lsl#8
+	orr	$T1,$T1,$t1,lsl#16
+	orr	$T1,$T1,$t0,lsl#24
+	`"str	$inp,[sp,#17*4]"	if ($i==15)`
+___
+$code.=<<___;
+	ldr	$t2,[$Ktbl],#4			@ *K256++
+	mov	$t0,$e,ror#$Sigma1[0]
+	str	$T1,[sp,#`$i%16`*4]
+	eor	$t0,$t0,$e,ror#$Sigma1[1]
+	eor	$t1,$f,$g
+	eor	$t0,$t0,$e,ror#$Sigma1[2]	@ Sigma1(e)
+	and	$t1,$t1,$e
+	add	$T1,$T1,$t0
+	eor	$t1,$t1,$g			@ Ch(e,f,g)
+	add	$T1,$T1,$h
+	mov	$h,$a,ror#$Sigma0[0]
+	add	$T1,$T1,$t1
+	eor	$h,$h,$a,ror#$Sigma0[1]
+	add	$T1,$T1,$t2
+	eor	$h,$h,$a,ror#$Sigma0[2]		@ Sigma0(a)
+	orr	$t0,$a,$b
+	and	$t1,$a,$b
+	and	$t0,$t0,$c
+	add	$h,$h,$T1
+	orr	$t0,$t0,$t1			@ Maj(a,b,c)
+	add	$d,$d,$T1
+	add	$h,$h,$t0
+___
+}
+
+sub BODY_16_XX {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
+
+$code.=<<___;
+	ldr	$t1,[sp,#`($i+1)%16`*4]		@ $i
+	ldr	$t2,[sp,#`($i+14)%16`*4]
+	ldr	$T1,[sp,#`($i+0)%16`*4]
+	mov	$t0,$t1,ror#$sigma0[0]
+	ldr	$inp,[sp,#`($i+9)%16`*4]
+	eor	$t0,$t0,$t1,ror#$sigma0[1]
+	eor	$t0,$t0,$t1,lsr#$sigma0[2]	@ sigma0(X[i+1])
+	mov	$t1,$t2,ror#$sigma1[0]
+	add	$T1,$T1,$t0
+	eor	$t1,$t1,$t2,ror#$sigma1[1]
+	add	$T1,$T1,$inp
+	eor	$t1,$t1,$t2,lsr#$sigma1[2]	@ sigma1(X[i+14])
+	add	$T1,$T1,$t1
+___
+	&BODY_00_15(@_);
+}
+
+$code=<<___;
+.text
+.code	32
+
+.type	K256,%object
+.align	5
+K256:
+.word	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+.word	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+.word	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+.word	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+.word	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+.word	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+.word	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+.word	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+.word	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+.word	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+.word	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+.word	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+.word	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+.word	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+.word	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+.word	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+.size	K256,.-K256
+
+.global	sha256_block_data_order
+.type	sha256_block_data_order,%function
+sha256_block_data_order:
+	sub	r3,pc,#8		@ sha256_block_data_order
+	add	$len,$inp,$len,lsl#6	@ len to point at the end of inp
+	stmdb	sp!,{$ctx,$inp,$len,r4-r12,lr}
+	ldmia	$ctx,{$A,$B,$C,$D,$E,$F,$G,$H}
+	sub	$Ktbl,r3,#256		@ K256
+	sub	sp,sp,#16*4		@ alloca(X[16])
+.Loop:
+___
+for($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
+$code.=".Lrounds_16_xx:\n";
+for (;$i<32;$i++)	{ &BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+	and	$t2,$t2,#0xff
+	cmp	$t2,#0xf2
+	bne	.Lrounds_16_xx
+
+	ldr	$T1,[sp,#16*4]		@ pull ctx
+	ldr	$t0,[$T1,#0]
+	ldr	$t1,[$T1,#4]
+	ldr	$t2,[$T1,#8]
+	add	$A,$A,$t0
+	ldr	$t0,[$T1,#12]
+	add	$B,$B,$t1
+	ldr	$t1,[$T1,#16]
+	add	$C,$C,$t2
+	ldr	$t2,[$T1,#20]
+	add	$D,$D,$t0
+	ldr	$t0,[$T1,#24]
+	add	$E,$E,$t1
+	ldr	$t1,[$T1,#28]
+	add	$F,$F,$t2
+	ldr	$inp,[sp,#17*4]		@ pull inp
+	ldr	$t2,[sp,#18*4]		@ pull inp+len
+	add	$G,$G,$t0
+	add	$H,$H,$t1
+	stmia	$T1,{$A,$B,$C,$D,$E,$F,$G,$H}
+	cmp	$inp,$t2
+	sub	$Ktbl,$Ktbl,#256	@ rewind Ktbl
+	bne	.Loop
+
+	add	sp,sp,#`16+3`*4	@ destroy frame
+	ldmia	sp!,{r4-r12,lr}
+	tst	lr,#1
+	moveq	pc,lr			@ be binary compatible with V4, yet
+	bx	lr			@ interoperable with Thumb ISA:-)
+.size   sha256_block_data_order,.-sha256_block_data_order
+.asciz  "SHA256 block transform for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
+.align	2
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
+print $code;
+close STDOUT; # enforce flush
diff --git a/openssl/crypto/sha/asm/sha512-586.pl b/openssl/crypto/sha/asm/sha512-586.pl
new file mode 100644
index 0000000..5b9f333
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha512-586.pl
@@ -0,0 +1,644 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# SHA512 block transform for x86. September 2007.
+#
+# Performance in clock cycles per processed byte (less is better):
+#
+#		Pentium	PIII	P4	AMD K8	Core2
+# gcc		100	75	116	54	66
+# icc		97	77	95	55	57
+# x86 asm	61	56	82	36	40
+# SSE2 asm	-	-	38	24	20
+# x86_64 asm(*)	-	-	30	10.0	10.5
+#
+# (*) x86_64 assembler performance is presented for reference
+#     purposes.
+#
+# IALU code-path is optimized for elder Pentiums. On vanilla Pentium
+# performance improvement over compiler generated code reaches ~60%,
+# while on PIII - ~35%. On newer µ-archs improvement varies from 15%
+# to 50%, but it's less important as they are expected to execute SSE2
+# code-path, which is commonly ~2-3x faster [than compiler generated
+# code]. SSE2 code-path is as fast as original sha512-sse2.pl, even
+# though it does not use 128-bit operations. The latter means that
+# SSE2-aware kernel is no longer required to execute the code. Another
+# difference is that new code optimizes amount of writes, but at the
+# cost of increased data cache "footprint" by 1/2KB.
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"sha512-586.pl",$ARGV[$#ARGV] eq "386");
+
+$sse2=0;
+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
+
+&external_label("OPENSSL_ia32cap_P") if ($sse2);
+
+$Tlo=&DWP(0,"esp");	$Thi=&DWP(4,"esp");
+$Alo=&DWP(8,"esp");	$Ahi=&DWP(8+4,"esp");
+$Blo=&DWP(16,"esp");	$Bhi=&DWP(16+4,"esp");
+$Clo=&DWP(24,"esp");	$Chi=&DWP(24+4,"esp");
+$Dlo=&DWP(32,"esp");	$Dhi=&DWP(32+4,"esp");
+$Elo=&DWP(40,"esp");	$Ehi=&DWP(40+4,"esp");
+$Flo=&DWP(48,"esp");	$Fhi=&DWP(48+4,"esp");
+$Glo=&DWP(56,"esp");	$Ghi=&DWP(56+4,"esp");
+$Hlo=&DWP(64,"esp");	$Hhi=&DWP(64+4,"esp");
+$K512="ebp";
+
+$Asse2=&QWP(0,"esp");
+$Bsse2=&QWP(8,"esp");
+$Csse2=&QWP(16,"esp");
+$Dsse2=&QWP(24,"esp");
+$Esse2=&QWP(32,"esp");
+$Fsse2=&QWP(40,"esp");
+$Gsse2=&QWP(48,"esp");
+$Hsse2=&QWP(56,"esp");
+
+$A="mm0";	# B-D and
+$E="mm4";	# F-H are commonly loaded to respectively mm1-mm3 and
+		# mm5-mm7, but it's done on on-demand basis...
+
+sub BODY_00_15_sse2 {
+    my $prefetch=shift;
+
+	&movq	("mm5",$Fsse2);			# load f
+	&movq	("mm6",$Gsse2);			# load g
+	&movq	("mm7",$Hsse2);			# load h
+
+	&movq	("mm1",$E);			# %mm1 is sliding right
+	&movq	("mm2",$E);			# %mm2 is sliding left
+	&psrlq	("mm1",14);
+	&movq	($Esse2,$E);			# modulo-scheduled save e
+	&psllq	("mm2",23);
+	&movq	("mm3","mm1");			# %mm3 is T1
+	&psrlq	("mm1",4);
+	&pxor	("mm3","mm2");
+	&psllq	("mm2",23);
+	&pxor	("mm3","mm1");
+	&psrlq	("mm1",23);
+	&pxor	("mm3","mm2");
+	&psllq	("mm2",4);
+	&pxor	("mm3","mm1");
+	&paddq	("mm7",QWP(0,$K512));		# h+=K512[i]
+	&pxor	("mm3","mm2");			# T1=Sigma1_512(e)
+
+	&pxor	("mm5","mm6");			# f^=g
+	&movq	("mm1",$Bsse2);			# load b
+	&pand	("mm5",$E);			# f&=e
+	&movq	("mm2",$Csse2);			# load c
+	&pxor	("mm5","mm6");			# f^=g
+	&movq	($E,$Dsse2);			# e = load d
+	&paddq	("mm3","mm5");			# T1+=Ch(e,f,g)
+	&movq	(&QWP(0,"esp"),$A);		# modulo-scheduled save a
+	&paddq	("mm3","mm7");			# T1+=h
+
+	&movq	("mm5",$A);			# %mm5 is sliding right
+	&movq	("mm6",$A);			# %mm6 is sliding left
+	&paddq	("mm3",&QWP(8*9,"esp"));	# T1+=X[0]
+	&psrlq	("mm5",28);
+	&paddq	($E,"mm3");			# e += T1
+	&psllq	("mm6",25);
+	&movq	("mm7","mm5");			# %mm7 is T2
+	&psrlq	("mm5",6);
+	&pxor	("mm7","mm6");
+	&psllq	("mm6",5);
+	&pxor	("mm7","mm5");
+	&psrlq	("mm5",5);
+	&pxor	("mm7","mm6");
+	&psllq	("mm6",6);
+	&pxor	("mm7","mm5");
+	&sub	("esp",8);
+	&pxor	("mm7","mm6");			# T2=Sigma0_512(a)
+
+	&movq	("mm5",$A);			# %mm5=a
+	&por	($A,"mm2");			# a=a|c
+	&movq	("mm6",&QWP(8*(9+16-14),"esp"))	if ($prefetch);
+	&pand	("mm5","mm2");			# %mm5=a&c
+	&pand	($A,"mm1");			# a=(a|c)&b
+	&movq	("mm2",&QWP(8*(9+16-1),"esp"))	if ($prefetch);
+	&por	("mm5",$A);			# %mm5=(a&c)|((a|c)&b)
+	&paddq	("mm7","mm5");			# T2+=Maj(a,b,c)
+	&movq	($A,"mm3");			# a=T1
+
+	&mov	(&LB("edx"),&BP(0,$K512));
+	&paddq	($A,"mm7");			# a+=T2
+	&add	($K512,8);
+}
+
+sub BODY_00_15_x86 {
+	#define Sigma1(x)	(ROTR((x),14) ^ ROTR((x),18)  ^ ROTR((x),41))
+	#	LO		lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23
+	#	HI		hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23
+	&mov	("ecx",$Elo);
+	&mov	("edx",$Ehi);
+	&mov	("esi","ecx");
+
+	&shr	("ecx",9)	# lo>>9
+	&mov	("edi","edx");
+	&shr	("edx",9)	# hi>>9
+	&mov	("ebx","ecx");
+	&shl	("esi",14);	# lo<<14
+	&mov	("eax","edx");
+	&shl	("edi",14);	# hi<<14
+	&xor	("ebx","esi");
+
+	&shr	("ecx",14-9);	# lo>>14
+	&xor	("eax","edi");
+	&shr	("edx",14-9);	# hi>>14
+	&xor	("eax","ecx");
+	&shl	("esi",18-14);	# lo<<18
+	&xor	("ebx","edx");
+	&shl	("edi",18-14);	# hi<<18
+	&xor	("ebx","esi");
+
+	&shr	("ecx",18-14);	# lo>>18
+	&xor	("eax","edi");
+	&shr	("edx",18-14);	# hi>>18
+	&xor	("eax","ecx");
+	&shl	("esi",23-18);	# lo<<23
+	&xor	("ebx","edx");
+	&shl	("edi",23-18);	# hi<<23
+	&xor	("eax","esi");
+	&xor	("ebx","edi");			# T1 = Sigma1(e)
+
+	&mov	("ecx",$Flo);
+	&mov	("edx",$Fhi);
+	&mov	("esi",$Glo);
+	&mov	("edi",$Ghi);
+	 &add	("eax",$Hlo);
+	 &adc	("ebx",$Hhi);			# T1 += h
+	&xor	("ecx","esi");
+	&xor	("edx","edi");
+	&and	("ecx",$Elo);
+	&and	("edx",$Ehi);
+	 &add	("eax",&DWP(8*(9+15)+0,"esp"));
+	 &adc	("ebx",&DWP(8*(9+15)+4,"esp"));	# T1 += X[0]
+	&xor	("ecx","esi");
+	&xor	("edx","edi");			# Ch(e,f,g) = (f^g)&e)^g
+
+	&mov	("esi",&DWP(0,$K512));
+	&mov	("edi",&DWP(4,$K512));		# K[i]
+	&add	("eax","ecx");
+	&adc	("ebx","edx");			# T1 += Ch(e,f,g)
+	&mov	("ecx",$Dlo);
+	&mov	("edx",$Dhi);
+	&add	("eax","esi");
+	&adc	("ebx","edi");			# T1 += K[i]
+	&mov	($Tlo,"eax");
+	&mov	($Thi,"ebx");			# put T1 away
+	&add	("eax","ecx");
+	&adc	("ebx","edx");			# d += T1
+
+	#define Sigma0(x)	(ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
+	#	LO		lo>>28^hi<<4  ^ hi>>2^lo<<30 ^ hi>>7^lo<<25
+	#	HI		hi>>28^lo<<4  ^ lo>>2^hi<<30 ^ lo>>7^hi<<25
+	&mov	("ecx",$Alo);
+	&mov	("edx",$Ahi);
+	&mov	($Dlo,"eax");
+	&mov	($Dhi,"ebx");
+	&mov	("esi","ecx");
+
+	&shr	("ecx",2)	# lo>>2
+	&mov	("edi","edx");
+	&shr	("edx",2)	# hi>>2
+	&mov	("ebx","ecx");
+	&shl	("esi",4);	# lo<<4
+	&mov	("eax","edx");
+	&shl	("edi",4);	# hi<<4
+	&xor	("ebx","esi");
+
+	&shr	("ecx",7-2);	# lo>>7
+	&xor	("eax","edi");
+	&shr	("edx",7-2);	# hi>>7
+	&xor	("ebx","ecx");
+	&shl	("esi",25-4);	# lo<<25
+	&xor	("eax","edx");
+	&shl	("edi",25-4);	# hi<<25
+	&xor	("eax","esi");
+
+	&shr	("ecx",28-7);	# lo>>28
+	&xor	("ebx","edi");
+	&shr	("edx",28-7);	# hi>>28
+	&xor	("eax","ecx");
+	&shl	("esi",30-25);	# lo<<30
+	&xor	("ebx","edx");
+	&shl	("edi",30-25);	# hi<<30
+	&xor	("eax","esi");
+	&xor	("ebx","edi");			# Sigma0(a)
+
+	&mov	("ecx",$Alo);
+	&mov	("edx",$Ahi);
+	&mov	("esi",$Blo);
+	&mov	("edi",$Bhi);
+	&add	("eax",$Tlo);
+	&adc	("ebx",$Thi);			# T1 = Sigma0(a)+T1
+	&or	("ecx","esi");
+	&or	("edx","edi");
+	&and	("ecx",$Clo);
+	&and	("edx",$Chi);
+	&and	("esi",$Alo);
+	&and	("edi",$Ahi);
+	&or	("ecx","esi");
+	&or	("edx","edi");			# Maj(a,b,c) = ((a|b)&c)|(a&b)
+
+	&add	("eax","ecx");
+	&adc	("ebx","edx");			# T1 += Maj(a,b,c)
+	&mov	($Tlo,"eax");
+	&mov	($Thi,"ebx");
+
+	&mov	(&LB("edx"),&BP(0,$K512));	# pre-fetch LSB of *K
+	&sub	("esp",8);
+	&lea	($K512,&DWP(8,$K512));		# K++
+}
+
+
+&function_begin("sha512_block_data_order");
+	&mov	("esi",wparam(0));	# ctx
+	&mov	("edi",wparam(1));	# inp
+	&mov	("eax",wparam(2));	# num
+	&mov	("ebx","esp");		# saved sp
+
+	&call	(&label("pic_point"));	# make it PIC!
+&set_label("pic_point");
+	&blindpop($K512);
+	&lea	($K512,&DWP(&label("K512")."-".&label("pic_point"),$K512));
+
+	&sub	("esp",16);
+	&and	("esp",-64);
+
+	&shl	("eax",7);
+	&add	("eax","edi");
+	&mov	(&DWP(0,"esp"),"esi");	# ctx
+	&mov	(&DWP(4,"esp"),"edi");	# inp
+	&mov	(&DWP(8,"esp"),"eax");	# inp+num*128
+	&mov	(&DWP(12,"esp"),"ebx");	# saved sp
+
+if ($sse2) {
+	&picmeup("edx","OPENSSL_ia32cap_P",$K512,&label("K512"));
+	&bt	(&DWP(0,"edx"),26);
+	&jnc	(&label("loop_x86"));
+
+	# load ctx->h[0-7]
+	&movq	($A,&QWP(0,"esi"));
+	&movq	("mm1",&QWP(8,"esi"));
+	&movq	("mm2",&QWP(16,"esi"));
+	&movq	("mm3",&QWP(24,"esi"));
+	&movq	($E,&QWP(32,"esi"));
+	&movq	("mm5",&QWP(40,"esi"));
+	&movq	("mm6",&QWP(48,"esi"));
+	&movq	("mm7",&QWP(56,"esi"));
+	&sub	("esp",8*10);
+
+&set_label("loop_sse2",16);
+	# &movq	($Asse2,$A);
+	&movq	($Bsse2,"mm1");
+	&movq	($Csse2,"mm2");
+	&movq	($Dsse2,"mm3");
+	# &movq	($Esse2,$E);
+	&movq	($Fsse2,"mm5");
+	&movq	($Gsse2,"mm6");
+	&movq	($Hsse2,"mm7");
+
+	&mov	("ecx",&DWP(0,"edi"));
+	&mov	("edx",&DWP(4,"edi"));
+	&add	("edi",8);
+	&bswap	("ecx");
+	&bswap	("edx");
+	&mov	(&DWP(8*9+4,"esp"),"ecx");
+	&mov	(&DWP(8*9+0,"esp"),"edx");
+
+&set_label("00_14_sse2",16);
+	&mov	("eax",&DWP(0,"edi"));
+	&mov	("ebx",&DWP(4,"edi"));
+	&add	("edi",8);
+	&bswap	("eax");
+	&bswap	("ebx");
+	&mov	(&DWP(8*8+4,"esp"),"eax");
+	&mov	(&DWP(8*8+0,"esp"),"ebx");
+
+	&BODY_00_15_sse2();
+
+	&cmp	(&LB("edx"),0x35);
+	&jne	(&label("00_14_sse2"));
+
+	&BODY_00_15_sse2(1);
+
+&set_label("16_79_sse2",16);
+	#&movq	("mm2",&QWP(8*(9+16-1),"esp"));	#prefetched in BODY_00_15 
+	#&movq	("mm6",&QWP(8*(9+16-14),"esp"));
+	&movq	("mm1","mm2");
+
+	&psrlq	("mm2",1);
+	&movq	("mm7","mm6");
+	&psrlq	("mm6",6);
+	&movq	("mm3","mm2");
+
+	&psrlq	("mm2",7-1);
+	&movq	("mm5","mm6");
+	&psrlq	("mm6",19-6);
+	&pxor	("mm3","mm2");
+
+	&psrlq	("mm2",8-7);
+	&pxor	("mm5","mm6");
+	&psrlq	("mm6",61-19);
+	&pxor	("mm3","mm2");
+
+	&movq	("mm2",&QWP(8*(9+16),"esp"));
+
+	&psllq	("mm1",56);
+	&pxor	("mm5","mm6");
+	&psllq	("mm7",3);
+	&pxor	("mm3","mm1");
+
+	&paddq	("mm2",&QWP(8*(9+16-9),"esp"));
+
+	&psllq	("mm1",63-56);
+	&pxor	("mm5","mm7");
+	&psllq	("mm7",45-3);
+	&pxor	("mm3","mm1");
+	&pxor	("mm5","mm7");
+
+	&paddq	("mm3","mm5");
+	&paddq	("mm3","mm2");
+	&movq	(&QWP(8*9,"esp"),"mm3");
+
+	&BODY_00_15_sse2(1);
+
+	&cmp	(&LB("edx"),0x17);
+	&jne	(&label("16_79_sse2"));
+
+	# &movq	($A,$Asse2);
+	&movq	("mm1",$Bsse2);
+	&movq	("mm2",$Csse2);
+	&movq	("mm3",$Dsse2);
+	# &movq	($E,$Esse2);
+	&movq	("mm5",$Fsse2);
+	&movq	("mm6",$Gsse2);
+	&movq	("mm7",$Hsse2);
+
+	&paddq	($A,&QWP(0,"esi"));
+	&paddq	("mm1",&QWP(8,"esi"));
+	&paddq	("mm2",&QWP(16,"esi"));
+	&paddq	("mm3",&QWP(24,"esi"));
+	&paddq	($E,&QWP(32,"esi"));
+	&paddq	("mm5",&QWP(40,"esi"));
+	&paddq	("mm6",&QWP(48,"esi"));
+	&paddq	("mm7",&QWP(56,"esi"));
+
+	&movq	(&QWP(0,"esi"),$A);
+	&movq	(&QWP(8,"esi"),"mm1");
+	&movq	(&QWP(16,"esi"),"mm2");
+	&movq	(&QWP(24,"esi"),"mm3");
+	&movq	(&QWP(32,"esi"),$E);
+	&movq	(&QWP(40,"esi"),"mm5");
+	&movq	(&QWP(48,"esi"),"mm6");
+	&movq	(&QWP(56,"esi"),"mm7");
+
+	&add	("esp",8*80);			# destroy frame
+	&sub	($K512,8*80);			# rewind K
+
+	&cmp	("edi",&DWP(8*10+8,"esp"));	# are we done yet?
+	&jb	(&label("loop_sse2"));
+
+	&emms	();
+	&mov	("esp",&DWP(8*10+12,"esp"));	# restore sp
+&function_end_A();
+}
+&set_label("loop_x86",16);
+    # copy input block to stack reversing byte and qword order
+    for ($i=0;$i<8;$i++) {
+	&mov	("eax",&DWP($i*16+0,"edi"));
+	&mov	("ebx",&DWP($i*16+4,"edi"));
+	&mov	("ecx",&DWP($i*16+8,"edi"));
+	&mov	("edx",&DWP($i*16+12,"edi"));
+	&bswap	("eax");
+	&bswap	("ebx");
+	&bswap	("ecx");
+	&bswap	("edx");
+	&push	("eax");
+	&push	("ebx");
+	&push	("ecx");
+	&push	("edx");
+    }
+	&add	("edi",128);
+	&sub	("esp",9*8);		# place for T,A,B,C,D,E,F,G,H
+	&mov	(&DWP(8*(9+16)+4,"esp"),"edi");
+
+	# copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack
+	&lea	("edi",&DWP(8,"esp"));
+	&mov	("ecx",16);
+	&data_word(0xA5F3F689);		# rep movsd
+
+&set_label("00_15_x86",16);
+	&BODY_00_15_x86();
+
+	&cmp	(&LB("edx"),0x94);
+	&jne	(&label("00_15_x86"));
+
+&set_label("16_79_x86",16);
+	#define sigma0(x)	(ROTR((x),1)  ^ ROTR((x),8)  ^ ((x)>>7))
+	#	LO		lo>>1^hi<<31  ^ lo>>8^hi<<24 ^ lo>>7^hi<<25
+	#	HI		hi>>1^lo<<31  ^ hi>>8^lo<<24 ^ hi>>7
+	&mov	("ecx",&DWP(8*(9+15+16-1)+0,"esp"));
+	&mov	("edx",&DWP(8*(9+15+16-1)+4,"esp"));
+	&mov	("esi","ecx");
+
+	&shr	("ecx",1)	# lo>>1
+	&mov	("edi","edx");
+	&shr	("edx",1)	# hi>>1
+	&mov	("eax","ecx");
+	&shl	("esi",24);	# lo<<24
+	&mov	("ebx","edx");
+	&shl	("edi",24);	# hi<<24
+	&xor	("ebx","esi");
+
+	&shr	("ecx",7-1);	# lo>>7
+	&xor	("eax","edi");
+	&shr	("edx",7-1);	# hi>>7
+	&xor	("eax","ecx");
+	&shl	("esi",31-24);	# lo<<31
+	&xor	("ebx","edx");
+	&shl	("edi",25-24);	# hi<<25
+	&xor	("ebx","esi");
+
+	&shr	("ecx",8-7);	# lo>>8
+	&xor	("eax","edi");
+	&shr	("edx",8-7);	# hi>>8
+	&xor	("eax","ecx");
+	&shl	("edi",31-25);	# hi<<31
+	&xor	("ebx","edx");
+	&xor	("eax","edi");			# T1 = sigma0(X[-15])
+
+	&mov	(&DWP(0,"esp"),"eax");
+	&mov	(&DWP(4,"esp"),"ebx");		# put T1 away
+
+	#define sigma1(x)	(ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
+	#	LO		lo>>19^hi<<13 ^ hi>>29^lo<<3 ^ lo>>6^hi<<26
+	#	HI		hi>>19^lo<<13 ^ lo>>29^hi<<3 ^ hi>>6
+	&mov	("ecx",&DWP(8*(9+15+16-14)+0,"esp"));
+	&mov	("edx",&DWP(8*(9+15+16-14)+4,"esp"));
+	&mov	("esi","ecx");
+
+	&shr	("ecx",6)	# lo>>6
+	&mov	("edi","edx");
+	&shr	("edx",6)	# hi>>6
+	&mov	("eax","ecx");
+	&shl	("esi",3);	# lo<<3
+	&mov	("ebx","edx");
+	&shl	("edi",3);	# hi<<3
+	&xor	("eax","esi");
+
+	&shr	("ecx",19-6);	# lo>>19
+	&xor	("ebx","edi");
+	&shr	("edx",19-6);	# hi>>19
+	&xor	("eax","ecx");
+	&shl	("esi",13-3);	# lo<<13
+	&xor	("ebx","edx");
+	&shl	("edi",13-3);	# hi<<13
+	&xor	("ebx","esi");
+
+	&shr	("ecx",29-19);	# lo>>29
+	&xor	("eax","edi");
+	&shr	("edx",29-19);	# hi>>29
+	&xor	("ebx","ecx");
+	&shl	("edi",26-13);	# hi<<26
+	&xor	("eax","edx");
+	&xor	("eax","edi");			# sigma1(X[-2])
+
+	&mov	("ecx",&DWP(8*(9+15+16)+0,"esp"));
+	&mov	("edx",&DWP(8*(9+15+16)+4,"esp"));
+	&add	("eax",&DWP(0,"esp"));
+	&adc	("ebx",&DWP(4,"esp"));		# T1 = sigma1(X[-2])+T1
+	&mov	("esi",&DWP(8*(9+15+16-9)+0,"esp"));
+	&mov	("edi",&DWP(8*(9+15+16-9)+4,"esp"));
+	&add	("eax","ecx");
+	&adc	("ebx","edx");			# T1 += X[-16]
+	&add	("eax","esi");
+	&adc	("ebx","edi");			# T1 += X[-7]
+	&mov	(&DWP(8*(9+15)+0,"esp"),"eax");
+	&mov	(&DWP(8*(9+15)+4,"esp"),"ebx");	# save X[0]
+
+	&BODY_00_15_x86();
+
+	&cmp	(&LB("edx"),0x17);
+	&jne	(&label("16_79_x86"));
+
+	&mov	("esi",&DWP(8*(9+16+80)+0,"esp"));# ctx
+	&mov	("edi",&DWP(8*(9+16+80)+4,"esp"));# inp
+    for($i=0;$i<4;$i++) {
+	&mov	("eax",&DWP($i*16+0,"esi"));
+	&mov	("ebx",&DWP($i*16+4,"esi"));
+	&mov	("ecx",&DWP($i*16+8,"esi"));
+	&mov	("edx",&DWP($i*16+12,"esi"));
+	&add	("eax",&DWP(8+($i*16)+0,"esp"));
+	&adc	("ebx",&DWP(8+($i*16)+4,"esp"));
+	&mov	(&DWP($i*16+0,"esi"),"eax");
+	&mov	(&DWP($i*16+4,"esi"),"ebx");
+	&add	("ecx",&DWP(8+($i*16)+8,"esp"));
+	&adc	("edx",&DWP(8+($i*16)+12,"esp"));
+	&mov	(&DWP($i*16+8,"esi"),"ecx");
+	&mov	(&DWP($i*16+12,"esi"),"edx");
+    }
+	&add	("esp",8*(9+16+80));		# destroy frame
+	&sub	($K512,8*80);			# rewind K
+
+	&cmp	("edi",&DWP(8,"esp"));		# are we done yet?
+	&jb	(&label("loop_x86"));
+
+	&mov	("esp",&DWP(12,"esp"));		# restore sp
+&function_end_A();
+
+&set_label("K512",64);	# Yes! I keep it in the code segment!
+	&data_word(0xd728ae22,0x428a2f98);	# u64
+	&data_word(0x23ef65cd,0x71374491);	# u64
+	&data_word(0xec4d3b2f,0xb5c0fbcf);	# u64
+	&data_word(0x8189dbbc,0xe9b5dba5);	# u64
+	&data_word(0xf348b538,0x3956c25b);	# u64
+	&data_word(0xb605d019,0x59f111f1);	# u64
+	&data_word(0xaf194f9b,0x923f82a4);	# u64
+	&data_word(0xda6d8118,0xab1c5ed5);	# u64
+	&data_word(0xa3030242,0xd807aa98);	# u64
+	&data_word(0x45706fbe,0x12835b01);	# u64
+	&data_word(0x4ee4b28c,0x243185be);	# u64
+	&data_word(0xd5ffb4e2,0x550c7dc3);	# u64
+	&data_word(0xf27b896f,0x72be5d74);	# u64
+	&data_word(0x3b1696b1,0x80deb1fe);	# u64
+	&data_word(0x25c71235,0x9bdc06a7);	# u64
+	&data_word(0xcf692694,0xc19bf174);	# u64
+	&data_word(0x9ef14ad2,0xe49b69c1);	# u64
+	&data_word(0x384f25e3,0xefbe4786);	# u64
+	&data_word(0x8b8cd5b5,0x0fc19dc6);	# u64
+	&data_word(0x77ac9c65,0x240ca1cc);	# u64
+	&data_word(0x592b0275,0x2de92c6f);	# u64
+	&data_word(0x6ea6e483,0x4a7484aa);	# u64
+	&data_word(0xbd41fbd4,0x5cb0a9dc);	# u64
+	&data_word(0x831153b5,0x76f988da);	# u64
+	&data_word(0xee66dfab,0x983e5152);	# u64
+	&data_word(0x2db43210,0xa831c66d);	# u64
+	&data_word(0x98fb213f,0xb00327c8);	# u64
+	&data_word(0xbeef0ee4,0xbf597fc7);	# u64
+	&data_word(0x3da88fc2,0xc6e00bf3);	# u64
+	&data_word(0x930aa725,0xd5a79147);	# u64
+	&data_word(0xe003826f,0x06ca6351);	# u64
+	&data_word(0x0a0e6e70,0x14292967);	# u64
+	&data_word(0x46d22ffc,0x27b70a85);	# u64
+	&data_word(0x5c26c926,0x2e1b2138);	# u64
+	&data_word(0x5ac42aed,0x4d2c6dfc);	# u64
+	&data_word(0x9d95b3df,0x53380d13);	# u64
+	&data_word(0x8baf63de,0x650a7354);	# u64
+	&data_word(0x3c77b2a8,0x766a0abb);	# u64
+	&data_word(0x47edaee6,0x81c2c92e);	# u64
+	&data_word(0x1482353b,0x92722c85);	# u64
+	&data_word(0x4cf10364,0xa2bfe8a1);	# u64
+	&data_word(0xbc423001,0xa81a664b);	# u64
+	&data_word(0xd0f89791,0xc24b8b70);	# u64
+	&data_word(0x0654be30,0xc76c51a3);	# u64
+	&data_word(0xd6ef5218,0xd192e819);	# u64
+	&data_word(0x5565a910,0xd6990624);	# u64
+	&data_word(0x5771202a,0xf40e3585);	# u64
+	&data_word(0x32bbd1b8,0x106aa070);	# u64
+	&data_word(0xb8d2d0c8,0x19a4c116);	# u64
+	&data_word(0x5141ab53,0x1e376c08);	# u64
+	&data_word(0xdf8eeb99,0x2748774c);	# u64
+	&data_word(0xe19b48a8,0x34b0bcb5);	# u64
+	&data_word(0xc5c95a63,0x391c0cb3);	# u64
+	&data_word(0xe3418acb,0x4ed8aa4a);	# u64
+	&data_word(0x7763e373,0x5b9cca4f);	# u64
+	&data_word(0xd6b2b8a3,0x682e6ff3);	# u64
+	&data_word(0x5defb2fc,0x748f82ee);	# u64
+	&data_word(0x43172f60,0x78a5636f);	# u64
+	&data_word(0xa1f0ab72,0x84c87814);	# u64
+	&data_word(0x1a6439ec,0x8cc70208);	# u64
+	&data_word(0x23631e28,0x90befffa);	# u64
+	&data_word(0xde82bde9,0xa4506ceb);	# u64
+	&data_word(0xb2c67915,0xbef9a3f7);	# u64
+	&data_word(0xe372532b,0xc67178f2);	# u64
+	&data_word(0xea26619c,0xca273ece);	# u64
+	&data_word(0x21c0c207,0xd186b8c7);	# u64
+	&data_word(0xcde0eb1e,0xeada7dd6);	# u64
+	&data_word(0xee6ed178,0xf57d4f7f);	# u64
+	&data_word(0x72176fba,0x06f067aa);	# u64
+	&data_word(0xa2c898a6,0x0a637dc5);	# u64
+	&data_word(0xbef90dae,0x113f9804);	# u64
+	&data_word(0x131c471b,0x1b710b35);	# u64
+	&data_word(0x23047d84,0x28db77f5);	# u64
+	&data_word(0x40c72493,0x32caab7b);	# u64
+	&data_word(0x15c9bebc,0x3c9ebe0a);	# u64
+	&data_word(0x9c100d4c,0x431d67c4);	# u64
+	&data_word(0xcb3e42b6,0x4cc5d4be);	# u64
+	&data_word(0xfc657e2a,0x597f299c);	# u64
+	&data_word(0x3ad6faec,0x5fcb6fab);	# u64
+	&data_word(0x4a475817,0x6c44198c);	# u64
+&function_end_B("sha512_block_data_order");
+&asciz("SHA512 block transform for x86, CRYPTOGAMS by <appro\@openssl.org>");
+
+&asm_finish();
diff --git a/openssl/crypto/sha/asm/sha512-armv4.pl b/openssl/crypto/sha/asm/sha512-armv4.pl
new file mode 100644
index 0000000..3a35861
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha512-armv4.pl
@@ -0,0 +1,403 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# SHA512 block procedure for ARMv4. September 2007.
+
+# This code is ~4.5 (four and a half) times faster than code generated
+# by gcc 3.4 and it spends ~72 clock cycles per byte [on single-issue
+# Xscale PXA250 core].
+#
+# July 2010.
+#
+# Rescheduling for dual-issue pipeline resulted in 6% improvement on
+# Cortex A8 core and ~40 cycles per processed byte.
+
+# Byte order [in]dependence. =========================================
+#
+# Caller is expected to maintain specific *dword* order in h[0-7],
+# namely with most significant dword at *lower* address, which is
+# reflected in below two parameters. *Byte* order within these dwords
+# in turn is whatever *native* byte order on current platform.
+$hi=0;
+$lo=4;
+# ====================================================================
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
+$ctx="r0";
+$inp="r1";
+$len="r2";
+$Tlo="r3";
+$Thi="r4";
+$Alo="r5";
+$Ahi="r6";
+$Elo="r7";
+$Ehi="r8";
+$t0="r9";
+$t1="r10";
+$t2="r11";
+$t3="r12";
+############	r13 is stack pointer
+$Ktbl="r14";
+############	r15 is program counter
+
+$Aoff=8*0;
+$Boff=8*1;
+$Coff=8*2;
+$Doff=8*3;
+$Eoff=8*4;
+$Foff=8*5;
+$Goff=8*6;
+$Hoff=8*7;
+$Xoff=8*8;
+
+sub BODY_00_15() {
+my $magic = shift;
+$code.=<<___;
+	ldr	$t2,[sp,#$Hoff+0]	@ h.lo
+	ldr	$t3,[sp,#$Hoff+4]	@ h.hi
+	@ Sigma1(x)	(ROTR((x),14) ^ ROTR((x),18)  ^ ROTR((x),41))
+	@ LO		lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23
+	@ HI		hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23
+	mov	$t0,$Elo,lsr#14
+	mov	$t1,$Ehi,lsr#14
+	eor	$t0,$t0,$Ehi,lsl#18
+	eor	$t1,$t1,$Elo,lsl#18
+	eor	$t0,$t0,$Elo,lsr#18
+	eor	$t1,$t1,$Ehi,lsr#18
+	eor	$t0,$t0,$Ehi,lsl#14
+	eor	$t1,$t1,$Elo,lsl#14
+	eor	$t0,$t0,$Ehi,lsr#9
+	eor	$t1,$t1,$Elo,lsr#9
+	eor	$t0,$t0,$Elo,lsl#23
+	eor	$t1,$t1,$Ehi,lsl#23	@ Sigma1(e)
+	adds	$Tlo,$Tlo,$t0
+	ldr	$t0,[sp,#$Foff+0]	@ f.lo
+	adc	$Thi,$Thi,$t1		@ T += Sigma1(e)
+	ldr	$t1,[sp,#$Foff+4]	@ f.hi
+	adds	$Tlo,$Tlo,$t2
+	ldr	$t2,[sp,#$Goff+0]	@ g.lo
+	adc	$Thi,$Thi,$t3		@ T += h
+	ldr	$t3,[sp,#$Goff+4]	@ g.hi
+
+	eor	$t0,$t0,$t2
+	str	$Elo,[sp,#$Eoff+0]
+	eor	$t1,$t1,$t3
+	str	$Ehi,[sp,#$Eoff+4]
+	and	$t0,$t0,$Elo
+	str	$Alo,[sp,#$Aoff+0]
+	and	$t1,$t1,$Ehi
+	str	$Ahi,[sp,#$Aoff+4]
+	eor	$t0,$t0,$t2
+	ldr	$t2,[$Ktbl,#4]		@ K[i].lo
+	eor	$t1,$t1,$t3		@ Ch(e,f,g)
+	ldr	$t3,[$Ktbl,#0]		@ K[i].hi
+
+	adds	$Tlo,$Tlo,$t0
+	ldr	$Elo,[sp,#$Doff+0]	@ d.lo
+	adc	$Thi,$Thi,$t1		@ T += Ch(e,f,g)
+	ldr	$Ehi,[sp,#$Doff+4]	@ d.hi
+	adds	$Tlo,$Tlo,$t2
+	adc	$Thi,$Thi,$t3		@ T += K[i]
+	adds	$Elo,$Elo,$Tlo
+	adc	$Ehi,$Ehi,$Thi		@ d += T
+
+	and	$t0,$t2,#0xff
+	teq	$t0,#$magic
+	orreq	$Ktbl,$Ktbl,#1
+
+	ldr	$t2,[sp,#$Boff+0]	@ b.lo
+	ldr	$t3,[sp,#$Coff+0]	@ c.lo
+	@ Sigma0(x)	(ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
+	@ LO		lo>>28^hi<<4  ^ hi>>2^lo<<30 ^ hi>>7^lo<<25
+	@ HI		hi>>28^lo<<4  ^ lo>>2^hi<<30 ^ lo>>7^hi<<25
+	mov	$t0,$Alo,lsr#28
+	mov	$t1,$Ahi,lsr#28
+	eor	$t0,$t0,$Ahi,lsl#4
+	eor	$t1,$t1,$Alo,lsl#4
+	eor	$t0,$t0,$Ahi,lsr#2
+	eor	$t1,$t1,$Alo,lsr#2
+	eor	$t0,$t0,$Alo,lsl#30
+	eor	$t1,$t1,$Ahi,lsl#30
+	eor	$t0,$t0,$Ahi,lsr#7
+	eor	$t1,$t1,$Alo,lsr#7
+	eor	$t0,$t0,$Alo,lsl#25
+	eor	$t1,$t1,$Ahi,lsl#25	@ Sigma0(a)
+	adds	$Tlo,$Tlo,$t0
+	adc	$Thi,$Thi,$t1		@ T += Sigma0(a)
+
+	and	$t0,$Alo,$t2
+	orr	$Alo,$Alo,$t2
+	ldr	$t1,[sp,#$Boff+4]	@ b.hi
+	ldr	$t2,[sp,#$Coff+4]	@ c.hi
+	and	$Alo,$Alo,$t3
+	orr	$Alo,$Alo,$t0		@ Maj(a,b,c).lo
+	and	$t3,$Ahi,$t1
+	orr	$Ahi,$Ahi,$t1
+	and	$Ahi,$Ahi,$t2
+	orr	$Ahi,$Ahi,$t3		@ Maj(a,b,c).hi
+	adds	$Alo,$Alo,$Tlo
+	adc	$Ahi,$Ahi,$Thi		@ h += T
+
+	sub	sp,sp,#8
+	add	$Ktbl,$Ktbl,#8
+___
+}
+$code=<<___;
+.text
+.code	32
+.type	K512,%object
+.align	5
+K512:
+.word	0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd
+.word	0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc
+.word	0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019
+.word	0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118
+.word	0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe
+.word	0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2
+.word	0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1
+.word	0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694
+.word	0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3
+.word	0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65
+.word	0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483
+.word	0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5
+.word	0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210
+.word	0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4
+.word	0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725
+.word	0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70
+.word	0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926
+.word	0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df
+.word	0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8
+.word	0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b
+.word	0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001
+.word	0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30
+.word	0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910
+.word	0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8
+.word	0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53
+.word	0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8
+.word	0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb
+.word	0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3
+.word	0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60
+.word	0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec
+.word	0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9
+.word	0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b
+.word	0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207
+.word	0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178
+.word	0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6
+.word	0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b
+.word	0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493
+.word	0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c
+.word	0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a
+.word	0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817
+.size	K512,.-K512
+
+.global	sha512_block_data_order
+.type	sha512_block_data_order,%function
+sha512_block_data_order:
+	sub	r3,pc,#8		@ sha512_block_data_order
+	add	$len,$inp,$len,lsl#7	@ len to point at the end of inp
+	stmdb	sp!,{r4-r12,lr}
+	sub	$Ktbl,r3,#640		@ K512
+	sub	sp,sp,#9*8
+
+	ldr	$Elo,[$ctx,#$Eoff+$lo]
+	ldr	$Ehi,[$ctx,#$Eoff+$hi]
+	ldr	$t0, [$ctx,#$Goff+$lo]
+	ldr	$t1, [$ctx,#$Goff+$hi]
+	ldr	$t2, [$ctx,#$Hoff+$lo]
+	ldr	$t3, [$ctx,#$Hoff+$hi]
+.Loop:
+	str	$t0, [sp,#$Goff+0]
+	str	$t1, [sp,#$Goff+4]
+	str	$t2, [sp,#$Hoff+0]
+	str	$t3, [sp,#$Hoff+4]
+	ldr	$Alo,[$ctx,#$Aoff+$lo]
+	ldr	$Ahi,[$ctx,#$Aoff+$hi]
+	ldr	$Tlo,[$ctx,#$Boff+$lo]
+	ldr	$Thi,[$ctx,#$Boff+$hi]
+	ldr	$t0, [$ctx,#$Coff+$lo]
+	ldr	$t1, [$ctx,#$Coff+$hi]
+	ldr	$t2, [$ctx,#$Doff+$lo]
+	ldr	$t3, [$ctx,#$Doff+$hi]
+	str	$Tlo,[sp,#$Boff+0]
+	str	$Thi,[sp,#$Boff+4]
+	str	$t0, [sp,#$Coff+0]
+	str	$t1, [sp,#$Coff+4]
+	str	$t2, [sp,#$Doff+0]
+	str	$t3, [sp,#$Doff+4]
+	ldr	$Tlo,[$ctx,#$Foff+$lo]
+	ldr	$Thi,[$ctx,#$Foff+$hi]
+	str	$Tlo,[sp,#$Foff+0]
+	str	$Thi,[sp,#$Foff+4]
+
+.L00_15:
+	ldrb	$Tlo,[$inp,#7]
+	ldrb	$t0, [$inp,#6]
+	ldrb	$t1, [$inp,#5]
+	ldrb	$t2, [$inp,#4]
+	ldrb	$Thi,[$inp,#3]
+	ldrb	$t3, [$inp,#2]
+	orr	$Tlo,$Tlo,$t0,lsl#8
+	ldrb	$t0, [$inp,#1]
+	orr	$Tlo,$Tlo,$t1,lsl#16
+	ldrb	$t1, [$inp],#8
+	orr	$Tlo,$Tlo,$t2,lsl#24
+	orr	$Thi,$Thi,$t3,lsl#8
+	orr	$Thi,$Thi,$t0,lsl#16
+	orr	$Thi,$Thi,$t1,lsl#24
+	str	$Tlo,[sp,#$Xoff+0]
+	str	$Thi,[sp,#$Xoff+4]
+___
+	&BODY_00_15(0x94);
+$code.=<<___;
+	tst	$Ktbl,#1
+	beq	.L00_15
+	bic	$Ktbl,$Ktbl,#1
+
+.L16_79:
+	ldr	$t0,[sp,#`$Xoff+8*(16-1)`+0]
+	ldr	$t1,[sp,#`$Xoff+8*(16-1)`+4]
+	ldr	$t2,[sp,#`$Xoff+8*(16-14)`+0]
+	ldr	$t3,[sp,#`$Xoff+8*(16-14)`+4]
+
+	@ sigma0(x)	(ROTR((x),1)  ^ ROTR((x),8)  ^ ((x)>>7))
+	@ LO		lo>>1^hi<<31  ^ lo>>8^hi<<24 ^ lo>>7^hi<<25
+	@ HI		hi>>1^lo<<31  ^ hi>>8^lo<<24 ^ hi>>7
+	mov	$Tlo,$t0,lsr#1
+	mov	$Thi,$t1,lsr#1
+	eor	$Tlo,$Tlo,$t1,lsl#31
+	eor	$Thi,$Thi,$t0,lsl#31
+	eor	$Tlo,$Tlo,$t0,lsr#8
+	eor	$Thi,$Thi,$t1,lsr#8
+	eor	$Tlo,$Tlo,$t1,lsl#24
+	eor	$Thi,$Thi,$t0,lsl#24
+	eor	$Tlo,$Tlo,$t0,lsr#7
+	eor	$Thi,$Thi,$t1,lsr#7
+	eor	$Tlo,$Tlo,$t1,lsl#25
+
+	@ sigma1(x)	(ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
+	@ LO		lo>>19^hi<<13 ^ hi>>29^lo<<3 ^ lo>>6^hi<<26
+	@ HI		hi>>19^lo<<13 ^ lo>>29^hi<<3 ^ hi>>6
+	mov	$t0,$t2,lsr#19
+	mov	$t1,$t3,lsr#19
+	eor	$t0,$t0,$t3,lsl#13
+	eor	$t1,$t1,$t2,lsl#13
+	eor	$t0,$t0,$t3,lsr#29
+	eor	$t1,$t1,$t2,lsr#29
+	eor	$t0,$t0,$t2,lsl#3
+	eor	$t1,$t1,$t3,lsl#3
+	eor	$t0,$t0,$t2,lsr#6
+	eor	$t1,$t1,$t3,lsr#6
+	eor	$t0,$t0,$t3,lsl#26
+
+	ldr	$t2,[sp,#`$Xoff+8*(16-9)`+0]
+	ldr	$t3,[sp,#`$Xoff+8*(16-9)`+4]
+	adds	$Tlo,$Tlo,$t0
+	adc	$Thi,$Thi,$t1
+
+	ldr	$t0,[sp,#`$Xoff+8*16`+0]
+	ldr	$t1,[sp,#`$Xoff+8*16`+4]
+	adds	$Tlo,$Tlo,$t2
+	adc	$Thi,$Thi,$t3
+	adds	$Tlo,$Tlo,$t0
+	adc	$Thi,$Thi,$t1
+	str	$Tlo,[sp,#$Xoff+0]
+	str	$Thi,[sp,#$Xoff+4]
+___
+	&BODY_00_15(0x17);
+$code.=<<___;
+	tst	$Ktbl,#1
+	beq	.L16_79
+	bic	$Ktbl,$Ktbl,#1
+
+	ldr	$Tlo,[sp,#$Boff+0]
+	ldr	$Thi,[sp,#$Boff+4]
+	ldr	$t0, [$ctx,#$Aoff+$lo]
+	ldr	$t1, [$ctx,#$Aoff+$hi]
+	ldr	$t2, [$ctx,#$Boff+$lo]
+	ldr	$t3, [$ctx,#$Boff+$hi]
+	adds	$t0,$Alo,$t0
+	adc	$t1,$Ahi,$t1
+	adds	$t2,$Tlo,$t2
+	adc	$t3,$Thi,$t3
+	str	$t0, [$ctx,#$Aoff+$lo]
+	str	$t1, [$ctx,#$Aoff+$hi]
+	str	$t2, [$ctx,#$Boff+$lo]
+	str	$t3, [$ctx,#$Boff+$hi]
+
+	ldr	$Alo,[sp,#$Coff+0]
+	ldr	$Ahi,[sp,#$Coff+4]
+	ldr	$Tlo,[sp,#$Doff+0]
+	ldr	$Thi,[sp,#$Doff+4]
+	ldr	$t0, [$ctx,#$Coff+$lo]
+	ldr	$t1, [$ctx,#$Coff+$hi]
+	ldr	$t2, [$ctx,#$Doff+$lo]
+	ldr	$t3, [$ctx,#$Doff+$hi]
+	adds	$t0,$Alo,$t0
+	adc	$t1,$Ahi,$t1
+	adds	$t2,$Tlo,$t2
+	adc	$t3,$Thi,$t3
+	str	$t0, [$ctx,#$Coff+$lo]
+	str	$t1, [$ctx,#$Coff+$hi]
+	str	$t2, [$ctx,#$Doff+$lo]
+	str	$t3, [$ctx,#$Doff+$hi]
+
+	ldr	$Tlo,[sp,#$Foff+0]
+	ldr	$Thi,[sp,#$Foff+4]
+	ldr	$t0, [$ctx,#$Eoff+$lo]
+	ldr	$t1, [$ctx,#$Eoff+$hi]
+	ldr	$t2, [$ctx,#$Foff+$lo]
+	ldr	$t3, [$ctx,#$Foff+$hi]
+	adds	$Elo,$Elo,$t0
+	adc	$Ehi,$Ehi,$t1
+	adds	$t2,$Tlo,$t2
+	adc	$t3,$Thi,$t3
+	str	$Elo,[$ctx,#$Eoff+$lo]
+	str	$Ehi,[$ctx,#$Eoff+$hi]
+	str	$t2, [$ctx,#$Foff+$lo]
+	str	$t3, [$ctx,#$Foff+$hi]
+
+	ldr	$Alo,[sp,#$Goff+0]
+	ldr	$Ahi,[sp,#$Goff+4]
+	ldr	$Tlo,[sp,#$Hoff+0]
+	ldr	$Thi,[sp,#$Hoff+4]
+	ldr	$t0, [$ctx,#$Goff+$lo]
+	ldr	$t1, [$ctx,#$Goff+$hi]
+	ldr	$t2, [$ctx,#$Hoff+$lo]
+	ldr	$t3, [$ctx,#$Hoff+$hi]
+	adds	$t0,$Alo,$t0
+	adc	$t1,$Ahi,$t1
+	adds	$t2,$Tlo,$t2
+	adc	$t3,$Thi,$t3
+	str	$t0, [$ctx,#$Goff+$lo]
+	str	$t1, [$ctx,#$Goff+$hi]
+	str	$t2, [$ctx,#$Hoff+$lo]
+	str	$t3, [$ctx,#$Hoff+$hi]
+
+	add	sp,sp,#640
+	sub	$Ktbl,$Ktbl,#640
+
+	teq	$inp,$len
+	bne	.Loop
+
+	add	sp,sp,#8*9		@ destroy frame
+	ldmia	sp!,{r4-r12,lr}
+	tst	lr,#1
+	moveq	pc,lr			@ be binary compatible with V4, yet
+	bx	lr			@ interoperable with Thumb ISA:-)
+.size   sha512_block_data_order,.-sha512_block_data_order
+.asciz  "SHA512 block transform for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
+.align	2
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
+print $code;
+close STDOUT; # enforce flush
diff --git a/openssl/crypto/sha/asm/sha512-ia64.pl b/openssl/crypto/sha/asm/sha512-ia64.pl
new file mode 100755
index 0000000..1c6ce56
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha512-ia64.pl
@@ -0,0 +1,672 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# SHA256/512_Transform for Itanium.
+#
+# sha512_block runs in 1003 cycles on Itanium 2, which is almost 50%
+# faster than gcc and >60%(!) faster than code generated by HP-UX
+# compiler (yes, HP-UX is generating slower code, because unlike gcc,
+# it failed to deploy "shift right pair," 'shrp' instruction, which
+# substitutes for 64-bit rotate).
+#
+# 924 cycles long sha256_block outperforms gcc by over factor of 2(!)
+# and HP-UX compiler - by >40% (yes, gcc won sha512_block, but lost
+# this one big time). Note that "formally" 924 is about 100 cycles
+# too much. I mean it's 64 32-bit rounds vs. 80 virtually identical
+# 64-bit ones and 1003*64/80 gives 802. Extra cycles, 2 per round,
+# are spent on extra work to provide for 32-bit rotations. 32-bit
+# rotations are still handled by 'shrp' instruction and for this
+# reason lower 32 bits are deposited to upper half of 64-bit register
+# prior 'shrp' issue. And in order to minimize the amount of such
+# operations, X[16] values are *maintained* with copies of lower
+# halves in upper halves, which is why you'll spot such instructions
+# as custom 'mux2', "parallel 32-bit add," 'padd4' and "parallel
+# 32-bit unsigned right shift," 'pshr4.u' instructions here.
+#
+# Rules of engagement.
+#
+# There is only one integer shifter meaning that if I have two rotate,
+# deposit or extract instructions in adjacent bundles, they shall
+# split [at run-time if they have to]. But note that variable and
+# parallel shifts are performed by multi-media ALU and *are* pairable
+# with rotates [and alike]. On the backside MMALU is rather slow: it
+# takes 2 extra cycles before the result of integer operation is
+# available *to* MMALU and 2(*) extra cycles before the result of MM
+# operation is available "back" *to* integer ALU, not to mention that
+# MMALU itself has 2 cycles latency. However! I explicitly scheduled
+# these MM instructions to avoid MM stalls, so that all these extra
+# latencies get "hidden" in instruction-level parallelism.
+#
+# (*) 2 cycles on Itanium 1 and 1 cycle on Itanium 2. But I schedule
+#     for 2 in order to provide for best *overall* performance,
+#     because on Itanium 1 stall on MM result is accompanied by
+#     pipeline flush, which takes 6 cycles:-(
+#
+# Resulting performance numbers for 900MHz Itanium 2 system:
+#
+# The 'numbers' are in 1000s of bytes per second processed.
+# type     16 bytes    64 bytes   256 bytes  1024 bytes  8192 bytes
+# sha1(*)   6210.14k   20376.30k   52447.83k   85870.05k  105478.12k
+# sha256    7476.45k   20572.05k   41538.34k   56062.29k   62093.18k
+# sha512    4996.56k   20026.28k   47597.20k   85278.79k  111501.31k
+#
+# (*) SHA1 numbers are for HP-UX compiler and are presented purely
+#     for reference purposes. I bet it can improved too...
+#
+# To generate code, pass the file name with either 256 or 512 in its
+# name and compiler flags.
+
+$output=shift;
+
+if ($output =~ /512.*\.[s|asm]/) {
+	$SZ=8;
+	$BITS=8*$SZ;
+	$LDW="ld8";
+	$STW="st8";
+	$ADD="add";
+	$SHRU="shr.u";
+	$TABLE="K512";
+	$func="sha512_block_data_order";
+	@Sigma0=(28,34,39);
+	@Sigma1=(14,18,41);
+	@sigma0=(1,  8, 7);
+	@sigma1=(19,61, 6);
+	$rounds=80;
+} elsif ($output =~ /256.*\.[s|asm]/) {
+	$SZ=4;
+	$BITS=8*$SZ;
+	$LDW="ld4";
+	$STW="st4";
+	$ADD="padd4";
+	$SHRU="pshr4.u";
+	$TABLE="K256";
+	$func="sha256_block_data_order";
+	@Sigma0=( 2,13,22);
+	@Sigma1=( 6,11,25);
+	@sigma0=( 7,18, 3);
+	@sigma1=(17,19,10);
+	$rounds=64;
+} else { die "nonsense $output"; }
+
+open STDOUT,">$output" || die "can't open $output: $!";
+
+if ($^O eq "hpux") {
+    $ADDP="addp4";
+    for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); }
+} else { $ADDP="add"; }
+for (@ARGV)  {	$big_endian=1 if (/\-DB_ENDIAN/);
+		$big_endian=0 if (/\-DL_ENDIAN/);  }
+if (!defined($big_endian))
+             {	$big_endian=(unpack('L',pack('N',1))==1);  }
+
+$code=<<___;
+.ident  \"$output, version 1.1\"
+.ident  \"IA-64 ISA artwork by Andy Polyakov <appro\@fy.chalmers.se>\"
+.explicit
+.text
+
+pfssave=r2;
+lcsave=r3;
+prsave=r14;
+K=r15;
+A=r16;	B=r17;	C=r18;	D=r19;
+E=r20;	F=r21;	G=r22;	H=r23;
+T1=r24;	T2=r25;
+s0=r26;	s1=r27;	t0=r28;	t1=r29;
+Ktbl=r30;
+ctx=r31;	// 1st arg
+input=r48;	// 2nd arg
+num=r49;	// 3rd arg
+sgm0=r50;	sgm1=r51;	// small constants
+A_=r54;	B_=r55;	C_=r56;	D_=r57;
+E_=r58;	F_=r59;	G_=r60;	H_=r61;
+
+// void $func (SHA_CTX *ctx, const void *in,size_t num[,int host])
+.global	$func#
+.proc	$func#
+.align	32
+$func:
+	.prologue
+	.save	ar.pfs,pfssave
+{ .mmi;	alloc	pfssave=ar.pfs,3,27,0,16
+	$ADDP	ctx=0,r32		// 1st arg
+	.save	ar.lc,lcsave
+	mov	lcsave=ar.lc	}
+{ .mmi;	$ADDP	input=0,r33		// 2nd arg
+	mov	num=r34			// 3rd arg
+	.save	pr,prsave
+	mov	prsave=pr	};;
+
+	.body
+{ .mib;	add	r8=0*$SZ,ctx
+	add	r9=1*$SZ,ctx
+	brp.loop.imp	.L_first16,.L_first16_end-16	}
+{ .mib;	add	r10=2*$SZ,ctx
+	add	r11=3*$SZ,ctx
+	brp.loop.imp	.L_rest,.L_rest_end-16		};;
+
+// load A-H
+.Lpic_point:
+{ .mmi;	$LDW	A_=[r8],4*$SZ
+	$LDW	B_=[r9],4*$SZ
+	mov	Ktbl=ip		}
+{ .mmi;	$LDW	C_=[r10],4*$SZ
+	$LDW	D_=[r11],4*$SZ
+	mov	sgm0=$sigma0[2]	};;
+{ .mmi;	$LDW	E_=[r8]
+	$LDW	F_=[r9]
+	add	Ktbl=($TABLE#-.Lpic_point),Ktbl		}
+{ .mmi;	$LDW	G_=[r10]
+	$LDW	H_=[r11]
+	cmp.ne	p0,p16=0,r0	};;	// used in sha256_block
+___
+$code.=<<___ if ($BITS==64);
+{ .mii;	and	r8=7,input
+	and	input=~7,input;;
+	cmp.eq	p9,p0=1,r8	}
+{ .mmi;	cmp.eq	p10,p0=2,r8
+	cmp.eq	p11,p0=3,r8
+	cmp.eq	p12,p0=4,r8	}
+{ .mmi;	cmp.eq	p13,p0=5,r8
+	cmp.eq	p14,p0=6,r8
+	cmp.eq	p15,p0=7,r8	};;
+___
+$code.=<<___;
+.L_outer:
+.rotr	X[16]
+{ .mmi;	mov	A=A_
+	mov	B=B_
+	mov	ar.lc=14	}
+{ .mmi;	mov	C=C_
+	mov	D=D_
+	mov	E=E_		}
+{ .mmi;	mov	F=F_
+	mov	G=G_
+	mov	ar.ec=2		}
+{ .mmi;	ld1	X[15]=[input],$SZ		// eliminated in 64-bit
+	mov	H=H_
+	mov	sgm1=$sigma1[2]	};;
+
+___
+$t0="t0", $t1="t1", $code.=<<___ if ($BITS==32);
+.align	32
+.L_first16:
+{ .mmi;		add	r9=1-$SZ,input
+		add	r10=2-$SZ,input
+		add	r11=3-$SZ,input	};;
+{ .mmi;		ld1	r9=[r9]
+		ld1	r10=[r10]
+		dep.z	$t1=E,32,32	}
+{ .mmi;		$LDW	K=[Ktbl],$SZ
+		ld1	r11=[r11]
+		zxt4	E=E		};;
+{ .mii;		or	$t1=$t1,E
+		dep	X[15]=X[15],r9,8,8
+		dep	r11=r10,r11,8,8	};;
+{ .mmi;		and	T1=F,E
+		and	T2=A,B
+		dep	X[15]=X[15],r11,16,16	}
+{ .mmi;		andcm	r8=G,E
+		and	r9=A,C
+		mux2	$t0=A,0x44	};;	// copy lower half to upper
+{ .mmi;	(p16)	ld1	X[15-1]=[input],$SZ	// prefetch
+		xor	T1=T1,r8		// T1=((e & f) ^ (~e & g))
+		_rotr	r11=$t1,$Sigma1[0] }	// ROTR(e,14)
+{ .mib;		and	r10=B,C
+		xor	T2=T2,r9	};;
+___
+$t0="A", $t1="E", $code.=<<___ if ($BITS==64);
+// in 64-bit mode I load whole X[16] at once and take care of alignment...
+{ .mmi;	add	r8=1*$SZ,input
+	add	r9=2*$SZ,input
+	add	r10=3*$SZ,input		};;
+{ .mmb;	$LDW	X[15]=[input],4*$SZ
+	$LDW	X[14]=[r8],4*$SZ
+(p9)	br.cond.dpnt.many	.L1byte	};;
+{ .mmb;	$LDW	X[13]=[r9],4*$SZ
+	$LDW	X[12]=[r10],4*$SZ
+(p10)	br.cond.dpnt.many	.L2byte	};;
+{ .mmb;	$LDW	X[11]=[input],4*$SZ
+	$LDW	X[10]=[r8],4*$SZ
+(p11)	br.cond.dpnt.many	.L3byte	};;
+{ .mmb;	$LDW	X[ 9]=[r9],4*$SZ
+	$LDW	X[ 8]=[r10],4*$SZ
+(p12)	br.cond.dpnt.many	.L4byte	};;
+{ .mmb;	$LDW	X[ 7]=[input],4*$SZ
+	$LDW	X[ 6]=[r8],4*$SZ
+(p13)	br.cond.dpnt.many	.L5byte	};;
+{ .mmb;	$LDW	X[ 5]=[r9],4*$SZ
+	$LDW	X[ 4]=[r10],4*$SZ
+(p14)	br.cond.dpnt.many	.L6byte	};;
+{ .mmb;	$LDW	X[ 3]=[input],4*$SZ
+	$LDW	X[ 2]=[r8],4*$SZ
+(p15)	br.cond.dpnt.many	.L7byte	};;
+{ .mmb;	$LDW	X[ 1]=[r9],4*$SZ
+	$LDW	X[ 0]=[r10],4*$SZ
+	br.many	.L_first16		};;
+.L1byte:
+{ .mmi;	$LDW	X[13]=[r9],4*$SZ
+	$LDW	X[12]=[r10],4*$SZ
+	shrp	X[15]=X[15],X[14],56	};;
+{ .mmi;	$LDW	X[11]=[input],4*$SZ
+	$LDW	X[10]=[r8],4*$SZ
+	shrp	X[14]=X[14],X[13],56	}
+{ .mmi;	$LDW	X[ 9]=[r9],4*$SZ
+	$LDW	X[ 8]=[r10],4*$SZ
+	shrp	X[13]=X[13],X[12],56	};;
+{ .mmi;	$LDW	X[ 7]=[input],4*$SZ
+	$LDW	X[ 6]=[r8],4*$SZ
+	shrp	X[12]=X[12],X[11],56	}
+{ .mmi;	$LDW	X[ 5]=[r9],4*$SZ
+	$LDW	X[ 4]=[r10],4*$SZ
+	shrp	X[11]=X[11],X[10],56	};;
+{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
+	$LDW	X[ 2]=[r8],4*$SZ
+	shrp	X[10]=X[10],X[ 9],56	}
+{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
+	$LDW	X[ 0]=[r10],4*$SZ
+	shrp	X[ 9]=X[ 9],X[ 8],56	};;
+{ .mii;	$LDW	T1=[input]
+	shrp	X[ 8]=X[ 8],X[ 7],56
+	shrp	X[ 7]=X[ 7],X[ 6],56	}
+{ .mii;	shrp	X[ 6]=X[ 6],X[ 5],56
+	shrp	X[ 5]=X[ 5],X[ 4],56	};;
+{ .mii;	shrp	X[ 4]=X[ 4],X[ 3],56
+	shrp	X[ 3]=X[ 3],X[ 2],56	}
+{ .mii;	shrp	X[ 2]=X[ 2],X[ 1],56
+	shrp	X[ 1]=X[ 1],X[ 0],56	}
+{ .mib;	shrp	X[ 0]=X[ 0],T1,56
+	br.many	.L_first16		};;
+.L2byte:
+{ .mmi;	$LDW	X[11]=[input],4*$SZ
+	$LDW	X[10]=[r8],4*$SZ
+	shrp	X[15]=X[15],X[14],48	}
+{ .mmi;	$LDW	X[ 9]=[r9],4*$SZ
+	$LDW	X[ 8]=[r10],4*$SZ
+	shrp	X[14]=X[14],X[13],48	};;
+{ .mmi;	$LDW	X[ 7]=[input],4*$SZ
+	$LDW	X[ 6]=[r8],4*$SZ
+	shrp	X[13]=X[13],X[12],48	}
+{ .mmi;	$LDW	X[ 5]=[r9],4*$SZ
+	$LDW	X[ 4]=[r10],4*$SZ
+	shrp	X[12]=X[12],X[11],48	};;
+{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
+	$LDW	X[ 2]=[r8],4*$SZ
+	shrp	X[11]=X[11],X[10],48	}
+{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
+	$LDW	X[ 0]=[r10],4*$SZ
+	shrp	X[10]=X[10],X[ 9],48	};;
+{ .mii;	$LDW	T1=[input]
+	shrp	X[ 9]=X[ 9],X[ 8],48
+	shrp	X[ 8]=X[ 8],X[ 7],48	}
+{ .mii;	shrp	X[ 7]=X[ 7],X[ 6],48
+	shrp	X[ 6]=X[ 6],X[ 5],48	};;
+{ .mii;	shrp	X[ 5]=X[ 5],X[ 4],48
+	shrp	X[ 4]=X[ 4],X[ 3],48	}
+{ .mii;	shrp	X[ 3]=X[ 3],X[ 2],48
+	shrp	X[ 2]=X[ 2],X[ 1],48	}
+{ .mii;	shrp	X[ 1]=X[ 1],X[ 0],48
+	shrp	X[ 0]=X[ 0],T1,48	}
+{ .mfb;	br.many	.L_first16		};;
+.L3byte:
+{ .mmi;	$LDW	X[ 9]=[r9],4*$SZ
+	$LDW	X[ 8]=[r10],4*$SZ
+	shrp	X[15]=X[15],X[14],40	};;
+{ .mmi;	$LDW	X[ 7]=[input],4*$SZ
+	$LDW	X[ 6]=[r8],4*$SZ
+	shrp	X[14]=X[14],X[13],40	}
+{ .mmi;	$LDW	X[ 5]=[r9],4*$SZ
+	$LDW	X[ 4]=[r10],4*$SZ
+	shrp	X[13]=X[13],X[12],40	};;
+{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
+	$LDW	X[ 2]=[r8],4*$SZ
+	shrp	X[12]=X[12],X[11],40	}
+{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
+	$LDW	X[ 0]=[r10],4*$SZ
+	shrp	X[11]=X[11],X[10],40	};;
+{ .mii;	$LDW	T1=[input]
+	shrp	X[10]=X[10],X[ 9],40
+	shrp	X[ 9]=X[ 9],X[ 8],40	}
+{ .mii;	shrp	X[ 8]=X[ 8],X[ 7],40
+	shrp	X[ 7]=X[ 7],X[ 6],40	};;
+{ .mii;	shrp	X[ 6]=X[ 6],X[ 5],40
+	shrp	X[ 5]=X[ 5],X[ 4],40	}
+{ .mii;	shrp	X[ 4]=X[ 4],X[ 3],40
+	shrp	X[ 3]=X[ 3],X[ 2],40	}
+{ .mii;	shrp	X[ 2]=X[ 2],X[ 1],40
+	shrp	X[ 1]=X[ 1],X[ 0],40	}
+{ .mib;	shrp	X[ 0]=X[ 0],T1,40
+	br.many	.L_first16		};;
+.L4byte:
+{ .mmi;	$LDW	X[ 7]=[input],4*$SZ
+	$LDW	X[ 6]=[r8],4*$SZ
+	shrp	X[15]=X[15],X[14],32	}
+{ .mmi;	$LDW	X[ 5]=[r9],4*$SZ
+	$LDW	X[ 4]=[r10],4*$SZ
+	shrp	X[14]=X[14],X[13],32	};;
+{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
+	$LDW	X[ 2]=[r8],4*$SZ
+	shrp	X[13]=X[13],X[12],32	}
+{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
+	$LDW	X[ 0]=[r10],4*$SZ
+	shrp	X[12]=X[12],X[11],32	};;
+{ .mii;	$LDW	T1=[input]
+	shrp	X[11]=X[11],X[10],32
+	shrp	X[10]=X[10],X[ 9],32	}
+{ .mii;	shrp	X[ 9]=X[ 9],X[ 8],32
+	shrp	X[ 8]=X[ 8],X[ 7],32	};;
+{ .mii;	shrp	X[ 7]=X[ 7],X[ 6],32
+	shrp	X[ 6]=X[ 6],X[ 5],32	}
+{ .mii;	shrp	X[ 5]=X[ 5],X[ 4],32
+	shrp	X[ 4]=X[ 4],X[ 3],32	}
+{ .mii;	shrp	X[ 3]=X[ 3],X[ 2],32
+	shrp	X[ 2]=X[ 2],X[ 1],32	}
+{ .mii;	shrp	X[ 1]=X[ 1],X[ 0],32
+	shrp	X[ 0]=X[ 0],T1,32	}
+{ .mfb;	br.many	.L_first16		};;
+.L5byte:
+{ .mmi;	$LDW	X[ 5]=[r9],4*$SZ
+	$LDW	X[ 4]=[r10],4*$SZ
+	shrp	X[15]=X[15],X[14],24	};;
+{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
+	$LDW	X[ 2]=[r8],4*$SZ
+	shrp	X[14]=X[14],X[13],24	}
+{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
+	$LDW	X[ 0]=[r10],4*$SZ
+	shrp	X[13]=X[13],X[12],24	};;
+{ .mii;	$LDW	T1=[input]
+	shrp	X[12]=X[12],X[11],24
+	shrp	X[11]=X[11],X[10],24	}
+{ .mii;	shrp	X[10]=X[10],X[ 9],24
+	shrp	X[ 9]=X[ 9],X[ 8],24	};;
+{ .mii;	shrp	X[ 8]=X[ 8],X[ 7],24
+	shrp	X[ 7]=X[ 7],X[ 6],24	}
+{ .mii;	shrp	X[ 6]=X[ 6],X[ 5],24
+	shrp	X[ 5]=X[ 5],X[ 4],24	}
+{ .mii;	shrp	X[ 4]=X[ 4],X[ 3],24
+	shrp	X[ 3]=X[ 3],X[ 2],24	}
+{ .mii;	shrp	X[ 2]=X[ 2],X[ 1],24
+	shrp	X[ 1]=X[ 1],X[ 0],24	}
+{ .mib;	shrp	X[ 0]=X[ 0],T1,24
+	br.many	.L_first16		};;
+.L6byte:
+{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
+	$LDW	X[ 2]=[r8],4*$SZ
+	shrp	X[15]=X[15],X[14],16	}
+{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
+	$LDW	X[ 0]=[r10],4*$SZ
+	shrp	X[14]=X[14],X[13],16	};;
+{ .mii;	$LDW	T1=[input]
+	shrp	X[13]=X[13],X[12],16
+	shrp	X[12]=X[12],X[11],16	}
+{ .mii;	shrp	X[11]=X[11],X[10],16
+	shrp	X[10]=X[10],X[ 9],16	};;
+{ .mii;	shrp	X[ 9]=X[ 9],X[ 8],16
+	shrp	X[ 8]=X[ 8],X[ 7],16	}
+{ .mii;	shrp	X[ 7]=X[ 7],X[ 6],16
+	shrp	X[ 6]=X[ 6],X[ 5],16	}
+{ .mii;	shrp	X[ 5]=X[ 5],X[ 4],16
+	shrp	X[ 4]=X[ 4],X[ 3],16	}
+{ .mii;	shrp	X[ 3]=X[ 3],X[ 2],16
+	shrp	X[ 2]=X[ 2],X[ 1],16	}
+{ .mii;	shrp	X[ 1]=X[ 1],X[ 0],16
+	shrp	X[ 0]=X[ 0],T1,16	}
+{ .mfb;	br.many	.L_first16		};;
+.L7byte:
+{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
+	$LDW	X[ 0]=[r10],4*$SZ
+	shrp	X[15]=X[15],X[14],8	};;
+{ .mii;	$LDW	T1=[input]
+	shrp	X[14]=X[14],X[13],8
+	shrp	X[13]=X[13],X[12],8	}
+{ .mii;	shrp	X[12]=X[12],X[11],8
+	shrp	X[11]=X[11],X[10],8	};;
+{ .mii;	shrp	X[10]=X[10],X[ 9],8
+	shrp	X[ 9]=X[ 9],X[ 8],8	}
+{ .mii;	shrp	X[ 8]=X[ 8],X[ 7],8
+	shrp	X[ 7]=X[ 7],X[ 6],8	}
+{ .mii;	shrp	X[ 6]=X[ 6],X[ 5],8
+	shrp	X[ 5]=X[ 5],X[ 4],8	}
+{ .mii;	shrp	X[ 4]=X[ 4],X[ 3],8
+	shrp	X[ 3]=X[ 3],X[ 2],8	}
+{ .mii;	shrp	X[ 2]=X[ 2],X[ 1],8
+	shrp	X[ 1]=X[ 1],X[ 0],8	}
+{ .mib;	shrp	X[ 0]=X[ 0],T1,8
+	br.many	.L_first16		};;
+
+.align	32
+.L_first16:
+{ .mmi;		$LDW	K=[Ktbl],$SZ
+		and	T1=F,E
+		and	T2=A,B		}
+{ .mmi;		//$LDW	X[15]=[input],$SZ	// X[i]=*input++
+		andcm	r8=G,E
+		and	r9=A,C		};;
+{ .mmi;		xor	T1=T1,r8		//T1=((e & f) ^ (~e & g))
+		and	r10=B,C
+		_rotr	r11=$t1,$Sigma1[0] }	// ROTR(e,14)
+{ .mmi;		xor	T2=T2,r9
+		mux1	X[15]=X[15],\@rev };;	// eliminated in big-endian
+___
+$code.=<<___;
+{ .mib;		add	T1=T1,H			// T1=Ch(e,f,g)+h
+		_rotr	r8=$t1,$Sigma1[1] }	// ROTR(e,18)
+{ .mib;		xor	T2=T2,r10		// T2=((a & b) ^ (a & c) ^ (b & c))
+		mov	H=G		};;
+{ .mib;		xor	r11=r8,r11
+		_rotr	r9=$t1,$Sigma1[2] }	// ROTR(e,41)
+{ .mib;		mov	G=F
+		mov	F=E		};;
+{ .mib;		xor	r9=r9,r11		// r9=Sigma1(e)
+		_rotr	r10=$t0,$Sigma0[0] }	// ROTR(a,28)
+{ .mib;		add	T1=T1,K			// T1=Ch(e,f,g)+h+K512[i]
+		mov	E=D		};;
+{ .mib;		add	T1=T1,r9		// T1+=Sigma1(e)
+		_rotr	r11=$t0,$Sigma0[1] }	// ROTR(a,34)
+{ .mib;		mov	D=C
+		mov	C=B		};;
+{ .mib;		add	T1=T1,X[15]		// T1+=X[i]
+		_rotr	r8=$t0,$Sigma0[2] }	// ROTR(a,39)
+{ .mib;		xor	r10=r10,r11
+		mux2	X[15]=X[15],0x44 };;	// eliminated in 64-bit
+{ .mmi;		xor	r10=r8,r10		// r10=Sigma0(a)
+		mov	B=A
+		add	A=T1,T2		};;
+{ .mib;		add	E=E,T1
+		add	A=A,r10			// T2=Maj(a,b,c)+Sigma0(a)
+	br.ctop.sptk	.L_first16	};;
+.L_first16_end:
+
+{ .mii;	mov	ar.lc=$rounds-17
+	mov	ar.ec=1			};;
+
+.align	32
+.L_rest:
+.rotr	X[16]
+{ .mib;		$LDW	K=[Ktbl],$SZ
+		_rotr	r8=X[15-1],$sigma0[0] }	// ROTR(s0,1)
+{ .mib; 	$ADD	X[15]=X[15],X[15-9]	// X[i&0xF]+=X[(i+9)&0xF]
+		$SHRU	s0=X[15-1],sgm0	};;	// s0=X[(i+1)&0xF]>>7
+{ .mib;		and	T1=F,E
+		_rotr	r9=X[15-1],$sigma0[1] }	// ROTR(s0,8)
+{ .mib;		andcm	r10=G,E
+		$SHRU	s1=X[15-14],sgm1 };;	// s1=X[(i+14)&0xF]>>6
+{ .mmi;		xor	T1=T1,r10		// T1=((e & f) ^ (~e & g))
+		xor	r9=r8,r9
+		_rotr	r10=X[15-14],$sigma1[0] };;// ROTR(s1,19)
+{ .mib;		and	T2=A,B		
+		_rotr	r11=X[15-14],$sigma1[1] }// ROTR(s1,61)
+{ .mib;		and	r8=A,C		};;
+___
+$t0="t0", $t1="t1", $code.=<<___ if ($BITS==32);
+// I adhere to mmi; in order to hold Itanium 1 back and avoid 6 cycle
+// pipeline flush in last bundle. Note that even on Itanium2 the
+// latter stalls for one clock cycle...
+{ .mmi;		xor	s0=s0,r9		// s0=sigma0(X[(i+1)&0xF])
+		dep.z	$t1=E,32,32	}
+{ .mmi;		xor	r10=r11,r10
+		zxt4	E=E		};;
+{ .mmi;		or	$t1=$t1,E
+		xor	s1=s1,r10		// s1=sigma1(X[(i+14)&0xF])
+		mux2	$t0=A,0x44	};;	// copy lower half to upper
+{ .mmi;		xor	T2=T2,r8
+		_rotr	r9=$t1,$Sigma1[0] }	// ROTR(e,14)
+{ .mmi;		and	r10=B,C
+		add	T1=T1,H			// T1=Ch(e,f,g)+h
+		$ADD	X[15]=X[15],s0	};;	// X[i&0xF]+=sigma0(X[(i+1)&0xF])
+___
+$t0="A", $t1="E", $code.=<<___ if ($BITS==64);
+{ .mib;		xor	s0=s0,r9		// s0=sigma0(X[(i+1)&0xF])
+		_rotr	r9=$t1,$Sigma1[0] }	// ROTR(e,14)
+{ .mib;		xor	r10=r11,r10
+		xor	T2=T2,r8	};;
+{ .mib;		xor	s1=s1,r10		// s1=sigma1(X[(i+14)&0xF])
+		add	T1=T1,H		}
+{ .mib;		and	r10=B,C
+		$ADD	X[15]=X[15],s0	};;	// X[i&0xF]+=sigma0(X[(i+1)&0xF])
+___
+$code.=<<___;
+{ .mmi;		xor	T2=T2,r10		// T2=((a & b) ^ (a & c) ^ (b & c))
+		mov	H=G
+		_rotr	r8=$t1,$Sigma1[1] };;	// ROTR(e,18)
+{ .mmi;		xor	r11=r8,r9
+		$ADD	X[15]=X[15],s1		// X[i&0xF]+=sigma1(X[(i+14)&0xF])
+		_rotr	r9=$t1,$Sigma1[2] }	// ROTR(e,41)
+{ .mmi;		mov	G=F
+		mov	F=E		};;
+{ .mib;		xor	r9=r9,r11		// r9=Sigma1(e)
+		_rotr	r10=$t0,$Sigma0[0] }	// ROTR(a,28)
+{ .mib;		add	T1=T1,K			// T1=Ch(e,f,g)+h+K512[i]
+		mov	E=D		};;
+{ .mib;		add	T1=T1,r9		// T1+=Sigma1(e)
+		_rotr	r11=$t0,$Sigma0[1] }	// ROTR(a,34)
+{ .mib;		mov	D=C
+		mov	C=B		};;
+{ .mmi;		add	T1=T1,X[15]		// T1+=X[i]
+		xor	r10=r10,r11
+		_rotr	r8=$t0,$Sigma0[2] };;	// ROTR(a,39)
+{ .mmi;		xor	r10=r8,r10		// r10=Sigma0(a)
+		mov	B=A
+		add	A=T1,T2		};;
+{ .mib;		add	E=E,T1
+		add	A=A,r10			// T2=Maj(a,b,c)+Sigma0(a)
+	br.ctop.sptk	.L_rest	};;
+.L_rest_end:
+
+{ .mmi;	add	A_=A_,A
+	add	B_=B_,B
+	add	C_=C_,C			}
+{ .mmi;	add	D_=D_,D
+	add	E_=E_,E
+	cmp.ltu	p16,p0=1,num		};;
+{ .mmi;	add	F_=F_,F
+	add	G_=G_,G
+	add	H_=H_,H			}
+{ .mmb;	add	Ktbl=-$SZ*$rounds,Ktbl
+(p16)	add	num=-1,num
+(p16)	br.dptk.many	.L_outer	};;
+
+{ .mib;	add	r8=0*$SZ,ctx
+	add	r9=1*$SZ,ctx		}
+{ .mib;	add	r10=2*$SZ,ctx
+	add	r11=3*$SZ,ctx		};;
+{ .mmi;	$STW	[r8]=A_,4*$SZ
+	$STW	[r9]=B_,4*$SZ
+	mov	ar.lc=lcsave		}
+{ .mmi;	$STW	[r10]=C_,4*$SZ
+	$STW	[r11]=D_,4*$SZ
+	mov	pr=prsave,0x1ffff	};;
+{ .mmb;	$STW	[r8]=E_
+	$STW	[r9]=F_			}
+{ .mmb;	$STW	[r10]=G_
+	$STW	[r11]=H_
+	br.ret.sptk.many	b0	};;
+.endp	$func#
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+$code =~ s/_rotr(\s+)([^=]+)=([^,]+),([0-9]+)/shrp$1$2=$3,$3,$4/gm;
+if ($BITS==64) {
+    $code =~ s/mux2(\s+)\S+/nop.i$1 0x0/gm;
+    $code =~ s/mux1(\s+)\S+/nop.i$1 0x0/gm	if ($big_endian);
+    $code =~ s/(shrp\s+X\[[^=]+)=([^,]+),([^,]+),([1-9]+)/$1=$3,$2,64-$4/gm
+    						if (!$big_endian);
+    $code =~ s/ld1(\s+)X\[\S+/nop.m$1 0x0/gm;
+}
+
+print $code;
+
+print<<___ if ($BITS==32);
+.align	64
+.type	K256#,\@object
+K256:	data4	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+	data4	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+	data4	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+	data4	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+	data4	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+	data4	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+	data4	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+	data4	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+	data4	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+	data4	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+	data4	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+	data4	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+	data4	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+	data4	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+	data4	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+	data4	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+.size	K256#,$SZ*$rounds
+stringz	"SHA256 block transform for IA64, CRYPTOGAMS by <appro\@openssl.org>"
+___
+print<<___ if ($BITS==64);
+.align	64
+.type	K512#,\@object
+K512:	data8	0x428a2f98d728ae22,0x7137449123ef65cd
+	data8	0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
+	data8	0x3956c25bf348b538,0x59f111f1b605d019
+	data8	0x923f82a4af194f9b,0xab1c5ed5da6d8118
+	data8	0xd807aa98a3030242,0x12835b0145706fbe
+	data8	0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
+	data8	0x72be5d74f27b896f,0x80deb1fe3b1696b1
+	data8	0x9bdc06a725c71235,0xc19bf174cf692694
+	data8	0xe49b69c19ef14ad2,0xefbe4786384f25e3
+	data8	0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
+	data8	0x2de92c6f592b0275,0x4a7484aa6ea6e483
+	data8	0x5cb0a9dcbd41fbd4,0x76f988da831153b5
+	data8	0x983e5152ee66dfab,0xa831c66d2db43210
+	data8	0xb00327c898fb213f,0xbf597fc7beef0ee4
+	data8	0xc6e00bf33da88fc2,0xd5a79147930aa725
+	data8	0x06ca6351e003826f,0x142929670a0e6e70
+	data8	0x27b70a8546d22ffc,0x2e1b21385c26c926
+	data8	0x4d2c6dfc5ac42aed,0x53380d139d95b3df
+	data8	0x650a73548baf63de,0x766a0abb3c77b2a8
+	data8	0x81c2c92e47edaee6,0x92722c851482353b
+	data8	0xa2bfe8a14cf10364,0xa81a664bbc423001
+	data8	0xc24b8b70d0f89791,0xc76c51a30654be30
+	data8	0xd192e819d6ef5218,0xd69906245565a910
+	data8	0xf40e35855771202a,0x106aa07032bbd1b8
+	data8	0x19a4c116b8d2d0c8,0x1e376c085141ab53
+	data8	0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
+	data8	0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
+	data8	0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
+	data8	0x748f82ee5defb2fc,0x78a5636f43172f60
+	data8	0x84c87814a1f0ab72,0x8cc702081a6439ec
+	data8	0x90befffa23631e28,0xa4506cebde82bde9
+	data8	0xbef9a3f7b2c67915,0xc67178f2e372532b
+	data8	0xca273eceea26619c,0xd186b8c721c0c207
+	data8	0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
+	data8	0x06f067aa72176fba,0x0a637dc5a2c898a6
+	data8	0x113f9804bef90dae,0x1b710b35131c471b
+	data8	0x28db77f523047d84,0x32caab7b40c72493
+	data8	0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
+	data8	0x4cc5d4becb3e42b6,0x597f299cfc657e2a
+	data8	0x5fcb6fab3ad6faec,0x6c44198c4a475817
+.size	K512#,$SZ*$rounds
+stringz	"SHA512 block transform for IA64, CRYPTOGAMS by <appro\@openssl.org>"
+___
diff --git a/openssl/crypto/sha/asm/sha512-ppc.pl b/openssl/crypto/sha/asm/sha512-ppc.pl
new file mode 100644
index 0000000..768a6a6
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha512-ppc.pl
@@ -0,0 +1,462 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# I let hardware handle unaligned input, except on page boundaries
+# (see below for details). Otherwise straightforward implementation
+# with X vector in register bank. The module is big-endian [which is
+# not big deal as there're no little-endian targets left around].
+
+#			sha256		|	sha512
+# 			-m64	-m32	|	-m64	-m32
+# --------------------------------------+-----------------------
+# PPC970,gcc-4.0.0	+50%	+38%	|	+40%	+410%(*)
+# Power6,xlc-7		+150%	+90%	|	+100%	+430%(*)
+#
+# (*)	64-bit code in 32-bit application context, which actually is
+#	on TODO list. It should be noted that for safe deployment in
+#	32-bit *mutli-threaded* context asyncronous signals should be
+#	blocked upon entry to SHA512 block routine. This is because
+#	32-bit signaling procedure invalidates upper halves of GPRs.
+#	Context switch procedure preserves them, but not signaling:-(
+
+# Second version is true multi-thread safe. Trouble with the original
+# version was that it was using thread local storage pointer register.
+# Well, it scrupulously preserved it, but the problem would arise the
+# moment asynchronous signal was delivered and signal handler would
+# dereference the TLS pointer. While it's never the case in openssl
+# application or test suite, we have to respect this scenario and not
+# use TLS pointer register. Alternative would be to require caller to
+# block signals prior calling this routine. For the record, in 32-bit
+# context R2 serves as TLS pointer, while in 64-bit context - R13.
+
+$flavour=shift;
+$output =shift;
+
+if ($flavour =~ /64/) {
+	$SIZE_T=8;
+	$STU="stdu";
+	$UCMP="cmpld";
+	$SHL="sldi";
+	$POP="ld";
+	$PUSH="std";
+} elsif ($flavour =~ /32/) {
+	$SIZE_T=4;
+	$STU="stwu";
+	$UCMP="cmplw";
+	$SHL="slwi";
+	$POP="lwz";
+	$PUSH="stw";
+} else { die "nonsense $flavour"; }
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!";
+
+if ($output =~ /512/) {
+	$func="sha512_block_data_order";
+	$SZ=8;
+	@Sigma0=(28,34,39);
+	@Sigma1=(14,18,41);
+	@sigma0=(1,  8, 7);
+	@sigma1=(19,61, 6);
+	$rounds=80;
+	$LD="ld";
+	$ST="std";
+	$ROR="rotrdi";
+	$SHR="srdi";
+} else {
+	$func="sha256_block_data_order";
+	$SZ=4;
+	@Sigma0=( 2,13,22);
+	@Sigma1=( 6,11,25);
+	@sigma0=( 7,18, 3);
+	@sigma1=(17,19,10);
+	$rounds=64;
+	$LD="lwz";
+	$ST="stw";
+	$ROR="rotrwi";
+	$SHR="srwi";
+}
+
+$FRAME=32*$SIZE_T;
+
+$sp ="r1";
+$toc="r2";
+$ctx="r3";	# zapped by $a0
+$inp="r4";	# zapped by $a1
+$num="r5";	# zapped by $t0
+
+$T  ="r0";
+$a0 ="r3";
+$a1 ="r4";
+$t0 ="r5";
+$t1 ="r6";
+$Tbl="r7";
+
+$A  ="r8";
+$B  ="r9";
+$C  ="r10";
+$D  ="r11";
+$E  ="r12";
+$F  ="r13";	$F="r2" if ($SIZE_T==8);# reassigned to exempt TLS pointer
+$G  ="r14";
+$H  ="r15";
+
+@V=($A,$B,$C,$D,$E,$F,$G,$H);
+@X=("r16","r17","r18","r19","r20","r21","r22","r23",
+    "r24","r25","r26","r27","r28","r29","r30","r31");
+
+$inp="r31";	# reassigned $inp! aliases with @X[15]
+
+sub ROUND_00_15 {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
+$code.=<<___;
+	$LD	$T,`$i*$SZ`($Tbl)
+	$ROR	$a0,$e,$Sigma1[0]
+	$ROR	$a1,$e,$Sigma1[1]
+	and	$t0,$f,$e
+	andc	$t1,$g,$e
+	add	$T,$T,$h
+	xor	$a0,$a0,$a1
+	$ROR	$a1,$a1,`$Sigma1[2]-$Sigma1[1]`
+	or	$t0,$t0,$t1		; Ch(e,f,g)
+	add	$T,$T,@X[$i]
+	xor	$a0,$a0,$a1		; Sigma1(e)
+	add	$T,$T,$t0
+	add	$T,$T,$a0
+
+	$ROR	$a0,$a,$Sigma0[0]
+	$ROR	$a1,$a,$Sigma0[1]
+	and	$t0,$a,$b
+	and	$t1,$a,$c
+	xor	$a0,$a0,$a1
+	$ROR	$a1,$a1,`$Sigma0[2]-$Sigma0[1]`
+	xor	$t0,$t0,$t1
+	and	$t1,$b,$c
+	xor	$a0,$a0,$a1		; Sigma0(a)
+	add	$d,$d,$T
+	xor	$t0,$t0,$t1		; Maj(a,b,c)
+	add	$h,$T,$a0
+	add	$h,$h,$t0
+
+___
+}
+
+sub ROUND_16_xx {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
+$i-=16;
+$code.=<<___;
+	$ROR	$a0,@X[($i+1)%16],$sigma0[0]
+	$ROR	$a1,@X[($i+1)%16],$sigma0[1]
+	$ROR	$t0,@X[($i+14)%16],$sigma1[0]
+	$ROR	$t1,@X[($i+14)%16],$sigma1[1]
+	xor	$a0,$a0,$a1
+	$SHR	$a1,@X[($i+1)%16],$sigma0[2]
+	xor	$t0,$t0,$t1
+	$SHR	$t1,@X[($i+14)%16],$sigma1[2]
+	add	@X[$i],@X[$i],@X[($i+9)%16]
+	xor	$a0,$a0,$a1		; sigma0(X[(i+1)&0x0f])
+	xor	$t0,$t0,$t1		; sigma1(X[(i+14)&0x0f])
+	add	@X[$i],@X[$i],$a0
+	add	@X[$i],@X[$i],$t0
+___
+&ROUND_00_15($i,$a,$b,$c,$d,$e,$f,$g,$h);
+}
+
+$code=<<___;
+.machine	"any"
+.text
+
+.globl	$func
+.align	6
+$func:
+	mflr	r0
+	$STU	$sp,`-($FRAME+16*$SZ)`($sp)
+	$SHL	$num,$num,`log(16*$SZ)/log(2)`
+
+	$PUSH	$ctx,`$FRAME-$SIZE_T*22`($sp)
+
+	$PUSH	r0,`$FRAME-$SIZE_T*21`($sp)
+	$PUSH	$toc,`$FRAME-$SIZE_T*20`($sp)
+	$PUSH	r13,`$FRAME-$SIZE_T*19`($sp)
+	$PUSH	r14,`$FRAME-$SIZE_T*18`($sp)
+	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
+	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
+	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
+	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
+	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
+	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
+	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
+	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
+	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
+	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
+	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
+	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
+	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
+
+	$LD	$A,`0*$SZ`($ctx)
+	mr	$inp,r4				; incarnate $inp
+	$LD	$B,`1*$SZ`($ctx)
+	$LD	$C,`2*$SZ`($ctx)
+	$LD	$D,`3*$SZ`($ctx)
+	$LD	$E,`4*$SZ`($ctx)
+	$LD	$F,`5*$SZ`($ctx)
+	$LD	$G,`6*$SZ`($ctx)
+	$LD	$H,`7*$SZ`($ctx)
+
+	b	LPICmeup
+LPICedup:
+	andi.	r0,$inp,3
+	bne	Lunaligned
+Laligned:
+	add	$num,$inp,$num
+	$PUSH	$num,`$FRAME-$SIZE_T*24`($sp)	; end pointer
+	$PUSH	$inp,`$FRAME-$SIZE_T*23`($sp)	; inp pointer
+	bl	Lsha2_block_private
+Ldone:
+	$POP	r0,`$FRAME-$SIZE_T*21`($sp)
+	$POP	$toc,`$FRAME-$SIZE_T*20`($sp)
+	$POP	r13,`$FRAME-$SIZE_T*19`($sp)
+	$POP	r14,`$FRAME-$SIZE_T*18`($sp)
+	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
+	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
+	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
+	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
+	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
+	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
+	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
+	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
+	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
+	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
+	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
+	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
+	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
+	mtlr	r0
+	addi	$sp,$sp,`$FRAME+16*$SZ`
+	blr
+___
+
+# PowerPC specification allows an implementation to be ill-behaved
+# upon unaligned access which crosses page boundary. "Better safe
+# than sorry" principle makes me treat it specially. But I don't
+# look for particular offending word, but rather for the input
+# block which crosses the boundary. Once found that block is aligned
+# and hashed separately...
+$code.=<<___;
+.align	4
+Lunaligned:
+	subfic	$t1,$inp,4096
+	andi.	$t1,$t1,`4096-16*$SZ`	; distance to closest page boundary
+	beq	Lcross_page
+	$UCMP	$num,$t1
+	ble-	Laligned		; didn't cross the page boundary
+	subfc	$num,$t1,$num
+	add	$t1,$inp,$t1
+	$PUSH	$num,`$FRAME-$SIZE_T*25`($sp)	; save real remaining num
+	$PUSH	$t1,`$FRAME-$SIZE_T*24`($sp)	; intermediate end pointer
+	$PUSH	$inp,`$FRAME-$SIZE_T*23`($sp)	; inp pointer
+	bl	Lsha2_block_private
+	; $inp equals to the intermediate end pointer here
+	$POP	$num,`$FRAME-$SIZE_T*25`($sp)	; restore real remaining num
+Lcross_page:
+	li	$t1,`16*$SZ/4`
+	mtctr	$t1
+	addi	r20,$sp,$FRAME			; aligned spot below the frame
+Lmemcpy:
+	lbz	r16,0($inp)
+	lbz	r17,1($inp)
+	lbz	r18,2($inp)
+	lbz	r19,3($inp)
+	addi	$inp,$inp,4
+	stb	r16,0(r20)
+	stb	r17,1(r20)
+	stb	r18,2(r20)
+	stb	r19,3(r20)
+	addi	r20,r20,4
+	bdnz	Lmemcpy
+
+	$PUSH	$inp,`$FRAME-$SIZE_T*26`($sp)	; save real inp
+	addi	$t1,$sp,`$FRAME+16*$SZ`		; fictitious end pointer
+	addi	$inp,$sp,$FRAME			; fictitious inp pointer
+	$PUSH	$num,`$FRAME-$SIZE_T*25`($sp)	; save real num
+	$PUSH	$t1,`$FRAME-$SIZE_T*24`($sp)	; end pointer
+	$PUSH	$inp,`$FRAME-$SIZE_T*23`($sp)	; inp pointer
+	bl	Lsha2_block_private
+	$POP	$inp,`$FRAME-$SIZE_T*26`($sp)	; restore real inp
+	$POP	$num,`$FRAME-$SIZE_T*25`($sp)	; restore real num
+	addic.	$num,$num,`-16*$SZ`		; num--
+	bne-	Lunaligned
+	b	Ldone
+___
+
+$code.=<<___;
+.align	4
+Lsha2_block_private:
+___
+for($i=0;$i<16;$i++) {
+$code.=<<___ if ($SZ==4);
+	lwz	@X[$i],`$i*$SZ`($inp)
+___
+# 64-bit loads are split to 2x32-bit ones, as CPU can't handle
+# unaligned 64-bit loads, only 32-bit ones...
+$code.=<<___ if ($SZ==8);
+	lwz	$t0,`$i*$SZ`($inp)
+	lwz	@X[$i],`$i*$SZ+4`($inp)
+	insrdi	@X[$i],$t0,32,0
+___
+	&ROUND_00_15($i,@V);
+	unshift(@V,pop(@V));
+}
+$code.=<<___;
+	li	$T,`$rounds/16-1`
+	mtctr	$T
+.align	4
+Lrounds:
+	addi	$Tbl,$Tbl,`16*$SZ`
+___
+for(;$i<32;$i++) {
+	&ROUND_16_xx($i,@V);
+	unshift(@V,pop(@V));
+}
+$code.=<<___;
+	bdnz-	Lrounds
+
+	$POP	$ctx,`$FRAME-$SIZE_T*22`($sp)
+	$POP	$inp,`$FRAME-$SIZE_T*23`($sp)	; inp pointer
+	$POP	$num,`$FRAME-$SIZE_T*24`($sp)	; end pointer
+	subi	$Tbl,$Tbl,`($rounds-16)*$SZ`	; rewind Tbl
+
+	$LD	r16,`0*$SZ`($ctx)
+	$LD	r17,`1*$SZ`($ctx)
+	$LD	r18,`2*$SZ`($ctx)
+	$LD	r19,`3*$SZ`($ctx)
+	$LD	r20,`4*$SZ`($ctx)
+	$LD	r21,`5*$SZ`($ctx)
+	$LD	r22,`6*$SZ`($ctx)
+	addi	$inp,$inp,`16*$SZ`		; advance inp
+	$LD	r23,`7*$SZ`($ctx)
+	add	$A,$A,r16
+	add	$B,$B,r17
+	$PUSH	$inp,`$FRAME-$SIZE_T*23`($sp)
+	add	$C,$C,r18
+	$ST	$A,`0*$SZ`($ctx)
+	add	$D,$D,r19
+	$ST	$B,`1*$SZ`($ctx)
+	add	$E,$E,r20
+	$ST	$C,`2*$SZ`($ctx)
+	add	$F,$F,r21
+	$ST	$D,`3*$SZ`($ctx)
+	add	$G,$G,r22
+	$ST	$E,`4*$SZ`($ctx)
+	add	$H,$H,r23
+	$ST	$F,`5*$SZ`($ctx)
+	$ST	$G,`6*$SZ`($ctx)
+	$UCMP	$inp,$num
+	$ST	$H,`7*$SZ`($ctx)
+	bne	Lsha2_block_private
+	blr
+___
+
+# Ugly hack here, because PPC assembler syntax seem to vary too
+# much from platforms to platform...
+$code.=<<___;
+.align	6
+LPICmeup:
+	bl	LPIC
+	addi	$Tbl,$Tbl,`64-4`	; "distance" between . and last nop
+	b	LPICedup
+	nop
+	nop
+	nop
+	nop
+	nop
+LPIC:	mflr	$Tbl
+	blr
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+___
+$code.=<<___ if ($SZ==8);
+	.long	0x428a2f98,0xd728ae22,0x71374491,0x23ef65cd
+	.long	0xb5c0fbcf,0xec4d3b2f,0xe9b5dba5,0x8189dbbc
+	.long	0x3956c25b,0xf348b538,0x59f111f1,0xb605d019
+	.long	0x923f82a4,0xaf194f9b,0xab1c5ed5,0xda6d8118
+	.long	0xd807aa98,0xa3030242,0x12835b01,0x45706fbe
+	.long	0x243185be,0x4ee4b28c,0x550c7dc3,0xd5ffb4e2
+	.long	0x72be5d74,0xf27b896f,0x80deb1fe,0x3b1696b1
+	.long	0x9bdc06a7,0x25c71235,0xc19bf174,0xcf692694
+	.long	0xe49b69c1,0x9ef14ad2,0xefbe4786,0x384f25e3
+	.long	0x0fc19dc6,0x8b8cd5b5,0x240ca1cc,0x77ac9c65
+	.long	0x2de92c6f,0x592b0275,0x4a7484aa,0x6ea6e483
+	.long	0x5cb0a9dc,0xbd41fbd4,0x76f988da,0x831153b5
+	.long	0x983e5152,0xee66dfab,0xa831c66d,0x2db43210
+	.long	0xb00327c8,0x98fb213f,0xbf597fc7,0xbeef0ee4
+	.long	0xc6e00bf3,0x3da88fc2,0xd5a79147,0x930aa725
+	.long	0x06ca6351,0xe003826f,0x14292967,0x0a0e6e70
+	.long	0x27b70a85,0x46d22ffc,0x2e1b2138,0x5c26c926
+	.long	0x4d2c6dfc,0x5ac42aed,0x53380d13,0x9d95b3df
+	.long	0x650a7354,0x8baf63de,0x766a0abb,0x3c77b2a8
+	.long	0x81c2c92e,0x47edaee6,0x92722c85,0x1482353b
+	.long	0xa2bfe8a1,0x4cf10364,0xa81a664b,0xbc423001
+	.long	0xc24b8b70,0xd0f89791,0xc76c51a3,0x0654be30
+	.long	0xd192e819,0xd6ef5218,0xd6990624,0x5565a910
+	.long	0xf40e3585,0x5771202a,0x106aa070,0x32bbd1b8
+	.long	0x19a4c116,0xb8d2d0c8,0x1e376c08,0x5141ab53
+	.long	0x2748774c,0xdf8eeb99,0x34b0bcb5,0xe19b48a8
+	.long	0x391c0cb3,0xc5c95a63,0x4ed8aa4a,0xe3418acb
+	.long	0x5b9cca4f,0x7763e373,0x682e6ff3,0xd6b2b8a3
+	.long	0x748f82ee,0x5defb2fc,0x78a5636f,0x43172f60
+	.long	0x84c87814,0xa1f0ab72,0x8cc70208,0x1a6439ec
+	.long	0x90befffa,0x23631e28,0xa4506ceb,0xde82bde9
+	.long	0xbef9a3f7,0xb2c67915,0xc67178f2,0xe372532b
+	.long	0xca273ece,0xea26619c,0xd186b8c7,0x21c0c207
+	.long	0xeada7dd6,0xcde0eb1e,0xf57d4f7f,0xee6ed178
+	.long	0x06f067aa,0x72176fba,0x0a637dc5,0xa2c898a6
+	.long	0x113f9804,0xbef90dae,0x1b710b35,0x131c471b
+	.long	0x28db77f5,0x23047d84,0x32caab7b,0x40c72493
+	.long	0x3c9ebe0a,0x15c9bebc,0x431d67c4,0x9c100d4c
+	.long	0x4cc5d4be,0xcb3e42b6,0x597f299c,0xfc657e2a
+	.long	0x5fcb6fab,0x3ad6faec,0x6c44198c,0x4a475817
+___
+$code.=<<___ if ($SZ==4);
+	.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+	.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+	.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+	.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+	.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+	.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+	.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+	.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+	.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+	.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+	.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+	.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+	.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+	.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+	.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+	.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/sha/asm/sha512-s390x.pl b/openssl/crypto/sha/asm/sha512-s390x.pl
new file mode 100644
index 0000000..e7ef2d5
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha512-s390x.pl
@@ -0,0 +1,301 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# SHA256/512 block procedures for s390x.
+
+# April 2007.
+#
+# sha256_block_data_order is reportedly >3 times faster than gcc 3.3
+# generated code (must be a bug in compiler, as improvement is
+# "pathologically" high, in particular in comparison to other SHA
+# modules). But the real twist is that it detects if hardware support
+# for SHA256 is available and in such case utilizes it. Then the
+# performance can reach >6.5x of assembler one for larger chunks.
+#
+# sha512_block_data_order is ~70% faster than gcc 3.3 generated code.
+
+# January 2009.
+#
+# Add support for hardware SHA512 and reschedule instructions to
+# favour dual-issue z10 pipeline. Hardware SHA256/512 is ~4.7x faster
+# than software.
+
+$t0="%r0";
+$t1="%r1";
+$ctx="%r2";	$t2="%r2";
+$inp="%r3";
+$len="%r4";	# used as index in inner loop
+
+$A="%r5";
+$B="%r6";
+$C="%r7";
+$D="%r8";
+$E="%r9";
+$F="%r10";
+$G="%r11";
+$H="%r12";	@V=($A,$B,$C,$D,$E,$F,$G,$H);
+$tbl="%r13";
+$T1="%r14";
+$sp="%r15";
+
+$output=shift;
+open STDOUT,">$output";
+
+if ($output =~ /512/) {
+	$label="512";
+	$SZ=8;
+	$LD="lg";	# load from memory
+	$ST="stg";	# store to memory
+	$ADD="alg";	# add with memory operand
+	$ROT="rllg";	# rotate left
+	$SHR="srlg";	# logical right shift [see even at the end]
+	@Sigma0=(25,30,36);
+	@Sigma1=(23,46,50);
+	@sigma0=(56,63, 7);
+	@sigma1=( 3,45, 6);
+	$rounds=80;
+	$kimdfunc=3;	# 0 means unknown/unsupported/unimplemented/disabled
+} else {
+	$label="256";
+	$SZ=4;
+	$LD="llgf";	# load from memory
+	$ST="st";	# store to memory
+	$ADD="al";	# add with memory operand
+	$ROT="rll";	# rotate left
+	$SHR="srl";	# logical right shift
+	@Sigma0=(10,19,30);
+	@Sigma1=( 7,21,26);
+	@sigma0=(14,25, 3);
+	@sigma1=(13,15,10);
+	$rounds=64;
+	$kimdfunc=2;	# magic function code for kimd instruction
+}
+$Func="sha${label}_block_data_order";
+$Table="K${label}";
+$frame=160+16*$SZ;
+
+sub BODY_00_15 {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
+
+$code.=<<___ if ($i<16);
+	$LD	$T1,`$i*$SZ`($inp)	### $i
+___
+$code.=<<___;
+	$ROT	$t0,$e,$Sigma1[0]
+	$ROT	$t1,$e,$Sigma1[1]
+	 lgr	$t2,$f
+	xgr	$t0,$t1
+	$ROT	$t1,$t1,`$Sigma1[2]-$Sigma1[1]`
+	 xgr	$t2,$g
+	$ST	$T1,`160+$SZ*($i%16)`($sp)
+	xgr	$t0,$t1			# Sigma1(e)
+	la	$T1,0($T1,$h)		# T1+=h
+	 ngr	$t2,$e
+	 lgr	$t1,$a
+	algr	$T1,$t0			# T1+=Sigma1(e)
+	$ROT	$h,$a,$Sigma0[0]
+	 xgr	$t2,$g			# Ch(e,f,g)
+	$ADD	$T1,`$i*$SZ`($len,$tbl)	# T1+=K[i]
+	$ROT	$t0,$a,$Sigma0[1]
+	algr	$T1,$t2			# T1+=Ch(e,f,g)
+	 ogr	$t1,$b
+	xgr	$h,$t0
+	 lgr	$t2,$a
+	 ngr	$t1,$c
+	$ROT	$t0,$t0,`$Sigma0[2]-$Sigma0[1]`
+	xgr	$h,$t0			# h=Sigma0(a)
+	 ngr	$t2,$b
+	algr	$h,$T1			# h+=T1
+	 ogr	$t2,$t1			# Maj(a,b,c)
+	la	$d,0($d,$T1)		# d+=T1
+	algr	$h,$t2			# h+=Maj(a,b,c)
+___
+}
+
+sub BODY_16_XX {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
+
+$code.=<<___;
+	$LD	$T1,`160+$SZ*(($i+1)%16)`($sp)	### $i
+	$LD	$t1,`160+$SZ*(($i+14)%16)`($sp)
+	$ROT	$t0,$T1,$sigma0[0]
+	$SHR	$T1,$sigma0[2]
+	$ROT	$t2,$t0,`$sigma0[1]-$sigma0[0]`
+	xgr	$T1,$t0
+	$ROT	$t0,$t1,$sigma1[0]
+	xgr	$T1,$t2				# sigma0(X[i+1])
+	$SHR	$t1,$sigma1[2]
+	$ADD	$T1,`160+$SZ*($i%16)`($sp)	# +=X[i]
+	xgr	$t1,$t0
+	$ROT	$t0,$t0,`$sigma1[1]-$sigma1[0]`
+	$ADD	$T1,`160+$SZ*(($i+9)%16)`($sp)	# +=X[i+9]
+	xgr	$t1,$t0				# sigma1(X[i+14])
+	algr	$T1,$t1				# +=sigma1(X[i+14])
+___
+	&BODY_00_15(@_);
+}
+
+$code.=<<___;
+.text
+.align	64
+.type	$Table,\@object
+$Table:
+___
+$code.=<<___ if ($SZ==4);
+	.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+	.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+	.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+	.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+	.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+	.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+	.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+	.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+	.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+	.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+	.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+	.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+	.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+	.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+	.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+	.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+___
+$code.=<<___ if ($SZ==8);
+	.quad	0x428a2f98d728ae22,0x7137449123ef65cd
+	.quad	0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
+	.quad	0x3956c25bf348b538,0x59f111f1b605d019
+	.quad	0x923f82a4af194f9b,0xab1c5ed5da6d8118
+	.quad	0xd807aa98a3030242,0x12835b0145706fbe
+	.quad	0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
+	.quad	0x72be5d74f27b896f,0x80deb1fe3b1696b1
+	.quad	0x9bdc06a725c71235,0xc19bf174cf692694
+	.quad	0xe49b69c19ef14ad2,0xefbe4786384f25e3
+	.quad	0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
+	.quad	0x2de92c6f592b0275,0x4a7484aa6ea6e483
+	.quad	0x5cb0a9dcbd41fbd4,0x76f988da831153b5
+	.quad	0x983e5152ee66dfab,0xa831c66d2db43210
+	.quad	0xb00327c898fb213f,0xbf597fc7beef0ee4
+	.quad	0xc6e00bf33da88fc2,0xd5a79147930aa725
+	.quad	0x06ca6351e003826f,0x142929670a0e6e70
+	.quad	0x27b70a8546d22ffc,0x2e1b21385c26c926
+	.quad	0x4d2c6dfc5ac42aed,0x53380d139d95b3df
+	.quad	0x650a73548baf63de,0x766a0abb3c77b2a8
+	.quad	0x81c2c92e47edaee6,0x92722c851482353b
+	.quad	0xa2bfe8a14cf10364,0xa81a664bbc423001
+	.quad	0xc24b8b70d0f89791,0xc76c51a30654be30
+	.quad	0xd192e819d6ef5218,0xd69906245565a910
+	.quad	0xf40e35855771202a,0x106aa07032bbd1b8
+	.quad	0x19a4c116b8d2d0c8,0x1e376c085141ab53
+	.quad	0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
+	.quad	0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
+	.quad	0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
+	.quad	0x748f82ee5defb2fc,0x78a5636f43172f60
+	.quad	0x84c87814a1f0ab72,0x8cc702081a6439ec
+	.quad	0x90befffa23631e28,0xa4506cebde82bde9
+	.quad	0xbef9a3f7b2c67915,0xc67178f2e372532b
+	.quad	0xca273eceea26619c,0xd186b8c721c0c207
+	.quad	0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
+	.quad	0x06f067aa72176fba,0x0a637dc5a2c898a6
+	.quad	0x113f9804bef90dae,0x1b710b35131c471b
+	.quad	0x28db77f523047d84,0x32caab7b40c72493
+	.quad	0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
+	.quad	0x4cc5d4becb3e42b6,0x597f299cfc657e2a
+	.quad	0x5fcb6fab3ad6faec,0x6c44198c4a475817
+___
+$code.=<<___;
+.size	$Table,.-$Table
+.globl	$Func
+.type	$Func,\@function
+$Func:
+___
+$code.=<<___ if ($kimdfunc);
+	larl	%r1,OPENSSL_s390xcap_P
+	lg	%r0,0(%r1)
+	tmhl	%r0,0x4000	# check for message-security assist
+	jz	.Lsoftware
+	lghi	%r0,0
+	la	%r1,16($sp)
+	.long	0xb93e0002	# kimd %r0,%r2
+	lg	%r0,16($sp)
+	tmhh	%r0,`0x8000>>$kimdfunc`
+	jz	.Lsoftware
+	lghi	%r0,$kimdfunc
+	lgr	%r1,$ctx
+	lgr	%r2,$inp
+	sllg	%r3,$len,`log(16*$SZ)/log(2)`
+	.long	0xb93e0002	# kimd %r0,%r2
+	brc	1,.-4		# pay attention to "partial completion"
+	br	%r14
+.align	16
+.Lsoftware:
+___
+$code.=<<___;
+	sllg	$len,$len,`log(16*$SZ)/log(2)`
+	lghi	%r1,-$frame
+	agr	$len,$inp
+	stmg	$ctx,%r15,16($sp)
+	lgr	%r0,$sp
+	la	$sp,0(%r1,$sp)
+	stg	%r0,0($sp)
+
+	larl	$tbl,$Table
+	$LD	$A,`0*$SZ`($ctx)
+	$LD	$B,`1*$SZ`($ctx)
+	$LD	$C,`2*$SZ`($ctx)
+	$LD	$D,`3*$SZ`($ctx)
+	$LD	$E,`4*$SZ`($ctx)
+	$LD	$F,`5*$SZ`($ctx)
+	$LD	$G,`6*$SZ`($ctx)
+	$LD	$H,`7*$SZ`($ctx)
+
+.Lloop:
+	lghi	$len,0
+___
+for ($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
+$code.=".Lrounds_16_xx:\n";
+for (;$i<32;$i++)	{ &BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+	aghi	$len,`16*$SZ`
+	lghi	$t0,`($rounds-16)*$SZ`
+	clgr	$len,$t0
+	jne	.Lrounds_16_xx
+
+	lg	$ctx,`$frame+16`($sp)
+	la	$inp,`16*$SZ`($inp)
+	$ADD	$A,`0*$SZ`($ctx)
+	$ADD	$B,`1*$SZ`($ctx)
+	$ADD	$C,`2*$SZ`($ctx)
+	$ADD	$D,`3*$SZ`($ctx)
+	$ADD	$E,`4*$SZ`($ctx)
+	$ADD	$F,`5*$SZ`($ctx)
+	$ADD	$G,`6*$SZ`($ctx)
+	$ADD	$H,`7*$SZ`($ctx)
+	$ST	$A,`0*$SZ`($ctx)
+	$ST	$B,`1*$SZ`($ctx)
+	$ST	$C,`2*$SZ`($ctx)
+	$ST	$D,`3*$SZ`($ctx)
+	$ST	$E,`4*$SZ`($ctx)
+	$ST	$F,`5*$SZ`($ctx)
+	$ST	$G,`6*$SZ`($ctx)
+	$ST	$H,`7*$SZ`($ctx)
+	clg	$inp,`$frame+32`($sp)
+	jne	.Lloop
+
+	lmg	%r6,%r15,`$frame+48`($sp)	
+	br	%r14
+.size	$Func,.-$Func
+.string	"SHA${label} block transform for s390x, CRYPTOGAMS by <appro\@openssl.org>"
+.comm	OPENSSL_s390xcap_P,8,8
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+# unlike 32-bit shift 64-bit one takes three arguments
+$code =~ s/(srlg\s+)(%r[0-9]+),/$1$2,$2,/gm;
+
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/sha/asm/sha512-sparcv9.pl b/openssl/crypto/sha/asm/sha512-sparcv9.pl
new file mode 100644
index 0000000..ec5d781
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha512-sparcv9.pl
@@ -0,0 +1,594 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# SHA256 performance improvement over compiler generated code varies
+# from 40% for Sun C [32-bit build] to 70% for gcc [3.3, 64-bit
+# build]. Just like in SHA1 module I aim to ensure scalability on
+# UltraSPARC T1 by packing X[16] to 8 64-bit registers.
+
+# SHA512 on pre-T1 UltraSPARC.
+#
+# Performance is >75% better than 64-bit code generated by Sun C and
+# over 2x than 32-bit code. X[16] resides on stack, but access to it
+# is scheduled for L2 latency and staged through 32 least significant
+# bits of %l0-%l7. The latter is done to achieve 32-/64-bit ABI
+# duality. Nevetheless it's ~40% faster than SHA256, which is pretty
+# good [optimal coefficient is 50%].
+#
+# SHA512 on UltraSPARC T1.
+#
+# It's not any faster than 64-bit code generated by Sun C 5.8. This is
+# because 64-bit code generator has the advantage of using 64-bit
+# loads(*) to access X[16], which I consciously traded for 32-/64-bit
+# ABI duality [as per above]. But it surpasses 32-bit Sun C generated
+# code by 60%, not to mention that it doesn't suffer from severe decay
+# when running 4 times physical cores threads and that it leaves gcc
+# [3.4] behind by over 4x factor! If compared to SHA256, single thread
+# performance is only 10% better, but overall throughput for maximum
+# amount of threads for given CPU exceeds corresponding one of SHA256
+# by 30% [again, optimal coefficient is 50%].
+#
+# (*)	Unlike pre-T1 UltraSPARC loads on T1 are executed strictly
+#	in-order, i.e. load instruction has to complete prior next
+#	instruction in given thread is executed, even if the latter is
+#	not dependent on load result! This means that on T1 two 32-bit
+#	loads are always slower than one 64-bit load. Once again this
+#	is unlike pre-T1 UltraSPARC, where, if scheduled appropriately,
+#	2x32-bit loads can be as fast as 1x64-bit ones.
+
+$bits=32;
+for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
+if ($bits==64)	{ $bias=2047; $frame=192; }
+else		{ $bias=0;    $frame=112; }
+
+$output=shift;
+open STDOUT,">$output";
+
+if ($output =~ /512/) {
+	$label="512";
+	$SZ=8;
+	$LD="ldx";		# load from memory
+	$ST="stx";		# store to memory
+	$SLL="sllx";		# shift left logical
+	$SRL="srlx";		# shift right logical
+	@Sigma0=(28,34,39);
+	@Sigma1=(14,18,41);
+	@sigma0=( 7, 1, 8);	# right shift first
+	@sigma1=( 6,19,61);	# right shift first
+	$lastK=0x817;
+	$rounds=80;
+	$align=4;
+
+	$locals=16*$SZ;		# X[16]
+
+	$A="%o0";
+	$B="%o1";
+	$C="%o2";
+	$D="%o3";
+	$E="%o4";
+	$F="%o5";
+	$G="%g1";
+	$H="%o7";
+	@V=($A,$B,$C,$D,$E,$F,$G,$H);
+} else {
+	$label="256";
+	$SZ=4;
+	$LD="ld";		# load from memory
+	$ST="st";		# store to memory
+	$SLL="sll";		# shift left logical
+	$SRL="srl";		# shift right logical
+	@Sigma0=( 2,13,22);
+	@Sigma1=( 6,11,25);
+	@sigma0=( 3, 7,18);	# right shift first
+	@sigma1=(10,17,19);	# right shift first
+	$lastK=0x8f2;
+	$rounds=64;
+	$align=8;
+
+	$locals=0;		# X[16] is register resident
+	@X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7");
+	
+	$A="%l0";
+	$B="%l1";
+	$C="%l2";
+	$D="%l3";
+	$E="%l4";
+	$F="%l5";
+	$G="%l6";
+	$H="%l7";
+	@V=($A,$B,$C,$D,$E,$F,$G,$H);
+}
+$T1="%g2";
+$tmp0="%g3";
+$tmp1="%g4";
+$tmp2="%g5";
+
+$ctx="%i0";
+$inp="%i1";
+$len="%i2";
+$Ktbl="%i3";
+$tmp31="%i4";
+$tmp32="%i5";
+
+########### SHA256
+$Xload = sub {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
+
+    if ($i==0) {
+$code.=<<___;
+	ldx	[$inp+0],@X[0]
+	ldx	[$inp+16],@X[2]
+	ldx	[$inp+32],@X[4]
+	ldx	[$inp+48],@X[6]
+	ldx	[$inp+8],@X[1]
+	ldx	[$inp+24],@X[3]
+	subcc	%g0,$tmp31,$tmp32 ! should be 64-$tmp31, but -$tmp31 works too
+	ldx	[$inp+40],@X[5]
+	bz,pt	%icc,.Laligned
+	ldx	[$inp+56],@X[7]
+
+	sllx	@X[0],$tmp31,@X[0]
+	ldx	[$inp+64],$T1
+___
+for($j=0;$j<7;$j++)
+{   $code.=<<___;
+	srlx	@X[$j+1],$tmp32,$tmp1
+	sllx	@X[$j+1],$tmp31,@X[$j+1]
+	or	$tmp1,@X[$j],@X[$j]
+___
+}
+$code.=<<___;
+	srlx	$T1,$tmp32,$T1
+	or	$T1,@X[7],@X[7]
+.Laligned:
+___
+    }
+
+    if ($i&1) {
+	$code.="\tadd	@X[$i/2],$h,$T1\n";
+    } else {
+	$code.="\tsrlx	@X[$i/2],32,$T1\n\tadd	$h,$T1,$T1\n";
+    }
+} if ($SZ==4);
+
+########### SHA512
+$Xload = sub {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
+my @pair=("%l".eval(($i*2)%8),"%l".eval(($i*2)%8+1),"%l".eval((($i+1)*2)%8));
+
+$code.=<<___ if ($i==0);
+	ld	[$inp+0],%l0
+	ld	[$inp+4],%l1
+	ld	[$inp+8],%l2
+	ld	[$inp+12],%l3
+	ld	[$inp+16],%l4
+	ld	[$inp+20],%l5
+	ld	[$inp+24],%l6
+	ld	[$inp+28],%l7
+___
+$code.=<<___ if ($i<15);
+	sllx	@pair[1],$tmp31,$tmp2	! Xload($i)
+	add	$tmp31,32,$tmp0
+	sllx	@pair[0],$tmp0,$tmp1
+	`"ld	[$inp+".eval(32+0+$i*8)."],@pair[0]"	if ($i<12)`
+	srlx	@pair[2],$tmp32,@pair[1]
+	or	$tmp1,$tmp2,$tmp2
+	or	@pair[1],$tmp2,$tmp2
+	`"ld	[$inp+".eval(32+4+$i*8)."],@pair[1]"	if ($i<12)`
+	add	$h,$tmp2,$T1
+	$ST	$tmp2,[%sp+`$bias+$frame+$i*$SZ`]
+___
+$code.=<<___ if ($i==12);
+	brnz,a	$tmp31,.+8
+	ld	[$inp+128],%l0
+___
+$code.=<<___ if ($i==15);
+	ld	[%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+0`],%l2
+	sllx	@pair[1],$tmp31,$tmp2	! Xload($i)
+	add	$tmp31,32,$tmp0
+	ld	[%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+4`],%l3
+	sllx	@pair[0],$tmp0,$tmp1
+	ld	[%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+0`],%l4
+	srlx	@pair[2],$tmp32,@pair[1]
+	or	$tmp1,$tmp2,$tmp2
+	ld	[%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+4`],%l5
+	or	@pair[1],$tmp2,$tmp2
+	ld	[%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+0`],%l6
+	add	$h,$tmp2,$T1
+	$ST	$tmp2,[%sp+`$bias+$frame+$i*$SZ`]
+	ld	[%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+4`],%l7
+	ld	[%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+0`],%l0
+	ld	[%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+4`],%l1
+___
+} if ($SZ==8);
+
+########### common
+sub BODY_00_15 {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
+
+    if ($i<16) {
+	&$Xload(@_);
+    } else {
+	$code.="\tadd	$h,$T1,$T1\n";
+    }
+
+$code.=<<___;
+	$SRL	$e,@Sigma1[0],$h	!! $i
+	xor	$f,$g,$tmp2
+	$SLL	$e,`$SZ*8-@Sigma1[2]`,$tmp1
+	and	$e,$tmp2,$tmp2
+	$SRL	$e,@Sigma1[1],$tmp0
+	xor	$tmp1,$h,$h
+	$SLL	$e,`$SZ*8-@Sigma1[1]`,$tmp1
+	xor	$tmp0,$h,$h
+	$SRL	$e,@Sigma1[2],$tmp0
+	xor	$tmp1,$h,$h
+	$SLL	$e,`$SZ*8-@Sigma1[0]`,$tmp1
+	xor	$tmp0,$h,$h
+	xor	$g,$tmp2,$tmp2		! Ch(e,f,g)
+	xor	$tmp1,$h,$tmp0		! Sigma1(e)
+
+	$SRL	$a,@Sigma0[0],$h
+	add	$tmp2,$T1,$T1
+	$LD	[$Ktbl+`$i*$SZ`],$tmp2	! K[$i]
+	$SLL	$a,`$SZ*8-@Sigma0[2]`,$tmp1
+	add	$tmp0,$T1,$T1
+	$SRL	$a,@Sigma0[1],$tmp0
+	xor	$tmp1,$h,$h
+	$SLL	$a,`$SZ*8-@Sigma0[1]`,$tmp1
+	xor	$tmp0,$h,$h
+	$SRL	$a,@Sigma0[2],$tmp0
+	xor	$tmp1,$h,$h	
+	$SLL	$a,`$SZ*8-@Sigma0[0]`,$tmp1
+	xor	$tmp0,$h,$h
+	xor	$tmp1,$h,$h		! Sigma0(a)
+
+	or	$a,$b,$tmp0
+	and	$a,$b,$tmp1
+	and	$c,$tmp0,$tmp0
+	or	$tmp0,$tmp1,$tmp1	! Maj(a,b,c)
+	add	$tmp2,$T1,$T1		! +=K[$i]
+	add	$tmp1,$h,$h
+
+	add	$T1,$d,$d
+	add	$T1,$h,$h
+___
+}
+
+########### SHA256
+$BODY_16_XX = sub {
+my $i=@_[0];
+my $xi;
+
+    if ($i&1) {
+	$xi=$tmp32;
+	$code.="\tsrlx	@X[(($i+1)/2)%8],32,$xi\n";
+    } else {
+	$xi=@X[(($i+1)/2)%8];
+    }
+$code.=<<___;
+	srl	$xi,@sigma0[0],$T1		!! Xupdate($i)
+	sll	$xi,`32-@sigma0[2]`,$tmp1
+	srl	$xi,@sigma0[1],$tmp0
+	xor	$tmp1,$T1,$T1
+	sll	$tmp1,`@sigma0[2]-@sigma0[1]`,$tmp1
+	xor	$tmp0,$T1,$T1
+	srl	$xi,@sigma0[2],$tmp0
+	xor	$tmp1,$T1,$T1
+___
+    if ($i&1) {
+	$xi=@X[(($i+14)/2)%8];
+    } else {
+	$xi=$tmp32;
+	$code.="\tsrlx	@X[(($i+14)/2)%8],32,$xi\n";
+    }
+$code.=<<___;
+	srl	$xi,@sigma1[0],$tmp2
+	xor	$tmp0,$T1,$T1			! T1=sigma0(X[i+1])
+	sll	$xi,`32-@sigma1[2]`,$tmp1
+	srl	$xi,@sigma1[1],$tmp0
+	xor	$tmp1,$tmp2,$tmp2
+	sll	$tmp1,`@sigma1[2]-@sigma1[1]`,$tmp1
+	xor	$tmp0,$tmp2,$tmp2
+	srl	$xi,@sigma1[2],$tmp0
+	xor	$tmp1,$tmp2,$tmp2
+___
+    if ($i&1) {
+	$xi=@X[($i/2)%8];
+$code.=<<___;
+	srlx	@X[(($i+9)/2)%8],32,$tmp1	! X[i+9]
+	xor	$tmp0,$tmp2,$tmp2		! sigma1(X[i+14])
+	srl	@X[($i/2)%8],0,$tmp0
+	add	$xi,$T1,$T1			! +=X[i]
+	xor	$tmp0,@X[($i/2)%8],@X[($i/2)%8]
+	add	$tmp2,$T1,$T1
+	add	$tmp1,$T1,$T1
+
+	srl	$T1,0,$T1
+	or	$T1,@X[($i/2)%8],@X[($i/2)%8]
+___
+    } else {
+	$xi=@X[(($i+9)/2)%8];
+$code.=<<___;
+	srlx	@X[($i/2)%8],32,$tmp1		! X[i]
+	xor	$tmp0,$tmp2,$tmp2		! sigma1(X[i+14])
+	srl	@X[($i/2)%8],0,@X[($i/2)%8]
+	add	$xi,$T1,$T1			! +=X[i+9]
+	add	$tmp2,$T1,$T1
+	add	$tmp1,$T1,$T1
+
+	sllx	$T1,32,$tmp0
+	or	$tmp0,@X[($i/2)%8],@X[($i/2)%8]
+___
+    }
+    &BODY_00_15(@_);
+} if ($SZ==4);
+
+########### SHA512
+$BODY_16_XX = sub {
+my $i=@_[0];
+my @pair=("%l".eval(($i*2)%8),"%l".eval(($i*2)%8+1));
+
+$code.=<<___;
+	sllx	%l2,32,$tmp0		!! Xupdate($i)
+	or	%l3,$tmp0,$tmp0
+
+	srlx	$tmp0,@sigma0[0],$T1
+	ld	[%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+0`],%l2
+	sllx	$tmp0,`64-@sigma0[2]`,$tmp1
+	ld	[%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+4`],%l3
+	srlx	$tmp0,@sigma0[1],$tmp0
+	xor	$tmp1,$T1,$T1
+	sllx	$tmp1,`@sigma0[2]-@sigma0[1]`,$tmp1
+	xor	$tmp0,$T1,$T1
+	srlx	$tmp0,`@sigma0[2]-@sigma0[1]`,$tmp0
+	xor	$tmp1,$T1,$T1
+	sllx	%l6,32,$tmp2
+	xor	$tmp0,$T1,$T1		! sigma0(X[$i+1])
+	or	%l7,$tmp2,$tmp2
+
+	srlx	$tmp2,@sigma1[0],$tmp1
+	ld	[%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+0`],%l6
+	sllx	$tmp2,`64-@sigma1[2]`,$tmp0
+	ld	[%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+4`],%l7
+	srlx	$tmp2,@sigma1[1],$tmp2
+	xor	$tmp0,$tmp1,$tmp1
+	sllx	$tmp0,`@sigma1[2]-@sigma1[1]`,$tmp0
+	xor	$tmp2,$tmp1,$tmp1
+	srlx	$tmp2,`@sigma1[2]-@sigma1[1]`,$tmp2
+	xor	$tmp0,$tmp1,$tmp1
+	sllx	%l4,32,$tmp0
+	xor	$tmp2,$tmp1,$tmp1	! sigma1(X[$i+14])
+	ld	[%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+0`],%l4
+	or	%l5,$tmp0,$tmp0
+	ld	[%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+4`],%l5
+
+	sllx	%l0,32,$tmp2
+	add	$tmp1,$T1,$T1
+	ld	[%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+0`],%l0
+	or	%l1,$tmp2,$tmp2
+	add	$tmp0,$T1,$T1		! +=X[$i+9]
+	ld	[%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+4`],%l1
+	add	$tmp2,$T1,$T1		! +=X[$i]
+	$ST	$T1,[%sp+`$bias+$frame+($i%16)*$SZ`]
+___
+    &BODY_00_15(@_);
+} if ($SZ==8);
+
+$code.=<<___ if ($bits==64);
+.register	%g2,#scratch
+.register	%g3,#scratch
+___
+$code.=<<___;
+.section	".text",#alloc,#execinstr
+
+.align	64
+K${label}:
+.type	K${label},#object
+___
+if ($SZ==4) {
+$code.=<<___;
+	.long	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
+	.long	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
+	.long	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
+	.long	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
+	.long	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
+	.long	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
+	.long	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
+	.long	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
+	.long	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
+	.long	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
+	.long	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
+	.long	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
+	.long	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
+	.long	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
+	.long	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
+	.long	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+___
+} else {
+$code.=<<___;
+	.long	0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd
+	.long	0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc
+	.long	0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019
+	.long	0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118
+	.long	0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe
+	.long	0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2
+	.long	0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1
+	.long	0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694
+	.long	0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3
+	.long	0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65
+	.long	0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483
+	.long	0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5
+	.long	0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210
+	.long	0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4
+	.long	0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725
+	.long	0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70
+	.long	0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926
+	.long	0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df
+	.long	0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8
+	.long	0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b
+	.long	0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001
+	.long	0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30
+	.long	0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910
+	.long	0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8
+	.long	0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53
+	.long	0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8
+	.long	0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb
+	.long	0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3
+	.long	0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60
+	.long	0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec
+	.long	0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9
+	.long	0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b
+	.long	0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207
+	.long	0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178
+	.long	0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6
+	.long	0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b
+	.long	0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493
+	.long	0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c
+	.long	0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a
+	.long	0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817
+___
+}
+$code.=<<___;
+.size	K${label},.-K${label}
+.globl	sha${label}_block_data_order
+sha${label}_block_data_order:
+	save	%sp,`-$frame-$locals`,%sp
+	and	$inp,`$align-1`,$tmp31
+	sllx	$len,`log(16*$SZ)/log(2)`,$len
+	andn	$inp,`$align-1`,$inp
+	sll	$tmp31,3,$tmp31
+	add	$inp,$len,$len
+___
+$code.=<<___ if ($SZ==8); # SHA512
+	mov	32,$tmp32
+	sub	$tmp32,$tmp31,$tmp32
+___
+$code.=<<___;
+.Lpic:	call	.+8
+	add	%o7,K${label}-.Lpic,$Ktbl
+
+	$LD	[$ctx+`0*$SZ`],$A
+	$LD	[$ctx+`1*$SZ`],$B
+	$LD	[$ctx+`2*$SZ`],$C
+	$LD	[$ctx+`3*$SZ`],$D
+	$LD	[$ctx+`4*$SZ`],$E
+	$LD	[$ctx+`5*$SZ`],$F
+	$LD	[$ctx+`6*$SZ`],$G
+	$LD	[$ctx+`7*$SZ`],$H
+
+.Lloop:
+___
+for ($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
+$code.=".L16_xx:\n";
+for (;$i<32;$i++)	{ &$BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+	and	$tmp2,0xfff,$tmp2
+	cmp	$tmp2,$lastK
+	bne	.L16_xx
+	add	$Ktbl,`16*$SZ`,$Ktbl	! Ktbl+=16
+
+___
+$code.=<<___ if ($SZ==4); # SHA256
+	$LD	[$ctx+`0*$SZ`],@X[0]
+	$LD	[$ctx+`1*$SZ`],@X[1]
+	$LD	[$ctx+`2*$SZ`],@X[2]
+	$LD	[$ctx+`3*$SZ`],@X[3]
+	$LD	[$ctx+`4*$SZ`],@X[4]
+	$LD	[$ctx+`5*$SZ`],@X[5]
+	$LD	[$ctx+`6*$SZ`],@X[6]
+	$LD	[$ctx+`7*$SZ`],@X[7]
+
+	add	$A,@X[0],$A
+	$ST	$A,[$ctx+`0*$SZ`]
+	add	$B,@X[1],$B
+	$ST	$B,[$ctx+`1*$SZ`]
+	add	$C,@X[2],$C
+	$ST	$C,[$ctx+`2*$SZ`]
+	add	$D,@X[3],$D
+	$ST	$D,[$ctx+`3*$SZ`]
+	add	$E,@X[4],$E
+	$ST	$E,[$ctx+`4*$SZ`]
+	add	$F,@X[5],$F
+	$ST	$F,[$ctx+`5*$SZ`]
+	add	$G,@X[6],$G
+	$ST	$G,[$ctx+`6*$SZ`]
+	add	$H,@X[7],$H
+	$ST	$H,[$ctx+`7*$SZ`]
+___
+$code.=<<___ if ($SZ==8); # SHA512
+	ld	[$ctx+`0*$SZ+0`],%l0
+	ld	[$ctx+`0*$SZ+4`],%l1
+	ld	[$ctx+`1*$SZ+0`],%l2
+	ld	[$ctx+`1*$SZ+4`],%l3
+	ld	[$ctx+`2*$SZ+0`],%l4
+	ld	[$ctx+`2*$SZ+4`],%l5
+	ld	[$ctx+`3*$SZ+0`],%l6
+
+	sllx	%l0,32,$tmp0
+	ld	[$ctx+`3*$SZ+4`],%l7
+	sllx	%l2,32,$tmp1
+	or	%l1,$tmp0,$tmp0
+	or	%l3,$tmp1,$tmp1
+	add	$tmp0,$A,$A
+	add	$tmp1,$B,$B
+	$ST	$A,[$ctx+`0*$SZ`]
+	sllx	%l4,32,$tmp2
+	$ST	$B,[$ctx+`1*$SZ`]
+	sllx	%l6,32,$T1
+	or	%l5,$tmp2,$tmp2
+	or	%l7,$T1,$T1
+	add	$tmp2,$C,$C
+	$ST	$C,[$ctx+`2*$SZ`]
+	add	$T1,$D,$D
+	$ST	$D,[$ctx+`3*$SZ`]
+
+	ld	[$ctx+`4*$SZ+0`],%l0
+	ld	[$ctx+`4*$SZ+4`],%l1
+	ld	[$ctx+`5*$SZ+0`],%l2
+	ld	[$ctx+`5*$SZ+4`],%l3
+	ld	[$ctx+`6*$SZ+0`],%l4
+	ld	[$ctx+`6*$SZ+4`],%l5
+	ld	[$ctx+`7*$SZ+0`],%l6
+
+	sllx	%l0,32,$tmp0
+	ld	[$ctx+`7*$SZ+4`],%l7
+	sllx	%l2,32,$tmp1
+	or	%l1,$tmp0,$tmp0
+	or	%l3,$tmp1,$tmp1
+	add	$tmp0,$E,$E
+	add	$tmp1,$F,$F
+	$ST	$E,[$ctx+`4*$SZ`]
+	sllx	%l4,32,$tmp2
+	$ST	$F,[$ctx+`5*$SZ`]
+	sllx	%l6,32,$T1
+	or	%l5,$tmp2,$tmp2
+	or	%l7,$T1,$T1
+	add	$tmp2,$G,$G
+	$ST	$G,[$ctx+`6*$SZ`]
+	add	$T1,$H,$H
+	$ST	$H,[$ctx+`7*$SZ`]
+___
+$code.=<<___;
+	add	$inp,`16*$SZ`,$inp		! advance inp
+	cmp	$inp,$len
+	bne	`$bits==64?"%xcc":"%icc"`,.Lloop
+	sub	$Ktbl,`($rounds-16)*$SZ`,$Ktbl	! rewind Ktbl
+
+	ret
+	restore
+.type	sha${label}_block_data_order,#function
+.size	sha${label}_block_data_order,(.-sha${label}_block_data_order)
+.asciz	"SHA${label} block transform for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
+.align	4
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/sha/asm/sha512-x86_64.pl b/openssl/crypto/sha/asm/sha512-x86_64.pl
new file mode 100755
index 0000000..e6643f8
--- /dev/null
+++ b/openssl/crypto/sha/asm/sha512-x86_64.pl
@@ -0,0 +1,456 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. Rights for redistribution and usage in source and binary
+# forms are granted according to the OpenSSL license.
+# ====================================================================
+#
+# sha256/512_block procedure for x86_64.
+#
+# 40% improvement over compiler-generated code on Opteron. On EM64T
+# sha256 was observed to run >80% faster and sha512 - >40%. No magical
+# tricks, just straight implementation... I really wonder why gcc
+# [being armed with inline assembler] fails to generate as fast code.
+# The only thing which is cool about this module is that it's very
+# same instruction sequence used for both SHA-256 and SHA-512. In
+# former case the instructions operate on 32-bit operands, while in
+# latter - on 64-bit ones. All I had to do is to get one flavor right,
+# the other one passed the test right away:-)
+#
+# sha256_block runs in ~1005 cycles on Opteron, which gives you
+# asymptotic performance of 64*1000/1005=63.7MBps times CPU clock
+# frequency in GHz. sha512_block runs in ~1275 cycles, which results
+# in 128*1000/1275=100MBps per GHz. Is there room for improvement?
+# Well, if you compare it to IA-64 implementation, which maintains
+# X[16] in register bank[!], tends to 4 instructions per CPU clock
+# cycle and runs in 1003 cycles, 1275 is very good result for 3-way
+# issue Opteron pipeline and X[16] maintained in memory. So that *if*
+# there is a way to improve it, *then* the only way would be to try to
+# offload X[16] updates to SSE unit, but that would require "deeper"
+# loop unroll, which in turn would naturally cause size blow-up, not
+# to mention increased complexity! And once again, only *if* it's
+# actually possible to noticeably improve overall ILP, instruction
+# level parallelism, on a given CPU implementation in this case.
+#
+# Special note on Intel EM64T. While Opteron CPU exhibits perfect
+# perfromance ratio of 1.5 between 64- and 32-bit flavors [see above],
+# [currently available] EM64T CPUs apparently are far from it. On the
+# contrary, 64-bit version, sha512_block, is ~30% *slower* than 32-bit
+# sha256_block:-( This is presumably because 64-bit shifts/rotates
+# apparently are not atomic instructions, but implemented in microcode.
+
+$flavour = shift;
+$output  = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour $output";
+
+if ($output =~ /512/) {
+	$func="sha512_block_data_order";
+	$TABLE="K512";
+	$SZ=8;
+	@ROT=($A,$B,$C,$D,$E,$F,$G,$H)=("%rax","%rbx","%rcx","%rdx",
+					"%r8", "%r9", "%r10","%r11");
+	($T1,$a0,$a1,$a2)=("%r12","%r13","%r14","%r15");
+	@Sigma0=(28,34,39);
+	@Sigma1=(14,18,41);
+	@sigma0=(1,  8, 7);
+	@sigma1=(19,61, 6);
+	$rounds=80;
+} else {
+	$func="sha256_block_data_order";
+	$TABLE="K256";
+	$SZ=4;
+	@ROT=($A,$B,$C,$D,$E,$F,$G,$H)=("%eax","%ebx","%ecx","%edx",
+					"%r8d","%r9d","%r10d","%r11d");
+	($T1,$a0,$a1,$a2)=("%r12d","%r13d","%r14d","%r15d");
+	@Sigma0=( 2,13,22);
+	@Sigma1=( 6,11,25);
+	@sigma0=( 7,18, 3);
+	@sigma1=(17,19,10);
+	$rounds=64;
+}
+
+$ctx="%rdi";	# 1st arg
+$round="%rdi";	# zaps $ctx
+$inp="%rsi";	# 2nd arg
+$Tbl="%rbp";
+
+$_ctx="16*$SZ+0*8(%rsp)";
+$_inp="16*$SZ+1*8(%rsp)";
+$_end="16*$SZ+2*8(%rsp)";
+$_rsp="16*$SZ+3*8(%rsp)";
+$framesz="16*$SZ+4*8";
+
+
+sub ROUND_00_15()
+{ my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
+
+$code.=<<___;
+	mov	$e,$a0
+	mov	$e,$a1
+	mov	$f,$a2
+
+	ror	\$$Sigma1[0],$a0
+	ror	\$$Sigma1[1],$a1
+	xor	$g,$a2			# f^g
+
+	xor	$a1,$a0
+	ror	\$`$Sigma1[2]-$Sigma1[1]`,$a1
+	and	$e,$a2			# (f^g)&e
+	mov	$T1,`$SZ*($i&0xf)`(%rsp)
+
+	xor	$a1,$a0			# Sigma1(e)
+	xor	$g,$a2			# Ch(e,f,g)=((f^g)&e)^g
+	add	$h,$T1			# T1+=h
+
+	mov	$a,$h
+	add	$a0,$T1			# T1+=Sigma1(e)
+
+	add	$a2,$T1			# T1+=Ch(e,f,g)
+	mov	$a,$a0
+	mov	$a,$a1
+
+	ror	\$$Sigma0[0],$h
+	ror	\$$Sigma0[1],$a0
+	mov	$a,$a2
+	add	($Tbl,$round,$SZ),$T1	# T1+=K[round]
+
+	xor	$a0,$h
+	ror	\$`$Sigma0[2]-$Sigma0[1]`,$a0
+	or	$c,$a1			# a|c
+
+	xor	$a0,$h			# h=Sigma0(a)
+	and	$c,$a2			# a&c
+	add	$T1,$d			# d+=T1
+
+	and	$b,$a1			# (a|c)&b
+	add	$T1,$h			# h+=T1
+
+	or	$a2,$a1			# Maj(a,b,c)=((a|c)&b)|(a&c)
+	lea	1($round),$round	# round++
+
+	add	$a1,$h			# h+=Maj(a,b,c)
+___
+}
+
+sub ROUND_16_XX()
+{ my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
+
+$code.=<<___;
+	mov	`$SZ*(($i+1)&0xf)`(%rsp),$a0
+	mov	`$SZ*(($i+14)&0xf)`(%rsp),$T1
+
+	mov	$a0,$a2
+
+	shr	\$$sigma0[2],$a0
+	ror	\$$sigma0[0],$a2
+
+	xor	$a2,$a0
+	ror	\$`$sigma0[1]-$sigma0[0]`,$a2
+
+	xor	$a2,$a0			# sigma0(X[(i+1)&0xf])
+	mov	$T1,$a1
+
+	shr	\$$sigma1[2],$T1
+	ror	\$$sigma1[0],$a1
+
+	xor	$a1,$T1
+	ror	\$`$sigma1[1]-$sigma1[0]`,$a1
+
+	xor	$a1,$T1			# sigma1(X[(i+14)&0xf])
+
+	add	$a0,$T1
+
+	add	`$SZ*(($i+9)&0xf)`(%rsp),$T1
+
+	add	`$SZ*($i&0xf)`(%rsp),$T1
+___
+	&ROUND_00_15(@_);
+}
+
+$code=<<___;
+.text
+
+.globl	$func
+.type	$func,\@function,4
+.align	16
+$func:
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	mov	%rsp,%r11		# copy %rsp
+	shl	\$4,%rdx		# num*16
+	sub	\$$framesz,%rsp
+	lea	($inp,%rdx,$SZ),%rdx	# inp+num*16*$SZ
+	and	\$-64,%rsp		# align stack frame
+	mov	$ctx,$_ctx		# save ctx, 1st arg
+	mov	$inp,$_inp		# save inp, 2nd arh
+	mov	%rdx,$_end		# save end pointer, "3rd" arg
+	mov	%r11,$_rsp		# save copy of %rsp
+.Lprologue:
+
+	lea	$TABLE(%rip),$Tbl
+
+	mov	$SZ*0($ctx),$A
+	mov	$SZ*1($ctx),$B
+	mov	$SZ*2($ctx),$C
+	mov	$SZ*3($ctx),$D
+	mov	$SZ*4($ctx),$E
+	mov	$SZ*5($ctx),$F
+	mov	$SZ*6($ctx),$G
+	mov	$SZ*7($ctx),$H
+	jmp	.Lloop
+
+.align	16
+.Lloop:
+	xor	$round,$round
+___
+	for($i=0;$i<16;$i++) {
+		$code.="	mov	$SZ*$i($inp),$T1\n";
+		$code.="	bswap	$T1\n";
+		&ROUND_00_15($i,@ROT);
+		unshift(@ROT,pop(@ROT));
+	}
+$code.=<<___;
+	jmp	.Lrounds_16_xx
+.align	16
+.Lrounds_16_xx:
+___
+	for(;$i<32;$i++) {
+		&ROUND_16_XX($i,@ROT);
+		unshift(@ROT,pop(@ROT));
+	}
+
+$code.=<<___;
+	cmp	\$$rounds,$round
+	jb	.Lrounds_16_xx
+
+	mov	$_ctx,$ctx
+	lea	16*$SZ($inp),$inp
+
+	add	$SZ*0($ctx),$A
+	add	$SZ*1($ctx),$B
+	add	$SZ*2($ctx),$C
+	add	$SZ*3($ctx),$D
+	add	$SZ*4($ctx),$E
+	add	$SZ*5($ctx),$F
+	add	$SZ*6($ctx),$G
+	add	$SZ*7($ctx),$H
+
+	cmp	$_end,$inp
+
+	mov	$A,$SZ*0($ctx)
+	mov	$B,$SZ*1($ctx)
+	mov	$C,$SZ*2($ctx)
+	mov	$D,$SZ*3($ctx)
+	mov	$E,$SZ*4($ctx)
+	mov	$F,$SZ*5($ctx)
+	mov	$G,$SZ*6($ctx)
+	mov	$H,$SZ*7($ctx)
+	jb	.Lloop
+
+	mov	$_rsp,%rsi
+	mov	(%rsi),%r15
+	mov	8(%rsi),%r14
+	mov	16(%rsi),%r13
+	mov	24(%rsi),%r12
+	mov	32(%rsi),%rbp
+	mov	40(%rsi),%rbx
+	lea	48(%rsi),%rsp
+.Lepilogue:
+	ret
+.size	$func,.-$func
+___
+
+if ($SZ==4) {
+$code.=<<___;
+.align	64
+.type	$TABLE,\@object
+$TABLE:
+	.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+	.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+	.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+	.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+	.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+	.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+	.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+	.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+	.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+	.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+	.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+	.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+	.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+	.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+	.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+	.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+___
+} else {
+$code.=<<___;
+.align	64
+.type	$TABLE,\@object
+$TABLE:
+	.quad	0x428a2f98d728ae22,0x7137449123ef65cd
+	.quad	0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
+	.quad	0x3956c25bf348b538,0x59f111f1b605d019
+	.quad	0x923f82a4af194f9b,0xab1c5ed5da6d8118
+	.quad	0xd807aa98a3030242,0x12835b0145706fbe
+	.quad	0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
+	.quad	0x72be5d74f27b896f,0x80deb1fe3b1696b1
+	.quad	0x9bdc06a725c71235,0xc19bf174cf692694
+	.quad	0xe49b69c19ef14ad2,0xefbe4786384f25e3
+	.quad	0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
+	.quad	0x2de92c6f592b0275,0x4a7484aa6ea6e483
+	.quad	0x5cb0a9dcbd41fbd4,0x76f988da831153b5
+	.quad	0x983e5152ee66dfab,0xa831c66d2db43210
+	.quad	0xb00327c898fb213f,0xbf597fc7beef0ee4
+	.quad	0xc6e00bf33da88fc2,0xd5a79147930aa725
+	.quad	0x06ca6351e003826f,0x142929670a0e6e70
+	.quad	0x27b70a8546d22ffc,0x2e1b21385c26c926
+	.quad	0x4d2c6dfc5ac42aed,0x53380d139d95b3df
+	.quad	0x650a73548baf63de,0x766a0abb3c77b2a8
+	.quad	0x81c2c92e47edaee6,0x92722c851482353b
+	.quad	0xa2bfe8a14cf10364,0xa81a664bbc423001
+	.quad	0xc24b8b70d0f89791,0xc76c51a30654be30
+	.quad	0xd192e819d6ef5218,0xd69906245565a910
+	.quad	0xf40e35855771202a,0x106aa07032bbd1b8
+	.quad	0x19a4c116b8d2d0c8,0x1e376c085141ab53
+	.quad	0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
+	.quad	0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
+	.quad	0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
+	.quad	0x748f82ee5defb2fc,0x78a5636f43172f60
+	.quad	0x84c87814a1f0ab72,0x8cc702081a6439ec
+	.quad	0x90befffa23631e28,0xa4506cebde82bde9
+	.quad	0xbef9a3f7b2c67915,0xc67178f2e372532b
+	.quad	0xca273eceea26619c,0xd186b8c721c0c207
+	.quad	0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
+	.quad	0x06f067aa72176fba,0x0a637dc5a2c898a6
+	.quad	0x113f9804bef90dae,0x1b710b35131c471b
+	.quad	0x28db77f523047d84,0x32caab7b40c72493
+	.quad	0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
+	.quad	0x4cc5d4becb3e42b6,0x597f299cfc657e2a
+	.quad	0x5fcb6fab3ad6faec,0x6c44198c4a475817
+___
+}
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern	__imp_RtlVirtualUnwind
+.type	se_handler,\@abi-omnipotent
+.align	16
+se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	lea	.Lprologue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lprologue
+	jb	.Lin_prologue
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	lea	.Lepilogue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
+	jae	.Lin_prologue
+
+	mov	16*$SZ+3*8(%rax),%rax	# pull $_rsp
+	lea	48(%rax),%rax
+
+	mov	-8(%rax),%rbx
+	mov	-16(%rax),%rbp
+	mov	-24(%rax),%r12
+	mov	-32(%rax),%r13
+	mov	-40(%rax),%r14
+	mov	-48(%rax),%r15
+	mov	%rbx,144($context)	# restore context->Rbx
+	mov	%rbp,160($context)	# restore context->Rbp
+	mov	%r12,216($context)	# restore context->R12
+	mov	%r13,224($context)	# restore context->R13
+	mov	%r14,232($context)	# restore context->R14
+	mov	%r15,240($context)	# restore context->R15
+
+.Lin_prologue:
+	mov	8(%rax),%rdi
+	mov	16(%rax),%rsi
+	mov	%rax,152($context)	# restore context->Rsp
+	mov	%rsi,168($context)	# restore context->Rsi
+	mov	%rdi,176($context)	# restore context->Rdi
+
+	mov	40($disp),%rdi		# disp->ContextRecord
+	mov	$context,%rsi		# context
+	mov	\$154,%ecx		# sizeof(CONTEXT)
+	.long	0xa548f3fc		# cld; rep movsq
+
+	mov	$disp,%rsi
+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
+	mov	40(%rsi),%r10		# disp->ContextRecord
+	lea	56(%rsi),%r11		# &disp->HandlerData
+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
+	mov	%r10,32(%rsp)		# arg5
+	mov	%r11,40(%rsp)		# arg6
+	mov	%r12,48(%rsp)		# arg7
+	mov	%rcx,56(%rsp)		# arg8, (NULL)
+	call	*__imp_RtlVirtualUnwind(%rip)
+
+	mov	\$1,%eax		# ExceptionContinueSearch
+	add	\$64,%rsp
+	popfq
+	pop	%r15
+	pop	%r14
+	pop	%r13
+	pop	%r12
+	pop	%rbp
+	pop	%rbx
+	pop	%rdi
+	pop	%rsi
+	ret
+.size	se_handler,.-se_handler
+
+.section	.pdata
+.align	4
+	.rva	.LSEH_begin_$func
+	.rva	.LSEH_end_$func
+	.rva	.LSEH_info_$func
+
+.section	.xdata
+.align	8
+.LSEH_info_$func:
+	.byte	9,0,0,0
+	.rva	se_handler
+___
+}
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/sha/sha.c b/openssl/crypto/sha/sha.c
new file mode 100644
index 0000000..4212655
--- /dev/null
+++ b/openssl/crypto/sha/sha.c
@@ -0,0 +1,124 @@
+/* crypto/sha/sha.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/sha.h>
+
+#define BUFSIZE	1024*16
+
+void do_fp(FILE *f);
+void pt(unsigned char *md);
+int read(int, void *, unsigned int);
+int main(int argc, char **argv)
+	{
+	int i,err=0;
+	FILE *IN;
+
+	if (argc == 1)
+		{
+		do_fp(stdin);
+		}
+	else
+		{
+		for (i=1; i<argc; i++)
+			{
+			IN=fopen(argv[i],"r");
+			if (IN == NULL)
+				{
+				perror(argv[i]);
+				err++;
+				continue;
+				}
+			printf("SHA(%s)= ",argv[i]);
+			do_fp(IN);
+			fclose(IN);
+			}
+		}
+	exit(err);
+	}
+
+void do_fp(FILE *f)
+	{
+	SHA_CTX c;
+	unsigned char md[SHA_DIGEST_LENGTH];
+	int fd;
+	int i;
+	unsigned char buf[BUFSIZE];
+
+	fd=fileno(f);
+	SHA_Init(&c);
+	for (;;)
+		{
+		i=read(fd,buf,BUFSIZE);
+		if (i <= 0) break;
+		SHA_Update(&c,buf,(unsigned long)i);
+		}
+	SHA_Final(&(md[0]),&c);
+	pt(md);
+	}
+
+void pt(unsigned char *md)
+	{
+	int i;
+
+	for (i=0; i<SHA_DIGEST_LENGTH; i++)
+		printf("%02x",md[i]);
+	printf("\n");
+	}
+
diff --git a/openssl/crypto/sha/sha.h b/openssl/crypto/sha/sha.h
new file mode 100644
index 0000000..16cacf9
--- /dev/null
+++ b/openssl/crypto/sha/sha.h
@@ -0,0 +1,200 @@
+/* crypto/sha/sha.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_SHA_H
+#define HEADER_SHA_H
+
+#include <openssl/e_os2.h>
+#include <stddef.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if defined(OPENSSL_NO_SHA) || (defined(OPENSSL_NO_SHA0) && defined(OPENSSL_NO_SHA1))
+#error SHA is disabled.
+#endif
+
+#if defined(OPENSSL_FIPS)
+#define FIPS_SHA_SIZE_T size_t
+#endif
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! SHA_LONG_LOG2 has to be defined along.                        !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#if defined(__LP32__)
+#define SHA_LONG unsigned long
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#define SHA_LONG unsigned long
+#define SHA_LONG_LOG2 3
+#else
+#define SHA_LONG unsigned int
+#endif
+
+#define SHA_LBLOCK	16
+#define SHA_CBLOCK	(SHA_LBLOCK*4)	/* SHA treats input data as a
+					 * contiguous array of 32 bit
+					 * wide big-endian values. */
+#define SHA_LAST_BLOCK  (SHA_CBLOCK-8)
+#define SHA_DIGEST_LENGTH 20
+
+typedef struct SHAstate_st
+	{
+	SHA_LONG h0,h1,h2,h3,h4;
+	SHA_LONG Nl,Nh;
+	SHA_LONG data[SHA_LBLOCK];
+	unsigned int num;
+	} SHA_CTX;
+
+#ifndef OPENSSL_NO_SHA0
+int SHA_Init(SHA_CTX *c);
+int SHA_Update(SHA_CTX *c, const void *data, size_t len);
+int SHA_Final(unsigned char *md, SHA_CTX *c);
+unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md);
+void SHA_Transform(SHA_CTX *c, const unsigned char *data);
+#endif
+#ifndef OPENSSL_NO_SHA1
+int SHA1_Init(SHA_CTX *c);
+int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
+int SHA1_Final(unsigned char *md, SHA_CTX *c);
+unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md);
+void SHA1_Transform(SHA_CTX *c, const unsigned char *data);
+#endif
+
+#define SHA256_CBLOCK	(SHA_LBLOCK*4)	/* SHA-256 treats input data as a
+					 * contiguous array of 32 bit
+					 * wide big-endian values. */
+#define SHA224_DIGEST_LENGTH	28
+#define SHA256_DIGEST_LENGTH	32
+
+typedef struct SHA256state_st
+	{
+	SHA_LONG h[8];
+	SHA_LONG Nl,Nh;
+	SHA_LONG data[SHA_LBLOCK];
+	unsigned int num,md_len;
+	} SHA256_CTX;
+
+#ifndef OPENSSL_NO_SHA256
+int SHA224_Init(SHA256_CTX *c);
+int SHA224_Update(SHA256_CTX *c, const void *data, size_t len);
+int SHA224_Final(unsigned char *md, SHA256_CTX *c);
+unsigned char *SHA224(const unsigned char *d, size_t n,unsigned char *md);
+int SHA256_Init(SHA256_CTX *c);
+int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
+int SHA256_Final(unsigned char *md, SHA256_CTX *c);
+unsigned char *SHA256(const unsigned char *d, size_t n,unsigned char *md);
+void SHA256_Transform(SHA256_CTX *c, const unsigned char *data);
+#endif
+
+#define SHA384_DIGEST_LENGTH	48
+#define SHA512_DIGEST_LENGTH	64
+
+#ifndef OPENSSL_NO_SHA512
+/*
+ * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64
+ * being exactly 64-bit wide. See Implementation Notes in sha512.c
+ * for further details.
+ */
+#define SHA512_CBLOCK	(SHA_LBLOCK*8)	/* SHA-512 treats input data as a
+					 * contiguous array of 64 bit
+					 * wide big-endian values. */
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
+#define SHA_LONG64 unsigned __int64
+#define U64(C)     C##UI64
+#elif defined(__arch64__)
+#define SHA_LONG64 unsigned long
+#define U64(C)     C##UL
+#else
+#define SHA_LONG64 unsigned long long
+#define U64(C)     C##ULL
+#endif
+
+typedef struct SHA512state_st
+	{
+	SHA_LONG64 h[8];
+	SHA_LONG64 Nl,Nh;
+	union {
+		SHA_LONG64	d[SHA_LBLOCK];
+		unsigned char	p[SHA512_CBLOCK];
+	} u;
+	unsigned int num,md_len;
+	} SHA512_CTX;
+#endif
+
+#ifndef OPENSSL_NO_SHA512
+int SHA384_Init(SHA512_CTX *c);
+int SHA384_Update(SHA512_CTX *c, const void *data, size_t len);
+int SHA384_Final(unsigned char *md, SHA512_CTX *c);
+unsigned char *SHA384(const unsigned char *d, size_t n,unsigned char *md);
+int SHA512_Init(SHA512_CTX *c);
+int SHA512_Update(SHA512_CTX *c, const void *data, size_t len);
+int SHA512_Final(unsigned char *md, SHA512_CTX *c);
+unsigned char *SHA512(const unsigned char *d, size_t n,unsigned char *md);
+void SHA512_Transform(SHA512_CTX *c, const unsigned char *data);
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/sha/sha1.c b/openssl/crypto/sha/sha1.c
new file mode 100644
index 0000000..d350c88
--- /dev/null
+++ b/openssl/crypto/sha/sha1.c
@@ -0,0 +1,127 @@
+/* crypto/sha/sha1.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/sha.h>
+
+#define BUFSIZE	1024*16
+
+void do_fp(FILE *f);
+void pt(unsigned char *md);
+#ifndef _OSD_POSIX
+int read(int, void *, unsigned int);
+#endif
+
+int main(int argc, char **argv)
+	{
+	int i,err=0;
+	FILE *IN;
+
+	if (argc == 1)
+		{
+		do_fp(stdin);
+		}
+	else
+		{
+		for (i=1; i<argc; i++)
+			{
+			IN=fopen(argv[i],"r");
+			if (IN == NULL)
+				{
+				perror(argv[i]);
+				err++;
+				continue;
+				}
+			printf("SHA1(%s)= ",argv[i]);
+			do_fp(IN);
+			fclose(IN);
+			}
+		}
+	exit(err);
+	}
+
+void do_fp(FILE *f)
+	{
+	SHA_CTX c;
+	unsigned char md[SHA_DIGEST_LENGTH];
+	int fd;
+	int i;
+	unsigned char buf[BUFSIZE];
+
+	fd=fileno(f);
+	SHA1_Init(&c);
+	for (;;)
+		{
+		i=read(fd,buf,BUFSIZE);
+		if (i <= 0) break;
+		SHA1_Update(&c,buf,(unsigned long)i);
+		}
+	SHA1_Final(&(md[0]),&c);
+	pt(md);
+	}
+
+void pt(unsigned char *md)
+	{
+	int i;
+
+	for (i=0; i<SHA_DIGEST_LENGTH; i++)
+		printf("%02x",md[i]);
+	printf("\n");
+	}
+
diff --git a/openssl/crypto/sha/sha1_one.c b/openssl/crypto/sha/sha1_one.c
new file mode 100644
index 0000000..7c65b60
--- /dev/null
+++ b/openssl/crypto/sha/sha1_one.c
@@ -0,0 +1,78 @@
+/* crypto/sha/sha1_one.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/sha.h>
+#include <openssl/crypto.h>
+
+#ifndef OPENSSL_NO_SHA1
+unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md)
+	{
+	SHA_CTX c;
+	static unsigned char m[SHA_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	if (!SHA1_Init(&c))
+		return NULL;
+	SHA1_Update(&c,d,n);
+	SHA1_Final(md,&c);
+	OPENSSL_cleanse(&c,sizeof(c));
+	return(md);
+	}
+#endif
diff --git a/openssl/crypto/sha/sha1dgst.c b/openssl/crypto/sha/sha1dgst.c
new file mode 100644
index 0000000..50d1925
--- /dev/null
+++ b/openssl/crypto/sha/sha1dgst.c
@@ -0,0 +1,74 @@
+/* crypto/sha/sha1dgst.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/opensslconf.h>
+#if !defined(OPENSSL_NO_SHA1) && !defined(OPENSSL_NO_SHA)
+
+#undef  SHA_0
+#define SHA_1
+
+#include <openssl/opensslv.h>
+
+const char SHA1_version[]="SHA1" OPENSSL_VERSION_PTEXT;
+
+/* The implementation is in ../md32_common.h */
+
+#include "sha_locl.h"
+
+#endif
+
diff --git a/openssl/crypto/sha/sha1test.c b/openssl/crypto/sha/sha1test.c
new file mode 100644
index 0000000..6feb396
--- /dev/null
+++ b/openssl/crypto/sha/sha1test.c
@@ -0,0 +1,178 @@
+/* crypto/sha/sha1test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_SHA
+int main(int argc, char *argv[])
+{
+    printf("No SHA support\n");
+    return(0);
+}
+#else
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+#undef SHA_0 /* FIPS 180 */
+#define  SHA_1 /* FIPS 180-1 */
+
+static char *test[]={
+	"abc",
+	"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+	NULL,
+	};
+
+#ifdef SHA_0
+static char *ret[]={
+	"0164b8a914cd2a5e74c4f7ff082c4d97f1edf880",
+	"d2516ee1acfa5baf33dfc1c471e438449ef134c8",
+	};
+static char *bigret=
+	"3232affa48628a26653b5aaa44541fd90d690603";
+#endif
+#ifdef SHA_1
+static char *ret[]={
+	"a9993e364706816aba3e25717850c26c9cd0d89d",
+	"84983e441c3bd26ebaae4aa1f95129e5e54670f1",
+	};
+static char *bigret=
+	"34aa973cd4c4daa4f61eeb2bdbad27316534016f";
+#endif
+
+static char *pt(unsigned char *md);
+int main(int argc, char *argv[])
+	{
+	int i,err=0;
+	char **P,**R;
+	static unsigned char buf[1000];
+	char *p,*r;
+	EVP_MD_CTX c;
+	unsigned char md[SHA_DIGEST_LENGTH];
+
+#ifdef CHARSET_EBCDIC
+	ebcdic2ascii(test[0], test[0], strlen(test[0]));
+	ebcdic2ascii(test[1], test[1], strlen(test[1]));
+#endif
+
+	EVP_MD_CTX_init(&c);
+	P=test;
+	R=ret;
+	i=1;
+	while (*P != NULL)
+		{
+		EVP_Digest(*P,strlen((char *)*P),md,NULL,EVP_sha1(), NULL);
+		p=pt(md);
+		if (strcmp(p,(char *)*R) != 0)
+			{
+			printf("error calculating SHA1 on '%s'\n",*P);
+			printf("got %s instead of %s\n",p,*R);
+			err++;
+			}
+		else
+			printf("test %d ok\n",i);
+		i++;
+		R++;
+		P++;
+		}
+
+	memset(buf,'a',1000);
+#ifdef CHARSET_EBCDIC
+	ebcdic2ascii(buf, buf, 1000);
+#endif /*CHARSET_EBCDIC*/
+	EVP_DigestInit_ex(&c,EVP_sha1(), NULL);
+	for (i=0; i<1000; i++)
+		EVP_DigestUpdate(&c,buf,1000);
+	EVP_DigestFinal_ex(&c,md,NULL);
+	p=pt(md);
+
+	r=bigret;
+	if (strcmp(p,r) != 0)
+		{
+		printf("error calculating SHA1 on 'a' * 1000\n");
+		printf("got %s instead of %s\n",p,r);
+		err++;
+		}
+	else
+		printf("test 3 ok\n");
+
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
+	EXIT(err);
+	EVP_MD_CTX_cleanup(&c);
+	return(0);
+	}
+
+static char *pt(unsigned char *md)
+	{
+	int i;
+	static char buf[80];
+
+	for (i=0; i<SHA_DIGEST_LENGTH; i++)
+		sprintf(&(buf[i*2]),"%02x",md[i]);
+	return(buf);
+	}
+#endif
diff --git a/openssl/crypto/sha/sha256.c b/openssl/crypto/sha/sha256.c
new file mode 100644
index 0000000..8952d87
--- /dev/null
+++ b/openssl/crypto/sha/sha256.c
@@ -0,0 +1,282 @@
+/* crypto/sha/sha256.c */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved
+ * according to the OpenSSL license [found in ../../LICENSE].
+ * ====================================================================
+ */
+#include <openssl/opensslconf.h>
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256)
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/crypto.h>
+#include <openssl/sha.h>
+#include <openssl/opensslv.h>
+
+const char SHA256_version[]="SHA-256" OPENSSL_VERSION_PTEXT;
+
+int SHA224_Init (SHA256_CTX *c)
+	{
+	memset (c,0,sizeof(*c));
+	c->h[0]=0xc1059ed8UL;	c->h[1]=0x367cd507UL;
+	c->h[2]=0x3070dd17UL;	c->h[3]=0xf70e5939UL;
+	c->h[4]=0xffc00b31UL;	c->h[5]=0x68581511UL;
+	c->h[6]=0x64f98fa7UL;	c->h[7]=0xbefa4fa4UL;
+	c->md_len=SHA224_DIGEST_LENGTH;
+	return 1;
+	}
+
+int SHA256_Init (SHA256_CTX *c)
+	{
+	memset (c,0,sizeof(*c));
+	c->h[0]=0x6a09e667UL;	c->h[1]=0xbb67ae85UL;
+	c->h[2]=0x3c6ef372UL;	c->h[3]=0xa54ff53aUL;
+	c->h[4]=0x510e527fUL;	c->h[5]=0x9b05688cUL;
+	c->h[6]=0x1f83d9abUL;	c->h[7]=0x5be0cd19UL;
+	c->md_len=SHA256_DIGEST_LENGTH;
+	return 1;
+	}
+
+unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md)
+	{
+	SHA256_CTX c;
+	static unsigned char m[SHA224_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	SHA224_Init(&c);
+	SHA256_Update(&c,d,n);
+	SHA256_Final(md,&c);
+	OPENSSL_cleanse(&c,sizeof(c));
+	return(md);
+	}
+
+unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md)
+	{
+	SHA256_CTX c;
+	static unsigned char m[SHA256_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	SHA256_Init(&c);
+	SHA256_Update(&c,d,n);
+	SHA256_Final(md,&c);
+	OPENSSL_cleanse(&c,sizeof(c));
+	return(md);
+	}
+
+int SHA224_Update(SHA256_CTX *c, const void *data, size_t len)
+{   return SHA256_Update (c,data,len);   }
+int SHA224_Final (unsigned char *md, SHA256_CTX *c)
+{   return SHA256_Final (md,c);   }
+
+#define	DATA_ORDER_IS_BIG_ENDIAN
+
+#define	HASH_LONG		SHA_LONG
+#define	HASH_CTX		SHA256_CTX
+#define	HASH_CBLOCK		SHA_CBLOCK
+/*
+ * Note that FIPS180-2 discusses "Truncation of the Hash Function Output."
+ * default: case below covers for it. It's not clear however if it's
+ * permitted to truncate to amount of bytes not divisible by 4. I bet not,
+ * but if it is, then default: case shall be extended. For reference.
+ * Idea behind separate cases for pre-defined lenghts is to let the
+ * compiler decide if it's appropriate to unroll small loops.
+ */
+#define	HASH_MAKE_STRING(c,s)	do {	\
+	unsigned long ll;		\
+	unsigned int  nn;		\
+	switch ((c)->md_len)		\
+	{   case SHA224_DIGEST_LENGTH:	\
+		for (nn=0;nn<SHA224_DIGEST_LENGTH/4;nn++)	\
+		{   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }	\
+		break;			\
+	    case SHA256_DIGEST_LENGTH:	\
+		for (nn=0;nn<SHA256_DIGEST_LENGTH/4;nn++)	\
+		{   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }	\
+		break;			\
+	    default:			\
+		if ((c)->md_len > SHA256_DIGEST_LENGTH)	\
+		    return 0;				\
+		for (nn=0;nn<(c)->md_len/4;nn++)		\
+		{   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }	\
+		break;			\
+	}				\
+	} while (0)
+
+#define	HASH_UPDATE		SHA256_Update
+#define	HASH_TRANSFORM		SHA256_Transform
+#define	HASH_FINAL		SHA256_Final
+#define	HASH_BLOCK_DATA_ORDER	sha256_block_data_order
+#ifndef SHA256_ASM
+static
+#endif
+void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num);
+
+#include "md32_common.h"
+
+#ifndef SHA256_ASM
+static const SHA_LONG K256[64] = {
+	0x428a2f98UL,0x71374491UL,0xb5c0fbcfUL,0xe9b5dba5UL,
+	0x3956c25bUL,0x59f111f1UL,0x923f82a4UL,0xab1c5ed5UL,
+	0xd807aa98UL,0x12835b01UL,0x243185beUL,0x550c7dc3UL,
+	0x72be5d74UL,0x80deb1feUL,0x9bdc06a7UL,0xc19bf174UL,
+	0xe49b69c1UL,0xefbe4786UL,0x0fc19dc6UL,0x240ca1ccUL,
+	0x2de92c6fUL,0x4a7484aaUL,0x5cb0a9dcUL,0x76f988daUL,
+	0x983e5152UL,0xa831c66dUL,0xb00327c8UL,0xbf597fc7UL,
+	0xc6e00bf3UL,0xd5a79147UL,0x06ca6351UL,0x14292967UL,
+	0x27b70a85UL,0x2e1b2138UL,0x4d2c6dfcUL,0x53380d13UL,
+	0x650a7354UL,0x766a0abbUL,0x81c2c92eUL,0x92722c85UL,
+	0xa2bfe8a1UL,0xa81a664bUL,0xc24b8b70UL,0xc76c51a3UL,
+	0xd192e819UL,0xd6990624UL,0xf40e3585UL,0x106aa070UL,
+	0x19a4c116UL,0x1e376c08UL,0x2748774cUL,0x34b0bcb5UL,
+	0x391c0cb3UL,0x4ed8aa4aUL,0x5b9cca4fUL,0x682e6ff3UL,
+	0x748f82eeUL,0x78a5636fUL,0x84c87814UL,0x8cc70208UL,
+	0x90befffaUL,0xa4506cebUL,0xbef9a3f7UL,0xc67178f2UL };
+
+/*
+ * FIPS specification refers to right rotations, while our ROTATE macro
+ * is left one. This is why you might notice that rotation coefficients
+ * differ from those observed in FIPS document by 32-N...
+ */
+#define Sigma0(x)	(ROTATE((x),30) ^ ROTATE((x),19) ^ ROTATE((x),10))
+#define Sigma1(x)	(ROTATE((x),26) ^ ROTATE((x),21) ^ ROTATE((x),7))
+#define sigma0(x)	(ROTATE((x),25) ^ ROTATE((x),14) ^ ((x)>>3))
+#define sigma1(x)	(ROTATE((x),15) ^ ROTATE((x),13) ^ ((x)>>10))
+
+#define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+#ifdef OPENSSL_SMALL_FOOTPRINT
+
+static void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num)
+	{
+	unsigned MD32_REG_T a,b,c,d,e,f,g,h,s0,s1,T1,T2;
+	SHA_LONG	X[16],l;
+	int i;
+	const unsigned char *data=in;
+
+			while (num--) {
+
+	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3];
+	e = ctx->h[4];	f = ctx->h[5];	g = ctx->h[6];	h = ctx->h[7];
+
+	for (i=0;i<16;i++)
+		{
+		HOST_c2l(data,l); T1 = X[i] = l;
+		T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i];
+		T2 = Sigma0(a) + Maj(a,b,c);
+		h = g;	g = f;	f = e;	e = d + T1;
+		d = c;	c = b;	b = a;	a = T1 + T2;
+		}
+
+	for (;i<64;i++)
+		{
+		s0 = X[(i+1)&0x0f];	s0 = sigma0(s0);
+		s1 = X[(i+14)&0x0f];	s1 = sigma1(s1);
+
+		T1 = X[i&0xf] += s0 + s1 + X[(i+9)&0xf];
+		T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i];
+		T2 = Sigma0(a) + Maj(a,b,c);
+		h = g;	g = f;	f = e;	e = d + T1;
+		d = c;	c = b;	b = a;	a = T1 + T2;
+		}
+
+	ctx->h[0] += a;	ctx->h[1] += b;	ctx->h[2] += c;	ctx->h[3] += d;
+	ctx->h[4] += e;	ctx->h[5] += f;	ctx->h[6] += g;	ctx->h[7] += h;
+
+			}
+}
+
+#else
+
+#define	ROUND_00_15(i,a,b,c,d,e,f,g,h)		do {	\
+	T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i];	\
+	h = Sigma0(a) + Maj(a,b,c);			\
+	d += T1;	h += T1;		} while (0)
+
+#define	ROUND_16_63(i,a,b,c,d,e,f,g,h,X)	do {	\
+	s0 = X[(i+1)&0x0f];	s0 = sigma0(s0);	\
+	s1 = X[(i+14)&0x0f];	s1 = sigma1(s1);	\
+	T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f];	\
+	ROUND_00_15(i,a,b,c,d,e,f,g,h);		} while (0)
+
+static void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num)
+	{
+	unsigned MD32_REG_T a,b,c,d,e,f,g,h,s0,s1,T1;
+	SHA_LONG	X[16];
+	int i;
+	const unsigned char *data=in;
+	const union { long one; char little; } is_endian = {1};
+
+			while (num--) {
+
+	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3];
+	e = ctx->h[4];	f = ctx->h[5];	g = ctx->h[6];	h = ctx->h[7];
+
+	if (!is_endian.little && sizeof(SHA_LONG)==4 && ((size_t)in%4)==0)
+		{
+		const SHA_LONG *W=(const SHA_LONG *)data;
+
+		T1 = X[0] = W[0];	ROUND_00_15(0,a,b,c,d,e,f,g,h);
+		T1 = X[1] = W[1];	ROUND_00_15(1,h,a,b,c,d,e,f,g);
+		T1 = X[2] = W[2];	ROUND_00_15(2,g,h,a,b,c,d,e,f);
+		T1 = X[3] = W[3];	ROUND_00_15(3,f,g,h,a,b,c,d,e);
+		T1 = X[4] = W[4];	ROUND_00_15(4,e,f,g,h,a,b,c,d);
+		T1 = X[5] = W[5];	ROUND_00_15(5,d,e,f,g,h,a,b,c);
+		T1 = X[6] = W[6];	ROUND_00_15(6,c,d,e,f,g,h,a,b);
+		T1 = X[7] = W[7];	ROUND_00_15(7,b,c,d,e,f,g,h,a);
+		T1 = X[8] = W[8];	ROUND_00_15(8,a,b,c,d,e,f,g,h);
+		T1 = X[9] = W[9];	ROUND_00_15(9,h,a,b,c,d,e,f,g);
+		T1 = X[10] = W[10];	ROUND_00_15(10,g,h,a,b,c,d,e,f);
+		T1 = X[11] = W[11];	ROUND_00_15(11,f,g,h,a,b,c,d,e);
+		T1 = X[12] = W[12];	ROUND_00_15(12,e,f,g,h,a,b,c,d);
+		T1 = X[13] = W[13];	ROUND_00_15(13,d,e,f,g,h,a,b,c);
+		T1 = X[14] = W[14];	ROUND_00_15(14,c,d,e,f,g,h,a,b);
+		T1 = X[15] = W[15];	ROUND_00_15(15,b,c,d,e,f,g,h,a);
+
+		data += SHA256_CBLOCK;
+		}
+	else
+		{
+		SHA_LONG l;
+
+		HOST_c2l(data,l); T1 = X[0] = l;  ROUND_00_15(0,a,b,c,d,e,f,g,h);
+		HOST_c2l(data,l); T1 = X[1] = l;  ROUND_00_15(1,h,a,b,c,d,e,f,g);
+		HOST_c2l(data,l); T1 = X[2] = l;  ROUND_00_15(2,g,h,a,b,c,d,e,f);
+		HOST_c2l(data,l); T1 = X[3] = l;  ROUND_00_15(3,f,g,h,a,b,c,d,e);
+		HOST_c2l(data,l); T1 = X[4] = l;  ROUND_00_15(4,e,f,g,h,a,b,c,d);
+		HOST_c2l(data,l); T1 = X[5] = l;  ROUND_00_15(5,d,e,f,g,h,a,b,c);
+		HOST_c2l(data,l); T1 = X[6] = l;  ROUND_00_15(6,c,d,e,f,g,h,a,b);
+		HOST_c2l(data,l); T1 = X[7] = l;  ROUND_00_15(7,b,c,d,e,f,g,h,a);
+		HOST_c2l(data,l); T1 = X[8] = l;  ROUND_00_15(8,a,b,c,d,e,f,g,h);
+		HOST_c2l(data,l); T1 = X[9] = l;  ROUND_00_15(9,h,a,b,c,d,e,f,g);
+		HOST_c2l(data,l); T1 = X[10] = l; ROUND_00_15(10,g,h,a,b,c,d,e,f);
+		HOST_c2l(data,l); T1 = X[11] = l; ROUND_00_15(11,f,g,h,a,b,c,d,e);
+		HOST_c2l(data,l); T1 = X[12] = l; ROUND_00_15(12,e,f,g,h,a,b,c,d);
+		HOST_c2l(data,l); T1 = X[13] = l; ROUND_00_15(13,d,e,f,g,h,a,b,c);
+		HOST_c2l(data,l); T1 = X[14] = l; ROUND_00_15(14,c,d,e,f,g,h,a,b);
+		HOST_c2l(data,l); T1 = X[15] = l; ROUND_00_15(15,b,c,d,e,f,g,h,a);
+		}
+
+	for (i=16;i<64;i+=8)
+		{
+		ROUND_16_63(i+0,a,b,c,d,e,f,g,h,X);
+		ROUND_16_63(i+1,h,a,b,c,d,e,f,g,X);
+		ROUND_16_63(i+2,g,h,a,b,c,d,e,f,X);
+		ROUND_16_63(i+3,f,g,h,a,b,c,d,e,X);
+		ROUND_16_63(i+4,e,f,g,h,a,b,c,d,X);
+		ROUND_16_63(i+5,d,e,f,g,h,a,b,c,X);
+		ROUND_16_63(i+6,c,d,e,f,g,h,a,b,X);
+		ROUND_16_63(i+7,b,c,d,e,f,g,h,a,X);
+		}
+
+	ctx->h[0] += a;	ctx->h[1] += b;	ctx->h[2] += c;	ctx->h[3] += d;
+	ctx->h[4] += e;	ctx->h[5] += f;	ctx->h[6] += g;	ctx->h[7] += h;
+
+			}
+	}
+
+#endif
+#endif /* SHA256_ASM */
+
+#endif /* OPENSSL_NO_SHA256 */
diff --git a/openssl/crypto/sha/sha256t.c b/openssl/crypto/sha/sha256t.c
new file mode 100644
index 0000000..6b4a3bd
--- /dev/null
+++ b/openssl/crypto/sha/sha256t.c
@@ -0,0 +1,147 @@
+/* crypto/sha/sha256t.c */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ * ====================================================================
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <openssl/sha.h>
+#include <openssl/evp.h>
+
+#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA256)
+int main(int argc, char *argv[])
+{
+    printf("No SHA256 support\n");
+    return(0);
+}
+#else
+
+unsigned char app_b1[SHA256_DIGEST_LENGTH] = {
+	0xba,0x78,0x16,0xbf,0x8f,0x01,0xcf,0xea,
+	0x41,0x41,0x40,0xde,0x5d,0xae,0x22,0x23,
+	0xb0,0x03,0x61,0xa3,0x96,0x17,0x7a,0x9c,
+	0xb4,0x10,0xff,0x61,0xf2,0x00,0x15,0xad	};
+
+unsigned char app_b2[SHA256_DIGEST_LENGTH] = {
+	0x24,0x8d,0x6a,0x61,0xd2,0x06,0x38,0xb8,
+	0xe5,0xc0,0x26,0x93,0x0c,0x3e,0x60,0x39,
+	0xa3,0x3c,0xe4,0x59,0x64,0xff,0x21,0x67,
+	0xf6,0xec,0xed,0xd4,0x19,0xdb,0x06,0xc1	};
+
+unsigned char app_b3[SHA256_DIGEST_LENGTH] = {
+	0xcd,0xc7,0x6e,0x5c,0x99,0x14,0xfb,0x92,
+	0x81,0xa1,0xc7,0xe2,0x84,0xd7,0x3e,0x67,
+	0xf1,0x80,0x9a,0x48,0xa4,0x97,0x20,0x0e,
+	0x04,0x6d,0x39,0xcc,0xc7,0x11,0x2c,0xd0	};
+
+unsigned char addenum_1[SHA224_DIGEST_LENGTH] = {
+	0x23,0x09,0x7d,0x22,0x34,0x05,0xd8,0x22,
+	0x86,0x42,0xa4,0x77,0xbd,0xa2,0x55,0xb3,
+	0x2a,0xad,0xbc,0xe4,0xbd,0xa0,0xb3,0xf7,
+	0xe3,0x6c,0x9d,0xa7 };
+
+unsigned char addenum_2[SHA224_DIGEST_LENGTH] = {
+	0x75,0x38,0x8b,0x16,0x51,0x27,0x76,0xcc,
+	0x5d,0xba,0x5d,0xa1,0xfd,0x89,0x01,0x50,
+	0xb0,0xc6,0x45,0x5c,0xb4,0xf5,0x8b,0x19,
+	0x52,0x52,0x25,0x25 };
+
+unsigned char addenum_3[SHA224_DIGEST_LENGTH] = {
+	0x20,0x79,0x46,0x55,0x98,0x0c,0x91,0xd8,
+	0xbb,0xb4,0xc1,0xea,0x97,0x61,0x8a,0x4b,
+	0xf0,0x3f,0x42,0x58,0x19,0x48,0xb2,0xee,
+	0x4e,0xe7,0xad,0x67 };
+
+int main (int argc,char **argv)
+{ unsigned char md[SHA256_DIGEST_LENGTH];
+  int		i;
+  EVP_MD_CTX	evp;
+
+    fprintf(stdout,"Testing SHA-256 ");
+
+    EVP_Digest ("abc",3,md,NULL,EVP_sha256(),NULL);
+    if (memcmp(md,app_b1,sizeof(app_b1)))
+    {	fflush(stdout);
+	fprintf(stderr,"\nTEST 1 of 3 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    EVP_Digest ("abcdbcde""cdefdefg""efghfghi""ghijhijk"
+		"ijkljklm""klmnlmno""mnopnopq",56,md,NULL,EVP_sha256(),NULL);
+    if (memcmp(md,app_b2,sizeof(app_b2)))
+    {	fflush(stdout);
+	fprintf(stderr,"\nTEST 2 of 3 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    EVP_MD_CTX_init (&evp);
+    EVP_DigestInit_ex (&evp,EVP_sha256(),NULL);
+    for (i=0;i<1000000;i+=160)
+	EVP_DigestUpdate (&evp,	"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
+				(1000000-i)<160?1000000-i:160);
+    EVP_DigestFinal_ex (&evp,md,NULL);
+    EVP_MD_CTX_cleanup (&evp);
+
+    if (memcmp(md,app_b3,sizeof(app_b3)))
+    {	fflush(stdout);
+	fprintf(stderr,"\nTEST 3 of 3 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    fprintf(stdout," passed.\n"); fflush(stdout);
+
+    fprintf(stdout,"Testing SHA-224 ");
+
+    EVP_Digest ("abc",3,md,NULL,EVP_sha224(),NULL);
+    if (memcmp(md,addenum_1,sizeof(addenum_1)))
+    {	fflush(stdout);
+	fprintf(stderr,"\nTEST 1 of 3 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    EVP_Digest ("abcdbcde""cdefdefg""efghfghi""ghijhijk"
+		"ijkljklm""klmnlmno""mnopnopq",56,md,NULL,EVP_sha224(),NULL);
+    if (memcmp(md,addenum_2,sizeof(addenum_2)))
+    {	fflush(stdout);
+	fprintf(stderr,"\nTEST 2 of 3 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    EVP_MD_CTX_init (&evp);
+    EVP_DigestInit_ex (&evp,EVP_sha224(),NULL);
+    for (i=0;i<1000000;i+=64)
+	EVP_DigestUpdate (&evp,	"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
+				(1000000-i)<64?1000000-i:64);
+    EVP_DigestFinal_ex (&evp,md,NULL);
+    EVP_MD_CTX_cleanup (&evp);
+
+    if (memcmp(md,addenum_3,sizeof(addenum_3)))
+    {	fflush(stdout);
+	fprintf(stderr,"\nTEST 3 of 3 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    fprintf(stdout," passed.\n"); fflush(stdout);
+
+  return 0;
+}
+#endif
diff --git a/openssl/crypto/sha/sha512.c b/openssl/crypto/sha/sha512.c
new file mode 100644
index 0000000..cbc0e58
--- /dev/null
+++ b/openssl/crypto/sha/sha512.c
@@ -0,0 +1,641 @@
+/* crypto/sha/sha512.c */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved
+ * according to the OpenSSL license [found in ../../LICENSE].
+ * ====================================================================
+ */
+#include <openssl/opensslconf.h>
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512)
+/*
+ * IMPLEMENTATION NOTES.
+ *
+ * As you might have noticed 32-bit hash algorithms:
+ *
+ * - permit SHA_LONG to be wider than 32-bit (case on CRAY);
+ * - optimized versions implement two transform functions: one operating
+ *   on [aligned] data in host byte order and one - on data in input
+ *   stream byte order;
+ * - share common byte-order neutral collector and padding function
+ *   implementations, ../md32_common.h;
+ *
+ * Neither of the above applies to this SHA-512 implementations. Reasons
+ * [in reverse order] are:
+ *
+ * - it's the only 64-bit hash algorithm for the moment of this writing,
+ *   there is no need for common collector/padding implementation [yet];
+ * - by supporting only one transform function [which operates on
+ *   *aligned* data in input stream byte order, big-endian in this case]
+ *   we minimize burden of maintenance in two ways: a) collector/padding
+ *   function is simpler; b) only one transform function to stare at;
+ * - SHA_LONG64 is required to be exactly 64-bit in order to be able to
+ *   apply a number of optimizations to mitigate potential performance
+ *   penalties caused by previous design decision;
+ *
+ * Caveat lector.
+ *
+ * Implementation relies on the fact that "long long" is 64-bit on
+ * both 32- and 64-bit platforms. If some compiler vendor comes up
+ * with 128-bit long long, adjustment to sha.h would be required.
+ * As this implementation relies on 64-bit integer type, it's totally
+ * inappropriate for platforms which don't support it, most notably
+ * 16-bit platforms.
+ *					<appro@fy.chalmers.se>
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/crypto.h>
+#include <openssl/sha.h>
+#include <openssl/opensslv.h>
+
+#include "cryptlib.h"
+
+const char SHA512_version[]="SHA-512" OPENSSL_VERSION_PTEXT;
+
+#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
+    defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || \
+    defined(__s390__) || defined(__s390x__) || \
+    defined(SHA512_ASM)
+#define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
+#endif
+
+int SHA384_Init (SHA512_CTX *c)
+	{
+#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm))
+	/* maintain dword order required by assembler module */
+	unsigned int *h = (unsigned int *)c->h;
+
+	h[0]  = 0xcbbb9d5d; h[1]  = 0xc1059ed8;
+	h[2]  = 0x629a292a; h[3]  = 0x367cd507;
+	h[4]  = 0x9159015a; h[5]  = 0x3070dd17;
+	h[6]  = 0x152fecd8; h[7]  = 0xf70e5939;
+	h[8]  = 0x67332667; h[9]  = 0xffc00b31;
+	h[10] = 0x8eb44a87; h[11] = 0x68581511;
+	h[12] = 0xdb0c2e0d; h[13] = 0x64f98fa7;
+	h[14] = 0x47b5481d; h[15] = 0xbefa4fa4;
+#else
+	c->h[0]=U64(0xcbbb9d5dc1059ed8);
+	c->h[1]=U64(0x629a292a367cd507);
+	c->h[2]=U64(0x9159015a3070dd17);
+	c->h[3]=U64(0x152fecd8f70e5939);
+	c->h[4]=U64(0x67332667ffc00b31);
+	c->h[5]=U64(0x8eb44a8768581511);
+	c->h[6]=U64(0xdb0c2e0d64f98fa7);
+	c->h[7]=U64(0x47b5481dbefa4fa4);
+#endif
+        c->Nl=0;        c->Nh=0;
+        c->num=0;       c->md_len=SHA384_DIGEST_LENGTH;
+        return 1;
+	}
+
+int SHA512_Init (SHA512_CTX *c)
+	{
+#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm))
+	/* maintain dword order required by assembler module */
+	unsigned int *h = (unsigned int *)c->h;
+
+	h[0]  = 0x6a09e667; h[1]  = 0xf3bcc908;
+	h[2]  = 0xbb67ae85; h[3]  = 0x84caa73b;
+	h[4]  = 0x3c6ef372; h[5]  = 0xfe94f82b;
+	h[6]  = 0xa54ff53a; h[7]  = 0x5f1d36f1;
+	h[8]  = 0x510e527f; h[9]  = 0xade682d1;
+	h[10] = 0x9b05688c; h[11] = 0x2b3e6c1f;
+	h[12] = 0x1f83d9ab; h[13] = 0xfb41bd6b;
+	h[14] = 0x5be0cd19; h[15] = 0x137e2179;
+#else
+	c->h[0]=U64(0x6a09e667f3bcc908);
+	c->h[1]=U64(0xbb67ae8584caa73b);
+	c->h[2]=U64(0x3c6ef372fe94f82b);
+	c->h[3]=U64(0xa54ff53a5f1d36f1);
+	c->h[4]=U64(0x510e527fade682d1);
+	c->h[5]=U64(0x9b05688c2b3e6c1f);
+	c->h[6]=U64(0x1f83d9abfb41bd6b);
+	c->h[7]=U64(0x5be0cd19137e2179);
+#endif
+        c->Nl=0;        c->Nh=0;
+        c->num=0;       c->md_len=SHA512_DIGEST_LENGTH;
+        return 1;
+	}
+
+#ifndef SHA512_ASM
+static
+#endif
+void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num);
+
+int SHA512_Final (unsigned char *md, SHA512_CTX *c)
+	{
+	unsigned char *p=(unsigned char *)c->u.p;
+	size_t n=c->num;
+
+	p[n]=0x80;	/* There always is a room for one */
+	n++;
+	if (n > (sizeof(c->u)-16))
+		memset (p+n,0,sizeof(c->u)-n), n=0,
+		sha512_block_data_order (c,p,1);
+
+	memset (p+n,0,sizeof(c->u)-16-n);
+#ifdef	B_ENDIAN
+	c->u.d[SHA_LBLOCK-2] = c->Nh;
+	c->u.d[SHA_LBLOCK-1] = c->Nl;
+#else
+	p[sizeof(c->u)-1]  = (unsigned char)(c->Nl);
+	p[sizeof(c->u)-2]  = (unsigned char)(c->Nl>>8);
+	p[sizeof(c->u)-3]  = (unsigned char)(c->Nl>>16);
+	p[sizeof(c->u)-4]  = (unsigned char)(c->Nl>>24);
+	p[sizeof(c->u)-5]  = (unsigned char)(c->Nl>>32);
+	p[sizeof(c->u)-6]  = (unsigned char)(c->Nl>>40);
+	p[sizeof(c->u)-7]  = (unsigned char)(c->Nl>>48);
+	p[sizeof(c->u)-8]  = (unsigned char)(c->Nl>>56);
+	p[sizeof(c->u)-9]  = (unsigned char)(c->Nh);
+	p[sizeof(c->u)-10] = (unsigned char)(c->Nh>>8);
+	p[sizeof(c->u)-11] = (unsigned char)(c->Nh>>16);
+	p[sizeof(c->u)-12] = (unsigned char)(c->Nh>>24);
+	p[sizeof(c->u)-13] = (unsigned char)(c->Nh>>32);
+	p[sizeof(c->u)-14] = (unsigned char)(c->Nh>>40);
+	p[sizeof(c->u)-15] = (unsigned char)(c->Nh>>48);
+	p[sizeof(c->u)-16] = (unsigned char)(c->Nh>>56);
+#endif
+
+	sha512_block_data_order (c,p,1);
+
+	if (md==0) return 0;
+
+#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm))
+	/* recall assembler dword order... */
+	n = c->md_len;
+	if (n == SHA384_DIGEST_LENGTH || n == SHA512_DIGEST_LENGTH)
+		{
+		unsigned int *h = (unsigned int *)c->h, t;
+
+		for (n/=4;n;n--)
+			{
+			t = *(h++);
+			*(md++) = (unsigned char)(t>>24);
+			*(md++) = (unsigned char)(t>>16);
+			*(md++) = (unsigned char)(t>>8);
+			*(md++) = (unsigned char)(t);
+			}
+		}
+	else	return 0;
+#else
+	switch (c->md_len)
+		{
+		/* Let compiler decide if it's appropriate to unroll... */
+		case SHA384_DIGEST_LENGTH:
+			for (n=0;n<SHA384_DIGEST_LENGTH/8;n++)
+				{
+				SHA_LONG64 t = c->h[n];
+
+				*(md++)	= (unsigned char)(t>>56);
+				*(md++)	= (unsigned char)(t>>48);
+				*(md++)	= (unsigned char)(t>>40);
+				*(md++)	= (unsigned char)(t>>32);
+				*(md++)	= (unsigned char)(t>>24);
+				*(md++)	= (unsigned char)(t>>16);
+				*(md++)	= (unsigned char)(t>>8);
+				*(md++)	= (unsigned char)(t);
+				}
+			break;
+		case SHA512_DIGEST_LENGTH:
+			for (n=0;n<SHA512_DIGEST_LENGTH/8;n++)
+				{
+				SHA_LONG64 t = c->h[n];
+
+				*(md++)	= (unsigned char)(t>>56);
+				*(md++)	= (unsigned char)(t>>48);
+				*(md++)	= (unsigned char)(t>>40);
+				*(md++)	= (unsigned char)(t>>32);
+				*(md++)	= (unsigned char)(t>>24);
+				*(md++)	= (unsigned char)(t>>16);
+				*(md++)	= (unsigned char)(t>>8);
+				*(md++)	= (unsigned char)(t);
+				}
+			break;
+		/* ... as well as make sure md_len is not abused. */
+		default:	return 0;
+		}
+#endif
+	return 1;
+	}
+
+int SHA384_Final (unsigned char *md,SHA512_CTX *c)
+{   return SHA512_Final (md,c);   }
+
+int SHA512_Update (SHA512_CTX *c, const void *_data, size_t len)
+	{
+	SHA_LONG64	l;
+	unsigned char  *p=c->u.p;
+	const unsigned char *data=(const unsigned char *)_data;
+
+	if (len==0) return  1;
+
+	l = (c->Nl+(((SHA_LONG64)len)<<3))&U64(0xffffffffffffffff);
+	if (l < c->Nl)		c->Nh++;
+	if (sizeof(len)>=8)	c->Nh+=(((SHA_LONG64)len)>>61);
+	c->Nl=l;
+
+	if (c->num != 0)
+		{
+		size_t n = sizeof(c->u) - c->num;
+
+		if (len < n)
+			{
+			memcpy (p+c->num,data,len), c->num += (unsigned int)len;
+			return 1;
+			}
+		else	{
+			memcpy (p+c->num,data,n), c->num = 0;
+			len-=n, data+=n;
+			sha512_block_data_order (c,p,1);
+			}
+		}
+
+	if (len >= sizeof(c->u))
+		{
+#ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
+		if ((size_t)data%sizeof(c->u.d[0]) != 0)
+			while (len >= sizeof(c->u))
+				memcpy (p,data,sizeof(c->u)),
+				sha512_block_data_order (c,p,1),
+				len  -= sizeof(c->u),
+				data += sizeof(c->u);
+		else
+#endif
+			sha512_block_data_order (c,data,len/sizeof(c->u)),
+			data += len,
+			len  %= sizeof(c->u),
+			data -= len;
+		}
+
+	if (len != 0)	memcpy (p,data,len), c->num = (int)len;
+
+	return 1;
+	}
+
+int SHA384_Update (SHA512_CTX *c, const void *data, size_t len)
+{   return SHA512_Update (c,data,len);   }
+
+void SHA512_Transform (SHA512_CTX *c, const unsigned char *data)
+{   sha512_block_data_order (c,data,1);  }
+
+unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md)
+	{
+	SHA512_CTX c;
+	static unsigned char m[SHA384_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	SHA384_Init(&c);
+	SHA512_Update(&c,d,n);
+	SHA512_Final(md,&c);
+	OPENSSL_cleanse(&c,sizeof(c));
+	return(md);
+	}
+
+unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md)
+	{
+	SHA512_CTX c;
+	static unsigned char m[SHA512_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	SHA512_Init(&c);
+	SHA512_Update(&c,d,n);
+	SHA512_Final(md,&c);
+	OPENSSL_cleanse(&c,sizeof(c));
+	return(md);
+	}
+
+#ifndef SHA512_ASM
+static const SHA_LONG64 K512[80] = {
+        U64(0x428a2f98d728ae22),U64(0x7137449123ef65cd),
+        U64(0xb5c0fbcfec4d3b2f),U64(0xe9b5dba58189dbbc),
+        U64(0x3956c25bf348b538),U64(0x59f111f1b605d019),
+        U64(0x923f82a4af194f9b),U64(0xab1c5ed5da6d8118),
+        U64(0xd807aa98a3030242),U64(0x12835b0145706fbe),
+        U64(0x243185be4ee4b28c),U64(0x550c7dc3d5ffb4e2),
+        U64(0x72be5d74f27b896f),U64(0x80deb1fe3b1696b1),
+        U64(0x9bdc06a725c71235),U64(0xc19bf174cf692694),
+        U64(0xe49b69c19ef14ad2),U64(0xefbe4786384f25e3),
+        U64(0x0fc19dc68b8cd5b5),U64(0x240ca1cc77ac9c65),
+        U64(0x2de92c6f592b0275),U64(0x4a7484aa6ea6e483),
+        U64(0x5cb0a9dcbd41fbd4),U64(0x76f988da831153b5),
+        U64(0x983e5152ee66dfab),U64(0xa831c66d2db43210),
+        U64(0xb00327c898fb213f),U64(0xbf597fc7beef0ee4),
+        U64(0xc6e00bf33da88fc2),U64(0xd5a79147930aa725),
+        U64(0x06ca6351e003826f),U64(0x142929670a0e6e70),
+        U64(0x27b70a8546d22ffc),U64(0x2e1b21385c26c926),
+        U64(0x4d2c6dfc5ac42aed),U64(0x53380d139d95b3df),
+        U64(0x650a73548baf63de),U64(0x766a0abb3c77b2a8),
+        U64(0x81c2c92e47edaee6),U64(0x92722c851482353b),
+        U64(0xa2bfe8a14cf10364),U64(0xa81a664bbc423001),
+        U64(0xc24b8b70d0f89791),U64(0xc76c51a30654be30),
+        U64(0xd192e819d6ef5218),U64(0xd69906245565a910),
+        U64(0xf40e35855771202a),U64(0x106aa07032bbd1b8),
+        U64(0x19a4c116b8d2d0c8),U64(0x1e376c085141ab53),
+        U64(0x2748774cdf8eeb99),U64(0x34b0bcb5e19b48a8),
+        U64(0x391c0cb3c5c95a63),U64(0x4ed8aa4ae3418acb),
+        U64(0x5b9cca4f7763e373),U64(0x682e6ff3d6b2b8a3),
+        U64(0x748f82ee5defb2fc),U64(0x78a5636f43172f60),
+        U64(0x84c87814a1f0ab72),U64(0x8cc702081a6439ec),
+        U64(0x90befffa23631e28),U64(0xa4506cebde82bde9),
+        U64(0xbef9a3f7b2c67915),U64(0xc67178f2e372532b),
+        U64(0xca273eceea26619c),U64(0xd186b8c721c0c207),
+        U64(0xeada7dd6cde0eb1e),U64(0xf57d4f7fee6ed178),
+        U64(0x06f067aa72176fba),U64(0x0a637dc5a2c898a6),
+        U64(0x113f9804bef90dae),U64(0x1b710b35131c471b),
+        U64(0x28db77f523047d84),U64(0x32caab7b40c72493),
+        U64(0x3c9ebe0a15c9bebc),U64(0x431d67c49c100d4c),
+        U64(0x4cc5d4becb3e42b6),U64(0x597f299cfc657e2a),
+        U64(0x5fcb6fab3ad6faec),U64(0x6c44198c4a475817) };
+
+#ifndef PEDANTIC
+# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+#  if defined(__x86_64) || defined(__x86_64__)
+#   define ROTR(a,n)	({ SHA_LONG64 ret;		\
+				asm ("rorq %1,%0"	\
+				: "=r"(ret)		\
+				: "J"(n),"0"(a)		\
+				: "cc"); ret;		})
+#   if !defined(B_ENDIAN)
+#    define PULL64(x) ({ SHA_LONG64 ret=*((const SHA_LONG64 *)(&(x)));	\
+				asm ("bswapq	%0"		\
+				: "=r"(ret)			\
+				: "0"(ret)); ret;		})
+#   endif
+#  elif (defined(__i386) || defined(__i386__)) && !defined(B_ENDIAN)
+#   if defined(I386_ONLY)
+#    define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\
+			 unsigned int hi=p[0],lo=p[1];		\
+				asm("xchgb %%ah,%%al;xchgb %%dh,%%dl;"\
+				    "roll $16,%%eax; roll $16,%%edx; "\
+				    "xchgb %%ah,%%al;xchgb %%dh,%%dl;" \
+				: "=a"(lo),"=d"(hi)		\
+				: "0"(lo),"1"(hi) : "cc");	\
+				((SHA_LONG64)hi)<<32|lo;	})
+#   else
+#    define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\
+			 unsigned int hi=p[0],lo=p[1];		\
+				asm ("bswapl %0; bswapl %1;"	\
+				: "=r"(lo),"=r"(hi)		\
+				: "0"(lo),"1"(hi));		\
+				((SHA_LONG64)hi)<<32|lo;	})
+#   endif
+#  elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64)
+#   define ROTR(a,n)	({ SHA_LONG64 ret;		\
+				asm ("rotrdi %0,%1,%2"	\
+				: "=r"(ret)		\
+				: "r"(a),"K"(n)); ret;	})
+#  endif
+# elif defined(_MSC_VER)
+#  if defined(_WIN64)	/* applies to both IA-64 and AMD64 */
+#   pragma intrinsic(_rotr64)
+#   define ROTR(a,n)	_rotr64((a),n)
+#  endif
+#  if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+#   if defined(I386_ONLY)
+    static SHA_LONG64 __fastcall __pull64be(const void *x)
+    {	_asm	mov	edx, [ecx + 0]
+	_asm	mov	eax, [ecx + 4]
+	_asm	xchg	dh,dl
+	_asm	xchg	ah,al
+	_asm	rol	edx,16
+	_asm	rol	eax,16
+	_asm	xchg	dh,dl
+	_asm	xchg	ah,al
+    }
+#   else
+    static SHA_LONG64 __fastcall __pull64be(const void *x)
+    {	_asm	mov	edx, [ecx + 0]
+	_asm	mov	eax, [ecx + 4]
+	_asm	bswap	edx
+	_asm	bswap	eax
+    }
+#   endif
+#   define PULL64(x) __pull64be(&(x))
+#   if _MSC_VER<=1200
+#    pragma inline_depth(0)
+#   endif
+#  endif
+# endif
+#endif
+
+#ifndef PULL64
+#define B(x,j)    (((SHA_LONG64)(*(((const unsigned char *)(&x))+j)))<<((7-j)*8))
+#define PULL64(x) (B(x,0)|B(x,1)|B(x,2)|B(x,3)|B(x,4)|B(x,5)|B(x,6)|B(x,7))
+#endif
+
+#ifndef ROTR
+#define ROTR(x,s)	(((x)>>s) | (x)<<(64-s))
+#endif
+
+#define Sigma0(x)	(ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
+#define Sigma1(x)	(ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
+#define sigma0(x)	(ROTR((x),1)  ^ ROTR((x),8)  ^ ((x)>>7))
+#define sigma1(x)	(ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
+
+#define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+
+#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
+/*
+ * This code should give better results on 32-bit CPU with less than
+ * ~24 registers, both size and performance wise...
+ */
+static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
+	{
+	const SHA_LONG64 *W=in;
+	SHA_LONG64	A,E,T;
+	SHA_LONG64	X[9+80],*F;
+	int i;
+
+			while (num--) {
+
+	F    = X+80;
+	A    = ctx->h[0];	F[1] = ctx->h[1];
+	F[2] = ctx->h[2];	F[3] = ctx->h[3];
+	E    = ctx->h[4];	F[5] = ctx->h[5];
+	F[6] = ctx->h[6];	F[7] = ctx->h[7];
+
+	for (i=0;i<16;i++,F--)
+		{
+#ifdef B_ENDIAN
+		T = W[i];
+#else
+		T = PULL64(W[i]);
+#endif
+		F[0] = A;
+		F[4] = E;
+		F[8] = T;
+		T   += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i];
+		E    = F[3] + T;
+		A    = T + Sigma0(A) + Maj(A,F[1],F[2]);
+		}
+
+	for (;i<80;i++,F--)
+		{
+		T    = sigma0(F[8+16-1]);
+		T   += sigma1(F[8+16-14]);
+		T   += F[8+16] + F[8+16-9];
+
+		F[0] = A;
+		F[4] = E;
+		F[8] = T;
+		T   += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i];
+		E    = F[3] + T;
+		A    = T + Sigma0(A) + Maj(A,F[1],F[2]);
+		}
+
+	ctx->h[0] += A;		ctx->h[1] += F[1];
+	ctx->h[2] += F[2];	ctx->h[3] += F[3];
+	ctx->h[4] += E;		ctx->h[5] += F[5];
+	ctx->h[6] += F[6];	ctx->h[7] += F[7];
+
+			W+=SHA_LBLOCK;
+			}
+	}
+
+#elif defined(OPENSSL_SMALL_FOOTPRINT)
+
+static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
+	{
+	const SHA_LONG64 *W=in;
+	SHA_LONG64	a,b,c,d,e,f,g,h,s0,s1,T1,T2;
+	SHA_LONG64	X[16];
+	int i;
+
+			while (num--) {
+
+	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3];
+	e = ctx->h[4];	f = ctx->h[5];	g = ctx->h[6];	h = ctx->h[7];
+
+	for (i=0;i<16;i++)
+		{
+#ifdef B_ENDIAN
+		T1 = X[i] = W[i];
+#else
+		T1 = X[i] = PULL64(W[i]);
+#endif
+		T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i];
+		T2 = Sigma0(a) + Maj(a,b,c);
+		h = g;	g = f;	f = e;	e = d + T1;
+		d = c;	c = b;	b = a;	a = T1 + T2;
+		}
+
+	for (;i<80;i++)
+		{
+		s0 = X[(i+1)&0x0f];	s0 = sigma0(s0);
+		s1 = X[(i+14)&0x0f];	s1 = sigma1(s1);
+
+		T1 = X[i&0xf] += s0 + s1 + X[(i+9)&0xf];
+		T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i];
+		T2 = Sigma0(a) + Maj(a,b,c);
+		h = g;	g = f;	f = e;	e = d + T1;
+		d = c;	c = b;	b = a;	a = T1 + T2;
+		}
+
+	ctx->h[0] += a;	ctx->h[1] += b;	ctx->h[2] += c;	ctx->h[3] += d;
+	ctx->h[4] += e;	ctx->h[5] += f;	ctx->h[6] += g;	ctx->h[7] += h;
+
+			W+=SHA_LBLOCK;
+			}
+	}
+
+#else
+
+#define	ROUND_00_15(i,a,b,c,d,e,f,g,h)		do {	\
+	T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i];	\
+	h = Sigma0(a) + Maj(a,b,c);			\
+	d += T1;	h += T1;		} while (0)
+
+#define	ROUND_16_80(i,j,a,b,c,d,e,f,g,h,X)	do {	\
+	s0 = X[(j+1)&0x0f];	s0 = sigma0(s0);	\
+	s1 = X[(j+14)&0x0f];	s1 = sigma1(s1);	\
+	T1 = X[(j)&0x0f] += s0 + s1 + X[(j+9)&0x0f];	\
+	ROUND_00_15(i+j,a,b,c,d,e,f,g,h);		} while (0)
+
+static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
+	{
+	const SHA_LONG64 *W=in;
+	SHA_LONG64	a,b,c,d,e,f,g,h,s0,s1,T1;
+	SHA_LONG64	X[16];
+	int i;
+
+			while (num--) {
+
+	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3];
+	e = ctx->h[4];	f = ctx->h[5];	g = ctx->h[6];	h = ctx->h[7];
+
+#ifdef B_ENDIAN
+	T1 = X[0] = W[0];	ROUND_00_15(0,a,b,c,d,e,f,g,h);
+	T1 = X[1] = W[1];	ROUND_00_15(1,h,a,b,c,d,e,f,g);
+	T1 = X[2] = W[2];	ROUND_00_15(2,g,h,a,b,c,d,e,f);
+	T1 = X[3] = W[3];	ROUND_00_15(3,f,g,h,a,b,c,d,e);
+	T1 = X[4] = W[4];	ROUND_00_15(4,e,f,g,h,a,b,c,d);
+	T1 = X[5] = W[5];	ROUND_00_15(5,d,e,f,g,h,a,b,c);
+	T1 = X[6] = W[6];	ROUND_00_15(6,c,d,e,f,g,h,a,b);
+	T1 = X[7] = W[7];	ROUND_00_15(7,b,c,d,e,f,g,h,a);
+	T1 = X[8] = W[8];	ROUND_00_15(8,a,b,c,d,e,f,g,h);
+	T1 = X[9] = W[9];	ROUND_00_15(9,h,a,b,c,d,e,f,g);
+	T1 = X[10] = W[10];	ROUND_00_15(10,g,h,a,b,c,d,e,f);
+	T1 = X[11] = W[11];	ROUND_00_15(11,f,g,h,a,b,c,d,e);
+	T1 = X[12] = W[12];	ROUND_00_15(12,e,f,g,h,a,b,c,d);
+	T1 = X[13] = W[13];	ROUND_00_15(13,d,e,f,g,h,a,b,c);
+	T1 = X[14] = W[14];	ROUND_00_15(14,c,d,e,f,g,h,a,b);
+	T1 = X[15] = W[15];	ROUND_00_15(15,b,c,d,e,f,g,h,a);
+#else
+	T1 = X[0]  = PULL64(W[0]);	ROUND_00_15(0,a,b,c,d,e,f,g,h);
+	T1 = X[1]  = PULL64(W[1]);	ROUND_00_15(1,h,a,b,c,d,e,f,g);
+	T1 = X[2]  = PULL64(W[2]);	ROUND_00_15(2,g,h,a,b,c,d,e,f);
+	T1 = X[3]  = PULL64(W[3]);	ROUND_00_15(3,f,g,h,a,b,c,d,e);
+	T1 = X[4]  = PULL64(W[4]);	ROUND_00_15(4,e,f,g,h,a,b,c,d);
+	T1 = X[5]  = PULL64(W[5]);	ROUND_00_15(5,d,e,f,g,h,a,b,c);
+	T1 = X[6]  = PULL64(W[6]);	ROUND_00_15(6,c,d,e,f,g,h,a,b);
+	T1 = X[7]  = PULL64(W[7]);	ROUND_00_15(7,b,c,d,e,f,g,h,a);
+	T1 = X[8]  = PULL64(W[8]);	ROUND_00_15(8,a,b,c,d,e,f,g,h);
+	T1 = X[9]  = PULL64(W[9]);	ROUND_00_15(9,h,a,b,c,d,e,f,g);
+	T1 = X[10] = PULL64(W[10]);	ROUND_00_15(10,g,h,a,b,c,d,e,f);
+	T1 = X[11] = PULL64(W[11]);	ROUND_00_15(11,f,g,h,a,b,c,d,e);
+	T1 = X[12] = PULL64(W[12]);	ROUND_00_15(12,e,f,g,h,a,b,c,d);
+	T1 = X[13] = PULL64(W[13]);	ROUND_00_15(13,d,e,f,g,h,a,b,c);
+	T1 = X[14] = PULL64(W[14]);	ROUND_00_15(14,c,d,e,f,g,h,a,b);
+	T1 = X[15] = PULL64(W[15]);	ROUND_00_15(15,b,c,d,e,f,g,h,a);
+#endif
+
+	for (i=16;i<80;i+=16)
+		{
+		ROUND_16_80(i, 0,a,b,c,d,e,f,g,h,X);
+		ROUND_16_80(i, 1,h,a,b,c,d,e,f,g,X);
+		ROUND_16_80(i, 2,g,h,a,b,c,d,e,f,X);
+		ROUND_16_80(i, 3,f,g,h,a,b,c,d,e,X);
+		ROUND_16_80(i, 4,e,f,g,h,a,b,c,d,X);
+		ROUND_16_80(i, 5,d,e,f,g,h,a,b,c,X);
+		ROUND_16_80(i, 6,c,d,e,f,g,h,a,b,X);
+		ROUND_16_80(i, 7,b,c,d,e,f,g,h,a,X);
+		ROUND_16_80(i, 8,a,b,c,d,e,f,g,h,X);
+		ROUND_16_80(i, 9,h,a,b,c,d,e,f,g,X);
+		ROUND_16_80(i,10,g,h,a,b,c,d,e,f,X);
+		ROUND_16_80(i,11,f,g,h,a,b,c,d,e,X);
+		ROUND_16_80(i,12,e,f,g,h,a,b,c,d,X);
+		ROUND_16_80(i,13,d,e,f,g,h,a,b,c,X);
+		ROUND_16_80(i,14,c,d,e,f,g,h,a,b,X);
+		ROUND_16_80(i,15,b,c,d,e,f,g,h,a,X);
+		}
+
+	ctx->h[0] += a;	ctx->h[1] += b;	ctx->h[2] += c;	ctx->h[3] += d;
+	ctx->h[4] += e;	ctx->h[5] += f;	ctx->h[6] += g;	ctx->h[7] += h;
+
+			W+=SHA_LBLOCK;
+			}
+	}
+
+#endif
+
+#endif /* SHA512_ASM */
+
+#else /* !OPENSSL_NO_SHA512 */
+
+#if defined(PEDANTIC) || defined(__DECC) || defined(OPENSSL_SYS_MACOSX)
+static void *dummy=&dummy;
+#endif
+
+#endif /* !OPENSSL_NO_SHA512 */
diff --git a/openssl/crypto/sha/sha512t.c b/openssl/crypto/sha/sha512t.c
new file mode 100644
index 0000000..210041d
--- /dev/null
+++ b/openssl/crypto/sha/sha512t.c
@@ -0,0 +1,184 @@
+/* crypto/sha/sha512t.c */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ * ====================================================================
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <openssl/sha.h>
+#include <openssl/evp.h>
+#include <openssl/crypto.h>
+
+#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA512)
+int main(int argc, char *argv[])
+{
+    printf("No SHA512 support\n");
+    return(0);
+}
+#else
+
+unsigned char app_c1[SHA512_DIGEST_LENGTH] = {
+	0xdd,0xaf,0x35,0xa1,0x93,0x61,0x7a,0xba,
+	0xcc,0x41,0x73,0x49,0xae,0x20,0x41,0x31,
+	0x12,0xe6,0xfa,0x4e,0x89,0xa9,0x7e,0xa2,
+	0x0a,0x9e,0xee,0xe6,0x4b,0x55,0xd3,0x9a,
+	0x21,0x92,0x99,0x2a,0x27,0x4f,0xc1,0xa8,
+	0x36,0xba,0x3c,0x23,0xa3,0xfe,0xeb,0xbd,
+	0x45,0x4d,0x44,0x23,0x64,0x3c,0xe8,0x0e,
+	0x2a,0x9a,0xc9,0x4f,0xa5,0x4c,0xa4,0x9f };
+
+unsigned char app_c2[SHA512_DIGEST_LENGTH] = {
+	0x8e,0x95,0x9b,0x75,0xda,0xe3,0x13,0xda,
+	0x8c,0xf4,0xf7,0x28,0x14,0xfc,0x14,0x3f,
+	0x8f,0x77,0x79,0xc6,0xeb,0x9f,0x7f,0xa1,
+	0x72,0x99,0xae,0xad,0xb6,0x88,0x90,0x18,
+	0x50,0x1d,0x28,0x9e,0x49,0x00,0xf7,0xe4,
+	0x33,0x1b,0x99,0xde,0xc4,0xb5,0x43,0x3a,
+	0xc7,0xd3,0x29,0xee,0xb6,0xdd,0x26,0x54,
+	0x5e,0x96,0xe5,0x5b,0x87,0x4b,0xe9,0x09 };
+
+unsigned char app_c3[SHA512_DIGEST_LENGTH] = {
+	0xe7,0x18,0x48,0x3d,0x0c,0xe7,0x69,0x64,
+	0x4e,0x2e,0x42,0xc7,0xbc,0x15,0xb4,0x63,
+	0x8e,0x1f,0x98,0xb1,0x3b,0x20,0x44,0x28,
+	0x56,0x32,0xa8,0x03,0xaf,0xa9,0x73,0xeb,
+	0xde,0x0f,0xf2,0x44,0x87,0x7e,0xa6,0x0a,
+	0x4c,0xb0,0x43,0x2c,0xe5,0x77,0xc3,0x1b,
+	0xeb,0x00,0x9c,0x5c,0x2c,0x49,0xaa,0x2e,
+	0x4e,0xad,0xb2,0x17,0xad,0x8c,0xc0,0x9b };
+
+unsigned char app_d1[SHA384_DIGEST_LENGTH] = {
+	0xcb,0x00,0x75,0x3f,0x45,0xa3,0x5e,0x8b,
+	0xb5,0xa0,0x3d,0x69,0x9a,0xc6,0x50,0x07,
+	0x27,0x2c,0x32,0xab,0x0e,0xde,0xd1,0x63,
+	0x1a,0x8b,0x60,0x5a,0x43,0xff,0x5b,0xed,
+	0x80,0x86,0x07,0x2b,0xa1,0xe7,0xcc,0x23,
+	0x58,0xba,0xec,0xa1,0x34,0xc8,0x25,0xa7 };
+
+unsigned char app_d2[SHA384_DIGEST_LENGTH] = {
+	0x09,0x33,0x0c,0x33,0xf7,0x11,0x47,0xe8,
+	0x3d,0x19,0x2f,0xc7,0x82,0xcd,0x1b,0x47,
+	0x53,0x11,0x1b,0x17,0x3b,0x3b,0x05,0xd2,
+	0x2f,0xa0,0x80,0x86,0xe3,0xb0,0xf7,0x12,
+	0xfc,0xc7,0xc7,0x1a,0x55,0x7e,0x2d,0xb9,
+	0x66,0xc3,0xe9,0xfa,0x91,0x74,0x60,0x39 };
+
+unsigned char app_d3[SHA384_DIGEST_LENGTH] = {
+	0x9d,0x0e,0x18,0x09,0x71,0x64,0x74,0xcb,
+	0x08,0x6e,0x83,0x4e,0x31,0x0a,0x4a,0x1c,
+	0xed,0x14,0x9e,0x9c,0x00,0xf2,0x48,0x52,
+	0x79,0x72,0xce,0xc5,0x70,0x4c,0x2a,0x5b,
+	0x07,0xb8,0xb3,0xdc,0x38,0xec,0xc4,0xeb,
+	0xae,0x97,0xdd,0xd8,0x7f,0x3d,0x89,0x85 };
+
+int main (int argc,char **argv)
+{ unsigned char md[SHA512_DIGEST_LENGTH];
+  int		i;
+  EVP_MD_CTX	evp;
+
+#ifdef OPENSSL_IA32_SSE2
+    /* Alternative to this is to call OpenSSL_add_all_algorithms...
+     * The below code is retained exclusively for debugging purposes. */
+    { char      *env;
+
+	if ((env=getenv("OPENSSL_ia32cap")))
+	    OPENSSL_ia32cap = strtoul (env,NULL,0);
+    }
+#endif
+
+    fprintf(stdout,"Testing SHA-512 ");
+
+    EVP_Digest ("abc",3,md,NULL,EVP_sha512(),NULL);
+    if (memcmp(md,app_c1,sizeof(app_c1)))
+    {	fflush(stdout);
+	fprintf(stderr,"\nTEST 1 of 3 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    EVP_Digest ("abcdefgh""bcdefghi""cdefghij""defghijk"
+		"efghijkl""fghijklm""ghijklmn""hijklmno"
+		"ijklmnop""jklmnopq""klmnopqr""lmnopqrs"
+		"mnopqrst""nopqrstu",112,md,NULL,EVP_sha512(),NULL);
+    if (memcmp(md,app_c2,sizeof(app_c2)))
+    {	fflush(stdout);
+	fprintf(stderr,"\nTEST 2 of 3 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    EVP_MD_CTX_init (&evp);
+    EVP_DigestInit_ex (&evp,EVP_sha512(),NULL);
+    for (i=0;i<1000000;i+=288)
+	EVP_DigestUpdate (&evp,	"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
+				(1000000-i)<288?1000000-i:288);
+    EVP_DigestFinal_ex (&evp,md,NULL);
+    EVP_MD_CTX_cleanup (&evp);
+
+    if (memcmp(md,app_c3,sizeof(app_c3)))
+    {	fflush(stdout);
+	fprintf(stderr,"\nTEST 3 of 3 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    fprintf(stdout," passed.\n"); fflush(stdout);
+
+    fprintf(stdout,"Testing SHA-384 ");
+
+    EVP_Digest ("abc",3,md,NULL,EVP_sha384(),NULL);
+    if (memcmp(md,app_d1,sizeof(app_d1)))
+    {	fflush(stdout);
+	fprintf(stderr,"\nTEST 1 of 3 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    EVP_Digest ("abcdefgh""bcdefghi""cdefghij""defghijk"
+		"efghijkl""fghijklm""ghijklmn""hijklmno"
+		"ijklmnop""jklmnopq""klmnopqr""lmnopqrs"
+		"mnopqrst""nopqrstu",112,md,NULL,EVP_sha384(),NULL);
+    if (memcmp(md,app_d2,sizeof(app_d2)))
+    {	fflush(stdout);
+	fprintf(stderr,"\nTEST 2 of 3 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    EVP_MD_CTX_init (&evp);
+    EVP_DigestInit_ex (&evp,EVP_sha384(),NULL);
+    for (i=0;i<1000000;i+=64)
+	EVP_DigestUpdate (&evp,	"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
+				(1000000-i)<64?1000000-i:64);
+    EVP_DigestFinal_ex (&evp,md,NULL);
+    EVP_MD_CTX_cleanup (&evp);
+
+    if (memcmp(md,app_d3,sizeof(app_d3)))
+    {	fflush(stdout);
+	fprintf(stderr,"\nTEST 3 of 3 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    fprintf(stdout," passed.\n"); fflush(stdout);
+
+  return 0;
+}
+#endif
diff --git a/openssl/crypto/sha/sha_dgst.c b/openssl/crypto/sha/sha_dgst.c
new file mode 100644
index 0000000..70eb560
--- /dev/null
+++ b/openssl/crypto/sha/sha_dgst.c
@@ -0,0 +1,74 @@
+/* crypto/sha/sha1dgst.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/opensslconf.h>
+#if !defined(OPENSSL_NO_SHA0) && !defined(OPENSSL_NO_SHA)
+
+#undef  SHA_1
+#define SHA_0
+
+#include <openssl/opensslv.h>
+
+const char SHA_version[]="SHA" OPENSSL_VERSION_PTEXT;
+
+/* The implementation is in ../md32_common.h */
+
+#include "sha_locl.h"
+
+#endif
+
diff --git a/openssl/crypto/sha/sha_locl.h b/openssl/crypto/sha/sha_locl.h
new file mode 100644
index 0000000..672c26e
--- /dev/null
+++ b/openssl/crypto/sha/sha_locl.h
@@ -0,0 +1,437 @@
+/* crypto/sha/sha_locl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/opensslconf.h>
+#include <openssl/sha.h>
+
+#define DATA_ORDER_IS_BIG_ENDIAN
+
+#define HASH_LONG               SHA_LONG
+#define HASH_CTX                SHA_CTX
+#define HASH_CBLOCK             SHA_CBLOCK
+#define HASH_MAKE_STRING(c,s)   do {	\
+	unsigned long ll;		\
+	ll=(c)->h0; HOST_l2c(ll,(s));	\
+	ll=(c)->h1; HOST_l2c(ll,(s));	\
+	ll=(c)->h2; HOST_l2c(ll,(s));	\
+	ll=(c)->h3; HOST_l2c(ll,(s));	\
+	ll=(c)->h4; HOST_l2c(ll,(s));	\
+	} while (0)
+
+#if defined(SHA_0)
+
+# define HASH_UPDATE             	SHA_Update
+# define HASH_TRANSFORM          	SHA_Transform
+# define HASH_FINAL              	SHA_Final
+# define HASH_INIT			SHA_Init
+# define HASH_BLOCK_DATA_ORDER   	sha_block_data_order
+# define Xupdate(a,ix,ia,ib,ic,id)	(ix=(a)=(ia^ib^ic^id))
+
+static void sha_block_data_order (SHA_CTX *c, const void *p,size_t num);
+
+#elif defined(SHA_1)
+
+# define HASH_UPDATE             	SHA1_Update
+# define HASH_TRANSFORM          	SHA1_Transform
+# define HASH_FINAL              	SHA1_Final
+# define HASH_INIT			SHA1_Init
+# define HASH_BLOCK_DATA_ORDER   	sha1_block_data_order
+# if defined(__MWERKS__) && defined(__MC68K__)
+   /* Metrowerks for Motorola fails otherwise:-( <appro@fy.chalmers.se> */
+#  define Xupdate(a,ix,ia,ib,ic,id)	do { (a)=(ia^ib^ic^id);		\
+					     ix=(a)=ROTATE((a),1);	\
+					} while (0)
+# else
+#  define Xupdate(a,ix,ia,ib,ic,id)	( (a)=(ia^ib^ic^id),	\
+					  ix=(a)=ROTATE((a),1)	\
+					)
+# endif
+
+#ifndef SHA1_ASM
+static
+#endif
+void sha1_block_data_order (SHA_CTX *c, const void *p,size_t num);
+
+#else
+# error "Either SHA_0 or SHA_1 must be defined."
+#endif
+
+#include "md32_common.h"
+
+#define INIT_DATA_h0 0x67452301UL
+#define INIT_DATA_h1 0xefcdab89UL
+#define INIT_DATA_h2 0x98badcfeUL
+#define INIT_DATA_h3 0x10325476UL
+#define INIT_DATA_h4 0xc3d2e1f0UL
+
+int HASH_INIT (SHA_CTX *c)
+	{
+	memset (c,0,sizeof(*c));
+	c->h0=INIT_DATA_h0;
+	c->h1=INIT_DATA_h1;
+	c->h2=INIT_DATA_h2;
+	c->h3=INIT_DATA_h3;
+	c->h4=INIT_DATA_h4;
+	return 1;
+	}
+
+#define K_00_19	0x5a827999UL
+#define K_20_39 0x6ed9eba1UL
+#define K_40_59 0x8f1bbcdcUL
+#define K_60_79 0xca62c1d6UL
+
+/* As  pointed out by Wei Dai <weidai@eskimo.com>, F() below can be
+ * simplified to the code in F_00_19.  Wei attributes these optimisations
+ * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
+ * #define F(x,y,z) (((x) & (y))  |  ((~(x)) & (z)))
+ * I've just become aware of another tweak to be made, again from Wei Dai,
+ * in F_40_59, (x&a)|(y&a) -> (x|y)&a
+ */
+#define	F_00_19(b,c,d)	((((c) ^ (d)) & (b)) ^ (d)) 
+#define	F_20_39(b,c,d)	((b) ^ (c) ^ (d))
+#define F_40_59(b,c,d)	(((b) & (c)) | (((b)|(c)) & (d))) 
+#define	F_60_79(b,c,d)	F_20_39(b,c,d)
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+
+#define BODY_00_15(i,a,b,c,d,e,f,xi) \
+	(f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
+	Xupdate(f,xi,xa,xb,xc,xd); \
+	(f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
+	Xupdate(f,xi,xa,xb,xc,xd); \
+	(f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+	Xupdate(f,xa,xa,xb,xc,xd); \
+	(f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+	Xupdate(f,xa,xa,xb,xc,xd); \
+	(f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+	Xupdate(f,xa,xa,xb,xc,xd); \
+	(f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#ifdef X
+#undef X
+#endif
+#ifndef MD32_XARRAY
+  /*
+   * Originally X was an array. As it's automatic it's natural
+   * to expect RISC compiler to accomodate at least part of it in
+   * the register bank, isn't it? Unfortunately not all compilers
+   * "find" this expectation reasonable:-( On order to make such
+   * compilers generate better code I replace X[] with a bunch of
+   * X0, X1, etc. See the function body below...
+   *					<appro@fy.chalmers.se>
+   */
+# define X(i)	XX##i
+#else
+  /*
+   * However! Some compilers (most notably HP C) get overwhelmed by
+   * that many local variables so that we have to have the way to
+   * fall down to the original behavior.
+   */
+# define X(i)	XX[i]
+#endif
+
+#if !defined(SHA_1) || !defined(SHA1_ASM)
+static void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, size_t num)
+	{
+	const unsigned char *data=p;
+	register unsigned MD32_REG_T A,B,C,D,E,T,l;
+#ifndef MD32_XARRAY
+	unsigned MD32_REG_T	XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+				XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
+#else
+	SHA_LONG	XX[16];
+#endif
+
+	A=c->h0;
+	B=c->h1;
+	C=c->h2;
+	D=c->h3;
+	E=c->h4;
+
+	for (;;)
+			{
+	const union { long one; char little; } is_endian = {1};
+
+	if (!is_endian.little && sizeof(SHA_LONG)==4 && ((size_t)p%4)==0)
+		{
+		const SHA_LONG *W=(const SHA_LONG *)data;
+
+		X( 0) = W[0];				X( 1) = W[ 1];
+		BODY_00_15( 0,A,B,C,D,E,T,X( 0));	X( 2) = W[ 2];
+		BODY_00_15( 1,T,A,B,C,D,E,X( 1));	X( 3) = W[ 3];
+		BODY_00_15( 2,E,T,A,B,C,D,X( 2));	X( 4) = W[ 4];
+		BODY_00_15( 3,D,E,T,A,B,C,X( 3));	X( 5) = W[ 5];
+		BODY_00_15( 4,C,D,E,T,A,B,X( 4));	X( 6) = W[ 6];
+		BODY_00_15( 5,B,C,D,E,T,A,X( 5));	X( 7) = W[ 7];
+		BODY_00_15( 6,A,B,C,D,E,T,X( 6));	X( 8) = W[ 8];
+		BODY_00_15( 7,T,A,B,C,D,E,X( 7));	X( 9) = W[ 9];
+		BODY_00_15( 8,E,T,A,B,C,D,X( 8));	X(10) = W[10];
+		BODY_00_15( 9,D,E,T,A,B,C,X( 9));	X(11) = W[11];
+		BODY_00_15(10,C,D,E,T,A,B,X(10));	X(12) = W[12];
+		BODY_00_15(11,B,C,D,E,T,A,X(11));	X(13) = W[13];
+		BODY_00_15(12,A,B,C,D,E,T,X(12));	X(14) = W[14];
+		BODY_00_15(13,T,A,B,C,D,E,X(13));	X(15) = W[15];
+		BODY_00_15(14,E,T,A,B,C,D,X(14));
+		BODY_00_15(15,D,E,T,A,B,C,X(15));
+
+		data += SHA_CBLOCK;
+		}
+	else
+		{
+		HOST_c2l(data,l); X( 0)=l;		HOST_c2l(data,l); X( 1)=l;
+		BODY_00_15( 0,A,B,C,D,E,T,X( 0));	HOST_c2l(data,l); X( 2)=l;
+		BODY_00_15( 1,T,A,B,C,D,E,X( 1));	HOST_c2l(data,l); X( 3)=l;
+		BODY_00_15( 2,E,T,A,B,C,D,X( 2));	HOST_c2l(data,l); X( 4)=l;
+		BODY_00_15( 3,D,E,T,A,B,C,X( 3));	HOST_c2l(data,l); X( 5)=l;
+		BODY_00_15( 4,C,D,E,T,A,B,X( 4));	HOST_c2l(data,l); X( 6)=l;
+		BODY_00_15( 5,B,C,D,E,T,A,X( 5));	HOST_c2l(data,l); X( 7)=l;
+		BODY_00_15( 6,A,B,C,D,E,T,X( 6));	HOST_c2l(data,l); X( 8)=l;
+		BODY_00_15( 7,T,A,B,C,D,E,X( 7));	HOST_c2l(data,l); X( 9)=l;
+		BODY_00_15( 8,E,T,A,B,C,D,X( 8));	HOST_c2l(data,l); X(10)=l;
+		BODY_00_15( 9,D,E,T,A,B,C,X( 9));	HOST_c2l(data,l); X(11)=l;
+		BODY_00_15(10,C,D,E,T,A,B,X(10));	HOST_c2l(data,l); X(12)=l;
+		BODY_00_15(11,B,C,D,E,T,A,X(11));	HOST_c2l(data,l); X(13)=l;
+		BODY_00_15(12,A,B,C,D,E,T,X(12));	HOST_c2l(data,l); X(14)=l;
+		BODY_00_15(13,T,A,B,C,D,E,X(13));	HOST_c2l(data,l); X(15)=l;
+		BODY_00_15(14,E,T,A,B,C,D,X(14));
+		BODY_00_15(15,D,E,T,A,B,C,X(15));
+		}
+
+	BODY_16_19(16,C,D,E,T,A,B,X( 0),X( 0),X( 2),X( 8),X(13));
+	BODY_16_19(17,B,C,D,E,T,A,X( 1),X( 1),X( 3),X( 9),X(14));
+	BODY_16_19(18,A,B,C,D,E,T,X( 2),X( 2),X( 4),X(10),X(15));
+	BODY_16_19(19,T,A,B,C,D,E,X( 3),X( 3),X( 5),X(11),X( 0));
+
+	BODY_20_31(20,E,T,A,B,C,D,X( 4),X( 4),X( 6),X(12),X( 1));
+	BODY_20_31(21,D,E,T,A,B,C,X( 5),X( 5),X( 7),X(13),X( 2));
+	BODY_20_31(22,C,D,E,T,A,B,X( 6),X( 6),X( 8),X(14),X( 3));
+	BODY_20_31(23,B,C,D,E,T,A,X( 7),X( 7),X( 9),X(15),X( 4));
+	BODY_20_31(24,A,B,C,D,E,T,X( 8),X( 8),X(10),X( 0),X( 5));
+	BODY_20_31(25,T,A,B,C,D,E,X( 9),X( 9),X(11),X( 1),X( 6));
+	BODY_20_31(26,E,T,A,B,C,D,X(10),X(10),X(12),X( 2),X( 7));
+	BODY_20_31(27,D,E,T,A,B,C,X(11),X(11),X(13),X( 3),X( 8));
+	BODY_20_31(28,C,D,E,T,A,B,X(12),X(12),X(14),X( 4),X( 9));
+	BODY_20_31(29,B,C,D,E,T,A,X(13),X(13),X(15),X( 5),X(10));
+	BODY_20_31(30,A,B,C,D,E,T,X(14),X(14),X( 0),X( 6),X(11));
+	BODY_20_31(31,T,A,B,C,D,E,X(15),X(15),X( 1),X( 7),X(12));
+
+	BODY_32_39(32,E,T,A,B,C,D,X( 0),X( 2),X( 8),X(13));
+	BODY_32_39(33,D,E,T,A,B,C,X( 1),X( 3),X( 9),X(14));
+	BODY_32_39(34,C,D,E,T,A,B,X( 2),X( 4),X(10),X(15));
+	BODY_32_39(35,B,C,D,E,T,A,X( 3),X( 5),X(11),X( 0));
+	BODY_32_39(36,A,B,C,D,E,T,X( 4),X( 6),X(12),X( 1));
+	BODY_32_39(37,T,A,B,C,D,E,X( 5),X( 7),X(13),X( 2));
+	BODY_32_39(38,E,T,A,B,C,D,X( 6),X( 8),X(14),X( 3));
+	BODY_32_39(39,D,E,T,A,B,C,X( 7),X( 9),X(15),X( 4));
+
+	BODY_40_59(40,C,D,E,T,A,B,X( 8),X(10),X( 0),X( 5));
+	BODY_40_59(41,B,C,D,E,T,A,X( 9),X(11),X( 1),X( 6));
+	BODY_40_59(42,A,B,C,D,E,T,X(10),X(12),X( 2),X( 7));
+	BODY_40_59(43,T,A,B,C,D,E,X(11),X(13),X( 3),X( 8));
+	BODY_40_59(44,E,T,A,B,C,D,X(12),X(14),X( 4),X( 9));
+	BODY_40_59(45,D,E,T,A,B,C,X(13),X(15),X( 5),X(10));
+	BODY_40_59(46,C,D,E,T,A,B,X(14),X( 0),X( 6),X(11));
+	BODY_40_59(47,B,C,D,E,T,A,X(15),X( 1),X( 7),X(12));
+	BODY_40_59(48,A,B,C,D,E,T,X( 0),X( 2),X( 8),X(13));
+	BODY_40_59(49,T,A,B,C,D,E,X( 1),X( 3),X( 9),X(14));
+	BODY_40_59(50,E,T,A,B,C,D,X( 2),X( 4),X(10),X(15));
+	BODY_40_59(51,D,E,T,A,B,C,X( 3),X( 5),X(11),X( 0));
+	BODY_40_59(52,C,D,E,T,A,B,X( 4),X( 6),X(12),X( 1));
+	BODY_40_59(53,B,C,D,E,T,A,X( 5),X( 7),X(13),X( 2));
+	BODY_40_59(54,A,B,C,D,E,T,X( 6),X( 8),X(14),X( 3));
+	BODY_40_59(55,T,A,B,C,D,E,X( 7),X( 9),X(15),X( 4));
+	BODY_40_59(56,E,T,A,B,C,D,X( 8),X(10),X( 0),X( 5));
+	BODY_40_59(57,D,E,T,A,B,C,X( 9),X(11),X( 1),X( 6));
+	BODY_40_59(58,C,D,E,T,A,B,X(10),X(12),X( 2),X( 7));
+	BODY_40_59(59,B,C,D,E,T,A,X(11),X(13),X( 3),X( 8));
+
+	BODY_60_79(60,A,B,C,D,E,T,X(12),X(14),X( 4),X( 9));
+	BODY_60_79(61,T,A,B,C,D,E,X(13),X(15),X( 5),X(10));
+	BODY_60_79(62,E,T,A,B,C,D,X(14),X( 0),X( 6),X(11));
+	BODY_60_79(63,D,E,T,A,B,C,X(15),X( 1),X( 7),X(12));
+	BODY_60_79(64,C,D,E,T,A,B,X( 0),X( 2),X( 8),X(13));
+	BODY_60_79(65,B,C,D,E,T,A,X( 1),X( 3),X( 9),X(14));
+	BODY_60_79(66,A,B,C,D,E,T,X( 2),X( 4),X(10),X(15));
+	BODY_60_79(67,T,A,B,C,D,E,X( 3),X( 5),X(11),X( 0));
+	BODY_60_79(68,E,T,A,B,C,D,X( 4),X( 6),X(12),X( 1));
+	BODY_60_79(69,D,E,T,A,B,C,X( 5),X( 7),X(13),X( 2));
+	BODY_60_79(70,C,D,E,T,A,B,X( 6),X( 8),X(14),X( 3));
+	BODY_60_79(71,B,C,D,E,T,A,X( 7),X( 9),X(15),X( 4));
+	BODY_60_79(72,A,B,C,D,E,T,X( 8),X(10),X( 0),X( 5));
+	BODY_60_79(73,T,A,B,C,D,E,X( 9),X(11),X( 1),X( 6));
+	BODY_60_79(74,E,T,A,B,C,D,X(10),X(12),X( 2),X( 7));
+	BODY_60_79(75,D,E,T,A,B,C,X(11),X(13),X( 3),X( 8));
+	BODY_60_79(76,C,D,E,T,A,B,X(12),X(14),X( 4),X( 9));
+	BODY_60_79(77,B,C,D,E,T,A,X(13),X(15),X( 5),X(10));
+	BODY_60_79(78,A,B,C,D,E,T,X(14),X( 0),X( 6),X(11));
+	BODY_60_79(79,T,A,B,C,D,E,X(15),X( 1),X( 7),X(12));
+	
+	c->h0=(c->h0+E)&0xffffffffL; 
+	c->h1=(c->h1+T)&0xffffffffL;
+	c->h2=(c->h2+A)&0xffffffffL;
+	c->h3=(c->h3+B)&0xffffffffL;
+	c->h4=(c->h4+C)&0xffffffffL;
+
+	if (--num == 0) break;
+
+	A=c->h0;
+	B=c->h1;
+	C=c->h2;
+	D=c->h3;
+	E=c->h4;
+
+			}
+	}
+#endif
+
+#else	/* OPENSSL_SMALL_FOOTPRINT */
+
+#define BODY_00_15(xi)		 do {	\
+	T=E+K_00_19+F_00_19(B,C,D);	\
+	E=D, D=C, C=ROTATE(B,30), B=A;	\
+	A=ROTATE(A,5)+T+xi;	    } while(0)
+
+#define BODY_16_19(xa,xb,xc,xd)	 do {	\
+	Xupdate(T,xa,xa,xb,xc,xd);	\
+	T+=E+K_00_19+F_00_19(B,C,D);	\
+	E=D, D=C, C=ROTATE(B,30), B=A;	\
+	A=ROTATE(A,5)+T;	    } while(0)
+
+#define BODY_20_39(xa,xb,xc,xd)	 do {	\
+	Xupdate(T,xa,xa,xb,xc,xd);	\
+	T+=E+K_20_39+F_20_39(B,C,D);	\
+	E=D, D=C, C=ROTATE(B,30), B=A;	\
+	A=ROTATE(A,5)+T;	    } while(0)
+
+#define BODY_40_59(xa,xb,xc,xd)	 do {	\
+	Xupdate(T,xa,xa,xb,xc,xd);	\
+	T+=E+K_40_59+F_40_59(B,C,D);	\
+	E=D, D=C, C=ROTATE(B,30), B=A;	\
+	A=ROTATE(A,5)+T;	    } while(0)
+
+#define BODY_60_79(xa,xb,xc,xd)	 do {	\
+	Xupdate(T,xa,xa,xb,xc,xd);	\
+	T=E+K_60_79+F_60_79(B,C,D);	\
+	E=D, D=C, C=ROTATE(B,30), B=A;	\
+	A=ROTATE(A,5)+T+xa;	    } while(0)
+
+#if !defined(SHA_1) || !defined(SHA1_ASM)
+static void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, size_t num)
+	{
+	const unsigned char *data=p;
+	register unsigned MD32_REG_T A,B,C,D,E,T,l;
+	int i;
+	SHA_LONG	X[16];
+
+	A=c->h0;
+	B=c->h1;
+	C=c->h2;
+	D=c->h3;
+	E=c->h4;
+
+	for (;;)
+		{
+	for (i=0;i<16;i++)
+	{ HOST_c2l(data,l); X[i]=l; BODY_00_15(X[i]); }
+	for (i=0;i<4;i++)
+	{ BODY_16_19(X[i],       X[i+2],      X[i+8],     X[(i+13)&15]); }
+	for (;i<24;i++)
+	{ BODY_20_39(X[i&15],    X[(i+2)&15], X[(i+8)&15],X[(i+13)&15]); }
+	for (i=0;i<20;i++)
+	{ BODY_40_59(X[(i+8)&15],X[(i+10)&15],X[i&15],    X[(i+5)&15]);  }
+	for (i=4;i<24;i++)
+	{ BODY_60_79(X[(i+8)&15],X[(i+10)&15],X[i&15],    X[(i+5)&15]);  }
+
+	c->h0=(c->h0+A)&0xffffffffL; 
+	c->h1=(c->h1+B)&0xffffffffL;
+	c->h2=(c->h2+C)&0xffffffffL;
+	c->h3=(c->h3+D)&0xffffffffL;
+	c->h4=(c->h4+E)&0xffffffffL;
+
+	if (--num == 0) break;
+
+	A=c->h0;
+	B=c->h1;
+	C=c->h2;
+	D=c->h3;
+	E=c->h4;
+
+		}
+	}
+#endif
+
+#endif
diff --git a/openssl/crypto/sha/sha_one.c b/openssl/crypto/sha/sha_one.c
new file mode 100644
index 0000000..3bae623
--- /dev/null
+++ b/openssl/crypto/sha/sha_one.c
@@ -0,0 +1,78 @@
+/* crypto/sha/sha_one.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/sha.h>
+#include <openssl/crypto.h>
+
+#ifndef OPENSSL_NO_SHA0
+unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md)
+	{
+	SHA_CTX c;
+	static unsigned char m[SHA_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	if (!SHA_Init(&c))
+		return NULL;
+	SHA_Update(&c,d,n);
+	SHA_Final(md,&c);
+	OPENSSL_cleanse(&c,sizeof(c));
+	return(md);
+	}
+#endif
diff --git a/openssl/crypto/sha/shatest.c b/openssl/crypto/sha/shatest.c
new file mode 100644
index 0000000..2761464
--- /dev/null
+++ b/openssl/crypto/sha/shatest.c
@@ -0,0 +1,178 @@
+/* crypto/sha/shatest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../e_os.h"
+
+#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA0)
+int main(int argc, char *argv[])
+{
+    printf("No SHA0 support\n");
+    return(0);
+}
+#else
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+#define SHA_0 /* FIPS 180 */
+#undef  SHA_1 /* FIPS 180-1 */
+
+static char *test[]={
+	"abc",
+	"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+	NULL,
+	};
+
+#ifdef SHA_0
+static char *ret[]={
+	"0164b8a914cd2a5e74c4f7ff082c4d97f1edf880",
+	"d2516ee1acfa5baf33dfc1c471e438449ef134c8",
+	};
+static char *bigret=
+	"3232affa48628a26653b5aaa44541fd90d690603";
+#endif
+#ifdef SHA_1
+static char *ret[]={
+	"a9993e364706816aba3e25717850c26c9cd0d89d",
+	"84983e441c3bd26ebaae4aa1f95129e5e54670f1",
+	};
+static char *bigret=
+	"34aa973cd4c4daa4f61eeb2bdbad27316534016f";
+#endif
+
+static char *pt(unsigned char *md);
+int main(int argc, char *argv[])
+	{
+	int i,err=0;
+	char **P,**R;
+	static unsigned char buf[1000];
+	char *p,*r;
+	EVP_MD_CTX c;
+	unsigned char md[SHA_DIGEST_LENGTH];
+
+#ifdef CHARSET_EBCDIC
+	ebcdic2ascii(test[0], test[0], strlen(test[0]));
+	ebcdic2ascii(test[1], test[1], strlen(test[1]));
+#endif
+
+	EVP_MD_CTX_init(&c);
+	P=test;
+	R=ret;
+	i=1;
+	while (*P != NULL)
+		{
+		EVP_Digest(*P,strlen(*P),md,NULL,EVP_sha(), NULL);
+		p=pt(md);
+		if (strcmp(p,*R) != 0)
+			{
+			printf("error calculating SHA on '%s'\n",*P);
+			printf("got %s instead of %s\n",p,*R);
+			err++;
+			}
+		else
+			printf("test %d ok\n",i);
+		i++;
+		R++;
+		P++;
+		}
+
+	memset(buf,'a',1000);
+#ifdef CHARSET_EBCDIC
+	ebcdic2ascii(buf, buf, 1000);
+#endif /*CHARSET_EBCDIC*/
+	EVP_DigestInit_ex(&c,EVP_sha(), NULL);
+	for (i=0; i<1000; i++)
+		EVP_DigestUpdate(&c,buf,1000);
+	EVP_DigestFinal_ex(&c,md,NULL);
+	p=pt(md);
+
+	r=bigret;
+	if (strcmp(p,r) != 0)
+		{
+		printf("error calculating SHA on '%s'\n",p);
+		printf("got %s instead of %s\n",p,r);
+		err++;
+		}
+	else
+		printf("test 3 ok\n");
+
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
+	EVP_MD_CTX_cleanup(&c);
+	EXIT(err);
+	return(0);
+	}
+
+static char *pt(unsigned char *md)
+	{
+	int i;
+	static char buf[80];
+
+	for (i=0; i<SHA_DIGEST_LENGTH; i++)
+		sprintf(&(buf[i*2]),"%02x",md[i]);
+	return(buf);
+	}
+#endif
diff --git a/openssl/crypto/sparccpuid.S b/openssl/crypto/sparccpuid.S
new file mode 100644
index 0000000..ae61f7f
--- /dev/null
+++ b/openssl/crypto/sparccpuid.S
@@ -0,0 +1,402 @@
+#if defined(__SUNPRO_C) && defined(__sparcv9)
+# define ABI64  /* They've said -xarch=v9 at command line */
+#elif defined(__GNUC__) && defined(__arch64__)
+# define ABI64  /* They've said -m64 at command line */
+#endif
+
+#ifdef ABI64
+  .register	%g2,#scratch
+  .register	%g3,#scratch
+# define	FRAME	-192
+# define	BIAS	2047
+#else
+# define	FRAME	-96
+# define	BIAS	0
+#endif
+
+.text
+.align	32
+.global	OPENSSL_wipe_cpu
+.type	OPENSSL_wipe_cpu,#function
+! Keep in mind that this does not excuse us from wiping the stack!
+! This routine wipes registers, but not the backing store [which
+! resides on the stack, toward lower addresses]. To facilitate for
+! stack wiping I return pointer to the top of stack of the *caller*.
+OPENSSL_wipe_cpu:
+	save	%sp,FRAME,%sp
+	nop
+#ifdef __sun
+#include <sys/trap.h>
+	ta	ST_CLEAN_WINDOWS
+#else
+	call	.walk.reg.wins
+#endif
+	nop
+	call	.PIC.zero.up
+	mov	.zero-(.-4),%o0
+	ld	[%o0],%f0
+	ld	[%o0],%f1
+
+	subcc	%g0,1,%o0
+	! Following is V9 "rd %ccr,%o0" instruction. However! V8
+	! specification says that it ("rd %asr2,%o0" in V8 terms) does
+	! not cause illegal_instruction trap. It therefore can be used
+	! to determine if the CPU the code is executing on is V8- or
+	! V9-compliant, as V9 returns a distinct value of 0x99,
+	! "negative" and "borrow" bits set in both %icc and %xcc.
+	.word	0x91408000	!rd	%ccr,%o0
+	cmp	%o0,0x99
+	bne	.v8
+	nop
+			! Even though we do not use %fp register bank,
+			! we wipe it as memcpy might have used it...
+			.word	0xbfa00040	!fmovd	%f0,%f62
+			.word	0xbba00040	!...
+			.word	0xb7a00040
+			.word	0xb3a00040
+			.word	0xafa00040
+			.word	0xaba00040
+			.word	0xa7a00040
+			.word	0xa3a00040
+			.word	0x9fa00040
+			.word	0x9ba00040
+			.word	0x97a00040
+			.word	0x93a00040
+			.word	0x8fa00040
+			.word	0x8ba00040
+			.word	0x87a00040
+			.word	0x83a00040	!fmovd	%f0,%f32
+.v8:			fmovs	%f1,%f31
+	clr	%o0
+			fmovs	%f0,%f30
+	clr	%o1
+			fmovs	%f1,%f29
+	clr	%o2
+			fmovs	%f0,%f28
+	clr	%o3
+			fmovs	%f1,%f27
+	clr	%o4
+			fmovs	%f0,%f26
+	clr	%o5
+			fmovs	%f1,%f25
+	clr	%o7
+			fmovs	%f0,%f24
+	clr	%l0
+			fmovs	%f1,%f23
+	clr	%l1
+			fmovs	%f0,%f22
+	clr	%l2
+			fmovs	%f1,%f21
+	clr	%l3
+			fmovs	%f0,%f20
+	clr	%l4
+			fmovs	%f1,%f19
+	clr	%l5
+			fmovs	%f0,%f18
+	clr	%l6
+			fmovs	%f1,%f17
+	clr	%l7
+			fmovs	%f0,%f16
+	clr	%i0
+			fmovs	%f1,%f15
+	clr	%i1
+			fmovs	%f0,%f14
+	clr	%i2
+			fmovs	%f1,%f13
+	clr	%i3
+			fmovs	%f0,%f12
+	clr	%i4
+			fmovs	%f1,%f11
+	clr	%i5
+			fmovs	%f0,%f10
+	clr	%g1
+			fmovs	%f1,%f9
+	clr	%g2
+			fmovs	%f0,%f8
+	clr	%g3
+			fmovs	%f1,%f7
+	clr	%g4
+			fmovs	%f0,%f6
+	clr	%g5
+			fmovs	%f1,%f5
+			fmovs	%f0,%f4
+			fmovs	%f1,%f3
+			fmovs	%f0,%f2
+
+	add	%fp,BIAS,%i0	! return pointer to caller´s top of stack
+
+	ret
+	restore
+
+.zero:	.long	0x0,0x0
+.PIC.zero.up:
+	retl
+	add	%o0,%o7,%o0
+#ifdef DEBUG
+.global	walk_reg_wins
+.type	walk_reg_wins,#function
+walk_reg_wins:
+#endif
+.walk.reg.wins:
+	save	%sp,FRAME,%sp
+	cmp	%i7,%o7
+	be	2f
+	clr	%o0
+	cmp	%o7,0	! compiler never cleans %o7...
+	be	1f	! could have been a leaf function...
+	clr	%o1
+	call	.walk.reg.wins
+	nop
+1:	clr	%o2
+	clr	%o3
+	clr	%o4
+	clr	%o5
+	clr	%o7
+	clr	%l0
+	clr	%l1
+	clr	%l2
+	clr	%l3
+	clr	%l4
+	clr	%l5
+	clr	%l6
+	clr	%l7
+	add	%o0,1,%i0	! used for debugging
+2:	ret
+	restore
+.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
+
+.global	OPENSSL_atomic_add
+.type	OPENSSL_atomic_add,#function
+.align	32
+OPENSSL_atomic_add:
+#ifndef ABI64
+	subcc	%g0,1,%o2
+	.word	0x95408000	!rd	%ccr,%o2, see comment above
+	cmp	%o2,0x99
+	be	.v9
+	nop
+	save	%sp,FRAME,%sp
+	ba	.enter
+	nop
+#ifdef __sun
+! Note that you do not have to link with libthread to call thr_yield,
+! as libc provides a stub, which is overloaded the moment you link
+! with *either* libpthread or libthread...
+#define	YIELD_CPU	thr_yield
+#else
+! applies at least to Linux and FreeBSD... Feedback expected...
+#define	YIELD_CPU	sched_yield
+#endif
+.spin:	call	YIELD_CPU
+	nop
+.enter:	ld	[%i0],%i2
+	cmp	%i2,-4096
+	be	.spin
+	mov	-1,%i2
+	swap	[%i0],%i2
+	cmp	%i2,-1
+	be	.spin
+	add	%i2,%i1,%i2
+	stbar
+	st	%i2,[%i0]
+	sra	%i2,%g0,%i0
+	ret
+	restore
+.v9:
+#endif
+	ld	[%o0],%o2
+1:	add	%o1,%o2,%o3
+	.word	0xd7e2100a	!cas [%o0],%o2,%o3, compare [%o0] with %o2 and swap %o3
+	cmp	%o2,%o3
+	bne	1b
+	mov	%o3,%o2		! cas is always fetching to dest. register
+	add	%o1,%o2,%o0	! OpenSSL expects the new value
+	retl
+	sra	%o0,%g0,%o0	! we return signed int, remember?
+.size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
+
+.global	_sparcv9_rdtick
+.align	32
+_sparcv9_rdtick:
+	subcc	%g0,1,%o0
+	.word	0x91408000	!rd	%ccr,%o0
+	cmp	%o0,0x99
+	bne	.notick
+	xor	%o0,%o0,%o0
+	.word	0x91410000	!rd	%tick,%o0
+	retl
+	.word	0x93323020	!srlx	%o0,32,%o1
+.notick:
+	retl
+	xor	%o1,%o1,%o1
+.type	_sparcv9_rdtick,#function
+.size	_sparcv9_rdtick,.-_sparcv9_rdtick
+
+.global	_sparcv9_vis1_probe
+.align	8
+_sparcv9_vis1_probe:
+	.word	0x81b00d80	!fxor	%f0,%f0,%f0
+	add	%sp,BIAS+2,%o1
+	retl
+	.word	0xc19a5a40	!ldda	[%o1]ASI_FP16_P,%f0
+.type	_sparcv9_vis1_probe,#function
+.size	_sparcv9_vis1_probe,.-_sparcv9_vis1_probe
+
+! Probe and instrument VIS1 instruction. Output is number of cycles it
+! takes to execute rdtick and pair of VIS1 instructions. US-Tx VIS unit
+! is slow (documented to be 6 cycles on T2) and the core is in-order
+! single-issue, it should be possible to distinguish Tx reliably...
+! Observed return values are:
+!
+!	UltraSPARC IIe		7
+!	UltraSPARC III		7
+!	UltraSPARC T1		24
+!
+! Numbers for T2 and SPARC64 V-VII are more than welcomed.
+!
+! It would be possible to detect specifically US-T1 by instrumenting
+! fmul8ulx16, which is emulated on T1 and as such accounts for quite
+! a lot of %tick-s, couple of thousand on Linux...
+.global	_sparcv9_vis1_instrument
+.align	8
+_sparcv9_vis1_instrument:
+	.word	0x91410000	!rd	%tick,%o0
+	.word	0x81b00d80	!fxor	%f0,%f0,%f0
+	.word	0x85b08d82	!fxor	%f2,%f2,%f2
+	.word	0x93410000	!rd	%tick,%o1
+	.word	0x81b00d80	!fxor	%f0,%f0,%f0
+	.word	0x85b08d82	!fxor	%f2,%f2,%f2
+	.word	0x95410000	!rd	%tick,%o2
+	.word	0x81b00d80	!fxor	%f0,%f0,%f0
+	.word	0x85b08d82	!fxor	%f2,%f2,%f2
+	.word	0x97410000	!rd	%tick,%o3
+	.word	0x81b00d80	!fxor	%f0,%f0,%f0
+	.word	0x85b08d82	!fxor	%f2,%f2,%f2
+	.word	0x99410000	!rd	%tick,%o4
+
+	! calculate intervals
+	sub	%o1,%o0,%o0
+	sub	%o2,%o1,%o1
+	sub	%o3,%o2,%o2
+	sub	%o4,%o3,%o3
+
+	! find minumum value
+	cmp	%o0,%o1
+	.word	0x38680002	!bgu,a	%xcc,.+8
+	mov	%o1,%o0
+	cmp	%o0,%o2
+	.word	0x38680002	!bgu,a	%xcc,.+8
+	mov	%o2,%o0
+	cmp	%o0,%o3
+	.word	0x38680002	!bgu,a	%xcc,.+8
+	mov	%o3,%o0
+
+	retl
+	nop
+.type	_sparcv9_vis1_instrument,#function
+.size	_sparcv9_vis1_instrument,.-_sparcv9_vis1_instrument
+
+.global	_sparcv9_vis2_probe
+.align	8
+_sparcv9_vis2_probe:
+	retl
+	.word	0x81b00980	!bshuffle	%f0,%f0,%f0
+.type	_sparcv9_vis2_probe,#function
+.size	_sparcv9_vis2_probe,.-_sparcv9_vis2_probe
+
+.global	_sparcv9_fmadd_probe
+.align	8
+_sparcv9_fmadd_probe:
+	.word	0x81b00d80	!fxor	%f0,%f0,%f0
+	.word	0x85b08d82	!fxor	%f2,%f2,%f2
+	retl
+	.word	0x81b80440	!fmaddd	%f0,%f0,%f2,%f0
+.type	_sparcv9_fmadd_probe,#function
+.size	_sparcv9_fmadd_probe,.-_sparcv9_fmadd_probe
+
+.global	OPENSSL_cleanse
+.align	32
+OPENSSL_cleanse:
+	cmp	%o1,14
+	nop
+#ifdef ABI64
+	bgu	%xcc,.Lot
+#else
+	bgu	.Lot
+#endif
+	cmp	%o1,0
+	bne	.Little
+	nop
+	retl
+	nop
+
+.Little:
+	stb	%g0,[%o0]
+	subcc	%o1,1,%o1
+	bnz	.Little
+	add	%o0,1,%o0
+	retl
+	nop
+.align	32
+.Lot:
+#ifndef ABI64
+	subcc	%g0,1,%g1
+	! see above for explanation
+	.word	0x83408000	!rd	%ccr,%g1
+	cmp	%g1,0x99
+	bne	.v8lot
+	nop
+#endif
+
+.v9lot:	andcc	%o0,7,%g0
+	bz	.v9aligned
+	nop
+	stb	%g0,[%o0]
+	sub	%o1,1,%o1
+	ba	.v9lot
+	add	%o0,1,%o0
+.align	16,0x01000000
+.v9aligned:
+	.word	0xc0720000	!stx	%g0,[%o0]
+	sub	%o1,8,%o1
+	andcc	%o1,-8,%g0
+#ifdef ABI64
+	.word	0x126ffffd	!bnz	%xcc,.v9aligned
+#else
+	.word	0x124ffffd	!bnz	%icc,.v9aligned
+#endif
+	add	%o0,8,%o0
+
+	cmp	%o1,0
+	bne	.Little
+	nop
+	retl
+	nop
+#ifndef ABI64
+.v8lot:	andcc	%o0,3,%g0
+	bz	.v8aligned
+	nop
+	stb	%g0,[%o0]
+	sub	%o1,1,%o1
+	ba	.v8lot
+	add	%o0,1,%o0
+	nop
+.v8aligned:
+	st	%g0,[%o0]
+	sub	%o1,4,%o1
+	andcc	%o1,-4,%g0
+	bnz	.v8aligned
+	add	%o0,4,%o0
+
+	cmp	%o1,0
+	bne	.Little
+	nop
+	retl
+	nop
+#endif
+.type	OPENSSL_cleanse,#function
+.size	OPENSSL_cleanse,.-OPENSSL_cleanse
+
+.section	".init",#alloc,#execinstr
+	call	OPENSSL_cpuid_setup
+	nop
diff --git a/openssl/crypto/sparcv9cap.c b/openssl/crypto/sparcv9cap.c
new file mode 100644
index 0000000..ed195ab
--- /dev/null
+++ b/openssl/crypto/sparcv9cap.c
@@ -0,0 +1,237 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <openssl/bn.h>
+
+#define SPARCV9_TICK_PRIVILEGED	(1<<0)
+#define SPARCV9_PREFER_FPU	(1<<1)
+#define SPARCV9_VIS1		(1<<2)
+#define SPARCV9_VIS2		(1<<3)	/* reserved */
+#define SPARCV9_FMADD		(1<<4)	/* reserved for SPARC64 V */
+
+static int OPENSSL_sparcv9cap_P=SPARCV9_TICK_PRIVILEGED;
+
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num)
+	{
+	int bn_mul_mont_fpu(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
+	int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
+
+	if ((OPENSSL_sparcv9cap_P&(SPARCV9_PREFER_FPU|SPARCV9_VIS1)) ==
+		(SPARCV9_PREFER_FPU|SPARCV9_VIS1))
+		return bn_mul_mont_fpu(rp,ap,bp,np,n0,num);
+	else
+		return bn_mul_mont_int(rp,ap,bp,np,n0,num);
+	}
+
+unsigned long	_sparcv9_rdtick(void);
+void		_sparcv9_vis1_probe(void);
+unsigned long	_sparcv9_vis1_instrument(void);
+void		_sparcv9_vis2_probe(void);
+void		_sparcv9_fmadd_probe(void);
+
+unsigned long OPENSSL_rdtsc(void)
+	{
+	if (OPENSSL_sparcv9cap_P&SPARCV9_TICK_PRIVILEGED)
+#if defined(__sun) && defined(__SVR4)
+		return gethrtime();
+#else
+		return 0;
+#endif
+	else
+		return _sparcv9_rdtick();
+	}
+
+#if 0 && defined(__sun) && defined(__SVR4)
+/* This code path is disabled, because of incompatibility of
+ * libdevinfo.so.1 and libmalloc.so.1 (see below for details)
+ */
+#include <malloc.h>
+#include <dlfcn.h>
+#include <libdevinfo.h>
+#include <sys/systeminfo.h>
+
+typedef di_node_t (*di_init_t)(const char *,uint_t);
+typedef void      (*di_fini_t)(di_node_t);
+typedef char *    (*di_node_name_t)(di_node_t);
+typedef int       (*di_walk_node_t)(di_node_t,uint_t,di_node_name_t,int (*)(di_node_t,di_node_name_t));
+
+#define DLLINK(h,name) (name=(name##_t)dlsym((h),#name))
+
+static int walk_nodename(di_node_t node, di_node_name_t di_node_name)
+	{
+	char *name = (*di_node_name)(node);
+
+	/* This is expected to catch all UltraSPARC flavors prior T1 */
+	if (!strcmp (name,"SUNW,UltraSPARC") ||
+	    !strncmp(name,"SUNW,UltraSPARC-I",17))  /* covers II,III,IV */
+		{
+		OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU|SPARCV9_VIS1;
+
+		/* %tick is privileged only on UltraSPARC-I/II, but not IIe */
+		if (name[14]!='\0' && name[17]!='\0' && name[18]!='\0')
+			OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
+
+		return DI_WALK_TERMINATE;
+		}
+	/* This is expected to catch remaining UltraSPARCs, such as T1 */
+	else if (!strncmp(name,"SUNW,UltraSPARC",15))
+		{
+		OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
+
+		return DI_WALK_TERMINATE;
+		}
+
+	return DI_WALK_CONTINUE;
+	}
+
+void OPENSSL_cpuid_setup(void)
+	{
+	void *h;
+	char *e,si[256];
+	static int trigger=0;
+
+	if (trigger) return;
+	trigger=1;
+
+	if ((e=getenv("OPENSSL_sparcv9cap")))
+		{
+		OPENSSL_sparcv9cap_P=strtoul(e,NULL,0);
+		return;
+		}
+
+	if (sysinfo(SI_MACHINE,si,sizeof(si))>0)
+		{
+		if (strcmp(si,"sun4v"))
+			/* FPU is preferred for all CPUs, but US-T1/2 */
+			OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU;
+		}
+
+	if (sysinfo(SI_ISALIST,si,sizeof(si))>0)
+		{
+		if (strstr(si,"+vis"))
+			OPENSSL_sparcv9cap_P |= SPARCV9_VIS1;
+		if (strstr(si,"+vis2"))
+			{
+			OPENSSL_sparcv9cap_P |= SPARCV9_VIS2;
+			OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
+			return;
+			}
+		}
+#ifdef M_KEEP
+	/*
+	 * Solaris libdevinfo.so.1 is effectively incomatible with
+	 * libmalloc.so.1. Specifically, if application is linked with
+	 * -lmalloc, it crashes upon startup with SIGSEGV in
+	 * free(3LIBMALLOC) called by di_fini. Prior call to
+	 * mallopt(M_KEEP,0) somehow helps... But not always...
+	 */
+	if ((h = dlopen(NULL,RTLD_LAZY)))
+		{
+		union { void *p; int (*f)(int,int); } sym;
+		if ((sym.p = dlsym(h,"mallopt"))) (*sym.f)(M_KEEP,0);
+		dlclose(h);
+		}
+#endif
+	if ((h = dlopen("libdevinfo.so.1",RTLD_LAZY))) do
+		{
+		di_init_t	di_init;
+		di_fini_t	di_fini;
+		di_walk_node_t	di_walk_node;
+		di_node_name_t	di_node_name;
+		di_node_t	root_node;
+
+		if (!DLLINK(h,di_init))		break;
+		if (!DLLINK(h,di_fini))		break;
+		if (!DLLINK(h,di_walk_node))	break;
+		if (!DLLINK(h,di_node_name))	break;
+
+		if ((root_node = (*di_init)("/",DINFOSUBTREE))!=DI_NODE_NIL)
+			{
+			(*di_walk_node)(root_node,DI_WALK_SIBFIRST,
+					di_node_name,walk_nodename);
+			(*di_fini)(root_node);
+			}
+		} while(0);
+
+	if (h) dlclose(h);
+	}
+
+#else
+
+static sigjmp_buf common_jmp;
+static void common_handler(int sig) { siglongjmp(common_jmp,sig); }
+
+void OPENSSL_cpuid_setup(void)
+	{
+	char *e;
+	struct sigaction	common_act,ill_oact,bus_oact;
+	sigset_t		all_masked,oset;
+	int			sig;
+	static int trigger=0;
+
+	if (trigger) return;
+	trigger=1;
+ 
+	if ((e=getenv("OPENSSL_sparcv9cap")))
+		{
+		OPENSSL_sparcv9cap_P=strtoul(e,NULL,0);
+		return;
+		}
+
+	/* Initial value, fits UltraSPARC-I&II... */
+	OPENSSL_sparcv9cap_P = SPARCV9_PREFER_FPU|SPARCV9_TICK_PRIVILEGED;
+
+	sigfillset(&all_masked);
+	sigdelset(&all_masked,SIGILL);
+	sigdelset(&all_masked,SIGTRAP);
+#ifdef SIGEMT
+	sigdelset(&all_masked,SIGEMT);
+#endif
+	sigdelset(&all_masked,SIGFPE);
+	sigdelset(&all_masked,SIGBUS);
+	sigdelset(&all_masked,SIGSEGV);
+	sigprocmask(SIG_SETMASK,&all_masked,&oset);
+
+	memset(&common_act,0,sizeof(common_act));
+	common_act.sa_handler = common_handler;
+	common_act.sa_mask    = all_masked;
+
+	sigaction(SIGILL,&common_act,&ill_oact);
+	sigaction(SIGBUS,&common_act,&bus_oact);/* T1 fails 16-bit ldda [on Linux] */
+
+	if (sigsetjmp(common_jmp,1) == 0)
+		{
+		_sparcv9_rdtick();
+		OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
+		}
+
+	if (sigsetjmp(common_jmp,1) == 0)
+		{
+		_sparcv9_vis1_probe();
+		OPENSSL_sparcv9cap_P |= SPARCV9_VIS1;
+		/* detect UltraSPARC-Tx, see sparccpud.S for details... */
+		if (_sparcv9_vis1_instrument() >= 12)
+			OPENSSL_sparcv9cap_P &= ~(SPARCV9_VIS1|SPARCV9_PREFER_FPU);
+		else
+			{
+			_sparcv9_vis2_probe();
+			OPENSSL_sparcv9cap_P |= SPARCV9_VIS2;
+			}
+		}
+
+	if (sigsetjmp(common_jmp,1) == 0)
+		{
+		_sparcv9_fmadd_probe();
+		OPENSSL_sparcv9cap_P |= SPARCV9_FMADD;
+		}
+
+	sigaction(SIGBUS,&bus_oact,NULL);
+	sigaction(SIGILL,&ill_oact,NULL);
+
+	sigprocmask(SIG_SETMASK,&oset,NULL);
+	}
+
+#endif
diff --git a/openssl/crypto/stack/Makefile b/openssl/crypto/stack/Makefile
new file mode 100644
index 0000000..5327692
--- /dev/null
+++ b/openssl/crypto/stack/Makefile
@@ -0,0 +1,84 @@
+#
+# OpenSSL/crypto/stack/Makefile
+#
+
+DIR=	stack
+TOP=	../..
+CC=	cc
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=stack.c
+LIBOBJ=stack.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= stack.h safestack.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+stack.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+stack.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+stack.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+stack.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+stack.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+stack.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+stack.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+stack.o: ../../include/openssl/symhacks.h ../cryptlib.h stack.c
diff --git a/openssl/crypto/stack/safestack.h b/openssl/crypto/stack/safestack.h
new file mode 100644
index 0000000..3e76aa5
--- /dev/null
+++ b/openssl/crypto/stack/safestack.h
@@ -0,0 +1,2575 @@
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_SAFESTACK_H
+#define HEADER_SAFESTACK_H
+
+#include <openssl/stack.h>
+
+#ifndef CHECKED_PTR_OF
+#define CHECKED_PTR_OF(type, p) \
+    ((void*) (1 ? p : (type*)0))
+#endif
+
+/* In C++ we get problems because an explicit cast is needed from (void *)
+ * we use CHECKED_STACK_OF to ensure the correct type is passed in the macros
+ * below. 
+ */
+
+#define CHECKED_STACK_OF(type, p) \
+    ((_STACK*) (1 ? p : (STACK_OF(type)*)0))
+
+#define CHECKED_SK_FREE_FUNC(type, p) \
+    ((void (*)(void *)) ((1 ? p : (void (*)(type *))0)))
+
+#define CHECKED_SK_FREE_FUNC2(type, p) \
+    ((void (*)(void *)) ((1 ? p : (void (*)(type))0)))
+
+#define CHECKED_SK_CMP_FUNC(type, p) \
+    ((int (*)(const void *, const void *)) \
+	((1 ? p : (int (*)(const type * const *, const type * const *))0)))
+
+#define STACK_OF(type) struct stack_st_##type
+#define PREDECLARE_STACK_OF(type) STACK_OF(type);
+
+#define DECLARE_STACK_OF(type) \
+STACK_OF(type) \
+    { \
+    _STACK stack; \
+    };
+#define DECLARE_SPECIAL_STACK_OF(type, type2) \
+STACK_OF(type) \
+    { \
+    _STACK stack; \
+    };
+
+#define IMPLEMENT_STACK_OF(type) /* nada (obsolete in new safestack approach)*/
+
+
+/* Strings are special: normally an lhash entry will point to a single
+ * (somewhat) mutable object. In the case of strings:
+ *
+ * a) Instead of a single char, there is an array of chars, NUL-terminated.
+ * b) The string may have be immutable.
+ *
+ * So, they need their own declarations. Especially important for
+ * type-checking tools, such as Deputy.
+ *
+o * In practice, however, it appears to be hard to have a const
+ * string. For now, I'm settling for dealing with the fact it is a
+ * string at all.
+ */
+typedef char *OPENSSL_STRING;
+
+typedef const char *OPENSSL_CSTRING;
+
+/* Confusingly, LHASH_OF(STRING) deals with char ** throughout, but
+ * STACK_OF(STRING) is really more like STACK_OF(char), only, as
+ * mentioned above, instead of a single char each entry is a
+ * NUL-terminated array of chars. So, we have to implement STRING
+ * specially for STACK_OF. This is dealt with in the autogenerated
+ * macros below.
+ */
+
+DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char)
+
+/* Similarly, we sometimes use a block of characters, NOT
+ * nul-terminated. These should also be distinguished from "normal"
+ * stacks. */
+
+typedef void *OPENSSL_BLOCK;
+DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
+
+/* SKM_sk_... stack macros are internal to safestack.h:
+ * never use them directly, use sk_<type>_... instead */
+#define SKM_sk_new(type, cmp) \
+	((STACK_OF(type) *)sk_new(CHECKED_SK_CMP_FUNC(type, cmp)))
+#define SKM_sk_new_null(type) \
+	((STACK_OF(type) *)sk_new_null())
+#define SKM_sk_free(type, st) \
+	sk_free(CHECKED_STACK_OF(type, st))
+#define SKM_sk_num(type, st) \
+	sk_num(CHECKED_STACK_OF(type, st))
+#define SKM_sk_value(type, st,i) \
+	((type *)sk_value(CHECKED_STACK_OF(type, st), i))
+#define SKM_sk_set(type, st,i,val) \
+	sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val))
+#define SKM_sk_zero(type, st) \
+	sk_zero(CHECKED_STACK_OF(type, st))
+#define SKM_sk_push(type, st, val) \
+	sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+#define SKM_sk_unshift(type, st, val) \
+	sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+#define SKM_sk_find(type, st, val) \
+	sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+#define SKM_sk_find_ex(type, st, val) \
+	sk_find_ex(CHECKED_STACK_OF(type, st), \
+		   CHECKED_PTR_OF(type, val))
+#define SKM_sk_delete(type, st, i) \
+	(type *)sk_delete(CHECKED_STACK_OF(type, st), i)
+#define SKM_sk_delete_ptr(type, st, ptr) \
+	(type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr))
+#define SKM_sk_insert(type, st,val, i) \
+	sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i)
+#define SKM_sk_set_cmp_func(type, st, cmp) \
+	((int (*)(const type * const *,const type * const *)) \
+	sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp)))
+#define SKM_sk_dup(type, st) \
+	(STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st))
+#define SKM_sk_pop_free(type, st, free_func) \
+	sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func))
+#define SKM_sk_shift(type, st) \
+	(type *)sk_shift(CHECKED_STACK_OF(type, st))
+#define SKM_sk_pop(type, st) \
+	(type *)sk_pop(CHECKED_STACK_OF(type, st))
+#define SKM_sk_sort(type, st) \
+	sk_sort(CHECKED_STACK_OF(type, st))
+#define SKM_sk_is_sorted(type, st) \
+	sk_is_sorted(CHECKED_STACK_OF(type, st))
+
+#define	SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+  (STACK_OF(type) *)d2i_ASN1_SET( \
+				(STACK_OF(OPENSSL_BLOCK) **)CHECKED_PTR_OF(STACK_OF(type)*, st), \
+				pp, length, \
+				CHECKED_D2I_OF(type, d2i_func), \
+				CHECKED_SK_FREE_FUNC(type, free_func), \
+				ex_tag, ex_class)
+
+#define	SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
+  i2d_ASN1_SET((STACK_OF(OPENSSL_BLOCK) *)CHECKED_STACK_OF(type, st), pp, \
+				CHECKED_I2D_OF(type, i2d_func), \
+				ex_tag, ex_class, is_set)
+
+#define	SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \
+	ASN1_seq_pack(CHECKED_PTR_OF(STACK_OF(type), st), \
+			CHECKED_I2D_OF(type, i2d_func), buf, len)
+
+#define	SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \
+	(STACK_OF(type) *)ASN1_seq_unpack(buf, len, CHECKED_D2I_OF(type, d2i_func), CHECKED_SK_FREE_FUNC(type, free_func))
+
+#define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \
+	(STACK_OF(type) *)PKCS12_decrypt_d2i(algor, \
+				CHECKED_D2I_OF(type, d2i_func), \
+				CHECKED_SK_FREE_FUNC(type, free_func), \
+				pass, passlen, oct, seq)
+
+/* This block of defines is updated by util/mkstack.pl, please do not touch! */
+#define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp))
+#define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION)
+#define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_value(st, i) SKM_sk_value(ACCESS_DESCRIPTION, (st), (i))
+#define sk_ACCESS_DESCRIPTION_set(st, i, val) SKM_sk_set(ACCESS_DESCRIPTION, (st), (i), (val))
+#define sk_ACCESS_DESCRIPTION_zero(st) SKM_sk_zero(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_push(st, val) SKM_sk_push(ACCESS_DESCRIPTION, (st), (val))
+#define sk_ACCESS_DESCRIPTION_unshift(st, val) SKM_sk_unshift(ACCESS_DESCRIPTION, (st), (val))
+#define sk_ACCESS_DESCRIPTION_find(st, val) SKM_sk_find(ACCESS_DESCRIPTION, (st), (val))
+#define sk_ACCESS_DESCRIPTION_find_ex(st, val) SKM_sk_find_ex(ACCESS_DESCRIPTION, (st), (val))
+#define sk_ACCESS_DESCRIPTION_delete(st, i) SKM_sk_delete(ACCESS_DESCRIPTION, (st), (i))
+#define sk_ACCESS_DESCRIPTION_delete_ptr(st, ptr) SKM_sk_delete_ptr(ACCESS_DESCRIPTION, (st), (ptr))
+#define sk_ACCESS_DESCRIPTION_insert(st, val, i) SKM_sk_insert(ACCESS_DESCRIPTION, (st), (val), (i))
+#define sk_ACCESS_DESCRIPTION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ACCESS_DESCRIPTION, (st), (cmp))
+#define sk_ACCESS_DESCRIPTION_dup(st) SKM_sk_dup(ACCESS_DESCRIPTION, st)
+#define sk_ACCESS_DESCRIPTION_pop_free(st, free_func) SKM_sk_pop_free(ACCESS_DESCRIPTION, (st), (free_func))
+#define sk_ACCESS_DESCRIPTION_shift(st) SKM_sk_shift(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_pop(st) SKM_sk_pop(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st))
+
+#define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp))
+#define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange)
+#define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st))
+#define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st))
+#define sk_ASIdOrRange_value(st, i) SKM_sk_value(ASIdOrRange, (st), (i))
+#define sk_ASIdOrRange_set(st, i, val) SKM_sk_set(ASIdOrRange, (st), (i), (val))
+#define sk_ASIdOrRange_zero(st) SKM_sk_zero(ASIdOrRange, (st))
+#define sk_ASIdOrRange_push(st, val) SKM_sk_push(ASIdOrRange, (st), (val))
+#define sk_ASIdOrRange_unshift(st, val) SKM_sk_unshift(ASIdOrRange, (st), (val))
+#define sk_ASIdOrRange_find(st, val) SKM_sk_find(ASIdOrRange, (st), (val))
+#define sk_ASIdOrRange_find_ex(st, val) SKM_sk_find_ex(ASIdOrRange, (st), (val))
+#define sk_ASIdOrRange_delete(st, i) SKM_sk_delete(ASIdOrRange, (st), (i))
+#define sk_ASIdOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASIdOrRange, (st), (ptr))
+#define sk_ASIdOrRange_insert(st, val, i) SKM_sk_insert(ASIdOrRange, (st), (val), (i))
+#define sk_ASIdOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASIdOrRange, (st), (cmp))
+#define sk_ASIdOrRange_dup(st) SKM_sk_dup(ASIdOrRange, st)
+#define sk_ASIdOrRange_pop_free(st, free_func) SKM_sk_pop_free(ASIdOrRange, (st), (free_func))
+#define sk_ASIdOrRange_shift(st) SKM_sk_shift(ASIdOrRange, (st))
+#define sk_ASIdOrRange_pop(st) SKM_sk_pop(ASIdOrRange, (st))
+#define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st))
+#define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st))
+
+#define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp))
+#define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING)
+#define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_value(st, i) SKM_sk_value(ASN1_GENERALSTRING, (st), (i))
+#define sk_ASN1_GENERALSTRING_set(st, i, val) SKM_sk_set(ASN1_GENERALSTRING, (st), (i), (val))
+#define sk_ASN1_GENERALSTRING_zero(st) SKM_sk_zero(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_push(st, val) SKM_sk_push(ASN1_GENERALSTRING, (st), (val))
+#define sk_ASN1_GENERALSTRING_unshift(st, val) SKM_sk_unshift(ASN1_GENERALSTRING, (st), (val))
+#define sk_ASN1_GENERALSTRING_find(st, val) SKM_sk_find(ASN1_GENERALSTRING, (st), (val))
+#define sk_ASN1_GENERALSTRING_find_ex(st, val) SKM_sk_find_ex(ASN1_GENERALSTRING, (st), (val))
+#define sk_ASN1_GENERALSTRING_delete(st, i) SKM_sk_delete(ASN1_GENERALSTRING, (st), (i))
+#define sk_ASN1_GENERALSTRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_GENERALSTRING, (st), (ptr))
+#define sk_ASN1_GENERALSTRING_insert(st, val, i) SKM_sk_insert(ASN1_GENERALSTRING, (st), (val), (i))
+#define sk_ASN1_GENERALSTRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_GENERALSTRING, (st), (cmp))
+#define sk_ASN1_GENERALSTRING_dup(st) SKM_sk_dup(ASN1_GENERALSTRING, st)
+#define sk_ASN1_GENERALSTRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_GENERALSTRING, (st), (free_func))
+#define sk_ASN1_GENERALSTRING_shift(st) SKM_sk_shift(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_pop(st) SKM_sk_pop(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st))
+
+#define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp))
+#define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER)
+#define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_value(st, i) SKM_sk_value(ASN1_INTEGER, (st), (i))
+#define sk_ASN1_INTEGER_set(st, i, val) SKM_sk_set(ASN1_INTEGER, (st), (i), (val))
+#define sk_ASN1_INTEGER_zero(st) SKM_sk_zero(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_push(st, val) SKM_sk_push(ASN1_INTEGER, (st), (val))
+#define sk_ASN1_INTEGER_unshift(st, val) SKM_sk_unshift(ASN1_INTEGER, (st), (val))
+#define sk_ASN1_INTEGER_find(st, val) SKM_sk_find(ASN1_INTEGER, (st), (val))
+#define sk_ASN1_INTEGER_find_ex(st, val) SKM_sk_find_ex(ASN1_INTEGER, (st), (val))
+#define sk_ASN1_INTEGER_delete(st, i) SKM_sk_delete(ASN1_INTEGER, (st), (i))
+#define sk_ASN1_INTEGER_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_INTEGER, (st), (ptr))
+#define sk_ASN1_INTEGER_insert(st, val, i) SKM_sk_insert(ASN1_INTEGER, (st), (val), (i))
+#define sk_ASN1_INTEGER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_INTEGER, (st), (cmp))
+#define sk_ASN1_INTEGER_dup(st) SKM_sk_dup(ASN1_INTEGER, st)
+#define sk_ASN1_INTEGER_pop_free(st, free_func) SKM_sk_pop_free(ASN1_INTEGER, (st), (free_func))
+#define sk_ASN1_INTEGER_shift(st) SKM_sk_shift(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_pop(st) SKM_sk_pop(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st))
+
+#define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp))
+#define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT)
+#define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_value(st, i) SKM_sk_value(ASN1_OBJECT, (st), (i))
+#define sk_ASN1_OBJECT_set(st, i, val) SKM_sk_set(ASN1_OBJECT, (st), (i), (val))
+#define sk_ASN1_OBJECT_zero(st) SKM_sk_zero(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_push(st, val) SKM_sk_push(ASN1_OBJECT, (st), (val))
+#define sk_ASN1_OBJECT_unshift(st, val) SKM_sk_unshift(ASN1_OBJECT, (st), (val))
+#define sk_ASN1_OBJECT_find(st, val) SKM_sk_find(ASN1_OBJECT, (st), (val))
+#define sk_ASN1_OBJECT_find_ex(st, val) SKM_sk_find_ex(ASN1_OBJECT, (st), (val))
+#define sk_ASN1_OBJECT_delete(st, i) SKM_sk_delete(ASN1_OBJECT, (st), (i))
+#define sk_ASN1_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_OBJECT, (st), (ptr))
+#define sk_ASN1_OBJECT_insert(st, val, i) SKM_sk_insert(ASN1_OBJECT, (st), (val), (i))
+#define sk_ASN1_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_OBJECT, (st), (cmp))
+#define sk_ASN1_OBJECT_dup(st) SKM_sk_dup(ASN1_OBJECT, st)
+#define sk_ASN1_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(ASN1_OBJECT, (st), (free_func))
+#define sk_ASN1_OBJECT_shift(st) SKM_sk_shift(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_pop(st) SKM_sk_pop(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st))
+
+#define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp))
+#define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE)
+#define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_value(st, i) SKM_sk_value(ASN1_STRING_TABLE, (st), (i))
+#define sk_ASN1_STRING_TABLE_set(st, i, val) SKM_sk_set(ASN1_STRING_TABLE, (st), (i), (val))
+#define sk_ASN1_STRING_TABLE_zero(st) SKM_sk_zero(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_push(st, val) SKM_sk_push(ASN1_STRING_TABLE, (st), (val))
+#define sk_ASN1_STRING_TABLE_unshift(st, val) SKM_sk_unshift(ASN1_STRING_TABLE, (st), (val))
+#define sk_ASN1_STRING_TABLE_find(st, val) SKM_sk_find(ASN1_STRING_TABLE, (st), (val))
+#define sk_ASN1_STRING_TABLE_find_ex(st, val) SKM_sk_find_ex(ASN1_STRING_TABLE, (st), (val))
+#define sk_ASN1_STRING_TABLE_delete(st, i) SKM_sk_delete(ASN1_STRING_TABLE, (st), (i))
+#define sk_ASN1_STRING_TABLE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_STRING_TABLE, (st), (ptr))
+#define sk_ASN1_STRING_TABLE_insert(st, val, i) SKM_sk_insert(ASN1_STRING_TABLE, (st), (val), (i))
+#define sk_ASN1_STRING_TABLE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_STRING_TABLE, (st), (cmp))
+#define sk_ASN1_STRING_TABLE_dup(st) SKM_sk_dup(ASN1_STRING_TABLE, st)
+#define sk_ASN1_STRING_TABLE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_STRING_TABLE, (st), (free_func))
+#define sk_ASN1_STRING_TABLE_shift(st) SKM_sk_shift(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_pop(st) SKM_sk_pop(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st))
+
+#define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp))
+#define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE)
+#define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_value(st, i) SKM_sk_value(ASN1_TYPE, (st), (i))
+#define sk_ASN1_TYPE_set(st, i, val) SKM_sk_set(ASN1_TYPE, (st), (i), (val))
+#define sk_ASN1_TYPE_zero(st) SKM_sk_zero(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_push(st, val) SKM_sk_push(ASN1_TYPE, (st), (val))
+#define sk_ASN1_TYPE_unshift(st, val) SKM_sk_unshift(ASN1_TYPE, (st), (val))
+#define sk_ASN1_TYPE_find(st, val) SKM_sk_find(ASN1_TYPE, (st), (val))
+#define sk_ASN1_TYPE_find_ex(st, val) SKM_sk_find_ex(ASN1_TYPE, (st), (val))
+#define sk_ASN1_TYPE_delete(st, i) SKM_sk_delete(ASN1_TYPE, (st), (i))
+#define sk_ASN1_TYPE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_TYPE, (st), (ptr))
+#define sk_ASN1_TYPE_insert(st, val, i) SKM_sk_insert(ASN1_TYPE, (st), (val), (i))
+#define sk_ASN1_TYPE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_TYPE, (st), (cmp))
+#define sk_ASN1_TYPE_dup(st) SKM_sk_dup(ASN1_TYPE, st)
+#define sk_ASN1_TYPE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_TYPE, (st), (free_func))
+#define sk_ASN1_TYPE_shift(st) SKM_sk_shift(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_pop(st) SKM_sk_pop(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st))
+
+#define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp))
+#define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING)
+#define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i))
+#define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val))
+#define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val))
+#define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val))
+#define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val))
+#define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val))
+#define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i))
+#define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr))
+#define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i))
+#define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp))
+#define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st)
+#define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func))
+#define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st))
+
+#define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp))
+#define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE)
+#define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_value(st, i) SKM_sk_value(ASN1_VALUE, (st), (i))
+#define sk_ASN1_VALUE_set(st, i, val) SKM_sk_set(ASN1_VALUE, (st), (i), (val))
+#define sk_ASN1_VALUE_zero(st) SKM_sk_zero(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_push(st, val) SKM_sk_push(ASN1_VALUE, (st), (val))
+#define sk_ASN1_VALUE_unshift(st, val) SKM_sk_unshift(ASN1_VALUE, (st), (val))
+#define sk_ASN1_VALUE_find(st, val) SKM_sk_find(ASN1_VALUE, (st), (val))
+#define sk_ASN1_VALUE_find_ex(st, val) SKM_sk_find_ex(ASN1_VALUE, (st), (val))
+#define sk_ASN1_VALUE_delete(st, i) SKM_sk_delete(ASN1_VALUE, (st), (i))
+#define sk_ASN1_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_VALUE, (st), (ptr))
+#define sk_ASN1_VALUE_insert(st, val, i) SKM_sk_insert(ASN1_VALUE, (st), (val), (i))
+#define sk_ASN1_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_VALUE, (st), (cmp))
+#define sk_ASN1_VALUE_dup(st) SKM_sk_dup(ASN1_VALUE, st)
+#define sk_ASN1_VALUE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_VALUE, (st), (free_func))
+#define sk_ASN1_VALUE_shift(st) SKM_sk_shift(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_pop(st) SKM_sk_pop(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st))
+
+#define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp))
+#define sk_BIO_new_null() SKM_sk_new_null(BIO)
+#define sk_BIO_free(st) SKM_sk_free(BIO, (st))
+#define sk_BIO_num(st) SKM_sk_num(BIO, (st))
+#define sk_BIO_value(st, i) SKM_sk_value(BIO, (st), (i))
+#define sk_BIO_set(st, i, val) SKM_sk_set(BIO, (st), (i), (val))
+#define sk_BIO_zero(st) SKM_sk_zero(BIO, (st))
+#define sk_BIO_push(st, val) SKM_sk_push(BIO, (st), (val))
+#define sk_BIO_unshift(st, val) SKM_sk_unshift(BIO, (st), (val))
+#define sk_BIO_find(st, val) SKM_sk_find(BIO, (st), (val))
+#define sk_BIO_find_ex(st, val) SKM_sk_find_ex(BIO, (st), (val))
+#define sk_BIO_delete(st, i) SKM_sk_delete(BIO, (st), (i))
+#define sk_BIO_delete_ptr(st, ptr) SKM_sk_delete_ptr(BIO, (st), (ptr))
+#define sk_BIO_insert(st, val, i) SKM_sk_insert(BIO, (st), (val), (i))
+#define sk_BIO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BIO, (st), (cmp))
+#define sk_BIO_dup(st) SKM_sk_dup(BIO, st)
+#define sk_BIO_pop_free(st, free_func) SKM_sk_pop_free(BIO, (st), (free_func))
+#define sk_BIO_shift(st) SKM_sk_shift(BIO, (st))
+#define sk_BIO_pop(st) SKM_sk_pop(BIO, (st))
+#define sk_BIO_sort(st) SKM_sk_sort(BIO, (st))
+#define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st))
+
+#define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp))
+#define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY)
+#define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i))
+#define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val))
+#define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val))
+#define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val))
+#define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val))
+#define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val))
+#define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i))
+#define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr))
+#define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i))
+#define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp))
+#define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st)
+#define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func))
+#define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st))
+
+#define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp))
+#define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH)
+#define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i))
+#define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val))
+#define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val))
+#define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val))
+#define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val))
+#define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val))
+#define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i))
+#define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr))
+#define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i))
+#define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp))
+#define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st)
+#define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func))
+#define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st))
+
+#define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp))
+#define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices)
+#define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st))
+#define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st))
+#define sk_CMS_CertificateChoices_value(st, i) SKM_sk_value(CMS_CertificateChoices, (st), (i))
+#define sk_CMS_CertificateChoices_set(st, i, val) SKM_sk_set(CMS_CertificateChoices, (st), (i), (val))
+#define sk_CMS_CertificateChoices_zero(st) SKM_sk_zero(CMS_CertificateChoices, (st))
+#define sk_CMS_CertificateChoices_push(st, val) SKM_sk_push(CMS_CertificateChoices, (st), (val))
+#define sk_CMS_CertificateChoices_unshift(st, val) SKM_sk_unshift(CMS_CertificateChoices, (st), (val))
+#define sk_CMS_CertificateChoices_find(st, val) SKM_sk_find(CMS_CertificateChoices, (st), (val))
+#define sk_CMS_CertificateChoices_find_ex(st, val) SKM_sk_find_ex(CMS_CertificateChoices, (st), (val))
+#define sk_CMS_CertificateChoices_delete(st, i) SKM_sk_delete(CMS_CertificateChoices, (st), (i))
+#define sk_CMS_CertificateChoices_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_CertificateChoices, (st), (ptr))
+#define sk_CMS_CertificateChoices_insert(st, val, i) SKM_sk_insert(CMS_CertificateChoices, (st), (val), (i))
+#define sk_CMS_CertificateChoices_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_CertificateChoices, (st), (cmp))
+#define sk_CMS_CertificateChoices_dup(st) SKM_sk_dup(CMS_CertificateChoices, st)
+#define sk_CMS_CertificateChoices_pop_free(st, free_func) SKM_sk_pop_free(CMS_CertificateChoices, (st), (free_func))
+#define sk_CMS_CertificateChoices_shift(st) SKM_sk_shift(CMS_CertificateChoices, (st))
+#define sk_CMS_CertificateChoices_pop(st) SKM_sk_pop(CMS_CertificateChoices, (st))
+#define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st))
+#define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st))
+
+#define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp))
+#define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo)
+#define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st))
+#define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st))
+#define sk_CMS_RecipientInfo_value(st, i) SKM_sk_value(CMS_RecipientInfo, (st), (i))
+#define sk_CMS_RecipientInfo_set(st, i, val) SKM_sk_set(CMS_RecipientInfo, (st), (i), (val))
+#define sk_CMS_RecipientInfo_zero(st) SKM_sk_zero(CMS_RecipientInfo, (st))
+#define sk_CMS_RecipientInfo_push(st, val) SKM_sk_push(CMS_RecipientInfo, (st), (val))
+#define sk_CMS_RecipientInfo_unshift(st, val) SKM_sk_unshift(CMS_RecipientInfo, (st), (val))
+#define sk_CMS_RecipientInfo_find(st, val) SKM_sk_find(CMS_RecipientInfo, (st), (val))
+#define sk_CMS_RecipientInfo_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientInfo, (st), (val))
+#define sk_CMS_RecipientInfo_delete(st, i) SKM_sk_delete(CMS_RecipientInfo, (st), (i))
+#define sk_CMS_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientInfo, (st), (ptr))
+#define sk_CMS_RecipientInfo_insert(st, val, i) SKM_sk_insert(CMS_RecipientInfo, (st), (val), (i))
+#define sk_CMS_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientInfo, (st), (cmp))
+#define sk_CMS_RecipientInfo_dup(st) SKM_sk_dup(CMS_RecipientInfo, st)
+#define sk_CMS_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientInfo, (st), (free_func))
+#define sk_CMS_RecipientInfo_shift(st) SKM_sk_shift(CMS_RecipientInfo, (st))
+#define sk_CMS_RecipientInfo_pop(st) SKM_sk_pop(CMS_RecipientInfo, (st))
+#define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st))
+#define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st))
+
+#define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp))
+#define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice)
+#define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st))
+#define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st))
+#define sk_CMS_RevocationInfoChoice_value(st, i) SKM_sk_value(CMS_RevocationInfoChoice, (st), (i))
+#define sk_CMS_RevocationInfoChoice_set(st, i, val) SKM_sk_set(CMS_RevocationInfoChoice, (st), (i), (val))
+#define sk_CMS_RevocationInfoChoice_zero(st) SKM_sk_zero(CMS_RevocationInfoChoice, (st))
+#define sk_CMS_RevocationInfoChoice_push(st, val) SKM_sk_push(CMS_RevocationInfoChoice, (st), (val))
+#define sk_CMS_RevocationInfoChoice_unshift(st, val) SKM_sk_unshift(CMS_RevocationInfoChoice, (st), (val))
+#define sk_CMS_RevocationInfoChoice_find(st, val) SKM_sk_find(CMS_RevocationInfoChoice, (st), (val))
+#define sk_CMS_RevocationInfoChoice_find_ex(st, val) SKM_sk_find_ex(CMS_RevocationInfoChoice, (st), (val))
+#define sk_CMS_RevocationInfoChoice_delete(st, i) SKM_sk_delete(CMS_RevocationInfoChoice, (st), (i))
+#define sk_CMS_RevocationInfoChoice_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RevocationInfoChoice, (st), (ptr))
+#define sk_CMS_RevocationInfoChoice_insert(st, val, i) SKM_sk_insert(CMS_RevocationInfoChoice, (st), (val), (i))
+#define sk_CMS_RevocationInfoChoice_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RevocationInfoChoice, (st), (cmp))
+#define sk_CMS_RevocationInfoChoice_dup(st) SKM_sk_dup(CMS_RevocationInfoChoice, st)
+#define sk_CMS_RevocationInfoChoice_pop_free(st, free_func) SKM_sk_pop_free(CMS_RevocationInfoChoice, (st), (free_func))
+#define sk_CMS_RevocationInfoChoice_shift(st) SKM_sk_shift(CMS_RevocationInfoChoice, (st))
+#define sk_CMS_RevocationInfoChoice_pop(st) SKM_sk_pop(CMS_RevocationInfoChoice, (st))
+#define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st))
+#define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st))
+
+#define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp))
+#define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo)
+#define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st))
+#define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st))
+#define sk_CMS_SignerInfo_value(st, i) SKM_sk_value(CMS_SignerInfo, (st), (i))
+#define sk_CMS_SignerInfo_set(st, i, val) SKM_sk_set(CMS_SignerInfo, (st), (i), (val))
+#define sk_CMS_SignerInfo_zero(st) SKM_sk_zero(CMS_SignerInfo, (st))
+#define sk_CMS_SignerInfo_push(st, val) SKM_sk_push(CMS_SignerInfo, (st), (val))
+#define sk_CMS_SignerInfo_unshift(st, val) SKM_sk_unshift(CMS_SignerInfo, (st), (val))
+#define sk_CMS_SignerInfo_find(st, val) SKM_sk_find(CMS_SignerInfo, (st), (val))
+#define sk_CMS_SignerInfo_find_ex(st, val) SKM_sk_find_ex(CMS_SignerInfo, (st), (val))
+#define sk_CMS_SignerInfo_delete(st, i) SKM_sk_delete(CMS_SignerInfo, (st), (i))
+#define sk_CMS_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_SignerInfo, (st), (ptr))
+#define sk_CMS_SignerInfo_insert(st, val, i) SKM_sk_insert(CMS_SignerInfo, (st), (val), (i))
+#define sk_CMS_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_SignerInfo, (st), (cmp))
+#define sk_CMS_SignerInfo_dup(st) SKM_sk_dup(CMS_SignerInfo, st)
+#define sk_CMS_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_SignerInfo, (st), (free_func))
+#define sk_CMS_SignerInfo_shift(st) SKM_sk_shift(CMS_SignerInfo, (st))
+#define sk_CMS_SignerInfo_pop(st) SKM_sk_pop(CMS_SignerInfo, (st))
+#define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st))
+#define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st))
+
+#define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp))
+#define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE)
+#define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_value(st, i) SKM_sk_value(CONF_IMODULE, (st), (i))
+#define sk_CONF_IMODULE_set(st, i, val) SKM_sk_set(CONF_IMODULE, (st), (i), (val))
+#define sk_CONF_IMODULE_zero(st) SKM_sk_zero(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_push(st, val) SKM_sk_push(CONF_IMODULE, (st), (val))
+#define sk_CONF_IMODULE_unshift(st, val) SKM_sk_unshift(CONF_IMODULE, (st), (val))
+#define sk_CONF_IMODULE_find(st, val) SKM_sk_find(CONF_IMODULE, (st), (val))
+#define sk_CONF_IMODULE_find_ex(st, val) SKM_sk_find_ex(CONF_IMODULE, (st), (val))
+#define sk_CONF_IMODULE_delete(st, i) SKM_sk_delete(CONF_IMODULE, (st), (i))
+#define sk_CONF_IMODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_IMODULE, (st), (ptr))
+#define sk_CONF_IMODULE_insert(st, val, i) SKM_sk_insert(CONF_IMODULE, (st), (val), (i))
+#define sk_CONF_IMODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_IMODULE, (st), (cmp))
+#define sk_CONF_IMODULE_dup(st) SKM_sk_dup(CONF_IMODULE, st)
+#define sk_CONF_IMODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_IMODULE, (st), (free_func))
+#define sk_CONF_IMODULE_shift(st) SKM_sk_shift(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_pop(st) SKM_sk_pop(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st))
+
+#define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp))
+#define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE)
+#define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st))
+#define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st))
+#define sk_CONF_MODULE_value(st, i) SKM_sk_value(CONF_MODULE, (st), (i))
+#define sk_CONF_MODULE_set(st, i, val) SKM_sk_set(CONF_MODULE, (st), (i), (val))
+#define sk_CONF_MODULE_zero(st) SKM_sk_zero(CONF_MODULE, (st))
+#define sk_CONF_MODULE_push(st, val) SKM_sk_push(CONF_MODULE, (st), (val))
+#define sk_CONF_MODULE_unshift(st, val) SKM_sk_unshift(CONF_MODULE, (st), (val))
+#define sk_CONF_MODULE_find(st, val) SKM_sk_find(CONF_MODULE, (st), (val))
+#define sk_CONF_MODULE_find_ex(st, val) SKM_sk_find_ex(CONF_MODULE, (st), (val))
+#define sk_CONF_MODULE_delete(st, i) SKM_sk_delete(CONF_MODULE, (st), (i))
+#define sk_CONF_MODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_MODULE, (st), (ptr))
+#define sk_CONF_MODULE_insert(st, val, i) SKM_sk_insert(CONF_MODULE, (st), (val), (i))
+#define sk_CONF_MODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_MODULE, (st), (cmp))
+#define sk_CONF_MODULE_dup(st) SKM_sk_dup(CONF_MODULE, st)
+#define sk_CONF_MODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_MODULE, (st), (free_func))
+#define sk_CONF_MODULE_shift(st) SKM_sk_shift(CONF_MODULE, (st))
+#define sk_CONF_MODULE_pop(st) SKM_sk_pop(CONF_MODULE, (st))
+#define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st))
+#define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st))
+
+#define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp))
+#define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE)
+#define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st))
+#define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st))
+#define sk_CONF_VALUE_value(st, i) SKM_sk_value(CONF_VALUE, (st), (i))
+#define sk_CONF_VALUE_set(st, i, val) SKM_sk_set(CONF_VALUE, (st), (i), (val))
+#define sk_CONF_VALUE_zero(st) SKM_sk_zero(CONF_VALUE, (st))
+#define sk_CONF_VALUE_push(st, val) SKM_sk_push(CONF_VALUE, (st), (val))
+#define sk_CONF_VALUE_unshift(st, val) SKM_sk_unshift(CONF_VALUE, (st), (val))
+#define sk_CONF_VALUE_find(st, val) SKM_sk_find(CONF_VALUE, (st), (val))
+#define sk_CONF_VALUE_find_ex(st, val) SKM_sk_find_ex(CONF_VALUE, (st), (val))
+#define sk_CONF_VALUE_delete(st, i) SKM_sk_delete(CONF_VALUE, (st), (i))
+#define sk_CONF_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_VALUE, (st), (ptr))
+#define sk_CONF_VALUE_insert(st, val, i) SKM_sk_insert(CONF_VALUE, (st), (val), (i))
+#define sk_CONF_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_VALUE, (st), (cmp))
+#define sk_CONF_VALUE_dup(st) SKM_sk_dup(CONF_VALUE, st)
+#define sk_CONF_VALUE_pop_free(st, free_func) SKM_sk_pop_free(CONF_VALUE, (st), (free_func))
+#define sk_CONF_VALUE_shift(st) SKM_sk_shift(CONF_VALUE, (st))
+#define sk_CONF_VALUE_pop(st) SKM_sk_pop(CONF_VALUE, (st))
+#define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st))
+#define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st))
+
+#define sk_CRYPTO_EX_DATA_FUNCS_new(cmp) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (cmp))
+#define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS)
+#define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_value(st, i) SKM_sk_value(CRYPTO_EX_DATA_FUNCS, (st), (i))
+#define sk_CRYPTO_EX_DATA_FUNCS_set(st, i, val) SKM_sk_set(CRYPTO_EX_DATA_FUNCS, (st), (i), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_zero(st) SKM_sk_zero(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_push(st, val) SKM_sk_push(CRYPTO_EX_DATA_FUNCS, (st), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_unshift(st, val) SKM_sk_unshift(CRYPTO_EX_DATA_FUNCS, (st), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_find(st, val) SKM_sk_find(CRYPTO_EX_DATA_FUNCS, (st), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_find_ex(st, val) SKM_sk_find_ex(CRYPTO_EX_DATA_FUNCS, (st), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_delete(st, i) SKM_sk_delete(CRYPTO_EX_DATA_FUNCS, (st), (i))
+#define sk_CRYPTO_EX_DATA_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_EX_DATA_FUNCS, (st), (ptr))
+#define sk_CRYPTO_EX_DATA_FUNCS_insert(st, val, i) SKM_sk_insert(CRYPTO_EX_DATA_FUNCS, (st), (val), (i))
+#define sk_CRYPTO_EX_DATA_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_EX_DATA_FUNCS, (st), (cmp))
+#define sk_CRYPTO_EX_DATA_FUNCS_dup(st) SKM_sk_dup(CRYPTO_EX_DATA_FUNCS, st)
+#define sk_CRYPTO_EX_DATA_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_EX_DATA_FUNCS, (st), (free_func))
+#define sk_CRYPTO_EX_DATA_FUNCS_shift(st) SKM_sk_shift(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_pop(st) SKM_sk_pop(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st))
+
+#define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp))
+#define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock)
+#define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_value(st, i) SKM_sk_value(CRYPTO_dynlock, (st), (i))
+#define sk_CRYPTO_dynlock_set(st, i, val) SKM_sk_set(CRYPTO_dynlock, (st), (i), (val))
+#define sk_CRYPTO_dynlock_zero(st) SKM_sk_zero(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_push(st, val) SKM_sk_push(CRYPTO_dynlock, (st), (val))
+#define sk_CRYPTO_dynlock_unshift(st, val) SKM_sk_unshift(CRYPTO_dynlock, (st), (val))
+#define sk_CRYPTO_dynlock_find(st, val) SKM_sk_find(CRYPTO_dynlock, (st), (val))
+#define sk_CRYPTO_dynlock_find_ex(st, val) SKM_sk_find_ex(CRYPTO_dynlock, (st), (val))
+#define sk_CRYPTO_dynlock_delete(st, i) SKM_sk_delete(CRYPTO_dynlock, (st), (i))
+#define sk_CRYPTO_dynlock_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_dynlock, (st), (ptr))
+#define sk_CRYPTO_dynlock_insert(st, val, i) SKM_sk_insert(CRYPTO_dynlock, (st), (val), (i))
+#define sk_CRYPTO_dynlock_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_dynlock, (st), (cmp))
+#define sk_CRYPTO_dynlock_dup(st) SKM_sk_dup(CRYPTO_dynlock, st)
+#define sk_CRYPTO_dynlock_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_dynlock, (st), (free_func))
+#define sk_CRYPTO_dynlock_shift(st) SKM_sk_shift(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_pop(st) SKM_sk_pop(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st))
+
+#define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp))
+#define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT)
+#define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st))
+#define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st))
+#define sk_DIST_POINT_value(st, i) SKM_sk_value(DIST_POINT, (st), (i))
+#define sk_DIST_POINT_set(st, i, val) SKM_sk_set(DIST_POINT, (st), (i), (val))
+#define sk_DIST_POINT_zero(st) SKM_sk_zero(DIST_POINT, (st))
+#define sk_DIST_POINT_push(st, val) SKM_sk_push(DIST_POINT, (st), (val))
+#define sk_DIST_POINT_unshift(st, val) SKM_sk_unshift(DIST_POINT, (st), (val))
+#define sk_DIST_POINT_find(st, val) SKM_sk_find(DIST_POINT, (st), (val))
+#define sk_DIST_POINT_find_ex(st, val) SKM_sk_find_ex(DIST_POINT, (st), (val))
+#define sk_DIST_POINT_delete(st, i) SKM_sk_delete(DIST_POINT, (st), (i))
+#define sk_DIST_POINT_delete_ptr(st, ptr) SKM_sk_delete_ptr(DIST_POINT, (st), (ptr))
+#define sk_DIST_POINT_insert(st, val, i) SKM_sk_insert(DIST_POINT, (st), (val), (i))
+#define sk_DIST_POINT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(DIST_POINT, (st), (cmp))
+#define sk_DIST_POINT_dup(st) SKM_sk_dup(DIST_POINT, st)
+#define sk_DIST_POINT_pop_free(st, free_func) SKM_sk_pop_free(DIST_POINT, (st), (free_func))
+#define sk_DIST_POINT_shift(st) SKM_sk_shift(DIST_POINT, (st))
+#define sk_DIST_POINT_pop(st) SKM_sk_pop(DIST_POINT, (st))
+#define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st))
+#define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st))
+
+#define sk_ENGINE_new(cmp) SKM_sk_new(ENGINE, (cmp))
+#define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE)
+#define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st))
+#define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st))
+#define sk_ENGINE_value(st, i) SKM_sk_value(ENGINE, (st), (i))
+#define sk_ENGINE_set(st, i, val) SKM_sk_set(ENGINE, (st), (i), (val))
+#define sk_ENGINE_zero(st) SKM_sk_zero(ENGINE, (st))
+#define sk_ENGINE_push(st, val) SKM_sk_push(ENGINE, (st), (val))
+#define sk_ENGINE_unshift(st, val) SKM_sk_unshift(ENGINE, (st), (val))
+#define sk_ENGINE_find(st, val) SKM_sk_find(ENGINE, (st), (val))
+#define sk_ENGINE_find_ex(st, val) SKM_sk_find_ex(ENGINE, (st), (val))
+#define sk_ENGINE_delete(st, i) SKM_sk_delete(ENGINE, (st), (i))
+#define sk_ENGINE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE, (st), (ptr))
+#define sk_ENGINE_insert(st, val, i) SKM_sk_insert(ENGINE, (st), (val), (i))
+#define sk_ENGINE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE, (st), (cmp))
+#define sk_ENGINE_dup(st) SKM_sk_dup(ENGINE, st)
+#define sk_ENGINE_pop_free(st, free_func) SKM_sk_pop_free(ENGINE, (st), (free_func))
+#define sk_ENGINE_shift(st) SKM_sk_shift(ENGINE, (st))
+#define sk_ENGINE_pop(st) SKM_sk_pop(ENGINE, (st))
+#define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st))
+#define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st))
+
+#define sk_ENGINE_CLEANUP_ITEM_new(cmp) SKM_sk_new(ENGINE_CLEANUP_ITEM, (cmp))
+#define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM)
+#define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_value(st, i) SKM_sk_value(ENGINE_CLEANUP_ITEM, (st), (i))
+#define sk_ENGINE_CLEANUP_ITEM_set(st, i, val) SKM_sk_set(ENGINE_CLEANUP_ITEM, (st), (i), (val))
+#define sk_ENGINE_CLEANUP_ITEM_zero(st) SKM_sk_zero(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_push(st, val) SKM_sk_push(ENGINE_CLEANUP_ITEM, (st), (val))
+#define sk_ENGINE_CLEANUP_ITEM_unshift(st, val) SKM_sk_unshift(ENGINE_CLEANUP_ITEM, (st), (val))
+#define sk_ENGINE_CLEANUP_ITEM_find(st, val) SKM_sk_find(ENGINE_CLEANUP_ITEM, (st), (val))
+#define sk_ENGINE_CLEANUP_ITEM_find_ex(st, val) SKM_sk_find_ex(ENGINE_CLEANUP_ITEM, (st), (val))
+#define sk_ENGINE_CLEANUP_ITEM_delete(st, i) SKM_sk_delete(ENGINE_CLEANUP_ITEM, (st), (i))
+#define sk_ENGINE_CLEANUP_ITEM_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE_CLEANUP_ITEM, (st), (ptr))
+#define sk_ENGINE_CLEANUP_ITEM_insert(st, val, i) SKM_sk_insert(ENGINE_CLEANUP_ITEM, (st), (val), (i))
+#define sk_ENGINE_CLEANUP_ITEM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE_CLEANUP_ITEM, (st), (cmp))
+#define sk_ENGINE_CLEANUP_ITEM_dup(st) SKM_sk_dup(ENGINE_CLEANUP_ITEM, st)
+#define sk_ENGINE_CLEANUP_ITEM_pop_free(st, free_func) SKM_sk_pop_free(ENGINE_CLEANUP_ITEM, (st), (free_func))
+#define sk_ENGINE_CLEANUP_ITEM_shift(st) SKM_sk_shift(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_pop(st) SKM_sk_pop(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st))
+
+#define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp))
+#define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID)
+#define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i))
+#define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val))
+#define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val))
+#define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val))
+#define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val))
+#define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val))
+#define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i))
+#define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr))
+#define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i))
+#define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp))
+#define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st)
+#define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func))
+#define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st))
+
+#define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp))
+#define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD)
+#define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st))
+#define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st))
+#define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i))
+#define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val))
+#define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st))
+#define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val))
+#define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val))
+#define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val))
+#define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val))
+#define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i))
+#define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr))
+#define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i))
+#define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp))
+#define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st)
+#define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func))
+#define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st))
+#define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st))
+#define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st))
+#define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st))
+
+#define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp))
+#define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL)
+#define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i))
+#define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val))
+#define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val))
+#define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val))
+#define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val))
+#define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val))
+#define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i))
+#define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr))
+#define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i))
+#define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp))
+#define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st)
+#define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func))
+#define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st))
+
+#define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp))
+#define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD)
+#define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i))
+#define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i))
+#define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr))
+#define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i))
+#define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp))
+#define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st)
+#define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func))
+#define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st))
+
+#define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp))
+#define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD)
+#define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i))
+#define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val))
+#define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val))
+#define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val))
+#define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val))
+#define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val))
+#define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i))
+#define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr))
+#define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i))
+#define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp))
+#define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st)
+#define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func))
+#define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st))
+
+#define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp))
+#define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME)
+#define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_value(st, i) SKM_sk_value(GENERAL_NAME, (st), (i))
+#define sk_GENERAL_NAME_set(st, i, val) SKM_sk_set(GENERAL_NAME, (st), (i), (val))
+#define sk_GENERAL_NAME_zero(st) SKM_sk_zero(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_push(st, val) SKM_sk_push(GENERAL_NAME, (st), (val))
+#define sk_GENERAL_NAME_unshift(st, val) SKM_sk_unshift(GENERAL_NAME, (st), (val))
+#define sk_GENERAL_NAME_find(st, val) SKM_sk_find(GENERAL_NAME, (st), (val))
+#define sk_GENERAL_NAME_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAME, (st), (val))
+#define sk_GENERAL_NAME_delete(st, i) SKM_sk_delete(GENERAL_NAME, (st), (i))
+#define sk_GENERAL_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAME, (st), (ptr))
+#define sk_GENERAL_NAME_insert(st, val, i) SKM_sk_insert(GENERAL_NAME, (st), (val), (i))
+#define sk_GENERAL_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAME, (st), (cmp))
+#define sk_GENERAL_NAME_dup(st) SKM_sk_dup(GENERAL_NAME, st)
+#define sk_GENERAL_NAME_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAME, (st), (free_func))
+#define sk_GENERAL_NAME_shift(st) SKM_sk_shift(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_pop(st) SKM_sk_pop(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st))
+
+#define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp))
+#define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES)
+#define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st))
+#define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st))
+#define sk_GENERAL_NAMES_value(st, i) SKM_sk_value(GENERAL_NAMES, (st), (i))
+#define sk_GENERAL_NAMES_set(st, i, val) SKM_sk_set(GENERAL_NAMES, (st), (i), (val))
+#define sk_GENERAL_NAMES_zero(st) SKM_sk_zero(GENERAL_NAMES, (st))
+#define sk_GENERAL_NAMES_push(st, val) SKM_sk_push(GENERAL_NAMES, (st), (val))
+#define sk_GENERAL_NAMES_unshift(st, val) SKM_sk_unshift(GENERAL_NAMES, (st), (val))
+#define sk_GENERAL_NAMES_find(st, val) SKM_sk_find(GENERAL_NAMES, (st), (val))
+#define sk_GENERAL_NAMES_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAMES, (st), (val))
+#define sk_GENERAL_NAMES_delete(st, i) SKM_sk_delete(GENERAL_NAMES, (st), (i))
+#define sk_GENERAL_NAMES_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAMES, (st), (ptr))
+#define sk_GENERAL_NAMES_insert(st, val, i) SKM_sk_insert(GENERAL_NAMES, (st), (val), (i))
+#define sk_GENERAL_NAMES_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAMES, (st), (cmp))
+#define sk_GENERAL_NAMES_dup(st) SKM_sk_dup(GENERAL_NAMES, st)
+#define sk_GENERAL_NAMES_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAMES, (st), (free_func))
+#define sk_GENERAL_NAMES_shift(st) SKM_sk_shift(GENERAL_NAMES, (st))
+#define sk_GENERAL_NAMES_pop(st) SKM_sk_pop(GENERAL_NAMES, (st))
+#define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st))
+#define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st))
+
+#define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp))
+#define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE)
+#define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_value(st, i) SKM_sk_value(GENERAL_SUBTREE, (st), (i))
+#define sk_GENERAL_SUBTREE_set(st, i, val) SKM_sk_set(GENERAL_SUBTREE, (st), (i), (val))
+#define sk_GENERAL_SUBTREE_zero(st) SKM_sk_zero(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_push(st, val) SKM_sk_push(GENERAL_SUBTREE, (st), (val))
+#define sk_GENERAL_SUBTREE_unshift(st, val) SKM_sk_unshift(GENERAL_SUBTREE, (st), (val))
+#define sk_GENERAL_SUBTREE_find(st, val) SKM_sk_find(GENERAL_SUBTREE, (st), (val))
+#define sk_GENERAL_SUBTREE_find_ex(st, val) SKM_sk_find_ex(GENERAL_SUBTREE, (st), (val))
+#define sk_GENERAL_SUBTREE_delete(st, i) SKM_sk_delete(GENERAL_SUBTREE, (st), (i))
+#define sk_GENERAL_SUBTREE_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_SUBTREE, (st), (ptr))
+#define sk_GENERAL_SUBTREE_insert(st, val, i) SKM_sk_insert(GENERAL_SUBTREE, (st), (val), (i))
+#define sk_GENERAL_SUBTREE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_SUBTREE, (st), (cmp))
+#define sk_GENERAL_SUBTREE_dup(st) SKM_sk_dup(GENERAL_SUBTREE, st)
+#define sk_GENERAL_SUBTREE_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_SUBTREE, (st), (free_func))
+#define sk_GENERAL_SUBTREE_shift(st) SKM_sk_shift(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_pop(st) SKM_sk_pop(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st))
+
+#define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp))
+#define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily)
+#define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st))
+#define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st))
+#define sk_IPAddressFamily_value(st, i) SKM_sk_value(IPAddressFamily, (st), (i))
+#define sk_IPAddressFamily_set(st, i, val) SKM_sk_set(IPAddressFamily, (st), (i), (val))
+#define sk_IPAddressFamily_zero(st) SKM_sk_zero(IPAddressFamily, (st))
+#define sk_IPAddressFamily_push(st, val) SKM_sk_push(IPAddressFamily, (st), (val))
+#define sk_IPAddressFamily_unshift(st, val) SKM_sk_unshift(IPAddressFamily, (st), (val))
+#define sk_IPAddressFamily_find(st, val) SKM_sk_find(IPAddressFamily, (st), (val))
+#define sk_IPAddressFamily_find_ex(st, val) SKM_sk_find_ex(IPAddressFamily, (st), (val))
+#define sk_IPAddressFamily_delete(st, i) SKM_sk_delete(IPAddressFamily, (st), (i))
+#define sk_IPAddressFamily_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressFamily, (st), (ptr))
+#define sk_IPAddressFamily_insert(st, val, i) SKM_sk_insert(IPAddressFamily, (st), (val), (i))
+#define sk_IPAddressFamily_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressFamily, (st), (cmp))
+#define sk_IPAddressFamily_dup(st) SKM_sk_dup(IPAddressFamily, st)
+#define sk_IPAddressFamily_pop_free(st, free_func) SKM_sk_pop_free(IPAddressFamily, (st), (free_func))
+#define sk_IPAddressFamily_shift(st) SKM_sk_shift(IPAddressFamily, (st))
+#define sk_IPAddressFamily_pop(st) SKM_sk_pop(IPAddressFamily, (st))
+#define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st))
+#define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st))
+
+#define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp))
+#define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange)
+#define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_value(st, i) SKM_sk_value(IPAddressOrRange, (st), (i))
+#define sk_IPAddressOrRange_set(st, i, val) SKM_sk_set(IPAddressOrRange, (st), (i), (val))
+#define sk_IPAddressOrRange_zero(st) SKM_sk_zero(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_push(st, val) SKM_sk_push(IPAddressOrRange, (st), (val))
+#define sk_IPAddressOrRange_unshift(st, val) SKM_sk_unshift(IPAddressOrRange, (st), (val))
+#define sk_IPAddressOrRange_find(st, val) SKM_sk_find(IPAddressOrRange, (st), (val))
+#define sk_IPAddressOrRange_find_ex(st, val) SKM_sk_find_ex(IPAddressOrRange, (st), (val))
+#define sk_IPAddressOrRange_delete(st, i) SKM_sk_delete(IPAddressOrRange, (st), (i))
+#define sk_IPAddressOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressOrRange, (st), (ptr))
+#define sk_IPAddressOrRange_insert(st, val, i) SKM_sk_insert(IPAddressOrRange, (st), (val), (i))
+#define sk_IPAddressOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressOrRange, (st), (cmp))
+#define sk_IPAddressOrRange_dup(st) SKM_sk_dup(IPAddressOrRange, st)
+#define sk_IPAddressOrRange_pop_free(st, free_func) SKM_sk_pop_free(IPAddressOrRange, (st), (free_func))
+#define sk_IPAddressOrRange_shift(st) SKM_sk_shift(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_pop(st) SKM_sk_pop(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st))
+
+#define sk_KRB5_APREQBODY_new(cmp) SKM_sk_new(KRB5_APREQBODY, (cmp))
+#define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY)
+#define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_value(st, i) SKM_sk_value(KRB5_APREQBODY, (st), (i))
+#define sk_KRB5_APREQBODY_set(st, i, val) SKM_sk_set(KRB5_APREQBODY, (st), (i), (val))
+#define sk_KRB5_APREQBODY_zero(st) SKM_sk_zero(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_push(st, val) SKM_sk_push(KRB5_APREQBODY, (st), (val))
+#define sk_KRB5_APREQBODY_unshift(st, val) SKM_sk_unshift(KRB5_APREQBODY, (st), (val))
+#define sk_KRB5_APREQBODY_find(st, val) SKM_sk_find(KRB5_APREQBODY, (st), (val))
+#define sk_KRB5_APREQBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_APREQBODY, (st), (val))
+#define sk_KRB5_APREQBODY_delete(st, i) SKM_sk_delete(KRB5_APREQBODY, (st), (i))
+#define sk_KRB5_APREQBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_APREQBODY, (st), (ptr))
+#define sk_KRB5_APREQBODY_insert(st, val, i) SKM_sk_insert(KRB5_APREQBODY, (st), (val), (i))
+#define sk_KRB5_APREQBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_APREQBODY, (st), (cmp))
+#define sk_KRB5_APREQBODY_dup(st) SKM_sk_dup(KRB5_APREQBODY, st)
+#define sk_KRB5_APREQBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_APREQBODY, (st), (free_func))
+#define sk_KRB5_APREQBODY_shift(st) SKM_sk_shift(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_pop(st) SKM_sk_pop(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st))
+
+#define sk_KRB5_AUTHDATA_new(cmp) SKM_sk_new(KRB5_AUTHDATA, (cmp))
+#define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA)
+#define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_value(st, i) SKM_sk_value(KRB5_AUTHDATA, (st), (i))
+#define sk_KRB5_AUTHDATA_set(st, i, val) SKM_sk_set(KRB5_AUTHDATA, (st), (i), (val))
+#define sk_KRB5_AUTHDATA_zero(st) SKM_sk_zero(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_push(st, val) SKM_sk_push(KRB5_AUTHDATA, (st), (val))
+#define sk_KRB5_AUTHDATA_unshift(st, val) SKM_sk_unshift(KRB5_AUTHDATA, (st), (val))
+#define sk_KRB5_AUTHDATA_find(st, val) SKM_sk_find(KRB5_AUTHDATA, (st), (val))
+#define sk_KRB5_AUTHDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHDATA, (st), (val))
+#define sk_KRB5_AUTHDATA_delete(st, i) SKM_sk_delete(KRB5_AUTHDATA, (st), (i))
+#define sk_KRB5_AUTHDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHDATA, (st), (ptr))
+#define sk_KRB5_AUTHDATA_insert(st, val, i) SKM_sk_insert(KRB5_AUTHDATA, (st), (val), (i))
+#define sk_KRB5_AUTHDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHDATA, (st), (cmp))
+#define sk_KRB5_AUTHDATA_dup(st) SKM_sk_dup(KRB5_AUTHDATA, st)
+#define sk_KRB5_AUTHDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHDATA, (st), (free_func))
+#define sk_KRB5_AUTHDATA_shift(st) SKM_sk_shift(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_pop(st) SKM_sk_pop(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st))
+
+#define sk_KRB5_AUTHENTBODY_new(cmp) SKM_sk_new(KRB5_AUTHENTBODY, (cmp))
+#define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY)
+#define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_value(st, i) SKM_sk_value(KRB5_AUTHENTBODY, (st), (i))
+#define sk_KRB5_AUTHENTBODY_set(st, i, val) SKM_sk_set(KRB5_AUTHENTBODY, (st), (i), (val))
+#define sk_KRB5_AUTHENTBODY_zero(st) SKM_sk_zero(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_push(st, val) SKM_sk_push(KRB5_AUTHENTBODY, (st), (val))
+#define sk_KRB5_AUTHENTBODY_unshift(st, val) SKM_sk_unshift(KRB5_AUTHENTBODY, (st), (val))
+#define sk_KRB5_AUTHENTBODY_find(st, val) SKM_sk_find(KRB5_AUTHENTBODY, (st), (val))
+#define sk_KRB5_AUTHENTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHENTBODY, (st), (val))
+#define sk_KRB5_AUTHENTBODY_delete(st, i) SKM_sk_delete(KRB5_AUTHENTBODY, (st), (i))
+#define sk_KRB5_AUTHENTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHENTBODY, (st), (ptr))
+#define sk_KRB5_AUTHENTBODY_insert(st, val, i) SKM_sk_insert(KRB5_AUTHENTBODY, (st), (val), (i))
+#define sk_KRB5_AUTHENTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHENTBODY, (st), (cmp))
+#define sk_KRB5_AUTHENTBODY_dup(st) SKM_sk_dup(KRB5_AUTHENTBODY, st)
+#define sk_KRB5_AUTHENTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHENTBODY, (st), (free_func))
+#define sk_KRB5_AUTHENTBODY_shift(st) SKM_sk_shift(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_pop(st) SKM_sk_pop(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st))
+
+#define sk_KRB5_CHECKSUM_new(cmp) SKM_sk_new(KRB5_CHECKSUM, (cmp))
+#define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM)
+#define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_value(st, i) SKM_sk_value(KRB5_CHECKSUM, (st), (i))
+#define sk_KRB5_CHECKSUM_set(st, i, val) SKM_sk_set(KRB5_CHECKSUM, (st), (i), (val))
+#define sk_KRB5_CHECKSUM_zero(st) SKM_sk_zero(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_push(st, val) SKM_sk_push(KRB5_CHECKSUM, (st), (val))
+#define sk_KRB5_CHECKSUM_unshift(st, val) SKM_sk_unshift(KRB5_CHECKSUM, (st), (val))
+#define sk_KRB5_CHECKSUM_find(st, val) SKM_sk_find(KRB5_CHECKSUM, (st), (val))
+#define sk_KRB5_CHECKSUM_find_ex(st, val) SKM_sk_find_ex(KRB5_CHECKSUM, (st), (val))
+#define sk_KRB5_CHECKSUM_delete(st, i) SKM_sk_delete(KRB5_CHECKSUM, (st), (i))
+#define sk_KRB5_CHECKSUM_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_CHECKSUM, (st), (ptr))
+#define sk_KRB5_CHECKSUM_insert(st, val, i) SKM_sk_insert(KRB5_CHECKSUM, (st), (val), (i))
+#define sk_KRB5_CHECKSUM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_CHECKSUM, (st), (cmp))
+#define sk_KRB5_CHECKSUM_dup(st) SKM_sk_dup(KRB5_CHECKSUM, st)
+#define sk_KRB5_CHECKSUM_pop_free(st, free_func) SKM_sk_pop_free(KRB5_CHECKSUM, (st), (free_func))
+#define sk_KRB5_CHECKSUM_shift(st) SKM_sk_shift(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_pop(st) SKM_sk_pop(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st))
+
+#define sk_KRB5_ENCDATA_new(cmp) SKM_sk_new(KRB5_ENCDATA, (cmp))
+#define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA)
+#define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_value(st, i) SKM_sk_value(KRB5_ENCDATA, (st), (i))
+#define sk_KRB5_ENCDATA_set(st, i, val) SKM_sk_set(KRB5_ENCDATA, (st), (i), (val))
+#define sk_KRB5_ENCDATA_zero(st) SKM_sk_zero(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_push(st, val) SKM_sk_push(KRB5_ENCDATA, (st), (val))
+#define sk_KRB5_ENCDATA_unshift(st, val) SKM_sk_unshift(KRB5_ENCDATA, (st), (val))
+#define sk_KRB5_ENCDATA_find(st, val) SKM_sk_find(KRB5_ENCDATA, (st), (val))
+#define sk_KRB5_ENCDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCDATA, (st), (val))
+#define sk_KRB5_ENCDATA_delete(st, i) SKM_sk_delete(KRB5_ENCDATA, (st), (i))
+#define sk_KRB5_ENCDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCDATA, (st), (ptr))
+#define sk_KRB5_ENCDATA_insert(st, val, i) SKM_sk_insert(KRB5_ENCDATA, (st), (val), (i))
+#define sk_KRB5_ENCDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCDATA, (st), (cmp))
+#define sk_KRB5_ENCDATA_dup(st) SKM_sk_dup(KRB5_ENCDATA, st)
+#define sk_KRB5_ENCDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCDATA, (st), (free_func))
+#define sk_KRB5_ENCDATA_shift(st) SKM_sk_shift(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_pop(st) SKM_sk_pop(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st))
+
+#define sk_KRB5_ENCKEY_new(cmp) SKM_sk_new(KRB5_ENCKEY, (cmp))
+#define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY)
+#define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_value(st, i) SKM_sk_value(KRB5_ENCKEY, (st), (i))
+#define sk_KRB5_ENCKEY_set(st, i, val) SKM_sk_set(KRB5_ENCKEY, (st), (i), (val))
+#define sk_KRB5_ENCKEY_zero(st) SKM_sk_zero(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_push(st, val) SKM_sk_push(KRB5_ENCKEY, (st), (val))
+#define sk_KRB5_ENCKEY_unshift(st, val) SKM_sk_unshift(KRB5_ENCKEY, (st), (val))
+#define sk_KRB5_ENCKEY_find(st, val) SKM_sk_find(KRB5_ENCKEY, (st), (val))
+#define sk_KRB5_ENCKEY_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCKEY, (st), (val))
+#define sk_KRB5_ENCKEY_delete(st, i) SKM_sk_delete(KRB5_ENCKEY, (st), (i))
+#define sk_KRB5_ENCKEY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCKEY, (st), (ptr))
+#define sk_KRB5_ENCKEY_insert(st, val, i) SKM_sk_insert(KRB5_ENCKEY, (st), (val), (i))
+#define sk_KRB5_ENCKEY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCKEY, (st), (cmp))
+#define sk_KRB5_ENCKEY_dup(st) SKM_sk_dup(KRB5_ENCKEY, st)
+#define sk_KRB5_ENCKEY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCKEY, (st), (free_func))
+#define sk_KRB5_ENCKEY_shift(st) SKM_sk_shift(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_pop(st) SKM_sk_pop(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st))
+
+#define sk_KRB5_PRINCNAME_new(cmp) SKM_sk_new(KRB5_PRINCNAME, (cmp))
+#define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME)
+#define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_value(st, i) SKM_sk_value(KRB5_PRINCNAME, (st), (i))
+#define sk_KRB5_PRINCNAME_set(st, i, val) SKM_sk_set(KRB5_PRINCNAME, (st), (i), (val))
+#define sk_KRB5_PRINCNAME_zero(st) SKM_sk_zero(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_push(st, val) SKM_sk_push(KRB5_PRINCNAME, (st), (val))
+#define sk_KRB5_PRINCNAME_unshift(st, val) SKM_sk_unshift(KRB5_PRINCNAME, (st), (val))
+#define sk_KRB5_PRINCNAME_find(st, val) SKM_sk_find(KRB5_PRINCNAME, (st), (val))
+#define sk_KRB5_PRINCNAME_find_ex(st, val) SKM_sk_find_ex(KRB5_PRINCNAME, (st), (val))
+#define sk_KRB5_PRINCNAME_delete(st, i) SKM_sk_delete(KRB5_PRINCNAME, (st), (i))
+#define sk_KRB5_PRINCNAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_PRINCNAME, (st), (ptr))
+#define sk_KRB5_PRINCNAME_insert(st, val, i) SKM_sk_insert(KRB5_PRINCNAME, (st), (val), (i))
+#define sk_KRB5_PRINCNAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_PRINCNAME, (st), (cmp))
+#define sk_KRB5_PRINCNAME_dup(st) SKM_sk_dup(KRB5_PRINCNAME, st)
+#define sk_KRB5_PRINCNAME_pop_free(st, free_func) SKM_sk_pop_free(KRB5_PRINCNAME, (st), (free_func))
+#define sk_KRB5_PRINCNAME_shift(st) SKM_sk_shift(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_pop(st) SKM_sk_pop(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st))
+
+#define sk_KRB5_TKTBODY_new(cmp) SKM_sk_new(KRB5_TKTBODY, (cmp))
+#define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY)
+#define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_value(st, i) SKM_sk_value(KRB5_TKTBODY, (st), (i))
+#define sk_KRB5_TKTBODY_set(st, i, val) SKM_sk_set(KRB5_TKTBODY, (st), (i), (val))
+#define sk_KRB5_TKTBODY_zero(st) SKM_sk_zero(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_push(st, val) SKM_sk_push(KRB5_TKTBODY, (st), (val))
+#define sk_KRB5_TKTBODY_unshift(st, val) SKM_sk_unshift(KRB5_TKTBODY, (st), (val))
+#define sk_KRB5_TKTBODY_find(st, val) SKM_sk_find(KRB5_TKTBODY, (st), (val))
+#define sk_KRB5_TKTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_TKTBODY, (st), (val))
+#define sk_KRB5_TKTBODY_delete(st, i) SKM_sk_delete(KRB5_TKTBODY, (st), (i))
+#define sk_KRB5_TKTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_TKTBODY, (st), (ptr))
+#define sk_KRB5_TKTBODY_insert(st, val, i) SKM_sk_insert(KRB5_TKTBODY, (st), (val), (i))
+#define sk_KRB5_TKTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_TKTBODY, (st), (cmp))
+#define sk_KRB5_TKTBODY_dup(st) SKM_sk_dup(KRB5_TKTBODY, st)
+#define sk_KRB5_TKTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_TKTBODY, (st), (free_func))
+#define sk_KRB5_TKTBODY_shift(st) SKM_sk_shift(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_pop(st) SKM_sk_pop(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st))
+
+#define sk_MEM_OBJECT_DATA_new(cmp) SKM_sk_new(MEM_OBJECT_DATA, (cmp))
+#define sk_MEM_OBJECT_DATA_new_null() SKM_sk_new_null(MEM_OBJECT_DATA)
+#define sk_MEM_OBJECT_DATA_free(st) SKM_sk_free(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_num(st) SKM_sk_num(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_value(st, i) SKM_sk_value(MEM_OBJECT_DATA, (st), (i))
+#define sk_MEM_OBJECT_DATA_set(st, i, val) SKM_sk_set(MEM_OBJECT_DATA, (st), (i), (val))
+#define sk_MEM_OBJECT_DATA_zero(st) SKM_sk_zero(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_push(st, val) SKM_sk_push(MEM_OBJECT_DATA, (st), (val))
+#define sk_MEM_OBJECT_DATA_unshift(st, val) SKM_sk_unshift(MEM_OBJECT_DATA, (st), (val))
+#define sk_MEM_OBJECT_DATA_find(st, val) SKM_sk_find(MEM_OBJECT_DATA, (st), (val))
+#define sk_MEM_OBJECT_DATA_find_ex(st, val) SKM_sk_find_ex(MEM_OBJECT_DATA, (st), (val))
+#define sk_MEM_OBJECT_DATA_delete(st, i) SKM_sk_delete(MEM_OBJECT_DATA, (st), (i))
+#define sk_MEM_OBJECT_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEM_OBJECT_DATA, (st), (ptr))
+#define sk_MEM_OBJECT_DATA_insert(st, val, i) SKM_sk_insert(MEM_OBJECT_DATA, (st), (val), (i))
+#define sk_MEM_OBJECT_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEM_OBJECT_DATA, (st), (cmp))
+#define sk_MEM_OBJECT_DATA_dup(st) SKM_sk_dup(MEM_OBJECT_DATA, st)
+#define sk_MEM_OBJECT_DATA_pop_free(st, free_func) SKM_sk_pop_free(MEM_OBJECT_DATA, (st), (free_func))
+#define sk_MEM_OBJECT_DATA_shift(st) SKM_sk_shift(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_pop(st) SKM_sk_pop(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_sort(st) SKM_sk_sort(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_is_sorted(st) SKM_sk_is_sorted(MEM_OBJECT_DATA, (st))
+
+#define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp))
+#define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER)
+#define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st))
+#define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st))
+#define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i))
+#define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val))
+#define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st))
+#define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i))
+#define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr))
+#define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i))
+#define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp))
+#define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st)
+#define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func))
+#define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st))
+#define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st))
+#define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st))
+#define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st))
+
+#define sk_MIME_PARAM_new(cmp) SKM_sk_new(MIME_PARAM, (cmp))
+#define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM)
+#define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st))
+#define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st))
+#define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i))
+#define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val))
+#define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st))
+#define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i))
+#define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr))
+#define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i))
+#define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp))
+#define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st)
+#define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func))
+#define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st))
+#define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st))
+#define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st))
+#define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st))
+
+#define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp))
+#define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS)
+#define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_value(st, i) SKM_sk_value(NAME_FUNCS, (st), (i))
+#define sk_NAME_FUNCS_set(st, i, val) SKM_sk_set(NAME_FUNCS, (st), (i), (val))
+#define sk_NAME_FUNCS_zero(st) SKM_sk_zero(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_push(st, val) SKM_sk_push(NAME_FUNCS, (st), (val))
+#define sk_NAME_FUNCS_unshift(st, val) SKM_sk_unshift(NAME_FUNCS, (st), (val))
+#define sk_NAME_FUNCS_find(st, val) SKM_sk_find(NAME_FUNCS, (st), (val))
+#define sk_NAME_FUNCS_find_ex(st, val) SKM_sk_find_ex(NAME_FUNCS, (st), (val))
+#define sk_NAME_FUNCS_delete(st, i) SKM_sk_delete(NAME_FUNCS, (st), (i))
+#define sk_NAME_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(NAME_FUNCS, (st), (ptr))
+#define sk_NAME_FUNCS_insert(st, val, i) SKM_sk_insert(NAME_FUNCS, (st), (val), (i))
+#define sk_NAME_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(NAME_FUNCS, (st), (cmp))
+#define sk_NAME_FUNCS_dup(st) SKM_sk_dup(NAME_FUNCS, st)
+#define sk_NAME_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(NAME_FUNCS, (st), (free_func))
+#define sk_NAME_FUNCS_shift(st) SKM_sk_shift(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_pop(st) SKM_sk_pop(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st))
+
+#define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp))
+#define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID)
+#define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_value(st, i) SKM_sk_value(OCSP_CERTID, (st), (i))
+#define sk_OCSP_CERTID_set(st, i, val) SKM_sk_set(OCSP_CERTID, (st), (i), (val))
+#define sk_OCSP_CERTID_zero(st) SKM_sk_zero(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_push(st, val) SKM_sk_push(OCSP_CERTID, (st), (val))
+#define sk_OCSP_CERTID_unshift(st, val) SKM_sk_unshift(OCSP_CERTID, (st), (val))
+#define sk_OCSP_CERTID_find(st, val) SKM_sk_find(OCSP_CERTID, (st), (val))
+#define sk_OCSP_CERTID_find_ex(st, val) SKM_sk_find_ex(OCSP_CERTID, (st), (val))
+#define sk_OCSP_CERTID_delete(st, i) SKM_sk_delete(OCSP_CERTID, (st), (i))
+#define sk_OCSP_CERTID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_CERTID, (st), (ptr))
+#define sk_OCSP_CERTID_insert(st, val, i) SKM_sk_insert(OCSP_CERTID, (st), (val), (i))
+#define sk_OCSP_CERTID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_CERTID, (st), (cmp))
+#define sk_OCSP_CERTID_dup(st) SKM_sk_dup(OCSP_CERTID, st)
+#define sk_OCSP_CERTID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_CERTID, (st), (free_func))
+#define sk_OCSP_CERTID_shift(st) SKM_sk_shift(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_pop(st) SKM_sk_pop(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st))
+
+#define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp))
+#define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ)
+#define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_value(st, i) SKM_sk_value(OCSP_ONEREQ, (st), (i))
+#define sk_OCSP_ONEREQ_set(st, i, val) SKM_sk_set(OCSP_ONEREQ, (st), (i), (val))
+#define sk_OCSP_ONEREQ_zero(st) SKM_sk_zero(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_push(st, val) SKM_sk_push(OCSP_ONEREQ, (st), (val))
+#define sk_OCSP_ONEREQ_unshift(st, val) SKM_sk_unshift(OCSP_ONEREQ, (st), (val))
+#define sk_OCSP_ONEREQ_find(st, val) SKM_sk_find(OCSP_ONEREQ, (st), (val))
+#define sk_OCSP_ONEREQ_find_ex(st, val) SKM_sk_find_ex(OCSP_ONEREQ, (st), (val))
+#define sk_OCSP_ONEREQ_delete(st, i) SKM_sk_delete(OCSP_ONEREQ, (st), (i))
+#define sk_OCSP_ONEREQ_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_ONEREQ, (st), (ptr))
+#define sk_OCSP_ONEREQ_insert(st, val, i) SKM_sk_insert(OCSP_ONEREQ, (st), (val), (i))
+#define sk_OCSP_ONEREQ_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_ONEREQ, (st), (cmp))
+#define sk_OCSP_ONEREQ_dup(st) SKM_sk_dup(OCSP_ONEREQ, st)
+#define sk_OCSP_ONEREQ_pop_free(st, free_func) SKM_sk_pop_free(OCSP_ONEREQ, (st), (free_func))
+#define sk_OCSP_ONEREQ_shift(st) SKM_sk_shift(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_pop(st) SKM_sk_pop(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st))
+
+#define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp))
+#define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID)
+#define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st))
+#define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st))
+#define sk_OCSP_RESPID_value(st, i) SKM_sk_value(OCSP_RESPID, (st), (i))
+#define sk_OCSP_RESPID_set(st, i, val) SKM_sk_set(OCSP_RESPID, (st), (i), (val))
+#define sk_OCSP_RESPID_zero(st) SKM_sk_zero(OCSP_RESPID, (st))
+#define sk_OCSP_RESPID_push(st, val) SKM_sk_push(OCSP_RESPID, (st), (val))
+#define sk_OCSP_RESPID_unshift(st, val) SKM_sk_unshift(OCSP_RESPID, (st), (val))
+#define sk_OCSP_RESPID_find(st, val) SKM_sk_find(OCSP_RESPID, (st), (val))
+#define sk_OCSP_RESPID_find_ex(st, val) SKM_sk_find_ex(OCSP_RESPID, (st), (val))
+#define sk_OCSP_RESPID_delete(st, i) SKM_sk_delete(OCSP_RESPID, (st), (i))
+#define sk_OCSP_RESPID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_RESPID, (st), (ptr))
+#define sk_OCSP_RESPID_insert(st, val, i) SKM_sk_insert(OCSP_RESPID, (st), (val), (i))
+#define sk_OCSP_RESPID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_RESPID, (st), (cmp))
+#define sk_OCSP_RESPID_dup(st) SKM_sk_dup(OCSP_RESPID, st)
+#define sk_OCSP_RESPID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_RESPID, (st), (free_func))
+#define sk_OCSP_RESPID_shift(st) SKM_sk_shift(OCSP_RESPID, (st))
+#define sk_OCSP_RESPID_pop(st) SKM_sk_pop(OCSP_RESPID, (st))
+#define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st))
+#define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st))
+
+#define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp))
+#define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP)
+#define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_value(st, i) SKM_sk_value(OCSP_SINGLERESP, (st), (i))
+#define sk_OCSP_SINGLERESP_set(st, i, val) SKM_sk_set(OCSP_SINGLERESP, (st), (i), (val))
+#define sk_OCSP_SINGLERESP_zero(st) SKM_sk_zero(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_push(st, val) SKM_sk_push(OCSP_SINGLERESP, (st), (val))
+#define sk_OCSP_SINGLERESP_unshift(st, val) SKM_sk_unshift(OCSP_SINGLERESP, (st), (val))
+#define sk_OCSP_SINGLERESP_find(st, val) SKM_sk_find(OCSP_SINGLERESP, (st), (val))
+#define sk_OCSP_SINGLERESP_find_ex(st, val) SKM_sk_find_ex(OCSP_SINGLERESP, (st), (val))
+#define sk_OCSP_SINGLERESP_delete(st, i) SKM_sk_delete(OCSP_SINGLERESP, (st), (i))
+#define sk_OCSP_SINGLERESP_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_SINGLERESP, (st), (ptr))
+#define sk_OCSP_SINGLERESP_insert(st, val, i) SKM_sk_insert(OCSP_SINGLERESP, (st), (val), (i))
+#define sk_OCSP_SINGLERESP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_SINGLERESP, (st), (cmp))
+#define sk_OCSP_SINGLERESP_dup(st) SKM_sk_dup(OCSP_SINGLERESP, st)
+#define sk_OCSP_SINGLERESP_pop_free(st, free_func) SKM_sk_pop_free(OCSP_SINGLERESP, (st), (free_func))
+#define sk_OCSP_SINGLERESP_shift(st) SKM_sk_shift(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_pop(st) SKM_sk_pop(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st))
+
+#define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp))
+#define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG)
+#define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_value(st, i) SKM_sk_value(PKCS12_SAFEBAG, (st), (i))
+#define sk_PKCS12_SAFEBAG_set(st, i, val) SKM_sk_set(PKCS12_SAFEBAG, (st), (i), (val))
+#define sk_PKCS12_SAFEBAG_zero(st) SKM_sk_zero(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_push(st, val) SKM_sk_push(PKCS12_SAFEBAG, (st), (val))
+#define sk_PKCS12_SAFEBAG_unshift(st, val) SKM_sk_unshift(PKCS12_SAFEBAG, (st), (val))
+#define sk_PKCS12_SAFEBAG_find(st, val) SKM_sk_find(PKCS12_SAFEBAG, (st), (val))
+#define sk_PKCS12_SAFEBAG_find_ex(st, val) SKM_sk_find_ex(PKCS12_SAFEBAG, (st), (val))
+#define sk_PKCS12_SAFEBAG_delete(st, i) SKM_sk_delete(PKCS12_SAFEBAG, (st), (i))
+#define sk_PKCS12_SAFEBAG_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS12_SAFEBAG, (st), (ptr))
+#define sk_PKCS12_SAFEBAG_insert(st, val, i) SKM_sk_insert(PKCS12_SAFEBAG, (st), (val), (i))
+#define sk_PKCS12_SAFEBAG_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS12_SAFEBAG, (st), (cmp))
+#define sk_PKCS12_SAFEBAG_dup(st) SKM_sk_dup(PKCS12_SAFEBAG, st)
+#define sk_PKCS12_SAFEBAG_pop_free(st, free_func) SKM_sk_pop_free(PKCS12_SAFEBAG, (st), (free_func))
+#define sk_PKCS12_SAFEBAG_shift(st) SKM_sk_shift(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_pop(st) SKM_sk_pop(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st))
+
+#define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp))
+#define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7)
+#define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st))
+#define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st))
+#define sk_PKCS7_value(st, i) SKM_sk_value(PKCS7, (st), (i))
+#define sk_PKCS7_set(st, i, val) SKM_sk_set(PKCS7, (st), (i), (val))
+#define sk_PKCS7_zero(st) SKM_sk_zero(PKCS7, (st))
+#define sk_PKCS7_push(st, val) SKM_sk_push(PKCS7, (st), (val))
+#define sk_PKCS7_unshift(st, val) SKM_sk_unshift(PKCS7, (st), (val))
+#define sk_PKCS7_find(st, val) SKM_sk_find(PKCS7, (st), (val))
+#define sk_PKCS7_find_ex(st, val) SKM_sk_find_ex(PKCS7, (st), (val))
+#define sk_PKCS7_delete(st, i) SKM_sk_delete(PKCS7, (st), (i))
+#define sk_PKCS7_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7, (st), (ptr))
+#define sk_PKCS7_insert(st, val, i) SKM_sk_insert(PKCS7, (st), (val), (i))
+#define sk_PKCS7_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7, (st), (cmp))
+#define sk_PKCS7_dup(st) SKM_sk_dup(PKCS7, st)
+#define sk_PKCS7_pop_free(st, free_func) SKM_sk_pop_free(PKCS7, (st), (free_func))
+#define sk_PKCS7_shift(st) SKM_sk_shift(PKCS7, (st))
+#define sk_PKCS7_pop(st) SKM_sk_pop(PKCS7, (st))
+#define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st))
+#define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st))
+
+#define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp))
+#define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO)
+#define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_value(st, i) SKM_sk_value(PKCS7_RECIP_INFO, (st), (i))
+#define sk_PKCS7_RECIP_INFO_set(st, i, val) SKM_sk_set(PKCS7_RECIP_INFO, (st), (i), (val))
+#define sk_PKCS7_RECIP_INFO_zero(st) SKM_sk_zero(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_push(st, val) SKM_sk_push(PKCS7_RECIP_INFO, (st), (val))
+#define sk_PKCS7_RECIP_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_RECIP_INFO, (st), (val))
+#define sk_PKCS7_RECIP_INFO_find(st, val) SKM_sk_find(PKCS7_RECIP_INFO, (st), (val))
+#define sk_PKCS7_RECIP_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_RECIP_INFO, (st), (val))
+#define sk_PKCS7_RECIP_INFO_delete(st, i) SKM_sk_delete(PKCS7_RECIP_INFO, (st), (i))
+#define sk_PKCS7_RECIP_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_RECIP_INFO, (st), (ptr))
+#define sk_PKCS7_RECIP_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_RECIP_INFO, (st), (val), (i))
+#define sk_PKCS7_RECIP_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_RECIP_INFO, (st), (cmp))
+#define sk_PKCS7_RECIP_INFO_dup(st) SKM_sk_dup(PKCS7_RECIP_INFO, st)
+#define sk_PKCS7_RECIP_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_RECIP_INFO, (st), (free_func))
+#define sk_PKCS7_RECIP_INFO_shift(st) SKM_sk_shift(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_pop(st) SKM_sk_pop(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st))
+
+#define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp))
+#define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO)
+#define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_value(st, i) SKM_sk_value(PKCS7_SIGNER_INFO, (st), (i))
+#define sk_PKCS7_SIGNER_INFO_set(st, i, val) SKM_sk_set(PKCS7_SIGNER_INFO, (st), (i), (val))
+#define sk_PKCS7_SIGNER_INFO_zero(st) SKM_sk_zero(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_push(st, val) SKM_sk_push(PKCS7_SIGNER_INFO, (st), (val))
+#define sk_PKCS7_SIGNER_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_SIGNER_INFO, (st), (val))
+#define sk_PKCS7_SIGNER_INFO_find(st, val) SKM_sk_find(PKCS7_SIGNER_INFO, (st), (val))
+#define sk_PKCS7_SIGNER_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_SIGNER_INFO, (st), (val))
+#define sk_PKCS7_SIGNER_INFO_delete(st, i) SKM_sk_delete(PKCS7_SIGNER_INFO, (st), (i))
+#define sk_PKCS7_SIGNER_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_SIGNER_INFO, (st), (ptr))
+#define sk_PKCS7_SIGNER_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_SIGNER_INFO, (st), (val), (i))
+#define sk_PKCS7_SIGNER_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_SIGNER_INFO, (st), (cmp))
+#define sk_PKCS7_SIGNER_INFO_dup(st) SKM_sk_dup(PKCS7_SIGNER_INFO, st)
+#define sk_PKCS7_SIGNER_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_SIGNER_INFO, (st), (free_func))
+#define sk_PKCS7_SIGNER_INFO_shift(st) SKM_sk_shift(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_pop(st) SKM_sk_pop(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st))
+
+#define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp))
+#define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO)
+#define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st))
+#define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st))
+#define sk_POLICYINFO_value(st, i) SKM_sk_value(POLICYINFO, (st), (i))
+#define sk_POLICYINFO_set(st, i, val) SKM_sk_set(POLICYINFO, (st), (i), (val))
+#define sk_POLICYINFO_zero(st) SKM_sk_zero(POLICYINFO, (st))
+#define sk_POLICYINFO_push(st, val) SKM_sk_push(POLICYINFO, (st), (val))
+#define sk_POLICYINFO_unshift(st, val) SKM_sk_unshift(POLICYINFO, (st), (val))
+#define sk_POLICYINFO_find(st, val) SKM_sk_find(POLICYINFO, (st), (val))
+#define sk_POLICYINFO_find_ex(st, val) SKM_sk_find_ex(POLICYINFO, (st), (val))
+#define sk_POLICYINFO_delete(st, i) SKM_sk_delete(POLICYINFO, (st), (i))
+#define sk_POLICYINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYINFO, (st), (ptr))
+#define sk_POLICYINFO_insert(st, val, i) SKM_sk_insert(POLICYINFO, (st), (val), (i))
+#define sk_POLICYINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYINFO, (st), (cmp))
+#define sk_POLICYINFO_dup(st) SKM_sk_dup(POLICYINFO, st)
+#define sk_POLICYINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYINFO, (st), (free_func))
+#define sk_POLICYINFO_shift(st) SKM_sk_shift(POLICYINFO, (st))
+#define sk_POLICYINFO_pop(st) SKM_sk_pop(POLICYINFO, (st))
+#define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st))
+#define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st))
+
+#define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp))
+#define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO)
+#define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_value(st, i) SKM_sk_value(POLICYQUALINFO, (st), (i))
+#define sk_POLICYQUALINFO_set(st, i, val) SKM_sk_set(POLICYQUALINFO, (st), (i), (val))
+#define sk_POLICYQUALINFO_zero(st) SKM_sk_zero(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_push(st, val) SKM_sk_push(POLICYQUALINFO, (st), (val))
+#define sk_POLICYQUALINFO_unshift(st, val) SKM_sk_unshift(POLICYQUALINFO, (st), (val))
+#define sk_POLICYQUALINFO_find(st, val) SKM_sk_find(POLICYQUALINFO, (st), (val))
+#define sk_POLICYQUALINFO_find_ex(st, val) SKM_sk_find_ex(POLICYQUALINFO, (st), (val))
+#define sk_POLICYQUALINFO_delete(st, i) SKM_sk_delete(POLICYQUALINFO, (st), (i))
+#define sk_POLICYQUALINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYQUALINFO, (st), (ptr))
+#define sk_POLICYQUALINFO_insert(st, val, i) SKM_sk_insert(POLICYQUALINFO, (st), (val), (i))
+#define sk_POLICYQUALINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYQUALINFO, (st), (cmp))
+#define sk_POLICYQUALINFO_dup(st) SKM_sk_dup(POLICYQUALINFO, st)
+#define sk_POLICYQUALINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYQUALINFO, (st), (free_func))
+#define sk_POLICYQUALINFO_shift(st) SKM_sk_shift(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_pop(st) SKM_sk_pop(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st))
+
+#define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp))
+#define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING)
+#define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_value(st, i) SKM_sk_value(POLICY_MAPPING, (st), (i))
+#define sk_POLICY_MAPPING_set(st, i, val) SKM_sk_set(POLICY_MAPPING, (st), (i), (val))
+#define sk_POLICY_MAPPING_zero(st) SKM_sk_zero(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_push(st, val) SKM_sk_push(POLICY_MAPPING, (st), (val))
+#define sk_POLICY_MAPPING_unshift(st, val) SKM_sk_unshift(POLICY_MAPPING, (st), (val))
+#define sk_POLICY_MAPPING_find(st, val) SKM_sk_find(POLICY_MAPPING, (st), (val))
+#define sk_POLICY_MAPPING_find_ex(st, val) SKM_sk_find_ex(POLICY_MAPPING, (st), (val))
+#define sk_POLICY_MAPPING_delete(st, i) SKM_sk_delete(POLICY_MAPPING, (st), (i))
+#define sk_POLICY_MAPPING_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICY_MAPPING, (st), (ptr))
+#define sk_POLICY_MAPPING_insert(st, val, i) SKM_sk_insert(POLICY_MAPPING, (st), (val), (i))
+#define sk_POLICY_MAPPING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICY_MAPPING, (st), (cmp))
+#define sk_POLICY_MAPPING_dup(st) SKM_sk_dup(POLICY_MAPPING, st)
+#define sk_POLICY_MAPPING_pop_free(st, free_func) SKM_sk_pop_free(POLICY_MAPPING, (st), (free_func))
+#define sk_POLICY_MAPPING_shift(st) SKM_sk_shift(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_pop(st) SKM_sk_pop(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st))
+
+#define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp))
+#define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER)
+#define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_value(st, i) SKM_sk_value(SSL_CIPHER, (st), (i))
+#define sk_SSL_CIPHER_set(st, i, val) SKM_sk_set(SSL_CIPHER, (st), (i), (val))
+#define sk_SSL_CIPHER_zero(st) SKM_sk_zero(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_push(st, val) SKM_sk_push(SSL_CIPHER, (st), (val))
+#define sk_SSL_CIPHER_unshift(st, val) SKM_sk_unshift(SSL_CIPHER, (st), (val))
+#define sk_SSL_CIPHER_find(st, val) SKM_sk_find(SSL_CIPHER, (st), (val))
+#define sk_SSL_CIPHER_find_ex(st, val) SKM_sk_find_ex(SSL_CIPHER, (st), (val))
+#define sk_SSL_CIPHER_delete(st, i) SKM_sk_delete(SSL_CIPHER, (st), (i))
+#define sk_SSL_CIPHER_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_CIPHER, (st), (ptr))
+#define sk_SSL_CIPHER_insert(st, val, i) SKM_sk_insert(SSL_CIPHER, (st), (val), (i))
+#define sk_SSL_CIPHER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_CIPHER, (st), (cmp))
+#define sk_SSL_CIPHER_dup(st) SKM_sk_dup(SSL_CIPHER, st)
+#define sk_SSL_CIPHER_pop_free(st, free_func) SKM_sk_pop_free(SSL_CIPHER, (st), (free_func))
+#define sk_SSL_CIPHER_shift(st) SKM_sk_shift(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_pop(st) SKM_sk_pop(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st))
+
+#define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp))
+#define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP)
+#define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st))
+#define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st))
+#define sk_SSL_COMP_value(st, i) SKM_sk_value(SSL_COMP, (st), (i))
+#define sk_SSL_COMP_set(st, i, val) SKM_sk_set(SSL_COMP, (st), (i), (val))
+#define sk_SSL_COMP_zero(st) SKM_sk_zero(SSL_COMP, (st))
+#define sk_SSL_COMP_push(st, val) SKM_sk_push(SSL_COMP, (st), (val))
+#define sk_SSL_COMP_unshift(st, val) SKM_sk_unshift(SSL_COMP, (st), (val))
+#define sk_SSL_COMP_find(st, val) SKM_sk_find(SSL_COMP, (st), (val))
+#define sk_SSL_COMP_find_ex(st, val) SKM_sk_find_ex(SSL_COMP, (st), (val))
+#define sk_SSL_COMP_delete(st, i) SKM_sk_delete(SSL_COMP, (st), (i))
+#define sk_SSL_COMP_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_COMP, (st), (ptr))
+#define sk_SSL_COMP_insert(st, val, i) SKM_sk_insert(SSL_COMP, (st), (val), (i))
+#define sk_SSL_COMP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_COMP, (st), (cmp))
+#define sk_SSL_COMP_dup(st) SKM_sk_dup(SSL_COMP, st)
+#define sk_SSL_COMP_pop_free(st, free_func) SKM_sk_pop_free(SSL_COMP, (st), (free_func))
+#define sk_SSL_COMP_shift(st) SKM_sk_shift(SSL_COMP, (st))
+#define sk_SSL_COMP_pop(st) SKM_sk_pop(SSL_COMP, (st))
+#define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st))
+#define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st))
+
+#define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp))
+#define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY)
+#define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i))
+#define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i))
+#define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr))
+#define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i))
+#define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp))
+#define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st)
+#define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func))
+#define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st))
+
+#define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp))
+#define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO)
+#define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i))
+#define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val))
+#define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val))
+#define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val))
+#define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val))
+#define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val))
+#define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i))
+#define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr))
+#define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i))
+#define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp))
+#define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st)
+#define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func))
+#define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st))
+
+#define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp))
+#define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT)
+#define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_value(st, i) SKM_sk_value(STORE_OBJECT, (st), (i))
+#define sk_STORE_OBJECT_set(st, i, val) SKM_sk_set(STORE_OBJECT, (st), (i), (val))
+#define sk_STORE_OBJECT_zero(st) SKM_sk_zero(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_push(st, val) SKM_sk_push(STORE_OBJECT, (st), (val))
+#define sk_STORE_OBJECT_unshift(st, val) SKM_sk_unshift(STORE_OBJECT, (st), (val))
+#define sk_STORE_OBJECT_find(st, val) SKM_sk_find(STORE_OBJECT, (st), (val))
+#define sk_STORE_OBJECT_find_ex(st, val) SKM_sk_find_ex(STORE_OBJECT, (st), (val))
+#define sk_STORE_OBJECT_delete(st, i) SKM_sk_delete(STORE_OBJECT, (st), (i))
+#define sk_STORE_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_OBJECT, (st), (ptr))
+#define sk_STORE_OBJECT_insert(st, val, i) SKM_sk_insert(STORE_OBJECT, (st), (val), (i))
+#define sk_STORE_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_OBJECT, (st), (cmp))
+#define sk_STORE_OBJECT_dup(st) SKM_sk_dup(STORE_OBJECT, st)
+#define sk_STORE_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(STORE_OBJECT, (st), (free_func))
+#define sk_STORE_OBJECT_shift(st) SKM_sk_shift(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_pop(st) SKM_sk_pop(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st))
+
+#define sk_SXNETID_new(cmp) SKM_sk_new(SXNETID, (cmp))
+#define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID)
+#define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st))
+#define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st))
+#define sk_SXNETID_value(st, i) SKM_sk_value(SXNETID, (st), (i))
+#define sk_SXNETID_set(st, i, val) SKM_sk_set(SXNETID, (st), (i), (val))
+#define sk_SXNETID_zero(st) SKM_sk_zero(SXNETID, (st))
+#define sk_SXNETID_push(st, val) SKM_sk_push(SXNETID, (st), (val))
+#define sk_SXNETID_unshift(st, val) SKM_sk_unshift(SXNETID, (st), (val))
+#define sk_SXNETID_find(st, val) SKM_sk_find(SXNETID, (st), (val))
+#define sk_SXNETID_find_ex(st, val) SKM_sk_find_ex(SXNETID, (st), (val))
+#define sk_SXNETID_delete(st, i) SKM_sk_delete(SXNETID, (st), (i))
+#define sk_SXNETID_delete_ptr(st, ptr) SKM_sk_delete_ptr(SXNETID, (st), (ptr))
+#define sk_SXNETID_insert(st, val, i) SKM_sk_insert(SXNETID, (st), (val), (i))
+#define sk_SXNETID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SXNETID, (st), (cmp))
+#define sk_SXNETID_dup(st) SKM_sk_dup(SXNETID, st)
+#define sk_SXNETID_pop_free(st, free_func) SKM_sk_pop_free(SXNETID, (st), (free_func))
+#define sk_SXNETID_shift(st) SKM_sk_shift(SXNETID, (st))
+#define sk_SXNETID_pop(st) SKM_sk_pop(SXNETID, (st))
+#define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st))
+#define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st))
+
+#define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp))
+#define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING)
+#define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st))
+#define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st))
+#define sk_UI_STRING_value(st, i) SKM_sk_value(UI_STRING, (st), (i))
+#define sk_UI_STRING_set(st, i, val) SKM_sk_set(UI_STRING, (st), (i), (val))
+#define sk_UI_STRING_zero(st) SKM_sk_zero(UI_STRING, (st))
+#define sk_UI_STRING_push(st, val) SKM_sk_push(UI_STRING, (st), (val))
+#define sk_UI_STRING_unshift(st, val) SKM_sk_unshift(UI_STRING, (st), (val))
+#define sk_UI_STRING_find(st, val) SKM_sk_find(UI_STRING, (st), (val))
+#define sk_UI_STRING_find_ex(st, val) SKM_sk_find_ex(UI_STRING, (st), (val))
+#define sk_UI_STRING_delete(st, i) SKM_sk_delete(UI_STRING, (st), (i))
+#define sk_UI_STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(UI_STRING, (st), (ptr))
+#define sk_UI_STRING_insert(st, val, i) SKM_sk_insert(UI_STRING, (st), (val), (i))
+#define sk_UI_STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(UI_STRING, (st), (cmp))
+#define sk_UI_STRING_dup(st) SKM_sk_dup(UI_STRING, st)
+#define sk_UI_STRING_pop_free(st, free_func) SKM_sk_pop_free(UI_STRING, (st), (free_func))
+#define sk_UI_STRING_shift(st) SKM_sk_shift(UI_STRING, (st))
+#define sk_UI_STRING_pop(st) SKM_sk_pop(UI_STRING, (st))
+#define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st))
+#define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st))
+
+#define sk_X509_new(cmp) SKM_sk_new(X509, (cmp))
+#define sk_X509_new_null() SKM_sk_new_null(X509)
+#define sk_X509_free(st) SKM_sk_free(X509, (st))
+#define sk_X509_num(st) SKM_sk_num(X509, (st))
+#define sk_X509_value(st, i) SKM_sk_value(X509, (st), (i))
+#define sk_X509_set(st, i, val) SKM_sk_set(X509, (st), (i), (val))
+#define sk_X509_zero(st) SKM_sk_zero(X509, (st))
+#define sk_X509_push(st, val) SKM_sk_push(X509, (st), (val))
+#define sk_X509_unshift(st, val) SKM_sk_unshift(X509, (st), (val))
+#define sk_X509_find(st, val) SKM_sk_find(X509, (st), (val))
+#define sk_X509_find_ex(st, val) SKM_sk_find_ex(X509, (st), (val))
+#define sk_X509_delete(st, i) SKM_sk_delete(X509, (st), (i))
+#define sk_X509_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509, (st), (ptr))
+#define sk_X509_insert(st, val, i) SKM_sk_insert(X509, (st), (val), (i))
+#define sk_X509_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509, (st), (cmp))
+#define sk_X509_dup(st) SKM_sk_dup(X509, st)
+#define sk_X509_pop_free(st, free_func) SKM_sk_pop_free(X509, (st), (free_func))
+#define sk_X509_shift(st) SKM_sk_shift(X509, (st))
+#define sk_X509_pop(st) SKM_sk_pop(X509, (st))
+#define sk_X509_sort(st) SKM_sk_sort(X509, (st))
+#define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st))
+
+#define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp))
+#define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD)
+#define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_value(st, i) SKM_sk_value(X509V3_EXT_METHOD, (st), (i))
+#define sk_X509V3_EXT_METHOD_set(st, i, val) SKM_sk_set(X509V3_EXT_METHOD, (st), (i), (val))
+#define sk_X509V3_EXT_METHOD_zero(st) SKM_sk_zero(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_push(st, val) SKM_sk_push(X509V3_EXT_METHOD, (st), (val))
+#define sk_X509V3_EXT_METHOD_unshift(st, val) SKM_sk_unshift(X509V3_EXT_METHOD, (st), (val))
+#define sk_X509V3_EXT_METHOD_find(st, val) SKM_sk_find(X509V3_EXT_METHOD, (st), (val))
+#define sk_X509V3_EXT_METHOD_find_ex(st, val) SKM_sk_find_ex(X509V3_EXT_METHOD, (st), (val))
+#define sk_X509V3_EXT_METHOD_delete(st, i) SKM_sk_delete(X509V3_EXT_METHOD, (st), (i))
+#define sk_X509V3_EXT_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509V3_EXT_METHOD, (st), (ptr))
+#define sk_X509V3_EXT_METHOD_insert(st, val, i) SKM_sk_insert(X509V3_EXT_METHOD, (st), (val), (i))
+#define sk_X509V3_EXT_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509V3_EXT_METHOD, (st), (cmp))
+#define sk_X509V3_EXT_METHOD_dup(st) SKM_sk_dup(X509V3_EXT_METHOD, st)
+#define sk_X509V3_EXT_METHOD_pop_free(st, free_func) SKM_sk_pop_free(X509V3_EXT_METHOD, (st), (free_func))
+#define sk_X509V3_EXT_METHOD_shift(st) SKM_sk_shift(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_pop(st) SKM_sk_pop(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st))
+
+#define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp))
+#define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR)
+#define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st))
+#define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st))
+#define sk_X509_ALGOR_value(st, i) SKM_sk_value(X509_ALGOR, (st), (i))
+#define sk_X509_ALGOR_set(st, i, val) SKM_sk_set(X509_ALGOR, (st), (i), (val))
+#define sk_X509_ALGOR_zero(st) SKM_sk_zero(X509_ALGOR, (st))
+#define sk_X509_ALGOR_push(st, val) SKM_sk_push(X509_ALGOR, (st), (val))
+#define sk_X509_ALGOR_unshift(st, val) SKM_sk_unshift(X509_ALGOR, (st), (val))
+#define sk_X509_ALGOR_find(st, val) SKM_sk_find(X509_ALGOR, (st), (val))
+#define sk_X509_ALGOR_find_ex(st, val) SKM_sk_find_ex(X509_ALGOR, (st), (val))
+#define sk_X509_ALGOR_delete(st, i) SKM_sk_delete(X509_ALGOR, (st), (i))
+#define sk_X509_ALGOR_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ALGOR, (st), (ptr))
+#define sk_X509_ALGOR_insert(st, val, i) SKM_sk_insert(X509_ALGOR, (st), (val), (i))
+#define sk_X509_ALGOR_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ALGOR, (st), (cmp))
+#define sk_X509_ALGOR_dup(st) SKM_sk_dup(X509_ALGOR, st)
+#define sk_X509_ALGOR_pop_free(st, free_func) SKM_sk_pop_free(X509_ALGOR, (st), (free_func))
+#define sk_X509_ALGOR_shift(st) SKM_sk_shift(X509_ALGOR, (st))
+#define sk_X509_ALGOR_pop(st) SKM_sk_pop(X509_ALGOR, (st))
+#define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st))
+#define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st))
+
+#define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp))
+#define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE)
+#define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_value(st, i) SKM_sk_value(X509_ATTRIBUTE, (st), (i))
+#define sk_X509_ATTRIBUTE_set(st, i, val) SKM_sk_set(X509_ATTRIBUTE, (st), (i), (val))
+#define sk_X509_ATTRIBUTE_zero(st) SKM_sk_zero(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_push(st, val) SKM_sk_push(X509_ATTRIBUTE, (st), (val))
+#define sk_X509_ATTRIBUTE_unshift(st, val) SKM_sk_unshift(X509_ATTRIBUTE, (st), (val))
+#define sk_X509_ATTRIBUTE_find(st, val) SKM_sk_find(X509_ATTRIBUTE, (st), (val))
+#define sk_X509_ATTRIBUTE_find_ex(st, val) SKM_sk_find_ex(X509_ATTRIBUTE, (st), (val))
+#define sk_X509_ATTRIBUTE_delete(st, i) SKM_sk_delete(X509_ATTRIBUTE, (st), (i))
+#define sk_X509_ATTRIBUTE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ATTRIBUTE, (st), (ptr))
+#define sk_X509_ATTRIBUTE_insert(st, val, i) SKM_sk_insert(X509_ATTRIBUTE, (st), (val), (i))
+#define sk_X509_ATTRIBUTE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ATTRIBUTE, (st), (cmp))
+#define sk_X509_ATTRIBUTE_dup(st) SKM_sk_dup(X509_ATTRIBUTE, st)
+#define sk_X509_ATTRIBUTE_pop_free(st, free_func) SKM_sk_pop_free(X509_ATTRIBUTE, (st), (free_func))
+#define sk_X509_ATTRIBUTE_shift(st) SKM_sk_shift(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_pop(st) SKM_sk_pop(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st))
+
+#define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp))
+#define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL)
+#define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st))
+#define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st))
+#define sk_X509_CRL_value(st, i) SKM_sk_value(X509_CRL, (st), (i))
+#define sk_X509_CRL_set(st, i, val) SKM_sk_set(X509_CRL, (st), (i), (val))
+#define sk_X509_CRL_zero(st) SKM_sk_zero(X509_CRL, (st))
+#define sk_X509_CRL_push(st, val) SKM_sk_push(X509_CRL, (st), (val))
+#define sk_X509_CRL_unshift(st, val) SKM_sk_unshift(X509_CRL, (st), (val))
+#define sk_X509_CRL_find(st, val) SKM_sk_find(X509_CRL, (st), (val))
+#define sk_X509_CRL_find_ex(st, val) SKM_sk_find_ex(X509_CRL, (st), (val))
+#define sk_X509_CRL_delete(st, i) SKM_sk_delete(X509_CRL, (st), (i))
+#define sk_X509_CRL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_CRL, (st), (ptr))
+#define sk_X509_CRL_insert(st, val, i) SKM_sk_insert(X509_CRL, (st), (val), (i))
+#define sk_X509_CRL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_CRL, (st), (cmp))
+#define sk_X509_CRL_dup(st) SKM_sk_dup(X509_CRL, st)
+#define sk_X509_CRL_pop_free(st, free_func) SKM_sk_pop_free(X509_CRL, (st), (free_func))
+#define sk_X509_CRL_shift(st) SKM_sk_shift(X509_CRL, (st))
+#define sk_X509_CRL_pop(st) SKM_sk_pop(X509_CRL, (st))
+#define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st))
+#define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st))
+
+#define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp))
+#define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION)
+#define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_value(st, i) SKM_sk_value(X509_EXTENSION, (st), (i))
+#define sk_X509_EXTENSION_set(st, i, val) SKM_sk_set(X509_EXTENSION, (st), (i), (val))
+#define sk_X509_EXTENSION_zero(st) SKM_sk_zero(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_push(st, val) SKM_sk_push(X509_EXTENSION, (st), (val))
+#define sk_X509_EXTENSION_unshift(st, val) SKM_sk_unshift(X509_EXTENSION, (st), (val))
+#define sk_X509_EXTENSION_find(st, val) SKM_sk_find(X509_EXTENSION, (st), (val))
+#define sk_X509_EXTENSION_find_ex(st, val) SKM_sk_find_ex(X509_EXTENSION, (st), (val))
+#define sk_X509_EXTENSION_delete(st, i) SKM_sk_delete(X509_EXTENSION, (st), (i))
+#define sk_X509_EXTENSION_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_EXTENSION, (st), (ptr))
+#define sk_X509_EXTENSION_insert(st, val, i) SKM_sk_insert(X509_EXTENSION, (st), (val), (i))
+#define sk_X509_EXTENSION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_EXTENSION, (st), (cmp))
+#define sk_X509_EXTENSION_dup(st) SKM_sk_dup(X509_EXTENSION, st)
+#define sk_X509_EXTENSION_pop_free(st, free_func) SKM_sk_pop_free(X509_EXTENSION, (st), (free_func))
+#define sk_X509_EXTENSION_shift(st) SKM_sk_shift(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_pop(st) SKM_sk_pop(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st))
+
+#define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp))
+#define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO)
+#define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st))
+#define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st))
+#define sk_X509_INFO_value(st, i) SKM_sk_value(X509_INFO, (st), (i))
+#define sk_X509_INFO_set(st, i, val) SKM_sk_set(X509_INFO, (st), (i), (val))
+#define sk_X509_INFO_zero(st) SKM_sk_zero(X509_INFO, (st))
+#define sk_X509_INFO_push(st, val) SKM_sk_push(X509_INFO, (st), (val))
+#define sk_X509_INFO_unshift(st, val) SKM_sk_unshift(X509_INFO, (st), (val))
+#define sk_X509_INFO_find(st, val) SKM_sk_find(X509_INFO, (st), (val))
+#define sk_X509_INFO_find_ex(st, val) SKM_sk_find_ex(X509_INFO, (st), (val))
+#define sk_X509_INFO_delete(st, i) SKM_sk_delete(X509_INFO, (st), (i))
+#define sk_X509_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_INFO, (st), (ptr))
+#define sk_X509_INFO_insert(st, val, i) SKM_sk_insert(X509_INFO, (st), (val), (i))
+#define sk_X509_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_INFO, (st), (cmp))
+#define sk_X509_INFO_dup(st) SKM_sk_dup(X509_INFO, st)
+#define sk_X509_INFO_pop_free(st, free_func) SKM_sk_pop_free(X509_INFO, (st), (free_func))
+#define sk_X509_INFO_shift(st) SKM_sk_shift(X509_INFO, (st))
+#define sk_X509_INFO_pop(st) SKM_sk_pop(X509_INFO, (st))
+#define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st))
+#define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st))
+
+#define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp))
+#define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP)
+#define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_value(st, i) SKM_sk_value(X509_LOOKUP, (st), (i))
+#define sk_X509_LOOKUP_set(st, i, val) SKM_sk_set(X509_LOOKUP, (st), (i), (val))
+#define sk_X509_LOOKUP_zero(st) SKM_sk_zero(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_push(st, val) SKM_sk_push(X509_LOOKUP, (st), (val))
+#define sk_X509_LOOKUP_unshift(st, val) SKM_sk_unshift(X509_LOOKUP, (st), (val))
+#define sk_X509_LOOKUP_find(st, val) SKM_sk_find(X509_LOOKUP, (st), (val))
+#define sk_X509_LOOKUP_find_ex(st, val) SKM_sk_find_ex(X509_LOOKUP, (st), (val))
+#define sk_X509_LOOKUP_delete(st, i) SKM_sk_delete(X509_LOOKUP, (st), (i))
+#define sk_X509_LOOKUP_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_LOOKUP, (st), (ptr))
+#define sk_X509_LOOKUP_insert(st, val, i) SKM_sk_insert(X509_LOOKUP, (st), (val), (i))
+#define sk_X509_LOOKUP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_LOOKUP, (st), (cmp))
+#define sk_X509_LOOKUP_dup(st) SKM_sk_dup(X509_LOOKUP, st)
+#define sk_X509_LOOKUP_pop_free(st, free_func) SKM_sk_pop_free(X509_LOOKUP, (st), (free_func))
+#define sk_X509_LOOKUP_shift(st) SKM_sk_shift(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_pop(st) SKM_sk_pop(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st))
+
+#define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp))
+#define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME)
+#define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st))
+#define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st))
+#define sk_X509_NAME_value(st, i) SKM_sk_value(X509_NAME, (st), (i))
+#define sk_X509_NAME_set(st, i, val) SKM_sk_set(X509_NAME, (st), (i), (val))
+#define sk_X509_NAME_zero(st) SKM_sk_zero(X509_NAME, (st))
+#define sk_X509_NAME_push(st, val) SKM_sk_push(X509_NAME, (st), (val))
+#define sk_X509_NAME_unshift(st, val) SKM_sk_unshift(X509_NAME, (st), (val))
+#define sk_X509_NAME_find(st, val) SKM_sk_find(X509_NAME, (st), (val))
+#define sk_X509_NAME_find_ex(st, val) SKM_sk_find_ex(X509_NAME, (st), (val))
+#define sk_X509_NAME_delete(st, i) SKM_sk_delete(X509_NAME, (st), (i))
+#define sk_X509_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME, (st), (ptr))
+#define sk_X509_NAME_insert(st, val, i) SKM_sk_insert(X509_NAME, (st), (val), (i))
+#define sk_X509_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME, (st), (cmp))
+#define sk_X509_NAME_dup(st) SKM_sk_dup(X509_NAME, st)
+#define sk_X509_NAME_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME, (st), (free_func))
+#define sk_X509_NAME_shift(st) SKM_sk_shift(X509_NAME, (st))
+#define sk_X509_NAME_pop(st) SKM_sk_pop(X509_NAME, (st))
+#define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st))
+#define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st))
+
+#define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp))
+#define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY)
+#define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_value(st, i) SKM_sk_value(X509_NAME_ENTRY, (st), (i))
+#define sk_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(X509_NAME_ENTRY, (st), (i), (val))
+#define sk_X509_NAME_ENTRY_zero(st) SKM_sk_zero(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_push(st, val) SKM_sk_push(X509_NAME_ENTRY, (st), (val))
+#define sk_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(X509_NAME_ENTRY, (st), (val))
+#define sk_X509_NAME_ENTRY_find(st, val) SKM_sk_find(X509_NAME_ENTRY, (st), (val))
+#define sk_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(X509_NAME_ENTRY, (st), (val))
+#define sk_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(X509_NAME_ENTRY, (st), (i))
+#define sk_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME_ENTRY, (st), (ptr))
+#define sk_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(X509_NAME_ENTRY, (st), (val), (i))
+#define sk_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME_ENTRY, (st), (cmp))
+#define sk_X509_NAME_ENTRY_dup(st) SKM_sk_dup(X509_NAME_ENTRY, st)
+#define sk_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME_ENTRY, (st), (free_func))
+#define sk_X509_NAME_ENTRY_shift(st) SKM_sk_shift(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_pop(st) SKM_sk_pop(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st))
+
+#define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp))
+#define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT)
+#define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st))
+#define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st))
+#define sk_X509_OBJECT_value(st, i) SKM_sk_value(X509_OBJECT, (st), (i))
+#define sk_X509_OBJECT_set(st, i, val) SKM_sk_set(X509_OBJECT, (st), (i), (val))
+#define sk_X509_OBJECT_zero(st) SKM_sk_zero(X509_OBJECT, (st))
+#define sk_X509_OBJECT_push(st, val) SKM_sk_push(X509_OBJECT, (st), (val))
+#define sk_X509_OBJECT_unshift(st, val) SKM_sk_unshift(X509_OBJECT, (st), (val))
+#define sk_X509_OBJECT_find(st, val) SKM_sk_find(X509_OBJECT, (st), (val))
+#define sk_X509_OBJECT_find_ex(st, val) SKM_sk_find_ex(X509_OBJECT, (st), (val))
+#define sk_X509_OBJECT_delete(st, i) SKM_sk_delete(X509_OBJECT, (st), (i))
+#define sk_X509_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_OBJECT, (st), (ptr))
+#define sk_X509_OBJECT_insert(st, val, i) SKM_sk_insert(X509_OBJECT, (st), (val), (i))
+#define sk_X509_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_OBJECT, (st), (cmp))
+#define sk_X509_OBJECT_dup(st) SKM_sk_dup(X509_OBJECT, st)
+#define sk_X509_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(X509_OBJECT, (st), (free_func))
+#define sk_X509_OBJECT_shift(st) SKM_sk_shift(X509_OBJECT, (st))
+#define sk_X509_OBJECT_pop(st) SKM_sk_pop(X509_OBJECT, (st))
+#define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st))
+#define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st))
+
+#define sk_X509_POLICY_DATA_new(cmp) SKM_sk_new(X509_POLICY_DATA, (cmp))
+#define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA)
+#define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_value(st, i) SKM_sk_value(X509_POLICY_DATA, (st), (i))
+#define sk_X509_POLICY_DATA_set(st, i, val) SKM_sk_set(X509_POLICY_DATA, (st), (i), (val))
+#define sk_X509_POLICY_DATA_zero(st) SKM_sk_zero(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_push(st, val) SKM_sk_push(X509_POLICY_DATA, (st), (val))
+#define sk_X509_POLICY_DATA_unshift(st, val) SKM_sk_unshift(X509_POLICY_DATA, (st), (val))
+#define sk_X509_POLICY_DATA_find(st, val) SKM_sk_find(X509_POLICY_DATA, (st), (val))
+#define sk_X509_POLICY_DATA_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_DATA, (st), (val))
+#define sk_X509_POLICY_DATA_delete(st, i) SKM_sk_delete(X509_POLICY_DATA, (st), (i))
+#define sk_X509_POLICY_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_DATA, (st), (ptr))
+#define sk_X509_POLICY_DATA_insert(st, val, i) SKM_sk_insert(X509_POLICY_DATA, (st), (val), (i))
+#define sk_X509_POLICY_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_DATA, (st), (cmp))
+#define sk_X509_POLICY_DATA_dup(st) SKM_sk_dup(X509_POLICY_DATA, st)
+#define sk_X509_POLICY_DATA_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_DATA, (st), (free_func))
+#define sk_X509_POLICY_DATA_shift(st) SKM_sk_shift(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_pop(st) SKM_sk_pop(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st))
+
+#define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp))
+#define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE)
+#define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i))
+#define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val))
+#define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val))
+#define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val))
+#define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val))
+#define sk_X509_POLICY_NODE_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_NODE, (st), (val))
+#define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i))
+#define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr))
+#define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i))
+#define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp))
+#define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st)
+#define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func))
+#define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st))
+
+#define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp))
+#define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE)
+#define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_value(st, i) SKM_sk_value(X509_PURPOSE, (st), (i))
+#define sk_X509_PURPOSE_set(st, i, val) SKM_sk_set(X509_PURPOSE, (st), (i), (val))
+#define sk_X509_PURPOSE_zero(st) SKM_sk_zero(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_push(st, val) SKM_sk_push(X509_PURPOSE, (st), (val))
+#define sk_X509_PURPOSE_unshift(st, val) SKM_sk_unshift(X509_PURPOSE, (st), (val))
+#define sk_X509_PURPOSE_find(st, val) SKM_sk_find(X509_PURPOSE, (st), (val))
+#define sk_X509_PURPOSE_find_ex(st, val) SKM_sk_find_ex(X509_PURPOSE, (st), (val))
+#define sk_X509_PURPOSE_delete(st, i) SKM_sk_delete(X509_PURPOSE, (st), (i))
+#define sk_X509_PURPOSE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_PURPOSE, (st), (ptr))
+#define sk_X509_PURPOSE_insert(st, val, i) SKM_sk_insert(X509_PURPOSE, (st), (val), (i))
+#define sk_X509_PURPOSE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_PURPOSE, (st), (cmp))
+#define sk_X509_PURPOSE_dup(st) SKM_sk_dup(X509_PURPOSE, st)
+#define sk_X509_PURPOSE_pop_free(st, free_func) SKM_sk_pop_free(X509_PURPOSE, (st), (free_func))
+#define sk_X509_PURPOSE_shift(st) SKM_sk_shift(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_pop(st) SKM_sk_pop(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st))
+
+#define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp))
+#define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED)
+#define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st))
+#define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st))
+#define sk_X509_REVOKED_value(st, i) SKM_sk_value(X509_REVOKED, (st), (i))
+#define sk_X509_REVOKED_set(st, i, val) SKM_sk_set(X509_REVOKED, (st), (i), (val))
+#define sk_X509_REVOKED_zero(st) SKM_sk_zero(X509_REVOKED, (st))
+#define sk_X509_REVOKED_push(st, val) SKM_sk_push(X509_REVOKED, (st), (val))
+#define sk_X509_REVOKED_unshift(st, val) SKM_sk_unshift(X509_REVOKED, (st), (val))
+#define sk_X509_REVOKED_find(st, val) SKM_sk_find(X509_REVOKED, (st), (val))
+#define sk_X509_REVOKED_find_ex(st, val) SKM_sk_find_ex(X509_REVOKED, (st), (val))
+#define sk_X509_REVOKED_delete(st, i) SKM_sk_delete(X509_REVOKED, (st), (i))
+#define sk_X509_REVOKED_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_REVOKED, (st), (ptr))
+#define sk_X509_REVOKED_insert(st, val, i) SKM_sk_insert(X509_REVOKED, (st), (val), (i))
+#define sk_X509_REVOKED_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_REVOKED, (st), (cmp))
+#define sk_X509_REVOKED_dup(st) SKM_sk_dup(X509_REVOKED, st)
+#define sk_X509_REVOKED_pop_free(st, free_func) SKM_sk_pop_free(X509_REVOKED, (st), (free_func))
+#define sk_X509_REVOKED_shift(st) SKM_sk_shift(X509_REVOKED, (st))
+#define sk_X509_REVOKED_pop(st) SKM_sk_pop(X509_REVOKED, (st))
+#define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st))
+#define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st))
+
+#define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp))
+#define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST)
+#define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st))
+#define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st))
+#define sk_X509_TRUST_value(st, i) SKM_sk_value(X509_TRUST, (st), (i))
+#define sk_X509_TRUST_set(st, i, val) SKM_sk_set(X509_TRUST, (st), (i), (val))
+#define sk_X509_TRUST_zero(st) SKM_sk_zero(X509_TRUST, (st))
+#define sk_X509_TRUST_push(st, val) SKM_sk_push(X509_TRUST, (st), (val))
+#define sk_X509_TRUST_unshift(st, val) SKM_sk_unshift(X509_TRUST, (st), (val))
+#define sk_X509_TRUST_find(st, val) SKM_sk_find(X509_TRUST, (st), (val))
+#define sk_X509_TRUST_find_ex(st, val) SKM_sk_find_ex(X509_TRUST, (st), (val))
+#define sk_X509_TRUST_delete(st, i) SKM_sk_delete(X509_TRUST, (st), (i))
+#define sk_X509_TRUST_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_TRUST, (st), (ptr))
+#define sk_X509_TRUST_insert(st, val, i) SKM_sk_insert(X509_TRUST, (st), (val), (i))
+#define sk_X509_TRUST_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_TRUST, (st), (cmp))
+#define sk_X509_TRUST_dup(st) SKM_sk_dup(X509_TRUST, st)
+#define sk_X509_TRUST_pop_free(st, free_func) SKM_sk_pop_free(X509_TRUST, (st), (free_func))
+#define sk_X509_TRUST_shift(st) SKM_sk_shift(X509_TRUST, (st))
+#define sk_X509_TRUST_pop(st) SKM_sk_pop(X509_TRUST, (st))
+#define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st))
+#define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st))
+
+#define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp))
+#define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM)
+#define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_value(st, i) SKM_sk_value(X509_VERIFY_PARAM, (st), (i))
+#define sk_X509_VERIFY_PARAM_set(st, i, val) SKM_sk_set(X509_VERIFY_PARAM, (st), (i), (val))
+#define sk_X509_VERIFY_PARAM_zero(st) SKM_sk_zero(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_push(st, val) SKM_sk_push(X509_VERIFY_PARAM, (st), (val))
+#define sk_X509_VERIFY_PARAM_unshift(st, val) SKM_sk_unshift(X509_VERIFY_PARAM, (st), (val))
+#define sk_X509_VERIFY_PARAM_find(st, val) SKM_sk_find(X509_VERIFY_PARAM, (st), (val))
+#define sk_X509_VERIFY_PARAM_find_ex(st, val) SKM_sk_find_ex(X509_VERIFY_PARAM, (st), (val))
+#define sk_X509_VERIFY_PARAM_delete(st, i) SKM_sk_delete(X509_VERIFY_PARAM, (st), (i))
+#define sk_X509_VERIFY_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_VERIFY_PARAM, (st), (ptr))
+#define sk_X509_VERIFY_PARAM_insert(st, val, i) SKM_sk_insert(X509_VERIFY_PARAM, (st), (val), (i))
+#define sk_X509_VERIFY_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_VERIFY_PARAM, (st), (cmp))
+#define sk_X509_VERIFY_PARAM_dup(st) SKM_sk_dup(X509_VERIFY_PARAM, st)
+#define sk_X509_VERIFY_PARAM_pop_free(st, free_func) SKM_sk_pop_free(X509_VERIFY_PARAM, (st), (free_func))
+#define sk_X509_VERIFY_PARAM_shift(st) SKM_sk_shift(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_pop(st) SKM_sk_pop(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st))
+
+#define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp))
+#define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple)
+#define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st))
+#define sk_nid_triple_num(st) SKM_sk_num(nid_triple, (st))
+#define sk_nid_triple_value(st, i) SKM_sk_value(nid_triple, (st), (i))
+#define sk_nid_triple_set(st, i, val) SKM_sk_set(nid_triple, (st), (i), (val))
+#define sk_nid_triple_zero(st) SKM_sk_zero(nid_triple, (st))
+#define sk_nid_triple_push(st, val) SKM_sk_push(nid_triple, (st), (val))
+#define sk_nid_triple_unshift(st, val) SKM_sk_unshift(nid_triple, (st), (val))
+#define sk_nid_triple_find(st, val) SKM_sk_find(nid_triple, (st), (val))
+#define sk_nid_triple_find_ex(st, val) SKM_sk_find_ex(nid_triple, (st), (val))
+#define sk_nid_triple_delete(st, i) SKM_sk_delete(nid_triple, (st), (i))
+#define sk_nid_triple_delete_ptr(st, ptr) SKM_sk_delete_ptr(nid_triple, (st), (ptr))
+#define sk_nid_triple_insert(st, val, i) SKM_sk_insert(nid_triple, (st), (val), (i))
+#define sk_nid_triple_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(nid_triple, (st), (cmp))
+#define sk_nid_triple_dup(st) SKM_sk_dup(nid_triple, st)
+#define sk_nid_triple_pop_free(st, free_func) SKM_sk_pop_free(nid_triple, (st), (free_func))
+#define sk_nid_triple_shift(st) SKM_sk_shift(nid_triple, (st))
+#define sk_nid_triple_pop(st) SKM_sk_pop(nid_triple, (st))
+#define sk_nid_triple_sort(st) SKM_sk_sort(nid_triple, (st))
+#define sk_nid_triple_is_sorted(st) SKM_sk_is_sorted(nid_triple, (st))
+
+#define sk_void_new(cmp) SKM_sk_new(void, (cmp))
+#define sk_void_new_null() SKM_sk_new_null(void)
+#define sk_void_free(st) SKM_sk_free(void, (st))
+#define sk_void_num(st) SKM_sk_num(void, (st))
+#define sk_void_value(st, i) SKM_sk_value(void, (st), (i))
+#define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val))
+#define sk_void_zero(st) SKM_sk_zero(void, (st))
+#define sk_void_push(st, val) SKM_sk_push(void, (st), (val))
+#define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val))
+#define sk_void_find(st, val) SKM_sk_find(void, (st), (val))
+#define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val))
+#define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i))
+#define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr))
+#define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i))
+#define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp))
+#define sk_void_dup(st) SKM_sk_dup(void, st)
+#define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func))
+#define sk_void_shift(st) SKM_sk_shift(void, (st))
+#define sk_void_pop(st) SKM_sk_pop(void, (st))
+#define sk_void_sort(st) SKM_sk_sort(void, (st))
+#define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st))
+
+#define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp)))
+#define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null())
+#define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_STACK_OF(OPENSSL_STRING, st), i))
+#define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st)
+#define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_STRING, free_func))
+#define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val), i)
+#define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st)
+#define sk_OPENSSL_STRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_STRING, st), i, CHECKED_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st))
+#define sk_OPENSSL_STRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i))
+#define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, ptr))
+#define sk_OPENSSL_STRING_set_cmp_func(st, cmp)  \
+	((int (*)(const char * const *,const char * const *)) \
+	sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_CMP_FUNC(char, cmp)))
+#define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st)
+#define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st))
+#define sk_OPENSSL_STRING_pop(st) (char *)sk_pop(CHECKED_STACK_OF(OPENSSL_STRING, st))
+#define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st))
+#define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st))
+
+
+#define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
+#define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null())
+#define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i))
+#define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st)
+#define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_PSTRING, free_func))
+#define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val), i)
+#define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st)
+#define sk_OPENSSL_PSTRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i, CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st))
+#define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i))
+#define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, ptr))
+#define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp)  \
+	((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \
+	sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
+#define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st)
+#define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st))
+#define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop(CHECKED_STACK_OF(OPENSSL_PSTRING, st))
+#define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st))
+#define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st))
+
+
+#define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp)))
+#define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null())
+#define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i))
+#define sk_OPENSSL_BLOCK_num(st) SKM_sk_num(OPENSSL_BLOCK, st)
+#define sk_OPENSSL_BLOCK_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_FREE_FUNC2(OPENSSL_BLOCK, free_func))
+#define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val), i)
+#define sk_OPENSSL_BLOCK_free(st) SKM_sk_free(OPENSSL_BLOCK, st)
+#define sk_OPENSSL_BLOCK_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i, CHECKED_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_zero(st) SKM_sk_zero(OPENSSL_BLOCK, (st))
+#define sk_OPENSSL_BLOCK_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_CONST_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_delete(st, i) SKM_sk_delete(OPENSSL_BLOCK, (st), (i))
+#define sk_OPENSSL_BLOCK_delete_ptr(st, ptr) (OPENSSL_BLOCK *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, ptr))
+#define sk_OPENSSL_BLOCK_set_cmp_func(st, cmp)  \
+	((int (*)(const void * const *,const void * const *)) \
+	sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_CMP_FUNC(void, cmp)))
+#define sk_OPENSSL_BLOCK_dup(st) SKM_sk_dup(OPENSSL_BLOCK, st)
+#define sk_OPENSSL_BLOCK_shift(st) SKM_sk_shift(OPENSSL_BLOCK, (st))
+#define sk_OPENSSL_BLOCK_pop(st) (void *)sk_pop(CHECKED_STACK_OF(OPENSSL_BLOCK, st))
+#define sk_OPENSSL_BLOCK_sort(st) SKM_sk_sort(OPENSSL_BLOCK, (st))
+#define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st))
+
+
+#define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ACCESS_DESCRIPTION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ACCESS_DESCRIPTION(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ACCESS_DESCRIPTION, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ACCESS_DESCRIPTION(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ACCESS_DESCRIPTION, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_ASN1_INTEGER(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ASN1_INTEGER, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ASN1_INTEGER(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ASN1_INTEGER, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ASN1_INTEGER(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ASN1_INTEGER, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ASN1_INTEGER(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ASN1_INTEGER, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_ASN1_OBJECT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ASN1_OBJECT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ASN1_OBJECT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ASN1_OBJECT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ASN1_OBJECT(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ASN1_OBJECT, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ASN1_OBJECT(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ASN1_OBJECT, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_ASN1_TYPE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ASN1_TYPE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ASN1_TYPE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ASN1_TYPE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ASN1_TYPE(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ASN1_TYPE, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ASN1_UTF8STRING, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ASN1_UTF8STRING, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ASN1_UTF8STRING(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ASN1_UTF8STRING, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ASN1_UTF8STRING(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ASN1_UTF8STRING, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(DIST_POINT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_DIST_POINT(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(DIST_POINT, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_ESS_CERT_ID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ESS_CERT_ID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ESS_CERT_ID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ESS_CERT_ID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ESS_CERT_ID(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ESS_CERT_ID, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ESS_CERT_ID(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ESS_CERT_ID, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_EVP_MD(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(EVP_MD, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_EVP_MD(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(EVP_MD, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_EVP_MD(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(EVP_MD, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_EVP_MD(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(EVP_MD, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(GENERAL_NAME, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_GENERAL_NAME(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(GENERAL_NAME, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_GENERAL_NAME(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(GENERAL_NAME, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_OCSP_ONEREQ(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(OCSP_ONEREQ, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_OCSP_ONEREQ(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(OCSP_ONEREQ, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_OCSP_ONEREQ(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(OCSP_ONEREQ, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_OCSP_ONEREQ(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(OCSP_ONEREQ, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(OCSP_SINGLERESP, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(OCSP_SINGLERESP, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_OCSP_SINGLERESP(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(OCSP_SINGLERESP, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_OCSP_SINGLERESP(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(OCSP_SINGLERESP, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(PKCS12_SAFEBAG, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(PKCS12_SAFEBAG, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_PKCS12_SAFEBAG(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(PKCS12_SAFEBAG, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_PKCS12_SAFEBAG(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(PKCS12_SAFEBAG, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_PKCS7(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(PKCS7, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_PKCS7(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(PKCS7, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_PKCS7(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(PKCS7, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_PKCS7(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(PKCS7, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(PKCS7_RECIP_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(PKCS7_RECIP_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_PKCS7_RECIP_INFO(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(PKCS7_RECIP_INFO, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_PKCS7_RECIP_INFO(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(PKCS7_RECIP_INFO, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(PKCS7_SIGNER_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(PKCS7_SIGNER_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_PKCS7_SIGNER_INFO(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(PKCS7_SIGNER_INFO, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_PKCS7_SIGNER_INFO(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(PKCS7_SIGNER_INFO, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_POLICYINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(POLICYINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_POLICYINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(POLICYINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_POLICYINFO(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(POLICYINFO, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_POLICYINFO(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(POLICYINFO, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_POLICYQUALINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(POLICYQUALINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_POLICYQUALINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(POLICYQUALINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_POLICYQUALINFO(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(POLICYQUALINFO, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_POLICYQUALINFO(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(POLICYQUALINFO, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_SXNETID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(SXNETID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_SXNETID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(SXNETID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_SXNETID(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(SXNETID, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_SXNETID(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(SXNETID, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_ALGOR(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_ALGOR, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_ALGOR(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_ALGOR, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_ALGOR(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_ALGOR, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_ALGOR(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_ALGOR, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_ATTRIBUTE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_ATTRIBUTE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_ATTRIBUTE(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_ATTRIBUTE, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_ATTRIBUTE(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_ATTRIBUTE, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_CRL(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_CRL, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_CRL(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_CRL, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_CRL(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_CRL, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_CRL(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_CRL, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_EXTENSION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_EXTENSION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_EXTENSION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_EXTENSION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_EXTENSION(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_EXTENSION, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_EXTENSION(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_EXTENSION, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_NAME_ENTRY, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_NAME_ENTRY, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_NAME_ENTRY(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_NAME_ENTRY, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_NAME_ENTRY(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_NAME_ENTRY, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_REVOKED(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_REVOKED, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_REVOKED(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_REVOKED, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_REVOKED(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_REVOKED, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_REVOKED(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_REVOKED, (buf), (len), (d2i_func), (free_func))
+
+#define PKCS12_decrypt_d2i_PKCS12_SAFEBAG(algor, d2i_func, free_func, pass, passlen, oct, seq) \
+	SKM_PKCS12_decrypt_d2i(PKCS12_SAFEBAG, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
+
+#define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \
+	SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
+
+#define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj)
+#define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst)
+#define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst)
+#define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst)
+#define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn)
+#define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg)
+#define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh)
+#define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh)
+#define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh)
+#define lh_ADDED_OBJ_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(ADDED_OBJ,lh,out)
+#define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out)
+#define lh_ADDED_OBJ_stats_bio(lh,out) \
+  LHM_lh_stats_bio(ADDED_OBJ,lh,out)
+#define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh)
+
+#define lh_APP_INFO_new() LHM_lh_new(APP_INFO,app_info)
+#define lh_APP_INFO_insert(lh,inst) LHM_lh_insert(APP_INFO,lh,inst)
+#define lh_APP_INFO_retrieve(lh,inst) LHM_lh_retrieve(APP_INFO,lh,inst)
+#define lh_APP_INFO_delete(lh,inst) LHM_lh_delete(APP_INFO,lh,inst)
+#define lh_APP_INFO_doall(lh,fn) LHM_lh_doall(APP_INFO,lh,fn)
+#define lh_APP_INFO_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(APP_INFO,lh,fn,arg_type,arg)
+#define lh_APP_INFO_error(lh) LHM_lh_error(APP_INFO,lh)
+#define lh_APP_INFO_num_items(lh) LHM_lh_num_items(APP_INFO,lh)
+#define lh_APP_INFO_down_load(lh) LHM_lh_down_load(APP_INFO,lh)
+#define lh_APP_INFO_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(APP_INFO,lh,out)
+#define lh_APP_INFO_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(APP_INFO,lh,out)
+#define lh_APP_INFO_stats_bio(lh,out) \
+  LHM_lh_stats_bio(APP_INFO,lh,out)
+#define lh_APP_INFO_free(lh) LHM_lh_free(APP_INFO,lh)
+
+#define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value)
+#define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst)
+#define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst)
+#define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst)
+#define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn)
+#define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg)
+#define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh)
+#define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh)
+#define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh)
+#define lh_CONF_VALUE_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(CONF_VALUE,lh,out)
+#define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out)
+#define lh_CONF_VALUE_stats_bio(lh,out) \
+  LHM_lh_stats_bio(CONF_VALUE,lh,out)
+#define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh)
+
+#define lh_ENGINE_PILE_new() LHM_lh_new(ENGINE_PILE,engine_pile)
+#define lh_ENGINE_PILE_insert(lh,inst) LHM_lh_insert(ENGINE_PILE,lh,inst)
+#define lh_ENGINE_PILE_retrieve(lh,inst) LHM_lh_retrieve(ENGINE_PILE,lh,inst)
+#define lh_ENGINE_PILE_delete(lh,inst) LHM_lh_delete(ENGINE_PILE,lh,inst)
+#define lh_ENGINE_PILE_doall(lh,fn) LHM_lh_doall(ENGINE_PILE,lh,fn)
+#define lh_ENGINE_PILE_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(ENGINE_PILE,lh,fn,arg_type,arg)
+#define lh_ENGINE_PILE_error(lh) LHM_lh_error(ENGINE_PILE,lh)
+#define lh_ENGINE_PILE_num_items(lh) LHM_lh_num_items(ENGINE_PILE,lh)
+#define lh_ENGINE_PILE_down_load(lh) LHM_lh_down_load(ENGINE_PILE,lh)
+#define lh_ENGINE_PILE_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(ENGINE_PILE,lh,out)
+#define lh_ENGINE_PILE_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(ENGINE_PILE,lh,out)
+#define lh_ENGINE_PILE_stats_bio(lh,out) \
+  LHM_lh_stats_bio(ENGINE_PILE,lh,out)
+#define lh_ENGINE_PILE_free(lh) LHM_lh_free(ENGINE_PILE,lh)
+
+#define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state)
+#define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst)
+#define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst)
+#define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst)
+#define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn)
+#define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg)
+#define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh)
+#define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh)
+#define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh)
+#define lh_ERR_STATE_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(ERR_STATE,lh,out)
+#define lh_ERR_STATE_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out)
+#define lh_ERR_STATE_stats_bio(lh,out) \
+  LHM_lh_stats_bio(ERR_STATE,lh,out)
+#define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh)
+
+#define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data)
+#define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst)
+#define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst)
+#define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst)
+#define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn)
+#define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg)
+#define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh)
+#define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh)
+#define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh)
+#define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out)
+#define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out)
+#define lh_ERR_STRING_DATA_stats_bio(lh,out) \
+  LHM_lh_stats_bio(ERR_STRING_DATA,lh,out)
+#define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh)
+
+#define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item)
+#define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst)
+#define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst)
+#define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst)
+#define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn)
+#define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg)
+#define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh)
+#define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh)
+#define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh)
+#define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out)
+#define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out)
+#define lh_EX_CLASS_ITEM_stats_bio(lh,out) \
+  LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out)
+#define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh)
+
+#define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function)
+#define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst)
+#define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst)
+#define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst)
+#define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn)
+#define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg)
+#define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh)
+#define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh)
+#define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh)
+#define lh_FUNCTION_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(FUNCTION,lh,out)
+#define lh_FUNCTION_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(FUNCTION,lh,out)
+#define lh_FUNCTION_stats_bio(lh,out) \
+  LHM_lh_stats_bio(FUNCTION,lh,out)
+#define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh)
+
+#define lh_MEM_new() LHM_lh_new(MEM,mem)
+#define lh_MEM_insert(lh,inst) LHM_lh_insert(MEM,lh,inst)
+#define lh_MEM_retrieve(lh,inst) LHM_lh_retrieve(MEM,lh,inst)
+#define lh_MEM_delete(lh,inst) LHM_lh_delete(MEM,lh,inst)
+#define lh_MEM_doall(lh,fn) LHM_lh_doall(MEM,lh,fn)
+#define lh_MEM_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(MEM,lh,fn,arg_type,arg)
+#define lh_MEM_error(lh) LHM_lh_error(MEM,lh)
+#define lh_MEM_num_items(lh) LHM_lh_num_items(MEM,lh)
+#define lh_MEM_down_load(lh) LHM_lh_down_load(MEM,lh)
+#define lh_MEM_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(MEM,lh,out)
+#define lh_MEM_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(MEM,lh,out)
+#define lh_MEM_stats_bio(lh,out) \
+  LHM_lh_stats_bio(MEM,lh,out)
+#define lh_MEM_free(lh) LHM_lh_free(MEM,lh)
+
+#define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name)
+#define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst)
+#define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst)
+#define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst)
+#define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn)
+#define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg)
+#define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh)
+#define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh)
+#define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh)
+#define lh_OBJ_NAME_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(OBJ_NAME,lh,out)
+#define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out)
+#define lh_OBJ_NAME_stats_bio(lh,out) \
+  LHM_lh_stats_bio(OBJ_NAME,lh,out)
+#define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh)
+
+#define lh_OPENSSL_CSTRING_new() LHM_lh_new(OPENSSL_CSTRING,openssl_cstring)
+#define lh_OPENSSL_CSTRING_insert(lh,inst) LHM_lh_insert(OPENSSL_CSTRING,lh,inst)
+#define lh_OPENSSL_CSTRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_CSTRING,lh,inst)
+#define lh_OPENSSL_CSTRING_delete(lh,inst) LHM_lh_delete(OPENSSL_CSTRING,lh,inst)
+#define lh_OPENSSL_CSTRING_doall(lh,fn) LHM_lh_doall(OPENSSL_CSTRING,lh,fn)
+#define lh_OPENSSL_CSTRING_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(OPENSSL_CSTRING,lh,fn,arg_type,arg)
+#define lh_OPENSSL_CSTRING_error(lh) LHM_lh_error(OPENSSL_CSTRING,lh)
+#define lh_OPENSSL_CSTRING_num_items(lh) LHM_lh_num_items(OPENSSL_CSTRING,lh)
+#define lh_OPENSSL_CSTRING_down_load(lh) LHM_lh_down_load(OPENSSL_CSTRING,lh)
+#define lh_OPENSSL_CSTRING_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(OPENSSL_CSTRING,lh,out)
+#define lh_OPENSSL_CSTRING_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(OPENSSL_CSTRING,lh,out)
+#define lh_OPENSSL_CSTRING_stats_bio(lh,out) \
+  LHM_lh_stats_bio(OPENSSL_CSTRING,lh,out)
+#define lh_OPENSSL_CSTRING_free(lh) LHM_lh_free(OPENSSL_CSTRING,lh)
+
+#define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string)
+#define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst)
+#define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst)
+#define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst)
+#define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn)
+#define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg)
+#define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh)
+#define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh)
+#define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh)
+#define lh_OPENSSL_STRING_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out)
+#define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out)
+#define lh_OPENSSL_STRING_stats_bio(lh,out) \
+  LHM_lh_stats_bio(OPENSSL_STRING,lh,out)
+#define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh)
+
+#define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session)
+#define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst)
+#define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst)
+#define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst)
+#define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn)
+#define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg)
+#define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh)
+#define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh)
+#define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh)
+#define lh_SSL_SESSION_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(SSL_SESSION,lh,out)
+#define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out)
+#define lh_SSL_SESSION_stats_bio(lh,out) \
+  LHM_lh_stats_bio(SSL_SESSION,lh,out)
+#define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh)
+/* End of util/mkstack.pl block, you may now edit :-) */
+
+#endif /* !defined HEADER_SAFESTACK_H */
diff --git a/openssl/crypto/stack/stack.c b/openssl/crypto/stack/stack.c
new file mode 100644
index 0000000..76cf1a1
--- /dev/null
+++ b/openssl/crypto/stack/stack.c
@@ -0,0 +1,334 @@
+/* crypto/stack/stack.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Code for stacks
+ * Author - Eric Young v 1.0
+ * 1.2 eay 12-Mar-97 -	Modified sk_find so that it _DOES_ return the
+ *			lowest index for the searched item.
+ *
+ * 1.1 eay - Take from netdb and added to SSLeay
+ *
+ * 1.0 eay - First version 29/07/92
+ */
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/stack.h>
+#include <openssl/objects.h>
+
+#undef MIN_NODES
+#define MIN_NODES	4
+
+const char STACK_version[]="Stack" OPENSSL_VERSION_PTEXT;
+
+#include <errno.h>
+
+int (*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *)))
+		(const void *, const void *)
+	{
+	int (*old)(const void *,const void *)=sk->comp;
+
+	if (sk->comp != c)
+		sk->sorted=0;
+	sk->comp=c;
+
+	return old;
+	}
+
+_STACK *sk_dup(_STACK *sk)
+	{
+	_STACK *ret;
+	char **s;
+
+	if ((ret=sk_new(sk->comp)) == NULL) goto err;
+	s=(char **)OPENSSL_realloc((char *)ret->data,
+		(unsigned int)sizeof(char *)*sk->num_alloc);
+	if (s == NULL) goto err;
+	ret->data=s;
+
+	ret->num=sk->num;
+	memcpy(ret->data,sk->data,sizeof(char *)*sk->num);
+	ret->sorted=sk->sorted;
+	ret->num_alloc=sk->num_alloc;
+	ret->comp=sk->comp;
+	return(ret);
+err:
+	if(ret)
+		sk_free(ret);
+	return(NULL);
+	}
+
+_STACK *sk_new_null(void)
+	{
+	return sk_new((int (*)(const void *, const void *))0);
+	}
+
+_STACK *sk_new(int (*c)(const void *, const void *))
+	{
+	_STACK *ret;
+	int i;
+
+	if ((ret=OPENSSL_malloc(sizeof(_STACK))) == NULL)
+		goto err;
+	if ((ret->data=OPENSSL_malloc(sizeof(char *)*MIN_NODES)) == NULL)
+		goto err;
+	for (i=0; i<MIN_NODES; i++)
+		ret->data[i]=NULL;
+	ret->comp=c;
+	ret->num_alloc=MIN_NODES;
+	ret->num=0;
+	ret->sorted=0;
+	return(ret);
+err:
+	if(ret)
+		OPENSSL_free(ret);
+	return(NULL);
+	}
+
+int sk_insert(_STACK *st, void *data, int loc)
+	{
+	char **s;
+
+	if(st == NULL) return 0;
+	if (st->num_alloc <= st->num+1)
+		{
+		s=OPENSSL_realloc((char *)st->data,
+			(unsigned int)sizeof(char *)*st->num_alloc*2);
+		if (s == NULL)
+			return(0);
+		st->data=s;
+		st->num_alloc*=2;
+		}
+	if ((loc >= (int)st->num) || (loc < 0))
+		st->data[st->num]=data;
+	else
+		{
+		int i;
+		char **f,**t;
+
+		f=st->data;
+		t=&(st->data[1]);
+		for (i=st->num; i>=loc; i--)
+			t[i]=f[i];
+			
+#ifdef undef /* no memmove on sunos :-( */
+		memmove(&(st->data[loc+1]),
+			&(st->data[loc]),
+			sizeof(char *)*(st->num-loc));
+#endif
+		st->data[loc]=data;
+		}
+	st->num++;
+	st->sorted=0;
+	return(st->num);
+	}
+
+void *sk_delete_ptr(_STACK *st, void *p)
+	{
+	int i;
+
+	for (i=0; i<st->num; i++)
+		if (st->data[i] == p)
+			return(sk_delete(st,i));
+	return(NULL);
+	}
+
+void *sk_delete(_STACK *st, int loc)
+	{
+	char *ret;
+	int i,j;
+
+	if(!st || (loc < 0) || (loc >= st->num)) return NULL;
+
+	ret=st->data[loc];
+	if (loc != st->num-1)
+		{
+		j=st->num-1;
+		for (i=loc; i<j; i++)
+			st->data[i]=st->data[i+1];
+		/* In theory memcpy is not safe for this
+		 * memcpy( &(st->data[loc]),
+		 *	&(st->data[loc+1]),
+		 *	sizeof(char *)*(st->num-loc-1));
+		 */
+		}
+	st->num--;
+	return(ret);
+	}
+
+static int internal_find(_STACK *st, void *data, int ret_val_options)
+	{
+	const void * const *r;
+	int i;
+
+	if(st == NULL) return -1;
+
+	if (st->comp == NULL)
+		{
+		for (i=0; i<st->num; i++)
+			if (st->data[i] == data)
+				return(i);
+		return(-1);
+		}
+	sk_sort(st);
+	if (data == NULL) return(-1);
+	r=OBJ_bsearch_ex_(&data,st->data,st->num,sizeof(void *),st->comp,
+			  ret_val_options);
+	if (r == NULL) return(-1);
+	return (int)((char **)r-st->data);
+	}
+
+int sk_find(_STACK *st, void *data)
+	{
+	return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH);
+	}
+int sk_find_ex(_STACK *st, void *data)
+	{
+	return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH);
+	}
+
+int sk_push(_STACK *st, void *data)
+	{
+	return(sk_insert(st,data,st->num));
+	}
+
+int sk_unshift(_STACK *st, void *data)
+	{
+	return(sk_insert(st,data,0));
+	}
+
+void *sk_shift(_STACK *st)
+	{
+	if (st == NULL) return(NULL);
+	if (st->num <= 0) return(NULL);
+	return(sk_delete(st,0));
+	}
+
+void *sk_pop(_STACK *st)
+	{
+	if (st == NULL) return(NULL);
+	if (st->num <= 0) return(NULL);
+	return(sk_delete(st,st->num-1));
+	}
+
+void sk_zero(_STACK *st)
+	{
+	if (st == NULL) return;
+	if (st->num <= 0) return;
+	memset((char *)st->data,0,sizeof(st->data)*st->num);
+	st->num=0;
+	}
+
+void sk_pop_free(_STACK *st, void (*func)(void *))
+	{
+	int i;
+
+	if (st == NULL) return;
+	for (i=0; i<st->num; i++)
+		if (st->data[i] != NULL)
+			func(st->data[i]);
+	sk_free(st);
+	}
+
+void sk_free(_STACK *st)
+	{
+	if (st == NULL) return;
+	if (st->data != NULL) OPENSSL_free(st->data);
+	OPENSSL_free(st);
+	}
+
+int sk_num(const _STACK *st)
+{
+	if(st == NULL) return -1;
+	return st->num;
+}
+
+void *sk_value(const _STACK *st, int i)
+{
+	if(!st || (i < 0) || (i >= st->num)) return NULL;
+	return st->data[i];
+}
+
+void *sk_set(_STACK *st, int i, void *value)
+{
+	if(!st || (i < 0) || (i >= st->num)) return NULL;
+	return (st->data[i] = value);
+}
+
+void sk_sort(_STACK *st)
+	{
+	if (st && !st->sorted)
+		{
+		int (*comp_func)(const void *,const void *);
+
+		/* same comment as in sk_find ... previously st->comp was declared
+		 * as a (void*,void*) callback type, but this made the population
+		 * of the callback pointer illogical - our callbacks compare
+		 * type** with type**, so we leave the casting until absolutely
+		 * necessary (ie. "now"). */
+		comp_func=(int (*)(const void *,const void *))(st->comp);
+		qsort(st->data,st->num,sizeof(char *), comp_func);
+		st->sorted=1;
+		}
+	}
+
+int sk_is_sorted(const _STACK *st)
+	{
+	if (!st)
+		return 1;
+	return st->sorted;
+	}
diff --git a/openssl/crypto/stack/stack.h b/openssl/crypto/stack/stack.h
new file mode 100644
index 0000000..ce35e55
--- /dev/null
+++ b/openssl/crypto/stack/stack.h
@@ -0,0 +1,108 @@
+/* crypto/stack/stack.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_STACK_H
+#define HEADER_STACK_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct stack_st
+	{
+	int num;
+	char **data;
+	int sorted;
+
+	int num_alloc;
+	int (*comp)(const void *, const void *);
+	} _STACK;  /* Use STACK_OF(...) instead */
+
+#define M_sk_num(sk)		((sk) ? (sk)->num:-1)
+#define M_sk_value(sk,n)	((sk) ? (sk)->data[n] : NULL)
+
+int sk_num(const _STACK *);
+void *sk_value(const _STACK *, int);
+
+void *sk_set(_STACK *, int, void *);
+
+_STACK *sk_new(int (*cmp)(const void *, const void *));
+_STACK *sk_new_null(void);
+void sk_free(_STACK *);
+void sk_pop_free(_STACK *st, void (*func)(void *));
+int sk_insert(_STACK *sk, void *data, int where);
+void *sk_delete(_STACK *st, int loc);
+void *sk_delete_ptr(_STACK *st, void *p);
+int sk_find(_STACK *st, void *data);
+int sk_find_ex(_STACK *st, void *data);
+int sk_push(_STACK *st, void *data);
+int sk_unshift(_STACK *st, void *data);
+void *sk_shift(_STACK *st);
+void *sk_pop(_STACK *st);
+void sk_zero(_STACK *st);
+int (*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *)))
+	(const void *, const void *);
+_STACK *sk_dup(_STACK *st);
+void sk_sort(_STACK *st);
+int sk_is_sorted(const _STACK *st);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/store/Makefile b/openssl/crypto/store/Makefile
new file mode 100644
index 0000000..0dcfd78
--- /dev/null
+++ b/openssl/crypto/store/Makefile
@@ -0,0 +1,112 @@
+#
+# OpenSSL/crypto/store/Makefile
+#
+
+DIR=	store
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+#TEST= storetest.c
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= str_err.c str_lib.c str_meth.c str_mem.c
+LIBOBJ= str_err.o str_lib.o str_meth.o str_mem.o
+
+SRC= $(LIBSRC)
+
+#EXHEADER= store.h str_compat.h
+EXHEADER= store.h
+HEADER=	$(EXHEADER) str_locl.h
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+str_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+str_err.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+str_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+str_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+str_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+str_err.o: ../../include/openssl/store.h ../../include/openssl/symhacks.h
+str_err.o: str_err.c
+str_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+str_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+str_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+str_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+str_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+str_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+str_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+str_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+str_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+str_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+str_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+str_lib.o: ../../include/openssl/store.h ../../include/openssl/symhacks.h
+str_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+str_lib.o: str_lib.c str_locl.h
+str_mem.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+str_mem.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+str_mem.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+str_mem.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+str_mem.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+str_mem.o: ../../include/openssl/store.h ../../include/openssl/symhacks.h
+str_mem.o: str_locl.h str_mem.c
+str_meth.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+str_meth.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+str_meth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+str_meth.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+str_meth.o: ../../include/openssl/store.h ../../include/openssl/symhacks.h
+str_meth.o: str_locl.h str_meth.c
diff --git a/openssl/crypto/store/README b/openssl/crypto/store/README
new file mode 100644
index 0000000..966168f
--- /dev/null
+++ b/openssl/crypto/store/README
@@ -0,0 +1,95 @@
+The STORE type
+==============
+
+A STORE, as defined in this code section, is really a rather simple
+thing which stores objects and per-object associations to a number
+of attributes.  What attributes are supported entirely depends on
+the particular implementation of a STORE.  It has some support for
+generation of certain objects (for example, keys and CRLs).
+
+
+Supported object types
+----------------------
+
+For now, the objects that are supported are the following:
+
+X.509 certificate
+X.509 CRL
+private key
+public key
+number
+arbitrary (application) data
+
+The intention is that a STORE should be able to store everything
+needed by an application that wants a cert/key store, as well as
+the data a CA might need to store (this includes the serial number
+counter, which explains the support for numbers).
+
+
+Supported attribute types
+-------------------------
+
+For now, the following attributes are supported:
+
+Friendly Name		- the value is a normal C string
+Key ID			- the value is a 160 bit SHA1 hash
+Issuer Key ID		- the value is a 160 bit SHA1 hash
+Subject Key ID		- the value is a 160 bit SHA1 hash
+Issuer/Serial Hash	- the value is a 160 bit SHA1 hash
+Issuer			- the value is a X509_NAME
+Serial			- the value is a BIGNUM
+Subject			- the value is a X509_NAME
+Certificate Hash	- the value is a 160 bit SHA1 hash
+Email			- the value is a normal C string
+Filename		- the value is a normal C string
+
+It is expected that these attributes should be enough to support
+the need from most, if not all, current applications.  Applications
+that need to do certificate verification would typically use Subject
+Key ID, Issuer/Serial Hash or Subject to look up issuer certificates.
+S/MIME applications would typically use Email to look up recipient
+and signer certificates.
+
+There's added support for combined sets of attributes to search for,
+with the special OR attribute.
+
+
+Supported basic functionality
+-----------------------------
+
+The functions that are supported through the STORE type are these:
+
+generate_object		- for example to generate keys and CRLs
+get_object		- to look up one object
+			  NOTE: this function is really rather
+			  redundant and probably of lesser usage
+			  than the list functions
+store_object		- store an object and the attributes
+			  associated with it
+modify_object		- modify the attributes associated with
+			  a specific object
+revoke_object		- revoke an object
+			  NOTE: this only marks an object as
+			  invalid, it doesn't remove the object
+			  from the database
+delete_object		- remove an object from the database
+list_object		- list objects associated with a given
+			  set of attributes
+			  NOTE: this is really four functions:
+			  list_start, list_next, list_end and
+			  list_endp
+update_store		- update the internal data of the store
+lock_store		- lock the store
+unlock_store		- unlock the store
+
+The list functions need some extra explanation: list_start is
+used to set up a lookup.  That's where the attributes to use in
+the search are set up.  It returns a search context.  list_next
+returns the next object searched for.  list_end closes the search.
+list_endp is used to check if we have reached the end.
+
+A few words on the store functions as well: update_store is
+typically used by a CA application to update the internal
+structure of a database.  This may for example involve automatic
+removal of expired certificates.  lock_store and unlock_store
+are used for locking a store to allow exclusive writes.
diff --git a/openssl/crypto/store/store.h b/openssl/crypto/store/store.h
new file mode 100644
index 0000000..0a28c7d
--- /dev/null
+++ b/openssl/crypto/store/store.h
@@ -0,0 +1,561 @@
+/* crypto/store/store.h -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2003.
+ */
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_STORE_H
+#define HEADER_STORE_H
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_STORE
+#error STORE is disabled.
+#endif
+
+#include <openssl/ossl_typ.h>
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct store_st STORE; */
+/* typedef struct store_method_st STORE_METHOD; */
+
+
+/* All the following functions return 0, a negative number or NULL on error.
+   When everything is fine, they return a positive value or a non-NULL
+   pointer, all depending on their purpose. */
+
+/* Creators and destructor.   */
+STORE *STORE_new_method(const STORE_METHOD *method);
+STORE *STORE_new_engine(ENGINE *engine);
+void STORE_free(STORE *ui);
+
+
+/* Give a user interface parametrised control commands.  This can be used to
+   send down an integer, a data pointer or a function pointer, as well as
+   be used to get information from a STORE. */
+int STORE_ctrl(STORE *store, int cmd, long i, void *p, void (*f)(void));
+
+/* A control to set the directory with keys and certificates.  Used by the
+   built-in directory level method. */
+#define STORE_CTRL_SET_DIRECTORY	0x0001
+/* A control to set a file to load.  Used by the built-in file level method. */
+#define STORE_CTRL_SET_FILE		0x0002
+/* A control to set a configuration file to load.  Can be used by any method
+   that wishes to load a configuration file. */
+#define STORE_CTRL_SET_CONF_FILE	0x0003
+/* A control to set a the section of the loaded configuration file.  Can be
+   used by any method that wishes to load a configuration file. */
+#define STORE_CTRL_SET_CONF_SECTION	0x0004
+
+
+/* Some methods may use extra data */
+#define STORE_set_app_data(s,arg)	STORE_set_ex_data(s,0,arg)
+#define STORE_get_app_data(s)		STORE_get_ex_data(s,0)
+int STORE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int STORE_set_ex_data(STORE *r,int idx,void *arg);
+void *STORE_get_ex_data(STORE *r, int idx);
+
+/* Use specific methods instead of the built-in one */
+const STORE_METHOD *STORE_get_method(STORE *store);
+const STORE_METHOD *STORE_set_method(STORE *store, const STORE_METHOD *meth);
+
+/* The standard OpenSSL methods. */
+/* This is the in-memory method.  It does everything except revoking and updating,
+   and is of course volatile.  It's used by other methods that have an in-memory
+   cache. */
+const STORE_METHOD *STORE_Memory(void);
+#if 0 /* Not yet implemented */
+/* This is the directory store.  It does everything except revoking and updating,
+   and uses STORE_Memory() to cache things in memory. */
+const STORE_METHOD *STORE_Directory(void);
+/* This is the file store.  It does everything except revoking and updating,
+   and uses STORE_Memory() to cache things in memory.  Certificates are added
+   to it with the store operation, and it will only get cached certificates. */
+const STORE_METHOD *STORE_File(void);
+#endif
+
+/* Store functions take a type code for the type of data they should store
+   or fetch */
+typedef enum STORE_object_types
+	{
+	STORE_OBJECT_TYPE_X509_CERTIFICATE=	0x01, /* X509 * */
+	STORE_OBJECT_TYPE_X509_CRL=		0x02, /* X509_CRL * */
+	STORE_OBJECT_TYPE_PRIVATE_KEY=		0x03, /* EVP_PKEY * */
+	STORE_OBJECT_TYPE_PUBLIC_KEY=		0x04, /* EVP_PKEY * */
+	STORE_OBJECT_TYPE_NUMBER=		0x05, /* BIGNUM * */
+	STORE_OBJECT_TYPE_ARBITRARY=		0x06, /* BUF_MEM * */
+	STORE_OBJECT_TYPE_NUM=			0x06  /* The amount of known
+							 object types */
+	} STORE_OBJECT_TYPES;
+/* List of text strings corresponding to the object types. */
+extern const char * const STORE_object_type_string[STORE_OBJECT_TYPE_NUM+1];
+
+/* Some store functions take a parameter list.  Those parameters come with
+   one of the following codes. The comments following the codes below indicate
+   what type the value should be a pointer to. */
+typedef enum STORE_params
+	{
+	STORE_PARAM_EVP_TYPE=			0x01, /* int */
+	STORE_PARAM_BITS=			0x02, /* size_t */
+	STORE_PARAM_KEY_PARAMETERS=		0x03, /* ??? */
+	STORE_PARAM_KEY_NO_PARAMETERS=		0x04, /* N/A */
+	STORE_PARAM_AUTH_PASSPHRASE=		0x05, /* char * */
+	STORE_PARAM_AUTH_KRB5_TICKET=		0x06, /* void * */
+	STORE_PARAM_TYPE_NUM=			0x06  /* The amount of known
+							 parameter types */
+	} STORE_PARAM_TYPES;
+/* Parameter value sizes.  -1 means unknown, anything else is the required size. */
+extern const int STORE_param_sizes[STORE_PARAM_TYPE_NUM+1];
+
+/* Store functions take attribute lists.  Those attributes come with codes.
+   The comments following the codes below indicate what type the value should
+   be a pointer to. */
+typedef enum STORE_attribs
+	{
+	STORE_ATTR_END=				0x00,
+	STORE_ATTR_FRIENDLYNAME=		0x01, /* C string */
+	STORE_ATTR_KEYID=			0x02, /* 160 bit string (SHA1) */
+	STORE_ATTR_ISSUERKEYID=			0x03, /* 160 bit string (SHA1) */
+	STORE_ATTR_SUBJECTKEYID=		0x04, /* 160 bit string (SHA1) */
+	STORE_ATTR_ISSUERSERIALHASH=		0x05, /* 160 bit string (SHA1) */
+	STORE_ATTR_ISSUER=			0x06, /* X509_NAME * */
+	STORE_ATTR_SERIAL=			0x07, /* BIGNUM * */
+	STORE_ATTR_SUBJECT=			0x08, /* X509_NAME * */
+	STORE_ATTR_CERTHASH=			0x09, /* 160 bit string (SHA1) */
+	STORE_ATTR_EMAIL=			0x0a, /* C string */
+	STORE_ATTR_FILENAME=			0x0b, /* C string */
+	STORE_ATTR_TYPE_NUM=			0x0b, /* The amount of known
+							 attribute types */
+	STORE_ATTR_OR=				0xff  /* This is a special
+							 separator, which
+							 expresses the OR
+							 operation.  */
+	} STORE_ATTR_TYPES;
+/* Attribute value sizes.  -1 means unknown, anything else is the required size. */
+extern const int STORE_attr_sizes[STORE_ATTR_TYPE_NUM+1];
+
+typedef enum STORE_certificate_status
+	{
+	STORE_X509_VALID=			0x00,
+	STORE_X509_EXPIRED=			0x01,
+	STORE_X509_SUSPENDED=			0x02,
+	STORE_X509_REVOKED=			0x03
+	} STORE_CERTIFICATE_STATUS;
+
+/* Engine store functions will return a structure that contains all the necessary
+ * information, including revokation status for certificates.  This is really not
+ * needed for application authors, as the ENGINE framework functions will extract
+ * the OpenSSL-specific information when at all possible.  However, for engine
+ * authors, it's crucial to know this structure.  */
+typedef struct STORE_OBJECT_st
+	{
+	STORE_OBJECT_TYPES type;
+	union
+		{
+		struct
+			{
+			STORE_CERTIFICATE_STATUS status;
+			X509 *certificate;
+			} x509;
+		X509_CRL *crl;
+		EVP_PKEY *key;
+		BIGNUM *number;
+		BUF_MEM *arbitrary;
+		} data;
+	} STORE_OBJECT;
+DECLARE_STACK_OF(STORE_OBJECT)
+STORE_OBJECT *STORE_OBJECT_new(void);
+void STORE_OBJECT_free(STORE_OBJECT *data);
+
+
+
+/* The following functions handle the storage. They return 0, a negative number
+   or NULL on error, anything else on success. */
+X509 *STORE_get_certificate(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_store_certificate(STORE *e, X509 *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_modify_certificate(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+int STORE_revoke_certificate(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_delete_certificate(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+void *STORE_list_certificate_start(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+X509 *STORE_list_certificate_next(STORE *e, void *handle);
+int STORE_list_certificate_end(STORE *e, void *handle);
+int STORE_list_certificate_endp(STORE *e, void *handle);
+EVP_PKEY *STORE_generate_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+EVP_PKEY *STORE_get_private_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_store_private_key(STORE *e, EVP_PKEY *data,
+	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+int STORE_modify_private_key(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+int STORE_revoke_private_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_delete_private_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+void *STORE_list_private_key_start(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+EVP_PKEY *STORE_list_private_key_next(STORE *e, void *handle);
+int STORE_list_private_key_end(STORE *e, void *handle);
+int STORE_list_private_key_endp(STORE *e, void *handle);
+EVP_PKEY *STORE_get_public_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_store_public_key(STORE *e, EVP_PKEY *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_modify_public_key(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+int STORE_revoke_public_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_delete_public_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+void *STORE_list_public_key_start(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+EVP_PKEY *STORE_list_public_key_next(STORE *e, void *handle);
+int STORE_list_public_key_end(STORE *e, void *handle);
+int STORE_list_public_key_endp(STORE *e, void *handle);
+X509_CRL *STORE_generate_crl(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+X509_CRL *STORE_get_crl(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_store_crl(STORE *e, X509_CRL *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_modify_crl(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+int STORE_delete_crl(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+void *STORE_list_crl_start(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+X509_CRL *STORE_list_crl_next(STORE *e, void *handle);
+int STORE_list_crl_end(STORE *e, void *handle);
+int STORE_list_crl_endp(STORE *e, void *handle);
+int STORE_store_number(STORE *e, BIGNUM *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_modify_number(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+BIGNUM *STORE_get_number(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_delete_number(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_store_arbitrary(STORE *e, BUF_MEM *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_modify_arbitrary(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+BUF_MEM *STORE_get_arbitrary(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_delete_arbitrary(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+
+
+/* Create and manipulate methods */
+STORE_METHOD *STORE_create_method(char *name);
+void STORE_destroy_method(STORE_METHOD *store_method);
+
+/* These callback types are use for store handlers */
+typedef int (*STORE_INITIALISE_FUNC_PTR)(STORE *);
+typedef void (*STORE_CLEANUP_FUNC_PTR)(STORE *);
+typedef STORE_OBJECT *(*STORE_GENERATE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef STORE_OBJECT *(*STORE_GET_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef void *(*STORE_START_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef STORE_OBJECT *(*STORE_NEXT_OBJECT_FUNC_PTR)(STORE *, void *handle);
+typedef int (*STORE_END_OBJECT_FUNC_PTR)(STORE *, void *handle);
+typedef int (*STORE_HANDLE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef int (*STORE_STORE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, STORE_OBJECT *data, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef int (*STORE_MODIFY_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+typedef int (*STORE_GENERIC_FUNC_PTR)(STORE *, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef int (*STORE_CTRL_FUNC_PTR)(STORE *, int cmd, long l, void *p, void (*f)(void));
+
+int STORE_method_set_initialise_function(STORE_METHOD *sm, STORE_INITIALISE_FUNC_PTR init_f);
+int STORE_method_set_cleanup_function(STORE_METHOD *sm, STORE_CLEANUP_FUNC_PTR clean_f);
+int STORE_method_set_generate_function(STORE_METHOD *sm, STORE_GENERATE_OBJECT_FUNC_PTR generate_f);
+int STORE_method_set_get_function(STORE_METHOD *sm, STORE_GET_OBJECT_FUNC_PTR get_f);
+int STORE_method_set_store_function(STORE_METHOD *sm, STORE_STORE_OBJECT_FUNC_PTR store_f);
+int STORE_method_set_modify_function(STORE_METHOD *sm, STORE_MODIFY_OBJECT_FUNC_PTR store_f);
+int STORE_method_set_revoke_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR revoke_f);
+int STORE_method_set_delete_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR delete_f);
+int STORE_method_set_list_start_function(STORE_METHOD *sm, STORE_START_OBJECT_FUNC_PTR list_start_f);
+int STORE_method_set_list_next_function(STORE_METHOD *sm, STORE_NEXT_OBJECT_FUNC_PTR list_next_f);
+int STORE_method_set_list_end_function(STORE_METHOD *sm, STORE_END_OBJECT_FUNC_PTR list_end_f);
+int STORE_method_set_update_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR);
+int STORE_method_set_lock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR);
+int STORE_method_set_unlock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR);
+int STORE_method_set_ctrl_function(STORE_METHOD *sm, STORE_CTRL_FUNC_PTR ctrl_f);
+
+STORE_INITIALISE_FUNC_PTR STORE_method_get_initialise_function(STORE_METHOD *sm);
+STORE_CLEANUP_FUNC_PTR STORE_method_get_cleanup_function(STORE_METHOD *sm);
+STORE_GENERATE_OBJECT_FUNC_PTR STORE_method_get_generate_function(STORE_METHOD *sm);
+STORE_GET_OBJECT_FUNC_PTR STORE_method_get_get_function(STORE_METHOD *sm);
+STORE_STORE_OBJECT_FUNC_PTR STORE_method_get_store_function(STORE_METHOD *sm);
+STORE_MODIFY_OBJECT_FUNC_PTR STORE_method_get_modify_function(STORE_METHOD *sm);
+STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_revoke_function(STORE_METHOD *sm);
+STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_delete_function(STORE_METHOD *sm);
+STORE_START_OBJECT_FUNC_PTR STORE_method_get_list_start_function(STORE_METHOD *sm);
+STORE_NEXT_OBJECT_FUNC_PTR STORE_method_get_list_next_function(STORE_METHOD *sm);
+STORE_END_OBJECT_FUNC_PTR STORE_method_get_list_end_function(STORE_METHOD *sm);
+STORE_GENERIC_FUNC_PTR STORE_method_get_update_store_function(STORE_METHOD *sm);
+STORE_GENERIC_FUNC_PTR STORE_method_get_lock_store_function(STORE_METHOD *sm);
+STORE_GENERIC_FUNC_PTR STORE_method_get_unlock_store_function(STORE_METHOD *sm);
+STORE_CTRL_FUNC_PTR STORE_method_get_ctrl_function(STORE_METHOD *sm);
+
+/* Method helper structures and functions. */
+
+/* This structure is the result of parsing through the information in a list
+   of OPENSSL_ITEMs.  It stores all the necessary information in a structured
+   way.*/
+typedef struct STORE_attr_info_st STORE_ATTR_INFO;
+
+/* Parse a list of OPENSSL_ITEMs and return a pointer to a STORE_ATTR_INFO.
+   Note that we do this in the list form, since the list of OPENSSL_ITEMs can
+   come in blocks separated with STORE_ATTR_OR.  Note that the value returned
+   by STORE_parse_attrs_next() must be freed with STORE_ATTR_INFO_free(). */
+void *STORE_parse_attrs_start(OPENSSL_ITEM *attributes);
+STORE_ATTR_INFO *STORE_parse_attrs_next(void *handle);
+int STORE_parse_attrs_end(void *handle);
+int STORE_parse_attrs_endp(void *handle);
+
+/* Creator and destructor */
+STORE_ATTR_INFO *STORE_ATTR_INFO_new(void);
+int STORE_ATTR_INFO_free(STORE_ATTR_INFO *attrs);
+
+/* Manipulators */
+char *STORE_ATTR_INFO_get0_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code);
+unsigned char *STORE_ATTR_INFO_get0_sha1str(STORE_ATTR_INFO *attrs,
+	STORE_ATTR_TYPES code);
+X509_NAME *STORE_ATTR_INFO_get0_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code);
+BIGNUM *STORE_ATTR_INFO_get0_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code);
+int STORE_ATTR_INFO_set_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	char *cstr, size_t cstr_size);
+int STORE_ATTR_INFO_set_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	unsigned char *sha1str, size_t sha1str_size);
+int STORE_ATTR_INFO_set_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	X509_NAME *dn);
+int STORE_ATTR_INFO_set_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	BIGNUM *number);
+int STORE_ATTR_INFO_modify_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	char *cstr, size_t cstr_size);
+int STORE_ATTR_INFO_modify_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	unsigned char *sha1str, size_t sha1str_size);
+int STORE_ATTR_INFO_modify_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	X509_NAME *dn);
+int STORE_ATTR_INFO_modify_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	BIGNUM *number);
+
+/* Compare on basis of a bit pattern formed by the STORE_ATTR_TYPES values
+   in each contained attribute. */
+int STORE_ATTR_INFO_compare(const STORE_ATTR_INFO * const *a,
+			    const STORE_ATTR_INFO * const *b);
+/* Check if the set of attributes in a is within the range of attributes
+   set in b. */
+int STORE_ATTR_INFO_in_range(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
+/* Check if the set of attributes in a are also set in b. */
+int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
+/* Same as STORE_ATTR_INFO_in(), but also checks the attribute values. */
+int STORE_ATTR_INFO_in_ex(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_STORE_strings(void);
+
+/* Error codes for the STORE functions. */
+
+/* Function codes. */
+#define STORE_F_MEM_DELETE				 134
+#define STORE_F_MEM_GENERATE				 135
+#define STORE_F_MEM_LIST_END				 168
+#define STORE_F_MEM_LIST_NEXT				 136
+#define STORE_F_MEM_LIST_START				 137
+#define STORE_F_MEM_MODIFY				 169
+#define STORE_F_MEM_STORE				 138
+#define STORE_F_STORE_ATTR_INFO_GET0_CSTR		 139
+#define STORE_F_STORE_ATTR_INFO_GET0_DN			 140
+#define STORE_F_STORE_ATTR_INFO_GET0_NUMBER		 141
+#define STORE_F_STORE_ATTR_INFO_GET0_SHA1STR		 142
+#define STORE_F_STORE_ATTR_INFO_MODIFY_CSTR		 143
+#define STORE_F_STORE_ATTR_INFO_MODIFY_DN		 144
+#define STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER		 145
+#define STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR		 146
+#define STORE_F_STORE_ATTR_INFO_SET_CSTR		 147
+#define STORE_F_STORE_ATTR_INFO_SET_DN			 148
+#define STORE_F_STORE_ATTR_INFO_SET_NUMBER		 149
+#define STORE_F_STORE_ATTR_INFO_SET_SHA1STR		 150
+#define STORE_F_STORE_CERTIFICATE			 170
+#define STORE_F_STORE_CTRL				 161
+#define STORE_F_STORE_DELETE_ARBITRARY			 158
+#define STORE_F_STORE_DELETE_CERTIFICATE		 102
+#define STORE_F_STORE_DELETE_CRL			 103
+#define STORE_F_STORE_DELETE_NUMBER			 104
+#define STORE_F_STORE_DELETE_PRIVATE_KEY		 105
+#define STORE_F_STORE_DELETE_PUBLIC_KEY			 106
+#define STORE_F_STORE_GENERATE_CRL			 107
+#define STORE_F_STORE_GENERATE_KEY			 108
+#define STORE_F_STORE_GET_ARBITRARY			 159
+#define STORE_F_STORE_GET_CERTIFICATE			 109
+#define STORE_F_STORE_GET_CRL				 110
+#define STORE_F_STORE_GET_NUMBER			 111
+#define STORE_F_STORE_GET_PRIVATE_KEY			 112
+#define STORE_F_STORE_GET_PUBLIC_KEY			 113
+#define STORE_F_STORE_LIST_CERTIFICATE_END		 114
+#define STORE_F_STORE_LIST_CERTIFICATE_ENDP		 153
+#define STORE_F_STORE_LIST_CERTIFICATE_NEXT		 115
+#define STORE_F_STORE_LIST_CERTIFICATE_START		 116
+#define STORE_F_STORE_LIST_CRL_END			 117
+#define STORE_F_STORE_LIST_CRL_ENDP			 154
+#define STORE_F_STORE_LIST_CRL_NEXT			 118
+#define STORE_F_STORE_LIST_CRL_START			 119
+#define STORE_F_STORE_LIST_PRIVATE_KEY_END		 120
+#define STORE_F_STORE_LIST_PRIVATE_KEY_ENDP		 155
+#define STORE_F_STORE_LIST_PRIVATE_KEY_NEXT		 121
+#define STORE_F_STORE_LIST_PRIVATE_KEY_START		 122
+#define STORE_F_STORE_LIST_PUBLIC_KEY_END		 123
+#define STORE_F_STORE_LIST_PUBLIC_KEY_ENDP		 156
+#define STORE_F_STORE_LIST_PUBLIC_KEY_NEXT		 124
+#define STORE_F_STORE_LIST_PUBLIC_KEY_START		 125
+#define STORE_F_STORE_MODIFY_ARBITRARY			 162
+#define STORE_F_STORE_MODIFY_CERTIFICATE		 163
+#define STORE_F_STORE_MODIFY_CRL			 164
+#define STORE_F_STORE_MODIFY_NUMBER			 165
+#define STORE_F_STORE_MODIFY_PRIVATE_KEY		 166
+#define STORE_F_STORE_MODIFY_PUBLIC_KEY			 167
+#define STORE_F_STORE_NEW_ENGINE			 133
+#define STORE_F_STORE_NEW_METHOD			 132
+#define STORE_F_STORE_PARSE_ATTRS_END			 151
+#define STORE_F_STORE_PARSE_ATTRS_ENDP			 172
+#define STORE_F_STORE_PARSE_ATTRS_NEXT			 152
+#define STORE_F_STORE_PARSE_ATTRS_START			 171
+#define STORE_F_STORE_REVOKE_CERTIFICATE		 129
+#define STORE_F_STORE_REVOKE_PRIVATE_KEY		 130
+#define STORE_F_STORE_REVOKE_PUBLIC_KEY			 131
+#define STORE_F_STORE_STORE_ARBITRARY			 157
+#define STORE_F_STORE_STORE_CERTIFICATE			 100
+#define STORE_F_STORE_STORE_CRL				 101
+#define STORE_F_STORE_STORE_NUMBER			 126
+#define STORE_F_STORE_STORE_PRIVATE_KEY			 127
+#define STORE_F_STORE_STORE_PUBLIC_KEY			 128
+
+/* Reason codes. */
+#define STORE_R_ALREADY_HAS_A_VALUE			 127
+#define STORE_R_FAILED_DELETING_ARBITRARY		 132
+#define STORE_R_FAILED_DELETING_CERTIFICATE		 100
+#define STORE_R_FAILED_DELETING_KEY			 101
+#define STORE_R_FAILED_DELETING_NUMBER			 102
+#define STORE_R_FAILED_GENERATING_CRL			 103
+#define STORE_R_FAILED_GENERATING_KEY			 104
+#define STORE_R_FAILED_GETTING_ARBITRARY		 133
+#define STORE_R_FAILED_GETTING_CERTIFICATE		 105
+#define STORE_R_FAILED_GETTING_KEY			 106
+#define STORE_R_FAILED_GETTING_NUMBER			 107
+#define STORE_R_FAILED_LISTING_CERTIFICATES		 108
+#define STORE_R_FAILED_LISTING_KEYS			 109
+#define STORE_R_FAILED_MODIFYING_ARBITRARY		 138
+#define STORE_R_FAILED_MODIFYING_CERTIFICATE		 139
+#define STORE_R_FAILED_MODIFYING_CRL			 140
+#define STORE_R_FAILED_MODIFYING_NUMBER			 141
+#define STORE_R_FAILED_MODIFYING_PRIVATE_KEY		 142
+#define STORE_R_FAILED_MODIFYING_PUBLIC_KEY		 143
+#define STORE_R_FAILED_REVOKING_CERTIFICATE		 110
+#define STORE_R_FAILED_REVOKING_KEY			 111
+#define STORE_R_FAILED_STORING_ARBITRARY		 134
+#define STORE_R_FAILED_STORING_CERTIFICATE		 112
+#define STORE_R_FAILED_STORING_KEY			 113
+#define STORE_R_FAILED_STORING_NUMBER			 114
+#define STORE_R_NOT_IMPLEMENTED				 128
+#define STORE_R_NO_CONTROL_FUNCTION			 144
+#define STORE_R_NO_DELETE_ARBITRARY_FUNCTION		 135
+#define STORE_R_NO_DELETE_NUMBER_FUNCTION		 115
+#define STORE_R_NO_DELETE_OBJECT_FUNCTION		 116
+#define STORE_R_NO_GENERATE_CRL_FUNCTION		 117
+#define STORE_R_NO_GENERATE_OBJECT_FUNCTION		 118
+#define STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION	 136
+#define STORE_R_NO_GET_OBJECT_FUNCTION			 119
+#define STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION		 120
+#define STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION		 131
+#define STORE_R_NO_LIST_OBJECT_END_FUNCTION		 121
+#define STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION		 122
+#define STORE_R_NO_LIST_OBJECT_START_FUNCTION		 123
+#define STORE_R_NO_MODIFY_OBJECT_FUNCTION		 145
+#define STORE_R_NO_REVOKE_OBJECT_FUNCTION		 124
+#define STORE_R_NO_STORE				 129
+#define STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION	 137
+#define STORE_R_NO_STORE_OBJECT_FUNCTION		 125
+#define STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION		 126
+#define STORE_R_NO_VALUE				 130
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/store/str_err.c b/openssl/crypto/store/str_err.c
new file mode 100644
index 0000000..924edf0
--- /dev/null
+++ b/openssl/crypto/store/str_err.c
@@ -0,0 +1,211 @@
+/* crypto/store/str_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/store.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_STORE,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_STORE,0,reason)
+
+static ERR_STRING_DATA STORE_str_functs[]=
+	{
+{ERR_FUNC(STORE_F_MEM_DELETE),	"MEM_DELETE"},
+{ERR_FUNC(STORE_F_MEM_GENERATE),	"MEM_GENERATE"},
+{ERR_FUNC(STORE_F_MEM_LIST_END),	"MEM_LIST_END"},
+{ERR_FUNC(STORE_F_MEM_LIST_NEXT),	"MEM_LIST_NEXT"},
+{ERR_FUNC(STORE_F_MEM_LIST_START),	"MEM_LIST_START"},
+{ERR_FUNC(STORE_F_MEM_MODIFY),	"MEM_MODIFY"},
+{ERR_FUNC(STORE_F_MEM_STORE),	"MEM_STORE"},
+{ERR_FUNC(STORE_F_STORE_ATTR_INFO_GET0_CSTR),	"STORE_ATTR_INFO_get0_cstr"},
+{ERR_FUNC(STORE_F_STORE_ATTR_INFO_GET0_DN),	"STORE_ATTR_INFO_get0_dn"},
+{ERR_FUNC(STORE_F_STORE_ATTR_INFO_GET0_NUMBER),	"STORE_ATTR_INFO_get0_number"},
+{ERR_FUNC(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR),	"STORE_ATTR_INFO_get0_sha1str"},
+{ERR_FUNC(STORE_F_STORE_ATTR_INFO_MODIFY_CSTR),	"STORE_ATTR_INFO_modify_cstr"},
+{ERR_FUNC(STORE_F_STORE_ATTR_INFO_MODIFY_DN),	"STORE_ATTR_INFO_modify_dn"},
+{ERR_FUNC(STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER),	"STORE_ATTR_INFO_modify_number"},
+{ERR_FUNC(STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR),	"STORE_ATTR_INFO_modify_sha1str"},
+{ERR_FUNC(STORE_F_STORE_ATTR_INFO_SET_CSTR),	"STORE_ATTR_INFO_set_cstr"},
+{ERR_FUNC(STORE_F_STORE_ATTR_INFO_SET_DN),	"STORE_ATTR_INFO_set_dn"},
+{ERR_FUNC(STORE_F_STORE_ATTR_INFO_SET_NUMBER),	"STORE_ATTR_INFO_set_number"},
+{ERR_FUNC(STORE_F_STORE_ATTR_INFO_SET_SHA1STR),	"STORE_ATTR_INFO_set_sha1str"},
+{ERR_FUNC(STORE_F_STORE_CERTIFICATE),	"STORE_CERTIFICATE"},
+{ERR_FUNC(STORE_F_STORE_CTRL),	"STORE_ctrl"},
+{ERR_FUNC(STORE_F_STORE_DELETE_ARBITRARY),	"STORE_delete_arbitrary"},
+{ERR_FUNC(STORE_F_STORE_DELETE_CERTIFICATE),	"STORE_delete_certificate"},
+{ERR_FUNC(STORE_F_STORE_DELETE_CRL),	"STORE_delete_crl"},
+{ERR_FUNC(STORE_F_STORE_DELETE_NUMBER),	"STORE_delete_number"},
+{ERR_FUNC(STORE_F_STORE_DELETE_PRIVATE_KEY),	"STORE_delete_private_key"},
+{ERR_FUNC(STORE_F_STORE_DELETE_PUBLIC_KEY),	"STORE_delete_public_key"},
+{ERR_FUNC(STORE_F_STORE_GENERATE_CRL),	"STORE_generate_crl"},
+{ERR_FUNC(STORE_F_STORE_GENERATE_KEY),	"STORE_generate_key"},
+{ERR_FUNC(STORE_F_STORE_GET_ARBITRARY),	"STORE_get_arbitrary"},
+{ERR_FUNC(STORE_F_STORE_GET_CERTIFICATE),	"STORE_get_certificate"},
+{ERR_FUNC(STORE_F_STORE_GET_CRL),	"STORE_get_crl"},
+{ERR_FUNC(STORE_F_STORE_GET_NUMBER),	"STORE_get_number"},
+{ERR_FUNC(STORE_F_STORE_GET_PRIVATE_KEY),	"STORE_get_private_key"},
+{ERR_FUNC(STORE_F_STORE_GET_PUBLIC_KEY),	"STORE_get_public_key"},
+{ERR_FUNC(STORE_F_STORE_LIST_CERTIFICATE_END),	"STORE_list_certificate_end"},
+{ERR_FUNC(STORE_F_STORE_LIST_CERTIFICATE_ENDP),	"STORE_list_certificate_endp"},
+{ERR_FUNC(STORE_F_STORE_LIST_CERTIFICATE_NEXT),	"STORE_list_certificate_next"},
+{ERR_FUNC(STORE_F_STORE_LIST_CERTIFICATE_START),	"STORE_list_certificate_start"},
+{ERR_FUNC(STORE_F_STORE_LIST_CRL_END),	"STORE_list_crl_end"},
+{ERR_FUNC(STORE_F_STORE_LIST_CRL_ENDP),	"STORE_list_crl_endp"},
+{ERR_FUNC(STORE_F_STORE_LIST_CRL_NEXT),	"STORE_list_crl_next"},
+{ERR_FUNC(STORE_F_STORE_LIST_CRL_START),	"STORE_list_crl_start"},
+{ERR_FUNC(STORE_F_STORE_LIST_PRIVATE_KEY_END),	"STORE_list_private_key_end"},
+{ERR_FUNC(STORE_F_STORE_LIST_PRIVATE_KEY_ENDP),	"STORE_list_private_key_endp"},
+{ERR_FUNC(STORE_F_STORE_LIST_PRIVATE_KEY_NEXT),	"STORE_list_private_key_next"},
+{ERR_FUNC(STORE_F_STORE_LIST_PRIVATE_KEY_START),	"STORE_list_private_key_start"},
+{ERR_FUNC(STORE_F_STORE_LIST_PUBLIC_KEY_END),	"STORE_list_public_key_end"},
+{ERR_FUNC(STORE_F_STORE_LIST_PUBLIC_KEY_ENDP),	"STORE_list_public_key_endp"},
+{ERR_FUNC(STORE_F_STORE_LIST_PUBLIC_KEY_NEXT),	"STORE_list_public_key_next"},
+{ERR_FUNC(STORE_F_STORE_LIST_PUBLIC_KEY_START),	"STORE_list_public_key_start"},
+{ERR_FUNC(STORE_F_STORE_MODIFY_ARBITRARY),	"STORE_modify_arbitrary"},
+{ERR_FUNC(STORE_F_STORE_MODIFY_CERTIFICATE),	"STORE_modify_certificate"},
+{ERR_FUNC(STORE_F_STORE_MODIFY_CRL),	"STORE_modify_crl"},
+{ERR_FUNC(STORE_F_STORE_MODIFY_NUMBER),	"STORE_modify_number"},
+{ERR_FUNC(STORE_F_STORE_MODIFY_PRIVATE_KEY),	"STORE_modify_private_key"},
+{ERR_FUNC(STORE_F_STORE_MODIFY_PUBLIC_KEY),	"STORE_modify_public_key"},
+{ERR_FUNC(STORE_F_STORE_NEW_ENGINE),	"STORE_new_engine"},
+{ERR_FUNC(STORE_F_STORE_NEW_METHOD),	"STORE_new_method"},
+{ERR_FUNC(STORE_F_STORE_PARSE_ATTRS_END),	"STORE_parse_attrs_end"},
+{ERR_FUNC(STORE_F_STORE_PARSE_ATTRS_ENDP),	"STORE_parse_attrs_endp"},
+{ERR_FUNC(STORE_F_STORE_PARSE_ATTRS_NEXT),	"STORE_parse_attrs_next"},
+{ERR_FUNC(STORE_F_STORE_PARSE_ATTRS_START),	"STORE_parse_attrs_start"},
+{ERR_FUNC(STORE_F_STORE_REVOKE_CERTIFICATE),	"STORE_revoke_certificate"},
+{ERR_FUNC(STORE_F_STORE_REVOKE_PRIVATE_KEY),	"STORE_revoke_private_key"},
+{ERR_FUNC(STORE_F_STORE_REVOKE_PUBLIC_KEY),	"STORE_revoke_public_key"},
+{ERR_FUNC(STORE_F_STORE_STORE_ARBITRARY),	"STORE_store_arbitrary"},
+{ERR_FUNC(STORE_F_STORE_STORE_CERTIFICATE),	"STORE_store_certificate"},
+{ERR_FUNC(STORE_F_STORE_STORE_CRL),	"STORE_store_crl"},
+{ERR_FUNC(STORE_F_STORE_STORE_NUMBER),	"STORE_store_number"},
+{ERR_FUNC(STORE_F_STORE_STORE_PRIVATE_KEY),	"STORE_store_private_key"},
+{ERR_FUNC(STORE_F_STORE_STORE_PUBLIC_KEY),	"STORE_store_public_key"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA STORE_str_reasons[]=
+	{
+{ERR_REASON(STORE_R_ALREADY_HAS_A_VALUE) ,"already has a value"},
+{ERR_REASON(STORE_R_FAILED_DELETING_ARBITRARY),"failed deleting arbitrary"},
+{ERR_REASON(STORE_R_FAILED_DELETING_CERTIFICATE),"failed deleting certificate"},
+{ERR_REASON(STORE_R_FAILED_DELETING_KEY) ,"failed deleting key"},
+{ERR_REASON(STORE_R_FAILED_DELETING_NUMBER),"failed deleting number"},
+{ERR_REASON(STORE_R_FAILED_GENERATING_CRL),"failed generating crl"},
+{ERR_REASON(STORE_R_FAILED_GENERATING_KEY),"failed generating key"},
+{ERR_REASON(STORE_R_FAILED_GETTING_ARBITRARY),"failed getting arbitrary"},
+{ERR_REASON(STORE_R_FAILED_GETTING_CERTIFICATE),"failed getting certificate"},
+{ERR_REASON(STORE_R_FAILED_GETTING_KEY)  ,"failed getting key"},
+{ERR_REASON(STORE_R_FAILED_GETTING_NUMBER),"failed getting number"},
+{ERR_REASON(STORE_R_FAILED_LISTING_CERTIFICATES),"failed listing certificates"},
+{ERR_REASON(STORE_R_FAILED_LISTING_KEYS) ,"failed listing keys"},
+{ERR_REASON(STORE_R_FAILED_MODIFYING_ARBITRARY),"failed modifying arbitrary"},
+{ERR_REASON(STORE_R_FAILED_MODIFYING_CERTIFICATE),"failed modifying certificate"},
+{ERR_REASON(STORE_R_FAILED_MODIFYING_CRL),"failed modifying crl"},
+{ERR_REASON(STORE_R_FAILED_MODIFYING_NUMBER),"failed modifying number"},
+{ERR_REASON(STORE_R_FAILED_MODIFYING_PRIVATE_KEY),"failed modifying private key"},
+{ERR_REASON(STORE_R_FAILED_MODIFYING_PUBLIC_KEY),"failed modifying public key"},
+{ERR_REASON(STORE_R_FAILED_REVOKING_CERTIFICATE),"failed revoking certificate"},
+{ERR_REASON(STORE_R_FAILED_REVOKING_KEY) ,"failed revoking key"},
+{ERR_REASON(STORE_R_FAILED_STORING_ARBITRARY),"failed storing arbitrary"},
+{ERR_REASON(STORE_R_FAILED_STORING_CERTIFICATE),"failed storing certificate"},
+{ERR_REASON(STORE_R_FAILED_STORING_KEY)  ,"failed storing key"},
+{ERR_REASON(STORE_R_FAILED_STORING_NUMBER),"failed storing number"},
+{ERR_REASON(STORE_R_NOT_IMPLEMENTED)     ,"not implemented"},
+{ERR_REASON(STORE_R_NO_CONTROL_FUNCTION) ,"no control function"},
+{ERR_REASON(STORE_R_NO_DELETE_ARBITRARY_FUNCTION),"no delete arbitrary function"},
+{ERR_REASON(STORE_R_NO_DELETE_NUMBER_FUNCTION),"no delete number function"},
+{ERR_REASON(STORE_R_NO_DELETE_OBJECT_FUNCTION),"no delete object function"},
+{ERR_REASON(STORE_R_NO_GENERATE_CRL_FUNCTION),"no generate crl function"},
+{ERR_REASON(STORE_R_NO_GENERATE_OBJECT_FUNCTION),"no generate object function"},
+{ERR_REASON(STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION),"no get object arbitrary function"},
+{ERR_REASON(STORE_R_NO_GET_OBJECT_FUNCTION),"no get object function"},
+{ERR_REASON(STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION),"no get object number function"},
+{ERR_REASON(STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION),"no list object endp function"},
+{ERR_REASON(STORE_R_NO_LIST_OBJECT_END_FUNCTION),"no list object end function"},
+{ERR_REASON(STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION),"no list object next function"},
+{ERR_REASON(STORE_R_NO_LIST_OBJECT_START_FUNCTION),"no list object start function"},
+{ERR_REASON(STORE_R_NO_MODIFY_OBJECT_FUNCTION),"no modify object function"},
+{ERR_REASON(STORE_R_NO_REVOKE_OBJECT_FUNCTION),"no revoke object function"},
+{ERR_REASON(STORE_R_NO_STORE)            ,"no store"},
+{ERR_REASON(STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION),"no store object arbitrary function"},
+{ERR_REASON(STORE_R_NO_STORE_OBJECT_FUNCTION),"no store object function"},
+{ERR_REASON(STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION),"no store object number function"},
+{ERR_REASON(STORE_R_NO_VALUE)            ,"no value"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_STORE_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(STORE_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,STORE_str_functs);
+		ERR_load_strings(0,STORE_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/store/str_lib.c b/openssl/crypto/store/str_lib.c
new file mode 100644
index 0000000..f1dbcbd
--- /dev/null
+++ b/openssl/crypto/store/str_lib.c
@@ -0,0 +1,1828 @@
+/* crypto/store/str_lib.c -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2003.
+ */
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/sha.h>
+#include <openssl/x509.h>
+#include "str_locl.h"
+
+const char * const STORE_object_type_string[STORE_OBJECT_TYPE_NUM+1] =
+	{
+	0,
+	"X.509 Certificate",
+	"X.509 CRL",
+	"Private Key",
+	"Public Key",
+	"Number",
+	"Arbitrary Data"
+	};
+
+const int STORE_param_sizes[STORE_PARAM_TYPE_NUM+1] =
+	{
+	0,
+	sizeof(int),		/* EVP_TYPE */
+	sizeof(size_t),		/* BITS */
+	-1,			/* KEY_PARAMETERS */
+	0			/* KEY_NO_PARAMETERS */
+	};	
+
+const int STORE_attr_sizes[STORE_ATTR_TYPE_NUM+1] =
+	{
+	0,
+	-1,			/* FRIENDLYNAME:	C string */
+	SHA_DIGEST_LENGTH,	/* KEYID:		SHA1 digest, 160 bits */
+	SHA_DIGEST_LENGTH,	/* ISSUERKEYID:		SHA1 digest, 160 bits */
+	SHA_DIGEST_LENGTH,	/* SUBJECTKEYID:	SHA1 digest, 160 bits */
+	SHA_DIGEST_LENGTH,	/* ISSUERSERIALHASH:	SHA1 digest, 160 bits */
+	sizeof(X509_NAME *),	/* ISSUER:		X509_NAME * */
+	sizeof(BIGNUM *),	/* SERIAL:		BIGNUM * */
+	sizeof(X509_NAME *),	/* SUBJECT:		X509_NAME * */
+	SHA_DIGEST_LENGTH,	/* CERTHASH:		SHA1 digest, 160 bits */
+	-1,			/* EMAIL:		C string */
+	-1,			/* FILENAME:		C string */
+	};	
+
+STORE *STORE_new_method(const STORE_METHOD *method)
+	{
+	STORE *ret;
+
+	if (method == NULL)
+		{
+		STOREerr(STORE_F_STORE_NEW_METHOD,ERR_R_PASSED_NULL_PARAMETER);
+		return NULL;
+		}
+
+	ret=(STORE *)OPENSSL_malloc(sizeof(STORE));
+	if (ret == NULL)
+		{
+		STOREerr(STORE_F_STORE_NEW_METHOD,ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+
+	ret->meth=method;
+
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_STORE, ret, &ret->ex_data);
+	if (ret->meth->init && !ret->meth->init(ret))
+		{
+		STORE_free(ret);
+		ret = NULL;
+		}
+	return ret;
+	}
+
+STORE *STORE_new_engine(ENGINE *engine)
+	{
+	STORE *ret = NULL;
+	ENGINE *e = engine;
+	const STORE_METHOD *meth = 0;
+
+#ifdef OPENSSL_NO_ENGINE
+	e = NULL;
+#else
+	if (engine)
+		{
+		if (!ENGINE_init(engine))
+			{
+			STOREerr(STORE_F_STORE_NEW_ENGINE, ERR_R_ENGINE_LIB);
+			return NULL;
+			}
+		e = engine;
+		}
+	else
+		{
+		STOREerr(STORE_F_STORE_NEW_ENGINE,ERR_R_PASSED_NULL_PARAMETER);
+		return NULL;
+		}
+	if(e)
+		{
+		meth = ENGINE_get_STORE(e);
+		if(!meth)
+			{
+			STOREerr(STORE_F_STORE_NEW_ENGINE,
+				ERR_R_ENGINE_LIB);
+			ENGINE_finish(e);
+			return NULL;
+			}
+		}
+#endif
+
+	ret = STORE_new_method(meth);
+	if (ret == NULL)
+		{
+		STOREerr(STORE_F_STORE_NEW_ENGINE,ERR_R_STORE_LIB);
+		return NULL;
+		}
+
+	ret->engine = e;
+
+	return(ret);
+	}
+
+void STORE_free(STORE *store)
+	{
+	if (store == NULL)
+		return;
+	if (store->meth->clean)
+		store->meth->clean(store);
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_STORE, store, &store->ex_data);
+	OPENSSL_free(store);
+	}
+
+int STORE_ctrl(STORE *store, int cmd, long i, void *p, void (*f)(void))
+	{
+	if (store == NULL)
+		{
+		STOREerr(STORE_F_STORE_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	if (store->meth->ctrl)
+		return store->meth->ctrl(store, cmd, i, p, f);
+	STOREerr(STORE_F_STORE_CTRL,STORE_R_NO_CONTROL_FUNCTION);
+	return 0;
+	}
+
+
+int STORE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+        {
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_STORE, argl, argp,
+				new_func, dup_func, free_func);
+        }
+
+int STORE_set_ex_data(STORE *r, int idx, void *arg)
+	{
+	return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
+	}
+
+void *STORE_get_ex_data(STORE *r, int idx)
+	{
+	return(CRYPTO_get_ex_data(&r->ex_data,idx));
+	}
+
+const STORE_METHOD *STORE_get_method(STORE *store)
+	{
+	return store->meth;
+	}
+
+const STORE_METHOD *STORE_set_method(STORE *store, const STORE_METHOD *meth)
+	{
+	store->meth=meth;
+	return store->meth;
+	}
+
+
+/* API helpers */
+
+#define check_store(s,fncode,fnname,fnerrcode) \
+	do \
+		{ \
+		if ((s) == NULL || (s)->meth == NULL) \
+			{ \
+			STOREerr((fncode), ERR_R_PASSED_NULL_PARAMETER); \
+			return 0; \
+			} \
+		if ((s)->meth->fnname == NULL) \
+			{ \
+			STOREerr((fncode), (fnerrcode)); \
+			return 0; \
+			} \
+		} \
+	while(0)
+
+/* API functions */
+
+X509 *STORE_get_certificate(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	STORE_OBJECT *object;
+	X509 *x;
+
+	check_store(s,STORE_F_STORE_GET_CERTIFICATE,
+		get_object,STORE_R_NO_GET_OBJECT_FUNCTION);
+
+	object = s->meth->get_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE,
+		attributes, parameters);
+	if (!object || !object->data.x509.certificate)
+		{
+		STOREerr(STORE_F_STORE_GET_CERTIFICATE,
+			STORE_R_FAILED_GETTING_CERTIFICATE);
+		return 0;
+		}
+	CRYPTO_add(&object->data.x509.certificate->references,1,CRYPTO_LOCK_X509);
+#ifdef REF_PRINT
+	REF_PRINT("X509",data);
+#endif
+	x = object->data.x509.certificate;
+	STORE_OBJECT_free(object);
+	return x;
+	}
+
+int STORE_store_certificate(STORE *s, X509 *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	STORE_OBJECT *object;
+	int i;
+
+	check_store(s,STORE_F_STORE_CERTIFICATE,
+		store_object,STORE_R_NO_STORE_OBJECT_FUNCTION);
+
+	object = STORE_OBJECT_new();
+	if (!object)
+		{
+		STOREerr(STORE_F_STORE_STORE_CERTIFICATE,
+			ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	
+	CRYPTO_add(&data->references,1,CRYPTO_LOCK_X509);
+#ifdef REF_PRINT
+	REF_PRINT("X509",data);
+#endif
+	object->data.x509.certificate = data;
+
+	i = s->meth->store_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE,
+		object, attributes, parameters);
+
+	STORE_OBJECT_free(object);
+
+	if (!i)
+		{
+		STOREerr(STORE_F_STORE_STORE_CERTIFICATE,
+			STORE_R_FAILED_STORING_CERTIFICATE);
+		return 0;
+		}
+	return 1;
+	}
+
+int STORE_modify_certificate(STORE *s, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
+	{
+	check_store(s,STORE_F_STORE_MODIFY_CERTIFICATE,
+		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
+
+	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE,
+		    search_attributes, add_attributes, modify_attributes,
+		    delete_attributes, parameters))
+		{
+		STOREerr(STORE_F_STORE_MODIFY_CERTIFICATE,
+			STORE_R_FAILED_MODIFYING_CERTIFICATE);
+		return 0;
+		}
+	return 1;
+	}
+
+int STORE_revoke_certificate(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	check_store(s,STORE_F_STORE_REVOKE_CERTIFICATE,
+		revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION);
+
+	if (!s->meth->revoke_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE,
+		    attributes, parameters))
+		{
+		STOREerr(STORE_F_STORE_REVOKE_CERTIFICATE,
+			STORE_R_FAILED_REVOKING_CERTIFICATE);
+		return 0;
+		}
+	return 1;
+	}
+
+int STORE_delete_certificate(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	check_store(s,STORE_F_STORE_DELETE_CERTIFICATE,
+		delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION);
+
+	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE,
+		    attributes, parameters))
+		{
+		STOREerr(STORE_F_STORE_DELETE_CERTIFICATE,
+			STORE_R_FAILED_DELETING_CERTIFICATE);
+		return 0;
+		}
+	return 1;
+	}
+
+void *STORE_list_certificate_start(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	void *handle;
+
+	check_store(s,STORE_F_STORE_LIST_CERTIFICATE_START,
+		list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION);
+
+	handle = s->meth->list_object_start(s,
+		STORE_OBJECT_TYPE_X509_CERTIFICATE, attributes, parameters);
+	if (!handle)
+		{
+		STOREerr(STORE_F_STORE_LIST_CERTIFICATE_START,
+			STORE_R_FAILED_LISTING_CERTIFICATES);
+		return 0;
+		}
+	return handle;
+	}
+
+X509 *STORE_list_certificate_next(STORE *s, void *handle)
+	{
+	STORE_OBJECT *object;
+	X509 *x;
+
+	check_store(s,STORE_F_STORE_LIST_CERTIFICATE_NEXT,
+		list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION);
+
+	object = s->meth->list_object_next(s, handle);
+	if (!object || !object->data.x509.certificate)
+		{
+		STOREerr(STORE_F_STORE_LIST_CERTIFICATE_NEXT,
+			STORE_R_FAILED_LISTING_CERTIFICATES);
+		return 0;
+		}
+	CRYPTO_add(&object->data.x509.certificate->references,1,CRYPTO_LOCK_X509);
+#ifdef REF_PRINT
+	REF_PRINT("X509",data);
+#endif
+	x = object->data.x509.certificate;
+	STORE_OBJECT_free(object);
+	return x;
+	}
+
+int STORE_list_certificate_end(STORE *s, void *handle)
+	{
+	check_store(s,STORE_F_STORE_LIST_CERTIFICATE_END,
+		list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION);
+
+	if (!s->meth->list_object_end(s, handle))
+		{
+		STOREerr(STORE_F_STORE_LIST_CERTIFICATE_END,
+			STORE_R_FAILED_LISTING_CERTIFICATES);
+		return 0;
+		}
+	return 1;
+	}
+
+int STORE_list_certificate_endp(STORE *s, void *handle)
+	{
+	check_store(s,STORE_F_STORE_LIST_CERTIFICATE_ENDP,
+		list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION);
+
+	if (!s->meth->list_object_endp(s, handle))
+		{
+		STOREerr(STORE_F_STORE_LIST_CERTIFICATE_ENDP,
+			STORE_R_FAILED_LISTING_CERTIFICATES);
+		return 0;
+		}
+	return 1;
+	}
+
+EVP_PKEY *STORE_generate_key(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	STORE_OBJECT *object;
+	EVP_PKEY *pkey;
+
+	check_store(s,STORE_F_STORE_GENERATE_KEY,
+		generate_object,STORE_R_NO_GENERATE_OBJECT_FUNCTION);
+
+	object = s->meth->generate_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
+		attributes, parameters);
+	if (!object || !object->data.key)
+		{
+		STOREerr(STORE_F_STORE_GENERATE_KEY,
+			STORE_R_FAILED_GENERATING_KEY);
+		return 0;
+		}
+	CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
+#ifdef REF_PRINT
+	REF_PRINT("EVP_PKEY",data);
+#endif
+	pkey = object->data.key;
+	STORE_OBJECT_free(object);
+	return pkey;
+	}
+
+EVP_PKEY *STORE_get_private_key(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	STORE_OBJECT *object;
+	EVP_PKEY *pkey;
+
+	check_store(s,STORE_F_STORE_GET_PRIVATE_KEY,
+		get_object,STORE_R_NO_GET_OBJECT_FUNCTION);
+
+	object = s->meth->get_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
+		attributes, parameters);
+	if (!object || !object->data.key || !object->data.key)
+		{
+		STOREerr(STORE_F_STORE_GET_PRIVATE_KEY,
+			STORE_R_FAILED_GETTING_KEY);
+		return 0;
+		}
+	CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
+#ifdef REF_PRINT
+	REF_PRINT("EVP_PKEY",data);
+#endif
+	pkey = object->data.key;
+	STORE_OBJECT_free(object);
+	return pkey;
+	}
+
+int STORE_store_private_key(STORE *s, EVP_PKEY *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	STORE_OBJECT *object;
+	int i;
+
+	check_store(s,STORE_F_STORE_STORE_PRIVATE_KEY,
+		store_object,STORE_R_NO_STORE_OBJECT_FUNCTION);
+
+	object = STORE_OBJECT_new();
+	if (!object)
+		{
+		STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY,
+			ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	object->data.key = EVP_PKEY_new();
+	if (!object->data.key)
+		{
+		STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY,
+			ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	
+	CRYPTO_add(&data->references,1,CRYPTO_LOCK_EVP_PKEY);
+#ifdef REF_PRINT
+	REF_PRINT("EVP_PKEY",data);
+#endif
+	object->data.key = data;
+
+	i = s->meth->store_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, object,
+		attributes, parameters);
+
+	STORE_OBJECT_free(object);
+
+	if (!i)
+		{
+		STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY,
+			STORE_R_FAILED_STORING_KEY);
+		return 0;
+		}
+	return i;
+	}
+
+int STORE_modify_private_key(STORE *s, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
+	{
+	check_store(s,STORE_F_STORE_MODIFY_PRIVATE_KEY,
+		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
+
+	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
+		    search_attributes, add_attributes, modify_attributes,
+		    delete_attributes, parameters))
+		{
+		STOREerr(STORE_F_STORE_MODIFY_PRIVATE_KEY,
+			STORE_R_FAILED_MODIFYING_PRIVATE_KEY);
+		return 0;
+		}
+	return 1;
+	}
+
+int STORE_revoke_private_key(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	int i;
+
+	check_store(s,STORE_F_STORE_REVOKE_PRIVATE_KEY,
+		revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION);
+
+	i = s->meth->revoke_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
+		attributes, parameters);
+
+	if (!i)
+		{
+		STOREerr(STORE_F_STORE_REVOKE_PRIVATE_KEY,
+			STORE_R_FAILED_REVOKING_KEY);
+		return 0;
+		}
+	return i;
+	}
+
+int STORE_delete_private_key(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	check_store(s,STORE_F_STORE_DELETE_PRIVATE_KEY,
+		delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION);
+	
+	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
+		    attributes, parameters))
+		{
+		STOREerr(STORE_F_STORE_DELETE_PRIVATE_KEY,
+			STORE_R_FAILED_DELETING_KEY);
+		return 0;
+		}
+	return 1;
+	}
+
+void *STORE_list_private_key_start(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	void *handle;
+
+	check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_START,
+		list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION);
+
+	handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
+		attributes, parameters);
+	if (!handle)
+		{
+		STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_START,
+			STORE_R_FAILED_LISTING_KEYS);
+		return 0;
+		}
+	return handle;
+	}
+
+EVP_PKEY *STORE_list_private_key_next(STORE *s, void *handle)
+	{
+	STORE_OBJECT *object;
+	EVP_PKEY *pkey;
+
+	check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_NEXT,
+		list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION);
+
+	object = s->meth->list_object_next(s, handle);
+	if (!object || !object->data.key || !object->data.key)
+		{
+		STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_NEXT,
+			STORE_R_FAILED_LISTING_KEYS);
+		return 0;
+		}
+	CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
+#ifdef REF_PRINT
+	REF_PRINT("EVP_PKEY",data);
+#endif
+	pkey = object->data.key;
+	STORE_OBJECT_free(object);
+	return pkey;
+	}
+
+int STORE_list_private_key_end(STORE *s, void *handle)
+	{
+	check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_END,
+		list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION);
+
+	if (!s->meth->list_object_end(s, handle))
+		{
+		STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_END,
+			STORE_R_FAILED_LISTING_KEYS);
+		return 0;
+		}
+	return 1;
+	}
+
+int STORE_list_private_key_endp(STORE *s, void *handle)
+	{
+	check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_ENDP,
+		list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION);
+
+	if (!s->meth->list_object_endp(s, handle))
+		{
+		STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_ENDP,
+			STORE_R_FAILED_LISTING_KEYS);
+		return 0;
+		}
+	return 1;
+	}
+
+EVP_PKEY *STORE_get_public_key(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	STORE_OBJECT *object;
+	EVP_PKEY *pkey;
+
+	check_store(s,STORE_F_STORE_GET_PUBLIC_KEY,
+		get_object,STORE_R_NO_GET_OBJECT_FUNCTION);
+
+	object = s->meth->get_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY,
+		attributes, parameters);
+	if (!object || !object->data.key || !object->data.key)
+		{
+		STOREerr(STORE_F_STORE_GET_PUBLIC_KEY,
+			STORE_R_FAILED_GETTING_KEY);
+		return 0;
+		}
+	CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
+#ifdef REF_PRINT
+	REF_PRINT("EVP_PKEY",data);
+#endif
+	pkey = object->data.key;
+	STORE_OBJECT_free(object);
+	return pkey;
+	}
+
+int STORE_store_public_key(STORE *s, EVP_PKEY *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	STORE_OBJECT *object;
+	int i;
+
+	check_store(s,STORE_F_STORE_STORE_PUBLIC_KEY,
+		store_object,STORE_R_NO_STORE_OBJECT_FUNCTION);
+
+	object = STORE_OBJECT_new();
+	if (!object)
+		{
+		STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY,
+			ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	object->data.key = EVP_PKEY_new();
+	if (!object->data.key)
+		{
+		STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY,
+			ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	
+	CRYPTO_add(&data->references,1,CRYPTO_LOCK_EVP_PKEY);
+#ifdef REF_PRINT
+	REF_PRINT("EVP_PKEY",data);
+#endif
+	object->data.key = data;
+
+	i = s->meth->store_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, object,
+		attributes, parameters);
+
+	STORE_OBJECT_free(object);
+
+	if (!i)
+		{
+		STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY,
+			STORE_R_FAILED_STORING_KEY);
+		return 0;
+		}
+	return i;
+	}
+
+int STORE_modify_public_key(STORE *s, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
+	{
+	check_store(s,STORE_F_STORE_MODIFY_PUBLIC_KEY,
+		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
+
+	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY,
+		    search_attributes, add_attributes, modify_attributes,
+		    delete_attributes, parameters))
+		{
+		STOREerr(STORE_F_STORE_MODIFY_PUBLIC_KEY,
+			STORE_R_FAILED_MODIFYING_PUBLIC_KEY);
+		return 0;
+		}
+	return 1;
+	}
+
+int STORE_revoke_public_key(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	int i;
+
+	check_store(s,STORE_F_STORE_REVOKE_PUBLIC_KEY,
+		revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION);
+
+	i = s->meth->revoke_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY,
+		attributes, parameters);
+
+	if (!i)
+		{
+		STOREerr(STORE_F_STORE_REVOKE_PUBLIC_KEY,
+			STORE_R_FAILED_REVOKING_KEY);
+		return 0;
+		}
+	return i;
+	}
+
+int STORE_delete_public_key(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	check_store(s,STORE_F_STORE_DELETE_PUBLIC_KEY,
+		delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION);
+	
+	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY,
+		    attributes, parameters))
+		{
+		STOREerr(STORE_F_STORE_DELETE_PUBLIC_KEY,
+			STORE_R_FAILED_DELETING_KEY);
+		return 0;
+		}
+	return 1;
+	}
+
+void *STORE_list_public_key_start(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	void *handle;
+
+	check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_START,
+		list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION);
+
+	handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_PUBLIC_KEY,
+		attributes, parameters);
+	if (!handle)
+		{
+		STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_START,
+			STORE_R_FAILED_LISTING_KEYS);
+		return 0;
+		}
+	return handle;
+	}
+
+EVP_PKEY *STORE_list_public_key_next(STORE *s, void *handle)
+	{
+	STORE_OBJECT *object;
+	EVP_PKEY *pkey;
+
+	check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_NEXT,
+		list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION);
+
+	object = s->meth->list_object_next(s, handle);
+	if (!object || !object->data.key || !object->data.key)
+		{
+		STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_NEXT,
+			STORE_R_FAILED_LISTING_KEYS);
+		return 0;
+		}
+	CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
+#ifdef REF_PRINT
+	REF_PRINT("EVP_PKEY",data);
+#endif
+	pkey = object->data.key;
+	STORE_OBJECT_free(object);
+	return pkey;
+	}
+
+int STORE_list_public_key_end(STORE *s, void *handle)
+	{
+	check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_END,
+		list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION);
+
+	if (!s->meth->list_object_end(s, handle))
+		{
+		STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_END,
+			STORE_R_FAILED_LISTING_KEYS);
+		return 0;
+		}
+	return 1;
+	}
+
+int STORE_list_public_key_endp(STORE *s, void *handle)
+	{
+	check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_ENDP,
+		list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION);
+
+	if (!s->meth->list_object_endp(s, handle))
+		{
+		STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_ENDP,
+			STORE_R_FAILED_LISTING_KEYS);
+		return 0;
+		}
+	return 1;
+	}
+
+X509_CRL *STORE_generate_crl(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	STORE_OBJECT *object;
+	X509_CRL *crl;
+
+	check_store(s,STORE_F_STORE_GENERATE_CRL,
+		generate_object,STORE_R_NO_GENERATE_CRL_FUNCTION);
+
+	object = s->meth->generate_object(s, STORE_OBJECT_TYPE_X509_CRL,
+		attributes, parameters);
+	if (!object || !object->data.crl)
+		{
+		STOREerr(STORE_F_STORE_GENERATE_CRL,
+			STORE_R_FAILED_GENERATING_CRL);
+		return 0;
+		}
+	CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
+#ifdef REF_PRINT
+	REF_PRINT("X509_CRL",data);
+#endif
+	crl = object->data.crl;
+	STORE_OBJECT_free(object);
+	return crl;
+	}
+
+X509_CRL *STORE_get_crl(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	STORE_OBJECT *object;
+	X509_CRL *crl;
+
+	check_store(s,STORE_F_STORE_GET_CRL,
+		get_object,STORE_R_NO_GET_OBJECT_FUNCTION);
+
+	object = s->meth->get_object(s, STORE_OBJECT_TYPE_X509_CRL,
+		attributes, parameters);
+	if (!object || !object->data.crl)
+		{
+		STOREerr(STORE_F_STORE_GET_CRL,
+			STORE_R_FAILED_GETTING_KEY);
+		return 0;
+		}
+	CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
+#ifdef REF_PRINT
+	REF_PRINT("X509_CRL",data);
+#endif
+	crl = object->data.crl;
+	STORE_OBJECT_free(object);
+	return crl;
+	}
+
+int STORE_store_crl(STORE *s, X509_CRL *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	STORE_OBJECT *object;
+	int i;
+
+	check_store(s,STORE_F_STORE_STORE_CRL,
+		store_object,STORE_R_NO_STORE_OBJECT_FUNCTION);
+
+	object = STORE_OBJECT_new();
+	if (!object)
+		{
+		STOREerr(STORE_F_STORE_STORE_CRL,
+			ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	
+	CRYPTO_add(&data->references,1,CRYPTO_LOCK_X509_CRL);
+#ifdef REF_PRINT
+	REF_PRINT("X509_CRL",data);
+#endif
+	object->data.crl = data;
+
+	i = s->meth->store_object(s, STORE_OBJECT_TYPE_X509_CRL, object,
+		attributes, parameters);
+
+	STORE_OBJECT_free(object);
+
+	if (!i)
+		{
+		STOREerr(STORE_F_STORE_STORE_CRL,
+			STORE_R_FAILED_STORING_KEY);
+		return 0;
+		}
+	return i;
+	}
+
+int STORE_modify_crl(STORE *s, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
+	{
+	check_store(s,STORE_F_STORE_MODIFY_CRL,
+		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
+
+	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_X509_CRL,
+		    search_attributes, add_attributes, modify_attributes,
+		    delete_attributes, parameters))
+		{
+		STOREerr(STORE_F_STORE_MODIFY_CRL,
+			STORE_R_FAILED_MODIFYING_CRL);
+		return 0;
+		}
+	return 1;
+	}
+
+int STORE_delete_crl(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	check_store(s,STORE_F_STORE_DELETE_CRL,
+		delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION);
+	
+	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_X509_CRL,
+		    attributes, parameters))
+		{
+		STOREerr(STORE_F_STORE_DELETE_CRL,
+			STORE_R_FAILED_DELETING_KEY);
+		return 0;
+		}
+	return 1;
+	}
+
+void *STORE_list_crl_start(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	void *handle;
+
+	check_store(s,STORE_F_STORE_LIST_CRL_START,
+		list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION);
+
+	handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_X509_CRL,
+		attributes, parameters);
+	if (!handle)
+		{
+		STOREerr(STORE_F_STORE_LIST_CRL_START,
+			STORE_R_FAILED_LISTING_KEYS);
+		return 0;
+		}
+	return handle;
+	}
+
+X509_CRL *STORE_list_crl_next(STORE *s, void *handle)
+	{
+	STORE_OBJECT *object;
+	X509_CRL *crl;
+
+	check_store(s,STORE_F_STORE_LIST_CRL_NEXT,
+		list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION);
+
+	object = s->meth->list_object_next(s, handle);
+	if (!object || !object->data.crl)
+		{
+		STOREerr(STORE_F_STORE_LIST_CRL_NEXT,
+			STORE_R_FAILED_LISTING_KEYS);
+		return 0;
+		}
+	CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
+#ifdef REF_PRINT
+	REF_PRINT("X509_CRL",data);
+#endif
+	crl = object->data.crl;
+	STORE_OBJECT_free(object);
+	return crl;
+	}
+
+int STORE_list_crl_end(STORE *s, void *handle)
+	{
+	check_store(s,STORE_F_STORE_LIST_CRL_END,
+		list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION);
+
+	if (!s->meth->list_object_end(s, handle))
+		{
+		STOREerr(STORE_F_STORE_LIST_CRL_END,
+			STORE_R_FAILED_LISTING_KEYS);
+		return 0;
+		}
+	return 1;
+	}
+
+int STORE_list_crl_endp(STORE *s, void *handle)
+	{
+	check_store(s,STORE_F_STORE_LIST_CRL_ENDP,
+		list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION);
+
+	if (!s->meth->list_object_endp(s, handle))
+		{
+		STOREerr(STORE_F_STORE_LIST_CRL_ENDP,
+			STORE_R_FAILED_LISTING_KEYS);
+		return 0;
+		}
+	return 1;
+	}
+
+int STORE_store_number(STORE *s, BIGNUM *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	STORE_OBJECT *object;
+	int i;
+
+	check_store(s,STORE_F_STORE_STORE_NUMBER,
+		store_object,STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION);
+
+	object = STORE_OBJECT_new();
+	if (!object)
+		{
+		STOREerr(STORE_F_STORE_STORE_NUMBER,
+			ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	
+	object->data.number = data;
+
+	i = s->meth->store_object(s, STORE_OBJECT_TYPE_NUMBER, object,
+		attributes, parameters);
+
+	STORE_OBJECT_free(object);
+
+	if (!i)
+		{
+		STOREerr(STORE_F_STORE_STORE_NUMBER,
+			STORE_R_FAILED_STORING_NUMBER);
+		return 0;
+		}
+	return 1;
+	}
+
+int STORE_modify_number(STORE *s, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
+	{
+	check_store(s,STORE_F_STORE_MODIFY_NUMBER,
+		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
+
+	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_NUMBER,
+		    search_attributes, add_attributes, modify_attributes,
+		    delete_attributes, parameters))
+		{
+		STOREerr(STORE_F_STORE_MODIFY_NUMBER,
+			STORE_R_FAILED_MODIFYING_NUMBER);
+		return 0;
+		}
+	return 1;
+	}
+
+BIGNUM *STORE_get_number(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	STORE_OBJECT *object;
+	BIGNUM *n;
+
+	check_store(s,STORE_F_STORE_GET_NUMBER,
+		get_object,STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION);
+
+	object = s->meth->get_object(s, STORE_OBJECT_TYPE_NUMBER, attributes,
+		parameters);
+	if (!object || !object->data.number)
+		{
+		STOREerr(STORE_F_STORE_GET_NUMBER,
+			STORE_R_FAILED_GETTING_NUMBER);
+		return 0;
+		}
+	n = object->data.number;
+	object->data.number = NULL;
+	STORE_OBJECT_free(object);
+	return n;
+	}
+
+int STORE_delete_number(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	check_store(s,STORE_F_STORE_DELETE_NUMBER,
+		delete_object,STORE_R_NO_DELETE_NUMBER_FUNCTION);
+
+	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_NUMBER, attributes,
+		    parameters))
+		{
+		STOREerr(STORE_F_STORE_DELETE_NUMBER,
+			STORE_R_FAILED_DELETING_NUMBER);
+		return 0;
+		}
+	return 1;
+	}
+
+int STORE_store_arbitrary(STORE *s, BUF_MEM *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	STORE_OBJECT *object;
+	int i;
+
+	check_store(s,STORE_F_STORE_STORE_ARBITRARY,
+		store_object,STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION);
+
+	object = STORE_OBJECT_new();
+	if (!object)
+		{
+		STOREerr(STORE_F_STORE_STORE_ARBITRARY,
+			ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	
+	object->data.arbitrary = data;
+
+	i = s->meth->store_object(s, STORE_OBJECT_TYPE_ARBITRARY, object,
+		attributes, parameters);
+
+	STORE_OBJECT_free(object);
+
+	if (!i)
+		{
+		STOREerr(STORE_F_STORE_STORE_ARBITRARY,
+			STORE_R_FAILED_STORING_ARBITRARY);
+		return 0;
+		}
+	return 1;
+	}
+
+int STORE_modify_arbitrary(STORE *s, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
+	{
+	check_store(s,STORE_F_STORE_MODIFY_ARBITRARY,
+		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
+
+	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_ARBITRARY,
+		    search_attributes, add_attributes, modify_attributes,
+		    delete_attributes, parameters))
+		{
+		STOREerr(STORE_F_STORE_MODIFY_ARBITRARY,
+			STORE_R_FAILED_MODIFYING_ARBITRARY);
+		return 0;
+		}
+	return 1;
+	}
+
+BUF_MEM *STORE_get_arbitrary(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	STORE_OBJECT *object;
+	BUF_MEM *b;
+
+	check_store(s,STORE_F_STORE_GET_ARBITRARY,
+		get_object,STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION);
+
+	object = s->meth->get_object(s, STORE_OBJECT_TYPE_ARBITRARY,
+		attributes, parameters);
+	if (!object || !object->data.arbitrary)
+		{
+		STOREerr(STORE_F_STORE_GET_ARBITRARY,
+			STORE_R_FAILED_GETTING_ARBITRARY);
+		return 0;
+		}
+	b = object->data.arbitrary;
+	object->data.arbitrary = NULL;
+	STORE_OBJECT_free(object);
+	return b;
+	}
+
+int STORE_delete_arbitrary(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	check_store(s,STORE_F_STORE_DELETE_ARBITRARY,
+		delete_object,STORE_R_NO_DELETE_ARBITRARY_FUNCTION);
+
+	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_ARBITRARY, attributes,
+		    parameters))
+		{
+		STOREerr(STORE_F_STORE_DELETE_ARBITRARY,
+			STORE_R_FAILED_DELETING_ARBITRARY);
+		return 0;
+		}
+	return 1;
+	}
+
+STORE_OBJECT *STORE_OBJECT_new(void)
+	{
+	STORE_OBJECT *object = OPENSSL_malloc(sizeof(STORE_OBJECT));
+	if (object) memset(object, 0, sizeof(STORE_OBJECT));
+	return object;
+	}
+void STORE_OBJECT_free(STORE_OBJECT *data)
+	{
+	if (!data) return;
+	switch (data->type)
+		{
+	case STORE_OBJECT_TYPE_X509_CERTIFICATE:
+		X509_free(data->data.x509.certificate);
+		break;
+	case STORE_OBJECT_TYPE_X509_CRL:
+		X509_CRL_free(data->data.crl);
+		break;
+	case STORE_OBJECT_TYPE_PRIVATE_KEY:
+	case STORE_OBJECT_TYPE_PUBLIC_KEY:
+		EVP_PKEY_free(data->data.key);
+		break;
+	case STORE_OBJECT_TYPE_NUMBER:
+		BN_free(data->data.number);
+		break;
+	case STORE_OBJECT_TYPE_ARBITRARY:
+		BUF_MEM_free(data->data.arbitrary);
+		break;
+		}
+	OPENSSL_free(data);
+	}
+
+IMPLEMENT_STACK_OF(STORE_OBJECT*)
+
+
+struct STORE_attr_info_st
+	{
+	unsigned char set[(STORE_ATTR_TYPE_NUM + 8) / 8];
+	union
+		{
+		char *cstring;
+		unsigned char *sha1string;
+		X509_NAME *dn;
+		BIGNUM *number;
+		void *any;
+		} values[STORE_ATTR_TYPE_NUM+1];
+	size_t value_sizes[STORE_ATTR_TYPE_NUM+1];
+	};
+
+#define ATTR_IS_SET(a,i)	((i) > 0 && (i) < STORE_ATTR_TYPE_NUM \
+				&& ((a)->set[(i) / 8] & (1 << ((i) % 8))))
+#define SET_ATTRBIT(a,i)	((a)->set[(i) / 8] |= (1 << ((i) % 8)))
+#define CLEAR_ATTRBIT(a,i)	((a)->set[(i) / 8] &= ~(1 << ((i) % 8)))
+
+STORE_ATTR_INFO *STORE_ATTR_INFO_new(void)
+	{
+	return (STORE_ATTR_INFO *)OPENSSL_malloc(sizeof(STORE_ATTR_INFO));
+	}
+static void STORE_ATTR_INFO_attr_free(STORE_ATTR_INFO *attrs,
+	STORE_ATTR_TYPES code)
+	{
+	if (ATTR_IS_SET(attrs,code))
+		{
+		switch(code)
+			{
+		case STORE_ATTR_FRIENDLYNAME:
+		case STORE_ATTR_EMAIL:
+		case STORE_ATTR_FILENAME:
+			STORE_ATTR_INFO_modify_cstr(attrs, code, NULL, 0);
+			break;
+		case STORE_ATTR_KEYID:
+		case STORE_ATTR_ISSUERKEYID:
+		case STORE_ATTR_SUBJECTKEYID:
+		case STORE_ATTR_ISSUERSERIALHASH:
+		case STORE_ATTR_CERTHASH:
+			STORE_ATTR_INFO_modify_sha1str(attrs, code, NULL, 0);
+			break;
+		case STORE_ATTR_ISSUER:
+		case STORE_ATTR_SUBJECT:
+			STORE_ATTR_INFO_modify_dn(attrs, code, NULL);
+			break;
+		case STORE_ATTR_SERIAL:
+			STORE_ATTR_INFO_modify_number(attrs, code, NULL);
+			break;
+		default:
+			break;
+			}
+		}
+	}
+int STORE_ATTR_INFO_free(STORE_ATTR_INFO *attrs)
+	{
+	if (attrs)
+		{
+		STORE_ATTR_TYPES i;
+		for(i = 0; i++ < STORE_ATTR_TYPE_NUM;)
+			STORE_ATTR_INFO_attr_free(attrs, i);
+		OPENSSL_free(attrs);
+		}
+	return 1;
+	}
+char *STORE_ATTR_INFO_get0_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code)
+	{
+	if (!attrs)
+		{
+		STOREerr(STORE_F_STORE_ATTR_INFO_GET0_CSTR,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return NULL;
+		}
+	if (ATTR_IS_SET(attrs,code))
+		return attrs->values[code].cstring;
+	STOREerr(STORE_F_STORE_ATTR_INFO_GET0_CSTR,
+		STORE_R_NO_VALUE);
+	return NULL;
+	}
+unsigned char *STORE_ATTR_INFO_get0_sha1str(STORE_ATTR_INFO *attrs,
+	STORE_ATTR_TYPES code)
+	{
+	if (!attrs)
+		{
+		STOREerr(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return NULL;
+		}
+	if (ATTR_IS_SET(attrs,code))
+		return attrs->values[code].sha1string;
+	STOREerr(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR,
+		STORE_R_NO_VALUE);
+	return NULL;
+	}
+X509_NAME *STORE_ATTR_INFO_get0_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code)
+	{
+	if (!attrs)
+		{
+		STOREerr(STORE_F_STORE_ATTR_INFO_GET0_DN,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return NULL;
+		}
+	if (ATTR_IS_SET(attrs,code))
+		return attrs->values[code].dn;
+	STOREerr(STORE_F_STORE_ATTR_INFO_GET0_DN,
+		STORE_R_NO_VALUE);
+	return NULL;
+	}
+BIGNUM *STORE_ATTR_INFO_get0_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code)
+	{
+	if (!attrs)
+		{
+		STOREerr(STORE_F_STORE_ATTR_INFO_GET0_NUMBER,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return NULL;
+		}
+	if (ATTR_IS_SET(attrs,code))
+		return attrs->values[code].number;
+	STOREerr(STORE_F_STORE_ATTR_INFO_GET0_NUMBER,
+		STORE_R_NO_VALUE);
+	return NULL;
+	}
+int STORE_ATTR_INFO_set_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	char *cstr, size_t cstr_size)
+	{
+	if (!attrs)
+		{
+		STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	if (!ATTR_IS_SET(attrs,code))
+		{
+		if ((attrs->values[code].cstring = BUF_strndup(cstr, cstr_size)))
+			return 1;
+		STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR,
+			ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR, STORE_R_ALREADY_HAS_A_VALUE);
+	return 0;
+	}
+int STORE_ATTR_INFO_set_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	unsigned char *sha1str, size_t sha1str_size)
+	{
+	if (!attrs)
+		{
+		STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	if (!ATTR_IS_SET(attrs,code))
+		{
+		if ((attrs->values[code].sha1string =
+			    (unsigned char *)BUF_memdup(sha1str,
+				    sha1str_size)))
+			return 1;
+		STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR,
+			ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR, STORE_R_ALREADY_HAS_A_VALUE);
+	return 0;
+	}
+int STORE_ATTR_INFO_set_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	X509_NAME *dn)
+	{
+	if (!attrs)
+		{
+		STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	if (!ATTR_IS_SET(attrs,code))
+		{
+		if ((attrs->values[code].dn = X509_NAME_dup(dn)))
+			return 1;
+		STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN,
+			ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN, STORE_R_ALREADY_HAS_A_VALUE);
+	return 0;
+	}
+int STORE_ATTR_INFO_set_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	BIGNUM *number)
+	{
+	if (!attrs)
+		{
+		STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	if (!ATTR_IS_SET(attrs,code))
+		{
+		if ((attrs->values[code].number = BN_dup(number)))
+			return 1;
+		STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER,
+			ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER, STORE_R_ALREADY_HAS_A_VALUE);
+	return 0;
+	}
+int STORE_ATTR_INFO_modify_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	char *cstr, size_t cstr_size)
+	{
+	if (!attrs)
+		{
+		STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_CSTR,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	if (ATTR_IS_SET(attrs,code))
+		{
+		OPENSSL_free(attrs->values[code].cstring);
+		attrs->values[code].cstring = NULL;
+		CLEAR_ATTRBIT(attrs, code);
+		}
+	return STORE_ATTR_INFO_set_cstr(attrs, code, cstr, cstr_size);
+	}
+int STORE_ATTR_INFO_modify_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	unsigned char *sha1str, size_t sha1str_size)
+	{
+	if (!attrs)
+		{
+		STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	if (ATTR_IS_SET(attrs,code))
+		{
+		OPENSSL_free(attrs->values[code].sha1string);
+		attrs->values[code].sha1string = NULL;
+		CLEAR_ATTRBIT(attrs, code);
+		}
+	return STORE_ATTR_INFO_set_sha1str(attrs, code, sha1str, sha1str_size);
+	}
+int STORE_ATTR_INFO_modify_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	X509_NAME *dn)
+	{
+	if (!attrs)
+		{
+		STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_DN,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	if (ATTR_IS_SET(attrs,code))
+		{
+		OPENSSL_free(attrs->values[code].dn);
+		attrs->values[code].dn = NULL;
+		CLEAR_ATTRBIT(attrs, code);
+		}
+	return STORE_ATTR_INFO_set_dn(attrs, code, dn);
+	}
+int STORE_ATTR_INFO_modify_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	BIGNUM *number)
+	{
+	if (!attrs)
+		{
+		STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	if (ATTR_IS_SET(attrs,code))
+		{
+		OPENSSL_free(attrs->values[code].number);
+		attrs->values[code].number = NULL;
+		CLEAR_ATTRBIT(attrs, code);
+		}
+	return STORE_ATTR_INFO_set_number(attrs, code, number);
+	}
+
+struct attr_list_ctx_st
+	{
+	OPENSSL_ITEM *attributes;
+	};
+void *STORE_parse_attrs_start(OPENSSL_ITEM *attributes)
+	{
+	if (attributes)
+		{
+		struct attr_list_ctx_st *context =
+			(struct attr_list_ctx_st *)OPENSSL_malloc(sizeof(struct attr_list_ctx_st));
+		if (context)
+			context->attributes = attributes;
+		else
+			STOREerr(STORE_F_STORE_PARSE_ATTRS_START,
+				ERR_R_MALLOC_FAILURE);
+		return context;
+		}
+	STOREerr(STORE_F_STORE_PARSE_ATTRS_START, ERR_R_PASSED_NULL_PARAMETER);
+	return 0;
+	}
+STORE_ATTR_INFO *STORE_parse_attrs_next(void *handle)
+	{
+	struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle;
+
+	if (context && context->attributes)
+		{
+		STORE_ATTR_INFO *attrs = NULL;
+
+		while(context->attributes
+			&& context->attributes->code != STORE_ATTR_OR
+			&& context->attributes->code != STORE_ATTR_END)
+			{
+			switch(context->attributes->code)
+				{
+			case STORE_ATTR_FRIENDLYNAME:
+			case STORE_ATTR_EMAIL:
+			case STORE_ATTR_FILENAME:
+				if (!attrs) attrs = STORE_ATTR_INFO_new();
+				if (attrs == NULL)
+					{
+					STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
+						ERR_R_MALLOC_FAILURE);
+					goto err;
+					}
+				STORE_ATTR_INFO_set_cstr(attrs,
+					context->attributes->code,
+					context->attributes->value,
+					context->attributes->value_size);
+				break;
+			case STORE_ATTR_KEYID:
+			case STORE_ATTR_ISSUERKEYID:
+			case STORE_ATTR_SUBJECTKEYID:
+			case STORE_ATTR_ISSUERSERIALHASH:
+			case STORE_ATTR_CERTHASH:
+				if (!attrs) attrs = STORE_ATTR_INFO_new();
+				if (attrs == NULL)
+					{
+					STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
+						ERR_R_MALLOC_FAILURE);
+					goto err;
+					}
+				STORE_ATTR_INFO_set_sha1str(attrs,
+					context->attributes->code,
+					context->attributes->value,
+					context->attributes->value_size);
+				break;
+			case STORE_ATTR_ISSUER:
+			case STORE_ATTR_SUBJECT:
+				if (!attrs) attrs = STORE_ATTR_INFO_new();
+				if (attrs == NULL)
+					{
+					STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
+						ERR_R_MALLOC_FAILURE);
+					goto err;
+					}
+				STORE_ATTR_INFO_modify_dn(attrs,
+					context->attributes->code,
+					context->attributes->value);
+				break;
+			case STORE_ATTR_SERIAL:
+				if (!attrs) attrs = STORE_ATTR_INFO_new();
+				if (attrs == NULL)
+					{
+					STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
+						ERR_R_MALLOC_FAILURE);
+					goto err;
+					}
+				STORE_ATTR_INFO_modify_number(attrs,
+					context->attributes->code,
+					context->attributes->value);
+				break;
+				}
+			context->attributes++;
+			}
+		if (context->attributes->code == STORE_ATTR_OR)
+			context->attributes++;
+		return attrs;
+	err:
+		while(context->attributes
+			&& context->attributes->code != STORE_ATTR_OR
+			&& context->attributes->code != STORE_ATTR_END)
+			context->attributes++;
+		if (context->attributes->code == STORE_ATTR_OR)
+			context->attributes++;
+		return NULL;
+		}
+	STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, ERR_R_PASSED_NULL_PARAMETER);
+	return NULL;
+	}
+int STORE_parse_attrs_end(void *handle)
+	{
+	struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle;
+
+	if (context && context->attributes)
+		{
+#if 0
+		OPENSSL_ITEM *attributes = context->attributes;
+#endif
+		OPENSSL_free(context);
+		return 1;
+		}
+	STOREerr(STORE_F_STORE_PARSE_ATTRS_END, ERR_R_PASSED_NULL_PARAMETER);
+	return 0;
+	}
+
+int STORE_parse_attrs_endp(void *handle)
+	{
+	struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle;
+
+	if (context && context->attributes)
+		{
+		return context->attributes->code == STORE_ATTR_END;
+		}
+	STOREerr(STORE_F_STORE_PARSE_ATTRS_ENDP, ERR_R_PASSED_NULL_PARAMETER);
+	return 0;
+	}
+
+static int attr_info_compare_compute_range(
+	const unsigned char *abits, const unsigned char *bbits,
+	unsigned int *alowp, unsigned int *ahighp,
+	unsigned int *blowp, unsigned int *bhighp)
+	{
+	unsigned int alow = (unsigned int)-1, ahigh = 0;
+	unsigned int blow = (unsigned int)-1, bhigh = 0;
+	int i, res = 0;
+
+	for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++)
+		{
+		if (res == 0)
+			{
+			if (*abits < *bbits) res = -1;
+			if (*abits > *bbits) res = 1;
+			}
+		if (*abits)
+			{
+			if (alow == (unsigned int)-1)
+				{
+				alow = i * 8;
+				if (!(*abits & 0x01)) alow++;
+				if (!(*abits & 0x02)) alow++;
+				if (!(*abits & 0x04)) alow++;
+				if (!(*abits & 0x08)) alow++;
+				if (!(*abits & 0x10)) alow++;
+				if (!(*abits & 0x20)) alow++;
+				if (!(*abits & 0x40)) alow++;
+				}
+			ahigh = i * 8 + 7;
+			if (!(*abits & 0x80)) ahigh++;
+			if (!(*abits & 0x40)) ahigh++;
+			if (!(*abits & 0x20)) ahigh++;
+			if (!(*abits & 0x10)) ahigh++;
+			if (!(*abits & 0x08)) ahigh++;
+			if (!(*abits & 0x04)) ahigh++;
+			if (!(*abits & 0x02)) ahigh++;
+			}
+		if (*bbits)
+			{
+			if (blow == (unsigned int)-1)
+				{
+				blow = i * 8;
+				if (!(*bbits & 0x01)) blow++;
+				if (!(*bbits & 0x02)) blow++;
+				if (!(*bbits & 0x04)) blow++;
+				if (!(*bbits & 0x08)) blow++;
+				if (!(*bbits & 0x10)) blow++;
+				if (!(*bbits & 0x20)) blow++;
+				if (!(*bbits & 0x40)) blow++;
+				}
+			bhigh = i * 8 + 7;
+			if (!(*bbits & 0x80)) bhigh++;
+			if (!(*bbits & 0x40)) bhigh++;
+			if (!(*bbits & 0x20)) bhigh++;
+			if (!(*bbits & 0x10)) bhigh++;
+			if (!(*bbits & 0x08)) bhigh++;
+			if (!(*bbits & 0x04)) bhigh++;
+			if (!(*bbits & 0x02)) bhigh++;
+			}
+		}
+	if (ahigh + alow < bhigh + blow) res = -1;
+	if (ahigh + alow > bhigh + blow) res = 1;
+	if (alowp) *alowp = alow;
+	if (ahighp) *ahighp = ahigh;
+	if (blowp) *blowp = blow;
+	if (bhighp) *bhighp = bhigh;
+	return res;
+	}
+
+int STORE_ATTR_INFO_compare(const STORE_ATTR_INFO * const *a,
+			    const STORE_ATTR_INFO * const *b)
+	{
+	if (a == b) return 0;
+	if (!a) return -1;
+	if (!b) return 1;
+	return attr_info_compare_compute_range((*a)->set, (*b)->set, 0, 0, 0, 0);
+	}
+
+int STORE_ATTR_INFO_in_range(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
+	{
+	unsigned int alow, ahigh, blow, bhigh;
+
+	if (a == b) return 1;
+	if (!a) return 0;
+	if (!b) return 0;
+	attr_info_compare_compute_range(a->set, b->set,
+		&alow, &ahigh, &blow, &bhigh);
+	if (alow >= blow && ahigh <= bhigh)
+		return 1;
+	return 0;
+	}
+
+int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
+	{
+	unsigned char *abits, *bbits;
+	int i;
+
+	if (a == b) return 1;
+	if (!a) return 0;
+	if (!b) return 0;
+	abits = a->set;
+	bbits = b->set;
+	for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++)
+		{
+		if (*abits && (*bbits & *abits) != *abits)
+			return 0;
+		}
+	return 1;
+	}
+
+int STORE_ATTR_INFO_in_ex(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
+	{
+	STORE_ATTR_TYPES i;
+
+	if (a == b) return 1;
+	if (!STORE_ATTR_INFO_in(a, b)) return 0;
+	for (i = 1; i < STORE_ATTR_TYPE_NUM; i++)
+		if (ATTR_IS_SET(a, i))
+			{
+			switch(i)
+				{
+			case STORE_ATTR_FRIENDLYNAME:
+			case STORE_ATTR_EMAIL:
+			case STORE_ATTR_FILENAME:
+				if (strcmp(a->values[i].cstring,
+					    b->values[i].cstring))
+					return 0;
+				break;
+			case STORE_ATTR_KEYID:
+			case STORE_ATTR_ISSUERKEYID:
+			case STORE_ATTR_SUBJECTKEYID:
+			case STORE_ATTR_ISSUERSERIALHASH:
+			case STORE_ATTR_CERTHASH:
+				if (memcmp(a->values[i].sha1string,
+					    b->values[i].sha1string,
+					    a->value_sizes[i]))
+					return 0;
+				break;
+			case STORE_ATTR_ISSUER:
+			case STORE_ATTR_SUBJECT:
+				if (X509_NAME_cmp(a->values[i].dn,
+					    b->values[i].dn))
+					return 0;
+				break;
+			case STORE_ATTR_SERIAL:
+				if (BN_cmp(a->values[i].number,
+					    b->values[i].number))
+					return 0;
+				break;
+			default:
+				break;
+				}
+			}
+
+	return 1;
+	}
diff --git a/openssl/crypto/store/str_locl.h b/openssl/crypto/store/str_locl.h
new file mode 100644
index 0000000..3f8cb75
--- /dev/null
+++ b/openssl/crypto/store/str_locl.h
@@ -0,0 +1,124 @@
+/* crypto/store/str_locl.h -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2003.
+ */
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_STORE_LOCL_H
+#define HEADER_STORE_LOCL_H
+
+#include <openssl/crypto.h>
+#include <openssl/store.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+struct store_method_st
+	{
+	char *name;
+
+	/* All the functions return a positive integer or non-NULL for success
+	   and 0, a negative integer or NULL for failure */
+
+	/* Initialise the STORE with private data */
+	STORE_INITIALISE_FUNC_PTR init;
+	/* Initialise the STORE with private data */
+	STORE_CLEANUP_FUNC_PTR clean;
+	/* Generate an object of a given type */
+	STORE_GENERATE_OBJECT_FUNC_PTR generate_object;
+	/* Get an object of a given type.  This function isn't really very
+	   useful since the listing functions (below) can be used for the
+	   same purpose and are much more general. */
+	STORE_GET_OBJECT_FUNC_PTR get_object;
+	/* Store an object of a given type. */
+	STORE_STORE_OBJECT_FUNC_PTR store_object;
+	/* Modify the attributes bound to an object of a given type. */
+	STORE_MODIFY_OBJECT_FUNC_PTR modify_object;
+	/* Revoke an object of a given type. */
+	STORE_HANDLE_OBJECT_FUNC_PTR revoke_object;
+	/* Delete an object of a given type. */
+	STORE_HANDLE_OBJECT_FUNC_PTR delete_object;
+	/* List a bunch of objects of a given type and with the associated
+	   attributes. */
+	STORE_START_OBJECT_FUNC_PTR list_object_start;
+	STORE_NEXT_OBJECT_FUNC_PTR list_object_next;
+	STORE_END_OBJECT_FUNC_PTR list_object_end;
+	STORE_END_OBJECT_FUNC_PTR list_object_endp;
+	/* Store-level function to make any necessary update operations. */
+	STORE_GENERIC_FUNC_PTR update_store;
+	/* Store-level function to get exclusive access to the store. */
+	STORE_GENERIC_FUNC_PTR lock_store;
+	/* Store-level function to release exclusive access to the store. */
+	STORE_GENERIC_FUNC_PTR unlock_store;
+
+	/* Generic control function */
+	STORE_CTRL_FUNC_PTR ctrl;
+	};
+
+struct store_st
+	{
+	const STORE_METHOD *meth;
+	/* functional reference if 'meth' is ENGINE-provided */
+	ENGINE *engine;
+
+	CRYPTO_EX_DATA ex_data;
+	int references;
+	};
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/store/str_mem.c b/openssl/crypto/store/str_mem.c
new file mode 100644
index 0000000..8ac4f7e
--- /dev/null
+++ b/openssl/crypto/store/str_mem.c
@@ -0,0 +1,365 @@
+/* crypto/store/str_mem.c -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2003.
+ */
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+#include <openssl/err.h>
+#include "str_locl.h"
+
+/* The memory store is currently highly experimental.  It's meant to become
+   a base store used by other stores for internal caching (for full caching
+   support, aging needs to be added).
+
+   The database use is meant to support as much attribute association as
+   possible, while providing for as small search ranges as possible.
+   This is currently provided for by sorting the entries by numbers that
+   are composed of bits set at the positions indicated by attribute type
+   codes.  This provides for ranges determined by the highest attribute
+   type code value.  A better idea might be to sort by values computed
+   from the range of attributes associated with the object (basically,
+   the difference between the highest and lowest attribute type code)
+   and it's distance from a base (basically, the lowest associated
+   attribute type code).
+*/
+
+typedef struct mem_object_data_st
+	{
+	STORE_OBJECT *object;
+	STORE_ATTR_INFO *attr_info;
+	int references;
+	} MEM_OBJECT_DATA;
+
+DECLARE_STACK_OF(MEM_OBJECT_DATA)
+struct mem_data_st
+	{
+	STACK_OF(MEM_OBJECT_DATA) *data; /* sorted with
+					  * STORE_ATTR_INFO_compare(). */
+	unsigned int compute_components : 1; /* Currently unused, but can
+						be used to add attributes
+						from parts of the data. */
+	};
+
+DECLARE_STACK_OF(STORE_ATTR_INFO)
+struct mem_ctx_st
+	{
+	int type;		/* The type we're searching for */
+	STACK_OF(STORE_ATTR_INFO) *search_attributes; /* Sets of
+				     attributes to search for.  Each
+				     element is a STORE_ATTR_INFO. */
+	int search_index;	/* which of the search attributes we
+				   found a match for, -1 when we still
+				   haven't found any */
+	int index;		/* -1 as long as we're searching for
+                                    the first */
+	};
+
+static int mem_init(STORE *s);
+static void mem_clean(STORE *s);
+static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type,
+	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type,
+	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+static int mem_store(STORE *s, STORE_OBJECT_TYPES type,
+	STORE_OBJECT *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+static int mem_modify(STORE *s, STORE_OBJECT_TYPES type,
+	OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[],
+	OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[],
+	OPENSSL_ITEM parameters[]);
+static int mem_delete(STORE *s, STORE_OBJECT_TYPES type,
+	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type,
+	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+static STORE_OBJECT *mem_list_next(STORE *s, void *handle);
+static int mem_list_end(STORE *s, void *handle);
+static int mem_list_endp(STORE *s, void *handle);
+static int mem_lock(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f)(void));
+
+static STORE_METHOD store_memory =
+	{
+	"OpenSSL memory store interface",
+	mem_init,
+	mem_clean,
+	mem_generate,
+	mem_get,
+	mem_store,
+	mem_modify,
+	NULL, /* revoke */
+	mem_delete,
+	mem_list_start,
+	mem_list_next,
+	mem_list_end,
+	mem_list_endp,
+	NULL, /* update */
+	mem_lock,
+	mem_unlock,
+	mem_ctrl
+	};
+
+const STORE_METHOD *STORE_Memory(void)
+	{
+	return &store_memory;
+	}
+
+static int mem_init(STORE *s)
+	{
+	return 1;
+	}
+
+static void mem_clean(STORE *s)
+	{
+	return;
+	}
+
+static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type,
+	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
+	{
+	STOREerr(STORE_F_MEM_GENERATE, STORE_R_NOT_IMPLEMENTED);
+	return 0;
+	}
+static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type,
+	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
+	{
+	void *context = mem_list_start(s, type, attributes, parameters);
+	
+	if (context)
+		{
+		STORE_OBJECT *object = mem_list_next(s, context);
+
+		if (mem_list_end(s, context))
+			return object;
+		}
+	return NULL;
+	}
+static int mem_store(STORE *s, STORE_OBJECT_TYPES type,
+	STORE_OBJECT *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	STOREerr(STORE_F_MEM_STORE, STORE_R_NOT_IMPLEMENTED);
+	return 0;
+	}
+static int mem_modify(STORE *s, STORE_OBJECT_TYPES type,
+	OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[],
+	OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	STOREerr(STORE_F_MEM_MODIFY, STORE_R_NOT_IMPLEMENTED);
+	return 0;
+	}
+static int mem_delete(STORE *s, STORE_OBJECT_TYPES type,
+	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
+	{
+	STOREerr(STORE_F_MEM_DELETE, STORE_R_NOT_IMPLEMENTED);
+	return 0;
+	}
+
+/* The list functions may be the hardest to understand.  Basically,
+   mem_list_start compiles a stack of attribute info elements, and
+   puts that stack into the context to be returned.  mem_list_next
+   will then find the first matching element in the store, and then
+   walk all the way to the end of the store (since any combination
+   of attribute bits above the starting point may match the searched
+   for bit pattern...). */
+static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type,
+	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
+	{
+	struct mem_ctx_st *context =
+		(struct mem_ctx_st *)OPENSSL_malloc(sizeof(struct mem_ctx_st));
+	void *attribute_context = NULL;
+	STORE_ATTR_INFO *attrs = NULL;
+
+	if (!context)
+		{
+		STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	memset(context, 0, sizeof(struct mem_ctx_st));
+
+	attribute_context = STORE_parse_attrs_start(attributes);
+	if (!attribute_context)
+		{
+		STOREerr(STORE_F_MEM_LIST_START, ERR_R_STORE_LIB);
+		goto err;
+		}
+
+	while((attrs = STORE_parse_attrs_next(attribute_context)))
+		{
+		if (context->search_attributes == NULL)
+			{
+			context->search_attributes =
+				sk_STORE_ATTR_INFO_new(STORE_ATTR_INFO_compare);
+			if (!context->search_attributes)
+				{
+				STOREerr(STORE_F_MEM_LIST_START,
+					ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			}
+		sk_STORE_ATTR_INFO_push(context->search_attributes,attrs);
+		}
+	if (!STORE_parse_attrs_endp(attribute_context))
+		goto err;
+	STORE_parse_attrs_end(attribute_context);
+	context->search_index = -1;
+	context->index = -1;
+	return context;
+ err:
+	if (attribute_context) STORE_parse_attrs_end(attribute_context);
+	mem_list_end(s, context);
+	return NULL;
+	}
+static STORE_OBJECT *mem_list_next(STORE *s, void *handle)
+	{
+	int i;
+	struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
+	struct mem_object_data_st key = { 0, 0, 1 };
+	struct mem_data_st *store =
+		(struct mem_data_st *)STORE_get_ex_data(s, 1);
+	int srch;
+	int cres = 0;
+
+	if (!context)
+		{
+		STOREerr(STORE_F_MEM_LIST_NEXT, ERR_R_PASSED_NULL_PARAMETER);
+		return NULL;
+		}
+	if (!store)
+		{
+		STOREerr(STORE_F_MEM_LIST_NEXT, STORE_R_NO_STORE);
+		return NULL;
+		}
+
+	if (context->search_index == -1)
+		{
+		for (i = 0;
+		     i < sk_STORE_ATTR_INFO_num(context->search_attributes);
+		     i++)
+			{
+			key.attr_info
+			  = sk_STORE_ATTR_INFO_value(context->search_attributes,
+						     i);
+			srch = sk_MEM_OBJECT_DATA_find_ex(store->data, &key);
+
+			if (srch >= 0)
+				{
+				context->search_index = srch;
+				break;
+				}
+			}
+		}
+	if (context->search_index < 0)
+		return NULL;
+	
+	key.attr_info =
+		sk_STORE_ATTR_INFO_value(context->search_attributes,
+					 context->search_index);
+	for(srch = context->search_index;
+	    srch < sk_MEM_OBJECT_DATA_num(store->data)
+		    && STORE_ATTR_INFO_in_range(key.attr_info,
+			    sk_MEM_OBJECT_DATA_value(store->data, srch)->attr_info)
+		    && !(cres = STORE_ATTR_INFO_in_ex(key.attr_info,
+				 sk_MEM_OBJECT_DATA_value(store->data, srch)->attr_info));
+	    srch++)
+		;
+
+	context->search_index = srch;
+	if (cres)
+		return (sk_MEM_OBJECT_DATA_value(store->data, srch))->object;
+	return NULL;
+	}
+static int mem_list_end(STORE *s, void *handle)
+	{
+	struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
+
+	if (!context)
+		{
+		STOREerr(STORE_F_MEM_LIST_END, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	if (context && context->search_attributes)
+		sk_STORE_ATTR_INFO_free(context->search_attributes);
+	if (context) OPENSSL_free(context);
+	return 1;
+	}
+static int mem_list_endp(STORE *s, void *handle)
+	{
+	struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
+
+	if (!context
+	    || context->search_index
+	       == sk_STORE_ATTR_INFO_num(context->search_attributes))
+		return 1;
+	return 0;
+	}
+static int mem_lock(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	return 1;
+	}
+static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[])
+	{
+	return 1;
+	}
+static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f)(void))
+	{
+	return 1;
+	}
diff --git a/openssl/crypto/store/str_meth.c b/openssl/crypto/store/str_meth.c
new file mode 100644
index 0000000..a46de03
--- /dev/null
+++ b/openssl/crypto/store/str_meth.c
@@ -0,0 +1,250 @@
+/* crypto/store/str_meth.c -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2003.
+ */
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+#include <openssl/buffer.h>
+#include "str_locl.h"
+
+STORE_METHOD *STORE_create_method(char *name)
+	{
+	STORE_METHOD *store_method = (STORE_METHOD *)OPENSSL_malloc(sizeof(STORE_METHOD));
+
+	if (store_method)
+		{
+		memset(store_method, 0, sizeof(*store_method));
+		store_method->name = BUF_strdup(name);
+		}
+	return store_method;
+	}
+
+/* BIG FSCKING WARNING!!!!  If you use this on a statically allocated method
+   (that is, it hasn't been allocated using STORE_create_method(), you deserve
+   anything Murphy can throw at you and more!  You have been warned. */
+void STORE_destroy_method(STORE_METHOD *store_method)
+	{
+	if (!store_method) return;
+	OPENSSL_free(store_method->name);
+	store_method->name = NULL;
+	OPENSSL_free(store_method);
+	}
+
+int STORE_method_set_initialise_function(STORE_METHOD *sm, STORE_INITIALISE_FUNC_PTR init_f)
+	{
+	sm->init = init_f;
+	return 1;
+	}
+
+int STORE_method_set_cleanup_function(STORE_METHOD *sm, STORE_CLEANUP_FUNC_PTR clean_f)
+	{
+	sm->clean = clean_f;
+	return 1;
+	}
+
+int STORE_method_set_generate_function(STORE_METHOD *sm, STORE_GENERATE_OBJECT_FUNC_PTR generate_f)
+	{
+	sm->generate_object = generate_f;
+	return 1;
+	}
+
+int STORE_method_set_get_function(STORE_METHOD *sm, STORE_GET_OBJECT_FUNC_PTR get_f)
+	{
+	sm->get_object = get_f;
+	return 1;
+	}
+
+int STORE_method_set_store_function(STORE_METHOD *sm, STORE_STORE_OBJECT_FUNC_PTR store_f)
+	{
+	sm->store_object = store_f;
+	return 1;
+	}
+
+int STORE_method_set_modify_function(STORE_METHOD *sm, STORE_MODIFY_OBJECT_FUNC_PTR modify_f)
+	{
+	sm->modify_object = modify_f;
+	return 1;
+	}
+
+int STORE_method_set_revoke_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR revoke_f)
+	{
+	sm->revoke_object = revoke_f;
+	return 1;
+	}
+
+int STORE_method_set_delete_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR delete_f)
+	{
+	sm->delete_object = delete_f;
+	return 1;
+	}
+
+int STORE_method_set_list_start_function(STORE_METHOD *sm, STORE_START_OBJECT_FUNC_PTR list_start_f)
+	{
+	sm->list_object_start = list_start_f;
+	return 1;
+	}
+
+int STORE_method_set_list_next_function(STORE_METHOD *sm, STORE_NEXT_OBJECT_FUNC_PTR list_next_f)
+	{
+	sm->list_object_next = list_next_f;
+	return 1;
+	}
+
+int STORE_method_set_list_end_function(STORE_METHOD *sm, STORE_END_OBJECT_FUNC_PTR list_end_f)
+	{
+	sm->list_object_end = list_end_f;
+	return 1;
+	}
+
+int STORE_method_set_update_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR update_f)
+	{
+	sm->update_store = update_f;
+	return 1;
+	}
+
+int STORE_method_set_lock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR lock_f)
+	{
+	sm->lock_store = lock_f;
+	return 1;
+	}
+
+int STORE_method_set_unlock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR unlock_f)
+	{
+	sm->unlock_store = unlock_f;
+	return 1;
+	}
+
+int STORE_method_set_ctrl_function(STORE_METHOD *sm, STORE_CTRL_FUNC_PTR ctrl_f)
+	{
+	sm->ctrl = ctrl_f;
+	return 1;
+	}
+
+STORE_INITIALISE_FUNC_PTR STORE_method_get_initialise_function(STORE_METHOD *sm)
+	{
+	return sm->init;
+	}
+
+STORE_CLEANUP_FUNC_PTR STORE_method_get_cleanup_function(STORE_METHOD *sm)
+	{
+	return sm->clean;
+	}
+
+STORE_GENERATE_OBJECT_FUNC_PTR STORE_method_get_generate_function(STORE_METHOD *sm)
+	{
+	return sm->generate_object;
+	}
+
+STORE_GET_OBJECT_FUNC_PTR STORE_method_get_get_function(STORE_METHOD *sm)
+	{
+	return sm->get_object;
+	}
+
+STORE_STORE_OBJECT_FUNC_PTR STORE_method_get_store_function(STORE_METHOD *sm)
+	{
+	return sm->store_object;
+	}
+
+STORE_MODIFY_OBJECT_FUNC_PTR STORE_method_get_modify_function(STORE_METHOD *sm)
+	{
+	return sm->modify_object;
+	}
+
+STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_revoke_function(STORE_METHOD *sm)
+	{
+	return sm->revoke_object;
+	}
+
+STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_delete_function(STORE_METHOD *sm)
+	{
+	return sm->delete_object;
+	}
+
+STORE_START_OBJECT_FUNC_PTR STORE_method_get_list_start_function(STORE_METHOD *sm)
+	{
+	return sm->list_object_start;
+	}
+
+STORE_NEXT_OBJECT_FUNC_PTR STORE_method_get_list_next_function(STORE_METHOD *sm)
+	{
+	return sm->list_object_next;
+	}
+
+STORE_END_OBJECT_FUNC_PTR STORE_method_get_list_end_function(STORE_METHOD *sm)
+	{
+	return sm->list_object_end;
+	}
+
+STORE_GENERIC_FUNC_PTR STORE_method_get_update_store_function(STORE_METHOD *sm)
+	{
+	return sm->update_store;
+	}
+
+STORE_GENERIC_FUNC_PTR STORE_method_get_lock_store_function(STORE_METHOD *sm)
+	{
+	return sm->lock_store;
+	}
+
+STORE_GENERIC_FUNC_PTR STORE_method_get_unlock_store_function(STORE_METHOD *sm)
+	{
+	return sm->unlock_store;
+	}
+
+STORE_CTRL_FUNC_PTR STORE_method_get_ctrl_function(STORE_METHOD *sm)
+	{
+	return sm->ctrl;
+	}
+
diff --git a/openssl/crypto/symhacks.h b/openssl/crypto/symhacks.h
new file mode 100644
index 0000000..3fd4a81
--- /dev/null
+++ b/openssl/crypto/symhacks.h
@@ -0,0 +1,449 @@
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_SYMHACKS_H
+#define HEADER_SYMHACKS_H
+
+#include <openssl/e_os2.h>
+
+/* Hacks to solve the problem with linkers incapable of handling very long
+   symbol names.  In the case of VMS, the limit is 31 characters on VMS for
+   VAX. */
+/* Note that this affects util/libeay.num and util/ssleay.num...  you may
+   change those manually, but that's not recommended, as those files are
+   controlled centrally and updated on Unix, and the central definition
+   may disagree with yours, which in turn may come with shareable library
+   incompatibilities. */
+#ifdef OPENSSL_SYS_VMS
+
+/* Hack a long name in crypto/ex_data.c */
+#undef CRYPTO_get_ex_data_implementation
+#define CRYPTO_get_ex_data_implementation	CRYPTO_get_ex_data_impl
+#undef CRYPTO_set_ex_data_implementation
+#define CRYPTO_set_ex_data_implementation	CRYPTO_set_ex_data_impl
+
+/* Hack a long name in crypto/asn1/a_mbstr.c */
+#undef ASN1_STRING_set_default_mask_asc
+#define ASN1_STRING_set_default_mask_asc	ASN1_STRING_set_def_mask_asc
+
+#if 0 /* No longer needed, since safestack macro magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) */
+#undef i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO
+#define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO	i2d_ASN1_SET_OF_PKCS7_SIGINF
+#undef d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO
+#define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO	d2i_ASN1_SET_OF_PKCS7_SIGINF
+#endif
+
+#if 0 /* No longer needed, since safestack macro magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) */
+#undef i2d_ASN1_SET_OF_PKCS7_RECIP_INFO
+#define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO	i2d_ASN1_SET_OF_PKCS7_RECINF
+#undef d2i_ASN1_SET_OF_PKCS7_RECIP_INFO
+#define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO	d2i_ASN1_SET_OF_PKCS7_RECINF
+#endif
+
+#if 0 /* No longer needed, since safestack macro magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) */
+#undef i2d_ASN1_SET_OF_ACCESS_DESCRIPTION
+#define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION	i2d_ASN1_SET_OF_ACC_DESC
+#undef d2i_ASN1_SET_OF_ACCESS_DESCRIPTION
+#define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION	d2i_ASN1_SET_OF_ACC_DESC
+#endif
+
+/* Hack the names created with DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE) */
+#undef PEM_read_NETSCAPE_CERT_SEQUENCE
+#define PEM_read_NETSCAPE_CERT_SEQUENCE		PEM_read_NS_CERT_SEQ
+#undef PEM_write_NETSCAPE_CERT_SEQUENCE
+#define PEM_write_NETSCAPE_CERT_SEQUENCE	PEM_write_NS_CERT_SEQ
+#undef PEM_read_bio_NETSCAPE_CERT_SEQUENCE
+#define PEM_read_bio_NETSCAPE_CERT_SEQUENCE	PEM_read_bio_NS_CERT_SEQ
+#undef PEM_write_bio_NETSCAPE_CERT_SEQUENCE
+#define PEM_write_bio_NETSCAPE_CERT_SEQUENCE	PEM_write_bio_NS_CERT_SEQ
+#undef PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE
+#define PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE	PEM_write_cb_bio_NS_CERT_SEQ
+
+/* Hack the names created with DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO) */
+#undef PEM_read_PKCS8_PRIV_KEY_INFO
+#define PEM_read_PKCS8_PRIV_KEY_INFO		PEM_read_P8_PRIV_KEY_INFO
+#undef PEM_write_PKCS8_PRIV_KEY_INFO
+#define PEM_write_PKCS8_PRIV_KEY_INFO		PEM_write_P8_PRIV_KEY_INFO
+#undef PEM_read_bio_PKCS8_PRIV_KEY_INFO
+#define PEM_read_bio_PKCS8_PRIV_KEY_INFO	PEM_read_bio_P8_PRIV_KEY_INFO
+#undef PEM_write_bio_PKCS8_PRIV_KEY_INFO
+#define PEM_write_bio_PKCS8_PRIV_KEY_INFO	PEM_write_bio_P8_PRIV_KEY_INFO
+#undef PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO
+#define PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO	PEM_wrt_cb_bio_P8_PRIV_KEY_INFO
+
+/* Hack other PEM names */
+#undef PEM_write_bio_PKCS8PrivateKey_nid
+#define PEM_write_bio_PKCS8PrivateKey_nid	PEM_write_bio_PKCS8PrivKey_nid
+
+/* Hack some long X509 names */
+#undef X509_REVOKED_get_ext_by_critical
+#define X509_REVOKED_get_ext_by_critical	X509_REVOKED_get_ext_by_critic
+#undef X509_policy_tree_get0_user_policies
+#define X509_policy_tree_get0_user_policies	X509_pcy_tree_get0_usr_policies
+#undef X509_policy_node_get0_qualifiers
+#define X509_policy_node_get0_qualifiers	X509_pcy_node_get0_qualifiers
+#undef X509_STORE_CTX_get_explicit_policy
+#define X509_STORE_CTX_get_explicit_policy	X509_STORE_CTX_get_expl_policy
+#undef X509_STORE_CTX_get0_current_issuer
+#define X509_STORE_CTX_get0_current_issuer	X509_STORE_CTX_get0_cur_issuer
+
+/* Hack some long CRYPTO names */
+#undef CRYPTO_set_dynlock_destroy_callback
+#define CRYPTO_set_dynlock_destroy_callback     CRYPTO_set_dynlock_destroy_cb
+#undef CRYPTO_set_dynlock_create_callback
+#define CRYPTO_set_dynlock_create_callback      CRYPTO_set_dynlock_create_cb
+#undef CRYPTO_set_dynlock_lock_callback
+#define CRYPTO_set_dynlock_lock_callback	CRYPTO_set_dynlock_lock_cb
+#undef CRYPTO_get_dynlock_lock_callback
+#define CRYPTO_get_dynlock_lock_callback	CRYPTO_get_dynlock_lock_cb
+#undef CRYPTO_get_dynlock_destroy_callback
+#define CRYPTO_get_dynlock_destroy_callback     CRYPTO_get_dynlock_destroy_cb
+#undef CRYPTO_get_dynlock_create_callback
+#define CRYPTO_get_dynlock_create_callback      CRYPTO_get_dynlock_create_cb
+#undef CRYPTO_set_locked_mem_ex_functions
+#define CRYPTO_set_locked_mem_ex_functions      CRYPTO_set_locked_mem_ex_funcs
+#undef CRYPTO_get_locked_mem_ex_functions
+#define CRYPTO_get_locked_mem_ex_functions      CRYPTO_get_locked_mem_ex_funcs
+
+/* Hack some long SSL names */
+#undef SSL_CTX_set_default_verify_paths
+#define SSL_CTX_set_default_verify_paths	SSL_CTX_set_def_verify_paths
+#undef SSL_get_ex_data_X509_STORE_CTX_idx
+#define SSL_get_ex_data_X509_STORE_CTX_idx      SSL_get_ex_d_X509_STORE_CTX_idx
+#undef SSL_add_file_cert_subjects_to_stack
+#define SSL_add_file_cert_subjects_to_stack     SSL_add_file_cert_subjs_to_stk
+#undef SSL_add_dir_cert_subjects_to_stack
+#define SSL_add_dir_cert_subjects_to_stack      SSL_add_dir_cert_subjs_to_stk
+#undef SSL_CTX_use_certificate_chain_file
+#define SSL_CTX_use_certificate_chain_file      SSL_CTX_use_cert_chain_file
+#undef SSL_CTX_set_cert_verify_callback
+#define SSL_CTX_set_cert_verify_callback	SSL_CTX_set_cert_verify_cb
+#undef SSL_CTX_set_default_passwd_cb_userdata
+#define SSL_CTX_set_default_passwd_cb_userdata  SSL_CTX_set_def_passwd_cb_ud
+#undef SSL_COMP_get_compression_methods
+#define SSL_COMP_get_compression_methods	SSL_COMP_get_compress_methods
+
+#undef ssl_add_clienthello_renegotiate_ext
+#define ssl_add_clienthello_renegotiate_ext	ssl_add_clienthello_reneg_ext
+#undef ssl_add_serverhello_renegotiate_ext
+#define ssl_add_serverhello_renegotiate_ext	ssl_add_serverhello_reneg_ext
+#undef ssl_parse_clienthello_renegotiate_ext
+#define ssl_parse_clienthello_renegotiate_ext	ssl_parse_clienthello_reneg_ext
+#undef ssl_parse_serverhello_renegotiate_ext
+#define ssl_parse_serverhello_renegotiate_ext	ssl_parse_serverhello_reneg_ext
+
+/* Hack some long ENGINE names */
+#undef ENGINE_get_default_BN_mod_exp_crt
+#define ENGINE_get_default_BN_mod_exp_crt	ENGINE_get_def_BN_mod_exp_crt
+#undef ENGINE_set_default_BN_mod_exp_crt
+#define ENGINE_set_default_BN_mod_exp_crt	ENGINE_set_def_BN_mod_exp_crt
+#undef ENGINE_set_load_privkey_function
+#define ENGINE_set_load_privkey_function	ENGINE_set_load_privkey_fn
+#undef ENGINE_get_load_privkey_function
+#define ENGINE_get_load_privkey_function	ENGINE_get_load_privkey_fn
+#undef ENGINE_unregister_pkey_asn1_meths
+#define ENGINE_unregister_pkey_asn1_meths	ENGINE_unreg_pkey_asn1_meths
+#undef ENGINE_register_all_pkey_asn1_meths
+#define ENGINE_register_all_pkey_asn1_meths	ENGINE_reg_all_pkey_asn1_meths
+#undef ENGINE_set_default_pkey_asn1_meths
+#define ENGINE_set_default_pkey_asn1_meths	ENGINE_set_def_pkey_asn1_meths
+#undef ENGINE_get_pkey_asn1_meth_engine
+#define ENGINE_get_pkey_asn1_meth_engine	ENGINE_get_pkey_asn1_meth_eng
+#undef ENGINE_set_load_ssl_client_cert_function
+#define ENGINE_set_load_ssl_client_cert_function \
+						ENGINE_set_ld_ssl_clnt_cert_fn
+#undef ENGINE_get_ssl_client_cert_function
+#define ENGINE_get_ssl_client_cert_function	ENGINE_get_ssl_client_cert_fn
+
+/* Hack some long OCSP names */
+#undef OCSP_REQUEST_get_ext_by_critical
+#define OCSP_REQUEST_get_ext_by_critical	OCSP_REQUEST_get_ext_by_crit
+#undef OCSP_BASICRESP_get_ext_by_critical
+#define OCSP_BASICRESP_get_ext_by_critical      OCSP_BASICRESP_get_ext_by_crit
+#undef OCSP_SINGLERESP_get_ext_by_critical
+#define OCSP_SINGLERESP_get_ext_by_critical     OCSP_SINGLERESP_get_ext_by_crit
+
+/* Hack some long DES names */
+#undef _ossl_old_des_ede3_cfb64_encrypt
+#define _ossl_old_des_ede3_cfb64_encrypt	_ossl_odes_ede3_cfb64_encrypt
+#undef _ossl_old_des_ede3_ofb64_encrypt
+#define _ossl_old_des_ede3_ofb64_encrypt	_ossl_odes_ede3_ofb64_encrypt
+
+/* Hack some long EVP names */
+#undef OPENSSL_add_all_algorithms_noconf
+#define OPENSSL_add_all_algorithms_noconf	OPENSSL_add_all_algo_noconf
+#undef OPENSSL_add_all_algorithms_conf
+#define OPENSSL_add_all_algorithms_conf		OPENSSL_add_all_algo_conf
+#undef EVP_PKEY_meth_set_verify_recover
+#define EVP_PKEY_meth_set_verify_recover	EVP_PKEY_meth_set_vrfy_recover
+
+/* Hack some long EC names */
+#undef EC_GROUP_set_point_conversion_form
+#define EC_GROUP_set_point_conversion_form	EC_GROUP_set_point_conv_form
+#undef EC_GROUP_get_point_conversion_form
+#define EC_GROUP_get_point_conversion_form	EC_GROUP_get_point_conv_form
+#undef EC_GROUP_clear_free_all_extra_data
+#define EC_GROUP_clear_free_all_extra_data	EC_GROUP_clr_free_all_xtra_data
+#undef EC_POINT_set_Jprojective_coordinates_GFp
+#define EC_POINT_set_Jprojective_coordinates_GFp \
+                                                EC_POINT_set_Jproj_coords_GFp
+#undef EC_POINT_get_Jprojective_coordinates_GFp
+#define EC_POINT_get_Jprojective_coordinates_GFp \
+                                                EC_POINT_get_Jproj_coords_GFp
+#undef EC_POINT_set_affine_coordinates_GFp
+#define EC_POINT_set_affine_coordinates_GFp     EC_POINT_set_affine_coords_GFp
+#undef EC_POINT_get_affine_coordinates_GFp
+#define EC_POINT_get_affine_coordinates_GFp     EC_POINT_get_affine_coords_GFp
+#undef EC_POINT_set_compressed_coordinates_GFp
+#define EC_POINT_set_compressed_coordinates_GFp EC_POINT_set_compr_coords_GFp
+#undef EC_POINT_set_affine_coordinates_GF2m
+#define EC_POINT_set_affine_coordinates_GF2m    EC_POINT_set_affine_coords_GF2m
+#undef EC_POINT_get_affine_coordinates_GF2m
+#define EC_POINT_get_affine_coordinates_GF2m    EC_POINT_get_affine_coords_GF2m
+#undef EC_POINT_set_compressed_coordinates_GF2m
+#define EC_POINT_set_compressed_coordinates_GF2m \
+                                                EC_POINT_set_compr_coords_GF2m
+#undef ec_GF2m_simple_group_clear_finish
+#define ec_GF2m_simple_group_clear_finish	ec_GF2m_simple_grp_clr_finish
+#undef ec_GF2m_simple_group_check_discriminant
+#define ec_GF2m_simple_group_check_discriminant	ec_GF2m_simple_grp_chk_discrim
+#undef ec_GF2m_simple_point_clear_finish
+#define ec_GF2m_simple_point_clear_finish	ec_GF2m_simple_pt_clr_finish
+#undef ec_GF2m_simple_point_set_to_infinity
+#define ec_GF2m_simple_point_set_to_infinity	ec_GF2m_simple_pt_set_to_inf
+#undef ec_GF2m_simple_points_make_affine
+#define ec_GF2m_simple_points_make_affine	ec_GF2m_simple_pts_make_affine
+#undef ec_GF2m_simple_point_set_affine_coordinates
+#define ec_GF2m_simple_point_set_affine_coordinates \
+                                                ec_GF2m_smp_pt_set_af_coords
+#undef ec_GF2m_simple_point_get_affine_coordinates
+#define ec_GF2m_simple_point_get_affine_coordinates \
+                                                ec_GF2m_smp_pt_get_af_coords
+#undef ec_GF2m_simple_set_compressed_coordinates
+#define ec_GF2m_simple_set_compressed_coordinates \
+                                                ec_GF2m_smp_set_compr_coords
+#undef ec_GFp_simple_group_set_curve_GFp
+#define ec_GFp_simple_group_set_curve_GFp       ec_GFp_simple_grp_set_curve_GFp
+#undef ec_GFp_simple_group_get_curve_GFp
+#define ec_GFp_simple_group_get_curve_GFp       ec_GFp_simple_grp_get_curve_GFp
+#undef ec_GFp_simple_group_clear_finish
+#define ec_GFp_simple_group_clear_finish	ec_GFp_simple_grp_clear_finish
+#undef ec_GFp_simple_group_set_generator
+#define ec_GFp_simple_group_set_generator       ec_GFp_simple_grp_set_generator
+#undef ec_GFp_simple_group_get0_generator
+#define ec_GFp_simple_group_get0_generator      ec_GFp_simple_grp_gt0_generator
+#undef ec_GFp_simple_group_get_cofactor
+#define ec_GFp_simple_group_get_cofactor	ec_GFp_simple_grp_get_cofactor
+#undef ec_GFp_simple_point_clear_finish
+#define ec_GFp_simple_point_clear_finish	ec_GFp_simple_pt_clear_finish
+#undef ec_GFp_simple_point_set_to_infinity
+#define ec_GFp_simple_point_set_to_infinity     ec_GFp_simple_pt_set_to_inf
+#undef ec_GFp_simple_points_make_affine
+#define ec_GFp_simple_points_make_affine	ec_GFp_simple_pts_make_affine
+#undef ec_GFp_simple_group_get_curve_GFp
+#define ec_GFp_simple_group_get_curve_GFp       ec_GFp_simple_grp_get_curve_GFp
+#undef ec_GFp_simple_set_Jprojective_coordinates_GFp
+#define ec_GFp_simple_set_Jprojective_coordinates_GFp \
+                                                ec_GFp_smp_set_Jproj_coords_GFp
+#undef ec_GFp_simple_get_Jprojective_coordinates_GFp
+#define ec_GFp_simple_get_Jprojective_coordinates_GFp \
+                                                ec_GFp_smp_get_Jproj_coords_GFp
+#undef ec_GFp_simple_point_set_affine_coordinates_GFp
+#define ec_GFp_simple_point_set_affine_coordinates_GFp \
+                                                ec_GFp_smp_pt_set_af_coords_GFp
+#undef ec_GFp_simple_point_get_affine_coordinates_GFp
+#define ec_GFp_simple_point_get_affine_coordinates_GFp \
+                                                ec_GFp_smp_pt_get_af_coords_GFp
+#undef ec_GFp_simple_set_compressed_coordinates_GFp
+#define ec_GFp_simple_set_compressed_coordinates_GFp \
+                                                ec_GFp_smp_set_compr_coords_GFp
+#undef ec_GFp_simple_point_set_affine_coordinates
+#define ec_GFp_simple_point_set_affine_coordinates \
+                                                ec_GFp_smp_pt_set_af_coords
+#undef ec_GFp_simple_point_get_affine_coordinates
+#define ec_GFp_simple_point_get_affine_coordinates \
+                                                ec_GFp_smp_pt_get_af_coords
+#undef ec_GFp_simple_set_compressed_coordinates
+#define ec_GFp_simple_set_compressed_coordinates \
+                                                ec_GFp_smp_set_compr_coords
+#undef ec_GFp_simple_group_check_discriminant
+#define ec_GFp_simple_group_check_discriminant	ec_GFp_simple_grp_chk_discrim
+
+/* Hack som long STORE names */
+#undef STORE_method_set_initialise_function
+#define STORE_method_set_initialise_function	STORE_meth_set_initialise_fn
+#undef STORE_method_set_cleanup_function
+#define STORE_method_set_cleanup_function	STORE_meth_set_cleanup_fn
+#undef STORE_method_set_generate_function
+#define STORE_method_set_generate_function	STORE_meth_set_generate_fn
+#undef STORE_method_set_modify_function
+#define STORE_method_set_modify_function	STORE_meth_set_modify_fn
+#undef STORE_method_set_revoke_function
+#define STORE_method_set_revoke_function	STORE_meth_set_revoke_fn
+#undef STORE_method_set_delete_function
+#define STORE_method_set_delete_function	STORE_meth_set_delete_fn
+#undef STORE_method_set_list_start_function
+#define STORE_method_set_list_start_function	STORE_meth_set_list_start_fn
+#undef STORE_method_set_list_next_function
+#define STORE_method_set_list_next_function	STORE_meth_set_list_next_fn
+#undef STORE_method_set_list_end_function
+#define STORE_method_set_list_end_function	STORE_meth_set_list_end_fn
+#undef STORE_method_set_update_store_function
+#define STORE_method_set_update_store_function	STORE_meth_set_update_store_fn
+#undef STORE_method_set_lock_store_function
+#define STORE_method_set_lock_store_function	STORE_meth_set_lock_store_fn
+#undef STORE_method_set_unlock_store_function
+#define STORE_method_set_unlock_store_function	STORE_meth_set_unlock_store_fn
+#undef STORE_method_get_initialise_function
+#define STORE_method_get_initialise_function	STORE_meth_get_initialise_fn
+#undef STORE_method_get_cleanup_function
+#define STORE_method_get_cleanup_function	STORE_meth_get_cleanup_fn
+#undef STORE_method_get_generate_function
+#define STORE_method_get_generate_function	STORE_meth_get_generate_fn
+#undef STORE_method_get_modify_function
+#define STORE_method_get_modify_function	STORE_meth_get_modify_fn
+#undef STORE_method_get_revoke_function
+#define STORE_method_get_revoke_function	STORE_meth_get_revoke_fn
+#undef STORE_method_get_delete_function
+#define STORE_method_get_delete_function	STORE_meth_get_delete_fn
+#undef STORE_method_get_list_start_function
+#define STORE_method_get_list_start_function	STORE_meth_get_list_start_fn
+#undef STORE_method_get_list_next_function
+#define STORE_method_get_list_next_function	STORE_meth_get_list_next_fn
+#undef STORE_method_get_list_end_function
+#define STORE_method_get_list_end_function	STORE_meth_get_list_end_fn
+#undef STORE_method_get_update_store_function
+#define STORE_method_get_update_store_function	STORE_meth_get_update_store_fn
+#undef STORE_method_get_lock_store_function
+#define STORE_method_get_lock_store_function	STORE_meth_get_lock_store_fn
+#undef STORE_method_get_unlock_store_function
+#define STORE_method_get_unlock_store_function	STORE_meth_get_unlock_store_fn
+
+/* Hack some long TS names */
+#undef TS_RESP_CTX_set_status_info_cond
+#define TS_RESP_CTX_set_status_info_cond	TS_RESP_CTX_set_stat_info_cond
+#undef TS_RESP_CTX_set_clock_precision_digits
+#define TS_RESP_CTX_set_clock_precision_digits	TS_RESP_CTX_set_clk_prec_digits
+#undef TS_CONF_set_clock_precision_digits
+#define TS_CONF_set_clock_precision_digits	TS_CONF_set_clk_prec_digits
+
+/* Hack some long CMS names */
+#undef CMS_RecipientInfo_ktri_get0_algs
+#define CMS_RecipientInfo_ktri_get0_algs	CMS_RecipInfo_ktri_get0_algs
+#undef CMS_RecipientInfo_ktri_get0_signer_id
+#define CMS_RecipientInfo_ktri_get0_signer_id	CMS_RecipInfo_ktri_get0_sigr_id
+#undef CMS_OtherRevocationInfoFormat_it
+#define CMS_OtherRevocationInfoFormat_it	CMS_OtherRevocInfoFormat_it
+#undef CMS_KeyAgreeRecipientIdentifier_it
+#define CMS_KeyAgreeRecipientIdentifier_it	CMS_KeyAgreeRecipIdentifier_it
+#undef CMS_OriginatorIdentifierOrKey_it
+#define CMS_OriginatorIdentifierOrKey_it	CMS_OriginatorIdOrKey_it
+#undef cms_SignerIdentifier_get0_signer_id
+#define cms_SignerIdentifier_get0_signer_id	cms_SignerId_get0_signer_id
+
+/* Hack some long DTLS1 names */
+#undef dtls1_retransmit_buffered_messages
+#define dtls1_retransmit_buffered_messages	dtls1_retransmit_buffered_msgs
+
+/* Hack some long UI names */
+#undef UI_method_get_prompt_constructor
+#define UI_method_get_prompt_constructor	UI_method_get_prompt_constructr
+#undef UI_method_set_prompt_constructor
+#define UI_method_set_prompt_constructor	UI_method_set_prompt_constructr
+
+#endif /* defined OPENSSL_SYS_VMS */
+
+
+/* Case insensitive linking causes problems.... */
+#if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2)
+#undef ERR_load_CRYPTO_strings
+#define ERR_load_CRYPTO_strings			ERR_load_CRYPTOlib_strings
+#undef OCSP_crlID_new
+#define OCSP_crlID_new				OCSP_crlID2_new
+
+#undef d2i_ECPARAMETERS
+#define d2i_ECPARAMETERS			d2i_UC_ECPARAMETERS
+#undef i2d_ECPARAMETERS
+#define i2d_ECPARAMETERS			i2d_UC_ECPARAMETERS
+#undef d2i_ECPKPARAMETERS
+#define d2i_ECPKPARAMETERS			d2i_UC_ECPKPARAMETERS
+#undef i2d_ECPKPARAMETERS
+#define i2d_ECPKPARAMETERS			i2d_UC_ECPKPARAMETERS
+
+/* These functions do not seem to exist!  However, I'm paranoid...
+   Original command in x509v3.h:
+   These functions are being redefined in another directory,
+   and clash when the linker is case-insensitive, so let's
+   hide them a little, by giving them an extra 'o' at the
+   beginning of the name... */
+#undef X509v3_cleanup_extensions
+#define X509v3_cleanup_extensions		oX509v3_cleanup_extensions
+#undef X509v3_add_extension
+#define X509v3_add_extension			oX509v3_add_extension
+#undef X509v3_add_netscape_extensions
+#define X509v3_add_netscape_extensions		oX509v3_add_netscape_extensions
+#undef X509v3_add_standard_extensions
+#define X509v3_add_standard_extensions		oX509v3_add_standard_extensions
+
+/* This one clashes with CMS_data_create */
+#undef cms_Data_create
+#define cms_Data_create				priv_cms_Data_create
+
+#endif
+
+
+#endif /* ! defined HEADER_VMS_IDHACKS_H */
diff --git a/openssl/crypto/threads/README b/openssl/crypto/threads/README
new file mode 100644
index 0000000..df6b26e
--- /dev/null
+++ b/openssl/crypto/threads/README
@@ -0,0 +1,14 @@
+Mutithreading testing area.
+
+Since this stuff is very very platorm specific, this is not part of the
+normal build.  Have a read of doc/threads.doc.
+
+mttest will do some testing and will currently build under Windows NT/95,
+Solaris and Linux.  The IRIX stuff is not finished.
+
+I have tested this program on a 12 CPU ultra sparc box (solaris 2.5.1)
+and things seem to work ok.
+
+The Linux pthreads package can be retrieved from 
+http://www.mit.edu:8001/people/proven/pthreads.html
+
diff --git a/openssl/crypto/threads/mttest.c b/openssl/crypto/threads/mttest.c
new file mode 100644
index 0000000..eba7aa8
--- /dev/null
+++ b/openssl/crypto/threads/mttest.c
@@ -0,0 +1,1310 @@
+/* crypto/threads/mttest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#ifdef LINUX
+#include <typedefs.h>
+#endif
+#ifdef OPENSSL_SYS_WIN32
+#include <windows.h>
+#endif
+#ifdef SOLARIS
+#include <synch.h>
+#include <thread.h>
+#endif
+#ifdef IRIX
+#include <ulocks.h>
+#include <sys/prctl.h>
+#endif
+#ifdef PTHREADS
+#include <pthread.h>
+#endif
+#ifdef OPENSSL_SYS_NETWARE
+#if !defined __int64
+#  define __int64 long long
+#endif   
+#include <nwmpk.h>
+#endif
+#include <openssl/lhash.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include "../../e_os.h"
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+#ifdef OPENSSL_NO_FP_API
+#define APPS_WIN16
+#include "../buffer/bss_file.c"
+#endif
+
+#ifdef OPENSSL_SYS_NETWARE
+#define TEST_SERVER_CERT "/openssl/apps/server.pem"
+#define TEST_CLIENT_CERT "/openssl/apps/client.pem"
+#else
+#define TEST_SERVER_CERT "../../apps/server.pem"
+#define TEST_CLIENT_CERT "../../apps/client.pem"
+#endif
+
+#define MAX_THREAD_NUMBER	100
+
+int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *xs);
+void thread_setup(void);
+void thread_cleanup(void);
+void do_threads(SSL_CTX *s_ctx,SSL_CTX *c_ctx);
+
+void irix_locking_callback(int mode,int type,char *file,int line);
+void solaris_locking_callback(int mode,int type,char *file,int line);
+void win32_locking_callback(int mode,int type,char *file,int line);
+void pthreads_locking_callback(int mode,int type,char *file,int line);
+void netware_locking_callback(int mode,int type,char *file,int line);
+void beos_locking_callback(int mode,int type,const char *file,int line);
+
+unsigned long irix_thread_id(void );
+unsigned long solaris_thread_id(void );
+unsigned long pthreads_thread_id(void );
+unsigned long netware_thread_id(void );
+unsigned long beos_thread_id(void );
+
+#if defined(OPENSSL_SYS_NETWARE)
+static MPKMutex *lock_cs;
+static MPKSema ThreadSem;
+static long *lock_count;
+#endif
+
+BIO *bio_err=NULL;
+BIO *bio_stdout=NULL;
+
+static char *cipher=NULL;
+int verbose=0;
+#ifdef FIONBIO
+static int s_nbio=0;
+#endif
+
+int thread_number=10;
+int number_of_loops=10;
+int reconnect=0;
+int cache_stats=0;
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+int doit(char *ctx[4]);
+static void print_stats(FILE *fp, SSL_CTX *ctx)
+{
+	fprintf(fp,"%4ld items in the session cache\n",
+		SSL_CTX_sess_number(ctx));
+	fprintf(fp,"%4d client connects (SSL_connect())\n",
+		SSL_CTX_sess_connect(ctx));
+	fprintf(fp,"%4d client connects that finished\n",
+		SSL_CTX_sess_connect_good(ctx));
+	fprintf(fp,"%4d server connects (SSL_accept())\n",
+		SSL_CTX_sess_accept(ctx));
+	fprintf(fp,"%4d server connects that finished\n",
+		SSL_CTX_sess_accept_good(ctx));
+	fprintf(fp,"%4d session cache hits\n",SSL_CTX_sess_hits(ctx));
+	fprintf(fp,"%4d session cache misses\n",SSL_CTX_sess_misses(ctx));
+	fprintf(fp,"%4d session cache timeouts\n",SSL_CTX_sess_timeouts(ctx));
+	}
+
+static void sv_usage(void)
+	{
+	fprintf(stderr,"usage: ssltest [args ...]\n");
+	fprintf(stderr,"\n");
+	fprintf(stderr," -server_auth  - check server certificate\n");
+	fprintf(stderr," -client_auth  - do client authentication\n");
+	fprintf(stderr," -v            - more output\n");
+	fprintf(stderr," -CApath arg   - PEM format directory of CA's\n");
+	fprintf(stderr," -CAfile arg   - PEM format file of CA's\n");
+	fprintf(stderr," -threads arg  - number of threads\n");
+	fprintf(stderr," -loops arg    - number of 'connections', per thread\n");
+	fprintf(stderr," -reconnect    - reuse session-id's\n");
+	fprintf(stderr," -stats        - server session-id cache stats\n");
+	fprintf(stderr," -cert arg     - server certificate/key\n");
+	fprintf(stderr," -ccert arg    - client certificate/key\n");
+	fprintf(stderr," -ssl3         - just SSLv3n\n");
+	}
+
+int main(int argc, char *argv[])
+	{
+	char *CApath=NULL,*CAfile=NULL;
+	int badop=0;
+	int ret=1;
+	int client_auth=0;
+	int server_auth=0;
+	SSL_CTX *s_ctx=NULL;
+	SSL_CTX *c_ctx=NULL;
+	char *scert=TEST_SERVER_CERT;
+	char *ccert=TEST_CLIENT_CERT;
+	SSL_METHOD *ssl_method=SSLv23_method();
+
+	RAND_seed(rnd_seed, sizeof rnd_seed);
+
+	if (bio_err == NULL)
+		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+	if (bio_stdout == NULL)
+		bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE);
+	argc--;
+	argv++;
+
+	while (argc >= 1)
+		{
+		if	(strcmp(*argv,"-server_auth") == 0)
+			server_auth=1;
+		else if	(strcmp(*argv,"-client_auth") == 0)
+			client_auth=1;
+		else if	(strcmp(*argv,"-reconnect") == 0)
+			reconnect=1;
+		else if	(strcmp(*argv,"-stats") == 0)
+			cache_stats=1;
+		else if	(strcmp(*argv,"-ssl3") == 0)
+			ssl_method=SSLv3_method();
+		else if	(strcmp(*argv,"-ssl2") == 0)
+			ssl_method=SSLv2_method();
+		else if	(strcmp(*argv,"-CApath") == 0)
+			{
+			if (--argc < 1) goto bad;
+			CApath= *(++argv);
+			}
+		else if	(strcmp(*argv,"-CAfile") == 0)
+			{
+			if (--argc < 1) goto bad;
+			CAfile= *(++argv);
+			}
+		else if	(strcmp(*argv,"-cert") == 0)
+			{
+			if (--argc < 1) goto bad;
+			scert= *(++argv);
+			}
+		else if	(strcmp(*argv,"-ccert") == 0)
+			{
+			if (--argc < 1) goto bad;
+			ccert= *(++argv);
+			}
+		else if	(strcmp(*argv,"-threads") == 0)
+			{
+			if (--argc < 1) goto bad;
+			thread_number= atoi(*(++argv));
+			if (thread_number == 0) thread_number=1;
+			if (thread_number > MAX_THREAD_NUMBER)
+				thread_number=MAX_THREAD_NUMBER;
+			}
+		else if	(strcmp(*argv,"-loops") == 0)
+			{
+			if (--argc < 1) goto bad;
+			number_of_loops= atoi(*(++argv));
+			if (number_of_loops == 0) number_of_loops=1;
+			}
+		else
+			{
+			fprintf(stderr,"unknown option %s\n",*argv);
+			badop=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+	if (badop)
+		{
+bad:
+		sv_usage();
+		goto end;
+		}
+
+	if (cipher == NULL && OPENSSL_issetugid() == 0)
+		cipher=getenv("SSL_CIPHER");
+
+	SSL_load_error_strings();
+	OpenSSL_add_ssl_algorithms();
+
+	c_ctx=SSL_CTX_new(ssl_method);
+	s_ctx=SSL_CTX_new(ssl_method);
+	if ((c_ctx == NULL) || (s_ctx == NULL))
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	SSL_CTX_set_session_cache_mode(s_ctx,
+		SSL_SESS_CACHE_NO_AUTO_CLEAR|SSL_SESS_CACHE_SERVER);
+	SSL_CTX_set_session_cache_mode(c_ctx,
+		SSL_SESS_CACHE_NO_AUTO_CLEAR|SSL_SESS_CACHE_SERVER);
+
+	if (!SSL_CTX_use_certificate_file(s_ctx,scert,SSL_FILETYPE_PEM))
+		{
+		ERR_print_errors(bio_err);
+		}
+	else if (!SSL_CTX_use_RSAPrivateKey_file(s_ctx,scert,SSL_FILETYPE_PEM))
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (client_auth)
+		{
+		SSL_CTX_use_certificate_file(c_ctx,ccert,
+			SSL_FILETYPE_PEM);
+		SSL_CTX_use_RSAPrivateKey_file(c_ctx,ccert,
+			SSL_FILETYPE_PEM);
+		}
+
+	if (	(!SSL_CTX_load_verify_locations(s_ctx,CAfile,CApath)) ||
+		(!SSL_CTX_set_default_verify_paths(s_ctx)) ||
+		(!SSL_CTX_load_verify_locations(c_ctx,CAfile,CApath)) ||
+		(!SSL_CTX_set_default_verify_paths(c_ctx)))
+		{
+		fprintf(stderr,"SSL_load_verify_locations\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (client_auth)
+		{
+		fprintf(stderr,"client authentication\n");
+		SSL_CTX_set_verify(s_ctx,
+			SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
+			verify_callback);
+		}
+	if (server_auth)
+		{
+		fprintf(stderr,"server authentication\n");
+		SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER,
+			verify_callback);
+		}
+
+	thread_setup();
+	do_threads(s_ctx,c_ctx);
+	thread_cleanup();
+end:
+	
+	if (c_ctx != NULL) 
+		{
+		fprintf(stderr,"Client SSL_CTX stats then free it\n");
+		print_stats(stderr,c_ctx);
+		SSL_CTX_free(c_ctx);
+		}
+	if (s_ctx != NULL)
+		{
+		fprintf(stderr,"Server SSL_CTX stats then free it\n");
+		print_stats(stderr,s_ctx);
+		if (cache_stats)
+			{
+			fprintf(stderr,"-----\n");
+			lh_stats(SSL_CTX_sessions(s_ctx),stderr);
+			fprintf(stderr,"-----\n");
+		/*	lh_node_stats(SSL_CTX_sessions(s_ctx),stderr);
+			fprintf(stderr,"-----\n"); */
+			lh_node_usage_stats(SSL_CTX_sessions(s_ctx),stderr);
+			fprintf(stderr,"-----\n");
+			}
+		SSL_CTX_free(s_ctx);
+		fprintf(stderr,"done free\n");
+		}
+	exit(ret);
+	return(0);
+	}
+
+#define W_READ	1
+#define W_WRITE	2
+#define C_DONE	1
+#define S_DONE	2
+
+int ndoit(SSL_CTX *ssl_ctx[2])
+	{
+	int i;
+	int ret;
+	char *ctx[4];
+
+	ctx[0]=(char *)ssl_ctx[0];
+	ctx[1]=(char *)ssl_ctx[1];
+
+	if (reconnect)
+		{
+		ctx[2]=(char *)SSL_new(ssl_ctx[0]);
+		ctx[3]=(char *)SSL_new(ssl_ctx[1]);
+		}
+	else
+		{
+		ctx[2]=NULL;
+		ctx[3]=NULL;
+		}
+
+	fprintf(stdout,"started thread %lu\n",CRYPTO_thread_id());
+	for (i=0; i<number_of_loops; i++)
+		{
+/*		fprintf(stderr,"%4d %2d ctx->ref (%3d,%3d)\n",
+			CRYPTO_thread_id(),i,
+			ssl_ctx[0]->references,
+			ssl_ctx[1]->references); */
+	/*	pthread_delay_np(&tm);*/
+
+		ret=doit(ctx);
+		if (ret != 0)
+			{
+			fprintf(stdout,"error[%d] %lu - %d\n",
+				i,CRYPTO_thread_id(),ret);
+			return(ret);
+			}
+		}
+	fprintf(stdout,"DONE %lu\n",CRYPTO_thread_id());
+	if (reconnect)
+		{
+		SSL_free((SSL *)ctx[2]);
+		SSL_free((SSL *)ctx[3]);
+		}
+#   ifdef OPENSSL_SYS_NETWARE
+        MPKSemaphoreSignal(ThreadSem);
+#   endif
+	return(0);
+	}
+
+int doit(char *ctx[4])
+	{
+	SSL_CTX *s_ctx,*c_ctx;
+	static char cbuf[200],sbuf[200];
+	SSL *c_ssl=NULL;
+	SSL *s_ssl=NULL;
+	BIO *c_to_s=NULL;
+	BIO *s_to_c=NULL;
+	BIO *c_bio=NULL;
+	BIO *s_bio=NULL;
+	int c_r,c_w,s_r,s_w;
+	int c_want,s_want;
+	int i;
+	int done=0;
+	int c_write,s_write;
+	int do_server=0,do_client=0;
+
+	s_ctx=(SSL_CTX *)ctx[0];
+	c_ctx=(SSL_CTX *)ctx[1];
+
+	if (ctx[2] != NULL)
+		s_ssl=(SSL *)ctx[2];
+	else
+		s_ssl=SSL_new(s_ctx);
+
+	if (ctx[3] != NULL)
+		c_ssl=(SSL *)ctx[3];
+	else
+		c_ssl=SSL_new(c_ctx);
+
+	if ((s_ssl == NULL) || (c_ssl == NULL)) goto err;
+
+	c_to_s=BIO_new(BIO_s_mem());
+	s_to_c=BIO_new(BIO_s_mem());
+	if ((s_to_c == NULL) || (c_to_s == NULL)) goto err;
+
+	c_bio=BIO_new(BIO_f_ssl());
+	s_bio=BIO_new(BIO_f_ssl());
+	if ((c_bio == NULL) || (s_bio == NULL)) goto err;
+
+	SSL_set_connect_state(c_ssl);
+	SSL_set_bio(c_ssl,s_to_c,c_to_s);
+	BIO_set_ssl(c_bio,c_ssl,(ctx[2] == NULL)?BIO_CLOSE:BIO_NOCLOSE);
+
+	SSL_set_accept_state(s_ssl);
+	SSL_set_bio(s_ssl,c_to_s,s_to_c);
+	BIO_set_ssl(s_bio,s_ssl,(ctx[3] == NULL)?BIO_CLOSE:BIO_NOCLOSE);
+
+	c_r=0; s_r=1;
+	c_w=1; s_w=0;
+	c_want=W_WRITE;
+	s_want=0;
+	c_write=1,s_write=0;
+
+	/* We can always do writes */
+	for (;;)
+		{
+		do_server=0;
+		do_client=0;
+
+		i=(int)BIO_pending(s_bio);
+		if ((i && s_r) || s_w) do_server=1;
+
+		i=(int)BIO_pending(c_bio);
+		if ((i && c_r) || c_w) do_client=1;
+
+		if (do_server && verbose)
+			{
+			if (SSL_in_init(s_ssl))
+				printf("server waiting in SSL_accept - %s\n",
+					SSL_state_string_long(s_ssl));
+			else if (s_write)
+				printf("server:SSL_write()\n");
+			else 
+				printf("server:SSL_read()\n");
+			}
+
+		if (do_client && verbose)
+			{
+			if (SSL_in_init(c_ssl))
+				printf("client waiting in SSL_connect - %s\n",
+					SSL_state_string_long(c_ssl));
+			else if (c_write)
+				printf("client:SSL_write()\n");
+			else
+				printf("client:SSL_read()\n");
+			}
+
+		if (!do_client && !do_server)
+			{
+			fprintf(stdout,"ERROR IN STARTUP\n");
+			break;
+			}
+		if (do_client && !(done & C_DONE))
+			{
+			if (c_write)
+				{
+				i=BIO_write(c_bio,"hello from client\n",18);
+				if (i < 0)
+					{
+					c_r=0;
+					c_w=0;
+					if (BIO_should_retry(c_bio))
+						{
+						if (BIO_should_read(c_bio))
+							c_r=1;
+						if (BIO_should_write(c_bio))
+							c_w=1;
+						}
+					else
+						{
+						fprintf(stderr,"ERROR in CLIENT\n");
+						ERR_print_errors_fp(stderr);
+						return(1);
+						}
+					}
+				else if (i == 0)
+					{
+					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
+					return(1);
+					}
+				else
+					{
+					/* ok */
+					c_write=0;
+					}
+				}
+			else
+				{
+				i=BIO_read(c_bio,cbuf,100);
+				if (i < 0)
+					{
+					c_r=0;
+					c_w=0;
+					if (BIO_should_retry(c_bio))
+						{
+						if (BIO_should_read(c_bio))
+							c_r=1;
+						if (BIO_should_write(c_bio))
+							c_w=1;
+						}
+					else
+						{
+						fprintf(stderr,"ERROR in CLIENT\n");
+						ERR_print_errors_fp(stderr);
+						return(1);
+						}
+					}
+				else if (i == 0)
+					{
+					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
+					return(1);
+					}
+				else
+					{
+					done|=C_DONE;
+#ifdef undef
+					fprintf(stdout,"CLIENT:from server:");
+					fwrite(cbuf,1,i,stdout);
+					fflush(stdout);
+#endif
+					}
+				}
+			}
+
+		if (do_server && !(done & S_DONE))
+			{
+			if (!s_write)
+				{
+				i=BIO_read(s_bio,sbuf,100);
+				if (i < 0)
+					{
+					s_r=0;
+					s_w=0;
+					if (BIO_should_retry(s_bio))
+						{
+						if (BIO_should_read(s_bio))
+							s_r=1;
+						if (BIO_should_write(s_bio))
+							s_w=1;
+						}
+					else
+						{
+						fprintf(stderr,"ERROR in SERVER\n");
+						ERR_print_errors_fp(stderr);
+						return(1);
+						}
+					}
+				else if (i == 0)
+					{
+					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
+					return(1);
+					}
+				else
+					{
+					s_write=1;
+					s_w=1;
+#ifdef undef
+					fprintf(stdout,"SERVER:from client:");
+					fwrite(sbuf,1,i,stdout);
+					fflush(stdout);
+#endif
+					}
+				}
+			else
+				{
+				i=BIO_write(s_bio,"hello from server\n",18);
+				if (i < 0)
+					{
+					s_r=0;
+					s_w=0;
+					if (BIO_should_retry(s_bio))
+						{
+						if (BIO_should_read(s_bio))
+							s_r=1;
+						if (BIO_should_write(s_bio))
+							s_w=1;
+						}
+					else
+						{
+						fprintf(stderr,"ERROR in SERVER\n");
+						ERR_print_errors_fp(stderr);
+						return(1);
+						}
+					}
+				else if (i == 0)
+					{
+					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
+					return(1);
+					}
+				else
+					{
+					s_write=0;
+					s_r=1;
+					done|=S_DONE;
+					}
+				}
+			}
+
+		if ((done & S_DONE) && (done & C_DONE)) break;
+#   if defined(OPENSSL_SYS_NETWARE)
+        ThreadSwitchWithDelay();
+#   endif
+		}
+
+	SSL_set_shutdown(c_ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+	SSL_set_shutdown(s_ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+
+#ifdef undef
+	fprintf(stdout,"DONE\n");
+#endif
+err:
+	/* We have to set the BIO's to NULL otherwise they will be
+	 * free()ed twice.  Once when th s_ssl is SSL_free()ed and
+	 * again when c_ssl is SSL_free()ed.
+	 * This is a hack required because s_ssl and c_ssl are sharing the same
+	 * BIO structure and SSL_set_bio() and SSL_free() automatically
+	 * BIO_free non NULL entries.
+	 * You should not normally do this or be required to do this */
+
+	if (s_ssl != NULL)
+		{
+		s_ssl->rbio=NULL;
+		s_ssl->wbio=NULL;
+		}
+	if (c_ssl != NULL)
+		{
+		c_ssl->rbio=NULL;
+		c_ssl->wbio=NULL;
+		}
+
+	/* The SSL's are optionally freed in the following calls */
+	if (c_to_s != NULL) BIO_free(c_to_s);
+	if (s_to_c != NULL) BIO_free(s_to_c);
+
+	if (c_bio != NULL) BIO_free(c_bio);
+	if (s_bio != NULL) BIO_free(s_bio);
+	return(0);
+	}
+
+int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
+	{
+	char *s, buf[256];
+
+	if (verbose)
+		{
+		s=X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),
+				    buf,256);
+		if (s != NULL)
+			{
+			if (ok)
+				fprintf(stderr,"depth=%d %s\n",
+					ctx->error_depth,buf);
+			else
+				fprintf(stderr,"depth=%d error=%d %s\n",
+					ctx->error_depth,ctx->error,buf);
+			}
+		}
+	return(ok);
+	}
+
+#define THREAD_STACK_SIZE (16*1024)
+
+#ifdef OPENSSL_SYS_WIN32
+
+static HANDLE *lock_cs;
+
+void thread_setup(void)
+	{
+	int i;
+
+	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE));
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+		lock_cs[i]=CreateMutex(NULL,FALSE,NULL);
+		}
+
+	CRYPTO_set_locking_callback((void (*)(int,int,char *,int))win32_locking_callback);
+	/* id callback defined */
+	}
+
+void thread_cleanup(void)
+	{
+	int i;
+
+	CRYPTO_set_locking_callback(NULL);
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		CloseHandle(lock_cs[i]);
+	OPENSSL_free(lock_cs);
+	}
+
+void win32_locking_callback(int mode, int type, char *file, int line)
+	{
+	if (mode & CRYPTO_LOCK)
+		{
+		WaitForSingleObject(lock_cs[type],INFINITE);
+		}
+	else
+		{
+		ReleaseMutex(lock_cs[type]);
+		}
+	}
+
+void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
+	{
+	double ret;
+	SSL_CTX *ssl_ctx[2];
+	DWORD thread_id[MAX_THREAD_NUMBER];
+	HANDLE thread_handle[MAX_THREAD_NUMBER];
+	int i;
+	SYSTEMTIME start,end;
+
+	ssl_ctx[0]=s_ctx;
+	ssl_ctx[1]=c_ctx;
+
+	GetSystemTime(&start);
+	for (i=0; i<thread_number; i++)
+		{
+		thread_handle[i]=CreateThread(NULL,
+			THREAD_STACK_SIZE,
+			(LPTHREAD_START_ROUTINE)ndoit,
+			(void *)ssl_ctx,
+			0L,
+			&(thread_id[i]));
+		}
+
+	printf("reaping\n");
+	for (i=0; i<thread_number; i+=50)
+		{
+		int j;
+
+		j=(thread_number < (i+50))?(thread_number-i):50;
+
+		if (WaitForMultipleObjects(j,
+			(CONST HANDLE *)&(thread_handle[i]),TRUE,INFINITE)
+			== WAIT_FAILED)
+			{
+			fprintf(stderr,"WaitForMultipleObjects failed:%d\n",GetLastError());
+			exit(1);
+			}
+		}
+	GetSystemTime(&end);
+
+	if (start.wDayOfWeek > end.wDayOfWeek) end.wDayOfWeek+=7;
+	ret=(end.wDayOfWeek-start.wDayOfWeek)*24;
+
+	ret=(ret+end.wHour-start.wHour)*60;
+	ret=(ret+end.wMinute-start.wMinute)*60;
+	ret=(ret+end.wSecond-start.wSecond);
+	ret+=(end.wMilliseconds-start.wMilliseconds)/1000.0;
+
+	printf("win32 threads done - %.3f seconds\n",ret);
+	}
+
+#endif /* OPENSSL_SYS_WIN32 */
+
+#ifdef SOLARIS
+
+static mutex_t *lock_cs;
+/*static rwlock_t *lock_cs; */
+static long *lock_count;
+
+void thread_setup(void)
+	{
+	int i;
+
+	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(mutex_t));
+	lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+		lock_count[i]=0;
+		/* rwlock_init(&(lock_cs[i]),USYNC_THREAD,NULL); */
+		mutex_init(&(lock_cs[i]),USYNC_THREAD,NULL);
+		}
+
+	CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id);
+	CRYPTO_set_locking_callback((void (*)())solaris_locking_callback);
+	}
+
+void thread_cleanup(void)
+	{
+	int i;
+
+	CRYPTO_set_locking_callback(NULL);
+
+	fprintf(stderr,"cleanup\n");
+
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+		/* rwlock_destroy(&(lock_cs[i])); */
+		mutex_destroy(&(lock_cs[i]));
+		fprintf(stderr,"%8ld:%s\n",lock_count[i],CRYPTO_get_lock_name(i));
+		}
+	OPENSSL_free(lock_cs);
+	OPENSSL_free(lock_count);
+
+	fprintf(stderr,"done cleanup\n");
+
+	}
+
+void solaris_locking_callback(int mode, int type, char *file, int line)
+	{
+#ifdef undef
+	fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
+		CRYPTO_thread_id(),
+		(mode&CRYPTO_LOCK)?"l":"u",
+		(type&CRYPTO_READ)?"r":"w",file,line);
+#endif
+
+	/*
+	if (CRYPTO_LOCK_SSL_CERT == type)
+	fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
+		CRYPTO_thread_id(),
+		mode,file,line);
+	*/
+	if (mode & CRYPTO_LOCK)
+		{
+	/*	if (mode & CRYPTO_READ)
+			rw_rdlock(&(lock_cs[type]));
+		else
+			rw_wrlock(&(lock_cs[type])); */
+
+		mutex_lock(&(lock_cs[type]));
+		lock_count[type]++;
+		}
+	else
+		{
+/*		rw_unlock(&(lock_cs[type]));  */
+		mutex_unlock(&(lock_cs[type]));
+		}
+	}
+
+void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
+	{
+	SSL_CTX *ssl_ctx[2];
+	thread_t thread_ctx[MAX_THREAD_NUMBER];
+	int i;
+
+	ssl_ctx[0]=s_ctx;
+	ssl_ctx[1]=c_ctx;
+
+	thr_setconcurrency(thread_number);
+	for (i=0; i<thread_number; i++)
+		{
+		thr_create(NULL, THREAD_STACK_SIZE,
+			(void *(*)())ndoit,
+			(void *)ssl_ctx,
+			0L,
+			&(thread_ctx[i]));
+		}
+
+	printf("reaping\n");
+	for (i=0; i<thread_number; i++)
+		{
+		thr_join(thread_ctx[i],NULL,NULL);
+		}
+
+	printf("solaris threads done (%d,%d)\n",
+		s_ctx->references,c_ctx->references);
+	}
+
+unsigned long solaris_thread_id(void)
+	{
+	unsigned long ret;
+
+	ret=(unsigned long)thr_self();
+	return(ret);
+	}
+#endif /* SOLARIS */
+
+#ifdef IRIX
+
+
+static usptr_t *arena;
+static usema_t **lock_cs;
+
+void thread_setup(void)
+	{
+	int i;
+	char filename[20];
+
+	strcpy(filename,"/tmp/mttest.XXXXXX");
+	mktemp(filename);
+
+	usconfig(CONF_STHREADIOOFF);
+	usconfig(CONF_STHREADMALLOCOFF);
+	usconfig(CONF_INITUSERS,100);
+	usconfig(CONF_LOCKTYPE,US_DEBUGPLUS);
+	arena=usinit(filename);
+	unlink(filename);
+
+	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(usema_t *));
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+		lock_cs[i]=usnewsema(arena,1);
+		}
+
+	CRYPTO_set_id_callback((unsigned long (*)())irix_thread_id);
+	CRYPTO_set_locking_callback((void (*)())irix_locking_callback);
+	}
+
+void thread_cleanup(void)
+	{
+	int i;
+
+	CRYPTO_set_locking_callback(NULL);
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+		char buf[10];
+
+		sprintf(buf,"%2d:",i);
+		usdumpsema(lock_cs[i],stdout,buf);
+		usfreesema(lock_cs[i],arena);
+		}
+	OPENSSL_free(lock_cs);
+	}
+
+void irix_locking_callback(int mode, int type, char *file, int line)
+	{
+	if (mode & CRYPTO_LOCK)
+		{
+		printf("lock %d\n",type);
+		uspsema(lock_cs[type]);
+		}
+	else
+		{
+		printf("unlock %d\n",type);
+		usvsema(lock_cs[type]);
+		}
+	}
+
+void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
+	{
+	SSL_CTX *ssl_ctx[2];
+	int thread_ctx[MAX_THREAD_NUMBER];
+	int i;
+
+	ssl_ctx[0]=s_ctx;
+	ssl_ctx[1]=c_ctx;
+
+	for (i=0; i<thread_number; i++)
+		{
+		thread_ctx[i]=sproc((void (*)())ndoit,
+			PR_SADDR|PR_SFDS,(void *)ssl_ctx);
+		}
+
+	printf("reaping\n");
+	for (i=0; i<thread_number; i++)
+		{
+		wait(NULL);
+		}
+
+	printf("irix threads done (%d,%d)\n",
+		s_ctx->references,c_ctx->references);
+	}
+
+unsigned long irix_thread_id(void)
+	{
+	unsigned long ret;
+
+	ret=(unsigned long)getpid();
+	return(ret);
+	}
+#endif /* IRIX */
+
+#ifdef PTHREADS
+
+static pthread_mutex_t *lock_cs;
+static long *lock_count;
+
+void thread_setup(void)
+	{
+	int i;
+
+	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
+	lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+		lock_count[i]=0;
+		pthread_mutex_init(&(lock_cs[i]),NULL);
+		}
+
+	CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
+	CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
+	}
+
+void thread_cleanup(void)
+	{
+	int i;
+
+	CRYPTO_set_locking_callback(NULL);
+	fprintf(stderr,"cleanup\n");
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+		pthread_mutex_destroy(&(lock_cs[i]));
+		fprintf(stderr,"%8ld:%s\n",lock_count[i],
+			CRYPTO_get_lock_name(i));
+		}
+	OPENSSL_free(lock_cs);
+	OPENSSL_free(lock_count);
+
+	fprintf(stderr,"done cleanup\n");
+	}
+
+void pthreads_locking_callback(int mode, int type, char *file,
+	     int line)
+      {
+#ifdef undef
+	fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
+		CRYPTO_thread_id(),
+		(mode&CRYPTO_LOCK)?"l":"u",
+		(type&CRYPTO_READ)?"r":"w",file,line);
+#endif
+/*
+	if (CRYPTO_LOCK_SSL_CERT == type)
+		fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
+		CRYPTO_thread_id(),
+		mode,file,line);
+*/
+	if (mode & CRYPTO_LOCK)
+		{
+		pthread_mutex_lock(&(lock_cs[type]));
+		lock_count[type]++;
+		}
+	else
+		{
+		pthread_mutex_unlock(&(lock_cs[type]));
+		}
+	}
+
+void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
+	{
+	SSL_CTX *ssl_ctx[2];
+	pthread_t thread_ctx[MAX_THREAD_NUMBER];
+	int i;
+
+	ssl_ctx[0]=s_ctx;
+	ssl_ctx[1]=c_ctx;
+
+	/*
+	thr_setconcurrency(thread_number);
+	*/
+	for (i=0; i<thread_number; i++)
+		{
+		pthread_create(&(thread_ctx[i]), NULL,
+			(void *(*)())ndoit, (void *)ssl_ctx);
+		}
+
+	printf("reaping\n");
+	for (i=0; i<thread_number; i++)
+		{
+		pthread_join(thread_ctx[i],NULL);
+		}
+
+	printf("pthreads threads done (%d,%d)\n",
+		s_ctx->references,c_ctx->references);
+	}
+
+unsigned long pthreads_thread_id(void)
+	{
+	unsigned long ret;
+
+	ret=(unsigned long)pthread_self();
+	return(ret);
+	}
+
+#endif /* PTHREADS */
+
+
+
+#ifdef OPENSSL_SYS_NETWARE
+
+void thread_setup(void)
+{
+   int i;
+
+   lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(MPKMutex));
+   lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
+   for (i=0; i<CRYPTO_num_locks(); i++)
+   {
+      lock_count[i]=0;
+      lock_cs[i]=MPKMutexAlloc("OpenSSL mutex");
+   }
+
+   ThreadSem = MPKSemaphoreAlloc("OpenSSL mttest semaphore", 0 );
+
+   CRYPTO_set_id_callback((unsigned long (*)())netware_thread_id);
+   CRYPTO_set_locking_callback((void (*)())netware_locking_callback);
+}
+
+void thread_cleanup(void)
+{
+   int i;
+
+   CRYPTO_set_locking_callback(NULL);
+
+   fprintf(stdout,"thread_cleanup\n");
+
+   for (i=0; i<CRYPTO_num_locks(); i++)
+   {
+      MPKMutexFree(lock_cs[i]);
+      fprintf(stdout,"%8ld:%s\n",lock_count[i],CRYPTO_get_lock_name(i));
+   }
+   OPENSSL_free(lock_cs);
+   OPENSSL_free(lock_count);
+
+   MPKSemaphoreFree(ThreadSem);
+
+   fprintf(stdout,"done cleanup\n");
+}
+
+void netware_locking_callback(int mode, int type, char *file, int line)
+{
+   if (mode & CRYPTO_LOCK)
+   {
+      MPKMutexLock(lock_cs[type]);
+      lock_count[type]++;
+   }
+   else
+      MPKMutexUnlock(lock_cs[type]);
+}
+
+void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
+{
+   SSL_CTX *ssl_ctx[2];
+   int i;
+   ssl_ctx[0]=s_ctx;
+   ssl_ctx[1]=c_ctx;
+
+   for (i=0; i<thread_number; i++)
+   {
+      BeginThread( (void(*)(void*))ndoit, NULL, THREAD_STACK_SIZE, 
+                   (void*)ssl_ctx);
+      ThreadSwitchWithDelay();
+   }
+
+   printf("reaping\n");
+
+      /* loop until all threads have signaled the semaphore */
+   for (i=0; i<thread_number; i++)
+   {
+      MPKSemaphoreWait(ThreadSem);
+   }
+   printf("netware threads done (%d,%d)\n",
+         s_ctx->references,c_ctx->references);
+}
+
+unsigned long netware_thread_id(void)
+{
+   unsigned long ret;
+
+   ret=(unsigned long)GetThreadID();
+   return(ret);
+}
+#endif /* NETWARE */
+
+#ifdef BEOS_THREADS
+
+#include <Locker.h>
+
+static BLocker** lock_cs;
+static long* lock_count;
+
+void thread_setup(void)
+	{
+	int i;
+
+	lock_cs=(BLocker**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(BLocker*));
+	lock_count=(long*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+		lock_count[i]=0;
+		lock_cs[i] = new BLocker(CRYPTO_get_lock_name(i));
+		}
+
+	CRYPTO_set_id_callback((unsigned long (*)())beos_thread_id);
+	CRYPTO_set_locking_callback(beos_locking_callback);
+	}
+
+void thread_cleanup(void)
+	{
+	int i;
+
+	CRYPTO_set_locking_callback(NULL);
+	fprintf(stderr,"cleanup\n");
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+		delete lock_cs[i];
+		fprintf(stderr,"%8ld:%s\n",lock_count[i],
+			CRYPTO_get_lock_name(i));
+		}
+	OPENSSL_free(lock_cs);
+	OPENSSL_free(lock_count);
+
+	fprintf(stderr,"done cleanup\n");
+	}
+
+void beos_locking_callback(int mode, int type, const char *file, int line)
+    {
+#if 0
+	fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
+		CRYPTO_thread_id(),
+		(mode&CRYPTO_LOCK)?"l":"u",
+		(type&CRYPTO_READ)?"r":"w",file,line);
+#endif
+	if (mode & CRYPTO_LOCK)
+		{
+		lock_cs[type]->Lock();
+		lock_count[type]++;
+		}
+	else
+		{
+		lock_cs[type]->Unlock();
+		}
+	}
+
+void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
+	{
+	SSL_CTX *ssl_ctx[2];
+	thread_id thread_ctx[MAX_THREAD_NUMBER];
+	int i;
+
+	ssl_ctx[0]=s_ctx;
+	ssl_ctx[1]=c_ctx;
+
+	for (i=0; i<thread_number; i++)
+		{
+		thread_ctx[i] = spawn_thread((thread_func)ndoit,
+			NULL, B_NORMAL_PRIORITY, (void *)ssl_ctx);
+		resume_thread(thread_ctx[i]);
+		}
+
+	printf("waiting...\n");
+	for (i=0; i<thread_number; i++)
+		{
+		status_t result;
+		wait_for_thread(thread_ctx[i], &result);
+		}
+
+	printf("beos threads done (%d,%d)\n",
+		s_ctx->references,c_ctx->references);
+	}
+
+unsigned long beos_thread_id(void)
+	{
+	unsigned long ret;
+
+	ret=(unsigned long)find_thread(NULL);
+	return(ret);
+	}
+
+#endif /* BEOS_THREADS */
diff --git a/openssl/crypto/threads/netware.bat b/openssl/crypto/threads/netware.bat
new file mode 100644
index 0000000..0b3eca3
--- /dev/null
+++ b/openssl/crypto/threads/netware.bat
@@ -0,0 +1,79 @@
+@echo off
+rem batch file to build multi-thread test ( mttest.nlm )
+
+rem command line arguments:
+rem      debug => build using debug settings
+
+rem
+rem After building, copy mttest.nlm to the server and run it, you'll probably
+rem want to redirect stdout and stderr.  An example command line would be
+rem "mttest.nlm -thread 20 -loops 10 -CAfile \openssl\apps\server.pem >mttest.out 2>mttest.err"
+rem 
+
+del mttest.nlm
+
+set BLD_DEBUG=
+set CFLAGS=
+set LFLAGS=
+set LIBS=
+
+if "%1" == "DEBUG" set BLD_DEBUG=YES
+if "%1" == "debug" set BLD_DEBUG=YES
+
+if "%MWCIncludes%" == "" goto inc_error
+if "%PRELUDE%" == "" goto prelude_error
+if "%IMPORTS%" == "" goto imports_error
+
+set CFLAGS=-c -I..\..\outinc_nw -nosyspath -DOPENSSL_SYS_NETWARE -opt off -g -sym internal -maxerrors 20
+
+if "%BLD_DEBUG%" == "YES" set LIBS=..\..\out_nw.dbg\ssl.lib ..\..\out_nw.dbg\crypto.lib
+if "%BLD_DEBUG%" == ""  set LIBS=..\..\out_nw\ssl.lib ..\..\out_nw\crypto.lib
+
+set LFLAGS=-msgstyle gcc -zerobss -stacksize 32768 -nostdlib -sym internal 
+  
+rem generate command file for metrowerks
+echo.
+echo Generating Metrowerks command file: mttest.def
+echo # dynamically generated command file for metrowerks build > mttest.def
+echo IMPORT @%IMPORTS%\clib.imp              >> mttest.def 
+echo IMPORT @%IMPORTS%\threads.imp           >> mttest.def 
+echo IMPORT @%IMPORTS%\ws2nlm.imp            >> mttest.def 
+echo IMPORT GetProcessSwitchCount            >> mttest.def
+echo MODULE clib                             >> mttest.def 
+
+rem compile
+echo.
+echo Compiling mttest.c
+mwccnlm.exe mttest.c %CFLAGS% 
+if errorlevel 1 goto end
+
+rem link               
+echo.
+echo Linking mttest.nlm
+mwldnlm.exe %LFLAGS% -screenname mttest -commandfile mttest.def mttest.o "%PRELUDE%" %LIBS% -o mttest.nlm
+if errorlevel 1 goto end
+
+goto end
+
+:inc_error
+echo.
+echo Environment variable MWCIncludes is not set - see install.nw
+goto end
+
+:prelude_error
+echo.
+echo Environment variable PRELUDE is not set - see install.nw
+goto end
+
+:imports_error
+echo.
+echo Environment variable IMPORTS is not set - see install.nw
+goto end
+    
+    
+:end
+set BLD_DEBUG=
+set CFLAGS=
+set LFLAGS=
+set LIBS=
+
diff --git a/openssl/crypto/threads/profile.sh b/openssl/crypto/threads/profile.sh
new file mode 100644
index 0000000..6e3e342
--- /dev/null
+++ b/openssl/crypto/threads/profile.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+/bin/rm -f mttest
+cc -p -DSOLARIS -I../../include -g mttest.c -o mttest -L/usr/lib/libc -ldl -L../.. -lthread  -lssl -lcrypto -lnsl -lsocket
+
diff --git a/openssl/crypto/threads/ptest.bat b/openssl/crypto/threads/ptest.bat
new file mode 100755
index 0000000..4071b5f
--- /dev/null
+++ b/openssl/crypto/threads/ptest.bat
@@ -0,0 +1,4 @@
+del mttest.exe
+
+purify cl /O2 -DWIN32 /MD -I..\..\out mttest.c /Femttest ..\..\out\ssl32.lib ..\..\out\crypt32.lib
+
diff --git a/openssl/crypto/threads/pthread.sh b/openssl/crypto/threads/pthread.sh
new file mode 100644
index 0000000..f1c4982
--- /dev/null
+++ b/openssl/crypto/threads/pthread.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# build using pthreads
+#
+# http://www.mit.edu:8001/people/proven/pthreads.html
+#
+/bin/rm -f mttest
+pgcc -DPTHREADS -I../../include -g mttest.c -o mttest -L../.. -lssl -lcrypto 
+
diff --git a/openssl/crypto/threads/pthread2.sh b/openssl/crypto/threads/pthread2.sh
new file mode 100755
index 0000000..41264c6
--- /dev/null
+++ b/openssl/crypto/threads/pthread2.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+#
+# build using pthreads where it's already built into the system
+#
+/bin/rm -f mttest
+gcc -DPTHREADS -I../../include -g mttest.c -o mttest -L../.. -lssl -lcrypto -lpthread
+
diff --git a/openssl/crypto/threads/pthreads-vms.com b/openssl/crypto/threads/pthreads-vms.com
new file mode 100644
index 0000000..1cf92bd
--- /dev/null
+++ b/openssl/crypto/threads/pthreads-vms.com
@@ -0,0 +1,14 @@
+$! To compile mttest on VMS.
+$!
+$! WARNING: only tested with DEC C so far.
+$
+$ if (f$getsyi("cpu").lt.128)
+$ then
+$     arch := VAX
+$ else
+$     arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$     if (arch .eqs. "") then arch = "UNK"
+$ endif
+$ define/user openssl [--.include.openssl]
+$ cc/def=PTHREADS mttest.c
+$ link mttest,[--.'arch'.exe.ssl]libssl/lib,[--.'arch'.exe.crypto]libcrypto/lib
diff --git a/openssl/crypto/threads/purify.sh b/openssl/crypto/threads/purify.sh
new file mode 100644
index 0000000..6d44fe2
--- /dev/null
+++ b/openssl/crypto/threads/purify.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+/bin/rm -f mttest
+purify cc -DSOLARIS -I../../include -g mttest.c -o mttest -L../.. -lthread  -lssl -lcrypto -lnsl -lsocket
+
diff --git a/openssl/crypto/threads/solaris.sh b/openssl/crypto/threads/solaris.sh
new file mode 100644
index 0000000..bc93094
--- /dev/null
+++ b/openssl/crypto/threads/solaris.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+/bin/rm -f mttest
+cc -DSOLARIS -I../../include -g mttest.c -o mttest -L../.. -lthread  -lssl -lcrypto -lnsl -lsocket
+
diff --git a/openssl/crypto/threads/th-lock.c b/openssl/crypto/threads/th-lock.c
new file mode 100644
index 0000000..14aae5f
--- /dev/null
+++ b/openssl/crypto/threads/th-lock.c
@@ -0,0 +1,387 @@
+/* crypto/threads/th-lock.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#ifdef LINUX
+#include <typedefs.h>
+#endif
+#ifdef OPENSSL_SYS_WIN32
+#include <windows.h>
+#endif
+#ifdef SOLARIS
+#include <synch.h>
+#include <thread.h>
+#endif
+#ifdef IRIX
+#include <ulocks.h>
+#include <sys/prctl.h>
+#endif
+#ifdef PTHREADS
+#include <pthread.h>
+#endif
+#include <openssl/lhash.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include "../../e_os.h"
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+void CRYPTO_thread_setup(void);
+void CRYPTO_thread_cleanup(void);
+
+static void irix_locking_callback(int mode,int type,char *file,int line);
+static void solaris_locking_callback(int mode,int type,char *file,int line);
+static void win32_locking_callback(int mode,int type,char *file,int line);
+static void pthreads_locking_callback(int mode,int type,char *file,int line);
+
+static unsigned long irix_thread_id(void );
+static unsigned long solaris_thread_id(void );
+static unsigned long pthreads_thread_id(void );
+
+/* usage:
+ * CRYPTO_thread_setup();
+ * application code
+ * CRYPTO_thread_cleanup();
+ */
+
+#define THREAD_STACK_SIZE (16*1024)
+
+#ifdef OPENSSL_SYS_WIN32
+
+static HANDLE *lock_cs;
+
+void CRYPTO_thread_setup(void)
+	{
+	int i;
+
+	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE));
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+		lock_cs[i]=CreateMutex(NULL,FALSE,NULL);
+		}
+
+	CRYPTO_set_locking_callback((void (*)(int,int,char *,int))win32_locking_callback);
+	/* id callback defined */
+	return(1);
+	}
+
+static void CRYPTO_thread_cleanup(void)
+	{
+	int i;
+
+	CRYPTO_set_locking_callback(NULL);
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		CloseHandle(lock_cs[i]);
+	OPENSSL_free(lock_cs);
+	}
+
+void win32_locking_callback(int mode, int type, char *file, int line)
+	{
+	if (mode & CRYPTO_LOCK)
+		{
+		WaitForSingleObject(lock_cs[type],INFINITE);
+		}
+	else
+		{
+		ReleaseMutex(lock_cs[type]);
+		}
+	}
+
+#endif /* OPENSSL_SYS_WIN32 */
+
+#ifdef SOLARIS
+
+#define USE_MUTEX
+
+#ifdef USE_MUTEX
+static mutex_t *lock_cs;
+#else
+static rwlock_t *lock_cs;
+#endif
+static long *lock_count;
+
+void CRYPTO_thread_setup(void)
+	{
+	int i;
+
+#ifdef USE_MUTEX
+	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(mutex_t));
+#else
+	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(rwlock_t));
+#endif
+	lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+		lock_count[i]=0;
+#ifdef USE_MUTEX
+		mutex_init(&(lock_cs[i]),USYNC_THREAD,NULL);
+#else
+		rwlock_init(&(lock_cs[i]),USYNC_THREAD,NULL);
+#endif
+		}
+
+	CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id);
+	CRYPTO_set_locking_callback((void (*)())solaris_locking_callback);
+	}
+
+void CRYPTO_thread_cleanup(void)
+	{
+	int i;
+
+	CRYPTO_set_locking_callback(NULL);
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+#ifdef USE_MUTEX
+		mutex_destroy(&(lock_cs[i]));
+#else
+		rwlock_destroy(&(lock_cs[i]));
+#endif
+		}
+	OPENSSL_free(lock_cs);
+	OPENSSL_free(lock_count);
+	}
+
+void solaris_locking_callback(int mode, int type, char *file, int line)
+	{
+#if 0
+	fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
+		CRYPTO_thread_id(),
+		(mode&CRYPTO_LOCK)?"l":"u",
+		(type&CRYPTO_READ)?"r":"w",file,line);
+#endif
+
+#if 0
+	if (CRYPTO_LOCK_SSL_CERT == type)
+		fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
+			CRYPTO_thread_id(),
+			mode,file,line);
+#endif
+	if (mode & CRYPTO_LOCK)
+		{
+#ifdef USE_MUTEX
+		mutex_lock(&(lock_cs[type]));
+#else
+		if (mode & CRYPTO_READ)
+			rw_rdlock(&(lock_cs[type]));
+		else
+			rw_wrlock(&(lock_cs[type]));
+#endif
+		lock_count[type]++;
+		}
+	else
+		{
+#ifdef USE_MUTEX
+		mutex_unlock(&(lock_cs[type]));
+#else
+		rw_unlock(&(lock_cs[type]));
+#endif
+		}
+	}
+
+unsigned long solaris_thread_id(void)
+	{
+	unsigned long ret;
+
+	ret=(unsigned long)thr_self();
+	return(ret);
+	}
+#endif /* SOLARIS */
+
+#ifdef IRIX
+/* I don't think this works..... */
+
+static usptr_t *arena;
+static usema_t **lock_cs;
+
+void CRYPTO_thread_setup(void)
+	{
+	int i;
+	char filename[20];
+
+	strcpy(filename,"/tmp/mttest.XXXXXX");
+	mktemp(filename);
+
+	usconfig(CONF_STHREADIOOFF);
+	usconfig(CONF_STHREADMALLOCOFF);
+	usconfig(CONF_INITUSERS,100);
+	usconfig(CONF_LOCKTYPE,US_DEBUGPLUS);
+	arena=usinit(filename);
+	unlink(filename);
+
+	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(usema_t *));
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+		lock_cs[i]=usnewsema(arena,1);
+		}
+
+	CRYPTO_set_id_callback((unsigned long (*)())irix_thread_id);
+	CRYPTO_set_locking_callback((void (*)())irix_locking_callback);
+	}
+
+void CRYPTO_thread_cleanup(void)
+	{
+	int i;
+
+	CRYPTO_set_locking_callback(NULL);
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+		char buf[10];
+
+		sprintf(buf,"%2d:",i);
+		usdumpsema(lock_cs[i],stdout,buf);
+		usfreesema(lock_cs[i],arena);
+		}
+	OPENSSL_free(lock_cs);
+	}
+
+void irix_locking_callback(int mode, int type, char *file, int line)
+	{
+	if (mode & CRYPTO_LOCK)
+		{
+		uspsema(lock_cs[type]);
+		}
+	else
+		{
+		usvsema(lock_cs[type]);
+		}
+	}
+
+unsigned long irix_thread_id(void)
+	{
+	unsigned long ret;
+
+	ret=(unsigned long)getpid();
+	return(ret);
+	}
+#endif /* IRIX */
+
+/* Linux and a few others */
+#ifdef PTHREADS
+
+static pthread_mutex_t *lock_cs;
+static long *lock_count;
+
+void CRYPTO_thread_setup(void)
+	{
+	int i;
+
+	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
+	lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+		lock_count[i]=0;
+		pthread_mutex_init(&(lock_cs[i]),NULL);
+		}
+
+	CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
+	CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
+	}
+
+void thread_cleanup(void)
+	{
+	int i;
+
+	CRYPTO_set_locking_callback(NULL);
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+		pthread_mutex_destroy(&(lock_cs[i]));
+		}
+	OPENSSL_free(lock_cs);
+	OPENSSL_free(lock_count);
+	}
+
+void pthreads_locking_callback(int mode, int type, char *file,
+	     int line)
+      {
+#if 0
+	fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
+		CRYPTO_thread_id(),
+		(mode&CRYPTO_LOCK)?"l":"u",
+		(type&CRYPTO_READ)?"r":"w",file,line);
+#endif
+#if 0
+	if (CRYPTO_LOCK_SSL_CERT == type)
+		fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
+		CRYPTO_thread_id(),
+		mode,file,line);
+#endif
+	if (mode & CRYPTO_LOCK)
+		{
+		pthread_mutex_lock(&(lock_cs[type]));
+		lock_count[type]++;
+		}
+	else
+		{
+		pthread_mutex_unlock(&(lock_cs[type]));
+		}
+	}
+
+unsigned long pthreads_thread_id(void)
+	{
+	unsigned long ret;
+
+	ret=(unsigned long)pthread_self();
+	return(ret);
+	}
+
+#endif /* PTHREADS */
+
diff --git a/openssl/crypto/threads/win32.bat b/openssl/crypto/threads/win32.bat
new file mode 100755
index 0000000..ee6da80
--- /dev/null
+++ b/openssl/crypto/threads/win32.bat
@@ -0,0 +1,4 @@
+del mttest.exe
+
+cl /O2 -DWIN32 /MD -I..\..\out mttest.c /Femttest ..\..\out\ssleay32.lib ..\..\out\libeay32.lib
+
diff --git a/openssl/crypto/ts/Makefile b/openssl/crypto/ts/Makefile
new file mode 100644
index 0000000..c182345
--- /dev/null
+++ b/openssl/crypto/ts/Makefile
@@ -0,0 +1,269 @@
+#
+# SSLeay/crypto/ts/Makefile
+#
+
+DIR=	ts
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I../../include
+CFLAG = -g
+INSTALL_PREFIX=
+OPENSSLDIR=     /usr/local/ssl
+INSTALLTOP=/usr/local/ssl
+MAKEDEPPROG=	makedepend
+MAKEDEPEND=	$(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
+MAKEFILE=	Makefile
+AR=		ar r
+
+PEX_LIBS=
+EX_LIBS=
+ 
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL= Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=	ts_err.c ts_req_utils.c ts_req_print.c ts_rsp_utils.c ts_rsp_print.c \
+	ts_rsp_sign.c ts_rsp_verify.c ts_verify_ctx.c ts_lib.c ts_conf.c \
+	ts_asn1.c
+LIBOBJ= ts_err.o ts_req_utils.o ts_req_print.o ts_rsp_utils.o ts_rsp_print.o \
+	ts_rsp_sign.o ts_rsp_verify.o ts_verify_ctx.o ts_lib.o ts_conf.o \
+	ts_asn1.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= ts.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+test:
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff enc dec sign verify
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+ts_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+ts_asn1.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+ts_asn1.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+ts_asn1.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+ts_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ts_asn1.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ts_asn1.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+ts_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ts_asn1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+ts_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ts_asn1.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+ts_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+ts_asn1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ts_asn1.o: ../../include/openssl/ts.h ../../include/openssl/x509.h
+ts_asn1.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+ts_asn1.o: ts_asn1.c
+ts_conf.o: ../../e_os.h ../../include/openssl/asn1.h
+ts_conf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+ts_conf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+ts_conf.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+ts_conf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ts_conf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ts_conf.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+ts_conf.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+ts_conf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ts_conf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+ts_conf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
+ts_conf.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
+ts_conf.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+ts_conf.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ts_conf.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
+ts_conf.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ts_conf.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_conf.c
+ts_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ts_err.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+ts_err.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+ts_err.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+ts_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+ts_err.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+ts_err.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+ts_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ts_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+ts_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+ts_err.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+ts_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ts_err.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
+ts_err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ts_err.o: ../../include/openssl/x509v3.h ts_err.c
+ts_lib.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ts_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+ts_lib.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+ts_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+ts_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ts_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ts_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+ts_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ts_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+ts_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ts_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+ts_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+ts_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ts_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ts_lib.o: ../../include/openssl/x509v3.h ../cryptlib.h ts.h ts_lib.c
+ts_req_print.o: ../../e_os.h ../../include/openssl/asn1.h
+ts_req_print.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+ts_req_print.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+ts_req_print.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+ts_req_print.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+ts_req_print.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+ts_req_print.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+ts_req_print.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+ts_req_print.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ts_req_print.o: ../../include/openssl/opensslconf.h
+ts_req_print.o: ../../include/openssl/opensslv.h
+ts_req_print.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+ts_req_print.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+ts_req_print.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ts_req_print.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
+ts_req_print.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ts_req_print.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_req_print.c
+ts_req_utils.o: ../../e_os.h ../../include/openssl/asn1.h
+ts_req_utils.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+ts_req_utils.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+ts_req_utils.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+ts_req_utils.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ts_req_utils.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ts_req_utils.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+ts_req_utils.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ts_req_utils.o: ../../include/openssl/objects.h
+ts_req_utils.o: ../../include/openssl/opensslconf.h
+ts_req_utils.o: ../../include/openssl/opensslv.h
+ts_req_utils.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+ts_req_utils.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+ts_req_utils.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ts_req_utils.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
+ts_req_utils.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ts_req_utils.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_req_utils.c
+ts_rsp_print.o: ../../e_os.h ../../include/openssl/asn1.h
+ts_rsp_print.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+ts_rsp_print.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+ts_rsp_print.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+ts_rsp_print.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+ts_rsp_print.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+ts_rsp_print.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+ts_rsp_print.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+ts_rsp_print.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ts_rsp_print.o: ../../include/openssl/opensslconf.h
+ts_rsp_print.o: ../../include/openssl/opensslv.h
+ts_rsp_print.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+ts_rsp_print.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+ts_rsp_print.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ts_rsp_print.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+ts_rsp_print.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+ts_rsp_print.o: ../cryptlib.h ts.h ts_rsp_print.c
+ts_rsp_sign.o: ../../e_os.h ../../include/openssl/asn1.h
+ts_rsp_sign.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+ts_rsp_sign.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+ts_rsp_sign.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+ts_rsp_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ts_rsp_sign.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ts_rsp_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+ts_rsp_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ts_rsp_sign.o: ../../include/openssl/objects.h
+ts_rsp_sign.o: ../../include/openssl/opensslconf.h
+ts_rsp_sign.o: ../../include/openssl/opensslv.h
+ts_rsp_sign.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+ts_rsp_sign.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+ts_rsp_sign.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ts_rsp_sign.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
+ts_rsp_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ts_rsp_sign.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_rsp_sign.c
+ts_rsp_utils.o: ../../e_os.h ../../include/openssl/asn1.h
+ts_rsp_utils.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+ts_rsp_utils.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+ts_rsp_utils.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+ts_rsp_utils.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ts_rsp_utils.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ts_rsp_utils.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+ts_rsp_utils.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ts_rsp_utils.o: ../../include/openssl/objects.h
+ts_rsp_utils.o: ../../include/openssl/opensslconf.h
+ts_rsp_utils.o: ../../include/openssl/opensslv.h
+ts_rsp_utils.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+ts_rsp_utils.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+ts_rsp_utils.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ts_rsp_utils.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
+ts_rsp_utils.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ts_rsp_utils.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_rsp_utils.c
+ts_rsp_verify.o: ../../e_os.h ../../include/openssl/asn1.h
+ts_rsp_verify.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+ts_rsp_verify.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+ts_rsp_verify.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+ts_rsp_verify.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ts_rsp_verify.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ts_rsp_verify.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+ts_rsp_verify.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ts_rsp_verify.o: ../../include/openssl/objects.h
+ts_rsp_verify.o: ../../include/openssl/opensslconf.h
+ts_rsp_verify.o: ../../include/openssl/opensslv.h
+ts_rsp_verify.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+ts_rsp_verify.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+ts_rsp_verify.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ts_rsp_verify.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
+ts_rsp_verify.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ts_rsp_verify.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_rsp_verify.c
+ts_verify_ctx.o: ../../e_os.h ../../include/openssl/asn1.h
+ts_verify_ctx.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+ts_verify_ctx.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+ts_verify_ctx.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+ts_verify_ctx.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ts_verify_ctx.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ts_verify_ctx.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+ts_verify_ctx.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ts_verify_ctx.o: ../../include/openssl/objects.h
+ts_verify_ctx.o: ../../include/openssl/opensslconf.h
+ts_verify_ctx.o: ../../include/openssl/opensslv.h
+ts_verify_ctx.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+ts_verify_ctx.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+ts_verify_ctx.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ts_verify_ctx.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
+ts_verify_ctx.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ts_verify_ctx.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_verify_ctx.c
diff --git a/openssl/crypto/ts/ts.h b/openssl/crypto/ts/ts.h
new file mode 100644
index 0000000..190e8a1
--- /dev/null
+++ b/openssl/crypto/ts/ts.h
@@ -0,0 +1,861 @@
+/* crypto/ts/ts.h */
+/* Written by Zoltan Glozik (zglozik@opentsa.org) for the OpenSSL
+ * project 2002, 2003, 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_TS_H
+#define HEADER_TS_H
+
+#include <openssl/opensslconf.h>
+#include <openssl/symhacks.h>
+#ifndef OPENSSL_NO_BUFFER
+#include <openssl/buffer.h>
+#endif
+#ifndef OPENSSL_NO_EVP
+#include <openssl/evp.h>
+#endif
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#include <openssl/stack.h>
+#include <openssl/asn1.h>
+#include <openssl/safestack.h>
+
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+
+#include <openssl/evp.h>
+
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef WIN32
+/* Under Win32 this is defined in wincrypt.h */
+#undef X509_NAME
+#endif
+
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+/*
+MessageImprint ::= SEQUENCE  {
+     hashAlgorithm                AlgorithmIdentifier,
+     hashedMessage                OCTET STRING  }
+*/
+
+typedef struct TS_msg_imprint_st
+	{
+	X509_ALGOR *hash_algo;
+	ASN1_OCTET_STRING *hashed_msg;
+	} TS_MSG_IMPRINT;
+
+/*
+TimeStampReq ::= SEQUENCE  {
+   version                  INTEGER  { v1(1) },
+   messageImprint           MessageImprint,
+     --a hash algorithm OID and the hash value of the data to be
+     --time-stamped
+   reqPolicy                TSAPolicyId                OPTIONAL,
+   nonce                    INTEGER                    OPTIONAL,
+   certReq                  BOOLEAN                    DEFAULT FALSE,
+   extensions               [0] IMPLICIT Extensions    OPTIONAL  }
+*/
+
+typedef struct TS_req_st
+	{
+	ASN1_INTEGER *version;
+	TS_MSG_IMPRINT *msg_imprint;
+	ASN1_OBJECT *policy_id;		/* OPTIONAL */
+	ASN1_INTEGER *nonce;		/* OPTIONAL */
+	ASN1_BOOLEAN cert_req;		/* DEFAULT FALSE */
+	STACK_OF(X509_EXTENSION) *extensions;	/* [0] OPTIONAL */
+	} TS_REQ;
+
+/*
+Accuracy ::= SEQUENCE {
+                seconds        INTEGER           OPTIONAL,
+                millis     [0] INTEGER  (1..999) OPTIONAL,
+                micros     [1] INTEGER  (1..999) OPTIONAL  }
+*/
+
+typedef struct TS_accuracy_st
+	{
+	ASN1_INTEGER *seconds;
+	ASN1_INTEGER *millis;
+	ASN1_INTEGER *micros;
+	} TS_ACCURACY;
+
+/*
+TSTInfo ::= SEQUENCE  {
+    version                      INTEGER  { v1(1) },
+    policy                       TSAPolicyId,
+    messageImprint               MessageImprint,
+      -- MUST have the same value as the similar field in
+      -- TimeStampReq
+    serialNumber                 INTEGER,
+     -- Time-Stamping users MUST be ready to accommodate integers
+     -- up to 160 bits.
+    genTime                      GeneralizedTime,
+    accuracy                     Accuracy                 OPTIONAL,
+    ordering                     BOOLEAN             DEFAULT FALSE,
+    nonce                        INTEGER                  OPTIONAL,
+      -- MUST be present if the similar field was present
+      -- in TimeStampReq.  In that case it MUST have the same value.
+    tsa                          [0] GeneralName          OPTIONAL,
+    extensions                   [1] IMPLICIT Extensions  OPTIONAL   }
+*/
+
+typedef struct TS_tst_info_st
+	{
+	ASN1_INTEGER *version;
+	ASN1_OBJECT *policy_id;
+	TS_MSG_IMPRINT *msg_imprint;
+	ASN1_INTEGER *serial;
+	ASN1_GENERALIZEDTIME *time;
+	TS_ACCURACY *accuracy;
+	ASN1_BOOLEAN ordering;
+	ASN1_INTEGER *nonce;
+	GENERAL_NAME *tsa;
+	STACK_OF(X509_EXTENSION) *extensions;
+	} TS_TST_INFO;	
+
+/*
+PKIStatusInfo ::= SEQUENCE {
+    status        PKIStatus,
+    statusString  PKIFreeText     OPTIONAL,
+    failInfo      PKIFailureInfo  OPTIONAL  }
+
+From RFC 1510 - section 3.1.1:
+PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
+	-- text encoded as UTF-8 String (note:  each UTF8String SHOULD
+	-- include an RFC 1766 language tag to indicate the language
+	-- of the contained text)
+*/
+
+/* Possible values for status. See ts_resp_print.c && ts_resp_verify.c. */
+
+#define	TS_STATUS_GRANTED			0
+#define	TS_STATUS_GRANTED_WITH_MODS		1
+#define	TS_STATUS_REJECTION			2
+#define	TS_STATUS_WAITING			3
+#define	TS_STATUS_REVOCATION_WARNING		4
+#define	TS_STATUS_REVOCATION_NOTIFICATION	5
+
+/* Possible values for failure_info. See ts_resp_print.c && ts_resp_verify.c */
+
+#define	TS_INFO_BAD_ALG			0
+#define	TS_INFO_BAD_REQUEST		2
+#define	TS_INFO_BAD_DATA_FORMAT		5
+#define	TS_INFO_TIME_NOT_AVAILABLE	14
+#define	TS_INFO_UNACCEPTED_POLICY	15
+#define	TS_INFO_UNACCEPTED_EXTENSION	16
+#define	TS_INFO_ADD_INFO_NOT_AVAILABLE	17
+#define	TS_INFO_SYSTEM_FAILURE		25
+
+typedef struct TS_status_info_st
+	{
+	ASN1_INTEGER *status;
+	STACK_OF(ASN1_UTF8STRING) *text;
+	ASN1_BIT_STRING *failure_info;
+	} TS_STATUS_INFO;
+
+DECLARE_STACK_OF(ASN1_UTF8STRING)
+DECLARE_ASN1_SET_OF(ASN1_UTF8STRING)
+
+/*
+TimeStampResp ::= SEQUENCE  {
+     status                  PKIStatusInfo,
+     timeStampToken          TimeStampToken     OPTIONAL }
+*/
+
+typedef struct TS_resp_st
+	{
+	TS_STATUS_INFO *status_info;
+	PKCS7 *token;
+	TS_TST_INFO *tst_info;
+	} TS_RESP;
+
+/* The structure below would belong to the ESS component. */
+
+/*
+IssuerSerial ::= SEQUENCE {
+	issuer                   GeneralNames,
+	serialNumber             CertificateSerialNumber
+	}
+*/
+
+typedef struct ESS_issuer_serial
+	{
+	STACK_OF(GENERAL_NAME)	*issuer;
+	ASN1_INTEGER		*serial;
+	} ESS_ISSUER_SERIAL;
+
+/*
+ESSCertID ::=  SEQUENCE {
+        certHash                 Hash,
+        issuerSerial             IssuerSerial OPTIONAL
+}
+*/
+
+typedef struct ESS_cert_id
+	{
+	ASN1_OCTET_STRING *hash;	/* Always SHA-1 digest. */
+	ESS_ISSUER_SERIAL *issuer_serial;
+	} ESS_CERT_ID;
+
+DECLARE_STACK_OF(ESS_CERT_ID)
+DECLARE_ASN1_SET_OF(ESS_CERT_ID)
+
+/*
+SigningCertificate ::=  SEQUENCE {
+       certs        SEQUENCE OF ESSCertID,
+       policies     SEQUENCE OF PolicyInformation OPTIONAL
+}
+*/
+
+typedef struct ESS_signing_cert
+	{
+	STACK_OF(ESS_CERT_ID) *cert_ids;
+	STACK_OF(POLICYINFO) *policy_info;
+	} ESS_SIGNING_CERT;
+
+
+TS_REQ	*TS_REQ_new(void);
+void	TS_REQ_free(TS_REQ *a);
+int	i2d_TS_REQ(const TS_REQ *a, unsigned char **pp);
+TS_REQ	*d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length);
+
+TS_REQ	*TS_REQ_dup(TS_REQ *a);
+
+TS_REQ	*d2i_TS_REQ_fp(FILE *fp, TS_REQ **a);
+int	i2d_TS_REQ_fp(FILE *fp, TS_REQ *a);
+TS_REQ	*d2i_TS_REQ_bio(BIO *fp, TS_REQ **a);
+int	i2d_TS_REQ_bio(BIO *fp, TS_REQ *a);
+
+TS_MSG_IMPRINT	*TS_MSG_IMPRINT_new(void);
+void		TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a);
+int		i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp);
+TS_MSG_IMPRINT	*d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a,
+				    const unsigned char **pp, long length);
+
+TS_MSG_IMPRINT	*TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a);
+
+TS_MSG_IMPRINT	*d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a);
+int		i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a);
+TS_MSG_IMPRINT	*d2i_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT **a);
+int		i2d_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT *a);
+
+TS_RESP	*TS_RESP_new(void);
+void	TS_RESP_free(TS_RESP *a);
+int	i2d_TS_RESP(const TS_RESP *a, unsigned char **pp);
+TS_RESP	*d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length);
+TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token);
+TS_RESP	*TS_RESP_dup(TS_RESP *a);
+
+TS_RESP	*d2i_TS_RESP_fp(FILE *fp, TS_RESP **a);
+int	i2d_TS_RESP_fp(FILE *fp, TS_RESP *a);
+TS_RESP	*d2i_TS_RESP_bio(BIO *fp, TS_RESP **a);
+int	i2d_TS_RESP_bio(BIO *fp, TS_RESP *a);
+
+TS_STATUS_INFO	*TS_STATUS_INFO_new(void);
+void		TS_STATUS_INFO_free(TS_STATUS_INFO *a);
+int		i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp);
+TS_STATUS_INFO	*d2i_TS_STATUS_INFO(TS_STATUS_INFO **a, 
+				    const unsigned char **pp, long length);
+TS_STATUS_INFO	*TS_STATUS_INFO_dup(TS_STATUS_INFO *a);
+
+TS_TST_INFO	*TS_TST_INFO_new(void);
+void		TS_TST_INFO_free(TS_TST_INFO *a);
+int		i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp);
+TS_TST_INFO	*d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp,
+				    long length);
+TS_TST_INFO	*TS_TST_INFO_dup(TS_TST_INFO *a);
+
+TS_TST_INFO	*d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a);
+int		i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a);
+TS_TST_INFO	*d2i_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO **a);
+int		i2d_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO *a);
+
+TS_ACCURACY	*TS_ACCURACY_new(void);
+void		TS_ACCURACY_free(TS_ACCURACY *a);
+int		i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp);
+TS_ACCURACY	*d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp,
+				    long length);
+TS_ACCURACY	*TS_ACCURACY_dup(TS_ACCURACY *a);
+
+ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void);
+void		  ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a);
+int		  i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a,
+					unsigned char **pp);
+ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a,
+					 const unsigned char **pp, long length);
+ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a);
+
+ESS_CERT_ID	*ESS_CERT_ID_new(void);
+void		ESS_CERT_ID_free(ESS_CERT_ID *a);
+int		i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp);
+ESS_CERT_ID	*d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp,
+				 long length);
+ESS_CERT_ID	*ESS_CERT_ID_dup(ESS_CERT_ID *a);
+
+ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void);
+void		 ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a);
+int		 i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, 
+				      unsigned char **pp);
+ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a,
+				       const unsigned char **pp, long length);
+ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a);
+
+void ERR_load_TS_strings(void);
+
+int TS_REQ_set_version(TS_REQ *a, long version);
+long TS_REQ_get_version(const TS_REQ *a);
+
+int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint);
+TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a);
+
+int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg);
+X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a);
+
+int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len);
+ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a);
+
+int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy);
+ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a);
+
+int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce);
+const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a);
+
+int TS_REQ_set_cert_req(TS_REQ *a, int cert_req);
+int TS_REQ_get_cert_req(const TS_REQ *a);
+
+STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a);
+void TS_REQ_ext_free(TS_REQ *a);
+int TS_REQ_get_ext_count(TS_REQ *a);
+int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos);
+int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos);
+int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos);
+X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc);
+X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc);
+int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc);
+void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx);
+
+/* Function declarations for TS_REQ defined in ts/ts_req_print.c */
+
+int TS_REQ_print_bio(BIO *bio, TS_REQ *a);
+
+/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */
+
+int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info);
+TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a);
+
+/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */
+void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info);
+PKCS7 *TS_RESP_get_token(TS_RESP *a);
+TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a);
+
+int TS_TST_INFO_set_version(TS_TST_INFO *a, long version);
+long TS_TST_INFO_get_version(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id);
+ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a);
+
+int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint);
+TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a);
+
+int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial);
+const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime);
+const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy);
+TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a);
+
+int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds);
+const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a);
+
+int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis);
+const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a);
+
+int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros);
+const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a);
+
+int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering);
+int TS_TST_INFO_get_ordering(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce);
+const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa);
+GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a);
+
+STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a);
+void TS_TST_INFO_ext_free(TS_TST_INFO *a);
+int TS_TST_INFO_get_ext_count(TS_TST_INFO *a);
+int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos);
+int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos);
+int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos);
+X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc);
+X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc);
+int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc);
+void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx);
+
+/* Declarations related to response generation, defined in ts/ts_resp_sign.c. */
+
+/* Optional flags for response generation. */
+
+/* Don't include the TSA name in response. */
+#define	TS_TSA_NAME		0x01
+
+/* Set ordering to true in response. */
+#define	TS_ORDERING		0x02
+
+/*
+ * Include the signer certificate and the other specified certificates in
+ * the ESS signing certificate attribute beside the PKCS7 signed data.
+ * Only the signer certificates is included by default.
+ */
+#define	TS_ESS_CERT_ID_CHAIN	0x04
+
+/* Forward declaration. */
+struct TS_resp_ctx;
+
+/* This must return a unique number less than 160 bits long. */
+typedef ASN1_INTEGER *(*TS_serial_cb)(struct TS_resp_ctx *, void *);
+
+/* This must return the seconds and microseconds since Jan 1, 1970 in
+   the sec and usec variables allocated by the caller. 
+   Return non-zero for success and zero for failure. */
+typedef	int (*TS_time_cb)(struct TS_resp_ctx *, void *, long *sec, long *usec);
+
+/* This must process the given extension.
+ * It can modify the TS_TST_INFO object of the context.
+ * Return values: !0 (processed), 0 (error, it must set the 
+ * status info/failure info of the response).
+ */
+typedef	int (*TS_extension_cb)(struct TS_resp_ctx *, X509_EXTENSION *, void *);
+
+typedef struct TS_resp_ctx
+	{
+	X509		*signer_cert;
+	EVP_PKEY	*signer_key;
+	STACK_OF(X509)	*certs;	/* Certs to include in signed data. */
+	STACK_OF(ASN1_OBJECT)	*policies;	/* Acceptable policies. */
+	ASN1_OBJECT	*default_policy; /* It may appear in policies, too. */
+	STACK_OF(EVP_MD)	*mds;	/* Acceptable message digests. */
+	ASN1_INTEGER	*seconds;	/* accuracy, 0 means not specified. */
+	ASN1_INTEGER	*millis;	/* accuracy, 0 means not specified. */
+	ASN1_INTEGER	*micros;	/* accuracy, 0 means not specified. */
+	unsigned	clock_precision_digits; /* fraction of seconds in
+						   time stamp token. */
+	unsigned	flags;		/* Optional info, see values above. */
+
+	/* Callback functions. */
+	TS_serial_cb serial_cb;
+	void *serial_cb_data;	/* User data for serial_cb. */
+	
+	TS_time_cb time_cb;
+	void *time_cb_data;	/* User data for time_cb. */
+	
+	TS_extension_cb extension_cb;
+	void *extension_cb_data;	/* User data for extension_cb. */
+
+	/* These members are used only while creating the response. */
+	TS_REQ		*request;
+	TS_RESP		*response;
+	TS_TST_INFO	*tst_info;
+	} TS_RESP_CTX;
+
+DECLARE_STACK_OF(EVP_MD)
+DECLARE_ASN1_SET_OF(EVP_MD)
+
+/* Creates a response context that can be used for generating responses. */
+TS_RESP_CTX *TS_RESP_CTX_new(void);
+void TS_RESP_CTX_free(TS_RESP_CTX *ctx);
+
+/* This parameter must be set. */
+int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer);
+
+/* This parameter must be set. */
+int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key);
+
+/* This parameter must be set. */
+int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy);
+
+/* No additional certs are included in the response by default. */
+int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs);
+
+/* Adds a new acceptable policy, only the default policy 
+   is accepted by default. */
+int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy);
+
+/* Adds a new acceptable message digest. Note that no message digests 
+   are accepted by default. The md argument is shared with the caller. */
+int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md);
+
+/* Accuracy is not included by default. */
+int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
+			     int secs, int millis, int micros);
+
+/* Clock precision digits, i.e. the number of decimal digits: 
+   '0' means sec, '3' msec, '6' usec, and so on. Default is 0. */ 
+int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx,
+					   unsigned clock_precision_digits);
+/* At most we accept usec precision. */	
+#define TS_MAX_CLOCK_PRECISION_DIGITS	6
+
+/* No flags are set by default. */
+void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags);
+
+/* Default callback always returns a constant. */
+void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data);
+
+/* Default callback uses the gettimeofday() and gmtime() system calls. */
+void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data);
+
+/* Default callback rejects all extensions. The extension callback is called 
+ * when the TS_TST_INFO object is already set up and not signed yet. */
+/* FIXME: extension handling is not tested yet. */
+void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, 
+				  TS_extension_cb cb, void *data);
+
+/* The following methods can be used in the callbacks. */
+int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, 
+				int status, const char *text);
+
+/* Sets the status info only if it is still TS_STATUS_GRANTED. */
+int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, 
+				     int status, const char *text);
+
+int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure);
+
+/* The get methods below can be used in the extension callback. */
+TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx);
+
+TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx);
+
+/* 
+ * Creates the signed TS_TST_INFO and puts it in TS_RESP.
+ * In case of errors it sets the status info properly.
+ * Returns NULL only in case of memory allocation/fatal error.
+ */
+TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio);
+
+/*
+ * Declarations related to response verification,
+ * they are defined in ts/ts_resp_verify.c.
+ */
+
+int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
+			     X509_STORE *store, X509 **signer_out);
+
+/* Context structure for the generic verify method. */
+
+/* Verify the signer's certificate and the signature of the response. */
+#define	TS_VFY_SIGNATURE	(1u << 0)
+/* Verify the version number of the response. */
+#define	TS_VFY_VERSION		(1u << 1)
+/* Verify if the policy supplied by the user matches the policy of the TSA. */
+#define	TS_VFY_POLICY		(1u << 2)
+/* Verify the message imprint provided by the user. This flag should not be
+   specified with TS_VFY_DATA. */
+#define	TS_VFY_IMPRINT		(1u << 3)
+/* Verify the message imprint computed by the verify method from the user
+   provided data and the MD algorithm of the response. This flag should not be
+   specified with TS_VFY_IMPRINT. */
+#define	TS_VFY_DATA		(1u << 4)
+/* Verify the nonce value. */
+#define	TS_VFY_NONCE		(1u << 5)
+/* Verify if the TSA name field matches the signer certificate. */
+#define	TS_VFY_SIGNER		(1u << 6)
+/* Verify if the TSA name field equals to the user provided name. */
+#define	TS_VFY_TSA_NAME		(1u << 7)
+
+/* You can use the following convenience constants. */
+#define	TS_VFY_ALL_IMPRINT	(TS_VFY_SIGNATURE	\
+				 | TS_VFY_VERSION	\
+				 | TS_VFY_POLICY	\
+				 | TS_VFY_IMPRINT	\
+				 | TS_VFY_NONCE		\
+				 | TS_VFY_SIGNER	\
+				 | TS_VFY_TSA_NAME)
+#define	TS_VFY_ALL_DATA		(TS_VFY_SIGNATURE	\
+				 | TS_VFY_VERSION	\
+				 | TS_VFY_POLICY	\
+				 | TS_VFY_DATA		\
+				 | TS_VFY_NONCE		\
+				 | TS_VFY_SIGNER	\
+				 | TS_VFY_TSA_NAME)
+
+typedef struct TS_verify_ctx
+	{
+	/* Set this to the union of TS_VFY_... flags you want to carry out. */
+	unsigned	flags;
+
+	/* Must be set only with TS_VFY_SIGNATURE. certs is optional. */
+	X509_STORE	*store;
+	STACK_OF(X509)	*certs;
+
+	/* Must be set only with TS_VFY_POLICY. */
+	ASN1_OBJECT	*policy;
+
+	/* Must be set only with TS_VFY_IMPRINT. If md_alg is NULL, 
+	   the algorithm from the response is used. */
+	X509_ALGOR	*md_alg;
+	unsigned char	*imprint;
+	unsigned	imprint_len;
+
+	/* Must be set only with TS_VFY_DATA. */
+	BIO		*data;
+
+	/* Must be set only with TS_VFY_TSA_NAME. */
+	ASN1_INTEGER	*nonce;
+
+	/* Must be set only with TS_VFY_TSA_NAME. */
+	GENERAL_NAME	*tsa_name;
+	} TS_VERIFY_CTX;
+
+int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response);
+int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token);
+
+/*
+ * Declarations related to response verification context,
+ * they are defined in ts/ts_verify_ctx.c.
+ */
+
+/* Set all fields to zero. */
+TS_VERIFY_CTX *TS_VERIFY_CTX_new(void);
+void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx);
+void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx);
+void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx);
+
+/* 
+ * If ctx is NULL, it allocates and returns a new object, otherwise
+ * it returns ctx. It initialises all the members as follows:
+ * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE)
+ * certs = NULL
+ * store = NULL
+ * policy = policy from the request or NULL if absent (in this case
+ *	TS_VFY_POLICY is cleared from flags as well)
+ * md_alg = MD algorithm from request
+ * imprint, imprint_len = imprint from request
+ * data = NULL
+ * nonce, nonce_len = nonce from the request or NULL if absent (in this case
+ * 	TS_VFY_NONCE is cleared from flags as well)
+ * tsa_name = NULL
+ * Important: after calling this method TS_VFY_SIGNATURE should be added!
+ */
+TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx);
+
+/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */
+
+int TS_RESP_print_bio(BIO *bio, TS_RESP *a);
+int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a);
+int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a);
+
+/* Common utility functions defined in ts/ts_lib.c */
+
+int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num);
+int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj);
+int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions);
+int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg);
+int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg);
+
+/* Function declarations for handling configuration options,
+   defined in ts/ts_conf.c */
+
+X509 *TS_CONF_load_cert(const char *file);
+STACK_OF(X509) *TS_CONF_load_certs(const char *file);
+EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass);
+const char *TS_CONF_get_tsa_section(CONF *conf, const char *section);
+int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb,
+		       TS_RESP_CTX *ctx);
+int TS_CONF_set_crypto_device(CONF *conf, const char *section,
+			      const char *device);
+int TS_CONF_set_default_engine(const char *name);
+int TS_CONF_set_signer_cert(CONF *conf, const char *section,
+			    const char *cert, TS_RESP_CTX *ctx);
+int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs,
+		      TS_RESP_CTX *ctx);
+int TS_CONF_set_signer_key(CONF *conf, const char *section,
+			   const char *key, const char *pass, TS_RESP_CTX *ctx);
+int TS_CONF_set_def_policy(CONF *conf, const char *section,
+			   const char *policy, TS_RESP_CTX *ctx);
+int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section,
+				       TS_RESP_CTX *ctx);
+int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
+				  TS_RESP_CTX *ctx);
+
+/* -------------------------------------------------- */
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_TS_strings(void);
+
+/* Error codes for the TS functions. */
+
+/* Function codes. */
+#define TS_F_D2I_TS_RESP				 147
+#define TS_F_DEF_SERIAL_CB				 110
+#define TS_F_DEF_TIME_CB				 111
+#define TS_F_ESS_ADD_SIGNING_CERT			 112
+#define TS_F_ESS_CERT_ID_NEW_INIT			 113
+#define TS_F_ESS_SIGNING_CERT_NEW_INIT			 114
+#define TS_F_INT_TS_RESP_VERIFY_TOKEN			 149
+#define TS_F_PKCS7_TO_TS_TST_INFO			 148
+#define TS_F_TS_ACCURACY_SET_MICROS			 115
+#define TS_F_TS_ACCURACY_SET_MILLIS			 116
+#define TS_F_TS_ACCURACY_SET_SECONDS			 117
+#define TS_F_TS_CHECK_IMPRINTS				 100
+#define TS_F_TS_CHECK_NONCES				 101
+#define TS_F_TS_CHECK_POLICY				 102
+#define TS_F_TS_CHECK_SIGNING_CERTS			 103
+#define TS_F_TS_CHECK_STATUS_INFO			 104
+#define TS_F_TS_COMPUTE_IMPRINT				 145
+#define TS_F_TS_CONF_SET_DEFAULT_ENGINE			 146
+#define TS_F_TS_GET_STATUS_TEXT				 105
+#define TS_F_TS_MSG_IMPRINT_SET_ALGO			 118
+#define TS_F_TS_REQ_SET_MSG_IMPRINT			 119
+#define TS_F_TS_REQ_SET_NONCE				 120
+#define TS_F_TS_REQ_SET_POLICY_ID			 121
+#define TS_F_TS_RESP_CREATE_RESPONSE			 122
+#define TS_F_TS_RESP_CREATE_TST_INFO			 123
+#define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO		 124
+#define TS_F_TS_RESP_CTX_ADD_MD				 125
+#define TS_F_TS_RESP_CTX_ADD_POLICY			 126
+#define TS_F_TS_RESP_CTX_NEW				 127
+#define TS_F_TS_RESP_CTX_SET_ACCURACY			 128
+#define TS_F_TS_RESP_CTX_SET_CERTS			 129
+#define TS_F_TS_RESP_CTX_SET_DEF_POLICY			 130
+#define TS_F_TS_RESP_CTX_SET_SIGNER_CERT		 131
+#define TS_F_TS_RESP_CTX_SET_STATUS_INFO		 132
+#define TS_F_TS_RESP_GET_POLICY				 133
+#define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION		 134
+#define TS_F_TS_RESP_SET_STATUS_INFO			 135
+#define TS_F_TS_RESP_SET_TST_INFO			 150
+#define TS_F_TS_RESP_SIGN				 136
+#define TS_F_TS_RESP_VERIFY_SIGNATURE			 106
+#define TS_F_TS_RESP_VERIFY_TOKEN			 107
+#define TS_F_TS_TST_INFO_SET_ACCURACY			 137
+#define TS_F_TS_TST_INFO_SET_MSG_IMPRINT		 138
+#define TS_F_TS_TST_INFO_SET_NONCE			 139
+#define TS_F_TS_TST_INFO_SET_POLICY_ID			 140
+#define TS_F_TS_TST_INFO_SET_SERIAL			 141
+#define TS_F_TS_TST_INFO_SET_TIME			 142
+#define TS_F_TS_TST_INFO_SET_TSA			 143
+#define TS_F_TS_VERIFY					 108
+#define TS_F_TS_VERIFY_CERT				 109
+#define TS_F_TS_VERIFY_CTX_NEW				 144
+
+/* Reason codes. */
+#define TS_R_BAD_PKCS7_TYPE				 132
+#define TS_R_BAD_TYPE					 133
+#define TS_R_CERTIFICATE_VERIFY_ERROR			 100
+#define TS_R_COULD_NOT_SET_ENGINE			 127
+#define TS_R_COULD_NOT_SET_TIME				 115
+#define TS_R_D2I_TS_RESP_INT_FAILED			 128
+#define TS_R_DETACHED_CONTENT				 134
+#define TS_R_ESS_ADD_SIGNING_CERT_ERROR			 116
+#define TS_R_ESS_SIGNING_CERTIFICATE_ERROR		 101
+#define TS_R_INVALID_NULL_POINTER			 102
+#define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE		 117
+#define TS_R_MESSAGE_IMPRINT_MISMATCH			 103
+#define TS_R_NONCE_MISMATCH				 104
+#define TS_R_NONCE_NOT_RETURNED				 105
+#define TS_R_NO_CONTENT					 106
+#define TS_R_NO_TIME_STAMP_TOKEN			 107
+#define TS_R_PKCS7_ADD_SIGNATURE_ERROR			 118
+#define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR		 119
+#define TS_R_PKCS7_TO_TS_TST_INFO_FAILED		 129
+#define TS_R_POLICY_MISMATCH				 108
+#define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 120
+#define TS_R_RESPONSE_SETUP_ERROR			 121
+#define TS_R_SIGNATURE_FAILURE				 109
+#define TS_R_THERE_MUST_BE_ONE_SIGNER			 110
+#define TS_R_TIME_SYSCALL_ERROR				 122
+#define TS_R_TOKEN_NOT_PRESENT				 130
+#define TS_R_TOKEN_PRESENT				 131
+#define TS_R_TSA_NAME_MISMATCH				 111
+#define TS_R_TSA_UNTRUSTED				 112
+#define TS_R_TST_INFO_SETUP_ERROR			 123
+#define TS_R_TS_DATASIGN				 124
+#define TS_R_UNACCEPTABLE_POLICY			 125
+#define TS_R_UNSUPPORTED_MD_ALGORITHM			 126
+#define TS_R_UNSUPPORTED_VERSION			 113
+#define TS_R_WRONG_CONTENT_TYPE				 114
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/ts/ts_asn1.c b/openssl/crypto/ts/ts_asn1.c
new file mode 100644
index 0000000..40b730c
--- /dev/null
+++ b/openssl/crypto/ts/ts_asn1.c
@@ -0,0 +1,322 @@
+/* crypto/ts/ts_asn1.c */
+/* Written by Nils Larsch for the OpenSSL project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/ts.h>
+#include <openssl/err.h>
+#include <openssl/asn1t.h>
+
+ASN1_SEQUENCE(TS_MSG_IMPRINT) = {
+	ASN1_SIMPLE(TS_MSG_IMPRINT, hash_algo, X509_ALGOR),
+	ASN1_SIMPLE(TS_MSG_IMPRINT, hashed_msg, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(TS_MSG_IMPRINT)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(TS_MSG_IMPRINT)
+IMPLEMENT_ASN1_DUP_FUNCTION(TS_MSG_IMPRINT)
+#ifndef OPENSSL_NO_BIO
+TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT **a)
+	{
+	return ASN1_d2i_bio_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, d2i_TS_MSG_IMPRINT, bp, a);
+	}
+
+int i2d_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT *a)
+{
+	return ASN1_i2d_bio_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, bp, a);
+}
+#endif
+#ifndef OPENSSL_NO_FP_API
+TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a)
+	{
+	return ASN1_d2i_fp_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, d2i_TS_MSG_IMPRINT, fp, a);
+	}
+
+int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a)
+	{
+	return ASN1_i2d_fp_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, fp, a);
+	}
+#endif
+
+ASN1_SEQUENCE(TS_REQ) = {
+	ASN1_SIMPLE(TS_REQ, version, ASN1_INTEGER),
+	ASN1_SIMPLE(TS_REQ, msg_imprint, TS_MSG_IMPRINT),
+	ASN1_OPT(TS_REQ, policy_id, ASN1_OBJECT),
+	ASN1_OPT(TS_REQ, nonce, ASN1_INTEGER),
+	ASN1_OPT(TS_REQ, cert_req, ASN1_FBOOLEAN),
+	ASN1_IMP_SEQUENCE_OF_OPT(TS_REQ, extensions, X509_EXTENSION, 0)
+} ASN1_SEQUENCE_END(TS_REQ)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(TS_REQ)
+IMPLEMENT_ASN1_DUP_FUNCTION(TS_REQ)
+#ifndef OPENSSL_NO_BIO
+TS_REQ *d2i_TS_REQ_bio(BIO *bp, TS_REQ **a)
+	{
+	return ASN1_d2i_bio_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, bp, a);
+	}
+
+int i2d_TS_REQ_bio(BIO *bp, TS_REQ *a)
+	{
+	return ASN1_i2d_bio_of_const(TS_REQ, i2d_TS_REQ, bp, a);
+	}
+#endif
+#ifndef OPENSSL_NO_FP_API
+TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a)
+	{
+	return ASN1_d2i_fp_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, fp, a);
+	}
+
+int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a)
+	{
+	return ASN1_i2d_fp_of_const(TS_REQ, i2d_TS_REQ, fp, a);
+	}
+#endif
+
+ASN1_SEQUENCE(TS_ACCURACY) = {
+	ASN1_OPT(TS_ACCURACY, seconds, ASN1_INTEGER),
+	ASN1_IMP_OPT(TS_ACCURACY, millis, ASN1_INTEGER, 0),
+	ASN1_IMP_OPT(TS_ACCURACY, micros, ASN1_INTEGER, 1)
+} ASN1_SEQUENCE_END(TS_ACCURACY)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(TS_ACCURACY)
+IMPLEMENT_ASN1_DUP_FUNCTION(TS_ACCURACY)
+
+ASN1_SEQUENCE(TS_TST_INFO) = {
+	ASN1_SIMPLE(TS_TST_INFO, version, ASN1_INTEGER),
+	ASN1_SIMPLE(TS_TST_INFO, policy_id, ASN1_OBJECT),
+	ASN1_SIMPLE(TS_TST_INFO, msg_imprint, TS_MSG_IMPRINT),
+	ASN1_SIMPLE(TS_TST_INFO, serial, ASN1_INTEGER),
+	ASN1_SIMPLE(TS_TST_INFO, time, ASN1_GENERALIZEDTIME),
+	ASN1_OPT(TS_TST_INFO, accuracy, TS_ACCURACY),
+	ASN1_OPT(TS_TST_INFO, ordering, ASN1_FBOOLEAN),
+	ASN1_OPT(TS_TST_INFO, nonce, ASN1_INTEGER),
+	ASN1_EXP_OPT(TS_TST_INFO, tsa, GENERAL_NAME, 0),
+	ASN1_IMP_SEQUENCE_OF_OPT(TS_TST_INFO, extensions, X509_EXTENSION, 1)
+} ASN1_SEQUENCE_END(TS_TST_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(TS_TST_INFO)
+IMPLEMENT_ASN1_DUP_FUNCTION(TS_TST_INFO)
+#ifndef OPENSSL_NO_BIO
+TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO **a)
+	{
+	return ASN1_d2i_bio_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, bp, a);
+	}
+
+int i2d_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO *a)
+	{
+	return ASN1_i2d_bio_of_const(TS_TST_INFO, i2d_TS_TST_INFO, bp, a);
+	}
+#endif
+#ifndef OPENSSL_NO_FP_API
+TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a)
+	{
+	return ASN1_d2i_fp_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, fp, a);
+	}
+
+int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a)
+	{
+	return ASN1_i2d_fp_of_const(TS_TST_INFO, i2d_TS_TST_INFO, fp, a);
+	}
+#endif
+
+ASN1_SEQUENCE(TS_STATUS_INFO) = {
+	ASN1_SIMPLE(TS_STATUS_INFO, status, ASN1_INTEGER),
+	ASN1_SEQUENCE_OF_OPT(TS_STATUS_INFO, text, ASN1_UTF8STRING),
+	ASN1_OPT(TS_STATUS_INFO, failure_info, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END(TS_STATUS_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(TS_STATUS_INFO)
+IMPLEMENT_ASN1_DUP_FUNCTION(TS_STATUS_INFO)
+
+static int ts_resp_set_tst_info(TS_RESP *a)
+{
+	long    status;
+
+	status = ASN1_INTEGER_get(a->status_info->status);
+
+	if (a->token) {
+		if (status != 0 && status != 1) {
+			TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_PRESENT);
+			return 0;
+		}
+		if (a->tst_info != NULL)
+			TS_TST_INFO_free(a->tst_info);
+		a->tst_info = PKCS7_to_TS_TST_INFO(a->token);
+		if (!a->tst_info) {
+			TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_PKCS7_TO_TS_TST_INFO_FAILED);
+			return 0;
+		}
+	} else if (status == 0 || status == 1) {
+		TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_NOT_PRESENT);
+		return 0;
+	}
+
+	return 1;
+}
+
+static int ts_resp_cb(int op, ASN1_VALUE **pval, const ASN1_ITEM *it,
+	void *exarg)
+{
+	TS_RESP *ts_resp = (TS_RESP *)*pval;
+	if (op == ASN1_OP_NEW_POST) {
+		ts_resp->tst_info = NULL;
+	} else if (op == ASN1_OP_FREE_POST) {
+		if (ts_resp->tst_info != NULL)
+			TS_TST_INFO_free(ts_resp->tst_info);
+	} else if (op == ASN1_OP_D2I_POST) {
+		if (ts_resp_set_tst_info(ts_resp) == 0)
+			return 0;
+	}
+	return 1;
+}
+
+ASN1_SEQUENCE_cb(TS_RESP, ts_resp_cb) = {
+	ASN1_SIMPLE(TS_RESP, status_info, TS_STATUS_INFO),
+	ASN1_OPT(TS_RESP, token, PKCS7),
+} ASN1_SEQUENCE_END_cb(TS_RESP, TS_RESP)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(TS_RESP)
+IMPLEMENT_ASN1_DUP_FUNCTION(TS_RESP)
+#ifndef OPENSSL_NO_BIO
+TS_RESP *d2i_TS_RESP_bio(BIO *bp, TS_RESP **a)
+	{
+	return ASN1_d2i_bio_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, bp, a);
+	}
+
+int i2d_TS_RESP_bio(BIO *bp, TS_RESP *a)
+	{
+	return ASN1_i2d_bio_of_const(TS_RESP, i2d_TS_RESP, bp, a);
+	}
+#endif
+#ifndef OPENSSL_NO_FP_API
+TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a)
+	{
+	return ASN1_d2i_fp_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, fp, a);
+	}
+
+int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a)
+	{
+	return ASN1_i2d_fp_of_const(TS_RESP, i2d_TS_RESP, fp, a);
+	}
+#endif
+
+ASN1_SEQUENCE(ESS_ISSUER_SERIAL) = {
+	ASN1_SEQUENCE_OF(ESS_ISSUER_SERIAL, issuer, GENERAL_NAME),
+	ASN1_SIMPLE(ESS_ISSUER_SERIAL, serial, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(ESS_ISSUER_SERIAL)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(ESS_ISSUER_SERIAL)
+IMPLEMENT_ASN1_DUP_FUNCTION(ESS_ISSUER_SERIAL)
+
+ASN1_SEQUENCE(ESS_CERT_ID) = {
+	ASN1_SIMPLE(ESS_CERT_ID, hash, ASN1_OCTET_STRING),
+	ASN1_OPT(ESS_CERT_ID, issuer_serial, ESS_ISSUER_SERIAL)
+} ASN1_SEQUENCE_END(ESS_CERT_ID)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(ESS_CERT_ID)
+IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID)
+
+ASN1_SEQUENCE(ESS_SIGNING_CERT) = {
+	ASN1_SEQUENCE_OF(ESS_SIGNING_CERT, cert_ids, ESS_CERT_ID),
+	ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT, policy_info, POLICYINFO)
+} ASN1_SEQUENCE_END(ESS_SIGNING_CERT)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT)
+IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT)
+
+/* Getting encapsulated TS_TST_INFO object from PKCS7. */
+TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token)
+{
+	PKCS7_SIGNED *pkcs7_signed;
+	PKCS7 *enveloped;
+	ASN1_TYPE *tst_info_wrapper;
+	ASN1_OCTET_STRING *tst_info_der;
+	const unsigned char *p;
+
+	if (!PKCS7_type_is_signed(token))
+		{
+		TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE);
+		return NULL;
+		}
+
+	/* Content must be present. */
+	if (PKCS7_get_detached(token))
+		{
+		TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_DETACHED_CONTENT);
+		return NULL;
+		}
+
+	/* We have a signed data with content. */
+	pkcs7_signed = token->d.sign;
+	enveloped = pkcs7_signed->contents;
+	if (OBJ_obj2nid(enveloped->type) != NID_id_smime_ct_TSTInfo)
+		{
+		TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE);
+		return NULL;
+		}
+
+	/* We have a DER encoded TST_INFO as the signed data. */
+	tst_info_wrapper = enveloped->d.other;
+	if (tst_info_wrapper->type != V_ASN1_OCTET_STRING)
+		{
+		TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_TYPE);
+		return NULL;
+		}
+
+	/* We have the correct ASN1_OCTET_STRING type. */
+	tst_info_der = tst_info_wrapper->value.octet_string;
+	/* At last, decode the TST_INFO. */
+	p = tst_info_der->data;
+	return d2i_TS_TST_INFO(NULL, &p, tst_info_der->length);
+}
diff --git a/openssl/crypto/ts/ts_conf.c b/openssl/crypto/ts/ts_conf.c
new file mode 100644
index 0000000..c39be76
--- /dev/null
+++ b/openssl/crypto/ts/ts_conf.c
@@ -0,0 +1,507 @@
+/* crypto/ts/ts_conf.c */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/pem.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/ts.h>
+
+/* Macro definitions for the configuration file. */
+
+#define	BASE_SECTION			"tsa"
+#define	ENV_DEFAULT_TSA			"default_tsa"
+#define	ENV_SERIAL			"serial"
+#define ENV_CRYPTO_DEVICE		"crypto_device"
+#define	ENV_SIGNER_CERT			"signer_cert"
+#define	ENV_CERTS			"certs"
+#define	ENV_SIGNER_KEY			"signer_key"
+#define	ENV_DEFAULT_POLICY		"default_policy"
+#define	ENV_OTHER_POLICIES		"other_policies"
+#define	ENV_DIGESTS			"digests"
+#define	ENV_ACCURACY			"accuracy"
+#define	ENV_ORDERING			"ordering"
+#define	ENV_TSA_NAME			"tsa_name"
+#define	ENV_ESS_CERT_ID_CHAIN		"ess_cert_id_chain"
+#define	ENV_VALUE_SECS			"secs"
+#define	ENV_VALUE_MILLISECS		"millisecs"
+#define	ENV_VALUE_MICROSECS		"microsecs"
+#define	ENV_CLOCK_PRECISION_DIGITS	"clock_precision_digits" 
+#define	ENV_VALUE_YES			"yes"
+#define	ENV_VALUE_NO			"no"
+
+/* Function definitions for certificate and key loading. */
+
+X509 *TS_CONF_load_cert(const char *file)
+	{
+	BIO *cert = NULL;
+	X509 *x = NULL;
+
+	if ((cert = BIO_new_file(file, "r")) == NULL) goto end;
+	x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL);
+end:
+	if (x == NULL)
+		fprintf(stderr, "unable to load certificate: %s\n", file);
+	BIO_free(cert);
+	return x;
+	}
+
+STACK_OF(X509) *TS_CONF_load_certs(const char *file)
+	{
+	BIO *certs = NULL;
+	STACK_OF(X509) *othercerts = NULL;
+	STACK_OF(X509_INFO) *allcerts = NULL;
+	int i;
+
+	if (!(certs = BIO_new_file(file, "r"))) goto end;
+
+	if (!(othercerts = sk_X509_new_null())) goto end;
+	allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL);
+	for(i = 0; i < sk_X509_INFO_num(allcerts); i++)
+		{
+		X509_INFO *xi = sk_X509_INFO_value(allcerts, i);
+		if (xi->x509)
+			{
+			sk_X509_push(othercerts, xi->x509);
+			xi->x509 = NULL;
+			}
+		}
+end:
+	if (othercerts == NULL)
+		fprintf(stderr, "unable to load certificates: %s\n", file);
+	sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
+	BIO_free(certs);
+	return othercerts;
+	}
+
+EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass)
+	{
+	BIO *key = NULL;
+	EVP_PKEY *pkey = NULL;
+
+	if (!(key = BIO_new_file(file, "r"))) goto end;
+	pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, (char *) pass);
+ end:
+	if (pkey == NULL)
+		fprintf(stderr, "unable to load private key: %s\n", file);
+	BIO_free(key);
+	return pkey;
+	}
+
+/* Function definitions for handling configuration options. */
+
+static void TS_CONF_lookup_fail(const char *name, const char *tag)
+	{
+	fprintf(stderr, "variable lookup failed for %s::%s\n", name, tag);
+	}
+
+static void TS_CONF_invalid(const char *name, const char *tag)
+	{
+	fprintf(stderr, "invalid variable value for %s::%s\n", name, tag);
+	}
+
+const char *TS_CONF_get_tsa_section(CONF *conf, const char *section)
+	{
+	if (!section)
+		{
+		section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_TSA);
+		if (!section)
+			TS_CONF_lookup_fail(BASE_SECTION, ENV_DEFAULT_TSA);
+		}
+	return section;
+	}
+
+int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb,
+		       TS_RESP_CTX *ctx)
+	{
+	int ret = 0;
+	char *serial = NCONF_get_string(conf, section, ENV_SERIAL);
+	if (!serial)
+		{
+		TS_CONF_lookup_fail(section, ENV_SERIAL);
+		goto err;
+		}
+	TS_RESP_CTX_set_serial_cb(ctx, cb, serial);
+
+	ret = 1;
+ err:
+	return ret;
+	}
+
+#ifndef OPENSSL_NO_ENGINE
+
+int TS_CONF_set_crypto_device(CONF *conf, const char *section,
+			      const char *device)
+	{
+	int ret = 0;
+	
+	if (!device)
+		device = NCONF_get_string(conf, section,
+					  ENV_CRYPTO_DEVICE);
+
+	if (device && !TS_CONF_set_default_engine(device))
+		{
+		TS_CONF_invalid(section, ENV_CRYPTO_DEVICE);
+		goto err;
+		}
+	ret = 1;
+ err:
+	return ret;
+	}
+
+int TS_CONF_set_default_engine(const char *name)
+	{
+	ENGINE *e = NULL;
+	int ret = 0;
+
+	/* Leave the default if builtin specified. */
+	if (strcmp(name, "builtin") == 0) return 1;
+
+	if (!(e = ENGINE_by_id(name))) goto err;
+	/* Enable the use of the NCipher HSM for forked children. */
+	if (strcmp(name, "chil") == 0) 
+		ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
+	/* All the operations are going to be carried out by the engine. */
+	if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) goto err;
+	ret = 1;
+ err:
+	if (!ret)
+		{
+		TSerr(TS_F_TS_CONF_SET_DEFAULT_ENGINE, 
+		      TS_R_COULD_NOT_SET_ENGINE);
+		ERR_add_error_data(2, "engine:", name);
+		}
+	if (e) ENGINE_free(e);
+	return ret;
+	}
+
+#endif
+
+int TS_CONF_set_signer_cert(CONF *conf, const char *section,
+			    const char *cert, TS_RESP_CTX *ctx)
+	{
+	int ret = 0;
+	X509 *cert_obj = NULL;
+	if (!cert) 
+		cert = NCONF_get_string(conf, section, ENV_SIGNER_CERT);
+	if (!cert)
+		{
+		TS_CONF_lookup_fail(section, ENV_SIGNER_CERT);
+		goto err;
+		}
+	if (!(cert_obj = TS_CONF_load_cert(cert)))
+		goto err;
+	if (!TS_RESP_CTX_set_signer_cert(ctx, cert_obj))
+		goto err;
+
+	ret = 1;
+ err:
+	X509_free(cert_obj);
+	return ret;
+	}
+
+int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs,
+		      TS_RESP_CTX *ctx)
+	{
+	int ret = 0;
+	STACK_OF(X509) *certs_obj = NULL;
+	if (!certs) 
+		certs = NCONF_get_string(conf, section, ENV_CERTS);
+	/* Certificate chain is optional. */
+	if (!certs) goto end;
+	if (!(certs_obj = TS_CONF_load_certs(certs))) goto err;
+	if (!TS_RESP_CTX_set_certs(ctx, certs_obj)) goto err;
+ end:
+	ret = 1;
+ err:
+	sk_X509_pop_free(certs_obj, X509_free);
+	return ret;
+	}
+
+int TS_CONF_set_signer_key(CONF *conf, const char *section,
+			   const char *key, const char *pass,
+			   TS_RESP_CTX *ctx)
+	{
+	int ret = 0;
+	EVP_PKEY *key_obj = NULL;
+	if (!key) 
+		key = NCONF_get_string(conf, section, ENV_SIGNER_KEY);
+	if (!key)
+		{
+		TS_CONF_lookup_fail(section, ENV_SIGNER_KEY);
+		goto err;
+		}
+	if (!(key_obj = TS_CONF_load_key(key, pass))) goto err;
+	if (!TS_RESP_CTX_set_signer_key(ctx, key_obj)) goto err;
+
+	ret = 1;
+ err:
+	EVP_PKEY_free(key_obj);
+	return ret;
+	}
+
+int TS_CONF_set_def_policy(CONF *conf, const char *section,
+			   const char *policy, TS_RESP_CTX *ctx)
+	{
+	int ret = 0;
+	ASN1_OBJECT *policy_obj = NULL;
+	if (!policy) 
+		policy = NCONF_get_string(conf, section, 
+					  ENV_DEFAULT_POLICY);
+	if (!policy)
+		{
+		TS_CONF_lookup_fail(section, ENV_DEFAULT_POLICY);
+		goto err;
+		}
+	if (!(policy_obj = OBJ_txt2obj(policy, 0)))
+		{
+		TS_CONF_invalid(section, ENV_DEFAULT_POLICY);
+		goto err;
+		}
+	if (!TS_RESP_CTX_set_def_policy(ctx, policy_obj))
+		goto err;
+
+	ret = 1;
+ err:
+	ASN1_OBJECT_free(policy_obj);
+	return ret;
+	}
+
+int TS_CONF_set_policies(CONF *conf, const char *section,
+			 TS_RESP_CTX *ctx)
+	{
+	int ret = 0;
+	int i;
+	STACK_OF(CONF_VALUE) *list = NULL;
+	char *policies = NCONF_get_string(conf, section, 
+					  ENV_OTHER_POLICIES);
+	/* If no other policy is specified, that's fine. */
+	if (policies && !(list = X509V3_parse_list(policies)))
+		{
+		TS_CONF_invalid(section, ENV_OTHER_POLICIES);
+		goto err;
+		}
+	for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
+		{
+		CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
+		const char *extval = val->value ? val->value : val->name;
+		ASN1_OBJECT *objtmp;
+		if (!(objtmp = OBJ_txt2obj(extval, 0)))
+			{
+			TS_CONF_invalid(section, ENV_OTHER_POLICIES);
+			goto err;
+			}
+		if (!TS_RESP_CTX_add_policy(ctx, objtmp))
+			goto err;
+		ASN1_OBJECT_free(objtmp);
+		}
+
+	ret = 1;
+ err:
+	sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
+	return ret;
+	}
+
+int TS_CONF_set_digests(CONF *conf, const char *section,
+			TS_RESP_CTX *ctx)
+	{
+	int ret = 0;
+	int i;
+	STACK_OF(CONF_VALUE) *list = NULL;
+	char *digests = NCONF_get_string(conf, section, ENV_DIGESTS);
+	if (!digests)
+		{
+		TS_CONF_lookup_fail(section, ENV_DIGESTS);
+		goto err;
+		}
+	if (!(list = X509V3_parse_list(digests)))
+		{
+		TS_CONF_invalid(section, ENV_DIGESTS);
+		goto err;
+		}
+	if (sk_CONF_VALUE_num(list) == 0)
+		{
+		TS_CONF_invalid(section, ENV_DIGESTS);
+		goto err;
+		}
+	for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
+		{
+		CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
+		const char *extval = val->value ? val->value : val->name;
+		const EVP_MD *md;
+		if (!(md = EVP_get_digestbyname(extval)))
+			{
+			TS_CONF_invalid(section, ENV_DIGESTS);
+			goto err;
+			}
+		if (!TS_RESP_CTX_add_md(ctx, md))
+			goto err;
+		}
+
+	ret = 1;
+ err:
+	sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
+	return ret;
+	}
+
+int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx)
+	{
+	int ret = 0;
+	int i;
+	int secs = 0, millis = 0, micros = 0;
+	STACK_OF(CONF_VALUE) *list = NULL;
+	char *accuracy = NCONF_get_string(conf, section, ENV_ACCURACY);
+
+	if (accuracy && !(list = X509V3_parse_list(accuracy)))
+		{
+		TS_CONF_invalid(section, ENV_ACCURACY);
+		goto err;
+		}
+	for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
+		{
+		CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
+		if (strcmp(val->name, ENV_VALUE_SECS) == 0) 
+			{
+			if (val->value) secs = atoi(val->value);
+			}
+		else if (strcmp(val->name, ENV_VALUE_MILLISECS) == 0)
+			{
+			if (val->value) millis = atoi(val->value);
+			}
+		else if (strcmp(val->name, ENV_VALUE_MICROSECS) == 0)
+			{
+			if (val->value) micros = atoi(val->value);
+			}
+		else
+			{
+			TS_CONF_invalid(section, ENV_ACCURACY);
+			goto err;
+			}
+		}
+	if (!TS_RESP_CTX_set_accuracy(ctx, secs, millis, micros))
+		goto err;
+
+	ret = 1;
+ err:
+	sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
+	return ret;
+	}
+
+int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section,
+				       TS_RESP_CTX *ctx)
+	{
+	int ret = 0;
+	long digits = 0;
+	
+	/* If not specified, set the default value to 0, i.e. sec  precision */
+	if (!NCONF_get_number_e(conf, section, ENV_CLOCK_PRECISION_DIGITS,
+				&digits))
+		digits = 0;
+	if (digits < 0 || digits > TS_MAX_CLOCK_PRECISION_DIGITS)
+		{
+		TS_CONF_invalid(section, ENV_CLOCK_PRECISION_DIGITS);
+		goto err;
+		}
+
+	if (!TS_RESP_CTX_set_clock_precision_digits(ctx, digits))
+		goto err;
+
+	return 1;
+ err:
+	return ret;
+	}
+
+static int TS_CONF_add_flag(CONF *conf, const char *section, const char *field,
+			    int flag, TS_RESP_CTX *ctx)
+	{
+	/* Default is false. */
+	const char *value = NCONF_get_string(conf, section, field);
+	if (value)
+		{
+		if (strcmp(value, ENV_VALUE_YES) == 0)
+			TS_RESP_CTX_add_flags(ctx, flag);
+		else if (strcmp(value, ENV_VALUE_NO) != 0)
+			{
+			TS_CONF_invalid(section, field);
+			return 0;
+			}
+		}
+
+	return 1;
+	}
+
+int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx)
+	{
+	return TS_CONF_add_flag(conf, section, ENV_ORDERING, TS_ORDERING, ctx);
+	}
+
+int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx)
+	{
+	return TS_CONF_add_flag(conf, section, ENV_TSA_NAME, TS_TSA_NAME, ctx);
+	}
+
+int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
+				  TS_RESP_CTX *ctx)
+	{
+	return TS_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN, 
+				TS_ESS_CERT_ID_CHAIN, ctx);
+	}
diff --git a/openssl/crypto/ts/ts_err.c b/openssl/crypto/ts/ts_err.c
new file mode 100644
index 0000000..a08b0ff
--- /dev/null
+++ b/openssl/crypto/ts/ts_err.c
@@ -0,0 +1,179 @@
+/* crypto/ts/ts_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ts.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_TS,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_TS,0,reason)
+
+static ERR_STRING_DATA TS_str_functs[]=
+	{
+{ERR_FUNC(TS_F_D2I_TS_RESP),	"d2i_TS_RESP"},
+{ERR_FUNC(TS_F_DEF_SERIAL_CB),	"DEF_SERIAL_CB"},
+{ERR_FUNC(TS_F_DEF_TIME_CB),	"DEF_TIME_CB"},
+{ERR_FUNC(TS_F_ESS_ADD_SIGNING_CERT),	"ESS_ADD_SIGNING_CERT"},
+{ERR_FUNC(TS_F_ESS_CERT_ID_NEW_INIT),	"ESS_CERT_ID_NEW_INIT"},
+{ERR_FUNC(TS_F_ESS_SIGNING_CERT_NEW_INIT),	"ESS_SIGNING_CERT_NEW_INIT"},
+{ERR_FUNC(TS_F_INT_TS_RESP_VERIFY_TOKEN),	"INT_TS_RESP_VERIFY_TOKEN"},
+{ERR_FUNC(TS_F_PKCS7_TO_TS_TST_INFO),	"PKCS7_to_TS_TST_INFO"},
+{ERR_FUNC(TS_F_TS_ACCURACY_SET_MICROS),	"TS_ACCURACY_set_micros"},
+{ERR_FUNC(TS_F_TS_ACCURACY_SET_MILLIS),	"TS_ACCURACY_set_millis"},
+{ERR_FUNC(TS_F_TS_ACCURACY_SET_SECONDS),	"TS_ACCURACY_set_seconds"},
+{ERR_FUNC(TS_F_TS_CHECK_IMPRINTS),	"TS_CHECK_IMPRINTS"},
+{ERR_FUNC(TS_F_TS_CHECK_NONCES),	"TS_CHECK_NONCES"},
+{ERR_FUNC(TS_F_TS_CHECK_POLICY),	"TS_CHECK_POLICY"},
+{ERR_FUNC(TS_F_TS_CHECK_SIGNING_CERTS),	"TS_CHECK_SIGNING_CERTS"},
+{ERR_FUNC(TS_F_TS_CHECK_STATUS_INFO),	"TS_CHECK_STATUS_INFO"},
+{ERR_FUNC(TS_F_TS_COMPUTE_IMPRINT),	"TS_COMPUTE_IMPRINT"},
+{ERR_FUNC(TS_F_TS_CONF_SET_DEFAULT_ENGINE),	"TS_CONF_set_default_engine"},
+{ERR_FUNC(TS_F_TS_GET_STATUS_TEXT),	"TS_GET_STATUS_TEXT"},
+{ERR_FUNC(TS_F_TS_MSG_IMPRINT_SET_ALGO),	"TS_MSG_IMPRINT_set_algo"},
+{ERR_FUNC(TS_F_TS_REQ_SET_MSG_IMPRINT),	"TS_REQ_set_msg_imprint"},
+{ERR_FUNC(TS_F_TS_REQ_SET_NONCE),	"TS_REQ_set_nonce"},
+{ERR_FUNC(TS_F_TS_REQ_SET_POLICY_ID),	"TS_REQ_set_policy_id"},
+{ERR_FUNC(TS_F_TS_RESP_CREATE_RESPONSE),	"TS_RESP_create_response"},
+{ERR_FUNC(TS_F_TS_RESP_CREATE_TST_INFO),	"TS_RESP_CREATE_TST_INFO"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO),	"TS_RESP_CTX_add_failure_info"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_MD),	"TS_RESP_CTX_add_md"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_POLICY),	"TS_RESP_CTX_add_policy"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_NEW),	"TS_RESP_CTX_new"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_SET_ACCURACY),	"TS_RESP_CTX_set_accuracy"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_SET_CERTS),	"TS_RESP_CTX_set_certs"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_SET_DEF_POLICY),	"TS_RESP_CTX_set_def_policy"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_SET_SIGNER_CERT),	"TS_RESP_CTX_set_signer_cert"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_SET_STATUS_INFO),	"TS_RESP_CTX_set_status_info"},
+{ERR_FUNC(TS_F_TS_RESP_GET_POLICY),	"TS_RESP_GET_POLICY"},
+{ERR_FUNC(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION),	"TS_RESP_SET_GENTIME_WITH_PRECISION"},
+{ERR_FUNC(TS_F_TS_RESP_SET_STATUS_INFO),	"TS_RESP_set_status_info"},
+{ERR_FUNC(TS_F_TS_RESP_SET_TST_INFO),	"TS_RESP_set_tst_info"},
+{ERR_FUNC(TS_F_TS_RESP_SIGN),	"TS_RESP_SIGN"},
+{ERR_FUNC(TS_F_TS_RESP_VERIFY_SIGNATURE),	"TS_RESP_verify_signature"},
+{ERR_FUNC(TS_F_TS_RESP_VERIFY_TOKEN),	"TS_RESP_verify_token"},
+{ERR_FUNC(TS_F_TS_TST_INFO_SET_ACCURACY),	"TS_TST_INFO_set_accuracy"},
+{ERR_FUNC(TS_F_TS_TST_INFO_SET_MSG_IMPRINT),	"TS_TST_INFO_set_msg_imprint"},
+{ERR_FUNC(TS_F_TS_TST_INFO_SET_NONCE),	"TS_TST_INFO_set_nonce"},
+{ERR_FUNC(TS_F_TS_TST_INFO_SET_POLICY_ID),	"TS_TST_INFO_set_policy_id"},
+{ERR_FUNC(TS_F_TS_TST_INFO_SET_SERIAL),	"TS_TST_INFO_set_serial"},
+{ERR_FUNC(TS_F_TS_TST_INFO_SET_TIME),	"TS_TST_INFO_set_time"},
+{ERR_FUNC(TS_F_TS_TST_INFO_SET_TSA),	"TS_TST_INFO_set_tsa"},
+{ERR_FUNC(TS_F_TS_VERIFY),	"TS_VERIFY"},
+{ERR_FUNC(TS_F_TS_VERIFY_CERT),	"TS_VERIFY_CERT"},
+{ERR_FUNC(TS_F_TS_VERIFY_CTX_NEW),	"TS_VERIFY_CTX_new"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA TS_str_reasons[]=
+	{
+{ERR_REASON(TS_R_BAD_PKCS7_TYPE)         ,"bad pkcs7 type"},
+{ERR_REASON(TS_R_BAD_TYPE)               ,"bad type"},
+{ERR_REASON(TS_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"},
+{ERR_REASON(TS_R_COULD_NOT_SET_ENGINE)   ,"could not set engine"},
+{ERR_REASON(TS_R_COULD_NOT_SET_TIME)     ,"could not set time"},
+{ERR_REASON(TS_R_D2I_TS_RESP_INT_FAILED) ,"d2i ts resp int failed"},
+{ERR_REASON(TS_R_DETACHED_CONTENT)       ,"detached content"},
+{ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_ERROR),"ess add signing cert error"},
+{ERR_REASON(TS_R_ESS_SIGNING_CERTIFICATE_ERROR),"ess signing certificate error"},
+{ERR_REASON(TS_R_INVALID_NULL_POINTER)   ,"invalid null pointer"},
+{ERR_REASON(TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE),"invalid signer certificate purpose"},
+{ERR_REASON(TS_R_MESSAGE_IMPRINT_MISMATCH),"message imprint mismatch"},
+{ERR_REASON(TS_R_NONCE_MISMATCH)         ,"nonce mismatch"},
+{ERR_REASON(TS_R_NONCE_NOT_RETURNED)     ,"nonce not returned"},
+{ERR_REASON(TS_R_NO_CONTENT)             ,"no content"},
+{ERR_REASON(TS_R_NO_TIME_STAMP_TOKEN)    ,"no time stamp token"},
+{ERR_REASON(TS_R_PKCS7_ADD_SIGNATURE_ERROR),"pkcs7 add signature error"},
+{ERR_REASON(TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR),"pkcs7 add signed attr error"},
+{ERR_REASON(TS_R_PKCS7_TO_TS_TST_INFO_FAILED),"pkcs7 to ts tst info failed"},
+{ERR_REASON(TS_R_POLICY_MISMATCH)        ,"policy mismatch"},
+{ERR_REASON(TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
+{ERR_REASON(TS_R_RESPONSE_SETUP_ERROR)   ,"response setup error"},
+{ERR_REASON(TS_R_SIGNATURE_FAILURE)      ,"signature failure"},
+{ERR_REASON(TS_R_THERE_MUST_BE_ONE_SIGNER),"there must be one signer"},
+{ERR_REASON(TS_R_TIME_SYSCALL_ERROR)     ,"time syscall error"},
+{ERR_REASON(TS_R_TOKEN_NOT_PRESENT)      ,"token not present"},
+{ERR_REASON(TS_R_TOKEN_PRESENT)          ,"token present"},
+{ERR_REASON(TS_R_TSA_NAME_MISMATCH)      ,"tsa name mismatch"},
+{ERR_REASON(TS_R_TSA_UNTRUSTED)          ,"tsa untrusted"},
+{ERR_REASON(TS_R_TST_INFO_SETUP_ERROR)   ,"tst info setup error"},
+{ERR_REASON(TS_R_TS_DATASIGN)            ,"ts datasign"},
+{ERR_REASON(TS_R_UNACCEPTABLE_POLICY)    ,"unacceptable policy"},
+{ERR_REASON(TS_R_UNSUPPORTED_MD_ALGORITHM),"unsupported md algorithm"},
+{ERR_REASON(TS_R_UNSUPPORTED_VERSION)    ,"unsupported version"},
+{ERR_REASON(TS_R_WRONG_CONTENT_TYPE)     ,"wrong content type"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_TS_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(TS_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,TS_str_functs);
+		ERR_load_strings(0,TS_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/ts/ts_lib.c b/openssl/crypto/ts/ts_lib.c
new file mode 100644
index 0000000..e8608db
--- /dev/null
+++ b/openssl/crypto/ts/ts_lib.c
@@ -0,0 +1,145 @@
+/* crypto/ts/ts_lib.c */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/bn.h>
+#include <openssl/x509v3.h>
+#include "ts.h"
+
+/* Local function declarations. */
+
+/* Function definitions. */
+
+int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num)
+	{
+	BIGNUM num_bn;
+	int result = 0;
+	char *hex;
+
+	BN_init(&num_bn);
+	ASN1_INTEGER_to_BN(num, &num_bn);
+	if ((hex = BN_bn2hex(&num_bn))) 
+		{
+		result = BIO_write(bio, "0x", 2) > 0;
+		result = result && BIO_write(bio, hex, strlen(hex)) > 0;
+		OPENSSL_free(hex);
+		}
+	BN_free(&num_bn);
+
+	return result;
+	}
+
+int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj)
+	{
+	char obj_txt[128];
+
+	int len = OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0);
+	BIO_write(bio, obj_txt, len);
+	BIO_write(bio, "\n", 1);
+
+	return 1;
+	}
+
+int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions)
+	{
+	int i, critical, n;
+	X509_EXTENSION *ex;
+	ASN1_OBJECT *obj;
+
+	BIO_printf(bio, "Extensions:\n");
+	n = X509v3_get_ext_count(extensions);
+	for (i = 0; i < n; i++)
+		{
+		ex = X509v3_get_ext(extensions, i);
+		obj = X509_EXTENSION_get_object(ex);
+		i2a_ASN1_OBJECT(bio, obj);
+		critical = X509_EXTENSION_get_critical(ex);
+		BIO_printf(bio, ": %s\n", critical ? "critical" : "");
+		if (!X509V3_EXT_print(bio, ex, 0, 4))
+			{
+			BIO_printf(bio, "%4s", "");
+			M_ASN1_OCTET_STRING_print(bio, ex->value);
+			}
+		BIO_write(bio, "\n", 1);
+		}
+
+	return 1;
+	}
+
+int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg)
+	{
+	int i = OBJ_obj2nid(alg->algorithm);
+	return BIO_printf(bio, "Hash Algorithm: %s\n",
+		(i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
+	}
+
+int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *a)
+	{
+	const ASN1_OCTET_STRING *msg;
+
+	TS_X509_ALGOR_print_bio(bio, TS_MSG_IMPRINT_get_algo(a));
+
+	BIO_printf(bio, "Message data:\n");
+	msg = TS_MSG_IMPRINT_get_msg(a);
+	BIO_dump_indent(bio, (const char *)M_ASN1_STRING_data(msg), 
+			M_ASN1_STRING_length(msg), 4);
+
+	return 1;
+	}
diff --git a/openssl/crypto/ts/ts_req_print.c b/openssl/crypto/ts/ts_req_print.c
new file mode 100644
index 0000000..eba12c3
--- /dev/null
+++ b/openssl/crypto/ts/ts_req_print.c
@@ -0,0 +1,102 @@
+/* crypto/ts/ts_req_print.c */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/bn.h>
+#include <openssl/x509v3.h>
+#include <openssl/ts.h>
+
+/* Function definitions. */
+
+int TS_REQ_print_bio(BIO *bio, TS_REQ *a)
+	{
+	int v;
+	ASN1_OBJECT *policy_id;
+	const ASN1_INTEGER *nonce;
+
+	if (a == NULL) return 0;
+
+	v = TS_REQ_get_version(a);
+	BIO_printf(bio, "Version: %d\n", v);
+
+	TS_MSG_IMPRINT_print_bio(bio, TS_REQ_get_msg_imprint(a));
+
+	BIO_printf(bio, "Policy OID: ");
+	policy_id = TS_REQ_get_policy_id(a);
+	if (policy_id == NULL)
+		BIO_printf(bio, "unspecified\n");
+	else	
+		TS_OBJ_print_bio(bio, policy_id);
+
+	BIO_printf(bio, "Nonce: ");
+	nonce = TS_REQ_get_nonce(a);
+	if (nonce == NULL)
+		BIO_printf(bio, "unspecified");
+	else
+		TS_ASN1_INTEGER_print_bio(bio, nonce);
+	BIO_write(bio, "\n", 1);
+
+	BIO_printf(bio, "Certificate required: %s\n", 
+		   TS_REQ_get_cert_req(a) ? "yes" : "no");
+
+	TS_ext_print_bio(bio, TS_REQ_get_exts(a));
+
+	return 1;
+	}
diff --git a/openssl/crypto/ts/ts_req_utils.c b/openssl/crypto/ts/ts_req_utils.c
new file mode 100644
index 0000000..43280c1
--- /dev/null
+++ b/openssl/crypto/ts/ts_req_utils.c
@@ -0,0 +1,234 @@
+/* crypto/ts/ts_req_utils.c */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/x509v3.h>
+#include <openssl/ts.h>
+
+int TS_REQ_set_version(TS_REQ *a, long version)
+	{
+	return ASN1_INTEGER_set(a->version, version);
+	}
+
+long TS_REQ_get_version(const TS_REQ *a)
+	{
+	return ASN1_INTEGER_get(a->version);
+	}
+
+int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint)
+	{
+	TS_MSG_IMPRINT *new_msg_imprint;
+
+	if (a->msg_imprint == msg_imprint)
+		return 1;
+	new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint);
+	if (new_msg_imprint == NULL)
+		{
+		TSerr(TS_F_TS_REQ_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	TS_MSG_IMPRINT_free(a->msg_imprint);
+	a->msg_imprint = new_msg_imprint;
+	return 1;
+	}
+
+TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a)
+	{
+	return a->msg_imprint;
+	}
+
+int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg)
+	{
+	X509_ALGOR *new_alg;
+
+	if (a->hash_algo == alg)
+		return 1;
+	new_alg = X509_ALGOR_dup(alg);
+	if (new_alg == NULL)
+		{
+		TSerr(TS_F_TS_MSG_IMPRINT_SET_ALGO, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	X509_ALGOR_free(a->hash_algo);
+	a->hash_algo = new_alg;
+	return 1;
+	}
+
+X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a)
+	{
+	return a->hash_algo;
+	}
+
+int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len)
+	{
+	return ASN1_OCTET_STRING_set(a->hashed_msg, d, len);
+	}
+
+ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a)
+	{
+	return a->hashed_msg;
+	}
+
+int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy)
+	{
+	ASN1_OBJECT *new_policy;
+
+	if (a->policy_id == policy)
+		return 1;
+	new_policy = OBJ_dup(policy);
+	if (new_policy == NULL)
+		{
+		TSerr(TS_F_TS_REQ_SET_POLICY_ID, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	ASN1_OBJECT_free(a->policy_id);
+	a->policy_id = new_policy;
+	return 1;
+	}
+
+ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a)
+	{
+	return a->policy_id;
+	}
+
+int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce)
+	{
+	ASN1_INTEGER *new_nonce;
+
+	if (a->nonce == nonce)
+		return 1;
+	new_nonce = ASN1_INTEGER_dup(nonce);
+	if (new_nonce == NULL)
+		{
+		TSerr(TS_F_TS_REQ_SET_NONCE, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	ASN1_INTEGER_free(a->nonce);
+	a->nonce = new_nonce;
+	return 1;
+	}
+
+const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a)
+	{
+	return a->nonce;
+	}
+
+int TS_REQ_set_cert_req(TS_REQ *a, int cert_req)
+	{
+	a->cert_req = cert_req ? 0xFF : 0x00;
+	return 1;
+	}
+
+int TS_REQ_get_cert_req(const TS_REQ *a)
+	{
+	return a->cert_req ? 1 : 0;
+	}
+
+STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a)
+	{
+	return a->extensions;
+	}
+
+void TS_REQ_ext_free(TS_REQ *a)
+	{
+	if (!a) return;
+	sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free);
+	a->extensions = NULL;
+	}
+
+int TS_REQ_get_ext_count(TS_REQ *a)
+	{
+	return X509v3_get_ext_count(a->extensions);
+	}
+
+int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos)
+	{
+	return X509v3_get_ext_by_NID(a->extensions, nid, lastpos);
+	}
+
+int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos)
+	{
+	return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos);
+	}
+
+int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos)
+	{
+	return X509v3_get_ext_by_critical(a->extensions, crit, lastpos);
+	}
+
+X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc)
+	{
+	return X509v3_get_ext(a->extensions,loc);
+	}
+
+X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc)
+	{
+	return X509v3_delete_ext(a->extensions,loc);
+	}
+
+int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc)
+	{
+	return X509v3_add_ext(&a->extensions,ex,loc) != NULL;
+	}
+
+void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx)
+	{
+	return X509V3_get_d2i(a->extensions, nid, crit, idx);
+	}
diff --git a/openssl/crypto/ts/ts_rsp_print.c b/openssl/crypto/ts/ts_rsp_print.c
new file mode 100644
index 0000000..2106251
--- /dev/null
+++ b/openssl/crypto/ts/ts_rsp_print.c
@@ -0,0 +1,287 @@
+/* crypto/ts/ts_resp_print.c */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/bn.h>
+#include <openssl/x509v3.h>
+#include "ts.h"
+
+struct status_map_st
+	{
+	int bit;
+	const char *text;
+	};
+
+/* Local function declarations. */
+
+static int TS_status_map_print(BIO *bio, struct status_map_st *a,
+			       ASN1_BIT_STRING *v);
+static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy);
+
+/* Function definitions. */
+
+int TS_RESP_print_bio(BIO *bio, TS_RESP *a)
+	{
+	TS_TST_INFO *tst_info;
+
+	BIO_printf(bio, "Status info:\n");
+	TS_STATUS_INFO_print_bio(bio, TS_RESP_get_status_info(a));
+
+	BIO_printf(bio, "\nTST info:\n");
+	tst_info = TS_RESP_get_tst_info(a);
+	if (tst_info != NULL)
+		TS_TST_INFO_print_bio(bio, TS_RESP_get_tst_info(a));
+	else
+		BIO_printf(bio, "Not included.\n");
+		
+	return 1;
+	}
+
+int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a)
+	{
+	static const char *status_map[] =
+		{
+		"Granted.",
+		"Granted with modifications.",
+		"Rejected.",
+		"Waiting.",
+		"Revocation warning.",
+		"Revoked."
+		};
+	static struct status_map_st failure_map[] =
+		{
+		{ TS_INFO_BAD_ALG,
+		"unrecognized or unsupported algorithm identifier" },
+		{ TS_INFO_BAD_REQUEST,
+		"transaction not permitted or supported" },
+		{ TS_INFO_BAD_DATA_FORMAT,
+		"the data submitted has the wrong format" },
+		{ TS_INFO_TIME_NOT_AVAILABLE,
+		"the TSA's time source is not available" },
+		{ TS_INFO_UNACCEPTED_POLICY,
+		"the requested TSA policy is not supported by the TSA" },
+		{ TS_INFO_UNACCEPTED_EXTENSION,
+		"the requested extension is not supported by the TSA" },
+		{ TS_INFO_ADD_INFO_NOT_AVAILABLE,
+		"the additional information requested could not be understood "
+		"or is not available" },
+		{ TS_INFO_SYSTEM_FAILURE,
+		"the request cannot be handled due to system failure" },
+		{ -1, NULL }
+		};
+	long status;
+	int i, lines = 0;
+
+	/* Printing status code. */
+	BIO_printf(bio, "Status: ");
+	status = ASN1_INTEGER_get(a->status);
+	if (0 <= status && status < (long)(sizeof(status_map)/sizeof(status_map[0])))
+		BIO_printf(bio, "%s\n", status_map[status]);
+	else
+		BIO_printf(bio, "out of bounds\n");
+	
+	/* Printing status description. */
+	BIO_printf(bio, "Status description: ");
+	for (i = 0; i < sk_ASN1_UTF8STRING_num(a->text); ++i)
+		{
+		if (i > 0)
+			BIO_puts(bio, "\t");
+		ASN1_STRING_print_ex(bio, sk_ASN1_UTF8STRING_value(a->text, i),
+				     0);
+		BIO_puts(bio, "\n");
+		}
+	if (i == 0)
+		BIO_printf(bio, "unspecified\n");
+
+	/* Printing failure information. */
+	BIO_printf(bio, "Failure info: ");
+	if (a->failure_info != NULL)
+		lines = TS_status_map_print(bio, failure_map,
+					    a->failure_info);
+	if (lines == 0)
+		BIO_printf(bio, "unspecified");
+	BIO_printf(bio, "\n");
+
+	return 1;
+	}
+
+static int TS_status_map_print(BIO *bio, struct status_map_st *a,
+			       ASN1_BIT_STRING *v)
+	{
+	int lines = 0;
+
+	for (; a->bit >= 0; ++a)
+		{
+		if (ASN1_BIT_STRING_get_bit(v, a->bit))
+			{
+			if (++lines > 1)
+				BIO_printf(bio, ", ");
+			BIO_printf(bio, "%s", a->text);
+			}
+		}
+
+	return lines;
+	}
+
+int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a)
+	{
+	int v;
+	ASN1_OBJECT *policy_id;
+	const ASN1_INTEGER *serial;
+	const ASN1_GENERALIZEDTIME *gtime;
+	TS_ACCURACY *accuracy;
+	const ASN1_INTEGER *nonce;
+	GENERAL_NAME *tsa_name;
+
+	if (a == NULL) return 0;
+
+	/* Print version. */
+	v = TS_TST_INFO_get_version(a);
+	BIO_printf(bio, "Version: %d\n", v);
+
+	/* Print policy id. */
+	BIO_printf(bio, "Policy OID: ");
+	policy_id = TS_TST_INFO_get_policy_id(a);
+	TS_OBJ_print_bio(bio, policy_id);
+
+	/* Print message imprint. */
+	TS_MSG_IMPRINT_print_bio(bio, TS_TST_INFO_get_msg_imprint(a));
+
+	/* Print serial number. */
+	BIO_printf(bio, "Serial number: ");
+	serial = TS_TST_INFO_get_serial(a);
+	if (serial == NULL)
+		BIO_printf(bio, "unspecified");
+	else
+		TS_ASN1_INTEGER_print_bio(bio, serial);
+	BIO_write(bio, "\n", 1);
+
+	/* Print time stamp. */
+	BIO_printf(bio, "Time stamp: ");
+	gtime = TS_TST_INFO_get_time(a);
+	ASN1_GENERALIZEDTIME_print(bio, gtime);
+	BIO_write(bio, "\n", 1);
+
+	/* Print accuracy. */
+	BIO_printf(bio, "Accuracy: ");
+	accuracy = TS_TST_INFO_get_accuracy(a);
+	if (accuracy == NULL)
+		BIO_printf(bio, "unspecified");
+	else
+		TS_ACCURACY_print_bio(bio, accuracy);
+	BIO_write(bio, "\n", 1);
+
+	/* Print ordering. */
+	BIO_printf(bio, "Ordering: %s\n", 
+		   TS_TST_INFO_get_ordering(a) ? "yes" : "no");
+
+	/* Print nonce. */
+	BIO_printf(bio, "Nonce: ");
+	nonce = TS_TST_INFO_get_nonce(a);
+	if (nonce == NULL)
+		BIO_printf(bio, "unspecified");
+	else
+		TS_ASN1_INTEGER_print_bio(bio, nonce);
+	BIO_write(bio, "\n", 1);
+
+	/* Print TSA name. */
+	BIO_printf(bio, "TSA: ");
+	tsa_name = TS_TST_INFO_get_tsa(a);
+	if (tsa_name == NULL)
+		BIO_printf(bio, "unspecified");
+	else
+		{
+		STACK_OF(CONF_VALUE) *nval;
+		if ((nval = i2v_GENERAL_NAME(NULL, tsa_name, NULL)))
+			X509V3_EXT_val_prn(bio, nval, 0, 0);
+		sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
+		}
+	BIO_write(bio, "\n", 1);
+
+	/* Print extensions. */
+	TS_ext_print_bio(bio, TS_TST_INFO_get_exts(a));
+
+	return 1;
+	}
+
+static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy)
+	{
+	const ASN1_INTEGER *seconds = TS_ACCURACY_get_seconds(accuracy);
+	const ASN1_INTEGER *millis = TS_ACCURACY_get_millis(accuracy);
+	const ASN1_INTEGER *micros = TS_ACCURACY_get_micros(accuracy);
+
+	if (seconds != NULL)
+		TS_ASN1_INTEGER_print_bio(bio, seconds);
+	else
+		BIO_printf(bio, "unspecified");
+	BIO_printf(bio, " seconds, ");
+	if (millis != NULL)
+		TS_ASN1_INTEGER_print_bio(bio, millis);
+	else
+		BIO_printf(bio, "unspecified");
+	BIO_printf(bio, " millis, ");
+	if (micros != NULL)
+		TS_ASN1_INTEGER_print_bio(bio, micros);
+	else
+		BIO_printf(bio, "unspecified");
+	BIO_printf(bio, " micros");
+
+	return 1;
+	}
diff --git a/openssl/crypto/ts/ts_rsp_sign.c b/openssl/crypto/ts/ts_rsp_sign.c
new file mode 100644
index 0000000..b0f023c
--- /dev/null
+++ b/openssl/crypto/ts/ts_rsp_sign.c
@@ -0,0 +1,1020 @@
+/* crypto/ts/ts_resp_sign.c */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+
+#if defined(OPENSSL_SYS_UNIX)
+#include <sys/time.h>
+#endif
+
+#include <openssl/objects.h>
+#include <openssl/ts.h>
+#include <openssl/pkcs7.h>
+
+/* Private function declarations. */
+
+static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *);
+static int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec);
+static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *);
+
+static void TS_RESP_CTX_init(TS_RESP_CTX *ctx);
+static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx);
+static int TS_RESP_check_request(TS_RESP_CTX *ctx);
+static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx);
+static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, 
+					    ASN1_OBJECT *policy);
+static int TS_RESP_process_extensions(TS_RESP_CTX *ctx);
+static int TS_RESP_sign(TS_RESP_CTX *ctx);
+
+static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, 
+						   STACK_OF(X509) *certs);
+static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed);
+static int TS_TST_INFO_content_new(PKCS7 *p7);
+static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc);
+
+static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision(
+	ASN1_GENERALIZEDTIME *, long, long, unsigned);
+
+/* Default callbacks for response generation. */
+
+static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data)
+	{
+	ASN1_INTEGER *serial = ASN1_INTEGER_new();
+	if (!serial) goto err;
+	if (!ASN1_INTEGER_set(serial, 1)) goto err;
+	return serial;
+ err:
+	TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE);
+	TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+				    "Error during serial number generation.");
+	return NULL;
+	}
+
+#if defined(OPENSSL_SYS_UNIX)
+
+/* Use the gettimeofday function call. */
+static int def_time_cb(struct TS_resp_ctx *ctx, void *data, 
+		       long *sec, long *usec)
+	{
+	struct timeval tv;
+	if (gettimeofday(&tv, NULL) != 0) 
+		{
+		TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+					    "Time is not available.");
+		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
+		return 0;
+		}
+	/* Return time to caller. */
+	*sec = tv.tv_sec;
+	*usec = tv.tv_usec;
+
+	return 1;
+	}
+
+#else
+
+/* Use the time function call that provides only seconds precision. */
+static int def_time_cb(struct TS_resp_ctx *ctx, void *data, 
+		       long *sec, long *usec)
+	{
+	time_t t;
+	if (time(&t) == (time_t) -1)
+		{
+		TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+					    "Time is not available.");
+		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
+		return 0;
+		}
+	/* Return time to caller, only second precision. */
+	*sec = (long) t;
+	*usec = 0;
+
+	return 1;
+	}
+
+#endif
+
+static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext,
+			    void *data)
+	{
+	/* No extensions are processed here. */
+	TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+				    "Unsupported extension.");
+	TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION);
+	return 0;
+	}
+
+/* TS_RESP_CTX management functions. */
+
+TS_RESP_CTX *TS_RESP_CTX_new()
+	{
+	TS_RESP_CTX *ctx;
+
+	if (!(ctx = (TS_RESP_CTX *) OPENSSL_malloc(sizeof(TS_RESP_CTX))))
+		{
+		TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+	memset(ctx, 0, sizeof(TS_RESP_CTX));
+
+	/* Setting default callbacks. */
+	ctx->serial_cb = def_serial_cb;
+	ctx->time_cb = def_time_cb;
+	ctx->extension_cb = def_extension_cb;
+
+	return ctx;
+	}
+
+void TS_RESP_CTX_free(TS_RESP_CTX *ctx)
+	{
+	if (!ctx) return;
+
+	X509_free(ctx->signer_cert);
+	EVP_PKEY_free(ctx->signer_key);
+	sk_X509_pop_free(ctx->certs, X509_free);
+	sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free);
+	ASN1_OBJECT_free(ctx->default_policy);
+	sk_EVP_MD_free(ctx->mds);	/* No EVP_MD_free method exists. */
+	ASN1_INTEGER_free(ctx->seconds);
+	ASN1_INTEGER_free(ctx->millis);
+	ASN1_INTEGER_free(ctx->micros);
+	OPENSSL_free(ctx);
+	}
+
+int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer)
+	{
+	if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1)
+		{
+		TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT, 
+		      TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE);
+		return 0;
+		}
+	if (ctx->signer_cert) X509_free(ctx->signer_cert);
+	ctx->signer_cert = signer;
+	CRYPTO_add(&ctx->signer_cert->references, +1, CRYPTO_LOCK_X509);
+	return 1;
+	}
+
+int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key)
+	{
+	if (ctx->signer_key) EVP_PKEY_free(ctx->signer_key);
+	ctx->signer_key = key;
+	CRYPTO_add(&ctx->signer_key->references, +1, CRYPTO_LOCK_EVP_PKEY);
+
+	return 1;
+	}
+
+int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy)
+	{
+	if (ctx->default_policy) ASN1_OBJECT_free(ctx->default_policy);
+	if (!(ctx->default_policy = OBJ_dup(def_policy))) goto err;
+	return 1;
+ err:
+	TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE);
+	return 0;
+	}
+
+int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs)
+	{
+	int i;
+
+	if (ctx->certs)
+		{
+		sk_X509_pop_free(ctx->certs, X509_free);
+		ctx->certs = NULL;
+		}
+	if (!certs) return 1;
+	if (!(ctx->certs = sk_X509_dup(certs))) 
+		{
+		TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	for (i = 0; i < sk_X509_num(ctx->certs); ++i)
+		{
+		X509 *cert = sk_X509_value(ctx->certs, i);
+		CRYPTO_add(&cert->references, +1, CRYPTO_LOCK_X509);
+		}
+
+	return 1;
+	}
+
+int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy)
+	{
+	ASN1_OBJECT *copy = NULL;
+
+	/* Create new policy stack if necessary. */
+	if (!ctx->policies && !(ctx->policies = sk_ASN1_OBJECT_new_null())) 
+		goto err;
+	if (!(copy = OBJ_dup(policy))) goto err;
+	if (!sk_ASN1_OBJECT_push(ctx->policies, copy)) goto err;
+
+	return 1;
+ err:
+	TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE);
+	ASN1_OBJECT_free(copy);
+	return 0;
+	}
+
+int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md)
+	{
+	/* Create new md stack if necessary. */
+	if (!ctx->mds && !(ctx->mds = sk_EVP_MD_new_null())) 
+		goto err;
+	/* Add the shared md, no copy needed. */
+	if (!sk_EVP_MD_push(ctx->mds, (EVP_MD *)md)) goto err;
+
+	return 1;
+ err:
+	TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE);
+	return 0;
+	}
+
+#define TS_RESP_CTX_accuracy_free(ctx)		\
+	ASN1_INTEGER_free(ctx->seconds);	\
+	ctx->seconds = NULL;			\
+	ASN1_INTEGER_free(ctx->millis);		\
+	ctx->millis = NULL;			\
+	ASN1_INTEGER_free(ctx->micros);		\
+	ctx->micros = NULL;
+
+int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, 
+			     int secs, int millis, int micros)
+	{
+
+	TS_RESP_CTX_accuracy_free(ctx);
+	if (secs && (!(ctx->seconds = ASN1_INTEGER_new())
+		     || !ASN1_INTEGER_set(ctx->seconds, secs)))
+		goto err;
+	if (millis && (!(ctx->millis = ASN1_INTEGER_new())
+		       || !ASN1_INTEGER_set(ctx->millis, millis)))
+		goto err;
+	if (micros && (!(ctx->micros = ASN1_INTEGER_new())
+		       || !ASN1_INTEGER_set(ctx->micros, micros)))
+		goto err;
+
+	return 1;
+ err:
+	TS_RESP_CTX_accuracy_free(ctx);
+	TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
+	return 0;
+	}
+
+void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags)
+	{
+	ctx->flags |= flags;
+	}
+
+void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data)
+	{
+	ctx->serial_cb = cb;
+	ctx->serial_cb_data = data;
+	}
+
+void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data)
+	{
+	ctx->time_cb = cb;
+	ctx->time_cb_data = data;
+	}
+
+void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, 
+				  TS_extension_cb cb, void *data)
+	{
+	ctx->extension_cb = cb;
+	ctx->extension_cb_data = data;
+	}
+
+int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, 
+				int status, const char *text)
+	{
+	TS_STATUS_INFO *si = NULL;
+	ASN1_UTF8STRING *utf8_text = NULL;
+	int ret = 0;
+
+	if (!(si = TS_STATUS_INFO_new())) goto err;
+	if (!ASN1_INTEGER_set(si->status, status)) goto err;
+	if (text)
+		{
+		if (!(utf8_text = ASN1_UTF8STRING_new())
+		    || !ASN1_STRING_set(utf8_text, text, strlen(text)))
+			goto err;
+		if (!si->text && !(si->text = sk_ASN1_UTF8STRING_new_null()))
+			goto err;
+		if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text)) goto err;
+		utf8_text = NULL;	/* Ownership is lost. */
+		}
+	if (!TS_RESP_set_status_info(ctx->response, si)) goto err;
+	ret = 1;
+ err:
+	if (!ret)
+		TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
+	TS_STATUS_INFO_free(si);
+	ASN1_UTF8STRING_free(utf8_text);
+	return ret;
+	}
+
+int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, 
+				     int status, const char *text)
+	{
+	int ret = 1;
+	TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response);
+
+	if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED)
+		{
+		/* Status has not been set, set it now. */
+		ret = TS_RESP_CTX_set_status_info(ctx, status, text);
+		}
+	return ret;
+	}
+
+int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure)
+	{
+	TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response);
+	if (!si->failure_info && !(si->failure_info = ASN1_BIT_STRING_new()))
+		goto err;
+	if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1))
+		goto err;
+	return 1;
+ err:
+	TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE);
+	return 0;
+	}
+
+TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx)
+	{
+	return ctx->request;
+	}
+
+TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx)
+	{
+	return ctx->tst_info;
+	}
+
+int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, unsigned precision)
+       {
+       if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
+	       return 0;
+       ctx->clock_precision_digits = precision;
+       return 1;
+       }
+
+/* Main entry method of the response generation. */
+TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio)
+	{
+	ASN1_OBJECT *policy;
+	TS_RESP *response;
+	int result = 0;
+
+	TS_RESP_CTX_init(ctx);
+
+	/* Creating the response object. */
+	if (!(ctx->response = TS_RESP_new())) 
+		{
+		TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE);
+		goto end;
+		}
+
+	/* Parsing DER request. */
+	if (!(ctx->request = d2i_TS_REQ_bio(req_bio, NULL)))
+		{
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+					    "Bad request format or "
+					    "system error.");
+		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
+		goto end;
+		}
+
+	/* Setting default status info. */
+	if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL))
+		goto end;
+
+	/* Checking the request format. */
+	if (!TS_RESP_check_request(ctx)) goto end;
+
+	/* Checking acceptable policies. */
+	if (!(policy = TS_RESP_get_policy(ctx))) goto end;
+
+	/* Creating the TS_TST_INFO object. */
+	if (!(ctx->tst_info = TS_RESP_create_tst_info(ctx, policy)))
+		goto end;
+
+	/* Processing extensions. */
+	if (!TS_RESP_process_extensions(ctx)) goto end;
+
+	/* Generating the signature. */
+	if (!TS_RESP_sign(ctx)) goto end;
+
+	/* Everything was successful. */
+	result = 1;
+ end:
+	if (!result)
+		{
+		TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR);
+		if (ctx->response != NULL)
+			{
+			if (TS_RESP_CTX_set_status_info_cond(ctx,
+				TS_STATUS_REJECTION, "Error during response "
+				"generation.") == 0)
+				{
+				TS_RESP_free(ctx->response);
+				ctx->response = NULL;
+				}
+			}
+		}
+	response = ctx->response;
+	ctx->response = NULL;	/* Ownership will be returned to caller. */
+	TS_RESP_CTX_cleanup(ctx);
+	return response;
+	}
+
+/* Initializes the variable part of the context. */
+static void TS_RESP_CTX_init(TS_RESP_CTX *ctx)
+	{
+	ctx->request = NULL;
+	ctx->response = NULL;
+	ctx->tst_info = NULL;
+	}
+
+/* Cleans up the variable part of the context. */
+static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx)
+	{
+	TS_REQ_free(ctx->request);
+	ctx->request = NULL;
+	TS_RESP_free(ctx->response);
+	ctx->response = NULL;
+	TS_TST_INFO_free(ctx->tst_info);
+	ctx->tst_info = NULL;
+	}
+
+/* Checks the format and content of the request. */
+static int TS_RESP_check_request(TS_RESP_CTX *ctx)
+	{
+	TS_REQ *request = ctx->request;
+	TS_MSG_IMPRINT *msg_imprint;
+	X509_ALGOR *md_alg;
+	int md_alg_id;
+	const ASN1_OCTET_STRING *digest;
+	EVP_MD *md = NULL;
+	int i;
+
+	/* Checking request version. */
+	if (TS_REQ_get_version(request) != 1)
+		{
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+					    "Bad request version.");
+		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST);
+		return 0;
+		}
+
+	/* Checking message digest algorithm. */
+	msg_imprint = TS_REQ_get_msg_imprint(request);
+	md_alg = TS_MSG_IMPRINT_get_algo(msg_imprint);
+	md_alg_id = OBJ_obj2nid(md_alg->algorithm);
+	for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i)
+		{
+		EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i);
+		if (md_alg_id == EVP_MD_type(current_md))
+			md = current_md;
+		}
+	if (!md)
+		{
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+					    "Message digest algorithm is "
+					    "not supported.");
+		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
+		return 0;
+		}
+
+	/* No message digest takes parameter. */
+	if (md_alg->parameter 
+	    && ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL)
+		{
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+					    "Superfluous message digest "
+					    "parameter.");
+		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
+		return 0;
+		}
+	/* Checking message digest size. */
+	digest = TS_MSG_IMPRINT_get_msg(msg_imprint);
+	if (digest->length != EVP_MD_size(md))
+		{
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+					    "Bad message digest.");
+		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
+		return 0;
+		}
+
+	return 1;
+	}
+
+/* Returns the TSA policy based on the requested and acceptable policies. */
+static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx)
+	{
+	ASN1_OBJECT *requested = TS_REQ_get_policy_id(ctx->request);
+	ASN1_OBJECT *policy = NULL;
+	int i;
+
+	if (ctx->default_policy == NULL)
+		{
+		TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER);
+		return NULL;
+		}
+	/* Return the default policy if none is requested or the default is
+	   requested. */
+	if (!requested || !OBJ_cmp(requested, ctx->default_policy))
+		policy = ctx->default_policy;
+
+	/* Check if the policy is acceptable. */
+	for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i)
+		{
+		ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i);
+		if (!OBJ_cmp(requested, current))
+			policy = current;
+		}
+	if (!policy)
+		{
+		TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY);
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+					    "Requested policy is not "
+					    "supported.");
+		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY);
+		}
+	return policy;
+	}
+
+/* Creates the TS_TST_INFO object based on the settings of the context. */
+static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx,
+					    ASN1_OBJECT *policy)
+	{
+	int result = 0;
+	TS_TST_INFO *tst_info = NULL;
+	ASN1_INTEGER *serial = NULL;
+	ASN1_GENERALIZEDTIME *asn1_time = NULL;
+	long sec, usec;
+	TS_ACCURACY *accuracy = NULL;
+	const ASN1_INTEGER *nonce;
+	GENERAL_NAME *tsa_name = NULL;
+
+	if (!(tst_info = TS_TST_INFO_new())) goto end;
+	if (!TS_TST_INFO_set_version(tst_info, 1)) goto end;
+	if (!TS_TST_INFO_set_policy_id(tst_info, policy)) goto end;
+	if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint))
+		goto end;
+	if (!(serial = (*ctx->serial_cb)(ctx, ctx->serial_cb_data))
+	    || !TS_TST_INFO_set_serial(tst_info, serial))
+		goto end;
+	if (!(*ctx->time_cb)(ctx, ctx->time_cb_data, &sec, &usec)
+            || !(asn1_time = TS_RESP_set_genTime_with_precision(NULL, 
+					sec, usec, 
+					ctx->clock_precision_digits))
+	    || !TS_TST_INFO_set_time(tst_info, asn1_time))
+		goto end;
+
+	/* Setting accuracy if needed. */
+	if ((ctx->seconds || ctx->millis || ctx->micros) 
+	    && !(accuracy = TS_ACCURACY_new()))
+		goto end;
+
+	if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds))
+		goto end;
+	if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis))
+		goto end;
+	if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros))
+		goto end;
+	if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy)) 
+		goto end;
+
+	/* Setting ordering. */
+	if ((ctx->flags & TS_ORDERING) 
+	    && !TS_TST_INFO_set_ordering(tst_info, 1))
+		goto end;
+	
+	/* Setting nonce if needed. */
+	if ((nonce = TS_REQ_get_nonce(ctx->request)) != NULL
+	    && !TS_TST_INFO_set_nonce(tst_info, nonce))
+		goto end;
+
+	/* Setting TSA name to subject of signer certificate. */
+	if (ctx->flags & TS_TSA_NAME)
+		{
+		if (!(tsa_name = GENERAL_NAME_new())) goto end;
+		tsa_name->type = GEN_DIRNAME;
+		tsa_name->d.dirn = 
+			X509_NAME_dup(ctx->signer_cert->cert_info->subject);
+		if (!tsa_name->d.dirn) goto end;
+		if (!TS_TST_INFO_set_tsa(tst_info, tsa_name)) goto end;
+		}
+
+	result = 1;
+ end:
+	if (!result)
+		{
+		TS_TST_INFO_free(tst_info);
+		tst_info = NULL;
+		TSerr(TS_F_TS_RESP_CREATE_TST_INFO, TS_R_TST_INFO_SETUP_ERROR);
+		TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
+						 "Error during TSTInfo "
+						 "generation.");
+		}
+	GENERAL_NAME_free(tsa_name);
+	TS_ACCURACY_free(accuracy);
+	ASN1_GENERALIZEDTIME_free(asn1_time);
+	ASN1_INTEGER_free(serial);
+	
+	return tst_info;
+	}
+
+/* Processing the extensions of the request. */
+static int TS_RESP_process_extensions(TS_RESP_CTX *ctx)
+	{
+	STACK_OF(X509_EXTENSION) *exts = TS_REQ_get_exts(ctx->request);
+	int i;
+	int ok = 1;
+
+	for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i)
+		{
+		X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
+		/* XXXXX The last argument was previously
+		   (void *)ctx->extension_cb, but ISO C doesn't permit
+		   converting a function pointer to void *.  For lack of
+		   better information, I'm placing a NULL there instead.
+		   The callback can pick its own address out from the ctx
+		   anyway...
+		*/
+		ok = (*ctx->extension_cb)(ctx, ext, NULL);
+		}
+
+	return ok;
+	}
+
+/* Functions for signing the TS_TST_INFO structure of the context. */
+static int TS_RESP_sign(TS_RESP_CTX *ctx)
+	{
+	int ret = 0;
+	PKCS7 *p7 = NULL;
+	PKCS7_SIGNER_INFO *si;
+	STACK_OF(X509) *certs;	/* Certificates to include in sc. */
+	ESS_SIGNING_CERT *sc = NULL;
+	ASN1_OBJECT *oid;
+	BIO *p7bio = NULL;
+	int i;
+
+	/* Check if signcert and pkey match. */
+	if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) {
+		TSerr(TS_F_TS_RESP_SIGN, 
+		      TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+                goto err;
+	}
+
+	/* Create a new PKCS7 signed object. */
+	if (!(p7 = PKCS7_new())) {
+		TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if (!PKCS7_set_type(p7, NID_pkcs7_signed)) goto err;
+
+	/* Force SignedData version to be 3 instead of the default 1. */
+	if (!ASN1_INTEGER_set(p7->d.sign->version, 3)) goto err;
+
+	/* Add signer certificate and optional certificate chain. */
+	if (TS_REQ_get_cert_req(ctx->request))
+		{
+		PKCS7_add_certificate(p7, ctx->signer_cert);
+		if (ctx->certs)
+			{
+			for(i = 0; i < sk_X509_num(ctx->certs); ++i) 
+				{
+				X509 *cert = sk_X509_value(ctx->certs, i);
+				PKCS7_add_certificate(p7, cert);
+				}
+			}
+		}
+
+	/* Add a new signer info. */
+    	if (!(si = PKCS7_add_signature(p7, ctx->signer_cert, 
+				       ctx->signer_key, EVP_sha1())))
+		{
+		TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR);
+		goto err;
+		}
+
+	/* Add content type signed attribute to the signer info. */
+	oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
+	if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
+					V_ASN1_OBJECT, oid))
+		{
+		TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR);
+		goto err;
+		}
+
+	/* Create the ESS SigningCertificate attribute which contains 
+	   the signer certificate id and optionally the certificate chain. */
+	certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL;
+	if (!(sc = ESS_SIGNING_CERT_new_init(ctx->signer_cert, certs)))
+		goto err;
+
+	/* Add SigningCertificate signed attribute to the signer info. */
+	if (!ESS_add_signing_cert(si, sc))
+		{
+		TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR);
+		goto err;
+		}	
+
+	/* Add a new empty NID_id_smime_ct_TSTInfo encapsulated content. */
+	if (!TS_TST_INFO_content_new(p7)) goto err;
+
+	/* Add the DER encoded tst_info to the PKCS7 structure. */
+	if (!(p7bio = PKCS7_dataInit(p7, NULL))) {
+		TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	/* Convert tst_info to DER. */
+	if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info))
+		{
+		TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
+		goto err;
+		}
+
+	/* Create the signature and add it to the signer info. */
+        if (!PKCS7_dataFinal(p7, p7bio))
+		{
+		TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
+		goto err;
+		}
+
+	/* Set new PKCS7 and TST_INFO objects. */
+	TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info);
+	p7 = NULL;		/* Ownership is lost. */
+	ctx->tst_info = NULL;	/* Ownership is lost. */
+
+	ret = 1;
+ err:
+	if (!ret)
+		TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
+						 "Error during signature "
+						 "generation.");
+	BIO_free_all(p7bio);
+	ESS_SIGNING_CERT_free(sc);
+	PKCS7_free(p7);
+	return ret;
+	}
+
+static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, 
+						   STACK_OF(X509) *certs)
+	{
+	ESS_CERT_ID *cid;
+	ESS_SIGNING_CERT *sc = NULL;
+	int i;
+
+	/* Creating the ESS_CERT_ID stack. */
+	if (!(sc = ESS_SIGNING_CERT_new())) goto err;
+	if (!sc->cert_ids && !(sc->cert_ids = sk_ESS_CERT_ID_new_null()))
+		goto err;
+
+	/* Adding the signing certificate id. */
+	if (!(cid = ESS_CERT_ID_new_init(signcert, 0))
+	    || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
+		goto err;
+	/* Adding the certificate chain ids. */
+	for (i = 0; i < sk_X509_num(certs); ++i)
+		{
+		X509 *cert = sk_X509_value(certs, i);
+		if (!(cid = ESS_CERT_ID_new_init(cert, 1))
+		    || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
+			goto err;
+		}
+
+	return sc;
+err:
+	ESS_SIGNING_CERT_free(sc);
+	TSerr(TS_F_ESS_SIGNING_CERT_NEW_INIT, ERR_R_MALLOC_FAILURE);
+	return NULL;
+	}
+
+static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed)
+	{
+	ESS_CERT_ID *cid = NULL;
+	GENERAL_NAME *name = NULL;
+	
+	/* Recompute SHA1 hash of certificate if necessary (side effect). */
+	X509_check_purpose(cert, -1, 0);
+
+	if (!(cid = ESS_CERT_ID_new())) goto err;
+	if (!ASN1_OCTET_STRING_set(cid->hash, cert->sha1_hash,
+				   sizeof(cert->sha1_hash)))
+		goto err;
+
+	/* Setting the issuer/serial if requested. */
+	if (issuer_needed)
+		{
+		/* Creating issuer/serial structure. */
+		if (!cid->issuer_serial
+		    && !(cid->issuer_serial = ESS_ISSUER_SERIAL_new()))
+			goto err;
+		/* Creating general name from the certificate issuer. */
+		if (!(name = GENERAL_NAME_new())) goto err;
+		name->type = GEN_DIRNAME;
+		if (!(name->d.dirn = X509_NAME_dup(cert->cert_info->issuer))) 
+			goto err;
+		if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) 
+			goto err;
+		name = NULL;	/* Ownership is lost. */
+		/* Setting the serial number. */
+		ASN1_INTEGER_free(cid->issuer_serial->serial);
+		if (!(cid->issuer_serial->serial = 
+		      ASN1_INTEGER_dup(cert->cert_info->serialNumber)))
+			goto err;
+		}
+
+	return cid;
+err:
+	GENERAL_NAME_free(name);
+	ESS_CERT_ID_free(cid);
+	TSerr(TS_F_ESS_CERT_ID_NEW_INIT, ERR_R_MALLOC_FAILURE);
+	return NULL;
+	}
+
+static int TS_TST_INFO_content_new(PKCS7 *p7)
+	{
+	PKCS7 *ret = NULL;
+	ASN1_OCTET_STRING *octet_string = NULL;
+
+	/* Create new encapsulated NID_id_smime_ct_TSTInfo content. */
+	if (!(ret = PKCS7_new())) goto err;
+	if (!(ret->d.other = ASN1_TYPE_new())) goto err;
+	ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
+	if (!(octet_string = ASN1_OCTET_STRING_new())) goto err;
+	ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string);
+	octet_string = NULL;
+
+	/* Add encapsulated content to signed PKCS7 structure. */
+	if (!PKCS7_set_content(p7, ret)) goto err;
+
+	return 1;
+ err:
+	ASN1_OCTET_STRING_free(octet_string);
+	PKCS7_free(ret);
+	return 0;
+	}
+
+static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc)
+	{
+	ASN1_STRING *seq = NULL;
+	unsigned char *p, *pp = NULL;
+	int len;
+
+	len = i2d_ESS_SIGNING_CERT(sc, NULL);
+	if (!(pp = (unsigned char *) OPENSSL_malloc(len)))
+		{
+		TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	p = pp;
+	i2d_ESS_SIGNING_CERT(sc, &p);
+	if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len))
+		{
+		TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	OPENSSL_free(pp); pp = NULL;
+	return PKCS7_add_signed_attribute(si, 
+					  NID_id_smime_aa_signingCertificate,
+					  V_ASN1_SEQUENCE, seq);
+ err:
+	ASN1_STRING_free(seq);
+	OPENSSL_free(pp);
+
+	return 0;
+	}
+
+
+static ASN1_GENERALIZEDTIME *
+TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time, 
+				   long sec, long usec, unsigned precision)
+	{
+	time_t time_sec = (time_t) sec;
+	struct tm *tm = NULL;	
+	char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS];
+	char *p = genTime_str;
+	char *p_end = genTime_str + sizeof(genTime_str);
+
+	if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
+		goto err;
+
+	
+	if (!(tm = gmtime(&time_sec)))
+		goto err;
+
+	/* 
+	 * Put "genTime_str" in GeneralizedTime format.  We work around the 
+	 * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST 
+	 * NOT include fractional seconds") and OpenSSL related functions to 
+	 * meet the rfc3161 requirement: "GeneralizedTime syntax can include 
+	 * fraction-of-second details". 
+	 */                   
+	p += BIO_snprintf(p, p_end - p,
+			  "%04d%02d%02d%02d%02d%02d",
+			  tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, 
+			  tm->tm_hour, tm->tm_min, tm->tm_sec);
+	if (precision > 0)
+	{
+		/* Add fraction of seconds (leave space for dot and null). */
+		BIO_snprintf(p, 2 + precision, ".%ld", usec);
+		/* We cannot use the snprintf return value, 
+		   because it might have been truncated. */
+		p += strlen(p);
+
+		/* To make things a bit harder, X.690 | ISO/IEC 8825-1 provides
+		   the following restrictions for a DER-encoding, which OpenSSL
+		   (specifically ASN1_GENERALIZEDTIME_check() function) doesn't 
+		   support:
+		   "The encoding MUST terminate with a "Z" (which means "Zulu" 
+		   time). The decimal point element, if present, MUST be the 
+		   point option ".". The fractional-seconds elements, 
+		   if present, MUST omit all trailing 0's; 
+		   if the elements correspond to 0, they MUST be wholly
+		   omitted, and the decimal point element also MUST be
+		   omitted." */
+		/* Remove trailing zeros. The dot guarantees the exit
+		   condition of this loop even if all the digits are zero. */
+		while (*--p == '0')
+			/* empty */;
+		/* p points to either the dot or the last non-zero digit. */
+		if (*p != '.') ++p;
+		}
+	/* Add the trailing Z and the terminating null. */
+	*p++ = 'Z';
+	*p++ = '\0';
+
+	/* Now call OpenSSL to check and set our genTime value */
+	if (!asn1_time && !(asn1_time = M_ASN1_GENERALIZEDTIME_new()))
+		goto err;
+	if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str))
+		{
+		ASN1_GENERALIZEDTIME_free(asn1_time);
+		goto err;
+		}
+
+	return asn1_time;
+ err:
+	TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME);
+	return NULL;
+	}
diff --git a/openssl/crypto/ts/ts_rsp_utils.c b/openssl/crypto/ts/ts_rsp_utils.c
new file mode 100644
index 0000000..401c1fd
--- /dev/null
+++ b/openssl/crypto/ts/ts_rsp_utils.c
@@ -0,0 +1,409 @@
+/* crypto/ts/ts_resp_utils.c */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/ts.h>
+#include <openssl/pkcs7.h>
+
+/* Function definitions. */
+
+int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *status_info)
+	{
+	TS_STATUS_INFO *new_status_info;
+
+	if (a->status_info == status_info)
+		return 1;
+	new_status_info = TS_STATUS_INFO_dup(status_info);
+	if (new_status_info == NULL)
+		{
+		TSerr(TS_F_TS_RESP_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	TS_STATUS_INFO_free(a->status_info);
+	a->status_info = new_status_info;
+
+	return 1;
+	}
+
+TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a)
+	{
+	return a->status_info;
+	}
+
+/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */
+void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info)
+	{
+	/* Set new PKCS7 and TST_INFO objects. */
+	PKCS7_free(a->token);
+	a->token = p7;
+	TS_TST_INFO_free(a->tst_info);
+	a->tst_info = tst_info;
+	}
+
+PKCS7 *TS_RESP_get_token(TS_RESP *a)
+	{
+	return a->token;
+	}
+
+TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a)
+	{
+	return a->tst_info;
+	}
+
+int TS_TST_INFO_set_version(TS_TST_INFO *a, long version)
+	{
+	return ASN1_INTEGER_set(a->version, version);
+	}
+
+long TS_TST_INFO_get_version(const TS_TST_INFO *a)
+	{
+	return ASN1_INTEGER_get(a->version);
+	}
+
+int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy)
+	{
+	ASN1_OBJECT *new_policy;
+
+	if (a->policy_id == policy)
+		return 1;
+	new_policy = OBJ_dup(policy);
+	if (new_policy == NULL)
+		{
+		TSerr(TS_F_TS_TST_INFO_SET_POLICY_ID, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	ASN1_OBJECT_free(a->policy_id);
+	a->policy_id = new_policy;
+	return 1;
+	}
+
+ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a)
+	{
+	return a->policy_id;
+	}
+
+int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint)
+	{
+	TS_MSG_IMPRINT *new_msg_imprint;
+
+	if (a->msg_imprint == msg_imprint)
+		return 1;
+	new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint);
+	if (new_msg_imprint == NULL)
+		{
+		TSerr(TS_F_TS_TST_INFO_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	TS_MSG_IMPRINT_free(a->msg_imprint);
+	a->msg_imprint = new_msg_imprint;
+	return 1;
+	}
+
+TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a)
+	{
+	return a->msg_imprint;
+	}
+
+int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial)
+	{
+	ASN1_INTEGER *new_serial;
+
+	if (a->serial == serial)
+		return 1;
+	new_serial = ASN1_INTEGER_dup(serial);
+	if (new_serial == NULL)
+		{
+		TSerr(TS_F_TS_TST_INFO_SET_SERIAL, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	ASN1_INTEGER_free(a->serial);
+	a->serial = new_serial;
+	return 1;
+	}
+
+const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a)
+	{
+	return a->serial;
+	}
+
+int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime)
+	{
+	ASN1_GENERALIZEDTIME *new_time;
+
+	if (a->time == gtime)
+		return 1;
+	new_time = M_ASN1_GENERALIZEDTIME_dup(gtime);
+	if (new_time == NULL)
+		{
+		TSerr(TS_F_TS_TST_INFO_SET_TIME, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	ASN1_GENERALIZEDTIME_free(a->time);
+	a->time = new_time;
+	return 1;
+	}
+
+const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a)
+	{
+	return a->time;
+	}
+
+int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy)
+	{
+	TS_ACCURACY *new_accuracy;
+
+	if (a->accuracy == accuracy)
+		return 1;
+	new_accuracy = TS_ACCURACY_dup(accuracy);
+	if (new_accuracy == NULL)
+		{
+		TSerr(TS_F_TS_TST_INFO_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	TS_ACCURACY_free(a->accuracy);
+	a->accuracy = new_accuracy;
+	return 1;
+	}
+
+TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a)
+	{
+	return a->accuracy;
+	}
+
+int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds)
+	{
+	ASN1_INTEGER *new_seconds;
+
+	if (a->seconds == seconds)
+		return 1;
+	new_seconds = ASN1_INTEGER_dup(seconds);
+	if (new_seconds == NULL)
+		{
+		TSerr(TS_F_TS_ACCURACY_SET_SECONDS, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	ASN1_INTEGER_free(a->seconds);
+	a->seconds = new_seconds;
+	return 1;
+	}
+
+const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a)
+	{
+	return a->seconds;
+	}
+
+int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis)
+	{
+	ASN1_INTEGER *new_millis = NULL;
+
+	if (a->millis == millis)
+		return 1;
+	if (millis != NULL)
+		{
+		new_millis = ASN1_INTEGER_dup(millis);
+		if (new_millis == NULL)
+			{
+			TSerr(TS_F_TS_ACCURACY_SET_MILLIS, 
+			      ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		}
+	ASN1_INTEGER_free(a->millis);
+	a->millis = new_millis;
+	return 1;
+	}
+
+const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a)
+	{
+	return a->millis;
+	}
+
+int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros)
+	{
+	ASN1_INTEGER *new_micros = NULL;
+
+	if (a->micros == micros)
+		return 1;
+	if (micros != NULL)
+		{
+		new_micros = ASN1_INTEGER_dup(micros);
+		if (new_micros == NULL)
+			{
+			TSerr(TS_F_TS_ACCURACY_SET_MICROS, 
+			      ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		}
+	ASN1_INTEGER_free(a->micros);
+	a->micros = new_micros;
+	return 1;
+	}
+
+const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a)
+	{
+	return a->micros;
+	}
+
+int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering)
+	{
+	a->ordering = ordering ? 0xFF : 0x00;
+	return 1;
+	}
+
+int TS_TST_INFO_get_ordering(const TS_TST_INFO *a)
+	{
+	return a->ordering ? 1 : 0;
+	}
+
+int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce)
+	{
+	ASN1_INTEGER *new_nonce;
+
+	if (a->nonce == nonce)
+		return 1;
+	new_nonce = ASN1_INTEGER_dup(nonce);
+	if (new_nonce == NULL)
+		{
+		TSerr(TS_F_TS_TST_INFO_SET_NONCE, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	ASN1_INTEGER_free(a->nonce);
+	a->nonce = new_nonce;
+	return 1;
+	}
+
+const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a)
+	{
+	return a->nonce;
+	}
+
+int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa)
+	{
+	GENERAL_NAME *new_tsa;
+
+	if (a->tsa == tsa)
+		return 1;
+	new_tsa = GENERAL_NAME_dup(tsa);
+	if (new_tsa == NULL)
+		{
+		TSerr(TS_F_TS_TST_INFO_SET_TSA, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	GENERAL_NAME_free(a->tsa);
+	a->tsa = new_tsa;
+	return 1;
+	}
+
+GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a)
+	{
+	return a->tsa;
+	}
+
+STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a)
+	{
+	return a->extensions;
+	}
+
+void TS_TST_INFO_ext_free(TS_TST_INFO *a)
+	{
+	if (!a) return;
+	sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free);
+	a->extensions = NULL;
+	}
+
+int TS_TST_INFO_get_ext_count(TS_TST_INFO *a)
+	{
+	return X509v3_get_ext_count(a->extensions);
+	}
+
+int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos)
+	{
+	return X509v3_get_ext_by_NID(a->extensions, nid, lastpos);
+	}
+
+int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos)
+	{
+	return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos);
+	}
+
+int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos)
+	{
+	return X509v3_get_ext_by_critical(a->extensions, crit, lastpos);
+	}
+
+X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc)
+	{
+	return X509v3_get_ext(a->extensions,loc);
+	}
+
+X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc)
+	{
+	return X509v3_delete_ext(a->extensions,loc);
+	}
+
+int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc)
+	{
+	return X509v3_add_ext(&a->extensions,ex,loc) != NULL;
+	}
+
+void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx)
+	{
+	return X509V3_get_d2i(a->extensions, nid, crit, idx);
+	}
diff --git a/openssl/crypto/ts/ts_rsp_verify.c b/openssl/crypto/ts/ts_rsp_verify.c
new file mode 100644
index 0000000..e1f3b53
--- /dev/null
+++ b/openssl/crypto/ts/ts_rsp_verify.c
@@ -0,0 +1,725 @@
+/* crypto/ts/ts_resp_verify.c */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/ts.h>
+#include <openssl/pkcs7.h>
+
+/* Private function declarations. */
+
+static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
+			  X509 *signer, STACK_OF(X509) **chain);
+static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain);
+static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si);
+static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert);
+static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo);
+static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, 
+				 PKCS7 *token, TS_TST_INFO *tst_info);
+static int TS_check_status_info(TS_RESP *response);
+static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text);
+static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info);
+static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
+			      X509_ALGOR **md_alg, 
+			      unsigned char **imprint, unsigned *imprint_len);
+static int TS_check_imprints(X509_ALGOR *algor_a, 
+			     unsigned char *imprint_a, unsigned len_a,
+			     TS_TST_INFO *tst_info);
+static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info);
+static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer);
+static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name);
+
+/*
+ * Local mapping between response codes and descriptions.
+ * Don't forget to change TS_STATUS_BUF_SIZE when modifying 
+ * the elements of this array.
+ */
+static const char *TS_status_text[] =
+	{ "granted",
+	  "grantedWithMods",
+	  "rejection",
+	  "waiting",
+	  "revocationWarning",
+	  "revocationNotification" };
+
+#define TS_STATUS_TEXT_SIZE	(sizeof(TS_status_text)/sizeof(*TS_status_text))
+
+/*
+ * This must be greater or equal to the sum of the strings in TS_status_text
+ * plus the number of its elements.
+ */
+#define TS_STATUS_BUF_SIZE	256
+
+static struct
+	{
+	int code;
+	const char *text;
+	} TS_failure_info[] =
+		{ { TS_INFO_BAD_ALG, "badAlg" },
+		  { TS_INFO_BAD_REQUEST, "badRequest" },
+		  { TS_INFO_BAD_DATA_FORMAT, "badDataFormat" },
+		  { TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable" },
+		  { TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy" },
+		  { TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension" },
+		  { TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable" },
+		  { TS_INFO_SYSTEM_FAILURE, "systemFailure" } };
+
+#define TS_FAILURE_INFO_SIZE	(sizeof(TS_failure_info) / \
+				sizeof(*TS_failure_info))
+
+/* Functions for verifying a signed TS_TST_INFO structure. */
+
+/*
+ * This function carries out the following tasks:
+ *	- Checks if there is one and only one signer.
+ *	- Search for the signing certificate in 'certs' and in the response.
+ *	- Check the extended key usage and key usage fields of the signer
+ *	certificate (done by the path validation).
+ *	- Build and validate the certificate path.
+ *	- Check if the certificate path meets the requirements of the
+ *	SigningCertificate ESS signed attribute.
+ *	- Verify the signature value.
+ *	- Returns the signer certificate in 'signer', if 'signer' is not NULL.
+ */
+int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
+			     X509_STORE *store, X509 **signer_out)
+	{
+	STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL;
+	PKCS7_SIGNER_INFO *si;
+	STACK_OF(X509) *signers = NULL;
+	X509	*signer;
+	STACK_OF(X509) *chain = NULL;
+	char	buf[4096];
+	int	i, j = 0, ret = 0;
+	BIO	*p7bio = NULL;
+
+	/* Some sanity checks first. */
+	if (!token)
+		{
+		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER);
+		goto err;
+		}
+
+	/* Check for the correct content type */
+	if(!PKCS7_type_is_signed(token))
+		{
+		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE);
+		goto err;
+		}
+
+	/* Check if there is one and only one signer. */
+	sinfos = PKCS7_get_signer_info(token);
+	if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1)
+		{
+		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE,
+		      TS_R_THERE_MUST_BE_ONE_SIGNER);
+		goto err;
+		}
+	si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0);
+
+	/* Check for no content: no data to verify signature. */
+	if (PKCS7_get_detached(token))
+		{
+		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT);
+		goto err;
+		}
+	
+	/* Get hold of the signer certificate, search only internal
+	   certificates if it was requested. */
+	signers = PKCS7_get0_signers(token, certs, 0);
+	if (!signers || sk_X509_num(signers) != 1) goto err;
+	signer = sk_X509_value(signers, 0);
+
+	/* Now verify the certificate. */
+	if (!TS_verify_cert(store, certs, signer, &chain)) goto err;
+
+	/* Check if the signer certificate is consistent with the
+	   ESS extension. */
+	if (!TS_check_signing_certs(si, chain)) goto err;
+
+	/* Creating the message digest. */
+	p7bio = PKCS7_dataInit(token, NULL);
+
+	/* We now have to 'read' from p7bio to calculate digests etc. */
+	while ((i = BIO_read(p7bio,buf,sizeof(buf))) > 0);
+
+	/* Verifying the signature. */
+	j = PKCS7_signatureVerify(p7bio, token, si, signer);
+	if (j <= 0)
+		{
+		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE);
+		goto err;
+		}
+
+	/* Return the signer certificate if needed. */
+	if (signer_out)
+		{
+		*signer_out = signer;
+		CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
+		}
+
+	ret = 1;
+
+ err:
+	BIO_free_all(p7bio);
+	sk_X509_pop_free(chain, X509_free);
+	sk_X509_free(signers);
+
+	return ret;
+	}
+
+/*
+ * The certificate chain is returned in chain. Caller is responsible for
+ * freeing the vector.
+ */
+static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
+			  X509 *signer, STACK_OF(X509) **chain)
+	{
+	X509_STORE_CTX	cert_ctx;
+	int i;
+	int ret = 1;
+
+	/* chain is an out argument. */
+	*chain = NULL;
+	X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted);
+	X509_STORE_CTX_set_purpose(&cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN);
+	i = X509_verify_cert(&cert_ctx);
+	if (i <= 0)
+		{
+		int j = X509_STORE_CTX_get_error(&cert_ctx);
+		TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR);
+		ERR_add_error_data(2, "Verify error:",
+				   X509_verify_cert_error_string(j));
+		ret = 0;
+		}
+	else
+		{
+		/* Get a copy of the certificate chain. */
+		*chain = X509_STORE_CTX_get1_chain(&cert_ctx);
+		}
+
+	X509_STORE_CTX_cleanup(&cert_ctx);
+
+	return ret;
+	}
+
+static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain)
+	{
+	ESS_SIGNING_CERT *ss = ESS_get_signing_cert(si);
+	STACK_OF(ESS_CERT_ID) *cert_ids = NULL;
+	X509 *cert;
+	int i = 0;
+	int ret = 0;
+
+	if (!ss) goto err;
+	cert_ids = ss->cert_ids;
+	/* The signer certificate must be the first in cert_ids. */
+	cert = sk_X509_value(chain, 0);
+	if (TS_find_cert(cert_ids, cert) != 0) goto err;
+	
+	/* Check the other certificates of the chain if there are more
+	   than one certificate ids in cert_ids. */
+	if (sk_ESS_CERT_ID_num(cert_ids) > 1)
+		{
+		/* All the certificates of the chain must be in cert_ids. */
+		for (i = 1; i < sk_X509_num(chain); ++i)
+			{
+			cert = sk_X509_value(chain, i);
+			if (TS_find_cert(cert_ids, cert) < 0) goto err;
+			}
+		}
+	ret = 1;
+ err:
+	if (!ret)
+		TSerr(TS_F_TS_CHECK_SIGNING_CERTS, 
+		      TS_R_ESS_SIGNING_CERTIFICATE_ERROR);
+	ESS_SIGNING_CERT_free(ss);
+	return ret;
+	}
+
+static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si)
+	{
+	ASN1_TYPE *attr;
+	const unsigned char *p;
+	attr = PKCS7_get_signed_attribute(si, 
+					  NID_id_smime_aa_signingCertificate);
+	if (!attr) return NULL;
+	p = attr->value.sequence->data;
+	return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length);
+	}
+
+/* Returns < 0 if certificate is not found, certificate index otherwise. */
+static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert)
+	{
+	int i;
+
+	if (!cert_ids || !cert) return -1;
+
+	/* Recompute SHA1 hash of certificate if necessary (side effect). */
+	X509_check_purpose(cert, -1, 0);
+
+	/* Look for cert in the cert_ids vector. */
+	for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i)
+		{
+		ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i);
+
+		/* Check the SHA-1 hash first. */
+		if (cid->hash->length == sizeof(cert->sha1_hash)
+		    && !memcmp(cid->hash->data, cert->sha1_hash,
+			       sizeof(cert->sha1_hash)))
+			{
+			/* Check the issuer/serial as well if specified. */
+			ESS_ISSUER_SERIAL *is = cid->issuer_serial;
+			if (!is || !TS_issuer_serial_cmp(is, cert->cert_info))
+				return i;
+			}
+		}
+	
+	return -1;
+	}
+
+static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo)
+	{
+	GENERAL_NAME *issuer;
+
+	if (!is || !cinfo || sk_GENERAL_NAME_num(is->issuer) != 1) return -1;
+
+	/* Check the issuer first. It must be a directory name. */
+	issuer = sk_GENERAL_NAME_value(is->issuer, 0);
+	if (issuer->type != GEN_DIRNAME 
+	    || X509_NAME_cmp(issuer->d.dirn, cinfo->issuer))
+		return -1;
+
+	/* Check the serial number, too. */
+	if (ASN1_INTEGER_cmp(is->serial, cinfo->serialNumber))
+		return -1;
+
+	return 0;
+	}
+
+/*
+ * Verifies whether 'response' contains a valid response with regards 
+ * to the settings of the context:
+ *	- Gives an error message if the TS_TST_INFO is not present.
+ *	- Calls _TS_RESP_verify_token to verify the token content.
+ */
+int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response)
+	{
+	PKCS7 *token = TS_RESP_get_token(response);
+	TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response);
+	int ret = 0;
+
+	/* Check if we have a successful TS_TST_INFO object in place. */
+	if (!TS_check_status_info(response)) goto err;
+
+	/* Check the contents of the time stamp token. */
+	if (!int_TS_RESP_verify_token(ctx, token, tst_info))
+		goto err;
+
+	ret = 1;
+ err:
+	return ret;
+	}
+
+/*
+ * Tries to extract a TS_TST_INFO structure from the PKCS7 token and
+ * calls the internal int_TS_RESP_verify_token function for verifying it.
+ */
+int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token)
+	{
+	TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token);
+	int ret = 0;
+	if (tst_info)
+		{
+		ret = int_TS_RESP_verify_token(ctx, token, tst_info);
+		TS_TST_INFO_free(tst_info);
+		}
+	return ret;
+	}
+
+/*
+ * Verifies whether the 'token' contains a valid time stamp token 
+ * with regards to the settings of the context. Only those checks are
+ * carried out that are specified in the context:
+ *	- Verifies the signature of the TS_TST_INFO.
+ *	- Checks the version number of the response.
+ *	- Check if the requested and returned policies math.
+ *	- Check if the message imprints are the same.
+ *	- Check if the nonces are the same.
+ *	- Check if the TSA name matches the signer.
+ *	- Check if the TSA name is the expected TSA.
+ */
+static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, 
+				 PKCS7 *token, TS_TST_INFO *tst_info)
+	{
+	X509 *signer = NULL;
+	GENERAL_NAME *tsa_name = TS_TST_INFO_get_tsa(tst_info);
+	X509_ALGOR *md_alg = NULL;
+	unsigned char *imprint = NULL;
+	unsigned imprint_len = 0;
+	int ret = 0;
+
+	/* Verify the signature. */
+	if ((ctx->flags & TS_VFY_SIGNATURE)
+	    && !TS_RESP_verify_signature(token, ctx->certs, ctx->store,
+					 &signer))
+		goto err;
+	
+	/* Check version number of response. */
+	if ((ctx->flags & TS_VFY_VERSION)
+	    && TS_TST_INFO_get_version(tst_info) != 1)
+		{
+		TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION);
+		goto err;
+		}
+
+	/* Check policies. */
+	if ((ctx->flags & TS_VFY_POLICY)
+	    && !TS_check_policy(ctx->policy, tst_info))
+		goto err;
+	
+	/* Check message imprints. */
+	if ((ctx->flags & TS_VFY_IMPRINT)
+	    && !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len,
+				  tst_info)) 
+		goto err;
+
+	/* Compute and check message imprints. */
+	if ((ctx->flags & TS_VFY_DATA)
+	    && (!TS_compute_imprint(ctx->data, tst_info,
+				    &md_alg, &imprint, &imprint_len)
+	    || !TS_check_imprints(md_alg, imprint, imprint_len, tst_info)))
+		goto err;
+
+	/* Check nonces. */
+	if ((ctx->flags & TS_VFY_NONCE)
+	    && !TS_check_nonces(ctx->nonce, tst_info))
+		goto err;
+
+	/* Check whether TSA name and signer certificate match. */
+	if ((ctx->flags & TS_VFY_SIGNER)
+	    && tsa_name && !TS_check_signer_name(tsa_name, signer))
+		{
+		TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH);
+		goto err;
+		}
+
+	/* Check whether the TSA is the expected one. */
+	if ((ctx->flags & TS_VFY_TSA_NAME)
+	    && !TS_check_signer_name(ctx->tsa_name, signer))
+		{
+		TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED);
+		goto err;
+		}
+
+	ret = 1;
+ err:
+	X509_free(signer);
+	X509_ALGOR_free(md_alg);
+	OPENSSL_free(imprint);
+	return ret;
+	}
+
+static int TS_check_status_info(TS_RESP *response)
+	{
+	TS_STATUS_INFO *info = TS_RESP_get_status_info(response);
+	long status = ASN1_INTEGER_get(info->status);
+	const char *status_text = NULL;
+	char *embedded_status_text = NULL;
+	char failure_text[TS_STATUS_BUF_SIZE] = "";
+
+	/* Check if everything went fine. */
+	if (status == 0 || status == 1) return 1;
+
+	/* There was an error, get the description in status_text. */
+	if (0 <= status && status < (long)TS_STATUS_TEXT_SIZE)
+		status_text = TS_status_text[status];
+	else
+		status_text = "unknown code";
+
+	/* Set the embedded_status_text to the returned description. */
+	if (sk_ASN1_UTF8STRING_num(info->text) > 0
+	    && !(embedded_status_text = TS_get_status_text(info->text)))
+		return 0;
+	
+	/* Filling in failure_text with the failure information. */
+	if (info->failure_info)
+		{
+		int i;
+		int first = 1;
+		for (i = 0; i < (int)TS_FAILURE_INFO_SIZE; ++i)
+			{
+			if (ASN1_BIT_STRING_get_bit(info->failure_info,
+						    TS_failure_info[i].code))
+				{
+				if (!first)
+					strcpy(failure_text, ",");
+				else
+					first = 0;
+				strcat(failure_text, TS_failure_info[i].text);
+				}
+			}
+		}
+	if (failure_text[0] == '\0')
+		strcpy(failure_text, "unspecified");
+
+	/* Making up the error string. */
+	TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN);
+	ERR_add_error_data(6,
+			   "status code: ", status_text,
+			   ", status text: ", embedded_status_text ? 
+			   embedded_status_text : "unspecified",
+			   ", failure codes: ", failure_text);
+	OPENSSL_free(embedded_status_text);
+
+	return 0;
+	}
+
+static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text)
+	{
+	int i;
+	unsigned int length = 0;
+	char *result = NULL;
+	char *p;
+
+	/* Determine length first. */
+	for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i)
+		{
+		ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
+		length += ASN1_STRING_length(current);
+		length += 1;	/* separator character */
+		}
+	/* Allocate memory (closing '\0' included). */
+	if (!(result = OPENSSL_malloc(length)))
+		{
+		TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+	/* Concatenate the descriptions. */
+	for (i = 0, p = result; i < sk_ASN1_UTF8STRING_num(text); ++i)
+		{
+		ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
+		length = ASN1_STRING_length(current);
+		if (i > 0) *p++ = '/';
+		strncpy(p, (const char *)ASN1_STRING_data(current), length);
+		p += length;
+		}
+	/* We do have space for this, too. */
+	*p = '\0';
+	
+	return result;
+	}
+
+static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info)
+	{
+	ASN1_OBJECT *resp_oid = TS_TST_INFO_get_policy_id(tst_info);
+
+	if (OBJ_cmp(req_oid, resp_oid) != 0)
+		{
+		TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH);
+		return 0;
+		}
+
+	return 1;
+	}
+
+static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
+			      X509_ALGOR **md_alg, 
+			      unsigned char **imprint, unsigned *imprint_len)
+	{
+	TS_MSG_IMPRINT *msg_imprint = TS_TST_INFO_get_msg_imprint(tst_info);
+	X509_ALGOR *md_alg_resp = TS_MSG_IMPRINT_get_algo(msg_imprint);
+	const EVP_MD *md;
+	EVP_MD_CTX md_ctx;
+	unsigned char buffer[4096];
+	int length;
+
+	*md_alg = NULL;
+	*imprint = NULL;
+
+	/* Return the MD algorithm of the response. */
+	if (!(*md_alg = X509_ALGOR_dup(md_alg_resp))) goto err;
+
+	/* Getting the MD object. */
+	if (!(md = EVP_get_digestbyobj((*md_alg)->algorithm)))
+		{
+		TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM);
+		goto err;
+		}
+
+	/* Compute message digest. */
+	length = EVP_MD_size(md);
+	if (length < 0)
+	    goto err;
+	*imprint_len = length;
+	if (!(*imprint = OPENSSL_malloc(*imprint_len))) 
+		{
+		TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	EVP_DigestInit(&md_ctx, md);
+	while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0)
+		{
+		EVP_DigestUpdate(&md_ctx, buffer, length);
+		}
+	EVP_DigestFinal(&md_ctx, *imprint, NULL);
+
+	return 1;
+ err:
+	X509_ALGOR_free(*md_alg);
+	OPENSSL_free(*imprint);
+	*imprint_len = 0;
+	return 0;
+	}
+
+static int TS_check_imprints(X509_ALGOR *algor_a, 
+			     unsigned char *imprint_a, unsigned len_a,
+			     TS_TST_INFO *tst_info)
+	{
+	TS_MSG_IMPRINT *b = TS_TST_INFO_get_msg_imprint(tst_info);
+	X509_ALGOR *algor_b = TS_MSG_IMPRINT_get_algo(b);
+	int ret = 0;
+
+	/* algor_a is optional. */
+	if (algor_a)
+		{
+		/* Compare algorithm OIDs. */
+		if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm)) goto err;
+
+		/* The parameter must be NULL in both. */
+		if ((algor_a->parameter 
+		     && ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL)
+		    || (algor_b->parameter
+			&& ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL))
+			goto err;
+		}
+
+	/* Compare octet strings. */
+	ret = len_a == (unsigned) ASN1_STRING_length(b->hashed_msg) &&
+		memcmp(imprint_a, ASN1_STRING_data(b->hashed_msg), len_a) == 0;
+ err:
+	if (!ret)
+		TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH);
+	return ret;
+	}
+
+static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info)
+	{
+	const ASN1_INTEGER *b = TS_TST_INFO_get_nonce(tst_info);
+
+	/* Error if nonce is missing. */
+	if (!b)
+		{
+		TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED);
+		return 0;
+		}
+
+	/* No error if a nonce is returned without being requested. */
+	if (ASN1_INTEGER_cmp(a, b) != 0)
+		{
+		TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH);
+		return 0;
+		}
+
+	return 1;
+	}
+
+/* Check if the specified TSA name matches either the subject
+   or one of the subject alternative names of the TSA certificate. */
+static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer)
+	{
+	STACK_OF(GENERAL_NAME) *gen_names = NULL;
+	int idx = -1;
+	int found = 0;
+
+	/* Check the subject name first. */
+	if (tsa_name->type == GEN_DIRNAME 
+	    && X509_name_cmp(tsa_name->d.dirn, signer->cert_info->subject) == 0)
+		return 1;
+
+	/* Check all the alternative names. */
+	gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name,
+				     NULL, &idx);
+	while (gen_names != NULL
+	       && !(found = TS_find_name(gen_names, tsa_name) >= 0))
+		{
+		/* Get the next subject alternative name,
+		   although there should be no more than one. */
+		GENERAL_NAMES_free(gen_names);
+		gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name,
+					     NULL, &idx);
+		}
+	if (gen_names) GENERAL_NAMES_free(gen_names);
+	
+	return found;
+	}
+
+/* Returns 1 if name is in gen_names, 0 otherwise. */
+static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name)
+	{
+	int i, found;
+	for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names);
+	     ++i)
+		{
+		GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i);
+		found = GENERAL_NAME_cmp(current, name) == 0;
+		}
+	return found ? i - 1 : -1;
+	}
diff --git a/openssl/crypto/ts/ts_verify_ctx.c b/openssl/crypto/ts/ts_verify_ctx.c
new file mode 100644
index 0000000..609b773
--- /dev/null
+++ b/openssl/crypto/ts/ts_verify_ctx.c
@@ -0,0 +1,159 @@
+/* crypto/ts/ts_verify_ctx.c */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2003.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/ts.h>
+
+TS_VERIFY_CTX *TS_VERIFY_CTX_new(void)
+	{
+	TS_VERIFY_CTX *ctx = 
+		(TS_VERIFY_CTX *) OPENSSL_malloc(sizeof(TS_VERIFY_CTX));
+	if (ctx)
+		memset(ctx, 0, sizeof(TS_VERIFY_CTX));
+	else
+		TSerr(TS_F_TS_VERIFY_CTX_NEW, ERR_R_MALLOC_FAILURE);
+	return ctx;
+	}
+
+void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx)
+	{
+	OPENSSL_assert(ctx != NULL);
+	memset(ctx, 0, sizeof(TS_VERIFY_CTX));
+	}
+
+void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx)
+	{
+	if (!ctx) return;
+
+	TS_VERIFY_CTX_cleanup(ctx);
+	OPENSSL_free(ctx);
+	}
+
+void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx)
+	{
+	if (!ctx) return;
+
+	X509_STORE_free(ctx->store);
+	sk_X509_pop_free(ctx->certs, X509_free);
+
+	ASN1_OBJECT_free(ctx->policy);
+
+	X509_ALGOR_free(ctx->md_alg);
+	OPENSSL_free(ctx->imprint);
+	
+	BIO_free_all(ctx->data);
+
+	ASN1_INTEGER_free(ctx->nonce);
+
+	GENERAL_NAME_free(ctx->tsa_name);
+
+	TS_VERIFY_CTX_init(ctx);
+	}
+
+TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx)
+	{
+	TS_VERIFY_CTX *ret = ctx;
+	ASN1_OBJECT *policy;
+	TS_MSG_IMPRINT *imprint;
+	X509_ALGOR *md_alg;
+	ASN1_OCTET_STRING *msg;
+	const ASN1_INTEGER *nonce;
+
+	OPENSSL_assert(req != NULL);
+	if (ret)
+		TS_VERIFY_CTX_cleanup(ret);
+	else
+		if (!(ret = TS_VERIFY_CTX_new())) return NULL;
+
+	/* Setting flags. */
+	ret->flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE);
+
+	/* Setting policy. */
+	if ((policy = TS_REQ_get_policy_id(req)) != NULL)
+		{
+		if (!(ret->policy = OBJ_dup(policy))) goto err;
+		}
+	else
+		ret->flags &= ~TS_VFY_POLICY;
+
+	/* Setting md_alg, imprint and imprint_len. */
+	imprint = TS_REQ_get_msg_imprint(req);
+	md_alg = TS_MSG_IMPRINT_get_algo(imprint);
+	if (!(ret->md_alg = X509_ALGOR_dup(md_alg))) goto err;
+	msg = TS_MSG_IMPRINT_get_msg(imprint);
+	ret->imprint_len = ASN1_STRING_length(msg);
+	if (!(ret->imprint = OPENSSL_malloc(ret->imprint_len))) goto err;
+	memcpy(ret->imprint, ASN1_STRING_data(msg), ret->imprint_len);
+
+	/* Setting nonce. */
+	if ((nonce = TS_REQ_get_nonce(req)) != NULL)
+		{
+		if (!(ret->nonce = ASN1_INTEGER_dup(nonce))) goto err;
+		}
+	else
+		ret->flags &= ~TS_VFY_NONCE;
+
+	return ret;
+ err:
+	if (ctx)
+		TS_VERIFY_CTX_cleanup(ctx);
+	else
+		TS_VERIFY_CTX_free(ret);
+	return NULL;
+	}
diff --git a/openssl/crypto/txt_db/Makefile b/openssl/crypto/txt_db/Makefile
new file mode 100644
index 0000000..e6f3033
--- /dev/null
+++ b/openssl/crypto/txt_db/Makefile
@@ -0,0 +1,84 @@
+#
+# OpenSSL/crypto/txt_db/Makefile
+#
+
+DIR=	txt_db
+TOP=	../..
+CC=	cc
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=txt_db.c
+LIBOBJ=txt_db.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= txt_db.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by top Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+txt_db.o: ../../e_os.h ../../include/openssl/bio.h
+txt_db.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+txt_db.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+txt_db.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+txt_db.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+txt_db.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+txt_db.o: ../../include/openssl/symhacks.h ../../include/openssl/txt_db.h
+txt_db.o: ../cryptlib.h txt_db.c
diff --git a/openssl/crypto/txt_db/txt_db.c b/openssl/crypto/txt_db/txt_db.c
new file mode 100644
index 0000000..6f2ce3b
--- /dev/null
+++ b/openssl/crypto/txt_db/txt_db.c
@@ -0,0 +1,388 @@
+/* crypto/txt_db/txt_db.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/txt_db.h>
+
+#undef BUFSIZE
+#define BUFSIZE	512
+
+const char TXT_DB_version[]="TXT_DB" OPENSSL_VERSION_PTEXT;
+
+TXT_DB *TXT_DB_read(BIO *in, int num)
+	{
+	TXT_DB *ret=NULL;
+	int er=1;
+	int esc=0;
+	long ln=0;
+	int i,add,n;
+	int size=BUFSIZE;
+	int offset=0;
+	char *p,*f;
+	OPENSSL_STRING *pp;
+	BUF_MEM *buf=NULL;
+
+	if ((buf=BUF_MEM_new()) == NULL) goto err;
+	if (!BUF_MEM_grow(buf,size)) goto err;
+
+	if ((ret=OPENSSL_malloc(sizeof(TXT_DB))) == NULL)
+		goto err;
+	ret->num_fields=num;
+	ret->index=NULL;
+	ret->qual=NULL;
+	if ((ret->data=sk_OPENSSL_PSTRING_new_null()) == NULL)
+		goto err;
+	if ((ret->index=OPENSSL_malloc(sizeof(*ret->index)*num)) == NULL)
+		goto err;
+	if ((ret->qual=OPENSSL_malloc(sizeof(*(ret->qual))*num)) == NULL)
+		goto err;
+	for (i=0; i<num; i++)
+		{
+		ret->index[i]=NULL;
+		ret->qual[i]=NULL;
+		}
+
+	add=(num+1)*sizeof(char *);
+	buf->data[size-1]='\0';
+	offset=0;
+	for (;;)
+		{
+		if (offset != 0)
+			{
+			size+=BUFSIZE;
+			if (!BUF_MEM_grow_clean(buf,size)) goto err;
+			}
+		buf->data[offset]='\0';
+		BIO_gets(in,&(buf->data[offset]),size-offset);
+		ln++;
+		if (buf->data[offset] == '\0') break;
+		if ((offset == 0) && (buf->data[0] == '#')) continue;
+		i=strlen(&(buf->data[offset]));
+		offset+=i;
+		if (buf->data[offset-1] != '\n')
+			continue;
+		else
+			{
+			buf->data[offset-1]='\0'; /* blat the '\n' */
+			if (!(p=OPENSSL_malloc(add+offset))) goto err;
+			offset=0;
+			}
+		pp=(char **)p;
+		p+=add;
+		n=0;
+		pp[n++]=p;
+		i=0;
+		f=buf->data;
+
+		esc=0;
+		for (;;)
+			{
+			if (*f == '\0') break;
+			if (*f == '\t')
+				{
+				if (esc)
+					p--;
+				else
+					{	
+					*(p++)='\0';
+					f++;
+					if (n >=  num) break;
+					pp[n++]=p;
+					continue;
+					}
+				}
+			esc=(*f == '\\');
+			*(p++)= *(f++);
+			}
+		*(p++)='\0';
+		if ((n != num) || (*f != '\0'))
+			{
+#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)	/* temporary fix :-( */
+			fprintf(stderr,"wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n",ln,num,n,f);
+#endif
+			er=2;
+			goto err;
+			}
+		pp[n]=p;
+		if (!sk_OPENSSL_PSTRING_push(ret->data,pp))
+			{
+#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)	/* temporary fix :-( */
+			fprintf(stderr,"failure in sk_push\n");
+#endif
+			er=2;
+			goto err;
+			}
+		}
+	er=0;
+err:
+	BUF_MEM_free(buf);
+	if (er)
+		{
+#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
+		if (er == 1) fprintf(stderr,"OPENSSL_malloc failure\n");
+#endif
+		if (ret != NULL)
+			{
+			if (ret->data != NULL) sk_OPENSSL_PSTRING_free(ret->data);
+			if (ret->index != NULL) OPENSSL_free(ret->index);
+			if (ret->qual != NULL) OPENSSL_free(ret->qual);
+			if (ret != NULL) OPENSSL_free(ret);
+			}
+		return(NULL);
+		}
+	else
+		return(ret);
+	}
+
+OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, OPENSSL_STRING *value)
+	{
+	OPENSSL_STRING *ret;
+	LHASH_OF(OPENSSL_STRING) *lh;
+
+	if (idx >= db->num_fields)
+		{
+		db->error=DB_ERROR_INDEX_OUT_OF_RANGE;
+		return(NULL);
+		}
+	lh=db->index[idx];
+	if (lh == NULL)
+		{
+		db->error=DB_ERROR_NO_INDEX;
+		return(NULL);
+		}
+	ret=lh_OPENSSL_STRING_retrieve(lh,value);
+	db->error=DB_ERROR_OK;
+	return(ret);
+	}
+
+int TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(OPENSSL_STRING *),
+			LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp)
+	{
+	LHASH_OF(OPENSSL_STRING) *idx;
+	OPENSSL_STRING *r;
+	int i,n;
+
+	if (field >= db->num_fields)
+		{
+		db->error=DB_ERROR_INDEX_OUT_OF_RANGE;
+		return(0);
+		}
+	/* FIXME: we lose type checking at this point */
+	if ((idx=(LHASH_OF(OPENSSL_STRING) *)lh_new(hash,cmp)) == NULL)
+		{
+		db->error=DB_ERROR_MALLOC;
+		return(0);
+		}
+	n=sk_OPENSSL_PSTRING_num(db->data);
+	for (i=0; i<n; i++)
+		{
+		r=sk_OPENSSL_PSTRING_value(db->data,i);
+		if ((qual != NULL) && (qual(r) == 0)) continue;
+		if ((r=lh_OPENSSL_STRING_insert(idx,r)) != NULL)
+			{
+			db->error=DB_ERROR_INDEX_CLASH;
+			db->arg1=sk_OPENSSL_PSTRING_find(db->data,r);
+			db->arg2=i;
+			lh_OPENSSL_STRING_free(idx);
+			return(0);
+			}
+		}
+	if (db->index[field] != NULL) lh_OPENSSL_STRING_free(db->index[field]);
+	db->index[field]=idx;
+	db->qual[field]=qual;
+	return(1);
+	}
+
+long TXT_DB_write(BIO *out, TXT_DB *db)
+	{
+	long i,j,n,nn,l,tot=0;
+	char *p,**pp,*f;
+	BUF_MEM *buf=NULL;
+	long ret= -1;
+
+	if ((buf=BUF_MEM_new()) == NULL)
+		goto err;
+	n=sk_OPENSSL_PSTRING_num(db->data);
+	nn=db->num_fields;
+	for (i=0; i<n; i++)
+		{
+		pp=sk_OPENSSL_PSTRING_value(db->data,i);
+
+		l=0;
+		for (j=0; j<nn; j++)
+			{
+			if (pp[j] != NULL)
+				l+=strlen(pp[j]);
+			}
+		if (!BUF_MEM_grow_clean(buf,(int)(l*2+nn))) goto err;
+
+		p=buf->data;
+		for (j=0; j<nn; j++)
+			{
+			f=pp[j];
+			if (f != NULL)
+				for (;;) 
+					{
+					if (*f == '\0') break;
+					if (*f == '\t') *(p++)='\\';
+					*(p++)= *(f++);
+					}
+			*(p++)='\t';
+			}
+		p[-1]='\n';
+		j=p-buf->data;
+		if (BIO_write(out,buf->data,(int)j) != j)
+			goto err;
+		tot+=j;
+		}
+	ret=tot;
+err:
+	if (buf != NULL) BUF_MEM_free(buf);
+	return(ret);
+	}
+
+int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *row)
+	{
+	int i;
+	OPENSSL_STRING *r;
+
+	for (i=0; i<db->num_fields; i++)
+		{
+		if (db->index[i] != NULL)
+			{
+			if ((db->qual[i] != NULL) &&
+				(db->qual[i](row) == 0)) continue;
+			r=lh_OPENSSL_STRING_retrieve(db->index[i],row);
+			if (r != NULL)
+				{
+				db->error=DB_ERROR_INDEX_CLASH;
+				db->arg1=i;
+				db->arg_row=r;
+				goto err;
+				}
+			}
+		}
+	/* We have passed the index checks, now just append and insert */
+	if (!sk_OPENSSL_PSTRING_push(db->data,row))
+		{
+		db->error=DB_ERROR_MALLOC;
+		goto err;
+		}
+
+	for (i=0; i<db->num_fields; i++)
+		{
+		if (db->index[i] != NULL)
+			{
+			if ((db->qual[i] != NULL) &&
+				(db->qual[i](row) == 0)) continue;
+			(void)lh_OPENSSL_STRING_insert(db->index[i],row);
+			}
+		}
+	return(1);
+err:
+	return(0);
+	}
+
+void TXT_DB_free(TXT_DB *db)
+	{
+	int i,n;
+	char **p,*max;
+
+	if(db == NULL)
+	    return;
+
+	if (db->index != NULL)
+		{
+		for (i=db->num_fields-1; i>=0; i--)
+			if (db->index[i] != NULL) lh_OPENSSL_STRING_free(db->index[i]);
+		OPENSSL_free(db->index);
+		}
+	if (db->qual != NULL)
+		OPENSSL_free(db->qual);
+	if (db->data != NULL)
+		{
+		for (i=sk_OPENSSL_PSTRING_num(db->data)-1; i>=0; i--)
+			{
+			/* check if any 'fields' have been allocated
+			 * from outside of the initial block */
+			p=sk_OPENSSL_PSTRING_value(db->data,i);
+			max=p[db->num_fields]; /* last address */
+			if (max == NULL) /* new row */
+				{
+				for (n=0; n<db->num_fields; n++)
+					if (p[n] != NULL) OPENSSL_free(p[n]);
+				}
+			else
+				{
+				for (n=0; n<db->num_fields; n++)
+					{
+					if (((p[n] < (char *)p) || (p[n] > max))
+						&& (p[n] != NULL))
+						OPENSSL_free(p[n]);
+					}
+				}
+			OPENSSL_free(sk_OPENSSL_PSTRING_value(db->data,i));
+			}
+		sk_OPENSSL_PSTRING_free(db->data);
+		}
+	OPENSSL_free(db);
+	}
diff --git a/openssl/crypto/txt_db/txt_db.h b/openssl/crypto/txt_db/txt_db.h
new file mode 100644
index 0000000..6abe435
--- /dev/null
+++ b/openssl/crypto/txt_db/txt_db.h
@@ -0,0 +1,112 @@
+/* crypto/txt_db/txt_db.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_TXT_DB_H
+#define HEADER_TXT_DB_H
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#include <openssl/stack.h>
+#include <openssl/lhash.h>
+
+#define DB_ERROR_OK			0
+#define DB_ERROR_MALLOC			1
+#define DB_ERROR_INDEX_CLASH    	2
+#define DB_ERROR_INDEX_OUT_OF_RANGE	3
+#define DB_ERROR_NO_INDEX		4
+#define DB_ERROR_INSERT_INDEX_CLASH    	5
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef OPENSSL_STRING *OPENSSL_PSTRING;
+DECLARE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING)
+
+typedef struct txt_db_st
+	{
+	int num_fields;
+	STACK_OF(OPENSSL_PSTRING) *data;
+	LHASH_OF(OPENSSL_STRING) **index;
+	int (**qual)(OPENSSL_STRING *);
+	long error;
+	long arg1;
+	long arg2;
+	OPENSSL_STRING *arg_row;
+	} TXT_DB;
+
+#ifndef OPENSSL_NO_BIO
+TXT_DB *TXT_DB_read(BIO *in, int num);
+long TXT_DB_write(BIO *out, TXT_DB *db);
+#else
+TXT_DB *TXT_DB_read(char *in, int num);
+long TXT_DB_write(char *out, TXT_DB *db);
+#endif
+int TXT_DB_create_index(TXT_DB *db,int field,int (*qual)(OPENSSL_STRING *),
+			LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp);
+void TXT_DB_free(TXT_DB *db);
+OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, OPENSSL_STRING *value);
+int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/ui/Makefile b/openssl/crypto/ui/Makefile
new file mode 100644
index 0000000..a685659
--- /dev/null
+++ b/openssl/crypto/ui/Makefile
@@ -0,0 +1,111 @@
+#
+# OpenSSL/crypto/ui/Makefile
+#
+
+DIR=	ui
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+#TEST= uitest.c
+TEST=
+APPS=
+
+COMPATSRC= ui_compat.c
+COMPATOBJ= ui_compat.o
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= ui_err.c ui_lib.c ui_openssl.c ui_util.c $(COMPATSRC)
+LIBOBJ= ui_err.o ui_lib.o ui_openssl.o ui_util.o $(COMPATOBJ)
+
+SRC= $(LIBSRC)
+
+EXHEADER= ui.h ui_compat.h
+HEADER=	$(EXHEADER) ui_locl.h
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+ui_compat.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+ui_compat.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+ui_compat.o: ../../include/openssl/stack.h ../../include/openssl/ui.h
+ui_compat.o: ../../include/openssl/ui_compat.h ui_compat.c
+ui_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+ui_err.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+ui_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+ui_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ui_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ui_err.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h ui_err.c
+ui_lib.o: ../../e_os.h ../../include/openssl/bio.h
+ui_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+ui_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+ui_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+ui_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ui_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ui_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+ui_lib.o: ../cryptlib.h ui_lib.c ui_locl.h
+ui_openssl.o: ../../e_os.h ../../include/openssl/bio.h
+ui_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+ui_openssl.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+ui_openssl.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+ui_openssl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ui_openssl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ui_openssl.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+ui_openssl.o: ../cryptlib.h ui_locl.h ui_openssl.c
+ui_util.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+ui_util.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+ui_util.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+ui_util.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ui_util.o: ../../include/openssl/ui.h ui_locl.h ui_util.c
diff --git a/openssl/crypto/ui/ui.h b/openssl/crypto/ui/ui.h
new file mode 100644
index 0000000..2b1cfa2
--- /dev/null
+++ b/openssl/crypto/ui/ui.h
@@ -0,0 +1,383 @@
+/* crypto/ui/ui.h -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_UI_H
+#define HEADER_UI_H
+
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/crypto.h>
+#endif
+#include <openssl/safestack.h>
+#include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Declared already in ossl_typ.h */
+/* typedef struct ui_st UI; */
+/* typedef struct ui_method_st UI_METHOD; */
+
+
+/* All the following functions return -1 or NULL on error and in some cases
+   (UI_process()) -2 if interrupted or in some other way cancelled.
+   When everything is fine, they return 0, a positive value or a non-NULL
+   pointer, all depending on their purpose. */
+
+/* Creators and destructor.   */
+UI *UI_new(void);
+UI *UI_new_method(const UI_METHOD *method);
+void UI_free(UI *ui);
+
+/* The following functions are used to add strings to be printed and prompt
+   strings to prompt for data.  The names are UI_{add,dup}_<function>_string
+   and UI_{add,dup}_input_boolean.
+
+   UI_{add,dup}_<function>_string have the following meanings:
+	add	add a text or prompt string.  The pointers given to these
+		functions are used verbatim, no copying is done.
+	dup	make a copy of the text or prompt string, then add the copy
+		to the collection of strings in the user interface.
+	<function>
+		The function is a name for the functionality that the given
+		string shall be used for.  It can be one of:
+			input	use the string as data prompt.
+			verify	use the string as verification prompt.  This
+				is used to verify a previous input.
+			info	use the string for informational output.
+			error	use the string for error output.
+   Honestly, there's currently no difference between info and error for the
+   moment.
+
+   UI_{add,dup}_input_boolean have the same semantics for "add" and "dup",
+   and are typically used when one wants to prompt for a yes/no response.
+
+
+   All of the functions in this group take a UI and a prompt string.
+   The string input and verify addition functions also take a flag argument,
+   a buffer for the result to end up with, a minimum input size and a maximum
+   input size (the result buffer MUST be large enough to be able to contain
+   the maximum number of characters).  Additionally, the verify addition
+   functions takes another buffer to compare the result against.
+   The boolean input functions take an action description string (which should
+   be safe to ignore if the expected user action is obvious, for example with
+   a dialog box with an OK button and a Cancel button), a string of acceptable
+   characters to mean OK and to mean Cancel.  The two last strings are checked
+   to make sure they don't have common characters.  Additionally, the same
+   flag argument as for the string input is taken, as well as a result buffer.
+   The result buffer is required to be at least one byte long.  Depending on
+   the answer, the first character from the OK or the Cancel character strings
+   will be stored in the first byte of the result buffer.  No NUL will be
+   added, so the result is *not* a string.
+
+   On success, the all return an index of the added information.  That index
+   is usefull when retrieving results with UI_get0_result(). */
+int UI_add_input_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize);
+int UI_dup_input_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize);
+int UI_add_verify_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize, const char *test_buf);
+int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize, const char *test_buf);
+int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+	const char *ok_chars, const char *cancel_chars,
+	int flags, char *result_buf);
+int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+	const char *ok_chars, const char *cancel_chars,
+	int flags, char *result_buf);
+int UI_add_info_string(UI *ui, const char *text);
+int UI_dup_info_string(UI *ui, const char *text);
+int UI_add_error_string(UI *ui, const char *text);
+int UI_dup_error_string(UI *ui, const char *text);
+
+/* These are the possible flags.  They can be or'ed together. */
+/* Use to have echoing of input */
+#define UI_INPUT_FLAG_ECHO		0x01
+/* Use a default password.  Where that password is found is completely
+   up to the application, it might for example be in the user data set
+   with UI_add_user_data().  It is not recommended to have more than
+   one input in each UI being marked with this flag, or the application
+   might get confused. */
+#define UI_INPUT_FLAG_DEFAULT_PWD	0x02
+
+/* The user of these routines may want to define flags of their own.  The core
+   UI won't look at those, but will pass them on to the method routines.  They
+   must use higher bits so they don't get confused with the UI bits above.
+   UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use.  A good
+   example of use is this:
+
+	#define MY_UI_FLAG1	(0x01 << UI_INPUT_FLAG_USER_BASE)
+
+*/
+#define UI_INPUT_FLAG_USER_BASE	16
+
+
+/* The following function helps construct a prompt.  object_desc is a
+   textual short description of the object, for example "pass phrase",
+   and object_name is the name of the object (might be a card name or
+   a file name.
+   The returned string shall always be allocated on the heap with
+   OPENSSL_malloc(), and need to be free'd with OPENSSL_free().
+
+   If the ui_method doesn't contain a pointer to a user-defined prompt
+   constructor, a default string is built, looking like this:
+
+	"Enter {object_desc} for {object_name}:"
+
+   So, if object_desc has the value "pass phrase" and object_name has
+   the value "foo.key", the resulting string is:
+
+	"Enter pass phrase for foo.key:"
+*/
+char *UI_construct_prompt(UI *ui_method,
+	const char *object_desc, const char *object_name);
+
+
+/* The following function is used to store a pointer to user-specific data.
+   Any previous such pointer will be returned and replaced.
+
+   For callback purposes, this function makes a lot more sense than using
+   ex_data, since the latter requires that different parts of OpenSSL or
+   applications share the same ex_data index.
+
+   Note that the UI_OpenSSL() method completely ignores the user data.
+   Other methods may not, however.  */
+void *UI_add_user_data(UI *ui, void *user_data);
+/* We need a user data retrieving function as well.  */
+void *UI_get0_user_data(UI *ui);
+
+/* Return the result associated with a prompt given with the index i. */
+const char *UI_get0_result(UI *ui, int i);
+
+/* When all strings have been added, process the whole thing. */
+int UI_process(UI *ui);
+
+/* Give a user interface parametrised control commands.  This can be used to
+   send down an integer, a data pointer or a function pointer, as well as
+   be used to get information from a UI. */
+int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f)(void));
+
+/* The commands */
+/* Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the
+   OpenSSL error stack before printing any info or added error messages and
+   before any prompting. */
+#define UI_CTRL_PRINT_ERRORS		1
+/* Check if a UI_process() is possible to do again with the same instance of
+   a user interface.  This makes UI_ctrl() return 1 if it is redoable, and 0
+   if not. */
+#define UI_CTRL_IS_REDOABLE		2
+
+
+/* Some methods may use extra data */
+#define UI_set_app_data(s,arg)         UI_set_ex_data(s,0,arg)
+#define UI_get_app_data(s)             UI_get_ex_data(s,0)
+int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int UI_set_ex_data(UI *r,int idx,void *arg);
+void *UI_get_ex_data(UI *r, int idx);
+
+/* Use specific methods instead of the built-in one */
+void UI_set_default_method(const UI_METHOD *meth);
+const UI_METHOD *UI_get_default_method(void);
+const UI_METHOD *UI_get_method(UI *ui);
+const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth);
+
+/* The method with all the built-in thingies */
+UI_METHOD *UI_OpenSSL(void);
+
+
+/* ---------- For method writers ---------- */
+/* A method contains a number of functions that implement the low level
+   of the User Interface.  The functions are:
+
+	an opener	This function starts a session, maybe by opening
+			a channel to a tty, or by opening a window.
+	a writer	This function is called to write a given string,
+			maybe to the tty, maybe as a field label in a
+			window.
+	a flusher	This function is called to flush everything that
+			has been output so far.  It can be used to actually
+			display a dialog box after it has been built.
+	a reader	This function is called to read a given prompt,
+			maybe from the tty, maybe from a field in a
+			window.  Note that it's called wth all string
+			structures, not only the prompt ones, so it must
+			check such things itself.
+	a closer	This function closes the session, maybe by closing
+			the channel to the tty, or closing the window.
+
+   All these functions are expected to return:
+
+	0	on error.
+	1	on success.
+	-1	on out-of-band events, for example if some prompting has
+		been canceled (by pressing Ctrl-C, for example).  This is
+		only checked when returned by the flusher or the reader.
+
+   The way this is used, the opener is first called, then the writer for all
+   strings, then the flusher, then the reader for all strings and finally the
+   closer.  Note that if you want to prompt from a terminal or other command
+   line interface, the best is to have the reader also write the prompts
+   instead of having the writer do it.  If you want to prompt from a dialog
+   box, the writer can be used to build up the contents of the box, and the
+   flusher to actually display the box and run the event loop until all data
+   has been given, after which the reader only grabs the given data and puts
+   them back into the UI strings.
+
+   All method functions take a UI as argument.  Additionally, the writer and
+   the reader take a UI_STRING.
+*/
+
+/* The UI_STRING type is the data structure that contains all the needed info
+   about a string or a prompt, including test data for a verification prompt.
+*/
+typedef struct ui_string_st UI_STRING;
+DECLARE_STACK_OF(UI_STRING)
+
+/* The different types of strings that are currently supported.
+   This is only needed by method authors. */
+enum UI_string_types
+	{
+	UIT_NONE=0,
+	UIT_PROMPT,		/* Prompt for a string */
+	UIT_VERIFY,		/* Prompt for a string and verify */
+	UIT_BOOLEAN,		/* Prompt for a yes/no response */
+	UIT_INFO,		/* Send info to the user */
+	UIT_ERROR		/* Send an error message to the user */
+	};
+
+/* Create and manipulate methods */
+UI_METHOD *UI_create_method(char *name);
+void UI_destroy_method(UI_METHOD *ui_method);
+int UI_method_set_opener(UI_METHOD *method, int (*opener)(UI *ui));
+int UI_method_set_writer(UI_METHOD *method, int (*writer)(UI *ui, UI_STRING *uis));
+int UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui));
+int UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis));
+int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui));
+int UI_method_set_prompt_constructor(UI_METHOD *method, char *(*prompt_constructor)(UI* ui, const char* object_desc, const char* object_name));
+int (*UI_method_get_opener(UI_METHOD *method))(UI*);
+int (*UI_method_get_writer(UI_METHOD *method))(UI*,UI_STRING*);
+int (*UI_method_get_flusher(UI_METHOD *method))(UI*);
+int (*UI_method_get_reader(UI_METHOD *method))(UI*,UI_STRING*);
+int (*UI_method_get_closer(UI_METHOD *method))(UI*);
+char* (*UI_method_get_prompt_constructor(UI_METHOD *method))(UI*, const char*, const char*);
+
+/* The following functions are helpers for method writers to access relevant
+   data from a UI_STRING. */
+
+/* Return type of the UI_STRING */
+enum UI_string_types UI_get_string_type(UI_STRING *uis);
+/* Return input flags of the UI_STRING */
+int UI_get_input_flags(UI_STRING *uis);
+/* Return the actual string to output (the prompt, info or error) */
+const char *UI_get0_output_string(UI_STRING *uis);
+/* Return the optional action string to output (the boolean promtp instruction) */
+const char *UI_get0_action_string(UI_STRING *uis);
+/* Return the result of a prompt */
+const char *UI_get0_result_string(UI_STRING *uis);
+/* Return the string to test the result against.  Only useful with verifies. */
+const char *UI_get0_test_string(UI_STRING *uis);
+/* Return the required minimum size of the result */
+int UI_get_result_minsize(UI_STRING *uis);
+/* Return the required maximum size of the result */
+int UI_get_result_maxsize(UI_STRING *uis);
+/* Set the result of a UI_STRING. */
+int UI_set_result(UI *ui, UI_STRING *uis, const char *result);
+
+
+/* A couple of popular utility functions */
+int UI_UTIL_read_pw_string(char *buf,int length,const char *prompt,int verify);
+int UI_UTIL_read_pw(char *buf,char *buff,int size,const char *prompt,int verify);
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_UI_strings(void);
+
+/* Error codes for the UI functions. */
+
+/* Function codes. */
+#define UI_F_GENERAL_ALLOCATE_BOOLEAN			 108
+#define UI_F_GENERAL_ALLOCATE_PROMPT			 109
+#define UI_F_GENERAL_ALLOCATE_STRING			 100
+#define UI_F_UI_CTRL					 111
+#define UI_F_UI_DUP_ERROR_STRING			 101
+#define UI_F_UI_DUP_INFO_STRING				 102
+#define UI_F_UI_DUP_INPUT_BOOLEAN			 110
+#define UI_F_UI_DUP_INPUT_STRING			 103
+#define UI_F_UI_DUP_VERIFY_STRING			 106
+#define UI_F_UI_GET0_RESULT				 107
+#define UI_F_UI_NEW_METHOD				 104
+#define UI_F_UI_SET_RESULT				 105
+
+/* Reason codes. */
+#define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS		 104
+#define UI_R_INDEX_TOO_LARGE				 102
+#define UI_R_INDEX_TOO_SMALL				 103
+#define UI_R_NO_RESULT_BUFFER				 105
+#define UI_R_RESULT_TOO_LARGE				 100
+#define UI_R_RESULT_TOO_SMALL				 101
+#define UI_R_UNKNOWN_CONTROL_COMMAND			 106
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/ui/ui_compat.c b/openssl/crypto/ui/ui_compat.c
new file mode 100644
index 0000000..13e0f70
--- /dev/null
+++ b/openssl/crypto/ui/ui_compat.c
@@ -0,0 +1,67 @@
+/* crypto/ui/ui_compat.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 2001-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+#include <openssl/ui_compat.h>
+
+int _ossl_old_des_read_pw_string(char *buf,int length,const char *prompt,int verify)
+	{
+	return UI_UTIL_read_pw_string(buf, length, prompt, verify);
+	}
+
+int _ossl_old_des_read_pw(char *buf,char *buff,int size,const char *prompt,int verify)
+	{
+	return UI_UTIL_read_pw(buf, buff, size, prompt, verify);
+	}
diff --git a/openssl/crypto/ui/ui_compat.h b/openssl/crypto/ui/ui_compat.h
new file mode 100644
index 0000000..b35c9bb
--- /dev/null
+++ b/openssl/crypto/ui/ui_compat.h
@@ -0,0 +1,83 @@
+/* crypto/ui/ui.h -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_UI_COMPAT_H
+#define HEADER_UI_COMPAT_H
+
+#include <openssl/opensslconf.h>
+#include <openssl/ui.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* The following functions were previously part of the DES section,
+   and are provided here for backward compatibility reasons. */
+
+#define des_read_pw_string(b,l,p,v) \
+	_ossl_old_des_read_pw_string((b),(l),(p),(v))
+#define des_read_pw(b,bf,s,p,v) \
+	_ossl_old_des_read_pw((b),(bf),(s),(p),(v))
+
+int _ossl_old_des_read_pw_string(char *buf,int length,const char *prompt,int verify);
+int _ossl_old_des_read_pw(char *buf,char *buff,int size,const char *prompt,int verify);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/ui/ui_err.c b/openssl/crypto/ui/ui_err.c
new file mode 100644
index 0000000..a6b9629
--- /dev/null
+++ b/openssl/crypto/ui/ui_err.c
@@ -0,0 +1,112 @@
+/* crypto/ui/ui_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ui.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_UI,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_UI,0,reason)
+
+static ERR_STRING_DATA UI_str_functs[]=
+	{
+{ERR_FUNC(UI_F_GENERAL_ALLOCATE_BOOLEAN),	"GENERAL_ALLOCATE_BOOLEAN"},
+{ERR_FUNC(UI_F_GENERAL_ALLOCATE_PROMPT),	"GENERAL_ALLOCATE_PROMPT"},
+{ERR_FUNC(UI_F_GENERAL_ALLOCATE_STRING),	"GENERAL_ALLOCATE_STRING"},
+{ERR_FUNC(UI_F_UI_CTRL),	"UI_ctrl"},
+{ERR_FUNC(UI_F_UI_DUP_ERROR_STRING),	"UI_dup_error_string"},
+{ERR_FUNC(UI_F_UI_DUP_INFO_STRING),	"UI_dup_info_string"},
+{ERR_FUNC(UI_F_UI_DUP_INPUT_BOOLEAN),	"UI_dup_input_boolean"},
+{ERR_FUNC(UI_F_UI_DUP_INPUT_STRING),	"UI_dup_input_string"},
+{ERR_FUNC(UI_F_UI_DUP_VERIFY_STRING),	"UI_dup_verify_string"},
+{ERR_FUNC(UI_F_UI_GET0_RESULT),	"UI_get0_result"},
+{ERR_FUNC(UI_F_UI_NEW_METHOD),	"UI_new_method"},
+{ERR_FUNC(UI_F_UI_SET_RESULT),	"UI_set_result"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA UI_str_reasons[]=
+	{
+{ERR_REASON(UI_R_COMMON_OK_AND_CANCEL_CHARACTERS),"common ok and cancel characters"},
+{ERR_REASON(UI_R_INDEX_TOO_LARGE)        ,"index too large"},
+{ERR_REASON(UI_R_INDEX_TOO_SMALL)        ,"index too small"},
+{ERR_REASON(UI_R_NO_RESULT_BUFFER)       ,"no result buffer"},
+{ERR_REASON(UI_R_RESULT_TOO_LARGE)       ,"result too large"},
+{ERR_REASON(UI_R_RESULT_TOO_SMALL)       ,"result too small"},
+{ERR_REASON(UI_R_UNKNOWN_CONTROL_COMMAND),"unknown control command"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_UI_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(UI_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,UI_str_functs);
+		ERR_load_strings(0,UI_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/ui/ui_lib.c b/openssl/crypto/ui/ui_lib.c
new file mode 100644
index 0000000..a8abc27
--- /dev/null
+++ b/openssl/crypto/ui/ui_lib.c
@@ -0,0 +1,924 @@
+/* crypto/ui/ui_lib.c -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/e_os2.h>
+#include <openssl/buffer.h>
+#include <openssl/ui.h>
+#include <openssl/err.h>
+#include "ui_locl.h"
+
+IMPLEMENT_STACK_OF(UI_STRING_ST)
+
+static const UI_METHOD *default_UI_meth=NULL;
+
+UI *UI_new(void)
+	{
+	return(UI_new_method(NULL));
+	}
+
+UI *UI_new_method(const UI_METHOD *method)
+	{
+	UI *ret;
+
+	ret=(UI *)OPENSSL_malloc(sizeof(UI));
+	if (ret == NULL)
+		{
+		UIerr(UI_F_UI_NEW_METHOD,ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+	if (method == NULL)
+		ret->meth=UI_get_default_method();
+	else
+		ret->meth=method;
+
+	ret->strings=NULL;
+	ret->user_data=NULL;
+	ret->flags=0;
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data);
+	return ret;
+	}
+
+static void free_string(UI_STRING *uis)
+	{
+	if (uis->flags & OUT_STRING_FREEABLE)
+		{
+		OPENSSL_free((char *)uis->out_string);
+		switch(uis->type)
+			{
+		case UIT_BOOLEAN:
+			OPENSSL_free((char *)uis->_.boolean_data.action_desc);
+			OPENSSL_free((char *)uis->_.boolean_data.ok_chars);
+			OPENSSL_free((char *)uis->_.boolean_data.cancel_chars);
+			break;
+		default:
+			break;
+			}
+		}
+	OPENSSL_free(uis);
+	}
+
+void UI_free(UI *ui)
+	{
+	if (ui == NULL)
+		return;
+	sk_UI_STRING_pop_free(ui->strings,free_string);
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_UI, ui, &ui->ex_data);
+	OPENSSL_free(ui);
+	}
+
+static int allocate_string_stack(UI *ui)
+	{
+	if (ui->strings == NULL)
+		{
+		ui->strings=sk_UI_STRING_new_null();
+		if (ui->strings == NULL)
+			{
+			return -1;
+			}
+		}
+	return 0;
+	}
+
+static UI_STRING *general_allocate_prompt(UI *ui, const char *prompt,
+	int prompt_freeable, enum UI_string_types type, int input_flags,
+	char *result_buf)
+	{
+	UI_STRING *ret = NULL;
+
+	if (prompt == NULL)
+		{
+		UIerr(UI_F_GENERAL_ALLOCATE_PROMPT,ERR_R_PASSED_NULL_PARAMETER);
+		}
+	else if ((type == UIT_PROMPT || type == UIT_VERIFY
+			 || type == UIT_BOOLEAN) && result_buf == NULL)
+		{
+		UIerr(UI_F_GENERAL_ALLOCATE_PROMPT,UI_R_NO_RESULT_BUFFER);
+		}
+	else if ((ret = (UI_STRING *)OPENSSL_malloc(sizeof(UI_STRING))))
+		{
+		ret->out_string=prompt;
+		ret->flags=prompt_freeable ? OUT_STRING_FREEABLE : 0;
+		ret->input_flags=input_flags;
+		ret->type=type;
+		ret->result_buf=result_buf;
+		}
+	return ret;
+	}
+
+static int general_allocate_string(UI *ui, const char *prompt,
+	int prompt_freeable, enum UI_string_types type, int input_flags,
+	char *result_buf, int minsize, int maxsize, const char *test_buf)
+	{
+	int ret = -1;
+	UI_STRING *s = general_allocate_prompt(ui, prompt, prompt_freeable,
+		type, input_flags, result_buf);
+
+	if (s)
+		{
+		if (allocate_string_stack(ui) >= 0)
+			{
+			s->_.string_data.result_minsize=minsize;
+			s->_.string_data.result_maxsize=maxsize;
+			s->_.string_data.test_buf=test_buf;
+			ret=sk_UI_STRING_push(ui->strings, s);
+			/* sk_push() returns 0 on error.  Let's addapt that */
+			if (ret <= 0) ret--;
+			}
+		else
+			free_string(s);
+		}
+	return ret;
+	}
+
+static int general_allocate_boolean(UI *ui,
+	const char *prompt, const char *action_desc,
+	const char *ok_chars, const char *cancel_chars,
+	int prompt_freeable, enum UI_string_types type, int input_flags,
+	char *result_buf)
+	{
+	int ret = -1;
+	UI_STRING *s;
+	const char *p;
+
+	if (ok_chars == NULL)
+		{
+		UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,ERR_R_PASSED_NULL_PARAMETER);
+		}
+	else if (cancel_chars == NULL)
+		{
+		UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,ERR_R_PASSED_NULL_PARAMETER);
+		}
+	else
+		{
+		for(p = ok_chars; *p; p++)
+			{
+			if (strchr(cancel_chars, *p))
+				{
+				UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,
+					UI_R_COMMON_OK_AND_CANCEL_CHARACTERS);
+				}
+			}
+
+		s = general_allocate_prompt(ui, prompt, prompt_freeable,
+			type, input_flags, result_buf);
+
+		if (s)
+			{
+			if (allocate_string_stack(ui) >= 0)
+				{
+				s->_.boolean_data.action_desc = action_desc;
+				s->_.boolean_data.ok_chars = ok_chars;
+				s->_.boolean_data.cancel_chars = cancel_chars;
+				ret=sk_UI_STRING_push(ui->strings, s);
+				/* sk_push() returns 0 on error.
+				   Let's addapt that */
+				if (ret <= 0) ret--;
+				}
+			else
+				free_string(s);
+			}
+		}
+	return ret;
+	}
+
+/* Returns the index to the place in the stack or -1 for error.  Uses a
+   direct reference to the prompt.  */
+int UI_add_input_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize)
+	{
+	return general_allocate_string(ui, prompt, 0,
+		UIT_PROMPT, flags, result_buf, minsize, maxsize, NULL);
+	}
+
+/* Same as UI_add_input_string(), excepts it takes a copy of the prompt */
+int UI_dup_input_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize)
+	{
+	char *prompt_copy=NULL;
+
+	if (prompt)
+		{
+		prompt_copy=BUF_strdup(prompt);
+		if (prompt_copy == NULL)
+			{
+			UIerr(UI_F_UI_DUP_INPUT_STRING,ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		}
+	
+	return general_allocate_string(ui, prompt_copy, 1,
+		UIT_PROMPT, flags, result_buf, minsize, maxsize, NULL);
+	}
+
+int UI_add_verify_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize, const char *test_buf)
+	{
+	return general_allocate_string(ui, prompt, 0,
+		UIT_VERIFY, flags, result_buf, minsize, maxsize, test_buf);
+	}
+
+int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize, const char *test_buf)
+	{
+	char *prompt_copy=NULL;
+
+	if (prompt)
+		{
+		prompt_copy=BUF_strdup(prompt);
+		if (prompt_copy == NULL)
+			{
+			UIerr(UI_F_UI_DUP_VERIFY_STRING,ERR_R_MALLOC_FAILURE);
+			return -1;
+			}
+		}
+	
+	return general_allocate_string(ui, prompt_copy, 1,
+		UIT_VERIFY, flags, result_buf, minsize, maxsize, test_buf);
+	}
+
+int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+	const char *ok_chars, const char *cancel_chars,
+	int flags, char *result_buf)
+	{
+	return general_allocate_boolean(ui, prompt, action_desc,
+		ok_chars, cancel_chars, 0, UIT_BOOLEAN, flags, result_buf);
+	}
+
+int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+	const char *ok_chars, const char *cancel_chars,
+	int flags, char *result_buf)
+	{
+	char *prompt_copy = NULL;
+	char *action_desc_copy = NULL;
+	char *ok_chars_copy = NULL;
+	char *cancel_chars_copy = NULL;
+
+	if (prompt)
+		{
+		prompt_copy=BUF_strdup(prompt);
+		if (prompt_copy == NULL)
+			{
+			UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+	
+	if (action_desc)
+		{
+		action_desc_copy=BUF_strdup(action_desc);
+		if (action_desc_copy == NULL)
+			{
+			UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+	
+	if (ok_chars)
+		{
+		ok_chars_copy=BUF_strdup(ok_chars);
+		if (ok_chars_copy == NULL)
+			{
+			UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+	
+	if (cancel_chars)
+		{
+		cancel_chars_copy=BUF_strdup(cancel_chars);
+		if (cancel_chars_copy == NULL)
+			{
+			UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+	
+	return general_allocate_boolean(ui, prompt_copy, action_desc_copy,
+		ok_chars_copy, cancel_chars_copy, 1, UIT_BOOLEAN, flags,
+		result_buf);
+ err:
+	if (prompt_copy) OPENSSL_free(prompt_copy);
+	if (action_desc_copy) OPENSSL_free(action_desc_copy);
+	if (ok_chars_copy) OPENSSL_free(ok_chars_copy);
+	if (cancel_chars_copy) OPENSSL_free(cancel_chars_copy);
+	return -1;
+	}
+
+int UI_add_info_string(UI *ui, const char *text)
+	{
+	return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0,
+		NULL);
+	}
+
+int UI_dup_info_string(UI *ui, const char *text)
+	{
+	char *text_copy=NULL;
+
+	if (text)
+		{
+		text_copy=BUF_strdup(text);
+		if (text_copy == NULL)
+			{
+			UIerr(UI_F_UI_DUP_INFO_STRING,ERR_R_MALLOC_FAILURE);
+			return -1;
+			}
+		}
+
+	return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL,
+		0, 0, NULL);
+	}
+
+int UI_add_error_string(UI *ui, const char *text)
+	{
+	return general_allocate_string(ui, text, 0, UIT_ERROR, 0, NULL, 0, 0,
+		NULL);
+	}
+
+int UI_dup_error_string(UI *ui, const char *text)
+	{
+	char *text_copy=NULL;
+
+	if (text)
+		{
+		text_copy=BUF_strdup(text);
+		if (text_copy == NULL)
+			{
+			UIerr(UI_F_UI_DUP_ERROR_STRING,ERR_R_MALLOC_FAILURE);
+			return -1;
+			}
+		}
+	return general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL,
+		0, 0, NULL);
+	}
+
+char *UI_construct_prompt(UI *ui, const char *object_desc,
+	const char *object_name)
+	{
+	char *prompt = NULL;
+
+	if (ui->meth->ui_construct_prompt)
+		prompt = ui->meth->ui_construct_prompt(ui,
+			object_desc, object_name);
+	else
+		{
+		char prompt1[] = "Enter ";
+		char prompt2[] = " for ";
+		char prompt3[] = ":";
+		int len = 0;
+
+		if (object_desc == NULL)
+			return NULL;
+		len = sizeof(prompt1) - 1 + strlen(object_desc);
+		if (object_name)
+			len += sizeof(prompt2) - 1 + strlen(object_name);
+		len += sizeof(prompt3) - 1;
+
+		prompt = (char *)OPENSSL_malloc(len + 1);
+		BUF_strlcpy(prompt, prompt1, len + 1);
+		BUF_strlcat(prompt, object_desc, len + 1);
+		if (object_name)
+			{
+			BUF_strlcat(prompt, prompt2, len + 1);
+			BUF_strlcat(prompt, object_name, len + 1);
+			}
+		BUF_strlcat(prompt, prompt3, len + 1);
+		}
+	return prompt;
+	}
+
+void *UI_add_user_data(UI *ui, void *user_data)
+	{
+	void *old_data = ui->user_data;
+	ui->user_data = user_data;
+	return old_data;
+	}
+
+void *UI_get0_user_data(UI *ui)
+	{
+	return ui->user_data;
+	}
+
+const char *UI_get0_result(UI *ui, int i)
+	{
+	if (i < 0)
+		{
+		UIerr(UI_F_UI_GET0_RESULT,UI_R_INDEX_TOO_SMALL);
+		return NULL;
+		}
+	if (i >= sk_UI_STRING_num(ui->strings))
+		{
+		UIerr(UI_F_UI_GET0_RESULT,UI_R_INDEX_TOO_LARGE);
+		return NULL;
+		}
+	return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i));
+	}
+
+static int print_error(const char *str, size_t len, UI *ui)
+	{
+	UI_STRING uis;
+
+	memset(&uis, 0, sizeof(uis));
+	uis.type = UIT_ERROR;
+	uis.out_string = str;
+
+	if (ui->meth->ui_write_string
+		&& !ui->meth->ui_write_string(ui, &uis))
+		return -1;
+	return 0;
+	}
+
+int UI_process(UI *ui)
+	{
+	int i, ok=0;
+
+	if (ui->meth->ui_open_session && !ui->meth->ui_open_session(ui))
+		return -1;
+
+	if (ui->flags & UI_FLAG_PRINT_ERRORS)
+		ERR_print_errors_cb(
+			(int (*)(const char *, size_t, void *))print_error,
+			(void *)ui);
+
+	for(i=0; i<sk_UI_STRING_num(ui->strings); i++)
+		{
+		if (ui->meth->ui_write_string
+			&& !ui->meth->ui_write_string(ui,
+				sk_UI_STRING_value(ui->strings, i)))
+			{
+			ok=-1;
+			goto err;
+			}
+		}
+
+	if (ui->meth->ui_flush)
+		switch(ui->meth->ui_flush(ui))
+			{
+		case -1: /* Interrupt/Cancel/something... */
+			ok = -2;
+			goto err;
+		case 0: /* Errors */
+			ok = -1;
+			goto err;
+		default: /* Success */
+			ok = 0;
+			break;
+			}
+
+	for(i=0; i<sk_UI_STRING_num(ui->strings); i++)
+		{
+		if (ui->meth->ui_read_string)
+			{
+			switch(ui->meth->ui_read_string(ui,
+				sk_UI_STRING_value(ui->strings, i)))
+				{
+			case -1: /* Interrupt/Cancel/something... */
+				ok = -2;
+				goto err;
+			case 0: /* Errors */
+				ok = -1;
+				goto err;
+			default: /* Success */
+				ok = 0;
+				break;
+				}
+			}
+		}
+ err:
+	if (ui->meth->ui_close_session && !ui->meth->ui_close_session(ui))
+		return -1;
+	return ok;
+	}
+
+int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f)(void))
+	{
+	if (ui == NULL)
+		{
+		UIerr(UI_F_UI_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+		return -1;
+		}
+	switch(cmd)
+		{
+	case UI_CTRL_PRINT_ERRORS:
+		{
+		int save_flag = !!(ui->flags & UI_FLAG_PRINT_ERRORS);
+		if (i)
+			ui->flags |= UI_FLAG_PRINT_ERRORS;
+		else
+			ui->flags &= ~UI_FLAG_PRINT_ERRORS;
+		return save_flag;
+		}
+	case UI_CTRL_IS_REDOABLE:
+		return !!(ui->flags & UI_FLAG_REDOABLE);
+	default:
+		break;
+		}
+	UIerr(UI_F_UI_CTRL,UI_R_UNKNOWN_CONTROL_COMMAND);
+	return -1;
+	}
+
+int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+        {
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, argl, argp,
+				new_func, dup_func, free_func);
+        }
+
+int UI_set_ex_data(UI *r, int idx, void *arg)
+	{
+	return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
+	}
+
+void *UI_get_ex_data(UI *r, int idx)
+	{
+	return(CRYPTO_get_ex_data(&r->ex_data,idx));
+	}
+
+void UI_set_default_method(const UI_METHOD *meth)
+	{
+	default_UI_meth=meth;
+	}
+
+const UI_METHOD *UI_get_default_method(void)
+	{
+	if (default_UI_meth == NULL)
+		{
+		default_UI_meth=UI_OpenSSL();
+		}
+	return default_UI_meth;
+	}
+
+const UI_METHOD *UI_get_method(UI *ui)
+	{
+	return ui->meth;
+	}
+
+const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth)
+	{
+	ui->meth=meth;
+	return ui->meth;
+	}
+
+
+UI_METHOD *UI_create_method(char *name)
+	{
+	UI_METHOD *ui_method = (UI_METHOD *)OPENSSL_malloc(sizeof(UI_METHOD));
+
+	if (ui_method)
+		{
+		memset(ui_method, 0, sizeof(*ui_method));
+		ui_method->name = BUF_strdup(name);
+		}
+	return ui_method;
+	}
+
+/* BIG FSCKING WARNING!!!!  If you use this on a statically allocated method
+   (that is, it hasn't been allocated using UI_create_method(), you deserve
+   anything Murphy can throw at you and more!  You have been warned. */
+void UI_destroy_method(UI_METHOD *ui_method)
+	{
+	OPENSSL_free(ui_method->name);
+	ui_method->name = NULL;
+	OPENSSL_free(ui_method);
+	}
+
+int UI_method_set_opener(UI_METHOD *method, int (*opener)(UI *ui))
+	{
+	if (method)
+		{
+		method->ui_open_session = opener;
+		return 0;
+		}
+	else
+		return -1;
+	}
+
+int UI_method_set_writer(UI_METHOD *method, int (*writer)(UI *ui, UI_STRING *uis))
+	{
+	if (method)
+		{
+		method->ui_write_string = writer;
+		return 0;
+		}
+	else
+		return -1;
+	}
+
+int UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui))
+	{
+	if (method)
+		{
+		method->ui_flush = flusher;
+		return 0;
+		}
+	else
+		return -1;
+	}
+
+int UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis))
+	{
+	if (method)
+		{
+		method->ui_read_string = reader;
+		return 0;
+		}
+	else
+		return -1;
+	}
+
+int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui))
+	{
+	if (method)
+		{
+		method->ui_close_session = closer;
+		return 0;
+		}
+	else
+		return -1;
+	}
+
+int UI_method_set_prompt_constructor(UI_METHOD *method, char *(*prompt_constructor)(UI* ui, const char* object_desc, const char* object_name))
+	{
+	if (method)
+		{
+		method->ui_construct_prompt = prompt_constructor;
+		return 0;
+		}
+	else
+		return -1;
+	}
+
+int (*UI_method_get_opener(UI_METHOD *method))(UI*)
+	{
+	if (method)
+		return method->ui_open_session;
+	else
+		return NULL;
+	}
+
+int (*UI_method_get_writer(UI_METHOD *method))(UI*,UI_STRING*)
+	{
+	if (method)
+		return method->ui_write_string;
+	else
+		return NULL;
+	}
+
+int (*UI_method_get_flusher(UI_METHOD *method))(UI*)
+	{
+	if (method)
+		return method->ui_flush;
+	else
+		return NULL;
+	}
+
+int (*UI_method_get_reader(UI_METHOD *method))(UI*,UI_STRING*)
+	{
+	if (method)
+		return method->ui_read_string;
+	else
+		return NULL;
+	}
+
+int (*UI_method_get_closer(UI_METHOD *method))(UI*)
+	{
+	if (method)
+		return method->ui_close_session;
+	else
+		return NULL;
+	}
+
+char* (*UI_method_get_prompt_constructor(UI_METHOD *method))(UI*, const char*, const char*)
+	{
+	if (method)
+		return method->ui_construct_prompt;
+	else
+		return NULL;
+	}
+
+enum UI_string_types UI_get_string_type(UI_STRING *uis)
+	{
+	if (!uis)
+		return UIT_NONE;
+	return uis->type;
+	}
+
+int UI_get_input_flags(UI_STRING *uis)
+	{
+	if (!uis)
+		return 0;
+	return uis->input_flags;
+	}
+
+const char *UI_get0_output_string(UI_STRING *uis)
+	{
+	if (!uis)
+		return NULL;
+	return uis->out_string;
+	}
+
+const char *UI_get0_action_string(UI_STRING *uis)
+	{
+	if (!uis)
+		return NULL;
+	switch(uis->type)
+		{
+	case UIT_PROMPT:
+	case UIT_BOOLEAN:
+		return uis->_.boolean_data.action_desc;
+	default:
+		return NULL;
+		}
+	}
+
+const char *UI_get0_result_string(UI_STRING *uis)
+	{
+	if (!uis)
+		return NULL;
+	switch(uis->type)
+		{
+	case UIT_PROMPT:
+	case UIT_VERIFY:
+		return uis->result_buf;
+	default:
+		return NULL;
+		}
+	}
+
+const char *UI_get0_test_string(UI_STRING *uis)
+	{
+	if (!uis)
+		return NULL;
+	switch(uis->type)
+		{
+	case UIT_VERIFY:
+		return uis->_.string_data.test_buf;
+	default:
+		return NULL;
+		}
+	}
+
+int UI_get_result_minsize(UI_STRING *uis)
+	{
+	if (!uis)
+		return -1;
+	switch(uis->type)
+		{
+	case UIT_PROMPT:
+	case UIT_VERIFY:
+		return uis->_.string_data.result_minsize;
+	default:
+		return -1;
+		}
+	}
+
+int UI_get_result_maxsize(UI_STRING *uis)
+	{
+	if (!uis)
+		return -1;
+	switch(uis->type)
+		{
+	case UIT_PROMPT:
+	case UIT_VERIFY:
+		return uis->_.string_data.result_maxsize;
+	default:
+		return -1;
+		}
+	}
+
+int UI_set_result(UI *ui, UI_STRING *uis, const char *result)
+	{
+	int l = strlen(result);
+
+	ui->flags &= ~UI_FLAG_REDOABLE;
+
+	if (!uis)
+		return -1;
+	switch (uis->type)
+		{
+	case UIT_PROMPT:
+	case UIT_VERIFY:
+		{
+		char number1[DECIMAL_SIZE(uis->_.string_data.result_minsize)+1];
+		char number2[DECIMAL_SIZE(uis->_.string_data.result_maxsize)+1];
+
+		BIO_snprintf(number1, sizeof(number1), "%d",
+			uis->_.string_data.result_minsize);
+		BIO_snprintf(number2, sizeof(number2), "%d",
+			uis->_.string_data.result_maxsize);
+
+		if (l < uis->_.string_data.result_minsize)
+			{
+			ui->flags |= UI_FLAG_REDOABLE;
+			UIerr(UI_F_UI_SET_RESULT,UI_R_RESULT_TOO_SMALL);
+			ERR_add_error_data(5,"You must type in ",
+				number1," to ",number2," characters");
+			return -1;
+			}
+		if (l > uis->_.string_data.result_maxsize)
+			{
+			ui->flags |= UI_FLAG_REDOABLE;
+			UIerr(UI_F_UI_SET_RESULT,UI_R_RESULT_TOO_LARGE);
+			ERR_add_error_data(5,"You must type in ",
+				number1," to ",number2," characters");
+			return -1;
+			}
+		}
+
+		if (!uis->result_buf)
+			{
+			UIerr(UI_F_UI_SET_RESULT,UI_R_NO_RESULT_BUFFER);
+			return -1;
+			}
+
+		BUF_strlcpy(uis->result_buf, result,
+			    uis->_.string_data.result_maxsize + 1);
+		break;
+	case UIT_BOOLEAN:
+		{
+		const char *p;
+
+		if (!uis->result_buf)
+			{
+			UIerr(UI_F_UI_SET_RESULT,UI_R_NO_RESULT_BUFFER);
+			return -1;
+			}
+
+		uis->result_buf[0] = '\0';
+		for(p = result; *p; p++)
+			{
+			if (strchr(uis->_.boolean_data.ok_chars, *p))
+				{
+				uis->result_buf[0] =
+					uis->_.boolean_data.ok_chars[0];
+				break;
+				}
+			if (strchr(uis->_.boolean_data.cancel_chars, *p))
+				{
+				uis->result_buf[0] =
+					uis->_.boolean_data.cancel_chars[0];
+				break;
+				}
+			}
+	default:
+		break;
+		}
+		}
+	return 0;
+	}
diff --git a/openssl/crypto/ui/ui_locl.h b/openssl/crypto/ui/ui_locl.h
new file mode 100644
index 0000000..aa4a556
--- /dev/null
+++ b/openssl/crypto/ui/ui_locl.h
@@ -0,0 +1,153 @@
+/* crypto/ui/ui.h -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_UI_LOCL_H
+#define HEADER_UI_LOCL_H
+
+#include <openssl/ui.h>
+#include <openssl/crypto.h>
+
+#ifdef _
+#undef _
+#endif
+
+struct ui_method_st
+	{
+	char *name;
+
+	/* All the functions return 1 or non-NULL for success and 0 or NULL
+	   for failure */
+
+	/* Open whatever channel for this, be it the console, an X window
+	   or whatever.
+	   This function should use the ex_data structure to save
+	   intermediate data. */
+	int (*ui_open_session)(UI *ui);
+
+	int (*ui_write_string)(UI *ui, UI_STRING *uis);
+
+	/* Flush the output.  If a GUI dialog box is used, this function can
+	   be used to actually display it. */
+	int (*ui_flush)(UI *ui);
+
+	int (*ui_read_string)(UI *ui, UI_STRING *uis);
+
+	int (*ui_close_session)(UI *ui);
+
+	/* Construct a prompt in a user-defined manner.  object_desc is a
+	   textual short description of the object, for example "pass phrase",
+	   and object_name is the name of the object (might be a card name or
+	   a file name.
+	   The returned string shall always be allocated on the heap with
+	   OPENSSL_malloc(), and need to be free'd with OPENSSL_free(). */
+	char *(*ui_construct_prompt)(UI *ui, const char *object_desc,
+		const char *object_name);
+	};
+
+struct ui_string_st
+	{
+	enum UI_string_types type; /* Input */
+	const char *out_string;	/* Input */
+	int input_flags;	/* Flags from the user */
+
+	/* The following parameters are completely irrelevant for UIT_INFO,
+	   and can therefore be set to 0 or NULL */
+	char *result_buf;	/* Input and Output: If not NULL, user-defined
+				   with size in result_maxsize.  Otherwise, it
+				   may be allocated by the UI routine, meaning
+				   result_minsize is going to be overwritten.*/
+	union
+		{
+		struct
+			{
+			int result_minsize;	/* Input: minimum required
+						   size of the result.
+						*/
+			int result_maxsize;	/* Input: maximum permitted
+						   size of the result */
+
+			const char *test_buf;	/* Input: test string to verify
+						   against */
+			} string_data;
+		struct
+			{
+			const char *action_desc; /* Input */
+			const char *ok_chars; /* Input */
+			const char *cancel_chars; /* Input */
+			} boolean_data;
+		} _;
+
+#define OUT_STRING_FREEABLE 0x01
+	int flags;		/* flags for internal use */
+	};
+
+struct ui_st
+	{
+	const UI_METHOD *meth;
+	STACK_OF(UI_STRING) *strings; /* We might want to prompt for more
+					 than one thing at a time, and
+					 with different echoing status.  */
+	void *user_data;
+	CRYPTO_EX_DATA ex_data;
+
+#define UI_FLAG_REDOABLE	0x0001
+#define UI_FLAG_PRINT_ERRORS	0x0100
+	int flags;
+	};
+
+#endif
diff --git a/openssl/crypto/ui/ui_openssl.c b/openssl/crypto/ui/ui_openssl.c
new file mode 100644
index 0000000..b05cbf3
--- /dev/null
+++ b/openssl/crypto/ui/ui_openssl.c
@@ -0,0 +1,712 @@
+/* crypto/ui/ui_openssl.c -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) and others
+ * for the OpenSSL project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* The lowest level part of this file was previously in crypto/des/read_pwd.c,
+ * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+
+#include <openssl/e_os2.h>
+
+/* need for #define _POSIX_C_SOURCE arises whenever you pass -ansi to gcc
+ * [maybe others?], because it masks interfaces not discussed in standard,
+ * sigaction and fileno included. -pedantic would be more appropriate for
+ * the intended purposes, but we can't prevent users from adding -ansi.
+ */
+#ifndef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 2
+#endif
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS)
+# ifdef OPENSSL_UNISTD
+#  include OPENSSL_UNISTD
+# else
+#  include <unistd.h>
+# endif
+/* If unistd.h defines _POSIX_VERSION, we conclude that we
+ * are on a POSIX system and have sigaction and termios. */
+# if defined(_POSIX_VERSION)
+
+#  define SIGACTION
+#  if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY)
+#   define TERMIOS
+#  endif
+
+# endif
+#endif
+
+#ifdef WIN16TTY
+# undef OPENSSL_SYS_WIN16
+# undef WIN16
+# undef _WINDOWS
+# include <graph.h>
+#endif
+
+/* 06-Apr-92 Luke Brennan    Support for VMS */
+#include "ui_locl.h"
+#include "cryptlib.h"
+
+#ifdef OPENSSL_SYS_VMS		/* prototypes for sys$whatever */
+# include <starlet.h>
+# ifdef __DECC
+#  pragma message disable DOLLARID
+# endif
+#endif
+
+#ifdef WIN_CONSOLE_BUG
+# include <windows.h>
+#ifndef OPENSSL_SYS_WINCE
+# include <wincon.h>
+#endif
+#endif
+
+
+/* There are 5 types of terminal interface supported,
+ * TERMIO, TERMIOS, VMS, MSDOS and SGTTY
+ */
+
+#if defined(__sgi) && !defined(TERMIOS)
+# define TERMIOS
+# undef  TERMIO
+# undef  SGTTY
+#endif
+
+#if defined(linux) && !defined(TERMIO) && !defined(__ANDROID__)
+# undef  TERMIOS
+# define TERMIO
+# undef  SGTTY
+#endif
+
+#ifdef _LIBC
+# undef  TERMIOS
+# define TERMIO
+# undef  SGTTY
+#endif
+
+#if !defined(TERMIO) && !defined(TERMIOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && !defined(MAC_OS_GUSI_SOURCE)
+# undef  TERMIOS
+# undef  TERMIO
+# define SGTTY
+#endif
+
+#if defined(OPENSSL_SYS_VXWORKS)
+#undef TERMIOS
+#undef TERMIO
+#undef SGTTY
+#endif
+
+#if defined(OPENSSL_SYS_NETWARE)
+#undef TERMIOS
+#undef TERMIO
+#undef SGTTY
+#endif
+
+#ifdef TERMIOS
+# include <termios.h>
+# define TTY_STRUCT		struct termios
+# define TTY_FLAGS		c_lflag
+# define TTY_get(tty,data)	tcgetattr(tty,data)
+# define TTY_set(tty,data)	tcsetattr(tty,TCSANOW,data)
+#endif
+
+#ifdef TERMIO
+# include <termio.h>
+# define TTY_STRUCT		struct termio
+# define TTY_FLAGS		c_lflag
+# define TTY_get(tty,data)	ioctl(tty,TCGETA,data)
+# define TTY_set(tty,data)	ioctl(tty,TCSETA,data)
+#endif
+
+#ifdef SGTTY
+# include <sgtty.h>
+# define TTY_STRUCT		struct sgttyb
+# define TTY_FLAGS		sg_flags
+# define TTY_get(tty,data)	ioctl(tty,TIOCGETP,data)
+# define TTY_set(tty,data)	ioctl(tty,TIOCSETP,data)
+#endif
+
+#if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && !defined(OPENSSL_SYS_SUNOS)
+# include <sys/ioctl.h>
+#endif
+
+#ifdef OPENSSL_SYS_MSDOS
+# include <conio.h>
+#endif
+
+#ifdef OPENSSL_SYS_VMS
+# include <ssdef.h>
+# include <iodef.h>
+# include <ttdef.h>
+# include <descrip.h>
+struct IOSB {
+	short iosb$w_value;
+	short iosb$w_count;
+	long  iosb$l_info;
+	};
+#endif
+
+#ifdef OPENSSL_SYS_SUNOS
+	typedef int sig_atomic_t;
+#endif
+
+#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(MAC_OS_GUSI_SOURCE) || defined(OPENSSL_SYS_NETWARE)
+/*
+ * This one needs work. As a matter of fact the code is unoperational
+ * and this is only a trick to get it compiled.
+ *					<appro@fy.chalmers.se>
+ */
+# define TTY_STRUCT int
+#endif
+
+#ifndef NX509_SIG
+# define NX509_SIG 32
+#endif
+
+
+/* Define globals.  They are protected by a lock */
+#ifdef SIGACTION
+static struct sigaction savsig[NX509_SIG];
+#else
+static void (*savsig[NX509_SIG])(int );
+#endif
+
+#ifdef OPENSSL_SYS_VMS
+static struct IOSB iosb;
+static $DESCRIPTOR(terminal,"TT");
+static long tty_orig[3], tty_new[3]; /* XXX   Is there any guarantee that this will always suffice for the actual structures? */
+static long status;
+static unsigned short channel = 0;
+#else
+#if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__)
+static TTY_STRUCT tty_orig,tty_new;
+#endif
+#endif
+static FILE *tty_in, *tty_out;
+static int is_a_tty;
+
+/* Declare static functions */
+#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE)
+static int read_till_nl(FILE *);
+static void recsig(int);
+static void pushsig(void);
+static void popsig(void);
+#endif
+#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16)
+static int noecho_fgets(char *buf, int size, FILE *tty);
+#endif
+static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl);
+
+static int read_string(UI *ui, UI_STRING *uis);
+static int write_string(UI *ui, UI_STRING *uis);
+
+static int open_console(UI *ui);
+static int echo_console(UI *ui);
+static int noecho_console(UI *ui);
+static int close_console(UI *ui);
+
+static UI_METHOD ui_openssl =
+	{
+	"OpenSSL default user interface",
+	open_console,
+	write_string,
+	NULL,			/* No flusher is needed for command lines */
+	read_string,
+	close_console,
+	NULL
+	};
+
+/* The method with all the built-in thingies */
+UI_METHOD *UI_OpenSSL(void)
+	{
+	return &ui_openssl;
+	}
+
+/* The following function makes sure that info and error strings are printed
+   before any prompt. */
+static int write_string(UI *ui, UI_STRING *uis)
+	{
+	switch (UI_get_string_type(uis))
+		{
+	case UIT_ERROR:
+	case UIT_INFO:
+		fputs(UI_get0_output_string(uis), tty_out);
+		fflush(tty_out);
+		break;
+	default:
+		break;
+		}
+	return 1;
+	}
+
+static int read_string(UI *ui, UI_STRING *uis)
+	{
+	int ok = 0;
+
+	switch (UI_get_string_type(uis))
+		{
+	case UIT_BOOLEAN:
+		fputs(UI_get0_output_string(uis), tty_out);
+		fputs(UI_get0_action_string(uis), tty_out);
+		fflush(tty_out);
+		return read_string_inner(ui, uis,
+			UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 0);
+	case UIT_PROMPT:
+		fputs(UI_get0_output_string(uis), tty_out);
+		fflush(tty_out);
+		return read_string_inner(ui, uis,
+			UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 1);
+	case UIT_VERIFY:
+		fprintf(tty_out,"Verifying - %s",
+			UI_get0_output_string(uis));
+		fflush(tty_out);
+		if ((ok = read_string_inner(ui, uis,
+			UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 1)) <= 0)
+			return ok;
+		if (strcmp(UI_get0_result_string(uis),
+			UI_get0_test_string(uis)) != 0)
+			{
+			fprintf(tty_out,"Verify failure\n");
+			fflush(tty_out);
+			return 0;
+			}
+		break;
+	default:
+		break;
+		}
+	return 1;
+	}
+
+
+#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE)
+/* Internal functions to read a string without echoing */
+static int read_till_nl(FILE *in)
+	{
+#define SIZE 4
+	char buf[SIZE+1];
+
+	do	{
+		if (!fgets(buf,SIZE,in))
+			return 0;
+		} while (strchr(buf,'\n') == NULL);
+	return 1;
+	}
+
+static volatile sig_atomic_t intr_signal;
+#endif
+
+static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl)
+	{
+	static int ps;
+	int ok;
+	char result[BUFSIZ];
+	int maxsize = BUFSIZ-1;
+#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE)
+	char *p;
+
+	intr_signal=0;
+	ok=0;
+	ps=0;
+
+	pushsig();
+	ps=1;
+
+	if (!echo && !noecho_console(ui))
+		goto error;
+	ps=2;
+
+	result[0]='\0';
+#ifdef OPENSSL_SYS_MSDOS
+	if (!echo)
+		{
+		noecho_fgets(result,maxsize,tty_in);
+		p=result; /* FIXME: noecho_fgets doesn't return errors */
+		}
+	else
+		p=fgets(result,maxsize,tty_in);
+#else
+	p=fgets(result,maxsize,tty_in);
+#endif
+	if(!p)
+		goto error;
+	if (feof(tty_in)) goto error;
+	if (ferror(tty_in)) goto error;
+	if ((p=(char *)strchr(result,'\n')) != NULL)
+		{
+		if (strip_nl)
+			*p='\0';
+		}
+	else
+		if (!read_till_nl(tty_in))
+			goto error;
+	if (UI_set_result(ui, uis, result) >= 0)
+		ok=1;
+
+error:
+	if (intr_signal == SIGINT)
+		ok=-1;
+	if (!echo) fprintf(tty_out,"\n");
+	if (ps >= 2 && !echo && !echo_console(ui))
+		ok=0;
+
+	if (ps >= 1)
+		popsig();
+#else
+	ok=1;
+#endif
+
+	OPENSSL_cleanse(result,BUFSIZ);
+	return ok;
+	}
+
+
+/* Internal functions to open, handle and close a channel to the console.  */
+static int open_console(UI *ui)
+	{
+	CRYPTO_w_lock(CRYPTO_LOCK_UI);
+	is_a_tty = 1;
+
+#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS)
+	tty_in=stdin;
+	tty_out=stderr;
+#else
+#  ifdef OPENSSL_SYS_MSDOS
+#    define DEV_TTY "con"
+#  else
+#    define DEV_TTY "/dev/tty"
+#  endif
+	if ((tty_in=fopen(DEV_TTY,"r")) == NULL)
+		tty_in=stdin;
+	if ((tty_out=fopen(DEV_TTY,"w")) == NULL)
+		tty_out=stderr;
+#endif
+
+#if defined(TTY_get) && !defined(OPENSSL_SYS_VMS)
+ 	if (TTY_get(fileno(tty_in),&tty_orig) == -1)
+		{
+#ifdef ENOTTY
+		if (errno == ENOTTY)
+			is_a_tty=0;
+		else
+#endif
+#ifdef EINVAL
+		/* Ariel Glenn ariel@columbia.edu reports that solaris
+		 * can return EINVAL instead.  This should be ok */
+		if (errno == EINVAL)
+			is_a_tty=0;
+		else
+#endif
+			return 0;
+		}
+#endif
+#ifdef OPENSSL_SYS_VMS
+	status = sys$assign(&terminal,&channel,0,0);
+	if (status != SS$_NORMAL)
+		return 0;
+	status=sys$qiow(0,channel,IO$_SENSEMODE,&iosb,0,0,tty_orig,12,0,0,0,0);
+	if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
+		return 0;
+#endif
+	return 1;
+	}
+
+static int noecho_console(UI *ui)
+	{
+#ifdef TTY_FLAGS
+	memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig));
+	tty_new.TTY_FLAGS &= ~ECHO;
+#endif
+
+#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
+	if (is_a_tty && (TTY_set(fileno(tty_in),&tty_new) == -1))
+		return 0;
+#endif
+#ifdef OPENSSL_SYS_VMS
+	tty_new[0] = tty_orig[0];
+	tty_new[1] = tty_orig[1] | TT$M_NOECHO;
+	tty_new[2] = tty_orig[2];
+	status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0);
+	if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
+		return 0;
+#endif
+	return 1;
+	}
+
+static int echo_console(UI *ui)
+	{
+#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
+	memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig));
+	tty_new.TTY_FLAGS |= ECHO;
+#endif
+
+#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
+	if (is_a_tty && (TTY_set(fileno(tty_in),&tty_new) == -1))
+		return 0;
+#endif
+#ifdef OPENSSL_SYS_VMS
+	tty_new[0] = tty_orig[0];
+	tty_new[1] = tty_orig[1] & ~TT$M_NOECHO;
+	tty_new[2] = tty_orig[2];
+	status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0);
+	if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
+		return 0;
+#endif
+	return 1;
+	}
+
+static int close_console(UI *ui)
+	{
+	if (tty_in != stdin) fclose(tty_in);
+	if (tty_out != stderr) fclose(tty_out);
+#ifdef OPENSSL_SYS_VMS
+	status = sys$dassgn(channel);
+#endif
+	CRYPTO_w_unlock(CRYPTO_LOCK_UI);
+
+	return 1;
+	}
+
+
+#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE)
+/* Internal functions to handle signals and act on them */
+static void pushsig(void)
+	{
+#ifndef OPENSSL_SYS_WIN32
+	int i;
+#endif
+#ifdef SIGACTION
+	struct sigaction sa;
+
+	memset(&sa,0,sizeof sa);
+	sa.sa_handler=recsig;
+#endif
+
+#ifdef OPENSSL_SYS_WIN32
+	savsig[SIGABRT]=signal(SIGABRT,recsig);
+	savsig[SIGFPE]=signal(SIGFPE,recsig);
+	savsig[SIGILL]=signal(SIGILL,recsig);
+	savsig[SIGINT]=signal(SIGINT,recsig);
+	savsig[SIGSEGV]=signal(SIGSEGV,recsig);
+	savsig[SIGTERM]=signal(SIGTERM,recsig);
+#else
+	for (i=1; i<NX509_SIG; i++)
+		{
+#ifdef SIGUSR1
+		if (i == SIGUSR1)
+			continue;
+#endif
+#ifdef SIGUSR2
+		if (i == SIGUSR2)
+			continue;
+#endif
+#ifdef SIGKILL
+		if (i == SIGKILL) /* We can't make any action on that. */
+			continue;
+#endif
+#ifdef SIGACTION
+		sigaction(i,&sa,&savsig[i]);
+#else
+		savsig[i]=signal(i,recsig);
+#endif
+		}
+#endif
+
+#ifdef SIGWINCH
+	signal(SIGWINCH,SIG_DFL);
+#endif
+	}
+
+static void popsig(void)
+	{
+#ifdef OPENSSL_SYS_WIN32
+	signal(SIGABRT,savsig[SIGABRT]);
+	signal(SIGFPE,savsig[SIGFPE]);
+	signal(SIGILL,savsig[SIGILL]);
+	signal(SIGINT,savsig[SIGINT]);
+	signal(SIGSEGV,savsig[SIGSEGV]);
+	signal(SIGTERM,savsig[SIGTERM]);
+#else
+	int i;
+	for (i=1; i<NX509_SIG; i++)
+		{
+#ifdef SIGUSR1
+		if (i == SIGUSR1)
+			continue;
+#endif
+#ifdef SIGUSR2
+		if (i == SIGUSR2)
+			continue;
+#endif
+#ifdef SIGACTION
+		sigaction(i,&savsig[i],NULL);
+#else
+		signal(i,savsig[i]);
+#endif
+		}
+#endif
+	}
+
+static void recsig(int i)
+	{
+	intr_signal=i;
+	}
+#endif
+
+/* Internal functions specific for Windows */
+#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE)
+static int noecho_fgets(char *buf, int size, FILE *tty)
+	{
+	int i;
+	char *p;
+
+	p=buf;
+	for (;;)
+		{
+		if (size == 0)
+			{
+			*p='\0';
+			break;
+			}
+		size--;
+#ifdef WIN16TTY
+		i=_inchar();
+#elif defined(_WIN32)
+		i=_getch();
+#else
+		i=getch();
+#endif
+		if (i == '\r') i='\n';
+		*(p++)=i;
+		if (i == '\n')
+			{
+			*p='\0';
+			break;
+			}
+		}
+#ifdef WIN_CONSOLE_BUG
+/* Win95 has several evil console bugs: one of these is that the
+ * last character read using getch() is passed to the next read: this is
+ * usually a CR so this can be trouble. No STDIO fix seems to work but
+ * flushing the console appears to do the trick.
+ */
+		{
+			HANDLE inh;
+			inh = GetStdHandle(STD_INPUT_HANDLE);
+			FlushConsoleInputBuffer(inh);
+		}
+#endif
+	return(strlen(buf));
+	}
+#endif
diff --git a/openssl/crypto/ui/ui_util.c b/openssl/crypto/ui/ui_util.c
new file mode 100644
index 0000000..5d9760b
--- /dev/null
+++ b/openssl/crypto/ui/ui_util.c
@@ -0,0 +1,91 @@
+/* crypto/ui/ui_util.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 2001-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+#include "ui_locl.h"
+
+int UI_UTIL_read_pw_string(char *buf,int length,const char *prompt,int verify)
+	{
+	char buff[BUFSIZ];
+	int ret;
+
+	ret=UI_UTIL_read_pw(buf,buff,(length>BUFSIZ)?BUFSIZ:length,prompt,verify);
+	OPENSSL_cleanse(buff,BUFSIZ);
+	return(ret);
+	}
+
+int UI_UTIL_read_pw(char *buf,char *buff,int size,const char *prompt,int verify)
+	{
+	int ok = 0;
+	UI *ui;
+
+	if (size < 1)
+		return -1;
+
+	ui = UI_new();
+	if (ui)
+		{
+		ok = UI_add_input_string(ui,prompt,0,buf,0,size-1);
+		if (ok >= 0 && verify)
+			ok = UI_add_verify_string(ui,prompt,0,buff,0,size-1,
+				buf);
+		if (ok >= 0)
+			ok=UI_process(ui);
+		UI_free(ui);
+		}
+	if (ok > 0)
+		ok = 0;
+	return(ok);
+	}
diff --git a/openssl/crypto/uid.c b/openssl/crypto/uid.c
new file mode 100644
index 0000000..b1fd52b
--- /dev/null
+++ b/openssl/crypto/uid.c
@@ -0,0 +1,89 @@
+/* crypto/uid.c */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/crypto.h>
+#include <openssl/opensslconf.h>
+
+#if defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD__ > 2)
+
+#include OPENSSL_UNISTD
+
+int OPENSSL_issetugid(void)
+	{
+	return issetugid();
+	}
+
+#elif defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)
+
+int OPENSSL_issetugid(void)
+	{
+	return 0;
+	}
+
+#else
+
+#include OPENSSL_UNISTD
+#include <sys/types.h>
+
+int OPENSSL_issetugid(void)
+	{
+	if (getuid() != geteuid()) return 1;
+	if (getgid() != getegid()) return 1;
+	return 0;
+	}
+#endif
+
+
+
diff --git a/openssl/crypto/vms_rms.h b/openssl/crypto/vms_rms.h
new file mode 100644
index 0000000..00a00d9
--- /dev/null
+++ b/openssl/crypto/vms_rms.h
@@ -0,0 +1,51 @@
+
+#ifdef NAML$C_MAXRSS
+
+# define CC_RMS_NAMX cc$rms_naml
+# define FAB_NAMX fab$l_naml
+# define FAB_OR_NAML( fab, naml) naml
+# define FAB_OR_NAML_DNA naml$l_long_defname
+# define FAB_OR_NAML_DNS naml$l_long_defname_size
+# define FAB_OR_NAML_FNA naml$l_long_filename
+# define FAB_OR_NAML_FNS naml$l_long_filename_size
+# define NAMX_ESA naml$l_long_expand
+# define NAMX_ESL naml$l_long_expand_size
+# define NAMX_ESS naml$l_long_expand_alloc
+# define NAMX_NOP naml$b_nop
+# define SET_NAMX_NO_SHORT_UPCASE( nam) nam.naml$v_no_short_upcase = 1
+
+# if __INITIAL_POINTER_SIZE == 64
+#  define NAMX_DNA_FNA_SET(fab) fab.fab$l_dna = (__char_ptr32) -1; \
+   fab.fab$l_fna = (__char_ptr32) -1;
+# else /* __INITIAL_POINTER_SIZE == 64 */
+#  define NAMX_DNA_FNA_SET(fab) fab.fab$l_dna = (char *) -1; \
+   fab.fab$l_fna = (char *) -1;
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+# define NAMX_MAXRSS NAML$C_MAXRSS
+# define NAMX_STRUCT NAML
+
+#else /* def NAML$C_MAXRSS */
+
+# define CC_RMS_NAMX cc$rms_nam
+# define FAB_NAMX fab$l_nam
+# define FAB_OR_NAML( fab, naml) fab
+# define FAB_OR_NAML_DNA fab$l_dna
+# define FAB_OR_NAML_DNS fab$b_dns
+# define FAB_OR_NAML_FNA fab$l_fna
+# define FAB_OR_NAML_FNS fab$b_fns
+# define NAMX_ESA nam$l_esa
+# define NAMX_ESL nam$b_esl
+# define NAMX_ESS nam$b_ess
+# define NAMX_NOP nam$b_nop
+# define NAMX_DNA_FNA_SET(fab)
+# define NAMX_MAXRSS NAM$C_MAXRSS
+# define NAMX_STRUCT NAM
+# ifdef NAM$M_NO_SHORT_UPCASE
+#  define SET_NAMX_NO_SHORT_UPCASE( nam) naml.naml$v_no_short_upcase = 1
+# else /* def NAM$M_NO_SHORT_UPCASE */
+#  define SET_NAMX_NO_SHORT_UPCASE( nam)
+# endif /* def NAM$M_NO_SHORT_UPCASE [else] */
+
+#endif /* def NAML$C_MAXRSS [else] */
+
diff --git a/openssl/crypto/whrlpool/Makefile b/openssl/crypto/whrlpool/Makefile
new file mode 100644
index 0000000..566b996
--- /dev/null
+++ b/openssl/crypto/whrlpool/Makefile
@@ -0,0 +1,93 @@
+#
+# crypto/whrlpool/Makefile
+#
+
+DIR=	whrlpool
+TOP=	../..
+CC=	cc
+CPP=	$(CC) -E
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+WP_ASM_OBJ=wp_block.o
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+ASFLAGS= $(INCLUDES) $(ASFLAG)
+AFLAGS= $(ASFLAGS)
+
+GENERAL=Makefile
+TEST=wp_test.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=wp_dgst.c wp_block.c
+LIBOBJ=wp_dgst.o $(WP_ASM_OBJ)
+
+SRC= $(LIBSRC)
+
+EXHEADER= whrlpool.h
+HEADER= wp_locl.h $(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+wp-mmx.s:	asm/wp-mmx.pl ../perlasm/x86asm.pl
+	$(PERL) asm/wp-mmx.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
+
+wp-x86_64.s: asm/wp-x86_64.pl
+	$(PERL) asm/wp-x86_64.pl $(PERLASM_SCHEME) > $@
+
+$(LIBOBJ): $(LIBSRC)
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+wp_block.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+wp_block.o: ../../include/openssl/whrlpool.h wp_block.c wp_locl.h
+wp_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+wp_dgst.o: ../../include/openssl/whrlpool.h wp_dgst.c wp_locl.h
diff --git a/openssl/crypto/whrlpool/asm/wp-mmx.pl b/openssl/crypto/whrlpool/asm/wp-mmx.pl
new file mode 100644
index 0000000..32cf163
--- /dev/null
+++ b/openssl/crypto/whrlpool/asm/wp-mmx.pl
@@ -0,0 +1,493 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. Rights for redistribution and usage in source and binary
+# forms are granted according to the OpenSSL license.
+# ====================================================================
+#
+# whirlpool_block_mmx implementation.
+#
+*SCALE=\(2); # 2 or 8, that is the question:-) Value of 8 results
+# in 16KB large table, which is tough on L1 cache, but eliminates
+# unaligned references to it. Value of 2 results in 4KB table, but
+# 7/8 of references to it are unaligned. AMD cores seem to be
+# allergic to the latter, while Intel ones - to former [see the
+# table]. I stick to value of 2 for two reasons: 1. smaller table
+# minimizes cache trashing and thus mitigates the hazard of side-
+# channel leakage similar to AES cache-timing one; 2. performance
+# gap among different µ-archs is smaller.
+#
+# Performance table lists rounded amounts of CPU cycles spent by
+# whirlpool_block_mmx routine on single 64 byte input block, i.e.
+# smaller is better and asymptotic throughput can be estimated by
+# multiplying 64 by CPU clock frequency and dividing by relevant
+# value from the given table:
+#
+#		$SCALE=2/8	icc8	gcc3	
+# Intel P4	3200/4600	4600(*)	6400
+# Intel PIII	2900/3000	4900	5400
+# AMD K[78]	2500/1800	9900	8200(**)
+#
+# (*)	I've sketched even non-MMX assembler, but for the record
+#	I've failed to beat the Intel compiler on P4, without using
+#	MMX that is...
+# (**)	... on AMD on the other hand non-MMX assembler was observed
+#	to perform significantly better, but I figured this MMX
+#	implementation is even faster anyway, so why bother? As for
+#	pre-MMX AMD core[s], the improvement coefficient is more
+#	than likely to vary anyway and I don't know how. But the
+#	least I know is that gcc-generated code compiled with
+#	-DL_ENDIAN and -DOPENSSL_SMALL_FOOTPRINT [see C module for
+#	details] and optimized for Pentium was observed to perform
+#	*better* on Pentium 100 than unrolled non-MMX assembler
+#	loop... So we just say that I don't know if maintaining
+#	non-MMX implementation would actually pay off, but till
+#	opposite is proved "unlikely" is assumed.
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"wp-mmx.pl");
+
+sub L()  { &data_byte(@_); }
+sub LL()
+{	if	($SCALE==2)	{ &data_byte(@_); &data_byte(@_); }
+	elsif	($SCALE==8)	{ for ($i=0;$i<8;$i++) {
+					&data_byte(@_);
+					unshift(@_,pop(@_));
+				  }
+				}
+	else			{ die "unvalid SCALE value"; }
+}
+
+sub scale()
+{	if	($SCALE==2)	{ &lea(@_[0],&DWP(0,@_[1],@_[1])); }
+	elsif	($SCALE==8)	{ &lea(@_[0],&DWP(0,"",@_[1],8));  }
+	else			{ die "unvalid SCALE value";       }
+}
+
+sub row()
+{	if	($SCALE==2)	{ ((8-shift)&7); }
+	elsif	($SCALE==8)	{ (8*shift);     }
+	else			{ die "unvalid SCALE value"; }
+}
+
+$tbl="ebp";
+@mm=("mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7");
+
+&function_begin_B("whirlpool_block_mmx");
+	&push	("ebp");
+	&push	("ebx");
+	&push	("esi");
+	&push	("edi");
+
+	&mov	("esi",&wparam(0));		# hash value
+	&mov	("edi",&wparam(1));		# input data stream
+	&mov	("ebp",&wparam(2));		# number of chunks in input
+
+	&mov	("eax","esp");			# copy stack pointer
+	&sub	("esp",128+20);			# allocate frame
+	&and	("esp",-64);			# align for cache-line
+
+	&lea	("ebx",&DWP(128,"esp"));
+	&mov	(&DWP(0,"ebx"),"esi");		# save parameter block
+	&mov	(&DWP(4,"ebx"),"edi");
+	&mov	(&DWP(8,"ebx"),"ebp");
+	&mov	(&DWP(16,"ebx"),"eax");		# saved stack pointer
+
+	&call	(&label("pic_point"));
+&set_label("pic_point");
+	&blindpop($tbl);
+	&lea	($tbl,&DWP(&label("table")."-".&label("pic_point"),$tbl));
+
+	&xor	("ecx","ecx");
+	&xor	("edx","edx");
+
+	for($i=0;$i<8;$i++) { &movq(@mm[$i],&QWP($i*8,"esi")); }    # L=H
+&set_label("outerloop");
+	for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esp"),@mm[$i]); }    # K=L
+	for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"edi")); }    # L^=inp
+	for($i=0;$i<8;$i++) { &movq(&QWP(64+$i*8,"esp"),@mm[$i]); } # S=L
+
+	&xor	("esi","esi");
+	&mov	(&DWP(12,"ebx"),"esi");		# zero round counter
+
+&set_label("round",16);
+	&movq	(@mm[0],&QWP(2048*$SCALE,$tbl,"esi",8));	# rc[r]
+	&mov	("eax",&DWP(0,"esp"));
+	&mov	("ebx",&DWP(4,"esp"));
+for($i=0;$i<8;$i++) {
+    my $func = ($i==0)? movq : pxor;
+	&movb	(&LB("ecx"),&LB("eax"));
+	&movb	(&LB("edx"),&HB("eax"));
+	&scale	("esi","ecx");
+	&scale	("edi","edx");
+	&shr	("eax",16);
+	&pxor	(@mm[0],&QWP(&row(0),$tbl,"esi",8));
+	&$func	(@mm[1],&QWP(&row(1),$tbl,"edi",8));
+	&movb	(&LB("ecx"),&LB("eax"));
+	&movb	(&LB("edx"),&HB("eax"));
+	&mov	("eax",&DWP(($i+1)*8,"esp"));
+	&scale	("esi","ecx");
+	&scale	("edi","edx");
+	&$func	(@mm[2],&QWP(&row(2),$tbl,"esi",8));
+	&$func	(@mm[3],&QWP(&row(3),$tbl,"edi",8));
+	&movb	(&LB("ecx"),&LB("ebx"));
+	&movb	(&LB("edx"),&HB("ebx"));
+	&scale	("esi","ecx");
+	&scale	("edi","edx");
+	&shr	("ebx",16);
+	&$func	(@mm[4],&QWP(&row(4),$tbl,"esi",8));
+	&$func	(@mm[5],&QWP(&row(5),$tbl,"edi",8));
+	&movb	(&LB("ecx"),&LB("ebx"));
+	&movb	(&LB("edx"),&HB("ebx"));
+	&mov	("ebx",&DWP(($i+1)*8+4,"esp"));
+	&scale	("esi","ecx");
+	&scale	("edi","edx");
+	&$func	(@mm[6],&QWP(&row(6),$tbl,"esi",8));
+	&$func	(@mm[7],&QWP(&row(7),$tbl,"edi",8));
+    push(@mm,shift(@mm));
+}
+
+	for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esp"),@mm[$i]); }    # K=L
+
+for($i=0;$i<8;$i++) {
+	&movb	(&LB("ecx"),&LB("eax"));
+	&movb	(&LB("edx"),&HB("eax"));
+	&scale	("esi","ecx");
+	&scale	("edi","edx");
+	&shr	("eax",16);
+	&pxor	(@mm[0],&QWP(&row(0),$tbl,"esi",8));
+	&pxor	(@mm[1],&QWP(&row(1),$tbl,"edi",8));
+	&movb	(&LB("ecx"),&LB("eax"));
+	&movb	(&LB("edx"),&HB("eax"));
+	&mov	("eax",&DWP(64+($i+1)*8,"esp"))		if ($i<7);
+	&scale	("esi","ecx");
+	&scale	("edi","edx");
+	&pxor	(@mm[2],&QWP(&row(2),$tbl,"esi",8));
+	&pxor	(@mm[3],&QWP(&row(3),$tbl,"edi",8));
+	&movb	(&LB("ecx"),&LB("ebx"));
+	&movb	(&LB("edx"),&HB("ebx"));
+	&scale	("esi","ecx");
+	&scale	("edi","edx");
+	&shr	("ebx",16);
+	&pxor	(@mm[4],&QWP(&row(4),$tbl,"esi",8));
+	&pxor	(@mm[5],&QWP(&row(5),$tbl,"edi",8));
+	&movb	(&LB("ecx"),&LB("ebx"));
+	&movb	(&LB("edx"),&HB("ebx"));
+	&mov	("ebx",&DWP(64+($i+1)*8+4,"esp"))	if ($i<7);
+	&scale	("esi","ecx");
+	&scale	("edi","edx");
+	&pxor	(@mm[6],&QWP(&row(6),$tbl,"esi",8));
+	&pxor	(@mm[7],&QWP(&row(7),$tbl,"edi",8));
+    push(@mm,shift(@mm));
+}
+	&lea	("ebx",&DWP(128,"esp"));
+	&mov	("esi",&DWP(12,"ebx"));		# pull round counter
+	&add	("esi",1);
+	&cmp	("esi",10);
+	&je	(&label("roundsdone"));
+
+	&mov	(&DWP(12,"ebx"),"esi");		# update round counter
+	for($i=0;$i<8;$i++) { &movq(&QWP(64+$i*8,"esp"),@mm[$i]); } # S=L
+	&jmp	(&label("round"));
+
+&set_label("roundsdone",16);
+	&mov	("esi",&DWP(0,"ebx"));		# reload argument block
+	&mov	("edi",&DWP(4,"ebx"));
+	&mov	("eax",&DWP(8,"ebx"));
+
+	for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"edi")); }    # L^=inp
+	for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"esi")); }    # L^=H
+	for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esi"),@mm[$i]); }    # H=L
+
+	&lea	("edi",&DWP(64,"edi"));		# inp+=64
+	&sub	("eax",1);			# num--
+	&jz	(&label("alldone"));
+	&mov	(&DWP(4,"ebx"),"edi");		# update argument block
+	&mov	(&DWP(8,"ebx"),"eax");
+	&jmp	(&label("outerloop"));
+
+&set_label("alldone");
+	&emms	();
+	&mov	("esp",&DWP(16,"ebx"));		# restore saved stack pointer
+	&pop	("edi");
+	&pop	("esi");
+	&pop	("ebx");
+	&pop	("ebp");
+	&ret	();
+
+&align(64);
+&set_label("table");
+	&LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8);
+	&LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26);
+	&LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8);
+	&LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb);
+	&LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb);
+	&LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11);
+	&LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09);
+	&LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d);
+	&LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b);
+	&LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff);
+	&LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c);
+	&LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e);
+	&LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96);
+	&LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30);
+	&LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d);
+	&LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8);
+	&LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47);
+	&LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35);
+	&LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37);
+	&LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a);
+	&LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2);
+	&LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c);
+	&LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84);
+	&LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80);
+	&LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5);
+	&LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3);
+	&LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21);
+	&LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c);
+	&LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43);
+	&LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29);
+	&LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d);
+	&LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5);
+	&LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd);
+	&LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8);
+	&LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92);
+	&LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e);
+	&LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13);
+	&LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23);
+	&LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20);
+	&LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44);
+	&LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2);
+	&LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf);
+	&LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c);
+	&LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a);
+	&LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50);
+	&LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9);
+	&LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14);
+	&LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9);
+	&LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c);
+	&LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f);
+	&LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90);
+	&LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07);
+	&LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd);
+	&LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3);
+	&LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d);
+	&LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78);
+	&LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97);
+	&LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02);
+	&LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73);
+	&LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7);
+	&LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6);
+	&LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2);
+	&LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49);
+	&LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56);
+	&LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70);
+	&LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd);
+	&LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb);
+	&LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71);
+	&LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b);
+	&LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf);
+	&LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45);
+	&LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a);
+	&LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4);
+	&LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58);
+	&LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e);
+	&LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f);
+	&LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac);
+	&LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0);
+	&LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef);
+	&LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6);
+	&LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c);
+	&LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12);
+	&LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93);
+	&LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde);
+	&LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6);
+	&LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1);
+	&LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b);
+	&LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f);
+	&LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31);
+	&LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8);
+	&LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9);
+	&LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc);
+	&LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e);
+	&LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b);
+	&LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf);
+	&LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59);
+	&LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2);
+	&LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77);
+	&LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33);
+	&LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4);
+	&LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27);
+	&LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb);
+	&LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89);
+	&LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32);
+	&LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54);
+	&LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d);
+	&LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64);
+	&LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d);
+	&LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d);
+	&LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f);
+	&LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca);
+	&LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7);
+	&LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d);
+	&LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce);
+	&LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f);
+	&LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f);
+	&LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63);
+	&LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a);
+	&LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc);
+	&LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82);
+	&LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a);
+	&LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48);
+	&LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95);
+	&LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf);
+	&LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d);
+	&LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0);
+	&LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91);
+	&LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8);
+	&LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b);
+	&LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
+	&LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9);
+	&LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e);
+	&LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1);
+	&LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6);
+	&LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28);
+	&LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3);
+	&LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74);
+	&LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe);
+	&LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d);
+	&LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea);
+	&LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57);
+	&LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38);
+	&LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad);
+	&LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4);
+	&LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda);
+	&LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7);
+	&LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb);
+	&LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9);
+	&LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a);
+	&LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03);
+	&LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a);
+	&LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e);
+	&LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60);
+	&LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc);
+	&LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46);
+	&LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f);
+	&LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76);
+	&LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa);
+	&LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36);
+	&LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae);
+	&LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b);
+	&LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85);
+	&LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e);
+	&LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7);
+	&LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55);
+	&LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a);
+	&LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81);
+	&LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52);
+	&LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62);
+	&LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3);
+	&LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10);
+	&LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab);
+	&LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0);
+	&LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5);
+	&LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec);
+	&LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16);
+	&LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94);
+	&LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f);
+	&LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5);
+	&LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98);
+	&LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17);
+	&LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4);
+	&LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1);
+	&LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e);
+	&LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42);
+	&LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34);
+	&LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08);
+	&LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee);
+	&LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61);
+	&LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1);
+	&LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f);
+	&LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24);
+	&LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3);
+	&LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25);
+	&LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22);
+	&LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65);
+	&LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79);
+	&LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69);
+	&LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9);
+	&LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19);
+	&LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe);
+	&LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a);
+	&LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0);
+	&LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99);
+	&LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83);
+	&LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04);
+	&LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66);
+	&LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0);
+	&LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1);
+	&LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd);
+	&LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40);
+	&LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c);
+	&LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18);
+	&LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b);
+	&LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51);
+	&LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05);
+	&LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c);
+	&LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39);
+	&LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa);
+	&LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b);
+	&LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc);
+	&LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e);
+	&LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0);
+	&LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88);
+	&LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67);
+	&LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a);
+	&LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87);
+	&LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1);
+	&LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72);
+	&LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53);
+	&LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01);
+	&LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b);
+	&LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4);
+	&LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3);
+	&LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15);
+	&LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c);
+	&LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5);
+	&LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5);
+	&LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4);
+	&LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba);
+	&LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6);
+	&LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7);
+	&LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06);
+	&LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41);
+	&LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7);
+	&LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f);
+	&LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e);
+	&LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6);
+	&LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2);
+	&LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68);
+	&LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c);
+	&LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed);
+	&LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75);
+	&LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86);
+	&LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b);
+	&LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2);
+
+	&L(0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f);	# rc[ROUNDS]
+	&L(0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52);
+	&L(0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35);
+	&L(0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57);
+	&L(0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda);
+	&L(0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85);
+	&L(0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67);
+	&L(0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8);
+	&L(0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e);
+	&L(0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33);
+
+&function_end_B("whirlpool_block_mmx");
+&asm_finish(); 
diff --git a/openssl/crypto/whrlpool/asm/wp-x86_64.pl b/openssl/crypto/whrlpool/asm/wp-x86_64.pl
new file mode 100644
index 0000000..87c0843
--- /dev/null
+++ b/openssl/crypto/whrlpool/asm/wp-x86_64.pl
@@ -0,0 +1,589 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. Rights for redistribution and usage in source and binary
+# forms are granted according to the OpenSSL license.
+# ====================================================================
+#
+# whirlpool_block for x86_64.
+#
+# 2500 cycles per 64-byte input block on AMD64, which is *identical*
+# to 32-bit MMX version executed on same CPU. So why did I bother?
+# Well, it's faster than gcc 3.3.2 generated code by over 50%, and
+# over 80% faster than PathScale 1.4, an "ambitious" commercial
+# compiler. Furthermore it surpasses gcc 3.4.3 by 170% and Sun Studio
+# 10 - by 360%[!]... What is it with x86_64 compilers? It's not the
+# first example when they fail to generate more optimal code, when
+# I believe they had *all* chances to...
+#
+# Note that register and stack frame layout are virtually identical
+# to 32-bit MMX version, except that %r8-15 are used instead of
+# %mm0-8. You can even notice that K[i] and S[i] are loaded to
+# %eax:%ebx as pair of 32-bit values and not as single 64-bit one.
+# This is done in order to avoid 64-bit shift penalties on Intel
+# EM64T core. Speaking of which! I bet it's possible to improve
+# Opteron performance by compressing the table to 2KB and replacing
+# unaligned references with complementary rotations [which would
+# incidentally replace lea instructions], but it would definitely
+# just "kill" EM64T, because it has only 1 shifter/rotator [against
+# 3 on Opteron] and which is *unacceptably* slow with 64-bit
+# operand.
+
+$flavour = shift;
+$output  = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour $output";
+
+sub L() { $code.=".byte	".join(',',@_)."\n"; }
+sub LL(){ $code.=".byte	".join(',',@_).",".join(',',@_)."\n"; }
+
+@mm=("%r8","%r9","%r10","%r11","%r12","%r13","%r14","%r15");
+
+$func="whirlpool_block";
+$table=".Ltable";
+
+$code=<<___;
+.text
+
+.globl	$func
+.type	$func,\@function,3
+.align	16
+$func:
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+
+	mov	%rsp,%r11
+	sub	\$128+40,%rsp
+	and	\$-64,%rsp
+
+	lea	128(%rsp),%r10
+	mov	%rdi,0(%r10)		# save parameter block
+	mov	%rsi,8(%r10)
+	mov	%rdx,16(%r10)
+	mov	%r11,32(%r10)		# saved stack pointer
+.Lprologue:
+
+	mov	%r10,%rbx
+	lea	$table(%rip),%rbp
+
+	xor	%rcx,%rcx
+	xor	%rdx,%rdx
+___
+for($i=0;$i<8;$i++) { $code.="mov $i*8(%rdi),@mm[$i]\n"; }	# L=H
+$code.=".Louterloop:\n";
+for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rsp)\n"; }	# K=L
+for($i=0;$i<8;$i++) { $code.="xor $i*8(%rsi),@mm[$i]\n"; }	# L^=inp
+for($i=0;$i<8;$i++) { $code.="mov @mm[$i],64+$i*8(%rsp)\n"; }	# S=L
+$code.=<<___;
+	xor	%rsi,%rsi
+	mov	%rsi,24(%rbx)		# zero round counter
+.align	16
+.Lround:
+	mov	4096(%rbp,%rsi,8),@mm[0]	# rc[r]
+	mov	0(%rsp),%eax
+	mov	4(%rsp),%ebx
+___
+for($i=0;$i<8;$i++) {
+    my $func = ($i==0)? "mov" : "xor";
+    $code.=<<___;
+	mov	%al,%cl
+	mov	%ah,%dl
+	lea	(%rcx,%rcx),%rsi
+	lea	(%rdx,%rdx),%rdi
+	shr	\$16,%eax
+	xor	0(%rbp,%rsi,8),@mm[0]
+	$func	7(%rbp,%rdi,8),@mm[1]
+	mov	%al,%cl
+	mov	%ah,%dl
+	mov	$i*8+8(%rsp),%eax		# ($i+1)*8
+	lea	(%rcx,%rcx),%rsi
+	lea	(%rdx,%rdx),%rdi
+	$func	6(%rbp,%rsi,8),@mm[2]
+	$func	5(%rbp,%rdi,8),@mm[3]
+	mov	%bl,%cl
+	mov	%bh,%dl
+	lea	(%rcx,%rcx),%rsi
+	lea	(%rdx,%rdx),%rdi
+	shr	\$16,%ebx
+	$func	4(%rbp,%rsi,8),@mm[4]
+	$func	3(%rbp,%rdi,8),@mm[5]
+	mov	%bl,%cl
+	mov	%bh,%dl
+	mov	$i*8+8+4(%rsp),%ebx		# ($i+1)*8+4
+	lea	(%rcx,%rcx),%rsi
+	lea	(%rdx,%rdx),%rdi
+	$func	2(%rbp,%rsi,8),@mm[6]
+	$func	1(%rbp,%rdi,8),@mm[7]
+___
+    push(@mm,shift(@mm));
+}
+for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rsp)\n"; }	# K=L
+for($i=0;$i<8;$i++) {
+    $code.=<<___;
+	mov	%al,%cl
+	mov	%ah,%dl
+	lea	(%rcx,%rcx),%rsi
+	lea	(%rdx,%rdx),%rdi
+	shr	\$16,%eax
+	xor	0(%rbp,%rsi,8),@mm[0]
+	xor	7(%rbp,%rdi,8),@mm[1]
+	mov	%al,%cl
+	mov	%ah,%dl
+	`"mov	64+$i*8+8(%rsp),%eax"	if($i<7);`	# 64+($i+1)*8
+	lea	(%rcx,%rcx),%rsi
+	lea	(%rdx,%rdx),%rdi
+	xor	6(%rbp,%rsi,8),@mm[2]
+	xor	5(%rbp,%rdi,8),@mm[3]
+	mov	%bl,%cl
+	mov	%bh,%dl
+	lea	(%rcx,%rcx),%rsi
+	lea	(%rdx,%rdx),%rdi
+	shr	\$16,%ebx
+	xor	4(%rbp,%rsi,8),@mm[4]
+	xor	3(%rbp,%rdi,8),@mm[5]
+	mov	%bl,%cl
+	mov	%bh,%dl
+	`"mov	64+$i*8+8+4(%rsp),%ebx"	if($i<7);`	# 64+($i+1)*8+4
+	lea	(%rcx,%rcx),%rsi
+	lea	(%rdx,%rdx),%rdi
+	xor	2(%rbp,%rsi,8),@mm[6]
+	xor	1(%rbp,%rdi,8),@mm[7]
+___
+    push(@mm,shift(@mm));
+}
+$code.=<<___;
+	lea	128(%rsp),%rbx
+	mov	24(%rbx),%rsi		# pull round counter
+	add	\$1,%rsi
+	cmp	\$10,%rsi
+	je	.Lroundsdone
+
+	mov	%rsi,24(%rbx)		# update round counter
+___
+for($i=0;$i<8;$i++) { $code.="mov @mm[$i],64+$i*8(%rsp)\n"; }	# S=L
+$code.=<<___;
+	jmp	.Lround
+.align	16
+.Lroundsdone:
+	mov	0(%rbx),%rdi		# reload argument block
+	mov	8(%rbx),%rsi
+	mov	16(%rbx),%rax
+___
+for($i=0;$i<8;$i++) { $code.="xor $i*8(%rsi),@mm[$i]\n"; }	# L^=inp
+for($i=0;$i<8;$i++) { $code.="xor $i*8(%rdi),@mm[$i]\n"; }	# L^=H
+for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rdi)\n"; }	# H=L
+$code.=<<___;
+	lea	64(%rsi),%rsi		# inp+=64
+	sub	\$1,%rax		# num--
+	jz	.Lalldone
+	mov	%rsi,8(%rbx)		# update parameter block
+	mov	%rax,16(%rbx)
+	jmp	.Louterloop
+.Lalldone:
+	mov	32(%rbx),%rsi		# restore saved pointer
+	mov	(%rsi),%r15
+	mov	8(%rsi),%r14
+	mov	16(%rsi),%r13
+	mov	24(%rsi),%r12
+	mov	32(%rsi),%rbp
+	mov	40(%rsi),%rbx
+	lea	48(%rsi),%rsp
+.Lepilogue:
+	ret
+.size	$func,.-$func
+
+.align	64
+.type	$table,\@object
+$table:
+___
+	&LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8);
+	&LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26);
+	&LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8);
+	&LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb);
+	&LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb);
+	&LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11);
+	&LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09);
+	&LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d);
+	&LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b);
+	&LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff);
+	&LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c);
+	&LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e);
+	&LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96);
+	&LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30);
+	&LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d);
+	&LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8);
+	&LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47);
+	&LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35);
+	&LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37);
+	&LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a);
+	&LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2);
+	&LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c);
+	&LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84);
+	&LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80);
+	&LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5);
+	&LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3);
+	&LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21);
+	&LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c);
+	&LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43);
+	&LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29);
+	&LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d);
+	&LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5);
+	&LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd);
+	&LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8);
+	&LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92);
+	&LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e);
+	&LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13);
+	&LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23);
+	&LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20);
+	&LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44);
+	&LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2);
+	&LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf);
+	&LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c);
+	&LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a);
+	&LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50);
+	&LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9);
+	&LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14);
+	&LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9);
+	&LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c);
+	&LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f);
+	&LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90);
+	&LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07);
+	&LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd);
+	&LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3);
+	&LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d);
+	&LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78);
+	&LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97);
+	&LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02);
+	&LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73);
+	&LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7);
+	&LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6);
+	&LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2);
+	&LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49);
+	&LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56);
+	&LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70);
+	&LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd);
+	&LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb);
+	&LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71);
+	&LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b);
+	&LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf);
+	&LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45);
+	&LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a);
+	&LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4);
+	&LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58);
+	&LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e);
+	&LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f);
+	&LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac);
+	&LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0);
+	&LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef);
+	&LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6);
+	&LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c);
+	&LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12);
+	&LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93);
+	&LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde);
+	&LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6);
+	&LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1);
+	&LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b);
+	&LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f);
+	&LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31);
+	&LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8);
+	&LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9);
+	&LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc);
+	&LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e);
+	&LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b);
+	&LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf);
+	&LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59);
+	&LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2);
+	&LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77);
+	&LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33);
+	&LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4);
+	&LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27);
+	&LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb);
+	&LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89);
+	&LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32);
+	&LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54);
+	&LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d);
+	&LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64);
+	&LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d);
+	&LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d);
+	&LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f);
+	&LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca);
+	&LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7);
+	&LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d);
+	&LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce);
+	&LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f);
+	&LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f);
+	&LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63);
+	&LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a);
+	&LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc);
+	&LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82);
+	&LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a);
+	&LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48);
+	&LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95);
+	&LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf);
+	&LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d);
+	&LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0);
+	&LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91);
+	&LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8);
+	&LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b);
+	&LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
+	&LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9);
+	&LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e);
+	&LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1);
+	&LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6);
+	&LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28);
+	&LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3);
+	&LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74);
+	&LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe);
+	&LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d);
+	&LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea);
+	&LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57);
+	&LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38);
+	&LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad);
+	&LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4);
+	&LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda);
+	&LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7);
+	&LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb);
+	&LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9);
+	&LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a);
+	&LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03);
+	&LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a);
+	&LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e);
+	&LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60);
+	&LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc);
+	&LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46);
+	&LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f);
+	&LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76);
+	&LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa);
+	&LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36);
+	&LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae);
+	&LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b);
+	&LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85);
+	&LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e);
+	&LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7);
+	&LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55);
+	&LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a);
+	&LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81);
+	&LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52);
+	&LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62);
+	&LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3);
+	&LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10);
+	&LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab);
+	&LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0);
+	&LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5);
+	&LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec);
+	&LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16);
+	&LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94);
+	&LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f);
+	&LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5);
+	&LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98);
+	&LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17);
+	&LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4);
+	&LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1);
+	&LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e);
+	&LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42);
+	&LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34);
+	&LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08);
+	&LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee);
+	&LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61);
+	&LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1);
+	&LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f);
+	&LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24);
+	&LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3);
+	&LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25);
+	&LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22);
+	&LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65);
+	&LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79);
+	&LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69);
+	&LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9);
+	&LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19);
+	&LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe);
+	&LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a);
+	&LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0);
+	&LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99);
+	&LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83);
+	&LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04);
+	&LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66);
+	&LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0);
+	&LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1);
+	&LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd);
+	&LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40);
+	&LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c);
+	&LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18);
+	&LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b);
+	&LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51);
+	&LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05);
+	&LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c);
+	&LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39);
+	&LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa);
+	&LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b);
+	&LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc);
+	&LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e);
+	&LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0);
+	&LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88);
+	&LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67);
+	&LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a);
+	&LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87);
+	&LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1);
+	&LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72);
+	&LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53);
+	&LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01);
+	&LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b);
+	&LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4);
+	&LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3);
+	&LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15);
+	&LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c);
+	&LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5);
+	&LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5);
+	&LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4);
+	&LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba);
+	&LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6);
+	&LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7);
+	&LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06);
+	&LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41);
+	&LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7);
+	&LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f);
+	&LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e);
+	&LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6);
+	&LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2);
+	&LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68);
+	&LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c);
+	&LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed);
+	&LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75);
+	&LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86);
+	&LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b);
+	&LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2);
+
+	&L(0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f);	# rc[ROUNDS]
+	&L(0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52);
+	&L(0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35);
+	&L(0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57);
+	&L(0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda);
+	&L(0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85);
+	&L(0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67);
+	&L(0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8);
+	&L(0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e);
+	&L(0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33);
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern	__imp_RtlVirtualUnwind
+.type	se_handler,\@abi-omnipotent
+.align	16
+se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	lea	.Lprologue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lprologue
+	jb	.Lin_prologue
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	lea	.Lepilogue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
+	jae	.Lin_prologue
+
+	mov	128+32(%rax),%rax	# pull saved stack pointer
+	lea	48(%rax),%rax
+
+	mov	-8(%rax),%rbx
+	mov	-16(%rax),%rbp
+	mov	-24(%rax),%r12
+	mov	-32(%rax),%r13
+	mov	-40(%rax),%r14
+	mov	-48(%rax),%r15
+	mov	%rbx,144($context)	# restore context->Rbx
+	mov	%rbp,160($context)	# restore context->Rbp
+	mov	%r12,216($context)	# restore context->R12
+	mov	%r13,224($context)	# restore context->R13
+	mov	%r14,232($context)	# restore context->R14
+	mov	%r15,240($context)	# restore context->R15
+
+.Lin_prologue:
+	mov	8(%rax),%rdi
+	mov	16(%rax),%rsi
+	mov	%rax,152($context)	# restore context->Rsp
+	mov	%rsi,168($context)	# restore context->Rsi
+	mov	%rdi,176($context)	# restore context->Rdi
+
+	mov	40($disp),%rdi		# disp->ContextRecord
+	mov	$context,%rsi		# context
+	mov	\$154,%ecx		# sizeof(CONTEXT)
+	.long	0xa548f3fc		# cld; rep movsq
+
+	mov	$disp,%rsi
+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
+	mov	40(%rsi),%r10		# disp->ContextRecord
+	lea	56(%rsi),%r11		# &disp->HandlerData
+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
+	mov	%r10,32(%rsp)		# arg5
+	mov	%r11,40(%rsp)		# arg6
+	mov	%r12,48(%rsp)		# arg7
+	mov	%rcx,56(%rsp)		# arg8, (NULL)
+	call	*__imp_RtlVirtualUnwind(%rip)
+
+	mov	\$1,%eax		# ExceptionContinueSearch
+	add	\$64,%rsp
+	popfq
+	pop	%r15
+	pop	%r14
+	pop	%r13
+	pop	%r12
+	pop	%rbp
+	pop	%rbx
+	pop	%rdi
+	pop	%rsi
+	ret
+.size	se_handler,.-se_handler
+
+.section	.pdata
+.align	4
+	.rva	.LSEH_begin_$func
+	.rva	.LSEH_end_$func
+	.rva	.LSEH_info_$func
+
+.section	.xdata
+.align	8
+.LSEH_info_$func:
+	.byte	9,0,0,0
+	.rva	se_handler
+___
+}
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/openssl/crypto/whrlpool/whrlpool.h b/openssl/crypto/whrlpool/whrlpool.h
new file mode 100644
index 0000000..03c91da
--- /dev/null
+++ b/openssl/crypto/whrlpool/whrlpool.h
@@ -0,0 +1,38 @@
+#ifndef HEADER_WHRLPOOL_H
+#define HEADER_WHRLPOOL_H
+
+#include <openssl/e_os2.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WHIRLPOOL_DIGEST_LENGTH	(512/8)
+#define WHIRLPOOL_BBLOCK	512
+#define WHIRLPOOL_COUNTER	(256/8)
+
+typedef struct	{
+	union	{
+		unsigned char	c[WHIRLPOOL_DIGEST_LENGTH];
+		/* double q is here to ensure 64-bit alignment */
+		double		q[WHIRLPOOL_DIGEST_LENGTH/sizeof(double)];
+		}	H;
+	unsigned char	data[WHIRLPOOL_BBLOCK/8];
+	unsigned int	bitoff;
+	size_t		bitlen[WHIRLPOOL_COUNTER/sizeof(size_t)];
+	} WHIRLPOOL_CTX;
+
+#ifndef OPENSSL_NO_WHIRLPOOL
+int WHIRLPOOL_Init	(WHIRLPOOL_CTX *c);
+int WHIRLPOOL_Update	(WHIRLPOOL_CTX *c,const void *inp,size_t bytes);
+void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *inp,size_t bits);
+int WHIRLPOOL_Final	(unsigned char *md,WHIRLPOOL_CTX *c);
+unsigned char *WHIRLPOOL(const void *inp,size_t bytes,unsigned char *md);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/crypto/whrlpool/wp_block.c b/openssl/crypto/whrlpool/wp_block.c
new file mode 100644
index 0000000..221f6cc
--- /dev/null
+++ b/openssl/crypto/whrlpool/wp_block.c
@@ -0,0 +1,655 @@
+/**
+ * The Whirlpool hashing function.
+ *
+ * <P>
+ * <b>References</b>
+ *
+ * <P>
+ * The Whirlpool algorithm was developed by
+ * <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and
+ * <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>.
+ *
+ * See
+ *      P.S.L.M. Barreto, V. Rijmen,
+ *      ``The Whirlpool hashing function,''
+ *      NESSIE submission, 2000 (tweaked version, 2001),
+ *      <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
+ *
+ * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and
+ * Vincent Rijmen. Lookup "reference implementations" on
+ * <http://planeta.terra.com.br/informatica/paulobarreto/>
+ *
+ * =============================================================================
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "wp_locl.h"
+#include <string.h>
+
+typedef unsigned char		u8;
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32)
+typedef unsigned __int64	u64;
+#elif defined(__arch64__)
+typedef unsigned long		u64;
+#else
+typedef unsigned long long	u64;
+#endif
+
+#define ROUNDS	10
+
+#define STRICT_ALIGNMENT
+#if defined(__i386) || defined(__i386__) || \
+    defined(__x86_64) || defined(__x86_64__) || \
+    defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)
+/* Well, formally there're couple of other architectures, which permit
+ * unaligned loads, specifically those not crossing cache lines, IA-64
+ * and PowerPC... */
+#  undef STRICT_ALIGNMENT
+#endif
+
+#undef SMALL_REGISTER_BANK
+#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
+#  define SMALL_REGISTER_BANK
+#  if defined(WHIRLPOOL_ASM)
+#    ifndef OPENSSL_SMALL_FOOTPRINT
+#      define OPENSSL_SMALL_FOOTPRINT	/* it appears that for elder non-MMX
+					   CPUs this is actually faster! */
+#    endif
+#    define GO_FOR_MMX(ctx,inp,num)	do {			\
+	extern unsigned long OPENSSL_ia32cap_P;			\
+	void whirlpool_block_mmx(void *,const void *,size_t);	\
+	if (!(OPENSSL_ia32cap_P & (1<<23)))	break;		\
+        whirlpool_block_mmx(ctx->H.c,inp,num);	return;		\
+					} while (0)
+#  endif
+#endif
+
+#undef ROTATE
+#if defined(_MSC_VER)
+#  if defined(_WIN64)	/* applies to both IA-64 and AMD64 */
+#    pragma intrinsic(_rotl64)
+#    define ROTATE(a,n)	_rotl64((a),n)
+#  endif
+#elif defined(__GNUC__) && __GNUC__>=2
+#  if defined(__x86_64) || defined(__x86_64__)
+#    if defined(L_ENDIAN)
+#      define ROTATE(a,n)	({ u64 ret; asm ("rolq %1,%0"	\
+				   : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; })
+#    elif defined(B_ENDIAN)
+       /* Most will argue that x86_64 is always little-endian. Well,
+        * yes, but then we have stratus.com who has modified gcc to
+	* "emulate" big-endian on x86. Is there evidence that they
+	* [or somebody else] won't do same for x86_64? Naturally no.
+	* And this line is waiting ready for that brave soul:-) */
+#      define ROTATE(a,n)	({ u64 ret; asm ("rorq %1,%0"	\
+				   : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; })
+#    endif
+#  elif defined(__ia64) || defined(__ia64__)
+#    if defined(L_ENDIAN)
+#      define ROTATE(a,n)	({ u64 ret; asm ("shrp %0=%1,%1,%2"	\
+				   : "=r"(ret) : "r"(a),"M"(64-(n))); ret; })
+#    elif defined(B_ENDIAN)
+#      define ROTATE(a,n)	({ u64 ret; asm ("shrp %0=%1,%1,%2"	\
+				   : "=r"(ret) : "r"(a),"M"(n)); ret; })
+#    endif
+#  endif
+#endif
+
+#if defined(OPENSSL_SMALL_FOOTPRINT)
+#  if !defined(ROTATE)
+#    if defined(L_ENDIAN)	/* little-endians have to rotate left */
+#      define ROTATE(i,n)	((i)<<(n) ^ (i)>>(64-n))
+#    elif defined(B_ENDIAN)	/* big-endians have to rotate right */
+#      define ROTATE(i,n)	((i)>>(n) ^ (i)<<(64-n))
+#    endif
+#  endif
+#  if defined(ROTATE) && !defined(STRICT_ALIGNMENT)
+#    define STRICT_ALIGNMENT	/* ensure smallest table size */
+#  endif
+#endif
+
+/*
+ * Table size depends on STRICT_ALIGNMENT and whether or not endian-
+ * specific ROTATE macro is defined. If STRICT_ALIGNMENT is not
+ * defined, which is normally the case on x86[_64] CPUs, the table is
+ * 4KB large unconditionally. Otherwise if ROTATE is defined, the
+ * table is 2KB large, and otherwise - 16KB. 2KB table requires a
+ * whole bunch of additional rotations, but I'm willing to "trade,"
+ * because 16KB table certainly trashes L1 cache. I wish all CPUs
+ * could handle unaligned load as 4KB table doesn't trash the cache,
+ * nor does it require additional rotations.
+ */
+/*
+ * Note that every Cn macro expands as two loads: one byte load and
+ * one quadword load. One can argue that that many single-byte loads
+ * is too excessive, as one could load a quadword and "milk" it for
+ * eight 8-bit values instead. Well, yes, but in order to do so *and*
+ * avoid excessive loads you have to accomodate a handful of 64-bit
+ * values in the register bank and issue a bunch of shifts and mask.
+ * It's a tradeoff: loads vs. shift and mask in big register bank[!].
+ * On most CPUs eight single-byte loads are faster and I let other
+ * ones to depend on smart compiler to fold byte loads if beneficial.
+ * Hand-coded assembler would be another alternative:-)
+ */
+#ifdef STRICT_ALIGNMENT
+#  if defined(ROTATE)
+#    define N	1
+#    define LL(c0,c1,c2,c3,c4,c5,c6,c7)	c0,c1,c2,c3,c4,c5,c6,c7
+#    define C0(K,i)	(Cx.q[K.c[(i)*8+0]])
+#    define C1(K,i)	ROTATE(Cx.q[K.c[(i)*8+1]],8)
+#    define C2(K,i)	ROTATE(Cx.q[K.c[(i)*8+2]],16)
+#    define C3(K,i)	ROTATE(Cx.q[K.c[(i)*8+3]],24)
+#    define C4(K,i)	ROTATE(Cx.q[K.c[(i)*8+4]],32)
+#    define C5(K,i)	ROTATE(Cx.q[K.c[(i)*8+5]],40)
+#    define C6(K,i)	ROTATE(Cx.q[K.c[(i)*8+6]],48)
+#    define C7(K,i)	ROTATE(Cx.q[K.c[(i)*8+7]],56)
+#  else
+#    define N	8
+#    define LL(c0,c1,c2,c3,c4,c5,c6,c7)	c0,c1,c2,c3,c4,c5,c6,c7, \
+					c7,c0,c1,c2,c3,c4,c5,c6, \
+					c6,c7,c0,c1,c2,c3,c4,c5, \
+					c5,c6,c7,c0,c1,c2,c3,c4, \
+					c4,c5,c6,c7,c0,c1,c2,c3, \
+					c3,c4,c5,c6,c7,c0,c1,c2, \
+					c2,c3,c4,c5,c6,c7,c0,c1, \
+					c1,c2,c3,c4,c5,c6,c7,c0
+#    define C0(K,i)	(Cx.q[0+8*K.c[(i)*8+0]])
+#    define C1(K,i)	(Cx.q[1+8*K.c[(i)*8+1]])
+#    define C2(K,i)	(Cx.q[2+8*K.c[(i)*8+2]])
+#    define C3(K,i)	(Cx.q[3+8*K.c[(i)*8+3]])
+#    define C4(K,i)	(Cx.q[4+8*K.c[(i)*8+4]])
+#    define C5(K,i)	(Cx.q[5+8*K.c[(i)*8+5]])
+#    define C6(K,i)	(Cx.q[6+8*K.c[(i)*8+6]])
+#    define C7(K,i)	(Cx.q[7+8*K.c[(i)*8+7]])
+#  endif
+#else
+#  define N	2
+#  define LL(c0,c1,c2,c3,c4,c5,c6,c7)	c0,c1,c2,c3,c4,c5,c6,c7, \
+					c0,c1,c2,c3,c4,c5,c6,c7
+#  define C0(K,i)	(((u64*)(Cx.c+0))[2*K.c[(i)*8+0]])
+#  define C1(K,i)	(((u64*)(Cx.c+7))[2*K.c[(i)*8+1]])
+#  define C2(K,i)	(((u64*)(Cx.c+6))[2*K.c[(i)*8+2]])
+#  define C3(K,i)	(((u64*)(Cx.c+5))[2*K.c[(i)*8+3]])
+#  define C4(K,i)	(((u64*)(Cx.c+4))[2*K.c[(i)*8+4]])
+#  define C5(K,i)	(((u64*)(Cx.c+3))[2*K.c[(i)*8+5]])
+#  define C6(K,i)	(((u64*)(Cx.c+2))[2*K.c[(i)*8+6]])
+#  define C7(K,i)	(((u64*)(Cx.c+1))[2*K.c[(i)*8+7]])
+#endif
+
+static const
+union	{
+	u8	c[(256*N+ROUNDS)*sizeof(u64)];
+	u64	q[(256*N+ROUNDS)];
+	} Cx = { {
+	/* Note endian-neutral representation:-) */
+	LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8),
+	LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26),
+	LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8),
+	LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb),
+	LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb),
+	LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11),
+	LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09),
+	LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d),
+	LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b),
+	LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff),
+	LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c),
+	LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e),
+	LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96),
+	LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30),
+	LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d),
+	LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8),
+	LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47),
+	LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35),
+	LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37),
+	LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a),
+	LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2),
+	LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c),
+	LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84),
+	LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80),
+	LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5),
+	LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3),
+	LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21),
+	LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c),
+	LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43),
+	LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29),
+	LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d),
+	LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5),
+	LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd),
+	LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8),
+	LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92),
+	LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e),
+	LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13),
+	LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23),
+	LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20),
+	LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44),
+	LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2),
+	LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf),
+	LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c),
+	LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a),
+	LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50),
+	LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9),
+	LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14),
+	LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9),
+	LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c),
+	LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f),
+	LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90),
+	LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07),
+	LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd),
+	LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3),
+	LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d),
+	LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78),
+	LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97),
+	LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02),
+	LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73),
+	LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7),
+	LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6),
+	LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2),
+	LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49),
+	LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56),
+	LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70),
+	LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd),
+	LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb),
+	LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71),
+	LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b),
+	LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf),
+	LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45),
+	LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a),
+	LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4),
+	LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58),
+	LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e),
+	LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f),
+	LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac),
+	LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0),
+	LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef),
+	LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6),
+	LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c),
+	LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12),
+	LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93),
+	LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde),
+	LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6),
+	LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1),
+	LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b),
+	LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f),
+	LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31),
+	LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8),
+	LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9),
+	LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc),
+	LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e),
+	LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b),
+	LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf),
+	LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59),
+	LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2),
+	LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77),
+	LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33),
+	LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4),
+	LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27),
+	LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb),
+	LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89),
+	LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32),
+	LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54),
+	LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d),
+	LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64),
+	LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d),
+	LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d),
+	LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f),
+	LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca),
+	LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7),
+	LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d),
+	LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce),
+	LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f),
+	LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f),
+	LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63),
+	LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a),
+	LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc),
+	LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82),
+	LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a),
+	LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48),
+	LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95),
+	LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf),
+	LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d),
+	LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0),
+	LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91),
+	LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8),
+	LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b),
+	LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
+	LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9),
+	LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e),
+	LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1),
+	LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6),
+	LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28),
+	LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3),
+	LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74),
+	LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe),
+	LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d),
+	LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea),
+	LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57),
+	LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38),
+	LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad),
+	LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4),
+	LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda),
+	LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7),
+	LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb),
+	LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9),
+	LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a),
+	LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03),
+	LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a),
+	LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e),
+	LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60),
+	LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc),
+	LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46),
+	LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f),
+	LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76),
+	LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa),
+	LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36),
+	LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae),
+	LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b),
+	LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85),
+	LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e),
+	LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7),
+	LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55),
+	LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a),
+	LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81),
+	LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52),
+	LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62),
+	LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3),
+	LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10),
+	LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab),
+	LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0),
+	LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5),
+	LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec),
+	LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16),
+	LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94),
+	LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f),
+	LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5),
+	LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98),
+	LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17),
+	LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4),
+	LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1),
+	LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e),
+	LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42),
+	LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34),
+	LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08),
+	LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee),
+	LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61),
+	LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1),
+	LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f),
+	LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24),
+	LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3),
+	LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25),
+	LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22),
+	LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65),
+	LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79),
+	LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69),
+	LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9),
+	LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19),
+	LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe),
+	LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a),
+	LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0),
+	LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99),
+	LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83),
+	LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04),
+	LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66),
+	LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0),
+	LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1),
+	LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd),
+	LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40),
+	LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c),
+	LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18),
+	LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b),
+	LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51),
+	LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05),
+	LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c),
+	LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39),
+	LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa),
+	LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b),
+	LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc),
+	LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e),
+	LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0),
+	LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88),
+	LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67),
+	LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a),
+	LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87),
+	LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1),
+	LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72),
+	LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53),
+	LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01),
+	LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b),
+	LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4),
+	LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3),
+	LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15),
+	LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c),
+	LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5),
+	LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5),
+	LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4),
+	LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba),
+	LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6),
+	LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7),
+	LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06),
+	LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41),
+	LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7),
+	LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f),
+	LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e),
+	LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6),
+	LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2),
+	LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68),
+	LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c),
+	LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed),
+	LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75),
+	LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86),
+	LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b),
+	LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2),
+#define RC	(&(Cx.q[256*N]))
+	0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f,	/* rc[ROUNDS] */
+	0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52,
+	0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35,
+	0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57,
+	0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda,
+	0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85,
+	0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67,
+	0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8,
+	0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e,
+	0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33
+	}
+};
+
+void whirlpool_block(WHIRLPOOL_CTX *ctx,const void *inp,size_t n)
+	{
+	int	r;
+	const u8 *p=inp;
+	union	{ u64 q[8]; u8 c[64]; } S,K,*H=(void *)ctx->H.q;
+
+#ifdef GO_FOR_MMX
+	GO_FOR_MMX(ctx,inp,n);
+#endif
+							do {
+#ifdef OPENSSL_SMALL_FOOTPRINT
+	u64	L[8];
+	int	i;
+
+	for (i=0;i<64;i++)	S.c[i] = (K.c[i] = H->c[i]) ^ p[i];
+	for (r=0;r<ROUNDS;r++)
+		{
+		for (i=0;i<8;i++)
+			{
+			L[i]  = i ? 0 : RC[r];
+			L[i] ^=	C0(K,i)       ^ C1(K,(i-1)&7) ^
+				C2(K,(i-2)&7) ^ C3(K,(i-3)&7) ^
+				C4(K,(i-4)&7) ^ C5(K,(i-5)&7) ^
+				C6(K,(i-6)&7) ^ C7(K,(i-7)&7);
+			}
+		memcpy (K.q,L,64);
+		for (i=0;i<8;i++)
+			{
+			L[i] ^= C0(S,i)       ^ C1(S,(i-1)&7) ^
+				C2(S,(i-2)&7) ^ C3(S,(i-3)&7) ^
+				C4(S,(i-4)&7) ^ C5(S,(i-5)&7) ^
+				C6(S,(i-6)&7) ^ C7(S,(i-7)&7);
+			}
+		memcpy (S.q,L,64);
+		}
+	for (i=0;i<64;i++)	H->c[i] ^= S.c[i] ^ p[i];
+#else
+	u64	L0,L1,L2,L3,L4,L5,L6,L7;
+
+#ifdef STRICT_ALIGNMENT
+	if ((size_t)p & 7)
+		{
+		memcpy (S.c,p,64);
+		S.q[0] ^= (K.q[0] = H->q[0]);
+		S.q[1] ^= (K.q[1] = H->q[1]);
+		S.q[2] ^= (K.q[2] = H->q[2]);
+		S.q[3] ^= (K.q[3] = H->q[3]);
+		S.q[4] ^= (K.q[4] = H->q[4]);
+		S.q[5] ^= (K.q[5] = H->q[5]);
+		S.q[6] ^= (K.q[6] = H->q[6]);
+		S.q[7] ^= (K.q[7] = H->q[7]);
+		}
+	else
+#endif
+		{
+		const u64 *pa = (const u64*)p;
+		S.q[0] = (K.q[0] = H->q[0]) ^ pa[0];
+		S.q[1] = (K.q[1] = H->q[1]) ^ pa[1];
+		S.q[2] = (K.q[2] = H->q[2]) ^ pa[2];
+		S.q[3] = (K.q[3] = H->q[3]) ^ pa[3];
+		S.q[4] = (K.q[4] = H->q[4]) ^ pa[4];
+		S.q[5] = (K.q[5] = H->q[5]) ^ pa[5];
+		S.q[6] = (K.q[6] = H->q[6]) ^ pa[6];
+		S.q[7] = (K.q[7] = H->q[7]) ^ pa[7];
+		}
+
+	for(r=0;r<ROUNDS;r++)
+		{
+#ifdef SMALL_REGISTER_BANK
+		L0 =	C0(K,0) ^ C1(K,7) ^ C2(K,6) ^ C3(K,5) ^
+			C4(K,4) ^ C5(K,3) ^ C6(K,2) ^ C7(K,1) ^ RC[r];
+		L1 =	C0(K,1) ^ C1(K,0) ^ C2(K,7) ^ C3(K,6) ^
+			C4(K,5) ^ C5(K,4) ^ C6(K,3) ^ C7(K,2);
+		L2 =	C0(K,2) ^ C1(K,1) ^ C2(K,0) ^ C3(K,7) ^
+			C4(K,6) ^ C5(K,5) ^ C6(K,4) ^ C7(K,3);
+		L3 =	C0(K,3) ^ C1(K,2) ^ C2(K,1) ^ C3(K,0) ^
+			C4(K,7) ^ C5(K,6) ^ C6(K,5) ^ C7(K,4);
+		L4 =	C0(K,4) ^ C1(K,3) ^ C2(K,2) ^ C3(K,1) ^
+			C4(K,0) ^ C5(K,7) ^ C6(K,6) ^ C7(K,5);
+		L5 =	C0(K,5) ^ C1(K,4) ^ C2(K,3) ^ C3(K,2) ^
+			C4(K,1) ^ C5(K,0) ^ C6(K,7) ^ C7(K,6);
+		L6 =	C0(K,6) ^ C1(K,5) ^ C2(K,4) ^ C3(K,3) ^
+			C4(K,2) ^ C5(K,1) ^ C6(K,0) ^ C7(K,7);
+		L7 =	C0(K,7) ^ C1(K,6) ^ C2(K,5) ^ C3(K,4) ^
+			C4(K,3) ^ C5(K,2) ^ C6(K,1) ^ C7(K,0);
+
+		K.q[0] = L0; K.q[1] = L1; K.q[2] = L2; K.q[3] = L3;
+		K.q[4] = L4; K.q[5] = L5; K.q[6] = L6; K.q[7] = L7;
+
+		L0 ^=	C0(S,0) ^ C1(S,7) ^ C2(S,6) ^ C3(S,5) ^
+			C4(S,4) ^ C5(S,3) ^ C6(S,2) ^ C7(S,1);
+		L1 ^=	C0(S,1) ^ C1(S,0) ^ C2(S,7) ^ C3(S,6) ^
+			C4(S,5) ^ C5(S,4) ^ C6(S,3) ^ C7(S,2);
+		L2 ^=	C0(S,2) ^ C1(S,1) ^ C2(S,0) ^ C3(S,7) ^
+			C4(S,6) ^ C5(S,5) ^ C6(S,4) ^ C7(S,3);
+		L3 ^=	C0(S,3) ^ C1(S,2) ^ C2(S,1) ^ C3(S,0) ^
+			C4(S,7) ^ C5(S,6) ^ C6(S,5) ^ C7(S,4);
+		L4 ^=	C0(S,4) ^ C1(S,3) ^ C2(S,2) ^ C3(S,1) ^
+			C4(S,0) ^ C5(S,7) ^ C6(S,6) ^ C7(S,5);
+		L5 ^=	C0(S,5) ^ C1(S,4) ^ C2(S,3) ^ C3(S,2) ^
+			C4(S,1) ^ C5(S,0) ^ C6(S,7) ^ C7(S,6);
+		L6 ^=	C0(S,6) ^ C1(S,5) ^ C2(S,4) ^ C3(S,3) ^
+			C4(S,2) ^ C5(S,1) ^ C6(S,0) ^ C7(S,7);
+		L7 ^=	C0(S,7) ^ C1(S,6) ^ C2(S,5) ^ C3(S,4) ^
+			C4(S,3) ^ C5(S,2) ^ C6(S,1) ^ C7(S,0);
+
+		S.q[0] = L0; S.q[1] = L1; S.q[2] = L2; S.q[3] = L3;
+		S.q[4] = L4; S.q[5] = L5; S.q[6] = L6; S.q[7] = L7;
+#else
+		L0  = C0(K,0); L1  = C1(K,0); L2  = C2(K,0); L3  = C3(K,0);
+		L4  = C4(K,0); L5  = C5(K,0); L6  = C6(K,0); L7  = C7(K,0);
+		L0 ^= RC[r];
+
+		L1 ^= C0(K,1); L2 ^= C1(K,1); L3 ^= C2(K,1); L4 ^= C3(K,1);
+		L5 ^= C4(K,1); L6 ^= C5(K,1); L7 ^= C6(K,1); L0 ^= C7(K,1);
+
+		L2 ^= C0(K,2); L3 ^= C1(K,2); L4 ^= C2(K,2); L5 ^= C3(K,2);
+		L6 ^= C4(K,2); L7 ^= C5(K,2); L0 ^= C6(K,2); L1 ^= C7(K,2);
+
+		L3 ^= C0(K,3); L4 ^= C1(K,3); L5 ^= C2(K,3); L6 ^= C3(K,3);
+		L7 ^= C4(K,3); L0 ^= C5(K,3); L1 ^= C6(K,3); L2 ^= C7(K,3);
+
+		L4 ^= C0(K,4); L5 ^= C1(K,4); L6 ^= C2(K,4); L7 ^= C3(K,4);
+		L0 ^= C4(K,4); L1 ^= C5(K,4); L2 ^= C6(K,4); L3 ^= C7(K,4);
+
+		L5 ^= C0(K,5); L6 ^= C1(K,5); L7 ^= C2(K,5); L0 ^= C3(K,5);
+		L1 ^= C4(K,5); L2 ^= C5(K,5); L3 ^= C6(K,5); L4 ^= C7(K,5);
+
+		L6 ^= C0(K,6); L7 ^= C1(K,6); L0 ^= C2(K,6); L1 ^= C3(K,6);
+		L2 ^= C4(K,6); L3 ^= C5(K,6); L4 ^= C6(K,6); L5 ^= C7(K,6);
+
+		L7 ^= C0(K,7); L0 ^= C1(K,7); L1 ^= C2(K,7); L2 ^= C3(K,7);
+		L3 ^= C4(K,7); L4 ^= C5(K,7); L5 ^= C6(K,7); L6 ^= C7(K,7);
+
+		K.q[0] = L0; K.q[1] = L1; K.q[2] = L2; K.q[3] = L3;
+		K.q[4] = L4; K.q[5] = L5; K.q[6] = L6; K.q[7] = L7;
+
+		L0 ^= C0(S,0); L1 ^= C1(S,0); L2 ^= C2(S,0); L3 ^= C3(S,0);
+		L4 ^= C4(S,0); L5 ^= C5(S,0); L6 ^= C6(S,0); L7 ^= C7(S,0);
+
+		L1 ^= C0(S,1); L2 ^= C1(S,1); L3 ^= C2(S,1); L4 ^= C3(S,1);
+		L5 ^= C4(S,1); L6 ^= C5(S,1); L7 ^= C6(S,1); L0 ^= C7(S,1);
+
+		L2 ^= C0(S,2); L3 ^= C1(S,2); L4 ^= C2(S,2); L5 ^= C3(S,2);
+		L6 ^= C4(S,2); L7 ^= C5(S,2); L0 ^= C6(S,2); L1 ^= C7(S,2);
+
+		L3 ^= C0(S,3); L4 ^= C1(S,3); L5 ^= C2(S,3); L6 ^= C3(S,3);
+		L7 ^= C4(S,3); L0 ^= C5(S,3); L1 ^= C6(S,3); L2 ^= C7(S,3);
+
+		L4 ^= C0(S,4); L5 ^= C1(S,4); L6 ^= C2(S,4); L7 ^= C3(S,4);
+		L0 ^= C4(S,4); L1 ^= C5(S,4); L2 ^= C6(S,4); L3 ^= C7(S,4);
+
+		L5 ^= C0(S,5); L6 ^= C1(S,5); L7 ^= C2(S,5); L0 ^= C3(S,5);
+		L1 ^= C4(S,5); L2 ^= C5(S,5); L3 ^= C6(S,5); L4 ^= C7(S,5);
+
+		L6 ^= C0(S,6); L7 ^= C1(S,6); L0 ^= C2(S,6); L1 ^= C3(S,6);
+		L2 ^= C4(S,6); L3 ^= C5(S,6); L4 ^= C6(S,6); L5 ^= C7(S,6);
+
+		L7 ^= C0(S,7); L0 ^= C1(S,7); L1 ^= C2(S,7); L2 ^= C3(S,7);
+		L3 ^= C4(S,7); L4 ^= C5(S,7); L5 ^= C6(S,7); L6 ^= C7(S,7);
+
+		S.q[0] = L0; S.q[1] = L1; S.q[2] = L2; S.q[3] = L3;
+		S.q[4] = L4; S.q[5] = L5; S.q[6] = L6; S.q[7] = L7;
+#endif
+		}
+
+#ifdef STRICT_ALIGNMENT
+	if ((size_t)p & 7)
+		{
+		int i;
+		for(i=0;i<64;i++)	H->c[i] ^= S.c[i] ^ p[i];
+		}
+	else
+#endif
+		{
+		const u64 *pa=(const u64 *)p;
+		H->q[0] ^= S.q[0] ^ pa[0];
+		H->q[1] ^= S.q[1] ^ pa[1];
+		H->q[2] ^= S.q[2] ^ pa[2];
+		H->q[3] ^= S.q[3] ^ pa[3];
+		H->q[4] ^= S.q[4] ^ pa[4];
+		H->q[5] ^= S.q[5] ^ pa[5];
+		H->q[6] ^= S.q[6] ^ pa[6];
+		H->q[7] ^= S.q[7] ^ pa[7];
+		}
+#endif
+							p += 64;
+							} while(--n);
+	}
diff --git a/openssl/crypto/whrlpool/wp_dgst.c b/openssl/crypto/whrlpool/wp_dgst.c
new file mode 100644
index 0000000..ee5c5c1
--- /dev/null
+++ b/openssl/crypto/whrlpool/wp_dgst.c
@@ -0,0 +1,264 @@
+/**
+ * The Whirlpool hashing function.
+ *
+ * <P>
+ * <b>References</b>
+ *
+ * <P>
+ * The Whirlpool algorithm was developed by
+ * <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and
+ * <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>.
+ *
+ * See
+ *      P.S.L.M. Barreto, V. Rijmen,
+ *      ``The Whirlpool hashing function,''
+ *      NESSIE submission, 2000 (tweaked version, 2001),
+ *      <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
+ *
+ * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and
+ * Vincent Rijmen. Lookup "reference implementations" on
+ * <http://planeta.terra.com.br/informatica/paulobarreto/>
+ *
+ * =============================================================================
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * OpenSSL-specific implementation notes.
+ *
+ * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect
+ * number of *bytes* as input length argument. Bit-oriented routine
+ * as specified by authors is called WHIRLPOOL_BitUpdate[!] and
+ * does not have one-stroke counterpart.
+ *
+ * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially
+ * to serve WHIRLPOOL_Update. This is done for performance.
+ *
+ * Unlike authors' reference implementation, block processing
+ * routine whirlpool_block is designed to operate on multi-block
+ * input. This is done for perfomance.
+ */
+
+#include "wp_locl.h"
+#include <string.h>
+
+int WHIRLPOOL_Init	(WHIRLPOOL_CTX *c)
+	{
+	memset (c,0,sizeof(*c));
+	return(1);
+	}
+
+int WHIRLPOOL_Update	(WHIRLPOOL_CTX *c,const void *_inp,size_t bytes)
+	{
+	/* Well, largest suitable chunk size actually is
+	 * (1<<(sizeof(size_t)*8-3))-64, but below number
+	 * is large enough for not to care about excessive
+	 * calls to WHIRLPOOL_BitUpdate... */
+	size_t chunk = ((size_t)1)<<(sizeof(size_t)*8-4);
+	const unsigned char *inp = _inp;
+
+	while (bytes>=chunk)
+		{
+		WHIRLPOOL_BitUpdate(c,inp,chunk*8);
+		bytes -= chunk;
+		inp   += chunk;
+		}
+	if (bytes)
+		WHIRLPOOL_BitUpdate(c,inp,bytes*8);
+
+	return(1);
+	}
+
+void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *_inp,size_t bits)
+	{
+	size_t		n;
+	unsigned int	bitoff = c->bitoff,
+			bitrem = bitoff%8,
+			inpgap = (8-(unsigned int)bits%8)&7;
+	const unsigned char *inp=_inp;
+
+	/* This 256-bit increment procedure relies on the size_t
+	 * being natural size of CPU register, so that we don't
+	 * have to mask the value in order to detect overflows. */
+	c->bitlen[0] += bits;
+	if (c->bitlen[0] < bits)	/* overflow */
+		{
+		n = 1;
+		do  { 	c->bitlen[n]++;
+		    } while(c->bitlen[n]==0
+		   	    && ++n<(WHIRLPOOL_COUNTER/sizeof(size_t)));
+		}
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	reconsider:
+	if (inpgap==0 && bitrem==0)	/* byte-oriented loop */
+		{
+		while (bits)
+			{
+			if (bitoff==0 && (n=bits/WHIRLPOOL_BBLOCK))
+				{
+				whirlpool_block(c,inp,n);
+				inp  += n*WHIRLPOOL_BBLOCK/8;
+				bits %= WHIRLPOOL_BBLOCK;
+				}
+			else
+				{
+				unsigned int byteoff = bitoff/8;
+
+				bitrem = WHIRLPOOL_BBLOCK - bitoff;/* re-use bitrem */
+				if (bits >= bitrem)
+					{
+					bits -= bitrem;
+					bitrem /= 8;
+					memcpy(c->data+byteoff,inp,bitrem);
+					inp  += bitrem;
+					whirlpool_block(c,c->data,1);
+					bitoff = 0;
+					}
+				else
+					{
+					memcpy(c->data+byteoff,inp,bits/8);
+					bitoff += (unsigned int)bits;
+					bits = 0;
+					}
+				c->bitoff = bitoff;
+				}
+			}
+		}
+	else				/* bit-oriented loop */
+#endif
+		{
+		/*
+			   inp
+			   |
+			   +-------+-------+-------
+			      |||||||||||||||||||||
+			   +-------+-------+-------
+		+-------+-------+-------+-------+-------
+		||||||||||||||				c->data
+		+-------+-------+-------+-------+-------
+			|
+			c->bitoff/8
+		*/
+		while (bits)
+			{
+			unsigned int	byteoff	= bitoff/8;
+			unsigned char	b;
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+			if (bitrem==inpgap)
+				{
+				c->data[byteoff++] |= inp[0] & (0xff>>inpgap);
+				inpgap = 8-inpgap;
+				bitoff += inpgap;  bitrem = 0;	/* bitoff%8 */
+				bits   -= inpgap;  inpgap = 0;	/* bits%8   */
+				inp++;
+				if (bitoff==WHIRLPOOL_BBLOCK)
+					{
+					whirlpool_block(c,c->data,1);
+					bitoff = 0;
+					}
+				c->bitoff = bitoff;
+				goto reconsider;
+				}
+			else
+#endif
+			if (bits>=8)
+				{
+				b  = ((inp[0]<<inpgap) | (inp[1]>>(8-inpgap)));
+				b &= 0xff;
+				if (bitrem)	c->data[byteoff++] |= b>>bitrem;
+				else		c->data[byteoff++]  = b;
+				bitoff += 8;
+				bits   -= 8;
+				inp++;
+				if (bitoff>=WHIRLPOOL_BBLOCK)
+					{
+					whirlpool_block(c,c->data,1);
+					byteoff  = 0;
+					bitoff  %= WHIRLPOOL_BBLOCK;
+					}
+				if (bitrem)	c->data[byteoff] = b<<(8-bitrem);
+				}
+			else	/* remaining less than 8 bits */
+				{
+				b = (inp[0]<<inpgap)&0xff;
+				if (bitrem)	c->data[byteoff++] |= b>>bitrem;
+				else		c->data[byteoff++]  = b;
+				bitoff += (unsigned int)bits;
+				if (bitoff==WHIRLPOOL_BBLOCK)
+					{
+					whirlpool_block(c,c->data,1);
+					byteoff  = 0;
+			        	bitoff  %= WHIRLPOOL_BBLOCK;
+					}
+				if (bitrem)	c->data[byteoff] = b<<(8-bitrem);
+				bits = 0;
+				}
+			c->bitoff = bitoff;
+			}
+		}
+	}
+
+int WHIRLPOOL_Final	(unsigned char *md,WHIRLPOOL_CTX *c)
+	{
+	unsigned int	bitoff  = c->bitoff,
+			byteoff = bitoff/8;
+	size_t		i,j,v;
+	unsigned char  *p;
+
+	bitoff %= 8;
+	if (bitoff)	c->data[byteoff] |= 0x80>>bitoff;
+	else		c->data[byteoff]  = 0x80;
+	byteoff++;
+
+	/* pad with zeros */
+	if (byteoff > (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER))
+		{
+		if (byteoff<WHIRLPOOL_BBLOCK/8)
+			memset(&c->data[byteoff],0,WHIRLPOOL_BBLOCK/8-byteoff);
+		whirlpool_block(c,c->data,1);
+		byteoff = 0;
+		}
+	if (byteoff < (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER))
+		memset(&c->data[byteoff],0,
+			(WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER)-byteoff);
+	/* smash 256-bit c->bitlen in big-endian order */
+	p = &c->data[WHIRLPOOL_BBLOCK/8-1];	/* last byte in c->data */
+	for(i=0;i<WHIRLPOOL_COUNTER/sizeof(size_t);i++)
+		for(v=c->bitlen[i],j=0;j<sizeof(size_t);j++,v>>=8)
+			*p-- = (unsigned char)(v&0xff);
+
+	whirlpool_block(c,c->data,1);
+
+	if (md)	{
+		memcpy(md,c->H.c,WHIRLPOOL_DIGEST_LENGTH);
+		memset(c,0,sizeof(*c));
+		return(1);
+		}
+	return(0);
+	}
+
+unsigned char *WHIRLPOOL(const void *inp, size_t bytes,unsigned char *md)
+	{
+	WHIRLPOOL_CTX ctx;
+	static unsigned char m[WHIRLPOOL_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	WHIRLPOOL_Init(&ctx);
+	WHIRLPOOL_Update(&ctx,inp,bytes);
+	WHIRLPOOL_Final(md,&ctx);
+	return(md);
+	}
diff --git a/openssl/crypto/whrlpool/wp_locl.h b/openssl/crypto/whrlpool/wp_locl.h
new file mode 100644
index 0000000..94e56a3
--- /dev/null
+++ b/openssl/crypto/whrlpool/wp_locl.h
@@ -0,0 +1,3 @@
+#include <openssl/whrlpool.h>
+
+void whirlpool_block(WHIRLPOOL_CTX *,const void *,size_t);
diff --git a/openssl/crypto/whrlpool/wp_test.c b/openssl/crypto/whrlpool/wp_test.c
new file mode 100644
index 0000000..c68c2c6
--- /dev/null
+++ b/openssl/crypto/whrlpool/wp_test.c
@@ -0,0 +1,228 @@
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project.  All rights reserved.
+ * ====================================================================
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <openssl/whrlpool.h>
+#include <openssl/crypto.h>
+
+#if defined(OPENSSL_NO_WHIRLPOOL)
+int main(int argc, char *argv[])
+{
+    printf("No Whirlpool support\n");
+    return(0);
+}
+#else
+
+/* ISO/IEC 10118-3 test vector set */
+unsigned char iso_test_1[WHIRLPOOL_DIGEST_LENGTH] = {
+	0x19,0xFA,0x61,0xD7,0x55,0x22,0xA4,0x66,
+	0x9B,0x44,0xE3,0x9C,0x1D,0x2E,0x17,0x26,
+	0xC5,0x30,0x23,0x21,0x30,0xD4,0x07,0xF8,
+	0x9A,0xFE,0xE0,0x96,0x49,0x97,0xF7,0xA7,
+	0x3E,0x83,0xBE,0x69,0x8B,0x28,0x8F,0xEB,
+	0xCF,0x88,0xE3,0xE0,0x3C,0x4F,0x07,0x57,
+	0xEA,0x89,0x64,0xE5,0x9B,0x63,0xD9,0x37,
+	0x08,0xB1,0x38,0xCC,0x42,0xA6,0x6E,0xB3 };
+
+unsigned char iso_test_2[WHIRLPOOL_DIGEST_LENGTH] = {
+	0x8A,0xCA,0x26,0x02,0x79,0x2A,0xEC,0x6F,
+	0x11,0xA6,0x72,0x06,0x53,0x1F,0xB7,0xD7,
+	0xF0,0xDF,0xF5,0x94,0x13,0x14,0x5E,0x69,
+	0x73,0xC4,0x50,0x01,0xD0,0x08,0x7B,0x42,
+	0xD1,0x1B,0xC6,0x45,0x41,0x3A,0xEF,0xF6,
+	0x3A,0x42,0x39,0x1A,0x39,0x14,0x5A,0x59,
+	0x1A,0x92,0x20,0x0D,0x56,0x01,0x95,0xE5,
+	0x3B,0x47,0x85,0x84,0xFD,0xAE,0x23,0x1A };
+
+unsigned char iso_test_3[WHIRLPOOL_DIGEST_LENGTH] = {
+	0x4E,0x24,0x48,0xA4,0xC6,0xF4,0x86,0xBB,
+	0x16,0xB6,0x56,0x2C,0x73,0xB4,0x02,0x0B,
+	0xF3,0x04,0x3E,0x3A,0x73,0x1B,0xCE,0x72,
+	0x1A,0xE1,0xB3,0x03,0xD9,0x7E,0x6D,0x4C,
+	0x71,0x81,0xEE,0xBD,0xB6,0xC5,0x7E,0x27,
+	0x7D,0x0E,0x34,0x95,0x71,0x14,0xCB,0xD6,
+	0xC7,0x97,0xFC,0x9D,0x95,0xD8,0xB5,0x82,
+	0xD2,0x25,0x29,0x20,0x76,0xD4,0xEE,0xF5 };
+
+unsigned char iso_test_4[WHIRLPOOL_DIGEST_LENGTH] = {
+	0x37,0x8C,0x84,0xA4,0x12,0x6E,0x2D,0xC6,
+	0xE5,0x6D,0xCC,0x74,0x58,0x37,0x7A,0xAC,
+	0x83,0x8D,0x00,0x03,0x22,0x30,0xF5,0x3C,
+	0xE1,0xF5,0x70,0x0C,0x0F,0xFB,0x4D,0x3B,
+	0x84,0x21,0x55,0x76,0x59,0xEF,0x55,0xC1,
+	0x06,0xB4,0xB5,0x2A,0xC5,0xA4,0xAA,0xA6,
+	0x92,0xED,0x92,0x00,0x52,0x83,0x8F,0x33,
+	0x62,0xE8,0x6D,0xBD,0x37,0xA8,0x90,0x3E };
+
+unsigned char iso_test_5[WHIRLPOOL_DIGEST_LENGTH] = {
+	0xF1,0xD7,0x54,0x66,0x26,0x36,0xFF,0xE9,
+	0x2C,0x82,0xEB,0xB9,0x21,0x2A,0x48,0x4A,
+	0x8D,0x38,0x63,0x1E,0xAD,0x42,0x38,0xF5,
+	0x44,0x2E,0xE1,0x3B,0x80,0x54,0xE4,0x1B,
+	0x08,0xBF,0x2A,0x92,0x51,0xC3,0x0B,0x6A,
+	0x0B,0x8A,0xAE,0x86,0x17,0x7A,0xB4,0xA6,
+	0xF6,0x8F,0x67,0x3E,0x72,0x07,0x86,0x5D,
+	0x5D,0x98,0x19,0xA3,0xDB,0xA4,0xEB,0x3B };
+
+unsigned char iso_test_6[WHIRLPOOL_DIGEST_LENGTH] = {
+	0xDC,0x37,0xE0,0x08,0xCF,0x9E,0xE6,0x9B,
+	0xF1,0x1F,0x00,0xED,0x9A,0xBA,0x26,0x90,
+	0x1D,0xD7,0xC2,0x8C,0xDE,0xC0,0x66,0xCC,
+	0x6A,0xF4,0x2E,0x40,0xF8,0x2F,0x3A,0x1E,
+	0x08,0xEB,0xA2,0x66,0x29,0x12,0x9D,0x8F,
+	0xB7,0xCB,0x57,0x21,0x1B,0x92,0x81,0xA6,
+	0x55,0x17,0xCC,0x87,0x9D,0x7B,0x96,0x21,
+	0x42,0xC6,0x5F,0x5A,0x7A,0xF0,0x14,0x67 };
+
+unsigned char iso_test_7[WHIRLPOOL_DIGEST_LENGTH] = {
+	0x46,0x6E,0xF1,0x8B,0xAB,0xB0,0x15,0x4D,
+	0x25,0xB9,0xD3,0x8A,0x64,0x14,0xF5,0xC0,
+	0x87,0x84,0x37,0x2B,0xCC,0xB2,0x04,0xD6,
+	0x54,0x9C,0x4A,0xFA,0xDB,0x60,0x14,0x29,
+	0x4D,0x5B,0xD8,0xDF,0x2A,0x6C,0x44,0xE5,
+	0x38,0xCD,0x04,0x7B,0x26,0x81,0xA5,0x1A,
+	0x2C,0x60,0x48,0x1E,0x88,0xC5,0xA2,0x0B,
+	0x2C,0x2A,0x80,0xCF,0x3A,0x9A,0x08,0x3B };
+
+unsigned char iso_test_8[WHIRLPOOL_DIGEST_LENGTH] = {
+	0x2A,0x98,0x7E,0xA4,0x0F,0x91,0x70,0x61,
+	0xF5,0xD6,0xF0,0xA0,0xE4,0x64,0x4F,0x48,
+	0x8A,0x7A,0x5A,0x52,0xDE,0xEE,0x65,0x62,
+	0x07,0xC5,0x62,0xF9,0x88,0xE9,0x5C,0x69,
+	0x16,0xBD,0xC8,0x03,0x1B,0xC5,0xBE,0x1B,
+	0x7B,0x94,0x76,0x39,0xFE,0x05,0x0B,0x56,
+	0x93,0x9B,0xAA,0xA0,0xAD,0xFF,0x9A,0xE6,
+	0x74,0x5B,0x7B,0x18,0x1C,0x3B,0xE3,0xFD };
+
+unsigned char iso_test_9[WHIRLPOOL_DIGEST_LENGTH] = {
+	0x0C,0x99,0x00,0x5B,0xEB,0x57,0xEF,0xF5,
+	0x0A,0x7C,0xF0,0x05,0x56,0x0D,0xDF,0x5D,
+	0x29,0x05,0x7F,0xD8,0x6B,0x20,0xBF,0xD6,
+	0x2D,0xEC,0xA0,0xF1,0xCC,0xEA,0x4A,0xF5,
+	0x1F,0xC1,0x54,0x90,0xED,0xDC,0x47,0xAF,
+	0x32,0xBB,0x2B,0x66,0xC3,0x4F,0xF9,0xAD,
+	0x8C,0x60,0x08,0xAD,0x67,0x7F,0x77,0x12,
+	0x69,0x53,0xB2,0x26,0xE4,0xED,0x8B,0x01 };
+
+int main (int argc,char *argv[])
+{ unsigned char md[WHIRLPOOL_DIGEST_LENGTH];
+  int		i;
+  WHIRLPOOL_CTX	ctx;
+
+#ifdef OPENSSL_IA32_SSE2
+    /* Alternative to this is to call OpenSSL_add_all_algorithms...
+     * The below code is retained exclusively for debugging purposes. */
+    { char      *env;
+
+	if ((env=getenv("OPENSSL_ia32cap")))
+	    OPENSSL_ia32cap = strtoul (env,NULL,0);
+    }
+#endif
+
+    fprintf(stdout,"Testing Whirlpool ");
+
+    WHIRLPOOL("",0,md);
+    if (memcmp(md,iso_test_1,sizeof(iso_test_1)))
+    {   fflush(stdout);
+	fprintf(stderr,"\nTEST 1 of 9 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    WHIRLPOOL("a",1,md);
+    if (memcmp(md,iso_test_2,sizeof(iso_test_2)))
+    {   fflush(stdout);
+	fprintf(stderr,"\nTEST 2 of 9 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    WHIRLPOOL("abc",3,md);
+    if (memcmp(md,iso_test_3,sizeof(iso_test_3)))
+    {   fflush(stdout);
+	fprintf(stderr,"\nTEST 3 of 9 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    WHIRLPOOL("message digest",14,md);
+    if (memcmp(md,iso_test_4,sizeof(iso_test_4)))
+    {   fflush(stdout);
+	fprintf(stderr,"\nTEST 4 of 9 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    WHIRLPOOL("abcdefghijklmnopqrstuvwxyz",26,md);
+    if (memcmp(md,iso_test_5,sizeof(iso_test_5)))
+    {   fflush(stdout);
+	fprintf(stderr,"\nTEST 5 of 9 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    WHIRLPOOL(	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+		"abcdefghijklmnopqrstuvwxyz"
+		"0123456789",62,md);
+    if (memcmp(md,iso_test_6,sizeof(iso_test_6)))
+    {   fflush(stdout);
+	fprintf(stderr,"\nTEST 6 of 9 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    WHIRLPOOL(	"1234567890""1234567890""1234567890""1234567890"
+		"1234567890""1234567890""1234567890""1234567890",80,md);
+    if (memcmp(md,iso_test_7,sizeof(iso_test_7)))
+    {   fflush(stdout);
+	fprintf(stderr,"\nTEST 7 of 9 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    WHIRLPOOL("abcdbcdecdefdefgefghfghighijhijk",32,md);
+    if (memcmp(md,iso_test_8,sizeof(iso_test_8)))
+    {   fflush(stdout);
+	fprintf(stderr,"\nTEST 8 of 9 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+ 
+    WHIRLPOOL_Init (&ctx);
+    for (i=0;i<1000000;i+=288)
+	WHIRLPOOL_Update (&ctx,	"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
+				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
+				(1000000-i)<288?1000000-i:288);
+    WHIRLPOOL_Final (md,&ctx);
+    if (memcmp(md,iso_test_9,sizeof(iso_test_9)))
+    {   fflush(stdout);
+	fprintf(stderr,"\nTEST 9 of 9 failed.\n");
+	return 1;
+    }
+    else
+	fprintf(stdout,"."); fflush(stdout);
+
+    fprintf(stdout," passed.\n"); fflush(stdout);
+
+  return 0;
+}
+#endif
diff --git a/openssl/crypto/x509/Makefile b/openssl/crypto/x509/Makefile
new file mode 100644
index 0000000..72c8227
--- /dev/null
+++ b/openssl/crypto/x509/Makefile
@@ -0,0 +1,407 @@
+#
+# OpenSSL/crypto/x509/Makefile
+#
+
+DIR=	x509
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile README
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=	x509_def.c x509_d2.c x509_r2x.c x509_cmp.c \
+	x509_obj.c x509_req.c x509spki.c x509_vfy.c \
+	x509_set.c x509cset.c x509rset.c x509_err.c \
+	x509name.c x509_v3.c x509_ext.c x509_att.c \
+	x509type.c x509_lu.c x_all.c x509_txt.c \
+	x509_trs.c by_file.c by_dir.c x509_vpm.c
+LIBOBJ= x509_def.o x509_d2.o x509_r2x.o x509_cmp.o \
+	x509_obj.o x509_req.o x509spki.o x509_vfy.o \
+	x509_set.o x509cset.o x509rset.o x509_err.o \
+	x509name.o x509_v3.o x509_ext.o x509_att.o \
+	x509type.o x509_lu.o x_all.o x509_txt.o \
+	x509_trs.o by_file.o by_dir.o x509_vpm.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= x509.h x509_vfy.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+by_dir.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+by_dir.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+by_dir.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+by_dir.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+by_dir.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+by_dir.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+by_dir.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+by_dir.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+by_dir.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+by_dir.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+by_dir.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+by_dir.o: ../../include/openssl/x509_vfy.h ../cryptlib.h by_dir.c
+by_file.o: ../../e_os.h ../../include/openssl/asn1.h
+by_file.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+by_file.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+by_file.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+by_file.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+by_file.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+by_file.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+by_file.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+by_file.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
+by_file.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
+by_file.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+by_file.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+by_file.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+by_file.o: ../cryptlib.h by_file.c
+x509_att.o: ../../e_os.h ../../include/openssl/asn1.h
+x509_att.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509_att.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+x509_att.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x509_att.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x509_att.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x509_att.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509_att.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_att.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509_att.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509_att.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_att.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509_att.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+x509_att.o: ../cryptlib.h x509_att.c
+x509_cmp.o: ../../e_os.h ../../include/openssl/asn1.h
+x509_cmp.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509_cmp.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+x509_cmp.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x509_cmp.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x509_cmp.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x509_cmp.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509_cmp.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_cmp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509_cmp.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509_cmp.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_cmp.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509_cmp.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+x509_cmp.o: ../cryptlib.h x509_cmp.c
+x509_d2.o: ../../e_os.h ../../include/openssl/asn1.h
+x509_d2.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509_d2.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x509_d2.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x509_d2.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+x509_d2.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+x509_d2.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509_d2.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x509_d2.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+x509_d2.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x509_d2.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x509_d2.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x509_d2.o: ../cryptlib.h x509_d2.c
+x509_def.o: ../../e_os.h ../../include/openssl/asn1.h
+x509_def.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509_def.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x509_def.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x509_def.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+x509_def.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+x509_def.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509_def.o: ../../include/openssl/opensslconf.h
+x509_def.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509_def.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509_def.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_def.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509_def.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_def.c
+x509_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+x509_err.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+x509_err.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x509_err.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x509_err.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x509_err.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509_err.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509_err.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_err.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509_err.o: ../../include/openssl/x509_vfy.h x509_err.c
+x509_ext.o: ../../e_os.h ../../include/openssl/asn1.h
+x509_ext.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509_ext.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+x509_ext.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x509_ext.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x509_ext.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x509_ext.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509_ext.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_ext.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509_ext.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509_ext.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_ext.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509_ext.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+x509_ext.o: ../cryptlib.h x509_ext.c
+x509_lu.o: ../../e_os.h ../../include/openssl/asn1.h
+x509_lu.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509_lu.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+x509_lu.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x509_lu.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x509_lu.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x509_lu.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509_lu.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_lu.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509_lu.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509_lu.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_lu.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509_lu.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+x509_lu.o: ../cryptlib.h x509_lu.c
+x509_obj.o: ../../e_os.h ../../include/openssl/asn1.h
+x509_obj.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509_obj.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x509_obj.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x509_obj.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+x509_obj.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+x509_obj.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509_obj.o: ../../include/openssl/opensslconf.h
+x509_obj.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509_obj.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509_obj.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_obj.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509_obj.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_obj.c
+x509_r2x.o: ../../e_os.h ../../include/openssl/asn1.h
+x509_r2x.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+x509_r2x.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+x509_r2x.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x509_r2x.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x509_r2x.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x509_r2x.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509_r2x.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_r2x.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509_r2x.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509_r2x.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_r2x.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509_r2x.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_r2x.c
+x509_req.o: ../../e_os.h ../../include/openssl/asn1.h
+x509_req.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+x509_req.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+x509_req.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x509_req.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x509_req.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+x509_req.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+x509_req.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509_req.o: ../../include/openssl/opensslconf.h
+x509_req.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509_req.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+x509_req.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509_req.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_req.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509_req.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_req.c
+x509_set.o: ../../e_os.h ../../include/openssl/asn1.h
+x509_set.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509_set.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x509_set.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x509_set.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+x509_set.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+x509_set.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509_set.o: ../../include/openssl/opensslconf.h
+x509_set.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509_set.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509_set.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_set.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509_set.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_set.c
+x509_trs.o: ../../e_os.h ../../include/openssl/asn1.h
+x509_trs.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509_trs.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+x509_trs.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x509_trs.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x509_trs.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x509_trs.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509_trs.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_trs.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509_trs.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509_trs.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_trs.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509_trs.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+x509_trs.o: ../cryptlib.h x509_trs.c
+x509_txt.o: ../../e_os.h ../../include/openssl/asn1.h
+x509_txt.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509_txt.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x509_txt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x509_txt.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+x509_txt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+x509_txt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509_txt.o: ../../include/openssl/opensslconf.h
+x509_txt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509_txt.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509_txt.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_txt.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509_txt.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_txt.c
+x509_v3.o: ../../e_os.h ../../include/openssl/asn1.h
+x509_v3.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509_v3.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+x509_v3.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x509_v3.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x509_v3.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x509_v3.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509_v3.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_v3.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509_v3.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509_v3.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_v3.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509_v3.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+x509_v3.o: ../cryptlib.h x509_v3.c
+x509_vfy.o: ../../e_os.h ../../include/openssl/asn1.h
+x509_vfy.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509_vfy.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+x509_vfy.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x509_vfy.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x509_vfy.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x509_vfy.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509_vfy.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_vfy.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509_vfy.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509_vfy.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_vfy.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509_vfy.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+x509_vfy.o: ../cryptlib.h x509_vfy.c
+x509_vpm.o: ../../e_os.h ../../include/openssl/asn1.h
+x509_vpm.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509_vpm.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+x509_vpm.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x509_vpm.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x509_vpm.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x509_vpm.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509_vpm.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_vpm.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509_vpm.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509_vpm.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_vpm.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509_vpm.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+x509_vpm.o: ../cryptlib.h x509_vpm.c
+x509cset.o: ../../e_os.h ../../include/openssl/asn1.h
+x509cset.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509cset.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x509cset.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x509cset.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+x509cset.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+x509cset.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509cset.o: ../../include/openssl/opensslconf.h
+x509cset.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509cset.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509cset.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509cset.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509cset.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509cset.c
+x509name.o: ../../e_os.h ../../include/openssl/asn1.h
+x509name.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509name.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x509name.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x509name.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+x509name.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+x509name.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509name.o: ../../include/openssl/opensslconf.h
+x509name.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509name.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509name.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509name.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509name.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509name.c
+x509rset.o: ../../e_os.h ../../include/openssl/asn1.h
+x509rset.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509rset.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x509rset.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x509rset.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+x509rset.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+x509rset.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509rset.o: ../../include/openssl/opensslconf.h
+x509rset.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509rset.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509rset.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509rset.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509rset.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509rset.c
+x509spki.o: ../../e_os.h ../../include/openssl/asn1.h
+x509spki.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509spki.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x509spki.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x509spki.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+x509spki.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+x509spki.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509spki.o: ../../include/openssl/opensslconf.h
+x509spki.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509spki.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509spki.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509spki.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509spki.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509spki.c
+x509type.o: ../../e_os.h ../../include/openssl/asn1.h
+x509type.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509type.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+x509type.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x509type.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+x509type.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+x509type.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509type.o: ../../include/openssl/opensslconf.h
+x509type.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509type.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509type.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509type.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509type.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509type.c
+x_all.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+x_all.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+x_all.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+x_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+x_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+x_all.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+x_all.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+x_all.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+x_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x_all.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x_all.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_all.c
diff --git a/openssl/crypto/x509/by_dir.c b/openssl/crypto/x509/by_dir.c
new file mode 100644
index 0000000..03293ac
--- /dev/null
+++ b/openssl/crypto/x509/by_dir.c
@@ -0,0 +1,490 @@
+/* crypto/x509/by_dir.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include "cryptlib.h"
+
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifndef OPENSSL_NO_POSIX_IO
+# include <sys/stat.h>
+#endif
+
+#include <openssl/lhash.h>
+#include <openssl/x509.h>
+
+
+typedef struct lookup_dir_hashes_st
+	{
+	unsigned long hash;
+	int suffix;
+	} BY_DIR_HASH;
+
+typedef struct lookup_dir_entry_st
+	{
+	char *dir;
+	int dir_type;
+	STACK_OF(BY_DIR_HASH) *hashes;
+	} BY_DIR_ENTRY;
+
+typedef struct lookup_dir_st
+	{
+	BUF_MEM *buffer;
+	STACK_OF(BY_DIR_ENTRY) *dirs;
+	} BY_DIR;
+
+DECLARE_STACK_OF(BY_DIR_HASH)
+DECLARE_STACK_OF(BY_DIR_ENTRY)
+
+static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
+	char **ret);
+static int new_dir(X509_LOOKUP *lu);
+static void free_dir(X509_LOOKUP *lu);
+static int add_cert_dir(BY_DIR *ctx,const char *dir,int type);
+static int get_cert_by_subject(X509_LOOKUP *xl,int type,X509_NAME *name,
+	X509_OBJECT *ret);
+X509_LOOKUP_METHOD x509_dir_lookup=
+	{
+	"Load certs from files in a directory",
+	new_dir,		/* new */
+	free_dir,		/* free */
+	NULL, 			/* init */
+	NULL,			/* shutdown */
+	dir_ctrl,		/* ctrl */
+	get_cert_by_subject,	/* get_by_subject */
+	NULL,			/* get_by_issuer_serial */
+	NULL,			/* get_by_fingerprint */
+	NULL,			/* get_by_alias */
+	};
+
+X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void)
+	{
+	return(&x509_dir_lookup);
+	}
+
+static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
+	     char **retp)
+	{
+	int ret=0;
+	BY_DIR *ld;
+	char *dir = NULL;
+
+	ld=(BY_DIR *)ctx->method_data;
+
+	switch (cmd)
+		{
+	case X509_L_ADD_DIR:
+		if (argl == X509_FILETYPE_DEFAULT)
+			{
+			dir=(char *)getenv(X509_get_default_cert_dir_env());
+			if (dir)
+				ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM);
+			else
+				ret=add_cert_dir(ld,X509_get_default_cert_dir(),
+					X509_FILETYPE_PEM);
+			if (!ret)
+				{
+				X509err(X509_F_DIR_CTRL,X509_R_LOADING_CERT_DIR);
+				}
+			}
+		else
+			ret=add_cert_dir(ld,argp,(int)argl);
+		break;
+		}
+	return(ret);
+	}
+
+static int new_dir(X509_LOOKUP *lu)
+	{
+	BY_DIR *a;
+
+	if ((a=(BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL)
+		return(0);
+	if ((a->buffer=BUF_MEM_new()) == NULL)
+		{
+		OPENSSL_free(a);
+		return(0);
+		}
+	a->dirs=NULL;
+	lu->method_data=(char *)a;
+	return(1);
+	}
+
+static void by_dir_hash_free(BY_DIR_HASH *hash)
+	{
+	OPENSSL_free(hash);
+	}
+
+static int by_dir_hash_cmp(const BY_DIR_HASH * const *a,
+			const BY_DIR_HASH * const *b)
+	{
+	if ((*a)->hash > (*b)->hash)
+		return 1;
+	if ((*a)->hash < (*b)->hash)
+		return -1;
+	return 0;
+	}
+
+static void by_dir_entry_free(BY_DIR_ENTRY *ent)
+	{
+	if (ent->dir)
+		OPENSSL_free(ent->dir);
+	if (ent->hashes)
+		sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free);
+	OPENSSL_free(ent);
+	}
+
+static void free_dir(X509_LOOKUP *lu)
+	{
+	BY_DIR *a;
+
+	a=(BY_DIR *)lu->method_data;
+	if (a->dirs != NULL)
+		sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
+	if (a->buffer != NULL)
+		BUF_MEM_free(a->buffer);
+	OPENSSL_free(a);
+	}
+
+static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
+	{
+	int j,len;
+	const char *s,*ss,*p;
+
+	if (dir == NULL || !*dir)
+	    {
+	    X509err(X509_F_ADD_CERT_DIR,X509_R_INVALID_DIRECTORY);
+	    return 0;
+	    }
+
+	s=dir;
+	p=s;
+	for (;;p++)
+		{
+		if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0'))
+			{
+			BY_DIR_ENTRY *ent;
+			ss=s;
+			s=p+1;
+			len=(int)(p-ss);
+			if (len == 0) continue;
+			for (j=0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++)
+				{
+				ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j);
+				if (strlen(ent->dir) == (size_t)len &&
+				    strncmp(ent->dir,ss,(unsigned int)len) == 0)
+					break;
+				}
+			if (j < sk_BY_DIR_ENTRY_num(ctx->dirs))
+				continue;
+			if (ctx->dirs == NULL)
+				{
+				ctx->dirs = sk_BY_DIR_ENTRY_new_null();
+				if (!ctx->dirs)
+					{
+					X509err(X509_F_ADD_CERT_DIR,ERR_R_MALLOC_FAILURE);
+					return 0;
+					}
+				}
+			ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY));
+			if (!ent)
+				return 0;
+			ent->dir_type = type;
+			ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp);
+			ent->dir = OPENSSL_malloc((unsigned int)len+1);
+			if (!ent->dir || !ent->hashes)
+				{
+				by_dir_entry_free(ent);
+				return 0;
+				}
+			strncpy(ent->dir,ss,(unsigned int)len);
+			ent->dir[len] = '\0';
+			if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent))
+				{
+				by_dir_entry_free(ent);
+				return 0;
+				}
+			}
+		if (*p == '\0')
+			break;
+		}
+	return 1;
+	}
+
+static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
+	     X509_OBJECT *ret)
+	{
+	BY_DIR *ctx;
+	union	{
+		struct	{
+			X509 st_x509;
+			X509_CINF st_x509_cinf;
+			} x509;
+		struct	{
+			X509_CRL st_crl;
+			X509_CRL_INFO st_crl_info;
+			} crl;
+		} data;
+	int ok=0;
+	int i,j,k;
+	unsigned long h;
+	unsigned long hash_array[2];
+	int hash_index;
+	BUF_MEM *b=NULL;
+	X509_OBJECT stmp,*tmp;
+	const char *postfix="";
+
+	if (name == NULL) return(0);
+
+	stmp.type=type;
+	if (type == X509_LU_X509)
+		{
+		data.x509.st_x509.cert_info= &data.x509.st_x509_cinf;
+		data.x509.st_x509_cinf.subject=name;
+		stmp.data.x509= &data.x509.st_x509;
+		postfix="";
+		}
+	else if (type == X509_LU_CRL)
+		{
+		data.crl.st_crl.crl= &data.crl.st_crl_info;
+		data.crl.st_crl_info.issuer=name;
+		stmp.data.crl= &data.crl.st_crl;
+		postfix="r";
+		}
+	else
+		{
+		X509err(X509_F_GET_CERT_BY_SUBJECT,X509_R_WRONG_LOOKUP_TYPE);
+		goto finish;
+		}
+
+	if ((b=BUF_MEM_new()) == NULL)
+		{
+		X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_BUF_LIB);
+		goto finish;
+		}
+	
+	ctx=(BY_DIR *)xl->method_data;
+
+	h=X509_NAME_hash(name);
+	hash_array[0]=h;
+	hash_array[1]=X509_NAME_hash_old(name);
+	for (hash_index=0; hash_index < 2; hash_index++)
+		{
+		h=hash_array[hash_index];
+	for (i=0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++)
+		{
+		BY_DIR_ENTRY *ent;
+		int idx;
+		BY_DIR_HASH htmp, *hent;
+		ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i);
+		j=strlen(ent->dir)+1+8+6+1+1;
+		if (!BUF_MEM_grow(b,j))
+			{
+			X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_MALLOC_FAILURE);
+			goto finish;
+			}
+		if (type == X509_LU_CRL && ent->hashes)
+			{
+			htmp.hash = h;
+			CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE);
+			idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
+			if (idx >= 0)
+				{
+				hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
+				k = hent->suffix;
+				}
+			else
+				{
+				hent = NULL;
+				k=0;
+				}
+			CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
+			}
+		else
+			{
+			k = 0;
+			hent = NULL;
+			}
+		for (;;)
+			{
+			char c = '/';
+#ifdef OPENSSL_SYS_VMS
+			c = ent->dir[strlen(ent->dir)-1];
+			if (c != ':' && c != '>' && c != ']')
+				{
+				/* If no separator is present, we assume the
+				   directory specifier is a logical name, and
+				   add a colon.  We really should use better
+				   VMS routines for merging things like this,
+				   but this will do for now...
+				   -- Richard Levitte */
+				c = ':';
+				}
+			else
+				{
+				c = '\0';
+				}
+#endif
+			if (c == '\0')
+				{
+				/* This is special.  When c == '\0', no
+				   directory separator should be added. */
+				BIO_snprintf(b->data,b->max,
+					"%s%08lx.%s%d",ent->dir,h,
+					postfix,k);
+				}
+			else
+				{
+				BIO_snprintf(b->data,b->max,
+					"%s%c%08lx.%s%d",ent->dir,c,h,
+					postfix,k);
+				}
+#ifndef OPENSSL_NO_POSIX_IO
+#ifdef _WIN32
+#define stat _stat
+#endif
+			{
+			struct stat st;
+			if (stat(b->data,&st) < 0)
+				break;
+			}
+#endif
+			/* found one. */
+			if (type == X509_LU_X509)
+				{
+				if ((X509_load_cert_file(xl,b->data,
+					ent->dir_type)) == 0)
+					break;
+				}
+			else if (type == X509_LU_CRL)
+				{
+				if ((X509_load_crl_file(xl,b->data,
+					ent->dir_type)) == 0)
+					break;
+				}
+			/* else case will caught higher up */
+			k++;
+			}
+
+		/* we have added it to the cache so now pull
+		 * it out again */
+		CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+		j = sk_X509_OBJECT_find(xl->store_ctx->objs,&stmp);
+		if(j != -1) tmp=sk_X509_OBJECT_value(xl->store_ctx->objs,j);
+		else tmp = NULL;
+		CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+
+
+		/* If a CRL, update the last file suffix added for this */
+
+		if (type == X509_LU_CRL)
+			{
+			CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+			/* Look for entry again in case another thread added
+			 * an entry first.
+			 */
+			if (!hent)
+				{
+				htmp.hash = h;
+				idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
+				if (idx >= 0)
+					hent =
+					 sk_BY_DIR_HASH_value(ent->hashes, idx);
+				}
+			if (!hent)
+				{
+				hent = OPENSSL_malloc(sizeof(BY_DIR_HASH));
+				hent->hash = h;
+				hent->suffix = k;
+				if (!sk_BY_DIR_HASH_push(ent->hashes, hent))
+					{
+					CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+					OPENSSL_free(hent);
+					ok = 0;
+					goto finish;
+					}
+				}
+			else if (hent->suffix < k)
+				hent->suffix = k;
+
+			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+
+			}
+
+		if (tmp != NULL)
+			{
+			ok=1;
+			ret->type=tmp->type;
+			memcpy(&ret->data,&tmp->data,sizeof(ret->data));
+			/* If we were going to up the reference count,
+			 * we would need to do it on a perl 'type'
+			 * basis */
+	/*		CRYPTO_add(&tmp->data.x509->references,1,
+				CRYPTO_LOCK_X509);*/
+			goto finish;
+			}
+		}
+		}
+finish:
+	if (b != NULL) BUF_MEM_free(b);
+	return(ok);
+	}
diff --git a/openssl/crypto/x509/by_file.c b/openssl/crypto/x509/by_file.c
new file mode 100644
index 0000000..57b08ee
--- /dev/null
+++ b/openssl/crypto/x509/by_file.c
@@ -0,0 +1,300 @@
+/* crypto/x509/by_file.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/buffer.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+#ifndef OPENSSL_NO_STDIO
+
+static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
+	long argl, char **ret);
+X509_LOOKUP_METHOD x509_file_lookup=
+	{
+	"Load file into cache",
+	NULL,		/* new */
+	NULL,		/* free */
+	NULL, 		/* init */
+	NULL,		/* shutdown */
+	by_file_ctrl,	/* ctrl */
+	NULL,		/* get_by_subject */
+	NULL,		/* get_by_issuer_serial */
+	NULL,		/* get_by_fingerprint */
+	NULL,		/* get_by_alias */
+	};
+
+X509_LOOKUP_METHOD *X509_LOOKUP_file(void)
+	{
+	return(&x509_file_lookup);
+	}
+
+static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
+	     char **ret)
+	{
+	int ok=0;
+	char *file;
+
+	switch (cmd)
+		{
+	case X509_L_FILE_LOAD:
+		if (argl == X509_FILETYPE_DEFAULT)
+			{
+			file = (char *)getenv(X509_get_default_cert_file_env());
+			if (file)
+				ok = (X509_load_cert_crl_file(ctx,file,
+					      X509_FILETYPE_PEM) != 0);
+
+			else
+				ok = (X509_load_cert_crl_file(ctx,X509_get_default_cert_file(),
+					      X509_FILETYPE_PEM) != 0);
+
+			if (!ok)
+				{
+				X509err(X509_F_BY_FILE_CTRL,X509_R_LOADING_DEFAULTS);
+				}
+			}
+		else
+			{
+			if(argl == X509_FILETYPE_PEM)
+				ok = (X509_load_cert_crl_file(ctx,argp,
+					X509_FILETYPE_PEM) != 0);
+			else
+				ok = (X509_load_cert_file(ctx,argp,(int)argl) != 0);
+			}
+		break;
+		}
+	return(ok);
+	}
+
+int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
+	{
+	int ret=0;
+	BIO *in=NULL;
+	int i,count=0;
+	X509 *x=NULL;
+
+	if (file == NULL) return(1);
+	in=BIO_new(BIO_s_file_internal());
+
+	if ((in == NULL) || (BIO_read_filename(in,file) <= 0))
+		{
+		X509err(X509_F_X509_LOAD_CERT_FILE,ERR_R_SYS_LIB);
+		goto err;
+		}
+
+	if (type == X509_FILETYPE_PEM)
+		{
+		for (;;)
+			{
+			x=PEM_read_bio_X509_AUX(in,NULL,NULL,NULL);
+			if (x == NULL)
+				{
+				if ((ERR_GET_REASON(ERR_peek_last_error()) ==
+					PEM_R_NO_START_LINE) && (count > 0))
+					{
+					ERR_clear_error();
+					break;
+					}
+				else
+					{
+					X509err(X509_F_X509_LOAD_CERT_FILE,
+						ERR_R_PEM_LIB);
+					goto err;
+					}
+				}
+			i=X509_STORE_add_cert(ctx->store_ctx,x);
+			if (!i) goto err;
+			count++;
+			X509_free(x);
+			x=NULL;
+			}
+		ret=count;
+		}
+	else if (type == X509_FILETYPE_ASN1)
+		{
+		x=d2i_X509_bio(in,NULL);
+		if (x == NULL)
+			{
+			X509err(X509_F_X509_LOAD_CERT_FILE,ERR_R_ASN1_LIB);
+			goto err;
+			}
+		i=X509_STORE_add_cert(ctx->store_ctx,x);
+		if (!i) goto err;
+		ret=i;
+		}
+	else
+		{
+		X509err(X509_F_X509_LOAD_CERT_FILE,X509_R_BAD_X509_FILETYPE);
+		goto err;
+		}
+err:
+	if (x != NULL) X509_free(x);
+	if (in != NULL) BIO_free(in);
+	return(ret);
+	}
+
+int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
+	{
+	int ret=0;
+	BIO *in=NULL;
+	int i,count=0;
+	X509_CRL *x=NULL;
+
+	if (file == NULL) return(1);
+	in=BIO_new(BIO_s_file_internal());
+
+	if ((in == NULL) || (BIO_read_filename(in,file) <= 0))
+		{
+		X509err(X509_F_X509_LOAD_CRL_FILE,ERR_R_SYS_LIB);
+		goto err;
+		}
+
+	if (type == X509_FILETYPE_PEM)
+		{
+		for (;;)
+			{
+			x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
+			if (x == NULL)
+				{
+				if ((ERR_GET_REASON(ERR_peek_last_error()) ==
+					PEM_R_NO_START_LINE) && (count > 0))
+					{
+					ERR_clear_error();
+					break;
+					}
+				else
+					{
+					X509err(X509_F_X509_LOAD_CRL_FILE,
+						ERR_R_PEM_LIB);
+					goto err;
+					}
+				}
+			i=X509_STORE_add_crl(ctx->store_ctx,x);
+			if (!i) goto err;
+			count++;
+			X509_CRL_free(x);
+			x=NULL;
+			}
+		ret=count;
+		}
+	else if (type == X509_FILETYPE_ASN1)
+		{
+		x=d2i_X509_CRL_bio(in,NULL);
+		if (x == NULL)
+			{
+			X509err(X509_F_X509_LOAD_CRL_FILE,ERR_R_ASN1_LIB);
+			goto err;
+			}
+		i=X509_STORE_add_crl(ctx->store_ctx,x);
+		if (!i) goto err;
+		ret=i;
+		}
+	else
+		{
+		X509err(X509_F_X509_LOAD_CRL_FILE,X509_R_BAD_X509_FILETYPE);
+		goto err;
+		}
+err:
+	if (x != NULL) X509_CRL_free(x);
+	if (in != NULL) BIO_free(in);
+	return(ret);
+	}
+
+int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
+{
+	STACK_OF(X509_INFO) *inf;
+	X509_INFO *itmp;
+	BIO *in;
+	int i, count = 0;
+	if(type != X509_FILETYPE_PEM)
+		return X509_load_cert_file(ctx, file, type);
+	in = BIO_new_file(file, "r");
+	if(!in) {
+		X509err(X509_F_X509_LOAD_CERT_CRL_FILE,ERR_R_SYS_LIB);
+		return 0;
+	}
+	inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
+	BIO_free(in);
+	if(!inf) {
+		X509err(X509_F_X509_LOAD_CERT_CRL_FILE,ERR_R_PEM_LIB);
+		return 0;
+	}
+	for(i = 0; i < sk_X509_INFO_num(inf); i++) {
+		itmp = sk_X509_INFO_value(inf, i);
+		if(itmp->x509) {
+			X509_STORE_add_cert(ctx->store_ctx, itmp->x509);
+			count++;
+		}
+		if(itmp->crl) {
+			X509_STORE_add_crl(ctx->store_ctx, itmp->crl);
+			count++;
+		}
+	}
+	sk_X509_INFO_pop_free(inf, X509_INFO_free);
+	return count;
+}
+
+
+#endif /* OPENSSL_NO_STDIO */
+
diff --git a/openssl/crypto/x509/x509.h b/openssl/crypto/x509/x509.h
new file mode 100644
index 0000000..e6f8a40
--- /dev/null
+++ b/openssl/crypto/x509/x509.h
@@ -0,0 +1,1286 @@
+/* crypto/x509/x509.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_X509_H
+#define HEADER_X509_H
+
+#include <openssl/e_os2.h>
+#include <openssl/symhacks.h>
+#ifndef OPENSSL_NO_BUFFER
+#include <openssl/buffer.h>
+#endif
+#ifndef OPENSSL_NO_EVP
+#include <openssl/evp.h>
+#endif
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#include <openssl/stack.h>
+#include <openssl/asn1.h>
+#include <openssl/safestack.h>
+
+#ifndef OPENSSL_NO_EC
+#include <openssl/ec.h>
+#endif
+
+#ifndef OPENSSL_NO_ECDSA
+#include <openssl/ecdsa.h>
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+#include <openssl/ecdh.h>
+#endif
+
+#ifndef OPENSSL_NO_DEPRECATED
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#endif
+
+#ifndef OPENSSL_NO_SHA
+#include <openssl/sha.h>
+#endif
+#include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_SYS_WIN32
+/* Under Win32 these are defined in wincrypt.h */
+#undef X509_NAME
+#undef X509_CERT_PAIR
+#undef X509_EXTENSIONS
+#endif
+
+#define X509_FILETYPE_PEM	1
+#define X509_FILETYPE_ASN1	2
+#define X509_FILETYPE_DEFAULT	3
+
+#define X509v3_KU_DIGITAL_SIGNATURE	0x0080
+#define X509v3_KU_NON_REPUDIATION	0x0040
+#define X509v3_KU_KEY_ENCIPHERMENT	0x0020
+#define X509v3_KU_DATA_ENCIPHERMENT	0x0010
+#define X509v3_KU_KEY_AGREEMENT		0x0008
+#define X509v3_KU_KEY_CERT_SIGN		0x0004
+#define X509v3_KU_CRL_SIGN		0x0002
+#define X509v3_KU_ENCIPHER_ONLY		0x0001
+#define X509v3_KU_DECIPHER_ONLY		0x8000
+#define X509v3_KU_UNDEF			0xffff
+
+typedef struct X509_objects_st
+	{
+	int nid;
+	int (*a2i)(void);
+	int (*i2a)(void);
+	} X509_OBJECTS;
+
+struct X509_algor_st
+	{
+	ASN1_OBJECT *algorithm;
+	ASN1_TYPE *parameter;
+	} /* X509_ALGOR */;
+
+DECLARE_ASN1_SET_OF(X509_ALGOR)
+
+typedef STACK_OF(X509_ALGOR) X509_ALGORS;
+
+typedef struct X509_val_st
+	{
+	ASN1_TIME *notBefore;
+	ASN1_TIME *notAfter;
+	} X509_VAL;
+
+struct X509_pubkey_st
+	{
+	X509_ALGOR *algor;
+	ASN1_BIT_STRING *public_key;
+	EVP_PKEY *pkey;
+	};
+
+typedef struct X509_sig_st
+	{
+	X509_ALGOR *algor;
+	ASN1_OCTET_STRING *digest;
+	} X509_SIG;
+
+typedef struct X509_name_entry_st
+	{
+	ASN1_OBJECT *object;
+	ASN1_STRING *value;
+	int set;
+	int size; 	/* temp variable */
+	} X509_NAME_ENTRY;
+
+DECLARE_STACK_OF(X509_NAME_ENTRY)
+DECLARE_ASN1_SET_OF(X509_NAME_ENTRY)
+
+/* we always keep X509_NAMEs in 2 forms. */
+struct X509_name_st
+	{
+	STACK_OF(X509_NAME_ENTRY) *entries;
+	int modified;	/* true if 'bytes' needs to be built */
+#ifndef OPENSSL_NO_BUFFER
+	BUF_MEM *bytes;
+#else
+	char *bytes;
+#endif
+/*	unsigned long hash; Keep the hash around for lookups */
+	unsigned char *canon_enc;
+	int canon_enclen;
+	} /* X509_NAME */;
+
+DECLARE_STACK_OF(X509_NAME)
+
+#define X509_EX_V_NETSCAPE_HACK		0x8000
+#define X509_EX_V_INIT			0x0001
+typedef struct X509_extension_st
+	{
+	ASN1_OBJECT *object;
+	ASN1_BOOLEAN critical;
+	ASN1_OCTET_STRING *value;
+	} X509_EXTENSION;
+
+typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS;
+
+DECLARE_STACK_OF(X509_EXTENSION)
+DECLARE_ASN1_SET_OF(X509_EXTENSION)
+
+/* a sequence of these are used */
+typedef struct x509_attributes_st
+	{
+	ASN1_OBJECT *object;
+	int single; /* 0 for a set, 1 for a single item (which is wrong) */
+	union	{
+		char		*ptr;
+/* 0 */		STACK_OF(ASN1_TYPE) *set;
+/* 1 */		ASN1_TYPE	*single;
+		} value;
+	} X509_ATTRIBUTE;
+
+DECLARE_STACK_OF(X509_ATTRIBUTE)
+DECLARE_ASN1_SET_OF(X509_ATTRIBUTE)
+
+
+typedef struct X509_req_info_st
+	{
+	ASN1_ENCODING enc;
+	ASN1_INTEGER *version;
+	X509_NAME *subject;
+	X509_PUBKEY *pubkey;
+	/*  d=2 hl=2 l=  0 cons: cont: 00 */
+	STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+	} X509_REQ_INFO;
+
+typedef struct X509_req_st
+	{
+	X509_REQ_INFO *req_info;
+	X509_ALGOR *sig_alg;
+	ASN1_BIT_STRING *signature;
+	int references;
+	} X509_REQ;
+
+typedef struct x509_cinf_st
+	{
+	ASN1_INTEGER *version;		/* [ 0 ] default of v1 */
+	ASN1_INTEGER *serialNumber;
+	X509_ALGOR *signature;
+	X509_NAME *issuer;
+	X509_VAL *validity;
+	X509_NAME *subject;
+	X509_PUBKEY *key;
+	ASN1_BIT_STRING *issuerUID;		/* [ 1 ] optional in v2 */
+	ASN1_BIT_STRING *subjectUID;		/* [ 2 ] optional in v2 */
+	STACK_OF(X509_EXTENSION) *extensions;	/* [ 3 ] optional in v3 */
+	ASN1_ENCODING enc;
+	} X509_CINF;
+
+/* This stuff is certificate "auxiliary info"
+ * it contains details which are useful in certificate
+ * stores and databases. When used this is tagged onto
+ * the end of the certificate itself
+ */
+
+typedef struct x509_cert_aux_st
+	{
+	STACK_OF(ASN1_OBJECT) *trust;		/* trusted uses */
+	STACK_OF(ASN1_OBJECT) *reject;		/* rejected uses */
+	ASN1_UTF8STRING *alias;			/* "friendly name" */
+	ASN1_OCTET_STRING *keyid;		/* key id of private key */
+	STACK_OF(X509_ALGOR) *other;		/* other unspecified info */
+	} X509_CERT_AUX;
+
+struct x509_st
+	{
+	X509_CINF *cert_info;
+	X509_ALGOR *sig_alg;
+	ASN1_BIT_STRING *signature;
+	int valid;
+	int references;
+	char *name;
+	CRYPTO_EX_DATA ex_data;
+	/* These contain copies of various extension values */
+	long ex_pathlen;
+	long ex_pcpathlen;
+	unsigned long ex_flags;
+	unsigned long ex_kusage;
+	unsigned long ex_xkusage;
+	unsigned long ex_nscert;
+	ASN1_OCTET_STRING *skid;
+	AUTHORITY_KEYID *akid;
+	X509_POLICY_CACHE *policy_cache;
+	STACK_OF(DIST_POINT) *crldp;
+	STACK_OF(GENERAL_NAME) *altname;
+	NAME_CONSTRAINTS *nc;
+#ifndef OPENSSL_NO_RFC3779
+	STACK_OF(IPAddressFamily) *rfc3779_addr;
+	struct ASIdentifiers_st *rfc3779_asid;
+#endif
+#ifndef OPENSSL_NO_SHA
+	unsigned char sha1_hash[SHA_DIGEST_LENGTH];
+#endif
+	X509_CERT_AUX *aux;
+	} /* X509 */;
+
+DECLARE_STACK_OF(X509)
+DECLARE_ASN1_SET_OF(X509)
+
+/* This is used for a table of trust checking functions */
+
+typedef struct x509_trust_st {
+	int trust;
+	int flags;
+	int (*check_trust)(struct x509_trust_st *, X509 *, int);
+	char *name;
+	int arg1;
+	void *arg2;
+} X509_TRUST;
+
+DECLARE_STACK_OF(X509_TRUST)
+
+typedef struct x509_cert_pair_st {
+	X509 *forward;
+	X509 *reverse;
+} X509_CERT_PAIR;
+
+/* standard trust ids */
+
+#define X509_TRUST_DEFAULT	-1	/* Only valid in purpose settings */
+
+#define X509_TRUST_COMPAT	1
+#define X509_TRUST_SSL_CLIENT	2
+#define X509_TRUST_SSL_SERVER	3
+#define X509_TRUST_EMAIL	4
+#define X509_TRUST_OBJECT_SIGN	5
+#define X509_TRUST_OCSP_SIGN	6
+#define X509_TRUST_OCSP_REQUEST	7
+#define X509_TRUST_TSA		8
+
+/* Keep these up to date! */
+#define X509_TRUST_MIN		1
+#define X509_TRUST_MAX		8
+
+
+/* trust_flags values */
+#define	X509_TRUST_DYNAMIC 	1
+#define	X509_TRUST_DYNAMIC_NAME	2
+
+/* check_trust return codes */
+
+#define X509_TRUST_TRUSTED	1
+#define X509_TRUST_REJECTED	2
+#define X509_TRUST_UNTRUSTED	3
+
+/* Flags for X509_print_ex() */
+
+#define	X509_FLAG_COMPAT		0
+#define	X509_FLAG_NO_HEADER		1L
+#define	X509_FLAG_NO_VERSION		(1L << 1)
+#define	X509_FLAG_NO_SERIAL		(1L << 2)
+#define	X509_FLAG_NO_SIGNAME		(1L << 3)
+#define	X509_FLAG_NO_ISSUER		(1L << 4)
+#define	X509_FLAG_NO_VALIDITY		(1L << 5)
+#define	X509_FLAG_NO_SUBJECT		(1L << 6)
+#define	X509_FLAG_NO_PUBKEY		(1L << 7)
+#define	X509_FLAG_NO_EXTENSIONS		(1L << 8)
+#define	X509_FLAG_NO_SIGDUMP		(1L << 9)
+#define	X509_FLAG_NO_AUX		(1L << 10)
+#define	X509_FLAG_NO_ATTRIBUTES		(1L << 11)
+
+/* Flags specific to X509_NAME_print_ex() */	
+
+/* The field separator information */
+
+#define XN_FLAG_SEP_MASK	(0xf << 16)
+
+#define XN_FLAG_COMPAT		0		/* Traditional SSLeay: use old X509_NAME_print */
+#define XN_FLAG_SEP_COMMA_PLUS	(1 << 16)	/* RFC2253 ,+ */
+#define XN_FLAG_SEP_CPLUS_SPC	(2 << 16)	/* ,+ spaced: more readable */
+#define XN_FLAG_SEP_SPLUS_SPC	(3 << 16)	/* ;+ spaced */
+#define XN_FLAG_SEP_MULTILINE	(4 << 16)	/* One line per field */
+
+#define XN_FLAG_DN_REV		(1 << 20)	/* Reverse DN order */
+
+/* How the field name is shown */
+
+#define XN_FLAG_FN_MASK		(0x3 << 21)
+
+#define XN_FLAG_FN_SN		0		/* Object short name */
+#define XN_FLAG_FN_LN		(1 << 21)	/* Object long name */
+#define XN_FLAG_FN_OID		(2 << 21)	/* Always use OIDs */
+#define XN_FLAG_FN_NONE		(3 << 21)	/* No field names */
+
+#define XN_FLAG_SPC_EQ		(1 << 23)	/* Put spaces round '=' */
+
+/* This determines if we dump fields we don't recognise:
+ * RFC2253 requires this.
+ */
+
+#define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24)
+
+#define XN_FLAG_FN_ALIGN	(1 << 25)	/* Align field names to 20 characters */
+
+/* Complete set of RFC2253 flags */
+
+#define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \
+			XN_FLAG_SEP_COMMA_PLUS | \
+			XN_FLAG_DN_REV | \
+			XN_FLAG_FN_SN | \
+			XN_FLAG_DUMP_UNKNOWN_FIELDS)
+
+/* readable oneline form */
+
+#define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \
+			ASN1_STRFLGS_ESC_QUOTE | \
+			XN_FLAG_SEP_CPLUS_SPC | \
+			XN_FLAG_SPC_EQ | \
+			XN_FLAG_FN_SN)
+
+/* readable multiline form */
+
+#define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \
+			ASN1_STRFLGS_ESC_MSB | \
+			XN_FLAG_SEP_MULTILINE | \
+			XN_FLAG_SPC_EQ | \
+			XN_FLAG_FN_LN | \
+			XN_FLAG_FN_ALIGN)
+
+struct x509_revoked_st
+	{
+	ASN1_INTEGER *serialNumber;
+	ASN1_TIME *revocationDate;
+	STACK_OF(X509_EXTENSION) /* optional */ *extensions;
+	/* Set up if indirect CRL */
+	STACK_OF(GENERAL_NAME) *issuer;
+	/* Revocation reason */
+	int reason;
+	int sequence; /* load sequence */
+	};
+
+DECLARE_STACK_OF(X509_REVOKED)
+DECLARE_ASN1_SET_OF(X509_REVOKED)
+
+typedef struct X509_crl_info_st
+	{
+	ASN1_INTEGER *version;
+	X509_ALGOR *sig_alg;
+	X509_NAME *issuer;
+	ASN1_TIME *lastUpdate;
+	ASN1_TIME *nextUpdate;
+	STACK_OF(X509_REVOKED) *revoked;
+	STACK_OF(X509_EXTENSION) /* [0] */ *extensions;
+	ASN1_ENCODING enc;
+	} X509_CRL_INFO;
+
+struct X509_crl_st
+	{
+	/* actual signature */
+	X509_CRL_INFO *crl;
+	X509_ALGOR *sig_alg;
+	ASN1_BIT_STRING *signature;
+	int references;
+	int flags;
+	/* Copies of various extensions */
+	AUTHORITY_KEYID *akid;
+	ISSUING_DIST_POINT *idp;
+	/* Convenient breakdown of IDP */
+	int idp_flags;
+	int idp_reasons;
+	/* CRL and base CRL numbers for delta processing */
+	ASN1_INTEGER *crl_number;
+	ASN1_INTEGER *base_crl_number;
+#ifndef OPENSSL_NO_SHA
+	unsigned char sha1_hash[SHA_DIGEST_LENGTH];
+#endif
+	STACK_OF(GENERAL_NAMES) *issuers;
+	const X509_CRL_METHOD *meth;
+	void *meth_data;
+	} /* X509_CRL */;
+
+DECLARE_STACK_OF(X509_CRL)
+DECLARE_ASN1_SET_OF(X509_CRL)
+
+typedef struct private_key_st
+	{
+	int version;
+	/* The PKCS#8 data types */
+	X509_ALGOR *enc_algor;
+	ASN1_OCTET_STRING *enc_pkey;	/* encrypted pub key */
+
+	/* When decrypted, the following will not be NULL */
+	EVP_PKEY *dec_pkey;
+
+	/* used to encrypt and decrypt */
+	int key_length;
+	char *key_data;
+	int key_free;	/* true if we should auto free key_data */
+
+	/* expanded version of 'enc_algor' */
+	EVP_CIPHER_INFO cipher;
+
+	int references;
+	} X509_PKEY;
+
+#ifndef OPENSSL_NO_EVP
+typedef struct X509_info_st
+	{
+	X509 *x509;
+	X509_CRL *crl;
+	X509_PKEY *x_pkey;
+
+	EVP_CIPHER_INFO enc_cipher;
+	int enc_len;
+	char *enc_data;
+
+	int references;
+	} X509_INFO;
+
+DECLARE_STACK_OF(X509_INFO)
+#endif
+
+/* The next 2 structures and their 8 routines were sent to me by
+ * Pat Richard <patr@x509.com> and are used to manipulate
+ * Netscapes spki structures - useful if you are writing a CA web page
+ */
+typedef struct Netscape_spkac_st
+	{
+	X509_PUBKEY *pubkey;
+	ASN1_IA5STRING *challenge;	/* challenge sent in atlas >= PR2 */
+	} NETSCAPE_SPKAC;
+
+typedef struct Netscape_spki_st
+	{
+	NETSCAPE_SPKAC *spkac;	/* signed public key and challenge */
+	X509_ALGOR *sig_algor;
+	ASN1_BIT_STRING *signature;
+	} NETSCAPE_SPKI;
+
+/* Netscape certificate sequence structure */
+typedef struct Netscape_certificate_sequence
+	{
+	ASN1_OBJECT *type;
+	STACK_OF(X509) *certs;
+	} NETSCAPE_CERT_SEQUENCE;
+
+/* Unused (and iv length is wrong)
+typedef struct CBCParameter_st
+	{
+	unsigned char iv[8];
+	} CBC_PARAM;
+*/
+
+/* Password based encryption structure */
+
+typedef struct PBEPARAM_st {
+ASN1_OCTET_STRING *salt;
+ASN1_INTEGER *iter;
+} PBEPARAM;
+
+/* Password based encryption V2 structures */
+
+typedef struct PBE2PARAM_st {
+X509_ALGOR *keyfunc;
+X509_ALGOR *encryption;
+} PBE2PARAM;
+
+typedef struct PBKDF2PARAM_st {
+ASN1_TYPE *salt;	/* Usually OCTET STRING but could be anything */
+ASN1_INTEGER *iter;
+ASN1_INTEGER *keylength;
+X509_ALGOR *prf;
+} PBKDF2PARAM;
+
+
+/* PKCS#8 private key info structure */
+
+struct pkcs8_priv_key_info_st
+        {
+        int broken;     /* Flag for various broken formats */
+#define PKCS8_OK		0
+#define PKCS8_NO_OCTET		1
+#define PKCS8_EMBEDDED_PARAM	2
+#define PKCS8_NS_DB		3
+#define PKCS8_NEG_PRIVKEY	4
+        ASN1_INTEGER *version;
+        X509_ALGOR *pkeyalg;
+        ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */
+        STACK_OF(X509_ATTRIBUTE) *attributes;
+        };
+
+#ifdef  __cplusplus
+}
+#endif
+
+#include <openssl/x509_vfy.h>
+#include <openssl/pkcs7.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define X509_EXT_PACK_UNKNOWN	1
+#define X509_EXT_PACK_STRING	2
+
+#define		X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version)
+/* #define	X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */
+#define		X509_get_notBefore(x) ((x)->cert_info->validity->notBefore)
+#define		X509_get_notAfter(x) ((x)->cert_info->validity->notAfter)
+#define		X509_extract_key(x)	X509_get_pubkey(x) /*****/
+#define		X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version)
+#define		X509_REQ_get_subject_name(x) ((x)->req_info->subject)
+#define		X509_REQ_extract_key(a)	X509_REQ_get_pubkey(a)
+#define		X509_name_cmp(a,b)	X509_NAME_cmp((a),(b))
+#define		X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm))
+
+#define		X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version)
+#define 	X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate)
+#define 	X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate)
+#define		X509_CRL_get_issuer(x) ((x)->crl->issuer)
+#define		X509_CRL_get_REVOKED(x) ((x)->crl->revoked)
+
+void X509_CRL_set_default_method(const X509_CRL_METHOD *meth);
+X509_CRL_METHOD *X509_CRL_METHOD_new(
+	int (*crl_init)(X509_CRL *crl),
+	int (*crl_free)(X509_CRL *crl),
+	int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
+				ASN1_INTEGER *ser, X509_NAME *issuer),
+	int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk));
+void X509_CRL_METHOD_free(X509_CRL_METHOD *m);
+
+void X509_CRL_set_meth_data(X509_CRL *crl, void *dat);
+void *X509_CRL_get_meth_data(X509_CRL *crl);
+
+/* This one is only used so that a binary form can output, as in
+ * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) */
+#define 	X509_get_X509_PUBKEY(x) ((x)->cert_info->key)
+
+
+const char *X509_verify_cert_error_string(long n);
+
+#ifndef OPENSSL_NO_EVP
+int X509_verify(X509 *a, EVP_PKEY *r);
+
+int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
+int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
+int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);
+
+NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len);
+char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
+EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
+int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
+
+int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);
+
+int X509_signature_print(BIO *bp,X509_ALGOR *alg, ASN1_STRING *sig);
+
+int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
+int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
+
+int X509_pubkey_digest(const X509 *data,const EVP_MD *type,
+		unsigned char *md, unsigned int *len);
+int X509_digest(const X509 *data,const EVP_MD *type,
+		unsigned char *md, unsigned int *len);
+int X509_CRL_digest(const X509_CRL *data,const EVP_MD *type,
+		unsigned char *md, unsigned int *len);
+int X509_REQ_digest(const X509_REQ *data,const EVP_MD *type,
+		unsigned char *md, unsigned int *len);
+int X509_NAME_digest(const X509_NAME *data,const EVP_MD *type,
+		unsigned char *md, unsigned int *len);
+#endif
+
+#ifndef OPENSSL_NO_FP_API
+X509 *d2i_X509_fp(FILE *fp, X509 **x509);
+int i2d_X509_fp(FILE *fp,X509 *x509);
+X509_CRL *d2i_X509_CRL_fp(FILE *fp,X509_CRL **crl);
+int i2d_X509_CRL_fp(FILE *fp,X509_CRL *crl);
+X509_REQ *d2i_X509_REQ_fp(FILE *fp,X509_REQ **req);
+int i2d_X509_REQ_fp(FILE *fp,X509_REQ *req);
+#ifndef OPENSSL_NO_RSA
+RSA *d2i_RSAPrivateKey_fp(FILE *fp,RSA **rsa);
+int i2d_RSAPrivateKey_fp(FILE *fp,RSA *rsa);
+RSA *d2i_RSAPublicKey_fp(FILE *fp,RSA **rsa);
+int i2d_RSAPublicKey_fp(FILE *fp,RSA *rsa);
+RSA *d2i_RSA_PUBKEY_fp(FILE *fp,RSA **rsa);
+int i2d_RSA_PUBKEY_fp(FILE *fp,RSA *rsa);
+#endif
+#ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
+int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa);
+DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
+int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa);
+#endif
+#ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey);
+int   i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey);
+EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey);
+int   i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey);
+#endif
+X509_SIG *d2i_PKCS8_fp(FILE *fp,X509_SIG **p8);
+int i2d_PKCS8_fp(FILE *fp,X509_SIG *p8);
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
+						PKCS8_PRIV_KEY_INFO **p8inf);
+int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
+int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
+int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
+#endif
+
+#ifndef OPENSSL_NO_BIO
+X509 *d2i_X509_bio(BIO *bp,X509 **x509);
+int i2d_X509_bio(BIO *bp,X509 *x509);
+X509_CRL *d2i_X509_CRL_bio(BIO *bp,X509_CRL **crl);
+int i2d_X509_CRL_bio(BIO *bp,X509_CRL *crl);
+X509_REQ *d2i_X509_REQ_bio(BIO *bp,X509_REQ **req);
+int i2d_X509_REQ_bio(BIO *bp,X509_REQ *req);
+#ifndef OPENSSL_NO_RSA
+RSA *d2i_RSAPrivateKey_bio(BIO *bp,RSA **rsa);
+int i2d_RSAPrivateKey_bio(BIO *bp,RSA *rsa);
+RSA *d2i_RSAPublicKey_bio(BIO *bp,RSA **rsa);
+int i2d_RSAPublicKey_bio(BIO *bp,RSA *rsa);
+RSA *d2i_RSA_PUBKEY_bio(BIO *bp,RSA **rsa);
+int i2d_RSA_PUBKEY_bio(BIO *bp,RSA *rsa);
+#endif
+#ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
+int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa);
+DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
+int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa);
+#endif
+#ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey);
+int   i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey);
+EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey);
+int   i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey);
+#endif
+X509_SIG *d2i_PKCS8_bio(BIO *bp,X509_SIG **p8);
+int i2d_PKCS8_bio(BIO *bp,X509_SIG *p8);
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
+						PKCS8_PRIV_KEY_INFO **p8inf);
+int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
+int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
+int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
+#endif
+
+X509 *X509_dup(X509 *x509);
+X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa);
+X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
+X509_CRL *X509_CRL_dup(X509_CRL *crl);
+X509_REQ *X509_REQ_dup(X509_REQ *req);
+X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
+int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval);
+void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
+						X509_ALGOR *algor);
+
+X509_NAME *X509_NAME_dup(X509_NAME *xn);
+X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
+
+int		X509_cmp_time(const ASN1_TIME *s, time_t *t);
+int		X509_cmp_current_time(const ASN1_TIME *s);
+ASN1_TIME *	X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
+ASN1_TIME *	X509_time_adj_ex(ASN1_TIME *s,
+				int offset_day, long offset_sec, time_t *t);
+ASN1_TIME *	X509_gmtime_adj(ASN1_TIME *s, long adj);
+
+const char *	X509_get_default_cert_area(void );
+const char *	X509_get_default_cert_dir(void );
+const char *	X509_get_default_cert_file(void );
+const char *	X509_get_default_cert_dir_env(void );
+const char *	X509_get_default_cert_file_env(void );
+const char *	X509_get_default_private_dir(void );
+
+X509_REQ *	X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+X509 *		X509_REQ_to_X509(X509_REQ *r, int days,EVP_PKEY *pkey);
+
+DECLARE_ASN1_FUNCTIONS(X509_ALGOR)
+DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS)
+DECLARE_ASN1_FUNCTIONS(X509_VAL)
+
+DECLARE_ASN1_FUNCTIONS(X509_PUBKEY)
+
+int		X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
+EVP_PKEY *	X509_PUBKEY_get(X509_PUBKEY *key);
+int		X509_get_pubkey_parameters(EVP_PKEY *pkey,
+					   STACK_OF(X509) *chain);
+int		i2d_PUBKEY(EVP_PKEY *a,unsigned char **pp);
+EVP_PKEY *	d2i_PUBKEY(EVP_PKEY **a,const unsigned char **pp,
+			long length);
+#ifndef OPENSSL_NO_RSA
+int		i2d_RSA_PUBKEY(RSA *a,unsigned char **pp);
+RSA *		d2i_RSA_PUBKEY(RSA **a,const unsigned char **pp,
+			long length);
+#endif
+#ifndef OPENSSL_NO_DSA
+int		i2d_DSA_PUBKEY(DSA *a,unsigned char **pp);
+DSA *		d2i_DSA_PUBKEY(DSA **a,const unsigned char **pp,
+			long length);
+#endif
+#ifndef OPENSSL_NO_EC
+int		i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp);
+EC_KEY 		*d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp,
+			long length);
+#endif
+
+DECLARE_ASN1_FUNCTIONS(X509_SIG)
+DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO)
+DECLARE_ASN1_FUNCTIONS(X509_REQ)
+
+DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE)
+X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);
+
+DECLARE_ASN1_FUNCTIONS(X509_EXTENSION)
+DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)
+
+DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY)
+
+DECLARE_ASN1_FUNCTIONS(X509_NAME)
+
+int		X509_NAME_set(X509_NAME **xn, X509_NAME *name);
+
+DECLARE_ASN1_FUNCTIONS(X509_CINF)
+
+DECLARE_ASN1_FUNCTIONS(X509)
+DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX)
+
+DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR)
+
+int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int X509_set_ex_data(X509 *r, int idx, void *arg);
+void *X509_get_ex_data(X509 *r, int idx);
+int		i2d_X509_AUX(X509 *a,unsigned char **pp);
+X509 *		d2i_X509_AUX(X509 **a,const unsigned char **pp,long length);
+
+int X509_alias_set1(X509 *x, unsigned char *name, int len);
+int X509_keyid_set1(X509 *x, unsigned char *id, int len);
+unsigned char * X509_alias_get0(X509 *x, int *len);
+unsigned char * X509_keyid_get0(X509 *x, int *len);
+int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int);
+int X509_TRUST_set(int *t, int trust);
+int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj);
+int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj);
+void X509_trust_clear(X509 *x);
+void X509_reject_clear(X509 *x);
+
+DECLARE_ASN1_FUNCTIONS(X509_REVOKED)
+DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO)
+DECLARE_ASN1_FUNCTIONS(X509_CRL)
+
+int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
+int X509_CRL_get0_by_serial(X509_CRL *crl,
+		X509_REVOKED **ret, ASN1_INTEGER *serial);
+int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x);
+
+X509_PKEY *	X509_PKEY_new(void );
+void		X509_PKEY_free(X509_PKEY *a);
+int		i2d_X509_PKEY(X509_PKEY *a,unsigned char **pp);
+X509_PKEY *	d2i_X509_PKEY(X509_PKEY **a,const unsigned char **pp,long length);
+
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI)
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
+
+#ifndef OPENSSL_NO_EVP
+X509_INFO *	X509_INFO_new(void);
+void		X509_INFO_free(X509_INFO *a);
+char *		X509_NAME_oneline(X509_NAME *a,char *buf,int size);
+
+int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1,
+		ASN1_BIT_STRING *signature,char *data,EVP_PKEY *pkey);
+
+int ASN1_digest(i2d_of_void *i2d,const EVP_MD *type,char *data,
+		unsigned char *md,unsigned int *len);
+
+int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1,
+	      X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
+	      char *data,EVP_PKEY *pkey, const EVP_MD *type);
+
+int ASN1_item_digest(const ASN1_ITEM *it,const EVP_MD *type,void *data,
+	unsigned char *md,unsigned int *len);
+
+int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
+	ASN1_BIT_STRING *signature,void *data,EVP_PKEY *pkey);
+
+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
+	ASN1_BIT_STRING *signature,
+	void *data, EVP_PKEY *pkey, const EVP_MD *type);
+#endif
+
+int 		X509_set_version(X509 *x,long version);
+int 		X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial);
+ASN1_INTEGER *	X509_get_serialNumber(X509 *x);
+int 		X509_set_issuer_name(X509 *x, X509_NAME *name);
+X509_NAME *	X509_get_issuer_name(X509 *a);
+int 		X509_set_subject_name(X509 *x, X509_NAME *name);
+X509_NAME *	X509_get_subject_name(X509 *a);
+int 		X509_set_notBefore(X509 *x, const ASN1_TIME *tm);
+int 		X509_set_notAfter(X509 *x, const ASN1_TIME *tm);
+int 		X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
+EVP_PKEY *	X509_get_pubkey(X509 *x);
+ASN1_BIT_STRING * X509_get0_pubkey_bitstr(const X509 *x);
+int		X509_certificate_type(X509 *x,EVP_PKEY *pubkey /* optional */);
+
+int		X509_REQ_set_version(X509_REQ *x,long version);
+int		X509_REQ_set_subject_name(X509_REQ *req,X509_NAME *name);
+int		X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
+EVP_PKEY *	X509_REQ_get_pubkey(X509_REQ *req);
+int		X509_REQ_extension_nid(int nid);
+int *		X509_REQ_get_extension_nids(void);
+void		X509_REQ_set_extension_nids(int *nids);
+STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
+int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
+				int nid);
+int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts);
+int X509_REQ_get_attr_count(const X509_REQ *req);
+int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid,
+			  int lastpos);
+int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
+X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
+int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
+int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
+			const ASN1_OBJECT *obj, int type,
+			const unsigned char *bytes, int len);
+int X509_REQ_add1_attr_by_NID(X509_REQ *req,
+			int nid, int type,
+			const unsigned char *bytes, int len);
+int X509_REQ_add1_attr_by_txt(X509_REQ *req,
+			const char *attrname, int type,
+			const unsigned char *bytes, int len);
+
+int X509_CRL_set_version(X509_CRL *x, long version);
+int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
+int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
+int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
+int X509_CRL_sort(X509_CRL *crl);
+
+int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
+int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
+
+int		X509_REQ_check_private_key(X509_REQ *x509,EVP_PKEY *pkey);
+
+int		X509_check_private_key(X509 *x509,EVP_PKEY *pkey);
+
+int		X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
+unsigned long	X509_issuer_and_serial_hash(X509 *a);
+
+int		X509_issuer_name_cmp(const X509 *a, const X509 *b);
+unsigned long	X509_issuer_name_hash(X509 *a);
+
+int		X509_subject_name_cmp(const X509 *a, const X509 *b);
+unsigned long	X509_subject_name_hash(X509 *x);
+
+#ifndef OPENSSL_NO_MD5
+unsigned long	X509_issuer_name_hash_old(X509 *a);
+unsigned long	X509_subject_name_hash_old(X509 *x);
+#endif
+
+int		X509_cmp(const X509 *a, const X509 *b);
+int		X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
+unsigned long	X509_NAME_hash(X509_NAME *x);
+unsigned long	X509_NAME_hash_old(X509_NAME *x);
+
+int		X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
+int		X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
+#ifndef OPENSSL_NO_FP_API
+int		X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag);
+int		X509_print_fp(FILE *bp,X509 *x);
+int		X509_CRL_print_fp(FILE *bp,X509_CRL *x);
+int		X509_REQ_print_fp(FILE *bp,X509_REQ *req);
+int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags);
+#endif
+
+#ifndef OPENSSL_NO_BIO
+int		X509_NAME_print(BIO *bp, X509_NAME *name, int obase);
+int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags);
+int		X509_print_ex(BIO *bp,X509 *x, unsigned long nmflag, unsigned long cflag);
+int		X509_print(BIO *bp,X509 *x);
+int		X509_ocspid_print(BIO *bp,X509 *x);
+int		X509_CERT_AUX_print(BIO *bp,X509_CERT_AUX *x, int indent);
+int		X509_CRL_print(BIO *bp,X509_CRL *x);
+int		X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, unsigned long cflag);
+int		X509_REQ_print(BIO *bp,X509_REQ *req);
+#endif
+
+int 		X509_NAME_entry_count(X509_NAME *name);
+int 		X509_NAME_get_text_by_NID(X509_NAME *name, int nid,
+			char *buf,int len);
+int		X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
+			char *buf,int len);
+
+/* NOTE: you should be passsing -1, not 0 as lastpos.  The functions that use
+ * lastpos, search after that position on. */
+int 		X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos);
+int 		X509_NAME_get_index_by_OBJ(X509_NAME *name,ASN1_OBJECT *obj,
+			int lastpos);
+X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
+X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
+int 		X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne,
+			int loc, int set);
+int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
+			unsigned char *bytes, int len, int loc, int set);
+int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
+			unsigned char *bytes, int len, int loc, int set);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
+		const char *field, int type, const unsigned char *bytes, int len);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
+			int type,unsigned char *bytes, int len);
+int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
+			const unsigned char *bytes, int len, int loc, int set);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
+			ASN1_OBJECT *obj, int type,const unsigned char *bytes,
+			int len);
+int 		X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne,
+			ASN1_OBJECT *obj);
+int 		X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
+			const unsigned char *bytes, int len);
+ASN1_OBJECT *	X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
+ASN1_STRING *	X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
+
+int		X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
+int		X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
+				      int nid, int lastpos);
+int		X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
+				      ASN1_OBJECT *obj,int lastpos);
+int		X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
+					   int crit, int lastpos);
+X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
+X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
+STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
+					 X509_EXTENSION *ex, int loc);
+
+int		X509_get_ext_count(X509 *x);
+int		X509_get_ext_by_NID(X509 *x, int nid, int lastpos);
+int		X509_get_ext_by_OBJ(X509 *x,ASN1_OBJECT *obj,int lastpos);
+int		X509_get_ext_by_critical(X509 *x, int crit, int lastpos);
+X509_EXTENSION *X509_get_ext(X509 *x, int loc);
+X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
+int		X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
+void	*	X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
+int		X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
+							unsigned long flags);
+
+int		X509_CRL_get_ext_count(X509_CRL *x);
+int		X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos);
+int		X509_CRL_get_ext_by_OBJ(X509_CRL *x,ASN1_OBJECT *obj,int lastpos);
+int		X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos);
+X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc);
+X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
+int		X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
+void	*	X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx);
+int		X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
+							unsigned long flags);
+
+int		X509_REVOKED_get_ext_count(X509_REVOKED *x);
+int		X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos);
+int		X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x,ASN1_OBJECT *obj,int lastpos);
+int		X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos);
+X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc);
+X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
+int		X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);
+void	*	X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx);
+int		X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
+							unsigned long flags);
+
+X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
+			int nid, int crit, ASN1_OCTET_STRING *data);
+X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
+			ASN1_OBJECT *obj,int crit,ASN1_OCTET_STRING *data);
+int		X509_EXTENSION_set_object(X509_EXTENSION *ex,ASN1_OBJECT *obj);
+int		X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit);
+int		X509_EXTENSION_set_data(X509_EXTENSION *ex,
+			ASN1_OCTET_STRING *data);
+ASN1_OBJECT *	X509_EXTENSION_get_object(X509_EXTENSION *ex);
+ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
+int		X509_EXTENSION_get_critical(X509_EXTENSION *ex);
+
+int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x);
+int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
+			  int lastpos);
+int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc);
+X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
+					 X509_ATTRIBUTE *attr);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x,
+			const ASN1_OBJECT *obj, int type,
+			const unsigned char *bytes, int len);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x,
+			int nid, int type,
+			const unsigned char *bytes, int len);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x,
+			const char *attrname, int type,
+			const unsigned char *bytes, int len);
+void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x,
+				ASN1_OBJECT *obj, int lastpos, int type);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
+	     int atrtype, const void *data, int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
+	     const ASN1_OBJECT *obj, int atrtype, const void *data, int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
+		const char *atrname, int type, const unsigned char *bytes, int len);
+int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj);
+int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len);
+void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
+					int atrtype, void *data);
+int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr);
+ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr);
+ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx);
+
+int EVP_PKEY_get_attr_count(const EVP_PKEY *key);
+int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid,
+			  int lastpos);
+int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc);
+X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc);
+int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr);
+int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
+			const ASN1_OBJECT *obj, int type,
+			const unsigned char *bytes, int len);
+int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
+			int nid, int type,
+			const unsigned char *bytes, int len);
+int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
+			const char *attrname, int type,
+			const unsigned char *bytes, int len);
+
+int		X509_verify_cert(X509_STORE_CTX *ctx);
+
+/* lookup a cert from a X509 STACK */
+X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk,X509_NAME *name,
+				     ASN1_INTEGER *serial);
+X509 *X509_find_by_subject(STACK_OF(X509) *sk,X509_NAME *name);
+
+DECLARE_ASN1_FUNCTIONS(PBEPARAM)
+DECLARE_ASN1_FUNCTIONS(PBE2PARAM)
+DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM)
+
+int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
+				const unsigned char *salt, int saltlen);
+
+X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
+				const unsigned char *salt, int saltlen);
+X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
+					 unsigned char *salt, int saltlen);
+X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
+				 unsigned char *salt, int saltlen,
+				 unsigned char *aiv, int prf_nid);
+
+/* PKCS#8 utilities */
+
+DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
+
+EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8);
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
+PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
+
+int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
+			int version, int ptype, void *pval,
+				unsigned char *penc, int penclen);
+int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
+		const unsigned char **pk, int *ppklen,
+		X509_ALGOR **pa,
+		PKCS8_PRIV_KEY_INFO *p8);
+
+int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
+					int ptype, void *pval,
+					unsigned char *penc, int penclen);
+int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
+		const unsigned char **pk, int *ppklen,
+		X509_ALGOR **pa,
+		X509_PUBKEY *pub);
+
+int X509_check_trust(X509 *x, int id, int flags);
+int X509_TRUST_get_count(void);
+X509_TRUST * X509_TRUST_get0(int idx);
+int X509_TRUST_get_by_id(int id);
+int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
+					char *name, int arg1, void *arg2);
+void X509_TRUST_cleanup(void);
+int X509_TRUST_get_flags(X509_TRUST *xp);
+char *X509_TRUST_get0_name(X509_TRUST *xp);
+int X509_TRUST_get_trust(X509_TRUST *xp);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_X509_strings(void);
+
+/* Error codes for the X509 functions. */
+
+/* Function codes. */
+#define X509_F_ADD_CERT_DIR				 100
+#define X509_F_BY_FILE_CTRL				 101
+#define X509_F_CHECK_POLICY				 145
+#define X509_F_DIR_CTRL					 102
+#define X509_F_GET_CERT_BY_SUBJECT			 103
+#define X509_F_NETSCAPE_SPKI_B64_DECODE			 129
+#define X509_F_NETSCAPE_SPKI_B64_ENCODE			 130
+#define X509_F_X509AT_ADD1_ATTR				 135
+#define X509_F_X509V3_ADD_EXT				 104
+#define X509_F_X509_ATTRIBUTE_CREATE_BY_NID		 136
+#define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ		 137
+#define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT		 140
+#define X509_F_X509_ATTRIBUTE_GET0_DATA			 139
+#define X509_F_X509_ATTRIBUTE_SET1_DATA			 138
+#define X509_F_X509_CHECK_PRIVATE_KEY			 128
+#define X509_F_X509_CRL_PRINT_FP			 147
+#define X509_F_X509_EXTENSION_CREATE_BY_NID		 108
+#define X509_F_X509_EXTENSION_CREATE_BY_OBJ		 109
+#define X509_F_X509_GET_PUBKEY_PARAMETERS		 110
+#define X509_F_X509_LOAD_CERT_CRL_FILE			 132
+#define X509_F_X509_LOAD_CERT_FILE			 111
+#define X509_F_X509_LOAD_CRL_FILE			 112
+#define X509_F_X509_NAME_ADD_ENTRY			 113
+#define X509_F_X509_NAME_ENTRY_CREATE_BY_NID		 114
+#define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT		 131
+#define X509_F_X509_NAME_ENTRY_SET_OBJECT		 115
+#define X509_F_X509_NAME_ONELINE			 116
+#define X509_F_X509_NAME_PRINT				 117
+#define X509_F_X509_PRINT_EX_FP				 118
+#define X509_F_X509_PUBKEY_GET				 119
+#define X509_F_X509_PUBKEY_SET				 120
+#define X509_F_X509_REQ_CHECK_PRIVATE_KEY		 144
+#define X509_F_X509_REQ_PRINT_EX			 121
+#define X509_F_X509_REQ_PRINT_FP			 122
+#define X509_F_X509_REQ_TO_X509				 123
+#define X509_F_X509_STORE_ADD_CERT			 124
+#define X509_F_X509_STORE_ADD_CRL			 125
+#define X509_F_X509_STORE_CTX_GET1_ISSUER		 146
+#define X509_F_X509_STORE_CTX_INIT			 143
+#define X509_F_X509_STORE_CTX_NEW			 142
+#define X509_F_X509_STORE_CTX_PURPOSE_INHERIT		 134
+#define X509_F_X509_TO_X509_REQ				 126
+#define X509_F_X509_TRUST_ADD				 133
+#define X509_F_X509_TRUST_SET				 141
+#define X509_F_X509_VERIFY_CERT				 127
+
+/* Reason codes. */
+#define X509_R_BAD_X509_FILETYPE			 100
+#define X509_R_BASE64_DECODE_ERROR			 118
+#define X509_R_CANT_CHECK_DH_KEY			 114
+#define X509_R_CERT_ALREADY_IN_HASH_TABLE		 101
+#define X509_R_ERR_ASN1_LIB				 102
+#define X509_R_INVALID_DIRECTORY			 113
+#define X509_R_INVALID_FIELD_NAME			 119
+#define X509_R_INVALID_TRUST				 123
+#define X509_R_KEY_TYPE_MISMATCH			 115
+#define X509_R_KEY_VALUES_MISMATCH			 116
+#define X509_R_LOADING_CERT_DIR				 103
+#define X509_R_LOADING_DEFAULTS				 104
+#define X509_R_METHOD_NOT_SUPPORTED			 124
+#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY		 105
+#define X509_R_PUBLIC_KEY_DECODE_ERROR			 125
+#define X509_R_PUBLIC_KEY_ENCODE_ERROR			 126
+#define X509_R_SHOULD_RETRY				 106
+#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN	 107
+#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY		 108
+#define X509_R_UNKNOWN_KEY_TYPE				 117
+#define X509_R_UNKNOWN_NID				 109
+#define X509_R_UNKNOWN_PURPOSE_ID			 121
+#define X509_R_UNKNOWN_TRUST_ID				 120
+#define X509_R_UNSUPPORTED_ALGORITHM			 111
+#define X509_R_WRONG_LOOKUP_TYPE			 112
+#define X509_R_WRONG_TYPE				 122
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/x509/x509_att.c b/openssl/crypto/x509/x509_att.c
new file mode 100644
index 0000000..98460e8
--- /dev/null
+++ b/openssl/crypto/x509/x509_att.c
@@ -0,0 +1,359 @@
+/* crypto/x509/x509_att.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/stack.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x)
+{
+	return sk_X509_ATTRIBUTE_num(x);
+}
+
+int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
+			  int lastpos)
+{
+	ASN1_OBJECT *obj;
+
+	obj=OBJ_nid2obj(nid);
+	if (obj == NULL) return(-2);
+	return(X509at_get_attr_by_OBJ(x,obj,lastpos));
+}
+
+int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, ASN1_OBJECT *obj,
+			  int lastpos)
+{
+	int n;
+	X509_ATTRIBUTE *ex;
+
+	if (sk == NULL) return(-1);
+	lastpos++;
+	if (lastpos < 0)
+		lastpos=0;
+	n=sk_X509_ATTRIBUTE_num(sk);
+	for ( ; lastpos < n; lastpos++)
+		{
+		ex=sk_X509_ATTRIBUTE_value(sk,lastpos);
+		if (OBJ_cmp(ex->object,obj) == 0)
+			return(lastpos);
+		}
+	return(-1);
+}
+
+X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc)
+{
+	if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
+		return NULL;
+	else
+		return sk_X509_ATTRIBUTE_value(x,loc);
+}
+
+X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc)
+{
+	X509_ATTRIBUTE *ret;
+
+	if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
+		return(NULL);
+	ret=sk_X509_ATTRIBUTE_delete(x,loc);
+	return(ret);
+}
+
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
+					 X509_ATTRIBUTE *attr)
+{
+	X509_ATTRIBUTE *new_attr=NULL;
+	STACK_OF(X509_ATTRIBUTE) *sk=NULL;
+
+	if (x == NULL)
+		{
+		X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_PASSED_NULL_PARAMETER);
+		goto err2;
+		} 
+
+	if (*x == NULL)
+		{
+		if ((sk=sk_X509_ATTRIBUTE_new_null()) == NULL)
+			goto err;
+		}
+	else
+		sk= *x;
+
+	if ((new_attr=X509_ATTRIBUTE_dup(attr)) == NULL)
+		goto err2;
+	if (!sk_X509_ATTRIBUTE_push(sk,new_attr))
+		goto err;
+	if (*x == NULL)
+		*x=sk;
+	return(sk);
+err:
+	X509err(X509_F_X509AT_ADD1_ATTR,ERR_R_MALLOC_FAILURE);
+err2:
+	if (new_attr != NULL) X509_ATTRIBUTE_free(new_attr);
+	if (sk != NULL) sk_X509_ATTRIBUTE_free(sk);
+	return(NULL);
+}
+
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x,
+			const ASN1_OBJECT *obj, int type,
+			const unsigned char *bytes, int len)
+{
+	X509_ATTRIBUTE *attr;
+	STACK_OF(X509_ATTRIBUTE) *ret;
+	attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len);
+	if(!attr) return 0;
+	ret = X509at_add1_attr(x, attr);
+	X509_ATTRIBUTE_free(attr);
+	return ret;
+}
+
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x,
+			int nid, int type,
+			const unsigned char *bytes, int len)
+{
+	X509_ATTRIBUTE *attr;
+	STACK_OF(X509_ATTRIBUTE) *ret;
+	attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len);
+	if(!attr) return 0;
+	ret = X509at_add1_attr(x, attr);
+	X509_ATTRIBUTE_free(attr);
+	return ret;
+}
+
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x,
+			const char *attrname, int type,
+			const unsigned char *bytes, int len)
+{
+	X509_ATTRIBUTE *attr;
+	STACK_OF(X509_ATTRIBUTE) *ret;
+	attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len);
+	if(!attr) return 0;
+	ret = X509at_add1_attr(x, attr);
+	X509_ATTRIBUTE_free(attr);
+	return ret;
+}
+
+void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x,
+				ASN1_OBJECT *obj, int lastpos, int type)
+{
+	int i;
+	X509_ATTRIBUTE *at;
+	i = X509at_get_attr_by_OBJ(x, obj, lastpos);
+	if (i == -1)
+		return NULL;
+	if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1))
+		return NULL;
+	at = X509at_get_attr(x, i);
+	if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1))
+		return NULL;
+	return X509_ATTRIBUTE_get0_data(at, 0, type, NULL);
+}
+
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
+	     int atrtype, const void *data, int len)
+{
+	ASN1_OBJECT *obj;
+	X509_ATTRIBUTE *ret;
+
+	obj=OBJ_nid2obj(nid);
+	if (obj == NULL)
+		{
+		X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_NID,X509_R_UNKNOWN_NID);
+		return(NULL);
+		}
+	ret=X509_ATTRIBUTE_create_by_OBJ(attr,obj,atrtype,data,len);
+	if (ret == NULL) ASN1_OBJECT_free(obj);
+	return(ret);
+}
+
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
+	     const ASN1_OBJECT *obj, int atrtype, const void *data, int len)
+{
+	X509_ATTRIBUTE *ret;
+
+	if ((attr == NULL) || (*attr == NULL))
+		{
+		if ((ret=X509_ATTRIBUTE_new()) == NULL)
+			{
+			X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ,ERR_R_MALLOC_FAILURE);
+			return(NULL);
+			}
+		}
+	else
+		ret= *attr;
+
+	if (!X509_ATTRIBUTE_set1_object(ret,obj))
+		goto err;
+	if (!X509_ATTRIBUTE_set1_data(ret,atrtype,data,len))
+		goto err;
+
+	if ((attr != NULL) && (*attr == NULL)) *attr=ret;
+	return(ret);
+err:
+	if ((attr == NULL) || (ret != *attr))
+		X509_ATTRIBUTE_free(ret);
+	return(NULL);
+}
+
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
+		const char *atrname, int type, const unsigned char *bytes, int len)
+	{
+	ASN1_OBJECT *obj;
+	X509_ATTRIBUTE *nattr;
+
+	obj=OBJ_txt2obj(atrname, 0);
+	if (obj == NULL)
+		{
+		X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT,
+						X509_R_INVALID_FIELD_NAME);
+		ERR_add_error_data(2, "name=", atrname);
+		return(NULL);
+		}
+	nattr = X509_ATTRIBUTE_create_by_OBJ(attr,obj,type,bytes,len);
+	ASN1_OBJECT_free(obj);
+	return nattr;
+	}
+
+int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj)
+{
+	if ((attr == NULL) || (obj == NULL))
+		return(0);
+	ASN1_OBJECT_free(attr->object);
+	attr->object=OBJ_dup(obj);
+	return(1);
+}
+
+int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len)
+{
+	ASN1_TYPE *ttmp;
+	ASN1_STRING *stmp = NULL;
+	int atype = 0;
+	if (!attr) return 0;
+	if(attrtype & MBSTRING_FLAG) {
+		stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
+						OBJ_obj2nid(attr->object));
+		if(!stmp) {
+			X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_ASN1_LIB);
+			return 0;
+		}
+		atype = stmp->type;
+	} else if (len != -1){
+		if(!(stmp = ASN1_STRING_type_new(attrtype))) goto err;
+		if(!ASN1_STRING_set(stmp, data, len)) goto err;
+		atype = attrtype;
+	}
+	if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err;
+	attr->single = 0;
+	/* This is a bit naughty because the attribute should really have
+	 * at least one value but some types use and zero length SET and
+	 * require this.
+	 */
+	if (attrtype == 0)
+		return 1;
+	if(!(ttmp = ASN1_TYPE_new())) goto err;
+	if ((len == -1) && !(attrtype & MBSTRING_FLAG))
+		{
+		if (!ASN1_TYPE_set1(ttmp, attrtype, data))
+			goto err;
+		}
+	else
+		ASN1_TYPE_set(ttmp, atype, stmp);
+	if(!sk_ASN1_TYPE_push(attr->value.set, ttmp)) goto err;
+	return 1;
+	err:
+	X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE);
+	return 0;
+}
+
+int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr)
+{
+	if(!attr->single) return sk_ASN1_TYPE_num(attr->value.set);
+	if(attr->value.single) return 1;
+	return 0;
+}
+
+ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr)
+{
+	if (attr == NULL) return(NULL);
+	return(attr->object);
+}
+
+void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
+					int atrtype, void *data)
+{
+	ASN1_TYPE *ttmp;
+	ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
+	if(!ttmp) return NULL;
+	if(atrtype != ASN1_TYPE_get(ttmp)){
+		X509err(X509_F_X509_ATTRIBUTE_GET0_DATA, X509_R_WRONG_TYPE);
+		return NULL;
+	}
+	return ttmp->value.ptr;
+}
+
+ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx)
+{
+	if (attr == NULL) return(NULL);
+	if(idx >= X509_ATTRIBUTE_count(attr)) return NULL;
+	if(!attr->single) return sk_ASN1_TYPE_value(attr->value.set, idx);
+	else return attr->value.single;
+}
diff --git a/openssl/crypto/x509/x509_cmp.c b/openssl/crypto/x509/x509_cmp.c
new file mode 100644
index 0000000..4bc9da0
--- /dev/null
+++ b/openssl/crypto/x509/x509_cmp.c
@@ -0,0 +1,331 @@
+/* crypto/x509/x509_cmp.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
+	{
+	int i;
+	X509_CINF *ai,*bi;
+
+	ai=a->cert_info;
+	bi=b->cert_info;
+	i=M_ASN1_INTEGER_cmp(ai->serialNumber,bi->serialNumber);
+	if (i) return(i);
+	return(X509_NAME_cmp(ai->issuer,bi->issuer));
+	}
+
+#ifndef OPENSSL_NO_MD5
+unsigned long X509_issuer_and_serial_hash(X509 *a)
+	{
+	unsigned long ret=0;
+	EVP_MD_CTX ctx;
+	unsigned char md[16];
+	char *f;
+
+	EVP_MD_CTX_init(&ctx);
+	f=X509_NAME_oneline(a->cert_info->issuer,NULL,0);
+	ret=strlen(f);
+	EVP_DigestInit_ex(&ctx, EVP_md5(), NULL);
+	EVP_DigestUpdate(&ctx,(unsigned char *)f,ret);
+	OPENSSL_free(f);
+	EVP_DigestUpdate(&ctx,(unsigned char *)a->cert_info->serialNumber->data,
+		(unsigned long)a->cert_info->serialNumber->length);
+	EVP_DigestFinal_ex(&ctx,&(md[0]),NULL);
+	ret=(	((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
+		((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
+		)&0xffffffffL;
+	EVP_MD_CTX_cleanup(&ctx);
+	return(ret);
+	}
+#endif
+	
+int X509_issuer_name_cmp(const X509 *a, const X509 *b)
+	{
+	return(X509_NAME_cmp(a->cert_info->issuer,b->cert_info->issuer));
+	}
+
+int X509_subject_name_cmp(const X509 *a, const X509 *b)
+	{
+	return(X509_NAME_cmp(a->cert_info->subject,b->cert_info->subject));
+	}
+
+int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
+	{
+	return(X509_NAME_cmp(a->crl->issuer,b->crl->issuer));
+	}
+
+#ifndef OPENSSL_NO_SHA
+int X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
+	{
+	return memcmp(a->sha1_hash, b->sha1_hash, 20);
+	}
+#endif
+
+X509_NAME *X509_get_issuer_name(X509 *a)
+	{
+	return(a->cert_info->issuer);
+	}
+
+unsigned long X509_issuer_name_hash(X509 *x)
+	{
+	return(X509_NAME_hash(x->cert_info->issuer));
+	}
+
+#ifndef OPENSSL_NO_MD5
+unsigned long X509_issuer_name_hash_old(X509 *x)
+	{
+	return(X509_NAME_hash_old(x->cert_info->issuer));
+	}
+#endif
+
+X509_NAME *X509_get_subject_name(X509 *a)
+	{
+	return(a->cert_info->subject);
+	}
+
+ASN1_INTEGER *X509_get_serialNumber(X509 *a)
+	{
+	return(a->cert_info->serialNumber);
+	}
+
+unsigned long X509_subject_name_hash(X509 *x)
+	{
+	return(X509_NAME_hash(x->cert_info->subject));
+	}
+
+#ifndef OPENSSL_NO_MD5
+unsigned long X509_subject_name_hash_old(X509 *x)
+	{
+	return(X509_NAME_hash_old(x->cert_info->subject));
+	}
+#endif
+
+#ifndef OPENSSL_NO_SHA
+/* Compare two certificates: they must be identical for
+ * this to work. NB: Although "cmp" operations are generally
+ * prototyped to take "const" arguments (eg. for use in
+ * STACKs), the way X509 handling is - these operations may
+ * involve ensuring the hashes are up-to-date and ensuring
+ * certain cert information is cached. So this is the point
+ * where the "depth-first" constification tree has to halt
+ * with an evil cast.
+ */
+int X509_cmp(const X509 *a, const X509 *b)
+{
+	/* ensure hash is valid */
+	X509_check_purpose((X509 *)a, -1, 0);
+	X509_check_purpose((X509 *)b, -1, 0);
+
+	return memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
+}
+#endif
+
+
+int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
+	{
+	int ret;
+
+	/* Ensure canonical encoding is present and up to date */
+
+	if (!a->canon_enc || a->modified)
+		{
+		ret = i2d_X509_NAME((X509_NAME *)a, NULL);
+		if (ret < 0)
+			return -2;
+		}
+
+	if (!b->canon_enc || b->modified)
+		{
+		ret = i2d_X509_NAME((X509_NAME *)b, NULL);
+		if (ret < 0)
+			return -2;
+		}
+
+	ret = a->canon_enclen - b->canon_enclen;
+
+	if (ret)
+		return ret;
+
+	return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
+
+	}
+
+unsigned long X509_NAME_hash(X509_NAME *x)
+	{
+	unsigned long ret=0;
+	unsigned char md[SHA_DIGEST_LENGTH];
+
+	/* Make sure X509_NAME structure contains valid cached encoding */
+	i2d_X509_NAME(x,NULL);
+	EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), NULL);
+
+	ret=(	((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
+		((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
+		)&0xffffffffL;
+	return(ret);
+	}
+
+
+#ifndef OPENSSL_NO_MD5
+/* I now DER encode the name and hash it.  Since I cache the DER encoding,
+ * this is reasonably efficient. */
+
+unsigned long X509_NAME_hash_old(X509_NAME *x)
+	{
+	unsigned long ret=0;
+	unsigned char md[16];
+
+	/* Make sure X509_NAME structure contains valid cached encoding */
+	i2d_X509_NAME(x,NULL);
+	EVP_Digest(x->bytes->data, x->bytes->length, md, NULL, EVP_md5(), NULL);
+
+	ret=(	((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
+		((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
+		)&0xffffffffL;
+	return(ret);
+	}
+#endif
+
+/* Search a stack of X509 for a match */
+X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
+		ASN1_INTEGER *serial)
+	{
+	int i;
+	X509_CINF cinf;
+	X509 x,*x509=NULL;
+
+	if(!sk) return NULL;
+
+	x.cert_info= &cinf;
+	cinf.serialNumber=serial;
+	cinf.issuer=name;
+
+	for (i=0; i<sk_X509_num(sk); i++)
+		{
+		x509=sk_X509_value(sk,i);
+		if (X509_issuer_and_serial_cmp(x509,&x) == 0)
+			return(x509);
+		}
+	return(NULL);
+	}
+
+X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name)
+	{
+	X509 *x509;
+	int i;
+
+	for (i=0; i<sk_X509_num(sk); i++)
+		{
+		x509=sk_X509_value(sk,i);
+		if (X509_NAME_cmp(X509_get_subject_name(x509),name) == 0)
+			return(x509);
+		}
+	return(NULL);
+	}
+
+EVP_PKEY *X509_get_pubkey(X509 *x)
+	{
+	if ((x == NULL) || (x->cert_info == NULL))
+		return(NULL);
+	return(X509_PUBKEY_get(x->cert_info->key));
+	}
+
+ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
+	{
+	if(!x) return NULL;
+	return x->cert_info->key->public_key;
+	}
+
+int X509_check_private_key(X509 *x, EVP_PKEY *k)
+	{
+	EVP_PKEY *xk;
+	int ret;
+
+	xk=X509_get_pubkey(x);
+
+	if (xk)
+		ret = EVP_PKEY_cmp(xk, k);
+	else
+		ret = -2;
+
+	switch (ret)
+		{
+	case 1:
+		break;
+	case 0:
+		X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
+		break;
+	case -1:
+		X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
+		break;
+	case -2:
+	        X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE);
+		}
+	if (xk)
+		EVP_PKEY_free(xk);
+	if (ret > 0)
+		return 1;
+	return 0;
+	}
diff --git a/openssl/crypto/x509/x509_d2.c b/openssl/crypto/x509/x509_d2.c
new file mode 100644
index 0000000..51410cf
--- /dev/null
+++ b/openssl/crypto/x509/x509_d2.c
@@ -0,0 +1,107 @@
+/* crypto/x509/x509_d2.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+
+#ifndef OPENSSL_NO_STDIO
+int X509_STORE_set_default_paths(X509_STORE *ctx)
+	{
+	X509_LOOKUP *lookup;
+
+	lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_file());
+	if (lookup == NULL) return(0);
+	X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
+
+	lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_hash_dir());
+	if (lookup == NULL) return(0);
+	X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
+	
+	/* clear any errors */
+	ERR_clear_error();
+
+	return(1);
+	}
+
+int X509_STORE_load_locations(X509_STORE *ctx, const char *file,
+		const char *path)
+	{
+	X509_LOOKUP *lookup;
+
+	if (file != NULL)
+		{
+		lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_file());
+		if (lookup == NULL) return(0);
+		if (X509_LOOKUP_load_file(lookup,file,X509_FILETYPE_PEM) != 1)
+		    return(0);
+		}
+	if (path != NULL)
+		{
+		lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_hash_dir());
+		if (lookup == NULL) return(0);
+		if (X509_LOOKUP_add_dir(lookup,path,X509_FILETYPE_PEM) != 1)
+		    return(0);
+		}
+	if ((path == NULL) && (file == NULL))
+		return(0);
+	return(1);
+	}
+
+#endif
diff --git a/openssl/crypto/x509/x509_def.c b/openssl/crypto/x509/x509_def.c
new file mode 100644
index 0000000..e0ac151
--- /dev/null
+++ b/openssl/crypto/x509/x509_def.c
@@ -0,0 +1,81 @@
+/* crypto/x509/x509_def.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+
+const char *X509_get_default_private_dir(void)
+	{ return(X509_PRIVATE_DIR); }
+	
+const char *X509_get_default_cert_area(void)
+	{ return(X509_CERT_AREA); }
+
+const char *X509_get_default_cert_dir(void)
+	{ return(X509_CERT_DIR); }
+
+const char *X509_get_default_cert_file(void)
+	{ return(X509_CERT_FILE); }
+
+const char *X509_get_default_cert_dir_env(void)
+	{ return(X509_CERT_DIR_EVP); }
+
+const char *X509_get_default_cert_file_env(void)
+	{ return(X509_CERT_FILE_EVP); }
+
diff --git a/openssl/crypto/x509/x509_err.c b/openssl/crypto/x509/x509_err.c
new file mode 100644
index 0000000..a01402f
--- /dev/null
+++ b/openssl/crypto/x509/x509_err.c
@@ -0,0 +1,164 @@
+/* crypto/x509/x509_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509,0,reason)
+
+static ERR_STRING_DATA X509_str_functs[]=
+	{
+{ERR_FUNC(X509_F_ADD_CERT_DIR),	"ADD_CERT_DIR"},
+{ERR_FUNC(X509_F_BY_FILE_CTRL),	"BY_FILE_CTRL"},
+{ERR_FUNC(X509_F_CHECK_POLICY),	"CHECK_POLICY"},
+{ERR_FUNC(X509_F_DIR_CTRL),	"DIR_CTRL"},
+{ERR_FUNC(X509_F_GET_CERT_BY_SUBJECT),	"GET_CERT_BY_SUBJECT"},
+{ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_DECODE),	"NETSCAPE_SPKI_b64_decode"},
+{ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_ENCODE),	"NETSCAPE_SPKI_b64_encode"},
+{ERR_FUNC(X509_F_X509AT_ADD1_ATTR),	"X509at_add1_attr"},
+{ERR_FUNC(X509_F_X509V3_ADD_EXT),	"X509v3_add_ext"},
+{ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_NID),	"X509_ATTRIBUTE_create_by_NID"},
+{ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ),	"X509_ATTRIBUTE_create_by_OBJ"},
+{ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT),	"X509_ATTRIBUTE_create_by_txt"},
+{ERR_FUNC(X509_F_X509_ATTRIBUTE_GET0_DATA),	"X509_ATTRIBUTE_get0_data"},
+{ERR_FUNC(X509_F_X509_ATTRIBUTE_SET1_DATA),	"X509_ATTRIBUTE_set1_data"},
+{ERR_FUNC(X509_F_X509_CHECK_PRIVATE_KEY),	"X509_check_private_key"},
+{ERR_FUNC(X509_F_X509_CRL_PRINT_FP),	"X509_CRL_print_fp"},
+{ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_NID),	"X509_EXTENSION_create_by_NID"},
+{ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_OBJ),	"X509_EXTENSION_create_by_OBJ"},
+{ERR_FUNC(X509_F_X509_GET_PUBKEY_PARAMETERS),	"X509_get_pubkey_parameters"},
+{ERR_FUNC(X509_F_X509_LOAD_CERT_CRL_FILE),	"X509_load_cert_crl_file"},
+{ERR_FUNC(X509_F_X509_LOAD_CERT_FILE),	"X509_load_cert_file"},
+{ERR_FUNC(X509_F_X509_LOAD_CRL_FILE),	"X509_load_crl_file"},
+{ERR_FUNC(X509_F_X509_NAME_ADD_ENTRY),	"X509_NAME_add_entry"},
+{ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_NID),	"X509_NAME_ENTRY_create_by_NID"},
+{ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT),	"X509_NAME_ENTRY_create_by_txt"},
+{ERR_FUNC(X509_F_X509_NAME_ENTRY_SET_OBJECT),	"X509_NAME_ENTRY_set_object"},
+{ERR_FUNC(X509_F_X509_NAME_ONELINE),	"X509_NAME_oneline"},
+{ERR_FUNC(X509_F_X509_NAME_PRINT),	"X509_NAME_print"},
+{ERR_FUNC(X509_F_X509_PRINT_EX_FP),	"X509_print_ex_fp"},
+{ERR_FUNC(X509_F_X509_PUBKEY_GET),	"X509_PUBKEY_get"},
+{ERR_FUNC(X509_F_X509_PUBKEY_SET),	"X509_PUBKEY_set"},
+{ERR_FUNC(X509_F_X509_REQ_CHECK_PRIVATE_KEY),	"X509_REQ_check_private_key"},
+{ERR_FUNC(X509_F_X509_REQ_PRINT_EX),	"X509_REQ_print_ex"},
+{ERR_FUNC(X509_F_X509_REQ_PRINT_FP),	"X509_REQ_print_fp"},
+{ERR_FUNC(X509_F_X509_REQ_TO_X509),	"X509_REQ_to_X509"},
+{ERR_FUNC(X509_F_X509_STORE_ADD_CERT),	"X509_STORE_add_cert"},
+{ERR_FUNC(X509_F_X509_STORE_ADD_CRL),	"X509_STORE_add_crl"},
+{ERR_FUNC(X509_F_X509_STORE_CTX_GET1_ISSUER),	"X509_STORE_CTX_get1_issuer"},
+{ERR_FUNC(X509_F_X509_STORE_CTX_INIT),	"X509_STORE_CTX_init"},
+{ERR_FUNC(X509_F_X509_STORE_CTX_NEW),	"X509_STORE_CTX_new"},
+{ERR_FUNC(X509_F_X509_STORE_CTX_PURPOSE_INHERIT),	"X509_STORE_CTX_purpose_inherit"},
+{ERR_FUNC(X509_F_X509_TO_X509_REQ),	"X509_to_X509_REQ"},
+{ERR_FUNC(X509_F_X509_TRUST_ADD),	"X509_TRUST_add"},
+{ERR_FUNC(X509_F_X509_TRUST_SET),	"X509_TRUST_set"},
+{ERR_FUNC(X509_F_X509_VERIFY_CERT),	"X509_verify_cert"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA X509_str_reasons[]=
+	{
+{ERR_REASON(X509_R_BAD_X509_FILETYPE)    ,"bad x509 filetype"},
+{ERR_REASON(X509_R_BASE64_DECODE_ERROR)  ,"base64 decode error"},
+{ERR_REASON(X509_R_CANT_CHECK_DH_KEY)    ,"cant check dh key"},
+{ERR_REASON(X509_R_CERT_ALREADY_IN_HASH_TABLE),"cert already in hash table"},
+{ERR_REASON(X509_R_ERR_ASN1_LIB)         ,"err asn1 lib"},
+{ERR_REASON(X509_R_INVALID_DIRECTORY)    ,"invalid directory"},
+{ERR_REASON(X509_R_INVALID_FIELD_NAME)   ,"invalid field name"},
+{ERR_REASON(X509_R_INVALID_TRUST)        ,"invalid trust"},
+{ERR_REASON(X509_R_KEY_TYPE_MISMATCH)    ,"key type mismatch"},
+{ERR_REASON(X509_R_KEY_VALUES_MISMATCH)  ,"key values mismatch"},
+{ERR_REASON(X509_R_LOADING_CERT_DIR)     ,"loading cert dir"},
+{ERR_REASON(X509_R_LOADING_DEFAULTS)     ,"loading defaults"},
+{ERR_REASON(X509_R_METHOD_NOT_SUPPORTED) ,"method not supported"},
+{ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY),"no cert set for us to verify"},
+{ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR),"public key decode error"},
+{ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR),"public key encode error"},
+{ERR_REASON(X509_R_SHOULD_RETRY)         ,"should retry"},
+{ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN),"unable to find parameters in chain"},
+{ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY),"unable to get certs public key"},
+{ERR_REASON(X509_R_UNKNOWN_KEY_TYPE)     ,"unknown key type"},
+{ERR_REASON(X509_R_UNKNOWN_NID)          ,"unknown nid"},
+{ERR_REASON(X509_R_UNKNOWN_PURPOSE_ID)   ,"unknown purpose id"},
+{ERR_REASON(X509_R_UNKNOWN_TRUST_ID)     ,"unknown trust id"},
+{ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM),"unsupported algorithm"},
+{ERR_REASON(X509_R_WRONG_LOOKUP_TYPE)    ,"wrong lookup type"},
+{ERR_REASON(X509_R_WRONG_TYPE)           ,"wrong type"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_X509_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(X509_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,X509_str_functs);
+		ERR_load_strings(0,X509_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/x509/x509_ext.c b/openssl/crypto/x509/x509_ext.c
new file mode 100644
index 0000000..e7fdacb
--- /dev/null
+++ b/openssl/crypto/x509/x509_ext.c
@@ -0,0 +1,210 @@
+/* crypto/x509/x509_ext.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/stack.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+
+int X509_CRL_get_ext_count(X509_CRL *x)
+	{
+	return(X509v3_get_ext_count(x->crl->extensions));
+	}
+
+int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos)
+	{
+	return(X509v3_get_ext_by_NID(x->crl->extensions,nid,lastpos));
+	}
+
+int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos)
+	{
+	return(X509v3_get_ext_by_OBJ(x->crl->extensions,obj,lastpos));
+	}
+
+int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos)
+	{
+	return(X509v3_get_ext_by_critical(x->crl->extensions,crit,lastpos));
+	}
+
+X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc)
+	{
+	return(X509v3_get_ext(x->crl->extensions,loc));
+	}
+
+X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc)
+	{
+	return(X509v3_delete_ext(x->crl->extensions,loc));
+	}
+
+void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx)
+{
+	return X509V3_get_d2i(x->crl->extensions, nid, crit, idx);
+}
+
+int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
+							unsigned long flags)
+{
+	return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags);
+}
+
+int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc)
+	{
+	return(X509v3_add_ext(&(x->crl->extensions),ex,loc) != NULL);
+	}
+
+int X509_get_ext_count(X509 *x)
+	{
+	return(X509v3_get_ext_count(x->cert_info->extensions));
+	}
+
+int X509_get_ext_by_NID(X509 *x, int nid, int lastpos)
+	{
+	return(X509v3_get_ext_by_NID(x->cert_info->extensions,nid,lastpos));
+	}
+
+int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos)
+	{
+	return(X509v3_get_ext_by_OBJ(x->cert_info->extensions,obj,lastpos));
+	}
+
+int X509_get_ext_by_critical(X509 *x, int crit, int lastpos)
+	{
+	return(X509v3_get_ext_by_critical(x->cert_info->extensions,crit,lastpos));
+	}
+
+X509_EXTENSION *X509_get_ext(X509 *x, int loc)
+	{
+	return(X509v3_get_ext(x->cert_info->extensions,loc));
+	}
+
+X509_EXTENSION *X509_delete_ext(X509 *x, int loc)
+	{
+	return(X509v3_delete_ext(x->cert_info->extensions,loc));
+	}
+
+int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc)
+	{
+	return(X509v3_add_ext(&(x->cert_info->extensions),ex,loc) != NULL);
+	}
+
+void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx)
+{
+	return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx);
+}
+
+int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
+							unsigned long flags)
+{
+	return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit,
+							flags);
+}
+
+int X509_REVOKED_get_ext_count(X509_REVOKED *x)
+	{
+	return(X509v3_get_ext_count(x->extensions));
+	}
+
+int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos)
+	{
+	return(X509v3_get_ext_by_NID(x->extensions,nid,lastpos));
+	}
+
+int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj,
+	     int lastpos)
+	{
+	return(X509v3_get_ext_by_OBJ(x->extensions,obj,lastpos));
+	}
+
+int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos)
+	{
+	return(X509v3_get_ext_by_critical(x->extensions,crit,lastpos));
+	}
+
+X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc)
+	{
+	return(X509v3_get_ext(x->extensions,loc));
+	}
+
+X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc)
+	{
+	return(X509v3_delete_ext(x->extensions,loc));
+	}
+
+int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc)
+	{
+	return(X509v3_add_ext(&(x->extensions),ex,loc) != NULL);
+	}
+
+void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx)
+{
+	return X509V3_get_d2i(x->extensions, nid, crit, idx);
+}
+
+int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
+							unsigned long flags)
+{
+	return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags);
+}
+
+IMPLEMENT_STACK_OF(X509_EXTENSION)
+IMPLEMENT_ASN1_SET_OF(X509_EXTENSION)
diff --git a/openssl/crypto/x509/x509_lu.c b/openssl/crypto/x509/x509_lu.c
new file mode 100644
index 0000000..3a6e04a
--- /dev/null
+++ b/openssl/crypto/x509/x509_lu.c
@@ -0,0 +1,716 @@
+/* crypto/x509/x509_lu.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
+	{
+	X509_LOOKUP *ret;
+
+	ret=(X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP));
+	if (ret == NULL) return NULL;
+
+	ret->init=0;
+	ret->skip=0;
+	ret->method=method;
+	ret->method_data=NULL;
+	ret->store_ctx=NULL;
+	if ((method->new_item != NULL) && !method->new_item(ret))
+		{
+		OPENSSL_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+void X509_LOOKUP_free(X509_LOOKUP *ctx)
+	{
+	if (ctx == NULL) return;
+	if (	(ctx->method != NULL) &&
+		(ctx->method->free != NULL))
+		ctx->method->free(ctx);
+	OPENSSL_free(ctx);
+	}
+
+int X509_LOOKUP_init(X509_LOOKUP *ctx)
+	{
+	if (ctx->method == NULL) return 0;
+	if (ctx->method->init != NULL)
+		return ctx->method->init(ctx);
+	else
+		return 1;
+	}
+
+int X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
+	{
+	if (ctx->method == NULL) return 0;
+	if (ctx->method->shutdown != NULL)
+		return ctx->method->shutdown(ctx);
+	else
+		return 1;
+	}
+
+int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
+	     char **ret)
+	{
+	if (ctx->method == NULL) return -1;
+	if (ctx->method->ctrl != NULL)
+		return ctx->method->ctrl(ctx,cmd,argc,argl,ret);
+	else
+		return 1;
+	}
+
+int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
+	     X509_OBJECT *ret)
+	{
+	if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
+		return X509_LU_FAIL;
+	if (ctx->skip) return 0;
+	return ctx->method->get_by_subject(ctx,type,name,ret);
+	}
+
+int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
+	     ASN1_INTEGER *serial, X509_OBJECT *ret)
+	{
+	if ((ctx->method == NULL) ||
+		(ctx->method->get_by_issuer_serial == NULL))
+		return X509_LU_FAIL;
+	return ctx->method->get_by_issuer_serial(ctx,type,name,serial,ret);
+	}
+
+int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
+	     unsigned char *bytes, int len, X509_OBJECT *ret)
+	{
+	if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
+		return X509_LU_FAIL;
+	return ctx->method->get_by_fingerprint(ctx,type,bytes,len,ret);
+	}
+
+int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len,
+	     X509_OBJECT *ret)
+	{
+	if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
+		return X509_LU_FAIL;
+	return ctx->method->get_by_alias(ctx,type,str,len,ret);
+	}
+
+  
+static int x509_object_cmp(const X509_OBJECT * const *a, const X509_OBJECT * const *b)
+  	{
+ 	int ret;
+
+ 	ret=((*a)->type - (*b)->type);
+ 	if (ret) return ret;
+ 	switch ((*a)->type)
+ 		{
+ 	case X509_LU_X509:
+ 		ret=X509_subject_name_cmp((*a)->data.x509,(*b)->data.x509);
+ 		break;
+ 	case X509_LU_CRL:
+ 		ret=X509_CRL_cmp((*a)->data.crl,(*b)->data.crl);
+ 		break;
+	default:
+		/* abort(); */
+		return 0;
+		}
+	return ret;
+	}
+
+X509_STORE *X509_STORE_new(void)
+	{
+	X509_STORE *ret;
+
+	if ((ret=(X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL)
+		return NULL;
+	ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
+	ret->cache=1;
+	ret->get_cert_methods=sk_X509_LOOKUP_new_null();
+	ret->verify=0;
+	ret->verify_cb=0;
+
+	if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
+		return NULL;
+
+	ret->get_issuer = 0;
+	ret->check_issued = 0;
+	ret->check_revocation = 0;
+	ret->get_crl = 0;
+	ret->check_crl = 0;
+	ret->cert_crl = 0;
+	ret->lookup_certs = 0;
+	ret->lookup_crls = 0;
+	ret->cleanup = 0;
+
+	if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data))
+		{
+		sk_X509_OBJECT_free(ret->objs);
+		OPENSSL_free(ret);
+		return NULL;
+		}
+
+	ret->references=1;
+	return ret;
+	}
+
+static void cleanup(X509_OBJECT *a)
+	{
+	if (a->type == X509_LU_X509)
+		{
+		X509_free(a->data.x509);
+		}
+	else if (a->type == X509_LU_CRL)
+		{
+		X509_CRL_free(a->data.crl);
+		}
+	else
+		{
+		/* abort(); */
+		}
+
+	OPENSSL_free(a);
+	}
+
+void X509_STORE_free(X509_STORE *vfy)
+	{
+	int i;
+	STACK_OF(X509_LOOKUP) *sk;
+	X509_LOOKUP *lu;
+
+	if (vfy == NULL)
+	    return;
+
+	sk=vfy->get_cert_methods;
+	for (i=0; i<sk_X509_LOOKUP_num(sk); i++)
+		{
+		lu=sk_X509_LOOKUP_value(sk,i);
+		X509_LOOKUP_shutdown(lu);
+		X509_LOOKUP_free(lu);
+		}
+	sk_X509_LOOKUP_free(sk);
+	sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
+
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data);
+	if (vfy->param)
+		X509_VERIFY_PARAM_free(vfy->param);
+	OPENSSL_free(vfy);
+	}
+
+X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
+	{
+	int i;
+	STACK_OF(X509_LOOKUP) *sk;
+	X509_LOOKUP *lu;
+
+	sk=v->get_cert_methods;
+	for (i=0; i<sk_X509_LOOKUP_num(sk); i++)
+		{
+		lu=sk_X509_LOOKUP_value(sk,i);
+		if (m == lu->method)
+			{
+			return lu;
+			}
+		}
+	/* a new one */
+	lu=X509_LOOKUP_new(m);
+	if (lu == NULL)
+		return NULL;
+	else
+		{
+		lu->store_ctx=v;
+		if (sk_X509_LOOKUP_push(v->get_cert_methods,lu))
+			return lu;
+		else
+			{
+			X509_LOOKUP_free(lu);
+			return NULL;
+			}
+		}
+	}
+
+int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
+	     X509_OBJECT *ret)
+	{
+	X509_STORE *ctx=vs->ctx;
+	X509_LOOKUP *lu;
+	X509_OBJECT stmp,*tmp;
+	int i,j;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+	tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name);
+	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+
+	if (tmp == NULL || type == X509_LU_CRL)
+		{
+		for (i=vs->current_method; i<sk_X509_LOOKUP_num(ctx->get_cert_methods); i++)
+			{
+			lu=sk_X509_LOOKUP_value(ctx->get_cert_methods,i);
+			j=X509_LOOKUP_by_subject(lu,type,name,&stmp);
+			if (j < 0)
+				{
+				vs->current_method=j;
+				return j;
+				}
+			else if (j)
+				{
+				tmp= &stmp;
+				break;
+				}
+			}
+		vs->current_method=0;
+		if (tmp == NULL)
+			return 0;
+		}
+
+/*	if (ret->data.ptr != NULL)
+		X509_OBJECT_free_contents(ret); */
+
+	ret->type=tmp->type;
+	ret->data.ptr=tmp->data.ptr;
+
+	X509_OBJECT_up_ref_count(ret);
+
+	return 1;
+	}
+
+int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
+	{
+	X509_OBJECT *obj;
+	int ret=1;
+
+	if (x == NULL) return 0;
+	obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
+	if (obj == NULL)
+		{
+		X509err(X509_F_X509_STORE_ADD_CERT,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	obj->type=X509_LU_X509;
+	obj->data.x509=x;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+
+	X509_OBJECT_up_ref_count(obj);
+
+	if (X509_OBJECT_retrieve_match(ctx->objs, obj))
+		{
+		X509_OBJECT_free_contents(obj);
+		OPENSSL_free(obj);
+		X509err(X509_F_X509_STORE_ADD_CERT,X509_R_CERT_ALREADY_IN_HASH_TABLE);
+		ret=0;
+		} 
+	else sk_X509_OBJECT_push(ctx->objs, obj);
+
+	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+
+	return ret;
+	}
+
+int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
+	{
+	X509_OBJECT *obj;
+	int ret=1;
+
+	if (x == NULL) return 0;
+	obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
+	if (obj == NULL)
+		{
+		X509err(X509_F_X509_STORE_ADD_CRL,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	obj->type=X509_LU_CRL;
+	obj->data.crl=x;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+
+	X509_OBJECT_up_ref_count(obj);
+
+	if (X509_OBJECT_retrieve_match(ctx->objs, obj))
+		{
+		X509_OBJECT_free_contents(obj);
+		OPENSSL_free(obj);
+		X509err(X509_F_X509_STORE_ADD_CRL,X509_R_CERT_ALREADY_IN_HASH_TABLE);
+		ret=0;
+		}
+	else sk_X509_OBJECT_push(ctx->objs, obj);
+
+	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+
+	return ret;
+	}
+
+void X509_OBJECT_up_ref_count(X509_OBJECT *a)
+	{
+	switch (a->type)
+		{
+	case X509_LU_X509:
+		CRYPTO_add(&a->data.x509->references,1,CRYPTO_LOCK_X509);
+		break;
+	case X509_LU_CRL:
+		CRYPTO_add(&a->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
+		break;
+		}
+	}
+
+void X509_OBJECT_free_contents(X509_OBJECT *a)
+	{
+	switch (a->type)
+		{
+	case X509_LU_X509:
+		X509_free(a->data.x509);
+		break;
+	case X509_LU_CRL:
+		X509_CRL_free(a->data.crl);
+		break;
+		}
+	}
+
+static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
+	     X509_NAME *name, int *pnmatch)
+	{
+	X509_OBJECT stmp;
+	X509 x509_s;
+	X509_CINF cinf_s;
+	X509_CRL crl_s;
+	X509_CRL_INFO crl_info_s;
+	int idx;
+
+	stmp.type=type;
+	switch (type)
+		{
+	case X509_LU_X509:
+		stmp.data.x509= &x509_s;
+		x509_s.cert_info= &cinf_s;
+		cinf_s.subject=name;
+		break;
+	case X509_LU_CRL:
+		stmp.data.crl= &crl_s;
+		crl_s.crl= &crl_info_s;
+		crl_info_s.issuer=name;
+		break;
+	default:
+		/* abort(); */
+		return -1;
+		}
+
+	idx = sk_X509_OBJECT_find(h,&stmp);
+	if (idx >= 0 && pnmatch)
+		{
+		int tidx;
+		const X509_OBJECT *tobj, *pstmp;
+		*pnmatch = 1;
+		pstmp = &stmp;
+		for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++)
+			{
+			tobj = sk_X509_OBJECT_value(h, tidx);
+			if (x509_object_cmp(&tobj, &pstmp))
+				break;
+			(*pnmatch)++;
+			}
+		}
+	return idx;
+	}
+
+
+int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
+	     X509_NAME *name)
+	{
+	return x509_object_idx_cnt(h, type, name, NULL);
+	}
+
+X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type,
+	     X509_NAME *name)
+	{
+	int idx;
+	idx = X509_OBJECT_idx_by_subject(h, type, name);
+	if (idx==-1) return NULL;
+	return sk_X509_OBJECT_value(h, idx);
+	}
+
+STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
+	{
+	int i, idx, cnt;
+	STACK_OF(X509) *sk;
+	X509 *x;
+	X509_OBJECT *obj;
+	sk = sk_X509_new_null();
+	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+	idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
+	if (idx < 0)
+		{
+		/* Nothing found in cache: do lookup to possibly add new
+		 * objects to cache
+		 */
+		X509_OBJECT xobj;
+		CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+		if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj))
+			{
+			sk_X509_free(sk);
+			return NULL;
+			}
+		X509_OBJECT_free_contents(&xobj);
+		CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+		idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_X509,nm, &cnt);
+		if (idx < 0)
+			{
+			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+			sk_X509_free(sk);
+			return NULL;
+			}
+		}
+	for (i = 0; i < cnt; i++, idx++)
+		{
+		obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
+		x = obj->data.x509;
+		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
+		if (!sk_X509_push(sk, x))
+			{
+			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+			X509_free(x);
+			sk_X509_pop_free(sk, X509_free);
+			return NULL;
+			}
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+	return sk;
+
+	}
+
+STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
+	{
+	int i, idx, cnt;
+	STACK_OF(X509_CRL) *sk;
+	X509_CRL *x;
+	X509_OBJECT *obj, xobj;
+	sk = sk_X509_CRL_new_null();
+	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+	/* Check cache first */
+	idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
+
+	/* Always do lookup to possibly add new CRLs to cache
+	 */
+	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+	if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj))
+		{
+		sk_X509_CRL_free(sk);
+		return NULL;
+		}
+	X509_OBJECT_free_contents(&xobj);
+	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+	idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_CRL, nm, &cnt);
+	if (idx < 0)
+		{
+		CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+		sk_X509_CRL_free(sk);
+		return NULL;
+		}
+
+	for (i = 0; i < cnt; i++, idx++)
+		{
+		obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
+		x = obj->data.crl;
+		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
+		if (!sk_X509_CRL_push(sk, x))
+			{
+			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+			X509_CRL_free(x);
+			sk_X509_CRL_pop_free(sk, X509_CRL_free);
+			return NULL;
+			}
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+	return sk;
+	}
+
+X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
+	{
+	int idx, i;
+	X509_OBJECT *obj;
+	idx = sk_X509_OBJECT_find(h, x);
+	if (idx == -1) return NULL;
+	if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
+		return sk_X509_OBJECT_value(h, idx);
+	for (i = idx; i < sk_X509_OBJECT_num(h); i++)
+		{
+		obj = sk_X509_OBJECT_value(h, i);
+		if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
+			return NULL;
+		if (x->type == X509_LU_X509)
+			{
+			if (!X509_cmp(obj->data.x509, x->data.x509))
+				return obj;
+			}
+		else if (x->type == X509_LU_CRL)
+			{
+			if (!X509_CRL_match(obj->data.crl, x->data.crl))
+				return obj;
+			}
+		else
+			return obj;
+		}
+	return NULL;
+	}
+
+
+/* Try to get issuer certificate from store. Due to limitations
+ * of the API this can only retrieve a single certificate matching
+ * a given subject name. However it will fill the cache with all
+ * matching certificates, so we can examine the cache for all
+ * matches.
+ *
+ * Return values are:
+ *  1 lookup successful.
+ *  0 certificate not found.
+ * -1 some other error.
+ */
+int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
+	{
+	X509_NAME *xn;
+	X509_OBJECT obj, *pobj;
+	int i, ok, idx, ret;
+	xn=X509_get_issuer_name(x);
+	ok=X509_STORE_get_by_subject(ctx,X509_LU_X509,xn,&obj);
+	if (ok != X509_LU_X509)
+		{
+		if (ok == X509_LU_RETRY)
+			{
+			X509_OBJECT_free_contents(&obj);
+			X509err(X509_F_X509_STORE_CTX_GET1_ISSUER,X509_R_SHOULD_RETRY);
+			return -1;
+			}
+		else if (ok != X509_LU_FAIL)
+			{
+			X509_OBJECT_free_contents(&obj);
+			/* not good :-(, break anyway */
+			return -1;
+			}
+		return 0;
+		}
+	/* If certificate matches all OK */
+	if (ctx->check_issued(ctx, x, obj.data.x509))
+		{
+		*issuer = obj.data.x509;
+		return 1;
+		}
+	X509_OBJECT_free_contents(&obj);
+
+	/* Else find index of first cert accepted by 'check_issued' */
+	ret = 0;
+	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+	idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
+	if (idx != -1) /* should be true as we've had at least one match */
+		{
+		/* Look through all matching certs for suitable issuer */
+		for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++)
+			{
+			pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
+			/* See if we've run past the matches */
+			if (pobj->type != X509_LU_X509)
+				break;
+			if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
+				break;
+			if (ctx->check_issued(ctx, x, pobj->data.x509))
+				{
+				*issuer = pobj->data.x509;
+				X509_OBJECT_up_ref_count(pobj);
+				ret = 1;
+				break;
+				}
+			}
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+	return ret;
+	}
+
+int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
+	{
+	return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
+	}
+
+int X509_STORE_set_depth(X509_STORE *ctx, int depth)
+	{
+	X509_VERIFY_PARAM_set_depth(ctx->param, depth);
+	return 1;
+	}
+
+int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
+	{
+	return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
+	}
+
+int X509_STORE_set_trust(X509_STORE *ctx, int trust)
+	{
+	return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
+	}
+
+int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
+	{
+	return X509_VERIFY_PARAM_set1(ctx->param, param);
+	}
+
+void X509_STORE_set_verify_cb(X509_STORE *ctx,
+				  int (*verify_cb)(int, X509_STORE_CTX *))
+	{
+	ctx->verify_cb = verify_cb;
+	}
+
+IMPLEMENT_STACK_OF(X509_LOOKUP)
+IMPLEMENT_STACK_OF(X509_OBJECT)
diff --git a/openssl/crypto/x509/x509_obj.c b/openssl/crypto/x509/x509_obj.c
new file mode 100644
index 0000000..21fed9f
--- /dev/null
+++ b/openssl/crypto/x509/x509_obj.c
@@ -0,0 +1,226 @@
+/* crypto/x509/x509_obj.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/buffer.h>
+
+char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
+	{
+	X509_NAME_ENTRY *ne;
+int i;
+	int n,lold,l,l1,l2,num,j,type;
+	const char *s;
+	char *p;
+	unsigned char *q;
+	BUF_MEM *b=NULL;
+	static const char hex[17]="0123456789ABCDEF";
+	int gs_doit[4];
+	char tmp_buf[80];
+#ifdef CHARSET_EBCDIC
+	char ebcdic_buf[1024];
+#endif
+
+	if (buf == NULL)
+		{
+		if ((b=BUF_MEM_new()) == NULL) goto err;
+		if (!BUF_MEM_grow(b,200)) goto err;
+		b->data[0]='\0';
+		len=200;
+		}
+	if (a == NULL)
+	    {
+	    if(b)
+		{
+		buf=b->data;
+		OPENSSL_free(b);
+		}
+	    strncpy(buf,"NO X509_NAME",len);
+	    buf[len-1]='\0';
+	    return buf;
+	    }
+
+	len--; /* space for '\0' */
+	l=0;
+	for (i=0; i<sk_X509_NAME_ENTRY_num(a->entries); i++)
+		{
+		ne=sk_X509_NAME_ENTRY_value(a->entries,i);
+		n=OBJ_obj2nid(ne->object);
+		if ((n == NID_undef) || ((s=OBJ_nid2sn(n)) == NULL))
+			{
+			i2t_ASN1_OBJECT(tmp_buf,sizeof(tmp_buf),ne->object);
+			s=tmp_buf;
+			}
+		l1=strlen(s);
+
+		type=ne->value->type;
+		num=ne->value->length;
+		q=ne->value->data;
+#ifdef CHARSET_EBCDIC
+                if (type == V_ASN1_GENERALSTRING ||
+		    type == V_ASN1_VISIBLESTRING ||
+		    type == V_ASN1_PRINTABLESTRING ||
+		    type == V_ASN1_TELETEXSTRING ||
+		    type == V_ASN1_VISIBLESTRING ||
+		    type == V_ASN1_IA5STRING) {
+                        ascii2ebcdic(ebcdic_buf, q,
+				     (num > sizeof ebcdic_buf)
+				     ? sizeof ebcdic_buf : num);
+                        q=ebcdic_buf;
+		}
+#endif
+
+		if ((type == V_ASN1_GENERALSTRING) && ((num%4) == 0))
+			{
+			gs_doit[0]=gs_doit[1]=gs_doit[2]=gs_doit[3]=0;
+			for (j=0; j<num; j++)
+				if (q[j] != 0) gs_doit[j&3]=1;
+
+			if (gs_doit[0]|gs_doit[1]|gs_doit[2])
+				gs_doit[0]=gs_doit[1]=gs_doit[2]=gs_doit[3]=1;
+			else
+				{
+				gs_doit[0]=gs_doit[1]=gs_doit[2]=0;
+				gs_doit[3]=1;
+				}
+			}
+		else
+			gs_doit[0]=gs_doit[1]=gs_doit[2]=gs_doit[3]=1;
+
+		for (l2=j=0; j<num; j++)
+			{
+			if (!gs_doit[j&3]) continue;
+			l2++;
+#ifndef CHARSET_EBCDIC
+			if ((q[j] < ' ') || (q[j] > '~')) l2+=3;
+#else
+			if ((os_toascii[q[j]] < os_toascii[' ']) ||
+			    (os_toascii[q[j]] > os_toascii['~'])) l2+=3;
+#endif
+			}
+
+		lold=l;
+		l+=1+l1+1+l2;
+		if (b != NULL)
+			{
+			if (!BUF_MEM_grow(b,l+1)) goto err;
+			p= &(b->data[lold]);
+			}
+		else if (l > len)
+			{
+			break;
+			}
+		else
+			p= &(buf[lold]);
+		*(p++)='/';
+		memcpy(p,s,(unsigned int)l1); p+=l1;
+		*(p++)='=';
+
+#ifndef CHARSET_EBCDIC /* q was assigned above already. */
+		q=ne->value->data;
+#endif
+
+		for (j=0; j<num; j++)
+			{
+			if (!gs_doit[j&3]) continue;
+#ifndef CHARSET_EBCDIC
+			n=q[j];
+			if ((n < ' ') || (n > '~'))
+				{
+				*(p++)='\\';
+				*(p++)='x';
+				*(p++)=hex[(n>>4)&0x0f];
+				*(p++)=hex[n&0x0f];
+				}
+			else
+				*(p++)=n;
+#else
+			n=os_toascii[q[j]];
+			if ((n < os_toascii[' ']) ||
+			    (n > os_toascii['~']))
+				{
+				*(p++)='\\';
+				*(p++)='x';
+				*(p++)=hex[(n>>4)&0x0f];
+				*(p++)=hex[n&0x0f];
+				}
+			else
+				*(p++)=q[j];
+#endif
+			}
+		*p='\0';
+		}
+	if (b != NULL)
+		{
+		p=b->data;
+		OPENSSL_free(b);
+		}
+	else
+		p=buf;
+	if (i == 0)
+		*p = '\0';
+	return(p);
+err:
+	X509err(X509_F_X509_NAME_ONELINE,ERR_R_MALLOC_FAILURE);
+	if (b != NULL) BUF_MEM_free(b);
+	return(NULL);
+	}
+
diff --git a/openssl/crypto/x509/x509_r2x.c b/openssl/crypto/x509/x509_r2x.c
new file mode 100644
index 0000000..254a146
--- /dev/null
+++ b/openssl/crypto/x509/x509_r2x.c
@@ -0,0 +1,114 @@
+/* crypto/x509/x509_r2x.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+
+X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
+	{
+	X509 *ret=NULL;
+	X509_CINF *xi=NULL;
+	X509_NAME *xn;
+
+	if ((ret=X509_new()) == NULL)
+		{
+		X509err(X509_F_X509_REQ_TO_X509,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	/* duplicate the request */
+	xi=ret->cert_info;
+
+	if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0)
+		{
+		if ((xi->version=M_ASN1_INTEGER_new()) == NULL) goto err;
+		if (!ASN1_INTEGER_set(xi->version,2)) goto err;
+/*		xi->extensions=ri->attributes; <- bad, should not ever be done
+		ri->attributes=NULL; */
+		}
+
+	xn=X509_REQ_get_subject_name(r);
+	if (X509_set_subject_name(ret,X509_NAME_dup(xn)) == 0)
+		goto err;
+	if (X509_set_issuer_name(ret,X509_NAME_dup(xn)) == 0)
+		goto err;
+
+	if (X509_gmtime_adj(xi->validity->notBefore,0) == NULL)
+		goto err;
+	if (X509_gmtime_adj(xi->validity->notAfter,(long)60*60*24*days) == NULL)
+		goto err;
+
+	X509_set_pubkey(ret,X509_REQ_get_pubkey(r));
+
+	if (!X509_sign(ret,pkey,EVP_md5()))
+		goto err;
+	if (0)
+		{
+err:
+		X509_free(ret);
+		ret=NULL;
+		}
+	return(ret);
+	}
+
diff --git a/openssl/crypto/x509/x509_req.c b/openssl/crypto/x509/x509_req.c
new file mode 100644
index 0000000..48183dc
--- /dev/null
+++ b/openssl/crypto/x509/x509_req.c
@@ -0,0 +1,316 @@
+/* crypto/x509/x509_req.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/pem.h>
+
+X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
+	{
+	X509_REQ *ret;
+	X509_REQ_INFO *ri;
+	int i;
+	EVP_PKEY *pktmp;
+
+	ret=X509_REQ_new();
+	if (ret == NULL)
+		{
+		X509err(X509_F_X509_TO_X509_REQ,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	ri=ret->req_info;
+
+	ri->version->length=1;
+	ri->version->data=(unsigned char *)OPENSSL_malloc(1);
+	if (ri->version->data == NULL) goto err;
+	ri->version->data[0]=0; /* version == 0 */
+
+	if (!X509_REQ_set_subject_name(ret,X509_get_subject_name(x)))
+		goto err;
+
+	pktmp = X509_get_pubkey(x);
+	i=X509_REQ_set_pubkey(ret,pktmp);
+	EVP_PKEY_free(pktmp);
+	if (!i) goto err;
+
+	if (pkey != NULL)
+		{
+		if (!X509_REQ_sign(ret,pkey,md))
+			goto err;
+		}
+	return(ret);
+err:
+	X509_REQ_free(ret);
+	return(NULL);
+	}
+
+EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req)
+	{
+	if ((req == NULL) || (req->req_info == NULL))
+		return(NULL);
+	return(X509_PUBKEY_get(req->req_info->pubkey));
+	}
+
+int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
+	{
+	EVP_PKEY *xk=NULL;
+	int ok=0;
+
+	xk=X509_REQ_get_pubkey(x);
+	switch (EVP_PKEY_cmp(xk, k))
+		{
+	case 1:
+		ok=1;
+		break;
+	case 0:
+		X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
+		break;
+	case -1:
+		X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
+		break;
+	case -2:
+#ifndef OPENSSL_NO_EC
+		if (k->type == EVP_PKEY_EC)
+			{
+			X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, ERR_R_EC_LIB);
+			break;
+			}
+#endif
+#ifndef OPENSSL_NO_DH
+		if (k->type == EVP_PKEY_DH)
+			{
+			/* No idea */
+			X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_CANT_CHECK_DH_KEY);
+			break;
+			}
+#endif
+	        X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE);
+		}
+
+	EVP_PKEY_free(xk);
+	return(ok);
+	}
+
+/* It seems several organisations had the same idea of including a list of
+ * extensions in a certificate request. There are at least two OIDs that are
+ * used and there may be more: so the list is configurable.
+ */
+
+static int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef};
+
+static int *ext_nids = ext_nid_list;
+
+int X509_REQ_extension_nid(int req_nid)
+{
+	int i, nid;
+	for(i = 0; ; i++) {
+		nid = ext_nids[i];
+		if(nid == NID_undef) return 0;
+		else if (req_nid == nid) return 1;
+	}
+}
+
+int *X509_REQ_get_extension_nids(void)
+{
+	return ext_nids;
+}
+	
+void X509_REQ_set_extension_nids(int *nids)
+{
+	ext_nids = nids;
+}
+
+STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req)
+	{
+	X509_ATTRIBUTE *attr;
+	ASN1_TYPE *ext = NULL;
+	int idx, *pnid;
+	const unsigned char *p;
+
+	if ((req == NULL) || (req->req_info == NULL) || !ext_nids)
+		return(NULL);
+	for (pnid = ext_nids; *pnid != NID_undef; pnid++)
+		{
+		idx = X509_REQ_get_attr_by_NID(req, *pnid, -1);
+		if (idx == -1)
+			continue;
+		attr = X509_REQ_get_attr(req, idx);
+		if(attr->single) ext = attr->value.single;
+		else if(sk_ASN1_TYPE_num(attr->value.set))
+			ext = sk_ASN1_TYPE_value(attr->value.set, 0);
+		break;
+		}
+	if(!ext || (ext->type != V_ASN1_SEQUENCE))
+		return NULL;
+	p = ext->value.sequence->data;
+	return (STACK_OF(X509_EXTENSION) *)
+		ASN1_item_d2i(NULL, &p, ext->value.sequence->length,
+				ASN1_ITEM_rptr(X509_EXTENSIONS));
+}
+
+/* Add a STACK_OF extensions to a certificate request: allow alternative OIDs
+ * in case we want to create a non standard one.
+ */
+
+int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
+				int nid)
+{
+	ASN1_TYPE *at = NULL;
+	X509_ATTRIBUTE *attr = NULL;
+	if(!(at = ASN1_TYPE_new()) ||
+		!(at->value.sequence = ASN1_STRING_new())) goto err;
+
+	at->type = V_ASN1_SEQUENCE;
+	/* Generate encoding of extensions */
+	at->value.sequence->length = 
+			ASN1_item_i2d((ASN1_VALUE *)exts,
+				&at->value.sequence->data,
+				ASN1_ITEM_rptr(X509_EXTENSIONS));
+	if(!(attr = X509_ATTRIBUTE_new())) goto err;
+	if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err;
+	if(!sk_ASN1_TYPE_push(attr->value.set, at)) goto err;
+	at = NULL;
+	attr->single = 0;
+	attr->object = OBJ_nid2obj(nid);
+	if (!req->req_info->attributes)
+		{
+		if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null()))
+			goto err;
+		}
+	if(!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) goto err;
+	return 1;
+	err:
+	X509_ATTRIBUTE_free(attr);
+	ASN1_TYPE_free(at);
+	return 0;
+}
+/* This is the normal usage: use the "official" OID */
+int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts)
+{
+	return X509_REQ_add_extensions_nid(req, exts, NID_ext_req);
+}
+
+/* Request attribute functions */
+
+int X509_REQ_get_attr_count(const X509_REQ *req)
+{
+	return X509at_get_attr_count(req->req_info->attributes);
+}
+
+int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid,
+			  int lastpos)
+{
+	return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos);
+}
+
+int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
+			  int lastpos)
+{
+	return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos);
+}
+
+X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc)
+{
+	return X509at_get_attr(req->req_info->attributes, loc);
+}
+
+X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc)
+{
+	return X509at_delete_attr(req->req_info->attributes, loc);
+}
+
+int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr)
+{
+	if(X509at_add1_attr(&req->req_info->attributes, attr)) return 1;
+	return 0;
+}
+
+int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
+			const ASN1_OBJECT *obj, int type,
+			const unsigned char *bytes, int len)
+{
+	if(X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj,
+				type, bytes, len)) return 1;
+	return 0;
+}
+
+int X509_REQ_add1_attr_by_NID(X509_REQ *req,
+			int nid, int type,
+			const unsigned char *bytes, int len)
+{
+	if(X509at_add1_attr_by_NID(&req->req_info->attributes, nid,
+				type, bytes, len)) return 1;
+	return 0;
+}
+
+int X509_REQ_add1_attr_by_txt(X509_REQ *req,
+			const char *attrname, int type,
+			const unsigned char *bytes, int len)
+{
+	if(X509at_add1_attr_by_txt(&req->req_info->attributes, attrname,
+				type, bytes, len)) return 1;
+	return 0;
+}
diff --git a/openssl/crypto/x509/x509_set.c b/openssl/crypto/x509/x509_set.c
new file mode 100644
index 0000000..4b94fc5
--- /dev/null
+++ b/openssl/crypto/x509/x509_set.c
@@ -0,0 +1,150 @@
+/* crypto/x509/x509_set.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+int X509_set_version(X509 *x, long version)
+	{
+	if (x == NULL) return(0);
+	if (x->cert_info->version == NULL)
+		{
+		if ((x->cert_info->version=M_ASN1_INTEGER_new()) == NULL)
+			return(0);
+		}
+	return(ASN1_INTEGER_set(x->cert_info->version,version));
+	}
+
+int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial)
+	{
+	ASN1_INTEGER *in;
+
+	if (x == NULL) return(0);
+	in=x->cert_info->serialNumber;
+	if (in != serial)
+		{
+		in=M_ASN1_INTEGER_dup(serial);
+		if (in != NULL)
+			{
+			M_ASN1_INTEGER_free(x->cert_info->serialNumber);
+			x->cert_info->serialNumber=in;
+			}
+		}
+	return(in != NULL);
+	}
+
+int X509_set_issuer_name(X509 *x, X509_NAME *name)
+	{
+	if ((x == NULL) || (x->cert_info == NULL)) return(0);
+	return(X509_NAME_set(&x->cert_info->issuer,name));
+	}
+
+int X509_set_subject_name(X509 *x, X509_NAME *name)
+	{
+	if ((x == NULL) || (x->cert_info == NULL)) return(0);
+	return(X509_NAME_set(&x->cert_info->subject,name));
+	}
+
+int X509_set_notBefore(X509 *x, const ASN1_TIME *tm)
+	{
+	ASN1_TIME *in;
+
+	if ((x == NULL) || (x->cert_info->validity == NULL)) return(0);
+	in=x->cert_info->validity->notBefore;
+	if (in != tm)
+		{
+		in=M_ASN1_TIME_dup(tm);
+		if (in != NULL)
+			{
+			M_ASN1_TIME_free(x->cert_info->validity->notBefore);
+			x->cert_info->validity->notBefore=in;
+			}
+		}
+	return(in != NULL);
+	}
+
+int X509_set_notAfter(X509 *x, const ASN1_TIME *tm)
+	{
+	ASN1_TIME *in;
+
+	if ((x == NULL) || (x->cert_info->validity == NULL)) return(0);
+	in=x->cert_info->validity->notAfter;
+	if (in != tm)
+		{
+		in=M_ASN1_TIME_dup(tm);
+		if (in != NULL)
+			{
+			M_ASN1_TIME_free(x->cert_info->validity->notAfter);
+			x->cert_info->validity->notAfter=in;
+			}
+		}
+	return(in != NULL);
+	}
+
+int X509_set_pubkey(X509 *x, EVP_PKEY *pkey)
+	{
+	if ((x == NULL) || (x->cert_info == NULL)) return(0);
+	return(X509_PUBKEY_set(&(x->cert_info->key),pkey));
+	}
+
+
+
diff --git a/openssl/crypto/x509/x509_trs.c b/openssl/crypto/x509/x509_trs.c
new file mode 100644
index 0000000..a6cb9c8
--- /dev/null
+++ b/openssl/crypto/x509/x509_trs.c
@@ -0,0 +1,288 @@
+/* x509_trs.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509v3.h>
+
+
+static int tr_cmp(const X509_TRUST * const *a,
+		const X509_TRUST * const *b);
+static void trtable_free(X509_TRUST *p);
+
+static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags);
+static int trust_1oid(X509_TRUST *trust, X509 *x, int flags);
+static int trust_compat(X509_TRUST *trust, X509 *x, int flags);
+
+static int obj_trust(int id, X509 *x, int flags);
+static int (*default_trust)(int id, X509 *x, int flags) = obj_trust;
+
+/* WARNING: the following table should be kept in order of trust
+ * and without any gaps so we can just subtract the minimum trust
+ * value to get an index into the table
+ */
+
+static X509_TRUST trstandard[] = {
+{X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL},
+{X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth, NULL},
+{X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Server", NID_server_auth, NULL},
+{X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, NULL},
+{X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign, NULL},
+{X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign, NULL},
+{X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, NULL},
+{X509_TRUST_TSA, 0, trust_1oidany, "TSA server", NID_time_stamp, NULL}
+};
+
+#define X509_TRUST_COUNT	(sizeof(trstandard)/sizeof(X509_TRUST))
+
+IMPLEMENT_STACK_OF(X509_TRUST)
+
+static STACK_OF(X509_TRUST) *trtable = NULL;
+
+static int tr_cmp(const X509_TRUST * const *a,
+		const X509_TRUST * const *b)
+{
+	return (*a)->trust - (*b)->trust;
+}
+
+int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int)
+{
+	int (*oldtrust)(int , X509 *, int);
+	oldtrust = default_trust;
+	default_trust = trust;
+	return oldtrust;
+}
+
+
+int X509_check_trust(X509 *x, int id, int flags)
+{
+	X509_TRUST *pt;
+	int idx;
+	if(id == -1) return 1;
+	idx = X509_TRUST_get_by_id(id);
+	if(idx == -1) return default_trust(id, x, flags);
+	pt = X509_TRUST_get0(idx);
+	return pt->check_trust(pt, x, flags);
+}
+
+int X509_TRUST_get_count(void)
+{
+	if(!trtable) return X509_TRUST_COUNT;
+	return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT;
+}
+
+X509_TRUST * X509_TRUST_get0(int idx)
+{
+	if(idx < 0) return NULL;
+	if(idx < (int)X509_TRUST_COUNT) return trstandard + idx;
+	return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT);
+}
+
+int X509_TRUST_get_by_id(int id)
+{
+	X509_TRUST tmp;
+	int idx;
+	if((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX))
+				 return id - X509_TRUST_MIN;
+	tmp.trust = id;
+	if(!trtable) return -1;
+	idx = sk_X509_TRUST_find(trtable, &tmp);
+	if(idx == -1) return -1;
+	return idx + X509_TRUST_COUNT;
+}
+
+int X509_TRUST_set(int *t, int trust)
+{
+	if(X509_TRUST_get_by_id(trust) == -1) {
+		X509err(X509_F_X509_TRUST_SET, X509_R_INVALID_TRUST);
+		return 0;
+	}
+	*t = trust;
+	return 1;
+}
+
+int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
+					char *name, int arg1, void *arg2)
+{
+	int idx;
+	X509_TRUST *trtmp;
+	/* This is set according to what we change: application can't set it */
+	flags &= ~X509_TRUST_DYNAMIC;
+	/* This will always be set for application modified trust entries */
+	flags |= X509_TRUST_DYNAMIC_NAME;
+	/* Get existing entry if any */
+	idx = X509_TRUST_get_by_id(id);
+	/* Need a new entry */
+	if(idx == -1) {
+		if(!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) {
+			X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		trtmp->flags = X509_TRUST_DYNAMIC;
+	} else trtmp = X509_TRUST_get0(idx);
+
+	/* OPENSSL_free existing name if dynamic */
+	if(trtmp->flags & X509_TRUST_DYNAMIC_NAME) OPENSSL_free(trtmp->name);
+	/* dup supplied name */
+	if(!(trtmp->name = BUF_strdup(name))) {
+		X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	/* Keep the dynamic flag of existing entry */
+	trtmp->flags &= X509_TRUST_DYNAMIC;
+	/* Set all other flags */
+	trtmp->flags |= flags;
+
+	trtmp->trust = id;
+	trtmp->check_trust = ck;
+	trtmp->arg1 = arg1;
+	trtmp->arg2 = arg2;
+
+	/* If its a new entry manage the dynamic table */
+	if(idx == -1) {
+		if(!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) {
+			X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		if (!sk_X509_TRUST_push(trtable, trtmp)) {
+			X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+	}
+	return 1;
+}
+
+static void trtable_free(X509_TRUST *p)
+	{
+	if(!p) return;
+	if (p->flags & X509_TRUST_DYNAMIC) 
+		{
+		if (p->flags & X509_TRUST_DYNAMIC_NAME)
+			OPENSSL_free(p->name);
+		OPENSSL_free(p);
+		}
+	}
+
+void X509_TRUST_cleanup(void)
+{
+	unsigned int i;
+	for(i = 0; i < X509_TRUST_COUNT; i++) trtable_free(trstandard + i);
+	sk_X509_TRUST_pop_free(trtable, trtable_free);
+	trtable = NULL;
+}
+
+int X509_TRUST_get_flags(X509_TRUST *xp)
+{
+	return xp->flags;
+}
+
+char *X509_TRUST_get0_name(X509_TRUST *xp)
+{
+	return xp->name;
+}
+
+int X509_TRUST_get_trust(X509_TRUST *xp)
+{
+	return xp->trust;
+}
+
+static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags)
+{
+	if(x->aux && (x->aux->trust || x->aux->reject))
+		return obj_trust(trust->arg1, x, flags);
+	/* we don't have any trust settings: for compatibility
+	 * we return trusted if it is self signed
+	 */
+	return trust_compat(trust, x, flags);
+}
+
+static int trust_1oid(X509_TRUST *trust, X509 *x, int flags)
+{
+	if(x->aux) return obj_trust(trust->arg1, x, flags);
+	return X509_TRUST_UNTRUSTED;
+}
+
+static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
+{
+	X509_check_purpose(x, -1, 0);
+	if(x->ex_flags & EXFLAG_SS) return X509_TRUST_TRUSTED;
+	else return X509_TRUST_UNTRUSTED;
+}
+
+static int obj_trust(int id, X509 *x, int flags)
+{
+	ASN1_OBJECT *obj;
+	int i;
+	X509_CERT_AUX *ax;
+	ax = x->aux;
+	if(!ax) return X509_TRUST_UNTRUSTED;
+	if(ax->reject) {
+		for(i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) {
+			obj = sk_ASN1_OBJECT_value(ax->reject, i);
+			if(OBJ_obj2nid(obj) == id) return X509_TRUST_REJECTED;
+		}
+	}	
+	if(ax->trust) {
+		for(i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) {
+			obj = sk_ASN1_OBJECT_value(ax->trust, i);
+			if(OBJ_obj2nid(obj) == id) return X509_TRUST_TRUSTED;
+		}
+	}
+	return X509_TRUST_UNTRUSTED;
+}
+
diff --git a/openssl/crypto/x509/x509_txt.c b/openssl/crypto/x509/x509_txt.c
new file mode 100644
index 0000000..c44f753
--- /dev/null
+++ b/openssl/crypto/x509/x509_txt.c
@@ -0,0 +1,193 @@
+/* crypto/x509/x509_txt.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+
+const char *X509_verify_cert_error_string(long n)
+	{
+	static char buf[100];
+
+	switch ((int)n)
+		{
+	case X509_V_OK:
+		return("ok");
+	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+		return("unable to get issuer certificate");
+	case X509_V_ERR_UNABLE_TO_GET_CRL:
+		return("unable to get certificate CRL");
+	case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
+		return("unable to decrypt certificate's signature");
+	case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
+		return("unable to decrypt CRL's signature");
+	case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
+		return("unable to decode issuer public key");
+	case X509_V_ERR_CERT_SIGNATURE_FAILURE:
+		return("certificate signature failure");
+	case X509_V_ERR_CRL_SIGNATURE_FAILURE:
+		return("CRL signature failure");
+	case X509_V_ERR_CERT_NOT_YET_VALID:
+		return("certificate is not yet valid");
+	case X509_V_ERR_CRL_NOT_YET_VALID:
+		return("CRL is not yet valid");
+	case X509_V_ERR_CERT_HAS_EXPIRED:
+		return("certificate has expired");
+	case X509_V_ERR_CRL_HAS_EXPIRED:
+		return("CRL has expired");
+	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+		return("format error in certificate's notBefore field");
+	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+		return("format error in certificate's notAfter field");
+	case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
+		return("format error in CRL's lastUpdate field");
+	case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
+		return("format error in CRL's nextUpdate field");
+	case X509_V_ERR_OUT_OF_MEM:
+		return("out of memory");
+	case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+		return("self signed certificate");
+	case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+		return("self signed certificate in certificate chain");
+	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
+		return("unable to get local issuer certificate");
+	case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
+		return("unable to verify the first certificate");
+	case X509_V_ERR_CERT_CHAIN_TOO_LONG:
+		return("certificate chain too long");
+	case X509_V_ERR_CERT_REVOKED:
+		return("certificate revoked");
+	case X509_V_ERR_INVALID_CA:
+		return ("invalid CA certificate");
+	case X509_V_ERR_INVALID_NON_CA:
+		return ("invalid non-CA certificate (has CA markings)");
+	case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+		return ("path length constraint exceeded");
+	case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
+		return("proxy path length constraint exceeded");
+	case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
+		return("proxy certificates not allowed, please set the appropriate flag");
+	case X509_V_ERR_INVALID_PURPOSE:
+		return ("unsupported certificate purpose");
+	case X509_V_ERR_CERT_UNTRUSTED:
+		return ("certificate not trusted");
+	case X509_V_ERR_CERT_REJECTED:
+		return ("certificate rejected");
+	case X509_V_ERR_APPLICATION_VERIFICATION:
+		return("application verification failure");
+	case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
+		return("subject issuer mismatch");
+	case X509_V_ERR_AKID_SKID_MISMATCH:
+		return("authority and subject key identifier mismatch");
+	case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
+		return("authority and issuer serial number mismatch");
+	case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
+		return("key usage does not include certificate signing");
+	case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
+		return("unable to get CRL issuer certificate");
+	case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
+		return("unhandled critical extension");
+	case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
+		return("key usage does not include CRL signing");
+	case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
+		return("key usage does not include digital signature");
+	case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
+		return("unhandled critical CRL extension");
+	case X509_V_ERR_INVALID_EXTENSION:
+		return("invalid or inconsistent certificate extension");
+	case X509_V_ERR_INVALID_POLICY_EXTENSION:
+		return("invalid or inconsistent certificate policy extension");
+	case X509_V_ERR_NO_EXPLICIT_POLICY:
+		return("no explicit policy");
+	case X509_V_ERR_DIFFERENT_CRL_SCOPE:
+	return("Different CRL scope");
+	case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE:
+	return("Unsupported extension feature");
+ 	case X509_V_ERR_UNNESTED_RESOURCE:
+ 		return("RFC 3779 resource not subset of parent's resources");
+
+	case X509_V_ERR_PERMITTED_VIOLATION:
+		return("permitted subtree violation");
+	case X509_V_ERR_EXCLUDED_VIOLATION:
+		return("excluded subtree violation");
+	case X509_V_ERR_SUBTREE_MINMAX:
+		return("name constraints minimum and maximum not supported");
+	case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:
+		return("unsupported name constraint type");
+	case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX:
+		return("unsupported or invalid name constraint syntax");
+	case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX:
+		return("unsupported or invalid name syntax");
+	case X509_V_ERR_CRL_PATH_VALIDATION_ERROR:
+		return("CRL path validation error");
+
+	default:
+		BIO_snprintf(buf,sizeof buf,"error number %ld",n);
+		return(buf);
+		}
+	}
+
+
diff --git a/openssl/crypto/x509/x509_v3.c b/openssl/crypto/x509/x509_v3.c
new file mode 100644
index 0000000..42e6f0a
--- /dev/null
+++ b/openssl/crypto/x509/x509_v3.c
@@ -0,0 +1,274 @@
+/* crypto/x509/x509_v3.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/stack.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x)
+	{
+	if (x == NULL) return(0);
+	return(sk_X509_EXTENSION_num(x));
+	}
+
+int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid,
+			  int lastpos)
+	{
+	ASN1_OBJECT *obj;
+
+	obj=OBJ_nid2obj(nid);
+	if (obj == NULL) return(-2);
+	return(X509v3_get_ext_by_OBJ(x,obj,lastpos));
+	}
+
+int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, ASN1_OBJECT *obj,
+			  int lastpos)
+	{
+	int n;
+	X509_EXTENSION *ex;
+
+	if (sk == NULL) return(-1);
+	lastpos++;
+	if (lastpos < 0)
+		lastpos=0;
+	n=sk_X509_EXTENSION_num(sk);
+	for ( ; lastpos < n; lastpos++)
+		{
+		ex=sk_X509_EXTENSION_value(sk,lastpos);
+		if (OBJ_cmp(ex->object,obj) == 0)
+			return(lastpos);
+		}
+	return(-1);
+	}
+
+int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit,
+			       int lastpos)
+	{
+	int n;
+	X509_EXTENSION *ex;
+
+	if (sk == NULL) return(-1);
+	lastpos++;
+	if (lastpos < 0)
+		lastpos=0;
+	n=sk_X509_EXTENSION_num(sk);
+	for ( ; lastpos < n; lastpos++)
+		{
+		ex=sk_X509_EXTENSION_value(sk,lastpos);
+		if (	((ex->critical > 0) && crit) ||
+			((ex->critical <= 0) && !crit))
+			return(lastpos);
+		}
+	return(-1);
+	}
+
+X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc)
+	{
+	if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0)
+		return NULL;
+	else
+		return sk_X509_EXTENSION_value(x,loc);
+	}
+
+X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc)
+	{
+	X509_EXTENSION *ret;
+
+	if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0)
+		return(NULL);
+	ret=sk_X509_EXTENSION_delete(x,loc);
+	return(ret);
+	}
+
+STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
+					 X509_EXTENSION *ex, int loc)
+	{
+	X509_EXTENSION *new_ex=NULL;
+	int n;
+	STACK_OF(X509_EXTENSION) *sk=NULL;
+
+	if (x == NULL)
+		{
+		X509err(X509_F_X509V3_ADD_EXT,ERR_R_PASSED_NULL_PARAMETER);
+		goto err2;
+		}
+
+	if (*x == NULL)
+		{
+		if ((sk=sk_X509_EXTENSION_new_null()) == NULL)
+			goto err;
+		}
+	else
+		sk= *x;
+
+	n=sk_X509_EXTENSION_num(sk);
+	if (loc > n) loc=n;
+	else if (loc < 0) loc=n;
+
+	if ((new_ex=X509_EXTENSION_dup(ex)) == NULL)
+		goto err2;
+	if (!sk_X509_EXTENSION_insert(sk,new_ex,loc))
+		goto err;
+	if (*x == NULL)
+		*x=sk;
+	return(sk);
+err:
+	X509err(X509_F_X509V3_ADD_EXT,ERR_R_MALLOC_FAILURE);
+err2:
+	if (new_ex != NULL) X509_EXTENSION_free(new_ex);
+	if (sk != NULL) sk_X509_EXTENSION_free(sk);
+	return(NULL);
+	}
+
+X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid,
+	     int crit, ASN1_OCTET_STRING *data)
+	{
+	ASN1_OBJECT *obj;
+	X509_EXTENSION *ret;
+
+	obj=OBJ_nid2obj(nid);
+	if (obj == NULL)
+		{
+		X509err(X509_F_X509_EXTENSION_CREATE_BY_NID,X509_R_UNKNOWN_NID);
+		return(NULL);
+		}
+	ret=X509_EXTENSION_create_by_OBJ(ex,obj,crit,data);
+	if (ret == NULL) ASN1_OBJECT_free(obj);
+	return(ret);
+	}
+
+X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
+	     ASN1_OBJECT *obj, int crit, ASN1_OCTET_STRING *data)
+	{
+	X509_EXTENSION *ret;
+
+	if ((ex == NULL) || (*ex == NULL))
+		{
+		if ((ret=X509_EXTENSION_new()) == NULL)
+			{
+			X509err(X509_F_X509_EXTENSION_CREATE_BY_OBJ,ERR_R_MALLOC_FAILURE);
+			return(NULL);
+			}
+		}
+	else
+		ret= *ex;
+
+	if (!X509_EXTENSION_set_object(ret,obj))
+		goto err;
+	if (!X509_EXTENSION_set_critical(ret,crit))
+		goto err;
+	if (!X509_EXTENSION_set_data(ret,data))
+		goto err;
+	
+	if ((ex != NULL) && (*ex == NULL)) *ex=ret;
+	return(ret);
+err:
+	if ((ex == NULL) || (ret != *ex))
+		X509_EXTENSION_free(ret);
+	return(NULL);
+	}
+
+int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj)
+	{
+	if ((ex == NULL) || (obj == NULL))
+		return(0);
+	ASN1_OBJECT_free(ex->object);
+	ex->object=OBJ_dup(obj);
+	return(1);
+	}
+
+int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit)
+	{
+	if (ex == NULL) return(0);
+	ex->critical=(crit)?0xFF:-1;
+	return(1);
+	}
+
+int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data)
+	{
+	int i;
+
+	if (ex == NULL) return(0);
+	i=M_ASN1_OCTET_STRING_set(ex->value,data->data,data->length);
+	if (!i) return(0);
+	return(1);
+	}
+
+ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex)
+	{
+	if (ex == NULL) return(NULL);
+	return(ex->object);
+	}
+
+ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex)
+	{
+	if (ex == NULL) return(NULL);
+	return(ex->value);
+	}
+
+int X509_EXTENSION_get_critical(X509_EXTENSION *ex)
+	{
+	if (ex == NULL) return(0);
+	if(ex->critical > 0) return 1;
+	return 0;
+	}
diff --git a/openssl/crypto/x509/x509_vfy.c b/openssl/crypto/x509/x509_vfy.c
new file mode 100644
index 0000000..701ec56
--- /dev/null
+++ b/openssl/crypto/x509/x509_vfy.c
@@ -0,0 +1,2219 @@
+/* crypto/x509/x509_vfy.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include "cryptlib.h"
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/objects.h>
+
+/* CRL score values */
+
+/* No unhandled critical extensions */
+
+#define CRL_SCORE_NOCRITICAL	0x100
+
+/* certificate is within CRL scope */
+
+#define CRL_SCORE_SCOPE		0x080
+
+/* CRL times valid */
+
+#define CRL_SCORE_TIME		0x040
+
+/* Issuer name matches certificate */
+
+#define CRL_SCORE_ISSUER_NAME	0x020
+
+/* If this score or above CRL is probably valid */
+
+#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE)
+
+/* CRL issuer is certificate issuer */
+
+#define CRL_SCORE_ISSUER_CERT	0x018
+
+/* CRL issuer is on certificate path */
+
+#define CRL_SCORE_SAME_PATH	0x008
+
+/* CRL issuer matches CRL AKID */
+
+#define CRL_SCORE_AKID		0x004
+
+/* Have a delta CRL with valid times */
+
+#define CRL_SCORE_TIME_DELTA	0x002
+
+static int null_callback(int ok,X509_STORE_CTX *e);
+static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
+static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
+static int check_chain_extensions(X509_STORE_CTX *ctx);
+static int check_name_constraints(X509_STORE_CTX *ctx);
+static int check_trust(X509_STORE_CTX *ctx);
+static int check_revocation(X509_STORE_CTX *ctx);
+static int check_cert(X509_STORE_CTX *ctx);
+static int check_policy(X509_STORE_CTX *ctx);
+
+static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
+			unsigned int *preasons,
+			X509_CRL *crl, X509 *x);
+static int get_crl_delta(X509_STORE_CTX *ctx,
+				X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x);
+static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score,
+			X509_CRL *base, STACK_OF(X509_CRL) *crls);
+static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
+				X509 **pissuer, int *pcrl_score);
+static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
+				unsigned int *preasons);
+static int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
+static int check_crl_chain(X509_STORE_CTX *ctx,
+			STACK_OF(X509) *cert_path,
+			STACK_OF(X509) *crl_path);
+
+static int internal_verify(X509_STORE_CTX *ctx);
+const char X509_version[]="X.509" OPENSSL_VERSION_PTEXT;
+
+
+static int null_callback(int ok, X509_STORE_CTX *e)
+	{
+	return ok;
+	}
+
+#if 0
+static int x509_subject_cmp(X509 **a, X509 **b)
+	{
+	return X509_subject_name_cmp(*a,*b);
+	}
+#endif
+
+int X509_verify_cert(X509_STORE_CTX *ctx)
+	{
+	X509 *x,*xtmp,*chain_ss=NULL;
+	X509_NAME *xn;
+	int bad_chain = 0;
+	X509_VERIFY_PARAM *param = ctx->param;
+	int depth,i,ok=0;
+	int num;
+	int (*cb)(int xok,X509_STORE_CTX *xctx);
+	STACK_OF(X509) *sktmp=NULL;
+	if (ctx->cert == NULL)
+		{
+		X509err(X509_F_X509_VERIFY_CERT,X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
+		return -1;
+		}
+
+	cb=ctx->verify_cb;
+
+	/* first we make sure the chain we are going to build is
+	 * present and that the first entry is in place */
+	if (ctx->chain == NULL)
+		{
+		if (	((ctx->chain=sk_X509_new_null()) == NULL) ||
+			(!sk_X509_push(ctx->chain,ctx->cert)))
+			{
+			X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
+			goto end;
+			}
+		CRYPTO_add(&ctx->cert->references,1,CRYPTO_LOCK_X509);
+		ctx->last_untrusted=1;
+		}
+
+	/* We use a temporary STACK so we can chop and hack at it */
+	if (ctx->untrusted != NULL
+	    && (sktmp=sk_X509_dup(ctx->untrusted)) == NULL)
+		{
+		X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
+		goto end;
+		}
+
+	num=sk_X509_num(ctx->chain);
+	x=sk_X509_value(ctx->chain,num-1);
+	depth=param->depth;
+
+
+	for (;;)
+		{
+		/* If we have enough, we break */
+		if (depth < num) break; /* FIXME: If this happens, we should take
+		                         * note of it and, if appropriate, use the
+		                         * X509_V_ERR_CERT_CHAIN_TOO_LONG error
+		                         * code later.
+		                         */
+
+		/* If we are self signed, we break */
+		xn=X509_get_issuer_name(x);
+		if (ctx->check_issued(ctx, x,x)) break;
+
+		/* If we were passed a cert chain, use it first */
+		if (ctx->untrusted != NULL)
+			{
+			xtmp=find_issuer(ctx, sktmp,x);
+			if (xtmp != NULL)
+				{
+				if (!sk_X509_push(ctx->chain,xtmp))
+					{
+					X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
+					goto end;
+					}
+				CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
+				(void)sk_X509_delete_ptr(sktmp,xtmp);
+				ctx->last_untrusted++;
+				x=xtmp;
+				num++;
+				/* reparse the full chain for
+				 * the next one */
+				continue;
+				}
+			}
+		break;
+		}
+
+	/* at this point, chain should contain a list of untrusted
+	 * certificates.  We now need to add at least one trusted one,
+	 * if possible, otherwise we complain. */
+
+	/* Examine last certificate in chain and see if it
+ 	 * is self signed.
+ 	 */
+
+	i=sk_X509_num(ctx->chain);
+	x=sk_X509_value(ctx->chain,i-1);
+	xn = X509_get_subject_name(x);
+	if (ctx->check_issued(ctx, x, x))
+		{
+		/* we have a self signed certificate */
+		if (sk_X509_num(ctx->chain) == 1)
+			{
+			/* We have a single self signed certificate: see if
+			 * we can find it in the store. We must have an exact
+			 * match to avoid possible impersonation.
+			 */
+			ok = ctx->get_issuer(&xtmp, ctx, x);
+			if ((ok <= 0) || X509_cmp(x, xtmp)) 
+				{
+				ctx->error=X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
+				ctx->current_cert=x;
+				ctx->error_depth=i-1;
+				if (ok == 1) X509_free(xtmp);
+				bad_chain = 1;
+				ok=cb(0,ctx);
+				if (!ok) goto end;
+				}
+			else 
+				{
+				/* We have a match: replace certificate with store version
+				 * so we get any trust settings.
+				 */
+				X509_free(x);
+				x = xtmp;
+				(void)sk_X509_set(ctx->chain, i - 1, x);
+				ctx->last_untrusted=0;
+				}
+			}
+		else
+			{
+			/* extract and save self signed certificate for later use */
+			chain_ss=sk_X509_pop(ctx->chain);
+			ctx->last_untrusted--;
+			num--;
+			x=sk_X509_value(ctx->chain,num-1);
+			}
+		}
+
+	/* We now lookup certs from the certificate store */
+	for (;;)
+		{
+		/* If we have enough, we break */
+		if (depth < num) break;
+
+		/* If we are self signed, we break */
+		xn=X509_get_issuer_name(x);
+		if (ctx->check_issued(ctx,x,x)) break;
+
+		ok = ctx->get_issuer(&xtmp, ctx, x);
+
+		if (ok < 0) return ok;
+		if (ok == 0) break;
+
+		x = xtmp;
+		if (!sk_X509_push(ctx->chain,x))
+			{
+			X509_free(xtmp);
+			X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		num++;
+		}
+
+	/* we now have our chain, lets check it... */
+	xn=X509_get_issuer_name(x);
+
+	/* Is last certificate looked up self signed? */
+	if (!ctx->check_issued(ctx,x,x))
+		{
+		if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss))
+			{
+			if (ctx->last_untrusted >= num)
+				ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
+			else
+				ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
+			ctx->current_cert=x;
+			}
+		else
+			{
+
+			sk_X509_push(ctx->chain,chain_ss);
+			num++;
+			ctx->last_untrusted=num;
+			ctx->current_cert=chain_ss;
+			ctx->error=X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
+			chain_ss=NULL;
+			}
+
+		ctx->error_depth=num-1;
+		bad_chain = 1;
+		ok=cb(0,ctx);
+		if (!ok) goto end;
+		}
+
+	/* We have the chain complete: now we need to check its purpose */
+	ok = check_chain_extensions(ctx);
+
+	if (!ok) goto end;
+
+	/* Check name constraints */
+
+	ok = check_name_constraints(ctx);
+	
+	if (!ok) goto end;
+
+	/* The chain extensions are OK: check trust */
+
+	if (param->trust > 0) ok = check_trust(ctx);
+
+	if (!ok) goto end;
+
+	/* We may as well copy down any DSA parameters that are required */
+	X509_get_pubkey_parameters(NULL,ctx->chain);
+
+	/* Check revocation status: we do this after copying parameters
+	 * because they may be needed for CRL signature verification.
+	 */
+
+	ok = ctx->check_revocation(ctx);
+	if(!ok) goto end;
+
+	/* At this point, we have a chain and need to verify it */
+	if (ctx->verify != NULL)
+		ok=ctx->verify(ctx);
+	else
+		ok=internal_verify(ctx);
+	if(!ok) goto end;
+
+#ifndef OPENSSL_NO_RFC3779
+	/* RFC 3779 path validation, now that CRL check has been done */
+	ok = v3_asid_validate_path(ctx);
+	if (!ok) goto end;
+	ok = v3_addr_validate_path(ctx);
+	if (!ok) goto end;
+#endif
+
+	/* If we get this far evaluate policies */
+	if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
+		ok = ctx->check_policy(ctx);
+	if(!ok) goto end;
+	if (0)
+		{
+end:
+		X509_get_pubkey_parameters(NULL,ctx->chain);
+		}
+	if (sktmp != NULL) sk_X509_free(sktmp);
+	if (chain_ss != NULL) X509_free(chain_ss);
+	return ok;
+	}
+
+
+/* Given a STACK_OF(X509) find the issuer of cert (if any)
+ */
+
+static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
+{
+	int i;
+	X509 *issuer;
+	for (i = 0; i < sk_X509_num(sk); i++)
+		{
+		issuer = sk_X509_value(sk, i);
+		if (ctx->check_issued(ctx, x, issuer))
+			return issuer;
+		}
+	return NULL;
+}
+
+/* Given a possible certificate and issuer check them */
+
+static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
+{
+	int ret;
+	ret = X509_check_issued(issuer, x);
+	if (ret == X509_V_OK)
+		return 1;
+	/* If we haven't asked for issuer errors don't set ctx */
+	if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK))
+		return 0;
+
+	ctx->error = ret;
+	ctx->current_cert = x;
+	ctx->current_issuer = issuer;
+	return ctx->verify_cb(0, ctx);
+	return 0;
+}
+
+/* Alternative lookup method: look from a STACK stored in other_ctx */
+
+static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
+{
+	*issuer = find_issuer(ctx, ctx->other_ctx, x);
+	if (*issuer)
+		{
+		CRYPTO_add(&(*issuer)->references,1,CRYPTO_LOCK_X509);
+		return 1;
+		}
+	else
+		return 0;
+}
+	
+
+/* Check a certificate chains extensions for consistency
+ * with the supplied purpose
+ */
+
+static int check_chain_extensions(X509_STORE_CTX *ctx)
+{
+#ifdef OPENSSL_NO_CHAIN_VERIFY
+	return 1;
+#else
+	int i, ok=0, must_be_ca, plen = 0;
+	X509 *x;
+	int (*cb)(int xok,X509_STORE_CTX *xctx);
+	int proxy_path_length = 0;
+	int purpose;
+	int allow_proxy_certs;
+	cb=ctx->verify_cb;
+
+	/* must_be_ca can have 1 of 3 values:
+	   -1: we accept both CA and non-CA certificates, to allow direct
+	       use of self-signed certificates (which are marked as CA).
+	   0:  we only accept non-CA certificates.  This is currently not
+	       used, but the possibility is present for future extensions.
+	   1:  we only accept CA certificates.  This is currently used for
+	       all certificates in the chain except the leaf certificate.
+	*/
+	must_be_ca = -1;
+
+	/* CRL path validation */
+	if (ctx->parent)
+		{
+		allow_proxy_certs = 0;
+		purpose = X509_PURPOSE_CRL_SIGN;
+		}
+	else
+		{
+		allow_proxy_certs =
+			!!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
+		/* A hack to keep people who don't want to modify their
+		   software happy */
+		if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
+			allow_proxy_certs = 1;
+		purpose = ctx->param->purpose;
+		}
+
+	/* Check all untrusted certificates */
+	for (i = 0; i < ctx->last_untrusted; i++)
+		{
+		int ret;
+		x = sk_X509_value(ctx->chain, i);
+		if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
+			&& (x->ex_flags & EXFLAG_CRITICAL))
+			{
+			ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
+			ctx->error_depth = i;
+			ctx->current_cert = x;
+			ok=cb(0,ctx);
+			if (!ok) goto end;
+			}
+		if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY))
+			{
+			ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
+			ctx->error_depth = i;
+			ctx->current_cert = x;
+			ok=cb(0,ctx);
+			if (!ok) goto end;
+			}
+		ret = X509_check_ca(x);
+		switch(must_be_ca)
+			{
+		case -1:
+			if ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
+				&& (ret != 1) && (ret != 0))
+				{
+				ret = 0;
+				ctx->error = X509_V_ERR_INVALID_CA;
+				}
+			else
+				ret = 1;
+			break;
+		case 0:
+			if (ret != 0)
+				{
+				ret = 0;
+				ctx->error = X509_V_ERR_INVALID_NON_CA;
+				}
+			else
+				ret = 1;
+			break;
+		default:
+			if ((ret == 0)
+				|| ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
+					&& (ret != 1)))
+				{
+				ret = 0;
+				ctx->error = X509_V_ERR_INVALID_CA;
+				}
+			else
+				ret = 1;
+			break;
+			}
+		if (ret == 0)
+			{
+			ctx->error_depth = i;
+			ctx->current_cert = x;
+			ok=cb(0,ctx);
+			if (!ok) goto end;
+			}
+		if (ctx->param->purpose > 0)
+			{
+			ret = X509_check_purpose(x, purpose, must_be_ca > 0);
+			if ((ret == 0)
+				|| ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
+					&& (ret != 1)))
+				{
+				ctx->error = X509_V_ERR_INVALID_PURPOSE;
+				ctx->error_depth = i;
+				ctx->current_cert = x;
+				ok=cb(0,ctx);
+				if (!ok) goto end;
+				}
+			}
+		/* Check pathlen if not self issued */
+		if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
+			   && (x->ex_pathlen != -1)
+			   && (plen > (x->ex_pathlen + proxy_path_length + 1)))
+			{
+			ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
+			ctx->error_depth = i;
+			ctx->current_cert = x;
+			ok=cb(0,ctx);
+			if (!ok) goto end;
+			}
+		/* Increment path length if not self issued */
+		if (!(x->ex_flags & EXFLAG_SI))
+			plen++;
+		/* If this certificate is a proxy certificate, the next
+		   certificate must be another proxy certificate or a EE
+		   certificate.  If not, the next certificate must be a
+		   CA certificate.  */
+		if (x->ex_flags & EXFLAG_PROXY)
+			{
+			if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen)
+				{
+				ctx->error =
+					X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
+				ctx->error_depth = i;
+				ctx->current_cert = x;
+				ok=cb(0,ctx);
+				if (!ok) goto end;
+				}
+			proxy_path_length++;
+			must_be_ca = 0;
+			}
+		else
+			must_be_ca = 1;
+		}
+	ok = 1;
+ end:
+	return ok;
+#endif
+}
+
+static int check_name_constraints(X509_STORE_CTX *ctx)
+	{
+	X509 *x;
+	int i, j, rv;
+	/* Check name constraints for all certificates */
+	for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--)
+		{
+		x = sk_X509_value(ctx->chain, i);
+		/* Ignore self issued certs unless last in chain */
+		if (i && (x->ex_flags & EXFLAG_SI))
+			continue;
+		/* Check against constraints for all certificates higher in
+		 * chain including trust anchor. Trust anchor not strictly
+		 * speaking needed but if it includes constraints it is to be
+		 * assumed it expects them to be obeyed.
+		 */
+		for (j = sk_X509_num(ctx->chain) - 1; j > i; j--)
+			{
+			NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
+			if (nc)
+				{
+				rv = NAME_CONSTRAINTS_check(x, nc);
+				if (rv != X509_V_OK)
+					{
+					ctx->error = rv;
+					ctx->error_depth = i;
+					ctx->current_cert = x;
+					if (!ctx->verify_cb(0,ctx))
+						return 0;
+					}
+				}
+			}
+		}
+	return 1;
+	}
+
+static int check_trust(X509_STORE_CTX *ctx)
+{
+#ifdef OPENSSL_NO_CHAIN_VERIFY
+	return 1;
+#else
+	int i, ok;
+	X509 *x;
+	int (*cb)(int xok,X509_STORE_CTX *xctx);
+	cb=ctx->verify_cb;
+/* For now just check the last certificate in the chain */
+	i = sk_X509_num(ctx->chain) - 1;
+	x = sk_X509_value(ctx->chain, i);
+	ok = X509_check_trust(x, ctx->param->trust, 0);
+	if (ok == X509_TRUST_TRUSTED)
+		return 1;
+	ctx->error_depth = i;
+	ctx->current_cert = x;
+	if (ok == X509_TRUST_REJECTED)
+		ctx->error = X509_V_ERR_CERT_REJECTED;
+	else
+		ctx->error = X509_V_ERR_CERT_UNTRUSTED;
+	ok = cb(0, ctx);
+	return ok;
+#endif
+}
+
+static int check_revocation(X509_STORE_CTX *ctx)
+	{
+	int i, last, ok;
+	if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
+		return 1;
+	if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
+		last = sk_X509_num(ctx->chain) - 1;
+	else
+		{
+		/* If checking CRL paths this isn't the EE certificate */
+		if (ctx->parent)
+			return 1;
+		last = 0;
+		}
+	for(i = 0; i <= last; i++)
+		{
+		ctx->error_depth = i;
+		ok = check_cert(ctx);
+		if (!ok) return ok;
+		}
+	return 1;
+	}
+
+static int check_cert(X509_STORE_CTX *ctx)
+	{
+	X509_CRL *crl = NULL, *dcrl = NULL;
+	X509 *x;
+	int ok, cnum;
+	cnum = ctx->error_depth;
+	x = sk_X509_value(ctx->chain, cnum);
+	ctx->current_cert = x;
+	ctx->current_issuer = NULL;
+	ctx->current_crl_score = 0;
+	ctx->current_reasons = 0;
+	while (ctx->current_reasons != CRLDP_ALL_REASONS)
+		{
+		/* Try to retrieve relevant CRL */
+		if (ctx->get_crl)
+			ok = ctx->get_crl(ctx, &crl, x);
+		else
+			ok = get_crl_delta(ctx, &crl, &dcrl, x);
+		/* If error looking up CRL, nothing we can do except
+		 * notify callback
+		 */
+		if(!ok)
+			{
+			ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
+			ok = ctx->verify_cb(0, ctx);
+			goto err;
+			}
+		ctx->current_crl = crl;
+		ok = ctx->check_crl(ctx, crl);
+		if (!ok)
+			goto err;
+
+		if (dcrl)
+			{
+			ok = ctx->check_crl(ctx, dcrl);
+			if (!ok)
+				goto err;
+			ok = ctx->cert_crl(ctx, dcrl, x);
+			if (!ok)
+				goto err;
+			}
+		else
+			ok = 1;
+
+		/* Don't look in full CRL if delta reason is removefromCRL */
+		if (ok != 2)
+			{
+			ok = ctx->cert_crl(ctx, crl, x);
+			if (!ok)
+				goto err;
+			}
+
+		X509_CRL_free(crl);
+		X509_CRL_free(dcrl);
+		crl = NULL;
+		dcrl = NULL;
+		}
+	err:
+	X509_CRL_free(crl);
+	X509_CRL_free(dcrl);
+
+	ctx->current_crl = NULL;
+	return ok;
+
+	}
+
+/* Check CRL times against values in X509_STORE_CTX */
+
+static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
+	{
+	time_t *ptime;
+	int i;
+	if (notify)
+		ctx->current_crl = crl;
+	if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
+		ptime = &ctx->param->check_time;
+	else
+		ptime = NULL;
+
+	i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
+	if (i == 0)
+		{
+		if (!notify)
+			return 0;
+		ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
+		if (!ctx->verify_cb(0, ctx))
+			return 0;
+		}
+
+	if (i > 0)
+		{
+		if (!notify)
+			return 0;
+		ctx->error=X509_V_ERR_CRL_NOT_YET_VALID;
+		if (!ctx->verify_cb(0, ctx))
+			return 0;
+		}
+
+	if(X509_CRL_get_nextUpdate(crl))
+		{
+		i=X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
+
+		if (i == 0)
+			{
+			if (!notify)
+				return 0;
+			ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
+			if (!ctx->verify_cb(0, ctx))
+				return 0;
+			}
+		/* Ignore expiry of base CRL is delta is valid */
+		if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA))
+			{
+			if (!notify)
+				return 0;
+			ctx->error=X509_V_ERR_CRL_HAS_EXPIRED;
+			if (!ctx->verify_cb(0, ctx))
+				return 0;
+			}
+		}
+
+	if (notify)
+		ctx->current_crl = NULL;
+
+	return 1;
+	}
+
+static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
+			X509 **pissuer, int *pscore, unsigned int *preasons,
+			STACK_OF(X509_CRL) *crls)
+	{
+	int i, crl_score, best_score = *pscore;
+	unsigned int reasons, best_reasons = 0;
+	X509 *x = ctx->current_cert;
+	X509_CRL *crl, *best_crl = NULL;
+	X509 *crl_issuer = NULL, *best_crl_issuer = NULL;
+
+	for (i = 0; i < sk_X509_CRL_num(crls); i++)
+		{
+		crl = sk_X509_CRL_value(crls, i);
+		reasons = *preasons;
+		crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
+
+		if (crl_score > best_score)
+			{
+			best_crl = crl;
+			best_crl_issuer = crl_issuer;
+			best_score = crl_score;
+			best_reasons = reasons;
+			}
+		}
+
+	if (best_crl)
+		{
+		if (*pcrl)
+			X509_CRL_free(*pcrl);
+		*pcrl = best_crl;
+		*pissuer = best_crl_issuer;
+		*pscore = best_score;
+		*preasons = best_reasons;
+		CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL);
+		if (*pdcrl)
+			{
+			X509_CRL_free(*pdcrl);
+			*pdcrl = NULL;
+			}
+		get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
+		}
+
+	if (best_score >= CRL_SCORE_VALID)
+		return 1;
+
+	return 0;
+	}
+
+/* Compare two CRL extensions for delta checking purposes. They should be
+ * both present or both absent. If both present all fields must be identical.
+ */
+
+static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
+	{
+	ASN1_OCTET_STRING *exta, *extb;
+	int i;
+	i = X509_CRL_get_ext_by_NID(a, nid, 0);
+	if (i >= 0)
+		{
+		/* Can't have multiple occurrences */
+		if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
+			return 0;
+		exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
+		}
+	else
+		exta = NULL;
+
+	i = X509_CRL_get_ext_by_NID(b, nid, 0);
+
+	if (i >= 0)
+		{
+
+		if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
+			return 0;
+		extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
+		}
+	else
+		extb = NULL;
+
+	if (!exta && !extb)
+		return 1;
+
+	if (!exta || !extb)
+		return 0;
+
+
+	if (ASN1_OCTET_STRING_cmp(exta, extb))
+		return 0;
+
+	return 1;
+	}
+
+/* See if a base and delta are compatible */
+
+static int check_delta_base(X509_CRL *delta, X509_CRL *base)
+	{
+	/* Delta CRL must be a delta */
+	if (!delta->base_crl_number)
+			return 0;
+	/* Base must have a CRL number */
+	if (!base->crl_number)
+			return 0;
+	/* Issuer names must match */
+	if (X509_NAME_cmp(X509_CRL_get_issuer(base),
+				X509_CRL_get_issuer(delta)))
+		return 0;
+	/* AKID and IDP must match */
+	if (!crl_extension_match(delta, base, NID_authority_key_identifier))
+			return 0;
+	if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
+			return 0;
+	/* Delta CRL base number must not exceed Full CRL number. */
+	if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
+			return 0;
+	/* Delta CRL number must exceed full CRL number */
+	if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
+			return 1;
+	return 0;
+	}
+
+/* For a given base CRL find a delta... maybe extend to delta scoring
+ * or retrieve a chain of deltas...
+ */
+
+static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
+			X509_CRL *base, STACK_OF(X509_CRL) *crls)
+	{
+	X509_CRL *delta;
+	int i;
+	if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
+		return;
+	if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
+		return;
+	for (i = 0; i < sk_X509_CRL_num(crls); i++)
+		{
+		delta = sk_X509_CRL_value(crls, i);
+		if (check_delta_base(delta, base))
+			{
+			if (check_crl_time(ctx, delta, 0))
+				*pscore |= CRL_SCORE_TIME_DELTA;
+			CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL);
+			*dcrl = delta;
+			return;
+			}
+		}
+	*dcrl = NULL;
+	}
+
+/* For a given CRL return how suitable it is for the supplied certificate 'x'.
+ * The return value is a mask of several criteria.
+ * If the issuer is not the certificate issuer this is returned in *pissuer.
+ * The reasons mask is also used to determine if the CRL is suitable: if
+ * no new reasons the CRL is rejected, otherwise reasons is updated.
+ */
+
+static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
+			unsigned int *preasons,
+			X509_CRL *crl, X509 *x)
+	{
+
+	int crl_score = 0;
+	unsigned int tmp_reasons = *preasons, crl_reasons;
+
+	/* First see if we can reject CRL straight away */
+
+	/* Invalid IDP cannot be processed */
+	if (crl->idp_flags & IDP_INVALID)
+		return 0;
+	/* Reason codes or indirect CRLs need extended CRL support */
+	if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
+		{
+		if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
+			return 0;
+		}
+	else if (crl->idp_flags & IDP_REASONS)
+		{
+		/* If no new reasons reject */
+		if (!(crl->idp_reasons & ~tmp_reasons))
+			return 0;
+		}
+	/* Don't process deltas at this stage */
+	else if (crl->base_crl_number)
+		return 0;
+	/* If issuer name doesn't match certificate need indirect CRL */
+	if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl)))
+		{
+		if (!(crl->idp_flags & IDP_INDIRECT))
+			return 0;
+		}
+	else
+		crl_score |= CRL_SCORE_ISSUER_NAME;
+
+	if (!(crl->flags & EXFLAG_CRITICAL))
+		crl_score |= CRL_SCORE_NOCRITICAL;
+
+	/* Check expiry */
+	if (check_crl_time(ctx, crl, 0))
+		crl_score |= CRL_SCORE_TIME;
+
+	/* Check authority key ID and locate certificate issuer */
+	crl_akid_check(ctx, crl, pissuer, &crl_score);
+
+	/* If we can't locate certificate issuer at this point forget it */
+
+	if (!(crl_score & CRL_SCORE_AKID))
+		return 0;
+
+	/* Check cert for matching CRL distribution points */
+
+	if (crl_crldp_check(x, crl, crl_score, &crl_reasons))
+		{
+		/* If no new reasons reject */
+		if (!(crl_reasons & ~tmp_reasons))
+			return 0;
+		tmp_reasons |= crl_reasons;
+		crl_score |= CRL_SCORE_SCOPE;
+		}
+
+	*preasons = tmp_reasons;
+
+	return crl_score;
+
+	}
+
+static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
+				X509 **pissuer, int *pcrl_score)
+	{
+	X509 *crl_issuer = NULL;
+	X509_NAME *cnm = X509_CRL_get_issuer(crl);
+	int cidx = ctx->error_depth;
+	int i;
+
+	if (cidx != sk_X509_num(ctx->chain) - 1)
+		cidx++;
+
+	crl_issuer = sk_X509_value(ctx->chain, cidx);
+
+	if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
+		{
+		if (*pcrl_score & CRL_SCORE_ISSUER_NAME)
+			{
+			*pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_ISSUER_CERT;
+			*pissuer = crl_issuer;
+			return;
+			}
+		}
+
+	for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++)
+		{
+		crl_issuer = sk_X509_value(ctx->chain, cidx);
+		if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
+			continue;
+		if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
+			{
+			*pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_SAME_PATH;
+			*pissuer = crl_issuer;
+			return;
+			}
+		}
+
+	/* Anything else needs extended CRL support */
+
+	if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
+		return;
+
+	/* Otherwise the CRL issuer is not on the path. Look for it in the
+	 * set of untrusted certificates.
+	 */
+	for (i = 0; i < sk_X509_num(ctx->untrusted); i++)
+		{
+		crl_issuer = sk_X509_value(ctx->untrusted, i);
+		if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
+			continue;
+		if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
+			{
+			*pissuer = crl_issuer;
+			*pcrl_score |= CRL_SCORE_AKID;
+			return;
+			}
+		}
+	}
+
+/* Check the path of a CRL issuer certificate. This creates a new
+ * X509_STORE_CTX and populates it with most of the parameters from the
+ * parent. This could be optimised somewhat since a lot of path checking
+ * will be duplicated by the parent, but this will rarely be used in 
+ * practice.
+ */
+
+static int check_crl_path(X509_STORE_CTX *ctx, X509 *x)
+	{
+	X509_STORE_CTX crl_ctx;
+	int ret;
+	/* Don't allow recursive CRL path validation */
+	if (ctx->parent)
+		return 0;
+	if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
+		return -1;
+
+	crl_ctx.crls = ctx->crls;
+	/* Copy verify params across */
+	X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
+
+	crl_ctx.parent = ctx;
+	crl_ctx.verify_cb = ctx->verify_cb;
+
+	/* Verify CRL issuer */
+	ret = X509_verify_cert(&crl_ctx);
+
+	if (ret <= 0)
+		goto err;
+
+	/* Check chain is acceptable */
+
+	ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
+	err:
+	X509_STORE_CTX_cleanup(&crl_ctx);
+	return ret;
+	}
+
+/* RFC3280 says nothing about the relationship between CRL path
+ * and certificate path, which could lead to situations where a
+ * certificate could be revoked or validated by a CA not authorised
+ * to do so. RFC5280 is more strict and states that the two paths must
+ * end in the same trust anchor, though some discussions remain...
+ * until this is resolved we use the RFC5280 version
+ */
+
+static int check_crl_chain(X509_STORE_CTX *ctx,
+			STACK_OF(X509) *cert_path,
+			STACK_OF(X509) *crl_path)
+	{
+	X509 *cert_ta, *crl_ta;
+	cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
+	crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
+	if (!X509_cmp(cert_ta, crl_ta))
+		return 1;
+	return 0;
+	}
+
+/* Check for match between two dist point names: three separate cases.
+ * 1. Both are relative names and compare X509_NAME types.
+ * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES.
+ * 3. Both are full names and compare two GENERAL_NAMES.
+ * 4. One is NULL: automatic match.
+ */
+
+
+static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b)
+	{
+	X509_NAME *nm = NULL;
+	GENERAL_NAMES *gens = NULL;
+	GENERAL_NAME *gena, *genb;
+	int i, j;
+	if (!a || !b)
+		return 1;
+	if (a->type == 1)
+		{
+		if (!a->dpname)
+			return 0;
+		/* Case 1: two X509_NAME */
+		if (b->type == 1)
+			{
+			if (!b->dpname)
+				return 0;
+			if (!X509_NAME_cmp(a->dpname, b->dpname))
+				return 1;
+			else
+				return 0;
+			}
+		/* Case 2: set name and GENERAL_NAMES appropriately */
+		nm = a->dpname;
+		gens = b->name.fullname;
+		}
+	else if (b->type == 1)
+		{
+		if (!b->dpname)
+			return 0;
+		/* Case 2: set name and GENERAL_NAMES appropriately */
+		gens = a->name.fullname;
+		nm = b->dpname;
+		}
+
+	/* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
+	if (nm)
+		{
+		for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
+			{
+			gena = sk_GENERAL_NAME_value(gens, i);	
+			if (gena->type != GEN_DIRNAME)
+				continue;
+			if (!X509_NAME_cmp(nm, gena->d.directoryName))
+				return 1;
+			}
+		return 0;
+		}
+
+	/* Else case 3: two GENERAL_NAMES */
+
+	for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++)
+		{
+		gena = sk_GENERAL_NAME_value(a->name.fullname, i);
+		for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++)
+			{
+			genb = sk_GENERAL_NAME_value(b->name.fullname, j);
+			if (!GENERAL_NAME_cmp(gena, genb))
+				return 1;
+			}
+		}
+
+	return 0;
+
+	}
+
+static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score)
+	{
+	int i;
+	X509_NAME *nm = X509_CRL_get_issuer(crl);
+	/* If no CRLissuer return is successful iff don't need a match */
+	if (!dp->CRLissuer)
+		return !!(crl_score & CRL_SCORE_ISSUER_NAME);
+	for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++)
+		{
+		GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
+		if (gen->type != GEN_DIRNAME)
+			continue;
+		if (!X509_NAME_cmp(gen->d.directoryName, nm))
+			return 1;
+		}
+	return 0;
+	}
+
+/* Check CRLDP and IDP */
+
+static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
+				unsigned int *preasons)
+	{
+	int i;
+	if (crl->idp_flags & IDP_ONLYATTR)
+		return 0;
+	if (x->ex_flags & EXFLAG_CA)
+		{
+		if (crl->idp_flags & IDP_ONLYUSER)
+			return 0;
+		}
+	else
+		{
+		if (crl->idp_flags & IDP_ONLYCA)
+			return 0;
+		}
+	*preasons = crl->idp_reasons;
+	for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
+		{
+		DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
+		if (crldp_check_crlissuer(dp, crl, crl_score))
+			{
+			if (!crl->idp ||
+			     idp_check_dp(dp->distpoint, crl->idp->distpoint))
+				{
+				*preasons &= dp->dp_reasons;
+				return 1;
+				}
+			}
+		}
+	if ((!crl->idp || !crl->idp->distpoint) && (crl_score & CRL_SCORE_ISSUER_NAME))
+		return 1;
+	return 0;
+	}
+
+/* Retrieve CRL corresponding to current certificate.
+ * If deltas enabled try to find a delta CRL too
+ */
+	
+static int get_crl_delta(X509_STORE_CTX *ctx,
+				X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x)
+	{
+	int ok;
+	X509 *issuer = NULL;
+	int crl_score = 0;
+	unsigned int reasons;
+	X509_CRL *crl = NULL, *dcrl = NULL;
+	STACK_OF(X509_CRL) *skcrl;
+	X509_NAME *nm = X509_get_issuer_name(x);
+	reasons = ctx->current_reasons;
+	ok = get_crl_sk(ctx, &crl, &dcrl, 
+				&issuer, &crl_score, &reasons, ctx->crls);
+
+	if (ok)
+		goto done;
+
+	/* Lookup CRLs from store */
+
+	skcrl = ctx->lookup_crls(ctx, nm);
+
+	/* If no CRLs found and a near match from get_crl_sk use that */
+	if (!skcrl && crl)
+		goto done;
+
+	get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);
+
+	sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
+
+	done:
+
+	/* If we got any kind of CRL use it and return success */
+	if (crl)
+		{
+		ctx->current_issuer = issuer;
+		ctx->current_crl_score = crl_score;
+		ctx->current_reasons = reasons;
+		*pcrl = crl;
+		*pdcrl = dcrl;
+		return 1;
+		}
+
+	return 0;
+	}
+
+/* Check CRL validity */
+static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
+	{
+	X509 *issuer = NULL;
+	EVP_PKEY *ikey = NULL;
+	int ok = 0, chnum, cnum;
+	cnum = ctx->error_depth;
+	chnum = sk_X509_num(ctx->chain) - 1;
+	/* if we have an alternative CRL issuer cert use that */
+	if (ctx->current_issuer)
+		issuer = ctx->current_issuer;
+
+	/* Else find CRL issuer: if not last certificate then issuer
+	 * is next certificate in chain.
+	 */
+	else if (cnum < chnum)
+		issuer = sk_X509_value(ctx->chain, cnum + 1);
+	else
+		{
+		issuer = sk_X509_value(ctx->chain, chnum);
+		/* If not self signed, can't check signature */
+		if(!ctx->check_issued(ctx, issuer, issuer))
+			{
+			ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
+			ok = ctx->verify_cb(0, ctx);
+			if(!ok) goto err;
+			}
+		}
+
+	if(issuer)
+		{
+		/* Skip most tests for deltas because they have already
+		 * been done
+		 */
+		if (!crl->base_crl_number)
+			{
+			/* Check for cRLSign bit if keyUsage present */
+			if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
+				!(issuer->ex_kusage & KU_CRL_SIGN))
+				{
+				ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
+				ok = ctx->verify_cb(0, ctx);
+				if(!ok) goto err;
+				}
+
+			if (!(ctx->current_crl_score & CRL_SCORE_SCOPE))
+				{
+				ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
+				ok = ctx->verify_cb(0, ctx);
+				if(!ok) goto err;
+				}
+
+			if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH))
+				{
+				if (check_crl_path(ctx, ctx->current_issuer) <= 0)
+					{
+					ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
+					ok = ctx->verify_cb(0, ctx);
+					if(!ok) goto err;
+					}
+				}
+
+			if (crl->idp_flags & IDP_INVALID)
+				{
+				ctx->error = X509_V_ERR_INVALID_EXTENSION;
+				ok = ctx->verify_cb(0, ctx);
+				if(!ok) goto err;
+				}
+
+
+			}
+
+		if (!(ctx->current_crl_score & CRL_SCORE_TIME))
+			{
+			ok = check_crl_time(ctx, crl, 1);
+			if (!ok)
+				goto err;
+			}
+
+		/* Attempt to get issuer certificate public key */
+		ikey = X509_get_pubkey(issuer);
+
+		if(!ikey)
+			{
+			ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
+			ok = ctx->verify_cb(0, ctx);
+			if (!ok) goto err;
+			}
+		else
+			{
+			/* Verify CRL signature */
+			if(X509_CRL_verify(crl, ikey) <= 0)
+				{
+				ctx->error=X509_V_ERR_CRL_SIGNATURE_FAILURE;
+				ok = ctx->verify_cb(0, ctx);
+				if (!ok) goto err;
+				}
+			}
+		}
+
+	ok = 1;
+
+	err:
+	EVP_PKEY_free(ikey);
+	return ok;
+	}
+
+/* Check certificate against CRL */
+static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
+	{
+	int ok;
+	X509_REVOKED *rev;
+	/* The rules changed for this... previously if a CRL contained
+	 * unhandled critical extensions it could still be used to indicate
+	 * a certificate was revoked. This has since been changed since 
+	 * critical extension can change the meaning of CRL entries.
+	 */
+	if (crl->flags & EXFLAG_CRITICAL)
+		{
+		if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
+			return 1;
+		ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
+		ok = ctx->verify_cb(0, ctx);
+		if(!ok)
+			return 0;
+		}
+	/* Look for serial number of certificate in CRL
+	 * If found make sure reason is not removeFromCRL.
+	 */
+	if (X509_CRL_get0_by_cert(crl, &rev, x))
+		{
+		if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
+			return 2;
+		ctx->error = X509_V_ERR_CERT_REVOKED;
+		ok = ctx->verify_cb(0, ctx);
+		if (!ok)
+			return 0;
+		}
+
+	return 1;
+	}
+
+static int check_policy(X509_STORE_CTX *ctx)
+	{
+	int ret;
+	if (ctx->parent)
+		return 1;
+	ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
+				ctx->param->policies, ctx->param->flags);
+	if (ret == 0)
+		{
+		X509err(X509_F_CHECK_POLICY,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	/* Invalid or inconsistent extensions */
+	if (ret == -1)
+		{
+		/* Locate certificates with bad extensions and notify
+		 * callback.
+		 */
+		X509 *x;
+		int i;
+		for (i = 1; i < sk_X509_num(ctx->chain); i++)
+			{
+			x = sk_X509_value(ctx->chain, i);
+			if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
+				continue;
+			ctx->current_cert = x;
+			ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
+			if(!ctx->verify_cb(0, ctx))
+				return 0;
+			}
+		return 1;
+		}
+	if (ret == -2)
+		{
+		ctx->current_cert = NULL;
+		ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
+		return ctx->verify_cb(0, ctx);
+		}
+
+	if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY)
+		{
+		ctx->current_cert = NULL;
+		ctx->error = X509_V_OK;
+		if (!ctx->verify_cb(2, ctx))
+			return 0;
+		}
+
+	return 1;
+	}
+
+static int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
+	{
+	time_t *ptime;
+	int i;
+
+	if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
+		ptime = &ctx->param->check_time;
+	else
+		ptime = NULL;
+
+	i=X509_cmp_time(X509_get_notBefore(x), ptime);
+	if (i == 0)
+		{
+		ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
+		ctx->current_cert=x;
+		if (!ctx->verify_cb(0, ctx))
+			return 0;
+		}
+
+	if (i > 0)
+		{
+		ctx->error=X509_V_ERR_CERT_NOT_YET_VALID;
+		ctx->current_cert=x;
+		if (!ctx->verify_cb(0, ctx))
+			return 0;
+		}
+
+	i=X509_cmp_time(X509_get_notAfter(x), ptime);
+	if (i == 0)
+		{
+		ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
+		ctx->current_cert=x;
+		if (!ctx->verify_cb(0, ctx))
+			return 0;
+		}
+
+	if (i < 0)
+		{
+		ctx->error=X509_V_ERR_CERT_HAS_EXPIRED;
+		ctx->current_cert=x;
+		if (!ctx->verify_cb(0, ctx))
+			return 0;
+		}
+
+	return 1;
+	}
+
+static int internal_verify(X509_STORE_CTX *ctx)
+	{
+	int ok=0,n;
+	X509 *xs,*xi;
+	EVP_PKEY *pkey=NULL;
+	int (*cb)(int xok,X509_STORE_CTX *xctx);
+
+	cb=ctx->verify_cb;
+
+	n=sk_X509_num(ctx->chain);
+	ctx->error_depth=n-1;
+	n--;
+	xi=sk_X509_value(ctx->chain,n);
+
+	if (ctx->check_issued(ctx, xi, xi))
+		xs=xi;
+	else
+		{
+		if (n <= 0)
+			{
+			ctx->error=X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
+			ctx->current_cert=xi;
+			ok=cb(0,ctx);
+			goto end;
+			}
+		else
+			{
+			n--;
+			ctx->error_depth=n;
+			xs=sk_X509_value(ctx->chain,n);
+			}
+		}
+
+/*	ctx->error=0;  not needed */
+	while (n >= 0)
+		{
+		ctx->error_depth=n;
+
+		/* Skip signature check for self signed certificates unless
+		 * explicitly asked for. It doesn't add any security and
+		 * just wastes time.
+		 */
+		if (!xs->valid && (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)))
+			{
+			if ((pkey=X509_get_pubkey(xi)) == NULL)
+				{
+				ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
+				ctx->current_cert=xi;
+				ok=(*cb)(0,ctx);
+				if (!ok) goto end;
+				}
+			else if (X509_verify(xs,pkey) <= 0)
+				{
+				ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE;
+				ctx->current_cert=xs;
+				ok=(*cb)(0,ctx);
+				if (!ok)
+					{
+					EVP_PKEY_free(pkey);
+					goto end;
+					}
+				}
+			EVP_PKEY_free(pkey);
+			pkey=NULL;
+			}
+
+		xs->valid = 1;
+
+		ok = check_cert_time(ctx, xs);
+		if (!ok)
+			goto end;
+
+		/* The last error (if any) is still in the error value */
+		ctx->current_issuer=xi;
+		ctx->current_cert=xs;
+		ok=(*cb)(1,ctx);
+		if (!ok) goto end;
+
+		n--;
+		if (n >= 0)
+			{
+			xi=xs;
+			xs=sk_X509_value(ctx->chain,n);
+			}
+		}
+	ok=1;
+end:
+	return ok;
+	}
+
+int X509_cmp_current_time(const ASN1_TIME *ctm)
+{
+	return X509_cmp_time(ctm, NULL);
+}
+
+int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
+	{
+	char *str;
+	ASN1_TIME atm;
+	long offset;
+	char buff1[24],buff2[24],*p;
+	int i,j;
+
+	p=buff1;
+	i=ctm->length;
+	str=(char *)ctm->data;
+	if (ctm->type == V_ASN1_UTCTIME)
+		{
+		if ((i < 11) || (i > 17)) return 0;
+		memcpy(p,str,10);
+		p+=10;
+		str+=10;
+		}
+	else
+		{
+		if (i < 13) return 0;
+		memcpy(p,str,12);
+		p+=12;
+		str+=12;
+		}
+
+	if ((*str == 'Z') || (*str == '-') || (*str == '+'))
+		{ *(p++)='0'; *(p++)='0'; }
+	else
+		{ 
+		*(p++)= *(str++);
+		*(p++)= *(str++);
+		/* Skip any fractional seconds... */
+		if (*str == '.')
+			{
+			str++;
+			while ((*str >= '0') && (*str <= '9')) str++;
+			}
+		
+		}
+	*(p++)='Z';
+	*(p++)='\0';
+
+	if (*str == 'Z')
+		offset=0;
+	else
+		{
+		if ((*str != '+') && (*str != '-'))
+			return 0;
+		offset=((str[1]-'0')*10+(str[2]-'0'))*60;
+		offset+=(str[3]-'0')*10+(str[4]-'0');
+		if (*str == '-')
+			offset= -offset;
+		}
+	atm.type=ctm->type;
+	atm.flags = 0;
+	atm.length=sizeof(buff2);
+	atm.data=(unsigned char *)buff2;
+
+	if (X509_time_adj(&atm, offset*60, cmp_time) == NULL)
+		return 0;
+
+	if (ctm->type == V_ASN1_UTCTIME)
+		{
+		i=(buff1[0]-'0')*10+(buff1[1]-'0');
+		if (i < 50) i+=100; /* cf. RFC 2459 */
+		j=(buff2[0]-'0')*10+(buff2[1]-'0');
+		if (j < 50) j+=100;
+
+		if (i < j) return -1;
+		if (i > j) return 1;
+		}
+	i=strcmp(buff1,buff2);
+	if (i == 0) /* wait a second then return younger :-) */
+		return -1;
+	else
+		return i;
+	}
+
+ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
+{
+	return X509_time_adj(s, adj, NULL);
+}
+
+ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm)
+	{
+	return X509_time_adj_ex(s, 0, offset_sec, in_tm);
+	}
+
+ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
+				int offset_day, long offset_sec, time_t *in_tm)
+	{
+	time_t t;
+
+	if (in_tm) t = *in_tm;
+	else time(&t);
+
+	if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING))
+		{
+		if (s->type == V_ASN1_UTCTIME)
+			return ASN1_UTCTIME_adj(s,t, offset_day, offset_sec);
+		if (s->type == V_ASN1_GENERALIZEDTIME)
+			return ASN1_GENERALIZEDTIME_adj(s, t, offset_day,
+								offset_sec);
+		}
+	return ASN1_TIME_adj(s, t, offset_day, offset_sec);
+	}
+
+int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
+	{
+	EVP_PKEY *ktmp=NULL,*ktmp2;
+	int i,j;
+
+	if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) return 1;
+
+	for (i=0; i<sk_X509_num(chain); i++)
+		{
+		ktmp=X509_get_pubkey(sk_X509_value(chain,i));
+		if (ktmp == NULL)
+			{
+			X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY);
+			return 0;
+			}
+		if (!EVP_PKEY_missing_parameters(ktmp))
+			break;
+		else
+			{
+			EVP_PKEY_free(ktmp);
+			ktmp=NULL;
+			}
+		}
+	if (ktmp == NULL)
+		{
+		X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN);
+		return 0;
+		}
+
+	/* first, populate the other certs */
+	for (j=i-1; j >= 0; j--)
+		{
+		ktmp2=X509_get_pubkey(sk_X509_value(chain,j));
+		EVP_PKEY_copy_parameters(ktmp2,ktmp);
+		EVP_PKEY_free(ktmp2);
+		}
+	
+	if (pkey != NULL) EVP_PKEY_copy_parameters(pkey,ktmp);
+	EVP_PKEY_free(ktmp);
+	return 1;
+	}
+
+int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+	{
+	/* This function is (usually) called only once, by
+	 * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp,
+			new_func, dup_func, free_func);
+	}
+
+int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
+	{
+	return CRYPTO_set_ex_data(&ctx->ex_data,idx,data);
+	}
+
+void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
+	{
+	return CRYPTO_get_ex_data(&ctx->ex_data,idx);
+	}
+
+int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
+	{
+	return ctx->error;
+	}
+
+void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
+	{
+	ctx->error=err;
+	}
+
+int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
+	{
+	return ctx->error_depth;
+	}
+
+X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
+	{
+	return ctx->current_cert;
+	}
+
+STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
+	{
+	return ctx->chain;
+	}
+
+STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
+	{
+	int i;
+	X509 *x;
+	STACK_OF(X509) *chain;
+	if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain))) return NULL;
+	for (i = 0; i < sk_X509_num(chain); i++)
+		{
+		x = sk_X509_value(chain, i);
+		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
+		}
+	return chain;
+	}
+
+X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx)
+	{
+	return ctx->current_issuer;
+	}
+
+X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx)
+	{
+	return ctx->current_crl;
+	}
+
+X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
+	{
+	return ctx->parent;
+	}
+
+void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
+	{
+	ctx->cert=x;
+	}
+
+void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
+	{
+	ctx->untrusted=sk;
+	}
+
+void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
+	{
+	ctx->crls=sk;
+	}
+
+int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
+	{
+	return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
+	}
+
+int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
+	{
+	return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
+	}
+
+/* This function is used to set the X509_STORE_CTX purpose and trust
+ * values. This is intended to be used when another structure has its
+ * own trust and purpose values which (if set) will be inherited by
+ * the ctx. If they aren't set then we will usually have a default
+ * purpose in mind which should then be used to set the trust value.
+ * An example of this is SSL use: an SSL structure will have its own
+ * purpose and trust settings which the application can set: if they
+ * aren't set then we use the default of SSL client/server.
+ */
+
+int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
+				int purpose, int trust)
+{
+	int idx;
+	/* If purpose not set use default */
+	if (!purpose) purpose = def_purpose;
+	/* If we have a purpose then check it is valid */
+	if (purpose)
+		{
+		X509_PURPOSE *ptmp;
+		idx = X509_PURPOSE_get_by_id(purpose);
+		if (idx == -1)
+			{
+			X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
+						X509_R_UNKNOWN_PURPOSE_ID);
+			return 0;
+			}
+		ptmp = X509_PURPOSE_get0(idx);
+		if (ptmp->trust == X509_TRUST_DEFAULT)
+			{
+			idx = X509_PURPOSE_get_by_id(def_purpose);
+			if (idx == -1)
+				{
+				X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
+						X509_R_UNKNOWN_PURPOSE_ID);
+				return 0;
+				}
+			ptmp = X509_PURPOSE_get0(idx);
+			}
+		/* If trust not set then get from purpose default */
+		if (!trust) trust = ptmp->trust;
+		}
+	if (trust)
+		{
+		idx = X509_TRUST_get_by_id(trust);
+		if (idx == -1)
+			{
+			X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
+						X509_R_UNKNOWN_TRUST_ID);
+			return 0;
+			}
+		}
+
+	if (purpose && !ctx->param->purpose) ctx->param->purpose = purpose;
+	if (trust && !ctx->param->trust) ctx->param->trust = trust;
+	return 1;
+}
+
+X509_STORE_CTX *X509_STORE_CTX_new(void)
+{
+	X509_STORE_CTX *ctx;
+	ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
+	if (!ctx)
+		{
+		X509err(X509_F_X509_STORE_CTX_NEW,ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+	memset(ctx, 0, sizeof(X509_STORE_CTX));
+	return ctx;
+}
+
+void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
+{
+	X509_STORE_CTX_cleanup(ctx);
+	OPENSSL_free(ctx);
+}
+
+int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
+	     STACK_OF(X509) *chain)
+	{
+	int ret = 1;
+	ctx->ctx=store;
+	ctx->current_method=0;
+	ctx->cert=x509;
+	ctx->untrusted=chain;
+	ctx->crls = NULL;
+	ctx->last_untrusted=0;
+	ctx->other_ctx=NULL;
+	ctx->valid=0;
+	ctx->chain=NULL;
+	ctx->error=0;
+	ctx->explicit_policy=0;
+	ctx->error_depth=0;
+	ctx->current_cert=NULL;
+	ctx->current_issuer=NULL;
+	ctx->current_crl=NULL;
+	ctx->current_crl_score=0;
+	ctx->current_reasons=0;
+	ctx->tree = NULL;
+	ctx->parent = NULL;
+
+	ctx->param = X509_VERIFY_PARAM_new();
+
+	if (!ctx->param)
+		{
+		X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+
+	/* Inherit callbacks and flags from X509_STORE if not set
+	 * use defaults.
+	 */
+
+
+	if (store)
+		ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
+	else
+		ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT|X509_VP_FLAG_ONCE;
+
+	if (store)
+		{
+		ctx->verify_cb = store->verify_cb;
+		ctx->cleanup = store->cleanup;
+		}
+	else
+		ctx->cleanup = 0;
+
+	if (ret)
+		ret = X509_VERIFY_PARAM_inherit(ctx->param,
+					X509_VERIFY_PARAM_lookup("default"));
+
+	if (ret == 0)
+		{
+		X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+
+	if (store && store->check_issued)
+		ctx->check_issued = store->check_issued;
+	else
+		ctx->check_issued = check_issued;
+
+	if (store && store->get_issuer)
+		ctx->get_issuer = store->get_issuer;
+	else
+		ctx->get_issuer = X509_STORE_CTX_get1_issuer;
+
+	if (store && store->verify_cb)
+		ctx->verify_cb = store->verify_cb;
+	else
+		ctx->verify_cb = null_callback;
+
+	if (store && store->verify)
+		ctx->verify = store->verify;
+	else
+		ctx->verify = internal_verify;
+
+	if (store && store->check_revocation)
+		ctx->check_revocation = store->check_revocation;
+	else
+		ctx->check_revocation = check_revocation;
+
+	if (store && store->get_crl)
+		ctx->get_crl = store->get_crl;
+	else
+		ctx->get_crl = NULL;
+
+	if (store && store->check_crl)
+		ctx->check_crl = store->check_crl;
+	else
+		ctx->check_crl = check_crl;
+
+	if (store && store->cert_crl)
+		ctx->cert_crl = store->cert_crl;
+	else
+		ctx->cert_crl = cert_crl;
+
+	if (store && store->lookup_certs)
+		ctx->lookup_certs = store->lookup_certs;
+	else
+		ctx->lookup_certs = X509_STORE_get1_certs;
+
+	if (store && store->lookup_crls)
+		ctx->lookup_crls = store->lookup_crls;
+	else
+		ctx->lookup_crls = X509_STORE_get1_crls;
+
+	ctx->check_policy = check_policy;
+
+
+	/* This memset() can't make any sense anyway, so it's removed. As
+	 * X509_STORE_CTX_cleanup does a proper "free" on the ex_data, we put a
+	 * corresponding "new" here and remove this bogus initialisation. */
+	/* memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); */
+	if(!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
+				&(ctx->ex_data)))
+		{
+		OPENSSL_free(ctx);
+		X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	return 1;
+	}
+
+/* Set alternative lookup method: just a STACK of trusted certificates.
+ * This avoids X509_STORE nastiness where it isn't needed.
+ */
+
+void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
+{
+	ctx->other_ctx = sk;
+	ctx->get_issuer = get_issuer_sk;
+}
+
+void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
+	{
+	if (ctx->cleanup) ctx->cleanup(ctx);
+	if (ctx->param != NULL)
+		{
+		if (ctx->parent == NULL)
+			X509_VERIFY_PARAM_free(ctx->param);
+		ctx->param=NULL;
+		}
+	if (ctx->tree != NULL)
+		{
+		X509_policy_tree_free(ctx->tree);
+		ctx->tree=NULL;
+		}
+	if (ctx->chain != NULL)
+		{
+		sk_X509_pop_free(ctx->chain,X509_free);
+		ctx->chain=NULL;
+		}
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data));
+	memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA));
+	}
+
+void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
+	{
+	X509_VERIFY_PARAM_set_depth(ctx->param, depth);
+	}
+
+void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags)
+	{
+	X509_VERIFY_PARAM_set_flags(ctx->param, flags);
+	}
+
+void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t)
+	{
+	X509_VERIFY_PARAM_set_time(ctx->param, t);
+	}
+
+void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
+				  int (*verify_cb)(int, X509_STORE_CTX *))
+	{
+	ctx->verify_cb=verify_cb;
+	}
+
+X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
+	{
+	return ctx->tree;
+	}
+
+int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
+	{
+	return ctx->explicit_policy;
+	}
+
+int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
+	{
+	const X509_VERIFY_PARAM *param;
+	param = X509_VERIFY_PARAM_lookup(name);
+	if (!param)
+		return 0;
+	return X509_VERIFY_PARAM_inherit(ctx->param, param);
+	}
+
+X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx)
+	{
+	return ctx->param;
+	}
+
+void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
+	{
+	if (ctx->param)
+		X509_VERIFY_PARAM_free(ctx->param);
+	ctx->param = param;
+	}
+
+IMPLEMENT_STACK_OF(X509)
+IMPLEMENT_ASN1_SET_OF(X509)
+
+IMPLEMENT_STACK_OF(X509_NAME)
+
+IMPLEMENT_STACK_OF(X509_ATTRIBUTE)
+IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)
diff --git a/openssl/crypto/x509/x509_vfy.h b/openssl/crypto/x509/x509_vfy.h
new file mode 100644
index 0000000..fe09b30
--- /dev/null
+++ b/openssl/crypto/x509/x509_vfy.h
@@ -0,0 +1,567 @@
+/* crypto/x509/x509_vfy.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_X509_H
+#include <openssl/x509.h>
+/* openssl/x509.h ends up #include-ing this file at about the only
+ * appropriate moment. */
+#endif
+
+#ifndef HEADER_X509_VFY_H
+#define HEADER_X509_VFY_H
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_LHASH
+#include <openssl/lhash.h>
+#endif
+#include <openssl/bio.h>
+#include <openssl/crypto.h>
+#include <openssl/symhacks.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if 0
+/* Outer object */
+typedef struct x509_hash_dir_st
+	{
+	int num_dirs;
+	char **dirs;
+	int *dirs_type;
+	int num_dirs_alloced;
+	} X509_HASH_DIR_CTX;
+#endif
+
+typedef struct x509_file_st
+	{
+	int num_paths;	/* number of paths to files or directories */
+	int num_alloced;
+	char **paths;	/* the list of paths or directories */
+	int *path_type;
+	} X509_CERT_FILE_CTX;
+
+/*******************************/
+/*
+SSL_CTX -> X509_STORE    
+		-> X509_LOOKUP
+			->X509_LOOKUP_METHOD
+		-> X509_LOOKUP
+			->X509_LOOKUP_METHOD
+ 
+SSL	-> X509_STORE_CTX
+		->X509_STORE    
+
+The X509_STORE holds the tables etc for verification stuff.
+A X509_STORE_CTX is used while validating a single certificate.
+The X509_STORE has X509_LOOKUPs for looking up certs.
+The X509_STORE then calls a function to actually verify the
+certificate chain.
+*/
+
+#define X509_LU_RETRY		-1
+#define X509_LU_FAIL		0
+#define X509_LU_X509		1
+#define X509_LU_CRL		2
+#define X509_LU_PKEY		3
+
+typedef struct x509_object_st
+	{
+	/* one of the above types */
+	int type;
+	union	{
+		char *ptr;
+		X509 *x509;
+		X509_CRL *crl;
+		EVP_PKEY *pkey;
+		} data;
+	} X509_OBJECT;
+
+typedef struct x509_lookup_st X509_LOOKUP;
+
+DECLARE_STACK_OF(X509_LOOKUP)
+DECLARE_STACK_OF(X509_OBJECT)
+
+/* This is a static that defines the function interface */
+typedef struct x509_lookup_method_st
+	{
+	const char *name;
+	int (*new_item)(X509_LOOKUP *ctx);
+	void (*free)(X509_LOOKUP *ctx);
+	int (*init)(X509_LOOKUP *ctx);
+	int (*shutdown)(X509_LOOKUP *ctx);
+	int (*ctrl)(X509_LOOKUP *ctx,int cmd,const char *argc,long argl,
+			char **ret);
+	int (*get_by_subject)(X509_LOOKUP *ctx,int type,X509_NAME *name,
+			      X509_OBJECT *ret);
+	int (*get_by_issuer_serial)(X509_LOOKUP *ctx,int type,X509_NAME *name,
+				    ASN1_INTEGER *serial,X509_OBJECT *ret);
+	int (*get_by_fingerprint)(X509_LOOKUP *ctx,int type,
+				  unsigned char *bytes,int len,
+				  X509_OBJECT *ret);
+	int (*get_by_alias)(X509_LOOKUP *ctx,int type,char *str,int len,
+			    X509_OBJECT *ret);
+	} X509_LOOKUP_METHOD;
+
+/* This structure hold all parameters associated with a verify operation
+ * by including an X509_VERIFY_PARAM structure in related structures the
+ * parameters used can be customized
+ */
+
+typedef struct X509_VERIFY_PARAM_st
+	{
+	char *name;
+	time_t check_time;	/* Time to use */
+	unsigned long inh_flags; /* Inheritance flags */
+	unsigned long flags;	/* Various verify flags */
+	int purpose;		/* purpose to check untrusted certificates */
+	int trust;		/* trust setting to check */
+	int depth;		/* Verify depth */
+	STACK_OF(ASN1_OBJECT) *policies;	/* Permissible policies */
+	} X509_VERIFY_PARAM;
+
+DECLARE_STACK_OF(X509_VERIFY_PARAM)
+
+/* This is used to hold everything.  It is used for all certificate
+ * validation.  Once we have a certificate chain, the 'verify'
+ * function is then called to actually check the cert chain. */
+struct x509_store_st
+	{
+	/* The following is a cache of trusted certs */
+	int cache; 	/* if true, stash any hits */
+	STACK_OF(X509_OBJECT) *objs;	/* Cache of all objects */
+
+	/* These are external lookup methods */
+	STACK_OF(X509_LOOKUP) *get_cert_methods;
+
+	X509_VERIFY_PARAM *param;
+
+	/* Callbacks for various operations */
+	int (*verify)(X509_STORE_CTX *ctx);	/* called to verify a certificate */
+	int (*verify_cb)(int ok,X509_STORE_CTX *ctx);	/* error callback */
+	int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);	/* get issuers cert from ctx */
+	int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */
+	int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */
+	int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */
+	int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
+	int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
+	STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm);
+	STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
+	int (*cleanup)(X509_STORE_CTX *ctx);
+
+	CRYPTO_EX_DATA ex_data;
+	int references;
+	} /* X509_STORE */;
+
+int X509_STORE_set_depth(X509_STORE *store, int depth);
+
+#define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func))
+#define X509_STORE_set_verify_func(ctx,func)	((ctx)->verify=(func))
+
+/* This is the functions plus an instance of the local variables. */
+struct x509_lookup_st
+	{
+	int init;			/* have we been started */
+	int skip;			/* don't use us. */
+	X509_LOOKUP_METHOD *method;	/* the functions */
+	char *method_data;		/* method data */
+
+	X509_STORE *store_ctx;	/* who owns us */
+	} /* X509_LOOKUP */;
+
+/* This is a used when verifying cert chains.  Since the
+ * gathering of the cert chain can take some time (and have to be
+ * 'retried', this needs to be kept and passed around. */
+struct x509_store_ctx_st      /* X509_STORE_CTX */
+	{
+	X509_STORE *ctx;
+	int current_method;	/* used when looking up certs */
+
+	/* The following are set by the caller */
+	X509 *cert;		/* The cert to check */
+	STACK_OF(X509) *untrusted;	/* chain of X509s - untrusted - passed in */
+	STACK_OF(X509_CRL) *crls;	/* set of CRLs passed in */
+
+	X509_VERIFY_PARAM *param;
+	void *other_ctx;	/* Other info for use with get_issuer() */
+
+	/* Callbacks for various operations */
+	int (*verify)(X509_STORE_CTX *ctx);	/* called to verify a certificate */
+	int (*verify_cb)(int ok,X509_STORE_CTX *ctx);		/* error callback */
+	int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);	/* get issuers cert from ctx */
+	int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */
+	int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */
+	int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */
+	int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
+	int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
+	int (*check_policy)(X509_STORE_CTX *ctx);
+	STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm);
+	STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
+	int (*cleanup)(X509_STORE_CTX *ctx);
+
+	/* The following is built up */
+	int valid;		/* if 0, rebuild chain */
+	int last_untrusted;	/* index of last untrusted cert */
+	STACK_OF(X509) *chain; 		/* chain of X509s - built up and trusted */
+	X509_POLICY_TREE *tree;	/* Valid policy tree */
+
+	int explicit_policy;	/* Require explicit policy value */
+
+	/* When something goes wrong, this is why */
+	int error_depth;
+	int error;
+	X509 *current_cert;
+	X509 *current_issuer;	/* cert currently being tested as valid issuer */
+	X509_CRL *current_crl;	/* current CRL */
+
+	int current_crl_score;  /* score of current CRL */
+	unsigned int current_reasons;  /* Reason mask */
+
+	X509_STORE_CTX *parent; /* For CRL path validation: parent context */
+
+	CRYPTO_EX_DATA ex_data;
+	} /* X509_STORE_CTX */;
+
+void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
+
+#define X509_STORE_CTX_set_app_data(ctx,data) \
+	X509_STORE_CTX_set_ex_data(ctx,0,data)
+#define X509_STORE_CTX_get_app_data(ctx) \
+	X509_STORE_CTX_get_ex_data(ctx,0)
+
+#define X509_L_FILE_LOAD	1
+#define X509_L_ADD_DIR		2
+
+#define X509_LOOKUP_load_file(x,name,type) \
+		X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL)
+
+#define X509_LOOKUP_add_dir(x,name,type) \
+		X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL)
+
+#define		X509_V_OK					0
+/* illegal error (for uninitialized values, to avoid X509_V_OK): 1 */
+
+#define		X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT		2
+#define		X509_V_ERR_UNABLE_TO_GET_CRL			3
+#define		X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE	4
+#define		X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE	5
+#define		X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY	6
+#define		X509_V_ERR_CERT_SIGNATURE_FAILURE		7
+#define		X509_V_ERR_CRL_SIGNATURE_FAILURE		8
+#define		X509_V_ERR_CERT_NOT_YET_VALID			9
+#define		X509_V_ERR_CERT_HAS_EXPIRED			10
+#define		X509_V_ERR_CRL_NOT_YET_VALID			11
+#define		X509_V_ERR_CRL_HAS_EXPIRED			12
+#define		X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD	13
+#define		X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD	14
+#define		X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD	15
+#define		X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD	16
+#define		X509_V_ERR_OUT_OF_MEM				17
+#define		X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT		18
+#define		X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN		19
+#define		X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY	20
+#define		X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE	21
+#define		X509_V_ERR_CERT_CHAIN_TOO_LONG			22
+#define		X509_V_ERR_CERT_REVOKED				23
+#define		X509_V_ERR_INVALID_CA				24
+#define		X509_V_ERR_PATH_LENGTH_EXCEEDED			25
+#define		X509_V_ERR_INVALID_PURPOSE			26
+#define		X509_V_ERR_CERT_UNTRUSTED			27
+#define		X509_V_ERR_CERT_REJECTED			28
+/* These are 'informational' when looking for issuer cert */
+#define		X509_V_ERR_SUBJECT_ISSUER_MISMATCH		29
+#define		X509_V_ERR_AKID_SKID_MISMATCH			30
+#define		X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH		31
+#define		X509_V_ERR_KEYUSAGE_NO_CERTSIGN			32
+
+#define		X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER		33
+#define		X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION		34
+#define		X509_V_ERR_KEYUSAGE_NO_CRL_SIGN			35
+#define		X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION	36
+#define		X509_V_ERR_INVALID_NON_CA			37
+#define		X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED		38
+#define		X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE	39
+#define		X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED	40
+
+#define		X509_V_ERR_INVALID_EXTENSION			41
+#define		X509_V_ERR_INVALID_POLICY_EXTENSION		42
+#define		X509_V_ERR_NO_EXPLICIT_POLICY			43
+#define		X509_V_ERR_DIFFERENT_CRL_SCOPE			44
+#define		X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE	45
+
+#define		X509_V_ERR_UNNESTED_RESOURCE			46
+
+#define		X509_V_ERR_PERMITTED_VIOLATION			47
+#define		X509_V_ERR_EXCLUDED_VIOLATION			48
+#define		X509_V_ERR_SUBTREE_MINMAX			49
+#define		X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE		51
+#define		X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX	52
+#define		X509_V_ERR_UNSUPPORTED_NAME_SYNTAX		53
+#define		X509_V_ERR_CRL_PATH_VALIDATION_ERROR		54
+
+/* The application is not happy */
+#define		X509_V_ERR_APPLICATION_VERIFICATION		50
+
+/* Certificate verify flags */
+
+/* Send issuer+subject checks to verify_cb */
+#define	X509_V_FLAG_CB_ISSUER_CHECK		0x1
+/* Use check time instead of current time */
+#define	X509_V_FLAG_USE_CHECK_TIME		0x2
+/* Lookup CRLs */
+#define	X509_V_FLAG_CRL_CHECK			0x4
+/* Lookup CRLs for whole chain */
+#define	X509_V_FLAG_CRL_CHECK_ALL		0x8
+/* Ignore unhandled critical extensions */
+#define	X509_V_FLAG_IGNORE_CRITICAL		0x10
+/* Disable workarounds for broken certificates */
+#define	X509_V_FLAG_X509_STRICT			0x20
+/* Enable proxy certificate validation */
+#define	X509_V_FLAG_ALLOW_PROXY_CERTS		0x40
+/* Enable policy checking */
+#define X509_V_FLAG_POLICY_CHECK		0x80
+/* Policy variable require-explicit-policy */
+#define X509_V_FLAG_EXPLICIT_POLICY		0x100
+/* Policy variable inhibit-any-policy */
+#define	X509_V_FLAG_INHIBIT_ANY			0x200
+/* Policy variable inhibit-policy-mapping */
+#define X509_V_FLAG_INHIBIT_MAP			0x400
+/* Notify callback that policy is OK */
+#define X509_V_FLAG_NOTIFY_POLICY		0x800
+/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */
+#define X509_V_FLAG_EXTENDED_CRL_SUPPORT	0x1000
+/* Delta CRL support */
+#define X509_V_FLAG_USE_DELTAS			0x2000
+/* Check selfsigned CA signature */
+#define X509_V_FLAG_CHECK_SS_SIGNATURE		0x4000
+
+
+#define X509_VP_FLAG_DEFAULT			0x1
+#define X509_VP_FLAG_OVERWRITE			0x2
+#define X509_VP_FLAG_RESET_FLAGS		0x4
+#define X509_VP_FLAG_LOCKED			0x8
+#define X509_VP_FLAG_ONCE			0x10
+
+/* Internal use: mask of policy related options */
+#define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \
+				| X509_V_FLAG_EXPLICIT_POLICY \
+				| X509_V_FLAG_INHIBIT_ANY \
+				| X509_V_FLAG_INHIBIT_MAP)
+
+int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
+	     X509_NAME *name);
+X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,int type,X509_NAME *name);
+X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x);
+void X509_OBJECT_up_ref_count(X509_OBJECT *a);
+void X509_OBJECT_free_contents(X509_OBJECT *a);
+X509_STORE *X509_STORE_new(void );
+void X509_STORE_free(X509_STORE *v);
+
+STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
+STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm);
+int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
+int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
+int X509_STORE_set_trust(X509_STORE *ctx, int trust);
+int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
+
+void X509_STORE_set_verify_cb(X509_STORE *ctx,
+				  int (*verify_cb)(int, X509_STORE_CTX *));
+
+X509_STORE_CTX *X509_STORE_CTX_new(void);
+
+int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+
+void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
+int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
+			 X509 *x509, STACK_OF(X509) *chain);
+void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
+void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
+
+X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m);
+
+X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void);
+X509_LOOKUP_METHOD *X509_LOOKUP_file(void);
+
+int X509_STORE_add_cert(X509_STORE *ctx, X509 *x);
+int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x);
+
+int X509_STORE_get_by_subject(X509_STORE_CTX *vs,int type,X509_NAME *name,
+	X509_OBJECT *ret);
+
+int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
+	long argl, char **ret);
+
+#ifndef OPENSSL_NO_STDIO
+int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+#endif
+
+
+X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method);
+void X509_LOOKUP_free(X509_LOOKUP *ctx);
+int X509_LOOKUP_init(X509_LOOKUP *ctx);
+int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
+	X509_OBJECT *ret);
+int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
+	ASN1_INTEGER *serial, X509_OBJECT *ret);
+int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
+	unsigned char *bytes, int len, X509_OBJECT *ret);
+int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str,
+	int len, X509_OBJECT *ret);
+int X509_LOOKUP_shutdown(X509_LOOKUP *ctx);
+
+#ifndef OPENSSL_NO_STDIO
+int	X509_STORE_load_locations (X509_STORE *ctx,
+		const char *file, const char *dir);
+int	X509_STORE_set_default_paths(X509_STORE *ctx);
+#endif
+
+int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int	X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data);
+void *	X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx);
+int	X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
+void	X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s);
+int	X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
+X509 *	X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
+X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx);
+X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx);
+X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx);
+STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
+STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
+void	X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x);
+void	X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk);
+void	X509_STORE_CTX_set0_crls(X509_STORE_CTX *c,STACK_OF(X509_CRL) *sk);
+int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
+int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
+int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
+				int purpose, int trust);
+void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags);
+void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
+								time_t t);
+void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
+				  int (*verify_cb)(int, X509_STORE_CTX *));
+  
+X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx);
+int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx);
+
+X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
+int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);
+
+/* X509_VERIFY_PARAM functions */
+
+X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void);
+void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param);
+int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to,
+						const X509_VERIFY_PARAM *from);
+int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, 
+						const X509_VERIFY_PARAM *from);
+int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name);
+int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags);
+int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
+							unsigned long flags);
+unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param);
+int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose);
+int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust);
+void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth);
+void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t);
+int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
+						ASN1_OBJECT *policy);
+int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, 
+					STACK_OF(ASN1_OBJECT) *policies);
+int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
+
+int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param);
+const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name);
+void X509_VERIFY_PARAM_table_cleanup(void);
+
+int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
+			STACK_OF(X509) *certs,
+			STACK_OF(ASN1_OBJECT) *policy_oids,
+			unsigned int flags);
+
+void X509_policy_tree_free(X509_POLICY_TREE *tree);
+
+int X509_policy_tree_level_count(const X509_POLICY_TREE *tree);
+X509_POLICY_LEVEL *
+	X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i);
+
+STACK_OF(X509_POLICY_NODE) *
+	X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree);
+
+STACK_OF(X509_POLICY_NODE) *
+	X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree);
+
+int X509_policy_level_node_count(X509_POLICY_LEVEL *level);
+
+X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i);
+
+const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node);
+
+STACK_OF(POLICYQUALINFO) *
+	X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node);
+const X509_POLICY_NODE *
+	X509_policy_node_get0_parent(const X509_POLICY_NODE *node);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/openssl/crypto/x509/x509_vpm.c b/openssl/crypto/x509/x509_vpm.c
new file mode 100644
index 0000000..dfd89d8
--- /dev/null
+++ b/openssl/crypto/x509/x509_vpm.c
@@ -0,0 +1,438 @@
+/* x509_vpm.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+
+#include "cryptlib.h"
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+#include <openssl/buffer.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+/* X509_VERIFY_PARAM functions */
+
+static void x509_verify_param_zero(X509_VERIFY_PARAM *param)
+	{
+	if (!param)
+		return;
+	param->name = NULL;
+	param->purpose = 0;
+	param->trust = 0;
+	/*param->inh_flags = X509_VP_FLAG_DEFAULT;*/
+	param->inh_flags = 0;
+	param->flags = 0;
+	param->depth = -1;
+	if (param->policies)
+		{
+		sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
+		param->policies = NULL;
+		}
+	}
+
+X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
+	{
+	X509_VERIFY_PARAM *param;
+	param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM));
+	memset(param, 0, sizeof(X509_VERIFY_PARAM));
+	x509_verify_param_zero(param);
+	return param;
+	}
+
+void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
+	{
+	x509_verify_param_zero(param);
+	OPENSSL_free(param);
+	}
+
+/* This function determines how parameters are "inherited" from one structure
+ * to another. There are several different ways this can happen.
+ *
+ * 1. If a child structure needs to have its values initialized from a parent
+ *    they are simply copied across. For example SSL_CTX copied to SSL.
+ * 2. If the structure should take on values only if they are currently unset.
+ *    For example the values in an SSL structure will take appropriate value
+ *    for SSL servers or clients but only if the application has not set new
+ *    ones.
+ *
+ * The "inh_flags" field determines how this function behaves. 
+ *
+ * Normally any values which are set in the default are not copied from the
+ * destination and verify flags are ORed together.
+ *
+ * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied
+ * to the destination. Effectively the values in "to" become default values
+ * which will be used only if nothing new is set in "from".
+ *
+ * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether
+ * they are set or not. Flags is still Ored though.
+ *
+ * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead
+ * of ORed.
+ *
+ * If X509_VP_FLAG_LOCKED is set then no values are copied.
+ *
+ * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed
+ * after the next call.
+ */
+
+/* Macro to test if a field should be copied from src to dest */
+
+#define test_x509_verify_param_copy(field, def) \
+	(to_overwrite || \
+		((src->field != def) && (to_default || (dest->field == def))))
+
+/* Macro to test and copy a field if necessary */
+
+#define x509_verify_param_copy(field, def) \
+	if (test_x509_verify_param_copy(field, def)) \
+		dest->field = src->field
+		
+
+int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
+						const X509_VERIFY_PARAM *src)
+	{
+	unsigned long inh_flags;
+	int to_default, to_overwrite;
+	if (!src)
+		return 1;
+	inh_flags = dest->inh_flags | src->inh_flags;
+
+	if (inh_flags & X509_VP_FLAG_ONCE)
+		dest->inh_flags = 0;
+
+	if (inh_flags & X509_VP_FLAG_LOCKED)
+		return 1;
+
+	if (inh_flags & X509_VP_FLAG_DEFAULT)
+		to_default = 1;
+	else
+		to_default = 0;
+
+	if (inh_flags & X509_VP_FLAG_OVERWRITE)
+		to_overwrite = 1;
+	else
+		to_overwrite = 0;
+
+	x509_verify_param_copy(purpose, 0);
+	x509_verify_param_copy(trust, 0);
+	x509_verify_param_copy(depth, -1);
+
+	/* If overwrite or check time not set, copy across */
+
+	if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME))
+		{
+		dest->check_time = src->check_time;
+		dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
+		/* Don't need to copy flag: that is done below */
+		}
+
+	if (inh_flags & X509_VP_FLAG_RESET_FLAGS)
+		dest->flags = 0;
+
+	dest->flags |= src->flags;
+
+	if (test_x509_verify_param_copy(policies, NULL))
+		{
+		if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies))
+			return 0;
+		}
+
+	return 1;
+	}
+
+int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
+						const X509_VERIFY_PARAM *from)
+	{
+	unsigned long save_flags = to->inh_flags;
+	int ret;
+	to->inh_flags |= X509_VP_FLAG_DEFAULT;
+	ret = X509_VERIFY_PARAM_inherit(to, from);
+	to->inh_flags = save_flags;
+	return ret;
+	}
+
+int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
+	{
+	if (param->name)
+		OPENSSL_free(param->name);
+	param->name = BUF_strdup(name);
+	if (param->name)
+		return 1;
+	return 0;
+	}
+
+int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags)
+	{
+	param->flags |= flags;
+	if (flags & X509_V_FLAG_POLICY_MASK)
+		param->flags |= X509_V_FLAG_POLICY_CHECK;
+	return 1;
+	}
+
+int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags)
+	{
+	param->flags &= ~flags;
+	return 1;
+	}
+
+unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
+	{
+	return param->flags;
+	}
+
+int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
+	{
+	return X509_PURPOSE_set(&param->purpose, purpose);
+	}
+
+int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust)
+	{
+	return X509_TRUST_set(&param->trust, trust);
+	}
+
+void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
+	{
+	param->depth = depth;
+	}
+
+void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t)
+	{
+	param->check_time = t;
+	param->flags |= X509_V_FLAG_USE_CHECK_TIME;
+	}
+
+int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy)
+	{
+	if (!param->policies)
+		{
+		param->policies = sk_ASN1_OBJECT_new_null();
+		if (!param->policies)
+			return 0;
+		}
+	if (!sk_ASN1_OBJECT_push(param->policies, policy))
+		return 0;
+	return 1;
+	}
+
+int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, 
+					STACK_OF(ASN1_OBJECT) *policies)
+	{
+	int i;
+	ASN1_OBJECT *oid, *doid;
+	if (!param)
+		return 0;
+	if (param->policies)
+		sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
+
+	if (!policies)
+		{
+		param->policies = NULL;
+		return 1;
+		}
+
+	param->policies = sk_ASN1_OBJECT_new_null();
+	if (!param->policies)
+		return 0;
+
+	for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++)
+		{
+		oid = sk_ASN1_OBJECT_value(policies, i);
+		doid = OBJ_dup(oid);
+		if (!doid)
+			return 0;
+		if (!sk_ASN1_OBJECT_push(param->policies, doid))
+			{
+			ASN1_OBJECT_free(doid);
+			return 0;
+			}
+		}
+	param->flags |= X509_V_FLAG_POLICY_CHECK;
+	return 1;
+	}
+
+int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
+	{
+	return param->depth;
+	}
+
+/* Default verify parameters: these are used for various
+ * applications and can be overridden by the user specified table.
+ * NB: the 'name' field *must* be in alphabetical order because it
+ * will be searched using OBJ_search.
+ */
+
+static const X509_VERIFY_PARAM default_table[] = {
+	{
+	"default",	/* X509 default parameters */
+	0,		/* Check time */
+	0,		/* internal flags */
+	0,		/* flags */
+	0,		/* purpose */
+	0,		/* trust */
+	100,		/* depth */
+	NULL		/* policies */
+	},
+	{
+	"pkcs7",			/* S/MIME sign parameters */
+	0,				/* Check time */
+	0,				/* internal flags */
+	0,				/* flags */
+	X509_PURPOSE_SMIME_SIGN,	/* purpose */
+	X509_TRUST_EMAIL,		/* trust */
+	-1,				/* depth */
+	NULL				/* policies */
+	},
+	{
+	"smime_sign",			/* S/MIME sign parameters */
+	0,				/* Check time */
+	0,				/* internal flags */
+	0,				/* flags */
+	X509_PURPOSE_SMIME_SIGN,	/* purpose */
+	X509_TRUST_EMAIL,		/* trust */
+	-1,				/* depth */
+	NULL				/* policies */
+	},
+	{
+	"ssl_client",			/* SSL/TLS client parameters */
+	0,				/* Check time */
+	0,				/* internal flags */
+	0,				/* flags */
+	X509_PURPOSE_SSL_CLIENT,	/* purpose */
+	X509_TRUST_SSL_CLIENT,		/* trust */
+	-1,				/* depth */
+	NULL				/* policies */
+	},
+	{
+	"ssl_server",			/* SSL/TLS server parameters */
+	0,				/* Check time */
+	0,				/* internal flags */
+	0,				/* flags */
+	X509_PURPOSE_SSL_SERVER,	/* purpose */
+	X509_TRUST_SSL_SERVER,		/* trust */
+	-1,				/* depth */
+	NULL				/* policies */
+	}};
+
+static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
+
+static int table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b)
+
+	{
+	return strcmp(a->name, b->name);
+	}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM,
+			   table);
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM,
+			     table);
+
+static int param_cmp(const X509_VERIFY_PARAM * const *a,
+			const X509_VERIFY_PARAM * const *b)
+	{
+	return strcmp((*a)->name, (*b)->name);
+	}
+
+int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
+	{
+	int idx;
+	X509_VERIFY_PARAM *ptmp;
+	if (!param_table)
+		{
+		param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
+		if (!param_table)
+			return 0;
+		}
+	else
+		{
+		idx = sk_X509_VERIFY_PARAM_find(param_table, param);
+		if (idx != -1)
+			{
+			ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
+			X509_VERIFY_PARAM_free(ptmp);
+			(void)sk_X509_VERIFY_PARAM_delete(param_table, idx);
+			}
+		}
+	if (!sk_X509_VERIFY_PARAM_push(param_table, param))
+		return 0;
+	return 1;
+	}
+
+const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
+	{
+	int idx;
+	X509_VERIFY_PARAM pm;
+
+	pm.name = (char *)name;
+	if (param_table)
+		{
+		idx = sk_X509_VERIFY_PARAM_find(param_table, &pm);
+		if (idx != -1)
+			return sk_X509_VERIFY_PARAM_value(param_table, idx);
+		}
+	return OBJ_bsearch_table(&pm, default_table,
+			   sizeof(default_table)/sizeof(X509_VERIFY_PARAM));
+	}
+
+void X509_VERIFY_PARAM_table_cleanup(void)
+	{
+	if (param_table)
+		sk_X509_VERIFY_PARAM_pop_free(param_table,
+						X509_VERIFY_PARAM_free);
+	param_table = NULL;
+	}
diff --git a/openssl/crypto/x509/x509cset.c b/openssl/crypto/x509/x509cset.c
new file mode 100644
index 0000000..3109def
--- /dev/null
+++ b/openssl/crypto/x509/x509cset.c
@@ -0,0 +1,170 @@
+/* crypto/x509/x509cset.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+int X509_CRL_set_version(X509_CRL *x, long version)
+	{
+	if (x == NULL) return(0);
+	if (x->crl->version == NULL)
+		{
+		if ((x->crl->version=M_ASN1_INTEGER_new()) == NULL)
+			return(0);
+		}
+	return(ASN1_INTEGER_set(x->crl->version,version));
+	}
+
+int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name)
+	{
+	if ((x == NULL) || (x->crl == NULL)) return(0);
+	return(X509_NAME_set(&x->crl->issuer,name));
+	}
+
+
+int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm)
+	{
+	ASN1_TIME *in;
+
+	if (x == NULL) return(0);
+	in=x->crl->lastUpdate;
+	if (in != tm)
+		{
+		in=M_ASN1_TIME_dup(tm);
+		if (in != NULL)
+			{
+			M_ASN1_TIME_free(x->crl->lastUpdate);
+			x->crl->lastUpdate=in;
+			}
+		}
+	return(in != NULL);
+	}
+
+int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm)
+	{
+	ASN1_TIME *in;
+
+	if (x == NULL) return(0);
+	in=x->crl->nextUpdate;
+	if (in != tm)
+		{
+		in=M_ASN1_TIME_dup(tm);
+		if (in != NULL)
+			{
+			M_ASN1_TIME_free(x->crl->nextUpdate);
+			x->crl->nextUpdate=in;
+			}
+		}
+	return(in != NULL);
+	}
+
+int X509_CRL_sort(X509_CRL *c)
+	{
+	int i;
+	X509_REVOKED *r;
+	/* sort the data so it will be written in serial
+	 * number order */
+	sk_X509_REVOKED_sort(c->crl->revoked);
+	for (i=0; i<sk_X509_REVOKED_num(c->crl->revoked); i++)
+		{
+		r=sk_X509_REVOKED_value(c->crl->revoked,i);
+		r->sequence=i;
+		}
+	c->crl->enc.modified = 1;
+	return 1;
+	}
+
+int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm)
+	{
+	ASN1_TIME *in;
+
+	if (x == NULL) return(0);
+	in=x->revocationDate;
+	if (in != tm)
+		{
+		in=M_ASN1_TIME_dup(tm);
+		if (in != NULL)
+			{
+			M_ASN1_TIME_free(x->revocationDate);
+			x->revocationDate=in;
+			}
+		}
+	return(in != NULL);
+	}
+
+int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial)
+	{
+	ASN1_INTEGER *in;
+
+	if (x == NULL) return(0);
+	in=x->serialNumber;
+	if (in != serial)
+		{
+		in=M_ASN1_INTEGER_dup(serial);
+		if (in != NULL)
+			{
+			M_ASN1_INTEGER_free(x->serialNumber);
+			x->serialNumber=in;
+			}
+		}
+	return(in != NULL);
+	}
diff --git a/openssl/crypto/x509/x509name.c b/openssl/crypto/x509/x509name.c
new file mode 100644
index 0000000..27bc4dc
--- /dev/null
+++ b/openssl/crypto/x509/x509name.c
@@ -0,0 +1,383 @@
+/* crypto/x509/x509name.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/stack.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
+	{
+	ASN1_OBJECT *obj;
+
+	obj=OBJ_nid2obj(nid);
+	if (obj == NULL) return(-1);
+	return(X509_NAME_get_text_by_OBJ(name,obj,buf,len));
+	}
+
+int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf,
+	     int len)
+	{
+	int i;
+	ASN1_STRING *data;
+
+	i=X509_NAME_get_index_by_OBJ(name,obj,-1);
+	if (i < 0) return(-1);
+	data=X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name,i));
+	i=(data->length > (len-1))?(len-1):data->length;
+	if (buf == NULL) return(data->length);
+	memcpy(buf,data->data,i);
+	buf[i]='\0';
+	return(i);
+	}
+
+int X509_NAME_entry_count(X509_NAME *name)
+	{
+	if (name == NULL) return(0);
+	return(sk_X509_NAME_ENTRY_num(name->entries));
+	}
+
+int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos)
+	{
+	ASN1_OBJECT *obj;
+
+	obj=OBJ_nid2obj(nid);
+	if (obj == NULL) return(-2);
+	return(X509_NAME_get_index_by_OBJ(name,obj,lastpos));
+	}
+
+/* NOTE: you should be passsing -1, not 0 as lastpos */
+int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
+	     int lastpos)
+	{
+	int n;
+	X509_NAME_ENTRY *ne;
+	STACK_OF(X509_NAME_ENTRY) *sk;
+
+	if (name == NULL) return(-1);
+	if (lastpos < 0)
+		lastpos= -1;
+	sk=name->entries;
+	n=sk_X509_NAME_ENTRY_num(sk);
+	for (lastpos++; lastpos < n; lastpos++)
+		{
+		ne=sk_X509_NAME_ENTRY_value(sk,lastpos);
+		if (OBJ_cmp(ne->object,obj) == 0)
+			return(lastpos);
+		}
+	return(-1);
+	}
+
+X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc)
+	{
+	if(name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc
+	   || loc < 0)
+		return(NULL);
+	else
+		return(sk_X509_NAME_ENTRY_value(name->entries,loc));
+	}
+
+X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc)
+	{
+	X509_NAME_ENTRY *ret;
+	int i,n,set_prev,set_next;
+	STACK_OF(X509_NAME_ENTRY) *sk;
+
+	if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc
+	    || loc < 0)
+		return(NULL);
+	sk=name->entries;
+	ret=sk_X509_NAME_ENTRY_delete(sk,loc);
+	n=sk_X509_NAME_ENTRY_num(sk);
+	name->modified=1;
+	if (loc == n) return(ret);
+
+	/* else we need to fixup the set field */
+	if (loc != 0)
+		set_prev=(sk_X509_NAME_ENTRY_value(sk,loc-1))->set;
+	else
+		set_prev=ret->set-1;
+	set_next=sk_X509_NAME_ENTRY_value(sk,loc)->set;
+
+	/* set_prev is the previous set
+	 * set is the current set
+	 * set_next is the following
+	 * prev  1 1	1 1	1 1	1 1
+	 * set   1	1	2	2
+	 * next  1 1	2 2	2 2	3 2
+	 * so basically only if prev and next differ by 2, then
+	 * re-number down by 1 */
+	if (set_prev+1 < set_next)
+		for (i=loc; i<n; i++)
+			sk_X509_NAME_ENTRY_value(sk,i)->set--;
+	return(ret);
+	}
+
+int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
+			unsigned char *bytes, int len, int loc, int set)
+{
+	X509_NAME_ENTRY *ne;
+	int ret;
+	ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len);
+	if(!ne) return 0;
+	ret = X509_NAME_add_entry(name, ne, loc, set);
+	X509_NAME_ENTRY_free(ne);
+	return ret;
+}
+
+int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
+			unsigned char *bytes, int len, int loc, int set)
+{
+	X509_NAME_ENTRY *ne;
+	int ret;
+	ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
+	if(!ne) return 0;
+	ret = X509_NAME_add_entry(name, ne, loc, set);
+	X509_NAME_ENTRY_free(ne);
+	return ret;
+}
+
+int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
+			const unsigned char *bytes, int len, int loc, int set)
+{
+	X509_NAME_ENTRY *ne;
+	int ret;
+	ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len);
+	if(!ne) return 0;
+	ret = X509_NAME_add_entry(name, ne, loc, set);
+	X509_NAME_ENTRY_free(ne);
+	return ret;
+}
+
+/* if set is -1, append to previous set, 0 'a new one', and 1,
+ * prepend to the guy we are about to stomp on. */
+int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc,
+	     int set)
+	{
+	X509_NAME_ENTRY *new_name=NULL;
+	int n,i,inc;
+	STACK_OF(X509_NAME_ENTRY) *sk;
+
+	if (name == NULL) return(0);
+	sk=name->entries;
+	n=sk_X509_NAME_ENTRY_num(sk);
+	if (loc > n) loc=n;
+	else if (loc < 0) loc=n;
+
+	name->modified=1;
+
+	if (set == -1)
+		{
+		if (loc == 0)
+			{
+			set=0;
+			inc=1;
+			}
+		else
+			{
+			set=sk_X509_NAME_ENTRY_value(sk,loc-1)->set;
+			inc=0;
+			}
+		}
+	else /* if (set >= 0) */
+		{
+		if (loc >= n)
+			{
+			if (loc != 0)
+				set=sk_X509_NAME_ENTRY_value(sk,loc-1)->set+1;
+			else
+				set=0;
+			}
+		else
+			set=sk_X509_NAME_ENTRY_value(sk,loc)->set;
+		inc=(set == 0)?1:0;
+		}
+
+	if ((new_name=X509_NAME_ENTRY_dup(ne)) == NULL)
+		goto err;
+	new_name->set=set;
+	if (!sk_X509_NAME_ENTRY_insert(sk,new_name,loc))
+		{
+		X509err(X509_F_X509_NAME_ADD_ENTRY,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	if (inc)
+		{
+		n=sk_X509_NAME_ENTRY_num(sk);
+		for (i=loc+1; i<n; i++)
+			sk_X509_NAME_ENTRY_value(sk,i-1)->set+=1;
+		}	
+	return(1);
+err:
+	if (new_name != NULL)
+		X509_NAME_ENTRY_free(new_name);
+	return(0);
+	}
+
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
+		const char *field, int type, const unsigned char *bytes, int len)
+	{
+	ASN1_OBJECT *obj;
+	X509_NAME_ENTRY *nentry;
+
+	obj=OBJ_txt2obj(field, 0);
+	if (obj == NULL)
+		{
+		X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT,
+						X509_R_INVALID_FIELD_NAME);
+		ERR_add_error_data(2, "name=", field);
+		return(NULL);
+		}
+	nentry = X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len);
+	ASN1_OBJECT_free(obj);
+	return nentry;
+	}
+
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
+	     int type, unsigned char *bytes, int len)
+	{
+	ASN1_OBJECT *obj;
+	X509_NAME_ENTRY *nentry;
+
+	obj=OBJ_nid2obj(nid);
+	if (obj == NULL)
+		{
+		X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_NID,X509_R_UNKNOWN_NID);
+		return(NULL);
+		}
+	nentry = X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len);
+	ASN1_OBJECT_free(obj);
+	return nentry;
+	}
+
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
+	     ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len)
+	{
+	X509_NAME_ENTRY *ret;
+
+	if ((ne == NULL) || (*ne == NULL))
+		{
+		if ((ret=X509_NAME_ENTRY_new()) == NULL)
+			return(NULL);
+		}
+	else
+		ret= *ne;
+
+	if (!X509_NAME_ENTRY_set_object(ret,obj))
+		goto err;
+	if (!X509_NAME_ENTRY_set_data(ret,type,bytes,len))
+		goto err;
+
+	if ((ne != NULL) && (*ne == NULL)) *ne=ret;
+	return(ret);
+err:
+	if ((ne == NULL) || (ret != *ne))
+		X509_NAME_ENTRY_free(ret);
+	return(NULL);
+	}
+
+int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj)
+	{
+	if ((ne == NULL) || (obj == NULL))
+		{
+		X509err(X509_F_X509_NAME_ENTRY_SET_OBJECT,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	ASN1_OBJECT_free(ne->object);
+	ne->object=OBJ_dup(obj);
+	return((ne->object == NULL)?0:1);
+	}
+
+int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
+	     const unsigned char *bytes, int len)
+	{
+	int i;
+
+	if ((ne == NULL) || ((bytes == NULL) && (len != 0))) return(0);
+	if((type > 0) && (type & MBSTRING_FLAG)) 
+		return ASN1_STRING_set_by_NID(&ne->value, bytes,
+						len, type,
+					OBJ_obj2nid(ne->object)) ? 1 : 0;
+	if (len < 0) len=strlen((const char *)bytes);
+	i=ASN1_STRING_set(ne->value,bytes,len);
+	if (!i) return(0);
+	if (type != V_ASN1_UNDEF)
+		{
+		if (type == V_ASN1_APP_CHOOSE)
+			ne->value->type=ASN1_PRINTABLE_type(bytes,len);
+		else
+			ne->value->type=type;
+		}
+	return(1);
+	}
+
+ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne)
+	{
+	if (ne == NULL) return(NULL);
+	return(ne->object);
+	}
+
+ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne)
+	{
+	if (ne == NULL) return(NULL);
+	return(ne->value);
+	}
+
diff --git a/openssl/crypto/x509/x509rset.c b/openssl/crypto/x509/x509rset.c
new file mode 100644
index 0000000..d9f6b57
--- /dev/null
+++ b/openssl/crypto/x509/x509rset.c
@@ -0,0 +1,83 @@
+/* crypto/x509/x509rset.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+int X509_REQ_set_version(X509_REQ *x, long version)
+	{
+	if (x == NULL) return(0);
+	return(ASN1_INTEGER_set(x->req_info->version,version));
+	}
+
+int X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name)
+	{
+	if ((x == NULL) || (x->req_info == NULL)) return(0);
+	return(X509_NAME_set(&x->req_info->subject,name));
+	}
+
+int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey)
+	{
+	if ((x == NULL) || (x->req_info == NULL)) return(0);
+	return(X509_PUBKEY_set(&x->req_info->pubkey,pkey));
+	}
+
diff --git a/openssl/crypto/x509/x509spki.c b/openssl/crypto/x509/x509spki.c
new file mode 100644
index 0000000..02a203d
--- /dev/null
+++ b/openssl/crypto/x509/x509spki.c
@@ -0,0 +1,121 @@
+/* x509spki.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+
+int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey)
+{
+	if ((x == NULL) || (x->spkac == NULL)) return(0);
+	return(X509_PUBKEY_set(&(x->spkac->pubkey),pkey));
+}
+
+EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x)
+{
+	if ((x == NULL) || (x->spkac == NULL))
+		return(NULL);
+	return(X509_PUBKEY_get(x->spkac->pubkey));
+}
+
+/* Load a Netscape SPKI from a base64 encoded string */
+
+NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len)
+{
+	unsigned char *spki_der;
+	const unsigned char *p;
+	int spki_len;
+	NETSCAPE_SPKI *spki;
+	if(len <= 0) len = strlen(str);
+	if (!(spki_der = OPENSSL_malloc(len + 1))) {
+		X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len);
+	if(spki_len < 0) {
+		X509err(X509_F_NETSCAPE_SPKI_B64_DECODE,
+						X509_R_BASE64_DECODE_ERROR);
+		OPENSSL_free(spki_der);
+		return NULL;
+	}
+	p = spki_der;
+	spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len);
+	OPENSSL_free(spki_der);
+	return spki;
+}
+
+/* Generate a base64 encoded string from an SPKI */
+
+char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
+{
+	unsigned char *der_spki, *p;
+	char *b64_str;
+	int der_len;
+	der_len = i2d_NETSCAPE_SPKI(spki, NULL);
+	der_spki = OPENSSL_malloc(der_len);
+	b64_str = OPENSSL_malloc(der_len * 2);
+	if(!der_spki || !b64_str) {
+		X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	p = der_spki;
+	i2d_NETSCAPE_SPKI(spki, &p);
+	EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len);
+	OPENSSL_free(der_spki);
+	return b64_str;
+}
diff --git a/openssl/crypto/x509/x509type.c b/openssl/crypto/x509/x509type.c
new file mode 100644
index 0000000..3385ad3
--- /dev/null
+++ b/openssl/crypto/x509/x509type.c
@@ -0,0 +1,125 @@
+/* crypto/x509/x509type.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int X509_certificate_type(X509 *x, EVP_PKEY *pkey)
+	{
+	EVP_PKEY *pk;
+	int ret=0,i;
+
+	if (x == NULL) return(0);
+
+	if (pkey == NULL)
+		pk=X509_get_pubkey(x);
+	else
+		pk=pkey;
+
+	if (pk == NULL) return(0);
+
+	switch (pk->type)
+		{
+	case EVP_PKEY_RSA:
+		ret=EVP_PK_RSA|EVP_PKT_SIGN;
+/*		if (!sign only extension) */
+			ret|=EVP_PKT_ENC;
+	break;
+	case EVP_PKEY_DSA:
+		ret=EVP_PK_DSA|EVP_PKT_SIGN;
+		break;
+	case EVP_PKEY_EC:
+		ret=EVP_PK_EC|EVP_PKT_SIGN|EVP_PKT_EXCH;
+		break;
+	case EVP_PKEY_DH:
+		ret=EVP_PK_DH|EVP_PKT_EXCH;
+		break;	
+	case NID_id_GostR3410_94:
+	case NID_id_GostR3410_2001:
+		ret=EVP_PKT_EXCH|EVP_PKT_SIGN;
+		break;
+	default:
+		break;
+		}
+
+	i=X509_get_signature_type(x);
+	switch (i)
+		{
+	case EVP_PKEY_RSA:
+		ret|=EVP_PKS_RSA;
+		break;
+	case EVP_PKEY_DSA:
+		ret|=EVP_PKS_DSA;
+		break;
+	case EVP_PKEY_EC:
+		ret|=EVP_PKS_EC;
+		break;
+	default:
+		break;
+		}
+
+	if (EVP_PKEY_size(pk) <= 1024/8)/* /8 because it's 1024 bits we look
+					   for, not bytes */
+		ret|=EVP_PKT_EXP;
+	if(pkey==NULL) EVP_PKEY_free(pk);
+	return(ret);
+	}
+
diff --git a/openssl/crypto/x509/x_all.c b/openssl/crypto/x509/x_all.c
new file mode 100644
index 0000000..8ec88c2
--- /dev/null
+++ b/openssl/crypto/x509/x_all.c
@@ -0,0 +1,516 @@
+/* crypto/x509/x_all.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/stack.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+
+int X509_verify(X509 *a, EVP_PKEY *r)
+	{
+	return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF),a->sig_alg,
+		a->signature,a->cert_info,r));
+	}
+
+int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r)
+	{
+	return( ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO),
+		a->sig_alg,a->signature,a->req_info,r));
+	}
+
+int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r)
+	{
+	return(ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC),
+		a->sig_algor,a->signature,a->spkac,r));
+	}
+
+int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
+	{
+	x->cert_info->enc.modified = 1;
+	return(ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature,
+		x->sig_alg, x->signature, x->cert_info,pkey,md));
+	}
+
+int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md)
+	{
+	return(ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO),x->sig_alg, NULL,
+		x->signature, x->req_info,pkey,md));
+	}
+
+int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md)
+	{
+	x->crl->enc.modified = 1;
+	return(ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO),x->crl->sig_alg,
+		x->sig_alg, x->signature, x->crl,pkey,md));
+	}
+
+int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md)
+	{
+	return(ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor,NULL,
+		x->signature, x->spkac,pkey,md));
+	}
+
+#ifndef OPENSSL_NO_FP_API
+X509 *d2i_X509_fp(FILE *fp, X509 **x509)
+	{
+	return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509);
+	}
+
+int i2d_X509_fp(FILE *fp, X509 *x509)
+	{
+	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509);
+	}
+#endif
+
+X509 *d2i_X509_bio(BIO *bp, X509 **x509)
+	{
+	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509);
+	}
+
+int i2d_X509_bio(BIO *bp, X509 *x509)
+	{
+	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509);
+	}
+
+#ifndef OPENSSL_NO_FP_API
+X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl)
+	{
+	return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
+	}
+
+int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl)
+	{
+	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
+	}
+#endif
+
+X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl)
+	{
+	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
+	}
+
+int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl)
+	{
+	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
+	}
+
+#ifndef OPENSSL_NO_FP_API
+PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7)
+	{
+	return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7);
+	}
+
+int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7)
+	{
+	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS7), fp, p7);
+	}
+#endif
+
+PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7)
+	{
+	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7);
+	}
+
+int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7)
+	{
+	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bp, p7);
+	}
+
+#ifndef OPENSSL_NO_FP_API
+X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req)
+	{
+	return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
+	}
+
+int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req)
+	{
+	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
+	}
+#endif
+
+X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req)
+	{
+	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
+	}
+
+int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req)
+	{
+	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
+	}
+
+#ifndef OPENSSL_NO_RSA
+
+#ifndef OPENSSL_NO_FP_API
+RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa)
+	{
+	return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
+	}
+
+int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa)
+	{
+	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
+	}
+
+RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa)
+	{
+	return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa);
+	}
+
+
+RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa)
+	{
+	return ASN1_d2i_fp((void *(*)(void))
+			   RSA_new,(D2I_OF(void))d2i_RSA_PUBKEY, fp,
+			   (void **)rsa);
+	}
+
+int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa)
+	{
+	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa);
+	}
+
+int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
+	{
+	return ASN1_i2d_fp((I2D_OF(void))i2d_RSA_PUBKEY,fp,rsa);
+	}
+#endif
+
+RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
+	{
+	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
+	}
+
+int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa)
+	{
+	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
+	}
+
+RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa)
+	{
+	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
+	}
+
+
+RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa)
+	{
+	return ASN1_d2i_bio_of(RSA,RSA_new,d2i_RSA_PUBKEY,bp,rsa);
+	}
+
+int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)
+	{
+	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
+	}
+
+int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa)
+	{
+	return ASN1_i2d_bio_of(RSA,i2d_RSA_PUBKEY,bp,rsa);
+	}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+#ifndef OPENSSL_NO_FP_API
+DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa)
+	{
+	return ASN1_d2i_fp_of(DSA,DSA_new,d2i_DSAPrivateKey,fp,dsa);
+	}
+
+int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa)
+	{
+	return ASN1_i2d_fp_of_const(DSA,i2d_DSAPrivateKey,fp,dsa);
+	}
+
+DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa)
+	{
+	return ASN1_d2i_fp_of(DSA,DSA_new,d2i_DSA_PUBKEY,fp,dsa);
+	}
+
+int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa)
+	{
+	return ASN1_i2d_fp_of(DSA,i2d_DSA_PUBKEY,fp,dsa);
+	}
+#endif
+
+DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa)
+	{
+	return ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAPrivateKey,bp,dsa
+);
+	}
+
+int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa)
+	{
+	return ASN1_i2d_bio_of_const(DSA,i2d_DSAPrivateKey,bp,dsa);
+	}
+
+DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa)
+	{
+	return ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSA_PUBKEY,bp,dsa);
+	}
+
+int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa)
+	{
+	return ASN1_i2d_bio_of(DSA,i2d_DSA_PUBKEY,bp,dsa);
+	}
+
+#endif
+
+#ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_FP_API
+EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey)
+	{
+	return ASN1_d2i_fp_of(EC_KEY,EC_KEY_new,d2i_EC_PUBKEY,fp,eckey);
+	}
+  
+int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey)
+	{
+	return ASN1_i2d_fp_of(EC_KEY,i2d_EC_PUBKEY,fp,eckey);
+	}
+
+EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey)
+	{
+	return ASN1_d2i_fp_of(EC_KEY,EC_KEY_new,d2i_ECPrivateKey,fp,eckey);
+	}
+  
+int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey)
+	{
+	return ASN1_i2d_fp_of(EC_KEY,i2d_ECPrivateKey,fp,eckey);
+	}
+#endif
+EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey)
+	{
+	return ASN1_d2i_bio_of(EC_KEY,EC_KEY_new,d2i_EC_PUBKEY,bp,eckey);
+	}
+  
+int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa)
+	{
+	return ASN1_i2d_bio_of(EC_KEY,i2d_EC_PUBKEY,bp,ecdsa);
+	}
+
+EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey)
+	{
+	return ASN1_d2i_bio_of(EC_KEY,EC_KEY_new,d2i_ECPrivateKey,bp,eckey);
+	}
+  
+int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey)
+	{
+	return ASN1_i2d_bio_of(EC_KEY,i2d_ECPrivateKey,bp,eckey);
+	}
+#endif
+
+
+int X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
+	     unsigned int *len)
+	{
+	ASN1_BIT_STRING *key;
+	key = X509_get0_pubkey_bitstr(data);
+	if(!key) return 0;
+	return EVP_Digest(key->data, key->length, md, len, type, NULL);
+	}
+
+int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
+	     unsigned int *len)
+	{
+	return(ASN1_item_digest(ASN1_ITEM_rptr(X509),type,(char *)data,md,len));
+	}
+
+int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, unsigned char *md,
+	     unsigned int *len)
+	{
+	return(ASN1_item_digest(ASN1_ITEM_rptr(X509_CRL),type,(char *)data,md,len));
+	}
+
+int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, unsigned char *md,
+	     unsigned int *len)
+	{
+	return(ASN1_item_digest(ASN1_ITEM_rptr(X509_REQ),type,(char *)data,md,len));
+	}
+
+int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, unsigned char *md,
+	     unsigned int *len)
+	{
+	return(ASN1_item_digest(ASN1_ITEM_rptr(X509_NAME),type,(char *)data,md,len));
+	}
+
+int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, const EVP_MD *type,
+	     unsigned char *md, unsigned int *len)
+	{
+	return(ASN1_item_digest(ASN1_ITEM_rptr(PKCS7_ISSUER_AND_SERIAL),type,
+		(char *)data,md,len));
+	}
+
+
+#ifndef OPENSSL_NO_FP_API
+X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8)
+	{
+	return ASN1_d2i_fp_of(X509_SIG,X509_SIG_new,d2i_X509_SIG,fp,p8);
+	}
+
+int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8)
+	{
+	return ASN1_i2d_fp_of(X509_SIG,i2d_X509_SIG,fp,p8);
+	}
+#endif
+
+X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8)
+	{
+	return ASN1_d2i_bio_of(X509_SIG,X509_SIG_new,d2i_X509_SIG,bp,p8);
+	}
+
+int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8)
+	{
+	return ASN1_i2d_bio_of(X509_SIG,i2d_X509_SIG,bp,p8);
+	}
+
+#ifndef OPENSSL_NO_FP_API
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
+						 PKCS8_PRIV_KEY_INFO **p8inf)
+	{
+	return ASN1_d2i_fp_of(PKCS8_PRIV_KEY_INFO,PKCS8_PRIV_KEY_INFO_new,
+			      d2i_PKCS8_PRIV_KEY_INFO,fp,p8inf);
+	}
+
+int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf)
+	{
+	return ASN1_i2d_fp_of(PKCS8_PRIV_KEY_INFO,i2d_PKCS8_PRIV_KEY_INFO,fp,
+			      p8inf);
+	}
+
+int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key)
+	{
+	PKCS8_PRIV_KEY_INFO *p8inf;
+	int ret;
+	p8inf = EVP_PKEY2PKCS8(key);
+	if(!p8inf) return 0;
+	ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf);
+	PKCS8_PRIV_KEY_INFO_free(p8inf);
+	return ret;
+	}
+
+int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey)
+	{
+	return ASN1_i2d_fp_of(EVP_PKEY,i2d_PrivateKey,fp,pkey);
+	}
+
+EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a)
+{
+	return ASN1_d2i_fp_of(EVP_PKEY,EVP_PKEY_new,d2i_AutoPrivateKey,fp,a);
+}
+
+int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey)
+	{
+	return ASN1_i2d_fp_of(EVP_PKEY,i2d_PUBKEY,fp,pkey);
+	}
+
+EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a)
+{
+	return ASN1_d2i_fp_of(EVP_PKEY,EVP_PKEY_new,d2i_PUBKEY,fp,a);
+}
+
+#endif
+
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
+						 PKCS8_PRIV_KEY_INFO **p8inf)
+	{
+	return ASN1_d2i_bio_of(PKCS8_PRIV_KEY_INFO,PKCS8_PRIV_KEY_INFO_new,
+			    d2i_PKCS8_PRIV_KEY_INFO,bp,p8inf);
+	}
+
+int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf)
+	{
+	return ASN1_i2d_bio_of(PKCS8_PRIV_KEY_INFO,i2d_PKCS8_PRIV_KEY_INFO,bp,
+			       p8inf);
+	}
+
+int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key)
+	{
+	PKCS8_PRIV_KEY_INFO *p8inf;
+	int ret;
+	p8inf = EVP_PKEY2PKCS8(key);
+	if(!p8inf) return 0;
+	ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
+	PKCS8_PRIV_KEY_INFO_free(p8inf);
+	return ret;
+	}
+
+int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey)
+	{
+	return ASN1_i2d_bio_of(EVP_PKEY,i2d_PrivateKey,bp,pkey);
+	}
+
+EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a)
+	{
+	return ASN1_d2i_bio_of(EVP_PKEY,EVP_PKEY_new,d2i_AutoPrivateKey,bp,a);
+	}
+
+int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey)
+	{
+	return ASN1_i2d_bio_of(EVP_PKEY,i2d_PUBKEY,bp,pkey);
+	}
+
+EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a)
+	{
+	return ASN1_d2i_bio_of(EVP_PKEY,EVP_PKEY_new,d2i_PUBKEY,bp,a);
+	}
diff --git a/openssl/crypto/x509v3/Makefile b/openssl/crypto/x509v3/Makefile
new file mode 100644
index 0000000..556ef35
--- /dev/null
+++ b/openssl/crypto/x509v3/Makefile
@@ -0,0 +1,591 @@
+#
+# OpenSSL/crypto/x509v3/Makefile
+#
+
+DIR=	x509v3
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile README
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=	v3_bcons.c v3_bitst.c v3_conf.c v3_extku.c v3_ia5.c v3_lib.c \
+v3_prn.c v3_utl.c v3err.c v3_genn.c v3_alt.c v3_skey.c v3_akey.c v3_pku.c \
+v3_int.c v3_enum.c v3_sxnet.c v3_cpols.c v3_crld.c v3_purp.c v3_info.c \
+v3_ocsp.c v3_akeya.c v3_pmaps.c v3_pcons.c v3_ncons.c v3_pcia.c v3_pci.c \
+pcy_cache.c pcy_node.c pcy_data.c pcy_map.c pcy_tree.c pcy_lib.c \
+v3_asid.c v3_addr.c
+LIBOBJ= v3_bcons.o v3_bitst.o v3_conf.o v3_extku.o v3_ia5.o v3_lib.o \
+v3_prn.o v3_utl.o v3err.o v3_genn.o v3_alt.o v3_skey.o v3_akey.o v3_pku.o \
+v3_int.o v3_enum.o v3_sxnet.o v3_cpols.o v3_crld.o v3_purp.o v3_info.o \
+v3_ocsp.o v3_akeya.o v3_pmaps.o v3_pcons.o v3_ncons.o v3_pcia.o v3_pci.o \
+pcy_cache.o pcy_node.o pcy_data.o pcy_map.o pcy_tree.o pcy_lib.o \
+v3_asid.o v3_addr.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= x509v3.h
+HEADER=	$(EXHEADER) pcy_int.h
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+pcy_cache.o: ../../e_os.h ../../include/openssl/asn1.h
+pcy_cache.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pcy_cache.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+pcy_cache.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+pcy_cache.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+pcy_cache.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+pcy_cache.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pcy_cache.o: ../../include/openssl/objects.h
+pcy_cache.o: ../../include/openssl/opensslconf.h
+pcy_cache.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pcy_cache.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+pcy_cache.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pcy_cache.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pcy_cache.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+pcy_cache.o: ../cryptlib.h pcy_cache.c pcy_int.h
+pcy_data.o: ../../e_os.h ../../include/openssl/asn1.h
+pcy_data.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pcy_data.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+pcy_data.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+pcy_data.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+pcy_data.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+pcy_data.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pcy_data.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pcy_data.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pcy_data.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+pcy_data.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pcy_data.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pcy_data.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+pcy_data.o: ../cryptlib.h pcy_data.c pcy_int.h
+pcy_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+pcy_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pcy_lib.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+pcy_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+pcy_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+pcy_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+pcy_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pcy_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pcy_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pcy_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+pcy_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pcy_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pcy_lib.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+pcy_lib.o: ../cryptlib.h pcy_int.h pcy_lib.c
+pcy_map.o: ../../e_os.h ../../include/openssl/asn1.h
+pcy_map.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pcy_map.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+pcy_map.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+pcy_map.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+pcy_map.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+pcy_map.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pcy_map.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pcy_map.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pcy_map.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+pcy_map.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pcy_map.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pcy_map.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+pcy_map.o: ../cryptlib.h pcy_int.h pcy_map.c
+pcy_node.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+pcy_node.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+pcy_node.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+pcy_node.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+pcy_node.o: ../../include/openssl/ecdsa.h ../../include/openssl/evp.h
+pcy_node.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pcy_node.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pcy_node.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pcy_node.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+pcy_node.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pcy_node.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pcy_node.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+pcy_node.o: pcy_int.h pcy_node.c
+pcy_tree.o: ../../e_os.h ../../include/openssl/asn1.h
+pcy_tree.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+pcy_tree.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+pcy_tree.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+pcy_tree.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+pcy_tree.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+pcy_tree.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pcy_tree.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pcy_tree.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pcy_tree.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+pcy_tree.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pcy_tree.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pcy_tree.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+pcy_tree.o: ../cryptlib.h pcy_int.h pcy_tree.c
+v3_addr.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_addr.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+v3_addr.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_addr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_addr.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_addr.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_addr.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_addr.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_addr.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_addr.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_addr.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_addr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_addr.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_addr.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_addr.c
+v3_akey.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_akey.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+v3_akey.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_akey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_akey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_akey.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_akey.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_akey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_akey.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_akey.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_akey.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_akey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_akey.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_akey.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_akey.c
+v3_akeya.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_akeya.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+v3_akeya.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_akeya.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_akeya.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_akeya.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_akeya.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_akeya.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_akeya.o: ../../include/openssl/opensslconf.h
+v3_akeya.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_akeya.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_akeya.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_akeya.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_akeya.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_akeya.o: ../cryptlib.h v3_akeya.c
+v3_alt.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+v3_alt.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_alt.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_alt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_alt.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_alt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_alt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_alt.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_alt.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_alt.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_alt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_alt.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_alt.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_alt.c
+v3_asid.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_asid.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+v3_asid.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+v3_asid.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+v3_asid.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+v3_asid.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+v3_asid.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+v3_asid.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_asid.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_asid.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_asid.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_asid.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_asid.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_asid.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_asid.o: ../cryptlib.h v3_asid.c
+v3_bcons.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_bcons.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+v3_bcons.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_bcons.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_bcons.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_bcons.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_bcons.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_bcons.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_bcons.o: ../../include/openssl/opensslconf.h
+v3_bcons.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_bcons.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_bcons.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_bcons.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_bcons.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_bcons.o: ../cryptlib.h v3_bcons.c
+v3_bitst.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_bitst.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+v3_bitst.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+v3_bitst.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+v3_bitst.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+v3_bitst.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+v3_bitst.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_bitst.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_bitst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_bitst.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_bitst.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_bitst.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_bitst.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_bitst.o: ../cryptlib.h v3_bitst.c
+v3_conf.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_conf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+v3_conf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+v3_conf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+v3_conf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+v3_conf.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+v3_conf.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_conf.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_conf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_conf.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_conf.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_conf.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_conf.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_conf.o: ../cryptlib.h v3_conf.c
+v3_cpols.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_cpols.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+v3_cpols.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_cpols.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_cpols.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_cpols.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_cpols.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_cpols.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_cpols.o: ../../include/openssl/opensslconf.h
+v3_cpols.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_cpols.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_cpols.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_cpols.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_cpols.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_cpols.o: ../cryptlib.h pcy_int.h v3_cpols.c
+v3_crld.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_crld.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+v3_crld.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_crld.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_crld.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_crld.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_crld.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_crld.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_crld.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_crld.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_crld.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_crld.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_crld.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_crld.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_crld.c
+v3_enum.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_enum.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+v3_enum.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+v3_enum.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+v3_enum.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+v3_enum.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+v3_enum.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_enum.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_enum.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_enum.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_enum.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_enum.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_enum.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_enum.o: ../cryptlib.h v3_enum.c
+v3_extku.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_extku.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+v3_extku.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_extku.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_extku.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_extku.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_extku.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_extku.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_extku.o: ../../include/openssl/opensslconf.h
+v3_extku.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_extku.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_extku.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_extku.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_extku.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_extku.o: ../cryptlib.h v3_extku.c
+v3_genn.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_genn.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+v3_genn.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_genn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_genn.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_genn.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_genn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_genn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_genn.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_genn.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_genn.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_genn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_genn.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_genn.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_genn.c
+v3_ia5.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+v3_ia5.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_ia5.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_ia5.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_ia5.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_ia5.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_ia5.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_ia5.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_ia5.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_ia5.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_ia5.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_ia5.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_ia5.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_ia5.c
+v3_info.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_info.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+v3_info.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_info.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_info.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_info.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_info.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_info.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_info.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_info.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_info.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_info.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_info.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_info.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_info.c
+v3_int.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+v3_int.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_int.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_int.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_int.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_int.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_int.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_int.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_int.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_int.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_int.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_int.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_int.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_int.c
+v3_lib.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+v3_lib.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_lib.o: ../../include/openssl/x509v3.h ../cryptlib.h ext_dat.h v3_lib.c
+v3_ncons.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_ncons.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+v3_ncons.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_ncons.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_ncons.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_ncons.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_ncons.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_ncons.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_ncons.o: ../../include/openssl/opensslconf.h
+v3_ncons.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_ncons.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_ncons.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_ncons.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_ncons.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_ncons.o: ../cryptlib.h v3_ncons.c
+v3_ocsp.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_ocsp.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+v3_ocsp.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+v3_ocsp.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+v3_ocsp.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+v3_ocsp.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+v3_ocsp.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_ocsp.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
+v3_ocsp.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_ocsp.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_ocsp.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_ocsp.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_ocsp.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_ocsp.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_ocsp.c
+v3_pci.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+v3_pci.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_pci.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_pci.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_pci.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_pci.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_pci.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_pci.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_pci.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_pci.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_pci.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_pci.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_pci.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_pci.c
+v3_pcia.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+v3_pcia.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+v3_pcia.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+v3_pcia.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+v3_pcia.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+v3_pcia.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_pcia.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_pcia.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_pcia.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_pcia.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_pcia.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_pcia.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_pcia.o: ../../include/openssl/x509v3.h v3_pcia.c
+v3_pcons.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_pcons.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+v3_pcons.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_pcons.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_pcons.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_pcons.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_pcons.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_pcons.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_pcons.o: ../../include/openssl/opensslconf.h
+v3_pcons.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_pcons.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_pcons.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_pcons.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_pcons.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_pcons.o: ../cryptlib.h v3_pcons.c
+v3_pku.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_pku.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+v3_pku.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_pku.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_pku.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_pku.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_pku.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_pku.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_pku.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_pku.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_pku.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_pku.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_pku.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_pku.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_pku.c
+v3_pmaps.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_pmaps.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+v3_pmaps.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_pmaps.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_pmaps.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_pmaps.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_pmaps.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_pmaps.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_pmaps.o: ../../include/openssl/opensslconf.h
+v3_pmaps.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_pmaps.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_pmaps.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_pmaps.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_pmaps.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_pmaps.o: ../cryptlib.h v3_pmaps.c
+v3_prn.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+v3_prn.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_prn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_prn.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_prn.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_prn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_prn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_prn.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_prn.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_prn.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_prn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_prn.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_prn.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_prn.c
+v3_purp.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_purp.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+v3_purp.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+v3_purp.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+v3_purp.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+v3_purp.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+v3_purp.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_purp.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_purp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_purp.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_purp.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_purp.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_purp.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_purp.o: ../cryptlib.h v3_purp.c
+v3_skey.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_skey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+v3_skey.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+v3_skey.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+v3_skey.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+v3_skey.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+v3_skey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_skey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_skey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_skey.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_skey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_skey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_skey.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_skey.o: ../cryptlib.h v3_skey.c
+v3_sxnet.o: ../../e_os.h ../../include/openssl/asn1.h
+v3_sxnet.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+v3_sxnet.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3_sxnet.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3_sxnet.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3_sxnet.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3_sxnet.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3_sxnet.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_sxnet.o: ../../include/openssl/opensslconf.h
+v3_sxnet.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_sxnet.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_sxnet.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_sxnet.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_sxnet.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_sxnet.o: ../cryptlib.h v3_sxnet.c
+v3_utl.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+v3_utl.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+v3_utl.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+v3_utl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+v3_utl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+v3_utl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+v3_utl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_utl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_utl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_utl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_utl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_utl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_utl.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_utl.o: ../cryptlib.h v3_utl.c
+v3err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+v3err.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+v3err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+v3err.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+v3err.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+v3err.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+v3err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3err.o: ../../include/openssl/x509v3.h v3err.c
diff --git a/openssl/crypto/x509v3/ext_dat.h b/openssl/crypto/x509v3/ext_dat.h
new file mode 100644
index 0000000..76daee6
--- /dev/null
+++ b/openssl/crypto/x509v3/ext_dat.h
@@ -0,0 +1,132 @@
+/* ext_dat.h */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* This file contains a table of "standard" extensions */
+
+extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku;
+extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo;
+extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id;
+extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate;
+extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl;
+extern X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff;
+extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc;
+extern X509V3_EXT_METHOD v3_crl_hold, v3_pci;
+extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints;
+extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp;
+extern X509V3_EXT_METHOD v3_addr, v3_asid;
+
+/* This table will be searched using OBJ_bsearch so it *must* kept in
+ * order of the ext_nid values.
+ */
+
+static const X509V3_EXT_METHOD *standard_exts[] = {
+&v3_nscert,
+&v3_ns_ia5_list[0],
+&v3_ns_ia5_list[1],
+&v3_ns_ia5_list[2],
+&v3_ns_ia5_list[3],
+&v3_ns_ia5_list[4],
+&v3_ns_ia5_list[5],
+&v3_ns_ia5_list[6],
+&v3_skey_id,
+&v3_key_usage,
+&v3_pkey_usage_period,
+&v3_alt[0],
+&v3_alt[1],
+&v3_bcons,
+&v3_crl_num,
+&v3_cpols,
+&v3_akey_id,
+&v3_crld,
+&v3_ext_ku,
+&v3_delta_crl,
+&v3_crl_reason,
+#ifndef OPENSSL_NO_OCSP
+&v3_crl_invdate,
+#endif
+&v3_sxnet,
+&v3_info,
+#ifndef OPENSSL_NO_RFC3779
+&v3_addr,
+&v3_asid,
+#endif
+#ifndef OPENSSL_NO_OCSP
+&v3_ocsp_nonce,
+&v3_ocsp_crlid,
+&v3_ocsp_accresp,
+&v3_ocsp_nocheck,
+&v3_ocsp_acutoff,
+&v3_ocsp_serviceloc,
+#endif
+&v3_sinfo,
+&v3_policy_constraints,
+#ifndef OPENSSL_NO_OCSP
+&v3_crl_hold,
+#endif
+&v3_pci,
+&v3_name_constraints,
+&v3_policy_mappings,
+&v3_inhibit_anyp,
+&v3_idp,
+&v3_alt[2],
+&v3_freshest_crl,
+};
+
+/* Number of standard extensions */
+
+#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *))
+
diff --git a/openssl/crypto/x509v3/pcy_cache.c b/openssl/crypto/x509v3/pcy_cache.c
new file mode 100644
index 0000000..172b7e7
--- /dev/null
+++ b/openssl/crypto/x509v3/pcy_cache.c
@@ -0,0 +1,286 @@
+/* pcy_cache.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+
+static int policy_data_cmp(const X509_POLICY_DATA * const *a,
+				const X509_POLICY_DATA * const *b);
+static int policy_cache_set_int(long *out, ASN1_INTEGER *value);
+
+/* Set cache entry according to CertificatePolicies extension.
+ * Note: this destroys the passed CERTIFICATEPOLICIES structure.
+ */
+
+static int policy_cache_create(X509 *x,
+			CERTIFICATEPOLICIES *policies, int crit)
+	{
+	int i;
+	int ret = 0;
+	X509_POLICY_CACHE *cache = x->policy_cache;
+	X509_POLICY_DATA *data = NULL;
+	POLICYINFO *policy;
+	if (sk_POLICYINFO_num(policies) == 0)
+		goto bad_policy;
+	cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp);
+	if (!cache->data)
+		goto bad_policy;
+	for (i = 0; i < sk_POLICYINFO_num(policies); i++)
+		{
+		policy = sk_POLICYINFO_value(policies, i);
+		data = policy_data_new(policy, NULL, crit);
+		if (!data)
+			goto bad_policy;
+		/* Duplicate policy OIDs are illegal: reject if matches
+		 * found.
+		 */
+		if (OBJ_obj2nid(data->valid_policy) == NID_any_policy)
+			{
+			if (cache->anyPolicy)
+				{
+				ret = -1;
+				goto bad_policy;
+				}
+			cache->anyPolicy = data;
+			}
+		else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1)
+			{
+			ret = -1;
+			goto bad_policy;
+			}
+		else if (!sk_X509_POLICY_DATA_push(cache->data, data))
+			goto bad_policy;
+		data = NULL;
+		}
+	ret = 1;
+	bad_policy:
+	if (ret == -1)
+		x->ex_flags |= EXFLAG_INVALID_POLICY;
+	if (data)
+		policy_data_free(data);
+	sk_POLICYINFO_pop_free(policies, POLICYINFO_free);
+	if (ret <= 0)
+		{
+		sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
+		cache->data = NULL;
+		}
+	return ret;
+	}
+
+	
+static int policy_cache_new(X509 *x)
+	{
+	X509_POLICY_CACHE *cache;
+	ASN1_INTEGER *ext_any = NULL;
+	POLICY_CONSTRAINTS *ext_pcons = NULL;
+	CERTIFICATEPOLICIES *ext_cpols = NULL;
+	POLICY_MAPPINGS *ext_pmaps = NULL;
+	int i;
+	cache = OPENSSL_malloc(sizeof(X509_POLICY_CACHE));
+	if (!cache)
+		return 0;
+	cache->anyPolicy = NULL;
+	cache->data = NULL;
+	cache->any_skip = -1;
+	cache->explicit_skip = -1;
+	cache->map_skip = -1;
+
+	x->policy_cache = cache;
+
+	/* Handle requireExplicitPolicy *first*. Need to process this
+	 * even if we don't have any policies.
+	 */
+	ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL);
+
+	if (!ext_pcons)
+		{
+		if (i != -1)
+			goto bad_cache;
+		}
+	else
+		{
+		if (!ext_pcons->requireExplicitPolicy
+			&& !ext_pcons->inhibitPolicyMapping)
+			goto bad_cache;
+		if (!policy_cache_set_int(&cache->explicit_skip,
+			ext_pcons->requireExplicitPolicy))
+			goto bad_cache;
+		if (!policy_cache_set_int(&cache->map_skip,
+			ext_pcons->inhibitPolicyMapping))
+			goto bad_cache;
+		}
+
+	/* Process CertificatePolicies */
+
+	ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL);
+	/* If no CertificatePolicies extension or problem decoding then
+	 * there is no point continuing because the valid policies will be
+	 * NULL.
+	 */
+	if (!ext_cpols)
+		{
+		/* If not absent some problem with extension */
+		if (i != -1)
+			goto bad_cache;
+		return 1;
+		}
+
+	i = policy_cache_create(x, ext_cpols, i);
+
+	/* NB: ext_cpols freed by policy_cache_set_policies */
+
+	if (i <= 0)
+		return i;
+
+	ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL);
+
+	if (!ext_pmaps)
+		{
+		/* If not absent some problem with extension */
+		if (i != -1)
+			goto bad_cache;
+		}
+	else
+		{
+		i = policy_cache_set_mapping(x, ext_pmaps);
+		if (i <= 0)
+			goto bad_cache;
+		}
+
+	ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL);
+
+	if (!ext_any)
+		{
+		if (i != -1)
+			goto bad_cache;
+		}
+	else if (!policy_cache_set_int(&cache->any_skip, ext_any))
+			goto bad_cache;
+
+	if (0)
+		{
+		bad_cache:
+		x->ex_flags |= EXFLAG_INVALID_POLICY;
+		}
+
+	if(ext_pcons)
+		POLICY_CONSTRAINTS_free(ext_pcons);
+
+	if (ext_any)
+		ASN1_INTEGER_free(ext_any);
+
+	return 1;
+
+	
+}
+
+void policy_cache_free(X509_POLICY_CACHE *cache)
+	{
+	if (!cache)
+		return;
+	if (cache->anyPolicy)
+		policy_data_free(cache->anyPolicy);
+	if (cache->data)
+		sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
+	OPENSSL_free(cache);
+	}
+
+const X509_POLICY_CACHE *policy_cache_set(X509 *x)
+	{
+
+	if (x->policy_cache == NULL)
+		{
+		CRYPTO_w_lock(CRYPTO_LOCK_X509);
+			policy_cache_new(x);
+		CRYPTO_w_unlock(CRYPTO_LOCK_X509);
+		}
+
+	return x->policy_cache;
+
+	}
+
+X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
+						const ASN1_OBJECT *id)
+	{
+	int idx;
+	X509_POLICY_DATA tmp;
+	tmp.valid_policy = (ASN1_OBJECT *)id;
+	idx = sk_X509_POLICY_DATA_find(cache->data, &tmp);
+	if (idx == -1)
+		return NULL;
+	return sk_X509_POLICY_DATA_value(cache->data, idx);
+	}
+
+static int policy_data_cmp(const X509_POLICY_DATA * const *a,
+				const X509_POLICY_DATA * const *b)
+	{
+	return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy);
+	}
+
+static int policy_cache_set_int(long *out, ASN1_INTEGER *value)
+	{
+	if (value == NULL)
+		return 1;
+	if (value->type == V_ASN1_NEG_INTEGER)
+		return 0;
+	*out = ASN1_INTEGER_get(value);
+	return 1;
+	}
diff --git a/openssl/crypto/x509v3/pcy_data.c b/openssl/crypto/x509v3/pcy_data.c
new file mode 100644
index 0000000..3444b03
--- /dev/null
+++ b/openssl/crypto/x509v3/pcy_data.c
@@ -0,0 +1,135 @@
+/* pcy_data.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+
+/* Policy Node routines */
+
+void policy_data_free(X509_POLICY_DATA *data)
+	{
+	ASN1_OBJECT_free(data->valid_policy);
+	/* Don't free qualifiers if shared */
+	if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS))
+		sk_POLICYQUALINFO_pop_free(data->qualifier_set,
+					POLICYQUALINFO_free);
+	sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free);
+	OPENSSL_free(data);
+	}
+
+/* Create a data based on an existing policy. If 'id' is NULL use the
+ * oid in the policy, otherwise use 'id'. This behaviour covers the two
+ * types of data in RFC3280: data with from a CertificatePolcies extension
+ * and additional data with just the qualifiers of anyPolicy and ID from
+ * another source.
+ */
+
+X509_POLICY_DATA *policy_data_new(POLICYINFO *policy,
+					const ASN1_OBJECT *cid, int crit)
+	{
+	X509_POLICY_DATA *ret;
+	ASN1_OBJECT *id;
+	if (!policy && !cid)
+		return NULL;
+	if (cid)
+		{
+		id = OBJ_dup(cid);
+		if (!id)
+			return NULL;
+		}
+	else
+		id = NULL;
+	ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA));
+	if (!ret)
+		return NULL;
+	ret->expected_policy_set = sk_ASN1_OBJECT_new_null();
+	if (!ret->expected_policy_set)
+		{
+		OPENSSL_free(ret);
+		if (id)
+			ASN1_OBJECT_free(id);
+		return NULL;
+		}
+
+	if (crit)
+		ret->flags = POLICY_DATA_FLAG_CRITICAL;
+	else
+		ret->flags = 0;
+
+	if (id)
+		ret->valid_policy = id;
+	else
+		{
+		ret->valid_policy = policy->policyid;
+		policy->policyid = NULL;
+		}
+
+	if (policy)
+		{
+		ret->qualifier_set = policy->qualifiers;
+		policy->qualifiers = NULL;
+		}
+	else
+		ret->qualifier_set = NULL;
+
+	return ret;
+	}
+
diff --git a/openssl/crypto/x509v3/pcy_int.h b/openssl/crypto/x509v3/pcy_int.h
new file mode 100644
index 0000000..ccff928
--- /dev/null
+++ b/openssl/crypto/x509v3/pcy_int.h
@@ -0,0 +1,212 @@
+/* pcy_int.h */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+typedef struct X509_POLICY_DATA_st X509_POLICY_DATA;
+
+DECLARE_STACK_OF(X509_POLICY_DATA)
+
+/* Internal structures */
+
+/* This structure and the field names correspond to the Policy 'node' of
+ * RFC3280. NB this structure contains no pointers to parent or child
+ * data: X509_POLICY_NODE contains that. This means that the main policy data
+ * can be kept static and cached with the certificate.
+ */
+
+struct X509_POLICY_DATA_st
+	{
+	unsigned int flags;
+	/* Policy OID and qualifiers for this data */
+	ASN1_OBJECT *valid_policy;
+	STACK_OF(POLICYQUALINFO) *qualifier_set;
+	STACK_OF(ASN1_OBJECT) *expected_policy_set;
+	};
+
+/* X509_POLICY_DATA flags values */
+
+/* This flag indicates the structure has been mapped using a policy mapping
+ * extension. If policy mapping is not active its references get deleted. 
+ */
+
+#define POLICY_DATA_FLAG_MAPPED			0x1
+
+/* This flag indicates the data doesn't correspond to a policy in Certificate
+ * Policies: it has been mapped to any policy.
+ */
+
+#define POLICY_DATA_FLAG_MAPPED_ANY		0x2
+
+/* AND with flags to see if any mapping has occurred */
+
+#define POLICY_DATA_FLAG_MAP_MASK		0x3
+
+/* qualifiers are shared and shouldn't be freed */
+
+#define POLICY_DATA_FLAG_SHARED_QUALIFIERS	0x4
+
+/* Parent node is an extra node and should be freed */
+
+#define POLICY_DATA_FLAG_EXTRA_NODE		0x8
+
+/* Corresponding CertificatePolicies is critical */
+
+#define POLICY_DATA_FLAG_CRITICAL		0x10
+
+/* This structure is cached with a certificate */
+
+struct X509_POLICY_CACHE_st {
+	/* anyPolicy data or NULL if no anyPolicy */
+	X509_POLICY_DATA *anyPolicy;
+	/* other policy data */
+	STACK_OF(X509_POLICY_DATA) *data;
+	/* If InhibitAnyPolicy present this is its value or -1 if absent. */
+	long any_skip;
+	/* If policyConstraints and requireExplicitPolicy present this is its
+	 * value or -1 if absent.
+	 */
+	long explicit_skip;
+	/* If policyConstraints and policyMapping present this is its
+	 * value or -1 if absent.
+         */
+	long map_skip;
+	};
+
+/*#define POLICY_CACHE_FLAG_CRITICAL		POLICY_DATA_FLAG_CRITICAL*/
+
+/* This structure represents the relationship between nodes */
+
+struct X509_POLICY_NODE_st
+	{
+	/* node data this refers to */
+	const X509_POLICY_DATA *data;
+	/* Parent node */
+	X509_POLICY_NODE *parent;
+	/* Number of child nodes */
+	int nchild;
+	};
+
+struct X509_POLICY_LEVEL_st
+	{
+	/* Cert for this level */
+	X509 *cert;
+	/* nodes at this level */
+	STACK_OF(X509_POLICY_NODE) *nodes;
+	/* anyPolicy node */
+	X509_POLICY_NODE *anyPolicy;
+	/* Extra data */
+	/*STACK_OF(X509_POLICY_DATA) *extra_data;*/
+	unsigned int flags;
+	};
+
+struct X509_POLICY_TREE_st
+	{
+	/* This is the tree 'level' data */
+	X509_POLICY_LEVEL *levels;
+	int nlevel;
+	/* Extra policy data when additional nodes (not from the certificate)
+	 * are required.
+	 */
+	STACK_OF(X509_POLICY_DATA) *extra_data;
+	/* This is the authority constained policy set */
+	STACK_OF(X509_POLICY_NODE) *auth_policies;
+	STACK_OF(X509_POLICY_NODE) *user_policies;
+	unsigned int flags;
+	};
+
+/* Set if anyPolicy present in user policies */
+#define POLICY_FLAG_ANY_POLICY		0x2
+
+/* Useful macros */
+
+#define node_data_critical(data) (data->flags & POLICY_DATA_FLAG_CRITICAL)
+#define node_critical(node) node_data_critical(node->data)
+
+/* Internal functions */
+
+X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id,
+								int crit);
+void policy_data_free(X509_POLICY_DATA *data);
+
+X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
+							const ASN1_OBJECT *id);
+int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps);
+
+
+STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void);
+
+void policy_cache_init(void);
+
+void policy_cache_free(X509_POLICY_CACHE *cache);
+
+X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
+					const X509_POLICY_NODE *parent,	
+					const ASN1_OBJECT *id);
+
+X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
+						const ASN1_OBJECT *id);
+
+X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
+			const X509_POLICY_DATA *data,
+			X509_POLICY_NODE *parent,
+			X509_POLICY_TREE *tree);
+void policy_node_free(X509_POLICY_NODE *node);
+int policy_node_match(const X509_POLICY_LEVEL *lvl,
+		      const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
+
+const X509_POLICY_CACHE *policy_cache_set(X509 *x);
diff --git a/openssl/crypto/x509v3/pcy_lib.c b/openssl/crypto/x509v3/pcy_lib.c
new file mode 100644
index 0000000..93bfd92
--- /dev/null
+++ b/openssl/crypto/x509v3/pcy_lib.c
@@ -0,0 +1,167 @@
+/* pcy_lib.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+
+/* accessor functions */
+
+/* X509_POLICY_TREE stuff */
+
+int X509_policy_tree_level_count(const X509_POLICY_TREE *tree)
+	{
+	if (!tree)
+		return 0;
+	return tree->nlevel;
+	}
+
+X509_POLICY_LEVEL *
+	X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i)
+	{
+	if (!tree || (i < 0) || (i >= tree->nlevel))
+		return NULL;
+	return tree->levels + i;
+	}
+
+STACK_OF(X509_POLICY_NODE) *
+		X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree)
+	{
+	if (!tree)
+		return NULL;
+	return tree->auth_policies;
+	}
+
+STACK_OF(X509_POLICY_NODE) *
+	X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree)
+	{
+	if (!tree)
+		return NULL;
+	if (tree->flags & POLICY_FLAG_ANY_POLICY)
+		return tree->auth_policies;
+	else
+		return tree->user_policies;
+	}
+
+/* X509_POLICY_LEVEL stuff */
+
+int X509_policy_level_node_count(X509_POLICY_LEVEL *level)
+	{
+	int n;
+	if (!level)
+		return 0;
+	if (level->anyPolicy)
+		n = 1;
+	else
+		n = 0;
+	if (level->nodes)
+		n += sk_X509_POLICY_NODE_num(level->nodes);
+	return n;
+	}
+
+X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i)
+	{
+	if (!level)
+		return NULL;
+	if (level->anyPolicy)
+		{
+		if (i == 0)
+			return level->anyPolicy;
+		i--;
+		}
+	return sk_X509_POLICY_NODE_value(level->nodes, i);
+	}
+
+/* X509_POLICY_NODE stuff */
+
+const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node)
+	{
+	if (!node)
+		return NULL;
+	return node->data->valid_policy;
+	}
+
+#if 0
+int X509_policy_node_get_critical(const X509_POLICY_NODE *node)
+	{
+	if (node_critical(node))
+		return 1;
+	return 0;
+	}
+#endif
+
+STACK_OF(POLICYQUALINFO) *
+		X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node)
+	{
+	if (!node)
+		return NULL;
+	return node->data->qualifier_set;
+	}
+
+const X509_POLICY_NODE *
+		X509_policy_node_get0_parent(const X509_POLICY_NODE *node)
+	{
+	if (!node)
+		return NULL;
+	return node->parent;
+	}
+
+
diff --git a/openssl/crypto/x509v3/pcy_map.c b/openssl/crypto/x509v3/pcy_map.c
new file mode 100644
index 0000000..21163b5
--- /dev/null
+++ b/openssl/crypto/x509v3/pcy_map.c
@@ -0,0 +1,132 @@
+/* pcy_map.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+
+/* Set policy mapping entries in cache.
+ * Note: this modifies the passed POLICY_MAPPINGS structure
+ */
+
+int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
+	{
+	POLICY_MAPPING *map;
+	X509_POLICY_DATA *data;
+	X509_POLICY_CACHE *cache = x->policy_cache;
+	int i;
+	int ret = 0;
+	if (sk_POLICY_MAPPING_num(maps) == 0)
+		{
+		ret = -1;
+		goto bad_mapping;
+		}
+	for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++)
+		{
+		map = sk_POLICY_MAPPING_value(maps, i);
+		/* Reject if map to or from anyPolicy */
+		if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy)
+		   || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy))
+			{
+			ret = -1;
+			goto bad_mapping;
+			}
+
+		/* Attempt to find matching policy data */
+		data = policy_cache_find_data(cache, map->issuerDomainPolicy);
+		/* If we don't have anyPolicy can't map */
+		if (!data && !cache->anyPolicy)
+			continue;
+
+		/* Create a NODE from anyPolicy */
+		if (!data)
+			{
+			data = policy_data_new(NULL, map->issuerDomainPolicy,
+					cache->anyPolicy->flags
+						& POLICY_DATA_FLAG_CRITICAL);
+			if (!data)
+				goto bad_mapping;
+			data->qualifier_set = cache->anyPolicy->qualifier_set;
+			/*map->issuerDomainPolicy = NULL;*/
+			data->flags |= POLICY_DATA_FLAG_MAPPED_ANY;
+			data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
+			if (!sk_X509_POLICY_DATA_push(cache->data, data))
+				{
+				policy_data_free(data);
+				goto bad_mapping;
+				}
+			}
+		else
+			data->flags |= POLICY_DATA_FLAG_MAPPED;
+		if (!sk_ASN1_OBJECT_push(data->expected_policy_set, 
+						map->subjectDomainPolicy))
+			goto bad_mapping;
+		map->subjectDomainPolicy = NULL;
+
+		}
+
+	ret = 1;
+	bad_mapping:
+	if (ret == -1)
+		x->ex_flags |= EXFLAG_INVALID_POLICY;
+	sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free);
+	return ret;
+
+	}
diff --git a/openssl/crypto/x509v3/pcy_node.c b/openssl/crypto/x509v3/pcy_node.c
new file mode 100644
index 0000000..bd1e7f1
--- /dev/null
+++ b/openssl/crypto/x509v3/pcy_node.c
@@ -0,0 +1,197 @@
+/* pcy_node.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+
+static int node_cmp(const X509_POLICY_NODE * const *a,
+			const X509_POLICY_NODE * const *b)
+	{
+	return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy);
+	}
+
+STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void)
+	{
+	return sk_X509_POLICY_NODE_new(node_cmp);
+	}
+
+X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes,
+					const ASN1_OBJECT *id)
+	{
+	X509_POLICY_DATA n;
+	X509_POLICY_NODE l;
+	int idx;
+
+	n.valid_policy = (ASN1_OBJECT *)id;
+	l.data = &n;
+
+	idx = sk_X509_POLICY_NODE_find(nodes, &l);
+	if (idx == -1)
+		return NULL;
+
+	return sk_X509_POLICY_NODE_value(nodes, idx);
+
+	}
+
+X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
+					const X509_POLICY_NODE *parent,	
+					const ASN1_OBJECT *id)
+	{
+	X509_POLICY_NODE *node;
+	int i;
+	for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++)
+		{
+		node = sk_X509_POLICY_NODE_value(level->nodes, i);
+		if (node->parent == parent)
+			{
+			if (!OBJ_cmp(node->data->valid_policy, id))
+				return node;
+			}
+		}
+	return NULL;
+	}
+
+X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
+			const X509_POLICY_DATA *data,
+			X509_POLICY_NODE *parent,
+			X509_POLICY_TREE *tree)
+	{
+	X509_POLICY_NODE *node;
+	node = OPENSSL_malloc(sizeof(X509_POLICY_NODE));
+	if (!node)
+		return NULL;
+	node->data = data;
+	node->parent = parent;
+	node->nchild = 0;
+	if (level)
+		{
+		if (OBJ_obj2nid(data->valid_policy) == NID_any_policy)
+			{
+			if (level->anyPolicy)
+				goto node_error;
+			level->anyPolicy = node;
+			}
+		else
+			{
+
+			if (!level->nodes)
+				level->nodes = policy_node_cmp_new();
+			if (!level->nodes)
+				goto node_error;
+			if (!sk_X509_POLICY_NODE_push(level->nodes, node))
+				goto node_error;
+			}
+		}
+
+	if (tree)
+		{
+		if (!tree->extra_data)
+			 tree->extra_data = sk_X509_POLICY_DATA_new_null();
+		if (!tree->extra_data)
+			goto node_error;
+		if (!sk_X509_POLICY_DATA_push(tree->extra_data, data))
+			goto node_error;
+		}
+
+	if (parent)
+		parent->nchild++;
+
+	return node;
+
+	node_error:
+	policy_node_free(node);
+	return 0;
+
+	}
+
+void policy_node_free(X509_POLICY_NODE *node)
+	{
+	OPENSSL_free(node);
+	}
+
+/* See if a policy node matches a policy OID. If mapping enabled look through
+ * expected policy set otherwise just valid policy.
+ */
+
+int policy_node_match(const X509_POLICY_LEVEL *lvl,
+		      const X509_POLICY_NODE *node, const ASN1_OBJECT *oid)
+	{
+	int i;
+	ASN1_OBJECT *policy_oid;
+	const X509_POLICY_DATA *x = node->data;
+
+	if (	    (lvl->flags & X509_V_FLAG_INHIBIT_MAP)
+		|| !(x->flags & POLICY_DATA_FLAG_MAP_MASK))
+		{
+		if (!OBJ_cmp(x->valid_policy, oid))
+			return 1;
+		return 0;
+		}
+
+	for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++)
+		{
+		policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i);
+		if (!OBJ_cmp(policy_oid, oid))
+			return 1;
+		}
+	return 0;
+
+	}
diff --git a/openssl/crypto/x509v3/pcy_tree.c b/openssl/crypto/x509v3/pcy_tree.c
new file mode 100644
index 0000000..bb97773
--- /dev/null
+++ b/openssl/crypto/x509v3/pcy_tree.c
@@ -0,0 +1,872 @@
+/* pcy_tree.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+
+/* Enable this to print out the complete policy tree at various point during
+ * evaluation.
+ */
+
+/*#define OPENSSL_POLICY_DEBUG*/
+
+#ifdef OPENSSL_POLICY_DEBUG
+
+static void expected_print(BIO *err, X509_POLICY_LEVEL *lev,
+				X509_POLICY_NODE *node, int indent)
+	{
+	if (	    (lev->flags & X509_V_FLAG_INHIBIT_MAP)
+		|| !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
+		BIO_puts(err, "  Not Mapped\n");
+	else
+		{
+		int i;
+		STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
+		ASN1_OBJECT *oid;
+		BIO_puts(err, "  Expected: ");
+		for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++)
+			{
+			oid = sk_ASN1_OBJECT_value(pset, i);
+			if (i)
+				BIO_puts(err, ", ");
+			i2a_ASN1_OBJECT(err, oid);
+			}
+		BIO_puts(err, "\n");
+		}
+	}
+
+static void tree_print(char *str, X509_POLICY_TREE *tree,
+			X509_POLICY_LEVEL *curr)
+	{
+	X509_POLICY_LEVEL *plev;
+	X509_POLICY_NODE *node;
+	int i;
+	BIO *err;
+	err = BIO_new_fp(stderr, BIO_NOCLOSE);
+	if (!curr)
+		curr = tree->levels + tree->nlevel;
+	else
+		curr++;
+	BIO_printf(err, "Level print after %s\n", str);
+	BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
+	for (plev = tree->levels; plev != curr; plev++)
+		{
+		BIO_printf(err, "Level %ld, flags = %x\n",
+				plev - tree->levels, plev->flags);
+		for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++)
+			{
+			node = sk_X509_POLICY_NODE_value(plev->nodes, i);
+			X509_POLICY_NODE_print(err, node, 2);
+			expected_print(err, plev, node, 2);
+			BIO_printf(err, "  Flags: %x\n", node->data->flags);
+			}
+		if (plev->anyPolicy)
+			X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
+		}
+
+	BIO_free(err);
+
+	}
+#else
+
+#define tree_print(a,b,c) /* */
+
+#endif
+
+/* Initialize policy tree. Return values:
+ *  0 Some internal error occured.
+ * -1 Inconsistent or invalid extensions in certificates.
+ *  1 Tree initialized OK.
+ *  2 Policy tree is empty.
+ *  5 Tree OK and requireExplicitPolicy true.
+ *  6 Tree empty and requireExplicitPolicy true.
+ */
+
+static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
+			unsigned int flags)
+	{
+	X509_POLICY_TREE *tree;
+	X509_POLICY_LEVEL *level;
+	const X509_POLICY_CACHE *cache;
+	X509_POLICY_DATA *data = NULL;
+	X509 *x;
+	int ret = 1;
+	int i, n;
+	int explicit_policy;
+	int any_skip;
+	int map_skip;
+	*ptree = NULL;
+	n = sk_X509_num(certs);
+
+#if 0
+	/* Disable policy mapping for now... */
+	flags |= X509_V_FLAG_INHIBIT_MAP;
+#endif
+
+	if (flags & X509_V_FLAG_EXPLICIT_POLICY)
+		explicit_policy = 0;
+	else
+		explicit_policy = n + 1;
+
+	if (flags & X509_V_FLAG_INHIBIT_ANY)
+		any_skip = 0;
+	else
+		any_skip = n + 1;
+
+	if (flags & X509_V_FLAG_INHIBIT_MAP)
+		map_skip = 0;
+	else
+		map_skip = n + 1;
+
+	/* Can't do anything with just a trust anchor */
+	if (n == 1)
+		return 1;
+	/* First setup policy cache in all certificates apart from the
+	 * trust anchor. Note any bad cache results on the way. Also can
+	 * calculate explicit_policy value at this point.
+	 */
+	for (i = n - 2; i >= 0; i--)
+		{
+		x = sk_X509_value(certs, i);
+		X509_check_purpose(x, -1, -1);
+		cache = policy_cache_set(x);
+		/* If cache NULL something bad happened: return immediately */
+		if (cache == NULL)
+			return 0;
+		/* If inconsistent extensions keep a note of it but continue */
+		if (x->ex_flags & EXFLAG_INVALID_POLICY)
+			ret = -1;
+		/* Otherwise if we have no data (hence no CertificatePolicies)
+		 * and haven't already set an inconsistent code note it.
+		 */
+		else if ((ret == 1) && !cache->data)
+			ret = 2;
+		if (explicit_policy > 0)
+			{
+			if (!(x->ex_flags & EXFLAG_SI))
+				explicit_policy--;
+			if ((cache->explicit_skip != -1)
+				&& (cache->explicit_skip < explicit_policy))
+				explicit_policy = cache->explicit_skip;
+			}
+		}
+
+	if (ret != 1)
+		{
+		if (ret == 2 && !explicit_policy)
+			return 6;
+		return ret;
+		}
+
+
+	/* If we get this far initialize the tree */
+
+	tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE));
+
+	if (!tree)
+		return 0;
+
+	tree->flags = 0;
+	tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n);
+	tree->nlevel = 0;
+	tree->extra_data = NULL;
+	tree->auth_policies = NULL;
+	tree->user_policies = NULL;
+
+	if (!tree->levels)
+		{
+		OPENSSL_free(tree);
+		return 0;
+		}
+
+	memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));
+
+	tree->nlevel = n;
+
+	level = tree->levels;
+
+	/* Root data: initialize to anyPolicy */
+
+	data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0);
+
+	if (!data || !level_add_node(level, data, NULL, tree))
+		goto bad_tree;
+
+	for (i = n - 2; i >= 0; i--)
+		{
+		level++;
+		x = sk_X509_value(certs, i);
+		cache = policy_cache_set(x);
+		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
+		level->cert = x;
+
+		if (!cache->anyPolicy)
+				level->flags |= X509_V_FLAG_INHIBIT_ANY;
+
+		/* Determine inhibit any and inhibit map flags */
+		if (any_skip == 0)
+			{
+			/* Any matching allowed if certificate is self
+			 * issued and not the last in the chain.
+			 */
+			if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
+				level->flags |= X509_V_FLAG_INHIBIT_ANY;
+			}
+		else
+			{
+			if (!(x->ex_flags & EXFLAG_SI))
+				any_skip--;
+			if ((cache->any_skip >= 0)
+				&& (cache->any_skip < any_skip))
+				any_skip = cache->any_skip;
+			}
+
+		if (map_skip == 0)
+			level->flags |= X509_V_FLAG_INHIBIT_MAP;
+		else
+			{
+			if (!(x->ex_flags & EXFLAG_SI))
+				map_skip--;
+			if ((cache->map_skip >= 0)
+				&& (cache->map_skip < map_skip))
+				map_skip = cache->map_skip;
+			}
+
+		}
+
+	*ptree = tree;
+
+	if (explicit_policy)
+		return 1;
+	else
+		return 5;
+
+	bad_tree:
+
+	X509_policy_tree_free(tree);
+
+	return 0;
+
+	}
+
+static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
+				const X509_POLICY_DATA *data)
+	{
+	X509_POLICY_LEVEL *last = curr - 1;
+	X509_POLICY_NODE *node;
+	int i, matched = 0;
+	/* Iterate through all in nodes linking matches */
+	for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
+		{
+		node = sk_X509_POLICY_NODE_value(last->nodes, i);
+		if (policy_node_match(last, node, data->valid_policy))
+			{
+			if (!level_add_node(curr, data, node, NULL))
+				return 0;
+			matched = 1;
+			}
+		}
+	if (!matched && last->anyPolicy)
+		{
+		if (!level_add_node(curr, data, last->anyPolicy, NULL))
+			return 0;
+		}
+	return 1;
+	}
+
+/* This corresponds to RFC3280 6.1.3(d)(1):
+ * link any data from CertificatePolicies onto matching parent
+ * or anyPolicy if no match.
+ */
+
+static int tree_link_nodes(X509_POLICY_LEVEL *curr,
+				const X509_POLICY_CACHE *cache)
+	{
+	int i;
+	X509_POLICY_DATA *data;
+
+	for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++)
+		{
+		data = sk_X509_POLICY_DATA_value(cache->data, i);
+		/* If a node is mapped any it doesn't have a corresponding
+		 * CertificatePolicies entry. 
+		 * However such an identical node would be created
+		 * if anyPolicy matching is enabled because there would be
+		 * no match with the parent valid_policy_set. So we create
+		 * link because then it will have the mapping flags
+		 * right and we can prune it later.
+		 */
+#if 0
+		if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
+			&& !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
+			continue;
+#endif
+		/* Look for matching nodes in previous level */
+		if (!tree_link_matching_nodes(curr, data))
+				return 0;
+		}
+	return 1;
+	}
+
+/* This corresponds to RFC3280 6.1.3(d)(2):
+ * Create new data for any unmatched policies in the parent and link
+ * to anyPolicy.
+ */
+
+static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
+			const X509_POLICY_CACHE *cache,
+			const ASN1_OBJECT *id,
+			X509_POLICY_NODE *node,
+			X509_POLICY_TREE *tree)
+	{
+	X509_POLICY_DATA *data;
+	if (id == NULL)
+		id = node->data->valid_policy;
+	/* Create a new node with qualifiers from anyPolicy and
+	 * id from unmatched node.
+	 */
+	data = policy_data_new(NULL, id, node_critical(node));
+
+	if (data == NULL)
+		return 0;
+	/* Curr may not have anyPolicy */
+	data->qualifier_set = cache->anyPolicy->qualifier_set;
+	data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
+	if (!level_add_node(curr, data, node, tree))
+		{
+		policy_data_free(data);
+		return 0;
+		}
+
+	return 1;
+	}
+
+static int tree_link_unmatched(X509_POLICY_LEVEL *curr,
+			const X509_POLICY_CACHE *cache,
+			X509_POLICY_NODE *node,
+			X509_POLICY_TREE *tree)
+	{
+	const X509_POLICY_LEVEL *last = curr - 1;
+	int i;
+
+	if (	    (last->flags & X509_V_FLAG_INHIBIT_MAP)
+		|| !(node->data->flags & POLICY_DATA_FLAG_MAPPED))
+		{
+		/* If no policy mapping: matched if one child present */
+		if (node->nchild)
+			return 1;
+		if (!tree_add_unmatched(curr, cache, NULL, node, tree))
+			return 0;
+		/* Add it */
+		}
+	else
+		{
+		/* If mapping: matched if one child per expected policy set */
+		STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
+		if (node->nchild == sk_ASN1_OBJECT_num(expset))
+			return 1;
+		/* Locate unmatched nodes */
+		for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++)
+			{
+			ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
+			if (level_find_node(curr, node, oid))
+				continue;
+			if (!tree_add_unmatched(curr, cache, oid, node, tree))
+				return 0;
+			}
+
+		}
+
+	return 1;
+
+	}
+
+static int tree_link_any(X509_POLICY_LEVEL *curr,
+			const X509_POLICY_CACHE *cache,
+			X509_POLICY_TREE *tree)
+	{
+	int i;
+	/*X509_POLICY_DATA *data;*/
+	X509_POLICY_NODE *node;
+	X509_POLICY_LEVEL *last = curr - 1;
+
+	for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
+		{
+		node = sk_X509_POLICY_NODE_value(last->nodes, i);
+
+		if (!tree_link_unmatched(curr, cache, node, tree))
+			return 0;
+
+#if 0
+
+		/* Skip any node with any children: we only want unmathced
+		 * nodes.
+		 *
+		 * Note: need something better for policy mapping
+		 * because each node may have multiple children 
+		 */
+		if (node->nchild)
+			continue;
+
+		/* Create a new node with qualifiers from anyPolicy and
+		 * id from unmatched node.
+		 */
+		data = policy_data_new(NULL, node->data->valid_policy, 
+						node_critical(node));
+
+		if (data == NULL)
+			return 0;
+		/* Curr may not have anyPolicy */
+		data->qualifier_set = cache->anyPolicy->qualifier_set;
+		data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
+		if (!level_add_node(curr, data, node, tree))
+			{
+			policy_data_free(data);
+			return 0;
+			}
+
+#endif
+
+		}
+	/* Finally add link to anyPolicy */
+	if (last->anyPolicy)
+		{
+		if (!level_add_node(curr, cache->anyPolicy,
+						last->anyPolicy, NULL))
+			return 0;
+		}
+	return 1;
+	}
+
+/* Prune the tree: delete any child mapped child data on the current level
+ * then proceed up the tree deleting any data with no children. If we ever
+ * have no data on a level we can halt because the tree will be empty.
+ */
+
+static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
+	{
+	STACK_OF(X509_POLICY_NODE) *nodes;
+	X509_POLICY_NODE *node;
+	int i;
+	nodes = curr->nodes;
+	if (curr->flags & X509_V_FLAG_INHIBIT_MAP)
+		{
+		for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
+			{
+			node = sk_X509_POLICY_NODE_value(nodes, i);
+			/* Delete any mapped data: see RFC3280 XXXX */
+			if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK)
+				{
+				node->parent->nchild--;
+				OPENSSL_free(node);
+				(void)sk_X509_POLICY_NODE_delete(nodes,i);
+				}
+			}
+		}
+
+	for(;;)	{
+		--curr;
+		nodes = curr->nodes;
+		for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
+			{
+			node = sk_X509_POLICY_NODE_value(nodes, i);
+			if (node->nchild == 0)
+				{
+				node->parent->nchild--;
+				OPENSSL_free(node);
+				(void)sk_X509_POLICY_NODE_delete(nodes, i);
+				}
+			}
+		if (curr->anyPolicy && !curr->anyPolicy->nchild)
+			{
+			if (curr->anyPolicy->parent)
+				curr->anyPolicy->parent->nchild--;
+			OPENSSL_free(curr->anyPolicy);
+			curr->anyPolicy = NULL;
+			}
+		if (curr == tree->levels)
+			{
+			/* If we zapped anyPolicy at top then tree is empty */
+			if (!curr->anyPolicy)
+					return 2;
+			return 1;
+			}
+		}
+
+	return 1;
+
+	}
+
+static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
+						 X509_POLICY_NODE *pcy)
+	{
+	if (!*pnodes)
+		{
+		*pnodes = policy_node_cmp_new();
+		if (!*pnodes)
+			return 0;
+		}
+	else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1)
+		return 1;
+
+	if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
+		return 0;
+
+	return 1;
+
+	}
+
+/* Calculate the authority set based on policy tree.
+ * The 'pnodes' parameter is used as a store for the set of policy nodes
+ * used to calculate the user set. If the authority set is not anyPolicy
+ * then pnodes will just point to the authority set. If however the authority
+ * set is anyPolicy then the set of valid policies (other than anyPolicy)
+ * is store in pnodes. The return value of '2' is used in this case to indicate
+ * that pnodes should be freed.
+ */
+
+static int tree_calculate_authority_set(X509_POLICY_TREE *tree,
+					STACK_OF(X509_POLICY_NODE) **pnodes)
+	{
+	X509_POLICY_LEVEL *curr;
+	X509_POLICY_NODE *node, *anyptr;
+	STACK_OF(X509_POLICY_NODE) **addnodes;
+	int i, j;
+	curr = tree->levels + tree->nlevel - 1;
+
+	/* If last level contains anyPolicy set is anyPolicy */
+	if (curr->anyPolicy)
+		{
+		if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
+			return 0;
+		addnodes = pnodes;
+		}
+	else
+		/* Add policies to authority set */
+		addnodes = &tree->auth_policies;
+
+	curr = tree->levels;
+	for (i = 1; i < tree->nlevel; i++)
+		{
+		/* If no anyPolicy node on this this level it can't
+		 * appear on lower levels so end search.
+		 */
+		if (!(anyptr = curr->anyPolicy))
+			break;
+		curr++;
+		for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++)
+			{
+			node = sk_X509_POLICY_NODE_value(curr->nodes, j);
+			if ((node->parent == anyptr)
+				&& !tree_add_auth_node(addnodes, node))
+					return 0;
+			}
+		}
+
+	if (addnodes == pnodes)
+		return 2;
+
+	*pnodes = tree->auth_policies;
+
+	return 1;
+	}
+
+static int tree_calculate_user_set(X509_POLICY_TREE *tree,
+				STACK_OF(ASN1_OBJECT) *policy_oids,
+				STACK_OF(X509_POLICY_NODE) *auth_nodes)
+	{
+	int i;
+	X509_POLICY_NODE *node;
+	ASN1_OBJECT *oid;
+
+	X509_POLICY_NODE *anyPolicy;
+	X509_POLICY_DATA *extra;
+
+	/* Check if anyPolicy present in authority constrained policy set:
+	 * this will happen if it is a leaf node.
+	 */
+
+	if (sk_ASN1_OBJECT_num(policy_oids) <= 0)
+		return 1;
+
+	anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
+
+	for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
+		{
+		oid = sk_ASN1_OBJECT_value(policy_oids, i);
+		if (OBJ_obj2nid(oid) == NID_any_policy)
+			{
+			tree->flags |= POLICY_FLAG_ANY_POLICY;
+			return 1;
+			}
+		}
+
+	for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
+		{
+		oid = sk_ASN1_OBJECT_value(policy_oids, i);
+		node = tree_find_sk(auth_nodes, oid);
+		if (!node)
+			{
+			if (!anyPolicy)
+				continue;
+			/* Create a new node with policy ID from user set
+			 * and qualifiers from anyPolicy.
+			 */
+			extra = policy_data_new(NULL, oid,
+						node_critical(anyPolicy));
+			if (!extra)
+				return 0;
+			extra->qualifier_set = anyPolicy->data->qualifier_set;
+			extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
+						| POLICY_DATA_FLAG_EXTRA_NODE;
+			node = level_add_node(NULL, extra, anyPolicy->parent,
+						tree);
+			}
+		if (!tree->user_policies)
+			{
+			tree->user_policies = sk_X509_POLICY_NODE_new_null();
+			if (!tree->user_policies)
+				return 1;
+			}
+		if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
+			return 0;
+		}
+	return 1;
+
+	}
+
+static int tree_evaluate(X509_POLICY_TREE *tree)
+	{
+	int ret, i;
+	X509_POLICY_LEVEL *curr = tree->levels + 1;
+	const X509_POLICY_CACHE *cache;
+
+	for(i = 1; i < tree->nlevel; i++, curr++)
+		{
+		cache = policy_cache_set(curr->cert);
+		if (!tree_link_nodes(curr, cache))
+			return 0;
+
+		if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
+			&& !tree_link_any(curr, cache, tree))
+			return 0;
+	tree_print("before tree_prune()", tree, curr);
+		ret = tree_prune(tree, curr);
+		if (ret != 1)
+			return ret;
+		}
+
+	return 1;
+
+	}
+
+static void exnode_free(X509_POLICY_NODE *node)
+	{
+	if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
+		OPENSSL_free(node);
+	}
+
+
+void X509_policy_tree_free(X509_POLICY_TREE *tree)
+	{
+	X509_POLICY_LEVEL *curr;
+	int i;
+
+	if (!tree)
+		return;
+
+	sk_X509_POLICY_NODE_free(tree->auth_policies);
+	sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
+
+	for(i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++)
+		{
+		if (curr->cert)
+			X509_free(curr->cert);
+		if (curr->nodes)
+			sk_X509_POLICY_NODE_pop_free(curr->nodes,
+						policy_node_free);
+		if (curr->anyPolicy)
+			policy_node_free(curr->anyPolicy);
+		}
+
+	if (tree->extra_data)
+		sk_X509_POLICY_DATA_pop_free(tree->extra_data,
+						policy_data_free);
+
+	OPENSSL_free(tree->levels);
+	OPENSSL_free(tree);
+
+	}
+
+/* Application policy checking function.
+ * Return codes:
+ *  0 	Internal Error.
+ *  1   Successful.
+ * -1   One or more certificates contain invalid or inconsistent extensions
+ * -2	User constrained policy set empty and requireExplicit true.
+ */
+
+int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
+			STACK_OF(X509) *certs,
+			STACK_OF(ASN1_OBJECT) *policy_oids,
+			unsigned int flags)
+	{
+	int ret;
+	X509_POLICY_TREE *tree = NULL;
+	STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
+	*ptree = NULL;
+
+	*pexplicit_policy = 0;
+	ret = tree_init(&tree, certs, flags);
+
+	switch (ret)
+		{
+
+		/* Tree empty requireExplicit False: OK */
+		case 2:
+		return 1;
+
+		/* Some internal error */
+		case -1:
+		return -1;
+
+		/* Some internal error */
+		case 0:
+		return 0;
+
+		/* Tree empty requireExplicit True: Error */
+
+		case 6:
+		*pexplicit_policy = 1;
+		return -2;
+
+		/* Tree OK requireExplicit True: OK and continue */
+		case 5:
+		*pexplicit_policy = 1;
+		break;
+
+		/* Tree OK: continue */
+
+		case 1:
+		if (!tree)
+			/*
+			 * tree_init() returns success and a null tree
+			 * if it's just looking at a trust anchor.
+			 * I'm not sure that returning success here is
+			 * correct, but I'm sure that reporting this
+			 * as an internal error which our caller
+			 * interprets as a malloc failure is wrong.
+			 */
+			return 1;
+		break;
+		}
+
+	if (!tree) goto error;
+	ret = tree_evaluate(tree);
+
+	tree_print("tree_evaluate()", tree, NULL);
+
+	if (ret <= 0)
+		goto error;
+
+	/* Return value 2 means tree empty */
+	if (ret == 2)
+		{
+		X509_policy_tree_free(tree);
+		if (*pexplicit_policy)
+			return -2;
+		else
+			return 1;
+		}
+
+	/* Tree is not empty: continue */
+
+	ret = tree_calculate_authority_set(tree, &auth_nodes);
+
+	if (!ret)
+		goto error;
+
+	if (!tree_calculate_user_set(tree, policy_oids, auth_nodes))
+		goto error;
+	
+	if (ret == 2)
+		sk_X509_POLICY_NODE_free(auth_nodes);
+
+	if (tree)
+		*ptree = tree;
+
+	if (*pexplicit_policy)
+		{
+		nodes = X509_policy_tree_get0_user_policies(tree);
+		if (sk_X509_POLICY_NODE_num(nodes) <= 0)
+			return -2;
+		}
+
+	return 1;
+
+	error:
+
+	X509_policy_tree_free(tree);
+
+	return 0;
+
+	}
+
diff --git a/openssl/crypto/x509v3/tabtest.c b/openssl/crypto/x509v3/tabtest.c
new file mode 100644
index 0000000..5ed6eb6
--- /dev/null
+++ b/openssl/crypto/x509v3/tabtest.c
@@ -0,0 +1,88 @@
+/* tabtest.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Simple program to check the ext_dat.h is correct and print out
+ * problems if it is not.
+ */
+
+#include <stdio.h>
+
+#include <openssl/x509v3.h>
+
+#include "ext_dat.h"
+
+main()
+{
+	int i, prev = -1, bad = 0;
+	X509V3_EXT_METHOD **tmp;
+	i = sizeof(standard_exts) / sizeof(X509V3_EXT_METHOD *);
+	if(i != STANDARD_EXTENSION_COUNT)
+		fprintf(stderr, "Extension number invalid expecting %d\n", i);
+	tmp = standard_exts;
+	for(i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++) {
+		if((*tmp)->ext_nid < prev) bad = 1;
+		prev = (*tmp)->ext_nid;
+		
+	}
+	if(bad) {
+		tmp = standard_exts;
+		fprintf(stderr, "Extensions out of order!\n");
+		for(i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++)
+		printf("%d : %s\n", (*tmp)->ext_nid, OBJ_nid2sn((*tmp)->ext_nid));
+	} else fprintf(stderr, "Order OK\n");
+}
diff --git a/openssl/crypto/x509v3/v3_addr.c b/openssl/crypto/x509v3/v3_addr.c
new file mode 100644
index 0000000..df46a49
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_addr.c
@@ -0,0 +1,1338 @@
+/*
+ * Contributed to the OpenSSL Project by the American Registry for
+ * Internet Numbers ("ARIN").
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ */
+
+/*
+ * Implementation of RFC 3779 section 2.2.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/buffer.h>
+#include <openssl/x509v3.h>
+
+#ifndef OPENSSL_NO_RFC3779
+
+/*
+ * OpenSSL ASN.1 template translation of RFC 3779 2.2.3.
+ */
+
+ASN1_SEQUENCE(IPAddressRange) = {
+  ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING),
+  ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END(IPAddressRange)
+
+ASN1_CHOICE(IPAddressOrRange) = {
+  ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING),
+  ASN1_SIMPLE(IPAddressOrRange, u.addressRange,  IPAddressRange)
+} ASN1_CHOICE_END(IPAddressOrRange)
+
+ASN1_CHOICE(IPAddressChoice) = {
+  ASN1_SIMPLE(IPAddressChoice,      u.inherit,           ASN1_NULL),
+  ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange)
+} ASN1_CHOICE_END(IPAddressChoice)
+
+ASN1_SEQUENCE(IPAddressFamily) = {
+  ASN1_SIMPLE(IPAddressFamily, addressFamily,   ASN1_OCTET_STRING),
+  ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice)
+} ASN1_SEQUENCE_END(IPAddressFamily)
+
+ASN1_ITEM_TEMPLATE(IPAddrBlocks) = 
+  ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0,
+			IPAddrBlocks, IPAddressFamily)
+ASN1_ITEM_TEMPLATE_END(IPAddrBlocks)
+
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange)
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange)
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice)
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily)
+
+/*
+ * How much buffer space do we need for a raw address?
+ */
+#define ADDR_RAW_BUF_LEN	16
+
+/*
+ * What's the address length associated with this AFI?
+ */
+static int length_from_afi(const unsigned afi)
+{
+  switch (afi) {
+  case IANA_AFI_IPV4:
+    return 4;
+  case IANA_AFI_IPV6:
+    return 16;
+  default:
+    return 0;
+  }
+}
+
+/*
+ * Extract the AFI from an IPAddressFamily.
+ */
+unsigned int v3_addr_get_afi(const IPAddressFamily *f)
+{
+  return ((f != NULL &&
+	   f->addressFamily != NULL &&
+	   f->addressFamily->data != NULL)
+	  ? ((f->addressFamily->data[0] << 8) |
+	     (f->addressFamily->data[1]))
+	  : 0);
+}
+
+/*
+ * Expand the bitstring form of an address into a raw byte array.
+ * At the moment this is coded for simplicity, not speed.
+ */
+static int addr_expand(unsigned char *addr,
+			const ASN1_BIT_STRING *bs,
+			const int length,
+			const unsigned char fill)
+{
+  if (bs->length < 0 || bs->length > length)
+    return 0;
+  if (bs->length > 0) {
+    memcpy(addr, bs->data, bs->length);
+    if ((bs->flags & 7) != 0) {
+      unsigned char mask = 0xFF >> (8 - (bs->flags & 7));
+      if (fill == 0)
+	addr[bs->length - 1] &= ~mask;
+      else
+	addr[bs->length - 1] |= mask;
+    }
+  }
+  memset(addr + bs->length, fill, length - bs->length);
+  return 1;
+}
+
+/*
+ * Extract the prefix length from a bitstring.
+ */
+#define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7)))
+
+/*
+ * i2r handler for one address bitstring.
+ */
+static int i2r_address(BIO *out,
+		       const unsigned afi,
+		       const unsigned char fill,
+		       const ASN1_BIT_STRING *bs)
+{
+  unsigned char addr[ADDR_RAW_BUF_LEN];
+  int i, n;
+
+  if (bs->length < 0)
+    return 0;
+  switch (afi) {
+  case IANA_AFI_IPV4:
+    if (!addr_expand(addr, bs, 4, fill))
+      return 0;
+    BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
+    break;
+  case IANA_AFI_IPV6:
+    if (!addr_expand(addr, bs, 16, fill))
+      return 0;
+    for (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2)
+      ;
+    for (i = 0; i < n; i += 2)
+      BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i+1], (i < 14 ? ":" : ""));
+    if (i < 16)
+      BIO_puts(out, ":");
+    if (i == 0)
+      BIO_puts(out, ":");
+    break;
+  default:
+    for (i = 0; i < bs->length; i++)
+      BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]);
+    BIO_printf(out, "[%d]", (int) (bs->flags & 7));
+    break;
+  }
+  return 1;
+}
+
+/*
+ * i2r handler for a sequence of addresses and ranges.
+ */
+static int i2r_IPAddressOrRanges(BIO *out,
+				 const int indent,
+				 const IPAddressOrRanges *aors,
+				 const unsigned afi)
+{
+  int i;
+  for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) {
+    const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i);
+    BIO_printf(out, "%*s", indent, "");
+    switch (aor->type) {
+    case IPAddressOrRange_addressPrefix:
+      if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix))
+	return 0;
+      BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix));
+      continue;
+    case IPAddressOrRange_addressRange:
+      if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min))
+	return 0;
+      BIO_puts(out, "-");
+      if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max))
+	return 0;
+      BIO_puts(out, "\n");
+      continue;
+    }
+  }
+  return 1;
+}
+
+/*
+ * i2r handler for an IPAddrBlocks extension.
+ */
+static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method,
+			    void *ext,
+			    BIO *out,
+			    int indent)
+{
+  const IPAddrBlocks *addr = ext;
+  int i;
+  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+    const unsigned int afi = v3_addr_get_afi(f);
+    switch (afi) {
+    case IANA_AFI_IPV4:
+      BIO_printf(out, "%*sIPv4", indent, "");
+      break;
+    case IANA_AFI_IPV6:
+      BIO_printf(out, "%*sIPv6", indent, "");
+      break;
+    default:
+      BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi);
+      break;
+    }
+    if (f->addressFamily->length > 2) {
+      switch (f->addressFamily->data[2]) {
+      case   1:
+	BIO_puts(out, " (Unicast)");
+	break;
+      case   2:
+	BIO_puts(out, " (Multicast)");
+	break;
+      case   3:
+	BIO_puts(out, " (Unicast/Multicast)");
+	break;
+      case   4:
+	BIO_puts(out, " (MPLS)");
+	break;
+      case  64:
+	BIO_puts(out, " (Tunnel)");
+	break;
+      case  65:
+	BIO_puts(out, " (VPLS)");
+	break;
+      case  66:
+	BIO_puts(out, " (BGP MDT)");
+	break;
+      case 128:
+	BIO_puts(out, " (MPLS-labeled VPN)");
+	break;
+      default:  
+	BIO_printf(out, " (Unknown SAFI %u)",
+		   (unsigned) f->addressFamily->data[2]);
+	break;
+      }
+    }
+    switch (f->ipAddressChoice->type) {
+    case IPAddressChoice_inherit:
+      BIO_puts(out, ": inherit\n");
+      break;
+    case IPAddressChoice_addressesOrRanges:
+      BIO_puts(out, ":\n");
+      if (!i2r_IPAddressOrRanges(out,
+				 indent + 2,
+				 f->ipAddressChoice->u.addressesOrRanges,
+				 afi))
+	return 0;
+      break;
+    }
+  }
+  return 1;
+}
+
+/*
+ * Sort comparison function for a sequence of IPAddressOrRange
+ * elements.
+ *
+ * There's no sane answer we can give if addr_expand() fails, and an
+ * assertion failure on externally supplied data is seriously uncool,
+ * so we just arbitrarily declare that if given invalid inputs this
+ * function returns -1.  If this messes up your preferred sort order
+ * for garbage input, tough noogies.
+ */
+static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
+				const IPAddressOrRange *b,
+				const int length)
+{
+  unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN];
+  int prefixlen_a = 0, prefixlen_b = 0;
+  int r;
+
+  switch (a->type) {
+  case IPAddressOrRange_addressPrefix:
+    if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00))
+      return -1;
+    prefixlen_a = addr_prefixlen(a->u.addressPrefix);
+    break;
+  case IPAddressOrRange_addressRange:
+    if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00))
+      return -1;
+    prefixlen_a = length * 8;
+    break;
+  }
+
+  switch (b->type) {
+  case IPAddressOrRange_addressPrefix:
+    if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00))
+      return -1;
+    prefixlen_b = addr_prefixlen(b->u.addressPrefix);
+    break;
+  case IPAddressOrRange_addressRange:
+    if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00))
+      return -1;
+    prefixlen_b = length * 8;
+    break;
+  }
+
+  if ((r = memcmp(addr_a, addr_b, length)) != 0)
+    return r;
+  else
+    return prefixlen_a - prefixlen_b;
+}
+
+/*
+ * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort()
+ * comparision routines are only allowed two arguments.
+ */
+static int v4IPAddressOrRange_cmp(const IPAddressOrRange * const *a,
+				  const IPAddressOrRange * const *b)
+{
+  return IPAddressOrRange_cmp(*a, *b, 4);
+}
+
+/*
+ * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort()
+ * comparision routines are only allowed two arguments.
+ */
+static int v6IPAddressOrRange_cmp(const IPAddressOrRange * const *a,
+				  const IPAddressOrRange * const *b)
+{
+  return IPAddressOrRange_cmp(*a, *b, 16);
+}
+
+/*
+ * Calculate whether a range collapses to a prefix.
+ * See last paragraph of RFC 3779 2.2.3.7.
+ */
+static int range_should_be_prefix(const unsigned char *min,
+				  const unsigned char *max,
+				  const int length)
+{
+  unsigned char mask;
+  int i, j;
+
+  OPENSSL_assert(memcmp(min, max, length) <= 0);
+  for (i = 0; i < length && min[i] == max[i]; i++)
+    ;
+  for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--)
+    ;
+  if (i < j)
+    return -1;
+  if (i > j)
+    return i * 8;
+  mask = min[i] ^ max[i];
+  switch (mask) {
+  case 0x01: j = 7; break;
+  case 0x03: j = 6; break;
+  case 0x07: j = 5; break;
+  case 0x0F: j = 4; break;
+  case 0x1F: j = 3; break;
+  case 0x3F: j = 2; break;
+  case 0x7F: j = 1; break;
+  default:   return -1;
+  }
+  if ((min[i] & mask) != 0 || (max[i] & mask) != mask)
+    return -1;
+  else
+    return i * 8 + j;
+}
+
+/*
+ * Construct a prefix.
+ */
+static int make_addressPrefix(IPAddressOrRange **result,
+			      unsigned char *addr,
+			      const int prefixlen)
+{
+  int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8;
+  IPAddressOrRange *aor = IPAddressOrRange_new();
+
+  if (aor == NULL)
+    return 0;
+  aor->type = IPAddressOrRange_addressPrefix;
+  if (aor->u.addressPrefix == NULL &&
+      (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL)
+    goto err;
+  if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen))
+    goto err;
+  aor->u.addressPrefix->flags &= ~7;
+  aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+  if (bitlen > 0) {
+    aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen);
+    aor->u.addressPrefix->flags |= 8 - bitlen;
+  }
+  
+  *result = aor;
+  return 1;
+
+ err:
+  IPAddressOrRange_free(aor);
+  return 0;
+}
+
+/*
+ * Construct a range.  If it can be expressed as a prefix,
+ * return a prefix instead.  Doing this here simplifies
+ * the rest of the code considerably.
+ */
+static int make_addressRange(IPAddressOrRange **result,
+			     unsigned char *min,
+			     unsigned char *max,
+			     const int length)
+{
+  IPAddressOrRange *aor;
+  int i, prefixlen;
+
+  if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0)
+    return make_addressPrefix(result, min, prefixlen);
+
+  if ((aor = IPAddressOrRange_new()) == NULL)
+    return 0;
+  aor->type = IPAddressOrRange_addressRange;
+  OPENSSL_assert(aor->u.addressRange == NULL);
+  if ((aor->u.addressRange = IPAddressRange_new()) == NULL)
+    goto err;
+  if (aor->u.addressRange->min == NULL &&
+      (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL)
+    goto err;
+  if (aor->u.addressRange->max == NULL &&
+      (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL)
+    goto err;
+
+  for (i = length; i > 0 && min[i - 1] == 0x00; --i)
+    ;
+  if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i))
+    goto err;
+  aor->u.addressRange->min->flags &= ~7;
+  aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+  if (i > 0) {
+    unsigned char b = min[i - 1];
+    int j = 1;
+    while ((b & (0xFFU >> j)) != 0) 
+      ++j;
+    aor->u.addressRange->min->flags |= 8 - j;
+  }
+
+  for (i = length; i > 0 && max[i - 1] == 0xFF; --i)
+    ;
+  if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i))
+    goto err;
+  aor->u.addressRange->max->flags &= ~7;
+  aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+  if (i > 0) {
+    unsigned char b = max[i - 1];
+    int j = 1;
+    while ((b & (0xFFU >> j)) != (0xFFU >> j))
+      ++j;
+    aor->u.addressRange->max->flags |= 8 - j;
+  }
+
+  *result = aor;
+  return 1;
+
+ err:
+  IPAddressOrRange_free(aor);
+  return 0;
+}
+
+/*
+ * Construct a new address family or find an existing one.
+ */
+static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr,
+					     const unsigned afi,
+					     const unsigned *safi)
+{
+  IPAddressFamily *f;
+  unsigned char key[3];
+  unsigned keylen;
+  int i;
+
+  key[0] = (afi >> 8) & 0xFF;
+  key[1] = afi & 0xFF;
+  if (safi != NULL) {
+    key[2] = *safi & 0xFF;
+    keylen = 3;
+  } else {
+    keylen = 2;
+  }
+
+  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+    f = sk_IPAddressFamily_value(addr, i);
+    OPENSSL_assert(f->addressFamily->data != NULL);
+    if (f->addressFamily->length == keylen &&
+	!memcmp(f->addressFamily->data, key, keylen))
+      return f;
+  }
+
+  if ((f = IPAddressFamily_new()) == NULL)
+    goto err;
+  if (f->ipAddressChoice == NULL &&
+      (f->ipAddressChoice = IPAddressChoice_new()) == NULL)
+    goto err;
+  if (f->addressFamily == NULL && 
+      (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL)
+    goto err;
+  if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen))
+    goto err;
+  if (!sk_IPAddressFamily_push(addr, f))
+    goto err;
+
+  return f;
+
+ err:
+  IPAddressFamily_free(f);
+  return NULL;
+}
+
+/*
+ * Add an inheritance element.
+ */
+int v3_addr_add_inherit(IPAddrBlocks *addr,
+			const unsigned afi,
+			const unsigned *safi)
+{
+  IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
+  if (f == NULL ||
+      f->ipAddressChoice == NULL ||
+      (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
+       f->ipAddressChoice->u.addressesOrRanges != NULL))
+    return 0;
+  if (f->ipAddressChoice->type == IPAddressChoice_inherit &&
+      f->ipAddressChoice->u.inherit != NULL)
+    return 1;
+  if (f->ipAddressChoice->u.inherit == NULL &&
+      (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL)
+    return 0;
+  f->ipAddressChoice->type = IPAddressChoice_inherit;
+  return 1;
+}
+
+/*
+ * Construct an IPAddressOrRange sequence, or return an existing one.
+ */
+static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr,
+					       const unsigned afi,
+					       const unsigned *safi)
+{
+  IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
+  IPAddressOrRanges *aors = NULL;
+
+  if (f == NULL ||
+      f->ipAddressChoice == NULL ||
+      (f->ipAddressChoice->type == IPAddressChoice_inherit &&
+       f->ipAddressChoice->u.inherit != NULL))
+    return NULL;
+  if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges)
+    aors = f->ipAddressChoice->u.addressesOrRanges;
+  if (aors != NULL)
+    return aors;
+  if ((aors = sk_IPAddressOrRange_new_null()) == NULL)
+    return NULL;
+  switch (afi) {
+  case IANA_AFI_IPV4:
+    (void) sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
+    break;
+  case IANA_AFI_IPV6:
+    (void) sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
+    break;
+  }
+  f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges;
+  f->ipAddressChoice->u.addressesOrRanges = aors;
+  return aors;
+}
+
+/*
+ * Add a prefix.
+ */
+int v3_addr_add_prefix(IPAddrBlocks *addr,
+		       const unsigned afi,
+		       const unsigned *safi,
+		       unsigned char *a,
+		       const int prefixlen)
+{
+  IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
+  IPAddressOrRange *aor;
+  if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen))
+    return 0;
+  if (sk_IPAddressOrRange_push(aors, aor))
+    return 1;
+  IPAddressOrRange_free(aor);
+  return 0;
+}
+
+/*
+ * Add a range.
+ */
+int v3_addr_add_range(IPAddrBlocks *addr,
+		      const unsigned afi,
+		      const unsigned *safi,
+		      unsigned char *min,
+		      unsigned char *max)
+{
+  IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
+  IPAddressOrRange *aor;
+  int length = length_from_afi(afi);
+  if (aors == NULL)
+    return 0;
+  if (!make_addressRange(&aor, min, max, length))
+    return 0;
+  if (sk_IPAddressOrRange_push(aors, aor))
+    return 1;
+  IPAddressOrRange_free(aor);
+  return 0;
+}
+
+/*
+ * Extract min and max values from an IPAddressOrRange.
+ */
+static int extract_min_max(IPAddressOrRange *aor,
+			    unsigned char *min,
+			    unsigned char *max,
+			    int length)
+{
+  if (aor == NULL || min == NULL || max == NULL)
+    return 0;
+  switch (aor->type) {
+  case IPAddressOrRange_addressPrefix:
+    return (addr_expand(min, aor->u.addressPrefix, length, 0x00) &&
+	    addr_expand(max, aor->u.addressPrefix, length, 0xFF));
+  case IPAddressOrRange_addressRange:
+    return (addr_expand(min, aor->u.addressRange->min, length, 0x00) &&
+	    addr_expand(max, aor->u.addressRange->max, length, 0xFF));
+  }
+  return 0;
+}
+
+/*
+ * Public wrapper for extract_min_max().
+ */
+int v3_addr_get_range(IPAddressOrRange *aor,
+		      const unsigned afi,
+		      unsigned char *min,
+		      unsigned char *max,
+		      const int length)
+{
+  int afi_length = length_from_afi(afi);
+  if (aor == NULL || min == NULL || max == NULL ||
+      afi_length == 0 || length < afi_length ||
+      (aor->type != IPAddressOrRange_addressPrefix &&
+       aor->type != IPAddressOrRange_addressRange) ||
+      !extract_min_max(aor, min, max, afi_length))
+    return 0;
+
+  return afi_length;
+}
+
+/*
+ * Sort comparision function for a sequence of IPAddressFamily.
+ *
+ * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about
+ * the ordering: I can read it as meaning that IPv6 without a SAFI
+ * comes before IPv4 with a SAFI, which seems pretty weird.  The
+ * examples in appendix B suggest that the author intended the
+ * null-SAFI rule to apply only within a single AFI, which is what I
+ * would have expected and is what the following code implements.
+ */
+static int IPAddressFamily_cmp(const IPAddressFamily * const *a_,
+			       const IPAddressFamily * const *b_)
+{
+  const ASN1_OCTET_STRING *a = (*a_)->addressFamily;
+  const ASN1_OCTET_STRING *b = (*b_)->addressFamily;
+  int len = ((a->length <= b->length) ? a->length : b->length);
+  int cmp = memcmp(a->data, b->data, len);
+  return cmp ? cmp : a->length - b->length;
+}
+
+/*
+ * Check whether an IPAddrBLocks is in canonical form.
+ */
+int v3_addr_is_canonical(IPAddrBlocks *addr)
+{
+  unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
+  unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
+  IPAddressOrRanges *aors;
+  int i, j, k;
+
+  /*
+   * Empty extension is cannonical.
+   */
+  if (addr == NULL)
+    return 1;
+
+  /*
+   * Check whether the top-level list is in order.
+   */
+  for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) {
+    const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i);
+    const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1);
+    if (IPAddressFamily_cmp(&a, &b) >= 0)
+      return 0;
+  }
+
+  /*
+   * Top level's ok, now check each address family.
+   */
+  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+    int length = length_from_afi(v3_addr_get_afi(f));
+
+    /*
+     * Inheritance is canonical.  Anything other than inheritance or
+     * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something.
+     */
+    if (f == NULL || f->ipAddressChoice == NULL)
+      return 0;
+    switch (f->ipAddressChoice->type) {
+    case IPAddressChoice_inherit:
+      continue;
+    case IPAddressChoice_addressesOrRanges:
+      break;
+    default:
+      return 0;
+    }
+
+    /*
+     * It's an IPAddressOrRanges sequence, check it.
+     */
+    aors = f->ipAddressChoice->u.addressesOrRanges;
+    if (sk_IPAddressOrRange_num(aors) == 0)
+      return 0;
+    for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) {
+      IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
+      IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1);
+
+      if (!extract_min_max(a, a_min, a_max, length) ||
+	  !extract_min_max(b, b_min, b_max, length))
+	return 0;
+
+      /*
+       * Punt misordered list, overlapping start, or inverted range.
+       */
+      if (memcmp(a_min, b_min, length) >= 0 ||
+	  memcmp(a_min, a_max, length) > 0 ||
+	  memcmp(b_min, b_max, length) > 0)
+	return 0;
+
+      /*
+       * Punt if adjacent or overlapping.  Check for adjacency by
+       * subtracting one from b_min first.
+       */
+      for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--)
+	;
+      if (memcmp(a_max, b_min, length) >= 0)
+	return 0;
+
+      /*
+       * Check for range that should be expressed as a prefix.
+       */
+      if (a->type == IPAddressOrRange_addressRange &&
+	  range_should_be_prefix(a_min, a_max, length) >= 0)
+	return 0;
+    }
+
+    /*
+     * Check range to see if it's inverted or should be a
+     * prefix.
+     */
+    j = sk_IPAddressOrRange_num(aors) - 1;
+    {
+      IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
+      if (a != NULL && a->type == IPAddressOrRange_addressRange) {
+	if (!extract_min_max(a, a_min, a_max, length))
+	  return 0;
+	if (memcmp(a_min, a_max, length) > 0 ||
+	    range_should_be_prefix(a_min, a_max, length) >= 0)
+	  return 0;
+      }
+    }
+  }
+
+  /*
+   * If we made it through all that, we're happy.
+   */
+  return 1;
+}
+
+/*
+ * Whack an IPAddressOrRanges into canonical form.
+ */
+static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
+				      const unsigned afi)
+{
+  int i, j, length = length_from_afi(afi);
+
+  /*
+   * Sort the IPAddressOrRanges sequence.
+   */
+  sk_IPAddressOrRange_sort(aors);
+
+  /*
+   * Clean up representation issues, punt on duplicates or overlaps.
+   */
+  for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) {
+    IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i);
+    IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1);
+    unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
+    unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
+
+    if (!extract_min_max(a, a_min, a_max, length) ||
+	!extract_min_max(b, b_min, b_max, length))
+      return 0;
+
+    /*
+     * Punt inverted ranges.
+     */
+    if (memcmp(a_min, a_max, length) > 0 ||
+	memcmp(b_min, b_max, length) > 0)
+      return 0;
+
+    /*
+     * Punt overlaps.
+     */
+    if (memcmp(a_max, b_min, length) >= 0)
+      return 0;
+
+    /*
+     * Merge if a and b are adjacent.  We check for
+     * adjacency by subtracting one from b_min first.
+     */
+    for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--)
+      ;
+    if (memcmp(a_max, b_min, length) == 0) {
+      IPAddressOrRange *merged;
+      if (!make_addressRange(&merged, a_min, b_max, length))
+	return 0;
+      (void) sk_IPAddressOrRange_set(aors, i, merged);
+      (void) sk_IPAddressOrRange_delete(aors, i + 1);
+      IPAddressOrRange_free(a);
+      IPAddressOrRange_free(b);
+      --i;
+      continue;
+    }
+  }
+
+  /*
+   * Check for inverted final range.
+   */
+  j = sk_IPAddressOrRange_num(aors) - 1;
+  {
+    IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
+    if (a != NULL && a->type == IPAddressOrRange_addressRange) {
+      unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
+      extract_min_max(a, a_min, a_max, length);
+      if (memcmp(a_min, a_max, length) > 0)
+	return 0;
+    }
+  }
+
+  return 1;
+}
+
+/*
+ * Whack an IPAddrBlocks extension into canonical form.
+ */
+int v3_addr_canonize(IPAddrBlocks *addr)
+{
+  int i;
+  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+    if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
+	!IPAddressOrRanges_canonize(f->ipAddressChoice->u.addressesOrRanges,
+				    v3_addr_get_afi(f)))
+      return 0;
+  }
+  (void) sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp);
+  sk_IPAddressFamily_sort(addr);
+  OPENSSL_assert(v3_addr_is_canonical(addr));
+  return 1;
+}
+
+/*
+ * v2i handler for the IPAddrBlocks extension.
+ */
+static void *v2i_IPAddrBlocks(const struct v3_ext_method *method,
+			      struct v3_ext_ctx *ctx,
+			      STACK_OF(CONF_VALUE) *values)
+{
+  static const char v4addr_chars[] = "0123456789.";
+  static const char v6addr_chars[] = "0123456789.:abcdefABCDEF";
+  IPAddrBlocks *addr = NULL;
+  char *s = NULL, *t;
+  int i;
+  
+  if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) {
+    X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+    return NULL;
+  }
+
+  for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+    CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
+    unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN];
+    unsigned afi, *safi = NULL, safi_;
+    const char *addr_chars;
+    int prefixlen, i1, i2, delim, length;
+
+    if (       !name_cmp(val->name, "IPv4")) {
+      afi = IANA_AFI_IPV4;
+    } else if (!name_cmp(val->name, "IPv6")) {
+      afi = IANA_AFI_IPV6;
+    } else if (!name_cmp(val->name, "IPv4-SAFI")) {
+      afi = IANA_AFI_IPV4;
+      safi = &safi_;
+    } else if (!name_cmp(val->name, "IPv6-SAFI")) {
+      afi = IANA_AFI_IPV6;
+      safi = &safi_;
+    } else {
+      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_NAME_ERROR);
+      X509V3_conf_err(val);
+      goto err;
+    }
+
+    switch (afi) {
+    case IANA_AFI_IPV4:
+      addr_chars = v4addr_chars;
+      break;
+    case IANA_AFI_IPV6:
+      addr_chars = v6addr_chars;
+      break;
+    }
+
+    length = length_from_afi(afi);
+
+    /*
+     * Handle SAFI, if any, and BUF_strdup() so we can null-terminate
+     * the other input values.
+     */
+    if (safi != NULL) {
+      *safi = strtoul(val->value, &t, 0);
+      t += strspn(t, " \t");
+      if (*safi > 0xFF || *t++ != ':') {
+	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI);
+	X509V3_conf_err(val);
+	goto err;
+      }
+      t += strspn(t, " \t");
+      s = BUF_strdup(t);
+    } else {
+      s = BUF_strdup(val->value);
+    }
+    if (s == NULL) {
+      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+      goto err;
+    }
+
+    /*
+     * Check for inheritance.  Not worth additional complexity to
+     * optimize this (seldom-used) case.
+     */
+    if (!strcmp(s, "inherit")) {
+      if (!v3_addr_add_inherit(addr, afi, safi)) {
+	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_INHERITANCE);
+	X509V3_conf_err(val);
+	goto err;
+      }
+      OPENSSL_free(s);
+      s = NULL;
+      continue;
+    }
+
+    i1 = strspn(s, addr_chars);
+    i2 = i1 + strspn(s + i1, " \t");
+    delim = s[i2++];
+    s[i1] = '\0';
+
+    if (a2i_ipadd(min, s) != length) {
+      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
+      X509V3_conf_err(val);
+      goto err;
+    }
+
+    switch (delim) {
+    case '/':
+      prefixlen = (int) strtoul(s + i2, &t, 10);
+      if (t == s + i2 || *t != '\0') {
+	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
+	X509V3_conf_err(val);
+	goto err;
+      }
+      if (!v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) {
+	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+	goto err;
+      }
+      break;
+    case '-':
+      i1 = i2 + strspn(s + i2, " \t");
+      i2 = i1 + strspn(s + i1, addr_chars);
+      if (i1 == i2 || s[i2] != '\0') {
+	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
+	X509V3_conf_err(val);
+	goto err;
+      }
+      if (a2i_ipadd(max, s + i1) != length) {
+	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
+	X509V3_conf_err(val);
+	goto err;
+      }
+      if (memcmp(min, max, length_from_afi(afi)) > 0) {
+	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
+	X509V3_conf_err(val);
+	goto err;
+      }
+      if (!v3_addr_add_range(addr, afi, safi, min, max)) {
+	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+	goto err;
+      }
+      break;
+    case '\0':
+      if (!v3_addr_add_prefix(addr, afi, safi, min, length * 8)) {
+	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+	goto err;
+      }
+      break;
+    default:
+      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
+      X509V3_conf_err(val);
+      goto err;
+    }
+
+    OPENSSL_free(s);
+    s = NULL;
+  }
+
+  /*
+   * Canonize the result, then we're done.
+   */
+  if (!v3_addr_canonize(addr))
+    goto err;    
+  return addr;
+
+ err:
+  OPENSSL_free(s);
+  sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free);
+  return NULL;
+}
+
+/*
+ * OpenSSL dispatch
+ */
+const X509V3_EXT_METHOD v3_addr = {
+  NID_sbgp_ipAddrBlock,		/* nid */
+  0,				/* flags */
+  ASN1_ITEM_ref(IPAddrBlocks),	/* template */
+  0, 0, 0, 0,			/* old functions, ignored */
+  0,				/* i2s */
+  0,				/* s2i */
+  0,				/* i2v */
+  v2i_IPAddrBlocks,		/* v2i */
+  i2r_IPAddrBlocks,		/* i2r */
+  0,				/* r2i */
+  NULL				/* extension-specific data */
+};
+
+/*
+ * Figure out whether extension sues inheritance.
+ */
+int v3_addr_inherits(IPAddrBlocks *addr)
+{
+  int i;
+  if (addr == NULL)
+    return 0;
+  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+    if (f->ipAddressChoice->type == IPAddressChoice_inherit)
+      return 1;
+  }
+  return 0;
+}
+
+/*
+ * Figure out whether parent contains child.
+ */
+static int addr_contains(IPAddressOrRanges *parent,
+			 IPAddressOrRanges *child,
+			 int length)
+{
+  unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN];
+  unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN];
+  int p, c;
+
+  if (child == NULL || parent == child)
+    return 1;
+  if (parent == NULL)
+    return 0;
+
+  p = 0;
+  for (c = 0; c < sk_IPAddressOrRange_num(child); c++) {
+    if (!extract_min_max(sk_IPAddressOrRange_value(child, c),
+			 c_min, c_max, length))
+      return -1;
+    for (;; p++) {
+      if (p >= sk_IPAddressOrRange_num(parent))
+	return 0;
+      if (!extract_min_max(sk_IPAddressOrRange_value(parent, p),
+			   p_min, p_max, length))
+	return 0;
+      if (memcmp(p_max, c_max, length) < 0)
+	continue;
+      if (memcmp(p_min, c_min, length) > 0)
+	return 0;
+      break;
+    }
+  }
+
+  return 1;
+}
+
+/*
+ * Test whether a is a subset of b.
+ */
+int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b)
+{
+  int i;
+  if (a == NULL || a == b)
+    return 1;
+  if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b))
+    return 0;
+  (void) sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp);
+  for (i = 0; i < sk_IPAddressFamily_num(a); i++) {
+    IPAddressFamily *fa = sk_IPAddressFamily_value(a, i);
+    int j = sk_IPAddressFamily_find(b, fa);
+    IPAddressFamily *fb;
+    fb = sk_IPAddressFamily_value(b, j);
+    if (fb == NULL)
+       return 0;
+    if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges, 
+		       fa->ipAddressChoice->u.addressesOrRanges,
+		       length_from_afi(v3_addr_get_afi(fb))))
+      return 0;
+  }
+  return 1;
+}
+
+/*
+ * Validation error handling via callback.
+ */
+#define validation_err(_err_)		\
+  do {					\
+    if (ctx != NULL) {			\
+      ctx->error = _err_;		\
+      ctx->error_depth = i;		\
+      ctx->current_cert = x;		\
+      ret = ctx->verify_cb(0, ctx);	\
+    } else {				\
+      ret = 0;				\
+    }					\
+    if (!ret)				\
+      goto done;			\
+  } while (0)
+
+/*
+ * Core code for RFC 3779 2.3 path validation.
+ */
+static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx,
+					  STACK_OF(X509) *chain,
+					  IPAddrBlocks *ext)
+{
+  IPAddrBlocks *child = NULL;
+  int i, j, ret = 1;
+  X509 *x;
+
+  OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0);
+  OPENSSL_assert(ctx != NULL || ext != NULL);
+  OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL);
+
+  /*
+   * Figure out where to start.  If we don't have an extension to
+   * check, we're done.  Otherwise, check canonical form and
+   * set up for walking up the chain.
+   */
+  if (ext != NULL) {
+    i = -1;
+    x = NULL;
+  } else {
+    i = 0;
+    x = sk_X509_value(chain, i);
+    OPENSSL_assert(x != NULL);
+    if ((ext = x->rfc3779_addr) == NULL)
+      goto done;
+  }
+  if (!v3_addr_is_canonical(ext))
+    validation_err(X509_V_ERR_INVALID_EXTENSION);
+  (void) sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp);
+  if ((child = sk_IPAddressFamily_dup(ext)) == NULL) {
+    X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, ERR_R_MALLOC_FAILURE);
+    ret = 0;
+    goto done;
+  }
+
+  /*
+   * Now walk up the chain.  No cert may list resources that its
+   * parent doesn't list.
+   */
+  for (i++; i < sk_X509_num(chain); i++) {
+    x = sk_X509_value(chain, i);
+    OPENSSL_assert(x != NULL);
+    if (!v3_addr_is_canonical(x->rfc3779_addr))
+      validation_err(X509_V_ERR_INVALID_EXTENSION);
+    if (x->rfc3779_addr == NULL) {
+      for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
+	IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
+	if (fc->ipAddressChoice->type != IPAddressChoice_inherit) {
+	  validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+	  break;
+	}
+      }
+      continue;
+    }
+    (void) sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp);
+    for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
+      IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
+      int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc);
+      IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, k);
+      if (fp == NULL) {
+	if (fc->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) {
+	  validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+	  break;
+	}
+	continue;
+      }
+      if (fp->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) {
+	if (fc->ipAddressChoice->type == IPAddressChoice_inherit ||
+	    addr_contains(fp->ipAddressChoice->u.addressesOrRanges, 
+			  fc->ipAddressChoice->u.addressesOrRanges,
+			  length_from_afi(v3_addr_get_afi(fc))))
+	  sk_IPAddressFamily_set(child, j, fp);
+	else
+	  validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+      }
+    }
+  }
+
+  /*
+   * Trust anchor can't inherit.
+   */
+  OPENSSL_assert(x != NULL);
+  if (x->rfc3779_addr != NULL) {
+    for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) {
+      IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, j);
+      if (fp->ipAddressChoice->type == IPAddressChoice_inherit &&
+	  sk_IPAddressFamily_find(child, fp) >= 0)
+	validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+    }
+  }
+
+ done:
+  sk_IPAddressFamily_free(child);
+  return ret;
+}
+
+#undef validation_err
+
+/*
+ * RFC 3779 2.3 path validation -- called from X509_verify_cert().
+ */
+int v3_addr_validate_path(X509_STORE_CTX *ctx)
+{
+  return v3_addr_validate_path_internal(ctx, ctx->chain, NULL);
+}
+
+/*
+ * RFC 3779 2.3 path validation of an extension.
+ * Test whether chain covers extension.
+ */
+int v3_addr_validate_resource_set(STACK_OF(X509) *chain,
+				  IPAddrBlocks *ext,
+				  int allow_inheritance)
+{
+  if (ext == NULL)
+    return 1;
+  if (chain == NULL || sk_X509_num(chain) == 0)
+    return 0;
+  if (!allow_inheritance && v3_addr_inherits(ext))
+    return 0;
+  return v3_addr_validate_path_internal(NULL, chain, ext);
+}
+
+#endif /* OPENSSL_NO_RFC3779 */
diff --git a/openssl/crypto/x509v3/v3_akey.c b/openssl/crypto/x509v3/v3_akey.c
new file mode 100644
index 0000000..c6b68ee
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_akey.c
@@ -0,0 +1,208 @@
+/* v3_akey.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
+			AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist);
+static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
+			X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
+
+const X509V3_EXT_METHOD v3_akey_id =
+	{
+	NID_authority_key_identifier,
+	X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID),
+	0,0,0,0,
+	0,0,
+	(X509V3_EXT_I2V)i2v_AUTHORITY_KEYID,
+	(X509V3_EXT_V2I)v2i_AUTHORITY_KEYID,
+	0,0,
+	NULL
+	};
+
+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
+	     AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist)
+{
+	char *tmp;
+	if(akeyid->keyid) {
+		tmp = hex_to_string(akeyid->keyid->data, akeyid->keyid->length);
+		X509V3_add_value("keyid", tmp, &extlist);
+		OPENSSL_free(tmp);
+	}
+	if(akeyid->issuer) 
+		extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist);
+	if(akeyid->serial) {
+		tmp = hex_to_string(akeyid->serial->data,
+						 akeyid->serial->length);
+		X509V3_add_value("serial", tmp, &extlist);
+		OPENSSL_free(tmp);
+	}
+	return extlist;
+}
+
+/* Currently two options:
+ * keyid: use the issuers subject keyid, the value 'always' means its is
+ * an error if the issuer certificate doesn't have a key id.
+ * issuer: use the issuers cert issuer and serial number. The default is
+ * to only use this if keyid is not present. With the option 'always'
+ * this is always included.
+ */
+
+static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
+	     X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values)
+	{
+	char keyid=0, issuer=0;
+	int i;
+	CONF_VALUE *cnf;
+	ASN1_OCTET_STRING *ikeyid = NULL;
+	X509_NAME *isname = NULL;
+	GENERAL_NAMES * gens = NULL;
+	GENERAL_NAME *gen = NULL;
+	ASN1_INTEGER *serial = NULL;
+	X509_EXTENSION *ext;
+	X509 *cert;
+	AUTHORITY_KEYID *akeyid;
+
+	for(i = 0; i < sk_CONF_VALUE_num(values); i++)
+		{
+		cnf = sk_CONF_VALUE_value(values, i);
+		if(!strcmp(cnf->name, "keyid"))
+			{
+			keyid = 1;
+			if(cnf->value && !strcmp(cnf->value, "always"))
+				keyid = 2;
+			}
+		else if(!strcmp(cnf->name, "issuer"))
+			{
+			issuer = 1;
+			if(cnf->value && !strcmp(cnf->value, "always"))
+				issuer = 2;
+			}
+		else
+			{
+			X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_UNKNOWN_OPTION);
+			ERR_add_error_data(2, "name=", cnf->name);
+			return NULL;
+			}
+		}
+
+	if(!ctx || !ctx->issuer_cert)
+		{
+		if(ctx && (ctx->flags==CTX_TEST))
+			return AUTHORITY_KEYID_new();
+		X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_NO_ISSUER_CERTIFICATE);
+		return NULL;
+		}
+
+	cert = ctx->issuer_cert;
+
+	if(keyid)
+		{
+		i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1);
+		if((i >= 0)  && (ext = X509_get_ext(cert, i)))
+			ikeyid = X509V3_EXT_d2i(ext);
+		if(keyid==2 && !ikeyid)
+			{
+			X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
+			return NULL;
+			}
+		}
+
+	if((issuer && !ikeyid) || (issuer == 2))
+		{
+		isname = X509_NAME_dup(X509_get_issuer_name(cert));
+		serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
+		if(!isname || !serial)
+			{
+			X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
+			goto err;
+			}
+		}
+
+	if(!(akeyid = AUTHORITY_KEYID_new())) goto err;
+
+	if(isname)
+		{
+		if(!(gens = sk_GENERAL_NAME_new_null())
+			|| !(gen = GENERAL_NAME_new())
+			|| !sk_GENERAL_NAME_push(gens, gen))
+			{
+			X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		gen->type = GEN_DIRNAME;
+		gen->d.dirn = isname;
+		}
+
+	akeyid->issuer = gens;
+	akeyid->serial = serial;
+	akeyid->keyid = ikeyid;
+
+	return akeyid;
+
+ err:
+	X509_NAME_free(isname);
+	M_ASN1_INTEGER_free(serial);
+	M_ASN1_OCTET_STRING_free(ikeyid);
+	return NULL;
+	}
diff --git a/openssl/crypto/x509v3/v3_akeya.c b/openssl/crypto/x509v3/v3_akeya.c
new file mode 100644
index 0000000..2c50f73
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_akeya.c
@@ -0,0 +1,72 @@
+/* v3_akey_asn1.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+ASN1_SEQUENCE(AUTHORITY_KEYID) = {
+	ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0),
+	ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1),
+	ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2)
+} ASN1_SEQUENCE_END(AUTHORITY_KEYID)
+
+IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_KEYID)
diff --git a/openssl/crypto/x509v3/v3_alt.c b/openssl/crypto/x509v3/v3_alt.c
new file mode 100644
index 0000000..d29d943
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_alt.c
@@ -0,0 +1,614 @@
+/* v3_alt.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
+static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
+static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
+static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
+
+const X509V3_EXT_METHOD v3_alt[] = {
+{ NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
+0,0,0,0,
+0,0,
+(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
+(X509V3_EXT_V2I)v2i_subject_alt,
+NULL, NULL, NULL},
+
+{ NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
+0,0,0,0,
+0,0,
+(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
+(X509V3_EXT_V2I)v2i_issuer_alt,
+NULL, NULL, NULL},
+
+{ NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES),
+0,0,0,0,
+0,0,
+(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
+NULL, NULL, NULL, NULL},
+};
+
+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
+		GENERAL_NAMES *gens, STACK_OF(CONF_VALUE) *ret)
+{
+	int i;
+	GENERAL_NAME *gen;
+	for(i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+		gen = sk_GENERAL_NAME_value(gens, i);
+		ret = i2v_GENERAL_NAME(method, gen, ret);
+	}
+	if(!ret) return sk_CONF_VALUE_new_null();
+	return ret;
+}
+
+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
+				GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret)
+{
+	unsigned char *p;
+	char oline[256], htmp[5];
+	int i;
+	switch (gen->type)
+	{
+		case GEN_OTHERNAME:
+		X509V3_add_value("othername","<unsupported>", &ret);
+		break;
+
+		case GEN_X400:
+		X509V3_add_value("X400Name","<unsupported>", &ret);
+		break;
+
+		case GEN_EDIPARTY:
+		X509V3_add_value("EdiPartyName","<unsupported>", &ret);
+		break;
+
+		case GEN_EMAIL:
+		X509V3_add_value_uchar("email",gen->d.ia5->data, &ret);
+		break;
+
+		case GEN_DNS:
+		X509V3_add_value_uchar("DNS",gen->d.ia5->data, &ret);
+		break;
+
+		case GEN_URI:
+		X509V3_add_value_uchar("URI",gen->d.ia5->data, &ret);
+		break;
+
+		case GEN_DIRNAME:
+		X509_NAME_oneline(gen->d.dirn, oline, 256);
+		X509V3_add_value("DirName",oline, &ret);
+		break;
+
+		case GEN_IPADD:
+		p = gen->d.ip->data;
+		if(gen->d.ip->length == 4)
+			BIO_snprintf(oline, sizeof oline,
+				     "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+		else if(gen->d.ip->length == 16)
+			{
+			oline[0] = 0;
+			for (i = 0; i < 8; i++)
+				{
+				BIO_snprintf(htmp, sizeof htmp,
+					     "%X", p[0] << 8 | p[1]);
+				p += 2;
+				strcat(oline, htmp);
+				if (i != 7)
+					strcat(oline, ":");
+				}
+			}
+		else
+			{
+			X509V3_add_value("IP Address","<invalid>", &ret);
+			break;
+			}
+		X509V3_add_value("IP Address",oline, &ret);
+		break;
+
+		case GEN_RID:
+		i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
+		X509V3_add_value("Registered ID",oline, &ret);
+		break;
+	}
+	return ret;
+}
+
+int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
+{
+	unsigned char *p;
+	int i;
+	switch (gen->type)
+	{
+		case GEN_OTHERNAME:
+		BIO_printf(out, "othername:<unsupported>");
+		break;
+
+		case GEN_X400:
+		BIO_printf(out, "X400Name:<unsupported>");
+		break;
+
+		case GEN_EDIPARTY:
+		/* Maybe fix this: it is supported now */
+		BIO_printf(out, "EdiPartyName:<unsupported>");
+		break;
+
+		case GEN_EMAIL:
+		BIO_printf(out, "email:%s",gen->d.ia5->data);
+		break;
+
+		case GEN_DNS:
+		BIO_printf(out, "DNS:%s",gen->d.ia5->data);
+		break;
+
+		case GEN_URI:
+		BIO_printf(out, "URI:%s",gen->d.ia5->data);
+		break;
+
+		case GEN_DIRNAME:
+		BIO_printf(out, "DirName: ");
+		X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
+		break;
+
+		case GEN_IPADD:
+		p = gen->d.ip->data;
+		if(gen->d.ip->length == 4)
+			BIO_printf(out, "IP Address:%d.%d.%d.%d",
+						p[0], p[1], p[2], p[3]);
+		else if(gen->d.ip->length == 16)
+			{
+			BIO_printf(out, "IP Address");
+			for (i = 0; i < 8; i++)
+				{
+				BIO_printf(out, ":%X", p[0] << 8 | p[1]);
+				p += 2;
+				}
+			BIO_puts(out, "\n");
+			}
+		else
+			{
+			BIO_printf(out,"IP Address:<invalid>");
+			break;
+			}
+		break;
+
+		case GEN_RID:
+		BIO_printf(out, "Registered ID");
+		i2a_ASN1_OBJECT(out, gen->d.rid);
+		break;
+	}
+	return 1;
+}
+
+static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
+				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+	GENERAL_NAMES *gens = NULL;
+	CONF_VALUE *cnf;
+	int i;
+	if(!(gens = sk_GENERAL_NAME_new_null())) {
+		X509V3err(X509V3_F_V2I_ISSUER_ALT,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+		cnf = sk_CONF_VALUE_value(nval, i);
+		if(!name_cmp(cnf->name, "issuer") && cnf->value &&
+						!strcmp(cnf->value, "copy")) {
+			if(!copy_issuer(ctx, gens)) goto err;
+		} else {
+			GENERAL_NAME *gen;
+			if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+								 goto err; 
+			sk_GENERAL_NAME_push(gens, gen);
+		}
+	}
+	return gens;
+	err:
+	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+	return NULL;
+}
+
+/* Append subject altname of issuer to issuer alt name of subject */
+
+static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
+{
+	GENERAL_NAMES *ialt;
+	GENERAL_NAME *gen;
+	X509_EXTENSION *ext;
+	int i;
+	if(ctx && (ctx->flags == CTX_TEST)) return 1;
+	if(!ctx || !ctx->issuer_cert) {
+		X509V3err(X509V3_F_COPY_ISSUER,X509V3_R_NO_ISSUER_DETAILS);
+		goto err;
+	}
+        i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
+	if(i < 0) return 1;
+        if(!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
+                        !(ialt = X509V3_EXT_d2i(ext)) ) {
+		X509V3err(X509V3_F_COPY_ISSUER,X509V3_R_ISSUER_DECODE_ERROR);
+		goto err;
+	}
+
+	for(i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
+		gen = sk_GENERAL_NAME_value(ialt, i);
+		if(!sk_GENERAL_NAME_push(gens, gen)) {
+			X509V3err(X509V3_F_COPY_ISSUER,ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+	}
+	sk_GENERAL_NAME_free(ialt);
+
+	return 1;
+		
+	err:
+	return 0;
+	
+}
+
+static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
+				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+	GENERAL_NAMES *gens = NULL;
+	CONF_VALUE *cnf;
+	int i;
+	if(!(gens = sk_GENERAL_NAME_new_null())) {
+		X509V3err(X509V3_F_V2I_SUBJECT_ALT,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+		cnf = sk_CONF_VALUE_value(nval, i);
+		if(!name_cmp(cnf->name, "email") && cnf->value &&
+						!strcmp(cnf->value, "copy")) {
+			if(!copy_email(ctx, gens, 0)) goto err;
+		} else if(!name_cmp(cnf->name, "email") && cnf->value &&
+						!strcmp(cnf->value, "move")) {
+			if(!copy_email(ctx, gens, 1)) goto err;
+		} else {
+			GENERAL_NAME *gen;
+			if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+								 goto err; 
+			sk_GENERAL_NAME_push(gens, gen);
+		}
+	}
+	return gens;
+	err:
+	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+	return NULL;
+}
+
+/* Copy any email addresses in a certificate or request to 
+ * GENERAL_NAMES
+ */
+
+static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
+{
+	X509_NAME *nm;
+	ASN1_IA5STRING *email = NULL;
+	X509_NAME_ENTRY *ne;
+	GENERAL_NAME *gen = NULL;
+	int i;
+	if(ctx != NULL && ctx->flags == CTX_TEST)
+		return 1;
+	if(!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
+		X509V3err(X509V3_F_COPY_EMAIL,X509V3_R_NO_SUBJECT_DETAILS);
+		goto err;
+	}
+	/* Find the subject name */
+	if(ctx->subject_cert) nm = X509_get_subject_name(ctx->subject_cert);
+	else nm = X509_REQ_get_subject_name(ctx->subject_req);
+
+	/* Now add any email address(es) to STACK */
+	i = -1;
+	while((i = X509_NAME_get_index_by_NID(nm,
+					 NID_pkcs9_emailAddress, i)) >= 0) {
+		ne = X509_NAME_get_entry(nm, i);
+		email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne));
+                if (move_p)
+                        {
+                        X509_NAME_delete_entry(nm, i);
+			X509_NAME_ENTRY_free(ne);
+                        i--;
+                        }
+		if(!email || !(gen = GENERAL_NAME_new())) {
+			X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		gen->d.ia5 = email;
+		email = NULL;
+		gen->type = GEN_EMAIL;
+		if(!sk_GENERAL_NAME_push(gens, gen)) {
+			X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		gen = NULL;
+	}
+
+	
+	return 1;
+		
+	err:
+	GENERAL_NAME_free(gen);
+	M_ASN1_IA5STRING_free(email);
+	return 0;
+	
+}
+
+GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
+				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+	GENERAL_NAME *gen;
+	GENERAL_NAMES *gens = NULL;
+	CONF_VALUE *cnf;
+	int i;
+	if(!(gens = sk_GENERAL_NAME_new_null())) {
+		X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+		cnf = sk_CONF_VALUE_value(nval, i);
+		if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) goto err; 
+		sk_GENERAL_NAME_push(gens, gen);
+	}
+	return gens;
+	err:
+	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+	return NULL;
+}
+
+GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+			       CONF_VALUE *cnf)
+	{
+	return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
+	}
+
+GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
+			       const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+			       int gen_type, char *value, int is_nc)
+	{
+	char is_string = 0;
+	GENERAL_NAME *gen = NULL;
+
+	if(!value)
+		{
+		X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_MISSING_VALUE);
+		return NULL;
+		}
+
+	if (out)
+		gen = out;
+	else
+		{
+		gen = GENERAL_NAME_new();
+		if(gen == NULL)
+			{
+			X509V3err(X509V3_F_A2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE);
+			return NULL;
+			}
+		}
+
+	switch (gen_type)
+		{
+		case GEN_URI:
+		case GEN_EMAIL:
+		case GEN_DNS:
+		is_string = 1;
+		break;
+		
+		case GEN_RID:
+		{
+		ASN1_OBJECT *obj;
+		if(!(obj = OBJ_txt2obj(value,0)))
+			{
+			X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_BAD_OBJECT);
+			ERR_add_error_data(2, "value=", value);
+			goto err;
+			}
+		gen->d.rid = obj;
+		}
+		break;
+
+		case GEN_IPADD:
+		if (is_nc)
+			gen->d.ip = a2i_IPADDRESS_NC(value);
+		else
+			gen->d.ip = a2i_IPADDRESS(value);
+		if(gen->d.ip == NULL)
+			{
+			X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_BAD_IP_ADDRESS);
+			ERR_add_error_data(2, "value=", value);
+			goto err;
+			}
+		break;
+
+		case GEN_DIRNAME:
+		if (!do_dirname(gen, value, ctx))
+			{
+			X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_DIRNAME_ERROR);
+			goto err;
+			}
+		break;
+
+		case GEN_OTHERNAME:
+		if (!do_othername(gen, value, ctx))
+			{
+			X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_OTHERNAME_ERROR);
+			goto err;
+			}
+		break;
+		default:
+		X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_UNSUPPORTED_TYPE);
+		goto err;
+		}
+
+	if(is_string)
+		{
+		if(!(gen->d.ia5 = M_ASN1_IA5STRING_new()) ||
+			      !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value,
+					       strlen(value)))
+			{
+			X509V3err(X509V3_F_A2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+
+	gen->type = gen_type;
+
+	return gen;
+
+	err:
+	if (!out)
+		GENERAL_NAME_free(gen);
+	return NULL;
+	}
+
+GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
+				  const X509V3_EXT_METHOD *method,
+				  X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
+	{
+	int type;
+
+	char *name, *value;
+
+	name = cnf->name;
+	value = cnf->value;
+
+	if(!value)
+		{
+		X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_MISSING_VALUE);
+		return NULL;
+		}
+
+	if(!name_cmp(name, "email"))
+		type = GEN_EMAIL;
+	else if(!name_cmp(name, "URI"))
+		type = GEN_URI;
+	else if(!name_cmp(name, "DNS"))
+		type = GEN_DNS;
+	else if(!name_cmp(name, "RID"))
+		type = GEN_RID;
+	else if(!name_cmp(name, "IP"))
+		type = GEN_IPADD;
+	else if(!name_cmp(name, "dirName"))
+		type = GEN_DIRNAME;
+	else if(!name_cmp(name, "otherName"))
+		type = GEN_OTHERNAME;
+	else
+		{
+		X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_UNSUPPORTED_OPTION);
+		ERR_add_error_data(2, "name=", name);
+		return NULL;
+		}
+
+	return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
+
+	}
+
+static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
+	{
+	char *objtmp = NULL, *p;
+	int objlen;
+	if (!(p = strchr(value, ';')))
+		return 0;
+	if (!(gen->d.otherName = OTHERNAME_new()))
+		return 0;
+	/* Free this up because we will overwrite it.
+	 * no need to free type_id because it is static
+	 */
+	ASN1_TYPE_free(gen->d.otherName->value);
+	if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)))
+		return 0;
+	objlen = p - value;
+	objtmp = OPENSSL_malloc(objlen + 1);
+	strncpy(objtmp, value, objlen);
+	objtmp[objlen] = 0;
+	gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
+	OPENSSL_free(objtmp);	
+	if (!gen->d.otherName->type_id)
+		return 0;
+	return 1;
+	}
+
+static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
+	{
+	int ret;
+	STACK_OF(CONF_VALUE) *sk;
+	X509_NAME *nm;
+	if (!(nm = X509_NAME_new()))
+		return 0;
+	sk = X509V3_get_section(ctx, value);
+	if (!sk)
+		{
+		X509V3err(X509V3_F_DO_DIRNAME,X509V3_R_SECTION_NOT_FOUND);
+		ERR_add_error_data(2, "section=", value);
+		X509_NAME_free(nm);
+		return 0;
+		}
+	/* FIXME: should allow other character types... */
+	ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC);
+	if (!ret)
+		X509_NAME_free(nm);
+	gen->d.dirn = nm;
+	X509V3_section_free(ctx, sk);
+		
+	return ret;
+	}
diff --git a/openssl/crypto/x509v3/v3_asid.c b/openssl/crypto/x509v3/v3_asid.c
new file mode 100644
index 0000000..3f434c0
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_asid.c
@@ -0,0 +1,843 @@
+/*
+ * Contributed to the OpenSSL Project by the American Registry for
+ * Internet Numbers ("ARIN").
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ */
+
+/*
+ * Implementation of RFC 3779 section 3.2.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+#include <openssl/x509.h>
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_RFC3779
+
+/*
+ * OpenSSL ASN.1 template translation of RFC 3779 3.2.3.
+ */
+
+ASN1_SEQUENCE(ASRange) = {
+  ASN1_SIMPLE(ASRange, min, ASN1_INTEGER),
+  ASN1_SIMPLE(ASRange, max, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(ASRange)
+
+ASN1_CHOICE(ASIdOrRange) = {
+  ASN1_SIMPLE(ASIdOrRange, u.id,    ASN1_INTEGER),
+  ASN1_SIMPLE(ASIdOrRange, u.range, ASRange)
+} ASN1_CHOICE_END(ASIdOrRange)
+
+ASN1_CHOICE(ASIdentifierChoice) = {
+  ASN1_SIMPLE(ASIdentifierChoice,      u.inherit,       ASN1_NULL),
+  ASN1_SEQUENCE_OF(ASIdentifierChoice, u.asIdsOrRanges, ASIdOrRange)
+} ASN1_CHOICE_END(ASIdentifierChoice)
+
+ASN1_SEQUENCE(ASIdentifiers) = {
+  ASN1_EXP_OPT(ASIdentifiers, asnum, ASIdentifierChoice, 0),
+  ASN1_EXP_OPT(ASIdentifiers, rdi,   ASIdentifierChoice, 1)
+} ASN1_SEQUENCE_END(ASIdentifiers)
+
+IMPLEMENT_ASN1_FUNCTIONS(ASRange)
+IMPLEMENT_ASN1_FUNCTIONS(ASIdOrRange)
+IMPLEMENT_ASN1_FUNCTIONS(ASIdentifierChoice)
+IMPLEMENT_ASN1_FUNCTIONS(ASIdentifiers)
+
+/*
+ * i2r method for an ASIdentifierChoice.
+ */
+static int i2r_ASIdentifierChoice(BIO *out,
+				  ASIdentifierChoice *choice,
+				  int indent,
+				  const char *msg)
+{
+  int i;
+  char *s;
+  if (choice == NULL)
+    return 1;
+  BIO_printf(out, "%*s%s:\n", indent, "", msg);
+  switch (choice->type) {
+  case ASIdentifierChoice_inherit:
+    BIO_printf(out, "%*sinherit\n", indent + 2, "");
+    break;
+  case ASIdentifierChoice_asIdsOrRanges:
+    for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); i++) {
+      ASIdOrRange *aor = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+      switch (aor->type) {
+      case ASIdOrRange_id:
+	if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == NULL)
+	  return 0;
+	BIO_printf(out, "%*s%s\n", indent + 2, "", s);
+	OPENSSL_free(s);
+	break;
+      case ASIdOrRange_range:
+	if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->min)) == NULL)
+	  return 0;
+	BIO_printf(out, "%*s%s-", indent + 2, "", s);
+	OPENSSL_free(s);
+	if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->max)) == NULL)
+	  return 0;
+	BIO_printf(out, "%s\n", s);
+	OPENSSL_free(s);
+	break;
+      default:
+	return 0;
+      }
+    }
+    break;
+  default:
+    return 0;
+  }
+  return 1;
+}
+
+/*
+ * i2r method for an ASIdentifier extension.
+ */
+static int i2r_ASIdentifiers(const X509V3_EXT_METHOD *method,
+			     void *ext,
+			     BIO *out,
+			     int indent)
+{
+  ASIdentifiers *asid = ext;
+  return (i2r_ASIdentifierChoice(out, asid->asnum, indent,
+				 "Autonomous System Numbers") &&
+	  i2r_ASIdentifierChoice(out, asid->rdi, indent,
+				 "Routing Domain Identifiers"));
+}
+
+/*
+ * Sort comparision function for a sequence of ASIdOrRange elements.
+ */
+static int ASIdOrRange_cmp(const ASIdOrRange * const *a_,
+			   const ASIdOrRange * const *b_)
+{
+  const ASIdOrRange *a = *a_, *b = *b_;
+
+  OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) ||
+	 (a->type == ASIdOrRange_range && a->u.range != NULL &&
+	  a->u.range->min != NULL && a->u.range->max != NULL));
+
+  OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) ||
+	 (b->type == ASIdOrRange_range && b->u.range != NULL &&
+	  b->u.range->min != NULL && b->u.range->max != NULL));
+
+  if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id)
+    return ASN1_INTEGER_cmp(a->u.id, b->u.id);
+
+  if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) {
+    int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min);
+    return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max, b->u.range->max);
+  }
+
+  if (a->type == ASIdOrRange_id)
+    return ASN1_INTEGER_cmp(a->u.id, b->u.range->min);
+  else
+    return ASN1_INTEGER_cmp(a->u.range->min, b->u.id);
+}
+
+/*
+ * Add an inherit element.
+ */
+int v3_asid_add_inherit(ASIdentifiers *asid, int which)
+{
+  ASIdentifierChoice **choice;
+  if (asid == NULL)
+    return 0;
+  switch (which) {
+  case V3_ASID_ASNUM:
+    choice = &asid->asnum;
+    break;
+  case V3_ASID_RDI:
+    choice = &asid->rdi;
+    break;
+  default:
+    return 0;
+  }
+  if (*choice == NULL) {
+    if ((*choice = ASIdentifierChoice_new()) == NULL)
+      return 0;
+    OPENSSL_assert((*choice)->u.inherit == NULL);
+    if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL)
+      return 0;
+    (*choice)->type = ASIdentifierChoice_inherit;
+  }
+  return (*choice)->type == ASIdentifierChoice_inherit;
+}
+
+/*
+ * Add an ID or range to an ASIdentifierChoice.
+ */
+int v3_asid_add_id_or_range(ASIdentifiers *asid,
+			    int which,
+			    ASN1_INTEGER *min,
+			    ASN1_INTEGER *max)
+{
+  ASIdentifierChoice **choice;
+  ASIdOrRange *aor;
+  if (asid == NULL)
+    return 0;
+  switch (which) {
+  case V3_ASID_ASNUM:
+    choice = &asid->asnum;
+    break;
+  case V3_ASID_RDI:
+    choice = &asid->rdi;
+    break;
+  default:
+    return 0;
+  }
+  if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit)
+    return 0;
+  if (*choice == NULL) {
+    if ((*choice = ASIdentifierChoice_new()) == NULL)
+      return 0;
+    OPENSSL_assert((*choice)->u.asIdsOrRanges == NULL);
+    (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp);
+    if ((*choice)->u.asIdsOrRanges == NULL)
+      return 0;
+    (*choice)->type = ASIdentifierChoice_asIdsOrRanges;
+  }
+  if ((aor = ASIdOrRange_new()) == NULL)
+    return 0;
+  if (max == NULL) {
+    aor->type = ASIdOrRange_id;
+    aor->u.id = min;
+  } else {
+    aor->type = ASIdOrRange_range;
+    if ((aor->u.range = ASRange_new()) == NULL)
+      goto err;
+    ASN1_INTEGER_free(aor->u.range->min);
+    aor->u.range->min = min;
+    ASN1_INTEGER_free(aor->u.range->max);
+    aor->u.range->max = max;
+  }
+  if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor)))
+    goto err;
+  return 1;
+
+ err:
+  ASIdOrRange_free(aor);
+  return 0;
+}
+
+/*
+ * Extract min and max values from an ASIdOrRange.
+ */
+static void extract_min_max(ASIdOrRange *aor,
+			    ASN1_INTEGER **min,
+			    ASN1_INTEGER **max)
+{
+  OPENSSL_assert(aor != NULL && min != NULL && max != NULL);
+  switch (aor->type) {
+  case ASIdOrRange_id:
+    *min = aor->u.id;
+    *max = aor->u.id;
+    return;
+  case ASIdOrRange_range:
+    *min = aor->u.range->min;
+    *max = aor->u.range->max;
+    return;
+  }
+}
+
+/*
+ * Check whether an ASIdentifierChoice is in canonical form.
+ */
+static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice)
+{
+  ASN1_INTEGER *a_max_plus_one = NULL;
+  BIGNUM *bn = NULL;
+  int i, ret = 0;
+
+  /*
+   * Empty element or inheritance is canonical.
+   */
+  if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
+    return 1;
+
+  /*
+   * If not a list, or if empty list, it's broken.
+   */
+  if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
+      sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0)
+    return 0;
+
+  /*
+   * It's a list, check it.
+   */
+  for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
+    ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+    ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
+    ASN1_INTEGER *a_min, *a_max, *b_min, *b_max;
+
+    extract_min_max(a, &a_min, &a_max);
+    extract_min_max(b, &b_min, &b_max);
+
+    /*
+     * Punt misordered list, overlapping start, or inverted range.
+     */
+    if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 ||
+	ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
+	ASN1_INTEGER_cmp(b_min, b_max) > 0)
+      goto done;
+
+    /*
+     * Calculate a_max + 1 to check for adjacency.
+     */
+    if ((bn == NULL && (bn = BN_new()) == NULL) ||
+	ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
+	!BN_add_word(bn, 1) ||
+	(a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
+      X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL,
+		ERR_R_MALLOC_FAILURE);
+      goto done;
+    }
+    
+    /*
+     * Punt if adjacent or overlapping.
+     */
+    if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0)
+      goto done;
+  }
+
+  ret = 1;
+
+ done:
+  ASN1_INTEGER_free(a_max_plus_one);
+  BN_free(bn);
+  return ret;
+}
+
+/*
+ * Check whether an ASIdentifier extension is in canonical form.
+ */
+int v3_asid_is_canonical(ASIdentifiers *asid)
+{
+  return (asid == NULL ||
+	  (ASIdentifierChoice_is_canonical(asid->asnum) &&
+	   ASIdentifierChoice_is_canonical(asid->rdi)));
+}
+
+/*
+ * Whack an ASIdentifierChoice into canonical form.
+ */
+static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
+{
+  ASN1_INTEGER *a_max_plus_one = NULL;
+  BIGNUM *bn = NULL;
+  int i, ret = 0;
+
+  /*
+   * Nothing to do for empty element or inheritance.
+   */
+  if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
+    return 1;
+
+  /*
+   * We have a list.  Sort it.
+   */
+  OPENSSL_assert(choice->type == ASIdentifierChoice_asIdsOrRanges);
+  sk_ASIdOrRange_sort(choice->u.asIdsOrRanges);
+
+  /*
+   * Now check for errors and suboptimal encoding, rejecting the
+   * former and fixing the latter.
+   */
+  for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
+    ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+    ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
+    ASN1_INTEGER *a_min, *a_max, *b_min, *b_max;
+
+    extract_min_max(a, &a_min, &a_max);
+    extract_min_max(b, &b_min, &b_max);
+
+    /*
+     * Make sure we're properly sorted (paranoia).
+     */
+    OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0);
+
+    /*
+     * Check for overlaps.
+     */
+    if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) {
+      X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
+		X509V3_R_EXTENSION_VALUE_ERROR);
+      goto done;
+    }
+
+    /*
+     * Calculate a_max + 1 to check for adjacency.
+     */
+    if ((bn == NULL && (bn = BN_new()) == NULL) ||
+	ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
+	!BN_add_word(bn, 1) ||
+	(a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
+      X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, ERR_R_MALLOC_FAILURE);
+      goto done;
+    }
+    
+    /*
+     * If a and b are adjacent, merge them.
+     */
+    if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) {
+      ASRange *r;
+      switch (a->type) {
+      case ASIdOrRange_id:
+	if ((r = OPENSSL_malloc(sizeof(ASRange))) == NULL) {
+	  X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
+		    ERR_R_MALLOC_FAILURE);
+	  goto done;
+	}
+	r->min = a_min;
+	r->max = b_max;
+	a->type = ASIdOrRange_range;
+	a->u.range = r;
+	break;
+      case ASIdOrRange_range:
+	ASN1_INTEGER_free(a->u.range->max);
+	a->u.range->max = b_max;
+	break;
+      }
+      switch (b->type) {
+      case ASIdOrRange_id:
+	b->u.id = NULL;
+	break;
+      case ASIdOrRange_range:
+	b->u.range->max = NULL;
+	break;
+      }
+      ASIdOrRange_free(b);
+      sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
+      i--;
+      continue;
+    }
+  }
+
+  OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */
+
+  ret = 1;
+
+ done:
+  ASN1_INTEGER_free(a_max_plus_one);
+  BN_free(bn);
+  return ret;
+}
+
+/*
+ * Whack an ASIdentifier extension into canonical form.
+ */
+int v3_asid_canonize(ASIdentifiers *asid)
+{
+  return (asid == NULL ||
+	  (ASIdentifierChoice_canonize(asid->asnum) &&
+	   ASIdentifierChoice_canonize(asid->rdi)));
+}
+
+/*
+ * v2i method for an ASIdentifier extension.
+ */
+static void *v2i_ASIdentifiers(const struct v3_ext_method *method,
+			       struct v3_ext_ctx *ctx,
+			       STACK_OF(CONF_VALUE) *values)
+{
+  ASIdentifiers *asid = NULL;
+  int i;
+
+  if ((asid = ASIdentifiers_new()) == NULL) {
+    X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+    return NULL;
+  }
+
+  for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+    CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
+    ASN1_INTEGER *min = NULL, *max = NULL;
+    int i1, i2, i3, is_range, which;
+
+    /*
+     * Figure out whether this is an AS or an RDI.
+     */
+    if (       !name_cmp(val->name, "AS")) {
+      which = V3_ASID_ASNUM;
+    } else if (!name_cmp(val->name, "RDI")) {
+      which = V3_ASID_RDI;
+    } else {
+      X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_EXTENSION_NAME_ERROR);
+      X509V3_conf_err(val);
+      goto err;
+    }
+
+    /*
+     * Handle inheritance.
+     */
+    if (!strcmp(val->value, "inherit")) {
+      if (v3_asid_add_inherit(asid, which))
+	continue;
+      X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_INHERITANCE);
+      X509V3_conf_err(val);
+      goto err;
+    }
+
+    /*
+     * Number, range, or mistake, pick it apart and figure out which.
+     */
+    i1 = strspn(val->value, "0123456789");
+    if (val->value[i1] == '\0') {
+      is_range = 0;
+    } else {
+      is_range = 1;
+      i2 = i1 + strspn(val->value + i1, " \t");
+      if (val->value[i2] != '-') {
+	X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASNUMBER);
+	X509V3_conf_err(val);
+	goto err;
+      }
+      i2++;
+      i2 = i2 + strspn(val->value + i2, " \t");
+      i3 = i2 + strspn(val->value + i2, "0123456789");
+      if (val->value[i3] != '\0') {
+	X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASRANGE);
+	X509V3_conf_err(val);
+	goto err;
+      }
+    }
+
+    /*
+     * Syntax is ok, read and add it.
+     */
+    if (!is_range) {
+      if (!X509V3_get_value_int(val, &min)) {
+	X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+	goto err;
+      }
+    } else {
+      char *s = BUF_strdup(val->value);
+      if (s == NULL) {
+	X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+	goto err;
+      }
+      s[i1] = '\0';
+      min = s2i_ASN1_INTEGER(NULL, s);
+      max = s2i_ASN1_INTEGER(NULL, s + i2);
+      OPENSSL_free(s);
+      if (min == NULL || max == NULL) {
+	ASN1_INTEGER_free(min);
+	ASN1_INTEGER_free(max);
+	X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+	goto err;
+      }
+    }
+    if (!v3_asid_add_id_or_range(asid, which, min, max)) {
+      ASN1_INTEGER_free(min);
+      ASN1_INTEGER_free(max);
+      X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+      goto err;
+    }
+  }
+
+  /*
+   * Canonize the result, then we're done.
+   */
+  if (!v3_asid_canonize(asid))
+    goto err;
+  return asid;
+
+ err:
+  ASIdentifiers_free(asid);
+  return NULL;
+}
+
+/*
+ * OpenSSL dispatch.
+ */
+const X509V3_EXT_METHOD v3_asid = {
+  NID_sbgp_autonomousSysNum,	/* nid */
+  0,				/* flags */
+  ASN1_ITEM_ref(ASIdentifiers),	/* template */
+  0, 0, 0, 0,			/* old functions, ignored */
+  0,				/* i2s */
+  0,				/* s2i */
+  0,				/* i2v */
+  v2i_ASIdentifiers,		/* v2i */
+  i2r_ASIdentifiers,		/* i2r */
+  0,				/* r2i */
+  NULL				/* extension-specific data */
+};
+
+/*
+ * Figure out whether extension uses inheritance.
+ */
+int v3_asid_inherits(ASIdentifiers *asid)
+{
+  return (asid != NULL &&
+	  ((asid->asnum != NULL &&
+	    asid->asnum->type == ASIdentifierChoice_inherit) ||
+	   (asid->rdi != NULL &&
+	    asid->rdi->type == ASIdentifierChoice_inherit)));
+}
+
+/*
+ * Figure out whether parent contains child.
+ */
+static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child)
+{
+  ASN1_INTEGER *p_min, *p_max, *c_min, *c_max;
+  int p, c;
+
+  if (child == NULL || parent == child)
+    return 1;
+  if (parent == NULL)
+    return 0;
+
+  p = 0;
+  for (c = 0; c < sk_ASIdOrRange_num(child); c++) {
+    extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, &c_max);
+    for (;; p++) {
+      if (p >= sk_ASIdOrRange_num(parent))
+	return 0;
+      extract_min_max(sk_ASIdOrRange_value(parent, p), &p_min, &p_max);
+      if (ASN1_INTEGER_cmp(p_max, c_max) < 0)
+	continue;
+      if (ASN1_INTEGER_cmp(p_min, c_min) > 0)
+	return 0;
+      break;
+    }
+  }
+
+  return 1;
+}
+
+/*
+ * Test whether a is a subet of b.
+ */
+int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b)
+{
+  return (a == NULL ||
+	  a == b ||
+	  (b != NULL &&
+	   !v3_asid_inherits(a) &&
+	   !v3_asid_inherits(b) &&
+	   asid_contains(b->asnum->u.asIdsOrRanges,
+			 a->asnum->u.asIdsOrRanges) &&
+	   asid_contains(b->rdi->u.asIdsOrRanges,
+			 a->rdi->u.asIdsOrRanges)));
+}
+
+/*
+ * Validation error handling via callback.
+ */
+#define validation_err(_err_)		\
+  do {					\
+    if (ctx != NULL) {			\
+      ctx->error = _err_;		\
+      ctx->error_depth = i;		\
+      ctx->current_cert = x;		\
+      ret = ctx->verify_cb(0, ctx);	\
+    } else {				\
+      ret = 0;				\
+    }					\
+    if (!ret)				\
+      goto done;			\
+  } while (0)
+
+/*
+ * Core code for RFC 3779 3.3 path validation.
+ */
+static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx,
+					  STACK_OF(X509) *chain,
+					  ASIdentifiers *ext)
+{
+  ASIdOrRanges *child_as = NULL, *child_rdi = NULL;
+  int i, ret = 1, inherit_as = 0, inherit_rdi = 0;
+  X509 *x;
+
+  OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0);
+  OPENSSL_assert(ctx != NULL || ext != NULL);
+  OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL);
+
+  /*
+   * Figure out where to start.  If we don't have an extension to
+   * check, we're done.  Otherwise, check canonical form and
+   * set up for walking up the chain.
+   */
+  if (ext != NULL) {
+    i = -1;
+    x = NULL;
+  } else {
+    i = 0;
+    x = sk_X509_value(chain, i);
+    OPENSSL_assert(x != NULL);
+    if ((ext = x->rfc3779_asid) == NULL)
+      goto done;
+  }
+  if (!v3_asid_is_canonical(ext))
+    validation_err(X509_V_ERR_INVALID_EXTENSION);
+  if (ext->asnum != NULL)  {
+    switch (ext->asnum->type) {
+    case ASIdentifierChoice_inherit:
+      inherit_as = 1;
+      break;
+    case ASIdentifierChoice_asIdsOrRanges:
+      child_as = ext->asnum->u.asIdsOrRanges;
+      break;
+    }
+  }
+  if (ext->rdi != NULL) {
+    switch (ext->rdi->type) {
+    case ASIdentifierChoice_inherit:
+      inherit_rdi = 1;
+      break;
+    case ASIdentifierChoice_asIdsOrRanges:
+      child_rdi = ext->rdi->u.asIdsOrRanges;
+      break;
+    }
+  }
+
+  /*
+   * Now walk up the chain.  Extensions must be in canonical form, no
+   * cert may list resources that its parent doesn't list.
+   */
+  for (i++; i < sk_X509_num(chain); i++) {
+    x = sk_X509_value(chain, i);
+    OPENSSL_assert(x != NULL);
+    if (x->rfc3779_asid == NULL) {
+      if (child_as != NULL || child_rdi != NULL)
+	validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+      continue;
+    }
+    if (!v3_asid_is_canonical(x->rfc3779_asid))
+      validation_err(X509_V_ERR_INVALID_EXTENSION);
+    if (x->rfc3779_asid->asnum == NULL && child_as != NULL) {
+      validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+      child_as = NULL;
+      inherit_as = 0;
+    }
+    if (x->rfc3779_asid->asnum != NULL &&
+	x->rfc3779_asid->asnum->type == ASIdentifierChoice_asIdsOrRanges) {
+      if (inherit_as ||
+	  asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, child_as)) {
+	child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges;
+	inherit_as = 0;
+      } else {
+	validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+      }
+    }
+    if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) {
+      validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+      child_rdi = NULL;
+      inherit_rdi = 0;
+    }
+    if (x->rfc3779_asid->rdi != NULL &&
+	x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) {
+      if (inherit_rdi ||
+	  asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, child_rdi)) {
+	child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges;
+	inherit_rdi = 0;
+      } else {
+	validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+      }
+    }
+  }
+
+  /*
+   * Trust anchor can't inherit.
+   */
+  OPENSSL_assert(x != NULL);
+  if (x->rfc3779_asid != NULL) {
+    if (x->rfc3779_asid->asnum != NULL &&
+	x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit)
+      validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+    if (x->rfc3779_asid->rdi != NULL &&
+	x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit)
+      validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+  }
+
+ done:
+  return ret;
+}
+
+#undef validation_err
+
+/*
+ * RFC 3779 3.3 path validation -- called from X509_verify_cert().
+ */
+int v3_asid_validate_path(X509_STORE_CTX *ctx)
+{
+  return v3_asid_validate_path_internal(ctx, ctx->chain, NULL);
+}
+
+/*
+ * RFC 3779 3.3 path validation of an extension.
+ * Test whether chain covers extension.
+ */
+int v3_asid_validate_resource_set(STACK_OF(X509) *chain,
+				  ASIdentifiers *ext,
+				  int allow_inheritance)
+{
+  if (ext == NULL)
+    return 1;
+  if (chain == NULL || sk_X509_num(chain) == 0)
+    return 0;
+  if (!allow_inheritance && v3_asid_inherits(ext))
+    return 0;
+  return v3_asid_validate_path_internal(NULL, chain, ext);
+}
+
+#endif /* OPENSSL_NO_RFC3779 */
diff --git a/openssl/crypto/x509v3/v3_bcons.c b/openssl/crypto/x509v3/v3_bcons.c
new file mode 100644
index 0000000..82aa488
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_bcons.c
@@ -0,0 +1,124 @@
+/* v3_bcons.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) *extlist);
+static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
+
+const X509V3_EXT_METHOD v3_bcons = {
+NID_basic_constraints, 0,
+ASN1_ITEM_ref(BASIC_CONSTRAINTS),
+0,0,0,0,
+0,0,
+(X509V3_EXT_I2V)i2v_BASIC_CONSTRAINTS,
+(X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS,
+NULL,NULL,
+NULL
+};
+
+ASN1_SEQUENCE(BASIC_CONSTRAINTS) = {
+	ASN1_OPT(BASIC_CONSTRAINTS, ca, ASN1_FBOOLEAN),
+	ASN1_OPT(BASIC_CONSTRAINTS, pathlen, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(BASIC_CONSTRAINTS)
+
+IMPLEMENT_ASN1_FUNCTIONS(BASIC_CONSTRAINTS)
+
+
+static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
+	     BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) *extlist)
+{
+	X509V3_add_value_bool("CA", bcons->ca, &extlist);
+	X509V3_add_value_int("pathlen", bcons->pathlen, &extlist);
+	return extlist;
+}
+
+static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
+	     X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values)
+{
+	BASIC_CONSTRAINTS *bcons=NULL;
+	CONF_VALUE *val;
+	int i;
+	if(!(bcons = BASIC_CONSTRAINTS_new())) {
+		X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	for(i = 0; i < sk_CONF_VALUE_num(values); i++) {
+		val = sk_CONF_VALUE_value(values, i);
+		if(!strcmp(val->name, "CA")) {
+			if(!X509V3_get_value_bool(val, &bcons->ca)) goto err;
+		} else if(!strcmp(val->name, "pathlen")) {
+			if(!X509V3_get_value_int(val, &bcons->pathlen)) goto err;
+		} else {
+			X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, X509V3_R_INVALID_NAME);
+			X509V3_conf_err(val);
+			goto err;
+		}
+	}
+	return bcons;
+	err:
+	BASIC_CONSTRAINTS_free(bcons);
+	return NULL;
+}
+
diff --git a/openssl/crypto/x509v3/v3_bitst.c b/openssl/crypto/x509v3/v3_bitst.c
new file mode 100644
index 0000000..058d0d4
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_bitst.c
@@ -0,0 +1,141 @@
+/* v3_bitst.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+static BIT_STRING_BITNAME ns_cert_type_table[] = {
+{0, "SSL Client", "client"},
+{1, "SSL Server", "server"},
+{2, "S/MIME", "email"},
+{3, "Object Signing", "objsign"},
+{4, "Unused", "reserved"},
+{5, "SSL CA", "sslCA"},
+{6, "S/MIME CA", "emailCA"},
+{7, "Object Signing CA", "objCA"},
+{-1, NULL, NULL}
+};
+
+static BIT_STRING_BITNAME key_usage_type_table[] = {
+{0, "Digital Signature", "digitalSignature"},
+{1, "Non Repudiation", "nonRepudiation"},
+{2, "Key Encipherment", "keyEncipherment"},
+{3, "Data Encipherment", "dataEncipherment"},
+{4, "Key Agreement", "keyAgreement"},
+{5, "Certificate Sign", "keyCertSign"},
+{6, "CRL Sign", "cRLSign"},
+{7, "Encipher Only", "encipherOnly"},
+{8, "Decipher Only", "decipherOnly"},
+{-1, NULL, NULL}
+};
+
+
+
+const X509V3_EXT_METHOD v3_nscert = EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table);
+const X509V3_EXT_METHOD v3_key_usage = EXT_BITSTRING(NID_key_usage, key_usage_type_table);
+
+STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+	     ASN1_BIT_STRING *bits, STACK_OF(CONF_VALUE) *ret)
+{
+	BIT_STRING_BITNAME *bnam;
+	for(bnam =method->usr_data; bnam->lname; bnam++) {
+		if(ASN1_BIT_STRING_get_bit(bits, bnam->bitnum)) 
+			X509V3_add_value(bnam->lname, NULL, &ret);
+	}
+	return ret;
+}
+	
+ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+	     X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+	CONF_VALUE *val;
+	ASN1_BIT_STRING *bs;
+	int i;
+	BIT_STRING_BITNAME *bnam;
+	if(!(bs = M_ASN1_BIT_STRING_new())) {
+		X509V3err(X509V3_F_V2I_ASN1_BIT_STRING,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+		val = sk_CONF_VALUE_value(nval, i);
+		for(bnam = method->usr_data; bnam->lname; bnam++) {
+			if(!strcmp(bnam->sname, val->name) ||
+				!strcmp(bnam->lname, val->name) ) {
+				if(!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) {
+					X509V3err(X509V3_F_V2I_ASN1_BIT_STRING,
+						ERR_R_MALLOC_FAILURE);
+					M_ASN1_BIT_STRING_free(bs);
+					return NULL;
+				}
+				break;
+			}
+		}
+		if(!bnam->lname) {
+			X509V3err(X509V3_F_V2I_ASN1_BIT_STRING,
+					X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT);
+			X509V3_conf_err(val);
+			M_ASN1_BIT_STRING_free(bs);
+			return NULL;
+		}
+	}
+	return bs;
+}
+	
+
diff --git a/openssl/crypto/x509v3/v3_conf.c b/openssl/crypto/x509v3/v3_conf.c
new file mode 100644
index 0000000..6730f9a
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_conf.c
@@ -0,0 +1,525 @@
+/* v3_conf.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* extension creation utilities */
+
+
+
+#include <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+static int v3_check_critical(char **value);
+static int v3_check_generic(char **value);
+static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, int crit, char *value);
+static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, int crit, int type, X509V3_CTX *ctx);
+static char *conf_lhash_get_string(void *db, char *section, char *value);
+static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section);
+static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
+				  int crit, void *ext_struc);
+static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len);
+/* CONF *conf:  Config file    */
+/* char *name:  Name    */
+/* char *value:  Value    */
+X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
+				 char *value)
+	{
+	int crit;
+	int ext_type;
+	X509_EXTENSION *ret;
+	crit = v3_check_critical(&value);
+	if ((ext_type = v3_check_generic(&value))) 
+		return v3_generic_extension(name, value, crit, ext_type, ctx);
+	ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
+	if (!ret)
+		{
+		X509V3err(X509V3_F_X509V3_EXT_NCONF,X509V3_R_ERROR_IN_EXTENSION);
+		ERR_add_error_data(4,"name=", name, ", value=", value);
+		}
+	return ret;
+	}
+
+/* CONF *conf:  Config file    */
+/* char *value:  Value    */
+X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
+				     char *value)
+	{
+	int crit;
+	int ext_type;
+	crit = v3_check_critical(&value);
+	if ((ext_type = v3_check_generic(&value))) 
+		return v3_generic_extension(OBJ_nid2sn(ext_nid),
+						 value, crit, ext_type, ctx);
+	return do_ext_nconf(conf, ctx, ext_nid, crit, value);
+	}
+
+/* CONF *conf:  Config file    */
+/* char *value:  Value    */
+static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
+				    int crit, char *value)
+	{
+	const X509V3_EXT_METHOD *method;
+	X509_EXTENSION *ext;
+	STACK_OF(CONF_VALUE) *nval;
+	void *ext_struc;
+	if (ext_nid == NID_undef)
+		{
+		X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_UNKNOWN_EXTENSION_NAME);
+		return NULL;
+		}
+	if (!(method = X509V3_EXT_get_nid(ext_nid)))
+		{
+		X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_UNKNOWN_EXTENSION);
+		return NULL;
+		}
+	/* Now get internal extension representation based on type */
+	if (method->v2i)
+		{
+		if(*value == '@') nval = NCONF_get_section(conf, value + 1);
+		else nval = X509V3_parse_list(value);
+		if(sk_CONF_VALUE_num(nval) <= 0)
+			{
+			X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_INVALID_EXTENSION_STRING);
+			ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", value);
+			return NULL;
+			}
+		ext_struc = method->v2i(method, ctx, nval);
+		if(*value != '@') sk_CONF_VALUE_pop_free(nval,
+							 X509V3_conf_free);
+		if(!ext_struc) return NULL;
+		}
+	else if(method->s2i)
+		{
+		if(!(ext_struc = method->s2i(method, ctx, value))) return NULL;
+		}
+	else if(method->r2i)
+		{
+		if(!ctx->db || !ctx->db_meth)
+			{
+			X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_NO_CONFIG_DATABASE);
+			return NULL;
+			}
+		if(!(ext_struc = method->r2i(method, ctx, value))) return NULL;
+		}
+	else
+		{
+		X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
+		ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
+		return NULL;
+		}
+
+	ext  = do_ext_i2d(method, ext_nid, crit, ext_struc);
+	if(method->it) ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
+	else method->ext_free(ext_struc);
+	return ext;
+
+	}
+
+static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
+				  int crit, void *ext_struc)
+	{
+	unsigned char *ext_der;
+	int ext_len;
+	ASN1_OCTET_STRING *ext_oct;
+	X509_EXTENSION *ext;
+	/* Convert internal representation to DER */
+	if (method->it)
+		{
+		ext_der = NULL;
+		ext_len = ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
+		if (ext_len < 0) goto merr;
+		}
+	 else
+		{
+		unsigned char *p;
+		ext_len = method->i2d(ext_struc, NULL);
+		if(!(ext_der = OPENSSL_malloc(ext_len))) goto merr;
+		p = ext_der;
+		method->i2d(ext_struc, &p);
+		}
+	if (!(ext_oct = M_ASN1_OCTET_STRING_new())) goto merr;
+	ext_oct->data = ext_der;
+	ext_oct->length = ext_len;
+
+	ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
+	if (!ext) goto merr;
+	M_ASN1_OCTET_STRING_free(ext_oct);
+
+	return ext;
+
+	merr:
+	X509V3err(X509V3_F_DO_EXT_I2D,ERR_R_MALLOC_FAILURE);
+	return NULL;
+
+	}
+
+/* Given an internal structure, nid and critical flag create an extension */
+
+X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc)
+	{
+	const X509V3_EXT_METHOD *method;
+	if (!(method = X509V3_EXT_get_nid(ext_nid))) {
+		X509V3err(X509V3_F_X509V3_EXT_I2D,X509V3_R_UNKNOWN_EXTENSION);
+		return NULL;
+	}
+	return do_ext_i2d(method, ext_nid, crit, ext_struc);
+}
+
+/* Check the extension string for critical flag */
+static int v3_check_critical(char **value)
+{
+	char *p = *value;
+	if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) return 0;
+	p+=9;
+	while(isspace((unsigned char)*p)) p++;
+	*value = p;
+	return 1;
+}
+
+/* Check extension string for generic extension and return the type */
+static int v3_check_generic(char **value)
+{
+	int gen_type = 0;
+	char *p = *value;
+	if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4))
+		{
+		p+=4;
+		gen_type = 1;
+		}
+	else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5))
+		{
+		p+=5;
+		gen_type = 2;
+		}
+	else
+		return 0;
+
+	while (isspace((unsigned char)*p)) p++;
+	*value = p;
+	return gen_type;
+}
+
+/* Create a generic extension: for now just handle DER type */
+static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
+					    int crit, int gen_type,
+					    X509V3_CTX *ctx)
+	{
+	unsigned char *ext_der=NULL;
+	long ext_len;
+	ASN1_OBJECT *obj=NULL;
+	ASN1_OCTET_STRING *oct=NULL;
+	X509_EXTENSION *extension=NULL;
+	if (!(obj = OBJ_txt2obj(ext, 0)))
+		{
+		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_NAME_ERROR);
+		ERR_add_error_data(2, "name=", ext);
+		goto err;
+		}
+
+	if (gen_type == 1)
+		ext_der = string_to_hex(value, &ext_len);
+	else if (gen_type == 2)
+		ext_der = generic_asn1(value, ctx, &ext_len);
+
+	if (ext_der == NULL)
+		{
+		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_VALUE_ERROR);
+		ERR_add_error_data(2, "value=", value);
+		goto err;
+		}
+
+	if (!(oct = M_ASN1_OCTET_STRING_new()))
+		{
+		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	oct->data = ext_der;
+	oct->length = ext_len;
+	ext_der = NULL;
+
+	extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);
+
+	err:
+	ASN1_OBJECT_free(obj);
+	M_ASN1_OCTET_STRING_free(oct);
+	if(ext_der) OPENSSL_free(ext_der);
+	return extension;
+
+	}
+
+static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len)
+	{
+	ASN1_TYPE *typ;
+	unsigned char *ext_der = NULL;
+	typ = ASN1_generate_v3(value, ctx);
+	if (typ == NULL)
+		return NULL;
+	*ext_len = i2d_ASN1_TYPE(typ, &ext_der);
+	ASN1_TYPE_free(typ);
+	return ext_der;
+	}
+
+/* This is the main function: add a bunch of extensions based on a config file
+ * section to an extension STACK.
+ */
+
+
+int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
+			    STACK_OF(X509_EXTENSION) **sk)
+	{
+	X509_EXTENSION *ext;
+	STACK_OF(CONF_VALUE) *nval;
+	CONF_VALUE *val;	
+	int i;
+	if (!(nval = NCONF_get_section(conf, section))) return 0;
+	for (i = 0; i < sk_CONF_VALUE_num(nval); i++)
+		{
+		val = sk_CONF_VALUE_value(nval, i);
+		if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)))
+								return 0;
+		if (sk) X509v3_add_ext(sk, ext, -1);
+		X509_EXTENSION_free(ext);
+		}
+	return 1;
+	}
+
+/* Convenience functions to add extensions to a certificate, CRL and request */
+
+int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
+			 X509 *cert)
+	{
+	STACK_OF(X509_EXTENSION) **sk = NULL;
+	if (cert)
+		sk = &cert->cert_info->extensions;
+	return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
+	}
+
+/* Same as above but for a CRL */
+
+int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
+			     X509_CRL *crl)
+	{
+	STACK_OF(X509_EXTENSION) **sk = NULL;
+	if (crl)
+		sk = &crl->crl->extensions;
+	return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
+	}
+
+/* Add extensions to certificate request */
+
+int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
+	     X509_REQ *req)
+	{
+	STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL;
+	int i;
+	if (req)
+		sk = &extlist;
+	i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
+	if (!i || !sk)
+		return i;
+	i = X509_REQ_add_extensions(req, extlist);
+	sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
+	return i;
+	}
+
+/* Config database functions */
+
+char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section)
+	{
+	if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string)
+		{
+		X509V3err(X509V3_F_X509V3_GET_STRING,X509V3_R_OPERATION_NOT_DEFINED);
+		return NULL;
+		}
+	if (ctx->db_meth->get_string)
+			return ctx->db_meth->get_string(ctx->db, name, section);
+	return NULL;
+	}
+
+STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section)
+	{
+	if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section)
+		{
+		X509V3err(X509V3_F_X509V3_GET_SECTION,X509V3_R_OPERATION_NOT_DEFINED);
+		return NULL;
+		}
+	if (ctx->db_meth->get_section)
+			return ctx->db_meth->get_section(ctx->db, section);
+	return NULL;
+	}
+
+void X509V3_string_free(X509V3_CTX *ctx, char *str)
+	{
+	if (!str) return;
+	if (ctx->db_meth->free_string)
+			ctx->db_meth->free_string(ctx->db, str);
+	}
+
+void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section)
+	{
+	if (!section) return;
+	if (ctx->db_meth->free_section)
+			ctx->db_meth->free_section(ctx->db, section);
+	}
+
+static char *nconf_get_string(void *db, char *section, char *value)
+	{
+	return NCONF_get_string(db, section, value);
+	}
+
+static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, char *section)
+	{
+	return NCONF_get_section(db, section);
+	}
+
+static X509V3_CONF_METHOD nconf_method = {
+nconf_get_string,
+nconf_get_section,
+NULL,
+NULL
+};
+
+void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf)
+	{
+	ctx->db_meth = &nconf_method;
+	ctx->db = conf;
+	}
+
+void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
+		    X509_CRL *crl, int flags)
+	{
+	ctx->issuer_cert = issuer;
+	ctx->subject_cert = subj;
+	ctx->crl = crl;
+	ctx->subject_req = req;
+	ctx->flags = flags;
+	}
+
+/* Old conf compatibility functions */
+
+X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+				char *name, char *value)
+	{
+	CONF ctmp;
+	CONF_set_nconf(&ctmp, conf);
+	return X509V3_EXT_nconf(&ctmp, ctx, name, value);
+	}
+
+/* LHASH *conf:  Config file    */
+/* char *value:  Value    */
+X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+				    int ext_nid, char *value)
+	{
+	CONF ctmp;
+	CONF_set_nconf(&ctmp, conf);
+	return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value);
+	}
+
+static char *conf_lhash_get_string(void *db, char *section, char *value)
+	{
+	return CONF_get_string(db, section, value);
+	}
+
+static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section)
+	{
+	return CONF_get_section(db, section);
+	}
+
+static X509V3_CONF_METHOD conf_lhash_method = {
+conf_lhash_get_string,
+conf_lhash_get_section,
+NULL,
+NULL
+};
+
+void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash)
+	{
+	ctx->db_meth = &conf_lhash_method;
+	ctx->db = lhash;
+	}
+
+int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+			char *section, X509 *cert)
+	{
+	CONF ctmp;
+	CONF_set_nconf(&ctmp, conf);
+	return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert);
+	}
+
+/* Same as above but for a CRL */
+
+int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+			    char *section, X509_CRL *crl)
+	{
+	CONF ctmp;
+	CONF_set_nconf(&ctmp, conf);
+	return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl);
+	}
+
+/* Add extensions to certificate request */
+
+int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+			    char *section, X509_REQ *req)
+	{
+	CONF ctmp;
+	CONF_set_nconf(&ctmp, conf);
+	return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req);
+	}
diff --git a/openssl/crypto/x509v3/v3_cpols.c b/openssl/crypto/x509v3/v3_cpols.c
new file mode 100644
index 0000000..1f0798b
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_cpols.c
@@ -0,0 +1,457 @@
+/* v3_cpols.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+
+/* Certificate policies extension support: this one is a bit complex... */
+
+static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO *out, int indent);
+static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value);
+static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent);
+static void print_notice(BIO *out, USERNOTICE *notice, int indent);
+static POLICYINFO *policy_section(X509V3_CTX *ctx,
+				 STACK_OF(CONF_VALUE) *polstrs, int ia5org);
+static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
+					STACK_OF(CONF_VALUE) *unot, int ia5org);
+static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos);
+
+const X509V3_EXT_METHOD v3_cpols = {
+NID_certificate_policies, 0,ASN1_ITEM_ref(CERTIFICATEPOLICIES),
+0,0,0,0,
+0,0,
+0,0,
+(X509V3_EXT_I2R)i2r_certpol,
+(X509V3_EXT_R2I)r2i_certpol,
+NULL
+};
+
+ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO)
+ASN1_ITEM_TEMPLATE_END(CERTIFICATEPOLICIES)
+
+IMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)
+
+ASN1_SEQUENCE(POLICYINFO) = {
+	ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT),
+	ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO)
+} ASN1_SEQUENCE_END(POLICYINFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO)
+
+ASN1_ADB_TEMPLATE(policydefault) = ASN1_SIMPLE(POLICYQUALINFO, d.other, ASN1_ANY);
+
+ASN1_ADB(POLICYQUALINFO) = {
+	ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)),
+	ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE))
+} ASN1_ADB_END(POLICYQUALINFO, 0, pqualid, 0, &policydefault_tt, NULL);
+
+ASN1_SEQUENCE(POLICYQUALINFO) = {
+	ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT),
+	ASN1_ADB_OBJECT(POLICYQUALINFO)
+} ASN1_SEQUENCE_END(POLICYQUALINFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO)
+
+ASN1_SEQUENCE(USERNOTICE) = {
+	ASN1_OPT(USERNOTICE, noticeref, NOTICEREF),
+	ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT)
+} ASN1_SEQUENCE_END(USERNOTICE)
+
+IMPLEMENT_ASN1_FUNCTIONS(USERNOTICE)
+
+ASN1_SEQUENCE(NOTICEREF) = {
+	ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT),
+	ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(NOTICEREF)
+
+IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF)
+
+static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
+		X509V3_CTX *ctx, char *value)
+{
+	STACK_OF(POLICYINFO) *pols = NULL;
+	char *pstr;
+	POLICYINFO *pol;
+	ASN1_OBJECT *pobj;
+	STACK_OF(CONF_VALUE) *vals;
+	CONF_VALUE *cnf;
+	int i, ia5org;
+	pols = sk_POLICYINFO_new_null();
+	if (pols == NULL) {
+		X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	vals =  X509V3_parse_list(value);
+	if (vals == NULL) {
+		X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_X509V3_LIB);
+		goto err;
+	}
+	ia5org = 0;
+	for(i = 0; i < sk_CONF_VALUE_num(vals); i++) {
+		cnf = sk_CONF_VALUE_value(vals, i);
+		if(cnf->value || !cnf->name ) {
+			X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_POLICY_IDENTIFIER);
+			X509V3_conf_err(cnf);
+			goto err;
+		}
+		pstr = cnf->name;
+		if(!strcmp(pstr,"ia5org")) {
+			ia5org = 1;
+			continue;
+		} else if(*pstr == '@') {
+			STACK_OF(CONF_VALUE) *polsect;
+			polsect = X509V3_get_section(ctx, pstr + 1);
+			if(!polsect) {
+				X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_SECTION);
+
+				X509V3_conf_err(cnf);
+				goto err;
+			}
+			pol = policy_section(ctx, polsect, ia5org);
+			X509V3_section_free(ctx, polsect);
+			if(!pol) goto err;
+		} else {
+			if(!(pobj = OBJ_txt2obj(cnf->name, 0))) {
+				X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_OBJECT_IDENTIFIER);
+				X509V3_conf_err(cnf);
+				goto err;
+			}
+			pol = POLICYINFO_new();
+			pol->policyid = pobj;
+		}
+		if (!sk_POLICYINFO_push(pols, pol)){
+			POLICYINFO_free(pol);
+			X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+	}
+	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+	return pols;
+	err:
+	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+	sk_POLICYINFO_pop_free(pols, POLICYINFO_free);
+	return NULL;
+}
+
+static POLICYINFO *policy_section(X509V3_CTX *ctx,
+				STACK_OF(CONF_VALUE) *polstrs, int ia5org)
+{
+	int i;
+	CONF_VALUE *cnf;
+	POLICYINFO *pol;
+	POLICYQUALINFO *qual;
+	if(!(pol = POLICYINFO_new())) goto merr;
+	for(i = 0; i < sk_CONF_VALUE_num(polstrs); i++) {
+		cnf = sk_CONF_VALUE_value(polstrs, i);
+		if(!strcmp(cnf->name, "policyIdentifier")) {
+			ASN1_OBJECT *pobj;
+			if(!(pobj = OBJ_txt2obj(cnf->value, 0))) {
+				X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_OBJECT_IDENTIFIER);
+				X509V3_conf_err(cnf);
+				goto err;
+			}
+			pol->policyid = pobj;
+
+		} else if(!name_cmp(cnf->name, "CPS")) {
+			if(!pol->qualifiers) pol->qualifiers =
+						 sk_POLICYQUALINFO_new_null();
+			if(!(qual = POLICYQUALINFO_new())) goto merr;
+			if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
+								 goto merr;
+			qual->pqualid = OBJ_nid2obj(NID_id_qt_cps);
+			qual->d.cpsuri = M_ASN1_IA5STRING_new();
+			if(!ASN1_STRING_set(qual->d.cpsuri, cnf->value,
+						 strlen(cnf->value))) goto merr;
+		} else if(!name_cmp(cnf->name, "userNotice")) {
+			STACK_OF(CONF_VALUE) *unot;
+			if(*cnf->value != '@') {
+				X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_EXPECTED_A_SECTION_NAME);
+				X509V3_conf_err(cnf);
+				goto err;
+			}
+			unot = X509V3_get_section(ctx, cnf->value + 1);
+			if(!unot) {
+				X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_SECTION);
+
+				X509V3_conf_err(cnf);
+				goto err;
+			}
+			qual = notice_section(ctx, unot, ia5org);
+			X509V3_section_free(ctx, unot);
+			if(!qual) goto err;
+			if(!pol->qualifiers) pol->qualifiers =
+						 sk_POLICYQUALINFO_new_null();
+			if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
+								 goto merr;
+		} else {
+			X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_OPTION);
+
+			X509V3_conf_err(cnf);
+			goto err;
+		}
+	}
+	if(!pol->policyid) {
+		X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_NO_POLICY_IDENTIFIER);
+		goto err;
+	}
+
+	return pol;
+
+	merr:
+	X509V3err(X509V3_F_POLICY_SECTION,ERR_R_MALLOC_FAILURE);
+
+	err:
+	POLICYINFO_free(pol);
+	return NULL;
+	
+	
+}
+
+static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
+					STACK_OF(CONF_VALUE) *unot, int ia5org)
+{
+	int i, ret;
+	CONF_VALUE *cnf;
+	USERNOTICE *not;
+	POLICYQUALINFO *qual;
+	if(!(qual = POLICYQUALINFO_new())) goto merr;
+	qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice);
+	if(!(not = USERNOTICE_new())) goto merr;
+	qual->d.usernotice = not;
+	for(i = 0; i < sk_CONF_VALUE_num(unot); i++) {
+		cnf = sk_CONF_VALUE_value(unot, i);
+		if(!strcmp(cnf->name, "explicitText")) {
+			not->exptext = M_ASN1_VISIBLESTRING_new();
+			if(!ASN1_STRING_set(not->exptext, cnf->value,
+						 strlen(cnf->value))) goto merr;
+		} else if(!strcmp(cnf->name, "organization")) {
+			NOTICEREF *nref;
+			if(!not->noticeref) {
+				if(!(nref = NOTICEREF_new())) goto merr;
+				not->noticeref = nref;
+			} else nref = not->noticeref;
+			if(ia5org) nref->organization->type = V_ASN1_IA5STRING;
+			else nref->organization->type = V_ASN1_VISIBLESTRING;
+			if(!ASN1_STRING_set(nref->organization, cnf->value,
+						 strlen(cnf->value))) goto merr;
+		} else if(!strcmp(cnf->name, "noticeNumbers")) {
+			NOTICEREF *nref;
+			STACK_OF(CONF_VALUE) *nos;
+			if(!not->noticeref) {
+				if(!(nref = NOTICEREF_new())) goto merr;
+				not->noticeref = nref;
+			} else nref = not->noticeref;
+			nos = X509V3_parse_list(cnf->value);
+			if(!nos || !sk_CONF_VALUE_num(nos)) {
+				X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_INVALID_NUMBERS);
+				X509V3_conf_err(cnf);
+				goto err;
+			}
+			ret = nref_nos(nref->noticenos, nos);
+			sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
+			if (!ret)
+				goto err;
+		} else {
+			X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_INVALID_OPTION);
+			X509V3_conf_err(cnf);
+			goto err;
+		}
+	}
+
+	if(not->noticeref && 
+	      (!not->noticeref->noticenos || !not->noticeref->organization)) {
+			X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
+			goto err;
+	}
+
+	return qual;
+
+	merr:
+	X509V3err(X509V3_F_NOTICE_SECTION,ERR_R_MALLOC_FAILURE);
+
+	err:
+	POLICYQUALINFO_free(qual);
+	return NULL;
+}
+
+static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
+{
+	CONF_VALUE *cnf;
+	ASN1_INTEGER *aint;
+
+	int i;
+
+	for(i = 0; i < sk_CONF_VALUE_num(nos); i++) {
+		cnf = sk_CONF_VALUE_value(nos, i);
+		if(!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) {
+			X509V3err(X509V3_F_NREF_NOS,X509V3_R_INVALID_NUMBER);
+			goto err;
+		}
+		if(!sk_ASN1_INTEGER_push(nnums, aint)) goto merr;
+	}
+	return 1;
+
+	merr:
+	X509V3err(X509V3_F_NREF_NOS,ERR_R_MALLOC_FAILURE);
+
+	err:
+	sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
+	return 0;
+}
+
+
+static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
+		BIO *out, int indent)
+{
+	int i;
+	POLICYINFO *pinfo;
+	/* First print out the policy OIDs */
+	for(i = 0; i < sk_POLICYINFO_num(pol); i++) {
+		pinfo = sk_POLICYINFO_value(pol, i);
+		BIO_printf(out, "%*sPolicy: ", indent, "");
+		i2a_ASN1_OBJECT(out, pinfo->policyid);
+		BIO_puts(out, "\n");
+		if(pinfo->qualifiers)
+			 print_qualifiers(out, pinfo->qualifiers, indent + 2);
+	}
+	return 1;
+}
+
+static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
+		int indent)
+{
+	POLICYQUALINFO *qualinfo;
+	int i;
+	for(i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
+		qualinfo = sk_POLICYQUALINFO_value(quals, i);
+		switch(OBJ_obj2nid(qualinfo->pqualid))
+		{
+			case NID_id_qt_cps:
+			BIO_printf(out, "%*sCPS: %s\n", indent, "",
+						qualinfo->d.cpsuri->data);
+			break;
+		
+			case NID_id_qt_unotice:
+			BIO_printf(out, "%*sUser Notice:\n", indent, "");
+			print_notice(out, qualinfo->d.usernotice, indent + 2);
+			break;
+
+			default:
+			BIO_printf(out, "%*sUnknown Qualifier: ",
+							 indent + 2, "");
+			
+			i2a_ASN1_OBJECT(out, qualinfo->pqualid);
+			BIO_puts(out, "\n");
+			break;
+		}
+	}
+}
+
+static void print_notice(BIO *out, USERNOTICE *notice, int indent)
+{
+	int i;
+	if(notice->noticeref) {
+		NOTICEREF *ref;
+		ref = notice->noticeref;
+		BIO_printf(out, "%*sOrganization: %s\n", indent, "",
+						 ref->organization->data);
+		BIO_printf(out, "%*sNumber%s: ", indent, "",
+			   sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
+		for(i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
+			ASN1_INTEGER *num;
+			char *tmp;
+			num = sk_ASN1_INTEGER_value(ref->noticenos, i);
+			if(i) BIO_puts(out, ", ");
+			tmp = i2s_ASN1_INTEGER(NULL, num);
+			BIO_puts(out, tmp);
+			OPENSSL_free(tmp);
+		}
+		BIO_puts(out, "\n");
+	}
+	if(notice->exptext)
+		BIO_printf(out, "%*sExplicit Text: %s\n", indent, "",
+							 notice->exptext->data);
+}
+
+void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent)
+	{
+	const X509_POLICY_DATA *dat = node->data;
+
+	BIO_printf(out, "%*sPolicy: ", indent, "");
+			
+	i2a_ASN1_OBJECT(out, dat->valid_policy);
+	BIO_puts(out, "\n");
+	BIO_printf(out, "%*s%s\n", indent + 2, "",
+		node_data_critical(dat) ? "Critical" : "Non Critical");
+	if (dat->qualifier_set)
+		print_qualifiers(out, dat->qualifier_set, indent + 2);
+	else
+		BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
+	}
+
+
+IMPLEMENT_STACK_OF(X509_POLICY_NODE)
+IMPLEMENT_STACK_OF(X509_POLICY_DATA)
+
diff --git a/openssl/crypto/x509v3/v3_crld.c b/openssl/crypto/x509v3/v3_crld.c
new file mode 100644
index 0000000..790a6dd
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_crld.c
@@ -0,0 +1,616 @@
+/* v3_crld.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+static void *v2i_crld(const X509V3_EXT_METHOD *method,
+		      X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
+		     int indent);
+
+const X509V3_EXT_METHOD v3_crld =
+	{
+	NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
+	0,0,0,0,
+	0,0,
+	0,
+	v2i_crld,
+	i2r_crldp,0,
+	NULL
+	};
+
+const X509V3_EXT_METHOD v3_freshest_crl =
+	{
+	NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
+	0,0,0,0,
+	0,0,
+	0,
+	v2i_crld,
+	i2r_crldp,0,
+	NULL
+	};
+
+static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, char *sect)
+	{
+	STACK_OF(CONF_VALUE) *gnsect;
+	STACK_OF(GENERAL_NAME) *gens;
+	if (*sect == '@')
+		gnsect = X509V3_get_section(ctx, sect + 1);
+	else
+		gnsect = X509V3_parse_list(sect);
+	if (!gnsect)
+		{
+		X509V3err(X509V3_F_GNAMES_FROM_SECTNAME,
+						X509V3_R_SECTION_NOT_FOUND);
+		return NULL;
+		}
+	gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
+	if (*sect == '@')
+		X509V3_section_free(ctx, gnsect);
+	else
+		sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free);
+	return gens;
+	}
+
+static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
+							CONF_VALUE *cnf)
+	{
+	STACK_OF(GENERAL_NAME) *fnm = NULL;
+	STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
+	if (!strncmp(cnf->name, "fullname", 9))
+		{
+		fnm = gnames_from_sectname(ctx, cnf->value);
+		if (!fnm)
+			goto err;
+		}
+	else if (!strcmp(cnf->name, "relativename"))
+		{
+		int ret;
+		STACK_OF(CONF_VALUE) *dnsect;
+		X509_NAME *nm;
+		nm = X509_NAME_new();
+		if (!nm)
+			return -1;
+		dnsect = X509V3_get_section(ctx, cnf->value);
+		if (!dnsect)
+			{
+			X509V3err(X509V3_F_SET_DIST_POINT_NAME,
+						X509V3_R_SECTION_NOT_FOUND);
+			return -1;
+			}
+		ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
+		X509V3_section_free(ctx, dnsect);
+		rnm = nm->entries;
+		nm->entries = NULL;
+		X509_NAME_free(nm);
+		if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0)
+			goto err;
+		/* Since its a name fragment can't have more than one
+		 * RDNSequence
+		 */
+		if (sk_X509_NAME_ENTRY_value(rnm,
+				sk_X509_NAME_ENTRY_num(rnm) - 1)->set)
+			{
+			X509V3err(X509V3_F_SET_DIST_POINT_NAME,
+						X509V3_R_INVALID_MULTIPLE_RDNS);
+			goto err;
+			}
+		}
+	else
+		return 0;
+
+	if (*pdp)
+		{
+		X509V3err(X509V3_F_SET_DIST_POINT_NAME,
+						X509V3_R_DISTPOINT_ALREADY_SET);
+		goto err;
+		}
+
+	*pdp = DIST_POINT_NAME_new();
+	if (!*pdp)
+		goto err;
+	if (fnm)
+		{
+		(*pdp)->type = 0;
+		(*pdp)->name.fullname = fnm;
+		}
+	else
+		{
+		(*pdp)->type = 1;
+		(*pdp)->name.relativename = rnm;
+		}
+
+	return 1;
+		
+	err:
+	if (fnm)
+		sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free);
+	if (rnm)
+		sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free);
+	return -1;
+	}
+
+static const BIT_STRING_BITNAME reason_flags[] = {
+{0, "Unused", "unused"},
+{1, "Key Compromise", "keyCompromise"},
+{2, "CA Compromise", "CACompromise"},
+{3, "Affiliation Changed", "affiliationChanged"},
+{4, "Superseded", "superseded"},
+{5, "Cessation Of Operation", "cessationOfOperation"},
+{6, "Certificate Hold", "certificateHold"},
+{7, "Privilege Withdrawn", "privilegeWithdrawn"},
+{8, "AA Compromise", "AACompromise"},
+{-1, NULL, NULL}
+};
+
+static int set_reasons(ASN1_BIT_STRING **preas, char *value)
+	{
+	STACK_OF(CONF_VALUE) *rsk = NULL;
+	const BIT_STRING_BITNAME *pbn;
+	const char *bnam;
+	int i, ret = 0;
+	rsk = X509V3_parse_list(value);
+	if (!rsk)
+		return 0;
+	if (*preas)
+		return 0;
+	for (i = 0; i < sk_CONF_VALUE_num(rsk); i++)
+		{
+		bnam = sk_CONF_VALUE_value(rsk, i)->name;
+		if (!*preas)
+			{
+			*preas = ASN1_BIT_STRING_new();
+			if (!*preas)
+				goto err;
+			}
+		for (pbn = reason_flags; pbn->lname; pbn++)
+			{
+			if (!strcmp(pbn->sname, bnam))
+				{
+				if (!ASN1_BIT_STRING_set_bit(*preas,
+							pbn->bitnum, 1))
+					goto err;
+				break;
+				}
+			}
+		if (!pbn->lname)
+			goto err;
+		}
+	ret = 1;
+
+	err:
+	sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
+	return ret;
+	}
+
+static int print_reasons(BIO *out, const char *rname,
+			ASN1_BIT_STRING *rflags, int indent)
+	{
+	int first = 1;
+	const BIT_STRING_BITNAME *pbn;
+	BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
+	for (pbn = reason_flags; pbn->lname; pbn++)
+		{
+		if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum))
+			{
+			if (first)
+				first = 0;
+			else
+				BIO_puts(out, ", ");
+			BIO_puts(out, pbn->lname);
+			}
+		}
+	if (first)
+		BIO_puts(out, "<EMPTY>\n");
+	else
+		BIO_puts(out, "\n");
+	return 1;
+	}
+
+static DIST_POINT *crldp_from_section(X509V3_CTX *ctx,
+						STACK_OF(CONF_VALUE) *nval)
+	{
+	int i;
+	CONF_VALUE *cnf;
+	DIST_POINT *point = NULL;
+	point = DIST_POINT_new();
+	if (!point)
+		goto err;
+	for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
+		{
+		int ret;
+		cnf = sk_CONF_VALUE_value(nval, i);
+		ret = set_dist_point_name(&point->distpoint, ctx, cnf);
+		if (ret > 0)
+			continue;
+		if (ret < 0)
+			goto err;
+		if (!strcmp(cnf->name, "reasons"))
+			{
+			if (!set_reasons(&point->reasons, cnf->value))
+				goto err;
+			}
+		else if (!strcmp(cnf->name, "CRLissuer"))
+			{
+			point->CRLissuer =
+				gnames_from_sectname(ctx, cnf->value);
+			if (!point->CRLissuer)
+				goto err;
+			}
+		}
+
+	return point;
+			
+
+	err:
+	if (point)
+		DIST_POINT_free(point);
+	return NULL;
+	}
+
+static void *v2i_crld(const X509V3_EXT_METHOD *method,
+		      X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+	{
+	STACK_OF(DIST_POINT) *crld = NULL;
+	GENERAL_NAMES *gens = NULL;
+	GENERAL_NAME *gen = NULL;
+	CONF_VALUE *cnf;
+	int i;
+	if(!(crld = sk_DIST_POINT_new_null())) goto merr;
+	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+		DIST_POINT *point;
+		cnf = sk_CONF_VALUE_value(nval, i);
+		if (!cnf->value)
+			{
+			STACK_OF(CONF_VALUE) *dpsect;
+			dpsect = X509V3_get_section(ctx, cnf->name);
+			if (!dpsect)
+				goto err;
+			point = crldp_from_section(ctx, dpsect);
+			X509V3_section_free(ctx, dpsect);
+			if (!point)
+				goto err;
+			if(!sk_DIST_POINT_push(crld, point))
+				{
+				DIST_POINT_free(point);
+				goto merr;
+				}
+			}
+		else
+			{
+			if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+				goto err; 
+			if(!(gens = GENERAL_NAMES_new()))
+				goto merr;
+			if(!sk_GENERAL_NAME_push(gens, gen))
+				goto merr;
+			gen = NULL;
+			if(!(point = DIST_POINT_new()))
+				goto merr;
+			if(!sk_DIST_POINT_push(crld, point))
+				{
+				DIST_POINT_free(point);
+				goto merr;
+				}
+			if(!(point->distpoint = DIST_POINT_NAME_new()))
+				goto merr;
+			point->distpoint->name.fullname = gens;
+			point->distpoint->type = 0;
+			gens = NULL;
+			}
+	}
+	return crld;
+
+	merr:
+	X509V3err(X509V3_F_V2I_CRLD,ERR_R_MALLOC_FAILURE);
+	err:
+	GENERAL_NAME_free(gen);
+	GENERAL_NAMES_free(gens);
+	sk_DIST_POINT_pop_free(crld, DIST_POINT_free);
+	return NULL;
+}
+
+IMPLEMENT_STACK_OF(DIST_POINT)
+IMPLEMENT_ASN1_SET_OF(DIST_POINT)
+
+static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+								void *exarg)
+	{
+	DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
+
+	switch(operation)
+		{
+		case ASN1_OP_NEW_POST:
+		dpn->dpname = NULL;
+		break;
+
+		case ASN1_OP_FREE_POST:
+		if (dpn->dpname)
+			X509_NAME_free(dpn->dpname);
+		break;
+		}
+	return 1;
+	}
+
+
+ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = {
+	ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0),
+	ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1)
+} ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type)
+
+
+IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME)
+
+ASN1_SEQUENCE(DIST_POINT) = {
+	ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0),
+	ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1),
+	ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2)
+} ASN1_SEQUENCE_END(DIST_POINT)
+
+IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT)
+
+ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT)
+ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS)
+
+IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS)
+
+ASN1_SEQUENCE(ISSUING_DIST_POINT) = {
+	ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0),
+	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1),
+	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2),
+	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3),
+	ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4),
+	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5)
+} ASN1_SEQUENCE_END(ISSUING_DIST_POINT)
+
+IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
+
+static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
+		   int indent);
+static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+		     STACK_OF(CONF_VALUE) *nval);
+
+const X509V3_EXT_METHOD v3_idp =
+	{
+	NID_issuing_distribution_point, X509V3_EXT_MULTILINE,
+	ASN1_ITEM_ref(ISSUING_DIST_POINT),
+	0,0,0,0,
+	0,0,
+	0,
+	v2i_idp,
+	i2r_idp,0,
+	NULL
+	};
+
+static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+		     STACK_OF(CONF_VALUE) *nval)
+	{
+	ISSUING_DIST_POINT *idp = NULL;
+	CONF_VALUE *cnf;
+	char *name, *val;
+	int i, ret;
+	idp = ISSUING_DIST_POINT_new();
+	if (!idp)
+		goto merr;
+	for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
+		{
+		cnf = sk_CONF_VALUE_value(nval, i);
+		name = cnf->name;
+		val = cnf->value;
+		ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
+		if (ret > 0)
+			continue;
+		if (ret < 0)
+			goto err;
+		if (!strcmp(name, "onlyuser"))
+			{
+			if (!X509V3_get_value_bool(cnf, &idp->onlyuser))
+				goto err;
+			}
+		else if (!strcmp(name, "onlyCA"))
+			{
+			if (!X509V3_get_value_bool(cnf, &idp->onlyCA))
+				goto err;
+			}
+		else if (!strcmp(name, "onlyAA"))
+			{
+			if (!X509V3_get_value_bool(cnf, &idp->onlyattr))
+				goto err;
+			}
+		else if (!strcmp(name, "indirectCRL"))
+			{
+			if (!X509V3_get_value_bool(cnf, &idp->indirectCRL))
+				goto err;
+			}
+		else if (!strcmp(name, "onlysomereasons"))
+			{
+			if (!set_reasons(&idp->onlysomereasons, val))
+				goto err;
+			}
+		else
+			{
+                        X509V3err(X509V3_F_V2I_IDP, X509V3_R_INVALID_NAME);
+                        X509V3_conf_err(cnf);
+                        goto err;
+			}
+		}
+	return idp;
+
+	merr:
+	X509V3err(X509V3_F_V2I_IDP,ERR_R_MALLOC_FAILURE);
+	err:
+	ISSUING_DIST_POINT_free(idp);
+	return NULL;
+	}
+
+static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent)
+	{
+	int i;
+	for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
+		{
+		BIO_printf(out, "%*s", indent + 2, "");
+		GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
+		BIO_puts(out, "\n");
+		}
+	return 1;
+	}
+
+static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent)
+	{
+	if (dpn->type == 0)
+		{
+		BIO_printf(out, "%*sFull Name:\n", indent, "");
+		print_gens(out, dpn->name.fullname, indent);
+		}
+	else
+		{
+		X509_NAME ntmp;
+		ntmp.entries = dpn->name.relativename;
+		BIO_printf(out, "%*sRelative Name:\n%*s",
+						indent, "", indent + 2, "");
+		X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE);
+		BIO_puts(out, "\n");
+		}
+	return 1;
+	}
+
+static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
+		   int indent)
+	{
+	ISSUING_DIST_POINT *idp = pidp;
+	if (idp->distpoint)
+		print_distpoint(out, idp->distpoint, indent);
+	if (idp->onlyuser > 0)
+		BIO_printf(out, "%*sOnly User Certificates\n", indent, "");
+	if (idp->onlyCA > 0)
+		BIO_printf(out, "%*sOnly CA Certificates\n", indent, "");
+	if (idp->indirectCRL > 0)
+		BIO_printf(out, "%*sIndirect CRL\n", indent, "");
+	if (idp->onlysomereasons)
+		print_reasons(out, "Only Some Reasons", 
+				idp->onlysomereasons, indent);
+	if (idp->onlyattr > 0)
+		BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, "");
+	if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0)
+		&& (idp->indirectCRL <= 0) && !idp->onlysomereasons
+		&& (idp->onlyattr <= 0))
+		BIO_printf(out, "%*s<EMPTY>\n", indent, "");
+		
+	return 1;
+	}
+
+static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
+		     int indent)
+	{
+	STACK_OF(DIST_POINT) *crld = pcrldp;
+	DIST_POINT *point;
+	int i;
+	for(i = 0; i < sk_DIST_POINT_num(crld); i++)
+		{
+		BIO_puts(out, "\n");
+		point = sk_DIST_POINT_value(crld, i);
+		if(point->distpoint)
+			print_distpoint(out, point->distpoint, indent);
+		if(point->reasons) 
+			print_reasons(out, "Reasons", point->reasons,
+								indent);
+		if(point->CRLissuer)
+			{
+			BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
+			print_gens(out, point->CRLissuer, indent);
+			}
+		}
+	return 1;
+	}
+
+int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname)
+	{
+	int i;
+	STACK_OF(X509_NAME_ENTRY) *frag;
+	X509_NAME_ENTRY *ne;
+	if (!dpn || (dpn->type != 1))
+		return 1;
+	frag = dpn->name.relativename;
+	dpn->dpname = X509_NAME_dup(iname);
+	if (!dpn->dpname)
+		return 0;
+	for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++)
+		{
+		ne = sk_X509_NAME_ENTRY_value(frag, i);
+		if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1))
+			{
+			X509_NAME_free(dpn->dpname);
+			dpn->dpname = NULL;
+			return 0;
+			}
+		}
+	/* generate cached encoding of name */
+	if (i2d_X509_NAME(dpn->dpname, NULL) < 0)
+		{
+		X509_NAME_free(dpn->dpname);
+		dpn->dpname = NULL;
+		return 0;
+		}
+	return 1;
+	}
diff --git a/openssl/crypto/x509v3/v3_enum.c b/openssl/crypto/x509v3/v3_enum.c
new file mode 100644
index 0000000..c0575e3
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_enum.c
@@ -0,0 +1,97 @@
+/* v3_enum.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509v3.h>
+
+static ENUMERATED_NAMES crl_reasons[] = {
+{CRL_REASON_UNSPECIFIED, 	 "Unspecified", "unspecified"},
+{CRL_REASON_KEY_COMPROMISE,	 "Key Compromise", "keyCompromise"},
+{CRL_REASON_CA_COMPROMISE,	 "CA Compromise", "CACompromise"},
+{CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", "affiliationChanged"},
+{CRL_REASON_SUPERSEDED, 	 "Superseded", "superseded"},
+{CRL_REASON_CESSATION_OF_OPERATION,
+			"Cessation Of Operation", "cessationOfOperation"},
+{CRL_REASON_CERTIFICATE_HOLD,	 "Certificate Hold", "certificateHold"},
+{CRL_REASON_REMOVE_FROM_CRL,	 "Remove From CRL", "removeFromCRL"},
+{CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", "privilegeWithdrawn"},
+{CRL_REASON_AA_COMPROMISE,	 "AA Compromise", "AACompromise"},
+{-1, NULL, NULL}
+};
+
+const X509V3_EXT_METHOD v3_crl_reason = { 
+NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED),
+0,0,0,0,
+(X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE,
+0,
+0,0,0,0,
+crl_reasons};
+
+
+char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method,
+	     ASN1_ENUMERATED *e)
+{
+	ENUMERATED_NAMES *enam;
+	long strval;
+	strval = ASN1_ENUMERATED_get(e);
+	for(enam = method->usr_data; enam->lname; enam++) {
+		if(strval == enam->bitnum) return BUF_strdup(enam->lname);
+	}
+	return i2s_ASN1_ENUMERATED(method, e);
+}
diff --git a/openssl/crypto/x509v3/v3_extku.c b/openssl/crypto/x509v3/v3_extku.c
new file mode 100644
index 0000000..1c66532
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_extku.c
@@ -0,0 +1,144 @@
+/* v3_extku.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
+				    X509V3_CTX *ctx,
+				    STACK_OF(CONF_VALUE) *nval);
+static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
+		void *eku, STACK_OF(CONF_VALUE) *extlist);
+
+const X509V3_EXT_METHOD v3_ext_ku = {
+	NID_ext_key_usage, 0,
+	ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
+	0,0,0,0,
+	0,0,
+	i2v_EXTENDED_KEY_USAGE,
+	v2i_EXTENDED_KEY_USAGE,
+	0,0,
+	NULL
+};
+
+/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */
+const X509V3_EXT_METHOD v3_ocsp_accresp = {
+	NID_id_pkix_OCSP_acceptableResponses, 0,
+	ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
+	0,0,0,0,
+	0,0,
+	i2v_EXTENDED_KEY_USAGE,
+	v2i_EXTENDED_KEY_USAGE,
+	0,0,
+	NULL
+};
+
+ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT)
+ASN1_ITEM_TEMPLATE_END(EXTENDED_KEY_USAGE)
+
+IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
+
+static STACK_OF(CONF_VALUE) *
+  i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, void *a,
+			 STACK_OF(CONF_VALUE) *ext_list)
+{
+	EXTENDED_KEY_USAGE *eku = a;
+	int i;
+	ASN1_OBJECT *obj;
+	char obj_tmp[80];
+	for(i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
+		obj = sk_ASN1_OBJECT_value(eku, i);
+		i2t_ASN1_OBJECT(obj_tmp, 80, obj);
+		X509V3_add_value(NULL, obj_tmp, &ext_list);
+	}
+	return ext_list;
+}
+
+static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
+				    X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+	EXTENDED_KEY_USAGE *extku;
+	char *extval;
+	ASN1_OBJECT *objtmp;
+	CONF_VALUE *val;
+	int i;
+
+	if(!(extku = sk_ASN1_OBJECT_new_null())) {
+		X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+		val = sk_CONF_VALUE_value(nval, i);
+		if(val->value) extval = val->value;
+		else extval = val->name;
+		if(!(objtmp = OBJ_txt2obj(extval, 0))) {
+			sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free);
+			X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE,X509V3_R_INVALID_OBJECT_IDENTIFIER);
+			X509V3_conf_err(val);
+			return NULL;
+		}
+		sk_ASN1_OBJECT_push(extku, objtmp);
+	}
+	return extku;
+}
diff --git a/openssl/crypto/x509v3/v3_genn.c b/openssl/crypto/x509v3/v3_genn.c
new file mode 100644
index 0000000..b628357
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_genn.c
@@ -0,0 +1,252 @@
+/* v3_genn.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+ASN1_SEQUENCE(OTHERNAME) = {
+	ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT),
+	/* Maybe have a true ANY DEFINED BY later */
+	ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0)
+} ASN1_SEQUENCE_END(OTHERNAME)
+
+IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME)
+
+ASN1_SEQUENCE(EDIPARTYNAME) = {
+	ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0),
+	ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1)
+} ASN1_SEQUENCE_END(EDIPARTYNAME)
+
+IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME)
+
+ASN1_CHOICE(GENERAL_NAME) = {
+	ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME),
+	ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL),
+	ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS),
+	/* Don't decode this */
+	ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400),
+	/* X509_NAME is a CHOICE type so use EXPLICIT */
+	ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME),
+	ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY),
+	ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI),
+	ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD),
+	ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID)
+} ASN1_CHOICE_END(GENERAL_NAME)
+
+IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME)
+
+ASN1_ITEM_TEMPLATE(GENERAL_NAMES) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME)
+ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES)
+
+IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES)
+
+GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a)
+	{
+	return (GENERAL_NAME *) ASN1_dup((i2d_of_void *) i2d_GENERAL_NAME,
+					 (d2i_of_void *) d2i_GENERAL_NAME,
+					 (char *) a);
+	}
+
+/* Returns 0 if they are equal, != 0 otherwise. */
+int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
+	{
+	int result = -1;
+
+	if (!a || !b || a->type != b->type) return -1;
+	switch(a->type)
+		{
+	case GEN_X400:
+	case GEN_EDIPARTY:
+		result = ASN1_TYPE_cmp(a->d.other, b->d.other);
+		break;
+
+	case GEN_OTHERNAME:
+		result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
+		break;
+
+	case GEN_EMAIL:
+	case GEN_DNS:
+	case GEN_URI:
+		result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
+		break;
+
+	case GEN_DIRNAME:
+		result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
+		break;
+
+	case GEN_IPADD:
+		result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
+		break;
+	
+	case GEN_RID:
+		result = OBJ_cmp(a->d.rid, b->d.rid);
+		break;
+		}
+	return result;
+	}
+
+/* Returns 0 if they are equal, != 0 otherwise. */
+int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b)
+	{
+	int result = -1;
+
+	if (!a || !b) return -1;
+	/* Check their type first. */
+	if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
+		return result;
+	/* Check the value. */
+	result = ASN1_TYPE_cmp(a->value, b->value);
+	return result;
+	}
+
+void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
+	{
+	switch(type)
+		{
+	case GEN_X400:
+	case GEN_EDIPARTY:
+		a->d.other = value;
+		break;
+
+	case GEN_OTHERNAME:
+		a->d.otherName = value;
+		break;
+
+	case GEN_EMAIL:
+	case GEN_DNS:
+	case GEN_URI:
+		a->d.ia5 = value;
+		break;
+
+	case GEN_DIRNAME:
+		a->d.dirn = value;
+		break;
+
+	case GEN_IPADD:
+		a->d.ip = value;
+		break;
+	
+	case GEN_RID:
+		a->d.rid = value;
+		break;
+		}
+	a->type = type;
+	}
+
+void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype)
+	{
+	if (ptype)
+		*ptype = a->type;
+	switch(a->type)
+		{
+	case GEN_X400:
+	case GEN_EDIPARTY:
+		return a->d.other;
+
+	case GEN_OTHERNAME:
+		return a->d.otherName;
+
+	case GEN_EMAIL:
+	case GEN_DNS:
+	case GEN_URI:
+		return a->d.ia5;
+
+	case GEN_DIRNAME:
+		return a->d.dirn;
+
+	case GEN_IPADD:
+		return a->d.ip;
+	
+	case GEN_RID:
+		return a->d.rid;
+
+	default:
+		return NULL;
+		}
+	}
+
+int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
+				ASN1_OBJECT *oid, ASN1_TYPE *value)
+	{
+	OTHERNAME *oth;
+	oth = OTHERNAME_new();
+	if (!oth)
+		return 0;
+	oth->type_id = oid;
+	oth->value = value;
+	GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
+	return 1;
+	}
+
+int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, 
+				ASN1_OBJECT **poid, ASN1_TYPE **pvalue)
+	{
+	if (gen->type != GEN_OTHERNAME)
+		return 0;
+	if (poid)
+		*poid = gen->d.otherName->type_id;
+	if (pvalue)
+		*pvalue = gen->d.otherName->value;
+	return 1;
+	}
+
diff --git a/openssl/crypto/x509v3/v3_ia5.c b/openssl/crypto/x509v3/v3_ia5.c
new file mode 100644
index 0000000..4ff12b5
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_ia5.c
@@ -0,0 +1,116 @@
+/* v3_ia5.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5);
+static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
+const X509V3_EXT_METHOD v3_ns_ia5_list[] = { 
+EXT_IA5STRING(NID_netscape_base_url),
+EXT_IA5STRING(NID_netscape_revocation_url),
+EXT_IA5STRING(NID_netscape_ca_revocation_url),
+EXT_IA5STRING(NID_netscape_renewal_url),
+EXT_IA5STRING(NID_netscape_ca_policy_url),
+EXT_IA5STRING(NID_netscape_ssl_server_name),
+EXT_IA5STRING(NID_netscape_comment),
+EXT_END
+};
+
+
+static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
+	     ASN1_IA5STRING *ia5)
+{
+	char *tmp;
+	if(!ia5 || !ia5->length) return NULL;
+	if(!(tmp = OPENSSL_malloc(ia5->length + 1))) {
+		X509V3err(X509V3_F_I2S_ASN1_IA5STRING,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	memcpy(tmp, ia5->data, ia5->length);
+	tmp[ia5->length] = 0;
+	return tmp;
+}
+
+static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
+	     X509V3_CTX *ctx, char *str)
+{
+	ASN1_IA5STRING *ia5;
+	if(!str) {
+		X509V3err(X509V3_F_S2I_ASN1_IA5STRING,X509V3_R_INVALID_NULL_ARGUMENT);
+		return NULL;
+	}
+	if(!(ia5 = M_ASN1_IA5STRING_new())) goto err;
+	if(!ASN1_STRING_set((ASN1_STRING *)ia5, (unsigned char*)str,
+			    strlen(str))) {
+		M_ASN1_IA5STRING_free(ia5);
+		goto err;
+	}
+#ifdef CHARSET_EBCDIC
+        ebcdic2ascii(ia5->data, ia5->data, ia5->length);
+#endif /*CHARSET_EBCDIC*/
+	return ia5;
+	err:
+	X509V3err(X509V3_F_S2I_ASN1_IA5STRING,ERR_R_MALLOC_FAILURE);
+	return NULL;
+}
+
diff --git a/openssl/crypto/x509v3/v3_info.c b/openssl/crypto/x509v3/v3_info.c
new file mode 100644
index 0000000..e1b8699
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_info.c
@@ -0,0 +1,193 @@
+/* v3_info.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
+				AUTHORITY_INFO_ACCESS *ainfo,
+						STACK_OF(CONF_VALUE) *ret);
+static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
+				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+
+const X509V3_EXT_METHOD v3_info =
+{ NID_info_access, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
+0,0,0,0,
+0,0,
+(X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS,
+(X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
+0,0,
+NULL};
+
+const X509V3_EXT_METHOD v3_sinfo =
+{ NID_sinfo_access, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
+0,0,0,0,
+0,0,
+(X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS,
+(X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
+0,0,
+NULL};
+
+ASN1_SEQUENCE(ACCESS_DESCRIPTION) = {
+	ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT),
+	ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME)
+} ASN1_SEQUENCE_END(ACCESS_DESCRIPTION)
+
+IMPLEMENT_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
+
+ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION)
+ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS)
+
+IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
+
+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
+				AUTHORITY_INFO_ACCESS *ainfo,
+						STACK_OF(CONF_VALUE) *ret)
+{
+	ACCESS_DESCRIPTION *desc;
+	int i,nlen;
+	char objtmp[80], *ntmp;
+	CONF_VALUE *vtmp;
+	for(i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
+		desc = sk_ACCESS_DESCRIPTION_value(ainfo, i);
+		ret = i2v_GENERAL_NAME(method, desc->location, ret);
+		if(!ret) break;
+		vtmp = sk_CONF_VALUE_value(ret, i);
+		i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method);
+		nlen = strlen(objtmp) + strlen(vtmp->name) + 5;
+		ntmp = OPENSSL_malloc(nlen);
+		if(!ntmp) {
+			X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS,
+					ERR_R_MALLOC_FAILURE);
+			return NULL;
+		}
+		BUF_strlcpy(ntmp, objtmp, nlen);
+		BUF_strlcat(ntmp, " - ", nlen);
+		BUF_strlcat(ntmp, vtmp->name, nlen);
+		OPENSSL_free(vtmp->name);
+		vtmp->name = ntmp;
+		
+	}
+	if(!ret) return sk_CONF_VALUE_new_null();
+	return ret;
+}
+
+static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
+				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+	AUTHORITY_INFO_ACCESS *ainfo = NULL;
+	CONF_VALUE *cnf, ctmp;
+	ACCESS_DESCRIPTION *acc;
+	int i, objlen;
+	char *objtmp, *ptmp;
+	if(!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) {
+		X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+		cnf = sk_CONF_VALUE_value(nval, i);
+		if(!(acc = ACCESS_DESCRIPTION_new())
+			|| !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) {
+			X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		ptmp = strchr(cnf->name, ';');
+		if(!ptmp) {
+			X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,X509V3_R_INVALID_SYNTAX);
+			goto err;
+		}
+		objlen = ptmp - cnf->name;
+		ctmp.name = ptmp + 1;
+		ctmp.value = cnf->value;
+		if(!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0))
+								 goto err; 
+		if(!(objtmp = OPENSSL_malloc(objlen + 1))) {
+			X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		strncpy(objtmp, cnf->name, objlen);
+		objtmp[objlen] = 0;
+		acc->method = OBJ_txt2obj(objtmp, 0);
+		if(!acc->method) {
+			X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,X509V3_R_BAD_OBJECT);
+			ERR_add_error_data(2, "value=", objtmp);
+			OPENSSL_free(objtmp);
+			goto err;
+		}
+		OPENSSL_free(objtmp);
+
+	}
+	return ainfo;
+	err:
+	sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free);
+	return NULL;
+}
+
+int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION* a)
+        {
+	i2a_ASN1_OBJECT(bp, a->method);
+#ifdef UNDEF
+	i2a_GENERAL_NAME(bp, a->location);
+#endif
+	return 2;
+	}
diff --git a/openssl/crypto/x509v3/v3_int.c b/openssl/crypto/x509v3/v3_int.c
new file mode 100644
index 0000000..4bfd14c
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_int.c
@@ -0,0 +1,89 @@
+/* v3_int.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509v3.h>
+
+const X509V3_EXT_METHOD v3_crl_num = { 
+	NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER),
+	0,0,0,0,
+	(X509V3_EXT_I2S)i2s_ASN1_INTEGER,
+	0,
+	0,0,0,0, NULL};
+
+const X509V3_EXT_METHOD v3_delta_crl = { 
+	NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER),
+	0,0,0,0,
+	(X509V3_EXT_I2S)i2s_ASN1_INTEGER,
+	0,
+	0,0,0,0, NULL};
+
+static void * s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, char *value)
+	{
+	return s2i_ASN1_INTEGER(meth, value);
+	}
+
+const X509V3_EXT_METHOD v3_inhibit_anyp = { 
+	NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER),
+	0,0,0,0,
+	(X509V3_EXT_I2S)i2s_ASN1_INTEGER,
+	(X509V3_EXT_S2I)s2i_asn1_int,
+	0,0,0,0, NULL};
+
+
diff --git a/openssl/crypto/x509v3/v3_lib.c b/openssl/crypto/x509v3/v3_lib.c
new file mode 100644
index 0000000..0f1e1d4
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_lib.c
@@ -0,0 +1,309 @@
+/* v3_lib.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* X509 v3 extension utilities */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+#include "ext_dat.h"
+
+static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL;
+
+static int ext_cmp(const X509V3_EXT_METHOD * const *a,
+		const X509V3_EXT_METHOD * const *b);
+static void ext_list_free(X509V3_EXT_METHOD *ext);
+
+int X509V3_EXT_add(X509V3_EXT_METHOD *ext)
+{
+	if(!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp))) {
+		X509V3err(X509V3_F_X509V3_EXT_ADD,ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	if(!sk_X509V3_EXT_METHOD_push(ext_list, ext)) {
+		X509V3err(X509V3_F_X509V3_EXT_ADD,ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	return 1;
+}
+
+static int ext_cmp(const X509V3_EXT_METHOD * const *a,
+		   const X509V3_EXT_METHOD * const *b)
+{
+	return ((*a)->ext_nid - (*b)->ext_nid);
+}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *, const X509V3_EXT_METHOD *,
+			   ext);
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *,
+			     const X509V3_EXT_METHOD *, ext);
+
+const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid)
+{
+	X509V3_EXT_METHOD tmp;
+	const X509V3_EXT_METHOD *t = &tmp, * const *ret;
+	int idx;
+	if(nid < 0) return NULL;
+	tmp.ext_nid = nid;
+	ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT);
+	if(ret) return *ret;
+	if(!ext_list) return NULL;
+	idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp);
+	if(idx == -1) return NULL;
+	return sk_X509V3_EXT_METHOD_value(ext_list, idx);
+}
+
+const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext)
+{
+	int nid;
+	if((nid = OBJ_obj2nid(ext->object)) == NID_undef) return NULL;
+	return X509V3_EXT_get_nid(nid);
+}
+
+
+int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist)
+{
+	for(;extlist->ext_nid!=-1;extlist++) 
+			if(!X509V3_EXT_add(extlist)) return 0;
+	return 1;
+}
+
+int X509V3_EXT_add_alias(int nid_to, int nid_from)
+{
+	const X509V3_EXT_METHOD *ext;
+	X509V3_EXT_METHOD *tmpext;
+
+	if(!(ext = X509V3_EXT_get_nid(nid_from))) {
+		X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS,X509V3_R_EXTENSION_NOT_FOUND);
+		return 0;
+	}
+	if(!(tmpext = (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) {
+		X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS,ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	*tmpext = *ext;
+	tmpext->ext_nid = nid_to;
+	tmpext->ext_flags |= X509V3_EXT_DYNAMIC;
+	return X509V3_EXT_add(tmpext);
+}
+
+void X509V3_EXT_cleanup(void)
+{
+	sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free);
+	ext_list = NULL;
+}
+
+static void ext_list_free(X509V3_EXT_METHOD *ext)
+{
+	if(ext->ext_flags & X509V3_EXT_DYNAMIC) OPENSSL_free(ext);
+}
+
+/* Legacy function: we don't need to add standard extensions
+ * any more because they are now kept in ext_dat.h.
+ */
+
+int X509V3_add_standard_extensions(void)
+{
+	return 1;
+}
+
+/* Return an extension internal structure */
+
+void *X509V3_EXT_d2i(X509_EXTENSION *ext)
+{
+	const X509V3_EXT_METHOD *method;
+	const unsigned char *p;
+
+	if(!(method = X509V3_EXT_get(ext))) return NULL;
+	p = ext->value->data;
+	if(method->it) return ASN1_item_d2i(NULL, &p, ext->value->length, ASN1_ITEM_ptr(method->it));
+	return method->d2i(NULL, &p, ext->value->length);
+}
+
+/* Get critical flag and decoded version of extension from a NID.
+ * The "idx" variable returns the last found extension and can
+ * be used to retrieve multiple extensions of the same NID.
+ * However multiple extensions with the same NID is usually
+ * due to a badly encoded certificate so if idx is NULL we
+ * choke if multiple extensions exist.
+ * The "crit" variable is set to the critical value.
+ * The return value is the decoded extension or NULL on
+ * error. The actual error can have several different causes,
+ * the value of *crit reflects the cause:
+ * >= 0, extension found but not decoded (reflects critical value).
+ * -1 extension not found.
+ * -2 extension occurs more than once.
+ */
+
+void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx)
+{
+	int lastpos, i;
+	X509_EXTENSION *ex, *found_ex = NULL;
+	if(!x) {
+		if(idx) *idx = -1;
+		if(crit) *crit = -1;
+		return NULL;
+	}
+	if(idx) lastpos = *idx + 1;
+	else lastpos = 0;
+	if(lastpos < 0) lastpos = 0;
+	for(i = lastpos; i < sk_X509_EXTENSION_num(x); i++)
+	{
+		ex = sk_X509_EXTENSION_value(x, i);
+		if(OBJ_obj2nid(ex->object) == nid) {
+			if(idx) {
+				*idx = i;
+				found_ex = ex;
+				break;
+			} else if(found_ex) {
+				/* Found more than one */
+				if(crit) *crit = -2;
+				return NULL;
+			}
+			found_ex = ex;
+		}
+	}
+	if(found_ex) {
+		/* Found it */
+		if(crit) *crit = X509_EXTENSION_get_critical(found_ex);
+		return X509V3_EXT_d2i(found_ex);
+	}
+
+	/* Extension not found */
+	if(idx) *idx = -1;
+	if(crit) *crit = -1;
+	return NULL;
+}
+
+/* This function is a general extension append, replace and delete utility.
+ * The precise operation is governed by the 'flags' value. The 'crit' and
+ * 'value' arguments (if relevant) are the extensions internal structure.
+ */
+
+int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
+					int crit, unsigned long flags)
+{
+	int extidx = -1;
+	int errcode;
+	X509_EXTENSION *ext, *extmp;
+	unsigned long ext_op = flags & X509V3_ADD_OP_MASK;
+
+	/* If appending we don't care if it exists, otherwise
+	 * look for existing extension.
+	 */
+	if(ext_op != X509V3_ADD_APPEND)
+		extidx = X509v3_get_ext_by_NID(*x, nid, -1);
+
+	/* See if extension exists */
+	if(extidx >= 0) {
+		/* If keep existing, nothing to do */
+		if(ext_op == X509V3_ADD_KEEP_EXISTING)
+			return 1;
+		/* If default then its an error */
+		if(ext_op == X509V3_ADD_DEFAULT) {
+			errcode = X509V3_R_EXTENSION_EXISTS;
+			goto err;
+		}
+		/* If delete, just delete it */
+		if(ext_op == X509V3_ADD_DELETE) {
+			if(!sk_X509_EXTENSION_delete(*x, extidx)) return -1;
+			return 1;
+		}
+	} else {
+		/* If replace existing or delete, error since 
+		 * extension must exist
+		 */
+		if((ext_op == X509V3_ADD_REPLACE_EXISTING) ||
+		   (ext_op == X509V3_ADD_DELETE)) {
+			errcode = X509V3_R_EXTENSION_NOT_FOUND;
+			goto err;
+		}
+	}
+
+	/* If we get this far then we have to create an extension:
+	 * could have some flags for alternative encoding schemes...
+	 */
+
+	ext = X509V3_EXT_i2d(nid, crit, value);
+
+	if(!ext) {
+		X509V3err(X509V3_F_X509V3_ADD1_I2D, X509V3_R_ERROR_CREATING_EXTENSION);
+		return 0;
+	}
+
+	/* If extension exists replace it.. */
+	if(extidx >= 0) {
+		extmp = sk_X509_EXTENSION_value(*x, extidx);
+		X509_EXTENSION_free(extmp);
+		if(!sk_X509_EXTENSION_set(*x, extidx, ext)) return -1;
+		return 1;
+	}
+
+	if(!*x && !(*x = sk_X509_EXTENSION_new_null())) return -1;
+	if(!sk_X509_EXTENSION_push(*x, ext)) return -1;
+
+	return 1;
+
+	err:
+	if(!(flags & X509V3_ADD_SILENT))
+		X509V3err(X509V3_F_X509V3_ADD1_I2D, errcode);
+	return 0;
+}
+
+IMPLEMENT_STACK_OF(X509V3_EXT_METHOD)
diff --git a/openssl/crypto/x509v3/v3_ncons.c b/openssl/crypto/x509v3/v3_ncons.c
new file mode 100644
index 0000000..a01dc64
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_ncons.c
@@ -0,0 +1,505 @@
+/* v3_ncons.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
+				  X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, 
+				void *a, BIO *bp, int ind);
+static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
+				   STACK_OF(GENERAL_SUBTREE) *trees,
+				   BIO *bp, int ind, char *name);
+static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip);
+
+static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc);
+static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen);
+static int nc_dn(X509_NAME *sub, X509_NAME *nm);
+static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns);
+static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml);
+static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base);
+
+const X509V3_EXT_METHOD v3_name_constraints = {
+	NID_name_constraints, 0,
+	ASN1_ITEM_ref(NAME_CONSTRAINTS),
+	0,0,0,0,
+	0,0,
+	0, v2i_NAME_CONSTRAINTS,
+	i2r_NAME_CONSTRAINTS,0,
+	NULL
+};
+
+ASN1_SEQUENCE(GENERAL_SUBTREE) = {
+	ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME),
+	ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0),
+	ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1)
+} ASN1_SEQUENCE_END(GENERAL_SUBTREE)
+
+ASN1_SEQUENCE(NAME_CONSTRAINTS) = {
+	ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees,
+							GENERAL_SUBTREE, 0),
+	ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees,
+							GENERAL_SUBTREE, 1),
+} ASN1_SEQUENCE_END(NAME_CONSTRAINTS)
+	
+
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
+
+static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
+				  X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+	{
+	int i;
+	CONF_VALUE tval, *val;
+	STACK_OF(GENERAL_SUBTREE) **ptree = NULL;
+	NAME_CONSTRAINTS *ncons = NULL;
+	GENERAL_SUBTREE *sub = NULL;
+	ncons = NAME_CONSTRAINTS_new();
+	if (!ncons)
+		goto memerr;
+	for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
+		{
+		val = sk_CONF_VALUE_value(nval, i);
+		if (!strncmp(val->name, "permitted", 9) && val->name[9])
+			{
+			ptree = &ncons->permittedSubtrees;
+			tval.name = val->name + 10;
+			}
+		else if (!strncmp(val->name, "excluded", 8) && val->name[8])
+			{
+			ptree = &ncons->excludedSubtrees;
+			tval.name = val->name + 9;
+			}
+		else
+			{
+			X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, X509V3_R_INVALID_SYNTAX);
+			goto err;
+			}
+		tval.value = val->value;
+		sub = GENERAL_SUBTREE_new();
+		if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1))
+			goto err;
+		if (!*ptree)
+			*ptree = sk_GENERAL_SUBTREE_new_null();
+		if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub))
+			goto memerr;
+		sub = NULL;
+		}
+
+	return ncons;
+
+	memerr:
+	X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+	err:
+	if (ncons)
+		NAME_CONSTRAINTS_free(ncons);
+	if (sub)
+		GENERAL_SUBTREE_free(sub);
+
+	return NULL;
+	}
+			
+
+	
+
+static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
+				BIO *bp, int ind)
+	{
+	NAME_CONSTRAINTS *ncons = a;
+	do_i2r_name_constraints(method, ncons->permittedSubtrees,
+					bp, ind, "Permitted");
+	do_i2r_name_constraints(method, ncons->excludedSubtrees,
+					bp, ind, "Excluded");
+	return 1;
+	}
+
+static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
+				   STACK_OF(GENERAL_SUBTREE) *trees,
+				   BIO *bp, int ind, char *name)
+	{
+	GENERAL_SUBTREE *tree;
+	int i;
+	if (sk_GENERAL_SUBTREE_num(trees) > 0)
+		BIO_printf(bp, "%*s%s:\n", ind, "", name);
+	for(i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++)
+		{
+		tree = sk_GENERAL_SUBTREE_value(trees, i);
+		BIO_printf(bp, "%*s", ind + 2, "");
+		if (tree->base->type == GEN_IPADD)
+			print_nc_ipadd(bp, tree->base->d.ip);
+		else
+			GENERAL_NAME_print(bp, tree->base);
+		BIO_puts(bp, "\n");
+		}
+	return 1;
+	}
+
+static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
+	{
+	int i, len;
+	unsigned char *p;
+	p = ip->data;
+	len = ip->length;
+	BIO_puts(bp, "IP:");
+	if(len == 8)
+		{
+		BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d",
+				p[0], p[1], p[2], p[3],
+				p[4], p[5], p[6], p[7]);
+		}
+	else if(len == 32)
+		{
+		for (i = 0; i < 16; i++)
+			{
+			BIO_printf(bp, "%X", p[0] << 8 | p[1]);
+			p += 2;
+			if (i == 7)
+				BIO_puts(bp, "/");
+			else if (i != 15)
+				BIO_puts(bp, ":");
+			}
+		}
+	else
+		BIO_printf(bp, "IP Address:<invalid>");
+	return 1;
+	}
+
+/* Check a certificate conforms to a specified set of constraints.
+ * Return values:
+ *  X509_V_OK: All constraints obeyed.
+ *  X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation.
+ *  X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation.
+ *  X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type.
+ *  X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:  Unsupported constraint type.
+ *  X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax.
+ *  X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name
+
+ */
+
+int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
+	{
+	int r, i;
+	X509_NAME *nm;
+
+	nm = X509_get_subject_name(x);
+
+	if (X509_NAME_entry_count(nm) > 0)
+		{
+		GENERAL_NAME gntmp;
+		gntmp.type = GEN_DIRNAME;
+		gntmp.d.directoryName = nm;
+
+		r = nc_match(&gntmp, nc);
+
+		if (r != X509_V_OK)
+			return r;
+
+		gntmp.type = GEN_EMAIL;
+
+
+		/* Process any email address attributes in subject name */
+
+		for (i = -1;;)
+			{
+			X509_NAME_ENTRY *ne;
+			i = X509_NAME_get_index_by_NID(nm,
+						       NID_pkcs9_emailAddress,
+						       i);
+			if (i == -1)
+				break;
+			ne = X509_NAME_get_entry(nm, i);
+			gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne);
+			if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING)
+				return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+
+			r = nc_match(&gntmp, nc);
+
+			if (r != X509_V_OK)
+				return r;
+			}
+		
+		}
+
+	for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++)
+		{
+		GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i);
+		r = nc_match(gen, nc);
+		if (r != X509_V_OK)
+			return r;
+		}
+
+	return X509_V_OK;
+
+	}
+
+static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
+	{
+	GENERAL_SUBTREE *sub;
+	int i, r, match = 0;
+
+	/* Permitted subtrees: if any subtrees exist of matching the type
+	 * at least one subtree must match.
+	 */
+
+	for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++)
+		{
+		sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
+		if (gen->type != sub->base->type)
+			continue;
+		if (sub->minimum || sub->maximum)
+			return X509_V_ERR_SUBTREE_MINMAX;
+		/* If we already have a match don't bother trying any more */
+		if (match == 2)
+			continue;
+		if (match == 0)
+			match = 1;
+		r = nc_match_single(gen, sub->base);
+		if (r == X509_V_OK)
+			match = 2;
+		else if (r != X509_V_ERR_PERMITTED_VIOLATION)
+			return r;
+		}
+
+	if (match == 1)
+		return X509_V_ERR_PERMITTED_VIOLATION;
+
+	/* Excluded subtrees: must not match any of these */
+
+	for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++)
+		{
+		sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
+		if (gen->type != sub->base->type)
+			continue;
+		if (sub->minimum || sub->maximum)
+			return X509_V_ERR_SUBTREE_MINMAX;
+
+		r = nc_match_single(gen, sub->base);
+		if (r == X509_V_OK)
+			return X509_V_ERR_EXCLUDED_VIOLATION;
+		else if (r != X509_V_ERR_PERMITTED_VIOLATION)
+			return r;
+
+		}
+
+	return X509_V_OK;
+
+	}
+
+static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base)
+	{
+	switch(base->type)
+		{
+		case GEN_DIRNAME:
+		return nc_dn(gen->d.directoryName, base->d.directoryName);
+
+		case GEN_DNS:
+		return nc_dns(gen->d.dNSName, base->d.dNSName);
+
+		case GEN_EMAIL:
+		return nc_email(gen->d.rfc822Name, base->d.rfc822Name);
+
+		case GEN_URI:
+		return nc_uri(gen->d.uniformResourceIdentifier,
+					base->d.uniformResourceIdentifier);
+
+		default:
+		return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
+		}
+
+	}
+
+/* directoryName name constraint matching.
+ * The canonical encoding of X509_NAME makes this comparison easy. It is
+ * matched if the subtree is a subset of the name.
+ */
+
+static int nc_dn(X509_NAME *nm, X509_NAME *base)
+	{
+	/* Ensure canonical encodings are up to date.  */
+	if (nm->modified && i2d_X509_NAME(nm, NULL) < 0)
+		return X509_V_ERR_OUT_OF_MEM;
+	if (base->modified && i2d_X509_NAME(base, NULL) < 0)
+		return X509_V_ERR_OUT_OF_MEM;
+	if (base->canon_enclen > nm->canon_enclen)
+		return X509_V_ERR_PERMITTED_VIOLATION;
+	if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen))
+		return X509_V_ERR_PERMITTED_VIOLATION;
+	return X509_V_OK;
+	}
+
+static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base)
+	{
+	char *baseptr = (char *)base->data;
+	char *dnsptr = (char *)dns->data;
+	/* Empty matches everything */
+	if (!*baseptr)
+		return X509_V_OK;
+	/* Otherwise can add zero or more components on the left so
+	 * compare RHS and if dns is longer and expect '.' as preceding
+	 * character.
+	 */
+	if (dns->length > base->length)
+		{
+		dnsptr += dns->length - base->length;
+		if (dnsptr[-1] != '.')
+			return X509_V_ERR_PERMITTED_VIOLATION;
+		}
+
+	if (strcasecmp(baseptr, dnsptr))
+			return X509_V_ERR_PERMITTED_VIOLATION;
+
+	return X509_V_OK;
+
+	}
+
+static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base)
+	{
+	const char *baseptr = (char *)base->data;
+	const char *emlptr = (char *)eml->data;
+
+	const char *baseat = strchr(baseptr, '@');
+	const char *emlat = strchr(emlptr, '@');
+	if (!emlat)
+		return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+	/* Special case: inital '.' is RHS match */
+	if (!baseat && (*baseptr == '.'))
+		{
+		if (eml->length > base->length)
+			{
+			emlptr += eml->length - base->length;
+			if (!strcasecmp(baseptr, emlptr))
+				return X509_V_OK;
+			}
+		return X509_V_ERR_PERMITTED_VIOLATION;
+		}
+
+	/* If we have anything before '@' match local part */
+
+	if (baseat)
+		{
+		if (baseat != baseptr)
+			{
+			if ((baseat - baseptr) != (emlat - emlptr))
+				return X509_V_ERR_PERMITTED_VIOLATION;
+			/* Case sensitive match of local part */
+			if (strncmp(baseptr, emlptr, emlat - emlptr))
+				return X509_V_ERR_PERMITTED_VIOLATION;
+			}
+		/* Position base after '@' */
+		baseptr = baseat + 1;
+		}
+	emlptr = emlat + 1;
+	/* Just have hostname left to match: case insensitive */
+	if (strcasecmp(baseptr, emlptr))
+		return X509_V_ERR_PERMITTED_VIOLATION;
+
+	return X509_V_OK;
+
+	}
+
+static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base)
+	{
+	const char *baseptr = (char *)base->data;
+	const char *hostptr = (char *)uri->data;
+	const char *p = strchr(hostptr, ':');
+	int hostlen;
+	/* Check for foo:// and skip past it */
+	if (!p || (p[1] != '/') || (p[2] != '/'))
+		return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+	hostptr = p + 3;
+
+	/* Determine length of hostname part of URI */
+
+	/* Look for a port indicator as end of hostname first */
+
+	p = strchr(hostptr, ':');
+	/* Otherwise look for trailing slash */
+	if (!p)
+		p = strchr(hostptr, '/');
+
+	if (!p)
+		hostlen = strlen(hostptr);
+	else
+		hostlen = p - hostptr;
+
+	if (hostlen == 0)
+		return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+
+	/* Special case: inital '.' is RHS match */
+	if (*baseptr == '.')
+		{
+		if (hostlen > base->length)
+			{
+			p = hostptr + hostlen - base->length;
+			if (!strncasecmp(p, baseptr, base->length))
+				return X509_V_OK;
+			}
+		return X509_V_ERR_PERMITTED_VIOLATION;
+		}
+
+	if ((base->length != (int)hostlen) || strncasecmp(hostptr, baseptr, hostlen))
+		return X509_V_ERR_PERMITTED_VIOLATION;
+
+	return X509_V_OK;
+
+	}
diff --git a/openssl/crypto/x509v3/v3_ocsp.c b/openssl/crypto/x509v3/v3_ocsp.c
new file mode 100644
index 0000000..0c165af
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_ocsp.c
@@ -0,0 +1,289 @@
+/* v3_ocsp.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef OPENSSL_NO_OCSP
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/ocsp.h>
+#include <openssl/x509v3.h>
+
+/* OCSP extensions and a couple of CRL entry extensions
+ */
+
+static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce,
+			  BIO *out, int indent);
+static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce,
+			    BIO *out, int indent);
+static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out,
+		      int indent);
+
+static void *ocsp_nonce_new(void);
+static int i2d_ocsp_nonce(void *a, unsigned char **pp);
+static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length);
+static void ocsp_nonce_free(void *a);
+static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
+			  BIO *out, int indent);
+
+static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method,
+			    void *nocheck, BIO *out, int indent);
+static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+			      const char *str);
+static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
+			       BIO *bp, int ind);
+
+const X509V3_EXT_METHOD v3_ocsp_crlid = {
+	NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID),
+	0,0,0,0,
+	0,0,
+	0,0,
+	i2r_ocsp_crlid,0,
+	NULL
+};
+
+const X509V3_EXT_METHOD v3_ocsp_acutoff = {
+	NID_id_pkix_OCSP_archiveCutoff, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
+	0,0,0,0,
+	0,0,
+	0,0,
+	i2r_ocsp_acutoff,0,
+	NULL
+};
+
+const X509V3_EXT_METHOD v3_crl_invdate = {
+	NID_invalidity_date, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
+	0,0,0,0,
+	0,0,
+	0,0,
+	i2r_ocsp_acutoff,0,
+	NULL
+};
+
+const X509V3_EXT_METHOD v3_crl_hold = {
+	NID_hold_instruction_code, 0, ASN1_ITEM_ref(ASN1_OBJECT),
+	0,0,0,0,
+	0,0,
+	0,0,
+	i2r_object,0,
+	NULL
+};
+
+const X509V3_EXT_METHOD v3_ocsp_nonce = {
+	NID_id_pkix_OCSP_Nonce, 0, NULL,
+	ocsp_nonce_new,
+	ocsp_nonce_free,
+	d2i_ocsp_nonce,
+	i2d_ocsp_nonce,
+	0,0,
+	0,0,
+	i2r_ocsp_nonce,0,
+	NULL
+};
+
+const X509V3_EXT_METHOD v3_ocsp_nocheck = {
+	NID_id_pkix_OCSP_noCheck, 0, ASN1_ITEM_ref(ASN1_NULL),
+	0,0,0,0,
+	0,s2i_ocsp_nocheck,
+	0,0,
+	i2r_ocsp_nocheck,0,
+	NULL
+};
+
+const X509V3_EXT_METHOD v3_ocsp_serviceloc = {
+	NID_id_pkix_OCSP_serviceLocator, 0, ASN1_ITEM_ref(OCSP_SERVICELOC),
+	0,0,0,0,
+	0,0,
+	0,0,
+	i2r_ocsp_serviceloc,0,
+	NULL
+};
+
+static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp,
+			  int ind)
+{
+	OCSP_CRLID *a = in;
+	if (a->crlUrl)
+	        {
+		if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0) goto err;
+		if (!ASN1_STRING_print(bp, (ASN1_STRING*)a->crlUrl)) goto err;
+		if (BIO_write(bp, "\n", 1) <= 0) goto err;
+		}
+	if (a->crlNum)
+	        {
+		if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0) goto err;
+		if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0) goto err;
+		if (BIO_write(bp, "\n", 1) <= 0) goto err;
+		}
+	if (a->crlTime)
+	        {
+		if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0) goto err;
+		if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime)) goto err;
+		if (BIO_write(bp, "\n", 1) <= 0) goto err;
+		}
+	return 1;
+	err:
+	return 0;
+}
+
+static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff,
+			    BIO *bp, int ind)
+{
+	if (BIO_printf(bp, "%*s", ind, "") <= 0) return 0;
+	if(!ASN1_GENERALIZEDTIME_print(bp, cutoff)) return 0;
+	return 1;
+}
+
+
+static int i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp,
+		      int ind)
+{
+	if (BIO_printf(bp, "%*s", ind, "") <= 0) return 0;
+	if(i2a_ASN1_OBJECT(bp, oid) <= 0) return 0;
+	return 1;
+}
+
+/* OCSP nonce. This is needs special treatment because it doesn't have
+ * an ASN1 encoding at all: it just contains arbitrary data.
+ */
+
+static void *ocsp_nonce_new(void)
+{
+	return ASN1_OCTET_STRING_new();
+}
+
+static int i2d_ocsp_nonce(void *a, unsigned char **pp)
+{
+	ASN1_OCTET_STRING *os = a;
+	if(pp) {
+		memcpy(*pp, os->data, os->length);
+		*pp += os->length;
+	}
+	return os->length;
+}
+
+static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length)
+{
+	ASN1_OCTET_STRING *os, **pos;
+	pos = a;
+	if(!pos || !*pos) os = ASN1_OCTET_STRING_new();
+	else os = *pos;
+	if(!ASN1_OCTET_STRING_set(os, *pp, length)) goto err;
+
+	*pp += length;
+
+	if(pos) *pos = os;
+	return os;
+
+	err:
+	if(os && (!pos || (*pos != os))) M_ASN1_OCTET_STRING_free(os);
+	OCSPerr(OCSP_F_D2I_OCSP_NONCE, ERR_R_MALLOC_FAILURE);
+	return NULL;
+}
+
+static void ocsp_nonce_free(void *a)
+{
+	M_ASN1_OCTET_STRING_free(a);
+}
+
+static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
+			  BIO *out, int indent)
+{
+	if(BIO_printf(out, "%*s", indent, "") <= 0) return 0;
+	if(i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0) return 0;
+	return 1;
+}
+
+/* Nocheck is just a single NULL. Don't print anything and always set it */
+
+static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck,
+			    BIO *out, int indent)
+{
+	return 1;
+}
+
+static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+			      const char *str)
+{
+	return ASN1_NULL_new();
+}
+
+static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
+			       BIO *bp, int ind)
+        {
+	int i;
+	OCSP_SERVICELOC *a = in;
+	ACCESS_DESCRIPTION *ad;
+
+        if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0) goto err;
+        if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0) goto err;
+	for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++)
+	        {
+				ad = sk_ACCESS_DESCRIPTION_value(a->locator,i);
+				if (BIO_printf(bp, "\n%*s", (2*ind), "") <= 0) 
+					goto err;
+				if(i2a_ASN1_OBJECT(bp, ad->method) <= 0) goto err;
+				if(BIO_puts(bp, " - ") <= 0) goto err;
+				if(GENERAL_NAME_print(bp, ad->location) <= 0) goto err;
+		}
+	return 1;
+err:
+	return 0;
+	}
+#endif
diff --git a/openssl/crypto/x509v3/v3_pci.c b/openssl/crypto/x509v3/v3_pci.c
new file mode 100644
index 0000000..0dcfa00
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_pci.c
@@ -0,0 +1,328 @@
+/* v3_pci.c -*- mode:C; c-file-style: "eay" -*- */
+/* Contributed to the OpenSSL Project 2004
+ * by Richard Levitte (richard@levitte.org)
+ */
+/* Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext,
+	BIO *out, int indent);
+static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
+	X509V3_CTX *ctx, char *str);
+
+const X509V3_EXT_METHOD v3_pci =
+	{ NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
+	  0,0,0,0,
+	  0,0,
+	  NULL, NULL,
+	  (X509V3_EXT_I2R)i2r_pci,
+	  (X509V3_EXT_R2I)r2i_pci,
+	  NULL,
+	};
+
+static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci,
+	BIO *out, int indent)
+	{
+	BIO_printf(out, "%*sPath Length Constraint: ", indent, "");
+	if (pci->pcPathLengthConstraint)
+	  i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint);
+	else
+	  BIO_printf(out, "infinite");
+	BIO_puts(out, "\n");
+	BIO_printf(out, "%*sPolicy Language: ", indent, "");
+	i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage);
+	BIO_puts(out, "\n");
+	if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data)
+	  BIO_printf(out, "%*sPolicy Text: %s\n", indent, "",
+		     pci->proxyPolicy->policy->data);
+	return 1;
+	}
+
+static int process_pci_value(CONF_VALUE *val,
+	ASN1_OBJECT **language, ASN1_INTEGER **pathlen,
+	ASN1_OCTET_STRING **policy)
+	{
+	int free_policy = 0;
+
+	if (strcmp(val->name, "language") == 0)
+		{
+		if (*language)
+			{
+			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
+			X509V3_conf_err(val);
+			return 0;
+			}
+		if (!(*language = OBJ_txt2obj(val->value, 0)))
+			{
+			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INVALID_OBJECT_IDENTIFIER);
+			X509V3_conf_err(val);
+			return 0;
+			}
+		}
+	else if (strcmp(val->name, "pathlen") == 0)
+		{
+		if (*pathlen)
+			{
+			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
+			X509V3_conf_err(val);
+			return 0;
+			}
+		if (!X509V3_get_value_int(val, pathlen))
+			{
+			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH);
+			X509V3_conf_err(val);
+			return 0;
+			}
+		}
+	else if (strcmp(val->name, "policy") == 0)
+		{
+		unsigned char *tmp_data = NULL;
+		long val_len;
+		if (!*policy)
+			{
+			*policy = ASN1_OCTET_STRING_new();
+			if (!*policy)
+				{
+				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
+				X509V3_conf_err(val);
+				return 0;
+				}
+			free_policy = 1;
+			}
+		if (strncmp(val->value, "hex:", 4) == 0)
+			{
+			unsigned char *tmp_data2 =
+				string_to_hex(val->value + 4, &val_len);
+
+			if (!tmp_data2) 
+				{
+				X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_ILLEGAL_HEX_DIGIT);
+				X509V3_conf_err(val);
+				goto err;
+				}
+
+			tmp_data = OPENSSL_realloc((*policy)->data,
+				(*policy)->length + val_len + 1);
+			if (tmp_data)
+				{
+				(*policy)->data = tmp_data;
+				memcpy(&(*policy)->data[(*policy)->length],
+					tmp_data2, val_len);
+				(*policy)->length += val_len;
+				(*policy)->data[(*policy)->length] = '\0';
+				}
+			else
+				{
+				OPENSSL_free(tmp_data2);
+				/* realloc failure implies the original data space is b0rked too! */
+				(*policy)->data = NULL;
+				(*policy)->length = 0;
+				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
+				X509V3_conf_err(val);
+				goto err;
+				}
+			OPENSSL_free(tmp_data2);
+			}
+		else if (strncmp(val->value, "file:", 5) == 0)
+			{
+			unsigned char buf[2048];
+			int n;
+			BIO *b = BIO_new_file(val->value + 5, "r");
+			if (!b)
+				{
+				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB);
+				X509V3_conf_err(val);
+				goto err;
+				}
+			while((n = BIO_read(b, buf, sizeof(buf))) > 0
+				|| (n == 0 && BIO_should_retry(b)))
+				{
+				if (!n) continue;
+
+				tmp_data = OPENSSL_realloc((*policy)->data,
+					(*policy)->length + n + 1);
+
+				if (!tmp_data)
+					break;
+
+				(*policy)->data = tmp_data;
+				memcpy(&(*policy)->data[(*policy)->length],
+					buf, n);
+				(*policy)->length += n;
+				(*policy)->data[(*policy)->length] = '\0';
+				}
+			BIO_free_all(b);
+
+			if (n < 0)
+				{
+				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB);
+				X509V3_conf_err(val);
+				goto err;
+				}
+			}
+		else if (strncmp(val->value, "text:", 5) == 0)
+			{
+			val_len = strlen(val->value + 5);
+			tmp_data = OPENSSL_realloc((*policy)->data,
+				(*policy)->length + val_len + 1);
+			if (tmp_data)
+				{
+				(*policy)->data = tmp_data;
+				memcpy(&(*policy)->data[(*policy)->length],
+					val->value + 5, val_len);
+				(*policy)->length += val_len;
+				(*policy)->data[(*policy)->length] = '\0';
+				}
+			else
+				{
+				/* realloc failure implies the original data space is b0rked too! */
+				(*policy)->data = NULL;
+				(*policy)->length = 0;
+				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
+				X509V3_conf_err(val);
+				goto err;
+				}
+			}
+		else
+			{
+			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
+			X509V3_conf_err(val);
+			goto err;
+			}
+		if (!tmp_data)
+			{
+			X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
+			X509V3_conf_err(val);
+			goto err;
+			}
+		}
+	return 1;
+err:
+	if (free_policy)
+		{
+		ASN1_OCTET_STRING_free(*policy);
+		*policy = NULL;
+		}
+	return 0;
+	}
+
+static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
+	X509V3_CTX *ctx, char *value)
+	{
+	PROXY_CERT_INFO_EXTENSION *pci = NULL;
+	STACK_OF(CONF_VALUE) *vals;
+	ASN1_OBJECT *language = NULL;
+	ASN1_INTEGER *pathlen = NULL;
+	ASN1_OCTET_STRING *policy = NULL;
+	int i, j;
+
+	vals = X509V3_parse_list(value);
+	for (i = 0; i < sk_CONF_VALUE_num(vals); i++)
+		{
+		CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
+		if (!cnf->name || (*cnf->name != '@' && !cnf->value))
+			{
+			X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_PROXY_POLICY_SETTING);
+			X509V3_conf_err(cnf);
+			goto err;
+			}
+		if (*cnf->name == '@')
+			{
+			STACK_OF(CONF_VALUE) *sect;
+			int success_p = 1;
+
+			sect = X509V3_get_section(ctx, cnf->name + 1);
+			if (!sect)
+				{
+				X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_SECTION);
+				X509V3_conf_err(cnf);
+				goto err;
+				}
+			for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++)
+				{
+				success_p =
+					process_pci_value(sk_CONF_VALUE_value(sect, j),
+						&language, &pathlen, &policy);
+				}
+			X509V3_section_free(ctx, sect);
+			if (!success_p)
+				goto err;
+			}
+		else
+			{
+			if (!process_pci_value(cnf,
+					&language, &pathlen, &policy))
+				{
+				X509V3_conf_err(cnf);
+				goto err;
+				}
+			}
+		}
+
+	/* Language is mandatory */
+	if (!language)
+		{
+		X509V3err(X509V3_F_R2I_PCI,X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
+		goto err;
+		}
+	i = OBJ_obj2nid(language);
+	if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy)
+		{
+		X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
+		goto err;
+		}
+
+	pci = PROXY_CERT_INFO_EXTENSION_new();
+	if (!pci)
+		{
+		X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	pci->proxyPolicy->policyLanguage = language; language = NULL;
+	pci->proxyPolicy->policy = policy; policy = NULL;
+	pci->pcPathLengthConstraint = pathlen; pathlen = NULL;
+	goto end;
+err:
+	if (language) { ASN1_OBJECT_free(language); language = NULL; }
+	if (pathlen) { ASN1_INTEGER_free(pathlen); pathlen = NULL; }
+	if (policy) { ASN1_OCTET_STRING_free(policy); policy = NULL; }
+	if (pci) { PROXY_CERT_INFO_EXTENSION_free(pci); pci = NULL; }
+end:
+	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+	return pci;
+	}
diff --git a/openssl/crypto/x509v3/v3_pcia.c b/openssl/crypto/x509v3/v3_pcia.c
new file mode 100644
index 0000000..bb362e0
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_pcia.c
@@ -0,0 +1,55 @@
+/* v3_pcia.c -*- mode:C; c-file-style: "eay" -*- */
+/* Contributed to the OpenSSL Project 2004
+ * by Richard Levitte (richard@levitte.org)
+ */
+/* Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+ASN1_SEQUENCE(PROXY_POLICY) =
+	{
+	ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT),
+	ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(PROXY_POLICY)
+
+IMPLEMENT_ASN1_FUNCTIONS(PROXY_POLICY)
+
+ASN1_SEQUENCE(PROXY_CERT_INFO_EXTENSION) =
+	{
+	ASN1_OPT(PROXY_CERT_INFO_EXTENSION,pcPathLengthConstraint,ASN1_INTEGER),
+	ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION,proxyPolicy,PROXY_POLICY)
+} ASN1_SEQUENCE_END(PROXY_CERT_INFO_EXTENSION)
+
+IMPLEMENT_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
diff --git a/openssl/crypto/x509v3/v3_pcons.c b/openssl/crypto/x509v3/v3_pcons.c
new file mode 100644
index 0000000..30ca652
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_pcons.c
@@ -0,0 +1,140 @@
+/* v3_pcons.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+static STACK_OF(CONF_VALUE) *
+i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *bcons,
+		       STACK_OF(CONF_VALUE) *extlist);
+static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
+				    X509V3_CTX *ctx,
+				    STACK_OF(CONF_VALUE) *values);
+
+const X509V3_EXT_METHOD v3_policy_constraints = {
+NID_policy_constraints, 0,
+ASN1_ITEM_ref(POLICY_CONSTRAINTS),
+0,0,0,0,
+0,0,
+i2v_POLICY_CONSTRAINTS,
+v2i_POLICY_CONSTRAINTS,
+NULL,NULL,
+NULL
+};
+
+ASN1_SEQUENCE(POLICY_CONSTRAINTS) = {
+	ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0),
+	ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1)
+} ASN1_SEQUENCE_END(POLICY_CONSTRAINTS)
+
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
+
+
+static STACK_OF(CONF_VALUE) *
+i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
+		       STACK_OF(CONF_VALUE) *extlist)
+{
+	POLICY_CONSTRAINTS *pcons = a;
+	X509V3_add_value_int("Require Explicit Policy",
+			pcons->requireExplicitPolicy, &extlist);
+	X509V3_add_value_int("Inhibit Policy Mapping",
+			pcons->inhibitPolicyMapping, &extlist);
+	return extlist;
+}
+
+static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
+				    X509V3_CTX *ctx,
+				    STACK_OF(CONF_VALUE) *values)
+{
+	POLICY_CONSTRAINTS *pcons=NULL;
+	CONF_VALUE *val;
+	int i;
+	if(!(pcons = POLICY_CONSTRAINTS_new())) {
+		X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	for(i = 0; i < sk_CONF_VALUE_num(values); i++) {
+		val = sk_CONF_VALUE_value(values, i);
+		if(!strcmp(val->name, "requireExplicitPolicy")) {
+			if(!X509V3_get_value_int(val,
+				&pcons->requireExplicitPolicy)) goto err;
+		} else if(!strcmp(val->name, "inhibitPolicyMapping")) {
+			if(!X509V3_get_value_int(val,
+				&pcons->inhibitPolicyMapping)) goto err;
+		} else {
+			X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_INVALID_NAME);
+			X509V3_conf_err(val);
+			goto err;
+		}
+	}
+	if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) {
+		X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_ILLEGAL_EMPTY_EXTENSION);
+		goto err;
+	}
+
+	return pcons;
+	err:
+	POLICY_CONSTRAINTS_free(pcons);
+	return NULL;
+}
+
diff --git a/openssl/crypto/x509v3/v3_pku.c b/openssl/crypto/x509v3/v3_pku.c
new file mode 100644
index 0000000..076f3ff
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_pku.c
@@ -0,0 +1,108 @@
+/* v3_pku.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, PKEY_USAGE_PERIOD *usage, BIO *out, int indent);
+/*
+static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
+*/
+const X509V3_EXT_METHOD v3_pkey_usage_period = {
+NID_private_key_usage_period, 0, ASN1_ITEM_ref(PKEY_USAGE_PERIOD),
+0,0,0,0,
+0,0,0,0,
+(X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, NULL,
+NULL
+};
+
+ASN1_SEQUENCE(PKEY_USAGE_PERIOD) = {
+	ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notBefore, ASN1_GENERALIZEDTIME, 0),
+	ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notAfter, ASN1_GENERALIZEDTIME, 1)
+} ASN1_SEQUENCE_END(PKEY_USAGE_PERIOD)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
+
+static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
+	     PKEY_USAGE_PERIOD *usage, BIO *out, int indent)
+{
+	BIO_printf(out, "%*s", indent, "");
+	if(usage->notBefore) {
+		BIO_write(out, "Not Before: ", 12);
+		ASN1_GENERALIZEDTIME_print(out, usage->notBefore);
+		if(usage->notAfter) BIO_write(out, ", ", 2);
+	}
+	if(usage->notAfter) {
+		BIO_write(out, "Not After: ", 11);
+		ASN1_GENERALIZEDTIME_print(out, usage->notAfter);
+	}
+	return 1;
+}
+
+/*
+static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(method, ctx, values)
+X509V3_EXT_METHOD *method;
+X509V3_CTX *ctx;
+STACK_OF(CONF_VALUE) *values;
+{
+return NULL;
+}
+*/
diff --git a/openssl/crypto/x509v3/v3_pmaps.c b/openssl/crypto/x509v3/v3_pmaps.c
new file mode 100644
index 0000000..865bcd3
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_pmaps.c
@@ -0,0 +1,155 @@
+/* v3_pmaps.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
+				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+static STACK_OF(CONF_VALUE) *
+i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *pmps,
+		    STACK_OF(CONF_VALUE) *extlist);
+
+const X509V3_EXT_METHOD v3_policy_mappings = {
+	NID_policy_mappings, 0,
+	ASN1_ITEM_ref(POLICY_MAPPINGS),
+	0,0,0,0,
+	0,0,
+	i2v_POLICY_MAPPINGS,
+	v2i_POLICY_MAPPINGS,
+	0,0,
+	NULL
+};
+
+ASN1_SEQUENCE(POLICY_MAPPING) = {
+	ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT),
+	ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT)
+} ASN1_SEQUENCE_END(POLICY_MAPPING)
+
+ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS,
+								POLICY_MAPPING)
+ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS)
+
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
+
+
+static STACK_OF(CONF_VALUE) *
+i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *a,
+		    STACK_OF(CONF_VALUE) *ext_list)
+{
+	POLICY_MAPPINGS *pmaps = a;
+	POLICY_MAPPING *pmap;
+	int i;
+	char obj_tmp1[80];
+	char obj_tmp2[80];
+	for(i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) {
+		pmap = sk_POLICY_MAPPING_value(pmaps, i);
+		i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy);
+		i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy);
+		X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list);
+	}
+	return ext_list;
+}
+
+static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
+				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+	POLICY_MAPPINGS *pmaps;
+	POLICY_MAPPING *pmap;
+	ASN1_OBJECT *obj1, *obj2;
+	CONF_VALUE *val;
+	int i;
+
+	if(!(pmaps = sk_POLICY_MAPPING_new_null())) {
+		X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+		val = sk_CONF_VALUE_value(nval, i);
+		if(!val->value || !val->name) {
+			sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
+			X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,X509V3_R_INVALID_OBJECT_IDENTIFIER);
+			X509V3_conf_err(val);
+			return NULL;
+		}
+		obj1 = OBJ_txt2obj(val->name, 0);
+		obj2 = OBJ_txt2obj(val->value, 0);
+		if(!obj1 || !obj2) {
+			sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
+			X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,X509V3_R_INVALID_OBJECT_IDENTIFIER);
+			X509V3_conf_err(val);
+			return NULL;
+		}
+		pmap = POLICY_MAPPING_new();
+		if (!pmap) {
+			sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
+			X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,ERR_R_MALLOC_FAILURE);
+			return NULL;
+		}
+		pmap->issuerDomainPolicy = obj1;
+		pmap->subjectDomainPolicy = obj2;
+		sk_POLICY_MAPPING_push(pmaps, pmap);
+	}
+	return pmaps;
+}
diff --git a/openssl/crypto/x509v3/v3_prn.c b/openssl/crypto/x509v3/v3_prn.c
new file mode 100644
index 0000000..3146218
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_prn.c
@@ -0,0 +1,234 @@
+/* v3_prn.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* X509 v3 extension utilities */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+/* Extension printing routines */
+
+static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent, int supported);
+
+/* Print out a name+value stack */
+
+void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, int ml)
+{
+	int i;
+	CONF_VALUE *nval;
+	if(!val) return;
+	if(!ml || !sk_CONF_VALUE_num(val)) {
+		BIO_printf(out, "%*s", indent, "");
+		if(!sk_CONF_VALUE_num(val)) BIO_puts(out, "<EMPTY>\n");
+	}
+	for(i = 0; i < sk_CONF_VALUE_num(val); i++) {
+		if(ml) BIO_printf(out, "%*s", indent, "");
+		else if(i > 0) BIO_printf(out, ", ");
+		nval = sk_CONF_VALUE_value(val, i);
+		if(!nval->name) BIO_puts(out, nval->value);
+		else if(!nval->value) BIO_puts(out, nval->name);
+#ifndef CHARSET_EBCDIC
+		else BIO_printf(out, "%s:%s", nval->name, nval->value);
+#else
+		else {
+			int len;
+			char *tmp;
+			len = strlen(nval->value)+1;
+			tmp = OPENSSL_malloc(len);
+			if (tmp)
+			{
+				ascii2ebcdic(tmp, nval->value, len);
+				BIO_printf(out, "%s:%s", nval->name, tmp);
+				OPENSSL_free(tmp);
+			}
+		}
+#endif
+		if(ml) BIO_puts(out, "\n");
+	}
+}
+
+/* Main routine: print out a general extension */
+
+int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent)
+{
+	void *ext_str = NULL;
+	char *value = NULL;
+	const unsigned char *p;
+	const X509V3_EXT_METHOD *method;	
+	STACK_OF(CONF_VALUE) *nval = NULL;
+	int ok = 1;
+
+	if(!(method = X509V3_EXT_get(ext)))
+		return unknown_ext_print(out, ext, flag, indent, 0);
+	p = ext->value->data;
+	if(method->it) ext_str = ASN1_item_d2i(NULL, &p, ext->value->length, ASN1_ITEM_ptr(method->it));
+	else ext_str = method->d2i(NULL, &p, ext->value->length);
+
+	if(!ext_str) return unknown_ext_print(out, ext, flag, indent, 1);
+
+	if(method->i2s) {
+		if(!(value = method->i2s(method, ext_str))) {
+			ok = 0;
+			goto err;
+		}
+#ifndef CHARSET_EBCDIC
+		BIO_printf(out, "%*s%s", indent, "", value);
+#else
+		{
+			int len;
+			char *tmp;
+			len = strlen(value)+1;
+			tmp = OPENSSL_malloc(len);
+			if (tmp)
+			{
+				ascii2ebcdic(tmp, value, len);
+				BIO_printf(out, "%*s%s", indent, "", tmp);
+				OPENSSL_free(tmp);
+			}
+		}
+#endif
+	} else if(method->i2v) {
+		if(!(nval = method->i2v(method, ext_str, NULL))) {
+			ok = 0;
+			goto err;
+		}
+		X509V3_EXT_val_prn(out, nval, indent,
+				 method->ext_flags & X509V3_EXT_MULTILINE);
+	} else if(method->i2r) {
+		if(!method->i2r(method, ext_str, out, indent)) ok = 0;
+	} else ok = 0;
+
+	err:
+		sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
+		if(value) OPENSSL_free(value);
+		if(method->it) ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it));
+		else method->ext_free(ext_str);
+		return ok;
+}
+
+int X509V3_extensions_print(BIO *bp, char *title, STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent)
+{
+	int i, j;
+
+	if(sk_X509_EXTENSION_num(exts) <= 0) return 1;
+
+	if(title) 
+		{
+		BIO_printf(bp,"%*s%s:\n",indent, "", title);
+		indent += 4;
+		}
+
+	for (i=0; i<sk_X509_EXTENSION_num(exts); i++)
+		{
+		ASN1_OBJECT *obj;
+		X509_EXTENSION *ex;
+		ex=sk_X509_EXTENSION_value(exts, i);
+		if (indent && BIO_printf(bp,"%*s",indent, "") <= 0) return 0;
+		obj=X509_EXTENSION_get_object(ex);
+		i2a_ASN1_OBJECT(bp,obj);
+		j=X509_EXTENSION_get_critical(ex);
+		if (BIO_printf(bp,": %s\n",j?"critical":"") <= 0)
+			return 0;
+		if(!X509V3_EXT_print(bp, ex, flag, indent + 4))
+			{
+			BIO_printf(bp, "%*s", indent + 4, "");
+			M_ASN1_OCTET_STRING_print(bp,ex->value);
+			}
+		if (BIO_write(bp,"\n",1) <= 0) return 0;
+		}
+	return 1;
+}
+
+static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent, int supported)
+{
+	switch(flag & X509V3_EXT_UNKNOWN_MASK) {
+
+		case X509V3_EXT_DEFAULT:
+		return 0;
+
+		case X509V3_EXT_ERROR_UNKNOWN:
+		if(supported)
+			BIO_printf(out, "%*s<Parse Error>", indent, "");
+		else
+			BIO_printf(out, "%*s<Not Supported>", indent, "");
+		return 1;
+
+		case X509V3_EXT_PARSE_UNKNOWN:
+			return ASN1_parse_dump(out,
+				ext->value->data, ext->value->length, indent, -1);
+		case X509V3_EXT_DUMP_UNKNOWN:
+			return BIO_dump_indent(out, (char *)ext->value->data, ext->value->length, indent);
+
+		default:
+		return 1;
+	}
+}
+	
+
+#ifndef OPENSSL_NO_FP_API
+int X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent)
+{
+	BIO *bio_tmp;
+	int ret;
+	if(!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE))) return 0;
+	ret = X509V3_EXT_print(bio_tmp, ext, flag, indent);
+	BIO_free(bio_tmp);
+	return ret;
+}
+#endif
diff --git a/openssl/crypto/x509v3/v3_purp.c b/openssl/crypto/x509v3/v3_purp.c
new file mode 100644
index 0000000..181bd34
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_purp.c
@@ -0,0 +1,767 @@
+/* v3_purp.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509v3.h>
+#include <openssl/x509_vfy.h>
+
+static void x509v3_cache_extensions(X509 *x);
+
+static int check_ssl_ca(const X509 *x);
+static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca);
+static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca);
+static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca);
+static int purpose_smime(const X509 *x, int ca);
+static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
+static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca);
+static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
+static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
+static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca);
+static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca);
+
+static int xp_cmp(const X509_PURPOSE * const *a,
+		const X509_PURPOSE * const *b);
+static void xptable_free(X509_PURPOSE *p);
+
+static X509_PURPOSE xstandard[] = {
+	{X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, check_purpose_ssl_client, "SSL client", "sslclient", NULL},
+	{X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ssl_server, "SSL server", "sslserver", NULL},
+	{X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ns_ssl_server, "Netscape SSL server", "nssslserver", NULL},
+	{X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, "S/MIME signing", "smimesign", NULL},
+	{X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL},
+	{X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, "CRL signing", "crlsign", NULL},
+	{X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", NULL},
+	{X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, "OCSP helper", "ocsphelper", NULL},
+	{X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, check_purpose_timestamp_sign, "Time Stamp signing", "timestampsign", NULL},
+};
+
+#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE))
+
+IMPLEMENT_STACK_OF(X509_PURPOSE)
+
+static STACK_OF(X509_PURPOSE) *xptable = NULL;
+
+static int xp_cmp(const X509_PURPOSE * const *a,
+		const X509_PURPOSE * const *b)
+{
+	return (*a)->purpose - (*b)->purpose;
+}
+
+/* As much as I'd like to make X509_check_purpose use a "const" X509*
+ * I really can't because it does recalculate hashes and do other non-const
+ * things. */
+int X509_check_purpose(X509 *x, int id, int ca)
+{
+	int idx;
+	const X509_PURPOSE *pt;
+	if(!(x->ex_flags & EXFLAG_SET)) {
+		CRYPTO_w_lock(CRYPTO_LOCK_X509);
+		x509v3_cache_extensions(x);
+		CRYPTO_w_unlock(CRYPTO_LOCK_X509);
+	}
+	if(id == -1) return 1;
+	idx = X509_PURPOSE_get_by_id(id);
+	if(idx == -1) return -1;
+	pt = X509_PURPOSE_get0(idx);
+	return pt->check_purpose(pt, x, ca);
+}
+
+int X509_PURPOSE_set(int *p, int purpose)
+{
+	if(X509_PURPOSE_get_by_id(purpose) == -1) {
+		X509V3err(X509V3_F_X509_PURPOSE_SET, X509V3_R_INVALID_PURPOSE);
+		return 0;
+	}
+	*p = purpose;
+	return 1;
+}
+
+int X509_PURPOSE_get_count(void)
+{
+	if(!xptable) return X509_PURPOSE_COUNT;
+	return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT;
+}
+
+X509_PURPOSE * X509_PURPOSE_get0(int idx)
+{
+	if(idx < 0) return NULL;
+	if(idx < (int)X509_PURPOSE_COUNT) return xstandard + idx;
+	return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT);
+}
+
+int X509_PURPOSE_get_by_sname(char *sname)
+{
+	int i;
+	X509_PURPOSE *xptmp;
+	for(i = 0; i < X509_PURPOSE_get_count(); i++) {
+		xptmp = X509_PURPOSE_get0(i);
+		if(!strcmp(xptmp->sname, sname)) return i;
+	}
+	return -1;
+}
+
+int X509_PURPOSE_get_by_id(int purpose)
+{
+	X509_PURPOSE tmp;
+	int idx;
+	if((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))
+		return purpose - X509_PURPOSE_MIN;
+	tmp.purpose = purpose;
+	if(!xptable) return -1;
+	idx = sk_X509_PURPOSE_find(xptable, &tmp);
+	if(idx == -1) return -1;
+	return idx + X509_PURPOSE_COUNT;
+}
+
+int X509_PURPOSE_add(int id, int trust, int flags,
+			int (*ck)(const X509_PURPOSE *, const X509 *, int),
+					char *name, char *sname, void *arg)
+{
+	int idx;
+	X509_PURPOSE *ptmp;
+	/* This is set according to what we change: application can't set it */
+	flags &= ~X509_PURPOSE_DYNAMIC;
+	/* This will always be set for application modified trust entries */
+	flags |= X509_PURPOSE_DYNAMIC_NAME;
+	/* Get existing entry if any */
+	idx = X509_PURPOSE_get_by_id(id);
+	/* Need a new entry */
+	if(idx == -1) {
+		if(!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) {
+			X509V3err(X509V3_F_X509_PURPOSE_ADD,ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		ptmp->flags = X509_PURPOSE_DYNAMIC;
+	} else ptmp = X509_PURPOSE_get0(idx);
+
+	/* OPENSSL_free existing name if dynamic */
+	if(ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {
+		OPENSSL_free(ptmp->name);
+		OPENSSL_free(ptmp->sname);
+	}
+	/* dup supplied name */
+	ptmp->name = BUF_strdup(name);
+	ptmp->sname = BUF_strdup(sname);
+	if(!ptmp->name || !ptmp->sname) {
+		X509V3err(X509V3_F_X509_PURPOSE_ADD,ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	/* Keep the dynamic flag of existing entry */
+	ptmp->flags &= X509_PURPOSE_DYNAMIC;
+	/* Set all other flags */
+	ptmp->flags |= flags;
+
+	ptmp->purpose = id;
+	ptmp->trust = trust;
+	ptmp->check_purpose = ck;
+	ptmp->usr_data = arg;
+
+	/* If its a new entry manage the dynamic table */
+	if(idx == -1) {
+		if(!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) {
+			X509V3err(X509V3_F_X509_PURPOSE_ADD,ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		if (!sk_X509_PURPOSE_push(xptable, ptmp)) {
+			X509V3err(X509V3_F_X509_PURPOSE_ADD,ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+	}
+	return 1;
+}
+
+static void xptable_free(X509_PURPOSE *p)
+	{
+	if(!p) return;
+	if (p->flags & X509_PURPOSE_DYNAMIC) 
+		{
+		if (p->flags & X509_PURPOSE_DYNAMIC_NAME) {
+			OPENSSL_free(p->name);
+			OPENSSL_free(p->sname);
+		}
+		OPENSSL_free(p);
+		}
+	}
+
+void X509_PURPOSE_cleanup(void)
+{
+	unsigned int i;
+	sk_X509_PURPOSE_pop_free(xptable, xptable_free);
+	for(i = 0; i < X509_PURPOSE_COUNT; i++) xptable_free(xstandard + i);
+	xptable = NULL;
+}
+
+int X509_PURPOSE_get_id(X509_PURPOSE *xp)
+{
+	return xp->purpose;
+}
+
+char *X509_PURPOSE_get0_name(X509_PURPOSE *xp)
+{
+	return xp->name;
+}
+
+char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp)
+{
+	return xp->sname;
+}
+
+int X509_PURPOSE_get_trust(X509_PURPOSE *xp)
+{
+	return xp->trust;
+}
+
+static int nid_cmp(const int *a, const int *b)
+	{
+	return *a - *b;
+	}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(int, int, nid);
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(int, int, nid);
+
+int X509_supported_extension(X509_EXTENSION *ex)
+	{
+	/* This table is a list of the NIDs of supported extensions:
+	 * that is those which are used by the verify process. If
+	 * an extension is critical and doesn't appear in this list
+	 * then the verify process will normally reject the certificate.
+	 * The list must be kept in numerical order because it will be
+	 * searched using bsearch.
+	 */
+
+	static const int supported_nids[] = {
+		NID_netscape_cert_type, /* 71 */
+        	NID_key_usage,		/* 83 */
+		NID_subject_alt_name,	/* 85 */
+		NID_basic_constraints,	/* 87 */
+		NID_certificate_policies, /* 89 */
+        	NID_ext_key_usage,	/* 126 */
+#ifndef OPENSSL_NO_RFC3779
+		NID_sbgp_ipAddrBlock,	/* 290 */
+		NID_sbgp_autonomousSysNum, /* 291 */
+#endif
+		NID_policy_constraints,	/* 401 */
+		NID_proxyCertInfo,	/* 663 */
+		NID_name_constraints,	/* 666 */
+		NID_policy_mappings,	/* 747 */
+		NID_inhibit_any_policy	/* 748 */
+	};
+
+	int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
+
+	if (ex_nid == NID_undef) 
+		return 0;
+
+	if (OBJ_bsearch_nid(&ex_nid, supported_nids,
+			sizeof(supported_nids)/sizeof(int)))
+		return 1;
+	return 0;
+	}
+
+static void setup_dp(X509 *x, DIST_POINT *dp)
+	{
+	X509_NAME *iname = NULL;
+	int i;
+	if (dp->reasons)
+		{
+		if (dp->reasons->length > 0)
+			dp->dp_reasons = dp->reasons->data[0];
+		if (dp->reasons->length > 1)
+			dp->dp_reasons |= (dp->reasons->data[1] << 8);
+		dp->dp_reasons &= CRLDP_ALL_REASONS;
+		}
+	else
+		dp->dp_reasons = CRLDP_ALL_REASONS;
+	if (!dp->distpoint || (dp->distpoint->type != 1))
+		return;
+	for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++)
+		{
+		GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
+		if (gen->type == GEN_DIRNAME)
+			{
+			iname = gen->d.directoryName;
+			break;
+			}
+		}
+	if (!iname)
+		iname = X509_get_issuer_name(x);
+
+	DIST_POINT_set_dpname(dp->distpoint, iname);
+
+	}
+
+static void setup_crldp(X509 *x)
+	{
+	int i;
+	x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
+	for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
+		setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
+	}
+
+static void x509v3_cache_extensions(X509 *x)
+{
+	BASIC_CONSTRAINTS *bs;
+	PROXY_CERT_INFO_EXTENSION *pci;
+	ASN1_BIT_STRING *usage;
+	ASN1_BIT_STRING *ns;
+	EXTENDED_KEY_USAGE *extusage;
+	X509_EXTENSION *ex;
+	
+	int i;
+	if(x->ex_flags & EXFLAG_SET) return;
+#ifndef OPENSSL_NO_SHA
+	X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
+#endif
+	/* Does subject name match issuer ? */
+	if(!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x)))
+			 x->ex_flags |= EXFLAG_SI;
+	/* V1 should mean no extensions ... */
+	if(!X509_get_version(x)) x->ex_flags |= EXFLAG_V1;
+	/* Handle basic constraints */
+	if((bs=X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
+		if(bs->ca) x->ex_flags |= EXFLAG_CA;
+		if(bs->pathlen) {
+			if((bs->pathlen->type == V_ASN1_NEG_INTEGER)
+						|| !bs->ca) {
+				x->ex_flags |= EXFLAG_INVALID;
+				x->ex_pathlen = 0;
+			} else x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
+		} else x->ex_pathlen = -1;
+		BASIC_CONSTRAINTS_free(bs);
+		x->ex_flags |= EXFLAG_BCONS;
+	}
+	/* Handle proxy certificates */
+	if((pci=X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
+		if (x->ex_flags & EXFLAG_CA
+		    || X509_get_ext_by_NID(x, NID_subject_alt_name, 0) >= 0
+		    || X509_get_ext_by_NID(x, NID_issuer_alt_name, 0) >= 0) {
+			x->ex_flags |= EXFLAG_INVALID;
+		}
+		if (pci->pcPathLengthConstraint) {
+			x->ex_pcpathlen =
+				ASN1_INTEGER_get(pci->pcPathLengthConstraint);
+		} else x->ex_pcpathlen = -1;
+		PROXY_CERT_INFO_EXTENSION_free(pci);
+		x->ex_flags |= EXFLAG_PROXY;
+	}
+	/* Handle key usage */
+	if((usage=X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
+		if(usage->length > 0) {
+			x->ex_kusage = usage->data[0];
+			if(usage->length > 1) 
+				x->ex_kusage |= usage->data[1] << 8;
+		} else x->ex_kusage = 0;
+		x->ex_flags |= EXFLAG_KUSAGE;
+		ASN1_BIT_STRING_free(usage);
+	}
+	x->ex_xkusage = 0;
+	if((extusage=X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) {
+		x->ex_flags |= EXFLAG_XKUSAGE;
+		for(i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
+			switch(OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage,i))) {
+				case NID_server_auth:
+				x->ex_xkusage |= XKU_SSL_SERVER;
+				break;
+
+				case NID_client_auth:
+				x->ex_xkusage |= XKU_SSL_CLIENT;
+				break;
+
+				case NID_email_protect:
+				x->ex_xkusage |= XKU_SMIME;
+				break;
+
+				case NID_code_sign:
+				x->ex_xkusage |= XKU_CODE_SIGN;
+				break;
+
+				case NID_ms_sgc:
+				case NID_ns_sgc:
+				x->ex_xkusage |= XKU_SGC;
+				break;
+
+				case NID_OCSP_sign:
+				x->ex_xkusage |= XKU_OCSP_SIGN;
+				break;
+
+				case NID_time_stamp:
+				x->ex_xkusage |= XKU_TIMESTAMP;
+				break;
+
+				case NID_dvcs:
+				x->ex_xkusage |= XKU_DVCS;
+				break;
+			}
+		}
+		sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
+	}
+
+	if((ns=X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) {
+		if(ns->length > 0) x->ex_nscert = ns->data[0];
+		else x->ex_nscert = 0;
+		x->ex_flags |= EXFLAG_NSCERT;
+		ASN1_BIT_STRING_free(ns);
+	}
+	x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
+	x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
+	x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
+	x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL);
+	if (!x->nc && (i != -1))
+		x->ex_flags |= EXFLAG_INVALID;
+	setup_crldp(x);
+
+#ifndef OPENSSL_NO_RFC3779
+ 	x->rfc3779_addr =X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL);
+ 	x->rfc3779_asid =X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum,
+ 					  NULL, NULL);
+#endif
+	for (i = 0; i < X509_get_ext_count(x); i++)
+		{
+		ex = X509_get_ext(x, i);
+		if (!X509_EXTENSION_get_critical(ex))
+			continue;
+		if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
+					== NID_freshest_crl)
+			x->ex_flags |= EXFLAG_FRESHEST;
+		if (!X509_supported_extension(ex))
+			{
+			x->ex_flags |= EXFLAG_CRITICAL;
+			break;
+			}
+		}
+	x->ex_flags |= EXFLAG_SET;
+}
+
+/* CA checks common to all purposes
+ * return codes:
+ * 0 not a CA
+ * 1 is a CA
+ * 2 basicConstraints absent so "maybe" a CA
+ * 3 basicConstraints absent but self signed V1.
+ * 4 basicConstraints absent but keyUsage present and keyCertSign asserted.
+ */
+
+#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
+#define ku_reject(x, usage) \
+	(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
+#define xku_reject(x, usage) \
+	(((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
+#define ns_reject(x, usage) \
+	(((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
+
+static int check_ca(const X509 *x)
+{
+	/* keyUsage if present should allow cert signing */
+	if(ku_reject(x, KU_KEY_CERT_SIGN)) return 0;
+	if(x->ex_flags & EXFLAG_BCONS) {
+		if(x->ex_flags & EXFLAG_CA) return 1;
+		/* If basicConstraints says not a CA then say so */
+		else return 0;
+	} else {
+		/* we support V1 roots for...  uh, I don't really know why. */
+		if((x->ex_flags & V1_ROOT) == V1_ROOT) return 3;
+		/* If key usage present it must have certSign so tolerate it */
+		else if (x->ex_flags & EXFLAG_KUSAGE) return 4;
+		/* Older certificates could have Netscape-specific CA types */
+		else if (x->ex_flags & EXFLAG_NSCERT
+			 && x->ex_nscert & NS_ANY_CA) return 5;
+		/* can this still be regarded a CA certificate?  I doubt it */
+		return 0;
+	}
+}
+
+int X509_check_ca(X509 *x)
+{
+	if(!(x->ex_flags & EXFLAG_SET)) {
+		CRYPTO_w_lock(CRYPTO_LOCK_X509);
+		x509v3_cache_extensions(x);
+		CRYPTO_w_unlock(CRYPTO_LOCK_X509);
+	}
+
+	return check_ca(x);
+}
+
+/* Check SSL CA: common checks for SSL client and server */
+static int check_ssl_ca(const X509 *x)
+{
+	int ca_ret;
+	ca_ret = check_ca(x);
+	if(!ca_ret) return 0;
+	/* check nsCertType if present */
+	if(ca_ret != 5 || x->ex_nscert & NS_SSL_CA) return ca_ret;
+	else return 0;
+}
+
+
+static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca)
+{
+	if(xku_reject(x,XKU_SSL_CLIENT)) return 0;
+	if(ca) return check_ssl_ca(x);
+	/* We need to do digital signatures with it */
+	if(ku_reject(x,KU_DIGITAL_SIGNATURE)) return 0;
+	/* nsCertType if present should allow SSL client use */	
+	if(ns_reject(x, NS_SSL_CLIENT)) return 0;
+	return 1;
+}
+
+static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
+{
+	if(xku_reject(x,XKU_SSL_SERVER|XKU_SGC)) return 0;
+	if(ca) return check_ssl_ca(x);
+
+	if(ns_reject(x, NS_SSL_SERVER)) return 0;
+	/* Now as for keyUsage: we'll at least need to sign OR encipher */
+	if(ku_reject(x, KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT)) return 0;
+	
+	return 1;
+
+}
+
+static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
+{
+	int ret;
+	ret = check_purpose_ssl_server(xp, x, ca);
+	if(!ret || ca) return ret;
+	/* We need to encipher or Netscape complains */
+	if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0;
+	return ret;
+}
+
+/* common S/MIME checks */
+static int purpose_smime(const X509 *x, int ca)
+{
+	if(xku_reject(x,XKU_SMIME)) return 0;
+	if(ca) {
+		int ca_ret;
+		ca_ret = check_ca(x);
+		if(!ca_ret) return 0;
+		/* check nsCertType if present */
+		if(ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) return ca_ret;
+		else return 0;
+	}
+	if(x->ex_flags & EXFLAG_NSCERT) {
+		if(x->ex_nscert & NS_SMIME) return 1;
+		/* Workaround for some buggy certificates */
+		if(x->ex_nscert & NS_SSL_CLIENT) return 2;
+		return 0;
+	}
+	return 1;
+}
+
+static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
+{
+	int ret;
+	ret = purpose_smime(x, ca);
+	if(!ret || ca) return ret;
+	if(ku_reject(x, KU_DIGITAL_SIGNATURE|KU_NON_REPUDIATION)) return 0;
+	return ret;
+}
+
+static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca)
+{
+	int ret;
+	ret = purpose_smime(x, ca);
+	if(!ret || ca) return ret;
+	if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0;
+	return ret;
+}
+
+static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
+{
+	if(ca) {
+		int ca_ret;
+		if((ca_ret = check_ca(x)) != 2) return ca_ret;
+		else return 0;
+	}
+	if(ku_reject(x, KU_CRL_SIGN)) return 0;
+	return 1;
+}
+
+/* OCSP helper: this is *not* a full OCSP check. It just checks that
+ * each CA is valid. Additional checks must be made on the chain.
+ */
+
+static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca)
+{
+	/* Must be a valid CA.  Should we really support the "I don't know"
+	   value (2)? */
+	if(ca) return check_ca(x);
+	/* leaf certificate is checked in OCSP_verify() */
+	return 1;
+}
+
+static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
+					int ca)
+{
+	int i_ext;
+
+	/* If ca is true we must return if this is a valid CA certificate. */
+	if (ca) return check_ca(x);
+
+	/* 
+	 * Check the optional key usage field:
+	 * if Key Usage is present, it must be one of digitalSignature 
+	 * and/or nonRepudiation (other values are not consistent and shall
+	 * be rejected).
+	 */
+	if ((x->ex_flags & EXFLAG_KUSAGE)
+	    && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) ||
+		!(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE))))
+		return 0;
+
+	/* Only time stamp key usage is permitted and it's required. */
+	if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP)
+		return 0;
+
+	/* Extended Key Usage MUST be critical */
+	i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, 0);
+	if (i_ext >= 0)
+		{
+		X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext);
+		if (!X509_EXTENSION_get_critical(ext))
+			return 0;
+		}
+
+	return 1;
+}
+
+static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca)
+{
+	return 1;
+}
+
+/* Various checks to see if one certificate issued the second.
+ * This can be used to prune a set of possible issuer certificates
+ * which have been looked up using some simple method such as by
+ * subject name.
+ * These are:
+ * 1. Check issuer_name(subject) == subject_name(issuer)
+ * 2. If akid(subject) exists check it matches issuer
+ * 3. If key_usage(issuer) exists check it supports certificate signing
+ * returns 0 for OK, positive for reason for mismatch, reasons match
+ * codes for X509_verify_cert()
+ */
+
+int X509_check_issued(X509 *issuer, X509 *subject)
+{
+	if(X509_NAME_cmp(X509_get_subject_name(issuer),
+			X509_get_issuer_name(subject)))
+				return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
+	x509v3_cache_extensions(issuer);
+	x509v3_cache_extensions(subject);
+
+	if(subject->akid)
+		{
+		int ret = X509_check_akid(issuer, subject->akid);
+		if (ret != X509_V_OK)
+			return ret;
+		}
+
+	if(subject->ex_flags & EXFLAG_PROXY)
+		{
+		if(ku_reject(issuer, KU_DIGITAL_SIGNATURE))
+			return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
+		}
+	else if(ku_reject(issuer, KU_KEY_CERT_SIGN))
+		return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
+	return X509_V_OK;
+}
+
+int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
+	{
+
+	if(!akid)
+		return X509_V_OK;
+
+	/* Check key ids (if present) */
+	if(akid->keyid && issuer->skid &&
+		 ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid) )
+				return X509_V_ERR_AKID_SKID_MISMATCH;
+	/* Check serial number */
+	if(akid->serial &&
+		ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial))
+				return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
+	/* Check issuer name */
+	if(akid->issuer)
+		{
+		/* Ugh, for some peculiar reason AKID includes
+		 * SEQUENCE OF GeneralName. So look for a DirName.
+		 * There may be more than one but we only take any
+		 * notice of the first.
+		 */
+		GENERAL_NAMES *gens;
+		GENERAL_NAME *gen;
+		X509_NAME *nm = NULL;
+		int i;
+		gens = akid->issuer;
+		for(i = 0; i < sk_GENERAL_NAME_num(gens); i++)
+			{
+			gen = sk_GENERAL_NAME_value(gens, i);
+			if(gen->type == GEN_DIRNAME)
+				{
+				nm = gen->d.dirn;
+				break;
+				}
+			}
+		if(nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
+			return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
+		}
+	return X509_V_OK;
+	}
+
diff --git a/openssl/crypto/x509v3/v3_skey.c b/openssl/crypto/x509v3/v3_skey.c
new file mode 100644
index 0000000..202c9e4
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_skey.c
@@ -0,0 +1,144 @@
+/* v3_skey.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509v3.h>
+
+static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
+const X509V3_EXT_METHOD v3_skey_id = { 
+NID_subject_key_identifier, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING),
+0,0,0,0,
+(X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING,
+(X509V3_EXT_S2I)s2i_skey_id,
+0,0,0,0,
+NULL};
+
+char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
+	     ASN1_OCTET_STRING *oct)
+{
+	return hex_to_string(oct->data, oct->length);
+}
+
+ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
+	     X509V3_CTX *ctx, char *str)
+{
+	ASN1_OCTET_STRING *oct;
+	long length;
+
+	if(!(oct = M_ASN1_OCTET_STRING_new())) {
+		X509V3err(X509V3_F_S2I_ASN1_OCTET_STRING,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	if(!(oct->data = string_to_hex(str, &length))) {
+		M_ASN1_OCTET_STRING_free(oct);
+		return NULL;
+	}
+
+	oct->length = length;
+
+	return oct;
+
+}
+
+static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
+	     X509V3_CTX *ctx, char *str)
+{
+	ASN1_OCTET_STRING *oct;
+	ASN1_BIT_STRING *pk;
+	unsigned char pkey_dig[EVP_MAX_MD_SIZE];
+	unsigned int diglen;
+
+	if(strcmp(str, "hash")) return s2i_ASN1_OCTET_STRING(method, ctx, str);
+
+	if(!(oct = M_ASN1_OCTET_STRING_new())) {
+		X509V3err(X509V3_F_S2I_SKEY_ID,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	if(ctx && (ctx->flags == CTX_TEST)) return oct;
+
+	if(!ctx || (!ctx->subject_req && !ctx->subject_cert)) {
+		X509V3err(X509V3_F_S2I_SKEY_ID,X509V3_R_NO_PUBLIC_KEY);
+		goto err;
+	}
+
+	if(ctx->subject_req) 
+		pk = ctx->subject_req->req_info->pubkey->public_key;
+	else pk = ctx->subject_cert->cert_info->key->public_key;
+
+	if(!pk) {
+		X509V3err(X509V3_F_S2I_SKEY_ID,X509V3_R_NO_PUBLIC_KEY);
+		goto err;
+	}
+
+	EVP_Digest(pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL);
+
+	if(!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) {
+		X509V3err(X509V3_F_S2I_SKEY_ID,ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	return oct;
+	
+	err:
+	M_ASN1_OCTET_STRING_free(oct);
+	return NULL;
+}
diff --git a/openssl/crypto/x509v3/v3_sxnet.c b/openssl/crypto/x509v3/v3_sxnet.c
new file mode 100644
index 0000000..2a6bf11
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_sxnet.c
@@ -0,0 +1,262 @@
+/* v3_sxnet.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+/* Support for Thawte strong extranet extension */
+
+#define SXNET_TEST
+
+static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, int indent);
+#ifdef SXNET_TEST
+static SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+						STACK_OF(CONF_VALUE) *nval);
+#endif
+const X509V3_EXT_METHOD v3_sxnet = {
+NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET),
+0,0,0,0,
+0,0,
+0, 
+#ifdef SXNET_TEST
+(X509V3_EXT_V2I)sxnet_v2i,
+#else
+0,
+#endif
+(X509V3_EXT_I2R)sxnet_i2r,
+0,
+NULL
+};
+
+ASN1_SEQUENCE(SXNETID) = {
+	ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER),
+	ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(SXNETID)
+
+IMPLEMENT_ASN1_FUNCTIONS(SXNETID)
+
+ASN1_SEQUENCE(SXNET) = {
+	ASN1_SIMPLE(SXNET, version, ASN1_INTEGER),
+	ASN1_SEQUENCE_OF(SXNET, ids, SXNETID)
+} ASN1_SEQUENCE_END(SXNET)
+
+IMPLEMENT_ASN1_FUNCTIONS(SXNET)
+
+static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
+	     int indent)
+{
+	long v;
+	char *tmp;
+	SXNETID *id;
+	int i;
+	v = ASN1_INTEGER_get(sx->version);
+	BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v);
+	for(i = 0; i < sk_SXNETID_num(sx->ids); i++) {
+		id = sk_SXNETID_value(sx->ids, i);
+		tmp = i2s_ASN1_INTEGER(NULL, id->zone);
+		BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp);
+		OPENSSL_free(tmp);
+		M_ASN1_OCTET_STRING_print(out, id->user);
+	}
+	return 1;
+}
+
+#ifdef SXNET_TEST
+
+/* NBB: this is used for testing only. It should *not* be used for anything
+ * else because it will just take static IDs from the configuration file and
+ * they should really be separate values for each user.
+ */
+
+
+static SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+	     STACK_OF(CONF_VALUE) *nval)
+{
+	CONF_VALUE *cnf;
+	SXNET *sx = NULL;
+	int i;
+	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+		cnf = sk_CONF_VALUE_value(nval, i);
+		if(!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1))
+								 return NULL;
+	}
+	return sx;
+}
+		
+	
+#endif
+
+/* Strong Extranet utility functions */
+
+/* Add an id given the zone as an ASCII number */
+
+int SXNET_add_id_asc(SXNET **psx, char *zone, char *user,
+	     int userlen)
+{
+	ASN1_INTEGER *izone = NULL;
+	if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
+		X509V3err(X509V3_F_SXNET_ADD_ID_ASC,X509V3_R_ERROR_CONVERTING_ZONE);
+		return 0;
+	}
+	return SXNET_add_id_INTEGER(psx, izone, user, userlen);
+}
+
+/* Add an id given the zone as an unsigned long */
+
+int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user,
+	     int userlen)
+{
+	ASN1_INTEGER *izone = NULL;
+	if(!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
+		X509V3err(X509V3_F_SXNET_ADD_ID_ULONG,ERR_R_MALLOC_FAILURE);
+		M_ASN1_INTEGER_free(izone);
+		return 0;
+	}
+	return SXNET_add_id_INTEGER(psx, izone, user, userlen);
+	
+}
+
+/* Add an id given the zone as an ASN1_INTEGER.
+ * Note this version uses the passed integer and doesn't make a copy so don't
+ * free it up afterwards.
+ */
+
+int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user,
+	     int userlen)
+{
+	SXNET *sx = NULL;
+	SXNETID *id = NULL;
+	if(!psx || !zone || !user) {
+		X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_INVALID_NULL_ARGUMENT);
+		return 0;
+	}
+	if(userlen == -1) userlen = strlen(user);
+	if(userlen > 64) {
+		X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_USER_TOO_LONG);
+		return 0;
+	}
+	if(!*psx) {
+		if(!(sx = SXNET_new())) goto err;
+		if(!ASN1_INTEGER_set(sx->version, 0)) goto err;
+		*psx = sx;
+	} else sx = *psx;
+	if(SXNET_get_id_INTEGER(sx, zone)) {
+		X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_DUPLICATE_ZONE_ID);
+		return 0;
+	}
+
+	if(!(id = SXNETID_new())) goto err;
+	if(userlen == -1) userlen = strlen(user);
+		
+	if(!M_ASN1_OCTET_STRING_set(id->user, user, userlen)) goto err;
+	if(!sk_SXNETID_push(sx->ids, id)) goto err;
+	id->zone = zone;
+	return 1;
+	
+	err:
+	X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,ERR_R_MALLOC_FAILURE);
+	SXNETID_free(id);
+	SXNET_free(sx);
+	*psx = NULL;
+	return 0;
+}
+
+ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone)
+{
+	ASN1_INTEGER *izone = NULL;
+	ASN1_OCTET_STRING *oct;
+	if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
+		X509V3err(X509V3_F_SXNET_GET_ID_ASC,X509V3_R_ERROR_CONVERTING_ZONE);
+		return NULL;
+	}
+	oct = SXNET_get_id_INTEGER(sx, izone);
+	M_ASN1_INTEGER_free(izone);
+	return oct;
+}
+
+ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone)
+{
+	ASN1_INTEGER *izone = NULL;
+	ASN1_OCTET_STRING *oct;
+	if(!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
+		X509V3err(X509V3_F_SXNET_GET_ID_ULONG,ERR_R_MALLOC_FAILURE);
+		M_ASN1_INTEGER_free(izone);
+		return NULL;
+	}
+	oct = SXNET_get_id_INTEGER(sx, izone);
+	M_ASN1_INTEGER_free(izone);
+	return oct;
+}
+
+ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone)
+{
+	SXNETID *id;
+	int i;
+	for(i = 0; i < sk_SXNETID_num(sx->ids); i++) {
+		id = sk_SXNETID_value(sx->ids, i);
+		if(!M_ASN1_INTEGER_cmp(id->zone, zone)) return id->user;
+	}
+	return NULL;
+}
+
+IMPLEMENT_STACK_OF(SXNETID)
+IMPLEMENT_ASN1_SET_OF(SXNETID)
diff --git a/openssl/crypto/x509v3/v3_utl.c b/openssl/crypto/x509v3/v3_utl.c
new file mode 100644
index 0000000..e030234
--- /dev/null
+++ b/openssl/crypto/x509v3/v3_utl.c
@@ -0,0 +1,874 @@
+/* v3_utl.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* X509 v3 extension utilities */
+
+
+#include <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+#include <openssl/bn.h>
+
+static char *strip_spaces(char *name);
+static int sk_strcmp(const char * const *a, const char * const *b);
+static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, GENERAL_NAMES *gens);
+static void str_free(OPENSSL_STRING str);
+static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email);
+
+static int ipv4_from_asc(unsigned char *v4, const char *in);
+static int ipv6_from_asc(unsigned char *v6, const char *in);
+static int ipv6_cb(const char *elem, int len, void *usr);
+static int ipv6_hex(unsigned char *out, const char *in, int inlen);
+
+/* Add a CONF_VALUE name value pair to stack */
+
+int X509V3_add_value(const char *name, const char *value,
+						STACK_OF(CONF_VALUE) **extlist)
+{
+	CONF_VALUE *vtmp = NULL;
+	char *tname = NULL, *tvalue = NULL;
+	if(name && !(tname = BUF_strdup(name))) goto err;
+	if(value && !(tvalue = BUF_strdup(value))) goto err;
+	if(!(vtmp = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) goto err;
+	if(!*extlist && !(*extlist = sk_CONF_VALUE_new_null())) goto err;
+	vtmp->section = NULL;
+	vtmp->name = tname;
+	vtmp->value = tvalue;
+	if(!sk_CONF_VALUE_push(*extlist, vtmp)) goto err;
+	return 1;
+	err:
+	X509V3err(X509V3_F_X509V3_ADD_VALUE,ERR_R_MALLOC_FAILURE);
+	if(vtmp) OPENSSL_free(vtmp);
+	if(tname) OPENSSL_free(tname);
+	if(tvalue) OPENSSL_free(tvalue);
+	return 0;
+}
+
+int X509V3_add_value_uchar(const char *name, const unsigned char *value,
+			   STACK_OF(CONF_VALUE) **extlist)
+    {
+    return X509V3_add_value(name,(const char *)value,extlist);
+    }
+
+/* Free function for STACK_OF(CONF_VALUE) */
+
+void X509V3_conf_free(CONF_VALUE *conf)
+{
+	if(!conf) return;
+	if(conf->name) OPENSSL_free(conf->name);
+	if(conf->value) OPENSSL_free(conf->value);
+	if(conf->section) OPENSSL_free(conf->section);
+	OPENSSL_free(conf);
+}
+
+int X509V3_add_value_bool(const char *name, int asn1_bool,
+						STACK_OF(CONF_VALUE) **extlist)
+{
+	if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
+	return X509V3_add_value(name, "FALSE", extlist);
+}
+
+int X509V3_add_value_bool_nf(char *name, int asn1_bool,
+						STACK_OF(CONF_VALUE) **extlist)
+{
+	if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
+	return 1;
+}
+
+
+char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a)
+{
+	BIGNUM *bntmp = NULL;
+	char *strtmp = NULL;
+	if(!a) return NULL;
+	if(!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) ||
+	    !(strtmp = BN_bn2dec(bntmp)) )
+		X509V3err(X509V3_F_I2S_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
+	BN_free(bntmp);
+	return strtmp;
+}
+
+char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a)
+{
+	BIGNUM *bntmp = NULL;
+	char *strtmp = NULL;
+	if(!a) return NULL;
+	if(!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) ||
+	    !(strtmp = BN_bn2dec(bntmp)) )
+		X509V3err(X509V3_F_I2S_ASN1_INTEGER,ERR_R_MALLOC_FAILURE);
+	BN_free(bntmp);
+	return strtmp;
+}
+
+ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
+{
+	BIGNUM *bn = NULL;
+	ASN1_INTEGER *aint;
+	int isneg, ishex;
+	int ret;
+	if (!value) {
+		X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_INVALID_NULL_VALUE);
+		return 0;
+	}
+	bn = BN_new();
+	if (value[0] == '-') {
+		value++;
+		isneg = 1;
+	} else isneg = 0;
+
+	if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) {
+		value += 2;
+		ishex = 1;
+	} else ishex = 0;
+
+	if (ishex) ret = BN_hex2bn(&bn, value);
+	else ret = BN_dec2bn(&bn, value);
+
+	if (!ret || value[ret]) {
+		BN_free(bn);
+		X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_BN_DEC2BN_ERROR);
+		return 0;
+	}
+
+	if (isneg && BN_is_zero(bn)) isneg = 0;
+
+	aint = BN_to_ASN1_INTEGER(bn, NULL);
+	BN_free(bn);
+	if (!aint) {
+		X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
+		return 0;
+	}
+	if (isneg) aint->type |= V_ASN1_NEG;
+	return aint;
+}
+
+int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
+	     STACK_OF(CONF_VALUE) **extlist)
+{
+	char *strtmp;
+	int ret;
+	if(!aint) return 1;
+	if(!(strtmp = i2s_ASN1_INTEGER(NULL, aint))) return 0;
+	ret = X509V3_add_value(name, strtmp, extlist);
+	OPENSSL_free(strtmp);
+	return ret;
+}
+
+int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool)
+{
+	char *btmp;
+	if(!(btmp = value->value)) goto err;
+	if(!strcmp(btmp, "TRUE") || !strcmp(btmp, "true")
+		 || !strcmp(btmp, "Y") || !strcmp(btmp, "y")
+		|| !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) {
+		*asn1_bool = 0xff;
+		return 1;
+	} else if(!strcmp(btmp, "FALSE") || !strcmp(btmp, "false")
+		 || !strcmp(btmp, "N") || !strcmp(btmp, "n")
+		|| !strcmp(btmp, "NO") || !strcmp(btmp, "no")) {
+		*asn1_bool = 0;
+		return 1;
+	}
+	err:
+	X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL,X509V3_R_INVALID_BOOLEAN_STRING);
+	X509V3_conf_err(value);
+	return 0;
+}
+
+int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint)
+{
+	ASN1_INTEGER *itmp;
+	if(!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) {
+		X509V3_conf_err(value);
+		return 0;
+	}
+	*aint = itmp;
+	return 1;
+}
+
+#define HDR_NAME	1
+#define HDR_VALUE	2
+
+/*#define DEBUG*/
+
+STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
+{
+	char *p, *q, c;
+	char *ntmp, *vtmp;
+	STACK_OF(CONF_VALUE) *values = NULL;
+	char *linebuf;
+	int state;
+	/* We are going to modify the line so copy it first */
+	linebuf = BUF_strdup(line);
+	state = HDR_NAME;
+	ntmp = NULL;
+	/* Go through all characters */
+	for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) {
+
+		switch(state) {
+			case HDR_NAME:
+			if(c == ':') {
+				state = HDR_VALUE;
+				*p = 0;
+				ntmp = strip_spaces(q);
+				if(!ntmp) {
+					X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
+					goto err;
+				}
+				q = p + 1;
+			} else if(c == ',') {
+				*p = 0;
+				ntmp = strip_spaces(q);
+				q = p + 1;
+#if 0
+				printf("%s\n", ntmp);
+#endif
+				if(!ntmp) {
+					X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
+					goto err;
+				}
+				X509V3_add_value(ntmp, NULL, &values);
+			}
+			break ;
+
+			case HDR_VALUE:
+			if(c == ',') {
+				state = HDR_NAME;
+				*p = 0;
+				vtmp = strip_spaces(q);
+#if 0
+				printf("%s\n", ntmp);
+#endif
+				if(!vtmp) {
+					X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_VALUE);
+					goto err;
+				}
+				X509V3_add_value(ntmp, vtmp, &values);
+				ntmp = NULL;
+				q = p + 1;
+			}
+
+		}
+	}
+
+	if(state == HDR_VALUE) {
+		vtmp = strip_spaces(q);
+#if 0
+		printf("%s=%s\n", ntmp, vtmp);
+#endif
+		if(!vtmp) {
+			X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_VALUE);
+			goto err;
+		}
+		X509V3_add_value(ntmp, vtmp, &values);
+	} else {
+		ntmp = strip_spaces(q);
+#if 0
+		printf("%s\n", ntmp);
+#endif
+		if(!ntmp) {
+			X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
+			goto err;
+		}
+		X509V3_add_value(ntmp, NULL, &values);
+	}
+OPENSSL_free(linebuf);
+return values;
+
+err:
+OPENSSL_free(linebuf);
+sk_CONF_VALUE_pop_free(values, X509V3_conf_free);
+return NULL;
+
+}
+
+/* Delete leading and trailing spaces from a string */
+static char *strip_spaces(char *name)
+{
+	char *p, *q;
+	/* Skip over leading spaces */
+	p = name;
+	while(*p && isspace((unsigned char)*p)) p++;
+	if(!*p) return NULL;
+	q = p + strlen(p) - 1;
+	while((q != p) && isspace((unsigned char)*q)) q--;
+	if(p != q) q[1] = 0;
+	if(!*p) return NULL;
+	return p;
+}
+
+/* hex string utilities */
+
+/* Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its
+ * hex representation
+ * @@@ (Contents of buffer are always kept in ASCII, also on EBCDIC machines)
+ */
+
+char *hex_to_string(const unsigned char *buffer, long len)
+{
+	char *tmp, *q;
+	const unsigned char *p;
+	int i;
+	const static char hexdig[] = "0123456789ABCDEF";
+	if(!buffer || !len) return NULL;
+	if(!(tmp = OPENSSL_malloc(len * 3 + 1))) {
+		X509V3err(X509V3_F_HEX_TO_STRING,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	q = tmp;
+	for(i = 0, p = buffer; i < len; i++,p++) {
+		*q++ = hexdig[(*p >> 4) & 0xf];
+		*q++ = hexdig[*p & 0xf];
+		*q++ = ':';
+	}
+	q[-1] = 0;
+#ifdef CHARSET_EBCDIC
+	ebcdic2ascii(tmp, tmp, q - tmp - 1);
+#endif
+
+	return tmp;
+}
+
+/* Give a string of hex digits convert to
+ * a buffer
+ */
+
+unsigned char *string_to_hex(const char *str, long *len)
+{
+	unsigned char *hexbuf, *q;
+	unsigned char ch, cl, *p;
+	if(!str) {
+		X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_INVALID_NULL_ARGUMENT);
+		return NULL;
+	}
+	if(!(hexbuf = OPENSSL_malloc(strlen(str) >> 1))) goto err;
+	for(p = (unsigned char *)str, q = hexbuf; *p;) {
+		ch = *p++;
+#ifdef CHARSET_EBCDIC
+		ch = os_toebcdic[ch];
+#endif
+		if(ch == ':') continue;
+		cl = *p++;
+#ifdef CHARSET_EBCDIC
+		cl = os_toebcdic[cl];
+#endif
+		if(!cl) {
+			X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_ODD_NUMBER_OF_DIGITS);
+			OPENSSL_free(hexbuf);
+			return NULL;
+		}
+		if(isupper(ch)) ch = tolower(ch);
+		if(isupper(cl)) cl = tolower(cl);
+
+		if((ch >= '0') && (ch <= '9')) ch -= '0';
+		else if ((ch >= 'a') && (ch <= 'f')) ch -= 'a' - 10;
+		else goto badhex;
+
+		if((cl >= '0') && (cl <= '9')) cl -= '0';
+		else if ((cl >= 'a') && (cl <= 'f')) cl -= 'a' - 10;
+		else goto badhex;
+
+		*q++ = (ch << 4) | cl;
+	}
+
+	if(len) *len = q - hexbuf;
+
+	return hexbuf;
+
+	err:
+	if(hexbuf) OPENSSL_free(hexbuf);
+	X509V3err(X509V3_F_STRING_TO_HEX,ERR_R_MALLOC_FAILURE);
+	return NULL;
+
+	badhex:
+	OPENSSL_free(hexbuf);
+	X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_ILLEGAL_HEX_DIGIT);
+	return NULL;
+
+}
+
+/* V2I name comparison function: returns zero if 'name' matches
+ * cmp or cmp.*
+ */
+
+int name_cmp(const char *name, const char *cmp)
+{
+	int len, ret;
+	char c;
+	len = strlen(cmp);
+	if((ret = strncmp(name, cmp, len))) return ret;
+	c = name[len];
+	if(!c || (c=='.')) return 0;
+	return 1;
+}
+
+static int sk_strcmp(const char * const *a, const char * const *b)
+{
+	return strcmp(*a, *b);
+}
+
+STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x)
+{
+	GENERAL_NAMES *gens;
+	STACK_OF(OPENSSL_STRING) *ret;
+
+	gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
+	ret = get_email(X509_get_subject_name(x), gens);
+	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+	return ret;
+}
+
+STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x)
+{
+	AUTHORITY_INFO_ACCESS *info;
+	STACK_OF(OPENSSL_STRING) *ret = NULL;
+	int i;
+
+	info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
+	if (!info)
+		return NULL;
+	for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++)
+		{
+		ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
+		if (OBJ_obj2nid(ad->method) == NID_ad_OCSP)
+			{
+			if (ad->location->type == GEN_URI)
+				{
+				if (!append_ia5(&ret, ad->location->d.uniformResourceIdentifier))
+					break;
+				}
+			}
+		}
+	AUTHORITY_INFO_ACCESS_free(info);
+	return ret;
+}
+
+STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x)
+{
+	GENERAL_NAMES *gens;
+	STACK_OF(X509_EXTENSION) *exts;
+	STACK_OF(OPENSSL_STRING) *ret;
+
+	exts = X509_REQ_get_extensions(x);
+	gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
+	ret = get_email(X509_REQ_get_subject_name(x), gens);
+	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+	sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+	return ret;
+}
+
+
+static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, GENERAL_NAMES *gens)
+{
+	STACK_OF(OPENSSL_STRING) *ret = NULL;
+	X509_NAME_ENTRY *ne;
+	ASN1_IA5STRING *email;
+	GENERAL_NAME *gen;
+	int i;
+	/* Now add any email address(es) to STACK */
+	i = -1;
+	/* First supplied X509_NAME */
+	while((i = X509_NAME_get_index_by_NID(name,
+					 NID_pkcs9_emailAddress, i)) >= 0) {
+		ne = X509_NAME_get_entry(name, i);
+		email = X509_NAME_ENTRY_get_data(ne);
+		if(!append_ia5(&ret, email)) return NULL;
+	}
+	for(i = 0; i < sk_GENERAL_NAME_num(gens); i++)
+	{
+		gen = sk_GENERAL_NAME_value(gens, i);
+		if(gen->type != GEN_EMAIL) continue;
+		if(!append_ia5(&ret, gen->d.ia5)) return NULL;
+	}
+	return ret;
+}
+
+static void str_free(OPENSSL_STRING str)
+{
+	OPENSSL_free(str);
+}
+
+static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email)
+{
+	char *emtmp;
+	/* First some sanity checks */
+	if(email->type != V_ASN1_IA5STRING) return 1;
+	if(!email->data || !email->length) return 1;
+	if(!*sk) *sk = sk_OPENSSL_STRING_new(sk_strcmp);
+	if(!*sk) return 0;
+	/* Don't add duplicates */
+	if(sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1) return 1;
+	emtmp = BUF_strdup((char *)email->data);
+	if(!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) {
+		X509_email_free(*sk);
+		*sk = NULL;
+		return 0;
+	}
+	return 1;
+}
+
+void X509_email_free(STACK_OF(OPENSSL_STRING) *sk)
+{
+	sk_OPENSSL_STRING_pop_free(sk, str_free);
+}
+
+/* Convert IP addresses both IPv4 and IPv6 into an 
+ * OCTET STRING compatible with RFC3280.
+ */
+
+ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc)
+	{
+	unsigned char ipout[16];
+	ASN1_OCTET_STRING *ret;
+	int iplen;
+
+	/* If string contains a ':' assume IPv6 */
+
+	iplen = a2i_ipadd(ipout, ipasc);
+
+	if (!iplen)
+		return NULL;
+
+	ret = ASN1_OCTET_STRING_new();
+	if (!ret)
+		return NULL;
+	if (!ASN1_OCTET_STRING_set(ret, ipout, iplen))
+		{
+		ASN1_OCTET_STRING_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc)
+	{
+	ASN1_OCTET_STRING *ret = NULL;
+	unsigned char ipout[32];
+	char *iptmp = NULL, *p;
+	int iplen1, iplen2;
+	p = strchr(ipasc,'/');
+	if (!p)
+		return NULL;
+	iptmp = BUF_strdup(ipasc);
+	if (!iptmp)
+		return NULL;
+	p = iptmp + (p - ipasc);
+	*p++ = 0;
+
+	iplen1 = a2i_ipadd(ipout, iptmp);
+
+	if (!iplen1)
+		goto err;
+
+	iplen2 = a2i_ipadd(ipout + iplen1, p);
+
+	OPENSSL_free(iptmp);
+	iptmp = NULL;
+
+	if (!iplen2 || (iplen1 != iplen2))
+		goto err;
+
+	ret = ASN1_OCTET_STRING_new();
+	if (!ret)
+		goto err;
+	if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2))
+		goto err;
+
+	return ret;
+
+	err:
+	if (iptmp)
+		OPENSSL_free(iptmp);
+	if (ret)
+		ASN1_OCTET_STRING_free(ret);
+	return NULL;
+	}
+	
+
+int a2i_ipadd(unsigned char *ipout, const char *ipasc)
+	{
+	/* If string contains a ':' assume IPv6 */
+
+	if (strchr(ipasc, ':'))
+		{
+		if (!ipv6_from_asc(ipout, ipasc))
+			return 0;
+		return 16;
+		}
+	else
+		{
+		if (!ipv4_from_asc(ipout, ipasc))
+			return 0;
+		return 4;
+		}
+	}
+
+static int ipv4_from_asc(unsigned char *v4, const char *in)
+	{
+	int a0, a1, a2, a3;
+	if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
+		return 0;
+	if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
+		|| (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255))
+		return 0;
+	v4[0] = a0;
+	v4[1] = a1;
+	v4[2] = a2;
+	v4[3] = a3;
+	return 1;
+	}
+
+typedef struct {
+		/* Temporary store for IPV6 output */
+		unsigned char tmp[16];
+		/* Total number of bytes in tmp */
+		int total;
+		/* The position of a zero (corresponding to '::') */
+		int zero_pos;
+		/* Number of zeroes */
+		int zero_cnt;
+	} IPV6_STAT;
+
+
+static int ipv6_from_asc(unsigned char *v6, const char *in)
+	{
+	IPV6_STAT v6stat;
+	v6stat.total = 0;
+	v6stat.zero_pos = -1;
+	v6stat.zero_cnt = 0;
+	/* Treat the IPv6 representation as a list of values
+	 * separated by ':'. The presence of a '::' will parse
+ 	 * as one, two or three zero length elements.
+	 */
+	if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat))
+		return 0;
+
+	/* Now for some sanity checks */
+
+	if (v6stat.zero_pos == -1)
+		{
+		/* If no '::' must have exactly 16 bytes */
+		if (v6stat.total != 16)
+			return 0;
+		}
+	else 
+		{
+		/* If '::' must have less than 16 bytes */
+		if (v6stat.total == 16)
+			return 0;
+		/* More than three zeroes is an error */
+		if (v6stat.zero_cnt > 3)
+			return 0;
+		/* Can only have three zeroes if nothing else present */
+		else if (v6stat.zero_cnt == 3)
+			{
+			if (v6stat.total > 0)
+				return 0;
+			}
+		/* Can only have two zeroes if at start or end */
+		else if (v6stat.zero_cnt == 2)
+			{
+			if ((v6stat.zero_pos != 0)
+				&& (v6stat.zero_pos != v6stat.total))
+				return 0;
+			}
+		else 
+		/* Can only have one zero if *not* start or end */
+			{
+			if ((v6stat.zero_pos == 0)
+				|| (v6stat.zero_pos == v6stat.total))
+				return 0;
+			}
+		}
+
+	/* Format result */
+
+	if (v6stat.zero_pos >= 0)
+		{
+		/* Copy initial part */
+		memcpy(v6, v6stat.tmp, v6stat.zero_pos);
+		/* Zero middle */
+		memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total);
+		/* Copy final part */
+		if (v6stat.total != v6stat.zero_pos)
+			memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
+				v6stat.tmp + v6stat.zero_pos,
+				v6stat.total - v6stat.zero_pos);
+		}
+	else
+		memcpy(v6, v6stat.tmp, 16);
+
+	return 1;
+	}
+
+static int ipv6_cb(const char *elem, int len, void *usr)
+	{
+	IPV6_STAT *s = usr;
+	/* Error if 16 bytes written */
+	if (s->total == 16)
+		return 0;
+	if (len == 0)
+		{
+		/* Zero length element, corresponds to '::' */
+		if (s->zero_pos == -1)
+			s->zero_pos = s->total;
+		/* If we've already got a :: its an error */
+		else if (s->zero_pos != s->total)
+			return 0;
+		s->zero_cnt++;
+		}
+	else 
+		{
+		/* If more than 4 characters could be final a.b.c.d form */
+		if (len > 4)
+			{
+			/* Need at least 4 bytes left */
+			if (s->total > 12)
+				return 0;
+			/* Must be end of string */
+			if (elem[len])
+				return 0;
+			if (!ipv4_from_asc(s->tmp + s->total, elem))
+				return 0;
+			s->total += 4;
+			}
+		else
+			{
+			if (!ipv6_hex(s->tmp + s->total, elem, len))
+				return 0;
+			s->total += 2;
+			}
+		}
+	return 1;
+	}
+
+/* Convert a string of up to 4 hex digits into the corresponding
+ * IPv6 form.
+ */
+
+static int ipv6_hex(unsigned char *out, const char *in, int inlen)
+	{
+	unsigned char c;
+	unsigned int num = 0;
+	if (inlen > 4)
+		return 0;
+	while(inlen--)
+		{
+		c = *in++;
+		num <<= 4;
+		if ((c >= '0') && (c <= '9'))
+			num |= c - '0';
+		else if ((c >= 'A') && (c <= 'F'))
+			num |= c - 'A' + 10;
+		else if ((c >= 'a') && (c <= 'f'))
+			num |=  c - 'a' + 10;
+		else
+			return 0;
+		}
+	out[0] = num >> 8;
+	out[1] = num & 0xff;
+	return 1;
+	}
+
+
+int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk,
+						unsigned long chtype)
+	{
+	CONF_VALUE *v;
+	int i, mval;
+	char *p, *type;
+	if (!nm)
+		return 0;
+
+	for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++)
+		{
+		v=sk_CONF_VALUE_value(dn_sk,i);
+		type=v->name;
+		/* Skip past any leading X. X: X, etc to allow for
+		 * multiple instances 
+		 */
+		for(p = type; *p ; p++) 
+#ifndef CHARSET_EBCDIC
+			if ((*p == ':') || (*p == ',') || (*p == '.'))
+#else
+			if ((*p == os_toascii[':']) || (*p == os_toascii[',']) || (*p == os_toascii['.']))
+#endif
+				{
+				p++;
+				if(*p) type = p;
+				break;
+				}
+#ifndef CHARSET_EBCDIC
+		if (*type == '+')
+#else
+		if (*type == os_toascii['+'])
+#endif
+			{
+			mval = -1;
+			type++;
+			}
+		else
+			mval = 0;
+		if (!X509_NAME_add_entry_by_txt(nm,type, chtype,
+				(unsigned char *) v->value,-1,-1,mval))
+					return 0;
+
+		}
+	return 1;
+	}
diff --git a/openssl/crypto/x509v3/v3conf.c b/openssl/crypto/x509v3/v3conf.c
new file mode 100644
index 0000000..a9e6ca3
--- /dev/null
+++ b/openssl/crypto/x509v3/v3conf.c
@@ -0,0 +1,127 @@
+/* v3conf.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/conf.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+/* Test application to add extensions from a config file */
+
+int main(int argc, char **argv)
+{
+	LHASH *conf;
+	X509 *cert;
+	FILE *inf;
+	char *conf_file;
+	int i;
+	int count;
+	X509_EXTENSION *ext;
+	X509V3_add_standard_extensions();
+	ERR_load_crypto_strings();
+	if(!argv[1]) {
+		fprintf(stderr, "Usage: v3conf cert.pem [file.cnf]\n");
+		exit(1);
+	}
+	conf_file = argv[2];
+	if(!conf_file) conf_file = "test.cnf";
+	conf = CONF_load(NULL, "test.cnf", NULL);
+	if(!conf) {
+		fprintf(stderr, "Error opening Config file %s\n", conf_file);
+		ERR_print_errors_fp(stderr);
+		exit(1);
+	}
+
+	inf = fopen(argv[1], "r");
+	if(!inf) {
+		fprintf(stderr, "Can't open certificate file %s\n", argv[1]);
+		exit(1);
+	}
+	cert = PEM_read_X509(inf, NULL, NULL);
+	if(!cert) {
+		fprintf(stderr, "Error reading certificate file %s\n", argv[1]);
+		exit(1);
+	}
+	fclose(inf);
+
+	sk_pop_free(cert->cert_info->extensions, X509_EXTENSION_free);
+	cert->cert_info->extensions = NULL;
+
+	if(!X509V3_EXT_add_conf(conf, NULL, "test_section", cert)) {
+		fprintf(stderr, "Error adding extensions\n");
+		ERR_print_errors_fp(stderr);
+		exit(1);
+	}
+
+	count = X509_get_ext_count(cert);
+	printf("%d extensions\n", count);
+	for(i = 0; i < count; i++) {
+		ext = X509_get_ext(cert, i);
+		printf("%s", OBJ_nid2ln(OBJ_obj2nid(ext->object)));
+		if(ext->critical) printf(",critical:\n");
+		else printf(":\n");
+		X509V3_EXT_print_fp(stdout, ext, 0, 0);
+		printf("\n");
+		
+	}
+	return 0;
+}
+
diff --git a/openssl/crypto/x509v3/v3err.c b/openssl/crypto/x509v3/v3err.c
new file mode 100644
index 0000000..f9f6f1f
--- /dev/null
+++ b/openssl/crypto/x509v3/v3err.c
@@ -0,0 +1,226 @@
+/* crypto/x509v3/v3err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509V3,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509V3,0,reason)
+
+static ERR_STRING_DATA X509V3_str_functs[]=
+	{
+{ERR_FUNC(X509V3_F_A2I_GENERAL_NAME),	"A2I_GENERAL_NAME"},
+{ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE),	"ASIDENTIFIERCHOICE_CANONIZE"},
+{ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL),	"ASIDENTIFIERCHOICE_IS_CANONICAL"},
+{ERR_FUNC(X509V3_F_COPY_EMAIL),	"COPY_EMAIL"},
+{ERR_FUNC(X509V3_F_COPY_ISSUER),	"COPY_ISSUER"},
+{ERR_FUNC(X509V3_F_DO_DIRNAME),	"DO_DIRNAME"},
+{ERR_FUNC(X509V3_F_DO_EXT_CONF),	"DO_EXT_CONF"},
+{ERR_FUNC(X509V3_F_DO_EXT_I2D),	"DO_EXT_I2D"},
+{ERR_FUNC(X509V3_F_DO_EXT_NCONF),	"DO_EXT_NCONF"},
+{ERR_FUNC(X509V3_F_DO_I2V_NAME_CONSTRAINTS),	"DO_I2V_NAME_CONSTRAINTS"},
+{ERR_FUNC(X509V3_F_GNAMES_FROM_SECTNAME),	"GNAMES_FROM_SECTNAME"},
+{ERR_FUNC(X509V3_F_HEX_TO_STRING),	"hex_to_string"},
+{ERR_FUNC(X509V3_F_I2S_ASN1_ENUMERATED),	"i2s_ASN1_ENUMERATED"},
+{ERR_FUNC(X509V3_F_I2S_ASN1_IA5STRING),	"I2S_ASN1_IA5STRING"},
+{ERR_FUNC(X509V3_F_I2S_ASN1_INTEGER),	"i2s_ASN1_INTEGER"},
+{ERR_FUNC(X509V3_F_I2V_AUTHORITY_INFO_ACCESS),	"I2V_AUTHORITY_INFO_ACCESS"},
+{ERR_FUNC(X509V3_F_NOTICE_SECTION),	"NOTICE_SECTION"},
+{ERR_FUNC(X509V3_F_NREF_NOS),	"NREF_NOS"},
+{ERR_FUNC(X509V3_F_POLICY_SECTION),	"POLICY_SECTION"},
+{ERR_FUNC(X509V3_F_PROCESS_PCI_VALUE),	"PROCESS_PCI_VALUE"},
+{ERR_FUNC(X509V3_F_R2I_CERTPOL),	"R2I_CERTPOL"},
+{ERR_FUNC(X509V3_F_R2I_PCI),	"R2I_PCI"},
+{ERR_FUNC(X509V3_F_S2I_ASN1_IA5STRING),	"S2I_ASN1_IA5STRING"},
+{ERR_FUNC(X509V3_F_S2I_ASN1_INTEGER),	"s2i_ASN1_INTEGER"},
+{ERR_FUNC(X509V3_F_S2I_ASN1_OCTET_STRING),	"s2i_ASN1_OCTET_STRING"},
+{ERR_FUNC(X509V3_F_S2I_ASN1_SKEY_ID),	"S2I_ASN1_SKEY_ID"},
+{ERR_FUNC(X509V3_F_S2I_SKEY_ID),	"S2I_SKEY_ID"},
+{ERR_FUNC(X509V3_F_SET_DIST_POINT_NAME),	"SET_DIST_POINT_NAME"},
+{ERR_FUNC(X509V3_F_STRING_TO_HEX),	"string_to_hex"},
+{ERR_FUNC(X509V3_F_SXNET_ADD_ID_ASC),	"SXNET_add_id_asc"},
+{ERR_FUNC(X509V3_F_SXNET_ADD_ID_INTEGER),	"SXNET_add_id_INTEGER"},
+{ERR_FUNC(X509V3_F_SXNET_ADD_ID_ULONG),	"SXNET_add_id_ulong"},
+{ERR_FUNC(X509V3_F_SXNET_GET_ID_ASC),	"SXNET_get_id_asc"},
+{ERR_FUNC(X509V3_F_SXNET_GET_ID_ULONG),	"SXNET_get_id_ulong"},
+{ERR_FUNC(X509V3_F_V2I_ASIDENTIFIERS),	"V2I_ASIDENTIFIERS"},
+{ERR_FUNC(X509V3_F_V2I_ASN1_BIT_STRING),	"v2i_ASN1_BIT_STRING"},
+{ERR_FUNC(X509V3_F_V2I_AUTHORITY_INFO_ACCESS),	"V2I_AUTHORITY_INFO_ACCESS"},
+{ERR_FUNC(X509V3_F_V2I_AUTHORITY_KEYID),	"V2I_AUTHORITY_KEYID"},
+{ERR_FUNC(X509V3_F_V2I_BASIC_CONSTRAINTS),	"V2I_BASIC_CONSTRAINTS"},
+{ERR_FUNC(X509V3_F_V2I_CRLD),	"V2I_CRLD"},
+{ERR_FUNC(X509V3_F_V2I_EXTENDED_KEY_USAGE),	"V2I_EXTENDED_KEY_USAGE"},
+{ERR_FUNC(X509V3_F_V2I_GENERAL_NAMES),	"v2i_GENERAL_NAMES"},
+{ERR_FUNC(X509V3_F_V2I_GENERAL_NAME_EX),	"v2i_GENERAL_NAME_ex"},
+{ERR_FUNC(X509V3_F_V2I_IDP),	"V2I_IDP"},
+{ERR_FUNC(X509V3_F_V2I_IPADDRBLOCKS),	"V2I_IPADDRBLOCKS"},
+{ERR_FUNC(X509V3_F_V2I_ISSUER_ALT),	"V2I_ISSUER_ALT"},
+{ERR_FUNC(X509V3_F_V2I_NAME_CONSTRAINTS),	"V2I_NAME_CONSTRAINTS"},
+{ERR_FUNC(X509V3_F_V2I_POLICY_CONSTRAINTS),	"V2I_POLICY_CONSTRAINTS"},
+{ERR_FUNC(X509V3_F_V2I_POLICY_MAPPINGS),	"V2I_POLICY_MAPPINGS"},
+{ERR_FUNC(X509V3_F_V2I_SUBJECT_ALT),	"V2I_SUBJECT_ALT"},
+{ERR_FUNC(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL),	"V3_ADDR_VALIDATE_PATH_INTERNAL"},
+{ERR_FUNC(X509V3_F_V3_GENERIC_EXTENSION),	"V3_GENERIC_EXTENSION"},
+{ERR_FUNC(X509V3_F_X509V3_ADD1_I2D),	"X509V3_add1_i2d"},
+{ERR_FUNC(X509V3_F_X509V3_ADD_VALUE),	"X509V3_add_value"},
+{ERR_FUNC(X509V3_F_X509V3_EXT_ADD),	"X509V3_EXT_add"},
+{ERR_FUNC(X509V3_F_X509V3_EXT_ADD_ALIAS),	"X509V3_EXT_add_alias"},
+{ERR_FUNC(X509V3_F_X509V3_EXT_CONF),	"X509V3_EXT_conf"},
+{ERR_FUNC(X509V3_F_X509V3_EXT_I2D),	"X509V3_EXT_i2d"},
+{ERR_FUNC(X509V3_F_X509V3_EXT_NCONF),	"X509V3_EXT_nconf"},
+{ERR_FUNC(X509V3_F_X509V3_GET_SECTION),	"X509V3_get_section"},
+{ERR_FUNC(X509V3_F_X509V3_GET_STRING),	"X509V3_get_string"},
+{ERR_FUNC(X509V3_F_X509V3_GET_VALUE_BOOL),	"X509V3_get_value_bool"},
+{ERR_FUNC(X509V3_F_X509V3_PARSE_LIST),	"X509V3_parse_list"},
+{ERR_FUNC(X509V3_F_X509_PURPOSE_ADD),	"X509_PURPOSE_add"},
+{ERR_FUNC(X509V3_F_X509_PURPOSE_SET),	"X509_PURPOSE_set"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA X509V3_str_reasons[]=
+	{
+{ERR_REASON(X509V3_R_BAD_IP_ADDRESS)     ,"bad ip address"},
+{ERR_REASON(X509V3_R_BAD_OBJECT)         ,"bad object"},
+{ERR_REASON(X509V3_R_BN_DEC2BN_ERROR)    ,"bn dec2bn error"},
+{ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR),"bn to asn1 integer error"},
+{ERR_REASON(X509V3_R_DIRNAME_ERROR)      ,"dirname error"},
+{ERR_REASON(X509V3_R_DISTPOINT_ALREADY_SET),"distpoint already set"},
+{ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID)  ,"duplicate zone id"},
+{ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE),"error converting zone"},
+{ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION),"error creating extension"},
+{ERR_REASON(X509V3_R_ERROR_IN_EXTENSION) ,"error in extension"},
+{ERR_REASON(X509V3_R_EXPECTED_A_SECTION_NAME),"expected a section name"},
+{ERR_REASON(X509V3_R_EXTENSION_EXISTS)   ,"extension exists"},
+{ERR_REASON(X509V3_R_EXTENSION_NAME_ERROR),"extension name error"},
+{ERR_REASON(X509V3_R_EXTENSION_NOT_FOUND),"extension not found"},
+{ERR_REASON(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED),"extension setting not supported"},
+{ERR_REASON(X509V3_R_EXTENSION_VALUE_ERROR),"extension value error"},
+{ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION),"illegal empty extension"},
+{ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT)  ,"illegal hex digit"},
+{ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG),"incorrect policy syntax tag"},
+{ERR_REASON(X509V3_R_INVALID_MULTIPLE_RDNS),"invalid multiple rdns"},
+{ERR_REASON(X509V3_R_INVALID_ASNUMBER)   ,"invalid asnumber"},
+{ERR_REASON(X509V3_R_INVALID_ASRANGE)    ,"invalid asrange"},
+{ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING),"invalid boolean string"},
+{ERR_REASON(X509V3_R_INVALID_EXTENSION_STRING),"invalid extension string"},
+{ERR_REASON(X509V3_R_INVALID_INHERITANCE),"invalid inheritance"},
+{ERR_REASON(X509V3_R_INVALID_IPADDRESS)  ,"invalid ipaddress"},
+{ERR_REASON(X509V3_R_INVALID_NAME)       ,"invalid name"},
+{ERR_REASON(X509V3_R_INVALID_NULL_ARGUMENT),"invalid null argument"},
+{ERR_REASON(X509V3_R_INVALID_NULL_NAME)  ,"invalid null name"},
+{ERR_REASON(X509V3_R_INVALID_NULL_VALUE) ,"invalid null value"},
+{ERR_REASON(X509V3_R_INVALID_NUMBER)     ,"invalid number"},
+{ERR_REASON(X509V3_R_INVALID_NUMBERS)    ,"invalid numbers"},
+{ERR_REASON(X509V3_R_INVALID_OBJECT_IDENTIFIER),"invalid object identifier"},
+{ERR_REASON(X509V3_R_INVALID_OPTION)     ,"invalid option"},
+{ERR_REASON(X509V3_R_INVALID_POLICY_IDENTIFIER),"invalid policy identifier"},
+{ERR_REASON(X509V3_R_INVALID_PROXY_POLICY_SETTING),"invalid proxy policy setting"},
+{ERR_REASON(X509V3_R_INVALID_PURPOSE)    ,"invalid purpose"},
+{ERR_REASON(X509V3_R_INVALID_SAFI)       ,"invalid safi"},
+{ERR_REASON(X509V3_R_INVALID_SECTION)    ,"invalid section"},
+{ERR_REASON(X509V3_R_INVALID_SYNTAX)     ,"invalid syntax"},
+{ERR_REASON(X509V3_R_ISSUER_DECODE_ERROR),"issuer decode error"},
+{ERR_REASON(X509V3_R_MISSING_VALUE)      ,"missing value"},
+{ERR_REASON(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS),"need organization and numbers"},
+{ERR_REASON(X509V3_R_NO_CONFIG_DATABASE) ,"no config database"},
+{ERR_REASON(X509V3_R_NO_ISSUER_CERTIFICATE),"no issuer certificate"},
+{ERR_REASON(X509V3_R_NO_ISSUER_DETAILS)  ,"no issuer details"},
+{ERR_REASON(X509V3_R_NO_POLICY_IDENTIFIER),"no policy identifier"},
+{ERR_REASON(X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED),"no proxy cert policy language defined"},
+{ERR_REASON(X509V3_R_NO_PUBLIC_KEY)      ,"no public key"},
+{ERR_REASON(X509V3_R_NO_SUBJECT_DETAILS) ,"no subject details"},
+{ERR_REASON(X509V3_R_ODD_NUMBER_OF_DIGITS),"odd number of digits"},
+{ERR_REASON(X509V3_R_OPERATION_NOT_DEFINED),"operation not defined"},
+{ERR_REASON(X509V3_R_OTHERNAME_ERROR)    ,"othername error"},
+{ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED),"policy language already defined"},
+{ERR_REASON(X509V3_R_POLICY_PATH_LENGTH) ,"policy path length"},
+{ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED),"policy path length already defined"},
+{ERR_REASON(X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED),"policy syntax not currently supported"},
+{ERR_REASON(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY),"policy when proxy language requires no policy"},
+{ERR_REASON(X509V3_R_SECTION_NOT_FOUND)  ,"section not found"},
+{ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS),"unable to get issuer details"},
+{ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_KEYID),"unable to get issuer keyid"},
+{ERR_REASON(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT),"unknown bit string argument"},
+{ERR_REASON(X509V3_R_UNKNOWN_EXTENSION)  ,"unknown extension"},
+{ERR_REASON(X509V3_R_UNKNOWN_EXTENSION_NAME),"unknown extension name"},
+{ERR_REASON(X509V3_R_UNKNOWN_OPTION)     ,"unknown option"},
+{ERR_REASON(X509V3_R_UNSUPPORTED_OPTION) ,"unsupported option"},
+{ERR_REASON(X509V3_R_UNSUPPORTED_TYPE)   ,"unsupported type"},
+{ERR_REASON(X509V3_R_USER_TOO_LONG)      ,"user too long"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_X509V3_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,X509V3_str_functs);
+		ERR_load_strings(0,X509V3_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/crypto/x509v3/v3prin.c b/openssl/crypto/x509v3/v3prin.c
new file mode 100644
index 0000000..d5ff268
--- /dev/null
+++ b/openssl/crypto/x509v3/v3prin.c
@@ -0,0 +1,99 @@
+/* v3prin.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+
+#include <stdio.h>
+#include <openssl/asn1.h>
+#include <openssl/conf.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+int main(int argc, char **argv)
+{
+	X509 *cert;
+	FILE *inf;
+	int i, count;
+	X509_EXTENSION *ext;
+	X509V3_add_standard_extensions();
+	ERR_load_crypto_strings();
+	if(!argv[1]) {
+		fprintf(stderr, "Usage v3prin cert.pem\n");
+		exit(1);
+	}
+	if(!(inf = fopen(argv[1], "r"))) {
+		fprintf(stderr, "Can't open %s\n", argv[1]);
+		exit(1);
+	}
+	if(!(cert = PEM_read_X509(inf, NULL, NULL))) {
+		fprintf(stderr, "Can't read certificate %s\n", argv[1]);
+		ERR_print_errors_fp(stderr);
+		exit(1);
+	}
+	fclose(inf);
+	count = X509_get_ext_count(cert);
+	printf("%d extensions\n", count);
+	for(i = 0; i < count; i++) {
+		ext = X509_get_ext(cert, i);
+		printf("%s\n", OBJ_nid2ln(OBJ_obj2nid(ext->object)));
+		if(!X509V3_EXT_print_fp(stdout, ext, 0, 0)) ERR_print_errors_fp(stderr);
+		printf("\n");
+		
+	}
+	return 0;
+}
diff --git a/openssl/crypto/x509v3/x509v3.h b/openssl/crypto/x509v3/x509v3.h
new file mode 100644
index 0000000..b308abe
--- /dev/null
+++ b/openssl/crypto/x509v3/x509v3.h
@@ -0,0 +1,1007 @@
+/* x509v3.h */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef HEADER_X509V3_H
+#define HEADER_X509V3_H
+
+#include <openssl/bio.h>
+#include <openssl/x509.h>
+#include <openssl/conf.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Forward reference */
+struct v3_ext_method;
+struct v3_ext_ctx;
+
+/* Useful typedefs */
+
+typedef void * (*X509V3_EXT_NEW)(void);
+typedef void (*X509V3_EXT_FREE)(void *);
+typedef void * (*X509V3_EXT_D2I)(void *, const unsigned char ** , long);
+typedef int (*X509V3_EXT_I2D)(void *, unsigned char **);
+typedef STACK_OF(CONF_VALUE) *
+  (*X509V3_EXT_I2V)(const struct v3_ext_method *method, void *ext,
+		    STACK_OF(CONF_VALUE) *extlist);
+typedef void * (*X509V3_EXT_V2I)(const struct v3_ext_method *method,
+				 struct v3_ext_ctx *ctx,
+				 STACK_OF(CONF_VALUE) *values);
+typedef char * (*X509V3_EXT_I2S)(const struct v3_ext_method *method, void *ext);
+typedef void * (*X509V3_EXT_S2I)(const struct v3_ext_method *method,
+				 struct v3_ext_ctx *ctx, const char *str);
+typedef int (*X509V3_EXT_I2R)(const struct v3_ext_method *method, void *ext,
+			      BIO *out, int indent);
+typedef void * (*X509V3_EXT_R2I)(const struct v3_ext_method *method,
+				 struct v3_ext_ctx *ctx, const char *str);
+
+/* V3 extension structure */
+
+struct v3_ext_method {
+int ext_nid;
+int ext_flags;
+/* If this is set the following four fields are ignored */
+ASN1_ITEM_EXP *it;
+/* Old style ASN1 calls */
+X509V3_EXT_NEW ext_new;
+X509V3_EXT_FREE ext_free;
+X509V3_EXT_D2I d2i;
+X509V3_EXT_I2D i2d;
+
+/* The following pair is used for string extensions */
+X509V3_EXT_I2S i2s;
+X509V3_EXT_S2I s2i;
+
+/* The following pair is used for multi-valued extensions */
+X509V3_EXT_I2V i2v;
+X509V3_EXT_V2I v2i;
+
+/* The following are used for raw extensions */
+X509V3_EXT_I2R i2r;
+X509V3_EXT_R2I r2i;
+
+void *usr_data;	/* Any extension specific data */
+};
+
+typedef struct X509V3_CONF_METHOD_st {
+char * (*get_string)(void *db, char *section, char *value);
+STACK_OF(CONF_VALUE) * (*get_section)(void *db, char *section);
+void (*free_string)(void *db, char * string);
+void (*free_section)(void *db, STACK_OF(CONF_VALUE) *section);
+} X509V3_CONF_METHOD;
+
+/* Context specific info */
+struct v3_ext_ctx {
+#define CTX_TEST 0x1
+int flags;
+X509 *issuer_cert;
+X509 *subject_cert;
+X509_REQ *subject_req;
+X509_CRL *crl;
+X509V3_CONF_METHOD *db_meth;
+void *db;
+/* Maybe more here */
+};
+
+typedef struct v3_ext_method X509V3_EXT_METHOD;
+
+DECLARE_STACK_OF(X509V3_EXT_METHOD)
+
+/* ext_flags values */
+#define X509V3_EXT_DYNAMIC	0x1
+#define X509V3_EXT_CTX_DEP	0x2
+#define X509V3_EXT_MULTILINE	0x4
+
+typedef BIT_STRING_BITNAME ENUMERATED_NAMES;
+
+typedef struct BASIC_CONSTRAINTS_st {
+int ca;
+ASN1_INTEGER *pathlen;
+} BASIC_CONSTRAINTS;
+
+
+typedef struct PKEY_USAGE_PERIOD_st {
+ASN1_GENERALIZEDTIME *notBefore;
+ASN1_GENERALIZEDTIME *notAfter;
+} PKEY_USAGE_PERIOD;
+
+typedef struct otherName_st {
+ASN1_OBJECT *type_id;
+ASN1_TYPE *value;
+} OTHERNAME;
+
+typedef struct EDIPartyName_st {
+	ASN1_STRING *nameAssigner;
+	ASN1_STRING *partyName;
+} EDIPARTYNAME;
+
+typedef struct GENERAL_NAME_st {
+
+#define GEN_OTHERNAME	0
+#define GEN_EMAIL	1
+#define GEN_DNS		2
+#define GEN_X400	3
+#define GEN_DIRNAME	4
+#define GEN_EDIPARTY	5
+#define GEN_URI		6
+#define GEN_IPADD	7
+#define GEN_RID		8
+
+int type;
+union {
+	char *ptr;
+	OTHERNAME *otherName; /* otherName */
+	ASN1_IA5STRING *rfc822Name;
+	ASN1_IA5STRING *dNSName;
+	ASN1_TYPE *x400Address;
+	X509_NAME *directoryName;
+	EDIPARTYNAME *ediPartyName;
+	ASN1_IA5STRING *uniformResourceIdentifier;
+	ASN1_OCTET_STRING *iPAddress;
+	ASN1_OBJECT *registeredID;
+
+	/* Old names */
+	ASN1_OCTET_STRING *ip; /* iPAddress */
+	X509_NAME *dirn;		/* dirn */
+	ASN1_IA5STRING *ia5;/* rfc822Name, dNSName, uniformResourceIdentifier */
+	ASN1_OBJECT *rid; /* registeredID */
+	ASN1_TYPE *other; /* x400Address */
+} d;
+} GENERAL_NAME;
+
+typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;
+
+typedef struct ACCESS_DESCRIPTION_st {
+	ASN1_OBJECT *method;
+	GENERAL_NAME *location;
+} ACCESS_DESCRIPTION;
+
+typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
+
+typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE;
+
+DECLARE_STACK_OF(GENERAL_NAME)
+DECLARE_ASN1_SET_OF(GENERAL_NAME)
+
+DECLARE_STACK_OF(ACCESS_DESCRIPTION)
+DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION)
+
+typedef struct DIST_POINT_NAME_st {
+int type;
+union {
+	GENERAL_NAMES *fullname;
+	STACK_OF(X509_NAME_ENTRY) *relativename;
+} name;
+/* If relativename then this contains the full distribution point name */
+X509_NAME *dpname;
+} DIST_POINT_NAME;
+/* All existing reasons */
+#define CRLDP_ALL_REASONS	0x807f
+
+#define CRL_REASON_NONE				-1
+#define CRL_REASON_UNSPECIFIED			0
+#define CRL_REASON_KEY_COMPROMISE		1
+#define CRL_REASON_CA_COMPROMISE		2
+#define CRL_REASON_AFFILIATION_CHANGED		3
+#define CRL_REASON_SUPERSEDED			4
+#define CRL_REASON_CESSATION_OF_OPERATION	5
+#define CRL_REASON_CERTIFICATE_HOLD		6
+#define CRL_REASON_REMOVE_FROM_CRL		8
+#define CRL_REASON_PRIVILEGE_WITHDRAWN		9
+#define CRL_REASON_AA_COMPROMISE		10
+
+struct DIST_POINT_st {
+DIST_POINT_NAME	*distpoint;
+ASN1_BIT_STRING *reasons;
+GENERAL_NAMES *CRLissuer;
+int dp_reasons;
+};
+
+typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS;
+
+DECLARE_STACK_OF(DIST_POINT)
+DECLARE_ASN1_SET_OF(DIST_POINT)
+
+struct AUTHORITY_KEYID_st {
+ASN1_OCTET_STRING *keyid;
+GENERAL_NAMES *issuer;
+ASN1_INTEGER *serial;
+};
+
+/* Strong extranet structures */
+
+typedef struct SXNET_ID_st {
+	ASN1_INTEGER *zone;
+	ASN1_OCTET_STRING *user;
+} SXNETID;
+
+DECLARE_STACK_OF(SXNETID)
+DECLARE_ASN1_SET_OF(SXNETID)
+
+typedef struct SXNET_st {
+	ASN1_INTEGER *version;
+	STACK_OF(SXNETID) *ids;
+} SXNET;
+
+typedef struct NOTICEREF_st {
+	ASN1_STRING *organization;
+	STACK_OF(ASN1_INTEGER) *noticenos;
+} NOTICEREF;
+
+typedef struct USERNOTICE_st {
+	NOTICEREF *noticeref;
+	ASN1_STRING *exptext;
+} USERNOTICE;
+
+typedef struct POLICYQUALINFO_st {
+	ASN1_OBJECT *pqualid;
+	union {
+		ASN1_IA5STRING *cpsuri;
+		USERNOTICE *usernotice;
+		ASN1_TYPE *other;
+	} d;
+} POLICYQUALINFO;
+
+DECLARE_STACK_OF(POLICYQUALINFO)
+DECLARE_ASN1_SET_OF(POLICYQUALINFO)
+
+typedef struct POLICYINFO_st {
+	ASN1_OBJECT *policyid;
+	STACK_OF(POLICYQUALINFO) *qualifiers;
+} POLICYINFO;
+
+typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES;
+
+DECLARE_STACK_OF(POLICYINFO)
+DECLARE_ASN1_SET_OF(POLICYINFO)
+
+typedef struct POLICY_MAPPING_st {
+	ASN1_OBJECT *issuerDomainPolicy;
+	ASN1_OBJECT *subjectDomainPolicy;
+} POLICY_MAPPING;
+
+DECLARE_STACK_OF(POLICY_MAPPING)
+
+typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS;
+
+typedef struct GENERAL_SUBTREE_st {
+	GENERAL_NAME *base;
+	ASN1_INTEGER *minimum;
+	ASN1_INTEGER *maximum;
+} GENERAL_SUBTREE;
+
+DECLARE_STACK_OF(GENERAL_SUBTREE)
+
+struct NAME_CONSTRAINTS_st {
+	STACK_OF(GENERAL_SUBTREE) *permittedSubtrees;
+	STACK_OF(GENERAL_SUBTREE) *excludedSubtrees;
+};
+
+typedef struct POLICY_CONSTRAINTS_st {
+	ASN1_INTEGER *requireExplicitPolicy;
+	ASN1_INTEGER *inhibitPolicyMapping;
+} POLICY_CONSTRAINTS;
+
+/* Proxy certificate structures, see RFC 3820 */
+typedef struct PROXY_POLICY_st
+	{
+	ASN1_OBJECT *policyLanguage;
+	ASN1_OCTET_STRING *policy;
+	} PROXY_POLICY;
+
+typedef struct PROXY_CERT_INFO_EXTENSION_st
+	{
+	ASN1_INTEGER *pcPathLengthConstraint;
+	PROXY_POLICY *proxyPolicy;
+	} PROXY_CERT_INFO_EXTENSION;
+
+DECLARE_ASN1_FUNCTIONS(PROXY_POLICY)
+DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
+
+struct ISSUING_DIST_POINT_st
+	{
+	DIST_POINT_NAME *distpoint;
+	int onlyuser;
+	int onlyCA;
+	ASN1_BIT_STRING *onlysomereasons;
+	int indirectCRL;
+	int onlyattr;
+	};
+
+/* Values in idp_flags field */
+/* IDP present */
+#define	IDP_PRESENT	0x1
+/* IDP values inconsistent */
+#define IDP_INVALID	0x2
+/* onlyuser true */
+#define	IDP_ONLYUSER	0x4
+/* onlyCA true */
+#define	IDP_ONLYCA	0x8
+/* onlyattr true */
+#define IDP_ONLYATTR	0x10
+/* indirectCRL true */
+#define IDP_INDIRECT	0x20
+/* onlysomereasons present */
+#define IDP_REASONS	0x40
+
+#define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \
+",name:", val->name, ",value:", val->value);
+
+#define X509V3_set_ctx_test(ctx) \
+			X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST)
+#define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL;
+
+#define EXT_BITSTRING(nid, table) { nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), \
+			0,0,0,0, \
+			0,0, \
+			(X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \
+			(X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \
+			NULL, NULL, \
+			table}
+
+#define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \
+			0,0,0,0, \
+			(X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \
+			(X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \
+			0,0,0,0, \
+			NULL}
+
+#define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+
+
+/* X509_PURPOSE stuff */
+
+#define EXFLAG_BCONS		0x1
+#define EXFLAG_KUSAGE		0x2
+#define EXFLAG_XKUSAGE		0x4
+#define EXFLAG_NSCERT		0x8
+
+#define EXFLAG_CA		0x10
+/* Really self issued not necessarily self signed */
+#define EXFLAG_SI		0x20
+#define EXFLAG_SS		0x20
+#define EXFLAG_V1		0x40
+#define EXFLAG_INVALID		0x80
+#define EXFLAG_SET		0x100
+#define EXFLAG_CRITICAL		0x200
+#define EXFLAG_PROXY		0x400
+
+#define EXFLAG_INVALID_POLICY	0x800
+#define EXFLAG_FRESHEST		0x1000
+
+#define KU_DIGITAL_SIGNATURE	0x0080
+#define KU_NON_REPUDIATION	0x0040
+#define KU_KEY_ENCIPHERMENT	0x0020
+#define KU_DATA_ENCIPHERMENT	0x0010
+#define KU_KEY_AGREEMENT	0x0008
+#define KU_KEY_CERT_SIGN	0x0004
+#define KU_CRL_SIGN		0x0002
+#define KU_ENCIPHER_ONLY	0x0001
+#define KU_DECIPHER_ONLY	0x8000
+
+#define NS_SSL_CLIENT		0x80
+#define NS_SSL_SERVER		0x40
+#define NS_SMIME		0x20
+#define NS_OBJSIGN		0x10
+#define NS_SSL_CA		0x04
+#define NS_SMIME_CA		0x02
+#define NS_OBJSIGN_CA		0x01
+#define NS_ANY_CA		(NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA)
+
+#define XKU_SSL_SERVER		0x1	
+#define XKU_SSL_CLIENT		0x2
+#define XKU_SMIME		0x4
+#define XKU_CODE_SIGN		0x8
+#define XKU_SGC			0x10
+#define XKU_OCSP_SIGN		0x20
+#define XKU_TIMESTAMP		0x40
+#define XKU_DVCS		0x80
+
+#define X509_PURPOSE_DYNAMIC	0x1
+#define X509_PURPOSE_DYNAMIC_NAME	0x2
+
+typedef struct x509_purpose_st {
+	int purpose;
+	int trust;		/* Default trust ID */
+	int flags;
+	int (*check_purpose)(const struct x509_purpose_st *,
+				const X509 *, int);
+	char *name;
+	char *sname;
+	void *usr_data;
+} X509_PURPOSE;
+
+#define X509_PURPOSE_SSL_CLIENT		1
+#define X509_PURPOSE_SSL_SERVER		2
+#define X509_PURPOSE_NS_SSL_SERVER	3
+#define X509_PURPOSE_SMIME_SIGN		4
+#define X509_PURPOSE_SMIME_ENCRYPT	5
+#define X509_PURPOSE_CRL_SIGN		6
+#define X509_PURPOSE_ANY		7
+#define X509_PURPOSE_OCSP_HELPER	8
+#define X509_PURPOSE_TIMESTAMP_SIGN	9
+
+#define X509_PURPOSE_MIN		1
+#define X509_PURPOSE_MAX		9
+
+/* Flags for X509V3_EXT_print() */
+
+#define X509V3_EXT_UNKNOWN_MASK		(0xfL << 16)
+/* Return error for unknown extensions */
+#define X509V3_EXT_DEFAULT		0
+/* Print error for unknown extensions */
+#define X509V3_EXT_ERROR_UNKNOWN	(1L << 16)
+/* ASN1 parse unknown extensions */
+#define X509V3_EXT_PARSE_UNKNOWN	(2L << 16)
+/* BIO_dump unknown extensions */
+#define X509V3_EXT_DUMP_UNKNOWN		(3L << 16)
+
+/* Flags for X509V3_add1_i2d */
+
+#define X509V3_ADD_OP_MASK		0xfL
+#define X509V3_ADD_DEFAULT		0L
+#define X509V3_ADD_APPEND		1L
+#define X509V3_ADD_REPLACE		2L
+#define X509V3_ADD_REPLACE_EXISTING	3L
+#define X509V3_ADD_KEEP_EXISTING	4L
+#define X509V3_ADD_DELETE		5L
+#define X509V3_ADD_SILENT		0x10
+
+DECLARE_STACK_OF(X509_PURPOSE)
+
+DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS)
+
+DECLARE_ASN1_FUNCTIONS(SXNET)
+DECLARE_ASN1_FUNCTIONS(SXNETID)
+
+int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen); 
+int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user, int userlen); 
+int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, char *user, int userlen); 
+
+ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone);
+ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone);
+ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone);
+
+DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID)
+
+DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
+
+DECLARE_ASN1_FUNCTIONS(GENERAL_NAME)
+GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a);
+int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b);
+
+
+
+ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+				ASN1_BIT_STRING *bits,
+				STACK_OF(CONF_VALUE) *extlist);
+
+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret);
+int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen);
+
+DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES)
+
+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
+		GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist);
+GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
+				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+
+DECLARE_ASN1_FUNCTIONS(OTHERNAME)
+DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME)
+int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b);
+void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value);
+void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype);
+int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
+				ASN1_OBJECT *oid, ASN1_TYPE *value);
+int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, 
+				ASN1_OBJECT **poid, ASN1_TYPE **pvalue);
+
+char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *ia5);
+ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
+
+DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
+int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION* a);
+
+DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)
+DECLARE_ASN1_FUNCTIONS(POLICYINFO)
+DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO)
+DECLARE_ASN1_FUNCTIONS(USERNOTICE)
+DECLARE_ASN1_FUNCTIONS(NOTICEREF)
+
+DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS)
+DECLARE_ASN1_FUNCTIONS(DIST_POINT)
+DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME)
+DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
+
+int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname);
+
+int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc);
+
+DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
+DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
+
+DECLARE_ASN1_ITEM(POLICY_MAPPING)
+DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
+DECLARE_ASN1_ITEM(POLICY_MAPPINGS)
+
+DECLARE_ASN1_ITEM(GENERAL_SUBTREE)
+DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
+
+DECLARE_ASN1_ITEM(NAME_CONSTRAINTS)
+DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
+DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS)
+
+GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
+			       const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+			       int gen_type, char *value, int is_nc);
+
+#ifdef HEADER_CONF_H
+GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+			       CONF_VALUE *cnf);
+GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
+				  const X509V3_EXT_METHOD *method,
+				  X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc);
+void X509V3_conf_free(CONF_VALUE *val);
+
+X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, char *value);
+X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, char *value);
+int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, STACK_OF(X509_EXTENSION) **sk);
+int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509 *cert);
+int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_REQ *req);
+int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl);
+
+X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+				    int ext_nid, char *value);
+X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+				char *name, char *value);
+int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+			char *section, X509 *cert);
+int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+			    char *section, X509_REQ *req);
+int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+			    char *section, X509_CRL *crl);
+
+int X509V3_add_value_bool_nf(char *name, int asn1_bool,
+			     STACK_OF(CONF_VALUE) **extlist);
+int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool);
+int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint);
+void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf);
+void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash);
+#endif
+
+char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section);
+STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section);
+void X509V3_string_free(X509V3_CTX *ctx, char *str);
+void X509V3_section_free( X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section);
+void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject,
+				 X509_REQ *req, X509_CRL *crl, int flags);
+
+int X509V3_add_value(const char *name, const char *value,
+						STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_uchar(const char *name, const unsigned char *value,
+						STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_bool(const char *name, int asn1_bool,
+						STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
+						STACK_OF(CONF_VALUE) **extlist);
+char * i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint);
+ASN1_INTEGER * s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value);
+char * i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
+char * i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
+int X509V3_EXT_add(X509V3_EXT_METHOD *ext);
+int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist);
+int X509V3_EXT_add_alias(int nid_to, int nid_from);
+void X509V3_EXT_cleanup(void);
+
+const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext);
+const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid);
+int X509V3_add_standard_extensions(void);
+STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line);
+void *X509V3_EXT_d2i(X509_EXTENSION *ext);
+void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx);
+
+
+X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
+int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags);
+
+char *hex_to_string(const unsigned char *buffer, long len);
+unsigned char *string_to_hex(const char *str, long *len);
+int name_cmp(const char *name, const char *cmp);
+
+void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
+								 int ml);
+int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent);
+int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent);
+
+int X509V3_extensions_print(BIO *out, char *title, STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent);
+
+int X509_check_ca(X509 *x);
+int X509_check_purpose(X509 *x, int id, int ca);
+int X509_supported_extension(X509_EXTENSION *ex);
+int X509_PURPOSE_set(int *p, int purpose);
+int X509_check_issued(X509 *issuer, X509 *subject);
+int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid);
+int X509_PURPOSE_get_count(void);
+X509_PURPOSE * X509_PURPOSE_get0(int idx);
+int X509_PURPOSE_get_by_sname(char *sname);
+int X509_PURPOSE_get_by_id(int id);
+int X509_PURPOSE_add(int id, int trust, int flags,
+			int (*ck)(const X509_PURPOSE *, const X509 *, int),
+				char *name, char *sname, void *arg);
+char *X509_PURPOSE_get0_name(X509_PURPOSE *xp);
+char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp);
+int X509_PURPOSE_get_trust(X509_PURPOSE *xp);
+void X509_PURPOSE_cleanup(void);
+int X509_PURPOSE_get_id(X509_PURPOSE *);
+
+STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x);
+STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x);
+void X509_email_free(STACK_OF(OPENSSL_STRING) *sk);
+STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x);
+
+ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
+ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
+int a2i_ipadd(unsigned char *ipout, const char *ipasc);
+int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk,
+						unsigned long chtype);
+
+void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent);
+DECLARE_STACK_OF(X509_POLICY_NODE)
+
+#ifndef OPENSSL_NO_RFC3779
+
+typedef struct ASRange_st {
+  ASN1_INTEGER *min, *max;
+} ASRange;
+
+#define	ASIdOrRange_id		0
+#define	ASIdOrRange_range	1
+
+typedef struct ASIdOrRange_st {
+  int type;
+  union {
+    ASN1_INTEGER *id;
+    ASRange      *range;
+  } u;
+} ASIdOrRange;
+
+typedef STACK_OF(ASIdOrRange) ASIdOrRanges;
+DECLARE_STACK_OF(ASIdOrRange)
+
+#define	ASIdentifierChoice_inherit		0
+#define	ASIdentifierChoice_asIdsOrRanges	1
+
+typedef struct ASIdentifierChoice_st {
+  int type;
+  union {
+    ASN1_NULL    *inherit;
+    ASIdOrRanges *asIdsOrRanges;
+  } u;
+} ASIdentifierChoice;
+
+typedef struct ASIdentifiers_st {
+  ASIdentifierChoice *asnum, *rdi;
+} ASIdentifiers;
+
+DECLARE_ASN1_FUNCTIONS(ASRange)
+DECLARE_ASN1_FUNCTIONS(ASIdOrRange)
+DECLARE_ASN1_FUNCTIONS(ASIdentifierChoice)
+DECLARE_ASN1_FUNCTIONS(ASIdentifiers)
+
+
+typedef struct IPAddressRange_st {
+  ASN1_BIT_STRING	*min, *max;
+} IPAddressRange;
+
+#define	IPAddressOrRange_addressPrefix	0
+#define	IPAddressOrRange_addressRange	1
+
+typedef struct IPAddressOrRange_st {
+  int type;
+  union {
+    ASN1_BIT_STRING	*addressPrefix;
+    IPAddressRange	*addressRange;
+  } u;
+} IPAddressOrRange;
+
+typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges;
+DECLARE_STACK_OF(IPAddressOrRange)
+
+#define	IPAddressChoice_inherit			0
+#define	IPAddressChoice_addressesOrRanges	1
+
+typedef struct IPAddressChoice_st {
+  int type;
+  union {
+    ASN1_NULL		*inherit;
+    IPAddressOrRanges	*addressesOrRanges;
+  } u;
+} IPAddressChoice;
+
+typedef struct IPAddressFamily_st {
+  ASN1_OCTET_STRING	*addressFamily;
+  IPAddressChoice	*ipAddressChoice;
+} IPAddressFamily;
+
+typedef STACK_OF(IPAddressFamily) IPAddrBlocks;
+DECLARE_STACK_OF(IPAddressFamily)
+
+DECLARE_ASN1_FUNCTIONS(IPAddressRange)
+DECLARE_ASN1_FUNCTIONS(IPAddressOrRange)
+DECLARE_ASN1_FUNCTIONS(IPAddressChoice)
+DECLARE_ASN1_FUNCTIONS(IPAddressFamily)
+
+/*
+ * API tag for elements of the ASIdentifer SEQUENCE.
+ */
+#define	V3_ASID_ASNUM	0
+#define	V3_ASID_RDI	1
+
+/*
+ * AFI values, assigned by IANA.  It'd be nice to make the AFI
+ * handling code totally generic, but there are too many little things
+ * that would need to be defined for other address families for it to
+ * be worth the trouble.
+ */
+#define	IANA_AFI_IPV4	1
+#define	IANA_AFI_IPV6	2
+
+/*
+ * Utilities to construct and extract values from RFC3779 extensions,
+ * since some of the encodings (particularly for IP address prefixes
+ * and ranges) are a bit tedious to work with directly.
+ */
+int v3_asid_add_inherit(ASIdentifiers *asid, int which);
+int v3_asid_add_id_or_range(ASIdentifiers *asid, int which,
+			    ASN1_INTEGER *min, ASN1_INTEGER *max);
+int v3_addr_add_inherit(IPAddrBlocks *addr,
+			const unsigned afi, const unsigned *safi);
+int v3_addr_add_prefix(IPAddrBlocks *addr,
+		       const unsigned afi, const unsigned *safi,
+		       unsigned char *a, const int prefixlen);
+int v3_addr_add_range(IPAddrBlocks *addr,
+		      const unsigned afi, const unsigned *safi,
+		      unsigned char *min, unsigned char *max);
+unsigned v3_addr_get_afi(const IPAddressFamily *f);
+int v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi,
+		      unsigned char *min, unsigned char *max,
+		      const int length);
+
+/*
+ * Canonical forms.
+ */
+int v3_asid_is_canonical(ASIdentifiers *asid);
+int v3_addr_is_canonical(IPAddrBlocks *addr);
+int v3_asid_canonize(ASIdentifiers *asid);
+int v3_addr_canonize(IPAddrBlocks *addr);
+
+/*
+ * Tests for inheritance and containment.
+ */
+int v3_asid_inherits(ASIdentifiers *asid);
+int v3_addr_inherits(IPAddrBlocks *addr);
+int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b);
+int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b);
+
+/*
+ * Check whether RFC 3779 extensions nest properly in chains.
+ */
+int v3_asid_validate_path(X509_STORE_CTX *);
+int v3_addr_validate_path(X509_STORE_CTX *);
+int v3_asid_validate_resource_set(STACK_OF(X509) *chain,
+				  ASIdentifiers *ext,
+				  int allow_inheritance);
+int v3_addr_validate_resource_set(STACK_OF(X509) *chain,
+				  IPAddrBlocks *ext,
+				  int allow_inheritance);
+
+#endif /* OPENSSL_NO_RFC3779 */
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_X509V3_strings(void);
+
+/* Error codes for the X509V3 functions. */
+
+/* Function codes. */
+#define X509V3_F_A2I_GENERAL_NAME			 164
+#define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE		 161
+#define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL	 162
+#define X509V3_F_COPY_EMAIL				 122
+#define X509V3_F_COPY_ISSUER				 123
+#define X509V3_F_DO_DIRNAME				 144
+#define X509V3_F_DO_EXT_CONF				 124
+#define X509V3_F_DO_EXT_I2D				 135
+#define X509V3_F_DO_EXT_NCONF				 151
+#define X509V3_F_DO_I2V_NAME_CONSTRAINTS		 148
+#define X509V3_F_GNAMES_FROM_SECTNAME			 156
+#define X509V3_F_HEX_TO_STRING				 111
+#define X509V3_F_I2S_ASN1_ENUMERATED			 121
+#define X509V3_F_I2S_ASN1_IA5STRING			 149
+#define X509V3_F_I2S_ASN1_INTEGER			 120
+#define X509V3_F_I2V_AUTHORITY_INFO_ACCESS		 138
+#define X509V3_F_NOTICE_SECTION				 132
+#define X509V3_F_NREF_NOS				 133
+#define X509V3_F_POLICY_SECTION				 131
+#define X509V3_F_PROCESS_PCI_VALUE			 150
+#define X509V3_F_R2I_CERTPOL				 130
+#define X509V3_F_R2I_PCI				 155
+#define X509V3_F_S2I_ASN1_IA5STRING			 100
+#define X509V3_F_S2I_ASN1_INTEGER			 108
+#define X509V3_F_S2I_ASN1_OCTET_STRING			 112
+#define X509V3_F_S2I_ASN1_SKEY_ID			 114
+#define X509V3_F_S2I_SKEY_ID				 115
+#define X509V3_F_SET_DIST_POINT_NAME			 158
+#define X509V3_F_STRING_TO_HEX				 113
+#define X509V3_F_SXNET_ADD_ID_ASC			 125
+#define X509V3_F_SXNET_ADD_ID_INTEGER			 126
+#define X509V3_F_SXNET_ADD_ID_ULONG			 127
+#define X509V3_F_SXNET_GET_ID_ASC			 128
+#define X509V3_F_SXNET_GET_ID_ULONG			 129
+#define X509V3_F_V2I_ASIDENTIFIERS			 163
+#define X509V3_F_V2I_ASN1_BIT_STRING			 101
+#define X509V3_F_V2I_AUTHORITY_INFO_ACCESS		 139
+#define X509V3_F_V2I_AUTHORITY_KEYID			 119
+#define X509V3_F_V2I_BASIC_CONSTRAINTS			 102
+#define X509V3_F_V2I_CRLD				 134
+#define X509V3_F_V2I_EXTENDED_KEY_USAGE			 103
+#define X509V3_F_V2I_GENERAL_NAMES			 118
+#define X509V3_F_V2I_GENERAL_NAME_EX			 117
+#define X509V3_F_V2I_IDP				 157
+#define X509V3_F_V2I_IPADDRBLOCKS			 159
+#define X509V3_F_V2I_ISSUER_ALT				 153
+#define X509V3_F_V2I_NAME_CONSTRAINTS			 147
+#define X509V3_F_V2I_POLICY_CONSTRAINTS			 146
+#define X509V3_F_V2I_POLICY_MAPPINGS			 145
+#define X509V3_F_V2I_SUBJECT_ALT			 154
+#define X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL		 160
+#define X509V3_F_V3_GENERIC_EXTENSION			 116
+#define X509V3_F_X509V3_ADD1_I2D			 140
+#define X509V3_F_X509V3_ADD_VALUE			 105
+#define X509V3_F_X509V3_EXT_ADD				 104
+#define X509V3_F_X509V3_EXT_ADD_ALIAS			 106
+#define X509V3_F_X509V3_EXT_CONF			 107
+#define X509V3_F_X509V3_EXT_I2D				 136
+#define X509V3_F_X509V3_EXT_NCONF			 152
+#define X509V3_F_X509V3_GET_SECTION			 142
+#define X509V3_F_X509V3_GET_STRING			 143
+#define X509V3_F_X509V3_GET_VALUE_BOOL			 110
+#define X509V3_F_X509V3_PARSE_LIST			 109
+#define X509V3_F_X509_PURPOSE_ADD			 137
+#define X509V3_F_X509_PURPOSE_SET			 141
+
+/* Reason codes. */
+#define X509V3_R_BAD_IP_ADDRESS				 118
+#define X509V3_R_BAD_OBJECT				 119
+#define X509V3_R_BN_DEC2BN_ERROR			 100
+#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR		 101
+#define X509V3_R_DIRNAME_ERROR				 149
+#define X509V3_R_DISTPOINT_ALREADY_SET			 160
+#define X509V3_R_DUPLICATE_ZONE_ID			 133
+#define X509V3_R_ERROR_CONVERTING_ZONE			 131
+#define X509V3_R_ERROR_CREATING_EXTENSION		 144
+#define X509V3_R_ERROR_IN_EXTENSION			 128
+#define X509V3_R_EXPECTED_A_SECTION_NAME		 137
+#define X509V3_R_EXTENSION_EXISTS			 145
+#define X509V3_R_EXTENSION_NAME_ERROR			 115
+#define X509V3_R_EXTENSION_NOT_FOUND			 102
+#define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED	 103
+#define X509V3_R_EXTENSION_VALUE_ERROR			 116
+#define X509V3_R_ILLEGAL_EMPTY_EXTENSION		 151
+#define X509V3_R_ILLEGAL_HEX_DIGIT			 113
+#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG		 152
+#define X509V3_R_INVALID_MULTIPLE_RDNS			 161
+#define X509V3_R_INVALID_ASNUMBER			 162
+#define X509V3_R_INVALID_ASRANGE			 163
+#define X509V3_R_INVALID_BOOLEAN_STRING			 104
+#define X509V3_R_INVALID_EXTENSION_STRING		 105
+#define X509V3_R_INVALID_INHERITANCE			 165
+#define X509V3_R_INVALID_IPADDRESS			 166
+#define X509V3_R_INVALID_NAME				 106
+#define X509V3_R_INVALID_NULL_ARGUMENT			 107
+#define X509V3_R_INVALID_NULL_NAME			 108
+#define X509V3_R_INVALID_NULL_VALUE			 109
+#define X509V3_R_INVALID_NUMBER				 140
+#define X509V3_R_INVALID_NUMBERS			 141
+#define X509V3_R_INVALID_OBJECT_IDENTIFIER		 110
+#define X509V3_R_INVALID_OPTION				 138
+#define X509V3_R_INVALID_POLICY_IDENTIFIER		 134
+#define X509V3_R_INVALID_PROXY_POLICY_SETTING		 153
+#define X509V3_R_INVALID_PURPOSE			 146
+#define X509V3_R_INVALID_SAFI				 164
+#define X509V3_R_INVALID_SECTION			 135
+#define X509V3_R_INVALID_SYNTAX				 143
+#define X509V3_R_ISSUER_DECODE_ERROR			 126
+#define X509V3_R_MISSING_VALUE				 124
+#define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS		 142
+#define X509V3_R_NO_CONFIG_DATABASE			 136
+#define X509V3_R_NO_ISSUER_CERTIFICATE			 121
+#define X509V3_R_NO_ISSUER_DETAILS			 127
+#define X509V3_R_NO_POLICY_IDENTIFIER			 139
+#define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED	 154
+#define X509V3_R_NO_PUBLIC_KEY				 114
+#define X509V3_R_NO_SUBJECT_DETAILS			 125
+#define X509V3_R_ODD_NUMBER_OF_DIGITS			 112
+#define X509V3_R_OPERATION_NOT_DEFINED			 148
+#define X509V3_R_OTHERNAME_ERROR			 147
+#define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED	 155
+#define X509V3_R_POLICY_PATH_LENGTH			 156
+#define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED	 157
+#define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED	 158
+#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159
+#define X509V3_R_SECTION_NOT_FOUND			 150
+#define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS		 122
+#define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID		 123
+#define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT		 111
+#define X509V3_R_UNKNOWN_EXTENSION			 129
+#define X509V3_R_UNKNOWN_EXTENSION_NAME			 130
+#define X509V3_R_UNKNOWN_OPTION				 120
+#define X509V3_R_UNSUPPORTED_OPTION			 117
+#define X509V3_R_UNSUPPORTED_TYPE			 167
+#define X509V3_R_USER_TOO_LONG				 132
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/x86_64cpuid.pl b/openssl/crypto/x86_64cpuid.pl
new file mode 100644
index 0000000..c96821a
--- /dev/null
+++ b/openssl/crypto/x86_64cpuid.pl
@@ -0,0 +1,232 @@
+#!/usr/bin/env perl
+
+$flavour = shift;
+$output  = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+open STDOUT,"| $^X ${dir}perlasm/x86_64-xlate.pl $flavour $output";
+
+if ($win64)	{ $arg1="%rcx"; $arg2="%rdx"; }
+else		{ $arg1="%rdi"; $arg2="%rsi"; }
+print<<___;
+.extern		OPENSSL_cpuid_setup
+.section	.init
+	call	OPENSSL_cpuid_setup
+
+.text
+
+.globl	OPENSSL_atomic_add
+.type	OPENSSL_atomic_add,\@abi-omnipotent
+.align	16
+OPENSSL_atomic_add:
+	movl	($arg1),%eax
+.Lspin:	leaq	($arg2,%rax),%r8
+	.byte	0xf0		# lock
+	cmpxchgl	%r8d,($arg1)
+	jne	.Lspin
+	movl	%r8d,%eax
+	.byte	0x48,0x98	# cltq/cdqe
+	ret
+.size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
+
+.globl	OPENSSL_rdtsc
+.type	OPENSSL_rdtsc,\@abi-omnipotent
+.align	16
+OPENSSL_rdtsc:
+	rdtsc
+	shl	\$32,%rdx
+	or	%rdx,%rax
+	ret
+.size	OPENSSL_rdtsc,.-OPENSSL_rdtsc
+
+.globl	OPENSSL_ia32_cpuid
+.type	OPENSSL_ia32_cpuid,\@abi-omnipotent
+.align	16
+OPENSSL_ia32_cpuid:
+	mov	%rbx,%r8
+
+	xor	%eax,%eax
+	cpuid
+	mov	%eax,%r11d		# max value for standard query level
+
+	xor	%eax,%eax
+	cmp	\$0x756e6547,%ebx	# "Genu"
+	setne	%al
+	mov	%eax,%r9d
+	cmp	\$0x49656e69,%edx	# "ineI"
+	setne	%al
+	or	%eax,%r9d
+	cmp	\$0x6c65746e,%ecx	# "ntel"
+	setne	%al
+	or	%eax,%r9d		# 0 indicates Intel CPU
+	jz	.Lintel
+
+	cmp	\$0x68747541,%ebx	# "Auth"
+	setne	%al
+	mov	%eax,%r10d
+	cmp	\$0x69746E65,%edx	# "enti"
+	setne	%al
+	or	%eax,%r10d
+	cmp	\$0x444D4163,%ecx	# "cAMD"
+	setne	%al
+	or	%eax,%r10d		# 0 indicates AMD CPU
+	jnz	.Lintel
+
+	# AMD specific
+	mov	\$0x80000000,%eax
+	cpuid
+	cmp	\$0x80000008,%eax
+	jb	.Lintel
+
+	mov	\$0x80000008,%eax
+	cpuid
+	movzb	%cl,%r10		# number of cores - 1
+	inc	%r10			# number of cores
+
+	mov	\$1,%eax
+	cpuid
+	bt	\$28,%edx		# test hyper-threading bit
+	jnc	.Ldone
+	shr	\$16,%ebx		# number of logical processors
+	cmp	%r10b,%bl
+	ja	.Ldone
+	and	\$0xefffffff,%edx	# ~(1<<28)
+	jmp	.Ldone
+
+.Lintel:
+	cmp	\$4,%r11d
+	mov	\$-1,%r10d
+	jb	.Lnocacheinfo
+
+	mov	\$4,%eax
+	mov	\$0,%ecx		# query L1D
+	cpuid
+	mov	%eax,%r10d
+	shr	\$14,%r10d
+	and	\$0xfff,%r10d		# number of cores -1 per L1D
+
+.Lnocacheinfo:
+	mov	\$1,%eax
+	cpuid
+	cmp	\$0,%r9d
+	jne	.Lnotintel
+	or	\$0x00100000,%edx	# use reserved 20th bit to engage RC4_CHAR
+	and	\$15,%ah
+	cmp	\$15,%ah		# examine Family ID
+	je	.Lnotintel
+	or	\$0x40000000,%edx	# use reserved bit to skip unrolled loop
+.Lnotintel:
+	bt	\$28,%edx		# test hyper-threading bit
+	jnc	.Ldone
+	and	\$0xefffffff,%edx	# ~(1<<28)
+	cmp	\$0,%r10d
+	je	.Ldone
+
+	or	\$0x10000000,%edx	# 1<<28
+	shr	\$16,%ebx
+	cmp	\$1,%bl			# see if cache is shared
+	ja	.Ldone
+	and	\$0xefffffff,%edx	# ~(1<<28)
+.Ldone:
+	shl	\$32,%rcx
+	mov	%edx,%eax
+	mov	%r8,%rbx
+	or	%rcx,%rax
+	ret
+.size	OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
+
+.globl  OPENSSL_cleanse
+.type   OPENSSL_cleanse,\@abi-omnipotent
+.align  16
+OPENSSL_cleanse:
+	xor	%rax,%rax
+	cmp	\$15,$arg2
+	jae	.Lot
+	cmp	\$0,$arg2
+	je	.Lret
+.Little:
+	mov	%al,($arg1)
+	sub	\$1,$arg2
+	lea	1($arg1),$arg1
+	jnz	.Little
+.Lret:
+	ret
+.align	16
+.Lot:
+	test	\$7,$arg1
+	jz	.Laligned
+	mov	%al,($arg1)
+	lea	-1($arg2),$arg2
+	lea	1($arg1),$arg1
+	jmp	.Lot
+.Laligned:
+	mov	%rax,($arg1)
+	lea	-8($arg2),$arg2
+	test	\$-8,$arg2
+	lea	8($arg1),$arg1
+	jnz	.Laligned
+	cmp	\$0,$arg2
+	jne	.Little
+	ret
+.size	OPENSSL_cleanse,.-OPENSSL_cleanse
+___
+
+print<<___ if (!$win64);
+.globl	OPENSSL_wipe_cpu
+.type	OPENSSL_wipe_cpu,\@abi-omnipotent
+.align	16
+OPENSSL_wipe_cpu:
+	pxor	%xmm0,%xmm0
+	pxor	%xmm1,%xmm1
+	pxor	%xmm2,%xmm2
+	pxor	%xmm3,%xmm3
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	pxor	%xmm6,%xmm6
+	pxor	%xmm7,%xmm7
+	pxor	%xmm8,%xmm8
+	pxor	%xmm9,%xmm9
+	pxor	%xmm10,%xmm10
+	pxor	%xmm11,%xmm11
+	pxor	%xmm12,%xmm12
+	pxor	%xmm13,%xmm13
+	pxor	%xmm14,%xmm14
+	pxor	%xmm15,%xmm15
+	xorq	%rcx,%rcx
+	xorq	%rdx,%rdx
+	xorq	%rsi,%rsi
+	xorq	%rdi,%rdi
+	xorq	%r8,%r8
+	xorq	%r9,%r9
+	xorq	%r10,%r10
+	xorq	%r11,%r11
+	leaq	8(%rsp),%rax
+	ret
+.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
+___
+print<<___ if ($win64);
+.globl	OPENSSL_wipe_cpu
+.type	OPENSSL_wipe_cpu,\@abi-omnipotent
+.align	16
+OPENSSL_wipe_cpu:
+	pxor	%xmm0,%xmm0
+	pxor	%xmm1,%xmm1
+	pxor	%xmm2,%xmm2
+	pxor	%xmm3,%xmm3
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	xorq	%rcx,%rcx
+	xorq	%rdx,%rdx
+	xorq	%r8,%r8
+	xorq	%r9,%r9
+	xorq	%r10,%r10
+	xorq	%r11,%r11
+	leaq	8(%rsp),%rax
+	ret
+.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
+___
+
+close STDOUT;	# flush
diff --git a/openssl/crypto/x86cpuid.pl b/openssl/crypto/x86cpuid.pl
new file mode 100644
index 0000000..a7464af
--- /dev/null
+++ b/openssl/crypto/x86cpuid.pl
@@ -0,0 +1,312 @@
+#!/usr/bin/env perl
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC, "${dir}perlasm", "perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"x86cpuid");
+
+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
+
+&function_begin("OPENSSL_ia32_cpuid");
+	&xor	("edx","edx");
+	&pushf	();
+	&pop	("eax");
+	&mov	("ecx","eax");
+	&xor	("eax",1<<21);
+	&push	("eax");
+	&popf	();
+	&pushf	();
+	&pop	("eax");
+	&xor	("ecx","eax");
+	&bt	("ecx",21);
+	&jnc	(&label("done"));
+	&xor	("eax","eax");
+	&cpuid	();
+	&mov	("edi","eax");		# max value for standard query level
+
+	&xor	("eax","eax");
+	&cmp	("ebx",0x756e6547);	# "Genu"
+	&setne	(&LB("eax"));
+	&mov	("ebp","eax");
+	&cmp	("edx",0x49656e69);	# "ineI"
+	&setne	(&LB("eax"));
+	&or	("ebp","eax");
+	&cmp	("ecx",0x6c65746e);	# "ntel"
+	&setne	(&LB("eax"));
+	&or	("ebp","eax");		# 0 indicates Intel CPU
+	&jz	(&label("intel"));
+
+	&cmp	("ebx",0x68747541);	# "Auth"
+	&setne	(&LB("eax"));
+	&mov	("esi","eax");
+	&cmp	("edx",0x69746E65);	# "enti"
+	&setne	(&LB("eax"));
+	&or	("esi","eax");
+	&cmp	("ecx",0x444D4163);	# "cAMD"
+	&setne	(&LB("eax"));
+	&or	("esi","eax");		# 0 indicates AMD CPU
+	&jnz	(&label("intel"));
+
+	# AMD specific
+	&mov	("eax",0x80000000);
+	&cpuid	();
+	&cmp	("eax",0x80000008);
+	&jb	(&label("intel"));
+
+	&mov	("eax",0x80000008);
+	&cpuid	();
+	&movz	("esi",&LB("ecx"));	# number of cores - 1
+	&inc	("esi");		# number of cores
+
+	&mov	("eax",1);
+	&cpuid	();
+	&bt	("edx",28);
+	&jnc	(&label("done"));
+	&shr	("ebx",16);
+	&and	("ebx",0xff);
+	&cmp	("ebx","esi");
+	&ja	(&label("done"));
+	&and	("edx",0xefffffff);	# clear hyper-threading bit
+	&jmp	(&label("done"));
+	
+&set_label("intel");
+	&cmp	("edi",4);
+	&mov	("edi",-1);
+	&jb	(&label("nocacheinfo"));
+
+	&mov	("eax",4);
+	&mov	("ecx",0);		# query L1D
+	&cpuid	();
+	&mov	("edi","eax");
+	&shr	("edi",14);
+	&and	("edi",0xfff);		# number of cores -1 per L1D
+
+&set_label("nocacheinfo");
+	&mov	("eax",1);
+	&cpuid	();
+	&cmp	("ebp",0);
+	&jne	(&label("notP4"));
+	&and	(&HB("eax"),15);	# familiy ID
+	&cmp	(&HB("eax"),15);	# P4?
+	&jne	(&label("notP4"));
+	&or	("edx",1<<20);		# use reserved bit to engage RC4_CHAR
+&set_label("notP4");
+	&bt	("edx",28);		# test hyper-threading bit
+	&jnc	(&label("done"));
+	&and	("edx",0xefffffff);
+	&cmp	("edi",0);
+	&je	(&label("done"));
+
+	&or	("edx",0x10000000);
+	&shr	("ebx",16);
+	&cmp	(&LB("ebx"),1);
+	&ja	(&label("done"));
+	&and	("edx",0xefffffff);	# clear hyper-threading bit if not
+&set_label("done");
+	&mov	("eax","edx");
+	&mov	("edx","ecx");
+&function_end("OPENSSL_ia32_cpuid");
+
+&external_label("OPENSSL_ia32cap_P");
+
+&function_begin_B("OPENSSL_rdtsc","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
+	&xor	("eax","eax");
+	&xor	("edx","edx");
+	&picmeup("ecx","OPENSSL_ia32cap_P");
+	&bt	(&DWP(0,"ecx"),4);
+	&jnc	(&label("notsc"));
+	&rdtsc	();
+&set_label("notsc");
+	&ret	();
+&function_end_B("OPENSSL_rdtsc");
+
+# This works in Ring 0 only [read DJGPP+MS-DOS+privileged DPMI host],
+# but it's safe to call it on any [supported] 32-bit platform...
+# Just check for [non-]zero return value...
+&function_begin_B("OPENSSL_instrument_halt","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
+	&picmeup("ecx","OPENSSL_ia32cap_P");
+	&bt	(&DWP(0,"ecx"),4);
+	&jnc	(&label("nohalt"));	# no TSC
+
+	&data_word(0x9058900e);		# push %cs; pop %eax
+	&and	("eax",3);
+	&jnz	(&label("nohalt"));	# not enough privileges
+
+	&pushf	();
+	&pop	("eax")
+	&bt	("eax",9);
+	&jnc	(&label("nohalt"));	# interrupts are disabled
+
+	&rdtsc	();
+	&push	("edx");
+	&push	("eax");
+	&halt	();
+	&rdtsc	();
+
+	&sub	("eax",&DWP(0,"esp"));
+	&sbb	("edx",&DWP(4,"esp"));
+	&add	("esp",8);
+	&ret	();
+
+&set_label("nohalt");
+	&xor	("eax","eax");
+	&xor	("edx","edx");
+	&ret	();
+&function_end_B("OPENSSL_instrument_halt");
+
+# Essentially there is only one use for this function. Under DJGPP:
+#
+#	#include <go32.h>
+#	...
+#	i=OPENSSL_far_spin(_dos_ds,0x46c);
+#	...
+# to obtain the number of spins till closest timer interrupt.
+
+&function_begin_B("OPENSSL_far_spin");
+	&pushf	();
+	&pop	("eax")
+	&bt	("eax",9);
+	&jnc	(&label("nospin"));	# interrupts are disabled
+
+	&mov	("eax",&DWP(4,"esp"));
+	&mov	("ecx",&DWP(8,"esp"));
+	&data_word (0x90d88e1e);	# push %ds, mov %eax,%ds
+	&xor	("eax","eax");
+	&mov	("edx",&DWP(0,"ecx"));
+	&jmp	(&label("spin"));
+
+	&align	(16);
+&set_label("spin");
+	&inc	("eax");
+	&cmp	("edx",&DWP(0,"ecx"));
+	&je	(&label("spin"));
+
+	&data_word (0x1f909090);	# pop	%ds
+	&ret	();
+
+&set_label("nospin");
+	&xor	("eax","eax");
+	&xor	("edx","edx");
+	&ret	();
+&function_end_B("OPENSSL_far_spin");
+
+&function_begin_B("OPENSSL_wipe_cpu","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
+	&xor	("eax","eax");
+	&xor	("edx","edx");
+	&picmeup("ecx","OPENSSL_ia32cap_P");
+	&mov	("ecx",&DWP(0,"ecx"));
+	&bt	(&DWP(0,"ecx"),1);
+	&jnc	(&label("no_x87"));
+	if ($sse2) {
+		&bt	(&DWP(0,"ecx"),26);
+		&jnc	(&label("no_sse2"));
+		&pxor	("xmm0","xmm0");
+		&pxor	("xmm1","xmm1");
+		&pxor	("xmm2","xmm2");
+		&pxor	("xmm3","xmm3");
+		&pxor	("xmm4","xmm4");
+		&pxor	("xmm5","xmm5");
+		&pxor	("xmm6","xmm6");
+		&pxor	("xmm7","xmm7");
+	&set_label("no_sse2");
+	}
+	# just a bunch of fldz to zap the fp/mm bank followed by finit...
+	&data_word(0xeed9eed9,0xeed9eed9,0xeed9eed9,0xeed9eed9,0x90e3db9b);
+&set_label("no_x87");
+	&lea	("eax",&DWP(4,"esp"));
+	&ret	();
+&function_end_B("OPENSSL_wipe_cpu");
+
+&function_begin_B("OPENSSL_atomic_add");
+	&mov	("edx",&DWP(4,"esp"));	# fetch the pointer, 1st arg
+	&mov	("ecx",&DWP(8,"esp"));	# fetch the increment, 2nd arg
+	&push	("ebx");
+	&nop	();
+	&mov	("eax",&DWP(0,"edx"));
+&set_label("spin");
+	&lea	("ebx",&DWP(0,"eax","ecx"));
+	&nop	();
+	&data_word(0x1ab10ff0);	# lock;	cmpxchg	%ebx,(%edx)	# %eax is envolved and is always reloaded
+	&jne	(&label("spin"));
+	&mov	("eax","ebx");	# OpenSSL expects the new value
+	&pop	("ebx");
+	&ret	();
+&function_end_B("OPENSSL_atomic_add");
+
+# This function can become handy under Win32 in situations when
+# we don't know which calling convention, __stdcall or __cdecl(*),
+# indirect callee is using. In C it can be deployed as
+#
+#ifdef OPENSSL_CPUID_OBJ
+#	type OPENSSL_indirect_call(void *f,...);
+#	...
+#	OPENSSL_indirect_call(func,[up to $max arguments]);
+#endif
+#
+# (*)	it's designed to work even for __fastcall if number of
+#	arguments is 1 or 2!
+&function_begin_B("OPENSSL_indirect_call");
+	{
+	my $i,$max=7;		# $max has to be chosen as 4*n-1
+				# in order to preserve eventual
+				# stack alignment
+	&push	("ebp");
+	&mov	("ebp","esp");
+	&sub	("esp",$max*4);
+	&mov	("ecx",&DWP(12,"ebp"));
+	&mov	(&DWP(0,"esp"),"ecx");
+	&mov	("edx",&DWP(16,"ebp"));
+	&mov	(&DWP(4,"esp"),"edx");
+	for($i=2;$i<$max;$i++)
+		{
+		# Some copies will be redundant/bogus...
+		&mov	("eax",&DWP(12+$i*4,"ebp"));
+		&mov	(&DWP(0+$i*4,"esp"),"eax");
+		}
+	&call_ptr	(&DWP(8,"ebp"));# make the call...
+	&mov	("esp","ebp");	# ... and just restore the stack pointer
+				# without paying attention to what we called,
+				# (__cdecl *func) or (__stdcall *one).
+	&pop	("ebp");
+	&ret	();
+	}
+&function_end_B("OPENSSL_indirect_call");
+
+&function_begin_B("OPENSSL_cleanse");
+	&mov	("edx",&wparam(0));
+	&mov	("ecx",&wparam(1));
+	&xor	("eax","eax");
+	&cmp	("ecx",7);
+	&jae	(&label("lot"));
+	&cmp	("ecx",0);
+	&je	(&label("ret"));
+&set_label("little");
+	&mov	(&BP(0,"edx"),"al");
+	&sub	("ecx",1);
+	&lea	("edx",&DWP(1,"edx"));
+	&jnz	(&label("little"));
+&set_label("ret");
+	&ret	();
+
+&set_label("lot",16);
+	&test	("edx",3);
+	&jz	(&label("aligned"));
+	&mov	(&BP(0,"edx"),"al");
+	&lea	("ecx",&DWP(-1,"ecx"));
+	&lea	("edx",&DWP(1,"edx"));
+	&jmp	(&label("lot"));
+&set_label("aligned");
+	&mov	(&DWP(0,"edx"),"eax");
+	&lea	("ecx",&DWP(-4,"ecx"));
+	&test	("ecx",-4);
+	&lea	("edx",&DWP(4,"edx"));
+	&jnz	(&label("aligned"));
+	&cmp	("ecx",0);
+	&jne	(&label("little"));
+	&ret	();
+&function_end_B("OPENSSL_cleanse");
+
+&initseg("OPENSSL_cpuid_setup");
+
+&asm_finish();
diff --git a/openssl/demos/README b/openssl/demos/README
new file mode 100644
index 0000000..d2155ef
--- /dev/null
+++ b/openssl/demos/README
@@ -0,0 +1,9 @@
+NOTE: Don't expect any of these programs to work with current
+OpenSSL releases, or even with later SSLeay releases.
+
+Original README:
+=============================================================================
+
+Some demo programs sent to me by various people
+
+eric
diff --git a/openssl/demos/asn1/README.ASN1 b/openssl/demos/asn1/README.ASN1
new file mode 100644
index 0000000..ac497be
--- /dev/null
+++ b/openssl/demos/asn1/README.ASN1
@@ -0,0 +1,7 @@
+This is a demo of the new ASN1 code. Its an OCSP ASN1 module. Doesn't
+do much yet other than demonstrate what the new ASN1 modules might look
+like.
+
+It wont even compile yet: the new code isn't in place.
+
+
diff --git a/openssl/demos/asn1/ocsp.c b/openssl/demos/asn1/ocsp.c
new file mode 100644
index 0000000..e89f1f7
--- /dev/null
+++ b/openssl/demos/asn1/ocsp.c
@@ -0,0 +1,366 @@
+/* ocsp.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+
+
+
+/* Example of new ASN1 code, OCSP request
+
+	OCSPRequest     ::=     SEQUENCE {
+	    tbsRequest                  TBSRequest,
+	    optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
+
+	TBSRequest      ::=     SEQUENCE {
+	    version             [0] EXPLICIT Version DEFAULT v1,
+	    requestorName       [1] EXPLICIT GeneralName OPTIONAL,
+	    requestList             SEQUENCE OF Request,
+	    requestExtensions   [2] EXPLICIT Extensions OPTIONAL }
+
+	Signature       ::=     SEQUENCE {
+	    signatureAlgorithm   AlgorithmIdentifier,
+	    signature            BIT STRING,
+	    certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+
+	Version  ::=  INTEGER  {  v1(0) }
+
+	Request ::=     SEQUENCE {
+	    reqCert                    CertID,
+	    singleRequestExtensions    [0] EXPLICIT Extensions OPTIONAL }
+
+	CertID ::= SEQUENCE {
+	    hashAlgorithm            AlgorithmIdentifier,
+	    issuerNameHash     OCTET STRING, -- Hash of Issuer's DN
+	    issuerKeyHash      OCTET STRING, -- Hash of Issuers public key
+	    serialNumber       CertificateSerialNumber }
+
+	OCSPResponse ::= SEQUENCE {
+	   responseStatus         OCSPResponseStatus,
+	   responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
+
+	OCSPResponseStatus ::= ENUMERATED {
+	    successful            (0),      --Response has valid confirmations
+	    malformedRequest      (1),      --Illegal confirmation request
+	    internalError         (2),      --Internal error in issuer
+	    tryLater              (3),      --Try again later
+					    --(4) is not used
+	    sigRequired           (5),      --Must sign the request
+	    unauthorized          (6)       --Request unauthorized
+	}
+
+	ResponseBytes ::=       SEQUENCE {
+	    responseType   OBJECT IDENTIFIER,
+	    response       OCTET STRING }
+
+	BasicOCSPResponse       ::= SEQUENCE {
+	   tbsResponseData      ResponseData,
+	   signatureAlgorithm   AlgorithmIdentifier,
+	   signature            BIT STRING,
+	   certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+
+	ResponseData ::= SEQUENCE {
+	   version              [0] EXPLICIT Version DEFAULT v1,
+	   responderID              ResponderID,
+	   producedAt               GeneralizedTime,
+	   responses                SEQUENCE OF SingleResponse,
+	   responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
+
+	ResponderID ::= CHOICE {
+	   byName   [1] Name,    --EXPLICIT
+	   byKey    [2] KeyHash }
+
+	KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key
+				 --(excluding the tag and length fields)
+
+	SingleResponse ::= SEQUENCE {
+	   certID                       CertID,
+	   certStatus                   CertStatus,
+	   thisUpdate                   GeneralizedTime,
+	   nextUpdate           [0]     EXPLICIT GeneralizedTime OPTIONAL,
+	   singleExtensions     [1]     EXPLICIT Extensions OPTIONAL }
+
+	CertStatus ::= CHOICE {
+	    good                [0]     IMPLICIT NULL,
+	    revoked             [1]     IMPLICIT RevokedInfo,
+	    unknown             [2]     IMPLICIT UnknownInfo }
+
+	RevokedInfo ::= SEQUENCE {
+	    revocationTime              GeneralizedTime,
+	    revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
+
+	UnknownInfo ::= NULL -- this can be replaced with an enumeration
+
+	ArchiveCutoff ::= GeneralizedTime
+
+	AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER
+
+	ServiceLocator ::= SEQUENCE {
+	    issuer    Name,
+	    locator   AuthorityInfoAccessSyntax }
+
+	-- Object Identifiers
+
+	id-kp-OCSPSigning            OBJECT IDENTIFIER ::= { id-kp 9 }
+	id-pkix-ocsp                 OBJECT IDENTIFIER ::= { id-ad-ocsp }
+	id-pkix-ocsp-basic           OBJECT IDENTIFIER ::= { id-pkix-ocsp 1 }
+	id-pkix-ocsp-nonce           OBJECT IDENTIFIER ::= { id-pkix-ocsp 2 }
+	id-pkix-ocsp-crl             OBJECT IDENTIFIER ::= { id-pkix-ocsp 3 }
+	id-pkix-ocsp-response        OBJECT IDENTIFIER ::= { id-pkix-ocsp 4 }
+	id-pkix-ocsp-nocheck         OBJECT IDENTIFIER ::= { id-pkix-ocsp 5 }
+	id-pkix-ocsp-archive-cutoff  OBJECT IDENTIFIER ::= { id-pkix-ocsp 6 }
+	id-pkix-ocsp-service-locator OBJECT IDENTIFIER ::= { id-pkix-ocsp 7 }
+
+*/
+
+/* Request Structures */
+
+DECLARE_STACK_OF(Request)
+
+typedef struct {
+	ASN1_INTEGER *version;
+	GENERAL_NAME *requestorName;
+	STACK_OF(Request) *requestList;
+	STACK_OF(X509_EXTENSION) *requestExtensions;
+} TBSRequest;
+
+typedef struct {
+	X509_ALGOR *signatureAlgorithm;
+	ASN1_BIT_STRING *signature;
+	STACK_OF(X509) *certs;
+} Signature;
+
+typedef struct {
+	TBSRequest *tbsRequest;
+	Signature *optionalSignature;
+} OCSPRequest;
+
+typedef struct {
+	X509_ALGOR *hashAlgorithm;
+	ASN1_OCTET_STRING *issuerNameHash;
+	ASN1_OCTET_STRING *issuerKeyHash;
+	ASN1_INTEGER *certificateSerialNumber;
+} CertID;
+
+typedef struct {
+	CertID *reqCert;
+	STACK_OF(X509_EXTENSION) *singleRequestExtensions;
+} Request;
+
+/* Response structures */
+
+typedef struct {
+	ASN1_OBJECT *responseType;
+	ASN1_OCTET_STRING *response;
+} ResponseBytes;
+
+typedef struct {
+	ASN1_ENUMERATED *responseStatus;
+	ResponseBytes *responseBytes;
+} OCSPResponse;
+
+typedef struct {
+	int type;
+	union {
+	   X509_NAME *byName;
+	   ASN1_OCTET_STRING *byKey;
+	}d;
+} ResponderID;
+
+typedef struct {
+	   ASN1_INTEGER *version;
+	   ResponderID *responderID;
+	   ASN1_GENERALIZEDTIME *producedAt;
+	   STACK_OF(SingleResponse) *responses;
+	   STACK_OF(X509_EXTENSION) *responseExtensions;
+} ResponseData;
+
+typedef struct {
+	   ResponseData *tbsResponseData;
+	   X509_ALGOR *signatureAlgorithm;
+	   ASN1_BIT_STRING *signature;
+	   STACK_OF(X509) *certs;
+} BasicOCSPResponse;
+
+typedef struct {
+	ASN1_GENERALIZEDTIME *revocationTime;
+	ASN1_ENUMERATED * revocationReason;
+} RevokedInfo;
+
+typedef struct {
+	int type;
+	union {
+	    ASN1_NULL *good;
+	    RevokedInfo *revoked;
+	    ASN1_NULL *unknown;
+	} d;
+} CertStatus;
+
+typedef struct {
+	   CertID *certID;
+	   CertStatus *certStatus;
+	   ASN1_GENERALIZEDTIME *thisUpdate;
+	   ASN1_GENERALIZEDTIME *nextUpdate;
+	   STACK_OF(X509_EXTENSION) *singleExtensions;
+} SingleResponse;
+
+
+typedef struct {
+    X509_NAME *issuer;
+    STACK_OF(ACCESS_DESCRIPTION) *locator;
+} ServiceLocator;
+
+
+/* Now the ASN1 templates */
+
+IMPLEMENT_COMPAT_ASN1(X509);
+IMPLEMENT_COMPAT_ASN1(X509_ALGOR);
+//IMPLEMENT_COMPAT_ASN1(X509_EXTENSION);
+IMPLEMENT_COMPAT_ASN1(GENERAL_NAME);
+IMPLEMENT_COMPAT_ASN1(X509_NAME);
+
+ASN1_SEQUENCE(X509_EXTENSION) = {
+	ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT),
+	ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN),
+	ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(X509_EXTENSION);
+	
+
+ASN1_SEQUENCE(Signature) = {
+	ASN1_SIMPLE(Signature, signatureAlgorithm, X509_ALGOR),
+	ASN1_SIMPLE(Signature, signature, ASN1_BIT_STRING),
+	ASN1_SEQUENCE_OF(Signature, certs, X509)
+} ASN1_SEQUENCE_END(Signature);
+
+ASN1_SEQUENCE(CertID) = {
+	ASN1_SIMPLE(CertID, hashAlgorithm, X509_ALGOR),
+	ASN1_SIMPLE(CertID, issuerNameHash, ASN1_OCTET_STRING),
+	ASN1_SIMPLE(CertID, issuerKeyHash, ASN1_OCTET_STRING),
+	ASN1_SIMPLE(CertID, certificateSerialNumber, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(CertID);
+
+ASN1_SEQUENCE(Request) = {
+	ASN1_SIMPLE(Request, reqCert, CertID),
+	ASN1_EXP_SEQUENCE_OF_OPT(Request, singleRequestExtensions, X509_EXTENSION, 0)
+} ASN1_SEQUENCE_END(Request);
+
+ASN1_SEQUENCE(TBSRequest) = {
+	ASN1_EXP_OPT(TBSRequest, version, ASN1_INTEGER, 0),
+	ASN1_EXP_OPT(TBSRequest, requestorName, GENERAL_NAME, 1),
+	ASN1_SEQUENCE_OF(TBSRequest, requestList, Request),
+	ASN1_EXP_SEQUENCE_OF_OPT(TBSRequest, requestExtensions, X509_EXTENSION, 2)
+} ASN1_SEQUENCE_END(TBSRequest);
+
+ASN1_SEQUENCE(OCSPRequest) = {
+	ASN1_SIMPLE(OCSPRequest, tbsRequest, TBSRequest),
+	ASN1_EXP_OPT(OCSPRequest, optionalSignature, Signature, 0)
+} ASN1_SEQUENCE_END(OCSPRequest);
+
+
+/* Response templates */
+
+ASN1_SEQUENCE(ResponseBytes) = {
+	    ASN1_SIMPLE(ResponseBytes, responseType, ASN1_OBJECT),
+	    ASN1_SIMPLE(ResponseBytes, response, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(ResponseBytes);
+
+ASN1_SEQUENCE(OCSPResponse) = {
+	ASN1_SIMPLE(OCSPResponse, responseStatus, ASN1_ENUMERATED),
+	ASN1_EXP_OPT(OCSPResponse, responseBytes, ResponseBytes, 0)
+} ASN1_SEQUENCE_END(OCSPResponse);
+
+ASN1_CHOICE(ResponderID) = {
+	   ASN1_EXP(ResponderID, d.byName, X509_NAME, 1),
+	   ASN1_IMP(ResponderID, d.byKey, ASN1_OCTET_STRING, 2)
+} ASN1_CHOICE_END(ResponderID);
+
+ASN1_SEQUENCE(RevokedInfo) = {
+	ASN1_SIMPLE(RevokedInfo, revocationTime, ASN1_GENERALIZEDTIME),
+  	ASN1_EXP_OPT(RevokedInfo, revocationReason, ASN1_ENUMERATED, 0)
+} ASN1_SEQUENCE_END(RevokedInfo);
+
+ASN1_CHOICE(CertStatus) = {
+	ASN1_IMP(CertStatus, d.good, ASN1_NULL, 0),
+	ASN1_IMP(CertStatus, d.revoked, RevokedInfo, 1),
+	ASN1_IMP(CertStatus, d.unknown, ASN1_NULL, 2)
+} ASN1_CHOICE_END(CertStatus);
+
+ASN1_SEQUENCE(SingleResponse) = {
+	   ASN1_SIMPLE(SingleResponse, certID, CertID),
+	   ASN1_SIMPLE(SingleResponse, certStatus, CertStatus),
+	   ASN1_SIMPLE(SingleResponse, thisUpdate, ASN1_GENERALIZEDTIME),
+	   ASN1_EXP_OPT(SingleResponse, nextUpdate, ASN1_GENERALIZEDTIME, 0),
+	   ASN1_EXP_SEQUENCE_OF_OPT(SingleResponse, singleExtensions, X509_EXTENSION, 1)
+} ASN1_SEQUENCE_END(SingleResponse);
+
+ASN1_SEQUENCE(ResponseData) = {
+	   ASN1_EXP_OPT(ResponseData, version, ASN1_INTEGER, 0),
+	   ASN1_SIMPLE(ResponseData, responderID, ResponderID),
+	   ASN1_SIMPLE(ResponseData, producedAt, ASN1_GENERALIZEDTIME),
+	   ASN1_SEQUENCE_OF(ResponseData, responses, SingleResponse),
+	   ASN1_EXP_SEQUENCE_OF_OPT(ResponseData, responseExtensions, X509_EXTENSION, 1)
+} ASN1_SEQUENCE_END(ResponseData);
+
+ASN1_SEQUENCE(BasicOCSPResponse) = {
+	   ASN1_SIMPLE(BasicOCSPResponse, tbsResponseData, ResponseData),
+	   ASN1_SIMPLE(BasicOCSPResponse, signatureAlgorithm, X509_ALGOR),
+	   ASN1_SIMPLE(BasicOCSPResponse, signature, ASN1_BIT_STRING),
+	   ASN1_EXP_SEQUENCE_OF_OPT(BasicOCSPResponse, certs, X509, 0)
+} ASN1_SEQUENCE_END(BasicOCSPResponse);
+
diff --git a/openssl/demos/b64.c b/openssl/demos/b64.c
new file mode 100644
index 0000000..efdd444
--- /dev/null
+++ b/openssl/demos/b64.c
@@ -0,0 +1,268 @@
+/* demos/b64.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "../apps/apps.h"
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+#undef SIZE
+#undef BSIZE
+#undef PROG
+
+#define SIZE	(512)
+#define BSIZE	(8*1024)
+#define	PROG	enc_main
+
+int main(argc,argv)
+int argc;
+char **argv;
+	{
+	char *strbuf=NULL;
+	unsigned char *buff=NULL,*bufsize=NULL;
+	int bsize=BSIZE,verbose=0;
+	int ret=1,inl;
+	char *str=NULL;
+	char *hkey=NULL,*hiv=NULL;
+	int enc=1,printkey=0,i,base64=0;
+	int debug=0;
+	EVP_CIPHER *cipher=NULL,*c;
+	char *inf=NULL,*outf=NULL;
+	BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL;
+#define PROG_NAME_SIZE  39
+
+
+	apps_startup();
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE);
+
+	base64=1;
+
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if	(strcmp(*argv,"-e") == 0)
+			enc=1;
+		if (strcmp(*argv,"-in") == 0)
+			{
+			if (--argc < 1) goto bad;
+			inf= *(++argv);
+			}
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) goto bad;
+			outf= *(++argv);
+			}
+		else if	(strcmp(*argv,"-d") == 0)
+			enc=0;
+		else if	(strcmp(*argv,"-v") == 0)
+			verbose=1;
+		else if	(strcmp(*argv,"-debug") == 0)
+			debug=1;
+		else if (strcmp(*argv,"-bufsize") == 0)
+			{
+			if (--argc < 1) goto bad;
+			bufsize=(unsigned char *)*(++argv);
+			}
+		else
+			{
+			BIO_printf(bio_err,"unknown option '%s'\n",*argv);
+bad:
+			BIO_printf(bio_err,"options are\n");
+			BIO_printf(bio_err,"%-14s input file\n","-in <file>");
+			BIO_printf(bio_err,"%-14s output file\n","-out <file>");
+			BIO_printf(bio_err,"%-14s encode\n","-e");
+			BIO_printf(bio_err,"%-14s decode\n","-d");
+			BIO_printf(bio_err,"%-14s buffer size\n","-bufsize <n>");
+
+			goto end;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (bufsize != NULL)
+		{
+		int i;
+		unsigned long n;
+
+		for (n=0; *bufsize; bufsize++)
+			{
+			i= *bufsize;
+			if ((i <= '9') && (i >= '0'))
+				n=n*10+i-'0';
+			else if (i == 'k')
+				{
+				n*=1024;
+				bufsize++;
+				break;
+				}
+			}
+		if (*bufsize != '\0')
+			{
+			BIO_printf(bio_err,"invalid 'bufsize' specified.\n");
+			goto end;
+			}
+
+		/* It must be large enough for a base64 encoded line */
+		if (n < 80) n=80;
+
+		bsize=(int)n;
+		if (verbose) BIO_printf(bio_err,"bufsize=%d\n",bsize);
+		}
+
+	strbuf=OPENSSL_malloc(SIZE);
+	buff=(unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize));
+	if ((buff == NULL) || (strbuf == NULL))
+		{
+		BIO_printf(bio_err,"OPENSSL_malloc failure\n");
+		goto end;
+		}
+
+	in=BIO_new(BIO_s_file());
+	out=BIO_new(BIO_s_file());
+	if ((in == NULL) || (out == NULL))
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+	if (debug)
+		{
+		BIO_set_callback(in,BIO_debug_callback);
+		BIO_set_callback(out,BIO_debug_callback);
+		BIO_set_callback_arg(in,bio_err);
+		BIO_set_callback_arg(out,bio_err);
+		}
+
+	if (inf == NULL)
+		BIO_set_fp(in,stdin,BIO_NOCLOSE);
+	else
+		{
+		if (BIO_read_filename(in,inf) <= 0)
+			{
+			perror(inf);
+			goto end;
+			}
+		}
+
+	if (outf == NULL)
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+	else
+		{
+		if (BIO_write_filename(out,outf) <= 0)
+			{
+			perror(outf);
+			goto end;
+			}
+		}
+
+	rbio=in;
+	wbio=out;
+
+	if (base64)
+		{
+		if ((b64=BIO_new(BIO_f_base64())) == NULL)
+			goto end;
+		if (debug)
+			{
+			BIO_set_callback(b64,BIO_debug_callback);
+			BIO_set_callback_arg(b64,bio_err);
+			}
+		if (enc)
+			wbio=BIO_push(b64,wbio);
+		else
+			rbio=BIO_push(b64,rbio);
+		}
+
+	for (;;)
+		{
+		inl=BIO_read(rbio,(char *)buff,bsize);
+		if (inl <= 0) break;
+		if (BIO_write(wbio,(char *)buff,inl) != inl)
+			{
+			BIO_printf(bio_err,"error writing output file\n");
+			goto end;
+			}
+		}
+	BIO_flush(wbio);
+
+	ret=0;
+	if (verbose)
+		{
+		BIO_printf(bio_err,"bytes read   :%8ld\n",BIO_number_read(in));
+		BIO_printf(bio_err,"bytes written:%8ld\n",BIO_number_written(out));
+		}
+end:
+	if (strbuf != NULL) OPENSSL_free(strbuf);
+	if (buff != NULL) OPENSSL_free(buff);
+	if (in != NULL) BIO_free(in);
+	if (out != NULL) BIO_free(out);
+	if (benc != NULL) BIO_free(benc);
+	if (b64 != NULL) BIO_free(b64);
+	EXIT(ret);
+	}
+
diff --git a/openssl/demos/b64.pl b/openssl/demos/b64.pl
new file mode 100644
index 0000000..8aa5fb4
--- /dev/null
+++ b/openssl/demos/b64.pl
@@ -0,0 +1,20 @@
+#!/usr/local/bin/perl
+
+#
+# Make PEM encoded data have lines of 64 bytes of data
+#
+
+while (<>)
+	{
+	if (/^-----BEGIN/ .. /^-----END/)
+		{
+		if (/^-----BEGIN/) { $first=$_; next; }
+		if (/^-----END/) { $last=$_; next; }
+		$out.=$_;
+		}
+	}
+$out =~ s/\s//g;
+$out =~ s/(.{64})/$1\n/g;
+print "$first$out\n$last\n";
+
+
diff --git a/openssl/demos/bio/Makefile b/openssl/demos/bio/Makefile
new file mode 100644
index 0000000..4351540
--- /dev/null
+++ b/openssl/demos/bio/Makefile
@@ -0,0 +1,16 @@
+CC=cc
+CFLAGS= -g -I../../include
+LIBS= -L../.. ../../libssl.a ../../libcrypto.a
+EXAMPLES=saccept sconnect
+
+all: $(EXAMPLES) 
+
+saccept: saccept.o
+	$(CC) -o saccept saccept.o $(LIBS)
+
+sconnect: sconnect.o
+	$(CC) -o sconnect sconnect.o $(LIBS)
+
+clean:	
+	rm -f $(EXAMPLES) *.o
+
diff --git a/openssl/demos/bio/README b/openssl/demos/bio/README
new file mode 100644
index 0000000..0b24e5b
--- /dev/null
+++ b/openssl/demos/bio/README
@@ -0,0 +1,3 @@
+This directory contains some simple examples of the use of BIO's
+to simplify socket programming.
+
diff --git a/openssl/demos/bio/saccept.c b/openssl/demos/bio/saccept.c
new file mode 100644
index 0000000..40cd4da
--- /dev/null
+++ b/openssl/demos/bio/saccept.c
@@ -0,0 +1,112 @@
+/* NOCW */
+/* demos/bio/saccept.c */
+
+/* A minimal program to server an SSL connection.
+ * It uses blocking.
+ * saccept host:port
+ * host is the interface IP to use.  If any interface, use *:port
+ * The default it *:4433
+ *
+ * cc -I../../include saccept.c -L../.. -lssl -lcrypto
+ */
+
+#include <stdio.h>
+#include <signal.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+#define CERT_FILE	"server.pem"
+
+BIO *in=NULL;
+
+void close_up()
+	{
+	if (in != NULL)
+		BIO_free(in);
+	}
+
+int main(argc,argv)
+int argc;
+char *argv[];
+	{
+	char *port=NULL;
+	BIO *ssl_bio,*tmp;
+	SSL_CTX *ctx;
+	SSL *ssl;
+	char buf[512];
+	int ret=1,i;
+
+        if (argc <= 1)
+		port="*:4433";
+	else
+		port=argv[1];
+
+	signal(SIGINT,close_up);
+
+	SSL_load_error_strings();
+
+#ifdef WATT32
+	dbug_init();
+	sock_init();
+#endif
+
+	/* Add ciphers and message digests */
+	OpenSSL_add_ssl_algorithms();
+
+	ctx=SSL_CTX_new(SSLv23_server_method());
+	if (!SSL_CTX_use_certificate_file(ctx,CERT_FILE,SSL_FILETYPE_PEM))
+		goto err;
+	if (!SSL_CTX_use_PrivateKey_file(ctx,CERT_FILE,SSL_FILETYPE_PEM))
+		goto err;
+	if (!SSL_CTX_check_private_key(ctx))
+		goto err;
+
+	/* Setup server side SSL bio */
+	ssl=SSL_new(ctx);
+	ssl_bio=BIO_new_ssl(ctx,0);
+
+	if ((in=BIO_new_accept(port)) == NULL) goto err;
+
+	/* This means that when a new connection is acceptede on 'in',
+	 * The ssl_bio will be 'dupilcated' and have the new socket
+	 * BIO push into it.  Basically it means the SSL BIO will be
+	 * automatically setup */
+	BIO_set_accept_bios(in,ssl_bio);
+
+again:
+	/* The first call will setup the accept socket, and the second
+	 * will get a socket.  In this loop, the first actual accept
+	 * will occur in the BIO_read() function. */
+
+	if (BIO_do_accept(in) <= 0) goto err;
+
+	for (;;)
+		{
+		i=BIO_read(in,buf,512);
+		if (i == 0)
+			{
+			/* If we have finished, remove the underlying
+			 * BIO stack so the next time we call any function
+			 * for this BIO, it will attempt to do an
+			 * accept */
+			printf("Done\n");
+			tmp=BIO_pop(in);
+			BIO_free_all(tmp);
+			goto again;
+			}
+		if (i < 0) goto err;
+		fwrite(buf,1,i,stdout);
+		fflush(stdout);
+		}
+
+	ret=0;
+err:
+	if (ret)
+		{
+		ERR_print_errors_fp(stderr);
+		}
+	if (in != NULL) BIO_free(in);
+	exit(ret);
+	return(!ret);
+	}
+
diff --git a/openssl/demos/bio/sconnect.c b/openssl/demos/bio/sconnect.c
new file mode 100644
index 0000000..880344e
--- /dev/null
+++ b/openssl/demos/bio/sconnect.c
@@ -0,0 +1,121 @@
+/* NOCW */
+/* demos/bio/sconnect.c */
+
+/* A minimal program to do SSL to a passed host and port.
+ * It is actually using non-blocking IO but in a very simple manner
+ * sconnect host:port - it does a 'GET / HTTP/1.0'
+ *
+ * cc -I../../include sconnect.c -L../.. -lssl -lcrypto
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+extern int errno;
+
+int main(argc,argv)
+int argc;
+char *argv[];
+	{
+	char *host;
+	BIO *out;
+	char buf[1024*10],*p;
+	SSL_CTX *ssl_ctx=NULL;
+	SSL *ssl;
+	BIO *ssl_bio;
+	int i,len,off,ret=1;
+
+	if (argc <= 1)
+		host="localhost:4433";
+	else
+		host=argv[1];
+
+#ifdef WATT32
+	dbug_init();
+	sock_init();
+#endif
+
+	/* Lets get nice error messages */
+	SSL_load_error_strings();
+
+	/* Setup all the global SSL stuff */
+	OpenSSL_add_ssl_algorithms();
+	ssl_ctx=SSL_CTX_new(SSLv23_client_method());
+
+	/* Lets make a SSL structure */
+	ssl=SSL_new(ssl_ctx);
+	SSL_set_connect_state(ssl);
+
+	/* Use it inside an SSL BIO */
+	ssl_bio=BIO_new(BIO_f_ssl());
+	BIO_set_ssl(ssl_bio,ssl,BIO_CLOSE);
+
+	/* Lets use a connect BIO under the SSL BIO */
+	out=BIO_new(BIO_s_connect());
+	BIO_set_conn_hostname(out,host);
+	BIO_set_nbio(out,1);
+	out=BIO_push(ssl_bio,out);
+
+	p="GET / HTTP/1.0\r\n\r\n";
+	len=strlen(p);
+
+	off=0;
+	for (;;)
+		{
+		i=BIO_write(out,&(p[off]),len);
+		if (i <= 0)
+			{
+			if (BIO_should_retry(out))
+				{
+				fprintf(stderr,"write DELAY\n");
+				sleep(1);
+				continue;
+				}
+			else
+				{
+				goto err;
+				}
+			}
+		off+=i;
+		len-=i;
+		if (len <= 0) break;
+		}
+
+	for (;;)
+		{
+		i=BIO_read(out,buf,sizeof(buf));
+		if (i == 0) break;
+		if (i < 0)
+			{
+			if (BIO_should_retry(out))
+				{
+				fprintf(stderr,"read DELAY\n");
+				sleep(1);
+				continue;
+				}
+			goto err;
+			}
+		fwrite(buf,1,i,stdout);
+		}
+
+	ret=1;
+
+	if (0)
+		{
+err:
+		if (ERR_peek_error() == 0) /* system call error */
+			{
+			fprintf(stderr,"errno=%d ",errno);
+			perror("error");
+			}
+		else
+			ERR_print_errors_fp(stderr);
+		}
+	BIO_free_all(out);
+	if (ssl_ctx != NULL) SSL_CTX_free(ssl_ctx);
+	exit(!ret);
+	return(ret);
+	}
+
diff --git a/openssl/demos/bio/server.pem b/openssl/demos/bio/server.pem
new file mode 100644
index 0000000..5cf1387
--- /dev/null
+++ b/openssl/demos/bio/server.pem
@@ -0,0 +1,30 @@
+subject=/C=AU/SP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
+issuer= /C=AU/SP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
+-----BEGIN X509 CERTIFICATE-----
+
+MIIBgjCCASwCAQQwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV
+BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MTAwOTIz
+MzIwNVoXDTk4MDcwNTIzMzIwNVowYDELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM
+RDEZMBcGA1UEChMQTWluY29tIFB0eS4gTHRkLjELMAkGA1UECxMCQ1MxGzAZBgNV
+BAMTElNTTGVheSBkZW1vIHNlcnZlcjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3
+LCXcScWua0PFLkHBLm2VejqpA1F4RQ8q0VjRiPafjx/Z/aWH3ipdMVvuJGa/wFXb
+/nDFLDlfWp+oCPwhBtVPAgMBAAEwDQYJKoZIhvcNAQEEBQADQQArNFsihWIjBzb0
+DCsU0BvL2bvSwJrPEqFlkDq3F4M6EGutL9axEcANWgbbEdAvNJD1dmEmoWny27Pn
+IMs6ZOZB
+-----END X509 CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+
+MIIBPAIBAAJBALcsJdxJxa5rQ8UuQcEubZV6OqkDUXhFDyrRWNGI9p+PH9n9pYfe
+Kl0xW+4kZr/AVdv+cMUsOV9an6gI/CEG1U8CAwEAAQJAXJMBZ34ZXHd1vtgL/3hZ
+hexKbVTx/djZO4imXO/dxPGRzG2ylYZpHmG32/T1kaHpZlCHoEPgHoSzmxYXfxjG
+sQIhAPmZ/bQOjmRUHM/VM2X5zrjjM6z18R1P6l3ObFwt9FGdAiEAu943Yh9SqMRw
+tL0xHGxKmM/YJueUw1gB6sLkETN71NsCIQCeT3RhoqXfrpXDoEcEU+gwzjI1bpxq
+agiNTOLfqGoA5QIhAIQFYjgzONxex7FLrsKBm16N2SFl5pXsN9SpRqqL2n63AiEA
+g9VNIQ3xwpw7og3IbONifeku+J9qGMGQJMKwSTwrFtI=
+-----END RSA PRIVATE KEY-----
+
+-----BEGIN DH PARAMETERS-----
+MEYCQQDaWDwW2YUiidDkr3VvTMqS3UvlM7gE+w/tlO+cikQD7VdGUNNpmdsp13Yn
+a6LT1BLiGPTdHghM9tgAPnxHdOgzAgEC
+-----END DH PARAMETERS-----
+
diff --git a/openssl/demos/cms/cacert.pem b/openssl/demos/cms/cacert.pem
new file mode 100644
index 0000000..75cbb34
--- /dev/null
+++ b/openssl/demos/cms/cacert.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC6DCCAlGgAwIBAgIJAMfGO3rdo2uUMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
+BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
+dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTc0MzE3
+WhcNMTcwNDEwMTc0MzE3WjBXMQswCQYDVQQGEwJVSzESMBAGA1UEBxMJVGVzdCBD
+aXR5MRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMRwwGgYDVQQDExNUZXN0IFMvTUlN
+RSBSb290IENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqJMal1uC1/1wz
+i5+dE4EZF2im3BgROm5PVMbwPY9V1t+KYvtdc3rMcRgJaMbP+qaEcDXoIsZfYXGR
+ielgfDNZmZcj1y/FOum+Jc2OZMs3ggPmjIQ3dbBECq0hZKcbz7wfr+2OeNWm46iT
+jcSIXpGIRhUYEzOgv7zb8oOU70IbbwIDAQABo4G7MIG4MB0GA1UdDgQWBBRHUypx
+CXFQYqewhGo72lWPQUsjoDCBiAYDVR0jBIGAMH6AFEdTKnEJcVBip7CEajvaVY9B
+SyOgoVukWTBXMQswCQYDVQQGEwJVSzESMBAGA1UEBxMJVGVzdCBDaXR5MRYwFAYD
+VQQKEw1PcGVuU1NMIEdyb3VwMRwwGgYDVQQDExNUZXN0IFMvTUlNRSBSb290IENB
+ggkAx8Y7et2ja5QwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQANI+Yc
+G/YDM1WMUGEzEkU9UhsIUqdyBebnK3+OyxZSouDcE/M10jFJzBf/F5b0uUGAKWwo
+u0dzmILfKjdfWe8EyCRafZcm00rVcO09i/63FBYzlHbmfUATIqZdhKzxxQMPs5mF
+1je+pHUpzIY8TSXyh/uD9IkAy04IHwGZQf9akw==
+-----END CERTIFICATE-----
diff --git a/openssl/demos/cms/cakey.pem b/openssl/demos/cms/cakey.pem
new file mode 100644
index 0000000..3b53c5e
--- /dev/null
+++ b/openssl/demos/cms/cakey.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQCqJMal1uC1/1wzi5+dE4EZF2im3BgROm5PVMbwPY9V1t+KYvtd
+c3rMcRgJaMbP+qaEcDXoIsZfYXGRielgfDNZmZcj1y/FOum+Jc2OZMs3ggPmjIQ3
+dbBECq0hZKcbz7wfr+2OeNWm46iTjcSIXpGIRhUYEzOgv7zb8oOU70IbbwIDAQAB
+AoGBAKWOZ2UTc1BkjDjz0XoscmAR8Rj77MdGzfOPkIxPultSW+3yZpkGNyUbnsH5
+HAtf4Avai/m3bMN+s91kDpx9/g/I9ZEHPQLcDICETvwt/EHT7+hwvaQgsM+TgpMs
+tjlGZOWent6wVIuvwwzqOMXZLgK9FvY7upwgtrys4G3Kab5hAkEA2QzFflWyEvKS
+rMSaVtn/IjFilwa7H0IdakkjM34z4peerFTPBr4J47YD4RCR/dAvxyNy3zUxtH18
+9R6dUixI6QJBAMitJD0xOkbGWBX8KVJvRiKOIdf/95ZUAgN/h3bWKy57EB9NYj3u
+jbxXcvdjfSqiITykkjAg7SG7nrlzJsu6CpcCQG6gVsy0auXDY0TRlASuaZ6I40Is
+uRUOgqWYj2uAaHuWYdZeB4LdO3cnX0TISFDAWom6JKNlnmbrCtR4fSDT13kCQQCU
++VQJyV3F5MDHsWbLt6eNR46AV5lpk/vatPXPlrZ/zwPs+PmRmGLICvNiDA2DdNDP
+wCx2Zjsj67CtY3rNitMJAkEAm09BQnjnbBXUb1rd2SjNDWTsu80Z+zLu8pAwXNhW
+8nsvMYqlYMIxuMPwu/QuTnMRhMZ08uhqoD3ukZnBeoMEVg==
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/demos/cms/cms_comp.c b/openssl/demos/cms/cms_comp.c
new file mode 100644
index 0000000..b7943e8
--- /dev/null
+++ b/openssl/demos/cms/cms_comp.c
@@ -0,0 +1,61 @@
+/* Simple S/MIME compress example */
+#include <openssl/pem.h>
+#include <openssl/cms.h>
+#include <openssl/err.h>
+
+int main(int argc, char **argv)
+	{
+	BIO *in = NULL, *out = NULL;
+	CMS_ContentInfo *cms = NULL;
+	int ret = 1;
+
+	/*
+	 * On OpenSSL 0.9.9 only:
+	 * for streaming set CMS_STREAM
+	 */
+	int flags = CMS_STREAM;
+
+	OpenSSL_add_all_algorithms();
+	ERR_load_crypto_strings();
+
+	/* Open content being compressed */
+
+	in = BIO_new_file("comp.txt", "r");
+
+	if (!in)
+		goto err;
+
+	/* compress content */
+	cms = CMS_compress(in, NID_zlib_compression, flags);
+
+	if (!cms)
+		goto err;
+
+	out = BIO_new_file("smcomp.txt", "w");
+	if (!out)
+		goto err;
+
+	/* Write out S/MIME message */
+	if (!SMIME_write_CMS(out, cms, in, flags))
+		goto err;
+
+	ret = 0;
+
+	err:
+
+	if (ret)
+		{
+		fprintf(stderr, "Error Compressing Data\n");
+		ERR_print_errors_fp(stderr);
+		}
+
+	if (cms)
+		CMS_ContentInfo_free(cms);
+	if (in)
+		BIO_free(in);
+	if (out)
+		BIO_free(out);
+
+	return ret;
+
+	}
diff --git a/openssl/demos/cms/cms_ddec.c b/openssl/demos/cms/cms_ddec.c
new file mode 100644
index 0000000..ba68cfd
--- /dev/null
+++ b/openssl/demos/cms/cms_ddec.c
@@ -0,0 +1,89 @@
+/* S/MIME detached data decrypt example: rarely done but
+ * should the need arise this is an example....
+ */
+#include <openssl/pem.h>
+#include <openssl/cms.h>
+#include <openssl/err.h>
+
+int main(int argc, char **argv)
+	{
+	BIO *in = NULL, *out = NULL, *tbio = NULL, *dcont = NULL;
+	X509 *rcert = NULL;
+	EVP_PKEY *rkey = NULL;
+	CMS_ContentInfo *cms = NULL;
+	int ret = 1;
+
+	OpenSSL_add_all_algorithms();
+	ERR_load_crypto_strings();
+
+	/* Read in recipient certificate and private key */
+	tbio = BIO_new_file("signer.pem", "r");
+
+	if (!tbio)
+		goto err;
+
+	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
+
+	BIO_reset(tbio);
+
+	rkey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
+
+	if (!rcert || !rkey)
+		goto err;
+
+	/* Open PEM file containing enveloped data */
+
+	in = BIO_new_file("smencr.pem", "r");
+
+	if (!in)
+		goto err;
+
+	/* Parse PEM content */
+	cms = PEM_read_bio_CMS(in, NULL, 0, NULL);
+
+	if (!cms)
+		goto err;
+
+	/* Open file containing detached content */
+	dcont = BIO_new_file("smencr.out", "rb");
+
+	if (!in)
+		goto err;
+
+	out = BIO_new_file("encrout.txt", "w");
+	if (!out)
+		goto err;
+
+	/* Decrypt S/MIME message */
+	if (!CMS_decrypt(cms, rkey, rcert, dcont, out, 0))
+		goto err;
+
+	ret = 0;
+
+	err:
+
+	if (ret)
+		{
+		fprintf(stderr, "Error Decrypting Data\n");
+		ERR_print_errors_fp(stderr);
+		}
+
+	if (cms)
+		CMS_ContentInfo_free(cms);
+	if (rcert)
+		X509_free(rcert);
+	if (rkey)
+		EVP_PKEY_free(rkey);
+
+	if (in)
+		BIO_free(in);
+	if (out)
+		BIO_free(out);
+	if (tbio)
+		BIO_free(tbio);
+	if (dcont)
+		BIO_free(dcont);
+
+	return ret;
+
+	}
diff --git a/openssl/demos/cms/cms_dec.c b/openssl/demos/cms/cms_dec.c
new file mode 100644
index 0000000..7ddf653
--- /dev/null
+++ b/openssl/demos/cms/cms_dec.c
@@ -0,0 +1,79 @@
+/* Simple S/MIME decryption example */
+#include <openssl/pem.h>
+#include <openssl/cms.h>
+#include <openssl/err.h>
+
+int main(int argc, char **argv)
+	{
+	BIO *in = NULL, *out = NULL, *tbio = NULL;
+	X509 *rcert = NULL;
+	EVP_PKEY *rkey = NULL;
+	CMS_ContentInfo *cms = NULL;
+	int ret = 1;
+
+	OpenSSL_add_all_algorithms();
+	ERR_load_crypto_strings();
+
+	/* Read in recipient certificate and private key */
+	tbio = BIO_new_file("signer.pem", "r");
+
+	if (!tbio)
+		goto err;
+
+	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
+
+	BIO_reset(tbio);
+
+	rkey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
+
+	if (!rcert || !rkey)
+		goto err;
+
+	/* Open S/MIME message to decrypt */
+
+	in = BIO_new_file("smencr.txt", "r");
+
+	if (!in)
+		goto err;
+
+	/* Parse message */
+	cms = SMIME_read_CMS(in, NULL);
+
+	if (!cms)
+		goto err;
+
+	out = BIO_new_file("decout.txt", "w");
+	if (!out)
+		goto err;
+
+	/* Decrypt S/MIME message */
+	if (!CMS_decrypt(cms, rkey, rcert, out, NULL, 0))
+		goto err;
+
+	ret = 0;
+
+	err:
+
+	if (ret)
+		{
+		fprintf(stderr, "Error Decrypting Data\n");
+		ERR_print_errors_fp(stderr);
+		}
+
+	if (cms)
+		CMS_ContentInfo_free(cms);
+	if (rcert)
+		X509_free(rcert);
+	if (rkey)
+		EVP_PKEY_free(rkey);
+
+	if (in)
+		BIO_free(in);
+	if (out)
+		BIO_free(out);
+	if (tbio)
+		BIO_free(tbio);
+
+	return ret;
+
+	}
diff --git a/openssl/demos/cms/cms_denc.c b/openssl/demos/cms/cms_denc.c
new file mode 100644
index 0000000..9265e47
--- /dev/null
+++ b/openssl/demos/cms/cms_denc.c
@@ -0,0 +1,97 @@
+/* S/MIME detached data encrypt example: rarely done but
+ * should the need arise this is an example....
+ */
+#include <openssl/pem.h>
+#include <openssl/cms.h>
+#include <openssl/err.h>
+
+int main(int argc, char **argv)
+	{
+	BIO *in = NULL, *out = NULL, *tbio = NULL, *dout = NULL;
+	X509 *rcert = NULL;
+	STACK_OF(X509) *recips = NULL;
+	CMS_ContentInfo *cms = NULL;
+	int ret = 1;
+
+	int flags = CMS_STREAM|CMS_DETACHED;
+
+	OpenSSL_add_all_algorithms();
+	ERR_load_crypto_strings();
+
+	/* Read in recipient certificate */
+	tbio = BIO_new_file("signer.pem", "r");
+
+	if (!tbio)
+		goto err;
+
+	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
+
+	if (!rcert)
+		goto err;
+
+	/* Create recipient STACK and add recipient cert to it */
+	recips = sk_X509_new_null();
+
+	if (!recips || !sk_X509_push(recips, rcert))
+		goto err;
+
+	/* sk_X509_pop_free will free up recipient STACK and its contents
+	 * so set rcert to NULL so it isn't freed up twice.
+	 */
+	rcert = NULL;
+
+	/* Open content being encrypted */
+
+	in = BIO_new_file("encr.txt", "r");
+
+	dout = BIO_new_file("smencr.out", "wb");
+
+	if (!in)
+		goto err;
+
+	/* encrypt content */
+	cms = CMS_encrypt(recips, in, EVP_des_ede3_cbc(), flags);
+
+	if (!cms)
+		goto err;
+
+	out = BIO_new_file("smencr.pem", "w");
+	if (!out)
+		goto err;
+
+	if (!CMS_final(cms, in, dout, flags))
+		goto err;
+
+	/* Write out CMS structure without content */
+	if (!PEM_write_bio_CMS(out, cms))
+		goto err;
+
+	ret = 0;
+
+	err:
+
+	if (ret)
+		{
+		fprintf(stderr, "Error Encrypting Data\n");
+		ERR_print_errors_fp(stderr);
+		}
+
+	if (cms)
+		CMS_ContentInfo_free(cms);
+	if (rcert)
+		X509_free(rcert);
+	if (recips)
+		sk_X509_pop_free(recips, X509_free);
+
+	if (in)
+		BIO_free(in);
+	if (out)
+		BIO_free(out);
+	if (dout)
+		BIO_free(dout);
+	if (tbio)
+		BIO_free(tbio);
+
+	return ret;
+
+	}
diff --git a/openssl/demos/cms/cms_enc.c b/openssl/demos/cms/cms_enc.c
new file mode 100644
index 0000000..916b479
--- /dev/null
+++ b/openssl/demos/cms/cms_enc.c
@@ -0,0 +1,92 @@
+/* Simple S/MIME encrypt example */
+#include <openssl/pem.h>
+#include <openssl/cms.h>
+#include <openssl/err.h>
+
+int main(int argc, char **argv)
+	{
+	BIO *in = NULL, *out = NULL, *tbio = NULL;
+	X509 *rcert = NULL;
+	STACK_OF(X509) *recips = NULL;
+	CMS_ContentInfo *cms = NULL;
+	int ret = 1;
+
+	/*
+	 * On OpenSSL 1.0.0 and later only:
+	 * for streaming set CMS_STREAM
+	 */
+	int flags = CMS_STREAM;
+
+	OpenSSL_add_all_algorithms();
+	ERR_load_crypto_strings();
+
+	/* Read in recipient certificate */
+	tbio = BIO_new_file("signer.pem", "r");
+
+	if (!tbio)
+		goto err;
+
+	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
+
+	if (!rcert)
+		goto err;
+
+	/* Create recipient STACK and add recipient cert to it */
+	recips = sk_X509_new_null();
+
+	if (!recips || !sk_X509_push(recips, rcert))
+		goto err;
+
+	/* sk_X509_pop_free will free up recipient STACK and its contents
+	 * so set rcert to NULL so it isn't freed up twice.
+	 */
+	rcert = NULL;
+
+	/* Open content being encrypted */
+
+	in = BIO_new_file("encr.txt", "r");
+
+	if (!in)
+		goto err;
+
+	/* encrypt content */
+	cms = CMS_encrypt(recips, in, EVP_des_ede3_cbc(), flags);
+
+	if (!cms)
+		goto err;
+
+	out = BIO_new_file("smencr.txt", "w");
+	if (!out)
+		goto err;
+
+	/* Write out S/MIME message */
+	if (!SMIME_write_CMS(out, cms, in, flags))
+		goto err;
+
+	ret = 0;
+
+	err:
+
+	if (ret)
+		{
+		fprintf(stderr, "Error Encrypting Data\n");
+		ERR_print_errors_fp(stderr);
+		}
+
+	if (cms)
+		CMS_ContentInfo_free(cms);
+	if (rcert)
+		X509_free(rcert);
+	if (recips)
+		sk_X509_pop_free(recips, X509_free);
+
+	if (in)
+		BIO_free(in);
+	if (out)
+		BIO_free(out);
+	if (tbio)
+		BIO_free(tbio);
+
+	return ret;
+
+	}
diff --git a/openssl/demos/cms/cms_sign.c b/openssl/demos/cms/cms_sign.c
new file mode 100644
index 0000000..42f7620
--- /dev/null
+++ b/openssl/demos/cms/cms_sign.c
@@ -0,0 +1,89 @@
+/* Simple S/MIME signing example */
+#include <openssl/pem.h>
+#include <openssl/cms.h>
+#include <openssl/err.h>
+
+int main(int argc, char **argv)
+	{
+	BIO *in = NULL, *out = NULL, *tbio = NULL;
+	X509 *scert = NULL;
+	EVP_PKEY *skey = NULL;
+	CMS_ContentInfo *cms = NULL;
+	int ret = 1;
+
+	/* For simple S/MIME signing use CMS_DETACHED.
+	 * On OpenSSL 0.9.9 only:
+	 * for streaming detached set CMS_DETACHED|CMS_STREAM
+	 * for streaming non-detached set CMS_STREAM
+	 */
+	int flags = CMS_DETACHED|CMS_STREAM;
+
+	OpenSSL_add_all_algorithms();
+	ERR_load_crypto_strings();
+
+	/* Read in signer certificate and private key */
+	tbio = BIO_new_file("signer.pem", "r");
+
+	if (!tbio)
+		goto err;
+
+	scert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
+
+	BIO_reset(tbio);
+
+	skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
+
+	if (!scert || !skey)
+		goto err;
+
+	/* Open content being signed */
+
+	in = BIO_new_file("sign.txt", "r");
+
+	if (!in)
+		goto err;
+
+	/* Sign content */
+	cms = CMS_sign(scert, skey, NULL, in, flags);
+
+	if (!cms)
+		goto err;
+
+	out = BIO_new_file("smout.txt", "w");
+	if (!out)
+		goto err;
+
+	if (!(flags & CMS_STREAM))
+		BIO_reset(in);
+
+	/* Write out S/MIME message */
+	if (!SMIME_write_CMS(out, cms, in, flags))
+		goto err;
+
+	ret = 0;
+
+	err:
+
+	if (ret)
+		{
+		fprintf(stderr, "Error Signing Data\n");
+		ERR_print_errors_fp(stderr);
+		}
+
+	if (cms)
+		CMS_ContentInfo_free(cms);
+	if (scert)
+		X509_free(scert);
+	if (skey)
+		EVP_PKEY_free(skey);
+
+	if (in)
+		BIO_free(in);
+	if (out)
+		BIO_free(out);
+	if (tbio)
+		BIO_free(tbio);
+
+	return ret;
+
+	}
diff --git a/openssl/demos/cms/cms_sign2.c b/openssl/demos/cms/cms_sign2.c
new file mode 100644
index 0000000..36adee7
--- /dev/null
+++ b/openssl/demos/cms/cms_sign2.c
@@ -0,0 +1,103 @@
+/* S/MIME signing example: 2 signers */
+#include <openssl/pem.h>
+#include <openssl/cms.h>
+#include <openssl/err.h>
+
+int main(int argc, char **argv)
+	{
+	BIO *in = NULL, *out = NULL, *tbio = NULL;
+	X509 *scert = NULL, *scert2 = NULL;
+	EVP_PKEY *skey = NULL, *skey2 = NULL;
+	CMS_ContentInfo *cms = NULL;
+	int ret = 1;
+
+	OpenSSL_add_all_algorithms();
+	ERR_load_crypto_strings();
+
+	tbio = BIO_new_file("signer.pem", "r");
+
+	if (!tbio)
+		goto err;
+
+	scert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
+
+	BIO_reset(tbio);
+
+	skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
+
+	BIO_free(tbio);
+
+	tbio = BIO_new_file("signer2.pem", "r");
+
+	if (!tbio)
+		goto err;
+
+	scert2 = PEM_read_bio_X509(tbio, NULL, 0, NULL);
+
+	BIO_reset(tbio);
+
+	skey2 = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
+
+	if (!scert2 || !skey2)
+		goto err;
+
+	in = BIO_new_file("sign.txt", "r");
+
+	if (!in)
+		goto err;
+
+	cms = CMS_sign(NULL, NULL, NULL, in, CMS_STREAM|CMS_PARTIAL);
+
+	if (!cms)
+		goto err;
+
+	/* Add each signer in turn */
+
+	if (!CMS_add1_signer(cms, scert, skey, NULL, 0))
+		goto err;
+
+	if (!CMS_add1_signer(cms, scert2, skey2, NULL, 0))
+		goto err;
+
+	out = BIO_new_file("smout.txt", "w");
+	if (!out)
+		goto err;
+
+	/* NB: content included and finalized by SMIME_write_CMS */
+
+	if (!SMIME_write_CMS(out, cms, in, CMS_STREAM))
+		goto err;
+
+	ret = 0;
+
+	err:
+
+	if (ret)
+		{
+		fprintf(stderr, "Error Signing Data\n");
+		ERR_print_errors_fp(stderr);
+		}
+
+	if (cms)
+		CMS_ContentInfo_free(cms);
+
+	if (scert)
+		X509_free(scert);
+	if (skey)
+		EVP_PKEY_free(skey);
+
+	if (scert2)
+		X509_free(scert2);
+	if (skey)
+		EVP_PKEY_free(skey2);
+
+	if (in)
+		BIO_free(in);
+	if (out)
+		BIO_free(out);
+	if (tbio)
+		BIO_free(tbio);
+
+	return ret;
+
+	}
diff --git a/openssl/demos/cms/cms_uncomp.c b/openssl/demos/cms/cms_uncomp.c
new file mode 100644
index 0000000..f15ae2f
--- /dev/null
+++ b/openssl/demos/cms/cms_uncomp.c
@@ -0,0 +1,56 @@
+/* Simple S/MIME uncompression example */
+#include <openssl/pem.h>
+#include <openssl/cms.h>
+#include <openssl/err.h>
+
+int main(int argc, char **argv)
+	{
+	BIO *in = NULL, *out = NULL;
+	CMS_ContentInfo *cms = NULL;
+	int ret = 1;
+
+	OpenSSL_add_all_algorithms();
+	ERR_load_crypto_strings();
+
+	/* Open compressed content */
+
+	in = BIO_new_file("smcomp.txt", "r");
+
+	if (!in)
+		goto err;
+
+	/* Sign content */
+	cms = SMIME_read_CMS(in, NULL);
+
+	if (!cms)
+		goto err;
+
+	out = BIO_new_file("smuncomp.txt", "w");
+	if (!out)
+		goto err;
+
+	/* Uncompress S/MIME message */
+	if (!CMS_uncompress(cms, out, NULL, 0))
+		goto err;
+
+	ret = 0;
+
+	err:
+
+	if (ret)
+		{
+		fprintf(stderr, "Error Uncompressing Data\n");
+		ERR_print_errors_fp(stderr);
+		}
+
+	if (cms)
+		CMS_ContentInfo_free(cms);
+
+	if (in)
+		BIO_free(in);
+	if (out)
+		BIO_free(out);
+
+	return ret;
+
+	}
diff --git a/openssl/demos/cms/cms_ver.c b/openssl/demos/cms/cms_ver.c
new file mode 100644
index 0000000..bf1145e
--- /dev/null
+++ b/openssl/demos/cms/cms_ver.c
@@ -0,0 +1,87 @@
+/* Simple S/MIME verification example */
+#include <openssl/pem.h>
+#include <openssl/cms.h>
+#include <openssl/err.h>
+
+int main(int argc, char **argv)
+	{
+	BIO *in = NULL, *out = NULL, *tbio = NULL, *cont = NULL;
+	X509_STORE *st = NULL;
+	X509 *cacert = NULL;
+	CMS_ContentInfo *cms = NULL;
+
+	int ret = 1;
+
+	OpenSSL_add_all_algorithms();
+	ERR_load_crypto_strings();
+
+	/* Set up trusted CA certificate store */
+
+	st = X509_STORE_new();
+
+	/* Read in CA certificate */
+	tbio = BIO_new_file("cacert.pem", "r");
+
+	if (!tbio)
+		goto err;
+
+	cacert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
+
+	if (!cacert)
+		goto err;
+
+	if (!X509_STORE_add_cert(st, cacert))
+		goto err;
+
+	/* Open message being verified */
+
+	in = BIO_new_file("smout.txt", "r");
+
+	if (!in)
+		goto err;
+
+	/* parse message */
+	cms = SMIME_read_CMS(in, &cont);
+
+	if (!cms)
+		goto err;
+
+	/* File to output verified content to */
+	out = BIO_new_file("smver.txt", "w");
+	if (!out)
+		goto err;
+
+	if (!CMS_verify(cms, NULL, st, cont, out, 0))
+		{
+		fprintf(stderr, "Verification Failure\n");
+		goto err;
+		}
+
+	fprintf(stderr, "Verification Successful\n");
+
+	ret = 0;
+
+	err:
+
+	if (ret)
+		{
+		fprintf(stderr, "Error Verifying Data\n");
+		ERR_print_errors_fp(stderr);
+		}
+
+	if (cms)
+		CMS_ContentInfo_free(cms);
+
+	if (cacert)
+		X509_free(cacert);
+
+	if (in)
+		BIO_free(in);
+	if (out)
+		BIO_free(out);
+	if (tbio)
+		BIO_free(tbio);
+
+	return ret;
+
+	}
diff --git a/openssl/demos/cms/comp.txt b/openssl/demos/cms/comp.txt
new file mode 100644
index 0000000..1672328
--- /dev/null
+++ b/openssl/demos/cms/comp.txt
@@ -0,0 +1,22 @@
+Content-type: text/plain
+
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
+Some Text To be Compressed
diff --git a/openssl/demos/cms/encr.txt b/openssl/demos/cms/encr.txt
new file mode 100644
index 0000000..0eceb40
--- /dev/null
+++ b/openssl/demos/cms/encr.txt
@@ -0,0 +1,3 @@
+Content-type: text/plain
+
+Sample OpenSSL Data for CMS encryption
diff --git a/openssl/demos/cms/sign.txt b/openssl/demos/cms/sign.txt
new file mode 100644
index 0000000..c3f9d73
--- /dev/null
+++ b/openssl/demos/cms/sign.txt
@@ -0,0 +1,3 @@
+Content-type: text/plain
+
+Test OpenSSL CMS Signed Content
diff --git a/openssl/demos/cms/signer.pem b/openssl/demos/cms/signer.pem
new file mode 100644
index 0000000..bac16ba
--- /dev/null
+++ b/openssl/demos/cms/signer.pem
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIICpjCCAg+gAwIBAgIJAJ+rfmEoLQRhMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
+BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
+dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTgyOTI3
+WhcNMTcwNDA5MTgyOTI3WjBWMQswCQYDVQQGEwJVSzElMCMGA1UEAxMcT3BlblNT
+TCB0ZXN0IFMvTUlNRSBzaWduZXIgMTEgMB4GCSqGSIb3DQEJARYRdGVzdDFAb3Bl
+bnNzbC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL1ocAQ7ON2pIUXz
+jwKPzpPB9ozB6PFG6F6kARO+i0DiT6Qn8abUjwpHPU+lGys83QlpbkQVUD6Fv/4L
+ytihk6N9Pr/feECVcSZ20dI43WXjfYak14dSVrZkGNMMXqKmnnqtkAdD0oJN7A7y
+gcf8RuViV0kvk9/36eCMwMHrImfhAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI
+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
+BBSyKqjvctIsFNBHULBTqr8SHtSxpDAfBgNVHSMEGDAWgBRHUypxCXFQYqewhGo7
+2lWPQUsjoDANBgkqhkiG9w0BAQQFAAOBgQBvdYVoBfd4RV/xWSMXIcgw/i5OiwyX
+MsenQePll51MpglfArd7pUipUalCqlJt/Gs8kD16Ih1z1yuWYVTMlnDZ0PwbIOYn
++Jr8XLF9b1SMJt6PwckZZ0LZdIi2KwGAxVsIW1kjJAqu9o4YH37XW37yYdQRxfvv
+lDiQlgX0JtmLgA==
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQC9aHAEOzjdqSFF848Cj86TwfaMwejxRuhepAETvotA4k+kJ/Gm
+1I8KRz1PpRsrPN0JaW5EFVA+hb/+C8rYoZOjfT6/33hAlXEmdtHSON1l432GpNeH
+Ula2ZBjTDF6ipp56rZAHQ9KCTewO8oHH/EblYldJL5Pf9+ngjMDB6yJn4QIDAQAB
+AoGACCuYIWaYll80UzslYRvo8lC8nOfEb5v6bBKxBTQD98GLY+5hKywiG3RlPalG
+mb/fXQeSPReaRYgpdwD1OBEIOEMW9kLyqpzokC0xjpZ+MwsuJTlxCesk5GEsMa3o
+wC3QMmiRA7qrZ/SzTtwrs++9mZ/pxp8JZ6pKYUj8SE7/vV0CQQDz8Ix2t40E16hx
+04+XhClnGqydZJyLLSxcTU3ZVhYxL+efo/5hZ8tKpkcDi8wq6T03BOKrKxrlIW55
+qDRNM24rAkEAxsWzu/rJhIouQyNoYygEIEYzFRlTQyZSg59u6dNiewMn27dOAbyc
+YT7B6da7e74QttTXo0lIllsX2S38+XsIIwJBANSRuIU3G66tkr5l4gnhhAaxqtuY
+sgVhvvdL8dvC9aG1Ifzt9hzBSthpHxbK+oYmK07HdhI8hLpIMLHYzoK7n3MCQEy4
+4rccBcxyyYiAkjozp+QNNIpgTBMPJ6pGT7lRLiHtBeV4y1NASdv/LTnk+Fi69Bid
+7t3H24ytfHcHmS1yn6ECQF6Jmh4C7dlvp59zXp+t+VsXxa/8sq41vKNIj0Rx9vh5
+xp9XL0C5ZpgmBnsTydP9pmkiL4ltLbMX0wJU6N2cmFw=
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/demos/cms/signer2.pem b/openssl/demos/cms/signer2.pem
new file mode 100644
index 0000000..25e23d1
--- /dev/null
+++ b/openssl/demos/cms/signer2.pem
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIICpjCCAg+gAwIBAgIJAJ+rfmEoLQRiMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
+BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
+dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTgyOTQ0
+WhcNMTcwNDA5MTgyOTQ0WjBWMQswCQYDVQQGEwJVSzElMCMGA1UEAxMcT3BlblNT
+TCB0ZXN0IFMvTUlNRSBzaWduZXIgMjEgMB4GCSqGSIb3DQEJARYRdGVzdDJAb3Bl
+bnNzbC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANco7VPgX9vcGwmZ
+jYqjq1JiR7M38dsMNhuJyLRVjJ5/cpFluQydQuG1PhzOJ8zfYVFicOXKvbYuKuXW
+ozZIwzqEqWsNf36KHTLS6yOMG8I13cRInh+fAIKq9Z8Eh65I7FJzVsNsfEQrGfEW
+GMA8us24IaSvP3QkbfHJn/4RaKznAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI
+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
+BBRlrLQJUB8uAa4q8B2OqvvTXonF5zAfBgNVHSMEGDAWgBRHUypxCXFQYqewhGo7
+2lWPQUsjoDANBgkqhkiG9w0BAQQFAAOBgQBQbi2juGALg2k9m1hKpzR2lCGmGO3X
+h3Jh/l0vIxDr0RTgP2vBrtITlx655P/o1snoeTIpYG8uUnFnTE/6YakdayAIlxV4
+aZl63AivZMpQB5SPaPH/jEsGJ8UQMfdiy4ORWIULupuPKlKwODNw7tVhQIACS/DR
+2aX6rl2JEuJ5Yg==
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQDXKO1T4F/b3BsJmY2Ko6tSYkezN/HbDDYbici0VYyef3KRZbkM
+nULhtT4czifM32FRYnDlyr22Lirl1qM2SMM6hKlrDX9+ih0y0usjjBvCNd3ESJ4f
+nwCCqvWfBIeuSOxSc1bDbHxEKxnxFhjAPLrNuCGkrz90JG3xyZ/+EWis5wIDAQAB
+AoGAUTB2bcIrKfGimjrBOGGOUmYXnD8uGnQ/LqENhU8K4vxApTD3ZRUqmbUknQYF
+6r8YH/e/llasw8QkF9qod+F5GTgsnyh/aMidFHKrXXbf1662scz9+S6crSXq9Eb2
+CL57f6Kw61k6edrz8zHdA+rnTK00hzgzKCP4ZL5k8/55ueECQQD+BK+nsKi6CcKf
+m3Mh61Sf2Icm5JlMCKaihlbnh78lBN1imYUAfHJEnQ1ujxXB94R+6o9S+XrWTnTX
+2m/JNIfpAkEA2NaidX7Sv5jnRPkwJ02Srl0urxINLmg4bU0zmM3VoMklYBHWnMyr
+upPZGPh5TzCa+g6FTBmU8XK61wvnEKNcTwJBAM24VdnlBIDGbsx8RJ3vzLU30xz4
+ff5J80okqjUQhwkgC3tTAZgHMTPITZyAXQqdvrxakoCMc6MkHxTBX08AMCECQHHL
+SdyxXrYv7waSY0PtANJCkpJLveEhzqMFxdMmCjtj9BpTojYNbv3uQxtIopj9YAdk
+gW2ray++zvC2DV/86x8CQH4UJwgO6JqU4bSgi6HiRNjDg26tJ0Beu8jjl1vrkIVX
+pHFwSUeLZUsT2/iTUSgYH4uYiZPgYNcKTCT9W6se30A=
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/demos/easy_tls/Makefile b/openssl/demos/easy_tls/Makefile
new file mode 100644
index 0000000..2080700
--- /dev/null
+++ b/openssl/demos/easy_tls/Makefile
@@ -0,0 +1,123 @@
+# Makefile for easy-tls example application (rudimentary client and server)
+# $Id: Makefile,v 1.2 2001/09/18 09:15:40 bodo Exp $
+
+SOLARIS_CFLAGS=-Wall -pedantic -g -O2
+SOLARIS_LIBS=-lxnet
+
+LINUX_CFLAGS=-Wall -pedantic -g -O2
+LINUX_LIBS=
+
+
+auto-all:
+	case `uname -s` in \
+	SunOS) echo Using SunOS configuration; \
+	  make SYSCFLAGS="$(SOLARIS_CFLAGS)" SYSLIBS="$(SOLARIS_LIBS)" all;; \
+	Linux) echo Using Linux configuration; \
+	  make SYSCFLAGS="$(LINUX_CFLAGS)" SYSLIBS="$(LINUX_LIBS)" all;; \
+	*) echo "unknown system"; exit 1;; \
+	esac
+
+all: test TAGS
+
+# For adapting this Makefile to a different system, only the following
+# definitions should need customizing:
+
+OPENSSLDIR=../..
+CC=gcc
+
+SYSCFLAGS=whatever
+SYSLIBS=whatever
+
+
+#############################################################################
+#
+# SSLeay/OpenSSL imports
+#
+# OPENSSLDIR (set above) can be either the directory where OpenSSL is
+# installed or the directory where it was compiled.
+
+# We rely on having a new OpenSSL release where include files
+# have names like <openssl/ssl.h> (not just <ssl.h>).
+OPENSSLINCLUDES=-I$(OPENSSLDIR)/include
+
+# libcrypto.a and libssl.a are directly in $(OPENSSLDIR) if this is
+# the compile directory, or in $(OPENSSLDIR)/lib if we use an installed
+# library.  With the following definition, we can handle either case.
+OPENSSLLIBS=-L$(OPENSSLDIR) -L$(OPENSSLDIR)/lib -lssl -lcrypto
+
+
+#############################################################################
+#
+# Stuff for handling the source files
+#
+
+SOURCES=easy-tls.c test.c
+HEADERS=easy-tls.h test.h
+DOCSandEXAMPLESetc=Makefile cert.pem cacerts.pem
+EVERYTHING=$(SOURCES) $(HEADERS) $(DOCSandEXAMPLESetc)
+
+ls: ls-l
+ls-l:
+	ls -l $(EVERYTHING)
+# For RCS:
+tag:
+	-rcs -n_`date +%y%m%d`: $(EVERYTHING)
+	rcs -nMYTAG $(EVERYTHING)
+	rcs -nMYTAG: $(EVERYTHING)
+diff:
+	-rcsdiff -rMYTAG -u $(EVERYTHING)
+today:
+	-rcsdiff -r_`date +%y%m%d` -u $(EVERYTHING)
+ident:
+	for a in $(EVERYTHING); do ident $$a; done
+
+# Distribution .tar:
+easy-tls.tar.gz: $(EVERYTHING)
+	tar cvf - $(EVERYTHING) | \
+	gzip -9 > easy-tls.tar.gz
+
+# Working .tar:
+tls.tgz: $(EVERYTHING)
+	tar cfv - `find . -type f -a ! -name '*.tgz' -a ! -name '*.tar.gz'` | \
+	gzip -9 > tls.tgz
+
+# For emacs:
+etags: TAGS
+TAGS: $(SOURCES) $(HEADERS)
+	-etags $(SOURCES) $(HEADERS)
+
+
+#############################################################################
+#
+# Compilation
+#
+# The following definitions are system dependent (and hence defined
+# at the beginning of this Makefile, where they are more easily found):
+
+### CC=gcc
+### SYSCFLAGS=-Wall -pedantic -g -O2
+### SYSLIBS=-lxnet
+
+EXTRACFLAGS=-DTLS_APP=\"test.h\"
+# EXTRACFLAGS=-DTLS_APP=\"test.h\" -DDEBUG_TLS
+
+#
+# The rest shouldn't need to be touched.
+#
+LDFLAGS=$(SYSLIBS) $(OPENSSLLIBS)
+INCLUDES=$(OPENSSLINCLUDES)
+CFLAGS=$(SYSCFLAGS) $(EXTRACFLAGS) $(INCLUDES)
+
+OBJS=easy-tls.o test.o
+
+clean:
+	@rm -f test
+	@rm -f TAGS
+	@rm -f *.o
+	@rm -f core
+
+test: $(OBJS)
+	$(CC) $(OBJS) $(LDFLAGS) -o test
+
+test.o: $(HEADERS)
+easy-tls.o: $(HEADERS)
diff --git a/openssl/demos/easy_tls/README b/openssl/demos/easy_tls/README
new file mode 100644
index 0000000..816a580
--- /dev/null
+++ b/openssl/demos/easy_tls/README
@@ -0,0 +1,65 @@
+easy_tls - generic SSL/TLS proxy
+========
+
+(... and example for non-blocking SSL/TLS I/O multiplexing.)
+
+
+  easy_tls.c, easy_tls.h:
+
+     Small generic SSL/TLS proxy library: With a few function calls,
+     an application socket will be replaced by a pipe handled by a
+     separate SSL/TLS proxy process.  This allows easily adding
+     SSL/TLS support to many programs not originally designed for it.
+
+     [Actually easy_tls.c is not a proper library: Customization
+     requires defining preprocessor macros while compiling it.
+     This is quite confusing, so I'll probably change it.]
+
+     These files may be used under the OpenSSL license.
+
+
+
+  test.c, test.h, Makefile, cert.pem, cacerts.pem:
+
+     Rudimentary example program using the easy_tls library, and
+     example key and certificates for it.  Usage examples:
+
+       $ ./test 8443     # create server listening at port 8443
+       $ ./test 127.0.0.1 8443  # create client, connect to port 8443
+                                # at IP address 127.0.0.1
+
+     'test' will not automatically do SSL/TLS, or even read or write
+     data -- it must be told to do so on input lines starting
+     with a command letter.  'W' means write a line, 'R' means
+     read a line, 'C' means close the connection, 'T' means
+     start an SSL/TLS proxy.  E.g. (user input tagged with '*'):
+
+     * R
+       <<< 220 mail.example.net
+     * WSTARTTLS
+       >>> STARTTLS
+     * R
+       <<< 220 Ready to start TLS
+     * T
+       test_process_init(fd = 3, client_p = 1, apparg = (nil))
+       +++ `E:self signed certificate in certificate chain'
+       +++ `<... certificate info ...>'
+     * WHELO localhost
+       >>> HELO localhost
+       R
+       <<< 250 mail.example.net
+
+     You can even do SSL/TLS over SSL/TLS over SSL/TLS ... by using
+     'T' multiple times.  I have no idea why you would want to though.
+
+
+This code is rather old.  When I find time I will update anything that
+should be changed, and improve code comments.  To compile the sample
+program 'test' on platforms other then Linux or Solaris, you will have
+to edit the Makefile.
+
+As noted above, easy_tls.c will be changed to become a library one
+day, which means that future revisions will not be fully compatible to
+the current version.
+
+Bodo Möller <bodo@openssl.org>
diff --git a/openssl/demos/easy_tls/cacerts.pem b/openssl/demos/easy_tls/cacerts.pem
new file mode 100644
index 0000000..acc70ba
--- /dev/null
+++ b/openssl/demos/easy_tls/cacerts.pem
@@ -0,0 +1,18 @@
+$Id: cacerts.pem,v 1.1 2001/09/17 19:06:57 bodo Exp $
+
+issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test PCA (1024 bit)
+subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit)
+-----BEGIN CERTIFICATE-----
+MIICJjCCAY8CAQAwDQYJKoZIhvcNAQEEBQAwXDELMAkGA1UEBhMCQVUxEzARBgNV
+BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYD
+VQQDExNUZXN0IFBDQSAoMTAyNCBiaXQpMB4XDTk3MDYwOTEzNTc0M1oXDTAxMDYw
+OTEzNTc0M1owWzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxGjAY
+BgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYDVQQDExJUZXN0IENBICgxMDI0
+IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKO7o8t116VP6cgybTsZ
+DCZhr95nYlZuya3aCi1IKoztqwWnjbmDFIriOqGFPrZQ+moMETC9D59iRW/dFXSv
+1F65ka/XY2hLh9exCCo7XuUcDs53Qp3bI3AmMqHjgzE8oO3ajyJAzJkTTOUecQU2
+mw/gI4tMM0LqWMQS7luTy4+xAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAM7achv3v
+hLQJcv/65eGEpBXM40ZDVoFQFFJWaY5p883HTqLB1x4FdzsXHH0QKBTcKpWwqyu4
+YDm3fb8oDugw72bCzfyZK/zVZPR/hVlqI/fvU109Qoc+7oPvIXWky71HfcK6ZBCA
+q30KIqGM/uoM60INq97qjDmCJapagcNBGQs=
+-----END CERTIFICATE-----
diff --git a/openssl/demos/easy_tls/cert.pem b/openssl/demos/easy_tls/cert.pem
new file mode 100644
index 0000000..364fe10
--- /dev/null
+++ b/openssl/demos/easy_tls/cert.pem
@@ -0,0 +1,31 @@
+$Id: cert.pem,v 1.1 2001/09/17 19:06:57 bodo Exp $
+
+Example certificate and key.
+
+-----BEGIN CERTIFICATE-----
+MIIB1jCCAT8CAQEwDQYJKoZIhvcNAQEEBQAwRTELMAkGA1UEBhMCQVUxEzARBgNV
+BAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0
+ZDAeFw05OTA1MDEwMTI2MzVaFw05OTA1MzEwMTI2MzVaMCIxCzAJBgNVBAYTAkRF
+MRMwEQYDVQQDEwpUZXN0c2VydmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
+gQD6I3oDKiexwwlkzjar69AIFnVUaG85LtCege2R+CtIDlkQYw68/8MbT3ou0pdF
+AcL9IGiYY3Y0SHM9PqF00RO1MCtNpqTnF3ScLpbmggGjKilmWYn2ai7emdjMjXVL
+tzWW2xGgIGATWQN32KgfJng4jXi1UjEiyLhkw0Zf1I/ggwIDAQABMA0GCSqGSIb3
+DQEBBAUAA4GBAMgM+sbAk8DfjSfa+Rf2gcGXmbrvZAzKzC+5RU3kaq/NyxIXAGco
+9dZjozzWfN/xuGup5boFk+KrP+xdgsaqGHsyzlgEoqz4ekqLjQeVbnoj339hVFU9
+MhPi6JULPxjXKumjfX2LLNkikW5puz8Df3UiX0EiaJvd7EwP8J75tiUT
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQD6I3oDKiexwwlkzjar69AIFnVUaG85LtCege2R+CtIDlkQYw68
+/8MbT3ou0pdFAcL9IGiYY3Y0SHM9PqF00RO1MCtNpqTnF3ScLpbmggGjKilmWYn2
+ai7emdjMjXVLtzWW2xGgIGATWQN32KgfJng4jXi1UjEiyLhkw0Zf1I/ggwIDAQAB
+AoGANST8c1etf1MU19oIO5aqaE19OCXIG7oakNLCCtVTPMfvnE+vffBJH7BPIUuU
+4BBzwRv1nQrkvk72TPjVjOAu81B1SStKQueun2flVuYxp9NyupNWCBley4QdohlP
+I92ml2tzTSPmNIoA6jdGyNzFcGchapRRmejsC39F1RUbHQECQQD9KX81Wt8ZOrri
+dWiEXja1L3X8Bkb9vvUjVMQDTJJPxBJjehC6eurgE6PP6SJD5p/f3RHPCcLr8tSM
+D4P/OpKhAkEA/PFNlhIZUDKK6aTvG2mn7qQ5phbadOoyN1Js3ttWG5OMOZ6b/QlC
+Wvp84h44506BIlv+Tg2YAI0AdBUrf7oEowJAM4joAVd/ROaEtqbJ4PBA2L9RmD06
+5FqkEk4mHLnQqvYx/BgUIbH18ClvVlqSBBqFfw/EmU3WZSuogt6Bs0ocIQJBAOxB
+AoPiYcxbeQ5kZIVJOXaX49SzUdaUDNVJYrEBUzsspHQJJo/Avz606kJVkjbSR6Ft
+JWmIHuqcyMikIV4KxFsCQQCU2evoVjVsqkkbHi7W28f73PGBsyu0KIwlK7nu4h08
+Daf7TAI+A6jW/WRUsJ6dFhUYi7/Jvkcdrlnbgm2fxziX
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/demos/easy_tls/easy-tls.c b/openssl/demos/easy_tls/easy-tls.c
new file mode 100644
index 0000000..9cd8314
--- /dev/null
+++ b/openssl/demos/easy_tls/easy-tls.c
@@ -0,0 +1,1240 @@
+/* -*- Mode: C; c-file-style: "bsd" -*- */
+/*
+ * easy-tls.c -- generic TLS proxy.
+ * $Id: easy-tls.c,v 1.4 2002/03/05 09:07:16 bodo Exp $
+ */
+/*
+ (c) Copyright 1999 Bodo Moeller.  All rights reserved.
+
+ This is free software; you can redistributed and/or modify it
+ unter the terms of either
+   -  the GNU General Public License as published by the
+      Free Software Foundation, version 1, or (at your option)
+      any later version,
+ or
+   -  the following license:
+*/
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that each of the following
+ * conditions is met:
+ *
+ * 1. Redistributions qualify as "freeware" or "Open Source Software" under
+ *    one of the following terms:
+ * 
+ *    (a) Redistributions are made at no charge beyond the reasonable cost of
+ *        materials and delivery.
+ * 
+ *    (b) Redistributions are accompanied by a copy of the Source Code
+ *        or by an irrevocable offer to provide a copy of the Source Code
+ *        for up to three years at the cost of materials and delivery.
+ *        Such redistributions must allow further use, modification, and
+ *        redistribution of the Source Code under substantially the same
+ *        terms as this license.
+ *
+ * 2. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 3. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 4. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by Bodo Moeller."
+ *    (If available, substitute umlauted o for oe.)
+ *
+ * 5. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Bodo Moeller."
+ *
+ * THIS SOFTWARE IS PROVIDED BY BODO MOELLER ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL BODO MOELLER OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Attribution for OpenSSL library:
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ * This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)
+ */
+
+static char const rcsid[] =
+"$Id: easy-tls.c,v 1.4 2002/03/05 09:07:16 bodo Exp $";
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+
+#include <openssl/crypto.h>
+#include <openssl/dh.h>
+#include <openssl/dsa.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/opensslv.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#ifndef NO_RSA
+ #include <openssl/rsa.h>
+#endif
+#include <openssl/ssl.h>
+#include <openssl/x509.h>
+#include <openssl/x509_vfy.h>
+
+#if OPENSSL_VERSION_NUMBER < 0x00904000L /* 0.9.4-dev */
+# error "This program needs OpenSSL 0.9.4 or later."
+#endif
+
+#include "easy-tls.h" /* include after <openssl/ssl.h> if both are needed */
+
+#if TLS_INFO_SIZE > PIPE_BUF
+# if PIPE_BUF < 512
+#  error "PIPE_BUF < 512" /* non-POSIX */
+# endif
+# error "TLS_INFO_SIZE > PIPE_BUF"
+#endif
+
+/*****************************************************************************/
+
+#ifdef TLS_APP
+# include TLS_APP
+#endif
+
+/* Applications can define:
+ *   TLS_APP_PROCESS_INIT -- void ...(int fd, int client_p, void *apparg)
+ *   TLS_CUMULATE_ERRORS 
+ *   TLS_ERROR_BUFSIZ
+ *   TLS_APP_ERRFLUSH -- void ...(int child_p, char *, size_t, void *apparg)
+ */
+
+#ifndef TLS_APP_PROCESS_INIT
+# define TLS_APP_PROCESS_INIT(fd, client_p, apparg) ((void) 0)
+#endif
+
+#ifndef TLS_ERROR_BUFSIZ
+# define TLS_ERROR_BUFSIZ (10*160)
+#endif
+#if TLS_ERROR_BUFSIZ < 2 /* {'\n',0} */
+# error "TLS_ERROR_BUFSIZE is too small."
+#endif
+
+#ifndef TLS_APP_ERRFLUSH
+# define TLS_APP_ERRFLUSH tls_app_errflush
+static void
+tls_app_errflush(int child_p, char *errbuf, size_t num, void *apparg)
+{
+    fputs(errbuf, stderr);
+}
+#endif
+
+/*****************************************************************************/
+
+#ifdef DEBUG_TLS
+# define DEBUG_MSG(x) fprintf(stderr,"  %s\n",x)
+# define DEBUG_MSG2(x,y) fprintf(stderr, "  %s: %d\n",x,y)
+static int tls_loop_count = 0;
+static int tls_select_count = 0;
+#else
+# define DEBUG_MSG(x) (void)0
+# define DEBUG_MSG2(x,y) (void)0
+#endif
+
+static void tls_rand_seed_uniquely(void);
+static void tls_proxy(int clear_fd, int tls_fd, int info_fd, SSL_CTX *ctx, int client_p);
+static int tls_socket_nonblocking(int fd);
+
+static int tls_child_p = 0;
+static void *tls_child_apparg;
+
+
+struct tls_start_proxy_args
+tls_start_proxy_defaultargs(void)
+{
+    struct tls_start_proxy_args ret;
+
+    ret.fd = -1;
+    ret.client_p = -1;
+    ret.ctx = NULL;
+    ret.pid = NULL;
+    ret.infofd = NULL;
+    
+    return ret;
+}
+
+/* Slice in TLS proxy process at fd.
+ * Return value:
+ *   0    ok  (*pid is set to child's PID if pid != NULL),
+ *   < 0  look at errno
+ *   > 0  other error
+ *   (return value encodes place of error)
+ *
+ */
+int
+tls_start_proxy(struct tls_start_proxy_args a, void *apparg)
+{
+    int fds[2] = {-1, -1};
+    int infofds[2] = {-1, -1};
+    int r, getfd, getfl;
+    int ret;
+
+    DEBUG_MSG2("tls_start_proxy fd", a.fd);
+    DEBUG_MSG2("tls_start_proxy client_p", a.client_p);
+
+    if (a.fd == -1 || a.client_p == -1 || a.ctx == NULL)
+	return 1;
+
+    if (a.pid != NULL) {
+	*a.pid = 0;
+    }
+    if (a.infofd != NULL) {
+	*a.infofd = -1;
+    }
+
+    r = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
+    if (r == -1)
+	return -1;
+    if (a.fd >= FD_SETSIZE || fds[0] >= FD_SETSIZE) {
+	ret = 2;
+	goto err;
+    }
+    if (a.infofd != NULL) {
+	r = pipe(infofds);
+	if (r == -1) {
+	    ret = -3;
+	    goto err;
+	}
+    }
+
+    r = fork();
+    if (r == -1) {
+	ret = -4;
+	goto err;
+    }
+    if (r == 0) {
+	DEBUG_MSG("fork");
+	tls_child_p = 1;
+	tls_child_apparg = apparg;
+	close(fds[1]);
+	if (infofds[0] != -1)
+	    close(infofds[0]);
+	TLS_APP_PROCESS_INIT(a.fd, a.client_p, apparg);
+	DEBUG_MSG("TLS_APP_PROCESS_INIT");
+	tls_proxy(fds[0], a.fd, infofds[1], a.ctx, a.client_p);
+	exit(0);
+    }
+    if (a.pid != NULL)
+	*a.pid = r;
+    if (infofds[1] != -1) {
+	close(infofds[1]);
+	infofds[1] = -1;
+    }
+    /* install fds[1] in place of fd: */
+    close(fds[0]);
+    fds[0] = -1;
+    getfd = fcntl(a.fd, F_GETFD);
+    getfl = fcntl(a.fd, F_GETFL);
+    r = dup2(fds[1], a.fd);
+    close(fds[1]);
+    fds[1] = -1;
+    if (r == -1) {
+	ret = -5;
+	goto err;
+    }
+    if (getfd != 1)
+	fcntl(a.fd, F_SETFD, getfd);
+    if (getfl & O_NONBLOCK)
+	(void)tls_socket_nonblocking(a.fd);
+    if (a.infofd != NULL)
+	*a.infofd = infofds[0];
+    return 0;
+    
+  err:
+    if (fds[0] != -1)
+	close(fds[0]);
+    if (fds[1] != -1)
+	close(fds[1]);
+    if (infofds[0] != -1)
+	close(infofds[0]);
+    if (infofds[1] != -1)
+	close(infofds[1]);
+    return ret;
+}
+
+/*****************************************************************************/
+
+static char errbuf[TLS_ERROR_BUFSIZ];
+static size_t errbuf_i = 0;
+
+static void
+tls_errflush(void *apparg)
+{
+    if (errbuf_i == 0)
+	return;
+    
+    assert(errbuf_i < sizeof errbuf);
+    assert(errbuf[errbuf_i] == 0);
+    if (errbuf_i == sizeof errbuf - 1) {
+	/* make sure we have a newline, even if string has been truncated */
+	errbuf[errbuf_i - 1] = '\n';
+    }
+
+    /* TLS_APP_ERRFLUSH may modify the string as needed,
+     * e.g. substitute other characters for \n for convenience */
+    TLS_APP_ERRFLUSH(tls_child_p, errbuf, errbuf_i, apparg);
+
+    errbuf_i = 0;
+}
+
+static void
+tls_errprintf(int flush, void *apparg, const char *fmt, ...)
+{
+    va_list args;
+    int r;
+    
+    if (errbuf_i < sizeof errbuf - 1) {
+	size_t n;
+
+	va_start(args, fmt);
+	n = (sizeof errbuf) - errbuf_i;
+	r = vsnprintf(errbuf + errbuf_i, n, fmt, args);
+	if (r >= n)
+	    r = n - 1;
+	if (r >= 0) {
+	    errbuf_i += r;
+	} else {
+	    errbuf_i = sizeof errbuf - 1;
+	    errbuf[errbuf_i] = '\0';
+	}
+	assert(errbuf_i < sizeof errbuf);
+	assert(errbuf[errbuf_i] == 0);
+    }
+#ifndef TLS_CUMULATE_ERRORS
+    tls_errflush(apparg);
+#else
+    if (flush)
+	tls_errflush(apparg);
+#endif
+}
+
+/* app_prefix.. are for additional information provided by caller.
+ * If OpenSSL error queue is empty, print default_text ("???" if NULL).
+ */
+static char *
+tls_openssl_errors(const char *app_prefix_1, const char *app_prefix_2, const char *default_text, void *apparg)
+{
+    static char reasons[255];
+    size_t reasons_i;
+    unsigned long err;
+    const char *file;
+    int line;
+    const char *data;
+    int flags;
+    char *errstring;
+    int printed_something = 0;
+    
+    reasons_i = 0;
+
+    assert(app_prefix_1 != NULL);
+    assert(app_prefix_2 != NULL);
+
+    if (default_text == NULL)
+	default_text = "?""?""?";
+    
+    while ((err = ERR_get_error_line_data(&file,&line,&data,&flags)) != 0) {
+	if (reasons_i < sizeof reasons) {
+	    size_t n;
+	    int r;
+
+	    n = (sizeof reasons) - reasons_i;
+	    r = snprintf(reasons + reasons_i, n, "%s%s", (reasons_i > 0 ? ", " : ""), ERR_reason_error_string(err));
+	    if (r >= n)
+		r = n - 1;
+	    if (r >= 0) {
+		reasons_i += r;
+	    } else {
+		reasons_i = sizeof reasons;
+	    }
+	    assert(reasons_i <= sizeof reasons);
+	}
+	
+	errstring = ERR_error_string(err, NULL);
+	assert(errstring != NULL);
+	tls_errprintf(0, apparg, "OpenSSL error%s%s: %s:%s:%d:%s\n", app_prefix_1, app_prefix_2, errstring, file, line, (flags & ERR_TXT_STRING) ? data : "");
+	printed_something = 1;
+    }
+
+    if (!printed_something) {
+	assert(reasons_i == 0);
+	snprintf(reasons, sizeof reasons, "%s", default_text);
+	tls_errprintf(0, apparg, "OpenSSL error%s%s: %s\n", app_prefix_1, app_prefix_2, default_text);
+    }
+
+#ifdef TLS_CUMULATE_ERRORS    
+    tls_errflush(apparg);
+#endif
+    assert(errbuf_i == 0);
+
+    return reasons;
+}
+
+/*****************************************************************************/
+
+static int tls_init_done = 0;
+
+static int
+tls_init(void *apparg)
+{
+    if (tls_init_done)
+	return 0;
+    
+    SSL_load_error_strings();
+    if (!SSL_library_init() /* aka SSLeay_add_ssl_algorithms() */ ) {
+	tls_errprintf(1, apparg, "SSL_library_init failed.\n");
+	return -1;
+    }
+    tls_init_done = 1;
+    tls_rand_seed();
+    return 0;
+}
+
+/*****************************************************************************/
+
+static void
+tls_rand_seed_uniquely(void)
+{
+    struct {
+	pid_t pid;
+	time_t time;
+	void *stack;
+    } data;
+
+    data.pid = getpid();
+    data.time = time(NULL);
+    data.stack = (void *)&data;
+
+    RAND_seed((const void *)&data, sizeof data);
+}
+
+void
+tls_rand_seed(void)
+{
+    struct {
+	struct utsname uname;
+	int uname_1;
+	int uname_2;
+	uid_t uid;
+	uid_t euid;
+	gid_t gid;
+	gid_t egid;
+    } data;
+    
+    data.uname_1 = uname(&data.uname);
+    data.uname_2 = errno; /* Let's hope that uname fails randomly :-) */
+
+    data.uid = getuid();
+    data.euid = geteuid();
+    data.gid = getgid();
+    data.egid = getegid();
+    
+    RAND_seed((const void *)&data, sizeof data);
+    tls_rand_seed_uniquely();
+}
+
+static int tls_rand_seeded_p = 0;
+
+#define my_MIN_SEED_BYTES 256 /* struct stat can be larger than 128 */
+int
+tls_rand_seed_from_file(const char *filename, size_t n, void *apparg)
+{
+    /* Seed OpenSSL's random number generator from file.
+       Try to read n bytes if n > 0, whole file if n == 0. */
+
+    int r;
+
+    if (tls_init(apparg) == -1)
+	return -1;
+    tls_rand_seed();
+
+    r = RAND_load_file(filename, (n > 0 && n < LONG_MAX) ? (long)n : LONG_MAX);
+    /* r is the number of bytes filled into the random number generator,
+     * which are taken from "stat(filename, ...)" in addition to the
+     * file contents.
+     */
+    assert(1 < my_MIN_SEED_BYTES);
+    /* We need to detect at least those cases when the file does not exist
+     * at all.  With current versions of OpenSSL, this should do it: */
+    if (n == 0)
+	n = my_MIN_SEED_BYTES;
+    if (r < n) {
+	tls_errprintf(1, apparg, "rand_seed_from_file: could not read %d bytes from %s.\n", n, filename);
+	return -1;
+    } else {
+	tls_rand_seeded_p = 1;
+	return 0;
+    }
+}
+
+void
+tls_rand_seed_from_memory(const void *buf, size_t n)
+{
+    size_t i = 0;
+    
+    while (i < n) {
+	size_t rest = n - i;
+	int chunk = rest < INT_MAX ? (int)rest : INT_MAX;
+	RAND_seed((const char *)buf + i, chunk);
+	i += chunk;
+    }
+    tls_rand_seeded_p = 1;
+}
+
+
+/*****************************************************************************/
+
+struct tls_x509_name_string {
+    char str[100];
+};
+
+static void
+tls_get_x509_subject_name_oneline(X509 *cert, struct tls_x509_name_string *namestring)
+{
+    X509_NAME *name;
+
+    if (cert == NULL) {
+	namestring->str[0] = '\0';
+	return;
+    }
+    
+    name = X509_get_subject_name(cert); /* does not increment any reference counter */
+
+    assert(sizeof namestring->str >= 4); /* "?" or "...", plus 0 */
+    
+    if (name == NULL) {
+	namestring->str[0] = '?';
+	namestring->str[1] = 0;
+    } else {
+	size_t len;
+
+	X509_NAME_oneline(name, namestring->str, sizeof namestring->str);
+	len = strlen(namestring->str);
+	assert(namestring->str[len] == 0);
+	assert(len < sizeof namestring->str);
+
+	if (len+1 == sizeof namestring->str) {
+	    /* (Probably something was cut off.)
+	     * Does not really work -- X509_NAME_oneline truncates after
+	     * name components, we cannot tell from the result whether
+	     * anything is missing. */
+
+	    assert(namestring->str[len] == 0);
+	    namestring->str[--len] = '.';
+	    namestring->str[--len] = '.';
+	    namestring->str[--len] = '.';
+	}
+    }
+}
+
+/*****************************************************************************/
+
+/* to hinder OpenSSL from asking for passphrases */
+static int
+no_passphrase_callback(char *buf, int num, int w, void *arg)
+{
+    return -1;
+}
+
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L
+static int
+verify_dont_fail_cb(X509_STORE_CTX *c, void *unused_arg)
+#else
+static int
+verify_dont_fail_cb(X509_STORE_CTX *c)
+#endif
+{
+    int i;
+    
+    i = X509_verify_cert(c); /* sets c->error */
+#if OPENSSL_VERSION_NUMBER >= 0x00905000L /* don't allow unverified
+					   * certificates -- they could
+					   * survive session reuse, but
+					   * OpenSSL < 0.9.5-dev does not
+					   * preserve their verify_result */
+    if (i == 0)
+	return 1;
+    else
+#endif
+	return i;
+}
+
+static DH *tls_dhe1024 = NULL; /* generating these takes a while, so do it just once */
+
+void
+tls_set_dhe1024(int i, void *apparg)
+{
+    DSA *dsaparams;
+    DH *dhparams;
+    const char *seed[] = { ";-)  :-(  :-)  :-(  ",
+			   ";-)  :-(  :-)  :-(  ",
+			   "Random String no. 12",
+			   ";-)  :-(  :-)  :-(  ",
+			   "hackers have even mo", /* from jargon file */
+    };
+    unsigned char seedbuf[20];
+    
+    tls_init(apparg);
+    if (i >= 0) {
+	i %= sizeof seed / sizeof seed[0];
+	assert(strlen(seed[i]) == 20);
+	memcpy(seedbuf, seed[i], 20);
+	dsaparams = DSA_generate_parameters(1024, seedbuf, 20, NULL, NULL, 0, NULL);
+    } else {
+	/* random parameters (may take a while) */
+	dsaparams = DSA_generate_parameters(1024, NULL, 0, NULL, NULL, 0, NULL);
+    }
+    
+    if (dsaparams == NULL) {
+	tls_openssl_errors("", "", NULL, apparg);
+	return;
+    }
+    dhparams = DSA_dup_DH(dsaparams);
+    DSA_free(dsaparams);
+    if (dhparams == NULL) {
+	tls_openssl_errors("", "", NULL, apparg);
+	return;
+    }
+    if (tls_dhe1024 != NULL)
+	DH_free(tls_dhe1024);
+    tls_dhe1024 = dhparams;
+}
+
+struct tls_create_ctx_args
+tls_create_ctx_defaultargs(void)
+{
+	struct tls_create_ctx_args ret;
+
+	ret.client_p = 0;
+	ret.certificate_file = NULL;
+	ret.key_file = NULL;
+	ret.ca_file = NULL;
+	ret.verify_depth = -1;
+	ret.fail_unless_verified = 0;
+	ret.export_p = 0;
+
+	return ret;
+}
+
+SSL_CTX *
+tls_create_ctx(struct tls_create_ctx_args a, void *apparg)
+{
+    int r;
+    static long context_num = 0;
+    SSL_CTX *ret;
+    const char *err_pref_1 = "", *err_pref_2 = "";
+    
+    if (tls_init(apparg) == -1)
+	return NULL;
+
+    ret = SSL_CTX_new((a.client_p? SSLv23_client_method:SSLv23_server_method)());
+
+    if (ret == NULL)
+	goto err;
+
+    SSL_CTX_set_default_passwd_cb(ret, no_passphrase_callback);
+    SSL_CTX_set_mode(ret, SSL_MODE_ENABLE_PARTIAL_WRITE);
+    
+    if ((a.certificate_file != NULL) || (a.key_file != NULL)) {
+	if (a.key_file == NULL) {
+	    tls_errprintf(1, apparg, "Need a key file.\n");
+	    goto err_return;
+	}
+	if (a.certificate_file == NULL) {
+	    tls_errprintf(1, apparg, "Need a certificate chain file.\n");
+	    goto err_return;
+	}
+	
+	if (!SSL_CTX_use_PrivateKey_file(ret, a.key_file, SSL_FILETYPE_PEM))
+	    goto err;
+	if (!tls_rand_seeded_p) {
+	    /* particularly paranoid people may not like this --
+	     * so provide your own random seeding before calling this */
+	    if (tls_rand_seed_from_file(a.key_file, 0, apparg) == -1)
+		goto err_return;
+	}
+	if (!SSL_CTX_use_certificate_chain_file(ret, a.certificate_file))
+	    goto err;
+	if (!SSL_CTX_check_private_key(ret)) {
+	    tls_errprintf(1, apparg, "Private key \"%s\" does not match certificate \"%s\".\n", a.key_file, a.certificate_file);
+	    goto err_peek;
+	}
+    }
+    
+    if ((a.ca_file != NULL) || (a.verify_depth > 0)) {
+	context_num++;
+	r = SSL_CTX_set_session_id_context(ret, (const void *)&context_num, (unsigned int)sizeof context_num);
+	if (!r)
+	    goto err;
+	
+	SSL_CTX_set_verify(ret, SSL_VERIFY_PEER | (a.fail_unless_verified ? SSL_VERIFY_FAIL_IF_NO_PEER_CERT : 0), 0);
+	if (!a.fail_unless_verified)
+	    SSL_CTX_set_cert_verify_callback(ret, verify_dont_fail_cb, NULL);
+	    
+	if (a.verify_depth > 0)
+	    SSL_CTX_set_verify_depth(ret, a.verify_depth);
+	
+	if (a.ca_file != NULL) {
+	    r = SSL_CTX_load_verify_locations(ret, a.ca_file, NULL /* no CA-directory */); /* does not report failure if file does not exist ... */
+	    if (!r) {
+		err_pref_1 = " while processing certificate file ";
+		err_pref_2 = a.ca_file;
+		goto err;
+	    }
+	    
+	    if (!a.client_p) {
+		/* SSL_load_client_CA_file is a misnomer, it just creates a list of CNs. */
+		SSL_CTX_set_client_CA_list(ret, SSL_load_client_CA_file(a.ca_file));
+		/* SSL_CTX_set_client_CA_list does not have a return value;
+		 * it does not really need one, but make sure
+		 * (we really test if SSL_load_client_CA_file worked) */
+		if (SSL_CTX_get_client_CA_list(ret) == NULL) {
+		    tls_errprintf(1, apparg, "Could not set client CA list from \"%s\".\n", a.ca_file);
+		    goto err_peek;
+		}
+	    }
+	}
+    }
+    
+    if (!a.client_p) {
+	if (tls_dhe1024 == NULL) {
+	    int i;
+
+	    RAND_bytes((unsigned char *) &i, sizeof i);
+	    /* make sure that i is non-negative -- pick one of the provided
+	     * seeds */
+	    if (i < 0)
+		i = -i;
+	    if (i < 0)
+		i = 0;
+	    tls_set_dhe1024(i, apparg);
+	    if (tls_dhe1024 == NULL)
+		goto err_return;
+	}
+	
+	if (!SSL_CTX_set_tmp_dh(ret, tls_dhe1024))
+	    goto err;
+
+	/* avoid small subgroup attacks: */
+	SSL_CTX_set_options(ret, SSL_OP_SINGLE_DH_USE);
+    }
+	
+#ifndef NO_RSA
+    if (!a.client_p && a.export_p) {
+	RSA *tmpkey;
+
+	tmpkey = RSA_generate_key(512, RSA_F4, 0, NULL);
+	if (tmpkey == NULL)
+	    goto err;
+	if (!SSL_CTX_set_tmp_rsa(ret, tmpkey)) {
+	    RSA_free(tmpkey);
+	    goto err;
+	}
+	RSA_free(tmpkey); /* SSL_CTX_set_tmp_rsa uses a duplicate. */
+    }
+#endif
+	
+    return ret;
+    
+ err_peek:
+    if (!ERR_peek_error())
+	goto err_return;
+ err:
+    tls_openssl_errors(err_pref_1, err_pref_2, NULL, apparg);
+ err_return:
+    if (ret != NULL)
+	SSL_CTX_free(ret);
+    return NULL;
+}
+
+
+/*****************************************************************************/
+
+static int
+tls_socket_nonblocking(int fd)
+{
+    int v, r;
+
+    v = fcntl(fd, F_GETFL, 0);
+    if (v == -1) {
+	if (errno == EINVAL)
+	    return 0; /* already shut down -- ignore */
+	return -1;
+    }
+    r = fcntl(fd, F_SETFL, v | O_NONBLOCK);
+    if (r == -1) {
+	if (errno == EINVAL)
+	    return 0; /* already shut down -- ignore */
+	return -1;
+    }
+    return 0;
+}
+
+static int
+max(int a, int b)
+{
+    return a > b ? a : b;
+}
+
+static void
+tls_sockets_select(int read_select_1, int read_select_2, int write_select_1, int write_select_2, int seconds /* timeout, -1 means no timeout */)
+{
+    int maxfd, n;
+    fd_set reads, writes;
+    struct timeval timeout;
+    struct timeval *timeout_p;
+    
+    assert(read_select_1 >= -1 && read_select_2 >= -1 && write_select_1 >= -1 && write_select_2 >= -1);
+    assert(read_select_1 < FD_SETSIZE && read_select_2 < FD_SETSIZE -1 && write_select_1 < FD_SETSIZE -1 && write_select_2 < FD_SETSIZE -1);
+
+    maxfd = max(max(read_select_1, read_select_2), max(write_select_1, write_select_2));
+    assert(maxfd >= 0);
+
+    FD_ZERO(&reads);
+    FD_ZERO(&writes);
+    
+    for(n = 0; n < 4; ++n) {
+	int i = n % 2;
+	int w = n >= 2;
+	/* loop over all (i, w) in {0,1}x{0,1} */
+	int fd;
+	
+	if (i == 0 && w == 0)
+	    fd = read_select_1;
+	else if (i == 1 && w == 0)
+	    fd = read_select_2;
+	else if (i == 0 && w == 1)
+	    fd = write_select_1;
+	else {
+	    assert(i == 1 && w == 1);
+	    fd = write_select_2;
+	}
+	
+	if (fd >= 0) {
+	    if (w == 0)
+		FD_SET(fd, &reads);
+	    else /* w == 1 */
+		FD_SET(fd, &writes);
+	}
+    }
+
+    if (seconds >= 0) {
+	timeout.tv_sec = seconds;
+	timeout.tv_usec = 0;
+	timeout_p = &timeout;
+    } else 
+	timeout_p = NULL;
+
+    DEBUG_MSG2("select no.", ++tls_select_count);
+    select(maxfd + 1, &reads, &writes, (fd_set *) NULL, timeout_p);
+    DEBUG_MSG("cont.");
+}
+
+/*****************************************************************************/
+
+#define TUNNELBUFSIZE (16*1024)
+struct tunnelbuf {
+    char buf[TUNNELBUFSIZE];
+    size_t len;
+    size_t offset;
+};
+
+static int tls_connect_attempt(SSL *, int *write_select, int *read_select, int *closed, int *progress, const char **err_pref);
+
+static int tls_accept_attempt(SSL *, int *write_select, int *read_select, int *closed, int *progress, const char **err_pref);
+
+static int tls_write_attempt(SSL *, struct tunnelbuf *, int *write_select, int *read_select, int *closed, int *progress, const char **err_pref);
+
+static int tls_read_attempt(SSL *, struct tunnelbuf *, int *write_select, int *read_select, int *closed, int *progress, const char **err_pref);
+
+static int write_attempt(int fd, struct tunnelbuf *, int *select, int *closed, int *progress);
+
+static int read_attempt(int fd, struct tunnelbuf *, int *select, int *closed, int *progress);
+
+static void write_info(SSL *ssl, int *info_fd)
+{
+    if (*info_fd != -1) {
+	long v;
+	int v_ok;
+	struct tls_x509_name_string peer;
+	char infobuf[TLS_INFO_SIZE];
+	int r;
+
+	DEBUG_MSG("write_info");
+	v = SSL_get_verify_result(ssl);
+	v_ok = (v == X509_V_OK) ? 'A' : 'E'; /* Auth./Error */
+	{
+	    X509 *peercert;
+
+	    peercert = SSL_get_peer_certificate(ssl);
+	    tls_get_x509_subject_name_oneline(peercert, &peer);
+	    if (peercert != NULL)
+		X509_free(peercert);
+	}
+	if (peer.str[0] == '\0')
+	    v_ok = '0'; /* no cert at all */
+	else
+	    if (strchr(peer.str, '\n')) {
+		/* should not happen, but make sure */
+		*strchr(peer.str, '\n') = '\0';
+	    }
+	r = snprintf(infobuf, sizeof infobuf, "%c:%s\n%s\n", v_ok, X509_verify_cert_error_string(v), peer.str);
+	DEBUG_MSG2("snprintf", r);
+	if (r == -1 || r >= sizeof infobuf)
+	    r = sizeof infobuf - 1;
+	write(*info_fd, infobuf, r);
+	close (*info_fd);
+	*info_fd = -1;
+    }
+}
+
+
+/* tls_proxy expects that all fds are closed after return */
+static void
+tls_proxy(int clear_fd, int tls_fd, int info_fd, SSL_CTX *ctx, int client_p)
+{
+    struct tunnelbuf clear_to_tls, tls_to_clear;
+    SSL *ssl;
+    BIO *rbio, *wbio;
+    int closed, in_handshake;
+    const char *err_pref_1 = "", *err_pref_2 = "";
+    const char *err_def = NULL;
+
+    assert(clear_fd != -1);
+    assert(tls_fd != -1);
+    assert(clear_fd < FD_SETSIZE);
+    assert(tls_fd < FD_SETSIZE);
+    /* info_fd may be -1 */
+    assert(ctx != NULL);
+
+    tls_rand_seed_uniquely();
+
+    tls_socket_nonblocking(clear_fd);
+    DEBUG_MSG2("clear_fd", clear_fd);
+    tls_socket_nonblocking(tls_fd);
+    DEBUG_MSG2("tls_fd", tls_fd);
+
+    ssl = SSL_new(ctx);
+    if (ssl == NULL)
+	goto err;
+    DEBUG_MSG("SSL_new");
+    if (!SSL_set_fd(ssl, tls_fd))
+	goto err;
+    rbio = SSL_get_rbio(ssl);
+    wbio = SSL_get_wbio(ssl); /* should be the same, but who cares */
+    assert(rbio != NULL);
+    assert(wbio != NULL);
+    if (client_p)
+	SSL_set_connect_state(ssl);
+    else
+	SSL_set_accept_state(ssl);
+    
+    closed = 0;
+    in_handshake = 1;
+    tls_to_clear.len = 0;
+    tls_to_clear.offset = 0;
+    clear_to_tls.len = 0;
+    clear_to_tls.offset = 0;
+
+    err_def = "I/O error";
+    
+    /* loop finishes as soon as we detect that one side closed;
+     * when all (program and OS) buffers have enough space,
+     * the data from the last succesful read in each direction is transferred
+     * before close */
+    do {
+	int clear_read_select = 0, clear_write_select = 0,
+	    tls_read_select = 0, tls_write_select = 0,
+	    progress = 0;
+	int r;
+	unsigned long num_read = BIO_number_read(rbio),
+	    num_written = BIO_number_written(wbio);
+
+	DEBUG_MSG2("loop iteration", ++tls_loop_count);
+
+	if (in_handshake) {
+	    DEBUG_MSG("in_handshake");
+	    if (client_p)
+		r = tls_connect_attempt(ssl, &tls_write_select, &tls_read_select, &closed, &progress, &err_pref_1);
+	    else
+		r = tls_accept_attempt(ssl, &tls_write_select, &tls_read_select, &closed, &progress, &err_pref_1);
+	    if (r != 0) {
+		write_info(ssl, &info_fd);
+		goto err;
+	    }
+	    if (closed)
+		goto err_return;
+	    if (!SSL_in_init(ssl)) {
+		in_handshake = 0;
+		write_info(ssl, &info_fd);
+	    }
+	}
+	
+	if (clear_to_tls.len != 0 && !in_handshake) {
+	    assert(!closed);
+	    
+	    r = tls_write_attempt(ssl, &clear_to_tls, &tls_write_select, &tls_read_select, &closed, &progress, &err_pref_1);
+	    if (r != 0)
+		goto err;
+	    if (closed) {
+		assert(progress);
+		tls_to_clear.offset = 0;
+		tls_to_clear.len = 0;
+	    }
+	}
+	
+	if (tls_to_clear.len != 0) {
+	    assert(!closed);
+
+	    r = write_attempt(clear_fd, &tls_to_clear, &clear_write_select, &closed, &progress);
+	    if (r != 0)
+		goto err_return;
+	    if (closed) {
+		assert(progress);
+		clear_to_tls.offset = 0;
+		clear_to_tls.len = 0;
+	    }
+	}
+	
+	if (!closed) {
+	    if (clear_to_tls.offset + clear_to_tls.len < sizeof clear_to_tls.buf) {
+		r = read_attempt(clear_fd, &clear_to_tls, &clear_read_select, &closed, &progress);
+		if (r != 0)
+		    goto err_return;
+		if (closed) {
+		    r = SSL_shutdown(ssl);
+		    DEBUG_MSG2("SSL_shutdown", r);
+		}
+	    }
+	}
+	
+	if (!closed && !in_handshake) {
+	    if (tls_to_clear.offset + tls_to_clear.len < sizeof tls_to_clear.buf) {
+		r = tls_read_attempt(ssl, &tls_to_clear, &tls_write_select, &tls_read_select, &closed, &progress, &err_pref_1);
+		if (r != 0)
+		    goto err;
+		if (closed) {
+		    r = SSL_shutdown(ssl);
+		    DEBUG_MSG2("SSL_shutdown", r);
+		}
+	    }
+	}
+
+	if (!progress) {
+	    DEBUG_MSG("!progress?");
+	    if (num_read != BIO_number_read(rbio) || num_written != BIO_number_written(wbio))
+		progress = 1;
+
+	    if (!progress) {
+		DEBUG_MSG("!progress");
+		assert(clear_read_select || tls_read_select || clear_write_select || tls_write_select);
+		tls_sockets_select(clear_read_select ? clear_fd : -1, tls_read_select ? tls_fd : -1, clear_write_select ? clear_fd : -1, tls_write_select ? tls_fd : -1, -1);
+	    }
+	}
+    } while (!closed);
+    return;
+
+ err:
+    tls_openssl_errors(err_pref_1, err_pref_2, err_def, tls_child_apparg);
+ err_return:
+    return;
+}
+
+
+static int
+tls_get_error(SSL *ssl, int r, int *write_select, int *read_select, int *closed, int *progress)
+{
+    int err = SSL_get_error(ssl, r);
+
+    if (err == SSL_ERROR_NONE) {
+	assert(r > 0);
+	*progress = 1;
+	return 0;
+    }
+
+    assert(r <= 0);
+
+    switch (err) {
+    case SSL_ERROR_ZERO_RETURN:
+	assert(r == 0);
+	*closed = 1;
+	*progress = 1;
+	return 0;
+
+    case SSL_ERROR_WANT_WRITE:
+	*write_select = 1;
+	return 0;
+	
+    case SSL_ERROR_WANT_READ:
+	*read_select = 1;
+	return 0;
+    }
+
+    return -1;
+}
+
+static int
+tls_connect_attempt(SSL *ssl, int *write_select, int *read_select, int *closed, int *progress, const char **err_pref)
+{
+    int n, r;
+
+    DEBUG_MSG("tls_connect_attempt");
+    n = SSL_connect(ssl);
+    DEBUG_MSG2("SSL_connect",n);
+    r = tls_get_error(ssl, n, write_select, read_select, closed, progress);
+    if (r == -1)
+	*err_pref = " during SSL_connect";
+    return r;
+}
+
+static int
+tls_accept_attempt(SSL *ssl, int *write_select, int *read_select, int *closed, int *progress, const char **err_pref)
+{
+    int n, r;
+
+    DEBUG_MSG("tls_accept_attempt");
+    n = SSL_accept(ssl);
+    DEBUG_MSG2("SSL_accept",n);
+    r = tls_get_error(ssl, n, write_select, read_select, closed, progress);
+    if (r == -1)
+	*err_pref = " during SSL_accept";
+    return r;
+}
+
+static int
+tls_write_attempt(SSL *ssl, struct tunnelbuf *buf, int *write_select, int *read_select, int *closed, int *progress, const char **err_pref)
+{
+    int n, r;
+
+    DEBUG_MSG("tls_write_attempt");
+    n = SSL_write(ssl, buf->buf + buf->offset, buf->len);
+    DEBUG_MSG2("SSL_write",n);
+    r = tls_get_error(ssl, n, write_select, read_select, closed, progress);
+    if (n > 0) {
+	buf->len -= n;
+	assert(buf->len >= 0);
+	if (buf->len == 0)
+	    buf->offset = 0;
+	else
+	    buf->offset += n;
+    }
+    if (r == -1)
+	*err_pref = " during SSL_write";
+    return r;
+}
+
+static int
+tls_read_attempt(SSL *ssl, struct tunnelbuf *buf, int *write_select, int *read_select, int *closed, int *progress, const char **err_pref)
+{
+    int n, r;
+    size_t total;
+
+    DEBUG_MSG("tls_read_attempt");
+    total = buf->offset + buf->len;
+    assert(total < sizeof buf->buf);
+    n = SSL_read(ssl, buf->buf + total, (sizeof buf->buf) - total);
+    DEBUG_MSG2("SSL_read",n);
+    r = tls_get_error(ssl, n, write_select, read_select, closed, progress);
+    if (n > 0) {
+	buf->len += n;
+	assert(buf->offset + buf->len <= sizeof buf->buf);
+    }
+    if (r == -1)
+	*err_pref = " during SSL_read";
+    return r;
+}
+
+static int
+get_error(int r, int *select, int *closed, int *progress)
+{
+    if (r >= 0) {
+	*progress = 1;
+	if (r == 0)
+	    *closed = 1;
+	return 0;
+    } else {
+	assert(r == -1);
+	if (errno == EAGAIN || errno == EWOULDBLOCK) {
+	    *select = 1;
+	    return 0;
+	} else if (errno == EPIPE) {
+	    *progress = 1;
+	    *closed = 1;
+	    return 0;
+	} else
+	    return -1;
+    }
+}
+
+static int write_attempt(int fd, struct tunnelbuf *buf, int *select, int *closed, int *progress)
+{
+    int n, r;
+
+    DEBUG_MSG("write_attempt");
+    n = write(fd, buf->buf + buf->offset, buf->len);
+    DEBUG_MSG2("write",n);
+    r = get_error(n, select, closed, progress);
+    if (n > 0) {
+	buf->len -= n;
+	assert(buf->len >= 0);
+	if (buf->len == 0)
+	    buf->offset = 0;
+	else
+	    buf->offset += n;
+    }
+    if (r == -1)
+	tls_errprintf(1, tls_child_apparg, "write error: %s\n", strerror(errno));
+    return r;
+}
+    
+static int
+read_attempt(int fd, struct tunnelbuf *buf, int *select, int *closed, int *progress)
+{
+    int n, r;
+    size_t total;
+
+    DEBUG_MSG("read_attempt");
+    total = buf->offset + buf->len;
+    assert(total < sizeof buf->buf);
+    n = read(fd, buf->buf + total, (sizeof buf->buf) - total);
+    DEBUG_MSG2("read",n);
+    r = get_error(n, select, closed, progress);
+    if (n > 0) {
+	buf->len += n;
+	assert(buf->offset + buf->len <= sizeof buf->buf);
+    }
+    if (r == -1)
+	tls_errprintf(1, tls_child_apparg, "read error: %s\n", strerror(errno));
+    return r;
+}
diff --git a/openssl/demos/easy_tls/easy-tls.h b/openssl/demos/easy_tls/easy-tls.h
new file mode 100644
index 0000000..52b298e
--- /dev/null
+++ b/openssl/demos/easy_tls/easy-tls.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; c-file-style: "bsd" -*- */
+/*
+ * easy-tls.h -- generic TLS proxy.
+ * $Id: easy-tls.h,v 1.1 2001/09/17 19:06:59 bodo Exp $
+ */
+/*
+ * (c) Copyright 1999 Bodo Moeller.  All rights reserved.
+ */
+
+#ifndef HEADER_TLS_H
+#define HEADER_TLS_H
+
+#ifndef HEADER_SSL_H
+typedef struct ssl_ctx_st SSL_CTX;
+#endif
+
+#define TLS_INFO_SIZE 512 /* max. # of bytes written to infofd */
+
+void tls_set_dhe1024(int i, void* apparg);
+/* Generate DHE parameters:
+ * i >= 0 deterministic (i selects seed), i < 0 random (may take a while).
+ * tls_create_ctx calls this with random non-negative i if the application
+ * has never called it.*/
+
+void tls_rand_seed(void);
+int tls_rand_seed_from_file(const char *filename, size_t n, void *apparg);
+void tls_rand_seed_from_memory(const void *buf, size_t n);
+
+struct tls_create_ctx_args 
+{
+    int client_p;
+    const char *certificate_file;
+    const char *key_file;
+    const char *ca_file;
+    int verify_depth;
+    int fail_unless_verified;
+    int export_p;
+};
+struct tls_create_ctx_args tls_create_ctx_defaultargs(void);
+/* struct tls_create_ctx_args is similar to a conventional argument list,
+ * but it can provide default values and allows for future extension. */
+SSL_CTX *tls_create_ctx(struct tls_create_ctx_args, void *apparg);
+
+struct tls_start_proxy_args
+{
+    int fd;
+    int client_p;
+    SSL_CTX *ctx;
+    pid_t *pid;
+    int *infofd;
+};
+struct tls_start_proxy_args tls_start_proxy_defaultargs(void);
+/* tls_start_proxy return value *MUST* be checked!
+ * 0 means ok, otherwise we've probably run out of some resources. */
+int tls_start_proxy(struct tls_start_proxy_args, void *apparg);
+
+#endif
diff --git a/openssl/demos/easy_tls/test.c b/openssl/demos/easy_tls/test.c
new file mode 100644
index 0000000..21f679a
--- /dev/null
+++ b/openssl/demos/easy_tls/test.c
@@ -0,0 +1,244 @@
+/* test.c */
+/* $Id: test.c,v 1.1 2001/09/17 19:06:59 bodo Exp $ */
+
+#define L_PORT 9999
+#define C_PORT 443
+
+#include <arpa/inet.h>
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include "test.h"
+#include "easy-tls.h"
+
+void
+test_process_init(int fd, int client_p, void *apparg)
+{
+    fprintf(stderr, "test_process_init(fd = %d, client_p = %d, apparg = %p)\n", fd, client_p, apparg);
+}
+
+void
+test_errflush(int child_p, char *errbuf, size_t num, void *apparg)
+{
+    fputs(errbuf, stderr);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+    int s, fd, r;
+    FILE *conn_in;
+    FILE *conn_out;
+    char buf[256];
+    SSL_CTX *ctx;
+    int client_p = 0;
+    int port;
+    int tls = 0;
+    char infobuf[TLS_INFO_SIZE + 1];
+
+    if (argc > 1 && argv[1][0] == '-') {
+	fputs("Usage: test [port]                   -- server\n"
+	      "       test num.num.num.num [port]   -- client\n",
+	      stderr);
+	exit(1);
+    }
+
+    if (argc > 1) {
+	if (strchr(argv[1], '.')) {
+	    client_p = 1;
+	}
+    }
+    
+    fputs(client_p ? "Client\n" : "Server\n", stderr);
+    
+    {
+	struct tls_create_ctx_args a = tls_create_ctx_defaultargs();
+	a.client_p = client_p;
+	a.certificate_file = "cert.pem";
+	a.key_file = "cert.pem";
+	a.ca_file = "cacerts.pem";
+	
+	ctx = tls_create_ctx(a, NULL);
+	if (ctx == NULL)
+	    exit(1);
+    }
+    
+    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (s == -1) {
+	perror("socket");
+	exit(1);
+    }
+    
+    if (client_p) {
+	struct sockaddr_in addr;
+	size_t addr_len = sizeof addr;
+	    
+	addr.sin_family = AF_INET;
+	assert(argc > 1);
+	if (argc > 2)
+	    sscanf(argv[2], "%d", &port);
+	else
+	    port = C_PORT;
+	addr.sin_port = htons(port);
+	addr.sin_addr.s_addr = inet_addr(argv[1]);
+	    
+	r = connect(s, &addr, addr_len);
+	if (r != 0) {
+	    perror("connect");
+	    exit(1);
+	}
+	fd = s;
+	fprintf(stderr, "Connect (fd = %d).\n", fd);
+    } else {
+	/* server */
+	{
+	    int i = 1;
+
+	    r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *) &i, sizeof i);
+	    if (r == -1) {
+		perror("setsockopt");
+		exit(1);
+	    }
+	}
+	
+	{
+	    struct sockaddr_in addr;
+	    size_t addr_len = sizeof addr;
+	    
+	    if (argc > 1)
+		sscanf(argv[1], "%d", &port);
+	    else
+		port = L_PORT;
+	    addr.sin_family = AF_INET;
+	    addr.sin_port = htons(port);
+	    addr.sin_addr.s_addr = INADDR_ANY;
+	    
+	    r = bind(s, &addr, addr_len);
+	    if (r != 0) {
+		perror("bind");
+		exit(1);
+	    }
+	}
+    
+	r = listen(s, 1);
+	if (r == -1) {
+	    perror("listen");
+	    exit(1);
+	}
+
+	fprintf(stderr, "Listening at port %i.\n", port);
+	
+	fd = accept(s, NULL, 0);
+	if (fd == -1) {
+	    perror("accept");
+	    exit(1);
+	}
+	
+	fprintf(stderr, "Accept (fd = %d).\n", fd);
+    }
+
+    conn_in = fdopen(fd, "r");
+    if (conn_in == NULL) {
+	perror("fdopen");
+	exit(1);
+    }
+    conn_out = fdopen(fd, "w");
+    if (conn_out == NULL) {
+	perror("fdopen");
+	exit(1);
+    }
+
+    setvbuf(conn_in, NULL, _IOLBF, 256);
+    setvbuf(conn_out, NULL, _IOLBF, 256);
+	
+    while (fgets(buf, sizeof buf, stdin) != NULL) {
+	if (buf[0] == 'W') {
+	    fprintf(conn_out, "%.*s\r\n", (int)(strlen(buf + 1) - 1), buf + 1);
+	    fprintf(stderr, ">>> %.*s\n", (int)(strlen(buf + 1) - 1), buf + 1);
+	} else if (buf[0] == 'C') {
+	    fprintf(stderr, "Closing.\n");
+	    fclose(conn_in);
+	    fclose(conn_out);
+	    exit(0);
+	} else if (buf[0] == 'R') {
+	    int lines = 0;
+
+	    sscanf(buf + 1, "%d", &lines);
+	    do {
+		if (fgets(buf, sizeof buf, conn_in) == NULL) {
+		    if (ferror(conn_in)) {
+			fprintf(stderr, "ERROR\n");
+			exit(1);
+		    }
+		    fprintf(stderr, "CLOSED\n");
+		    return 0;
+		}
+		fprintf(stderr, "<<< %s", buf);
+	    } while (--lines > 0);
+	} else if (buf[0] == 'T') {
+	    int infofd;
+
+	    tls++;
+	    {
+		struct tls_start_proxy_args a = tls_start_proxy_defaultargs();
+		a.fd = fd;
+		a.client_p = client_p;
+		a.ctx = ctx;
+		a.infofd = &infofd;
+		r = tls_start_proxy(a, NULL);
+	    }
+	    assert(r != 1);
+	    if (r != 0) {
+		fprintf(stderr, "tls_start_proxy failed: %d\n", r);
+		switch (r) {
+		case -1:
+		    fputs("socketpair", stderr); break;
+		case 2:
+		    fputs("FD_SETSIZE exceeded", stderr); break;
+		case -3:
+		    fputs("pipe", stderr); break;
+		case -4:
+		    fputs("fork", stderr); break;
+		case -5:
+		    fputs("dup2", stderr); break;
+		default:
+		    fputs("?", stderr);
+		}
+		if (r < 0)
+		    perror("");
+		else
+		    fputc('\n', stderr);
+		exit(1);
+	    }
+	    
+	    r = read(infofd, infobuf, sizeof infobuf - 1);
+	    if (r > 0) {
+		const char *info = infobuf;
+		const char *eol;
+		
+		infobuf[r] = '\0';
+		while ((eol = strchr(info, '\n')) != NULL) {
+		    fprintf(stderr, "+++ `%.*s'\n", eol - info, info);
+		    info = eol+1;
+		}
+		close (infofd);
+	    }
+	} else {
+	    fprintf(stderr, "W...  write line to network\n"
+		    "R[n]  read line (n lines) from network\n"
+		    "C     close\n"
+		    "T     start %sTLS proxy\n", tls ? "another " : "");
+	}
+    }
+    return 0;
+}
diff --git a/openssl/demos/easy_tls/test.h b/openssl/demos/easy_tls/test.h
new file mode 100644
index 0000000..dda6678
--- /dev/null
+++ b/openssl/demos/easy_tls/test.h
@@ -0,0 +1,11 @@
+/* test.h */
+/* $Id: test.h,v 1.1 2001/09/17 19:07:00 bodo Exp $ */
+
+
+void test_process_init(int fd, int client_p, void *apparg);
+#define TLS_APP_PROCESS_INIT test_process_init
+
+#undef TLS_CUMULATE_ERRORS
+
+void test_errflush(int child_p, char *errbuf, size_t num, void *apparg);
+#define TLS_APP_ERRFLUSH test_errflush
diff --git a/openssl/demos/eay/Makefile b/openssl/demos/eay/Makefile
new file mode 100644
index 0000000..2d22eac
--- /dev/null
+++ b/openssl/demos/eay/Makefile
@@ -0,0 +1,24 @@
+CC=cc
+CFLAGS= -g -I../../include
+#LIBS=  -L../.. -lcrypto -lssl
+LIBS= -L../.. ../../libssl.a ../../libcrypto.a
+
+# the file conn.c requires a file "proxy.h" which I couldn't find...
+#EXAMPLES=base64 conn loadrsa
+EXAMPLES=base64 loadrsa
+
+all: $(EXAMPLES) 
+
+base64: base64.o
+	$(CC) -o base64 base64.o $(LIBS)
+#
+# sorry... can't find "proxy.h"
+#conn: conn.o
+#	$(CC) -o conn conn.o $(LIBS)
+
+loadrsa: loadrsa.o
+	$(CC) -o loadrsa loadrsa.o $(LIBS)
+
+clean:	
+	rm -f $(EXAMPLES) *.o
+
diff --git a/openssl/demos/eay/base64.c b/openssl/demos/eay/base64.c
new file mode 100644
index 0000000..4b8b062
--- /dev/null
+++ b/openssl/demos/eay/base64.c
@@ -0,0 +1,49 @@
+/* This is a simple example of using the base64 BIO to a memory BIO and then
+ * getting the data.
+ */
+#include <stdio.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+
+main()
+	{
+	int i;
+	BIO *mbio,*b64bio,*bio;
+	char buf[512];
+	char *p;
+
+	mbio=BIO_new(BIO_s_mem());
+	b64bio=BIO_new(BIO_f_base64());
+
+	bio=BIO_push(b64bio,mbio);
+	/* We now have bio pointing at b64->mem, the base64 bio encodes on
+	 * write and decodes on read */
+
+	for (;;)
+		{
+		i=fread(buf,1,512,stdin);
+		if (i <= 0) break;
+		BIO_write(bio,buf,i);
+		}
+	/* We need to 'flush' things to push out the encoding of the
+	 * last few bytes.  There is special encoding if it is not a
+	 * multiple of 3
+	 */
+	BIO_flush(bio);
+
+	printf("We have %d bytes available\n",BIO_pending(mbio));
+
+	/* We will now get a pointer to the data and the number of elements. */
+	/* hmm... this one was not defined by a macro in bio.h, it will be for
+	 * 0.9.1.  The other option is too just read from the memory bio.
+	 */
+	i=(int)BIO_ctrl(mbio,BIO_CTRL_INFO,0,(char *)&p);
+
+	printf("%d\n",i);
+	fwrite("---\n",1,4,stdout);
+	fwrite(p,1,i,stdout);
+	fwrite("---\n",1,4,stdout);
+
+	/* This call will walk the chain freeing all the BIOs */
+	BIO_free_all(bio);
+	}
diff --git a/openssl/demos/eay/conn.c b/openssl/demos/eay/conn.c
new file mode 100644
index 0000000..c4b8f51
--- /dev/null
+++ b/openssl/demos/eay/conn.c
@@ -0,0 +1,105 @@
+/* NOCW */
+/* demos/eay/conn.c */
+
+/* A minimal program to connect to a port using the sock4a protocol.
+ *
+ * cc -I../../include conn.c -L../.. -lcrypto
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/err.h>
+#include <openssl/bio.h>
+/* #include "proxy.h" */
+
+extern int errno;
+
+int main(argc,argv)
+int argc;
+char *argv[];
+	{
+	PROXY *pxy;
+	char *host;
+	char buf[1024*10],*p;
+	BIO *bio;
+	int i,len,off,ret=1;
+
+	if (argc <= 1)
+		host="localhost:4433";
+	else
+		host=argv[1];
+
+	/* Lets get nice error messages */
+	ERR_load_crypto_strings();
+
+	/* First, configure proxy settings */
+	pxy=PROXY_new();
+	PROXY_add_server(pxy,PROXY_PROTOCOL_SOCKS,"gromit:1080");
+
+	bio=BIO_new(BIO_s_socks4a_connect());
+
+	BIO_set_conn_hostname(bio,host);
+	BIO_set_proxies(bio,pxy);
+	BIO_set_socks_userid(bio,"eay");
+	BIO_set_nbio(bio,1);
+
+	p="GET / HTTP/1.0\r\n\r\n";
+	len=strlen(p);
+
+	off=0;
+	for (;;)
+		{
+		i=BIO_write(bio,&(p[off]),len);
+		if (i <= 0)
+			{
+			if (BIO_should_retry(bio))
+				{
+				fprintf(stderr,"write DELAY\n");
+				sleep(1);
+				continue;
+				}
+			else
+				{
+				goto err;
+				}
+			}
+		off+=i;
+		len-=i;
+		if (len <= 0) break;
+		}
+
+	for (;;)
+		{
+		i=BIO_read(bio,buf,sizeof(buf));
+		if (i == 0) break;
+		if (i < 0)
+			{
+			if (BIO_should_retry(bio))
+				{
+				fprintf(stderr,"read DELAY\n");
+				sleep(1);
+				continue;
+				}
+			goto err;
+			}
+		fwrite(buf,1,i,stdout);
+		}
+
+	ret=1;
+
+	if (0)
+		{
+err:
+		if (ERR_peek_error() == 0) /* system call error */
+			{
+			fprintf(stderr,"errno=%d ",errno);
+			perror("error");
+			}
+		else
+			ERR_print_errors_fp(stderr);
+		}
+	BIO_free_all(bio);
+	if (pxy != NULL) PROXY_free(pxy);
+	exit(!ret);
+	return(ret);
+	}
+
diff --git a/openssl/demos/eay/loadrsa.c b/openssl/demos/eay/loadrsa.c
new file mode 100644
index 0000000..79f1885
--- /dev/null
+++ b/openssl/demos/eay/loadrsa.c
@@ -0,0 +1,53 @@
+#include <stdio.h>
+#include <openssl/rsa.h>
+
+/* This is a simple program to generate an RSA private key.  It then
+ * saves both the public and private key into a char array, then
+ * re-reads them.  It saves them as DER encoded binary data.
+ */
+
+void callback(stage,count,arg)
+int stage,count;
+char *arg;
+	{
+	FILE *out;
+
+	out=(FILE *)arg;
+	fprintf(out,"%d",stage);
+	if (stage == 3)
+		fprintf(out,"\n");
+	fflush(out);
+	}
+
+main()
+	{
+	RSA *rsa,*pub_rsa,*priv_rsa;
+	int len;
+	unsigned char buf[1024],*p;
+
+	rsa=RSA_generate_key(512,RSA_F4,callback,(char *)stdout);
+
+	p=buf;
+
+	/* Save the public key into buffer, we know it will be big enough
+	 * but we should really check how much space we need by calling the
+	 * i2d functions with a NULL second parameter */
+	len=i2d_RSAPublicKey(rsa,&p);
+	len+=i2d_RSAPrivateKey(rsa,&p);
+
+	printf("The public and private key are now both in a char array\n");
+	printf("and are taking up %d bytes\n",len);
+
+	RSA_free(rsa);
+
+	p=buf;
+	pub_rsa=d2i_RSAPublicKey(NULL,&p,(long)len);
+	len-=(p-buf);
+	priv_rsa=d2i_RSAPrivateKey(NULL,&p,(long)len);
+
+	if ((pub_rsa == NULL) || (priv_rsa == NULL))
+		ERR_print_errors_fp(stderr);
+
+	RSA_free(pub_rsa);
+	RSA_free(priv_rsa);
+	}
diff --git a/openssl/demos/engines/cluster_labs/Makefile b/openssl/demos/engines/cluster_labs/Makefile
new file mode 100644
index 0000000..956193f
--- /dev/null
+++ b/openssl/demos/engines/cluster_labs/Makefile
@@ -0,0 +1,114 @@
+LIBNAME=	libclabs
+SRC=		hw_cluster_labs.c
+OBJ=		hw_cluster_labs.o
+HEADER=		hw_cluster_labs.h
+
+CC=		gcc
+PIC=		-fPIC
+CFLAGS=		-g -I../../../include $(PIC) -DENGINE_DYNAMIC_SUPPORT -DFLAT_INC
+AR=		ar r
+RANLIB=		ranlib
+
+LIB=		$(LIBNAME).a
+SHLIB=		$(LIBNAME).so
+
+all:
+		@echo 'Please choose a system to build on:'
+		@echo ''
+		@echo 'tru64:    Tru64 Unix, Digital Unix, Digital OSF/1'
+		@echo 'solaris:  Solaris'
+		@echo 'irix:     IRIX'
+		@echo 'hpux32:   32-bit HP/UX'
+		@echo 'hpux64:   64-bit HP/UX'
+		@echo 'aix:      AIX'
+		@echo 'gnu:      Generic GNU-based system (gcc and GNU ld)'
+		@echo ''
+
+FORCE.update:
+update:		FORCE.update
+		perl ../../../util/mkerr.pl -conf hw_cluster_labs.ec \
+			-nostatic -staticloader -write hw_cluster_labs.c
+
+gnu:		$(SHLIB).gnu
+tru64:		$(SHLIB).tru64
+solaris:	$(SHLIB).solaris
+irix:		$(SHLIB).irix
+hpux32:		$(SHLIB).hpux32
+hpux64:		$(SHLIB).hpux64
+aix:		$(SHLIB).aix
+
+$(LIB):		$(OBJ)
+		$(AR) $(LIB) $(OBJ)
+		- $(RANLIB) $(LIB)
+
+LINK_SO=	\
+  ld -r -o $(LIBNAME).o $$ALLSYMSFLAGS $(LIB) && \
+  (nm -Pg $(LIBNAME).o | grep ' [BDT] ' | cut -f1 -d' ' > $(LIBNAME).exp; \
+   $$SHAREDCMD $$SHAREDFLAGS -o $(SHLIB) $(LIBNAME).o -L ../../.. -lcrypto -lc)
+
+$(SHLIB).gnu:	$(LIB)
+		ALLSYMSFLAGS='--whole-archive' \
+		SHAREDFLAGS='-shared -Wl,-soname=$(SHLIB)' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).gnu
+$(SHLIB).tru64:	$(LIB)
+		ALLSYMSFLAGS='-all' \
+		SHAREDFLAGS='-shared' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).tru64
+$(SHLIB).solaris:	$(LIB)
+		ALLSYMSFLAGS='-z allextract' \
+		SHAREDFLAGS='-G -h $(SHLIB)' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).solaris
+$(SHLIB).irix:	$(LIB)
+		ALLSYMSFLAGS='-all' \
+		SHAREDFLAGS='-shared -Wl,-soname,$(SHLIB)' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).irix
+$(SHLIB).hpux32:	$(LIB)
+		ALLSYMSFLAGS='-Fl' \
+		SHAREDFLAGS='+vnocompatwarnings -b -z +s +h $(SHLIB)' \
+		SHAREDCMD='/usr/ccs/bin/ld'; \
+		$(LINK_SO)
+		touch $(SHLIB).hpux32
+$(SHLIB).hpux64:	$(LIB)
+		ALLSYMSFLAGS='+forceload' \
+		SHAREDFLAGS='-b -z +h $(SHLIB)' \
+		SHAREDCMD='/usr/ccs/bin/ld'; \
+		$(LINK_SO)
+		touch $(SHLIB).hpux64
+$(SHLIB).aix:	$(LIB)
+		ALLSYMSFLAGS='-bnogc' \
+		SHAREDFLAGS='-G -bE:$(LIBNAME).exp -bM:SRE' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).aix
+
+depend:
+		sed -e '/^# DO NOT DELETE.*/,$$d' < Makefile > Makefile.tmp
+		echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' >> Makefile.tmp
+		gcc -M $(CFLAGS) $(SRC) >> Makefile.tmp
+		perl ../../../util/clean-depend.pl < Makefile.tmp > Makefile.new
+		rm -f Makefile.tmp Makefile
+		mv Makefile.new Makefile
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+rsaref.o: ../../../include/openssl/asn1.h ../../../include/openssl/bio.h
+rsaref.o: ../../../include/openssl/bn.h ../../../include/openssl/crypto.h
+rsaref.o: ../../../include/openssl/dh.h ../../../include/openssl/dsa.h
+rsaref.o: ../../../include/openssl/e_os2.h ../../../include/openssl/engine.h
+rsaref.o: ../../../include/openssl/err.h ../../../include/openssl/lhash.h
+rsaref.o: ../../../include/openssl/opensslconf.h
+rsaref.o: ../../../include/openssl/opensslv.h
+rsaref.o: ../../../include/openssl/ossl_typ.h ../../../include/openssl/rand.h
+rsaref.o: ../../../include/openssl/rsa.h ../../../include/openssl/safestack.h
+rsaref.o: ../../../include/openssl/stack.h ../../../include/openssl/symhacks.h
+rsaref.o: ../../../include/openssl/ui.h rsaref.c rsaref_err.c rsaref_err.h
+rsaref.o: source/des.h source/global.h source/md2.h source/md5.h source/rsa.h
+rsaref.o: source/rsaref.h
diff --git a/openssl/demos/engines/cluster_labs/cluster_labs.h b/openssl/demos/engines/cluster_labs/cluster_labs.h
new file mode 100644
index 0000000..d092679
--- /dev/null
+++ b/openssl/demos/engines/cluster_labs/cluster_labs.h
@@ -0,0 +1,35 @@
+typedef int cl_engine_init(void);
+typedef int cl_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			const BIGNUM *m, BN_CTX *cgx);
+typedef int cl_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
+		const BIGNUM *iqmp, BN_CTX *ctx);
+typedef int cl_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
+typedef int cl_rsa_pub_enc(int flen, const unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding);
+typedef int cl_rsa_pub_dec(int flen, const unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding);
+typedef int cl_rsa_priv_enc(int flen, const unsigned char *from, 
+		unsigned char *to, RSA *rsa, int padding);
+typedef int cl_rsa_priv_dec(int flen, const unsigned char *from, 
+		unsigned char *to, RSA *rsa, int padding);		
+typedef int cl_rand_bytes(unsigned char *buf, int num);
+typedef DSA_SIG *cl_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+typedef int cl_dsa_verify(const unsigned char *dgst, int dgst_len,
+				DSA_SIG *sig, DSA *dsa);
+
+
+static const char *CLUSTER_LABS_LIB_NAME = "cluster_labs";
+static const char *CLUSTER_LABS_F1	 = "hw_engine_init";
+static const char *CLUSTER_LABS_F2	 = "hw_mod_exp";
+static const char *CLUSTER_LABS_F3	 = "hw_mod_exp_crt";
+static const char *CLUSTER_LABS_F4	 = "hw_rsa_mod_exp";
+static const char *CLUSTER_LABS_F5	 = "hw_rsa_priv_enc";
+static const char *CLUSTER_LABS_F6	 = "hw_rsa_priv_dec";
+static const char *CLUSTER_LABS_F7	 = "hw_rsa_pub_enc";
+static const char *CLUSTER_LABS_F8	 = "hw_rsa_pub_dec";
+static const char *CLUSTER_LABS_F20	 = "hw_rand_bytes";
+static const char *CLUSTER_LABS_F30	 = "hw_dsa_sign";
+static const char *CLUSTER_LABS_F31	 = "hw_dsa_verify";
+
+
diff --git a/openssl/demos/engines/cluster_labs/hw_cluster_labs.c b/openssl/demos/engines/cluster_labs/hw_cluster_labs.c
new file mode 100644
index 0000000..036f48b
--- /dev/null
+++ b/openssl/demos/engines/cluster_labs/hw_cluster_labs.c
@@ -0,0 +1,721 @@
+/* crypto/engine/hw_cluster_labs.c */
+/* Written by Jan Tschirschwitz (jan.tschirschwitz@cluster-labs.com
+ * for the OpenSSL project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#define MSC_VER   /* only used cryptic.h */
+
+#include <stdio.h>
+#include <openssl/crypto.h>
+#include <openssl/dso.h>
+#include <openssl/des.h>
+#include <openssl/engine.h>
+
+#ifndef NO_HW
+#ifndef NO_HW_CLUSTER_LABS
+
+#ifdef FLAT_INC
+#include "cluster_labs.h"
+#else
+#include "vendor_defns/cluster_labs.h"
+#endif
+
+#define CL_LIB_NAME "cluster_labs engine"
+#include "hw_cluster_labs_err.c"
+
+
+static int cluster_labs_destroy(ENGINE *e);
+static int cluster_labs_init(ENGINE *e);
+static int cluster_labs_finish(ENGINE *e);
+static int cluster_labs_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
+
+
+/* BIGNUM stuff */
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int cluster_labs_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+		
+/* RSA stuff */
+#ifndef OPENSSL_NO_RSA
+static int cluster_labs_rsa_pub_enc(int flen, const unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding);
+static int cluster_labs_rsa_pub_dec(int flen, const unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding);
+static int cluster_labs_rsa_priv_enc(int flen, const unsigned char *from, 
+		unsigned char *to, RSA *rsa, int padding);
+static int cluster_labs_rsa_priv_dec(int flen, const unsigned char *from, 
+		unsigned char *to, RSA *rsa, int padding);
+static int cluster_labs_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
+#endif
+
+/* DSA stuff */
+#ifndef OPENSSL_NO_DSA
+static DSA_SIG *cluster_labs_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+static int cluster_labs_dsa_verify(const unsigned char *dgst, int dgst_len,
+				DSA_SIG *sig, DSA *dsa);
+static int cluster_labs_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
+		BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
+		BN_CTX *ctx, BN_MONT_CTX *in_mont);
+static int cluster_labs_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+		BN_MONT_CTX *m_ctx);
+#endif
+								
+/* DH stuff */
+#ifndef OPENSSL_NO_DH
+/* This function is alised to mod_exp (with the DH and mont dropped). */
+static int cluster_labs_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#endif
+		
+/* RANDOM stuff */						
+static int cluster_labs_rand_bytes(unsigned char *buf, int num);
+
+/* The definitions for control commands specific to this engine */
+#define CLUSTER_LABS_CMD_SO_PATH		ENGINE_CMD_BASE
+static const ENGINE_CMD_DEFN cluster_labs_cmd_defns[] =
+	{
+	{ CLUSTER_LABS_CMD_SO_PATH,
+	  "SO_PATH",
+	  "Specifies the path to the 'cluster labs' shared library",
+	  ENGINE_CMD_FLAG_STRING
+	},
+	{0, NULL, NULL, 0}
+	};
+
+/* Our internal RSA_METHOD that we provide pointers to */
+#ifndef OPENSSL_NO_RSA
+static RSA_METHOD cluster_labs_rsa =
+	{
+	"Cluster Labs RSA method",
+	cluster_labs_rsa_pub_enc,	/* rsa_pub_enc */
+	cluster_labs_rsa_pub_dec,	/* rsa_pub_dec */
+	cluster_labs_rsa_priv_enc,	/* rsa_priv_enc */
+	cluster_labs_rsa_priv_dec,	/* rsa_priv_dec */
+	cluster_labs_rsa_mod_exp,	/* rsa_mod_exp */
+	cluster_labs_mod_exp_mont,	/* bn_mod_exp */
+	NULL,				/* init */
+	NULL,				/* finish */
+	0, 				/* flags */
+	NULL,				/* apps_data */
+	NULL,				/* rsa_sign */
+	NULL				/* rsa_verify */
+	};
+#endif
+
+/* Our internal DSA_METHOD that we provide pointers to */
+#ifndef OPENSSL_NO_DSA
+static DSA_METHOD cluster_labs_dsa =
+	{
+	"Cluster Labs DSA method",
+	cluster_labs_dsa_sign,  	/* dsa_do_sign */
+	NULL, 				/* dsa_sign_setup */
+	cluster_labs_dsa_verify,	/* dsa_do_verify */
+	cluster_labs_dsa_mod_exp, 	/* dsa_mod_exp */
+	cluster_labs_mod_exp_dsa, 	/* bn_mod_exp */
+	NULL, 				/* init */
+	NULL, 				/* finish */
+	0, 				/* flags */
+	NULL 				/* app_data */
+	};
+#endif	
+
+/* Our internal DH_METHOD that we provide pointers to */
+#ifndef OPENSSL_NO_DH
+static DH_METHOD cluster_labs_dh =
+	{
+	"Cluster Labs DH method",
+	NULL,				/* generate key */
+	NULL,				/* compute key */
+	cluster_labs_mod_exp_dh,	/* bn_mod_exp */
+	NULL,				/* init */
+	NULL,				/* finish */
+	0,				/* flags */
+	NULL				/* app_data */
+	};
+#endif	
+	
+static RAND_METHOD cluster_labs_rand =
+	{
+	/* "Cluster Labs RAND method", */
+	NULL,				/* seed */
+	cluster_labs_rand_bytes,	/* bytes */
+	NULL,				/* cleanup */
+	NULL,				/* add */
+	cluster_labs_rand_bytes,	/* pseudorand */
+	NULL,				/* status */
+	};	
+
+static const char *engine_cluster_labs_id = "cluster_labs";
+static const char *engine_cluster_labs_name = "Cluster Labs hardware engine support";
+
+/* engine implementation */
+/*-----------------------*/
+static int bind_helper(ENGINE *e)
+	{
+	
+	if(!ENGINE_set_id(e, engine_cluster_labs_id) ||
+			!ENGINE_set_name(e, engine_cluster_labs_name) ||
+#ifndef OPENSSL_NO_RSA
+			!ENGINE_set_RSA(e, &cluster_labs_rsa) ||
+#endif
+#ifndef OPENSSL_NO_DSA
+			!ENGINE_set_DSA(e, &cluster_labs_dsa) ||
+#endif
+#ifndef OPENSSL_NO_DH
+			!ENGINE_set_DH(e, &cluster_labs_dh) ||
+#endif
+			!ENGINE_set_RAND(e, &cluster_labs_rand) ||
+			!ENGINE_set_destroy_function(e, cluster_labs_destroy) ||
+			!ENGINE_set_init_function(e, cluster_labs_init) ||
+			!ENGINE_set_finish_function(e, cluster_labs_finish) ||
+			!ENGINE_set_ctrl_function(e, cluster_labs_ctrl) ||
+			!ENGINE_set_cmd_defns(e, cluster_labs_cmd_defns))
+		return 0;
+	/* Ensure the error handling is set up */
+	ERR_load_CL_strings();
+	return 1;
+	}
+	
+#ifndef ENGINE_DYNAMIC_SUPPORT
+static ENGINE *engine_cluster_labs(void)
+	{
+	ENGINE *ret = ENGINE_new();
+
+	if(!ret)
+		return NULL;
+	if(!bind_helper(ret))
+		{
+		ENGINE_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+#ifdef ENGINE_DYNAMIC_SUPPORT
+static
+#endif
+void ENGINE_load_cluster_labs(void)
+	{
+
+	ENGINE *cluster_labs = engine_cluster_labs();
+	
+	if(!cluster_labs) return;
+	ENGINE_add(cluster_labs);
+	ENGINE_free(cluster_labs);
+	ERR_clear_error();
+	}
+#endif /* !ENGINE_DYNAMIC_SUPPORT */
+
+static int cluster_labs_destroy(ENGINE *e)
+	{
+	
+	ERR_unload_CL_strings();
+	return 1;
+	}
+
+
+
+/* This is a process-global DSO handle used for loading and unloading
+ * the Cluster Labs library. NB: This is only set (or unset) during an
+ * init() or finish() call (reference counts permitting) and they're
+ * operating with global locks, so this should be thread-safe
+ * implicitly. */
+static DSO *cluster_labs_dso = NULL;
+
+/* These are the function pointers that are (un)set when the library has
+ * successfully (un)loaded. */
+static cl_engine_init	  	*p_cl_engine_init 		 = NULL;
+static cl_mod_exp	 	*p_cl_mod_exp 			 = NULL;
+static cl_mod_exp_crt		*p_cl_mod_exp_crt 		 = NULL;
+static cl_rsa_mod_exp		*p_cl_rsa_mod_exp 		 = NULL;
+static cl_rsa_priv_enc		*p_cl_rsa_priv_enc 		 = NULL;
+static cl_rsa_priv_dec		*p_cl_rsa_priv_dec 		 = NULL;
+static cl_rsa_pub_enc		*p_cl_rsa_pub_enc 		 = NULL;
+static cl_rsa_pub_dec		*p_cl_rsa_pub_dec 		 = NULL;
+static cl_rand_bytes		*p_cl_rand_bytes	 	 = NULL;
+static cl_dsa_sign		*p_cl_dsa_sign		 	 = NULL;
+static cl_dsa_verify		*p_cl_dsa_verify	 	 = NULL;
+
+
+int cluster_labs_init(ENGINE *e)
+	{
+
+	cl_engine_init			*p1;
+	cl_mod_exp			*p2;
+	cl_mod_exp_crt			*p3;
+	cl_rsa_mod_exp			*p4;
+	cl_rsa_priv_enc			*p5;
+	cl_rsa_priv_dec			*p6;	
+	cl_rsa_pub_enc			*p7;
+	cl_rsa_pub_dec			*p8;
+	cl_rand_bytes			*p20;
+	cl_dsa_sign			*p30;	
+	cl_dsa_verify			*p31;		
+	
+	/* engine already loaded */
+	if(cluster_labs_dso != NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_INIT,CL_R_ALREADY_LOADED);
+		goto err;
+		}
+	/* try to load engine	 */	
+	cluster_labs_dso = DSO_load(NULL, CLUSTER_LABS_LIB_NAME, NULL,0);
+	if(cluster_labs_dso == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_INIT,CL_R_DSO_FAILURE);
+		goto err;
+		}
+	/* bind functions */
+	if(	!(p1 = (cl_engine_init *)DSO_bind_func(
+				cluster_labs_dso, CLUSTER_LABS_F1)) ||
+		!(p2 = (cl_mod_exp *)DSO_bind_func(
+				cluster_labs_dso, CLUSTER_LABS_F2)) ||			
+		!(p3 = (cl_mod_exp_crt *)DSO_bind_func(
+				cluster_labs_dso, CLUSTER_LABS_F3)) ||				
+		!(p4 = (cl_rsa_mod_exp *)DSO_bind_func(
+				cluster_labs_dso, CLUSTER_LABS_F4)) ||				
+		!(p5 = (cl_rsa_priv_enc *)DSO_bind_func(
+				cluster_labs_dso, CLUSTER_LABS_F5)) ||
+		!(p6 = (cl_rsa_priv_dec *)DSO_bind_func(
+				cluster_labs_dso, CLUSTER_LABS_F6)) ||
+		!(p7 = (cl_rsa_pub_enc *)DSO_bind_func(
+				cluster_labs_dso, CLUSTER_LABS_F7)) ||
+		!(p8 = (cl_rsa_pub_dec *)DSO_bind_func(
+				cluster_labs_dso, CLUSTER_LABS_F8)) ||
+		!(p20= (cl_rand_bytes *)DSO_bind_func(
+				cluster_labs_dso, CLUSTER_LABS_F20)) ||
+		!(p30= (cl_dsa_sign *)DSO_bind_func(
+				cluster_labs_dso, CLUSTER_LABS_F30)) ||
+		!(p31= (cl_dsa_verify *)DSO_bind_func(
+				cluster_labs_dso, CLUSTER_LABS_F31)))
+		{
+		CLerr(CL_F_CLUSTER_LABS_INIT,CL_R_DSO_FAILURE);
+		goto err;
+		}
+		
+	/* copy function pointers */
+	p_cl_engine_init		= p1;
+	p_cl_mod_exp			= p2;
+	p_cl_mod_exp_crt		= p3;	
+	p_cl_rsa_mod_exp 		= p4;
+	p_cl_rsa_priv_enc	 	= p5;
+	p_cl_rsa_priv_dec	 	= p6;
+	p_cl_rsa_pub_enc	 	= p7;
+	p_cl_rsa_pub_dec	 	= p8;
+	p_cl_rand_bytes			= p20;	
+	p_cl_dsa_sign			= p30;
+	p_cl_dsa_verify			= p31;	
+	
+	
+	
+	/* cluster labs engine init */
+	if(p_cl_engine_init()== 0){
+		CLerr(CL_F_CLUSTER_LABS_INIT,CL_R_INIT_FAILED);		
+		goto err;
+	}
+
+	return(1);
+
+err:	
+	/* reset all pointers */
+	if(cluster_labs_dso)
+		DSO_free(cluster_labs_dso);
+
+	cluster_labs_dso		= NULL;
+	p_cl_engine_init		= NULL;	
+	p_cl_mod_exp			= NULL;
+	p_cl_mod_exp_crt		= NULL;
+	p_cl_rsa_mod_exp		= NULL;
+	p_cl_rsa_priv_enc		= NULL;
+	p_cl_rsa_priv_dec		= NULL;	
+	p_cl_rsa_pub_enc		= NULL;
+	p_cl_rsa_pub_dec		= NULL;	
+	p_cl_rand_bytes			= NULL;	
+	p_cl_dsa_sign			= NULL;
+	p_cl_dsa_verify			= NULL;	
+	
+	return(0);
+	}
+	
+
+static int cluster_labs_finish(ENGINE *e)
+	{
+
+	if(cluster_labs_dso == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_FINISH,CL_R_NOT_LOADED);
+		return 0;
+		}
+	if(!DSO_free(cluster_labs_dso))
+		{
+		CLerr(CL_F_CLUSTER_LABS_FINISH,CL_R_DSO_FAILURE);
+		return 0;
+		}
+		
+	cluster_labs_dso 		= NULL;
+	p_cl_engine_init		= NULL;		
+	p_cl_mod_exp			= NULL;
+	p_cl_rsa_mod_exp		= NULL;	
+	p_cl_mod_exp_crt		= NULL;	
+	p_cl_rsa_priv_enc		= NULL;	
+	p_cl_rsa_priv_dec		= NULL;	
+	p_cl_rsa_pub_enc		= NULL;
+	p_cl_rsa_pub_dec		= NULL;	
+	p_cl_rand_bytes			= NULL;		
+	p_cl_dsa_sign			= NULL;
+	p_cl_dsa_verify			= NULL;	
+	
+	return(1);	
+	
+	}
+	
+static int cluster_labs_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
+	{
+	int initialised = ((cluster_labs_dso == NULL) ? 0 : 1);
+
+	switch(cmd)
+		{
+	case CLUSTER_LABS_CMD_SO_PATH:
+		if(p == NULL)
+			{
+			CLerr(CL_F_CLUSTER_LABS_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+			return 0;
+			}
+		if(initialised)
+			{
+			CLerr(CL_F_CLUSTER_LABS_CTRL,CL_R_ALREADY_LOADED);
+			return 0;
+			}
+		CLUSTER_LABS_LIB_NAME = (const char *)p;
+		return 1;
+	default:
+		break;
+		}
+	CLerr(CL_F_CLUSTER_LABS_CTRL,CL_R_COMMAND_NOT_IMPLEMENTED);
+	return 0;
+	}
+	
+
+static int cluster_labs_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx)
+	{
+
+	if(cluster_labs_dso == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_MOD_EXP,CL_R_NOT_LOADED);
+		return 0;
+		}	
+	if(p_cl_mod_exp == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_MOD_EXP,CL_R_FUNCTION_NOT_BINDED);
+		return 0;
+		}
+
+	return	p_cl_mod_exp(r, a, p, m, ctx);
+
+	}
+	
+static int cluster_labs_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
+		const BIGNUM *iqmp, BN_CTX *ctx)
+	{
+
+	if(cluster_labs_dso == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_MOD_EXP_CRT,CL_R_NOT_LOADED);		
+		return 0;
+		}
+	if(p_cl_mod_exp_crt == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_MOD_EXP_CRT,CL_R_FUNCTION_NOT_BINDED);		
+		return 0;
+		}
+	
+	return	p_cl_mod_exp_crt(r, a, p, q,dmp1, dmq1, iqmp, ctx);
+	
+	}
+	
+static int cluster_labs_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
+	{
+
+	if(cluster_labs_dso == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_RSA_MOD_EXP,CL_R_NOT_LOADED);		
+		return 0;
+		}
+	if(p_cl_rsa_mod_exp == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_RSA_MOD_EXP,CL_R_FUNCTION_NOT_BINDED);				
+		return 0;
+		}
+
+	return p_cl_rsa_mod_exp(r0, I, rsa);
+
+	}
+	
+static DSA_SIG *cluster_labs_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+	{
+
+	if(cluster_labs_dso == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_DSA_SIGN,CL_R_NOT_LOADED);		
+		return 0;
+		}
+	if(p_cl_dsa_sign == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_DSA_SIGN,CL_R_FUNCTION_NOT_BINDED);				
+		return 0;
+		}
+
+	return p_cl_dsa_sign(dgst, dlen, dsa);
+	
+	}
+	
+static int cluster_labs_dsa_verify(const unsigned char *dgst, int dgst_len,
+				DSA_SIG *sig, DSA *dsa)
+	{
+
+	if(cluster_labs_dso == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_DSA_VERIFY,CL_R_NOT_LOADED);		
+		return 0;
+		}
+	
+	if(p_cl_dsa_verify == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_DSA_VERIFY,CL_R_FUNCTION_NOT_BINDED);				
+		return 0;
+		}
+
+	return p_cl_dsa_verify(dgst, dgst_len, sig, dsa);
+	
+	}			
+
+static int cluster_labs_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
+		BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
+		BN_CTX *ctx, BN_MONT_CTX *in_mont)
+	{
+	BIGNUM t;
+	int status = 0;
+		
+	BN_init(&t);
+	/* let rr = a1 ^ p1 mod m */
+	if (!cluster_labs_mod_exp(rr,a1,p1,m,ctx)) goto end;
+	/* let t = a2 ^ p2 mod m */
+	if (!cluster_labs_mod_exp(&t,a2,p2,m,ctx)) goto end;
+	/* let rr = rr * t mod m */
+	if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
+	status = 1;
+end:
+	BN_free(&t);
+	
+	return(1);
+
+	}
+
+static int cluster_labs_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+		BN_MONT_CTX *m_ctx)
+	{
+	return 	cluster_labs_mod_exp(r, a, p, m, ctx);
+	}
+	
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int cluster_labs_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+	{
+	return	cluster_labs_mod_exp(r, a, p, m, ctx);
+	}
+	
+
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int cluster_labs_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+	{
+	return 	cluster_labs_mod_exp(r, a, p, m, ctx);
+	}
+
+
+static int cluster_labs_rsa_pub_enc(int flen, const unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+
+	if(cluster_labs_dso == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_RSA_PUB_ENC,CL_R_NOT_LOADED);		
+		return 0;
+		}
+	if(p_cl_rsa_priv_enc == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_RSA_PUB_ENC,CL_R_FUNCTION_NOT_BINDED);				
+		return 0;
+		}
+		
+	return 	p_cl_rsa_pub_enc(flen, from, to, rsa, padding);
+	
+	}  
+	     
+static int cluster_labs_rsa_pub_dec(int flen, const unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+
+	if(cluster_labs_dso == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_RSA_PUB_DEC,CL_R_NOT_LOADED);		
+		return 0;
+		}
+	if(p_cl_rsa_priv_enc == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_RSA_PUB_DEC,CL_R_FUNCTION_NOT_BINDED);				
+		return 0;
+		}
+		
+	return 	p_cl_rsa_pub_dec(flen, from, to, rsa, padding);
+	
+	}  
+
+
+static int cluster_labs_rsa_priv_enc(int flen, const unsigned char *from, 
+		unsigned char *to, RSA *rsa, int padding)
+	{
+
+	if(cluster_labs_dso == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_RSA_PRIV_ENC,CL_R_NOT_LOADED);		
+		return 0;
+		}
+
+	if(p_cl_rsa_priv_enc == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_RSA_PRIV_ENC,CL_R_FUNCTION_NOT_BINDED);				
+		return 0;
+		}
+		
+	return 	p_cl_rsa_priv_enc(flen, from, to, rsa, padding);
+	
+	}  
+
+static int cluster_labs_rsa_priv_dec(int flen, const unsigned char *from, 
+		unsigned char *to, RSA *rsa, int padding)
+	{
+	
+	if(cluster_labs_dso == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_RSA_PRIV_DEC,CL_R_NOT_LOADED);		
+		return 0;
+		}
+	if(p_cl_rsa_priv_dec == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_RSA_PRIV_DEC,CL_R_FUNCTION_NOT_BINDED);				
+		return 0;
+		}
+
+	return 	p_cl_rsa_priv_dec(flen, from, to, rsa, padding);
+		
+	}  
+
+/************************************************************************************
+* Symmetric algorithms
+************************************************************************************/
+/* this will be come soon! */
+
+/************************************************************************************
+* Random generator
+************************************************************************************/
+
+static int cluster_labs_rand_bytes(unsigned char *buf, int num){
+
+	if(cluster_labs_dso == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_RAND_BYTES,CL_R_NOT_LOADED);		
+		return 0;
+		}
+	if(p_cl_mod_exp_crt == NULL)
+		{
+		CLerr(CL_F_CLUSTER_LABS_RAND_BYTES,CL_R_FUNCTION_NOT_BINDED);				
+		return 0;
+		}
+
+	return 	p_cl_rand_bytes(buf, num);
+
+}
+
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library. */
+#ifdef ENGINE_DYNAMIC_SUPPORT
+static int bind_fn(ENGINE *e, const char *id)
+	{
+	fprintf(stderr, "bind_fn CLUSTER_LABS\n");
+	if(id && (strcmp(id, engine_cluster_labs_id) != 0)) {
+		fprintf(stderr, "bind_fn return(0) first\n");
+		return 0;
+		}
+	if(!bind_helper(e)) {
+		fprintf(stderr, "bind_fn return(1) first\n");
+		return 0;
+		}
+	fprintf(stderr, "bind_fn return(1)\n");		
+	return 1;
+	}
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#endif /* ENGINE_DYNAMIC_SUPPORT */
+						
+#endif /* !NO_HW_CLUSTER_LABS */
+#endif /* !NO_HW */
+
diff --git a/openssl/demos/engines/cluster_labs/hw_cluster_labs.ec b/openssl/demos/engines/cluster_labs/hw_cluster_labs.ec
new file mode 100644
index 0000000..1f64786
--- /dev/null
+++ b/openssl/demos/engines/cluster_labs/hw_cluster_labs.ec
@@ -0,0 +1,8 @@
+# configuration file for util/mkerr.pl
+#
+# use like this:
+#
+#	perl ../../../util/mkerr.pl -conf hw_cluster_labs.ec \
+#		-nostatic -staticloader -write *.c
+
+L CL		hw_cluster_labs_err.h		hw_cluster_labs_err.c
diff --git a/openssl/demos/engines/cluster_labs/hw_cluster_labs_err.c b/openssl/demos/engines/cluster_labs/hw_cluster_labs_err.c
new file mode 100644
index 0000000..a7fa408
--- /dev/null
+++ b/openssl/demos/engines/cluster_labs/hw_cluster_labs_err.c
@@ -0,0 +1,151 @@
+/* hw_cluster_labs_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "hw_cluster_labs_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+static ERR_STRING_DATA CL_str_functs[]=
+	{
+{ERR_PACK(0,CL_F_CLUSTER_LABS_CTRL,0),	"CLUSTER_LABS_CTRL"},
+{ERR_PACK(0,CL_F_CLUSTER_LABS_DSA_SIGN,0),	"CLUSTER_LABS_DSA_SIGN"},
+{ERR_PACK(0,CL_F_CLUSTER_LABS_DSA_VERIFY,0),	"CLUSTER_LABS_DSA_VERIFY"},
+{ERR_PACK(0,CL_F_CLUSTER_LABS_FINISH,0),	"CLUSTER_LABS_FINISH"},
+{ERR_PACK(0,CL_F_CLUSTER_LABS_INIT,0),	"CLUSTER_LABS_INIT"},
+{ERR_PACK(0,CL_F_CLUSTER_LABS_MOD_EXP,0),	"CLUSTER_LABS_MOD_EXP"},
+{ERR_PACK(0,CL_F_CLUSTER_LABS_MOD_EXP_CRT,0),	"CLUSTER_LABS_MOD_EXP_CRT"},
+{ERR_PACK(0,CL_F_CLUSTER_LABS_RAND_BYTES,0),	"CLUSTER_LABS_RAND_BYTES"},
+{ERR_PACK(0,CL_F_CLUSTER_LABS_RSA_MOD_EXP,0),	"CLUSTER_LABS_RSA_MOD_EXP"},
+{ERR_PACK(0,CL_F_CLUSTER_LABS_RSA_PRIV_DEC,0),	"CLUSTER_LABS_RSA_PRIV_DEC"},
+{ERR_PACK(0,CL_F_CLUSTER_LABS_RSA_PRIV_ENC,0),	"CLUSTER_LABS_RSA_PRIV_ENC"},
+{ERR_PACK(0,CL_F_CLUSTER_LABS_RSA_PUB_DEC,0),	"CLUSTER_LABS_RSA_PUB_DEC"},
+{ERR_PACK(0,CL_F_CLUSTER_LABS_RSA_PUB_ENC,0),	"CLUSTER_LABS_RSA_PUB_ENC"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA CL_str_reasons[]=
+	{
+{CL_R_ALREADY_LOADED                     ,"already loaded"},
+{CL_R_COMMAND_NOT_IMPLEMENTED            ,"command not implemented"},
+{CL_R_DSO_FAILURE                        ,"dso failure"},
+{CL_R_FUNCTION_NOT_BINDED                ,"function not binded"},
+{CL_R_INIT_FAILED                        ,"init failed"},
+{CL_R_NOT_LOADED                         ,"not loaded"},
+{0,NULL}
+	};
+
+#endif
+
+#ifdef CL_LIB_NAME
+static ERR_STRING_DATA CL_lib_name[]=
+        {
+{0	,CL_LIB_NAME},
+{0,NULL}
+	};
+#endif
+
+
+static int CL_lib_error_code=0;
+static int CL_error_init=1;
+
+static void ERR_load_CL_strings(void)
+	{
+	if (CL_lib_error_code == 0)
+		CL_lib_error_code=ERR_get_next_error_library();
+
+	if (CL_error_init)
+		{
+		CL_error_init=0;
+#ifndef OPENSSL_NO_ERR
+		ERR_load_strings(CL_lib_error_code,CL_str_functs);
+		ERR_load_strings(CL_lib_error_code,CL_str_reasons);
+#endif
+
+#ifdef CL_LIB_NAME
+		CL_lib_name->error = ERR_PACK(CL_lib_error_code,0,0);
+		ERR_load_strings(0,CL_lib_name);
+#endif
+		}
+	}
+
+static void ERR_unload_CL_strings(void)
+	{
+	if (CL_error_init == 0)
+		{
+#ifndef OPENSSL_NO_ERR
+		ERR_unload_strings(CL_lib_error_code,CL_str_functs);
+		ERR_unload_strings(CL_lib_error_code,CL_str_reasons);
+#endif
+
+#ifdef CL_LIB_NAME
+		ERR_unload_strings(0,CL_lib_name);
+#endif
+		CL_error_init=1;
+		}
+	}
+
+static void ERR_CL_error(int function, int reason, char *file, int line)
+	{
+	if (CL_lib_error_code == 0)
+		CL_lib_error_code=ERR_get_next_error_library();
+	ERR_PUT_error(CL_lib_error_code,function,reason,file,line);
+	}
diff --git a/openssl/demos/engines/cluster_labs/hw_cluster_labs_err.h b/openssl/demos/engines/cluster_labs/hw_cluster_labs_err.h
new file mode 100644
index 0000000..f548a3b
--- /dev/null
+++ b/openssl/demos/engines/cluster_labs/hw_cluster_labs_err.h
@@ -0,0 +1,99 @@
+/* ====================================================================
+ * Copyright (c) 2001-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_CL_ERR_H
+#define HEADER_CL_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_CL_strings(void);
+static void ERR_unload_CL_strings(void);
+static void ERR_CL_error(int function, int reason, char *file, int line);
+#define CLerr(f,r) ERR_CL_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the CL functions. */
+
+/* Function codes. */
+#define CL_F_CLUSTER_LABS_CTRL				 100
+#define CL_F_CLUSTER_LABS_DSA_SIGN			 101
+#define CL_F_CLUSTER_LABS_DSA_VERIFY			 102
+#define CL_F_CLUSTER_LABS_FINISH			 103
+#define CL_F_CLUSTER_LABS_INIT				 104
+#define CL_F_CLUSTER_LABS_MOD_EXP			 105
+#define CL_F_CLUSTER_LABS_MOD_EXP_CRT			 106
+#define CL_F_CLUSTER_LABS_RAND_BYTES			 107
+#define CL_F_CLUSTER_LABS_RSA_MOD_EXP			 108
+#define CL_F_CLUSTER_LABS_RSA_PRIV_DEC			 109
+#define CL_F_CLUSTER_LABS_RSA_PRIV_ENC			 110
+#define CL_F_CLUSTER_LABS_RSA_PUB_DEC			 111
+#define CL_F_CLUSTER_LABS_RSA_PUB_ENC			 112
+
+/* Reason codes. */
+#define CL_R_ALREADY_LOADED				 100
+#define CL_R_COMMAND_NOT_IMPLEMENTED			 101
+#define CL_R_DSO_FAILURE				 102
+#define CL_R_FUNCTION_NOT_BINDED			 103
+#define CL_R_INIT_FAILED				 104
+#define CL_R_NOT_LOADED					 105
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/demos/engines/ibmca/Makefile b/openssl/demos/engines/ibmca/Makefile
new file mode 100644
index 0000000..72f3546
--- /dev/null
+++ b/openssl/demos/engines/ibmca/Makefile
@@ -0,0 +1,114 @@
+LIBNAME=	libibmca
+SRC=		hw_ibmca.c
+OBJ=		hw_ibmca.o
+HEADER=		hw_ibmca.h
+
+CC=		gcc
+PIC=		-fPIC
+CFLAGS=		-g -I../../../include $(PIC) -DENGINE_DYNAMIC_SUPPORT -DFLAT_INC
+AR=		ar r
+RANLIB=		ranlib
+
+LIB=		$(LIBNAME).a
+SHLIB=		$(LIBNAME).so
+
+all:
+		@echo 'Please choose a system to build on:'
+		@echo ''
+		@echo 'tru64:    Tru64 Unix, Digital Unix, Digital OSF/1'
+		@echo 'solaris:  Solaris'
+		@echo 'irix:     IRIX'
+		@echo 'hpux32:   32-bit HP/UX'
+		@echo 'hpux64:   64-bit HP/UX'
+		@echo 'aix:      AIX'
+		@echo 'gnu:      Generic GNU-based system (gcc and GNU ld)'
+		@echo ''
+
+FORCE.update:
+update:		FORCE.update
+		perl ../../../util/mkerr.pl -conf hw_ibmca.ec \
+			-nostatic -staticloader -write hw_ibmca.c
+
+gnu:		$(SHLIB).gnu
+tru64:		$(SHLIB).tru64
+solaris:	$(SHLIB).solaris
+irix:		$(SHLIB).irix
+hpux32:		$(SHLIB).hpux32
+hpux64:		$(SHLIB).hpux64
+aix:		$(SHLIB).aix
+
+$(LIB):		$(OBJ)
+		$(AR) $(LIB) $(OBJ)
+		- $(RANLIB) $(LIB)
+
+LINK_SO=	\
+  ld -r -o $(LIBNAME).o $$ALLSYMSFLAGS $(LIB) && \
+  (nm -Pg $(LIBNAME).o | grep ' [BDT] ' | cut -f1 -d' ' > $(LIBNAME).exp; \
+   $$SHAREDCMD $$SHAREDFLAGS -o $(SHLIB) $(LIBNAME).o -L ../../.. -lcrypto -lc)
+
+$(SHLIB).gnu:	$(LIB)
+		ALLSYMSFLAGS='--whole-archive' \
+		SHAREDFLAGS='-shared -Wl,-soname=$(SHLIB)' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).gnu
+$(SHLIB).tru64:	$(LIB)
+		ALLSYMSFLAGS='-all' \
+		SHAREDFLAGS='-shared' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).tru64
+$(SHLIB).solaris:	$(LIB)
+		ALLSYMSFLAGS='-z allextract' \
+		SHAREDFLAGS='-G -h $(SHLIB)' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).solaris
+$(SHLIB).irix:	$(LIB)
+		ALLSYMSFLAGS='-all' \
+		SHAREDFLAGS='-shared -Wl,-soname,$(SHLIB)' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).irix
+$(SHLIB).hpux32:	$(LIB)
+		ALLSYMSFLAGS='-Fl' \
+		SHAREDFLAGS='+vnocompatwarnings -b -z +s +h $(SHLIB)' \
+		SHAREDCMD='/usr/ccs/bin/ld'; \
+		$(LINK_SO)
+		touch $(SHLIB).hpux32
+$(SHLIB).hpux64:	$(LIB)
+		ALLSYMSFLAGS='+forceload' \
+		SHAREDFLAGS='-b -z +h $(SHLIB)' \
+		SHAREDCMD='/usr/ccs/bin/ld'; \
+		$(LINK_SO)
+		touch $(SHLIB).hpux64
+$(SHLIB).aix:	$(LIB)
+		ALLSYMSFLAGS='-bnogc' \
+		SHAREDFLAGS='-G -bE:$(LIBNAME).exp -bM:SRE' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).aix
+
+depend:
+		sed -e '/^# DO NOT DELETE.*/,$$d' < Makefile > Makefile.tmp
+		echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' >> Makefile.tmp
+		gcc -M $(CFLAGS) $(SRC) >> Makefile.tmp
+		perl ../../../util/clean-depend.pl < Makefile.tmp > Makefile.new
+		rm -f Makefile.tmp Makefile
+		mv Makefile.new Makefile
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+rsaref.o: ../../../include/openssl/asn1.h ../../../include/openssl/bio.h
+rsaref.o: ../../../include/openssl/bn.h ../../../include/openssl/crypto.h
+rsaref.o: ../../../include/openssl/dh.h ../../../include/openssl/dsa.h
+rsaref.o: ../../../include/openssl/e_os2.h ../../../include/openssl/engine.h
+rsaref.o: ../../../include/openssl/err.h ../../../include/openssl/lhash.h
+rsaref.o: ../../../include/openssl/opensslconf.h
+rsaref.o: ../../../include/openssl/opensslv.h
+rsaref.o: ../../../include/openssl/ossl_typ.h ../../../include/openssl/rand.h
+rsaref.o: ../../../include/openssl/rsa.h ../../../include/openssl/safestack.h
+rsaref.o: ../../../include/openssl/stack.h ../../../include/openssl/symhacks.h
+rsaref.o: ../../../include/openssl/ui.h rsaref.c rsaref_err.c rsaref_err.h
+rsaref.o: source/des.h source/global.h source/md2.h source/md5.h source/rsa.h
+rsaref.o: source/rsaref.h
diff --git a/openssl/demos/engines/ibmca/hw_ibmca.c b/openssl/demos/engines/ibmca/hw_ibmca.c
new file mode 100644
index 0000000..0c2c39b
--- /dev/null
+++ b/openssl/demos/engines/ibmca/hw_ibmca.c
@@ -0,0 +1,920 @@
+/* crypto/engine/hw_ibmca.c */

+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL

+ * project 2000.

+ */

+/* ====================================================================

+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ *

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ *

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in

+ *    the documentation and/or other materials provided with the

+ *    distribution.

+ *

+ * 3. All advertising materials mentioning features or use of this

+ *    software must display the following acknowledgment:

+ *    "This product includes software developed by the OpenSSL Project

+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"

+ *

+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to

+ *    endorse or promote products derived from this software without

+ *    prior written permission. For written permission, please contact

+ *    licensing@OpenSSL.org.

+ *

+ * 5. Products derived from this software may not be called "OpenSSL"

+ *    nor may "OpenSSL" appear in their names without prior written

+ *    permission of the OpenSSL Project.

+ *

+ * 6. Redistributions of any form whatsoever must retain the following

+ *    acknowledgment:

+ *    "This product includes software developed by the OpenSSL Project

+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY

+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR

+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR

+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT

+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,

+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED

+ * OF THE POSSIBILITY OF SUCH DAMAGE.

+ * ====================================================================

+ *

+ * This product includes cryptographic software written by Eric Young

+ * (eay@cryptsoft.com).  This product includes software written by Tim

+ * Hudson (tjh@cryptsoft.com).

+ *

+ */

+

+/* (C) COPYRIGHT International Business Machines Corp. 2001 */

+

+#include <stdio.h>

+#include <openssl/crypto.h>

+#include <openssl/dso.h>

+#include <openssl/engine.h>

+

+#ifndef OPENSSL_NO_HW

+#ifndef OPENSSL_NO_HW_IBMCA

+

+#ifdef FLAT_INC

+#include "ica_openssl_api.h"

+#else

+#include "vendor_defns/ica_openssl_api.h"

+#endif

+

+#define IBMCA_LIB_NAME "ibmca engine"

+#include "hw_ibmca_err.c"

+

+static int ibmca_destroy(ENGINE *e);

+static int ibmca_init(ENGINE *e);

+static int ibmca_finish(ENGINE *e);

+static int ibmca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());

+

+static const char *IBMCA_F1 = "icaOpenAdapter";

+static const char *IBMCA_F2 = "icaCloseAdapter";

+static const char *IBMCA_F3 = "icaRsaModExpo";

+static const char *IBMCA_F4 = "icaRandomNumberGenerate";

+static const char *IBMCA_F5 = "icaRsaCrt";

+

+ICA_ADAPTER_HANDLE handle=0;

+

+/* BIGNUM stuff */

+static int ibmca_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,

+        const BIGNUM *m, BN_CTX *ctx);

+

+static int ibmca_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,

+        const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,

+        const BIGNUM *iqmp, BN_CTX *ctx);

+

+#ifndef OPENSSL_NO_RSA  

+/* RSA stuff */

+static int ibmca_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);

+#endif

+

+/* This function is aliased to mod_exp (with the mont stuff dropped). */

+static int ibmca_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,

+        const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);

+

+#ifndef OPENSSL_NO_DSA 

+/* DSA stuff */

+static int ibmca_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,

+        BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,

+        BN_CTX *ctx, BN_MONT_CTX *in_mont);

+static int ibmca_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,

+        const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,

+        BN_MONT_CTX *m_ctx);

+#endif

+

+#ifndef OPENSSL_NO_DH 

+/* DH stuff */

+/* This function is alised to mod_exp (with the DH and mont dropped). */

+static int ibmca_mod_exp_dh(const DH *dh, BIGNUM *r, 

+	const BIGNUM *a, const BIGNUM *p,

+	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);

+#endif

+

+/* RAND stuff */

+static int ibmca_rand_bytes(unsigned char *buf, int num);

+static int ibmca_rand_status(void);

+

+

+/* WJH - check for more commands, like in nuron */

+

+/* The definitions for control commands specific to this engine */

+#define IBMCA_CMD_SO_PATH		ENGINE_CMD_BASE

+static const ENGINE_CMD_DEFN ibmca_cmd_defns[] = {

+	{IBMCA_CMD_SO_PATH,

+		"SO_PATH",

+		"Specifies the path to the 'atasi' shared library",

+		ENGINE_CMD_FLAG_STRING},

+	{0, NULL, NULL, 0}

+	};

+

+#ifndef OPENSSL_NO_RSA  

+/* Our internal RSA_METHOD that we provide pointers to */

+static RSA_METHOD ibmca_rsa =

+        {

+        "Ibmca RSA method",

+        NULL,

+        NULL,

+        NULL,

+        NULL,

+        ibmca_rsa_mod_exp,

+        ibmca_mod_exp_mont,

+        NULL,

+        NULL,

+        0,

+        NULL,

+        NULL,

+        NULL

+        };

+#endif

+

+#ifndef OPENSSL_NO_DSA

+/* Our internal DSA_METHOD that we provide pointers to */

+static DSA_METHOD ibmca_dsa =

+        {

+        "Ibmca DSA method",

+        NULL, /* dsa_do_sign */

+        NULL, /* dsa_sign_setup */

+        NULL, /* dsa_do_verify */

+        ibmca_dsa_mod_exp, /* dsa_mod_exp */

+        ibmca_mod_exp_dsa, /* bn_mod_exp */

+        NULL, /* init */

+        NULL, /* finish */

+        0, /* flags */

+        NULL /* app_data */

+        };

+#endif

+

+#ifndef OPENSSL_NO_DH

+/* Our internal DH_METHOD that we provide pointers to */

+static DH_METHOD ibmca_dh =

+        {

+        "Ibmca DH method",

+        NULL,

+        NULL,

+        ibmca_mod_exp_dh,

+        NULL,

+        NULL,

+        0,

+        NULL

+        };

+#endif

+

+static RAND_METHOD ibmca_rand =

+        {

+        /* "IBMCA RAND method", */

+        NULL,

+        ibmca_rand_bytes,

+        NULL,

+        NULL,

+        ibmca_rand_bytes,

+        ibmca_rand_status,

+        };

+

+/* Constants used when creating the ENGINE */

+static const char *engine_ibmca_id = "ibmca";

+static const char *engine_ibmca_name = "Ibmca hardware engine support";

+

+/* This internal function is used by ENGINE_ibmca() and possibly by the

+ * "dynamic" ENGINE support too */

+static int bind_helper(ENGINE *e)

+	{

+#ifndef OPENSSL_NO_RSA

+	const RSA_METHOD *meth1;

+#endif

+#ifndef OPENSSL_NO_DSA

+	const DSA_METHOD *meth2;

+#endif

+#ifndef OPENSSL_NO_DH

+	const DH_METHOD *meth3;

+#endif

+	if(!ENGINE_set_id(e, engine_ibmca_id) ||

+		!ENGINE_set_name(e, engine_ibmca_name) ||

+#ifndef OPENSSL_NO_RSA

+		!ENGINE_set_RSA(e, &ibmca_rsa) ||

+#endif

+#ifndef OPENSSL_NO_DSA

+		!ENGINE_set_DSA(e, &ibmca_dsa) ||

+#endif

+#ifndef OPENSSL_NO_DH

+		!ENGINE_set_DH(e, &ibmca_dh) ||

+#endif

+		!ENGINE_set_RAND(e, &ibmca_rand) ||

+		!ENGINE_set_destroy_function(e, ibmca_destroy) ||

+		!ENGINE_set_init_function(e, ibmca_init) ||

+		!ENGINE_set_finish_function(e, ibmca_finish) ||

+		!ENGINE_set_ctrl_function(e, ibmca_ctrl) ||

+		!ENGINE_set_cmd_defns(e, ibmca_cmd_defns))

+		return 0;

+

+#ifndef OPENSSL_NO_RSA

+	/* We know that the "PKCS1_SSLeay()" functions hook properly

+	 * to the ibmca-specific mod_exp and mod_exp_crt so we use

+	 * those functions. NB: We don't use ENGINE_openssl() or

+	 * anything "more generic" because something like the RSAref

+	 * code may not hook properly, and if you own one of these

+	 * cards then you have the right to do RSA operations on it

+	 * anyway! */ 

+	meth1 = RSA_PKCS1_SSLeay();

+	ibmca_rsa.rsa_pub_enc = meth1->rsa_pub_enc;

+	ibmca_rsa.rsa_pub_dec = meth1->rsa_pub_dec;

+	ibmca_rsa.rsa_priv_enc = meth1->rsa_priv_enc;

+	ibmca_rsa.rsa_priv_dec = meth1->rsa_priv_dec;

+#endif

+

+#ifndef OPENSSL_NO_DSA

+	/* Use the DSA_OpenSSL() method and just hook the mod_exp-ish

+	 * bits. */

+	meth2 = DSA_OpenSSL();

+	ibmca_dsa.dsa_do_sign = meth2->dsa_do_sign;

+	ibmca_dsa.dsa_sign_setup = meth2->dsa_sign_setup;

+	ibmca_dsa.dsa_do_verify = meth2->dsa_do_verify;

+#endif

+

+#ifndef OPENSSL_NO_DH

+	/* Much the same for Diffie-Hellman */

+	meth3 = DH_OpenSSL();

+	ibmca_dh.generate_key = meth3->generate_key;

+	ibmca_dh.compute_key = meth3->compute_key;

+#endif

+

+	/* Ensure the ibmca error handling is set up */

+	ERR_load_IBMCA_strings(); 

+	return 1;

+	}

+

+static ENGINE *engine_ibmca(void)

+	{

+	ENGINE *ret = ENGINE_new();

+	if(!ret)

+		return NULL;

+	if(!bind_helper(ret))

+		{

+		ENGINE_free(ret);

+		return NULL;

+		}

+	return ret;

+	}

+

+#ifdef ENGINE_DYNAMIC_SUPPORT

+static

+#endif

+void ENGINE_load_ibmca(void)

+	{

+	/* Copied from eng_[openssl|dyn].c */

+	ENGINE *toadd = engine_ibmca();

+	if(!toadd) return;

+	ENGINE_add(toadd);

+	ENGINE_free(toadd);

+	ERR_clear_error();

+	}

+

+/* Destructor (complements the "ENGINE_ibmca()" constructor) */

+static int ibmca_destroy(ENGINE *e)

+	{

+	/* Unload the ibmca error strings so any error state including our

+	 * functs or reasons won't lead to a segfault (they simply get displayed

+	 * without corresponding string data because none will be found). */

+        ERR_unload_IBMCA_strings(); 

+	return 1;

+	}

+

+

+/* This is a process-global DSO handle used for loading and unloading

+ * the Ibmca library. NB: This is only set (or unset) during an

+ * init() or finish() call (reference counts permitting) and they're

+ * operating with global locks, so this should be thread-safe

+ * implicitly. */

+

+static DSO *ibmca_dso = NULL;

+

+/* These are the function pointers that are (un)set when the library has

+ * successfully (un)loaded. */

+

+static unsigned int    (ICA_CALL *p_icaOpenAdapter)();

+static unsigned int    (ICA_CALL *p_icaCloseAdapter)();

+static unsigned int    (ICA_CALL *p_icaRsaModExpo)();

+static unsigned int    (ICA_CALL *p_icaRandomNumberGenerate)();

+static unsigned int    (ICA_CALL *p_icaRsaCrt)();

+

+/* utility function to obtain a context */

+static int get_context(ICA_ADAPTER_HANDLE *p_handle)

+        {

+        unsigned int status=0;

+

+        status = p_icaOpenAdapter(0, p_handle);

+        if(status != 0)

+                return 0;

+        return 1;

+        }

+

+/* similarly to release one. */

+static void release_context(ICA_ADAPTER_HANDLE handle)

+        {

+        p_icaCloseAdapter(handle);

+        }

+

+/* (de)initialisation functions. */

+static int ibmca_init(ENGINE *e)

+        {

+

+        void          (*p1)();

+        void          (*p2)();

+        void          (*p3)();

+        void          (*p4)();

+        void          (*p5)();

+

+        if(ibmca_dso != NULL)

+                {

+                IBMCAerr(IBMCA_F_IBMCA_INIT,IBMCA_R_ALREADY_LOADED);

+                goto err;

+                }

+        /* Attempt to load libatasi.so/atasi.dll/whatever. Needs to be

+         * changed unfortunately because the Ibmca drivers don't have

+         * standard library names that can be platform-translated well. */

+        /* TODO: Work out how to actually map to the names the Ibmca

+         * drivers really use - for now a symbollic link needs to be

+         * created on the host system from libatasi.so to atasi.so on

+         * unix variants. */

+

+	/* WJH XXX check name translation */

+

+        ibmca_dso = DSO_load(NULL, IBMCA_LIBNAME, NULL,

+			     /* DSO_FLAG_NAME_TRANSLATION */ 0);

+        if(ibmca_dso == NULL)

+                {

+                IBMCAerr(IBMCA_F_IBMCA_INIT,IBMCA_R_DSO_FAILURE);

+                goto err;

+                }

+

+        if(!(p1 = DSO_bind_func(

+                ibmca_dso, IBMCA_F1)) ||

+                !(p2 = DSO_bind_func(

+                        ibmca_dso, IBMCA_F2)) ||

+                !(p3 = DSO_bind_func(

+                        ibmca_dso, IBMCA_F3)) ||

+                !(p4 = DSO_bind_func(

+                        ibmca_dso, IBMCA_F4)) ||

+                !(p5 = DSO_bind_func(

+                        ibmca_dso, IBMCA_F5)))

+                {

+                IBMCAerr(IBMCA_F_IBMCA_INIT,IBMCA_R_DSO_FAILURE);

+                goto err;

+                }

+

+        /* Copy the pointers */

+

+	p_icaOpenAdapter =           (unsigned int (ICA_CALL *)())p1;

+	p_icaCloseAdapter =          (unsigned int (ICA_CALL *)())p2;

+	p_icaRsaModExpo =            (unsigned int (ICA_CALL *)())p3;

+	p_icaRandomNumberGenerate =  (unsigned int (ICA_CALL *)())p4;

+	p_icaRsaCrt =                (unsigned int (ICA_CALL *)())p5;

+

+        if(!get_context(&handle))

+                {

+                IBMCAerr(IBMCA_F_IBMCA_INIT,IBMCA_R_UNIT_FAILURE);

+                goto err;

+                }

+

+        return 1;

+ err:

+        if(ibmca_dso)

+                DSO_free(ibmca_dso);

+

+        p_icaOpenAdapter = NULL;

+        p_icaCloseAdapter = NULL;

+        p_icaRsaModExpo = NULL;

+        p_icaRandomNumberGenerate = NULL;

+

+        return 0;

+        }

+

+static int ibmca_finish(ENGINE *e)

+        {

+        if(ibmca_dso == NULL)

+                {

+                IBMCAerr(IBMCA_F_IBMCA_FINISH,IBMCA_R_NOT_LOADED);

+                return 0;

+                }

+        release_context(handle);

+        if(!DSO_free(ibmca_dso))

+                {

+                IBMCAerr(IBMCA_F_IBMCA_FINISH,IBMCA_R_DSO_FAILURE);

+                return 0;

+                }

+        ibmca_dso = NULL;

+

+        return 1;

+        }

+

+static int ibmca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())

+	{

+	int initialised = ((ibmca_dso == NULL) ? 0 : 1);

+	switch(cmd)

+		{

+	case IBMCA_CMD_SO_PATH:

+		if(p == NULL)

+			{

+			IBMCAerr(IBMCA_F_IBMCA_CTRL,ERR_R_PASSED_NULL_PARAMETER);

+			return 0;

+			}

+		if(initialised)

+			{

+			IBMCAerr(IBMCA_F_IBMCA_CTRL,IBMCA_R_ALREADY_LOADED);

+			return 0;

+			}

+		IBMCA_LIBNAME = (const char *)p;

+		return 1;

+	default:

+		break;

+		}

+	IBMCAerr(IBMCA_F_IBMCA_CTRL,IBMCA_R_CTRL_COMMAND_NOT_IMPLEMENTED);

+	return 0;

+	}

+

+

+static int ibmca_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,

+        const BIGNUM *m, BN_CTX *ctx)

+        {

+        /* I need somewhere to store temporary serialised values for

+         * use with the Ibmca API calls. A neat cheat - I'll use

+         * BIGNUMs from the BN_CTX but access their arrays directly as

+         * byte arrays <grin>. This way I don't have to clean anything

+         * up. */

+

+        BIGNUM *argument=NULL;

+        BIGNUM *result=NULL;

+        BIGNUM *key=NULL;

+        int to_return;

+	int inLen, outLen, tmpLen;

+

+

+        ICA_KEY_RSA_MODEXPO *publKey=NULL;

+        unsigned int rc;

+

+        to_return = 0; /* expect failure */

+

+        if(!ibmca_dso)

+                {

+                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_NOT_LOADED);

+                goto err;

+                }

+        /* Prepare the params */

+	BN_CTX_start(ctx);

+        argument = BN_CTX_get(ctx);

+        result = BN_CTX_get(ctx);

+        key = BN_CTX_get(ctx);

+

+        if( !argument || !result || !key)

+                {

+                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_BN_CTX_FULL);

+                goto err;

+                }

+

+

+	if(!bn_wexpand(argument, m->top) || !bn_wexpand(result, m->top) ||

+                !bn_wexpand(key, sizeof(*publKey)/BN_BYTES))

+

+                {

+                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_BN_EXPAND_FAIL);

+                goto err;

+                }

+

+        publKey = (ICA_KEY_RSA_MODEXPO *)key->d;

+

+        if (publKey == NULL)

+                {

+                goto err;

+                }

+        memset(publKey, 0, sizeof(ICA_KEY_RSA_MODEXPO));

+

+        publKey->keyType   =  CORRECT_ENDIANNESS(ME_KEY_TYPE);

+        publKey->keyLength =  CORRECT_ENDIANNESS(sizeof(ICA_KEY_RSA_MODEXPO));

+        publKey->expOffset =  (char *) publKey->keyRecord - (char *) publKey;

+

+        /* A quirk of the card: the exponent length has to be the same

+     as the modulus (key) length */

+

+	outLen = BN_num_bytes(m);

+

+/* check for modulus length SAB*/

+	if (outLen > 256 ) {

+		IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_MEXP_LENGTH_TO_LARGE);

+		goto err;

+	}

+/* check for modulus length SAB*/

+

+

+	publKey->expLength = publKey->nLength = outLen;

+/* SAB Check for underflow condition

+    the size of the exponent is less than the size of the parameter

+    then we have a big problem and will underflow the keyRecord

+   buffer.  Bad stuff could happen then

+*/

+if (outLen < BN_num_bytes(p)){

+	IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_UNDERFLOW_KEYRECORD);

+	goto err;

+}

+/* SAB End check for underflow */

+

+

+        BN_bn2bin(p, &publKey->keyRecord[publKey->expLength -

+                BN_num_bytes(p)]);

+        BN_bn2bin(m, &publKey->keyRecord[publKey->expLength]);

+

+

+

+        publKey->modulusBitLength = CORRECT_ENDIANNESS(publKey->nLength * 8);

+        publKey->nOffset   = CORRECT_ENDIANNESS(publKey->expOffset + 

+						publKey->expLength);

+

+        publKey->expOffset = CORRECT_ENDIANNESS((char *) publKey->keyRecord - 

+						(char *) publKey);

+

+	tmpLen = outLen;

+	publKey->expLength = publKey->nLength = CORRECT_ENDIANNESS(tmpLen);

+

+  /* Prepare the argument */

+

+	memset(argument->d, 0, outLen);

+	BN_bn2bin(a, (unsigned char *)argument->d + outLen -

+                 BN_num_bytes(a));

+

+	inLen = outLen;

+

+  /* Perform the operation */

+

+          if( (rc = p_icaRsaModExpo(handle, inLen,(unsigned char *)argument->d,

+                publKey, &outLen, (unsigned char *)result->d))

+                !=0 )

+

+                {

+                printf("rc = %d\n", rc);

+                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_REQUEST_FAILED);

+                goto err;

+                }

+

+

+        /* Convert the response */

+        BN_bin2bn((unsigned char *)result->d, outLen, r);

+        to_return = 1;

+ err:

+	BN_CTX_end(ctx);

+        return to_return;

+        }

+

+#ifndef OPENSSL_NO_RSA 

+static int ibmca_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)

+        {

+        BN_CTX *ctx;

+        int to_return = 0;

+

+        if((ctx = BN_CTX_new()) == NULL)

+                goto err;

+        if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)

+                {

+                if(!rsa->d || !rsa->n)

+                        {

+                        IBMCAerr(IBMCA_F_IBMCA_RSA_MOD_EXP,

+                                IBMCA_R_MISSING_KEY_COMPONENTS);

+                        goto err;

+                        }

+                to_return = ibmca_mod_exp(r0, I, rsa->d, rsa->n, ctx);

+                }

+        else

+                {

+                to_return = ibmca_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,

+                        rsa->dmq1, rsa->iqmp, ctx);

+                }

+ err:

+        if(ctx)

+                BN_CTX_free(ctx);

+        return to_return;

+        }

+#endif

+

+/* Ein kleines chinesisches "Restessen"  */

+static int ibmca_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,

+        const BIGNUM *q, const BIGNUM *dmp1,

+        const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx)

+        {

+

+        BIGNUM *argument = NULL;

+        BIGNUM *result = NULL;

+        BIGNUM *key = NULL;

+

+        int to_return = 0; /* expect failure */

+

+        char                *pkey=NULL;

+        ICA_KEY_RSA_CRT     *privKey=NULL;

+        int inLen, outLen;

+

+        int rc;

+        unsigned int        offset, pSize, qSize;

+/* SAB New variables */

+	unsigned int keyRecordSize;

+	unsigned int pbytes = BN_num_bytes(p);

+	unsigned int qbytes = BN_num_bytes(q);

+	unsigned int dmp1bytes = BN_num_bytes(dmp1);

+	unsigned int dmq1bytes = BN_num_bytes(dmq1);

+	unsigned int iqmpbytes = BN_num_bytes(iqmp);

+

+        /* Prepare the params */

+

+	BN_CTX_start(ctx);

+        argument = BN_CTX_get(ctx);

+        result = BN_CTX_get(ctx);

+        key = BN_CTX_get(ctx);

+

+        if(!argument || !result || !key)

+                {

+                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_BN_CTX_FULL);

+                goto err;

+                }

+

+	if(!bn_wexpand(argument, p->top + q->top) ||

+                !bn_wexpand(result, p->top + q->top) ||

+                !bn_wexpand(key, sizeof(*privKey)/BN_BYTES ))

+                {

+                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_BN_EXPAND_FAIL);

+                goto err;

+                }

+

+

+        privKey = (ICA_KEY_RSA_CRT *)key->d;

+/* SAB Add check for total size in bytes of the parms does not exceed

+   the buffer space we have

+   do this first

+*/

+      keyRecordSize = pbytes+qbytes+dmp1bytes+dmq1bytes+iqmpbytes;

+     if (  keyRecordSize > sizeof(privKey->keyRecord )) {

+	 IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_OPERANDS_TO_LARGE);

+         goto err;

+     }

+

+     if ( (qbytes + dmq1bytes)  > 256 ){

+	 IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_OPERANDS_TO_LARGE);

+         goto err;

+     }

+

+     if ( pbytes + dmp1bytes > 256 ) {

+	 IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_OPERANDS_TO_LARGE);

+         goto err;

+     }

+

+/* end SAB additions */

+  

+        memset(privKey, 0, sizeof(ICA_KEY_RSA_CRT));

+        privKey->keyType =  CORRECT_ENDIANNESS(CRT_KEY_TYPE);

+        privKey->keyLength = CORRECT_ENDIANNESS(sizeof(ICA_KEY_RSA_CRT));

+        privKey->modulusBitLength = 

+	  CORRECT_ENDIANNESS(BN_num_bytes(q) * 2 * 8);

+

+        /*

+         * p,dp & qInv are 1 QWORD Larger

+         */

+        privKey->pLength = CORRECT_ENDIANNESS(BN_num_bytes(p)+8);

+        privKey->qLength = CORRECT_ENDIANNESS(BN_num_bytes(q));

+        privKey->dpLength = CORRECT_ENDIANNESS(BN_num_bytes(dmp1)+8);

+        privKey->dqLength = CORRECT_ENDIANNESS(BN_num_bytes(dmq1));

+        privKey->qInvLength = CORRECT_ENDIANNESS(BN_num_bytes(iqmp)+8);

+

+        offset = (char *) privKey->keyRecord

+                  - (char *) privKey;

+

+        qSize = BN_num_bytes(q);

+        pSize = qSize + 8;   /*  1 QWORD larger */

+

+

+/* SAB  probably aittle redundant, but we'll verify that each of the

+   components which make up a key record sent ot the card does not exceed

+   the space that is allocated for it.  this handles the case where even if

+   the total length does not exceed keyrecord zied, if the operands are funny sized

+they could cause potential side affects on either the card or the result */

+

+     if ( (pbytes > pSize) || (dmp1bytes > pSize) ||

+          (iqmpbytes > pSize) || ( qbytes >qSize) ||

+          (dmq1bytes > qSize) ) {

+		IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT, IBMCA_R_OPERANDS_TO_LARGE);

+		goto err;

+

+	}

+     

+

+        privKey->dpOffset = CORRECT_ENDIANNESS(offset);

+

+	offset += pSize;

+	privKey->dqOffset = CORRECT_ENDIANNESS(offset);

+

+	offset += qSize;

+	privKey->pOffset = CORRECT_ENDIANNESS(offset);

+

+	offset += pSize;

+	privKey->qOffset = CORRECT_ENDIANNESS(offset);

+

+	offset += qSize;

+	privKey->qInvOffset = CORRECT_ENDIANNESS(offset);

+

+        pkey = (char *) privKey->keyRecord;

+

+

+/* SAB first check that we don;t under flow the buffer */

+	if ( pSize < pbytes ) {

+		IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT, IBMCA_R_UNDERFLOW_CONDITION);

+		goto err;

+	}

+

+        /* pkey += pSize - BN_num_bytes(p); WROING this should be dmp1) */

+        pkey += pSize - BN_num_bytes(dmp1);

+        BN_bn2bin(dmp1, pkey);   

+        pkey += BN_num_bytes(dmp1);  /* move the pointer */

+

+        BN_bn2bin(dmq1, pkey);  /* Copy over dmq1 */

+

+        pkey += qSize;     /* move pointer */

+	pkey += pSize - BN_num_bytes(p);  /* set up for zero padding of next field */

+

+        BN_bn2bin(p, pkey);

+        pkey += BN_num_bytes(p);  /* increment pointer by number of bytes moved  */

+

+        BN_bn2bin(q, pkey);

+        pkey += qSize ;  /* move the pointer */

+	pkey +=  pSize - BN_num_bytes(iqmp); /* Adjust for padding */

+        BN_bn2bin(iqmp, pkey);

+

+        /* Prepare the argument and response */

+

+	outLen = CORRECT_ENDIANNESS(privKey->qLength) * 2;  /* Correct endianess is used 

+						because the fields were converted above */

+

+        if (outLen > 256) {

+		IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_OUTLEN_TO_LARGE);

+		goto err;

+	}

+

+	/* SAB check for underflow here on the argeument */

+	if ( outLen < BN_num_bytes(a)) {

+		IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_UNDERFLOW_CONDITION);

+		goto err;

+	}

+

+        BN_bn2bin(a, (unsigned char *)argument->d + outLen -

+                          BN_num_bytes(a));

+        inLen = outLen;

+

+        memset(result->d, 0, outLen);

+

+        /* Perform the operation */

+

+        if ( (rc = p_icaRsaCrt(handle, inLen, (unsigned char *)argument->d,

+                privKey, &outLen, (unsigned char *)result->d)) != 0)

+                {

+                printf("rc = %d\n", rc);

+                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_REQUEST_FAILED);

+                goto err;

+                }

+

+        /* Convert the response */

+

+        BN_bin2bn((unsigned char *)result->d, outLen, r);

+        to_return = 1;

+

+ err:

+	BN_CTX_end(ctx);

+        return to_return;

+

+        }

+

+#ifndef OPENSSL_NO_DSA

+/* This code was liberated and adapted from the commented-out code in

+ * dsa_ossl.c. Because of the unoptimised form of the Ibmca acceleration

+ * (it doesn't have a CRT form for RSA), this function means that an

+ * Ibmca system running with a DSA server certificate can handshake

+ * around 5 or 6 times faster/more than an equivalent system running with

+ * RSA. Just check out the "signs" statistics from the RSA and DSA parts

+ * of "openssl speed -engine ibmca dsa1024 rsa1024". */

+static int ibmca_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,

+        BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,

+        BN_CTX *ctx, BN_MONT_CTX *in_mont)

+        {

+        BIGNUM t;

+        int to_return = 0;

+

+        BN_init(&t);

+        /* let rr = a1 ^ p1 mod m */

+        if (!ibmca_mod_exp(rr,a1,p1,m,ctx)) goto end;

+        /* let t = a2 ^ p2 mod m */

+        if (!ibmca_mod_exp(&t,a2,p2,m,ctx)) goto end;

+        /* let rr = rr * t mod m */

+        if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;

+        to_return = 1;

+ end:

+        BN_free(&t);

+        return to_return;

+        }

+

+

+static int ibmca_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,

+        const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,

+        BN_MONT_CTX *m_ctx)

+        {

+        return ibmca_mod_exp(r, a, p, m, ctx);

+        }

+#endif

+

+/* This function is aliased to mod_exp (with the mont stuff dropped). */

+static int ibmca_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,

+        const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)

+        {

+        return ibmca_mod_exp(r, a, p, m, ctx);

+        }

+

+#ifndef OPENSSL_NO_DH 

+/* This function is aliased to mod_exp (with the dh and mont dropped). */

+static int ibmca_mod_exp_dh(DH const *dh, BIGNUM *r, 

+	const BIGNUM *a, const BIGNUM *p, 

+	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)

+        {

+        return ibmca_mod_exp(r, a, p, m, ctx);

+        }

+#endif

+

+/* Random bytes are good */

+static int ibmca_rand_bytes(unsigned char *buf, int num)

+        {

+        int to_return = 0; /* assume failure */

+        unsigned int ret;

+

+

+        if(handle == 0)

+                {

+                IBMCAerr(IBMCA_F_IBMCA_RAND_BYTES,IBMCA_R_NOT_INITIALISED);

+                goto err;

+                }

+

+        ret = p_icaRandomNumberGenerate(handle, num, buf);

+        if (ret < 0)

+                {

+                IBMCAerr(IBMCA_F_IBMCA_RAND_BYTES,IBMCA_R_REQUEST_FAILED);

+                goto err;

+                }

+        to_return = 1;

+ err:

+        return to_return;

+        }

+

+static int ibmca_rand_status(void)

+        {

+        return 1;

+        }

+

+/* This stuff is needed if this ENGINE is being compiled into a self-contained

+ * shared-library. */

+#ifdef ENGINE_DYNAMIC_SUPPORT

+static int bind_fn(ENGINE *e, const char *id)

+	{

+	if(id && (strcmp(id, engine_ibmca_id) != 0))  /* WJH XXX */

+		return 0;

+	if(!bind_helper(e))

+		return 0;

+	return 1;

+	}

+IMPLEMENT_DYNAMIC_CHECK_FN()

+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)

+#endif /* ENGINE_DYNAMIC_SUPPORT */

+

+

+#endif /* !OPENSSL_NO_HW_IBMCA */

+#endif /* !OPENSSL_NO_HW */

diff --git a/openssl/demos/engines/ibmca/hw_ibmca.ec b/openssl/demos/engines/ibmca/hw_ibmca.ec
new file mode 100644
index 0000000..f68646d
--- /dev/null
+++ b/openssl/demos/engines/ibmca/hw_ibmca.ec
@@ -0,0 +1,8 @@
+# configuration file for util/mkerr.pl
+#
+# use like this:
+#
+#	perl ../../../util/mkerr.pl -conf hw_ibmca.ec \
+#		-nostatic -staticloader -write *.c
+
+L IBMCA		hw_ibmca_err.h			hw_ibmca_err.c
diff --git a/openssl/demos/engines/ibmca/hw_ibmca_err.c b/openssl/demos/engines/ibmca/hw_ibmca_err.c
new file mode 100644
index 0000000..c4053f6
--- /dev/null
+++ b/openssl/demos/engines/ibmca/hw_ibmca_err.c
@@ -0,0 +1,154 @@
+/* hw_ibmca_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "hw_ibmca_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+static ERR_STRING_DATA IBMCA_str_functs[]=
+	{
+{ERR_PACK(0,IBMCA_F_IBMCA_CTRL,0),	"IBMCA_CTRL"},
+{ERR_PACK(0,IBMCA_F_IBMCA_FINISH,0),	"IBMCA_FINISH"},
+{ERR_PACK(0,IBMCA_F_IBMCA_INIT,0),	"IBMCA_INIT"},
+{ERR_PACK(0,IBMCA_F_IBMCA_MOD_EXP,0),	"IBMCA_MOD_EXP"},
+{ERR_PACK(0,IBMCA_F_IBMCA_MOD_EXP_CRT,0),	"IBMCA_MOD_EXP_CRT"},
+{ERR_PACK(0,IBMCA_F_IBMCA_RAND_BYTES,0),	"IBMCA_RAND_BYTES"},
+{ERR_PACK(0,IBMCA_F_IBMCA_RSA_MOD_EXP,0),	"IBMCA_RSA_MOD_EXP"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA IBMCA_str_reasons[]=
+	{
+{IBMCA_R_ALREADY_LOADED                  ,"already loaded"},
+{IBMCA_R_BN_CTX_FULL                     ,"bn ctx full"},
+{IBMCA_R_BN_EXPAND_FAIL                  ,"bn expand fail"},
+{IBMCA_R_CTRL_COMMAND_NOT_IMPLEMENTED    ,"ctrl command not implemented"},
+{IBMCA_R_DSO_FAILURE                     ,"dso failure"},
+{IBMCA_R_MEXP_LENGTH_TO_LARGE            ,"mexp length to large"},
+{IBMCA_R_MISSING_KEY_COMPONENTS          ,"missing key components"},
+{IBMCA_R_NOT_INITIALISED                 ,"not initialised"},
+{IBMCA_R_NOT_LOADED                      ,"not loaded"},
+{IBMCA_R_OPERANDS_TO_LARGE               ,"operands to large"},
+{IBMCA_R_OUTLEN_TO_LARGE                 ,"outlen to large"},
+{IBMCA_R_REQUEST_FAILED                  ,"request failed"},
+{IBMCA_R_UNDERFLOW_CONDITION             ,"underflow condition"},
+{IBMCA_R_UNDERFLOW_KEYRECORD             ,"underflow keyrecord"},
+{IBMCA_R_UNIT_FAILURE                    ,"unit failure"},
+{0,NULL}
+	};
+
+#endif
+
+#ifdef IBMCA_LIB_NAME
+static ERR_STRING_DATA IBMCA_lib_name[]=
+        {
+{0	,IBMCA_LIB_NAME},
+{0,NULL}
+	};
+#endif
+
+
+static int IBMCA_lib_error_code=0;
+static int IBMCA_error_init=1;
+
+static void ERR_load_IBMCA_strings(void)
+	{
+	if (IBMCA_lib_error_code == 0)
+		IBMCA_lib_error_code=ERR_get_next_error_library();
+
+	if (IBMCA_error_init)
+		{
+		IBMCA_error_init=0;
+#ifndef OPENSSL_NO_ERR
+		ERR_load_strings(IBMCA_lib_error_code,IBMCA_str_functs);
+		ERR_load_strings(IBMCA_lib_error_code,IBMCA_str_reasons);
+#endif
+
+#ifdef IBMCA_LIB_NAME
+		IBMCA_lib_name->error = ERR_PACK(IBMCA_lib_error_code,0,0);
+		ERR_load_strings(0,IBMCA_lib_name);
+#endif
+		}
+	}
+
+static void ERR_unload_IBMCA_strings(void)
+	{
+	if (IBMCA_error_init == 0)
+		{
+#ifndef OPENSSL_NO_ERR
+		ERR_unload_strings(IBMCA_lib_error_code,IBMCA_str_functs);
+		ERR_unload_strings(IBMCA_lib_error_code,IBMCA_str_reasons);
+#endif
+
+#ifdef IBMCA_LIB_NAME
+		ERR_unload_strings(0,IBMCA_lib_name);
+#endif
+		IBMCA_error_init=1;
+		}
+	}
+
+static void ERR_IBMCA_error(int function, int reason, char *file, int line)
+	{
+	if (IBMCA_lib_error_code == 0)
+		IBMCA_lib_error_code=ERR_get_next_error_library();
+	ERR_PUT_error(IBMCA_lib_error_code,function,reason,file,line);
+	}
diff --git a/openssl/demos/engines/ibmca/hw_ibmca_err.h b/openssl/demos/engines/ibmca/hw_ibmca_err.h
new file mode 100644
index 0000000..2070f95
--- /dev/null
+++ b/openssl/demos/engines/ibmca/hw_ibmca_err.h
@@ -0,0 +1,102 @@
+/* ====================================================================
+ * Copyright (c) 2001-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_IBMCA_ERR_H
+#define HEADER_IBMCA_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_IBMCA_strings(void);
+static void ERR_unload_IBMCA_strings(void);
+static void ERR_IBMCA_error(int function, int reason, char *file, int line);
+#define IBMCAerr(f,r) ERR_IBMCA_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the IBMCA functions. */
+
+/* Function codes. */
+#define IBMCA_F_IBMCA_CTRL				 100
+#define IBMCA_F_IBMCA_FINISH				 101
+#define IBMCA_F_IBMCA_INIT				 102
+#define IBMCA_F_IBMCA_MOD_EXP				 103
+#define IBMCA_F_IBMCA_MOD_EXP_CRT			 104
+#define IBMCA_F_IBMCA_RAND_BYTES			 105
+#define IBMCA_F_IBMCA_RSA_MOD_EXP			 106
+
+/* Reason codes. */
+#define IBMCA_R_ALREADY_LOADED				 100
+#define IBMCA_R_BN_CTX_FULL				 101
+#define IBMCA_R_BN_EXPAND_FAIL				 102
+#define IBMCA_R_CTRL_COMMAND_NOT_IMPLEMENTED		 103
+#define IBMCA_R_DSO_FAILURE				 104
+#define IBMCA_R_MEXP_LENGTH_TO_LARGE			 105
+#define IBMCA_R_MISSING_KEY_COMPONENTS			 106
+#define IBMCA_R_NOT_INITIALISED				 107
+#define IBMCA_R_NOT_LOADED				 108
+#define IBMCA_R_OPERANDS_TO_LARGE			 109
+#define IBMCA_R_OUTLEN_TO_LARGE				 110
+#define IBMCA_R_REQUEST_FAILED				 111
+#define IBMCA_R_UNDERFLOW_CONDITION			 112
+#define IBMCA_R_UNDERFLOW_KEYRECORD			 113
+#define IBMCA_R_UNIT_FAILURE				 114
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/demos/engines/ibmca/ica_openssl_api.h b/openssl/demos/engines/ibmca/ica_openssl_api.h
new file mode 100644
index 0000000..c77e0fd
--- /dev/null
+++ b/openssl/demos/engines/ibmca/ica_openssl_api.h
@@ -0,0 +1,189 @@
+
+#ifndef __ICA_OPENSSL_API_H__
+#define __ICA_OPENSSL_API_H__
+
+/**
+ ** abstract data types for API
+ **/
+
+#define ICA_ADAPTER_HANDLE int
+
+#if defined(linux) || defined (_AIX)
+#define ICA_CALL 
+#endif
+
+#if defined(WIN32) || defined(_WIN32)
+#define ICA_CALL  __stdcall
+#endif
+
+/*------------------------------------------------*
+ | RSA defines and typedefs                       |
+ *------------------------------------------------*/
+ /*
+ * All data elements of the RSA key are in big-endian format
+ * Modulus-Exponent form of key
+ *
+ */
+ #define MAX_EXP_SIZE 256
+ #define MAX_MODULUS_SIZE 256
+ #define MAX_MODEXP_SIZE  (MAX_EXP_SIZE + MAX_MODULUS_SIZE)
+
+ #define MAX_OPERAND_SIZE  MAX_EXP_SIZE
+
+ typedef unsigned char ICA_KEY_RSA_MODEXPO_REC[MAX_MODEXP_SIZE];
+ /*
+ * All data elements of the RSA key are in big-endian format
+ * Chinese Remainder Thereom(CRT) form of key
+ * Used only for Decrypt, the encrypt form is typically Modulus-Exponent
+ *
+ */
+ #define MAX_BP_SIZE 136
+ #define MAX_BQ_SIZE 128
+ #define MAX_NP_SIZE 136
+ #define MAX_NQ_SIZE 128
+ #define MAX_QINV_SIZE 136
+ #define MAX_RSACRT_SIZE (MAX_BP_SIZE+MAX_BQ_SIZE+MAX_NP_SIZE+MAX_NQ_SIZE+MAX_QINV_SIZE)
+
+#define RSA_GEN_OPERAND_MAX   256 /* bytes */
+
+typedef unsigned char ICA_KEY_RSA_CRT_REC[MAX_RSACRT_SIZE];
+/*------------------------------------------------*
+ | RSA key token types                            |
+ *------------------------------------------------*/
+
+#define  RSA_PUBLIC_MODULUS_EXPONENT        3
+#define  RSA_PKCS_PRIVATE_CHINESE_REMAINDER 6
+
+#define KEYTYPE_MODEXPO         1
+#define KEYTYPE_PKCSCRT         2
+
+
+/*------------------------------------------------*
+ | RSA Key Token format                           |
+ *------------------------------------------------*/
+
+/*
+ * NOTE:  All the fields in the ICA_KEY_RSA_MODEXPO structure
+ *        (lengths, offsets, exponents, modulus, etc.) are
+ *        stored in big-endian format
+ */
+
+typedef struct _ICA_KEY_RSA_MODEXPO
+{   unsigned int  keyType;             /* RSA key type.               */
+    unsigned int  keyLength;           /* Total length of the token.  */
+    unsigned int  modulusBitLength;    /* Modulus n bit length.       */
+                                       /* -- Start of the data length.*/
+    unsigned int  nLength;             /* Modulus n = p * q           */
+    unsigned int  expLength;           /* exponent (public or private)*/
+                                       /*   e = 1/d * mod(p-1)(q-1)   */
+                                       /* -- Start of the data offsets*/
+    unsigned int  nOffset;             /* Modulus n .                 */
+    unsigned int  expOffset;           /* exponent (public or private)*/
+    unsigned char reserved[112];       /* reserved area               */
+                                       /* -- Start of the variable -- */
+                                       /* -- length token data.    -- */
+    ICA_KEY_RSA_MODEXPO_REC keyRecord;
+} ICA_KEY_RSA_MODEXPO;
+#define SZ_HEADER_MODEXPO (sizeof(ICA_KEY_RSA_MODEXPO) - sizeof(ICA_KEY_RSA_MODEXPO_REC))
+
+/*
+ * NOTE:  All the fields in the ICA_KEY_RSA_CRT structure
+ *        (lengths, offsets, exponents, modulus, etc.) are
+ *        stored in big-endian format
+ */
+
+typedef struct _ICA_KEY_RSA_CRT
+{   unsigned int  keyType;             /* RSA key type.               */
+    unsigned int  keyLength;           /* Total length of the token.  */
+    unsigned int  modulusBitLength;    /* Modulus n bit length.       */
+                                       /* -- Start of the data length.*/
+#if _AIX
+    unsigned int  nLength;             /* Modulus n = p * q           */
+#endif
+    unsigned int  pLength;             /* Prime number p .            */
+    unsigned int  qLength;             /* Prime number q .            */
+    unsigned int  dpLength;            /* dp = d * mod(p-1) .         */
+    unsigned int  dqLength;            /* dq = d * mod(q-1) .         */
+    unsigned int  qInvLength;          /* PKCS: qInv = Ap/q           */
+                                       /* -- Start of the data offsets*/
+#if _AIX
+    unsigned int  nOffset;             /* Modulus n .                 */
+#endif
+    unsigned int  pOffset;             /* Prime number p .            */
+    unsigned int  qOffset;             /* Prime number q .            */
+    unsigned int  dpOffset;            /* dp .                        */
+    unsigned int  dqOffset;            /* dq .                        */
+    unsigned int  qInvOffset;          /* qInv for PKCS               */
+#if _AIX
+    unsigned char reserved[80];        /* reserved area               */
+#else
+    unsigned char reserved[88];        /* reserved area               */
+#endif
+                                       /* -- Start of the variable -- */
+                                       /* -- length token data.    -- */
+    ICA_KEY_RSA_CRT_REC keyRecord;
+} ICA_KEY_RSA_CRT;
+#define SZ_HEADER_CRT (sizeof(ICA_KEY_RSA_CRT) - sizeof(ICA_KEY_RSA_CRT_REC))
+
+unsigned int
+icaOpenAdapter( unsigned int        adapterId,
+	        ICA_ADAPTER_HANDLE *pAdapterHandle );
+
+unsigned int
+icaCloseAdapter( ICA_ADAPTER_HANDLE adapterHandle );
+
+unsigned int
+icaRsaModExpo( ICA_ADAPTER_HANDLE    hAdapterHandle,
+	       unsigned int          inputDataLength,
+	       unsigned char        *pInputData,
+	       ICA_KEY_RSA_MODEXPO  *pKeyModExpo,
+	       unsigned int         *pOutputDataLength,
+	       unsigned char        *pOutputData );
+
+unsigned int
+icaRsaCrt( ICA_ADAPTER_HANDLE     hAdapterHandle,
+	   unsigned int           inputDataLength,
+	   unsigned char         *pInputData,
+	   ICA_KEY_RSA_CRT       *pKeyCrt,
+	   unsigned int          *pOutputDataLength,
+	   unsigned char         *pOutputData );
+
+unsigned int
+icaRandomNumberGenerate( ICA_ADAPTER_HANDLE  hAdapterHandle,
+			 unsigned int        outputDataLength,
+			 unsigned char      *pOutputData );
+
+/* Specific macros and definitions to not have IFDEF;s all over the
+   main code */
+
+#if (_AIX)
+static const char *IBMCA_LIBNAME = "/lib/libica.a(shr.o)";
+#elif (WIN32)
+static const char *IBMCA_LIBNAME = "cryptica";
+#else
+static const char *IBMCA_LIBNAME = "ica";
+#endif
+
+#if (WIN32)
+/*
+ The ICA_KEY_RSA_MODEXPO & ICA_KEY_RSA_CRT lengths and
+ offsets must be in big-endian format.
+
+*/
+#define CORRECT_ENDIANNESS(b) (  \
+                             (((unsigned long) (b) & 0x000000ff) << 24) |  \
+                             (((unsigned long) (b) & 0x0000ff00) <<  8) |  \
+                             (((unsigned long) (b) & 0x00ff0000) >>  8) |  \
+                             (((unsigned long) (b) & 0xff000000) >> 24)    \
+                             )
+#define CRT_KEY_TYPE   RSA_PKCS_PRIVATE_CHINESE_REMAINDER
+#define ME_KEY_TYPE    RSA_PUBLIC_MODULUS_EXPONENT
+#else
+#define CORRECT_ENDIANNESS(b) (b)
+#define CRT_KEY_TYPE       KEYTYPE_PKCSCRT
+#define ME_KEY_TYPE        KEYTYPE_MODEXPO
+#endif
+
+
+
+#endif   /* __ICA_OPENSSL_API_H__ */
diff --git a/openssl/demos/engines/rsaref/Makefile b/openssl/demos/engines/rsaref/Makefile
new file mode 100644
index 0000000..63b8c79
--- /dev/null
+++ b/openssl/demos/engines/rsaref/Makefile
@@ -0,0 +1,135 @@
+LIBNAME=	librsaref
+SRC=		rsaref.c
+OBJ=		rsaref.o
+HEADER=		rsaref.h
+
+CC=		gcc
+PIC=		-fPIC
+CFLAGS=		-g -I../../../include $(PIC) -DENGINE_DYNAMIC_SUPPORT
+AR=		ar r
+RANLIB=		ranlib
+
+LIB=		$(LIBNAME).a
+SHLIB=		$(LIBNAME).so
+
+all:
+		@echo 'Please choose a system to build on:'
+		@echo ''
+		@echo 'tru64:    Tru64 Unix, Digital Unix, Digital OSF/1'
+		@echo 'solaris:  Solaris'
+		@echo 'irix:     IRIX'
+		@echo 'hpux32:   32-bit HP/UX'
+		@echo 'hpux64:   64-bit HP/UX'
+		@echo 'aix:      AIX'
+		@echo 'gnu:      Generic GNU-based system (gcc and GNU ld)'
+		@echo ''
+
+FORCE.install:
+install:	FORCE.install
+		cd install; \
+			make -f unix/makefile CFLAGS='-I. -DPROTOTYPES=1 -O -c' RSAREFLIB=librsaref.a librsaref.a
+
+FORCE.update:
+update:		FORCE.update
+		perl ../../../util/mkerr.pl -conf rsaref.ec \
+			-nostatic -staticloader -write rsaref.c
+
+darwin:		install $(SHLIB).darwin
+cygwin:		install $(SHLIB).cygwin
+gnu:		install $(SHLIB).gnu
+alpha-osf1:	install $(SHLIB).alpha-osf1
+tru64:		install $(SHLIB).tru64
+solaris:	install $(SHLIB).solaris
+irix:		install $(SHLIB).irix
+hpux32:		install $(SHLIB).hpux32
+hpux64:		install $(SHLIB).hpux64
+aix:		install $(SHLIB).aix
+reliantunix:	install $(SHLIB).reliantunix
+
+$(LIB):		$(OBJ)
+		$(AR) $(LIB) $(OBJ)
+		- $(RANLIB) $(LIB)
+
+LINK_SO=	\
+  ld -r -o $(LIBNAME).o $$ALLSYMSFLAGS $(LIB) install/librsaref.a && \
+  (nm -Pg $(LIBNAME).o | grep ' [BDT] ' | cut -f1 -d' ' > $(LIBNAME).exp; \
+   $$SHAREDCMD $$SHAREDFLAGS -o $(SHLIB) $(LIBNAME).o -L ../../.. -lcrypto -lc)
+
+$(SHLIB).darwin:	$(LIB) install/librsaref.a
+		ALLSYMSFLAGS='-all_load' \
+		SHAREDFLAGS='-dynamiclib -install_name $(SHLIB)' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).darwin
+$(SHLIB).cygwin:	$(LIB) install/librsaref.a
+		ALLSYMSFLAGS='--whole-archive' \
+		SHAREDFLAGS='-shared -Wl,-Bsymbolic -Wl,--out-implib,$(LIBNAME).dll.a' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).cygwin
+$(SHLIB).gnu:	$(LIB) install/librsaref.a
+		ALLSYMSFLAGS='--whole-archive' \
+		SHAREDFLAGS='-shared -Wl,-soname=$(SHLIB)' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).gnu
+$(SHLIB).tru64:	$(LIB) install/librsaref.a
+		ALLSYMSFLAGS='-all' \
+		SHAREDFLAGS='-shared' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).tru64
+$(SHLIB).solaris:	$(LIB) install/librsaref.a
+		ALLSYMSFLAGS='-z allextract' \
+		SHAREDFLAGS='-G -h $(SHLIB)' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).solaris
+$(SHLIB).irix:	$(LIB) install/librsaref.a
+		ALLSYMSFLAGS='-all' \
+		SHAREDFLAGS='-shared -Wl,-soname,$(SHLIB)' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).irix
+$(SHLIB).hpux32:	$(LIB) install/librsaref.a
+		ALLSYMSFLAGS='-Fl' \
+		SHAREDFLAGS='+vnocompatwarnings -b -z +s +h $(SHLIB)' \
+		SHAREDCMD='/usr/ccs/bin/ld'; \
+		$(LINK_SO)
+		touch $(SHLIB).hpux32
+$(SHLIB).hpux64:	$(LIB) install/librsaref.a
+		ALLSYMSFLAGS='+forceload' \
+		SHAREDFLAGS='-b -z +h $(SHLIB)' \
+		SHAREDCMD='/usr/ccs/bin/ld'; \
+		$(LINK_SO)
+		touch $(SHLIB).hpux64
+$(SHLIB).aix:	$(LIB) install/librsaref.a
+		ALLSYMSFLAGS='-bnogc' \
+		SHAREDFLAGS='-G -bE:$(LIBNAME).exp -bM:SRE' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).aix
+
+depend:
+		sed -e '/^# DO NOT DELETE.*/,$$d' < Makefile > Makefile.tmp
+		echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' >> Makefile.tmp
+		gcc -M $(CFLAGS) $(SRC) >> Makefile.tmp
+		perl ../../../util/clean-depend.pl < Makefile.tmp > Makefile.new
+		rm -f Makefile.tmp Makefile
+		mv Makefile.new Makefile
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+rsaref.o: ../../../include/openssl/asn1.h ../../../include/openssl/bio.h
+rsaref.o: ../../../include/openssl/bn.h ../../../include/openssl/crypto.h
+rsaref.o: ../../../include/openssl/dh.h ../../../include/openssl/dsa.h
+rsaref.o: ../../../include/openssl/e_os2.h ../../../include/openssl/engine.h
+rsaref.o: ../../../include/openssl/err.h ../../../include/openssl/lhash.h
+rsaref.o: ../../../include/openssl/opensslconf.h
+rsaref.o: ../../../include/openssl/opensslv.h
+rsaref.o: ../../../include/openssl/ossl_typ.h ../../../include/openssl/rand.h
+rsaref.o: ../../../include/openssl/rsa.h ../../../include/openssl/safestack.h
+rsaref.o: ../../../include/openssl/stack.h ../../../include/openssl/symhacks.h
+rsaref.o: ../../../include/openssl/ui.h rsaref.c rsaref_err.c rsaref_err.h
+rsaref.o: source/des.h source/global.h source/md2.h source/md5.h source/rsa.h
+rsaref.o: source/rsaref.h
diff --git a/openssl/demos/engines/rsaref/README b/openssl/demos/engines/rsaref/README
new file mode 100644
index 0000000..00b1f74
--- /dev/null
+++ b/openssl/demos/engines/rsaref/README
@@ -0,0 +1,22 @@
+librsaref.so is a demonstration dynamic engine that does RSA
+operations using the old RSAref 2.0 implementation.
+
+To make proper use of this engine, you must download RSAref 2.0
+(search the web for rsaref.tar.Z for example) and unpack it in this
+directory, so you'll end up having the subdirectories "install" and
+"source" among others.
+
+To build, do the following:
+
+	make
+
+This will list a number of available targets to choose from.  Most of
+them are architecture-specific.  The exception is "gnu" which is to be
+used on systems where GNU ld and gcc have been installed in such a way
+that gcc uses GNU ld to link together programs and shared libraries.
+
+The make file assumes you use gcc.  To change that, just reassign CC:
+
+	make CC=cc
+
+The result is librsaref.so, which you can copy to any place you wish.
diff --git a/openssl/demos/engines/rsaref/build.com b/openssl/demos/engines/rsaref/build.com
new file mode 100644
index 0000000..72b013d
--- /dev/null
+++ b/openssl/demos/engines/rsaref/build.com
@@ -0,0 +1,105 @@
+$! BUILD.COM -- Building procedure for the RSAref engine
+$
+$	if f$search("source.dir") .eqs. "" -
+	   .or. f$search("install.dir") .eqs. ""
+$	then
+$	    write sys$error "RSAref 2.0 hasn't been properly extracted."
+$	    exit
+$	endif
+$
+$	if (f$getsyi("cpu").lt.128)
+$	then
+$	    arch := vax
+$	else
+$	    arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$	    if (arch .eqs. "") then arch = "UNK"
+$	endif
+$
+$	_save_default = f$environment("default")
+$	set default [.install]
+$	files := desc,digit,md2c,md5c,nn,prime,-
+		rsa,r_encode,r_dh,r_enhanc,r_keygen,r_random,-
+		r_stdlib
+$	delete rsaref.olb;*
+$	library/create/object rsaref.olb
+$	files_i = 0
+$ rsaref_loop:
+$	files_e = f$edit(f$element(files_i,",",files),"trim")
+$	files_i = files_i + 1
+$	if files_e .eqs. "," then goto rsaref_loop_end
+$	cc/include=([-.source],[])/define=PROTOTYPES=1/object=[]'files_e'.obj -
+		[-.source]'files_e'.c
+$	library/replace/object rsaref.olb 'files_e'.obj
+$	goto rsaref_loop
+$ rsaref_loop_end:
+$
+$	set default [-]
+$	define/user openssl [---.include.openssl]
+$	cc/define=ENGINE_DYNAMIC_SUPPORT rsaref.c
+$
+$	if arch .eqs. "VAX"
+$	then
+$	    macro/object=rsaref_vec.obj sys$input:
+;
+; Transfer vector for VAX shareable image
+;
+	.TITLE librsaref
+;
+; Define macro to assist in building transfer vector entries.  Each entry
+; should take no more than 8 bytes.
+;
+	.MACRO FTRANSFER_ENTRY routine
+	.ALIGN QUAD
+	.TRANSFER routine
+	.MASK	routine
+	JMP	routine+2
+	.ENDM FTRANSFER_ENTRY
+;
+; Place entries in own program section.
+;
+	.PSECT $$LIBRSAREF,QUAD,PIC,USR,CON,REL,LCL,SHR,EXE,RD,NOWRT
+
+LIBRSAREF_xfer:
+	FTRANSFER_ENTRY bind_engine
+	FTRANSFER_ENTRY v_check
+
+;
+; Allocate extra storage at end of vector to allow for expansion.
+;
+	.BLKB 512-<.-LIBRSAREF_xfer>	; 1 page.
+	.END
+$	    link/share=librsaref.exe sys$input:/option
+!
+! Ensure transfer vector is at beginning of image
+!
+CLUSTER=FIRST
+COLLECT=FIRST,$$LIBRSAREF
+!
+! make psects nonshareable so image can be installed.
+!
+PSECT_ATTR=$CHAR_STRING_CONSTANTS,NOWRT
+[]rsaref_vec.obj
+[]rsaref.obj
+[.install]rsaref.olb/lib
+[---.vax.exe.crypto]libcrypto.olb/lib
+$	else
+$	    if arch_name .eqs. "ALPHA"
+$	    then
+$		link/share=librsaref.exe sys$input:/option
+[]rsaref.obj
+[.install]rsaref.olb/lib
+[---.alpha.exe.crypto]libcrypto.olb/lib
+symbol_vector=(bind_engine=procedure,v_check=procedure)
+$	    else
+$		if arch_name .eqs. "IA64"
+$		then
+$		    link /shareable=librsaref.exe sys$input: /options
+[]rsaref.obj
+[.install]rsaref.olb/lib
+[---.ia64.exe.crypto]libcrypto.olb/lib
+symbol_vector=(bind_engine=procedure,v_check=procedure)
+$		endif
+$	    endif
+$	endif
+$
+$	set default '_save_default'
diff --git a/openssl/demos/engines/rsaref/rsaref.c b/openssl/demos/engines/rsaref/rsaref.c
new file mode 100644
index 0000000..f97974f
--- /dev/null
+++ b/openssl/demos/engines/rsaref/rsaref.c
@@ -0,0 +1,685 @@
+/* Demo of how to construct your own engine and using it.  The basis of this
+   engine is RSAref, an old reference of the RSA algorithm which can still
+   be found a little here and there. */
+
+#include <stdio.h>
+#include <string.h>
+#include "./source/global.h"
+#include "./source/rsaref.h"
+#include "./source/rsa.h"
+#include "./source/des.h"
+#include <openssl/err.h>
+#define OPENSSL_NO_MD2
+#define OPENSSL_NO_MD5
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/engine.h>
+
+#define RSAREF_LIB_NAME "rsaref engine"
+#include "rsaref_err.c"
+
+/*****************************************************************************
+ *** Function declarations and global variable definitions                 ***
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Constants used when creating the ENGINE
+ **/
+static const char *engine_rsaref_id = "rsaref";
+static const char *engine_rsaref_name = "RSAref engine support";
+
+/*****************************************************************************
+ * Functions to handle the engine
+ **/
+static int rsaref_destroy(ENGINE *e);
+static int rsaref_init(ENGINE *e);
+static int rsaref_finish(ENGINE *e);
+#if 0
+static int rsaref_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); 
+#endif
+
+/*****************************************************************************
+ * Engine commands
+ **/
+static const ENGINE_CMD_DEFN rsaref_cmd_defns[] = {
+	{0, NULL, NULL, 0}
+	};
+
+/*****************************************************************************
+ * RSA functions
+ **/
+static int rsaref_private_decrypt(int len, const unsigned char *from,
+	unsigned char *to, RSA *rsa, int padding);
+static int rsaref_private_encrypt(int len, const unsigned char *from,
+	unsigned char *to, RSA *rsa, int padding);
+static int rsaref_public_encrypt(int len, const unsigned char *from,
+	unsigned char *to, RSA *rsa, int padding);
+static int rsaref_public_decrypt(int len, const unsigned char *from,
+	unsigned char *to, RSA *rsa, int padding);
+static int bnref_mod_exp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,const BIGNUM *m,
+			  BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+static int rsaref_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
+
+/*****************************************************************************
+ * Our RSA method
+ **/
+static RSA_METHOD rsaref_rsa =
+{
+  "RSAref PKCS#1 RSA",
+  rsaref_public_encrypt,
+  rsaref_public_decrypt,
+  rsaref_private_encrypt,
+  rsaref_private_decrypt,
+  rsaref_mod_exp,
+  bnref_mod_exp,
+  NULL,
+  NULL,
+  0,
+  NULL,
+  NULL,
+  NULL
+};
+
+/*****************************************************************************
+ * Symetric cipher and digest function registrars
+ **/
+static int rsaref_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
+	const int **nids, int nid);
+static int rsaref_digests(ENGINE *e, const EVP_MD **digest,
+	const int **nids, int nid);
+
+static int rsaref_cipher_nids[] =
+	{ NID_des_cbc, NID_des_ede3_cbc, NID_desx_cbc, 0 };
+static int rsaref_digest_nids[] =
+	{ NID_md2, NID_md5, 0 };
+
+/*****************************************************************************
+ * DES functions
+ **/
+static int cipher_des_cbc_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+	const unsigned char *iv, int enc);
+static int cipher_des_cbc_code(EVP_CIPHER_CTX *ctx, unsigned char *out,
+	const unsigned char *in, unsigned int inl);
+static int cipher_des_cbc_clean(EVP_CIPHER_CTX *);
+static int cipher_des_ede3_cbc_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+	const unsigned char *iv, int enc);
+static int cipher_des_ede3_cbc_code(EVP_CIPHER_CTX *ctx, unsigned char *out,
+	const unsigned char *in, unsigned int inl);
+static int cipher_des_ede3_cbc_clean(EVP_CIPHER_CTX *);
+static int cipher_desx_cbc_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+	const unsigned char *iv, int enc);
+static int cipher_desx_cbc_code(EVP_CIPHER_CTX *ctx, unsigned char *out,
+	const unsigned char *in, unsigned int inl);
+static int cipher_desx_cbc_clean(EVP_CIPHER_CTX *);
+
+/*****************************************************************************
+ * Our DES ciphers
+ **/
+static const EVP_CIPHER cipher_des_cbc =
+	{
+	NID_des_cbc,
+	8, 8, 8,
+	0 | EVP_CIPH_CBC_MODE,
+	cipher_des_cbc_init,
+	cipher_des_cbc_code,
+	cipher_des_cbc_clean,
+	sizeof(DES_CBC_CTX),
+	NULL,
+	NULL,
+	NULL,
+	NULL
+	};
+
+static const EVP_CIPHER cipher_des_ede3_cbc =
+	{
+	NID_des_ede3_cbc,
+	8, 24, 8,
+	0 | EVP_CIPH_CBC_MODE,
+	cipher_des_ede3_cbc_init,
+	cipher_des_ede3_cbc_code,
+	cipher_des_ede3_cbc_clean,
+	sizeof(DES3_CBC_CTX),
+	NULL,
+	NULL,
+	NULL,
+	NULL
+	};
+
+static const EVP_CIPHER cipher_desx_cbc =
+	{
+	NID_desx_cbc,
+	8, 24, 8,
+	0 | EVP_CIPH_CBC_MODE,
+	cipher_desx_cbc_init,
+	cipher_desx_cbc_code,
+	cipher_desx_cbc_clean,
+	sizeof(DESX_CBC_CTX),
+	NULL,
+	NULL,
+	NULL,
+	NULL
+	};
+
+/*****************************************************************************
+ * MD functions
+ **/
+static int digest_md2_init(EVP_MD_CTX *ctx);
+static int digest_md2_update(EVP_MD_CTX *ctx,const void *data,
+	unsigned long count);
+static int digest_md2_final(EVP_MD_CTX *ctx,unsigned char *md);
+static int digest_md5_init(EVP_MD_CTX *ctx);
+static int digest_md5_update(EVP_MD_CTX *ctx,const void *data,
+	unsigned long count);
+static int digest_md5_final(EVP_MD_CTX *ctx,unsigned char *md);
+
+/*****************************************************************************
+ * Our MD digests
+ **/
+static const EVP_MD digest_md2 =
+	{
+	NID_md2,
+	NID_md2WithRSAEncryption,
+	16,
+	0,
+	digest_md2_init,
+	digest_md2_update,
+	digest_md2_final,
+	NULL,
+	NULL,
+	EVP_PKEY_RSA_method,
+	16,
+	sizeof(MD2_CTX)
+	};
+
+static const EVP_MD digest_md5 =
+	{
+	NID_md5,
+	NID_md5WithRSAEncryption,
+	16,
+	0,
+	digest_md5_init,
+	digest_md5_update,
+	digest_md5_final,
+	NULL,
+	NULL,
+	EVP_PKEY_RSA_method,
+	64,
+	sizeof(MD5_CTX)
+	};
+
+/*****************************************************************************
+ *** Function definitions                                                  ***
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Functions to handle the engine
+ **/
+
+static int bind_rsaref(ENGINE *e)
+	{
+	const RSA_METHOD *meth1;
+	if(!ENGINE_set_id(e, engine_rsaref_id)
+		|| !ENGINE_set_name(e, engine_rsaref_name)
+		|| !ENGINE_set_RSA(e, &rsaref_rsa)
+		|| !ENGINE_set_ciphers(e, rsaref_ciphers)
+		|| !ENGINE_set_digests(e, rsaref_digests)
+		|| !ENGINE_set_destroy_function(e, rsaref_destroy)
+		|| !ENGINE_set_init_function(e, rsaref_init)
+		|| !ENGINE_set_finish_function(e, rsaref_finish)
+		/* || !ENGINE_set_ctrl_function(e, rsaref_ctrl) */
+		/* || !ENGINE_set_cmd_defns(e, rsaref_cmd_defns) */)
+		return 0;
+
+	/* Ensure the rsaref error handling is set up */
+	ERR_load_RSAREF_strings();
+	return 1;
+	}
+
+#ifdef ENGINE_DYNAMIC_SUPPORT
+static int bind_helper(ENGINE *e, const char *id)
+	{
+	if(id && (strcmp(id, engine_rsaref_id) != 0))
+		return 0;
+	if(!bind_rsaref(e))
+		return 0;
+	return 1;
+	}       
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
+#else
+static ENGINE *engine_rsaref(void)
+	{
+	ENGINE *ret = ENGINE_new();
+	if(!ret)
+		return NULL;
+	if(!bind_rsaref(ret))
+		{
+		ENGINE_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+void ENGINE_load_rsaref(void)
+	{
+	/* Copied from eng_[openssl|dyn].c */
+	ENGINE *toadd = engine_rsaref();
+	if(!toadd) return;
+	ENGINE_add(toadd);
+	ENGINE_free(toadd);
+	ERR_clear_error();
+	}
+#endif
+
+/* Initiator which is only present to make sure this engine looks available */
+static int rsaref_init(ENGINE *e)
+	{
+	return 1;
+	}
+
+/* Finisher which is only present to make sure this engine looks available */
+static int rsaref_finish(ENGINE *e)
+	{
+	return 1;
+	}
+
+/* Destructor (complements the "ENGINE_ncipher()" constructor) */
+static int rsaref_destroy(ENGINE *e)
+	{
+	ERR_unload_RSAREF_strings();
+	return 1;
+	}
+
+/*****************************************************************************
+ * RSA functions
+ **/
+
+static int rsaref_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
+	{
+	RSAREFerr(RSAREF_F_RSAREF_MOD_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+	return(0);
+	}
+
+static int bnref_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+	{
+	RSAREFerr(RSAREF_F_BNREF_MOD_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+	return(0);
+	}
+
+/* unsigned char *to:  [max]    */
+static int RSAref_bn2bin(BIGNUM *from, unsigned char *to, int max)
+	{
+	int i;
+
+	i=BN_num_bytes(from);
+	if (i > max)
+		{
+		RSAREFerr(RSAREF_F_RSAREF_BN2BIN,RSAREF_R_LEN);
+		return(0);
+		}
+
+	memset(to,0,(unsigned int)max);
+	if (!BN_bn2bin(from,&(to[max-i])))
+		return(0);
+	return(1);
+	}
+
+#ifdef undef
+/* unsigned char *from:  [max]    */
+static BIGNUM *RSAref_bin2bn(unsigned char *from, BIGNUM *to, int max)
+	{
+	int i;
+	BIGNUM *ret;
+
+	for (i=0; i<max; i++)
+		if (from[i]) break;
+
+	ret=BN_bin2bn(&(from[i]),max-i,to);
+	return(ret);
+	}
+
+static int RSAref_Public_ref2eay(RSArefPublicKey *from, RSA *to)
+	{
+	to->n=RSAref_bin2bn(from->m,NULL,RSAref_MAX_LEN);
+	to->e=RSAref_bin2bn(from->e,NULL,RSAref_MAX_LEN);
+	if ((to->n == NULL) || (to->e == NULL)) return(0);
+	return(1);
+	}
+#endif
+
+static int RSAref_Public_eay2ref(RSA *from, R_RSA_PUBLIC_KEY *to)
+	{
+	to->bits=BN_num_bits(from->n);
+	if (!RSAref_bn2bin(from->n,to->modulus,MAX_RSA_MODULUS_LEN)) return(0);
+	if (!RSAref_bn2bin(from->e,to->exponent,MAX_RSA_MODULUS_LEN)) return(0);
+	return(1);
+	}
+
+#ifdef undef
+static int RSAref_Private_ref2eay(RSArefPrivateKey *from, RSA *to)
+	{
+	if ((to->n=RSAref_bin2bn(from->m,NULL,RSAref_MAX_LEN)) == NULL)
+		return(0);
+	if ((to->e=RSAref_bin2bn(from->e,NULL,RSAref_MAX_LEN)) == NULL)
+		return(0);
+	if ((to->d=RSAref_bin2bn(from->d,NULL,RSAref_MAX_LEN)) == NULL)
+		return(0);
+	if ((to->p=RSAref_bin2bn(from->prime[0],NULL,RSAref_MAX_PLEN)) == NULL)
+		return(0);
+	if ((to->q=RSAref_bin2bn(from->prime[1],NULL,RSAref_MAX_PLEN)) == NULL)
+		return(0);
+	if ((to->dmp1=RSAref_bin2bn(from->pexp[0],NULL,RSAref_MAX_PLEN))
+		== NULL)
+		return(0);
+	if ((to->dmq1=RSAref_bin2bn(from->pexp[1],NULL,RSAref_MAX_PLEN))
+		== NULL)
+		return(0);
+	if ((to->iqmp=RSAref_bin2bn(from->coef,NULL,RSAref_MAX_PLEN)) == NULL)
+		return(0);
+	return(1);
+	}
+#endif
+
+static int RSAref_Private_eay2ref(RSA *from, R_RSA_PRIVATE_KEY *to)
+	{
+	to->bits=BN_num_bits(from->n);
+	if (!RSAref_bn2bin(from->n,to->modulus,MAX_RSA_MODULUS_LEN)) return(0);
+	if (!RSAref_bn2bin(from->e,to->publicExponent,MAX_RSA_MODULUS_LEN)) return(0);
+	if (!RSAref_bn2bin(from->d,to->exponent,MAX_RSA_MODULUS_LEN)) return(0);
+	if (!RSAref_bn2bin(from->p,to->prime[0],MAX_RSA_PRIME_LEN)) return(0);
+	if (!RSAref_bn2bin(from->q,to->prime[1],MAX_RSA_PRIME_LEN)) return(0);
+	if (!RSAref_bn2bin(from->dmp1,to->primeExponent[0],MAX_RSA_PRIME_LEN)) return(0);
+	if (!RSAref_bn2bin(from->dmq1,to->primeExponent[1],MAX_RSA_PRIME_LEN)) return(0);
+	if (!RSAref_bn2bin(from->iqmp,to->coefficient,MAX_RSA_PRIME_LEN)) return(0);
+	return(1);
+	}
+
+static int rsaref_private_decrypt(int len, const unsigned char *from, unsigned char *to,
+	     RSA *rsa, int padding)
+	{
+	int i,outlen= -1;
+	R_RSA_PRIVATE_KEY RSAkey;
+
+	if (!RSAref_Private_eay2ref(rsa,&RSAkey))
+		goto err;
+	if ((i=RSAPrivateDecrypt(to,(unsigned int *)&outlen,(unsigned char *)from,len,&RSAkey)) != 0)
+		{
+		RSAREFerr(RSAREF_F_RSAREF_PRIVATE_DECRYPT,i);
+		outlen= -1;
+		}
+err:
+	memset(&RSAkey,0,sizeof(RSAkey));
+	return(outlen);
+	}
+
+static int rsaref_private_encrypt(int len, const unsigned char *from, unsigned char *to,
+	     RSA *rsa, int padding)
+	{
+	int i,outlen= -1;
+	R_RSA_PRIVATE_KEY RSAkey;
+
+	if (padding != RSA_PKCS1_PADDING)
+		{
+		RSAREFerr(RSAREF_F_RSAREF_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+	}
+	if (!RSAref_Private_eay2ref(rsa,&RSAkey))
+		goto err;
+	if ((i=RSAPrivateEncrypt(to,(unsigned int *)&outlen,(unsigned char *)from,len,&RSAkey)) != 0)
+		{
+		RSAREFerr(RSAREF_F_RSAREF_PRIVATE_ENCRYPT,i);
+		outlen= -1;
+		}
+err:
+	memset(&RSAkey,0,sizeof(RSAkey));
+	return(outlen);
+	}
+
+static int rsaref_public_decrypt(int len, const unsigned char *from, unsigned char *to,
+	     RSA *rsa, int padding)
+	{
+	int i,outlen= -1;
+	R_RSA_PUBLIC_KEY RSAkey;
+
+	if (!RSAref_Public_eay2ref(rsa,&RSAkey))
+		goto err;
+	if ((i=RSAPublicDecrypt(to,(unsigned int *)&outlen,(unsigned char *)from,len,&RSAkey)) != 0)
+		{
+		RSAREFerr(RSAREF_F_RSAREF_PUBLIC_DECRYPT,i);
+		outlen= -1;
+		}
+err:
+	memset(&RSAkey,0,sizeof(RSAkey));
+	return(outlen);
+	}
+
+static int rsaref_public_encrypt(int len, const unsigned char *from, unsigned char *to,
+	     RSA *rsa, int padding)
+	{
+	int outlen= -1;
+	int i;
+	R_RSA_PUBLIC_KEY RSAkey;
+	R_RANDOM_STRUCT rnd;
+	unsigned char buf[16];
+
+	if (padding != RSA_PKCS1_PADDING && padding != RSA_SSLV23_PADDING) 
+		{
+		RSAREFerr(RSAREF_F_RSAREF_PUBLIC_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+		}
+	
+	R_RandomInit(&rnd);
+	R_GetRandomBytesNeeded((unsigned int *)&i,&rnd);
+	while (i > 0)
+		{
+		if (RAND_bytes(buf,16) <= 0)
+			goto err;
+		R_RandomUpdate(&rnd,buf,(unsigned int)((i>16)?16:i));
+		i-=16;
+		}
+
+	if (!RSAref_Public_eay2ref(rsa,&RSAkey))
+		goto err;
+	if ((i=RSAPublicEncrypt(to,(unsigned int *)&outlen,(unsigned char *)from,len,&RSAkey,&rnd)) != 0)
+		{
+		RSAREFerr(RSAREF_F_RSAREF_PUBLIC_ENCRYPT,i);
+		outlen= -1;
+		goto err;
+		}
+err:
+	memset(&RSAkey,0,sizeof(RSAkey));
+	R_RandomFinal(&rnd);
+	memset(&rnd,0,sizeof(rnd));
+	return(outlen);
+	}
+
+/*****************************************************************************
+ * Symetric cipher and digest function registrars
+ **/
+static int rsaref_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
+	const int **nids, int nid)
+	{
+	int ok = 1;
+	if(!cipher)
+		{
+		/* We are returning a list of supported nids */
+		*nids = rsaref_cipher_nids;
+		return (sizeof(rsaref_cipher_nids)-1)/sizeof(rsaref_cipher_nids[0]);
+		}
+	/* We are being asked for a specific cipher */
+	switch (nid)
+		{
+	case NID_des_cbc:
+		*cipher = &cipher_des_cbc; break;
+	case NID_des_ede3_cbc:
+		*cipher = &cipher_des_ede3_cbc; break;
+	case NID_desx_cbc:
+		*cipher = &cipher_desx_cbc; break;
+	default:
+		ok = 0;
+		*cipher = NULL;
+		break;
+		}
+	return ok;
+	}
+static int rsaref_digests(ENGINE *e, const EVP_MD **digest,
+	const int **nids, int nid)
+	{
+	int ok = 1;
+	if(!digest)
+		{
+		/* We are returning a list of supported nids */
+		*nids = rsaref_digest_nids;
+		return (sizeof(rsaref_digest_nids)-1)/sizeof(rsaref_digest_nids[0]);
+		}
+	/* We are being asked for a specific digest */
+	switch (nid)
+		{
+	case NID_md2:
+		*digest = &digest_md2; break;
+	case NID_md5:
+		*digest = &digest_md5; break;
+	default:
+		ok = 0;
+		*digest = NULL;
+		break;
+		}
+	return ok;
+	}
+
+/*****************************************************************************
+ * DES functions
+ **/
+#undef data
+#define data(ctx) ((DES_CBC_CTX *)(ctx)->cipher_data)
+static int cipher_des_cbc_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+	const unsigned char *iv, int enc)
+	{
+	DES_CBCInit(data(ctx), (unsigned char *)key, (unsigned char *)iv, enc);
+	return 1;
+	}
+static int cipher_des_cbc_code(EVP_CIPHER_CTX *ctx, unsigned char *out,
+	const unsigned char *in, unsigned int inl)
+	{
+	int ret = DES_CBCUpdate(data(ctx), out, (unsigned char *)in, inl);
+	switch (ret)
+		{
+	case RE_LEN:
+		RSAREFerr(RSAREF_F_CIPHER_DES_CBC_CODE,RSAREF_R_LENGTH_NOT_BLOCK_ALIGNED);
+		break;
+	case 0:
+		break;
+	default:
+		RSAREFerr(RSAREF_F_CIPHER_DES_CBC_CODE,RSAREF_R_UNKNOWN_FAULT);
+		}
+	return !ret;
+	}
+static int cipher_des_cbc_clean(EVP_CIPHER_CTX *ctx)
+	{
+	memset(data(ctx), 0, ctx->cipher->ctx_size);
+	return 1;
+	}
+
+#undef data
+#define data(ctx) ((DES3_CBC_CTX *)(ctx)->cipher_data)
+static int cipher_des_ede3_cbc_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+	const unsigned char *iv, int enc)
+	{
+	DES3_CBCInit(data(ctx), (unsigned char *)key, (unsigned char *)iv,
+		enc);
+	return 1;
+	}
+static int cipher_des_ede3_cbc_code(EVP_CIPHER_CTX *ctx, unsigned char *out,
+	const unsigned char *in, unsigned int inl)
+	{
+	int ret = DES3_CBCUpdate(data(ctx), out, (unsigned char *)in, inl);
+	switch (ret)
+		{
+	case RE_LEN:
+		RSAREFerr(RSAREF_F_CIPHER_DES_CBC_CODE,RSAREF_R_LENGTH_NOT_BLOCK_ALIGNED);
+		break;
+	case 0:
+		break;
+	default:
+		RSAREFerr(RSAREF_F_CIPHER_DES_CBC_CODE,RSAREF_R_UNKNOWN_FAULT);
+		}
+	return !ret;
+	}
+static int cipher_des_ede3_cbc_clean(EVP_CIPHER_CTX *ctx)
+	{
+	memset(data(ctx), 0, ctx->cipher->ctx_size);
+	return 1;
+	}
+
+#undef data
+#define data(ctx) ((DESX_CBC_CTX *)(ctx)->cipher_data)
+static int cipher_desx_cbc_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+	const unsigned char *iv, int enc)
+	{
+	DESX_CBCInit(data(ctx), (unsigned char *)key, (unsigned char *)iv,
+		enc);
+	return 1;
+	}
+static int cipher_desx_cbc_code(EVP_CIPHER_CTX *ctx, unsigned char *out,
+	const unsigned char *in, unsigned int inl)
+	{
+	int ret = DESX_CBCUpdate(data(ctx), out, (unsigned char *)in, inl);
+	switch (ret)
+		{
+	case RE_LEN:
+		RSAREFerr(RSAREF_F_CIPHER_DES_CBC_CODE,RSAREF_R_LENGTH_NOT_BLOCK_ALIGNED);
+		break;
+	case 0:
+		break;
+	default:
+		RSAREFerr(RSAREF_F_CIPHER_DES_CBC_CODE,RSAREF_R_UNKNOWN_FAULT);
+		}
+	return !ret;
+	}
+static int cipher_desx_cbc_clean(EVP_CIPHER_CTX *ctx)
+	{
+	memset(data(ctx), 0, ctx->cipher->ctx_size);
+	return 1;
+	}
+
+/*****************************************************************************
+ * MD functions
+ **/
+#undef data
+#define data(ctx) ((MD2_CTX *)(ctx)->md_data)
+static int digest_md2_init(EVP_MD_CTX *ctx)
+	{
+	MD2Init(data(ctx));
+	return 1;
+	}
+static int digest_md2_update(EVP_MD_CTX *ctx,const void *data,
+	unsigned long count)
+	{
+	MD2Update(data(ctx), (unsigned char *)data, (unsigned int)count);
+	return 1;
+	}
+static int digest_md2_final(EVP_MD_CTX *ctx,unsigned char *md)
+	{
+	MD2Final(md, data(ctx));
+	return 1;
+	}
+
+#undef data
+#define data(ctx) ((MD5_CTX *)(ctx)->md_data)
+static int digest_md5_init(EVP_MD_CTX *ctx)
+	{
+	MD5Init(data(ctx));
+	return 1;
+	}
+static int digest_md5_update(EVP_MD_CTX *ctx,const void *data,
+	unsigned long count)
+	{
+	MD5Update(data(ctx), (unsigned char *)data, (unsigned int)count);
+	return 1;
+	}
+static int digest_md5_final(EVP_MD_CTX *ctx,unsigned char *md)
+	{
+	MD5Final(md, data(ctx));
+	return 1;
+	}
diff --git a/openssl/demos/engines/rsaref/rsaref.ec b/openssl/demos/engines/rsaref/rsaref.ec
new file mode 100644
index 0000000..c690ae3
--- /dev/null
+++ b/openssl/demos/engines/rsaref/rsaref.ec
@@ -0,0 +1,8 @@
+# configuration file for util/mkerr.pl
+#
+# use like this:
+#
+#	perl ../../../util/mkerr.pl -conf rsaref.ec \
+#		-nostatic -staticloader -write *.c
+
+L RSAREF	rsaref_err.h			rsaref_err.c
diff --git a/openssl/demos/engines/rsaref/rsaref_err.c b/openssl/demos/engines/rsaref/rsaref_err.c
new file mode 100644
index 0000000..ceaf057
--- /dev/null
+++ b/openssl/demos/engines/rsaref/rsaref_err.c
@@ -0,0 +1,161 @@
+/* rsaref_err.c */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "rsaref_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+static ERR_STRING_DATA RSAREF_str_functs[]=
+	{
+{ERR_PACK(0,RSAREF_F_BNREF_MOD_EXP,0),	"BNREF_MOD_EXP"},
+{ERR_PACK(0,RSAREF_F_CIPHER_DES_CBC_CODE,0),	"CIPHER_DES_CBC_CODE"},
+{ERR_PACK(0,RSAREF_F_RSAREF_BN2BIN,0),	"RSAREF_BN2BIN"},
+{ERR_PACK(0,RSAREF_F_RSAREF_MOD_EXP,0),	"RSAREF_MOD_EXP"},
+{ERR_PACK(0,RSAREF_F_RSAREF_PRIVATE_DECRYPT,0),	"RSAREF_PRIVATE_DECRYPT"},
+{ERR_PACK(0,RSAREF_F_RSAREF_PRIVATE_ENCRYPT,0),	"RSAREF_PRIVATE_ENCRYPT"},
+{ERR_PACK(0,RSAREF_F_RSAREF_PUBLIC_DECRYPT,0),	"RSAREF_PUBLIC_DECRYPT"},
+{ERR_PACK(0,RSAREF_F_RSAREF_PUBLIC_ENCRYPT,0),	"RSAREF_PUBLIC_ENCRYPT"},
+{ERR_PACK(0,RSAREF_F_RSA_BN2BIN,0),	"RSA_BN2BIN"},
+{ERR_PACK(0,RSAREF_F_RSA_PRIVATE_DECRYPT,0),	"RSA_PRIVATE_DECRYPT"},
+{ERR_PACK(0,RSAREF_F_RSA_PRIVATE_ENCRYPT,0),	"RSA_PRIVATE_ENCRYPT"},
+{ERR_PACK(0,RSAREF_F_RSA_PUBLIC_DECRYPT,0),	"RSA_PUBLIC_DECRYPT"},
+{ERR_PACK(0,RSAREF_F_RSA_PUBLIC_ENCRYPT,0),	"RSA_PUBLIC_ENCRYPT"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA RSAREF_str_reasons[]=
+	{
+{RSAREF_R_CONTENT_ENCODING               ,"content encoding"},
+{RSAREF_R_DATA                           ,"data"},
+{RSAREF_R_DIGEST_ALGORITHM               ,"digest algorithm"},
+{RSAREF_R_ENCODING                       ,"encoding"},
+{RSAREF_R_ENCRYPTION_ALGORITHM           ,"encryption algorithm"},
+{RSAREF_R_KEY                            ,"key"},
+{RSAREF_R_KEY_ENCODING                   ,"key encoding"},
+{RSAREF_R_LEN                            ,"len"},
+{RSAREF_R_LENGTH_NOT_BLOCK_ALIGNED       ,"length not block aligned"},
+{RSAREF_R_MODULUS_LEN                    ,"modulus len"},
+{RSAREF_R_NEED_RANDOM                    ,"need random"},
+{RSAREF_R_PRIVATE_KEY                    ,"private key"},
+{RSAREF_R_PUBLIC_KEY                     ,"public key"},
+{RSAREF_R_SIGNATURE                      ,"signature"},
+{RSAREF_R_SIGNATURE_ENCODING             ,"signature encoding"},
+{RSAREF_R_UNKNOWN_FAULT                  ,"unknown fault"},
+{0,NULL}
+	};
+
+#endif
+
+#ifdef RSAREF_LIB_NAME
+static ERR_STRING_DATA RSAREF_lib_name[]=
+        {
+{0	,RSAREF_LIB_NAME},
+{0,NULL}
+	};
+#endif
+
+
+static int RSAREF_lib_error_code=0;
+static int RSAREF_error_init=1;
+
+static void ERR_load_RSAREF_strings(void)
+	{
+	if (RSAREF_lib_error_code == 0)
+		RSAREF_lib_error_code=ERR_get_next_error_library();
+
+	if (RSAREF_error_init)
+		{
+		RSAREF_error_init=0;
+#ifndef OPENSSL_NO_ERR
+		ERR_load_strings(RSAREF_lib_error_code,RSAREF_str_functs);
+		ERR_load_strings(RSAREF_lib_error_code,RSAREF_str_reasons);
+#endif
+
+#ifdef RSAREF_LIB_NAME
+		RSAREF_lib_name->error = ERR_PACK(RSAREF_lib_error_code,0,0);
+		ERR_load_strings(0,RSAREF_lib_name);
+#endif
+		}
+	}
+
+static void ERR_unload_RSAREF_strings(void)
+	{
+	if (RSAREF_error_init == 0)
+		{
+#ifndef OPENSSL_NO_ERR
+		ERR_unload_strings(RSAREF_lib_error_code,RSAREF_str_functs);
+		ERR_unload_strings(RSAREF_lib_error_code,RSAREF_str_reasons);
+#endif
+
+#ifdef RSAREF_LIB_NAME
+		ERR_unload_strings(0,RSAREF_lib_name);
+#endif
+		RSAREF_error_init=1;
+		}
+	}
+
+static void ERR_RSAREF_error(int function, int reason, char *file, int line)
+	{
+	if (RSAREF_lib_error_code == 0)
+		RSAREF_lib_error_code=ERR_get_next_error_library();
+	ERR_PUT_error(RSAREF_lib_error_code,function,reason,file,line);
+	}
diff --git a/openssl/demos/engines/rsaref/rsaref_err.h b/openssl/demos/engines/rsaref/rsaref_err.h
new file mode 100644
index 0000000..1975970
--- /dev/null
+++ b/openssl/demos/engines/rsaref/rsaref_err.h
@@ -0,0 +1,109 @@
+/* rsaref_err.h */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_RSAREF_ERR_H
+#define HEADER_RSAREF_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_RSAREF_strings(void);
+static void ERR_unload_RSAREF_strings(void);
+static void ERR_RSAREF_error(int function, int reason, char *file, int line);
+#define RSAREFerr(f,r) ERR_RSAREF_error((f),(r),__FILE__,__LINE__)
+/* Error codes for the RSAREF functions. */
+
+/* Function codes. */
+#define RSAREF_F_BNREF_MOD_EXP				 100
+#define RSAREF_F_CIPHER_DES_CBC_CODE			 112
+#define RSAREF_F_RSAREF_BN2BIN				 101
+#define RSAREF_F_RSAREF_MOD_EXP				 102
+#define RSAREF_F_RSAREF_PRIVATE_DECRYPT			 103
+#define RSAREF_F_RSAREF_PRIVATE_ENCRYPT			 104
+#define RSAREF_F_RSAREF_PUBLIC_DECRYPT			 105
+#define RSAREF_F_RSAREF_PUBLIC_ENCRYPT			 106
+#define RSAREF_F_RSA_BN2BIN				 107
+#define RSAREF_F_RSA_PRIVATE_DECRYPT			 108
+#define RSAREF_F_RSA_PRIVATE_ENCRYPT			 109
+#define RSAREF_F_RSA_PUBLIC_DECRYPT			 110
+#define RSAREF_F_RSA_PUBLIC_ENCRYPT			 111
+
+/* Reason codes. */
+#define RSAREF_R_CONTENT_ENCODING			 100
+#define RSAREF_R_DATA					 101
+#define RSAREF_R_DIGEST_ALGORITHM			 102
+#define RSAREF_R_ENCODING				 103
+#define RSAREF_R_ENCRYPTION_ALGORITHM			 104
+#define RSAREF_R_KEY					 105
+#define RSAREF_R_KEY_ENCODING				 106
+#define RSAREF_R_LEN					 107
+#define RSAREF_R_LENGTH_NOT_BLOCK_ALIGNED		 114
+#define RSAREF_R_MODULUS_LEN				 108
+#define RSAREF_R_NEED_RANDOM				 109
+#define RSAREF_R_PRIVATE_KEY				 110
+#define RSAREF_R_PUBLIC_KEY				 111
+#define RSAREF_R_SIGNATURE				 112
+#define RSAREF_R_SIGNATURE_ENCODING			 113
+#define RSAREF_R_UNKNOWN_FAULT				 115
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/demos/engines/zencod/Makefile b/openssl/demos/engines/zencod/Makefile
new file mode 100644
index 0000000..5b6a339
--- /dev/null
+++ b/openssl/demos/engines/zencod/Makefile
@@ -0,0 +1,114 @@
+LIBNAME=	libzencod
+SRC=		hw_zencod.c
+OBJ=		hw_zencod.o
+HEADER=		hw_zencod.h
+
+CC=		gcc
+PIC=		-fPIC
+CFLAGS=		-g -I../../../include $(PIC) -DENGINE_DYNAMIC_SUPPORT -DFLAT_INC
+AR=		ar r
+RANLIB=		ranlib
+
+LIB=		$(LIBNAME).a
+SHLIB=		$(LIBNAME).so
+
+all:
+		@echo 'Please choose a system to build on:'
+		@echo ''
+		@echo 'tru64:    Tru64 Unix, Digital Unix, Digital OSF/1'
+		@echo 'solaris:  Solaris'
+		@echo 'irix:     IRIX'
+		@echo 'hpux32:   32-bit HP/UX'
+		@echo 'hpux64:   64-bit HP/UX'
+		@echo 'aix:      AIX'
+		@echo 'gnu:      Generic GNU-based system (gcc and GNU ld)'
+		@echo ''
+
+FORCE.update:
+update:		FORCE.update
+		perl ../../../util/mkerr.pl -conf hw_zencod.ec \
+			-nostatic -staticloader -write hw_zencod.c
+
+gnu:		$(SHLIB).gnu
+tru64:		$(SHLIB).tru64
+solaris:	$(SHLIB).solaris
+irix:		$(SHLIB).irix
+hpux32:		$(SHLIB).hpux32
+hpux64:		$(SHLIB).hpux64
+aix:		$(SHLIB).aix
+
+$(LIB):		$(OBJ)
+		$(AR) $(LIB) $(OBJ)
+		- $(RANLIB) $(LIB)
+
+LINK_SO=	\
+  ld -r -o $(LIBNAME).o $$ALLSYMSFLAGS $(LIB) && \
+  (nm -Pg $(LIBNAME).o | grep ' [BDT] ' | cut -f1 -d' ' > $(LIBNAME).exp; \
+   $$SHAREDCMD $$SHAREDFLAGS -o $(SHLIB) $(LIBNAME).o -L ../../.. -lcrypto -lc)
+
+$(SHLIB).gnu:	$(LIB)
+		ALLSYMSFLAGS='--whole-archive' \
+		SHAREDFLAGS='-shared -Wl,-soname=$(SHLIB)' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).gnu
+$(SHLIB).tru64:	$(LIB)
+		ALLSYMSFLAGS='-all' \
+		SHAREDFLAGS='-shared' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).tru64
+$(SHLIB).solaris:	$(LIB)
+		ALLSYMSFLAGS='-z allextract' \
+		SHAREDFLAGS='-G -h $(SHLIB)' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).solaris
+$(SHLIB).irix:	$(LIB)
+		ALLSYMSFLAGS='-all' \
+		SHAREDFLAGS='-shared -Wl,-soname,$(SHLIB)' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).irix
+$(SHLIB).hpux32:	$(LIB)
+		ALLSYMSFLAGS='-Fl' \
+		SHAREDFLAGS='+vnocompatwarnings -b -z +s +h $(SHLIB)' \
+		SHAREDCMD='/usr/ccs/bin/ld'; \
+		$(LINK_SO)
+		touch $(SHLIB).hpux32
+$(SHLIB).hpux64:	$(LIB)
+		ALLSYMSFLAGS='+forceload' \
+		SHAREDFLAGS='-b -z +h $(SHLIB)' \
+		SHAREDCMD='/usr/ccs/bin/ld'; \
+		$(LINK_SO)
+		touch $(SHLIB).hpux64
+$(SHLIB).aix:	$(LIB)
+		ALLSYMSFLAGS='-bnogc' \
+		SHAREDFLAGS='-G -bE:$(LIBNAME).exp -bM:SRE' \
+		SHAREDCMD='$(CC)'; \
+		$(LINK_SO)
+		touch $(SHLIB).aix
+
+depend:
+		sed -e '/^# DO NOT DELETE.*/,$$d' < Makefile > Makefile.tmp
+		echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' >> Makefile.tmp
+		gcc -M $(CFLAGS) $(SRC) >> Makefile.tmp
+		perl ../../../util/clean-depend.pl < Makefile.tmp > Makefile.new
+		rm -f Makefile.tmp Makefile
+		mv Makefile.new Makefile
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+rsaref.o: ../../../include/openssl/asn1.h ../../../include/openssl/bio.h
+rsaref.o: ../../../include/openssl/bn.h ../../../include/openssl/crypto.h
+rsaref.o: ../../../include/openssl/dh.h ../../../include/openssl/dsa.h
+rsaref.o: ../../../include/openssl/e_os2.h ../../../include/openssl/engine.h
+rsaref.o: ../../../include/openssl/err.h ../../../include/openssl/lhash.h
+rsaref.o: ../../../include/openssl/opensslconf.h
+rsaref.o: ../../../include/openssl/opensslv.h
+rsaref.o: ../../../include/openssl/ossl_typ.h ../../../include/openssl/rand.h
+rsaref.o: ../../../include/openssl/rsa.h ../../../include/openssl/safestack.h
+rsaref.o: ../../../include/openssl/stack.h ../../../include/openssl/symhacks.h
+rsaref.o: ../../../include/openssl/ui.h rsaref.c rsaref_err.c rsaref_err.h
+rsaref.o: source/des.h source/global.h source/md2.h source/md5.h source/rsa.h
+rsaref.o: source/rsaref.h
diff --git a/openssl/demos/engines/zencod/hw_zencod.c b/openssl/demos/engines/zencod/hw_zencod.c
new file mode 100644
index 0000000..4234b93
--- /dev/null
+++ b/openssl/demos/engines/zencod/hw_zencod.c
@@ -0,0 +1,1739 @@
+/* crypto/engine/hw_zencod.c */
+ /* Written by Fred Donnat (frederic.donnat@zencod.com) for "zencod"
+ * engine integration in order to redirect crypto computing on a crypto
+ * hardware accelerator zenssl32  ;-)
+ *
+ * Date : 25 jun 2002
+ * Revision : 17 Ju7 2002
+ * Version : zencod_engine-0.9.7
+ */
+
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+/* ENGINE general include */
+#include <stdio.h>
+#include <openssl/crypto.h>
+#include <openssl/dso.h>
+#include <openssl/engine.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_ZENCOD
+
+#ifdef FLAT_INC
+#  include "hw_zencod.h"
+#else
+#  include "vendor_defns/hw_zencod.h"
+#endif
+
+#define ZENCOD_LIB_NAME "zencod engine"
+#include "hw_zencod_err.c"
+
+#define FAIL_TO_SOFTWARE		-15
+
+#define	ZEN_LIBRARY	"zenbridge"
+
+#if 0
+#  define PERROR(s)	perror(s)
+#  define CHEESE()	fputs("## [ZenEngine] ## " __FUNCTION__ "\n", stderr)
+#else
+#  define PERROR(s)
+#  define CHEESE()
+#endif
+
+
+/* Sorry ;) */
+#ifndef WIN32
+static inline void esrever ( unsigned char *d, int l )
+{
+	for(;--l>0;--l,d++){*d^=*(d+l);*(d+l)^=*d;*d^=*(d+l);}
+}
+
+static inline void ypcmem ( unsigned char *d, const unsigned char *s, int l )
+{
+	for(d+=l;l--;)*--d=*s++;
+}
+#else
+static __inline void esrever ( unsigned char *d, int l )
+{
+	for(;--l>0;--l,d++){*d^=*(d+l);*(d+l)^=*d;*d^=*(d+l);}
+}
+
+static __inline void ypcmem ( unsigned char *d, const unsigned char *s, int l )
+{
+	for(d+=l;l--;)*--d=*s++;
+}
+#endif
+
+
+#define BIGNUM2ZEN(n, bn)	(ptr_zencod_init_number((n), \
+					(unsigned long) ((bn)->top * BN_BITS2), \
+					(unsigned char *) ((bn)->d)))
+
+#define ZEN_BITS(n, bytes)	(ptr_zencod_bytes2bits((unsigned char *) (n), (unsigned long) (bytes)))
+#define ZEN_BYTES(bits)	(ptr_zencod_bits2bytes((unsigned long) (bits)))
+
+
+/* Function for ENGINE detection and control */
+static int zencod_destroy ( ENGINE *e ) ;
+static int zencod_init ( ENGINE *e ) ;
+static int zencod_finish ( ENGINE *e ) ;
+static int zencod_ctrl ( ENGINE *e, int cmd, long i, void *p, void (*f) () ) ;
+
+/* BIGNUM stuff */
+static int zencod_bn_mod_exp ( BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx ) ;
+
+/* RSA stuff */
+#ifndef OPENSSL_NO_RSA
+static int RSA_zencod_rsa_mod_exp ( BIGNUM *r0, const BIGNUM *I, RSA *rsa ) ;
+static int RSA_zencod_bn_mod_exp ( BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx ) ;
+#endif
+
+/* DSA stuff */
+#ifndef OPENSSL_NO_DSA
+static int DSA_zencod_bn_mod_exp ( DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+		BN_MONT_CTX *m_ctx ) ;
+
+static DSA_SIG *DSA_zencod_do_sign ( const unsigned char *dgst, int dlen, DSA *dsa ) ;
+static int DSA_zencod_do_verify ( const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
+		DSA *dsa ) ;
+#endif
+
+/* DH stuff */
+#ifndef OPENSSL_NO_DH
+static int DH_zencod_bn_mod_exp ( const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+		BN_MONT_CTX *m_ctx ) ;
+static int DH_zencod_generate_key ( DH *dh ) ;
+static int DH_zencod_compute_key ( unsigned char *key, const BIGNUM *pub_key, DH *dh ) ;
+#endif
+
+/* Rand stuff */
+static void RAND_zencod_seed ( const void *buf, int num ) ;
+static int RAND_zencod_rand_bytes ( unsigned char *buf, int num ) ;
+static int RAND_zencod_rand_status ( void ) ;
+
+/* Digest Stuff */
+static int engine_digests ( ENGINE *e, const EVP_MD **digest, const int **nids, int nid ) ;
+
+/* Cipher Stuff */
+static int engine_ciphers ( ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid ) ;
+
+
+#define ZENCOD_CMD_SO_PATH			ENGINE_CMD_BASE
+static const ENGINE_CMD_DEFN zencod_cmd_defns [ ] =
+{
+	{ ZENCOD_CMD_SO_PATH,
+	  "SO_PATH",
+	  "Specifies the path to the 'zenbridge' shared library",
+	  ENGINE_CMD_FLAG_STRING},
+	{ 0, NULL, NULL, 0 }
+} ;
+
+
+#ifndef OPENSSL_NO_RSA
+/* Our internal RSA_METHOD specific to zencod ENGINE providing pointers to our function */
+static RSA_METHOD zencod_rsa =
+{
+	"ZENCOD RSA method",
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	RSA_zencod_rsa_mod_exp,
+	RSA_zencod_bn_mod_exp,
+	NULL,
+	NULL,
+	0,
+	NULL,
+	NULL,
+	NULL
+} ;
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* Our internal DSA_METHOD specific to zencod ENGINE providing pointers to our function */
+static DSA_METHOD zencod_dsa =
+{
+	"ZENCOD DSA method",
+	DSA_zencod_do_sign,
+	NULL,
+	DSA_zencod_do_verify,
+	NULL,
+	DSA_zencod_bn_mod_exp,
+	NULL,
+	NULL,
+	0,
+	NULL
+} ;
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* Our internal DH_METHOD specific to zencod ENGINE providing pointers to our function */
+static DH_METHOD zencod_dh =
+{
+	"ZENCOD DH method",
+	DH_zencod_generate_key,
+	DH_zencod_compute_key,
+	DH_zencod_bn_mod_exp,
+	NULL,
+	NULL,
+	0,
+	NULL
+} ;
+#endif
+
+/* Our internal RAND_meth specific to zencod ZNGINE providing pointers to  our function */
+static RAND_METHOD zencod_rand =
+{
+	RAND_zencod_seed,
+	RAND_zencod_rand_bytes,
+	NULL,
+	NULL,
+	RAND_zencod_rand_bytes,
+	RAND_zencod_rand_status
+} ;
+
+
+/* Constants used when creating the ENGINE */
+static const char *engine_zencod_id = "zencod";
+static const char *engine_zencod_name = "ZENCOD hardware engine support";
+
+
+/* This internal function is used by ENGINE_zencod () and possibly by the
+ * "dynamic" ENGINE support too   ;-)
+ */
+static int bind_helper ( ENGINE *e )
+{
+
+#ifndef OPENSSL_NO_RSA
+	const RSA_METHOD *meth_rsa ;
+#endif
+#ifndef OPENSSL_NO_DSA
+	const DSA_METHOD *meth_dsa ;
+#endif
+#ifndef OPENSSL_NO_DH
+	const DH_METHOD *meth_dh ;
+#endif
+
+	const RAND_METHOD *meth_rand ;
+
+
+	if ( !ENGINE_set_id ( e, engine_zencod_id ) ||
+			!ENGINE_set_name ( e, engine_zencod_name ) ||
+#ifndef OPENSSL_NO_RSA
+			!ENGINE_set_RSA ( e, &zencod_rsa ) ||
+#endif
+#ifndef OPENSSL_NO_DSA
+			!ENGINE_set_DSA ( e, &zencod_dsa ) ||
+#endif
+#ifndef OPENSSL_NO_DH
+			!ENGINE_set_DH ( e, &zencod_dh ) ||
+#endif
+			!ENGINE_set_RAND ( e, &zencod_rand ) ||
+
+			!ENGINE_set_destroy_function ( e, zencod_destroy ) ||
+			!ENGINE_set_init_function ( e, zencod_init ) ||
+			!ENGINE_set_finish_function ( e, zencod_finish ) ||
+			!ENGINE_set_ctrl_function ( e, zencod_ctrl ) ||
+			!ENGINE_set_cmd_defns ( e, zencod_cmd_defns ) ||
+			!ENGINE_set_digests ( e, engine_digests ) ||
+			!ENGINE_set_ciphers ( e, engine_ciphers ) ) {
+		return 0 ;
+	}
+
+#ifndef OPENSSL_NO_RSA
+	/* We know that the "PKCS1_SSLeay()" functions hook properly
+	 * to the Zencod-specific mod_exp and mod_exp_crt so we use
+	 * those functions. NB: We don't use ENGINE_openssl() or
+	 * anything "more generic" because something like the RSAref
+	 * code may not hook properly, and if you own one of these
+	 * cards then you have the right to do RSA operations on it
+	 * anyway!
+	 */
+	meth_rsa = RSA_PKCS1_SSLeay () ;
+
+	zencod_rsa.rsa_pub_enc = meth_rsa->rsa_pub_enc ;
+	zencod_rsa.rsa_pub_dec = meth_rsa->rsa_pub_dec ;
+	zencod_rsa.rsa_priv_enc = meth_rsa->rsa_priv_enc ;
+	zencod_rsa.rsa_priv_dec = meth_rsa->rsa_priv_dec ;
+	/* meth_rsa->rsa_mod_exp */
+	/* meth_rsa->bn_mod_exp */
+	zencod_rsa.init = meth_rsa->init ;
+	zencod_rsa.finish = meth_rsa->finish ;
+#endif
+
+#ifndef OPENSSL_NO_DSA
+	/* We use OpenSSL meth to supply what we don't provide ;-*)
+	 */
+	meth_dsa = DSA_OpenSSL () ;
+
+	/* meth_dsa->dsa_do_sign */
+	zencod_dsa.dsa_sign_setup = meth_dsa->dsa_sign_setup ;
+	/* meth_dsa->dsa_do_verify */
+	zencod_dsa.dsa_mod_exp = meth_dsa->dsa_mod_exp ;
+	/* zencod_dsa.bn_mod_exp = meth_dsa->bn_mod_exp ; */
+	zencod_dsa.init = meth_dsa->init ;
+	zencod_dsa.finish = meth_dsa->finish ;
+#endif
+
+#ifndef OPENSSL_NO_DH
+	/* We use OpenSSL meth to supply what we don't provide ;-*)
+	 */
+	meth_dh = DH_OpenSSL () ;
+
+	/* zencod_dh.generate_key = meth_dh->generate_key ; */
+	/* zencod_dh.compute_key = meth_dh->compute_key ; */
+	/* zencod_dh.bn_mod_exp = meth_dh->bn_mod_exp ; */
+	zencod_dh.init = meth_dh->init ;
+	zencod_dh.finish = meth_dh->finish ;
+
+#endif
+
+	/* We use OpenSSL (SSLeay) meth to supply what we don't provide ;-*)
+	 */
+	meth_rand = RAND_SSLeay () ;
+
+	/* meth_rand->seed ; */
+	/* zencod_rand.seed = meth_rand->seed ; */
+	/* meth_rand->bytes ; */
+	/* zencod_rand.bytes = meth_rand->bytes ; */
+	zencod_rand.cleanup = meth_rand->cleanup ;
+	zencod_rand.add = meth_rand->add ;
+	/* meth_rand->pseudorand ; */
+	/* zencod_rand.pseudorand = meth_rand->pseudorand ; */
+	/* zencod_rand.status = meth_rand->status ; */
+	/* meth_rand->status ; */
+
+	/* Ensure the zencod error handling is set up */
+	ERR_load_ZENCOD_strings () ;
+	return 1 ;
+}
+
+
+/* As this is only ever called once, there's no need for locking
+ * (indeed - the lock will already be held by our caller!!!)
+ */
+static ENGINE *ENGINE_zencod ( void )
+{
+
+	ENGINE *eng = ENGINE_new () ;
+
+	if ( !eng ) {
+		return NULL ;
+	}
+	if ( !bind_helper ( eng ) ) {
+		ENGINE_free ( eng ) ;
+		return NULL ;
+	}
+
+	return eng ;
+}
+
+
+#ifdef ENGINE_DYNAMIC_SUPPORT
+static
+#endif
+void ENGINE_load_zencod ( void )
+{
+	/* Copied from eng_[openssl|dyn].c */
+	ENGINE *toadd = ENGINE_zencod ( ) ;
+	if ( !toadd ) return ;
+	ENGINE_add ( toadd ) ;
+	ENGINE_free ( toadd ) ;
+	ERR_clear_error ( ) ;
+}
+
+
+/* This is a process-global DSO handle used for loading and unloading
+ * the ZENBRIDGE library.
+ * NB: This is only set (or unset) during an * init () or finish () call
+ * (reference counts permitting) and they're  * operating with global locks,
+ * so this should be thread-safe * implicitly.
+ */
+static DSO *zencod_dso = NULL ;
+
+static t_zencod_test *ptr_zencod_test = NULL ;
+static t_zencod_bytes2bits *ptr_zencod_bytes2bits = NULL ;
+static t_zencod_bits2bytes *ptr_zencod_bits2bytes = NULL ;
+static t_zencod_new_number *ptr_zencod_new_number = NULL ;
+static t_zencod_init_number *ptr_zencod_init_number = NULL ;
+
+static t_zencod_rsa_mod_exp *ptr_zencod_rsa_mod_exp = NULL ;
+static t_zencod_rsa_mod_exp_crt *ptr_zencod_rsa_mod_exp_crt = NULL ;
+static t_zencod_dsa_do_sign *ptr_zencod_dsa_do_sign = NULL ;
+static t_zencod_dsa_do_verify *ptr_zencod_dsa_do_verify = NULL ;
+static t_zencod_dh_generate_key *ptr_zencod_dh_generate_key = NULL ;
+static t_zencod_dh_compute_key *ptr_zencod_dh_compute_key = NULL ;
+static t_zencod_rand_bytes *ptr_zencod_rand_bytes = NULL ;
+static t_zencod_math_mod_exp *ptr_zencod_math_mod_exp = NULL ;
+
+static t_zencod_md5_init *ptr_zencod_md5_init = NULL ;
+static t_zencod_md5_update *ptr_zencod_md5_update = NULL ;
+static t_zencod_md5_do_final *ptr_zencod_md5_do_final = NULL ;
+static t_zencod_sha1_init *ptr_zencod_sha1_init = NULL ;
+static t_zencod_sha1_update *ptr_zencod_sha1_update = NULL ;
+static t_zencod_sha1_do_final *ptr_zencod_sha1_do_final = NULL ;
+
+static t_zencod_xdes_cipher *ptr_zencod_xdes_cipher = NULL ;
+static t_zencod_rc4_cipher *ptr_zencod_rc4_cipher = NULL ;
+
+/* These are the static string constants for the DSO file name and the function
+ * symbol names to bind to.
+ */
+static const char *ZENCOD_LIBNAME = ZEN_LIBRARY ;
+
+static const char *ZENCOD_Fct_0 = "test_device" ;
+static const char *ZENCOD_Fct_1 = "zenbridge_bytes2bits" ;
+static const char *ZENCOD_Fct_2 = "zenbridge_bits2bytes" ;
+static const char *ZENCOD_Fct_3 = "zenbridge_new_number" ;
+static const char *ZENCOD_Fct_4 = "zenbridge_init_number" ;
+
+static const char *ZENCOD_Fct_exp_1 = "zenbridge_rsa_mod_exp" ;
+static const char *ZENCOD_Fct_exp_2 = "zenbridge_rsa_mod_exp_crt" ;
+static const char *ZENCOD_Fct_dsa_1 = "zenbridge_dsa_do_sign" ;
+static const char *ZENCOD_Fct_dsa_2 = "zenbridge_dsa_do_verify" ;
+static const char *ZENCOD_Fct_dh_1 = "zenbridge_dh_generate_key" ;
+static const char *ZENCOD_Fct_dh_2 = "zenbridge_dh_compute_key" ;
+static const char *ZENCOD_Fct_rand_1 = "zenbridge_rand_bytes" ;
+static const char *ZENCOD_Fct_math_1 = "zenbridge_math_mod_exp" ;
+
+static const char *ZENCOD_Fct_md5_1 = "zenbridge_md5_init" ;
+static const char *ZENCOD_Fct_md5_2 = "zenbridge_md5_update" ;
+static const char *ZENCOD_Fct_md5_3 = "zenbridge_md5_do_final" ;
+static const char *ZENCOD_Fct_sha1_1 = "zenbridge_sha1_init" ;
+static const char *ZENCOD_Fct_sha1_2 = "zenbridge_sha1_update" ;
+static const char *ZENCOD_Fct_sha1_3 = "zenbridge_sha1_do_final" ;
+
+static const char *ZENCOD_Fct_xdes_1 = "zenbridge_xdes_cipher" ;
+static const char *ZENCOD_Fct_rc4_1 = "zenbridge_rc4_cipher" ;
+
+/* Destructor (complements the "ENGINE_zencod ()" constructor)
+ */
+static int zencod_destroy (ENGINE *e )
+{
+
+	ERR_unload_ZENCOD_strings () ;
+
+	return 1 ;
+}
+
+
+/* (de)initialisation functions. Control Function
+ */
+static int zencod_init ( ENGINE *e )
+{
+
+	t_zencod_test *ptr_0 ;
+	t_zencod_bytes2bits *ptr_1 ;
+	t_zencod_bits2bytes *ptr_2 ;
+	t_zencod_new_number *ptr_3 ;
+	t_zencod_init_number *ptr_4 ;
+	t_zencod_rsa_mod_exp *ptr_exp_1 ;
+	t_zencod_rsa_mod_exp_crt *ptr_exp_2 ;
+	t_zencod_dsa_do_sign *ptr_dsa_1 ;
+	t_zencod_dsa_do_verify *ptr_dsa_2 ;
+	t_zencod_dh_generate_key *ptr_dh_1 ;
+	t_zencod_dh_compute_key *ptr_dh_2 ;
+	t_zencod_rand_bytes *ptr_rand_1 ;
+	t_zencod_math_mod_exp *ptr_math_1 ;
+	t_zencod_md5_init *ptr_md5_1 ;
+	t_zencod_md5_update *ptr_md5_2 ;
+	t_zencod_md5_do_final *ptr_md5_3 ;
+	t_zencod_sha1_init *ptr_sha1_1 ;
+	t_zencod_sha1_update *ptr_sha1_2 ;
+	t_zencod_sha1_do_final *ptr_sha1_3 ;
+	t_zencod_xdes_cipher *ptr_xdes_1 ;
+	t_zencod_rc4_cipher *ptr_rc4_1 ;
+
+	CHEESE () ;
+
+	/*
+	 * We Should add some tests for non NULL parameters or bad value !!
+	 * Stuff to be done ...
+	 */
+
+	if ( zencod_dso != NULL ) {
+		ZENCODerr ( ZENCOD_F_ZENCOD_INIT, ZENCOD_R_ALREADY_LOADED ) ;
+		goto err ;
+	}
+	/* Trying to load the Library "cryptozen"
+	 */
+	zencod_dso = DSO_load ( NULL, ZENCOD_LIBNAME, NULL, 0 ) ;
+	if ( zencod_dso == NULL ) {
+		ZENCODerr ( ZENCOD_F_ZENCOD_INIT, ZENCOD_R_DSO_FAILURE ) ;
+		goto err ;
+	}
+
+	/* Trying to load Function from the Library
+	 */
+	if ( ! ( ptr_1 = (t_zencod_bytes2bits*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_1 ) ) ||
+			! ( ptr_2 = (t_zencod_bits2bytes*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_2 ) ) ||
+			! ( ptr_3 = (t_zencod_new_number*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_3 ) ) ||
+			! ( ptr_4 = (t_zencod_init_number*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_4 ) ) ||
+			! ( ptr_exp_1 = (t_zencod_rsa_mod_exp*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_exp_1 ) ) ||
+			! ( ptr_exp_2 = (t_zencod_rsa_mod_exp_crt*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_exp_2 ) ) ||
+			! ( ptr_dsa_1 = (t_zencod_dsa_do_sign*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_dsa_1 ) ) ||
+			! ( ptr_dsa_2 = (t_zencod_dsa_do_verify*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_dsa_2 ) ) ||
+			! ( ptr_dh_1 = (t_zencod_dh_generate_key*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_dh_1 ) ) ||
+			! ( ptr_dh_2 = (t_zencod_dh_compute_key*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_dh_2 ) ) ||
+			! ( ptr_rand_1 = (t_zencod_rand_bytes*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_rand_1 ) ) ||
+			! ( ptr_math_1 = (t_zencod_math_mod_exp*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_math_1 ) ) ||
+			! ( ptr_0 = (t_zencod_test *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_0 ) ) ||
+			! ( ptr_md5_1 = (t_zencod_md5_init *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_md5_1 ) ) ||
+			! ( ptr_md5_2 = (t_zencod_md5_update *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_md5_2 ) ) ||
+			! ( ptr_md5_3 = (t_zencod_md5_do_final *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_md5_3 ) ) ||
+			! ( ptr_sha1_1 = (t_zencod_sha1_init *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_sha1_1 ) ) ||
+			! ( ptr_sha1_2 = (t_zencod_sha1_update *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_sha1_2 ) ) ||
+			! ( ptr_sha1_3 = (t_zencod_sha1_do_final *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_sha1_3 ) ) ||
+			! ( ptr_xdes_1 = (t_zencod_xdes_cipher *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_xdes_1 ) ) ||
+			! ( ptr_rc4_1 = (t_zencod_rc4_cipher *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_rc4_1 ) ) ) {
+
+		ZENCODerr ( ZENCOD_F_ZENCOD_INIT, ZENCOD_R_DSO_FAILURE ) ;
+		goto err ;
+	}
+
+	/* The function from "cryptozen" Library have been correctly loaded so copy them
+	 */
+	ptr_zencod_test = ptr_0 ;
+	ptr_zencod_bytes2bits = ptr_1 ;
+	ptr_zencod_bits2bytes = ptr_2 ;
+	ptr_zencod_new_number = ptr_3 ;
+	ptr_zencod_init_number = ptr_4 ;
+	ptr_zencod_rsa_mod_exp = ptr_exp_1 ;
+	ptr_zencod_rsa_mod_exp_crt = ptr_exp_2 ;
+	ptr_zencod_dsa_do_sign = ptr_dsa_1 ;
+	ptr_zencod_dsa_do_verify = ptr_dsa_2 ;
+	ptr_zencod_dh_generate_key = ptr_dh_1 ;
+	ptr_zencod_dh_compute_key = ptr_dh_2 ;
+	ptr_zencod_rand_bytes = ptr_rand_1 ;
+	ptr_zencod_math_mod_exp = ptr_math_1 ;
+	ptr_zencod_test = ptr_0 ;
+	ptr_zencod_md5_init = ptr_md5_1 ;
+	ptr_zencod_md5_update = ptr_md5_2 ;
+	ptr_zencod_md5_do_final = ptr_md5_3 ;
+	ptr_zencod_sha1_init = ptr_sha1_1 ;
+	ptr_zencod_sha1_update = ptr_sha1_2 ;
+	ptr_zencod_sha1_do_final = ptr_sha1_3 ;
+	ptr_zencod_xdes_cipher = ptr_xdes_1 ;
+	ptr_zencod_rc4_cipher = ptr_rc4_1 ;
+
+	/* We should peform a test to see if there is actually any unit runnig on the system ...
+	 * Even if the cryptozen library is loaded the module coul not be loaded on the system ...
+	 * For now we may just open and close the device !!
+	 */
+
+	if ( ptr_zencod_test () != 0 ) {
+		ZENCODerr ( ZENCOD_F_ZENCOD_INIT, ZENCOD_R_UNIT_FAILURE ) ;
+		goto err ;
+	}
+
+	return 1 ;
+err :
+	if ( zencod_dso ) {
+		DSO_free ( zencod_dso ) ;
+	}
+	zencod_dso = NULL ;
+	ptr_zencod_bytes2bits = NULL ;
+	ptr_zencod_bits2bytes = NULL ;
+	ptr_zencod_new_number = NULL ;
+	ptr_zencod_init_number = NULL ;
+	ptr_zencod_rsa_mod_exp = NULL ;
+	ptr_zencod_rsa_mod_exp_crt = NULL ;
+	ptr_zencod_dsa_do_sign = NULL ;
+	ptr_zencod_dsa_do_verify = NULL ;
+	ptr_zencod_dh_generate_key = NULL ;
+	ptr_zencod_dh_compute_key = NULL ;
+	ptr_zencod_rand_bytes = NULL ;
+	ptr_zencod_math_mod_exp = NULL ;
+	ptr_zencod_test = NULL ;
+	ptr_zencod_md5_init = NULL ;
+	ptr_zencod_md5_update = NULL ;
+	ptr_zencod_md5_do_final = NULL ;
+	ptr_zencod_sha1_init = NULL ;
+	ptr_zencod_sha1_update = NULL ;
+	ptr_zencod_sha1_do_final = NULL ;
+	ptr_zencod_xdes_cipher = NULL ;
+	ptr_zencod_rc4_cipher = NULL ;
+
+	return 0 ;
+}
+
+
+static int zencod_finish ( ENGINE *e )
+{
+
+	CHEESE () ;
+
+	/*
+	 * We Should add some tests for non NULL parameters or bad value !!
+	 * Stuff to be done ...
+	 */
+	if ( zencod_dso == NULL ) {
+		ZENCODerr ( ZENCOD_F_ZENCOD_FINISH, ZENCOD_R_NOT_LOADED ) ;
+		return 0 ;
+	}
+	if ( !DSO_free ( zencod_dso ) ) {
+		ZENCODerr ( ZENCOD_F_ZENCOD_FINISH, ZENCOD_R_DSO_FAILURE ) ;
+		return 0 ;
+	}
+
+	zencod_dso = NULL ;
+
+	ptr_zencod_bytes2bits = NULL ;
+	ptr_zencod_bits2bytes = NULL ;
+	ptr_zencod_new_number = NULL ;
+	ptr_zencod_init_number = NULL ;
+	ptr_zencod_rsa_mod_exp = NULL ;
+	ptr_zencod_rsa_mod_exp_crt = NULL ;
+	ptr_zencod_dsa_do_sign = NULL ;
+	ptr_zencod_dsa_do_verify = NULL ;
+	ptr_zencod_dh_generate_key = NULL ;
+	ptr_zencod_dh_compute_key = NULL ;
+	ptr_zencod_rand_bytes = NULL ;
+	ptr_zencod_math_mod_exp = NULL ;
+	ptr_zencod_test = NULL ;
+	ptr_zencod_md5_init = NULL ;
+	ptr_zencod_md5_update = NULL ;
+	ptr_zencod_md5_do_final = NULL ;
+	ptr_zencod_sha1_init = NULL ;
+	ptr_zencod_sha1_update = NULL ;
+	ptr_zencod_sha1_do_final = NULL ;
+	ptr_zencod_xdes_cipher = NULL ;
+	ptr_zencod_rc4_cipher = NULL ;
+
+	return 1 ;
+}
+
+
+static int zencod_ctrl ( ENGINE *e, int cmd, long i, void *p, void (*f) () )
+{
+
+	int initialised = ( ( zencod_dso == NULL ) ? 0 : 1 ) ;
+
+	CHEESE () ;
+
+	/*
+	 * We Should add some tests for non NULL parameters or bad value !!
+	 * Stuff to be done ...
+	 */
+	switch ( cmd ) {
+	case ZENCOD_CMD_SO_PATH :
+		if ( p == NULL ) {
+			ZENCODerr ( ZENCOD_F_ZENCOD_CTRL, ERR_R_PASSED_NULL_PARAMETER ) ;
+			return 0 ;
+		}
+		if ( initialised ) {
+			ZENCODerr ( ZENCOD_F_ZENCOD_CTRL, ZENCOD_R_ALREADY_LOADED ) ;
+			return 0 ;
+		}
+		ZENCOD_LIBNAME = (const char *) p ;
+		return 1 ;
+	default :
+		break ;
+	}
+
+	ZENCODerr ( ZENCOD_F_ZENCOD_CTRL, ZENCOD_R_CTRL_COMMAND_NOT_IMPLEMENTED ) ;
+
+	return 0 ;
+}
+
+
+/* BIGNUM stuff Functions
+ */
+static int zencod_bn_mod_exp ( BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx )
+{
+	zen_nb_t y, x, e, n;
+	int ret;
+
+	CHEESE () ;
+
+	if ( !zencod_dso ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_BN_MOD_EXP, ZENCOD_R_NOT_LOADED);
+		return 0;
+	}
+
+	if ( !bn_wexpand(r, m->top + 1) ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_BN_MOD_EXP, ZENCOD_R_BN_EXPAND_FAIL);
+		return 0;
+	}
+
+	memset(r->d, 0, BN_num_bytes(m));
+
+	ptr_zencod_init_number ( &y, (r->dmax - 1) * sizeof (BN_ULONG) * 8, (unsigned char *) r->d ) ;
+	BIGNUM2ZEN ( &x, a ) ;
+	BIGNUM2ZEN ( &e, p ) ;
+	BIGNUM2ZEN ( &n, m ) ;
+
+	/* Must invert x and e parameter due to BN mod exp prototype ... */
+	ret = ptr_zencod_math_mod_exp ( &y, &e, &x, &n ) ;
+
+	if ( ret )  {
+		PERROR("zenbridge_math_mod_exp");
+		ENGINEerr(ZENCOD_F_ZENCOD_BN_MOD_EXP, ZENCOD_R_REQUEST_FAILED);
+		return 0;
+	}
+
+	r->top = (BN_num_bits(m) + BN_BITS2 - 1) / BN_BITS2;
+
+	return 1;
+}
+
+
+/* RSA stuff Functions
+ */
+#ifndef OPENSSL_NO_RSA
+static int RSA_zencod_rsa_mod_exp ( BIGNUM *r0, const BIGNUM *i, RSA *rsa )
+{
+
+	CHEESE () ;
+
+	if ( !zencod_dso ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT, ZENCOD_R_NOT_LOADED);
+		return 0;
+	}
+
+	if ( !rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT, ZENCOD_R_BAD_KEY_COMPONENTS);
+		return 0;
+	}
+
+	/* Do in software if argument is too large for hardware */
+	if ( RSA_size(rsa) * 8 > ZENBRIDGE_MAX_KEYSIZE_RSA_CRT ) {
+		const RSA_METHOD *meth;
+
+		meth = RSA_PKCS1_SSLeay();
+		return meth->rsa_mod_exp(r0, i, rsa);
+	} else {
+		zen_nb_t y, x, p, q, dmp1, dmq1, iqmp;
+
+		if ( !bn_expand(r0, RSA_size(rsa) * 8) ) {
+			ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT, ZENCOD_R_BN_EXPAND_FAIL);
+			return 0;
+		}
+		r0->top = (RSA_size(rsa) * 8 + BN_BITS2 - 1) / BN_BITS2;
+
+		BIGNUM2ZEN ( &x, i ) ;
+		BIGNUM2ZEN ( &y, r0 ) ;
+		BIGNUM2ZEN ( &p, rsa->p ) ;
+		BIGNUM2ZEN ( &q, rsa->q ) ;
+		BIGNUM2ZEN ( &dmp1, rsa->dmp1 ) ;
+		BIGNUM2ZEN ( &dmq1, rsa->dmq1 ) ;
+		BIGNUM2ZEN ( &iqmp, rsa->iqmp ) ;
+
+		if ( ptr_zencod_rsa_mod_exp_crt ( &y, &x, &p, &q, &dmp1, &dmq1, &iqmp ) < 0 ) {
+			PERROR("zenbridge_rsa_mod_exp_crt");
+			ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT, ZENCOD_R_REQUEST_FAILED);
+			return 0;
+		}
+
+		return 1;
+	}
+}
+
+
+/* This function is aliased to RSA_mod_exp (with the mont stuff dropped).
+ */
+static int RSA_zencod_bn_mod_exp ( BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx )
+{
+
+	CHEESE () ;
+
+	if ( !zencod_dso ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP, ZENCOD_R_NOT_LOADED);
+		return 0;
+	}
+
+	/* Do in software if argument is too large for hardware */
+	if ( BN_num_bits(m) > ZENBRIDGE_MAX_KEYSIZE_RSA ) {
+		const RSA_METHOD *meth;
+
+		meth = RSA_PKCS1_SSLeay();
+		return meth->bn_mod_exp(r, a, p, m, ctx, m_ctx);
+	} else {
+		zen_nb_t y, x, e, n;
+
+		if ( !bn_expand(r, BN_num_bits(m)) ) {
+			ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP, ZENCOD_R_BN_EXPAND_FAIL);
+			return 0;
+		}
+		r->top = (BN_num_bits(m) + BN_BITS2 - 1) / BN_BITS2;
+
+		BIGNUM2ZEN ( &x, a ) ;
+		BIGNUM2ZEN ( &y, r ) ;
+		BIGNUM2ZEN ( &e, p ) ;
+		BIGNUM2ZEN ( &n, m ) ;
+
+		if ( ptr_zencod_rsa_mod_exp ( &y, &x, &n, &e ) < 0 ) {
+			PERROR("zenbridge_rsa_mod_exp");
+			ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP, ZENCOD_R_REQUEST_FAILED);
+			return 0;
+		}
+
+		return 1;
+	}
+}
+#endif /* !OPENSSL_NO_RSA */
+
+
+#ifndef OPENSSL_NO_DSA
+/* DSA stuff Functions
+ */
+static DSA_SIG *DSA_zencod_do_sign ( const unsigned char *dgst, int dlen, DSA *dsa )
+{
+	zen_nb_t p, q, g, x, y, r, s, data;
+	DSA_SIG *sig;
+	BIGNUM *bn_r = NULL;
+	BIGNUM *bn_s = NULL;
+	char msg[20];
+
+	CHEESE();
+
+	if ( !zencod_dso ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_NOT_LOADED);
+		goto FAILED;
+	}
+
+	if ( dlen > 160 ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED);
+		goto FAILED;
+	}
+
+	/* Do in software if argument is too large for hardware */
+	if ( BN_num_bits(dsa->p) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN ||
+		BN_num_bits(dsa->g) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN ) {
+		const DSA_METHOD *meth;
+		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BAD_KEY_COMPONENTS);
+		meth = DSA_OpenSSL();
+		return meth->dsa_do_sign(dgst, dlen, dsa);
+	}
+
+	if ( !(bn_s = BN_new()) || !(bn_r = BN_new()) ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BAD_KEY_COMPONENTS);
+		goto FAILED;
+	}
+
+	if ( !bn_expand(bn_r, 160) || !bn_expand(bn_s, 160) ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BN_EXPAND_FAIL);
+		goto FAILED;
+	}
+
+	bn_r->top = bn_s->top = (160 + BN_BITS2 - 1) / BN_BITS2;
+	BIGNUM2ZEN ( &p, dsa->p ) ;
+	BIGNUM2ZEN ( &q, dsa->q ) ;
+	BIGNUM2ZEN ( &g, dsa->g ) ;
+	BIGNUM2ZEN ( &x, dsa->priv_key ) ;
+	BIGNUM2ZEN ( &y, dsa->pub_key ) ;
+	BIGNUM2ZEN ( &r, bn_r ) ;
+	BIGNUM2ZEN ( &s, bn_s ) ;
+	q.len = x.len = 160;
+
+	ypcmem(msg, dgst, 20);
+	ptr_zencod_init_number ( &data, 160, msg ) ;
+
+	if ( ptr_zencod_dsa_do_sign ( 0, &data, &y, &p, &q, &g, &x, &r, &s ) < 0 ) {
+		PERROR("zenbridge_dsa_do_sign");
+		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED);
+		goto FAILED;
+	}
+
+	if ( !( sig = DSA_SIG_new () ) ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED);
+		goto FAILED;
+	}
+	sig->r = bn_r;
+	sig->s = bn_s;
+	return sig;
+
+ FAILED:
+	if (bn_r)
+		BN_free(bn_r);
+	if (bn_s)
+		BN_free(bn_s);
+	return NULL;
+}
+
+
+static int DSA_zencod_do_verify ( const unsigned char *dgst, int dlen, DSA_SIG *sig, DSA *dsa )
+{
+	zen_nb_t data, p, q, g, y, r, s, v;
+	char msg[20];
+	char v_data[20];
+	int ret;
+
+	CHEESE();
+
+	if ( !zencod_dso ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_VERIFY, ZENCOD_R_NOT_LOADED);
+		return 0;
+	}
+
+	if ( dlen > 160 ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED);
+		return 0;
+	}
+
+	/* Do in software if argument is too large for hardware */
+	if ( BN_num_bits(dsa->p) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN ||
+		BN_num_bits(dsa->g) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN ) {
+		const DSA_METHOD *meth;
+		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BAD_KEY_COMPONENTS);
+		meth = DSA_OpenSSL();
+		return meth->dsa_do_verify(dgst, dlen, sig, dsa);
+	}
+
+	BIGNUM2ZEN ( &p, dsa->p ) ;
+	BIGNUM2ZEN ( &q, dsa->q ) ;
+	BIGNUM2ZEN ( &g, dsa->g ) ;
+	BIGNUM2ZEN ( &y, dsa->pub_key ) ;
+	BIGNUM2ZEN ( &r, sig->r ) ;
+	BIGNUM2ZEN ( &s, sig->s ) ;
+	ptr_zencod_init_number ( &v, 160, v_data ) ;
+	ypcmem(msg, dgst, 20);
+	ptr_zencod_init_number ( &data, 160, msg ) ;
+
+	if ( ( ret = ptr_zencod_dsa_do_verify ( 0, &data, &p, &q, &g, &y, &r, &s, &v ) ) < 0 ) {
+		PERROR("zenbridge_dsa_do_verify");
+		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_VERIFY, ZENCOD_R_REQUEST_FAILED);
+		return 0;
+	}
+
+	return ( ( ret == 0 ) ? 1 : ret ) ;
+}
+
+
+static int DSA_zencod_bn_mod_exp ( DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+			     BN_CTX *ctx, BN_MONT_CTX *m_ctx )
+{
+	CHEESE () ;
+
+	return zencod_bn_mod_exp ( r, a, p, m, ctx ) ;
+}
+#endif /* !OPENSSL_NO_DSA */
+
+
+#ifndef OPENSSl_NO_DH
+/* DH stuff Functions
+ */
+static int DH_zencod_generate_key ( DH *dh )
+{
+	BIGNUM *bn_prv = NULL;
+	BIGNUM *bn_pub = NULL;
+	zen_nb_t y, x, g, p;
+	int generate_x;
+
+	CHEESE();
+
+	if ( !zencod_dso ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_NOT_LOADED);
+		return 0;
+	}
+
+	/* Private key */
+	if ( dh->priv_key ) {
+		bn_prv = dh->priv_key;
+		generate_x = 0;
+	} else {
+		if (!(bn_prv = BN_new())) {
+			ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_BN_EXPAND_FAIL);
+			goto FAILED;
+		}
+		generate_x = 1;
+	}
+
+	/* Public key */
+	if ( dh->pub_key )
+		bn_pub = dh->pub_key;
+	else
+		if ( !( bn_pub = BN_new () ) ) {
+			ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_BN_EXPAND_FAIL);
+			goto FAILED;
+		}
+
+	/* Expand */
+	if ( !bn_wexpand ( bn_prv, dh->p->dmax ) ||
+	    !bn_wexpand ( bn_pub, dh->p->dmax ) ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_BN_EXPAND_FAIL);
+		goto FAILED;
+	}
+	bn_prv->top = dh->p->top;
+	bn_pub->top = dh->p->top;
+
+	/* Convert all keys */
+	BIGNUM2ZEN ( &p, dh->p ) ;
+	BIGNUM2ZEN ( &g, dh->g ) ;
+	BIGNUM2ZEN ( &y, bn_pub ) ;
+	BIGNUM2ZEN ( &x, bn_prv ) ;
+	x.len = DH_size(dh) * 8;
+
+	/* Adjust the lengths of P and G */
+	p.len = ptr_zencod_bytes2bits ( p.data, ZEN_BYTES ( p.len ) ) ;
+	g.len = ptr_zencod_bytes2bits ( g.data, ZEN_BYTES ( g.len ) ) ;
+
+	/* Send the request to the driver */
+	if ( ptr_zencod_dh_generate_key ( &y, &x, &g, &p, generate_x ) < 0 ) {
+		perror("zenbridge_dh_generate_key");
+		ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_REQUEST_FAILED);
+		goto FAILED;
+	}
+
+	dh->priv_key = bn_prv;
+	dh->pub_key  = bn_pub;
+
+	return 1;
+
+ FAILED:
+	if (!dh->priv_key && bn_prv)
+		BN_free(bn_prv);
+	if (!dh->pub_key && bn_pub)
+		BN_free(bn_pub);
+
+	return 0;
+}
+
+
+static int DH_zencod_compute_key ( unsigned char *key, const BIGNUM *pub_key, DH *dh )
+{
+	zen_nb_t y, x, p, k;
+
+	CHEESE();
+
+	if ( !zencod_dso ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_DH_COMPUTE, ZENCOD_R_NOT_LOADED);
+		return 0;
+	}
+
+	if ( !dh->priv_key ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_DH_COMPUTE, ZENCOD_R_BAD_KEY_COMPONENTS);
+		return 0;
+	}
+
+	/* Convert all keys */
+	BIGNUM2ZEN ( &y, pub_key ) ;
+	BIGNUM2ZEN ( &x, dh->priv_key ) ;
+	BIGNUM2ZEN ( &p, dh->p ) ;
+	ptr_zencod_init_number ( &k, p.len, key ) ;
+
+	/* Adjust the lengths */
+	p.len = ptr_zencod_bytes2bits ( p.data, ZEN_BYTES ( p.len ) ) ;
+	y.len = ptr_zencod_bytes2bits ( y.data, ZEN_BYTES ( y.len ) ) ;
+	x.len = ptr_zencod_bytes2bits ( x.data, ZEN_BYTES ( x.len ) ) ;
+
+	/* Call the hardware */
+	if ( ptr_zencod_dh_compute_key ( &k, &y, &x, &p ) < 0 ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_DH_COMPUTE, ZENCOD_R_REQUEST_FAILED);
+		return 0;
+	}
+
+	/* The key must be written MSB -> LSB */
+	k.len = ptr_zencod_bytes2bits ( k.data, ZEN_BYTES ( k.len ) ) ;
+	esrever ( key, ZEN_BYTES ( k.len ) ) ;
+
+	return ZEN_BYTES ( k.len ) ;
+}
+
+
+static int DH_zencod_bn_mod_exp ( const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+		BN_MONT_CTX *m_ctx )
+{
+	CHEESE () ;
+
+	return zencod_bn_mod_exp ( r, a, p, m, ctx ) ;
+}
+#endif	/* !OPENSSL_NO_DH */
+
+
+/* RAND stuff Functions
+ */
+static void RAND_zencod_seed ( const void *buf, int num )
+{
+	/* Nothing to do cause our crypto accelerator provide a true random generator */
+}
+
+
+static int RAND_zencod_rand_bytes ( unsigned char *buf, int num )
+{
+	zen_nb_t r;
+
+	CHEESE();
+
+	if ( !zencod_dso ) {
+		ENGINEerr(ZENCOD_F_ZENCOD_RAND, ZENCOD_R_NOT_LOADED);
+		return 0;
+	}
+
+	ptr_zencod_init_number ( &r, num * 8, buf ) ;
+
+	if ( ptr_zencod_rand_bytes ( &r, ZENBRIDGE_RNG_DIRECT ) < 0 ) {
+		PERROR("zenbridge_rand_bytes");
+		ENGINEerr(ZENCOD_F_ZENCOD_RAND, ZENCOD_R_REQUEST_FAILED);
+		return 0;
+	}
+
+	return 1;
+}
+
+
+static int RAND_zencod_rand_status ( void )
+{
+	CHEESE () ;
+
+	return 1;
+}
+
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library.
+ */
+#ifdef ENGINE_DYNAMIC_SUPPORT
+static int bind_fn ( ENGINE *e, const char *id )
+{
+
+	if ( id && ( strcmp ( id, engine_zencod_id ) != 0 ) ) {
+		return 0 ;
+	}
+	if ( !bind_helper ( e ) )  {
+		return 0 ;
+	}
+
+	return 1 ;
+}
+
+IMPLEMENT_DYNAMIC_CHECK_FN ()
+IMPLEMENT_DYNAMIC_BIND_FN ( bind_fn )
+#endif /* ENGINE_DYNAMIC_SUPPORT */
+
+
+
+
+/*
+ * Adding "Digest" and "Cipher" tools ...
+ * This is in development ... ;-)
+ * In orfer to code this, i refer to hw_openbsd_dev_crypto and openssl engine made by Geoff Thorpe (if i'm rigth),
+ * and evp, sha md5 definitions etc ...
+ */
+/* First add some include ... */
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+#include <openssl/md5.h>
+#include <openssl/rc4.h>
+#include <openssl/des.h>
+
+
+/* Some variables declaration ... */
+/* DONS:
+ * Disable symetric computation except DES and 3DES, but let part of the code
+ */
+/* static int engine_digest_nids [ ] = { NID_sha1, NID_md5 } ; */
+static int engine_digest_nids [ ] = {  } ;
+static int engine_digest_nids_num = 0 ;
+/* static int engine_cipher_nids [ ] = { NID_rc4, NID_rc4_40, NID_des_cbc, NID_des_ede3_cbc } ; */
+static int engine_cipher_nids [ ] = { NID_des_cbc, NID_des_ede3_cbc } ;
+static int engine_cipher_nids_num = 2 ;
+
+
+/* Function prototype ... */
+/*  SHA stuff */
+static int engine_sha1_init ( EVP_MD_CTX *ctx ) ;
+static int engine_sha1_update ( EVP_MD_CTX *ctx, const void *data, unsigned long count ) ;
+static int engine_sha1_final ( EVP_MD_CTX *ctx, unsigned char *md ) ;
+
+/*  MD5 stuff */
+static int engine_md5_init ( EVP_MD_CTX *ctx ) ;
+static int engine_md5_update ( EVP_MD_CTX *ctx, const void *data, unsigned long count ) ;
+static int engine_md5_final ( EVP_MD_CTX *ctx, unsigned char *md ) ;
+
+static int engine_md_cleanup ( EVP_MD_CTX *ctx ) ;
+static int engine_md_copy ( EVP_MD_CTX *to, const EVP_MD_CTX *from ) ;
+
+
+/* RC4 Stuff */
+static int engine_rc4_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc ) ;
+static int engine_rc4_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl ) ;
+
+/* DES Stuff */
+static int engine_des_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc ) ;
+static int engine_des_cbc_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl ) ;
+
+/*  3DES Stuff */
+static int engine_des_ede3_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc ) ;
+static int engine_des_ede3_cbc_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out,const unsigned char *in, unsigned int inl ) ;
+
+static int engine_cipher_cleanup ( EVP_CIPHER_CTX *ctx ) ;	/* cleanup ctx */
+
+
+/* The one for SHA ... */
+static const EVP_MD engine_sha1_md =
+{
+	NID_sha1,
+	NID_sha1WithRSAEncryption,
+	SHA_DIGEST_LENGTH,
+	EVP_MD_FLAG_ONESHOT,
+	/* 0, */			/* EVP_MD_FLAG_ONESHOT = x0001 digest can only handle a single block
+				* XXX: set according to device info ... */
+	engine_sha1_init,
+	engine_sha1_update,
+	engine_sha1_final,
+	engine_md_copy,		/* dev_crypto_sha_copy */
+	engine_md_cleanup,		/* dev_crypto_sha_cleanup */
+	EVP_PKEY_RSA_method,
+	SHA_CBLOCK,
+	/* sizeof ( EVP_MD * ) + sizeof ( SHA_CTX ) */
+	sizeof ( ZEN_MD_DATA )
+	/* sizeof ( MD_CTX_DATA )	The message digest data structure ... */
+} ;
+
+/* The one for MD5 ... */
+static const EVP_MD engine_md5_md =
+{
+	NID_md5,
+	NID_md5WithRSAEncryption,
+	MD5_DIGEST_LENGTH,
+	EVP_MD_FLAG_ONESHOT,
+	/* 0, */			/* EVP_MD_FLAG_ONESHOT = x0001 digest can only handle a single block
+				* XXX: set according to device info ... */
+	engine_md5_init,
+	engine_md5_update,
+	engine_md5_final,
+	engine_md_copy,		/* dev_crypto_md5_copy */
+	engine_md_cleanup,		/* dev_crypto_md5_cleanup */
+	EVP_PKEY_RSA_method,
+	MD5_CBLOCK,
+	/* sizeof ( EVP_MD * ) + sizeof ( MD5_CTX ) */
+	sizeof ( ZEN_MD_DATA )
+	/* sizeof ( MD_CTX_DATA )	The message digest data structure ... */
+} ;
+
+
+/* The one for RC4 ... */
+#define EVP_RC4_KEY_SIZE			16
+
+/* Try something static ... */
+typedef struct
+{
+	unsigned int len ;
+	unsigned int first ;
+	unsigned char rc4_state [ 260 ] ;
+} NEW_ZEN_RC4_KEY ;
+
+#define rc4_data(ctx)				( (EVP_RC4_KEY *) ( ctx )->cipher_data )
+
+static const EVP_CIPHER engine_rc4 =
+{
+	NID_rc4,
+	1,
+	16,				/* EVP_RC4_KEY_SIZE should be 128 bits */
+	0,				/* FIXME: key should be up to 256 bytes */
+	EVP_CIPH_VARIABLE_LENGTH,
+	engine_rc4_init_key,
+	engine_rc4_cipher,
+	engine_cipher_cleanup,
+	sizeof ( NEW_ZEN_RC4_KEY ),
+	NULL,
+	NULL,
+	NULL
+} ;
+
+/* The one for RC4_40 ... */
+static const EVP_CIPHER engine_rc4_40 =
+{
+	NID_rc4_40,
+	1,
+	5,				/* 40 bits */
+	0,
+	EVP_CIPH_VARIABLE_LENGTH,
+	engine_rc4_init_key,
+	engine_rc4_cipher,
+	engine_cipher_cleanup,
+	sizeof ( NEW_ZEN_RC4_KEY ),
+	NULL,
+	NULL,
+	NULL
+} ;
+
+/* The one for DES ... */
+
+/* Try something static ... */
+typedef struct
+{
+	unsigned char des_key [ 24 ] ;
+	unsigned char des_iv [ 8 ] ;
+} ZEN_DES_KEY ;
+
+static const EVP_CIPHER engine_des_cbc =
+	{
+	NID_des_cbc,
+	8, 8, 8,
+	0 | EVP_CIPH_CBC_MODE,
+	engine_des_init_key,
+	engine_des_cbc_cipher,
+	engine_cipher_cleanup,
+	sizeof(ZEN_DES_KEY),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL,
+	NULL
+	};
+
+/* The one for 3DES ... */
+
+/* Try something static ... */
+typedef struct
+{
+	unsigned char des3_key [ 24 ] ;
+	unsigned char des3_iv [ 8 ] ;
+} ZEN_3DES_KEY ;
+
+#define des_data(ctx)				 ( (DES_EDE_KEY *) ( ctx )->cipher_data )
+
+static const EVP_CIPHER engine_des_ede3_cbc =
+	{
+	NID_des_ede3_cbc,
+	8, 8, 8,
+	0 | EVP_CIPH_CBC_MODE,
+	engine_des_ede3_init_key,
+	engine_des_ede3_cbc_cipher,
+	engine_cipher_cleanup,
+	sizeof(ZEN_3DES_KEY),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL,
+	NULL
+	};
+
+
+/* General function cloned on hw_openbsd_dev_crypto one ... */
+static int engine_digests ( ENGINE *e, const EVP_MD **digest, const int **nids, int nid )
+{
+
+#ifdef DEBUG_ZENCOD_MD
+	fprintf ( stderr, "\t=>Function : static int engine_digests () called !\n" ) ;
+#endif
+
+	if ( !digest ) {
+		/* We are returning a list of supported nids */
+		*nids = engine_digest_nids ;
+		return engine_digest_nids_num ;
+	}
+	/* We are being asked for a specific digest */
+	if ( nid == NID_md5 ) {
+		*digest = &engine_md5_md ;
+	}
+	else if ( nid == NID_sha1 ) {
+		*digest = &engine_sha1_md ;
+	}
+	else {
+		*digest = NULL ;
+		return 0 ;
+	}
+	return 1 ;
+}
+
+
+/* SHA stuff Functions
+ */
+static int engine_sha1_init ( EVP_MD_CTX *ctx )
+{
+
+	int to_return = 0 ;
+
+	/* Test with zenbridge library ... */
+	to_return = ptr_zencod_sha1_init ( (ZEN_MD_DATA *) ctx->md_data ) ;
+	to_return = !to_return ;
+
+	return to_return ;
+}
+
+
+static int engine_sha1_update ( EVP_MD_CTX *ctx, const void *data, unsigned long count )
+{
+
+	zen_nb_t input ;
+	int to_return = 0 ;
+
+	/* Convert parameters ... */
+	input.len = count ;
+	input.data = (unsigned char *) data ;
+
+	/* Test with zenbridge library ... */
+	to_return = ptr_zencod_sha1_update ( (ZEN_MD_DATA *) ctx->md_data, (const zen_nb_t *) &input ) ;
+	to_return = !to_return ;
+
+	return to_return ;
+}
+
+
+static int engine_sha1_final ( EVP_MD_CTX *ctx, unsigned char *md )
+{
+
+	zen_nb_t output ;
+	int to_return = 0 ;
+
+	/* Convert parameters ... */
+	output.len = SHA_DIGEST_LENGTH ;
+	output.data = md ;
+
+	/* Test with zenbridge library ... */
+	to_return = ptr_zencod_sha1_do_final ( (ZEN_MD_DATA *) ctx->md_data, (zen_nb_t *) &output ) ;
+	to_return = !to_return ;
+
+	return to_return ;
+}
+
+
+
+/* MD5 stuff Functions
+ */
+static int engine_md5_init ( EVP_MD_CTX *ctx )
+{
+
+	int to_return = 0 ;
+
+	/* Test with zenbridge library ... */
+	to_return = ptr_zencod_md5_init ( (ZEN_MD_DATA *) ctx->md_data ) ;
+	to_return = !to_return ;
+
+	return to_return ;
+}
+
+
+static int engine_md5_update ( EVP_MD_CTX *ctx, const void *data, unsigned long count )
+{
+
+	zen_nb_t input ;
+	int to_return = 0 ;
+
+	/* Convert parameters ... */
+	input.len = count ;
+	input.data = (unsigned char *) data ;
+
+	/* Test with zenbridge library ... */
+	to_return = ptr_zencod_md5_update ( (ZEN_MD_DATA *) ctx->md_data, (const zen_nb_t *) &input ) ;
+	to_return = !to_return ;
+
+	return to_return ;
+}
+
+
+static int engine_md5_final ( EVP_MD_CTX *ctx, unsigned char *md )
+{
+
+	zen_nb_t output ;
+	int to_return = 0 ;
+
+	/* Convert parameters ... */
+	output.len = MD5_DIGEST_LENGTH ;
+	output.data = md ;
+
+	/* Test with zenbridge library ... */
+	to_return = ptr_zencod_md5_do_final ( (ZEN_MD_DATA *) ctx->md_data, (zen_nb_t *) &output ) ;
+	to_return = !to_return ;
+
+	return to_return ;
+}
+
+
+static int engine_md_cleanup ( EVP_MD_CTX *ctx )
+{
+
+	ZEN_MD_DATA *zen_md_data = (ZEN_MD_DATA *) ctx->md_data ;
+
+	if ( zen_md_data->HashBuffer != NULL ) {
+		OPENSSL_free ( zen_md_data->HashBuffer ) ;
+		zen_md_data->HashBufferSize = 0 ;
+		ctx->md_data = NULL ;
+	}
+
+	return 1 ;
+}
+
+
+static int engine_md_copy ( EVP_MD_CTX *to, const EVP_MD_CTX *from )
+{
+	const ZEN_MD_DATA *from_md = (ZEN_MD_DATA *) from->md_data ;
+	ZEN_MD_DATA *to_md = (ZEN_MD_DATA *) to->md_data ;
+
+	to_md->HashBuffer = OPENSSL_malloc ( from_md->HashBufferSize ) ;
+	memcpy ( to_md->HashBuffer, from_md->HashBuffer, from_md->HashBufferSize ) ;
+
+	return 1;
+}
+
+
+/* General function cloned on hw_openbsd_dev_crypto one ... */
+static int engine_ciphers ( ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid )
+{
+
+	if ( !cipher ) {
+		/* We are returning a list of supported nids */
+		*nids = engine_cipher_nids ;
+		return engine_cipher_nids_num ;
+	}
+	/* We are being asked for a specific cipher */
+	if ( nid == NID_rc4 ) {
+		*cipher = &engine_rc4 ;
+	}
+	else if ( nid == NID_rc4_40 ) {
+		*cipher = &engine_rc4_40 ;
+	}
+	else if ( nid == NID_des_cbc ) {
+		*cipher = &engine_des_cbc ;
+	}
+	else if ( nid == NID_des_ede3_cbc ) {
+		*cipher = &engine_des_ede3_cbc ;
+	}
+	else {
+		*cipher = NULL ;
+		return 0 ;
+	}
+
+	return 1 ;
+}
+
+
+static int engine_rc4_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc )
+{
+	int to_return = 0 ;
+	int i = 0 ;
+	int nb = 0 ;
+	NEW_ZEN_RC4_KEY *tmp_rc4_key = NULL ;
+
+	tmp_rc4_key = (NEW_ZEN_RC4_KEY *) ( ctx->cipher_data ) ;
+	tmp_rc4_key->first = 0 ;
+	tmp_rc4_key->len = ctx->key_len ;
+	tmp_rc4_key->rc4_state [ 0 ] = 0x00 ;
+	tmp_rc4_key->rc4_state [ 2 ] = 0x00 ;
+	nb = 256 / ctx->key_len ;
+	for ( i = 0; i < nb ; i++ ) {
+		memcpy ( &( tmp_rc4_key->rc4_state [ 4 + i*ctx->key_len ] ), key, ctx->key_len ) ;
+	}
+
+	to_return = 1 ;
+
+	return to_return ;
+}
+
+
+static int engine_rc4_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int in_len )
+{
+
+	zen_nb_t output, input ;
+	zen_nb_t rc4key ;
+	int to_return = 0 ;
+	NEW_ZEN_RC4_KEY *tmp_rc4_key = NULL ;
+
+	/* Convert parameters ... */
+	input.len = in_len ;
+	input.data = (unsigned char *) in ;
+	output.len = in_len ;
+	output.data = (unsigned char *) out ;
+
+	tmp_rc4_key = ( (NEW_ZEN_RC4_KEY *) ( ctx->cipher_data ) ) ;
+	rc4key.len = 260 ;
+	rc4key.data = &( tmp_rc4_key->rc4_state [ 0 ] ) ;
+
+	/* Test with zenbridge library ... */
+	to_return = ptr_zencod_rc4_cipher ( &output, &input, (const zen_nb_t *) &rc4key, &( tmp_rc4_key->rc4_state [0] ), &( tmp_rc4_key->rc4_state [3] ), !tmp_rc4_key->first ) ;
+	to_return = !to_return ;
+
+	/* Update encryption state ... */
+	tmp_rc4_key->first = 1 ;
+	tmp_rc4_key = NULL ;
+
+	return to_return ;
+}
+
+
+static int engine_des_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc )
+{
+
+	ZEN_DES_KEY *tmp_des_key = NULL ;
+	int to_return = 0 ;
+
+	tmp_des_key = (ZEN_DES_KEY *) ( ctx->cipher_data ) ;
+	memcpy ( &( tmp_des_key->des_key [ 0 ] ), key, 8 ) ;
+	memcpy ( &( tmp_des_key->des_key [ 8 ] ), key, 8 ) ;
+	memcpy ( &( tmp_des_key->des_key [ 16 ] ), key, 8 ) ;
+	memcpy ( &( tmp_des_key->des_iv [ 0 ] ), iv, 8 ) ;
+
+	to_return = 1 ;
+
+	return to_return ;
+}
+
+
+static int engine_des_cbc_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl )
+{
+
+	zen_nb_t output, input ;
+	zen_nb_t deskey_1, deskey_2, deskey_3, iv ;
+	int to_return = 0 ;
+
+	/* Convert parameters ... */
+	input.len = inl ;
+	input.data = (unsigned char *) in ;
+	output.len = inl ;
+	output.data = out ;
+
+	/* Set key parameters ... */
+	deskey_1.len = 8 ;
+	deskey_2.len = 8 ;
+	deskey_3.len = 8 ;
+	deskey_1.data = (unsigned char *) ( (ZEN_DES_KEY *) ( ctx->cipher_data ) )->des_key ;
+	deskey_2.data =  (unsigned char *) &( (ZEN_DES_KEY *) ( ctx->cipher_data ) )->des_key [ 8 ] ;
+	deskey_3.data =  (unsigned char *) &( (ZEN_DES_KEY *) ( ctx->cipher_data ) )->des_key [ 16 ] ;
+
+	/* Key correct iv ... */
+	memcpy ( ( (ZEN_DES_KEY *) ( ctx->cipher_data ) )->des_iv, ctx->iv, 8 ) ;
+	iv.len = 8 ;
+	iv.data = (unsigned char *) ( (ZEN_DES_KEY *) ( ctx->cipher_data ) )->des_iv ;
+
+	if ( ctx->encrypt == 0 ) {
+		memcpy ( ctx->iv, &( input.data [ input.len - 8 ] ), 8 ) ;
+	}
+
+	/* Test with zenbridge library ... */
+	to_return = ptr_zencod_xdes_cipher ( &output, &input,
+			(zen_nb_t *) &deskey_1, (zen_nb_t *) &deskey_2, (zen_nb_t *) &deskey_3, &iv, ctx->encrypt ) ;
+	to_return = !to_return ;
+
+	/* But we need to set up the rigth iv ...
+	 * Test ENCRYPT or DECRYPT mode to set iv ... */
+	if ( ctx->encrypt == 1 ) {
+		memcpy ( ctx->iv, &( output.data [ output.len - 8 ] ), 8 ) ;
+	}
+
+	return to_return ;
+}
+
+
+static int engine_des_ede3_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc )
+{
+
+	ZEN_3DES_KEY *tmp_3des_key = NULL ;
+	int to_return = 0 ;
+
+	tmp_3des_key = (ZEN_3DES_KEY *) ( ctx->cipher_data ) ;
+	memcpy ( &( tmp_3des_key->des3_key [ 0 ] ), key, 24 ) ;
+	memcpy ( &( tmp_3des_key->des3_iv [ 0 ] ), iv, 8 ) ;
+
+	to_return = 1;
+
+	return to_return ;
+}
+
+
+static int engine_des_ede3_cbc_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
+	unsigned int in_len )
+{
+
+	zen_nb_t output, input ;
+	zen_nb_t deskey_1, deskey_2, deskey_3, iv ;
+	int to_return = 0 ;
+
+	/* Convert parameters ... */
+	input.len = in_len ;
+	input.data = (unsigned char *) in ;
+	output.len = in_len ;
+	output.data = out ;
+
+	/* Set key ... */
+	deskey_1.len = 8 ;
+	deskey_2.len = 8 ;
+	deskey_3.len = 8 ;
+	deskey_1.data =  (unsigned char *) ( (ZEN_3DES_KEY *) ( ctx->cipher_data ) )->des3_key ;
+	deskey_2.data =  (unsigned char *) &( (ZEN_3DES_KEY *) ( ctx->cipher_data ) )->des3_key [ 8 ] ;
+	deskey_3.data =  (unsigned char *) &( (ZEN_3DES_KEY *) ( ctx->cipher_data ) )->des3_key [ 16 ] ;
+
+	/* Key correct iv ... */
+	memcpy ( ( (ZEN_3DES_KEY *) ( ctx->cipher_data ) )->des3_iv, ctx->iv, 8 ) ;
+	iv.len = 8 ;
+	iv.data = (unsigned char *) ( (ZEN_3DES_KEY *) ( ctx->cipher_data ) )->des3_iv ;
+
+	if ( ctx->encrypt == 0 ) {
+		memcpy ( ctx->iv, &( input.data [ input.len - 8 ] ), 8 ) ;
+	}
+
+	/* Test with zenbridge library ... */
+	to_return = ptr_zencod_xdes_cipher ( &output, &input,
+			(zen_nb_t *) &deskey_1, (zen_nb_t *) &deskey_2, (zen_nb_t *) &deskey_3, &iv, ctx->encrypt ) ;
+	to_return = !to_return ;
+
+	if ( ctx->encrypt == 1 ) {
+		memcpy ( ctx->iv, &( output.data [ output.len - 8 ] ), 8 ) ;
+	}
+
+	return to_return ;
+}
+
+
+static int engine_cipher_cleanup ( EVP_CIPHER_CTX *ctx )
+{
+
+	/* Set the key pointer ... */
+	if ( ctx->cipher->nid == NID_rc4 || ctx->cipher->nid == NID_rc4_40 ) {
+	}
+	else if ( ctx->cipher->nid == NID_des_cbc ) {
+	}
+	else if ( ctx->cipher->nid == NID_des_ede3_cbc ) {
+	}
+
+	return 1 ;
+}
+
+
+#endif /* !OPENSSL_NO_HW_ZENCOD */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/demos/engines/zencod/hw_zencod.ec b/openssl/demos/engines/zencod/hw_zencod.ec
new file mode 100644
index 0000000..1552c79
--- /dev/null
+++ b/openssl/demos/engines/zencod/hw_zencod.ec
@@ -0,0 +1,8 @@
+# configuration file for util/mkerr.pl
+#
+# use like this:
+#
+#	perl ../../../util/mkerr.pl -conf hw_zencod.ec \
+#		-nostatic -staticloader -write *.c
+
+L ZENCOD	hw_zencod_err.h			hw_zencod_err.c
diff --git a/openssl/demos/engines/zencod/hw_zencod.h b/openssl/demos/engines/zencod/hw_zencod.h
new file mode 100644
index 0000000..415c9a6
--- /dev/null
+++ b/openssl/demos/engines/zencod/hw_zencod.h
@@ -0,0 +1,160 @@
+/* File : /crypto/engine/vendor_defns/hw_zencod.h */
+/* ====================================================================
+ * Written by Donnat Frederic (frederic.donnat@zencod.com) from ZENCOD
+ * for "zencod" ENGINE integration in OpenSSL project.
+ */
+
+
+ #ifndef	_HW_ZENCOD_H_
+#define	_HW_ZENCOD_H_
+
+#include <stdio.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif	/* __cplusplus */
+
+#define ZENBRIDGE_MAX_KEYSIZE_RSA	2048
+#define ZENBRIDGE_MAX_KEYSIZE_RSA_CRT	1024
+#define ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN	1024
+#define ZENBRIDGE_MAX_KEYSIZE_DSA_VRFY	1024
+
+/* Library version computation */
+#define	ZENBRIDGE_VERSION_MAJOR(x)	(((x) >> 16) | 0xff)
+#define	ZENBRIDGE_VERSION_MINOR(x)	(((x) >>  8) | 0xff)
+#define	ZENBRIDGE_VERSION_PATCH(x)	(((x) >>  0) | 0xff)
+#define	ZENBRIDGE_VERSION(x, y, z)		((x) << 16 | (y) << 8 | (z))
+
+/*
+ * Memory type
+ */
+typedef struct zencod_number_s {
+	unsigned long len;
+	unsigned char *data;
+} zen_nb_t;
+
+#define KEY	zen_nb_t
+
+
+/*
+ * Misc
+ */
+typedef int t_zencod_lib_version (void);
+typedef int t_zencod_hw_version (void);
+typedef int t_zencod_test (void);
+typedef int t_zencod_dump_key (FILE *stream, char *msg, KEY *key);
+
+
+/*
+ * Key management tools
+ */
+typedef KEY *t_zencod_new_number (unsigned long len, unsigned char *data);
+typedef int t_zencod_init_number (KEY *n, unsigned long len, unsigned char *data);
+typedef unsigned long t_zencod_bytes2bits (unsigned char *n, unsigned long bytes);
+typedef unsigned long t_zencod_bits2bytes (unsigned long bits);
+
+
+/*
+ * RSA API
+ */
+/* Compute modular exponential : y = x**e | n */
+typedef int t_zencod_rsa_mod_exp (KEY *y, KEY *x, KEY *n, KEY *e);
+/* Compute modular exponential : y1 = (x | p)**edp | p, y2 = (x | p)**edp | p, y = y2 + (qinv * (y1 - y2) | p) * q */
+typedef int t_zencod_rsa_mod_exp_crt (KEY *y, KEY *x, KEY *p, KEY *q,
+					KEY *edp, KEY *edq, KEY *qinv);
+
+
+/*
+ * DSA API
+ */
+typedef int t_zencod_dsa_do_sign (unsigned int hash, KEY *data, KEY *random,
+				    KEY *p, KEY *q, KEY *g, KEY *x, KEY *r, KEY *s);
+typedef int t_zencod_dsa_do_verify (unsigned int hash, KEY *data,
+				      KEY *p, KEY *q, KEY *g, KEY *y,
+				      KEY *r, KEY *s, KEY *v);
+
+
+/*
+ * DH API
+ */
+ /* Key generation : compute public value y = g**x | n */
+typedef int t_zencod_dh_generate_key (KEY *y, KEY *x, KEY *g, KEY *n, int gen_x);
+typedef int t_zencod_dh_compute_key (KEY *k, KEY *y, KEY *x, KEY *n);
+
+
+/*
+ * RNG API
+ */
+#define ZENBRIDGE_RNG_DIRECT		0
+#define ZENBRIDGE_RNG_SHA1		1
+typedef int t_zencod_rand_bytes (KEY *rand, unsigned int flags);
+
+
+/*
+ * Math API
+ */
+typedef int t_zencod_math_mod_exp (KEY *r, KEY *a, KEY *e, KEY *n);
+
+
+
+
+/*
+ * Symetric API
+ */
+/* Define a data structure for digests operations */
+typedef struct ZEN_data_st
+{
+	unsigned int HashBufferSize ;
+	unsigned char *HashBuffer ;
+} ZEN_MD_DATA ;
+
+/*
+ * Functions for Digest (MD5, SHA1) stuff
+ */
+/* output : output data buffer */
+/* input : input data buffer */
+/* algo : hash algorithm, MD5 or SHA1 */
+/* typedef int t_zencod_hash ( KEY *output, const KEY *input, int algo ) ;
+ * typedef int t_zencod_sha_hash ( KEY *output, const KEY *input, int algo ) ;
+ */
+/* For now separate this stuff that mad it easier to test */
+typedef int t_zencod_md5_init ( ZEN_MD_DATA *data ) ;
+typedef int t_zencod_md5_update ( ZEN_MD_DATA *data, const KEY *input ) ;
+typedef int t_zencod_md5_do_final ( ZEN_MD_DATA *data, KEY *output ) ;
+
+typedef int t_zencod_sha1_init ( ZEN_MD_DATA *data ) ;
+typedef int t_zencod_sha1_update ( ZEN_MD_DATA *data, const KEY *input ) ;
+typedef int t_zencod_sha1_do_final ( ZEN_MD_DATA *data, KEY *output ) ;
+
+
+/*
+ * Functions for Cipher (RC4, DES, 3DES) stuff
+ */
+/* output : output data buffer */
+/* input : input data buffer */
+/* key : rc4 key data */
+/* index_1 : value of index x from RC4 key structure */
+/* index_2 : value of index y from RC4 key structure */
+/* Be carefull : RC4 key should be expanded before calling this method (Should we provide an expand function ??) */
+typedef int t_zencod_rc4_cipher ( KEY *output, const KEY *input, const KEY *key,
+		unsigned char *index_1, unsigned char *index_2, int mode ) ;
+
+/* output : output data buffer */
+/* input : input data buffer */
+/* key_1 : des first key data */
+/* key_2 : des second key data */
+/* key_3 : des third key data */
+/* iv : initial vector */
+/* mode : xdes mode (encrypt or decrypt) */
+/* Be carefull : In DES mode key_1 = key_2 = key_3 (as far as i can see !!) */
+typedef int t_zencod_xdes_cipher ( KEY *output, const KEY *input, const KEY *key_1,
+		const KEY *key_2, const KEY *key_3, const KEY *iv, int mode ) ;
+
+
+#undef KEY
+
+#ifdef	__cplusplus
+}
+#endif	/* __cplusplus */
+
+#endif	/* !_HW_ZENCOD_H_ */
diff --git a/openssl/demos/engines/zencod/hw_zencod_err.c b/openssl/demos/engines/zencod/hw_zencod_err.c
new file mode 100644
index 0000000..8ed0fff
--- /dev/null
+++ b/openssl/demos/engines/zencod/hw_zencod_err.c
@@ -0,0 +1,151 @@
+/* hw_zencod_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "hw_zencod_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+static ERR_STRING_DATA ZENCOD_str_functs[]=
+	{
+{ERR_PACK(0,ZENCOD_F_ZENCOD_BN_MOD_EXP,0),	"ZENCOD_BN_MOD_EXP"},
+{ERR_PACK(0,ZENCOD_F_ZENCOD_CTRL,0),	"ZENCOD_CTRL"},
+{ERR_PACK(0,ZENCOD_F_ZENCOD_DH_COMPUTE,0),	"ZENCOD_DH_COMPUTE"},
+{ERR_PACK(0,ZENCOD_F_ZENCOD_DH_GENERATE,0),	"ZENCOD_DH_GENERATE"},
+{ERR_PACK(0,ZENCOD_F_ZENCOD_DSA_DO_SIGN,0),	"ZENCOD_DSA_DO_SIGN"},
+{ERR_PACK(0,ZENCOD_F_ZENCOD_DSA_DO_VERIFY,0),	"ZENCOD_DSA_DO_VERIFY"},
+{ERR_PACK(0,ZENCOD_F_ZENCOD_FINISH,0),	"ZENCOD_FINISH"},
+{ERR_PACK(0,ZENCOD_F_ZENCOD_INIT,0),	"ZENCOD_INIT"},
+{ERR_PACK(0,ZENCOD_F_ZENCOD_RAND,0),	"ZENCOD_RAND"},
+{ERR_PACK(0,ZENCOD_F_ZENCOD_RSA_MOD_EXP,0),	"ZENCOD_RSA_MOD_EXP"},
+{ERR_PACK(0,ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT,0),	"ZENCOD_RSA_MOD_EXP_CRT"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA ZENCOD_str_reasons[]=
+	{
+{ZENCOD_R_ALREADY_LOADED                 ,"already loaded"},
+{ZENCOD_R_BAD_KEY_COMPONENTS             ,"bad key components"},
+{ZENCOD_R_BN_EXPAND_FAIL                 ,"bn expand fail"},
+{ZENCOD_R_CTRL_COMMAND_NOT_IMPLEMENTED   ,"ctrl command not implemented"},
+{ZENCOD_R_DSO_FAILURE                    ,"dso failure"},
+{ZENCOD_R_NOT_LOADED                     ,"not loaded"},
+{ZENCOD_R_REQUEST_FAILED                 ,"request failed"},
+{ZENCOD_R_UNIT_FAILURE                   ,"unit failure"},
+{0,NULL}
+	};
+
+#endif
+
+#ifdef ZENCOD_LIB_NAME
+static ERR_STRING_DATA ZENCOD_lib_name[]=
+        {
+{0	,ZENCOD_LIB_NAME},
+{0,NULL}
+	};
+#endif
+
+
+static int ZENCOD_lib_error_code=0;
+static int ZENCOD_error_init=1;
+
+static void ERR_load_ZENCOD_strings(void)
+	{
+	if (ZENCOD_lib_error_code == 0)
+		ZENCOD_lib_error_code=ERR_get_next_error_library();
+
+	if (ZENCOD_error_init)
+		{
+		ZENCOD_error_init=0;
+#ifndef OPENSSL_NO_ERR
+		ERR_load_strings(ZENCOD_lib_error_code,ZENCOD_str_functs);
+		ERR_load_strings(ZENCOD_lib_error_code,ZENCOD_str_reasons);
+#endif
+
+#ifdef ZENCOD_LIB_NAME
+		ZENCOD_lib_name->error = ERR_PACK(ZENCOD_lib_error_code,0,0);
+		ERR_load_strings(0,ZENCOD_lib_name);
+#endif
+		}
+	}
+
+static void ERR_unload_ZENCOD_strings(void)
+	{
+	if (ZENCOD_error_init == 0)
+		{
+#ifndef OPENSSL_NO_ERR
+		ERR_unload_strings(ZENCOD_lib_error_code,ZENCOD_str_functs);
+		ERR_unload_strings(ZENCOD_lib_error_code,ZENCOD_str_reasons);
+#endif
+
+#ifdef ZENCOD_LIB_NAME
+		ERR_unload_strings(0,ZENCOD_lib_name);
+#endif
+		ZENCOD_error_init=1;
+		}
+	}
+
+static void ERR_ZENCOD_error(int function, int reason, char *file, int line)
+	{
+	if (ZENCOD_lib_error_code == 0)
+		ZENCOD_lib_error_code=ERR_get_next_error_library();
+	ERR_PUT_error(ZENCOD_lib_error_code,function,reason,file,line);
+	}
diff --git a/openssl/demos/engines/zencod/hw_zencod_err.h b/openssl/demos/engines/zencod/hw_zencod_err.h
new file mode 100644
index 0000000..60e923f
--- /dev/null
+++ b/openssl/demos/engines/zencod/hw_zencod_err.h
@@ -0,0 +1,99 @@
+/* ====================================================================
+ * Copyright (c) 2001-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_ZENCOD_ERR_H
+#define HEADER_ZENCOD_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_ZENCOD_strings(void);
+static void ERR_unload_ZENCOD_strings(void);
+static void ERR_ZENCOD_error(int function, int reason, char *file, int line);
+#define ZENCODerr(f,r) ERR_ZENCOD_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the ZENCOD functions. */
+
+/* Function codes. */
+#define ZENCOD_F_ZENCOD_BN_MOD_EXP			 100
+#define ZENCOD_F_ZENCOD_CTRL				 101
+#define ZENCOD_F_ZENCOD_DH_COMPUTE			 102
+#define ZENCOD_F_ZENCOD_DH_GENERATE			 103
+#define ZENCOD_F_ZENCOD_DSA_DO_SIGN			 104
+#define ZENCOD_F_ZENCOD_DSA_DO_VERIFY			 105
+#define ZENCOD_F_ZENCOD_FINISH				 106
+#define ZENCOD_F_ZENCOD_INIT				 107
+#define ZENCOD_F_ZENCOD_RAND				 108
+#define ZENCOD_F_ZENCOD_RSA_MOD_EXP			 109
+#define ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT			 110
+
+/* Reason codes. */
+#define ZENCOD_R_ALREADY_LOADED				 100
+#define ZENCOD_R_BAD_KEY_COMPONENTS			 101
+#define ZENCOD_R_BN_EXPAND_FAIL				 102
+#define ZENCOD_R_CTRL_COMMAND_NOT_IMPLEMENTED		 103
+#define ZENCOD_R_DSO_FAILURE				 104
+#define ZENCOD_R_NOT_LOADED				 105
+#define ZENCOD_R_REQUEST_FAILED				 106
+#define ZENCOD_R_UNIT_FAILURE				 107
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/demos/maurice/Makefile b/openssl/demos/maurice/Makefile
new file mode 100644
index 0000000..f9bf622
--- /dev/null
+++ b/openssl/demos/maurice/Makefile
@@ -0,0 +1,59 @@
+CC=cc
+CFLAGS= -g -I../../include -Wall
+LIBS=  -L../.. -lcrypto
+EXAMPLES=example1 example2 example3 example4
+
+all: $(EXAMPLES) 
+
+example1: example1.o loadkeys.o 
+	$(CC) -o example1 example1.o loadkeys.o $(LIBS)
+
+example2: example2.o loadkeys.o
+	$(CC) -o example2 example2.o loadkeys.o $(LIBS)
+
+example3: example3.o 
+	$(CC) -o example3 example3.o $(LIBS)
+
+example4: example4.o
+	$(CC) -o example4 example4.o $(LIBS)
+
+clean:	
+	rm -f $(EXAMPLES) *.o
+
+test: all
+	@echo
+	@echo Example 1 Demonstrates the sealing and opening APIs
+	@echo Doing the encrypt side...
+	./example1 <README >t.t
+	@echo Doing the decrypt side...
+	./example1 -d <t.t >t.2
+	diff t.2 README
+	rm -f t.t t.2
+	@echo  example1 is OK
+
+	@echo
+	@echo Example2 Demonstrates rsa encryption and decryption
+	@echo   and it should just print \"This the clear text\"
+	./example2
+
+	@echo
+	@echo Example3 Demonstrates the use of symmetric block ciphers
+	@echo in this case it uses EVP_des_ede3_cbc
+	@echo i.e. triple DES in Cipher Block Chaining mode
+	@echo Doing the encrypt side...
+	./example3 ThisIsThePassword <README >t.t
+	@echo Doing the decrypt side...
+	./example3 -d ThisIsThePassword <t.t >t.2
+	diff t.2 README
+	rm -f t.t t.2
+	@echo  example3 is OK
+
+	@echo
+	@echo Example4 Demonstrates base64 encoding and decoding
+	@echo Doing the encrypt side...
+	./example4 <README >t.t
+	@echo Doing the decrypt side...
+	./example4 -d <t.t >t.2
+	diff t.2 README
+	rm -f t.t t.2
+	@echo example4 is OK
diff --git a/openssl/demos/maurice/README b/openssl/demos/maurice/README
new file mode 100644
index 0000000..29778d5
--- /dev/null
+++ b/openssl/demos/maurice/README
@@ -0,0 +1,34 @@
+From Maurice Gittens <mgittens@gits.nl>
+--
+	Example programs, demonstrating some basic SSLeay crypto library
+	operations, to help you not to make the same mistakes I did. 
+
+	The following files are present.
+	- loadkeys.c 	Demonstrates the loading and of public and 
+			private keys.
+	- loadkeys.h   	The interface for loadkeys.c
+	- example1.c    Demonstrates the sealing and opening API's
+	- example2.c  	Demonstrates rsa encryption and decryption
+	- example3.c    Demonstrates the use of symmetric block ciphers
+	- example4.c	Demonstrates base64 and decoding 		
+	- Makefile	A makefile you probably will have to adjust for
+			your environment
+	- README	this file
+
+
+	The programs were written by Maurice Gittens <mgittens@gits.nl>
+	with the necesary help from Eric Young <eay@cryptsoft.com> 
+	
+	You may do as you please with these programs, but please don't
+	pretend that you wrote them. 
+
+	To be complete: If you use these programs you acknowlegde that
+	you are aware that there is NO warranty of any kind associated
+	with these programs. I don't even claim that the programs work,
+	they are provided AS-IS.
+
+ 	January 1997
+
+	Maurice	
+
+
diff --git a/openssl/demos/maurice/cert.pem b/openssl/demos/maurice/cert.pem
new file mode 100644
index 0000000..e31a9ae
--- /dev/null
+++ b/openssl/demos/maurice/cert.pem
@@ -0,0 +1,77 @@
+issuer :/C=NL/SP=Brabant/L=Eindhoven/O=Gittens Information Systems B.V./OU=Certification Services/CN=ca.gits.nl/Email=mgittens@gits.nl
+subject:/C=NL/SP=Brabant/O=Gittens Information Systems B.V./OU=Certification Services/CN=caleb.gits.nl/Email=mgittens@gits.nl
+serial :01
+
+Certificate:
+    Data:
+        Version: 0 (0x0)
+        Serial Number: 1 (0x1)
+        Signature Algorithm: md5withRSAEncryption
+        Issuer: C=NL, SP=Brabant, L=Eindhoven, O=Gittens Information Systems B.V., OU=Certification Services, CN=ca.gits.nl/Email=mgittens@gits.nl
+        Validity
+            Not Before: Jan  5 13:21:16 1997 GMT
+            Not After : Jul 24 13:21:16 1997 GMT
+        Subject: C=NL, SP=Brabant, O=Gittens Information Systems B.V., OU=Certification Services, CN=caleb.gits.nl/Email=mgittens@gits.nl
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Modulus:
+                    00:dd:82:a0:fe:a9:8d:6a:02:7e:78:d6:33:75:9b:
+                    82:01:4b:12:80:ea:6b:9b:83:9e:e3:ae:dc:f3:d0:
+                    71:7c:4b:ea:03:57:b4:cc:ba:44:5b:b8:4b:49:d3:
+                    f6:39:cc:3d:12:1f:da:58:26:27:bc:bc:ab:a4:6d:
+                    62:d1:91:5a:47:9f:80:40:c1:b9:fa:e3:1e:ef:52:
+                    78:46:26:43:65:1d:f2:6b:bf:ff:c0:81:66:14:cd:
+                    81:32:91:f1:f8:51:7d:0e:17:1f:27:fc:c7:51:fd:
+                    1c:73:41:e5:66:43:3c:67:a3:09:b9:5e:36:50:50:
+                    b1:e8:42:bd:5c:c6:2b:ec:a9:2c:fe:6a:fe:40:26:
+                    64:9e:b9:bf:2d:1d:fb:d0:48:5b:82:2a:8e:ab:a4:
+                    d5:7b:5f:26:84:8a:9a:69:5e:c1:71:e2:a9:59:4c:
+                    2a:76:f7:fd:f4:cf:3f:d3:ce:30:72:62:65:1c:e9:
+                    e9:ee:d2:fc:44:00:1e:e0:80:57:e9:41:b3:f0:44:
+                    e5:0f:77:3b:1a:1f:57:5e:94:1d:c3:a5:fa:af:41:
+                    8c:4c:30:6b:2b:00:84:52:0c:64:0c:a8:5b:17:16:
+                    d1:1e:f8:ea:72:01:47:9a:b9:21:95:f9:71:ed:7c:
+                    d2:93:54:0c:c5:9c:e8:e5:40:28:c5:a0:ca:b1:a9:
+                    20:f9
+                Exponent: 65537 (0x10001)
+    Signature Algorithm: md5withRSAEncryption
+        93:08:f9:e0:d4:c5:ca:95:de:4e:38:3b:28:87:e9:d3:b6:ce:
+        4f:69:2e:c9:09:57:2f:fa:e2:50:9f:39:ec:f3:84:e8:3a:8f:
+        9b:c3:06:62:90:49:93:6d:23:7a:2b:3d:7b:f9:46:32:18:d3:
+        87:44:49:f7:29:2f:f3:58:97:70:c3:45:5b:90:52:1c:df:fb:
+        a8:a3:a1:29:53:a3:4c:ed:d2:51:d0:44:98:a4:14:6f:76:9d:
+        0d:03:76:e5:d3:13:21:ce:a3:4d:2a:77:fe:ad:b3:47:6d:42:
+        b9:4a:0e:ff:61:f4:ec:62:b2:3b:00:9c:ac:16:a2:ec:19:c8:
+        c7:3d:d7:7d:97:cd:4d:1a:d2:00:07:4e:40:3d:b9:ba:1e:e2:
+        fe:81:28:57:b9:ad:2b:74:59:b0:9f:8b:a5:98:d3:75:06:67:
+        4a:04:11:b2:ea:1a:8c:e0:d4:be:c8:0c:46:76:7f:5f:5a:7b:
+        72:09:dd:b6:d3:6b:97:70:e8:7e:17:74:1c:f7:3a:5f:e3:fa:
+        c2:f7:95:bd:74:5e:44:4b:9b:bd:27:de:02:7f:87:1f:68:68:
+        60:b9:f4:1d:2b:7b:ce:ef:b1:7f:3a:be:b9:66:60:54:6f:0c:
+        a0:dd:8c:03:a7:f1:9f:f8:0e:8d:bb:c6:ba:77:61:f7:8e:be:
+        28:ba:d8:4f
+
+-----BEGIN CERTIFICATE-----
+MIIDzzCCArcCAQEwDQYJKoZIhvcNAQEEBQAwgbUxCzAJBgNVBAYTAk5MMRAwDgYD
+VQQIEwdCcmFiYW50MRIwEAYDVQQHEwlFaW5kaG92ZW4xKTAnBgNVBAoTIEdpdHRl
+bnMgSW5mb3JtYXRpb24gU3lzdGVtcyBCLlYuMR8wHQYDVQQLExZDZXJ0aWZpY2F0
+aW9uIFNlcnZpY2VzMRMwEQYDVQQDEwpjYS5naXRzLm5sMR8wHQYJKoZIhvcNAQkB
+FhBtZ2l0dGVuc0BnaXRzLm5sMB4XDTk3MDEwNTEzMjExNloXDTk3MDcyNDEzMjEx
+NlowgaQxCzAJBgNVBAYTAk5MMRAwDgYDVQQIEwdCcmFiYW50MSkwJwYDVQQKEyBH
+aXR0ZW5zIEluZm9ybWF0aW9uIFN5c3RlbXMgQi5WLjEfMB0GA1UECxMWQ2VydGlm
+aWNhdGlvbiBTZXJ2aWNlczEWMBQGA1UEAxMNY2FsZWIuZ2l0cy5ubDEfMB0GCSqG
+SIb3DQEJARYQbWdpdHRlbnNAZ2l0cy5ubDCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAN2CoP6pjWoCfnjWM3WbggFLEoDqa5uDnuOu3PPQcXxL6gNXtMy6
+RFu4S0nT9jnMPRIf2lgmJ7y8q6RtYtGRWkefgEDBufrjHu9SeEYmQ2Ud8mu//8CB
+ZhTNgTKR8fhRfQ4XHyf8x1H9HHNB5WZDPGejCbleNlBQsehCvVzGK+ypLP5q/kAm
+ZJ65vy0d+9BIW4Iqjquk1XtfJoSKmmlewXHiqVlMKnb3/fTPP9POMHJiZRzp6e7S
+/EQAHuCAV+lBs/BE5Q93OxofV16UHcOl+q9BjEwwaysAhFIMZAyoWxcW0R746nIB
+R5q5IZX5ce180pNUDMWc6OVAKMWgyrGpIPkCAwEAATANBgkqhkiG9w0BAQQFAAOC
+AQEAkwj54NTFypXeTjg7KIfp07bOT2kuyQlXL/riUJ857POE6DqPm8MGYpBJk20j
+eis9e/lGMhjTh0RJ9ykv81iXcMNFW5BSHN/7qKOhKVOjTO3SUdBEmKQUb3adDQN2
+5dMTIc6jTSp3/q2zR21CuUoO/2H07GKyOwCcrBai7BnIxz3XfZfNTRrSAAdOQD25
+uh7i/oEoV7mtK3RZsJ+LpZjTdQZnSgQRsuoajODUvsgMRnZ/X1p7cgndttNrl3Do
+fhd0HPc6X+P6wveVvXReREubvSfeAn+HH2hoYLn0HSt7zu+xfzq+uWZgVG8MoN2M
+A6fxn/gOjbvGundh946+KLrYTw==
+-----END CERTIFICATE-----
+
diff --git a/openssl/demos/maurice/example1.c b/openssl/demos/maurice/example1.c
new file mode 100644
index 0000000..1ef8299
--- /dev/null
+++ b/openssl/demos/maurice/example1.c
@@ -0,0 +1,198 @@
+/* NOCW */
+/*
+	Please read the README file for condition of use, before
+	using this software.
+	
+	Maurice Gittens  <mgittens@gits.nl>   January 1997
+*/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <netinet/in.h>
+#include <fcntl.h>
+#include <strings.h>
+#include <stdlib.h>
+
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+
+#include "loadkeys.h"
+
+#define PUBFILE   "cert.pem"
+#define PRIVFILE  "privkey.pem"
+
+#define STDIN     0
+#define STDOUT    1 
+
+void main_encrypt(void);
+void main_decrypt(void);
+
+static const char *usage = "Usage: example1 [-d]\n";
+
+int main(int argc, char *argv[])
+{
+
+        ERR_load_crypto_strings();
+
+	if ((argc == 1))	
+	{
+		main_encrypt();
+	}	
+	else if ((argc == 2) && !strcmp(argv[1],"-d"))
+	{
+		main_decrypt();
+	}
+	else
+	{
+		printf("%s",usage);
+		exit(1);
+	}
+
+	return 0;		
+}
+
+void main_encrypt(void)
+{
+	unsigned int ebuflen;
+        EVP_CIPHER_CTX ectx;
+        unsigned char iv[EVP_MAX_IV_LENGTH];
+	unsigned char *ekey[1]; 
+	int readlen;
+	int ekeylen, net_ekeylen; 
+	EVP_PKEY *pubKey[1];
+	char buf[512];
+	char ebuf[512];
+	
+ 	memset(iv, '\0', sizeof(iv));
+
+        pubKey[0] = ReadPublicKey(PUBFILE);
+
+	if(!pubKey[0])
+	{
+           fprintf(stderr,"Error: can't load public key");
+           exit(1);
+        }      
+
+        ekey[0] = malloc(EVP_PKEY_size(pubKey[0]));  
+        if (!ekey[0])
+	{
+	   EVP_PKEY_free(pubKey[0]); 
+	   perror("malloc");
+	   exit(1);
+	}
+
+	EVP_SealInit(&ectx,
+                   EVP_des_ede3_cbc(),
+		   ekey,
+		   &ekeylen,
+		   iv,
+		   pubKey,
+		   1); 
+
+	net_ekeylen = htonl(ekeylen);	
+	write(STDOUT, (char*)&net_ekeylen, sizeof(net_ekeylen));
+        write(STDOUT, ekey[0], ekeylen);
+        write(STDOUT, iv, sizeof(iv));
+
+	while(1)
+	{
+		readlen = read(STDIN, buf, sizeof(buf));
+
+		if (readlen <= 0)
+		{
+		   if (readlen < 0)
+			perror("read");
+
+		   break;
+		}
+
+		EVP_SealUpdate(&ectx, ebuf, &ebuflen, buf, readlen);
+
+		write(STDOUT, ebuf, ebuflen);
+	}
+
+        EVP_SealFinal(&ectx, ebuf, &ebuflen);
+        
+	write(STDOUT, ebuf, ebuflen);
+
+        EVP_PKEY_free(pubKey[0]);
+	free(ekey[0]);
+}
+
+void main_decrypt(void)
+{
+	char buf[520];
+	char ebuf[512];
+	unsigned int buflen;
+        EVP_CIPHER_CTX ectx;
+        unsigned char iv[EVP_MAX_IV_LENGTH];
+	unsigned char *encryptKey; 
+	unsigned int ekeylen; 
+	EVP_PKEY *privateKey;
+
+	memset(iv, '\0', sizeof(iv));
+
+	privateKey = ReadPrivateKey(PRIVFILE);
+	if (!privateKey)
+	{
+		fprintf(stderr, "Error: can't load private key");
+		exit(1);	
+	}
+
+     	read(STDIN, &ekeylen, sizeof(ekeylen));
+	ekeylen = ntohl(ekeylen);
+
+	if (ekeylen != EVP_PKEY_size(privateKey))
+	{
+        	EVP_PKEY_free(privateKey);
+		fprintf(stderr, "keylength mismatch");
+		exit(1);	
+	}
+
+	encryptKey = malloc(sizeof(char) * ekeylen);
+	if (!encryptKey)
+	{
+        	EVP_PKEY_free(privateKey);
+		perror("malloc");
+		exit(1);
+	}
+
+	read(STDIN, encryptKey, ekeylen);
+	read(STDIN, iv, sizeof(iv));
+	EVP_OpenInit(&ectx,
+		   EVP_des_ede3_cbc(), 
+		   encryptKey,
+		   ekeylen,
+		   iv,
+		   privateKey); 	
+
+	while(1)
+	{
+		int readlen = read(STDIN, ebuf, sizeof(ebuf));
+
+		if (readlen <= 0)
+		{
+			if (readlen < 0)
+				perror("read");
+
+			break;
+		}
+
+		EVP_OpenUpdate(&ectx, buf, &buflen, ebuf, readlen);
+		write(STDOUT, buf, buflen);
+	}
+
+        EVP_OpenFinal(&ectx, buf, &buflen);
+
+	write(STDOUT, buf, buflen);
+
+        EVP_PKEY_free(privateKey);
+	free(encryptKey);
+}
+
+
diff --git a/openssl/demos/maurice/example2.c b/openssl/demos/maurice/example2.c
new file mode 100644
index 0000000..57bce10
--- /dev/null
+++ b/openssl/demos/maurice/example2.c
@@ -0,0 +1,75 @@
+/* NOCW */
+/*
+        Please read the README file for condition of use, before
+        using this software.
+
+        Maurice Gittens  <mgittens@gits.nl>   January 1997
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+
+#include "loadkeys.h"
+
+#define PUBFILE   "cert.pem"
+#define PRIVFILE  "privkey.pem"
+#define STDIN     0
+#define STDOUT    1 
+
+int main()
+{
+        char *ct = "This the clear text";
+	char *buf;   
+	char *buf2;
+  	EVP_PKEY *pubKey;
+  	EVP_PKEY *privKey;
+	int len;
+
+        ERR_load_crypto_strings();
+
+        privKey = ReadPrivateKey(PRIVFILE);
+        if (!privKey) 
+	{  
+		ERR_print_errors_fp (stderr);    
+		exit (1);  
+	}
+
+        pubKey = ReadPublicKey(PUBFILE);  
+	if(!pubKey)
+	{
+	   EVP_PKEY_free(privKey);   
+           fprintf(stderr,"Error: can't load public key");
+	   exit(1);
+	}
+
+	/* No error checking */
+        buf = malloc(EVP_PKEY_size(pubKey));
+        buf2 = malloc(EVP_PKEY_size(pubKey));
+
+	len = RSA_public_encrypt(strlen(ct)+1, ct, buf, pubKey->pkey.rsa,RSA_PKCS1_PADDING);
+
+	if (len != EVP_PKEY_size(pubKey))
+	{
+	    fprintf(stderr,"Error: ciphertext should match length of key\n");
+	    exit(1);
+	}
+
+	RSA_private_decrypt(len, buf, buf2, privKey->pkey.rsa,RSA_PKCS1_PADDING);
+
+	printf("%s\n", buf2);
+
+	EVP_PKEY_free(privKey);
+	EVP_PKEY_free(pubKey);
+	free(buf);
+	free(buf2);
+        return 0;
+}
diff --git a/openssl/demos/maurice/example3.c b/openssl/demos/maurice/example3.c
new file mode 100644
index 0000000..03d8a20
--- /dev/null
+++ b/openssl/demos/maurice/example3.c
@@ -0,0 +1,87 @@
+/* NOCW */
+/*
+        Please read the README file for condition of use, before
+        using this software.
+
+        Maurice Gittens  <mgittens@gits.nl>   January 1997
+
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <openssl/evp.h>
+
+#define STDIN     	0
+#define STDOUT    	1
+#define BUFLEN	  	512 
+#define INIT_VECTOR 	"12345678"
+#define ENCRYPT		1
+#define DECRYPT         0
+#define ALG		EVP_des_ede3_cbc()
+
+static const char *usage = "Usage: example3 [-d] password\n";
+
+void do_cipher(char *,int);
+
+int main(int argc, char *argv[])
+{
+	if ((argc == 2))	
+	{
+		do_cipher(argv[1],ENCRYPT);
+	}	
+	else if ((argc == 3) && !strcmp(argv[1],"-d"))
+	{
+		do_cipher(argv[2],DECRYPT);
+	}
+	else
+	{
+		fprintf(stderr,"%s", usage);
+		exit(1);
+	}
+
+	return 0;		
+}
+
+void do_cipher(char *pw, int operation)
+{
+	char buf[BUFLEN];
+	char ebuf[BUFLEN + 8];
+	unsigned int ebuflen; /* rc; */
+        unsigned char iv[EVP_MAX_IV_LENGTH], key[EVP_MAX_KEY_LENGTH];
+	/* unsigned int ekeylen, net_ekeylen;  */
+	EVP_CIPHER_CTX ectx;
+        
+	memcpy(iv, INIT_VECTOR, sizeof(iv));
+
+	EVP_BytesToKey(ALG, EVP_md5(), "salu", pw, strlen(pw), 1, key, iv);
+
+	EVP_CIPHER_CTX_init(&ectx);
+	EVP_CipherInit_ex(&ectx, ALG, NULL, key, iv, operation);
+
+	while(1)
+	{
+		int readlen = read(STDIN, buf, sizeof(buf));
+	
+		if (readlen <= 0)
+		{
+			if (!readlen)
+			   break;
+			else
+			{
+				perror("read");
+				exit(1);
+			}
+		}
+
+		EVP_CipherUpdate(&ectx, ebuf, &ebuflen, buf, readlen);
+
+		write(STDOUT, ebuf, ebuflen);
+	}
+
+        EVP_CipherFinal_ex(&ectx, ebuf, &ebuflen); 
+	EVP_CIPHER_CTX_cleanup(&ectx);
+
+	write(STDOUT, ebuf, ebuflen); 
+}
diff --git a/openssl/demos/maurice/example4.c b/openssl/demos/maurice/example4.c
new file mode 100644
index 0000000..ce62984
--- /dev/null
+++ b/openssl/demos/maurice/example4.c
@@ -0,0 +1,123 @@
+/* NOCW */
+/*
+        Please read the README file for condition of use, before
+        using this software.
+
+        Maurice Gittens  <mgittens@gits.nl>   January 1997
+
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <openssl/evp.h>
+
+#define STDIN     	0
+#define STDOUT    	1
+#define BUFLEN	  	512 
+
+static const char *usage = "Usage: example4 [-d]\n";
+
+void do_encode(void);
+void do_decode(void);
+
+int main(int argc, char *argv[])
+{
+	if ((argc == 1))	
+	{
+		do_encode();
+	}	
+	else if ((argc == 2) && !strcmp(argv[1],"-d"))
+	{
+		do_decode();
+	}
+	else
+	{
+		fprintf(stderr,"%s", usage);
+		exit(1);
+	}
+
+	return 0;		
+}
+
+void do_encode()
+{
+	char buf[BUFLEN];
+	char ebuf[BUFLEN+24];
+	unsigned int ebuflen;
+	EVP_ENCODE_CTX ectx;
+        
+	EVP_EncodeInit(&ectx);
+
+	while(1)
+	{
+		int readlen = read(STDIN, buf, sizeof(buf));
+	
+		if (readlen <= 0)
+		{
+			if (!readlen)
+			   break;
+			else
+			{
+				perror("read");
+				exit(1);
+			}
+		}
+
+		EVP_EncodeUpdate(&ectx, ebuf, &ebuflen, buf, readlen);
+
+		write(STDOUT, ebuf, ebuflen);
+	}
+
+        EVP_EncodeFinal(&ectx, ebuf, &ebuflen); 
+
+	write(STDOUT, ebuf, ebuflen);
+}
+
+void do_decode()
+{
+ 	char buf[BUFLEN];
+ 	char ebuf[BUFLEN+24];
+	unsigned int ebuflen;
+	EVP_ENCODE_CTX ectx;
+        
+	EVP_DecodeInit(&ectx);
+
+	while(1)
+	{
+		int readlen = read(STDIN, buf, sizeof(buf));
+		int rc;	
+	
+		if (readlen <= 0)
+		{
+			if (!readlen)
+			   break;
+			else
+			{
+				perror("read");
+				exit(1);
+			}
+		}
+
+		rc = EVP_DecodeUpdate(&ectx, ebuf, &ebuflen, buf, readlen);
+		if (rc <= 0)
+		{
+			if (!rc)
+			{
+				write(STDOUT, ebuf, ebuflen);
+				break;
+			}
+
+			fprintf(stderr, "Error: decoding message\n");
+			return;
+		}
+
+		write(STDOUT, ebuf, ebuflen);
+	}
+
+        EVP_DecodeFinal(&ectx, ebuf, &ebuflen); 
+
+	write(STDOUT, ebuf, ebuflen); 
+}
+
diff --git a/openssl/demos/maurice/loadkeys.c b/openssl/demos/maurice/loadkeys.c
new file mode 100644
index 0000000..82fd22a
--- /dev/null
+++ b/openssl/demos/maurice/loadkeys.c
@@ -0,0 +1,72 @@
+/* NOCW */
+/*
+        Please read the README file for condition of use, before
+        using this software.
+
+        Maurice Gittens  <mgittens@gits.nl>   January 1997
+
+*/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <netinet/in.h>
+#include <fcntl.h>
+#include <strings.h>
+#include <stdlib.h>
+
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+
+EVP_PKEY * ReadPublicKey(const char *certfile)
+{
+  FILE *fp = fopen (certfile, "r");   
+  X509 *x509;
+  EVP_PKEY *pkey;
+
+  if (!fp) 
+     return NULL; 
+
+  x509 = PEM_read_X509(fp, NULL, 0, NULL);
+
+  if (x509 == NULL) 
+  {  
+     ERR_print_errors_fp (stderr);
+     return NULL;   
+  }
+
+  fclose (fp);
+  
+  pkey=X509_extract_key(x509);
+
+  X509_free(x509);
+
+  if (pkey == NULL) 
+     ERR_print_errors_fp (stderr);
+
+  return pkey; 
+}
+
+EVP_PKEY *ReadPrivateKey(const char *keyfile)
+{
+	FILE *fp = fopen(keyfile, "r");
+	EVP_PKEY *pkey;
+
+	if (!fp)
+		return NULL;
+
+	pkey = PEM_read_PrivateKey(fp, NULL, 0, NULL);
+
+	fclose (fp);
+
+  	if (pkey == NULL) 
+		ERR_print_errors_fp (stderr);   
+
+	return pkey;
+}
+
+
diff --git a/openssl/demos/maurice/loadkeys.h b/openssl/demos/maurice/loadkeys.h
new file mode 100644
index 0000000..d8fde86
--- /dev/null
+++ b/openssl/demos/maurice/loadkeys.h
@@ -0,0 +1,19 @@
+/* NOCW */
+/*
+        Please read the README file for condition of use, before
+        using this software.
+
+        Maurice Gittens  <mgittens@gits.nl>   January 1997
+
+*/
+
+#ifndef LOADKEYS_H_SEEN
+#define LOADKEYS_H_SEEN
+
+#include <openssl/evp.h>
+
+EVP_PKEY * ReadPublicKey(const char *certfile);
+EVP_PKEY *ReadPrivateKey(const char *keyfile);
+
+#endif
+
diff --git a/openssl/demos/maurice/privkey.pem b/openssl/demos/maurice/privkey.pem
new file mode 100644
index 0000000..fc3554e
--- /dev/null
+++ b/openssl/demos/maurice/privkey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA3YKg/qmNagJ+eNYzdZuCAUsSgOprm4Oe467c89BxfEvqA1e0
+zLpEW7hLSdP2Ocw9Eh/aWCYnvLyrpG1i0ZFaR5+AQMG5+uMe71J4RiZDZR3ya7//
+wIFmFM2BMpHx+FF9DhcfJ/zHUf0cc0HlZkM8Z6MJuV42UFCx6EK9XMYr7Kks/mr+
+QCZknrm/LR370EhbgiqOq6TVe18mhIqaaV7BceKpWUwqdvf99M8/084wcmJlHOnp
+7tL8RAAe4IBX6UGz8ETlD3c7Gh9XXpQdw6X6r0GMTDBrKwCEUgxkDKhbFxbRHvjq
+cgFHmrkhlflx7XzSk1QMxZzo5UAoxaDKsakg+QIDAQABAoIBAQC0hnh083PnuJ6g
+Flob+B+stCUhYWtPc6ZzgphaMD+9ABV4oescipWZdooNYiyikBwZgFIvUvFBtTXh
+rLBDgUVlZ81beUb7/EvC2aBh818rsotWW0Sw/ARY4d7wetcL/EWBzUA8E5vR6wlb
+uZGelR9OiyYqp2h2bj1/v5yaVnuHxBeBj5clTHtPMXc+/70iUNBDMZ0ruZTdSwll
+e0DH8pp/5USYewlrKtRIJT7elC8LFMqEz4OpNvfaR2OEY0FatYYmSvQPNwV8/Eor
+XlNzRi9qD0uXbVexaAgQZ3/KZuAzUbOgwJZZXEAOGkZ/J1n08jljPXdU0o7bHhNl
+7siHbuEBAoGBAP53IvvJkhnH8Akf6E6sXelZkPKHnwDwfywDAiIhXza9DB1DViRS
+bZUB5gzcxmLGalex5+LcwZmsqFO5NXZ8SQeE9p0YT8yJsX4J1w9JzSvsWJBS2vyW
+Kbt21oG6JAGrWSGMIfxKpuahtWLf4JpGjftti0qIVQ60GKEPc1/xE2PZAoGBAN7Y
+nRPaUaqcIwbnH9kovOKwZ/PWREy1ecr3YXj65VYTnwSJHD0+CJa/DX8eB/G4AoNA
+Y2LPbq0Xu3+7SaUsO45VkaZuJmNwheUQ4tmyd/YdnVZ0AHXx1tvpR7QeO0WjnlNK
+mR+x00fetrff2Ypahs0wtU0Xf3F8ORgVB8jnxBIhAoGAcwf0PpI+g30Im3dbEsWE
+poogpiJ81HXjZ0fs3PTtD9eh9FCOTlkcxHFZR5M980TyqbX4t2tH8WpFpaNh8a/5
+a3bF7PoiiLnuDKXyHC0mnKZ42rU53VkcgGwWSAqXYFHPNwUcD+rHTBbp4kqGQ/eF
+E5XPk9/RY5YyVAyiAUr/kvECgYBvW1Ua75SxqbZDI8mhbZ79tGMt0NtubZz/1KCL
+oOxrGAD1dkJ7Q/1svunSpMIZgvcWeV1wqfFHY72ZNZC2jiTwmkffH9nlBPyTm92Q
+JYOWo/PUmMEGLyRL3gWrtxOtV/as7nEYCndmyZ8KwTxmy5fi/z0J2f0gS5AIPbIX
+LeGnoQKBgQDapjz9K4HWR5AMxyga4eiLIrmADySP846uz3eZIvTJQZ+6TAamvnno
+KbnU21cGq5HBBtxqQvGswLPGW9rZAgykHHJmYBUp0xv4+I4qHfXyD7QNmvq+Vxjj
+V2tgIafEpaf2ZsfM7BZeZz8MzeGcDwyrHtIO1FQiYN5Qz9Hq68XmVA==
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/demos/pkcs12/README b/openssl/demos/pkcs12/README
new file mode 100644
index 0000000..c87434b
--- /dev/null
+++ b/openssl/demos/pkcs12/README
@@ -0,0 +1,3 @@
+PKCS#12 demo applications
+
+Written by Steve Henson.
diff --git a/openssl/demos/pkcs12/pkread.c b/openssl/demos/pkcs12/pkread.c
new file mode 100644
index 0000000..fa8f509
--- /dev/null
+++ b/openssl/demos/pkcs12/pkread.c
@@ -0,0 +1,61 @@
+/* pkread.c */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/pkcs12.h>
+
+/* Simple PKCS#12 file reader */
+
+int main(int argc, char **argv)
+{
+	FILE *fp;
+	EVP_PKEY *pkey;
+	X509 *cert;
+	STACK_OF(X509) *ca = NULL;
+	PKCS12 *p12;
+	int i;
+	if (argc != 4) {
+		fprintf(stderr, "Usage: pkread p12file password opfile\n");
+		exit (1);
+	}
+	OpenSSL_add_all_algorithms();
+	ERR_load_crypto_strings();
+	if (!(fp = fopen(argv[1], "rb"))) {
+		fprintf(stderr, "Error opening file %s\n", argv[1]);
+		exit(1);
+	}
+	p12 = d2i_PKCS12_fp(fp, NULL);
+	fclose (fp);
+	if (!p12) {
+		fprintf(stderr, "Error reading PKCS#12 file\n");
+		ERR_print_errors_fp(stderr);
+		exit (1);
+	}
+	if (!PKCS12_parse(p12, argv[2], &pkey, &cert, &ca)) {
+		fprintf(stderr, "Error parsing PKCS#12 file\n");
+		ERR_print_errors_fp(stderr);
+		exit (1);
+	}
+	PKCS12_free(p12);
+	if (!(fp = fopen(argv[3], "w"))) {
+		fprintf(stderr, "Error opening file %s\n", argv[1]);
+		exit(1);
+	}
+	if (pkey) {
+		fprintf(fp, "***Private Key***\n");
+		PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL);
+	}
+	if (cert) {
+		fprintf(fp, "***User Certificate***\n");
+		PEM_write_X509_AUX(fp, cert);
+	}
+	if (ca && sk_X509_num(ca)) {
+		fprintf(fp, "***Other Certificates***\n");
+		for (i = 0; i < sk_X509_num(ca); i++) 
+		    PEM_write_X509_AUX(fp, sk_X509_value(ca, i));
+	}
+	fclose(fp);
+	return 0;
+}
diff --git a/openssl/demos/pkcs12/pkwrite.c b/openssl/demos/pkcs12/pkwrite.c
new file mode 100644
index 0000000..15f839d
--- /dev/null
+++ b/openssl/demos/pkcs12/pkwrite.c
@@ -0,0 +1,46 @@
+/* pkwrite.c */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/pkcs12.h>
+
+/* Simple PKCS#12 file creator */
+
+int main(int argc, char **argv)
+{
+	FILE *fp;
+	EVP_PKEY *pkey;
+	X509 *cert;
+	PKCS12 *p12;
+	if (argc != 5) {
+		fprintf(stderr, "Usage: pkwrite infile password name p12file\n");
+		exit(1);
+	}
+	SSLeay_add_all_algorithms();
+	ERR_load_crypto_strings();
+	if (!(fp = fopen(argv[1], "r"))) {
+		fprintf(stderr, "Error opening file %s\n", argv[1]);
+		exit(1);
+	}
+	cert = PEM_read_X509(fp, NULL, NULL, NULL);
+	rewind(fp);
+	pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
+	fclose(fp);
+	p12 = PKCS12_create(argv[2], argv[3], pkey, cert, NULL, 0,0,0,0,0);
+	if(!p12) {
+		fprintf(stderr, "Error creating PKCS#12 structure\n");
+		ERR_print_errors_fp(stderr);
+		exit(1);
+	}
+	if (!(fp = fopen(argv[4], "wb"))) {
+		fprintf(stderr, "Error opening file %s\n", argv[1]);
+		ERR_print_errors_fp(stderr);
+		exit(1);
+	}
+	i2d_PKCS12_fp(fp, p12);
+	PKCS12_free(p12);
+	fclose(fp);
+	return 0;
+}
diff --git a/openssl/demos/prime/Makefile b/openssl/demos/prime/Makefile
new file mode 100644
index 0000000..0166cd4
--- /dev/null
+++ b/openssl/demos/prime/Makefile
@@ -0,0 +1,20 @@
+CC=cc
+CFLAGS= -g -I../../include -Wall
+LIBS=  -L../.. -lcrypto
+EXAMPLES=prime
+
+all: $(EXAMPLES) 
+
+prime: prime.o
+	$(CC) -o prime prime.o $(LIBS)
+
+clean:	
+	rm -f $(EXAMPLES) *.o
+
+test: all
+	@echo Test creating a 128-bit prime
+	./prime 128
+	@echo Test creating a 256-bit prime
+	./prime 256
+	@echo Test creating a 512-bit prime
+	./prime 512
diff --git a/openssl/demos/prime/prime.c b/openssl/demos/prime/prime.c
new file mode 100644
index 0000000..103e0ef
--- /dev/null
+++ b/openssl/demos/prime/prime.c
@@ -0,0 +1,101 @@
+/* demos/prime/prime.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/bn.h>    
+
+void callback(type,num)
+int type,num;
+	{
+	if (type == 0)
+		fprintf(stderr,".");
+	else if (type == 1)
+		fprintf(stderr,"+");
+	else if (type == 2)
+		fprintf(stderr,"*");
+	fflush(stderr);
+	}
+
+int main(argc,argv)
+int argc;
+char *argv[];
+	{
+	BIGNUM *rand;
+	int num=256;
+
+	/* we should really call RAND_seed(char *bytes,int num);
+	 * to fully initalise the random number generator */
+	if (argc >= 2)
+		{
+		num=atoi(argv[1]);
+		if (num == 0) num=256;
+		}
+
+	fprintf(stderr,"generate a strong prime\n");
+        rand=BN_generate_prime(NULL,num,1,NULL,NULL,callback,NULL);
+	/* change the third parameter to 1 for a strong prime */
+	fprintf(stderr,"\n");
+
+	BN_print_fp(stdout,rand);           
+	fprintf(stdout,"\n");
+	BN_free(rand); 
+	exit(0);
+	return(0);
+	}
+
diff --git a/openssl/demos/privkey.pem b/openssl/demos/privkey.pem
new file mode 100644
index 0000000..ddae240
--- /dev/null
+++ b/openssl/demos/privkey.pem
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBPAIBAAJBAN+FmbxmHVOp/RxtpMGz0DvQEBz1sDktHp19hIoMSu0YZift5MAu
+4xAEJYvWVCshDiyOTWsUBXwZkrkt87FyctkCAwEAAQJAG/vxBGpQb6IPo1iC0RF/
+F430BnwoBPCGLbeCOXpSgx5X+19vuTSdEqMgeNB6+aNb+XY/7mvVfCjyD6WZ0oxs
+JQIhAPO+uL9cP40lFs62pdL3QSWsh3VNDByvOtr9LpeaxBm/AiEA6sKVfXsDQ5hd
+SHt9U61r2r8Lcxmzi9Kw6JNqjMmzqWcCIQCKoRy+aZ8Tjdas9yDVHh+FZ90bEBkl
+b1xQFNOdEj8aTQIhAOJWrO6INYNsWTPS6+hLYZtLamyUsQj0H+B8kNQge/mtAiEA
+nBfvUl243qbqN8gF7Az1u33uc9FsPVvQPiBzLxZ4ixw=
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/demos/selfsign.c b/openssl/demos/selfsign.c
new file mode 100644
index 0000000..68904c6
--- /dev/null
+++ b/openssl/demos/selfsign.c
@@ -0,0 +1,180 @@
+/* NOCW */
+/* cc -o ssdemo -I../include selfsign.c ../libcrypto.a */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <openssl/pem.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+int mkit(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days);
+
+int main()
+	{
+	BIO *bio_err;
+	X509 *x509=NULL;
+	EVP_PKEY *pkey=NULL;
+
+	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+	bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
+
+	mkit(&x509,&pkey,512,0,365);
+
+	RSA_print_fp(stdout,pkey->pkey.rsa,0);
+	X509_print_fp(stdout,x509);
+
+	PEM_write_PrivateKey(stdout,pkey,NULL,NULL,0,NULL, NULL);
+	PEM_write_X509(stdout,x509);
+
+	X509_free(x509);
+	EVP_PKEY_free(pkey);
+
+#ifdef CUSTOM_EXT
+	/* Only needed if we add objects or custom extensions */
+	X509V3_EXT_cleanup();
+	OBJ_cleanup();
+#endif
+
+	CRYPTO_mem_leaks(bio_err);
+	BIO_free(bio_err);
+	return(0);
+	}
+
+#ifdef WIN16
+#  define MS_CALLBACK   _far _loadds
+#  define MS_FAR        _far
+#else
+#  define MS_CALLBACK
+#  define MS_FAR
+#endif
+
+static void MS_CALLBACK callback(p, n, arg)
+int p;
+int n;
+void *arg;
+	{
+	char c='B';
+
+	if (p == 0) c='.';
+	if (p == 1) c='+';
+	if (p == 2) c='*';
+	if (p == 3) c='\n';
+	fputc(c,stderr);
+	}
+
+int mkit(x509p,pkeyp,bits,serial,days)
+X509 **x509p;
+EVP_PKEY **pkeyp;
+int bits;
+int serial;
+int days;
+	{
+	X509 *x;
+	EVP_PKEY *pk;
+	RSA *rsa;
+	X509_NAME *name=NULL;
+	X509_NAME_ENTRY *ne=NULL;
+	X509_EXTENSION *ex=NULL;
+
+	
+	if ((pkeyp == NULL) || (*pkeyp == NULL))
+		{
+		if ((pk=EVP_PKEY_new()) == NULL)
+			{
+			abort(); 
+			return(0);
+			}
+		}
+	else
+		pk= *pkeyp;
+
+	if ((x509p == NULL) || (*x509p == NULL))
+		{
+		if ((x=X509_new()) == NULL)
+			goto err;
+		}
+	else
+		x= *x509p;
+
+	rsa=RSA_generate_key(bits,RSA_F4,callback,NULL);
+	if (!EVP_PKEY_assign_RSA(pk,rsa))
+		{
+		abort();
+		goto err;
+		}
+	rsa=NULL;
+
+	X509_set_version(x,3);
+	ASN1_INTEGER_set(X509_get_serialNumber(x),serial);
+	X509_gmtime_adj(X509_get_notBefore(x),0);
+	X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);
+	X509_set_pubkey(x,pk);
+
+	name=X509_get_subject_name(x);
+
+	/* This function creates and adds the entry, working out the
+	 * correct string type and performing checks on its length.
+	 * Normally we'd check the return value for errors...
+	 */
+	X509_NAME_add_entry_by_txt(name,"C",
+				MBSTRING_ASC, "UK", -1, -1, 0);
+	X509_NAME_add_entry_by_txt(name,"CN",
+				MBSTRING_ASC, "OpenSSL Group", -1, -1, 0);
+
+	X509_set_issuer_name(x,name);
+
+	/* Add extension using V3 code: we can set the config file as NULL
+	 * because we wont reference any other sections. We can also set
+         * the context to NULL because none of these extensions below will need
+	 * to access it.
+	 */
+
+	ex = X509V3_EXT_conf_nid(NULL, NULL, NID_netscape_cert_type, "server");
+	X509_add_ext(x,ex,-1);
+	X509_EXTENSION_free(ex);
+
+	ex = X509V3_EXT_conf_nid(NULL, NULL, NID_netscape_comment,
+						"example comment extension");
+	X509_add_ext(x,ex,-1);
+	X509_EXTENSION_free(ex);
+
+	ex = X509V3_EXT_conf_nid(NULL, NULL, NID_netscape_ssl_server_name,
+							"www.openssl.org");
+
+	X509_add_ext(x,ex,-1);
+	X509_EXTENSION_free(ex);
+
+#if 0
+	/* might want something like this too.... */
+	ex = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints,
+							"critical,CA:TRUE");
+
+
+	X509_add_ext(x,ex,-1);
+	X509_EXTENSION_free(ex);
+#endif
+
+#ifdef CUSTOM_EXT
+	/* Maybe even add our own extension based on existing */
+	{
+		int nid;
+		nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
+		X509V3_EXT_add_alias(nid, NID_netscape_comment);
+		ex = X509V3_EXT_conf_nid(NULL, NULL, nid,
+						"example comment alias");
+		X509_add_ext(x,ex,-1);
+		X509_EXTENSION_free(ex);
+	}
+#endif
+	
+	if (!X509_sign(x,pk,EVP_md5()))
+		goto err;
+
+	*x509p=x;
+	*pkeyp=pk;
+	return(1);
+err:
+	return(0);
+	}
diff --git a/openssl/demos/sign/Makefile b/openssl/demos/sign/Makefile
new file mode 100644
index 0000000..e6d391e
--- /dev/null
+++ b/openssl/demos/sign/Makefile
@@ -0,0 +1,15 @@
+CC=cc
+CFLAGS= -g -I../../include -Wall
+LIBS=  -L../.. -lcrypto
+EXAMPLES=sign
+
+all: $(EXAMPLES) 
+
+sign: sign.o
+	$(CC) -o sign sign.o $(LIBS)
+
+clean:	
+	rm -f $(EXAMPLES) *.o
+
+test: all
+	./sign
diff --git a/openssl/demos/sign/cert.pem b/openssl/demos/sign/cert.pem
new file mode 100644
index 0000000..9d7ac23
--- /dev/null
+++ b/openssl/demos/sign/cert.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICLDCCAdYCAQAwDQYJKoZIhvcNAQEEBQAwgaAxCzAJBgNVBAYTAlBUMRMwEQYD
+VQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5ldXJv
+bmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMTEmJy
+dXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZpMB4X
+DTk2MDkwNTAzNDI0M1oXDTk2MTAwNTAzNDI0M1owgaAxCzAJBgNVBAYTAlBUMRMw
+EQYDVQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5l
+dXJvbmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMT
+EmJydXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZp
+MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNw
+L4lYKbpzzlmC5beaQXeQ2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAATAN
+BgkqhkiG9w0BAQQFAANBAFqPEKFjk6T6CKTHvaQeEAsX0/8YHPHqH/9AnhSjrwuX
+9EBc0n6bVGhN7XaXd6sJ7dym9sbsWxb+pJdurnkxjx4=
+-----END CERTIFICATE-----
diff --git a/openssl/demos/sign/key.pem b/openssl/demos/sign/key.pem
new file mode 100644
index 0000000..239ad66
--- /dev/null
+++ b/openssl/demos/sign/key.pem
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBPAIBAAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNwL4lYKbpzzlmC5beaQXeQ
+2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAAQJBALjkK+jc2+iihI98riEF
+oudmkNziSRTYjnwjx8mCoAjPWviB3c742eO3FG4/soi1jD9A5alihEOXfUzloenr
+8IECIQD3B5+0l+68BA/6d76iUNqAAV8djGTzvxnCxycnxPQydQIhAMXt4trUI3nc
+a+U8YL2HPFA3gmhBsSICbq2OptOCnM7hAiEA6Xi3JIQECob8YwkRj29DU3/4WYD7
+WLPgsQpwo1GuSpECICGsnWH5oaeD9t9jbFoSfhJvv0IZmxdcLpRcpslpeWBBAiEA
+6/5B8J0GHdJq89FHwEG/H2eVVUYu5y/aD6sgcm+0Avg=
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/demos/sign/sig.txt b/openssl/demos/sign/sig.txt
new file mode 100644
index 0000000..5613c0e
--- /dev/null
+++ b/openssl/demos/sign/sig.txt
@@ -0,0 +1,158 @@
+From ssl-lists-owner@mincom.com Mon Sep 30 02:37:40 1996
+Received: from cygnus.mincom.oz.au by orb.mincom.oz.au with SMTP id AA11782
+  (5.65c/IDA-1.4.4 for eay); Mon, 30 Sep 1996 11:46:21 +1000
+Received: (from daemon@localhost) by cygnus.mincom.oz.au (8.7.5/8.7.3) id LAA18980 for ssl-users-outgoing; Mon, 30 Sep 1996 11:44:56 +1000 (EST)
+Received: from minbne.mincom.oz.au (minbne.mincom.oz.au [192.55.196.247]) by cygnus.mincom.oz.au (8.7.5/8.7.3) with SMTP id LAA18962 for <ssl-users@listserv.mincom.oz.au>; Mon, 30 Sep 1996 11:44:51 +1000 (EST)
+Received: by minbne.mincom.oz.au id AA22230
+  (5.65c/IDA-1.4.4 for ssl-users@listserv.mincom.oz.au); Mon, 30 Sep 1996 11:38:41 +1000
+Received: from brutus.neuronio.pt (brutus.neuronio.pt [193.126.253.2]) by bunyip.cc.uq.oz.au (8.7.6/8.7.3) with SMTP id LAA15824 for <ssl-users@mincom.com>; Mon, 30 Sep 1996 11:40:07 +1000
+Received: (from sampo@localhost) by brutus.neuronio.pt (8.6.11/8.6.11) id BAA08729; Mon, 30 Sep 1996 01:37:40 +0100
+Date: Mon, 30 Sep 1996 01:37:40 +0100
+Message-Id: <199609300037.BAA08729@brutus.neuronio.pt>
+From: Sampo Kellomaki <sampo@neuronio.pt>
+To: ssl-users@mincom.com
+Cc: sampo@brutus.neuronio.pt
+Subject: Signing with envelope routines
+Sender: ssl-lists-owner@mincom.com
+Precedence: bulk
+Status: RO
+X-Status: D
+
+
+I have been trying to figure out how to produce signatures with EVP_
+routines. I seem to be able to read in private key and sign some
+data ok, but I can't figure out how I am supposed to read in
+public key so that I could verify my signature. I use self signed
+certificate.
+
+I figured I should use
+	EVP_PKEY* pkey = PEM_ASN1_read(d2i_PrivateKey, PEM_STRING_EVP_PKEY,
+	                               fp, NULL, NULL);
+to read in private key and this seems to work Ok.
+
+However when I try analogous
+	EVP_PKEY* pkey = PEM_ASN1_read(d2i_PublicKey, PEM_STRING_X509,
+	                               fp, NULL, NULL);
+the program fails with
+
+error:0D09508D:asn1 encoding routines:D2I_PUBLICKEY:unknown public key type:d2i_pu.c:93
+error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib:pem_lib.c:232
+
+I figured that the second argument to PEM_ASN1_read should match the
+name in my PEM encoded object, hence PEM_STRING_X509.
+PEM_STRING_EVP_PKEY seems to be somehow magical
+because it matches whatever private key there happens to be. I could
+not find a similar constant to use with getting the certificate, however.
+
+Is my approach of using PEM_ASN1_read correct? What should I pass in
+as name?  Can I use normal (or even self signed) X509 certificate for
+verifying the signature?
+
+When will SSLeay documentation be written ;-)? If I would contribute
+comments to the code, would Eric take time to review them and include
+them in distribution?
+
+I'm using SSLeay-0.6.4. My program is included below along with the
+key and cert that I use.
+
+--Sampo
+
+-----------------------------------
+/* sign-it.cpp  -  Simple test app using SSLeay envelopes to sign data
+   29.9.1996, Sampo Kellomaki <sampo@iki.fi> */
+
+#include <stdio.h>
+#include "rsa.h"
+#include "evp.h"
+#include "objects.h"
+#include "x509.h"
+#include "err.h"
+#include "pem.h"
+#include "ssl.h"
+
+void main ()
+{
+  int err;
+  int sig_len;
+  unsigned char sig_buf [4096];
+  const char certfile[] = "plain-cert.pem";
+  const char keyfile[]  = "plain-key.pem";
+  const char data[]     = "I owe you...";
+  EVP_MD_CTX     md_ctx;
+  EVP_PKEY*      pkey;
+  FILE*          fp;
+
+  SSL_load_error_strings();
+  
+  /* Read private key */
+  
+  fp = fopen (keyfile, "r");   if (fp == NULL) exit (1);
+  pkey = (EVP_PKEY*)PEM_ASN1_read ((char *(*)())d2i_PrivateKey,
+				   PEM_STRING_EVP_PKEY,
+				   fp,
+				   NULL, NULL);
+  if (pkey == NULL) {  ERR_print_errors_fp (stderr);    exit (1);  }
+  fclose (fp);
+  
+  /* Do the signature */
+  
+  EVP_SignInit   (&md_ctx, EVP_md5());
+  EVP_SignUpdate (&md_ctx, data, strlen(data));
+  sig_len = sizeof(sig_buf);
+  err = EVP_SignFinal (&md_ctx,
+		       sig_buf, 
+		       &sig_len,
+		       pkey);
+  if (err != 1) {  ERR_print_errors_fp (stderr);    exit (1);  }
+  EVP_PKEY_free (pkey);
+  
+  /* Read public key */
+  
+  fp = fopen (certfile, "r");   if (fp == NULL) exit (1);
+  pkey = (EVP_PKEY*)PEM_ASN1_read ((char *(*)())d2i_PublicKey,
+				   PEM_STRING_X509,
+				   fp,
+				   NULL, NULL);
+  if (pkey == NULL) {  ERR_print_errors_fp (stderr);    exit (1);  }
+  fclose (fp);
+  
+  /* Verify the signature */
+  
+  EVP_VerifyInit   (&md_ctx, EVP_md5());
+  EVP_VerifyUpdate (&md_ctx, data, strlen((char*)data));
+  err = EVP_VerifyFinal (&md_ctx,
+			 sig_buf,
+			 sig_len,
+			 pkey);
+  if (err != 1) {  ERR_print_errors_fp (stderr);    exit (1);  }
+  EVP_PKEY_free (pkey);
+  printf ("Signature Verified Ok.\n");
+}
+/* EOF */
+--------------- plain-cert.pem -----------------
+-----BEGIN CERTIFICATE-----
+MIICLDCCAdYCAQAwDQYJKoZIhvcNAQEEBQAwgaAxCzAJBgNVBAYTAlBUMRMwEQYD
+VQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5ldXJv
+bmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMTEmJy
+dXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZpMB4X
+DTk2MDkwNTAzNDI0M1oXDTk2MTAwNTAzNDI0M1owgaAxCzAJBgNVBAYTAlBUMRMw
+EQYDVQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5l
+dXJvbmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMT
+EmJydXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZp
+MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNw
+L4lYKbpzzlmC5beaQXeQ2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAATAN
+BgkqhkiG9w0BAQQFAANBAFqPEKFjk6T6CKTHvaQeEAsX0/8YHPHqH/9AnhSjrwuX
+9EBc0n6bVGhN7XaXd6sJ7dym9sbsWxb+pJdurnkxjx4=
+-----END CERTIFICATE-----
+---------------- plain-key.pem -----------------
+-----BEGIN RSA PRIVATE KEY-----
+MIIBPAIBAAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNwL4lYKbpzzlmC5beaQXeQ
+2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAAQJBALjkK+jc2+iihI98riEF
+oudmkNziSRTYjnwjx8mCoAjPWviB3c742eO3FG4/soi1jD9A5alihEOXfUzloenr
+8IECIQD3B5+0l+68BA/6d76iUNqAAV8djGTzvxnCxycnxPQydQIhAMXt4trUI3nc
+a+U8YL2HPFA3gmhBsSICbq2OptOCnM7hAiEA6Xi3JIQECob8YwkRj29DU3/4WYD7
+WLPgsQpwo1GuSpECICGsnWH5oaeD9t9jbFoSfhJvv0IZmxdcLpRcpslpeWBBAiEA
+6/5B8J0GHdJq89FHwEG/H2eVVUYu5y/aD6sgcm+0Avg=
+-----END RSA PRIVATE KEY-----
+------------------------------------------------
+
diff --git a/openssl/demos/sign/sign.c b/openssl/demos/sign/sign.c
new file mode 100644
index 0000000..a6c66e1
--- /dev/null
+++ b/openssl/demos/sign/sign.c
@@ -0,0 +1,153 @@
+/* demos/sign/sign.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* sign-it.cpp  -  Simple test app using SSLeay envelopes to sign data
+   29.9.1996, Sampo Kellomaki <sampo@iki.fi> */
+
+/* converted to C - eay :-) */
+
+/* reformated a bit and converted to use the more common functions: this was
+ * initially written at the dawn of time :-) - Steve.
+ */
+
+#include <stdio.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+
+int main ()
+{
+  int err;
+  int sig_len;
+  unsigned char sig_buf [4096];
+  static char certfile[] = "cert.pem";
+  static char keyfile[]  = "key.pem";
+  static char data[]     = "I owe you...";
+  EVP_MD_CTX     md_ctx;
+  EVP_PKEY *      pkey;
+  FILE *          fp;
+  X509 *	x509;
+
+  /* Just load the crypto library error strings,
+   * SSL_load_error_strings() loads the crypto AND the SSL ones */
+  /* SSL_load_error_strings();*/
+  ERR_load_crypto_strings();
+  
+  /* Read private key */
+  
+  fp = fopen (keyfile, "r");
+  if (fp == NULL) exit (1);
+  pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
+  fclose (fp);
+
+  if (pkey == NULL) { 
+	ERR_print_errors_fp (stderr);
+	exit (1);
+  }
+  
+  /* Do the signature */
+  
+  EVP_SignInit   (&md_ctx, EVP_sha1());
+  EVP_SignUpdate (&md_ctx, data, strlen(data));
+  sig_len = sizeof(sig_buf);
+  err = EVP_SignFinal (&md_ctx, sig_buf, &sig_len, pkey);
+
+  if (err != 1) {
+	ERR_print_errors_fp(stderr);
+	exit (1);
+  }
+
+  EVP_PKEY_free (pkey);
+  
+  /* Read public key */
+  
+  fp = fopen (certfile, "r");
+  if (fp == NULL) exit (1);
+  x509 = PEM_read_X509(fp, NULL, NULL, NULL);
+  fclose (fp);
+
+  if (x509 == NULL) {
+	ERR_print_errors_fp (stderr);
+	exit (1);
+  }
+  
+  /* Get public key - eay */
+  pkey=X509_get_pubkey(x509);
+  if (pkey == NULL) {
+	ERR_print_errors_fp (stderr);
+	exit (1);
+  }
+
+  /* Verify the signature */
+  
+  EVP_VerifyInit   (&md_ctx, EVP_sha1());
+  EVP_VerifyUpdate (&md_ctx, data, strlen((char*)data));
+  err = EVP_VerifyFinal (&md_ctx, sig_buf, sig_len, pkey);
+  EVP_PKEY_free (pkey);
+
+  if (err != 1) {
+	ERR_print_errors_fp (stderr);
+	exit (1);
+  }
+  printf ("Signature Verified Ok.\n");
+  return(0);
+}
diff --git a/openssl/demos/sign/sign.txt b/openssl/demos/sign/sign.txt
new file mode 100644
index 0000000..2aa2b46
--- /dev/null
+++ b/openssl/demos/sign/sign.txt
@@ -0,0 +1,170 @@
+From ssl-lists-owner@mincom.com Mon Sep 30 22:43:15 1996
+Received: from cygnus.mincom.oz.au by orb.mincom.oz.au with SMTP id AA12802
+  (5.65c/IDA-1.4.4 for eay); Mon, 30 Sep 1996 12:45:43 +1000
+Received: (from daemon@localhost) by cygnus.mincom.oz.au (8.7.5/8.7.3) id MAA25922 for ssl-users-outgoing; Mon, 30 Sep 1996 12:43:43 +1000 (EST)
+Received: from orb.mincom.oz.au (eay@orb.mincom.oz.au [192.55.197.1]) by cygnus.mincom.oz.au (8.7.5/8.7.3) with SMTP id MAA25900 for <ssl-users@listserv.mincom.oz.au>; Mon, 30 Sep 1996 12:43:39 +1000 (EST)
+Received: by orb.mincom.oz.au id AA12688
+  (5.65c/IDA-1.4.4 for ssl-users@listserv.mincom.oz.au); Mon, 30 Sep 1996 12:43:16 +1000
+Date: Mon, 30 Sep 1996 12:43:15 +1000 (EST)
+From: Eric Young <eay@mincom.com>
+X-Sender: eay@orb
+To: Sampo Kellomaki <sampo@neuronio.pt>
+Cc: ssl-users@mincom.com, sampo@brutus.neuronio.pt
+Subject: Re: Signing with envelope routines
+In-Reply-To: <199609300037.BAA08729@brutus.neuronio.pt>
+Message-Id: <Pine.SOL.3.91.960930121504.11800Y-100000@orb>
+Mime-Version: 1.0
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+Sender: ssl-lists-owner@mincom.com
+Precedence: bulk
+Status: O
+X-Status: 
+
+
+On Mon, 30 Sep 1996, Sampo Kellomaki wrote:
+> I have been trying to figure out how to produce signatures with EVP_
+> routines. I seem to be able to read in private key and sign some
+> data ok, but I can't figure out how I am supposed to read in
+> public key so that I could verify my signature. I use self signed
+> certificate.
+
+hmm... a rather poorly documented are of the library at this point in time.
+
+> I figured I should use
+> 	EVP_PKEY* pkey = PEM_ASN1_read(d2i_PrivateKey, PEM_STRING_EVP_PKEY,
+> 	                               fp, NULL, NULL);
+> to read in private key and this seems to work Ok.
+> 
+> However when I try analogous
+> 	EVP_PKEY* pkey = PEM_ASN1_read(d2i_PublicKey, PEM_STRING_X509,
+> 	                               fp, NULL, NULL);
+
+What you should do is 
+	X509 *x509=PEM_read_X509(fp,NULL,NULL);
+	/* which is the same as PEM_ASN1_read(d2i_X509,PEM_STRING_X509,fp,
+	 * NULL,NULL); */
+Then
+	EVP_PKEY *pkey=X509_extract_key(x509);
+
+There is also a X509_REQ_extract_key(req);
+which gets the public key from a certificate request.
+
+I re-worked quite a bit of this when I cleaned up the dependancy on
+RSA as the private key.
+
+> I figured that the second argument to PEM_ASN1_read should match the
+> name in my PEM encoded object, hence PEM_STRING_X509.
+> PEM_STRING_EVP_PKEY seems to be somehow magical
+> because it matches whatever private key there happens to be. I could
+> not find a similar constant to use with getting the certificate, however.
+
+:-), PEM_STRING_EVP_PKEY is 'magical' :-).  In theory I should be using a
+standard such as PKCS#8 to store the private key so that the type is 
+encoded in the asn.1 encoding of the object.
+
+> Is my approach of using PEM_ASN1_read correct? What should I pass in
+> as name?  Can I use normal (or even self signed) X509 certificate for
+> verifying the signature?
+
+The actual public key is kept in the certificate, so basically you have 
+to load the certificate and then 'unpack' the public key from the 
+certificate.
+
+> When will SSLeay documentation be written ;-)? If I would contribute
+> comments to the code, would Eric take time to review them and include
+> them in distribution?
+
+:-) After SSLv3 and PKCS#7 :-).  I actually started doing a function list 
+but what I really need to do is do quite a few 'this is how you do xyz' 
+type documents.  I suppose the current method is to post to ssl-users and 
+I'll respond :-).
+
+I'll add a 'demo' directory for the next release, I've appended a 
+modified version of your program that works, you were very close :-).
+
+eric
+
+/* sign-it.cpp  -  Simple test app using SSLeay envelopes to sign data
+   29.9.1996, Sampo Kellomaki <sampo@iki.fi> */
+
+/* converted to C - eay :-) */
+
+#include <stdio.h>
+#include "rsa.h"
+#include "evp.h"
+#include "objects.h"
+#include "x509.h"
+#include "err.h"
+#include "pem.h"
+#include "ssl.h"
+
+void main ()
+{
+  int err;
+  int sig_len;
+  unsigned char sig_buf [4096];
+  static char certfile[] = "plain-cert.pem";
+  static char keyfile[]  = "plain-key.pem";
+  static char data[]     = "I owe you...";
+  EVP_MD_CTX     md_ctx;
+  EVP_PKEY *      pkey;
+  FILE *          fp;
+  X509 *	x509;
+
+  /* Just load the crypto library error strings,
+   * SSL_load_error_strings() loads the crypto AND the SSL ones */
+  /* SSL_load_error_strings();*/
+  ERR_load_crypto_strings();
+  
+  /* Read private key */
+  
+  fp = fopen (keyfile, "r");   if (fp == NULL) exit (1);
+  pkey = (EVP_PKEY*)PEM_ASN1_read ((char *(*)())d2i_PrivateKey,
+				   PEM_STRING_EVP_PKEY,
+				   fp,
+				   NULL, NULL);
+  if (pkey == NULL) {  ERR_print_errors_fp (stderr);    exit (1);  }
+  fclose (fp);
+  
+  /* Do the signature */
+  
+  EVP_SignInit   (&md_ctx, EVP_md5());
+  EVP_SignUpdate (&md_ctx, data, strlen(data));
+  sig_len = sizeof(sig_buf);
+  err = EVP_SignFinal (&md_ctx,
+		       sig_buf, 
+		       &sig_len,
+		       pkey);
+  if (err != 1) {  ERR_print_errors_fp (stderr);    exit (1);  }
+  EVP_PKEY_free (pkey);
+  
+  /* Read public key */
+  
+  fp = fopen (certfile, "r");   if (fp == NULL) exit (1);
+  x509 = (X509 *)PEM_ASN1_read ((char *(*)())d2i_X509,
+				   PEM_STRING_X509,
+				   fp, NULL, NULL);
+  if (x509 == NULL) {  ERR_print_errors_fp (stderr);    exit (1);  }
+  fclose (fp);
+  
+  /* Get public key - eay */
+  pkey=X509_extract_key(x509);
+  if (pkey == NULL) {  ERR_print_errors_fp (stderr);    exit (1);  }
+
+  /* Verify the signature */
+  
+  EVP_VerifyInit   (&md_ctx, EVP_md5());
+  EVP_VerifyUpdate (&md_ctx, data, strlen((char*)data));
+  err = EVP_VerifyFinal (&md_ctx,
+			 sig_buf,
+			 sig_len,
+			 pkey);
+  if (err != 1) {  ERR_print_errors_fp (stderr);    exit (1);  }
+  EVP_PKEY_free (pkey);
+  printf ("Signature Verified Ok.\n");
+}
+
+
+
+
+
diff --git a/openssl/demos/smime/cacert.pem b/openssl/demos/smime/cacert.pem
new file mode 100644
index 0000000..75cbb34
--- /dev/null
+++ b/openssl/demos/smime/cacert.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC6DCCAlGgAwIBAgIJAMfGO3rdo2uUMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
+BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
+dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTc0MzE3
+WhcNMTcwNDEwMTc0MzE3WjBXMQswCQYDVQQGEwJVSzESMBAGA1UEBxMJVGVzdCBD
+aXR5MRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMRwwGgYDVQQDExNUZXN0IFMvTUlN
+RSBSb290IENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqJMal1uC1/1wz
+i5+dE4EZF2im3BgROm5PVMbwPY9V1t+KYvtdc3rMcRgJaMbP+qaEcDXoIsZfYXGR
+ielgfDNZmZcj1y/FOum+Jc2OZMs3ggPmjIQ3dbBECq0hZKcbz7wfr+2OeNWm46iT
+jcSIXpGIRhUYEzOgv7zb8oOU70IbbwIDAQABo4G7MIG4MB0GA1UdDgQWBBRHUypx
+CXFQYqewhGo72lWPQUsjoDCBiAYDVR0jBIGAMH6AFEdTKnEJcVBip7CEajvaVY9B
+SyOgoVukWTBXMQswCQYDVQQGEwJVSzESMBAGA1UEBxMJVGVzdCBDaXR5MRYwFAYD
+VQQKEw1PcGVuU1NMIEdyb3VwMRwwGgYDVQQDExNUZXN0IFMvTUlNRSBSb290IENB
+ggkAx8Y7et2ja5QwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQANI+Yc
+G/YDM1WMUGEzEkU9UhsIUqdyBebnK3+OyxZSouDcE/M10jFJzBf/F5b0uUGAKWwo
+u0dzmILfKjdfWe8EyCRafZcm00rVcO09i/63FBYzlHbmfUATIqZdhKzxxQMPs5mF
+1je+pHUpzIY8TSXyh/uD9IkAy04IHwGZQf9akw==
+-----END CERTIFICATE-----
diff --git a/openssl/demos/smime/cakey.pem b/openssl/demos/smime/cakey.pem
new file mode 100644
index 0000000..3b53c5e
--- /dev/null
+++ b/openssl/demos/smime/cakey.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQCqJMal1uC1/1wzi5+dE4EZF2im3BgROm5PVMbwPY9V1t+KYvtd
+c3rMcRgJaMbP+qaEcDXoIsZfYXGRielgfDNZmZcj1y/FOum+Jc2OZMs3ggPmjIQ3
+dbBECq0hZKcbz7wfr+2OeNWm46iTjcSIXpGIRhUYEzOgv7zb8oOU70IbbwIDAQAB
+AoGBAKWOZ2UTc1BkjDjz0XoscmAR8Rj77MdGzfOPkIxPultSW+3yZpkGNyUbnsH5
+HAtf4Avai/m3bMN+s91kDpx9/g/I9ZEHPQLcDICETvwt/EHT7+hwvaQgsM+TgpMs
+tjlGZOWent6wVIuvwwzqOMXZLgK9FvY7upwgtrys4G3Kab5hAkEA2QzFflWyEvKS
+rMSaVtn/IjFilwa7H0IdakkjM34z4peerFTPBr4J47YD4RCR/dAvxyNy3zUxtH18
+9R6dUixI6QJBAMitJD0xOkbGWBX8KVJvRiKOIdf/95ZUAgN/h3bWKy57EB9NYj3u
+jbxXcvdjfSqiITykkjAg7SG7nrlzJsu6CpcCQG6gVsy0auXDY0TRlASuaZ6I40Is
+uRUOgqWYj2uAaHuWYdZeB4LdO3cnX0TISFDAWom6JKNlnmbrCtR4fSDT13kCQQCU
++VQJyV3F5MDHsWbLt6eNR46AV5lpk/vatPXPlrZ/zwPs+PmRmGLICvNiDA2DdNDP
+wCx2Zjsj67CtY3rNitMJAkEAm09BQnjnbBXUb1rd2SjNDWTsu80Z+zLu8pAwXNhW
+8nsvMYqlYMIxuMPwu/QuTnMRhMZ08uhqoD3ukZnBeoMEVg==
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/demos/smime/encr.txt b/openssl/demos/smime/encr.txt
new file mode 100644
index 0000000..f163a32
--- /dev/null
+++ b/openssl/demos/smime/encr.txt
@@ -0,0 +1,3 @@
+Content-type: text/plain
+
+Sample OpenSSL Data for PKCS#7 encryption
diff --git a/openssl/demos/smime/sign.txt b/openssl/demos/smime/sign.txt
new file mode 100644
index 0000000..af1341d
--- /dev/null
+++ b/openssl/demos/smime/sign.txt
@@ -0,0 +1,3 @@
+Content-type: text/plain
+
+Test OpenSSL Signed Content
diff --git a/openssl/demos/smime/signer.pem b/openssl/demos/smime/signer.pem
new file mode 100644
index 0000000..bac16ba
--- /dev/null
+++ b/openssl/demos/smime/signer.pem
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIICpjCCAg+gAwIBAgIJAJ+rfmEoLQRhMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
+BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
+dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTgyOTI3
+WhcNMTcwNDA5MTgyOTI3WjBWMQswCQYDVQQGEwJVSzElMCMGA1UEAxMcT3BlblNT
+TCB0ZXN0IFMvTUlNRSBzaWduZXIgMTEgMB4GCSqGSIb3DQEJARYRdGVzdDFAb3Bl
+bnNzbC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL1ocAQ7ON2pIUXz
+jwKPzpPB9ozB6PFG6F6kARO+i0DiT6Qn8abUjwpHPU+lGys83QlpbkQVUD6Fv/4L
+ytihk6N9Pr/feECVcSZ20dI43WXjfYak14dSVrZkGNMMXqKmnnqtkAdD0oJN7A7y
+gcf8RuViV0kvk9/36eCMwMHrImfhAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI
+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
+BBSyKqjvctIsFNBHULBTqr8SHtSxpDAfBgNVHSMEGDAWgBRHUypxCXFQYqewhGo7
+2lWPQUsjoDANBgkqhkiG9w0BAQQFAAOBgQBvdYVoBfd4RV/xWSMXIcgw/i5OiwyX
+MsenQePll51MpglfArd7pUipUalCqlJt/Gs8kD16Ih1z1yuWYVTMlnDZ0PwbIOYn
++Jr8XLF9b1SMJt6PwckZZ0LZdIi2KwGAxVsIW1kjJAqu9o4YH37XW37yYdQRxfvv
+lDiQlgX0JtmLgA==
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQC9aHAEOzjdqSFF848Cj86TwfaMwejxRuhepAETvotA4k+kJ/Gm
+1I8KRz1PpRsrPN0JaW5EFVA+hb/+C8rYoZOjfT6/33hAlXEmdtHSON1l432GpNeH
+Ula2ZBjTDF6ipp56rZAHQ9KCTewO8oHH/EblYldJL5Pf9+ngjMDB6yJn4QIDAQAB
+AoGACCuYIWaYll80UzslYRvo8lC8nOfEb5v6bBKxBTQD98GLY+5hKywiG3RlPalG
+mb/fXQeSPReaRYgpdwD1OBEIOEMW9kLyqpzokC0xjpZ+MwsuJTlxCesk5GEsMa3o
+wC3QMmiRA7qrZ/SzTtwrs++9mZ/pxp8JZ6pKYUj8SE7/vV0CQQDz8Ix2t40E16hx
+04+XhClnGqydZJyLLSxcTU3ZVhYxL+efo/5hZ8tKpkcDi8wq6T03BOKrKxrlIW55
+qDRNM24rAkEAxsWzu/rJhIouQyNoYygEIEYzFRlTQyZSg59u6dNiewMn27dOAbyc
+YT7B6da7e74QttTXo0lIllsX2S38+XsIIwJBANSRuIU3G66tkr5l4gnhhAaxqtuY
+sgVhvvdL8dvC9aG1Ifzt9hzBSthpHxbK+oYmK07HdhI8hLpIMLHYzoK7n3MCQEy4
+4rccBcxyyYiAkjozp+QNNIpgTBMPJ6pGT7lRLiHtBeV4y1NASdv/LTnk+Fi69Bid
+7t3H24ytfHcHmS1yn6ECQF6Jmh4C7dlvp59zXp+t+VsXxa/8sq41vKNIj0Rx9vh5
+xp9XL0C5ZpgmBnsTydP9pmkiL4ltLbMX0wJU6N2cmFw=
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/demos/smime/signer2.pem b/openssl/demos/smime/signer2.pem
new file mode 100644
index 0000000..25e23d1
--- /dev/null
+++ b/openssl/demos/smime/signer2.pem
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIICpjCCAg+gAwIBAgIJAJ+rfmEoLQRiMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
+BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
+dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTgyOTQ0
+WhcNMTcwNDA5MTgyOTQ0WjBWMQswCQYDVQQGEwJVSzElMCMGA1UEAxMcT3BlblNT
+TCB0ZXN0IFMvTUlNRSBzaWduZXIgMjEgMB4GCSqGSIb3DQEJARYRdGVzdDJAb3Bl
+bnNzbC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANco7VPgX9vcGwmZ
+jYqjq1JiR7M38dsMNhuJyLRVjJ5/cpFluQydQuG1PhzOJ8zfYVFicOXKvbYuKuXW
+ozZIwzqEqWsNf36KHTLS6yOMG8I13cRInh+fAIKq9Z8Eh65I7FJzVsNsfEQrGfEW
+GMA8us24IaSvP3QkbfHJn/4RaKznAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI
+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
+BBRlrLQJUB8uAa4q8B2OqvvTXonF5zAfBgNVHSMEGDAWgBRHUypxCXFQYqewhGo7
+2lWPQUsjoDANBgkqhkiG9w0BAQQFAAOBgQBQbi2juGALg2k9m1hKpzR2lCGmGO3X
+h3Jh/l0vIxDr0RTgP2vBrtITlx655P/o1snoeTIpYG8uUnFnTE/6YakdayAIlxV4
+aZl63AivZMpQB5SPaPH/jEsGJ8UQMfdiy4ORWIULupuPKlKwODNw7tVhQIACS/DR
+2aX6rl2JEuJ5Yg==
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQDXKO1T4F/b3BsJmY2Ko6tSYkezN/HbDDYbici0VYyef3KRZbkM
+nULhtT4czifM32FRYnDlyr22Lirl1qM2SMM6hKlrDX9+ih0y0usjjBvCNd3ESJ4f
+nwCCqvWfBIeuSOxSc1bDbHxEKxnxFhjAPLrNuCGkrz90JG3xyZ/+EWis5wIDAQAB
+AoGAUTB2bcIrKfGimjrBOGGOUmYXnD8uGnQ/LqENhU8K4vxApTD3ZRUqmbUknQYF
+6r8YH/e/llasw8QkF9qod+F5GTgsnyh/aMidFHKrXXbf1662scz9+S6crSXq9Eb2
+CL57f6Kw61k6edrz8zHdA+rnTK00hzgzKCP4ZL5k8/55ueECQQD+BK+nsKi6CcKf
+m3Mh61Sf2Icm5JlMCKaihlbnh78lBN1imYUAfHJEnQ1ujxXB94R+6o9S+XrWTnTX
+2m/JNIfpAkEA2NaidX7Sv5jnRPkwJ02Srl0urxINLmg4bU0zmM3VoMklYBHWnMyr
+upPZGPh5TzCa+g6FTBmU8XK61wvnEKNcTwJBAM24VdnlBIDGbsx8RJ3vzLU30xz4
+ff5J80okqjUQhwkgC3tTAZgHMTPITZyAXQqdvrxakoCMc6MkHxTBX08AMCECQHHL
+SdyxXrYv7waSY0PtANJCkpJLveEhzqMFxdMmCjtj9BpTojYNbv3uQxtIopj9YAdk
+gW2ray++zvC2DV/86x8CQH4UJwgO6JqU4bSgi6HiRNjDg26tJ0Beu8jjl1vrkIVX
+pHFwSUeLZUsT2/iTUSgYH4uYiZPgYNcKTCT9W6se30A=
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/demos/smime/smdec.c b/openssl/demos/smime/smdec.c
new file mode 100644
index 0000000..8b1a854
--- /dev/null
+++ b/openssl/demos/smime/smdec.c
@@ -0,0 +1,83 @@
+/* Simple S/MIME signing example */
+#include <openssl/pem.h>
+#include <openssl/pkcs7.h>
+#include <openssl/err.h>
+
+int main(int argc, char **argv)
+	{
+	BIO *in = NULL, *out = NULL, *tbio = NULL;
+	X509 *rcert = NULL;
+	EVP_PKEY *rkey = NULL;
+	PKCS7 *p7 = NULL;
+	int ret = 1;
+
+	OpenSSL_add_all_algorithms();
+	ERR_load_crypto_strings();
+
+	/* Read in recipient certificate and private key */
+	tbio = BIO_new_file("signer.pem", "r");
+
+	if (!tbio)
+		goto err;
+
+	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
+
+	BIO_reset(tbio);
+
+	rkey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
+
+	if (!rcert || !rkey)
+		goto err;
+
+	/* Open content being signed */
+
+	in = BIO_new_file("smencr.txt", "r");
+
+	if (!in)
+		goto err;
+
+	/* Sign content */
+	p7 = SMIME_read_PKCS7(in, NULL);
+
+	if (!p7)
+		goto err;
+
+	out = BIO_new_file("encrout.txt", "w");
+	if (!out)
+		goto err;
+
+	/* Decrypt S/MIME message */
+	if (!PKCS7_decrypt(p7, rkey, rcert, out, 0))
+		goto err;
+
+	ret = 0;
+
+	err:
+
+	if (ret)
+		{
+		fprintf(stderr, "Error Signing Data\n");
+		ERR_print_errors_fp(stderr);
+		}
+
+	if (p7)
+		PKCS7_free(p7);
+	if (rcert)
+		X509_free(rcert);
+	if (rkey)
+		EVP_PKEY_free(rkey);
+
+	if (in)
+		BIO_free(in);
+	if (out)
+		BIO_free(out);
+	if (tbio)
+		BIO_free(tbio);
+
+	return ret;
+
+	}
+
+
+
+
diff --git a/openssl/demos/smime/smenc.c b/openssl/demos/smime/smenc.c
new file mode 100644
index 0000000..77dd732
--- /dev/null
+++ b/openssl/demos/smime/smenc.c
@@ -0,0 +1,92 @@
+/* Simple S/MIME encrypt example */
+#include <openssl/pem.h>
+#include <openssl/pkcs7.h>
+#include <openssl/err.h>
+
+int main(int argc, char **argv)
+	{
+	BIO *in = NULL, *out = NULL, *tbio = NULL;
+	X509 *rcert = NULL;
+	STACK_OF(X509) *recips = NULL;
+	PKCS7 *p7 = NULL;
+	int ret = 1;
+
+	/*
+	 * On OpenSSL 0.9.9 only:
+	 * for streaming set PKCS7_STREAM
+	 */
+	int flags = PKCS7_STREAM;
+
+	OpenSSL_add_all_algorithms();
+	ERR_load_crypto_strings();
+
+	/* Read in recipient certificate */
+	tbio = BIO_new_file("signer.pem", "r");
+
+	if (!tbio)
+		goto err;
+
+	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
+
+	if (!rcert)
+		goto err;
+
+	/* Create recipient STACK and add recipient cert to it */
+	recips = sk_X509_new_null();
+
+	if (!recips || !sk_X509_push(recips, rcert))
+		goto err;
+
+	/* sk_X509_pop_free will free up recipient STACK and its contents
+	 * so set rcert to NULL so it isn't freed up twice.
+	 */
+	rcert = NULL;
+
+	/* Open content being encrypted */
+
+	in = BIO_new_file("encr.txt", "r");
+
+	if (!in)
+		goto err;
+
+	/* encrypt content */
+	p7 = PKCS7_encrypt(recips, in, EVP_des_ede3_cbc(), flags);
+
+	if (!p7)
+		goto err;
+
+	out = BIO_new_file("smencr.txt", "w");
+	if (!out)
+		goto err;
+
+	/* Write out S/MIME message */
+	if (!SMIME_write_PKCS7(out, p7, in, flags))
+		goto err;
+
+	ret = 0;
+
+	err:
+
+	if (ret)
+		{
+		fprintf(stderr, "Error Encrypting Data\n");
+		ERR_print_errors_fp(stderr);
+		}
+
+	if (p7)
+		PKCS7_free(p7);
+	if (rcert)
+		X509_free(rcert);
+	if (recips)
+		sk_X509_pop_free(recips, X509_free);
+
+	if (in)
+		BIO_free(in);
+	if (out)
+		BIO_free(out);
+	if (tbio)
+		BIO_free(tbio);
+
+	return ret;
+
+	}
diff --git a/openssl/demos/smime/smsign.c b/openssl/demos/smime/smsign.c
new file mode 100644
index 0000000..ba78830
--- /dev/null
+++ b/openssl/demos/smime/smsign.c
@@ -0,0 +1,89 @@
+/* Simple S/MIME signing example */
+#include <openssl/pem.h>
+#include <openssl/pkcs7.h>
+#include <openssl/err.h>
+
+int main(int argc, char **argv)
+	{
+	BIO *in = NULL, *out = NULL, *tbio = NULL;
+	X509 *scert = NULL;
+	EVP_PKEY *skey = NULL;
+	PKCS7 *p7 = NULL;
+	int ret = 1;
+
+	/* For simple S/MIME signing use PKCS7_DETACHED.
+	 * On OpenSSL 0.9.9 only:
+	 * for streaming detached set PKCS7_DETACHED|PKCS7_STREAM
+	 * for streaming non-detached set PKCS7_STREAM
+	 */
+	int flags = PKCS7_DETACHED|PKCS7_STREAM;
+
+	OpenSSL_add_all_algorithms();
+	ERR_load_crypto_strings();
+
+	/* Read in signer certificate and private key */
+	tbio = BIO_new_file("signer.pem", "r");
+
+	if (!tbio)
+		goto err;
+
+	scert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
+
+	BIO_reset(tbio);
+
+	skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
+
+	if (!scert || !skey)
+		goto err;
+
+	/* Open content being signed */
+
+	in = BIO_new_file("sign.txt", "r");
+
+	if (!in)
+		goto err;
+
+	/* Sign content */
+	p7 = PKCS7_sign(scert, skey, NULL, in, flags);
+
+	if (!p7)
+		goto err;
+
+	out = BIO_new_file("smout.txt", "w");
+	if (!out)
+		goto err;
+
+	if (!(flags & PKCS7_STREAM))
+		BIO_reset(in);
+
+	/* Write out S/MIME message */
+	if (!SMIME_write_PKCS7(out, p7, in, flags))
+		goto err;
+
+	ret = 0;
+
+	err:
+
+	if (ret)
+		{
+		fprintf(stderr, "Error Signing Data\n");
+		ERR_print_errors_fp(stderr);
+		}
+
+	if (p7)
+		PKCS7_free(p7);
+	if (scert)
+		X509_free(scert);
+	if (skey)
+		EVP_PKEY_free(skey);
+
+	if (in)
+		BIO_free(in);
+	if (out)
+		BIO_free(out);
+	if (tbio)
+		BIO_free(tbio);
+
+	return ret;
+
+	}
diff --git a/openssl/demos/smime/smsign2.c b/openssl/demos/smime/smsign2.c
new file mode 100644
index 0000000..ff835c5
--- /dev/null
+++ b/openssl/demos/smime/smsign2.c
@@ -0,0 +1,107 @@
+/* S/MIME signing example: 2 signers. OpenSSL 0.9.9 only */
+#include <openssl/pem.h>
+#include <openssl/pkcs7.h>
+#include <openssl/err.h>
+
+int main(int argc, char **argv)
+	{
+	BIO *in = NULL, *out = NULL, *tbio = NULL;
+	X509 *scert = NULL, *scert2 = NULL;
+	EVP_PKEY *skey = NULL, *skey2 = NULL;
+	PKCS7 *p7 = NULL;
+	int ret = 1;
+
+	OpenSSL_add_all_algorithms();
+	ERR_load_crypto_strings();
+
+	tbio = BIO_new_file("signer.pem", "r");
+
+	if (!tbio)
+		goto err;
+
+	scert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
+
+	BIO_reset(tbio);
+
+	skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
+
+	BIO_free(tbio);
+
+	tbio = BIO_new_file("signer2.pem", "r");
+
+	if (!tbio)
+		goto err;
+
+	scert2 = PEM_read_bio_X509(tbio, NULL, 0, NULL);
+
+	BIO_reset(tbio);
+
+	skey2 = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
+
+	if (!scert2 || !skey2)
+		goto err;
+
+	in = BIO_new_file("sign.txt", "r");
+
+	if (!in)
+		goto err;
+
+	p7 = PKCS7_sign(NULL, NULL, NULL, in, PKCS7_STREAM|PKCS7_PARTIAL);
+
+	if (!p7)
+		goto err;
+
+	/* Add each signer in turn */
+
+	if (!PKCS7_sign_add_signer(p7, scert, skey, NULL, 0))
+		goto err;
+
+	if (!PKCS7_sign_add_signer(p7, scert2, skey2, NULL, 0))
+		goto err;
+
+	out = BIO_new_file("smout.txt", "w");
+	if (!out)
+		goto err;
+
+	/* NB: content included and finalized by SMIME_write_PKCS7 */
+
+	if (!SMIME_write_PKCS7(out, p7, in, PKCS7_STREAM))
+		goto err;
+
+	ret = 0;
+
+	err:
+
+	if (ret)
+		{
+		fprintf(stderr, "Error Signing Data\n");
+		ERR_print_errors_fp(stderr);
+		}
+
+	if (p7)
+		PKCS7_free(p7);
+
+	if (scert)
+		X509_free(scert);
+	if (skey)
+		EVP_PKEY_free(skey);
+
+	if (scert2)
+		X509_free(scert2);
+	if (skey)
+		EVP_PKEY_free(skey2);
+
+	if (in)
+		BIO_free(in);
+	if (out)
+		BIO_free(out);
+	if (tbio)
+		BIO_free(tbio);
+
+	return ret;
+
+	}
+
+
+
+
diff --git a/openssl/demos/smime/smver.c b/openssl/demos/smime/smver.c
new file mode 100644
index 0000000..9d360c2
--- /dev/null
+++ b/openssl/demos/smime/smver.c
@@ -0,0 +1,87 @@
+/* Simple S/MIME verification example */
+#include <openssl/pem.h>
+#include <openssl/pkcs7.h>
+#include <openssl/err.h>
+
+int main(int argc, char **argv)
+	{
+	BIO *in = NULL, *out = NULL, *tbio = NULL, *cont = NULL;
+	X509_STORE *st = NULL;
+	X509 *cacert = NULL;
+	PKCS7 *p7 = NULL;
+
+	int ret = 1;
+
+	OpenSSL_add_all_algorithms();
+	ERR_load_crypto_strings();
+
+	/* Set up trusted CA certificate store */
+
+	st = X509_STORE_new();
+
+	/* Read in signer certificate and private key */
+	tbio = BIO_new_file("cacert.pem", "r");
+
+	if (!tbio)
+		goto err;
+
+	cacert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
+
+	if (!cacert)
+		goto err;
+
+	if (!X509_STORE_add_cert(st, cacert))
+		goto err;
+
+	/* Open content being signed */
+
+	in = BIO_new_file("smout.txt", "r");
+
+	if (!in)
+		goto err;
+
+	/* Sign content */
+	p7 = SMIME_read_PKCS7(in, &cont);
+
+	if (!p7)
+		goto err;
+
+	/* File to output verified content to */
+	out = BIO_new_file("smver.txt", "w");
+	if (!out)
+		goto err;
+
+	if (!PKCS7_verify(p7, NULL, st, cont, out, 0))
+		{
+		fprintf(stderr, "Verification Failure\n");
+		goto err;
+		}
+
+	fprintf(stderr, "Verification Successful\n");
+
+	ret = 0;
+
+	err:
+
+	if (ret)
+		{
+		fprintf(stderr, "Error Verifying Data\n");
+		ERR_print_errors_fp(stderr);
+		}
+
+	if (p7)
+		PKCS7_free(p7);
+
+	if (cacert)
+		X509_free(cacert);
+
+	if (in)
+		BIO_free(in);
+	if (out)
+		BIO_free(out);
+	if (tbio)
+		BIO_free(tbio);
+
+	return ret;
+
+	}
diff --git a/openssl/demos/spkigen.c b/openssl/demos/spkigen.c
new file mode 100644
index 0000000..2cd5dfe
--- /dev/null
+++ b/openssl/demos/spkigen.c
@@ -0,0 +1,161 @@
+/* NOCW */
+/* demos/spkigen.c
+ * 18-Mar-1997 - eay - A quick hack :-) 
+ * 		version 1.1, it would probably help to save or load the
+ *		private key :-)
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/err.h>
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+/* The following two don't exist in SSLeay but they are in here as
+ * examples */
+#define PEM_write_SPKI(fp,x) \
+	PEM_ASN1_write((int (*)())i2d_NETSCAPE_SPKI,"SPKI",fp,\
+			(char *)x,NULL,NULL,0,NULL)
+int SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
+
+/* These are defined in the next version of SSLeay */
+int EVP_PKEY_assign(EVP_PKEY *pkey, int type,char *key);
+#define RSA_F4	0x10001
+#define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
+					(char *)(rsa))
+
+int main(argc,argv)
+int argc;
+char *argv[];
+	{
+	RSA *rsa=NULL;
+	NETSCAPE_SPKI *spki=NULL;
+	EVP_PKEY *pkey=NULL;
+	char buf[128];
+	int ok=0,i;
+	FILE *fp;
+
+	pkey=EVP_PKEY_new();
+	 
+	if (argc < 2)
+		{
+		/* Generate an RSA key, the random state should have been seeded
+		 * with lots of calls to RAND_seed(....) */
+		fprintf(stderr,"generating RSA key, could take some time...\n");
+		if ((rsa=RSA_generate_key(512,RSA_F4,NULL)) == NULL) goto err;
+		}
+	else
+		{
+		if ((fp=fopen(argv[1],"r")) == NULL)
+			{ perror(argv[1]); goto err; }
+		if ((rsa=PEM_read_RSAPrivateKey(fp,NULL,NULL)) == NULL)
+			goto err;
+		fclose(fp);
+		}
+	
+	if (!EVP_PKEY_assign_RSA(pkey,rsa)) goto err;
+	rsa=NULL;
+
+	/* lets make the spki and set the public key and challenge */
+	if ((spki=NETSCAPE_SPKI_new()) == NULL) goto err;
+
+	if (!SPKI_set_pubkey(spki,pkey)) goto err;
+
+	fprintf(stderr,"please enter challenge string:");
+	fflush(stderr);
+	buf[0]='\0';
+	fgets(buf,sizeof buf,stdin);
+	i=strlen(buf);
+	if (i > 0) buf[--i]='\0';
+	if (!ASN1_STRING_set((ASN1_STRING *)spki->spkac->challenge,
+		buf,i)) goto err;
+
+	if (!NETSCAPE_SPKI_sign(spki,pkey,EVP_md5())) goto err;
+	PEM_write_SPKI(stdout,spki);
+	if (argc < 2)
+		PEM_write_RSAPrivateKey(stdout,pkey->pkey.rsa,NULL,NULL,0,NULL);
+
+	ok=1;
+err:
+	if (!ok)
+		{
+		fprintf(stderr,"something bad happened....");
+		ERR_print_errors_fp(stderr);
+		}
+	NETSCAPE_SPKI_free(spki);
+	EVP_PKEY_free(pkey);
+	exit(!ok);
+	}
+
+/* This function is in the next version of SSLeay */
+int EVP_PKEY_assign(pkey,type,key)
+EVP_PKEY *pkey;
+int type;
+char *key;
+	{
+	if (pkey == NULL) return(0);
+	if (pkey->pkey.ptr != NULL)
+		{
+		if (pkey->type == EVP_PKEY_RSA)
+			RSA_free(pkey->pkey.rsa);
+		/* else memory leak */
+		}
+	pkey->type=type;
+	pkey->pkey.ptr=key;
+	return(1);
+	}
+
+/* While I have a 
+ * X509_set_pubkey() and X509_REQ_set_pubkey(), SPKI_set_pubkey() does
+ * not currently exist so here is a version of it.
+ * The next SSLeay release will probably have
+ * X509_set_pubkey(),
+ * X509_REQ_set_pubkey() and
+ * NETSCAPE_SPKI_set_pubkey()
+ * as macros calling the same function */
+int SPKI_set_pubkey(x,pkey)
+NETSCAPE_SPKI *x;
+EVP_PKEY *pkey;
+	{
+	int ok=0;
+	X509_PUBKEY *pk;
+	X509_ALGOR *a;
+	ASN1_OBJECT *o;
+	unsigned char *s,*p;
+	int i;
+
+	if (x == NULL) return(0);
+
+	if ((pk=X509_PUBKEY_new()) == NULL) goto err;
+	a=pk->algor;
+
+	/* set the algorithm id */
+	if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err;
+	ASN1_OBJECT_free(a->algorithm);
+	a->algorithm=o;
+
+	/* Set the parameter list */
+	if ((a->parameter == NULL) || (a->parameter->type != V_ASN1_NULL))
+		{
+		ASN1_TYPE_free(a->parameter);
+		a->parameter=ASN1_TYPE_new();
+		a->parameter->type=V_ASN1_NULL;
+		}
+	i=i2d_PublicKey(pkey,NULL);
+	if ((s=(unsigned char *)malloc(i+1)) == NULL) goto err;
+	p=s;
+	i2d_PublicKey(pkey,&p);
+	if (!ASN1_BIT_STRING_set(pk->public_key,s,i)) goto err;
+	free(s);
+
+	X509_PUBKEY_free(x->spkac->pubkey);
+	x->spkac->pubkey=pk;
+	pk=NULL;
+	ok=1;
+err:
+	if (pk != NULL) X509_PUBKEY_free(pk);
+	return(ok);
+	}
+
diff --git a/openssl/demos/ssl/cli.cpp b/openssl/demos/ssl/cli.cpp
new file mode 100644
index 0000000..49cba5d
--- /dev/null
+++ b/openssl/demos/ssl/cli.cpp
@@ -0,0 +1,110 @@
+/* cli.cpp  -  Minimal ssleay client for Unix
+   30.9.1996, Sampo Kellomaki <sampo@iki.fi> */
+
+/* mangled to work with SSLeay-0.9.0b and OpenSSL 0.9.2b
+   Simplified to be even more minimal
+   12/98 - 4/99 Wade Scholine <wades@mail.cybg.com> */
+
+#include <stdio.h>
+#include <memory.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+
+#define CHK_NULL(x) if ((x)==NULL) exit (1)
+#define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); }
+#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(2); }
+
+void main ()
+{
+  int err;
+  int sd;
+  struct sockaddr_in sa;
+  SSL_CTX* ctx;
+  SSL*     ssl;
+  X509*    server_cert;
+  char*    str;
+  char     buf [4096];
+  SSL_METHOD *meth;
+
+  SSLeay_add_ssl_algorithms();
+  meth = SSLv2_client_method();
+  SSL_load_error_strings();
+  ctx = SSL_CTX_new (meth);                        CHK_NULL(ctx);
+
+  CHK_SSL(err);
+  
+  /* ----------------------------------------------- */
+  /* Create a socket and connect to server using normal socket calls. */
+  
+  sd = socket (AF_INET, SOCK_STREAM, 0);       CHK_ERR(sd, "socket");
+ 
+  memset (&sa, '\0', sizeof(sa));
+  sa.sin_family      = AF_INET;
+  sa.sin_addr.s_addr = inet_addr ("127.0.0.1");   /* Server IP */
+  sa.sin_port        = htons     (1111);          /* Server Port number */
+  
+  err = connect(sd, (struct sockaddr*) &sa,
+		sizeof(sa));                   CHK_ERR(err, "connect");
+
+  /* ----------------------------------------------- */
+  /* Now we have TCP conncetion. Start SSL negotiation. */
+  
+  ssl = SSL_new (ctx);                         CHK_NULL(ssl);    
+  SSL_set_fd (ssl, sd);
+  err = SSL_connect (ssl);                     CHK_SSL(err);
+    
+  /* Following two steps are optional and not required for
+     data exchange to be successful. */
+  
+  /* Get the cipher - opt */
+
+  printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
+  
+  /* Get server's certificate (note: beware of dynamic allocation) - opt */
+
+  server_cert = SSL_get_peer_certificate (ssl);       CHK_NULL(server_cert);
+  printf ("Server certificate:\n");
+  
+  str = X509_NAME_oneline (X509_get_subject_name (server_cert),0,0);
+  CHK_NULL(str);
+  printf ("\t subject: %s\n", str);
+  OPENSSL_free (str);
+
+  str = X509_NAME_oneline (X509_get_issuer_name  (server_cert),0,0);
+  CHK_NULL(str);
+  printf ("\t issuer: %s\n", str);
+  OPENSSL_free (str);
+
+  /* We could do all sorts of certificate verification stuff here before
+     deallocating the certificate. */
+
+  X509_free (server_cert);
+  
+  /* --------------------------------------------------- */
+  /* DATA EXCHANGE - Send a message and receive a reply. */
+
+  err = SSL_write (ssl, "Hello World!", strlen("Hello World!"));  CHK_SSL(err);
+  
+  err = SSL_read (ssl, buf, sizeof(buf) - 1);                     CHK_SSL(err);
+  buf[err] = '\0';
+  printf ("Got %d chars:'%s'\n", err, buf);
+  SSL_shutdown (ssl);  /* send SSL/TLS close_notify */
+
+  /* Clean up. */
+
+  close (sd);
+  SSL_free (ssl);
+  SSL_CTX_free (ctx);
+}
+/* EOF - cli.cpp */
diff --git a/openssl/demos/ssl/inetdsrv.cpp b/openssl/demos/ssl/inetdsrv.cpp
new file mode 100644
index 0000000..efd70d2
--- /dev/null
+++ b/openssl/demos/ssl/inetdsrv.cpp
@@ -0,0 +1,98 @@
+/* inetdserv.cpp  -  Minimal ssleay server for Unix inetd.conf
+ * 30.9.1996, Sampo Kellomaki <sampo@iki.fi>
+ * From /etc/inetd.conf:
+ *     1111 stream tcp nowait sampo /usr/users/sampo/demo/inetdserv inetdserv
+ */
+
+#include <stdio.h>
+#include <errno.h>
+
+#include "rsa.h"       /* SSLeay stuff */
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+#define HOME "/usr/users/sampo/demo/"
+#define CERTF HOME "plain-cert.pem"
+#define KEYF  HOME "plain-key.pem"
+
+#define CHK_NULL(x) if ((x)==NULL) exit (1)
+#define CHK_ERR(err,s) if ((err)==-1) \
+                         { fprintf(log, "%s %d\n", (s), errno); exit(1); }
+#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(log); exit(2); }
+
+void main ()
+{
+  int err;
+  SSL_CTX* ctx;
+  SSL*     ssl;
+  X509*    client_cert;
+  char*    str;
+  char     buf [4096];
+  FILE* log;
+  
+  log = fopen ("/dev/console", "a");                     CHK_NULL(log);
+  fprintf (log, "inetdserv %ld\n", (long)getpid());
+  
+  SSL_load_error_strings();
+  ctx = SSL_CTX_new (); CHK_NULL(ctx);
+  
+  err = SSL_CTX_use_RSAPrivateKey_file (ctx, KEYF,  SSL_FILETYPE_PEM);
+  CHK_SSL (err);
+  
+  err = SSL_CTX_use_certificate_file   (ctx, CERTF, SSL_FILETYPE_PEM);
+  CHK_SSL (err);
+
+  /* inetd has already opened the TCP connection, so we can get right
+     down to business. */
+  
+  ssl = SSL_new (ctx);  CHK_NULL(ssl);
+  SSL_set_fd (ssl,  fileno(stdin));
+  err = SSL_accept (ssl);                                CHK_SSL(err);
+  
+  /* Get the cipher - opt */
+  
+  fprintf (log, "SSL connection using %s\n", SSL_get_cipher (ssl));
+  
+  /* Get client's certificate (note: beware of dynamic allocation) - opt */
+
+  client_cert = SSL_get_peer_certificate (ssl);
+  if (client_cert != NULL) {
+    fprintf (log, "Client certificate:\n");
+    
+    str = X509_NAME_oneline (X509_get_subject_name (client_cert));
+    CHK_NULL(str);
+    fprintf (log, "\t subject: %s\n", str);
+    OPENSSL_free (str);
+    
+    str = X509_NAME_oneline (X509_get_issuer_name  (client_cert));
+    CHK_NULL(str);
+    fprintf (log, "\t issuer: %s\n", str);
+    OPENSSL_free (str);
+    
+    /* We could do all sorts of certificate verification stuff here before
+       deallocating the certificate. */
+    
+    X509_free (client_cert);
+  } else
+    fprintf (log, "Client doe not have certificate.\n");
+
+  /* ------------------------------------------------- */
+  /* DATA EXCHANGE: Receive message and send reply  */
+  
+  err = SSL_read (ssl, buf, sizeof(buf) - 1);  CHK_SSL(err);
+  buf[err] = '\0';
+  fprintf (log, "Got %d chars:'%s'\n", err, buf);
+  
+  err = SSL_write (ssl, "Loud and clear.", strlen("Loud and clear."));
+  CHK_SSL(err);
+
+  /* Clean up. */
+
+  fclose (log);
+  SSL_free (ssl);
+  SSL_CTX_free (ctx);
+}
+/* EOF - inetdserv.cpp */
diff --git a/openssl/demos/ssl/serv.cpp b/openssl/demos/ssl/serv.cpp
new file mode 100644
index 0000000..b142c75
--- /dev/null
+++ b/openssl/demos/ssl/serv.cpp
@@ -0,0 +1,152 @@
+/* serv.cpp  -  Minimal ssleay server for Unix
+   30.9.1996, Sampo Kellomaki <sampo@iki.fi> */
+
+
+/* mangled to work with SSLeay-0.9.0b and OpenSSL 0.9.2b
+   Simplified to be even more minimal
+   12/98 - 4/99 Wade Scholine <wades@mail.cybg.com> */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <openssl/rsa.h>       /* SSLeay stuff */
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+
+/* define HOME to be dir for key and cert files... */
+#define HOME "./"
+/* Make these what you want for cert & key files */
+#define CERTF  HOME "foo-cert.pem"
+#define KEYF  HOME  "foo-cert.pem"
+
+
+#define CHK_NULL(x) if ((x)==NULL) exit (1)
+#define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); }
+#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(2); }
+
+void main ()
+{
+  int err;
+  int listen_sd;
+  int sd;
+  struct sockaddr_in sa_serv;
+  struct sockaddr_in sa_cli;
+  size_t client_len;
+  SSL_CTX* ctx;
+  SSL*     ssl;
+  X509*    client_cert;
+  char*    str;
+  char     buf [4096];
+  SSL_METHOD *meth;
+  
+  /* SSL preliminaries. We keep the certificate and key with the context. */
+
+  SSL_load_error_strings();
+  SSLeay_add_ssl_algorithms();
+  meth = SSLv23_server_method();
+  ctx = SSL_CTX_new (meth);
+  if (!ctx) {
+    ERR_print_errors_fp(stderr);
+    exit(2);
+  }
+  
+  if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0) {
+    ERR_print_errors_fp(stderr);
+    exit(3);
+  }
+  if (SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM) <= 0) {
+    ERR_print_errors_fp(stderr);
+    exit(4);
+  }
+
+  if (!SSL_CTX_check_private_key(ctx)) {
+    fprintf(stderr,"Private key does not match the certificate public key\n");
+    exit(5);
+  }
+
+  /* ----------------------------------------------- */
+  /* Prepare TCP socket for receiving connections */
+
+  listen_sd = socket (AF_INET, SOCK_STREAM, 0);   CHK_ERR(listen_sd, "socket");
+  
+  memset (&sa_serv, '\0', sizeof(sa_serv));
+  sa_serv.sin_family      = AF_INET;
+  sa_serv.sin_addr.s_addr = INADDR_ANY;
+  sa_serv.sin_port        = htons (1111);          /* Server Port number */
+  
+  err = bind(listen_sd, (struct sockaddr*) &sa_serv,
+	     sizeof (sa_serv));                   CHK_ERR(err, "bind");
+	     
+  /* Receive a TCP connection. */
+	     
+  err = listen (listen_sd, 5);                    CHK_ERR(err, "listen");
+  
+  client_len = sizeof(sa_cli);
+  sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len);
+  CHK_ERR(sd, "accept");
+  close (listen_sd);
+
+  printf ("Connection from %lx, port %x\n",
+	  sa_cli.sin_addr.s_addr, sa_cli.sin_port);
+  
+  /* ----------------------------------------------- */
+  /* TCP connection is ready. Do server side SSL. */
+
+  ssl = SSL_new (ctx);                           CHK_NULL(ssl);
+  SSL_set_fd (ssl, sd);
+  err = SSL_accept (ssl);                        CHK_SSL(err);
+  
+  /* Get the cipher - opt */
+  
+  printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
+  
+  /* Get client's certificate (note: beware of dynamic allocation) - opt */
+
+  client_cert = SSL_get_peer_certificate (ssl);
+  if (client_cert != NULL) {
+    printf ("Client certificate:\n");
+    
+    str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);
+    CHK_NULL(str);
+    printf ("\t subject: %s\n", str);
+    OPENSSL_free (str);
+    
+    str = X509_NAME_oneline (X509_get_issuer_name  (client_cert), 0, 0);
+    CHK_NULL(str);
+    printf ("\t issuer: %s\n", str);
+    OPENSSL_free (str);
+    
+    /* We could do all sorts of certificate verification stuff here before
+       deallocating the certificate. */
+    
+    X509_free (client_cert);
+  } else
+    printf ("Client does not have certificate.\n");
+
+  /* DATA EXCHANGE - Receive message and send reply. */
+
+  err = SSL_read (ssl, buf, sizeof(buf) - 1);                   CHK_SSL(err);
+  buf[err] = '\0';
+  printf ("Got %d chars:'%s'\n", err, buf);
+  
+  err = SSL_write (ssl, "I hear you.", strlen("I hear you."));  CHK_SSL(err);
+
+  /* Clean up. */
+
+  close (sd);
+  SSL_free (ssl);
+  SSL_CTX_free (ctx);
+}
+/* EOF - serv.cpp */
diff --git a/openssl/demos/ssltest-ecc/ECC-RSAcertgen.sh b/openssl/demos/ssltest-ecc/ECC-RSAcertgen.sh
new file mode 100755
index 0000000..b31a4f1
--- /dev/null
+++ b/openssl/demos/ssltest-ecc/ECC-RSAcertgen.sh
@@ -0,0 +1,98 @@
+#!/bin/sh
+
+# For a list of supported curves, use "apps/openssl ecparam -list_curves".
+
+# Path to the openssl distribution
+OPENSSL_DIR=../..
+# Path to the openssl program
+OPENSSL_CMD=$OPENSSL_DIR/apps/openssl
+# Option to find configuration file
+OPENSSL_CNF="-config $OPENSSL_DIR/apps/openssl.cnf"
+# Directory where certificates are stored
+CERTS_DIR=./Certs
+# Directory where private key files are stored
+KEYS_DIR=$CERTS_DIR
+# Directory where combo files (containing a certificate and corresponding
+# private key together) are stored
+COMBO_DIR=$CERTS_DIR
+# cat command
+CAT=/bin/cat
+# rm command
+RM=/bin/rm
+# mkdir command
+MKDIR=/bin/mkdir
+# The certificate will expire these many days after the issue date.
+DAYS=1500
+TEST_CA_FILE=rsa1024TestCA
+
+TEST_SERVER_CURVE=sect163r1
+TEST_SERVER_FILE=sect163r1-rsaTestServer
+TEST_SERVER_DN="/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test Server (sect163r1 key signed with RSA)"
+
+TEST_CLIENT_CURVE=sect163r1
+TEST_CLIENT_FILE=sect163r1-rsaTestClient
+TEST_CLIENT_DN="/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test Client (sect163r1 key signed with RSA)"
+
+# Generating an EC certificate involves the following main steps
+# 1. Generating curve parameters (if needed)
+# 2. Generating a certificate request
+# 3. Signing the certificate request 
+# 4. [Optional] One can combine the cert and private key into a single
+#    file and also delete the certificate request
+
+$MKDIR -p $CERTS_DIR
+$MKDIR -p $KEYS_DIR
+$MKDIR -p $COMBO_DIR
+
+echo "GENERATING A TEST SERVER CERTIFICATE (ECC key signed with RSA)"
+echo "=============================================================="
+$OPENSSL_CMD ecparam -name $TEST_SERVER_CURVE -out $TEST_SERVER_CURVE.pem
+
+$OPENSSL_CMD req $OPENSSL_CNF -nodes -subj "$TEST_SERVER_DN" \
+    -keyout $KEYS_DIR/$TEST_SERVER_FILE.key.pem \
+    -newkey ec:$TEST_SERVER_CURVE.pem -new \
+    -out $CERTS_DIR/$TEST_SERVER_FILE.req.pem
+
+$OPENSSL_CMD x509 -req -days $DAYS \
+    -in $CERTS_DIR/$TEST_SERVER_FILE.req.pem \
+    -CA $CERTS_DIR/$TEST_CA_FILE.cert.pem \
+    -CAkey $KEYS_DIR/$TEST_CA_FILE.key.pem \
+    -out $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -CAcreateserial
+
+# Display the certificate 
+$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -text
+
+# Place the certificate and key in a common file
+$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -issuer -subject \
+	 > $COMBO_DIR/$TEST_SERVER_FILE.pem
+$CAT $KEYS_DIR/$TEST_SERVER_FILE.key.pem >> $COMBO_DIR/$TEST_SERVER_FILE.pem
+
+# Remove the cert request file (no longer needed)
+$RM $CERTS_DIR/$TEST_SERVER_FILE.req.pem
+
+echo "GENERATING A TEST CLIENT CERTIFICATE (ECC key signed with RSA)"
+echo "=============================================================="
+$OPENSSL_CMD ecparam -name $TEST_CLIENT_CURVE -out $TEST_CLIENT_CURVE.pem
+
+$OPENSSL_CMD req $OPENSSL_CNF -nodes -subj "$TEST_CLIENT_DN" \
+	     -keyout $KEYS_DIR/$TEST_CLIENT_FILE.key.pem \
+	     -newkey ec:$TEST_CLIENT_CURVE.pem -new \
+	     -out $CERTS_DIR/$TEST_CLIENT_FILE.req.pem
+
+$OPENSSL_CMD x509 -req -days $DAYS \
+    -in $CERTS_DIR/$TEST_CLIENT_FILE.req.pem \
+    -CA $CERTS_DIR/$TEST_CA_FILE.cert.pem \
+    -CAkey $KEYS_DIR/$TEST_CA_FILE.key.pem \
+    -out $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -CAcreateserial
+
+# Display the certificate 
+$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -text
+
+# Place the certificate and key in a common file
+$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -issuer -subject \
+	 > $COMBO_DIR/$TEST_CLIENT_FILE.pem
+$CAT $KEYS_DIR/$TEST_CLIENT_FILE.key.pem >> $COMBO_DIR/$TEST_CLIENT_FILE.pem
+
+# Remove the cert request file (no longer needed)
+$RM $CERTS_DIR/$TEST_CLIENT_FILE.req.pem
+
diff --git a/openssl/demos/ssltest-ecc/ECCcertgen.sh b/openssl/demos/ssltest-ecc/ECCcertgen.sh
new file mode 100755
index 0000000..a47b8bb
--- /dev/null
+++ b/openssl/demos/ssltest-ecc/ECCcertgen.sh
@@ -0,0 +1,164 @@
+#!/bin/sh
+
+# For a list of supported curves, use "apps/openssl ecparam -list_curves".
+
+# Path to the openssl distribution
+OPENSSL_DIR=../..
+# Path to the openssl program
+OPENSSL_CMD=$OPENSSL_DIR/apps/openssl
+# Option to find configuration file
+OPENSSL_CNF="-config $OPENSSL_DIR/apps/openssl.cnf"
+# Directory where certificates are stored
+CERTS_DIR=./Certs
+# Directory where private key files are stored
+KEYS_DIR=$CERTS_DIR
+# Directory where combo files (containing a certificate and corresponding
+# private key together) are stored
+COMBO_DIR=$CERTS_DIR
+# cat command
+CAT=/bin/cat
+# rm command
+RM=/bin/rm
+# mkdir command
+MKDIR=/bin/mkdir
+# The certificate will expire these many days after the issue date.
+DAYS=1500
+TEST_CA_CURVE=secp160r1
+TEST_CA_FILE=secp160r1TestCA
+TEST_CA_DN="/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test CA (Elliptic curve secp160r1)"
+
+TEST_SERVER_CURVE=secp160r2
+TEST_SERVER_FILE=secp160r2TestServer
+TEST_SERVER_DN="/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test Server (Elliptic curve secp160r2)"
+
+TEST_CLIENT_CURVE=secp160r2
+TEST_CLIENT_FILE=secp160r2TestClient
+TEST_CLIENT_DN="/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test Client (Elliptic curve secp160r2)"
+
+# Generating an EC certificate involves the following main steps
+# 1. Generating curve parameters (if needed)
+# 2. Generating a certificate request
+# 3. Signing the certificate request 
+# 4. [Optional] One can combine the cert and private key into a single
+#    file and also delete the certificate request
+
+$MKDIR -p $CERTS_DIR
+$MKDIR -p $KEYS_DIR
+$MKDIR -p $COMBO_DIR
+
+echo "Generating self-signed CA certificate (on curve $TEST_CA_CURVE)"
+echo "==============================================================="
+$OPENSSL_CMD ecparam -name $TEST_CA_CURVE -out $TEST_CA_CURVE.pem
+
+# Generate a new certificate request in $TEST_CA_FILE.req.pem. A 
+# new ecdsa (actually ECC) key pair is generated on the parameters in
+# $TEST_CA_CURVE.pem and the private key is saved in $TEST_CA_FILE.key.pem
+# WARNING: By using the -nodes option, we force the private key to be 
+# stored in the clear (rather than encrypted with a password).
+$OPENSSL_CMD req $OPENSSL_CNF -nodes -subj "$TEST_CA_DN" \
+    -keyout $KEYS_DIR/$TEST_CA_FILE.key.pem \
+    -newkey ec:$TEST_CA_CURVE.pem -new \
+    -out $CERTS_DIR/$TEST_CA_FILE.req.pem
+
+# Sign the certificate request in $TEST_CA_FILE.req.pem using the
+# private key in $TEST_CA_FILE.key.pem and include the CA extension.
+# Make the certificate valid for 1500 days from the time of signing.
+# The certificate is written into $TEST_CA_FILE.cert.pem
+$OPENSSL_CMD x509 -req -days $DAYS \
+    -in $CERTS_DIR/$TEST_CA_FILE.req.pem \
+    -extfile $OPENSSL_DIR/apps/openssl.cnf \
+    -extensions v3_ca \
+    -signkey $KEYS_DIR/$TEST_CA_FILE.key.pem \
+    -out $CERTS_DIR/$TEST_CA_FILE.cert.pem
+
+# Display the certificate
+$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CA_FILE.cert.pem -text
+
+# Place the certificate and key in a common file
+$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CA_FILE.cert.pem -issuer -subject \
+	 > $COMBO_DIR/$TEST_CA_FILE.pem
+$CAT $KEYS_DIR/$TEST_CA_FILE.key.pem >> $COMBO_DIR/$TEST_CA_FILE.pem
+
+# Remove the cert request file (no longer needed)
+$RM $CERTS_DIR/$TEST_CA_FILE.req.pem
+
+echo "GENERATING A TEST SERVER CERTIFICATE (on elliptic curve $TEST_SERVER_CURVE)"
+echo "=========================================================================="
+# Generate parameters for curve $TEST_SERVER_CURVE, if needed
+$OPENSSL_CMD ecparam -name $TEST_SERVER_CURVE -out $TEST_SERVER_CURVE.pem
+
+# Generate a new certificate request in $TEST_SERVER_FILE.req.pem. A 
+# new ecdsa (actually ECC) key pair is generated on the parameters in
+# $TEST_SERVER_CURVE.pem and the private key is saved in 
+# $TEST_SERVER_FILE.key.pem
+# WARNING: By using the -nodes option, we force the private key to be 
+# stored in the clear (rather than encrypted with a password).
+$OPENSSL_CMD req $OPENSSL_CNF -nodes -subj "$TEST_SERVER_DN" \
+    -keyout $KEYS_DIR/$TEST_SERVER_FILE.key.pem \
+    -newkey ec:$TEST_SERVER_CURVE.pem -new \
+    -out $CERTS_DIR/$TEST_SERVER_FILE.req.pem
+
+# Sign the certificate request in $TEST_SERVER_FILE.req.pem using the
+# CA certificate in $TEST_CA_FILE.cert.pem and the CA private key in
+# $TEST_CA_FILE.key.pem. Since we do not have an existing serial number
+# file for this CA, create one. Make the certificate valid for $DAYS days
+# from the time of signing. The certificate is written into 
+# $TEST_SERVER_FILE.cert.pem
+$OPENSSL_CMD x509 -req -days $DAYS \
+    -in $CERTS_DIR/$TEST_SERVER_FILE.req.pem \
+    -CA $CERTS_DIR/$TEST_CA_FILE.cert.pem \
+    -CAkey $KEYS_DIR/$TEST_CA_FILE.key.pem \
+    -out $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -CAcreateserial
+
+# Display the certificate 
+$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -text
+
+# Place the certificate and key in a common file
+$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -issuer -subject \
+	 > $COMBO_DIR/$TEST_SERVER_FILE.pem
+$CAT $KEYS_DIR/$TEST_SERVER_FILE.key.pem >> $COMBO_DIR/$TEST_SERVER_FILE.pem
+
+# Remove the cert request file (no longer needed)
+$RM $CERTS_DIR/$TEST_SERVER_FILE.req.pem
+
+echo "GENERATING A TEST CLIENT CERTIFICATE (on elliptic curve $TEST_CLIENT_CURVE)"
+echo "=========================================================================="
+# Generate parameters for curve $TEST_CLIENT_CURVE, if needed
+$OPENSSL_CMD ecparam -name $TEST_CLIENT_CURVE -out $TEST_CLIENT_CURVE.pem
+
+# Generate a new certificate request in $TEST_CLIENT_FILE.req.pem. A 
+# new ecdsa (actually ECC) key pair is generated on the parameters in
+# $TEST_CLIENT_CURVE.pem and the private key is saved in 
+# $TEST_CLIENT_FILE.key.pem
+# WARNING: By using the -nodes option, we force the private key to be 
+# stored in the clear (rather than encrypted with a password).
+$OPENSSL_CMD req $OPENSSL_CNF -nodes -subj "$TEST_CLIENT_DN" \
+	     -keyout $KEYS_DIR/$TEST_CLIENT_FILE.key.pem \
+	     -newkey ec:$TEST_CLIENT_CURVE.pem -new \
+	     -out $CERTS_DIR/$TEST_CLIENT_FILE.req.pem
+
+# Sign the certificate request in $TEST_CLIENT_FILE.req.pem using the
+# CA certificate in $TEST_CA_FILE.cert.pem and the CA private key in
+# $TEST_CA_FILE.key.pem. Since we do not have an existing serial number
+# file for this CA, create one. Make the certificate valid for $DAYS days
+# from the time of signing. The certificate is written into 
+# $TEST_CLIENT_FILE.cert.pem
+$OPENSSL_CMD x509 -req -days $DAYS \
+    -in $CERTS_DIR/$TEST_CLIENT_FILE.req.pem \
+    -CA $CERTS_DIR/$TEST_CA_FILE.cert.pem \
+    -CAkey $KEYS_DIR/$TEST_CA_FILE.key.pem \
+    -out $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -CAcreateserial
+
+# Display the certificate 
+$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -text
+
+# Place the certificate and key in a common file
+$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -issuer -subject \
+	 > $COMBO_DIR/$TEST_CLIENT_FILE.pem
+$CAT $KEYS_DIR/$TEST_CLIENT_FILE.key.pem >> $COMBO_DIR/$TEST_CLIENT_FILE.pem
+
+# Remove the cert request file (no longer needed)
+$RM $CERTS_DIR/$TEST_CLIENT_FILE.req.pem
+
+
+
diff --git a/openssl/demos/ssltest-ecc/README b/openssl/demos/ssltest-ecc/README
new file mode 100644
index 0000000..71c070a
--- /dev/null
+++ b/openssl/demos/ssltest-ecc/README
@@ -0,0 +1,15 @@
+Scripts for using ECC ciphersuites with test/testssl
+(these ciphersuites are described in the Internet Draft available at
+http://www.ietf.org/internet-drafts/draft-ietf-tls-ecc-03.txt).
+
+Use ECCcertgen.sh, RSAcertgen.sh, ECC-RSAcertgen.sh to generate
+root, client and server certs of the following types:
+
+     ECC certs signed with ECDSA
+     RSA certs signed with RSA
+     ECC certs signed with RSA
+
+Afterwards, you can use ssltest.sh to run the various tests;
+specify one of the following options:
+
+     aecdh, ecdh-ecdsa, ecdhe-ecdsa, ecdh-rsa, ecdhe-rsa
diff --git a/openssl/demos/ssltest-ecc/RSAcertgen.sh b/openssl/demos/ssltest-ecc/RSAcertgen.sh
new file mode 100755
index 0000000..0cb0153
--- /dev/null
+++ b/openssl/demos/ssltest-ecc/RSAcertgen.sh
@@ -0,0 +1,121 @@
+#!/bin/sh
+
+# For a list of supported curves, use "apps/openssl ecparam -list_curves".
+
+# Path to the openssl distribution
+OPENSSL_DIR=../..
+# Path to the openssl program
+OPENSSL_CMD=$OPENSSL_DIR/apps/openssl
+# Option to find configuration file
+OPENSSL_CNF="-config $OPENSSL_DIR/apps/openssl.cnf"
+# Directory where certificates are stored
+CERTS_DIR=./Certs
+# Directory where private key files are stored
+KEYS_DIR=$CERTS_DIR
+# Directory where combo files (containing a certificate and corresponding
+# private key together) are stored
+COMBO_DIR=$CERTS_DIR
+# cat command
+CAT=/bin/cat
+# rm command
+RM=/bin/rm
+# mkdir command
+MKDIR=/bin/mkdir
+# The certificate will expire these many days after the issue date.
+DAYS=1500
+TEST_CA_FILE=rsa1024TestCA
+TEST_CA_DN="/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test CA (1024 bit RSA)"
+
+TEST_SERVER_FILE=rsa1024TestServer
+TEST_SERVER_DN="/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test Server (1024 bit RSA)"
+
+TEST_CLIENT_FILE=rsa1024TestClient
+TEST_CLIENT_DN="/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test Client (1024 bit RSA)"
+
+# Generating an EC certificate involves the following main steps
+# 1. Generating curve parameters (if needed)
+# 2. Generating a certificate request
+# 3. Signing the certificate request 
+# 4. [Optional] One can combine the cert and private key into a single
+#    file and also delete the certificate request
+
+$MKDIR -p $CERTS_DIR
+$MKDIR -p $KEYS_DIR
+$MKDIR -p $COMBO_DIR
+
+echo "Generating self-signed CA certificate (RSA)"
+echo "==========================================="
+
+$OPENSSL_CMD req $OPENSSL_CNF -nodes -subj "$TEST_CA_DN" \
+    -keyout $KEYS_DIR/$TEST_CA_FILE.key.pem \
+    -newkey rsa:1024 -new \
+    -out $CERTS_DIR/$TEST_CA_FILE.req.pem
+
+$OPENSSL_CMD x509 -req -days $DAYS \
+    -in $CERTS_DIR/$TEST_CA_FILE.req.pem \
+    -extfile $OPENSSL_DIR/apps/openssl.cnf \
+    -extensions v3_ca \
+    -signkey $KEYS_DIR/$TEST_CA_FILE.key.pem \
+    -out $CERTS_DIR/$TEST_CA_FILE.cert.pem
+
+# Display the certificate
+$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CA_FILE.cert.pem -text
+
+# Place the certificate and key in a common file
+$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CA_FILE.cert.pem -issuer -subject \
+	 > $COMBO_DIR/$TEST_CA_FILE.pem
+$CAT $KEYS_DIR/$TEST_CA_FILE.key.pem >> $COMBO_DIR/$TEST_CA_FILE.pem
+
+# Remove the cert request file (no longer needed)
+$RM $CERTS_DIR/$TEST_CA_FILE.req.pem
+
+echo "GENERATING A TEST SERVER CERTIFICATE (RSA)"
+echo "=========================================="
+
+$OPENSSL_CMD req $OPENSSL_CNF -nodes -subj "$TEST_SERVER_DN" \
+    -keyout $KEYS_DIR/$TEST_SERVER_FILE.key.pem \
+    -newkey rsa:1024 -new \
+    -out $CERTS_DIR/$TEST_SERVER_FILE.req.pem
+
+$OPENSSL_CMD x509 -req -days $DAYS \
+    -in $CERTS_DIR/$TEST_SERVER_FILE.req.pem \
+    -CA $CERTS_DIR/$TEST_CA_FILE.cert.pem \
+    -CAkey $KEYS_DIR/$TEST_CA_FILE.key.pem \
+    -out $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -CAcreateserial
+
+# Display the certificate 
+$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -text
+
+# Place the certificate and key in a common file
+$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -issuer -subject \
+	 > $COMBO_DIR/$TEST_SERVER_FILE.pem
+$CAT $KEYS_DIR/$TEST_SERVER_FILE.key.pem >> $COMBO_DIR/$TEST_SERVER_FILE.pem
+
+# Remove the cert request file (no longer needed)
+$RM $CERTS_DIR/$TEST_SERVER_FILE.req.pem
+
+echo "GENERATING A TEST CLIENT CERTIFICATE (RSA)"
+echo "=========================================="
+
+$OPENSSL_CMD req $OPENSSL_CNF -nodes -subj "$TEST_CLIENT_DN" \
+	     -keyout $KEYS_DIR/$TEST_CLIENT_FILE.key.pem \
+	     -newkey rsa:1024 -new \
+	     -out $CERTS_DIR/$TEST_CLIENT_FILE.req.pem
+
+$OPENSSL_CMD x509 -req -days $DAYS \
+    -in $CERTS_DIR/$TEST_CLIENT_FILE.req.pem \
+    -CA $CERTS_DIR/$TEST_CA_FILE.cert.pem \
+    -CAkey $KEYS_DIR/$TEST_CA_FILE.key.pem \
+    -out $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -CAcreateserial
+
+# Display the certificate 
+$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -text
+
+# Place the certificate and key in a common file
+$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -issuer -subject \
+	 > $COMBO_DIR/$TEST_CLIENT_FILE.pem
+$CAT $KEYS_DIR/$TEST_CLIENT_FILE.key.pem >> $COMBO_DIR/$TEST_CLIENT_FILE.pem
+
+# Remove the cert request file (no longer needed)
+$RM $CERTS_DIR/$TEST_CLIENT_FILE.req.pem
+
diff --git a/openssl/demos/ssltest-ecc/ssltest.sh b/openssl/demos/ssltest-ecc/ssltest.sh
new file mode 100755
index 0000000..923ca43
--- /dev/null
+++ b/openssl/demos/ssltest-ecc/ssltest.sh
@@ -0,0 +1,188 @@
+#! /bin/sh
+# Tests ECC cipher suites using ssltest. Requires one argument which could
+# be aecdh or ecdh-ecdsa or ecdhe-ecdsa or ecdh-rsa or ecdhe-rsa.
+# A second optional argument can be one of ssl2 ssl3 or tls1
+
+if [ "$1" = "" ]; then
+  (echo "Usage: $0 test [ protocol ]"
+   echo "   where test is one of aecdh, ecdh-ecdsa, ecdhe-ecdsa, ecdh-rsa, ecdhe-rsa"
+   echo "   and protocol (optional) is one of ssl2, ssl3, tls1"
+   echo "Run RSAcertgen.sh, ECC-RSAcertgen.sh, ECCcertgen.sh first."
+  ) >&2
+  exit 1
+fi
+
+
+OPENSSL_DIR=../..
+CERTS_DIR=./Certs
+SSLTEST=$OPENSSL_DIR/test/ssltest
+# SSL protocol version to test (one of ssl2 ssl3 or tls1)"
+SSLVERSION=
+
+# These don't really require any certificates
+AECDH_CIPHER_LIST="AECDH-AES256-SHA AECDH-AES128-SHA AECDH-DES-CBC3-SHA AECDH-RC4-SHA AECDH-NULL-SHA"
+
+# These require ECC certificates signed with ECDSA
+# The EC public key must be authorized for key agreement.
+ECDH_ECDSA_CIPHER_LIST="ECDH-ECDSA-AES256-SHA ECDH-ECDSA-AES128-SHA ECDH-ECDSA-DES-CBC3-SHA ECDH-ECDSA-RC4-SHA ECDH-ECDSA-NULL-SHA"
+
+# These require ECC certificates.
+# The EC public key must be authorized for digital signature.
+ECDHE_ECDSA_CIPHER_LIST="ECDHE-ECDSA-AES256-SHA ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-DES-CBC3-SHA ECDHE-ECDSA-RC4-SHA ECDHE-ECDSA-NULL-SHA"
+
+# These require ECC certificates signed with RSA.
+# The EC public key must be authorized for key agreement.
+ECDH_RSA_CIPHER_LIST="ECDH-RSA-AES256-SHA ECDH-RSA-AES128-SHA ECDH-RSA-DES-CBC3-SHA ECDH-RSA-RC4-SHA ECDH-RSA-NULL-SHA"
+
+# These require RSA certificates.
+# The RSA public key must be authorized for digital signature.
+ECDHE_RSA_CIPHER_LIST="ECDHE-RSA-AES256-SHA ECDHE-RSA-AES128-SHA ECDHE-RSA-DES-CBC3-SHA ECDHE-RSA-RC4-SHA ECDHE-RSA-NULL-SHA"
+
+# List of Elliptic curves over which we wish to test generation of
+# ephemeral ECDH keys when using AECDH or ECDHE ciphers
+# NOTE: secp192r1 = prime192v1 and secp256r1 = prime256v1
+#ELLIPTIC_CURVE_LIST="secp112r1 sect113r2 secp128r1 sect131r1 secp160k1 sect163r2 wap-wsg-idm-ecid-wtls7 c2pnb163v3 c2pnb176v3 c2tnb191v3 secp192r1 prime192v3 sect193r2 secp224r1 wap-wsg-idm-ecid-wtls10 sect239k1 prime239v2 secp256r1 prime256v1 sect283k1 secp384r1 sect409r1 secp521r1 sect571r1"
+ELLIPTIC_CURVE_LIST="sect163k1 sect163r1 sect163r2 sect193r1 sect193r2 sect233k1 sect233r1 sect239k1 sect283k1 sect283r1 sect409k1 sect409r1 sect571k1 sect571r1 secp160k1 secp160r1 secp160r2 secp192k1 prime192v1 secp224k1 secp224r1 secp256k1 prime256v1 secp384r1 secp521r1"
+
+DEFAULT_CURVE="sect163r2"
+
+if [ "$2" = "" ]; then
+    if [ "$SSL_VERSION" = "" ]; then
+	SSL_VERSION=""
+    else
+	SSL_VERSION="-$SSL_VERSION"
+    fi
+else
+    SSL_VERSION="-$2"
+fi
+
+#==============================================================
+# Anonymous cipher suites do not require key or certificate files
+# but ssltest expects a cert file and complains if it can't
+# open the default one.
+SERVER_PEM=$OPENSSL_DIR/apps/server.pem
+
+if [ "$1" = "aecdh" ]; then
+for cipher in $AECDH_CIPHER_LIST
+do
+    echo "Testing $cipher"
+    $SSLTEST $SSL_VERSION -cert $SERVER_PEM -cipher $cipher 
+done
+#--------------------------------------------------------------
+for curve in $ELLIPTIC_CURVE_LIST
+do
+    echo "Testing AECDH-NULL-SHA (with $curve)"
+    $SSLTEST $SSL_VERSION -cert $SERVER_PEM \
+	-named_curve $curve -cipher AECDH-NULL-SHA
+done
+
+for curve in $ELLIPTIC_CURVE_LIST
+do
+    echo "Testing AECDH-RC4-SHA (with $curve)"
+    $SSLTEST $SSL_VERSION -cert $SERVER_PEM \
+	-named_curve $curve -cipher AECDH-RC4-SHA
+done
+fi
+
+#==============================================================
+# Both ECDH-ECDSA and ECDHE-ECDSA cipher suites require 
+# the server to have an ECC certificate signed with ECDSA.
+CA_PEM=$CERTS_DIR/secp160r1TestCA.pem
+SERVER_PEM=$CERTS_DIR/secp160r2TestServer.pem
+CLIENT_PEM=$CERTS_DIR/secp160r2TestClient.pem
+
+if [ "$1" = "ecdh-ecdsa" ]; then
+for cipher in $ECDH_ECDSA_CIPHER_LIST
+do
+    echo "Testing $cipher (with server authentication)"
+    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
+	-cert $SERVER_PEM -server_auth \
+	-cipher $cipher
+
+    echo "Testing $cipher (with server and client authentication)"
+    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
+	-cert $SERVER_PEM -server_auth \
+	-c_cert $CLIENT_PEM -client_auth \
+	-cipher $cipher
+done
+fi
+
+#==============================================================
+if [ "$1" = "ecdhe-ecdsa" ]; then
+for cipher in $ECDHE_ECDSA_CIPHER_LIST
+do
+    echo "Testing $cipher (with server authentication)"
+    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
+	-cert $SERVER_PEM -server_auth \
+	-cipher $cipher -named_curve $DEFAULT_CURVE
+
+    echo "Testing $cipher (with server and client authentication)"
+    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
+	-cert $SERVER_PEM -server_auth \
+	-c_cert $CLIENT_PEM -client_auth \
+	-cipher $cipher -named_curve $DEFAULT_CURVE
+done
+
+#--------------------------------------------------------------
+for curve in $ELLIPTIC_CURVE_LIST
+do
+    echo "Testing ECDHE-ECDSA-AES128-SHA (2-way auth with $curve)"
+    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
+	-cert $SERVER_PEM -server_auth \
+	-c_cert $CLIENT_PEM -client_auth \
+	-cipher ECDHE-ECDSA-AES128-SHA -named_curve $curve 
+done
+fi
+
+#==============================================================
+# ECDH-RSA cipher suites require the server to have an ECC
+# certificate signed with RSA.
+CA_PEM=$CERTS_DIR/rsa1024TestCA.pem
+SERVER_PEM=$CERTS_DIR/sect163r1-rsaTestServer.pem
+CLIENT_PEM=$CERTS_DIR/sect163r1-rsaTestClient.pem
+
+if [ "$1" = "ecdh-rsa" ]; then
+for cipher in $ECDH_RSA_CIPHER_LIST
+do
+    echo "Testing $cipher (with server authentication)"
+    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
+	-cert $SERVER_PEM -server_auth \
+	-cipher $cipher
+
+    echo "Testing $cipher (with server and client authentication)"
+    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
+	-cert $SERVER_PEM -server_auth \
+	-c_cert $CLIENT_PEM -client_auth \
+	-cipher $cipher
+done
+fi
+
+#==============================================================
+# ECDHE-RSA cipher suites require the server to have an RSA cert.
+CA_PEM=$CERTS_DIR/rsa1024TestCA.pem
+SERVER_PEM=$CERTS_DIR/rsa1024TestServer.pem
+CLIENT_PEM=$CERTS_DIR/rsa1024TestClient.pem
+
+if [ "$1" = "ecdhe-rsa" ]; then
+for cipher in $ECDHE_RSA_CIPHER_LIST
+do
+    echo "Testing $cipher (with server authentication)"
+    echo $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
+	-cert $SERVER_PEM -server_auth \
+	-cipher $cipher -named_curve $DEFAULT_CURVE
+    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
+	-cert $SERVER_PEM -server_auth \
+	-cipher $cipher -named_curve $DEFAULT_CURVE
+
+    echo "Testing $cipher (with server and client authentication)"
+    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
+	-cert $SERVER_PEM -server_auth \
+	-c_cert $CLIENT_PEM -client_auth \
+	-cipher $cipher -named_curve $DEFAULT_CURVE
+done
+fi
+#==============================================================
+
+
+
+
diff --git a/openssl/demos/state_machine/Makefile b/openssl/demos/state_machine/Makefile
new file mode 100644
index 0000000..c7a1145
--- /dev/null
+++ b/openssl/demos/state_machine/Makefile
@@ -0,0 +1,9 @@
+CFLAGS=-I../../include -Wall -Werror -g
+
+all: state_machine
+
+state_machine: state_machine.o
+	$(CC) -o state_machine state_machine.o -L../.. -lssl -lcrypto
+
+test: state_machine
+	./state_machine 10000 ../../apps/server.pem ../../apps/server.pem
diff --git a/openssl/demos/state_machine/state_machine.c b/openssl/demos/state_machine/state_machine.c
new file mode 100644
index 0000000..fef3f3e
--- /dev/null
+++ b/openssl/demos/state_machine/state_machine.c
@@ -0,0 +1,416 @@
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+ * Nuron, a leader in hardware encryption technology, generously
+ * sponsored the development of this demo by Ben Laurie.
+ *
+ * See http://www.nuron.com/.
+ */
+
+/*
+ * the aim of this demo is to provide a fully working state-machine
+ * style SSL implementation, i.e. one where the main loop acquires
+ * some data, then converts it from or to SSL by feeding it into the
+ * SSL state machine. It then does any I/O required by the state machine
+ * and loops.
+ *
+ * In order to keep things as simple as possible, this implementation
+ * listens on a TCP socket, which it expects to get an SSL connection
+ * on (for example, from s_client) and from then on writes decrypted
+ * data to stdout and encrypts anything arriving on stdin. Verbose
+ * commentary is written to stderr.
+ *
+ * This implementation acts as a server, but it can also be done for a client.  */
+
+#include <openssl/ssl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <string.h>
+#include <openssl/err.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+/* die_unless is intended to work like assert, except that it happens
+   always, even if NDEBUG is defined. Use assert as a stopgap. */
+
+#define die_unless(x)	assert(x)
+
+typedef struct
+    {
+    SSL_CTX *pCtx;
+    BIO *pbioRead;
+    BIO *pbioWrite;
+    SSL *pSSL;
+    } SSLStateMachine;
+
+void SSLStateMachine_print_error(SSLStateMachine *pMachine,const char *szErr)
+    {
+    unsigned long l;
+
+    fprintf(stderr,"%s\n",szErr);
+    while((l=ERR_get_error()))
+	{
+	char buf[1024];
+
+	ERR_error_string_n(l,buf,sizeof buf);
+	fprintf(stderr,"Error %lx: %s\n",l,buf);
+	}
+    }
+
+SSLStateMachine *SSLStateMachine_new(const char *szCertificateFile,
+				     const char *szKeyFile)
+    {
+    SSLStateMachine *pMachine=malloc(sizeof *pMachine);
+    int n;
+
+    die_unless(pMachine);
+
+    pMachine->pCtx=SSL_CTX_new(SSLv23_server_method());
+    die_unless(pMachine->pCtx);
+
+    n=SSL_CTX_use_certificate_file(pMachine->pCtx,szCertificateFile,
+				   SSL_FILETYPE_PEM);
+    die_unless(n > 0);
+
+    n=SSL_CTX_use_PrivateKey_file(pMachine->pCtx,szKeyFile,SSL_FILETYPE_PEM);
+    die_unless(n > 0);
+
+    pMachine->pSSL=SSL_new(pMachine->pCtx);
+    die_unless(pMachine->pSSL);
+
+    pMachine->pbioRead=BIO_new(BIO_s_mem());
+
+    pMachine->pbioWrite=BIO_new(BIO_s_mem());
+
+    SSL_set_bio(pMachine->pSSL,pMachine->pbioRead,pMachine->pbioWrite);
+
+    SSL_set_accept_state(pMachine->pSSL);
+
+    return pMachine;
+    }
+
+void SSLStateMachine_read_inject(SSLStateMachine *pMachine,
+				 const unsigned char *aucBuf,int nBuf)
+    {
+    int n=BIO_write(pMachine->pbioRead,aucBuf,nBuf);
+    /* If it turns out this assert fails, then buffer the data here
+     * and just feed it in in churn instead. Seems to me that it
+     * should be guaranteed to succeed, though.
+     */
+    assert(n == nBuf);
+    fprintf(stderr,"%d bytes of encrypted data fed to state machine\n",n);
+    }
+
+int SSLStateMachine_read_extract(SSLStateMachine *pMachine,
+				 unsigned char *aucBuf,int nBuf)
+    {
+    int n;
+
+    if(!SSL_is_init_finished(pMachine->pSSL))
+	{
+	fprintf(stderr,"Doing SSL_accept\n");
+	n=SSL_accept(pMachine->pSSL);
+	if(n == 0)
+	    fprintf(stderr,"SSL_accept returned zero\n");
+	if(n < 0)
+	    {
+	    int err;
+
+	    if((err=SSL_get_error(pMachine->pSSL,n)) == SSL_ERROR_WANT_READ)
+		{
+		fprintf(stderr,"SSL_accept wants more data\n");
+		return 0;
+		}
+
+	    SSLStateMachine_print_error(pMachine,"SSL_accept error");
+	    exit(7);
+	    }
+	return 0;
+	}
+
+    n=SSL_read(pMachine->pSSL,aucBuf,nBuf);
+    if(n < 0)
+	{
+	int err=SSL_get_error(pMachine->pSSL,n);
+
+	if(err == SSL_ERROR_WANT_READ)
+	    {
+	    fprintf(stderr,"SSL_read wants more data\n");
+	    return 0;
+	    }
+
+	SSLStateMachine_print_error(pMachine,"SSL_read error");
+	exit(8);
+	}
+
+    fprintf(stderr,"%d bytes of decrypted data read from state machine\n",n);
+    return n;
+    }
+
+int SSLStateMachine_write_can_extract(SSLStateMachine *pMachine)
+    {
+    int n=BIO_pending(pMachine->pbioWrite);
+    if(n)
+	fprintf(stderr,"There is encrypted data available to write\n");
+    else
+	fprintf(stderr,"There is no encrypted data available to write\n");
+
+    return n;
+    }
+
+int SSLStateMachine_write_extract(SSLStateMachine *pMachine,
+				  unsigned char *aucBuf,int nBuf)
+    {
+    int n;
+
+    n=BIO_read(pMachine->pbioWrite,aucBuf,nBuf);
+    fprintf(stderr,"%d bytes of encrypted data read from state machine\n",n);
+    return n;
+    }
+
+void SSLStateMachine_write_inject(SSLStateMachine *pMachine,
+				  const unsigned char *aucBuf,int nBuf)
+    {
+    int n=SSL_write(pMachine->pSSL,aucBuf,nBuf);
+    /* If it turns out this assert fails, then buffer the data here
+     * and just feed it in in churn instead. Seems to me that it
+     * should be guaranteed to succeed, though.
+     */
+    assert(n == nBuf);
+    fprintf(stderr,"%d bytes of unencrypted data fed to state machine\n",n);
+    }
+
+int OpenSocket(int nPort)
+    {
+    int nSocket;
+    struct sockaddr_in saServer;
+    struct sockaddr_in saClient;
+    int one=1;
+    int nSize;
+    int nFD;
+    int nLen;
+
+    nSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
+    if(nSocket < 0)
+	{
+	perror("socket");
+	exit(1);
+	}
+
+    if(setsockopt(nSocket,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof one) < 0)
+	{
+	perror("setsockopt");
+        exit(2);
+	}
+
+    memset(&saServer,0,sizeof saServer);
+    saServer.sin_family=AF_INET;
+    saServer.sin_port=htons(nPort);
+    nSize=sizeof saServer;
+    if(bind(nSocket,(struct sockaddr *)&saServer,nSize) < 0)
+	{
+	perror("bind");
+	exit(3);
+	}
+
+    if(listen(nSocket,512) < 0)
+	{
+	perror("listen");
+	exit(4);
+	}
+
+    nLen=sizeof saClient;
+    nFD=accept(nSocket,(struct sockaddr *)&saClient,&nLen);
+    if(nFD < 0)
+	{
+	perror("accept");
+	exit(5);
+	}
+
+    fprintf(stderr,"Incoming accepted on port %d\n",nPort);
+
+    return nFD;
+    }
+
+int main(int argc,char **argv)
+    {
+    SSLStateMachine *pMachine;
+    int nPort;
+    int nFD;
+    const char *szCertificateFile;
+    const char *szKeyFile;
+    char rbuf[1];
+    int nrbuf=0;
+
+    if(argc != 4)
+	{
+	fprintf(stderr,"%s <port> <certificate file> <key file>\n",argv[0]);
+	exit(6);
+	}
+
+    nPort=atoi(argv[1]);
+    szCertificateFile=argv[2];
+    szKeyFile=argv[3];
+
+    SSL_library_init();
+    OpenSSL_add_ssl_algorithms();
+    SSL_load_error_strings();
+    ERR_load_crypto_strings();
+
+    nFD=OpenSocket(nPort);
+
+    pMachine=SSLStateMachine_new(szCertificateFile,szKeyFile);
+
+    for( ; ; )
+	{
+	fd_set rfds,wfds;
+	unsigned char buf[1024];
+	int n;
+
+	FD_ZERO(&rfds);
+	FD_ZERO(&wfds);
+
+	/* Select socket for input */
+	FD_SET(nFD,&rfds);
+
+	/* check whether there's decrypted data */
+	if(!nrbuf)
+	    nrbuf=SSLStateMachine_read_extract(pMachine,rbuf,1);
+
+	/* if there's decrypted data, check whether we can write it */
+	if(nrbuf)
+	    FD_SET(1,&wfds);
+
+	/* Select socket for output */
+	if(SSLStateMachine_write_can_extract(pMachine))
+	    FD_SET(nFD,&wfds);
+
+	/* Select stdin for input */
+	FD_SET(0,&rfds);
+
+	/* Wait for something to do something */
+	n=select(nFD+1,&rfds,&wfds,NULL,NULL);
+	assert(n > 0);
+
+	/* Socket is ready for input */
+	if(FD_ISSET(nFD,&rfds))
+	    {
+	    n=read(nFD,buf,sizeof buf);
+	    if(n == 0)
+		{
+		fprintf(stderr,"Got EOF on socket\n");
+		exit(0);
+		}
+	    assert(n > 0);
+
+	    SSLStateMachine_read_inject(pMachine,buf,n);
+	    }
+
+	/* stdout is ready for output (and hence we have some to send it) */
+	if(FD_ISSET(1,&wfds))
+	    {
+	    assert(nrbuf == 1);
+	    buf[0]=rbuf[0];
+	    nrbuf=0;
+
+	    n=SSLStateMachine_read_extract(pMachine,buf+1,sizeof buf-1);
+	    if(n < 0)
+		{
+		SSLStateMachine_print_error(pMachine,"read extract failed");
+		break;
+		}
+	    assert(n >= 0);
+	    ++n;
+	    if(n > 0) /* FIXME: has to be true now */
+		{
+		int w;
+		
+		w=write(1,buf,n);
+		/* FIXME: we should push back any unwritten data */
+		assert(w == n);
+		}
+	    }
+
+	/* Socket is ready for output (and therefore we have output to send) */
+	if(FD_ISSET(nFD,&wfds))
+	    {
+	    int w;
+
+	    n=SSLStateMachine_write_extract(pMachine,buf,sizeof buf);
+	    assert(n > 0);
+
+	    w=write(nFD,buf,n);
+	    /* FIXME: we should push back any unwritten data */
+	    assert(w == n);
+	    }
+
+	/* Stdin is ready for input */
+	if(FD_ISSET(0,&rfds))
+	    {
+	    n=read(0,buf,sizeof buf);
+	    if(n == 0)
+		{
+		fprintf(stderr,"Got EOF on stdin\n");
+		exit(0);
+		}
+	    assert(n > 0);
+
+	    SSLStateMachine_write_inject(pMachine,buf,n);
+	    }
+	}
+    /* not reached */
+    return 0;
+    }
diff --git a/openssl/demos/tunala/A-client.pem b/openssl/demos/tunala/A-client.pem
new file mode 100644
index 0000000..a4caf6e
--- /dev/null
+++ b/openssl/demos/tunala/A-client.pem
@@ -0,0 +1,84 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 2 (0x2)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: C=NZ, L=Wellington, O=Really Irresponsible Authorisation Authority (RIAA), OU=Cert-stamping, CN=Jackov al-Trades/Email=none@fake.domain
+        Validity
+            Not Before: Jan 16 05:19:30 2002 GMT
+            Not After : Jan 14 05:19:30 2012 GMT
+        Subject: C=NZ, L=Auckland, O=Mordor, OU=SSL grunt things, CN=tunala-client/Email=client@fake.domain
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (1024 bit)
+                Modulus (1024 bit):
+                    00:b0:d3:56:5c:c8:7f:fb:f4:95:9d:04:84:4f:82:
+                    b7:a2:75:5c:81:48:8c:56:5d:52:ee:38:e1:5c:c8:
+                    9a:70:8e:72:f2:00:1c:17:ef:df:b7:06:59:82:04:
+                    f1:f6:49:11:12:a6:4d:cb:1e:ed:ac:59:1c:4a:d0:
+                    3d:de:e6:f2:8d:cd:39:c2:0f:e0:46:2f:db:cb:9f:
+                    47:f7:56:e7:f8:16:5f:68:71:fb:3a:e3:ab:d2:e5:
+                    05:b7:da:65:61:fe:6d:30:e4:12:a8:b5:c1:71:24:
+                    6b:aa:80:05:41:17:a0:8b:6e:8b:e6:04:cf:85:7b:
+                    2a:ac:a1:79:7d:f4:96:6e:77
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                F8:43:CB:4F:4D:4F:BC:6E:52:1A:FD:F9:7B:E1:12:3F:A7:A3:BA:93
+            X509v3 Authority Key Identifier: 
+                keyid:49:FB:45:72:12:C4:CC:E1:45:A1:D3:08:9E:95:C4:2C:6D:55:3F:17
+                DirName:/C=NZ/L=Wellington/O=Really Irresponsible Authorisation Authority (RIAA)/OU=Cert-stamping/CN=Jackov al-Trades/Email=none@fake.domain
+                serial:00
+
+    Signature Algorithm: md5WithRSAEncryption
+        8f:5f:0e:43:da:9d:61:43:7e:03:38:9a:e6:50:9d:42:e8:95:
+        34:49:75:ec:04:8d:5c:85:99:94:70:a0:e7:1f:1e:a0:8b:0f:
+        d6:e2:cb:f7:35:d9:96:72:bd:a6:e9:8d:4e:b1:e2:ac:97:7f:
+        2f:70:01:9d:aa:04:bc:d4:01:2b:63:77:a5:de:63:3c:a8:f5:
+        f2:72:af:ec:11:12:c0:d4:70:cf:71:a6:fb:e9:1d:b3:27:07:
+        aa:f2:b1:f3:87:d6:ab:8b:ce:c2:08:1b:3c:f9:ba:ff:77:71:
+        86:09:ef:9e:4e:04:06:63:44:e9:93:20:90:c7:2d:50:c6:50:
+        f8:66
+-----BEGIN CERTIFICATE-----
+MIID9TCCA16gAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBtDELMAkGA1UEBhMCTlox
+EzARBgNVBAcTCldlbGxpbmd0b24xPDA6BgNVBAoTM1JlYWxseSBJcnJlc3BvbnNp
+YmxlIEF1dGhvcmlzYXRpb24gQXV0aG9yaXR5IChSSUFBKTEWMBQGA1UECxMNQ2Vy
+dC1zdGFtcGluZzEZMBcGA1UEAxMQSmFja292IGFsLVRyYWRlczEfMB0GCSqGSIb3
+DQEJARYQbm9uZUBmYWtlLmRvbWFpbjAeFw0wMjAxMTYwNTE5MzBaFw0xMjAxMTQw
+NTE5MzBaMIGHMQswCQYDVQQGEwJOWjERMA8GA1UEBxMIQXVja2xhbmQxDzANBgNV
+BAoTBk1vcmRvcjEZMBcGA1UECxMQU1NMIGdydW50IHRoaW5nczEWMBQGA1UEAxMN
+dHVuYWxhLWNsaWVudDEhMB8GCSqGSIb3DQEJARYSY2xpZW50QGZha2UuZG9tYWlu
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCw01ZcyH/79JWdBIRPgreidVyB
+SIxWXVLuOOFcyJpwjnLyABwX79+3BlmCBPH2SRESpk3LHu2sWRxK0D3e5vKNzTnC
+D+BGL9vLn0f3Vuf4Fl9ocfs646vS5QW32mVh/m0w5BKotcFxJGuqgAVBF6CLbovm
+BM+FeyqsoXl99JZudwIDAQABo4IBQDCCATwwCQYDVR0TBAIwADAsBglghkgBhvhC
+AQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFPhD
+y09NT7xuUhr9+XvhEj+no7qTMIHhBgNVHSMEgdkwgdaAFEn7RXISxMzhRaHTCJ6V
+xCxtVT8XoYG6pIG3MIG0MQswCQYDVQQGEwJOWjETMBEGA1UEBxMKV2VsbGluZ3Rv
+bjE8MDoGA1UEChMzUmVhbGx5IElycmVzcG9uc2libGUgQXV0aG9yaXNhdGlvbiBB
+dXRob3JpdHkgKFJJQUEpMRYwFAYDVQQLEw1DZXJ0LXN0YW1waW5nMRkwFwYDVQQD
+ExBKYWNrb3YgYWwtVHJhZGVzMR8wHQYJKoZIhvcNAQkBFhBub25lQGZha2UuZG9t
+YWluggEAMA0GCSqGSIb3DQEBBAUAA4GBAI9fDkPanWFDfgM4muZQnULolTRJdewE
+jVyFmZRwoOcfHqCLD9biy/c12ZZyvabpjU6x4qyXfy9wAZ2qBLzUAStjd6XeYzyo
+9fJyr+wREsDUcM9xpvvpHbMnB6rysfOH1quLzsIIGzz5uv93cYYJ755OBAZjROmT
+IJDHLVDGUPhm
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQCw01ZcyH/79JWdBIRPgreidVyBSIxWXVLuOOFcyJpwjnLyABwX
+79+3BlmCBPH2SRESpk3LHu2sWRxK0D3e5vKNzTnCD+BGL9vLn0f3Vuf4Fl9ocfs6
+46vS5QW32mVh/m0w5BKotcFxJGuqgAVBF6CLbovmBM+FeyqsoXl99JZudwIDAQAB
+AoGAU4chbqbPvkclPYzaq2yGLlneHrwUft+KwzlfS6L/QVgo+CQRIUWQmjaHpaGM
+YtjVFcg1S1QK1bUqZjTEZT0XKhfbYmqW8yYTfbcDEbnY7esoYlvIlW8qRlPRlTBE
+utKrtZafmVhLgoNawYGD0aLZofPqpYjbGUlrC7nrem2vNJECQQDVLD3Qb+OlEMET
+73ApnJhYsK3e+G2LTrtjrS8y5zS4+Xv61XUqvdV7ogzRl0tpvSAmMOItVyoYadkB
+S3xSIWX9AkEA1Fm1FhkQSZwGG5rf4c6gMN71jJ6JE3/kocdVa0sUjRevIupo4XQ2
+Vkykxi84MRP8cfHqyjewq7Ozv3op2MGWgwJBAKemsb66IJjzAkaBav7u70nhOf0/
++Dc1Zl7QF2y7NVW8sGrnccx5m+ot2lMD4AV6/kvK6jaqdKrapBZGnbGiHqkCQQDI
+T1r33mqz1R8Z2S2Jtzz6/McKf930a/dC+GLGVEutkILf39lRmytKmv/wB0jtWtoO
+rlJ5sLDSNzC+1cE1u997AkEAu3IrtGmLKiuS6kDj6W47m+iiTIsuSJtTJb1SbUaK
+fIoBNFxbvJYW6rUU9+PxpMRaEhzh5s24/jBOE+mlb17mRQ==
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/demos/tunala/A-server.pem b/openssl/demos/tunala/A-server.pem
new file mode 100644
index 0000000..e9f37b1
--- /dev/null
+++ b/openssl/demos/tunala/A-server.pem
@@ -0,0 +1,84 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1 (0x1)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: C=NZ, L=Wellington, O=Really Irresponsible Authorisation Authority (RIAA), OU=Cert-stamping, CN=Jackov al-Trades/Email=none@fake.domain
+        Validity
+            Not Before: Jan 16 05:14:06 2002 GMT
+            Not After : Jan 14 05:14:06 2012 GMT
+        Subject: C=NZ, L=Wellington, O=Middle Earth, OU=SSL dev things, CN=tunala-server/Email=server@fake.domain
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (1024 bit)
+                Modulus (1024 bit):
+                    00:a9:3e:62:87:97:13:6b:de:8f:bc:1d:0a:3f:65:
+                    0c:f9:76:a3:53:ce:97:30:27:0d:c6:df:72:1f:8d:
+                    5a:ce:58:23:6a:65:e5:e3:72:1a:8d:7f:fe:90:01:
+                    ea:42:f1:9f:6e:7b:0a:bd:eb:52:15:7b:f4:3d:9c:
+                    4e:db:74:29:2b:d1:81:9d:b9:9e:18:2b:87:e1:da:
+                    50:20:3c:59:6c:c9:83:3e:2c:11:0b:78:1e:03:f4:
+                    56:3a:db:95:6a:75:33:85:a9:7b:cc:3c:4a:67:96:
+                    f2:24:b2:a0:cb:2e:cc:52:18:16:6f:44:d9:29:64:
+                    07:2e:fb:56:cc:7c:dc:a2:d7
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                70:AC:7A:B5:6E:97:C2:82:AF:11:9E:32:CB:8D:48:49:93:B7:DC:22
+            X509v3 Authority Key Identifier: 
+                keyid:49:FB:45:72:12:C4:CC:E1:45:A1:D3:08:9E:95:C4:2C:6D:55:3F:17
+                DirName:/C=NZ/L=Wellington/O=Really Irresponsible Authorisation Authority (RIAA)/OU=Cert-stamping/CN=Jackov al-Trades/Email=none@fake.domain
+                serial:00
+
+    Signature Algorithm: md5WithRSAEncryption
+        2e:cb:a3:cd:6d:a8:9d:d1:dc:e5:f0:e0:27:7e:4b:5a:90:a8:
+        85:43:f0:05:f7:04:43:d7:5f:d1:a5:8f:5c:58:eb:fc:da:c6:
+        7c:e0:0b:2b:98:72:95:f6:79:48:96:7a:fa:0c:6b:09:ec:c6:
+        8c:91:74:45:9f:8f:0f:16:78:e3:66:14:fa:1e:f4:f0:23:ec:
+        cd:a9:52:77:20:4d:c5:05:2c:52:b6:7b:f3:42:33:fd:90:1f:
+        3e:88:6f:9b:23:61:c8:80:3b:e6:57:84:2e:f7:26:c7:35:ed:
+        00:8b:08:30:9b:aa:21:83:b6:6d:b8:7c:8a:9b:2a:ef:79:3d:
+        96:31
+-----BEGIN CERTIFICATE-----
+MIID+zCCA2SgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBtDELMAkGA1UEBhMCTlox
+EzARBgNVBAcTCldlbGxpbmd0b24xPDA6BgNVBAoTM1JlYWxseSBJcnJlc3BvbnNp
+YmxlIEF1dGhvcmlzYXRpb24gQXV0aG9yaXR5IChSSUFBKTEWMBQGA1UECxMNQ2Vy
+dC1zdGFtcGluZzEZMBcGA1UEAxMQSmFja292IGFsLVRyYWRlczEfMB0GCSqGSIb3
+DQEJARYQbm9uZUBmYWtlLmRvbWFpbjAeFw0wMjAxMTYwNTE0MDZaFw0xMjAxMTQw
+NTE0MDZaMIGNMQswCQYDVQQGEwJOWjETMBEGA1UEBxMKV2VsbGluZ3RvbjEVMBMG
+A1UEChMMTWlkZGxlIEVhcnRoMRcwFQYDVQQLEw5TU0wgZGV2IHRoaW5nczEWMBQG
+A1UEAxMNdHVuYWxhLXNlcnZlcjEhMB8GCSqGSIb3DQEJARYSc2VydmVyQGZha2Uu
+ZG9tYWluMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpPmKHlxNr3o+8HQo/
+ZQz5dqNTzpcwJw3G33IfjVrOWCNqZeXjchqNf/6QAepC8Z9uewq961IVe/Q9nE7b
+dCkr0YGduZ4YK4fh2lAgPFlsyYM+LBELeB4D9FY625VqdTOFqXvMPEpnlvIksqDL
+LsxSGBZvRNkpZAcu+1bMfNyi1wIDAQABo4IBQDCCATwwCQYDVR0TBAIwADAsBglg
+hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
+BBYEFHCserVul8KCrxGeMsuNSEmTt9wiMIHhBgNVHSMEgdkwgdaAFEn7RXISxMzh
+RaHTCJ6VxCxtVT8XoYG6pIG3MIG0MQswCQYDVQQGEwJOWjETMBEGA1UEBxMKV2Vs
+bGluZ3RvbjE8MDoGA1UEChMzUmVhbGx5IElycmVzcG9uc2libGUgQXV0aG9yaXNh
+dGlvbiBBdXRob3JpdHkgKFJJQUEpMRYwFAYDVQQLEw1DZXJ0LXN0YW1waW5nMRkw
+FwYDVQQDExBKYWNrb3YgYWwtVHJhZGVzMR8wHQYJKoZIhvcNAQkBFhBub25lQGZh
+a2UuZG9tYWluggEAMA0GCSqGSIb3DQEBBAUAA4GBAC7Lo81tqJ3R3OXw4Cd+S1qQ
+qIVD8AX3BEPXX9Glj1xY6/zaxnzgCyuYcpX2eUiWevoMawnsxoyRdEWfjw8WeONm
+FPoe9PAj7M2pUncgTcUFLFK2e/NCM/2QHz6Ib5sjYciAO+ZXhC73Jsc17QCLCDCb
+qiGDtm24fIqbKu95PZYx
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQCpPmKHlxNr3o+8HQo/ZQz5dqNTzpcwJw3G33IfjVrOWCNqZeXj
+chqNf/6QAepC8Z9uewq961IVe/Q9nE7bdCkr0YGduZ4YK4fh2lAgPFlsyYM+LBEL
+eB4D9FY625VqdTOFqXvMPEpnlvIksqDLLsxSGBZvRNkpZAcu+1bMfNyi1wIDAQAB
+AoGANCwqHZhiAU/TyW6+WPqivEhpYw19p/dyFMuPF9DwnEmpaUROUQY8z0AUznn4
+qHhp6Jn/nrprTHowucl0ucweYIYVxZoUiUDFpxdFUbzMdFvo6HcyV1Pe4Rt81HaY
+KYWrTZ6PaPtN65hLms8NhPEdGcGAFlY1owYv4QNGq2bU1JECQQDd32LM0NSfyGmK
+4ziajqGcvzK9NO2XyV/nJsGlJZNgMh2zm1t7yR28l/6Q2uyU49cCN+2aYULZCAfs
+taNvxBspAkEAw0alNub+xj2AVQvaxOB1sGfKzsJjHCzKIxUXn/tJi3j0+2asmkBZ
+Umx1MWr9jKQBnCMciCRUbnMEZiElOxCN/wJAfAeQl6Z19gx206lJzzzEo3dOye54
+k02DSxijT8q9pBzf9bN3ZK987BybtiZr8p+bZiYVsSOF1wViSLURdD1QYQJAIaMU
+qH1n24wShBPTrmAfxbBLTgxL+Dl65Eoo1KT7iSvfv0JzbuqwuDL4iPeuD0DdCiE+
+M/FWHeRwGIuTFzaFzwJBANKwx0jZS/h093w9g0Clw6UzeA1P5VcAt9y+qMC9hO3c
+4KXwIxQAt9yRaFLpiIR9do5bjjKNnMguf3aO/XRSDQM=
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/demos/tunala/CA.pem b/openssl/demos/tunala/CA.pem
new file mode 100644
index 0000000..7a55b54
--- /dev/null
+++ b/openssl/demos/tunala/CA.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID9zCCA2CgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtDELMAkGA1UEBhMCTlox
+EzARBgNVBAcTCldlbGxpbmd0b24xPDA6BgNVBAoTM1JlYWxseSBJcnJlc3BvbnNp
+YmxlIEF1dGhvcmlzYXRpb24gQXV0aG9yaXR5IChSSUFBKTEWMBQGA1UECxMNQ2Vy
+dC1zdGFtcGluZzEZMBcGA1UEAxMQSmFja292IGFsLVRyYWRlczEfMB0GCSqGSIb3
+DQEJARYQbm9uZUBmYWtlLmRvbWFpbjAeFw0wMjAxMTYwNTA5NTlaFw0xMjAxMTQw
+NTA5NTlaMIG0MQswCQYDVQQGEwJOWjETMBEGA1UEBxMKV2VsbGluZ3RvbjE8MDoG
+A1UEChMzUmVhbGx5IElycmVzcG9uc2libGUgQXV0aG9yaXNhdGlvbiBBdXRob3Jp
+dHkgKFJJQUEpMRYwFAYDVQQLEw1DZXJ0LXN0YW1waW5nMRkwFwYDVQQDExBKYWNr
+b3YgYWwtVHJhZGVzMR8wHQYJKoZIhvcNAQkBFhBub25lQGZha2UuZG9tYWluMIGf
+MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7QdDfFIrJn3X24hKmpkyk3TG0Ivxd
+K2wWmDPXq1wjr8lUTwrA6hM5Ba9N36jLieWpXhviLOWu9DBza5GmtgCuXloATKTC
+94xOdKHlciTVujG3wDlLDB5e710Kar84nnj6VueL1RyZ0bmP5PANa4mbGW9Tqc7J
+CkBTTW2y9d0SgQIDAQABo4IBFTCCAREwHQYDVR0OBBYEFEn7RXISxMzhRaHTCJ6V
+xCxtVT8XMIHhBgNVHSMEgdkwgdaAFEn7RXISxMzhRaHTCJ6VxCxtVT8XoYG6pIG3
+MIG0MQswCQYDVQQGEwJOWjETMBEGA1UEBxMKV2VsbGluZ3RvbjE8MDoGA1UEChMz
+UmVhbGx5IElycmVzcG9uc2libGUgQXV0aG9yaXNhdGlvbiBBdXRob3JpdHkgKFJJ
+QUEpMRYwFAYDVQQLEw1DZXJ0LXN0YW1waW5nMRkwFwYDVQQDExBKYWNrb3YgYWwt
+VHJhZGVzMR8wHQYJKoZIhvcNAQkBFhBub25lQGZha2UuZG9tYWluggEAMAwGA1Ud
+EwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAYQo95V/NY+eKxYxkhibZiUQygph+
+gTfgbDG20MsnH6+8//w5ArHauFCgDrf0P2VyACgq+N4pBTWFGaAaLwbjKy9HCe2E
+j9C91tO1CqDS4MJkDB5AP13FTkK6fP1ZCiTQranOAp3DlGWTTWsFVyW5kVfQ9diS
+ZOyJZ9Fit5XM2X0=
+-----END CERTIFICATE-----
diff --git a/openssl/demos/tunala/INSTALL b/openssl/demos/tunala/INSTALL
new file mode 100644
index 0000000..a65bbeb
--- /dev/null
+++ b/openssl/demos/tunala/INSTALL
@@ -0,0 +1,107 @@
+There are two ways to build this code;
+
+(1) Manually
+
+(2) Using all-singing all-dancing (all-confusing) autotools, ie. autoconf,
+automake, and their little friends (autoheader, etc).
+
+=================
+Building Manually
+=================
+
+There is a basic "Makefile" in this directory that gets moved out of the way and
+ignored when building with autoconf et al. This Makefile is suitable for
+building tunala on Linux using gcc. Any other platform probably requires some
+tweaking. Here are the various bits you might need to do if you want to build
+this way and the default Makefile isn't sufficient;
+
+* Compiler: Edit the "CC" definition in Makefile
+
+* Headers, features: tunala.h controls what happens in the non-autoconf world.
+  It, by default, assumes the system has *everything* (except autoconf's
+  "config.h") so if a target system is missing something it must define the
+  appropriate "NO_***" symbols in CFLAGS. These include;
+
+  - NO_HAVE_UNISTD_H, NO_HAVE_FCNTL_H, NO_HAVE_LIMITS_H
+    Indicates the compiling system doesn't have (or need) these header files.
+  - NO_HAVE_STRSTR, NO_HAVE_STRTOUL
+    Indicates the compiling system doesn't have these functions. Replacements
+    are compiled and used in breakage.c
+  - NO_HAVE_SELECT, NO_HAVE_SOCKET
+    Pointless symbols - these indicate select() and/or socket() are missing in
+    which case the program won't compile anyway.
+
+  If you want to specify any of these, add them with "-D" prefixed to each in
+  the CFLAGS definition in Makefile.
+
+* Compilation flags: edit DEBUG_FLAGS and/or CFLAGS directly to control the
+  flags passed to the compiler. This can also be used to change the degree of
+  optimisation.
+
+* Linker flags: some systems (eg. Solaris) require extra linker flags such as;
+  -ldl, -lsocket, -lnsl, etc. If unsure, bring up the man page for whichever
+  function is "undefined" when the linker fails - that usually indicates what
+  you need to add. Make changes to the LINK_FLAGS symbol.
+
+* Linker command: if a different linker syntax or even a different program is
+  required to link, edit the linker line directly in the "tunala:" target
+  definition - it currently assumes the "CC" (compiler) program is used to link.
+
+======================
+Building Automagically
+======================
+
+Automagic building is handled courtesy of autoconf, automake, etc. There are in
+fact two steps required to build, and only the first has to be done on a system
+with these tools installed (and if I was prepared to bloat out the CVS
+repository, I could store these extra files, but I'm not).
+
+First step: "autogunk.sh"
+-------------------------
+
+The "./autogunk.sh" script will call all the necessary autotool commands to
+create missing files and run automake and autoconf. The result is that a
+"./configure" script should be generated and a "Makefile.in" generated from the
+supplied "Makefile.am". NB: This script also moves the "manual" Makefile (see
+above) out of the way and calls it "Makefile.plain" - the "ungunk" script
+reverses this to leave the directory it was previously.
+
+Once "ungunk" has been run, the resulting directory should be able to build on
+other systems without autoconf, automake, or libtool. Which is what the second
+step describes;
+
+Second step: "./configure"
+--------------------------
+
+The second step is to run the generated "./configure" script to create a
+config.h header for your system and to generate a "Makefile" (generated from
+"Makefile.in") tweaked to compile on your system. This is the standard sort of
+thing you see in GNU packages, for example, and the standard tricks also work.
+Eg. to override "configure"'s choice of compiler, set the CC environment
+variable prior to running configure, eg.
+
+    CC=gcc ./configure
+
+would cause "gcc" to be used even if there is an otherwise preferable (to
+autoconf) native compiler on your system.
+
+After this run "make" and it should build the "tunala" executable.
+
+Notes
+-----
+
+- Some versions of autoconf (or automake?) generate a Makefile syntax that gives
+  trouble to some "make" programs on some systems (eg. OpenBSD). If this
+  happens, either build 'Manually' (see above) or use "gmake" instead of "make".
+  I don't like this either but like even less the idea of sifting into all the
+  script magic crud that's involved.
+
+- On a solaris system I tried, the "configure" script specified some broken
+  compiler flags in the resulting Makefile that don't even get echoed to
+  stdout/err when the error happens (evil!). If this happens, go into the
+  generated Makefile, find the two affected targets ("%.o:" and "%.lo"), and
+  remove the offending hidden option in the $(COMPILE) line all the sludge after
+  the two first lines of script (ie. after the "echo" and the "COMPILE" lines).
+  NB: This will probably only function if "--disable-shared" was used, otherwise
+  who knows what would result ...
+
diff --git a/openssl/demos/tunala/Makefile b/openssl/demos/tunala/Makefile
new file mode 100644
index 0000000..bef1704
--- /dev/null
+++ b/openssl/demos/tunala/Makefile
@@ -0,0 +1,41 @@
+# Edit these to suit
+#
+# Oh yeah, and please read the README too.
+
+
+SSL_HOMEDIR=../..
+SSL_INCLUDEDIR=$(SSL_HOMEDIR)/include
+SSL_LIBDIR=$(SSL_HOMEDIR)
+
+RM=rm -f
+CC=gcc
+DEBUG_FLAGS=-g -ggdb3 -Wall -Wshadow
+INCLUDE_FLAGS=-I$(SSL_INCLUDEDIR)
+CFLAGS=$(DEBUG_FLAGS) $(INCLUDE_FLAGS) -DNO_CONFIG_H
+COMPILE=$(CC) $(CFLAGS) -c
+
+# Edit, particularly the "-ldl" if not building with "dlfcn" support
+LINK_FLAGS=-L$(SSL_LIBDIR) -lssl -lcrypto -ldl
+
+SRCS=buffer.c cb.c ip.c sm.c tunala.c breakage.c
+OBJS=buffer.o cb.o ip.o sm.o tunala.o breakage.o
+
+TARGETS=tunala
+
+default: $(TARGETS)
+
+clean:
+	$(RM) $(OBJS) $(TARGETS) *.bak core
+
+.c.o:
+	$(COMPILE) $<
+
+tunala: $(OBJS)
+	$(CC) -o tunala $(OBJS) $(LINK_FLAGS)
+
+# Extra dependencies, should really use makedepend
+buffer.o: buffer.c tunala.h
+cb.o: cb.c tunala.h
+ip.o: ip.c tunala.h
+sm.o: sm.c tunala.h
+tunala.o: tunala.c tunala.h
diff --git a/openssl/demos/tunala/Makefile.am b/openssl/demos/tunala/Makefile.am
new file mode 100644
index 0000000..706c780
--- /dev/null
+++ b/openssl/demos/tunala/Makefile.am
@@ -0,0 +1,7 @@
+# Our includes come from the OpenSSL build-tree we're in
+INCLUDES		= -I$(top_builddir)/../../include
+
+bin_PROGRAMS		= tunala
+
+tunala_SOURCES		= tunala.c buffer.c cb.c ip.c sm.c breakage.c
+tunala_LDADD		= -L$(top_builddir)/../.. -lssl -lcrypto
diff --git a/openssl/demos/tunala/README b/openssl/demos/tunala/README
new file mode 100644
index 0000000..1569008
--- /dev/null
+++ b/openssl/demos/tunala/README
@@ -0,0 +1,233 @@
+This is intended to be an example of a state-machine driven SSL application. It
+acts as an SSL tunneler (functioning as either the server or client half,
+depending on command-line arguments). *PLEASE* read the comments in tunala.h
+before you treat this stuff as anything more than a curiosity - YOU HAVE BEEN
+WARNED!! There, that's the draconian bit out of the way ...
+
+
+Why "tunala"??
+--------------
+
+I thought I asked you to read tunala.h?? :-)
+
+
+Show me
+-------
+
+If you want to simply see it running, skip to the end and see some example
+command-line arguments to demonstrate with.
+
+
+Where to look and what to do?
+-----------------------------
+
+The code is split up roughly coinciding with the detaching of an "abstract" SSL
+state machine (which is the purpose of all this) and its surrounding application
+specifics. This is primarily to make it possible for me to know when I could cut
+corners and when I needed to be rigorous (or at least maintain the pretense as
+such :-).
+
+Network stuff:
+
+Basically, the network part of all this is what is supposed to be abstracted out
+of the way. The intention is to illustrate one way to stick OpenSSL's mechanisms
+inside a little memory-driven sandbox and operate it like a pure state-machine.
+So, the network code is inside both ip.c (general utility functions and gory
+IPv4 details) and tunala.c itself, which takes care of application specifics
+like the main select() loop. The connectivity between the specifics of this
+application (TCP/IP tunneling and the associated network code) and the
+underlying abstract SSL state machine stuff is through the use of the "buffer_t"
+type, declared in tunala.h and implemented in buffer.c.
+
+State machine:
+
+Which leaves us, generally speaking, with the abstract "state machine" code left
+over and this is sitting inside sm.c, with declarations inside tunala.h. As can
+be seen by the definition of the state_machine_t structure and the associated
+functions to manipulate it, there are the 3 OpenSSL "handles" plus 4 buffer_t
+structures dealing with IO on both the encrypted and unencrypted sides ("dirty"
+and "clean" respectively). The "SSL" handle is what facilitates the reading and
+writing of the unencrypted (tunneled) data. The two "BIO" handles act as the
+read and write channels for encrypted tunnel traffic - in other applications
+these are often socket BIOs so that the OpenSSL framework operates with the
+network layer directly. In this example, those two BIOs are memory BIOs
+(BIO_s_mem()) so that the sending and receiving of the tunnel traffic stays
+within the state-machine, and we can handle where this gets send to (or read
+from) ourselves.
+
+
+Why?
+----
+
+If you take a look at the "state_machine_t" section of tunala.h and the code in
+sm.c, you will notice that nothing related to the concept of 'transport' is
+involved. The binding to TCP/IP networking occurs in tunala.c, specifically
+within the "tunala_item_t" structure that associates a state_machine_t object
+with 4 file-descriptors. The way to best see where the bridge between the
+outside world (TCP/IP reads, writes, select()s, file-descriptors, etc) and the
+state machine is, is to examine the "tunala_item_io()" function in tunala.c.
+This is currently around lines 641-732 but of course could be subject to change.
+
+
+And...?
+-------
+
+Well, although that function is around 90 lines of code, it could easily have
+been a lot less only I was trying to address an easily missed "gotcha" (item (2)
+below). The main() code that drives the select/accept/IO loop initialises new
+tunala_item_t structures when connections arrive, and works out which
+file-descriptors go where depending on whether we're an SSL client or server
+(client --> accepted connection is clean and proxied is dirty, server -->
+accepted connection is dirty and proxied is clean). What that tunala_item_io()
+function is attempting to do is 2 things;
+
+  (1) Perform all reads and writes on the network directly into the
+      state_machine_t's buffers (based on a previous select() result), and only
+      then allow the abstact state_machine_t to "churn()" using those buffers.
+      This will cause the SSL machine to consume as much input data from the two
+      "IN" buffers as possible, and generate as much output data into the two
+      "OUT" buffers as possible. Back up in the main() function, the next main
+      loop loop will examine these output buffers and select() for writability
+      on the corresponding sockets if the buffers are non-empty.
+
+  (2) Handle the complicated tunneling-specific issue of cascading "close"s.
+      This is the reason for most of the complexity in the logic - if one side
+      of the tunnel is closed, you can't simply close the other side and throw
+      away the whole thing - (a) there may still be outgoing data on the other
+      side of the tunnel that hasn't been sent yet, (b) the close (or things
+      happening during the close) may cause more data to be generated that needs
+      sending on the other side. Of course, this logic is complicated yet futher
+      by the fact that it's different depending on which side closes first :-)
+      state_machine_close_clean() will indicate to the state machine that the
+      unencrypted side of the tunnel has closed, so any existing outgoing data
+      needs to be flushed, and the SSL stream needs to be closed down using the
+      appropriate shutdown sequence. state_machine_close_dirty() is simpler
+      because it indicates that the SSL stream has been disconnected, so all
+      that remains before closing the other side is to flush out anything that
+      remains and wait for it to all be sent.
+
+Anyway, with those things in mind, the code should be a little easier to follow
+in terms of "what is *this* bit supposed to achieve??!!".
+
+
+How might this help?
+--------------------
+
+Well, the reason I wrote this is that there seemed to be rather a flood of
+questions of late on the openssl-dev and openssl-users lists about getting this
+whole IO logic thing sorted out, particularly by those who were trying to either
+use non-blocking IO, or wanted SSL in an environment where "something else" was
+handling the network already and they needed to operate in memory only. This
+code is loosely based on some other stuff I've been working on, although that
+stuff is far more complete, far more dependant on a whole slew of other
+network/framework code I don't want to incorporate here, and far harder to look
+at for 5 minutes and follow where everything is going. I will be trying over
+time to suck in a few things from that into this demo in the hopes it might be
+more useful, and maybe to even make this demo usable as a utility of its own.
+Possible things include:
+
+  * controlling multiple processes/threads - this can be used to combat
+    latencies and get passed file-descriptor limits on some systems, and it uses
+    a "controller" process/thread that maintains IPC links with the
+    processes/threads doing the real work.
+
+  * cert verification rules - having some say over which certs get in or out :-)
+
+  * control over SSL protocols and cipher suites
+
+  * A few other things you can already do in s_client and s_server :-)
+
+  * Support (and control over) session resuming, particularly when functioning
+    as an SSL client.
+
+If you have a particular environment where this model might work to let you "do
+SSL" without having OpenSSL be aware of the transport, then you should find you
+could use the state_machine_t structure (or your own variant thereof) and hook
+it up to your transport stuff in much the way tunala.c matches it up with those
+4 file-descriptors. The state_machine_churn(), state_machine_close_clean(), and
+state_machine_close_dirty() functions are the main things to understand - after
+that's done, you just have to ensure you're feeding and bleeding the 4
+state_machine buffers in a logical fashion. This state_machine loop handles not
+only handshakes and normal streaming, but also renegotiates - there's no special
+handling required beyond keeping an eye on those 4 buffers and keeping them in
+sync with your outer "loop" logic. Ie. if one of the OUT buffers is not empty,
+you need to find an opportunity to try and forward its data on. If one of the IN
+buffers is not full, you should keep an eye out for data arriving that should be
+placed there.
+
+This approach could hopefully also allow you to run the SSL protocol in very
+different environments. As an example, you could support encrypted event-driven
+IPC where threads/processes pass messages to each other inside an SSL layer;
+each IPC-message's payload would be in fact the "dirty" content, and the "clean"
+payload coming out of the tunnel at each end would be the real intended message.
+Likewise, this could *easily* be made to work across unix domain sockets, or
+even entirely different network/comms protocols.
+
+This is also a quick and easy way to do VPN if you (and the remote network's
+gateway) support virtual network devices that are encapsulted in a single
+network connection, perhaps PPP going through an SSL tunnel?
+
+
+Suggestions
+-----------
+
+Please let me know if you find this useful, or if there's anything wrong or
+simply too confusing about it. Patches are also welcome, but please attach a
+description of what it changes and why, and "diff -urN" format is preferred.
+Mail to geoff@openssl.org should do the trick.
+
+
+Example
+-------
+
+Here is an example of how to use "tunala" ...
+
+First, it's assumed that OpenSSL has already built, and that you are building
+inside the ./demos/tunala/ directory. If not - please correct the paths and
+flags inside the Makefile. Likewise, if you want to tweak the building, it's
+best to try and do so in the makefile (eg. removing the debug flags and adding
+optimisation flags).
+
+Secondly, this code has mostly only been tested on Linux. However, some
+autoconf/etc support has been added and the code has been compiled on openbsd
+and solaris using that.
+
+Thirdly, if you are Win32, you probably need to do some *major* rewriting of
+ip.c to stand a hope in hell. Good luck, and please mail me the diff if you do
+this, otherwise I will take a look at another time. It can certainly be done,
+but it's very non-POSIXy.
+
+See the INSTALL document for details on building.
+
+Now, if you don't have an executable "tunala" compiled, go back to "First,...".
+Rinse and repeat.
+
+Inside one console, try typing;
+
+(i)  ./tunala -listen localhost:8080 -proxy localhost:8081 -cacert CA.pem \
+              -cert A-client.pem -out_totals -v_peer -v_strict
+
+In another console, type;
+
+(ii) ./tunala -listen localhost:8081 -proxy localhost:23 -cacert CA.pem \
+              -cert A-server.pem -server 1 -out_totals -v_peer -v_strict
+
+Now if you open another console and "telnet localhost 8080", you should be
+tunneled through to the telnet service on your local machine (if it's running -
+you could change it to port "22" and tunnel ssh instead if you so desired). When
+you logout of the telnet session, the tunnel should cleanly shutdown and show
+you some traffic stats in both consoles. Feel free to experiment. :-)
+
+Notes:
+
+ - the format for the "-listen" argument can skip the host part (eg. "-listen
+   8080" is fine). If you do, the listening socket will listen on all interfaces
+   so you can connect from other machines for example. Using the "localhost"
+   form listens only on 127.0.0.1 so you can only connect locally (unless, of
+   course, you've set up weird stuff with your networking in which case probably
+   none of the above applies).
+
+ - ./tunala -? gives you a list of other command-line options, but tunala.c is
+   also a good place to look :-)
+
+
diff --git a/openssl/demos/tunala/autogunk.sh b/openssl/demos/tunala/autogunk.sh
new file mode 100755
index 0000000..c9783c6
--- /dev/null
+++ b/openssl/demos/tunala/autogunk.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# This script tries to follow the "GNU way" w.r.t. the autobits.
+# This does of course generate a number of irritating files.
+# Try to get over it (I am getting there myself).
+
+# This should generate any missing crud, and then run autoconf which should turn
+# configure.in into a "./configure" script and "Makefile.am" into a
+# "Makefile.in". Then running "./configure" should turn "Makefile.in" into
+# "Makefile" and should generate the config.h containing your systems various
+# settings. I know ... what a hassle ...
+
+# Also, sometimes these autobits things generate bizarre output (looking like
+# errors). So I direct everything "elsewhere" ...
+
+(aclocal
+autoheader
+libtoolize --copy --force
+automake --foreign --add-missing --copy
+autoconf) 1> /dev/null 2>&1
+
+# Move the "no-autotools" Makefile out of the way
+if test ! -f Makefile.plain; then
+	mv Makefile Makefile.plain
+fi
diff --git a/openssl/demos/tunala/autoungunk.sh b/openssl/demos/tunala/autoungunk.sh
new file mode 100755
index 0000000..2179088
--- /dev/null
+++ b/openssl/demos/tunala/autoungunk.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# This script tries to clean up as much as is possible from whatever diabolical
+# mess has been left in the directory thanks to autoconf, automake, and their
+# friends.
+
+if test -f Makefile.plain; then
+	if test -f Makefile; then
+		make distclean
+	fi
+	mv Makefile.plain Makefile
+else
+	make clean
+fi
+
+rm -f aclocal.m4 config.* configure install-sh \
+	missing mkinstalldirs stamp-h.* Makefile.in \
+	ltconfig ltmain.sh depcomp
+rm -rf autom4te.cache
diff --git a/openssl/demos/tunala/breakage.c b/openssl/demos/tunala/breakage.c
new file mode 100644
index 0000000..dcdd64b
--- /dev/null
+++ b/openssl/demos/tunala/breakage.c
@@ -0,0 +1,66 @@
+#include "tunala.h"
+
+int int_strtoul(const char *str, unsigned long *val)
+{
+#ifdef HAVE_STRTOUL
+	char *tmp;
+	unsigned long ret = strtoul(str, &tmp, 10);
+	if((str == tmp) || (*tmp != '\0'))
+		/* The value didn't parse cleanly */
+		return 0;
+	if(ret == ULONG_MAX)
+		/* We hit a limit */
+		return 0;
+	*val = ret;
+	return 1;
+#else
+	char buf[2];
+	unsigned long ret = 0;
+	buf[1] = '\0';
+	if(str == '\0')
+		/* An empty string ... */
+		return 0;
+	while(*str != '\0') {
+		/* We have to multiply 'ret' by 10 before absorbing the next
+		 * digit. If this will overflow, catch it now. */
+		if(ret && (((ULONG_MAX + 10) / ret) < 10))
+			return 0;
+		ret *= 10;
+		if(!isdigit(*str))
+			return 0;
+		buf[0] = *str;
+		ret += atoi(buf);
+		str++;
+	}
+	*val = ret;
+	return 1;
+#endif
+}
+
+#ifndef HAVE_STRSTR
+char *int_strstr(const char *haystack, const char *needle)
+{
+	const char *sub_haystack = haystack, *sub_needle = needle;
+	unsigned int offset = 0;
+	if(!needle)
+		return haystack;
+	if(!haystack)
+		return NULL;
+	while((*sub_haystack != '\0') && (*sub_needle != '\0')) {
+		if(sub_haystack[offset] == sub_needle) {
+			/* sub_haystack is still a candidate */
+			offset++;
+			sub_needle++;
+		} else {
+			/* sub_haystack is no longer a possibility */
+			sub_haystack++;
+			offset = 0;
+			sub_needle = needle;
+		}
+	}
+	if(*sub_haystack == '\0')
+		/* Found nothing */
+		return NULL;
+	return sub_haystack;
+}
+#endif
diff --git a/openssl/demos/tunala/buffer.c b/openssl/demos/tunala/buffer.c
new file mode 100644
index 0000000..c5cd004
--- /dev/null
+++ b/openssl/demos/tunala/buffer.c
@@ -0,0 +1,205 @@
+#include "tunala.h"
+
+#ifndef NO_BUFFER
+
+void buffer_init(buffer_t *buf)
+{
+	buf->used = 0;
+	buf->total_in = buf->total_out = 0;
+}
+
+void buffer_close(buffer_t *buf)
+{
+	/* Our data is static - nothing needs "release", just reset it */
+	buf->used = 0;
+}
+
+/* Code these simple ones in compact form */
+unsigned int buffer_used(buffer_t *buf) {
+	return buf->used; }
+unsigned int buffer_unused(buffer_t *buf) {
+	return (MAX_DATA_SIZE - buf->used); }
+int buffer_full(buffer_t *buf) {
+	return (buf->used == MAX_DATA_SIZE ? 1 : 0); }
+int buffer_notfull(buffer_t *buf) {
+	return (buf->used < MAX_DATA_SIZE ? 1 : 0); }
+int buffer_empty(buffer_t *buf) {
+	return (buf->used == 0 ? 1 : 0); }
+int buffer_notempty(buffer_t *buf) {
+	return (buf->used > 0 ? 1 : 0); }
+unsigned long buffer_total_in(buffer_t *buf) {
+	return buf->total_in; }
+unsigned long buffer_total_out(buffer_t *buf) {
+	return buf->total_out; }
+
+/* These 3 static (internal) functions don't adjust the "total" variables as
+ * it's not sure when they're called how it should be interpreted. Only the
+ * higher-level "buffer_[to|from]_[fd|SSL|BIO]" functions should alter these
+ * values. */
+#if 0 /* To avoid "unused" warnings */
+static unsigned int buffer_adddata(buffer_t *buf, const unsigned char *ptr,
+		unsigned int size)
+{
+	unsigned int added = MAX_DATA_SIZE - buf->used;
+	if(added > size)
+		added = size;
+	if(added == 0)
+		return 0;
+	memcpy(buf->data + buf->used, ptr, added);
+	buf->used += added;
+	buf->total_in += added;
+	return added;
+}
+
+static unsigned int buffer_tobuffer(buffer_t *to, buffer_t *from, int cap)
+{
+	unsigned int moved, tomove = from->used;
+	if((int)tomove > cap)
+		tomove = cap;
+	if(tomove == 0)
+		return 0;
+	moved = buffer_adddata(to, from->data, tomove);
+	if(moved == 0)
+		return 0;
+	buffer_takedata(from, NULL, moved);
+	return moved;
+}
+#endif
+
+static unsigned int buffer_takedata(buffer_t *buf, unsigned char *ptr,
+		unsigned int size)
+{
+	unsigned int taken = buf->used;
+	if(taken > size)
+		taken = size;
+	if(taken == 0)
+		return 0;
+	if(ptr)
+		memcpy(ptr, buf->data, taken);
+	buf->used -= taken;
+	/* Do we have to scroll? */
+	if(buf->used > 0)
+		memmove(buf->data, buf->data + taken, buf->used);
+	return taken;
+}
+
+#ifndef NO_IP
+
+int buffer_from_fd(buffer_t *buf, int fd)
+{
+	int toread = buffer_unused(buf);
+	if(toread == 0)
+		/* Shouldn't be called in this case! */
+		abort();
+	toread = read(fd, buf->data + buf->used, toread);
+	if(toread > 0) {
+		buf->used += toread;
+		buf->total_in += toread;
+	}
+	return toread;
+}
+
+int buffer_to_fd(buffer_t *buf, int fd)
+{
+	int towrite = buffer_used(buf);
+	if(towrite == 0)
+		/* Shouldn't be called in this case! */
+		abort();
+	towrite = write(fd, buf->data, towrite);
+	if(towrite > 0) {
+		buffer_takedata(buf, NULL, towrite);
+		buf->total_out += towrite;
+	}
+	return towrite;
+}
+
+#endif /* !defined(NO_IP) */
+
+#ifndef NO_OPENSSL
+
+static void int_ssl_check(SSL *s, int ret)
+{
+	int e = SSL_get_error(s, ret);
+	switch(e) {
+		/* These seem to be harmless and already "dealt with" by our
+		 * non-blocking environment. NB: "ZERO_RETURN" is the clean
+		 * "error" indicating a successfully closed SSL tunnel. We let
+		 * this happen because our IO loop should not appear to have
+		 * broken on this condition - and outside the IO loop, the
+		 * "shutdown" state is checked. */
+	case SSL_ERROR_NONE:
+	case SSL_ERROR_WANT_READ:
+	case SSL_ERROR_WANT_WRITE:
+	case SSL_ERROR_WANT_X509_LOOKUP:
+	case SSL_ERROR_ZERO_RETURN:
+		return;
+		/* These seem to be indications of a genuine error that should
+		 * result in the SSL tunnel being regarded as "dead". */
+	case SSL_ERROR_SYSCALL:
+	case SSL_ERROR_SSL:
+		SSL_set_app_data(s, (char *)1);
+		return;
+	default:
+		break;
+	}
+	/* For any other errors that (a) exist, and (b) crop up - we need to
+	 * interpret what to do with them - so "politely inform" the caller that
+	 * the code needs updating here. */
+	abort();
+}
+
+void buffer_from_SSL(buffer_t *buf, SSL *ssl)
+{
+	int ret;
+	if(!ssl || buffer_full(buf))
+		return;
+	ret = SSL_read(ssl, buf->data + buf->used, buffer_unused(buf));
+	if(ret > 0) {
+		buf->used += ret;
+		buf->total_in += ret;
+	}
+	if(ret < 0)
+		int_ssl_check(ssl, ret);
+}
+
+void buffer_to_SSL(buffer_t *buf, SSL *ssl)
+{
+	int ret;
+	if(!ssl || buffer_empty(buf))
+		return;
+	ret = SSL_write(ssl, buf->data, buf->used);
+	if(ret > 0) {
+		buffer_takedata(buf, NULL, ret);
+		buf->total_out += ret;
+	}
+	if(ret < 0)
+		int_ssl_check(ssl, ret);
+}
+
+void buffer_from_BIO(buffer_t *buf, BIO *bio)
+{
+	int ret;
+	if(!bio || buffer_full(buf))
+		return;
+	ret = BIO_read(bio, buf->data + buf->used, buffer_unused(buf));
+	if(ret > 0) {
+		buf->used += ret;
+		buf->total_in += ret;
+	}
+}
+
+void buffer_to_BIO(buffer_t *buf, BIO *bio)
+{
+	int ret;
+	if(!bio || buffer_empty(buf))
+		return;
+	ret = BIO_write(bio, buf->data, buf->used);
+	if(ret > 0) {
+		buffer_takedata(buf, NULL, ret);
+		buf->total_out += ret;
+	}
+}
+
+#endif /* !defined(NO_OPENSSL) */
+
+#endif /* !defined(NO_BUFFER) */
diff --git a/openssl/demos/tunala/cb.c b/openssl/demos/tunala/cb.c
new file mode 100644
index 0000000..f6e452a
--- /dev/null
+++ b/openssl/demos/tunala/cb.c
@@ -0,0 +1,162 @@
+#include "tunala.h"
+
+#ifndef NO_OPENSSL
+
+/* For callbacks generating output, here are their file-descriptors. */
+static FILE *fp_cb_ssl_info = NULL;
+static FILE *fp_cb_ssl_verify = NULL;
+/* Output level:
+ *     0 = nothing,
+ *     1 = minimal, just errors,
+ *     2 = minimal, all steps,
+ *     3 = detail, all steps */
+static unsigned int cb_ssl_verify_level = 1;
+
+/* Other static rubbish (to mirror s_cb.c where required) */
+static int int_verify_depth = 10;
+
+/* This function is largely borrowed from the one used in OpenSSL's "s_client"
+ * and "s_server" utilities. */
+void cb_ssl_info(const SSL *s, int where, int ret)
+{
+	const char *str1, *str2;
+	int w;
+
+	if(!fp_cb_ssl_info)
+		return;
+
+	w = where & ~SSL_ST_MASK;
+	str1 = (w & SSL_ST_CONNECT ? "SSL_connect" : (w & SSL_ST_ACCEPT ?
+				"SSL_accept" : "undefined")),
+	str2 = SSL_state_string_long(s);
+
+	if (where & SSL_CB_LOOP)
+		fprintf(fp_cb_ssl_info, "(%s) %s\n", str1, str2);
+	else if (where & SSL_CB_EXIT) {
+		if (ret == 0)
+			fprintf(fp_cb_ssl_info, "(%s) failed in %s\n", str1, str2);
+/* In a non-blocking model, we get a few of these "error"s simply because we're
+ * calling "reads" and "writes" on the state-machine that are virtual NOPs
+ * simply to avoid wasting the time seeing if we *should* call them. Removing
+ * this case makes the "-out_state" output a lot easier on the eye. */
+#if 0
+		else if (ret < 0)
+			fprintf(fp_cb_ssl_info, "%s:error in %s\n", str1, str2);
+#endif
+	}
+}
+
+void cb_ssl_info_set_output(FILE *fp)
+{
+	fp_cb_ssl_info = fp;
+}
+
+static const char *int_reason_no_issuer = "X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT";
+static const char *int_reason_not_yet = "X509_V_ERR_CERT_NOT_YET_VALID";
+static const char *int_reason_before = "X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD";
+static const char *int_reason_expired = "X509_V_ERR_CERT_HAS_EXPIRED";
+static const char *int_reason_after = "X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD";
+
+/* Stolen wholesale from apps/s_cb.c :-) And since then, mutilated ... */
+int cb_ssl_verify(int ok, X509_STORE_CTX *ctx)
+{
+	char buf1[256]; /* Used for the subject name */
+	char buf2[256]; /* Used for the issuer name */
+	const char *reason = NULL; /* Error reason (if any) */
+	X509 *err_cert;
+	int err, depth;
+
+	if(!fp_cb_ssl_verify || (cb_ssl_verify_level == 0))
+		return ok;
+	err_cert = X509_STORE_CTX_get_current_cert(ctx);
+	err = X509_STORE_CTX_get_error(ctx);
+	depth = X509_STORE_CTX_get_error_depth(ctx);
+
+	buf1[0] = buf2[0] = '\0';
+	/* Fill buf1 */
+	X509_NAME_oneline(X509_get_subject_name(err_cert), buf1, 256);
+	/* Fill buf2 */
+	X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf2, 256);
+	switch (ctx->error) {
+	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+		reason = int_reason_no_issuer;
+		break;
+	case X509_V_ERR_CERT_NOT_YET_VALID:
+		reason = int_reason_not_yet;
+		break;
+	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+		reason = int_reason_before;
+		break;
+	case X509_V_ERR_CERT_HAS_EXPIRED:
+		reason = int_reason_expired;
+		break;
+	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+		reason = int_reason_after;
+		break;
+	}
+
+	if((cb_ssl_verify_level == 1) && ok)
+		return ok;
+	fprintf(fp_cb_ssl_verify, "chain-depth=%d, ", depth);
+	if(reason)
+		fprintf(fp_cb_ssl_verify, "error=%s\n", reason);
+	else
+		fprintf(fp_cb_ssl_verify, "error=%d\n", err);
+	if(cb_ssl_verify_level < 3)
+		return ok;
+	fprintf(fp_cb_ssl_verify, "--> subject = %s\n", buf1);
+	fprintf(fp_cb_ssl_verify, "--> issuer  = %s\n", buf2);
+	if(!ok)
+		fprintf(fp_cb_ssl_verify,"--> verify error:num=%d:%s\n",err,
+			X509_verify_cert_error_string(err));
+	fprintf(fp_cb_ssl_verify, "--> verify return:%d\n",ok);
+	return ok;
+}
+
+void cb_ssl_verify_set_output(FILE *fp)
+{
+	fp_cb_ssl_verify = fp;
+}
+
+void cb_ssl_verify_set_depth(unsigned int verify_depth)
+{
+	int_verify_depth = verify_depth;
+}
+
+void cb_ssl_verify_set_level(unsigned int level)
+{
+	if(level < 4)
+		cb_ssl_verify_level = level;
+}
+
+RSA *cb_generate_tmp_rsa(SSL *s, int is_export, int keylength)
+{
+	/* TODO: Perhaps make it so our global key can be generated on-the-fly
+	 * after certain intervals? */
+	static RSA *rsa_tmp = NULL;
+	BIGNUM *bn = NULL;
+	int ok = 1;
+	if(!rsa_tmp) {
+		ok = 0;
+		if(!(bn = BN_new()))
+			goto end;
+		if(!BN_set_word(bn, RSA_F4))
+			goto end;
+		if(!(rsa_tmp = RSA_new()))
+			goto end;
+		if(!RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL))
+			goto end;
+		ok = 1;
+	}
+end:
+	if(bn)
+		BN_free(bn);
+	if(!ok) {
+		RSA_free(rsa_tmp);
+		rsa_tmp = NULL;
+	}
+	return rsa_tmp;
+}
+
+#endif /* !defined(NO_OPENSSL) */
+
diff --git a/openssl/demos/tunala/configure.in b/openssl/demos/tunala/configure.in
new file mode 100644
index 0000000..590cdbf
--- /dev/null
+++ b/openssl/demos/tunala/configure.in
@@ -0,0 +1,29 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(tunala.c)
+AM_CONFIG_HEADER(config.h)
+AM_INIT_AUTOMAKE(tunala, 0.0.1-dev)
+
+dnl Checks for programs. (Though skip libtool)
+AC_PROG_CC
+dnl AC_PROG_LIBTOOL
+dnl AM_PROG_LIBTOOL
+
+dnl Checks for libraries.
+AC_CHECK_LIB(dl, dlopen)
+AC_CHECK_LIB(z, inflate)
+AC_CHECK_LIB(socket, socket)
+AC_CHECK_LIB(nsl, gethostbyname)
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS(fcntl.h limits.h unistd.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+
+dnl Checks for library functions.
+AC_CHECK_FUNCS(strstr strtoul)
+AC_CHECK_FUNCS(select socket)
+AC_CHECK_FUNCS(dlopen)
+
+AC_OUTPUT(Makefile)
diff --git a/openssl/demos/tunala/ip.c b/openssl/demos/tunala/ip.c
new file mode 100644
index 0000000..96ef4e6
--- /dev/null
+++ b/openssl/demos/tunala/ip.c
@@ -0,0 +1,146 @@
+#include "tunala.h"
+
+#ifndef NO_IP
+
+#define IP_LISTENER_BACKLOG 511 /* So if it gets masked by 256 or some other
+				   such value it'll still be respectable */
+
+/* Any IP-related initialisations. For now, this means blocking SIGPIPE */
+int ip_initialise(void)
+{
+	struct sigaction sa;
+
+	sa.sa_handler = SIG_IGN;
+	sa.sa_flags = 0;
+	sigemptyset(&sa.sa_mask);
+	if(sigaction(SIGPIPE, &sa, NULL) != 0)
+		return 0;
+	return 1;
+}
+
+int ip_create_listener_split(const char *ip, unsigned short port)
+{
+	struct sockaddr_in in_addr;
+	int fd = -1;
+	int reuseVal = 1;
+
+	/* Create the socket */
+	if((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
+		goto err;
+	/* Set the SO_REUSEADDR flag - servers act weird without it */
+	if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)(&reuseVal),
+				sizeof(reuseVal)) != 0)
+		goto err;
+	/* Prepare the listen address stuff */
+	in_addr.sin_family = AF_INET;
+	memcpy(&in_addr.sin_addr.s_addr, ip, 4);
+	in_addr.sin_port = htons(port);
+	/* Bind to the required port/address/interface */
+	if(bind(fd, (struct sockaddr *)&in_addr, sizeof(struct sockaddr_in)) != 0)
+		goto err;
+	/* Start "listening" */
+	if(listen(fd, IP_LISTENER_BACKLOG) != 0)
+		goto err;
+	return fd;
+err:
+	if(fd != -1)
+		close(fd);
+	return -1;
+}
+
+int ip_create_connection_split(const char *ip, unsigned short port)
+{
+	struct sockaddr_in in_addr;
+	int flags, fd = -1;
+
+	/* Create the socket */
+	if((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
+		goto err;
+	/* Make it non-blocking */
+	if(((flags = fcntl(fd, F_GETFL, 0)) < 0) ||
+			(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0))
+		goto err;
+	/* Prepare the connection address stuff */
+	in_addr.sin_family = AF_INET;
+	memcpy(&in_addr.sin_addr.s_addr, ip, 4);
+	in_addr.sin_port = htons(port);
+	/* Start a connect (non-blocking, in all likelihood) */
+	if((connect(fd, (struct sockaddr *)&in_addr,
+			sizeof(struct sockaddr_in)) != 0) &&
+			(errno != EINPROGRESS))
+		goto err;
+	return fd;
+err:
+	if(fd != -1)
+		close(fd);
+	return -1;
+}
+
+static char all_local_ip[] = {0x00,0x00,0x00,0x00};
+
+int ip_parse_address(const char *address, const char **parsed_ip,
+		unsigned short *parsed_port, int accept_all_ip)
+{
+	char buf[256];
+	struct hostent *lookup;
+	unsigned long port;
+	const char *ptr = strstr(address, ":");
+	const char *ip = all_local_ip;
+
+	if(!ptr) {
+		/* We assume we're listening on all local interfaces and have
+		 * only specified a port. */
+		if(!accept_all_ip)
+			return 0;
+		ptr = address;
+		goto determine_port;
+	}
+	if((ptr - address) > 255)
+		return 0;
+	memset(buf, 0, 256);
+	memcpy(buf, address, ptr - address);
+	ptr++;
+	if((lookup = gethostbyname(buf)) == NULL) {
+		/* Spit a message to differentiate between lookup failures and
+		 * bad strings. */
+		fprintf(stderr, "hostname lookup for '%s' failed\n", buf);
+		return 0;
+	}
+	ip = lookup->h_addr_list[0];
+determine_port:
+	if(strlen(ptr) < 1)
+		return 0;
+	if(!int_strtoul(ptr, &port) || (port > 65535))
+		return 0;
+	*parsed_ip = ip;
+	*parsed_port = (unsigned short)port;
+	return 1;
+}
+
+int ip_create_listener(const char *address)
+{
+	const char *ip;
+	unsigned short port;
+
+	if(!ip_parse_address(address, &ip, &port, 1))
+		return -1;
+	return ip_create_listener_split(ip, port);
+}
+
+int ip_create_connection(const char *address)
+{
+	const char *ip;
+	unsigned short port;
+
+	if(!ip_parse_address(address, &ip, &port, 0))
+		return -1;
+	return ip_create_connection_split(ip, port);
+}
+
+int ip_accept_connection(int listen_fd)
+{
+	return accept(listen_fd, NULL, NULL);
+}
+
+#endif /* !defined(NO_IP) */
+
diff --git a/openssl/demos/tunala/sm.c b/openssl/demos/tunala/sm.c
new file mode 100644
index 0000000..25359e6
--- /dev/null
+++ b/openssl/demos/tunala/sm.c
@@ -0,0 +1,151 @@
+#include "tunala.h"
+
+#ifndef NO_TUNALA
+
+void state_machine_init(state_machine_t *machine)
+{
+	machine->ssl = NULL;
+	machine->bio_intossl = machine->bio_fromssl = NULL;
+	buffer_init(&machine->clean_in);
+	buffer_init(&machine->clean_out);
+	buffer_init(&machine->dirty_in);
+	buffer_init(&machine->dirty_out);
+}
+
+void state_machine_close(state_machine_t *machine)
+{
+	if(machine->ssl)
+		SSL_free(machine->ssl);
+/* SSL_free seems to decrement the reference counts already so doing this goes
+ * kaboom. */
+#if 0
+	if(machine->bio_intossl)
+		BIO_free(machine->bio_intossl);
+	if(machine->bio_fromssl)
+		BIO_free(machine->bio_fromssl);
+#endif
+	buffer_close(&machine->clean_in);
+	buffer_close(&machine->clean_out);
+	buffer_close(&machine->dirty_in);
+	buffer_close(&machine->dirty_out);
+	state_machine_init(machine);
+}
+
+buffer_t *state_machine_get_buffer(state_machine_t *machine, sm_buffer_t type)
+{
+	switch(type) {
+	case SM_CLEAN_IN:
+		return &machine->clean_in;
+	case SM_CLEAN_OUT:
+		return &machine->clean_out;
+	case SM_DIRTY_IN:
+		return &machine->dirty_in;
+	case SM_DIRTY_OUT:
+		return &machine->dirty_out;
+	default:
+		break;
+	}
+	/* Should never get here */
+	abort();
+	return NULL;
+}
+
+SSL *state_machine_get_SSL(state_machine_t *machine)
+{
+	return machine->ssl;
+}
+
+int state_machine_set_SSL(state_machine_t *machine, SSL *ssl, int is_server)
+{
+	if(machine->ssl)
+		/* Shouldn't ever be set twice */
+		abort();
+	machine->ssl = ssl;
+	/* Create the BIOs to handle the dirty side of the SSL */
+	if((machine->bio_intossl = BIO_new(BIO_s_mem())) == NULL)
+		abort();
+	if((machine->bio_fromssl = BIO_new(BIO_s_mem())) == NULL)
+		abort();
+	/* Hook up the BIOs on the dirty side of the SSL */
+	SSL_set_bio(machine->ssl, machine->bio_intossl, machine->bio_fromssl);
+	if(is_server)
+		SSL_set_accept_state(machine->ssl);
+	else
+		SSL_set_connect_state(machine->ssl);
+	/* If we're the first one to generate traffic - do it now otherwise we
+	 * go into the next select empty-handed and our peer will not send data
+	 * but will similarly wait for us. */
+	return state_machine_churn(machine);
+}
+
+/* Performs the data-IO loop and returns zero if the machine should close */
+int state_machine_churn(state_machine_t *machine)
+{
+	unsigned int loop;
+	if(machine->ssl == NULL) {
+		if(buffer_empty(&machine->clean_out))
+			/* Time to close this state-machine altogether */
+			return 0;
+		else
+			/* Still buffered data on the clean side to go out */
+			return 1;
+	}
+	/* Do this loop twice to cover any dependencies about which precise
+	 * order of reads and writes is required. */
+	for(loop = 0; loop < 2; loop++) {
+		buffer_to_SSL(&machine->clean_in, machine->ssl);
+		buffer_to_BIO(&machine->dirty_in, machine->bio_intossl);
+		buffer_from_SSL(&machine->clean_out, machine->ssl);
+		buffer_from_BIO(&machine->dirty_out, machine->bio_fromssl);
+	}
+	/* We close on the SSL side if the info callback noticed some problems
+	 * or an SSL shutdown was underway and shutdown traffic had all been
+	 * sent. */
+	if(SSL_get_app_data(machine->ssl) || (SSL_get_shutdown(machine->ssl) &&
+				buffer_empty(&machine->dirty_out))) {
+		/* Great, we can seal off the dirty side completely */
+		if(!state_machine_close_dirty(machine))
+			return 0;
+	}
+	/* Either the SSL is alive and well, or the closing process still has
+	 * outgoing data waiting to be sent */
+	return 1;
+}
+
+/* Called when the clean side of the SSL has lost its connection */
+int state_machine_close_clean(state_machine_t *machine)
+{
+	/* Well, first thing to do is null out the clean-side buffers - they're
+	 * no use any more. */
+	buffer_close(&machine->clean_in);
+	buffer_close(&machine->clean_out);
+	/* And start an SSL shutdown */
+	if(machine->ssl)
+		SSL_shutdown(machine->ssl);
+	/* This is an "event", so flush the SSL of any generated traffic */
+	state_machine_churn(machine);
+	if(buffer_empty(&machine->dirty_in) &&
+			buffer_empty(&machine->dirty_out))
+		return 0;
+	return 1;
+}
+
+/* Called when the dirty side of the SSL has lost its connection. This is pretty
+ * terminal as all that can be left to do is send any buffered output on the
+ * clean side - after that, we're done. */
+int state_machine_close_dirty(state_machine_t *machine)
+{
+	buffer_close(&machine->dirty_in);
+	buffer_close(&machine->dirty_out);
+	buffer_close(&machine->clean_in);
+	if(machine->ssl)
+		SSL_free(machine->ssl);
+	machine->ssl = NULL;
+	machine->bio_intossl = machine->bio_fromssl = NULL;
+	if(buffer_empty(&machine->clean_out))
+		return 0;
+	return 1;
+}
+
+#endif /* !defined(NO_TUNALA) */
+
diff --git a/openssl/demos/tunala/test.sh b/openssl/demos/tunala/test.sh
new file mode 100755
index 0000000..105b447
--- /dev/null
+++ b/openssl/demos/tunala/test.sh
@@ -0,0 +1,107 @@
+#!/bin/sh
+
+HTTP="localhost:8080"
+CLIENT_PORT="9020"
+SERVER_PORT="9021"
+
+sub_test ()
+{
+	echo "STARTING - $VER $CIPHER"
+	./tunala -listen localhost:$CLIENT_PORT -proxy localhost:$SERVER_PORT \
+		-cacert CA.pem -cert A-client.pem -server 0 \
+		-dh_special standard -v_peer -v_strict \
+		$VER -cipher $CIPHER 1> tc1.txt 2> tc2.txt &
+	./tunala -listen localhost:$SERVER_PORT -proxy $HTTP \
+		-cacert CA.pem -cert A-server.pem -server 1 \
+		-dh_special standard -v_peer -v_strict \
+		$VER -cipher $CIPHER 1> ts1.txt 2> ts2.txt &
+	# Wait for the servers to be listening before starting the wget test
+	DONE="no"
+	while [ "$DONE" != "yes" ]; do
+		L1=`netstat -a | egrep "LISTEN[\t ]*$" | grep ":$CLIENT_PORT"`
+		L2=`netstat -a | egrep "LISTEN[\t ]*$" | grep ":$SERVER_PORT"`
+		if [ "x$L1" != "x" ]; then
+			DONE="yes"
+		elif [ "x$L2" != "x" ]; then
+			DONE="yes"
+		else
+			sleep 1
+		fi
+	done
+	HTML=`wget -O - -T 1 http://localhost:$CLIENT_PORT 2> /dev/null | grep "<HTML>"`
+	if [ "x$HTML" != "x" ]; then
+		echo "OK - $CIPHER ($VER)"
+	else
+		echo "FAIL - $CIPHER ($VER)"
+		killall tunala
+		exit 1
+	fi
+	killall tunala
+	# Wait for the servers to stop before returning - otherwise the next
+	# test my fail to start ... (fscking race conditions)
+	DONE="yes"
+	while [ "$DONE" != "no" ]; do
+		L1=`netstat -a | egrep "LISTEN[\t ]*$" | grep ":$CLIENT_PORT"`
+		L2=`netstat -a | egrep "LISTEN[\t ]*$" | grep ":$SERVER_PORT"`
+		if [ "x$L1" != "x" ]; then
+			DONE="yes"
+		elif [ "x$L2" != "x" ]; then
+			DONE="yes"
+		else
+			DONE="no"
+		fi
+	done
+	exit 0
+}
+
+run_test ()
+{
+	(sub_test 1> /dev/null) || exit 1
+}
+
+run_ssl_test ()
+{
+killall tunala 1> /dev/null 2> /dev/null
+echo ""
+echo "Starting all $PRETTY tests"
+if [ "$PRETTY" != "SSLv2" ]; then
+	if [ "$PRETTY" != "SSLv3" ]; then
+		export VER="-no_ssl2 -no_ssl3"
+		export OSSL="-tls1"
+	else
+		export VER="-no_ssl2 -no_tls1"
+		export OSSL="-ssl3"
+	fi
+else
+	export VER="-no_ssl3 -no_tls1"
+	export OSSL="-ssl2"
+fi
+LIST="`../../apps/openssl ciphers $OSSL | sed -e 's/:/ /g'`"
+#echo "$LIST"
+for i in $LIST; do \
+	DSS=`echo "$i" | grep "DSS"`
+	if [ "x$DSS" != "x" ]; then
+		echo "---- skipping $i (no DSA cert/keys) ----"
+	else
+		export CIPHER=$i
+		run_test
+		echo "SUCCESS: $i"
+	fi
+done;
+}
+
+# Welcome the user
+echo "Tests will assume an http server running at $HTTP"
+
+# TLSv1 test
+export PRETTY="TLSv1"
+run_ssl_test
+
+# SSLv3 test
+export PRETTY="SSLv3"
+run_ssl_test
+
+# SSLv2 test
+export PRETTY="SSLv2"
+run_ssl_test
+
diff --git a/openssl/demos/tunala/tunala.c b/openssl/demos/tunala/tunala.c
new file mode 100644
index 0000000..ec49d3e
--- /dev/null
+++ b/openssl/demos/tunala/tunala.c
@@ -0,0 +1,1109 @@
+#if defined(NO_BUFFER) || defined(NO_IP) || defined(NO_OPENSSL)
+#error "Badness, NO_BUFFER, NO_IP or NO_OPENSSL is defined, turn them *off*"
+#endif
+
+/* Include our bits'n'pieces */
+#include "tunala.h"
+
+
+/********************************************/
+/* Our local types that specify our "world" */
+/********************************************/
+
+/* These represent running "tunnels". Eg. if you wanted to do SSL in a
+ * "message-passing" scanario, the "int" file-descriptors might be replaced by
+ * thread or process IDs, and the "select" code might be replaced by message
+ * handling code. Whatever. */
+typedef struct _tunala_item_t {
+	/* The underlying SSL state machine. This is a data-only processing unit
+	 * and we communicate with it by talking to its four "buffers". */
+	state_machine_t sm;
+	/* The file-descriptors for the "dirty" (encrypted) side of the SSL
+	 * setup. In actuality, this is typically a socket and both values are
+	 * identical. */
+	int dirty_read, dirty_send;
+	/* The file-descriptors for the "clean" (unencrypted) side of the SSL
+	 * setup. These could be stdin/stdout, a socket (both values the same),
+	 * or whatever you like. */
+	int clean_read, clean_send;
+} tunala_item_t;
+
+/* This structure is used as the data for running the main loop. Namely, in a
+ * network format such as this, it is stuff for select() - but as pointed out,
+ * when moving the real-world to somewhere else, this might be replaced by
+ * something entirely different. It's basically the stuff that controls when
+ * it's time to do some "work". */
+typedef struct _select_sets_t {
+	int max; /* As required as the first argument to select() */
+	fd_set reads, sends, excepts; /* As passed to select() */
+} select_sets_t;
+typedef struct _tunala_selector_t {
+	select_sets_t last_selected; /* Results of the last select() */
+	select_sets_t next_select; /* What we'll next select on */
+} tunala_selector_t;
+
+/* This structure is *everything*. We do it to avoid the use of globals so that,
+ * for example, it would be easier to shift things around between async-IO,
+ * thread-based, or multi-fork()ed (or combinations thereof). */
+typedef struct _tunala_world_t {
+	/* The file-descriptor we "listen" on for new connections */
+	int listen_fd;
+	/* The array of tunnels */
+	tunala_item_t *tunnels;
+	/* the number of tunnels in use and allocated, respectively */
+	unsigned int tunnels_used, tunnels_size;
+	/* Our outside "loop" context stuff */
+	tunala_selector_t selector;
+	/* Our SSL_CTX, which is configured as the SSL client or server and has
+	 * the various cert-settings and callbacks configured. */
+	SSL_CTX *ssl_ctx;
+	/* Simple flag with complex logic :-) Indicates whether we're an SSL
+	 * server or an SSL client. */
+	int server_mode;
+} tunala_world_t;
+
+/*****************************/
+/* Internal static functions */
+/*****************************/
+
+static SSL_CTX *initialise_ssl_ctx(int server_mode, const char *engine_id,
+		const char *CAfile, const char *cert, const char *key,
+		const char *dcert, const char *dkey, const char *cipher_list,
+		const char *dh_file, const char *dh_special, int tmp_rsa,
+		int ctx_options, int out_state, int out_verify, int verify_mode,
+		unsigned int verify_depth);
+static void selector_init(tunala_selector_t *selector);
+static void selector_add_listener(tunala_selector_t *selector, int fd);
+static void selector_add_tunala(tunala_selector_t *selector, tunala_item_t *t);
+static int selector_select(tunala_selector_t *selector);
+/* This returns -1 for error, 0 for no new connections, or 1 for success, in
+ * which case *newfd is populated. */
+static int selector_get_listener(tunala_selector_t *selector, int fd, int *newfd);
+static int tunala_world_new_item(tunala_world_t *world, int fd,
+		const char *ip, unsigned short port, int flipped);
+static void tunala_world_del_item(tunala_world_t *world, unsigned int idx);
+static int tunala_item_io(tunala_selector_t *selector, tunala_item_t *item);
+
+/*********************************************/
+/* MAIN FUNCTION (and its utility functions) */
+/*********************************************/
+
+static const char *def_proxyhost = "127.0.0.1:443";
+static const char *def_listenhost = "127.0.0.1:8080";
+static int def_max_tunnels = 50;
+static const char *def_cacert = NULL;
+static const char *def_cert = NULL;
+static const char *def_key = NULL;
+static const char *def_dcert = NULL;
+static const char *def_dkey = NULL;
+static const char *def_engine_id = NULL;
+static int def_server_mode = 0;
+static int def_flipped = 0;
+static const char *def_cipher_list = NULL;
+static const char *def_dh_file = NULL;
+static const char *def_dh_special = NULL;
+static int def_tmp_rsa = 1;
+static int def_ctx_options = 0;
+static int def_verify_mode = 0;
+static unsigned int def_verify_depth = 10;
+static int def_out_state = 0;
+static unsigned int def_out_verify = 0;
+static int def_out_totals = 0;
+static int def_out_conns = 0;
+
+static const char *helpstring =
+"\n'Tunala' (A tunneler with a New Zealand accent)\n"
+"Usage: tunala [options], where options are from;\n"
+" -listen [host:]<port>  (default = 127.0.0.1:8080)\n"
+" -proxy <host>:<port>   (default = 127.0.0.1:443)\n"
+" -maxtunnels <num>      (default = 50)\n"
+" -cacert <path|NULL>    (default = NULL)\n"
+" -cert <path|NULL>      (default = NULL)\n"
+" -key <path|NULL>       (default = whatever '-cert' is)\n"
+" -dcert <path|NULL>     (usually for DSA, default = NULL)\n"
+" -dkey <path|NULL>      (usually for DSA, default = whatever '-dcert' is)\n"
+" -engine <id|NULL>      (default = NULL)\n"
+" -server <0|1>          (default = 0, ie. an SSL client)\n"
+" -flipped <0|1>         (makes SSL servers be network clients, and vice versa)\n"
+" -cipher <list>         (specifies cipher list to use)\n"
+" -dh_file <path>        (a PEM file containing DH parameters to use)\n"
+" -dh_special <NULL|generate|standard> (see below: def=NULL)\n"
+" -no_tmp_rsa            (don't generate temporary RSA keys)\n"
+" -no_ssl2               (disable SSLv2)\n"
+" -no_ssl3               (disable SSLv3)\n"
+" -no_tls1               (disable TLSv1)\n"
+" -v_peer                (verify the peer certificate)\n"
+" -v_strict              (do not continue if peer doesn't authenticate)\n"
+" -v_once                (no verification in renegotiates)\n"
+" -v_depth <num>         (limit certificate chain depth, default = 10)\n"
+" -out_conns             (prints client connections and disconnections)\n"
+" -out_state             (prints SSL handshake states)\n"
+" -out_verify <0|1|2|3>  (prints certificate verification states: def=1)\n"
+" -out_totals            (prints out byte-totals when a tunnel closes)\n"
+" -<h|help|?>            (displays this help screen)\n"
+"Notes:\n"
+"(1) It is recommended to specify a cert+key when operating as an SSL server.\n"
+"    If you only specify '-cert', the same file must contain a matching\n"
+"    private key.\n"
+"(2) Either dh_file or dh_special can be used to specify where DH parameters\n"
+"    will be obtained from (or '-dh_special NULL' for the default choice) but\n"
+"    you cannot specify both. For dh_special, 'generate' will create new DH\n"
+"    parameters on startup, and 'standard' will use embedded parameters\n"
+"    instead.\n"
+"(3) Normally an ssl client connects to an ssl server - so that an 'ssl client\n"
+"    tunala' listens for 'clean' client connections and proxies ssl, and an\n"
+"    'ssl server tunala' listens for ssl connections and proxies 'clean'. With\n"
+"    '-flipped 1', this behaviour is reversed so that an 'ssl server tunala'\n"
+"    listens for clean client connections and proxies ssl (but participating\n"
+"    as an ssl *server* in the SSL/TLS protocol), and an 'ssl client tunala'\n"
+"    listens for ssl connections (participating as an ssl *client* in the\n"
+"    SSL/TLS protocol) and proxies 'clean' to the end destination. This can\n"
+"    be useful for allowing network access to 'servers' where only the server\n"
+"    needs to authenticate the client (ie. the other way is not required).\n"
+"    Even with client and server authentication, this 'technique' mitigates\n"
+"    some DoS (denial-of-service) potential as it will be the network client\n"
+"    having to perform the first private key operation rather than the other\n"
+"    way round.\n"
+"(4) The 'technique' used by setting '-flipped 1' is probably compatible with\n"
+"    absolutely nothing except another complimentary instance of 'tunala'\n"
+"    running with '-flipped 1'. :-)\n";
+
+/* Default DH parameters for use with "-dh_special standard" ... stolen striaght
+ * from s_server. */
+static unsigned char dh512_p[]={
+	0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
+	0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
+	0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
+	0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
+	0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
+	0x47,0x74,0xE8,0x33,
+	};
+static unsigned char dh512_g[]={
+	0x02,
+	};
+
+/* And the function that parses the above "standard" parameters, again, straight
+ * out of s_server. */
+static DH *get_dh512(void)
+	{
+	DH *dh=NULL;
+
+	if ((dh=DH_new()) == NULL) return(NULL);
+	dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
+	dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
+	if ((dh->p == NULL) || (dh->g == NULL))
+		return(NULL);
+	return(dh);
+	}
+
+/* Various help/error messages used by main() */
+static int usage(const char *errstr, int isunknownarg)
+{
+	if(isunknownarg)
+		fprintf(stderr, "Error: unknown argument '%s'\n", errstr);
+	else
+		fprintf(stderr, "Error: %s\n", errstr);
+	fprintf(stderr, "%s\n", helpstring);
+	return 1;
+}
+
+static int err_str0(const char *str0)
+{
+	fprintf(stderr, "%s\n", str0);
+	return 1;
+}
+
+static int err_str1(const char *fmt, const char *str1)
+{
+	fprintf(stderr, fmt, str1);
+	fprintf(stderr, "\n");
+	return 1;
+}
+
+static int parse_max_tunnels(const char *s, unsigned int *maxtunnels)
+{
+	unsigned long l;
+	if(!int_strtoul(s, &l) || (l < 1) || (l > 1024)) {
+		fprintf(stderr, "Error, '%s' is an invalid value for "
+				"maxtunnels\n", s);
+		return 0;
+	}
+	*maxtunnels = (unsigned int)l;
+	return 1;
+}
+
+static int parse_server_mode(const char *s, int *servermode)
+{
+	unsigned long l;
+	if(!int_strtoul(s, &l) || (l > 1)) {
+		fprintf(stderr, "Error, '%s' is an invalid value for the "
+				"server mode\n", s);
+		return 0;
+	}
+	*servermode = (int)l;
+	return 1;
+}
+
+static int parse_dh_special(const char *s, const char **dh_special)
+{
+	if((strcmp(s, "NULL") == 0) || (strcmp(s, "generate") == 0) ||
+			(strcmp(s, "standard") == 0)) {
+		*dh_special = s;
+		return 1;
+	}
+	fprintf(stderr, "Error, '%s' is an invalid value for 'dh_special'\n", s);
+	return 0;
+}
+
+static int parse_verify_level(const char *s, unsigned int *verify_level)
+{
+	unsigned long l;
+	if(!int_strtoul(s, &l) || (l > 3)) {
+		fprintf(stderr, "Error, '%s' is an invalid value for "
+				"out_verify\n", s);
+		return 0;
+	}
+	*verify_level = (unsigned int)l;
+	return 1;
+}
+
+static int parse_verify_depth(const char *s, unsigned int *verify_depth)
+{
+	unsigned long l;
+	if(!int_strtoul(s, &l) || (l < 1) || (l > 50)) {
+		fprintf(stderr, "Error, '%s' is an invalid value for "
+				"verify_depth\n", s);
+		return 0;
+	}
+	*verify_depth = (unsigned int)l;
+	return 1;
+}
+
+/* Some fprintf format strings used when tunnels close */
+static const char *io_stats_dirty =
+"    SSL traffic;   %8lu bytes in, %8lu bytes out\n";
+static const char *io_stats_clean =
+"    clear traffic; %8lu bytes in, %8lu bytes out\n";
+
+int main(int argc, char *argv[])
+{
+	unsigned int loop;
+	int newfd;
+	tunala_world_t world;
+	tunala_item_t *t_item;
+	const char *proxy_ip;
+	unsigned short proxy_port;
+	/* Overridables */
+	const char *proxyhost = def_proxyhost;
+	const char *listenhost = def_listenhost;
+	unsigned int max_tunnels = def_max_tunnels;
+	const char *cacert = def_cacert;
+	const char *cert = def_cert;
+	const char *key = def_key;
+	const char *dcert = def_dcert;
+	const char *dkey = def_dkey;
+	const char *engine_id = def_engine_id;
+	int server_mode = def_server_mode;
+	int flipped = def_flipped;
+	const char *cipher_list = def_cipher_list;
+	const char *dh_file = def_dh_file;
+	const char *dh_special = def_dh_special;
+	int tmp_rsa = def_tmp_rsa;
+	int ctx_options = def_ctx_options;
+	int verify_mode = def_verify_mode;
+	unsigned int verify_depth = def_verify_depth;
+	int out_state = def_out_state;
+	unsigned int out_verify = def_out_verify;
+	int out_totals = def_out_totals;
+	int out_conns = def_out_conns;
+
+/* Parse command-line arguments */
+next_arg:
+	argc--; argv++;
+	if(argc > 0) {
+		if(strcmp(*argv, "-listen") == 0) {
+			if(argc < 2)
+				return usage("-listen requires an argument", 0);
+			argc--; argv++;
+			listenhost = *argv;
+			goto next_arg;
+		} else if(strcmp(*argv, "-proxy") == 0) {
+			if(argc < 2)
+				return usage("-proxy requires an argument", 0);
+			argc--; argv++;
+			proxyhost = *argv;
+			goto next_arg;
+		} else if(strcmp(*argv, "-maxtunnels") == 0) {
+			if(argc < 2)
+				return usage("-maxtunnels requires an argument", 0);
+			argc--; argv++;
+			if(!parse_max_tunnels(*argv, &max_tunnels))
+				return 1;
+			goto next_arg;
+		} else if(strcmp(*argv, "-cacert") == 0) {
+			if(argc < 2)
+				return usage("-cacert requires an argument", 0);
+			argc--; argv++;
+			if(strcmp(*argv, "NULL") == 0)
+				cacert = NULL;
+			else
+				cacert = *argv;
+			goto next_arg;
+		} else if(strcmp(*argv, "-cert") == 0) {
+			if(argc < 2)
+				return usage("-cert requires an argument", 0);
+			argc--; argv++;
+			if(strcmp(*argv, "NULL") == 0)
+				cert = NULL;
+			else
+				cert = *argv;
+			goto next_arg;
+		} else if(strcmp(*argv, "-key") == 0) {
+			if(argc < 2)
+				return usage("-key requires an argument", 0);
+			argc--; argv++;
+			if(strcmp(*argv, "NULL") == 0)
+				key = NULL;
+			else
+				key = *argv;
+			goto next_arg;
+		} else if(strcmp(*argv, "-dcert") == 0) {
+			if(argc < 2)
+				return usage("-dcert requires an argument", 0);
+			argc--; argv++;
+			if(strcmp(*argv, "NULL") == 0)
+				dcert = NULL;
+			else
+				dcert = *argv;
+			goto next_arg;
+		} else if(strcmp(*argv, "-dkey") == 0) {
+			if(argc < 2)
+				return usage("-dkey requires an argument", 0);
+			argc--; argv++;
+			if(strcmp(*argv, "NULL") == 0)
+				dkey = NULL;
+			else
+				dkey = *argv;
+			goto next_arg;
+		} else if(strcmp(*argv, "-engine") == 0) {
+			if(argc < 2)
+				return usage("-engine requires an argument", 0);
+			argc--; argv++;
+			engine_id = *argv;
+			goto next_arg;
+		} else if(strcmp(*argv, "-server") == 0) {
+			if(argc < 2)
+				return usage("-server requires an argument", 0);
+			argc--; argv++;
+			if(!parse_server_mode(*argv, &server_mode))
+				return 1;
+			goto next_arg;
+		} else if(strcmp(*argv, "-flipped") == 0) {
+			if(argc < 2)
+				return usage("-flipped requires an argument", 0);
+			argc--; argv++;
+			if(!parse_server_mode(*argv, &flipped))
+				return 1;
+			goto next_arg;
+		} else if(strcmp(*argv, "-cipher") == 0) {
+			if(argc < 2)
+				return usage("-cipher requires an argument", 0);
+			argc--; argv++;
+			cipher_list = *argv;
+			goto next_arg;
+		} else if(strcmp(*argv, "-dh_file") == 0) {
+			if(argc < 2)
+				return usage("-dh_file requires an argument", 0);
+			if(dh_special)
+				return usage("cannot mix -dh_file with "
+						"-dh_special", 0);
+			argc--; argv++;
+			dh_file = *argv;
+			goto next_arg;
+		} else if(strcmp(*argv, "-dh_special") == 0) {
+			if(argc < 2)
+				return usage("-dh_special requires an argument", 0);
+			if(dh_file)
+				return usage("cannot mix -dh_file with "
+						"-dh_special", 0);
+			argc--; argv++;
+			if(!parse_dh_special(*argv, &dh_special))
+				return 1;
+			goto next_arg;
+		} else if(strcmp(*argv, "-no_tmp_rsa") == 0) {
+			tmp_rsa = 0;
+			goto next_arg;
+		} else if(strcmp(*argv, "-no_ssl2") == 0) {
+			ctx_options |= SSL_OP_NO_SSLv2;
+			goto next_arg;
+		} else if(strcmp(*argv, "-no_ssl3") == 0) {
+			ctx_options |= SSL_OP_NO_SSLv3;
+			goto next_arg;
+		} else if(strcmp(*argv, "-no_tls1") == 0) {
+			ctx_options |= SSL_OP_NO_TLSv1;
+			goto next_arg;
+		} else if(strcmp(*argv, "-v_peer") == 0) {
+			verify_mode |= SSL_VERIFY_PEER;
+			goto next_arg;
+		} else if(strcmp(*argv, "-v_strict") == 0) {
+			verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+			goto next_arg;
+		} else if(strcmp(*argv, "-v_once") == 0) {
+			verify_mode |= SSL_VERIFY_CLIENT_ONCE;
+			goto next_arg;
+		} else if(strcmp(*argv, "-v_depth") == 0) {
+			if(argc < 2)
+				return usage("-v_depth requires an argument", 0);
+			argc--; argv++;
+			if(!parse_verify_depth(*argv, &verify_depth))
+				return 1;
+			goto next_arg;
+		} else if(strcmp(*argv, "-out_state") == 0) {
+			out_state = 1;
+			goto next_arg;
+		} else if(strcmp(*argv, "-out_verify") == 0) {
+			if(argc < 2)
+				return usage("-out_verify requires an argument", 0);
+			argc--; argv++;
+			if(!parse_verify_level(*argv, &out_verify))
+				return 1;
+			goto next_arg;
+		} else if(strcmp(*argv, "-out_totals") == 0) {
+			out_totals = 1;
+			goto next_arg;
+		} else if(strcmp(*argv, "-out_conns") == 0) {
+			out_conns = 1;
+			goto next_arg;
+		} else if((strcmp(*argv, "-h") == 0) ||
+				(strcmp(*argv, "-help") == 0) ||
+				(strcmp(*argv, "-?") == 0)) {
+			fprintf(stderr, "%s\n", helpstring);
+			return 0;
+		} else
+			return usage(*argv, 1);
+	}
+	/* Run any sanity checks we want here */
+	if(!cert && !dcert && server_mode)
+		fprintf(stderr, "WARNING: you are running an SSL server without "
+				"a certificate - this may not work!\n");
+
+	/* Initialise network stuff */
+	if(!ip_initialise())
+		return err_str0("ip_initialise failed");
+	/* Create the SSL_CTX */
+	if((world.ssl_ctx = initialise_ssl_ctx(server_mode, engine_id,
+			cacert, cert, key, dcert, dkey, cipher_list, dh_file,
+			dh_special, tmp_rsa, ctx_options, out_state, out_verify,
+			verify_mode, verify_depth)) == NULL)
+		return err_str1("initialise_ssl_ctx(engine_id=%s) failed",
+			(engine_id == NULL) ? "NULL" : engine_id);
+	if(engine_id)
+		fprintf(stderr, "Info, engine '%s' initialised\n", engine_id);
+	/* Create the listener */
+	if((world.listen_fd = ip_create_listener(listenhost)) == -1)
+		return err_str1("ip_create_listener(%s) failed", listenhost);
+	fprintf(stderr, "Info, listening on '%s'\n", listenhost);
+	if(!ip_parse_address(proxyhost, &proxy_ip, &proxy_port, 0))
+		return err_str1("ip_parse_address(%s) failed", proxyhost);
+	fprintf(stderr, "Info, proxying to '%s' (%d.%d.%d.%d:%d)\n", proxyhost,
+			(int)proxy_ip[0], (int)proxy_ip[1],
+			(int)proxy_ip[2], (int)proxy_ip[3], (int)proxy_port);
+	fprintf(stderr, "Info, set maxtunnels to %d\n", (int)max_tunnels);
+	fprintf(stderr, "Info, set to operate as an SSL %s\n",
+			(server_mode ? "server" : "client"));
+	/* Initialise the rest of the stuff */
+	world.tunnels_used = world.tunnels_size = 0;
+	world.tunnels = NULL;
+	world.server_mode = server_mode;
+	selector_init(&world.selector);
+
+/* We're ready to loop */
+main_loop:
+	/* Should we listen for *new* tunnels? */
+	if(world.tunnels_used < max_tunnels)
+		selector_add_listener(&world.selector, world.listen_fd);
+	/* We should add in our existing tunnels */
+	for(loop = 0; loop < world.tunnels_used; loop++)
+		selector_add_tunala(&world.selector, world.tunnels + loop);
+	/* Now do the select */
+	switch(selector_select(&world.selector)) {
+	case -1:
+		if(errno != EINTR) {
+			fprintf(stderr, "selector_select returned a "
+					"badness error.\n");
+			goto shouldnt_happen;
+		}
+		fprintf(stderr, "Warn, selector interrupted by a signal\n");
+		goto main_loop;
+	case 0:
+		fprintf(stderr, "Warn, selector_select returned 0 - signal?""?\n");
+		goto main_loop;
+	default:
+		break;
+	}
+	/* Accept new connection if we should and can */
+	if((world.tunnels_used < max_tunnels) && (selector_get_listener(
+					&world.selector, world.listen_fd,
+					&newfd) == 1)) {
+		/* We have a new connection */
+		if(!tunala_world_new_item(&world, newfd, proxy_ip,
+						proxy_port, flipped))
+			fprintf(stderr, "tunala_world_new_item failed\n");
+		else if(out_conns)
+			fprintf(stderr, "Info, new tunnel opened, now up to "
+					"%d\n", world.tunnels_used);
+	}
+	/* Give each tunnel its moment, note the while loop is because it makes
+	 * the logic easier than with "for" to deal with an array that may shift
+	 * because of deletes. */
+	loop = 0;
+	t_item = world.tunnels;
+	while(loop < world.tunnels_used) {
+		if(!tunala_item_io(&world.selector, t_item)) {
+			/* We're closing whether for reasons of an error or a
+			 * natural close. Don't increment loop or t_item because
+			 * the next item is moving to us! */
+			if(!out_totals)
+				goto skip_totals;
+			fprintf(stderr, "Tunnel closing, traffic stats follow\n");
+			/* Display the encrypted (over the network) stats */
+			fprintf(stderr, io_stats_dirty,
+				buffer_total_in(state_machine_get_buffer(
+						&t_item->sm,SM_DIRTY_IN)),
+				buffer_total_out(state_machine_get_buffer(
+						&t_item->sm,SM_DIRTY_OUT)));
+			/* Display the local (tunnelled) stats. NB: Data we
+			 * *receive* is data sent *out* of the state_machine on
+			 * its 'clean' side. Hence the apparent back-to-front
+			 * OUT/IN mixup here :-) */
+			fprintf(stderr, io_stats_clean,
+				buffer_total_out(state_machine_get_buffer(
+						&t_item->sm,SM_CLEAN_OUT)),
+				buffer_total_in(state_machine_get_buffer(
+						&t_item->sm,SM_CLEAN_IN)));
+skip_totals:
+			tunala_world_del_item(&world, loop);
+			if(out_conns)
+				fprintf(stderr, "Info, tunnel closed, down to %d\n",
+					world.tunnels_used);
+		}
+		else {
+			/* Move to the next item */
+			loop++;
+			t_item++;
+		}
+	}
+	goto main_loop;
+	/* Should never get here */
+shouldnt_happen:
+	abort();
+	return 1;
+}
+
+/****************/
+/* OpenSSL bits */
+/****************/
+
+static int ctx_set_cert(SSL_CTX *ctx, const char *cert, const char *key)
+{
+	FILE *fp = NULL;
+	X509 *x509 = NULL;
+	EVP_PKEY *pkey = NULL;
+	int toret = 0; /* Assume an error */
+
+	/* cert */
+	if(cert) {
+		if((fp = fopen(cert, "r")) == NULL) {
+			fprintf(stderr, "Error opening cert file '%s'\n", cert);
+			goto err;
+		}
+		if(!PEM_read_X509(fp, &x509, NULL, NULL)) {
+			fprintf(stderr, "Error reading PEM cert from '%s'\n",
+					cert);
+			goto err;
+		}
+		if(!SSL_CTX_use_certificate(ctx, x509)) {
+			fprintf(stderr, "Error, cert in '%s' can not be used\n",
+					cert);
+			goto err;
+		}
+		/* Clear the FILE* for reuse in the "key" code */
+		fclose(fp);
+		fp = NULL;
+		fprintf(stderr, "Info, operating with cert in '%s'\n", cert);
+		/* If a cert was given without matching key, we assume the same
+		 * file contains the required key. */
+		if(!key)
+			key = cert;
+	} else {
+		if(key)
+			fprintf(stderr, "Error, can't specify a key without a "
+					"corresponding certificate\n");
+		else
+			fprintf(stderr, "Error, ctx_set_cert called with "
+					"NULLs!\n");
+		goto err;
+	}
+	/* key */
+	if(key) {
+		if((fp = fopen(key, "r")) == NULL) {
+			fprintf(stderr, "Error opening key file '%s'\n", key);
+			goto err;
+		}
+		if(!PEM_read_PrivateKey(fp, &pkey, NULL, NULL)) {
+			fprintf(stderr, "Error reading PEM key from '%s'\n",
+					key);
+			goto err;
+		}
+		if(!SSL_CTX_use_PrivateKey(ctx, pkey)) {
+			fprintf(stderr, "Error, key in '%s' can not be used\n",
+					key);
+			goto err;
+		}
+		fprintf(stderr, "Info, operating with key in '%s'\n", key);
+	} else
+		fprintf(stderr, "Info, operating without a cert or key\n");
+	/* Success */
+	toret = 1; err:
+	if(x509)
+		X509_free(x509);
+	if(pkey)
+		EVP_PKEY_free(pkey);
+	if(fp)
+		fclose(fp);
+	return toret;
+}
+
+static int ctx_set_dh(SSL_CTX *ctx, const char *dh_file, const char *dh_special)
+{
+	DH *dh = NULL;
+	FILE *fp = NULL;
+
+	if(dh_special) {
+		if(strcmp(dh_special, "NULL") == 0)
+			return 1;
+		if(strcmp(dh_special, "standard") == 0) {
+			if((dh = get_dh512()) == NULL) {
+				fprintf(stderr, "Error, can't parse 'standard'"
+						" DH parameters\n");
+				return 0;
+			}
+			fprintf(stderr, "Info, using 'standard' DH parameters\n");
+			goto do_it;
+		}
+		if(strcmp(dh_special, "generate") != 0)
+			/* This shouldn't happen - screening values is handled
+			 * in main(). */
+			abort();
+		fprintf(stderr, "Info, generating DH parameters ... ");
+		fflush(stderr);
+		if(!(dh = DH_new()) || !DH_generate_parameters_ex(dh, 512,
+					DH_GENERATOR_5, NULL)) {
+			fprintf(stderr, "error!\n");
+			if(dh)
+				DH_free(dh);
+			return 0;
+		}
+		fprintf(stderr, "complete\n");
+		goto do_it;
+	}
+	/* So, we're loading dh_file */
+	if((fp = fopen(dh_file, "r")) == NULL) {
+		fprintf(stderr, "Error, couldn't open '%s' for DH parameters\n",
+				dh_file);
+		return 0;
+	}
+	dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
+	fclose(fp);
+	if(dh == NULL) {
+		fprintf(stderr, "Error, could not parse DH parameters from '%s'\n",
+				dh_file);
+		return 0;
+	}
+	fprintf(stderr, "Info, using DH parameters from file '%s'\n", dh_file);
+do_it:
+	SSL_CTX_set_tmp_dh(ctx, dh);
+	DH_free(dh);
+	return 1;
+}
+
+static SSL_CTX *initialise_ssl_ctx(int server_mode, const char *engine_id,
+		const char *CAfile, const char *cert, const char *key,
+		const char *dcert, const char *dkey, const char *cipher_list,
+		const char *dh_file, const char *dh_special, int tmp_rsa,
+		int ctx_options, int out_state, int out_verify, int verify_mode,
+		unsigned int verify_depth)
+{
+	SSL_CTX *ctx = NULL, *ret = NULL;
+	const SSL_METHOD *meth;
+	ENGINE *e = NULL;
+
+        OpenSSL_add_ssl_algorithms();
+        SSL_load_error_strings();
+
+	meth = (server_mode ? SSLv23_server_method() : SSLv23_client_method());
+	if(meth == NULL)
+		goto err;
+	if(engine_id) {
+		ENGINE_load_builtin_engines();
+		if((e = ENGINE_by_id(engine_id)) == NULL) {
+			fprintf(stderr, "Error obtaining '%s' engine, openssl "
+					"errors follow\n", engine_id);
+			goto err;
+		}
+		if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
+			fprintf(stderr, "Error assigning '%s' engine, openssl "
+					"errors follow\n", engine_id);
+			goto err;
+		}
+		ENGINE_free(e);
+	}
+	if((ctx = SSL_CTX_new(meth)) == NULL)
+		goto err;
+	/* cacert */
+	if(CAfile) {
+		if(!X509_STORE_load_locations(SSL_CTX_get_cert_store(ctx),
+					CAfile, NULL)) {
+			fprintf(stderr, "Error loading CA cert(s) in '%s'\n",
+					CAfile);
+			goto err;
+		}
+		fprintf(stderr, "Info, operating with CA cert(s) in '%s'\n",
+				CAfile);
+	} else
+		fprintf(stderr, "Info, operating without a CA cert(-list)\n");
+	if(!SSL_CTX_set_default_verify_paths(ctx)) {
+		fprintf(stderr, "Error setting default verify paths\n");
+		goto err;
+	}
+
+	/* cert and key */
+	if((cert || key) && !ctx_set_cert(ctx, cert, key))
+		goto err;
+	/* dcert and dkey */
+	if((dcert || dkey) && !ctx_set_cert(ctx, dcert, dkey))
+		goto err;
+	/* temporary RSA key generation */
+	if(tmp_rsa)
+		SSL_CTX_set_tmp_rsa_callback(ctx, cb_generate_tmp_rsa);
+
+	/* cipher_list */
+	if(cipher_list) {
+		if(!SSL_CTX_set_cipher_list(ctx, cipher_list)) {
+			fprintf(stderr, "Error setting cipher list '%s'\n",
+					cipher_list);
+			goto err;
+		}
+		fprintf(stderr, "Info, set cipher list '%s'\n", cipher_list);
+	} else
+		fprintf(stderr, "Info, operating with default cipher list\n");
+
+	/* dh_file & dh_special */
+	if((dh_file || dh_special) && !ctx_set_dh(ctx, dh_file, dh_special))
+		goto err;
+
+	/* ctx_options */
+	SSL_CTX_set_options(ctx, ctx_options);
+
+	/* out_state (output of SSL handshake states to screen). */
+	if(out_state)
+		cb_ssl_info_set_output(stderr);
+
+	/* out_verify */
+	if(out_verify > 0) {
+		cb_ssl_verify_set_output(stderr);
+		cb_ssl_verify_set_level(out_verify);
+	}
+
+	/* verify_depth */
+	cb_ssl_verify_set_depth(verify_depth);
+
+	/* Success! (includes setting verify_mode) */
+	SSL_CTX_set_info_callback(ctx, cb_ssl_info);
+	SSL_CTX_set_verify(ctx, verify_mode, cb_ssl_verify);
+	ret = ctx;
+err:
+	if(!ret) {
+		ERR_print_errors_fp(stderr);
+		if(ctx)
+			SSL_CTX_free(ctx);
+	}
+	return ret;
+}
+
+/*****************/
+/* Selector bits */
+/*****************/
+
+static void selector_sets_init(select_sets_t *s)
+{
+	s->max = 0;
+	FD_ZERO(&s->reads);
+	FD_ZERO(&s->sends);
+	FD_ZERO(&s->excepts);
+}
+static void selector_init(tunala_selector_t *selector)
+{
+	selector_sets_init(&selector->last_selected);
+	selector_sets_init(&selector->next_select);
+}
+
+#define SEL_EXCEPTS 0x00
+#define SEL_READS   0x01
+#define SEL_SENDS   0x02
+static void selector_add_raw_fd(tunala_selector_t *s, int fd, int flags)
+{
+	FD_SET(fd, &s->next_select.excepts);
+	if(flags & SEL_READS)
+		FD_SET(fd, &s->next_select.reads);
+	if(flags & SEL_SENDS)
+		FD_SET(fd, &s->next_select.sends);
+	/* Adjust "max" */
+	if(s->next_select.max < (fd + 1))
+		s->next_select.max = fd + 1;
+}
+
+static void selector_add_listener(tunala_selector_t *selector, int fd)
+{
+	selector_add_raw_fd(selector, fd, SEL_READS);
+}
+
+static void selector_add_tunala(tunala_selector_t *s, tunala_item_t *t)
+{
+	/* Set clean read if sm.clean_in is not full */
+	if(t->clean_read != -1) {
+		selector_add_raw_fd(s, t->clean_read,
+			(buffer_full(state_machine_get_buffer(&t->sm,
+				SM_CLEAN_IN)) ? SEL_EXCEPTS : SEL_READS));
+	}
+	/* Set clean send if sm.clean_out is not empty */
+	if(t->clean_send != -1) {
+		selector_add_raw_fd(s, t->clean_send,
+			(buffer_empty(state_machine_get_buffer(&t->sm,
+				SM_CLEAN_OUT)) ? SEL_EXCEPTS : SEL_SENDS));
+	}
+	/* Set dirty read if sm.dirty_in is not full */
+	if(t->dirty_read != -1) {
+		selector_add_raw_fd(s, t->dirty_read,
+			(buffer_full(state_machine_get_buffer(&t->sm,
+				SM_DIRTY_IN)) ? SEL_EXCEPTS : SEL_READS));
+	}
+	/* Set dirty send if sm.dirty_out is not empty */
+	if(t->dirty_send != -1) {
+		selector_add_raw_fd(s, t->dirty_send,
+			(buffer_empty(state_machine_get_buffer(&t->sm,
+				SM_DIRTY_OUT)) ? SEL_EXCEPTS : SEL_SENDS));
+	}
+}
+
+static int selector_select(tunala_selector_t *selector)
+{
+	memcpy(&selector->last_selected, &selector->next_select,
+			sizeof(select_sets_t));
+	selector_sets_init(&selector->next_select);
+	return select(selector->last_selected.max,
+			&selector->last_selected.reads,
+			&selector->last_selected.sends,
+			&selector->last_selected.excepts, NULL);
+}
+
+/* This returns -1 for error, 0 for no new connections, or 1 for success, in
+ * which case *newfd is populated. */
+static int selector_get_listener(tunala_selector_t *selector, int fd, int *newfd)
+{
+	if(FD_ISSET(fd, &selector->last_selected.excepts))
+		return -1;
+	if(!FD_ISSET(fd, &selector->last_selected.reads))
+		return 0;
+	if((*newfd = ip_accept_connection(fd)) == -1)
+		return -1;
+	return 1;
+}
+
+/************************/
+/* "Tunala" world stuff */
+/************************/
+
+static int tunala_world_make_room(tunala_world_t *world)
+{
+	unsigned int newsize;
+	tunala_item_t *newarray;
+
+	if(world->tunnels_used < world->tunnels_size)
+		return 1;
+	newsize = (world->tunnels_size == 0 ? 16 :
+			((world->tunnels_size * 3) / 2));
+	if((newarray = malloc(newsize * sizeof(tunala_item_t))) == NULL)
+		return 0;
+	memset(newarray, 0, newsize * sizeof(tunala_item_t));
+	if(world->tunnels_used > 0)
+		memcpy(newarray, world->tunnels,
+			world->tunnels_used * sizeof(tunala_item_t));
+	if(world->tunnels_size > 0)
+		free(world->tunnels);
+	/* migrate */
+	world->tunnels = newarray;
+	world->tunnels_size = newsize;
+	return 1;
+}
+
+static int tunala_world_new_item(tunala_world_t *world, int fd,
+		const char *ip, unsigned short port, int flipped)
+{
+	tunala_item_t *item;
+	int newfd;
+	SSL *new_ssl = NULL;
+
+	if(!tunala_world_make_room(world))
+		return 0;
+	if((new_ssl = SSL_new(world->ssl_ctx)) == NULL) {
+		fprintf(stderr, "Error creating new SSL\n");
+		ERR_print_errors_fp(stderr);
+		return 0;
+	}
+	item = world->tunnels + (world->tunnels_used++);
+	state_machine_init(&item->sm);
+	item->clean_read = item->clean_send =
+		item->dirty_read = item->dirty_send = -1;
+	if((newfd = ip_create_connection_split(ip, port)) == -1)
+		goto err;
+	/* Which way round? If we're a server, "fd" is the dirty side and the
+	 * connection we open is the clean one. For a client, it's the other way
+	 * around. Unless, of course, we're "flipped" in which case everything
+	 * gets reversed. :-) */
+	if((world->server_mode && !flipped) ||
+			(!world->server_mode && flipped)) {
+		item->dirty_read = item->dirty_send = fd;
+		item->clean_read = item->clean_send = newfd;
+	} else {
+		item->clean_read = item->clean_send = fd;
+		item->dirty_read = item->dirty_send = newfd;
+	}
+	/* We use the SSL's "app_data" to indicate a call-back induced "kill" */
+	SSL_set_app_data(new_ssl, NULL);
+	if(!state_machine_set_SSL(&item->sm, new_ssl, world->server_mode))
+		goto err;
+	return 1;
+err:
+	tunala_world_del_item(world, world->tunnels_used - 1);
+	return 0;
+
+}
+
+static void tunala_world_del_item(tunala_world_t *world, unsigned int idx)
+{
+	tunala_item_t *item = world->tunnels + idx;
+	if(item->clean_read != -1)
+		close(item->clean_read);
+	if(item->clean_send != item->clean_read)
+		close(item->clean_send);
+	item->clean_read = item->clean_send = -1;
+	if(item->dirty_read != -1)
+		close(item->dirty_read);
+	if(item->dirty_send != item->dirty_read)
+		close(item->dirty_send);
+	item->dirty_read = item->dirty_send = -1;
+	state_machine_close(&item->sm);
+	/* OK, now we fix the item array */
+	if(idx + 1 < world->tunnels_used)
+		/* We need to scroll entries to the left */
+		memmove(world->tunnels + idx,
+				world->tunnels + (idx + 1),
+				(world->tunnels_used - (idx + 1)) *
+					sizeof(tunala_item_t));
+	world->tunnels_used--;
+}
+
+static int tunala_item_io(tunala_selector_t *selector, tunala_item_t *item)
+{
+	int c_r, c_s, d_r, d_s; /* Four boolean flags */
+
+	/* Take ourselves out of the gene-pool if there was an except */
+	if((item->clean_read != -1) && FD_ISSET(item->clean_read,
+				&selector->last_selected.excepts))
+		return 0;
+	if((item->clean_send != -1) && FD_ISSET(item->clean_send,
+				&selector->last_selected.excepts))
+		return 0;
+	if((item->dirty_read != -1) && FD_ISSET(item->dirty_read,
+				&selector->last_selected.excepts))
+		return 0;
+	if((item->dirty_send != -1) && FD_ISSET(item->dirty_send,
+				&selector->last_selected.excepts))
+		return 0;
+	/* Grab our 4 IO flags */
+	c_r = c_s = d_r = d_s = 0;
+	if(item->clean_read != -1)
+		c_r = FD_ISSET(item->clean_read, &selector->last_selected.reads);
+	if(item->clean_send != -1)
+		c_s = FD_ISSET(item->clean_send, &selector->last_selected.sends);
+	if(item->dirty_read != -1)
+		d_r = FD_ISSET(item->dirty_read, &selector->last_selected.reads);
+	if(item->dirty_send != -1)
+		d_s = FD_ISSET(item->dirty_send, &selector->last_selected.sends);
+	/* If no IO has happened for us, skip needless data looping */
+	if(!c_r && !c_s && !d_r && !d_s)
+		return 1;
+	if(c_r)
+		c_r = (buffer_from_fd(state_machine_get_buffer(&item->sm,
+				SM_CLEAN_IN), item->clean_read) <= 0);
+	if(c_s)
+		c_s = (buffer_to_fd(state_machine_get_buffer(&item->sm,
+				SM_CLEAN_OUT), item->clean_send) <= 0);
+	if(d_r)
+		d_r = (buffer_from_fd(state_machine_get_buffer(&item->sm,
+				SM_DIRTY_IN), item->dirty_read) <= 0);
+	if(d_s)
+		d_s = (buffer_to_fd(state_machine_get_buffer(&item->sm,
+				SM_DIRTY_OUT), item->dirty_send) <= 0);
+	/* If any of the flags is non-zero, that means they need closing */
+	if(c_r) {
+		close(item->clean_read);
+		if(item->clean_send == item->clean_read)
+			item->clean_send = -1;
+		item->clean_read = -1;
+	}
+	if(c_s && (item->clean_send != -1)) {
+		close(item->clean_send);
+		if(item->clean_send == item->clean_read)
+			item->clean_read = -1;
+		item->clean_send = -1;
+	}
+	if(d_r) {
+		close(item->dirty_read);
+		if(item->dirty_send == item->dirty_read)
+			item->dirty_send = -1;
+		item->dirty_read = -1;
+	}
+	if(d_s && (item->dirty_send != -1)) {
+		close(item->dirty_send);
+		if(item->dirty_send == item->dirty_read)
+			item->dirty_read = -1;
+		item->dirty_send = -1;
+	}
+	/* This function name is attributed to the term donated by David
+	 * Schwartz on openssl-dev, message-ID:
+	 * <NCBBLIEPOCNJOAEKBEAKEEDGLIAA.davids@webmaster.com>. :-) */
+	if(!state_machine_churn(&item->sm))
+		/* If the SSL closes, it will also zero-out the _in buffers
+		 * and will in future process just outgoing data. As and
+		 * when the outgoing data has gone, it will return zero
+		 * here to tell us to bail out. */
+		return 0;
+	/* Otherwise, we return zero if both sides are dead. */
+	if(((item->clean_read == -1) || (item->clean_send == -1)) &&
+			((item->dirty_read == -1) || (item->dirty_send == -1)))
+		return 0;
+	/* If only one side closed, notify the SSL of this so it can take
+	 * appropriate action. */
+	if((item->clean_read == -1) || (item->clean_send == -1)) {
+		if(!state_machine_close_clean(&item->sm))
+			return 0;
+	}
+	if((item->dirty_read == -1) || (item->dirty_send == -1)) {
+		if(!state_machine_close_dirty(&item->sm))
+			return 0;
+	}
+	return 1;
+}
+
diff --git a/openssl/demos/tunala/tunala.h b/openssl/demos/tunala/tunala.h
new file mode 100644
index 0000000..3a752f2
--- /dev/null
+++ b/openssl/demos/tunala/tunala.h
@@ -0,0 +1,215 @@
+/* Tunala ("Tunneler with a New Zealand accent")
+ *
+ * Written by Geoff Thorpe, but endorsed/supported by noone. Please use this is
+ * if it's useful or informative to you, but it's only here as a scratchpad for
+ * ideas about how you might (or might not) program with OpenSSL. If you deploy
+ * this is in a mission-critical environment, and have not read, understood,
+ * audited, and modified this code to your satisfaction, and the result is that
+ * all hell breaks loose and you are looking for a new employer, then it proves
+ * nothing except perhaps that Darwinism is alive and well. Let's just say, *I*
+ * don't use this in a mission-critical environment, so it would be stupid for
+ * anyone to assume that it is solid and/or tested enough when even its author
+ * doesn't place that much trust in it. You have been warned.
+ *
+ * With thanks to Cryptographic Appliances, Inc.
+ */
+
+#ifndef _TUNALA_H
+#define _TUNALA_H
+
+/* pull in autoconf fluff */
+#ifndef NO_CONFIG_H
+#include "config.h"
+#else
+/* We don't have autoconf, we have to set all of these unless a tweaked Makefile
+ * tells us not to ... */
+/* headers */
+#ifndef NO_HAVE_SELECT
+#define HAVE_SELECT
+#endif
+#ifndef NO_HAVE_SOCKET
+#define HAVE_SOCKET
+#endif
+#ifndef NO_HAVE_UNISTD_H
+#define HAVE_UNISTD_H
+#endif
+#ifndef NO_HAVE_FCNTL_H
+#define HAVE_FCNTL_H
+#endif
+#ifndef NO_HAVE_LIMITS_H
+#define HAVE_LIMITS_H
+#endif
+/* features */
+#ifndef NO_HAVE_STRSTR
+#define HAVE_STRSTR
+#endif
+#ifndef NO_HAVE_STRTOUL
+#define HAVE_STRTOUL
+#endif
+#endif
+
+#if !defined(HAVE_SELECT) || !defined(HAVE_SOCKET)
+#error "can't build without some network basics like select() and socket()"
+#endif
+
+#include <stdlib.h>
+#ifndef NO_SYSTEM_H
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#include <netdb.h>
+#include <signal.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#endif /* !defined(NO_SYSTEM_H) */
+
+#ifndef NO_OPENSSL
+#include <openssl/err.h>
+#include <openssl/engine.h>
+#include <openssl/ssl.h>
+#endif /* !defined(NO_OPENSSL) */
+
+#ifndef OPENSSL_NO_BUFFER
+/* This is the generic "buffer" type that is used when feeding the
+ * state-machine. It's basically a FIFO with respect to the "adddata" &
+ * "takedata" type functions that operate on it. */
+#define MAX_DATA_SIZE 16384
+typedef struct _buffer_t {
+	unsigned char data[MAX_DATA_SIZE];
+	unsigned int used;
+	/* Statistical values - counts the total number of bytes read in and
+	 * read out (respectively) since "buffer_init()" */
+	unsigned long total_in, total_out;
+} buffer_t;
+
+/* Initialise a buffer structure before use */
+void buffer_init(buffer_t *buf);
+/* Cleanup a buffer structure - presently not needed, but if buffer_t is
+ * converted to using dynamic allocation, this would be required - so should be
+ * called to protect against an explosion of memory leaks later if the change is
+ * made. */
+void buffer_close(buffer_t *buf);
+
+/* Basic functions to manipulate buffers */
+
+unsigned int buffer_used(buffer_t *buf); /* How much data in the buffer */
+unsigned int buffer_unused(buffer_t *buf); /* How much space in the buffer */
+int buffer_full(buffer_t *buf); /* Boolean, is it full? */
+int buffer_notfull(buffer_t *buf); /* Boolean, is it not full? */
+int buffer_empty(buffer_t *buf); /* Boolean, is it empty? */
+int buffer_notempty(buffer_t *buf); /* Boolean, is it not empty? */
+unsigned long buffer_total_in(buffer_t *buf); /* Total bytes written to buffer */
+unsigned long buffer_total_out(buffer_t *buf); /* Total bytes read from buffer */
+
+#if 0 /* Currently used only within buffer.c - better to expose only
+       * higher-level functions anyway */
+/* Add data to the tail of the buffer, returns the amount that was actually
+ * added (so, you need to check if return value is less than size) */
+unsigned int buffer_adddata(buffer_t *buf, const unsigned char *ptr,
+		unsigned int size);
+
+/* Take data from the front of the buffer (and scroll the rest forward). If
+ * "ptr" is NULL, this just removes data off the front of the buffer. Return
+ * value is the amount actually removed (can be less than size if the buffer has
+ * too little data). */
+unsigned int buffer_takedata(buffer_t *buf, unsigned char *ptr,
+		unsigned int size);
+
+/* Flushes as much data as possible out of the "from" buffer into the "to"
+ * buffer. Return value is the amount moved. The amount moved can be restricted
+ * to a maximum by specifying "cap" - setting it to -1 means no limit. */
+unsigned int buffer_tobuffer(buffer_t *to, buffer_t *from, int cap);
+#endif
+
+#ifndef NO_IP
+/* Read or write between a file-descriptor and a buffer */
+int buffer_from_fd(buffer_t *buf, int fd);
+int buffer_to_fd(buffer_t *buf, int fd);
+#endif /* !defined(NO_IP) */
+
+#ifndef NO_OPENSSL
+/* Read or write between an SSL or BIO and a buffer */
+void buffer_from_SSL(buffer_t *buf, SSL *ssl);
+void buffer_to_SSL(buffer_t *buf, SSL *ssl);
+void buffer_from_BIO(buffer_t *buf, BIO *bio);
+void buffer_to_BIO(buffer_t *buf, BIO *bio);
+
+/* Callbacks */
+void cb_ssl_info(const SSL *s, int where, int ret);
+void cb_ssl_info_set_output(FILE *fp); /* Called if output should be sent too */
+int cb_ssl_verify(int ok, X509_STORE_CTX *ctx);
+void cb_ssl_verify_set_output(FILE *fp);
+void cb_ssl_verify_set_depth(unsigned int verify_depth);
+void cb_ssl_verify_set_level(unsigned int level);
+RSA *cb_generate_tmp_rsa(SSL *s, int is_export, int keylength);
+#endif /* !defined(NO_OPENSSL) */
+#endif /* !defined(OPENSSL_NO_BUFFER) */
+
+#ifndef NO_TUNALA
+#ifdef OPENSSL_NO_BUFFER
+#error "TUNALA section of tunala.h requires BUFFER support"
+#endif
+typedef struct _state_machine_t {
+	SSL *ssl;
+	BIO *bio_intossl;
+	BIO *bio_fromssl;
+	buffer_t clean_in, clean_out;
+	buffer_t dirty_in, dirty_out;
+} state_machine_t;
+typedef enum {
+	SM_CLEAN_IN, SM_CLEAN_OUT,
+	SM_DIRTY_IN, SM_DIRTY_OUT
+} sm_buffer_t;
+void state_machine_init(state_machine_t *machine);
+void state_machine_close(state_machine_t *machine);
+buffer_t *state_machine_get_buffer(state_machine_t *machine, sm_buffer_t type);
+SSL *state_machine_get_SSL(state_machine_t *machine);
+int state_machine_set_SSL(state_machine_t *machine, SSL *ssl, int is_server);
+/* Performs the data-IO loop and returns zero if the machine should close */
+int state_machine_churn(state_machine_t *machine);
+/* Is used to handle closing conditions - namely when one side of the tunnel has
+ * closed but the other should finish flushing. */
+int state_machine_close_clean(state_machine_t *machine);
+int state_machine_close_dirty(state_machine_t *machine);
+#endif /* !defined(NO_TUNALA) */
+
+#ifndef NO_IP
+/* Initialise anything related to the networking. This includes blocking pesky
+ * SIGPIPE signals. */
+int ip_initialise(void);
+/* ip is the 4-byte ip address (eg. 127.0.0.1 is {0x7F,0x00,0x00,0x01}), port is
+ * the port to listen on (host byte order), and the return value is the
+ * file-descriptor or -1 on error. */
+int ip_create_listener_split(const char *ip, unsigned short port);
+/* Same semantics as above. */
+int ip_create_connection_split(const char *ip, unsigned short port);
+/* Converts a string into the ip/port before calling the above */
+int ip_create_listener(const char *address);
+int ip_create_connection(const char *address);
+/* Just does a string conversion on its own. NB: If accept_all_ip is non-zero,
+ * then the address string could be just a port. Ie. it's suitable for a
+ * listening address but not a connecting address. */
+int ip_parse_address(const char *address, const char **parsed_ip,
+		unsigned short *port, int accept_all_ip);
+/* Accepts an incoming connection through the listener. Assumes selects and
+ * what-not have deemed it an appropriate thing to do. */
+int ip_accept_connection(int listen_fd);
+#endif /* !defined(NO_IP) */
+
+/* These functions wrap up things that can be portability hassles. */
+int int_strtoul(const char *str, unsigned long *val);
+#ifdef HAVE_STRSTR
+#define int_strstr strstr
+#else
+char *int_strstr(const char *haystack, const char *needle);
+#endif
+
+#endif /* !defined(_TUNALA_H) */
diff --git a/openssl/demos/x509/README b/openssl/demos/x509/README
new file mode 100644
index 0000000..88f9d6c
--- /dev/null
+++ b/openssl/demos/x509/README
@@ -0,0 +1,3 @@
+This directory contains examples of how to contruct
+various X509 structures. Certificates, certificate requests
+and CRLs.
diff --git a/openssl/demos/x509/mkcert.c b/openssl/demos/x509/mkcert.c
new file mode 100644
index 0000000..6a52e5d
--- /dev/null
+++ b/openssl/demos/x509/mkcert.c
@@ -0,0 +1,172 @@
+/* Certificate creation. Demonstrates some certificate related
+ * operations.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <openssl/pem.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days);
+int add_ext(X509 *cert, int nid, char *value);
+
+int main(int argc, char **argv)
+	{
+	BIO *bio_err;
+	X509 *x509=NULL;
+	EVP_PKEY *pkey=NULL;
+
+	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+	bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
+
+	mkcert(&x509,&pkey,512,0,365);
+
+	RSA_print_fp(stdout,pkey->pkey.rsa,0);
+	X509_print_fp(stdout,x509);
+
+	PEM_write_PrivateKey(stdout,pkey,NULL,NULL,0,NULL, NULL);
+	PEM_write_X509(stdout,x509);
+
+	X509_free(x509);
+	EVP_PKEY_free(pkey);
+
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE_cleanup();
+#endif
+	CRYPTO_cleanup_all_ex_data();
+
+	CRYPTO_mem_leaks(bio_err);
+	BIO_free(bio_err);
+	return(0);
+	}
+
+static void callback(int p, int n, void *arg)
+	{
+	char c='B';
+
+	if (p == 0) c='.';
+	if (p == 1) c='+';
+	if (p == 2) c='*';
+	if (p == 3) c='\n';
+	fputc(c,stderr);
+	}
+
+int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days)
+	{
+	X509 *x;
+	EVP_PKEY *pk;
+	RSA *rsa;
+	X509_NAME *name=NULL;
+	
+	if ((pkeyp == NULL) || (*pkeyp == NULL))
+		{
+		if ((pk=EVP_PKEY_new()) == NULL)
+			{
+			abort(); 
+			return(0);
+			}
+		}
+	else
+		pk= *pkeyp;
+
+	if ((x509p == NULL) || (*x509p == NULL))
+		{
+		if ((x=X509_new()) == NULL)
+			goto err;
+		}
+	else
+		x= *x509p;
+
+	rsa=RSA_generate_key(bits,RSA_F4,callback,NULL);
+	if (!EVP_PKEY_assign_RSA(pk,rsa))
+		{
+		abort();
+		goto err;
+		}
+	rsa=NULL;
+
+	X509_set_version(x,2);
+	ASN1_INTEGER_set(X509_get_serialNumber(x),serial);
+	X509_gmtime_adj(X509_get_notBefore(x),0);
+	X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);
+	X509_set_pubkey(x,pk);
+
+	name=X509_get_subject_name(x);
+
+	/* This function creates and adds the entry, working out the
+	 * correct string type and performing checks on its length.
+	 * Normally we'd check the return value for errors...
+	 */
+	X509_NAME_add_entry_by_txt(name,"C",
+				MBSTRING_ASC, "UK", -1, -1, 0);
+	X509_NAME_add_entry_by_txt(name,"CN",
+				MBSTRING_ASC, "OpenSSL Group", -1, -1, 0);
+
+	/* Its self signed so set the issuer name to be the same as the
+ 	 * subject.
+	 */
+	X509_set_issuer_name(x,name);
+
+	/* Add various extensions: standard extensions */
+	add_ext(x, NID_basic_constraints, "critical,CA:TRUE");
+	add_ext(x, NID_key_usage, "critical,keyCertSign,cRLSign");
+
+	add_ext(x, NID_subject_key_identifier, "hash");
+
+	/* Some Netscape specific extensions */
+	add_ext(x, NID_netscape_cert_type, "sslCA");
+
+	add_ext(x, NID_netscape_comment, "example comment extension");
+
+
+#ifdef CUSTOM_EXT
+	/* Maybe even add our own extension based on existing */
+	{
+		int nid;
+		nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
+		X509V3_EXT_add_alias(nid, NID_netscape_comment);
+		add_ext(x, nid, "example comment alias");
+	}
+#endif
+	
+	if (!X509_sign(x,pk,EVP_sha1()))
+		goto err;
+
+	*x509p=x;
+	*pkeyp=pk;
+	return(1);
+err:
+	return(0);
+	}
+
+/* Add extension using V3 code: we can set the config file as NULL
+ * because we wont reference any other sections.
+ */
+
+int add_ext(X509 *cert, int nid, char *value)
+	{
+	X509_EXTENSION *ex;
+	X509V3_CTX ctx;
+	/* This sets the 'context' of the extensions. */
+	/* No configuration database */
+	X509V3_set_ctx_nodb(&ctx);
+	/* Issuer and subject certs: both the target since it is self signed,
+	 * no request and no CRL
+	 */
+	X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
+	ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
+	if (!ex)
+		return 0;
+
+	X509_add_ext(cert,ex,-1);
+	X509_EXTENSION_free(ex);
+	return 1;
+	}
+	
diff --git a/openssl/demos/x509/mkreq.c b/openssl/demos/x509/mkreq.c
new file mode 100644
index 0000000..d17e4ad
--- /dev/null
+++ b/openssl/demos/x509/mkreq.c
@@ -0,0 +1,161 @@
+/* Certificate request creation. Demonstrates some request related
+ * operations.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <openssl/pem.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+int mkreq(X509_REQ **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days);
+int add_ext(STACK_OF(X509_REQUEST) *sk, int nid, char *value);
+
+int main(int argc, char **argv)
+	{
+	BIO *bio_err;
+	X509_REQ *req=NULL;
+	EVP_PKEY *pkey=NULL;
+
+	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+	bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
+
+	mkreq(&req,&pkey,512,0,365);
+
+	RSA_print_fp(stdout,pkey->pkey.rsa,0);
+	X509_REQ_print_fp(stdout,req);
+
+	PEM_write_X509_REQ(stdout,req);
+
+	X509_REQ_free(req);
+	EVP_PKEY_free(pkey);
+
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE_cleanup();
+#endif
+	CRYPTO_cleanup_all_ex_data();
+
+	CRYPTO_mem_leaks(bio_err);
+	BIO_free(bio_err);
+	return(0);
+	}
+
+static void callback(int p, int n, void *arg)
+	{
+	char c='B';
+
+	if (p == 0) c='.';
+	if (p == 1) c='+';
+	if (p == 2) c='*';
+	if (p == 3) c='\n';
+	fputc(c,stderr);
+	}
+
+int mkreq(X509_REQ **req, EVP_PKEY **pkeyp, int bits, int serial, int days)
+	{
+	X509_REQ *x;
+	EVP_PKEY *pk;
+	RSA *rsa;
+	X509_NAME *name=NULL;
+	STACK_OF(X509_EXTENSION) *exts = NULL;
+	
+	if ((pk=EVP_PKEY_new()) == NULL)
+		goto err;
+
+	if ((x=X509_REQ_new()) == NULL)
+		goto err;
+
+	rsa=RSA_generate_key(bits,RSA_F4,callback,NULL);
+	if (!EVP_PKEY_assign_RSA(pk,rsa))
+		goto err;
+
+	rsa=NULL;
+
+	X509_REQ_set_pubkey(x,pk);
+
+	name=X509_REQ_get_subject_name(x);
+
+	/* This function creates and adds the entry, working out the
+	 * correct string type and performing checks on its length.
+	 * Normally we'd check the return value for errors...
+	 */
+	X509_NAME_add_entry_by_txt(name,"C",
+				MBSTRING_ASC, "UK", -1, -1, 0);
+	X509_NAME_add_entry_by_txt(name,"CN",
+				MBSTRING_ASC, "OpenSSL Group", -1, -1, 0);
+
+#ifdef REQUEST_EXTENSIONS
+	/* Certificate requests can contain extensions, which can be used
+	 * to indicate the extensions the requestor would like added to 
+	 * their certificate. CAs might ignore them however or even choke
+	 * if they are present.
+	 */
+
+	/* For request extensions they are all packed in a single attribute.
+	 * We save them in a STACK and add them all at once later...
+	 */
+
+	exts = sk_X509_EXTENSION_new_null();
+	/* Standard extenions */
+
+	add_ext(exts, NID_key_usage, "critical,digitalSignature,keyEncipherment");
+
+	/* This is a typical use for request extensions: requesting a value for
+	 * subject alternative name.
+	 */
+
+	add_ext(exts, NID_subject_alt_name, "email:steve@openssl.org");
+
+	/* Some Netscape specific extensions */
+	add_ext(exts, NID_netscape_cert_type, "client,email");
+
+
+
+#ifdef CUSTOM_EXT
+	/* Maybe even add our own extension based on existing */
+	{
+		int nid;
+		nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
+		X509V3_EXT_add_alias(nid, NID_netscape_comment);
+		add_ext(x, nid, "example comment alias");
+	}
+#endif
+
+	/* Now we've created the extensions we add them to the request */
+
+	X509_REQ_add_extensions(x, exts);
+
+	sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+
+#endif
+	
+	if (!X509_REQ_sign(x,pk,EVP_sha1()))
+		goto err;
+
+	*req=x;
+	*pkeyp=pk;
+	return(1);
+err:
+	return(0);
+	}
+
+/* Add extension using V3 code: we can set the config file as NULL
+ * because we wont reference any other sections.
+ */
+
+int add_ext(STACK_OF(X509_REQUEST) *sk, int nid, char *value)
+	{
+	X509_EXTENSION *ex;
+	ex = X509V3_EXT_conf_nid(NULL, NULL, nid, value);
+	if (!ex)
+		return 0;
+	sk_X509_EXTENSION_push(sk, ex);
+
+	return 1;
+	}
+	
diff --git a/openssl/doc/HOWTO/certificates.txt b/openssl/doc/HOWTO/certificates.txt
new file mode 100644
index 0000000..a8a34c7
--- /dev/null
+++ b/openssl/doc/HOWTO/certificates.txt
@@ -0,0 +1,105 @@
+<DRAFT!>
+			HOWTO certificates
+
+1. Introduction
+
+How you handle certificates depend a great deal on what your role is.
+Your role can be one or several of:
+
+  - User of some client software
+  - User of some server software
+  - Certificate authority
+
+This file is for users who wish to get a certificate of their own.
+Certificate authorities should read ca.txt.
+
+In all the cases shown below, the standard configuration file, as
+compiled into openssl, will be used.  You may find it in /etc/,
+/usr/local/ssl/ or somewhere else.  The name is openssl.cnf, and
+is better described in another HOWTO <config.txt?>.  If you want to
+use a different configuration file, use the argument '-config {file}'
+with the command shown below.
+
+
+2. Relationship with keys
+
+Certificates are related to public key cryptography by containing a
+public key.  To be useful, there must be a corresponding private key
+somewhere.  With OpenSSL, public keys are easily derived from private
+keys, so before you create a certificate or a certificate request, you
+need to create a private key.
+
+Private keys are generated with 'openssl genrsa' if you want a RSA
+private key, or 'openssl gendsa' if you want a DSA private key.
+Further information on how to create private keys can be found in
+another HOWTO <keys.txt?>.  The rest of this text assumes you have
+a private key in the file privkey.pem.
+
+
+3. Creating a certificate request
+
+To create a certificate, you need to start with a certificate
+request (or, as some certificate authorities like to put
+it, "certificate signing request", since that's exactly what they do,
+they sign it and give you the result back, thus making it authentic
+according to their policies).  A certificate request can then be sent
+to a certificate authority to get it signed into a certificate, or if
+you have your own certificate authority, you may sign it yourself, or
+if you need a self-signed certificate (because you just want a test
+certificate or because you are setting up your own CA).
+
+The certificate request is created like this:
+
+  openssl req -new -key privkey.pem -out cert.csr
+
+Now, cert.csr can be sent to the certificate authority, if they can
+handle files in PEM format.  If not, use the extra argument '-outform'
+followed by the keyword for the format to use (see another HOWTO
+<formats.txt?>).  In some cases, that isn't sufficient and you will
+have to be more creative.
+
+When the certificate authority has then done the checks the need to
+do (and probably gotten payment from you), they will hand over your
+new certificate to you.
+
+Section 5 will tell you more on how to handle the certificate you
+received.
+
+
+4. Creating a self-signed test certificate
+
+If you don't want to deal with another certificate authority, or just
+want to create a test certificate for yourself.  This is similar to
+creating a certificate request, but creates a certificate instead of
+a certificate request.  This is NOT the recommended way to create a
+CA certificate, see ca.txt.
+
+  openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095
+
+
+5. What to do with the certificate
+
+If you created everything yourself, or if the certificate authority
+was kind enough, your certificate is a raw DER thing in PEM format.
+Your key most definitely is if you have followed the examples above.
+However, some (most?) certificate authorities will encode them with
+things like PKCS7 or PKCS12, or something else.  Depending on your
+applications, this may be perfectly OK, it all depends on what they
+know how to decode.  If not, There are a number of OpenSSL tools to
+convert between some (most?) formats.
+
+So, depending on your application, you may have to convert your
+certificate and your key to various formats, most often also putting
+them together into one file.  The ways to do this is described in
+another HOWTO <formats.txt?>, I will just mention the simplest case.
+In the case of a raw DER thing in PEM format, and assuming that's all
+right for yor applications, simply concatenating the certificate and
+the key into a new file and using that one should be enough.  With
+some applications, you don't even have to do that.
+
+
+By now, you have your cetificate and your private key and can start
+using the software that depend on it.
+
+-- 
+Richard Levitte
diff --git a/openssl/doc/HOWTO/keys.txt b/openssl/doc/HOWTO/keys.txt
new file mode 100644
index 0000000..7ae2a3a
--- /dev/null
+++ b/openssl/doc/HOWTO/keys.txt
@@ -0,0 +1,73 @@
+<DRAFT!>
+			HOWTO keys
+
+1. Introduction
+
+Keys are the basis of public key algorithms and PKI.  Keys usually
+come in pairs, with one half being the public key and the other half
+being the private key.  With OpenSSL, the private key contains the
+public key information as well, so a public key doesn't need to be
+generated separately.
+
+Public keys come in several flavors, using different cryptographic
+algorithms.  The most popular ones associated with certificates are
+RSA and DSA, and this HOWTO will show how to generate each of them.
+
+
+2. To generate a RSA key
+
+A RSA key can be used both for encryption and for signing.
+
+Generating a key for the RSA algorithm is quite easy, all you have to
+do is the following:
+
+  openssl genrsa -des3 -out privkey.pem 2048
+
+With this variant, you will be prompted for a protecting password.  If
+you don't want your key to be protected by a password, remove the flag
+'-des3' from the command line above.
+
+    NOTE: if you intend to use the key together with a server
+    certificate, it may be a good thing to avoid protecting it
+    with a password, since that would mean someone would have to
+    type in the password every time the server needs to access
+    the key.
+
+The number 2048 is the size of the key, in bits.  Today, 2048 or
+higher is recommended for RSA keys, as fewer amount of bits is
+consider insecure or to be insecure pretty soon.
+
+
+3. To generate a DSA key
+
+A DSA key can be used for signing only.  This is important to keep
+in mind to know what kind of purposes a certificate request with a
+DSA key can really be used for.
+
+Generating a key for the DSA algorithm is a two-step process.  First,
+you have to generate parameters from which to generate the key:
+
+  openssl dsaparam -out dsaparam.pem 2048
+
+The number 2048 is the size of the key, in bits.  Today, 2048 or
+higher is recommended for DSA keys, as fewer amount of bits is
+consider insecure or to be insecure pretty soon.
+
+When that is done, you can generate a key using the parameters in
+question (actually, several keys can be generated from the same
+parameters):
+
+  openssl gendsa -des3 -out privkey.pem dsaparam.pem
+
+With this variant, you will be prompted for a protecting password.  If
+you don't want your key to be protected by a password, remove the flag
+'-des3' from the command line above.
+
+    NOTE: if you intend to use the key together with a server
+    certificate, it may be a good thing to avoid protecting it
+    with a password, since that would mean someone would have to
+    type in the password every time the server needs to access
+    the key.
+
+-- 
+Richard Levitte
diff --git a/openssl/doc/HOWTO/proxy_certificates.txt b/openssl/doc/HOWTO/proxy_certificates.txt
new file mode 100644
index 0000000..3d36b02
--- /dev/null
+++ b/openssl/doc/HOWTO/proxy_certificates.txt
@@ -0,0 +1,322 @@
+<DRAFT!>
+			HOWTO proxy certificates
+
+0. WARNING
+
+NONE OF THE CODE PRESENTED HERE HAVE BEEN CHECKED!  They are just an
+example to show you how things can be done.  There may be typos or
+type conflicts, and you will have to resolve them.
+
+1. Introduction
+
+Proxy certificates are defined in RFC 3820.  They are really usual
+certificates with the mandatory extension proxyCertInfo.
+
+Proxy certificates are issued by an End Entity (typically a user),
+either directly with the EE certificate as issuing certificate, or by
+extension through an already issued proxy certificate..  They are used
+to extend rights to some other entity (a computer process, typically,
+or sometimes to the user itself), so it can perform operations in the
+name of the owner of the EE certificate.
+
+See http://www.ietf.org/rfc/rfc3820.txt for more information.
+
+
+2. A warning about proxy certificates
+
+Noone seems to have tested proxy certificates with security in mind.
+Basically, to this date, it seems that proxy certificates have only
+been used in a world that's highly aware of them.  What would happen
+if an unsuspecting application is to validate a chain of certificates
+that contains proxy certificates?  It would usually consider the leaf
+to be the certificate to check for authorisation data, and since proxy
+certificates are controlled by the EE certificate owner alone, it's
+would be normal to consider what the EE certificate owner could do
+with them.
+
+subjectAltName and issuerAltName are forbidden in proxy certificates,
+and this is enforced in OpenSSL.  The subject must be the same as the
+issuer, with one commonName added on.
+
+Possible threats are, as far as has been imagined so far:
+
+ - impersonation through commonName (think server certificates).
+ - use of additional extensions, possibly non-standard ones used in
+   certain environments, that would grant extra or different
+   authorisation rights.
+
+For this reason, OpenSSL requires that the use of proxy certificates
+be explicitely allowed.  Currently, this can be done using the
+following methods:
+
+ - if the application calls X509_verify_cert() itself, it can do the
+   following prior to that call (ctx is the pointer passed in the call
+   to X509_verify_cert()):
+
+	X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
+
+ - in all other cases, proxy certificate validation can be enabled
+   before starting the application by setting the envirnoment variable
+   OPENSSL_ALLOW_PROXY with some non-empty value.
+
+There are thoughts to allow proxy certificates with a line in the
+default openssl.cnf, but that's still in the future.
+
+
+3. How to create proxy cerificates
+
+It's quite easy to create proxy certificates, by taking advantage of
+the lack of checks of the 'openssl x509' application (*ahem*).  But
+first, you need to create a configuration section that contains a
+definition of the proxyCertInfo extension, a little like this:
+
+  [ v3_proxy ]
+  # A proxy certificate MUST NEVER be a CA certificate.
+  basicConstraints=CA:FALSE
+
+  # Usual authority key ID
+  authorityKeyIdentifier=keyid,issuer:always
+
+  # Now, for the extension that marks this certificate as a proxy one
+  proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:1,policy:text:AB
+
+It's also possible to give the proxy extension in a separate section:
+
+  proxyCertInfo=critical,@proxy_ext
+
+  [ proxy_ext ]
+  language=id-ppl-anyLanguage
+  pathlen=0
+  policy=text:BC
+
+The policy value has a specific syntax, {syntag}:{string}, where the
+syntag determines what will be done with the string.  The recognised
+syntags are as follows:
+
+  text	indicates that the string is simply the bytes, not
+	encoded in any kind of way:
+
+		policy=text:räksmörgås
+
+	Previous versions of this design had a specific tag
+	for UTF-8 text.  However, since the bytes are copied
+	as-is anyway, there's no need for it.  Instead, use
+	the text: tag, like this:
+
+		policy=text:räksmörgås
+
+  hex	indicates the string is encoded in hex, with colons
+	between each byte (every second hex digit):
+
+		policy=hex:72:E4:6B:73:6D:F6:72:67:E5:73
+
+	Previous versions of this design had a tag to insert a
+	complete DER blob.  However, the only legal use for
+	this would be to surround the bytes that would go with
+	the hex: tag with what's needed to construct a correct
+	OCTET STRING.  Since hex: does that, the DER tag felt
+	superfluous, and was therefore removed.
+
+  file	indicates that the text of the policy should really be
+	taken from a file.  The string is then really a file
+	name.  This is useful for policies that are large
+	(more than a few of lines) XML documents, for example.
+
+The 'policy' setting can be split up in multiple lines like this:
+
+  0.policy=This is
+  1.polisy= a multi-
+  2.policy=line policy.
+
+NOTE: the proxy policy value is the part that determines the rights
+granted to the process using the proxy certificate.  The value is
+completely dependent on the application reading and interpretting it!
+
+Now that you have created an extension section for your proxy
+certificate, you can now easily create a proxy certificate like this:
+
+  openssl req -new -config openssl.cnf \
+	  -out proxy.req -keyout proxy.key
+  openssl x509 -req -CAcreateserial -in proxy.req -days 7 \
+	  -out proxy.crt -CA user.crt -CAkey user.key \
+	  -extfile openssl.cnf -extensions v3_proxy
+
+It's just as easy to create a proxy certificate using another proxy
+certificate as issuer (note that I'm using a different configuration
+section for it):
+
+  openssl req -new -config openssl.cnf \
+	  -out proxy2.req -keyout proxy2.key
+  openssl x509 -req -CAcreateserial -in proxy2.req -days 7 \
+	  -out proxy2.crt -CA proxy.crt -CAkey proxy.key \
+	  -extfile openssl.cnf -extensions v3_proxy2
+
+
+4. How to have your application interpret the policy?
+
+The basic way to interpret proxy policies is to prepare some default
+rights, then do a check of the proxy certificate against the a chain
+of proxy certificates, user certificate and CA certificates, and see
+what rights came out by the end.  Sounds easy, huh?  It almost is.
+
+The slightly complicated part is how to pass data between your
+application and the certificate validation procedure.
+
+You need the following ingredients:
+
+ - a callback routing that will be called for every certificate that's
+   validated.  It will be called several times for each certificates,
+   so you must be attentive to when it's a good time to do the proxy
+   policy interpretation and check, as well as to fill in the defaults
+   when the EE certificate is checked.
+
+ - a structure of data that's shared between your application code and
+   the callback.
+
+ - a wrapper function that sets it all up.
+
+ - an ex_data index function that creates an index into the generic
+   ex_data store that's attached to an X509 validation context.
+
+This is some cookbook code for you to fill in:
+
+  /* In this example, I will use a view of granted rights as a bit
+     array, one bit for each possible right.  */
+  typedef struct your_rights {
+    unsigned char rights[total_rights / 8];
+  } YOUR_RIGHTS;
+
+  /* The following procedure will create an index for the ex_data
+     store in the X509 validation context the first time it's called.
+     Subsequent calls will return the same index.  */
+  static int get_proxy_auth_ex_data_idx(void)
+  {
+    static volatile int idx = -1;
+    if (idx < 0)
+      {
+        CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+        if (idx < 0)
+          {
+            idx = X509_STORE_CTX_get_ex_new_index(0,
+                                                  "for verify callback",
+                                                  NULL,NULL,NULL);
+          }
+        CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+      }
+    return idx;
+  }
+
+  /* Callback to be given to the X509 validation procedure.  */
+  static int verify_callback(int ok, X509_STORE_CTX *ctx)
+  {
+    if (ok == 1) /* It's REALLY important you keep the proxy policy
+                    check within this secion.  It's important to know
+                    that when ok is 1, the certificates are checked
+                    from top to bottom.  You get the CA root first,
+                    followed by the possible chain of intermediate
+                    CAs, followed by the EE certificate, followed by
+                    the possible proxy certificates.  */
+      {
+        X509 *xs = ctx->current_cert;
+
+        if (xs->ex_flags & EXFLAG_PROXY)
+          {
+	    YOUR_RIGHTS *rights =
+              (YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx,
+                get_proxy_auth_ex_data_idx());
+            PROXY_CERT_INFO_EXTENSION *pci =
+              X509_get_ext_d2i(xs, NID_proxyCertInfo, NULL, NULL);
+
+            switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage))
+              {
+              case NID_Independent:
+                /* Do whatever you need to grant explicit rights to
+                   this particular proxy certificate, usually by
+                   pulling them from some database.  If there are none
+                   to be found, clear all rights (making this and any
+                   subsequent proxy certificate void of any rights).
+                */
+                memset(rights->rights, 0, sizeof(rights->rights));
+                break;
+              case NID_id_ppl_inheritAll:
+                /* This is basically a NOP, we simply let the current
+                   rights stand as they are. */
+                break;
+              default:
+                /* This is usually the most complex section of code.
+                   You really do whatever you want as long as you
+                   follow RFC 3820.  In the example we use here, the
+                   simplest thing to do is to build another, temporary
+                   bit array and fill it with the rights granted by
+                   the current proxy certificate, then use it as a
+                   mask on the accumulated rights bit array, and
+                   voilà, you now have a new accumulated rights bit
+                   array.  */
+                {
+                  int i;
+                  YOUR_RIGHTS tmp_rights;
+		  memset(tmp_rights.rights, 0, sizeof(tmp_rights.rights));
+
+                  /* process_rights() is supposed to be a procedure
+                     that takes a string and it's length, interprets
+                     it and sets the bits in the YOUR_RIGHTS pointed
+                     at by the third argument.  */
+                  process_rights((char *) pci->proxyPolicy->policy->data,
+                                 pci->proxyPolicy->policy->length,
+                                 &tmp_rights);
+
+                  for(i = 0; i < total_rights / 8; i++)
+                    rights->rights[i] &= tmp_rights.rights[i];
+                }
+                break;
+              }
+            PROXY_CERT_INFO_EXTENSION_free(pci);
+          }
+        else if (!(xs->ex_flags & EXFLAG_CA))
+          {
+            /* We have a EE certificate, let's use it to set default!
+            */
+	    YOUR_RIGHTS *rights =
+              (YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx,
+                get_proxy_auth_ex_data_idx());
+
+            /* The following procedure finds out what rights the owner
+               of the current certificate has, and sets them in the
+               YOUR_RIGHTS structure pointed at by the second
+               argument.  */
+            set_default_rights(xs, rights);
+          }
+      }
+    return ok;
+  }
+
+  static int my_X509_verify_cert(X509_STORE_CTX *ctx,
+                                 YOUR_RIGHTS *needed_rights)
+  {
+    int i;
+    int (*save_verify_cb)(int ok,X509_STORE_CTX *ctx) = ctx->verify_cb;
+    YOUR_RIGHTS rights;
+
+    X509_STORE_CTX_set_verify_cb(ctx, verify_callback);
+    X509_STORE_CTX_set_ex_data(ctx, get_proxy_auth_ex_data_idx(), &rights);
+    X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
+    ok = X509_verify_cert(ctx);
+
+    if (ok == 1)
+      {
+        ok = check_needed_rights(rights, needed_rights);
+      }
+
+    X509_STORE_CTX_set_verify_cb(ctx, save_verify_cb);
+
+    return ok;
+  }
+
+If you use SSL or TLS, you can easily set up a callback to have the
+certificates checked properly, using the code above:
+
+  SSL_CTX_set_cert_verify_callback(s_ctx, my_X509_verify_cert, &needed_rights);
+
+
+-- 
+Richard Levitte
diff --git a/openssl/doc/README b/openssl/doc/README
new file mode 100644
index 0000000..6ecc14d
--- /dev/null
+++ b/openssl/doc/README
@@ -0,0 +1,12 @@
+
+ apps/openssl.pod .... Documentation of OpenSSL `openssl' command
+ crypto/crypto.pod ... Documentation of OpenSSL crypto.h+libcrypto.a
+ ssl/ssl.pod ......... Documentation of OpenSSL ssl.h+libssl.a
+ openssl.txt ......... Assembled documentation files for OpenSSL [not final]
+ ssleay.txt .......... Assembled documentation of ancestor SSLeay [obsolete]
+ standards.txt ....... Assembled pointers to standards, RFCs or internet drafts
+                       that are related to OpenSSL.
+
+ An archive of HTML documents for the SSLeay library is available from
+ http://www.columbia.edu/~ariel/ssleay/
+
diff --git a/openssl/doc/apps/CA.pl.pod b/openssl/doc/apps/CA.pl.pod
new file mode 100644
index 0000000..ed69952
--- /dev/null
+++ b/openssl/doc/apps/CA.pl.pod
@@ -0,0 +1,179 @@
+
+=pod
+
+=head1 NAME
+
+CA.pl - friendlier interface for OpenSSL certificate programs
+
+=head1 SYNOPSIS
+
+B<CA.pl>
+[B<-?>]
+[B<-h>]
+[B<-help>]
+[B<-newcert>]
+[B<-newreq>]
+[B<-newreq-nodes>]
+[B<-newca>]
+[B<-xsign>]
+[B<-sign>]
+[B<-signreq>]
+[B<-signcert>]
+[B<-verify>]
+[B<files>]
+
+=head1 DESCRIPTION
+
+The B<CA.pl> script is a perl script that supplies the relevant command line
+arguments to the B<openssl> command for some common certificate operations.
+It is intended to simplify the process of certificate creation and management
+by the use of some simple options.
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<?>, B<-h>, B<-help>
+
+prints a usage message.
+
+=item B<-newcert>
+
+creates a new self signed certificate. The private key and certificate are
+written to the file "newreq.pem".
+
+=item B<-newreq>
+
+creates a new certificate request. The private key and request are
+written to the file "newreq.pem".
+
+=item B<-newreq-nodes>
+
+is like B<-newreq> except that the private key will not be encrypted.
+
+=item B<-newca>
+
+creates a new CA hierarchy for use with the B<ca> program (or the B<-signcert>
+and B<-xsign> options). The user is prompted to enter the filename of the CA
+certificates (which should also contain the private key) or by hitting ENTER
+details of the CA will be prompted for. The relevant files and directories
+are created in a directory called "demoCA" in the current directory.
+
+=item B<-pkcs12>
+
+create a PKCS#12 file containing the user certificate, private key and CA
+certificate. It expects the user certificate and private key to be in the
+file "newcert.pem" and the CA certificate to be in the file demoCA/cacert.pem,
+it creates a file "newcert.p12". This command can thus be called after the
+B<-sign> option. The PKCS#12 file can be imported directly into a browser.
+If there is an additional argument on the command line it will be used as the
+"friendly name" for the certificate (which is typically displayed in the browser
+list box), otherwise the name "My Certificate" is used.
+
+=item B<-sign>, B<-signreq>, B<-xsign>
+
+calls the B<ca> program to sign a certificate request. It expects the request
+to be in the file "newreq.pem". The new certificate is written to the file
+"newcert.pem" except in the case of the B<-xsign> option when it is written
+to standard output.
+
+
+=item B<-signCA>
+
+this option is the same as the B<-signreq> option except it uses the configuration
+file section B<v3_ca> and so makes the signed request a valid CA certificate. This
+is useful when creating intermediate CA from a root CA.
+
+=item B<-signcert>
+
+this option is the same as B<-sign> except it expects a self signed certificate
+to be present in the file "newreq.pem".
+
+=item B<-verify>
+
+verifies certificates against the CA certificate for "demoCA". If no certificates
+are specified on the command line it tries to verify the file "newcert.pem". 
+
+=item B<files>
+
+one or more optional certificate file names for use with the B<-verify> command.
+
+=back
+
+=head1 EXAMPLES
+
+Create a CA hierarchy:
+
+ CA.pl -newca
+
+Complete certificate creation example: create a CA, create a request, sign
+the request and finally create a PKCS#12 file containing it.
+
+ CA.pl -newca
+ CA.pl -newreq
+ CA.pl -signreq
+ CA.pl -pkcs12 "My Test Certificate"
+
+=head1 DSA CERTIFICATES
+
+Although the B<CA.pl> creates RSA CAs and requests it is still possible to
+use it with DSA certificates and requests using the L<req(1)|req(1)> command
+directly. The following example shows the steps that would typically be taken.
+
+Create some DSA parameters:
+
+ openssl dsaparam -out dsap.pem 1024
+
+Create a DSA CA certificate and private key:
+
+ openssl req -x509 -newkey dsa:dsap.pem -keyout cacert.pem -out cacert.pem
+
+Create the CA directories and files:
+
+ CA.pl -newca
+
+enter cacert.pem when prompted for the CA file name.
+
+Create a DSA certificate request and private key (a different set of parameters
+can optionally be created first):
+
+ openssl req -out newreq.pem -newkey dsa:dsap.pem 
+
+Sign the request:
+
+ CA.pl -signreq
+
+=head1 NOTES
+
+Most of the filenames mentioned can be modified by editing the B<CA.pl> script.
+
+If the demoCA directory already exists then the B<-newca> command will not
+overwrite it and will do nothing. This can happen if a previous call using
+the B<-newca> option terminated abnormally. To get the correct behaviour
+delete the demoCA directory if it already exists.
+
+Under some environments it may not be possible to run the B<CA.pl> script
+directly (for example Win32) and the default configuration file location may
+be wrong. In this case the command:
+
+ perl -S CA.pl
+
+can be used and the B<OPENSSL_CONF> environment variable changed to point to 
+the correct path of the configuration file "openssl.cnf".
+
+The script is intended as a simple front end for the B<openssl> program for use
+by a beginner. Its behaviour isn't always what is wanted. For more control over the
+behaviour of the certificate commands call the B<openssl> command directly.
+
+=head1 ENVIRONMENT VARIABLES
+
+The variable B<OPENSSL_CONF> if defined allows an alternative configuration
+file location to be specified, it should contain the full path to the
+configuration file, not just its directory.
+
+=head1 SEE ALSO
+
+L<x509(1)|x509(1)>, L<ca(1)|ca(1)>, L<req(1)|req(1)>, L<pkcs12(1)|pkcs12(1)>,
+L<config(5)|config(5)>
+
+=cut
diff --git a/openssl/doc/apps/asn1parse.pod b/openssl/doc/apps/asn1parse.pod
new file mode 100644
index 0000000..f7bb926
--- /dev/null
+++ b/openssl/doc/apps/asn1parse.pod
@@ -0,0 +1,175 @@
+=pod
+
+=head1 NAME
+
+asn1parse - ASN.1 parsing tool
+
+=head1 SYNOPSIS
+
+B<openssl> B<asn1parse>
+[B<-inform PEM|DER>]
+[B<-in filename>]
+[B<-out filename>]
+[B<-noout>]
+[B<-offset number>]
+[B<-length number>]
+[B<-i>]
+[B<-oid filename>]
+[B<-strparse offset>]
+[B<-genstr string>]
+[B<-genconf file>]
+
+=head1 DESCRIPTION
+
+The B<asn1parse> command is a diagnostic utility that can parse ASN.1
+structures. It can also be used to extract data from ASN.1 formatted data.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-inform> B<DER|PEM>
+
+the input format. B<DER> is binary format and B<PEM> (the default) is base64
+encoded.
+
+=item B<-in filename>
+
+the input file, default is standard input
+
+=item B<-out filename>
+
+output file to place the DER encoded data into. If this
+option is not present then no data will be output. This is most useful when
+combined with the B<-strparse> option.
+
+=item B<-noout>
+
+don't output the parsed version of the input file.
+
+=item B<-offset number>
+
+starting offset to begin parsing, default is start of file.
+
+=item B<-length number>
+
+number of bytes to parse, default is until end of file.
+
+=item B<-i>
+
+indents the output according to the "depth" of the structures.
+
+=item B<-oid filename>
+
+a file containing additional OBJECT IDENTIFIERs (OIDs). The format of this
+file is described in the NOTES section below.
+
+=item B<-strparse offset>
+
+parse the contents octets of the ASN.1 object starting at B<offset>. This
+option can be used multiple times to "drill down" into a nested structure.
+
+=item B<-genstr string>, B<-genconf file>
+
+generate encoded data based on B<string>, B<file> or both using
+L<ASN1_generate_nconf(3)|ASN1_generate_nconf(3)> format. If B<file> only is
+present then the string is obtained from the default section using the name
+B<asn1>. The encoded data is passed through the ASN1 parser and printed out as
+though it came from a file, the contents can thus be examined and written to a
+file using the B<out> option. 
+
+=back
+
+=head2 OUTPUT
+
+The output will typically contain lines like this:
+
+  0:d=0  hl=4 l= 681 cons: SEQUENCE          
+
+.....
+
+  229:d=3  hl=3 l= 141 prim: BIT STRING        
+  373:d=2  hl=3 l= 162 cons: cont [ 3 ]        
+  376:d=3  hl=3 l= 159 cons: SEQUENCE          
+  379:d=4  hl=2 l=  29 cons: SEQUENCE          
+  381:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Subject Key Identifier
+  386:d=5  hl=2 l=  22 prim: OCTET STRING      
+  410:d=4  hl=2 l= 112 cons: SEQUENCE          
+  412:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Authority Key Identifier
+  417:d=5  hl=2 l= 105 prim: OCTET STRING      
+  524:d=4  hl=2 l=  12 cons: SEQUENCE          
+
+.....
+
+This example is part of a self signed certificate. Each line starts with the
+offset in decimal. B<d=XX> specifies the current depth. The depth is increased
+within the scope of any SET or SEQUENCE. B<hl=XX> gives the header length
+(tag and length octets) of the current type. B<l=XX> gives the length of
+the contents octets.
+
+The B<-i> option can be used to make the output more readable.
+
+Some knowledge of the ASN.1 structure is needed to interpret the output. 
+
+In this example the BIT STRING at offset 229 is the certificate public key.
+The contents octets of this will contain the public key information. This can
+be examined using the option B<-strparse 229> to yield:
+
+    0:d=0  hl=3 l= 137 cons: SEQUENCE          
+    3:d=1  hl=3 l= 129 prim: INTEGER           :E5D21E1F5C8D208EA7A2166C7FAF9F6BDF2059669C60876DDB70840F1A5AAFA59699FE471F379F1DD6A487E7D5409AB6A88D4A9746E24B91D8CF55DB3521015460C8EDE44EE8A4189F7A7BE77D6CD3A9AF2696F486855CF58BF0EDF2B4068058C7A947F52548DDF7E15E96B385F86422BEA9064A3EE9E1158A56E4A6F47E5897
+  135:d=1  hl=2 l=   3 prim: INTEGER           :010001
+
+=head1 NOTES
+
+If an OID is not part of OpenSSL's internal table it will be represented in
+numerical form (for example 1.2.3.4). The file passed to the B<-oid> option 
+allows additional OIDs to be included. Each line consists of three columns,
+the first column is the OID in numerical format and should be followed by white
+space. The second column is the "short name" which is a single word followed
+by white space. The final column is the rest of the line and is the
+"long name". B<asn1parse> displays the long name. Example:
+
+C<1.2.3.4	shortName	A long name>
+
+=head1 EXAMPLES
+
+Parse a file:
+
+ openssl asn1parse -in file.pem
+
+Parse a DER file:
+
+ openssl asn1parse -inform DER -in file.der
+
+Generate a simple UTF8String:
+
+ openssl asn1parse -genstr 'UTF8:Hello World'
+
+Generate and write out a UTF8String, don't print parsed output:
+
+ openssl asn1parse -genstr 'UTF8:Hello World' -noout -out utf8.der
+
+Generate using a config file:
+
+ openssl asn1parse -genconf asn1.cnf -noout -out asn1.der
+
+Example config file:
+
+ asn1=SEQUENCE:seq_sect
+
+ [seq_sect]
+
+ field1=BOOL:TRUE
+ field2=EXP:0, UTF8:some random string
+
+
+=head1 BUGS
+
+There should be options to change the format of output lines. The output of some
+ASN.1 types is not well handled (if at all).
+
+=head1 SEE ALSO
+
+L<ASN1_generate_nconf(3)|ASN1_generate_nconf(3)>
+
+=cut
diff --git a/openssl/doc/apps/ca.pod b/openssl/doc/apps/ca.pod
new file mode 100644
index 0000000..9ff0cc3
--- /dev/null
+++ b/openssl/doc/apps/ca.pod
@@ -0,0 +1,675 @@
+
+=pod
+
+=head1 NAME
+
+ca - sample minimal CA application
+
+=head1 SYNOPSIS
+
+B<openssl> B<ca>
+[B<-verbose>]
+[B<-config filename>]
+[B<-name section>]
+[B<-gencrl>]
+[B<-revoke file>]
+[B<-crl_reason reason>]
+[B<-crl_hold instruction>]
+[B<-crl_compromise time>]
+[B<-crl_CA_compromise time>]
+[B<-crldays days>]
+[B<-crlhours hours>]
+[B<-crlexts section>]
+[B<-startdate date>]
+[B<-enddate date>]
+[B<-days arg>]
+[B<-md arg>]
+[B<-policy arg>]
+[B<-keyfile arg>]
+[B<-key arg>]
+[B<-passin arg>]
+[B<-cert file>]
+[B<-selfsign>]
+[B<-in file>]
+[B<-out file>]
+[B<-notext>]
+[B<-outdir dir>]
+[B<-infiles>]
+[B<-spkac file>]
+[B<-ss_cert file>]
+[B<-preserveDN>]
+[B<-noemailDN>]
+[B<-batch>]
+[B<-msie_hack>]
+[B<-extensions section>]
+[B<-extfile section>]
+[B<-engine id>]
+[B<-subj arg>]
+[B<-utf8>]
+[B<-multivalue-rdn>]
+
+=head1 DESCRIPTION
+
+The B<ca> command is a minimal CA application. It can be used
+to sign certificate requests in a variety of forms and generate
+CRLs it also maintains a text database of issued certificates
+and their status.
+
+The options descriptions will be divided into each purpose.
+
+=head1 CA OPTIONS
+
+=over 4
+
+=item B<-config filename>
+
+specifies the configuration file to use.
+
+=item B<-name section>
+
+specifies the configuration file section to use (overrides
+B<default_ca> in the B<ca> section).
+
+=item B<-in filename>
+
+an input filename containing a single certificate request to be
+signed by the CA.
+
+=item B<-ss_cert filename>
+
+a single self signed certificate to be signed by the CA.
+
+=item B<-spkac filename>
+
+a file containing a single Netscape signed public key and challenge
+and additional field values to be signed by the CA. See the B<SPKAC FORMAT>
+section for information on the required format.
+
+=item B<-infiles>
+
+if present this should be the last option, all subsequent arguments
+are assumed to the the names of files containing certificate requests. 
+
+=item B<-out filename>
+
+the output file to output certificates to. The default is standard
+output. The certificate details will also be printed out to this
+file.
+
+=item B<-outdir directory>
+
+the directory to output certificates to. The certificate will be
+written to a filename consisting of the serial number in hex with
+".pem" appended.
+
+=item B<-cert>
+
+the CA certificate file.
+
+=item B<-keyfile filename>
+
+the private key to sign requests with.
+
+=item B<-key password>
+
+the password used to encrypt the private key. Since on some
+systems the command line arguments are visible (e.g. Unix with
+the 'ps' utility) this option should be used with caution.
+
+=item B<-selfsign>
+
+indicates the issued certificates are to be signed with the key
+the certificate requests were signed with (given with B<-keyfile>).
+Cerificate requests signed with a different key are ignored.  If
+B<-spkac>, B<-ss_cert> or B<-gencrl> are given, B<-selfsign> is
+ignored.
+
+A consequence of using B<-selfsign> is that the self-signed
+certificate appears among the entries in the certificate database
+(see the configuration option B<database>), and uses the same
+serial number counter as all other certificates sign with the
+self-signed certificate.
+
+=item B<-passin arg>
+
+the key password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-verbose>
+
+this prints extra details about the operations being performed.
+
+=item B<-notext>
+
+don't output the text form of a certificate to the output file.
+
+=item B<-startdate date>
+
+this allows the start date to be explicitly set. The format of the
+date is YYMMDDHHMMSSZ (the same as an ASN1 UTCTime structure).
+
+=item B<-enddate date>
+
+this allows the expiry date to be explicitly set. The format of the
+date is YYMMDDHHMMSSZ (the same as an ASN1 UTCTime structure).
+
+=item B<-days arg>
+
+the number of days to certify the certificate for.
+
+=item B<-md alg>
+
+the message digest to use. Possible values include md5, sha1 and mdc2.
+This option also applies to CRLs.
+
+=item B<-policy arg>
+
+this option defines the CA "policy" to use. This is a section in
+the configuration file which decides which fields should be mandatory
+or match the CA certificate. Check out the B<POLICY FORMAT> section
+for more information.
+
+=item B<-msie_hack>
+
+this is a legacy option to make B<ca> work with very old versions of
+the IE certificate enrollment control "certenr3". It used UniversalStrings
+for almost everything. Since the old control has various security bugs
+its use is strongly discouraged. The newer control "Xenroll" does not
+need this option.
+
+=item B<-preserveDN>
+
+Normally the DN order of a certificate is the same as the order of the
+fields in the relevant policy section. When this option is set the order 
+is the same as the request. This is largely for compatibility with the
+older IE enrollment control which would only accept certificates if their
+DNs match the order of the request. This is not needed for Xenroll.
+
+=item B<-noemailDN>
+
+The DN of a certificate can contain the EMAIL field if present in the
+request DN, however it is good policy just having the e-mail set into
+the altName extension of the certificate. When this option is set the
+EMAIL field is removed from the certificate' subject and set only in
+the, eventually present, extensions. The B<email_in_dn> keyword can be
+used in the configuration file to enable this behaviour.
+
+=item B<-batch>
+
+this sets the batch mode. In this mode no questions will be asked
+and all certificates will be certified automatically.
+
+=item B<-extensions section>
+
+the section of the configuration file containing certificate extensions
+to be added when a certificate is issued (defaults to B<x509_extensions>
+unless the B<-extfile> option is used). If no extension section is
+present then, a V1 certificate is created. If the extension section
+is present (even if it is empty), then a V3 certificate is created. See the:w
+L<x509v3_config(5)|x509v3_config(5)> manual page for details of the
+extension section format.
+
+=item B<-extfile file>
+
+an additional configuration file to read certificate extensions from
+(using the default section unless the B<-extensions> option is also
+used).
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<ca>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=item B<-subj arg>
+
+supersedes subject name given in the request.
+The arg must be formatted as I</type0=value0/type1=value1/type2=...>,
+characters may be escaped by \ (backslash), no spaces are skipped.
+
+=item B<-utf8>
+
+this option causes field values to be interpreted as UTF8 strings, by 
+default they are interpreted as ASCII. This means that the field
+values, whether prompted from a terminal or obtained from a
+configuration file, must be valid UTF8 strings.
+
+=item B<-multivalue-rdn>
+
+this option causes the -subj argument to be interpretedt with full
+support for multivalued RDNs. Example:
+
+I</DC=org/DC=OpenSSL/DC=users/UID=123456+CN=John Doe>
+
+If -multi-rdn is not used then the UID value is I<123456+CN=John Doe>.
+
+=back
+
+=head1 CRL OPTIONS
+
+=over 4
+
+=item B<-gencrl>
+
+this option generates a CRL based on information in the index file.
+
+=item B<-crldays num>
+
+the number of days before the next CRL is due. That is the days from
+now to place in the CRL nextUpdate field.
+
+=item B<-crlhours num>
+
+the number of hours before the next CRL is due.
+
+=item B<-revoke filename>
+
+a filename containing a certificate to revoke.
+
+=item B<-crl_reason reason>
+
+revocation reason, where B<reason> is one of: B<unspecified>, B<keyCompromise>,
+B<CACompromise>, B<affiliationChanged>, B<superseded>, B<cessationOfOperation>,
+B<certificateHold> or B<removeFromCRL>. The matching of B<reason> is case
+insensitive. Setting any revocation reason will make the CRL v2.
+
+In practive B<removeFromCRL> is not particularly useful because it is only used
+in delta CRLs which are not currently implemented.
+
+=item B<-crl_hold instruction>
+
+This sets the CRL revocation reason code to B<certificateHold> and the hold
+instruction to B<instruction> which must be an OID. Although any OID can be
+used only B<holdInstructionNone> (the use of which is discouraged by RFC2459)
+B<holdInstructionCallIssuer> or B<holdInstructionReject> will normally be used.
+
+=item B<-crl_compromise time>
+
+This sets the revocation reason to B<keyCompromise> and the compromise time to
+B<time>. B<time> should be in GeneralizedTime format that is B<YYYYMMDDHHMMSSZ>.
+
+=item B<-crl_CA_compromise time>
+
+This is the same as B<crl_compromise> except the revocation reason is set to
+B<CACompromise>.
+
+=item B<-crlexts section>
+
+the section of the configuration file containing CRL extensions to
+include. If no CRL extension section is present then a V1 CRL is
+created, if the CRL extension section is present (even if it is
+empty) then a V2 CRL is created. The CRL extensions specified are
+CRL extensions and B<not> CRL entry extensions.  It should be noted
+that some software (for example Netscape) can't handle V2 CRLs. See
+L<x509v3_config(5)|x509v3_config(5)> manual page for details of the
+extension section format.
+
+=back
+
+=head1 CONFIGURATION FILE OPTIONS
+
+The section of the configuration file containing options for B<ca>
+is found as follows: If the B<-name> command line option is used,
+then it names the section to be used. Otherwise the section to
+be used must be named in the B<default_ca> option of the B<ca> section
+of the configuration file (or in the default section of the
+configuration file). Besides B<default_ca>, the following options are
+read directly from the B<ca> section:
+ RANDFILE
+ preserve
+ msie_hack
+With the exception of B<RANDFILE>, this is probably a bug and may
+change in future releases.
+
+Many of the configuration file options are identical to command line
+options. Where the option is present in the configuration file
+and the command line the command line value is used. Where an
+option is described as mandatory then it must be present in
+the configuration file or the command line equivalent (if
+any) used.
+
+=over 4
+
+=item B<oid_file>
+
+This specifies a file containing additional B<OBJECT IDENTIFIERS>.
+Each line of the file should consist of the numerical form of the
+object identifier followed by white space then the short name followed
+by white space and finally the long name. 
+
+=item B<oid_section>
+
+This specifies a section in the configuration file containing extra
+object identifiers. Each line should consist of the short name of the
+object identifier followed by B<=> and the numerical form. The short
+and long names are the same when this option is used.
+
+=item B<new_certs_dir>
+
+the same as the B<-outdir> command line option. It specifies
+the directory where new certificates will be placed. Mandatory.
+
+=item B<certificate>
+
+the same as B<-cert>. It gives the file containing the CA
+certificate. Mandatory.
+
+=item B<private_key>
+
+same as the B<-keyfile> option. The file containing the
+CA private key. Mandatory.
+
+=item B<RANDFILE>
+
+a file used to read and write random number seed information, or
+an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
+
+=item B<default_days>
+
+the same as the B<-days> option. The number of days to certify
+a certificate for. 
+
+=item B<default_startdate>
+
+the same as the B<-startdate> option. The start date to certify
+a certificate for. If not set the current time is used.
+
+=item B<default_enddate>
+
+the same as the B<-enddate> option. Either this option or
+B<default_days> (or the command line equivalents) must be
+present.
+
+=item B<default_crl_hours default_crl_days>
+
+the same as the B<-crlhours> and the B<-crldays> options. These
+will only be used if neither command line option is present. At
+least one of these must be present to generate a CRL.
+
+=item B<default_md>
+
+the same as the B<-md> option. The message digest to use. Mandatory.
+
+=item B<database>
+
+the text database file to use. Mandatory. This file must be present
+though initially it will be empty.
+
+=item B<unique_subject>
+
+if the value B<yes> is given, the valid certificate entries in the
+database must have unique subjects.  if the value B<no> is given,
+several valid certificate entries may have the exact same subject.
+The default value is B<yes>, to be compatible with older (pre 0.9.8)
+versions of OpenSSL.  However, to make CA certificate roll-over easier,
+it's recommended to use the value B<no>, especially if combined with
+the B<-selfsign> command line option.
+
+=item B<serial>
+
+a text file containing the next serial number to use in hex. Mandatory.
+This file must be present and contain a valid serial number.
+
+=item B<crlnumber>
+
+a text file containing the next CRL number to use in hex. The crl number
+will be inserted in the CRLs only if this file exists. If this file is
+present, it must contain a valid CRL number.
+
+=item B<x509_extensions>
+
+the same as B<-extensions>.
+
+=item B<crl_extensions>
+
+the same as B<-crlexts>.
+
+=item B<preserve>
+
+the same as B<-preserveDN>
+
+=item B<email_in_dn>
+
+the same as B<-noemailDN>. If you want the EMAIL field to be removed
+from the DN of the certificate simply set this to 'no'. If not present
+the default is to allow for the EMAIL filed in the certificate's DN.
+
+=item B<msie_hack>
+
+the same as B<-msie_hack>
+
+=item B<policy>
+
+the same as B<-policy>. Mandatory. See the B<POLICY FORMAT> section
+for more information.
+
+=item B<name_opt>, B<cert_opt>
+
+these options allow the format used to display the certificate details
+when asking the user to confirm signing. All the options supported by
+the B<x509> utilities B<-nameopt> and B<-certopt> switches can be used
+here, except the B<no_signame> and B<no_sigdump> are permanently set
+and cannot be disabled (this is because the certificate signature cannot
+be displayed because the certificate has not been signed at this point).
+
+For convenience the values B<ca_default> are accepted by both to produce
+a reasonable output.
+
+If neither option is present the format used in earlier versions of
+OpenSSL is used. Use of the old format is B<strongly> discouraged because
+it only displays fields mentioned in the B<policy> section, mishandles
+multicharacter string types and does not display extensions.
+
+=item B<copy_extensions>
+
+determines how extensions in certificate requests should be handled.
+If set to B<none> or this option is not present then extensions are
+ignored and not copied to the certificate. If set to B<copy> then any
+extensions present in the request that are not already present are copied
+to the certificate. If set to B<copyall> then all extensions in the
+request are copied to the certificate: if the extension is already present
+in the certificate it is deleted first. See the B<WARNINGS> section before
+using this option.
+
+The main use of this option is to allow a certificate request to supply
+values for certain extensions such as subjectAltName.
+
+=back
+
+=head1 POLICY FORMAT
+
+The policy section consists of a set of variables corresponding to
+certificate DN fields. If the value is "match" then the field value
+must match the same field in the CA certificate. If the value is
+"supplied" then it must be present. If the value is "optional" then
+it may be present. Any fields not mentioned in the policy section
+are silently deleted, unless the B<-preserveDN> option is set but
+this can be regarded more of a quirk than intended behaviour.
+
+=head1 SPKAC FORMAT
+
+The input to the B<-spkac> command line option is a Netscape
+signed public key and challenge. This will usually come from
+the B<KEYGEN> tag in an HTML form to create a new private key. 
+It is however possible to create SPKACs using the B<spkac> utility.
+
+The file should contain the variable SPKAC set to the value of
+the SPKAC and also the required DN components as name value pairs.
+If you need to include the same component twice then it can be
+preceded by a number and a '.'.
+
+=head1 EXAMPLES
+
+Note: these examples assume that the B<ca> directory structure is
+already set up and the relevant files already exist. This usually
+involves creating a CA certificate and private key with B<req>, a
+serial number file and an empty index file and placing them in
+the relevant directories.
+
+To use the sample configuration file below the directories demoCA,
+demoCA/private and demoCA/newcerts would be created. The CA
+certificate would be copied to demoCA/cacert.pem and its private
+key to demoCA/private/cakey.pem. A file demoCA/serial would be
+created containing for example "01" and the empty index file
+demoCA/index.txt.
+
+
+Sign a certificate request:
+
+ openssl ca -in req.pem -out newcert.pem
+
+Sign a certificate request, using CA extensions:
+
+ openssl ca -in req.pem -extensions v3_ca -out newcert.pem
+
+Generate a CRL
+
+ openssl ca -gencrl -out crl.pem
+
+Sign several requests:
+
+ openssl ca -infiles req1.pem req2.pem req3.pem
+
+Certify a Netscape SPKAC:
+
+ openssl ca -spkac spkac.txt
+
+A sample SPKAC file (the SPKAC line has been truncated for clarity):
+
+ SPKAC=MIG0MGAwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAn7PDhCeV/xIxUg8V70YRxK2A5
+ CN=Steve Test
+ emailAddress=steve@openssl.org
+ 0.OU=OpenSSL Group
+ 1.OU=Another Group
+
+A sample configuration file with the relevant sections for B<ca>:
+
+ [ ca ]
+ default_ca      = CA_default            # The default ca section
+ 
+ [ CA_default ]
+
+ dir            = ./demoCA              # top dir
+ database       = $dir/index.txt        # index file.
+ new_certs_dir	= $dir/newcerts         # new certs dir
+ 
+ certificate    = $dir/cacert.pem       # The CA cert
+ serial         = $dir/serial           # serial no file
+ private_key    = $dir/private/cakey.pem# CA private key
+ RANDFILE       = $dir/private/.rand    # random number file
+ 
+ default_days   = 365                   # how long to certify for
+ default_crl_days= 30                   # how long before next CRL
+ default_md     = md5                   # md to use
+
+ policy         = policy_any            # default policy
+ email_in_dn    = no                    # Don't add the email into cert DN
+
+ name_opt	= ca_default		# Subject name display option
+ cert_opt	= ca_default		# Certificate display option
+ copy_extensions = none			# Don't copy extensions from request
+
+ [ policy_any ]
+ countryName            = supplied
+ stateOrProvinceName    = optional
+ organizationName       = optional
+ organizationalUnitName = optional
+ commonName             = supplied
+ emailAddress           = optional
+
+=head1 FILES
+
+Note: the location of all files can change either by compile time options,
+configuration file entries, environment variables or command line options.
+The values below reflect the default values.
+
+ /usr/local/ssl/lib/openssl.cnf - master configuration file
+ ./demoCA                       - main CA directory
+ ./demoCA/cacert.pem            - CA certificate
+ ./demoCA/private/cakey.pem     - CA private key
+ ./demoCA/serial                - CA serial number file
+ ./demoCA/serial.old            - CA serial number backup file
+ ./demoCA/index.txt             - CA text database file
+ ./demoCA/index.txt.old         - CA text database backup file
+ ./demoCA/certs                 - certificate output file
+ ./demoCA/.rnd                  - CA random seed information
+
+=head1 ENVIRONMENT VARIABLES
+
+B<OPENSSL_CONF> reflects the location of master configuration file it can
+be overridden by the B<-config> command line option.
+
+=head1 RESTRICTIONS
+
+The text database index file is a critical part of the process and 
+if corrupted it can be difficult to fix. It is theoretically possible
+to rebuild the index file from all the issued certificates and a current
+CRL: however there is no option to do this.
+
+V2 CRL features like delta CRLs are not currently supported.
+
+Although several requests can be input and handled at once it is only
+possible to include one SPKAC or self signed certificate.
+
+=head1 BUGS
+
+The use of an in memory text database can cause problems when large
+numbers of certificates are present because, as the name implies
+the database has to be kept in memory.
+
+The B<ca> command really needs rewriting or the required functionality
+exposed at either a command or interface level so a more friendly utility
+(perl script or GUI) can handle things properly. The scripts B<CA.sh> and
+B<CA.pl> help a little but not very much.
+
+Any fields in a request that are not present in a policy are silently
+deleted. This does not happen if the B<-preserveDN> option is used. To
+enforce the absence of the EMAIL field within the DN, as suggested by
+RFCs, regardless the contents of the request' subject the B<-noemailDN>
+option can be used. The behaviour should be more friendly and
+configurable.
+
+Cancelling some commands by refusing to certify a certificate can
+create an empty file.
+
+=head1 WARNINGS
+
+The B<ca> command is quirky and at times downright unfriendly.
+
+The B<ca> utility was originally meant as an example of how to do things
+in a CA. It was not supposed to be used as a full blown CA itself:
+nevertheless some people are using it for this purpose.
+
+The B<ca> command is effectively a single user command: no locking is
+done on the various files and attempts to run more than one B<ca> command
+on the same database can have unpredictable results.
+
+The B<copy_extensions> option should be used with caution. If care is
+not taken then it can be a security risk. For example if a certificate
+request contains a basicConstraints extension with CA:TRUE and the
+B<copy_extensions> value is set to B<copyall> and the user does not spot
+this when the certificate is displayed then this will hand the requestor
+a valid CA certificate.
+
+This situation can be avoided by setting B<copy_extensions> to B<copy>
+and including basicConstraints with CA:FALSE in the configuration file.
+Then if the request contains a basicConstraints extension it will be
+ignored.
+
+It is advisable to also include values for other extensions such
+as B<keyUsage> to prevent a request supplying its own values.
+
+Additional restrictions can be placed on the CA certificate itself.
+For example if the CA certificate has:
+
+ basicConstraints = CA:TRUE, pathlen:0
+
+then even if a certificate is issued with CA:TRUE it will not be valid.
+
+=head1 SEE ALSO
+
+L<req(1)|req(1)>, L<spkac(1)|spkac(1)>, L<x509(1)|x509(1)>, L<CA.pl(1)|CA.pl(1)>,
+L<config(5)|config(5)>, L<x509v3_config(5)|x509v3_config(5)> 
+
+=cut
diff --git a/openssl/doc/apps/ciphers.pod b/openssl/doc/apps/ciphers.pod
new file mode 100644
index 0000000..f44aa00
--- /dev/null
+++ b/openssl/doc/apps/ciphers.pod
@@ -0,0 +1,478 @@
+=pod
+
+=head1 NAME
+
+ciphers - SSL cipher display and cipher list tool.
+
+=head1 SYNOPSIS
+
+B<openssl> B<ciphers>
+[B<-v>]
+[B<-V>]
+[B<-ssl2>]
+[B<-ssl3>]
+[B<-tls1>]
+[B<cipherlist>]
+
+=head1 DESCRIPTION
+
+The B<ciphers> command converts textual OpenSSL cipher lists into ordered
+SSL cipher preference lists. It can be used as a test tool to determine
+the appropriate cipherlist.
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<-v>
+
+Verbose option. List ciphers with a complete description of
+protocol version (SSLv2 or SSLv3; the latter includes TLS), key exchange,
+authentication, encryption and mac algorithms used along with any key size
+restrictions and whether the algorithm is classed as an "export" cipher.
+Note that without the B<-v> option, ciphers may seem to appear twice
+in a cipher list; this is when similar ciphers are available for
+SSL v2 and for SSL v3/TLS v1.
+
+=item B<-V>
+
+Like B<-V>, but include cipher suite codes in output (hex format).
+
+=item B<-ssl3>
+
+only include SSL v3 ciphers.
+
+=item B<-ssl2>
+
+only include SSL v2 ciphers.
+
+=item B<-tls1>
+
+only include TLS v1 ciphers.
+
+=item B<-h>, B<-?>
+
+print a brief usage message.
+
+=item B<cipherlist>
+
+a cipher list to convert to a cipher preference list. If it is not included
+then the default cipher list will be used. The format is described below.
+
+=back
+
+=head1 CIPHER LIST FORMAT
+
+The cipher list consists of one or more I<cipher strings> separated by colons.
+Commas or spaces are also acceptable separators but colons are normally used.
+
+The actual cipher string can take several different forms.
+
+It can consist of a single cipher suite such as B<RC4-SHA>.
+
+It can represent a list of cipher suites containing a certain algorithm, or
+cipher suites of a certain type. For example B<SHA1> represents all ciphers
+suites using the digest algorithm SHA1 and B<SSLv3> represents all SSL v3
+algorithms.
+
+Lists of cipher suites can be combined in a single cipher string using the
+B<+> character. This is used as a logical B<and> operation. For example
+B<SHA1+DES> represents all cipher suites containing the SHA1 B<and> the DES
+algorithms.
+
+Each cipher string can be optionally preceded by the characters B<!>,
+B<-> or B<+>.
+
+If B<!> is used then the ciphers are permanently deleted from the list.
+The ciphers deleted can never reappear in the list even if they are
+explicitly stated.
+
+If B<-> is used then the ciphers are deleted from the list, but some or
+all of the ciphers can be added again by later options.
+
+If B<+> is used then the ciphers are moved to the end of the list. This
+option doesn't add any new ciphers it just moves matching existing ones.
+
+If none of these characters is present then the string is just interpreted
+as a list of ciphers to be appended to the current preference list. If the
+list includes any ciphers already present they will be ignored: that is they
+will not moved to the end of the list.
+
+Additionally the cipher string B<@STRENGTH> can be used at any point to sort
+the current cipher list in order of encryption algorithm key length.
+
+=head1 CIPHER STRINGS
+
+The following is a list of all permitted cipher strings and their meanings.
+
+=over 4
+
+=item B<DEFAULT>
+
+the default cipher list. This is determined at compile time and, as of OpenSSL
+1.0.0, is normally B<ALL:!aNULL:!eNULL>. This must be the first cipher string
+specified.
+
+=item B<COMPLEMENTOFDEFAULT>
+
+the ciphers included in B<ALL>, but not enabled by default. Currently
+this is B<ADH>. Note that this rule does not cover B<eNULL>, which is
+not included by B<ALL> (use B<COMPLEMENTOFALL> if necessary).
+
+=item B<ALL>
+
+all cipher suites except the B<eNULL> ciphers which must be explicitly enabled;
+as of OpenSSL, the B<ALL> cipher suites are reasonably ordered by default
+
+=item B<COMPLEMENTOFALL>
+
+the cipher suites not enabled by B<ALL>, currently being B<eNULL>.
+
+=item B<HIGH>
+
+"high" encryption cipher suites. This currently means those with key lengths larger
+than 128 bits, and some cipher suites with 128-bit keys.
+
+=item B<MEDIUM>
+
+"medium" encryption cipher suites, currently some of those using 128 bit encryption.
+
+=item B<LOW>
+
+"low" encryption cipher suites, currently those using 64 or 56 bit encryption algorithms
+but excluding export cipher suites.
+
+=item B<EXP>, B<EXPORT>
+
+export encryption algorithms. Including 40 and 56 bits algorithms.
+
+=item B<EXPORT40>
+
+40 bit export encryption algorithms
+
+=item B<EXPORT56>
+
+56 bit export encryption algorithms. In OpenSSL 0.9.8c and later the set of
+56 bit export ciphers is empty unless OpenSSL has been explicitly configured
+with support for experimental ciphers.
+
+=item B<eNULL>, B<NULL>
+
+the "NULL" ciphers that is those offering no encryption. Because these offer no
+encryption at all and are a security risk they are disabled unless explicitly
+included.
+
+=item B<aNULL>
+
+the cipher suites offering no authentication. This is currently the anonymous
+DH algorithms. These cipher suites are vulnerable to a "man in the middle"
+attack and so their use is normally discouraged.
+
+=item B<kRSA>, B<RSA>
+
+cipher suites using RSA key exchange.
+
+=item B<kEDH>
+
+cipher suites using ephemeral DH key agreement.
+
+=item B<kDHr>, B<kDHd>
+
+cipher suites using DH key agreement and DH certificates signed by CAs with RSA
+and DSS keys respectively. Not implemented.
+
+=item B<aRSA>
+
+cipher suites using RSA authentication, i.e. the certificates carry RSA keys.
+
+=item B<aDSS>, B<DSS>
+
+cipher suites using DSS authentication, i.e. the certificates carry DSS keys.
+
+=item B<aDH>
+
+cipher suites effectively using DH authentication, i.e. the certificates carry
+DH keys.  Not implemented.
+
+=item B<kFZA>, B<aFZA>, B<eFZA>, B<FZA>
+
+ciphers suites using FORTEZZA key exchange, authentication, encryption or all
+FORTEZZA algorithms. Not implemented.
+
+=item B<TLSv1>, B<SSLv3>, B<SSLv2>
+
+TLS v1.0, SSL v3.0 or SSL v2.0 cipher suites respectively.
+
+=item B<DH>
+
+cipher suites using DH, including anonymous DH.
+
+=item B<ADH>
+
+anonymous DH cipher suites.
+
+=item B<AES>
+
+cipher suites using AES.
+
+=item B<CAMELLIA>
+
+cipher suites using Camellia.
+
+=item B<3DES>
+
+cipher suites using triple DES.
+
+=item B<DES>
+
+cipher suites using DES (not triple DES).
+
+=item B<RC4>
+
+cipher suites using RC4.
+
+=item B<RC2>
+
+cipher suites using RC2.
+
+=item B<IDEA>
+
+cipher suites using IDEA.
+
+=item B<SEED>
+
+cipher suites using SEED.
+
+=item B<MD5>
+
+cipher suites using MD5.
+
+=item B<SHA1>, B<SHA>
+
+cipher suites using SHA1.
+
+=item B<aGOST> 
+
+cipher suites using GOST R 34.10 (either 2001 or 94) for authenticaction
+(needs an engine supporting GOST algorithms). 
+
+=item B<aGOST01>
+
+cipher suites using GOST R 34.10-2001 authentication.
+
+=item B<aGOST94>
+
+cipher suites using GOST R 34.10-94 authentication (note that R 34.10-94
+standard has been expired so use GOST R 34.10-2001)
+
+=item B<kGOST>
+
+cipher suites, using VKO 34.10 key exchange, specified in the RFC 4357.
+
+=item B<GOST94>
+
+cipher suites, using HMAC based on GOST R 34.11-94.
+
+=item B<GOST89MAC>
+
+cipher suites using GOST 28147-89 MAC B<instead of> HMAC.
+
+
+=back
+
+=head1 CIPHER SUITE NAMES
+
+The following lists give the SSL or TLS cipher suites names from the
+relevant specification and their OpenSSL equivalents. It should be noted,
+that several cipher suite names do not include the authentication used,
+e.g. DES-CBC3-SHA. In these cases, RSA authentication is used.
+
+=head2 SSL v3.0 cipher suites.
+
+ SSL_RSA_WITH_NULL_MD5                   NULL-MD5
+ SSL_RSA_WITH_NULL_SHA                   NULL-SHA
+ SSL_RSA_EXPORT_WITH_RC4_40_MD5          EXP-RC4-MD5
+ SSL_RSA_WITH_RC4_128_MD5                RC4-MD5
+ SSL_RSA_WITH_RC4_128_SHA                RC4-SHA
+ SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5      EXP-RC2-CBC-MD5
+ SSL_RSA_WITH_IDEA_CBC_SHA               IDEA-CBC-SHA
+ SSL_RSA_EXPORT_WITH_DES40_CBC_SHA       EXP-DES-CBC-SHA
+ SSL_RSA_WITH_DES_CBC_SHA                DES-CBC-SHA
+ SSL_RSA_WITH_3DES_EDE_CBC_SHA           DES-CBC3-SHA
+
+ SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA    Not implemented.
+ SSL_DH_DSS_WITH_DES_CBC_SHA             Not implemented.
+ SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA        Not implemented.
+ SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA    Not implemented.
+ SSL_DH_RSA_WITH_DES_CBC_SHA             Not implemented.
+ SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA        Not implemented.
+ SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA   EXP-EDH-DSS-DES-CBC-SHA
+ SSL_DHE_DSS_WITH_DES_CBC_SHA            EDH-DSS-CBC-SHA
+ SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA       EDH-DSS-DES-CBC3-SHA
+ SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA   EXP-EDH-RSA-DES-CBC-SHA
+ SSL_DHE_RSA_WITH_DES_CBC_SHA            EDH-RSA-DES-CBC-SHA
+ SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA       EDH-RSA-DES-CBC3-SHA
+
+ SSL_DH_anon_EXPORT_WITH_RC4_40_MD5      EXP-ADH-RC4-MD5
+ SSL_DH_anon_WITH_RC4_128_MD5            ADH-RC4-MD5
+ SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA   EXP-ADH-DES-CBC-SHA
+ SSL_DH_anon_WITH_DES_CBC_SHA            ADH-DES-CBC-SHA
+ SSL_DH_anon_WITH_3DES_EDE_CBC_SHA       ADH-DES-CBC3-SHA
+
+ SSL_FORTEZZA_KEA_WITH_NULL_SHA          Not implemented.
+ SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA  Not implemented.
+ SSL_FORTEZZA_KEA_WITH_RC4_128_SHA       Not implemented.
+
+=head2 TLS v1.0 cipher suites.
+
+ TLS_RSA_WITH_NULL_MD5                   NULL-MD5
+ TLS_RSA_WITH_NULL_SHA                   NULL-SHA
+ TLS_RSA_EXPORT_WITH_RC4_40_MD5          EXP-RC4-MD5
+ TLS_RSA_WITH_RC4_128_MD5                RC4-MD5
+ TLS_RSA_WITH_RC4_128_SHA                RC4-SHA
+ TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5      EXP-RC2-CBC-MD5
+ TLS_RSA_WITH_IDEA_CBC_SHA               IDEA-CBC-SHA
+ TLS_RSA_EXPORT_WITH_DES40_CBC_SHA       EXP-DES-CBC-SHA
+ TLS_RSA_WITH_DES_CBC_SHA                DES-CBC-SHA
+ TLS_RSA_WITH_3DES_EDE_CBC_SHA           DES-CBC3-SHA
+
+ TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA    Not implemented.
+ TLS_DH_DSS_WITH_DES_CBC_SHA             Not implemented.
+ TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA        Not implemented.
+ TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA    Not implemented.
+ TLS_DH_RSA_WITH_DES_CBC_SHA             Not implemented.
+ TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA        Not implemented.
+ TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA   EXP-EDH-DSS-DES-CBC-SHA
+ TLS_DHE_DSS_WITH_DES_CBC_SHA            EDH-DSS-CBC-SHA
+ TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA       EDH-DSS-DES-CBC3-SHA
+ TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA   EXP-EDH-RSA-DES-CBC-SHA
+ TLS_DHE_RSA_WITH_DES_CBC_SHA            EDH-RSA-DES-CBC-SHA
+ TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA       EDH-RSA-DES-CBC3-SHA
+
+ TLS_DH_anon_EXPORT_WITH_RC4_40_MD5      EXP-ADH-RC4-MD5
+ TLS_DH_anon_WITH_RC4_128_MD5            ADH-RC4-MD5
+ TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA   EXP-ADH-DES-CBC-SHA
+ TLS_DH_anon_WITH_DES_CBC_SHA            ADH-DES-CBC-SHA
+ TLS_DH_anon_WITH_3DES_EDE_CBC_SHA       ADH-DES-CBC3-SHA
+
+=head2 AES ciphersuites from RFC3268, extending TLS v1.0
+
+ TLS_RSA_WITH_AES_128_CBC_SHA            AES128-SHA
+ TLS_RSA_WITH_AES_256_CBC_SHA            AES256-SHA
+
+ TLS_DH_DSS_WITH_AES_128_CBC_SHA         Not implemented.
+ TLS_DH_DSS_WITH_AES_256_CBC_SHA         Not implemented.
+ TLS_DH_RSA_WITH_AES_128_CBC_SHA         Not implemented.
+ TLS_DH_RSA_WITH_AES_256_CBC_SHA         Not implemented.
+
+ TLS_DHE_DSS_WITH_AES_128_CBC_SHA        DHE-DSS-AES128-SHA
+ TLS_DHE_DSS_WITH_AES_256_CBC_SHA        DHE-DSS-AES256-SHA
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA        DHE-RSA-AES128-SHA
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA        DHE-RSA-AES256-SHA
+
+ TLS_DH_anon_WITH_AES_128_CBC_SHA        ADH-AES128-SHA
+ TLS_DH_anon_WITH_AES_256_CBC_SHA        ADH-AES256-SHA
+
+=head2 Camellia ciphersuites from RFC4132, extending TLS v1.0
+
+ TLS_RSA_WITH_CAMELLIA_128_CBC_SHA      CAMELLIA128-SHA
+ TLS_RSA_WITH_CAMELLIA_256_CBC_SHA      CAMELLIA256-SHA
+
+ TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA   Not implemented.
+ TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA   Not implemented.
+ TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA   Not implemented.
+ TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA   Not implemented.
+
+ TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA  DHE-DSS-CAMELLIA128-SHA
+ TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA  DHE-DSS-CAMELLIA256-SHA
+ TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA  DHE-RSA-CAMELLIA128-SHA
+ TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA  DHE-RSA-CAMELLIA256-SHA
+
+ TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA  ADH-CAMELLIA128-SHA
+ TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA  ADH-CAMELLIA256-SHA
+
+=head2 SEED ciphersuites from RFC4162, extending TLS v1.0
+
+ TLS_RSA_WITH_SEED_CBC_SHA              SEED-SHA
+
+ TLS_DH_DSS_WITH_SEED_CBC_SHA           Not implemented.
+ TLS_DH_RSA_WITH_SEED_CBC_SHA           Not implemented.
+
+ TLS_DHE_DSS_WITH_SEED_CBC_SHA          DHE-DSS-SEED-SHA
+ TLS_DHE_RSA_WITH_SEED_CBC_SHA          DHE-RSA-SEED-SHA
+
+ TLS_DH_anon_WITH_SEED_CBC_SHA          ADH-SEED-SHA
+
+=head2 GOST ciphersuites from draft-chudov-cryptopro-cptls, extending TLS v1.0
+
+Note: these ciphers require an engine which including GOST cryptographic
+algorithms, such as the B<ccgost> engine, included in the OpenSSL distribution.
+
+ TLS_GOSTR341094_WITH_28147_CNT_IMIT GOST94-GOST89-GOST89
+ TLS_GOSTR341001_WITH_28147_CNT_IMIT GOST2001-GOST89-GOST89
+ TLS_GOSTR341094_WITH_NULL_GOSTR3411 GOST94-NULL-GOST94
+ TLS_GOSTR341001_WITH_NULL_GOSTR3411 GOST2001-NULL-GOST94
+
+=head2 Additional Export 1024 and other cipher suites
+
+Note: these ciphers can also be used in SSL v3.
+
+ TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA     EXP1024-DES-CBC-SHA
+ TLS_RSA_EXPORT1024_WITH_RC4_56_SHA      EXP1024-RC4-SHA
+ TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA EXP1024-DHE-DSS-DES-CBC-SHA
+ TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA  EXP1024-DHE-DSS-RC4-SHA
+ TLS_DHE_DSS_WITH_RC4_128_SHA            DHE-DSS-RC4-SHA
+
+=head2 SSL v2.0 cipher suites.
+
+ SSL_CK_RC4_128_WITH_MD5                 RC4-MD5
+ SSL_CK_RC4_128_EXPORT40_WITH_MD5        EXP-RC4-MD5
+ SSL_CK_RC2_128_CBC_WITH_MD5             RC2-MD5
+ SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5    EXP-RC2-MD5
+ SSL_CK_IDEA_128_CBC_WITH_MD5            IDEA-CBC-MD5
+ SSL_CK_DES_64_CBC_WITH_MD5              DES-CBC-MD5
+ SSL_CK_DES_192_EDE3_CBC_WITH_MD5        DES-CBC3-MD5
+
+=head1 NOTES
+
+The non-ephemeral DH modes are currently unimplemented in OpenSSL
+because there is no support for DH certificates.
+
+Some compiled versions of OpenSSL may not include all the ciphers
+listed here because some ciphers were excluded at compile time.
+
+=head1 EXAMPLES
+
+Verbose listing of all OpenSSL ciphers including NULL ciphers:
+
+ openssl ciphers -v 'ALL:eNULL'
+
+Include all ciphers except NULL and anonymous DH then sort by
+strength:
+
+ openssl ciphers -v 'ALL:!ADH:@STRENGTH'
+
+Include only 3DES ciphers and then place RSA ciphers last:
+
+ openssl ciphers -v '3DES:+RSA'
+
+Include all RC4 ciphers but leave out those without authentication:
+
+ openssl ciphers -v 'RC4:!COMPLEMENTOFDEFAULT'
+
+Include all chiphers with RSA authentication but leave out ciphers without
+encryption.
+
+ openssl ciphers -v 'RSA:!COMPLEMENTOFALL'
+
+=head1 SEE ALSO
+
+L<s_client(1)|s_client(1)>, L<s_server(1)|s_server(1)>, L<ssl(3)|ssl(3)>
+
+=head1 HISTORY
+
+The B<COMPLENTOFALL> and B<COMPLEMENTOFDEFAULT> selection options
+for cipherlist strings were added in OpenSSL 0.9.7.
+The B<-V> option for the B<ciphers> command was added in OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/apps/cms.pod b/openssl/doc/apps/cms.pod
new file mode 100644
index 0000000..a09588a
--- /dev/null
+++ b/openssl/doc/apps/cms.pod
@@ -0,0 +1,602 @@
+=pod
+
+=head1 NAME
+
+cms - CMS utility
+
+=head1 SYNOPSIS
+
+B<openssl> B<cms>
+[B<-encrypt>]
+[B<-decrypt>]
+[B<-sign>]
+[B<-verify>]
+[B<-cmsout>]
+[B<-resign>]
+[B<-data_create>]
+[B<-data_out>]
+[B<-digest_create>]
+[B<-digest_verify>]
+[B<-compress>]
+[B<-uncompress>]
+[B<-EncryptedData_encrypt>]
+[B<-sign_receipt>]
+[B<-verify_receipt receipt>]
+[B<-in filename>]
+[B<-inform SMIME|PEM|DER>]
+[B<-rctform SMIME|PEM|DER>]
+[B<-out filename>]
+[B<-outform SMIME|PEM|DER>]
+[B<-stream -indef -noindef>]
+[B<-noindef>]
+[B<-content filename>]
+[B<-text>]
+[B<-noout>]
+[B<-print>]
+[B<-CAfile file>]
+[B<-CApath dir>]
+[B<-md digest>]
+[B<-[cipher]>]
+[B<-nointern>]
+[B<-no_signer_cert_verify>]
+[B<-nocerts>]
+[B<-noattr>]
+[B<-nosmimecap>]
+[B<-binary>]
+[B<-nodetach>]
+[B<-certfile file>]
+[B<-certsout file>]
+[B<-signer file>]
+[B<-recip file>]
+[B<-keyid>]
+[B<-receipt_request_all -receipt_request_first>]
+[B<-receipt_request_from emailaddress>]
+[B<-receipt_request_to emailaddress>]
+[B<-receipt_request_print>]
+[B<-secretkey key>]
+[B<-secretkeyid id>]
+[B<-econtent_type type>]
+[B<-inkey file>]
+[B<-passin arg>]
+[B<-rand file(s)>]
+[B<cert.pem...>]
+[B<-to addr>]
+[B<-from addr>]
+[B<-subject subj>]
+[cert.pem]...
+
+=head1 DESCRIPTION
+
+The B<cms> command handles S/MIME v3.1 mail. It can encrypt, decrypt, sign and
+verify, compress and uncompress S/MIME messages.
+
+=head1 COMMAND OPTIONS
+
+There are fourteen operation options that set the type of operation to be
+performed. The meaning of the other options varies according to the operation
+type.
+
+=over 4
+
+=item B<-encrypt>
+
+encrypt mail for the given recipient certificates. Input file is the message
+to be encrypted. The output file is the encrypted mail in MIME format. The
+actual CMS type is <B>EnvelopedData<B>.
+
+=item B<-decrypt>
+
+decrypt mail using the supplied certificate and private key. Expects an
+encrypted mail message in MIME format for the input file. The decrypted mail
+is written to the output file.
+
+=item B<-sign>
+
+sign mail using the supplied certificate and private key. Input file is
+the message to be signed. The signed message in MIME format is written
+to the output file.
+
+=item B<-verify>
+
+verify signed mail. Expects a signed mail message on input and outputs
+the signed data. Both clear text and opaque signing is supported.
+
+=item B<-cmsout>
+
+takes an input message and writes out a PEM encoded CMS structure.
+
+=item B<-resign>
+
+resign a message: take an existing message and one or more new signers.
+
+=item B<-data_create>
+
+Create a CMS B<Data> type.
+
+=item B<-data_out>
+
+B<Data> type and output the content.
+
+=item B<-digest_create>
+
+Create a CMS B<DigestedData> type.
+
+=item B<-digest_verify>
+
+Verify a CMS B<DigestedData> type and output the content.
+
+=item B<-compress>
+
+Create a CMS B<CompressedData> type. OpenSSL must be compiled with B<zlib>
+support for this option to work, otherwise it will output an error.
+
+=item B<-uncompress>
+
+Uncompress a CMS B<CompressedData> type and output the content. OpenSSL must be
+compiled with B<zlib> support for this option to work, otherwise it will
+output an error.
+
+=item B<-EncryptedData_encrypt>
+
+Encrypt suppled content using supplied symmetric key and algorithm using a CMS
+B<EncrytedData> type and output the content.
+
+=item B<-sign_receipt>
+
+Generate and output a signed receipt for the supplied message. The input 
+message B<must> contain a signed receipt request. Functionality is otherwise
+similar to the B<-sign> operation.
+
+=item B<-verify_receipt receipt>
+
+Verify a signed receipt in filename B<receipt>. The input message B<must> 
+contain the original receipt request. Functionality is otherwise similar
+to the B<-verify> operation.
+
+=item B<-in filename>
+
+the input message to be encrypted or signed or the message to be decrypted
+or verified.
+
+=item B<-inform SMIME|PEM|DER>
+
+this specifies the input format for the CMS structure. The default
+is B<SMIME> which reads an S/MIME format message. B<PEM> and B<DER>
+format change this to expect PEM and DER format CMS structures
+instead. This currently only affects the input format of the CMS
+structure, if no CMS structure is being input (for example with
+B<-encrypt> or B<-sign>) this option has no effect.
+
+=item B<-rctform SMIME|PEM|DER>
+
+specify the format for a signed receipt for use with the B<-receipt_verify>
+operation.
+
+=item B<-out filename>
+
+the message text that has been decrypted or verified or the output MIME
+format message that has been signed or verified.
+
+=item B<-outform SMIME|PEM|DER>
+
+this specifies the output format for the CMS structure. The default
+is B<SMIME> which writes an S/MIME format message. B<PEM> and B<DER>
+format change this to write PEM and DER format CMS structures
+instead. This currently only affects the output format of the CMS
+structure, if no CMS structure is being output (for example with
+B<-verify> or B<-decrypt>) this option has no effect.
+
+=item B<-stream -indef -noindef>
+
+the B<-stream> and B<-indef> options are equivalent and enable streaming I/O
+for encoding operations. This permits single pass processing of data without
+the need to hold the entire contents in memory, potentially supporting very
+large files. Streaming is automatically set for S/MIME signing with detached
+data if the output format is B<SMIME> it is currently off by default for all
+other operations.
+
+=item B<-noindef>
+
+disable streaming I/O where it would produce and indefinite length constructed
+encoding. This option currently has no effect. In future streaming will be
+enabled by default on all relevant operations and this option will disable it.
+
+=item B<-content filename>
+
+This specifies a file containing the detached content, this is only
+useful with the B<-verify> command. This is only usable if the CMS
+structure is using the detached signature form where the content is
+not included. This option will override any content if the input format
+is S/MIME and it uses the multipart/signed MIME content type.
+
+=item B<-text>
+
+this option adds plain text (text/plain) MIME headers to the supplied
+message if encrypting or signing. If decrypting or verifying it strips
+off text headers: if the decrypted or verified message is not of MIME 
+type text/plain then an error occurs.
+
+=item B<-noout>
+
+for the B<-cmsout> operation do not output the parsed CMS structure. This
+is useful when combined with the B<-print> option or if the syntax of the CMS
+structure is being checked.
+
+=item B<-print>
+
+for the B<-cmsout> operation print out all fields of the CMS structure. This
+is mainly useful for testing purposes.
+
+=item B<-CAfile file>
+
+a file containing trusted CA certificates, only used with B<-verify>.
+
+=item B<-CApath dir>
+
+a directory containing trusted CA certificates, only used with
+B<-verify>. This directory must be a standard certificate directory: that
+is a hash of each subject name (using B<x509 -hash>) should be linked
+to each certificate.
+
+=item B<-md digest>
+
+digest algorithm to use when signing or resigning. If not present then the
+default digest algorithm for the signing key will be used (usually SHA1).
+
+=item B<-[cipher]>
+
+the encryption algorithm to use. For example triple DES (168 bits) - B<-des3>
+or 256 bit AES - B<-aes256>. Any standard algorithm name (as used by the
+EVP_get_cipherbyname() function) can also be used preceded by a dash, for 
+example B<-aes_128_cbc>. See L<B<enc>|enc(1)> for a list of ciphers
+supported by your version of OpenSSL.
+
+If not specified triple DES is used. Only used with B<-encrypt> and 
+B<-EncryptedData_create> commands.
+
+=item B<-nointern>
+
+when verifying a message normally certificates (if any) included in
+the message are searched for the signing certificate. With this option
+only the certificates specified in the B<-certfile> option are used.
+The supplied certificates can still be used as untrusted CAs however.
+
+=item B<-no_signer_cert_verify>
+
+do not verify the signers certificate of a signed message.
+
+=item B<-nocerts>
+
+when signing a message the signer's certificate is normally included
+with this option it is excluded. This will reduce the size of the
+signed message but the verifier must have a copy of the signers certificate
+available locally (passed using the B<-certfile> option for example).
+
+=item B<-noattr>
+
+normally when a message is signed a set of attributes are included which
+include the signing time and supported symmetric algorithms. With this
+option they are not included.
+
+=item B<-nosmimecap>
+
+exclude the list of supported algorithms from signed attributes, other options
+such as signing time and content type are still included.
+
+=item B<-binary>
+
+normally the input message is converted to "canonical" format which is
+effectively using CR and LF as end of line: as required by the S/MIME
+specification. When this option is present no translation occurs. This
+is useful when handling binary data which may not be in MIME format.
+
+=item B<-nodetach>
+
+when signing a message use opaque signing: this form is more resistant
+to translation by mail relays but it cannot be read by mail agents that
+do not support S/MIME.  Without this option cleartext signing with
+the MIME type multipart/signed is used.
+
+=item B<-certfile file>
+
+allows additional certificates to be specified. When signing these will
+be included with the message. When verifying these will be searched for
+the signers certificates. The certificates should be in PEM format.
+
+=item B<-certsout file>
+
+any certificates contained in the message are written to B<file>.
+
+=item B<-signer file>
+
+a signing certificate when signing or resigning a message, this option can be
+used multiple times if more than one signer is required. If a message is being
+verified then the signers certificates will be written to this file if the
+verification was successful.
+
+=item B<-recip file>
+
+the recipients certificate when decrypting a message. This certificate
+must match one of the recipients of the message or an error occurs.
+
+=item B<-keyid>
+
+use subject key identifier to identify certificates instead of issuer name and
+serial number. The supplied certificate B<must> include a subject key
+identifier extension. Supported by B<-sign> and B<-encrypt> options.
+
+=item B<-receipt_request_all -receipt_request_first>
+
+for B<-sign> option include a signed receipt request. Indicate requests should
+be provided by all receipient or first tier recipients (those mailed directly
+and not from a mailing list). Ignored it B<-receipt_request_from> is included.
+
+=item B<-receipt_request_from emailaddress>
+
+for B<-sign> option include a signed receipt request. Add an explicit email
+address where receipts should be supplied.
+
+=item B<-receipt_request_to emailaddress>
+
+Add an explicit email address where signed receipts should be sent to. This 
+option B<must> but supplied if a signed receipt it requested.
+
+=item B<-receipt_request_print>
+
+For the B<-verify> operation print out the contents of any signed receipt
+requests.
+
+=item B<-secretkey key>
+
+specify symmetric key to use. The key must be supplied in hex format and be
+consistent with the algorithm used. Supported by the B<-EncryptedData_encrypt>
+B<-EncrryptedData_decrypt>, B<-encrypt> and B<-decrypt> options. When used
+with B<-encrypt> or B<-decrypt> the supplied key is used to wrap or unwrap the
+content encryption key using an AES key in the B<KEKRecipientInfo> type.
+
+=item B<-secretkeyid id>
+
+the key identifier for the supplied symmetric key for B<KEKRecipientInfo> type.
+This option B<must> be present if the B<-secretkey> option is used with
+B<-encrypt>. With B<-decrypt> operations the B<id> is used to locate the
+relevant key if it is not supplied then an attempt is used to decrypt any
+B<KEKRecipientInfo> structures.
+
+=item B<-econtent_type type>
+
+set the encapsulated content type to B<type> if not supplied the B<Data> type
+is used. The B<type> argument can be any valid OID name in either text or
+numerical format. 
+
+=item B<-inkey file>
+
+the private key to use when signing or decrypting. This must match the
+corresponding certificate. If this option is not specified then the
+private key must be included in the certificate file specified with
+the B<-recip> or B<-signer> file. When signing this option can be used
+multiple times to specify successive keys.
+
+=item B<-passin arg>
+
+the private key password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-rand file(s)>
+
+a file or files containing random data used to seed the random number
+generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
+Multiple files can be specified separated by a OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item B<cert.pem...>
+
+one or more certificates of message recipients: used when encrypting
+a message. 
+
+=item B<-to, -from, -subject>
+
+the relevant mail headers. These are included outside the signed
+portion of a message so they may be included manually. If signing
+then many S/MIME mail clients check the signers certificate's email
+address matches that specified in the From: address.
+
+=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig>
+
+Set various certificate chain valiadition option. See the
+L<B<verify>|verify(1)> manual page for details.
+
+=back
+
+=head1 NOTES
+
+The MIME message must be sent without any blank lines between the
+headers and the output. Some mail programs will automatically add
+a blank line. Piping the mail directly to sendmail is one way to
+achieve the correct format.
+
+The supplied message to be signed or encrypted must include the
+necessary MIME headers or many S/MIME clients wont display it
+properly (if at all). You can use the B<-text> option to automatically
+add plain text headers.
+
+A "signed and encrypted" message is one where a signed message is
+then encrypted. This can be produced by encrypting an already signed
+message: see the examples section.
+
+This version of the program only allows one signer per message but it
+will verify multiple signers on received messages. Some S/MIME clients
+choke if a message contains multiple signers. It is possible to sign
+messages "in parallel" by signing an already signed message.
+
+The options B<-encrypt> and B<-decrypt> reflect common usage in S/MIME
+clients. Strictly speaking these process CMS enveloped data: CMS
+encrypted data is used for other purposes.
+
+The B<-resign> option uses an existing message digest when adding a new
+signer. This means that attributes must be present in at least one existing
+signer using the same message digest or this operation will fail.
+
+The B<-stream> and B<-indef> options enable experimental streaming I/O support.
+As a result the encoding is BER using indefinite length constructed encoding
+and no longer DER. Streaming is supported for the B<-encrypt> operation and the
+B<-sign> operation if the content is not detached.
+
+Streaming is always used for the B<-sign> operation with detached data but
+since the content is no longer part of the CMS structure the encoding
+remains DER.
+
+=head1 EXIT CODES
+
+=over 4
+
+=item 0
+
+the operation was completely successfully.
+
+=item 1 
+
+an error occurred parsing the command options.
+
+=item 2
+
+one of the input files could not be read.
+
+=item 3
+
+an error occurred creating the CMS file or when reading the MIME
+message.
+
+=item 4
+
+an error occurred decrypting or verifying the message.
+
+=item 5
+
+the message was verified correctly but an error occurred writing out
+the signers certificates.
+
+=back
+
+=head1 COMPATIBILITY WITH PKCS#7 format.
+
+The B<smime> utility can only process the older B<PKCS#7> format. The B<cms>
+utility supports Cryptographic Message Syntax format. Use of some features
+will result in messages which cannot be processed by applications which only
+support the older format. These are detailed below.
+
+The use of the B<-keyid> option with B<-sign> or B<-encrypt>.
+
+The B<-outform PEM> option uses different headers.
+
+The B<-compress> option.
+
+The B<-secretkey> option when used with B<-encrypt>.
+
+Additionally the B<-EncryptedData_create> and B<-data_create> type cannot
+be processed by the older B<smime> command.
+
+=head1 EXAMPLES
+
+Create a cleartext signed message:
+
+ openssl cms -sign -in message.txt -text -out mail.msg \
+	-signer mycert.pem
+
+Create an opaque signed message
+
+ openssl cms -sign -in message.txt -text -out mail.msg -nodetach \
+	-signer mycert.pem
+
+Create a signed message, include some additional certificates and
+read the private key from another file:
+
+ openssl cms -sign -in in.txt -text -out mail.msg \
+	-signer mycert.pem -inkey mykey.pem -certfile mycerts.pem
+
+Create a signed message with two signers, use key identifier:
+
+ openssl cms -sign -in message.txt -text -out mail.msg \
+	-signer mycert.pem -signer othercert.pem -keyid
+
+Send a signed message under Unix directly to sendmail, including headers:
+
+ openssl cms -sign -in in.txt -text -signer mycert.pem \
+	-from steve@openssl.org -to someone@somewhere \
+	-subject "Signed message" | sendmail someone@somewhere
+
+Verify a message and extract the signer's certificate if successful:
+
+ openssl cms -verify -in mail.msg -signer user.pem -out signedtext.txt
+
+Send encrypted mail using triple DES:
+
+ openssl cms -encrypt -in in.txt -from steve@openssl.org \
+	-to someone@somewhere -subject "Encrypted message" \
+	-des3 user.pem -out mail.msg
+
+Sign and encrypt mail:
+
+ openssl cms -sign -in ml.txt -signer my.pem -text \
+	| openssl cms -encrypt -out mail.msg \
+	-from steve@openssl.org -to someone@somewhere \
+	-subject "Signed and Encrypted message" -des3 user.pem
+
+Note: the encryption command does not include the B<-text> option because the
+message being encrypted already has MIME headers.
+
+Decrypt mail:
+
+ openssl cms -decrypt -in mail.msg -recip mycert.pem -inkey key.pem
+
+The output from Netscape form signing is a PKCS#7 structure with the
+detached signature format. You can use this program to verify the
+signature by line wrapping the base64 encoded structure and surrounding
+it with:
+
+ -----BEGIN PKCS7-----
+ -----END PKCS7-----
+
+and using the command, 
+
+ openssl cms -verify -inform PEM -in signature.pem -content content.txt
+
+alternatively you can base64 decode the signature and use
+
+ openssl cms -verify -inform DER -in signature.der -content content.txt
+
+Create an encrypted message using 128 bit Camellia:
+
+ openssl cms -encrypt -in plain.txt -camellia128 -out mail.msg cert.pem
+
+Add a signer to an existing message:
+
+ openssl cms -resign -in mail.msg -signer newsign.pem -out mail2.msg
+
+=head1 BUGS
+
+The MIME parser isn't very clever: it seems to handle most messages that I've
+thrown at it but it may choke on others.
+
+The code currently will only write out the signer's certificate to a file: if
+the signer has a separate encryption certificate this must be manually
+extracted. There should be some heuristic that determines the correct
+encryption certificate.
+
+Ideally a database should be maintained of a certificates for each email
+address.
+
+The code doesn't currently take note of the permitted symmetric encryption
+algorithms as supplied in the SMIMECapabilities signed attribute. this means the
+user has to manually include the correct encryption algorithm. It should store
+the list of permitted ciphers in a database and only use those.
+
+No revocation checking is done on the signer's certificate.
+
+=head1 HISTORY
+
+The use of multiple B<-signer> options and the B<-resign> command were first
+added in OpenSSL 1.0.0
+
+
+=cut
diff --git a/openssl/doc/apps/config.pod b/openssl/doc/apps/config.pod
new file mode 100644
index 0000000..ace34b6
--- /dev/null
+++ b/openssl/doc/apps/config.pod
@@ -0,0 +1,279 @@
+
+=pod
+
+=for comment openssl_manual_section:5
+
+=head1 NAME
+
+config - OpenSSL CONF library configuration files
+
+=head1 DESCRIPTION
+
+The OpenSSL CONF library can be used to read configuration files.
+It is used for the OpenSSL master configuration file B<openssl.cnf>
+and in a few other places like B<SPKAC> files and certificate extension
+files for the B<x509> utility. OpenSSL applications can also use the
+CONF library for their own purposes.
+
+A configuration file is divided into a number of sections. Each section
+starts with a line B<[ section_name ]> and ends when a new section is
+started or end of file is reached. A section name can consist of
+alphanumeric characters and underscores.
+
+The first section of a configuration file is special and is referred
+to as the B<default> section this is usually unnamed and is from the
+start of file until the first named section. When a name is being looked up
+it is first looked up in a named section (if any) and then the
+default section.
+
+The environment is mapped onto a section called B<ENV>.
+
+Comments can be included by preceding them with the B<#> character
+
+Each section in a configuration file consists of a number of name and
+value pairs of the form B<name=value>
+
+The B<name> string can contain any alphanumeric characters as well as
+a few punctuation symbols such as B<.> B<,> B<;> and B<_>.
+
+The B<value> string consists of the string following the B<=> character
+until end of line with any leading and trailing white space removed.
+
+The value string undergoes variable expansion. This can be done by
+including the form B<$var> or B<${var}>: this will substitute the value
+of the named variable in the current section. It is also possible to
+substitute a value from another section using the syntax B<$section::name>
+or B<${section::name}>. By using the form B<$ENV::name> environment
+variables can be substituted. It is also possible to assign values to
+environment variables by using the name B<ENV::name>, this will work
+if the program looks up environment variables using the B<CONF> library
+instead of calling B<getenv()> directly.
+
+It is possible to escape certain characters by using any kind of quote
+or the B<\> character. By making the last character of a line a B<\>
+a B<value> string can be spread across multiple lines. In addition
+the sequences B<\n>, B<\r>, B<\b> and B<\t> are recognized.
+
+=head1 OPENSSL LIBRARY CONFIGURATION
+
+In OpenSSL 0.9.7 and later applications can automatically configure certain
+aspects of OpenSSL using the master OpenSSL configuration file, or optionally
+an alternative configuration file. The B<openssl> utility includes this
+functionality: any sub command uses the master OpenSSL configuration file
+unless an option is used in the sub command to use an alternative configuration
+file.
+
+To enable library configuration the default section needs to contain an 
+appropriate line which points to the main configuration section. The default
+name is B<openssl_conf> which is used by the B<openssl> utility. Other
+applications may use an alternative name such as B<myapplicaton_conf>.
+
+The configuration section should consist of a set of name value pairs which
+contain specific module configuration information. The B<name> represents
+the name of the I<configuration module> the meaning of the B<value> is 
+module specific: it may, for example, represent a further configuration
+section containing configuration module specific information. E.g.
+
+ openssl_conf = openssl_init
+
+ [openssl_init]
+
+ oid_section = new_oids
+ engines = engine_section
+
+ [new_oids]
+
+ ... new oids here ...
+
+ [engine_section]
+
+ ... engine stuff here ...
+
+Currently there are two configuration modules. One for ASN1 objects another
+for ENGINE configuration.
+
+=head2 ASN1 OBJECT CONFIGURATION MODULE
+
+This module has the name B<oid_section>. The value of this variable points
+to a section containing name value pairs of OIDs: the name is the OID short
+and long name, the value is the numerical form of the OID. Although some of
+the B<openssl> utility sub commands already have their own ASN1 OBJECT section
+functionality not all do. By using the ASN1 OBJECT configuration module
+B<all> the B<openssl> utility sub commands can see the new objects as well
+as any compliant applications. For example:
+
+ [new_oids]
+ 
+ some_new_oid = 1.2.3.4
+ some_other_oid = 1.2.3.5
+
+In OpenSSL 0.9.8 it is also possible to set the value to the long name followed
+by a comma and the numerical OID form. For example:
+
+ shortName = some object long name, 1.2.3.4
+
+=head2 ENGINE CONFIGURATION MODULE
+
+This ENGINE configuration module has the name B<engines>. The value of this
+variable points to a section containing further ENGINE configuration
+information.
+
+The section pointed to by B<engines> is a table of engine names (though see
+B<engine_id> below) and further sections containing configuration informations
+specific to each ENGINE.
+
+Each ENGINE specific section is used to set default algorithms, load
+dynamic, perform initialization and send ctrls. The actual operation performed
+depends on the I<command> name which is the name of the name value pair. The
+currently supported commands are listed below.
+
+For example:
+
+ [engine_section]
+
+ # Configure ENGINE named "foo"
+ foo = foo_section
+ # Configure ENGINE named "bar"
+ bar = bar_section
+
+ [foo_section]
+ ... foo ENGINE specific commands ...
+
+ [bar_section]
+ ... "bar" ENGINE specific commands ...
+
+The command B<engine_id> is used to give the ENGINE name. If used this 
+command must be first. For example:
+
+ [engine_section]
+ # This would normally handle an ENGINE named "foo"
+ foo = foo_section
+
+ [foo_section]
+ # Override default name and use "myfoo" instead.
+ engine_id = myfoo
+
+The command B<dynamic_path> loads and adds an ENGINE from the given path. It
+is equivalent to sending the ctrls B<SO_PATH> with the path argument followed
+by B<LIST_ADD> with value 2 and B<LOAD> to the dynamic ENGINE. If this is
+not the required behaviour then alternative ctrls can be sent directly
+to the dynamic ENGINE using ctrl commands.
+
+The command B<init> determines whether to initialize the ENGINE. If the value
+is B<0> the ENGINE will not be initialized, if B<1> and attempt it made to
+initialized the ENGINE immediately. If the B<init> command is not present
+then an attempt will be made to initialize the ENGINE after all commands in
+its section have been processed.
+
+The command B<default_algorithms> sets the default algorithms an ENGINE will
+supply using the functions B<ENGINE_set_default_string()>
+
+If the name matches none of the above command names it is assumed to be a
+ctrl command which is sent to the ENGINE. The value of the command is the 
+argument to the ctrl command. If the value is the string B<EMPTY> then no
+value is sent to the command.
+
+For example:
+
+
+ [engine_section]
+
+ # Configure ENGINE named "foo"
+ foo = foo_section
+
+ [foo_section]
+ # Load engine from DSO
+ dynamic_path = /some/path/fooengine.so
+ # A foo specific ctrl.
+ some_ctrl = some_value
+ # Another ctrl that doesn't take a value.
+ other_ctrl = EMPTY
+ # Supply all default algorithms
+ default_algorithms = ALL
+
+=head1 NOTES
+
+If a configuration file attempts to expand a variable that doesn't exist
+then an error is flagged and the file will not load. This can happen
+if an attempt is made to expand an environment variable that doesn't
+exist. For example in a previous version of OpenSSL the default OpenSSL
+master configuration file used the value of B<HOME> which may not be
+defined on non Unix systems and would cause an error.
+
+This can be worked around by including a B<default> section to provide
+a default value: then if the environment lookup fails the default value
+will be used instead. For this to work properly the default value must
+be defined earlier in the configuration file than the expansion. See
+the B<EXAMPLES> section for an example of how to do this.
+
+If the same variable exists in the same section then all but the last
+value will be silently ignored. In certain circumstances such as with
+DNs the same field may occur multiple times. This is usually worked
+around by ignoring any characters before an initial B<.> e.g.
+
+ 1.OU="My first OU"
+ 2.OU="My Second OU"
+
+=head1 EXAMPLES
+
+Here is a sample configuration file using some of the features
+mentioned above.
+
+ # This is the default section.
+ 
+ HOME=/temp
+ RANDFILE= ${ENV::HOME}/.rnd
+ configdir=$ENV::HOME/config
+
+ [ section_one ]
+
+ # We are now in section one.
+
+ # Quotes permit leading and trailing whitespace
+ any = " any variable name "
+
+ other = A string that can \
+ cover several lines \
+ by including \\ characters
+
+ message = Hello World\n
+
+ [ section_two ]
+
+ greeting = $section_one::message
+
+This next example shows how to expand environment variables safely.
+
+Suppose you want a variable called B<tmpfile> to refer to a
+temporary filename. The directory it is placed in can determined by
+the the B<TEMP> or B<TMP> environment variables but they may not be
+set to any value at all. If you just include the environment variable
+names and the variable doesn't exist then this will cause an error when
+an attempt is made to load the configuration file. By making use of the
+default section both values can be looked up with B<TEMP> taking 
+priority and B</tmp> used if neither is defined:
+
+ TMP=/tmp
+ # The above value is used if TMP isn't in the environment
+ TEMP=$ENV::TMP
+ # The above value is used if TEMP isn't in the environment
+ tmpfile=${ENV::TEMP}/tmp.filename
+
+=head1 BUGS
+
+Currently there is no way to include characters using the octal B<\nnn>
+form. Strings are all null terminated so nulls cannot form part of
+the value.
+
+The escaping isn't quite right: if you want to use sequences like B<\n>
+you can't use any quote escaping on the same line.
+
+Files are loaded in a single pass. This means that an variable expansion
+will only work if the variables referenced are defined earlier in the
+file.
+
+=head1 SEE ALSO
+
+L<x509(1)|x509(1)>, L<req(1)|req(1)>, L<ca(1)|ca(1)>
+
+=cut
diff --git a/openssl/doc/apps/crl.pod b/openssl/doc/apps/crl.pod
new file mode 100644
index 0000000..a40c873
--- /dev/null
+++ b/openssl/doc/apps/crl.pod
@@ -0,0 +1,117 @@
+=pod
+
+=head1 NAME
+
+crl - CRL utility
+
+=head1 SYNOPSIS
+
+B<openssl> B<crl>
+[B<-inform PEM|DER>]
+[B<-outform PEM|DER>]
+[B<-text>]
+[B<-in filename>]
+[B<-out filename>]
+[B<-noout>]
+[B<-hash>]
+[B<-issuer>]
+[B<-lastupdate>]
+[B<-nextupdate>]
+[B<-CAfile file>]
+[B<-CApath dir>]
+
+=head1 DESCRIPTION
+
+The B<crl> command processes CRL files in DER or PEM format.
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<-inform DER|PEM>
+
+This specifies the input format. B<DER> format is DER encoded CRL
+structure. B<PEM> (the default) is a base64 encoded version of
+the DER form with header and footer lines.
+
+=item B<-outform DER|PEM>
+
+This specifies the output format, the options have the same meaning as the 
+B<-inform> option.
+
+=item B<-in filename>
+
+This specifies the input filename to read from or standard input if this
+option is not specified.
+
+=item B<-out filename>
+
+specifies the output filename to write to or standard output by
+default.
+
+=item B<-text>
+
+print out the CRL in text form.
+
+=item B<-noout>
+
+don't output the encoded version of the CRL.
+
+=item B<-hash>
+
+output a hash of the issuer name. This can be use to lookup CRLs in
+a directory by issuer name.
+
+=item B<-issuer>
+
+output the issuer name.
+
+=item B<-lastupdate>
+
+output the lastUpdate field.
+
+=item B<-nextupdate>
+
+output the nextUpdate field.
+
+=item B<-CAfile file>
+
+verify the signature on a CRL by looking up the issuing certificate in
+B<file>
+
+=item B<-CApath dir>
+
+verify the signature on a CRL by looking up the issuing certificate in
+B<dir>. This directory must be a standard certificate directory: that
+is a hash of each subject name (using B<x509 -hash>) should be linked
+to each certificate.
+
+=back
+
+=head1 NOTES
+
+The PEM CRL format uses the header and footer lines:
+
+ -----BEGIN X509 CRL-----
+ -----END X509 CRL-----
+
+=head1 EXAMPLES
+
+Convert a CRL file from PEM to DER:
+
+ openssl crl -in crl.pem -outform DER -out crl.der
+
+Output the text form of a DER encoded certificate:
+
+ openssl crl -in crl.der -text -noout
+
+=head1 BUGS
+
+Ideally it should be possible to create a CRL using appropriate options
+and files too.
+
+=head1 SEE ALSO
+
+L<crl2pkcs7(1)|crl2pkcs7(1)>, L<ca(1)|ca(1)>, L<x509(1)|x509(1)>
+
+=cut
diff --git a/openssl/doc/apps/crl2pkcs7.pod b/openssl/doc/apps/crl2pkcs7.pod
new file mode 100644
index 0000000..3797bc0
--- /dev/null
+++ b/openssl/doc/apps/crl2pkcs7.pod
@@ -0,0 +1,91 @@
+=pod
+
+=head1 NAME
+
+crl2pkcs7 - Create a PKCS#7 structure from a CRL and certificates.
+
+=head1 SYNOPSIS
+
+B<openssl> B<crl2pkcs7>
+[B<-inform PEM|DER>]
+[B<-outform PEM|DER>]
+[B<-in filename>]
+[B<-out filename>]
+[B<-certfile filename>]
+[B<-nocrl>]
+
+=head1 DESCRIPTION
+
+The B<crl2pkcs7> command takes an optional CRL and one or more
+certificates and converts them into a PKCS#7 degenerate "certificates
+only" structure.
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<-inform DER|PEM>
+
+This specifies the CRL input format. B<DER> format is DER encoded CRL
+structure.B<PEM> (the default) is a base64 encoded version of
+the DER form with header and footer lines.
+
+=item B<-outform DER|PEM>
+
+This specifies the PKCS#7 structure output format. B<DER> format is DER
+encoded PKCS#7 structure.B<PEM> (the default) is a base64 encoded version of
+the DER form with header and footer lines.
+
+=item B<-in filename>
+
+This specifies the input filename to read a CRL from or standard input if this
+option is not specified.
+
+=item B<-out filename>
+
+specifies the output filename to write the PKCS#7 structure to or standard
+output by default.
+
+=item B<-certfile filename>
+
+specifies a filename containing one or more certificates in B<PEM> format.
+All certificates in the file will be added to the PKCS#7 structure. This
+option can be used more than once to read certificates form multiple
+files.
+
+=item B<-nocrl>
+
+normally a CRL is included in the output file. With this option no CRL is
+included in the output file and a CRL is not read from the input file.
+
+=back
+
+=head1 EXAMPLES
+
+Create a PKCS#7 structure from a certificate and CRL:
+
+ openssl crl2pkcs7 -in crl.pem -certfile cert.pem -out p7.pem
+
+Creates a PKCS#7 structure in DER format with no CRL from several
+different certificates:
+
+ openssl crl2pkcs7 -nocrl -certfile newcert.pem 
+	-certfile demoCA/cacert.pem -outform DER -out p7.der
+
+=head1 NOTES
+
+The output file is a PKCS#7 signed data structure containing no signers and
+just certificates and an optional CRL.
+
+This utility can be used to send certificates and CAs to Netscape as part of
+the certificate enrollment process. This involves sending the DER encoded output
+as MIME type application/x-x509-user-cert.
+
+The B<PEM> encoded form with the header and footer lines removed can be used to
+install user certificates and CAs in MSIE using the Xenroll control.
+
+=head1 SEE ALSO
+
+L<pkcs7(1)|pkcs7(1)>
+
+=cut
diff --git a/openssl/doc/apps/dgst.pod b/openssl/doc/apps/dgst.pod
new file mode 100644
index 0000000..b035edf
--- /dev/null
+++ b/openssl/doc/apps/dgst.pod
@@ -0,0 +1,162 @@
+=pod
+
+=head1 NAME
+
+dgst, md5, md4, md2, sha1, sha, mdc2, ripemd160 - message digests
+
+=head1 SYNOPSIS
+
+B<openssl> B<dgst> 
+[B<-md5|-md4|-md2|-sha1|-sha|-mdc2|-ripemd160|-dss1>]
+[B<-c>]
+[B<-d>]
+[B<-hex>]
+[B<-binary>]
+[B<-out filename>]
+[B<-sign filename>]
+[B<-keyform arg>]
+[B<-passin arg>]
+[B<-verify filename>]
+[B<-prverify filename>]
+[B<-signature filename>]
+[B<-hmac key>]
+[B<file...>]
+
+[B<md5|md4|md2|sha1|sha|mdc2|ripemd160>]
+[B<-c>]
+[B<-d>]
+[B<file...>]
+
+=head1 DESCRIPTION
+
+The digest functions output the message digest of a supplied file or files
+in hexadecimal form. They can also be used for digital signing and verification.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-c>
+
+print out the digest in two digit groups separated by colons, only relevant if
+B<hex> format output is used.
+
+=item B<-d>
+
+print out BIO debugging information.
+
+=item B<-hex>
+
+digest is to be output as a hex dump. This is the default case for a "normal"
+digest as opposed to a digital signature.
+
+=item B<-binary>
+
+output the digest or signature in binary form.
+
+=item B<-out filename>
+
+filename to output to, or standard output by default.
+
+=item B<-sign filename>
+
+digitally sign the digest using the private key in "filename".
+
+=item B<-keyform arg>
+
+Specifies the key format to sign digest with. Only PEM and ENGINE
+formats are supported by the B<dgst> command.
+
+=item B<-engine id>
+
+Use engine B<id> for operations (including private key storage).
+This engine is not used as source for digest algorithms, unless it is
+also specified in the configuration file.
+
+=item B<-sigopt nm:v>
+
+Pass options to the signature algorithm during sign or verify operations.
+Names and values of these options are algorithm-specific.
+
+
+=item B<-passin arg>
+
+the private key password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-verify filename>
+
+verify the signature using the the public key in "filename".
+The output is either "Verification OK" or "Verification Failure".
+
+=item B<-prverify filename>
+
+verify the signature using the  the private key in "filename".
+
+=item B<-signature filename>
+
+the actual signature to verify.
+
+=item B<-hmac key>
+
+create a hashed MAC using "key".
+
+=item B<-mac alg>
+
+create MAC (keyed Message Authentication Code). The most popular MAC
+algorithm is HMAC (hash-based MAC), but there are other MAC algorithms
+which are not based on hash, for instance B<gost-mac> algorithm,
+supported by B<ccgost> engine. MAC keys and other options should be set
+via B<-macopt> parameter.
+
+=item B<-macopt nm:v>
+
+Passes options to MAC algorithm, specified by B<-mac> key.
+Following options are supported by both by B<HMAC> and B<gost-mac>:
+
+=over 8
+
+=item B<key:string>
+	
+Specifies MAC key as alphnumeric string (use if key contain printable
+characters only). String length must conform to any restrictions of
+the MAC algorithm for example exactly 32 chars for gost-mac.
+
+=item B<hexkey:string>
+
+Specifies MAC key in hexadecimal form (two hex digits per byte).
+Key length must conform to any restrictions of the MAC algorithm
+for example exactly 32 chars for gost-mac.
+
+=back
+
+=item B<-rand file(s)>
+
+a file or files containing random data used to seed the random number
+generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
+Multiple files can be specified separated by a OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others. 
+
+=item B<file...>
+
+file or files to digest. If no files are specified then standard input is
+used.
+
+=back
+
+=head1 NOTES
+
+The digest of choice for all new applications is SHA1. Other digests are
+however still widely used.
+
+If you wish to sign or verify data using the DSA algorithm then the dss1
+digest must be used.
+
+A source of random numbers is required for certain signing algorithms, in
+particular DSA.
+
+The signing and verify options should only be used if a single file is
+being signed or verified.
+
+=cut
diff --git a/openssl/doc/apps/dhparam.pod b/openssl/doc/apps/dhparam.pod
new file mode 100644
index 0000000..9edb4ff
--- /dev/null
+++ b/openssl/doc/apps/dhparam.pod
@@ -0,0 +1,141 @@
+=pod
+
+=head1 NAME
+
+dhparam - DH parameter manipulation and generation
+
+=head1 SYNOPSIS
+
+B<openssl dhparam>
+[B<-inform DER|PEM>]
+[B<-outform DER|PEM>]
+[B<-in> I<filename>]
+[B<-out> I<filename>]
+[B<-dsaparam>]
+[B<-noout>]
+[B<-text>]
+[B<-C>]
+[B<-2>]
+[B<-5>]
+[B<-rand> I<file(s)>]
+[B<-engine id>]
+[I<numbits>]
+
+=head1 DESCRIPTION
+
+This command is used to manipulate DH parameter files.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-inform DER|PEM>
+
+This specifies the input format. The B<DER> option uses an ASN1 DER encoded
+form compatible with the PKCS#3 DHparameter structure. The PEM form is the
+default format: it consists of the B<DER> format base64 encoded with
+additional header and footer lines.
+
+=item B<-outform DER|PEM>
+
+This specifies the output format, the options have the same meaning as the 
+B<-inform> option.
+
+=item B<-in> I<filename>
+
+This specifies the input filename to read parameters from or standard input if
+this option is not specified.
+
+=item B<-out> I<filename>
+
+This specifies the output filename parameters to. Standard output is used
+if this option is not present. The output filename should B<not> be the same
+as the input filename.
+
+=item B<-dsaparam>
+
+If this option is used, DSA rather than DH parameters are read or created;
+they are converted to DH format.  Otherwise, "strong" primes (such
+that (p-1)/2 is also prime) will be used for DH parameter generation.
+
+DH parameter generation with the B<-dsaparam> option is much faster,
+and the recommended exponent length is shorter, which makes DH key
+exchange more efficient.  Beware that with such DSA-style DH
+parameters, a fresh DH key should be created for each use to
+avoid small-subgroup attacks that may be possible otherwise.
+
+=item B<-2>, B<-5>
+
+The generator to use, either 2 or 5. 2 is the default. If present then the
+input file is ignored and parameters are generated instead.
+
+=item B<-rand> I<file(s)>
+
+a file or files containing random data used to seed the random number
+generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
+Multiple files can be specified separated by a OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item I<numbits>
+
+this option specifies that a parameter set should be generated of size
+I<numbits>. It must be the last option. If not present then a value of 512
+is used. If this option is present then the input file is ignored and 
+parameters are generated instead.
+
+=item B<-noout>
+
+this option inhibits the output of the encoded version of the parameters.
+
+=item B<-text>
+
+this option prints out the DH parameters in human readable form.
+
+=item B<-C>
+
+this option converts the parameters into C code. The parameters can then
+be loaded by calling the B<get_dh>I<numbits>B<()> function.
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<dhparam>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=back
+
+=head1 WARNINGS
+
+The program B<dhparam> combines the functionality of the programs B<dh> and
+B<gendh> in previous versions of OpenSSL and SSLeay. The B<dh> and B<gendh>
+programs are retained for now but may have different purposes in future 
+versions of OpenSSL.
+
+=head1 NOTES
+
+PEM format DH parameters use the header and footer lines:
+
+ -----BEGIN DH PARAMETERS-----
+ -----END DH PARAMETERS-----
+
+OpenSSL currently only supports the older PKCS#3 DH, not the newer X9.42
+DH.
+
+This program manipulates DH parameters not keys.
+
+=head1 BUGS
+
+There should be a way to generate and manipulate DH keys.
+
+=head1 SEE ALSO
+
+L<dsaparam(1)|dsaparam(1)>
+
+=head1 HISTORY
+
+The B<dhparam> command was added in OpenSSL 0.9.5.
+The B<-dsaparam> option was added in OpenSSL 0.9.6.
+
+=cut
diff --git a/openssl/doc/apps/dsa.pod b/openssl/doc/apps/dsa.pod
new file mode 100644
index 0000000..ddbc932
--- /dev/null
+++ b/openssl/doc/apps/dsa.pod
@@ -0,0 +1,158 @@
+=pod
+
+=head1 NAME
+
+dsa - DSA key processing
+
+=head1 SYNOPSIS
+
+B<openssl> B<dsa>
+[B<-inform PEM|DER>]
+[B<-outform PEM|DER>]
+[B<-in filename>]
+[B<-passin arg>]
+[B<-out filename>]
+[B<-passout arg>]
+[B<-des>]
+[B<-des3>]
+[B<-idea>]
+[B<-text>]
+[B<-noout>]
+[B<-modulus>]
+[B<-pubin>]
+[B<-pubout>]
+[B<-engine id>]
+
+=head1 DESCRIPTION
+
+The B<dsa> command processes DSA keys. They can be converted between various
+forms and their components printed out. B<Note> This command uses the
+traditional SSLeay compatible format for private key encryption: newer
+applications should use the more secure PKCS#8 format using the B<pkcs8>
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<-inform DER|PEM>
+
+This specifies the input format. The B<DER> option with a private key uses
+an ASN1 DER encoded form of an ASN.1 SEQUENCE consisting of the values of
+version (currently zero), p, q, g, the public and private key components
+respectively as ASN.1 INTEGERs. When used with a public key it uses a
+SubjectPublicKeyInfo structure: it is an error if the key is not DSA.
+
+The B<PEM> form is the default format: it consists of the B<DER> format base64
+encoded with additional header and footer lines. In the case of a private key
+PKCS#8 format is also accepted.
+
+=item B<-outform DER|PEM>
+
+This specifies the output format, the options have the same meaning as the 
+B<-inform> option.
+
+=item B<-in filename>
+
+This specifies the input filename to read a key from or standard input if this
+option is not specified. If the key is encrypted a pass phrase will be
+prompted for.
+
+=item B<-passin arg>
+
+the input file password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-out filename>
+
+This specifies the output filename to write a key to or standard output by
+is not specified. If any encryption options are set then a pass phrase will be
+prompted for. The output filename should B<not> be the same as the input
+filename.
+
+=item B<-passout arg>
+
+the output file password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-des|-des3|-idea>
+
+These options encrypt the private key with the DES, triple DES, or the 
+IDEA ciphers respectively before outputting it. A pass phrase is prompted for.
+If none of these options is specified the key is written in plain text. This
+means that using the B<dsa> utility to read in an encrypted key with no
+encryption option can be used to remove the pass phrase from a key, or by
+setting the encryption options it can be use to add or change the pass phrase.
+These options can only be used with PEM format output files.
+
+=item B<-text>
+
+prints out the public, private key components and parameters.
+
+=item B<-noout>
+
+this option prevents output of the encoded version of the key.
+
+=item B<-modulus>
+
+this option prints out the value of the public key component of the key.
+
+=item B<-pubin>
+
+by default a private key is read from the input file: with this option a
+public key is read instead.
+
+=item B<-pubout>
+
+by default a private key is output. With this option a public
+key will be output instead. This option is automatically set if the input is
+a public key.
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<dsa>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=back
+
+=head1 NOTES
+
+The PEM private key format uses the header and footer lines:
+
+ -----BEGIN DSA PRIVATE KEY-----
+ -----END DSA PRIVATE KEY-----
+
+The PEM public key format uses the header and footer lines:
+
+ -----BEGIN PUBLIC KEY-----
+ -----END PUBLIC KEY-----
+
+=head1 EXAMPLES
+
+To remove the pass phrase on a DSA private key:
+
+ openssl dsa -in key.pem -out keyout.pem
+
+To encrypt a private key using triple DES:
+
+ openssl dsa -in key.pem -des3 -out keyout.pem
+
+To convert a private key from PEM to DER format: 
+
+ openssl dsa -in key.pem -outform DER -out keyout.der
+
+To print out the components of a private key to standard output:
+
+ openssl dsa -in key.pem -text -noout
+
+To just output the public part of a private key:
+
+ openssl dsa -in key.pem -pubout -out pubkey.pem
+
+=head1 SEE ALSO
+
+L<dsaparam(1)|dsaparam(1)>, L<gendsa(1)|gendsa(1)>, L<rsa(1)|rsa(1)>,
+L<genrsa(1)|genrsa(1)>
+
+=cut
diff --git a/openssl/doc/apps/dsaparam.pod b/openssl/doc/apps/dsaparam.pod
new file mode 100644
index 0000000..ba5ec4d
--- /dev/null
+++ b/openssl/doc/apps/dsaparam.pod
@@ -0,0 +1,110 @@
+=pod
+
+=head1 NAME
+
+dsaparam - DSA parameter manipulation and generation
+
+=head1 SYNOPSIS
+
+B<openssl dsaparam>
+[B<-inform DER|PEM>]
+[B<-outform DER|PEM>]
+[B<-in filename>]
+[B<-out filename>]
+[B<-noout>]
+[B<-text>]
+[B<-C>]
+[B<-rand file(s)>]
+[B<-genkey>]
+[B<-engine id>]
+[B<numbits>]
+
+=head1 DESCRIPTION
+
+This command is used to manipulate or generate DSA parameter files.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-inform DER|PEM>
+
+This specifies the input format. The B<DER> option uses an ASN1 DER encoded
+form compatible with RFC2459 (PKIX) DSS-Parms that is a SEQUENCE consisting
+of p, q and g respectively. The PEM form is the default format: it consists
+of the B<DER> format base64 encoded with additional header and footer lines.
+
+=item B<-outform DER|PEM>
+
+This specifies the output format, the options have the same meaning as the 
+B<-inform> option.
+
+=item B<-in filename>
+
+This specifies the input filename to read parameters from or standard input if
+this option is not specified. If the B<numbits> parameter is included then
+this option will be ignored.
+
+=item B<-out filename>
+
+This specifies the output filename parameters to. Standard output is used
+if this option is not present. The output filename should B<not> be the same
+as the input filename.
+
+=item B<-noout>
+
+this option inhibits the output of the encoded version of the parameters.
+
+=item B<-text>
+
+this option prints out the DSA parameters in human readable form.
+
+=item B<-C>
+
+this option converts the parameters into C code. The parameters can then
+be loaded by calling the B<get_dsaXXX()> function.
+
+=item B<-genkey>
+
+this option will generate a DSA either using the specified or generated
+parameters.
+
+=item B<-rand file(s)>
+
+a file or files containing random data used to seed the random number
+generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
+Multiple files can be specified separated by a OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item B<numbits>
+
+this option specifies that a parameter set should be generated of size
+B<numbits>. It must be the last option. If this option is included then
+the input file (if any) is ignored.
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<dsaparam>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=back
+
+=head1 NOTES
+
+PEM format DSA parameters use the header and footer lines:
+
+ -----BEGIN DSA PARAMETERS-----
+ -----END DSA PARAMETERS-----
+
+DSA parameter generation is a slow process and as a result the same set of
+DSA parameters is often used to generate several distinct keys.
+
+=head1 SEE ALSO
+
+L<gendsa(1)|gendsa(1)>, L<dsa(1)|dsa(1)>, L<genrsa(1)|genrsa(1)>,
+L<rsa(1)|rsa(1)>
+
+=cut
diff --git a/openssl/doc/apps/ec.pod b/openssl/doc/apps/ec.pod
new file mode 100644
index 0000000..ba6dc46
--- /dev/null
+++ b/openssl/doc/apps/ec.pod
@@ -0,0 +1,190 @@
+=pod
+
+=head1 NAME
+
+ec - EC key processing
+
+=head1 SYNOPSIS
+
+B<openssl> B<ec>
+[B<-inform PEM|DER>]
+[B<-outform PEM|DER>]
+[B<-in filename>]
+[B<-passin arg>]
+[B<-out filename>]
+[B<-passout arg>]
+[B<-des>]
+[B<-des3>]
+[B<-idea>]
+[B<-text>]
+[B<-noout>]
+[B<-param_out>]
+[B<-pubin>]
+[B<-pubout>]
+[B<-conv_form arg>]
+[B<-param_enc arg>]
+[B<-engine id>]
+
+=head1 DESCRIPTION
+
+The B<ec> command processes EC keys. They can be converted between various
+forms and their components printed out. B<Note> OpenSSL uses the 
+private key format specified in 'SEC 1: Elliptic Curve Cryptography'
+(http://www.secg.org/). To convert a OpenSSL EC private key into the
+PKCS#8 private key format use the B<pkcs8> command.
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<-inform DER|PEM>
+
+This specifies the input format. The B<DER> option with a private key uses
+an ASN.1 DER encoded SEC1 private key. When used with a public key it
+uses the SubjectPublicKeyInfo structur as specified in RFC 3280.
+The B<PEM> form is the default format: it consists of the B<DER> format base64
+encoded with additional header and footer lines. In the case of a private key
+PKCS#8 format is also accepted.
+
+=item B<-outform DER|PEM>
+
+This specifies the output format, the options have the same meaning as the 
+B<-inform> option.
+
+=item B<-in filename>
+
+This specifies the input filename to read a key from or standard input if this
+option is not specified. If the key is encrypted a pass phrase will be
+prompted for.
+
+=item B<-passin arg>
+
+the input file password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-out filename>
+
+This specifies the output filename to write a key to or standard output by
+is not specified. If any encryption options are set then a pass phrase will be
+prompted for. The output filename should B<not> be the same as the input
+filename.
+
+=item B<-passout arg>
+
+the output file password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-des|-des3|-idea>
+
+These options encrypt the private key with the DES, triple DES, IDEA or 
+any other cipher supported by OpenSSL before outputting it. A pass phrase is
+prompted for.
+If none of these options is specified the key is written in plain text. This
+means that using the B<ec> utility to read in an encrypted key with no
+encryption option can be used to remove the pass phrase from a key, or by
+setting the encryption options it can be use to add or change the pass phrase.
+These options can only be used with PEM format output files.
+
+=item B<-text>
+
+prints out the public, private key components and parameters.
+
+=item B<-noout>
+
+this option prevents output of the encoded version of the key.
+
+=item B<-modulus>
+
+this option prints out the value of the public key component of the key.
+
+=item B<-pubin>
+
+by default a private key is read from the input file: with this option a
+public key is read instead.
+
+=item B<-pubout>
+
+by default a private key is output. With this option a public
+key will be output instead. This option is automatically set if the input is
+a public key.
+
+=item B<-conv_form>
+
+This specifies how the points on the elliptic curve are converted
+into octet strings. Possible values are: B<compressed> (the default
+value), B<uncompressed> and B<hybrid>. For more information regarding
+the point conversion forms please read the X9.62 standard.
+B<Note> Due to patent issues the B<compressed> option is disabled
+by default for binary curves and can be enabled by defining
+the preprocessor macro B<OPENSSL_EC_BIN_PT_COMP> at compile time.
+
+=item B<-param_enc arg>
+
+This specifies how the elliptic curve parameters are encoded.
+Possible value are: B<named_curve>, i.e. the ec parameters are
+specified by a OID, or B<explicit> where the ec parameters are
+explicitly given (see RFC 3279 for the definition of the 
+EC parameters structures). The default value is B<named_curve>.
+B<Note> the B<implicitlyCA> alternative ,as specified in RFC 3279,
+is currently not implemented in OpenSSL.
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<ec>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=back
+
+=head1 NOTES
+
+The PEM private key format uses the header and footer lines:
+
+ -----BEGIN EC PRIVATE KEY-----
+ -----END EC PRIVATE KEY-----
+
+The PEM public key format uses the header and footer lines:
+
+ -----BEGIN PUBLIC KEY-----
+ -----END PUBLIC KEY-----
+
+=head1 EXAMPLES
+
+To encrypt a private key using triple DES:
+
+ openssl ec -in key.pem -des3 -out keyout.pem
+
+To convert a private key from PEM to DER format: 
+
+ openssl ec -in key.pem -outform DER -out keyout.der
+
+To print out the components of a private key to standard output:
+
+ openssl ec -in key.pem -text -noout
+
+To just output the public part of a private key:
+
+ openssl ec -in key.pem -pubout -out pubkey.pem
+
+To change the parameters encoding to B<explicit>:
+
+ openssl ec -in key.pem -param_enc explicit -out keyout.pem
+
+To change the point conversion form to B<compressed>:
+
+ openssl ec -in key.pem -conv_form compressed -out keyout.pem
+
+=head1 SEE ALSO
+
+L<ecparam(1)|ecparam(1)>, L<dsa(1)|dsa(1)>, L<rsa(1)|rsa(1)>
+
+=head1 HISTORY
+
+The ec command was first introduced in OpenSSL 0.9.8.
+
+=head1 AUTHOR
+
+Nils Larsch for the OpenSSL project (http://www.openssl.org).
+
+=cut
diff --git a/openssl/doc/apps/ecparam.pod b/openssl/doc/apps/ecparam.pod
new file mode 100644
index 0000000..788c074
--- /dev/null
+++ b/openssl/doc/apps/ecparam.pod
@@ -0,0 +1,179 @@
+=pod
+
+=head1 NAME
+
+ecparam - EC parameter manipulation and generation
+
+=head1 SYNOPSIS
+
+B<openssl ecparam>
+[B<-inform DER|PEM>]
+[B<-outform DER|PEM>]
+[B<-in filename>]
+[B<-out filename>]
+[B<-noout>]
+[B<-text>]
+[B<-C>]
+[B<-check>]
+[B<-name arg>]
+[B<-list_curve>]
+[B<-conv_form arg>]
+[B<-param_enc arg>]
+[B<-no_seed>]
+[B<-rand file(s)>]
+[B<-genkey>]
+[B<-engine id>]
+
+=head1 DESCRIPTION
+
+This command is used to manipulate or generate EC parameter files.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-inform DER|PEM>
+
+This specifies the input format. The B<DER> option uses an ASN.1 DER encoded
+form compatible with RFC 3279 EcpkParameters. The PEM form is the default
+format: it consists of the B<DER> format base64 encoded with additional 
+header and footer lines.
+
+=item B<-outform DER|PEM>
+
+This specifies the output format, the options have the same meaning as the 
+B<-inform> option.
+
+=item B<-in filename>
+
+This specifies the input filename to read parameters from or standard input if
+this option is not specified.
+
+=item B<-out filename>
+
+This specifies the output filename parameters to. Standard output is used
+if this option is not present. The output filename should B<not> be the same
+as the input filename.
+
+=item B<-noout>
+
+This option inhibits the output of the encoded version of the parameters.
+
+=item B<-text>
+
+This option prints out the EC parameters in human readable form.
+
+=item B<-C>
+
+This option converts the EC parameters into C code. The parameters can then
+be loaded by calling the B<get_ec_group_XXX()> function.
+
+=item B<-check>
+
+Validate the elliptic curve parameters.
+
+=item B<-name arg>
+
+Use the EC parameters with the specified 'short' name. Use B<-list_curves>
+to get a list of all currently implemented EC parameters.
+
+=item B<-list_curves>
+
+If this options is specified B<ecparam> will print out a list of all
+currently implemented EC parameters names and exit.
+
+=item B<-conv_form>
+
+This specifies how the points on the elliptic curve are converted
+into octet strings. Possible values are: B<compressed> (the default
+value), B<uncompressed> and B<hybrid>. For more information regarding
+the point conversion forms please read the X9.62 standard.
+B<Note> Due to patent issues the B<compressed> option is disabled
+by default for binary curves and can be enabled by defining
+the preprocessor macro B<OPENSSL_EC_BIN_PT_COMP> at compile time.
+
+=item B<-param_enc arg>
+
+This specifies how the elliptic curve parameters are encoded.
+Possible value are: B<named_curve>, i.e. the ec parameters are
+specified by a OID, or B<explicit> where the ec parameters are
+explicitly given (see RFC 3279 for the definition of the 
+EC parameters structures). The default value is B<named_curve>.
+B<Note> the B<implicitlyCA> alternative ,as specified in RFC 3279,
+is currently not implemented in OpenSSL.
+
+=item B<-no_seed>
+
+This option inhibits that the 'seed' for the parameter generation
+is included in the ECParameters structure (see RFC 3279).
+
+=item B<-genkey>
+
+This option will generate a EC private key using the specified parameters.
+
+=item B<-rand file(s)>
+
+a file or files containing random data used to seed the random number
+generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
+Multiple files can be specified separated by a OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<ecparam>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=back
+
+=head1 NOTES
+
+PEM format EC parameters use the header and footer lines:
+
+ -----BEGIN EC PARAMETERS-----
+ -----END EC PARAMETERS-----
+
+OpenSSL is currently not able to generate new groups and therefore
+B<ecparam> can only create EC parameters from known (named) curves. 
+
+=head1 EXAMPLES
+
+To create EC parameters with the group 'prime192v1':
+
+  openssl ecparam -out ec_param.pem -name prime192v1
+
+To create EC parameters with explicit parameters:
+
+  openssl ecparam -out ec_param.pem -name prime192v1 -param_enc explicit
+
+To validate given EC parameters:
+
+  openssl ecparam -in ec_param.pem -check
+
+To create EC parameters and a private key:
+
+  openssl ecparam -out ec_key.pem -name prime192v1 -genkey
+
+To change the point encoding to 'compressed':
+
+  openssl ecparam -in ec_in.pem -out ec_out.pem -conv_form compressed
+
+To print out the EC parameters to standard output:
+
+  openssl ecparam -in ec_param.pem -noout -text
+
+=head1 SEE ALSO
+
+L<ec(1)|ec(1)>, L<dsaparam(1)|dsaparam(1)>
+
+=head1 HISTORY
+
+The ecparam command was first introduced in OpenSSL 0.9.8.
+
+=head1 AUTHOR
+
+Nils Larsch for the OpenSSL project (http://www.openssl.org)
+
+=cut
diff --git a/openssl/doc/apps/enc.pod b/openssl/doc/apps/enc.pod
new file mode 100644
index 0000000..3dee4ed
--- /dev/null
+++ b/openssl/doc/apps/enc.pod
@@ -0,0 +1,329 @@
+=pod
+
+=head1 NAME
+
+enc - symmetric cipher routines
+
+=head1 SYNOPSIS
+
+B<openssl enc -ciphername>
+[B<-in filename>]
+[B<-out filename>]
+[B<-pass arg>]
+[B<-e>]
+[B<-d>]
+[B<-a/-base64>]
+[B<-A>]
+[B<-k password>]
+[B<-kfile filename>]
+[B<-K key>]
+[B<-iv IV>]
+[B<-S salt>]
+[B<-salt>]
+[B<-nosalt>]
+[B<-z>]
+[B<-md>]
+[B<-p>]
+[B<-P>]
+[B<-bufsize number>]
+[B<-nopad>]
+[B<-debug>]
+[B<-none>]
+[B<-engine id>]
+
+=head1 DESCRIPTION
+
+The symmetric cipher commands allow data to be encrypted or decrypted
+using various block and stream ciphers using keys based on passwords
+or explicitly provided. Base64 encoding or decoding can also be performed
+either by itself or in addition to the encryption or decryption.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-in filename>
+
+the input filename, standard input by default.
+
+=item B<-out filename>
+
+the output filename, standard output by default.
+
+=item B<-pass arg>
+
+the password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-salt>
+
+use a salt in the key derivation routines. This is the default.
+
+=item B<-nosalt>
+
+don't use a salt in the key derivation routines. This option B<SHOULD NOT> be
+used except for test purposes or compatibility with ancient versions of OpenSSL
+and SSLeay.
+
+=item B<-e>
+
+encrypt the input data: this is the default.
+
+=item B<-d>
+
+decrypt the input data.
+
+=item B<-a>
+
+base64 process the data. This means that if encryption is taking place
+the data is base64 encoded after encryption. If decryption is set then
+the input data is base64 decoded before being decrypted.
+
+=item B<-base64>
+
+same as B<-a>
+
+=item B<-A>
+
+if the B<-a> option is set then base64 process the data on one line.
+
+=item B<-k password>
+
+the password to derive the key from. This is for compatibility with previous
+versions of OpenSSL. Superseded by the B<-pass> argument.
+
+=item B<-kfile filename>
+
+read the password to derive the key from the first line of B<filename>.
+This is for compatibility with previous versions of OpenSSL. Superseded by
+the B<-pass> argument.
+
+=item B<-nosalt>
+
+do not use a salt 
+
+=item B<-salt>
+
+use salt (randomly generated or provide with B<-S> option) when
+encrypting (this is the default).
+
+=item B<-S salt>
+
+the actual salt to use: this must be represented as a string of hex digits.
+
+=item B<-K key>
+
+the actual key to use: this must be represented as a string comprised only
+of hex digits. If only the key is specified, the IV must additionally specified
+using the B<-iv> option. When both a key and a password are specified, the
+key given with the B<-K> option will be used and the IV generated from the
+password will be taken. It probably does not make much sense to specify
+both key and password.
+
+=item B<-iv IV>
+
+the actual IV to use: this must be represented as a string comprised only
+of hex digits. When only the key is specified using the B<-K> option, the
+IV must explicitly be defined. When a password is being specified using
+one of the other options, the IV is generated from this password.
+
+=item B<-p>
+
+print out the key and IV used.
+
+=item B<-P>
+
+print out the key and IV used then immediately exit: don't do any encryption
+or decryption.
+
+=item B<-bufsize number>
+
+set the buffer size for I/O
+
+=item B<-nopad>
+
+disable standard block padding
+
+=item B<-debug>
+
+debug the BIOs used for I/O.
+
+=item B<-z>
+
+Compress or decompress clear text using zlib before encryption or after
+decryption. This option exists only if OpenSSL with compiled with zlib
+or zlib-dynamic option.
+
+=item B<-none>
+
+Use NULL cipher (no encryption or decryption of input).
+
+=back
+
+=head1 NOTES
+
+The program can be called either as B<openssl ciphername> or
+B<openssl enc -ciphername>. But the first form doesn't work with
+engine-provided ciphers, because this form is processed before the
+configuration file is read and any ENGINEs loaded.
+
+Engines which provide entirely new encryption algorithms (such as ccgost
+engine which provides gost89 algorithm) should be configured in the
+configuration file. Engines, specified in the command line using -engine
+options can only be used for hadrware-assisted implementations of
+ciphers, which are supported by OpenSSL core or other engine, specified
+in the configuration file.
+
+When enc command lists supported ciphers, ciphers provided by engines,
+specified in the configuration files are listed too.
+
+A password will be prompted for to derive the key and IV if necessary.
+
+The B<-salt> option should B<ALWAYS> be used if the key is being derived
+from a password unless you want compatibility with previous versions of
+OpenSSL and SSLeay.
+
+Without the B<-salt> option it is possible to perform efficient dictionary
+attacks on the password and to attack stream cipher encrypted data. The reason
+for this is that without the salt the same password always generates the same
+encryption key. When the salt is being used the first eight bytes of the
+encrypted data are reserved for the salt: it is generated at random when
+encrypting a file and read from the encrypted file when it is decrypted.
+
+Some of the ciphers do not have large keys and others have security
+implications if not used correctly. A beginner is advised to just use
+a strong block cipher in CBC mode such as bf or des3.
+
+All the block ciphers normally use PKCS#5 padding also known as standard block
+padding: this allows a rudimentary integrity or password check to be
+performed. However since the chance of random data passing the test is
+better than 1 in 256 it isn't a very good test.
+
+If padding is disabled then the input data must be a multiple of the cipher
+block length.
+
+All RC2 ciphers have the same key and effective key length.
+
+Blowfish and RC5 algorithms use a 128 bit key.
+
+=head1 SUPPORTED CIPHERS
+
+Note that some of these ciphers can be disabled at compile time
+and some are available only if an appropriate engine is configured
+in the configuration file. The output of the B<enc> command run with
+unsupported options (for example B<openssl enc -help>) includes a
+list of ciphers, supported by your versesion of OpenSSL, including
+ones provided by configured engines.
+
+
+ base64             Base 64
+
+ bf-cbc             Blowfish in CBC mode
+ bf                 Alias for bf-cbc
+ bf-cfb             Blowfish in CFB mode
+ bf-ecb             Blowfish in ECB mode
+ bf-ofb             Blowfish in OFB mode
+
+ cast-cbc           CAST in CBC mode
+ cast               Alias for cast-cbc
+ cast5-cbc          CAST5 in CBC mode
+ cast5-cfb          CAST5 in CFB mode
+ cast5-ecb          CAST5 in ECB mode
+ cast5-ofb          CAST5 in OFB mode
+
+ des-cbc            DES in CBC mode
+ des                Alias for des-cbc
+ des-cfb            DES in CBC mode
+ des-ofb            DES in OFB mode
+ des-ecb            DES in ECB mode
+
+ des-ede-cbc        Two key triple DES EDE in CBC mode
+ des-ede            Two key triple DES EDE in ECB mode
+ des-ede-cfb        Two key triple DES EDE in CFB mode
+ des-ede-ofb        Two key triple DES EDE in OFB mode
+
+ des-ede3-cbc       Three key triple DES EDE in CBC mode
+ des-ede3           Three key triple DES EDE in ECB mode
+ des3               Alias for des-ede3-cbc
+ des-ede3-cfb       Three key triple DES EDE CFB mode
+ des-ede3-ofb       Three key triple DES EDE in OFB mode
+
+ desx               DESX algorithm.
+
+ gost89             GOST 28147-89 in CFB mode (provided by ccgost engine)
+ gost89-cnt        `GOST 28147-89 in CNT mode (provided by ccgost engine) 
+
+ idea-cbc           IDEA algorithm in CBC mode
+ idea               same as idea-cbc
+ idea-cfb           IDEA in CFB mode
+ idea-ecb           IDEA in ECB mode
+ idea-ofb           IDEA in OFB mode
+
+ rc2-cbc            128 bit RC2 in CBC mode
+ rc2                Alias for rc2-cbc
+ rc2-cfb            128 bit RC2 in CFB mode
+ rc2-ecb            128 bit RC2 in ECB mode
+ rc2-ofb            128 bit RC2 in OFB mode
+ rc2-64-cbc         64 bit RC2 in CBC mode
+ rc2-40-cbc         40 bit RC2 in CBC mode
+
+ rc4                128 bit RC4
+ rc4-64             64 bit RC4
+ rc4-40             40 bit RC4
+
+ rc5-cbc            RC5 cipher in CBC mode
+ rc5                Alias for rc5-cbc
+ rc5-cfb            RC5 cipher in CFB mode
+ rc5-ecb            RC5 cipher in ECB mode
+ rc5-ofb            RC5 cipher in OFB mode
+
+ aes-[128|192|256]-cbc	128/192/256 bit AES in CBC mode
+ aes-[128|192|256]	Alias for aes-[128|192|256]-cbc
+ aes-[128|192|256]-cfb	128/192/256 bit AES in 128 bit CFB mode
+ aes-[128|192|256]-cfb1	128/192/256 bit AES in 1 bit CFB mode
+ aes-[128|192|256]-cfb8	128/192/256 bit AES in 8 bit CFB mode
+ aes-[128|192|256]-ecb	128/192/256 bit AES in ECB mode
+ aes-[128|192|256]-ofb	128/192/256 bit AES in OFB mode
+
+=head1 EXAMPLES
+
+Just base64 encode a binary file:
+
+ openssl base64 -in file.bin -out file.b64
+
+Decode the same file
+
+ openssl base64 -d -in file.b64 -out file.bin 
+
+Encrypt a file using triple DES in CBC mode using a prompted password:
+
+ openssl des3 -salt -in file.txt -out file.des3 
+
+Decrypt a file using a supplied password:
+
+ openssl des3 -d -salt -in file.des3 -out file.txt -k mypassword
+
+Encrypt a file then base64 encode it (so it can be sent via mail for example)
+using Blowfish in CBC mode:
+
+ openssl bf -a -salt -in file.txt -out file.bf
+
+Base64 decode a file then decrypt it:
+
+ openssl bf -d -salt -a -in file.bf -out file.txt
+
+Decrypt some data using a supplied 40 bit RC4 key:
+
+ openssl rc4-40 -in file.rc4 -out file.txt -K 0102030405
+
+=head1 BUGS
+
+The B<-A> option when used with large files doesn't work properly.
+
+There should be an option to allow an iteration count to be included.
+
+The B<enc> program only supports a fixed number of algorithms with
+certain parameters. So if, for example, you want to use RC2 with a
+76 bit key or RC4 with an 84 bit key you can't use this program.
+
+=cut
diff --git a/openssl/doc/apps/errstr.pod b/openssl/doc/apps/errstr.pod
new file mode 100644
index 0000000..b3c6ccf
--- /dev/null
+++ b/openssl/doc/apps/errstr.pod
@@ -0,0 +1,39 @@
+=pod
+
+=head1 NAME
+
+errstr - lookup error codes
+
+=head1 SYNOPSIS
+
+B<openssl errstr error_code>
+
+=head1 DESCRIPTION
+
+Sometimes an application will not load error message and only
+numerical forms will be available. The B<errstr> utility can be used to 
+display the meaning of the hex code. The hex code is the hex digits after the
+second colon.
+
+=head1 EXAMPLE
+
+The error code:
+
+ 27594:error:2006D080:lib(32):func(109):reason(128):bss_file.c:107:
+
+can be displayed with:
+ 
+ openssl errstr 2006D080
+
+to produce the error message:
+
+ error:2006D080:BIO routines:BIO_new_file:no such file
+
+=head1 SEE ALSO
+
+L<err(3)|err(3)>,
+L<ERR_load_crypto_strings(3)|ERR_load_crypto_strings(3)>,
+L<SSL_load_error_strings(3)|SSL_load_error_strings(3)>
+
+
+=cut
diff --git a/openssl/doc/apps/gendsa.pod b/openssl/doc/apps/gendsa.pod
new file mode 100644
index 0000000..8c7f114
--- /dev/null
+++ b/openssl/doc/apps/gendsa.pod
@@ -0,0 +1,66 @@
+=pod
+
+=head1 NAME
+
+gendsa - generate a DSA private key from a set of parameters
+
+=head1 SYNOPSIS
+
+B<openssl> B<gendsa>
+[B<-out filename>]
+[B<-des>]
+[B<-des3>]
+[B<-idea>]
+[B<-rand file(s)>]
+[B<-engine id>]
+[B<paramfile>]
+
+=head1 DESCRIPTION
+
+The B<gendsa> command generates a DSA private key from a DSA parameter file
+(which will be typically generated by the B<openssl dsaparam> command).
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-des|-des3|-idea>
+
+These options encrypt the private key with the DES, triple DES, or the 
+IDEA ciphers respectively before outputting it. A pass phrase is prompted for.
+If none of these options is specified no encryption is used.
+
+=item B<-rand file(s)>
+
+a file or files containing random data used to seed the random number
+generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
+Multiple files can be specified separated by a OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<gendsa>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=item B<paramfile>
+
+This option specifies the DSA parameter file to use. The parameters in this
+file determine the size of the private key. DSA parameters can be generated
+and examined using the B<openssl dsaparam> command.
+
+=back
+
+=head1 NOTES
+
+DSA key generation is little more than random number generation so it is
+much quicker that RSA key generation for example.
+
+=head1 SEE ALSO
+
+L<dsaparam(1)|dsaparam(1)>, L<dsa(1)|dsa(1)>, L<genrsa(1)|genrsa(1)>,
+L<rsa(1)|rsa(1)>
+
+=cut
diff --git a/openssl/doc/apps/genpkey.pod b/openssl/doc/apps/genpkey.pod
new file mode 100644
index 0000000..1611b5c
--- /dev/null
+++ b/openssl/doc/apps/genpkey.pod
@@ -0,0 +1,213 @@
+=pod
+
+=head1 NAME
+
+genpkey - generate a private key
+
+=head1 SYNOPSIS
+
+B<openssl> B<genpkey>
+[B<-out filename>]
+[B<-outform PEM|DER>]
+[B<-pass arg>]
+[B<-cipher>]
+[B<-engine id>]
+[B<-paramfile file>]
+[B<-algorithm alg>]
+[B<-pkeyopt opt:value>]
+[B<-genparam>]
+[B<-text>]
+
+=head1 DESCRIPTION
+
+The B<genpkey> command generates a private key.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-out filename>
+
+the output filename. If this argument is not specified then standard output is
+used.  
+
+=item B<-outform DER|PEM>
+
+This specifies the output format DER or PEM.
+
+=item B<-pass arg>
+
+the output file password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-cipher>
+
+This option encrypts the private key with the supplied cipher. Any algorithm
+name accepted by EVP_get_cipherbyname() is acceptable such as B<des3>.
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<genpkey>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms. If used this option should precede all other
+options.
+
+=item B<-algorithm alg>
+
+public key algorithm to use such as RSA, DSA or DH. If used this option must
+precede any B<-pkeyopt> options. The options B<-paramfile> and B<-algorithm>
+are mutually exclusive.
+
+=item B<-pkeyopt opt:value>
+
+set the public key algorithm option B<opt> to B<value>. The precise set of
+options supported depends on the public key algorithm used and its
+implementation. See B<KEY GENERATION OPTIONS> below for more details.
+
+=item B<-genparam>
+
+generate a set of parameters instead of a private key. If used this option must
+precede and B<-algorithm>, B<-paramfile> or B<-pkeyopt> options.
+
+=item B<-paramfile filename>
+
+Some public key algorithms generate a private key based on a set of parameters.
+They can be supplied using this option. If this option is used the public key
+algorithm used is determined by the parameters. If used this option must
+precede and B<-pkeyopt> options. The options B<-paramfile> and B<-algorithm>
+are mutually exclusive.
+
+=item B<-text>
+
+Print an (unencrypted) text representation of private and public keys and
+parameters along with the PEM or DER structure.
+
+=back
+
+=head1 KEY GENERATION OPTIONS
+
+The options supported by each algorith and indeed each implementation of an
+algorithm can vary. The options for the OpenSSL implementations are detailed
+below.
+
+=head1 RSA KEY GENERATION OPTIONS
+
+=over 4
+
+=item B<rsa_keygen_bits:numbits>
+
+The number of bits in the generated key. If not specified 1024 is used.
+
+=item B<rsa_keygen_pubexp:value>
+
+The RSA public exponent value. This can be a large decimal or
+hexadecimal value if preceded by B<0x>. Default value is 65537.
+
+=back
+
+=head1 DSA PARAMETER GENERATION OPTIONS
+
+=over 4
+
+=item B<dsa_paramgen_bits:numbits>
+
+The number of bits in the generated parameters. If not specified 1024 is used.
+
+=head1 DH PARAMETER GENERATION OPTIONS
+
+=over 4
+
+=item B<dh_paramgen_prime_len:numbits>
+
+The number of bits in the prime parameter B<p>.
+
+=item B<dh_paramgen_generator:value>
+
+The value to use for the generator B<g>.
+
+=back
+
+=head1 EC PARAMETER GENERATION OPTIONS
+
+=over 4
+
+=item B<ec_paramgen_curve:curve>
+
+the EC curve to use.
+
+=back
+
+=head1 GOST2001 KEY GENERATION AND PARAMETER OPTIONS
+
+Gost 2001 support is not enabled by default. To enable this algorithm,
+one should load the ccgost engine in the OpenSSL configuration file.
+See README.gost file in the engines/ccgost directiry of the source
+distribution for more details.
+
+Use of a parameter file for the GOST R 34.10 algorithm is optional.
+Parameters can be specified during key generation directly as well as
+during generation of parameter file.
+
+=over 4
+
+=item B<paramset:name>
+
+Specifies GOST R 34.10-2001 parameter set according to RFC 4357.
+Parameter set can be specified using abbreviated name, object short name or
+numeric OID. Following parameter sets are supported:
+
+  paramset   OID               Usage
+  A          1.2.643.2.2.35.1  Signature
+  B          1.2.643.2.2.35.2  Signature
+  C          1.2.643.2.2.35.3  Signature
+  XA         1.2.643.2.2.36.0  Key exchange
+  XB         1.2.643.2.2.36.1  Key exchange
+  test       1.2.643.2.2.35.0  Test purposes
+
+=back
+
+
+
+=head1 NOTES
+
+The use of the genpkey program is encouraged over the algorithm specific
+utilities because additional algorithm options and ENGINE provided algorithms
+can be used.
+
+=head1 EXAMPLES
+
+Generate an RSA private key using default parameters:
+
+ openssl genpkey -algorithm RSA -out key.pem 
+
+Encrypt output private key using 128 bit AES and the passphrase "hello":
+
+ openssl genpkey -algorithm RSA -out key.pem -aes-128-cbc -pass pass:hello
+
+Generate a 2048 bit RSA key using 3 as the public exponent:
+
+ openssl genpkey -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:2048 \
+ 						-pkeyopt rsa_keygen_pubexp:3
+
+Generate 1024 bit DSA parameters:
+
+ openssl genpkey -genparam -algorithm DSA -out dsap.pem \
+						-pkeyopt dsa_paramgen_bits:1024
+
+Generate DSA key from parameters:
+
+ openssl genpkey -paramfile dsap.pem -out dsakey.pem 
+
+Generate 1024 bit DH parameters:
+
+ openssl genpkey -genparam -algorithm DH -out dhp.pem \
+					-pkeyopt dh_paramgen_prime_len:1024
+
+Generate DH key from parameters:
+
+ openssl genpkey -paramfile dhp.pem -out dhkey.pem 
+
+
+=cut
+
diff --git a/openssl/doc/apps/genrsa.pod b/openssl/doc/apps/genrsa.pod
new file mode 100644
index 0000000..7dcac2a
--- /dev/null
+++ b/openssl/doc/apps/genrsa.pod
@@ -0,0 +1,96 @@
+=pod
+
+=head1 NAME
+
+genrsa - generate an RSA private key
+
+=head1 SYNOPSIS
+
+B<openssl> B<genrsa>
+[B<-out filename>]
+[B<-passout arg>]
+[B<-des>]
+[B<-des3>]
+[B<-idea>]
+[B<-f4>]
+[B<-3>]
+[B<-rand file(s)>]
+[B<-engine id>]
+[B<numbits>]
+
+=head1 DESCRIPTION
+
+The B<genrsa> command generates an RSA private key.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-out filename>
+
+the output filename. If this argument is not specified then standard output is
+used.  
+
+=item B<-passout arg>
+
+the output file password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-des|-des3|-idea>
+
+These options encrypt the private key with the DES, triple DES, or the 
+IDEA ciphers respectively before outputting it. If none of these options is
+specified no encryption is used. If encryption is used a pass phrase is prompted
+for if it is not supplied via the B<-passout> argument.
+
+=item B<-F4|-3>
+
+the public exponent to use, either 65537 or 3. The default is 65537.
+
+=item B<-rand file(s)>
+
+a file or files containing random data used to seed the random number
+generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
+Multiple files can be specified separated by a OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<genrsa>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=item B<numbits>
+
+the size of the private key to generate in bits. This must be the last option
+specified. The default is 512.
+
+=back
+
+=head1 NOTES
+
+RSA private key generation essentially involves the generation of two prime
+numbers. When generating a private key various symbols will be output to
+indicate the progress of the generation. A B<.> represents each number which
+has passed an initial sieve test, B<+> means a number has passed a single
+round of the Miller-Rabin primality test. A newline means that the number has
+passed all the prime tests (the actual number depends on the key size).
+
+Because key generation is a random process the time taken to generate a key
+may vary somewhat.
+
+=head1 BUGS
+
+A quirk of the prime generation algorithm is that it cannot generate small
+primes. Therefore the number of bits should not be less that 64. For typical
+private keys this will not matter because for security reasons they will
+be much larger (typically 1024 bits).
+
+=head1 SEE ALSO
+
+L<gendsa(1)|gendsa(1)>
+
+=cut
+
diff --git a/openssl/doc/apps/nseq.pod b/openssl/doc/apps/nseq.pod
new file mode 100644
index 0000000..989c310
--- /dev/null
+++ b/openssl/doc/apps/nseq.pod
@@ -0,0 +1,70 @@
+=pod
+
+=head1 NAME
+
+nseq - create or examine a netscape certificate sequence
+
+=head1 SYNOPSIS
+
+B<openssl> B<nseq>
+[B<-in filename>]
+[B<-out filename>]
+[B<-toseq>]
+
+=head1 DESCRIPTION
+
+The B<nseq> command takes a file containing a Netscape certificate
+sequence and prints out the certificates contained in it or takes a
+file of certificates and converts it into a Netscape certificate
+sequence.
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<-in filename>
+
+This specifies the input filename to read or standard input if this
+option is not specified.
+
+=item B<-out filename>
+
+specifies the output filename or standard output by default.
+
+=item B<-toseq>
+
+normally a Netscape certificate sequence will be input and the output
+is the certificates contained in it. With the B<-toseq> option the
+situation is reversed: a Netscape certificate sequence is created from
+a file of certificates.
+
+=back
+
+=head1 EXAMPLES
+
+Output the certificates in a Netscape certificate sequence
+
+ openssl nseq -in nseq.pem -out certs.pem
+
+Create a Netscape certificate sequence
+
+ openssl nseq -in certs.pem -toseq -out nseq.pem
+
+=head1 NOTES
+
+The B<PEM> encoded form uses the same headers and footers as a certificate:
+
+ -----BEGIN CERTIFICATE-----
+ -----END CERTIFICATE-----
+
+A Netscape certificate sequence is a Netscape specific form that can be sent
+to browsers as an alternative to the standard PKCS#7 format when several
+certificates are sent to the browser: for example during certificate enrollment.
+It is used by Netscape certificate server for example.
+
+=head1 BUGS
+
+This program needs a few more options: like allowing DER or PEM input and
+output files and allowing multiple certificate files to be used.
+
+=cut
diff --git a/openssl/doc/apps/ocsp.pod b/openssl/doc/apps/ocsp.pod
new file mode 100644
index 0000000..af2e12e
--- /dev/null
+++ b/openssl/doc/apps/ocsp.pod
@@ -0,0 +1,371 @@
+=pod
+
+=head1 NAME
+
+ocsp - Online Certificate Status Protocol utility
+
+=head1 SYNOPSIS
+
+B<openssl> B<ocsp>
+[B<-out file>]
+[B<-issuer file>]
+[B<-cert file>]
+[B<-serial n>]
+[B<-signer file>]
+[B<-signkey file>]
+[B<-sign_other file>]
+[B<-no_certs>]
+[B<-req_text>]
+[B<-resp_text>]
+[B<-text>]
+[B<-reqout file>]
+[B<-respout file>]
+[B<-reqin file>]
+[B<-respin file>]
+[B<-nonce>]
+[B<-no_nonce>]
+[B<-url URL>]
+[B<-host host:n>]
+[B<-path>]
+[B<-CApath dir>]
+[B<-CAfile file>]
+[B<-VAfile file>]
+[B<-validity_period n>]
+[B<-status_age n>]
+[B<-noverify>]
+[B<-verify_other file>]
+[B<-trust_other>]
+[B<-no_intern>]
+[B<-no_signature_verify>]
+[B<-no_cert_verify>]
+[B<-no_chain>]
+[B<-no_cert_checks>]
+[B<-port num>]
+[B<-index file>]
+[B<-CA file>]
+[B<-rsigner file>]
+[B<-rkey file>]
+[B<-rother file>]
+[B<-resp_no_certs>]
+[B<-nmin n>]
+[B<-ndays n>]
+[B<-resp_key_id>]
+[B<-nrequest n>]
+[B<-md5|-sha1|...>]
+
+=head1 DESCRIPTION
+
+The Online Certificate Status Protocol (OCSP) enables applications to
+determine the (revocation) state of an identified certificate (RFC 2560).
+
+The B<ocsp> command performs many common OCSP tasks. It can be used
+to print out requests and responses, create requests and send queries
+to an OCSP responder and behave like a mini OCSP server itself.
+
+=head1 OCSP CLIENT OPTIONS
+
+=over 4
+
+=item B<-out filename>
+
+specify output filename, default is standard output.
+
+=item B<-issuer filename>
+
+This specifies the current issuer certificate. This option can be used
+multiple times. The certificate specified in B<filename> must be in
+PEM format. This option B<MUST> come before any B<-cert> options.
+
+=item B<-cert filename>
+
+Add the certificate B<filename> to the request. The issuer certificate
+is taken from the previous B<issuer> option, or an error occurs if no
+issuer certificate is specified.
+
+=item B<-serial num>
+
+Same as the B<cert> option except the certificate with serial number
+B<num> is added to the request. The serial number is interpreted as a
+decimal integer unless preceded by B<0x>. Negative integers can also
+be specified by preceding the value by a B<-> sign.
+
+=item B<-signer filename>, B<-signkey filename>
+
+Sign the OCSP request using the certificate specified in the B<signer>
+option and the private key specified by the B<signkey> option. If
+the B<signkey> option is not present then the private key is read
+from the same file as the certificate. If neither option is specified then
+the OCSP request is not signed.
+
+=item B<-sign_other filename>
+
+Additional certificates to include in the signed request.
+
+=item B<-nonce>, B<-no_nonce>
+
+Add an OCSP nonce extension to a request or disable OCSP nonce addition.
+Normally if an OCSP request is input using the B<respin> option no
+nonce is added: using the B<nonce> option will force addition of a nonce.
+If an OCSP request is being created (using B<cert> and B<serial> options)
+a nonce is automatically added specifying B<no_nonce> overrides this.
+
+=item B<-req_text>, B<-resp_text>, B<-text>
+
+print out the text form of the OCSP request, response or both respectively.
+
+=item B<-reqout file>, B<-respout file>
+
+write out the DER encoded certificate request or response to B<file>.
+
+=item B<-reqin file>, B<-respin file>
+
+read OCSP request or response file from B<file>. These option are ignored
+if OCSP request or response creation is implied by other options (for example
+with B<serial>, B<cert> and B<host> options).
+
+=item B<-url responder_url>
+
+specify the responder URL. Both HTTP and HTTPS (SSL/TLS) URLs can be specified.
+
+=item B<-host hostname:port>, B<-path pathname>
+
+if the B<host> option is present then the OCSP request is sent to the host
+B<hostname> on port B<port>. B<path> specifies the HTTP path name to use
+or "/" by default.
+
+=item B<-CAfile file>, B<-CApath pathname>
+
+file or pathname containing trusted CA certificates. These are used to verify
+the signature on the OCSP response.
+
+=item B<-verify_other file>
+
+file containing additional certificates to search when attempting to locate
+the OCSP response signing certificate. Some responders omit the actual signer's
+certificate from the response: this option can be used to supply the necessary
+certificate in such cases.
+
+=item B<-trust_other>
+
+the certificates specified by the B<-verify_other> option should be explicitly
+trusted and no additional checks will be performed on them. This is useful
+when the complete responder certificate chain is not available or trusting a
+root CA is not appropriate.
+
+=item B<-VAfile file>
+
+file containing explicitly trusted responder certificates. Equivalent to the
+B<-verify_other> and B<-trust_other> options.
+
+=item B<-noverify>
+
+don't attempt to verify the OCSP response signature or the nonce values. This
+option will normally only be used for debugging since it disables all verification
+of the responders certificate.
+
+=item B<-no_intern>
+
+ignore certificates contained in the OCSP response when searching for the
+signers certificate. With this option the signers certificate must be specified
+with either the B<-verify_other> or B<-VAfile> options.
+
+=item B<-no_signature_verify>
+
+don't check the signature on the OCSP response. Since this option tolerates invalid
+signatures on OCSP responses it will normally only be used for testing purposes.
+
+=item B<-no_cert_verify>
+
+don't verify the OCSP response signers certificate at all. Since this option allows
+the OCSP response to be signed by any certificate it should only be used for
+testing purposes.
+
+=item B<-no_chain>
+
+do not use certificates in the response as additional untrusted CA
+certificates.
+
+=item B<-no_cert_checks>
+
+don't perform any additional checks on the OCSP response signers certificate.
+That is do not make any checks to see if the signers certificate is authorised
+to provide the necessary status information: as a result this option should
+only be used for testing purposes.
+
+=item B<-validity_period nsec>, B<-status_age age>
+
+these options specify the range of times, in seconds, which will be tolerated
+in an OCSP response. Each certificate status response includes a B<notBefore> time and
+an optional B<notAfter> time. The current time should fall between these two values, but
+the interval between the two times may be only a few seconds. In practice the OCSP
+responder and clients clocks may not be precisely synchronised and so such a check
+may fail. To avoid this the B<-validity_period> option can be used to specify an
+acceptable error range in seconds, the default value is 5 minutes.
+
+If the B<notAfter> time is omitted from a response then this means that new status
+information is immediately available. In this case the age of the B<notBefore> field
+is checked to see it is not older than B<age> seconds old. By default this additional
+check is not performed.
+
+=item B<-md5|-sha1|-sha256|-ripemod160|...>
+
+this option sets digest algorithm to use for certificate identification
+in the OCSP request. By default SHA-1 is used. 
+
+=back
+
+=head1 OCSP SERVER OPTIONS
+
+=over 4
+
+=item B<-index indexfile>
+
+B<indexfile> is a text index file in B<ca> format containing certificate revocation
+information.
+
+If the B<index> option is specified the B<ocsp> utility is in responder mode, otherwise
+it is in client mode. The request(s) the responder processes can be either specified on
+the command line (using B<issuer> and B<serial> options), supplied in a file (using the
+B<respin> option) or via external OCSP clients (if B<port> or B<url> is specified).
+
+If the B<index> option is present then the B<CA> and B<rsigner> options must also be
+present.
+
+=item B<-CA file>
+
+CA certificate corresponding to the revocation information in B<indexfile>.
+
+=item B<-rsigner file>
+
+The certificate to sign OCSP responses with.
+
+=item B<-rother file>
+
+Additional certificates to include in the OCSP response.
+
+=item B<-resp_no_certs>
+
+Don't include any certificates in the OCSP response.
+
+=item B<-resp_key_id>
+
+Identify the signer certificate using the key ID, default is to use the subject name.
+
+=item B<-rkey file>
+
+The private key to sign OCSP responses with: if not present the file specified in the
+B<rsigner> option is used.
+
+=item B<-port portnum>
+
+Port to listen for OCSP requests on. The port may also be specified using the B<url>
+option.
+
+=item B<-nrequest number>
+
+The OCSP server will exit after receiving B<number> requests, default unlimited. 
+
+=item B<-nmin minutes>, B<-ndays days>
+
+Number of minutes or days when fresh revocation information is available: used in the
+B<nextUpdate> field. If neither option is present then the B<nextUpdate> field is 
+omitted meaning fresh revocation information is immediately available.
+
+=back
+
+=head1 OCSP Response verification.
+
+OCSP Response follows the rules specified in RFC2560.
+
+Initially the OCSP responder certificate is located and the signature on
+the OCSP request checked using the responder certificate's public key.
+
+Then a normal certificate verify is performed on the OCSP responder certificate
+building up a certificate chain in the process. The locations of the trusted
+certificates used to build the chain can be specified by the B<CAfile>
+and B<CApath> options or they will be looked for in the standard OpenSSL
+certificates directory.
+
+If the initial verify fails then the OCSP verify process halts with an
+error.
+
+Otherwise the issuing CA certificate in the request is compared to the OCSP
+responder certificate: if there is a match then the OCSP verify succeeds.
+
+Otherwise the OCSP responder certificate's CA is checked against the issuing
+CA certificate in the request. If there is a match and the OCSPSigning
+extended key usage is present in the OCSP responder certificate then the
+OCSP verify succeeds.
+
+Otherwise the root CA of the OCSP responders CA is checked to see if it
+is trusted for OCSP signing. If it is the OCSP verify succeeds.
+
+If none of these checks is successful then the OCSP verify fails.
+
+What this effectively means if that if the OCSP responder certificate is
+authorised directly by the CA it is issuing revocation information about
+(and it is correctly configured) then verification will succeed.
+
+If the OCSP responder is a "global responder" which can give details about
+multiple CAs and has its own separate certificate chain then its root
+CA can be trusted for OCSP signing. For example:
+
+ openssl x509 -in ocspCA.pem -addtrust OCSPSigning -out trustedCA.pem
+
+Alternatively the responder certificate itself can be explicitly trusted
+with the B<-VAfile> option.
+
+=head1 NOTES
+
+As noted, most of the verify options are for testing or debugging purposes.
+Normally only the B<-CApath>, B<-CAfile> and (if the responder is a 'global
+VA') B<-VAfile> options need to be used.
+
+The OCSP server is only useful for test and demonstration purposes: it is
+not really usable as a full OCSP responder. It contains only a very
+simple HTTP request handling and can only handle the POST form of OCSP
+queries. It also handles requests serially meaning it cannot respond to
+new requests until it has processed the current one. The text index file
+format of revocation is also inefficient for large quantities of revocation
+data.
+
+It is possible to run the B<ocsp> application in responder mode via a CGI
+script using the B<respin> and B<respout> options.
+
+=head1 EXAMPLES
+
+Create an OCSP request and write it to a file:
+
+ openssl ocsp -issuer issuer.pem -cert c1.pem -cert c2.pem -reqout req.der
+
+Send a query to an OCSP responder with URL http://ocsp.myhost.com/ save the 
+response to a file and print it out in text form
+
+ openssl ocsp -issuer issuer.pem -cert c1.pem -cert c2.pem \
+     -url http://ocsp.myhost.com/ -resp_text -respout resp.der
+
+Read in an OCSP response and print out text form:
+
+ openssl ocsp -respin resp.der -text
+
+OCSP server on port 8888 using a standard B<ca> configuration, and a separate
+responder certificate. All requests and responses are printed to a file.
+
+ openssl ocsp -index demoCA/index.txt -port 8888 -rsigner rcert.pem -CA demoCA/cacert.pem
+	-text -out log.txt
+
+As above but exit after processing one request:
+
+ openssl ocsp -index demoCA/index.txt -port 8888 -rsigner rcert.pem -CA demoCA/cacert.pem
+     -nrequest 1
+
+Query status information using internally generated request:
+
+ openssl ocsp -index demoCA/index.txt -rsigner rcert.pem -CA demoCA/cacert.pem
+     -issuer demoCA/cacert.pem -serial 1
+
+Query status information using request read from a file, write response to a
+second file.
+
+ openssl ocsp -index demoCA/index.txt -rsigner rcert.pem -CA demoCA/cacert.pem
+     -reqin req.der -respout resp.der
diff --git a/openssl/doc/apps/openssl.pod b/openssl/doc/apps/openssl.pod
new file mode 100644
index 0000000..738142e
--- /dev/null
+++ b/openssl/doc/apps/openssl.pod
@@ -0,0 +1,422 @@
+
+=pod
+
+=head1 NAME
+
+openssl - OpenSSL command line tool
+
+=head1 SYNOPSIS
+
+B<openssl>
+I<command>
+[ I<command_opts> ]
+[ I<command_args> ]
+
+B<openssl> [ B<list-standard-commands> | B<list-message-digest-commands> | B<list-cipher-commands> | B<list-cipher-algorithms> | B<list-message-digest-algorithms> | B<list-public-key-algorithms>]
+
+B<openssl> B<no->I<XXX> [ I<arbitrary options> ]
+
+=head1 DESCRIPTION
+
+OpenSSL is a cryptography toolkit implementing the Secure Sockets Layer (SSL
+v2/v3) and Transport Layer Security (TLS v1) network protocols and related
+cryptography standards required by them.
+
+The B<openssl> program is a command line tool for using the various
+cryptography functions of OpenSSL's B<crypto> library from the shell. 
+It can be used for 
+
+ o  Creation and management of private keys, public keys and parameters
+ o  Public key cryptographic operations
+ o  Creation of X.509 certificates, CSRs and CRLs 
+ o  Calculation of Message Digests
+ o  Encryption and Decryption with Ciphers
+ o  SSL/TLS Client and Server Tests
+ o  Handling of S/MIME signed or encrypted mail
+ o  Time Stamp requests, generation and verification
+
+=head1 COMMAND SUMMARY
+
+The B<openssl> program provides a rich variety of commands (I<command> in the
+SYNOPSIS above), each of which often has a wealth of options and arguments
+(I<command_opts> and I<command_args> in the SYNOPSIS).
+
+The pseudo-commands B<list-standard-commands>, B<list-message-digest-commands>,
+and B<list-cipher-commands> output a list (one entry per line) of the names
+of all standard commands, message digest commands, or cipher commands,
+respectively, that are available in the present B<openssl> utility.
+
+The pseudo-commands B<list-cipher-algorithms> and
+B<list-message-digest-algorithms> list all cipher and message digest names, one entry per line. Aliases are listed as:
+
+ from => to
+
+The pseudo-command B<list-public-key-algorithms> lists all supported public
+key algorithms.
+
+The pseudo-command B<no->I<XXX> tests whether a command of the
+specified name is available.  If no command named I<XXX> exists, it
+returns 0 (success) and prints B<no->I<XXX>; otherwise it returns 1
+and prints I<XXX>.  In both cases, the output goes to B<stdout> and
+nothing is printed to B<stderr>.  Additional command line arguments
+are always ignored.  Since for each cipher there is a command of the
+same name, this provides an easy way for shell scripts to test for the
+availability of ciphers in the B<openssl> program.  (B<no->I<XXX> is
+not able to detect pseudo-commands such as B<quit>,
+B<list->I<...>B<-commands>, or B<no->I<XXX> itself.)
+
+=head2 STANDARD COMMANDS
+
+=over 10
+
+=item L<B<asn1parse>|asn1parse(1)>
+
+Parse an ASN.1 sequence.
+
+=item L<B<ca>|ca(1)>
+
+Certificate Authority (CA) Management.  
+
+=item L<B<ciphers>|ciphers(1)>
+
+Cipher Suite Description Determination.
+
+=item L<B<cms>|cms(1)>
+
+CMS (Cryptographic Message Syntax) utility
+
+=item L<B<crl>|crl(1)>
+
+Certificate Revocation List (CRL) Management.
+
+=item L<B<crl2pkcs7>|crl2pkcs7(1)>
+
+CRL to PKCS#7 Conversion.
+
+=item L<B<dgst>|dgst(1)>
+
+Message Digest Calculation.
+
+=item B<dh>
+
+Diffie-Hellman Parameter Management.
+Obsoleted by L<B<dhparam>|dhparam(1)>.
+
+=item L<B<dhparam>|dhparam(1)>
+
+Generation and Management of Diffie-Hellman Parameters. Superseded by 
+L<B<genpkey>|genpkey(1)> and L<B<pkeyparam>|pkeyparam(1)>
+
+
+=item L<B<dsa>|dsa(1)>
+
+DSA Data Management.
+
+=item L<B<dsaparam>|dsaparam(1)>
+
+DSA Parameter Generation and Management. Superseded by 
+L<B<genpkey>|genpkey(1)> and L<B<pkeyparam>|pkeyparam(1)>
+
+=item L<B<ec>|ec(1)>
+
+EC (Elliptic curve) key processing
+
+=item L<B<ecparam>|ecparam(1)>
+
+EC parameter manipulation and generation
+
+=item L<B<enc>|enc(1)>
+
+Encoding with Ciphers.
+
+=item L<B<engine>|engine(1)>
+
+Engine (loadble module) information and manipulation.
+
+=item L<B<errstr>|errstr(1)>
+
+Error Number to Error String Conversion.
+
+=item B<gendh>
+
+Generation of Diffie-Hellman Parameters.
+Obsoleted by L<B<dhparam>|dhparam(1)>.
+
+=item L<B<gendsa>|gendsa(1)>
+
+Generation of DSA Private Key from Parameters. Superseded by 
+L<B<genpkey>|genpkey(1)> and L<B<pkey>|pkey(1)>
+
+=item L<B<genpkey>|genpkey(1)>
+
+Generation of Private Key or Parameters.
+
+=item L<B<genrsa>|genrsa(1)>
+
+Generation of RSA Private Key. Superceded by L<B<genpkey>|genpkey(1)>.
+
+=item L<B<nseq>|nseq(1)>
+
+Create or examine a netscape certificate sequence
+
+=item L<B<ocsp>|ocsp(1)>
+
+Online Certificate Status Protocol utility.
+
+=item L<B<passwd>|passwd(1)>
+
+Generation of hashed passwords.
+
+=item L<B<pkcs12>|pkcs12(1)>
+
+PKCS#12 Data Management.
+
+=item L<B<pkcs7>|pkcs7(1)>
+
+PKCS#7 Data Management.
+
+=item L<B<pkey>|pkey(1)>
+
+Public and private key management.
+
+=item L<B<pkeyparam>|pkeyparam(1)>
+
+Public key algorithm parameter management.
+
+=item L<B<pkeyutl>|pkeyutl(1)>
+
+Public key algorithm cryptographic operation utility.
+
+=item L<B<rand>|rand(1)>
+
+Generate pseudo-random bytes.
+
+=item L<B<req>|req(1)>
+
+PKCS#10 X.509 Certificate Signing Request (CSR) Management.
+
+=item L<B<rsa>|rsa(1)>
+
+RSA key management.
+
+
+=item L<B<rsautl>|rsautl(1)>
+
+RSA utility for signing, verification, encryption, and decryption. Superseded
+by  L<B<pkeyutl>|pkeyutl(1)>
+
+=item L<B<s_client>|s_client(1)>
+
+This implements a generic SSL/TLS client which can establish a transparent
+connection to a remote server speaking SSL/TLS. It's intended for testing
+purposes only and provides only rudimentary interface functionality but
+internally uses mostly all functionality of the OpenSSL B<ssl> library.
+
+=item L<B<s_server>|s_server(1)>
+
+This implements a generic SSL/TLS server which accepts connections from remote
+clients speaking SSL/TLS. It's intended for testing purposes only and provides
+only rudimentary interface functionality but internally uses mostly all
+functionality of the OpenSSL B<ssl> library.  It provides both an own command
+line oriented protocol for testing SSL functions and a simple HTTP response
+facility to emulate an SSL/TLS-aware webserver.
+
+=item L<B<s_time>|s_time(1)>
+
+SSL Connection Timer.
+
+=item L<B<sess_id>|sess_id(1)>
+
+SSL Session Data Management.
+
+=item L<B<smime>|smime(1)>
+
+S/MIME mail processing.
+
+=item L<B<speed>|speed(1)>
+
+Algorithm Speed Measurement.
+
+=item L<B<spkac>|spkac(1)>
+
+SPKAC printing and generating utility
+
+=item L<B<ts>|ts(1)>
+
+Time Stamping Authority tool (client/server)
+
+=item L<B<verify>|verify(1)>
+
+X.509 Certificate Verification.
+
+=item L<B<version>|version(1)>
+
+OpenSSL Version Information.
+
+=item L<B<x509>|x509(1)>
+
+X.509 Certificate Data Management.
+
+=back
+
+=head2 MESSAGE DIGEST COMMANDS
+
+=over 10
+
+=item B<md2>
+
+MD2 Digest
+
+=item B<md5>
+
+MD5 Digest
+
+=item B<mdc2>
+
+MDC2 Digest
+
+=item B<rmd160>
+
+RMD-160 Digest
+
+=item B<sha>            
+
+SHA Digest
+
+=item B<sha1>           
+
+SHA-1 Digest
+
+=back
+
+=item B<sha224>
+
+SHA-224 Digest
+
+=item B<sha256>
+
+SHA-256 Digest
+
+=item B<sha384>
+
+SHA-384 Digest
+
+=item B<sha512>
+
+SHA-512 Digest
+
+=head2 ENCODING AND CIPHER COMMANDS
+
+=over 10
+
+=item B<base64>
+
+Base64 Encoding
+
+=item B<bf bf-cbc bf-cfb bf-ecb bf-ofb>
+
+Blowfish Cipher
+
+=item B<cast cast-cbc>
+
+CAST Cipher
+
+=item B<cast5-cbc cast5-cfb cast5-ecb cast5-ofb>
+
+CAST5 Cipher
+
+=item B<des des-cbc des-cfb des-ecb des-ede des-ede-cbc des-ede-cfb des-ede-ofb des-ofb>
+
+DES Cipher
+
+=item B<des3 desx des-ede3 des-ede3-cbc des-ede3-cfb des-ede3-ofb>
+
+Triple-DES Cipher
+
+=item B<idea idea-cbc idea-cfb idea-ecb idea-ofb>
+
+IDEA Cipher
+
+=item B<rc2 rc2-cbc rc2-cfb rc2-ecb rc2-ofb>
+
+RC2 Cipher
+
+=item B<rc4>
+
+RC4 Cipher
+
+=item B<rc5 rc5-cbc rc5-cfb rc5-ecb rc5-ofb>
+
+RC5 Cipher
+
+=back
+
+=head1 PASS PHRASE ARGUMENTS
+
+Several commands accept password arguments, typically using B<-passin>
+and B<-passout> for input and output passwords respectively. These allow
+the password to be obtained from a variety of sources. Both of these
+options take a single argument whose format is described below. If no
+password argument is given and a password is required then the user is
+prompted to enter one: this will typically be read from the current
+terminal with echoing turned off.
+
+=over 10
+
+=item B<pass:password>
+
+the actual password is B<password>. Since the password is visible
+to utilities (like 'ps' under Unix) this form should only be used
+where security is not important.
+
+=item B<env:var>
+
+obtain the password from the environment variable B<var>. Since
+the environment of other processes is visible on certain platforms
+(e.g. ps under certain Unix OSes) this option should be used with caution.
+
+=item B<file:pathname>
+
+the first line of B<pathname> is the password. If the same B<pathname>
+argument is supplied to B<-passin> and B<-passout> arguments then the first
+line will be used for the input password and the next line for the output
+password. B<pathname> need not refer to a regular file: it could for example
+refer to a device or named pipe.
+
+=item B<fd:number>
+
+read the password from the file descriptor B<number>. This can be used to
+send the data via a pipe for example.
+
+=item B<stdin>
+
+read the password from standard input.
+
+=back
+
+=head1 SEE ALSO
+
+L<asn1parse(1)|asn1parse(1)>, L<ca(1)|ca(1)>, L<config(5)|config(5)>,
+L<crl(1)|crl(1)>, L<crl2pkcs7(1)|crl2pkcs7(1)>, L<dgst(1)|dgst(1)>,
+L<dhparam(1)|dhparam(1)>, L<dsa(1)|dsa(1)>, L<dsaparam(1)|dsaparam(1)>,
+L<enc(1)|enc(1)>, L<gendsa(1)|gendsa(1)>, L<genpkey(1)|genpkey(1)>,
+L<genrsa(1)|genrsa(1)>, L<nseq(1)|nseq(1)>, L<openssl(1)|openssl(1)>,
+L<passwd(1)|passwd(1)>,
+L<pkcs12(1)|pkcs12(1)>, L<pkcs7(1)|pkcs7(1)>, L<pkcs8(1)|pkcs8(1)>,
+L<rand(1)|rand(1)>, L<req(1)|req(1)>, L<rsa(1)|rsa(1)>,
+L<rsautl(1)|rsautl(1)>, L<s_client(1)|s_client(1)>,
+L<s_server(1)|s_server(1)>, L<s_time(1)|s_time(1)>,
+L<smime(1)|smime(1)>, L<spkac(1)|spkac(1)>,
+L<verify(1)|verify(1)>, L<version(1)|version(1)>, L<x509(1)|x509(1)>,
+L<crypto(3)|crypto(3)>, L<ssl(3)|ssl(3)>, L<x509v3_config(5)|x509v3_config(5)> 
+
+=head1 HISTORY
+
+The openssl(1) document appeared in OpenSSL 0.9.2.
+The B<list->I<XXX>B<-commands> pseudo-commands were added in OpenSSL 0.9.3;
+The B<list->I<XXX>B<-algorithms> pseudo-commands were added in OpenSSL 1.0.0;
+the B<no->I<XXX> pseudo-commands were added in OpenSSL 0.9.5a.
+For notes on the availability of other commands, see their individual
+manual pages.
+
+=cut
diff --git a/openssl/doc/apps/passwd.pod b/openssl/doc/apps/passwd.pod
new file mode 100644
index 0000000..f449825
--- /dev/null
+++ b/openssl/doc/apps/passwd.pod
@@ -0,0 +1,82 @@
+=pod
+
+=head1 NAME
+
+passwd - compute password hashes
+
+=head1 SYNOPSIS
+
+B<openssl passwd>
+[B<-crypt>]
+[B<-1>]
+[B<-apr1>]
+[B<-salt> I<string>]
+[B<-in> I<file>]
+[B<-stdin>]
+[B<-noverify>]
+[B<-quiet>]
+[B<-table>]
+{I<password>}
+
+=head1 DESCRIPTION
+
+The B<passwd> command computes the hash of a password typed at
+run-time or the hash of each password in a list.  The password list is
+taken from the named file for option B<-in file>, from stdin for
+option B<-stdin>, or from the command line, or from the terminal otherwise.
+The Unix standard algorithm B<crypt> and the MD5-based BSD password
+algorithm B<1> and its Apache variant B<apr1> are available.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-crypt>
+
+Use the B<crypt> algorithm (default).
+
+=item B<-1>
+
+Use the MD5 based BSD password algorithm B<1>.
+
+=item B<-apr1>
+
+Use the B<apr1> algorithm (Apache variant of the BSD algorithm).
+
+=item B<-salt> I<string>
+
+Use the specified salt.
+When reading a password from the terminal, this implies B<-noverify>.
+
+=item B<-in> I<file>
+
+Read passwords from I<file>.
+
+=item B<-stdin>
+
+Read passwords from B<stdin>.
+
+=item B<-noverify>
+
+Don't verify when reading a password from the terminal.
+
+=item B<-quiet>
+
+Don't output warnings when passwords given at the command line are truncated.
+
+=item B<-table>
+
+In the output list, prepend the cleartext password and a TAB character
+to each password hash.
+
+=back
+
+=head1 EXAMPLES
+
+B<openssl passwd -crypt -salt xx password> prints B<xxj31ZMTZzkVA>.
+
+B<openssl passwd -1 -salt xxxxxxxx password> prints B<$1$xxxxxxxx$UYCIxa628.9qXjpQCjM4a.>.
+
+B<openssl passwd -apr1 -salt xxxxxxxx password> prints B<$apr1$xxxxxxxx$dxHfLAsjHkDRmG83UXe8K0>.
+
+=cut
diff --git a/openssl/doc/apps/pkcs12.pod b/openssl/doc/apps/pkcs12.pod
new file mode 100644
index 0000000..f69a5c5
--- /dev/null
+++ b/openssl/doc/apps/pkcs12.pod
@@ -0,0 +1,363 @@
+
+=pod
+
+=head1 NAME
+
+pkcs12 - PKCS#12 file utility
+
+=head1 SYNOPSIS
+
+B<openssl> B<pkcs12>
+[B<-export>]
+[B<-chain>]
+[B<-inkey filename>]
+[B<-certfile filename>]
+[B<-name name>]
+[B<-caname name>]
+[B<-in filename>]
+[B<-out filename>]
+[B<-noout>]
+[B<-nomacver>]
+[B<-nocerts>]
+[B<-clcerts>]
+[B<-cacerts>]
+[B<-nokeys>]
+[B<-info>]
+[B<-des | -des3 | -idea | -aes128 | -aes192 | -aes256 | -camellia128 | -camellia192 | -camellia256 | -nodes>]
+[B<-noiter>]
+[B<-maciter | -nomaciter | -nomac>]
+[B<-twopass>]
+[B<-descert>]
+[B<-certpbe cipher>]
+[B<-keypbe cipher>]
+[B<-macalg digest>]
+[B<-keyex>]
+[B<-keysig>]
+[B<-password arg>]
+[B<-passin arg>]
+[B<-passout arg>]
+[B<-rand file(s)>]
+[B<-CAfile file>]
+[B<-CApath dir>]
+[B<-CSP name>]
+
+=head1 DESCRIPTION
+
+The B<pkcs12> command allows PKCS#12 files (sometimes referred to as
+PFX files) to be created and parsed. PKCS#12 files are used by several
+programs including Netscape, MSIE and MS Outlook.
+
+=head1 COMMAND OPTIONS
+
+There are a lot of options the meaning of some depends of whether a PKCS#12 file
+is being created or parsed. By default a PKCS#12 file is parsed. A PKCS#12
+file can be created by using the B<-export> option (see below).
+
+=head1 PARSING OPTIONS
+
+=over 4
+
+=item B<-in filename>
+
+This specifies filename of the PKCS#12 file to be parsed. Standard input is used
+by default.
+
+=item B<-out filename>
+
+The filename to write certificates and private keys to, standard output by
+default.  They are all written in PEM format.
+
+=item B<-pass arg>, B<-passin arg>
+
+the PKCS#12 file (i.e. input file) password source. For more information about
+the format of B<arg> see the B<PASS PHRASE ARGUMENTS> section in
+L<openssl(1)|openssl(1)>.
+
+=item B<-passout arg>
+
+pass phrase source to encrypt any outputed private keys with. For more
+information about the format of B<arg> see the B<PASS PHRASE ARGUMENTS> section
+in L<openssl(1)|openssl(1)>.
+
+=item B<-noout>
+
+this option inhibits output of the keys and certificates to the output file
+version of the PKCS#12 file.
+
+=item B<-clcerts>
+
+only output client certificates (not CA certificates).
+
+=item B<-cacerts>
+
+only output CA certificates (not client certificates).
+
+=item B<-nocerts>
+
+no certificates at all will be output.
+
+=item B<-nokeys>
+
+no private keys will be output.
+
+=item B<-info>
+
+output additional information about the PKCS#12 file structure, algorithms used and
+iteration counts.
+
+=item B<-des>
+
+use DES to encrypt private keys before outputting.
+
+=item B<-des3>
+
+use triple DES to encrypt private keys before outputting, this is the default.
+
+=item B<-idea>
+
+use IDEA to encrypt private keys before outputting.
+
+=item B<-aes128>, B<-aes192>, B<-aes256>
+
+use AES to encrypt private keys before outputting.
+
+=item B<-camellia128>, B<-camellia192>, B<-camellia256>
+
+use Camellia to encrypt private keys before outputting.
+
+=item B<-nodes>
+
+don't encrypt the private keys at all.
+
+=item B<-nomacver>
+
+don't attempt to verify the integrity MAC before reading the file.
+
+=item B<-twopass>
+
+prompt for separate integrity and encryption passwords: most software
+always assumes these are the same so this option will render such
+PKCS#12 files unreadable.
+
+=back
+
+=head1 FILE CREATION OPTIONS
+
+=over 4
+
+=item B<-export>
+
+This option specifies that a PKCS#12 file will be created rather than
+parsed.
+
+=item B<-out filename>
+
+This specifies filename to write the PKCS#12 file to. Standard output is used
+by default.
+
+=item B<-in filename>
+
+The filename to read certificates and private keys from, standard input by
+default.  They must all be in PEM format. The order doesn't matter but one
+private key and its corresponding certificate should be present. If additional
+certificates are present they will also be included in the PKCS#12 file.
+
+=item B<-inkey filename>
+
+file to read private key from. If not present then a private key must be present
+in the input file.
+
+=item B<-name friendlyname>
+
+This specifies the "friendly name" for the certificate and private key. This
+name is typically displayed in list boxes by software importing the file.
+
+=item B<-certfile filename>
+
+A filename to read additional certificates from.
+
+=item B<-caname friendlyname>
+
+This specifies the "friendly name" for other certificates. This option may be
+used multiple times to specify names for all certificates in the order they
+appear. Netscape ignores friendly names on other certificates whereas MSIE
+displays them.
+
+=item B<-pass arg>, B<-passout arg>
+
+the PKCS#12 file (i.e. output file) password source. For more information about
+the format of B<arg> see the B<PASS PHRASE ARGUMENTS> section in
+L<openssl(1)|openssl(1)>.
+
+=item B<-passin password>
+
+pass phrase source to decrypt any input private keys with. For more information
+about the format of B<arg> see the B<PASS PHRASE ARGUMENTS> section in
+L<openssl(1)|openssl(1)>.
+
+=item B<-chain>
+
+if this option is present then an attempt is made to include the entire
+certificate chain of the user certificate. The standard CA store is used
+for this search. If the search fails it is considered a fatal error.
+
+=item B<-descert>
+
+encrypt the certificate using triple DES, this may render the PKCS#12
+file unreadable by some "export grade" software. By default the private
+key is encrypted using triple DES and the certificate using 40 bit RC2.
+
+=item B<-keypbe alg>, B<-certpbe alg>
+
+these options allow the algorithm used to encrypt the private key and
+certificates to be selected. Any PKCS#5 v1.5 or PKCS#12 PBE algorithm name
+can be used (see B<NOTES> section for more information). If a a cipher name
+(as output by the B<list-cipher-algorithms> command is specified then it
+is used with PKCS#5 v2.0. For interoperability reasons it is advisable to only
+use PKCS#12 algorithms.
+
+=item B<-keyex|-keysig>
+
+specifies that the private key is to be used for key exchange or just signing.
+This option is only interpreted by MSIE and similar MS software. Normally
+"export grade" software will only allow 512 bit RSA keys to be used for
+encryption purposes but arbitrary length keys for signing. The B<-keysig>
+option marks the key for signing only. Signing only keys can be used for
+S/MIME signing, authenticode (ActiveX control signing)  and SSL client
+authentication, however due to a bug only MSIE 5.0 and later support
+the use of signing only keys for SSL client authentication.
+
+=item B<-macalg digest>
+
+specify the MAC digest algorithm. If not included them SHA1 will be used.
+
+=item B<-nomaciter>, B<-noiter>
+
+these options affect the iteration counts on the MAC and key algorithms.
+Unless you wish to produce files compatible with MSIE 4.0 you should leave
+these options alone.
+
+To discourage attacks by using large dictionaries of common passwords the
+algorithm that derives keys from passwords can have an iteration count applied
+to it: this causes a certain part of the algorithm to be repeated and slows it
+down. The MAC is used to check the file integrity but since it will normally
+have the same password as the keys and certificates it could also be attacked.
+By default both MAC and encryption iteration counts are set to 2048, using
+these options the MAC and encryption iteration counts can be set to 1, since
+this reduces the file security you should not use these options unless you
+really have to. Most software supports both MAC and key iteration counts.
+MSIE 4.0 doesn't support MAC iteration counts so it needs the B<-nomaciter>
+option.
+
+=item B<-maciter>
+
+This option is included for compatibility with previous versions, it used
+to be needed to use MAC iterations counts but they are now used by default.
+
+=item B<-nomac>
+
+don't attempt to provide the MAC integrity.
+
+=item B<-rand file(s)>
+
+a file or files containing random data used to seed the random number
+generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
+Multiple files can be specified separated by a OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item B<-CAfile file>
+
+CA storage as a file.
+
+=item B<-CApath dir>
+
+CA storage as a directory. This directory must be a standard certificate
+directory: that is a hash of each subject name (using B<x509 -hash>) should be
+linked to each certificate.
+
+=item B<-CSP name>
+
+write B<name> as a Microsoft CSP name.
+
+=back
+
+=head1 NOTES
+
+Although there are a large number of options most of them are very rarely
+used. For PKCS#12 file parsing only B<-in> and B<-out> need to be used
+for PKCS#12 file creation B<-export> and B<-name> are also used.
+
+If none of the B<-clcerts>, B<-cacerts> or B<-nocerts> options are present
+then all certificates will be output in the order they appear in the input
+PKCS#12 files. There is no guarantee that the first certificate present is
+the one corresponding to the private key. Certain software which requires
+a private key and certificate and assumes the first certificate in the
+file is the one corresponding to the private key: this may not always
+be the case. Using the B<-clcerts> option will solve this problem by only
+outputting the certificate corresponding to the private key. If the CA
+certificates are required then they can be output to a separate file using
+the B<-nokeys -cacerts> options to just output CA certificates.
+
+The B<-keypbe> and B<-certpbe> algorithms allow the precise encryption
+algorithms for private keys and certificates to be specified. Normally
+the defaults are fine but occasionally software can't handle triple DES
+encrypted private keys, then the option B<-keypbe PBE-SHA1-RC2-40> can
+be used to reduce the private key encryption to 40 bit RC2. A complete
+description of all algorithms is contained in the B<pkcs8> manual page.
+
+=head1 EXAMPLES
+
+Parse a PKCS#12 file and output it to a file:
+
+ openssl pkcs12 -in file.p12 -out file.pem
+
+Output only client certificates to a file:
+
+ openssl pkcs12 -in file.p12 -clcerts -out file.pem
+
+Don't encrypt the private key:
+ 
+ openssl pkcs12 -in file.p12 -out file.pem -nodes
+
+Print some info about a PKCS#12 file:
+
+ openssl pkcs12 -in file.p12 -info -noout
+
+Create a PKCS#12 file:
+
+ openssl pkcs12 -export -in file.pem -out file.p12 -name "My Certificate"
+
+Include some extra certificates:
+
+ openssl pkcs12 -export -in file.pem -out file.p12 -name "My Certificate" \
+  -certfile othercerts.pem
+
+=head1 BUGS
+
+Some would argue that the PKCS#12 standard is one big bug :-)
+
+Versions of OpenSSL before 0.9.6a had a bug in the PKCS#12 key generation
+routines. Under rare circumstances this could produce a PKCS#12 file encrypted
+with an invalid key. As a result some PKCS#12 files which triggered this bug
+from other implementations (MSIE or Netscape) could not be decrypted
+by OpenSSL and similarly OpenSSL could produce PKCS#12 files which could
+not be decrypted by other implementations. The chances of producing such
+a file are relatively small: less than 1 in 256.
+
+A side effect of fixing this bug is that any old invalidly encrypted PKCS#12
+files cannot no longer be parsed by the fixed version. Under such circumstances
+the B<pkcs12> utility will report that the MAC is OK but fail with a decryption
+error when extracting private keys.
+
+This problem can be resolved by extracting the private keys and certificates
+from the PKCS#12 file using an older version of OpenSSL and recreating the PKCS#12
+file from the keys and certificates using a newer version of OpenSSL. For example:
+
+ old-openssl -in bad.p12 -out keycerts.pem
+ openssl -in keycerts.pem -export -name "My PKCS#12 file" -out fixed.p12
+
+=head1 SEE ALSO
+
+L<pkcs8(1)|pkcs8(1)>
+
diff --git a/openssl/doc/apps/pkcs7.pod b/openssl/doc/apps/pkcs7.pod
new file mode 100644
index 0000000..acfb810
--- /dev/null
+++ b/openssl/doc/apps/pkcs7.pod
@@ -0,0 +1,105 @@
+=pod
+
+=head1 NAME
+
+pkcs7 - PKCS#7 utility
+
+=head1 SYNOPSIS
+
+B<openssl> B<pkcs7>
+[B<-inform PEM|DER>]
+[B<-outform PEM|DER>]
+[B<-in filename>]
+[B<-out filename>]
+[B<-print_certs>]
+[B<-text>]
+[B<-noout>]
+[B<-engine id>]
+
+=head1 DESCRIPTION
+
+The B<pkcs7> command processes PKCS#7 files in DER or PEM format.
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<-inform DER|PEM>
+
+This specifies the input format. B<DER> format is DER encoded PKCS#7
+v1.5 structure.B<PEM> (the default) is a base64 encoded version of
+the DER form with header and footer lines.
+
+=item B<-outform DER|PEM>
+
+This specifies the output format, the options have the same meaning as the 
+B<-inform> option.
+
+=item B<-in filename>
+
+This specifies the input filename to read from or standard input if this
+option is not specified.
+
+=item B<-out filename>
+
+specifies the output filename to write to or standard output by
+default.
+
+=item B<-print_certs>
+
+prints out any certificates or CRLs contained in the file. They are
+preceded by their subject and issuer names in one line format.
+
+=item B<-text>
+
+prints out certificates details in full rather than just subject and
+issuer names.
+
+=item B<-noout>
+
+don't output the encoded version of the PKCS#7 structure (or certificates
+is B<-print_certs> is set).
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<pkcs7>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=back
+
+=head1 EXAMPLES
+
+Convert a PKCS#7 file from PEM to DER:
+
+ openssl pkcs7 -in file.pem -outform DER -out file.der
+
+Output all certificates in a file:
+
+ openssl pkcs7 -in file.pem -print_certs -out certs.pem
+
+=head1 NOTES
+
+The PEM PKCS#7 format uses the header and footer lines:
+
+ -----BEGIN PKCS7-----
+ -----END PKCS7-----
+
+For compatibility with some CAs it will also accept:
+
+ -----BEGIN CERTIFICATE-----
+ -----END CERTIFICATE-----
+
+=head1 RESTRICTIONS
+
+There is no option to print out all the fields of a PKCS#7 file.
+
+This PKCS#7 routines only understand PKCS#7 v 1.5 as specified in RFC2315 they 
+cannot currently parse, for example, the new CMS as described in RFC2630.
+
+=head1 SEE ALSO
+
+L<crl2pkcs7(1)|crl2pkcs7(1)>
+
+=cut
diff --git a/openssl/doc/apps/pkcs8.pod b/openssl/doc/apps/pkcs8.pod
new file mode 100644
index 0000000..84abee7
--- /dev/null
+++ b/openssl/doc/apps/pkcs8.pod
@@ -0,0 +1,243 @@
+=pod
+
+=head1 NAME
+
+pkcs8 - PKCS#8 format private key conversion tool
+
+=head1 SYNOPSIS
+
+B<openssl> B<pkcs8>
+[B<-topk8>]
+[B<-inform PEM|DER>]
+[B<-outform PEM|DER>]
+[B<-in filename>]
+[B<-passin arg>]
+[B<-out filename>]
+[B<-passout arg>]
+[B<-noiter>]
+[B<-nocrypt>]
+[B<-nooct>]
+[B<-embed>]
+[B<-nsdb>]
+[B<-v2 alg>]
+[B<-v1 alg>]
+[B<-engine id>]
+
+=head1 DESCRIPTION
+
+The B<pkcs8> command processes private keys in PKCS#8 format. It can handle
+both unencrypted PKCS#8 PrivateKeyInfo format and EncryptedPrivateKeyInfo
+format with a variety of PKCS#5 (v1.5 and v2.0) and PKCS#12 algorithms.
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<-topk8>
+
+Normally a PKCS#8 private key is expected on input and a traditional format
+private key will be written. With the B<-topk8> option the situation is
+reversed: it reads a traditional format private key and writes a PKCS#8
+format key.
+
+=item B<-inform DER|PEM>
+
+This specifies the input format. If a PKCS#8 format key is expected on input
+then either a B<DER> or B<PEM> encoded version of a PKCS#8 key will be
+expected. Otherwise the B<DER> or B<PEM> format of the traditional format
+private key is used.
+
+=item B<-outform DER|PEM>
+
+This specifies the output format, the options have the same meaning as the 
+B<-inform> option.
+
+=item B<-in filename>
+
+This specifies the input filename to read a key from or standard input if this
+option is not specified. If the key is encrypted a pass phrase will be
+prompted for.
+
+=item B<-passin arg>
+
+the input file password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-out filename>
+
+This specifies the output filename to write a key to or standard output by
+default. If any encryption options are set then a pass phrase will be
+prompted for. The output filename should B<not> be the same as the input
+filename.
+
+=item B<-passout arg>
+
+the output file password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-nocrypt>
+
+PKCS#8 keys generated or input are normally PKCS#8 EncryptedPrivateKeyInfo
+structures using an appropriate password based encryption algorithm. With
+this option an unencrypted PrivateKeyInfo structure is expected or output.
+This option does not encrypt private keys at all and should only be used
+when absolutely necessary. Certain software such as some versions of Java
+code signing software used unencrypted private keys.
+
+=item B<-nooct>
+
+This option generates RSA private keys in a broken format that some software
+uses. Specifically the private key should be enclosed in a OCTET STRING
+but some software just includes the structure itself without the
+surrounding OCTET STRING.
+
+=item B<-embed>
+
+This option generates DSA keys in a broken format. The DSA parameters are
+embedded inside the PrivateKey structure. In this form the OCTET STRING
+contains an ASN1 SEQUENCE consisting of two structures: a SEQUENCE containing
+the parameters and an ASN1 INTEGER containing the private key.
+
+=item B<-nsdb>
+
+This option generates DSA keys in a broken format compatible with Netscape
+private key databases. The PrivateKey contains a SEQUENCE consisting of
+the public and private keys respectively.
+
+=item B<-v2 alg>
+
+This option enables the use of PKCS#5 v2.0 algorithms. Normally PKCS#8
+private keys are encrypted with the password based encryption algorithm
+called B<pbeWithMD5AndDES-CBC> this uses 56 bit DES encryption but it
+was the strongest encryption algorithm supported in PKCS#5 v1.5. Using 
+the B<-v2> option PKCS#5 v2.0 algorithms are used which can use any
+encryption algorithm such as 168 bit triple DES or 128 bit RC2 however
+not many implementations support PKCS#5 v2.0 yet. If you are just using
+private keys with OpenSSL then this doesn't matter.
+
+The B<alg> argument is the encryption algorithm to use, valid values include
+B<des>, B<des3> and B<rc2>. It is recommended that B<des3> is used.
+
+=item B<-v1 alg>
+
+This option specifies a PKCS#5 v1.5 or PKCS#12 algorithm to use. A complete
+list of possible algorithms is included below.
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<pkcs8>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=back
+
+=head1 NOTES
+
+The encrypted form of a PEM encode PKCS#8 files uses the following
+headers and footers:
+
+ -----BEGIN ENCRYPTED PRIVATE KEY-----
+ -----END ENCRYPTED PRIVATE KEY-----
+
+The unencrypted form uses:
+
+ -----BEGIN PRIVATE KEY-----
+ -----END PRIVATE KEY-----
+
+Private keys encrypted using PKCS#5 v2.0 algorithms and high iteration
+counts are more secure that those encrypted using the traditional
+SSLeay compatible formats. So if additional security is considered
+important the keys should be converted.
+
+The default encryption is only 56 bits because this is the encryption
+that most current implementations of PKCS#8 will support.
+
+Some software may use PKCS#12 password based encryption algorithms
+with PKCS#8 format private keys: these are handled automatically
+but there is no option to produce them.
+
+It is possible to write out DER encoded encrypted private keys in
+PKCS#8 format because the encryption details are included at an ASN1
+level whereas the traditional format includes them at a PEM level.
+
+=head1 PKCS#5 v1.5 and PKCS#12 algorithms.
+
+Various algorithms can be used with the B<-v1> command line option,
+including PKCS#5 v1.5 and PKCS#12. These are described in more detail
+below.
+
+=over 4
+
+=item B<PBE-MD2-DES PBE-MD5-DES>
+
+These algorithms were included in the original PKCS#5 v1.5 specification.
+They only offer 56 bits of protection since they both use DES.
+
+=item B<PBE-SHA1-RC2-64 PBE-MD2-RC2-64 PBE-MD5-RC2-64 PBE-SHA1-DES>
+
+These algorithms are not mentioned in the original PKCS#5 v1.5 specification
+but they use the same key derivation algorithm and are supported by some
+software. They are mentioned in PKCS#5 v2.0. They use either 64 bit RC2 or
+56 bit DES.
+
+=item B<PBE-SHA1-RC4-128 PBE-SHA1-RC4-40 PBE-SHA1-3DES PBE-SHA1-2DES PBE-SHA1-RC2-128 PBE-SHA1-RC2-40>
+
+These algorithms use the PKCS#12 password based encryption algorithm and
+allow strong encryption algorithms like triple DES or 128 bit RC2 to be used.
+
+=back
+
+=head1 EXAMPLES
+
+Convert a private from traditional to PKCS#5 v2.0 format using triple
+DES:
+
+ openssl pkcs8 -in key.pem -topk8 -v2 des3 -out enckey.pem
+
+Convert a private key to PKCS#8 using a PKCS#5 1.5 compatible algorithm
+(DES):
+
+ openssl pkcs8 -in key.pem -topk8 -out enckey.pem
+
+Convert a private key to PKCS#8 using a PKCS#12 compatible algorithm
+(3DES):
+
+ openssl pkcs8 -in key.pem -topk8 -out enckey.pem -v1 PBE-SHA1-3DES
+
+Read a DER unencrypted PKCS#8 format private key:
+
+ openssl pkcs8 -inform DER -nocrypt -in key.der -out key.pem
+
+Convert a private key from any PKCS#8 format to traditional format:
+
+ openssl pkcs8 -in pk8.pem -out key.pem
+
+=head1 STANDARDS
+
+Test vectors from this PKCS#5 v2.0 implementation were posted to the
+pkcs-tng mailing list using triple DES, DES and RC2 with high iteration
+counts, several people confirmed that they could decrypt the private
+keys produced and Therefore it can be assumed that the PKCS#5 v2.0
+implementation is reasonably accurate at least as far as these
+algorithms are concerned.
+
+The format of PKCS#8 DSA (and other) private keys is not well documented:
+it is hidden away in PKCS#11 v2.01, section 11.9. OpenSSL's default DSA
+PKCS#8 private key format complies with this standard.
+
+=head1 BUGS
+
+There should be an option that prints out the encryption algorithm
+in use and other details such as the iteration count.
+
+PKCS#8 using triple DES and PKCS#5 v2.0 should be the default private
+key format for OpenSSL: for compatibility several of the utilities use
+the old format at present.
+
+=head1 SEE ALSO
+
+L<dsa(1)|dsa(1)>, L<rsa(1)|rsa(1)>, L<genrsa(1)|genrsa(1)>,
+L<gendsa(1)|gendsa(1)> 
+
+=cut
diff --git a/openssl/doc/apps/pkey.pod b/openssl/doc/apps/pkey.pod
new file mode 100644
index 0000000..4851223
--- /dev/null
+++ b/openssl/doc/apps/pkey.pod
@@ -0,0 +1,135 @@
+
+=pod
+
+=head1 NAME
+
+pkey - public or private key processing tool
+
+=head1 SYNOPSIS
+
+B<openssl> B<pkey>
+[B<-inform PEM|DER>]
+[B<-outform PEM|DER>]
+[B<-in filename>]
+[B<-passin arg>]
+[B<-out filename>]
+[B<-passout arg>]
+[B<-cipher>]
+[B<-text>]
+[B<-text_pub>]
+[B<-noout>]
+[B<-pubin>]
+[B<-pubout>]
+[B<-engine id>]
+
+=head1 DESCRIPTION
+
+The B<pkey> command processes public or private keys. They can be converted
+between various forms and their components printed out.
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<-inform DER|PEM>
+
+This specifies the input format DER or PEM.
+
+=item B<-outform DER|PEM>
+
+This specifies the output format, the options have the same meaning as the 
+B<-inform> option.
+
+=item B<-in filename>
+
+This specifies the input filename to read a key from or standard input if this
+option is not specified. If the key is encrypted a pass phrase will be
+prompted for.
+
+=item B<-passin arg>
+
+the input file password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-out filename>
+
+This specifies the output filename to write a key to or standard output if this
+option is not specified. If any encryption options are set then a pass phrase
+will be prompted for. The output filename should B<not> be the same as the input
+filename.
+
+=item B<-passout password>
+
+the output file password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-cipher>
+
+These options encrypt the private key with the supplied cipher. Any algorithm
+name accepted by EVP_get_cipherbyname() is acceptable such as B<des3>.
+
+=item B<-text>
+
+prints out the various public or private key components in
+plain text in addition to the encoded version. 
+
+=item B<-text_pub>
+
+print out only public key components even if a private key is being processed.
+
+=item B<-noout>
+
+do not output the encoded version of the key.
+
+=item B<-pubin>
+
+by default a private key is read from the input file: with this
+option a public key is read instead.
+
+=item B<-pubout>
+
+by default a private key is output: with this option a public
+key will be output instead. This option is automatically set if
+the input is a public key.
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<pkey>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=back
+
+=head1 EXAMPLES
+
+To remove the pass phrase on an RSA private key:
+
+ openssl pkey -in key.pem -out keyout.pem
+
+To encrypt a private key using triple DES:
+
+ openssl pkey -in key.pem -des3 -out keyout.pem
+
+To convert a private key from PEM to DER format: 
+
+ openssl pkey -in key.pem -outform DER -out keyout.der
+
+To print out the components of a private key to standard output:
+
+ openssl pkey -in key.pem -text -noout
+
+To print out the public components of a private key to standard output:
+
+ openssl pkey -in key.pem -text_pub -noout
+
+To just output the public part of a private key:
+
+ openssl pkey -in key.pem -pubout -out pubkey.pem
+
+=head1 SEE ALSO
+
+L<genpkey(1)|genpkey(1)>, L<rsa(1)|rsa(1)>, L<pkcs8(1)|pkcs8(1)>,
+L<dsa(1)|dsa(1)>, L<genrsa(1)|genrsa(1)>, L<gendsa(1)|gendsa(1)> 
+
+=cut
diff --git a/openssl/doc/apps/pkeyparam.pod b/openssl/doc/apps/pkeyparam.pod
new file mode 100644
index 0000000..154f672
--- /dev/null
+++ b/openssl/doc/apps/pkeyparam.pod
@@ -0,0 +1,69 @@
+
+=pod
+
+=head1 NAME
+
+pkeyparam - public key algorithm parameter processing tool
+
+=head1 SYNOPSIS
+
+B<openssl> B<pkeyparam>
+[B<-in filename>]
+[B<-out filename>]
+[B<-text>]
+[B<-noout>]
+[B<-engine id>]
+
+=head1 DESCRIPTION
+
+The B<pkey> command processes public or private keys. They can be converted
+between various forms and their components printed out.
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<-in filename>
+
+This specifies the input filename to read parameters from or standard input if
+this option is not specified.
+
+=item B<-out filename>
+
+This specifies the output filename to write parameters to or standard output if
+this option is not specified.
+
+=item B<-text>
+
+prints out the parameters in plain text in addition to the encoded version. 
+
+=item B<-noout>
+
+do not output the encoded version of the parameters.
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<pkeyparam>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=back
+
+=head1 EXAMPLE
+
+Print out text version of parameters:
+
+ openssl pkeyparam -in param.pem -text
+
+=head1 NOTES
+
+There are no B<-inform> or B<-outform> options for this command because only
+PEM format is supported because the key type is determined by the PEM headers.
+
+=head1 SEE ALSO
+
+L<genpkey(1)|genpkey(1)>, L<rsa(1)|rsa(1)>, L<pkcs8(1)|pkcs8(1)>,
+L<dsa(1)|dsa(1)>, L<genrsa(1)|genrsa(1)>, L<gendsa(1)|gendsa(1)> 
+
+=cut
diff --git a/openssl/doc/apps/pkeyutl.pod b/openssl/doc/apps/pkeyutl.pod
new file mode 100644
index 0000000..27be9a9
--- /dev/null
+++ b/openssl/doc/apps/pkeyutl.pod
@@ -0,0 +1,222 @@
+=pod
+
+=head1 NAME
+
+pkeyutl - public key algorithm utility
+
+=head1 SYNOPSIS
+
+B<openssl> B<pkeyutl>
+[B<-in file>]
+[B<-out file>]
+[B<-sigfile file>]
+[B<-inkey file>]
+[B<-keyform PEM|DER>]
+[B<-passin arg>]
+[B<-peerkey file>]
+[B<-peerform PEM|DER>]
+[B<-pubin>]
+[B<-certin>]
+[B<-rev>]
+[B<-sign>]
+[B<-verify>]
+[B<-verifyrecover>]
+[B<-encrypt>]
+[B<-decrypt>]
+[B<-derive>]
+[B<-pkeyopt opt:value>]
+[B<-hexdump>]
+[B<-asn1parse>]
+[B<-engine id>]
+
+=head1 DESCRIPTION
+
+The B<pkeyutl> command can be used to perform public key operations using
+any supported algorithm.
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<-in filename>
+
+This specifies the input filename to read data from or standard input
+if this option is not specified.
+
+=item B<-out filename>
+
+specifies the output filename to write to or standard output by
+default.
+
+=item B<-inkey file>
+
+the input key file, by default it should be a private key.
+
+=item B<-keyform PEM|DER>
+
+the key format PEM, DER or ENGINE.
+
+=item B<-passin arg>
+
+the input key password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+
+=item B<-peerkey file>
+
+the peer key file, used by key derivation (agreement) operations.
+
+=item B<-peerform PEM|DER>
+
+the peer key format PEM, DER or ENGINE.
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<pkeyutl>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+
+=item B<-pubin>
+
+the input file is a public key. 
+
+=item B<-certin>
+
+the input is a certificate containing a public key. 
+
+=item B<-rev>
+
+reverse the order of the input buffer. This is useful for some libraries
+(such as CryptoAPI) which represent the buffer in little endian format.
+
+=item B<-sign>
+
+sign the input data and output the signed result. This requires
+a private key.
+
+=item B<-verify>
+
+verify the input data against the signature file and indicate if the
+verification succeeded or failed.
+
+=item B<-verifyrecover>
+
+verify the input data and output the recovered data.
+
+=item B<-encrypt>
+
+encrypt the input data using a public key.
+
+=item B<-decrypt>
+
+decrypt the input data using a private key.
+
+=item B<-derive>
+
+derive a shared secret using the peer key.
+
+=item B<-hexdump>
+
+hex dump the output data.
+
+=item B<-asn1parse>
+
+asn1parse the output data, this is useful when combined with the
+B<-verifyrecover> option when an ASN1 structure is signed.
+
+=back
+
+=head1 NOTES
+
+The operations and options supported vary according to the key algorithm
+and its implementation. The OpenSSL operations and options are indicated below.
+
+Unless otherwise mentioned all algorithms support the B<digest:alg> option
+which specifies the digest in use for sign, verify and verifyrecover operations.
+The value B<alg> should represent a digest name as used in the
+EVP_get_digestbyname() function for example B<sha1>.
+
+=head1 RSA ALGORITHM
+
+The RSA algorithm supports encrypt, decrypt, sign, verify and verifyrecover
+operations in general. Some padding modes only support some of these 
+operations however.
+
+=over 4
+
+=item -B<rsa_padding_mode:mode>
+
+This sets the RSA padding mode. Acceptable values for B<mode> are B<pkcs1> for
+PKCS#1 padding, B<sslv23> for SSLv23 padding, B<none> for no padding, B<oaep>
+for B<OAEP> mode, B<x931> for X9.31 mode and B<pss> for PSS.
+
+In PKCS#1 padding if the message digest is not set then the supplied data is 
+signed or verified directly instead of using a B<DigestInfo> structure. If a
+digest is set then the a B<DigestInfo> structure is used and its the length
+must correspond to the digest type.
+
+For B<oeap> mode only encryption and decryption is supported.
+
+For B<x931> if the digest type is set it is used to format the block data
+otherwise the first byte is used to specify the X9.31 digest ID. Sign,
+verify and verifyrecover are can be performed in this mode.
+
+For B<pss> mode only sign and verify are supported and the digest type must be
+specified.
+
+=item B<rsa_pss_saltlen:len>
+
+For B<pss> mode only this option specifies the salt length. Two special values
+are supported: -1 sets the salt length to the digest length. When signing -2
+sets the salt length to the maximum permissible value. When verifying -2 causes
+the salt length to be automatically determined based on the B<PSS> block
+structure.
+
+=back
+
+=head1 DSA ALGORITHM
+
+The DSA algorithm supports signing and verification operations only. Currently
+there are no additional options other than B<digest>. Only the SHA1
+digest can be used and this digest is assumed by default.
+
+=head1 DH ALGORITHM
+
+The DH algorithm only supports the derivation operation and no additional
+options.
+
+=head1 EC ALGORITHM
+
+The EC algorithm supports sign, verify and derive operations. The sign and
+verify operations use ECDSA and derive uses ECDH. Currently there are no
+additional options other than B<digest>. Only the SHA1 digest can be used and
+this digest is assumed by default.
+
+=head1 EXAMPLES
+
+Sign some data using a private key:
+
+ openssl pkeyutl -sign -in file -inkey key.pem -out sig
+
+Recover the signed data (e.g. if an RSA key is used):
+
+ openssl pkeyutl -verifyrecover -in sig -inkey key.pem
+
+Verify the signature (e.g. a DSA key):
+
+ openssl pkeyutl -verify -in file -sigfile sig -inkey key.pem
+
+Sign data using a message digest value (this is currently only valid for RSA):
+
+ openssl pkeyutl -sign -in file -inkey key.pem -out sig -pkeyopt digest:sha256
+
+Derive a shared secret value:
+
+ openssl pkeyutl -derive -inkey key.pem -peerkey pubkey.pem -out secret
+
+=head1 SEE ALSO
+
+L<genpkey(1)|genpkey(1)>, L<pkey(1)|pkey(1)>, L<rsautl(1)|rsautl(1)>
+L<dgst(1)|dgst(1)>, L<rsa(1)|rsa(1)>, L<genrsa(1)|genrsa(1)>
diff --git a/openssl/doc/apps/rand.pod b/openssl/doc/apps/rand.pod
new file mode 100644
index 0000000..d1d213e
--- /dev/null
+++ b/openssl/doc/apps/rand.pod
@@ -0,0 +1,55 @@
+=pod
+
+=head1 NAME
+
+rand - generate pseudo-random bytes
+
+=head1 SYNOPSIS
+
+B<openssl rand>
+[B<-out> I<file>]
+[B<-rand> I<file(s)>]
+[B<-base64>]
+[B<-hex>]
+I<num>
+
+=head1 DESCRIPTION
+
+The B<rand> command outputs I<num> pseudo-random bytes after seeding
+the random number generator once.  As in other B<openssl> command
+line tools, PRNG seeding uses the file I<$HOME/>B<.rnd> or B<.rnd>
+in addition to the files given in the B<-rand> option.  A new
+I<$HOME>/B<.rnd> or B<.rnd> file will be written back if enough
+seeding was obtained from these sources.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-out> I<file>
+
+Write to I<file> instead of standard output.
+
+=item B<-rand> I<file(s)>
+
+Use specified file or files or EGD socket (see L<RAND_egd(3)|RAND_egd(3)>)
+for seeding the random number generator.
+Multiple files can be specified separated by a OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item B<-base64>
+
+Perform base64 encoding on the output.
+
+=item B<-hex>
+
+Show the output as a hex string.
+
+=back
+
+=head1 SEE ALSO
+
+L<RAND_bytes(3)|RAND_bytes(3)>
+
+=cut
diff --git a/openssl/doc/apps/req.pod b/openssl/doc/apps/req.pod
new file mode 100644
index 0000000..ff48bbd
--- /dev/null
+++ b/openssl/doc/apps/req.pod
@@ -0,0 +1,678 @@
+
+=pod
+
+=head1 NAME
+
+req - PKCS#10 certificate request and certificate generating utility.
+
+=head1 SYNOPSIS
+
+B<openssl> B<req>
+[B<-inform PEM|DER>]
+[B<-outform PEM|DER>]
+[B<-in filename>]
+[B<-passin arg>]
+[B<-out filename>]
+[B<-passout arg>]
+[B<-text>]
+[B<-pubkey>]
+[B<-noout>]
+[B<-verify>]
+[B<-modulus>]
+[B<-new>]
+[B<-rand file(s)>]
+[B<-newkey rsa:bits>]
+[B<-newkey alg:file>]
+[B<-nodes>]
+[B<-key filename>]
+[B<-keyform PEM|DER>]
+[B<-keyout filename>]
+[B<-keygen_engine id>]
+[B<-[digest]>]
+[B<-config filename>]
+[B<-subj arg>]
+[B<-multivalue-rdn>]
+[B<-x509>]
+[B<-days n>]
+[B<-set_serial n>]
+[B<-asn1-kludge>]
+[B<-no-asn1-kludge>]
+[B<-newhdr>]
+[B<-extensions section>]
+[B<-reqexts section>]
+[B<-utf8>]
+[B<-nameopt>]
+[B<-reqopt>]
+[B<-subject>]
+[B<-subj arg>]
+[B<-batch>]
+[B<-verbose>]
+[B<-engine id>]
+
+=head1 DESCRIPTION
+
+The B<req> command primarily creates and processes certificate requests
+in PKCS#10 format. It can additionally create self signed certificates
+for use as root CAs for example.
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<-inform DER|PEM>
+
+This specifies the input format. The B<DER> option uses an ASN1 DER encoded
+form compatible with the PKCS#10. The B<PEM> form is the default format: it
+consists of the B<DER> format base64 encoded with additional header and
+footer lines.
+
+=item B<-outform DER|PEM>
+
+This specifies the output format, the options have the same meaning as the 
+B<-inform> option.
+
+=item B<-in filename>
+
+This specifies the input filename to read a request from or standard input
+if this option is not specified. A request is only read if the creation
+options (B<-new> and B<-newkey>) are not specified.
+
+=item B<-passin arg>
+
+the input file password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-out filename>
+
+This specifies the output filename to write to or standard output by
+default.
+
+=item B<-passout arg>
+
+the output file password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-text>
+
+prints out the certificate request in text form.
+
+=item B<-subject>
+
+prints out the request subject (or certificate subject if B<-x509> is
+specified)
+
+=item B<-pubkey>
+
+outputs the public key.
+
+=item B<-noout>
+
+this option prevents output of the encoded version of the request.
+
+=item B<-modulus>
+
+this option prints out the value of the modulus of the public key
+contained in the request.
+
+=item B<-verify>
+
+verifies the signature on the request.
+
+=item B<-new>
+
+this option generates a new certificate request. It will prompt
+the user for the relevant field values. The actual fields
+prompted for and their maximum and minimum sizes are specified
+in the configuration file and any requested extensions.
+
+If the B<-key> option is not used it will generate a new RSA private
+key using information specified in the configuration file.
+
+=item B<-subj arg>
+
+Replaces subject field of input request with specified data and outputs
+modified request. The arg must be formatted as
+I</type0=value0/type1=value1/type2=...>,
+characters may be escaped by \ (backslash), no spaces are skipped.
+
+=item B<-rand file(s)>
+
+a file or files containing random data used to seed the random number
+generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
+Multiple files can be specified separated by a OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item B<-newkey arg>
+
+this option creates a new certificate request and a new private
+key. The argument takes one of several forms. B<rsa:nbits>, where
+B<nbits> is the number of bits, generates an RSA key B<nbits>
+in size. If B<nbits> is omitted, i.e. B<-newkey rsa> specified,
+the default key size, specified in the configuration file is used.
+
+All other algorithms support the B<-newkey alg:file> form, where file may be
+an algorithm parameter file, created by the B<genpkey -genparam> command
+or and X.509 certificate for a key with approriate algorithm.
+
+B<param:file> generates a key using the parameter file or certificate B<file>,
+the algorithm is determined by the parameters. B<algname:file> use algorithm
+B<algname> and parameter file B<file>: the two algorithms must match or an
+error occurs. B<algname> just uses algorithm B<algname>, and parameters,
+if neccessary should be specified via B<-pkeyopt> parameter.
+
+B<dsa:filename> generates a DSA key using the parameters
+in the file B<filename>. B<ec:filename> generates EC key (usable both with
+ECDSA or ECDH algorithms), B<gost2001:filename> generates GOST R
+34.10-2001 key (requires B<ccgost> engine configured in the configuration
+file). If just B<gost2001> is specified a parameter set should be
+specified by B<-pkeyopt paramset:X>
+
+
+=item B<-pkeyopt opt:value>
+
+set the public key algorithm option B<opt> to B<value>. The precise set of
+options supported depends on the public key algorithm used and its
+implementation. See B<KEY GENERATION OPTIONS> in the B<genpkey> manual page
+for more details.
+
+=item B<-key filename>
+
+This specifies the file to read the private key from. It also
+accepts PKCS#8 format private keys for PEM format files.
+
+=item B<-keyform PEM|DER>
+
+the format of the private key file specified in the B<-key>
+argument. PEM is the default.
+
+=item B<-keyout filename>
+
+this gives the filename to write the newly created private key to.
+If this option is not specified then the filename present in the
+configuration file is used.
+
+=item B<-nodes>
+
+if this option is specified then if a private key is created it
+will not be encrypted.
+
+=item B<-[digest]>
+
+this specifies the message digest to sign the request with (such as
+B<-md5>, B<-sha1>). This overrides the digest algorithm specified in
+the configuration file.
+
+Some public key algorithms may override this choice. For instance, DSA
+signatures always use SHA1, GOST R 34.10 signatures always use
+GOST R 34.11-94 (B<-md_gost94>).
+
+=item B<-config filename>
+
+this allows an alternative configuration file to be specified,
+this overrides the compile time filename or any specified in
+the B<OPENSSL_CONF> environment variable.
+
+=item B<-subj arg>
+
+sets subject name for new request or supersedes the subject name
+when processing a request.
+The arg must be formatted as I</type0=value0/type1=value1/type2=...>,
+characters may be escaped by \ (backslash), no spaces are skipped.
+
+=item B<-multivalue-rdn>
+
+this option causes the -subj argument to be interpreted with full
+support for multivalued RDNs. Example:
+
+I</DC=org/DC=OpenSSL/DC=users/UID=123456+CN=John Doe>
+
+If -multi-rdn is not used then the UID value is I<123456+CN=John Doe>.
+
+=item B<-x509>
+
+this option outputs a self signed certificate instead of a certificate
+request. This is typically used to generate a test certificate or
+a self signed root CA. The extensions added to the certificate
+(if any) are specified in the configuration file. Unless specified
+using the B<set_serial> option B<0> will be used for the serial
+number.
+
+=item B<-days n>
+
+when the B<-x509> option is being used this specifies the number of
+days to certify the certificate for. The default is 30 days.
+
+=item B<-set_serial n>
+
+serial number to use when outputting a self signed certificate. This
+may be specified as a decimal value or a hex value if preceded by B<0x>.
+It is possible to use negative serial numbers but this is not recommended.
+
+=item B<-extensions section>
+
+=item B<-reqexts section>
+
+these options specify alternative sections to include certificate
+extensions (if the B<-x509> option is present) or certificate
+request extensions. This allows several different sections to
+be used in the same configuration file to specify requests for
+a variety of purposes.
+
+=item B<-utf8>
+
+this option causes field values to be interpreted as UTF8 strings, by 
+default they are interpreted as ASCII. This means that the field
+values, whether prompted from a terminal or obtained from a
+configuration file, must be valid UTF8 strings.
+
+=item B<-nameopt option>
+
+option which determines how the subject or issuer names are displayed. The
+B<option> argument can be a single option or multiple options separated by
+commas.  Alternatively the B<-nameopt> switch may be used more than once to
+set multiple options. See the L<x509(1)|x509(1)> manual page for details.
+
+=item B<-reqopt>
+
+customise the output format used with B<-text>. The B<option> argument can be
+a single option or multiple options separated by commas. 
+
+See discission of the  B<-certopt> parameter in the L<B<x509>|x509(1)>
+command.
+
+
+=item B<-asn1-kludge>
+
+by default the B<req> command outputs certificate requests containing
+no attributes in the correct PKCS#10 format. However certain CAs will only
+accept requests containing no attributes in an invalid form: this
+option produces this invalid format.
+
+More precisely the B<Attributes> in a PKCS#10 certificate request
+are defined as a B<SET OF Attribute>. They are B<not OPTIONAL> so
+if no attributes are present then they should be encoded as an
+empty B<SET OF>. The invalid form does not include the empty
+B<SET OF> whereas the correct form does.
+
+It should be noted that very few CAs still require the use of this option.
+
+=item B<-no-asn1-kludge>
+
+Reverses effect of B<-asn1-kludge>
+
+=item B<-newhdr>
+
+Adds the word B<NEW> to the PEM file header and footer lines on the outputed
+request. Some software (Netscape certificate server) and some CAs need this.
+
+=item B<-batch>
+
+non-interactive mode.
+
+=item B<-verbose>
+
+print extra details about the operations being performed.
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<req>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=item B<-keygen_engine id>
+
+specifies an engine (by its unique B<id> string) which would be used
+for key generation operations.
+
+=back
+
+=head1 CONFIGURATION FILE FORMAT
+
+The configuration options are specified in the B<req> section of
+the configuration file. As with all configuration files if no
+value is specified in the specific section (i.e. B<req>) then
+the initial unnamed or B<default> section is searched too.
+
+The options available are described in detail below.
+
+=over 4
+
+=item B<input_password output_password>
+
+The passwords for the input private key file (if present) and
+the output private key file (if one will be created). The
+command line options B<passin> and B<passout> override the
+configuration file values.
+
+=item B<default_bits>
+
+This specifies the default key size in bits. If not specified then
+512 is used. It is used if the B<-new> option is used. It can be
+overridden by using the B<-newkey> option.
+
+=item B<default_keyfile>
+
+This is the default filename to write a private key to. If not
+specified the key is written to standard output. This can be
+overridden by the B<-keyout> option.
+
+=item B<oid_file>
+
+This specifies a file containing additional B<OBJECT IDENTIFIERS>.
+Each line of the file should consist of the numerical form of the
+object identifier followed by white space then the short name followed
+by white space and finally the long name. 
+
+=item B<oid_section>
+
+This specifies a section in the configuration file containing extra
+object identifiers. Each line should consist of the short name of the
+object identifier followed by B<=> and the numerical form. The short
+and long names are the same when this option is used.
+
+=item B<RANDFILE>
+
+This specifies a filename in which random number seed information is
+placed and read from, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
+It is used for private key generation.
+
+=item B<encrypt_key>
+
+If this is set to B<no> then if a private key is generated it is
+B<not> encrypted. This is equivalent to the B<-nodes> command line
+option. For compatibility B<encrypt_rsa_key> is an equivalent option.
+
+=item B<default_md>
+
+This option specifies the digest algorithm to use. Possible values
+include B<md5 sha1 mdc2>. If not present then MD5 is used. This
+option can be overridden on the command line.
+
+=item B<string_mask>
+
+This option masks out the use of certain string types in certain
+fields. Most users will not need to change this option.
+
+It can be set to several values B<default> which is also the default
+option uses PrintableStrings, T61Strings and BMPStrings if the 
+B<pkix> value is used then only PrintableStrings and BMPStrings will
+be used. This follows the PKIX recommendation in RFC2459. If the
+B<utf8only> option is used then only UTF8Strings will be used: this
+is the PKIX recommendation in RFC2459 after 2003. Finally the B<nombstr>
+option just uses PrintableStrings and T61Strings: certain software has
+problems with BMPStrings and UTF8Strings: in particular Netscape.
+
+=item B<req_extensions>
+
+this specifies the configuration file section containing a list of
+extensions to add to the certificate request. It can be overridden
+by the B<-reqexts> command line switch. See the 
+L<x509v3_config(5)|x509v3_config(5)> manual page for details of the
+extension section format.
+
+=item B<x509_extensions>
+
+this specifies the configuration file section containing a list of
+extensions to add to certificate generated when the B<-x509> switch
+is used. It can be overridden by the B<-extensions> command line switch.
+
+=item B<prompt>
+
+if set to the value B<no> this disables prompting of certificate fields
+and just takes values from the config file directly. It also changes the
+expected format of the B<distinguished_name> and B<attributes> sections.
+
+=item B<utf8>
+
+if set to the value B<yes> then field values to be interpreted as UTF8
+strings, by default they are interpreted as ASCII. This means that
+the field values, whether prompted from a terminal or obtained from a
+configuration file, must be valid UTF8 strings.
+
+=item B<attributes>
+
+this specifies the section containing any request attributes: its format
+is the same as B<distinguished_name>. Typically these may contain the
+challengePassword or unstructuredName types. They are currently ignored
+by OpenSSL's request signing utilities but some CAs might want them.
+
+=item B<distinguished_name>
+
+This specifies the section containing the distinguished name fields to
+prompt for when generating a certificate or certificate request. The format
+is described in the next section.
+
+=back
+
+=head1 DISTINGUISHED NAME AND ATTRIBUTE SECTION FORMAT
+
+There are two separate formats for the distinguished name and attribute
+sections. If the B<prompt> option is set to B<no> then these sections
+just consist of field names and values: for example,
+
+ CN=My Name
+ OU=My Organization
+ emailAddress=someone@somewhere.org
+
+This allows external programs (e.g. GUI based) to generate a template file
+with all the field names and values and just pass it to B<req>. An example
+of this kind of configuration file is contained in the B<EXAMPLES> section.
+
+Alternatively if the B<prompt> option is absent or not set to B<no> then the
+file contains field prompting information. It consists of lines of the form:
+
+ fieldName="prompt"
+ fieldName_default="default field value"
+ fieldName_min= 2
+ fieldName_max= 4
+
+"fieldName" is the field name being used, for example commonName (or CN).
+The "prompt" string is used to ask the user to enter the relevant
+details. If the user enters nothing then the default value is used if no
+default value is present then the field is omitted. A field can
+still be omitted if a default value is present if the user just
+enters the '.' character.
+
+The number of characters entered must be between the fieldName_min and
+fieldName_max limits: there may be additional restrictions based
+on the field being used (for example countryName can only ever be
+two characters long and must fit in a PrintableString).
+
+Some fields (such as organizationName) can be used more than once
+in a DN. This presents a problem because configuration files will
+not recognize the same name occurring twice. To avoid this problem
+if the fieldName contains some characters followed by a full stop
+they will be ignored. So for example a second organizationName can
+be input by calling it "1.organizationName".
+
+The actual permitted field names are any object identifier short or
+long names. These are compiled into OpenSSL and include the usual
+values such as commonName, countryName, localityName, organizationName,
+organizationUnitName, stateOrProvinceName. Additionally emailAddress
+is include as well as name, surname, givenName initials and dnQualifier.
+
+Additional object identifiers can be defined with the B<oid_file> or
+B<oid_section> options in the configuration file. Any additional fields
+will be treated as though they were a DirectoryString.
+
+
+=head1 EXAMPLES
+
+Examine and verify certificate request:
+
+ openssl req -in req.pem -text -verify -noout
+
+Create a private key and then generate a certificate request from it:
+
+ openssl genrsa -out key.pem 1024
+ openssl req -new -key key.pem -out req.pem
+
+The same but just using req:
+
+ openssl req -newkey rsa:1024 -keyout key.pem -out req.pem
+
+Generate a self signed root certificate:
+
+ openssl req -x509 -newkey rsa:1024 -keyout key.pem -out req.pem
+
+Example of a file pointed to by the B<oid_file> option:
+
+ 1.2.3.4	shortName	A longer Name
+ 1.2.3.6	otherName	Other longer Name
+
+Example of a section pointed to by B<oid_section> making use of variable
+expansion:
+
+ testoid1=1.2.3.5
+ testoid2=${testoid1}.6
+
+Sample configuration file prompting for field values:
+
+ [ req ]
+ default_bits		= 1024
+ default_keyfile 	= privkey.pem
+ distinguished_name	= req_distinguished_name
+ attributes		= req_attributes
+ x509_extensions	= v3_ca
+
+ dirstring_type = nobmp
+
+ [ req_distinguished_name ]
+ countryName			= Country Name (2 letter code)
+ countryName_default		= AU
+ countryName_min		= 2
+ countryName_max		= 2
+
+ localityName			= Locality Name (eg, city)
+
+ organizationalUnitName		= Organizational Unit Name (eg, section)
+
+ commonName			= Common Name (eg, YOUR name)
+ commonName_max			= 64
+
+ emailAddress			= Email Address
+ emailAddress_max		= 40
+
+ [ req_attributes ]
+ challengePassword		= A challenge password
+ challengePassword_min		= 4
+ challengePassword_max		= 20
+
+ [ v3_ca ]
+
+ subjectKeyIdentifier=hash
+ authorityKeyIdentifier=keyid:always,issuer:always
+ basicConstraints = CA:true
+
+Sample configuration containing all field values:
+
+
+ RANDFILE		= $ENV::HOME/.rnd
+
+ [ req ]
+ default_bits		= 1024
+ default_keyfile 	= keyfile.pem
+ distinguished_name	= req_distinguished_name
+ attributes		= req_attributes
+ prompt			= no
+ output_password	= mypass
+
+ [ req_distinguished_name ]
+ C			= GB
+ ST			= Test State or Province
+ L			= Test Locality
+ O			= Organization Name
+ OU			= Organizational Unit Name
+ CN			= Common Name
+ emailAddress		= test@email.address
+
+ [ req_attributes ]
+ challengePassword		= A challenge password
+
+
+=head1 NOTES
+
+The header and footer lines in the B<PEM> format are normally:
+
+ -----BEGIN CERTIFICATE REQUEST-----
+ -----END CERTIFICATE REQUEST-----
+
+some software (some versions of Netscape certificate server) instead needs:
+
+ -----BEGIN NEW CERTIFICATE REQUEST-----
+ -----END NEW CERTIFICATE REQUEST-----
+
+which is produced with the B<-newhdr> option but is otherwise compatible.
+Either form is accepted transparently on input.
+
+The certificate requests generated by B<Xenroll> with MSIE have extensions
+added. It includes the B<keyUsage> extension which determines the type of
+key (signature only or general purpose) and any additional OIDs entered
+by the script in an extendedKeyUsage extension.
+
+=head1 DIAGNOSTICS
+
+The following messages are frequently asked about:
+
+	Using configuration from /some/path/openssl.cnf
+	Unable to load config info
+
+This is followed some time later by...
+
+	unable to find 'distinguished_name' in config
+	problems making Certificate Request
+
+The first error message is the clue: it can't find the configuration
+file! Certain operations (like examining a certificate request) don't
+need a configuration file so its use isn't enforced. Generation of
+certificates or requests however does need a configuration file. This
+could be regarded as a bug.
+
+Another puzzling message is this:
+
+        Attributes:
+            a0:00
+
+this is displayed when no attributes are present and the request includes
+the correct empty B<SET OF> structure (the DER encoding of which is 0xa0
+0x00). If you just see:
+
+        Attributes:
+
+then the B<SET OF> is missing and the encoding is technically invalid (but
+it is tolerated). See the description of the command line option B<-asn1-kludge>
+for more information.
+
+=head1 ENVIRONMENT VARIABLES
+
+The variable B<OPENSSL_CONF> if defined allows an alternative configuration
+file location to be specified, it will be overridden by the B<-config> command
+line switch if it is present. For compatibility reasons the B<SSLEAY_CONF>
+environment variable serves the same purpose but its use is discouraged.
+
+=head1 BUGS
+
+OpenSSL's handling of T61Strings (aka TeletexStrings) is broken: it effectively
+treats them as ISO-8859-1 (Latin 1), Netscape and MSIE have similar behaviour.
+This can cause problems if you need characters that aren't available in
+PrintableStrings and you don't want to or can't use BMPStrings.
+
+As a consequence of the T61String handling the only correct way to represent
+accented characters in OpenSSL is to use a BMPString: unfortunately Netscape
+currently chokes on these. If you have to use accented characters with Netscape
+and MSIE then you currently need to use the invalid T61String form.
+
+The current prompting is not very friendly. It doesn't allow you to confirm what
+you've just entered. Other things like extensions in certificate requests are
+statically defined in the configuration file. Some of these: like an email
+address in subjectAltName should be input by the user.
+
+=head1 SEE ALSO
+
+L<x509(1)|x509(1)>, L<ca(1)|ca(1)>, L<genrsa(1)|genrsa(1)>,
+L<gendsa(1)|gendsa(1)>, L<config(5)|config(5)>,
+L<x509v3_config(5)|x509v3_config(5)> 
+
+=cut
diff --git a/openssl/doc/apps/rsa.pod b/openssl/doc/apps/rsa.pod
new file mode 100644
index 0000000..69b2bef
--- /dev/null
+++ b/openssl/doc/apps/rsa.pod
@@ -0,0 +1,189 @@
+
+=pod
+
+=head1 NAME
+
+rsa - RSA key processing tool
+
+=head1 SYNOPSIS
+
+B<openssl> B<rsa>
+[B<-inform PEM|NET|DER>]
+[B<-outform PEM|NET|DER>]
+[B<-in filename>]
+[B<-passin arg>]
+[B<-out filename>]
+[B<-passout arg>]
+[B<-sgckey>]
+[B<-des>]
+[B<-des3>]
+[B<-idea>]
+[B<-text>]
+[B<-noout>]
+[B<-modulus>]
+[B<-check>]
+[B<-pubin>]
+[B<-pubout>]
+[B<-engine id>]
+
+=head1 DESCRIPTION
+
+The B<rsa> command processes RSA keys. They can be converted between various
+forms and their components printed out. B<Note> this command uses the
+traditional SSLeay compatible format for private key encryption: newer
+applications should use the more secure PKCS#8 format using the B<pkcs8>
+utility.
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<-inform DER|NET|PEM>
+
+This specifies the input format. The B<DER> option uses an ASN1 DER encoded
+form compatible with the PKCS#1 RSAPrivateKey or SubjectPublicKeyInfo format.
+The B<PEM> form is the default format: it consists of the B<DER> format base64
+encoded with additional header and footer lines. On input PKCS#8 format private
+keys are also accepted. The B<NET> form is a format is described in the B<NOTES>
+section.
+
+=item B<-outform DER|NET|PEM>
+
+This specifies the output format, the options have the same meaning as the 
+B<-inform> option.
+
+=item B<-in filename>
+
+This specifies the input filename to read a key from or standard input if this
+option is not specified. If the key is encrypted a pass phrase will be
+prompted for.
+
+=item B<-passin arg>
+
+the input file password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-out filename>
+
+This specifies the output filename to write a key to or standard output if this
+option is not specified. If any encryption options are set then a pass phrase
+will be prompted for. The output filename should B<not> be the same as the input
+filename.
+
+=item B<-passout password>
+
+the output file password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-sgckey>
+
+use the modified NET algorithm used with some versions of Microsoft IIS and SGC
+keys.
+
+=item B<-des|-des3|-idea>
+
+These options encrypt the private key with the DES, triple DES, or the 
+IDEA ciphers respectively before outputting it. A pass phrase is prompted for.
+If none of these options is specified the key is written in plain text. This
+means that using the B<rsa> utility to read in an encrypted key with no
+encryption option can be used to remove the pass phrase from a key, or by
+setting the encryption options it can be use to add or change the pass phrase.
+These options can only be used with PEM format output files.
+
+=item B<-text>
+
+prints out the various public or private key components in
+plain text in addition to the encoded version. 
+
+=item B<-noout>
+
+this option prevents output of the encoded version of the key.
+
+=item B<-modulus>
+
+this option prints out the value of the modulus of the key.
+
+=item B<-check>
+
+this option checks the consistency of an RSA private key.
+
+=item B<-pubin>
+
+by default a private key is read from the input file: with this
+option a public key is read instead.
+
+=item B<-pubout>
+
+by default a private key is output: with this option a public
+key will be output instead. This option is automatically set if
+the input is a public key.
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<rsa>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=back
+
+=head1 NOTES
+
+The PEM private key format uses the header and footer lines:
+
+ -----BEGIN RSA PRIVATE KEY-----
+ -----END RSA PRIVATE KEY-----
+
+The PEM public key format uses the header and footer lines:
+
+ -----BEGIN PUBLIC KEY-----
+ -----END PUBLIC KEY-----
+
+The B<NET> form is a format compatible with older Netscape servers
+and Microsoft IIS .key files, this uses unsalted RC4 for its encryption.
+It is not very secure and so should only be used when necessary.
+
+Some newer version of IIS have additional data in the exported .key
+files. To use these with the utility, view the file with a binary editor
+and look for the string "private-key", then trace back to the byte
+sequence 0x30, 0x82 (this is an ASN1 SEQUENCE). Copy all the data
+from this point onwards to another file and use that as the input
+to the B<rsa> utility with the B<-inform NET> option. If you get
+an error after entering the password try the B<-sgckey> option.
+
+=head1 EXAMPLES
+
+To remove the pass phrase on an RSA private key:
+
+ openssl rsa -in key.pem -out keyout.pem
+
+To encrypt a private key using triple DES:
+
+ openssl rsa -in key.pem -des3 -out keyout.pem
+
+To convert a private key from PEM to DER format: 
+
+ openssl rsa -in key.pem -outform DER -out keyout.der
+
+To print out the components of a private key to standard output:
+
+ openssl rsa -in key.pem -text -noout
+
+To just output the public part of a private key:
+
+ openssl rsa -in key.pem -pubout -out pubkey.pem
+
+=head1 BUGS
+
+The command line password arguments don't currently work with
+B<NET> format.
+
+There should be an option that automatically handles .key files,
+without having to manually edit them.
+
+=head1 SEE ALSO
+
+L<pkcs8(1)|pkcs8(1)>, L<dsa(1)|dsa(1)>, L<genrsa(1)|genrsa(1)>,
+L<gendsa(1)|gendsa(1)> 
+
+=cut
diff --git a/openssl/doc/apps/rsautl.pod b/openssl/doc/apps/rsautl.pod
new file mode 100644
index 0000000..1a498c2
--- /dev/null
+++ b/openssl/doc/apps/rsautl.pod
@@ -0,0 +1,183 @@
+=pod
+
+=head1 NAME
+
+rsautl - RSA utility
+
+=head1 SYNOPSIS
+
+B<openssl> B<rsautl>
+[B<-in file>]
+[B<-out file>]
+[B<-inkey file>]
+[B<-pubin>]
+[B<-certin>]
+[B<-sign>]
+[B<-verify>]
+[B<-encrypt>]
+[B<-decrypt>]
+[B<-pkcs>]
+[B<-ssl>]
+[B<-raw>]
+[B<-hexdump>]
+[B<-asn1parse>]
+
+=head1 DESCRIPTION
+
+The B<rsautl> command can be used to sign, verify, encrypt and decrypt
+data using the RSA algorithm.
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<-in filename>
+
+This specifies the input filename to read data from or standard input
+if this option is not specified.
+
+=item B<-out filename>
+
+specifies the output filename to write to or standard output by
+default.
+
+=item B<-inkey file>
+
+the input key file, by default it should be an RSA private key.
+
+=item B<-pubin>
+
+the input file is an RSA public key. 
+
+=item B<-certin>
+
+the input is a certificate containing an RSA public key. 
+
+=item B<-sign>
+
+sign the input data and output the signed result. This requires
+and RSA private key.
+
+=item B<-verify>
+
+verify the input data and output the recovered data.
+
+=item B<-encrypt>
+
+encrypt the input data using an RSA public key.
+
+=item B<-decrypt>
+
+decrypt the input data using an RSA private key.
+
+=item B<-pkcs, -oaep, -ssl, -raw>
+
+the padding to use: PKCS#1 v1.5 (the default), PKCS#1 OAEP,
+special padding used in SSL v2 backwards compatible handshakes,
+or no padding, respectively.
+For signatures, only B<-pkcs> and B<-raw> can be used.
+
+=item B<-hexdump>
+
+hex dump the output data.
+
+=item B<-asn1parse>
+
+asn1parse the output data, this is useful when combined with the
+B<-verify> option.
+
+=back
+
+=head1 NOTES
+
+B<rsautl> because it uses the RSA algorithm directly can only be
+used to sign or verify small pieces of data.
+
+=head1 EXAMPLES
+
+Sign some data using a private key:
+
+ openssl rsautl -sign -in file -inkey key.pem -out sig
+
+Recover the signed data
+
+ openssl rsautl -verify -in sig -inkey key.pem
+
+Examine the raw signed data:
+
+ openssl rsautl -verify -in file -inkey key.pem -raw -hexdump
+
+ 0000 - 00 01 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff   ................
+ 0010 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff   ................
+ 0020 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff   ................
+ 0030 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff   ................
+ 0040 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff   ................
+ 0050 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff   ................
+ 0060 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff   ................
+ 0070 - ff ff ff ff 00 68 65 6c-6c 6f 20 77 6f 72 6c 64   .....hello world
+
+The PKCS#1 block formatting is evident from this. If this was done using
+encrypt and decrypt the block would have been of type 2 (the second byte)
+and random padding data visible instead of the 0xff bytes.
+
+It is possible to analyse the signature of certificates using this
+utility in conjunction with B<asn1parse>. Consider the self signed
+example in certs/pca-cert.pem . Running B<asn1parse> as follows yields:
+
+ openssl asn1parse -in pca-cert.pem
+
+    0:d=0  hl=4 l= 742 cons: SEQUENCE          
+    4:d=1  hl=4 l= 591 cons:  SEQUENCE          
+    8:d=2  hl=2 l=   3 cons:   cont [ 0 ]        
+   10:d=3  hl=2 l=   1 prim:    INTEGER           :02
+   13:d=2  hl=2 l=   1 prim:   INTEGER           :00
+   16:d=2  hl=2 l=  13 cons:   SEQUENCE          
+   18:d=3  hl=2 l=   9 prim:    OBJECT            :md5WithRSAEncryption
+   29:d=3  hl=2 l=   0 prim:    NULL              
+   31:d=2  hl=2 l=  92 cons:   SEQUENCE          
+   33:d=3  hl=2 l=  11 cons:    SET               
+   35:d=4  hl=2 l=   9 cons:     SEQUENCE          
+   37:d=5  hl=2 l=   3 prim:      OBJECT            :countryName
+   42:d=5  hl=2 l=   2 prim:      PRINTABLESTRING   :AU
+  ....
+  599:d=1  hl=2 l=  13 cons:  SEQUENCE          
+  601:d=2  hl=2 l=   9 prim:   OBJECT            :md5WithRSAEncryption
+  612:d=2  hl=2 l=   0 prim:   NULL              
+  614:d=1  hl=3 l= 129 prim:  BIT STRING        
+
+
+The final BIT STRING contains the actual signature. It can be extracted with:
+
+ openssl asn1parse -in pca-cert.pem -out sig -noout -strparse 614
+
+The certificate public key can be extracted with:
+ 
+ openssl x509 -in test/testx509.pem -pubkey -noout >pubkey.pem
+
+The signature can be analysed with:
+
+ openssl rsautl -in sig -verify -asn1parse -inkey pubkey.pem -pubin
+
+    0:d=0  hl=2 l=  32 cons: SEQUENCE          
+    2:d=1  hl=2 l=  12 cons:  SEQUENCE          
+    4:d=2  hl=2 l=   8 prim:   OBJECT            :md5
+   14:d=2  hl=2 l=   0 prim:   NULL              
+   16:d=1  hl=2 l=  16 prim:  OCTET STRING      
+      0000 - f3 46 9e aa 1a 4a 73 c9-37 ea 93 00 48 25 08 b5   .F...Js.7...H%..
+
+This is the parsed version of an ASN1 DigestInfo structure. It can be seen that
+the digest used was md5. The actual part of the certificate that was signed can
+be extracted with:
+
+ openssl asn1parse -in pca-cert.pem -out tbs -noout -strparse 4
+
+and its digest computed with:
+
+ openssl md5 -c tbs
+ MD5(tbs)= f3:46:9e:aa:1a:4a:73:c9:37:ea:93:00:48:25:08:b5
+
+which it can be seen agrees with the recovered value above.
+
+=head1 SEE ALSO
+
+L<dgst(1)|dgst(1)>, L<rsa(1)|rsa(1)>, L<genrsa(1)|genrsa(1)>
diff --git a/openssl/doc/apps/s_client.pod b/openssl/doc/apps/s_client.pod
new file mode 100644
index 0000000..4ebf7b5
--- /dev/null
+++ b/openssl/doc/apps/s_client.pod
@@ -0,0 +1,306 @@
+
+=pod
+
+=head1 NAME
+
+s_client - SSL/TLS client program
+
+=head1 SYNOPSIS
+
+B<openssl> B<s_client>
+[B<-connect host:port>]
+[B<-verify depth>]
+[B<-cert filename>]
+[B<-certform DER|PEM>]
+[B<-key filename>]
+[B<-keyform DER|PEM>]
+[B<-pass arg>]
+[B<-CApath directory>]
+[B<-CAfile filename>]
+[B<-reconnect>]
+[B<-pause>]
+[B<-showcerts>]
+[B<-debug>]
+[B<-msg>]
+[B<-nbio_test>]
+[B<-state>]
+[B<-nbio>]
+[B<-crlf>]
+[B<-ign_eof>]
+[B<-quiet>]
+[B<-ssl2>]
+[B<-ssl3>]
+[B<-tls1>]
+[B<-no_ssl2>]
+[B<-no_ssl3>]
+[B<-no_tls1>]
+[B<-bugs>]
+[B<-cipher cipherlist>]
+[B<-starttls protocol>]
+[B<-engine id>]
+[B<-tlsextdebug>]
+[B<-no_ticket>]
+[B<-sess_out filename>]
+[B<-sess_in filename>]
+[B<-rand file(s)>]
+
+=head1 DESCRIPTION
+
+The B<s_client> command implements a generic SSL/TLS client which connects
+to a remote host using SSL/TLS. It is a I<very> useful diagnostic tool for
+SSL servers.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-connect host:port>
+
+This specifies the host and optional port to connect to. If not specified
+then an attempt is made to connect to the local host on port 4433.
+
+=item B<-cert certname>
+
+The certificate to use, if one is requested by the server. The default is
+not to use a certificate.
+
+=item B<-certform format>
+
+The certificate format to use: DER or PEM. PEM is the default.
+
+=item B<-key keyfile>
+
+The private key to use. If not specified then the certificate file will
+be used.
+
+=item B<-keyform format>
+
+The private format to use: DER or PEM. PEM is the default.
+
+=item B<-pass arg>
+
+the private key password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-verify depth>
+
+The verify depth to use. This specifies the maximum length of the
+server certificate chain and turns on server certificate verification.
+Currently the verify operation continues after errors so all the problems
+with a certificate chain can be seen. As a side effect the connection
+will never fail due to a server certificate verify failure.
+
+=item B<-CApath directory>
+
+The directory to use for server certificate verification. This directory
+must be in "hash format", see B<verify> for more information. These are
+also used when building the client certificate chain.
+
+=item B<-CAfile file>
+
+A file containing trusted certificates to use during server authentication
+and to use when attempting to build the client certificate chain.
+
+=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig>
+
+Set various certificate chain valiadition option. See the
+L<B<verify>|verify(1)> manual page for details.
+
+=item B<-reconnect>
+
+reconnects to the same server 5 times using the same session ID, this can
+be used as a test that session caching is working.
+
+=item B<-pause>
+
+pauses 1 second between each read and write call.
+
+=item B<-showcerts>
+
+display the whole server certificate chain: normally only the server
+certificate itself is displayed.
+
+=item B<-prexit>
+
+print session information when the program exits. This will always attempt
+to print out information even if the connection fails. Normally information
+will only be printed out once if the connection succeeds. This option is useful
+because the cipher in use may be renegotiated or the connection may fail
+because a client certificate is required or is requested only after an
+attempt is made to access a certain URL. Note: the output produced by this
+option is not always accurate because a connection might never have been
+established.
+
+=item B<-state>
+
+prints out the SSL session states.
+
+=item B<-debug>
+
+print extensive debugging information including a hex dump of all traffic.
+
+=item B<-msg>
+
+show all protocol messages with hex dump.
+
+=item B<-nbio_test>
+
+tests non-blocking I/O
+
+=item B<-nbio>
+
+turns on non-blocking I/O
+
+=item B<-crlf>
+
+this option translated a line feed from the terminal into CR+LF as required
+by some servers.
+
+=item B<-ign_eof>
+
+inhibit shutting down the connection when end of file is reached in the
+input.
+
+=item B<-quiet>
+
+inhibit printing of session and certificate information.  This implicitly
+turns on B<-ign_eof> as well.
+
+=item B<-psk_identity identity>
+
+Use the PSK identity B<identity> when using a PSK cipher suite.
+
+=item B<-psk key>
+
+Use the PSK key B<key> when using a PSK cipher suite. The key is
+given as a hexadecimal number without leading 0x, for example -psk
+1a2b3c4d.
+
+=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>
+
+these options disable the use of certain SSL or TLS protocols. By default
+the initial handshake uses a method which should be compatible with all
+servers and permit them to use SSL v3, SSL v2 or TLS as appropriate.
+
+Unfortunately there are a lot of ancient and broken servers in use which
+cannot handle this technique and will fail to connect. Some servers only
+work if TLS is turned off with the B<-no_tls> option others will only
+support SSL v2 and may need the B<-ssl2> option.
+
+=item B<-bugs>
+
+there are several known bug in SSL and TLS implementations. Adding this
+option enables various workarounds.
+
+=item B<-cipher cipherlist>
+
+this allows the cipher list sent by the client to be modified. Although
+the server determines which cipher suite is used it should take the first
+supported cipher in the list sent by the client. See the B<ciphers>
+command for more information.
+
+=item B<-starttls protocol>
+
+send the protocol-specific message(s) to switch to TLS for communication.
+B<protocol> is a keyword for the intended protocol.  Currently, the only
+supported keywords are "smtp", "pop3", "imap", and "ftp".
+
+=item B<-tlsextdebug>
+
+print out a hex dump of any TLS extensions received from the server.
+
+=item B<-no_ticket>
+
+disable RFC4507bis session ticket support. 
+
+=item B<-sess_out filename>
+
+output SSL session to B<filename>
+
+=item B<-sess_in sess.pem>
+
+load SSL session from B<filename>. The client will attempt to resume a
+connection from this session.
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<s_client>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=item B<-rand file(s)>
+
+a file or files containing random data used to seed the random number
+generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
+Multiple files can be specified separated by a OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=back
+
+=head1 CONNECTED COMMANDS
+
+If a connection is established with an SSL server then any data received
+from the server is displayed and any key presses will be sent to the
+server. When used interactively (which means neither B<-quiet> nor B<-ign_eof>
+have been given), the session will be renegotiated if the line begins with an
+B<R>, and if the line begins with a B<Q> or if end of file is reached, the
+connection will be closed down.
+
+=head1 NOTES
+
+B<s_client> can be used to debug SSL servers. To connect to an SSL HTTP
+server the command:
+
+ openssl s_client -connect servername:443
+
+would typically be used (https uses port 443). If the connection succeeds
+then an HTTP command can be given such as "GET /" to retrieve a web page.
+
+If the handshake fails then there are several possible causes, if it is
+nothing obvious like no client certificate then the B<-bugs>, B<-ssl2>,
+B<-ssl3>, B<-tls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1> options can be tried
+in case it is a buggy server. In particular you should play with these
+options B<before> submitting a bug report to an OpenSSL mailing list.
+
+A frequent problem when attempting to get client certificates working
+is that a web client complains it has no certificates or gives an empty
+list to choose from. This is normally because the server is not sending
+the clients certificate authority in its "acceptable CA list" when it
+requests a certificate. By using B<s_client> the CA list can be viewed
+and checked. However some servers only request client authentication
+after a specific URL is requested. To obtain the list in this case it
+is necessary to use the B<-prexit> option and send an HTTP request
+for an appropriate page.
+
+If a certificate is specified on the command line using the B<-cert>
+option it will not be used unless the server specifically requests
+a client certificate. Therefor merely including a client certificate
+on the command line is no guarantee that the certificate works.
+
+If there are problems verifying a server certificate then the
+B<-showcerts> option can be used to show the whole chain.
+
+Since the SSLv23 client hello cannot include compression methods or extensions
+these will only be supported if its use is disabled, for example by using the
+B<-no_sslv2> option.
+
+=head1 BUGS
+
+Because this program has a lot of options and also because some of
+the techniques used are rather old, the C source of s_client is rather
+hard to read and not a model of how things should be done. A typical
+SSL client program would be much simpler.
+
+The B<-verify> option should really exit if the server verification
+fails.
+
+The B<-prexit> option is a bit of a hack. We should really report
+information whenever a session is renegotiated.
+
+=head1 SEE ALSO
+
+L<sess_id(1)|sess_id(1)>, L<s_server(1)|s_server(1)>, L<ciphers(1)|ciphers(1)>
+
+=cut
diff --git a/openssl/doc/apps/s_server.pod b/openssl/doc/apps/s_server.pod
new file mode 100644
index 0000000..3e503e1
--- /dev/null
+++ b/openssl/doc/apps/s_server.pod
@@ -0,0 +1,355 @@
+
+=pod
+
+=head1 NAME
+
+s_server - SSL/TLS server program
+
+=head1 SYNOPSIS
+
+B<openssl> B<s_server>
+[B<-accept port>]
+[B<-context id>]
+[B<-verify depth>]
+[B<-Verify depth>]
+[B<-crl_check>]
+[B<-crl_check_all>]
+[B<-cert filename>]
+[B<-certform DER|PEM>]
+[B<-key keyfile>]
+[B<-keyform DER|PEM>]
+[B<-pass arg>]
+[B<-dcert filename>]
+[B<-dcertform DER|PEM>]
+[B<-dkey keyfile>]
+[B<-dkeyform DER|PEM>]
+[B<-dpass arg>]
+[B<-dhparam filename>]
+[B<-nbio>]
+[B<-nbio_test>]
+[B<-crlf>]
+[B<-debug>]
+[B<-msg>]
+[B<-state>]
+[B<-CApath directory>]
+[B<-CAfile filename>]
+[B<-nocert>]
+[B<-cipher cipherlist>]
+[B<-quiet>]
+[B<-no_tmp_rsa>]
+[B<-ssl2>]
+[B<-ssl3>]
+[B<-tls1>]
+[B<-no_ssl2>]
+[B<-no_ssl3>]
+[B<-no_tls1>]
+[B<-no_dhe>]
+[B<-bugs>]
+[B<-hack>]
+[B<-www>]
+[B<-WWW>]
+[B<-HTTP>]
+[B<-engine id>]
+[B<-tlsextdebug>]
+[B<-no_ticket>]
+[B<-id_prefix arg>]
+[B<-rand file(s)>]
+
+=head1 DESCRIPTION
+
+The B<s_server> command implements a generic SSL/TLS server which listens
+for connections on a given port using SSL/TLS.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-accept port>
+
+the TCP port to listen on for connections. If not specified 4433 is used.
+
+=item B<-context id>
+
+sets the SSL context id. It can be given any string value. If this option
+is not present a default value will be used.
+
+=item B<-cert certname>
+
+The certificate to use, most servers cipher suites require the use of a
+certificate and some require a certificate with a certain public key type:
+for example the DSS cipher suites require a certificate containing a DSS
+(DSA) key. If not specified then the filename "server.pem" will be used.
+
+=item B<-certform format>
+
+The certificate format to use: DER or PEM. PEM is the default.
+
+=item B<-key keyfile>
+
+The private key to use. If not specified then the certificate file will
+be used.
+
+=item B<-keyform format>
+
+The private format to use: DER or PEM. PEM is the default.
+
+=item B<-pass arg>
+
+the private key password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-dcert filename>, B<-dkey keyname>
+
+specify an additional certificate and private key, these behave in the
+same manner as the B<-cert> and B<-key> options except there is no default
+if they are not specified (no additional certificate and key is used). As
+noted above some cipher suites require a certificate containing a key of
+a certain type. Some cipher suites need a certificate carrying an RSA key
+and some a DSS (DSA) key. By using RSA and DSS certificates and keys
+a server can support clients which only support RSA or DSS cipher suites
+by using an appropriate certificate.
+
+=item B<-dcertform format>, B<-dkeyform format>, B<-dpass arg>
+
+addtional certificate and private key format and passphrase respectively.
+
+=item B<-nocert>
+
+if this option is set then no certificate is used. This restricts the
+cipher suites available to the anonymous ones (currently just anonymous
+DH).
+
+=item B<-dhparam filename>
+
+the DH parameter file to use. The ephemeral DH cipher suites generate keys
+using a set of DH parameters. If not specified then an attempt is made to
+load the parameters from the server certificate file. If this fails then
+a static set of parameters hard coded into the s_server program will be used.
+
+=item B<-no_dhe>
+
+if this option is set then no DH parameters will be loaded effectively
+disabling the ephemeral DH cipher suites.
+
+=item B<-no_tmp_rsa>
+
+certain export cipher suites sometimes use a temporary RSA key, this option
+disables temporary RSA key generation.
+
+=item B<-verify depth>, B<-Verify depth>
+
+The verify depth to use. This specifies the maximum length of the
+client certificate chain and makes the server request a certificate from
+the client. With the B<-verify> option a certificate is requested but the
+client does not have to send one, with the B<-Verify> option the client
+must supply a certificate or an error occurs.
+
+=item B<-crl_check>, B<-crl_check_all>
+
+Check the peer certificate has not been revoked by its CA.
+The CRL(s) are appended to the certificate file. With the B<-crl_check_all>
+option all CRLs of all CAs in the chain are checked.
+
+=item B<-CApath directory>
+
+The directory to use for client certificate verification. This directory
+must be in "hash format", see B<verify> for more information. These are
+also used when building the server certificate chain.
+
+=item B<-CAfile file>
+
+A file containing trusted certificates to use during client authentication
+and to use when attempting to build the server certificate chain. The list
+is also used in the list of acceptable client CAs passed to the client when
+a certificate is requested.
+
+=item B<-state>
+
+prints out the SSL session states.
+
+=item B<-debug>
+
+print extensive debugging information including a hex dump of all traffic.
+
+=item B<-msg>
+
+show all protocol messages with hex dump.
+
+=item B<-nbio_test>
+
+tests non blocking I/O
+
+=item B<-nbio>
+
+turns on non blocking I/O
+
+=item B<-crlf>
+
+this option translated a line feed from the terminal into CR+LF.
+
+=item B<-quiet>
+
+inhibit printing of session and certificate information.
+
+=item B<-psk_hint hint>
+
+Use the PSK identity hint B<hint> when using a PSK cipher suite.
+
+=item B<-psk key>
+
+Use the PSK key B<key> when using a PSK cipher suite. The key is
+given as a hexadecimal number without leading 0x, for example -psk
+1a2b3c4d.
+
+=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>
+
+these options disable the use of certain SSL or TLS protocols. By default
+the initial handshake uses a method which should be compatible with all
+servers and permit them to use SSL v3, SSL v2 or TLS as appropriate.
+
+=item B<-bugs>
+
+there are several known bug in SSL and TLS implementations. Adding this
+option enables various workarounds.
+
+=item B<-hack>
+
+this option enables a further workaround for some some early Netscape
+SSL code (?).
+
+=item B<-cipher cipherlist>
+
+this allows the cipher list used by the server to be modified.  When
+the client sends a list of supported ciphers the first client cipher
+also included in the server list is used. Because the client specifies
+the preference order, the order of the server cipherlist irrelevant. See
+the B<ciphers> command for more information.
+
+=item B<-tlsextdebug>
+
+print out a hex dump of any TLS extensions received from the server.
+
+=item B<-no_ticket>
+
+disable RFC4507bis session ticket support. 
+
+=item B<-www>
+
+sends a status message back to the client when it connects. This includes
+lots of information about the ciphers used and various session parameters.
+The output is in HTML format so this option will normally be used with a
+web browser.
+
+=item B<-WWW>
+
+emulates a simple web server. Pages will be resolved relative to the
+current directory, for example if the URL https://myhost/page.html is
+requested the file ./page.html will be loaded.
+
+=item B<-HTTP>
+
+emulates a simple web server. Pages will be resolved relative to the
+current directory, for example if the URL https://myhost/page.html is
+requested the file ./page.html will be loaded. The files loaded are
+assumed to contain a complete and correct HTTP response (lines that
+are part of the HTTP response line and headers must end with CRLF).
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<s_server>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=item B<-id_prefix arg>
+
+generate SSL/TLS session IDs prefixed by B<arg>. This is mostly useful
+for testing any SSL/TLS code (eg. proxies) that wish to deal with multiple
+servers, when each of which might be generating a unique range of session
+IDs (eg. with a certain prefix).
+
+=item B<-rand file(s)>
+
+a file or files containing random data used to seed the random number
+generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
+Multiple files can be specified separated by a OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=back
+
+=head1 CONNECTED COMMANDS
+
+If a connection request is established with an SSL client and neither the
+B<-www> nor the B<-WWW> option has been used then normally any data received
+from the client is displayed and any key presses will be sent to the client. 
+
+Certain single letter commands are also recognized which perform special
+operations: these are listed below.
+
+=over 4
+
+=item B<q>
+
+end the current SSL connection but still accept new connections.
+
+=item B<Q>
+
+end the current SSL connection and exit.
+
+=item B<r>
+
+renegotiate the SSL session.
+
+=item B<R>
+
+renegotiate the SSL session and request a client certificate.
+
+=item B<P>
+
+send some plain text down the underlying TCP connection: this should
+cause the client to disconnect due to a protocol violation.
+
+=item B<S>
+
+print out some session cache status information.
+
+=back
+
+=head1 NOTES
+
+B<s_server> can be used to debug SSL clients. To accept connections from
+a web browser the command:
+
+ openssl s_server -accept 443 -www
+
+can be used for example.
+
+Most web browsers (in particular Netscape and MSIE) only support RSA cipher
+suites, so they cannot connect to servers which don't use a certificate
+carrying an RSA key or a version of OpenSSL with RSA disabled.
+
+Although specifying an empty list of CAs when requesting a client certificate
+is strictly speaking a protocol violation, some SSL clients interpret this to
+mean any CA is acceptable. This is useful for debugging purposes.
+
+The session parameters can printed out using the B<sess_id> program.
+
+=head1 BUGS
+
+Because this program has a lot of options and also because some of
+the techniques used are rather old, the C source of s_server is rather
+hard to read and not a model of how things should be done. A typical
+SSL server program would be much simpler.
+
+The output of common ciphers is wrong: it just gives the list of ciphers that
+OpenSSL recognizes and the client supports.
+
+There should be a way for the B<s_server> program to print out details of any
+unknown cipher suites a client says it supports.
+
+=head1 SEE ALSO
+
+L<sess_id(1)|sess_id(1)>, L<s_client(1)|s_client(1)>, L<ciphers(1)|ciphers(1)>
+
+=cut
diff --git a/openssl/doc/apps/s_time.pod b/openssl/doc/apps/s_time.pod
new file mode 100644
index 0000000..5a38aa2
--- /dev/null
+++ b/openssl/doc/apps/s_time.pod
@@ -0,0 +1,173 @@
+
+=pod
+
+=head1 NAME
+
+s_time - SSL/TLS performance timing program
+
+=head1 SYNOPSIS
+
+B<openssl> B<s_time>
+[B<-connect host:port>]
+[B<-www page>]
+[B<-cert filename>]
+[B<-key filename>]
+[B<-CApath directory>]
+[B<-CAfile filename>]
+[B<-reuse>]
+[B<-new>]
+[B<-verify depth>]
+[B<-nbio>]
+[B<-time seconds>]
+[B<-ssl2>]
+[B<-ssl3>]
+[B<-bugs>]
+[B<-cipher cipherlist>]
+
+=head1 DESCRIPTION
+
+The B<s_client> command implements a generic SSL/TLS client which connects to a
+remote host using SSL/TLS. It can request a page from the server and includes
+the time to transfer the payload data in its timing measurements. It measures
+the number of connections within a given timeframe, the amount of data
+transferred (if any), and calculates the average time spent for one connection.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-connect host:port>
+
+This specifies the host and optional port to connect to.
+
+=item B<-www page>
+
+This specifies the page to GET from the server. A value of '/' gets the
+index.htm[l] page. If this parameter is not specified, then B<s_time> will only
+perform the handshake to establish SSL connections but not transfer any
+payload data.
+
+=item B<-cert certname>
+
+The certificate to use, if one is requested by the server. The default is
+not to use a certificate. The file is in PEM format.
+
+=item B<-key keyfile>
+
+The private key to use. If not specified then the certificate file will
+be used. The file is in PEM format.
+
+=item B<-verify depth>
+
+The verify depth to use. This specifies the maximum length of the
+server certificate chain and turns on server certificate verification.
+Currently the verify operation continues after errors so all the problems
+with a certificate chain can be seen. As a side effect the connection
+will never fail due to a server certificate verify failure.
+
+=item B<-CApath directory>
+
+The directory to use for server certificate verification. This directory
+must be in "hash format", see B<verify> for more information. These are
+also used when building the client certificate chain.
+
+=item B<-CAfile file>
+
+A file containing trusted certificates to use during server authentication
+and to use when attempting to build the client certificate chain.
+
+=item B<-new>
+
+performs the timing test using a new session ID for each connection.
+If neither B<-new> nor B<-reuse> are specified, they are both on by default
+and executed in sequence.
+
+=item B<-reuse>
+
+performs the timing test using the same session ID; this can be used as a test
+that session caching is working. If neither B<-new> nor B<-reuse> are
+specified, they are both on by default and executed in sequence.
+
+=item B<-nbio>
+
+turns on non-blocking I/O.
+
+=item B<-ssl2>, B<-ssl3>
+
+these options disable the use of certain SSL or TLS protocols. By default
+the initial handshake uses a method which should be compatible with all
+servers and permit them to use SSL v3, SSL v2 or TLS as appropriate.
+The timing program is not as rich in options to turn protocols on and off as
+the L<s_client(1)|s_client(1)> program and may not connect to all servers.
+
+Unfortunately there are a lot of ancient and broken servers in use which
+cannot handle this technique and will fail to connect. Some servers only
+work if TLS is turned off with the B<-ssl3> option; others
+will only support SSL v2 and may need the B<-ssl2> option.
+
+=item B<-bugs>
+
+there are several known bug in SSL and TLS implementations. Adding this
+option enables various workarounds.
+
+=item B<-cipher cipherlist>
+
+this allows the cipher list sent by the client to be modified. Although
+the server determines which cipher suite is used it should take the first
+supported cipher in the list sent by the client.
+See the L<ciphers(1)|ciphers(1)> command for more information.
+
+=item B<-time length>
+
+specifies how long (in seconds) B<s_time> should establish connections and
+optionally transfer payload data from a server. Server and client performance
+and the link speed determine how many connections B<s_time> can establish.
+
+=back
+
+=head1 NOTES
+
+B<s_client> can be used to measure the performance of an SSL connection.
+To connect to an SSL HTTP server and get the default page the command
+
+ openssl s_time -connect servername:443 -www / -CApath yourdir -CAfile yourfile.pem -cipher commoncipher [-ssl3]
+
+would typically be used (https uses port 443). 'commoncipher' is a cipher to
+which both client and server can agree, see the L<ciphers(1)|ciphers(1)> command
+for details.
+
+If the handshake fails then there are several possible causes, if it is
+nothing obvious like no client certificate then the B<-bugs>, B<-ssl2>,
+B<-ssl3> options can be tried
+in case it is a buggy server. In particular you should play with these
+options B<before> submitting a bug report to an OpenSSL mailing list.
+
+A frequent problem when attempting to get client certificates working
+is that a web client complains it has no certificates or gives an empty
+list to choose from. This is normally because the server is not sending
+the clients certificate authority in its "acceptable CA list" when it
+requests a certificate. By using L<s_client(1)|s_client(1)> the CA list can be
+viewed and checked. However some servers only request client authentication
+after a specific URL is requested. To obtain the list in this case it
+is necessary to use the B<-prexit> option of L<s_client(1)|s_client(1)> and
+send an HTTP request for an appropriate page.
+
+If a certificate is specified on the command line using the B<-cert>
+option it will not be used unless the server specifically requests
+a client certificate. Therefor merely including a client certificate
+on the command line is no guarantee that the certificate works.
+
+=head1 BUGS
+
+Because this program does not have all the options of the
+L<s_client(1)|s_client(1)> program to turn protocols on and off, you may not be
+able to measure the performance of all protocols with all servers.
+
+The B<-verify> option should really exit if the server verification
+fails.
+
+=head1 SEE ALSO
+
+L<s_client(1)|s_client(1)>, L<s_server(1)|s_server(1)>, L<ciphers(1)|ciphers(1)>
+
+=cut
diff --git a/openssl/doc/apps/sess_id.pod b/openssl/doc/apps/sess_id.pod
new file mode 100644
index 0000000..9988d2c
--- /dev/null
+++ b/openssl/doc/apps/sess_id.pod
@@ -0,0 +1,151 @@
+
+=pod
+
+=head1 NAME
+
+sess_id - SSL/TLS session handling utility
+
+=head1 SYNOPSIS
+
+B<openssl> B<sess_id>
+[B<-inform PEM|DER>]
+[B<-outform PEM|DER>]
+[B<-in filename>]
+[B<-out filename>]
+[B<-text>]
+[B<-noout>]
+[B<-context ID>]
+
+=head1 DESCRIPTION
+
+The B<sess_id> process the encoded version of the SSL session structure
+and optionally prints out SSL session details (for example the SSL session
+master key) in human readable format. Since this is a diagnostic tool that
+needs some knowledge of the SSL protocol to use properly, most users will
+not need to use it.
+
+=over 4
+
+=item B<-inform DER|PEM>
+
+This specifies the input format. The B<DER> option uses an ASN1 DER encoded
+format containing session details. The precise format can vary from one version
+to the next.  The B<PEM> form is the default format: it consists of the B<DER>
+format base64 encoded with additional header and footer lines.
+
+=item B<-outform DER|PEM>
+
+This specifies the output format, the options have the same meaning as the 
+B<-inform> option.
+
+=item B<-in filename>
+
+This specifies the input filename to read session information from or standard
+input by default.
+
+=item B<-out filename>
+
+This specifies the output filename to write session information to or standard
+output if this option is not specified.
+
+=item B<-text>
+
+prints out the various public or private key components in
+plain text in addition to the encoded version. 
+
+=item B<-cert>
+
+if a certificate is present in the session it will be output using this option,
+if the B<-text> option is also present then it will be printed out in text form.
+
+=item B<-noout>
+
+this option prevents output of the encoded version of the session.
+
+=item B<-context ID>
+
+this option can set the session id so the output session information uses the
+supplied ID. The ID can be any string of characters. This option wont normally
+be used.
+
+=back
+
+=head1 OUTPUT
+
+Typical output:
+
+ SSL-Session:
+     Protocol  : TLSv1
+     Cipher    : 0016
+     Session-ID: 871E62626C554CE95488823752CBD5F3673A3EF3DCE9C67BD916C809914B40ED
+     Session-ID-ctx: 01000000
+     Master-Key: A7CEFC571974BE02CAC305269DC59F76EA9F0B180CB6642697A68251F2D2BB57E51DBBB4C7885573192AE9AEE220FACD
+     Key-Arg   : None
+     Start Time: 948459261
+     Timeout   : 300 (sec)
+     Verify return code 0 (ok)
+
+Theses are described below in more detail.
+
+=over 4
+
+=item B<Protocol>
+
+this is the protocol in use TLSv1, SSLv3 or SSLv2.
+
+=item B<Cipher>
+
+the cipher used this is the actual raw SSL or TLS cipher code, see the SSL
+or TLS specifications for more information.
+
+=item B<Session-ID>
+
+the SSL session ID in hex format.
+
+=item B<Session-ID-ctx>
+
+the session ID context in hex format.
+
+=item B<Master-Key>
+
+this is the SSL session master key.
+
+=item B<Key-Arg>
+
+the key argument, this is only used in SSL v2.
+
+=item B<Start Time>
+
+this is the session start time represented as an integer in standard Unix format.
+
+=item B<Timeout>
+
+the timeout in seconds.
+
+=item B<Verify return code>
+
+this is the return code when an SSL client certificate is verified.
+
+=back
+
+=head1 NOTES
+
+The PEM encoded session format uses the header and footer lines:
+
+ -----BEGIN SSL SESSION PARAMETERS-----
+ -----END SSL SESSION PARAMETERS-----
+
+Since the SSL session output contains the master key it is possible to read the contents
+of an encrypted session using this information. Therefore appropriate security precautions
+should be taken if the information is being output by a "real" application. This is
+however strongly discouraged and should only be used for debugging purposes.
+
+=head1 BUGS
+
+The cipher and start time should be printed out in human readable form.
+
+=head1 SEE ALSO
+
+L<ciphers(1)|ciphers(1)>, L<s_server(1)|s_server(1)>
+
+=cut
diff --git a/openssl/doc/apps/smime.pod b/openssl/doc/apps/smime.pod
new file mode 100644
index 0000000..e4e89af
--- /dev/null
+++ b/openssl/doc/apps/smime.pod
@@ -0,0 +1,445 @@
+=pod
+
+=head1 NAME
+
+smime - S/MIME utility
+
+=head1 SYNOPSIS
+
+B<openssl> B<smime>
+[B<-encrypt>]
+[B<-decrypt>]
+[B<-sign>]
+[B<-resign>]
+[B<-verify>]
+[B<-pk7out>]
+[B<-[cipher]>]
+[B<-in file>]
+[B<-certfile file>]
+[B<-signer file>]
+[B<-recip  file>]
+[B<-inform SMIME|PEM|DER>]
+[B<-passin arg>]
+[B<-inkey file>]
+[B<-out file>]
+[B<-outform SMIME|PEM|DER>]
+[B<-content file>]
+[B<-to addr>]
+[B<-from ad>]
+[B<-subject s>]
+[B<-text>]
+[B<-indef>]
+[B<-noindef>]
+[B<-stream>]
+[B<-rand file(s)>]
+[B<-md digest>]
+[cert.pem]...
+
+=head1 DESCRIPTION
+
+The B<smime> command handles S/MIME mail. It can encrypt, decrypt, sign and
+verify S/MIME messages.
+
+=head1 COMMAND OPTIONS
+
+There are six operation options that set the type of operation to be performed.
+The meaning of the other options varies according to the operation type.
+
+=over 4
+
+=item B<-encrypt>
+
+encrypt mail for the given recipient certificates. Input file is the message
+to be encrypted. The output file is the encrypted mail in MIME format.
+
+=item B<-decrypt>
+
+decrypt mail using the supplied certificate and private key. Expects an
+encrypted mail message in MIME format for the input file. The decrypted mail
+is written to the output file.
+
+=item B<-sign>
+
+sign mail using the supplied certificate and private key. Input file is
+the message to be signed. The signed message in MIME format is written
+to the output file.
+
+=item B<-verify>
+
+verify signed mail. Expects a signed mail message on input and outputs
+the signed data. Both clear text and opaque signing is supported.
+
+=item B<-pk7out>
+
+takes an input message and writes out a PEM encoded PKCS#7 structure.
+
+=item B<-resign>
+
+resign a message: take an existing message and one or more new signers.
+
+=item B<-in filename>
+
+the input message to be encrypted or signed or the MIME message to
+be decrypted or verified.
+
+=item B<-inform SMIME|PEM|DER>
+
+this specifies the input format for the PKCS#7 structure. The default
+is B<SMIME> which reads an S/MIME format message. B<PEM> and B<DER>
+format change this to expect PEM and DER format PKCS#7 structures
+instead. This currently only affects the input format of the PKCS#7
+structure, if no PKCS#7 structure is being input (for example with
+B<-encrypt> or B<-sign>) this option has no effect.
+
+=item B<-out filename>
+
+the message text that has been decrypted or verified or the output MIME
+format message that has been signed or verified.
+
+=item B<-outform SMIME|PEM|DER>
+
+this specifies the output format for the PKCS#7 structure. The default
+is B<SMIME> which write an S/MIME format message. B<PEM> and B<DER>
+format change this to write PEM and DER format PKCS#7 structures
+instead. This currently only affects the output format of the PKCS#7
+structure, if no PKCS#7 structure is being output (for example with
+B<-verify> or B<-decrypt>) this option has no effect.
+
+=item B<-stream -indef -noindef>
+
+the B<-stream> and B<-indef> options are equivalent and enable streaming I/O
+for encoding operations. This permits single pass processing of data without
+the need to hold the entire contents in memory, potentially supporting very
+large files. Streaming is automatically set for S/MIME signing with detached
+data if the output format is B<SMIME> it is currently off by default for all
+other operations.
+
+=item B<-noindef>
+
+disable streaming I/O where it would produce and indefinite length constructed
+encoding. This option currently has no effect. In future streaming will be
+enabled by default on all relevant operations and this option will disable it.
+
+=item B<-content filename>
+
+This specifies a file containing the detached content, this is only
+useful with the B<-verify> command. This is only usable if the PKCS#7
+structure is using the detached signature form where the content is
+not included. This option will override any content if the input format
+is S/MIME and it uses the multipart/signed MIME content type.
+
+=item B<-text>
+
+this option adds plain text (text/plain) MIME headers to the supplied
+message if encrypting or signing. If decrypting or verifying it strips
+off text headers: if the decrypted or verified message is not of MIME 
+type text/plain then an error occurs.
+
+=item B<-CAfile file>
+
+a file containing trusted CA certificates, only used with B<-verify>.
+
+=item B<-CApath dir>
+
+a directory containing trusted CA certificates, only used with
+B<-verify>. This directory must be a standard certificate directory: that
+is a hash of each subject name (using B<x509 -hash>) should be linked
+to each certificate.
+
+=item B<-md digest>
+
+digest algorithm to use when signing or resigning. If not present then the
+default digest algorithm for the signing key will be used (usually SHA1).
+
+=item B<-[cipher]>
+
+the encryption algorithm to use. For example DES  (56 bits) - B<-des>,
+triple DES (168 bits) - B<-des3>,
+EVP_get_cipherbyname() function) can also be used preceded by a dash, for 
+example B<-aes_128_cbc>. See L<B<enc>|enc(1)> for list of ciphers
+supported by your version of OpenSSL.
+
+If not specified 40 bit RC2 is used. Only used with B<-encrypt>.
+
+=item B<-nointern>
+
+when verifying a message normally certificates (if any) included in
+the message are searched for the signing certificate. With this option
+only the certificates specified in the B<-certfile> option are used.
+The supplied certificates can still be used as untrusted CAs however.
+
+=item B<-noverify>
+
+do not verify the signers certificate of a signed message.
+
+=item B<-nochain>
+
+do not do chain verification of signers certificates: that is don't
+use the certificates in the signed message as untrusted CAs.
+
+=item B<-nosigs>
+
+don't try to verify the signatures on the message.
+
+=item B<-nocerts>
+
+when signing a message the signer's certificate is normally included
+with this option it is excluded. This will reduce the size of the
+signed message but the verifier must have a copy of the signers certificate
+available locally (passed using the B<-certfile> option for example).
+
+=item B<-noattr>
+
+normally when a message is signed a set of attributes are included which
+include the signing time and supported symmetric algorithms. With this
+option they are not included.
+
+=item B<-binary>
+
+normally the input message is converted to "canonical" format which is
+effectively using CR and LF as end of line: as required by the S/MIME
+specification. When this option is present no translation occurs. This
+is useful when handling binary data which may not be in MIME format.
+
+=item B<-nodetach>
+
+when signing a message use opaque signing: this form is more resistant
+to translation by mail relays but it cannot be read by mail agents that
+do not support S/MIME.  Without this option cleartext signing with
+the MIME type multipart/signed is used.
+
+=item B<-certfile file>
+
+allows additional certificates to be specified. When signing these will
+be included with the message. When verifying these will be searched for
+the signers certificates. The certificates should be in PEM format.
+
+=item B<-signer file>
+
+a signing certificate when signing or resigning a message, this option can be
+used multiple times if more than one signer is required. If a message is being
+verified then the signers certificates will be written to this file if the
+verification was successful.
+
+=item B<-recip file>
+
+the recipients certificate when decrypting a message. This certificate
+must match one of the recipients of the message or an error occurs.
+
+=item B<-inkey file>
+
+the private key to use when signing or decrypting. This must match the
+corresponding certificate. If this option is not specified then the
+private key must be included in the certificate file specified with
+the B<-recip> or B<-signer> file. When signing this option can be used
+multiple times to specify successive keys.
+
+=item B<-passin arg>
+
+the private key password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-rand file(s)>
+
+a file or files containing random data used to seed the random number
+generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
+Multiple files can be specified separated by a OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item B<cert.pem...>
+
+one or more certificates of message recipients: used when encrypting
+a message. 
+
+=item B<-to, -from, -subject>
+
+the relevant mail headers. These are included outside the signed
+portion of a message so they may be included manually. If signing
+then many S/MIME mail clients check the signers certificate's email
+address matches that specified in the From: address.
+
+=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig>
+
+Set various options of certificate chain verification. See
+L<B<verify>|verify(1)> manual page for details.
+
+=back
+
+=head1 NOTES
+
+The MIME message must be sent without any blank lines between the
+headers and the output. Some mail programs will automatically add
+a blank line. Piping the mail directly to sendmail is one way to
+achieve the correct format.
+
+The supplied message to be signed or encrypted must include the
+necessary MIME headers or many S/MIME clients wont display it
+properly (if at all). You can use the B<-text> option to automatically
+add plain text headers.
+
+A "signed and encrypted" message is one where a signed message is
+then encrypted. This can be produced by encrypting an already signed
+message: see the examples section.
+
+This version of the program only allows one signer per message but it
+will verify multiple signers on received messages. Some S/MIME clients
+choke if a message contains multiple signers. It is possible to sign
+messages "in parallel" by signing an already signed message.
+
+The options B<-encrypt> and B<-decrypt> reflect common usage in S/MIME
+clients. Strictly speaking these process PKCS#7 enveloped data: PKCS#7
+encrypted data is used for other purposes.
+
+The B<-resign> option uses an existing message digest when adding a new
+signer. This means that attributes must be present in at least one existing
+signer using the same message digest or this operation will fail.
+
+The B<-stream> and B<-indef> options enable experimental streaming I/O support.
+As a result the encoding is BER using indefinite length constructed encoding
+and no longer DER. Streaming is supported for the B<-encrypt> operation and the
+B<-sign> operation if the content is not detached.
+
+Streaming is always used for the B<-sign> operation with detached data but
+since the content is no longer part of the PKCS#7 structure the encoding
+remains DER.
+
+=head1 EXIT CODES
+
+=over 4
+
+=item 0
+
+the operation was completely successfully.
+
+=item 1 
+
+an error occurred parsing the command options.
+
+=item 2
+
+one of the input files could not be read.
+
+=item 3
+
+an error occurred creating the PKCS#7 file or when reading the MIME
+message.
+
+=item 4
+
+an error occurred decrypting or verifying the message.
+
+=item 5
+
+the message was verified correctly but an error occurred writing out
+the signers certificates.
+
+=back
+
+=head1 EXAMPLES
+
+Create a cleartext signed message:
+
+ openssl smime -sign -in message.txt -text -out mail.msg \
+	-signer mycert.pem
+
+Create an opaque signed message:
+
+ openssl smime -sign -in message.txt -text -out mail.msg -nodetach \
+	-signer mycert.pem
+
+Create a signed message, include some additional certificates and
+read the private key from another file:
+
+ openssl smime -sign -in in.txt -text -out mail.msg \
+	-signer mycert.pem -inkey mykey.pem -certfile mycerts.pem
+
+Create a signed message with two signers:
+
+ openssl smime -sign -in message.txt -text -out mail.msg \
+	-signer mycert.pem -signer othercert.pem
+
+Send a signed message under Unix directly to sendmail, including headers:
+
+ openssl smime -sign -in in.txt -text -signer mycert.pem \
+	-from steve@openssl.org -to someone@somewhere \
+	-subject "Signed message" | sendmail someone@somewhere
+
+Verify a message and extract the signer's certificate if successful:
+
+ openssl smime -verify -in mail.msg -signer user.pem -out signedtext.txt
+
+Send encrypted mail using triple DES:
+
+ openssl smime -encrypt -in in.txt -from steve@openssl.org \
+	-to someone@somewhere -subject "Encrypted message" \
+	-des3 user.pem -out mail.msg
+
+Sign and encrypt mail:
+
+ openssl smime -sign -in ml.txt -signer my.pem -text \
+	| openssl smime -encrypt -out mail.msg \
+	-from steve@openssl.org -to someone@somewhere \
+	-subject "Signed and Encrypted message" -des3 user.pem
+
+Note: the encryption command does not include the B<-text> option because the
+message being encrypted already has MIME headers.
+
+Decrypt mail:
+
+ openssl smime -decrypt -in mail.msg -recip mycert.pem -inkey key.pem
+
+The output from Netscape form signing is a PKCS#7 structure with the
+detached signature format. You can use this program to verify the
+signature by line wrapping the base64 encoded structure and surrounding
+it with:
+
+ -----BEGIN PKCS7-----
+ -----END PKCS7-----
+
+and using the command: 
+
+ openssl smime -verify -inform PEM -in signature.pem -content content.txt
+
+Alternatively you can base64 decode the signature and use:
+
+ openssl smime -verify -inform DER -in signature.der -content content.txt
+
+Create an encrypted message using 128 bit Camellia:
+
+ openssl smime -encrypt -in plain.txt -camellia128 -out mail.msg cert.pem
+
+Add a signer to an existing message:
+
+ openssl smime -resign -in mail.msg -signer newsign.pem -out mail2.msg
+
+=head1 BUGS
+
+The MIME parser isn't very clever: it seems to handle most messages that I've
+thrown at it but it may choke on others.
+
+The code currently will only write out the signer's certificate to a file: if
+the signer has a separate encryption certificate this must be manually
+extracted. There should be some heuristic that determines the correct
+encryption certificate.
+
+Ideally a database should be maintained of a certificates for each email
+address.
+
+The code doesn't currently take note of the permitted symmetric encryption
+algorithms as supplied in the SMIMECapabilities signed attribute. This means the
+user has to manually include the correct encryption algorithm. It should store
+the list of permitted ciphers in a database and only use those.
+
+No revocation checking is done on the signer's certificate.
+
+The current code can only handle S/MIME v2 messages, the more complex S/MIME v3
+structures may cause parsing errors.
+
+=head1 HISTORY
+
+The use of multiple B<-signer> options and the B<-resign> command were first
+added in OpenSSL 1.0.0
+
+
+=cut
diff --git a/openssl/doc/apps/speed.pod b/openssl/doc/apps/speed.pod
new file mode 100644
index 0000000..1cd1998
--- /dev/null
+++ b/openssl/doc/apps/speed.pod
@@ -0,0 +1,59 @@
+=pod
+
+=head1 NAME
+
+speed - test library performance
+
+=head1 SYNOPSIS
+
+B<openssl speed>
+[B<-engine id>]
+[B<md2>]
+[B<mdc2>]
+[B<md5>]
+[B<hmac>]
+[B<sha1>]
+[B<rmd160>]
+[B<idea-cbc>]
+[B<rc2-cbc>]
+[B<rc5-cbc>]
+[B<bf-cbc>]
+[B<des-cbc>]
+[B<des-ede3>]
+[B<rc4>]
+[B<rsa512>]
+[B<rsa1024>]
+[B<rsa2048>]
+[B<rsa4096>]
+[B<dsa512>]
+[B<dsa1024>]
+[B<dsa2048>]
+[B<idea>]
+[B<rc2>]
+[B<des>]
+[B<rsa>]
+[B<blowfish>]
+
+=head1 DESCRIPTION
+
+This command is used to test the performance of cryptographic algorithms.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<speed>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=item B<[zero or more test algorithms]>
+
+If any options are given, B<speed> tests those algorithms, otherwise all of
+the above are tested.
+
+=back
+
+=cut
diff --git a/openssl/doc/apps/spkac.pod b/openssl/doc/apps/spkac.pod
new file mode 100644
index 0000000..97fb80e
--- /dev/null
+++ b/openssl/doc/apps/spkac.pod
@@ -0,0 +1,133 @@
+=pod
+
+=head1 NAME
+
+spkac - SPKAC printing and generating utility
+
+=head1 SYNOPSIS
+
+B<openssl> B<spkac>
+[B<-in filename>]
+[B<-out filename>]
+[B<-key keyfile>]
+[B<-passin arg>]
+[B<-challenge string>]
+[B<-pubkey>]
+[B<-spkac spkacname>]
+[B<-spksect section>]
+[B<-noout>]
+[B<-verify>]
+[B<-engine id>]
+
+=head1 DESCRIPTION
+
+The B<spkac> command processes Netscape signed public key and challenge
+(SPKAC) files. It can print out their contents, verify the signature and
+produce its own SPKACs from a supplied private key.
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<-in filename>
+
+This specifies the input filename to read from or standard input if this
+option is not specified. Ignored if the B<-key> option is used.
+
+=item B<-out filename>
+
+specifies the output filename to write to or standard output by
+default.
+
+=item B<-key keyfile>
+
+create an SPKAC file using the private key in B<keyfile>. The
+B<-in>, B<-noout>, B<-spksect> and B<-verify> options are ignored if
+present.
+
+=item B<-passin password>
+
+the input file password source. For more information about the format of B<arg>
+see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
+
+=item B<-challenge string>
+
+specifies the challenge string if an SPKAC is being created.
+
+=item B<-spkac spkacname>
+
+allows an alternative name form the variable containing the
+SPKAC. The default is "SPKAC". This option affects both
+generated and input SPKAC files.
+
+=item B<-spksect section>
+
+allows an alternative name form the section containing the
+SPKAC. The default is the default section.
+
+=item B<-noout>
+
+don't output the text version of the SPKAC (not used if an
+SPKAC is being created).
+
+=item B<-pubkey>
+
+output the public key of an SPKAC (not used if an SPKAC is
+being created).
+
+=item B<-verify>
+
+verifies the digital signature on the supplied SPKAC.
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<spkac>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=back
+
+=head1 EXAMPLES
+
+Print out the contents of an SPKAC:
+
+ openssl spkac -in spkac.cnf
+
+Verify the signature of an SPKAC:
+
+ openssl spkac -in spkac.cnf -noout -verify
+
+Create an SPKAC using the challenge string "hello":
+
+ openssl spkac -key key.pem -challenge hello -out spkac.cnf
+
+Example of an SPKAC, (long lines split up for clarity):
+
+ SPKAC=MIG5MGUwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA1cCoq2Wa3Ixs47uI7F\
+ PVwHVIPDx5yso105Y6zpozam135a8R0CpoRvkkigIyXfcCjiVi5oWk+6FfPaD03u\
+ PFoQIDAQABFgVoZWxsbzANBgkqhkiG9w0BAQQFAANBAFpQtY/FojdwkJh1bEIYuc\
+ 2EeM2KHTWPEepWYeawvHD0gQ3DngSC75YCWnnDdq+NQ3F+X4deMx9AaEglZtULwV\
+ 4=
+
+=head1 NOTES
+
+A created SPKAC with suitable DN components appended can be fed into
+the B<ca> utility.
+
+SPKACs are typically generated by Netscape when a form is submitted
+containing the B<KEYGEN> tag as part of the certificate enrollment
+process.
+
+The challenge string permits a primitive form of proof of possession
+of private key. By checking the SPKAC signature and a random challenge
+string some guarantee is given that the user knows the private key
+corresponding to the public key being certified. This is important in
+some applications. Without this it is possible for a previous SPKAC
+to be used in a "replay attack".
+
+=head1 SEE ALSO
+
+L<ca(1)|ca(1)>
+
+=cut
diff --git a/openssl/doc/apps/ts.pod b/openssl/doc/apps/ts.pod
new file mode 100644
index 0000000..7fb6caa
--- /dev/null
+++ b/openssl/doc/apps/ts.pod
@@ -0,0 +1,594 @@
+=pod
+
+=head1 NAME
+
+ts - Time Stamping Authority tool (client/server)
+
+=head1 SYNOPSIS
+
+B<openssl> B<ts>
+B<-query>
+[B<-rand> file:file...]
+[B<-config> configfile]
+[B<-data> file_to_hash]
+[B<-digest> digest_bytes]
+[B<-md2>|B<-md4>|B<-md5>|B<-sha>|B<-sha1>|B<-mdc2>|B<-ripemd160>|B<...>]
+[B<-policy> object_id]
+[B<-no_nonce>]
+[B<-cert>]
+[B<-in> request.tsq]
+[B<-out> request.tsq]
+[B<-text>]
+
+B<openssl> B<ts>
+B<-reply>
+[B<-config> configfile]
+[B<-section> tsa_section]
+[B<-queryfile> request.tsq]
+[B<-passin> password_src]
+[B<-signer> tsa_cert.pem]
+[B<-inkey> private.pem]
+[B<-chain> certs_file.pem]
+[B<-policy> object_id]
+[B<-in> response.tsr]
+[B<-token_in>]
+[B<-out> response.tsr]
+[B<-token_out>]
+[B<-text>]
+[B<-engine> id]
+
+B<openssl> B<ts>
+B<-verify>
+[B<-data> file_to_hash]
+[B<-digest> digest_bytes]
+[B<-queryfile> request.tsq]
+[B<-in> response.tsr]
+[B<-token_in>]
+[B<-CApath> trusted_cert_path]
+[B<-CAfile> trusted_certs.pem]
+[B<-untrusted> cert_file.pem]
+
+=head1 DESCRIPTION
+
+The B<ts> command is a basic Time Stamping Authority (TSA) client and server
+application as specified in RFC 3161 (Time-Stamp Protocol, TSP). A
+TSA can be part of a PKI deployment and its role is to provide long
+term proof of the existence of a certain datum before a particular
+time. Here is a brief description of the protocol:
+
+=over 4
+
+=item 1.
+
+The TSA client computes a one-way hash value for a data file and sends
+the hash to the TSA.
+
+=item 2.
+
+The TSA attaches the current date and time to the received hash value,
+signs them and sends the time stamp token back to the client. By
+creating this token the TSA certifies the existence of the original
+data file at the time of response generation.
+
+=item 3.
+
+The TSA client receives the time stamp token and verifies the
+signature on it. It also checks if the token contains the same hash
+value that it had sent to the TSA.
+
+=back
+
+There is one DER encoded protocol data unit defined for transporting a time
+stamp request to the TSA and one for sending the time stamp response
+back to the client. The B<ts> command has three main functions:
+creating a time stamp request based on a data file,
+creating a time stamp response based on a request, verifying if a
+response corresponds to a particular request or a data file.
+
+There is no support for sending the requests/responses automatically
+over HTTP or TCP yet as suggested in RFC 3161. The users must send the
+requests either by ftp or e-mail.
+
+=head1 OPTIONS
+
+=head2 Time Stamp Request generation
+
+The B<-query> switch can be used for creating and printing a time stamp
+request with the following options:
+
+=over 4
+
+=item B<-rand> file:file...
+
+The files containing random data for seeding the random number
+generator. Multiple files can be specified, the separator is B<;> for
+MS-Windows, B<,> for VMS and B<:> for all other platforms. (Optional)
+
+=item B<-config> configfile
+
+The configuration file to use, this option overrides the
+B<OPENSSL_CONF> environment variable. Only the OID section
+of the config file is used with the B<-query> command. (Optional)
+
+=item B<-data> file_to_hash
+
+The data file for which the time stamp request needs to be
+created. stdin is the default if neither the B<-data> nor the B<-digest>
+parameter is specified. (Optional)
+
+=item B<-digest> digest_bytes
+
+It is possible to specify the message imprint explicitly without the data
+file. The imprint must be specified in a hexadecimal format, two characters
+per byte, the bytes optionally separated by colons (e.g. 1A:F6:01:... or
+1AF601...). The number of bytes must match the message digest algorithm 
+in use. (Optional)
+
+=item B<-md2>|B<-md4>|B<-md5>|B<-sha>|B<-sha1>|B<-mdc2>|B<-ripemd160>|B<...>
+
+The message digest to apply to the data file, it supports all the message
+digest algorithms that are supported by the openssl B<dgst> command.
+The default is SHA-1. (Optional)
+
+=item B<-policy> object_id
+
+The policy that the client expects the TSA to use for creating the
+time stamp token. Either the dotted OID notation or OID names defined
+in the config file can be used. If no policy is requested the TSA will
+use its own default policy. (Optional)
+
+=item B<-no_nonce>
+
+No nonce is specified in the request if this option is
+given. Otherwise a 64 bit long pseudo-random none is
+included in the request. It is recommended to use nonce to
+protect against replay-attacks. (Optional)
+
+=item B<-cert>
+
+The TSA is expected to include its signing certificate in the
+response. (Optional)
+
+=item B<-in> request.tsq
+
+This option specifies a previously created time stamp request in DER
+format that will be printed into the output file. Useful when you need
+to examine the content of a request in human-readable
+
+format. (Optional)
+
+=item B<-out> request.tsq
+
+Name of the output file to which the request will be written. Default
+is stdout. (Optional)
+
+=item B<-text>
+
+If this option is specified the output is human-readable text format
+instead of DER. (Optional)
+
+=back
+
+=head2 Time Stamp Response generation
+
+A time stamp response (TimeStampResp) consists of a response status
+and the time stamp token itself (ContentInfo), if the token generation was
+successful. The B<-reply> command is for creating a time stamp
+response or time stamp token based on a request and printing the
+response/token in human-readable format. If B<-token_out> is not
+specified the output is always a time stamp response (TimeStampResp),
+otherwise it is a time stamp token (ContentInfo).
+
+=over 4
+
+=item B<-config> configfile
+
+The configuration file to use, this option overrides the
+B<OPENSSL_CONF> environment variable. See B<CONFIGURATION FILE
+OPTIONS> for configurable variables. (Optional)
+
+=item B<-section> tsa_section
+
+The name of the config file section conatining the settings for the
+response generation. If not specified the default TSA section is
+used, see B<CONFIGURATION FILE OPTIONS> for details. (Optional)
+
+=item B<-queryfile> request.tsq
+
+The name of the file containing a DER encoded time stamp request. (Optional)
+
+=item B<-passin> password_src
+
+Specifies the password source for the private key of the TSA. See
+B<PASS PHRASE ARGUMENTS> in L<openssl(1)|openssl(1)>. (Optional)
+
+=item B<-signer> tsa_cert.pem
+
+The signer certificate of the TSA in PEM format. The TSA signing
+certificate must have exactly one extended key usage assigned to it:
+timeStamping. The extended key usage must also be critical, otherwise
+the certificate is going to be refused. Overrides the B<signer_cert>
+variable of the config file. (Optional)
+
+=item B<-inkey> private.pem
+
+The signer private key of the TSA in PEM format. Overrides the
+B<signer_key> config file option. (Optional)
+
+=item B<-chain> certs_file.pem
+
+The collection of certificates in PEM format that will all
+be included in the response in addition to the signer certificate if
+the B<-cert> option was used for the request. This file is supposed to
+contain the certificate chain for the signer certificate from its
+issuer upwards. The B<-reply> command does not build a certificate
+chain automatically. (Optional)
+
+=item B<-policy> object_id
+
+The default policy to use for the response unless the client
+explicitly requires a particular TSA policy. The OID can be specified
+either in dotted notation or with its name. Overrides the
+B<default_policy> config file option. (Optional)
+
+=item B<-in> response.tsr
+
+Specifies a previously created time stamp response or time stamp token
+(if B<-token_in> is also specified) in DER format that will be written
+to the output file. This option does not require a request, it is
+useful e.g. when you need to examine the content of a response or
+token or you want to extract the time stamp token from a response. If
+the input is a token and the output is a time stamp response a default
+'granted' status info is added to the token. (Optional)
+
+=item B<-token_in>
+
+This flag can be used together with the B<-in> option and indicates
+that the input is a DER encoded time stamp token (ContentInfo) instead
+of a time stamp response (TimeStampResp). (Optional)
+
+=item B<-out> response.tsr
+
+The response is written to this file. The format and content of the
+file depends on other options (see B<-text>, B<-token_out>). The default is
+stdout. (Optional)
+
+=item B<-token_out>
+
+The output is a time stamp token (ContentInfo) instead of time stamp
+response (TimeStampResp). (Optional)
+
+=item B<-text>
+
+If this option is specified the output is human-readable text format
+instead of DER. (Optional)
+
+=item B<-engine> id
+
+Specifying an engine (by its unique B<id> string) will cause B<ts>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms. Default is builtin. (Optional)
+
+=back
+
+=head2 Time Stamp Response verification
+
+The B<-verify> command is for verifying if a time stamp response or time
+stamp token is valid and matches a particular time stamp request or
+data file. The B<-verify> command does not use the configuration file.
+
+=over 4
+
+=item B<-data> file_to_hash
+
+The response or token must be verified against file_to_hash. The file
+is hashed with the message digest algorithm specified in the token. 
+The B<-digest> and B<-queryfile> options must not be specified with this one.
+(Optional)
+
+=item B<-digest> digest_bytes
+
+The response or token must be verified against the message digest specified
+with this option. The number of bytes must match the message digest algorithm
+specified in the token. The B<-data> and B<-queryfile> options must not be
+specified with this one. (Optional)
+
+=item B<-queryfile> request.tsq
+
+The original time stamp request in DER format. The B<-data> and B<-digest>
+options must not be specified with this one. (Optional)
+
+=item B<-in> response.tsr
+
+The time stamp response that needs to be verified in DER format. (Mandatory)
+
+=item B<-token_in>
+
+This flag can be used together with the B<-in> option and indicates
+that the input is a DER encoded time stamp token (ContentInfo) instead
+of a time stamp response (TimeStampResp). (Optional)
+
+=item B<-CApath> trusted_cert_path
+
+The name of the directory containing the trused CA certificates of the
+client. See the similar option of L<verify(1)|verify(1)> for additional
+details. Either this option or B<-CAfile> must be specified. (Optional)
+
+
+=item B<-CAfile> trusted_certs.pem
+
+The name of the file containing a set of trusted self-signed CA 
+certificates in PEM format. See the similar option of 
+L<verify(1)|verify(1)> for additional details. Either this option 
+or B<-CApath> must be specified.
+(Optional)
+
+=item B<-untrusted> cert_file.pem
+
+Set of additional untrusted certificates in PEM format which may be
+needed when building the certificate chain for the TSA's signing
+certificate. This file must contain the TSA signing certificate and
+all intermediate CA certificates unless the response includes them.
+(Optional)
+
+=back
+
+=head1 CONFIGURATION FILE OPTIONS
+
+The B<-query> and B<-reply> commands make use of a configuration file
+defined by the B<OPENSSL_CONF> environment variable. See L<config(5)|config(5)>
+for a general description of the syntax of the config file. The
+B<-query> command uses only the symbolic OID names section
+and it can work without it. However, the B<-reply> command needs the
+config file for its operation.
+
+When there is a command line switch equivalent of a variable the
+switch always overrides the settings in the config file.
+
+=over 4
+
+=item B<tsa> section, B<default_tsa>	
+
+This is the main section and it specifies the name of another section
+that contains all the options for the B<-reply> command. This default
+section can be overriden with the B<-section> command line switch. (Optional)
+
+=item B<oid_file>
+
+See L<ca(1)|ca(1)> for description. (Optional)
+
+=item B<oid_section>
+
+See L<ca(1)|ca(1)> for description. (Optional)
+
+=item B<RANDFILE>
+
+See L<ca(1)|ca(1)> for description. (Optional)
+
+=item B<serial>
+
+The name of the file containing the hexadecimal serial number of the
+last time stamp response created. This number is incremented by 1 for
+each response. If the file does not exist at the time of response
+generation a new file is created with serial number 1. (Mandatory)
+
+=item B<crypto_device>
+
+Specifies the OpenSSL engine that will be set as the default for 
+all available algorithms. The default value is builtin, you can specify 
+any other engines supported by OpenSSL (e.g. use chil for the NCipher HSM).
+(Optional)
+
+=item B<signer_cert>
+
+TSA signing certificate in PEM format. The same as the B<-signer>
+command line option. (Optional)
+
+=item B<certs>
+
+A file containing a set of PEM encoded certificates that need to be
+included in the response. The same as the B<-chain> command line
+option. (Optional)
+
+=item B<signer_key>
+
+The private key of the TSA in PEM format. The same as the B<-inkey>
+command line option. (Optional)
+
+=item B<default_policy>
+
+The default policy to use when the request does not mandate any
+policy. The same as the B<-policy> command line option. (Optional)
+
+=item B<other_policies>
+
+Comma separated list of policies that are also acceptable by the TSA
+and used only if the request explicitly specifies one of them. (Optional)
+
+=item B<digests>
+
+The list of message digest algorithms that the TSA accepts. At least
+one algorithm must be specified. (Mandatory)
+
+=item B<accuracy>
+
+The accuracy of the time source of the TSA in seconds, milliseconds
+and microseconds. E.g. secs:1, millisecs:500, microsecs:100. If any of
+the components is missing zero is assumed for that field. (Optional)
+
+=item B<clock_precision_digits>
+
+Specifies the maximum number of digits, which represent the fraction of 
+seconds, that  need to be included in the time field. The trailing zeroes
+must be removed from the time, so there might actually be fewer digits,
+or no fraction of seconds at all. Supported only on UNIX platforms.
+The maximum value is 6, default is 0.
+(Optional)
+
+=item B<ordering>
+
+If this option is yes the responses generated by this TSA can always
+be ordered, even if the time difference between two responses is less
+than the sum of their accuracies. Default is no. (Optional)
+
+=item B<tsa_name>
+
+Set this option to yes if the subject name of the TSA must be included in
+the TSA name field of the response. Default is no. (Optional)
+
+=item B<ess_cert_id_chain>
+
+The SignedData objects created by the TSA always contain the
+certificate identifier of the signing certificate in a signed
+attribute (see RFC 2634, Enhanced Security Services). If this option
+is set to yes and either the B<certs> variable or the B<-chain> option
+is specified then the certificate identifiers of the chain will also
+be included in the SigningCertificate signed attribute. If this
+variable is set to no, only the signing certificate identifier is
+included. Default is no. (Optional)
+
+=back
+
+=head1 ENVIRONMENT VARIABLES
+
+B<OPENSSL_CONF> contains the path of the configuration file and can be
+overriden by the B<-config> command line option.
+
+=head1 EXAMPLES
+
+All the examples below presume that B<OPENSSL_CONF> is set to a proper
+configuration file, e.g. the example configuration file 
+openssl/apps/openssl.cnf will do.
+
+=head2 Time Stamp Request
+
+To create a time stamp request for design1.txt with SHA-1 
+without nonce and policy and no certificate is required in the response:
+
+  openssl ts -query -data design1.txt -no_nonce \
+	-out design1.tsq
+
+To create a similar time stamp request with specifying the message imprint
+explicitly:
+
+  openssl ts -query -digest b7e5d3f93198b38379852f2c04e78d73abdd0f4b \
+	 -no_nonce -out design1.tsq
+
+To print the content of the previous request in human readable format:
+
+  openssl ts -query -in design1.tsq -text
+
+To create a time stamp request which includes the MD-5 digest 
+of design2.txt, requests the signer certificate and nonce,
+specifies a policy id (assuming the tsa_policy1 name is defined in the
+OID section of the config file):
+
+  openssl ts -query -data design2.txt -md5 \
+	-policy tsa_policy1 -cert -out design2.tsq
+
+=head2 Time Stamp Response
+
+Before generating a response a signing certificate must be created for
+the TSA that contains the B<timeStamping> critical extended key usage extension
+without any other key usage extensions. You can add the
+'extendedKeyUsage = critical,timeStamping' line to the user certificate section
+of the config file to generate a proper certificate. See L<req(1)|req(1)>,
+L<ca(1)|ca(1)>, L<x509(1)|x509(1)> for instructions. The examples
+below assume that cacert.pem contains the certificate of the CA,
+tsacert.pem is the signing certificate issued by cacert.pem and
+tsakey.pem is the private key of the TSA.
+
+To create a time stamp response for a request:
+
+  openssl ts -reply -queryfile design1.tsq -inkey tsakey.pem \
+	-signer tsacert.pem -out design1.tsr
+
+If you want to use the settings in the config file you could just write:
+
+  openssl ts -reply -queryfile design1.tsq -out design1.tsr
+
+To print a time stamp reply to stdout in human readable format:
+
+  openssl ts -reply -in design1.tsr -text
+
+To create a time stamp token instead of time stamp response:
+
+  openssl ts -reply -queryfile design1.tsq -out design1_token.der -token_out
+
+To print a time stamp token to stdout in human readable format:
+
+  openssl ts -reply -in design1_token.der -token_in -text -token_out
+
+To extract the time stamp token from a response:
+
+  openssl ts -reply -in design1.tsr -out design1_token.der -token_out
+
+To add 'granted' status info to a time stamp token thereby creating a
+valid response:
+
+  openssl ts -reply -in design1_token.der -token_in -out design1.tsr
+
+=head2 Time Stamp Verification
+
+To verify a time stamp reply against a request:
+
+  openssl ts -verify -queryfile design1.tsq -in design1.tsr \
+	-CAfile cacert.pem -untrusted tsacert.pem
+
+To verify a time stamp reply that includes the certificate chain:
+
+  openssl ts -verify -queryfile design2.tsq -in design2.tsr \
+	-CAfile cacert.pem
+
+To verify a time stamp token against the original data file:
+  openssl ts -verify -data design2.txt -in design2.tsr \
+	-CAfile cacert.pem
+
+To verify a time stamp token against a message imprint:
+  openssl ts -verify -digest b7e5d3f93198b38379852f2c04e78d73abdd0f4b \
+	 -in design2.tsr -CAfile cacert.pem
+
+You could also look at the 'test' directory for more examples.
+
+=head1 BUGS
+
+If you find any bugs or you have suggestions please write to
+Zoltan Glozik <zglozik@opentsa.org>. Known issues:
+
+=over 4
+
+=item * No support for time stamps over SMTP, though it is quite easy
+to implement an automatic e-mail based TSA with L<procmail(1)|procmail(1)> 
+and L<perl(1)|perl(1)>. HTTP server support is provided in the form of 
+a separate apache module. HTTP client support is provided by
+L<tsget(1)|tsget(1)>. Pure TCP/IP protocol is not supported.
+
+=item * The file containing the last serial number of the TSA is not
+locked when being read or written. This is a problem if more than one
+instance of L<openssl(1)|openssl(1)> is trying to create a time stamp
+response at the same time. This is not an issue when using the apache
+server module, it does proper locking.
+
+=item * Look for the FIXME word in the source files.
+
+=item * The source code should really be reviewed by somebody else, too.
+
+=item * More testing is needed, I have done only some basic tests (see
+test/testtsa).
+
+=back
+
+=cut
+
+=head1 AUTHOR
+
+Zoltan Glozik <zglozik@opentsa.org>, OpenTSA project (http://www.opentsa.org)
+
+=head1 SEE ALSO
+
+L<tsget(1)|tsget(1)>, L<openssl(1)|openssl(1)>, L<req(1)|req(1)>, 
+L<x509(1)|x509(1)>, L<ca(1)|ca(1)>, L<genrsa(1)|genrsa(1)>, 
+L<config(5)|config(5)>
+
+=cut
diff --git a/openssl/doc/apps/tsget.pod b/openssl/doc/apps/tsget.pod
new file mode 100644
index 0000000..b05957b
--- /dev/null
+++ b/openssl/doc/apps/tsget.pod
@@ -0,0 +1,194 @@
+=pod
+
+=head1 NAME
+
+tsget - Time Stamping HTTP/HTTPS client
+
+=head1 SYNOPSIS
+
+B<tsget>
+B<-h> server_url
+[B<-e> extension]
+[B<-o> output]
+[B<-v>]
+[B<-d>]
+[B<-k> private_key.pem]
+[B<-p> key_password]
+[B<-c> client_cert.pem]
+[B<-C> CA_certs.pem]
+[B<-P> CA_path]
+[B<-r> file:file...]
+[B<-g> EGD_socket]
+[request]...
+
+=head1 DESCRIPTION
+
+The B<tsget> command can be used for sending a time stamp request, as
+specified in B<RFC 3161>, to a time stamp server over HTTP or HTTPS and storing
+the time stamp response in a file. This tool cannot be used for creating the
+requests and verifying responses, you can use the OpenSSL B<ts(1)> command to
+do that. B<tsget> can send several requests to the server without closing
+the TCP connection if more than one requests are specified on the command
+line.
+
+The tool sends the following HTTP request for each time stamp request:
+
+	POST url HTTP/1.1
+	User-Agent: OpenTSA tsget.pl/<version>
+	Host: <host>:<port>
+	Pragma: no-cache
+	Content-Type: application/timestamp-query
+	Accept: application/timestamp-reply
+	Content-Length: length of body
+
+	...binary request specified by the user...
+
+B<tsget> expects a response of type application/timestamp-reply, which is
+written to a file without any interpretation.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-h> server_url
+
+The URL of the HTTP/HTTPS server listening for time stamp requests.
+
+=item B<-e> extension
+
+If the B<-o> option is not given this argument specifies the extension of the
+output files. The base name of the output file will be the same as those of
+the input files. Default extension is '.tsr'. (Optional)
+
+=item B<-o> output
+
+This option can be specified only when just one request is sent to the
+server. The time stamp response will be written to the given output file. '-'
+means standard output. In case of multiple time stamp requests or the absence
+of this argument the names of the output files will be derived from the names
+of the input files and the default or specified extension argument. (Optional)
+
+=item B<-v>
+
+The name of the currently processed request is printed on standard
+error. (Optional)
+
+=item B<-d>
+
+Switches on verbose mode for the underlying B<curl> library. You can see
+detailed debug messages for the connection. (Optional)
+
+=item B<-k> private_key.pem
+
+(HTTPS) In case of certificate-based client authentication over HTTPS
+<private_key.pem> must contain the private key of the user. The private key
+file can optionally be protected by a passphrase. The B<-c> option must also
+be specified. (Optional)
+
+=item B<-p> key_password
+
+(HTTPS) Specifies the passphrase for the private key specified by the B<-k>
+argument. If this option is omitted and the key is passphrase protected B<tsget>
+will ask for it. (Optional)
+
+=item B<-c> client_cert.pem
+
+(HTTPS) In case of certificate-based client authentication over HTTPS
+<client_cert.pem> must contain the X.509 certificate of the user.  The B<-k>
+option must also be specified. If this option is not specified no
+certificate-based client authentication will take place. (Optional)
+
+=item B<-C> CA_certs.pem
+
+(HTTPS) The trusted CA certificate store. The certificate chain of the peer's
+certificate must include one of the CA certificates specified in this file.
+Either option B<-C> or option B<-P> must be given in case of HTTPS. (Optional)
+
+=item B<-P> CA_path
+
+(HTTPS) The path containing the trusted CA certificates to verify the peer's
+certificate. The directory must be prepared with the B<c_rehash>
+OpenSSL utility. Either option B<-C> or option B<-P> must be given in case of
+HTTPS. (Optional)
+
+=item B<-rand> file:file...
+
+The files containing random data for seeding the random number
+generator. Multiple files can be specified, the separator is B<;> for
+MS-Windows, B<,> for VMS and B<:> for all other platforms. (Optional)
+
+=item B<-g> EGD_socket
+
+The name of an EGD socket to get random data from. (Optional)
+
+=item [request]...
+
+List of files containing B<RFC 3161> DER-encoded time stamp requests. If no
+requests are specifed only one request will be sent to the server and it will be
+read from the standard input. (Optional)
+
+=back
+
+=head1 ENVIRONMENT VARIABLES
+
+The B<TSGET> environment variable can optionally contain default
+arguments. The content of this variable is added to the list of command line
+arguments.
+
+=head1 EXAMPLES
+
+The examples below presume that B<file1.tsq> and B<file2.tsq> contain valid
+time stamp requests, tsa.opentsa.org listens at port 8080 for HTTP requests
+and at port 8443 for HTTPS requests, the TSA service is available at the /tsa
+absolute path.
+
+Get a time stamp response for file1.tsq over HTTP, output is written to 
+file1.tsr:
+
+  tsget -h http://tsa.opentsa.org:8080/tsa file1.tsq
+
+Get a time stamp response for file1.tsq and file2.tsq over HTTP showing
+progress, output is written to file1.reply and file2.reply respectively:
+
+  tsget -h http://tsa.opentsa.org:8080/tsa -v -e .reply \
+	file1.tsq file2.tsq
+
+Create a time stamp request, write it to file3.tsq, send it to the server and
+write the response to file3.tsr:
+
+  openssl ts -query -data file3.txt -cert | tee file3.tsq \
+	| tsget -h http://tsa.opentsa.org:8080/tsa \
+	-o file3.tsr
+
+Get a time stamp response for file1.tsq over HTTPS without client
+authentication:
+
+  tsget -h https://tsa.opentsa.org:8443/tsa \
+	-C cacerts.pem file1.tsq
+
+Get a time stamp response for file1.tsq over HTTPS with certificate-based
+client authentication (it will ask for the passphrase if client_key.pem is
+protected):
+
+  tsget -h https://tsa.opentsa.org:8443/tsa -C cacerts.pem \
+	-k client_key.pem -c client_cert.pem file1.tsq
+
+You can shorten the previous command line if you make use of the B<TSGET>
+environment variable. The following commands do the same as the previous
+example:
+
+  TSGET='-h https://tsa.opentsa.org:8443/tsa -C cacerts.pem \
+	-k client_key.pem -c client_cert.pem'
+  export TSGET
+  tsget file1.tsq
+
+=head1 AUTHOR
+
+Zoltan Glozik <zglozik@opentsa.org>, OpenTSA project (http://www.opentsa.org)
+
+=head1 SEE ALSO
+
+L<openssl(1)|openssl(1)>, L<ts(1)|ts(1)>, L<curl(1)|curl(1)>, 
+B<RFC 3161>
+
+=cut
diff --git a/openssl/doc/apps/verify.pod b/openssl/doc/apps/verify.pod
new file mode 100644
index 0000000..336098f
--- /dev/null
+++ b/openssl/doc/apps/verify.pod
@@ -0,0 +1,406 @@
+=pod
+
+=head1 NAME
+
+verify - Utility to verify certificates.
+
+=head1 SYNOPSIS
+
+B<openssl> B<verify>
+[B<-CApath directory>]
+[B<-CAfile file>]
+[B<-purpose purpose>]
+[B<-policy arg>]
+[B<-ignore_critical>]
+[B<-crl_check>]
+[B<-crl_check_all>]
+[B<-policy_check>]
+[B<-explicit_policy>]
+[B<-inhibit_any>]
+[B<-inhibit_map>]
+[B<-x509_strict>]
+[B<-extended_crl>]
+[B<-use_deltas>]
+[B<-policy_print>]
+[B<-untrusted file>]
+[B<-help>]
+[B<-issuer_checks>]
+[B<-verbose>]
+[B<->]
+[certificates]
+
+
+=head1 DESCRIPTION
+
+The B<verify> command verifies certificate chains.
+
+=head1 COMMAND OPTIONS
+
+=over 4
+
+=item B<-CApath directory>
+
+A directory of trusted certificates. The certificates should have names
+of the form: hash.0 or have symbolic links to them of this
+form ("hash" is the hashed certificate subject name: see the B<-hash> option
+of the B<x509> utility). Under Unix the B<c_rehash> script will automatically
+create symbolic links to a directory of certificates.
+
+=item B<-CAfile file>
+
+A file of trusted certificates. The file should contain multiple certificates
+in PEM format concatenated together.
+
+=item B<-untrusted file>
+
+A file of untrusted certificates. The file should contain multiple certificates
+
+=item B<-purpose purpose>
+
+the intended use for the certificate. Without this option no chain verification
+will be done. Currently accepted uses are B<sslclient>, B<sslserver>,
+B<nssslserver>, B<smimesign>, B<smimeencrypt>. See the B<VERIFY OPERATION>
+section for more information.
+
+=item B<-help>
+
+prints out a usage message.
+
+=item B<-verbose>
+
+print extra information about the operations being performed.
+
+=item B<-issuer_checks>
+
+print out diagnostics relating to searches for the issuer certificate
+of the current certificate. This shows why each candidate issuer
+certificate was rejected. However the presence of rejection messages
+does not itself imply that anything is wrong: during the normal
+verify process several rejections may take place.
+
+=item B<-policy arg>
+
+Enable policy processing and add B<arg> to the user-initial-policy-set
+(see RFC3280 et al). The policy B<arg> can be an object name an OID in numeric
+form. This argument can appear more than once.
+
+=item B<-policy_check>
+
+Enables certificate policy processing.
+
+=item B<-explicit_policy>
+
+Set policy variable require-explicit-policy (see RFC3280 et al).
+
+=item B<-inhibit_any>
+
+Set policy variable inhibit-any-policy (see RFC3280 et al).
+
+=item B<-inhibit_map>
+
+Set policy variable inhibit-policy-mapping (see RFC3280 et al).
+
+=item B<-policy_print>
+
+Print out diagnostics, related to policy checking
+
+=item B<-crl_check>
+
+Checks end entity certificate validity by attempting to lookup a valid CRL.
+If a valid CRL cannot be found an error occurs. 
+
+=item B<-crl_check_all>
+
+Checks the validity of B<all> certificates in the chain by attempting
+to lookup valid CRLs.
+
+=item B<-ignore_critical>
+
+Normally if an unhandled critical extension is present which is not
+supported by OpenSSL the certificate is rejected (as required by
+RFC3280 et al). If this option is set critical extensions are
+ignored.
+
+=item B<-x509_strict>
+
+Disable workarounds for broken certificates which have to be disabled
+for strict X.509 compliance.
+
+=item B<-extended_crl>
+
+Enable extended CRL features such as indirect CRLs and alternate CRL
+signing keys.
+
+=item B<-use_deltas>
+
+Enable support for delta CRLs.
+
+=item B<-check_ss_sig>
+
+Verify the signature on the self-signed root CA. This is disabled by default
+because it doesn't add any security.
+
+=item B<->
+
+marks the last option. All arguments following this are assumed to be
+certificate files. This is useful if the first certificate filename begins
+with a B<->.
+
+=item B<certificates>
+
+one or more certificates to verify. If no certificate filenames are included
+then an attempt is made to read a certificate from standard input. They should
+all be in PEM format.
+
+
+=back
+
+=head1 VERIFY OPERATION
+
+The B<verify> program uses the same functions as the internal SSL and S/MIME
+verification, therefore this description applies to these verify operations
+too.
+
+There is one crucial difference between the verify operations performed
+by the B<verify> program: wherever possible an attempt is made to continue
+after an error whereas normally the verify operation would halt on the
+first error. This allows all the problems with a certificate chain to be
+determined.
+
+The verify operation consists of a number of separate steps.
+
+Firstly a certificate chain is built up starting from the supplied certificate
+and ending in the root CA. It is an error if the whole chain cannot be built
+up. The chain is built up by looking up the issuers certificate of the current
+certificate. If a certificate is found which is its own issuer it is assumed 
+to be the root CA.
+
+The process of 'looking up the issuers certificate' itself involves a number
+of steps. In versions of OpenSSL before 0.9.5a the first certificate whose
+subject name matched the issuer of the current certificate was assumed to be
+the issuers certificate. In OpenSSL 0.9.6 and later all certificates
+whose subject name matches the issuer name of the current certificate are 
+subject to further tests. The relevant authority key identifier components
+of the current certificate (if present) must match the subject key identifier
+(if present) and issuer and serial number of the candidate issuer, in addition
+the keyUsage extension of the candidate issuer (if present) must permit
+certificate signing.
+
+The lookup first looks in the list of untrusted certificates and if no match
+is found the remaining lookups are from the trusted certificates. The root CA
+is always looked up in the trusted certificate list: if the certificate to
+verify is a root certificate then an exact match must be found in the trusted
+list.
+
+The second operation is to check every untrusted certificate's extensions for
+consistency with the supplied purpose. If the B<-purpose> option is not included
+then no checks are done. The supplied or "leaf" certificate must have extensions
+compatible with the supplied purpose and all other certificates must also be valid
+CA certificates. The precise extensions required are described in more detail in
+the B<CERTIFICATE EXTENSIONS> section of the B<x509> utility.
+
+The third operation is to check the trust settings on the root CA. The root
+CA should be trusted for the supplied purpose. For compatibility with previous
+versions of SSLeay and OpenSSL a certificate with no trust settings is considered
+to be valid for all purposes. 
+
+The final operation is to check the validity of the certificate chain. The validity
+period is checked against the current system time and the notBefore and notAfter
+dates in the certificate. The certificate signatures are also checked at this
+point.
+
+If all operations complete successfully then certificate is considered valid. If
+any operation fails then the certificate is not valid.
+
+=head1 DIAGNOSTICS
+
+When a verify operation fails the output messages can be somewhat cryptic. The
+general form of the error message is:
+
+ server.pem: /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit)
+ error 24 at 1 depth lookup:invalid CA certificate
+
+The first line contains the name of the certificate being verified followed by
+the subject name of the certificate. The second line contains the error number
+and the depth. The depth is number of the certificate being verified when a
+problem was detected starting with zero for the certificate being verified itself
+then 1 for the CA that signed the certificate and so on. Finally a text version
+of the error number is presented.
+
+An exhaustive list of the error codes and messages is shown below, this also
+includes the name of the error code as defined in the header file x509_vfy.h
+Some of the error codes are defined but never returned: these are described
+as "unused".
+
+=over 4
+
+=item B<0 X509_V_OK: ok>
+
+the operation was successful.
+
+=item B<2 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: unable to get issuer certificate>
+
+the issuer certificate of a looked up certificate could not be found. This
+normally means the list of trusted certificates is not complete.
+
+=item B<3 X509_V_ERR_UNABLE_TO_GET_CRL: unable to get certificate CRL>
+
+the CRL of a certificate could not be found.
+
+=item B<4 X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: unable to decrypt certificate's signature>
+
+the certificate signature could not be decrypted. This means that the actual signature value
+could not be determined rather than it not matching the expected value, this is only
+meaningful for RSA keys.
+
+=item B<5 X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: unable to decrypt CRL's signature>
+
+the CRL signature could not be decrypted: this means that the actual signature value
+could not be determined rather than it not matching the expected value. Unused.
+
+=item B<6 X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: unable to decode issuer public key>
+
+the public key in the certificate SubjectPublicKeyInfo could not be read.
+
+=item B<7 X509_V_ERR_CERT_SIGNATURE_FAILURE: certificate signature failure>
+
+the signature of the certificate is invalid.
+
+=item B<8 X509_V_ERR_CRL_SIGNATURE_FAILURE: CRL signature failure>
+
+the signature of the certificate is invalid.
+
+=item B<9 X509_V_ERR_CERT_NOT_YET_VALID: certificate is not yet valid>
+
+the certificate is not yet valid: the notBefore date is after the current time.
+
+=item B<10 X509_V_ERR_CERT_HAS_EXPIRED: certificate has expired>
+
+the certificate has expired: that is the notAfter date is before the current time.
+
+=item B<11 X509_V_ERR_CRL_NOT_YET_VALID: CRL is not yet valid>
+
+the CRL is not yet valid.
+
+=item B<12 X509_V_ERR_CRL_HAS_EXPIRED: CRL has expired>
+
+the CRL has expired.
+
+=item B<13 X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: format error in certificate's notBefore field>
+
+the certificate notBefore field contains an invalid time.
+
+=item B<14 X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: format error in certificate's notAfter field>
+
+the certificate notAfter field contains an invalid time.
+
+=item B<15 X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: format error in CRL's lastUpdate field>
+
+the CRL lastUpdate field contains an invalid time.
+
+=item B<16 X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: format error in CRL's nextUpdate field>
+
+the CRL nextUpdate field contains an invalid time.
+
+=item B<17 X509_V_ERR_OUT_OF_MEM: out of memory>
+
+an error occurred trying to allocate memory. This should never happen.
+
+=item B<18 X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: self signed certificate>
+
+the passed certificate is self signed and the same certificate cannot be found in the list of
+trusted certificates.
+
+=item B<19 X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: self signed certificate in certificate chain>
+
+the certificate chain could be built up using the untrusted certificates but the root could not
+be found locally.
+
+=item B<20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate>
+
+the issuer certificate could not be found: this occurs if the issuer
+certificate of an untrusted certificate cannot be found.
+
+=item B<21 X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: unable to verify the first certificate>
+
+no signatures could be verified because the chain contains only one certificate and it is not
+self signed.
+
+=item B<22 X509_V_ERR_CERT_CHAIN_TOO_LONG: certificate chain too long>
+
+the certificate chain length is greater than the supplied maximum depth. Unused.
+
+=item B<23 X509_V_ERR_CERT_REVOKED: certificate revoked>
+
+the certificate has been revoked.
+
+=item B<24 X509_V_ERR_INVALID_CA: invalid CA certificate>
+
+a CA certificate is invalid. Either it is not a CA or its extensions are not consistent
+with the supplied purpose.
+
+=item B<25 X509_V_ERR_PATH_LENGTH_EXCEEDED: path length constraint exceeded>
+
+the basicConstraints pathlength parameter has been exceeded.
+
+=item B<26 X509_V_ERR_INVALID_PURPOSE: unsupported certificate purpose>
+
+the supplied certificate cannot be used for the specified purpose.
+
+=item B<27 X509_V_ERR_CERT_UNTRUSTED: certificate not trusted>
+
+the root CA is not marked as trusted for the specified purpose.
+
+=item B<28 X509_V_ERR_CERT_REJECTED: certificate rejected>
+
+the root CA is marked to reject the specified purpose.
+
+=item B<29 X509_V_ERR_SUBJECT_ISSUER_MISMATCH: subject issuer mismatch>
+
+the current candidate issuer certificate was rejected because its subject name
+did not match the issuer name of the current certificate. Only displayed when
+the B<-issuer_checks> option is set.
+
+=item B<30 X509_V_ERR_AKID_SKID_MISMATCH: authority and subject key identifier mismatch>
+
+the current candidate issuer certificate was rejected because its subject key
+identifier was present and did not match the authority key identifier current
+certificate. Only displayed when the B<-issuer_checks> option is set.
+
+=item B<31 X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: authority and issuer serial number mismatch>
+
+the current candidate issuer certificate was rejected because its issuer name
+and serial number was present and did not match the authority key identifier
+of the current certificate. Only displayed when the B<-issuer_checks> option is set.
+
+=item B<32 X509_V_ERR_KEYUSAGE_NO_CERTSIGN:key usage does not include certificate signing>
+
+the current candidate issuer certificate was rejected because its keyUsage extension
+does not permit certificate signing.
+
+=item B<50 X509_V_ERR_APPLICATION_VERIFICATION: application verification failure>
+
+an application specific error. Unused.
+
+=back
+
+=head1 BUGS
+
+Although the issuer checks are a considerably improvement over the old technique they still
+suffer from limitations in the underlying X509_LOOKUP API. One consequence of this is that
+trusted certificates with matching subject name must either appear in a file (as specified by the
+B<-CAfile> option) or a directory (as specified by B<-CApath>. If they occur in both then only
+the certificates in the file will be recognised.
+
+Previous versions of OpenSSL assume certificates with matching subject name are identical and
+mishandled them.
+
+Previous versions of this documentation swapped the meaning of the
+B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT> and
+B<20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY> error codes.
+
+=head1 SEE ALSO
+
+L<x509(1)|x509(1)>
+
+=cut
diff --git a/openssl/doc/apps/version.pod b/openssl/doc/apps/version.pod
new file mode 100644
index 0000000..e00324c
--- /dev/null
+++ b/openssl/doc/apps/version.pod
@@ -0,0 +1,64 @@
+=pod
+
+=head1 NAME
+
+version - print OpenSSL version information
+
+=head1 SYNOPSIS
+
+B<openssl version>
+[B<-a>]
+[B<-v>]
+[B<-b>]
+[B<-o>]
+[B<-f>]
+[B<-p>]
+
+=head1 DESCRIPTION
+
+This command is used to print out version information about OpenSSL.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-a>
+
+all information, this is the same as setting all the other flags.
+
+=item B<-v>
+
+the current OpenSSL version.
+
+=item B<-b>
+
+the date the current version of OpenSSL was built.
+
+=item B<-o>
+
+option information: various options set when the library was built.
+
+=item B<-c>
+
+compilation flags.
+
+=item B<-p>
+
+platform setting.
+
+=item B<-d>
+
+OPENSSLDIR setting.
+
+=back
+
+=head1 NOTES
+
+The output of B<openssl version -a> would typically be used when sending
+in a bug report.
+
+=head1 HISTORY
+
+The B<-d> option was added in OpenSSL 0.9.7.
+
+=cut
diff --git a/openssl/doc/apps/x509.pod b/openssl/doc/apps/x509.pod
new file mode 100644
index 0000000..3002b08
--- /dev/null
+++ b/openssl/doc/apps/x509.pod
@@ -0,0 +1,856 @@
+
+=pod
+
+=head1 NAME
+
+x509 - Certificate display and signing utility
+
+=head1 SYNOPSIS
+
+B<openssl> B<x509>
+[B<-inform DER|PEM|NET>]
+[B<-outform DER|PEM|NET>]
+[B<-keyform DER|PEM>]
+[B<-CAform DER|PEM>]
+[B<-CAkeyform DER|PEM>]
+[B<-in filename>]
+[B<-out filename>]
+[B<-serial>]
+[B<-hash>]
+[B<-subject_hash>]
+[B<-issuer_hash>]
+[B<-subject>]
+[B<-issuer>]
+[B<-nameopt option>]
+[B<-email>]
+[B<-ocsp_uri>]
+[B<-startdate>]
+[B<-enddate>]
+[B<-purpose>]
+[B<-dates>]
+[B<-modulus>]
+[B<-fingerprint>]
+[B<-alias>]
+[B<-noout>]
+[B<-trustout>]
+[B<-clrtrust>]
+[B<-clrreject>]
+[B<-addtrust arg>]
+[B<-addreject arg>]
+[B<-setalias arg>]
+[B<-days arg>]
+[B<-set_serial n>]
+[B<-signkey filename>]
+[B<-x509toreq>]
+[B<-req>]
+[B<-CA filename>]
+[B<-CAkey filename>]
+[B<-CAcreateserial>]
+[B<-CAserial filename>]
+[B<-text>]
+[B<-C>]
+[B<-md2|-md5|-sha1|-mdc2>]
+[B<-clrext>]
+[B<-extfile filename>]
+[B<-extensions section>]
+[B<-engine id>]
+
+=head1 DESCRIPTION
+
+The B<x509> command is a multi purpose certificate utility. It can be
+used to display certificate information, convert certificates to
+various forms, sign certificate requests like a "mini CA" or edit
+certificate trust settings.
+
+Since there are a large number of options they will split up into
+various sections.
+
+=head1 OPTIONS
+
+=head2 INPUT, OUTPUT AND GENERAL PURPOSE OPTIONS
+
+=over 4
+
+=item B<-inform DER|PEM|NET>
+
+This specifies the input format normally the command will expect an X509
+certificate but this can change if other options such as B<-req> are
+present. The DER format is the DER encoding of the certificate and PEM
+is the base64 encoding of the DER encoding with header and footer lines
+added. The NET option is an obscure Netscape server format that is now
+obsolete.
+
+=item B<-outform DER|PEM|NET>
+
+This specifies the output format, the options have the same meaning as the 
+B<-inform> option.
+
+=item B<-in filename>
+
+This specifies the input filename to read a certificate from or standard input
+if this option is not specified.
+
+=item B<-out filename>
+
+This specifies the output filename to write to or standard output by
+default.
+
+=item B<-md2|-md5|-sha1|-mdc2>
+
+the digest to use. This affects any signing or display option that uses a message
+digest, such as the B<-fingerprint>, B<-signkey> and B<-CA> options. If not
+specified then SHA1 is used. If the key being used to sign with is a DSA key
+then this option has no effect: SHA1 is always used with DSA keys.
+
+=item B<-engine id>
+
+specifying an engine (by its unique B<id> string) will cause B<x509>
+to attempt to obtain a functional reference to the specified engine,
+thus initialising it if needed. The engine will then be set as the default
+for all available algorithms.
+
+=back
+
+=head2 DISPLAY OPTIONS
+
+Note: the B<-alias> and B<-purpose> options are also display options
+but are described in the B<TRUST SETTINGS> section.
+
+=over 4
+
+=item B<-text>
+
+prints out the certificate in text form. Full details are output including the
+public key, signature algorithms, issuer and subject names, serial number
+any extensions present and any trust settings.
+
+=item B<-certopt option>
+
+customise the output format used with B<-text>. The B<option> argument can be
+a single option or multiple options separated by commas. The B<-certopt> switch
+may be also be used more than once to set multiple options. See the B<TEXT OPTIONS>
+section for more information.
+
+=item B<-noout>
+
+this option prevents output of the encoded version of the request.
+
+=item B<-modulus>
+
+this option prints out the value of the modulus of the public key
+contained in the certificate.
+
+=item B<-serial>
+
+outputs the certificate serial number.
+
+=item B<-subject_hash>
+
+outputs the "hash" of the certificate subject name. This is used in OpenSSL to
+form an index to allow certificates in a directory to be looked up by subject
+name.
+
+=item B<-issuer_hash>
+
+outputs the "hash" of the certificate issuer name.
+
+=item B<-hash>
+
+synonym for "-subject_hash" for backward compatibility reasons.
+
+=item B<-subject_hash_old>
+
+outputs the "hash" of the certificate subject name using the older algorithm
+as used by OpenSSL versions before 1.0.0.
+
+=item B<-issuer_hash_old>
+
+outputs the "hash" of the certificate issuer name using the older algorithm
+as used by OpenSSL versions before 1.0.0.
+
+=item B<-subject>
+
+outputs the subject name.
+
+=item B<-issuer>
+
+outputs the issuer name.
+
+=item B<-nameopt option>
+
+option which determines how the subject or issuer names are displayed. The
+B<option> argument can be a single option or multiple options separated by
+commas.  Alternatively the B<-nameopt> switch may be used more than once to
+set multiple options. See the B<NAME OPTIONS> section for more information.
+
+=item B<-email>
+
+outputs the email address(es) if any.
+
+=item B<-ocsp_uri>
+
+outputs the OCSP responder address(es) if any.
+
+=item B<-startdate>
+
+prints out the start date of the certificate, that is the notBefore date.
+
+=item B<-enddate>
+
+prints out the expiry date of the certificate, that is the notAfter date.
+
+=item B<-dates>
+
+prints out the start and expiry dates of a certificate.
+
+=item B<-fingerprint>
+
+prints out the digest of the DER encoded version of the whole certificate
+(see digest options).
+
+=item B<-C>
+
+this outputs the certificate in the form of a C source file.
+
+=back
+
+=head2 TRUST SETTINGS
+
+Please note these options are currently experimental and may well change.
+
+A B<trusted certificate> is an ordinary certificate which has several
+additional pieces of information attached to it such as the permitted
+and prohibited uses of the certificate and an "alias".
+
+Normally when a certificate is being verified at least one certificate
+must be "trusted". By default a trusted certificate must be stored
+locally and must be a root CA: any certificate chain ending in this CA
+is then usable for any purpose.
+
+Trust settings currently are only used with a root CA. They allow a finer
+control over the purposes the root CA can be used for. For example a CA
+may be trusted for SSL client but not SSL server use.
+
+See the description of the B<verify> utility for more information on the
+meaning of trust settings.
+
+Future versions of OpenSSL will recognize trust settings on any
+certificate: not just root CAs.
+
+
+=over 4
+
+=item B<-trustout>
+
+this causes B<x509> to output a B<trusted> certificate. An ordinary
+or trusted certificate can be input but by default an ordinary
+certificate is output and any trust settings are discarded. With the
+B<-trustout> option a trusted certificate is output. A trusted
+certificate is automatically output if any trust settings are modified.
+
+=item B<-setalias arg>
+
+sets the alias of the certificate. This will allow the certificate
+to be referred to using a nickname for example "Steve's Certificate".
+
+=item B<-alias>
+
+outputs the certificate alias, if any.
+
+=item B<-clrtrust>
+
+clears all the permitted or trusted uses of the certificate.
+
+=item B<-clrreject>
+
+clears all the prohibited or rejected uses of the certificate.
+
+=item B<-addtrust arg>
+
+adds a trusted certificate use. Any object name can be used here
+but currently only B<clientAuth> (SSL client use), B<serverAuth>
+(SSL server use) and B<emailProtection> (S/MIME email) are used.
+Other OpenSSL applications may define additional uses.
+
+=item B<-addreject arg>
+
+adds a prohibited use. It accepts the same values as the B<-addtrust>
+option.
+
+=item B<-purpose>
+
+this option performs tests on the certificate extensions and outputs
+the results. For a more complete description see the B<CERTIFICATE
+EXTENSIONS> section.
+
+=back
+
+=head2 SIGNING OPTIONS
+
+The B<x509> utility can be used to sign certificates and requests: it
+can thus behave like a "mini CA".
+
+=over 4
+
+=item B<-signkey filename>
+
+this option causes the input file to be self signed using the supplied
+private key. 
+
+If the input file is a certificate it sets the issuer name to the
+subject name (i.e.  makes it self signed) changes the public key to the
+supplied value and changes the start and end dates. The start date is
+set to the current time and the end date is set to a value determined
+by the B<-days> option. Any certificate extensions are retained unless
+the B<-clrext> option is supplied.
+
+If the input is a certificate request then a self signed certificate
+is created using the supplied private key using the subject name in
+the request.
+
+=item B<-clrext>
+
+delete any extensions from a certificate. This option is used when a
+certificate is being created from another certificate (for example with
+the B<-signkey> or the B<-CA> options). Normally all extensions are
+retained.
+
+=item B<-keyform PEM|DER>
+
+specifies the format (DER or PEM) of the private key file used in the
+B<-signkey> option.
+
+=item B<-days arg>
+
+specifies the number of days to make a certificate valid for. The default
+is 30 days.
+
+=item B<-x509toreq>
+
+converts a certificate into a certificate request. The B<-signkey> option
+is used to pass the required private key.
+
+=item B<-req>
+
+by default a certificate is expected on input. With this option a
+certificate request is expected instead.
+
+=item B<-set_serial n>
+
+specifies the serial number to use. This option can be used with either
+the B<-signkey> or B<-CA> options. If used in conjunction with the B<-CA>
+option the serial number file (as specified by the B<-CAserial> or
+B<-CAcreateserial> options) is not used.
+
+The serial number can be decimal or hex (if preceded by B<0x>). Negative
+serial numbers can also be specified but their use is not recommended.
+
+=item B<-CA filename>
+
+specifies the CA certificate to be used for signing. When this option is
+present B<x509> behaves like a "mini CA". The input file is signed by this
+CA using this option: that is its issuer name is set to the subject name
+of the CA and it is digitally signed using the CAs private key.
+
+This option is normally combined with the B<-req> option. Without the
+B<-req> option the input is a certificate which must be self signed.
+
+=item B<-CAkey filename>
+
+sets the CA private key to sign a certificate with. If this option is
+not specified then it is assumed that the CA private key is present in
+the CA certificate file.
+
+=item B<-CAserial filename>
+
+sets the CA serial number file to use.
+
+When the B<-CA> option is used to sign a certificate it uses a serial
+number specified in a file. This file consist of one line containing
+an even number of hex digits with the serial number to use. After each
+use the serial number is incremented and written out to the file again.
+
+The default filename consists of the CA certificate file base name with
+".srl" appended. For example if the CA certificate file is called 
+"mycacert.pem" it expects to find a serial number file called "mycacert.srl".
+
+=item B<-CAcreateserial>
+
+with this option the CA serial number file is created if it does not exist:
+it will contain the serial number "02" and the certificate being signed will
+have the 1 as its serial number. Normally if the B<-CA> option is specified
+and the serial number file does not exist it is an error.
+
+=item B<-extfile filename>
+
+file containing certificate extensions to use. If not specified then
+no extensions are added to the certificate.
+
+=item B<-extensions section>
+
+the section to add certificate extensions from. If this option is not
+specified then the extensions should either be contained in the unnamed
+(default) section or the default section should contain a variable called
+"extensions" which contains the section to use. See the
+L<x509v3_config(5)|x509v3_config(5)> manual page for details of the
+extension section format.
+
+=back
+
+=head2 NAME OPTIONS
+
+The B<nameopt> command line switch determines how the subject and issuer
+names are displayed. If no B<nameopt> switch is present the default "oneline"
+format is used which is compatible with previous versions of OpenSSL.
+Each option is described in detail below, all options can be preceded by
+a B<-> to turn the option off. Only the first four will normally be used.
+
+=over 4
+
+=item B<compat>
+
+use the old format. This is equivalent to specifying no name options at all.
+
+=item B<RFC2253>
+
+displays names compatible with RFC2253 equivalent to B<esc_2253>, B<esc_ctrl>,
+B<esc_msb>, B<utf8>, B<dump_nostr>, B<dump_unknown>, B<dump_der>,
+B<sep_comma_plus>, B<dn_rev> and B<sname>.
+
+=item B<oneline>
+
+a oneline format which is more readable than RFC2253. It is equivalent to
+specifying the  B<esc_2253>, B<esc_ctrl>, B<esc_msb>, B<utf8>, B<dump_nostr>,
+B<dump_der>, B<use_quote>, B<sep_comma_plus_space>, B<space_eq> and B<sname>
+options.
+
+=item B<multiline>
+
+a multiline format. It is equivalent B<esc_ctrl>, B<esc_msb>, B<sep_multiline>,
+B<space_eq>, B<lname> and B<align>.
+
+=item B<esc_2253>
+
+escape the "special" characters required by RFC2253 in a field That is
+B<,+"E<lt>E<gt>;>. Additionally B<#> is escaped at the beginning of a string
+and a space character at the beginning or end of a string.
+
+=item B<esc_ctrl>
+
+escape control characters. That is those with ASCII values less than
+0x20 (space) and the delete (0x7f) character. They are escaped using the
+RFC2253 \XX notation (where XX are two hex digits representing the
+character value).
+
+=item B<esc_msb>
+
+escape characters with the MSB set, that is with ASCII values larger than
+127.
+
+=item B<use_quote>
+
+escapes some characters by surrounding the whole string with B<"> characters,
+without the option all escaping is done with the B<\> character.
+
+=item B<utf8>
+
+convert all strings to UTF8 format first. This is required by RFC2253. If
+you are lucky enough to have a UTF8 compatible terminal then the use
+of this option (and B<not> setting B<esc_msb>) may result in the correct
+display of multibyte (international) characters. Is this option is not
+present then multibyte characters larger than 0xff will be represented
+using the format \UXXXX for 16 bits and \WXXXXXXXX for 32 bits.
+Also if this option is off any UTF8Strings will be converted to their
+character form first.
+
+=item B<no_type>
+
+this option does not attempt to interpret multibyte characters in any
+way. That is their content octets are merely dumped as though one octet
+represents each character. This is useful for diagnostic purposes but
+will result in rather odd looking output.
+
+=item B<show_type>
+
+show the type of the ASN1 character string. The type precedes the
+field contents. For example "BMPSTRING: Hello World".
+
+=item B<dump_der>
+
+when this option is set any fields that need to be hexdumped will
+be dumped using the DER encoding of the field. Otherwise just the
+content octets will be displayed. Both options use the RFC2253
+B<#XXXX...> format.
+
+=item B<dump_nostr>
+
+dump non character string types (for example OCTET STRING) if this
+option is not set then non character string types will be displayed
+as though each content octet represents a single character.
+
+=item B<dump_all>
+
+dump all fields. This option when used with B<dump_der> allows the
+DER encoding of the structure to be unambiguously determined.
+
+=item B<dump_unknown>
+
+dump any field whose OID is not recognised by OpenSSL.
+
+=item B<sep_comma_plus>, B<sep_comma_plus_space>, B<sep_semi_plus_space>,
+B<sep_multiline>
+
+these options determine the field separators. The first character is
+between RDNs and the second between multiple AVAs (multiple AVAs are
+very rare and their use is discouraged). The options ending in
+"space" additionally place a space after the separator to make it
+more readable. The B<sep_multiline> uses a linefeed character for
+the RDN separator and a spaced B<+> for the AVA separator. It also
+indents the fields by four characters.
+
+=item B<dn_rev>
+
+reverse the fields of the DN. This is required by RFC2253. As a side
+effect this also reverses the order of multiple AVAs but this is
+permissible.
+
+=item B<nofname>, B<sname>, B<lname>, B<oid>
+
+these options alter how the field name is displayed. B<nofname> does
+not display the field at all. B<sname> uses the "short name" form
+(CN for commonName for example). B<lname> uses the long form.
+B<oid> represents the OID in numerical form and is useful for
+diagnostic purpose.
+
+=item B<align>
+
+align field values for a more readable output. Only usable with
+B<sep_multiline>.
+
+=item B<space_eq>
+
+places spaces round the B<=> character which follows the field
+name.
+
+=back
+
+=head2 TEXT OPTIONS
+
+As well as customising the name output format, it is also possible to
+customise the actual fields printed using the B<certopt> options when
+the B<text> option is present. The default behaviour is to print all fields.
+
+=over 4
+
+=item B<compatible>
+
+use the old format. This is equivalent to specifying no output options at all.
+
+=item B<no_header>
+
+don't print header information: that is the lines saying "Certificate" and "Data".
+
+=item B<no_version>
+
+don't print out the version number.
+
+=item B<no_serial>
+
+don't print out the serial number.
+
+=item B<no_signame>
+
+don't print out the signature algorithm used.
+
+=item B<no_validity>
+
+don't print the validity, that is the B<notBefore> and B<notAfter> fields.
+
+=item B<no_subject>
+
+don't print out the subject name.
+
+=item B<no_issuer>
+
+don't print out the issuer name.
+
+=item B<no_pubkey>
+
+don't print out the public key.
+
+=item B<no_sigdump>
+
+don't give a hexadecimal dump of the certificate signature.
+
+=item B<no_aux>
+
+don't print out certificate trust information.
+
+=item B<no_extensions>
+
+don't print out any X509V3 extensions.
+
+=item B<ext_default>
+
+retain default extension behaviour: attempt to print out unsupported certificate extensions.
+
+=item B<ext_error>
+
+print an error message for unsupported certificate extensions.
+
+=item B<ext_parse>
+
+ASN1 parse unsupported extensions.
+
+=item B<ext_dump>
+
+hex dump unsupported extensions.
+
+=item B<ca_default>
+
+the value used by the B<ca> utility, equivalent to B<no_issuer>, B<no_pubkey>, B<no_header>,
+B<no_version>, B<no_sigdump> and B<no_signame>.
+
+=back
+
+=head1 EXAMPLES
+
+Note: in these examples the '\' means the example should be all on one
+line.
+
+Display the contents of a certificate:
+
+ openssl x509 -in cert.pem -noout -text
+
+Display the certificate serial number:
+
+ openssl x509 -in cert.pem -noout -serial
+
+Display the certificate subject name:
+
+ openssl x509 -in cert.pem -noout -subject
+
+Display the certificate subject name in RFC2253 form:
+
+ openssl x509 -in cert.pem -noout -subject -nameopt RFC2253
+
+Display the certificate subject name in oneline form on a terminal
+supporting UTF8:
+
+ openssl x509 -in cert.pem -noout -subject -nameopt oneline,-esc_msb
+
+Display the certificate MD5 fingerprint:
+
+ openssl x509 -in cert.pem -noout -fingerprint
+
+Display the certificate SHA1 fingerprint:
+
+ openssl x509 -sha1 -in cert.pem -noout -fingerprint
+
+Convert a certificate from PEM to DER format:
+
+ openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER
+
+Convert a certificate to a certificate request:
+
+ openssl x509 -x509toreq -in cert.pem -out req.pem -signkey key.pem
+
+Convert a certificate request into a self signed certificate using
+extensions for a CA:
+
+ openssl x509 -req -in careq.pem -extfile openssl.cnf -extensions v3_ca \
+	-signkey key.pem -out cacert.pem
+
+Sign a certificate request using the CA certificate above and add user
+certificate extensions:
+
+ openssl x509 -req -in req.pem -extfile openssl.cnf -extensions v3_usr \
+	-CA cacert.pem -CAkey key.pem -CAcreateserial
+
+
+Set a certificate to be trusted for SSL client use and change set its alias to
+"Steve's Class 1 CA"
+
+ openssl x509 -in cert.pem -addtrust clientAuth \
+	-setalias "Steve's Class 1 CA" -out trust.pem
+
+=head1 NOTES
+
+The PEM format uses the header and footer lines:
+
+ -----BEGIN CERTIFICATE-----
+ -----END CERTIFICATE-----
+
+it will also handle files containing:
+
+ -----BEGIN X509 CERTIFICATE-----
+ -----END X509 CERTIFICATE-----
+
+Trusted certificates have the lines
+
+ -----BEGIN TRUSTED CERTIFICATE-----
+ -----END TRUSTED CERTIFICATE-----
+
+The conversion to UTF8 format used with the name options assumes that
+T61Strings use the ISO8859-1 character set. This is wrong but Netscape
+and MSIE do this as do many certificates. So although this is incorrect
+it is more likely to display the majority of certificates correctly.
+
+The B<-fingerprint> option takes the digest of the DER encoded certificate.
+This is commonly called a "fingerprint". Because of the nature of message
+digests the fingerprint of a certificate is unique to that certificate and
+two certificates with the same fingerprint can be considered to be the same.
+
+The Netscape fingerprint uses MD5 whereas MSIE uses SHA1.
+
+The B<-email> option searches the subject name and the subject alternative
+name extension. Only unique email addresses will be printed out: it will
+not print the same address more than once.
+
+=head1 CERTIFICATE EXTENSIONS
+
+The B<-purpose> option checks the certificate extensions and determines
+what the certificate can be used for. The actual checks done are rather
+complex and include various hacks and workarounds to handle broken
+certificates and software.
+
+The same code is used when verifying untrusted certificates in chains
+so this section is useful if a chain is rejected by the verify code.
+
+The basicConstraints extension CA flag is used to determine whether the
+certificate can be used as a CA. If the CA flag is true then it is a CA,
+if the CA flag is false then it is not a CA. B<All> CAs should have the
+CA flag set to true.
+
+If the basicConstraints extension is absent then the certificate is
+considered to be a "possible CA" other extensions are checked according
+to the intended use of the certificate. A warning is given in this case
+because the certificate should really not be regarded as a CA: however
+it is allowed to be a CA to work around some broken software.
+
+If the certificate is a V1 certificate (and thus has no extensions) and
+it is self signed it is also assumed to be a CA but a warning is again
+given: this is to work around the problem of Verisign roots which are V1
+self signed certificates.
+
+If the keyUsage extension is present then additional restraints are
+made on the uses of the certificate. A CA certificate B<must> have the
+keyCertSign bit set if the keyUsage extension is present.
+
+The extended key usage extension places additional restrictions on the
+certificate uses. If this extension is present (whether critical or not)
+the key can only be used for the purposes specified.
+
+A complete description of each test is given below. The comments about
+basicConstraints and keyUsage and V1 certificates above apply to B<all>
+CA certificates.
+
+
+=over 4
+
+=item B<SSL Client>
+
+The extended key usage extension must be absent or include the "web client
+authentication" OID.  keyUsage must be absent or it must have the
+digitalSignature bit set. Netscape certificate type must be absent or it must
+have the SSL client bit set.
+
+=item B<SSL Client CA>
+
+The extended key usage extension must be absent or include the "web client
+authentication" OID. Netscape certificate type must be absent or it must have
+the SSL CA bit set: this is used as a work around if the basicConstraints
+extension is absent.
+
+=item B<SSL Server>
+
+The extended key usage extension must be absent or include the "web server
+authentication" and/or one of the SGC OIDs.  keyUsage must be absent or it
+must have the digitalSignature, the keyEncipherment set or both bits set.
+Netscape certificate type must be absent or have the SSL server bit set.
+
+=item B<SSL Server CA>
+
+The extended key usage extension must be absent or include the "web server
+authentication" and/or one of the SGC OIDs.  Netscape certificate type must
+be absent or the SSL CA bit must be set: this is used as a work around if the
+basicConstraints extension is absent.
+
+=item B<Netscape SSL Server>
+
+For Netscape SSL clients to connect to an SSL server it must have the
+keyEncipherment bit set if the keyUsage extension is present. This isn't
+always valid because some cipher suites use the key for digital signing.
+Otherwise it is the same as a normal SSL server.
+
+=item B<Common S/MIME Client Tests>
+
+The extended key usage extension must be absent or include the "email
+protection" OID. Netscape certificate type must be absent or should have the
+S/MIME bit set. If the S/MIME bit is not set in netscape certificate type
+then the SSL client bit is tolerated as an alternative but a warning is shown:
+this is because some Verisign certificates don't set the S/MIME bit.
+
+=item B<S/MIME Signing>
+
+In addition to the common S/MIME client tests the digitalSignature bit must
+be set if the keyUsage extension is present.
+
+=item B<S/MIME Encryption>
+
+In addition to the common S/MIME tests the keyEncipherment bit must be set
+if the keyUsage extension is present.
+
+=item B<S/MIME CA>
+
+The extended key usage extension must be absent or include the "email
+protection" OID. Netscape certificate type must be absent or must have the
+S/MIME CA bit set: this is used as a work around if the basicConstraints
+extension is absent. 
+
+=item B<CRL Signing>
+
+The keyUsage extension must be absent or it must have the CRL signing bit
+set.
+
+=item B<CRL Signing CA>
+
+The normal CA tests apply. Except in this case the basicConstraints extension
+must be present.
+
+=back
+
+=head1 BUGS
+
+Extensions in certificates are not transferred to certificate requests and
+vice versa.
+
+It is possible to produce invalid certificates or requests by specifying the
+wrong private key or using inconsistent options in some cases: these should
+be checked.
+
+There should be options to explicitly set such things as start and end
+dates rather than an offset from the current time.
+
+The code to implement the verify behaviour described in the B<TRUST SETTINGS>
+is currently being developed. It thus describes the intended behaviour rather
+than the current behaviour. It is hoped that it will represent reality in
+OpenSSL 0.9.5 and later.
+
+=head1 SEE ALSO
+
+L<req(1)|req(1)>, L<ca(1)|ca(1)>, L<genrsa(1)|genrsa(1)>,
+L<gendsa(1)|gendsa(1)>, L<verify(1)|verify(1)>,
+L<x509v3_config(5)|x509v3_config(5)> 
+
+=head1 HISTORY
+
+Before OpenSSL 0.9.8, the default digest for RSA keys was MD5.
+
+The hash algorithm used in the B<-subject_hash> and B<-issuer_hash> options
+before OpenSSL 1.0.0 was based on the deprecated MD5 algorithm and the encoding
+of the distinguished name. In OpenSSL 1.0.0 and later it is based on a
+canonical version of the DN using SHA1. This means that any directories using
+the old form must have their links rebuilt using B<c_rehash> or similar. 
+
+=cut
diff --git a/openssl/doc/apps/x509v3_config.pod b/openssl/doc/apps/x509v3_config.pod
new file mode 100644
index 0000000..0450067
--- /dev/null
+++ b/openssl/doc/apps/x509v3_config.pod
@@ -0,0 +1,529 @@
+=pod
+
+=for comment openssl_manual_section:5
+
+=head1 NAME
+
+x509v3_config - X509 V3 certificate extension configuration format
+
+=head1 DESCRIPTION
+
+Several of the OpenSSL utilities can add extensions to a certificate or
+certificate request based on the contents of a configuration file.
+
+Typically the application will contain an option to point to an extension
+section. Each line of the extension section takes the form:
+
+ extension_name=[critical,] extension_options
+
+If B<critical> is present then the extension will be critical.
+
+The format of B<extension_options> depends on the value of B<extension_name>.
+
+There are four main types of extension: I<string> extensions, I<multi-valued>
+extensions, I<raw> and I<arbitrary> extensions.
+
+String extensions simply have a string which contains either the value itself
+or how it is obtained.
+
+For example:
+
+ nsComment="This is a Comment"
+
+Multi-valued extensions have a short form and a long form. The short form
+is a list of names and values:
+
+ basicConstraints=critical,CA:true,pathlen:1
+
+The long form allows the values to be placed in a separate section:
+
+ basicConstraints=critical,@bs_section
+
+ [bs_section]
+
+ CA=true
+ pathlen=1
+
+Both forms are equivalent.
+
+The syntax of raw extensions is governed by the extension code: it can
+for example contain data in multiple sections. The correct syntax to
+use is defined by the extension code itself: check out the certificate
+policies extension for an example.
+
+If an extension type is unsupported then the I<arbitrary> extension syntax
+must be used, see the L<ARBITRARY EXTENSIONS|/"ARBITRARY EXTENSIONS"> section for more details.
+
+=head1 STANDARD EXTENSIONS
+
+The following sections describe each supported extension in detail.
+
+=head2 Basic Constraints.
+
+This is a multi valued extension which indicates whether a certificate is
+a CA certificate. The first (mandatory) name is B<CA> followed by B<TRUE> or
+B<FALSE>. If B<CA> is B<TRUE> then an optional B<pathlen> name followed by an
+non-negative value can be included.
+
+For example:
+
+ basicConstraints=CA:TRUE
+
+ basicConstraints=CA:FALSE
+
+ basicConstraints=critical,CA:TRUE, pathlen:0
+
+A CA certificate B<must> include the basicConstraints value with the CA field
+set to TRUE. An end user certificate must either set CA to FALSE or exclude the
+extension entirely. Some software may require the inclusion of basicConstraints
+with CA set to FALSE for end entity certificates.
+
+The pathlen parameter indicates the maximum number of CAs that can appear
+below this one in a chain. So if you have a CA with a pathlen of zero it can
+only be used to sign end user certificates and not further CAs.
+
+
+=head2 Key Usage.
+
+Key usage is a multi valued extension consisting of a list of names of the
+permitted key usages.
+
+The supporte names are: digitalSignature, nonRepudiation, keyEncipherment,
+dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly
+and decipherOnly.
+
+Examples:
+
+ keyUsage=digitalSignature, nonRepudiation
+
+ keyUsage=critical, keyCertSign
+
+
+=head2 Extended Key Usage.
+
+This extensions consists of a list of usages indicating purposes for which
+the certificate public key can be used for,
+
+These can either be object short names of the dotted numerical form of OIDs.
+While any OID can be used only certain values make sense. In particular the
+following PKIX, NS and MS values are meaningful:
+
+ Value			Meaning
+ -----			-------
+ serverAuth		SSL/TLS Web Server Authentication.
+ clientAuth		SSL/TLS Web Client Authentication.
+ codeSigning		Code signing.
+ emailProtection	E-mail Protection (S/MIME).
+ timeStamping		Trusted Timestamping
+ msCodeInd		Microsoft Individual Code Signing (authenticode)
+ msCodeCom		Microsoft Commercial Code Signing (authenticode)
+ msCTLSign		Microsoft Trust List Signing
+ msSGC			Microsoft Server Gated Crypto
+ msEFS			Microsoft Encrypted File System
+ nsSGC			Netscape Server Gated Crypto
+
+Examples:
+
+ extendedKeyUsage=critical,codeSigning,1.2.3.4
+ extendedKeyUsage=nsSGC,msSGC
+
+
+=head2 Subject Key Identifier.
+
+This is really a string extension and can take two possible values. Either
+the word B<hash> which will automatically follow the guidelines in RFC3280
+or a hex string giving the extension value to include. The use of the hex
+string is strongly discouraged.
+
+Example:
+
+ subjectKeyIdentifier=hash
+
+
+=head2 Authority Key Identifier.
+
+The authority key identifier extension permits two options. keyid and issuer:
+both can take the optional value "always".
+
+If the keyid option is present an attempt is made to copy the subject key
+identifier from the parent certificate. If the value "always" is present
+then an error is returned if the option fails.
+
+The issuer option copies the issuer and serial number from the issuer
+certificate. This will only be done if the keyid option fails or
+is not included unless the "always" flag will always include the value.
+
+Example:
+
+ authorityKeyIdentifier=keyid,issuer
+
+
+=head2 Subject Alternative Name.
+
+The subject alternative name extension allows various literal values to be
+included in the configuration file. These include B<email> (an email address)
+B<URI> a uniform resource indicator, B<DNS> (a DNS domain name), B<RID> (a
+registered ID: OBJECT IDENTIFIER), B<IP> (an IP address), B<dirName>
+(a distinguished name) and otherName.
+
+The email option include a special 'copy' value. This will automatically
+include and email addresses contained in the certificate subject name in
+the extension.
+
+The IP address used in the B<IP> options can be in either IPv4 or IPv6 format.
+
+The value of B<dirName> should point to a section containing the distinguished
+name to use as a set of name value pairs. Multi values AVAs can be formed by
+preceeding the name with a B<+> character.
+
+otherName can include arbitrary data associated with an OID: the value
+should be the OID followed by a semicolon and the content in standard
+L<ASN1_generate_nconf(3)|ASN1_generate_nconf(3)> format.
+
+Examples:
+
+ subjectAltName=email:copy,email:my@other.address,URI:http://my.url.here/
+ subjectAltName=IP:192.168.7.1
+ subjectAltName=IP:13::17
+ subjectAltName=email:my@other.address,RID:1.2.3.4
+ subjectAltName=otherName:1.2.3.4;UTF8:some other identifier
+
+ subjectAltName=dirName:dir_sect
+
+ [dir_sect]
+ C=UK
+ O=My Organization
+ OU=My Unit
+ CN=My Name
+
+
+=head2 Issuer Alternative Name.
+
+The issuer alternative name option supports all the literal options of
+subject alternative name. It does B<not> support the email:copy option because
+that would not make sense. It does support an additional issuer:copy option
+that will copy all the subject alternative name values from the issuer 
+certificate (if possible).
+
+Example:
+
+ issuserAltName = issuer:copy
+
+
+=head2 Authority Info Access.
+
+The authority information access extension gives details about how to access
+certain information relating to the CA. Its syntax is accessOID;location
+where I<location> has the same syntax as subject alternative name (except
+that email:copy is not supported). accessOID can be any valid OID but only
+certain values are meaningful, for example OCSP and caIssuers.
+
+Example:
+
+ authorityInfoAccess = OCSP;URI:http://ocsp.my.host/
+ authorityInfoAccess = caIssuers;URI:http://my.ca/ca.html
+
+
+=head2 CRL distribution points.
+
+This is a multi-valued extension whose options can be either in name:value pair
+using the same form as subject alternative name or a single value representing
+a section name containing all the distribution point fields.
+
+For a name:value pair a new DistributionPoint with the fullName field set to
+the given value both the cRLissuer and reasons fields are omitted in this case.
+
+In the single option case the section indicated contains values for each
+field. In this section:
+
+If the name is "fullname" the value field should contain the full name
+of the distribution point in the same format as subject alternative name.
+
+If the name is "relativename" then the value field should contain a section
+name whose contents represent a DN fragment to be placed in this field.
+
+The name "CRLIssuer" if present should contain a value for this field in
+subject alternative name format.
+
+If the name is "reasons" the value field should consist of a comma
+separated field containing the reasons. Valid reasons are: "keyCompromise",
+"CACompromise", "affiliationChanged", "superseded", "cessationOfOperation",
+"certificateHold", "privilegeWithdrawn" and "AACompromise".
+
+
+Simple examples:
+
+ crlDistributionPoints=URI:http://myhost.com/myca.crl
+ crlDistributionPoints=URI:http://my.com/my.crl,URI:http://oth.com/my.crl
+
+Full distribution point example:
+
+ crlDistributionPoints=crldp1_section
+
+ [crldp1_section]
+
+ fullname=URI:http://myhost.com/myca.crl
+ CRLissuer=dirName:issuer_sect
+ reasons=keyCompromise, CACompromise
+
+ [issuer_sect]
+ C=UK
+ O=Organisation
+ CN=Some Name
+
+=head2 Issuing Distribution Point
+
+This extension should only appear in CRLs. It is a multi valued extension
+whose syntax is similar to the "section" pointed to by the CRL distribution
+points extension with a few differences.
+
+The names "reasons" and "CRLissuer" are not recognized.
+
+The name "onlysomereasons" is accepted which sets this field. The value is
+in the same format as the CRL distribution point "reasons" field.
+
+The names "onlyuser", "onlyCA", "onlyAA" and "indirectCRL" are also accepted
+the values should be a boolean value (TRUE or FALSE) to indicate the value of
+the corresponding field.
+
+Example:
+
+ issuingDistributionPoint=critical, @idp_section
+
+ [idp_section]
+
+ fullname=URI:http://myhost.com/myca.crl
+ indirectCRL=TRUE
+ onlysomereasons=keyCompromise, CACompromise
+
+ [issuer_sect]
+ C=UK
+ O=Organisation
+ CN=Some Name
+
+ 
+=head2 Certificate Policies.
+
+This is a I<raw> extension. All the fields of this extension can be set by
+using the appropriate syntax.
+
+If you follow the PKIX recommendations and just using one OID then you just
+include the value of that OID. Multiple OIDs can be set separated by commas,
+for example:
+
+ certificatePolicies= 1.2.4.5, 1.1.3.4
+
+If you wish to include qualifiers then the policy OID and qualifiers need to
+be specified in a separate section: this is done by using the @section syntax
+instead of a literal OID value.
+
+The section referred to must include the policy OID using the name
+policyIdentifier, cPSuri qualifiers can be included using the syntax:
+
+ CPS.nnn=value
+
+userNotice qualifiers can be set using the syntax:
+
+ userNotice.nnn=@notice
+
+The value of the userNotice qualifier is specified in the relevant section.
+This section can include explicitText, organization and noticeNumbers
+options. explicitText and organization are text strings, noticeNumbers is a
+comma separated list of numbers. The organization and noticeNumbers options
+(if included) must BOTH be present. If you use the userNotice option with IE5
+then you need the 'ia5org' option at the top level to modify the encoding:
+otherwise it will not be interpreted properly.
+
+Example:
+
+ certificatePolicies=ia5org,1.2.3.4,1.5.6.7.8,@polsect
+
+ [polsect]
+
+ policyIdentifier = 1.3.5.8
+ CPS.1="http://my.host.name/"
+ CPS.2="http://my.your.name/"
+ userNotice.1=@notice
+
+ [notice]
+
+ explicitText="Explicit Text Here"
+ organization="Organisation Name"
+ noticeNumbers=1,2,3,4
+
+The B<ia5org> option changes the type of the I<organization> field. In RFC2459
+it can only be of type DisplayText. In RFC3280 IA5Strring is also permissible.
+Some software (for example some versions of MSIE) may require ia5org.
+
+=head2 Policy Constraints
+
+This is a multi-valued extension which consisting of the names
+B<requireExplicitPolicy> or B<inhibitPolicyMapping> and a non negative intger
+value. At least one component must be present.
+
+Example:
+
+ policyConstraints = requireExplicitPolicy:3
+
+
+=head2 Inhibit Any Policy
+
+This is a string extension whose value must be a non negative integer.
+
+Example:
+
+ inhibitAnyPolicy = 2
+
+
+=head2 Name Constraints
+
+The name constraints extension is a multi-valued extension. The name should
+begin with the word B<permitted> or B<excluded> followed by a B<;>. The rest of
+the name and the value follows the syntax of subjectAltName except email:copy
+is not supported and the B<IP> form should consist of an IP addresses and 
+subnet mask separated by a B</>.
+
+Examples:
+
+ nameConstraints=permitted;IP:192.168.0.0/255.255.0.0
+
+ nameConstraints=permitted;email:.somedomain.com
+
+ nameConstraints=excluded;email:.com
+issuingDistributionPoint = idp_section
+
+=head2 OCSP No Check
+
+The OCSP No Check extension is a string extension but its value is ignored.
+
+Example:
+
+ noCheck = ignored
+
+
+=head1 DEPRECATED EXTENSIONS
+
+The following extensions are non standard, Netscape specific and largely
+obsolete. Their use in new applications is discouraged.
+
+=head2 Netscape String extensions.
+
+Netscape Comment (B<nsComment>) is a string extension containing a comment
+which will be displayed when the certificate is viewed in some browsers.
+
+Example:
+
+ nsComment = "Some Random Comment"
+
+Other supported extensions in this category are: B<nsBaseUrl>,
+B<nsRevocationUrl>, B<nsCaRevocationUrl>, B<nsRenewalUrl>, B<nsCaPolicyUrl>
+and B<nsSslServerName>.
+
+
+=head2 Netscape Certificate Type
+
+This is a multi-valued extensions which consists of a list of flags to be
+included. It was used to indicate the purposes for which a certificate could
+be used. The basicConstraints, keyUsage and extended key usage extensions are
+now used instead.
+
+Acceptable values for nsCertType are: B<client>, B<server>, B<email>,
+B<objsign>, B<reserved>, B<sslCA>, B<emailCA>, B<objCA>.
+
+
+=head1 ARBITRARY EXTENSIONS
+
+If an extension is not supported by the OpenSSL code then it must be encoded
+using the arbitrary extension format. It is also possible to use the arbitrary
+format for supported extensions. Extreme care should be taken to ensure that
+the data is formatted correctly for the given extension type.
+
+There are two ways to encode arbitrary extensions.
+
+The first way is to use the word ASN1 followed by the extension content
+using the same syntax as L<ASN1_generate_nconf(3)|ASN1_generate_nconf(3)>.
+For example:
+
+ 1.2.3.4=critical,ASN1:UTF8String:Some random data
+
+ 1.2.3.4=ASN1:SEQUENCE:seq_sect
+
+ [seq_sect]
+
+ field1 = UTF8:field1
+ field2 = UTF8:field2
+
+It is also possible to use the word DER to include the raw encoded data in any
+extension.
+
+ 1.2.3.4=critical,DER:01:02:03:04
+ 1.2.3.4=DER:01020304
+
+The value following DER is a hex dump of the DER encoding of the extension
+Any extension can be placed in this form to override the default behaviour.
+For example:
+
+ basicConstraints=critical,DER:00:01:02:03
+
+=head1 WARNING
+
+There is no guarantee that a specific implementation will process a given
+extension. It may therefore be sometimes possible to use certificates for
+purposes prohibited by their extensions because a specific application does
+not recognize or honour the values of the relevant extensions.
+
+The DER and ASN1 options should be used with caution. It is possible to create
+totally invalid extensions if they are not used carefully.
+
+
+=head1 NOTES
+
+If an extension is multi-value and a field value must contain a comma the long
+form must be used otherwise the comma would be misinterpreted as a field
+separator. For example:
+
+ subjectAltName=URI:ldap://somehost.com/CN=foo,OU=bar
+
+will produce an error but the equivalent form:
+
+ subjectAltName=@subject_alt_section
+
+ [subject_alt_section]
+ subjectAltName=URI:ldap://somehost.com/CN=foo,OU=bar
+
+is valid. 
+
+Due to the behaviour of the OpenSSL B<conf> library the same field name
+can only occur once in a section. This means that:
+
+ subjectAltName=@alt_section
+
+ [alt_section]
+
+ email=steve@here
+ email=steve@there
+
+will only recognize the last value. This can be worked around by using the form:
+
+ [alt_section]
+
+ email.1=steve@here
+ email.2=steve@there
+
+=head1 HISTORY
+
+The X509v3 extension code was first added to OpenSSL 0.9.2.
+
+Policy mappings, inhibit any policy and name constraints support was added in
+OpenSSL 0.9.8
+
+The B<directoryName> and B<otherName> option as well as the B<ASN1> option
+for arbitrary extensions was added in OpenSSL 0.9.8
+
+=head1 SEE ALSO
+
+L<req(1)|req(1)>, L<ca(1)|ca(1)>, L<x509(1)|x509(1)>,
+L<ASN1_generate_nconf(3)|ASN1_generate_nconf(3)>
+
+
+=cut
diff --git a/openssl/doc/c-indentation.el b/openssl/doc/c-indentation.el
new file mode 100644
index 0000000..90861d3
--- /dev/null
+++ b/openssl/doc/c-indentation.el
@@ -0,0 +1,45 @@
+; This Emacs Lisp file defines a C indentation style that closely
+; follows most aspects of the one that is used throughout SSLeay,
+; and hence in OpenSSL.
+; 
+; This definition is for the "CC mode" package, which is the default
+; mode for editing C source files in Emacs 20, not for the older
+; c-mode.el (which was the default in less recent releaes of Emacs 19).
+;
+; Copy the definition in your .emacs file or use M-x eval-buffer.
+; To activate this indentation style, visit a C file, type
+; M-x c-set-style <RET> (or C-c . for short), and enter "eay".
+; To toggle the auto-newline feature of CC mode, type C-c C-a.
+;
+; Apparently statement blocks that are not introduced by a statement
+; such as "if" and that are not the body of a function cannot
+; be handled too well by CC mode with this indentation style,
+; so you have to indent them manually (you can use C-q tab).
+; 
+; For suggesting improvements, please send e-mail to bodo@openssl.org.
+
+(c-add-style "eay"
+	     '((c-basic-offset . 8)
+	       (indent-tabs-mode . t)
+	       (c-comment-only-line-offset . 0)
+	       (c-hanging-braces-alist)
+	       (c-offsets-alist	. ((defun-open . +)
+				   (defun-block-intro . 0)
+				   (class-open . +)
+				   (class-close . +)
+				   (block-open . 0)
+				   (block-close . 0)
+				   (substatement-open . +)
+				   (statement . 0)
+				   (statement-block-intro . 0)
+				   (statement-case-open . +)
+				   (statement-case-intro . +)
+				   (case-label . -)
+				   (label . -)
+				   (arglist-cont-nonempty . +)
+				   (topmost-intro . -)
+				   (brace-list-close . 0)
+				   (brace-list-intro . 0)
+				   (brace-list-open . +)
+				   ))))
+
diff --git a/openssl/doc/crypto/ASN1_OBJECT_new.pod b/openssl/doc/crypto/ASN1_OBJECT_new.pod
new file mode 100644
index 0000000..9bae40f
--- /dev/null
+++ b/openssl/doc/crypto/ASN1_OBJECT_new.pod
@@ -0,0 +1,45 @@
+=pod
+
+=head1 NAME
+
+ASN1_OBJECT_new, ASN1_OBJECT_free, - object allocation functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/asn1.h>
+
+ ASN1_OBJECT *ASN1_OBJECT_new(void);
+ void ASN1_OBJECT_free(ASN1_OBJECT *a);
+
+=head1 DESCRIPTION
+
+The ASN1_OBJECT allocation routines, allocate and free an
+ASN1_OBJECT structure, which represents an ASN1 OBJECT IDENTIFIER.
+
+ASN1_OBJECT_new() allocates and initializes a ASN1_OBJECT structure.
+
+ASN1_OBJECT_free() frees up the B<ASN1_OBJECT> structure B<a>.
+
+=head1 NOTES
+
+Although ASN1_OBJECT_new() allocates a new ASN1_OBJECT structure it
+is almost never used in applications. The ASN1 object utility functions
+such as OBJ_nid2obj() are used instead.
+
+=head1 RETURN VALUES
+
+If the allocation fails, ASN1_OBJECT_new() returns B<NULL> and sets an error
+code that can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+Otherwise it returns a pointer to the newly allocated structure.
+
+ASN1_OBJECT_free() returns no value.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<d2i_ASN1_OBJECT(3)|d2i_ASN1_OBJECT(3)>
+
+=head1 HISTORY
+
+ASN1_OBJECT_new() and ASN1_OBJECT_free() are available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/ASN1_STRING_length.pod b/openssl/doc/crypto/ASN1_STRING_length.pod
new file mode 100644
index 0000000..a08e9a0
--- /dev/null
+++ b/openssl/doc/crypto/ASN1_STRING_length.pod
@@ -0,0 +1,83 @@
+=pod
+
+=head1 NAME
+
+ASN1_STRING_dup, ASN1_STRING_cmp, ASN1_STRING_set, ASN1_STRING_length,
+ASN1_STRING_length_set, ASN1_STRING_type, ASN1_STRING_data -
+ASN1_STRING utility functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/asn1.h>
+
+ int ASN1_STRING_length(ASN1_STRING *x);
+ unsigned char * ASN1_STRING_data(ASN1_STRING *x);
+
+ ASN1_STRING * ASN1_STRING_dup(ASN1_STRING *a);
+
+ int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b);
+
+ int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
+
+ int ASN1_STRING_type(ASN1_STRING *x);
+
+ int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in);
+
+=head1 DESCRIPTION
+
+These functions allow an B<ASN1_STRING> structure to be manipulated.
+
+ASN1_STRING_length() returns the length of the content of B<x>.
+
+ASN1_STRING_data() returns an internal pointer to the data of B<x>.
+Since this is an internal pointer it should B<not> be freed or
+modified in any way.
+
+ASN1_STRING_dup() returns a copy of the structure B<a>.
+
+ASN1_STRING_cmp() compares B<a> and B<b> returning 0 if the two
+are identical. The string types and content are compared.
+
+ASN1_STRING_set() sets the data of string B<str> to the buffer
+B<data> or length B<len>. The supplied data is copied. If B<len>
+is -1 then the length is determined by strlen(data).
+
+ASN1_STRING_type() returns the type of B<x>, using standard constants
+such as B<V_ASN1_OCTET_STRING>.
+
+ASN1_STRING_to_UTF8() converts the string B<in> to UTF8 format, the
+converted data is allocated in a buffer in B<*out>. The length of
+B<out> is returned or a negative error code. The buffer B<*out>
+should be free using OPENSSL_free().
+
+=head1 NOTES
+
+Almost all ASN1 types in OpenSSL are represented as an B<ASN1_STRING>
+structure. Other types such as B<ASN1_OCTET_STRING> are simply typedefed
+to B<ASN1_STRING> and the functions call the B<ASN1_STRING> equivalents.
+B<ASN1_STRING> is also used for some B<CHOICE> types which consist
+entirely of primitive string types such as B<DirectoryString> and
+B<Time>.
+
+These functions should B<not> be used to examine or modify B<ASN1_INTEGER>
+or B<ASN1_ENUMERATED> types: the relevant B<INTEGER> or B<ENUMERATED>
+utility functions should be used instead.
+
+In general it cannot be assumed that the data returned by ASN1_STRING_data()
+is null terminated or does not contain embedded nulls. The actual format
+of the data will depend on the actual string type itself: for example
+for and IA5String the data will be ASCII, for a BMPString two bytes per
+character in big endian format, UTF8String will be in UTF8 format.
+
+Similar care should be take to ensure the data is in the correct format
+when calling ASN1_STRING_set().
+
+=head1 RETURN VALUES
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>
+
+=head1 HISTORY
+
+=cut
diff --git a/openssl/doc/crypto/ASN1_STRING_new.pod b/openssl/doc/crypto/ASN1_STRING_new.pod
new file mode 100644
index 0000000..8ac2a03
--- /dev/null
+++ b/openssl/doc/crypto/ASN1_STRING_new.pod
@@ -0,0 +1,46 @@
+=pod
+
+=head1 NAME
+
+ASN1_STRING_new, ASN1_STRING_type_new, ASN1_STRING_free -
+ASN1_STRING allocation functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/asn1.h>
+
+ ASN1_STRING * ASN1_STRING_new(void);
+ ASN1_STRING * ASN1_STRING_type_new(int type);
+ void ASN1_STRING_free(ASN1_STRING *a);
+
+=head1 DESCRIPTION
+
+ASN1_STRING_new() returns an allocated B<ASN1_STRING> structure. Its type
+is undefined.
+
+ASN1_STRING_type_new() returns an allocated B<ASN1_STRING> structure of
+type B<type>.
+
+ASN1_STRING_free() frees up B<a>.
+
+=head1 NOTES
+
+Other string types call the B<ASN1_STRING> functions. For example
+ASN1_OCTET_STRING_new() calls ASN1_STRING_type(V_ASN1_OCTET_STRING).
+
+=head1 RETURN VALUES
+
+ASN1_STRING_new() and ASN1_STRING_type_new() return a valid
+ASN1_STRING structure or B<NULL> if an error occurred.
+
+ASN1_STRING_free() does not return a value.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/ASN1_STRING_print_ex.pod b/openssl/doc/crypto/ASN1_STRING_print_ex.pod
new file mode 100644
index 0000000..3891b88
--- /dev/null
+++ b/openssl/doc/crypto/ASN1_STRING_print_ex.pod
@@ -0,0 +1,96 @@
+=pod
+
+=head1 NAME
+
+ASN1_STRING_print_ex, ASN1_STRING_print_ex_fp - ASN1_STRING output routines.
+
+=head1 SYNOPSIS
+
+ #include <openssl/asn1.h>
+
+ int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
+ int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags);
+ int ASN1_STRING_print(BIO *out, ASN1_STRING *str);
+
+
+=head1 DESCRIPTION
+
+These functions output an B<ASN1_STRING> structure. B<ASN1_STRING> is used to
+represent all the ASN1 string types.
+
+ASN1_STRING_print_ex() outputs B<str> to B<out>, the format is determined by
+the options B<flags>. ASN1_STRING_print_ex_fp() is identical except it outputs
+to B<fp> instead.
+
+ASN1_STRING_print() prints B<str> to B<out> but using a different format to
+ASN1_STRING_print_ex(). It replaces unprintable characters (other than CR, LF)
+with '.'.
+
+=head1 NOTES
+
+ASN1_STRING_print() is a legacy function which should be avoided in new applications.
+
+Although there are a large number of options frequently B<ASN1_STRFLGS_RFC2253> is 
+suitable, or on UTF8 terminals B<ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB>.
+
+The complete set of supported options for B<flags> is listed below.
+
+Various characters can be escaped. If B<ASN1_STRFLGS_ESC_2253> is set the characters
+determined by RFC2253 are escaped. If B<ASN1_STRFLGS_ESC_CTRL> is set control
+characters are escaped. If B<ASN1_STRFLGS_ESC_MSB> is set characters with the
+MSB set are escaped: this option should B<not> be used if the terminal correctly
+interprets UTF8 sequences.
+
+Escaping takes several forms.
+
+If the character being escaped is a 16 bit character then the form "\UXXXX" is used
+using exactly four characters for the hex representation. If it is 32 bits then
+"\WXXXXXXXX" is used using eight characters of its hex representation. These forms
+will only be used if UTF8 conversion is not set (see below).
+
+Printable characters are normally escaped using the backslash '\' character. If
+B<ASN1_STRFLGS_ESC_QUOTE> is set then the whole string is instead surrounded by
+double quote characters: this is arguably more readable than the backslash
+notation. Other characters use the "\XX" using exactly two characters of the hex
+representation.
+
+If B<ASN1_STRFLGS_UTF8_CONVERT> is set then characters are converted to UTF8
+format first. If the terminal supports the display of UTF8 sequences then this
+option will correctly display multi byte characters.
+
+If B<ASN1_STRFLGS_IGNORE_TYPE> is set then the string type is not interpreted at
+all: everything is assumed to be one byte per character. This is primarily for
+debugging purposes and can result in confusing output in multi character strings.
+
+If B<ASN1_STRFLGS_SHOW_TYPE> is set then the string type itself is printed out
+before its value (for example "BMPSTRING"), this actually uses ASN1_tag2str().
+
+The content of a string instead of being interpreted can be "dumped": this just
+outputs the value of the string using the form #XXXX using hex format for each
+octet.
+
+If B<ASN1_STRFLGS_DUMP_ALL> is set then any type is dumped.
+
+Normally non character string types (such as OCTET STRING) are assumed to be
+one byte per character, if B<ASN1_STRFLGS_DUMP_UNKNOWN> is set then they will
+be dumped instead.
+
+When a type is dumped normally just the content octets are printed, if 
+B<ASN1_STRFLGS_DUMP_DER> is set then the complete encoding is dumped
+instead (including tag and length octets).
+
+B<ASN1_STRFLGS_RFC2253> includes all the flags required by RFC2253. It is
+equivalent to:
+ ASN1_STRFLGS_ESC_2253 | ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB |
+ ASN1_STRFLGS_UTF8_CONVERT | ASN1_STRFLGS_DUMP_UNKNOWN ASN1_STRFLGS_DUMP_DER
+
+=head1 SEE ALSO
+
+L<X509_NAME_print_ex(3)|X509_NAME_print_ex(3)>,
+L<ASN1_tag2str(3)|ASN1_tag2str(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/ASN1_generate_nconf.pod b/openssl/doc/crypto/ASN1_generate_nconf.pod
new file mode 100644
index 0000000..542fd15
--- /dev/null
+++ b/openssl/doc/crypto/ASN1_generate_nconf.pod
@@ -0,0 +1,265 @@
+=pod
+
+=head1 NAME
+
+ASN1_generate_nconf, ASN1_generate_v3 - ASN1 generation functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/asn1.h>
+
+ ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
+ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
+
+=head1 DESCRIPTION
+
+These functions generate the ASN1 encoding of a string
+in an B<ASN1_TYPE> structure.
+
+B<str> contains the string to encode B<nconf> or B<cnf> contains
+the optional configuration information where additional strings
+will be read from. B<nconf> will typically come from a config
+file wherease B<cnf> is obtained from an B<X509V3_CTX> structure
+which will typically be used by X509 v3 certificate extension
+functions. B<cnf> or B<nconf> can be set to B<NULL> if no additional
+configuration will be used.
+
+=head1 GENERATION STRING FORMAT
+
+The actual data encoded is determined by the string B<str> and
+the configuration information. The general format of the string
+is:
+
+=over 2
+
+=item B<[modifier,]type[:value]>
+
+=back
+
+That is zero or more comma separated modifiers followed by a type
+followed by an optional colon and a value. The formats of B<type>,
+B<value> and B<modifier> are explained below.
+
+=head2 SUPPORTED TYPES
+
+The supported types are listed below. Unless otherwise specified
+only the B<ASCII> format is permissible.
+
+=over 2
+
+=item B<BOOLEAN>, B<BOOL>
+
+This encodes a boolean type. The B<value> string is mandatory and
+should be B<TRUE> or B<FALSE>. Additionally B<TRUE>, B<true>, B<Y>,
+B<y>, B<YES>, B<yes>, B<FALSE>, B<false>, B<N>, B<n>, B<NO> and B<no>
+are acceptable. 
+
+=item B<NULL>
+
+Encode the B<NULL> type, the B<value> string must not be present.
+
+=item B<INTEGER>, B<INT>
+
+Encodes an ASN1 B<INTEGER> type. The B<value> string represents
+the value of the integer, it can be preceeded by a minus sign and
+is normally interpreted as a decimal value unless the prefix B<0x>
+is included.
+
+=item B<ENUMERATED>, B<ENUM>
+
+Encodes the ASN1 B<ENUMERATED> type, it is otherwise identical to
+B<INTEGER>.
+
+=item B<OBJECT>, B<OID>
+
+Encodes an ASN1 B<OBJECT IDENTIFIER>, the B<value> string can be
+a short name, a long name or numerical format.
+
+=item B<UTCTIME>, B<UTC>
+
+Encodes an ASN1 B<UTCTime> structure, the value should be in
+the format B<YYMMDDHHMMSSZ>. 
+
+=item B<GENERALIZEDTIME>, B<GENTIME>
+
+Encodes an ASN1 B<GeneralizedTime> structure, the value should be in
+the format B<YYYYMMDDHHMMSSZ>. 
+
+=item B<OCTETSTRING>, B<OCT>
+
+Encodes an ASN1 B<OCTET STRING>. B<value> represents the contents
+of this structure, the format strings B<ASCII> and B<HEX> can be
+used to specify the format of B<value>.
+
+=item B<BITSTRING>, B<BITSTR>
+
+Encodes an ASN1 B<BIT STRING>. B<value> represents the contents
+of this structure, the format strings B<ASCII>, B<HEX> and B<BITLIST>
+can be used to specify the format of B<value>.
+
+If the format is anything other than B<BITLIST> the number of unused
+bits is set to zero.
+
+=item B<UNIVERSALSTRING>, B<UNIV>, B<IA5>, B<IA5STRING>, B<UTF8>,
+B<UTF8String>, B<BMP>, B<BMPSTRING>, B<VISIBLESTRING>,
+B<VISIBLE>, B<PRINTABLESTRING>, B<PRINTABLE>, B<T61>,
+B<T61STRING>, B<TELETEXSTRING>, B<GeneralString>, B<NUMERICSTRING>,
+B<NUMERIC>
+
+These encode the corresponding string types. B<value> represents the
+contents of this structure. The format can be B<ASCII> or B<UTF8>.
+
+=item B<SEQUENCE>, B<SEQ>, B<SET>
+
+Formats the result as an ASN1 B<SEQUENCE> or B<SET> type. B<value>
+should be a section name which will contain the contents. The
+field names in the section are ignored and the values are in the
+generated string format. If B<value> is absent then an empty SEQUENCE
+will be encoded.
+
+=back
+
+=head2 MODIFIERS
+
+Modifiers affect the following structure, they can be used to
+add EXPLICIT or IMPLICIT tagging, add wrappers or to change
+the string format of the final type and value. The supported
+formats are documented below.
+
+=over 2
+
+=item B<EXPLICIT>, B<EXP>
+
+Add an explicit tag to the following structure. This string
+should be followed by a colon and the tag value to use as a
+decimal value.
+
+By following the number with B<U>, B<A>, B<P> or B<C> UNIVERSAL,
+APPLICATION, PRIVATE or CONTEXT SPECIFIC tagging can be used,
+the default is CONTEXT SPECIFIC.
+
+=item B<IMPLICIT>, B<IMP>
+
+This is the same as B<EXPLICIT> except IMPLICIT tagging is used
+instead.
+
+=item B<OCTWRAP>, B<SEQWRAP>, B<SETWRAP>, B<BITWRAP>
+
+The following structure is surrounded by an OCTET STRING, a SEQUENCE,
+a SET or a BIT STRING respectively. For a BIT STRING the number of unused
+bits is set to zero.
+
+=item B<FORMAT>
+
+This specifies the format of the ultimate value. It should be followed
+by a colon and one of the strings B<ASCII>, B<UTF8>, B<HEX> or B<BITLIST>.
+
+If no format specifier is included then B<ASCII> is used. If B<UTF8> is
+specified then the value string must be a valid B<UTF8> string. For B<HEX> the
+output must be a set of hex digits. B<BITLIST> (which is only valid for a BIT
+STRING) is a comma separated list of the indices of the set bits, all other
+bits are zero.
+
+=back
+
+=head1 EXAMPLES
+
+A simple IA5String:
+
+ IA5STRING:Hello World
+
+An IA5String explicitly tagged:
+
+ EXPLICIT:0,IA5STRING:Hello World
+
+An IA5String explicitly tagged using APPLICATION tagging:
+
+ EXPLICIT:0A,IA5STRING:Hello World
+
+A BITSTRING with bits 1 and 5 set and all others zero:
+
+ FORMAT:BITLIST,BITSTRING:1,5
+
+A more complex example using a config file to produce a
+SEQUENCE consiting of a BOOL an OID and a UTF8String:
+
+ asn1 = SEQUENCE:seq_section
+
+ [seq_section]
+
+ field1 = BOOLEAN:TRUE
+ field2 = OID:commonName
+ field3 = UTF8:Third field
+
+This example produces an RSAPrivateKey structure, this is the
+key contained in the file client.pem in all OpenSSL distributions
+(note: the field names such as 'coeff' are ignored and are present just
+for clarity):
+
+ asn1=SEQUENCE:private_key
+ [private_key]
+ version=INTEGER:0
+
+ n=INTEGER:0xBB6FE79432CC6EA2D8F970675A5A87BFBE1AFF0BE63E879F2AFFB93644\
+ D4D2C6D000430DEC66ABF47829E74B8C5108623A1C0EE8BE217B3AD8D36D5EB4FCA1D9
+
+ e=INTEGER:0x010001
+
+ d=INTEGER:0x6F05EAD2F27FFAEC84BEC360C4B928FD5F3A9865D0FCAAD291E2A52F4A\
+ F810DC6373278C006A0ABBA27DC8C63BF97F7E666E27C5284D7D3B1FFFE16B7A87B51D
+
+ p=INTEGER:0xF3929B9435608F8A22C208D86795271D54EBDFB09DDEF539AB083DA912\
+ D4BD57
+
+ q=INTEGER:0xC50016F89DFF2561347ED1186A46E150E28BF2D0F539A1594BBD7FE467\
+ 46EC4F
+
+ exp1=INTEGER:0x9E7D4326C924AFC1DEA40B45650134966D6F9DFA3A7F9D698CD4ABEA\
+ 9C0A39B9
+
+ exp2=INTEGER:0xBA84003BB95355AFB7C50DF140C60513D0BA51D637272E355E397779\
+ E7B2458F
+
+ coeff=INTEGER:0x30B9E4F2AFA5AC679F920FC83F1F2DF1BAF1779CF989447FABC2F5\
+ 628657053A
+
+This example is the corresponding public key in a SubjectPublicKeyInfo
+structure:
+
+ # Start with a SEQUENCE
+ asn1=SEQUENCE:pubkeyinfo
+
+ # pubkeyinfo contains an algorithm identifier and the public key wrapped
+ # in a BIT STRING
+ [pubkeyinfo]
+ algorithm=SEQUENCE:rsa_alg
+ pubkey=BITWRAP,SEQUENCE:rsapubkey
+
+ # algorithm ID for RSA is just an OID and a NULL
+ [rsa_alg]
+ algorithm=OID:rsaEncryption
+ parameter=NULL
+
+ # Actual public key: modulus and exponent
+ [rsapubkey]
+ n=INTEGER:0xBB6FE79432CC6EA2D8F970675A5A87BFBE1AFF0BE63E879F2AFFB93644\
+ D4D2C6D000430DEC66ABF47829E74B8C5108623A1C0EE8BE217B3AD8D36D5EB4FCA1D9
+
+ e=INTEGER:0x010001
+
+=head1 RETURN VALUES
+
+ASN1_generate_nconf() and ASN1_generate_v3() return the encoded
+data as an B<ASN1_TYPE> structure or B<NULL> if an error occurred.
+
+The error codes that can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>
+
+=head1 HISTORY
+
+ASN1_generate_nconf() and ASN1_generate_v3() were added to OpenSSL 0.9.8
+
+=cut
diff --git a/openssl/doc/crypto/BIO_ctrl.pod b/openssl/doc/crypto/BIO_ctrl.pod
new file mode 100644
index 0000000..722e8b8
--- /dev/null
+++ b/openssl/doc/crypto/BIO_ctrl.pod
@@ -0,0 +1,128 @@
+=pod
+
+=head1 NAME
+
+BIO_ctrl, BIO_callback_ctrl, BIO_ptr_ctrl, BIO_int_ctrl, BIO_reset,
+BIO_seek, BIO_tell, BIO_flush, BIO_eof, BIO_set_close, BIO_get_close,
+BIO_pending, BIO_wpending, BIO_ctrl_pending, BIO_ctrl_wpending,
+BIO_get_info_callback, BIO_set_info_callback - BIO control operations
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ long BIO_ctrl(BIO *bp,int cmd,long larg,void *parg);
+ long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long));
+ char *	BIO_ptr_ctrl(BIO *bp,int cmd,long larg);
+ long BIO_int_ctrl(BIO *bp,int cmd,long larg,int iarg);
+
+ int BIO_reset(BIO *b);
+ int BIO_seek(BIO *b, int ofs);
+ int BIO_tell(BIO *b);
+ int BIO_flush(BIO *b);
+ int BIO_eof(BIO *b);
+ int BIO_set_close(BIO *b,long flag);
+ int BIO_get_close(BIO *b);
+ int BIO_pending(BIO *b);
+ int BIO_wpending(BIO *b);
+ size_t BIO_ctrl_pending(BIO *b);
+ size_t BIO_ctrl_wpending(BIO *b);
+
+ int BIO_get_info_callback(BIO *b,bio_info_cb **cbp);
+ int BIO_set_info_callback(BIO *b,bio_info_cb *cb);
+
+ typedef void bio_info_cb(BIO *b, int oper, const char *ptr, int arg1, long arg2, long arg3);
+
+=head1 DESCRIPTION
+
+BIO_ctrl(), BIO_callback_ctrl(), BIO_ptr_ctrl() and BIO_int_ctrl()
+are BIO "control" operations taking arguments of various types.
+These functions are not normally called directly, various macros
+are used instead. The standard macros are described below, macros
+specific to a particular type of BIO are described in the specific
+BIOs manual page as well as any special features of the standard
+calls.
+
+BIO_reset() typically resets a BIO to some initial state, in the case
+of file related BIOs for example it rewinds the file pointer to the
+start of the file.
+
+BIO_seek() resets a file related BIO's (that is file descriptor and
+FILE BIOs) file position pointer to B<ofs> bytes from start of file.
+
+BIO_tell() returns the current file position of a file related BIO.
+
+BIO_flush() normally writes out any internally buffered data, in some
+cases it is used to signal EOF and that no more data will be written.
+
+BIO_eof() returns 1 if the BIO has read EOF, the precise meaning of
+"EOF" varies according to the BIO type.
+
+BIO_set_close() sets the BIO B<b> close flag to B<flag>. B<flag> can
+take the value BIO_CLOSE or BIO_NOCLOSE. Typically BIO_CLOSE is used
+in a source/sink BIO to indicate that the underlying I/O stream should
+be closed when the BIO is freed.
+
+BIO_get_close() returns the BIOs close flag.
+
+BIO_pending(), BIO_ctrl_pending(), BIO_wpending() and BIO_ctrl_wpending()
+return the number of pending characters in the BIOs read and write buffers.
+Not all BIOs support these calls. BIO_ctrl_pending() and BIO_ctrl_wpending()
+return a size_t type and are functions, BIO_pending() and BIO_wpending() are
+macros which call BIO_ctrl().
+
+=head1 RETURN VALUES
+
+BIO_reset() normally returns 1 for success and 0 or -1 for failure. File
+BIOs are an exception, they return 0 for success and -1 for failure.
+
+BIO_seek() and BIO_tell() both return the current file position on success
+and -1 for failure, except file BIOs which for BIO_seek() always return 0
+for success and -1 for failure.
+
+BIO_flush() returns 1 for success and 0 or -1 for failure.
+
+BIO_eof() returns 1 if EOF has been reached 0 otherwise.
+
+BIO_set_close() always returns 1.
+
+BIO_get_close() returns the close flag value: BIO_CLOSE or BIO_NOCLOSE.
+
+BIO_pending(), BIO_ctrl_pending(), BIO_wpending() and BIO_ctrl_wpending()
+return the amount of pending data.
+
+=head1 NOTES
+
+BIO_flush(), because it can write data may return 0 or -1 indicating
+that the call should be retried later in a similar manner to BIO_write(). 
+The BIO_should_retry() call should be used and appropriate action taken
+is the call fails.
+
+The return values of BIO_pending() and BIO_wpending() may not reliably
+determine the amount of pending data in all cases. For example in the
+case of a file BIO some data may be available in the FILE structures
+internal buffers but it is not possible to determine this in a
+portably way. For other types of BIO they may not be supported.
+
+Filter BIOs if they do not internally handle a particular BIO_ctrl()
+operation usually pass the operation to the next BIO in the chain.
+This often means there is no need to locate the required BIO for
+a particular operation, it can be called on a chain and it will
+be automatically passed to the relevant BIO. However this can cause
+unexpected results: for example no current filter BIOs implement
+BIO_seek(), but this may still succeed if the chain ends in a FILE
+or file descriptor BIO.
+
+Source/sink BIOs return an 0 if they do not recognize the BIO_ctrl()
+operation.
+
+=head1 BUGS
+
+Some of the return values are ambiguous and care should be taken. In
+particular a return value of 0 can be returned if an operation is not
+supported, if an error occurred, if EOF has not been reached and in
+the case of BIO_seek() on a file BIO for a successful operation. 
+
+=head1 SEE ALSO
+
+TBA
diff --git a/openssl/doc/crypto/BIO_f_base64.pod b/openssl/doc/crypto/BIO_f_base64.pod
new file mode 100644
index 0000000..438af3b
--- /dev/null
+++ b/openssl/doc/crypto/BIO_f_base64.pod
@@ -0,0 +1,81 @@
+=pod
+
+=head1 NAME
+
+BIO_f_base64 - base64 BIO filter
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+ #include <openssl/evp.h>
+
+ BIO_METHOD *	BIO_f_base64(void);
+
+=head1 DESCRIPTION
+
+BIO_f_base64() returns the base64 BIO method. This is a filter
+BIO that base64 encodes any data written through it and decodes
+any data read through it.
+
+Base64 BIOs do not support BIO_gets() or BIO_puts(). 
+
+BIO_flush() on a base64 BIO that is being written through is
+used to signal that no more data is to be encoded: this is used
+to flush the final block through the BIO.
+
+The flag BIO_FLAGS_BASE64_NO_NL can be set with BIO_set_flags()
+to encode the data all on one line or expect the data to be all
+on one line.
+
+=head1 NOTES
+
+Because of the format of base64 encoding the end of the encoded
+block cannot always be reliably determined.
+
+=head1 RETURN VALUES
+
+BIO_f_base64() returns the base64 BIO method.
+
+=head1 EXAMPLES
+
+Base64 encode the string "Hello World\n" and write the result
+to standard output:
+
+ BIO *bio, *b64;
+ char message[] = "Hello World \n";
+
+ b64 = BIO_new(BIO_f_base64());
+ bio = BIO_new_fp(stdout, BIO_NOCLOSE);
+ bio = BIO_push(b64, bio);
+ BIO_write(bio, message, strlen(message));
+ BIO_flush(bio);
+
+ BIO_free_all(bio);
+
+Read Base64 encoded data from standard input and write the decoded
+data to standard output:
+
+ BIO *bio, *b64, *bio_out;
+ char inbuf[512];
+ int inlen;
+
+ b64 = BIO_new(BIO_f_base64());
+ bio = BIO_new_fp(stdin, BIO_NOCLOSE);
+ bio_out = BIO_new_fp(stdout, BIO_NOCLOSE);
+ bio = BIO_push(b64, bio);
+ while((inlen = BIO_read(bio, inbuf, 512)) > 0) 
+	BIO_write(bio_out, inbuf, inlen);
+
+ BIO_free_all(bio);
+
+=head1 BUGS
+
+The ambiguity of EOF in base64 encoded data can cause additional
+data following the base64 encoded block to be misinterpreted.
+
+There should be some way of specifying a test that the BIO can perform
+to reliably determine EOF (for example a MIME boundary).
+
+=head1 SEE ALSO
+
+TBA
diff --git a/openssl/doc/crypto/BIO_f_buffer.pod b/openssl/doc/crypto/BIO_f_buffer.pod
new file mode 100644
index 0000000..c0dccf1
--- /dev/null
+++ b/openssl/doc/crypto/BIO_f_buffer.pod
@@ -0,0 +1,74 @@
+=pod
+
+=head1 NAME
+
+BIO_f_buffer - buffering BIO
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ BIO_METHOD * BIO_f_buffer(void);
+
+ #define BIO_get_buffer_num_lines(b)	BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL)
+ #define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0)
+ #define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1)
+ #define BIO_set_buffer_size(b,size)	BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL)
+ #define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf)
+
+=head1 DESCRIPTION
+
+BIO_f_buffer() returns the buffering BIO method.
+
+Data written to a buffering BIO is buffered and periodically written
+to the next BIO in the chain. Data read from a buffering BIO comes from
+an internal buffer which is filled from the next BIO in the chain.
+Both BIO_gets() and BIO_puts() are supported.
+
+Calling BIO_reset() on a buffering BIO clears any buffered data.
+
+BIO_get_buffer_num_lines() returns the number of lines currently buffered.
+
+BIO_set_read_buffer_size(), BIO_set_write_buffer_size() and BIO_set_buffer_size()
+set the read, write or both read and write buffer sizes to B<size>. The initial
+buffer size is DEFAULT_BUFFER_SIZE, currently 4096. Any attempt to reduce the
+buffer size below DEFAULT_BUFFER_SIZE is ignored. Any buffered data is cleared
+when the buffer is resized.
+
+BIO_set_buffer_read_data() clears the read buffer and fills it with B<num>
+bytes of B<buf>. If B<num> is larger than the current buffer size the buffer
+is expanded.
+
+=head1 NOTES
+
+Buffering BIOs implement BIO_gets() by using BIO_read() operations on the
+next BIO in the chain. By prepending a buffering BIO to a chain it is therefore
+possible to provide BIO_gets() functionality if the following BIOs do not
+support it (for example SSL BIOs).
+
+Data is only written to the next BIO in the chain when the write buffer fills
+or when BIO_flush() is called. It is therefore important to call BIO_flush()
+whenever any pending data should be written such as when removing a buffering
+BIO using BIO_pop(). BIO_flush() may need to be retried if the ultimate
+source/sink BIO is non blocking.
+
+=head1 RETURN VALUES
+
+BIO_f_buffer() returns the buffering BIO method.
+
+BIO_get_buffer_num_lines() returns the number of lines buffered (may be 0).
+
+BIO_set_read_buffer_size(), BIO_set_write_buffer_size() and BIO_set_buffer_size()
+return 1 if the buffer was successfully resized or 0 for failure.
+
+BIO_set_buffer_read_data() returns 1 if the data was set correctly or 0 if
+there was an error.
+
+=head1 SEE ALSO
+
+L<BIO(3)|BIO(3)>,
+L<BIO_reset(3)|BIO_reset(3)>,
+L<BIO_flush(3)|BIO_flush(3)>,
+L<BIO_pop(3)|BIO_pop(3)>,
+L<BIO_ctrl(3)|BIO_ctrl(3)>,
+L<BIO_int_ctrl(3)|BIO_ctrl(3)>
diff --git a/openssl/doc/crypto/BIO_f_cipher.pod b/openssl/doc/crypto/BIO_f_cipher.pod
new file mode 100644
index 0000000..02439ce
--- /dev/null
+++ b/openssl/doc/crypto/BIO_f_cipher.pod
@@ -0,0 +1,76 @@
+=pod
+
+=head1 NAME
+
+BIO_f_cipher, BIO_set_cipher, BIO_get_cipher_status, BIO_get_cipher_ctx - cipher BIO filter
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+ #include <openssl/evp.h>
+
+ BIO_METHOD *	BIO_f_cipher(void);
+ void BIO_set_cipher(BIO *b,const EVP_CIPHER *cipher,
+		unsigned char *key, unsigned char *iv, int enc);
+ int BIO_get_cipher_status(BIO *b)
+ int BIO_get_cipher_ctx(BIO *b, EVP_CIPHER_CTX **pctx)
+
+=head1 DESCRIPTION
+
+BIO_f_cipher() returns the cipher BIO method. This is a filter
+BIO that encrypts any data written through it, and decrypts any data
+read from it. It is a BIO wrapper for the cipher routines
+EVP_CipherInit(), EVP_CipherUpdate() and EVP_CipherFinal().
+
+Cipher BIOs do not support BIO_gets() or BIO_puts(). 
+
+BIO_flush() on an encryption BIO that is being written through is
+used to signal that no more data is to be encrypted: this is used
+to flush and possibly pad the final block through the BIO.
+
+BIO_set_cipher() sets the cipher of BIO B<b> to B<cipher> using key B<key>
+and IV B<iv>. B<enc> should be set to 1 for encryption and zero for
+decryption.
+
+When reading from an encryption BIO the final block is automatically
+decrypted and checked when EOF is detected. BIO_get_cipher_status()
+is a BIO_ctrl() macro which can be called to determine whether the
+decryption operation was successful.
+
+BIO_get_cipher_ctx() is a BIO_ctrl() macro which retrieves the internal
+BIO cipher context. The retrieved context can be used in conjunction
+with the standard cipher routines to set it up. This is useful when
+BIO_set_cipher() is not flexible enough for the applications needs.
+
+=head1 NOTES
+
+When encrypting BIO_flush() B<must> be called to flush the final block
+through the BIO. If it is not then the final block will fail a subsequent
+decrypt.
+
+When decrypting an error on the final block is signalled by a zero
+return value from the read operation. A successful decrypt followed
+by EOF will also return zero for the final read. BIO_get_cipher_status()
+should be called to determine if the decrypt was successful.
+
+As always, if BIO_gets() or BIO_puts() support is needed then it can
+be achieved by preceding the cipher BIO with a buffering BIO.
+
+=head1 RETURN VALUES
+
+BIO_f_cipher() returns the cipher BIO method.
+
+BIO_set_cipher() does not return a value.
+
+BIO_get_cipher_status() returns 1 for a successful decrypt and 0
+for failure.
+
+BIO_get_cipher_ctx() currently always returns 1.
+
+=head1 EXAMPLES
+
+TBA
+
+=head1 SEE ALSO
+
+TBA
diff --git a/openssl/doc/crypto/BIO_f_md.pod b/openssl/doc/crypto/BIO_f_md.pod
new file mode 100644
index 0000000..2cc41f8
--- /dev/null
+++ b/openssl/doc/crypto/BIO_f_md.pod
@@ -0,0 +1,144 @@
+=pod
+
+=head1 NAME
+
+BIO_f_md, BIO_set_md, BIO_get_md, BIO_get_md_ctx - message digest BIO filter
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+ #include <openssl/evp.h>
+
+ BIO_METHOD *	BIO_f_md(void);
+ int BIO_set_md(BIO *b,EVP_MD *md);
+ int BIO_get_md(BIO *b,EVP_MD **mdp);
+ int BIO_get_md_ctx(BIO *b,EVP_MD_CTX **mdcp);
+
+=head1 DESCRIPTION
+
+BIO_f_md() returns the message digest BIO method. This is a filter
+BIO that digests any data passed through it, it is a BIO wrapper
+for the digest routines EVP_DigestInit(), EVP_DigestUpdate()
+and EVP_DigestFinal().
+
+Any data written or read through a digest BIO using BIO_read() and
+BIO_write() is digested.
+
+BIO_gets(), if its B<size> parameter is large enough finishes the
+digest calculation and returns the digest value. BIO_puts() is
+not supported.
+
+BIO_reset() reinitialises a digest BIO.
+
+BIO_set_md() sets the message digest of BIO B<b> to B<md>: this
+must be called to initialize a digest BIO before any data is
+passed through it. It is a BIO_ctrl() macro.
+
+BIO_get_md() places the a pointer to the digest BIOs digest method
+in B<mdp>, it is a BIO_ctrl() macro.
+
+BIO_get_md_ctx() returns the digest BIOs context into B<mdcp>.
+
+=head1 NOTES
+
+The context returned by BIO_get_md_ctx() can be used in calls
+to EVP_DigestFinal() and also the signature routines EVP_SignFinal()
+and EVP_VerifyFinal().
+
+The context returned by BIO_get_md_ctx() is an internal context
+structure. Changes made to this context will affect the digest
+BIO itself and the context pointer will become invalid when the digest
+BIO is freed.
+
+After the digest has been retrieved from a digest BIO it must be
+reinitialized by calling BIO_reset(), or BIO_set_md() before any more
+data is passed through it.
+
+If an application needs to call BIO_gets() or BIO_puts() through
+a chain containing digest BIOs then this can be done by prepending
+a buffering BIO.
+
+Before OpenSSL 1.0.0 the call to BIO_get_md_ctx() would only work if the BIO
+had been initialized for example by calling BIO_set_md() ). In OpenSSL
+1.0.0 and later the context is always returned and the BIO is state is set
+to initialized. This allows applications to initialize the context externally
+if the standard calls such as BIO_set_md() are not sufficiently flexible.
+
+=head1 RETURN VALUES
+
+BIO_f_md() returns the digest BIO method.
+
+BIO_set_md(), BIO_get_md() and BIO_md_ctx() return 1 for success and
+0 for failure.
+
+=head1 EXAMPLES
+
+The following example creates a BIO chain containing an SHA1 and MD5
+digest BIO and passes the string "Hello World" through it. Error
+checking has been omitted for clarity.
+
+ BIO *bio, *mdtmp;
+ char message[] = "Hello World";
+ bio = BIO_new(BIO_s_null());
+ mdtmp = BIO_new(BIO_f_md());
+ BIO_set_md(mdtmp, EVP_sha1());
+ /* For BIO_push() we want to append the sink BIO and keep a note of
+  * the start of the chain.
+  */
+ bio = BIO_push(mdtmp, bio);
+ mdtmp = BIO_new(BIO_f_md());
+ BIO_set_md(mdtmp, EVP_md5());
+ bio = BIO_push(mdtmp, bio);
+ /* Note: mdtmp can now be discarded */
+ BIO_write(bio, message, strlen(message));
+
+The next example digests data by reading through a chain instead:
+
+ BIO *bio, *mdtmp;
+ char buf[1024];
+ int rdlen;
+ bio = BIO_new_file(file, "rb");
+ mdtmp = BIO_new(BIO_f_md());
+ BIO_set_md(mdtmp, EVP_sha1());
+ bio = BIO_push(mdtmp, bio);
+ mdtmp = BIO_new(BIO_f_md());
+ BIO_set_md(mdtmp, EVP_md5());
+ bio = BIO_push(mdtmp, bio);
+ do {
+ 	rdlen = BIO_read(bio, buf, sizeof(buf));
+        /* Might want to do something with the data here */
+ } while(rdlen > 0);
+
+This next example retrieves the message digests from a BIO chain and
+outputs them. This could be used with the examples above.
+
+ BIO *mdtmp;
+ unsigned char mdbuf[EVP_MAX_MD_SIZE];
+ int mdlen;
+ int i;
+ mdtmp = bio;	/* Assume bio has previously been set up */
+ do {
+	EVP_MD *md;
+ 	mdtmp = BIO_find_type(mdtmp, BIO_TYPE_MD);
+        if(!mdtmp) break;
+	BIO_get_md(mdtmp, &md);
+        printf("%s digest", OBJ_nid2sn(EVP_MD_type(md)));
+	mdlen = BIO_gets(mdtmp, mdbuf, EVP_MAX_MD_SIZE);
+	for(i = 0; i < mdlen; i++) printf(":%02X", mdbuf[i]);
+	printf("\n");
+	mdtmp = BIO_next(mdtmp);
+ } while(mdtmp);
+
+ BIO_free_all(bio);
+
+=head1 BUGS
+
+The lack of support for BIO_puts() and the non standard behaviour of
+BIO_gets() could be regarded as anomalous. It could be argued that BIO_gets()
+and BIO_puts() should be passed to the next BIO in the chain and digest
+the data passed through and that digests should be retrieved using a
+separate BIO_ctrl() call.
+
+=head1 SEE ALSO
+
+TBA
diff --git a/openssl/doc/crypto/BIO_f_null.pod b/openssl/doc/crypto/BIO_f_null.pod
new file mode 100644
index 0000000..b057c18
--- /dev/null
+++ b/openssl/doc/crypto/BIO_f_null.pod
@@ -0,0 +1,32 @@
+=pod
+
+=head1 NAME
+
+BIO_f_null - null filter
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ BIO_METHOD *	BIO_f_null(void);
+
+=head1 DESCRIPTION
+
+BIO_f_null() returns the null filter BIO method. This is a filter BIO
+that does nothing.
+
+All requests to a null filter BIO are passed through to the next BIO in
+the chain: this means that a BIO chain containing a null filter BIO
+behaves just as though the BIO was not there.
+
+=head1 NOTES
+
+As may be apparent a null filter BIO is not particularly useful.
+
+=head1 RETURN VALUES
+
+BIO_f_null() returns the null filter BIO method.
+
+=head1 SEE ALSO
+
+TBA
diff --git a/openssl/doc/crypto/BIO_f_ssl.pod b/openssl/doc/crypto/BIO_f_ssl.pod
new file mode 100644
index 0000000..bc5861a
--- /dev/null
+++ b/openssl/doc/crypto/BIO_f_ssl.pod
@@ -0,0 +1,322 @@
+=pod
+
+=head1 NAME
+
+BIO_f_ssl, BIO_set_ssl, BIO_get_ssl, BIO_set_ssl_mode, BIO_set_ssl_renegotiate_bytes,
+BIO_get_num_renegotiates, BIO_set_ssl_renegotiate_timeout, BIO_new_ssl,
+BIO_new_ssl_connect, BIO_new_buffer_ssl_connect, BIO_ssl_copy_session_id,
+BIO_ssl_shutdown - SSL BIO
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+ #include <openssl/ssl.h>
+
+ BIO_METHOD *BIO_f_ssl(void);
+
+ #define BIO_set_ssl(b,ssl,c)	BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl)
+ #define BIO_get_ssl(b,sslp)	BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp)
+ #define BIO_set_ssl_mode(b,client)	BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL)
+ #define BIO_set_ssl_renegotiate_bytes(b,num) \
+	BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL);
+ #define BIO_set_ssl_renegotiate_timeout(b,seconds) \
+	BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL);
+ #define BIO_get_num_renegotiates(b) \
+	BIO_ctrl(b,BIO_C_SET_SSL_NUM_RENEGOTIATES,0,NULL);
+
+ BIO *BIO_new_ssl(SSL_CTX *ctx,int client);
+ BIO *BIO_new_ssl_connect(SSL_CTX *ctx);
+ BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx);
+ int BIO_ssl_copy_session_id(BIO *to,BIO *from);
+ void BIO_ssl_shutdown(BIO *bio);
+
+ #define BIO_do_handshake(b)	BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL)
+
+=head1 DESCRIPTION
+
+BIO_f_ssl() returns the SSL BIO method. This is a filter BIO which
+is a wrapper round the OpenSSL SSL routines adding a BIO "flavour" to
+SSL I/O. 
+
+I/O performed on an SSL BIO communicates using the SSL protocol with
+the SSLs read and write BIOs. If an SSL connection is not established
+then an attempt is made to establish one on the first I/O call.
+
+If a BIO is appended to an SSL BIO using BIO_push() it is automatically
+used as the SSL BIOs read and write BIOs.
+
+Calling BIO_reset() on an SSL BIO closes down any current SSL connection
+by calling SSL_shutdown(). BIO_reset() is then sent to the next BIO in
+the chain: this will typically disconnect the underlying transport.
+The SSL BIO is then reset to the initial accept or connect state.
+
+If the close flag is set when an SSL BIO is freed then the internal
+SSL structure is also freed using SSL_free().
+
+BIO_set_ssl() sets the internal SSL pointer of BIO B<b> to B<ssl> using
+the close flag B<c>.
+
+BIO_get_ssl() retrieves the SSL pointer of BIO B<b>, it can then be
+manipulated using the standard SSL library functions.
+
+BIO_set_ssl_mode() sets the SSL BIO mode to B<client>. If B<client>
+is 1 client mode is set. If B<client> is 0 server mode is set.
+
+BIO_set_ssl_renegotiate_bytes() sets the renegotiate byte count
+to B<num>. When set after every B<num> bytes of I/O (read and write) 
+the SSL session is automatically renegotiated. B<num> must be at
+least 512 bytes.
+
+BIO_set_ssl_renegotiate_timeout() sets the renegotiate timeout to
+B<seconds>. When the renegotiate timeout elapses the session is
+automatically renegotiated.
+
+BIO_get_num_renegotiates() returns the total number of session
+renegotiations due to I/O or timeout.
+
+BIO_new_ssl() allocates an SSL BIO using SSL_CTX B<ctx> and using
+client mode if B<client> is non zero.
+
+BIO_new_ssl_connect() creates a new BIO chain consisting of an
+SSL BIO (using B<ctx>) followed by a connect BIO.
+
+BIO_new_buffer_ssl_connect() creates a new BIO chain consisting
+of a buffering BIO, an SSL BIO (using B<ctx>) and a connect
+BIO.
+
+BIO_ssl_copy_session_id() copies an SSL session id between 
+BIO chains B<from> and B<to>. It does this by locating the
+SSL BIOs in each chain and calling SSL_copy_session_id() on
+the internal SSL pointer.
+
+BIO_ssl_shutdown() closes down an SSL connection on BIO
+chain B<bio>. It does this by locating the SSL BIO in the
+chain and calling SSL_shutdown() on its internal SSL
+pointer.
+
+BIO_do_handshake() attempts to complete an SSL handshake on the
+supplied BIO and establish the SSL connection. It returns 1
+if the connection was established successfully. A zero or negative
+value is returned if the connection could not be established, the
+call BIO_should_retry() should be used for non blocking connect BIOs
+to determine if the call should be retried. If an SSL connection has
+already been established this call has no effect.
+
+=head1 NOTES
+
+SSL BIOs are exceptional in that if the underlying transport
+is non blocking they can still request a retry in exceptional
+circumstances. Specifically this will happen if a session
+renegotiation takes place during a BIO_read() operation, one
+case where this happens is when SGC or step up occurs.
+
+In OpenSSL 0.9.6 and later the SSL flag SSL_AUTO_RETRY can be
+set to disable this behaviour. That is when this flag is set
+an SSL BIO using a blocking transport will never request a
+retry.
+
+Since unknown BIO_ctrl() operations are sent through filter
+BIOs the servers name and port can be set using BIO_set_host()
+on the BIO returned by BIO_new_ssl_connect() without having
+to locate the connect BIO first.
+
+Applications do not have to call BIO_do_handshake() but may wish
+to do so to separate the handshake process from other I/O
+processing.
+
+=head1 RETURN VALUES
+
+TBA
+
+=head1 EXAMPLE
+
+This SSL/TLS client example, attempts to retrieve a page from an
+SSL/TLS web server. The I/O routines are identical to those of the
+unencrypted example in L<BIO_s_connect(3)|BIO_s_connect(3)>.
+
+ BIO *sbio, *out;
+ int len;
+ char tmpbuf[1024];
+ SSL_CTX *ctx;
+ SSL *ssl;
+
+ ERR_load_crypto_strings();
+ ERR_load_SSL_strings();
+ OpenSSL_add_all_algorithms();
+
+ /* We would seed the PRNG here if the platform didn't
+  * do it automatically
+  */
+
+ ctx = SSL_CTX_new(SSLv23_client_method());
+
+ /* We'd normally set some stuff like the verify paths and
+  * mode here because as things stand this will connect to
+  * any server whose certificate is signed by any CA.
+  */
+
+ sbio = BIO_new_ssl_connect(ctx);
+
+ BIO_get_ssl(sbio, &ssl);
+
+ if(!ssl) {
+   fprintf(stderr, "Can't locate SSL pointer\n");
+   /* whatever ... */
+ }
+
+ /* Don't want any retries */
+ SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
+
+ /* We might want to do other things with ssl here */
+
+ BIO_set_conn_hostname(sbio, "localhost:https");
+
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+ if(BIO_do_connect(sbio) <= 0) {
+	fprintf(stderr, "Error connecting to server\n");
+	ERR_print_errors_fp(stderr);
+	/* whatever ... */
+ }
+
+ if(BIO_do_handshake(sbio) <= 0) {
+	fprintf(stderr, "Error establishing SSL connection\n");
+	ERR_print_errors_fp(stderr);
+	/* whatever ... */
+ }
+
+ /* Could examine ssl here to get connection info */
+
+ BIO_puts(sbio, "GET / HTTP/1.0\n\n");
+ for(;;) {	
+	len = BIO_read(sbio, tmpbuf, 1024);
+	if(len <= 0) break;
+	BIO_write(out, tmpbuf, len);
+ }
+ BIO_free_all(sbio);
+ BIO_free(out);
+
+Here is a simple server example. It makes use of a buffering
+BIO to allow lines to be read from the SSL BIO using BIO_gets.
+It creates a pseudo web page containing the actual request from
+a client and also echoes the request to standard output.
+
+ BIO *sbio, *bbio, *acpt, *out;
+ int len;
+ char tmpbuf[1024];
+ SSL_CTX *ctx;
+ SSL *ssl;
+
+ ERR_load_crypto_strings();
+ ERR_load_SSL_strings();
+ OpenSSL_add_all_algorithms();
+
+ /* Might seed PRNG here */
+
+ ctx = SSL_CTX_new(SSLv23_server_method());
+
+ if (!SSL_CTX_use_certificate_file(ctx,"server.pem",SSL_FILETYPE_PEM)
+	|| !SSL_CTX_use_PrivateKey_file(ctx,"server.pem",SSL_FILETYPE_PEM)
+	|| !SSL_CTX_check_private_key(ctx)) {
+
+	fprintf(stderr, "Error setting up SSL_CTX\n");
+	ERR_print_errors_fp(stderr);
+	return 0;
+ }
+
+ /* Might do other things here like setting verify locations and
+  * DH and/or RSA temporary key callbacks
+  */
+
+ /* New SSL BIO setup as server */
+ sbio=BIO_new_ssl(ctx,0);
+
+ BIO_get_ssl(sbio, &ssl);
+
+ if(!ssl) {
+   fprintf(stderr, "Can't locate SSL pointer\n");
+   /* whatever ... */
+ }
+
+ /* Don't want any retries */
+ SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
+
+ /* Create the buffering BIO */
+
+ bbio = BIO_new(BIO_f_buffer());
+
+ /* Add to chain */
+ sbio = BIO_push(bbio, sbio);
+
+ acpt=BIO_new_accept("4433");
+
+ /* By doing this when a new connection is established
+  * we automatically have sbio inserted into it. The
+  * BIO chain is now 'swallowed' by the accept BIO and
+  * will be freed when the accept BIO is freed. 
+  */
+ 
+ BIO_set_accept_bios(acpt,sbio);
+
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+
+ /* Setup accept BIO */
+ if(BIO_do_accept(acpt) <= 0) {
+	fprintf(stderr, "Error setting up accept BIO\n");
+	ERR_print_errors_fp(stderr);
+	return 0;
+ }
+
+ /* Now wait for incoming connection */
+ if(BIO_do_accept(acpt) <= 0) {
+	fprintf(stderr, "Error in connection\n");
+	ERR_print_errors_fp(stderr);
+	return 0;
+ }
+
+ /* We only want one connection so remove and free
+  * accept BIO
+  */
+
+ sbio = BIO_pop(acpt);
+
+ BIO_free_all(acpt);
+
+ if(BIO_do_handshake(sbio) <= 0) {
+	fprintf(stderr, "Error in SSL handshake\n");
+	ERR_print_errors_fp(stderr);
+	return 0;
+ }
+
+ BIO_puts(sbio, "HTTP/1.0 200 OK\r\nContent-type: text/plain\r\n\r\n");
+ BIO_puts(sbio, "\r\nConnection Established\r\nRequest headers:\r\n");
+ BIO_puts(sbio, "--------------------------------------------------\r\n");
+
+ for(;;) {
+ 	len = BIO_gets(sbio, tmpbuf, 1024);
+        if(len <= 0) break;
+	BIO_write(sbio, tmpbuf, len);
+	BIO_write(out, tmpbuf, len);
+	/* Look for blank line signifying end of headers*/
+	if((tmpbuf[0] == '\r') || (tmpbuf[0] == '\n')) break;
+ }
+
+ BIO_puts(sbio, "--------------------------------------------------\r\n");
+ BIO_puts(sbio, "\r\n");
+
+ /* Since there is a buffering BIO present we had better flush it */
+ BIO_flush(sbio);
+
+ BIO_free_all(sbio);
+
+=head1 BUGS
+
+In OpenSSL versions before 1.0.0 the BIO_pop() call was handled incorrectly,
+the I/O BIO reference count was incorrectly incremented (instead of
+decremented) and dissociated with the SSL BIO even if the SSL BIO was not
+explicitly being popped (e.g. a pop higher up the chain). Applications which
+included workarounds for this bug (e.g. freeing BIOs more than once) should
+be modified to handle this fix or they may free up an already freed BIO.
+
+=head1 SEE ALSO
+
+TBA
diff --git a/openssl/doc/crypto/BIO_find_type.pod b/openssl/doc/crypto/BIO_find_type.pod
new file mode 100644
index 0000000..bd3b256
--- /dev/null
+++ b/openssl/doc/crypto/BIO_find_type.pod
@@ -0,0 +1,98 @@
+=pod
+
+=head1 NAME
+
+BIO_find_type, BIO_next - BIO chain traversal
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ BIO *	BIO_find_type(BIO *b,int bio_type);
+ BIO *	BIO_next(BIO *b);
+
+ #define BIO_method_type(b)		((b)->method->type)
+
+ #define BIO_TYPE_NONE		0
+ #define BIO_TYPE_MEM		(1|0x0400)
+ #define BIO_TYPE_FILE		(2|0x0400)
+
+ #define BIO_TYPE_FD		(4|0x0400|0x0100)
+ #define BIO_TYPE_SOCKET		(5|0x0400|0x0100)
+ #define BIO_TYPE_NULL		(6|0x0400)
+ #define BIO_TYPE_SSL		(7|0x0200)
+ #define BIO_TYPE_MD		(8|0x0200)
+ #define BIO_TYPE_BUFFER		(9|0x0200)
+ #define BIO_TYPE_CIPHER		(10|0x0200)
+ #define BIO_TYPE_BASE64		(11|0x0200)
+ #define BIO_TYPE_CONNECT	(12|0x0400|0x0100)
+ #define BIO_TYPE_ACCEPT		(13|0x0400|0x0100)
+ #define BIO_TYPE_PROXY_CLIENT	(14|0x0200)
+ #define BIO_TYPE_PROXY_SERVER	(15|0x0200)
+ #define BIO_TYPE_NBIO_TEST	(16|0x0200)
+ #define BIO_TYPE_NULL_FILTER	(17|0x0200)
+ #define BIO_TYPE_BER		(18|0x0200)
+ #define BIO_TYPE_BIO		(19|0x0400)
+
+ #define BIO_TYPE_DESCRIPTOR	0x0100
+ #define BIO_TYPE_FILTER		0x0200
+ #define BIO_TYPE_SOURCE_SINK	0x0400
+
+=head1 DESCRIPTION
+
+The BIO_find_type() searches for a BIO of a given type in a chain, starting
+at BIO B<b>. If B<type> is a specific type (such as BIO_TYPE_MEM) then a search
+is made for a BIO of that type. If B<type> is a general type (such as
+B<BIO_TYPE_SOURCE_SINK>) then the next matching BIO of the given general type is
+searched for. BIO_find_type() returns the next matching BIO or NULL if none is
+found.
+
+Note: not all the B<BIO_TYPE_*> types above have corresponding BIO implementations.
+
+BIO_next() returns the next BIO in a chain. It can be used to traverse all BIOs
+in a chain or used in conjunction with BIO_find_type() to find all BIOs of a
+certain type.
+
+BIO_method_type() returns the type of a BIO.
+
+=head1 RETURN VALUES
+
+BIO_find_type() returns a matching BIO or NULL for no match.
+
+BIO_next() returns the next BIO in a chain.
+
+BIO_method_type() returns the type of the BIO B<b>.
+
+=head1 NOTES
+
+BIO_next() was added to OpenSSL 0.9.6 to provide a 'clean' way to traverse a BIO
+chain or find multiple matches using BIO_find_type(). Previous versions had to
+use:
+
+ next = bio->next_bio;
+
+=head1 BUGS
+
+BIO_find_type() in OpenSSL 0.9.5a and earlier could not be safely passed a
+NULL pointer for the B<b> argument.
+
+=head1 EXAMPLE
+
+Traverse a chain looking for digest BIOs:
+
+ BIO *btmp;
+ btmp = in_bio;	/* in_bio is chain to search through */
+
+ do {
+ 	btmp = BIO_find_type(btmp, BIO_TYPE_MD);
+	if(btmp == NULL) break;	/* Not found */
+	/* btmp is a digest BIO, do something with it ...*/
+   	...
+
+	btmp = BIO_next(btmp);
+ } while(btmp);
+
+
+=head1 SEE ALSO
+
+TBA
diff --git a/openssl/doc/crypto/BIO_new.pod b/openssl/doc/crypto/BIO_new.pod
new file mode 100644
index 0000000..2a245fc
--- /dev/null
+++ b/openssl/doc/crypto/BIO_new.pod
@@ -0,0 +1,65 @@
+=pod
+
+=head1 NAME
+
+BIO_new, BIO_set, BIO_free, BIO_vfree, BIO_free_all - BIO allocation and freeing functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ BIO *	BIO_new(BIO_METHOD *type);
+ int	BIO_set(BIO *a,BIO_METHOD *type);
+ int	BIO_free(BIO *a);
+ void	BIO_vfree(BIO *a);
+ void	BIO_free_all(BIO *a);
+
+=head1 DESCRIPTION
+
+The BIO_new() function returns a new BIO using method B<type>.
+
+BIO_set() sets the method of an already existing BIO.
+
+BIO_free() frees up a single BIO, BIO_vfree() also frees up a single BIO
+but it does not return a value. Calling BIO_free() may also have some effect
+on the underlying I/O structure, for example it may close the file being
+referred to under certain circumstances. For more details see the individual
+BIO_METHOD descriptions.
+
+BIO_free_all() frees up an entire BIO chain, it does not halt if an error
+occurs freeing up an individual BIO in the chain.
+
+=head1 RETURN VALUES
+
+BIO_new() returns a newly created BIO or NULL if the call fails.
+
+BIO_set(), BIO_free() return 1 for success and 0 for failure.
+
+BIO_free_all() and BIO_vfree() do not return values.
+
+=head1 NOTES
+
+Some BIOs (such as memory BIOs) can be used immediately after calling
+BIO_new(). Others (such as file BIOs) need some additional initialization,
+and frequently a utility function exists to create and initialize such BIOs.
+
+If BIO_free() is called on a BIO chain it will only free one BIO resulting
+in a memory leak.
+
+Calling BIO_free_all() a single BIO has the same effect as calling BIO_free()
+on it other than the discarded return value.
+
+Normally the B<type> argument is supplied by a function which returns a
+pointer to a BIO_METHOD. There is a naming convention for such functions:
+a source/sink BIO is normally called BIO_s_*() and a filter BIO
+BIO_f_*();
+
+=head1 EXAMPLE
+
+Create a memory BIO:
+
+ BIO *mem = BIO_new(BIO_s_mem());
+
+=head1 SEE ALSO
+
+TBA
diff --git a/openssl/doc/crypto/BIO_new_CMS.pod b/openssl/doc/crypto/BIO_new_CMS.pod
new file mode 100644
index 0000000..9e3a4b7
--- /dev/null
+++ b/openssl/doc/crypto/BIO_new_CMS.pod
@@ -0,0 +1,66 @@
+=pod
+
+=head1 NAME
+
+ BIO_new_CMS - CMS streaming filter BIO
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms);
+
+=head1 DESCRIPTION
+
+BIO_new_CMS() returns a streaming filter BIO chain based on B<cms>. The output
+of the filter is written to B<out>. Any data written to the chain is
+automatically translated to a BER format CMS structure of the appropriate type.
+
+=head1 NOTES
+
+The chain returned by this function behaves like a standard filter BIO. It
+supports non blocking I/O. Content is processed and streamed on the fly and not
+all held in memory at once: so it is possible to encode very large structures.
+After all content has been written through the chain BIO_flush() must be called
+to finalise the structure.
+
+The B<CMS_STREAM> flag must be included in the corresponding B<flags>
+parameter of the B<cms> creation function.
+
+If an application wishes to write additional data to B<out> BIOs should be
+removed from the chain using BIO_pop() and freed with BIO_free() until B<out>
+is reached. If no additional data needs to be written BIO_free_all() can be
+called to free up the whole chain.
+
+Any content written through the filter is used verbatim: no canonical
+translation is performed.
+
+It is possible to chain multiple BIOs to, for example, create a triple wrapped
+signed, enveloped, signed structure. In this case it is the applications
+responsibility to set the inner content type of any outer CMS_ContentInfo
+structures.
+
+Large numbers of small writes through the chain should be avoided as this will
+produce an output consisting of lots of OCTET STRING structures. Prepending
+a BIO_f_buffer() buffering BIO will prevent this.
+
+=head1 BUGS
+
+There is currently no corresponding inverse BIO: i.e. one which can decode
+a CMS structure on the fly.
+
+=head1 RETURN VALUES
+
+BIO_new_CMS() returns a BIO chain when successful or NULL if an error
+occurred. The error can be obtained from ERR_get_error(3).
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
+L<CMS_encrypt(3)|CMS_encrypt(3)>
+
+=head1 HISTORY
+
+BIO_new_CMS() was added to OpenSSL 1.0.0
+
+=cut
diff --git a/openssl/doc/crypto/BIO_push.pod b/openssl/doc/crypto/BIO_push.pod
new file mode 100644
index 0000000..8af1d3c
--- /dev/null
+++ b/openssl/doc/crypto/BIO_push.pod
@@ -0,0 +1,69 @@
+=pod
+
+=head1 NAME
+
+BIO_push, BIO_pop - add and remove BIOs from a chain.
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ BIO *	BIO_push(BIO *b,BIO *append);
+ BIO *	BIO_pop(BIO *b);
+
+=head1 DESCRIPTION
+
+The BIO_push() function appends the BIO B<append> to B<b>, it returns
+B<b>.
+
+BIO_pop() removes the BIO B<b> from a chain and returns the next BIO
+in the chain, or NULL if there is no next BIO. The removed BIO then
+becomes a single BIO with no association with the original chain,
+it can thus be freed or attached to a different chain.
+
+=head1 NOTES
+
+The names of these functions are perhaps a little misleading. BIO_push()
+joins two BIO chains whereas BIO_pop() deletes a single BIO from a chain,
+the deleted BIO does not need to be at the end of a chain.
+
+The process of calling BIO_push() and BIO_pop() on a BIO may have additional
+consequences (a control call is made to the affected BIOs) any effects will
+be noted in the descriptions of individual BIOs.
+
+=head1 EXAMPLES
+
+For these examples suppose B<md1> and B<md2> are digest BIOs, B<b64> is
+a base64 BIO and B<f> is a file BIO.
+
+If the call:
+
+ BIO_push(b64, f);
+
+is made then the new chain will be B<b64-chain>. After making the calls
+
+ BIO_push(md2, b64);
+ BIO_push(md1, md2);
+
+the new chain is B<md1-md2-b64-f>. Data written to B<md1> will be digested
+by B<md1> and B<md2>, B<base64> encoded and written to B<f>.
+
+It should be noted that reading causes data to pass in the reverse
+direction, that is data is read from B<f>, base64 B<decoded> and digested
+by B<md1> and B<md2>. If the call:
+
+ BIO_pop(md2);
+
+The call will return B<b64> and the new chain will be B<md1-b64-f> data can
+be written to B<md1> as before.
+
+=head1 RETURN VALUES
+
+BIO_push() returns the end of the chain, B<b>.
+
+BIO_pop() returns the next BIO in the chain, or NULL if there is no next
+BIO.
+
+=head1 SEE ALSO
+
+TBA
diff --git a/openssl/doc/crypto/BIO_read.pod b/openssl/doc/crypto/BIO_read.pod
new file mode 100644
index 0000000..b345281
--- /dev/null
+++ b/openssl/doc/crypto/BIO_read.pod
@@ -0,0 +1,66 @@
+=pod
+
+=head1 NAME
+
+BIO_read, BIO_write, BIO_gets, BIO_puts - BIO I/O functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ int	BIO_read(BIO *b, void *buf, int len);
+ int	BIO_gets(BIO *b,char *buf, int size);
+ int	BIO_write(BIO *b, const void *buf, int len);
+ int	BIO_puts(BIO *b,const char *buf);
+
+=head1 DESCRIPTION
+
+BIO_read() attempts to read B<len> bytes from BIO B<b> and places
+the data in B<buf>.
+
+BIO_gets() performs the BIOs "gets" operation and places the data
+in B<buf>. Usually this operation will attempt to read a line of data
+from the BIO of maximum length B<len>. There are exceptions to this
+however, for example BIO_gets() on a digest BIO will calculate and
+return the digest and other BIOs may not support BIO_gets() at all.
+
+BIO_write() attempts to write B<len> bytes from B<buf> to BIO B<b>.
+
+BIO_puts() attempts to write a null terminated string B<buf> to BIO B<b>
+
+=head1 RETURN VALUES
+
+All these functions return either the amount of data successfully read or
+written (if the return value is positive) or that no data was successfully
+read or written if the result is 0 or -1. If the return value is -2 then
+the operation is not implemented in the specific BIO type.
+
+=head1 NOTES
+
+A 0 or -1 return is not necessarily an indication of an error. In
+particular when the source/sink is non-blocking or of a certain type
+it may merely be an indication that no data is currently available and that
+the application should retry the operation later.
+
+One technique sometimes used with blocking sockets is to use a system call
+(such as select(), poll() or equivalent) to determine when data is available
+and then call read() to read the data. The equivalent with BIOs (that is call
+select() on the underlying I/O structure and then call BIO_read() to
+read the data) should B<not> be used because a single call to BIO_read()
+can cause several reads (and writes in the case of SSL BIOs) on the underlying
+I/O structure and may block as a result. Instead select() (or equivalent)
+should be combined with non blocking I/O so successive reads will request
+a retry instead of blocking.
+
+See L<BIO_should_retry(3)|BIO_should_retry(3)> for details of how to
+determine the cause of a retry and other I/O issues.
+
+If the BIO_gets() function is not supported by a BIO then it possible to
+work around this by adding a buffering BIO L<BIO_f_buffer(3)|BIO_f_buffer(3)>
+to the chain.
+
+=head1 SEE ALSO
+
+L<BIO_should_retry(3)|BIO_should_retry(3)>
+
+TBA
diff --git a/openssl/doc/crypto/BIO_s_accept.pod b/openssl/doc/crypto/BIO_s_accept.pod
new file mode 100644
index 0000000..7b63e46
--- /dev/null
+++ b/openssl/doc/crypto/BIO_s_accept.pod
@@ -0,0 +1,195 @@
+=pod
+
+=head1 NAME
+
+BIO_s_accept, BIO_set_accept_port, BIO_get_accept_port,
+BIO_set_nbio_accept, BIO_set_accept_bios, BIO_set_bind_mode,
+BIO_get_bind_mode, BIO_do_accept - accept BIO
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ BIO_METHOD *BIO_s_accept(void);
+
+ long BIO_set_accept_port(BIO *b, char *name);
+ char *BIO_get_accept_port(BIO *b);
+
+ BIO *BIO_new_accept(char *host_port);
+
+ long BIO_set_nbio_accept(BIO *b, int n);
+ long BIO_set_accept_bios(BIO *b, char *bio);
+
+ long BIO_set_bind_mode(BIO *b, long mode);
+ long BIO_get_bind_mode(BIO *b, long dummy);
+
+ #define BIO_BIND_NORMAL		0
+ #define BIO_BIND_REUSEADDR_IF_UNUSED	1
+ #define BIO_BIND_REUSEADDR		2
+
+ int BIO_do_accept(BIO *b);
+
+=head1 DESCRIPTION
+
+BIO_s_accept() returns the accept BIO method. This is a wrapper
+round the platform's TCP/IP socket accept routines.
+
+Using accept BIOs, TCP/IP connections can be accepted and data
+transferred using only BIO routines. In this way any platform
+specific operations are hidden by the BIO abstraction.
+
+Read and write operations on an accept BIO will perform I/O
+on the underlying connection. If no connection is established
+and the port (see below) is set up properly then the BIO
+waits for an incoming connection.
+
+Accept BIOs support BIO_puts() but not BIO_gets().
+
+If the close flag is set on an accept BIO then any active
+connection on that chain is shutdown and the socket closed when
+the BIO is freed.
+
+Calling BIO_reset() on a accept BIO will close any active
+connection and reset the BIO into a state where it awaits another
+incoming connection.
+
+BIO_get_fd() and BIO_set_fd() can be called to retrieve or set
+the accept socket. See L<BIO_s_fd(3)|BIO_s_fd(3)>
+
+BIO_set_accept_port() uses the string B<name> to set the accept
+port. The port is represented as a string of the form "host:port",
+where "host" is the interface to use and "port" is the port.
+Either or both values can be "*" which is interpreted as meaning
+any interface or port respectively. "port" has the same syntax
+as the port specified in BIO_set_conn_port() for connect BIOs,
+that is it can be a numerical port string or a string to lookup
+using getservbyname() and a string table.
+
+BIO_new_accept() combines BIO_new() and BIO_set_accept_port() into
+a single call: that is it creates a new accept BIO with port
+B<host_port>.
+
+BIO_set_nbio_accept() sets the accept socket to blocking mode
+(the default) if B<n> is 0 or non blocking mode if B<n> is 1.
+
+BIO_set_accept_bios() can be used to set a chain of BIOs which
+will be duplicated and prepended to the chain when an incoming
+connection is received. This is useful if, for example, a 
+buffering or SSL BIO is required for each connection. The
+chain of BIOs must not be freed after this call, they will
+be automatically freed when the accept BIO is freed.
+
+BIO_set_bind_mode() and BIO_get_bind_mode() set and retrieve
+the current bind mode. If BIO_BIND_NORMAL (the default) is set
+then another socket cannot be bound to the same port. If
+BIO_BIND_REUSEADDR is set then other sockets can bind to the
+same port. If BIO_BIND_REUSEADDR_IF_UNUSED is set then and
+attempt is first made to use BIO_BIN_NORMAL, if this fails
+and the port is not in use then a second attempt is made
+using BIO_BIND_REUSEADDR.
+
+BIO_do_accept() serves two functions. When it is first
+called, after the accept BIO has been setup, it will attempt
+to create the accept socket and bind an address to it. Second
+and subsequent calls to BIO_do_accept() will await an incoming
+connection, or request a retry in non blocking mode.
+
+=head1 NOTES
+
+When an accept BIO is at the end of a chain it will await an
+incoming connection before processing I/O calls. When an accept
+BIO is not at then end of a chain it passes I/O calls to the next
+BIO in the chain.
+
+When a connection is established a new socket BIO is created for
+the connection and appended to the chain. That is the chain is now
+accept->socket. This effectively means that attempting I/O on
+an initial accept socket will await an incoming connection then
+perform I/O on it.
+
+If any additional BIOs have been set using BIO_set_accept_bios()
+then they are placed between the socket and the accept BIO,
+that is the chain will be accept->otherbios->socket.
+
+If a server wishes to process multiple connections (as is normally
+the case) then the accept BIO must be made available for further
+incoming connections. This can be done by waiting for a connection and
+then calling:
+
+ connection = BIO_pop(accept);
+
+After this call B<connection> will contain a BIO for the recently
+established connection and B<accept> will now be a single BIO
+again which can be used to await further incoming connections.
+If no further connections will be accepted the B<accept> can
+be freed using BIO_free().
+
+If only a single connection will be processed it is possible to
+perform I/O using the accept BIO itself. This is often undesirable
+however because the accept BIO will still accept additional incoming
+connections. This can be resolved by using BIO_pop() (see above)
+and freeing up the accept BIO after the initial connection.
+
+If the underlying accept socket is non-blocking and BIO_do_accept() is
+called to await an incoming connection it is possible for
+BIO_should_io_special() with the reason BIO_RR_ACCEPT. If this happens
+then it is an indication that an accept attempt would block: the application
+should take appropriate action to wait until the underlying socket has
+accepted a connection and retry the call.
+
+BIO_set_accept_port(), BIO_get_accept_port(), BIO_set_nbio_accept(),
+BIO_set_accept_bios(), BIO_set_bind_mode(), BIO_get_bind_mode() and
+BIO_do_accept() are macros.
+
+=head1 RETURN VALUES
+
+TBA
+
+=head1 EXAMPLE
+
+This example accepts two connections on port 4444, sends messages
+down each and finally closes both down.
+
+ BIO *abio, *cbio, *cbio2;
+ ERR_load_crypto_strings();
+ abio = BIO_new_accept("4444");
+
+ /* First call to BIO_accept() sets up accept BIO */
+ if(BIO_do_accept(abio) <= 0) {
+	fprintf(stderr, "Error setting up accept\n");
+	ERR_print_errors_fp(stderr);
+	exit(0);		
+ }
+
+ /* Wait for incoming connection */
+ if(BIO_do_accept(abio) <= 0) {
+	fprintf(stderr, "Error accepting connection\n");
+	ERR_print_errors_fp(stderr);
+	exit(0);		
+ }
+ fprintf(stderr, "Connection 1 established\n");
+ /* Retrieve BIO for connection */
+ cbio = BIO_pop(abio);
+ BIO_puts(cbio, "Connection 1: Sending out Data on initial connection\n");
+ fprintf(stderr, "Sent out data on connection 1\n");
+ /* Wait for another connection */
+ if(BIO_do_accept(abio) <= 0) {
+	fprintf(stderr, "Error accepting connection\n");
+	ERR_print_errors_fp(stderr);
+	exit(0);		
+ }
+ fprintf(stderr, "Connection 2 established\n");
+ /* Close accept BIO to refuse further connections */
+ cbio2 = BIO_pop(abio);
+ BIO_free(abio);
+ BIO_puts(cbio2, "Connection 2: Sending out Data on second\n");
+ fprintf(stderr, "Sent out data on connection 2\n");
+
+ BIO_puts(cbio, "Connection 1: Second connection established\n");
+ /* Close the two established connections */
+ BIO_free(cbio);
+ BIO_free(cbio2);
+
+=head1 SEE ALSO
+
+TBA
diff --git a/openssl/doc/crypto/BIO_s_bio.pod b/openssl/doc/crypto/BIO_s_bio.pod
new file mode 100644
index 0000000..8d0a55a
--- /dev/null
+++ b/openssl/doc/crypto/BIO_s_bio.pod
@@ -0,0 +1,182 @@
+=pod
+
+=head1 NAME
+
+BIO_s_bio, BIO_make_bio_pair, BIO_destroy_bio_pair, BIO_shutdown_wr, 
+BIO_set_write_buf_size, BIO_get_write_buf_size, BIO_new_bio_pair,
+BIO_get_write_guarantee, BIO_ctrl_get_write_guarantee, BIO_get_read_request,
+BIO_ctrl_get_read_request, BIO_ctrl_reset_read_request - BIO pair BIO
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ BIO_METHOD *BIO_s_bio(void);
+
+ #define BIO_make_bio_pair(b1,b2)   (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2)
+ #define BIO_destroy_bio_pair(b)    (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL)
+
+ #define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL)
+
+ #define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL)
+ #define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL)
+
+ int BIO_new_bio_pair(BIO **bio1, size_t writebuf1, BIO **bio2, size_t writebuf2);
+
+ #define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL)
+ size_t BIO_ctrl_get_write_guarantee(BIO *b);
+
+ #define BIO_get_read_request(b)    (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL)
+ size_t BIO_ctrl_get_read_request(BIO *b);
+
+ int BIO_ctrl_reset_read_request(BIO *b);
+
+=head1 DESCRIPTION
+
+BIO_s_bio() returns the method for a BIO pair. A BIO pair is a pair of source/sink
+BIOs where data written to either half of the pair is buffered and can be read from
+the other half. Both halves must usually by handled by the same application thread
+since no locking is done on the internal data structures.
+
+Since BIO chains typically end in a source/sink BIO it is possible to make this
+one half of a BIO pair and have all the data processed by the chain under application
+control.
+
+One typical use of BIO pairs is to place TLS/SSL I/O under application control, this
+can be used when the application wishes to use a non standard transport for
+TLS/SSL or the normal socket routines are inappropriate.
+
+Calls to BIO_read() will read data from the buffer or request a retry if no
+data is available.
+
+Calls to BIO_write() will place data in the buffer or request a retry if the
+buffer is full.
+
+The standard calls BIO_ctrl_pending() and BIO_ctrl_wpending() can be used to
+determine the amount of pending data in the read or write buffer.
+
+BIO_reset() clears any data in the write buffer.
+
+BIO_make_bio_pair() joins two separate BIOs into a connected pair.
+
+BIO_destroy_pair() destroys the association between two connected BIOs. Freeing
+up any half of the pair will automatically destroy the association.
+
+BIO_shutdown_wr() is used to close down a BIO B<b>. After this call no further
+writes on BIO B<b> are allowed (they will return an error). Reads on the other
+half of the pair will return any pending data or EOF when all pending data has
+been read. 
+
+BIO_set_write_buf_size() sets the write buffer size of BIO B<b> to B<size>.
+If the size is not initialized a default value is used. This is currently
+17K, sufficient for a maximum size TLS record.
+
+BIO_get_write_buf_size() returns the size of the write buffer.
+
+BIO_new_bio_pair() combines the calls to BIO_new(), BIO_make_bio_pair() and
+BIO_set_write_buf_size() to create a connected pair of BIOs B<bio1>, B<bio2>
+with write buffer sizes B<writebuf1> and B<writebuf2>. If either size is
+zero then the default size is used.  BIO_new_bio_pair() does not check whether
+B<bio1> or B<bio2> do point to some other BIO, the values are overwritten,
+BIO_free() is not called.
+
+BIO_get_write_guarantee() and BIO_ctrl_get_write_guarantee() return the maximum
+length of data that can be currently written to the BIO. Writes larger than this
+value will return a value from BIO_write() less than the amount requested or if the
+buffer is full request a retry. BIO_ctrl_get_write_guarantee() is a function
+whereas BIO_get_write_guarantee() is a macro.
+
+BIO_get_read_request() and BIO_ctrl_get_read_request() return the
+amount of data requested, or the buffer size if it is less, if the
+last read attempt at the other half of the BIO pair failed due to an
+empty buffer.  This can be used to determine how much data should be
+written to the BIO so the next read will succeed: this is most useful
+in TLS/SSL applications where the amount of data read is usually
+meaningful rather than just a buffer size. After a successful read
+this call will return zero.  It also will return zero once new data
+has been written satisfying the read request or part of it.
+Note that BIO_get_read_request() never returns an amount larger
+than that returned by BIO_get_write_guarantee().
+
+BIO_ctrl_reset_read_request() can also be used to reset the value returned by
+BIO_get_read_request() to zero.
+
+=head1 NOTES
+
+Both halves of a BIO pair should be freed. That is even if one half is implicit
+freed due to a BIO_free_all() or SSL_free() call the other half needs to be freed.
+
+When used in bidirectional applications (such as TLS/SSL) care should be taken to
+flush any data in the write buffer. This can be done by calling BIO_pending()
+on the other half of the pair and, if any data is pending, reading it and sending
+it to the underlying transport. This must be done before any normal processing
+(such as calling select() ) due to a request and BIO_should_read() being true.
+
+To see why this is important consider a case where a request is sent using
+BIO_write() and a response read with BIO_read(), this can occur during an
+TLS/SSL handshake for example. BIO_write() will succeed and place data in the write
+buffer. BIO_read() will initially fail and BIO_should_read() will be true. If
+the application then waits for data to be available on the underlying transport
+before flushing the write buffer it will never succeed because the request was
+never sent!
+
+=head1 RETURN VALUES
+
+BIO_new_bio_pair() returns 1 on success, with the new BIOs available in
+B<bio1> and B<bio2>, or 0 on failure, with NULL pointers stored into the
+locations for B<bio1> and B<bio2>. Check the error stack for more information.
+
+[XXXXX: More return values need to be added here]
+
+=head1 EXAMPLE
+
+The BIO pair can be used to have full control over the network access of an
+application. The application can call select() on the socket as required
+without having to go through the SSL-interface.
+
+ BIO *internal_bio, *network_bio;
+ ...
+ BIO_new_bio_pair(internal_bio, 0, network_bio, 0);
+ SSL_set_bio(ssl, internal_bio, internal_bio);
+ SSL_operations();
+ ...
+
+ application |   TLS-engine
+    |        |
+    +----------> SSL_operations()
+             |     /\    ||
+             |     ||    \/
+             |   BIO-pair (internal_bio)
+    +----------< BIO-pair (network_bio)
+    |        |
+  socket     |
+
+  ...
+  SSL_free(ssl);		/* implicitly frees internal_bio */
+  BIO_free(network_bio);
+  ...
+
+As the BIO pair will only buffer the data and never directly access the
+connection, it behaves non-blocking and will return as soon as the write
+buffer is full or the read buffer is drained. Then the application has to
+flush the write buffer and/or fill the read buffer.
+
+Use the BIO_ctrl_pending(), to find out whether data is buffered in the BIO
+and must be transfered to the network. Use BIO_ctrl_get_read_request() to
+find out, how many bytes must be written into the buffer before the
+SSL_operation() can successfully be continued.
+
+=head1 WARNING
+
+As the data is buffered, SSL_operation() may return with a ERROR_SSL_WANT_READ
+condition, but there is still data in the write buffer. An application must
+not rely on the error value of SSL_operation() but must assure that the
+write buffer is always flushed first. Otherwise a deadlock may occur as
+the peer might be waiting for the data before being able to continue.
+
+=head1 SEE ALSO
+
+L<SSL_set_bio(3)|SSL_set_bio(3)>, L<ssl(3)|ssl(3)>, L<bio(3)|bio(3)>,
+L<BIO_should_retry(3)|BIO_should_retry(3)>, L<BIO_read(3)|BIO_read(3)>
+
+=cut
diff --git a/openssl/doc/crypto/BIO_s_connect.pod b/openssl/doc/crypto/BIO_s_connect.pod
new file mode 100644
index 0000000..bcf7d8d
--- /dev/null
+++ b/openssl/doc/crypto/BIO_s_connect.pod
@@ -0,0 +1,192 @@
+=pod
+
+=head1 NAME
+
+BIO_s_connect, BIO_set_conn_hostname, BIO_set_conn_port,
+BIO_set_conn_ip, BIO_set_conn_int_port, BIO_get_conn_hostname,
+BIO_get_conn_port, BIO_get_conn_ip, BIO_get_conn_int_port,
+BIO_set_nbio, BIO_do_connect - connect BIO
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ BIO_METHOD * BIO_s_connect(void);
+
+ BIO *BIO_new_connect(char *name);
+
+ long BIO_set_conn_hostname(BIO *b, char *name);
+ long BIO_set_conn_port(BIO *b, char *port);
+ long BIO_set_conn_ip(BIO *b, char *ip);
+ long BIO_set_conn_int_port(BIO *b, char *port);
+ char *BIO_get_conn_hostname(BIO *b);
+ char *BIO_get_conn_port(BIO *b);
+ char *BIO_get_conn_ip(BIO *b, dummy);
+ long BIO_get_conn_int_port(BIO *b, int port);
+
+ long BIO_set_nbio(BIO *b, long n);
+
+ int BIO_do_connect(BIO *b);
+
+=head1 DESCRIPTION
+
+BIO_s_connect() returns the connect BIO method. This is a wrapper
+round the platform's TCP/IP socket connection routines.
+
+Using connect BIOs, TCP/IP connections can be made and data
+transferred using only BIO routines. In this way any platform
+specific operations are hidden by the BIO abstraction.
+
+Read and write operations on a connect BIO will perform I/O
+on the underlying connection. If no connection is established
+and the port and hostname (see below) is set up properly then
+a connection is established first.
+
+Connect BIOs support BIO_puts() but not BIO_gets().
+
+If the close flag is set on a connect BIO then any active
+connection is shutdown and the socket closed when the BIO
+is freed.
+
+Calling BIO_reset() on a connect BIO will close any active
+connection and reset the BIO into a state where it can connect
+to the same host again.
+
+BIO_get_fd() places the underlying socket in B<c> if it is not NULL,
+it also returns the socket . If B<c> is not NULL it should be of
+type (int *).
+
+BIO_set_conn_hostname() uses the string B<name> to set the hostname.
+The hostname can be an IP address. The hostname can also include the
+port in the form hostname:port . It is also acceptable to use the
+form "hostname/any/other/path" or "hostname:port/any/other/path".
+
+BIO_set_conn_port() sets the port to B<port>. B<port> can be the
+numerical form or a string such as "http". A string will be looked
+up first using getservbyname() on the host platform but if that
+fails a standard table of port names will be used. Currently the
+list is http, telnet, socks, https, ssl, ftp, gopher and wais.
+
+BIO_set_conn_ip() sets the IP address to B<ip> using binary form,
+that is four bytes specifying the IP address in big-endian form.
+
+BIO_set_conn_int_port() sets the port using B<port>. B<port> should
+be of type (int *).
+
+BIO_get_conn_hostname() returns the hostname of the connect BIO or
+NULL if the BIO is initialized but no hostname is set.
+This return value is an internal pointer which should not be modified.
+
+BIO_get_conn_port() returns the port as a string.
+
+BIO_get_conn_ip() returns the IP address in binary form.
+
+BIO_get_conn_int_port() returns the port as an int.
+
+BIO_set_nbio() sets the non blocking I/O flag to B<n>. If B<n> is
+zero then blocking I/O is set. If B<n> is 1 then non blocking I/O
+is set. Blocking I/O is the default. The call to BIO_set_nbio()
+should be made before the connection is established because 
+non blocking I/O is set during the connect process.
+
+BIO_new_connect() combines BIO_new() and BIO_set_conn_hostname() into
+a single call: that is it creates a new connect BIO with B<name>.
+
+BIO_do_connect() attempts to connect the supplied BIO. It returns 1
+if the connection was established successfully. A zero or negative
+value is returned if the connection could not be established, the
+call BIO_should_retry() should be used for non blocking connect BIOs
+to determine if the call should be retried.
+
+=head1 NOTES
+
+If blocking I/O is set then a non positive return value from any
+I/O call is caused by an error condition, although a zero return
+will normally mean that the connection was closed.
+
+If the port name is supplied as part of the host name then this will
+override any value set with BIO_set_conn_port(). This may be undesirable
+if the application does not wish to allow connection to arbitrary
+ports. This can be avoided by checking for the presence of the ':'
+character in the passed hostname and either indicating an error or
+truncating the string at that point.
+
+The values returned by BIO_get_conn_hostname(), BIO_get_conn_port(),
+BIO_get_conn_ip() and BIO_get_conn_int_port() are updated when a
+connection attempt is made. Before any connection attempt the values
+returned are those set by the application itself.
+
+Applications do not have to call BIO_do_connect() but may wish to do
+so to separate the connection process from other I/O processing.
+
+If non blocking I/O is set then retries will be requested as appropriate.
+
+It addition to BIO_should_read() and BIO_should_write() it is also
+possible for BIO_should_io_special() to be true during the initial
+connection process with the reason BIO_RR_CONNECT. If this is returned
+then this is an indication that a connection attempt would block,
+the application should then take appropriate action to wait until
+the underlying socket has connected and retry the call.
+
+BIO_set_conn_hostname(), BIO_set_conn_port(), BIO_set_conn_ip(),
+BIO_set_conn_int_port(), BIO_get_conn_hostname(), BIO_get_conn_port(),
+BIO_get_conn_ip(), BIO_get_conn_int_port(), BIO_set_nbio() and
+BIO_do_connect() are macros.
+
+=head1 RETURN VALUES
+
+BIO_s_connect() returns the connect BIO method.
+
+BIO_get_fd() returns the socket or -1 if the BIO has not
+been initialized.
+
+BIO_set_conn_hostname(), BIO_set_conn_port(), BIO_set_conn_ip() and
+BIO_set_conn_int_port() always return 1.
+
+BIO_get_conn_hostname() returns the connected hostname or NULL is
+none was set.
+
+BIO_get_conn_port() returns a string representing the connected
+port or NULL if not set.
+
+BIO_get_conn_ip() returns a pointer to the connected IP address in
+binary form or all zeros if not set.
+
+BIO_get_conn_int_port() returns the connected port or 0 if none was
+set.
+
+BIO_set_nbio() always returns 1.
+
+BIO_do_connect() returns 1 if the connection was successfully
+established and 0 or -1 if the connection failed.
+
+=head1 EXAMPLE
+
+This is example connects to a webserver on the local host and attempts
+to retrieve a page and copy the result to standard output.
+
+
+ BIO *cbio, *out;
+ int len;
+ char tmpbuf[1024];
+ ERR_load_crypto_strings();
+ cbio = BIO_new_connect("localhost:http");
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+ if(BIO_do_connect(cbio) <= 0) {
+	fprintf(stderr, "Error connecting to server\n");
+	ERR_print_errors_fp(stderr);
+	/* whatever ... */
+	}
+ BIO_puts(cbio, "GET / HTTP/1.0\n\n");
+ for(;;) {	
+	len = BIO_read(cbio, tmpbuf, 1024);
+	if(len <= 0) break;
+	BIO_write(out, tmpbuf, len);
+ }
+ BIO_free(cbio);
+ BIO_free(out);
+
+
+=head1 SEE ALSO
+
+TBA
diff --git a/openssl/doc/crypto/BIO_s_fd.pod b/openssl/doc/crypto/BIO_s_fd.pod
new file mode 100644
index 0000000..b1de1d1
--- /dev/null
+++ b/openssl/doc/crypto/BIO_s_fd.pod
@@ -0,0 +1,89 @@
+=pod
+
+=head1 NAME
+
+BIO_s_fd, BIO_set_fd, BIO_get_fd, BIO_new_fd - file descriptor BIO
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ BIO_METHOD *	BIO_s_fd(void);
+
+ #define BIO_set_fd(b,fd,c)	BIO_int_ctrl(b,BIO_C_SET_FD,c,fd)
+ #define BIO_get_fd(b,c)	BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c)
+
+ BIO *BIO_new_fd(int fd, int close_flag);
+
+=head1 DESCRIPTION
+
+BIO_s_fd() returns the file descriptor BIO method. This is a wrapper
+round the platforms file descriptor routines such as read() and write().
+
+BIO_read() and BIO_write() read or write the underlying descriptor.
+BIO_puts() is supported but BIO_gets() is not.
+
+If the close flag is set then then close() is called on the underlying
+file descriptor when the BIO is freed.
+
+BIO_reset() attempts to change the file pointer to the start of file
+using lseek(fd, 0, 0).
+
+BIO_seek() sets the file pointer to position B<ofs> from start of file
+using lseek(fd, ofs, 0).
+
+BIO_tell() returns the current file position by calling lseek(fd, 0, 1).
+
+BIO_set_fd() sets the file descriptor of BIO B<b> to B<fd> and the close
+flag to B<c>.
+
+BIO_get_fd() places the file descriptor in B<c> if it is not NULL, it also
+returns the file descriptor. If B<c> is not NULL it should be of type
+(int *).
+
+BIO_new_fd() returns a file descriptor BIO using B<fd> and B<close_flag>.
+
+=head1 NOTES
+
+The behaviour of BIO_read() and BIO_write() depends on the behavior of the
+platforms read() and write() calls on the descriptor. If the underlying 
+file descriptor is in a non blocking mode then the BIO will behave in the
+manner described in the L<BIO_read(3)|BIO_read(3)> and L<BIO_should_retry(3)|BIO_should_retry(3)>
+manual pages.
+
+File descriptor BIOs should not be used for socket I/O. Use socket BIOs
+instead.
+
+=head1 RETURN VALUES
+
+BIO_s_fd() returns the file descriptor BIO method.
+
+BIO_reset() returns zero for success and -1 if an error occurred.
+BIO_seek() and BIO_tell() return the current file position or -1
+is an error occurred. These values reflect the underlying lseek()
+behaviour.
+
+BIO_set_fd() always returns 1.
+
+BIO_get_fd() returns the file descriptor or -1 if the BIO has not
+been initialized.
+
+BIO_new_fd() returns the newly allocated BIO or NULL is an error
+occurred.
+
+=head1 EXAMPLE
+
+This is a file descriptor BIO version of "Hello World":
+
+ BIO *out;
+ out = BIO_new_fd(fileno(stdout), BIO_NOCLOSE);
+ BIO_printf(out, "Hello World\n");
+ BIO_free(out);
+
+=head1 SEE ALSO
+
+L<BIO_seek(3)|BIO_seek(3)>, L<BIO_tell(3)|BIO_tell(3)>,
+L<BIO_reset(3)|BIO_reset(3)>, L<BIO_read(3)|BIO_read(3)>,
+L<BIO_write(3)|BIO_write(3)>, L<BIO_puts(3)|BIO_puts(3)>,
+L<BIO_gets(3)|BIO_gets(3)>, L<BIO_printf(3)|BIO_printf(3)>,
+L<BIO_set_close(3)|BIO_set_close(3)>, L<BIO_get_close(3)|BIO_get_close(3)>
diff --git a/openssl/doc/crypto/BIO_s_file.pod b/openssl/doc/crypto/BIO_s_file.pod
new file mode 100644
index 0000000..188aea3
--- /dev/null
+++ b/openssl/doc/crypto/BIO_s_file.pod
@@ -0,0 +1,148 @@
+=pod
+
+=head1 NAME
+
+BIO_s_file, BIO_new_file, BIO_new_fp, BIO_set_fp, BIO_get_fp,
+BIO_read_filename, BIO_write_filename, BIO_append_filename,
+BIO_rw_filename - FILE bio
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ BIO_METHOD *	BIO_s_file(void);
+ BIO *BIO_new_file(const char *filename, const char *mode);
+ BIO *BIO_new_fp(FILE *stream, int flags);
+
+ BIO_set_fp(BIO *b,FILE *fp, int flags);
+ BIO_get_fp(BIO *b,FILE **fpp);
+
+ int BIO_read_filename(BIO *b, char *name)
+ int BIO_write_filename(BIO *b, char *name)
+ int BIO_append_filename(BIO *b, char *name)
+ int BIO_rw_filename(BIO *b, char *name)
+
+=head1 DESCRIPTION
+
+BIO_s_file() returns the BIO file method. As its name implies it
+is a wrapper round the stdio FILE structure and it is a
+source/sink BIO.
+
+Calls to BIO_read() and BIO_write() read and write data to the
+underlying stream. BIO_gets() and BIO_puts() are supported on file BIOs.
+
+BIO_flush() on a file BIO calls the fflush() function on the wrapped
+stream.
+
+BIO_reset() attempts to change the file pointer to the start of file
+using fseek(stream, 0, 0).
+
+BIO_seek() sets the file pointer to position B<ofs> from start of file
+using fseek(stream, ofs, 0).
+
+BIO_eof() calls feof().
+
+Setting the BIO_CLOSE flag calls fclose() on the stream when the BIO
+is freed.
+
+BIO_new_file() creates a new file BIO with mode B<mode> the meaning
+of B<mode> is the same as the stdio function fopen(). The BIO_CLOSE
+flag is set on the returned BIO.
+
+BIO_new_fp() creates a file BIO wrapping B<stream>. Flags can be:
+BIO_CLOSE, BIO_NOCLOSE (the close flag) BIO_FP_TEXT (sets the underlying
+stream to text mode, default is binary: this only has any effect under
+Win32).
+
+BIO_set_fp() set the fp of a file BIO to B<fp>. B<flags> has the same
+meaning as in BIO_new_fp(), it is a macro.
+
+BIO_get_fp() retrieves the fp of a file BIO, it is a macro.
+
+BIO_seek() is a macro that sets the position pointer to B<offset> bytes
+from the start of file.
+
+BIO_tell() returns the value of the position pointer.
+
+BIO_read_filename(), BIO_write_filename(), BIO_append_filename() and
+BIO_rw_filename() set the file BIO B<b> to use file B<name> for
+reading, writing, append or read write respectively.
+
+=head1 NOTES
+
+When wrapping stdout, stdin or stderr the underlying stream should not
+normally be closed so the BIO_NOCLOSE flag should be set.
+
+Because the file BIO calls the underlying stdio functions any quirks
+in stdio behaviour will be mirrored by the corresponding BIO.
+
+On Windows BIO_new_files reserves for the filename argument to be
+UTF-8 encoded. In other words if you have to make it work in multi-
+lingual environment, encode file names in UTF-8.
+
+=head1 EXAMPLES
+
+File BIO "hello world":
+
+ BIO *bio_out;
+ bio_out = BIO_new_fp(stdout, BIO_NOCLOSE);
+ BIO_printf(bio_out, "Hello World\n");
+
+Alternative technique:
+
+ BIO *bio_out;
+ bio_out = BIO_new(BIO_s_file());
+ if(bio_out == NULL) /* Error ... */
+ if(!BIO_set_fp(bio_out, stdout, BIO_NOCLOSE)) /* Error ... */
+ BIO_printf(bio_out, "Hello World\n");
+
+Write to a file:
+
+ BIO *out;
+ out = BIO_new_file("filename.txt", "w");
+ if(!out) /* Error occurred */
+ BIO_printf(out, "Hello World\n");
+ BIO_free(out);
+
+Alternative technique:
+
+ BIO *out;
+ out = BIO_new(BIO_s_file());
+ if(out == NULL) /* Error ... */
+ if(!BIO_write_filename(out, "filename.txt")) /* Error ... */
+ BIO_printf(out, "Hello World\n");
+ BIO_free(out);
+
+=head1 RETURN VALUES
+
+BIO_s_file() returns the file BIO method.
+
+BIO_new_file() and BIO_new_fp() return a file BIO or NULL if an error
+occurred.
+
+BIO_set_fp() and BIO_get_fp() return 1 for success or 0 for failure
+(although the current implementation never return 0).
+
+BIO_seek() returns the same value as the underlying fseek() function:
+0 for success or -1 for failure.
+
+BIO_tell() returns the current file position.
+
+BIO_read_filename(), BIO_write_filename(),  BIO_append_filename() and
+BIO_rw_filename() return 1 for success or 0 for failure.
+
+=head1 BUGS
+
+BIO_reset() and BIO_seek() are implemented using fseek() on the underlying
+stream. The return value for fseek() is 0 for success or -1 if an error
+occurred this differs from other types of BIO which will typically return
+1 for success and a non positive value if an error occurred.
+
+=head1 SEE ALSO
+
+L<BIO_seek(3)|BIO_seek(3)>, L<BIO_tell(3)|BIO_tell(3)>,
+L<BIO_reset(3)|BIO_reset(3)>, L<BIO_flush(3)|BIO_flush(3)>,
+L<BIO_read(3)|BIO_read(3)>,
+L<BIO_write(3)|BIO_write(3)>, L<BIO_puts(3)|BIO_puts(3)>,
+L<BIO_gets(3)|BIO_gets(3)>, L<BIO_printf(3)|BIO_printf(3)>,
+L<BIO_set_close(3)|BIO_set_close(3)>, L<BIO_get_close(3)|BIO_get_close(3)>
diff --git a/openssl/doc/crypto/BIO_s_mem.pod b/openssl/doc/crypto/BIO_s_mem.pod
new file mode 100644
index 0000000..8f85e0d
--- /dev/null
+++ b/openssl/doc/crypto/BIO_s_mem.pod
@@ -0,0 +1,115 @@
+=pod
+
+=head1 NAME
+
+BIO_s_mem, BIO_set_mem_eof_return, BIO_get_mem_data, BIO_set_mem_buf,
+BIO_get_mem_ptr, BIO_new_mem_buf - memory BIO
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ BIO_METHOD *	BIO_s_mem(void);
+
+ BIO_set_mem_eof_return(BIO *b,int v)
+ long BIO_get_mem_data(BIO *b, char **pp)
+ BIO_set_mem_buf(BIO *b,BUF_MEM *bm,int c)
+ BIO_get_mem_ptr(BIO *b,BUF_MEM **pp)
+
+ BIO *BIO_new_mem_buf(void *buf, int len);
+
+=head1 DESCRIPTION
+
+BIO_s_mem() return the memory BIO method function. 
+
+A memory BIO is a source/sink BIO which uses memory for its I/O. Data
+written to a memory BIO is stored in a BUF_MEM structure which is extended
+as appropriate to accommodate the stored data.
+
+Any data written to a memory BIO can be recalled by reading from it.
+Unless the memory BIO is read only any data read from it is deleted from
+the BIO.
+
+Memory BIOs support BIO_gets() and BIO_puts().
+
+If the BIO_CLOSE flag is set when a memory BIO is freed then the underlying
+BUF_MEM structure is also freed.
+
+Calling BIO_reset() on a read write memory BIO clears any data in it. On a
+read only BIO it restores the BIO to its original state and the read only
+data can be read again.
+
+BIO_eof() is true if no data is in the BIO.
+
+BIO_ctrl_pending() returns the number of bytes currently stored.
+
+BIO_set_mem_eof_return() sets the behaviour of memory BIO B<b> when it is
+empty. If the B<v> is zero then an empty memory BIO will return EOF (that is
+it will return zero and BIO_should_retry(b) will be false. If B<v> is non
+zero then it will return B<v> when it is empty and it will set the read retry
+flag (that is BIO_read_retry(b) is true). To avoid ambiguity with a normal
+positive return value B<v> should be set to a negative value, typically -1.
+
+BIO_get_mem_data() sets B<pp> to a pointer to the start of the memory BIOs data
+and returns the total amount of data available. It is implemented as a macro.
+
+BIO_set_mem_buf() sets the internal BUF_MEM structure to B<bm> and sets the
+close flag to B<c>, that is B<c> should be either BIO_CLOSE or BIO_NOCLOSE.
+It is a macro.
+
+BIO_get_mem_ptr() places the underlying BUF_MEM structure in B<pp>. It is
+a macro.
+
+BIO_new_mem_buf() creates a memory BIO using B<len> bytes of data at B<buf>,
+if B<len> is -1 then the B<buf> is assumed to be null terminated and its
+length is determined by B<strlen>. The BIO is set to a read only state and
+as a result cannot be written to. This is useful when some data needs to be
+made available from a static area of memory in the form of a BIO. The
+supplied data is read directly from the supplied buffer: it is B<not> copied
+first, so the supplied area of memory must be unchanged until the BIO is freed.
+
+=head1 NOTES
+
+Writes to memory BIOs will always succeed if memory is available: that is
+their size can grow indefinitely.
+
+Every read from a read write memory BIO will remove the data just read with
+an internal copy operation, if a BIO contains a lot of data and it is
+read in small chunks the operation can be very slow. The use of a read only
+memory BIO avoids this problem. If the BIO must be read write then adding
+a buffering BIO to the chain will speed up the process.
+
+=head1 BUGS
+
+There should be an option to set the maximum size of a memory BIO.
+
+There should be a way to "rewind" a read write BIO without destroying
+its contents.
+
+The copying operation should not occur after every small read of a large BIO
+to improve efficiency.
+
+=head1 EXAMPLE
+
+Create a memory BIO and write some data to it:
+
+ BIO *mem = BIO_new(BIO_s_mem());
+ BIO_puts(mem, "Hello World\n"); 
+
+Create a read only memory BIO:
+
+ char data[] = "Hello World";
+ BIO *mem;
+ mem = BIO_new_mem_buf(data, -1);
+
+Extract the BUF_MEM structure from a memory BIO and then free up the BIO:
+
+ BUF_MEM *bptr;
+ BIO_get_mem_ptr(mem, &bptr);
+ BIO_set_close(mem, BIO_NOCLOSE); /* So BIO_free() leaves BUF_MEM alone */
+ BIO_free(mem);
+ 
+
+=head1 SEE ALSO
+
+TBA
diff --git a/openssl/doc/crypto/BIO_s_null.pod b/openssl/doc/crypto/BIO_s_null.pod
new file mode 100644
index 0000000..e5514f7
--- /dev/null
+++ b/openssl/doc/crypto/BIO_s_null.pod
@@ -0,0 +1,37 @@
+=pod
+
+=head1 NAME
+
+BIO_s_null - null data sink
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ BIO_METHOD *	BIO_s_null(void);
+
+=head1 DESCRIPTION
+
+BIO_s_null() returns the null sink BIO method. Data written to
+the null sink is discarded, reads return EOF.
+
+=head1 NOTES
+
+A null sink BIO behaves in a similar manner to the Unix /dev/null
+device.
+
+A null bio can be placed on the end of a chain to discard any data
+passed through it.
+
+A null sink is useful if, for example, an application wishes to digest some
+data by writing through a digest bio but not send the digested data anywhere.
+Since a BIO chain must normally include a source/sink BIO this can be achieved
+by adding a null sink BIO to the end of the chain
+
+=head1 RETURN VALUES
+
+BIO_s_null() returns the null sink BIO method.
+
+=head1 SEE ALSO
+
+TBA
diff --git a/openssl/doc/crypto/BIO_s_socket.pod b/openssl/doc/crypto/BIO_s_socket.pod
new file mode 100644
index 0000000..1c8d3a9
--- /dev/null
+++ b/openssl/doc/crypto/BIO_s_socket.pod
@@ -0,0 +1,63 @@
+=pod
+
+=head1 NAME
+
+BIO_s_socket, BIO_new_socket - socket BIO
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ BIO_METHOD *BIO_s_socket(void);
+
+ long BIO_set_fd(BIO *b, int fd, long close_flag);
+ long BIO_get_fd(BIO *b, int *c);
+
+ BIO *BIO_new_socket(int sock, int close_flag);
+
+=head1 DESCRIPTION
+
+BIO_s_socket() returns the socket BIO method. This is a wrapper
+round the platform's socket routines.
+
+BIO_read() and BIO_write() read or write the underlying socket.
+BIO_puts() is supported but BIO_gets() is not.
+
+If the close flag is set then the socket is shut down and closed
+when the BIO is freed.
+
+BIO_set_fd() sets the socket of BIO B<b> to B<fd> and the close
+flag to B<close_flag>.
+
+BIO_get_fd() places the socket in B<c> if it is not NULL, it also
+returns the socket. If B<c> is not NULL it should be of type (int *).
+
+BIO_new_socket() returns a socket BIO using B<sock> and B<close_flag>.
+
+=head1 NOTES
+
+Socket BIOs also support any relevant functionality of file descriptor
+BIOs.
+
+The reason for having separate file descriptor and socket BIOs is that on some
+platforms sockets are not file descriptors and use distinct I/O routines,
+Windows is one such platform. Any code mixing the two will not work on
+all platforms.
+
+BIO_set_fd() and BIO_get_fd() are macros.
+
+=head1 RETURN VALUES
+
+BIO_s_socket() returns the socket BIO method.
+
+BIO_set_fd() always returns 1.
+
+BIO_get_fd() returns the socket or -1 if the BIO has not been
+initialized.
+
+BIO_new_socket() returns the newly allocated BIO or NULL is an error
+occurred.
+
+=head1 SEE ALSO
+
+TBA
diff --git a/openssl/doc/crypto/BIO_set_callback.pod b/openssl/doc/crypto/BIO_set_callback.pod
new file mode 100644
index 0000000..4759556
--- /dev/null
+++ b/openssl/doc/crypto/BIO_set_callback.pod
@@ -0,0 +1,108 @@
+=pod
+
+=head1 NAME
+
+BIO_set_callback, BIO_get_callback, BIO_set_callback_arg, BIO_get_callback_arg,
+BIO_debug_callback - BIO callback functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ #define BIO_set_callback(b,cb)		((b)->callback=(cb))
+ #define BIO_get_callback(b)		((b)->callback)
+ #define BIO_set_callback_arg(b,arg)	((b)->cb_arg=(char *)(arg))
+ #define BIO_get_callback_arg(b)		((b)->cb_arg)
+
+ long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
+	long argl,long ret);
+
+ typedef long (*callback)(BIO *b, int oper, const char *argp,
+			int argi, long argl, long retvalue);
+
+=head1 DESCRIPTION
+
+BIO_set_callback() and BIO_get_callback() set and retrieve the BIO callback,
+they are both macros. The callback is called during most high level BIO
+operations. It can be used for debugging purposes to trace operations on
+a BIO or to modify its operation.
+
+BIO_set_callback_arg() and BIO_get_callback_arg() are macros which can be
+used to set and retrieve an argument for use in the callback.
+
+BIO_debug_callback() is a standard debugging callback which prints
+out information relating to each BIO operation. If the callback
+argument is set if is interpreted as a BIO to send the information
+to, otherwise stderr is used.
+
+callback() is the callback function itself. The meaning of each
+argument is described below.
+
+The BIO the callback is attached to is passed in B<b>.
+
+B<oper> is set to the operation being performed. For some operations
+the callback is called twice, once before and once after the actual
+operation, the latter case has B<oper> or'ed with BIO_CB_RETURN.
+
+The meaning of the arguments B<argp>, B<argi> and B<argl> depends on
+the value of B<oper>, that is the operation being performed.
+
+B<retvalue> is the return value that would be returned to the
+application if no callback were present. The actual value returned
+is the return value of the callback itself. In the case of callbacks
+called before the actual BIO operation 1 is placed in retvalue, if
+the return value is not positive it will be immediately returned to
+the application and the BIO operation will not be performed.
+
+The callback should normally simply return B<retvalue> when it has
+finished processing, unless if specifically wishes to modify the
+value returned to the application.
+
+=head1 CALLBACK OPERATIONS
+
+=over 4
+
+=item B<BIO_free(b)>
+
+callback(b, BIO_CB_FREE, NULL, 0L, 0L, 1L) is called before the
+free operation.
+
+=item B<BIO_read(b, out, outl)>
+
+callback(b, BIO_CB_READ, out, outl, 0L, 1L) is called before
+the read and callback(b, BIO_CB_READ|BIO_CB_RETURN, out, outl, 0L, retvalue)
+after.
+
+=item B<BIO_write(b, in, inl)>
+
+callback(b, BIO_CB_WRITE, in, inl, 0L, 1L) is called before
+the write and callback(b, BIO_CB_WRITE|BIO_CB_RETURN, in, inl, 0L, retvalue)
+after.
+
+=item B<BIO_gets(b, out, outl)>
+
+callback(b, BIO_CB_GETS, out, outl, 0L, 1L) is called before
+the operation and callback(b, BIO_CB_GETS|BIO_CB_RETURN, out, outl, 0L, retvalue)
+after.
+
+=item B<BIO_puts(b, in)>
+
+callback(b, BIO_CB_WRITE, in, 0, 0L, 1L) is called before
+the operation and callback(b, BIO_CB_WRITE|BIO_CB_RETURN, in, 0, 0L, retvalue)
+after.
+
+=item B<BIO_ctrl(BIO *b, int cmd, long larg, void *parg)>
+
+callback(b,BIO_CB_CTRL,parg,cmd,larg,1L) is called before the call and
+callback(b,BIO_CB_CTRL|BIO_CB_RETURN,parg,cmd, larg,ret) after.
+
+=back
+
+=head1 EXAMPLE
+
+The BIO_debug_callback() function is a good example, its source is
+in crypto/bio/bio_cb.c
+
+=head1 SEE ALSO
+
+TBA
diff --git a/openssl/doc/crypto/BIO_should_retry.pod b/openssl/doc/crypto/BIO_should_retry.pod
new file mode 100644
index 0000000..b6d51f7
--- /dev/null
+++ b/openssl/doc/crypto/BIO_should_retry.pod
@@ -0,0 +1,114 @@
+=pod
+
+=head1 NAME
+
+BIO_should_retry, BIO_should_read, BIO_should_write,
+BIO_should_io_special, BIO_retry_type, BIO_should_retry,
+BIO_get_retry_BIO, BIO_get_retry_reason - BIO retry functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ #define BIO_should_read(a)		((a)->flags & BIO_FLAGS_READ)
+ #define BIO_should_write(a)		((a)->flags & BIO_FLAGS_WRITE)
+ #define BIO_should_io_special(a)	((a)->flags & BIO_FLAGS_IO_SPECIAL)
+ #define BIO_retry_type(a)		((a)->flags & BIO_FLAGS_RWS)
+ #define BIO_should_retry(a)		((a)->flags & BIO_FLAGS_SHOULD_RETRY)
+
+ #define BIO_FLAGS_READ		0x01
+ #define BIO_FLAGS_WRITE	0x02
+ #define BIO_FLAGS_IO_SPECIAL	0x04
+ #define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL)
+ #define BIO_FLAGS_SHOULD_RETRY	0x08
+
+ BIO *	BIO_get_retry_BIO(BIO *bio, int *reason);
+ int	BIO_get_retry_reason(BIO *bio);
+
+=head1 DESCRIPTION
+
+These functions determine why a BIO is not able to read or write data.
+They will typically be called after a failed BIO_read() or BIO_write()
+call.
+
+BIO_should_retry() is true if the call that produced this condition
+should then be retried at a later time.
+
+If BIO_should_retry() is false then the cause is an error condition.
+
+BIO_should_read() is true if the cause of the condition is that a BIO
+needs to read data.
+
+BIO_should_write() is true if the cause of the condition is that a BIO
+needs to read data.
+
+BIO_should_io_special() is true if some "special" condition, that is a
+reason other than reading or writing is the cause of the condition.
+
+BIO_retry_type() returns a mask of the cause of a retry condition
+consisting of the values B<BIO_FLAGS_READ>, B<BIO_FLAGS_WRITE>,
+B<BIO_FLAGS_IO_SPECIAL> though current BIO types will only set one of
+these.
+
+BIO_get_retry_BIO() determines the precise reason for the special
+condition, it returns the BIO that caused this condition and if 
+B<reason> is not NULL it contains the reason code. The meaning of
+the reason code and the action that should be taken depends on
+the type of BIO that resulted in this condition.
+
+BIO_get_retry_reason() returns the reason for a special condition if
+passed the relevant BIO, for example as returned by BIO_get_retry_BIO().
+
+=head1 NOTES
+
+If BIO_should_retry() returns false then the precise "error condition"
+depends on the BIO type that caused it and the return code of the BIO
+operation. For example if a call to BIO_read() on a socket BIO returns
+0 and BIO_should_retry() is false then the cause will be that the
+connection closed. A similar condition on a file BIO will mean that it
+has reached EOF. Some BIO types may place additional information on
+the error queue. For more details see the individual BIO type manual
+pages.
+
+If the underlying I/O structure is in a blocking mode almost all current
+BIO types will not request a retry, because the underlying I/O
+calls will not. If the application knows that the BIO type will never
+signal a retry then it need not call BIO_should_retry() after a failed
+BIO I/O call. This is typically done with file BIOs.
+
+SSL BIOs are the only current exception to this rule: they can request a
+retry even if the underlying I/O structure is blocking, if a handshake
+occurs during a call to BIO_read(). An application can retry the failed
+call immediately or avoid this situation by setting SSL_MODE_AUTO_RETRY
+on the underlying SSL structure.
+
+While an application may retry a failed non blocking call immediately
+this is likely to be very inefficient because the call will fail
+repeatedly until data can be processed or is available. An application
+will normally wait until the necessary condition is satisfied. How
+this is done depends on the underlying I/O structure.
+
+For example if the cause is ultimately a socket and BIO_should_read()
+is true then a call to select() may be made to wait until data is
+available and then retry the BIO operation. By combining the retry
+conditions of several non blocking BIOs in a single select() call
+it is possible to service several BIOs in a single thread, though
+the performance may be poor if SSL BIOs are present because long delays
+can occur during the initial handshake process. 
+
+It is possible for a BIO to block indefinitely if the underlying I/O
+structure cannot process or return any data. This depends on the behaviour of
+the platforms I/O functions. This is often not desirable: one solution
+is to use non blocking I/O and use a timeout on the select() (or
+equivalent) call.
+
+=head1 BUGS
+
+The OpenSSL ASN1 functions cannot gracefully deal with non blocking I/O:
+that is they cannot retry after a partial read or write. This is usually
+worked around by only passing the relevant data to ASN1 functions when
+the entire structure can be read or written.
+
+=head1 SEE ALSO
+
+TBA
diff --git a/openssl/doc/crypto/BN_BLINDING_new.pod b/openssl/doc/crypto/BN_BLINDING_new.pod
new file mode 100644
index 0000000..5f51fdb
--- /dev/null
+++ b/openssl/doc/crypto/BN_BLINDING_new.pod
@@ -0,0 +1,115 @@
+=pod
+
+=head1 NAME
+
+BN_BLINDING_new, BN_BLINDING_free, BN_BLINDING_update, BN_BLINDING_convert, 
+BN_BLINDING_invert, BN_BLINDING_convert_ex, BN_BLINDING_invert_ex, 
+BN_BLINDING_get_thread_id, BN_BLINDING_set_thread_id, BN_BLINDING_get_flags,
+BN_BLINDING_set_flags, BN_BLINDING_create_param - blinding related BIGNUM
+functions.
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai,
+	BIGNUM *mod);
+ void BN_BLINDING_free(BN_BLINDING *b);
+ int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
+ int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+ int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+ int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b,
+	BN_CTX *ctx);
+ int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
+	BN_CTX *ctx);
+ #ifndef OPENSSL_NO_DEPRECATED
+ unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
+ void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
+ #endif
+ CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *);
+ unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
+ void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
+ BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
+	const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
+	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
+	BN_MONT_CTX *m_ctx);
+
+=head1 DESCRIPTION
+
+BN_BLINDING_new() allocates a new B<BN_BLINDING> structure and copies
+the B<A> and B<Ai> values into the newly created B<BN_BLINDING> object.
+
+BN_BLINDING_free() frees the B<BN_BLINDING> structure.
+
+BN_BLINDING_update() updates the B<BN_BLINDING> parameters by squaring
+the B<A> and B<Ai> or, after specific number of uses and if the
+necessary parameters are set, by re-creating the blinding parameters.
+
+BN_BLINDING_convert_ex() multiplies B<n> with the blinding factor B<A>.
+If B<r> is not NULL a copy the inverse blinding factor B<Ai> will be
+returned in B<r> (this is useful if a B<RSA> object is shared amoung
+several threads). BN_BLINDING_invert_ex() multiplies B<n> with the
+inverse blinding factor B<Ai>. If B<r> is not NULL it will be used as
+the inverse blinding.
+
+BN_BLINDING_convert() and BN_BLINDING_invert() are wrapper
+functions for BN_BLINDING_convert_ex() and BN_BLINDING_invert_ex()
+with B<r> set to NULL.
+
+BN_BLINDING_thread_id() provides access to the B<CRYPTO_THREADID>
+object within the B<BN_BLINDING> structure. This is to help users
+provide proper locking if needed for multi-threaded use. The "thread
+id" object of a newly allocated B<BN_BLINDING> structure is
+initialised to the thread id in which BN_BLINDING_new() was called.
+
+BN_BLINDING_get_flags() returns the BN_BLINDING flags. Currently
+there are two supported flags: B<BN_BLINDING_NO_UPDATE> and
+B<BN_BLINDING_NO_RECREATE>. B<BN_BLINDING_NO_UPDATE> inhibits the
+automatic update of the B<BN_BLINDING> parameters after each use
+and B<BN_BLINDING_NO_RECREATE> inhibits the automatic re-creation
+of the B<BN_BLINDING> parameters after a fixed number of uses (currently
+32). In newly allocated B<BN_BLINDING> objects no flags are set.
+BN_BLINDING_set_flags() sets the B<BN_BLINDING> parameters flags.
+
+BN_BLINDING_create_param() creates new B<BN_BLINDING> parameters
+using the exponent B<e> and the modulus B<m>. B<bn_mod_exp> and
+B<m_ctx> can be used to pass special functions for exponentiation
+(normally BN_mod_exp_mont() and B<BN_MONT_CTX>).
+
+=head1 RETURN VALUES
+
+BN_BLINDING_new() returns the newly allocated B<BN_BLINDING> structure
+or NULL in case of an error.
+
+BN_BLINDING_update(), BN_BLINDING_convert(), BN_BLINDING_invert(),
+BN_BLINDING_convert_ex() and BN_BLINDING_invert_ex() return 1 on
+success and 0 if an error occured.
+
+BN_BLINDING_thread_id() returns a pointer to the thread id object
+within a B<BN_BLINDING> object.
+
+BN_BLINDING_get_flags() returns the currently set B<BN_BLINDING> flags
+(a B<unsigned long> value).
+
+BN_BLINDING_create_param() returns the newly created B<BN_BLINDING> 
+parameters or NULL on error.
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>
+
+=head1 HISTORY
+
+BN_BLINDING_thread_id was first introduced in OpenSSL 1.0.0, and it
+deprecates BN_BLINDING_set_thread_id and BN_BLINDING_get_thread_id.
+
+BN_BLINDING_convert_ex, BN_BLINDIND_invert_ex, BN_BLINDING_get_thread_id,
+BN_BLINDING_set_thread_id, BN_BLINDING_set_flags, BN_BLINDING_get_flags
+and BN_BLINDING_create_param were first introduced in OpenSSL 0.9.8
+
+=head1 AUTHOR
+
+Nils Larsch for the OpenSSL project (http://www.openssl.org).
+
+=cut
diff --git a/openssl/doc/crypto/BN_CTX_new.pod b/openssl/doc/crypto/BN_CTX_new.pod
new file mode 100644
index 0000000..ad8d07d
--- /dev/null
+++ b/openssl/doc/crypto/BN_CTX_new.pod
@@ -0,0 +1,53 @@
+=pod
+
+=head1 NAME
+
+BN_CTX_new, BN_CTX_init, BN_CTX_free - allocate and free BN_CTX structures
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ BN_CTX *BN_CTX_new(void);
+
+ void BN_CTX_init(BN_CTX *c);
+
+ void BN_CTX_free(BN_CTX *c);
+
+=head1 DESCRIPTION
+
+A B<BN_CTX> is a structure that holds B<BIGNUM> temporary variables used by
+library functions. Since dynamic memory allocation to create B<BIGNUM>s
+is rather expensive when used in conjunction with repeated subroutine
+calls, the B<BN_CTX> structure is used.
+
+BN_CTX_new() allocates and initializes a B<BN_CTX>
+structure. BN_CTX_init() initializes an existing uninitialized
+B<BN_CTX>.
+
+BN_CTX_free() frees the components of the B<BN_CTX>, and if it was
+created by BN_CTX_new(), also the structure itself.
+If L<BN_CTX_start(3)|BN_CTX_start(3)> has been used on the B<BN_CTX>,
+L<BN_CTX_end(3)|BN_CTX_end(3)> must be called before the B<BN_CTX>
+may be freed by BN_CTX_free().
+
+
+=head1 RETURN VALUES
+
+BN_CTX_new() returns a pointer to the B<BN_CTX>. If the allocation fails,
+it returns B<NULL> and sets an error code that can be obtained by
+L<ERR_get_error(3)|ERR_get_error(3)>.
+
+BN_CTX_init() and BN_CTX_free() have no return values.
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<BN_add(3)|BN_add(3)>,
+L<BN_CTX_start(3)|BN_CTX_start(3)>
+
+=head1 HISTORY
+
+BN_CTX_new() and BN_CTX_free() are available in all versions on SSLeay
+and OpenSSL. BN_CTX_init() was added in SSLeay 0.9.1b.
+
+=cut
diff --git a/openssl/doc/crypto/BN_CTX_start.pod b/openssl/doc/crypto/BN_CTX_start.pod
new file mode 100644
index 0000000..dfcefe1
--- /dev/null
+++ b/openssl/doc/crypto/BN_CTX_start.pod
@@ -0,0 +1,52 @@
+=pod
+
+=head1 NAME
+
+BN_CTX_start, BN_CTX_get, BN_CTX_end - use temporary BIGNUM variables
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ void BN_CTX_start(BN_CTX *ctx);
+
+ BIGNUM *BN_CTX_get(BN_CTX *ctx);
+
+ void BN_CTX_end(BN_CTX *ctx);
+
+=head1 DESCRIPTION
+
+These functions are used to obtain temporary B<BIGNUM> variables from
+a B<BN_CTX> (which can been created by using L<BN_CTX_new(3)|BN_CTX_new(3)>)
+in order to save the overhead of repeatedly creating and
+freeing B<BIGNUM>s in functions that are called from inside a loop.
+
+A function must call BN_CTX_start() first. Then, BN_CTX_get() may be
+called repeatedly to obtain temporary B<BIGNUM>s. All BN_CTX_get()
+calls must be made before calling any other functions that use the
+B<ctx> as an argument.
+
+Finally, BN_CTX_end() must be called before returning from the function.
+When BN_CTX_end() is called, the B<BIGNUM> pointers obtained from
+BN_CTX_get() become invalid.
+
+=head1 RETURN VALUES
+
+BN_CTX_start() and BN_CTX_end() return no values.
+
+BN_CTX_get() returns a pointer to the B<BIGNUM>, or B<NULL> on error.
+Once BN_CTX_get() has failed, the subsequent calls will return B<NULL>
+as well, so it is sufficient to check the return value of the last
+BN_CTX_get() call. In case of an error, an error code is set, which
+can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+
+=head1 SEE ALSO
+
+L<BN_CTX_new(3)|BN_CTX_new(3)>
+
+=head1 HISTORY
+
+BN_CTX_start(), BN_CTX_get() and BN_CTX_end() were added in OpenSSL 0.9.5.
+
+=cut
diff --git a/openssl/doc/crypto/BN_add.pod b/openssl/doc/crypto/BN_add.pod
new file mode 100644
index 0000000..88c7a79
--- /dev/null
+++ b/openssl/doc/crypto/BN_add.pod
@@ -0,0 +1,126 @@
+=pod
+
+=head1 NAME
+
+BN_add, BN_sub, BN_mul, BN_sqr, BN_div, BN_mod, BN_nnmod, BN_mod_add,
+BN_mod_sub, BN_mod_mul, BN_mod_sqr, BN_exp, BN_mod_exp, BN_gcd -
+arithmetic operations on BIGNUMs
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+
+ int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+
+ int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+
+ int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx);
+
+ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *a, const BIGNUM *d,
+         BN_CTX *ctx);
+
+ int BN_mod(BIGNUM *rem, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+
+ int BN_nnmod(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+
+ int BN_mod_add(BIGNUM *r, BIGNUM *a, BIGNUM *b, const BIGNUM *m,
+         BN_CTX *ctx);
+
+ int BN_mod_sub(BIGNUM *r, BIGNUM *a, BIGNUM *b, const BIGNUM *m,
+         BN_CTX *ctx);
+
+ int BN_mod_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, const BIGNUM *m,
+         BN_CTX *ctx);
+
+ int BN_mod_sqr(BIGNUM *r, BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+
+ int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx);
+
+ int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+         const BIGNUM *m, BN_CTX *ctx);
+
+ int BN_gcd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+
+=head1 DESCRIPTION
+
+BN_add() adds I<a> and I<b> and places the result in I<r> (C<r=a+b>).
+I<r> may be the same B<BIGNUM> as I<a> or I<b>.
+
+BN_sub() subtracts I<b> from I<a> and places the result in I<r> (C<r=a-b>).
+
+BN_mul() multiplies I<a> and I<b> and places the result in I<r> (C<r=a*b>).
+I<r> may be the same B<BIGNUM> as I<a> or I<b>.
+For multiplication by powers of 2, use L<BN_lshift(3)|BN_lshift(3)>.
+
+BN_sqr() takes the square of I<a> and places the result in I<r>
+(C<r=a^2>). I<r> and I<a> may be the same B<BIGNUM>.
+This function is faster than BN_mul(r,a,a).
+
+BN_div() divides I<a> by I<d> and places the result in I<dv> and the
+remainder in I<rem> (C<dv=a/d, rem=a%d>). Either of I<dv> and I<rem> may
+be B<NULL>, in which case the respective value is not returned.
+The result is rounded towards zero; thus if I<a> is negative, the
+remainder will be zero or negative.
+For division by powers of 2, use BN_rshift(3).
+
+BN_mod() corresponds to BN_div() with I<dv> set to B<NULL>.
+
+BN_nnmod() reduces I<a> modulo I<m> and places the non-negative
+remainder in I<r>.
+
+BN_mod_add() adds I<a> to I<b> modulo I<m> and places the non-negative
+result in I<r>.
+
+BN_mod_sub() subtracts I<b> from I<a> modulo I<m> and places the
+non-negative result in I<r>.
+
+BN_mod_mul() multiplies I<a> by I<b> and finds the non-negative
+remainder respective to modulus I<m> (C<r=(a*b) mod m>). I<r> may be
+the same B<BIGNUM> as I<a> or I<b>. For more efficient algorithms for
+repeated computations using the same modulus, see
+L<BN_mod_mul_montgomery(3)|BN_mod_mul_montgomery(3)> and
+L<BN_mod_mul_reciprocal(3)|BN_mod_mul_reciprocal(3)>.
+
+BN_mod_sqr() takes the square of I<a> modulo B<m> and places the
+result in I<r>.
+
+BN_exp() raises I<a> to the I<p>-th power and places the result in I<r>
+(C<r=a^p>). This function is faster than repeated applications of
+BN_mul().
+
+BN_mod_exp() computes I<a> to the I<p>-th power modulo I<m> (C<r=a^p %
+m>). This function uses less time and space than BN_exp().
+
+BN_gcd() computes the greatest common divisor of I<a> and I<b> and
+places the result in I<r>. I<r> may be the same B<BIGNUM> as I<a> or
+I<b>.
+
+For all functions, I<ctx> is a previously allocated B<BN_CTX> used for
+temporary variables; see L<BN_CTX_new(3)|BN_CTX_new(3)>.
+
+Unless noted otherwise, the result B<BIGNUM> must be different from
+the arguments.
+
+=head1 RETURN VALUES
+
+For all functions, 1 is returned for success, 0 on error. The return
+value should always be checked (e.g., C<if (!BN_add(r,a,b)) goto err;>).
+The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<BN_CTX_new(3)|BN_CTX_new(3)>,
+L<BN_add_word(3)|BN_add_word(3)>, L<BN_set_bit(3)|BN_set_bit(3)>
+
+=head1 HISTORY
+
+BN_add(), BN_sub(), BN_sqr(), BN_div(), BN_mod(), BN_mod_mul(),
+BN_mod_exp() and BN_gcd() are available in all versions of SSLeay and
+OpenSSL. The I<ctx> argument to BN_mul() was added in SSLeay
+0.9.1b. BN_exp() appeared in SSLeay 0.9.0.
+BN_nnmod(), BN_mod_add(), BN_mod_sub(), and BN_mod_sqr() were added in
+OpenSSL 0.9.7.
+
+=cut
diff --git a/openssl/doc/crypto/BN_add_word.pod b/openssl/doc/crypto/BN_add_word.pod
new file mode 100644
index 0000000..70667d2
--- /dev/null
+++ b/openssl/doc/crypto/BN_add_word.pod
@@ -0,0 +1,61 @@
+=pod
+
+=head1 NAME
+
+BN_add_word, BN_sub_word, BN_mul_word, BN_div_word, BN_mod_word - arithmetic
+functions on BIGNUMs with integers
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ int BN_add_word(BIGNUM *a, BN_ULONG w);
+
+ int BN_sub_word(BIGNUM *a, BN_ULONG w);
+
+ int BN_mul_word(BIGNUM *a, BN_ULONG w);
+
+ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
+
+ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
+
+=head1 DESCRIPTION
+
+These functions perform arithmetic operations on BIGNUMs with unsigned
+integers. They are much more efficient than the normal BIGNUM
+arithmetic operations.
+
+BN_add_word() adds B<w> to B<a> (C<a+=w>).
+
+BN_sub_word() subtracts B<w> from B<a> (C<a-=w>).
+
+BN_mul_word() multiplies B<a> and B<w> (C<a*=w>).
+
+BN_div_word() divides B<a> by B<w> (C<a/=w>) and returns the remainder.
+
+BN_mod_word() returns the remainder of B<a> divided by B<w> (C<a%w>).
+
+For BN_div_word() and BN_mod_word(), B<w> must not be 0.
+
+=head1 RETURN VALUES
+
+BN_add_word(), BN_sub_word() and BN_mul_word() return 1 for success, 0
+on error. The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+BN_mod_word() and BN_div_word() return B<a>%B<w> on success and
+B<(BN_ULONG)-1> if an error occurred.
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<BN_add(3)|BN_add(3)>
+
+=head1 HISTORY
+
+BN_add_word() and BN_mod_word() are available in all versions of
+SSLeay and OpenSSL. BN_div_word() was added in SSLeay 0.8, and
+BN_sub_word() and BN_mul_word() in SSLeay 0.9.0.
+
+Before 0.9.8a the return value for BN_div_word() and BN_mod_word()
+in case of an error was 0.
+
+=cut
diff --git a/openssl/doc/crypto/BN_bn2bin.pod b/openssl/doc/crypto/BN_bn2bin.pod
new file mode 100644
index 0000000..a4b17ca
--- /dev/null
+++ b/openssl/doc/crypto/BN_bn2bin.pod
@@ -0,0 +1,95 @@
+=pod
+
+=head1 NAME
+
+BN_bn2bin, BN_bin2bn, BN_bn2hex, BN_bn2dec, BN_hex2bn, BN_dec2bn,
+BN_print, BN_print_fp, BN_bn2mpi, BN_mpi2bn - format conversions
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ int BN_bn2bin(const BIGNUM *a, unsigned char *to);
+ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
+
+ char *BN_bn2hex(const BIGNUM *a);
+ char *BN_bn2dec(const BIGNUM *a);
+ int BN_hex2bn(BIGNUM **a, const char *str);
+ int BN_dec2bn(BIGNUM **a, const char *str);
+
+ int BN_print(BIO *fp, const BIGNUM *a);
+ int BN_print_fp(FILE *fp, const BIGNUM *a);
+
+ int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
+ BIGNUM *BN_mpi2bn(unsigned char *s, int len, BIGNUM *ret);
+
+=head1 DESCRIPTION
+
+BN_bn2bin() converts the absolute value of B<a> into big-endian form
+and stores it at B<to>. B<to> must point to BN_num_bytes(B<a>) bytes of
+memory.
+
+BN_bin2bn() converts the positive integer in big-endian form of length
+B<len> at B<s> into a B<BIGNUM> and places it in B<ret>. If B<ret> is
+NULL, a new B<BIGNUM> is created.
+
+BN_bn2hex() and BN_bn2dec() return printable strings containing the
+hexadecimal and decimal encoding of B<a> respectively. For negative
+numbers, the string is prefaced with a leading '-'. The string must be
+freed later using OPENSSL_free().
+
+BN_hex2bn() converts the string B<str> containing a hexadecimal number
+to a B<BIGNUM> and stores it in **B<bn>. If *B<bn> is NULL, a new
+B<BIGNUM> is created. If B<bn> is NULL, it only computes the number's
+length in hexadecimal digits. If the string starts with '-', the
+number is negative. BN_dec2bn() is the same using the decimal system.
+
+BN_print() and BN_print_fp() write the hexadecimal encoding of B<a>,
+with a leading '-' for negative numbers, to the B<BIO> or B<FILE>
+B<fp>.
+
+BN_bn2mpi() and BN_mpi2bn() convert B<BIGNUM>s from and to a format
+that consists of the number's length in bytes represented as a 4-byte
+big-endian number, and the number itself in big-endian format, where
+the most significant bit signals a negative number (the representation
+of numbers with the MSB set is prefixed with null byte).
+
+BN_bn2mpi() stores the representation of B<a> at B<to>, where B<to>
+must be large enough to hold the result. The size can be determined by
+calling BN_bn2mpi(B<a>, NULL).
+
+BN_mpi2bn() converts the B<len> bytes long representation at B<s> to
+a B<BIGNUM> and stores it at B<ret>, or in a newly allocated B<BIGNUM>
+if B<ret> is NULL.
+
+=head1 RETURN VALUES
+
+BN_bn2bin() returns the length of the big-endian number placed at B<to>.
+BN_bin2bn() returns the B<BIGNUM>, NULL on error.
+
+BN_bn2hex() and BN_bn2dec() return a null-terminated string, or NULL
+on error. BN_hex2bn() and BN_dec2bn() return the number's length in
+hexadecimal or decimal digits, and 0 on error.
+
+BN_print_fp() and BN_print() return 1 on success, 0 on write errors.
+
+BN_bn2mpi() returns the length of the representation. BN_mpi2bn()
+returns the B<BIGNUM>, and NULL on error.
+
+The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<BN_zero(3)|BN_zero(3)>,
+L<ASN1_INTEGER_to_BN(3)|ASN1_INTEGER_to_BN(3)>,
+L<BN_num_bytes(3)|BN_num_bytes(3)>
+
+=head1 HISTORY
+
+BN_bn2bin(), BN_bin2bn(), BN_print_fp() and BN_print() are available
+in all versions of SSLeay and OpenSSL.
+
+BN_bn2hex(), BN_bn2dec(), BN_hex2bn(), BN_dec2bn(), BN_bn2mpi() and
+BN_mpi2bn() were added in SSLeay 0.9.0.
+
+=cut
diff --git a/openssl/doc/crypto/BN_cmp.pod b/openssl/doc/crypto/BN_cmp.pod
new file mode 100644
index 0000000..23e9ed0
--- /dev/null
+++ b/openssl/doc/crypto/BN_cmp.pod
@@ -0,0 +1,48 @@
+=pod
+
+=head1 NAME
+
+BN_cmp, BN_ucmp, BN_is_zero, BN_is_one, BN_is_word, BN_is_odd - BIGNUM comparison and test functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ int BN_cmp(BIGNUM *a, BIGNUM *b);
+ int BN_ucmp(BIGNUM *a, BIGNUM *b);
+
+ int BN_is_zero(BIGNUM *a);
+ int BN_is_one(BIGNUM *a);
+ int BN_is_word(BIGNUM *a, BN_ULONG w);
+ int BN_is_odd(BIGNUM *a);
+
+=head1 DESCRIPTION
+
+BN_cmp() compares the numbers B<a> and B<b>. BN_ucmp() compares their
+absolute values.
+
+BN_is_zero(), BN_is_one() and BN_is_word() test if B<a> equals 0, 1,
+or B<w> respectively. BN_is_odd() tests if a is odd.
+
+BN_is_zero(), BN_is_one(), BN_is_word() and BN_is_odd() are macros.
+
+=head1 RETURN VALUES
+
+BN_cmp() returns -1 if B<a> E<lt> B<b>, 0 if B<a> == B<b> and 1 if
+B<a> E<gt> B<b>. BN_ucmp() is the same using the absolute values
+of B<a> and B<b>.
+
+BN_is_zero(), BN_is_one() BN_is_word() and BN_is_odd() return 1 if
+the condition is true, 0 otherwise.
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>
+
+=head1 HISTORY
+
+BN_cmp(), BN_ucmp(), BN_is_zero(), BN_is_one() and BN_is_word() are
+available in all versions of SSLeay and OpenSSL.
+BN_is_odd() was added in SSLeay 0.8.
+
+=cut
diff --git a/openssl/doc/crypto/BN_copy.pod b/openssl/doc/crypto/BN_copy.pod
new file mode 100644
index 0000000..388dd7d
--- /dev/null
+++ b/openssl/doc/crypto/BN_copy.pod
@@ -0,0 +1,34 @@
+=pod
+
+=head1 NAME
+
+BN_copy, BN_dup - copy BIGNUMs
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ BIGNUM *BN_copy(BIGNUM *to, const BIGNUM *from);
+
+ BIGNUM *BN_dup(const BIGNUM *from);
+
+=head1 DESCRIPTION
+
+BN_copy() copies B<from> to B<to>. BN_dup() creates a new B<BIGNUM>
+containing the value B<from>.
+
+=head1 RETURN VALUES
+
+BN_copy() returns B<to> on success, NULL on error. BN_dup() returns
+the new B<BIGNUM>, and NULL on error. The error codes can be obtained
+by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>
+
+=head1 HISTORY
+
+BN_copy() and BN_dup() are available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/BN_generate_prime.pod b/openssl/doc/crypto/BN_generate_prime.pod
new file mode 100644
index 0000000..7dccacb
--- /dev/null
+++ b/openssl/doc/crypto/BN_generate_prime.pod
@@ -0,0 +1,102 @@
+=pod
+
+=head1 NAME
+
+BN_generate_prime, BN_is_prime, BN_is_prime_fasttest - generate primes and test for primality
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ BIGNUM *BN_generate_prime(BIGNUM *ret, int num, int safe, BIGNUM *add,
+     BIGNUM *rem, void (*callback)(int, int, void *), void *cb_arg);
+
+ int BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int, int, 
+     void *), BN_CTX *ctx, void *cb_arg);
+
+ int BN_is_prime_fasttest(const BIGNUM *a, int checks,
+     void (*callback)(int, int, void *), BN_CTX *ctx, void *cb_arg,
+     int do_trial_division);
+
+=head1 DESCRIPTION
+
+BN_generate_prime() generates a pseudo-random prime number of B<num>
+bits.
+If B<ret> is not B<NULL>, it will be used to store the number.
+
+If B<callback> is not B<NULL>, it is called as follows:
+
+=over 4
+
+=item *
+
+B<callback(0, i, cb_arg)> is called after generating the i-th
+potential prime number.
+
+=item *
+
+While the number is being tested for primality, B<callback(1, j,
+cb_arg)> is called as described below.
+
+=item *
+
+When a prime has been found, B<callback(2, i, cb_arg)> is called.
+
+=back
+
+The prime may have to fulfill additional requirements for use in
+Diffie-Hellman key exchange:
+
+If B<add> is not B<NULL>, the prime will fulfill the condition p % B<add>
+== B<rem> (p % B<add> == 1 if B<rem> == B<NULL>) in order to suit a given
+generator.
+
+If B<safe> is true, it will be a safe prime (i.e. a prime p so
+that (p-1)/2 is also prime).
+
+The PRNG must be seeded prior to calling BN_generate_prime().
+The prime number generation has a negligible error probability.
+
+BN_is_prime() and BN_is_prime_fasttest() test if the number B<a> is
+prime.  The following tests are performed until one of them shows that
+B<a> is composite; if B<a> passes all these tests, it is considered
+prime.
+
+BN_is_prime_fasttest(), when called with B<do_trial_division == 1>,
+first attempts trial division by a number of small primes;
+if no divisors are found by this test and B<callback> is not B<NULL>,
+B<callback(1, -1, cb_arg)> is called.
+If B<do_trial_division == 0>, this test is skipped.
+
+Both BN_is_prime() and BN_is_prime_fasttest() perform a Miller-Rabin
+probabilistic primality test with B<checks> iterations. If
+B<checks == BN_prime_checks>, a number of iterations is used that
+yields a false positive rate of at most 2^-80 for random input.
+
+If B<callback> is not B<NULL>, B<callback(1, j, cb_arg)> is called
+after the j-th iteration (j = 0, 1, ...). B<ctx> is a
+pre-allocated B<BN_CTX> (to save the overhead of allocating and
+freeing the structure in a loop), or B<NULL>.
+
+=head1 RETURN VALUES
+
+BN_generate_prime() returns the prime number on success, B<NULL> otherwise.
+
+BN_is_prime() returns 0 if the number is composite, 1 if it is
+prime with an error probability of less than 0.25^B<checks>, and
+-1 on error.
+
+The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>
+
+=head1 HISTORY
+
+The B<cb_arg> arguments to BN_generate_prime() and to BN_is_prime()
+were added in SSLeay 0.9.0. The B<ret> argument to BN_generate_prime()
+was added in SSLeay 0.9.1.
+BN_is_prime_fasttest() was added in OpenSSL 0.9.5.
+
+=cut
diff --git a/openssl/doc/crypto/BN_mod_inverse.pod b/openssl/doc/crypto/BN_mod_inverse.pod
new file mode 100644
index 0000000..3ea3975
--- /dev/null
+++ b/openssl/doc/crypto/BN_mod_inverse.pod
@@ -0,0 +1,36 @@
+=pod
+
+=head1 NAME
+
+BN_mod_inverse - compute inverse modulo n
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ BIGNUM *BN_mod_inverse(BIGNUM *r, BIGNUM *a, const BIGNUM *n,
+           BN_CTX *ctx);
+
+=head1 DESCRIPTION
+
+BN_mod_inverse() computes the inverse of B<a> modulo B<n>
+places the result in B<r> (C<(a*r)%n==1>). If B<r> is NULL,
+a new B<BIGNUM> is created.
+
+B<ctx> is a previously allocated B<BN_CTX> used for temporary
+variables. B<r> may be the same B<BIGNUM> as B<a> or B<n>.
+
+=head1 RETURN VALUES
+
+BN_mod_inverse() returns the B<BIGNUM> containing the inverse, and
+NULL on error. The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<BN_add(3)|BN_add(3)>
+
+=head1 HISTORY
+
+BN_mod_inverse() is available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/BN_mod_mul_montgomery.pod b/openssl/doc/crypto/BN_mod_mul_montgomery.pod
new file mode 100644
index 0000000..6b16351
--- /dev/null
+++ b/openssl/doc/crypto/BN_mod_mul_montgomery.pod
@@ -0,0 +1,101 @@
+=pod
+
+=head1 NAME
+
+BN_mod_mul_montgomery, BN_MONT_CTX_new, BN_MONT_CTX_init,
+BN_MONT_CTX_free, BN_MONT_CTX_set, BN_MONT_CTX_copy,
+BN_from_montgomery, BN_to_montgomery - Montgomery multiplication
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ BN_MONT_CTX *BN_MONT_CTX_new(void);
+ void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
+ void BN_MONT_CTX_free(BN_MONT_CTX *mont);
+
+ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *m, BN_CTX *ctx);
+ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from);
+
+ int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b,
+         BN_MONT_CTX *mont, BN_CTX *ctx);
+
+ int BN_from_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont,
+         BN_CTX *ctx);
+
+ int BN_to_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont,
+         BN_CTX *ctx);
+
+=head1 DESCRIPTION
+
+These functions implement Montgomery multiplication. They are used
+automatically when L<BN_mod_exp(3)|BN_mod_exp(3)> is called with suitable input,
+but they may be useful when several operations are to be performed
+using the same modulus.
+
+BN_MONT_CTX_new() allocates and initializes a B<BN_MONT_CTX> structure.
+BN_MONT_CTX_init() initializes an existing uninitialized B<BN_MONT_CTX>.
+
+BN_MONT_CTX_set() sets up the I<mont> structure from the modulus I<m>
+by precomputing its inverse and a value R.
+
+BN_MONT_CTX_copy() copies the B<BN_MONT_CTX> I<from> to I<to>.
+
+BN_MONT_CTX_free() frees the components of the B<BN_MONT_CTX>, and, if
+it was created by BN_MONT_CTX_new(), also the structure itself.
+
+BN_mod_mul_montgomery() computes Mont(I<a>,I<b>):=I<a>*I<b>*R^-1 and places
+the result in I<r>.
+
+BN_from_montgomery() performs the Montgomery reduction I<r> = I<a>*R^-1.
+
+BN_to_montgomery() computes Mont(I<a>,R^2), i.e. I<a>*R.
+Note that I<a> must be non-negative and smaller than the modulus.
+
+For all functions, I<ctx> is a previously allocated B<BN_CTX> used for
+temporary variables.
+
+The B<BN_MONT_CTX> structure is defined as follows:
+
+ typedef struct bn_mont_ctx_st
+        {
+        int ri;         /* number of bits in R */
+        BIGNUM RR;      /* R^2 (used to convert to Montgomery form) */
+        BIGNUM N;       /* The modulus */
+        BIGNUM Ni;      /* R*(1/R mod N) - N*Ni = 1
+                         * (Ni is only stored for bignum algorithm) */
+        BN_ULONG n0;    /* least significant word of Ni */
+        int flags;
+        } BN_MONT_CTX;
+
+BN_to_montgomery() is a macro.
+
+=head1 RETURN VALUES
+
+BN_MONT_CTX_new() returns the newly allocated B<BN_MONT_CTX>, and NULL
+on error.
+
+BN_MONT_CTX_init() and BN_MONT_CTX_free() have no return values.
+
+For the other functions, 1 is returned for success, 0 on error.
+The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 WARNING
+
+The inputs must be reduced modulo B<m>, otherwise the result will be
+outside the expected range.
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<BN_add(3)|BN_add(3)>,
+L<BN_CTX_new(3)|BN_CTX_new(3)>
+
+=head1 HISTORY
+
+BN_MONT_CTX_new(), BN_MONT_CTX_free(), BN_MONT_CTX_set(),
+BN_mod_mul_montgomery(), BN_from_montgomery() and BN_to_montgomery()
+are available in all versions of SSLeay and OpenSSL.
+
+BN_MONT_CTX_init() and BN_MONT_CTX_copy() were added in SSLeay 0.9.1b.
+
+=cut
diff --git a/openssl/doc/crypto/BN_mod_mul_reciprocal.pod b/openssl/doc/crypto/BN_mod_mul_reciprocal.pod
new file mode 100644
index 0000000..74a216d
--- /dev/null
+++ b/openssl/doc/crypto/BN_mod_mul_reciprocal.pod
@@ -0,0 +1,81 @@
+=pod
+
+=head1 NAME
+
+BN_mod_mul_reciprocal,  BN_div_recp, BN_RECP_CTX_new, BN_RECP_CTX_init,
+BN_RECP_CTX_free, BN_RECP_CTX_set - modular multiplication using
+reciprocal
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ BN_RECP_CTX *BN_RECP_CTX_new(void);
+ void BN_RECP_CTX_init(BN_RECP_CTX *recp);
+ void BN_RECP_CTX_free(BN_RECP_CTX *recp);
+
+ int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *m, BN_CTX *ctx);
+
+ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *a, BN_RECP_CTX *recp,
+        BN_CTX *ctx);
+
+ int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *a, BIGNUM *b,
+        BN_RECP_CTX *recp, BN_CTX *ctx);
+
+=head1 DESCRIPTION
+
+BN_mod_mul_reciprocal() can be used to perform an efficient
+L<BN_mod_mul(3)|BN_mod_mul(3)> operation when the operation will be performed
+repeatedly with the same modulus. It computes B<r>=(B<a>*B<b>)%B<m>
+using B<recp>=1/B<m>, which is set as described below.  B<ctx> is a
+previously allocated B<BN_CTX> used for temporary variables.
+
+BN_RECP_CTX_new() allocates and initializes a B<BN_RECP> structure.
+BN_RECP_CTX_init() initializes an existing uninitialized B<BN_RECP>.
+
+BN_RECP_CTX_free() frees the components of the B<BN_RECP>, and, if it
+was created by BN_RECP_CTX_new(), also the structure itself.
+
+BN_RECP_CTX_set() stores B<m> in B<recp> and sets it up for computing
+1/B<m> and shifting it left by BN_num_bits(B<m>)+1 to make it an
+integer. The result and the number of bits it was shifted left will
+later be stored in B<recp>.
+
+BN_div_recp() divides B<a> by B<m> using B<recp>. It places the quotient
+in B<dv> and the remainder in B<rem>.
+
+The B<BN_RECP_CTX> structure is defined as follows:
+
+ typedef struct bn_recp_ctx_st
+	{
+	BIGNUM N;	/* the divisor */
+	BIGNUM Nr;	/* the reciprocal */
+	int num_bits;
+	int shift;
+	int flags;
+	} BN_RECP_CTX;
+
+It cannot be shared between threads.
+
+=head1 RETURN VALUES
+
+BN_RECP_CTX_new() returns the newly allocated B<BN_RECP_CTX>, and NULL
+on error.
+
+BN_RECP_CTX_init() and BN_RECP_CTX_free() have no return values.
+
+For the other functions, 1 is returned for success, 0 on error.
+The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<BN_add(3)|BN_add(3)>,
+L<BN_CTX_new(3)|BN_CTX_new(3)>
+
+=head1 HISTORY
+
+B<BN_RECP_CTX> was added in SSLeay 0.9.0. Before that, the function
+BN_reciprocal() was used instead, and the BN_mod_mul_reciprocal()
+arguments were different.
+
+=cut
diff --git a/openssl/doc/crypto/BN_new.pod b/openssl/doc/crypto/BN_new.pod
new file mode 100644
index 0000000..ab7a105
--- /dev/null
+++ b/openssl/doc/crypto/BN_new.pod
@@ -0,0 +1,53 @@
+=pod
+
+=head1 NAME
+
+BN_new, BN_init, BN_clear, BN_free, BN_clear_free - allocate and free BIGNUMs
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ BIGNUM *BN_new(void);
+
+ void BN_init(BIGNUM *);
+
+ void BN_clear(BIGNUM *a);
+
+ void BN_free(BIGNUM *a);
+
+ void BN_clear_free(BIGNUM *a);
+
+=head1 DESCRIPTION
+
+BN_new() allocates and initializes a B<BIGNUM> structure. BN_init()
+initializes an existing uninitialized B<BIGNUM>.
+
+BN_clear() is used to destroy sensitive data such as keys when they
+are no longer needed. It erases the memory used by B<a> and sets it
+to the value 0.
+
+BN_free() frees the components of the B<BIGNUM>, and if it was created
+by BN_new(), also the structure itself. BN_clear_free() additionally
+overwrites the data before the memory is returned to the system.
+
+=head1 RETURN VALUES
+
+BN_new() returns a pointer to the B<BIGNUM>. If the allocation fails,
+it returns B<NULL> and sets an error code that can be obtained
+by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+BN_init(), BN_clear(), BN_free() and BN_clear_free() have no return
+values.
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>
+
+=head1 HISTORY
+
+BN_new(), BN_clear(), BN_free() and BN_clear_free() are available in
+all versions on SSLeay and OpenSSL.  BN_init() was added in SSLeay
+0.9.1b.
+
+=cut
diff --git a/openssl/doc/crypto/BN_num_bytes.pod b/openssl/doc/crypto/BN_num_bytes.pod
new file mode 100644
index 0000000..a6a2e3f
--- /dev/null
+++ b/openssl/doc/crypto/BN_num_bytes.pod
@@ -0,0 +1,57 @@
+=pod
+
+=head1 NAME
+
+BN_num_bits, BN_num_bytes, BN_num_bits_word - get BIGNUM size
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ int BN_num_bytes(const BIGNUM *a);
+
+ int BN_num_bits(const BIGNUM *a);
+
+ int BN_num_bits_word(BN_ULONG w);
+
+=head1 DESCRIPTION
+
+BN_num_bytes() returns the size of a B<BIGNUM> in bytes.
+
+BN_num_bits_word() returns the number of significant bits in a word.
+If we take 0x00000432 as an example, it returns 11, not 16, not 32.
+Basically, except for a zero, it returns I<floor(log2(w))+1>.
+
+BN_num_bits() returns the number of significant bits in a B<BIGNUM>,
+following the same principle as BN_num_bits_word().
+
+BN_num_bytes() is a macro.
+
+=head1 RETURN VALUES
+
+The size.
+
+=head1 NOTES
+
+Some have tried using BN_num_bits() on individual numbers in RSA keys,
+DH keys and DSA keys, and found that they don't always come up with
+the number of bits they expected (something like 512, 1024, 2048,
+...).  This is because generating a number with some specific number
+of bits doesn't always set the highest bits, thereby making the number
+of I<significant> bits a little lower.  If you want to know the "key
+size" of such a key, either use functions like RSA_size(), DH_size()
+and DSA_size(), or use BN_num_bytes() and multiply with 8 (although
+there's no real guarantee that will match the "key size", just a lot
+more probability).
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>, L<DH_size(3)|DH_size(3)>, L<DSA_size(3)|DSA_size(3)>,
+L<RSA_size(3)|RSA_size(3)>
+
+=head1 HISTORY
+
+BN_num_bytes(), BN_num_bits() and BN_num_bits_word() are available in
+all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/BN_rand.pod b/openssl/doc/crypto/BN_rand.pod
new file mode 100644
index 0000000..81f93c2
--- /dev/null
+++ b/openssl/doc/crypto/BN_rand.pod
@@ -0,0 +1,58 @@
+=pod
+
+=head1 NAME
+
+BN_rand, BN_pseudo_rand - generate pseudo-random number
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
+
+ int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom);
+
+ int BN_rand_range(BIGNUM *rnd, BIGNUM *range);
+
+ int BN_pseudo_rand_range(BIGNUM *rnd, BIGNUM *range);
+
+=head1 DESCRIPTION
+
+BN_rand() generates a cryptographically strong pseudo-random number of
+B<bits> bits in length and stores it in B<rnd>. If B<top> is -1, the
+most significant bit of the random number can be zero. If B<top> is 0,
+it is set to 1, and if B<top> is 1, the two most significant bits of
+the number will be set to 1, so that the product of two such random
+numbers will always have 2*B<bits> length.  If B<bottom> is true, the
+number will be odd.
+
+BN_pseudo_rand() does the same, but pseudo-random numbers generated by
+this function are not necessarily unpredictable. They can be used for
+non-cryptographic purposes and for certain purposes in cryptographic
+protocols, but usually not for key generation etc.
+
+BN_rand_range() generates a cryptographically strong pseudo-random
+number B<rnd> in the range 0 <lt>= B<rnd> E<lt> B<range>.
+BN_pseudo_rand_range() does the same, but is based on BN_pseudo_rand(),
+and hence numbers generated by it are not necessarily unpredictable.
+
+The PRNG must be seeded prior to calling BN_rand() or BN_rand_range().
+
+=head1 RETURN VALUES
+
+The functions return 1 on success, 0 on error.
+The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>,
+L<RAND_add(3)|RAND_add(3)>, L<RAND_bytes(3)|RAND_bytes(3)>
+
+=head1 HISTORY
+
+BN_rand() is available in all versions of SSLeay and OpenSSL.
+BN_pseudo_rand() was added in OpenSSL 0.9.5. The B<top> == -1 case
+and the function BN_rand_range() were added in OpenSSL 0.9.6a.
+BN_pseudo_rand_range() was added in OpenSSL 0.9.6c.
+
+=cut
diff --git a/openssl/doc/crypto/BN_set_bit.pod b/openssl/doc/crypto/BN_set_bit.pod
new file mode 100644
index 0000000..b7c47b9
--- /dev/null
+++ b/openssl/doc/crypto/BN_set_bit.pod
@@ -0,0 +1,66 @@
+=pod
+
+=head1 NAME
+
+BN_set_bit, BN_clear_bit, BN_is_bit_set, BN_mask_bits, BN_lshift,
+BN_lshift1, BN_rshift, BN_rshift1 - bit operations on BIGNUMs
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ int BN_set_bit(BIGNUM *a, int n);
+ int BN_clear_bit(BIGNUM *a, int n);
+
+ int BN_is_bit_set(const BIGNUM *a, int n);
+
+ int BN_mask_bits(BIGNUM *a, int n);
+
+ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+ int BN_lshift1(BIGNUM *r, BIGNUM *a);
+
+ int BN_rshift(BIGNUM *r, BIGNUM *a, int n);
+ int BN_rshift1(BIGNUM *r, BIGNUM *a);
+
+=head1 DESCRIPTION
+
+BN_set_bit() sets bit B<n> in B<a> to 1 (C<a|=(1E<lt>E<lt>n)>). The
+number is expanded if necessary.
+
+BN_clear_bit() sets bit B<n> in B<a> to 0 (C<a&=~(1E<lt>E<lt>n)>). An
+error occurs if B<a> is shorter than B<n> bits.
+
+BN_is_bit_set() tests if bit B<n> in B<a> is set.
+
+BN_mask_bits() truncates B<a> to an B<n> bit number
+(C<a&=~((~0)E<gt>E<gt>n)>).  An error occurs if B<a> already is
+shorter than B<n> bits.
+
+BN_lshift() shifts B<a> left by B<n> bits and places the result in
+B<r> (C<r=a*2^n>). BN_lshift1() shifts B<a> left by one and places
+the result in B<r> (C<r=2*a>).
+
+BN_rshift() shifts B<a> right by B<n> bits and places the result in
+B<r> (C<r=a/2^n>). BN_rshift1() shifts B<a> right by one and places
+the result in B<r> (C<r=a/2>).
+
+For the shift functions, B<r> and B<a> may be the same variable.
+
+=head1 RETURN VALUES
+
+BN_is_bit_set() returns 1 if the bit is set, 0 otherwise.
+
+All other functions return 1 for success, 0 on error. The error codes
+can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>, L<BN_num_bytes(3)|BN_num_bytes(3)>, L<BN_add(3)|BN_add(3)>
+
+=head1 HISTORY
+
+BN_set_bit(), BN_clear_bit(), BN_is_bit_set(), BN_mask_bits(),
+BN_lshift(), BN_lshift1(), BN_rshift(), and BN_rshift1() are available
+in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/BN_swap.pod b/openssl/doc/crypto/BN_swap.pod
new file mode 100644
index 0000000..79efaa1
--- /dev/null
+++ b/openssl/doc/crypto/BN_swap.pod
@@ -0,0 +1,23 @@
+=pod
+
+=head1 NAME
+
+BN_swap - exchange BIGNUMs
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ void BN_swap(BIGNUM *a, BIGNUM *b);
+
+=head1 DESCRIPTION
+
+BN_swap() exchanges the values of I<a> and I<b>.
+
+L<bn(3)|bn(3)>
+
+=head1 HISTORY
+
+BN_swap was added in OpenSSL 0.9.7.
+
+=cut
diff --git a/openssl/doc/crypto/BN_zero.pod b/openssl/doc/crypto/BN_zero.pod
new file mode 100644
index 0000000..b555ec3
--- /dev/null
+++ b/openssl/doc/crypto/BN_zero.pod
@@ -0,0 +1,59 @@
+=pod
+
+=head1 NAME
+
+BN_zero, BN_one, BN_value_one, BN_set_word, BN_get_word - BIGNUM assignment
+operations
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ int BN_zero(BIGNUM *a);
+ int BN_one(BIGNUM *a);
+
+ const BIGNUM *BN_value_one(void);
+
+ int BN_set_word(BIGNUM *a, unsigned long w);
+ unsigned long BN_get_word(BIGNUM *a);
+
+=head1 DESCRIPTION
+
+BN_zero(), BN_one() and BN_set_word() set B<a> to the values 0, 1 and
+B<w> respectively.  BN_zero() and BN_one() are macros.
+
+BN_value_one() returns a B<BIGNUM> constant of value 1. This constant
+is useful for use in comparisons and assignment.
+
+BN_get_word() returns B<a>, if it can be represented as an unsigned
+long.
+
+=head1 RETURN VALUES
+
+BN_get_word() returns the value B<a>, and 0xffffffffL if B<a> cannot
+be represented as an unsigned long.
+
+BN_zero(), BN_one() and BN_set_word() return 1 on success, 0 otherwise.
+BN_value_one() returns the constant.
+
+=head1 BUGS
+
+Someone might change the constant.
+
+If a B<BIGNUM> is equal to 0xffffffffL it can be represented as an
+unsigned long but this value is also returned on error.
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>, L<BN_bn2bin(3)|BN_bn2bin(3)>
+
+=head1 HISTORY
+
+BN_zero(), BN_one() and BN_set_word() are available in all versions of
+SSLeay and OpenSSL. BN_value_one() and BN_get_word() were added in
+SSLeay 0.8.
+
+BN_value_one() was changed to return a true const BIGNUM * in OpenSSL
+0.9.7.
+
+=cut
diff --git a/openssl/doc/crypto/CMS_add0_cert.pod b/openssl/doc/crypto/CMS_add0_cert.pod
new file mode 100644
index 0000000..9c13f48
--- /dev/null
+++ b/openssl/doc/crypto/CMS_add0_cert.pod
@@ -0,0 +1,66 @@
+=pod
+
+=head1 NAME
+
+ CMS_add0_cert, CMS_add1_cert, CMS_get1_certs, CMS_add0_crl, CMS_get1_crls, - CMS certificate and CRL utility functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert);
+ int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert);
+ STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms);
+
+ int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl);
+ int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl);
+ STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms);
+
+
+=head1 DESCRIPTION
+
+CMS_add0_cert() and CMS_add1_cert() add certificate B<cert> to B<cms>.
+must be of type signed data or enveloped data. 
+
+CMS_get1_certs() returns all certificates in B<cms>.
+
+CMS_add0_crl() and CMS_add1_crl() add CRL B<crl> to B<cms>. CMS_get1_crls()
+returns any CRLs in B<cms>.
+
+=head1 NOTES
+
+The CMS_ContentInfo structure B<cms> must be of type signed data or enveloped
+data or an error will be returned.
+
+For signed data certificates and CRLs are added to the B<certificates> and
+B<crls> fields of SignedData structure. For enveloped data they are added to
+B<OriginatorInfo>.
+
+As the B<0> implies CMS_add0_cert() adds B<cert> internally to B<cms> and it
+must not be freed up after the call as opposed to CMS_add1_cert() where B<cert>
+must be freed up.
+
+The same certificate or CRL must not be added to the same cms structure more
+than once.
+
+=head1 RETURN VALUES
+
+CMS_add0_cert(), CMS_add1_cert() and CMS_add0_crl() and CMS_add1_crl() return
+1 for success and 0 for failure. 
+
+CMS_get1_certs() and CMS_get1_crls() return the STACK of certificates or CRLs
+or NULL if there are none or an error occurs. The only error which will occur
+in practice is if the B<cms> type is invalid.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>,
+L<CMS_sign(3)|CMS_sign(3)>,
+L<CMS_encrypt(3)|CMS_encrypt(3)>
+
+=head1 HISTORY
+
+CMS_add0_cert(), CMS_add1_cert(), CMS_get1_certs(), CMS_add0_crl()
+and CMS_get1_crls() were all first added to OpenSSL 0.9.8
+
+=cut
diff --git a/openssl/doc/crypto/CMS_add1_recipient_cert.pod b/openssl/doc/crypto/CMS_add1_recipient_cert.pod
new file mode 100644
index 0000000..d7d8e25
--- /dev/null
+++ b/openssl/doc/crypto/CMS_add1_recipient_cert.pod
@@ -0,0 +1,62 @@
+=pod
+
+=head1 NAME
+
+ CMS_add1_recipient_cert, CMS_add0_recipient_key - add recipients to a CMS enveloped data structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip, unsigned int flags);
+
+ CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, unsigned char *key, size_t keylen, unsigned char *id, size_t idlen, ASN1_GENERALIZEDTIME *date, ASN1_OBJECT *otherTypeId, ASN1_TYPE *otherType);
+
+=head1 DESCRIPTION
+
+CMS_add1_recipient_cert() adds recipient B<recip> to CMS_ContentInfo enveloped
+data structure B<cms> as a KeyTransRecipientInfo structure.
+
+CMS_add0_recipient_key() adds symmetric key B<key> of length B<keylen> using
+wrapping algorithm B<nid>, identifier B<id> of length B<idlen> and optional
+values B<date>, B<otherTypeId> and B<otherType> to CMS_ContentInfo enveloped
+data structure B<cms> as a KEKRecipientInfo structure.
+
+The CMS_ContentInfo structure should be obtained from an initial call to
+CMS_encrypt() with the flag B<CMS_PARTIAL> set.
+
+=head1 NOTES
+
+The main purpose of this function is to provide finer control over a CMS
+enveloped data structure where the simpler CMS_encrypt() function defaults are
+not appropriate. For example if one or more KEKRecipientInfo structures
+need to be added. New attributes can also be added using the returned
+CMS_RecipientInfo structure and the CMS attribute utility functions.
+
+OpenSSL will by default identify recipient certificates using issuer name
+and serial number. If B<CMS_USE_KEYID> is set it will use the subject key
+identifier value instead. An error occurs if all recipient certificates do not
+have a subject key identifier extension.
+
+Currently only AES based key wrapping algorithms are supported for B<nid>,
+specifically: NID_id_aes128_wrap, NID_id_aes192_wrap and NID_id_aes256_wrap.
+If B<nid> is set to B<NID_undef> then an AES wrap algorithm will be used
+consistent with B<keylen>.
+
+=head1 RETURN VALUES
+
+CMS_add1_recipient_cert() and CMS_add0_recipient_key() return an internal
+pointer to the CMS_RecipientInfo structure just added or NULL if an error
+occurs.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_decrypt(3)|CMS_decrypt(3)>,
+L<CMS_final(3)|CMS_final(3)>,
+
+=head1 HISTORY
+
+CMS_add1_recipient_cert() and CMS_add0_recipient_key() were added to OpenSSL
+0.9.8
+
+=cut
diff --git a/openssl/doc/crypto/CMS_compress.pod b/openssl/doc/crypto/CMS_compress.pod
new file mode 100644
index 0000000..0a07152
--- /dev/null
+++ b/openssl/doc/crypto/CMS_compress.pod
@@ -0,0 +1,73 @@
+=pod
+
+=head1 NAME
+
+CMS_compress - create a CMS CompressedData structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags);
+
+=head1 DESCRIPTION
+
+CMS_compress() creates and returns a CMS CompressedData structure. B<comp_nid>
+is the compression algorithm to use or B<NID_undef> to use the default
+algorithm (zlib compression). B<in> is the content to be compressed.
+B<flags> is an optional set of flags.
+
+=head1 NOTES
+
+The only currently supported compression algorithm is zlib using the NID
+NID_zlib_compression.
+
+If zlib support is not compiled into OpenSSL then CMS_compress() will return
+an error.
+
+If the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are
+prepended to the data.
+
+Normally the supplied content is translated into MIME canonical format (as
+required by the S/MIME specifications) if B<CMS_BINARY> is set no translation
+occurs. This option should be used if the supplied data is in binary format
+otherwise the translation will corrupt it. If B<CMS_BINARY> is set then
+B<CMS_TEXT> is ignored.
+
+If the B<CMS_STREAM> flag is set a partial B<CMS_ContentInfo> structure is
+returned suitable for streaming I/O: no data is read from the BIO B<in>.
+
+The compressed data is included in the CMS_ContentInfo structure, unless
+B<CMS_DETACHED> is set in which case it is omitted. This is rarely used in
+practice and is not supported by SMIME_write_CMS().
+
+=head1 NOTES
+
+If the flag B<CMS_STREAM> is set the returned B<CMS_ContentInfo> structure is
+B<not> complete and outputting its contents via a function that does not
+properly finalize the B<CMS_ContentInfo> structure will give unpredictable
+results.
+
+Several functions including SMIME_write_CMS(), i2d_CMS_bio_stream(),
+PEM_write_bio_CMS_stream() finalize the structure. Alternatively finalization
+can be performed by obtaining the streaming ASN1 B<BIO> directly using
+BIO_new_CMS().
+
+Additional compression parameters such as the zlib compression level cannot
+currently be set.
+
+=head1 RETURN VALUES
+
+CMS_compress() returns either a CMS_ContentInfo structure or NULL if an error
+occurred. The error can be obtained from ERR_get_error(3).
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_uncompress(3)|CMS_uncompress(3)>
+
+=head1 HISTORY
+
+CMS_compress() was added to OpenSSL 0.9.8
+The B<CMS_STREAM> flag was first supported in OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/CMS_decrypt.pod b/openssl/doc/crypto/CMS_decrypt.pod
new file mode 100644
index 0000000..d857e4f
--- /dev/null
+++ b/openssl/doc/crypto/CMS_decrypt.pod
@@ -0,0 +1,65 @@
+=pod
+
+=head1 NAME
+
+ CMS_decrypt - decrypt content from a CMS envelopedData structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, BIO *dcont, BIO *out, unsigned int flags);
+
+=head1 DESCRIPTION
+
+CMS_decrypt() extracts and decrypts the content from a CMS EnvelopedData
+structure. B<pkey> is the private key of the recipient, B<cert> is the
+recipient's certificate, B<out> is a BIO to write the content to and
+B<flags> is an optional set of flags.
+
+The B<dcont> parameter is used in the rare case where the encrypted content
+is detached. It will normally be set to NULL.
+
+=head1 NOTES
+
+OpenSSL_add_all_algorithms() (or equivalent) should be called before using this
+function or errors about unknown algorithms will occur.
+
+Although the recipients certificate is not needed to decrypt the data it is
+needed to locate the appropriate (of possible several) recipients in the CMS
+structure. If B<cert> is set to NULL all possible recipients are tried.
+
+It is possible to determine the correct recipient key by other means (for
+example looking them up in a database) and setting them in the CMS structure
+in advance using the CMS utility functions such as CMS_set1_pkey(). In this
+case both B<cert> and B<pkey> should be set to NULL.
+
+To process KEKRecipientInfo types CMS_set1_key() or CMS_RecipientInfo_set0_key()
+and CMS_ReceipientInfo_decrypt() should be called before CMS_decrypt() and
+B<cert> and B<pkey> set to NULL.
+
+The following flags can be passed in the B<flags> parameter.
+
+If the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are deleted
+from the content. If the content is not of type B<text/plain> then an error is
+returned.
+
+=head1 RETURN VALUES
+
+CMS_decrypt() returns either 1 for success or 0 for failure.
+The error can be obtained from ERR_get_error(3)
+
+=head1 BUGS
+
+The lack of single pass processing and the need to hold all data in memory as
+mentioned in CMS_verify() also applies to CMS_decrypt().
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)>
+
+=head1 HISTORY
+
+CMS_decrypt() was added to OpenSSL 0.9.8
+
+=cut
diff --git a/openssl/doc/crypto/CMS_encrypt.pod b/openssl/doc/crypto/CMS_encrypt.pod
new file mode 100644
index 0000000..1ee5b27
--- /dev/null
+++ b/openssl/doc/crypto/CMS_encrypt.pod
@@ -0,0 +1,96 @@
+=pod
+
+=head1 NAME
+
+ CMS_encrypt - create a CMS envelopedData structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, unsigned int flags);
+
+=head1 DESCRIPTION
+
+CMS_encrypt() creates and returns a CMS EnvelopedData structure. B<certs>
+is a list of recipient certificates. B<in> is the content to be encrypted.
+B<cipher> is the symmetric cipher to use. B<flags> is an optional set of flags.
+
+=head1 NOTES
+
+Only certificates carrying RSA keys are supported so the recipient certificates
+supplied to this function must all contain RSA public keys, though they do not
+have to be signed using the RSA algorithm.
+
+EVP_des_ede3_cbc() (triple DES) is the algorithm of choice for S/MIME use
+because most clients will support it.
+
+The algorithm passed in the B<cipher> parameter must support ASN1 encoding of
+its parameters. 
+
+Many browsers implement a "sign and encrypt" option which is simply an S/MIME
+envelopedData containing an S/MIME signed message. This can be readily produced
+by storing the S/MIME signed message in a memory BIO and passing it to
+CMS_encrypt().
+
+The following flags can be passed in the B<flags> parameter.
+
+If the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are
+prepended to the data.
+
+Normally the supplied content is translated into MIME canonical format (as
+required by the S/MIME specifications) if B<CMS_BINARY> is set no translation
+occurs. This option should be used if the supplied data is in binary format
+otherwise the translation will corrupt it. If B<CMS_BINARY> is set then
+B<CMS_TEXT> is ignored.
+
+OpenSSL will by default identify recipient certificates using issuer name
+and serial number. If B<CMS_USE_KEYID> is set it will use the subject key
+identifier value instead. An error occurs if all recipient certificates do not
+have a subject key identifier extension.
+
+If the B<CMS_STREAM> flag is set a partial B<CMS_ContentInfo> structure is
+returned suitable for streaming I/O: no data is read from the BIO B<in>.
+
+If the B<CMS_PARTIAL> flag is set a partial B<CMS_ContentInfo> structure is
+returned to which additional recipients and attributes can be added before
+finalization.
+
+The data being encrypted is included in the CMS_ContentInfo structure, unless
+B<CMS_DETACHED> is set in which case it is omitted. This is rarely used in
+practice and is not supported by SMIME_write_CMS().
+
+=head1 NOTES
+
+If the flag B<CMS_STREAM> is set the returned B<CMS_ContentInfo> structure is
+B<not> complete and outputting its contents via a function that does not
+properly finalize the B<CMS_ContentInfo> structure will give unpredictable
+results.
+
+Several functions including SMIME_write_CMS(), i2d_CMS_bio_stream(),
+PEM_write_bio_CMS_stream() finalize the structure. Alternatively finalization
+can be performed by obtaining the streaming ASN1 B<BIO> directly using
+BIO_new_CMS().
+
+The recipients specified in B<certs> use a CMS KeyTransRecipientInfo info
+structure. KEKRecipientInfo is also supported using the flag B<CMS_PARTIAL>
+and CMS_add0_recipient_key().
+
+The parameter B<certs> may be NULL if B<CMS_PARTIAL> is set and recipients
+added later using CMS_add1_recipient_cert() or CMS_add0_recipient_key().
+
+=head1 RETURN VALUES
+
+CMS_encrypt() returns either a CMS_ContentInfo structure or NULL if an error
+occurred. The error can be obtained from ERR_get_error(3).
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_decrypt(3)|CMS_decrypt(3)>
+
+=head1 HISTORY
+
+CMS_decrypt() was added to OpenSSL 0.9.8
+The B<CMS_STREAM> flag was first supported in OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/CMS_final.pod b/openssl/doc/crypto/CMS_final.pod
new file mode 100644
index 0000000..36cf96b
--- /dev/null
+++ b/openssl/doc/crypto/CMS_final.pod
@@ -0,0 +1,41 @@
+=pod
+
+=head1 NAME
+
+ CMS_final - finalise a CMS_ContentInfo structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags);
+
+=head1 DESCRIPTION
+
+CMS_final() finalises the structure B<cms>. It's purpose is to perform any
+operations necessary on B<cms> (digest computation for example) and set the
+appropriate fields. The parameter B<data> contains the content to be 
+processed. The B<dcont> parameter contains a BIO to write content to after
+processing: this is only used with detached data and will usually be set to
+NULL.
+
+=head1 NOTES
+
+This function will normally be called when the B<CMS_PARTIAL> flag is used. It
+should only be used when streaming is not performed because the streaming
+I/O functions perform finalisation operations internally.
+
+=head1 RETURN VALUES
+
+CMS_final() returns 1 for success or 0 for failure.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
+L<CMS_encrypt(3)|CMS_encrypt(3)>
+
+=head1 HISTORY
+
+CMS_final() was added to OpenSSL 0.9.8
+
+=cut
diff --git a/openssl/doc/crypto/CMS_get0_RecipientInfos.pod b/openssl/doc/crypto/CMS_get0_RecipientInfos.pod
new file mode 100644
index 0000000..e035542
--- /dev/null
+++ b/openssl/doc/crypto/CMS_get0_RecipientInfos.pod
@@ -0,0 +1,106 @@
+=pod
+
+=head1 NAME
+
+ CMS_get0_RecipientInfos, CMS_RecipientInfo_type, CMS_RecipientInfo_ktri_get0_signer_id,CMS_RecipientInfo_ktri_cert_cmp, CMS_RecipientInfo_set0_pkey, CMS_RecipientInfo_kekri_get0_id, CMS_RecipientInfo_kekri_id_cmp, CMS_RecipientInfo_set0_key, CMS_RecipientInfo_decrypt - CMS envelopedData RecipientInfo routines
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
+ int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
+
+ int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno);
+ int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert);
+ int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey);
+
+ int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, X509_ALGOR **palg, ASN1_OCTET_STRING **pid, ASN1_GENERALIZEDTIME **pdate, ASN1_OBJECT **potherid, ASN1_TYPE **pothertype);
+ int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, const unsigned char *id, size_t idlen);
+ int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, unsigned char *key, size_t keylen);
+
+ int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
+
+=head1 DESCRIPTION
+
+The function CMS_get0_RecipientInfos() returns all the CMS_RecipientInfo
+structures associated with a CMS EnvelopedData structure.
+
+CMS_RecipientInfo_type() returns the type of CMS_RecipientInfo structure B<ri>.
+It will currently return CMS_RECIPINFO_TRANS, CMS_RECIPINFO_AGREE,
+CMS_RECIPINFO_KEK, CMS_RECIPINFO_PASS, or CMS_RECIPINFO_OTHER.
+
+CMS_RecipientInfo_ktri_get0_signer_id() retrieves the certificate recipient
+identifier associated with a specific CMS_RecipientInfo structure B<ri>, which
+must be of type CMS_RECIPINFO_TRANS. Either the keyidentifier will be set in
+B<keyid> or B<both> issuer name and serial number in B<issuer> and B<sno>. 
+
+CMS_RecipientInfo_ktri_cert_cmp() compares the certificate B<cert> against the
+CMS_RecipientInfo structure B<ri>, which must be of type CMS_RECIPINFO_TRANS.
+It returns zero if the comparison is successful and non zero if not.
+
+CMS_RecipientInfo_set0_pkey() associates the private key B<pkey> with
+the CMS_RecipientInfo structure B<ri>, which must be of type
+CMS_RECIPINFO_TRANS.
+
+CMS_RecipientInfo_kekri_get0_id() retrieves the key information from the
+CMS_RecipientInfo structure B<ri> which must be of type CMS_RECIPINFO_KEK.  Any
+of the remaining parameters can be NULL if the application is not interested in
+the value of a field. Where a field is optional and absent NULL will be written
+to the corresponding parameter. The keyEncryptionAlgorithm field is written to
+B<palg>, the B<keyIdentifier> field is written to B<pid>, the B<date> field if
+present is written to B<pdate>, if the B<other> field is present the components
+B<keyAttrId> and B<keyAttr> are written to parameters B<potherid> and
+B<pothertype>.
+
+CMS_RecipientInfo_kekri_id_cmp() compares the ID in the B<id> and B<idlen>
+parameters against the B<keyIdentifier> CMS_RecipientInfo structure B<ri>,
+which must be of type CMS_RECIPINFO_KEK.  It returns zero if the comparison is
+successful and non zero if not.
+
+CMS_RecipientInfo_set0_key() associates the symmetric key B<key> of length
+B<keylen> with the CMS_RecipientInfo structure B<ri>, which must be of type
+CMS_RECIPINFO_KEK.
+
+CMS_RecipientInfo_decrypt() attempts to decrypt CMS_RecipientInfo structure
+B<ri> in structure B<cms>. A key must have been associated with the structure
+first.
+
+=head1 NOTES
+
+The main purpose of these functions is to enable an application to lookup
+recipient keys using any appropriate technique when the simpler method
+of CMS_decrypt() is not appropriate.
+
+In typical usage and application will retrieve all CMS_RecipientInfo structures
+using CMS_get0_RecipientInfos() and check the type of each using
+CMS_RecpientInfo_type(). Depending on the type the CMS_RecipientInfo structure
+can be ignored or its key identifier data retrieved using an appropriate
+function. Then if the corresponding secret or private key can be obtained by
+any appropriate means it can then associated with the structure and
+CMS_RecpientInfo_decrypt() called. If successful CMS_decrypt() can be called
+with a NULL key to decrypt the enveloped content.
+
+=head1 RETURN VALUES
+
+CMS_get0_RecipientInfos() returns all CMS_RecipientInfo structures, or NULL if
+an error occurs.
+
+CMS_RecipientInfo_ktri_get0_signer_id(), CMS_RecipientInfo_set0_pkey(),
+CMS_RecipientInfo_kekri_get0_id(), CMS_RecipientInfo_set0_key() and
+CMS_RecipientInfo_decrypt() return 1 for success or 0 if an error occurs.
+
+CMS_RecipientInfo_ktri_cert_cmp() and CMS_RecipientInfo_kekri_cmp() return 0
+for a successful comparison and non zero otherwise.
+
+Any error can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_decrypt(3)|CMS_decrypt(3)>
+
+=head1 HISTORY
+
+These functions were first was added to OpenSSL 0.9.8
+
+=cut
diff --git a/openssl/doc/crypto/CMS_get0_SignerInfos.pod b/openssl/doc/crypto/CMS_get0_SignerInfos.pod
new file mode 100644
index 0000000..47f6d2a
--- /dev/null
+++ b/openssl/doc/crypto/CMS_get0_SignerInfos.pod
@@ -0,0 +1,75 @@
+=pod
+
+=head1 NAME
+
+ CMS_get0_SignerInfos, CMS_SignerInfo_get0_signer_id, CMS_SignerInfo_cert_cmp, CMS_set1_signer_certs - CMS signedData signer functions.
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms);
+
+ int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno);
+ int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert);
+ void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer);
+
+=head1 DESCRIPTION
+
+The function CMS_get0_SignerInfos() returns all the CMS_SignerInfo structures
+associated with a CMS signedData structure.
+
+CMS_SignerInfo_get0_signer_id() retrieves the certificate signer identifier
+associated with a specific CMS_SignerInfo structure B<si>. Either the
+keyidentifier will be set in B<keyid> or B<both> issuer name and serial number
+in B<issuer> and B<sno>.
+
+CMS_SignerInfo_cert_cmp() compares the certificate B<cert> against the signer
+identifier B<si>. It returns zero if the comparison is successful and non zero
+if not.
+
+CMS_SignerInfo_set1_signer_cert() sets the signers certificate of B<si> to
+B<signer>.
+
+=head1 NOTES
+
+The main purpose of these functions is to enable an application to lookup
+signers certificates using any appropriate technique when the simpler method
+of CMS_verify() is not appropriate.
+
+In typical usage and application will retrieve all CMS_SignerInfo structures
+using CMS_get0_SignerInfo() and retrieve the identifier information using
+CMS. It will then obtain the signer certificate by some unspecified means
+(or return and error if it cannot be found) and set it using
+CMS_SignerInfo_set1_signer_cert().
+
+Once all signer certificates have been set CMS_verify() can be used.
+
+Although CMS_get0_SignerInfos() can return NULL is an error occur B<or> if
+there are no signers this is not a problem in practice because the only
+error which can occur is if the B<cms> structure is not of type signedData
+due to application error.
+
+=head1 RETURN VALUES
+
+CMS_get0_SignerInfos() returns all CMS_SignerInfo structures, or NULL there
+are no signers or an error occurs.
+
+CMS_SignerInfo_get0_signer_id() returns 1 for success and 0 for failure.
+
+CMS_SignerInfo_cert_cmp() returns 0 for a successful comparison and non
+zero otherwise.
+
+CMS_SignerInfo_set1_signer_cert() does not return a value.
+
+Any error can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_verify(3)|CMS_verify(3)>
+
+=head1 HISTORY
+
+These functions were first was added to OpenSSL 0.9.8
+
+=cut
diff --git a/openssl/doc/crypto/CMS_get0_type.pod b/openssl/doc/crypto/CMS_get0_type.pod
new file mode 100644
index 0000000..8ff1c31
--- /dev/null
+++ b/openssl/doc/crypto/CMS_get0_type.pod
@@ -0,0 +1,63 @@
+=pod
+
+=head1 NAME
+
+ CMS_get0_type, CMS_set1_eContentType, CMS_get0_eContentType - get and set CMS content types
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms);
+ int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid);
+ const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms);
+
+=head1 DESCRIPTION
+
+CMS_get0_type() returns the content type of a CMS_ContentInfo structure as
+and ASN1_OBJECT pointer. An application can then decide how to process the
+CMS_ContentInfo structure based on this value.
+
+CMS_set1_eContentType() sets the embedded content type of a CMS_ContentInfo
+structure. It should be called with CMS functions with the B<CMS_PARTIAL>
+flag and B<before> the structure is finalised, otherwise the results are
+undefined.
+
+ASN1_OBJECT *CMS_get0_eContentType() returns a pointer to the embedded
+content type.
+
+=head1 NOTES
+
+As the B<0> implies CMS_get0_type() and CMS_get0_eContentType() return internal
+pointers which should B<not> be freed up. CMS_set1_eContentType() copies the
+supplied OID and it B<should> be freed up after use.
+
+The B<ASN1_OBJECT> values returned can be converted to an integer B<NID> value
+using OBJ_obj2nid(). For the currently supported content types the following
+values are returned:
+
+ NID_pkcs7_data
+ NID_pkcs7_signed
+ NID_pkcs7_digest
+ NID_id_smime_ct_compressedData:
+ NID_pkcs7_encrypted
+ NID_pkcs7_enveloped
+
+
+=head1 RETURN VALUES
+
+CMS_get0_type() and CMS_get0_eContentType() return and ASN1_OBJECT structure.
+
+CMS_set1_eContentType() returns 1 for success or 0 if an error occurred.  The
+error can be obtained from ERR_get_error(3).
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>
+
+=head1 HISTORY
+
+CMS_get0_type(), CMS_set1_eContentType() and CMS_get0_eContentType() were all
+first added to OpenSSL 0.9.8
+
+=cut
diff --git a/openssl/doc/crypto/CMS_get1_ReceiptRequest.pod b/openssl/doc/crypto/CMS_get1_ReceiptRequest.pod
new file mode 100644
index 0000000..f546376
--- /dev/null
+++ b/openssl/doc/crypto/CMS_get1_ReceiptRequest.pod
@@ -0,0 +1,69 @@
+=pod
+
+=head1 NAME
+
+ CMS_ReceiptRequest_create0, CMS_add1_ReceiptRequest, CMS_get1_ReceiptRequest, CMS_ReceiptRequest_get0_values - CMS signed receipt request functions.
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, int allorfirst, STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo);
+ int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
+ int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
+ void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, ASN1_STRING **pcid, int *pallorfirst, STACK_OF(GENERAL_NAMES) **plist, STACK_OF(GENERAL_NAMES) **prto);
+
+=head1 DESCRIPTION
+
+CMS_ReceiptRequest_create0() creates a signed receipt request structure. The
+B<signedContentIdentifier> field is set using B<id> and B<idlen>, or it is set
+to 32 bytes of pseudo random data if B<id> is NULL. If B<receiptList> is NULL
+the allOrFirstTier option in B<receiptsFrom> is used and set to the value of
+the B<allorfirst> parameter. If B<receiptList> is not NULL the B<receiptList>
+option in B<receiptsFrom> is used. The B<receiptsTo> parameter specifies the
+B<receiptsTo> field value.
+
+The CMS_add1_ReceiptRequest() function adds a signed receipt request B<rr>
+to SignerInfo structure B<si>.
+
+int CMS_get1_ReceiptRequest() looks for a signed receipt request in B<si>, if
+any is found it is decoded and written to B<prr>.
+
+CMS_ReceiptRequest_get0_values() retrieves the values of a receipt request.
+The signedContentIdentifier is copied to B<pcid>. If the B<allOrFirstTier>
+option of B<receiptsFrom> is used its value is copied to B<pallorfirst>
+otherwise the B<receiptList> field is copied to B<plist>. The B<receiptsTo>
+parameter is copied to B<prto>.
+
+=head1 NOTES
+
+For more details of the meaning of the fields see RFC2634.
+
+The contents of a signed receipt should only be considered meaningful if the
+corresponding CMS_ContentInfo structure can be successfully verified using
+CMS_verify().
+
+=head1 RETURN VALUES
+
+CMS_ReceiptRequest_create0() returns a signed receipt request structure or 
+NULL if an error occurred.
+
+CMS_add1_ReceiptRequest() returns 1 for success or 0 is an error occurred.
+
+CMS_get1_ReceiptRequest() returns 1 is a signed receipt request is found and
+decoded. It returns 0 if a signed receipt request is not present and -1 if
+it is present but malformed.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
+L<CMS_sign_receipt(3)|CMS_sign_receipt(3)>, L<CMS_verify(3)|CMS_verify(3)>
+L<CMS_verify_receipt(3)|CMS_verify_receipt(3)>
+
+=head1 HISTORY
+
+CMS_ReceiptRequest_create0(), CMS_add1_ReceiptRequest(),
+CMS_get1_ReceiptRequest() and CMS_ReceiptRequest_get0_values() were added to
+OpenSSL 0.9.8
+
+=cut
diff --git a/openssl/doc/crypto/CMS_sign.pod b/openssl/doc/crypto/CMS_sign.pod
new file mode 100644
index 0000000..2cc72de
--- /dev/null
+++ b/openssl/doc/crypto/CMS_sign.pod
@@ -0,0 +1,121 @@
+=pod
+
+=head1 NAME
+
+ CMS_sign - create a CMS SignedData structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, unsigned int flags);
+
+=head1 DESCRIPTION
+
+CMS_sign() creates and returns a CMS SignedData structure. B<signcert> is
+the certificate to sign with, B<pkey> is the corresponding private key.
+B<certs> is an optional additional set of certificates to include in the CMS
+structure (for example any intermediate CAs in the chain). Any or all of
+these parameters can be B<NULL>, see B<NOTES> below.
+
+The data to be signed is read from BIO B<data>.
+
+B<flags> is an optional set of flags.
+
+=head1 NOTES
+
+Any of the following flags (ored together) can be passed in the B<flags>
+parameter.
+
+Many S/MIME clients expect the signed content to include valid MIME headers. If
+the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are prepended
+to the data.
+
+If B<CMS_NOCERTS> is set the signer's certificate will not be included in the
+CMS_ContentInfo structure, the signer's certificate must still be supplied in
+the B<signcert> parameter though. This can reduce the size of the signature if
+the signers certificate can be obtained by other means: for example a
+previously signed message.
+
+The data being signed is included in the CMS_ContentInfo structure, unless
+B<CMS_DETACHED> is set in which case it is omitted. This is used for
+CMS_ContentInfo detached signatures which are used in S/MIME plaintext signed
+messages for example.
+
+Normally the supplied content is translated into MIME canonical format (as
+required by the S/MIME specifications) if B<CMS_BINARY> is set no translation
+occurs. This option should be used if the supplied data is in binary format
+otherwise the translation will corrupt it.
+
+The SignedData structure includes several CMS signedAttributes including the
+signing time, the CMS content type and the supported list of ciphers in an
+SMIMECapabilities attribute. If B<CMS_NOATTR> is set then no signedAttributes
+will be used. If B<CMS_NOSMIMECAP> is set then just the SMIMECapabilities are
+omitted.
+
+If present the SMIMECapabilities attribute indicates support for the following
+algorithms in preference order: 256 bit AES, Gost R3411-94, Gost 28147-89, 192
+bit AES, 128 bit AES, triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2.
+If any of these algorithms is not available then it will not be included: for example the GOST algorithms will not be included if the GOST ENGINE is
+not loaded.
+
+OpenSSL will by default identify signing certificates using issuer name
+and serial number. If B<CMS_USE_KEYID> is set it will use the subject key
+identifier value instead. An error occurs if the signing certificate does not
+have a subject key identifier extension.
+
+If the flags B<CMS_STREAM> is set then the returned B<CMS_ContentInfo>
+structure is just initialized ready to perform the signing operation. The
+signing is however B<not> performed and the data to be signed is not read from
+the B<data> parameter. Signing is deferred until after the data has been
+written. In this way data can be signed in a single pass.
+
+If the B<CMS_PARTIAL> flag is set a partial B<CMS_ContentInfo> structure is
+output to which additional signers and capabilities can be added before
+finalization.
+
+If the flag B<CMS_STREAM> is set the returned B<CMS_ContentInfo> structure is
+B<not> complete and outputting its contents via a function that does not
+properly finalize the B<CMS_ContentInfo> structure will give unpredictable
+results.
+
+Several functions including SMIME_write_CMS(), i2d_CMS_bio_stream(),
+PEM_write_bio_CMS_stream() finalize the structure. Alternatively finalization
+can be performed by obtaining the streaming ASN1 B<BIO> directly using
+BIO_new_CMS().
+
+If a signer is specified it will use the default digest for the signing
+algorithm. This is B<SHA1> for both RSA and DSA keys.
+
+If B<signcert> and B<pkey> are NULL then a certificates only CMS structure is
+output.
+
+The function CMS_sign() is a basic CMS signing function whose output will be
+suitable for many purposes. For finer control of the output format the
+B<certs>, B<signcert> and B<pkey> parameters can all be B<NULL> and the
+B<CMS_PARTIAL> flag set. Then one or more signers can be added using the
+function CMS_sign_add1_signer(), non default digests can be used and custom
+attributes added. B<CMS_final()> must then be called to finalize the
+structure if streaming is not enabled. 
+
+=head1 BUGS
+
+Some attributes such as counter signatures are not supported.
+
+=head1 RETURN VALUES
+
+CMS_sign() returns either a valid CMS_ContentInfo structure or NULL if an error
+occurred. The error can be obtained from ERR_get_error(3).
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_verify(3)|CMS_verify(3)>
+
+=head1 HISTORY
+
+CMS_sign() was added to OpenSSL 0.9.8
+
+The B<CMS_STREAM> flag is only supported for detached data in OpenSSL 0.9.8,
+it is supported for embedded data in OpenSSL 1.0.0 and later.
+
+=cut
diff --git a/openssl/doc/crypto/CMS_sign_add1_signer.pod b/openssl/doc/crypto/CMS_sign_add1_signer.pod
new file mode 100644
index 0000000..bda3ca2
--- /dev/null
+++ b/openssl/doc/crypto/CMS_sign_add1_signer.pod
@@ -0,0 +1,101 @@
+=pod
+
+=head1 NAME
+
+ CMS_sign_add1_signer, CMS_SignerInfo_sign - add a signer to a CMS_ContentInfo signed data structure.
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ CMS_SignerInfo *CMS_sign_add1_signer(CMS_ContentInfo *cms, X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md, unsigned int flags);
+
+ int CMS_SignerInfo_sign(CMS_SignerInfo *si);
+
+
+=head1 DESCRIPTION
+
+CMS_sign_add1_signer() adds a signer with certificate B<signcert> and private
+key B<pkey> using message digest B<md> to CMS_ContentInfo SignedData
+structure B<cms>.
+
+The CMS_ContentInfo structure should be obtained from an initial call to
+CMS_sign() with the flag B<CMS_PARTIAL> set or in the case or re-signing a
+valid CMS_ContentInfo SignedData structure.
+
+If the B<md> parameter is B<NULL> then the default digest for the public
+key algorithm will be used.
+
+Unless the B<CMS_REUSE_DIGEST> flag is set the returned CMS_ContentInfo
+structure is not complete and must be finalized either by streaming (if
+applicable) or a call to CMS_final().
+
+The CMS_SignerInfo_sign() function will explicitly sign a CMS_SignerInfo
+structure, its main use is when B<CMS_REUSE_DIGEST> and B<CMS_PARTIAL> flags
+are both set.
+
+=head1 NOTES
+
+The main purpose of CMS_sign_add1_signer() is to provide finer control
+over a CMS signed data structure where the simpler CMS_sign() function defaults
+are not appropriate. For example if multiple signers or non default digest
+algorithms are needed. New attributes can also be added using the returned
+CMS_SignerInfo structure and the CMS attribute utility functions or the
+CMS signed receipt request functions.
+
+Any of the following flags (ored together) can be passed in the B<flags>
+parameter.
+
+If B<CMS_REUSE_DIGEST> is set then an attempt is made to copy the content
+digest value from the CMS_ContentInfo structure: to add a signer to an existing
+structure.  An error occurs if a matching digest value cannot be found to copy.
+The returned CMS_ContentInfo structure will be valid and finalized when this
+flag is set.
+
+If B<CMS_PARTIAL> is set in addition to B<CMS_REUSE_DIGEST> then the 
+CMS_SignerInfo structure will not be finalized so additional attributes
+can be added. In this case an explicit call to CMS_SignerInfo_sign() is
+needed to finalize it.
+
+If B<CMS_NOCERTS> is set the signer's certificate will not be included in the
+CMS_ContentInfo structure, the signer's certificate must still be supplied in
+the B<signcert> parameter though. This can reduce the size of the signature if
+the signers certificate can be obtained by other means: for example a
+previously signed message.
+
+The SignedData structure includes several CMS signedAttributes including the
+signing time, the CMS content type and the supported list of ciphers in an
+SMIMECapabilities attribute. If B<CMS_NOATTR> is set then no signedAttributes
+will be used. If B<CMS_NOSMIMECAP> is set then just the SMIMECapabilities are
+omitted.
+
+OpenSSL will by default identify signing certificates using issuer name
+and serial number. If B<CMS_USE_KEYID> is set it will use the subject key
+identifier value instead. An error occurs if the signing certificate does not
+have a subject key identifier extension.
+
+If present the SMIMECapabilities attribute indicates support for the following
+algorithms in preference order: 256 bit AES, Gost R3411-94, Gost 28147-89, 192
+bit AES, 128 bit AES, triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2.
+If any of these algorithms is not available then it will not be included: for example the GOST algorithms will not be included if the GOST ENGINE is
+not loaded.
+
+CMS_sign_add1_signer() returns an internal pointer to the CMS_SignerInfo
+structure just added, this can be used to set additional attributes 
+before it is finalized.
+
+=head1 RETURN VALUES
+
+CMS_sign1_add_signers() returns an internal pointer to the CMS_SignerInfo
+structure just added or NULL if an error occurs.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
+L<CMS_final(3)|CMS_final(3)>,
+
+=head1 HISTORY
+
+CMS_sign_add1_signer() was added to OpenSSL 0.9.8
+
+=cut
diff --git a/openssl/doc/crypto/CMS_sign_receipt.pod b/openssl/doc/crypto/CMS_sign_receipt.pod
new file mode 100644
index 0000000..cae1f83
--- /dev/null
+++ b/openssl/doc/crypto/CMS_sign_receipt.pod
@@ -0,0 +1,45 @@
+=pod
+
+=head1 NAME
+
+ CMS_sign_receipt - create a CMS signed receipt
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, unsigned int flags);
+
+=head1 DESCRIPTION
+
+CMS_sign_receipt() creates and returns a CMS signed receipt structure. B<si> is
+the B<CMS_SignerInfo> structure containing the signed receipt request.
+B<signcert> is the certificate to sign with, B<pkey> is the corresponding
+private key.  B<certs> is an optional additional set of certificates to include
+in the CMS structure (for example any intermediate CAs in the chain).
+
+B<flags> is an optional set of flags.
+
+=head1 NOTES
+
+This functions behaves in a similar way to CMS_sign() except the flag values
+B<CMS_DETACHED>, B<CMS_BINARY>, B<CMS_NOATTR>, B<CMS_TEXT> and B<CMS_STREAM>
+are not supported since they do not make sense in the context of signed
+receipts.
+
+=head1 RETURN VALUES
+
+CMS_sign_receipt() returns either a valid CMS_ContentInfo structure or NULL if
+an error occurred.  The error can be obtained from ERR_get_error(3).
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>,
+L<CMS_verify_receipt(3)|CMS_verify_receipt(3)>,
+L<CMS_sign(3)|CMS_sign(3)>
+
+=head1 HISTORY
+
+CMS_sign_receipt() was added to OpenSSL 0.9.8
+
+=cut
diff --git a/openssl/doc/crypto/CMS_uncompress.pod b/openssl/doc/crypto/CMS_uncompress.pod
new file mode 100644
index 0000000..c6056b0
--- /dev/null
+++ b/openssl/doc/crypto/CMS_uncompress.pod
@@ -0,0 +1,54 @@
+=pod
+
+=head1 NAME
+
+ CMS_uncompress - uncompress a CMS CompressedData structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags);
+
+=head1 DESCRIPTION
+
+CMS_uncompress() extracts and uncompresses the content from a CMS
+CompressedData structure B<cms>. B<data> is a BIO to write the content to and
+B<flags> is an optional set of flags.
+
+The B<dcont> parameter is used in the rare case where the compressed content
+is detached. It will normally be set to NULL.
+
+=head1 NOTES
+
+The only currently supported compression algorithm is zlib: if the structure
+indicates the use of any other algorithm an error is returned.
+
+If zlib support is not compiled into OpenSSL then CMS_uncompress() will always
+return an error.
+
+The following flags can be passed in the B<flags> parameter.
+
+If the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are deleted
+from the content. If the content is not of type B<text/plain> then an error is
+returned.
+
+=head1 RETURN VALUES
+
+CMS_uncompress() returns either 1 for success or 0 for failure. The error can
+be obtained from ERR_get_error(3)
+
+=head1 BUGS
+
+The lack of single pass processing and the need to hold all data in memory as
+mentioned in CMS_verify() also applies to CMS_decompress().
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_compress(3)|CMS_compress(3)>
+
+=head1 HISTORY
+
+CMS_uncompress() was added to OpenSSL 0.9.8
+
+=cut
diff --git a/openssl/doc/crypto/CMS_verify.pod b/openssl/doc/crypto/CMS_verify.pod
new file mode 100644
index 0000000..8f26fda
--- /dev/null
+++ b/openssl/doc/crypto/CMS_verify.pod
@@ -0,0 +1,126 @@
+=pod
+
+=head1 NAME
+
+ CMS_verify - verify a CMS SignedData structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, BIO *out, unsigned int flags);
+
+ STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
+
+=head1 DESCRIPTION
+
+CMS_verify() verifies a CMS SignedData structure. B<cms> is the CMS_ContentInfo
+structure to verify. B<certs> is a set of certificates in which to search for
+the signing certificate(s). B<store> is a trusted certificate store used for
+chain verification. B<indata> is the detached content if the content is not
+present in B<cms>. The content is written to B<out> if it is not NULL.
+
+B<flags> is an optional set of flags, which can be used to modify the verify
+operation.
+
+CMS_get0_signers() retrieves the signing certificate(s) from B<cms>, it must
+be called after a successful CMS_verify() operation.
+
+=head1 VERIFY PROCESS
+
+Normally the verify process proceeds as follows.
+
+Initially some sanity checks are performed on B<cms>. The type of B<cms> must
+be SignedData. There must be at least one signature on the data and if
+the content is detached B<indata> cannot be B<NULL>.
+
+An attempt is made to locate all the signing certificate(s), first looking in
+the B<certs> parameter (if it is not NULL) and then looking in any
+certificates contained in the B<cms> structure itself. If any signing
+certificate cannot be located the operation fails.
+
+Each signing certificate is chain verified using the B<smimesign> purpose and
+the supplied trusted certificate store. Any internal certificates in the message
+are used as untrusted CAs. If CRL checking is enabled in B<store> any internal
+CRLs are used in addition to attempting to look them up in B<store>. If any
+chain verify fails an error code is returned.
+
+Finally the signed content is read (and written to B<out> is it is not NULL)
+and the signature's checked.
+
+If all signature's verify correctly then the function is successful.
+
+Any of the following flags (ored together) can be passed in the B<flags>
+parameter to change the default verify behaviour.
+
+If B<CMS_NOINTERN> is set the certificates in the message itself are not
+searched when locating the signing certificate(s). This means that all the
+signing certificates must be in the B<certs> parameter.
+
+If B<CMS_NOCRL> is set and CRL checking is enabled in B<store> then any
+CRLs in the message itself are ignored.
+
+If the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are deleted
+from the content. If the content is not of type B<text/plain> then an error is
+returned.
+
+If B<CMS_NO_SIGNER_CERT_VERIFY> is set the signing certificates are not
+verified.
+
+If B<CMS_NO_ATTR_VERIFY> is set the signed attributes signature is not 
+verified.
+
+If B<CMS_NO_CONTENT_VERIFY> is set then the content digest is not checked.
+
+=head1 NOTES
+
+One application of B<CMS_NOINTERN> is to only accept messages signed by
+a small number of certificates. The acceptable certificates would be passed
+in the B<certs> parameter. In this case if the signer is not one of the
+certificates supplied in B<certs> then the verify will fail because the
+signer cannot be found.
+
+In some cases the standard techniques for looking up and validating
+certificates are not appropriate: for example an application may wish to 
+lookup certificates in a database or perform customised verification. This
+can be achieved by setting and verifying the signers certificates manually 
+using the signed data utility functions.
+
+Care should be taken when modifying the default verify behaviour, for example
+setting B<CMS_NO_CONTENT_VERIFY> will totally disable all content verification 
+and any modified content will be considered valid. This combination is however
+useful if one merely wishes to write the content to B<out> and its validity
+is not considered important.
+
+Chain verification should arguably be performed using the signing time rather
+than the current time. However since the signing time is supplied by the
+signer it cannot be trusted without additional evidence (such as a trusted
+timestamp).
+
+=head1 RETURN VALUES
+
+CMS_verify() returns 1 for a successful verification and zero if an error
+occurred.
+
+CMS_get0_signers() returns all signers or NULL if an error occurred.
+
+The error can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>
+
+=head1 BUGS
+
+The trusted certificate store is not searched for the signing certificate,
+this is primarily due to the inadequacies of the current B<X509_STORE>
+functionality.
+
+The lack of single pass processing means that the signed content must all
+be held in memory if it is not detached.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>
+
+=head1 HISTORY
+
+CMS_verify() was added to OpenSSL 0.9.8
+
+=cut
diff --git a/openssl/doc/crypto/CMS_verify_receipt.pod b/openssl/doc/crypto/CMS_verify_receipt.pod
new file mode 100644
index 0000000..9283e0e
--- /dev/null
+++ b/openssl/doc/crypto/CMS_verify_receipt.pod
@@ -0,0 +1,47 @@
+=pod
+
+=head1 NAME
+
+ CMS_verify_receipt - verify a CMS signed receipt
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, STACK_OF(X509) *certs, X509_STORE *store, unsigned int flags);
+
+=head1 DESCRIPTION
+
+CMS_verify_receipt() verifies a CMS signed receipt. B<rcms> is the signed
+receipt to verify. B<ocms> is the original SignedData structure containing the
+receipt request. B<certs> is a set of certificates in which to search for the
+signing certificate. B<store> is a trusted certificate store (used for chain
+verification). 
+
+B<flags> is an optional set of flags, which can be used to modify the verify
+operation.
+
+=head1 NOTES
+
+This functions behaves in a similar way to CMS_verify() except the flag values
+B<CMS_DETACHED>, B<CMS_BINARY>, B<CMS_TEXT> and B<CMS_STREAM> are not
+supported since they do not make sense in the context of signed receipts.
+
+=head1 RETURN VALUES
+
+CMS_verify_receipt() returns 1 for a successful verification and zero if an
+error occurred.
+
+The error can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>,
+L<CMS_sign_receipt(3)|CMS_sign_receipt(3)>,
+L<CMS_verify(3)|CMS_verify(3)>,
+
+=head1 HISTORY
+
+CMS_verify_receipt() was added to OpenSSL 0.9.8
+
+=cut
diff --git a/openssl/doc/crypto/CONF_modules_free.pod b/openssl/doc/crypto/CONF_modules_free.pod
new file mode 100644
index 0000000..87bc7b7
--- /dev/null
+++ b/openssl/doc/crypto/CONF_modules_free.pod
@@ -0,0 +1,47 @@
+=pod
+
+=head1 NAME
+
+ CONF_modules_free, CONF_modules_finish, CONF_modules_unload -
+ OpenSSL configuration cleanup functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/conf.h>
+
+ void CONF_modules_free(void);
+ void CONF_modules_finish(void);
+ void CONF_modules_unload(int all);
+
+=head1 DESCRIPTION
+
+CONF_modules_free() closes down and frees up all memory allocated by all
+configuration modules.
+
+CONF_modules_finish() calls each configuration modules B<finish> handler
+to free up any configuration that module may have performed.
+
+CONF_modules_unload() finishes and unloads configuration modules. If
+B<all> is set to B<0> only modules loaded from DSOs will be unloads. If
+B<all> is B<1> all modules, including builtin modules will be unloaded.
+
+=head1 NOTES
+
+Normally applications will only call CONF_modules_free() at application to
+tidy up any configuration performed.
+
+=head1 RETURN VALUE
+
+None of the functions return a value.
+
+=head1 SEE ALSO
+
+L<conf(5)|conf(5)>, L<OPENSSL_config(3)|OPENSSL_config(3)>,
+L<CONF_modules_load_file(3), CONF_modules_load_file(3)>
+
+=head1 HISTORY
+
+CONF_modules_free(), CONF_modules_unload(), and CONF_modules_finish()
+first appeared in OpenSSL 0.9.7.
+
+=cut
diff --git a/openssl/doc/crypto/CONF_modules_load_file.pod b/openssl/doc/crypto/CONF_modules_load_file.pod
new file mode 100644
index 0000000..9965d69
--- /dev/null
+++ b/openssl/doc/crypto/CONF_modules_load_file.pod
@@ -0,0 +1,60 @@
+=pod
+
+=head1 NAME
+
+ CONF_modules_load_file, CONF_modules_load - OpenSSL configuration functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/conf.h>
+
+ int CONF_modules_load_file(const char *filename, const char *appname,
+			   unsigned long flags);
+ int CONF_modules_load(const CONF *cnf, const char *appname,
+		      unsigned long flags);
+
+=head1 DESCRIPTION
+
+The function CONF_modules_load_file() configures OpenSSL using file
+B<filename> and application name B<appname>. If B<filename> is NULL
+the standard OpenSSL configuration file is used. If B<appname> is
+NULL the standard OpenSSL application name B<openssl_conf> is used.
+The behaviour can be cutomized using B<flags>.
+
+CONF_modules_load() is idential to CONF_modules_load_file() except it
+read configuration information from B<cnf>. 
+
+=head1 NOTES
+
+The following B<flags> are currently recognized:
+
+B<CONF_MFLAGS_IGNORE_ERRORS> if set errors returned by individual
+configuration modules are ignored. If not set the first module error is
+considered fatal and no further modules are loads.
+
+Normally any modules errors will add error information to the error queue. If
+B<CONF_MFLAGS_SILENT> is set no error information is added.
+
+If B<CONF_MFLAGS_NO_DSO> is set configuration module loading from DSOs is
+disabled.
+
+B<CONF_MFLAGS_IGNORE_MISSING_FILE> if set will make CONF_load_modules_file()
+ignore missing configuration files. Normally a missing configuration file
+return an error.
+
+=head1 RETURN VALUE
+
+These functions return 1 for success and a zero or negative value for
+failure. If module errors are not ignored the return code will reflect the
+return value of the failing module (this will always be zero or negative).
+
+=head1 SEE ALSO
+
+L<conf(5)|conf(5)>, L<OPENSSL_config(3)|OPENSSL_config(3)>,
+L<CONF_free(3), CONF_free(3)>, L<err(3),err(3)>
+
+=head1 HISTORY
+
+CONF_modules_load_file and CONF_modules_load first appeared in OpenSSL 0.9.7.
+
+=cut
diff --git a/openssl/doc/crypto/CRYPTO_set_ex_data.pod b/openssl/doc/crypto/CRYPTO_set_ex_data.pod
new file mode 100644
index 0000000..7409c02
--- /dev/null
+++ b/openssl/doc/crypto/CRYPTO_set_ex_data.pod
@@ -0,0 +1,53 @@
+=pod
+
+=head1 NAME
+
+CRYPTO_set_ex_data, CRYPTO_get_ex_data - internal application specific data functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/crypto.h>
+
+ int CRYPTO_set_ex_data(CRYPTO_EX_DATA *r, int idx, void *arg);
+
+ void *CRYPTO_get_ex_data(CRYPTO_EX_DATA *r, int idx);
+
+=head1 DESCRIPTION
+
+Several OpenSSL structures can have application specific data attached to them.
+These functions are used internally by OpenSSL to manipulate application
+specific data attached to a specific structure.
+
+These functions should only be used by applications to manipulate
+B<CRYPTO_EX_DATA> structures passed to the B<new_func()>, B<free_func()> and
+B<dup_func()> callbacks: as passed to B<RSA_get_ex_new_index()> for example.
+
+B<CRYPTO_set_ex_data()> is used to set application specific data, the data is
+supplied in the B<arg> parameter and its precise meaning is up to the
+application.
+
+B<CRYPTO_get_ex_data()> is used to retrieve application specific data. The data
+is returned to the application, this will be the same value as supplied to
+a previous B<CRYPTO_set_ex_data()> call.
+
+=head1 RETURN VALUES
+
+B<CRYPTO_set_ex_data()> returns 1 on success or 0 on failure.
+
+B<CRYPTO_get_ex_data()> returns the application data or 0 on failure. 0 may also
+be valid application data but currently it can only fail if given an invalid B<idx>
+parameter.
+
+On failure an error code can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 SEE ALSO
+
+L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>,
+L<DSA_get_ex_new_index(3)|DSA_get_ex_new_index(3)>,
+L<DH_get_ex_new_index(3)|DH_get_ex_new_index(3)>
+
+=head1 HISTORY
+
+CRYPTO_set_ex_data() and CRYPTO_get_ex_data() have been available since SSLeay 0.9.0.
+
+=cut
diff --git a/openssl/doc/crypto/DH_generate_key.pod b/openssl/doc/crypto/DH_generate_key.pod
new file mode 100644
index 0000000..81f09fd
--- /dev/null
+++ b/openssl/doc/crypto/DH_generate_key.pod
@@ -0,0 +1,50 @@
+=pod
+
+=head1 NAME
+
+DH_generate_key, DH_compute_key - perform Diffie-Hellman key exchange
+
+=head1 SYNOPSIS
+
+ #include <openssl/dh.h>
+
+ int DH_generate_key(DH *dh);
+
+ int DH_compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh);
+
+=head1 DESCRIPTION
+
+DH_generate_key() performs the first step of a Diffie-Hellman key
+exchange by generating private and public DH values. By calling
+DH_compute_key(), these are combined with the other party's public
+value to compute the shared key.
+
+DH_generate_key() expects B<dh> to contain the shared parameters
+B<dh-E<gt>p> and B<dh-E<gt>g>. It generates a random private DH value
+unless B<dh-E<gt>priv_key> is already set, and computes the
+corresponding public value B<dh-E<gt>pub_key>, which can then be
+published.
+
+DH_compute_key() computes the shared secret from the private DH value
+in B<dh> and the other party's public value in B<pub_key> and stores
+it in B<key>. B<key> must point to B<DH_size(dh)> bytes of memory.
+
+=head1 RETURN VALUES
+
+DH_generate_key() returns 1 on success, 0 otherwise.
+
+DH_compute_key() returns the size of the shared secret on success, -1
+on error.
+
+The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 SEE ALSO
+
+L<dh(3)|dh(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>, L<DH_size(3)|DH_size(3)>
+
+=head1 HISTORY
+
+DH_generate_key() and DH_compute_key() are available in all versions
+of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/DH_generate_parameters.pod b/openssl/doc/crypto/DH_generate_parameters.pod
new file mode 100644
index 0000000..9081e9e
--- /dev/null
+++ b/openssl/doc/crypto/DH_generate_parameters.pod
@@ -0,0 +1,73 @@
+=pod
+
+=head1 NAME
+
+DH_generate_parameters, DH_check - generate and check Diffie-Hellman parameters
+
+=head1 SYNOPSIS
+
+ #include <openssl/dh.h>
+
+ DH *DH_generate_parameters(int prime_len, int generator,
+     void (*callback)(int, int, void *), void *cb_arg);
+
+ int DH_check(DH *dh, int *codes);
+
+=head1 DESCRIPTION
+
+DH_generate_parameters() generates Diffie-Hellman parameters that can
+be shared among a group of users, and returns them in a newly
+allocated B<DH> structure. The pseudo-random number generator must be
+seeded prior to calling DH_generate_parameters().
+
+B<prime_len> is the length in bits of the safe prime to be generated.
+B<generator> is a small number E<gt> 1, typically 2 or 5. 
+
+A callback function may be used to provide feedback about the progress
+of the key generation. If B<callback> is not B<NULL>, it will be
+called as described in L<BN_generate_prime(3)|BN_generate_prime(3)> while a random prime
+number is generated, and when a prime has been found, B<callback(3,
+0, cb_arg)> is called.
+
+DH_check() validates Diffie-Hellman parameters. It checks that B<p> is
+a safe prime, and that B<g> is a suitable generator. In the case of an
+error, the bit flags DH_CHECK_P_NOT_SAFE_PRIME or
+DH_NOT_SUITABLE_GENERATOR are set in B<*codes>.
+DH_UNABLE_TO_CHECK_GENERATOR is set if the generator cannot be
+checked, i.e. it does not equal 2 or 5.
+
+=head1 RETURN VALUES
+
+DH_generate_parameters() returns a pointer to the DH structure, or
+NULL if the parameter generation fails. The error codes can be
+obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+DH_check() returns 1 if the check could be performed, 0 otherwise.
+
+=head1 NOTES
+
+DH_generate_parameters() may run for several hours before finding a
+suitable prime.
+
+The parameters generated by DH_generate_parameters() are not to be
+used in signature schemes.
+
+=head1 BUGS
+
+If B<generator> is not 2 or 5, B<dh-E<gt>g>=B<generator> is not
+a usable generator.
+
+=head1 SEE ALSO
+
+L<dh(3)|dh(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>,
+L<DH_free(3)|DH_free(3)>
+
+=head1 HISTORY
+
+DH_check() is available in all versions of SSLeay and OpenSSL.
+The B<cb_arg> argument to DH_generate_parameters() was added in SSLeay 0.9.0.
+
+In versions before OpenSSL 0.9.5, DH_CHECK_P_NOT_STRONG_PRIME is used
+instead of DH_CHECK_P_NOT_SAFE_PRIME.
+
+=cut
diff --git a/openssl/doc/crypto/DH_get_ex_new_index.pod b/openssl/doc/crypto/DH_get_ex_new_index.pod
new file mode 100644
index 0000000..fa5eab2
--- /dev/null
+++ b/openssl/doc/crypto/DH_get_ex_new_index.pod
@@ -0,0 +1,36 @@
+=pod
+
+=head1 NAME
+
+DH_get_ex_new_index, DH_set_ex_data, DH_get_ex_data - add application specific data to DH structures
+
+=head1 SYNOPSIS
+
+ #include <openssl/dh.h>
+
+ int DH_get_ex_new_index(long argl, void *argp,
+		CRYPTO_EX_new *new_func,
+		CRYPTO_EX_dup *dup_func,
+		CRYPTO_EX_free *free_func);
+
+ int DH_set_ex_data(DH *d, int idx, void *arg);
+
+ char *DH_get_ex_data(DH *d, int idx);
+
+=head1 DESCRIPTION
+
+These functions handle application specific data in DH
+structures. Their usage is identical to that of
+RSA_get_ex_new_index(), RSA_set_ex_data() and RSA_get_ex_data()
+as described in L<RSA_get_ex_new_index(3)>.
+
+=head1 SEE ALSO
+
+L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>, L<dh(3)|dh(3)>
+
+=head1 HISTORY
+
+DH_get_ex_new_index(), DH_set_ex_data() and DH_get_ex_data() are
+available since OpenSSL 0.9.5.
+
+=cut
diff --git a/openssl/doc/crypto/DH_new.pod b/openssl/doc/crypto/DH_new.pod
new file mode 100644
index 0000000..60c9300
--- /dev/null
+++ b/openssl/doc/crypto/DH_new.pod
@@ -0,0 +1,40 @@
+=pod
+
+=head1 NAME
+
+DH_new, DH_free - allocate and free DH objects
+
+=head1 SYNOPSIS
+
+ #include <openssl/dh.h>
+
+ DH* DH_new(void);
+
+ void DH_free(DH *dh);
+
+=head1 DESCRIPTION
+
+DH_new() allocates and initializes a B<DH> structure.
+
+DH_free() frees the B<DH> structure and its components. The values are
+erased before the memory is returned to the system.
+
+=head1 RETURN VALUES
+
+If the allocation fails, DH_new() returns B<NULL> and sets an error
+code that can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. Otherwise it returns
+a pointer to the newly allocated structure.
+
+DH_free() returns no value.
+
+=head1 SEE ALSO
+
+L<dh(3)|dh(3)>, L<ERR_get_error(3)|ERR_get_error(3)>,
+L<DH_generate_parameters(3)|DH_generate_parameters(3)>,
+L<DH_generate_key(3)|DH_generate_key(3)>
+
+=head1 HISTORY
+
+DH_new() and DH_free() are available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/DH_set_method.pod b/openssl/doc/crypto/DH_set_method.pod
new file mode 100644
index 0000000..d5cdc3b
--- /dev/null
+++ b/openssl/doc/crypto/DH_set_method.pod
@@ -0,0 +1,129 @@
+=pod
+
+=head1 NAME
+
+DH_set_default_method, DH_get_default_method,
+DH_set_method, DH_new_method, DH_OpenSSL - select DH method
+
+=head1 SYNOPSIS
+
+ #include <openssl/dh.h>
+ #include <openssl/engine.h>
+
+ void DH_set_default_method(const DH_METHOD *meth);
+
+ const DH_METHOD *DH_get_default_method(void);
+
+ int DH_set_method(DH *dh, const DH_METHOD *meth);
+
+ DH *DH_new_method(ENGINE *engine);
+
+ const DH_METHOD *DH_OpenSSL(void);
+
+=head1 DESCRIPTION
+
+A B<DH_METHOD> specifies the functions that OpenSSL uses for Diffie-Hellman
+operations. By modifying the method, alternative implementations
+such as hardware accelerators may be used. IMPORTANT: See the NOTES section for
+important information about how these DH API functions are affected by the use
+of B<ENGINE> API calls.
+
+Initially, the default DH_METHOD is the OpenSSL internal implementation, as
+returned by DH_OpenSSL().
+
+DH_set_default_method() makes B<meth> the default method for all DH
+structures created later. B<NB>: This is true only whilst no ENGINE has been set
+as a default for DH, so this function is no longer recommended.
+
+DH_get_default_method() returns a pointer to the current default DH_METHOD.
+However, the meaningfulness of this result is dependent on whether the ENGINE
+API is being used, so this function is no longer recommended.
+
+DH_set_method() selects B<meth> to perform all operations using the key B<dh>.
+This will replace the DH_METHOD used by the DH key and if the previous method
+was supplied by an ENGINE, the handle to that ENGINE will be released during the
+change. It is possible to have DH keys that only work with certain DH_METHOD
+implementations (eg. from an ENGINE module that supports embedded
+hardware-protected keys), and in such cases attempting to change the DH_METHOD
+for the key can have unexpected results.
+
+DH_new_method() allocates and initializes a DH structure so that B<engine> will
+be used for the DH operations. If B<engine> is NULL, the default ENGINE for DH
+operations is used, and if no default ENGINE is set, the DH_METHOD controlled by
+DH_set_default_method() is used.
+
+=head1 THE DH_METHOD STRUCTURE
+
+ typedef struct dh_meth_st
+ {
+     /* name of the implementation */
+	const char *name;
+
+     /* generate private and public DH values for key agreement */
+        int (*generate_key)(DH *dh);
+
+     /* compute shared secret */
+        int (*compute_key)(unsigned char *key, BIGNUM *pub_key, DH *dh);
+
+     /* compute r = a ^ p mod m (May be NULL for some implementations) */
+        int (*bn_mod_exp)(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+                                const BIGNUM *m, BN_CTX *ctx,
+                                BN_MONT_CTX *m_ctx);
+
+     /* called at DH_new */
+        int (*init)(DH *dh);
+
+     /* called at DH_free */
+        int (*finish)(DH *dh);
+
+        int flags;
+
+        char *app_data; /* ?? */
+
+ } DH_METHOD;
+
+=head1 RETURN VALUES
+
+DH_OpenSSL() and DH_get_default_method() return pointers to the respective
+B<DH_METHOD>s.
+
+DH_set_default_method() returns no value.
+
+DH_set_method() returns non-zero if the provided B<meth> was successfully set as
+the method for B<dh> (including unloading the ENGINE handle if the previous
+method was supplied by an ENGINE).
+
+DH_new_method() returns NULL and sets an error code that can be obtained by
+L<ERR_get_error(3)|ERR_get_error(3)> if the allocation fails. Otherwise it
+returns a pointer to the newly allocated structure.
+
+=head1 NOTES
+
+As of version 0.9.7, DH_METHOD implementations are grouped together with other
+algorithmic APIs (eg. RSA_METHOD, EVP_CIPHER, etc) in B<ENGINE> modules. If a
+default ENGINE is specified for DH functionality using an ENGINE API function,
+that will override any DH defaults set using the DH API (ie.
+DH_set_default_method()). For this reason, the ENGINE API is the recommended way
+to control default implementations for use in DH and other cryptographic
+algorithms.
+
+=head1 SEE ALSO
+
+L<dh(3)|dh(3)>, L<DH_new(3)|DH_new(3)>
+
+=head1 HISTORY
+
+DH_set_default_method(), DH_get_default_method(), DH_set_method(),
+DH_new_method() and DH_OpenSSL() were added in OpenSSL 0.9.4.
+
+DH_set_default_openssl_method() and DH_get_default_openssl_method() replaced
+DH_set_default_method() and DH_get_default_method() respectively, and
+DH_set_method() and DH_new_method() were altered to use B<ENGINE>s rather than
+B<DH_METHOD>s during development of the engine version of OpenSSL 0.9.6. For
+0.9.7, the handling of defaults in the ENGINE API was restructured so that this
+change was reversed, and behaviour of the other functions resembled more closely
+the previous behaviour. The behaviour of defaults in the ENGINE API now
+transparently overrides the behaviour of defaults in the DH API without
+requiring changing these function prototypes.
+
+=cut
diff --git a/openssl/doc/crypto/DH_size.pod b/openssl/doc/crypto/DH_size.pod
new file mode 100644
index 0000000..97f26fd
--- /dev/null
+++ b/openssl/doc/crypto/DH_size.pod
@@ -0,0 +1,33 @@
+=pod
+
+=head1 NAME
+
+DH_size - get Diffie-Hellman prime size
+
+=head1 SYNOPSIS
+
+ #include <openssl/dh.h>
+
+ int DH_size(DH *dh);
+
+=head1 DESCRIPTION
+
+This function returns the Diffie-Hellman size in bytes. It can be used
+to determine how much memory must be allocated for the shared secret
+computed by DH_compute_key().
+
+B<dh-E<gt>p> must not be B<NULL>.
+
+=head1 RETURN VALUE
+
+The size in bytes.
+
+=head1 SEE ALSO
+
+L<dh(3)|dh(3)>, L<DH_generate_key(3)|DH_generate_key(3)>
+
+=head1 HISTORY
+
+DH_size() is available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/DSA_SIG_new.pod b/openssl/doc/crypto/DSA_SIG_new.pod
new file mode 100644
index 0000000..3ac6140
--- /dev/null
+++ b/openssl/doc/crypto/DSA_SIG_new.pod
@@ -0,0 +1,40 @@
+=pod
+
+=head1 NAME
+
+DSA_SIG_new, DSA_SIG_free - allocate and free DSA signature objects
+
+=head1 SYNOPSIS
+
+ #include <openssl/dsa.h>
+
+ DSA_SIG *DSA_SIG_new(void);
+
+ void	DSA_SIG_free(DSA_SIG *a);
+
+=head1 DESCRIPTION
+
+DSA_SIG_new() allocates and initializes a B<DSA_SIG> structure.
+
+DSA_SIG_free() frees the B<DSA_SIG> structure and its components. The
+values are erased before the memory is returned to the system.
+
+=head1 RETURN VALUES
+
+If the allocation fails, DSA_SIG_new() returns B<NULL> and sets an
+error code that can be obtained by
+L<ERR_get_error(3)|ERR_get_error(3)>. Otherwise it returns a pointer
+to the newly allocated structure.
+
+DSA_SIG_free() returns no value.
+
+=head1 SEE ALSO
+
+L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>,
+L<DSA_do_sign(3)|DSA_do_sign(3)>
+
+=head1 HISTORY
+
+DSA_SIG_new() and DSA_SIG_free() were added in OpenSSL 0.9.3.
+
+=cut
diff --git a/openssl/doc/crypto/DSA_do_sign.pod b/openssl/doc/crypto/DSA_do_sign.pod
new file mode 100644
index 0000000..5dfc733
--- /dev/null
+++ b/openssl/doc/crypto/DSA_do_sign.pod
@@ -0,0 +1,47 @@
+=pod
+
+=head1 NAME
+
+DSA_do_sign, DSA_do_verify - raw DSA signature operations
+
+=head1 SYNOPSIS
+
+ #include <openssl/dsa.h>
+
+ DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+
+ int DSA_do_verify(const unsigned char *dgst, int dgst_len,
+	     DSA_SIG *sig, DSA *dsa);
+
+=head1 DESCRIPTION
+
+DSA_do_sign() computes a digital signature on the B<len> byte message
+digest B<dgst> using the private key B<dsa> and returns it in a
+newly allocated B<DSA_SIG> structure.
+
+L<DSA_sign_setup(3)|DSA_sign_setup(3)> may be used to precompute part
+of the signing operation in case signature generation is
+time-critical.
+
+DSA_do_verify() verifies that the signature B<sig> matches a given
+message digest B<dgst> of size B<len>.  B<dsa> is the signer's public
+key.
+
+=head1 RETURN VALUES
+
+DSA_do_sign() returns the signature, NULL on error.  DSA_do_verify()
+returns 1 for a valid signature, 0 for an incorrect signature and -1
+on error. The error codes can be obtained by
+L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 SEE ALSO
+
+L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>,
+L<DSA_SIG_new(3)|DSA_SIG_new(3)>,
+L<DSA_sign(3)|DSA_sign(3)>
+
+=head1 HISTORY
+
+DSA_do_sign() and DSA_do_verify() were added in OpenSSL 0.9.3.
+
+=cut
diff --git a/openssl/doc/crypto/DSA_dup_DH.pod b/openssl/doc/crypto/DSA_dup_DH.pod
new file mode 100644
index 0000000..7f6f0d1
--- /dev/null
+++ b/openssl/doc/crypto/DSA_dup_DH.pod
@@ -0,0 +1,36 @@
+=pod
+
+=head1 NAME
+
+DSA_dup_DH - create a DH structure out of DSA structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/dsa.h>
+
+ DH * DSA_dup_DH(const DSA *r);
+
+=head1 DESCRIPTION
+
+DSA_dup_DH() duplicates DSA parameters/keys as DH parameters/keys. q
+is lost during that conversion, but the resulting DH parameters
+contain its length.
+
+=head1 RETURN VALUE
+
+DSA_dup_DH() returns the new B<DH> structure, and NULL on error. The
+error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 NOTE
+
+Be careful to avoid small subgroup attacks when using this.
+
+=head1 SEE ALSO
+
+L<dh(3)|dh(3)>, L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>
+
+=head1 HISTORY
+
+DSA_dup_DH() was added in OpenSSL 0.9.4.
+
+=cut
diff --git a/openssl/doc/crypto/DSA_generate_key.pod b/openssl/doc/crypto/DSA_generate_key.pod
new file mode 100644
index 0000000..af83ccf
--- /dev/null
+++ b/openssl/doc/crypto/DSA_generate_key.pod
@@ -0,0 +1,34 @@
+=pod
+
+=head1 NAME
+
+DSA_generate_key - generate DSA key pair
+
+=head1 SYNOPSIS
+
+ #include <openssl/dsa.h>
+
+ int DSA_generate_key(DSA *a);
+
+=head1 DESCRIPTION
+
+DSA_generate_key() expects B<a> to contain DSA parameters. It generates
+a new key pair and stores it in B<a-E<gt>pub_key> and B<a-E<gt>priv_key>.
+
+The PRNG must be seeded prior to calling DSA_generate_key().
+
+=head1 RETURN VALUE
+
+DSA_generate_key() returns 1 on success, 0 otherwise.
+The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 SEE ALSO
+
+L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>,
+L<DSA_generate_parameters(3)|DSA_generate_parameters(3)>
+
+=head1 HISTORY
+
+DSA_generate_key() is available since SSLeay 0.8.
+
+=cut
diff --git a/openssl/doc/crypto/DSA_generate_parameters.pod b/openssl/doc/crypto/DSA_generate_parameters.pod
new file mode 100644
index 0000000..be7c924
--- /dev/null
+++ b/openssl/doc/crypto/DSA_generate_parameters.pod
@@ -0,0 +1,105 @@
+=pod
+
+=head1 NAME
+
+DSA_generate_parameters - generate DSA parameters
+
+=head1 SYNOPSIS
+
+ #include <openssl/dsa.h>
+
+ DSA *DSA_generate_parameters(int bits, unsigned char *seed,
+                int seed_len, int *counter_ret, unsigned long *h_ret,
+		void (*callback)(int, int, void *), void *cb_arg);
+
+=head1 DESCRIPTION
+
+DSA_generate_parameters() generates primes p and q and a generator g
+for use in the DSA.
+
+B<bits> is the length of the prime to be generated; the DSS allows a
+maximum of 1024 bits.
+
+If B<seed> is B<NULL> or B<seed_len> E<lt> 20, the primes will be
+generated at random. Otherwise, the seed is used to generate
+them. If the given seed does not yield a prime q, a new random
+seed is chosen and placed at B<seed>.
+
+DSA_generate_parameters() places the iteration count in
+*B<counter_ret> and a counter used for finding a generator in
+*B<h_ret>, unless these are B<NULL>.
+
+A callback function may be used to provide feedback about the progress
+of the key generation. If B<callback> is not B<NULL>, it will be
+called as follows:
+
+=over 4
+
+=item *
+
+When a candidate for q is generated, B<callback(0, m++, cb_arg)> is called
+(m is 0 for the first candidate).
+
+=item *
+
+When a candidate for q has passed a test by trial division,
+B<callback(1, -1, cb_arg)> is called.
+While a candidate for q is tested by Miller-Rabin primality tests,
+B<callback(1, i, cb_arg)> is called in the outer loop
+(once for each witness that confirms that the candidate may be prime);
+i is the loop counter (starting at 0).
+
+=item *
+
+When a prime q has been found, B<callback(2, 0, cb_arg)> and
+B<callback(3, 0, cb_arg)> are called.
+
+=item *
+
+Before a candidate for p (other than the first) is generated and tested,
+B<callback(0, counter, cb_arg)> is called.
+
+=item *
+
+When a candidate for p has passed the test by trial division,
+B<callback(1, -1, cb_arg)> is called.
+While it is tested by the Miller-Rabin primality test,
+B<callback(1, i, cb_arg)> is called in the outer loop
+(once for each witness that confirms that the candidate may be prime).
+i is the loop counter (starting at 0).
+
+=item *
+
+When p has been found, B<callback(2, 1, cb_arg)> is called.
+
+=item *
+
+When the generator has been found, B<callback(3, 1, cb_arg)> is called.
+
+=back
+
+=head1 RETURN VALUE
+
+DSA_generate_parameters() returns a pointer to the DSA structure, or
+B<NULL> if the parameter generation fails. The error codes can be
+obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 BUGS
+
+Seed lengths E<gt> 20 are not supported.
+
+=head1 SEE ALSO
+
+L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>,
+L<DSA_free(3)|DSA_free(3)>
+
+=head1 HISTORY
+
+DSA_generate_parameters() appeared in SSLeay 0.8. The B<cb_arg>
+argument was added in SSLeay 0.9.0.
+In versions up to OpenSSL 0.9.4, B<callback(1, ...)> was called
+in the inner loop of the Miller-Rabin test whenever it reached the
+squaring step (the parameters to B<callback> did not reveal how many
+witnesses had been tested); since OpenSSL 0.9.5, B<callback(1, ...)>
+is called as in BN_is_prime(3), i.e. once for each witness.
+=cut
diff --git a/openssl/doc/crypto/DSA_get_ex_new_index.pod b/openssl/doc/crypto/DSA_get_ex_new_index.pod
new file mode 100644
index 0000000..fb6efc1
--- /dev/null
+++ b/openssl/doc/crypto/DSA_get_ex_new_index.pod
@@ -0,0 +1,36 @@
+=pod
+
+=head1 NAME
+
+DSA_get_ex_new_index, DSA_set_ex_data, DSA_get_ex_data - add application specific data to DSA structures
+
+=head1 SYNOPSIS
+
+ #include <openssl/dsa.h>
+
+ int DSA_get_ex_new_index(long argl, void *argp,
+		CRYPTO_EX_new *new_func,
+		CRYPTO_EX_dup *dup_func,
+		CRYPTO_EX_free *free_func);
+
+ int DSA_set_ex_data(DSA *d, int idx, void *arg);
+
+ char *DSA_get_ex_data(DSA *d, int idx);
+
+=head1 DESCRIPTION
+
+These functions handle application specific data in DSA
+structures. Their usage is identical to that of
+RSA_get_ex_new_index(), RSA_set_ex_data() and RSA_get_ex_data()
+as described in L<RSA_get_ex_new_index(3)>.
+
+=head1 SEE ALSO
+
+L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>, L<dsa(3)|dsa(3)>
+
+=head1 HISTORY
+
+DSA_get_ex_new_index(), DSA_set_ex_data() and DSA_get_ex_data() are
+available since OpenSSL 0.9.5.
+
+=cut
diff --git a/openssl/doc/crypto/DSA_new.pod b/openssl/doc/crypto/DSA_new.pod
new file mode 100644
index 0000000..48e9b82
--- /dev/null
+++ b/openssl/doc/crypto/DSA_new.pod
@@ -0,0 +1,42 @@
+=pod
+
+=head1 NAME
+
+DSA_new, DSA_free - allocate and free DSA objects
+
+=head1 SYNOPSIS
+
+ #include <openssl/dsa.h>
+
+ DSA* DSA_new(void);
+
+ void DSA_free(DSA *dsa);
+
+=head1 DESCRIPTION
+
+DSA_new() allocates and initializes a B<DSA> structure. It is equivalent to
+calling DSA_new_method(NULL).
+
+DSA_free() frees the B<DSA> structure and its components. The values are
+erased before the memory is returned to the system.
+
+=head1 RETURN VALUES
+
+If the allocation fails, DSA_new() returns B<NULL> and sets an error
+code that can be obtained by
+L<ERR_get_error(3)|ERR_get_error(3)>. Otherwise it returns a pointer
+to the newly allocated structure.
+
+DSA_free() returns no value.
+
+=head1 SEE ALSO
+
+L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>,
+L<DSA_generate_parameters(3)|DSA_generate_parameters(3)>,
+L<DSA_generate_key(3)|DSA_generate_key(3)>
+
+=head1 HISTORY
+
+DSA_new() and DSA_free() are available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/DSA_set_method.pod b/openssl/doc/crypto/DSA_set_method.pod
new file mode 100644
index 0000000..9c1434b
--- /dev/null
+++ b/openssl/doc/crypto/DSA_set_method.pod
@@ -0,0 +1,143 @@
+=pod
+
+=head1 NAME
+
+DSA_set_default_method, DSA_get_default_method,
+DSA_set_method, DSA_new_method, DSA_OpenSSL - select DSA method
+
+=head1 SYNOPSIS
+
+ #include <openssl/dsa.h>
+ #include <openssl/engine.h>
+
+ void DSA_set_default_method(const DSA_METHOD *meth);
+
+ const DSA_METHOD *DSA_get_default_method(void);
+
+ int DSA_set_method(DSA *dsa, const DSA_METHOD *meth);
+
+ DSA *DSA_new_method(ENGINE *engine);
+
+ DSA_METHOD *DSA_OpenSSL(void);
+
+=head1 DESCRIPTION
+
+A B<DSA_METHOD> specifies the functions that OpenSSL uses for DSA
+operations. By modifying the method, alternative implementations
+such as hardware accelerators may be used. IMPORTANT: See the NOTES section for
+important information about how these DSA API functions are affected by the use
+of B<ENGINE> API calls.
+
+Initially, the default DSA_METHOD is the OpenSSL internal implementation,
+as returned by DSA_OpenSSL().
+
+DSA_set_default_method() makes B<meth> the default method for all DSA
+structures created later. B<NB>: This is true only whilst no ENGINE has
+been set as a default for DSA, so this function is no longer recommended.
+
+DSA_get_default_method() returns a pointer to the current default
+DSA_METHOD. However, the meaningfulness of this result is dependent on
+whether the ENGINE API is being used, so this function is no longer 
+recommended.
+
+DSA_set_method() selects B<meth> to perform all operations using the key
+B<rsa>. This will replace the DSA_METHOD used by the DSA key and if the
+previous method was supplied by an ENGINE, the handle to that ENGINE will
+be released during the change. It is possible to have DSA keys that only
+work with certain DSA_METHOD implementations (eg. from an ENGINE module
+that supports embedded hardware-protected keys), and in such cases
+attempting to change the DSA_METHOD for the key can have unexpected
+results.
+
+DSA_new_method() allocates and initializes a DSA structure so that B<engine>
+will be used for the DSA operations. If B<engine> is NULL, the default engine
+for DSA operations is used, and if no default ENGINE is set, the DSA_METHOD
+controlled by DSA_set_default_method() is used.
+
+=head1 THE DSA_METHOD STRUCTURE
+
+struct
+ {
+     /* name of the implementation */
+        const char *name;
+
+     /* sign */
+	DSA_SIG *(*dsa_do_sign)(const unsigned char *dgst, int dlen,
+                                 DSA *dsa);
+
+     /* pre-compute k^-1 and r */
+	int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
+                                 BIGNUM **rp);
+
+     /* verify */
+	int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len,
+                                 DSA_SIG *sig, DSA *dsa);
+
+     /* compute rr = a1^p1 * a2^p2 mod m (May be NULL for some
+                                          implementations) */
+	int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
+                                 BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
+                                 BN_CTX *ctx, BN_MONT_CTX *in_mont);
+
+     /* compute r = a ^ p mod m (May be NULL for some implementations) */
+        int (*bn_mod_exp)(DSA *dsa, BIGNUM *r, BIGNUM *a,
+                                 const BIGNUM *p, const BIGNUM *m,
+                                 BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+
+     /* called at DSA_new */
+        int (*init)(DSA *DSA);
+
+     /* called at DSA_free */
+        int (*finish)(DSA *DSA);
+
+        int flags;
+
+        char *app_data; /* ?? */
+
+ } DSA_METHOD;
+
+=head1 RETURN VALUES
+
+DSA_OpenSSL() and DSA_get_default_method() return pointers to the respective
+B<DSA_METHOD>s.
+
+DSA_set_default_method() returns no value.
+
+DSA_set_method() returns non-zero if the provided B<meth> was successfully set as
+the method for B<dsa> (including unloading the ENGINE handle if the previous
+method was supplied by an ENGINE).
+
+DSA_new_method() returns NULL and sets an error code that can be
+obtained by L<ERR_get_error(3)|ERR_get_error(3)> if the allocation
+fails. Otherwise it returns a pointer to the newly allocated structure.
+
+=head1 NOTES
+
+As of version 0.9.7, DSA_METHOD implementations are grouped together with other
+algorithmic APIs (eg. RSA_METHOD, EVP_CIPHER, etc) in B<ENGINE> modules. If a
+default ENGINE is specified for DSA functionality using an ENGINE API function,
+that will override any DSA defaults set using the DSA API (ie.
+DSA_set_default_method()). For this reason, the ENGINE API is the recommended way
+to control default implementations for use in DSA and other cryptographic
+algorithms.
+
+=head1 SEE ALSO
+
+L<dsa(3)|dsa(3)>, L<DSA_new(3)|DSA_new(3)>
+
+=head1 HISTORY
+
+DSA_set_default_method(), DSA_get_default_method(), DSA_set_method(),
+DSA_new_method() and DSA_OpenSSL() were added in OpenSSL 0.9.4.
+
+DSA_set_default_openssl_method() and DSA_get_default_openssl_method() replaced
+DSA_set_default_method() and DSA_get_default_method() respectively, and
+DSA_set_method() and DSA_new_method() were altered to use B<ENGINE>s rather than
+B<DSA_METHOD>s during development of the engine version of OpenSSL 0.9.6. For
+0.9.7, the handling of defaults in the ENGINE API was restructured so that this
+change was reversed, and behaviour of the other functions resembled more closely
+the previous behaviour. The behaviour of defaults in the ENGINE API now
+transparently overrides the behaviour of defaults in the DSA API without
+requiring changing these function prototypes.
+
+=cut
diff --git a/openssl/doc/crypto/DSA_sign.pod b/openssl/doc/crypto/DSA_sign.pod
new file mode 100644
index 0000000..97389e8
--- /dev/null
+++ b/openssl/doc/crypto/DSA_sign.pod
@@ -0,0 +1,66 @@
+=pod
+
+=head1 NAME
+
+DSA_sign, DSA_sign_setup, DSA_verify - DSA signatures
+
+=head1 SYNOPSIS
+
+ #include <openssl/dsa.h>
+
+ int	DSA_sign(int type, const unsigned char *dgst, int len,
+		unsigned char *sigret, unsigned int *siglen, DSA *dsa);
+
+ int	DSA_sign_setup(DSA *dsa, BN_CTX *ctx, BIGNUM **kinvp,
+                BIGNUM **rp);
+
+ int	DSA_verify(int type, const unsigned char *dgst, int len,
+		unsigned char *sigbuf, int siglen, DSA *dsa);
+
+=head1 DESCRIPTION
+
+DSA_sign() computes a digital signature on the B<len> byte message
+digest B<dgst> using the private key B<dsa> and places its ASN.1 DER
+encoding at B<sigret>. The length of the signature is places in
+*B<siglen>. B<sigret> must point to DSA_size(B<dsa>) bytes of memory.
+
+DSA_sign_setup() may be used to precompute part of the signing
+operation in case signature generation is time-critical. It expects
+B<dsa> to contain DSA parameters. It places the precomputed values
+in newly allocated B<BIGNUM>s at *B<kinvp> and *B<rp>, after freeing
+the old ones unless *B<kinvp> and *B<rp> are NULL. These values may
+be passed to DSA_sign() in B<dsa-E<gt>kinv> and B<dsa-E<gt>r>.
+B<ctx> is a pre-allocated B<BN_CTX> or NULL.
+
+DSA_verify() verifies that the signature B<sigbuf> of size B<siglen>
+matches a given message digest B<dgst> of size B<len>.
+B<dsa> is the signer's public key.
+
+The B<type> parameter is ignored.
+
+The PRNG must be seeded before DSA_sign() (or DSA_sign_setup())
+is called.
+
+=head1 RETURN VALUES
+
+DSA_sign() and DSA_sign_setup() return 1 on success, 0 on error.
+DSA_verify() returns 1 for a valid signature, 0 for an incorrect
+signature and -1 on error. The error codes can be obtained by
+L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 CONFORMING TO
+
+US Federal Information Processing Standard FIPS 186 (Digital Signature
+Standard, DSS), ANSI X9.30
+
+=head1 SEE ALSO
+
+L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>,
+L<DSA_do_sign(3)|DSA_do_sign(3)>
+
+=head1 HISTORY
+
+DSA_sign() and DSA_verify() are available in all versions of SSLeay.
+DSA_sign_setup() was added in SSLeay 0.8.
+
+=cut
diff --git a/openssl/doc/crypto/DSA_size.pod b/openssl/doc/crypto/DSA_size.pod
new file mode 100644
index 0000000..ba4f650
--- /dev/null
+++ b/openssl/doc/crypto/DSA_size.pod
@@ -0,0 +1,33 @@
+=pod
+
+=head1 NAME
+
+DSA_size - get DSA signature size
+
+=head1 SYNOPSIS
+
+ #include <openssl/dsa.h>
+
+ int DSA_size(const DSA *dsa);
+
+=head1 DESCRIPTION
+
+This function returns the size of an ASN.1 encoded DSA signature in
+bytes. It can be used to determine how much memory must be allocated
+for a DSA signature.
+
+B<dsa-E<gt>q> must not be B<NULL>.
+
+=head1 RETURN VALUE
+
+The size in bytes.
+
+=head1 SEE ALSO
+
+L<dsa(3)|dsa(3)>, L<DSA_sign(3)|DSA_sign(3)>
+
+=head1 HISTORY
+
+DSA_size() is available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/ERR_GET_LIB.pod b/openssl/doc/crypto/ERR_GET_LIB.pod
new file mode 100644
index 0000000..2a129da
--- /dev/null
+++ b/openssl/doc/crypto/ERR_GET_LIB.pod
@@ -0,0 +1,51 @@
+=pod
+
+=head1 NAME
+
+ERR_GET_LIB, ERR_GET_FUNC, ERR_GET_REASON - get library, function and
+reason code
+
+=head1 SYNOPSIS
+
+ #include <openssl/err.h>
+
+ int ERR_GET_LIB(unsigned long e);
+
+ int ERR_GET_FUNC(unsigned long e);
+
+ int ERR_GET_REASON(unsigned long e);
+
+=head1 DESCRIPTION
+
+The error code returned by ERR_get_error() consists of a library
+number, function code and reason code. ERR_GET_LIB(), ERR_GET_FUNC()
+and ERR_GET_REASON() can be used to extract these.
+
+The library number and function code describe where the error
+occurred, the reason code is the information about what went wrong.
+
+Each sub-library of OpenSSL has a unique library number; function and
+reason codes are unique within each sub-library.  Note that different
+libraries may use the same value to signal different functions and
+reasons.
+
+B<ERR_R_...> reason codes such as B<ERR_R_MALLOC_FAILURE> are globally
+unique. However, when checking for sub-library specific reason codes,
+be sure to also compare the library number.
+
+ERR_GET_LIB(), ERR_GET_FUNC() and ERR_GET_REASON() are macros.
+
+=head1 RETURN VALUES
+
+The library number, function code and reason code respectively.
+
+=head1 SEE ALSO
+
+L<err(3)|err(3)>, L<ERR_get_error(3)|ERR_get_error(3)>
+
+=head1 HISTORY
+
+ERR_GET_LIB(), ERR_GET_FUNC() and ERR_GET_REASON() are available in
+all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/ERR_clear_error.pod b/openssl/doc/crypto/ERR_clear_error.pod
new file mode 100644
index 0000000..566e1f4
--- /dev/null
+++ b/openssl/doc/crypto/ERR_clear_error.pod
@@ -0,0 +1,29 @@
+=pod
+
+=head1 NAME
+
+ERR_clear_error - clear the error queue
+
+=head1 SYNOPSIS
+
+ #include <openssl/err.h>
+
+ void ERR_clear_error(void);
+
+=head1 DESCRIPTION
+
+ERR_clear_error() empties the current thread's error queue.
+
+=head1 RETURN VALUES
+
+ERR_clear_error() has no return value.
+
+=head1 SEE ALSO
+
+L<err(3)|err(3)>, L<ERR_get_error(3)|ERR_get_error(3)>
+
+=head1 HISTORY
+
+ERR_clear_error() is available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/ERR_error_string.pod b/openssl/doc/crypto/ERR_error_string.pod
new file mode 100644
index 0000000..cdfa7fe
--- /dev/null
+++ b/openssl/doc/crypto/ERR_error_string.pod
@@ -0,0 +1,73 @@
+=pod
+
+=head1 NAME
+
+ERR_error_string, ERR_error_string_n, ERR_lib_error_string,
+ERR_func_error_string, ERR_reason_error_string - obtain human-readable
+error message
+
+=head1 SYNOPSIS
+
+ #include <openssl/err.h>
+
+ char *ERR_error_string(unsigned long e, char *buf);
+ void ERR_error_string_n(unsigned long e, char *buf, size_t len);
+
+ const char *ERR_lib_error_string(unsigned long e);
+ const char *ERR_func_error_string(unsigned long e);
+ const char *ERR_reason_error_string(unsigned long e);
+
+=head1 DESCRIPTION
+
+ERR_error_string() generates a human-readable string representing the
+error code I<e>, and places it at I<buf>. I<buf> must be at least 120
+bytes long. If I<buf> is B<NULL>, the error string is placed in a
+static buffer.
+ERR_error_string_n() is a variant of ERR_error_string() that writes
+at most I<len> characters (including the terminating 0)
+and truncates the string if necessary.
+For ERR_error_string_n(), I<buf> may not be B<NULL>.
+
+The string will have the following format:
+
+ error:[error code]:[library name]:[function name]:[reason string]
+
+I<error code> is an 8 digit hexadecimal number, I<library name>,
+I<function name> and I<reason string> are ASCII text.
+
+ERR_lib_error_string(), ERR_func_error_string() and
+ERR_reason_error_string() return the library name, function
+name and reason string respectively.
+
+The OpenSSL error strings should be loaded by calling
+L<ERR_load_crypto_strings(3)|ERR_load_crypto_strings(3)> or, for SSL
+applications, L<SSL_load_error_strings(3)|SSL_load_error_strings(3)>
+first.
+If there is no text string registered for the given error code,
+the error string will contain the numeric code.
+
+L<ERR_print_errors(3)|ERR_print_errors(3)> can be used to print
+all error codes currently in the queue.
+
+=head1 RETURN VALUES
+
+ERR_error_string() returns a pointer to a static buffer containing the
+string if I<buf> B<== NULL>, I<buf> otherwise.
+
+ERR_lib_error_string(), ERR_func_error_string() and
+ERR_reason_error_string() return the strings, and B<NULL> if
+none is registered for the error code.
+
+=head1 SEE ALSO
+
+L<err(3)|err(3)>, L<ERR_get_error(3)|ERR_get_error(3)>,
+L<ERR_load_crypto_strings(3)|ERR_load_crypto_strings(3)>,
+L<SSL_load_error_strings(3)|SSL_load_error_strings(3)>
+L<ERR_print_errors(3)|ERR_print_errors(3)>
+
+=head1 HISTORY
+
+ERR_error_string() is available in all versions of SSLeay and OpenSSL.
+ERR_error_string_n() was added in OpenSSL 0.9.6.
+
+=cut
diff --git a/openssl/doc/crypto/ERR_get_error.pod b/openssl/doc/crypto/ERR_get_error.pod
new file mode 100644
index 0000000..3444304
--- /dev/null
+++ b/openssl/doc/crypto/ERR_get_error.pod
@@ -0,0 +1,76 @@
+=pod
+
+=head1 NAME
+
+ERR_get_error, ERR_peek_error, ERR_peek_last_error,
+ERR_get_error_line, ERR_peek_error_line, ERR_peek_last_error_line,
+ERR_get_error_line_data, ERR_peek_error_line_data,
+ERR_peek_last_error_line_data - obtain error code and data
+
+=head1 SYNOPSIS
+
+ #include <openssl/err.h>
+
+ unsigned long ERR_get_error(void);
+ unsigned long ERR_peek_error(void);
+ unsigned long ERR_peek_last_error(void);
+
+ unsigned long ERR_get_error_line(const char **file, int *line);
+ unsigned long ERR_peek_error_line(const char **file, int *line);
+ unsigned long ERR_peek_last_error_line(const char **file, int *line);
+
+ unsigned long ERR_get_error_line_data(const char **file, int *line,
+         const char **data, int *flags);
+ unsigned long ERR_peek_error_line_data(const char **file, int *line,
+         const char **data, int *flags);
+ unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
+         const char **data, int *flags);
+
+=head1 DESCRIPTION
+
+ERR_get_error() returns the earliest error code from the thread's error
+queue and removes the entry. This function can be called repeatedly
+until there are no more error codes to return.
+
+ERR_peek_error() returns the earliest error code from the thread's
+error queue without modifying it.
+
+ERR_peek_last_error() returns the latest error code from the thread's
+error queue without modifying it.
+
+See L<ERR_GET_LIB(3)|ERR_GET_LIB(3)> for obtaining information about
+location and reason of the error, and
+L<ERR_error_string(3)|ERR_error_string(3)> for human-readable error
+messages.
+
+ERR_get_error_line(), ERR_peek_error_line() and
+ERR_peek_last_error_line() are the same as the above, but they
+additionally store the file name and line number where
+the error occurred in *B<file> and *B<line>, unless these are B<NULL>.
+
+ERR_get_error_line_data(), ERR_peek_error_line_data() and
+ERR_get_last_error_line_data() store additional data and flags
+associated with the error code in *B<data>
+and *B<flags>, unless these are B<NULL>. *B<data> contains a string
+if *B<flags>&B<ERR_TXT_STRING>. If it has been allocated by OPENSSL_malloc(),
+*B<flags>&B<ERR_TXT_MALLOCED> is true.
+
+=head1 RETURN VALUES
+
+The error code, or 0 if there is no error in the queue.
+
+=head1 SEE ALSO
+
+L<err(3)|err(3)>, L<ERR_error_string(3)|ERR_error_string(3)>,
+L<ERR_GET_LIB(3)|ERR_GET_LIB(3)>
+
+=head1 HISTORY
+
+ERR_get_error(), ERR_peek_error(), ERR_get_error_line() and
+ERR_peek_error_line() are available in all versions of SSLeay and
+OpenSSL. ERR_get_error_line_data() and ERR_peek_error_line_data()
+were added in SSLeay 0.9.0.
+ERR_peek_last_error(), ERR_peek_last_error_line() and
+ERR_peek_last_error_line_data() were added in OpenSSL 0.9.7.
+
+=cut
diff --git a/openssl/doc/crypto/ERR_load_crypto_strings.pod b/openssl/doc/crypto/ERR_load_crypto_strings.pod
new file mode 100644
index 0000000..9bdec75
--- /dev/null
+++ b/openssl/doc/crypto/ERR_load_crypto_strings.pod
@@ -0,0 +1,46 @@
+=pod
+
+=head1 NAME
+
+ERR_load_crypto_strings, SSL_load_error_strings, ERR_free_strings -
+load and free error strings
+
+=head1 SYNOPSIS
+
+ #include <openssl/err.h>
+
+ void ERR_load_crypto_strings(void);
+ void ERR_free_strings(void);
+
+ #include <openssl/ssl.h>
+
+ void SSL_load_error_strings(void);
+
+=head1 DESCRIPTION
+
+ERR_load_crypto_strings() registers the error strings for all
+B<libcrypto> functions. SSL_load_error_strings() does the same,
+but also registers the B<libssl> error strings.
+
+One of these functions should be called before generating
+textual error messages. However, this is not required when memory
+usage is an issue.
+
+ERR_free_strings() frees all previously loaded error strings.
+
+=head1 RETURN VALUES
+
+ERR_load_crypto_strings(), SSL_load_error_strings() and
+ERR_free_strings() return no values.
+
+=head1 SEE ALSO
+
+L<err(3)|err(3)>, L<ERR_error_string(3)|ERR_error_string(3)>
+
+=head1 HISTORY
+
+ERR_load_error_strings(), SSL_load_error_strings() and
+ERR_free_strings() are available in all versions of SSLeay and
+OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/ERR_load_strings.pod b/openssl/doc/crypto/ERR_load_strings.pod
new file mode 100644
index 0000000..5acdd0e
--- /dev/null
+++ b/openssl/doc/crypto/ERR_load_strings.pod
@@ -0,0 +1,54 @@
+=pod
+
+=head1 NAME
+
+ERR_load_strings, ERR_PACK, ERR_get_next_error_library - load
+arbitrary error strings
+
+=head1 SYNOPSIS
+
+ #include <openssl/err.h>
+
+ void ERR_load_strings(int lib, ERR_STRING_DATA str[]);
+
+ int ERR_get_next_error_library(void);
+
+ unsigned long ERR_PACK(int lib, int func, int reason);
+
+=head1 DESCRIPTION
+
+ERR_load_strings() registers error strings for library number B<lib>.
+
+B<str> is an array of error string data:
+
+ typedef struct ERR_string_data_st
+ {
+        unsigned long error;
+        char *string;
+ } ERR_STRING_DATA;
+
+The error code is generated from the library number and a function and
+reason code: B<error> = ERR_PACK(B<lib>, B<func>, B<reason>).
+ERR_PACK() is a macro.
+
+The last entry in the array is {0,0}.
+
+ERR_get_next_error_library() can be used to assign library numbers
+to user libraries at runtime.
+
+=head1 RETURN VALUE
+
+ERR_load_strings() returns no value. ERR_PACK() return the error code.
+ERR_get_next_error_library() returns a new library number.
+
+=head1 SEE ALSO
+
+L<err(3)|err(3)>, L<ERR_load_strings(3)|ERR_load_strings(3)>
+
+=head1 HISTORY
+
+ERR_load_error_strings() and ERR_PACK() are available in all versions
+of SSLeay and OpenSSL. ERR_get_next_error_library() was added in
+SSLeay 0.9.0.
+
+=cut
diff --git a/openssl/doc/crypto/ERR_print_errors.pod b/openssl/doc/crypto/ERR_print_errors.pod
new file mode 100644
index 0000000..b100a5f
--- /dev/null
+++ b/openssl/doc/crypto/ERR_print_errors.pod
@@ -0,0 +1,51 @@
+=pod
+
+=head1 NAME
+
+ERR_print_errors, ERR_print_errors_fp - print error messages
+
+=head1 SYNOPSIS
+
+ #include <openssl/err.h>
+
+ void ERR_print_errors(BIO *bp);
+ void ERR_print_errors_fp(FILE *fp);
+
+=head1 DESCRIPTION
+
+ERR_print_errors() is a convenience function that prints the error
+strings for all errors that OpenSSL has recorded to B<bp>, thus
+emptying the error queue.
+
+ERR_print_errors_fp() is the same, except that the output goes to a
+B<FILE>.
+
+
+The error strings will have the following format:
+
+ [pid]:error:[error code]:[library name]:[function name]:[reason string]:[file name]:[line]:[optional text message]
+
+I<error code> is an 8 digit hexadecimal number. I<library name>,
+I<function name> and I<reason string> are ASCII text, as is I<optional
+text message> if one was set for the respective error code.
+
+If there is no text string registered for the given error code,
+the error string will contain the numeric code.
+
+=head1 RETURN VALUES
+
+ERR_print_errors() and ERR_print_errors_fp() return no values.
+
+=head1 SEE ALSO
+
+L<err(3)|err(3)>, L<ERR_error_string(3)|ERR_error_string(3)>,
+L<ERR_get_error(3)|ERR_get_error(3)>,
+L<ERR_load_crypto_strings(3)|ERR_load_crypto_strings(3)>,
+L<SSL_load_error_strings(3)|SSL_load_error_strings(3)>
+
+=head1 HISTORY
+
+ERR_print_errors() and ERR_print_errors_fp()
+are available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/ERR_put_error.pod b/openssl/doc/crypto/ERR_put_error.pod
new file mode 100644
index 0000000..acd241f
--- /dev/null
+++ b/openssl/doc/crypto/ERR_put_error.pod
@@ -0,0 +1,44 @@
+=pod
+
+=head1 NAME
+
+ERR_put_error, ERR_add_error_data - record an error
+
+=head1 SYNOPSIS
+
+ #include <openssl/err.h>
+
+ void ERR_put_error(int lib, int func, int reason, const char *file,
+         int line);
+
+ void ERR_add_error_data(int num, ...);
+
+=head1 DESCRIPTION
+
+ERR_put_error() adds an error code to the thread's error queue. It
+signals that the error of reason code B<reason> occurred in function
+B<func> of library B<lib>, in line number B<line> of B<file>.
+This function is usually called by a macro.
+
+ERR_add_error_data() associates the concatenation of its B<num> string
+arguments with the error code added last.
+
+L<ERR_load_strings(3)|ERR_load_strings(3)> can be used to register
+error strings so that the application can a generate human-readable
+error messages for the error code.
+
+=head1 RETURN VALUES
+
+ERR_put_error() and ERR_add_error_data() return
+no values.
+
+=head1 SEE ALSO
+
+L<err(3)|err(3)>, L<ERR_load_strings(3)|ERR_load_strings(3)>
+
+=head1 HISTORY
+
+ERR_put_error() is available in all versions of SSLeay and OpenSSL.
+ERR_add_error_data() was added in SSLeay 0.9.0.
+
+=cut
diff --git a/openssl/doc/crypto/ERR_remove_state.pod b/openssl/doc/crypto/ERR_remove_state.pod
new file mode 100644
index 0000000..72925fb
--- /dev/null
+++ b/openssl/doc/crypto/ERR_remove_state.pod
@@ -0,0 +1,34 @@
+=pod
+
+=head1 NAME
+
+ERR_remove_state - free a thread's error queue
+
+=head1 SYNOPSIS
+
+ #include <openssl/err.h>
+
+ void ERR_remove_state(unsigned long pid);
+
+=head1 DESCRIPTION
+
+ERR_remove_state() frees the error queue associated with thread B<pid>.
+If B<pid> == 0, the current thread will have its error queue removed.
+
+Since error queue data structures are allocated automatically for new
+threads, they must be freed when threads are terminated in order to
+avoid memory leaks.
+
+=head1 RETURN VALUE
+
+ERR_remove_state() returns no value.
+
+=head1 SEE ALSO
+
+L<err(3)|err(3)>
+
+=head1 HISTORY
+
+ERR_remove_state() is available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/ERR_set_mark.pod b/openssl/doc/crypto/ERR_set_mark.pod
new file mode 100644
index 0000000..d3ca4f2
--- /dev/null
+++ b/openssl/doc/crypto/ERR_set_mark.pod
@@ -0,0 +1,38 @@
+=pod
+
+=head1 NAME
+
+ERR_set_mark, ERR_pop_to_mark - set marks and pop errors until mark
+
+=head1 SYNOPSIS
+
+ #include <openssl/err.h>
+
+ int ERR_set_mark(void);
+
+ int ERR_pop_to_mark(void);
+
+=head1 DESCRIPTION
+
+ERR_set_mark() sets a mark on the current topmost error record if there
+is one.
+
+ERR_pop_to_mark() will pop the top of the error stack until a mark is found.
+The mark is then removed.  If there is no mark, the whole stack is removed.
+
+=head1 RETURN VALUES
+
+ERR_set_mark() returns 0 if the error stack is empty, otherwise 1.
+
+ERR_pop_to_mark() returns 0 if there was no mark in the error stack, which
+implies that the stack became empty, otherwise 1.
+
+=head1 SEE ALSO
+
+L<err(3)|err(3)>
+
+=head1 HISTORY
+
+ERR_set_mark() and ERR_pop_to_mark() were added in OpenSSL 0.9.8.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_BytesToKey.pod b/openssl/doc/crypto/EVP_BytesToKey.pod
new file mode 100644
index 0000000..d375c46
--- /dev/null
+++ b/openssl/doc/crypto/EVP_BytesToKey.pod
@@ -0,0 +1,67 @@
+=pod
+
+=head1 NAME
+
+EVP_BytesToKey - password based encryption routine
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_BytesToKey(const EVP_CIPHER *type,const EVP_MD *md,
+                       const unsigned char *salt,
+                       const unsigned char *data, int datal, int count,
+                       unsigned char *key,unsigned char *iv);
+
+=head1 DESCRIPTION
+
+EVP_BytesToKey() derives a key and IV from various parameters. B<type> is
+the cipher to derive the key and IV for. B<md> is the message digest to use.
+The B<salt> paramter is used as a salt in the derivation: it should point to
+an 8 byte buffer or NULL if no salt is used. B<data> is a buffer containing
+B<datal> bytes which is used to derive the keying data. B<count> is the
+iteration count to use. The derived key and IV will be written to B<key>
+and B<iv> respectively.
+
+=head1 NOTES
+
+A typical application of this function is to derive keying material for an
+encryption algorithm from a password in the B<data> parameter.
+
+Increasing the B<count> parameter slows down the algorithm which makes it
+harder for an attacker to peform a brute force attack using a large number
+of candidate passwords.
+
+If the total key and IV length is less than the digest length and
+B<MD5> is used then the derivation algorithm is compatible with PKCS#5 v1.5
+otherwise a non standard extension is used to derive the extra data.
+
+Newer applications should use more standard algorithms such as PKCS#5
+v2.0 for key derivation.
+
+=head1 KEY DERIVATION ALGORITHM
+
+The key and IV is derived by concatenating D_1, D_2, etc until
+enough data is available for the key and IV. D_i is defined as:
+
+	D_i = HASH^count(D_(i-1) || data || salt)
+
+where || denotes concatentaion, D_0 is empty, HASH is the digest
+algorithm in use, HASH^1(data) is simply HASH(data), HASH^2(data)
+is HASH(HASH(data)) and so on.
+
+The initial bytes are used for the key and the subsequent bytes for
+the IV.
+
+=head1 RETURN VALUES
+
+EVP_BytesToKey() returns the size of the derived key in bytes.
+
+=head1 SEE ALSO
+
+L<evp(3)|evp(3)>, L<rand(3)|rand(3)>,
+L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>
+
+=head1 HISTORY
+
+=cut
diff --git a/openssl/doc/crypto/EVP_DigestInit.pod b/openssl/doc/crypto/EVP_DigestInit.pod
new file mode 100644
index 0000000..5b477ac
--- /dev/null
+++ b/openssl/doc/crypto/EVP_DigestInit.pod
@@ -0,0 +1,259 @@
+=pod
+
+=head1 NAME
+
+EVP_MD_CTX_init, EVP_MD_CTX_create, EVP_DigestInit_ex, EVP_DigestUpdate,
+EVP_DigestFinal_ex, EVP_MD_CTX_cleanup, EVP_MD_CTX_destroy, EVP_MAX_MD_SIZE,
+EVP_MD_CTX_copy_ex, EVP_MD_CTX_copy, EVP_MD_type, EVP_MD_pkey_type, EVP_MD_size,
+EVP_MD_block_size, EVP_MD_CTX_md, EVP_MD_CTX_size, EVP_MD_CTX_block_size, EVP_MD_CTX_type,
+EVP_md_null, EVP_md2, EVP_md5, EVP_sha, EVP_sha1, EVP_dss, EVP_dss1, EVP_mdc2,
+EVP_ripemd160, EVP_get_digestbyname, EVP_get_digestbynid, EVP_get_digestbyobj -
+EVP digest routines
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ void EVP_MD_CTX_init(EVP_MD_CTX *ctx);
+ EVP_MD_CTX *EVP_MD_CTX_create(void);
+
+ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
+ int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt);
+ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md,
+        unsigned int *s);
+
+ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
+ void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
+
+ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in);  
+
+ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
+ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md,
+        unsigned int *s);
+
+ int EVP_MD_CTX_copy(EVP_MD_CTX *out,EVP_MD_CTX *in);  
+
+ #define EVP_MAX_MD_SIZE (16+20) /* The SSLv3 md5+sha1 type */
+
+
+ #define EVP_MD_type(e)			((e)->type)
+ #define EVP_MD_pkey_type(e)		((e)->pkey_type)
+ #define EVP_MD_size(e)			((e)->md_size)
+ #define EVP_MD_block_size(e)		((e)->block_size)
+
+ #define EVP_MD_CTX_md(e)		(e)->digest)
+ #define EVP_MD_CTX_size(e)		EVP_MD_size((e)->digest)
+ #define EVP_MD_CTX_block_size(e)	EVP_MD_block_size((e)->digest)
+ #define EVP_MD_CTX_type(e)		EVP_MD_type((e)->digest)
+
+ const EVP_MD *EVP_md_null(void);
+ const EVP_MD *EVP_md2(void);
+ const EVP_MD *EVP_md5(void);
+ const EVP_MD *EVP_sha(void);
+ const EVP_MD *EVP_sha1(void);
+ const EVP_MD *EVP_dss(void);
+ const EVP_MD *EVP_dss1(void);
+ const EVP_MD *EVP_mdc2(void);
+ const EVP_MD *EVP_ripemd160(void);
+
+ const EVP_MD *EVP_get_digestbyname(const char *name);
+ #define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a))
+ #define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a))
+
+=head1 DESCRIPTION
+
+The EVP digest routines are a high level interface to message digests.
+
+EVP_MD_CTX_init() initializes digest context B<ctx>.
+
+EVP_MD_CTX_create() allocates, initializes and returns a digest context.
+
+EVP_DigestInit_ex() sets up digest context B<ctx> to use a digest
+B<type> from ENGINE B<impl>. B<ctx> must be initialized before calling this
+function. B<type> will typically be supplied by a functionsuch as EVP_sha1().
+If B<impl> is NULL then the default implementation of digest B<type> is used.
+
+EVP_DigestUpdate() hashes B<cnt> bytes of data at B<d> into the
+digest context B<ctx>. This function can be called several times on the
+same B<ctx> to hash additional data.
+
+EVP_DigestFinal_ex() retrieves the digest value from B<ctx> and places
+it in B<md>. If the B<s> parameter is not NULL then the number of
+bytes of data written (i.e. the length of the digest) will be written
+to the integer at B<s>, at most B<EVP_MAX_MD_SIZE> bytes will be written.
+After calling EVP_DigestFinal_ex() no additional calls to EVP_DigestUpdate()
+can be made, but EVP_DigestInit_ex() can be called to initialize a new
+digest operation.
+
+EVP_MD_CTX_cleanup() cleans up digest context B<ctx>, it should be called
+after a digest context is no longer needed.
+
+EVP_MD_CTX_destroy() cleans up digest context B<ctx> and frees up the
+space allocated to it, it should be called only on a context created
+using EVP_MD_CTX_create().
+
+EVP_MD_CTX_copy_ex() can be used to copy the message digest state from
+B<in> to B<out>. This is useful if large amounts of data are to be
+hashed which only differ in the last few bytes. B<out> must be initialized
+before calling this function.
+
+EVP_DigestInit() behaves in the same way as EVP_DigestInit_ex() except
+the passed context B<ctx> does not have to be initialized, and it always
+uses the default digest implementation.
+
+EVP_DigestFinal() is similar to EVP_DigestFinal_ex() except the digest
+context B<ctx> is automatically cleaned up.
+
+EVP_MD_CTX_copy() is similar to EVP_MD_CTX_copy_ex() except the destination
+B<out> does not have to be initialized.
+
+EVP_MD_size() and EVP_MD_CTX_size() return the size of the message digest
+when passed an B<EVP_MD> or an B<EVP_MD_CTX> structure, i.e. the size of the
+hash.
+
+EVP_MD_block_size() and EVP_MD_CTX_block_size() return the block size of the
+message digest when passed an B<EVP_MD> or an B<EVP_MD_CTX> structure.
+
+EVP_MD_type() and EVP_MD_CTX_type() return the NID of the OBJECT IDENTIFIER
+representing the given message digest when passed an B<EVP_MD> structure.
+For example EVP_MD_type(EVP_sha1()) returns B<NID_sha1>. This function is
+normally used when setting ASN1 OIDs.
+
+EVP_MD_CTX_md() returns the B<EVP_MD> structure corresponding to the passed
+B<EVP_MD_CTX>.
+
+EVP_MD_pkey_type() returns the NID of the public key signing algorithm associated
+with this digest. For example EVP_sha1() is associated with RSA so this will
+return B<NID_sha1WithRSAEncryption>. This "link" between digests and signature
+algorithms may not be retained in future versions of OpenSSL.
+
+EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), EVP_mdc2() and EVP_ripemd160()
+return B<EVP_MD> structures for the MD2, MD5, SHA, SHA1, MDC2 and RIPEMD160 digest
+algorithms respectively. The associated signature algorithm is RSA in each case.
+
+EVP_dss() and EVP_dss1() return B<EVP_MD> structures for SHA and SHA1 digest
+algorithms but using DSS (DSA) for the signature algorithm. Note: there is 
+no need to use these pseudo-digests in OpenSSL 1.0.0 and later, they are
+however retained for compatibility.
+
+EVP_md_null() is a "null" message digest that does nothing: i.e. the hash it
+returns is of zero length.
+
+EVP_get_digestbyname(), EVP_get_digestbynid() and EVP_get_digestbyobj()
+return an B<EVP_MD> structure when passed a digest name, a digest NID or
+an ASN1_OBJECT structure respectively. The digest table must be initialized
+using, for example, OpenSSL_add_all_digests() for these functions to work.
+
+=head1 RETURN VALUES
+
+EVP_DigestInit_ex(), EVP_DigestUpdate() and EVP_DigestFinal_ex() return 1 for
+success and 0 for failure.
+
+EVP_MD_CTX_copy_ex() returns 1 if successful or 0 for failure.
+
+EVP_MD_type(), EVP_MD_pkey_type() and EVP_MD_type() return the NID of the
+corresponding OBJECT IDENTIFIER or NID_undef if none exists.
+
+EVP_MD_size(), EVP_MD_block_size(), EVP_MD_CTX_size(e), EVP_MD_size(),
+EVP_MD_CTX_block_size()	and EVP_MD_block_size() return the digest or block
+size in bytes.
+
+EVP_md_null(), EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), EVP_dss(),
+EVP_dss1(), EVP_mdc2() and EVP_ripemd160() return pointers to the
+corresponding EVP_MD structures.
+
+EVP_get_digestbyname(), EVP_get_digestbynid() and EVP_get_digestbyobj()
+return either an B<EVP_MD> structure or NULL if an error occurs.
+
+=head1 NOTES
+
+The B<EVP> interface to message digests should almost always be used in
+preference to the low level interfaces. This is because the code then becomes
+transparent to the digest used and much more flexible.
+
+SHA1 is the digest of choice for new applications. The other digest algorithms
+are still in common use.
+
+For most applications the B<impl> parameter to EVP_DigestInit_ex() will be
+set to NULL to use the default digest implementation.
+
+The functions EVP_DigestInit(), EVP_DigestFinal() and EVP_MD_CTX_copy() are 
+obsolete but are retained to maintain compatibility with existing code. New
+applications should use EVP_DigestInit_ex(), EVP_DigestFinal_ex() and 
+EVP_MD_CTX_copy_ex() because they can efficiently reuse a digest context
+instead of initializing and cleaning it up on each call and allow non default
+implementations of digests to be specified.
+
+In OpenSSL 0.9.7 and later if digest contexts are not cleaned up after use
+memory leaks will occur. 
+
+=head1 EXAMPLE
+
+This example digests the data "Test Message\n" and "Hello World\n", using the
+digest name passed on the command line.
+
+ #include <stdio.h>
+ #include <openssl/evp.h>
+
+ main(int argc, char *argv[])
+ {
+ EVP_MD_CTX mdctx;
+ const EVP_MD *md;
+ char mess1[] = "Test Message\n";
+ char mess2[] = "Hello World\n";
+ unsigned char md_value[EVP_MAX_MD_SIZE];
+ int md_len, i;
+
+ OpenSSL_add_all_digests();
+
+ if(!argv[1]) {
+ 	printf("Usage: mdtest digestname\n");
+	exit(1);
+ }
+
+ md = EVP_get_digestbyname(argv[1]);
+
+ if(!md) {
+ 	printf("Unknown message digest %s\n", argv[1]);
+	exit(1);
+ }
+
+ EVP_MD_CTX_init(&mdctx);
+ EVP_DigestInit_ex(&mdctx, md, NULL);
+ EVP_DigestUpdate(&mdctx, mess1, strlen(mess1));
+ EVP_DigestUpdate(&mdctx, mess2, strlen(mess2));
+ EVP_DigestFinal_ex(&mdctx, md_value, &md_len);
+ EVP_MD_CTX_cleanup(&mdctx);
+
+ printf("Digest is: ");
+ for(i = 0; i < md_len; i++) printf("%02x", md_value[i]);
+ printf("\n");
+ }
+
+=head1 SEE ALSO
+
+L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>,
+L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>,
+L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)>
+
+=head1 HISTORY
+
+EVP_DigestInit(), EVP_DigestUpdate() and EVP_DigestFinal() are
+available in all versions of SSLeay and OpenSSL.
+
+EVP_MD_CTX_init(), EVP_MD_CTX_create(), EVP_MD_CTX_copy_ex(),
+EVP_MD_CTX_cleanup(), EVP_MD_CTX_destroy(), EVP_DigestInit_ex()
+and EVP_DigestFinal_ex() were added in OpenSSL 0.9.7.
+
+EVP_md_null(), EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(),
+EVP_dss(), EVP_dss1(), EVP_mdc2() and EVP_ripemd160() were
+changed to return truely const EVP_MD * in OpenSSL 0.9.7.
+
+The link between digests and signing algorithms was fixed in OpenSSL 1.0 and
+later, so now EVP_sha1() can be used with RSA and DSA, there is no need to
+use EVP_dss1() any more.
+
+OpenSSL 1.0 and later does not include the MD2 digest algorithm in the
+default configuration due to its security weaknesses.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_DigestSignInit.pod b/openssl/doc/crypto/EVP_DigestSignInit.pod
new file mode 100644
index 0000000..37d960e
--- /dev/null
+++ b/openssl/doc/crypto/EVP_DigestSignInit.pod
@@ -0,0 +1,87 @@
+=pod
+
+=head1 NAME
+
+EVP_DigestSignInit, EVP_DigestSignUpdate, EVP_DigestSignFinal - EVP signing functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
+ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);
+ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen);
+
+=head1 DESCRIPTION
+
+The EVP signature routines are a high level interface to digital signatures.
+
+EVP_DigestSignInit() sets up signing context B<ctx> to use digest B<type> from
+ENGINE B<impl> and private key B<pkey>. B<ctx> must be initialized with
+EVP_MD_CTX_init() before calling this function. If B<pctx> is not NULL the
+EVP_PKEY_CTX of the signing operation will be written to B<*pctx>: this can
+be used to set alternative signing options.
+
+EVP_DigestSignUpdate() hashes B<cnt> bytes of data at B<d> into the
+signature context B<ctx>. This function can be called several times on the
+same B<ctx> to include additional data. This function is currently implemented
+usig a macro.
+
+EVP_DigestSignFinal() signs the data in B<ctx> places the signature in B<sig>.
+If B<sig> is B<NULL> then the maximum size of the output buffer is written to
+the B<siglen> parameter. If B<sig> is not B<NULL> then before the call the
+B<siglen> parameter should contain the length of the B<sig> buffer, if the
+call is successful the signature is written to B<sig> and the amount of data
+written to B<siglen>.
+
+=head1 RETURN VALUES
+
+EVP_DigestSignInit() EVP_DigestSignUpdate() and EVP_DigestSignaFinal() return
+1 for success and 0 or a negative value for failure. In particular a return
+value of -2 indicates the operation is not supported by the public key
+algorithm.
+
+The error codes can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 NOTES
+
+The B<EVP> interface to digital signatures should almost always be used in
+preference to the low level interfaces. This is because the code then becomes
+transparent to the algorithm used and much more flexible.
+
+In previous versions of OpenSSL there was a link between message digest types
+and public key algorithms. This meant that "clone" digests such as EVP_dss1()
+needed to be used to sign using SHA1 and DSA. This is no longer necessary and
+the use of clone digest is now discouraged.
+
+For some key types and parameters the random number generator must be seeded
+or the operation will fail. 
+
+The call to EVP_DigestSignFinal() internally finalizes a copy of the digest
+context. This means that calls to EVP_DigestSignUpdate() and
+EVP_DigestSignFinal() can be called later to digest and sign additional data.
+
+Since only a copy of the digest context is ever finalized the context must
+be cleaned up after use by calling EVP_MD_CTX_cleanup() or a memory leak
+will occur.
+
+The use of EVP_PKEY_size() with these functions is discouraged because some
+signature operations may have a signature length which depends on the
+parameters set. As a result EVP_PKEY_size() would have to return a value
+which indicates the maximum possible signature for any set of parameters.
+
+=head1 SEE ALSO
+
+L<EVP_DigestVerifyInit(3)|EVP_DigestVerifyInit(3)>,
+L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<err(3)|err(3)>,
+L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>,
+L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>,
+L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)>
+
+=head1 HISTORY
+
+EVP_DigestSignInit(), EVP_DigestSignUpdate() and EVP_DigestSignFinal() 
+were first added to OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_DigestVerifyInit.pod b/openssl/doc/crypto/EVP_DigestVerifyInit.pod
new file mode 100644
index 0000000..f224488
--- /dev/null
+++ b/openssl/doc/crypto/EVP_DigestVerifyInit.pod
@@ -0,0 +1,82 @@
+=pod
+
+=head1 NAME
+
+EVP_DigestVerifyInit, EVP_DigestVerifyUpdate, EVP_DigestVerifyFinal - EVP signature verification functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
+ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);
+ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen);
+
+=head1 DESCRIPTION
+
+The EVP signature routines are a high level interface to digital signatures.
+
+EVP_DigestVerifyInit() sets up verification context B<ctx> to use digest
+B<type> from ENGINE B<impl> and public key B<pkey>. B<ctx> must be initialized
+with EVP_MD_CTX_init() before calling this function. If B<pctx> is not NULL the
+EVP_PKEY_CTX of the verification operation will be written to B<*pctx>: this
+can be used to set alternative verification options.
+
+EVP_DigestVerifyUpdate() hashes B<cnt> bytes of data at B<d> into the
+verification context B<ctx>. This function can be called several times on the
+same B<ctx> to include additional data. This function is currently implemented
+using a macro.
+
+EVP_DigestVerifyFinal() verifies the data in B<ctx> against the signature in
+B<sig> of length B<siglen>.
+
+=head1 RETURN VALUES
+
+EVP_DigestVerifyInit() and EVP_DigestVerifyUpdate() return 1 for success and 0
+or a negative value for failure. In particular a return value of -2 indicates
+the operation is not supported by the public key algorithm.
+
+Unlike other functions the return value 0 from EVP_DigestVerifyFinal() only
+indicates that the signature did not not verify successfully (that is tbs did
+not match the original data or the signature was of invalid form) it is not an
+indication of a more serious error.
+
+The error codes can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 NOTES
+
+The B<EVP> interface to digital signatures should almost always be used in
+preference to the low level interfaces. This is because the code then becomes
+transparent to the algorithm used and much more flexible.
+
+In previous versions of OpenSSL there was a link between message digest types
+and public key algorithms. This meant that "clone" digests such as EVP_dss1()
+needed to be used to sign using SHA1 and DSA. This is no longer necessary and
+the use of clone digest is now discouraged.
+
+For some key types and parameters the random number generator must be seeded
+or the operation will fail. 
+
+The call to EVP_DigestVerifyFinal() internally finalizes a copy of the digest
+context. This means that calls to EVP_VerifyUpdate() and EVP_VerifyFinal() can
+be called later to digest and verify additional data.
+
+Since only a copy of the digest context is ever finalized the context must
+be cleaned up after use by calling EVP_MD_CTX_cleanup() or a memory leak
+will occur.
+
+=head1 SEE ALSO
+
+L<EVP_DigestSignInit(3)|EVP_DigestSignInit(3)>,
+L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<err(3)|err(3)>,
+L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>,
+L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>,
+L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)>
+
+=head1 HISTORY
+
+EVP_DigestVerifyInit(), EVP_DigestVerifyUpdate() and EVP_DigestVerifyFinal() 
+were first added to OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_EncryptInit.pod b/openssl/doc/crypto/EVP_EncryptInit.pod
new file mode 100644
index 0000000..8271d3d
--- /dev/null
+++ b/openssl/doc/crypto/EVP_EncryptInit.pod
@@ -0,0 +1,511 @@
+=pod
+
+=head1 NAME
+
+EVP_CIPHER_CTX_init, EVP_EncryptInit_ex, EVP_EncryptUpdate,
+EVP_EncryptFinal_ex, EVP_DecryptInit_ex, EVP_DecryptUpdate,
+EVP_DecryptFinal_ex, EVP_CipherInit_ex, EVP_CipherUpdate,
+EVP_CipherFinal_ex, EVP_CIPHER_CTX_set_key_length,
+EVP_CIPHER_CTX_ctrl, EVP_CIPHER_CTX_cleanup, EVP_EncryptInit,
+EVP_EncryptFinal, EVP_DecryptInit, EVP_DecryptFinal,
+EVP_CipherInit, EVP_CipherFinal, EVP_get_cipherbyname,
+EVP_get_cipherbynid, EVP_get_cipherbyobj, EVP_CIPHER_nid,
+EVP_CIPHER_block_size, EVP_CIPHER_key_length, EVP_CIPHER_iv_length,
+EVP_CIPHER_flags, EVP_CIPHER_mode, EVP_CIPHER_type, EVP_CIPHER_CTX_cipher,
+EVP_CIPHER_CTX_nid, EVP_CIPHER_CTX_block_size, EVP_CIPHER_CTX_key_length,
+EVP_CIPHER_CTX_iv_length, EVP_CIPHER_CTX_get_app_data,
+EVP_CIPHER_CTX_set_app_data, EVP_CIPHER_CTX_type, EVP_CIPHER_CTX_flags,
+EVP_CIPHER_CTX_mode, EVP_CIPHER_param_to_asn1, EVP_CIPHER_asn1_to_param,
+EVP_CIPHER_CTX_set_padding - EVP cipher routines
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
+
+ int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+	 ENGINE *impl, unsigned char *key, unsigned char *iv);
+ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+         int *outl, unsigned char *in, int inl);
+ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out,
+         int *outl);
+
+ int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+	 ENGINE *impl, unsigned char *key, unsigned char *iv);
+ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+         int *outl, unsigned char *in, int inl);
+ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm,
+         int *outl);
+
+ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+         ENGINE *impl, unsigned char *key, unsigned char *iv, int enc);
+ int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+         int *outl, unsigned char *in, int inl);
+ int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm,
+         int *outl);
+
+ int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+         unsigned char *key, unsigned char *iv);
+ int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out,
+         int *outl);
+
+ int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+         unsigned char *key, unsigned char *iv);
+ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm,
+         int *outl);
+
+ int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+         unsigned char *key, unsigned char *iv, int enc);
+ int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm,
+         int *outl);
+
+ int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *x, int padding);
+ int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
+ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
+ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
+
+ const EVP_CIPHER *EVP_get_cipherbyname(const char *name);
+ #define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))
+ #define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))
+
+ #define EVP_CIPHER_nid(e)		((e)->nid)
+ #define EVP_CIPHER_block_size(e)	((e)->block_size)
+ #define EVP_CIPHER_key_length(e)	((e)->key_len)
+ #define EVP_CIPHER_iv_length(e)		((e)->iv_len)
+ #define EVP_CIPHER_flags(e)		((e)->flags)
+ #define EVP_CIPHER_mode(e)		((e)->flags) & EVP_CIPH_MODE)
+ int EVP_CIPHER_type(const EVP_CIPHER *ctx);
+
+ #define EVP_CIPHER_CTX_cipher(e)	((e)->cipher)
+ #define EVP_CIPHER_CTX_nid(e)		((e)->cipher->nid)
+ #define EVP_CIPHER_CTX_block_size(e)	((e)->cipher->block_size)
+ #define EVP_CIPHER_CTX_key_length(e)	((e)->key_len)
+ #define EVP_CIPHER_CTX_iv_length(e)	((e)->cipher->iv_len)
+ #define EVP_CIPHER_CTX_get_app_data(e)	((e)->app_data)
+ #define EVP_CIPHER_CTX_set_app_data(e,d) ((e)->app_data=(char *)(d))
+ #define EVP_CIPHER_CTX_type(c)         EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c))
+ #define EVP_CIPHER_CTX_flags(e)		((e)->cipher->flags)
+ #define EVP_CIPHER_CTX_mode(e)		((e)->cipher->flags & EVP_CIPH_MODE)
+
+ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+
+=head1 DESCRIPTION
+
+The EVP cipher routines are a high level interface to certain
+symmetric ciphers.
+
+EVP_CIPHER_CTX_init() initializes cipher contex B<ctx>.
+
+EVP_EncryptInit_ex() sets up cipher context B<ctx> for encryption
+with cipher B<type> from ENGINE B<impl>. B<ctx> must be initialized
+before calling this function. B<type> is normally supplied
+by a function such as EVP_des_cbc(). If B<impl> is NULL then the
+default implementation is used. B<key> is the symmetric key to use
+and B<iv> is the IV to use (if necessary), the actual number of bytes
+used for the key and IV depends on the cipher. It is possible to set
+all parameters to NULL except B<type> in an initial call and supply
+the remaining parameters in subsequent calls, all of which have B<type>
+set to NULL. This is done when the default cipher parameters are not
+appropriate.
+
+EVP_EncryptUpdate() encrypts B<inl> bytes from the buffer B<in> and
+writes the encrypted version to B<out>. This function can be called
+multiple times to encrypt successive blocks of data. The amount
+of data written depends on the block alignment of the encrypted data:
+as a result the amount of data written may be anything from zero bytes
+to (inl + cipher_block_size - 1) so B<outl> should contain sufficient
+room. The actual number of bytes written is placed in B<outl>.
+
+If padding is enabled (the default) then EVP_EncryptFinal_ex() encrypts
+the "final" data, that is any data that remains in a partial block.
+It uses L<standard block padding|/NOTES> (aka PKCS padding). The encrypted
+final data is written to B<out> which should have sufficient space for
+one cipher block. The number of bytes written is placed in B<outl>. After
+this function is called the encryption operation is finished and no further
+calls to EVP_EncryptUpdate() should be made.
+
+If padding is disabled then EVP_EncryptFinal_ex() will not encrypt any more
+data and it will return an error if any data remains in a partial block:
+that is if the total data length is not a multiple of the block size. 
+
+EVP_DecryptInit_ex(), EVP_DecryptUpdate() and EVP_DecryptFinal_ex() are the
+corresponding decryption operations. EVP_DecryptFinal() will return an
+error code if padding is enabled and the final block is not correctly
+formatted. The parameters and restrictions are identical to the encryption
+operations except that if padding is enabled the decrypted data buffer B<out>
+passed to EVP_DecryptUpdate() should have sufficient room for
+(B<inl> + cipher_block_size) bytes unless the cipher block size is 1 in
+which case B<inl> bytes is sufficient.
+
+EVP_CipherInit_ex(), EVP_CipherUpdate() and EVP_CipherFinal_ex() are
+functions that can be used for decryption or encryption. The operation
+performed depends on the value of the B<enc> parameter. It should be set
+to 1 for encryption, 0 for decryption and -1 to leave the value unchanged
+(the actual value of 'enc' being supplied in a previous call).
+
+EVP_CIPHER_CTX_cleanup() clears all information from a cipher context
+and free up any allocated memory associate with it. It should be called
+after all operations using a cipher are complete so sensitive information
+does not remain in memory.
+
+EVP_EncryptInit(), EVP_DecryptInit() and EVP_CipherInit() behave in a
+similar way to EVP_EncryptInit_ex(), EVP_DecryptInit_ex and
+EVP_CipherInit_ex() except the B<ctx> paramter does not need to be
+initialized and they always use the default cipher implementation.
+
+EVP_EncryptFinal(), EVP_DecryptFinal() and EVP_CipherFinal() behave in a
+similar way to EVP_EncryptFinal_ex(), EVP_DecryptFinal_ex() and
+EVP_CipherFinal_ex() except B<ctx> is automatically cleaned up 
+after the call.
+
+EVP_get_cipherbyname(), EVP_get_cipherbynid() and EVP_get_cipherbyobj()
+return an EVP_CIPHER structure when passed a cipher name, a NID or an
+ASN1_OBJECT structure.
+
+EVP_CIPHER_nid() and EVP_CIPHER_CTX_nid() return the NID of a cipher when
+passed an B<EVP_CIPHER> or B<EVP_CIPHER_CTX> structure.  The actual NID
+value is an internal value which may not have a corresponding OBJECT
+IDENTIFIER.
+
+EVP_CIPHER_CTX_set_padding() enables or disables padding. By default
+encryption operations are padded using standard block padding and the
+padding is checked and removed when decrypting. If the B<pad> parameter
+is zero then no padding is performed, the total amount of data encrypted
+or decrypted must then be a multiple of the block size or an error will
+occur.
+
+EVP_CIPHER_key_length() and EVP_CIPHER_CTX_key_length() return the key
+length of a cipher when passed an B<EVP_CIPHER> or B<EVP_CIPHER_CTX>
+structure. The constant B<EVP_MAX_KEY_LENGTH> is the maximum key length
+for all ciphers. Note: although EVP_CIPHER_key_length() is fixed for a
+given cipher, the value of EVP_CIPHER_CTX_key_length() may be different
+for variable key length ciphers.
+
+EVP_CIPHER_CTX_set_key_length() sets the key length of the cipher ctx.
+If the cipher is a fixed length cipher then attempting to set the key
+length to any value other than the fixed value is an error.
+
+EVP_CIPHER_iv_length() and EVP_CIPHER_CTX_iv_length() return the IV
+length of a cipher when passed an B<EVP_CIPHER> or B<EVP_CIPHER_CTX>.
+It will return zero if the cipher does not use an IV.  The constant
+B<EVP_MAX_IV_LENGTH> is the maximum IV length for all ciphers.
+
+EVP_CIPHER_block_size() and EVP_CIPHER_CTX_block_size() return the block
+size of a cipher when passed an B<EVP_CIPHER> or B<EVP_CIPHER_CTX>
+structure. The constant B<EVP_MAX_IV_LENGTH> is also the maximum block
+length for all ciphers.
+
+EVP_CIPHER_type() and EVP_CIPHER_CTX_type() return the type of the passed
+cipher or context. This "type" is the actual NID of the cipher OBJECT
+IDENTIFIER as such it ignores the cipher parameters and 40 bit RC2 and
+128 bit RC2 have the same NID. If the cipher does not have an object
+identifier or does not have ASN1 support this function will return
+B<NID_undef>.
+
+EVP_CIPHER_CTX_cipher() returns the B<EVP_CIPHER> structure when passed
+an B<EVP_CIPHER_CTX> structure.
+
+EVP_CIPHER_mode() and EVP_CIPHER_CTX_mode() return the block cipher mode:
+EVP_CIPH_ECB_MODE, EVP_CIPH_CBC_MODE, EVP_CIPH_CFB_MODE or
+EVP_CIPH_OFB_MODE. If the cipher is a stream cipher then
+EVP_CIPH_STREAM_CIPHER is returned.
+
+EVP_CIPHER_param_to_asn1() sets the AlgorithmIdentifier "parameter" based
+on the passed cipher. This will typically include any parameters and an
+IV. The cipher IV (if any) must be set when this call is made. This call
+should be made before the cipher is actually "used" (before any
+EVP_EncryptUpdate(), EVP_DecryptUpdate() calls for example). This function
+may fail if the cipher does not have any ASN1 support.
+
+EVP_CIPHER_asn1_to_param() sets the cipher parameters based on an ASN1
+AlgorithmIdentifier "parameter". The precise effect depends on the cipher
+In the case of RC2, for example, it will set the IV and effective key length.
+This function should be called after the base cipher type is set but before
+the key is set. For example EVP_CipherInit() will be called with the IV and
+key set to NULL, EVP_CIPHER_asn1_to_param() will be called and finally
+EVP_CipherInit() again with all parameters except the key set to NULL. It is
+possible for this function to fail if the cipher does not have any ASN1 support
+or the parameters cannot be set (for example the RC2 effective key length
+is not supported.
+
+EVP_CIPHER_CTX_ctrl() allows various cipher specific parameters to be determined
+and set. Currently only the RC2 effective key length and the number of rounds of
+RC5 can be set.
+
+=head1 RETURN VALUES
+
+EVP_EncryptInit_ex(), EVP_EncryptUpdate() and EVP_EncryptFinal_ex()
+return 1 for success and 0 for failure.
+
+EVP_DecryptInit_ex() and EVP_DecryptUpdate() return 1 for success and 0 for failure.
+EVP_DecryptFinal_ex() returns 0 if the decrypt failed or 1 for success.
+
+EVP_CipherInit_ex() and EVP_CipherUpdate() return 1 for success and 0 for failure.
+EVP_CipherFinal_ex() returns 0 for a decryption failure or 1 for success.
+
+EVP_CIPHER_CTX_cleanup() returns 1 for success and 0 for failure.
+
+EVP_get_cipherbyname(), EVP_get_cipherbynid() and EVP_get_cipherbyobj()
+return an B<EVP_CIPHER> structure or NULL on error.
+
+EVP_CIPHER_nid() and EVP_CIPHER_CTX_nid() return a NID.
+
+EVP_CIPHER_block_size() and EVP_CIPHER_CTX_block_size() return the block
+size.
+
+EVP_CIPHER_key_length() and EVP_CIPHER_CTX_key_length() return the key
+length.
+
+EVP_CIPHER_CTX_set_padding() always returns 1.
+
+EVP_CIPHER_iv_length() and EVP_CIPHER_CTX_iv_length() return the IV
+length or zero if the cipher does not use an IV.
+
+EVP_CIPHER_type() and EVP_CIPHER_CTX_type() return the NID of the cipher's
+OBJECT IDENTIFIER or NID_undef if it has no defined OBJECT IDENTIFIER.
+
+EVP_CIPHER_CTX_cipher() returns an B<EVP_CIPHER> structure.
+
+EVP_CIPHER_param_to_asn1() and EVP_CIPHER_asn1_to_param() return 1 for 
+success or zero for failure.
+
+=head1 CIPHER LISTING
+
+All algorithms have a fixed key length unless otherwise stated.
+
+=over 4
+
+=item EVP_enc_null()
+
+Null cipher: does nothing.
+
+=item EVP_des_cbc(void), EVP_des_ecb(void), EVP_des_cfb(void), EVP_des_ofb(void)
+
+DES in CBC, ECB, CFB and OFB modes respectively. 
+
+=item EVP_des_ede_cbc(void), EVP_des_ede(), EVP_des_ede_ofb(void),  EVP_des_ede_cfb(void)
+
+Two key triple DES in CBC, ECB, CFB and OFB modes respectively.
+
+=item EVP_des_ede3_cbc(void), EVP_des_ede3(), EVP_des_ede3_ofb(void),  EVP_des_ede3_cfb(void)
+
+Three key triple DES in CBC, ECB, CFB and OFB modes respectively.
+
+=item EVP_desx_cbc(void)
+
+DESX algorithm in CBC mode.
+
+=item EVP_rc4(void)
+
+RC4 stream cipher. This is a variable key length cipher with default key length 128 bits.
+
+=item EVP_rc4_40(void)
+
+RC4 stream cipher with 40 bit key length. This is obsolete and new code should use EVP_rc4()
+and the EVP_CIPHER_CTX_set_key_length() function.
+
+=item EVP_idea_cbc() EVP_idea_ecb(void), EVP_idea_cfb(void), EVP_idea_ofb(void), EVP_idea_cbc(void)
+
+IDEA encryption algorithm in CBC, ECB, CFB and OFB modes respectively.
+
+=item EVP_rc2_cbc(void), EVP_rc2_ecb(void), EVP_rc2_cfb(void), EVP_rc2_ofb(void)
+
+RC2 encryption algorithm in CBC, ECB, CFB and OFB modes respectively. This is a variable key
+length cipher with an additional parameter called "effective key bits" or "effective key length".
+By default both are set to 128 bits.
+
+=item EVP_rc2_40_cbc(void), EVP_rc2_64_cbc(void)
+
+RC2 algorithm in CBC mode with a default key length and effective key length of 40 and 64 bits.
+These are obsolete and new code should use EVP_rc2_cbc(), EVP_CIPHER_CTX_set_key_length() and
+EVP_CIPHER_CTX_ctrl() to set the key length and effective key length.
+
+=item EVP_bf_cbc(void), EVP_bf_ecb(void), EVP_bf_cfb(void), EVP_bf_ofb(void);
+
+Blowfish encryption algorithm in CBC, ECB, CFB and OFB modes respectively. This is a variable key
+length cipher.
+
+=item EVP_cast5_cbc(void), EVP_cast5_ecb(void), EVP_cast5_cfb(void), EVP_cast5_ofb(void)
+
+CAST encryption algorithm in CBC, ECB, CFB and OFB modes respectively. This is a variable key
+length cipher.
+
+=item EVP_rc5_32_12_16_cbc(void), EVP_rc5_32_12_16_ecb(void), EVP_rc5_32_12_16_cfb(void), EVP_rc5_32_12_16_ofb(void)
+
+RC5 encryption algorithm in CBC, ECB, CFB and OFB modes respectively. This is a variable key length
+cipher with an additional "number of rounds" parameter. By default the key length is set to 128
+bits and 12 rounds.
+
+=back
+
+=head1 NOTES
+
+Where possible the B<EVP> interface to symmetric ciphers should be used in
+preference to the low level interfaces. This is because the code then becomes
+transparent to the cipher used and much more flexible.
+
+PKCS padding works by adding B<n> padding bytes of value B<n> to make the total 
+length of the encrypted data a multiple of the block size. Padding is always
+added so if the data is already a multiple of the block size B<n> will equal
+the block size. For example if the block size is 8 and 11 bytes are to be
+encrypted then 5 padding bytes of value 5 will be added.
+
+When decrypting the final block is checked to see if it has the correct form.
+
+Although the decryption operation can produce an error if padding is enabled,
+it is not a strong test that the input data or key is correct. A random block
+has better than 1 in 256 chance of being of the correct format and problems with
+the input data earlier on will not produce a final decrypt error.
+
+If padding is disabled then the decryption operation will always succeed if
+the total amount of data decrypted is a multiple of the block size.
+
+The functions EVP_EncryptInit(), EVP_EncryptFinal(), EVP_DecryptInit(),
+EVP_CipherInit() and EVP_CipherFinal() are obsolete but are retained for
+compatibility with existing code. New code should use EVP_EncryptInit_ex(),
+EVP_EncryptFinal_ex(), EVP_DecryptInit_ex(), EVP_DecryptFinal_ex(),
+EVP_CipherInit_ex() and EVP_CipherFinal_ex() because they can reuse an
+existing context without allocating and freeing it up on each call.
+
+=head1 BUGS
+
+For RC5 the number of rounds can currently only be set to 8, 12 or 16. This is
+a limitation of the current RC5 code rather than the EVP interface.
+
+EVP_MAX_KEY_LENGTH and EVP_MAX_IV_LENGTH only refer to the internal ciphers with
+default key lengths. If custom ciphers exceed these values the results are
+unpredictable. This is because it has become standard practice to define a 
+generic key as a fixed unsigned char array containing EVP_MAX_KEY_LENGTH bytes.
+
+The ASN1 code is incomplete (and sometimes inaccurate) it has only been tested
+for certain common S/MIME ciphers (RC2, DES, triple DES) in CBC mode.
+
+=head1 EXAMPLES
+
+Get the number of rounds used in RC5:
+
+ int nrounds;
+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GET_RC5_ROUNDS, 0, &nrounds);
+
+Get the RC2 effective key length:
+
+ int key_bits;
+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GET_RC2_KEY_BITS, 0, &key_bits);
+
+Set the number of rounds used in RC5:
+
+ int nrounds;
+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC5_ROUNDS, nrounds, NULL);
+
+Set the effective key length used in RC2:
+
+ int key_bits;
+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
+
+Encrypt a string using blowfish:
+
+ int do_crypt(char *outfile)
+ 	{
+	unsigned char outbuf[1024];
+	int outlen, tmplen;
+	/* Bogus key and IV: we'd normally set these from
+	 * another source.
+	 */
+	unsigned char key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+	unsigned char iv[] = {1,2,3,4,5,6,7,8};
+	char intext[] = "Some Crypto Text";
+	EVP_CIPHER_CTX ctx;
+	FILE *out;
+	EVP_CIPHER_CTX_init(&ctx);
+	EVP_EncryptInit_ex(&ctx, EVP_bf_cbc(), NULL, key, iv);
+
+	if(!EVP_EncryptUpdate(&ctx, outbuf, &outlen, intext, strlen(intext)))
+		{
+		/* Error */
+		return 0;
+		}
+	/* Buffer passed to EVP_EncryptFinal() must be after data just
+	 * encrypted to avoid overwriting it.
+	 */
+	if(!EVP_EncryptFinal_ex(&ctx, outbuf + outlen, &tmplen))
+		{
+		/* Error */
+		return 0;
+		}
+	outlen += tmplen;
+	EVP_CIPHER_CTX_cleanup(&ctx);
+	/* Need binary mode for fopen because encrypted data is
+	 * binary data. Also cannot use strlen() on it because
+         * it wont be null terminated and may contain embedded
+	 * nulls.
+	 */
+	out = fopen(outfile, "wb");
+	fwrite(outbuf, 1, outlen, out);
+	fclose(out);
+	return 1;
+	}
+
+The ciphertext from the above example can be decrypted using the B<openssl>
+utility with the command line:
+ 
+ S<openssl bf -in cipher.bin -K 000102030405060708090A0B0C0D0E0F -iv 0102030405060708 -d>
+
+General encryption, decryption function example using FILE I/O and RC2 with an
+80 bit key:
+
+ int do_crypt(FILE *in, FILE *out, int do_encrypt)
+ 	{
+	/* Allow enough space in output buffer for additional block */
+	inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
+	int inlen, outlen;
+	/* Bogus key and IV: we'd normally set these from
+	 * another source.
+	 */
+	unsigned char key[] = "0123456789";
+	unsigned char iv[] = "12345678";
+	/* Don't set key or IV because we will modify the parameters */
+	EVP_CIPHER_CTX_init(&ctx);
+	EVP_CipherInit_ex(&ctx, EVP_rc2(), NULL, NULL, NULL, do_encrypt);
+	EVP_CIPHER_CTX_set_key_length(&ctx, 10);
+	/* We finished modifying parameters so now we can set key and IV */
+	EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);
+
+	for(;;) 
+		{
+		inlen = fread(inbuf, 1, 1024, in);
+		if(inlen <= 0) break;
+		if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen))
+			{
+			/* Error */
+			EVP_CIPHER_CTX_cleanup(&ctx);
+			return 0;
+			}
+		fwrite(outbuf, 1, outlen, out);
+		}
+	if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen))
+		{
+		/* Error */
+		EVP_CIPHER_CTX_cleanup(&ctx);
+		return 0;
+		}
+	fwrite(outbuf, 1, outlen, out);
+
+	EVP_CIPHER_CTX_cleanup(&ctx);
+	return 1;
+	}
+
+
+=head1 SEE ALSO
+
+L<evp(3)|evp(3)>
+
+=head1 HISTORY
+
+EVP_CIPHER_CTX_init(), EVP_EncryptInit_ex(), EVP_EncryptFinal_ex(),
+EVP_DecryptInit_ex(), EVP_DecryptFinal_ex(), EVP_CipherInit_ex(),
+EVP_CipherFinal_ex() and EVP_CIPHER_CTX_set_padding() appeared in
+OpenSSL 0.9.7.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_OpenInit.pod b/openssl/doc/crypto/EVP_OpenInit.pod
new file mode 100644
index 0000000..2e710da
--- /dev/null
+++ b/openssl/doc/crypto/EVP_OpenInit.pod
@@ -0,0 +1,63 @@
+=pod
+
+=head1 NAME
+
+EVP_OpenInit, EVP_OpenUpdate, EVP_OpenFinal - EVP envelope decryption
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_OpenInit(EVP_CIPHER_CTX *ctx,EVP_CIPHER *type,unsigned char *ek,
+		int ekl,unsigned char *iv,EVP_PKEY *priv);
+ int EVP_OpenUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+         int *outl, unsigned char *in, int inl);
+ int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out,
+         int *outl);
+
+=head1 DESCRIPTION
+
+The EVP envelope routines are a high level interface to envelope
+decryption. They decrypt a public key encrypted symmetric key and
+then decrypt data using it.
+
+EVP_OpenInit() initializes a cipher context B<ctx> for decryption
+with cipher B<type>. It decrypts the encrypted symmetric key of length
+B<ekl> bytes passed in the B<ek> parameter using the private key B<priv>.
+The IV is supplied in the B<iv> parameter.
+
+EVP_OpenUpdate() and EVP_OpenFinal() have exactly the same properties
+as the EVP_DecryptUpdate() and EVP_DecryptFinal() routines, as 
+documented on the L<EVP_EncryptInit(3)|EVP_EncryptInit(3)> manual
+page.
+
+=head1 NOTES
+
+It is possible to call EVP_OpenInit() twice in the same way as
+EVP_DecryptInit(). The first call should have B<priv> set to NULL
+and (after setting any cipher parameters) it should be called again
+with B<type> set to NULL.
+
+If the cipher passed in the B<type> parameter is a variable length
+cipher then the key length will be set to the value of the recovered
+key length. If the cipher is a fixed length cipher then the recovered
+key length must match the fixed cipher length.
+
+=head1 RETURN VALUES
+
+EVP_OpenInit() returns 0 on error or a non zero integer (actually the
+recovered secret key size) if successful.
+
+EVP_OpenUpdate() returns 1 for success or 0 for failure.
+
+EVP_OpenFinal() returns 0 if the decrypt failed or 1 for success.
+
+=head1 SEE ALSO
+
+L<evp(3)|evp(3)>, L<rand(3)|rand(3)>,
+L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>,
+L<EVP_SealInit(3)|EVP_SealInit(3)>
+
+=head1 HISTORY
+
+=cut
diff --git a/openssl/doc/crypto/EVP_PKEY_CTX_ctrl.pod b/openssl/doc/crypto/EVP_PKEY_CTX_ctrl.pod
new file mode 100644
index 0000000..f2f4559
--- /dev/null
+++ b/openssl/doc/crypto/EVP_PKEY_CTX_ctrl.pod
@@ -0,0 +1,128 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_ctrl, EVP_PKEY_ctrl_str - algorithm specific control operations
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
+				int cmd, int p1, void *p2);
+ int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
+						const char *value);
+
+ int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
+
+ #include <openssl/rsa.h>
+
+ int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
+
+ int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad);
+ int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int len);
+ int EVP_PKEY_CTX_set_rsa_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int mbits);
+ int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp);
+
+ #include <openssl/dsa.h>
+ int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits);
+
+ #include <openssl/dh.h>
+ int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int len);
+ int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen);
+
+ #include <openssl/ec.h>
+ int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid);
+
+=head1 DESCRIPTION
+
+The function EVP_PKEY_CTX_ctrl() sends a control operation to the context
+B<ctx>. The key type used must match B<keytype> if it is not -1. The parameter
+B<optype> is a mask indicating which operations the control can be applied to.
+The control command is indicated in B<cmd> and any additional arguments in
+B<p1> and B<p2>.
+
+Applications will not normally call EVP_PKEY_CTX_ctrl() directly but will
+instead call one of the algorithm specific macros below.
+
+The function EVP_PKEY_ctrl_str() allows an application to send an algorithm
+specific control operation to a context B<ctx> in string form. This is
+intended to be used for options specified on the command line or in text
+files. The commands supported are documented in the openssl utility
+command line pages for the option B<-pkeyopt> which is supported by the
+B<pkeyutl>, B<genpkey> and B<req> commands.
+
+All the remaining "functions" are implemented as macros.
+
+The EVP_PKEY_CTX_set_signature_md() macro sets the message digest type used
+in a signature. It can be used with any public key algorithm supporting
+signature operations.
+
+The macro EVP_PKEY_CTX_set_rsa_padding() sets the RSA padding mode for B<ctx>.
+The B<pad> parameter can take the value RSA_PKCS1_PADDING for PKCS#1 padding,
+RSA_SSLV23_PADDING for SSLv23 padding, RSA_NO_PADDING for no padding,
+RSA_PKCS1_OAEP_PADDING for OAEP padding (encrypt and decrypt only),
+RSA_X931_PADDING for X9.31 padding (signature operations only) and 
+RSA_PKCS1_PSS_PADDING (sign and verify only).
+
+Two RSA padding modes behave differently if EVP_PKEY_CTX_set_signature_md()
+is used. If this macro is called for PKCS#1 padding the plaintext buffer is
+an actual digest value and is encapsulated in a DigestInfo structure according
+to PKCS#1 when signing and this structure is expected (and stripped off) when
+verifying. If this control is not used with RSA and PKCS#1 padding then the
+supplied data is used directly and not encapsulated. In the case of X9.31
+padding for RSA the algorithm identifier byte is added or checked and removed
+if this control is called. If it is not called then the first byte of the plaintext buffer is expected to be the algorithm identifier byte.
+
+The EVP_PKEY_CTX_set_rsa_pss_saltlen() macro sets the RSA PSS salt length to
+B<len> as its name implies it is only supported for PSS padding.  Two special
+values are supported: -1 sets the salt length to the digest length. When
+signing -2 sets the salt length to the maximum permissible value. When
+verifying -2 causes the salt length to be automatically determined based on the
+B<PSS> block structure. If this macro is not called a salt length value of -2
+is used by default.
+
+The EVP_PKEY_CTX_set_rsa_rsa_keygen_bits() macro sets the RSA key length for
+RSA key genration to B<bits>. If not specified 1024 bits is used.
+
+The EVP_PKEY_CTX_set_rsa_keygen_pubexp() macro sets the public exponent value
+for RSA key generation to B<pubexp> currently it should be an odd integer. The
+B<pubexp> pointer is used internally by this function so it should not be 
+modified or free after the call. If this macro is not called then 65537 is used.
+
+The macro EVP_PKEY_CTX_set_dsa_paramgen_bits() sets the number of bits used
+for DSA parameter generation to B<bits>. If not specified 1024 is used.
+
+The macro EVP_PKEY_CTX_set_dh_paramgen_prime_len() sets the length of the DH
+prime parameter B<p> for DH parameter generation. If this macro is not called
+then 1024 is used.
+
+The EVP_PKEY_CTX_set_dh_paramgen_generator() macro sets DH generator to B<gen>
+for DH parameter generation. If not specified 2 is used.
+
+The EVP_PKEY_CTX_set_ec_paramgen_curve_nid() sets the EC curve for EC parameter
+generation to B<nid>. For EC parameter generation this macro must be called
+or an error occurs because there is no default curve.
+
+=head1 RETURN VALUES
+
+EVP_PKEY_CTX_ctrl() and its macros return a positive value for success and 0
+or a negative value for failure. In particular a return value of -2
+indicates the operation is not supported by the public key algorithm.
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
+L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
+L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
+L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
+L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
+L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
+L<EVP_PKEY_keygen(3)|EVP_PKEY_keygen(3)> 
+
+=head1 HISTORY
+
+These functions were first added to OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_PKEY_CTX_new.pod b/openssl/doc/crypto/EVP_PKEY_CTX_new.pod
new file mode 100644
index 0000000..a9af867
--- /dev/null
+++ b/openssl/doc/crypto/EVP_PKEY_CTX_new.pod
@@ -0,0 +1,52 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_CTX_new, EVP_PKEY_CTX_new_id, EVP_PKEY_CTX_dup, EVP_PKEY_CTX_free - public key algorithm context functions.
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
+ EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
+ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx);
+ void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
+
+=head1 DESCRIPTION
+
+The EVP_PKEY_CTX_new() function allocates public key algorithm context using
+the algorithm specified in B<pkey> and ENGINE B<e>.
+
+The EVP_PKEY_CTX_new_id() function allocates public key algorithm context
+using the algorithm specified by B<id> and ENGINE B<e>. It is normally used
+when no B<EVP_PKEY> structure is associated with the operations, for example
+during parameter generation of key genration for some algorithms.
+
+EVP_PKEY_CTX_dup() duplicates the context B<ctx>.
+
+EVP_PKEY_CTX_free() frees up the context B<ctx>.
+
+=head1 NOTES
+
+The B<EVP_PKEY_CTX> structure is an opaque public key algorithm context used
+by the OpenSSL high level public key API. Contexts B<MUST NOT> be shared between
+threads: that is it is not permissible to use the same context simultaneously
+in two threads.
+
+=head1 RETURN VALUES
+
+EVP_PKEY_CTX_new(), EVP_PKEY_CTX_new_id(), EVP_PKEY_CTX_dup() returns either
+the newly allocated B<EVP_PKEY_CTX> structure of B<NULL> if an error occurred.
+
+EVP_PKEY_CTX_free() does not return a value.
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_new(3)|EVP_PKEY_new(3)>
+
+=head1 HISTORY
+
+These functions were first added to OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_PKEY_cmp.pod b/openssl/doc/crypto/EVP_PKEY_cmp.pod
new file mode 100644
index 0000000..4f8185e
--- /dev/null
+++ b/openssl/doc/crypto/EVP_PKEY_cmp.pod
@@ -0,0 +1,61 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_copy_parameters, EVP_PKEY_missing_parameters, EVP_PKEY_cmp_parameters, EVP_PKEY_cmp - public key parameter and comparison functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey);
+ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from);
+
+ int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b);
+ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
+
+=head1 DESCRIPTION
+
+The function EVP_PKEY_missing_parameters() returns 1 if the public key
+parameters of B<pkey> are missing and 0 if they are present or the algorithm
+doesn't use parameters.
+
+The function EVP_PKEY_copy_parameters() copies the parameters from key
+B<from> to key B<to>.
+
+The funcion EVP_PKEY_cmp_parameters() compares the parameters of keys
+B<a> and B<b>.
+
+The funcion EVP_PKEY_cmp() compares the public key components and paramters
+(if present) of keys B<a> and B<b>.
+
+=head1 NOTES
+
+The main purpose of the functions EVP_PKEY_missing_parameters() and
+EVP_PKEY_copy_parameters() is to handle public keys in certificates where the
+parameters are sometimes omitted from a public key if they are inherited from
+the CA that signed it.
+
+Since OpenSSL private keys contain public key components too the function
+EVP_PKEY_cmp() can also be used to determine if a private key matches
+a public key.
+
+=head1 RETURN VALUES
+
+The function EVP_PKEY_missing_parameters() returns 1 if the public key
+parameters of B<pkey> are missing and 0 if they are present or the algorithm
+doesn't use parameters.
+
+These functions EVP_PKEY_copy_parameters() returns 1 for success and 0 for
+failure.
+
+The function EVP_PKEY_cmp_parameters() and EVP_PKEY_cmp() return 1 if the
+keys match, 0 if they don't match, -1 if the key types are different and
+-2 if the operation is not supported.
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
+L<EVP_PKEY_keygen(3)|EVP_PKEY_keygen(3)> 
+
+=cut
diff --git a/openssl/doc/crypto/EVP_PKEY_decrypt.pod b/openssl/doc/crypto/EVP_PKEY_decrypt.pod
new file mode 100644
index 0000000..42b2a8c
--- /dev/null
+++ b/openssl/doc/crypto/EVP_PKEY_decrypt.pod
@@ -0,0 +1,93 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_decrypt_init, EVP_PKEY_decrypt - decrypt using a public key algorithm
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
+ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
+			unsigned char *out, size_t *outlen,
+			const unsigned char *in, size_t inlen);
+
+=head1 DESCRIPTION
+
+The EVP_PKEY_decrypt_init() function initializes a public key algorithm
+context using key B<pkey> for a decryption operation.
+
+The EVP_PKEY_decrypt() function performs a public key decryption operation
+using B<ctx>. The data to be decrypted is specified using the B<in> and
+B<inlen> parameters. If B<out> is B<NULL> then the maximum size of the output
+buffer is written to the B<outlen> parameter. If B<out> is not B<NULL> then
+before the call the B<outlen> parameter should contain the length of the
+B<out> buffer, if the call is successful the decrypted data is written to
+B<out> and the amount of data written to B<outlen>.
+
+=head1 NOTES
+
+After the call to EVP_PKEY_decrypt_init() algorithm specific control
+operations can be performed to set any appropriate parameters for the
+operation.
+
+The function EVP_PKEY_decrypt() can be called more than once on the same
+context if several operations are performed using the same parameters.
+
+=head1 RETURN VALUES
+
+EVP_PKEY_decrypt_init() and EVP_PKEY_decrypt() return 1 for success and 0
+or a negative value for failure. In particular a return value of -2
+indicates the operation is not supported by the public key algorithm.
+
+=head1 EXAMPLE
+
+Decrypt data using OAEP (for RSA keys):
+
+ #include <openssl/evp.h>
+ #include <openssl/rsa.h>
+
+ EVP_PKEY_CTX *ctx;
+ unsigned char *out, *in;
+ size_t outlen, inlen; 
+ EVP_PKEY *key;
+ /* NB: assumes key in, inlen are already set up
+  * and that key is an RSA private key
+  */
+ ctx = EVP_PKEY_CTX_new(key);
+ if (!ctx)
+	/* Error occurred */
+ if (EVP_PKEY_decrypt_init(ctx) <= 0)
+	/* Error */
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_OAEP_PADDING) <= 0)
+	/* Error */
+
+ /* Determine buffer length */
+ if (EVP_PKEY_decrypt(ctx, NULL, &outlen, in, inlen) <= 0)
+	/* Error */
+
+ out = OPENSSL_malloc(outlen);
+
+ if (!out)
+	/* malloc failure */
+ 
+ if (EVP_PKEY_decrypt(ctx, out, &outlen, in, inlen) <= 0)
+	/* Error */
+
+ /* Decrypted data is outlen bytes written to buffer out */
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
+L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
+L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
+L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
+L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
+
+=head1 HISTORY
+
+These functions were first added to OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_PKEY_derive.pod b/openssl/doc/crypto/EVP_PKEY_derive.pod
new file mode 100644
index 0000000..d9d6d76
--- /dev/null
+++ b/openssl/doc/crypto/EVP_PKEY_derive.pod
@@ -0,0 +1,93 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_derive_init, EVP_PKEY_derive_set_peer, EVP_PKEY_derive - derive public key algorithm shared secret.
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
+ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
+ int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
+
+=head1 DESCRIPTION
+
+The EVP_PKEY_derive_init() function initializes a public key algorithm
+context using key B<pkey> for shared secret derivation.
+
+The EVP_PKEY_derive_set_peer() function sets the peer key: this will normally
+be a public key.
+
+The EVP_PKEY_derive() derives a shared secret using B<ctx>.
+If B<key> is B<NULL> then the maximum size of the output buffer is written to
+the B<keylen> parameter. If B<key> is not B<NULL> then before the call the
+B<keylen> parameter should contain the length of the B<key> buffer, if the call
+is successful the shared secret is written to B<key> and the amount of data
+written to B<keylen>.
+
+=head1 NOTES
+
+After the call to EVP_PKEY_derive_init() algorithm specific control
+operations can be performed to set any appropriate parameters for the
+operation.
+
+The function EVP_PKEY_derive() can be called more than once on the same
+context if several operations are performed using the same parameters.
+
+=head1 RETURN VALUES
+
+EVP_PKEY_derive_init() and EVP_PKEY_derive() return 1 for success and 0
+or a negative value for failure. In particular a return value of -2
+indicates the operation is not supported by the public key algorithm.
+
+=head1 EXAMPLE
+
+Derive shared secret (for example DH or EC keys):
+
+ #include <openssl/evp.h>
+ #include <openssl/rsa.h>
+
+ EVP_PKEY_CTX *ctx;
+ unsigned char *skey;
+ size_t skeylen;
+ EVP_PKEY *pkey, *peerkey;
+ /* NB: assumes pkey, peerkey have been already set up */
+
+ ctx = EVP_PKEY_CTX_new(pkey);
+ if (!ctx)
+	/* Error occurred */
+ if (EVP_PKEY_derive_init(ctx) <= 0)
+	/* Error */
+ if (EVP_PKEY_derive_set_peer(ctx, peerkey) <= 0)
+	/* Error */
+
+ /* Determine buffer length */
+ if (EVP_PKEY_derive(ctx, NULL, &skeylen) <= 0)
+	/* Error */
+
+ skey = OPENSSL_malloc(skeylen);
+
+ if (!skey)
+	/* malloc failure */
+ 
+ if (EVP_PKEY_derive(ctx, skey, &skeylen) <= 0)
+	/* Error */
+
+ /* Shared secret is skey bytes written to buffer skey */
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
+L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
+L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
+L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
+L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
+L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+
+=head1 HISTORY
+
+These functions were first added to OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_PKEY_encrypt.pod b/openssl/doc/crypto/EVP_PKEY_encrypt.pod
new file mode 100644
index 0000000..91c9c5d
--- /dev/null
+++ b/openssl/doc/crypto/EVP_PKEY_encrypt.pod
@@ -0,0 +1,93 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_encrypt_init, EVP_PKEY_encrypt - encrypt using a public key algorithm
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
+ int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
+			unsigned char *out, size_t *outlen,
+			const unsigned char *in, size_t inlen);
+
+=head1 DESCRIPTION
+
+The EVP_PKEY_encrypt_init() function initializes a public key algorithm
+context using key B<pkey> for an encryption operation.
+
+The EVP_PKEY_encrypt() function performs a public key encryption operation
+using B<ctx>. The data to be encrypted is specified using the B<in> and
+B<inlen> parameters. If B<out> is B<NULL> then the maximum size of the output
+buffer is written to the B<outlen> parameter. If B<out> is not B<NULL> then
+before the call the B<outlen> parameter should contain the length of the
+B<out> buffer, if the call is successful the encrypted data is written to
+B<out> and the amount of data written to B<outlen>.
+
+=head1 NOTES
+
+After the call to EVP_PKEY_encrypt_init() algorithm specific control
+operations can be performed to set any appropriate parameters for the
+operation.
+
+The function EVP_PKEY_encrypt() can be called more than once on the same
+context if several operations are performed using the same parameters.
+
+=head1 RETURN VALUES
+
+EVP_PKEY_encrypt_init() and EVP_PKEY_encrypt() return 1 for success and 0
+or a negative value for failure. In particular a return value of -2
+indicates the operation is not supported by the public key algorithm.
+
+=head1 EXAMPLE
+
+Encrypt data using OAEP (for RSA keys):
+
+ #include <openssl/evp.h>
+ #include <openssl/rsa.h>
+
+ EVP_PKEY_CTX *ctx;
+ unsigned char *out, *in;
+ size_t outlen, inlen; 
+ EVP_PKEY *key;
+ /* NB: assumes key in, inlen are already set up
+  * and that key is an RSA public key
+  */
+ ctx = EVP_PKEY_CTX_new(key);
+ if (!ctx)
+	/* Error occurred */
+ if (EVP_PKEY_encrypt_init(ctx) <= 0)
+	/* Error */
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_OAEP_PADDING) <= 0)
+	/* Error */
+
+ /* Determine buffer length */
+ if (EVP_PKEY_encrypt(ctx, NULL, &outlen, in, inlen) <= 0)
+	/* Error */
+
+ out = OPENSSL_malloc(outlen);
+
+ if (!out)
+	/* malloc failure */
+ 
+ if (EVP_PKEY_encrypt(ctx, out, &outlen, in, inlen) <= 0)
+	/* Error */
+
+ /* Encrypted data is outlen bytes written to buffer out */
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
+L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
+L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
+L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
+L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
+
+=head1 HISTORY
+
+These functions were first added to OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_PKEY_get_default_digest.pod b/openssl/doc/crypto/EVP_PKEY_get_default_digest.pod
new file mode 100644
index 0000000..1a9c795
--- /dev/null
+++ b/openssl/doc/crypto/EVP_PKEY_get_default_digest.pod
@@ -0,0 +1,41 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_get_default_digest_nid - get default signature digest
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+ int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
+
+=head1 DESCRIPTION
+
+The EVP_PKEY_get_default_digest_nid() function sets B<pnid> to the default
+message digest NID for the public key signature operations associated with key
+B<pkey>.
+
+=head1 NOTES
+
+For all current standard OpenSSL public key algorithms SHA1 is returned.
+
+=head1 RETURN VALUES
+
+The EVP_PKEY_get_default_digest_nid() function returns 1 if the message digest
+is advisory (that is other digests can be used) and 2 if it is mandatory (other
+digests can not be used).  It returns 0 or a negative value for failure. In
+particular a return value of -2 indicates the operation is not supported by the
+public key algorithm.
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
+L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
+L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
+L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+
+=head1 HISTORY
+
+This function was first added to OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_PKEY_keygen.pod b/openssl/doc/crypto/EVP_PKEY_keygen.pod
new file mode 100644
index 0000000..37c6fe9
--- /dev/null
+++ b/openssl/doc/crypto/EVP_PKEY_keygen.pod
@@ -0,0 +1,161 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_keygen_init, EVP_PKEY_keygen, EVP_PKEY_paramgen_init, EVP_PKEY_paramgen, EVP_PKEY_CTX_set_cb, EVP_PKEY_CTX_get_cb, EVP_PKEY_CTX_get_keygen_info, EVP_PKEVP_PKEY_CTX_set_app_data, EVP_PKEY_CTX_get_app_data - key and parameter generation functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
+ int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
+ int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
+ int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
+
+ typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
+
+ void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb);
+ EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx);
+
+ int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx);
+
+ void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
+ void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);
+
+=head1 DESCRIPTION
+
+The EVP_PKEY_keygen_init() function initializes a public key algorithm
+context using key B<pkey> for a key genration operation.
+
+The EVP_PKEY_keygen() function performs a key generation operation, the 
+generated key is written to B<ppkey>.
+
+The functions EVP_PKEY_paramgen_init() and EVP_PKEY_paramgen() are similar
+except parameters are generated.
+
+The function EVP_PKEY_set_cb() sets the key or parameter generation callback
+to B<cb>. The function EVP_PKEY_CTX_get_cb() returns the key or parameter
+generation callback.
+
+The function EVP_PKEY_CTX_get_keygen_info() returns parameters associated
+with the generation operation. If B<idx> is -1 the total number of
+parameters available is returned. Any non negative value returns the value of
+that parameter. EVP_PKEY_CTX_gen_keygen_info() with a non-negative value for
+B<idx> should only be called within the generation callback.
+
+If the callback returns 0 then the key genration operation is aborted and an
+error occurs. This might occur during a time consuming operation where
+a user clicks on a "cancel" button.
+
+The functions EVP_PKEY_CTX_set_app_data() and EVP_PKEY_CTX_get_app_data() set
+and retrieve an opaque pointer. This can be used to set some application
+defined value which can be retrieved in the callback: for example a handle
+which is used to update a "progress dialog".
+
+=head1 NOTES
+
+After the call to EVP_PKEY_keygen_init() or EVP_PKEY_paramgen_init() algorithm
+specific control operations can be performed to set any appropriate parameters
+for the operation.
+
+The functions EVP_PKEY_keygen() and EVP_PKEY_paramgen() can be called more than
+once on the same context if several operations are performed using the same
+parameters.
+
+The meaning of the parameters passed to the callback will depend on the
+algorithm and the specifiic implementation of the algorithm. Some might not
+give any useful information at all during key or parameter generation. Others
+might not even call the callback.
+
+The operation performed by key or parameter generation depends on the algorithm
+used. In some cases (e.g. EC with a supplied named curve) the "generation"
+option merely sets the appropriate fields in an EVP_PKEY structure.
+
+In OpenSSL an EVP_PKEY structure containing a private key also contains the
+public key components and parameters (if any). An OpenSSL private key is
+equivalent to what some libraries call a "key pair". A private key can be used
+in functions which require the use of a public key or parameters.
+
+=head1 RETURN VALUES
+
+EVP_PKEY_keygen_init(), EVP_PKEY_paramgen_init(), EVP_PKEY_keygen() and
+EVP_PKEY_paramgen() return 1 for success and 0 or a negative value for failure.
+In particular a return value of -2 indicates the operation is not supported by
+the public key algorithm.
+
+=head1 EXAMPLES
+
+Generate a 2048 bit RSA key:
+
+ #include <openssl/evp.h>
+ #include <openssl/rsa.h>
+
+ EVP_PKEY_CTX *ctx;
+ EVP_PKEY *pkey = NULL;
+ ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
+ if (!ctx)
+	/* Error occurred */
+ if (EVP_PKEY_keygen_init(ctx) <= 0)
+	/* Error */
+ if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0)
+	/* Error */
+
+ /* Generate key */
+ if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
+	/* Error */
+
+Generate a key from a set of parameters:
+
+ #include <openssl/evp.h>
+ #include <openssl/rsa.h>
+
+ EVP_PKEY_CTX *ctx;
+ EVP_PKEY *pkey = NULL, *param;
+ /* Assumed param is set up already */
+ ctx = EVP_PKEY_CTX_new(param);
+ if (!ctx)
+	/* Error occurred */
+ if (EVP_PKEY_keygen_init(ctx) <= 0)
+	/* Error */
+
+ /* Generate key */
+ if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
+	/* Error */
+
+Example of generation callback for OpenSSL public key implementations:
+
+ /* Application data is a BIO to output status to */
+
+ EVP_PKEY_CTX_set_app_data(ctx, status_bio);
+
+ static int genpkey_cb(EVP_PKEY_CTX *ctx)
+	{
+	char c='*';
+	BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
+	int p;
+	p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
+	if (p == 0) c='.';
+	if (p == 1) c='+';
+	if (p == 2) c='*';
+	if (p == 3) c='\n';
+	BIO_write(b,&c,1);
+	(void)BIO_flush(b);
+	return 1;
+	}
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
+L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
+L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
+L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
+L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
+L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
+
+=head1 HISTORY
+
+These functions were first added to OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_PKEY_new.pod b/openssl/doc/crypto/EVP_PKEY_new.pod
new file mode 100644
index 0000000..10687e4
--- /dev/null
+++ b/openssl/doc/crypto/EVP_PKEY_new.pod
@@ -0,0 +1,47 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_new, EVP_PKEY_free - private key allocation functions.
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ EVP_PKEY *EVP_PKEY_new(void);
+ void EVP_PKEY_free(EVP_PKEY *key);
+
+
+=head1 DESCRIPTION
+
+The EVP_PKEY_new() function allocates an empty B<EVP_PKEY> 
+structure which is used by OpenSSL to store private keys.
+
+EVP_PKEY_free() frees up the private key B<key>.
+
+=head1 NOTES
+
+The B<EVP_PKEY> structure is used by various OpenSSL functions
+which require a general private key without reference to any
+particular algorithm.
+
+The structure returned by EVP_PKEY_new() is empty. To add a
+private key to this empty structure the functions described in
+L<EVP_PKEY_set1_RSA(3)|EVP_PKEY_set1_RSA(3)> should be used.
+
+=head1 RETURN VALUES
+
+EVP_PKEY_new() returns either the newly allocated B<EVP_PKEY>
+structure of B<NULL> if an error occurred.
+
+EVP_PKEY_free() does not return a value.
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_set1_RSA(3)|EVP_PKEY_set1_RSA(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/EVP_PKEY_print_private.pod b/openssl/doc/crypto/EVP_PKEY_print_private.pod
new file mode 100644
index 0000000..ce9d70d
--- /dev/null
+++ b/openssl/doc/crypto/EVP_PKEY_print_private.pod
@@ -0,0 +1,53 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_print_public, EVP_PKEY_print_private, EVP_PKEY_print_params - public key algorithm printing routines.
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx);
+ int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx);
+ int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx);
+
+=head1 DESCRIPTION
+
+The functions EVP_PKEY_print_public(), EVP_PKEY_print_private() and
+EVP_PKEY_print_params() print out the public, private or parameter components
+of key B<pkey> respectively. The key is sent to BIO B<out> in human readable
+form. The parameter B<indent> indicated how far the printout should be indented.
+
+The B<pctx> parameter allows the print output to be finely tuned by using
+ASN1 printing options. If B<pctx> is set to NULL then default values will
+be used.
+
+=head1 NOTES
+
+Currently no public key algorithms include any options in the B<pctx> parameter 
+parameter.
+
+If the key does not include all the components indicated by the function then
+only those contained in the key will be printed. For example passing a public
+key to EVP_PKEY_print_private() will only print the public components.
+
+=head1 RETURN VALUES
+
+These functions all return 1 for success and 0 or a negative value for failure.
+In particular a return value of -2 indicates the operation is not supported by
+the public key algorithm.
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
+L<EVP_PKEY_keygen(3)|EVP_PKEY_keygen(3)> 
+
+=head1 HISTORY
+
+These functions were first added to OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_PKEY_set1_RSA.pod b/openssl/doc/crypto/EVP_PKEY_set1_RSA.pod
new file mode 100644
index 0000000..2db692e
--- /dev/null
+++ b/openssl/doc/crypto/EVP_PKEY_set1_RSA.pod
@@ -0,0 +1,80 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_set1_RSA, EVP_PKEY_set1_DSA, EVP_PKEY_set1_DH, EVP_PKEY_set1_EC_KEY,
+EVP_PKEY_get1_RSA, EVP_PKEY_get1_DSA, EVP_PKEY_get1_DH, EVP_PKEY_get1_EC_KEY,
+EVP_PKEY_assign_RSA, EVP_PKEY_assign_DSA, EVP_PKEY_assign_DH, EVP_PKEY_assign_EC_KEY,
+EVP_PKEY_type - EVP_PKEY assignment functions.
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_PKEY_set1_RSA(EVP_PKEY *pkey,RSA *key);
+ int EVP_PKEY_set1_DSA(EVP_PKEY *pkey,DSA *key);
+ int EVP_PKEY_set1_DH(EVP_PKEY *pkey,DH *key);
+ int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey,EC_KEY *key);
+
+ RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey);
+ DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
+ DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
+ EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
+
+ int EVP_PKEY_assign_RSA(EVP_PKEY *pkey,RSA *key);
+ int EVP_PKEY_assign_DSA(EVP_PKEY *pkey,DSA *key);
+ int EVP_PKEY_assign_DH(EVP_PKEY *pkey,DH *key);
+ int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey,EC_KEY *key);
+
+ int EVP_PKEY_type(int type);
+
+=head1 DESCRIPTION
+
+EVP_PKEY_set1_RSA(), EVP_PKEY_set1_DSA(), EVP_PKEY_set1_DH() and
+EVP_PKEY_set1_EC_KEY() set the key referenced by B<pkey> to B<key>.
+
+EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and
+EVP_PKEY_get1_EC_KEY() return the referenced key in B<pkey> or
+B<NULL> if the key is not of the correct type.
+
+EVP_PKEY_assign_RSA() EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
+and EVP_PKEY_assign_EC_KEY() also set the referenced key to B<key>
+however these use the supplied B<key> internally and so B<key>
+will be freed when the parent B<pkey> is freed.
+
+EVP_PKEY_type() returns the type of key corresponding to the value
+B<type>. The type of a key can be obtained with
+EVP_PKEY_type(pkey->type). The return value will be EVP_PKEY_RSA,
+EVP_PKEY_DSA, EVP_PKEY_DH or EVP_PKEY_EC for the corresponding
+key types or NID_undef if the key type is unassigned.
+
+=head1 NOTES
+
+In accordance with the OpenSSL naming convention the key obtained
+from or assigned to the B<pkey> using the B<1> functions must be
+freed as well as B<pkey>.
+
+EVP_PKEY_assign_RSA() EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
+EVP_PKEY_assign_EC_KEY() are implemented as macros.
+
+=head1 RETURN VALUES
+
+EVP_PKEY_set1_RSA(), EVP_PKEY_set1_DSA(), EVP_PKEY_set1_DH() and
+EVP_PKEY_set1_EC_KEY() return 1 for success or 0 for failure.
+
+EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and
+EVP_PKEY_get1_EC_KEY() return the referenced key or B<NULL> if 
+an error occurred.
+
+EVP_PKEY_assign_RSA() EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
+and EVP_PKEY_assign_EC_KEY() return 1 for success and 0 for failure.
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_new(3)|EVP_PKEY_new(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/EVP_PKEY_sign.pod b/openssl/doc/crypto/EVP_PKEY_sign.pod
new file mode 100644
index 0000000..2fb52c3
--- /dev/null
+++ b/openssl/doc/crypto/EVP_PKEY_sign.pod
@@ -0,0 +1,96 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_sign_init, EVP_PKEY_sign - sign using a public key algorithm
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
+ int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
+			unsigned char *sig, size_t *siglen,
+			const unsigned char *tbs, size_t tbslen);
+
+=head1 DESCRIPTION
+
+The EVP_PKEY_sign_init() function initializes a public key algorithm
+context using key B<pkey> for a signing operation.
+
+The EVP_PKEY_sign() function performs a public key signing operation
+using B<ctx>. The data to be signed is specified using the B<tbs> and
+B<tbslen> parameters. If B<sig> is B<NULL> then the maximum size of the output
+buffer is written to the B<siglen> parameter. If B<sig> is not B<NULL> then
+before the call the B<siglen> parameter should contain the length of the
+B<sig> buffer, if the call is successful the signature is written to
+B<sig> and the amount of data written to B<siglen>.
+
+=head1 NOTES
+
+After the call to EVP_PKEY_sign_init() algorithm specific control
+operations can be performed to set any appropriate parameters for the
+operation.
+
+The function EVP_PKEY_sign() can be called more than once on the same
+context if several operations are performed using the same parameters.
+
+=head1 RETURN VALUES
+
+EVP_PKEY_sign_init() and EVP_PKEY_sign() return 1 for success and 0
+or a negative value for failure. In particular a return value of -2
+indicates the operation is not supported by the public key algorithm.
+
+=head1 EXAMPLE
+
+Sign data using RSA with PKCS#1 padding and SHA256 digest:
+
+ #include <openssl/evp.h>
+ #include <openssl/rsa.h>
+
+ EVP_PKEY_CTX *ctx;
+ unsigned char *md, *sig;
+ size_t mdlen, siglen; 
+ EVP_PKEY *signing_key;
+ /* NB: assumes signing_key, md and mdlen are already set up
+  * and that signing_key is an RSA private key
+  */
+ ctx = EVP_PKEY_CTX_new(signing_key);
+ if (!ctx)
+	/* Error occurred */
+ if (EVP_PKEY_sign_init(ctx) <= 0)
+	/* Error */
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
+	/* Error */
+ if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0)
+	/* Error */
+
+ /* Determine buffer length */
+ if (EVP_PKEY_sign(ctx, NULL, &siglen, md, mdlen) <= 0)
+	/* Error */
+
+ sig = OPENSSL_malloc(siglen);
+
+ if (!sig)
+	/* malloc failure */
+ 
+ if (EVP_PKEY_sign(ctx, sig, &siglen, md, mdlen) <= 0)
+	/* Error */
+
+ /* Signature is siglen bytes written to buffer sig */
+
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
+L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
+L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
+L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
+L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
+
+=head1 HISTORY
+
+These functions were first added to OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_PKEY_verify.pod b/openssl/doc/crypto/EVP_PKEY_verify.pod
new file mode 100644
index 0000000..f93e5fc
--- /dev/null
+++ b/openssl/doc/crypto/EVP_PKEY_verify.pod
@@ -0,0 +1,91 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_verify_init, EVP_PKEY_verify - signature verification using a public key algorithm
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
+ int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
+			const unsigned char *sig, size_t siglen,
+			const unsigned char *tbs, size_t tbslen);
+
+=head1 DESCRIPTION
+
+The EVP_PKEY_verify_init() function initializes a public key algorithm
+context using key B<pkey> for a signature verification operation.
+
+The EVP_PKEY_verify() function performs a public key verification operation
+using B<ctx>. The signature is specified using the B<sig> and
+B<siglen> parameters. The verified data (i.e. the data believed originally
+signed) is specified using the B<tbs> and B<tbslen> parameters.
+
+=head1 NOTES
+
+After the call to EVP_PKEY_verify_init() algorithm specific control
+operations can be performed to set any appropriate parameters for the
+operation.
+
+The function EVP_PKEY_verify() can be called more than once on the same
+context if several operations are performed using the same parameters.
+
+=head1 RETURN VALUES
+
+EVP_PKEY_verify_init() and EVP_PKEY_verify() return 1 if the verification was
+successful and 0 if it failed. Unlike other functions the return value 0 from
+EVP_PKEY_verify() only indicates that the signature did not not verify
+successfully (that is tbs did not match the original data or the signature was
+of invalid form) it is not an indication of a more serious error.
+
+A negative value indicates an error other that signature verification failure.
+In particular a return value of -2 indicates the operation is not supported by
+the public key algorithm.
+
+=head1 EXAMPLE
+
+Verify signature using PKCS#1 and SHA256 digest:
+
+ #include <openssl/evp.h>
+ #include <openssl/rsa.h>
+
+ EVP_PKEY_CTX *ctx;
+ unsigned char *md, *sig;
+ size_t mdlen, siglen; 
+ EVP_PKEY *verify_key;
+ /* NB: assumes verify_key, sig, siglen md and mdlen are already set up
+  * and that verify_key is an RSA public key
+  */
+ ctx = EVP_PKEY_CTX_new(verify_key);
+ if (!ctx)
+	/* Error occurred */
+ if (EVP_PKEY_verify_init(ctx) <= 0)
+	/* Error */
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
+	/* Error */
+ if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0)
+	/* Error */
+
+ /* Perform operation */
+ ret = EVP_PKEY_verify(ctx, sig, siglen, md, mdlen);
+
+ /* ret == 1 indicates success, 0 verify failure and < 0 for some
+  * other error.
+  */
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
+L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
+L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
+L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
+L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
+
+=head1 HISTORY
+
+These functions were first added to OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_PKEY_verifyrecover.pod b/openssl/doc/crypto/EVP_PKEY_verifyrecover.pod
new file mode 100644
index 0000000..f3605eb
--- /dev/null
+++ b/openssl/doc/crypto/EVP_PKEY_verifyrecover.pod
@@ -0,0 +1,103 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_verifyrecover_init, EVP_PKEY_verifyrecover - recover signature using a public key algorithm
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_PKEY_verifyrecover_init(EVP_PKEY_CTX *ctx);
+ int EVP_PKEY_verifyrecover(EVP_PKEY_CTX *ctx,
+			unsigned char *rout, size_t *routlen,
+			const unsigned char *sig, size_t siglen);
+
+=head1 DESCRIPTION
+
+The EVP_PKEY_verifyrecover_init() function initializes a public key algorithm
+context using key B<pkey> for a verify recover operation.
+
+The EVP_PKEY_verifyrecover() function recovers signed data
+using B<ctx>. The signature is specified using the B<sig> and
+B<siglen> parameters. If B<rout> is B<NULL> then the maximum size of the output
+buffer is written to the B<routlen> parameter. If B<rout> is not B<NULL> then
+before the call the B<routlen> parameter should contain the length of the
+B<rout> buffer, if the call is successful recovered data is written to
+B<rout> and the amount of data written to B<routlen>.
+
+=head1 NOTES
+
+Normally an application is only interested in whether a signature verification
+operation is successful in those cases the EVP_verify() function should be 
+used.
+
+Sometimes however it is useful to obtain the data originally signed using a
+signing operation. Only certain public key algorithms can recover a signature
+in this way (for example RSA in PKCS padding mode).
+
+After the call to EVP_PKEY_verifyrecover_init() algorithm specific control
+operations can be performed to set any appropriate parameters for the
+operation.
+
+The function EVP_PKEY_verifyrecover() can be called more than once on the same
+context if several operations are performed using the same parameters.
+
+=head1 RETURN VALUES
+
+EVP_PKEY_verifyrecover_init() and EVP_PKEY_verifyrecover() return 1 for success
+and 0 or a negative value for failure. In particular a return value of -2
+indicates the operation is not supported by the public key algorithm.
+
+=head1 EXAMPLE
+
+Recover digest originally signed using PKCS#1 and SHA256 digest:
+
+ #include <openssl/evp.h>
+ #include <openssl/rsa.h>
+
+ EVP_PKEY_CTX *ctx;
+ unsigned char *rout, *sig;
+ size_t routlen, siglen; 
+ EVP_PKEY *verify_key;
+ /* NB: assumes verify_key, sig and siglen are already set up
+  * and that verify_key is an RSA public key
+  */
+ ctx = EVP_PKEY_CTX_new(verify_key);
+ if (!ctx)
+	/* Error occurred */
+ if (EVP_PKEY_verifyrecover_init(ctx) <= 0)
+	/* Error */
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
+	/* Error */
+ if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0)
+	/* Error */
+
+ /* Determine buffer length */
+ if (EVP_PKEY_verifyrecover(ctx, NULL, &routlen, sig, siglen) <= 0)
+	/* Error */
+
+ rout = OPENSSL_malloc(routlen);
+
+ if (!rout)
+	/* malloc failure */
+ 
+ if (EVP_PKEY_verifyrecover(ctx, rout, &routlen, sig, siglen) <= 0)
+	/* Error */
+
+ /* Recovered data is routlen bytes written to buffer rout */
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
+L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
+L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
+L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
+L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
+L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
+
+=head1 HISTORY
+
+These functions were first added to OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_SealInit.pod b/openssl/doc/crypto/EVP_SealInit.pod
new file mode 100644
index 0000000..7d793e1
--- /dev/null
+++ b/openssl/doc/crypto/EVP_SealInit.pod
@@ -0,0 +1,85 @@
+=pod
+
+=head1 NAME
+
+EVP_SealInit, EVP_SealUpdate, EVP_SealFinal - EVP envelope encryption
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+                  unsigned char **ek, int *ekl, unsigned char *iv,
+                  EVP_PKEY **pubk, int npubk);
+ int EVP_SealUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+         int *outl, unsigned char *in, int inl);
+ int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out,
+         int *outl);
+
+=head1 DESCRIPTION
+
+The EVP envelope routines are a high level interface to envelope
+encryption. They generate a random key and IV (if required) then
+"envelope" it by using public key encryption. Data can then be
+encrypted using this key.
+
+EVP_SealInit() initializes a cipher context B<ctx> for encryption
+with cipher B<type> using a random secret key and IV. B<type> is normally
+supplied by a function such as EVP_des_cbc(). The secret key is encrypted
+using one or more public keys, this allows the same encrypted data to be
+decrypted using any of the corresponding private keys. B<ek> is an array of
+buffers where the public key encrypted secret key will be written, each buffer
+must contain enough room for the corresponding encrypted key: that is
+B<ek[i]> must have room for B<EVP_PKEY_size(pubk[i])> bytes. The actual
+size of each encrypted secret key is written to the array B<ekl>. B<pubk> is
+an array of B<npubk> public keys.
+
+The B<iv> parameter is a buffer where the generated IV is written to. It must
+contain enough room for the corresponding cipher's IV, as determined by (for
+example) EVP_CIPHER_iv_length(type).
+
+If the cipher does not require an IV then the B<iv> parameter is ignored
+and can be B<NULL>.
+
+EVP_SealUpdate() and EVP_SealFinal() have exactly the same properties
+as the EVP_EncryptUpdate() and EVP_EncryptFinal() routines, as 
+documented on the L<EVP_EncryptInit(3)|EVP_EncryptInit(3)> manual
+page. 
+
+=head1 RETURN VALUES
+
+EVP_SealInit() returns 0 on error or B<npubk> if successful.
+
+EVP_SealUpdate() and EVP_SealFinal() return 1 for success and 0 for
+failure.
+
+=head1 NOTES
+
+Because a random secret key is generated the random number generator
+must be seeded before calling EVP_SealInit().
+
+The public key must be RSA because it is the only OpenSSL public key
+algorithm that supports key transport.
+
+Envelope encryption is the usual method of using public key encryption
+on large amounts of data, this is because public key encryption is slow
+but symmetric encryption is fast. So symmetric encryption is used for
+bulk encryption and the small random symmetric key used is transferred
+using public key encryption.
+
+It is possible to call EVP_SealInit() twice in the same way as
+EVP_EncryptInit(). The first call should have B<npubk> set to 0
+and (after setting any cipher parameters) it should be called again
+with B<type> set to NULL.
+
+=head1 SEE ALSO
+
+L<evp(3)|evp(3)>, L<rand(3)|rand(3)>,
+L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>,
+L<EVP_OpenInit(3)|EVP_OpenInit(3)>
+
+=head1 HISTORY
+
+EVP_SealFinal() did not return a value before OpenSSL 0.9.7.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_SignInit.pod b/openssl/doc/crypto/EVP_SignInit.pod
new file mode 100644
index 0000000..620a623
--- /dev/null
+++ b/openssl/doc/crypto/EVP_SignInit.pod
@@ -0,0 +1,104 @@
+=pod
+
+=head1 NAME
+
+EVP_SignInit, EVP_SignUpdate, EVP_SignFinal - EVP signing functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_SignInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
+ int EVP_SignUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);
+ int EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *sig,unsigned int *s, EVP_PKEY *pkey);
+
+ void EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type);
+
+ int EVP_PKEY_size(EVP_PKEY *pkey);
+
+=head1 DESCRIPTION
+
+The EVP signature routines are a high level interface to digital
+signatures.
+
+EVP_SignInit_ex() sets up signing context B<ctx> to use digest
+B<type> from ENGINE B<impl>. B<ctx> must be initialized with
+EVP_MD_CTX_init() before calling this function.
+
+EVP_SignUpdate() hashes B<cnt> bytes of data at B<d> into the
+signature context B<ctx>. This function can be called several times on the
+same B<ctx> to include additional data.
+
+EVP_SignFinal() signs the data in B<ctx> using the private key B<pkey> and
+places the signature in B<sig>. The number of bytes of data written (i.e. the
+length of the signature) will be written to the integer at B<s>, at most
+EVP_PKEY_size(pkey) bytes will be written. 
+
+EVP_SignInit() initializes a signing context B<ctx> to use the default
+implementation of digest B<type>.
+
+EVP_PKEY_size() returns the maximum size of a signature in bytes. The actual
+signature returned by EVP_SignFinal() may be smaller.
+
+=head1 RETURN VALUES
+
+EVP_SignInit_ex(), EVP_SignUpdate() and EVP_SignFinal() return 1
+for success and 0 for failure.
+
+EVP_PKEY_size() returns the maximum size of a signature in bytes.
+
+The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 NOTES
+
+The B<EVP> interface to digital signatures should almost always be used in
+preference to the low level interfaces. This is because the code then becomes
+transparent to the algorithm used and much more flexible.
+
+Due to the link between message digests and public key algorithms the correct
+digest algorithm must be used with the correct public key type. A list of
+algorithms and associated public key algorithms appears in 
+L<EVP_DigestInit(3)|EVP_DigestInit(3)>.
+
+When signing with DSA private keys the random number generator must be seeded
+or the operation will fail. The random number generator does not need to be
+seeded for RSA signatures.
+
+The call to EVP_SignFinal() internally finalizes a copy of the digest context.
+This means that calls to EVP_SignUpdate() and EVP_SignFinal() can be called
+later to digest and sign additional data.
+
+Since only a copy of the digest context is ever finalized the context must
+be cleaned up after use by calling EVP_MD_CTX_cleanup() or a memory leak
+will occur.
+
+=head1 BUGS
+
+Older versions of this documentation wrongly stated that calls to 
+EVP_SignUpdate() could not be made after calling EVP_SignFinal().
+
+Since the private key is passed in the call to EVP_SignFinal() any error
+relating to the private key (for example an unsuitable key and digest
+combination) will not be indicated until after potentially large amounts of
+data have been passed through EVP_SignUpdate().
+
+It is not possible to change the signing parameters using these function.
+
+The previous two bugs are fixed in the newer EVP_SignDigest*() function.
+
+=head1 SEE ALSO
+
+L<EVP_VerifyInit(3)|EVP_VerifyInit(3)>,
+L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<err(3)|err(3)>,
+L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>,
+L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>,
+L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)>
+
+=head1 HISTORY
+
+EVP_SignInit(), EVP_SignUpdate() and EVP_SignFinal() are
+available in all versions of SSLeay and OpenSSL.
+
+EVP_SignInit_ex() was added in OpenSSL 0.9.7.
+
+=cut
diff --git a/openssl/doc/crypto/EVP_VerifyInit.pod b/openssl/doc/crypto/EVP_VerifyInit.pod
new file mode 100644
index 0000000..9097f09
--- /dev/null
+++ b/openssl/doc/crypto/EVP_VerifyInit.pod
@@ -0,0 +1,95 @@
+=pod
+
+=head1 NAME
+
+EVP_VerifyInit, EVP_VerifyUpdate, EVP_VerifyFinal - EVP signature verification functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_VerifyInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
+ int EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);
+ int EVP_VerifyFinal(EVP_MD_CTX *ctx,unsigned char *sigbuf, unsigned int siglen,EVP_PKEY *pkey);
+
+ int EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type);
+
+=head1 DESCRIPTION
+
+The EVP signature verification routines are a high level interface to digital
+signatures.
+
+EVP_VerifyInit_ex() sets up verification context B<ctx> to use digest
+B<type> from ENGINE B<impl>. B<ctx> must be initialized by calling
+EVP_MD_CTX_init() before calling this function.
+
+EVP_VerifyUpdate() hashes B<cnt> bytes of data at B<d> into the
+verification context B<ctx>. This function can be called several times on the
+same B<ctx> to include additional data.
+
+EVP_VerifyFinal() verifies the data in B<ctx> using the public key B<pkey>
+and against the B<siglen> bytes at B<sigbuf>.
+
+EVP_VerifyInit() initializes verification context B<ctx> to use the default
+implementation of digest B<type>.
+
+=head1 RETURN VALUES
+
+EVP_VerifyInit_ex() and EVP_VerifyUpdate() return 1 for success and 0 for
+failure.
+
+EVP_VerifyFinal() returns 1 for a correct signature, 0 for failure and -1 if some
+other error occurred.
+
+The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 NOTES
+
+The B<EVP> interface to digital signatures should almost always be used in
+preference to the low level interfaces. This is because the code then becomes
+transparent to the algorithm used and much more flexible.
+
+Due to the link between message digests and public key algorithms the correct
+digest algorithm must be used with the correct public key type. A list of
+algorithms and associated public key algorithms appears in 
+L<EVP_DigestInit(3)|EVP_DigestInit(3)>.
+
+The call to EVP_VerifyFinal() internally finalizes a copy of the digest context.
+This means that calls to EVP_VerifyUpdate() and EVP_VerifyFinal() can be called
+later to digest and verify additional data.
+
+Since only a copy of the digest context is ever finalized the context must
+be cleaned up after use by calling EVP_MD_CTX_cleanup() or a memory leak
+will occur.
+
+=head1 BUGS
+
+Older versions of this documentation wrongly stated that calls to 
+EVP_VerifyUpdate() could not be made after calling EVP_VerifyFinal().
+
+Since the public key is passed in the call to EVP_SignFinal() any error
+relating to the private key (for example an unsuitable key and digest
+combination) will not be indicated until after potentially large amounts of
+data have been passed through EVP_SignUpdate().
+
+It is not possible to change the signing parameters using these function.
+
+The previous two bugs are fixed in the newer EVP_VerifyDigest*() function.
+
+=head1 SEE ALSO
+
+L<evp(3)|evp(3)>,
+L<EVP_SignInit(3)|EVP_SignInit(3)>,
+L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<err(3)|err(3)>,
+L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>,
+L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>,
+L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)>
+
+=head1 HISTORY
+
+EVP_VerifyInit(), EVP_VerifyUpdate() and EVP_VerifyFinal() are
+available in all versions of SSLeay and OpenSSL.
+
+EVP_VerifyInit_ex() was added in OpenSSL 0.9.7
+
+=cut
diff --git a/openssl/doc/crypto/OBJ_nid2obj.pod b/openssl/doc/crypto/OBJ_nid2obj.pod
new file mode 100644
index 0000000..1e45dd4
--- /dev/null
+++ b/openssl/doc/crypto/OBJ_nid2obj.pod
@@ -0,0 +1,151 @@
+=pod
+
+=head1 NAME
+
+OBJ_nid2obj, OBJ_nid2ln, OBJ_nid2sn, OBJ_obj2nid, OBJ_txt2nid, OBJ_ln2nid, OBJ_sn2nid,
+OBJ_cmp, OBJ_dup, OBJ_txt2obj, OBJ_obj2txt, OBJ_create, OBJ_cleanup - ASN1 object utility
+functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/objects.h>
+
+ ASN1_OBJECT * OBJ_nid2obj(int n);
+ const char *  OBJ_nid2ln(int n);
+ const char *  OBJ_nid2sn(int n);
+
+ int OBJ_obj2nid(const ASN1_OBJECT *o);
+ int OBJ_ln2nid(const char *ln);
+ int OBJ_sn2nid(const char *sn);
+
+ int OBJ_txt2nid(const char *s);
+
+ ASN1_OBJECT * OBJ_txt2obj(const char *s, int no_name);
+ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name);
+
+ int OBJ_cmp(const ASN1_OBJECT *a,const ASN1_OBJECT *b);
+ ASN1_OBJECT * OBJ_dup(const ASN1_OBJECT *o);
+
+ int OBJ_create(const char *oid,const char *sn,const char *ln);
+ void OBJ_cleanup(void);
+
+=head1 DESCRIPTION
+
+The ASN1 object utility functions process ASN1_OBJECT structures which are
+a representation of the ASN1 OBJECT IDENTIFIER (OID) type.
+
+OBJ_nid2obj(), OBJ_nid2ln() and OBJ_nid2sn() convert the NID B<n> to 
+an ASN1_OBJECT structure, its long name and its short name respectively,
+or B<NULL> is an error occurred.
+
+OBJ_obj2nid(), OBJ_ln2nid(), OBJ_sn2nid() return the corresponding NID
+for the object B<o>, the long name <ln> or the short name <sn> respectively
+or NID_undef if an error occurred.
+
+OBJ_txt2nid() returns NID corresponding to text string <s>. B<s> can be
+a long name, a short name or the numerical respresentation of an object.
+
+OBJ_txt2obj() converts the text string B<s> into an ASN1_OBJECT structure.
+If B<no_name> is 0 then long names and short names will be interpreted
+as well as numerical forms. If B<no_name> is 1 only the numerical form
+is acceptable.
+
+OBJ_obj2txt() converts the B<ASN1_OBJECT> B<a> into a textual representation.
+The representation is written as a null terminated string to B<buf>
+at most B<buf_len> bytes are written, truncating the result if necessary.
+The total amount of space required is returned. If B<no_name> is 0 then
+if the object has a long or short name then that will be used, otherwise
+the numerical form will be used. If B<no_name> is 1 then the numerical
+form will always be used.
+
+OBJ_cmp() compares B<a> to B<b>. If the two are identical 0 is returned.
+
+OBJ_dup() returns a copy of B<o>.
+
+OBJ_create() adds a new object to the internal table. B<oid> is the 
+numerical form of the object, B<sn> the short name and B<ln> the
+long name. A new NID is returned for the created object.
+
+OBJ_cleanup() cleans up OpenSSLs internal object table: this should
+be called before an application exits if any new objects were added
+using OBJ_create().
+
+=head1 NOTES
+
+Objects in OpenSSL can have a short name, a long name and a numerical
+identifier (NID) associated with them. A standard set of objects is
+represented in an internal table. The appropriate values are defined
+in the header file B<objects.h>.
+
+For example the OID for commonName has the following definitions:
+
+ #define SN_commonName                   "CN"
+ #define LN_commonName                   "commonName"
+ #define NID_commonName                  13
+
+New objects can be added by calling OBJ_create().
+
+Table objects have certain advantages over other objects: for example
+their NIDs can be used in a C language switch statement. They are
+also static constant structures which are shared: that is there
+is only a single constant structure for each table object.
+
+Objects which are not in the table have the NID value NID_undef.
+
+Objects do not need to be in the internal tables to be processed,
+the functions OBJ_txt2obj() and OBJ_obj2txt() can process the numerical
+form of an OID.
+
+=head1 EXAMPLES
+
+Create an object for B<commonName>:
+
+ ASN1_OBJECT *o;
+ o = OBJ_nid2obj(NID_commonName);
+
+Check if an object is B<commonName>
+
+ if (OBJ_obj2nid(obj) == NID_commonName)
+	/* Do something */
+
+Create a new NID and initialize an object from it:
+
+ int new_nid;
+ ASN1_OBJECT *obj;
+ new_nid = OBJ_create("1.2.3.4", "NewOID", "New Object Identifier");
+
+ obj = OBJ_nid2obj(new_nid);
+ 
+Create a new object directly:
+
+ obj = OBJ_txt2obj("1.2.3.4", 1);
+
+=head1 BUGS
+
+OBJ_obj2txt() is awkward and messy to use: it doesn't follow the 
+convention of other OpenSSL functions where the buffer can be set
+to B<NULL> to determine the amount of data that should be written.
+Instead B<buf> must point to a valid buffer and B<buf_len> should
+be set to a positive value. A buffer length of 80 should be more
+than enough to handle any OID encountered in practice.
+
+=head1 RETURN VALUES
+
+OBJ_nid2obj() returns an B<ASN1_OBJECT> structure or B<NULL> is an
+error occurred.
+
+OBJ_nid2ln() and OBJ_nid2sn() returns a valid string or B<NULL>
+on error.
+
+OBJ_obj2nid(), OBJ_ln2nid(), OBJ_sn2nid() and OBJ_txt2nid() return
+a NID or B<NID_undef> on error.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/OPENSSL_Applink.pod b/openssl/doc/crypto/OPENSSL_Applink.pod
new file mode 100644
index 0000000..e54de12
--- /dev/null
+++ b/openssl/doc/crypto/OPENSSL_Applink.pod
@@ -0,0 +1,21 @@
+=pod
+
+=head1 NAME
+
+OPENSSL_Applink - glue between OpenSSL BIO and Win32 compiler run-time
+
+=head1 SYNOPSIS
+
+ __declspec(dllexport) void **OPENSSL_Applink();
+
+=head1 DESCRIPTION
+
+OPENSSL_Applink is application-side interface which provides a glue
+between OpenSSL BIO layer and Win32 compiler run-time environment.
+Even though it appears at application side, it's essentially OpenSSL
+private interface. For this reason application developers are not
+expected to implement it, but to compile provided module with
+compiler of their choice and link it into the target application.
+The referred module is available as <openssl>/ms/applink.c.
+
+=cut
diff --git a/openssl/doc/crypto/OPENSSL_VERSION_NUMBER.pod b/openssl/doc/crypto/OPENSSL_VERSION_NUMBER.pod
new file mode 100644
index 0000000..c39ac35
--- /dev/null
+++ b/openssl/doc/crypto/OPENSSL_VERSION_NUMBER.pod
@@ -0,0 +1,101 @@
+=pod
+
+=head1 NAME
+
+OPENSSL_VERSION_NUMBER, SSLeay, SSLeay_version - get OpenSSL version number
+
+=head1 SYNOPSIS
+
+ #include <openssl/opensslv.h>
+ #define OPENSSL_VERSION_NUMBER 0xnnnnnnnnnL
+
+ #include <openssl/crypto.h>
+ long SSLeay(void);
+ const char *SSLeay_version(int t);
+
+=head1 DESCRIPTION
+
+OPENSSL_VERSION_NUMBER is a numeric release version identifier:
+
+ MMNNFFPPS: major minor fix patch status
+
+The status nibble has one of the values 0 for development, 1 to e for betas
+1 to 14, and f for release.
+
+for example
+
+ 0x000906000 == 0.9.6 dev
+ 0x000906023 == 0.9.6b beta 3
+ 0x00090605f == 0.9.6e release
+
+Versions prior to 0.9.3 have identifiers E<lt> 0x0930.
+Versions between 0.9.3 and 0.9.5 had a version identifier with this
+interpretation:
+
+ MMNNFFRBB major minor fix final beta/patch
+
+for example
+
+ 0x000904100 == 0.9.4 release
+ 0x000905000 == 0.9.5 dev
+
+Version 0.9.5a had an interim interpretation that is like the current one,
+except the patch level got the highest bit set, to keep continuity.  The
+number was therefore 0x0090581f.
+
+
+For backward compatibility, SSLEAY_VERSION_NUMBER is also defined.
+
+SSLeay() returns this number. The return value can be compared to the
+macro to make sure that the correct version of the library has been
+loaded, especially when using DLLs on Windows systems.
+
+SSLeay_version() returns different strings depending on B<t>:
+
+=over 4
+
+=item SSLEAY_VERSION
+
+The text variant of the version number and the release date.  For example,
+"OpenSSL 0.9.5a 1 Apr 2000".
+
+=item SSLEAY_CFLAGS
+
+The compiler flags set for the compilation process in the form
+"compiler: ..."  if available or "compiler: information not available"
+otherwise.
+
+=item SSLEAY_BUILT_ON
+
+The date of the build process in the form "built on: ..." if available
+or "built on: date not available" otherwise.
+
+=item SSLEAY_PLATFORM
+
+The "Configure" target of the library build in the form "platform: ..."
+if available or "platform: information not available" otherwise.
+
+=item SSLEAY_DIR
+
+The "OPENSSLDIR" setting of the library build in the form "OPENSSLDIR: "...""
+if available or "OPENSSLDIR: N/A" otherwise.
+
+=back
+
+For an unknown B<t>, the text "not available" is returned.
+
+=head1 RETURN VALUE
+
+The version number.
+
+=head1 SEE ALSO
+
+L<crypto(3)|crypto(3)>
+
+=head1 HISTORY
+
+SSLeay() and SSLEAY_VERSION_NUMBER are available in all versions of SSLeay and OpenSSL.
+OPENSSL_VERSION_NUMBER is available in all versions of OpenSSL.
+B<SSLEAY_DIR> was added in OpenSSL 0.9.7.
+
+=cut
diff --git a/openssl/doc/crypto/OPENSSL_config.pod b/openssl/doc/crypto/OPENSSL_config.pod
new file mode 100644
index 0000000..e7bba2a
--- /dev/null
+++ b/openssl/doc/crypto/OPENSSL_config.pod
@@ -0,0 +1,82 @@
+=pod
+
+=head1 NAME
+
+OPENSSL_config, OPENSSL_no_config - simple OpenSSL configuration functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/conf.h>
+
+ void OPENSSL_config(const char *config_name);
+ void OPENSSL_no_config(void);
+
+=head1 DESCRIPTION
+
+OPENSSL_config() configures OpenSSL using the standard B<openssl.cnf>
+configuration file name using B<config_name>. If B<config_name> is NULL then
+the default name B<openssl_conf> will be used. Any errors are ignored. Further
+calls to OPENSSL_config() will have no effect. The configuration file format
+is documented in the L<conf(5)|conf(5)> manual page.
+
+OPENSSL_no_config() disables configuration. If called before OPENSSL_config()
+no configuration takes place.
+
+=head1 NOTES
+
+It is B<strongly> recommended that B<all> new applications call OPENSSL_config()
+or the more sophisticated functions such as CONF_modules_load() during
+initialization (that is before starting any threads). By doing this
+an application does not need to keep track of all configuration options
+and some new functionality can be supported automatically.
+
+It is also possible to automatically call OPENSSL_config() when an application
+calls OPENSSL_add_all_algorithms() by compiling an application with the
+preprocessor symbol B<OPENSSL_LOAD_CONF> #define'd. In this way configuration
+can be added without source changes.
+
+The environment variable B<OPENSSL_CONF> can be set to specify the location
+of the configuration file.
+ 
+Currently ASN1 OBJECTs and ENGINE configuration can be performed future
+versions of OpenSSL will add new configuration options.
+
+There are several reasons why calling the OpenSSL configuration routines is
+advisable. For example new ENGINE functionality was added to OpenSSL 0.9.7.
+In OpenSSL 0.9.7 control functions can be supported by ENGINEs, this can be
+used (among other things) to load dynamic ENGINEs from shared libraries (DSOs).
+However very few applications currently support the control interface and so
+very few can load and use dynamic ENGINEs. Equally in future more sophisticated
+ENGINEs will require certain control operations to customize them. If an
+application calls OPENSSL_config() it doesn't need to know or care about
+ENGINE control operations because they can be performed by editing a
+configuration file.
+
+Applications should free up configuration at application closedown by calling
+CONF_modules_free().
+
+=head1 RESTRICTIONS
+
+The OPENSSL_config() function is designed to be a very simple "call it and
+forget it" function. As a result its behaviour is somewhat limited. It ignores
+all errors silently and it can only load from the standard configuration file
+location for example.
+
+It is however B<much> better than nothing. Applications which need finer
+control over their configuration functionality should use the configuration
+functions such as CONF_load_modules() directly.
+
+=head1 RETURN VALUES
+
+Neither OPENSSL_config() nor OPENSSL_no_config() return a value.
+
+=head1 SEE ALSO
+
+L<conf(5)|conf(5)>, L<CONF_load_modules_file(3)|CONF_load_modules_file(3)>,
+L<CONF_modules_free(3),CONF_modules_free(3)>
+
+=head1 HISTORY
+
+OPENSSL_config() and OPENSSL_no_config() first appeared in OpenSSL 0.9.7
+
+=cut
diff --git a/openssl/doc/crypto/OPENSSL_ia32cap.pod b/openssl/doc/crypto/OPENSSL_ia32cap.pod
new file mode 100644
index 0000000..2e659d3
--- /dev/null
+++ b/openssl/doc/crypto/OPENSSL_ia32cap.pod
@@ -0,0 +1,43 @@
+=pod
+
+=head1 NAME
+
+OPENSSL_ia32cap - finding the IA-32 processor capabilities
+
+=head1 SYNOPSIS
+
+ unsigned long *OPENSSL_ia32cap_loc(void);
+ #define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc()))
+
+=head1 DESCRIPTION
+
+Value returned by OPENSSL_ia32cap_loc() is address of a variable
+containing IA-32 processor capabilities bit vector as it appears in EDX
+register after executing CPUID instruction with EAX=1 input value (see
+Intel Application Note #241618). Naturally it's meaningful on IA-32[E]
+platforms only. The variable is normally set up automatically upon
+toolkit initialization, but can be manipulated afterwards to modify
+crypto library behaviour. For the moment of this writing six bits are
+significant, namely:
+
+1. bit #28 denoting Hyperthreading, which is used to distiguish
+   cores with shared cache;
+2. bit #26 denoting SSE2 support;
+3. bit #25 denoting SSE support;
+4. bit #23 denoting MMX support;
+5. bit #20, reserved by Intel, is used to choose between RC4 code
+   pathes;
+6. bit #4 denoting presence of Time-Stamp Counter.
+
+For example, clearing bit #26 at run-time disables high-performance
+SSE2 code present in the crypto library. You might have to do this if
+target OpenSSL application is executed on SSE2 capable CPU, but under
+control of OS which does not support SSE2 extentions. Even though you
+can manipulate the value programmatically, you most likely will find it
+more appropriate to set up an environment variable with the same name
+prior starting target application, e.g. on Intel P4 processor 'env
+OPENSSL_ia32cap=0x12900010 apps/openssl', to achieve same effect
+without modifying the application source code. Alternatively you can
+reconfigure the toolkit with no-sse2 option and recompile.
+
+=cut
diff --git a/openssl/doc/crypto/OPENSSL_load_builtin_modules.pod b/openssl/doc/crypto/OPENSSL_load_builtin_modules.pod
new file mode 100644
index 0000000..f14dfaf
--- /dev/null
+++ b/openssl/doc/crypto/OPENSSL_load_builtin_modules.pod
@@ -0,0 +1,51 @@
+=pod
+
+=head1 NAME
+
+OPENSSL_load_builtin_modules - add standard configuration modules
+
+=head1 SYNOPSIS
+
+ #include <openssl/conf.h>
+
+ void OPENSSL_load_builtin_modules(void);
+ void ASN1_add_oid_module(void);
+ ENGINE_add_conf_module();
+
+=head1 DESCRIPTION
+
+The function OPENSSL_load_builtin_modules() adds all the standard OpenSSL
+configuration modules to the internal list. They can then be used by the
+OpenSSL configuration code.
+
+ASN1_add_oid_module() adds just the ASN1 OBJECT module.
+
+ENGINE_add_conf_module() adds just the ENGINE configuration module.
+
+=head1 NOTES
+
+If the simple configuration function OPENSSL_config() is called then 
+OPENSSL_load_builtin_modules() is called automatically.
+
+Applications which use the configuration functions directly will need to
+call OPENSSL_load_builtin_modules() themselves I<before> any other 
+configuration code.
+
+Applications should call OPENSSL_load_builtin_modules() to load all
+configuration modules instead of adding modules selectively: otherwise 
+functionality may be missing from the application if an when new
+modules are added.
+
+=head1 RETURN VALUE
+
+None of the functions return a value.
+
+=head1 SEE ALSO
+
+L<conf(3)|conf(3)>, L<OPENSSL_config(3)|OPENSSL_config(3)>
+
+=head1 HISTORY
+
+These functions first appeared in OpenSSL 0.9.7.
+
+=cut
diff --git a/openssl/doc/crypto/OpenSSL_add_all_algorithms.pod b/openssl/doc/crypto/OpenSSL_add_all_algorithms.pod
new file mode 100644
index 0000000..e63411b
--- /dev/null
+++ b/openssl/doc/crypto/OpenSSL_add_all_algorithms.pod
@@ -0,0 +1,66 @@
+=pod
+
+=head1 NAME
+
+OpenSSL_add_all_algorithms, OpenSSL_add_all_ciphers, OpenSSL_add_all_digests -
+add algorithms to internal table
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ void OpenSSL_add_all_algorithms(void);
+ void OpenSSL_add_all_ciphers(void);
+ void OpenSSL_add_all_digests(void);
+
+ void EVP_cleanup(void);
+
+=head1 DESCRIPTION
+
+OpenSSL keeps an internal table of digest algorithms and ciphers. It uses
+this table to lookup ciphers via functions such as EVP_get_cipher_byname().
+
+OpenSSL_add_all_digests() adds all digest algorithms to the table.
+
+OpenSSL_add_all_algorithms() adds all algorithms to the table (digests and
+ciphers).
+
+OpenSSL_add_all_ciphers() adds all encryption algorithms to the table including
+password based encryption algorithms.
+
+EVP_cleanup() removes all ciphers and digests from the table.
+
+=head1 RETURN VALUES
+
+None of the functions return a value.
+
+=head1 NOTES
+
+A typical application will call OpenSSL_add_all_algorithms() initially and
+EVP_cleanup() before exiting.
+
+An application does not need to add algorithms to use them explicitly, for example
+by EVP_sha1(). It just needs to add them if it (or any of the functions it calls)
+needs to lookup algorithms.
+
+The cipher and digest lookup functions are used in many parts of the library. If
+the table is not initialized several functions will misbehave and complain they
+cannot find algorithms. This includes the PEM, PKCS#12, SSL and S/MIME libraries.
+This is a common query in the OpenSSL mailing lists.
+
+Calling OpenSSL_add_all_algorithms() links in all algorithms: as a result a
+statically linked executable can be quite large. If this is important it is possible
+to just add the required ciphers and digests.
+
+=head1 BUGS
+
+Although the functions do not return error codes it is possible for them to fail.
+This will only happen as a result of a memory allocation failure so this is not
+too much of a problem in practice.
+
+=head1 SEE ALSO
+
+L<evp(3)|evp(3)>, L<EVP_DigestInit(3)|EVP_DigestInit(3)>,
+L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>
+
+=cut
diff --git a/openssl/doc/crypto/PEM_write_bio_CMS_stream.pod b/openssl/doc/crypto/PEM_write_bio_CMS_stream.pod
new file mode 100644
index 0000000..e070c45
--- /dev/null
+++ b/openssl/doc/crypto/PEM_write_bio_CMS_stream.pod
@@ -0,0 +1,41 @@
+=pod
+
+=head1 NAME
+
+ PEM_write_bio_CMS_stream - output CMS_ContentInfo structure in PEM format.
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+ #include <openssl/pem.h>
+
+ int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *data, int flags);
+
+=head1 DESCRIPTION
+
+PEM_write_bio_CMS_stream() outputs a CMS_ContentInfo structure in PEM format.
+
+It is otherwise identical to the function SMIME_write_CMS().
+
+=head1 NOTES
+
+This function is effectively a version of the PEM_write_bio_CMS() supporting
+streaming.
+
+=head1 RETURN VALUES
+
+PEM_write_bio_CMS_stream() returns 1 for success or 0 for failure.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
+L<CMS_verify(3)|CMS_verify(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)>
+L<CMS_decrypt(3)|CMS_decrypt(3)>,
+L<SMIME_write_CMS(3)|SMIME_write_CMS(3)>,
+L<i2d_CMS_bio_stream(3)|i2d_CMS_bio_stream(3)>
+
+=head1 HISTORY
+
+PEM_write_bio_CMS_stream() was added to OpenSSL 1.0.0
+
+=cut
diff --git a/openssl/doc/crypto/PEM_write_bio_PKCS7_stream.pod b/openssl/doc/crypto/PEM_write_bio_PKCS7_stream.pod
new file mode 100644
index 0000000..16fc9b6
--- /dev/null
+++ b/openssl/doc/crypto/PEM_write_bio_PKCS7_stream.pod
@@ -0,0 +1,41 @@
+=pod
+
+=head1 NAME
+
+PEM_write_bio_PKCS7_stream - output PKCS7 structure in PEM format.
+
+=head1 SYNOPSIS
+
+ #include <openssl/pkcs7.h>
+ #include <openssl/pem.h>
+
+ int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *data, int flags);
+
+=head1 DESCRIPTION
+
+PEM_write_bio_PKCS7_stream() outputs a PKCS7 structure in PEM format.
+
+It is otherwise identical to the function SMIME_write_PKCS7().
+
+=head1 NOTES
+
+This function is effectively a version of the PEM_write_bio_PKCS7() supporting
+streaming.
+
+=head1 RETURN VALUES
+
+PEM_write_bio_PKCS7_stream() returns 1 for success or 0 for failure.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>,
+L<PKCS7_verify(3)|PKCS7_verify(3)>, L<PKCS7_encrypt(3)|PKCS7_encrypt(3)>
+L<PKCS7_decrypt(3)|PKCS7_decrypt(3)>,
+L<SMIME_write_PKCS7(3)|SMIME_write_PKCS7(3)>,
+L<i2d_PKCS7_bio_stream(3)|i2d_PKCS7_bio_stream(3)>
+
+=head1 HISTORY
+
+PEM_write_bio_PKCS7_stream() was added to OpenSSL 1.0.0
+
+=cut
diff --git a/openssl/doc/crypto/PKCS12_create.pod b/openssl/doc/crypto/PKCS12_create.pod
new file mode 100644
index 0000000..de7cab2
--- /dev/null
+++ b/openssl/doc/crypto/PKCS12_create.pod
@@ -0,0 +1,75 @@
+=pod
+
+=head1 NAME
+
+PKCS12_create - create a PKCS#12 structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/pkcs12.h>
+
+ PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, STACK_OF(X509) *ca,
+				int nid_key, int nid_cert, int iter, int mac_iter, int keytype);
+
+=head1 DESCRIPTION
+
+PKCS12_create() creates a PKCS#12 structure.
+
+B<pass> is the passphrase to use. B<name> is the B<friendlyName> to use for
+the supplied certifictate and key. B<pkey> is the private key to include in
+the structure and B<cert> its corresponding certificates. B<ca>, if not B<NULL>
+is an optional set of certificates to also include in the structure.
+
+B<nid_key> and B<nid_cert> are the encryption algorithms that should be used
+for the key and certificate respectively. B<iter> is the encryption algorithm
+iteration count to use and B<mac_iter> is the MAC iteration count to use.
+B<keytype> is the type of key.
+
+=head1 NOTES
+
+The parameters B<nid_key>, B<nid_cert>, B<iter>, B<mac_iter> and B<keytype>
+can all be set to zero and sensible defaults will be used.
+
+These defaults are: 40 bit RC2 encryption for certificates, triple DES
+encryption for private keys, a key iteration count of PKCS12_DEFAULT_ITER
+(currently 2048) and a MAC iteration count of 1.
+
+The default MAC iteration count is 1 in order to retain compatibility with
+old software which did not interpret MAC iteration counts. If such compatibility
+is not required then B<mac_iter> should be set to PKCS12_DEFAULT_ITER.
+
+B<keytype> adds a flag to the store private key. This is a non standard extension
+that is only currently interpreted by MSIE. If set to zero the flag is omitted,
+if set to B<KEY_SIG> the key can be used for signing only, if set to B<KEY_EX>
+it can be used for signing and encryption. This option was useful for old
+export grade software which could use signing only keys of arbitrary size but
+had restrictions on the permissible sizes of keys which could be used for
+encryption.
+
+=head1 NEW FUNCTIONALITY IN OPENSSL 0.9.8
+
+Some additional functionality was added to PKCS12_create() in OpenSSL
+0.9.8. These extensions are detailed below.
+
+If a certificate contains an B<alias> or B<keyid> then this will be
+used for the corresponding B<friendlyName> or B<localKeyID> in the
+PKCS12 structure.
+
+Either B<pkey>, B<cert> or both can be B<NULL> to indicate that no key or
+certficate is required. In previous versions both had to be present or
+a fatal error is returned.
+
+B<nid_key> or B<nid_cert> can be set to -1 indicating that no encryption
+should be used. 
+
+B<mac_iter> can be set to -1 and the MAC will then be omitted entirely.
+
+=head1 SEE ALSO
+
+L<d2i_PKCS12(3)|d2i_PKCS12(3)>
+
+=head1 HISTORY
+
+PKCS12_create was added in OpenSSL 0.9.3
+
+=cut
diff --git a/openssl/doc/crypto/PKCS12_parse.pod b/openssl/doc/crypto/PKCS12_parse.pod
new file mode 100644
index 0000000..c54cf2a
--- /dev/null
+++ b/openssl/doc/crypto/PKCS12_parse.pod
@@ -0,0 +1,57 @@
+=pod
+
+=head1 NAME
+
+PKCS12_parse - parse a PKCS#12 structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/pkcs12.h>
+
+int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca);
+
+=head1 DESCRIPTION
+
+PKCS12_parse() parses a PKCS12 structure.
+
+B<p12> is the B<PKCS12> structure to parse. B<pass> is the passphrase to use.
+If successful the private key will be written to B<*pkey>, the corresponding
+certificate to B<*cert> and any additional certificates to B<*ca>.
+
+=head1 NOTES
+
+The parameters B<pkey> and B<cert> cannot be B<NULL>. B<ca> can be <NULL> in
+which case additional certificates will be discarded. B<*ca> can also be a
+valid STACK in which case additional certificates are appended to B<*ca>. If
+B<*ca> is B<NULL> a new STACK will be allocated.
+
+The B<friendlyName> and B<localKeyID> attributes (if present) on each
+certificate will be stored in the B<alias> and B<keyid> attributes of the
+B<X509> structure.
+
+=head1 RETURN VALUES
+
+PKCS12_parse() returns 1 for success and zero if an error occurred.
+
+The error can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>
+
+=head1 BUGS
+
+Only a single private key and corresponding certificate is returned by this
+function. More complex PKCS#12 files with multiple private keys will only
+return the first match.
+
+Only B<friendlyName> and B<localKeyID> attributes are currently stored in
+certificates. Other attributes are discarded.
+
+Attributes currently cannot be stored in the private key B<EVP_PKEY> structure.
+
+=head1 SEE ALSO
+
+L<d2i_PKCS12(3)|d2i_PKCS12(3)>
+
+=head1 HISTORY
+
+PKCS12_parse was added in OpenSSL 0.9.3
+
+=cut
diff --git a/openssl/doc/crypto/PKCS7_decrypt.pod b/openssl/doc/crypto/PKCS7_decrypt.pod
new file mode 100644
index 0000000..325699d
--- /dev/null
+++ b/openssl/doc/crypto/PKCS7_decrypt.pod
@@ -0,0 +1,55 @@
+=pod
+
+=head1 NAME
+
+PKCS7_decrypt - decrypt content from a PKCS#7 envelopedData structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/pkcs7.h>
+
+ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags);
+
+=head1 DESCRIPTION
+
+PKCS7_decrypt() extracts and decrypts the content from a PKCS#7 envelopedData
+structure. B<pkey> is the private key of the recipient, B<cert> is the
+recipients certificate, B<data> is a BIO to write the content to and
+B<flags> is an optional set of flags.
+
+=head1 NOTES
+
+OpenSSL_add_all_algorithms() (or equivalent) should be called before using this
+function or errors about unknown algorithms will occur.
+
+Although the recipients certificate is not needed to decrypt the data it is needed
+to locate the appropriate (of possible several) recipients in the PKCS#7 structure.
+
+The following flags can be passed in the B<flags> parameter.
+
+If the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> are deleted
+from the content. If the content is not of type B<text/plain> then an error is
+returned.
+
+=head1 RETURN VALUES
+
+PKCS7_decrypt() returns either 1 for success or 0 for failure.
+The error can be obtained from ERR_get_error(3)
+
+=head1 BUGS
+
+PKCS7_decrypt() must be passed the correct recipient key and certificate. It would
+be better if it could look up the correct key and certificate from a database.
+
+The lack of single pass processing and need to hold all data in memory as
+mentioned in PKCS7_sign() also applies to PKCS7_verify().
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_encrypt(3)|PKCS7_encrypt(3)>
+
+=head1 HISTORY
+
+PKCS7_decrypt() was added to OpenSSL 0.9.5
+
+=cut
diff --git a/openssl/doc/crypto/PKCS7_encrypt.pod b/openssl/doc/crypto/PKCS7_encrypt.pod
new file mode 100644
index 0000000..2cd925a
--- /dev/null
+++ b/openssl/doc/crypto/PKCS7_encrypt.pod
@@ -0,0 +1,80 @@
+=pod
+
+=head1 NAME
+
+PKCS7_encrypt - create a PKCS#7 envelopedData structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/pkcs7.h>
+
+ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, int flags);
+
+=head1 DESCRIPTION
+
+PKCS7_encrypt() creates and returns a PKCS#7 envelopedData structure. B<certs>
+is a list of recipient certificates. B<in> is the content to be encrypted.
+B<cipher> is the symmetric cipher to use. B<flags> is an optional set of flags.
+
+=head1 NOTES
+
+Only RSA keys are supported in PKCS#7 and envelopedData so the recipient
+certificates supplied to this function must all contain RSA public keys, though
+they do not have to be signed using the RSA algorithm.
+
+EVP_des_ede3_cbc() (triple DES) is the algorithm of choice for S/MIME use
+because most clients will support it.
+
+Some old "export grade" clients may only support weak encryption using 40 or 64
+bit RC2. These can be used by passing EVP_rc2_40_cbc() and EVP_rc2_64_cbc()
+respectively.
+
+The algorithm passed in the B<cipher> parameter must support ASN1 encoding of
+its parameters. 
+
+Many browsers implement a "sign and encrypt" option which is simply an S/MIME
+envelopedData containing an S/MIME signed message. This can be readily produced
+by storing the S/MIME signed message in a memory BIO and passing it to
+PKCS7_encrypt().
+
+The following flags can be passed in the B<flags> parameter.
+
+If the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> are
+prepended to the data.
+
+Normally the supplied content is translated into MIME canonical format (as
+required by the S/MIME specifications) if B<PKCS7_BINARY> is set no translation
+occurs. This option should be used if the supplied data is in binary format
+otherwise the translation will corrupt it. If B<PKCS7_BINARY> is set then
+B<PKCS7_TEXT> is ignored.
+
+If the B<PKCS7_STREAM> flag is set a partial B<PKCS7> structure is output
+suitable for streaming I/O: no data is read from the BIO B<in>.
+
+=head1 NOTES
+
+If the flag B<PKCS7_STREAM> is set the returned B<PKCS7> structure is B<not>
+complete and outputting its contents via a function that does not
+properly finalize the B<PKCS7> structure will give unpredictable 
+results.
+
+Several functions including SMIME_write_PKCS7(), i2d_PKCS7_bio_stream(),
+PEM_write_bio_PKCS7_stream() finalize the structure. Alternatively finalization
+can be performed by obtaining the streaming ASN1 B<BIO> directly using
+BIO_new_PKCS7().
+
+=head1 RETURN VALUES
+
+PKCS7_encrypt() returns either a PKCS7 structure or NULL if an error occurred.
+The error can be obtained from ERR_get_error(3).
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_decrypt(3)|PKCS7_decrypt(3)>
+
+=head1 HISTORY
+
+PKCS7_decrypt() was added to OpenSSL 0.9.5
+The B<PKCS7_STREAM> flag was first supported in OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/PKCS7_sign.pod b/openssl/doc/crypto/PKCS7_sign.pod
new file mode 100644
index 0000000..64a3514
--- /dev/null
+++ b/openssl/doc/crypto/PKCS7_sign.pod
@@ -0,0 +1,116 @@
+=pod
+
+=head1 NAME
+
+PKCS7_sign - create a PKCS#7 signedData structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/pkcs7.h>
+
+ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, int flags);
+
+=head1 DESCRIPTION
+
+PKCS7_sign() creates and returns a PKCS#7 signedData structure. B<signcert> is
+the certificate to sign with, B<pkey> is the corresponsding private key.
+B<certs> is an optional additional set of certificates to include in the PKCS#7
+structure (for example any intermediate CAs in the chain). 
+
+The data to be signed is read from BIO B<data>.
+
+B<flags> is an optional set of flags.
+
+=head1 NOTES
+
+Any of the following flags (ored together) can be passed in the B<flags>
+parameter.
+
+Many S/MIME clients expect the signed content to include valid MIME headers. If
+the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> are prepended
+to the data.
+
+If B<PKCS7_NOCERTS> is set the signer's certificate will not be included in the
+PKCS7 structure, the signer's certificate must still be supplied in the
+B<signcert> parameter though. This can reduce the size of the signature if the
+signers certificate can be obtained by other means: for example a previously
+signed message.
+
+The data being signed is included in the PKCS7 structure, unless
+B<PKCS7_DETACHED> is set in which case it is omitted. This is used for PKCS7
+detached signatures which are used in S/MIME plaintext signed messages for
+example.
+
+Normally the supplied content is translated into MIME canonical format (as
+required by the S/MIME specifications) if B<PKCS7_BINARY> is set no translation
+occurs. This option should be used if the supplied data is in binary format
+otherwise the translation will corrupt it.
+
+The signedData structure includes several PKCS#7 autenticatedAttributes
+including the signing time, the PKCS#7 content type and the supported list of
+ciphers in an SMIMECapabilities attribute. If B<PKCS7_NOATTR> is set then no
+authenticatedAttributes will be used. If B<PKCS7_NOSMIMECAP> is set then just
+the SMIMECapabilities are omitted.
+
+If present the SMIMECapabilities attribute indicates support for the following
+algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any of
+these algorithms is disabled then it will not be included.
+
+If the flags B<PKCS7_STREAM> is set then the returned B<PKCS7> structure is
+just initialized ready to perform the signing operation. The signing is however
+B<not> performed and the data to be signed is not read from the B<data>
+parameter. Signing is deferred until after the data has been written. In this
+way data can be signed in a single pass.
+
+If the B<PKCS7_PARTIAL> flag is set a partial B<PKCS7> structure is output to
+which additional signers and capabilities can be added before finalization.
+
+
+=head1 NOTES
+
+If the flag B<PKCS7_STREAM> is set the returned B<PKCS7> structure is B<not>
+complete and outputting its contents via a function that does not properly
+finalize the B<PKCS7> structure will give unpredictable results.
+
+Several functions including SMIME_write_PKCS7(), i2d_PKCS7_bio_stream(),
+PEM_write_bio_PKCS7_stream() finalize the structure. Alternatively finalization
+can be performed by obtaining the streaming ASN1 B<BIO> directly using
+BIO_new_PKCS7().
+
+If a signer is specified it will use the default digest for the signing
+algorithm. This is B<SHA1> for both RSA and DSA keys.
+
+In OpenSSL 1.0.0 the B<certs>, B<signcert> and B<pkey> parameters can all be
+B<NULL> if the B<PKCS7_PARTIAL> flag is set. One or more signers can be added
+using the function B<PKCS7_sign_add_signer()>. B<PKCS7_final()> must also be
+called to finalize the structure if streaming is not enabled. Alternative
+signing digests can also be specified using this method.
+
+In OpenSSL 1.0.0 if B<signcert> and B<pkey> are NULL then a certificates only
+PKCS#7 structure is output.
+
+In versions of OpenSSL before 1.0.0 the B<signcert> and B<pkey> parameters must
+B<NOT> be NULL.
+
+=head1 BUGS
+
+Some advanced attributes such as counter signatures are not supported.
+
+=head1 RETURN VALUES
+
+PKCS7_sign() returns either a valid PKCS7 structure or NULL if an error
+occurred.  The error can be obtained from ERR_get_error(3).
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_verify(3)|PKCS7_verify(3)>
+
+=head1 HISTORY
+
+PKCS7_sign() was added to OpenSSL 0.9.5
+
+The B<PKCS7_PARTIAL> flag was added in OpenSSL 1.0.0
+
+The B<PKCS7_STREAM> flag was added in OpenSSL 1.0.0
+
+=cut
diff --git a/openssl/doc/crypto/PKCS7_sign_add_signer.pod b/openssl/doc/crypto/PKCS7_sign_add_signer.pod
new file mode 100644
index 0000000..ebec4d5
--- /dev/null
+++ b/openssl/doc/crypto/PKCS7_sign_add_signer.pod
@@ -0,0 +1,87 @@
+=pod
+
+=head1 NAME
+
+PKCS7_sign_add_signer - add a signer PKCS7 signed data structure.
+
+=head1 SYNOPSIS
+
+ #include <openssl/pkcs7.h>
+
+ PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md, int flags);
+
+
+=head1 DESCRIPTION
+
+PKCS7_sign_add_signer() adds a signer with certificate B<signcert> and private
+key B<pkey> using message digest B<md> to a PKCS7 signed data structure
+B<p7>.
+
+The PKCS7 structure should be obtained from an initial call to PKCS7_sign()
+with the flag B<PKCS7_PARTIAL> set or in the case or re-signing a valid PKCS7
+signed data structure.
+
+If the B<md> parameter is B<NULL> then the default digest for the public
+key algorithm will be used.
+
+Unless the B<PKCS7_REUSE_DIGEST> flag is set the returned PKCS7 structure
+is not complete and must be finalized either by streaming (if applicable) or
+a call to PKCS7_final().
+
+
+=head1 NOTES
+
+The main purpose of this function is to provide finer control over a PKCS#7
+signed data structure where the simpler PKCS7_sign() function defaults are
+not appropriate. For example if multiple signers or non default digest
+algorithms are needed.
+
+Any of the following flags (ored together) can be passed in the B<flags>
+parameter.
+
+If B<PKCS7_REUSE_DIGEST> is set then an attempt is made to copy the content
+digest value from the PKCS7 struture: to add a signer to an existing structure.
+An error occurs if a matching digest value cannot be found to copy. The
+returned PKCS7 structure will be valid and finalized when this flag is set.
+
+If B<PKCS7_PARTIAL> is set in addition to B<PKCS7_REUSE_DIGEST> then the 
+B<PKCS7_SIGNER_INO> structure will not be finalized so additional attributes
+can be added. In this case an explicit call to PKCS7_SIGNER_INFO_sign() is
+needed to finalize it.
+
+If B<PKCS7_NOCERTS> is set the signer's certificate will not be included in the
+PKCS7 structure, the signer's certificate must still be supplied in the
+B<signcert> parameter though. This can reduce the size of the signature if the
+signers certificate can be obtained by other means: for example a previously
+signed message.
+
+The signedData structure includes several PKCS#7 autenticatedAttributes
+including the signing time, the PKCS#7 content type and the supported list of
+ciphers in an SMIMECapabilities attribute. If B<PKCS7_NOATTR> is set then no
+authenticatedAttributes will be used. If B<PKCS7_NOSMIMECAP> is set then just
+the SMIMECapabilities are omitted.
+
+If present the SMIMECapabilities attribute indicates support for the following
+algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any of
+these algorithms is disabled then it will not be included.
+
+
+PKCS7_sign_add_signers() returns an internal pointer to the PKCS7_SIGNER_INFO
+structure just added, this can be used to set additional attributes 
+before it is finalized.
+
+=head1 RETURN VALUES
+
+PKCS7_sign_add_signers() returns an internal pointer to the PKCS7_SIGNER_INFO
+structure just added or NULL if an error occurs.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>,
+L<PKCS7_final(3)|PKCS7_final(3)>,
+
+=head1 HISTORY
+
+PPKCS7_sign_add_signer() was added to OpenSSL 1.0.0
+
+=cut
diff --git a/openssl/doc/crypto/PKCS7_verify.pod b/openssl/doc/crypto/PKCS7_verify.pod
new file mode 100644
index 0000000..7c10a4c
--- /dev/null
+++ b/openssl/doc/crypto/PKCS7_verify.pod
@@ -0,0 +1,118 @@
+=pod
+
+=head1 NAME
+
+PKCS7_verify - verify a PKCS#7 signedData structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/pkcs7.h>
+
+ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, BIO *out, int flags);
+
+ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags);
+
+=head1 DESCRIPTION
+
+PKCS7_verify() verifies a PKCS#7 signedData structure. B<p7> is the PKCS7
+structure to verify. B<certs> is a set of certificates in which to search for
+the signer's certificate. B<store> is a trusted certficate store (used for
+chain verification). B<indata> is the signed data if the content is not
+present in B<p7> (that is it is detached). The content is written to B<out>
+if it is not NULL.
+
+B<flags> is an optional set of flags, which can be used to modify the verify
+operation.
+
+PKCS7_get0_signers() retrieves the signer's certificates from B<p7>, it does
+B<not> check their validity or whether any signatures are valid. The B<certs>
+and B<flags> parameters have the same meanings as in PKCS7_verify().
+
+=head1 VERIFY PROCESS
+
+Normally the verify process proceeds as follows.
+
+Initially some sanity checks are performed on B<p7>. The type of B<p7> must
+be signedData. There must be at least one signature on the data and if
+the content is detached B<indata> cannot be B<NULL>.
+
+An attempt is made to locate all the signer's certificates, first looking in
+the B<certs> parameter (if it is not B<NULL>) and then looking in any certificates
+contained in the B<p7> structure itself. If any signer's certificates cannot be
+located the operation fails.
+
+Each signer's certificate is chain verified using the B<smimesign> purpose and
+the supplied trusted certificate store. Any internal certificates in the message
+are used as untrusted CAs. If any chain verify fails an error code is returned.
+
+Finally the signed content is read (and written to B<out> is it is not NULL) and
+the signature's checked.
+
+If all signature's verify correctly then the function is successful.
+
+Any of the following flags (ored together) can be passed in the B<flags> parameter
+to change the default verify behaviour. Only the flag B<PKCS7_NOINTERN> is
+meaningful to PKCS7_get0_signers().
+
+If B<PKCS7_NOINTERN> is set the certificates in the message itself are not 
+searched when locating the signer's certificate. This means that all the signers
+certificates must be in the B<certs> parameter.
+
+If the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> are deleted
+from the content. If the content is not of type B<text/plain> then an error is
+returned.
+
+If B<PKCS7_NOVERIFY> is set the signer's certificates are not chain verified.
+
+If B<PKCS7_NOCHAIN> is set then the certificates contained in the message are
+not used as untrusted CAs. This means that the whole verify chain (apart from
+the signer's certificate) must be contained in the trusted store.
+
+If B<PKCS7_NOSIGS> is set then the signatures on the data are not checked.
+
+=head1 NOTES
+
+One application of B<PKCS7_NOINTERN> is to only accept messages signed by
+a small number of certificates. The acceptable certificates would be passed
+in the B<certs> parameter. In this case if the signer is not one of the
+certificates supplied in B<certs> then the verify will fail because the
+signer cannot be found.
+
+Care should be taken when modifying the default verify behaviour, for example
+setting B<PKCS7_NOVERIFY|PKCS7_NOSIGS> will totally disable all verification 
+and any signed message will be considered valid. This combination is however
+useful if one merely wishes to write the content to B<out> and its validity
+is not considered important.
+
+Chain verification should arguably be performed  using the signing time rather
+than the current time. However since the signing time is supplied by the
+signer it cannot be trusted without additional evidence (such as a trusted
+timestamp).
+
+=head1 RETURN VALUES
+
+PKCS7_verify() returns 1 for a successful verification and zero or a negative
+value if an error occurs.
+
+PKCS7_get0_signers() returns all signers or B<NULL> if an error occurred.
+
+The error can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>
+
+=head1 BUGS
+
+The trusted certificate store is not searched for the signers certificate,
+this is primarily due to the inadequacies of the current B<X509_STORE>
+functionality.
+
+The lack of single pass processing and need to hold all data in memory as
+mentioned in PKCS7_sign() also applies to PKCS7_verify().
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>
+
+=head1 HISTORY
+
+PKCS7_verify() was added to OpenSSL 0.9.5
+
+=cut
diff --git a/openssl/doc/crypto/RAND_add.pod b/openssl/doc/crypto/RAND_add.pod
new file mode 100644
index 0000000..67c66f3
--- /dev/null
+++ b/openssl/doc/crypto/RAND_add.pod
@@ -0,0 +1,77 @@
+=pod
+
+=head1 NAME
+
+RAND_add, RAND_seed, RAND_status, RAND_event, RAND_screen - add
+entropy to the PRNG
+
+=head1 SYNOPSIS
+
+ #include <openssl/rand.h>
+
+ void RAND_seed(const void *buf, int num);
+
+ void RAND_add(const void *buf, int num, double entropy);
+
+ int  RAND_status(void);
+
+ int  RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam);
+ void RAND_screen(void);
+
+=head1 DESCRIPTION
+
+RAND_add() mixes the B<num> bytes at B<buf> into the PRNG state. Thus,
+if the data at B<buf> are unpredictable to an adversary, this
+increases the uncertainty about the state and makes the PRNG output
+less predictable. Suitable input comes from user interaction (random
+key presses, mouse movements) and certain hardware events. The
+B<entropy> argument is (the lower bound of) an estimate of how much
+randomness is contained in B<buf>, measured in bytes. Details about
+sources of randomness and how to estimate their entropy can be found
+in the literature, e.g. RFC 1750.
+
+RAND_add() may be called with sensitive data such as user entered
+passwords. The seed values cannot be recovered from the PRNG output.
+
+OpenSSL makes sure that the PRNG state is unique for each thread. On
+systems that provide C</dev/urandom>, the randomness device is used
+to seed the PRNG transparently. However, on all other systems, the
+application is responsible for seeding the PRNG by calling RAND_add(),
+L<RAND_egd(3)|RAND_egd(3)>
+or L<RAND_load_file(3)|RAND_load_file(3)>.
+
+RAND_seed() is equivalent to RAND_add() when B<num == entropy>.
+
+RAND_event() collects the entropy from Windows events such as mouse
+movements and other user interaction. It should be called with the
+B<iMsg>, B<wParam> and B<lParam> arguments of I<all> messages sent to
+the window procedure. It will estimate the entropy contained in the
+event message (if any), and add it to the PRNG. The program can then
+process the messages as usual.
+
+The RAND_screen() function is available for the convenience of Windows
+programmers. It adds the current contents of the screen to the PRNG.
+For applications that can catch Windows events, seeding the PRNG by
+calling RAND_event() is a significantly better source of
+randomness. It should be noted that both methods cannot be used on
+servers that run without user interaction.
+
+=head1 RETURN VALUES
+
+RAND_status() and RAND_event() return 1 if the PRNG has been seeded
+with enough data, 0 otherwise.
+
+The other functions do not return values.
+
+=head1 SEE ALSO
+
+L<rand(3)|rand(3)>, L<RAND_egd(3)|RAND_egd(3)>,
+L<RAND_load_file(3)|RAND_load_file(3)>, L<RAND_cleanup(3)|RAND_cleanup(3)>
+
+=head1 HISTORY
+
+RAND_seed() and RAND_screen() are available in all versions of SSLeay
+and OpenSSL. RAND_add() and RAND_status() have been added in OpenSSL
+0.9.5, RAND_event() in OpenSSL 0.9.5a.
+
+=cut
diff --git a/openssl/doc/crypto/RAND_bytes.pod b/openssl/doc/crypto/RAND_bytes.pod
new file mode 100644
index 0000000..1a9b91e
--- /dev/null
+++ b/openssl/doc/crypto/RAND_bytes.pod
@@ -0,0 +1,50 @@
+=pod
+
+=head1 NAME
+
+RAND_bytes, RAND_pseudo_bytes - generate random data
+
+=head1 SYNOPSIS
+
+ #include <openssl/rand.h>
+
+ int RAND_bytes(unsigned char *buf, int num);
+
+ int RAND_pseudo_bytes(unsigned char *buf, int num);
+
+=head1 DESCRIPTION
+
+RAND_bytes() puts B<num> cryptographically strong pseudo-random bytes
+into B<buf>. An error occurs if the PRNG has not been seeded with
+enough randomness to ensure an unpredictable byte sequence.
+
+RAND_pseudo_bytes() puts B<num> pseudo-random bytes into B<buf>.
+Pseudo-random byte sequences generated by RAND_pseudo_bytes() will be
+unique if they are of sufficient length, but are not necessarily
+unpredictable. They can be used for non-cryptographic purposes and for
+certain purposes in cryptographic protocols, but usually not for key
+generation etc.
+
+The contents of B<buf> is mixed into the entropy pool before retrieving
+the new pseudo-random bytes unless disabled at compile time (see FAQ).
+
+=head1 RETURN VALUES
+
+RAND_bytes() returns 1 on success, 0 otherwise. The error code can be
+obtained by L<ERR_get_error(3)|ERR_get_error(3)>. RAND_pseudo_bytes() returns 1 if the
+bytes generated are cryptographically strong, 0 otherwise. Both
+functions return -1 if they are not supported by the current RAND
+method.
+
+=head1 SEE ALSO
+
+L<rand(3)|rand(3)>, L<ERR_get_error(3)|ERR_get_error(3)>,
+L<RAND_add(3)|RAND_add(3)>
+
+=head1 HISTORY
+
+RAND_bytes() is available in all versions of SSLeay and OpenSSL.  It
+has a return value since OpenSSL 0.9.5. RAND_pseudo_bytes() was added
+in OpenSSL 0.9.5.
+
+=cut
diff --git a/openssl/doc/crypto/RAND_cleanup.pod b/openssl/doc/crypto/RAND_cleanup.pod
new file mode 100644
index 0000000..3a8f074
--- /dev/null
+++ b/openssl/doc/crypto/RAND_cleanup.pod
@@ -0,0 +1,29 @@
+=pod
+
+=head1 NAME
+
+RAND_cleanup - erase the PRNG state
+
+=head1 SYNOPSIS
+
+ #include <openssl/rand.h>
+
+ void RAND_cleanup(void);
+
+=head1 DESCRIPTION
+
+RAND_cleanup() erases the memory used by the PRNG.
+
+=head1 RETURN VALUE
+
+RAND_cleanup() returns no value.
+
+=head1 SEE ALSO
+
+L<rand(3)|rand(3)>
+
+=head1 HISTORY
+
+RAND_cleanup() is available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/RAND_egd.pod b/openssl/doc/crypto/RAND_egd.pod
new file mode 100644
index 0000000..8b8c61d
--- /dev/null
+++ b/openssl/doc/crypto/RAND_egd.pod
@@ -0,0 +1,88 @@
+=pod
+
+=head1 NAME
+
+RAND_egd - query entropy gathering daemon
+
+=head1 SYNOPSIS
+
+ #include <openssl/rand.h>
+
+ int RAND_egd(const char *path);
+ int RAND_egd_bytes(const char *path, int bytes);
+
+ int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes);
+
+=head1 DESCRIPTION
+
+RAND_egd() queries the entropy gathering daemon EGD on socket B<path>.
+It queries 255 bytes and uses L<RAND_add(3)|RAND_add(3)> to seed the
+OpenSSL built-in PRNG. RAND_egd(path) is a wrapper for
+RAND_egd_bytes(path, 255);
+
+RAND_egd_bytes() queries the entropy gathering daemon EGD on socket B<path>.
+It queries B<bytes> bytes and uses L<RAND_add(3)|RAND_add(3)> to seed the
+OpenSSL built-in PRNG.
+This function is more flexible than RAND_egd().
+When only one secret key must
+be generated, it is not necessary to request the full amount 255 bytes from
+the EGD socket. This can be advantageous, since the amount of entropy
+that can be retrieved from EGD over time is limited.
+
+RAND_query_egd_bytes() performs the actual query of the EGD daemon on socket
+B<path>. If B<buf> is given, B<bytes> bytes are queried and written into
+B<buf>. If B<buf> is NULL, B<bytes> bytes are queried and used to seed the
+OpenSSL built-in PRNG using L<RAND_add(3)|RAND_add(3)>.
+
+=head1 NOTES
+
+On systems without /dev/*random devices providing entropy from the kernel,
+the EGD entropy gathering daemon can be used to collect entropy. It provides
+a socket interface through which entropy can be gathered in chunks up to
+255 bytes. Several chunks can be queried during one connection.
+
+EGD is available from http://www.lothar.com/tech/crypto/ (C<perl
+Makefile.PL; make; make install> to install). It is run as B<egd>
+I<path>, where I<path> is an absolute path designating a socket. When
+RAND_egd() is called with that path as an argument, it tries to read
+random bytes that EGD has collected. RAND_egd() retrieves entropy from the
+daemon using the daemon's "non-blocking read" command which shall
+be answered immediately by the daemon without waiting for additional
+entropy to be collected. The write and read socket operations in the
+communication are blocking.
+
+Alternatively, the EGD-interface compatible daemon PRNGD can be used. It is
+available from
+http://prngd.sourceforge.net/ .
+PRNGD does employ an internal PRNG itself and can therefore never run
+out of entropy.
+
+OpenSSL automatically queries EGD when entropy is requested via RAND_bytes()
+or the status is checked via RAND_status() for the first time, if the socket
+is located at /var/run/egd-pool, /dev/egd-pool or /etc/egd-pool.
+
+=head1 RETURN VALUE
+
+RAND_egd() and RAND_egd_bytes() return the number of bytes read from the
+daemon on success, and -1 if the connection failed or the daemon did not
+return enough data to fully seed the PRNG.
+
+RAND_query_egd_bytes() returns the number of bytes read from the daemon on
+success, and -1 if the connection failed. The PRNG state is not considered.
+
+=head1 SEE ALSO
+
+L<rand(3)|rand(3)>, L<RAND_add(3)|RAND_add(3)>,
+L<RAND_cleanup(3)|RAND_cleanup(3)>
+
+=head1 HISTORY
+
+RAND_egd() is available since OpenSSL 0.9.5.
+
+RAND_egd_bytes() is available since OpenSSL 0.9.6.
+
+RAND_query_egd_bytes() is available since OpenSSL 0.9.7.
+
+The automatic query of /var/run/egd-pool et al was added in OpenSSL 0.9.7.
+
+=cut
diff --git a/openssl/doc/crypto/RAND_load_file.pod b/openssl/doc/crypto/RAND_load_file.pod
new file mode 100644
index 0000000..d8c134e
--- /dev/null
+++ b/openssl/doc/crypto/RAND_load_file.pod
@@ -0,0 +1,53 @@
+=pod
+
+=head1 NAME
+
+RAND_load_file, RAND_write_file, RAND_file_name - PRNG seed file
+
+=head1 SYNOPSIS
+
+ #include <openssl/rand.h>
+
+ const char *RAND_file_name(char *buf, size_t num);
+
+ int RAND_load_file(const char *filename, long max_bytes);
+
+ int RAND_write_file(const char *filename);
+
+=head1 DESCRIPTION
+
+RAND_file_name() generates a default path for the random seed
+file. B<buf> points to a buffer of size B<num> in which to store the
+filename. The seed file is $RANDFILE if that environment variable is
+set, $HOME/.rnd otherwise. If $HOME is not set either, or B<num> is
+too small for the path name, an error occurs.
+
+RAND_load_file() reads a number of bytes from file B<filename> and
+adds them to the PRNG. If B<max_bytes> is non-negative,
+up to to B<max_bytes> are read; starting with OpenSSL 0.9.5,
+if B<max_bytes> is -1, the complete file is read.
+
+RAND_write_file() writes a number of random bytes (currently 1024) to
+file B<filename> which can be used to initialize the PRNG by calling
+RAND_load_file() in a later session.
+
+=head1 RETURN VALUES
+
+RAND_load_file() returns the number of bytes read.
+
+RAND_write_file() returns the number of bytes written, and -1 if the
+bytes written were generated without appropriate seed.
+
+RAND_file_name() returns a pointer to B<buf> on success, and NULL on
+error.
+
+=head1 SEE ALSO
+
+L<rand(3)|rand(3)>, L<RAND_add(3)|RAND_add(3)>, L<RAND_cleanup(3)|RAND_cleanup(3)>
+
+=head1 HISTORY
+
+RAND_load_file(), RAND_write_file() and RAND_file_name() are available in
+all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/RAND_set_rand_method.pod b/openssl/doc/crypto/RAND_set_rand_method.pod
new file mode 100644
index 0000000..e5b780f
--- /dev/null
+++ b/openssl/doc/crypto/RAND_set_rand_method.pod
@@ -0,0 +1,83 @@
+=pod
+
+=head1 NAME
+
+RAND_set_rand_method, RAND_get_rand_method, RAND_SSLeay - select RAND method
+
+=head1 SYNOPSIS
+
+ #include <openssl/rand.h>
+
+ void RAND_set_rand_method(const RAND_METHOD *meth);
+
+ const RAND_METHOD *RAND_get_rand_method(void);
+
+ RAND_METHOD *RAND_SSLeay(void);
+
+=head1 DESCRIPTION
+
+A B<RAND_METHOD> specifies the functions that OpenSSL uses for random number
+generation. By modifying the method, alternative implementations such as
+hardware RNGs may be used. IMPORTANT: See the NOTES section for important
+information about how these RAND API functions are affected by the use of
+B<ENGINE> API calls.
+
+Initially, the default RAND_METHOD is the OpenSSL internal implementation, as
+returned by RAND_SSLeay().
+
+RAND_set_default_method() makes B<meth> the method for PRNG use. B<NB>: This is
+true only whilst no ENGINE has been set as a default for RAND, so this function
+is no longer recommended.
+
+RAND_get_default_method() returns a pointer to the current RAND_METHOD.
+However, the meaningfulness of this result is dependent on whether the ENGINE
+API is being used, so this function is no longer recommended.
+
+=head1 THE RAND_METHOD STRUCTURE
+
+ typedef struct rand_meth_st
+ {
+        void (*seed)(const void *buf, int num);
+        int (*bytes)(unsigned char *buf, int num);
+        void (*cleanup)(void);
+        void (*add)(const void *buf, int num, int entropy);
+        int (*pseudorand)(unsigned char *buf, int num);
+	int (*status)(void);
+ } RAND_METHOD;
+
+The components point to the implementation of RAND_seed(),
+RAND_bytes(), RAND_cleanup(), RAND_add(), RAND_pseudo_rand()
+and RAND_status().
+Each component may be NULL if the function is not implemented.
+
+=head1 RETURN VALUES
+
+RAND_set_rand_method() returns no value. RAND_get_rand_method() and
+RAND_SSLeay() return pointers to the respective methods.
+
+=head1 NOTES
+
+As of version 0.9.7, RAND_METHOD implementations are grouped together with other
+algorithmic APIs (eg. RSA_METHOD, EVP_CIPHER, etc) in B<ENGINE> modules. If a
+default ENGINE is specified for RAND functionality using an ENGINE API function,
+that will override any RAND defaults set using the RAND API (ie.
+RAND_set_rand_method()). For this reason, the ENGINE API is the recommended way
+to control default implementations for use in RAND and other cryptographic
+algorithms.
+
+=head1 SEE ALSO
+
+L<rand(3)|rand(3)>, L<engine(3)|engine(3)>
+
+=head1 HISTORY
+
+RAND_set_rand_method(), RAND_get_rand_method() and RAND_SSLeay() are
+available in all versions of OpenSSL.
+
+In the engine version of version 0.9.6, RAND_set_rand_method() was altered to
+take an ENGINE pointer as its argument. As of version 0.9.7, that has been
+reverted as the ENGINE API transparently overrides RAND defaults if used,
+otherwise RAND API functions work as before. RAND_set_rand_engine() was also
+introduced in version 0.9.7.
+
+=cut
diff --git a/openssl/doc/crypto/RSA_blinding_on.pod b/openssl/doc/crypto/RSA_blinding_on.pod
new file mode 100644
index 0000000..fd2c69a
--- /dev/null
+++ b/openssl/doc/crypto/RSA_blinding_on.pod
@@ -0,0 +1,43 @@
+=pod
+
+=head1 NAME
+
+RSA_blinding_on, RSA_blinding_off - protect the RSA operation from timing attacks
+
+=head1 SYNOPSIS
+
+ #include <openssl/rsa.h>
+
+ int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
+
+ void RSA_blinding_off(RSA *rsa);
+
+=head1 DESCRIPTION
+
+RSA is vulnerable to timing attacks. In a setup where attackers can
+measure the time of RSA decryption or signature operations, blinding
+must be used to protect the RSA operation from that attack.
+
+RSA_blinding_on() turns blinding on for key B<rsa> and generates a
+random blinding factor. B<ctx> is B<NULL> or a pre-allocated and
+initialized B<BN_CTX>. The random number generator must be seeded
+prior to calling RSA_blinding_on().
+
+RSA_blinding_off() turns blinding off and frees the memory used for
+the blinding factor.
+
+=head1 RETURN VALUES
+
+RSA_blinding_on() returns 1 on success, and 0 if an error occurred.
+
+RSA_blinding_off() returns no value.
+
+=head1 SEE ALSO
+
+L<rsa(3)|rsa(3)>, L<rand(3)|rand(3)>
+
+=head1 HISTORY
+
+RSA_blinding_on() and RSA_blinding_off() appeared in SSLeay 0.9.0.
+
+=cut
diff --git a/openssl/doc/crypto/RSA_check_key.pod b/openssl/doc/crypto/RSA_check_key.pod
new file mode 100644
index 0000000..a5198f3
--- /dev/null
+++ b/openssl/doc/crypto/RSA_check_key.pod
@@ -0,0 +1,67 @@
+=pod
+
+=head1 NAME
+
+RSA_check_key - validate private RSA keys
+
+=head1 SYNOPSIS
+
+ #include <openssl/rsa.h>
+
+ int RSA_check_key(RSA *rsa);
+
+=head1 DESCRIPTION
+
+This function validates RSA keys. It checks that B<p> and B<q> are
+in fact prime, and that B<n = p*q>.
+
+It also checks that B<d*e = 1 mod (p-1*q-1)>,
+and that B<dmp1>, B<dmq1> and B<iqmp> are set correctly or are B<NULL>.
+
+As such, this function can not be used with any arbitrary RSA key object,
+even if it is otherwise fit for regular RSA operation. See B<NOTES> for more
+information.
+
+=head1 RETURN VALUE
+
+RSA_check_key() returns 1 if B<rsa> is a valid RSA key, and 0 otherwise.
+-1 is returned if an error occurs while checking the key.
+
+If the key is invalid or an error occurred, the reason code can be
+obtained using L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 NOTES
+
+This function does not work on RSA public keys that have only the modulus
+and public exponent elements populated. It performs integrity checks on all
+the RSA key material, so the RSA key structure must contain all the private
+key data too.
+
+Unlike most other RSA functions, this function does B<not> work
+transparently with any underlying ENGINE implementation because it uses the
+key data in the RSA structure directly. An ENGINE implementation can
+override the way key data is stored and handled, and can even provide
+support for HSM keys - in which case the RSA structure may contain B<no>
+key data at all! If the ENGINE in question is only being used for
+acceleration or analysis purposes, then in all likelihood the RSA key data
+is complete and untouched, but this can't be assumed in the general case.
+
+=head1 BUGS
+
+A method of verifying the RSA key using opaque RSA API functions might need
+to be considered. Right now RSA_check_key() simply uses the RSA structure
+elements directly, bypassing the RSA_METHOD table altogether (and
+completely violating encapsulation and object-orientation in the process).
+The best fix will probably be to introduce a "check_key()" handler to the
+RSA_METHOD function table so that alternative implementations can also
+provide their own verifiers.
+
+=head1 SEE ALSO
+
+L<rsa(3)|rsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>
+
+=head1 HISTORY
+
+RSA_check_key() appeared in OpenSSL 0.9.4.
+
+=cut
diff --git a/openssl/doc/crypto/RSA_generate_key.pod b/openssl/doc/crypto/RSA_generate_key.pod
new file mode 100644
index 0000000..52dbb14
--- /dev/null
+++ b/openssl/doc/crypto/RSA_generate_key.pod
@@ -0,0 +1,69 @@
+=pod
+
+=head1 NAME
+
+RSA_generate_key - generate RSA key pair
+
+=head1 SYNOPSIS
+
+ #include <openssl/rsa.h>
+
+ RSA *RSA_generate_key(int num, unsigned long e,
+    void (*callback)(int,int,void *), void *cb_arg);
+
+=head1 DESCRIPTION
+
+RSA_generate_key() generates a key pair and returns it in a newly
+allocated B<RSA> structure. The pseudo-random number generator must
+be seeded prior to calling RSA_generate_key().
+
+The modulus size will be B<num> bits, and the public exponent will be
+B<e>. Key sizes with B<num> E<lt> 1024 should be considered insecure.
+The exponent is an odd number, typically 3, 17 or 65537.
+
+A callback function may be used to provide feedback about the
+progress of the key generation. If B<callback> is not B<NULL>, it
+will be called as follows:
+
+=over 4
+
+=item *
+
+While a random prime number is generated, it is called as
+described in L<BN_generate_prime(3)|BN_generate_prime(3)>.
+
+=item *
+
+When the n-th randomly generated prime is rejected as not
+suitable for the key, B<callback(2, n, cb_arg)> is called.
+
+=item *
+
+When a random p has been found with p-1 relatively prime to B<e>,
+it is called as B<callback(3, 0, cb_arg)>.
+
+=back
+
+The process is then repeated for prime q with B<callback(3, 1, cb_arg)>.
+
+=head1 RETURN VALUE
+
+If key generation fails, RSA_generate_key() returns B<NULL>; the
+error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 BUGS
+
+B<callback(2, x, cb_arg)> is used with two different meanings.
+
+RSA_generate_key() goes into an infinite loop for illegal input values.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>,
+L<RSA_free(3)|RSA_free(3)>
+
+=head1 HISTORY
+
+The B<cb_arg> argument was added in SSLeay 0.9.0.
+
+=cut
diff --git a/openssl/doc/crypto/RSA_get_ex_new_index.pod b/openssl/doc/crypto/RSA_get_ex_new_index.pod
new file mode 100644
index 0000000..7d0fd1f
--- /dev/null
+++ b/openssl/doc/crypto/RSA_get_ex_new_index.pod
@@ -0,0 +1,120 @@
+=pod
+
+=head1 NAME
+
+RSA_get_ex_new_index, RSA_set_ex_data, RSA_get_ex_data - add application specific data to RSA structures
+
+=head1 SYNOPSIS
+
+ #include <openssl/rsa.h>
+
+ int RSA_get_ex_new_index(long argl, void *argp,
+		CRYPTO_EX_new *new_func,
+		CRYPTO_EX_dup *dup_func,
+		CRYPTO_EX_free *free_func);
+
+ int RSA_set_ex_data(RSA *r, int idx, void *arg);
+
+ void *RSA_get_ex_data(RSA *r, int idx);
+
+ typedef int CRYPTO_EX_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                           int idx, long argl, void *argp);
+ typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                             int idx, long argl, void *argp);
+ typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d,
+                           int idx, long argl, void *argp);
+
+=head1 DESCRIPTION
+
+Several OpenSSL structures can have application specific data attached to them.
+This has several potential uses, it can be used to cache data associated with
+a structure (for example the hash of some part of the structure) or some
+additional data (for example a handle to the data in an external library).
+
+Since the application data can be anything at all it is passed and retrieved
+as a B<void *> type.
+
+The B<RSA_get_ex_new_index()> function is initially called to "register" some
+new application specific data. It takes three optional function pointers which
+are called when the parent structure (in this case an RSA structure) is
+initially created, when it is copied and when it is freed up. If any or all of
+these function pointer arguments are not used they should be set to NULL. The
+precise manner in which these function pointers are called is described in more
+detail below. B<RSA_get_ex_new_index()> also takes additional long and pointer
+parameters which will be passed to the supplied functions but which otherwise
+have no special meaning. It returns an B<index> which should be stored
+(typically in a static variable) and passed used in the B<idx> parameter in
+the remaining functions. Each successful call to B<RSA_get_ex_new_index()>
+will return an index greater than any previously returned, this is important
+because the optional functions are called in order of increasing index value.
+
+B<RSA_set_ex_data()> is used to set application specific data, the data is
+supplied in the B<arg> parameter and its precise meaning is up to the
+application.
+
+B<RSA_get_ex_data()> is used to retrieve application specific data. The data
+is returned to the application, this will be the same value as supplied to
+a previous B<RSA_set_ex_data()> call.
+
+B<new_func()> is called when a structure is initially allocated (for example
+with B<RSA_new()>. The parent structure members will not have any meaningful
+values at this point. This function will typically be used to allocate any
+application specific structure.
+
+B<free_func()> is called when a structure is being freed up. The dynamic parent
+structure members should not be accessed because they will be freed up when
+this function is called.
+
+B<new_func()> and B<free_func()> take the same parameters. B<parent> is a
+pointer to the parent RSA structure. B<ptr> is a the application specific data
+(this wont be of much use in B<new_func()>. B<ad> is a pointer to the
+B<CRYPTO_EX_DATA> structure from the parent RSA structure: the functions
+B<CRYPTO_get_ex_data()> and B<CRYPTO_set_ex_data()> can be called to manipulate
+it. The B<idx> parameter is the index: this will be the same value returned by
+B<RSA_get_ex_new_index()> when the functions were initially registered. Finally
+the B<argl> and B<argp> parameters are the values originally passed to the same
+corresponding parameters when B<RSA_get_ex_new_index()> was called.
+
+B<dup_func()> is called when a structure is being copied. Pointers to the
+destination and source B<CRYPTO_EX_DATA> structures are passed in the B<to> and
+B<from> parameters respectively. The B<from_d> parameter is passed a pointer to
+the source application data when the function is called, when the function returns
+the value is copied to the destination: the application can thus modify the data
+pointed to by B<from_d> and have different values in the source and destination.
+The B<idx>, B<argl> and B<argp> parameters are the same as those in B<new_func()>
+and B<free_func()>.
+
+=head1 RETURN VALUES
+
+B<RSA_get_ex_new_index()> returns a new index or -1 on failure (note 0 is a valid
+index value).
+
+B<RSA_set_ex_data()> returns 1 on success or 0 on failure.
+
+B<RSA_get_ex_data()> returns the application data or 0 on failure. 0 may also
+be valid application data but currently it can only fail if given an invalid B<idx>
+parameter.
+
+B<new_func()> and B<dup_func()> should return 0 for failure and 1 for success.
+
+On failure an error code can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 BUGS
+
+B<dup_func()> is currently never called.
+
+The return value of B<new_func()> is ignored.
+
+The B<new_func()> function isn't very useful because no meaningful values are
+present in the parent RSA structure when it is called.
+
+=head1 SEE ALSO
+
+L<rsa(3)|rsa(3)>, L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>
+
+=head1 HISTORY
+
+RSA_get_ex_new_index(), RSA_set_ex_data() and RSA_get_ex_data() are
+available since SSLeay 0.9.0.
+
+=cut
diff --git a/openssl/doc/crypto/RSA_new.pod b/openssl/doc/crypto/RSA_new.pod
new file mode 100644
index 0000000..3d15b92
--- /dev/null
+++ b/openssl/doc/crypto/RSA_new.pod
@@ -0,0 +1,41 @@
+=pod
+
+=head1 NAME
+
+RSA_new, RSA_free - allocate and free RSA objects
+
+=head1 SYNOPSIS
+
+ #include <openssl/rsa.h>
+
+ RSA * RSA_new(void);
+
+ void RSA_free(RSA *rsa);
+
+=head1 DESCRIPTION
+
+RSA_new() allocates and initializes an B<RSA> structure. It is equivalent to
+calling RSA_new_method(NULL).
+
+RSA_free() frees the B<RSA> structure and its components. The key is
+erased before the memory is returned to the system.
+
+=head1 RETURN VALUES
+
+If the allocation fails, RSA_new() returns B<NULL> and sets an error
+code that can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. Otherwise it returns
+a pointer to the newly allocated structure.
+
+RSA_free() returns no value.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<rsa(3)|rsa(3)>,
+L<RSA_generate_key(3)|RSA_generate_key(3)>,
+L<RSA_new_method(3)|RSA_new_method(3)>
+
+=head1 HISTORY
+
+RSA_new() and RSA_free() are available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/RSA_padding_add_PKCS1_type_1.pod b/openssl/doc/crypto/RSA_padding_add_PKCS1_type_1.pod
new file mode 100644
index 0000000..b8f678f
--- /dev/null
+++ b/openssl/doc/crypto/RSA_padding_add_PKCS1_type_1.pod
@@ -0,0 +1,124 @@
+=pod
+
+=head1 NAME
+
+RSA_padding_add_PKCS1_type_1, RSA_padding_check_PKCS1_type_1,
+RSA_padding_add_PKCS1_type_2, RSA_padding_check_PKCS1_type_2,
+RSA_padding_add_PKCS1_OAEP, RSA_padding_check_PKCS1_OAEP,
+RSA_padding_add_SSLv23, RSA_padding_check_SSLv23,
+RSA_padding_add_none, RSA_padding_check_none - asymmetric encryption
+padding
+
+=head1 SYNOPSIS
+
+ #include <openssl/rsa.h>
+
+ int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen,
+    unsigned char *f, int fl);
+
+ int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen,
+    unsigned char *f, int fl, int rsa_len);
+
+ int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen,
+    unsigned char *f, int fl);
+
+ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
+    unsigned char *f, int fl, int rsa_len);
+
+ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
+    unsigned char *f, int fl, unsigned char *p, int pl);
+
+ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
+    unsigned char *f, int fl, int rsa_len, unsigned char *p, int pl);
+
+ int RSA_padding_add_SSLv23(unsigned char *to, int tlen,
+    unsigned char *f, int fl);
+
+ int RSA_padding_check_SSLv23(unsigned char *to, int tlen,
+    unsigned char *f, int fl, int rsa_len);
+
+ int RSA_padding_add_none(unsigned char *to, int tlen,
+    unsigned char *f, int fl);
+
+ int RSA_padding_check_none(unsigned char *to, int tlen,
+    unsigned char *f, int fl, int rsa_len);
+
+=head1 DESCRIPTION
+
+The RSA_padding_xxx_xxx() functions are called from the RSA encrypt,
+decrypt, sign and verify functions. Normally they should not be called
+from application programs.
+
+However, they can also be called directly to implement padding for other
+asymmetric ciphers. RSA_padding_add_PKCS1_OAEP() and
+RSA_padding_check_PKCS1_OAEP() may be used in an application combined
+with B<RSA_NO_PADDING> in order to implement OAEP with an encoding
+parameter.
+
+RSA_padding_add_xxx() encodes B<fl> bytes from B<f> so as to fit into
+B<tlen> bytes and stores the result at B<to>. An error occurs if B<fl>
+does not meet the size requirements of the encoding method.
+
+The following encoding methods are implemented:
+
+=over 4
+
+=item PKCS1_type_1
+
+PKCS #1 v2.0 EMSA-PKCS1-v1_5 (PKCS #1 v1.5 block type 1); used for signatures
+
+=item PKCS1_type_2
+
+PKCS #1 v2.0 EME-PKCS1-v1_5 (PKCS #1 v1.5 block type 2)
+
+=item PKCS1_OAEP
+
+PKCS #1 v2.0 EME-OAEP
+
+=item SSLv23
+
+PKCS #1 EME-PKCS1-v1_5 with SSL-specific modification
+
+=item none
+
+simply copy the data
+
+=back
+
+The random number generator must be seeded prior to calling
+RSA_padding_add_xxx().
+
+RSA_padding_check_xxx() verifies that the B<fl> bytes at B<f> contain
+a valid encoding for a B<rsa_len> byte RSA key in the respective
+encoding method and stores the recovered data of at most B<tlen> bytes
+(for B<RSA_NO_PADDING>: of size B<tlen>)
+at B<to>.
+
+For RSA_padding_xxx_OAEP(), B<p> points to the encoding parameter
+of length B<pl>. B<p> may be B<NULL> if B<pl> is 0.
+
+=head1 RETURN VALUES
+
+The RSA_padding_add_xxx() functions return 1 on success, 0 on error.
+The RSA_padding_check_xxx() functions return the length of the
+recovered data, -1 on error. Error codes can be obtained by calling
+L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 SEE ALSO
+
+L<RSA_public_encrypt(3)|RSA_public_encrypt(3)>,
+L<RSA_private_decrypt(3)|RSA_private_decrypt(3)>,
+L<RSA_sign(3)|RSA_sign(3)>, L<RSA_verify(3)|RSA_verify(3)>
+
+=head1 HISTORY
+
+RSA_padding_add_PKCS1_type_1(), RSA_padding_check_PKCS1_type_1(),
+RSA_padding_add_PKCS1_type_2(), RSA_padding_check_PKCS1_type_2(),
+RSA_padding_add_SSLv23(), RSA_padding_check_SSLv23(),
+RSA_padding_add_none() and RSA_padding_check_none() appeared in
+SSLeay 0.9.0.
+
+RSA_padding_add_PKCS1_OAEP() and RSA_padding_check_PKCS1_OAEP() were
+added in OpenSSL 0.9.2b.
+
+=cut
diff --git a/openssl/doc/crypto/RSA_print.pod b/openssl/doc/crypto/RSA_print.pod
new file mode 100644
index 0000000..c971e91
--- /dev/null
+++ b/openssl/doc/crypto/RSA_print.pod
@@ -0,0 +1,49 @@
+=pod
+
+=head1 NAME
+
+RSA_print, RSA_print_fp,
+DSAparams_print, DSAparams_print_fp, DSA_print, DSA_print_fp,
+DHparams_print, DHparams_print_fp - print cryptographic parameters
+
+=head1 SYNOPSIS
+
+ #include <openssl/rsa.h>
+
+ int RSA_print(BIO *bp, RSA *x, int offset);
+ int RSA_print_fp(FILE *fp, RSA *x, int offset);
+
+ #include <openssl/dsa.h>
+
+ int DSAparams_print(BIO *bp, DSA *x);
+ int DSAparams_print_fp(FILE *fp, DSA *x);
+ int DSA_print(BIO *bp, DSA *x, int offset);
+ int DSA_print_fp(FILE *fp, DSA *x, int offset);
+
+ #include <openssl/dh.h>
+
+ int DHparams_print(BIO *bp, DH *x);
+ int DHparams_print_fp(FILE *fp, DH *x);
+
+=head1 DESCRIPTION
+
+A human-readable hexadecimal output of the components of the RSA
+key, DSA parameters or key or DH parameters is printed to B<bp> or B<fp>.
+
+The output lines are indented by B<offset> spaces.
+
+=head1 RETURN VALUES
+
+These functions return 1 on success, 0 on error.
+
+=head1 SEE ALSO
+
+L<dh(3)|dh(3)>, L<dsa(3)|dsa(3)>, L<rsa(3)|rsa(3)>, L<BN_bn2bin(3)|BN_bn2bin(3)>
+
+=head1 HISTORY
+
+RSA_print(), RSA_print_fp(), DSA_print(), DSA_print_fp(), DH_print(),
+DH_print_fp() are available in all versions of SSLeay and OpenSSL.
+DSAparams_print() and DSAparams_print_fp() were added in SSLeay 0.8.
+
+=cut
diff --git a/openssl/doc/crypto/RSA_private_encrypt.pod b/openssl/doc/crypto/RSA_private_encrypt.pod
new file mode 100644
index 0000000..746a80c
--- /dev/null
+++ b/openssl/doc/crypto/RSA_private_encrypt.pod
@@ -0,0 +1,70 @@
+=pod
+
+=head1 NAME
+
+RSA_private_encrypt, RSA_public_decrypt - low level signature operations
+
+=head1 SYNOPSIS
+
+ #include <openssl/rsa.h>
+
+ int RSA_private_encrypt(int flen, unsigned char *from,
+    unsigned char *to, RSA *rsa, int padding);
+
+ int RSA_public_decrypt(int flen, unsigned char *from, 
+    unsigned char *to, RSA *rsa, int padding);
+
+=head1 DESCRIPTION
+
+These functions handle RSA signatures at a low level.
+
+RSA_private_encrypt() signs the B<flen> bytes at B<from> (usually a
+message digest with an algorithm identifier) using the private key
+B<rsa> and stores the signature in B<to>. B<to> must point to
+B<RSA_size(rsa)> bytes of memory.
+
+B<padding> denotes one of the following modes:
+
+=over 4
+
+=item RSA_PKCS1_PADDING
+
+PKCS #1 v1.5 padding. This function does not handle the
+B<algorithmIdentifier> specified in PKCS #1. When generating or
+verifying PKCS #1 signatures, L<RSA_sign(3)|RSA_sign(3)> and L<RSA_verify(3)|RSA_verify(3)> should be
+used.
+
+=item RSA_NO_PADDING
+
+Raw RSA signature. This mode should I<only> be used to implement
+cryptographically sound padding modes in the application code.
+Signing user data directly with RSA is insecure.
+
+=back
+
+RSA_public_decrypt() recovers the message digest from the B<flen>
+bytes long signature at B<from> using the signer's public key
+B<rsa>. B<to> must point to a memory section large enough to hold the
+message digest (which is smaller than B<RSA_size(rsa) -
+11>). B<padding> is the padding mode that was used to sign the data.
+
+=head1 RETURN VALUES
+
+RSA_private_encrypt() returns the size of the signature (i.e.,
+RSA_size(rsa)). RSA_public_decrypt() returns the size of the
+recovered message digest.
+
+On error, -1 is returned; the error codes can be
+obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<rsa(3)|rsa(3)>,
+L<RSA_sign(3)|RSA_sign(3)>, L<RSA_verify(3)|RSA_verify(3)>
+
+=head1 HISTORY
+
+The B<padding> argument was added in SSLeay 0.8. RSA_NO_PADDING is
+available since SSLeay 0.9.0.
+
+=cut
diff --git a/openssl/doc/crypto/RSA_public_encrypt.pod b/openssl/doc/crypto/RSA_public_encrypt.pod
new file mode 100644
index 0000000..ab0fe3b
--- /dev/null
+++ b/openssl/doc/crypto/RSA_public_encrypt.pod
@@ -0,0 +1,84 @@
+=pod
+
+=head1 NAME
+
+RSA_public_encrypt, RSA_private_decrypt - RSA public key cryptography
+
+=head1 SYNOPSIS
+
+ #include <openssl/rsa.h>
+
+ int RSA_public_encrypt(int flen, unsigned char *from,
+    unsigned char *to, RSA *rsa, int padding);
+
+ int RSA_private_decrypt(int flen, unsigned char *from,
+     unsigned char *to, RSA *rsa, int padding);
+
+=head1 DESCRIPTION
+
+RSA_public_encrypt() encrypts the B<flen> bytes at B<from> (usually a
+session key) using the public key B<rsa> and stores the ciphertext in
+B<to>. B<to> must point to RSA_size(B<rsa>) bytes of memory.
+
+B<padding> denotes one of the following modes:
+
+=over 4
+
+=item RSA_PKCS1_PADDING
+
+PKCS #1 v1.5 padding. This currently is the most widely used mode.
+
+=item RSA_PKCS1_OAEP_PADDING
+
+EME-OAEP as defined in PKCS #1 v2.0 with SHA-1, MGF1 and an empty
+encoding parameter. This mode is recommended for all new applications.
+
+=item RSA_SSLV23_PADDING
+
+PKCS #1 v1.5 padding with an SSL-specific modification that denotes
+that the server is SSL3 capable.
+
+=item RSA_NO_PADDING
+
+Raw RSA encryption. This mode should I<only> be used to implement
+cryptographically sound padding modes in the application code.
+Encrypting user data directly with RSA is insecure.
+
+=back
+
+B<flen> must be less than RSA_size(B<rsa>) - 11 for the PKCS #1 v1.5
+based padding modes, less than RSA_size(B<rsa>) - 41 for
+RSA_PKCS1_OAEP_PADDING and exactly RSA_size(B<rsa>) for RSA_NO_PADDING.
+The random number generator must be seeded prior to calling
+RSA_public_encrypt().
+
+RSA_private_decrypt() decrypts the B<flen> bytes at B<from> using the
+private key B<rsa> and stores the plaintext in B<to>. B<to> must point
+to a memory section large enough to hold the decrypted data (which is
+smaller than RSA_size(B<rsa>)). B<padding> is the padding mode that
+was used to encrypt the data.
+
+=head1 RETURN VALUES
+
+RSA_public_encrypt() returns the size of the encrypted data (i.e.,
+RSA_size(B<rsa>)). RSA_private_decrypt() returns the size of the
+recovered plaintext.
+
+On error, -1 is returned; the error codes can be
+obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 CONFORMING TO
+
+SSL, PKCS #1 v2.0
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>,
+L<RSA_size(3)|RSA_size(3)>
+
+=head1 HISTORY
+
+The B<padding> argument was added in SSLeay 0.8. RSA_NO_PADDING is
+available since SSLeay 0.9.0, OAEP was added in OpenSSL 0.9.2b.
+
+=cut
diff --git a/openssl/doc/crypto/RSA_set_method.pod b/openssl/doc/crypto/RSA_set_method.pod
new file mode 100644
index 0000000..2c963d7
--- /dev/null
+++ b/openssl/doc/crypto/RSA_set_method.pod
@@ -0,0 +1,202 @@
+=pod
+
+=head1 NAME
+
+RSA_set_default_method, RSA_get_default_method, RSA_set_method,
+RSA_get_method, RSA_PKCS1_SSLeay, RSA_null_method, RSA_flags,
+RSA_new_method - select RSA method
+
+=head1 SYNOPSIS
+
+ #include <openssl/rsa.h>
+
+ void RSA_set_default_method(const RSA_METHOD *meth);
+
+ RSA_METHOD *RSA_get_default_method(void);
+
+ int RSA_set_method(RSA *rsa, const RSA_METHOD *meth);
+
+ RSA_METHOD *RSA_get_method(const RSA *rsa);
+
+ RSA_METHOD *RSA_PKCS1_SSLeay(void);
+
+ RSA_METHOD *RSA_null_method(void);
+
+ int RSA_flags(const RSA *rsa);
+
+ RSA *RSA_new_method(RSA_METHOD *method);
+
+=head1 DESCRIPTION
+
+An B<RSA_METHOD> specifies the functions that OpenSSL uses for RSA
+operations. By modifying the method, alternative implementations such as
+hardware accelerators may be used. IMPORTANT: See the NOTES section for
+important information about how these RSA API functions are affected by the
+use of B<ENGINE> API calls.
+
+Initially, the default RSA_METHOD is the OpenSSL internal implementation,
+as returned by RSA_PKCS1_SSLeay().
+
+RSA_set_default_method() makes B<meth> the default method for all RSA
+structures created later. B<NB>: This is true only whilst no ENGINE has
+been set as a default for RSA, so this function is no longer recommended.
+
+RSA_get_default_method() returns a pointer to the current default
+RSA_METHOD. However, the meaningfulness of this result is dependent on
+whether the ENGINE API is being used, so this function is no longer 
+recommended.
+
+RSA_set_method() selects B<meth> to perform all operations using the key
+B<rsa>. This will replace the RSA_METHOD used by the RSA key and if the
+previous method was supplied by an ENGINE, the handle to that ENGINE will
+be released during the change. It is possible to have RSA keys that only
+work with certain RSA_METHOD implementations (eg. from an ENGINE module
+that supports embedded hardware-protected keys), and in such cases
+attempting to change the RSA_METHOD for the key can have unexpected
+results.
+
+RSA_get_method() returns a pointer to the RSA_METHOD being used by B<rsa>.
+This method may or may not be supplied by an ENGINE implementation, but if
+it is, the return value can only be guaranteed to be valid as long as the
+RSA key itself is valid and does not have its implementation changed by
+RSA_set_method().
+
+RSA_flags() returns the B<flags> that are set for B<rsa>'s current
+RSA_METHOD. See the BUGS section.
+
+RSA_new_method() allocates and initializes an RSA structure so that
+B<engine> will be used for the RSA operations. If B<engine> is NULL, the
+default ENGINE for RSA operations is used, and if no default ENGINE is set,
+the RSA_METHOD controlled by RSA_set_default_method() is used.
+
+RSA_flags() returns the B<flags> that are set for B<rsa>'s current method.
+
+RSA_new_method() allocates and initializes an B<RSA> structure so that
+B<method> will be used for the RSA operations. If B<method> is B<NULL>,
+the default method is used.
+
+=head1 THE RSA_METHOD STRUCTURE
+
+ typedef struct rsa_meth_st
+ {
+     /* name of the implementation */
+	const char *name;
+
+     /* encrypt */
+	int (*rsa_pub_enc)(int flen, unsigned char *from,
+          unsigned char *to, RSA *rsa, int padding);
+
+     /* verify arbitrary data */
+	int (*rsa_pub_dec)(int flen, unsigned char *from,
+          unsigned char *to, RSA *rsa, int padding);
+
+     /* sign arbitrary data */
+	int (*rsa_priv_enc)(int flen, unsigned char *from,
+          unsigned char *to, RSA *rsa, int padding);
+
+     /* decrypt */
+	int (*rsa_priv_dec)(int flen, unsigned char *from,
+          unsigned char *to, RSA *rsa, int padding);
+
+     /* compute r0 = r0 ^ I mod rsa->n (May be NULL for some
+                                        implementations) */
+	int (*rsa_mod_exp)(BIGNUM *r0, BIGNUM *I, RSA *rsa);
+
+     /* compute r = a ^ p mod m (May be NULL for some implementations) */
+	int (*bn_mod_exp)(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+          const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+
+     /* called at RSA_new */
+	int (*init)(RSA *rsa);
+
+     /* called at RSA_free */
+	int (*finish)(RSA *rsa);
+
+     /* RSA_FLAG_EXT_PKEY        - rsa_mod_exp is called for private key
+      *                            operations, even if p,q,dmp1,dmq1,iqmp
+      *                            are NULL
+      * RSA_FLAG_SIGN_VER        - enable rsa_sign and rsa_verify
+      * RSA_METHOD_FLAG_NO_CHECK - don't check pub/private match
+      */
+	int flags;
+
+	char *app_data; /* ?? */
+
+     /* sign. For backward compatibility, this is used only
+      * if (flags & RSA_FLAG_SIGN_VER)
+      */
+	int (*rsa_sign)(int type, unsigned char *m, unsigned int m_len,
+           unsigned char *sigret, unsigned int *siglen, RSA *rsa);
+
+     /* verify. For backward compatibility, this is used only
+      * if (flags & RSA_FLAG_SIGN_VER)
+      */
+	int (*rsa_verify)(int type, unsigned char *m, unsigned int m_len,
+           unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
+
+ } RSA_METHOD;
+
+=head1 RETURN VALUES
+
+RSA_PKCS1_SSLeay(), RSA_PKCS1_null_method(), RSA_get_default_method()
+and RSA_get_method() return pointers to the respective RSA_METHODs.
+
+RSA_set_default_method() returns no value.
+
+RSA_set_method() returns a pointer to the old RSA_METHOD implementation
+that was replaced. However, this return value should probably be ignored
+because if it was supplied by an ENGINE, the pointer could be invalidated
+at any time if the ENGINE is unloaded (in fact it could be unloaded as a
+result of the RSA_set_method() function releasing its handle to the
+ENGINE). For this reason, the return type may be replaced with a B<void>
+declaration in a future release.
+
+RSA_new_method() returns NULL and sets an error code that can be obtained
+by L<ERR_get_error(3)|ERR_get_error(3)> if the allocation fails. Otherwise
+it returns a pointer to the newly allocated structure.
+
+=head1 NOTES
+
+As of version 0.9.7, RSA_METHOD implementations are grouped together with
+other algorithmic APIs (eg. DSA_METHOD, EVP_CIPHER, etc) into B<ENGINE>
+modules. If a default ENGINE is specified for RSA functionality using an
+ENGINE API function, that will override any RSA defaults set using the RSA
+API (ie.  RSA_set_default_method()). For this reason, the ENGINE API is the
+recommended way to control default implementations for use in RSA and other
+cryptographic algorithms.
+
+=head1 BUGS
+
+The behaviour of RSA_flags() is a mis-feature that is left as-is for now
+to avoid creating compatibility problems. RSA functionality, such as the
+encryption functions, are controlled by the B<flags> value in the RSA key
+itself, not by the B<flags> value in the RSA_METHOD attached to the RSA key
+(which is what this function returns). If the flags element of an RSA key
+is changed, the changes will be honoured by RSA functionality but will not
+be reflected in the return value of the RSA_flags() function - in effect
+RSA_flags() behaves more like an RSA_default_flags() function (which does
+not currently exist).
+
+=head1 SEE ALSO
+
+L<rsa(3)|rsa(3)>, L<RSA_new(3)|RSA_new(3)>
+
+=head1 HISTORY
+
+RSA_new_method() and RSA_set_default_method() appeared in SSLeay 0.8.
+RSA_get_default_method(), RSA_set_method() and RSA_get_method() as
+well as the rsa_sign and rsa_verify components of RSA_METHOD were
+added in OpenSSL 0.9.4.
+
+RSA_set_default_openssl_method() and RSA_get_default_openssl_method()
+replaced RSA_set_default_method() and RSA_get_default_method()
+respectively, and RSA_set_method() and RSA_new_method() were altered to use
+B<ENGINE>s rather than B<RSA_METHOD>s during development of the engine
+version of OpenSSL 0.9.6. For 0.9.7, the handling of defaults in the ENGINE
+API was restructured so that this change was reversed, and behaviour of the
+other functions resembled more closely the previous behaviour. The
+behaviour of defaults in the ENGINE API now transparently overrides the
+behaviour of defaults in the RSA API without requiring changing these
+function prototypes.
+
+=cut
diff --git a/openssl/doc/crypto/RSA_sign.pod b/openssl/doc/crypto/RSA_sign.pod
new file mode 100644
index 0000000..8553be8
--- /dev/null
+++ b/openssl/doc/crypto/RSA_sign.pod
@@ -0,0 +1,62 @@
+=pod
+
+=head1 NAME
+
+RSA_sign, RSA_verify - RSA signatures
+
+=head1 SYNOPSIS
+
+ #include <openssl/rsa.h>
+
+ int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
+    unsigned char *sigret, unsigned int *siglen, RSA *rsa);
+
+ int RSA_verify(int type, const unsigned char *m, unsigned int m_len,
+    unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
+
+=head1 DESCRIPTION
+
+RSA_sign() signs the message digest B<m> of size B<m_len> using the
+private key B<rsa> as specified in PKCS #1 v2.0. It stores the
+signature in B<sigret> and the signature size in B<siglen>. B<sigret>
+must point to RSA_size(B<rsa>) bytes of memory.
+
+B<type> denotes the message digest algorithm that was used to generate
+B<m>. It usually is one of B<NID_sha1>, B<NID_ripemd160> and B<NID_md5>;
+see L<objects(3)|objects(3)> for details. If B<type> is B<NID_md5_sha1>,
+an SSL signature (MD5 and SHA1 message digests with PKCS #1 padding
+and no algorithm identifier) is created.
+
+RSA_verify() verifies that the signature B<sigbuf> of size B<siglen>
+matches a given message digest B<m> of size B<m_len>. B<type> denotes
+the message digest algorithm that was used to generate the signature.
+B<rsa> is the signer's public key.
+
+=head1 RETURN VALUES
+
+RSA_sign() returns 1 on success, 0 otherwise.  RSA_verify() returns 1
+on successful verification, 0 otherwise.
+
+The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 BUGS
+
+Certain signatures with an improper algorithm identifier are accepted
+for compatibility with SSLeay 0.4.5 :-)
+
+=head1 CONFORMING TO
+
+SSL, PKCS #1 v2.0
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<objects(3)|objects(3)>,
+L<rsa(3)|rsa(3)>, L<RSA_private_encrypt(3)|RSA_private_encrypt(3)>,
+L<RSA_public_decrypt(3)|RSA_public_decrypt(3)> 
+
+=head1 HISTORY
+
+RSA_sign() and RSA_verify() are available in all versions of SSLeay
+and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/RSA_sign_ASN1_OCTET_STRING.pod b/openssl/doc/crypto/RSA_sign_ASN1_OCTET_STRING.pod
new file mode 100644
index 0000000..e70380b
--- /dev/null
+++ b/openssl/doc/crypto/RSA_sign_ASN1_OCTET_STRING.pod
@@ -0,0 +1,59 @@
+=pod
+
+=head1 NAME
+
+RSA_sign_ASN1_OCTET_STRING, RSA_verify_ASN1_OCTET_STRING - RSA signatures
+
+=head1 SYNOPSIS
+
+ #include <openssl/rsa.h>
+
+ int RSA_sign_ASN1_OCTET_STRING(int dummy, unsigned char *m,
+    unsigned int m_len, unsigned char *sigret, unsigned int *siglen,
+    RSA *rsa);
+
+ int RSA_verify_ASN1_OCTET_STRING(int dummy, unsigned char *m,
+    unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
+    RSA *rsa);
+
+=head1 DESCRIPTION
+
+RSA_sign_ASN1_OCTET_STRING() signs the octet string B<m> of size
+B<m_len> using the private key B<rsa> represented in DER using PKCS #1
+padding. It stores the signature in B<sigret> and the signature size
+in B<siglen>. B<sigret> must point to B<RSA_size(rsa)> bytes of
+memory.
+
+B<dummy> is ignored.
+
+The random number generator must be seeded prior to calling RSA_sign_ASN1_OCTET_STRING().
+
+RSA_verify_ASN1_OCTET_STRING() verifies that the signature B<sigbuf>
+of size B<siglen> is the DER representation of a given octet string
+B<m> of size B<m_len>. B<dummy> is ignored. B<rsa> is the signer's
+public key.
+
+=head1 RETURN VALUES
+
+RSA_sign_ASN1_OCTET_STRING() returns 1 on success, 0 otherwise.
+RSA_verify_ASN1_OCTET_STRING() returns 1 on successful verification, 0
+otherwise.
+
+The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 BUGS
+
+These functions serve no recognizable purpose.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<objects(3)|objects(3)>,
+L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>, L<RSA_sign(3)|RSA_sign(3)>,
+L<RSA_verify(3)|RSA_verify(3)>
+
+=head1 HISTORY
+
+RSA_sign_ASN1_OCTET_STRING() and RSA_verify_ASN1_OCTET_STRING() were
+added in SSLeay 0.8.
+
+=cut
diff --git a/openssl/doc/crypto/RSA_size.pod b/openssl/doc/crypto/RSA_size.pod
new file mode 100644
index 0000000..5b7f835
--- /dev/null
+++ b/openssl/doc/crypto/RSA_size.pod
@@ -0,0 +1,33 @@
+=pod
+
+=head1 NAME
+
+RSA_size - get RSA modulus size
+
+=head1 SYNOPSIS
+
+ #include <openssl/rsa.h>
+
+ int RSA_size(const RSA *rsa);
+
+=head1 DESCRIPTION
+
+This function returns the RSA modulus size in bytes. It can be used to
+determine how much memory must be allocated for an RSA encrypted
+value.
+
+B<rsa-E<gt>n> must not be B<NULL>.
+
+=head1 RETURN VALUE
+
+The size in bytes.
+
+=head1 SEE ALSO
+
+L<rsa(3)|rsa(3)>
+
+=head1 HISTORY
+
+RSA_size() is available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/SMIME_read_CMS.pod b/openssl/doc/crypto/SMIME_read_CMS.pod
new file mode 100644
index 0000000..acc5524
--- /dev/null
+++ b/openssl/doc/crypto/SMIME_read_CMS.pod
@@ -0,0 +1,70 @@
+=pod
+
+=head1 NAME
+
+ SMIME_read_CMS - parse S/MIME message.
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ CMS_ContentInfo *SMIME_read_CMS(BIO *in, BIO **bcont);
+
+=head1 DESCRIPTION
+
+SMIME_read_CMS() parses a message in S/MIME format.
+
+B<in> is a BIO to read the message from.
+
+If cleartext signing is used then the content is saved in a memory bio which is
+written to B<*bcont>, otherwise B<*bcont> is set to NULL.
+
+The parsed CMS_ContentInfo structure is returned or NULL if an
+error occurred.
+
+=head1 NOTES
+
+If B<*bcont> is not NULL then the message is clear text signed. B<*bcont> can
+then be passed to CMS_verify() with the B<CMS_DETACHED> flag set.
+
+Otherwise the type of the returned structure can be determined
+using CMS_get0_type().
+
+To support future functionality if B<bcont> is not NULL B<*bcont> should be
+initialized to NULL. For example:
+
+ BIO *cont = NULL;
+ CMS_ContentInfo *cms;
+
+ cms = SMIME_read_CMS(in, &cont);
+
+=head1 BUGS
+
+The MIME parser used by SMIME_read_CMS() is somewhat primitive.  While it will
+handle most S/MIME messages more complex compound formats may not work.
+
+The parser assumes that the CMS_ContentInfo structure is always base64 encoded
+and will not handle the case where it is in binary format or uses quoted
+printable format.
+
+The use of a memory BIO to hold the signed content limits the size of message
+which can be processed due to memory restraints: a streaming single pass option
+should be available.
+
+=head1 RETURN VALUES
+
+SMIME_read_CMS() returns a valid B<CMS_ContentInfo> structure or B<NULL>
+if an error occurred. The error can be obtained from ERR_get_error(3).
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_type(3)|CMS_type(3)>
+L<SMIME_read_CMS(3)|SMIME_read_CMS(3)>, L<CMS_sign(3)|CMS_sign(3)>,
+L<CMS_verify(3)|CMS_verify(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)>
+L<CMS_decrypt(3)|CMS_decrypt(3)>
+
+=head1 HISTORY
+
+SMIME_read_CMS() was added to OpenSSL 0.9.8
+
+=cut
diff --git a/openssl/doc/crypto/SMIME_read_PKCS7.pod b/openssl/doc/crypto/SMIME_read_PKCS7.pod
new file mode 100644
index 0000000..9d46715
--- /dev/null
+++ b/openssl/doc/crypto/SMIME_read_PKCS7.pod
@@ -0,0 +1,73 @@
+=pod
+
+=head1 NAME
+
+SMIME_read_PKCS7 - parse S/MIME message.
+
+=head1 SYNOPSIS
+
+ #include <openssl/pkcs7.h>
+
+ PKCS7 *SMIME_read_PKCS7(BIO *in, BIO **bcont);
+
+=head1 DESCRIPTION
+
+SMIME_read_PKCS7() parses a message in S/MIME format.
+
+B<in> is a BIO to read the message from.
+
+If cleartext signing is used then the content is saved in
+a memory bio which is written to B<*bcont>, otherwise
+B<*bcont> is set to B<NULL>.
+
+The parsed PKCS#7 structure is returned or B<NULL> if an
+error occurred.
+
+=head1 NOTES
+
+If B<*bcont> is not B<NULL> then the message is clear text
+signed. B<*bcont> can then be passed to PKCS7_verify() with
+the B<PKCS7_DETACHED> flag set.
+
+Otherwise the type of the returned structure can be determined
+using PKCS7_type().
+
+To support future functionality if B<bcont> is not B<NULL>
+B<*bcont> should be initialized to B<NULL>. For example:
+
+ BIO *cont = NULL;
+ PKCS7 *p7;
+
+ p7 = SMIME_read_PKCS7(in, &cont);
+
+=head1 BUGS
+
+The MIME parser used by SMIME_read_PKCS7() is somewhat primitive.
+While it will handle most S/MIME messages more complex compound
+formats may not work.
+
+The parser assumes that the PKCS7 structure is always base64
+encoded and will not handle the case where it is in binary format
+or uses quoted printable format.
+
+The use of a memory BIO to hold the signed content limits the size
+of message which can be processed due to memory restraints: a
+streaming single pass option should be available.
+
+=head1 RETURN VALUES
+
+SMIME_read_PKCS7() returns a valid B<PKCS7> structure or B<NULL>
+is an error occurred. The error can be obtained from ERR_get_error(3).
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_type(3)|PKCS7_type(3)>
+L<SMIME_read_PKCS7(3)|SMIME_read_PKCS7(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>,
+L<PKCS7_verify(3)|PKCS7_verify(3)>, L<PKCS7_encrypt(3)|PKCS7_encrypt(3)>
+L<PKCS7_decrypt(3)|PKCS7_decrypt(3)>
+
+=head1 HISTORY
+
+SMIME_read_PKCS7() was added to OpenSSL 0.9.5
+
+=cut
diff --git a/openssl/doc/crypto/SMIME_write_CMS.pod b/openssl/doc/crypto/SMIME_write_CMS.pod
new file mode 100644
index 0000000..04bedfb
--- /dev/null
+++ b/openssl/doc/crypto/SMIME_write_CMS.pod
@@ -0,0 +1,64 @@
+=pod
+
+=head1 NAME
+
+ SMIME_write_CMS - convert CMS structure to S/MIME format.
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ int SMIME_write_CMS(BIO *out, CMS_ContentInfo *cms, BIO *data, int flags);
+
+=head1 DESCRIPTION
+
+SMIME_write_CMS() adds the appropriate MIME headers to a CMS
+structure to produce an S/MIME message.
+
+B<out> is the BIO to write the data to. B<cms> is the appropriate
+B<CMS_ContentInfo> structure. If streaming is enabled then the content must be
+supplied in the B<data> argument. B<flags> is an optional set of flags.
+
+=head1 NOTES
+
+The following flags can be passed in the B<flags> parameter.
+
+If B<CMS_DETACHED> is set then cleartext signing will be used, this option only
+makes sense for SignedData where B<CMS_DETACHED> is also set when CMS_sign() is
+called.
+
+If the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are added to
+the content, this only makes sense if B<CMS_DETACHED> is also set.
+
+If the B<CMS_STREAM> flag is set streaming is performed. This flag should only
+be set if B<CMS_STREAM> was also set in the previous call to a CMS_ContentInfo
+creation function.
+
+If cleartext signing is being used and B<CMS_STREAM> not set then the data must
+be read twice: once to compute the signature in CMS_sign() and once to output
+the S/MIME message.
+
+If streaming is performed the content is output in BER format using indefinite
+length constructed encoding except in the case of signed data with detached
+content where the content is absent and DER format is used.
+
+=head1 BUGS
+
+SMIME_write_CMS() always base64 encodes CMS structures, there should be an
+option to disable this.
+
+=head1 RETURN VALUES
+
+SMIME_write_CMS() returns 1 for success or 0 for failure.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
+L<CMS_verify(3)|CMS_verify(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)>
+L<CMS_decrypt(3)|CMS_decrypt(3)>
+
+=head1 HISTORY
+
+SMIME_write_CMS() was added to OpenSSL 0.9.8
+
+=cut
diff --git a/openssl/doc/crypto/SMIME_write_PKCS7.pod b/openssl/doc/crypto/SMIME_write_PKCS7.pod
new file mode 100644
index 0000000..ca6bd02
--- /dev/null
+++ b/openssl/doc/crypto/SMIME_write_PKCS7.pod
@@ -0,0 +1,65 @@
+=pod
+
+=head1 NAME
+
+SMIME_write_PKCS7 - convert PKCS#7 structure to S/MIME format.
+
+=head1 SYNOPSIS
+
+ #include <openssl/pkcs7.h>
+
+ int SMIME_write_PKCS7(BIO *out, PKCS7 *p7, BIO *data, int flags);
+
+=head1 DESCRIPTION
+
+SMIME_write_PKCS7() adds the appropriate MIME headers to a PKCS#7
+structure to produce an S/MIME message.
+
+B<out> is the BIO to write the data to. B<p7> is the appropriate B<PKCS7>
+structure. If streaming is enabled then the content must be supplied in the
+B<data> argument. B<flags> is an optional set of flags.
+
+=head1 NOTES
+
+The following flags can be passed in the B<flags> parameter.
+
+If B<PKCS7_DETACHED> is set then cleartext signing will be used,
+this option only makes sense for signedData where B<PKCS7_DETACHED>
+is also set when PKCS7_sign() is also called.
+
+If the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain>
+are added to the content, this only makes sense if B<PKCS7_DETACHED>
+is also set.
+
+If the B<PKCS7_STREAM> flag is set streaming is performed. This flag should
+only be set if B<PKCS7_STREAM> was also set in the previous call to
+PKCS7_sign() or B<PKCS7_encrypt()>.
+
+If cleartext signing is being used and B<PKCS7_STREAM> not set then
+the data must be read twice: once to compute the signature in PKCS7_sign()
+and once to output the S/MIME message.
+
+If streaming is performed the content is output in BER format using indefinite
+length constructuted encoding except in the case of signed data with detached
+content where the content is absent and DER format is used.
+
+=head1 BUGS
+
+SMIME_write_PKCS7() always base64 encodes PKCS#7 structures, there
+should be an option to disable this.
+
+=head1 RETURN VALUES
+
+SMIME_write_PKCS7() returns 1 for success or 0 for failure.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>,
+L<PKCS7_verify(3)|PKCS7_verify(3)>, L<PKCS7_encrypt(3)|PKCS7_encrypt(3)>
+L<PKCS7_decrypt(3)|PKCS7_decrypt(3)>
+
+=head1 HISTORY
+
+SMIME_write_PKCS7() was added to OpenSSL 0.9.5
+
+=cut
diff --git a/openssl/doc/crypto/X509_NAME_ENTRY_get_object.pod b/openssl/doc/crypto/X509_NAME_ENTRY_get_object.pod
new file mode 100644
index 0000000..41902c0
--- /dev/null
+++ b/openssl/doc/crypto/X509_NAME_ENTRY_get_object.pod
@@ -0,0 +1,74 @@
+=pod
+
+=head1 NAME
+
+X509_NAME_ENTRY_get_object, X509_NAME_ENTRY_get_data,
+X509_NAME_ENTRY_set_object, X509_NAME_ENTRY_set_data,
+X509_NAME_ENTRY_create_by_txt, X509_NAME_ENTRY_create_by_NID,
+X509_NAME_ENTRY_create_by_OBJ - X509_NAME_ENTRY utility functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509.h>
+
+ ASN1_OBJECT * X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
+ ASN1_STRING * X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
+
+ int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj);
+ int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, const unsigned char *bytes, int len);
+
+ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, const char *field, int type, const unsigned char *bytes, int len);
+ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, int type,unsigned char *bytes, int len);
+ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len);
+
+=head1 DESCRIPTION
+
+X509_NAME_ENTRY_get_object() retrieves the field name of B<ne> in
+and B<ASN1_OBJECT> structure.
+
+X509_NAME_ENTRY_get_data() retrieves the field value of B<ne> in
+and B<ASN1_STRING> structure.
+
+X509_NAME_ENTRY_set_object() sets the field name of B<ne> to B<obj>.
+
+X509_NAME_ENTRY_set_data() sets the field value of B<ne> to string type
+B<type> and value determined by B<bytes> and B<len>.
+
+X509_NAME_ENTRY_create_by_txt(), X509_NAME_ENTRY_create_by_NID()
+and X509_NAME_ENTRY_create_by_OBJ() create and return an 
+B<X509_NAME_ENTRY> structure.
+
+=head1 NOTES
+
+X509_NAME_ENTRY_get_object() and X509_NAME_ENTRY_get_data() can be
+used to examine an B<X509_NAME_ENTRY> function as returned by 
+X509_NAME_get_entry() for example.
+
+X509_NAME_ENTRY_create_by_txt(), X509_NAME_ENTRY_create_by_NID(),
+and X509_NAME_ENTRY_create_by_OBJ() create and return an 
+
+X509_NAME_ENTRY_create_by_txt(), X509_NAME_ENTRY_create_by_OBJ(),
+X509_NAME_ENTRY_create_by_NID() and X509_NAME_ENTRY_set_data()
+are seldom used in practice because B<X509_NAME_ENTRY> structures
+are almost always part of B<X509_NAME> structures and the
+corresponding B<X509_NAME> functions are typically used to
+create and add new entries in a single operation.
+
+The arguments of these functions support similar options to the similarly
+named ones of the corresponding B<X509_NAME> functions such as
+X509_NAME_add_entry_by_txt(). So for example B<type> can be set to
+B<MBSTRING_ASC> but in the case of X509_set_data() the field name must be
+set first so the relevant field information can be looked up internally.
+
+=head1 RETURN VALUES
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<d2i_X509_NAME(3)|d2i_X509_NAME(3)>,
+L<OBJ_nid2obj(3),OBJ_nid2obj(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/X509_NAME_add_entry_by_txt.pod b/openssl/doc/crypto/X509_NAME_add_entry_by_txt.pod
new file mode 100644
index 0000000..1afd008
--- /dev/null
+++ b/openssl/doc/crypto/X509_NAME_add_entry_by_txt.pod
@@ -0,0 +1,116 @@
+=pod
+
+=head1 NAME
+
+X509_NAME_add_entry_by_txt, X509_NAME_add_entry_by_OBJ, X509_NAME_add_entry_by_NID,
+X509_NAME_add_entry, X509_NAME_delete_entry - X509_NAME modification functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509.h>
+
+ int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, const unsigned char *bytes, int len, int loc, int set);
+
+ int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, unsigned char *bytes, int len, int loc, int set);
+
+ int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, unsigned char *bytes, int len, int loc, int set);
+
+ int X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne, int loc, int set);
+
+ X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
+
+=head1 DESCRIPTION
+
+X509_NAME_add_entry_by_txt(), X509_NAME_add_entry_by_OBJ() and
+X509_NAME_add_entry_by_NID() add a field whose name is defined
+by a string B<field>, an object B<obj> or a NID B<nid> respectively.
+The field value to be added is in B<bytes> of length B<len>. If
+B<len> is -1 then the field length is calculated internally using
+strlen(bytes).
+
+The type of field is determined by B<type> which can either be a
+definition of the type of B<bytes> (such as B<MBSTRING_ASC>) or a
+standard ASN1 type (such as B<V_ASN1_IA5STRING>). The new entry is
+added to a position determined by B<loc> and B<set>.
+
+X509_NAME_add_entry() adds a copy of B<X509_NAME_ENTRY> structure B<ne>
+to B<name>. The new entry is added to a position determined by B<loc>
+and B<set>. Since a copy of B<ne> is added B<ne> must be freed up after
+the call.
+
+X509_NAME_delete_entry() deletes an entry from B<name> at position
+B<loc>. The deleted entry is returned and must be freed up.
+
+=head1 NOTES
+
+The use of string types such as B<MBSTRING_ASC> or B<MBSTRING_UTF8>
+is strongly recommened for the B<type> parameter. This allows the
+internal code to correctly determine the type of the field and to
+apply length checks according to the relevant standards. This is
+done using ASN1_STRING_set_by_NID().
+
+If instead an ASN1 type is used no checks are performed and the
+supplied data in B<bytes> is used directly.
+
+In X509_NAME_add_entry_by_txt() the B<field> string represents
+the field name using OBJ_txt2obj(field, 0).
+
+The B<loc> and B<set> parameters determine where a new entry should
+be added. For almost all applications B<loc> can be set to -1 and B<set>
+to 0. This adds a new entry to the end of B<name> as a single valued
+RelativeDistinguishedName (RDN).
+
+B<loc> actually determines the index where the new entry is inserted:
+if it is -1 it is appended. 
+
+B<set> determines how the new type is added. If it is zero a
+new RDN is created.
+
+If B<set> is -1 or 1 it is added to the previous or next RDN
+structure respectively. This will then be a multivalued RDN:
+since multivalues RDNs are very seldom used B<set> is almost
+always set to zero.
+
+=head1 EXAMPLES
+
+Create an B<X509_NAME> structure:
+
+"C=UK, O=Disorganized Organization, CN=Joe Bloggs"
+
+ X509_NAME *nm;
+ nm = X509_NAME_new();
+ if (nm == NULL)
+	/* Some error */
+ if (!X509_NAME_add_entry_by_txt(nm, MBSTRING_ASC,
+			"C", "UK", -1, -1, 0))
+	/* Error */
+ if (!X509_NAME_add_entry_by_txt(nm, MBSTRING_ASC,
+			"O", "Disorganized Organization", -1, -1, 0))
+	/* Error */
+ if (!X509_NAME_add_entry_by_txt(nm, MBSTRING_ASC,
+			"CN", "Joe Bloggs", -1, -1, 0))
+	/* Error */
+
+=head1 RETURN VALUES
+
+X509_NAME_add_entry_by_txt(), X509_NAME_add_entry_by_OBJ(),
+X509_NAME_add_entry_by_NID() and X509_NAME_add_entry() return 1 for
+success of 0 if an error occurred.
+
+X509_NAME_delete_entry() returns either the deleted B<X509_NAME_ENTRY>
+structure of B<NULL> if an error occurred.
+
+=head1 BUGS
+
+B<type> can still be set to B<V_ASN1_APP_CHOOSE> to use a
+different algorithm to determine field types. Since this form does
+not understand multicharacter types, performs no length checks and
+can result in invalid field types its use is strongly discouraged.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<d2i_X509_NAME(3)|d2i_X509_NAME(3)>
+
+=head1 HISTORY
+
+=cut
diff --git a/openssl/doc/crypto/X509_NAME_get_index_by_NID.pod b/openssl/doc/crypto/X509_NAME_get_index_by_NID.pod
new file mode 100644
index 0000000..3b1f9ff
--- /dev/null
+++ b/openssl/doc/crypto/X509_NAME_get_index_by_NID.pod
@@ -0,0 +1,108 @@
+=pod
+
+=head1 NAME
+
+X509_NAME_get_index_by_NID, X509_NAME_get_index_by_OBJ, X509_NAME_get_entry,
+X509_NAME_entry_count, X509_NAME_get_text_by_NID, X509_NAME_get_text_by_OBJ -
+X509_NAME lookup and enumeration functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509.h>
+
+ int X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos);
+ int X509_NAME_get_index_by_OBJ(X509_NAME *name,ASN1_OBJECT *obj, int lastpos);
+
+ int X509_NAME_entry_count(X509_NAME *name);
+ X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
+
+ int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf,int len);
+ int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf,int len);
+
+=head1 DESCRIPTION
+
+These functions allow an B<X509_NAME> structure to be examined. The
+B<X509_NAME> structure is the same as the B<Name> type defined in
+RFC2459 (and elsewhere) and used for example in certificate subject
+and issuer names.
+
+X509_NAME_get_index_by_NID() and X509_NAME_get_index_by_OBJ() retrieve
+the next index matching B<nid> or B<obj> after B<lastpos>. B<lastpos>
+should initially be set to -1. If there are no more entries -1 is returned.
+
+X509_NAME_entry_count() returns the total number of entries in B<name>.
+
+X509_NAME_get_entry() retrieves the B<X509_NAME_ENTRY> from B<name>
+corresponding to index B<loc>. Acceptable values for B<loc> run from
+0 to (X509_NAME_entry_count(name) - 1). The value returned is an
+internal pointer which must not be freed.
+
+X509_NAME_get_text_by_NID(), X509_NAME_get_text_by_OBJ() retrieve
+the "text" from the first entry in B<name> which matches B<nid> or
+B<obj>, if no such entry exists -1 is returned. At most B<len> bytes
+will be written and the text written to B<buf> will be null
+terminated. The length of the output string written is returned
+excluding the terminating null. If B<buf> is <NULL> then the amount
+of space needed in B<buf> (excluding the final null) is returned. 
+
+=head1 NOTES
+
+X509_NAME_get_text_by_NID() and X509_NAME_get_text_by_OBJ() are
+legacy functions which have various limitations which make them
+of minimal use in practice. They can only find the first matching
+entry and will copy the contents of the field verbatim: this can
+be highly confusing if the target is a muticharacter string type
+like a BMPString or a UTF8String.
+
+For a more general solution X509_NAME_get_index_by_NID() or
+X509_NAME_get_index_by_OBJ() should be used followed by
+X509_NAME_get_entry() on any matching indices and then the
+various B<X509_NAME_ENTRY> utility functions on the result.
+
+=head1 EXAMPLES
+
+Process all entries:
+
+ int i;
+ X509_NAME_ENTRY *e;
+
+ for (i = 0; i < X509_NAME_entry_count(nm); i++)
+	{
+	e = X509_NAME_get_entry(nm, i);
+	/* Do something with e */
+	}
+
+Process all commonName entries:
+
+ int loc;
+ X509_NAME_ENTRY *e;
+
+ loc = -1;
+ for (;;)
+	{
+	lastpos = X509_NAME_get_index_by_NID(nm, NID_commonName, lastpos);
+	if (lastpos == -1)
+		break;
+	e = X509_NAME_get_entry(nm, lastpos);
+	/* Do something with e */
+	}
+
+=head1 RETURN VALUES
+
+X509_NAME_get_index_by_NID() and X509_NAME_get_index_by_OBJ()
+return the index of the next matching entry or -1 if not found.
+
+X509_NAME_entry_count() returns the total number of entries.
+
+X509_NAME_get_entry() returns an B<X509_NAME> pointer to the
+requested entry or B<NULL> if the index is invalid.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<d2i_X509_NAME(3)|d2i_X509_NAME(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/X509_NAME_print_ex.pod b/openssl/doc/crypto/X509_NAME_print_ex.pod
new file mode 100644
index 0000000..2579a5d
--- /dev/null
+++ b/openssl/doc/crypto/X509_NAME_print_ex.pod
@@ -0,0 +1,105 @@
+=pod
+
+=head1 NAME
+
+X509_NAME_print_ex, X509_NAME_print_ex_fp, X509_NAME_print,
+X509_NAME_oneline - X509_NAME printing routines.
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509.h>
+
+ int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags);
+ int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags);
+ char *	X509_NAME_oneline(X509_NAME *a,char *buf,int size);
+ int X509_NAME_print(BIO *bp, X509_NAME *name, int obase);
+
+=head1 DESCRIPTION
+
+X509_NAME_print_ex() prints a human readable version of B<nm> to BIO B<out>. Each
+line (for multiline formats) is indented by B<indent> spaces. The output format
+can be extensively customised by use of the B<flags> parameter.
+
+X509_NAME_print_ex_fp() is identical to X509_NAME_print_ex() except the output is
+written to FILE pointer B<fp>.
+
+X509_NAME_oneline() prints an ASCII version of B<a> to B<buf>. At most B<size>
+bytes will be written. If B<buf> is B<NULL> then a buffer is dynamically allocated
+and returned, otherwise B<buf> is returned.
+
+X509_NAME_print() prints out B<name> to B<bp> indenting each line by B<obase> 
+characters. Multiple lines are used if the output (including indent) exceeds
+80 characters.
+
+=head1 NOTES
+
+The functions X509_NAME_oneline() and X509_NAME_print() are legacy functions which
+produce a non standard output form, they don't handle multi character fields and
+have various quirks and inconsistencies. Their use is strongly discouraged in new
+applications.
+
+Although there are a large number of possible flags for most purposes
+B<XN_FLAG_ONELINE>, B<XN_FLAG_MULTILINE> or B<XN_FLAG_RFC2253> will suffice.
+As noted on the L<ASN1_STRING_print_ex(3)|ASN1_STRING_print_ex(3)> manual page
+for UTF8 terminals the B<ASN1_STRFLGS_ESC_MSB> should be unset: so for example
+B<XN_FLAG_ONELINE & ~ASN1_STRFLGS_ESC_MSB> would be used.
+
+The complete set of the flags supported by X509_NAME_print_ex() is listed below.
+
+Several options can be ored together.
+
+The options B<XN_FLAG_SEP_COMMA_PLUS>, B<XN_FLAG_SEP_CPLUS_SPC>,
+B<XN_FLAG_SEP_SPLUS_SPC> and B<XN_FLAG_SEP_MULTILINE> determine the field separators
+to use. Two distinct separators are used between distinct RelativeDistinguishedName
+components and separate values in the same RDN for a multi-valued RDN. Multi-valued
+RDNs are currently very rare so the second separator will hardly ever be used.
+
+B<XN_FLAG_SEP_COMMA_PLUS> uses comma and plus as separators. B<XN_FLAG_SEP_CPLUS_SPC>
+uses comma and plus with spaces: this is more readable that plain comma and plus.
+B<XN_FLAG_SEP_SPLUS_SPC> uses spaced semicolon and plus. B<XN_FLAG_SEP_MULTILINE> uses
+spaced newline and plus respectively.
+
+If B<XN_FLAG_DN_REV> is set the whole DN is printed in reversed order.
+
+The fields B<XN_FLAG_FN_SN>, B<XN_FLAG_FN_LN>, B<XN_FLAG_FN_OID>,
+B<XN_FLAG_FN_NONE> determine how a field name is displayed. It will
+use the short name (e.g. CN) the long name (e.g. commonName) always
+use OID numerical form (normally OIDs are only used if the field name is not
+recognised) and no field name respectively.
+
+If B<XN_FLAG_SPC_EQ> is set then spaces will be placed around the '=' character
+separating field names and values.
+
+If B<XN_FLAG_DUMP_UNKNOWN_FIELDS> is set then the encoding of unknown fields is
+printed instead of the values.
+
+If B<XN_FLAG_FN_ALIGN> is set then field names are padded to 20 characters: this
+is only of use for multiline format.
+
+Additionally all the options supported by ASN1_STRING_print_ex() can be used to 
+control how each field value is displayed.
+
+In addition a number options can be set for commonly used formats.
+
+B<XN_FLAG_RFC2253> sets options which produce an output compatible with RFC2253 it
+is equivalent to:
+ B<ASN1_STRFLGS_RFC2253 | XN_FLAG_SEP_COMMA_PLUS | XN_FLAG_DN_REV | XN_FLAG_FN_SN | XN_FLAG_DUMP_UNKNOWN_FIELDS>
+
+
+B<XN_FLAG_ONELINE> is a more readable one line format which is the same as:
+ B<ASN1_STRFLGS_RFC2253 | ASN1_STRFLGS_ESC_QUOTE | XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_SPC_EQ | XN_FLAG_FN_SN>
+
+B<XN_FLAG_MULTILINE> is a multiline format which is the same as:
+ B<ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB | XN_FLAG_SEP_MULTILINE | XN_FLAG_SPC_EQ | XN_FLAG_FN_LN | XN_FLAG_FN_ALIGN>
+
+B<XN_FLAG_COMPAT> uses a format identical to X509_NAME_print(): in fact it calls X509_NAME_print() internally.
+
+=head1 SEE ALSO
+
+L<ASN1_STRING_print_ex(3)|ASN1_STRING_print_ex(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/X509_STORE_CTX_get_error.pod b/openssl/doc/crypto/X509_STORE_CTX_get_error.pod
new file mode 100644
index 0000000..a883f6c
--- /dev/null
+++ b/openssl/doc/crypto/X509_STORE_CTX_get_error.pod
@@ -0,0 +1,303 @@
+=pod
+
+=head1 NAME
+
+X509_STORE_CTX_get_error, X509_STORE_CTX_set_error, X509_STORE_CTX_get_error_depth, X509_STORE_CTX_get_current_cert, X509_STORE_CTX_get1_chain, X509_verify_cert_error_string - get or set certificate verification status information
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509.h>
+ #include <openssl/x509_vfy.h>
+
+ int	X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
+ void	X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s);
+ int	X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
+ X509 *	X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
+
+ STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
+
+ const char *X509_verify_cert_error_string(long n);
+
+=head1 DESCRIPTION
+
+These functions are typically called after X509_verify_cert() has indicated
+an error or in a verification callback to determine the nature of an error.
+
+X509_STORE_CTX_get_error() returns the error code of B<ctx>, see
+the B<ERROR CODES> section for a full description of all error codes.
+
+X509_STORE_CTX_set_error() sets the error code of B<ctx> to B<s>. For example
+it might be used in a verification callback to set an error based on additional
+checks.
+
+X509_STORE_CTX_get_error_depth() returns the B<depth> of the error. This is a
+non-negative integer representing where in the certificate chain the error
+occurred. If it is zero it occured in the end entity certificate, one if
+it is the certificate which signed the end entity certificate and so on.
+
+X509_STORE_CTX_get_current_cert() returns the certificate in B<ctx> which
+caused the error or B<NULL> if no certificate is relevant.
+
+X509_STORE_CTX_get1_chain() returns a complete validate chain if a previous
+call to X509_verify_cert() is successful. If the call to X509_verify_cert()
+is B<not> successful the returned chain may be incomplete or invalid. The
+returned chain persists after the B<ctx> structure is freed, when it is
+no longer needed it should be free up using:
+
+  sk_X509_pop_free(chain, X509_free);
+
+X509_verify_cert_error_string() returns a human readable error string for
+verification error B<n>.
+
+=head1 RETURN VALUES
+
+X509_STORE_CTX_get_error() returns B<X509_V_OK> or an error code.
+
+X509_STORE_CTX_get_error_depth() returns a non-negative error depth.
+
+X509_STORE_CTX_get_current_cert() returns the cerificate which caused the
+error or B<NULL> if no certificate is relevant to the error.
+
+X509_verify_cert_error_string() returns a human readable error string for
+verification error B<n>.
+
+=head1 ERROR CODES
+
+A list of error codes and messages is shown below.  Some of the
+error codes are defined but currently never returned: these are described as
+"unused".
+
+=over 4
+
+=item B<X509_V_OK: ok>
+
+the operation was successful.
+
+=item B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: unable to get issuer certificate>
+
+the issuer certificate could not be found: this occurs if the issuer certificate
+of an untrusted certificate cannot be found.
+
+=item B<X509_V_ERR_UNABLE_TO_GET_CRL: unable to get certificate CRL>
+
+the CRL of a certificate could not be found.
+
+=item B<X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: unable to decrypt certificate's signature>
+
+the certificate signature could not be decrypted. This means that the actual
+signature value could not be determined rather than it not matching the
+expected value, this is only meaningful for RSA keys.
+
+=item B<X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: unable to decrypt CRL's signature>
+
+the CRL signature could not be decrypted: this means that the actual signature
+value could not be determined rather than it not matching the expected value.
+Unused.
+
+=item B<X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: unable to decode issuer public key>
+
+the public key in the certificate SubjectPublicKeyInfo could not be read.
+
+=item B<X509_V_ERR_CERT_SIGNATURE_FAILURE: certificate signature failure>
+
+the signature of the certificate is invalid.
+
+=item B<X509_V_ERR_CRL_SIGNATURE_FAILURE: CRL signature failure>
+
+the signature of the certificate is invalid.
+
+=item B<X509_V_ERR_CERT_NOT_YET_VALID: certificate is not yet valid>
+
+the certificate is not yet valid: the notBefore date is after the current time.
+
+=item B<X509_V_ERR_CERT_HAS_EXPIRED: certificate has expired>
+
+the certificate has expired: that is the notAfter date is before the current time.
+
+=item B<X509_V_ERR_CRL_NOT_YET_VALID: CRL is not yet valid>
+
+the CRL is not yet valid.
+
+=item B<X509_V_ERR_CRL_HAS_EXPIRED: CRL has expired>
+
+the CRL has expired.
+
+=item B<X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: format error in certificate's notBefore field>
+
+the certificate notBefore field contains an invalid time.
+
+=item B<X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: format error in certificate's notAfter field>
+
+the certificate notAfter field contains an invalid time.
+
+=item B<X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: format error in CRL's lastUpdate field>
+
+the CRL lastUpdate field contains an invalid time.
+
+=item B<X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: format error in CRL's nextUpdate field>
+
+the CRL nextUpdate field contains an invalid time.
+
+=item B<X509_V_ERR_OUT_OF_MEM: out of memory>
+
+an error occurred trying to allocate memory. This should never happen.
+
+=item B<X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: self signed certificate>
+
+the passed certificate is self signed and the same certificate cannot be found
+in the list of trusted certificates.
+
+=item B<X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: self signed certificate in certificate chain>
+
+the certificate chain could be built up using the untrusted certificates but
+the root could not be found locally.
+
+=item B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate>
+
+the issuer certificate of a locally looked up certificate could not be found.
+This normally means the list of trusted certificates is not complete.
+
+=item B<X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: unable to verify the first certificate>
+
+no signatures could be verified because the chain contains only one certificate
+and it is not self signed.
+
+=item B<X509_V_ERR_CERT_CHAIN_TOO_LONG: certificate chain too long>
+
+the certificate chain length is greater than the supplied maximum depth. Unused.
+
+=item B<X509_V_ERR_CERT_REVOKED: certificate revoked>
+
+the certificate has been revoked.
+
+=item B<X509_V_ERR_INVALID_CA: invalid CA certificate>
+
+a CA certificate is invalid. Either it is not a CA or its extensions are not
+consistent with the supplied purpose.
+
+=item B<X509_V_ERR_PATH_LENGTH_EXCEEDED: path length constraint exceeded>
+
+the basicConstraints pathlength parameter has been exceeded.
+
+=item B<X509_V_ERR_INVALID_PURPOSE: unsupported certificate purpose>
+
+the supplied certificate cannot be used for the specified purpose.
+
+=item B<X509_V_ERR_CERT_UNTRUSTED: certificate not trusted>
+
+the root CA is not marked as trusted for the specified purpose.
+
+=item B<X509_V_ERR_CERT_REJECTED: certificate rejected>
+
+the root CA is marked to reject the specified purpose.
+
+=item B<X509_V_ERR_SUBJECT_ISSUER_MISMATCH: subject issuer mismatch>
+
+the current candidate issuer certificate was rejected because its subject name
+did not match the issuer name of the current certificate. This is only set
+if issuer check debugging is enabled it is used for status notification and
+is B<not> in itself an error.
+
+=item B<X509_V_ERR_AKID_SKID_MISMATCH: authority and subject key identifier mismatch>
+
+the current candidate issuer certificate was rejected because its subject key
+identifier was present and did not match the authority key identifier current
+certificate. This is only set if issuer check debugging is enabled it is used
+for status notification and is B<not> in itself an error.
+
+=item B<X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: authority and issuer serial number mismatch>
+
+the current candidate issuer certificate was rejected because its issuer name
+and serial number was present and did not match the authority key identifier of
+the current certificate. This is only set if issuer check debugging is enabled
+it is used for status notification and is B<not> in itself an error.
+
+=item B<X509_V_ERR_KEYUSAGE_NO_CERTSIGN:key usage does not include certificate signing>
+
+the current candidate issuer certificate was rejected because its keyUsage
+extension does not permit certificate signing. This is only set if issuer check
+debugging is enabled it is used for status notification and is B<not> in itself
+an error.
+
+=item B<X509_V_ERR_INVALID_EXTENSION: invalid or inconsistent certificate extension>
+
+A certificate extension had an invalid value (for example an incorrect
+encoding) or some value inconsistent with other extensions.
+
+
+=item B<X509_V_ERR_INVALID_POLICY_EXTENSION: invalid or inconsistent certificate policy extension>
+
+A certificate policies extension had an invalid value (for example an incorrect
+encoding) or some value inconsistent with other extensions. This error only
+occurs if policy processing is enabled.
+
+=item B<X509_V_ERR_NO_EXPLICIT_POLICY: no explicit policy>
+
+The verification flags were set to require and explicit policy but none was
+present.
+
+=item B<X509_V_ERR_DIFFERENT_CRL_SCOPE: Different CRL scope>
+
+The only CRLs that could be found did not match the scope of the certificate.
+
+=item B<X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: Unsupported extension feature>
+
+Some feature of a certificate extension is not supported. Unused.
+
+=item B<X509_V_ERR_PERMITTED_VIOLATION: permitted subtree violation>
+
+A name constraint violation occured in the permitted subtrees.
+
+=item B<X509_V_ERR_EXCLUDED_VIOLATION: excluded subtree violation>
+
+A name constraint violation occured in the excluded subtrees.
+
+=item B<X509_V_ERR_SUBTREE_MINMAX: name constraints minimum and maximum not supported>
+
+A certificate name constraints extension included a minimum or maximum field:
+this is not supported.
+
+=item B<X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: unsupported name constraint type>
+
+An unsupported name constraint type was encountered. OpenSSL currently only
+supports directory name, DNS name, email and URI types.
+
+=item B<X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: unsupported or invalid name constraint syntax>
+
+The format of the name constraint is not recognised: for example an email
+address format of a form not mentioned in RFC3280. This could be caused by
+a garbage extension or some new feature not currently supported.
+
+=item B<X509_V_ERR_CRL_PATH_VALIDATION_ERROR: CRL path validation error>
+
+An error occured when attempting to verify the CRL path. This error can only
+happen if extended CRL checking is enabled.
+
+=item B<X509_V_ERR_APPLICATION_VERIFICATION: application verification failure>
+
+an application specific error. This will never be returned unless explicitly
+set by an application.
+
+=head1 NOTES
+
+The above functions should be used instead of directly referencing the fields
+in the B<X509_VERIFY_CTX> structure.
+
+In versions of OpenSSL before 1.0 the current certificate returned by
+X509_STORE_CTX_get_current_cert() was never B<NULL>. Applications should
+check the return value before printing out any debugging information relating
+to the current certificate.
+
+If an unrecognised error code is passed to X509_verify_cert_error_string() the
+numerical value of the unknown code is returned in a static buffer. This is not
+thread safe but will never happen unless an invalid code is passed.
+
+=head1 SEE ALSO
+
+L<X509_verify_cert(3)|X509_verify_cert(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/X509_STORE_CTX_get_ex_new_index.pod b/openssl/doc/crypto/X509_STORE_CTX_get_ex_new_index.pod
new file mode 100644
index 0000000..8d6b9dd
--- /dev/null
+++ b/openssl/doc/crypto/X509_STORE_CTX_get_ex_new_index.pod
@@ -0,0 +1,41 @@
+=pod
+
+=head1 NAME
+
+X509_STORE_CTX_get_ex_new_index, X509_STORE_CTX_set_ex_data, X509_STORE_CTX_get_ex_data - add application specific data to X509_STORE_CTX structures
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509_vfy.h>
+
+ int X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
+		CRYPTO_EX_new *new_func,
+		CRYPTO_EX_dup *dup_func,
+		CRYPTO_EX_free *free_func);
+
+ int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *d, int idx, void *arg);
+
+ char *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *d, int idx);
+
+=head1 DESCRIPTION
+
+These functions handle application specific data in X509_STORE_CTX structures.
+Their usage is identical to that of RSA_get_ex_new_index(), RSA_set_ex_data()
+and RSA_get_ex_data() as described in L<RSA_get_ex_new_index(3)>.
+
+=head1 NOTES
+
+This mechanism is used internally by the B<ssl> library to store the B<SSL>
+structure associated with a verification operation in an B<X509_STORE_CTX>
+structure. 
+
+=head1 SEE ALSO
+
+L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>
+
+=head1 HISTORY
+
+X509_STORE_CTX_get_ex_new_index(), X509_STORE_CTX_set_ex_data() and
+X509_STORE_CTX_get_ex_data() are available since OpenSSL 0.9.5.
+
+=cut
diff --git a/openssl/doc/crypto/X509_STORE_CTX_new.pod b/openssl/doc/crypto/X509_STORE_CTX_new.pod
new file mode 100644
index 0000000..b17888f
--- /dev/null
+++ b/openssl/doc/crypto/X509_STORE_CTX_new.pod
@@ -0,0 +1,122 @@
+=pod
+
+=head1 NAME
+
+X509_STORE_CTX_new, X509_STORE_CTX_cleanup, X509_STORE_CTX_free, X509_STORE_CTX_init, X509_STORE_CTX_trusted_stack, X509_STORE_CTX_set_cert, X509_STORE_CTX_set_chain, X509_STORE_CTX_set0_crls, X509_STORE_CTX_get0_param, X509_STORE_CTX_set0_param, X509_STORE_CTX_set_default - X509_STORE_CTX initialisation
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509_vfy.h>
+
+ X509_STORE_CTX *X509_STORE_CTX_new(void);
+ void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
+ void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
+
+ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
+			 X509 *x509, STACK_OF(X509) *chain);
+
+ void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
+
+ void	X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx,X509 *x);
+ void	X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx,STACK_OF(X509) *sk);
+ void	X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk);
+
+ X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
+ void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
+ int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);
+
+=head1 DESCRIPTION
+
+These functions initialise an B<X509_STORE_CTX> structure for subsequent use
+by X509_verify_cert().
+
+X509_STORE_CTX_new() returns a newly initialised B<X509_STORE_CTX> structure.
+
+X509_STORE_CTX_cleanup() internally cleans up an B<X509_STORE_CTX> structure.
+The context can then be reused with an new call to X509_STORE_CTX_init().
+
+X509_STORE_CTX_free() completely frees up B<ctx>. After this call B<ctx>
+is no longer valid.
+
+X509_STORE_CTX_init() sets up B<ctx> for a subsequent verification operation.
+The trusted certificate store is set to B<store>, the end entity certificate
+to be verified is set to B<x509> and a set of additional certificates (which
+will be untrusted but may be used to build the chain) in B<chain>. Any or
+all of the B<store>, B<x509> and B<chain> parameters can be B<NULL>.
+
+X509_STORE_CTX_trusted_stack() sets the set of trusted certificates of B<ctx>
+to B<sk>. This is an alternative way of specifying trusted certificates 
+instead of using an B<X509_STORE>.
+
+X509_STORE_CTX_set_cert() sets the certificate to be vertified in B<ctx> to
+B<x>.
+
+X509_STORE_CTX_set_chain() sets the additional certificate chain used by B<ctx>
+to B<sk>.
+
+X509_STORE_CTX_set0_crls() sets a set of CRLs to use to aid certificate
+verification to B<sk>. These CRLs will only be used if CRL verification is
+enabled in the associated B<X509_VERIFY_PARAM> structure. This might be
+used where additional "useful" CRLs are supplied as part of a protocol,
+for example in a PKCS#7 structure.
+
+X509_VERIFY_PARAM *X509_STORE_CTX_get0_param() retrieves an intenal pointer
+to the verification parameters associated with B<ctx>.
+
+X509_STORE_CTX_set0_param() sets the intenal verification parameter pointer
+to B<param>. After this call B<param> should not be used.
+
+X509_STORE_CTX_set_default() looks up and sets the default verification
+method to B<name>. This uses the function X509_VERIFY_PARAM_lookup() to
+find an appropriate set of parameters from B<name>.
+
+=head1 NOTES
+
+The certificates and CRLs in a store are used internally and should B<not>
+be freed up until after the associated B<X509_STORE_CTX> is freed. Legacy
+applications might implicitly use an B<X509_STORE_CTX> like this:
+
+  X509_STORE_CTX ctx;
+  X509_STORE_CTX_init(&ctx, store, cert, chain);
+
+this is B<not> recommended in new applications they should instead do:
+
+  X509_STORE_CTX *ctx;
+  ctx = X509_STORE_CTX_new();
+  if (ctx == NULL)
+	/* Bad error */
+  X509_STORE_CTX_init(ctx, store, cert, chain);
+
+=head1 BUGS
+
+The certificates and CRLs in a context are used internally and should B<not>
+be freed up until after the associated B<X509_STORE_CTX> is freed. Copies
+should be made or reference counts increased instead.
+
+=head1 RETURN VALUES
+
+X509_STORE_CTX_new() returns an newly allocates context or B<NULL> is an
+error occurred.
+
+X509_STORE_CTX_init() returns 1 for success or 0 if an error occurred.
+
+X509_STORE_CTX_get0_param() returns a pointer to an B<X509_VERIFY_PARAM>
+structure or B<NULL> if an error occurred.
+
+X509_STORE_CTX_cleanup(), X509_STORE_CTX_free(), X509_STORE_CTX_trusted_stack(),
+X509_STORE_CTX_set_cert(), X509_STORE_CTX_set_chain(),
+X509_STORE_CTX_set0_crls() and X509_STORE_CTX_set0_param() do not return
+values.
+
+X509_STORE_CTX_set_default() returns 1 for success or 0 if an error occurred.
+
+=head1 SEE ALSO
+
+L<X509_verify_cert(3)|X509_verify_cert(3)>
+L<X509_VERIFY_PARAM_set_flags(3)|X509_VERIFY_PARAM_set_flags(3)>
+
+=head1 HISTORY
+
+X509_STORE_CTX_set0_crls() was first added to OpenSSL 1.0.0
+
+=cut
diff --git a/openssl/doc/crypto/X509_STORE_CTX_set_verify_cb.pod b/openssl/doc/crypto/X509_STORE_CTX_set_verify_cb.pod
new file mode 100644
index 0000000..b9787a6
--- /dev/null
+++ b/openssl/doc/crypto/X509_STORE_CTX_set_verify_cb.pod
@@ -0,0 +1,161 @@
+=pod
+
+=head1 NAME
+
+X509_STORE_CTX_set_verify_cb - set verification callback
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509_vfy.h>
+
+ void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
+				int (*verify_cb)(int ok, X509_STORE_CTX *ctx));
+
+=head1 DESCRIPTION
+
+X509_STORE_CTX_set_verify_cb() sets the verification callback of B<ctx> to
+B<verify_cb> overwriting any existing callback.
+
+The verification callback can be used to customise the operation of certificate
+verification, either by overriding error conditions or logging errors for
+debugging purposes.
+
+However a verification callback is B<not> essential and the default operation
+is often sufficient.
+
+The B<ok> parameter to the callback indicates the value the callback should
+return to retain the default behaviour. If it is zero then and error condition
+is indicated. If it is 1 then no error occurred. If the flag
+B<X509_V_FLAG_NOTIFY_POLICY> is set then B<ok> is set to 2 to indicate the
+policy checking is complete.
+
+The B<ctx> parameter to the callback is the B<X509_STORE_CTX> structure that
+is performing the verification operation. A callback can examine this
+structure and receive additional information about the error, for example
+by calling X509_STORE_CTX_get_current_cert(). Additional application data can
+be passed to the callback via the B<ex_data> mechanism.
+
+=head1 WARNING
+
+In general a verification callback should B<NOT> unconditionally return 1 in
+all circumstances because this will allow verification to succeed no matter
+what the error. This effectively removes all security from the application
+because B<any> certificate (including untrusted generated ones) will be
+accepted.
+
+=head1 NOTES
+
+The verification callback can be set and inherited from the parent structure
+performing the operation. In some cases (such as S/MIME verification) the
+B<X509_STORE_CTX> structure is created and destroyed internally and the
+only way to set a custom verification callback is by inheriting it from the
+associated B<X509_STORE>.
+
+=head1 RETURN VALUES
+
+X509_STORE_CTX_set_verify_cb() does not return a value.
+
+=head1 EXAMPLES
+
+Default callback operation:
+
+ int verify_callback(int ok, X509_STORE_CTX *ctx)
+	{
+	return ok;
+	}
+
+Simple example, suppose a certificate in the chain is expired and we wish
+to continue after this error:
+
+ int verify_callback(int ok, X509_STORE_CTX *ctx)
+	{
+	/* Tolerate certificate expiration */
+	if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_CERT_HAS_EXPIRED)
+			return 1;
+	/* Otherwise don't override */
+	return ok;
+	}
+
+More complex example, we don't wish to continue after B<any> certificate has
+expired just one specific case:
+
+ int verify_callback(int ok, X509_STORE_CTX *ctx)
+	{
+	int err = X509_STORE_CTX_get_error(ctx);
+	X509 *err_cert = X509_STORE_CTX_get_current_cert(ctx);
+	if (err == X509_V_ERR_CERT_HAS_EXPIRED)
+		{
+		if (check_is_acceptable_expired_cert(err_cert)
+			return 1;
+		}
+	return ok;
+	}
+
+Full featured logging callback. In this case the B<bio_err> is assumed to be
+a global logging B<BIO>, an alternative would to store a BIO in B<ctx> using
+B<ex_data>.
+	
+ int verify_callback(int ok, X509_STORE_CTX *ctx)
+	{
+	X509 *err_cert;
+	int err,depth;
+
+	err_cert = X509_STORE_CTX_get_current_cert(ctx);
+	err =	X509_STORE_CTX_get_error(ctx);
+	depth =	X509_STORE_CTX_get_error_depth(ctx);
+
+	BIO_printf(bio_err,"depth=%d ",depth);
+	if (err_cert)
+		{
+		X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert),
+					0, XN_FLAG_ONELINE);
+		BIO_puts(bio_err, "\n");
+		}
+	else
+		BIO_puts(bio_err, "<no cert>\n");
+	if (!ok)
+		BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
+			X509_verify_cert_error_string(err));
+	switch (err)
+		{
+	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+		BIO_puts(bio_err,"issuer= ");
+		X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert),
+					0, XN_FLAG_ONELINE);
+		BIO_puts(bio_err, "\n");
+		break;
+	case X509_V_ERR_CERT_NOT_YET_VALID:
+	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+		BIO_printf(bio_err,"notBefore=");
+		ASN1_TIME_print(bio_err,X509_get_notBefore(err_cert));
+		BIO_printf(bio_err,"\n");
+		break;
+	case X509_V_ERR_CERT_HAS_EXPIRED:
+	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+		BIO_printf(bio_err,"notAfter=");
+		ASN1_TIME_print(bio_err,X509_get_notAfter(err_cert));
+		BIO_printf(bio_err,"\n");
+		break;
+	case X509_V_ERR_NO_EXPLICIT_POLICY:
+		policies_print(bio_err, ctx);
+		break;
+		}
+	if (err == X509_V_OK && ok == 2)
+		/* print out policies */
+
+	BIO_printf(bio_err,"verify return:%d\n",ok);
+	return(ok);
+	}
+
+=head1 SEE ALSO
+
+L<X509_STORE_CTX_get_error(3)|X509_STORE_CTX_get_error(3)>
+L<X509_STORE_set_verify_cb_func(3)|X509_STORE_set_verify_cb_func(3)>
+L<X509_STORE_CTX_get_ex_new_index(3)|X509_STORE_CTX_get_ex_new_index(3)>
+
+=head1 HISTORY
+
+X509_STORE_CTX_set_verify_cb() is available in all versions of SSLeay and
+OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/X509_STORE_set_verify_cb_func.pod b/openssl/doc/crypto/X509_STORE_set_verify_cb_func.pod
new file mode 100644
index 0000000..29e3bbe
--- /dev/null
+++ b/openssl/doc/crypto/X509_STORE_set_verify_cb_func.pod
@@ -0,0 +1,54 @@
+=pod
+
+=head1 NAME
+
+X509_STORE_set_verify_cb_func, X509_STORE_set_verify_cb - set verification callback
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509_vfy.h>
+
+ void X509_STORE_set_verify_cb(X509_STORE *st,
+				int (*verify_cb)(int ok, X509_STORE_CTX *ctx));
+
+ void X509_STORE_set_verify_cb_func(X509_STORE *st,
+				int (*verify_cb)(int ok, X509_STORE_CTX *ctx));
+
+=head1 DESCRIPTION
+
+X509_STORE_set_verify_cb() sets the verification callback of B<ctx> to
+B<verify_cb> overwriting any existing callback.
+
+X509_STORE_set_verify_cb_func() also sets the verification callback but it
+is implemented as a macro.
+
+=head1 NOTES
+
+The verification callback from an B<X509_STORE> is inherited by 
+the corresponding B<X509_STORE_CTX> structure when it is initialized. This can
+be used to set the verification callback when the B<X509_STORE_CTX> is 
+otherwise inaccessible (for example during S/MIME verification).
+
+=head1 BUGS
+
+The macro version of this function was the only one available before 
+OpenSSL 1.0.0.
+
+=head1 RETURN VALUES
+
+X509_STORE_set_verify_cb() and X509_STORE_set_verify_cb_func() do not return
+a value.
+
+=head1 SEE ALSO
+
+L<X509_STORE_CTX_set_verify_cb(3)|X509_STORE_CTX_set_verify_cb(3)>
+L<CMS_verify(3)|CMS_verify(3)>
+
+=head1 HISTORY
+
+X509_STORE_set_verify_cb_func() is available in all versions of SSLeay and
+OpenSSL.
+
+X509_STORE_set_verify_cb() was added to OpenSSL 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/X509_VERIFY_PARAM_set_flags.pod b/openssl/doc/crypto/X509_VERIFY_PARAM_set_flags.pod
new file mode 100644
index 0000000..b68eece
--- /dev/null
+++ b/openssl/doc/crypto/X509_VERIFY_PARAM_set_flags.pod
@@ -0,0 +1,171 @@
+=pod
+
+=head1 NAME
+
+X509_VERIFY_PARAM_set_flags, X509_VERIFY_PARAM_clear_flags, X509_VERIFY_PARAM_get_flags, X509_VERIFY_PARAM_set_purpose, X509_VERIFY_PARAM_set_trust, X509_VERIFY_PARAM_set_depth, X509_VERIFY_PARAM_get_depth, X509_VERIFY_PARAM_set_time, X509_VERIFY_PARAM_add0_policy, X509_VERIFY_PARAM_set1_policies - X509 verification parameters 
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509_vfy.h>
+
+ int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags);
+ int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
+							unsigned long flags);
+ unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param);
+
+ int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose);
+ int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust);
+
+ void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t);
+
+ int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
+						ASN1_OBJECT *policy);
+ int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, 
+					STACK_OF(ASN1_OBJECT) *policies);
+
+ void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth);
+ int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
+
+=head1 DESCRIPTION
+
+These functions manipulate the B<X509_VERIFY_PARAM> structure associated with
+a certificate verification operation. 
+
+The X509_VERIFY_PARAM_set_flags() function sets the flags in B<param> by oring
+it with B<flags>. See the B<VERIFICATION FLAGS> section for a complete
+description of values the B<flags> parameter can take.
+
+X509_VERIFY_PARAM_get_flags() returns the flags in B<param>.
+
+X509_VERIFY_PARAM_clear_flags() clears the flags B<flags> in B<param>.
+
+X509_VERIFY_PARAM_set_purpose() sets the verification purpose in B<param>
+to B<purpose>. This determines the acceptable purpose of the certificate
+chain, for example SSL client or SSL server.
+
+X509_VERIFY_PARAM_set_trust() sets the trust setting in B<param> to 
+B<trust>.
+
+X509_VERIFY_PARAM_set_time() sets the verification time in B<param> to
+B<t>. Normally the current time is used.
+
+X509_VERIFY_PARAM_add0_policy() enables policy checking (it is disabled
+by default) and adds B<policy> to the acceptable policy set.
+
+X509_VERIFY_PARAM_set1_policies() enables policy checking (it is disabled
+by default) and sets the acceptable policy set to B<policies>. Any existing
+policy set is cleared. The B<policies> parameter can be B<NULL> to clear
+an existing policy set.
+
+X509_VERIFY_PARAM_set_depth() sets the maximum verification depth to B<depth>.
+That is the maximum number of untrusted CA certificates that can appear in a
+chain.
+
+=head1 RETURN VALUES
+
+X509_VERIFY_PARAM_set_flags(), X509_VERIFY_PARAM_clear_flags(), 
+X509_VERIFY_PARAM_set_purpose(), X509_VERIFY_PARAM_set_trust(),
+X509_VERIFY_PARAM_add0_policy() and X509_VERIFY_PARAM_set1_policies() return 1
+for success and 0 for failure. 
+
+X509_VERIFY_PARAM_get_flags() returns the current verification flags.
+
+X509_VERIFY_PARAM_set_time() and X509_VERIFY_PARAM_set_depth() do not return
+values.
+
+X509_VERIFY_PARAM_get_depth() returns the current verification depth.
+
+=head1 VERIFICATION FLAGS
+
+The verification flags consists of zero or more of the following flags
+ored together.
+
+B<X509_V_FLAG_CRL_CHECK> enables CRL checking for the certificate chain leaf
+certificate. An error occurs if a suitable CRL cannot be found. 
+
+B<X509_V_FLAG_CRL_CHECK_ALL> enables CRL checking for the entire certificate
+chain.
+
+B<X509_V_FLAG_IGNORE_CRITICAL> disabled critical extension checking. By default
+any unhandled critical extensions in certificates or (if checked) CRLs results
+in a fatal error. If this flag is set unhandled critical extensions are
+ignored. B<WARNING> setting this option for anything other than debugging
+purposes can be a security risk. Finer control over which extensions are
+supported can be performed in the verification callback.
+
+THe B<X509_V_FLAG_X509_STRICT> flag disables workarounds for some broken
+certificates and makes the verification strictly apply B<X509> rules.
+
+B<X509_V_FLAG_ALLOW_PROXY_CERTS> enables proxy certificate verification.
+
+B<X509_V_FLAG_POLICY_CHECK> enables certificate policy checking, by default
+no policy checking is peformed. Additional information is sent to the 
+verification callback relating to policy checking.
+
+B<X509_V_FLAG_EXPLICIT_POLICY>, B<X509_V_FLAG_INHIBIT_ANY> and
+B<X509_V_FLAG_INHIBIT_MAP> set the B<require explicit policy>, B<inhibit any
+policy> and B<inhibit policy mapping> flags respectively as defined in
+B<RFC3280>. Policy checking is automatically enabled if any of these flags
+are set.
+
+If B<X509_V_FLAG_NOTIFY_POLICY> is set and the policy checking is successful
+a special status code is set to the verification callback. This permits it
+to examine the valid policy tree and perform additional checks or simply
+log it for debugging purposes.
+
+By default some addtional features such as indirect CRLs and CRLs signed by
+different keys are disabled. If B<X509_V_FLAG_EXTENDED_CRL_SUPPORT> is set
+they are enabled.
+
+If B<X509_V_FLAG_USE_DELTAS> ise set delta CRLs (if present) are used to
+determine certificate status. If not set deltas are ignored.
+
+B<X509_V_FLAG_CHECK_SS_SIGNATURE> enables checking of the root CA self signed
+cerificate signature. By default this check is disabled because it doesn't
+add any additional security but in some cases applications might want to
+check the signature anyway. A side effect of not checking the root CA
+signature is that disabled or unsupported message digests on the root CA
+are not treated as fatal errors.
+
+The B<X509_V_FLAG_CB_ISSUER_CHECK> flag enables debugging of certificate
+issuer checks. It is B<not> needed unless you are logging certificate
+verification. If this flag is set then additional status codes will be sent
+to the verification callback and it B<must> be prepared to handle such cases
+without assuming they are hard errors.
+
+=head1 NOTES
+
+The above functions should be used to manipulate verification parameters
+instead of legacy functions which work in specific structures such as
+X509_STORE_CTX_set_flags().
+
+=head1 BUGS
+
+Delta CRL checking is currently primitive. Only a single delta can be used and
+(partly due to limitations of B<X509_STORE>) constructed CRLs are not 
+maintained.
+
+If CRLs checking is enable CRLs are expected to be available in the
+corresponding B<X509_STORE> structure. No attempt is made to download
+CRLs from the CRL distribution points extension.
+
+=head1 EXAMPLE
+
+Enable CRL checking when performing certificate verification during SSL 
+connections associated with an B<SSL_CTX> structure B<ctx>:
+
+  X509_VERIFY_PARAM *param;
+  param = X509_VERIFY_PARAM_new();
+  X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
+  SSL_CTX_set1_param(ctx, param);
+  X509_VERIFY_PARAM_free(param);
+
+=head1 SEE ALSO
+
+L<X509_verify_cert(3)|X509_verify_cert(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/X509_new.pod b/openssl/doc/crypto/X509_new.pod
new file mode 100644
index 0000000..d388723
--- /dev/null
+++ b/openssl/doc/crypto/X509_new.pod
@@ -0,0 +1,39 @@
+=pod
+
+=head1 NAME
+
+X509_new, X509_free - X509 certificate ASN1 allocation functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509.h>
+
+ X509 *X509_new(void);
+ void X509_free(X509 *a);
+
+=head1 DESCRIPTION
+
+The X509 ASN1 allocation routines, allocate and free an
+X509 structure, which represents an X509 certificate.
+
+X509_new() allocates and initializes a X509 structure.
+
+X509_free() frees up the B<X509> structure B<a>.
+
+=head1 RETURN VALUES
+
+If the allocation fails, X509_new() returns B<NULL> and sets an error
+code that can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+Otherwise it returns a pointer to the newly allocated structure.
+
+X509_free() returns no value.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<d2i_X509(3)|d2i_X509(3)>
+
+=head1 HISTORY
+
+X509_new() and X509_free() are available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/X509_verify_cert.pod b/openssl/doc/crypto/X509_verify_cert.pod
new file mode 100644
index 0000000..5253bdc
--- /dev/null
+++ b/openssl/doc/crypto/X509_verify_cert.pod
@@ -0,0 +1,53 @@
+=pod
+
+=head1 NAME
+
+X509_verify_cert - discover and verify X509 certificte chain
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509.h>
+
+ int X509_verify_cert(X509_STORE_CTX *ctx);
+
+=head1 DESCRIPTION
+
+The X509_verify_cert() function attempts to discover and validate a
+certificate chain based on parameters in B<ctx>. A complete description of
+the process is contained in the L<verify(1)|verify(1)> manual page.
+
+=head1 RETURN VALUES
+
+If a complete chain can be built and validated this function returns 1,
+otherwise it return zero, in exceptional circumstances it can also
+return a negative code.
+
+If the function fails additional error information can be obtained by
+examining B<ctx> using, for example X509_STORE_CTX_get_error().
+
+=head1 NOTES
+
+Applications rarely call this function directly but it is used by
+OpenSSL internally for certificate validation, in both the S/MIME and
+SSL/TLS code.
+
+The negative return value from X509_verify_cert() can only occur if no
+certificate is set in B<ctx> (due to a programming error) or if a retry
+operation is requested during internal lookups (which never happens with
+standard lookup methods). It is however recommended that application check
+for <= 0 return value on error.
+
+=head1 BUGS
+
+This function uses the header B<x509.h> as opposed to most chain verification
+functiosn which use B<x509_vfy.h>.
+
+=head1 SEE ALSO
+
+L<X509_STORE_CTX_get_error(3)|X509_STORE_CTX_get_error(3)>
+
+=head1 HISTORY
+
+X509_verify_cert() is available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/bio.pod b/openssl/doc/crypto/bio.pod
new file mode 100644
index 0000000..f923922
--- /dev/null
+++ b/openssl/doc/crypto/bio.pod
@@ -0,0 +1,54 @@
+=pod
+
+=head1 NAME
+
+bio - I/O abstraction
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+TBA
+
+
+=head1 DESCRIPTION
+
+A BIO is an I/O abstraction, it hides many of the underlying I/O
+details from an application. If an application uses a BIO for its
+I/O it can transparently handle SSL connections, unencrypted network
+connections and file I/O.
+
+There are two type of BIO, a source/sink BIO and a filter BIO.
+
+As its name implies a source/sink BIO is a source and/or sink of data,
+examples include a socket BIO and a file BIO.
+
+A filter BIO takes data from one BIO and passes it through to
+another, or the application. The data may be left unmodified (for
+example a message digest BIO) or translated (for example an
+encryption BIO). The effect of a filter BIO may change according
+to the I/O operation it is performing: for example an encryption
+BIO will encrypt data if it is being written to and decrypt data
+if it is being read from.
+
+BIOs can be joined together to form a chain (a single BIO is a chain
+with one component). A chain normally consist of one source/sink
+BIO and one or more filter BIOs. Data read from or written to the
+first BIO then traverses the chain to the end (normally a source/sink
+BIO).
+
+=head1 SEE ALSO
+
+L<BIO_ctrl(3)|BIO_ctrl(3)>,
+L<BIO_f_base64(3)|BIO_f_base64(3)>, L<BIO_f_buffer(3)|BIO_f_buffer(3)>,
+L<BIO_f_cipher(3)|BIO_f_cipher(3)>, L<BIO_f_md(3)|BIO_f_md(3)>,
+L<BIO_f_null(3)|BIO_f_null(3)>, L<BIO_f_ssl(3)|BIO_f_ssl(3)>,
+L<BIO_find_type(3)|BIO_find_type(3)>, L<BIO_new(3)|BIO_new(3)>,
+L<BIO_new_bio_pair(3)|BIO_new_bio_pair(3)>,
+L<BIO_push(3)|BIO_push(3)>, L<BIO_read(3)|BIO_read(3)>,
+L<BIO_s_accept(3)|BIO_s_accept(3)>, L<BIO_s_bio(3)|BIO_s_bio(3)>,
+L<BIO_s_connect(3)|BIO_s_connect(3)>, L<BIO_s_fd(3)|BIO_s_fd(3)>,
+L<BIO_s_file(3)|BIO_s_file(3)>, L<BIO_s_mem(3)|BIO_s_mem(3)>,
+L<BIO_s_null(3)|BIO_s_null(3)>, L<BIO_s_socket(3)|BIO_s_socket(3)>,
+L<BIO_set_callback(3)|BIO_set_callback(3)>,
+L<BIO_should_retry(3)|BIO_should_retry(3)>
diff --git a/openssl/doc/crypto/blowfish.pod b/openssl/doc/crypto/blowfish.pod
new file mode 100644
index 0000000..5b2d274
--- /dev/null
+++ b/openssl/doc/crypto/blowfish.pod
@@ -0,0 +1,112 @@
+=pod
+
+=head1 NAME
+
+blowfish, BF_set_key, BF_encrypt, BF_decrypt, BF_ecb_encrypt, BF_cbc_encrypt,
+BF_cfb64_encrypt, BF_ofb64_encrypt, BF_options - Blowfish encryption
+
+=head1 SYNOPSIS
+
+ #include <openssl/blowfish.h>
+
+ void BF_set_key(BF_KEY *key, int len, const unsigned char *data);
+
+ void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
+         BF_KEY *key, int enc);
+ void BF_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ 	 long length, BF_KEY *schedule, unsigned char *ivec, int enc);
+ void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+ 	 long length, BF_KEY *schedule, unsigned char *ivec, int *num,
+         int enc);
+ void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+ 	 long length, BF_KEY *schedule, unsigned char *ivec, int *num);
+ const char *BF_options(void);
+
+ void BF_encrypt(BF_LONG *data,const BF_KEY *key);
+ void BF_decrypt(BF_LONG *data,const BF_KEY *key);
+
+=head1 DESCRIPTION
+
+This library implements the Blowfish cipher, which was invented and described
+by Counterpane (see http://www.counterpane.com/blowfish.html ).
+
+Blowfish is a block cipher that operates on 64 bit (8 byte) blocks of data.
+It uses a variable size key, but typically, 128 bit (16 byte) keys are
+considered good for strong encryption.  Blowfish can be used in the same
+modes as DES (see L<des_modes(7)|des_modes(7)>).  Blowfish is currently one
+of the faster block ciphers.  It is quite a bit faster than DES, and much
+faster than IDEA or RC2.
+
+Blowfish consists of a key setup phase and the actual encryption or decryption
+phase.
+
+BF_set_key() sets up the B<BF_KEY> B<key> using the B<len> bytes long key
+at B<data>.
+
+BF_ecb_encrypt() is the basic Blowfish encryption and decryption function.
+It encrypts or decrypts the first 64 bits of B<in> using the key B<key>,
+putting the result in B<out>.  B<enc> decides if encryption (B<BF_ENCRYPT>)
+or decryption (B<BF_DECRYPT>) shall be performed.  The vector pointed at by
+B<in> and B<out> must be 64 bits in length, no less.  If they are larger,
+everything after the first 64 bits is ignored.
+
+The mode functions BF_cbc_encrypt(), BF_cfb64_encrypt() and BF_ofb64_encrypt()
+all operate on variable length data.  They all take an initialization vector
+B<ivec> which needs to be passed along into the next call of the same function 
+for the same message.  B<ivec> may be initialized with anything, but the
+recipient needs to know what it was initialized with, or it won't be able
+to decrypt.  Some programs and protocols simplify this, like SSH, where
+B<ivec> is simply initialized to zero.
+BF_cbc_encrypt() operates on data that is a multiple of 8 bytes long, while
+BF_cfb64_encrypt() and BF_ofb64_encrypt() are used to encrypt an variable
+number of bytes (the amount does not have to be an exact multiple of 8).  The
+purpose of the latter two is to simulate stream ciphers, and therefore, they
+need the parameter B<num>, which is a pointer to an integer where the current
+offset in B<ivec> is stored between calls.  This integer must be initialized
+to zero when B<ivec> is initialized.
+
+BF_cbc_encrypt() is the Cipher Block Chaining function for Blowfish.  It
+encrypts or decrypts the 64 bits chunks of B<in> using the key B<schedule>,
+putting the result in B<out>.  B<enc> decides if encryption (BF_ENCRYPT) or
+decryption (BF_DECRYPT) shall be performed.  B<ivec> must point at an 8 byte
+long initialization vector.
+
+BF_cfb64_encrypt() is the CFB mode for Blowfish with 64 bit feedback.
+It encrypts or decrypts the bytes in B<in> using the key B<schedule>,
+putting the result in B<out>.  B<enc> decides if encryption (B<BF_ENCRYPT>)
+or decryption (B<BF_DECRYPT>) shall be performed.  B<ivec> must point at an
+8 byte long initialization vector. B<num> must point at an integer which must
+be initially zero.
+
+BF_ofb64_encrypt() is the OFB mode for Blowfish with 64 bit feedback.
+It uses the same parameters as BF_cfb64_encrypt(), which must be initialized
+the same way.
+
+BF_encrypt() and BF_decrypt() are the lowest level functions for Blowfish
+encryption.  They encrypt/decrypt the first 64 bits of the vector pointed by
+B<data>, using the key B<key>.  These functions should not be used unless you
+implement 'modes' of Blowfish.  The alternative is to use BF_ecb_encrypt().
+If you still want to use these functions, you should be aware that they take
+each 32-bit chunk in host-byte order, which is little-endian on little-endian
+platforms and big-endian on big-endian ones.
+
+=head1 RETURN VALUES
+
+None of the functions presented here return any value.
+
+=head1 NOTE
+
+Applications should use the higher level functions
+L<EVP_EncryptInit(3)|EVP_EncryptInit(3)> etc. instead of calling the
+blowfish functions directly.
+
+=head1 SEE ALSO
+
+L<des_modes(7)|des_modes(7)>
+
+=head1 HISTORY
+
+The Blowfish functions are available in all versions of SSLeay and OpenSSL.
+
+=cut
+
diff --git a/openssl/doc/crypto/bn.pod b/openssl/doc/crypto/bn.pod
new file mode 100644
index 0000000..cd2f8e5
--- /dev/null
+++ b/openssl/doc/crypto/bn.pod
@@ -0,0 +1,181 @@
+=pod
+
+=head1 NAME
+
+bn - multiprecision integer arithmetics
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ BIGNUM *BN_new(void);
+ void BN_free(BIGNUM *a);
+ void BN_init(BIGNUM *);
+ void BN_clear(BIGNUM *a);
+ void BN_clear_free(BIGNUM *a);
+
+ BN_CTX *BN_CTX_new(void);
+ void BN_CTX_init(BN_CTX *c);
+ void BN_CTX_free(BN_CTX *c);
+
+ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
+ BIGNUM *BN_dup(const BIGNUM *a);
+
+ BIGNUM *BN_swap(BIGNUM *a, BIGNUM *b);
+
+ int BN_num_bytes(const BIGNUM *a);
+ int BN_num_bits(const BIGNUM *a);
+ int BN_num_bits_word(BN_ULONG w);
+
+ void BN_set_negative(BIGNUM *a, int n);
+ int  BN_is_negative(const BIGNUM *a);
+
+ int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+ int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+ int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+ int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx);
+ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *a, const BIGNUM *d,
+         BN_CTX *ctx);
+ int BN_mod(BIGNUM *rem, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+ int BN_nnmod(BIGNUM *rem, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+ int BN_mod_add(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m,
+         BN_CTX *ctx);
+ int BN_mod_sub(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m,
+         BN_CTX *ctx);
+ int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m,
+         BN_CTX *ctx);
+ int BN_mod_sqr(BIGNUM *ret, BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+ int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx);
+ int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+         const BIGNUM *m, BN_CTX *ctx);
+ int BN_gcd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+
+ int BN_add_word(BIGNUM *a, BN_ULONG w);
+ int BN_sub_word(BIGNUM *a, BN_ULONG w);
+ int BN_mul_word(BIGNUM *a, BN_ULONG w);
+ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
+ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
+
+ int BN_cmp(BIGNUM *a, BIGNUM *b);
+ int BN_ucmp(BIGNUM *a, BIGNUM *b);
+ int BN_is_zero(BIGNUM *a);
+ int BN_is_one(BIGNUM *a);
+ int BN_is_word(BIGNUM *a, BN_ULONG w);
+ int BN_is_odd(BIGNUM *a);
+
+ int BN_zero(BIGNUM *a);
+ int BN_one(BIGNUM *a);
+ const BIGNUM *BN_value_one(void);
+ int BN_set_word(BIGNUM *a, unsigned long w);
+ unsigned long BN_get_word(BIGNUM *a);
+
+ int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
+ int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom);
+ int BN_rand_range(BIGNUM *rnd, BIGNUM *range);
+ int BN_pseudo_rand_range(BIGNUM *rnd, BIGNUM *range);
+
+ BIGNUM *BN_generate_prime(BIGNUM *ret, int bits,int safe, BIGNUM *add,
+         BIGNUM *rem, void (*callback)(int, int, void *), void *cb_arg);
+ int BN_is_prime(const BIGNUM *p, int nchecks,
+         void (*callback)(int, int, void *), BN_CTX *ctx, void *cb_arg);
+
+ int BN_set_bit(BIGNUM *a, int n);
+ int BN_clear_bit(BIGNUM *a, int n);
+ int BN_is_bit_set(const BIGNUM *a, int n);
+ int BN_mask_bits(BIGNUM *a, int n);
+ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+ int BN_lshift1(BIGNUM *r, BIGNUM *a);
+ int BN_rshift(BIGNUM *r, BIGNUM *a, int n);
+ int BN_rshift1(BIGNUM *r, BIGNUM *a);
+
+ int BN_bn2bin(const BIGNUM *a, unsigned char *to);
+ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
+ char *BN_bn2hex(const BIGNUM *a);
+ char *BN_bn2dec(const BIGNUM *a);
+ int BN_hex2bn(BIGNUM **a, const char *str);
+ int BN_dec2bn(BIGNUM **a, const char *str);
+ int BN_print(BIO *fp, const BIGNUM *a);
+ int BN_print_fp(FILE *fp, const BIGNUM *a);
+ int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
+ BIGNUM *BN_mpi2bn(unsigned char *s, int len, BIGNUM *ret);
+
+ BIGNUM *BN_mod_inverse(BIGNUM *r, BIGNUM *a, const BIGNUM *n,
+     BN_CTX *ctx);
+
+ BN_RECP_CTX *BN_RECP_CTX_new(void);
+ void BN_RECP_CTX_init(BN_RECP_CTX *recp);
+ void BN_RECP_CTX_free(BN_RECP_CTX *recp);
+ int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *m, BN_CTX *ctx);
+ int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *a, BIGNUM *b,
+        BN_RECP_CTX *recp, BN_CTX *ctx);
+
+ BN_MONT_CTX *BN_MONT_CTX_new(void);
+ void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
+ void BN_MONT_CTX_free(BN_MONT_CTX *mont);
+ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *m, BN_CTX *ctx);
+ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from);
+ int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b,
+         BN_MONT_CTX *mont, BN_CTX *ctx);
+ int BN_from_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont,
+         BN_CTX *ctx);
+ int BN_to_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont,
+         BN_CTX *ctx);
+
+ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai,
+	BIGNUM *mod);
+ void BN_BLINDING_free(BN_BLINDING *b);
+ int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
+ int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+ int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+ int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b,
+	BN_CTX *ctx);
+ int BN_BLINDING_invert_ex(BIGNUM *n,const BIGNUM *r,BN_BLINDING *b,
+	BN_CTX *ctx);
+ unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
+ void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
+ unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
+ void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
+ BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
+	const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
+	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
+	BN_MONT_CTX *m_ctx);
+
+=head1 DESCRIPTION
+
+This library performs arithmetic operations on integers of arbitrary
+size. It was written for use in public key cryptography, such as RSA
+and Diffie-Hellman.
+
+It uses dynamic memory allocation for storing its data structures.
+That means that there is no limit on the size of the numbers
+manipulated by these functions, but return values must always be
+checked in case a memory allocation error has occurred.
+
+The basic object in this library is a B<BIGNUM>. It is used to hold a
+single large integer. This type should be considered opaque and fields
+should not be modified or accessed directly.
+
+The creation of B<BIGNUM> objects is described in L<BN_new(3)|BN_new(3)>;
+L<BN_add(3)|BN_add(3)> describes most of the arithmetic operations.
+Comparison is described in L<BN_cmp(3)|BN_cmp(3)>; L<BN_zero(3)|BN_zero(3)>
+describes certain assignments, L<BN_rand(3)|BN_rand(3)> the generation of
+random numbers, L<BN_generate_prime(3)|BN_generate_prime(3)> deals with prime
+numbers and L<BN_set_bit(3)|BN_set_bit(3)> with bit operations. The conversion
+of B<BIGNUM>s to external formats is described in L<BN_bn2bin(3)|BN_bn2bin(3)>.
+
+=head1 SEE ALSO
+
+L<bn_internal(3)|bn_internal(3)>,
+L<dh(3)|dh(3)>, L<err(3)|err(3)>, L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>,
+L<BN_new(3)|BN_new(3)>, L<BN_CTX_new(3)|BN_CTX_new(3)>,
+L<BN_copy(3)|BN_copy(3)>, L<BN_swap(3)|BN_swap(3)>, L<BN_num_bytes(3)|BN_num_bytes(3)>,
+L<BN_add(3)|BN_add(3)>, L<BN_add_word(3)|BN_add_word(3)>,
+L<BN_cmp(3)|BN_cmp(3)>, L<BN_zero(3)|BN_zero(3)>, L<BN_rand(3)|BN_rand(3)>,
+L<BN_generate_prime(3)|BN_generate_prime(3)>, L<BN_set_bit(3)|BN_set_bit(3)>,
+L<BN_bn2bin(3)|BN_bn2bin(3)>, L<BN_mod_inverse(3)|BN_mod_inverse(3)>,
+L<BN_mod_mul_reciprocal(3)|BN_mod_mul_reciprocal(3)>,
+L<BN_mod_mul_montgomery(3)|BN_mod_mul_montgomery(3)>,
+L<BN_BLINDING_new(3)|BN_BLINDING_new(3)>
+
+=cut
diff --git a/openssl/doc/crypto/bn_internal.pod b/openssl/doc/crypto/bn_internal.pod
new file mode 100644
index 0000000..91840b0
--- /dev/null
+++ b/openssl/doc/crypto/bn_internal.pod
@@ -0,0 +1,238 @@
+=pod
+
+=head1 NAME
+
+bn_mul_words, bn_mul_add_words, bn_sqr_words, bn_div_words,
+bn_add_words, bn_sub_words, bn_mul_comba4, bn_mul_comba8,
+bn_sqr_comba4, bn_sqr_comba8, bn_cmp_words, bn_mul_normal,
+bn_mul_low_normal, bn_mul_recursive, bn_mul_part_recursive,
+bn_mul_low_recursive, bn_mul_high, bn_sqr_normal, bn_sqr_recursive,
+bn_expand, bn_wexpand, bn_expand2, bn_fix_top, bn_check_top,
+bn_print, bn_dump, bn_set_max, bn_set_high, bn_set_low - BIGNUM
+library internal functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);
+ BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num,
+   BN_ULONG w);
+ void     bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num);
+ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
+ BN_ULONG bn_add_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,
+   int num);
+ BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,
+   int num);
+
+ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
+ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
+ void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a);
+ void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a);
+
+ int bn_cmp_words(BN_ULONG *a, BN_ULONG *b, int n);
+
+ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b,
+   int nb);
+ void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n);
+ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+   int dna,int dnb,BN_ULONG *tmp);
+ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b,
+   int n, int tna,int tnb, BN_ULONG *tmp);
+ void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b,
+   int n2, BN_ULONG *tmp);
+ void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l,
+   int n2, BN_ULONG *tmp);
+
+ void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp);
+ void bn_sqr_recursive(BN_ULONG *r, BN_ULONG *a, int n2, BN_ULONG *tmp);
+
+ void mul(BN_ULONG r, BN_ULONG a, BN_ULONG w, BN_ULONG c);
+ void mul_add(BN_ULONG r, BN_ULONG a, BN_ULONG w, BN_ULONG c);
+ void sqr(BN_ULONG r0, BN_ULONG r1, BN_ULONG a);
+
+ BIGNUM *bn_expand(BIGNUM *a, int bits);
+ BIGNUM *bn_wexpand(BIGNUM *a, int n);
+ BIGNUM *bn_expand2(BIGNUM *a, int n);
+ void bn_fix_top(BIGNUM *a);
+
+ void bn_check_top(BIGNUM *a);
+ void bn_print(BIGNUM *a);
+ void bn_dump(BN_ULONG *d, int n);
+ void bn_set_max(BIGNUM *a);
+ void bn_set_high(BIGNUM *r, BIGNUM *a, int n);
+ void bn_set_low(BIGNUM *r, BIGNUM *a, int n);
+
+=head1 DESCRIPTION
+
+This page documents the internal functions used by the OpenSSL
+B<BIGNUM> implementation. They are described here to facilitate
+debugging and extending the library. They are I<not> to be used by
+applications.
+
+=head2 The BIGNUM structure
+
+ typedef struct bignum_st BIGNUM;
+
+ struct bignum_st
+        {
+        BN_ULONG *d;    /* Pointer to an array of 'BN_BITS2' bit chunks. */
+        int top;        /* Index of last used d +1. */
+        /* The next are internal book keeping for bn_expand. */
+        int dmax;       /* Size of the d array. */
+        int neg;        /* one if the number is negative */
+        int flags;
+        };
+
+
+The integer value is stored in B<d>, a malloc()ed array of words (B<BN_ULONG>),
+least significant word first. A B<BN_ULONG> can be either 16, 32 or 64 bits
+in size, depending on the 'number of bits' (B<BITS2>) specified in
+C<openssl/bn.h>.
+
+B<dmax> is the size of the B<d> array that has been allocated.  B<top>
+is the number of words being used, so for a value of 4, bn.d[0]=4 and
+bn.top=1.  B<neg> is 1 if the number is negative.  When a B<BIGNUM> is
+B<0>, the B<d> field can be B<NULL> and B<top> == B<0>.
+
+B<flags> is a bit field of flags which are defined in C<openssl/bn.h>. The 
+flags begin with B<BN_FLG_>. The macros BN_set_flags(b,n) and 
+BN_get_flags(b,n) exist to enable or fetch flag(s) B<n> from B<BIGNUM>
+structure B<b>.
+
+Various routines in this library require the use of temporary
+B<BIGNUM> variables during their execution.  Since dynamic memory
+allocation to create B<BIGNUM>s is rather expensive when used in
+conjunction with repeated subroutine calls, the B<BN_CTX> structure is
+used.  This structure contains B<BN_CTX_NUM> B<BIGNUM>s, see
+L<BN_CTX_start(3)|BN_CTX_start(3)>.
+
+=head2 Low-level arithmetic operations
+
+These functions are implemented in C and for several platforms in
+assembly language:
+
+bn_mul_words(B<rp>, B<ap>, B<num>, B<w>) operates on the B<num> word
+arrays B<rp> and B<ap>.  It computes B<ap> * B<w>, places the result
+in B<rp>, and returns the high word (carry).
+
+bn_mul_add_words(B<rp>, B<ap>, B<num>, B<w>) operates on the B<num>
+word arrays B<rp> and B<ap>.  It computes B<ap> * B<w> + B<rp>, places
+the result in B<rp>, and returns the high word (carry).
+
+bn_sqr_words(B<rp>, B<ap>, B<n>) operates on the B<num> word array
+B<ap> and the 2*B<num> word array B<ap>.  It computes B<ap> * B<ap>
+word-wise, and places the low and high bytes of the result in B<rp>.
+
+bn_div_words(B<h>, B<l>, B<d>) divides the two word number (B<h>,B<l>)
+by B<d> and returns the result.
+
+bn_add_words(B<rp>, B<ap>, B<bp>, B<num>) operates on the B<num> word
+arrays B<ap>, B<bp> and B<rp>.  It computes B<ap> + B<bp>, places the
+result in B<rp>, and returns the high word (carry).
+
+bn_sub_words(B<rp>, B<ap>, B<bp>, B<num>) operates on the B<num> word
+arrays B<ap>, B<bp> and B<rp>.  It computes B<ap> - B<bp>, places the
+result in B<rp>, and returns the carry (1 if B<bp> E<gt> B<ap>, 0
+otherwise).
+
+bn_mul_comba4(B<r>, B<a>, B<b>) operates on the 4 word arrays B<a> and
+B<b> and the 8 word array B<r>.  It computes B<a>*B<b> and places the
+result in B<r>.
+
+bn_mul_comba8(B<r>, B<a>, B<b>) operates on the 8 word arrays B<a> and
+B<b> and the 16 word array B<r>.  It computes B<a>*B<b> and places the
+result in B<r>.
+
+bn_sqr_comba4(B<r>, B<a>, B<b>) operates on the 4 word arrays B<a> and
+B<b> and the 8 word array B<r>.
+
+bn_sqr_comba8(B<r>, B<a>, B<b>) operates on the 8 word arrays B<a> and
+B<b> and the 16 word array B<r>.
+
+The following functions are implemented in C:
+
+bn_cmp_words(B<a>, B<b>, B<n>) operates on the B<n> word arrays B<a>
+and B<b>.  It returns 1, 0 and -1 if B<a> is greater than, equal and
+less than B<b>.
+
+bn_mul_normal(B<r>, B<a>, B<na>, B<b>, B<nb>) operates on the B<na>
+word array B<a>, the B<nb> word array B<b> and the B<na>+B<nb> word
+array B<r>.  It computes B<a>*B<b> and places the result in B<r>.
+
+bn_mul_low_normal(B<r>, B<a>, B<b>, B<n>) operates on the B<n> word
+arrays B<r>, B<a> and B<b>.  It computes the B<n> low words of
+B<a>*B<b> and places the result in B<r>.
+
+bn_mul_recursive(B<r>, B<a>, B<b>, B<n2>, B<dna>, B<dnb>, B<t>) operates
+on the word arrays B<a> and B<b> of length B<n2>+B<dna> and B<n2>+B<dnb>
+(B<dna> and B<dnb> are currently allowed to be 0 or negative) and the 2*B<n2>
+word arrays B<r> and B<t>.  B<n2> must be a power of 2.  It computes
+B<a>*B<b> and places the result in B<r>.
+
+bn_mul_part_recursive(B<r>, B<a>, B<b>, B<n>, B<tna>, B<tnb>, B<tmp>)
+operates on the word arrays B<a> and B<b> of length B<n>+B<tna> and
+B<n>+B<tnb> and the 4*B<n> word arrays B<r> and B<tmp>.
+
+bn_mul_low_recursive(B<r>, B<a>, B<b>, B<n2>, B<tmp>) operates on the
+B<n2> word arrays B<r> and B<tmp> and the B<n2>/2 word arrays B<a>
+and B<b>.
+
+bn_mul_high(B<r>, B<a>, B<b>, B<l>, B<n2>, B<tmp>) operates on the
+B<n2> word arrays B<r>, B<a>, B<b> and B<l> (?) and the 3*B<n2> word
+array B<tmp>.
+
+BN_mul() calls bn_mul_normal(), or an optimized implementation if the
+factors have the same size: bn_mul_comba8() is used if they are 8
+words long, bn_mul_recursive() if they are larger than
+B<BN_MULL_SIZE_NORMAL> and the size is an exact multiple of the word
+size, and bn_mul_part_recursive() for others that are larger than
+B<BN_MULL_SIZE_NORMAL>.
+
+bn_sqr_normal(B<r>, B<a>, B<n>, B<tmp>) operates on the B<n> word array
+B<a> and the 2*B<n> word arrays B<tmp> and B<r>.
+
+The implementations use the following macros which, depending on the
+architecture, may use "long long" C operations or inline assembler.
+They are defined in C<bn_lcl.h>.
+
+mul(B<r>, B<a>, B<w>, B<c>) computes B<w>*B<a>+B<c> and places the
+low word of the result in B<r> and the high word in B<c>.
+
+mul_add(B<r>, B<a>, B<w>, B<c>) computes B<w>*B<a>+B<r>+B<c> and
+places the low word of the result in B<r> and the high word in B<c>.
+
+sqr(B<r0>, B<r1>, B<a>) computes B<a>*B<a> and places the low word
+of the result in B<r0> and the high word in B<r1>.
+
+=head2 Size changes
+
+bn_expand() ensures that B<b> has enough space for a B<bits> bit
+number.  bn_wexpand() ensures that B<b> has enough space for an
+B<n> word number.  If the number has to be expanded, both macros
+call bn_expand2(), which allocates a new B<d> array and copies the
+data.  They return B<NULL> on error, B<b> otherwise.
+
+The bn_fix_top() macro reduces B<a-E<gt>top> to point to the most
+significant non-zero word plus one when B<a> has shrunk.
+
+=head2 Debugging
+
+bn_check_top() verifies that C<((a)-E<gt>top E<gt>= 0 && (a)-E<gt>top
+E<lt>= (a)-E<gt>dmax)>.  A violation will cause the program to abort.
+
+bn_print() prints B<a> to stderr. bn_dump() prints B<n> words at B<d>
+(in reverse order, i.e. most significant word first) to stderr.
+
+bn_set_max() makes B<a> a static number with a B<dmax> of its current size.
+This is used by bn_set_low() and bn_set_high() to make B<r> a read-only
+B<BIGNUM> that contains the B<n> low or high words of B<a>.
+
+If B<BN_DEBUG> is not defined, bn_check_top(), bn_print(), bn_dump()
+and bn_set_max() are defined as empty macros.
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>
+
+=cut
diff --git a/openssl/doc/crypto/buffer.pod b/openssl/doc/crypto/buffer.pod
new file mode 100644
index 0000000..781f5b1
--- /dev/null
+++ b/openssl/doc/crypto/buffer.pod
@@ -0,0 +1,73 @@
+=pod
+
+=head1 NAME
+
+BUF_MEM_new, BUF_MEM_free, BUF_MEM_grow, BUF_strdup - simple
+character arrays structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/buffer.h>
+
+ BUF_MEM *BUF_MEM_new(void);
+
+ void	BUF_MEM_free(BUF_MEM *a);
+
+ int	BUF_MEM_grow(BUF_MEM *str, int len);
+
+ char *	BUF_strdup(const char *str);
+
+=head1 DESCRIPTION
+
+The buffer library handles simple character arrays. Buffers are used for
+various purposes in the library, most notably memory BIOs.
+
+The library uses the BUF_MEM structure defined in buffer.h:
+
+ typedef struct buf_mem_st
+ {
+        int length;     /* current number of bytes */
+        char *data;
+        int max;        /* size of buffer */
+ } BUF_MEM;
+
+B<length> is the current size of the buffer in bytes, B<max> is the amount of
+memory allocated to the buffer. There are three functions which handle these
+and one "miscellaneous" function.
+
+BUF_MEM_new() allocates a new buffer of zero size.
+
+BUF_MEM_free() frees up an already existing buffer. The data is zeroed
+before freeing up in case the buffer contains sensitive data.
+
+BUF_MEM_grow() changes the size of an already existing buffer to
+B<len>. Any data already in the buffer is preserved if it increases in
+size.
+
+BUF_strdup() copies a null terminated string into a block of allocated
+memory and returns a pointer to the allocated block.
+Unlike the standard C library strdup() this function uses OPENSSL_malloc() and so
+should be used in preference to the standard library strdup() because it can
+be used for memory leak checking or replacing the malloc() function.
+
+The memory allocated from BUF_strdup() should be freed up using the OPENSSL_free()
+function.
+
+=head1 RETURN VALUES
+
+BUF_MEM_new() returns the buffer or NULL on error.
+
+BUF_MEM_free() has no return value.
+
+BUF_MEM_grow() returns zero on error or the new size (i.e. B<len>).
+
+=head1 SEE ALSO
+
+L<bio(3)|bio(3)>
+
+=head1 HISTORY
+
+BUF_MEM_new(), BUF_MEM_free() and BUF_MEM_grow() are available in all
+versions of SSLeay and OpenSSL. BUF_strdup() was added in SSLeay 0.8.
+
+=cut
diff --git a/openssl/doc/crypto/crypto.pod b/openssl/doc/crypto/crypto.pod
new file mode 100644
index 0000000..7a52799
--- /dev/null
+++ b/openssl/doc/crypto/crypto.pod
@@ -0,0 +1,85 @@
+=pod
+
+=head1 NAME
+
+crypto - OpenSSL cryptographic library
+
+=head1 SYNOPSIS
+
+=head1 DESCRIPTION
+
+The OpenSSL B<crypto> library implements a wide range of cryptographic
+algorithms used in various Internet standards. The services provided
+by this library are used by the OpenSSL implementations of SSL, TLS
+and S/MIME, and they have also been used to implement SSH, OpenPGP, and
+other cryptographic standards.
+
+=head1 OVERVIEW
+
+B<libcrypto> consists of a number of sub-libraries that implement the
+individual algorithms.
+
+The functionality includes symmetric encryption, public key
+cryptography and key agreement, certificate handling, cryptographic
+hash functions and a cryptographic pseudo-random number generator.
+
+=over 4
+
+=item SYMMETRIC CIPHERS
+
+L<blowfish(3)|blowfish(3)>, L<cast(3)|cast(3)>, L<des(3)|des(3)>,
+L<idea(3)|idea(3)>, L<rc2(3)|rc2(3)>, L<rc4(3)|rc4(3)>, L<rc5(3)|rc5(3)> 
+
+=item PUBLIC KEY CRYPTOGRAPHY AND KEY AGREEMENT
+
+L<dsa(3)|dsa(3)>, L<dh(3)|dh(3)>, L<rsa(3)|rsa(3)>
+
+=item CERTIFICATES
+
+L<x509(3)|x509(3)>, L<x509v3(3)|x509v3(3)>
+
+=item AUTHENTICATION CODES, HASH FUNCTIONS
+
+L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>, L<md4(3)|md4(3)>,
+L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>,
+L<sha(3)|sha(3)>
+
+=item AUXILIARY FUNCTIONS
+
+L<err(3)|err(3)>, L<threads(3)|threads(3)>, L<rand(3)|rand(3)>,
+L<OPENSSL_VERSION_NUMBER(3)|OPENSSL_VERSION_NUMBER(3)>
+
+=item INPUT/OUTPUT, DATA ENCODING
+
+L<asn1(3)|asn1(3)>, L<bio(3)|bio(3)>, L<evp(3)|evp(3)>, L<pem(3)|pem(3)>,
+L<pkcs7(3)|pkcs7(3)>, L<pkcs12(3)|pkcs12(3)> 
+
+=item INTERNAL FUNCTIONS
+
+L<bn(3)|bn(3)>, L<buffer(3)|buffer(3)>, L<lhash(3)|lhash(3)>,
+L<objects(3)|objects(3)>, L<stack(3)|stack(3)>,
+L<txt_db(3)|txt_db(3)> 
+
+=back
+
+=head1 NOTES
+
+Some of the newer functions follow a naming convention using the numbers
+B<0> and B<1>. For example the functions:
+
+ int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
+ int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj);
+
+The B<0> version uses the supplied structure pointer directly
+in the parent and it will be freed up when the parent is freed.
+In the above example B<crl> would be freed but B<rev> would not.
+
+The B<1> function uses a copy of the supplied structure pointer
+(or in some cases increases its link count) in the parent and
+so both (B<x> and B<obj> above) should be freed up.
+
+=head1 SEE ALSO
+
+L<openssl(1)|openssl(1)>, L<ssl(3)|ssl(3)>
+
+=cut
diff --git a/openssl/doc/crypto/d2i_ASN1_OBJECT.pod b/openssl/doc/crypto/d2i_ASN1_OBJECT.pod
new file mode 100644
index 0000000..45bb184
--- /dev/null
+++ b/openssl/doc/crypto/d2i_ASN1_OBJECT.pod
@@ -0,0 +1,29 @@
+=pod
+
+=head1 NAME
+
+d2i_ASN1_OBJECT, i2d_ASN1_OBJECT - ASN1 OBJECT IDENTIFIER functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/objects.h>
+
+ ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, unsigned char **pp, long length);
+ int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp);
+
+=head1 DESCRIPTION
+
+These functions decode and encode an ASN1 OBJECT IDENTIFIER.
+
+Othewise these behave in a similar way to d2i_X509() and i2d_X509()
+described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
+
+=head1 SEE ALSO
+
+L<d2i_X509(3)|d2i_X509(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/d2i_DHparams.pod b/openssl/doc/crypto/d2i_DHparams.pod
new file mode 100644
index 0000000..1e98aeb
--- /dev/null
+++ b/openssl/doc/crypto/d2i_DHparams.pod
@@ -0,0 +1,30 @@
+=pod
+
+=head1 NAME
+
+d2i_DHparams, i2d_DHparams - PKCS#3 DH parameter functions.
+
+=head1 SYNOPSIS
+
+ #include <openssl/dh.h>
+
+ DH *d2i_DHparams(DH **a, unsigned char **pp, long length);
+ int i2d_DHparams(DH *a, unsigned char **pp);
+
+=head1 DESCRIPTION
+
+These functions decode and encode PKCS#3 DH parameters using the
+DHparameter structure described in PKCS#3.
+
+Othewise these behave in a similar way to d2i_X509() and i2d_X509()
+described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
+
+=head1 SEE ALSO
+
+L<d2i_X509(3)|d2i_X509(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/d2i_DSAPublicKey.pod b/openssl/doc/crypto/d2i_DSAPublicKey.pod
new file mode 100644
index 0000000..22c1b50
--- /dev/null
+++ b/openssl/doc/crypto/d2i_DSAPublicKey.pod
@@ -0,0 +1,83 @@
+=pod
+
+=head1 NAME
+
+d2i_DSAPublicKey, i2d_DSAPublicKey, d2i_DSAPrivateKey, i2d_DSAPrivateKey,
+d2i_DSA_PUBKEY, i2d_DSA_PUBKEY, d2i_DSA_SIG, i2d_DSA_SIG - DSA key encoding
+and parsing functions.
+
+=head1 SYNOPSIS
+
+ #include <openssl/dsa.h>
+ #include <openssl/x509.h>
+
+ DSA * d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length);
+
+ int i2d_DSAPublicKey(const DSA *a, unsigned char **pp);
+
+ DSA * d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length);
+
+ int i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp);
+
+ DSA * d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length);
+
+ int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
+
+ DSA * d2i_DSAparams(DSA **a, const unsigned char **pp, long length);
+
+ int i2d_DSAparams(const DSA *a, unsigned char **pp);
+
+ DSA * d2i_DSA_SIG(DSA_SIG **a, const unsigned char **pp, long length);
+
+ int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp);
+
+=head1 DESCRIPTION
+
+d2i_DSAPublicKey() and i2d_DSAPublicKey() decode and encode the DSA public key
+components structure.
+
+d2i_DSA_PUBKEY() and i2d_DSA_PUBKEY() decode and encode an DSA public key using
+a SubjectPublicKeyInfo (certificate public key) structure.
+
+d2i_DSAPrivateKey(), i2d_DSAPrivateKey() decode and encode the DSA private key
+components.
+
+d2i_DSAparams(), i2d_DSAparams() decode and encode the DSA parameters using
+a B<Dss-Parms> structure as defined in RFC2459.
+
+d2i_DSA_SIG(), i2d_DSA_SIG() decode and encode a DSA signature using a
+B<Dss-Sig-Value> structure as defined in RFC2459.
+
+The usage of all of these functions is similar to the d2i_X509() and
+i2d_X509() described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
+
+=head1 NOTES
+
+The B<DSA> structure passed to the private key encoding functions should have
+all the private key components present.
+
+The data encoded by the private key functions is unencrypted and therefore 
+offers no private key security.
+
+The B<DSA_PUBKEY> functions should be used in preference to the B<DSAPublicKey>
+functions when encoding public keys because they use a standard format.
+
+The B<DSAPublicKey> functions use an non standard format the actual data encoded
+depends on the value of the B<write_params> field of the B<a> key parameter.
+If B<write_params> is zero then only the B<pub_key> field is encoded as an
+B<INTEGER>. If B<write_params> is 1 then a B<SEQUENCE> consisting of the
+B<p>, B<q>, B<g> and B<pub_key> respectively fields are encoded.
+
+The B<DSAPrivateKey> functions also use a non standard structure consiting
+consisting of a SEQUENCE containing the B<p>, B<q>, B<g> and B<pub_key> and
+B<priv_key> fields respectively.
+
+=head1 SEE ALSO
+
+L<d2i_X509(3)|d2i_X509(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/d2i_PKCS8PrivateKey.pod b/openssl/doc/crypto/d2i_PKCS8PrivateKey.pod
new file mode 100644
index 0000000..a54b779
--- /dev/null
+++ b/openssl/doc/crypto/d2i_PKCS8PrivateKey.pod
@@ -0,0 +1,56 @@
+=pod
+
+=head1 NAME
+
+d2i_PKCS8PrivateKey_bio, d2i_PKCS8PrivateKey_fp,
+i2d_PKCS8PrivateKey_bio, i2d_PKCS8PrivateKey_fp,
+i2d_PKCS8PrivateKey_nid_bio, i2d_PKCS8PrivateKey_nid_fp - PKCS#8 format private key functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u);
+ EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u);
+
+ int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+
+ int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+
+ int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+
+ int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+
+=head1 DESCRIPTION
+
+The PKCS#8 functions encode and decode private keys in PKCS#8 format using both
+PKCS#5 v1.5 and PKCS#5 v2.0 password based encryption algorithms.
+
+Other than the use of DER as opposed to PEM these functions are identical to the
+corresponding B<PEM> function as described in the L<pem(3)|pem(3)> manual page.
+
+=head1 NOTES
+
+Before using these functions L<OpenSSL_add_all_algorithms(3)|OpenSSL_add_all_algorithms(3)>
+should be called to initialize the internal algorithm lookup tables otherwise errors about
+unknown algorithms will occur if an attempt is made to decrypt a private key. 
+
+These functions are currently the only way to store encrypted private keys using DER format.
+
+Currently all the functions use BIOs or FILE pointers, there are no functions which
+work directly on memory: this can be readily worked around by converting the buffers
+to memory BIOs, see L<BIO_s_mem(3)|BIO_s_mem(3)> for details.
+
+=head1 SEE ALSO
+
+L<pem(3)|pem(3)>
+
+=cut
diff --git a/openssl/doc/crypto/d2i_RSAPublicKey.pod b/openssl/doc/crypto/d2i_RSAPublicKey.pod
new file mode 100644
index 0000000..aa6078b
--- /dev/null
+++ b/openssl/doc/crypto/d2i_RSAPublicKey.pod
@@ -0,0 +1,67 @@
+=pod
+
+=head1 NAME
+
+d2i_RSAPublicKey, i2d_RSAPublicKey, d2i_RSAPrivateKey, i2d_RSAPrivateKey,
+d2i_RSA_PUBKEY, i2d_RSA_PUBKEY, i2d_Netscape_RSA,
+d2i_Netscape_RSA - RSA public and private key encoding functions.
+
+=head1 SYNOPSIS
+
+ #include <openssl/rsa.h>
+ #include <openssl/x509.h>
+
+ RSA * d2i_RSAPublicKey(RSA **a, const unsigned char **pp, long length);
+
+ int i2d_RSAPublicKey(RSA *a, unsigned char **pp);
+
+ RSA * d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length);
+
+ int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp);
+
+ RSA * d2i_RSAPrivateKey(RSA **a, const unsigned char **pp, long length);
+
+ int i2d_RSAPrivateKey(RSA *a, unsigned char **pp);
+
+ int i2d_Netscape_RSA(RSA *a, unsigned char **pp, int (*cb)());
+
+ RSA * d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, int (*cb)());
+
+=head1 DESCRIPTION
+
+d2i_RSAPublicKey() and i2d_RSAPublicKey() decode and encode a PKCS#1 RSAPublicKey
+structure.
+
+d2i_RSA_PUBKEY() and i2d_RSA_PUBKEY() decode and encode an RSA public key using
+a SubjectPublicKeyInfo (certificate public key) structure.
+
+d2i_RSAPrivateKey(), i2d_RSAPrivateKey() decode and encode a PKCS#1 RSAPrivateKey
+structure.
+
+d2i_Netscape_RSA(), i2d_Netscape_RSA() decode and encode an RSA private key in
+NET format.
+
+The usage of all of these functions is similar to the d2i_X509() and
+i2d_X509() described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
+
+=head1 NOTES
+
+The B<RSA> structure passed to the private key encoding functions should have
+all the PKCS#1 private key components present.
+
+The data encoded by the private key functions is unencrypted and therefore 
+offers no private key security. 
+
+The NET format functions are present to provide compatibility with certain very
+old software. This format has some severe security weaknesses and should be
+avoided if possible.
+
+=head1 SEE ALSO
+
+L<d2i_X509(3)|d2i_X509(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/d2i_X509.pod b/openssl/doc/crypto/d2i_X509.pod
new file mode 100644
index 0000000..298ec54
--- /dev/null
+++ b/openssl/doc/crypto/d2i_X509.pod
@@ -0,0 +1,231 @@
+=pod
+
+=head1 NAME
+
+d2i_X509, i2d_X509, d2i_X509_bio, d2i_X509_fp, i2d_X509_bio,
+i2d_X509_fp - X509 encode and decode functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509.h>
+
+ X509 *d2i_X509(X509 **px, const unsigned char **in, int len);
+ int i2d_X509(X509 *x, unsigned char **out);
+
+ X509 *d2i_X509_bio(BIO *bp, X509 **x);
+ X509 *d2i_X509_fp(FILE *fp, X509 **x);
+
+ int i2d_X509_bio(BIO *bp, X509 *x);
+ int i2d_X509_fp(FILE *fp, X509 *x);
+
+=head1 DESCRIPTION
+
+The X509 encode and decode routines encode and parse an
+B<X509> structure, which represents an X509 certificate.
+
+d2i_X509() attempts to decode B<len> bytes at B<*in>. If 
+successful a pointer to the B<X509> structure is returned. If an error
+occurred then B<NULL> is returned. If B<px> is not B<NULL> then the
+returned structure is written to B<*px>. If B<*px> is not B<NULL>
+then it is assumed that B<*px> contains a valid B<X509>
+structure and an attempt is made to reuse it. If the call is
+successful B<*in> is incremented to the byte following the
+parsed data.
+
+i2d_X509() encodes the structure pointed to by B<x> into DER format.
+If B<out> is not B<NULL> is writes the DER encoded data to the buffer
+at B<*out>, and increments it to point after the data just written.
+If the return value is negative an error occurred, otherwise it
+returns the length of the encoded data. 
+
+For OpenSSL 0.9.7 and later if B<*out> is B<NULL> memory will be
+allocated for a buffer and the encoded data written to it. In this
+case B<*out> is not incremented and it points to the start of the
+data just written.
+
+d2i_X509_bio() is similar to d2i_X509() except it attempts
+to parse data from BIO B<bp>.
+
+d2i_X509_fp() is similar to d2i_X509() except it attempts
+to parse data from FILE pointer B<fp>.
+
+i2d_X509_bio() is similar to i2d_X509() except it writes
+the encoding of the structure B<x> to BIO B<bp> and it
+returns 1 for success and 0 for failure.
+
+i2d_X509_fp() is similar to i2d_X509() except it writes
+the encoding of the structure B<x> to BIO B<bp> and it
+returns 1 for success and 0 for failure.
+
+=head1 NOTES
+
+The letters B<i> and B<d> in for example B<i2d_X509> stand for
+"internal" (that is an internal C structure) and "DER". So that
+B<i2d_X509> converts from internal to DER.
+
+The functions can also understand B<BER> forms.
+
+The actual X509 structure passed to i2d_X509() must be a valid
+populated B<X509> structure it can B<not> simply be fed with an
+empty structure such as that returned by X509_new().
+
+The encoded data is in binary form and may contain embedded zeroes.
+Therefore any FILE pointers or BIOs should be opened in binary mode.
+Functions such as B<strlen()> will B<not> return the correct length
+of the encoded structure.
+
+The ways that B<*in> and B<*out> are incremented after the operation
+can trap the unwary. See the B<WARNINGS> section for some common
+errors.
+
+The reason for the auto increment behaviour is to reflect a typical
+usage of ASN1 functions: after one structure is encoded or decoded
+another will processed after it.
+
+=head1 EXAMPLES
+
+Allocate and encode the DER encoding of an X509 structure:
+
+ int len;
+ unsigned char *buf, *p;
+
+ len = i2d_X509(x, NULL);
+
+ buf = OPENSSL_malloc(len);
+
+ if (buf == NULL)
+	/* error */
+
+ p = buf;
+
+ i2d_X509(x, &p);
+
+If you are using OpenSSL 0.9.7 or later then this can be
+simplified to:
+
+
+ int len;
+ unsigned char *buf;
+
+ buf = NULL;
+
+ len = i2d_X509(x, &buf);
+
+ if (len < 0)
+	/* error */
+
+Attempt to decode a buffer:
+
+ X509 *x;
+
+ unsigned char *buf, *p;
+
+ int len;
+
+ /* Something to setup buf and len */
+
+ p = buf;
+
+ x = d2i_X509(NULL, &p, len);
+
+ if (x == NULL)
+    /* Some error */
+
+Alternative technique:
+
+ X509 *x;
+
+ unsigned char *buf, *p;
+
+ int len;
+
+ /* Something to setup buf and len */
+
+ p = buf;
+
+ x = NULL;
+
+ if(!d2i_X509(&x, &p, len))
+    /* Some error */
+
+
+=head1 WARNINGS
+
+The use of temporary variable is mandatory. A common
+mistake is to attempt to use a buffer directly as follows:
+
+ int len;
+ unsigned char *buf;
+
+ len = i2d_X509(x, NULL);
+
+ buf = OPENSSL_malloc(len);
+
+ if (buf == NULL)
+	/* error */
+
+ i2d_X509(x, &buf);
+
+ /* Other stuff ... */
+
+ OPENSSL_free(buf);
+
+This code will result in B<buf> apparently containing garbage because
+it was incremented after the call to point after the data just written.
+Also B<buf> will no longer contain the pointer allocated by B<OPENSSL_malloc()>
+and the subsequent call to B<OPENSSL_free()> may well crash.
+
+The auto allocation feature (setting buf to NULL) only works on OpenSSL
+0.9.7 and later. Attempts to use it on earlier versions will typically
+cause a segmentation violation.
+
+Another trap to avoid is misuse of the B<xp> argument to B<d2i_X509()>:
+
+ X509 *x;
+
+ if (!d2i_X509(&x, &p, len))
+	/* Some error */
+
+This will probably crash somewhere in B<d2i_X509()>. The reason for this
+is that the variable B<x> is uninitialized and an attempt will be made to
+interpret its (invalid) value as an B<X509> structure, typically causing
+a segmentation violation. If B<x> is set to NULL first then this will not
+happen.
+
+=head1 BUGS
+
+In some versions of OpenSSL the "reuse" behaviour of d2i_X509() when 
+B<*px> is valid is broken and some parts of the reused structure may
+persist if they are not present in the new one. As a result the use
+of this "reuse" behaviour is strongly discouraged.
+
+i2d_X509() will not return an error in many versions of OpenSSL,
+if mandatory fields are not initialized due to a programming error
+then the encoded structure may contain invalid data or omit the
+fields entirely and will not be parsed by d2i_X509(). This may be
+fixed in future so code should not assume that i2d_X509() will
+always succeed.
+
+=head1 RETURN VALUES
+
+d2i_X509(), d2i_X509_bio() and d2i_X509_fp() return a valid B<X509> structure
+or B<NULL> if an error occurs. The error code that can be obtained by
+L<ERR_get_error(3)|ERR_get_error(3)>. 
+
+i2d_X509() returns the number of bytes successfully encoded or a negative
+value if an error occurs. The error code can be obtained by
+L<ERR_get_error(3)|ERR_get_error(3)>. 
+
+i2d_X509_bio() and i2d_X509_fp() return 1 for success and 0 if an error 
+occurs The error code can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. 
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>
+
+=head1 HISTORY
+
+d2i_X509, i2d_X509, d2i_X509_bio, d2i_X509_fp, i2d_X509_bio and i2d_X509_fp
+are available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/d2i_X509_ALGOR.pod b/openssl/doc/crypto/d2i_X509_ALGOR.pod
new file mode 100644
index 0000000..9e5cd92
--- /dev/null
+++ b/openssl/doc/crypto/d2i_X509_ALGOR.pod
@@ -0,0 +1,30 @@
+=pod
+
+=head1 NAME
+
+d2i_X509_ALGOR, i2d_X509_ALGOR - AlgorithmIdentifier functions.
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509.h>
+
+ X509_ALGOR *d2i_X509_ALGOR(X509_ALGOR **a, unsigned char **pp, long length);
+ int i2d_X509_ALGOR(X509_ALGOR *a, unsigned char **pp);
+
+=head1 DESCRIPTION
+
+These functions decode and encode an B<X509_ALGOR> structure which is
+equivalent to the B<AlgorithmIdentifier> structure.
+
+Othewise these behave in a similar way to d2i_X509() and i2d_X509()
+described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
+
+=head1 SEE ALSO
+
+L<d2i_X509(3)|d2i_X509(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/d2i_X509_CRL.pod b/openssl/doc/crypto/d2i_X509_CRL.pod
new file mode 100644
index 0000000..224f9e0
--- /dev/null
+++ b/openssl/doc/crypto/d2i_X509_CRL.pod
@@ -0,0 +1,37 @@
+=pod
+
+=head1 NAME
+
+d2i_X509_CRL, i2d_X509_CRL, d2i_X509_CRL_bio, d2i_509_CRL_fp,
+i2d_X509_CRL_bio, i2d_X509_CRL_fp - PKCS#10 certificate request functions.
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509.h>
+
+ X509_CRL *d2i_X509_CRL(X509_CRL **a, const unsigned char **pp, long length);
+ int i2d_X509_CRL(X509_CRL *a, unsigned char **pp);
+
+ X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **x);
+ X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **x);
+
+ int i2d_X509_CRL_bio(BIO *bp, X509_CRL *x);
+ int i2d_X509_CRL_fp(FILE *fp, X509_CRL *x);
+
+=head1 DESCRIPTION
+
+These functions decode and encode an X509 CRL (certificate revocation
+list).
+
+Othewise the functions behave in a similar way to d2i_X509() and i2d_X509()
+described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
+
+=head1 SEE ALSO
+
+L<d2i_X509(3)|d2i_X509(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/d2i_X509_NAME.pod b/openssl/doc/crypto/d2i_X509_NAME.pod
new file mode 100644
index 0000000..343ffe1
--- /dev/null
+++ b/openssl/doc/crypto/d2i_X509_NAME.pod
@@ -0,0 +1,31 @@
+=pod
+
+=head1 NAME
+
+d2i_X509_NAME, i2d_X509_NAME - X509_NAME encoding functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509.h>
+
+ X509_NAME *d2i_X509_NAME(X509_NAME **a, unsigned char **pp, long length);
+ int i2d_X509_NAME(X509_NAME *a, unsigned char **pp);
+
+=head1 DESCRIPTION
+
+These functions decode and encode an B<X509_NAME> structure which is the
+the same as the B<Name> type defined in RFC2459 (and elsewhere) and used
+for example in certificate subject and issuer names.
+
+Othewise the functions behave in a similar way to d2i_X509() and i2d_X509()
+described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
+
+=head1 SEE ALSO
+
+L<d2i_X509(3)|d2i_X509(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/d2i_X509_REQ.pod b/openssl/doc/crypto/d2i_X509_REQ.pod
new file mode 100644
index 0000000..91c0c19
--- /dev/null
+++ b/openssl/doc/crypto/d2i_X509_REQ.pod
@@ -0,0 +1,36 @@
+=pod
+
+=head1 NAME
+
+d2i_X509_REQ, i2d_X509_REQ, d2i_X509_REQ_bio, d2i_X509_REQ_fp,
+i2d_X509_REQ_bio, i2d_X509_REQ_fp - PKCS#10 certificate request functions.
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509.h>
+
+ X509_REQ *d2i_X509_REQ(X509_REQ **a, const unsigned char **pp, long length);
+ int i2d_X509_REQ(X509_REQ *a, unsigned char **pp);
+
+ X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **x);
+ X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **x);
+
+ int i2d_X509_REQ_bio(BIO *bp, X509_REQ *x);
+ int i2d_X509_REQ_fp(FILE *fp, X509_REQ *x);
+
+=head1 DESCRIPTION
+
+These functions decode and encode a PKCS#10 certificate request.
+
+Othewise these behave in a similar way to d2i_X509() and i2d_X509()
+described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
+
+=head1 SEE ALSO
+
+L<d2i_X509(3)|d2i_X509(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/d2i_X509_SIG.pod b/openssl/doc/crypto/d2i_X509_SIG.pod
new file mode 100644
index 0000000..e48fd79
--- /dev/null
+++ b/openssl/doc/crypto/d2i_X509_SIG.pod
@@ -0,0 +1,30 @@
+=pod
+
+=head1 NAME
+
+d2i_X509_SIG, i2d_X509_SIG - DigestInfo functions.
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509.h>
+
+ X509_SIG *d2i_X509_SIG(X509_SIG **a, unsigned char **pp, long length);
+ int i2d_X509_SIG(X509_SIG *a, unsigned char **pp);
+
+=head1 DESCRIPTION
+
+These functions decode and encode an X509_SIG structure which is
+equivalent to the B<DigestInfo> structure defined in PKCS#1 and PKCS#7.
+
+Othewise these behave in a similar way to d2i_X509() and i2d_X509()
+described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
+
+=head1 SEE ALSO
+
+L<d2i_X509(3)|d2i_X509(3)>
+
+=head1 HISTORY
+
+TBA
+
+=cut
diff --git a/openssl/doc/crypto/des.pod b/openssl/doc/crypto/des.pod
new file mode 100644
index 0000000..6f0cf1c
--- /dev/null
+++ b/openssl/doc/crypto/des.pod
@@ -0,0 +1,358 @@
+=pod
+
+=head1 NAME
+
+DES_random_key, DES_set_key, DES_key_sched, DES_set_key_checked,
+DES_set_key_unchecked, DES_set_odd_parity, DES_is_weak_key,
+DES_ecb_encrypt, DES_ecb2_encrypt, DES_ecb3_encrypt, DES_ncbc_encrypt,
+DES_cfb_encrypt, DES_ofb_encrypt, DES_pcbc_encrypt, DES_cfb64_encrypt,
+DES_ofb64_encrypt, DES_xcbc_encrypt, DES_ede2_cbc_encrypt,
+DES_ede2_cfb64_encrypt, DES_ede2_ofb64_encrypt, DES_ede3_cbc_encrypt,
+DES_ede3_cbcm_encrypt, DES_ede3_cfb64_encrypt, DES_ede3_ofb64_encrypt,
+DES_cbc_cksum, DES_quad_cksum, DES_string_to_key, DES_string_to_2keys,
+DES_fcrypt, DES_crypt, DES_enc_read, DES_enc_write - DES encryption
+
+=head1 SYNOPSIS
+
+ #include <openssl/des.h>
+
+ void DES_random_key(DES_cblock *ret);
+
+ int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule);
+ int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule);
+ int DES_set_key_checked(const_DES_cblock *key,
+        DES_key_schedule *schedule);
+ void DES_set_key_unchecked(const_DES_cblock *key,
+        DES_key_schedule *schedule);
+
+ void DES_set_odd_parity(DES_cblock *key);
+ int DES_is_weak_key(const_DES_cblock *key);
+
+ void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, 
+        DES_key_schedule *ks, int enc);
+ void DES_ecb2_encrypt(const_DES_cblock *input, DES_cblock *output, 
+        DES_key_schedule *ks1, DES_key_schedule *ks2, int enc);
+ void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, 
+        DES_key_schedule *ks1, DES_key_schedule *ks2, 
+        DES_key_schedule *ks3, int enc);
+
+ void DES_ncbc_encrypt(const unsigned char *input, unsigned char *output, 
+        long length, DES_key_schedule *schedule, DES_cblock *ivec, 
+        int enc);
+ void DES_cfb_encrypt(const unsigned char *in, unsigned char *out,
+        int numbits, long length, DES_key_schedule *schedule,
+        DES_cblock *ivec, int enc);
+ void DES_ofb_encrypt(const unsigned char *in, unsigned char *out,
+        int numbits, long length, DES_key_schedule *schedule,
+        DES_cblock *ivec);
+ void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output, 
+        long length, DES_key_schedule *schedule, DES_cblock *ivec, 
+        int enc);
+ void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+        long length, DES_key_schedule *schedule, DES_cblock *ivec,
+        int *num, int enc);
+ void DES_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+        long length, DES_key_schedule *schedule, DES_cblock *ivec,
+        int *num);
+
+ void DES_xcbc_encrypt(const unsigned char *input, unsigned char *output, 
+        long length, DES_key_schedule *schedule, DES_cblock *ivec, 
+        const_DES_cblock *inw, const_DES_cblock *outw, int enc);
+
+ void DES_ede2_cbc_encrypt(const unsigned char *input,
+        unsigned char *output, long length, DES_key_schedule *ks1,
+        DES_key_schedule *ks2, DES_cblock *ivec, int enc);
+ void DES_ede2_cfb64_encrypt(const unsigned char *in,
+        unsigned char *out, long length, DES_key_schedule *ks1,
+        DES_key_schedule *ks2, DES_cblock *ivec, int *num, int enc);
+ void DES_ede2_ofb64_encrypt(const unsigned char *in,
+        unsigned char *out, long length, DES_key_schedule *ks1,
+        DES_key_schedule *ks2, DES_cblock *ivec, int *num);
+
+ void DES_ede3_cbc_encrypt(const unsigned char *input,
+        unsigned char *output, long length, DES_key_schedule *ks1,
+        DES_key_schedule *ks2, DES_key_schedule *ks3, DES_cblock *ivec,
+        int enc);
+ void DES_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out, 
+        long length, DES_key_schedule *ks1, DES_key_schedule *ks2, 
+        DES_key_schedule *ks3, DES_cblock *ivec1, DES_cblock *ivec2, 
+        int enc);
+ void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out, 
+        long length, DES_key_schedule *ks1, DES_key_schedule *ks2,
+        DES_key_schedule *ks3, DES_cblock *ivec, int *num, int enc);
+ void DES_ede3_ofb64_encrypt(const unsigned char *in, unsigned char *out, 
+        long length, DES_key_schedule *ks1, 
+        DES_key_schedule *ks2, DES_key_schedule *ks3, 
+        DES_cblock *ivec, int *num);
+
+ DES_LONG DES_cbc_cksum(const unsigned char *input, DES_cblock *output, 
+        long length, DES_key_schedule *schedule, 
+        const_DES_cblock *ivec);
+ DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[], 
+        long length, int out_count, DES_cblock *seed);
+ void DES_string_to_key(const char *str, DES_cblock *key);
+ void DES_string_to_2keys(const char *str, DES_cblock *key1,
+        DES_cblock *key2);
+
+ char *DES_fcrypt(const char *buf, const char *salt, char *ret);
+ char *DES_crypt(const char *buf, const char *salt);
+
+ int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched,
+        DES_cblock *iv);
+ int DES_enc_write(int fd, const void *buf, int len,
+        DES_key_schedule *sched, DES_cblock *iv);
+
+=head1 DESCRIPTION
+
+This library contains a fast implementation of the DES encryption
+algorithm.
+
+There are two phases to the use of DES encryption.  The first is the
+generation of a I<DES_key_schedule> from a key, the second is the
+actual encryption.  A DES key is of type I<DES_cblock>. This type is
+consists of 8 bytes with odd parity.  The least significant bit in
+each byte is the parity bit.  The key schedule is an expanded form of
+the key; it is used to speed the encryption process.
+
+DES_random_key() generates a random key.  The PRNG must be seeded
+prior to using this function (see L<rand(3)|rand(3)>).  If the PRNG
+could not generate a secure key, 0 is returned.
+
+Before a DES key can be used, it must be converted into the
+architecture dependent I<DES_key_schedule> via the
+DES_set_key_checked() or DES_set_key_unchecked() function.
+
+DES_set_key_checked() will check that the key passed is of odd parity
+and is not a week or semi-weak key.  If the parity is wrong, then -1
+is returned.  If the key is a weak key, then -2 is returned.  If an
+error is returned, the key schedule is not generated.
+
+DES_set_key() works like
+DES_set_key_checked() if the I<DES_check_key> flag is non-zero,
+otherwise like DES_set_key_unchecked().  These functions are available
+for compatibility; it is recommended to use a function that does not
+depend on a global variable.
+
+DES_set_odd_parity() sets the parity of the passed I<key> to odd.
+
+DES_is_weak_key() returns 1 is the passed key is a weak key, 0 if it
+is ok.  The probability that a randomly generated key is weak is
+1/2^52, so it is not really worth checking for them.
+
+The following routines mostly operate on an input and output stream of
+I<DES_cblock>s.
+
+DES_ecb_encrypt() is the basic DES encryption routine that encrypts or
+decrypts a single 8-byte I<DES_cblock> in I<electronic code book>
+(ECB) mode.  It always transforms the input data, pointed to by
+I<input>, into the output data, pointed to by the I<output> argument.
+If the I<encrypt> argument is non-zero (DES_ENCRYPT), the I<input>
+(cleartext) is encrypted in to the I<output> (ciphertext) using the
+key_schedule specified by the I<schedule> argument, previously set via
+I<DES_set_key>. If I<encrypt> is zero (DES_DECRYPT), the I<input> (now
+ciphertext) is decrypted into the I<output> (now cleartext).  Input
+and output may overlap.  DES_ecb_encrypt() does not return a value.
+
+DES_ecb3_encrypt() encrypts/decrypts the I<input> block by using
+three-key Triple-DES encryption in ECB mode.  This involves encrypting
+the input with I<ks1>, decrypting with the key schedule I<ks2>, and
+then encrypting with I<ks3>.  This routine greatly reduces the chances
+of brute force breaking of DES and has the advantage of if I<ks1>,
+I<ks2> and I<ks3> are the same, it is equivalent to just encryption
+using ECB mode and I<ks1> as the key.
+
+The macro DES_ecb2_encrypt() is provided to perform two-key Triple-DES
+encryption by using I<ks1> for the final encryption.
+
+DES_ncbc_encrypt() encrypts/decrypts using the I<cipher-block-chaining>
+(CBC) mode of DES.  If the I<encrypt> argument is non-zero, the
+routine cipher-block-chain encrypts the cleartext data pointed to by
+the I<input> argument into the ciphertext pointed to by the I<output>
+argument, using the key schedule provided by the I<schedule> argument,
+and initialization vector provided by the I<ivec> argument.  If the
+I<length> argument is not an integral multiple of eight bytes, the
+last block is copied to a temporary area and zero filled.  The output
+is always an integral multiple of eight bytes.
+
+DES_xcbc_encrypt() is RSA's DESX mode of DES.  It uses I<inw> and
+I<outw> to 'whiten' the encryption.  I<inw> and I<outw> are secret
+(unlike the iv) and are as such, part of the key.  So the key is sort
+of 24 bytes.  This is much better than CBC DES.
+
+DES_ede3_cbc_encrypt() implements outer triple CBC DES encryption with
+three keys. This means that each DES operation inside the CBC mode is
+really an C<C=E(ks3,D(ks2,E(ks1,M)))>.  This mode is used by SSL.
+
+The DES_ede2_cbc_encrypt() macro implements two-key Triple-DES by
+reusing I<ks1> for the final encryption.  C<C=E(ks1,D(ks2,E(ks1,M)))>.
+This form of Triple-DES is used by the RSAREF library.
+
+DES_pcbc_encrypt() encrypt/decrypts using the propagating cipher block
+chaining mode used by Kerberos v4. Its parameters are the same as
+DES_ncbc_encrypt().
+
+DES_cfb_encrypt() encrypt/decrypts using cipher feedback mode.  This
+method takes an array of characters as input and outputs and array of
+characters.  It does not require any padding to 8 character groups.
+Note: the I<ivec> variable is changed and the new changed value needs to
+be passed to the next call to this function.  Since this function runs
+a complete DES ECB encryption per I<numbits>, this function is only
+suggested for use when sending small numbers of characters.
+
+DES_cfb64_encrypt()
+implements CFB mode of DES with 64bit feedback.  Why is this
+useful you ask?  Because this routine will allow you to encrypt an
+arbitrary number of bytes, no 8 byte padding.  Each call to this
+routine will encrypt the input bytes to output and then update ivec
+and num.  num contains 'how far' we are though ivec.  If this does
+not make much sense, read more about cfb mode of DES :-).
+
+DES_ede3_cfb64_encrypt() and DES_ede2_cfb64_encrypt() is the same as
+DES_cfb64_encrypt() except that Triple-DES is used.
+
+DES_ofb_encrypt() encrypts using output feedback mode.  This method
+takes an array of characters as input and outputs and array of
+characters.  It does not require any padding to 8 character groups.
+Note: the I<ivec> variable is changed and the new changed value needs to
+be passed to the next call to this function.  Since this function runs
+a complete DES ECB encryption per numbits, this function is only
+suggested for use when sending small numbers of characters.
+
+DES_ofb64_encrypt() is the same as DES_cfb64_encrypt() using Output
+Feed Back mode.
+
+DES_ede3_ofb64_encrypt() and DES_ede2_ofb64_encrypt() is the same as
+DES_ofb64_encrypt(), using Triple-DES.
+
+The following functions are included in the DES library for
+compatibility with the MIT Kerberos library.
+
+DES_cbc_cksum() produces an 8 byte checksum based on the input stream
+(via CBC encryption).  The last 4 bytes of the checksum are returned
+and the complete 8 bytes are placed in I<output>. This function is
+used by Kerberos v4.  Other applications should use
+L<EVP_DigestInit(3)|EVP_DigestInit(3)> etc. instead.
+
+DES_quad_cksum() is a Kerberos v4 function.  It returns a 4 byte
+checksum from the input bytes.  The algorithm can be iterated over the
+input, depending on I<out_count>, 1, 2, 3 or 4 times.  If I<output> is
+non-NULL, the 8 bytes generated by each pass are written into
+I<output>.
+
+The following are DES-based transformations:
+
+DES_fcrypt() is a fast version of the Unix crypt(3) function.  This
+version takes only a small amount of space relative to other fast
+crypt() implementations.  This is different to the normal crypt in
+that the third parameter is the buffer that the return value is
+written into.  It needs to be at least 14 bytes long.  This function
+is thread safe, unlike the normal crypt.
+
+DES_crypt() is a faster replacement for the normal system crypt().
+This function calls DES_fcrypt() with a static array passed as the
+third parameter.  This emulates the normal non-thread safe semantics
+of crypt(3).
+
+DES_enc_write() writes I<len> bytes to file descriptor I<fd> from
+buffer I<buf>. The data is encrypted via I<pcbc_encrypt> (default)
+using I<sched> for the key and I<iv> as a starting vector.  The actual
+data send down I<fd> consists of 4 bytes (in network byte order)
+containing the length of the following encrypted data.  The encrypted
+data then follows, padded with random data out to a multiple of 8
+bytes.
+
+DES_enc_read() is used to read I<len> bytes from file descriptor
+I<fd> into buffer I<buf>. The data being read from I<fd> is assumed to
+have come from DES_enc_write() and is decrypted using I<sched> for
+the key schedule and I<iv> for the initial vector.
+
+B<Warning:> The data format used by DES_enc_write() and DES_enc_read()
+has a cryptographic weakness: When asked to write more than MAXWRITE
+bytes, DES_enc_write() will split the data into several chunks that
+are all encrypted using the same IV.  So don't use these functions
+unless you are sure you know what you do (in which case you might not
+want to use them anyway).  They cannot handle non-blocking sockets.
+DES_enc_read() uses an internal state and thus cannot be used on
+multiple files.
+
+I<DES_rw_mode> is used to specify the encryption mode to use with
+DES_enc_read() and DES_end_write().  If set to I<DES_PCBC_MODE> (the
+default), DES_pcbc_encrypt is used.  If set to I<DES_CBC_MODE>
+DES_cbc_encrypt is used.
+
+=head1 NOTES
+
+Single-key DES is insecure due to its short key size.  ECB mode is
+not suitable for most applications; see L<des_modes(7)|des_modes(7)>.
+
+The L<evp(3)|evp(3)> library provides higher-level encryption functions.
+
+=head1 BUGS
+
+DES_3cbc_encrypt() is flawed and must not be used in applications.
+
+DES_cbc_encrypt() does not modify B<ivec>; use DES_ncbc_encrypt()
+instead.
+
+DES_cfb_encrypt() and DES_ofb_encrypt() operates on input of 8 bits.
+What this means is that if you set numbits to 12, and length to 2, the
+first 12 bits will come from the 1st input byte and the low half of
+the second input byte.  The second 12 bits will have the low 8 bits
+taken from the 3rd input byte and the top 4 bits taken from the 4th
+input byte.  The same holds for output.  This function has been
+implemented this way because most people will be using a multiple of 8
+and because once you get into pulling bytes input bytes apart things
+get ugly!
+
+DES_string_to_key() is available for backward compatibility with the
+MIT library.  New applications should use a cryptographic hash function.
+The same applies for DES_string_to_2key().
+
+=head1 CONFORMING TO
+
+ANSI X3.106
+
+The B<des> library was written to be source code compatible with
+the MIT Kerberos library.
+
+=head1 SEE ALSO
+
+crypt(3), L<des_modes(7)|des_modes(7)>, L<evp(3)|evp(3)>, L<rand(3)|rand(3)>
+
+=head1 HISTORY
+
+In OpenSSL 0.9.7, all des_ functions were renamed to DES_ to avoid
+clashes with older versions of libdes.  Compatibility des_ functions
+are provided for a short while, as well as crypt().
+Declarations for these are in <openssl/des_old.h>. There is no DES_
+variant for des_random_seed().
+This will happen to other functions
+as well if they are deemed redundant (des_random_seed() just calls
+RAND_seed() and is present for backward compatibility only), buggy or
+already scheduled for removal.
+
+des_cbc_cksum(), des_cbc_encrypt(), des_ecb_encrypt(),
+des_is_weak_key(), des_key_sched(), des_pcbc_encrypt(),
+des_quad_cksum(), des_random_key() and des_string_to_key()
+are available in the MIT Kerberos library;
+des_check_key_parity(), des_fixup_key_parity() and des_is_weak_key()
+are available in newer versions of that library.
+
+des_set_key_checked() and des_set_key_unchecked() were added in
+OpenSSL 0.9.5.
+
+des_generate_random_block(), des_init_random_number_generator(),
+des_new_random_key(), des_set_random_generator_seed() and
+des_set_sequence_number() and des_rand_data() are used in newer
+versions of Kerberos but are not implemented here.
+
+des_random_key() generated cryptographically weak random data in
+SSLeay and in OpenSSL prior version 0.9.5, as well as in the original
+MIT library.
+
+=head1 AUTHOR
+
+Eric Young (eay@cryptsoft.com). Modified for the OpenSSL project
+(http://www.openssl.org).
+
+=cut
diff --git a/openssl/doc/crypto/des_modes.pod b/openssl/doc/crypto/des_modes.pod
new file mode 100644
index 0000000..e883ca8
--- /dev/null
+++ b/openssl/doc/crypto/des_modes.pod
@@ -0,0 +1,255 @@
+=pod
+
+=for comment openssl_manual_section:7
+
+=head1 NAME
+
+des_modes - the variants of DES and other crypto algorithms of OpenSSL
+
+=head1 DESCRIPTION
+
+Several crypto algorithms for OpenSSL can be used in a number of modes.  Those
+are used for using block ciphers in a way similar to stream ciphers, among
+other things.
+
+=head1 OVERVIEW
+
+=head2 Electronic Codebook Mode (ECB)
+
+Normally, this is found as the function I<algorithm>_ecb_encrypt().
+
+=over 2
+
+=item *
+
+64 bits are enciphered at a time.
+
+=item *
+
+The order of the blocks can be rearranged without detection.
+
+=item *
+
+The same plaintext block always produces the same ciphertext block
+(for the same key) making it vulnerable to a 'dictionary attack'.
+
+=item *
+
+An error will only affect one ciphertext block.
+
+=back
+
+=head2 Cipher Block Chaining Mode (CBC)
+
+Normally, this is found as the function I<algorithm>_cbc_encrypt().
+Be aware that des_cbc_encrypt() is not really DES CBC (it does
+not update the IV); use des_ncbc_encrypt() instead.
+
+=over 2
+
+=item *
+
+a multiple of 64 bits are enciphered at a time.
+
+=item *
+
+The CBC mode produces the same ciphertext whenever the same
+plaintext is encrypted using the same key and starting variable.
+
+=item *
+
+The chaining operation makes the ciphertext blocks dependent on the
+current and all preceding plaintext blocks and therefore blocks can not
+be rearranged.
+
+=item *
+
+The use of different starting variables prevents the same plaintext
+enciphering to the same ciphertext.
+
+=item *
+
+An error will affect the current and the following ciphertext blocks.
+
+=back
+
+=head2 Cipher Feedback Mode (CFB)
+
+Normally, this is found as the function I<algorithm>_cfb_encrypt().
+
+=over 2
+
+=item *
+
+a number of bits (j) <= 64 are enciphered at a time.
+
+=item *
+
+The CFB mode produces the same ciphertext whenever the same
+plaintext is encrypted using the same key and starting variable.
+
+=item *
+
+The chaining operation makes the ciphertext variables dependent on the
+current and all preceding variables and therefore j-bit variables are
+chained together and can not be rearranged.
+
+=item *
+
+The use of different starting variables prevents the same plaintext
+enciphering to the same ciphertext.
+
+=item *
+
+The strength of the CFB mode depends on the size of k (maximal if
+j == k).  In my implementation this is always the case.
+
+=item *
+
+Selection of a small value for j will require more cycles through
+the encipherment algorithm per unit of plaintext and thus cause
+greater processing overheads.
+
+=item *
+
+Only multiples of j bits can be enciphered.
+
+=item *
+
+An error will affect the current and the following ciphertext variables.
+
+=back
+
+=head2 Output Feedback Mode (OFB)
+
+Normally, this is found as the function I<algorithm>_ofb_encrypt().
+
+=over 2
+
+
+=item *
+
+a number of bits (j) <= 64 are enciphered at a time.
+
+=item *
+
+The OFB mode produces the same ciphertext whenever the same
+plaintext enciphered using the same key and starting variable.  More
+over, in the OFB mode the same key stream is produced when the same
+key and start variable are used.  Consequently, for security reasons
+a specific start variable should be used only once for a given key.
+
+=item *
+
+The absence of chaining makes the OFB more vulnerable to specific attacks.
+
+=item *
+
+The use of different start variables values prevents the same
+plaintext enciphering to the same ciphertext, by producing different
+key streams.
+
+=item *
+
+Selection of a small value for j will require more cycles through
+the encipherment algorithm per unit of plaintext and thus cause
+greater processing overheads.
+
+=item *
+
+Only multiples of j bits can be enciphered.
+
+=item *
+
+OFB mode of operation does not extend ciphertext errors in the
+resultant plaintext output.  Every bit error in the ciphertext causes
+only one bit to be in error in the deciphered plaintext.
+
+=item *
+
+OFB mode is not self-synchronizing.  If the two operation of
+encipherment and decipherment get out of synchronism, the system needs
+to be re-initialized.
+
+=item *
+
+Each re-initialization should use a value of the start variable
+different from the start variable values used before with the same
+key.  The reason for this is that an identical bit stream would be
+produced each time from the same parameters.  This would be
+susceptible to a 'known plaintext' attack.
+
+=back
+
+=head2 Triple ECB Mode
+
+Normally, this is found as the function I<algorithm>_ecb3_encrypt().
+
+=over 2
+
+=item *
+
+Encrypt with key1, decrypt with key2 and encrypt with key3 again.
+
+=item *
+
+As for ECB encryption but increases the key length to 168 bits.
+There are theoretic attacks that can be used that make the effective
+key length 112 bits, but this attack also requires 2^56 blocks of
+memory, not very likely, even for the NSA.
+
+=item *
+
+If both keys are the same it is equivalent to encrypting once with
+just one key.
+
+=item *
+
+If the first and last key are the same, the key length is 112 bits.
+There are attacks that could reduce the effective key strength
+to only slightly more than 56 bits, but these require a lot of memory.
+
+=item *
+
+If all 3 keys are the same, this is effectively the same as normal
+ecb mode.
+
+=back
+
+=head2 Triple CBC Mode
+
+Normally, this is found as the function I<algorithm>_ede3_cbc_encrypt().
+
+=over 2
+
+
+=item *
+
+Encrypt with key1, decrypt with key2 and then encrypt with key3.
+
+=item *
+
+As for CBC encryption but increases the key length to 168 bits with
+the same restrictions as for triple ecb mode.
+
+=back
+
+=head1 NOTES
+
+This text was been written in large parts by Eric Young in his original
+documentation for SSLeay, the predecessor of OpenSSL.  In turn, he attributed
+it to:
+
+	AS 2805.5.2
+	Australian Standard
+	Electronic funds transfer - Requirements for interfaces,
+	Part 5.2: Modes of operation for an n-bit block cipher algorithm
+	Appendix A
+
+=head1 SEE ALSO
+
+L<blowfish(3)|blowfish(3)>, L<des(3)|des(3)>, L<idea(3)|idea(3)>,
+L<rc2(3)|rc2(3)>
+
+=cut
+
diff --git a/openssl/doc/crypto/dh.pod b/openssl/doc/crypto/dh.pod
new file mode 100644
index 0000000..c3ccd06
--- /dev/null
+++ b/openssl/doc/crypto/dh.pod
@@ -0,0 +1,78 @@
+=pod
+
+=head1 NAME
+
+dh - Diffie-Hellman key agreement
+
+=head1 SYNOPSIS
+
+ #include <openssl/dh.h>
+ #include <openssl/engine.h>
+
+ DH *	DH_new(void);
+ void	DH_free(DH *dh);
+
+ int	DH_size(const DH *dh);
+
+ DH *	DH_generate_parameters(int prime_len, int generator,
+		void (*callback)(int, int, void *), void *cb_arg);
+ int	DH_check(const DH *dh, int *codes);
+
+ int	DH_generate_key(DH *dh);
+ int	DH_compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh);
+
+ void DH_set_default_method(const DH_METHOD *meth);
+ const DH_METHOD *DH_get_default_method(void);
+ int DH_set_method(DH *dh, const DH_METHOD *meth);
+ DH *DH_new_method(ENGINE *engine);
+ const DH_METHOD *DH_OpenSSL(void);
+
+ int DH_get_ex_new_index(long argl, char *argp, int (*new_func)(),
+	     int (*dup_func)(), void (*free_func)());
+ int DH_set_ex_data(DH *d, int idx, char *arg);
+ char *DH_get_ex_data(DH *d, int idx);
+
+ DH *	d2i_DHparams(DH **a, unsigned char **pp, long length);
+ int	i2d_DHparams(const DH *a, unsigned char **pp);
+
+ int	DHparams_print_fp(FILE *fp, const DH *x);
+ int	DHparams_print(BIO *bp, const DH *x);
+
+=head1 DESCRIPTION
+
+These functions implement the Diffie-Hellman key agreement protocol.
+The generation of shared DH parameters is described in
+L<DH_generate_parameters(3)|DH_generate_parameters(3)>; L<DH_generate_key(3)|DH_generate_key(3)> describes how
+to perform a key agreement.
+
+The B<DH> structure consists of several BIGNUM components.
+
+ struct
+        {
+        BIGNUM *p;		// prime number (shared)
+        BIGNUM *g;		// generator of Z_p (shared)
+        BIGNUM *priv_key;	// private DH value x
+        BIGNUM *pub_key;	// public DH value g^x
+        // ...
+        };
+ DH
+
+Note that DH keys may use non-standard B<DH_METHOD> implementations,
+either directly or by the use of B<ENGINE> modules. In some cases (eg. an
+ENGINE providing support for hardware-embedded keys), these BIGNUM values
+will not be used by the implementation or may be used for alternative data
+storage. For this reason, applications should generally avoid using DH
+structure elements directly and instead use API functions to query or
+modify keys.
+
+=head1 SEE ALSO
+
+L<dhparam(1)|dhparam(1)>, L<bn(3)|bn(3)>, L<dsa(3)|dsa(3)>, L<err(3)|err(3)>,
+L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>, L<engine(3)|engine(3)>,
+L<DH_set_method(3)|DH_set_method(3)>, L<DH_new(3)|DH_new(3)>,
+L<DH_get_ex_new_index(3)|DH_get_ex_new_index(3)>,
+L<DH_generate_parameters(3)|DH_generate_parameters(3)>,
+L<DH_compute_key(3)|DH_compute_key(3)>, L<d2i_DHparams(3)|d2i_DHparams(3)>,
+L<RSA_print(3)|RSA_print(3)> 
+
+=cut
diff --git a/openssl/doc/crypto/dsa.pod b/openssl/doc/crypto/dsa.pod
new file mode 100644
index 0000000..da07d2b
--- /dev/null
+++ b/openssl/doc/crypto/dsa.pod
@@ -0,0 +1,114 @@
+=pod
+
+=head1 NAME
+
+dsa - Digital Signature Algorithm
+
+=head1 SYNOPSIS
+
+ #include <openssl/dsa.h>
+ #include <openssl/engine.h>
+
+ DSA *	DSA_new(void);
+ void	DSA_free(DSA *dsa);
+
+ int	DSA_size(const DSA *dsa);
+
+ DSA *	DSA_generate_parameters(int bits, unsigned char *seed,
+                int seed_len, int *counter_ret, unsigned long *h_ret,
+		void (*callback)(int, int, void *), void *cb_arg);
+
+ DH *	DSA_dup_DH(const DSA *r);
+
+ int	DSA_generate_key(DSA *dsa);
+
+ int	DSA_sign(int dummy, const unsigned char *dgst, int len,
+		unsigned char *sigret, unsigned int *siglen, DSA *dsa);
+ int	DSA_sign_setup(DSA *dsa, BN_CTX *ctx, BIGNUM **kinvp,
+                BIGNUM **rp);
+ int	DSA_verify(int dummy, const unsigned char *dgst, int len,
+		const unsigned char *sigbuf, int siglen, DSA *dsa);
+
+ void DSA_set_default_method(const DSA_METHOD *meth);
+ const DSA_METHOD *DSA_get_default_method(void);
+ int DSA_set_method(DSA *dsa, const DSA_METHOD *meth);
+ DSA *DSA_new_method(ENGINE *engine);
+ const DSA_METHOD *DSA_OpenSSL(void);
+
+ int DSA_get_ex_new_index(long argl, char *argp, int (*new_func)(),
+	     int (*dup_func)(), void (*free_func)());
+ int DSA_set_ex_data(DSA *d, int idx, char *arg);
+ char *DSA_get_ex_data(DSA *d, int idx);
+
+ DSA_SIG *DSA_SIG_new(void);
+ void	DSA_SIG_free(DSA_SIG *a);
+ int	i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp);
+ DSA_SIG *d2i_DSA_SIG(DSA_SIG **v, unsigned char **pp, long length);
+
+ DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+ int	DSA_do_verify(const unsigned char *dgst, int dgst_len,
+	     DSA_SIG *sig, DSA *dsa);
+
+ DSA *	d2i_DSAPublicKey(DSA **a, unsigned char **pp, long length);
+ DSA *	d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length);
+ DSA * 	d2i_DSAparams(DSA **a, unsigned char **pp, long length);
+ int	i2d_DSAPublicKey(const DSA *a, unsigned char **pp);
+ int 	i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
+ int	i2d_DSAparams(const DSA *a,unsigned char **pp);
+
+ int	DSAparams_print(BIO *bp, const DSA *x);
+ int	DSAparams_print_fp(FILE *fp, const DSA *x);
+ int	DSA_print(BIO *bp, const DSA *x, int off);
+ int	DSA_print_fp(FILE *bp, const DSA *x, int off);
+
+=head1 DESCRIPTION
+
+These functions implement the Digital Signature Algorithm (DSA).  The
+generation of shared DSA parameters is described in
+L<DSA_generate_parameters(3)|DSA_generate_parameters(3)>;
+L<DSA_generate_key(3)|DSA_generate_key(3)> describes how to
+generate a signature key. Signature generation and verification are
+described in L<DSA_sign(3)|DSA_sign(3)>.
+
+The B<DSA> structure consists of several BIGNUM components.
+
+ struct
+        {
+        BIGNUM *p;		// prime number (public)
+        BIGNUM *q;		// 160-bit subprime, q | p-1 (public)
+        BIGNUM *g;		// generator of subgroup (public)
+        BIGNUM *priv_key;	// private key x
+        BIGNUM *pub_key;	// public key y = g^x
+        // ...
+        }
+ DSA;
+
+In public keys, B<priv_key> is NULL.
+
+Note that DSA keys may use non-standard B<DSA_METHOD> implementations,
+either directly or by the use of B<ENGINE> modules. In some cases (eg. an
+ENGINE providing support for hardware-embedded keys), these BIGNUM values
+will not be used by the implementation or may be used for alternative data
+storage. For this reason, applications should generally avoid using DSA
+structure elements directly and instead use API functions to query or
+modify keys.
+
+=head1 CONFORMING TO
+
+US Federal Information Processing Standard FIPS 186 (Digital Signature
+Standard, DSS), ANSI X9.30
+
+=head1 SEE ALSO
+
+L<bn(3)|bn(3)>, L<dh(3)|dh(3)>, L<err(3)|err(3)>, L<rand(3)|rand(3)>,
+L<rsa(3)|rsa(3)>, L<sha(3)|sha(3)>, L<engine(3)|engine(3)>,
+L<DSA_new(3)|DSA_new(3)>,
+L<DSA_size(3)|DSA_size(3)>,
+L<DSA_generate_parameters(3)|DSA_generate_parameters(3)>,
+L<DSA_dup_DH(3)|DSA_dup_DH(3)>,
+L<DSA_generate_key(3)|DSA_generate_key(3)>,
+L<DSA_sign(3)|DSA_sign(3)>, L<DSA_set_method(3)|DSA_set_method(3)>,
+L<DSA_get_ex_new_index(3)|DSA_get_ex_new_index(3)>,
+L<RSA_print(3)|RSA_print(3)>
+
+=cut
diff --git a/openssl/doc/crypto/ecdsa.pod b/openssl/doc/crypto/ecdsa.pod
new file mode 100644
index 0000000..49b10f2
--- /dev/null
+++ b/openssl/doc/crypto/ecdsa.pod
@@ -0,0 +1,210 @@
+=pod
+
+=head1 NAME
+
+ecdsa - Elliptic Curve Digital Signature Algorithm
+
+=head1 SYNOPSIS
+
+ #include <openssl/ecdsa.h>
+
+ ECDSA_SIG*	ECDSA_SIG_new(void);
+ void		ECDSA_SIG_free(ECDSA_SIG *sig);
+ int		i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
+ ECDSA_SIG*	d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, 
+		long len);
+
+ ECDSA_SIG*	ECDSA_do_sign(const unsigned char *dgst, int dgst_len,
+			EC_KEY *eckey);
+ ECDSA_SIG*	ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, 
+			const BIGNUM *kinv, const BIGNUM *rp,
+			EC_KEY *eckey);
+ int		ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
+			const ECDSA_SIG *sig, EC_KEY* eckey);
+ int		ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx,
+			BIGNUM **kinv, BIGNUM **rp);
+ int		ECDSA_sign(int type, const unsigned char *dgst,
+			int dgstlen, unsigned char *sig,
+			unsigned int *siglen, EC_KEY *eckey);
+ int		ECDSA_sign_ex(int type, const unsigned char *dgst,
+			int dgstlen, unsigned char *sig,
+			unsigned int *siglen, const BIGNUM *kinv, 
+			const BIGNUM *rp, EC_KEY *eckey);
+ int		ECDSA_verify(int type, const unsigned char *dgst,
+			int dgstlen, const unsigned char *sig,
+			int siglen, EC_KEY *eckey);
+ int		ECDSA_size(const EC_KEY *eckey);
+
+ const ECDSA_METHOD*	ECDSA_OpenSSL(void);
+ void		ECDSA_set_default_method(const ECDSA_METHOD *meth);
+ const ECDSA_METHOD*	ECDSA_get_default_method(void);
+ int		ECDSA_set_method(EC_KEY *eckey,const ECDSA_METHOD *meth);
+
+ int		ECDSA_get_ex_new_index(long argl, void *argp,
+			CRYPTO_EX_new *new_func,
+			CRYPTO_EX_dup *dup_func,
+			CRYPTO_EX_free *free_func);
+ int		ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg);
+ void*		ECDSA_get_ex_data(EC_KEY *d, int idx);
+
+=head1 DESCRIPTION
+
+The B<ECDSA_SIG> structure consists of two BIGNUMs for the
+r and s value of a ECDSA signature (see X9.62 or FIPS 186-2).
+
+ struct
+	{
+	BIGNUM *r;
+	BIGNUM *s;
+ } ECDSA_SIG;
+
+ECDSA_SIG_new() allocates a new B<ECDSA_SIG> structure (note: this
+function also allocates the BIGNUMs) and initialize it.
+
+ECDSA_SIG_free() frees the B<ECDSA_SIG> structure B<sig>.
+
+i2d_ECDSA_SIG() creates the DER encoding of the ECDSA signature
+B<sig> and writes the encoded signature to B<*pp> (note: if B<pp>
+is NULL B<i2d_ECDSA_SIG> returns the expected length in bytes of 
+the DER encoded signature). B<i2d_ECDSA_SIG> returns the length
+of the DER encoded signature (or 0 on error).
+
+d2i_ECDSA_SIG() decodes a DER encoded ECDSA signature and returns
+the decoded signature in a newly allocated B<ECDSA_SIG> structure.
+B<*sig> points to the buffer containing the DER encoded signature
+of size B<len>.
+
+ECDSA_size() returns the maximum length of a DER encoded
+ECDSA signature created with the private EC key B<eckey>.
+
+ECDSA_sign_setup() may be used to precompute parts of the
+signing operation. B<eckey> is the private EC key and B<ctx>
+is a pointer to B<BN_CTX> structure (or NULL). The precomputed
+values or returned in B<kinv> and B<rp> and can be used in a
+later call to B<ECDSA_sign_ex> or B<ECDSA_do_sign_ex>.
+
+ECDSA_sign() is wrapper function for ECDSA_sign_ex with B<kinv>
+and B<rp> set to NULL.
+
+ECDSA_sign_ex() computes a digital signature of the B<dgstlen> bytes
+hash value B<dgst> using the private EC key B<eckey> and the optional
+pre-computed values B<kinv> and B<rp>. The DER encoded signatures is
+stored in B<sig> and it's length is returned in B<sig_len>. Note: B<sig>
+must point to B<ECDSA_size> bytes of memory. The parameter B<type>
+is ignored.
+
+ECDSA_verify() verifies that the signature in B<sig> of size
+B<siglen> is a valid ECDSA signature of the hash value
+value B<dgst> of size B<dgstlen> using the public key B<eckey>.
+The parameter B<type> is ignored.
+
+ECDSA_do_sign() is wrapper function for ECDSA_do_sign_ex with B<kinv>
+and B<rp> set to NULL.
+
+ECDSA_do_sign_ex() computes a digital signature of the B<dgst_len>
+bytes hash value B<dgst> using the private key B<eckey> and the
+optional pre-computed values B<kinv> and B<rp>. The signature is
+returned in a newly allocated B<ECDSA_SIG> structure (or NULL on error).
+
+ECDSA_do_verify() verifies that the signature B<sig> is a valid
+ECDSA signature of the hash value B<dgst> of size B<dgst_len>
+using the public key B<eckey>.
+
+=head1 RETURN VALUES
+
+ECDSA_size() returns the maximum length signature or 0 on error.
+
+ECDSA_sign_setup() and ECDSA_sign() return 1 if successful or -1
+on error.
+
+ECDSA_verify() and ECDSA_do_verify() return 1 for a valid
+signature, 0 for an invalid signature and -1 on error.
+The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
+
+=head1 EXAMPLES
+
+Creating a ECDSA signature of given SHA-1 hash value using the
+named curve secp192k1.
+
+First step: create a EC_KEY object (note: this part is B<not> ECDSA
+specific)
+
+ int        ret;
+ ECDSA_SIG *sig;
+ EC_KEY    *eckey = EC_KEY_new();
+ if (eckey == NULL)
+	{
+	/* error */
+	}
+ key->group = EC_GROUP_new_by_nid(NID_secp192k1);
+ if (key->group == NULL)
+	{
+	/* error */
+	}
+ if (!EC_KEY_generate_key(eckey))
+	{
+	/* error */
+	}
+
+Second step: compute the ECDSA signature of a SHA-1 hash value 
+using B<ECDSA_do_sign> 
+
+ sig = ECDSA_do_sign(digest, 20, eckey);
+ if (sig == NULL)
+	{
+	/* error */
+	}
+
+or using B<ECDSA_sign>
+
+ unsigned char *buffer, *pp;
+ int            buf_len;
+ buf_len = ECDSA_size(eckey);
+ buffer  = OPENSSL_malloc(buf_len);
+ pp = buffer;
+ if (!ECDSA_sign(0, dgst, dgstlen, pp, &buf_len, eckey);
+	{
+	/* error */
+	}
+
+Third step: verify the created ECDSA signature using B<ECDSA_do_verify>
+
+ ret = ECDSA_do_verify(digest, 20, sig, eckey);
+
+or using B<ECDSA_verify>
+
+ ret = ECDSA_verify(0, digest, 20, buffer, buf_len, eckey);
+
+and finally evaluate the return value:
+
+ if (ret == -1)
+	{
+	/* error */
+	}
+ else if (ret == 0)
+	{
+	/* incorrect signature */
+	}
+ else	/* ret == 1 */
+	{
+	/* signature ok */
+	}
+
+=head1 CONFORMING TO
+
+ANSI X9.62, US Federal Information Processing Standard FIPS 186-2
+(Digital Signature Standard, DSS)
+
+=head1 SEE ALSO
+
+L<dsa(3)|dsa(3)>, L<rsa(3)|rsa(3)>
+
+=head1 HISTORY
+
+The ecdsa implementation was first introduced in OpenSSL 0.9.8
+
+=head1 AUTHOR
+
+Nils Larsch for the OpenSSL project (http://www.openssl.org).
+
+=cut
diff --git a/openssl/doc/crypto/engine.pod b/openssl/doc/crypto/engine.pod
new file mode 100644
index 0000000..f5ab1c3
--- /dev/null
+++ b/openssl/doc/crypto/engine.pod
@@ -0,0 +1,599 @@
+=pod
+
+=head1 NAME
+
+engine - ENGINE cryptographic module support
+
+=head1 SYNOPSIS
+
+ #include <openssl/engine.h>
+
+ ENGINE *ENGINE_get_first(void);
+ ENGINE *ENGINE_get_last(void);
+ ENGINE *ENGINE_get_next(ENGINE *e);
+ ENGINE *ENGINE_get_prev(ENGINE *e);
+
+ int ENGINE_add(ENGINE *e);
+ int ENGINE_remove(ENGINE *e);
+
+ ENGINE *ENGINE_by_id(const char *id);
+
+ int ENGINE_init(ENGINE *e);
+ int ENGINE_finish(ENGINE *e);
+
+ void ENGINE_load_openssl(void);
+ void ENGINE_load_dynamic(void);
+ #ifndef OPENSSL_NO_STATIC_ENGINE
+ void ENGINE_load_4758cca(void);
+ void ENGINE_load_aep(void);
+ void ENGINE_load_atalla(void);
+ void ENGINE_load_chil(void);
+ void ENGINE_load_cswift(void);
+ void ENGINE_load_gmp(void);
+ void ENGINE_load_nuron(void);
+ void ENGINE_load_sureware(void);
+ void ENGINE_load_ubsec(void);
+ #endif
+ void ENGINE_load_cryptodev(void);
+ void ENGINE_load_builtin_engines(void);
+
+ void ENGINE_cleanup(void);
+
+ ENGINE *ENGINE_get_default_RSA(void);
+ ENGINE *ENGINE_get_default_DSA(void);
+ ENGINE *ENGINE_get_default_ECDH(void);
+ ENGINE *ENGINE_get_default_ECDSA(void);
+ ENGINE *ENGINE_get_default_DH(void);
+ ENGINE *ENGINE_get_default_RAND(void);
+ ENGINE *ENGINE_get_cipher_engine(int nid);
+ ENGINE *ENGINE_get_digest_engine(int nid);
+
+ int ENGINE_set_default_RSA(ENGINE *e);
+ int ENGINE_set_default_DSA(ENGINE *e);
+ int ENGINE_set_default_ECDH(ENGINE *e);
+ int ENGINE_set_default_ECDSA(ENGINE *e);
+ int ENGINE_set_default_DH(ENGINE *e);
+ int ENGINE_set_default_RAND(ENGINE *e);
+ int ENGINE_set_default_ciphers(ENGINE *e);
+ int ENGINE_set_default_digests(ENGINE *e);
+ int ENGINE_set_default_string(ENGINE *e, const char *list);
+
+ int ENGINE_set_default(ENGINE *e, unsigned int flags);
+
+ unsigned int ENGINE_get_table_flags(void);
+ void ENGINE_set_table_flags(unsigned int flags);
+
+ int ENGINE_register_RSA(ENGINE *e);
+ void ENGINE_unregister_RSA(ENGINE *e);
+ void ENGINE_register_all_RSA(void);
+ int ENGINE_register_DSA(ENGINE *e);
+ void ENGINE_unregister_DSA(ENGINE *e);
+ void ENGINE_register_all_DSA(void);
+ int ENGINE_register_ECDH(ENGINE *e);
+ void ENGINE_unregister_ECDH(ENGINE *e);
+ void ENGINE_register_all_ECDH(void);
+ int ENGINE_register_ECDSA(ENGINE *e);
+ void ENGINE_unregister_ECDSA(ENGINE *e);
+ void ENGINE_register_all_ECDSA(void);
+ int ENGINE_register_DH(ENGINE *e);
+ void ENGINE_unregister_DH(ENGINE *e);
+ void ENGINE_register_all_DH(void);
+ int ENGINE_register_RAND(ENGINE *e);
+ void ENGINE_unregister_RAND(ENGINE *e);
+ void ENGINE_register_all_RAND(void);
+ int ENGINE_register_STORE(ENGINE *e);
+ void ENGINE_unregister_STORE(ENGINE *e);
+ void ENGINE_register_all_STORE(void);
+ int ENGINE_register_ciphers(ENGINE *e);
+ void ENGINE_unregister_ciphers(ENGINE *e);
+ void ENGINE_register_all_ciphers(void);
+ int ENGINE_register_digests(ENGINE *e);
+ void ENGINE_unregister_digests(ENGINE *e);
+ void ENGINE_register_all_digests(void);
+ int ENGINE_register_complete(ENGINE *e);
+ int ENGINE_register_all_complete(void);
+
+ int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+ int ENGINE_cmd_is_executable(ENGINE *e, int cmd);
+ int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
+         long i, void *p, void (*f)(void), int cmd_optional);
+ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
+         int cmd_optional);
+
+ int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
+ void *ENGINE_get_ex_data(const ENGINE *e, int idx);
+
+ int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+         CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+
+ ENGINE *ENGINE_new(void);
+ int ENGINE_free(ENGINE *e);
+ int ENGINE_up_ref(ENGINE *e);
+
+ int ENGINE_set_id(ENGINE *e, const char *id);
+ int ENGINE_set_name(ENGINE *e, const char *name);
+ int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
+ int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
+ int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *dh_meth);
+ int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *dh_meth);
+ int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
+ int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
+ int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *rand_meth);
+ int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
+ int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
+ int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
+ int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
+ int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f);
+ int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
+ int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
+ int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
+ int ENGINE_set_flags(ENGINE *e, int flags);
+ int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
+
+ const char *ENGINE_get_id(const ENGINE *e);
+ const char *ENGINE_get_name(const ENGINE *e);
+ const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
+ const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
+ const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e);
+ const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e);
+ const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
+ const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
+ const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e);
+ ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
+ ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
+ ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
+ ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
+ ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
+ ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
+ ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
+ ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
+ const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
+ const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
+ int ENGINE_get_flags(const ENGINE *e);
+ const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
+
+ EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
+     UI_METHOD *ui_method, void *callback_data);
+ EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
+     UI_METHOD *ui_method, void *callback_data);
+
+ void ENGINE_add_conf_module(void);
+
+=head1 DESCRIPTION
+
+These functions create, manipulate, and use cryptographic modules in the
+form of B<ENGINE> objects. These objects act as containers for
+implementations of cryptographic algorithms, and support a
+reference-counted mechanism to allow them to be dynamically loaded in and
+out of the running application.
+
+The cryptographic functionality that can be provided by an B<ENGINE>
+implementation includes the following abstractions;
+
+ RSA_METHOD - for providing alternative RSA implementations
+ DSA_METHOD, DH_METHOD, RAND_METHOD, ECDH_METHOD, ECDSA_METHOD,
+       STORE_METHOD - similarly for other OpenSSL APIs
+ EVP_CIPHER - potentially multiple cipher algorithms (indexed by 'nid')
+ EVP_DIGEST - potentially multiple hash algorithms (indexed by 'nid')
+ key-loading - loading public and/or private EVP_PKEY keys
+
+=head2 Reference counting and handles
+
+Due to the modular nature of the ENGINE API, pointers to ENGINEs need to be
+treated as handles - ie. not only as pointers, but also as references to
+the underlying ENGINE object. Ie. one should obtain a new reference when
+making copies of an ENGINE pointer if the copies will be used (and
+released) independently.
+
+ENGINE objects have two levels of reference-counting to match the way in
+which the objects are used. At the most basic level, each ENGINE pointer is
+inherently a B<structural> reference - a structural reference is required
+to use the pointer value at all, as this kind of reference is a guarantee
+that the structure can not be deallocated until the reference is released.
+
+However, a structural reference provides no guarantee that the ENGINE is
+initiliased and able to use any of its cryptographic
+implementations. Indeed it's quite possible that most ENGINEs will not
+initialise at all in typical environments, as ENGINEs are typically used to
+support specialised hardware. To use an ENGINE's functionality, you need a
+B<functional> reference. This kind of reference can be considered a
+specialised form of structural reference, because each functional reference
+implicitly contains a structural reference as well - however to avoid
+difficult-to-find programming bugs, it is recommended to treat the two
+kinds of reference independently. If you have a functional reference to an
+ENGINE, you have a guarantee that the ENGINE has been initialised ready to
+perform cryptographic operations and will remain uninitialised
+until after you have released your reference.
+
+I<Structural references>
+
+This basic type of reference is used for instantiating new ENGINEs,
+iterating across OpenSSL's internal linked-list of loaded
+ENGINEs, reading information about an ENGINE, etc. Essentially a structural
+reference is sufficient if you only need to query or manipulate the data of
+an ENGINE implementation rather than use its functionality.
+
+The ENGINE_new() function returns a structural reference to a new (empty)
+ENGINE object. There are other ENGINE API functions that return structural
+references such as; ENGINE_by_id(), ENGINE_get_first(), ENGINE_get_last(),
+ENGINE_get_next(), ENGINE_get_prev(). All structural references should be
+released by a corresponding to call to the ENGINE_free() function - the
+ENGINE object itself will only actually be cleaned up and deallocated when
+the last structural reference is released.
+
+It should also be noted that many ENGINE API function calls that accept a
+structural reference will internally obtain another reference - typically
+this happens whenever the supplied ENGINE will be needed by OpenSSL after
+the function has returned. Eg. the function to add a new ENGINE to
+OpenSSL's internal list is ENGINE_add() - if this function returns success,
+then OpenSSL will have stored a new structural reference internally so the
+caller is still responsible for freeing their own reference with
+ENGINE_free() when they are finished with it. In a similar way, some
+functions will automatically release the structural reference passed to it
+if part of the function's job is to do so. Eg. the ENGINE_get_next() and
+ENGINE_get_prev() functions are used for iterating across the internal
+ENGINE list - they will return a new structural reference to the next (or
+previous) ENGINE in the list or NULL if at the end (or beginning) of the
+list, but in either case the structural reference passed to the function is
+released on behalf of the caller.
+
+To clarify a particular function's handling of references, one should
+always consult that function's documentation "man" page, or failing that
+the openssl/engine.h header file includes some hints.
+
+I<Functional references>
+
+As mentioned, functional references exist when the cryptographic
+functionality of an ENGINE is required to be available. A functional
+reference can be obtained in one of two ways; from an existing structural
+reference to the required ENGINE, or by asking OpenSSL for the default
+operational ENGINE for a given cryptographic purpose.
+
+To obtain a functional reference from an existing structural reference,
+call the ENGINE_init() function. This returns zero if the ENGINE was not
+already operational and couldn't be successfully initialised (eg. lack of
+system drivers, no special hardware attached, etc), otherwise it will
+return non-zero to indicate that the ENGINE is now operational and will
+have allocated a new B<functional> reference to the ENGINE. All functional
+references are released by calling ENGINE_finish() (which removes the
+implicit structural reference as well).
+
+The second way to get a functional reference is by asking OpenSSL for a
+default implementation for a given task, eg. by ENGINE_get_default_RSA(),
+ENGINE_get_default_cipher_engine(), etc. These are discussed in the next
+section, though they are not usually required by application programmers as
+they are used automatically when creating and using the relevant
+algorithm-specific types in OpenSSL, such as RSA, DSA, EVP_CIPHER_CTX, etc.
+
+=head2 Default implementations
+
+For each supported abstraction, the ENGINE code maintains an internal table
+of state to control which implementations are available for a given
+abstraction and which should be used by default. These implementations are
+registered in the tables and indexed by an 'nid' value, because
+abstractions like EVP_CIPHER and EVP_DIGEST support many distinct
+algorithms and modes, and ENGINEs can support arbitrarily many of them.
+In the case of other abstractions like RSA, DSA, etc, there is only one
+"algorithm" so all implementations implicitly register using the same 'nid'
+index.
+
+When a default ENGINE is requested for a given abstraction/algorithm/mode, (eg.
+when calling RSA_new_method(NULL)), a "get_default" call will be made to the
+ENGINE subsystem to process the corresponding state table and return a
+functional reference to an initialised ENGINE whose implementation should be
+used. If no ENGINE should (or can) be used, it will return NULL and the caller
+will operate with a NULL ENGINE handle - this usually equates to using the
+conventional software implementation. In the latter case, OpenSSL will from
+then on behave the way it used to before the ENGINE API existed.
+
+Each state table has a flag to note whether it has processed this
+"get_default" query since the table was last modified, because to process
+this question it must iterate across all the registered ENGINEs in the
+table trying to initialise each of them in turn, in case one of them is
+operational. If it returns a functional reference to an ENGINE, it will
+also cache another reference to speed up processing future queries (without
+needing to iterate across the table). Likewise, it will cache a NULL
+response if no ENGINE was available so that future queries won't repeat the
+same iteration unless the state table changes. This behaviour can also be
+changed; if the ENGINE_TABLE_FLAG_NOINIT flag is set (using
+ENGINE_set_table_flags()), no attempted initialisations will take place,
+instead the only way for the state table to return a non-NULL ENGINE to the
+"get_default" query will be if one is expressly set in the table. Eg.
+ENGINE_set_default_RSA() does the same job as ENGINE_register_RSA() except
+that it also sets the state table's cached response for the "get_default"
+query. In the case of abstractions like EVP_CIPHER, where implementations are
+indexed by 'nid', these flags and cached-responses are distinct for each 'nid'
+value.
+
+=head2 Application requirements
+
+This section will explain the basic things an application programmer should
+support to make the most useful elements of the ENGINE functionality
+available to the user. The first thing to consider is whether the
+programmer wishes to make alternative ENGINE modules available to the
+application and user. OpenSSL maintains an internal linked list of
+"visible" ENGINEs from which it has to operate - at start-up, this list is
+empty and in fact if an application does not call any ENGINE API calls and
+it uses static linking against openssl, then the resulting application
+binary will not contain any alternative ENGINE code at all. So the first
+consideration is whether any/all available ENGINE implementations should be
+made visible to OpenSSL - this is controlled by calling the various "load"
+functions, eg.
+
+ /* Make the "dynamic" ENGINE available */
+ void ENGINE_load_dynamic(void);
+ /* Make the CryptoSwift hardware acceleration support available */
+ void ENGINE_load_cswift(void);
+ /* Make support for nCipher's "CHIL" hardware available */
+ void ENGINE_load_chil(void);
+ ...
+ /* Make ALL ENGINE implementations bundled with OpenSSL available */
+ void ENGINE_load_builtin_engines(void);
+
+Having called any of these functions, ENGINE objects would have been
+dynamically allocated and populated with these implementations and linked
+into OpenSSL's internal linked list. At this point it is important to
+mention an important API function;
+
+ void ENGINE_cleanup(void);
+
+If no ENGINE API functions are called at all in an application, then there
+are no inherent memory leaks to worry about from the ENGINE functionality,
+however if any ENGINEs are loaded, even if they are never registered or
+used, it is necessary to use the ENGINE_cleanup() function to
+correspondingly cleanup before program exit, if the caller wishes to avoid
+memory leaks. This mechanism uses an internal callback registration table
+so that any ENGINE API functionality that knows it requires cleanup can
+register its cleanup details to be called during ENGINE_cleanup(). This
+approach allows ENGINE_cleanup() to clean up after any ENGINE functionality
+at all that your program uses, yet doesn't automatically create linker
+dependencies to all possible ENGINE functionality - only the cleanup
+callbacks required by the functionality you do use will be required by the
+linker.
+
+The fact that ENGINEs are made visible to OpenSSL (and thus are linked into
+the program and loaded into memory at run-time) does not mean they are
+"registered" or called into use by OpenSSL automatically - that behaviour
+is something for the application to control. Some applications
+will want to allow the user to specify exactly which ENGINE they want used
+if any is to be used at all. Others may prefer to load all support and have
+OpenSSL automatically use at run-time any ENGINE that is able to
+successfully initialise - ie. to assume that this corresponds to
+acceleration hardware attached to the machine or some such thing. There are
+probably numerous other ways in which applications may prefer to handle
+things, so we will simply illustrate the consequences as they apply to a
+couple of simple cases and leave developers to consider these and the
+source code to openssl's builtin utilities as guides.
+
+I<Using a specific ENGINE implementation>
+
+Here we'll assume an application has been configured by its user or admin
+to want to use the "ACME" ENGINE if it is available in the version of
+OpenSSL the application was compiled with. If it is available, it should be
+used by default for all RSA, DSA, and symmetric cipher operation, otherwise
+OpenSSL should use its builtin software as per usual. The following code
+illustrates how to approach this;
+
+ ENGINE *e;
+ const char *engine_id = "ACME";
+ ENGINE_load_builtin_engines();
+ e = ENGINE_by_id(engine_id);
+ if(!e)
+     /* the engine isn't available */
+     return;
+ if(!ENGINE_init(e)) {
+     /* the engine couldn't initialise, release 'e' */
+     ENGINE_free(e);
+     return;
+ }
+ if(!ENGINE_set_default_RSA(e))
+     /* This should only happen when 'e' can't initialise, but the previous
+      * statement suggests it did. */
+     abort();
+ ENGINE_set_default_DSA(e);
+ ENGINE_set_default_ciphers(e);
+ /* Release the functional reference from ENGINE_init() */
+ ENGINE_finish(e);
+ /* Release the structural reference from ENGINE_by_id() */
+ ENGINE_free(e);
+
+I<Automatically using builtin ENGINE implementations>
+
+Here we'll assume we want to load and register all ENGINE implementations
+bundled with OpenSSL, such that for any cryptographic algorithm required by
+OpenSSL - if there is an ENGINE that implements it and can be initialise,
+it should be used. The following code illustrates how this can work;
+
+ /* Load all bundled ENGINEs into memory and make them visible */
+ ENGINE_load_builtin_engines();
+ /* Register all of them for every algorithm they collectively implement */
+ ENGINE_register_all_complete();
+
+That's all that's required. Eg. the next time OpenSSL tries to set up an
+RSA key, any bundled ENGINEs that implement RSA_METHOD will be passed to
+ENGINE_init() and if any of those succeed, that ENGINE will be set as the
+default for RSA use from then on.
+
+=head2 Advanced configuration support
+
+There is a mechanism supported by the ENGINE framework that allows each
+ENGINE implementation to define an arbitrary set of configuration
+"commands" and expose them to OpenSSL and any applications based on
+OpenSSL. This mechanism is entirely based on the use of name-value pairs
+and assumes ASCII input (no unicode or UTF for now!), so it is ideal if
+applications want to provide a transparent way for users to provide
+arbitrary configuration "directives" directly to such ENGINEs. It is also
+possible for the application to dynamically interrogate the loaded ENGINE
+implementations for the names, descriptions, and input flags of their
+available "control commands", providing a more flexible configuration
+scheme. However, if the user is expected to know which ENGINE device he/she
+is using (in the case of specialised hardware, this goes without saying)
+then applications may not need to concern themselves with discovering the
+supported control commands and simply prefer to pass settings into ENGINEs
+exactly as they are provided by the user.
+
+Before illustrating how control commands work, it is worth mentioning what
+they are typically used for. Broadly speaking there are two uses for
+control commands; the first is to provide the necessary details to the
+implementation (which may know nothing at all specific to the host system)
+so that it can be initialised for use. This could include the path to any
+driver or config files it needs to load, required network addresses,
+smart-card identifiers, passwords to initialise protected devices,
+logging information, etc etc. This class of commands typically needs to be
+passed to an ENGINE B<before> attempting to initialise it, ie. before
+calling ENGINE_init(). The other class of commands consist of settings or
+operations that tweak certain behaviour or cause certain operations to take
+place, and these commands may work either before or after ENGINE_init(), or
+in some cases both. ENGINE implementations should provide indications of
+this in the descriptions attached to builtin control commands and/or in
+external product documentation.
+
+I<Issuing control commands to an ENGINE>
+
+Let's illustrate by example; a function for which the caller supplies the
+name of the ENGINE it wishes to use, a table of string-pairs for use before
+initialisation, and another table for use after initialisation. Note that
+the string-pairs used for control commands consist of a command "name"
+followed by the command "parameter" - the parameter could be NULL in some
+cases but the name can not. This function should initialise the ENGINE
+(issuing the "pre" commands beforehand and the "post" commands afterwards)
+and set it as the default for everything except RAND and then return a
+boolean success or failure.
+
+ int generic_load_engine_fn(const char *engine_id,
+                            const char **pre_cmds, int pre_num,
+                            const char **post_cmds, int post_num)
+ {
+     ENGINE *e = ENGINE_by_id(engine_id);
+     if(!e) return 0;
+     while(pre_num--) {
+         if(!ENGINE_ctrl_cmd_string(e, pre_cmds[0], pre_cmds[1], 0)) {
+             fprintf(stderr, "Failed command (%s - %s:%s)\n", engine_id,
+                 pre_cmds[0], pre_cmds[1] ? pre_cmds[1] : "(NULL)");
+             ENGINE_free(e);
+             return 0;
+         }
+	 pre_cmds += 2;
+     }
+     if(!ENGINE_init(e)) {
+         fprintf(stderr, "Failed initialisation\n");
+         ENGINE_free(e);
+         return 0;
+     }
+     /* ENGINE_init() returned a functional reference, so free the structural
+      * reference from ENGINE_by_id(). */
+     ENGINE_free(e);
+     while(post_num--) {
+         if(!ENGINE_ctrl_cmd_string(e, post_cmds[0], post_cmds[1], 0)) {
+             fprintf(stderr, "Failed command (%s - %s:%s)\n", engine_id,
+                 post_cmds[0], post_cmds[1] ? post_cmds[1] : "(NULL)");
+             ENGINE_finish(e);
+             return 0;
+         }
+	 post_cmds += 2;
+     }
+     ENGINE_set_default(e, ENGINE_METHOD_ALL & ~ENGINE_METHOD_RAND);
+     /* Success */
+     return 1;
+ }
+
+Note that ENGINE_ctrl_cmd_string() accepts a boolean argument that can
+relax the semantics of the function - if set non-zero it will only return
+failure if the ENGINE supported the given command name but failed while
+executing it, if the ENGINE doesn't support the command name it will simply
+return success without doing anything. In this case we assume the user is
+only supplying commands specific to the given ENGINE so we set this to
+FALSE.
+
+I<Discovering supported control commands>
+
+It is possible to discover at run-time the names, numerical-ids, descriptions
+and input parameters of the control commands supported by an ENGINE using a
+structural reference. Note that some control commands are defined by OpenSSL
+itself and it will intercept and handle these control commands on behalf of the
+ENGINE, ie. the ENGINE's ctrl() handler is not used for the control command.
+openssl/engine.h defines an index, ENGINE_CMD_BASE, that all control commands
+implemented by ENGINEs should be numbered from. Any command value lower than
+this symbol is considered a "generic" command is handled directly by the
+OpenSSL core routines.
+
+It is using these "core" control commands that one can discover the the control
+commands implemented by a given ENGINE, specifically the commands;
+
+ #define ENGINE_HAS_CTRL_FUNCTION		10
+ #define ENGINE_CTRL_GET_FIRST_CMD_TYPE		11
+ #define ENGINE_CTRL_GET_NEXT_CMD_TYPE		12
+ #define ENGINE_CTRL_GET_CMD_FROM_NAME		13
+ #define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD	14
+ #define ENGINE_CTRL_GET_NAME_FROM_CMD		15
+ #define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD	16
+ #define ENGINE_CTRL_GET_DESC_FROM_CMD		17
+ #define ENGINE_CTRL_GET_CMD_FLAGS		18
+
+Whilst these commands are automatically processed by the OpenSSL framework code,
+they use various properties exposed by each ENGINE to process these
+queries. An ENGINE has 3 properties it exposes that can affect how this behaves;
+it can supply a ctrl() handler, it can specify ENGINE_FLAGS_MANUAL_CMD_CTRL in
+the ENGINE's flags, and it can expose an array of control command descriptions.
+If an ENGINE specifies the ENGINE_FLAGS_MANUAL_CMD_CTRL flag, then it will
+simply pass all these "core" control commands directly to the ENGINE's ctrl()
+handler (and thus, it must have supplied one), so it is up to the ENGINE to
+reply to these "discovery" commands itself. If that flag is not set, then the
+OpenSSL framework code will work with the following rules;
+
+ if no ctrl() handler supplied;
+     ENGINE_HAS_CTRL_FUNCTION returns FALSE (zero),
+     all other commands fail.
+ if a ctrl() handler was supplied but no array of control commands;
+     ENGINE_HAS_CTRL_FUNCTION returns TRUE,
+     all other commands fail.
+ if a ctrl() handler and array of control commands was supplied;
+     ENGINE_HAS_CTRL_FUNCTION returns TRUE,
+     all other commands proceed processing ...
+
+If the ENGINE's array of control commands is empty then all other commands will
+fail, otherwise; ENGINE_CTRL_GET_FIRST_CMD_TYPE returns the identifier of
+the first command supported by the ENGINE, ENGINE_GET_NEXT_CMD_TYPE takes the
+identifier of a command supported by the ENGINE and returns the next command
+identifier or fails if there are no more, ENGINE_CMD_FROM_NAME takes a string
+name for a command and returns the corresponding identifier or fails if no such
+command name exists, and the remaining commands take a command identifier and
+return properties of the corresponding commands. All except
+ENGINE_CTRL_GET_FLAGS return the string length of a command name or description,
+or populate a supplied character buffer with a copy of the command name or
+description. ENGINE_CTRL_GET_FLAGS returns a bitwise-OR'd mask of the following
+possible values;
+
+ #define ENGINE_CMD_FLAG_NUMERIC		(unsigned int)0x0001
+ #define ENGINE_CMD_FLAG_STRING			(unsigned int)0x0002
+ #define ENGINE_CMD_FLAG_NO_INPUT		(unsigned int)0x0004
+ #define ENGINE_CMD_FLAG_INTERNAL		(unsigned int)0x0008
+
+If the ENGINE_CMD_FLAG_INTERNAL flag is set, then any other flags are purely
+informational to the caller - this flag will prevent the command being usable
+for any higher-level ENGINE functions such as ENGINE_ctrl_cmd_string().
+"INTERNAL" commands are not intended to be exposed to text-based configuration
+by applications, administrations, users, etc. These can support arbitrary
+operations via ENGINE_ctrl(), including passing to and/or from the control
+commands data of any arbitrary type. These commands are supported in the
+discovery mechanisms simply to allow applications determinie if an ENGINE
+supports certain specific commands it might want to use (eg. application "foo"
+might query various ENGINEs to see if they implement "FOO_GET_VENDOR_LOGO_GIF" -
+and ENGINE could therefore decide whether or not to support this "foo"-specific
+extension).
+
+=head2 Future developments
+
+The ENGINE API and internal architecture is currently being reviewed. Slated for
+possible release in 0.9.8 is support for transparent loading of "dynamic"
+ENGINEs (built as self-contained shared-libraries). This would allow ENGINE
+implementations to be provided independently of OpenSSL libraries and/or
+OpenSSL-based applications, and would also remove any requirement for
+applications to explicitly use the "dynamic" ENGINE to bind to shared-library
+implementations.
+
+=head1 SEE ALSO
+
+L<rsa(3)|rsa(3)>, L<dsa(3)|dsa(3)>, L<dh(3)|dh(3)>, L<rand(3)|rand(3)>
+
+=cut
diff --git a/openssl/doc/crypto/err.pod b/openssl/doc/crypto/err.pod
new file mode 100644
index 0000000..6f72955
--- /dev/null
+++ b/openssl/doc/crypto/err.pod
@@ -0,0 +1,187 @@
+=pod
+
+=head1 NAME
+
+err - error codes
+
+=head1 SYNOPSIS
+
+ #include <openssl/err.h>
+
+ unsigned long ERR_get_error(void);
+ unsigned long ERR_peek_error(void);
+ unsigned long ERR_get_error_line(const char **file, int *line);
+ unsigned long ERR_peek_error_line(const char **file, int *line);
+ unsigned long ERR_get_error_line_data(const char **file, int *line,
+         const char **data, int *flags);
+ unsigned long ERR_peek_error_line_data(const char **file, int *line,
+         const char **data, int *flags);
+
+ int ERR_GET_LIB(unsigned long e);
+ int ERR_GET_FUNC(unsigned long e);
+ int ERR_GET_REASON(unsigned long e);
+
+ void ERR_clear_error(void);
+
+ char *ERR_error_string(unsigned long e, char *buf);
+ const char *ERR_lib_error_string(unsigned long e);
+ const char *ERR_func_error_string(unsigned long e);
+ const char *ERR_reason_error_string(unsigned long e);
+
+ void ERR_print_errors(BIO *bp);
+ void ERR_print_errors_fp(FILE *fp);
+
+ void ERR_load_crypto_strings(void);
+ void ERR_free_strings(void);
+
+ void ERR_remove_state(unsigned long pid);
+
+ void ERR_put_error(int lib, int func, int reason, const char *file,
+         int line);
+ void ERR_add_error_data(int num, ...);
+
+ void ERR_load_strings(int lib,ERR_STRING_DATA str[]);
+ unsigned long ERR_PACK(int lib, int func, int reason);
+ int ERR_get_next_error_library(void);
+
+=head1 DESCRIPTION
+
+When a call to the OpenSSL library fails, this is usually signalled
+by the return value, and an error code is stored in an error queue
+associated with the current thread. The B<err> library provides
+functions to obtain these error codes and textual error messages.
+
+The L<ERR_get_error(3)|ERR_get_error(3)> manpage describes how to
+access error codes.
+
+Error codes contain information about where the error occurred, and
+what went wrong. L<ERR_GET_LIB(3)|ERR_GET_LIB(3)> describes how to
+extract this information. A method to obtain human-readable error
+messages is described in L<ERR_error_string(3)|ERR_error_string(3)>.
+
+L<ERR_clear_error(3)|ERR_clear_error(3)> can be used to clear the
+error queue.
+
+Note that L<ERR_remove_state(3)|ERR_remove_state(3)> should be used to
+avoid memory leaks when threads are terminated.
+
+=head1 ADDING NEW ERROR CODES TO OPENSSL
+
+See L<ERR_put_error(3)> if you want to record error codes in the
+OpenSSL error system from within your application.
+
+The remainder of this section is of interest only if you want to add
+new error codes to OpenSSL or add error codes from external libraries.
+
+=head2 Reporting errors
+
+Each sub-library has a specific macro XXXerr() that is used to report
+errors. Its first argument is a function code B<XXX_F_...>, the second
+argument is a reason code B<XXX_R_...>. Function codes are derived
+from the function names; reason codes consist of textual error
+descriptions. For example, the function ssl23_read() reports a
+"handshake failure" as follows:
+
+ SSLerr(SSL_F_SSL23_READ, SSL_R_SSL_HANDSHAKE_FAILURE);
+
+Function and reason codes should consist of upper case characters,
+numbers and underscores only. The error file generation script translates
+function codes into function names by looking in the header files
+for an appropriate function name, if none is found it just uses
+the capitalized form such as "SSL23_READ" in the above example.
+
+The trailing section of a reason code (after the "_R_") is translated
+into lower case and underscores changed to spaces.
+
+When you are using new function or reason codes, run B<make errors>.
+The necessary B<#define>s will then automatically be added to the
+sub-library's header file.
+
+Although a library will normally report errors using its own specific
+XXXerr macro, another library's macro can be used. This is normally
+only done when a library wants to include ASN1 code which must use
+the ASN1err() macro.
+
+=head2 Adding new libraries
+
+When adding a new sub-library to OpenSSL, assign it a library number
+B<ERR_LIB_XXX>, define a macro XXXerr() (both in B<err.h>), add its
+name to B<ERR_str_libraries[]> (in B<crypto/err/err.c>), and add
+C<ERR_load_XXX_strings()> to the ERR_load_crypto_strings() function
+(in B<crypto/err/err_all.c>). Finally, add an entry
+
+ L	XXX	xxx.h	xxx_err.c
+
+to B<crypto/err/openssl.ec>, and add B<xxx_err.c> to the Makefile.
+Running B<make errors> will then generate a file B<xxx_err.c>, and
+add all error codes used in the library to B<xxx.h>.
+
+Additionally the library include file must have a certain form.
+Typically it will initially look like this:
+
+ #ifndef HEADER_XXX_H
+ #define HEADER_XXX_H
+
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
+ /* Include files */
+
+ #include <openssl/bio.h>
+ #include <openssl/x509.h>
+
+ /* Macros, structures and function prototypes */
+
+
+ /* BEGIN ERROR CODES */
+
+The B<BEGIN ERROR CODES> sequence is used by the error code
+generation script as the point to place new error codes, any text
+after this point will be overwritten when B<make errors> is run.
+The closing #endif etc will be automatically added by the script.
+
+The generated C error code file B<xxx_err.c> will load the header
+files B<stdio.h>, B<openssl/err.h> and B<openssl/xxx.h> so the
+header file must load any additional header files containing any
+definitions it uses.
+
+=head1 USING ERROR CODES IN EXTERNAL LIBRARIES
+
+It is also possible to use OpenSSL's error code scheme in external
+libraries. The library needs to load its own codes and call the OpenSSL
+error code insertion script B<mkerr.pl> explicitly to add codes to
+the header file and generate the C error code file. This will normally
+be done if the external library needs to generate new ASN1 structures
+but it can also be used to add more general purpose error code handling.
+
+TBA more details
+
+=head1 INTERNALS
+
+The error queues are stored in a hash table with one B<ERR_STATE>
+entry for each pid. ERR_get_state() returns the current thread's
+B<ERR_STATE>. An B<ERR_STATE> can hold up to B<ERR_NUM_ERRORS> error
+codes. When more error codes are added, the old ones are overwritten,
+on the assumption that the most recent errors are most important.
+
+Error strings are also stored in hash table. The hash tables can
+be obtained by calling ERR_get_err_state_table(void) and
+ERR_get_string_table(void) respectively.
+
+=head1 SEE ALSO
+
+L<CRYPTO_set_id_callback(3)|CRYPTO_set_id_callback(3)>,
+L<CRYPTO_set_locking_callback(3)|CRYPTO_set_locking_callback(3)>,
+L<ERR_get_error(3)|ERR_get_error(3)>,
+L<ERR_GET_LIB(3)|ERR_GET_LIB(3)>,
+L<ERR_clear_error(3)|ERR_clear_error(3)>,
+L<ERR_error_string(3)|ERR_error_string(3)>,
+L<ERR_print_errors(3)|ERR_print_errors(3)>,
+L<ERR_load_crypto_strings(3)|ERR_load_crypto_strings(3)>,
+L<ERR_remove_state(3)|ERR_remove_state(3)>,
+L<ERR_put_error(3)|ERR_put_error(3)>,
+L<ERR_load_strings(3)|ERR_load_strings(3)>,
+L<SSL_get_error(3)|SSL_get_error(3)>
+
+=cut
diff --git a/openssl/doc/crypto/evp.pod b/openssl/doc/crypto/evp.pod
new file mode 100644
index 0000000..9faa349
--- /dev/null
+++ b/openssl/doc/crypto/evp.pod
@@ -0,0 +1,55 @@
+=pod
+
+=head1 NAME
+
+evp - high-level cryptographic functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+=head1 DESCRIPTION
+
+The EVP library provides a high-level interface to cryptographic
+functions.
+
+B<EVP_Seal>I<...> and B<EVP_Open>I<...> provide public key encryption
+and decryption to implement digital "envelopes".
+
+The B<EVP_Sign>I<...> and B<EVP_Verify>I<...> functions implement
+digital signatures.
+
+Symmetric encryption is available with the B<EVP_Encrypt>I<...>
+functions.  The B<EVP_Digest>I<...> functions provide message digests.
+
+The B<EVP_PKEY>I<...> functions provide a high level interface to
+asymmetric algorithms.
+
+Algorithms are loaded with OpenSSL_add_all_algorithms(3).
+
+All the symmetric algorithms (ciphers), digests and asymmetric algorithms
+(public key algorithms) can be replaced by ENGINE modules providing alternative
+implementations. If ENGINE implementations of ciphers or digests are registered
+as defaults, then the various EVP functions will automatically use those
+implementations automatically in preference to built in software
+implementations. For more information, consult the engine(3) man page.
+
+Although low level algorithm specific functions exist for many algorithms
+their use is discouraged. They cannot be used with an ENGINE and ENGINE
+versions of new algorithms cannot be accessed using the low level functions.
+Also makes code harder to adapt to new algorithms and some options are not 
+cleanly supported at the low level and some operations are more efficient
+using the high level interface.
+
+=head1 SEE ALSO
+
+L<EVP_DigestInit(3)|EVP_DigestInit(3)>,
+L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>,
+L<EVP_OpenInit(3)|EVP_OpenInit(3)>,
+L<EVP_SealInit(3)|EVP_SealInit(3)>,
+L<EVP_SignInit(3)|EVP_SignInit(3)>,
+L<EVP_VerifyInit(3)|EVP_VerifyInit(3)>,
+L<OpenSSL_add_all_algorithms(3)|OpenSSL_add_all_algorithms(3)>,
+L<engine(3)|engine(3)>
+
+=cut
diff --git a/openssl/doc/crypto/hmac.pod b/openssl/doc/crypto/hmac.pod
new file mode 100644
index 0000000..d92138d
--- /dev/null
+++ b/openssl/doc/crypto/hmac.pod
@@ -0,0 +1,106 @@
+=pod
+
+=head1 NAME
+
+HMAC, HMAC_Init, HMAC_Update, HMAC_Final, HMAC_cleanup - HMAC message
+authentication code
+
+=head1 SYNOPSIS
+
+ #include <openssl/hmac.h>
+
+ unsigned char *HMAC(const EVP_MD *evp_md, const void *key,
+               int key_len, const unsigned char *d, int n,
+               unsigned char *md, unsigned int *md_len);
+
+ void HMAC_CTX_init(HMAC_CTX *ctx);
+
+ int HMAC_Init(HMAC_CTX *ctx, const void *key, int key_len,
+               const EVP_MD *md);
+ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len,
+               	   const EVP_MD *md, ENGINE *impl);
+ int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len);
+ int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
+
+ void HMAC_CTX_cleanup(HMAC_CTX *ctx);
+ void HMAC_cleanup(HMAC_CTX *ctx);
+
+=head1 DESCRIPTION
+
+HMAC is a MAC (message authentication code), i.e. a keyed hash
+function used for message authentication, which is based on a hash
+function.
+
+HMAC() computes the message authentication code of the B<n> bytes at
+B<d> using the hash function B<evp_md> and the key B<key> which is
+B<key_len> bytes long.
+
+It places the result in B<md> (which must have space for the output of
+the hash function, which is no more than B<EVP_MAX_MD_SIZE> bytes).
+If B<md> is NULL, the digest is placed in a static array.  The size of
+the output is placed in B<md_len>, unless it is B<NULL>.
+
+B<evp_md> can be EVP_sha1(), EVP_ripemd160() etc.
+
+HMAC_CTX_init() initialises a B<HMAC_CTX> before first use. It must be
+called.
+
+HMAC_CTX_cleanup() erases the key and other data from the B<HMAC_CTX>
+and releases any associated resources. It must be called when an
+B<HMAC_CTX> is no longer required.
+
+HMAC_cleanup() is an alias for HMAC_CTX_cleanup() included for back
+compatibility with 0.9.6b, it is deprecated.
+
+The following functions may be used if the message is not completely
+stored in memory:
+
+HMAC_Init() initializes a B<HMAC_CTX> structure to use the hash
+function B<evp_md> and the key B<key> which is B<key_len> bytes
+long. It is deprecated and only included for backward compatibility
+with OpenSSL 0.9.6b.
+
+HMAC_Init_ex() initializes or reuses a B<HMAC_CTX> structure to use
+the function B<evp_md> and key B<key>. Either can be NULL, in which
+case the existing one will be reused. HMAC_CTX_init() must have been
+called before the first use of an B<HMAC_CTX> in this
+function. B<N.B. HMAC_Init() had this undocumented behaviour in
+previous versions of OpenSSL - failure to switch to HMAC_Init_ex() in
+programs that expect it will cause them to stop working>.
+
+HMAC_Update() can be called repeatedly with chunks of the message to
+be authenticated (B<len> bytes at B<data>).
+
+HMAC_Final() places the message authentication code in B<md>, which
+must have space for the hash function output.
+
+=head1 RETURN VALUES
+
+HMAC() returns a pointer to the message authentication code or NULL if
+an error occurred.
+
+HMAC_Init_ex(), HMAC_Update() and HMAC_Final() return 1 for success or 0 if
+an error occurred.
+
+HMAC_CTX_init() and HMAC_CTX_cleanup() do not return values.
+
+=head1 CONFORMING TO
+
+RFC 2104
+
+=head1 SEE ALSO
+
+L<sha(3)|sha(3)>, L<evp(3)|evp(3)>
+
+=head1 HISTORY
+
+HMAC(), HMAC_Init(), HMAC_Update(), HMAC_Final() and HMAC_cleanup()
+are available since SSLeay 0.9.0.
+
+HMAC_CTX_init(), HMAC_Init_ex() and HMAC_CTX_cleanup() are available
+since OpenSSL 0.9.7.
+
+HMAC_Init_ex(), HMAC_Update() and HMAC_Final() did not return values in
+versions of OpenSSL before 1.0.0.
+
+=cut
diff --git a/openssl/doc/crypto/i2d_CMS_bio_stream.pod b/openssl/doc/crypto/i2d_CMS_bio_stream.pod
new file mode 100644
index 0000000..558bdd0
--- /dev/null
+++ b/openssl/doc/crypto/i2d_CMS_bio_stream.pod
@@ -0,0 +1,44 @@
+=pod
+
+=head1 NAME
+
+ i2d_CMS_bio_stream - output CMS_ContentInfo structure in BER format.
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *data, int flags);
+
+=head1 DESCRIPTION
+
+i2d_CMS_bio_stream() outputs a CMS_ContentInfo structure in BER format.
+
+It is otherwise identical to the function SMIME_write_CMS().
+
+=head1 NOTES
+
+This function is effectively a version of the i2d_CMS_bio() supporting
+streaming.
+
+=head1 BUGS
+
+The prefix "i2d" is arguably wrong because the function outputs BER format.
+
+=head1 RETURN VALUES
+
+i2d_CMS_bio_stream() returns 1 for success or 0 for failure.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
+L<CMS_verify(3)|CMS_verify(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)>
+L<CMS_decrypt(3)|CMS_decrypt(3)>,
+L<SMIME_write_CMS(3)|SMIME_write_CMS(3)>,
+L<PEM_write_bio_CMS_stream(3)|PEM_write_bio_CMS_stream(3)>
+
+=head1 HISTORY
+
+i2d_CMS_bio_stream() was added to OpenSSL 1.0.0
+
+=cut
diff --git a/openssl/doc/crypto/i2d_PKCS7_bio_stream.pod b/openssl/doc/crypto/i2d_PKCS7_bio_stream.pod
new file mode 100644
index 0000000..dc4d884
--- /dev/null
+++ b/openssl/doc/crypto/i2d_PKCS7_bio_stream.pod
@@ -0,0 +1,44 @@
+=pod
+
+=head1 NAME
+
+i2d_PKCS7_bio_stream - output PKCS7 structure in BER format.
+
+=head1 SYNOPSIS
+
+ #include <openssl/pkcs7.h>
+
+ int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *data, int flags);
+
+=head1 DESCRIPTION
+
+i2d_PKCS7_bio_stream() outputs a PKCS7 structure in BER format.
+
+It is otherwise identical to the function SMIME_write_PKCS7().
+
+=head1 NOTES
+
+This function is effectively a version of the d2i_PKCS7_bio() supporting
+streaming.
+
+=head1 BUGS
+
+The prefix "d2i" is arguably wrong because the function outputs BER format.
+
+=head1 RETURN VALUES
+
+i2d_PKCS7_bio_stream() returns 1 for success or 0 for failure.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>,
+L<PKCS7_verify(3)|PKCS7_verify(3)>, L<PKCS7_encrypt(3)|PKCS7_encrypt(3)>
+L<PKCS7_decrypt(3)|PKCS7_decrypt(3)>,
+L<SMIME_write_PKCS7(3)|SMIME_write_PKCS7(3)>,
+L<PEM_write_bio_PKCS7_stream(3)|PEM_write_bio_PKCS7_stream(3)>
+
+=head1 HISTORY
+
+i2d_PKCS7_bio_stream() was added to OpenSSL 1.0.0
+
+=cut
diff --git a/openssl/doc/crypto/lh_stats.pod b/openssl/doc/crypto/lh_stats.pod
new file mode 100644
index 0000000..3eeaa72
--- /dev/null
+++ b/openssl/doc/crypto/lh_stats.pod
@@ -0,0 +1,60 @@
+=pod
+
+=head1 NAME
+
+lh_stats, lh_node_stats, lh_node_usage_stats, lh_stats_bio,
+lh_node_stats_bio, lh_node_usage_stats_bio - LHASH statistics
+
+=head1 SYNOPSIS
+
+ #include <openssl/lhash.h>
+
+ void lh_stats(LHASH *table, FILE *out);
+ void lh_node_stats(LHASH *table, FILE *out);
+ void lh_node_usage_stats(LHASH *table, FILE *out);
+
+ void lh_stats_bio(LHASH *table, BIO *out);
+ void lh_node_stats_bio(LHASH *table, BIO *out);
+ void lh_node_usage_stats_bio(LHASH *table, BIO *out);
+
+=head1 DESCRIPTION
+
+The B<LHASH> structure records statistics about most aspects of
+accessing the hash table.  This is mostly a legacy of Eric Young
+writing this library for the reasons of implementing what looked like
+a nice algorithm rather than for a particular software product.
+
+lh_stats() prints out statistics on the size of the hash table, how
+many entries are in it, and the number and result of calls to the
+routines in this library.
+
+lh_node_stats() prints the number of entries for each 'bucket' in the
+hash table.
+
+lh_node_usage_stats() prints out a short summary of the state of the
+hash table.  It prints the 'load' and the 'actual load'.  The load is
+the average number of data items per 'bucket' in the hash table.  The
+'actual load' is the average number of items per 'bucket', but only
+for buckets which contain entries.  So the 'actual load' is the
+average number of searches that will need to find an item in the hash
+table, while the 'load' is the average number that will be done to
+record a miss.
+
+lh_stats_bio(), lh_node_stats_bio() and lh_node_usage_stats_bio()
+are the same as the above, except that the output goes to a B<BIO>.
+
+=head1 RETURN VALUES
+
+These functions do not return values.
+
+=head1 SEE ALSO
+
+L<bio(3)|bio(3)>, L<lhash(3)|lhash(3)>
+
+=head1 HISTORY
+
+These functions are available in all versions of SSLeay and OpenSSL.
+
+This manpage is derived from the SSLeay documentation.
+
+=cut
diff --git a/openssl/doc/crypto/lhash.pod b/openssl/doc/crypto/lhash.pod
new file mode 100644
index 0000000..73a19b6
--- /dev/null
+++ b/openssl/doc/crypto/lhash.pod
@@ -0,0 +1,302 @@
+=pod
+
+=head1 NAME
+
+lh_new, lh_free, lh_insert, lh_delete, lh_retrieve, lh_doall, lh_doall_arg, lh_error - dynamic hash table
+
+=head1 SYNOPSIS
+
+ #include <openssl/lhash.h>
+
+ DECLARE_LHASH_OF(<type>);
+
+ LHASH *lh_<type>_new();
+ void lh_<type>_free(LHASH_OF(<type> *table);
+
+ <type> *lh_<type>_insert(LHASH_OF(<type> *table, <type> *data);
+ <type> *lh_<type>_delete(LHASH_OF(<type> *table, <type> *data);
+ <type> *lh_retrieve(LHASH_OF<type> *table, <type> *data);
+
+ void lh_<type>_doall(LHASH_OF(<type> *table, LHASH_DOALL_FN_TYPE func);
+ void lh_<type>_doall_arg(LHASH_OF(<type> *table, LHASH_DOALL_ARG_FN_TYPE func,
+          <type2>, <type2> *arg);
+
+ int lh_<type>_error(LHASH_OF(<type> *table);
+
+ typedef int (*LHASH_COMP_FN_TYPE)(const void *, const void *);
+ typedef unsigned long (*LHASH_HASH_FN_TYPE)(const void *);
+ typedef void (*LHASH_DOALL_FN_TYPE)(const void *);
+ typedef void (*LHASH_DOALL_ARG_FN_TYPE)(const void *, const void *);
+
+=head1 DESCRIPTION
+
+This library implements type-checked dynamic hash tables. The hash
+table entries can be arbitrary structures. Usually they consist of key
+and value fields.
+
+lh_<type>_new() creates a new B<LHASH_OF(<type>> structure to store
+arbitrary data entries, and provides the 'hash' and 'compare'
+callbacks to be used in organising the table's entries.  The B<hash>
+callback takes a pointer to a table entry as its argument and returns
+an unsigned long hash value for its key field.  The hash value is
+normally truncated to a power of 2, so make sure that your hash
+function returns well mixed low order bits.  The B<compare> callback
+takes two arguments (pointers to two hash table entries), and returns
+0 if their keys are equal, non-zero otherwise.  If your hash table
+will contain items of some particular type and the B<hash> and
+B<compare> callbacks hash/compare these types, then the
+B<DECLARE_LHASH_HASH_FN> and B<IMPLEMENT_LHASH_COMP_FN> macros can be
+used to create callback wrappers of the prototypes required by
+lh_<type>_new().  These provide per-variable casts before calling the
+type-specific callbacks written by the application author.  These
+macros, as well as those used for the "doall" callbacks, are defined
+as;
+
+ #define DECLARE_LHASH_HASH_FN(name, o_type) \
+	 unsigned long name##_LHASH_HASH(const void *);
+ #define IMPLEMENT_LHASH_HASH_FN(name, o_type) \
+	 unsigned long name##_LHASH_HASH(const void *arg) { \
+		 const o_type *a = arg; \
+		 return name##_hash(a); }
+ #define LHASH_HASH_FN(name) name##_LHASH_HASH
+
+ #define DECLARE_LHASH_COMP_FN(name, o_type) \
+	 int name##_LHASH_COMP(const void *, const void *);
+ #define IMPLEMENT_LHASH_COMP_FN(name, o_type) \
+	 int name##_LHASH_COMP(const void *arg1, const void *arg2) { \
+		 const o_type *a = arg1;		    \
+		 const o_type *b = arg2; \
+		 return name##_cmp(a,b); }
+ #define LHASH_COMP_FN(name) name##_LHASH_COMP
+
+ #define DECLARE_LHASH_DOALL_FN(name, o_type) \
+	 void name##_LHASH_DOALL(void *);
+ #define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \
+	 void name##_LHASH_DOALL(void *arg) { \
+		 o_type *a = arg; \
+		 name##_doall(a); }
+ #define LHASH_DOALL_FN(name) name##_LHASH_DOALL
+
+ #define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
+	 void name##_LHASH_DOALL_ARG(void *, void *);
+ #define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
+	 void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
+		 o_type *a = arg1; \
+		 a_type *b = arg2; \
+		 name##_doall_arg(a, b); }
+ #define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG
+
+ An example of a hash table storing (pointers to) structures of type 'STUFF'
+ could be defined as follows;
+
+ /* Calculates the hash value of 'tohash' (implemented elsewhere) */
+ unsigned long STUFF_hash(const STUFF *tohash);
+ /* Orders 'arg1' and 'arg2' (implemented elsewhere) */
+ int stuff_cmp(const STUFF *arg1, const STUFF *arg2);
+ /* Create the type-safe wrapper functions for use in the LHASH internals */
+ static IMPLEMENT_LHASH_HASH_FN(stuff, STUFF);
+ static IMPLEMENT_LHASH_COMP_FN(stuff, STUFF);
+ /* ... */
+ int main(int argc, char *argv[]) {
+         /* Create the new hash table using the hash/compare wrappers */
+         LHASH_OF(STUFF) *hashtable = lh_STUFF_new(LHASH_HASH_FN(STUFF_hash),
+                                   LHASH_COMP_FN(STUFF_cmp));
+	 /* ... */
+ }
+
+lh_<type>_free() frees the B<LHASH_OF(<type>> structure
+B<table>. Allocated hash table entries will not be freed; consider
+using lh_<type>_doall() to deallocate any remaining entries in the
+hash table (see below).
+
+lh_<type>_insert() inserts the structure pointed to by B<data> into
+B<table>.  If there already is an entry with the same key, the old
+value is replaced. Note that lh_<type>_insert() stores pointers, the
+data are not copied.
+
+lh_<type>_delete() deletes an entry from B<table>.
+
+lh_<type>_retrieve() looks up an entry in B<table>. Normally, B<data>
+is a structure with the key field(s) set; the function will return a
+pointer to a fully populated structure.
+
+lh_<type>_doall() will, for every entry in the hash table, call
+B<func> with the data item as its parameter.  For lh_<type>_doall()
+and lh_<type>_doall_arg(), function pointer casting should be avoided
+in the callbacks (see B<NOTE>) - instead use the declare/implement
+macros to create type-checked wrappers that cast variables prior to
+calling your type-specific callbacks.  An example of this is
+illustrated here where the callback is used to cleanup resources for
+items in the hash table prior to the hashtable itself being
+deallocated:
+
+ /* Cleans up resources belonging to 'a' (this is implemented elsewhere) */
+ void STUFF_cleanup_doall(STUFF *a);
+ /* Implement a prototype-compatible wrapper for "STUFF_cleanup" */
+ IMPLEMENT_LHASH_DOALL_FN(STUFF_cleanup, STUFF)
+         /* ... then later in the code ... */
+ /* So to run "STUFF_cleanup" against all items in a hash table ... */
+ lh_STUFF_doall(hashtable, LHASH_DOALL_FN(STUFF_cleanup));
+ /* Then the hash table itself can be deallocated */
+ lh_STUFF_free(hashtable);
+
+When doing this, be careful if you delete entries from the hash table
+in your callbacks: the table may decrease in size, moving the item
+that you are currently on down lower in the hash table - this could
+cause some entries to be skipped during the iteration.  The second
+best solution to this problem is to set hash-E<gt>down_load=0 before
+you start (which will stop the hash table ever decreasing in size).
+The best solution is probably to avoid deleting items from the hash
+table inside a "doall" callback!
+
+lh_<type>_doall_arg() is the same as lh_<type>_doall() except that
+B<func> will be called with B<arg> as the second argument and B<func>
+should be of type B<LHASH_DOALL_ARG_FN_TYPE> (a callback prototype
+that is passed both the table entry and an extra argument).  As with
+lh_doall(), you can instead choose to declare your callback with a
+prototype matching the types you are dealing with and use the
+declare/implement macros to create compatible wrappers that cast
+variables before calling your type-specific callbacks.  An example of
+this is demonstrated here (printing all hash table entries to a BIO
+that is provided by the caller):
+
+ /* Prints item 'a' to 'output_bio' (this is implemented elsewhere) */
+ void STUFF_print_doall_arg(const STUFF *a, BIO *output_bio);
+ /* Implement a prototype-compatible wrapper for "STUFF_print" */
+ static IMPLEMENT_LHASH_DOALL_ARG_FN(STUFF, const STUFF, BIO)
+         /* ... then later in the code ... */
+ /* Print out the entire hashtable to a particular BIO */
+ lh_STUFF_doall_arg(hashtable, LHASH_DOALL_ARG_FN(STUFF_print), BIO,
+                    logging_bio);
+ 
+lh_<type>_error() can be used to determine if an error occurred in the last
+operation. lh_<type>_error() is a macro.
+
+=head1 RETURN VALUES
+
+lh_<type>_new() returns B<NULL> on error, otherwise a pointer to the new
+B<LHASH> structure.
+
+When a hash table entry is replaced, lh_<type>_insert() returns the value
+being replaced. B<NULL> is returned on normal operation and on error.
+
+lh_<type>_delete() returns the entry being deleted.  B<NULL> is returned if
+there is no such value in the hash table.
+
+lh_<type>_retrieve() returns the hash table entry if it has been found,
+B<NULL> otherwise.
+
+lh_<type>_error() returns 1 if an error occurred in the last operation, 0
+otherwise.
+
+lh_<type>_free(), lh_<type>_doall() and lh_<type>_doall_arg() return no values.
+
+=head1 NOTE
+
+The various LHASH macros and callback types exist to make it possible
+to write type-checked code without resorting to function-prototype
+casting - an evil that makes application code much harder to
+audit/verify and also opens the window of opportunity for stack
+corruption and other hard-to-find bugs.  It also, apparently, violates
+ANSI-C.
+
+The LHASH code regards table entries as constant data.  As such, it
+internally represents lh_insert()'d items with a "const void *"
+pointer type.  This is why callbacks such as those used by lh_doall()
+and lh_doall_arg() declare their prototypes with "const", even for the
+parameters that pass back the table items' data pointers - for
+consistency, user-provided data is "const" at all times as far as the
+LHASH code is concerned.  However, as callers are themselves providing
+these pointers, they can choose whether they too should be treating
+all such parameters as constant.
+
+As an example, a hash table may be maintained by code that, for
+reasons of encapsulation, has only "const" access to the data being
+indexed in the hash table (ie. it is returned as "const" from
+elsewhere in their code) - in this case the LHASH prototypes are
+appropriate as-is.  Conversely, if the caller is responsible for the
+life-time of the data in question, then they may well wish to make
+modifications to table item passed back in the lh_doall() or
+lh_doall_arg() callbacks (see the "STUFF_cleanup" example above).  If
+so, the caller can either cast the "const" away (if they're providing
+the raw callbacks themselves) or use the macros to declare/implement
+the wrapper functions without "const" types.
+
+Callers that only have "const" access to data they're indexing in a
+table, yet declare callbacks without constant types (or cast the
+"const" away themselves), are therefore creating their own risks/bugs
+without being encouraged to do so by the API.  On a related note,
+those auditing code should pay special attention to any instances of
+DECLARE/IMPLEMENT_LHASH_DOALL_[ARG_]_FN macros that provide types
+without any "const" qualifiers.
+
+=head1 BUGS
+
+lh_<type>_insert() returns B<NULL> both for success and error.
+
+=head1 INTERNALS
+
+The following description is based on the SSLeay documentation:
+
+The B<lhash> library implements a hash table described in the
+I<Communications of the ACM> in 1991.  What makes this hash table
+different is that as the table fills, the hash table is increased (or
+decreased) in size via OPENSSL_realloc().  When a 'resize' is done, instead of
+all hashes being redistributed over twice as many 'buckets', one
+bucket is split.  So when an 'expand' is done, there is only a minimal
+cost to redistribute some values.  Subsequent inserts will cause more
+single 'bucket' redistributions but there will never be a sudden large
+cost due to redistributing all the 'buckets'.
+
+The state for a particular hash table is kept in the B<LHASH> structure.
+The decision to increase or decrease the hash table size is made
+depending on the 'load' of the hash table.  The load is the number of
+items in the hash table divided by the size of the hash table.  The
+default values are as follows.  If (hash->up_load E<lt> load) =E<gt>
+expand.  if (hash-E<gt>down_load E<gt> load) =E<gt> contract.  The
+B<up_load> has a default value of 1 and B<down_load> has a default value
+of 2.  These numbers can be modified by the application by just
+playing with the B<up_load> and B<down_load> variables.  The 'load' is
+kept in a form which is multiplied by 256.  So
+hash-E<gt>up_load=8*256; will cause a load of 8 to be set.
+
+If you are interested in performance the field to watch is
+num_comp_calls.  The hash library keeps track of the 'hash' value for
+each item so when a lookup is done, the 'hashes' are compared, if
+there is a match, then a full compare is done, and
+hash-E<gt>num_comp_calls is incremented.  If num_comp_calls is not equal
+to num_delete plus num_retrieve it means that your hash function is
+generating hashes that are the same for different values.  It is
+probably worth changing your hash function if this is the case because
+even if your hash table has 10 items in a 'bucket', it can be searched
+with 10 B<unsigned long> compares and 10 linked list traverses.  This
+will be much less expensive that 10 calls to your compare function.
+
+lh_strhash() is a demo string hashing function:
+
+ unsigned long lh_strhash(const char *c);
+
+Since the B<LHASH> routines would normally be passed structures, this
+routine would not normally be passed to lh_<type>_new(), rather it would be
+used in the function passed to lh_<type>_new().
+
+=head1 SEE ALSO
+
+L<lh_stats(3)|lh_stats(3)>
+
+=head1 HISTORY
+
+The B<lhash> library is available in all versions of SSLeay and OpenSSL.
+lh_error() was added in SSLeay 0.9.1b.
+
+This manpage is derived from the SSLeay documentation.
+
+In OpenSSL 0.9.7, all lhash functions that were passed function pointers
+were changed for better type safety, and the function types LHASH_COMP_FN_TYPE,
+LHASH_HASH_FN_TYPE, LHASH_DOALL_FN_TYPE and LHASH_DOALL_ARG_FN_TYPE 
+became available.
+
+In OpenSSL 1.0.0, the lhash interface was revamped for even better
+type checking.
+
+=cut
diff --git a/openssl/doc/crypto/md5.pod b/openssl/doc/crypto/md5.pod
new file mode 100644
index 0000000..d11d5c3
--- /dev/null
+++ b/openssl/doc/crypto/md5.pod
@@ -0,0 +1,101 @@
+=pod
+
+=head1 NAME
+
+MD2, MD4, MD5, MD2_Init, MD2_Update, MD2_Final, MD4_Init, MD4_Update,
+MD4_Final, MD5_Init, MD5_Update, MD5_Final - MD2, MD4, and MD5 hash functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/md2.h>
+
+ unsigned char *MD2(const unsigned char *d, unsigned long n,
+                  unsigned char *md);
+
+ int MD2_Init(MD2_CTX *c);
+ int MD2_Update(MD2_CTX *c, const unsigned char *data,
+                  unsigned long len);
+ int MD2_Final(unsigned char *md, MD2_CTX *c);
+
+
+ #include <openssl/md4.h>
+
+ unsigned char *MD4(const unsigned char *d, unsigned long n,
+                  unsigned char *md);
+
+ int MD4_Init(MD4_CTX *c);
+ int MD4_Update(MD4_CTX *c, const void *data,
+                  unsigned long len);
+ int MD4_Final(unsigned char *md, MD4_CTX *c);
+
+
+ #include <openssl/md5.h>
+
+ unsigned char *MD5(const unsigned char *d, unsigned long n,
+                  unsigned char *md);
+
+ int MD5_Init(MD5_CTX *c);
+ int MD5_Update(MD5_CTX *c, const void *data,
+                  unsigned long len);
+ int MD5_Final(unsigned char *md, MD5_CTX *c);
+
+=head1 DESCRIPTION
+
+MD2, MD4, and MD5 are cryptographic hash functions with a 128 bit output.
+
+MD2(), MD4(), and MD5() compute the MD2, MD4, and MD5 message digest
+of the B<n> bytes at B<d> and place it in B<md> (which must have space
+for MD2_DIGEST_LENGTH == MD4_DIGEST_LENGTH == MD5_DIGEST_LENGTH == 16
+bytes of output). If B<md> is NULL, the digest is placed in a static
+array.
+
+The following functions may be used if the message is not completely
+stored in memory:
+
+MD2_Init() initializes a B<MD2_CTX> structure.
+
+MD2_Update() can be called repeatedly with chunks of the message to
+be hashed (B<len> bytes at B<data>).
+
+MD2_Final() places the message digest in B<md>, which must have space
+for MD2_DIGEST_LENGTH == 16 bytes of output, and erases the B<MD2_CTX>.
+
+MD4_Init(), MD4_Update(), MD4_Final(), MD5_Init(), MD5_Update(), and
+MD5_Final() are analogous using an B<MD4_CTX> and B<MD5_CTX> structure.
+
+Applications should use the higher level functions
+L<EVP_DigestInit(3)|EVP_DigestInit(3)>
+etc. instead of calling the hash functions directly.
+
+=head1 NOTE
+
+MD2, MD4, and MD5 are recommended only for compatibility with existing
+applications. In new applications, SHA-1 or RIPEMD-160 should be
+preferred.
+
+=head1 RETURN VALUES
+
+MD2(), MD4(), and MD5() return pointers to the hash value. 
+
+MD2_Init(), MD2_Update(), MD2_Final(), MD4_Init(), MD4_Update(),
+MD4_Final(), MD5_Init(), MD5_Update(), and MD5_Final() return 1 for
+success, 0 otherwise.
+
+=head1 CONFORMING TO
+
+RFC 1319, RFC 1320, RFC 1321
+
+=head1 SEE ALSO
+
+L<sha(3)|sha(3)>, L<ripemd(3)|ripemd(3)>, L<EVP_DigestInit(3)|EVP_DigestInit(3)>
+
+=head1 HISTORY
+
+MD2(), MD2_Init(), MD2_Update() MD2_Final(), MD5(), MD5_Init(),
+MD5_Update() and MD5_Final() are available in all versions of SSLeay
+and OpenSSL.
+
+MD4(), MD4_Init(), and MD4_Update() are available in OpenSSL 0.9.6 and
+above.
+
+=cut
diff --git a/openssl/doc/crypto/mdc2.pod b/openssl/doc/crypto/mdc2.pod
new file mode 100644
index 0000000..41f648a
--- /dev/null
+++ b/openssl/doc/crypto/mdc2.pod
@@ -0,0 +1,64 @@
+=pod
+
+=head1 NAME
+
+MDC2, MDC2_Init, MDC2_Update, MDC2_Final - MDC2 hash function
+
+=head1 SYNOPSIS
+
+ #include <openssl/mdc2.h>
+
+ unsigned char *MDC2(const unsigned char *d, unsigned long n,
+                  unsigned char *md);
+
+ int MDC2_Init(MDC2_CTX *c);
+ int MDC2_Update(MDC2_CTX *c, const unsigned char *data,
+                  unsigned long len);
+ int MDC2_Final(unsigned char *md, MDC2_CTX *c);
+
+=head1 DESCRIPTION
+
+MDC2 is a method to construct hash functions with 128 bit output from
+block ciphers.  These functions are an implementation of MDC2 with
+DES.
+
+MDC2() computes the MDC2 message digest of the B<n>
+bytes at B<d> and places it in B<md> (which must have space for
+MDC2_DIGEST_LENGTH == 16 bytes of output). If B<md> is NULL, the digest
+is placed in a static array.
+
+The following functions may be used if the message is not completely
+stored in memory:
+
+MDC2_Init() initializes a B<MDC2_CTX> structure.
+
+MDC2_Update() can be called repeatedly with chunks of the message to
+be hashed (B<len> bytes at B<data>).
+
+MDC2_Final() places the message digest in B<md>, which must have space
+for MDC2_DIGEST_LENGTH == 16 bytes of output, and erases the B<MDC2_CTX>.
+
+Applications should use the higher level functions
+L<EVP_DigestInit(3)|EVP_DigestInit(3)> etc. instead of calling the
+hash functions directly.
+
+=head1 RETURN VALUES
+
+MDC2() returns a pointer to the hash value. 
+
+MDC2_Init(), MDC2_Update() and MDC2_Final() return 1 for success, 0 otherwise.
+
+=head1 CONFORMING TO
+
+ISO/IEC 10118-2, with DES
+
+=head1 SEE ALSO
+
+L<sha(3)|sha(3)>, L<EVP_DigestInit(3)|EVP_DigestInit(3)>
+
+=head1 HISTORY
+
+MDC2(), MDC2_Init(), MDC2_Update() and MDC2_Final() are available since
+SSLeay 0.8.
+
+=cut
diff --git a/openssl/doc/crypto/pem.pod b/openssl/doc/crypto/pem.pod
new file mode 100644
index 0000000..d5b1896
--- /dev/null
+++ b/openssl/doc/crypto/pem.pod
@@ -0,0 +1,476 @@
+=pod
+
+=head1 NAME
+
+PEM, PEM_read_bio_PrivateKey, PEM_read_PrivateKey, PEM_write_bio_PrivateKey, PEM_write_PrivateKey, PEM_write_bio_PKCS8PrivateKey, PEM_write_PKCS8PrivateKey, PEM_write_bio_PKCS8PrivateKey_nid, PEM_write_PKCS8PrivateKey_nid, PEM_read_bio_PUBKEY, PEM_read_PUBKEY, PEM_write_bio_PUBKEY, PEM_write_PUBKEY, PEM_read_bio_RSAPrivateKey, PEM_read_RSAPrivateKey, PEM_write_bio_RSAPrivateKey, PEM_write_RSAPrivateKey, PEM_read_bio_RSAPublicKey, PEM_read_RSAPublicKey, PEM_write_bio_RSAPublicKey, PEM_write_RSAPublicKey, PEM_read_bio_RSA_PUBKEY, PEM_read_RSA_PUBKEY, PEM_write_bio_RSA_PUBKEY, PEM_write_RSA_PUBKEY, PEM_read_bio_DSAPrivateKey, PEM_read_DSAPrivateKey, PEM_write_bio_DSAPrivateKey, PEM_write_DSAPrivateKey, PEM_read_bio_DSA_PUBKEY, PEM_read_DSA_PUBKEY, PEM_write_bio_DSA_PUBKEY, PEM_write_DSA_PUBKEY, PEM_read_bio_DSAparams, PEM_read_DSAparams, PEM_write_bio_DSAparams, PEM_write_DSAparams, PEM_read_bio_DHparams, PEM_read_DHparams, PEM_write_bio_DHparams, PEM_write_DHparams, PEM_read_bio_X509, PEM_read_X509, PEM_write_bio_X509, PEM_write_X509, PEM_read_bio_X509_AUX, PEM_read_X509_AUX, PEM_write_bio_X509_AUX, PEM_write_X509_AUX, PEM_read_bio_X509_REQ, PEM_read_X509_REQ, PEM_write_bio_X509_REQ, PEM_write_X509_REQ, PEM_write_bio_X509_REQ_NEW, PEM_write_X509_REQ_NEW, PEM_read_bio_X509_CRL, PEM_read_X509_CRL, PEM_write_bio_X509_CRL, PEM_write_X509_CRL, PEM_read_bio_PKCS7, PEM_read_PKCS7, PEM_write_bio_PKCS7, PEM_write_PKCS7, PEM_read_bio_NETSCAPE_CERT_SEQUENCE, PEM_read_NETSCAPE_CERT_SEQUENCE, PEM_write_bio_NETSCAPE_CERT_SEQUENCE, PEM_write_NETSCAPE_CERT_SEQUENCE - PEM routines
+
+=head1 SYNOPSIS
+
+ #include <openssl/pem.h>
+
+ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x,
+					pem_password_cb *cb, void *u);
+
+ EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x,
+					pem_password_cb *cb, void *u);
+
+ int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+					unsigned char *kstr, int klen,
+					pem_password_cb *cb, void *u);
+
+ int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+					unsigned char *kstr, int klen,
+					pem_password_cb *cb, void *u);
+
+ int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+					char *kstr, int klen,
+					pem_password_cb *cb, void *u);
+
+ int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+					char *kstr, int klen,
+					pem_password_cb *cb, void *u);
+
+ int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
+					char *kstr, int klen,
+					pem_password_cb *cb, void *u);
+
+ int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
+					char *kstr, int klen,
+					pem_password_cb *cb, void *u);
+
+ EVP_PKEY *PEM_read_bio_PUBKEY(BIO *bp, EVP_PKEY **x,
+					pem_password_cb *cb, void *u);
+
+ EVP_PKEY *PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x,
+					pem_password_cb *cb, void *u);
+
+ int PEM_write_bio_PUBKEY(BIO *bp, EVP_PKEY *x);
+ int PEM_write_PUBKEY(FILE *fp, EVP_PKEY *x);
+
+ RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **x,
+					pem_password_cb *cb, void *u);
+
+ RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **x,
+					pem_password_cb *cb, void *u);
+
+ int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc,
+					unsigned char *kstr, int klen,
+					pem_password_cb *cb, void *u);
+
+ int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
+					unsigned char *kstr, int klen,
+					pem_password_cb *cb, void *u);
+
+ RSA *PEM_read_bio_RSAPublicKey(BIO *bp, RSA **x,
+					pem_password_cb *cb, void *u);
+
+ RSA *PEM_read_RSAPublicKey(FILE *fp, RSA **x,
+					pem_password_cb *cb, void *u);
+
+ int PEM_write_bio_RSAPublicKey(BIO *bp, RSA *x);
+
+ int PEM_write_RSAPublicKey(FILE *fp, RSA *x);
+
+ RSA *PEM_read_bio_RSA_PUBKEY(BIO *bp, RSA **x,
+					pem_password_cb *cb, void *u);
+
+ RSA *PEM_read_RSA_PUBKEY(FILE *fp, RSA **x,
+					pem_password_cb *cb, void *u);
+
+ int PEM_write_bio_RSA_PUBKEY(BIO *bp, RSA *x);
+
+ int PEM_write_RSA_PUBKEY(FILE *fp, RSA *x);
+
+ DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **x,
+					pem_password_cb *cb, void *u);
+
+ DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **x,
+					pem_password_cb *cb, void *u);
+
+ int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc,
+					unsigned char *kstr, int klen,
+					pem_password_cb *cb, void *u);
+
+ int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc,
+					unsigned char *kstr, int klen,
+					pem_password_cb *cb, void *u);
+
+ DSA *PEM_read_bio_DSA_PUBKEY(BIO *bp, DSA **x,
+					pem_password_cb *cb, void *u);
+
+ DSA *PEM_read_DSA_PUBKEY(FILE *fp, DSA **x,
+					pem_password_cb *cb, void *u);
+
+ int PEM_write_bio_DSA_PUBKEY(BIO *bp, DSA *x);
+
+ int PEM_write_DSA_PUBKEY(FILE *fp, DSA *x);
+
+ DSA *PEM_read_bio_DSAparams(BIO *bp, DSA **x, pem_password_cb *cb, void *u);
+
+ DSA *PEM_read_DSAparams(FILE *fp, DSA **x, pem_password_cb *cb, void *u);
+
+ int PEM_write_bio_DSAparams(BIO *bp, DSA *x);
+
+ int PEM_write_DSAparams(FILE *fp, DSA *x);
+
+ DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u);
+
+ DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u);
+
+ int PEM_write_bio_DHparams(BIO *bp, DH *x);
+
+ int PEM_write_DHparams(FILE *fp, DH *x);
+
+ X509 *PEM_read_bio_X509(BIO *bp, X509 **x, pem_password_cb *cb, void *u);
+
+ X509 *PEM_read_X509(FILE *fp, X509 **x, pem_password_cb *cb, void *u);
+
+ int PEM_write_bio_X509(BIO *bp, X509 *x);
+
+ int PEM_write_X509(FILE *fp, X509 *x);
+
+ X509 *PEM_read_bio_X509_AUX(BIO *bp, X509 **x, pem_password_cb *cb, void *u);
+
+ X509 *PEM_read_X509_AUX(FILE *fp, X509 **x, pem_password_cb *cb, void *u);
+
+ int PEM_write_bio_X509_AUX(BIO *bp, X509 *x);
+
+ int PEM_write_X509_AUX(FILE *fp, X509 *x);
+
+ X509_REQ *PEM_read_bio_X509_REQ(BIO *bp, X509_REQ **x,
+					pem_password_cb *cb, void *u);
+
+ X509_REQ *PEM_read_X509_REQ(FILE *fp, X509_REQ **x,
+					pem_password_cb *cb, void *u);
+
+ int PEM_write_bio_X509_REQ(BIO *bp, X509_REQ *x);
+
+ int PEM_write_X509_REQ(FILE *fp, X509_REQ *x);
+
+ int PEM_write_bio_X509_REQ_NEW(BIO *bp, X509_REQ *x);
+
+ int PEM_write_X509_REQ_NEW(FILE *fp, X509_REQ *x);
+
+ X509_CRL *PEM_read_bio_X509_CRL(BIO *bp, X509_CRL **x,
+					pem_password_cb *cb, void *u);
+ X509_CRL *PEM_read_X509_CRL(FILE *fp, X509_CRL **x,
+					pem_password_cb *cb, void *u);
+ int PEM_write_bio_X509_CRL(BIO *bp, X509_CRL *x);
+ int PEM_write_X509_CRL(FILE *fp, X509_CRL *x);
+
+ PKCS7 *PEM_read_bio_PKCS7(BIO *bp, PKCS7 **x, pem_password_cb *cb, void *u);
+
+ PKCS7 *PEM_read_PKCS7(FILE *fp, PKCS7 **x, pem_password_cb *cb, void *u);
+
+ int PEM_write_bio_PKCS7(BIO *bp, PKCS7 *x);
+
+ int PEM_write_PKCS7(FILE *fp, PKCS7 *x);
+
+ NETSCAPE_CERT_SEQUENCE *PEM_read_bio_NETSCAPE_CERT_SEQUENCE(BIO *bp,
+						NETSCAPE_CERT_SEQUENCE **x,
+						pem_password_cb *cb, void *u);
+
+ NETSCAPE_CERT_SEQUENCE *PEM_read_NETSCAPE_CERT_SEQUENCE(FILE *fp,
+						NETSCAPE_CERT_SEQUENCE **x,
+						pem_password_cb *cb, void *u);
+
+ int PEM_write_bio_NETSCAPE_CERT_SEQUENCE(BIO *bp, NETSCAPE_CERT_SEQUENCE *x);
+
+ int PEM_write_NETSCAPE_CERT_SEQUENCE(FILE *fp, NETSCAPE_CERT_SEQUENCE *x);
+
+=head1 DESCRIPTION
+
+The PEM functions read or write structures in PEM format. In
+this sense PEM format is simply base64 encoded data surrounded
+by header lines.
+
+For more details about the meaning of arguments see the
+B<PEM FUNCTION ARGUMENTS> section.
+
+Each operation has four functions associated with it. For
+clarity the term "B<foobar> functions" will be used to collectively
+refer to the PEM_read_bio_foobar(), PEM_read_foobar(),
+PEM_write_bio_foobar() and PEM_write_foobar() functions.
+
+The B<PrivateKey> functions read or write a private key in
+PEM format using an EVP_PKEY structure. The write routines use
+"traditional" private key format and can handle both RSA and DSA
+private keys. The read functions can additionally transparently
+handle PKCS#8 format encrypted and unencrypted keys too.
+
+PEM_write_bio_PKCS8PrivateKey() and PEM_write_PKCS8PrivateKey()
+write a private key in an EVP_PKEY structure in PKCS#8
+EncryptedPrivateKeyInfo format using PKCS#5 v2.0 password based encryption
+algorithms. The B<cipher> argument specifies the encryption algoritm to
+use: unlike all other PEM routines the encryption is applied at the
+PKCS#8 level and not in the PEM headers. If B<cipher> is NULL then no
+encryption is used and a PKCS#8 PrivateKeyInfo structure is used instead.
+
+PEM_write_bio_PKCS8PrivateKey_nid() and PEM_write_PKCS8PrivateKey_nid()
+also write out a private key as a PKCS#8 EncryptedPrivateKeyInfo however
+it uses PKCS#5 v1.5 or PKCS#12 encryption algorithms instead. The algorithm
+to use is specified in the B<nid> parameter and should be the NID of the
+corresponding OBJECT IDENTIFIER (see NOTES section).
+
+The B<PUBKEY> functions process a public key using an EVP_PKEY
+structure. The public key is encoded as a SubjectPublicKeyInfo
+structure.
+
+The B<RSAPrivateKey> functions process an RSA private key using an
+RSA structure. It handles the same formats as the B<PrivateKey>
+functions but an error occurs if the private key is not RSA.
+
+The B<RSAPublicKey> functions process an RSA public key using an
+RSA structure. The public key is encoded using a PKCS#1 RSAPublicKey
+structure.
+
+The B<RSA_PUBKEY> functions also process an RSA public key using
+an RSA structure. However the public key is encoded using a
+SubjectPublicKeyInfo structure and an error occurs if the public
+key is not RSA.
+
+The B<DSAPrivateKey> functions process a DSA private key using a
+DSA structure. It handles the same formats as the B<PrivateKey>
+functions but an error occurs if the private key is not DSA.
+
+The B<DSA_PUBKEY> functions process a DSA public key using
+a DSA structure. The public key is encoded using a
+SubjectPublicKeyInfo structure and an error occurs if the public
+key is not DSA.
+
+The B<DSAparams> functions process DSA parameters using a DSA
+structure. The parameters are encoded using a foobar structure.
+
+The B<DHparams> functions process DH parameters using a DH
+structure. The parameters are encoded using a PKCS#3 DHparameter
+structure.
+
+The B<X509> functions process an X509 certificate using an X509
+structure. They will also process a trusted X509 certificate but
+any trust settings are discarded.
+
+The B<X509_AUX> functions process a trusted X509 certificate using
+an X509 structure. 
+
+The B<X509_REQ> and B<X509_REQ_NEW> functions process a PKCS#10
+certificate request using an X509_REQ structure. The B<X509_REQ>
+write functions use B<CERTIFICATE REQUEST> in the header whereas
+the B<X509_REQ_NEW> functions use B<NEW CERTIFICATE REQUEST>
+(as required by some CAs). The B<X509_REQ> read functions will
+handle either form so there are no B<X509_REQ_NEW> read functions.
+
+The B<X509_CRL> functions process an X509 CRL using an X509_CRL
+structure.
+
+The B<PKCS7> functions process a PKCS#7 ContentInfo using a PKCS7
+structure.
+
+The B<NETSCAPE_CERT_SEQUENCE> functions process a Netscape Certificate
+Sequence using a NETSCAPE_CERT_SEQUENCE structure.
+
+=head1 PEM FUNCTION ARGUMENTS
+
+The PEM functions have many common arguments.
+
+The B<bp> BIO parameter (if present) specifies the BIO to read from
+or write to.
+
+The B<fp> FILE parameter (if present) specifies the FILE pointer to
+read from or write to.
+
+The PEM read functions all take an argument B<TYPE **x> and return
+a B<TYPE *> pointer. Where B<TYPE> is whatever structure the function
+uses. If B<x> is NULL then the parameter is ignored. If B<x> is not
+NULL but B<*x> is NULL then the structure returned will be written
+to B<*x>. If neither B<x> nor B<*x> is NULL then an attempt is made
+to reuse the structure at B<*x> (but see BUGS and EXAMPLES sections).
+Irrespective of the value of B<x> a pointer to the structure is always
+returned (or NULL if an error occurred).
+
+The PEM functions which write private keys take an B<enc> parameter
+which specifies the encryption algorithm to use, encryption is done
+at the PEM level. If this parameter is set to NULL then the private
+key is written in unencrypted form.
+
+The B<cb> argument is the callback to use when querying for the pass
+phrase used for encrypted PEM structures (normally only private keys).
+
+For the PEM write routines if the B<kstr> parameter is not NULL then
+B<klen> bytes at B<kstr> are used as the passphrase and B<cb> is
+ignored.
+
+If the B<cb> parameters is set to NULL and the B<u> parameter is not
+NULL then the B<u> parameter is interpreted as a null terminated string
+to use as the passphrase. If both B<cb> and B<u> are NULL then the
+default callback routine is used which will typically prompt for the
+passphrase on the current terminal with echoing turned off.
+
+The default passphrase callback is sometimes inappropriate (for example
+in a GUI application) so an alternative can be supplied. The callback
+routine has the following form:
+
+ int cb(char *buf, int size, int rwflag, void *u);
+
+B<buf> is the buffer to write the passphrase to. B<size> is the maximum
+length of the passphrase (i.e. the size of buf). B<rwflag> is a flag
+which is set to 0 when reading and 1 when writing. A typical routine
+will ask the user to verify the passphrase (for example by prompting
+for it twice) if B<rwflag> is 1. The B<u> parameter has the same
+value as the B<u> parameter passed to the PEM routine. It allows
+arbitrary data to be passed to the callback by the application
+(for example a window handle in a GUI application). The callback
+B<must> return the number of characters in the passphrase or 0 if
+an error occurred.
+
+=head1 EXAMPLES
+
+Although the PEM routines take several arguments in almost all applications
+most of them are set to 0 or NULL.
+
+Read a certificate in PEM format from a BIO:
+
+ X509 *x;
+ x = PEM_read_bio_X509(bp, NULL, 0, NULL);
+ if (x == NULL)
+	{
+	/* Error */
+	}
+
+Alternative method:
+
+ X509 *x = NULL;
+ if (!PEM_read_bio_X509(bp, &x, 0, NULL))
+	{
+	/* Error */
+	}
+
+Write a certificate to a BIO:
+
+ if (!PEM_write_bio_X509(bp, x))
+	{
+	/* Error */
+	}
+
+Write an unencrypted private key to a FILE pointer:
+
+ if (!PEM_write_PrivateKey(fp, key, NULL, NULL, 0, 0, NULL))
+	{
+	/* Error */
+	}
+
+Write a private key (using traditional format) to a BIO using
+triple DES encryption, the pass phrase is prompted for:
+
+ if (!PEM_write_bio_PrivateKey(bp, key, EVP_des_ede3_cbc(), NULL, 0, 0, NULL))
+	{
+	/* Error */
+	}
+
+Write a private key (using PKCS#8 format) to a BIO using triple
+DES encryption, using the pass phrase "hello":
+
+ if (!PEM_write_bio_PKCS8PrivateKey(bp, key, EVP_des_ede3_cbc(), NULL, 0, 0, "hello"))
+	{
+	/* Error */
+	}
+
+Read a private key from a BIO using the pass phrase "hello":
+
+ key = PEM_read_bio_PrivateKey(bp, NULL, 0, "hello");
+ if (key == NULL)
+	{
+	/* Error */
+	}
+
+Read a private key from a BIO using a pass phrase callback:
+
+ key = PEM_read_bio_PrivateKey(bp, NULL, pass_cb, "My Private Key");
+ if (key == NULL)
+	{
+	/* Error */
+	}
+
+Skeleton pass phrase callback:
+
+ int pass_cb(char *buf, int size, int rwflag, void *u);
+	{
+	int len;
+	char *tmp;
+	/* We'd probably do something else if 'rwflag' is 1 */
+	printf("Enter pass phrase for \"%s\"\n", u);
+
+	/* get pass phrase, length 'len' into 'tmp' */
+	tmp = "hello";
+	len = strlen(tmp);
+
+	if (len <= 0) return 0;
+	/* if too long, truncate */
+	if (len > size) len = size;
+	memcpy(buf, tmp, len);
+	return len;
+	}
+
+=head1 NOTES
+
+The old B<PrivateKey> write routines are retained for compatibility.
+New applications should write private keys using the
+PEM_write_bio_PKCS8PrivateKey() or PEM_write_PKCS8PrivateKey() routines
+because they are more secure (they use an iteration count of 2048 whereas
+the traditional routines use a count of 1) unless compatibility with older
+versions of OpenSSL is important.
+
+The B<PrivateKey> read routines can be used in all applications because
+they handle all formats transparently.
+
+A frequent cause of problems is attempting to use the PEM routines like
+this:
+
+ X509 *x;
+ PEM_read_bio_X509(bp, &x, 0, NULL);
+
+this is a bug because an attempt will be made to reuse the data at B<x>
+which is an uninitialised pointer.
+
+=head1 PEM ENCRYPTION FORMAT
+
+This old B<PrivateKey> routines use a non standard technique for encryption.
+
+The private key (or other data) takes the following form: 
+
+ -----BEGIN RSA PRIVATE KEY-----
+ Proc-Type: 4,ENCRYPTED
+ DEK-Info: DES-EDE3-CBC,3F17F5316E2BAC89
+
+ ...base64 encoded data...
+ -----END RSA PRIVATE KEY-----
+
+The line beginning DEK-Info contains two comma separated pieces of information:
+the encryption algorithm name as used by EVP_get_cipherbyname() and an 8
+byte B<salt> encoded as a set of hexadecimal digits.
+
+After this is the base64 encoded encrypted data.
+
+The encryption key is determined using EVP_bytestokey(), using B<salt> and an
+iteration count of 1. The IV used is the value of B<salt> and *not* the IV
+returned by EVP_bytestokey().
+
+=head1 BUGS
+
+The PEM read routines in some versions of OpenSSL will not correctly reuse
+an existing structure. Therefore the following:
+
+ PEM_read_bio_X509(bp, &x, 0, NULL);
+
+where B<x> already contains a valid certificate, may not work, whereas: 
+
+ X509_free(x);
+ x = PEM_read_bio_X509(bp, NULL, 0, NULL);
+
+is guaranteed to work.
+
+=head1 RETURN CODES
+
+The read routines return either a pointer to the structure read or NULL
+if an error occurred.
+
+The write routines return 1 for success or 0 for failure.
diff --git a/openssl/doc/crypto/rand.pod b/openssl/doc/crypto/rand.pod
new file mode 100644
index 0000000..1c068c8
--- /dev/null
+++ b/openssl/doc/crypto/rand.pod
@@ -0,0 +1,175 @@
+=pod
+
+=head1 NAME
+
+rand - pseudo-random number generator
+
+=head1 SYNOPSIS
+
+ #include <openssl/rand.h>
+
+ int  RAND_set_rand_engine(ENGINE *engine);
+
+ int  RAND_bytes(unsigned char *buf, int num);
+ int  RAND_pseudo_bytes(unsigned char *buf, int num);
+
+ void RAND_seed(const void *buf, int num);
+ void RAND_add(const void *buf, int num, int entropy);
+ int  RAND_status(void);
+
+ int  RAND_load_file(const char *file, long max_bytes);
+ int  RAND_write_file(const char *file);
+ const char *RAND_file_name(char *file, size_t num);
+
+ int  RAND_egd(const char *path);
+
+ void RAND_set_rand_method(const RAND_METHOD *meth);
+ const RAND_METHOD *RAND_get_rand_method(void);
+ RAND_METHOD *RAND_SSLeay(void);
+
+ void RAND_cleanup(void);
+
+ /* For Win32 only */
+ void RAND_screen(void);
+ int RAND_event(UINT, WPARAM, LPARAM);
+
+=head1 DESCRIPTION
+
+Since the introduction of the ENGINE API, the recommended way of controlling
+default implementations is by using the ENGINE API functions. The default
+B<RAND_METHOD>, as set by RAND_set_rand_method() and returned by
+RAND_get_rand_method(), is only used if no ENGINE has been set as the default
+"rand" implementation. Hence, these two functions are no longer the recommened
+way to control defaults.
+
+If an alternative B<RAND_METHOD> implementation is being used (either set
+directly or as provided by an ENGINE module), then it is entirely responsible
+for the generation and management of a cryptographically secure PRNG stream. The
+mechanisms described below relate solely to the software PRNG implementation
+built in to OpenSSL and used by default.
+
+These functions implement a cryptographically secure pseudo-random
+number generator (PRNG). It is used by other library functions for
+example to generate random keys, and applications can use it when they
+need randomness.
+
+A cryptographic PRNG must be seeded with unpredictable data such as
+mouse movements or keys pressed at random by the user. This is
+described in L<RAND_add(3)|RAND_add(3)>. Its state can be saved in a seed file
+(see L<RAND_load_file(3)|RAND_load_file(3)>) to avoid having to go through the
+seeding process whenever the application is started.
+
+L<RAND_bytes(3)|RAND_bytes(3)> describes how to obtain random data from the
+PRNG. 
+
+=head1 INTERNALS
+
+The RAND_SSLeay() method implements a PRNG based on a cryptographic
+hash function.
+
+The following description of its design is based on the SSLeay
+documentation:
+
+First up I will state the things I believe I need for a good RNG.
+
+=over 4
+
+=item 1
+
+A good hashing algorithm to mix things up and to convert the RNG 'state'
+to random numbers.
+
+=item 2
+
+An initial source of random 'state'.
+
+=item 3
+
+The state should be very large.  If the RNG is being used to generate
+4096 bit RSA keys, 2 2048 bit random strings are required (at a minimum).
+If your RNG state only has 128 bits, you are obviously limiting the
+search space to 128 bits, not 2048.  I'm probably getting a little
+carried away on this last point but it does indicate that it may not be
+a bad idea to keep quite a lot of RNG state.  It should be easier to
+break a cipher than guess the RNG seed data.
+
+=item 4
+
+Any RNG seed data should influence all subsequent random numbers
+generated.  This implies that any random seed data entered will have
+an influence on all subsequent random numbers generated.
+
+=item 5
+
+When using data to seed the RNG state, the data used should not be
+extractable from the RNG state.  I believe this should be a
+requirement because one possible source of 'secret' semi random
+data would be a private key or a password.  This data must
+not be disclosed by either subsequent random numbers or a
+'core' dump left by a program crash.
+
+=item 6
+
+Given the same initial 'state', 2 systems should deviate in their RNG state
+(and hence the random numbers generated) over time if at all possible.
+
+=item 7
+
+Given the random number output stream, it should not be possible to determine
+the RNG state or the next random number.
+
+=back
+
+The algorithm is as follows.
+
+There is global state made up of a 1023 byte buffer (the 'state'), a
+working hash value ('md'), and a counter ('count').
+
+Whenever seed data is added, it is inserted into the 'state' as
+follows.
+
+The input is chopped up into units of 20 bytes (or less for
+the last block).  Each of these blocks is run through the hash
+function as follows:  The data passed to the hash function
+is the current 'md', the same number of bytes from the 'state'
+(the location determined by in incremented looping index) as
+the current 'block', the new key data 'block', and 'count'
+(which is incremented after each use).
+The result of this is kept in 'md' and also xored into the
+'state' at the same locations that were used as input into the
+hash function. I
+believe this system addresses points 1 (hash function; currently
+SHA-1), 3 (the 'state'), 4 (via the 'md'), 5 (by the use of a hash
+function and xor).
+
+When bytes are extracted from the RNG, the following process is used.
+For each group of 10 bytes (or less), we do the following:
+
+Input into the hash function the local 'md' (which is initialized from
+the global 'md' before any bytes are generated), the bytes that are to
+be overwritten by the random bytes, and bytes from the 'state'
+(incrementing looping index). From this digest output (which is kept
+in 'md'), the top (up to) 10 bytes are returned to the caller and the
+bottom 10 bytes are xored into the 'state'.
+
+Finally, after we have finished 'num' random bytes for the caller,
+'count' (which is incremented) and the local and global 'md' are fed
+into the hash function and the results are kept in the global 'md'.
+
+I believe the above addressed points 1 (use of SHA-1), 6 (by hashing
+into the 'state' the 'old' data from the caller that is about to be
+overwritten) and 7 (by not using the 10 bytes given to the caller to
+update the 'state', but they are used to update 'md').
+
+So of the points raised, only 2 is not addressed (but see
+L<RAND_add(3)|RAND_add(3)>).
+
+=head1 SEE ALSO
+
+L<BN_rand(3)|BN_rand(3)>, L<RAND_add(3)|RAND_add(3)>,
+L<RAND_load_file(3)|RAND_load_file(3)>, L<RAND_egd(3)|RAND_egd(3)>,
+L<RAND_bytes(3)|RAND_bytes(3)>,
+L<RAND_set_rand_method(3)|RAND_set_rand_method(3)>,
+L<RAND_cleanup(3)|RAND_cleanup(3)> 
+
+=cut
diff --git a/openssl/doc/crypto/rc4.pod b/openssl/doc/crypto/rc4.pod
new file mode 100644
index 0000000..b6d3a43
--- /dev/null
+++ b/openssl/doc/crypto/rc4.pod
@@ -0,0 +1,62 @@
+=pod
+
+=head1 NAME
+
+RC4_set_key, RC4 - RC4 encryption
+
+=head1 SYNOPSIS
+
+ #include <openssl/rc4.h>
+
+ void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
+
+ void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
+          unsigned char *outdata);
+
+=head1 DESCRIPTION
+
+This library implements the Alleged RC4 cipher, which is described for
+example in I<Applied Cryptography>.  It is believed to be compatible
+with RC4[TM], a proprietary cipher of RSA Security Inc.
+
+RC4 is a stream cipher with variable key length.  Typically, 128 bit
+(16 byte) keys are used for strong encryption, but shorter insecure
+key sizes have been widely used due to export restrictions.
+
+RC4 consists of a key setup phase and the actual encryption or
+decryption phase.
+
+RC4_set_key() sets up the B<RC4_KEY> B<key> using the B<len> bytes long
+key at B<data>.
+
+RC4() encrypts or decrypts the B<len> bytes of data at B<indata> using
+B<key> and places the result at B<outdata>.  Repeated RC4() calls with
+the same B<key> yield a continuous key stream.
+
+Since RC4 is a stream cipher (the input is XORed with a pseudo-random
+key stream to produce the output), decryption uses the same function
+calls as encryption.
+
+Applications should use the higher level functions
+L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>
+etc. instead of calling the RC4 functions directly.
+
+=head1 RETURN VALUES
+
+RC4_set_key() and RC4() do not return values.
+
+=head1 NOTE
+
+Certain conditions have to be observed to securely use stream ciphers.
+It is not permissible to perform multiple encryptions using the same
+key stream.
+
+=head1 SEE ALSO
+
+L<blowfish(3)|blowfish(3)>, L<des(3)|des(3)>, L<rc2(3)|rc2(3)>
+
+=head1 HISTORY
+
+RC4_set_key() and RC4() are available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/ripemd.pod b/openssl/doc/crypto/ripemd.pod
new file mode 100644
index 0000000..264bb99
--- /dev/null
+++ b/openssl/doc/crypto/ripemd.pod
@@ -0,0 +1,66 @@
+=pod
+
+=head1 NAME
+
+RIPEMD160, RIPEMD160_Init, RIPEMD160_Update, RIPEMD160_Final -
+RIPEMD-160 hash function
+
+=head1 SYNOPSIS
+
+ #include <openssl/ripemd.h>
+
+ unsigned char *RIPEMD160(const unsigned char *d, unsigned long n,
+                  unsigned char *md);
+
+ int RIPEMD160_Init(RIPEMD160_CTX *c);
+ int RIPEMD160_Update(RIPEMD_CTX *c, const void *data,
+                  unsigned long len);
+ int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c);
+
+=head1 DESCRIPTION
+
+RIPEMD-160 is a cryptographic hash function with a
+160 bit output.
+
+RIPEMD160() computes the RIPEMD-160 message digest of the B<n>
+bytes at B<d> and places it in B<md> (which must have space for
+RIPEMD160_DIGEST_LENGTH == 20 bytes of output). If B<md> is NULL, the digest
+is placed in a static array.
+
+The following functions may be used if the message is not completely
+stored in memory:
+
+RIPEMD160_Init() initializes a B<RIPEMD160_CTX> structure.
+
+RIPEMD160_Update() can be called repeatedly with chunks of the message to
+be hashed (B<len> bytes at B<data>).
+
+RIPEMD160_Final() places the message digest in B<md>, which must have
+space for RIPEMD160_DIGEST_LENGTH == 20 bytes of output, and erases
+the B<RIPEMD160_CTX>.
+
+Applications should use the higher level functions
+L<EVP_DigestInit(3)|EVP_DigestInit(3)> etc. instead of calling the
+hash functions directly.
+
+=head1 RETURN VALUES
+
+RIPEMD160() returns a pointer to the hash value. 
+
+RIPEMD160_Init(), RIPEMD160_Update() and RIPEMD160_Final() return 1 for
+success, 0 otherwise.
+
+=head1 CONFORMING TO
+
+ISO/IEC 10118-3 (draft) (??)
+
+=head1 SEE ALSO
+
+L<sha(3)|sha(3)>, L<hmac(3)|hmac(3)>, L<EVP_DigestInit(3)|EVP_DigestInit(3)>
+
+=head1 HISTORY
+
+RIPEMD160(), RIPEMD160_Init(), RIPEMD160_Update() and
+RIPEMD160_Final() are available since SSLeay 0.9.0.
+
+=cut
diff --git a/openssl/doc/crypto/rsa.pod b/openssl/doc/crypto/rsa.pod
new file mode 100644
index 0000000..45ac53f
--- /dev/null
+++ b/openssl/doc/crypto/rsa.pod
@@ -0,0 +1,123 @@
+=pod
+
+=head1 NAME
+
+rsa - RSA public key cryptosystem
+
+=head1 SYNOPSIS
+
+ #include <openssl/rsa.h>
+ #include <openssl/engine.h>
+
+ RSA * RSA_new(void);
+ void RSA_free(RSA *rsa);
+
+ int RSA_public_encrypt(int flen, unsigned char *from,
+    unsigned char *to, RSA *rsa, int padding);
+ int RSA_private_decrypt(int flen, unsigned char *from,
+    unsigned char *to, RSA *rsa, int padding);
+ int RSA_private_encrypt(int flen, unsigned char *from,
+    unsigned char *to, RSA *rsa,int padding);
+ int RSA_public_decrypt(int flen, unsigned char *from, 
+    unsigned char *to, RSA *rsa,int padding);
+
+ int RSA_sign(int type, unsigned char *m, unsigned int m_len,
+    unsigned char *sigret, unsigned int *siglen, RSA *rsa);
+ int RSA_verify(int type, unsigned char *m, unsigned int m_len,
+    unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
+
+ int RSA_size(const RSA *rsa);
+
+ RSA *RSA_generate_key(int num, unsigned long e,
+    void (*callback)(int,int,void *), void *cb_arg);
+
+ int RSA_check_key(RSA *rsa);
+
+ int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
+ void RSA_blinding_off(RSA *rsa);
+
+ void RSA_set_default_method(const RSA_METHOD *meth);
+ const RSA_METHOD *RSA_get_default_method(void);
+ int RSA_set_method(RSA *rsa, const RSA_METHOD *meth);
+ const RSA_METHOD *RSA_get_method(const RSA *rsa);
+ RSA_METHOD *RSA_PKCS1_SSLeay(void);
+ RSA_METHOD *RSA_null_method(void);
+ int RSA_flags(const RSA *rsa);
+ RSA *RSA_new_method(ENGINE *engine);
+
+ int RSA_print(BIO *bp, RSA *x, int offset);
+ int RSA_print_fp(FILE *fp, RSA *x, int offset);
+
+ int RSA_get_ex_new_index(long argl, char *argp, int (*new_func)(),
+    int (*dup_func)(), void (*free_func)());
+ int RSA_set_ex_data(RSA *r,int idx,char *arg);
+ char *RSA_get_ex_data(RSA *r, int idx);
+
+ int RSA_sign_ASN1_OCTET_STRING(int dummy, unsigned char *m,
+    unsigned int m_len, unsigned char *sigret, unsigned int *siglen,
+    RSA *rsa);
+ int RSA_verify_ASN1_OCTET_STRING(int dummy, unsigned char *m,
+    unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
+    RSA *rsa);
+
+=head1 DESCRIPTION
+
+These functions implement RSA public key encryption and signatures
+as defined in PKCS #1 v2.0 [RFC 2437].
+
+The B<RSA> structure consists of several BIGNUM components. It can
+contain public as well as private RSA keys:
+
+ struct
+        {
+        BIGNUM *n;		// public modulus
+        BIGNUM *e;		// public exponent
+        BIGNUM *d;		// private exponent
+        BIGNUM *p;		// secret prime factor
+        BIGNUM *q;		// secret prime factor
+        BIGNUM *dmp1;		// d mod (p-1)
+        BIGNUM *dmq1;		// d mod (q-1)
+        BIGNUM *iqmp;		// q^-1 mod p
+	// ...
+        };
+ RSA
+
+In public keys, the private exponent and the related secret values are
+B<NULL>.
+
+B<p>, B<q>, B<dmp1>, B<dmq1> and B<iqmp> may be B<NULL> in private
+keys, but the RSA operations are much faster when these values are
+available.
+
+Note that RSA keys may use non-standard B<RSA_METHOD> implementations,
+either directly or by the use of B<ENGINE> modules. In some cases (eg. an
+ENGINE providing support for hardware-embedded keys), these BIGNUM values
+will not be used by the implementation or may be used for alternative data
+storage. For this reason, applications should generally avoid using RSA
+structure elements directly and instead use API functions to query or
+modify keys.
+
+=head1 CONFORMING TO
+
+SSL, PKCS #1 v2.0
+
+=head1 PATENTS
+
+RSA was covered by a US patent which expired in September 2000.
+
+=head1 SEE ALSO
+
+L<rsa(1)|rsa(1)>, L<bn(3)|bn(3)>, L<dsa(3)|dsa(3)>, L<dh(3)|dh(3)>,
+L<rand(3)|rand(3)>, L<engine(3)|engine(3)>, L<RSA_new(3)|RSA_new(3)>,
+L<RSA_public_encrypt(3)|RSA_public_encrypt(3)>,
+L<RSA_sign(3)|RSA_sign(3)>, L<RSA_size(3)|RSA_size(3)>,
+L<RSA_generate_key(3)|RSA_generate_key(3)>,
+L<RSA_check_key(3)|RSA_check_key(3)>,
+L<RSA_blinding_on(3)|RSA_blinding_on(3)>,
+L<RSA_set_method(3)|RSA_set_method(3)>, L<RSA_print(3)|RSA_print(3)>,
+L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>,
+L<RSA_private_encrypt(3)|RSA_private_encrypt(3)>,
+L<RSA_sign_ASN1_OCTET_STRING(3)|RSA_sign_ASN1_OCTET_STRING(3)>,
+L<RSA_padding_add_PKCS1_type_1(3)|RSA_padding_add_PKCS1_type_1(3)> 
+
+=cut
diff --git a/openssl/doc/crypto/sha.pod b/openssl/doc/crypto/sha.pod
new file mode 100644
index 0000000..94ab7bc
--- /dev/null
+++ b/openssl/doc/crypto/sha.pod
@@ -0,0 +1,70 @@
+=pod
+
+=head1 NAME
+
+SHA1, SHA1_Init, SHA1_Update, SHA1_Final - Secure Hash Algorithm
+
+=head1 SYNOPSIS
+
+ #include <openssl/sha.h>
+
+ unsigned char *SHA1(const unsigned char *d, unsigned long n,
+                  unsigned char *md);
+
+ int SHA1_Init(SHA_CTX *c);
+ int SHA1_Update(SHA_CTX *c, const void *data,
+                  unsigned long len);
+ int SHA1_Final(unsigned char *md, SHA_CTX *c);
+
+=head1 DESCRIPTION
+
+SHA-1 (Secure Hash Algorithm) is a cryptographic hash function with a
+160 bit output.
+
+SHA1() computes the SHA-1 message digest of the B<n>
+bytes at B<d> and places it in B<md> (which must have space for
+SHA_DIGEST_LENGTH == 20 bytes of output). If B<md> is NULL, the digest
+is placed in a static array.
+
+The following functions may be used if the message is not completely
+stored in memory:
+
+SHA1_Init() initializes a B<SHA_CTX> structure.
+
+SHA1_Update() can be called repeatedly with chunks of the message to
+be hashed (B<len> bytes at B<data>).
+
+SHA1_Final() places the message digest in B<md>, which must have space
+for SHA_DIGEST_LENGTH == 20 bytes of output, and erases the B<SHA_CTX>.
+
+Applications should use the higher level functions
+L<EVP_DigestInit(3)|EVP_DigestInit(3)>
+etc. instead of calling the hash functions directly.
+
+The predecessor of SHA-1, SHA, is also implemented, but it should be
+used only when backward compatibility is required.
+
+=head1 RETURN VALUES
+
+SHA1() returns a pointer to the hash value. 
+
+SHA1_Init(), SHA1_Update() and SHA1_Final() return 1 for success, 0 otherwise.
+
+=head1 CONFORMING TO
+
+SHA: US Federal Information Processing Standard FIPS PUB 180 (Secure Hash
+Standard),
+SHA-1: US Federal Information Processing Standard FIPS PUB 180-1 (Secure Hash
+Standard),
+ANSI X9.30
+
+=head1 SEE ALSO
+
+L<ripemd(3)|ripemd(3)>, L<hmac(3)|hmac(3)>, L<EVP_DigestInit(3)|EVP_DigestInit(3)>
+
+=head1 HISTORY
+
+SHA1(), SHA1_Init(), SHA1_Update() and SHA1_Final() are available in all
+versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/openssl/doc/crypto/threads.pod b/openssl/doc/crypto/threads.pod
new file mode 100644
index 0000000..dc0e939
--- /dev/null
+++ b/openssl/doc/crypto/threads.pod
@@ -0,0 +1,210 @@
+=pod
+
+=head1 NAME
+
+CRYPTO_THREADID_set_callback, CRYPTO_THREADID_get_callback,
+CRYPTO_THREADID_current, CRYPTO_THREADID_cmp, CRYPTO_THREADID_cpy,
+CRYPTO_THREADID_hash, CRYPTO_set_locking_callback, CRYPTO_num_locks,
+CRYPTO_set_dynlock_create_callback, CRYPTO_set_dynlock_lock_callback,
+CRYPTO_set_dynlock_destroy_callback, CRYPTO_get_new_dynlockid,
+CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support
+
+=head1 SYNOPSIS
+
+ #include <openssl/crypto.h>
+
+ /* Don't use this structure directly. */
+ typedef struct crypto_threadid_st
+         {
+         void *ptr;
+         unsigned long val;
+         } CRYPTO_THREADID;
+ /* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
+ void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
+ void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
+ int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *));
+ void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *);
+ void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
+ int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a,
+                         const CRYPTO_THREADID *b);
+ void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest,
+                          const CRYPTO_THREADID *src);
+ unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id);
+
+ int CRYPTO_num_locks(void);
+
+ /* struct CRYPTO_dynlock_value needs to be defined by the user */
+ struct CRYPTO_dynlock_value;
+
+ void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *
+	(*dyn_create_function)(char *file, int line));
+ void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)
+	(int mode, struct CRYPTO_dynlock_value *l,
+	const char *file, int line));
+ void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)
+	(struct CRYPTO_dynlock_value *l, const char *file, int line));
+
+ int CRYPTO_get_new_dynlockid(void);
+
+ void CRYPTO_destroy_dynlockid(int i);
+
+ void CRYPTO_lock(int mode, int n, const char *file, int line);
+
+ #define CRYPTO_w_lock(type)	\
+	CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
+ #define CRYPTO_w_unlock(type)	\
+	CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
+ #define CRYPTO_r_lock(type)	\
+	CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__)
+ #define CRYPTO_r_unlock(type)	\
+	CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__)
+ #define CRYPTO_add(addr,amount,type)	\
+	CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__)
+
+=head1 DESCRIPTION
+
+OpenSSL can safely be used in multi-threaded applications provided
+that at least two callback functions are set, locking_function and
+threadid_func.
+
+locking_function(int mode, int n, const char *file, int line) is
+needed to perform locking on shared data structures. 
+(Note that OpenSSL uses a number of global data structures that
+will be implicitly shared whenever multiple threads use OpenSSL.)
+Multi-threaded applications will crash at random if it is not set.
+
+locking_function() must be able to handle up to CRYPTO_num_locks()
+different mutex locks. It sets the B<n>-th lock if B<mode> &
+B<CRYPTO_LOCK>, and releases it otherwise.
+
+B<file> and B<line> are the file number of the function setting the
+lock. They can be useful for debugging.
+
+threadid_func(CRYPTO_THREADID *id) is needed to record the currently-executing
+thread's identifier into B<id>. The implementation of this callback should not
+fill in B<id> directly, but should use CRYPTO_THREADID_set_numeric() if thread
+IDs are numeric, or CRYPTO_THREADID_set_pointer() if they are pointer-based.
+If the application does not register such a callback using
+CRYPTO_THREADID_set_callback(), then a default implementation is used - on
+Windows and BeOS this uses the system's default thread identifying APIs, and on
+all other platforms it uses the address of B<errno>. The latter is satisfactory
+for thread-safety if and only if the platform has a thread-local error number
+facility.
+
+Once threadid_func() is registered, or if the built-in default implementation is
+to be used;
+
+=over 4
+
+=item *
+CRYPTO_THREADID_current() records the currently-executing thread ID into the
+given B<id> object.
+
+=item *
+CRYPTO_THREADID_cmp() compares two thread IDs (returning zero for equality, ie.
+the same semantics as memcmp()).
+
+=item *
+CRYPTO_THREADID_cpy() duplicates a thread ID value,
+
+=item *
+CRYPTO_THREADID_hash() returns a numeric value usable as a hash-table key. This
+is usually the exact numeric or pointer-based thread ID used internally, however
+this also handles the unusual case where pointers are larger than 'long'
+variables and the platform's thread IDs are pointer-based - in this case, mixing
+is done to attempt to produce a unique numeric value even though it is not as
+wide as the platform's true thread IDs.
+
+=back
+
+Additionally, OpenSSL supports dynamic locks, and sometimes, some parts
+of OpenSSL need it for better performance.  To enable this, the following
+is required:
+
+=over 4
+
+=item *
+Three additional callback function, dyn_create_function, dyn_lock_function
+and dyn_destroy_function.
+
+=item *
+A structure defined with the data that each lock needs to handle.
+
+=back
+
+struct CRYPTO_dynlock_value has to be defined to contain whatever structure
+is needed to handle locks.
+
+dyn_create_function(const char *file, int line) is needed to create a
+lock.  Multi-threaded applications might crash at random if it is not set.
+
+dyn_lock_function(int mode, CRYPTO_dynlock *l, const char *file, int line)
+is needed to perform locking off dynamic lock numbered n. Multi-threaded
+applications might crash at random if it is not set.
+
+dyn_destroy_function(CRYPTO_dynlock *l, const char *file, int line) is
+needed to destroy the lock l. Multi-threaded applications might crash at
+random if it is not set.
+
+CRYPTO_get_new_dynlockid() is used to create locks.  It will call
+dyn_create_function for the actual creation.
+
+CRYPTO_destroy_dynlockid() is used to destroy locks.  It will call
+dyn_destroy_function for the actual destruction.
+
+CRYPTO_lock() is used to lock and unlock the locks.  mode is a bitfield
+describing what should be done with the lock.  n is the number of the
+lock as returned from CRYPTO_get_new_dynlockid().  mode can be combined
+from the following values.  These values are pairwise exclusive, with
+undefined behaviour if misused (for example, CRYPTO_READ and CRYPTO_WRITE
+should not be used together):
+
+	CRYPTO_LOCK	0x01
+	CRYPTO_UNLOCK	0x02
+	CRYPTO_READ	0x04
+	CRYPTO_WRITE	0x08
+
+=head1 RETURN VALUES
+
+CRYPTO_num_locks() returns the required number of locks.
+
+CRYPTO_get_new_dynlockid() returns the index to the newly created lock.
+
+The other functions return no values.
+
+=head1 NOTES
+
+You can find out if OpenSSL was configured with thread support:
+
+ #define OPENSSL_THREAD_DEFINES
+ #include <openssl/opensslconf.h>
+ #if defined(OPENSSL_THREADS)
+   // thread support enabled
+ #else
+   // no thread support
+ #endif
+
+Also, dynamic locks are currently not used internally by OpenSSL, but
+may do so in the future.
+
+=head1 EXAMPLES
+
+B<crypto/threads/mttest.c> shows examples of the callback functions on
+Solaris, Irix and Win32.
+
+=head1 HISTORY
+
+CRYPTO_set_locking_callback() is
+available in all versions of SSLeay and OpenSSL.
+CRYPTO_num_locks() was added in OpenSSL 0.9.4.
+All functions dealing with dynamic locks were added in OpenSSL 0.9.5b-dev.
+B<CRYPTO_THREADID> and associated functions were introduced in OpenSSL 1.0.0
+to replace (actually, deprecate) the previous CRYPTO_set_id_callback(),
+CRYPTO_get_id_callback(), and CRYPTO_thread_id() functions which assumed
+thread IDs to always be represented by 'unsigned long'.
+
+=head1 SEE ALSO
+
+L<crypto(3)|crypto(3)>
+
+=cut
diff --git a/openssl/doc/crypto/ui.pod b/openssl/doc/crypto/ui.pod
new file mode 100644
index 0000000..6df68d6
--- /dev/null
+++ b/openssl/doc/crypto/ui.pod
@@ -0,0 +1,194 @@
+=pod
+
+=head1 NAME
+
+UI_new, UI_new_method, UI_free, UI_add_input_string, UI_dup_input_string,
+UI_add_verify_string, UI_dup_verify_string, UI_add_input_boolean,
+UI_dup_input_boolean, UI_add_info_string, UI_dup_info_string,
+UI_add_error_string, UI_dup_error_string, UI_construct_prompt,
+UI_add_user_data, UI_get0_user_data, UI_get0_result, UI_process,
+UI_ctrl, UI_set_default_method, UI_get_default_method, UI_get_method,
+UI_set_method, UI_OpenSSL, ERR_load_UI_strings - New User Interface
+
+=head1 SYNOPSIS
+
+ #include <openssl/ui.h>
+
+ typedef struct ui_st UI;
+ typedef struct ui_method_st UI_METHOD;
+
+ UI *UI_new(void);
+ UI *UI_new_method(const UI_METHOD *method);
+ void UI_free(UI *ui);
+
+ int UI_add_input_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize);
+ int UI_dup_input_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize);
+ int UI_add_verify_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize, const char *test_buf);
+ int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize, const char *test_buf);
+ int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+	const char *ok_chars, const char *cancel_chars,
+	int flags, char *result_buf);
+ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+	const char *ok_chars, const char *cancel_chars,
+	int flags, char *result_buf);
+ int UI_add_info_string(UI *ui, const char *text);
+ int UI_dup_info_string(UI *ui, const char *text);
+ int UI_add_error_string(UI *ui, const char *text);
+ int UI_dup_error_string(UI *ui, const char *text);
+
+ /* These are the possible flags.  They can be or'ed together. */
+ #define UI_INPUT_FLAG_ECHO		0x01
+ #define UI_INPUT_FLAG_DEFAULT_PWD	0x02
+
+ char *UI_construct_prompt(UI *ui_method,
+	const char *object_desc, const char *object_name);
+
+ void *UI_add_user_data(UI *ui, void *user_data);
+ void *UI_get0_user_data(UI *ui);
+
+ const char *UI_get0_result(UI *ui, int i);
+
+ int UI_process(UI *ui);
+
+ int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f)());
+ #define UI_CTRL_PRINT_ERRORS		1
+ #define UI_CTRL_IS_REDOABLE		2
+
+ void UI_set_default_method(const UI_METHOD *meth);
+ const UI_METHOD *UI_get_default_method(void);
+ const UI_METHOD *UI_get_method(UI *ui);
+ const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth);
+
+ UI_METHOD *UI_OpenSSL(void);
+
+=head1 DESCRIPTION
+
+UI stands for User Interface, and is general purpose set of routines to
+prompt the user for text-based information.  Through user-written methods
+(see L<ui_create(3)|ui_create(3)>), prompting can be done in any way
+imaginable, be it plain text prompting, through dialog boxes or from a
+cell phone.
+
+All the functions work through a context of the type UI.  This context
+contains all the information needed to prompt correctly as well as a
+reference to a UI_METHOD, which is an ordered vector of functions that
+carry out the actual prompting.
+
+The first thing to do is to create a UI with UI_new() or UI_new_method(),
+then add information to it with the UI_add or UI_dup functions.  Also,
+user-defined random data can be passed down to the underlying method
+through calls to UI_add_user_data.  The default UI method doesn't care
+about these data, but other methods might.  Finally, use UI_process()
+to actually perform the prompting and UI_get0_result() to find the result
+to the prompt.
+
+A UI can contain more than one prompt, which are performed in the given
+sequence.  Each prompt gets an index number which is returned by the
+UI_add and UI_dup functions, and has to be used to get the corresponding
+result with UI_get0_result().
+
+The functions are as follows:
+
+UI_new() creates a new UI using the default UI method.  When done with
+this UI, it should be freed using UI_free().
+
+UI_new_method() creates a new UI using the given UI method.  When done with
+this UI, it should be freed using UI_free().
+
+UI_OpenSSL() returns the built-in UI method (note: not the default one,
+since the default can be changed.  See further on).  This method is the
+most machine/OS dependent part of OpenSSL and normally generates the
+most problems when porting.
+
+UI_free() removes a UI from memory, along with all other pieces of memory
+that's connected to it, like duplicated input strings, results and others.
+
+UI_add_input_string() and UI_add_verify_string() add a prompt to the UI,
+as well as flags and a result buffer and the desired minimum and maximum
+sizes of the result.  The given information is used to prompt for
+information, for example a password, and to verify a password (i.e. having
+the user enter it twice and check that the same string was entered twice).
+UI_add_verify_string() takes and extra argument that should be a pointer
+to the result buffer of the input string that it's supposed to verify, or
+verification will fail.
+
+UI_add_input_boolean() adds a prompt to the UI that's supposed to be answered
+in a boolean way, with a single character for yes and a different character
+for no.  A set of characters that can be used to cancel the prompt is given
+as well.  The prompt itself is really divided in two, one part being the
+descriptive text (given through the I<prompt> argument) and one describing
+the possible answers (given through the I<action_desc> argument).
+
+UI_add_info_string() and UI_add_error_string() add strings that are shown at
+the same time as the prompt for extra information or to show an error string.
+The difference between the two is only conceptual.  With the builtin method,
+there's no technical difference between them.  Other methods may make a
+difference between them, however.
+
+The flags currently supported are UI_INPUT_FLAG_ECHO, which is relevant for
+UI_add_input_string() and will have the users response be echoed (when
+prompting for a password, this flag should obviously not be used, and
+UI_INPUT_FLAG_DEFAULT_PWD, which means that a default password of some
+sort will be used (completely depending on the application and the UI
+method).
+
+UI_dup_input_string(), UI_dup_verify_string(), UI_dup_input_boolean(),
+UI_dup_info_string() and UI_dup_error_string() are basically the same
+as their UI_add counterparts, except that they make their own copies
+of all strings.
+
+UI_construct_prompt() is a helper function that can be used to create
+a prompt from two pieces of information: an description and a name.
+The default constructor (if there is none provided by the method used)
+creates a string "Enter I<description> for I<name>:".  With the
+description "pass phrase" and the file name "foo.key", that becomes
+"Enter pass phrase for foo.key:".  Other methods may create whatever
+string and may include encodings that will be processed by the other
+method functions.
+
+UI_add_user_data() adds a piece of memory for the method to use at any
+time.  The builtin UI method doesn't care about this info.  Note that several
+calls to this function doesn't add data, it replaces the previous blob
+with the one given as argument.
+
+UI_get0_user_data() retrieves the data that has last been given to the
+UI with UI_add_user_data().
+
+UI_get0_result() returns a pointer to the result buffer associated with
+the information indexed by I<i>.
+
+UI_process() goes through the information given so far, does all the printing
+and prompting and returns.
+
+UI_ctrl() adds extra control for the application author.  For now, it
+understands two commands: UI_CTRL_PRINT_ERRORS, which makes UI_process()
+print the OpenSSL error stack as part of processing the UI, and
+UI_CTRL_IS_REDOABLE, which returns a flag saying if the used UI can
+be used again or not.
+
+UI_set_default_method() changes the default UI method to the one given.
+
+UI_get_default_method() returns a pointer to the current default UI method.
+
+UI_get_method() returns the UI method associated with a given UI.
+
+UI_set_method() changes the UI method associated with a given UI.
+
+=head1 SEE ALSO
+
+L<ui_create(3)|ui_create(3)>, L<ui_compat(3)|ui_compat(3)>
+
+=head1 HISTORY
+
+The UI section was first introduced in OpenSSL 0.9.7.
+
+=head1 AUTHOR
+
+Richard Levitte (richard@levitte.org) for the OpenSSL project
+(http://www.openssl.org).
+
+=cut
diff --git a/openssl/doc/crypto/ui_compat.pod b/openssl/doc/crypto/ui_compat.pod
new file mode 100644
index 0000000..adf2ae5
--- /dev/null
+++ b/openssl/doc/crypto/ui_compat.pod
@@ -0,0 +1,57 @@
+=pod
+
+=head1 NAME
+
+des_read_password, des_read_2passwords, des_read_pw_string, des_read_pw -
+Compatibility user interface functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/des_old.h>
+
+ int des_read_password(DES_cblock *key,const char *prompt,int verify);
+ int des_read_2passwords(DES_cblock *key1,DES_cblock *key2,
+ 	const char *prompt,int verify);
+
+ int des_read_pw_string(char *buf,int length,const char *prompt,int verify);
+ int des_read_pw(char *buf,char *buff,int size,const char *prompt,int verify);
+
+=head1 DESCRIPTION
+
+The DES library contained a few routines to prompt for passwords.  These
+aren't necessarely dependent on DES, and have therefore become part of the
+UI compatibility library.
+
+des_read_pw() writes the string specified by I<prompt> to standard output
+turns echo off and reads an input string from the terminal.  The string is
+returned in I<buf>, which must have spac for at least I<size> bytes.
+If I<verify> is set, the user is asked for the password twice and unless
+the two copies match, an error is returned.  The second password is stored
+in I<buff>, which must therefore also be at least I<size> bytes.  A return
+code of -1 indicates a system error, 1 failure due to use interaction, and
+0 is success.  All other functions described here use des_read_pw() to do
+the work.
+
+des_read_pw_string() is a variant of des_read_pw() that provides a buffer
+for you if I<verify> is set.
+
+des_read_password() calls des_read_pw() and converts the password to a
+DES key by calling DES_string_to_key(); des_read_2password() operates in
+the same way as des_read_password() except that it generates two keys
+by using the DES_string_to_2key() function.
+
+=head1 NOTES
+
+des_read_pw_string() is available in the MIT Kerberos library as well, and
+is also available under the name EVP_read_pw_string().
+
+=head1 SEE ALSO
+
+L<ui(3)|ui(3)>, L<ui_create(3)|ui_create(3)>
+
+=head1 AUTHOR
+
+Richard Levitte (richard@levitte.org) for the OpenSSL project
+(http://www.openssl.org).
+
+=cut
diff --git a/openssl/doc/crypto/x509.pod b/openssl/doc/crypto/x509.pod
new file mode 100644
index 0000000..f9e58e0
--- /dev/null
+++ b/openssl/doc/crypto/x509.pod
@@ -0,0 +1,64 @@
+=pod
+
+=head1 NAME
+
+x509 - X.509 certificate handling
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509.h>
+
+=head1 DESCRIPTION
+
+A X.509 certificate is a structured grouping of information about
+an individual, a device, or anything one can imagine.  A X.509 CRL
+(certificate revocation list) is a tool to help determine if a
+certificate is still valid.  The exact definition of those can be
+found in the X.509 document from ITU-T, or in RFC3280 from PKIX.
+In OpenSSL, the type X509 is used to express such a certificate, and
+the type X509_CRL is used to express a CRL.
+
+A related structure is a certificate request, defined in PKCS#10 from
+RSA Security, Inc, also reflected in RFC2896.  In OpenSSL, the type
+X509_REQ is used to express such a certificate request.
+
+To handle some complex parts of a certificate, there are the types
+X509_NAME (to express a certificate name), X509_ATTRIBUTE (to express
+a certificate attributes), X509_EXTENSION (to express a certificate
+extension) and a few more.
+
+Finally, there's the supertype X509_INFO, which can contain a CRL, a
+certificate and a corresponding private key.
+
+B<X509_>I<...>, B<d2i_X509_>I<...> and B<i2d_X509_>I<...> handle X.509
+certificates, with some exceptions, shown below.
+
+B<X509_CRL_>I<...>, B<d2i_X509_CRL_>I<...> and B<i2d_X509_CRL_>I<...>
+handle X.509 CRLs.
+
+B<X509_REQ_>I<...>, B<d2i_X509_REQ_>I<...> and B<i2d_X509_REQ_>I<...>
+handle PKCS#10 certificate requests.
+
+B<X509_NAME_>I<...> handle certificate names.
+
+B<X509_ATTRIBUTE_>I<...> handle certificate attributes.
+
+B<X509_EXTENSION_>I<...> handle certificate extensions.
+
+=head1 SEE ALSO
+
+L<X509_NAME_ENTRY_get_object(3)|X509_NAME_ENTRY_get_object(3)>,
+L<X509_NAME_add_entry_by_txt(3)|X509_NAME_add_entry_by_txt(3)>,
+L<X509_NAME_add_entry_by_NID(3)|X509_NAME_add_entry_by_NID(3)>,
+L<X509_NAME_print_ex(3)|X509_NAME_print_ex(3)>,
+L<X509_NAME_new(3)|X509_NAME_new(3)>,
+L<d2i_X509(3)|d2i_X509(3)>,
+L<d2i_X509_ALGOR(3)|d2i_X509_ALGOR(3)>,
+L<d2i_X509_CRL(3)|d2i_X509_CRL(3)>,
+L<d2i_X509_NAME(3)|d2i_X509_NAME(3)>,
+L<d2i_X509_REQ(3)|d2i_X509_REQ(3)>,
+L<d2i_X509_SIG(3)|d2i_X509_SIG(3)>,
+L<crypto(3)|crypto(3)>,
+L<x509v3(3)|x509v3(3)>
+
+=cut
diff --git a/openssl/doc/fingerprints.txt b/openssl/doc/fingerprints.txt
new file mode 100644
index 0000000..7d05a85
--- /dev/null
+++ b/openssl/doc/fingerprints.txt
@@ -0,0 +1,57 @@
+                              Fingerprints
+
+OpenSSL releases are signed with PGP/GnuPG keys.  You can find the
+signatures in separate files in the same location you find the
+distributions themselves.  The normal file name is the same as the
+distribution file, with '.asc' added.  For example, the signature for
+the distribution of OpenSSL 0.9.7f, openssl-0.9.7f.tar.gz, is found in
+the file openssl-0.9.7f.tar.gz.asc.
+
+The following is the list of fingerprints for the keys that are
+currently in use (have been used since summer 2004) to sign OpenSSL
+distributions:
+
+pub   1024D/F709453B 2003-10-20
+      Key fingerprint = C4CA B749 C34F 7F4C C04F  DAC9 A7AF 9E78 F709 453B
+uid                  Richard Levitte <richard@levitte.org>
+uid                  Richard Levitte <levitte@openssl.org>
+uid                  Richard Levitte <levitte@lp.se>
+
+pub   2048R/F295C759 1998-12-13
+      Key fingerprint = D0 5D 8C 61 6E 27 E6 60  41 EC B1 B8 D5 7E E5 97
+uid                  Dr S N Henson <shenson@drh-consultancy.demon.co.uk>
+
+pub   1024R/49A563D9 1997-02-24
+      Key fingerprint = 7B 79 19 FA 71 6B 87 25  0E 77 21 E5 52 D9 83 BF
+uid                  Mark Cox <mjc@redhat.com>
+uid                  Mark Cox <mark@awe.com>
+uid                  Mark Cox <mjc@apache.org>
+
+pub   1024R/26BB437D 1997-04-28
+      Key fingerprint = 00 C9 21 8E D1 AB 70 37  DD 67 A2 3A 0A 6F 8D A5
+uid                  Ralf S. Engelschall <rse@engelschall.com>
+
+pub   1024R/9C58A66D 1997-04-03
+      Key fingerprint = 13 D0 B8 9D 37 30 C3 ED  AC 9C 24 7D 45 8C 17 67
+uid                  jaenicke@openssl.org
+uid                  Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE>
+
+pub   1024D/2118CF83 1998-07-13
+      Key fingerprint = 7656 55DE 62E3 96FF 2587  EB6C 4F6D E156 2118 CF83
+uid                  Ben Laurie <ben@thebunker.net>
+uid                  Ben Laurie <ben@cryptix.org>
+uid                  Ben Laurie <ben@algroup.co.uk>
+sub   4096g/1F5143E7 1998-07-13
+
+pub   1024R/5A6A9B85 1994-03-22
+      Key fingerprint = C7 AC 7E AD 56 6A 65 EC  F6 16 66 83 7E 86 68 28
+uid                  Bodo Moeller <2005@bmoeller.de>
+uid                  Bodo Moeller <2003@bmoeller.de>
+uid                  Bodo Moeller <2004@bmoeller.de>
+uid                  Bodo Moeller <bmoeller@acm.org>
+uid                  Bodo Moeller <bodo@openssl.org>
+uid                  Bodo Moeller <bm@ulf.mali.sub.org>
+uid                  Bodo Moeller <3moeller@informatik.uni-hamburg.de>
+uid                  Bodo Moeller <Bodo_Moeller@public.uni-hamburg.de>
+uid                  Bodo Moeller <3moeller@rzdspc5.informatik.uni-hamburg.de>
+
diff --git a/openssl/doc/openssl-shared.txt b/openssl/doc/openssl-shared.txt
new file mode 100644
index 0000000..5cf84a0
--- /dev/null
+++ b/openssl/doc/openssl-shared.txt
@@ -0,0 +1,32 @@
+The OpenSSL  shared libraries are often installed in a directory like
+/usr/local/ssl/lib.
+
+If this directory is not in a standard system path for dynamic/shared
+libraries, then you will have problems linking and executing
+applications that use OpenSSL libraries UNLESS:
+
+* you link with static (archive) libraries.  If you are truly
+  paranoid about security, you should use static libraries.
+* you use the GNU libtool code during linking
+  (http://www.gnu.org/software/libtool/libtool.html)
+* you use pkg-config during linking (this requires that
+  PKG_CONFIG_PATH includes the path to the OpenSSL shared
+  library directory), and make use of -R or -rpath.
+  (http://www.freedesktop.org/software/pkgconfig/)
+* you specify the system-wide link path via a command such
+  as crle(1) on Solaris systems.
+* you add the OpenSSL shared library directory to /etc/ld.so.conf
+  and run ldconfig(8) on Linux systems.
+* you define the LD_LIBRARY_PATH, LIBPATH, SHLIB_PATH (HP),
+  DYLD_LIBRARY_PATH (MacOS X) or PATH (Cygwin and DJGPP)
+  environment variable and add the OpenSSL shared library
+  directory to it.
+
+One common tool to check the dynamic dependencies of an executable
+or dynamic library is ldd(1) on most UNIX systems.
+
+See any operating system documentation and manpages about shared
+libraries for your version of UNIX.  The following manpages may be
+helpful: ld(1), ld.so(1), ld.so.1(1) [Solaris], dld.sl(1) [HP],
+ldd(1), crle(1) [Solaris], pldd(1) [Solaris], ldconfig(8) [Linux],
+chatr(1) [HP].
diff --git a/openssl/doc/openssl.txt b/openssl/doc/openssl.txt
new file mode 100644
index 0000000..f8817b0
--- /dev/null
+++ b/openssl/doc/openssl.txt
@@ -0,0 +1,1254 @@
+
+This is some preliminary documentation for OpenSSL.
+
+Contents:
+
+ OpenSSL X509V3 extension configuration
+ X509V3 Extension code: programmers guide
+ PKCS#12 Library
+
+
+==============================================================================
+               OpenSSL X509V3 extension configuration
+==============================================================================
+
+OpenSSL X509V3 extension configuration: preliminary documentation.
+
+INTRODUCTION.
+
+For OpenSSL 0.9.2 the extension code has be considerably enhanced. It is now
+possible to add and print out common X509 V3 certificate and CRL extensions.
+
+BEGINNERS NOTE
+
+For most simple applications you don't need to know too much about extensions:
+the default openssl.cnf values will usually do sensible things.
+
+If you want to know more you can initially quickly look through the sections
+describing how the standard OpenSSL utilities display and add extensions and
+then the list of supported extensions.
+
+For more technical information about the meaning of extensions see:
+
+http://www.imc.org/ietf-pkix/
+http://home.netscape.com/eng/security/certs.html
+
+PRINTING EXTENSIONS.
+
+Extension values are automatically printed out for supported extensions.
+
+openssl x509 -in cert.pem -text
+openssl crl -in crl.pem -text
+
+will give information in the extension printout, for example:
+
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:TRUE
+            X509v3 Subject Key Identifier: 
+                73:FE:F7:59:A7:E1:26:84:44:D6:44:36:EE:79:1A:95:7C:B1:4B:15
+            X509v3 Authority Key Identifier: 
+                keyid:73:FE:F7:59:A7:E1:26:84:44:D6:44:36:EE:79:1A:95:7C:B1:4B:15, DirName:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/Email=email@1.address/Email=email@2.address, serial:00
+            X509v3 Key Usage: 
+                Certificate Sign, CRL Sign
+            X509v3 Subject Alternative Name: 
+                email:email@1.address, email:email@2.address
+
+CONFIGURATION FILES.
+
+The OpenSSL utilities 'ca' and 'req' can now have extension sections listing
+which certificate extensions to include. In each case a line:
+
+x509_extensions = extension_section
+
+indicates which section contains the extensions. In the case of 'req' the
+extension section is used when the -x509 option is present to create a
+self signed root certificate.
+
+The 'x509' utility also supports extensions when it signs a certificate.
+The -extfile option is used to set the configuration file containing the
+extensions. In this case a line with:
+
+extensions = extension_section
+
+in the nameless (default) section is used. If no such line is included then
+it uses the default section.
+
+You can also add extensions to CRLs: a line
+
+crl_extensions = crl_extension_section
+
+will include extensions when the -gencrl option is used with the 'ca' utility.
+You can add any extension to a CRL but of the supported extensions only
+issuerAltName and authorityKeyIdentifier make any real sense. Note: these are
+CRL extensions NOT CRL *entry* extensions which cannot currently be generated.
+CRL entry extensions can be displayed.
+
+NB. At this time Netscape Communicator rejects V2 CRLs: to get an old V1 CRL
+you should not include a crl_extensions line in the configuration file.
+
+As with all configuration files you can use the inbuilt environment expansion
+to allow the values to be passed in the environment. Therefore if you have
+several extension sections used for different purposes you can have a line:
+
+x509_extensions = $ENV::ENV_EXT
+
+and set the ENV_EXT environment variable before calling the relevant utility.
+
+EXTENSION SYNTAX.
+
+Extensions have the basic form:
+
+extension_name=[critical,] extension_options
+
+the use of the critical option makes the extension critical. Extreme caution
+should be made when using the critical flag. If an extension is marked
+as critical then any client that does not understand the extension should
+reject it as invalid. Some broken software will reject certificates which
+have *any* critical extensions (these violates PKIX but we have to live
+with it).
+
+There are three main types of extension: string extensions, multi-valued
+extensions, and raw extensions.
+
+String extensions simply have a string which contains either the value itself
+or how it is obtained.
+
+For example:
+
+nsComment="This is a Comment"
+
+Multi-valued extensions have a short form and a long form. The short form
+is a list of names and values:
+
+basicConstraints=critical,CA:true,pathlen:1
+
+The long form allows the values to be placed in a separate section:
+
+basicConstraints=critical,@bs_section
+
+[bs_section]
+
+CA=true
+pathlen=1
+
+Both forms are equivalent. However it should be noted that in some cases the
+same name can appear multiple times, for example,
+
+subjectAltName=email:steve@here,email:steve@there
+
+in this case an equivalent long form is:
+
+subjectAltName=@alt_section
+
+[alt_section]
+
+email.1=steve@here
+email.2=steve@there
+
+This is because the configuration file code cannot handle the same name
+occurring twice in the same section.
+
+The syntax of raw extensions is governed by the extension code: it can
+for example contain data in multiple sections. The correct syntax to
+use is defined by the extension code itself: check out the certificate
+policies extension for an example.
+
+There are two ways to encode arbitrary extensions.
+
+The first way is to use the word ASN1 followed by the extension content
+using the same syntax as ASN1_generate_nconf(). For example:
+
+1.2.3.4=critical,ASN1:UTF8String:Some random data
+
+1.2.3.4=ASN1:SEQUENCE:seq_sect
+
+[seq_sect]
+
+field1 = UTF8:field1
+field2 = UTF8:field2
+
+It is also possible to use the word DER to include arbitrary data in any
+extension.
+
+1.2.3.4=critical,DER:01:02:03:04
+1.2.3.4=DER:01020304
+
+The value following DER is a hex dump of the DER encoding of the extension
+Any extension can be placed in this form to override the default behaviour.
+For example:
+
+basicConstraints=critical,DER:00:01:02:03
+
+WARNING: DER should be used with caution. It is possible to create totally
+invalid extensions unless care is taken.
+
+CURRENTLY SUPPORTED EXTENSIONS.
+
+If you aren't sure about extensions then they can be largely ignored: its only
+when you want to do things like restrict certificate usage when you need to
+worry about them. 
+
+The only extension that a beginner might want to look at is Basic Constraints.
+If in addition you want to try Netscape object signing the you should also
+look at Netscape Certificate Type.
+
+Literal String extensions.
+
+In each case the 'value' of the extension is placed directly in the
+extension. Currently supported extensions in this category are: nsBaseUrl,
+nsRevocationUrl, nsCaRevocationUrl, nsRenewalUrl, nsCaPolicyUrl,
+nsSslServerName and nsComment.
+
+For example:
+
+nsComment="This is a test comment"
+
+Bit Strings.
+
+Bit string extensions just consist of a list of supported bits, currently
+two extensions are in this category: PKIX keyUsage and the Netscape specific
+nsCertType.
+
+nsCertType (netscape certificate type) takes the flags: client, server, email,
+objsign, reserved, sslCA, emailCA, objCA.
+
+keyUsage (PKIX key usage) takes the flags: digitalSignature, nonRepudiation,
+keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign,
+encipherOnly, decipherOnly.
+
+For example:
+
+nsCertType=server
+
+keyUsage=digitalSignature, nonRepudiation
+
+Hints on Netscape Certificate Type.
+
+Other than Basic Constraints this is the only extension a beginner might
+want to use, if you want to try Netscape object signing, otherwise it can
+be ignored.
+
+If you want a certificate that can be used just for object signing then:
+
+nsCertType=objsign
+
+will do the job. If you want to use it as a normal end user and server
+certificate as well then
+
+nsCertType=objsign,email,server
+
+is more appropriate. You cannot use a self signed certificate for object
+signing (well Netscape signtool can but it cheats!) so you need to create
+a CA certificate and sign an end user certificate with it.
+
+Side note: If you want to conform to the Netscape specifications then you
+should really also set:
+
+nsCertType=objCA
+
+in the *CA* certificate for just an object signing CA and
+
+nsCertType=objCA,emailCA,sslCA
+
+for everything. Current Netscape software doesn't enforce this so it can
+be omitted.
+
+Basic Constraints.
+
+This is generally the only extension you need to worry about for simple
+applications. If you want your certificate to be usable as a CA certificate
+(in addition to an end user certificate) then you set this to:
+
+basicConstraints=CA:TRUE
+
+if you want to be certain the certificate cannot be used as a CA then do:
+
+basicConstraints=CA:FALSE
+
+The rest of this section describes more advanced usage.
+
+Basic constraints is a multi-valued extension that supports a CA and an
+optional pathlen option. The CA option takes the values true and false and
+pathlen takes an integer. Note if the CA option is false the pathlen option
+should be omitted. 
+
+The pathlen parameter indicates the maximum number of CAs that can appear
+below this one in a chain. So if you have a CA with a pathlen of zero it can
+only be used to sign end user certificates and not further CAs. This all
+assumes that the software correctly interprets this extension of course.
+
+Examples:
+
+basicConstraints=CA:TRUE
+basicConstraints=critical,CA:TRUE, pathlen:0
+
+NOTE: for a CA to be considered valid it must have the CA option set to
+TRUE. An end user certificate MUST NOT have the CA value set to true.
+According to PKIX recommendations it should exclude the extension entirely,
+however some software may require CA set to FALSE for end entity certificates.
+
+Extended Key Usage.
+
+This extensions consists of a list of usages.
+
+These can either be object short names of the dotted numerical form of OIDs.
+While any OID can be used only certain values make sense. In particular the
+following PKIX, NS and MS values are meaningful:
+
+Value			Meaning
+-----			-------
+serverAuth		SSL/TLS Web Server Authentication.
+clientAuth		SSL/TLS Web Client Authentication.
+codeSigning		Code signing.
+emailProtection		E-mail Protection (S/MIME).
+timeStamping		Trusted Timestamping
+msCodeInd		Microsoft Individual Code Signing (authenticode)
+msCodeCom		Microsoft Commercial Code Signing (authenticode)
+msCTLSign		Microsoft Trust List Signing
+msSGC			Microsoft Server Gated Crypto
+msEFS			Microsoft Encrypted File System
+nsSGC			Netscape Server Gated Crypto
+
+For example, under IE5 a CA can be used for any purpose: by including a list
+of the above usages the CA can be restricted to only authorised uses.
+
+Note: software packages may place additional interpretations on certificate 
+use, in particular some usages may only work for selected CAs. Don't for example
+expect just including msSGC or nsSGC will automatically mean that a certificate
+can be used for SGC ("step up" encryption) otherwise anyone could use it.
+
+Examples:
+
+extendedKeyUsage=critical,codeSigning,1.2.3.4
+extendedKeyUsage=nsSGC,msSGC
+
+Subject Key Identifier.
+
+This is really a string extension and can take two possible values. Either
+a hex string giving details of the extension value to include or the word
+'hash' which then automatically follow PKIX guidelines in selecting and
+appropriate key identifier. The use of the hex string is strongly discouraged.
+
+Example: subjectKeyIdentifier=hash
+
+Authority Key Identifier.
+
+The authority key identifier extension permits two options. keyid and issuer:
+both can take the optional value "always".
+
+If the keyid option is present an attempt is made to copy the subject key
+identifier from the parent certificate. If the value "always" is present
+then an error is returned if the option fails.
+
+The issuer option copies the issuer and serial number from the issuer
+certificate. Normally this will only be done if the keyid option fails or
+is not included: the "always" flag will always include the value.
+
+Subject Alternative Name.
+
+The subject alternative name extension allows various literal values to be
+included in the configuration file. These include "email" (an email address)
+"URI" a uniform resource indicator, "DNS" (a DNS domain name), RID (a
+registered ID: OBJECT IDENTIFIER), IP (and IP address) and otherName.
+
+Also the email option include a special 'copy' value. This will automatically
+include and email addresses contained in the certificate subject name in
+the extension.
+
+otherName can include arbitrary data associated with an OID: the value
+should be the OID followed by a semicolon and the content in standard
+ASN1_generate_nconf() format.
+
+Examples:
+
+subjectAltName=email:copy,email:my@other.address,URI:http://my.url.here/
+subjectAltName=email:my@other.address,RID:1.2.3.4
+subjectAltName=otherName:1.2.3.4;UTF8:some other identifier
+
+Issuer Alternative Name.
+
+The issuer alternative name option supports all the literal options of
+subject alternative name. It does *not* support the email:copy option because
+that would not make sense. It does support an additional issuer:copy option
+that will copy all the subject alternative name values from the issuer 
+certificate (if possible).
+
+Example:
+
+issuserAltName = issuer:copy
+
+Authority Info Access.
+
+The authority information access extension gives details about how to access
+certain information relating to the CA. Its syntax is accessOID;location
+where 'location' has the same syntax as subject alternative name (except
+that email:copy is not supported). accessOID can be any valid OID but only
+certain values are meaningful for example OCSP and caIssuers. OCSP gives the
+location of an OCSP responder: this is used by Netscape PSM and other software.
+
+Example:
+
+authorityInfoAccess = OCSP;URI:http://ocsp.my.host/
+authorityInfoAccess = caIssuers;URI:http://my.ca/ca.html
+
+CRL distribution points.
+
+This is a multi-valued extension that supports all the literal options of
+subject alternative name. Of the few software packages that currently interpret
+this extension most only interpret the URI option.
+
+Currently each option will set a new DistributionPoint with the fullName
+field set to the given value.
+
+Other fields like cRLissuer and reasons cannot currently be set or displayed:
+at this time no examples were available that used these fields.
+
+If you see this extension with <UNSUPPORTED> when you attempt to print it out
+or it doesn't appear to display correctly then let me know, including the
+certificate (mail me at steve@openssl.org) .
+
+Examples:
+
+crlDistributionPoints=URI:http://www.myhost.com/myca.crl
+crlDistributionPoints=URI:http://www.my.com/my.crl,URI:http://www.oth.com/my.crl
+
+Certificate Policies.
+
+This is a RAW extension. It attempts to display the contents of this extension:
+unfortunately this extension is often improperly encoded.
+
+The certificate policies extension will rarely be used in practice: few
+software packages interpret it correctly or at all. IE5 does partially
+support this extension: but it needs the 'ia5org' option because it will
+only correctly support a broken encoding. Of the options below only the
+policy OID, explicitText and CPS options are displayed with IE5.
+
+All the fields of this extension can be set by using the appropriate syntax.
+
+If you follow the PKIX recommendations of not including any qualifiers and just
+using only one OID then you just include the value of that OID. Multiple OIDs
+can be set separated by commas, for example:
+
+certificatePolicies= 1.2.4.5, 1.1.3.4
+
+If you wish to include qualifiers then the policy OID and qualifiers need to
+be specified in a separate section: this is done by using the @section syntax
+instead of a literal OID value.
+
+The section referred to must include the policy OID using the name
+policyIdentifier, cPSuri qualifiers can be included using the syntax:
+
+CPS.nnn=value
+
+userNotice qualifiers can be set using the syntax:
+
+userNotice.nnn=@notice
+
+The value of the userNotice qualifier is specified in the relevant section.
+This section can include explicitText, organization and noticeNumbers
+options. explicitText and organization are text strings, noticeNumbers is a
+comma separated list of numbers. The organization and noticeNumbers options
+(if included) must BOTH be present. If you use the userNotice option with IE5
+then you need the 'ia5org' option at the top level to modify the encoding:
+otherwise it will not be interpreted properly.
+
+Example:
+
+certificatePolicies=ia5org,1.2.3.4,1.5.6.7.8,@polsect
+
+[polsect]
+
+policyIdentifier = 1.3.5.8
+CPS.1="http://my.host.name/"
+CPS.2="http://my.your.name/"
+userNotice.1=@notice
+
+[notice]
+
+explicitText="Explicit Text Here"
+organization="Organisation Name"
+noticeNumbers=1,2,3,4
+
+TECHNICAL NOTE: the ia5org option changes the type of the 'organization' field,
+according to PKIX it should be of type DisplayText but Verisign uses an 
+IA5STRING and IE5 needs this too.
+
+Display only extensions.
+
+Some extensions are only partially supported and currently are only displayed
+but cannot be set. These include private key usage period, CRL number, and
+CRL reason.
+
+==============================================================================
+		X509V3 Extension code: programmers guide
+==============================================================================
+
+The purpose of the extension code is twofold. It allows an extension to be
+created from a string or structure describing its contents and it prints out an
+extension in a human or machine readable form.
+
+1. Initialisation and cleanup.
+
+No special initialisation is needed before calling the extension functions.
+You used to have to call X509V3_add_standard_extensions(); but this is no longer
+required and this function no longer does anything.
+
+void X509V3_EXT_cleanup(void);
+
+This function should be called to cleanup the extension code if any custom
+extensions have been added. If no custom extensions have been added then this
+call does nothing. After this call all custom extension code is freed up but
+you can still use the standard extensions.
+
+2. Printing and parsing extensions.
+
+The simplest way to print out extensions is via the standard X509 printing
+routines: if you use the standard X509_print() function, the supported
+extensions will be printed out automatically.
+
+The following functions allow finer control over extension display:
+
+int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, int flag, int indent);
+int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent);
+
+These two functions print out an individual extension to a BIO or FILE pointer.
+Currently the flag argument is unused and should be set to 0. The 'indent'
+argument is the number of spaces to indent each line.
+
+void *X509V3_EXT_d2i(X509_EXTENSION *ext);
+
+This function parses an extension and returns its internal structure. The
+precise structure you get back depends on the extension being parsed. If the
+extension if basicConstraints you will get back a pointer to a
+BASIC_CONSTRAINTS structure. Check out the source in crypto/x509v3 for more
+details about the structures returned. The returned structure should be freed
+after use using the relevant free function, BASIC_CONSTRAINTS_free() for 
+example.
+
+void	*	X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
+void	*	X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx);
+void	*	X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx);
+void 	*	X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx);
+
+These functions combine the operations of searching for extensions and
+parsing them. They search a certificate, a CRL a CRL entry or a stack
+of extensions respectively for extension whose NID is 'nid' and return
+the parsed result of NULL if an error occurred. For example:
+
+BASIC_CONSTRAINTS *bs;
+bs = X509_get_ext_d2i(cert, NID_basic_constraints, NULL, NULL);
+
+This will search for the basicConstraints extension and either return
+it value or NULL. NULL can mean either the extension was not found, it
+occurred more than once or it could not be parsed.
+
+If 'idx' is NULL then an extension is only parsed if it occurs precisely
+once. This is standard behaviour because extensions normally cannot occur
+more than once. If however more than one extension of the same type can
+occur it can be used to parse successive extensions for example:
+
+int i;
+void *ext;
+
+i = -1;
+for(;;) {
+	ext = X509_get_ext_d2i(x, nid, crit, &idx);
+	if(ext == NULL) break;
+	 /* Do something with ext */
+}
+
+If 'crit' is not NULL and the extension was found then the int it points to
+is set to 1 for critical extensions and 0 for non critical. Therefore if the
+function returns NULL but 'crit' is set to 0 or 1 then the extension was
+found but it could not be parsed.
+
+The int pointed to by crit will be set to -1 if the extension was not found
+and -2 if the extension occurred more than once (this will only happen if
+idx is NULL). In both cases the function will return NULL.
+
+3. Generating extensions.
+
+An extension will typically be generated from a configuration file, or some
+other kind of configuration database.
+
+int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
+								 X509 *cert);
+int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
+								 X509_CRL *crl);
+
+These functions add all the extensions in the given section to the given
+certificate or CRL. They will normally be called just before the certificate
+or CRL is due to be signed. Both return 0 on error on non zero for success.
+
+In each case 'conf' is the LHASH pointer of the configuration file to use
+and 'section' is the section containing the extension details.
+
+See the 'context functions' section for a description of the ctx parameter.
+
+
+X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name,
+								 char *value);
+
+This function returns an extension based on a name and value pair, if the
+pair will not need to access other sections in a config file (or there is no
+config file) then the 'conf' parameter can be set to NULL.
+
+X509_EXTENSION *X509V3_EXT_conf_nid(char *conf, X509V3_CTX *ctx, int nid,
+								 char *value);
+
+This function creates an extension in the same way as X509V3_EXT_conf() but
+takes the NID of the extension rather than its name.
+
+For example to produce basicConstraints with the CA flag and a path length of
+10:
+
+x = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints,"CA:TRUE,pathlen:10");
+
+
+X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
+
+This function sets up an extension from its internal structure. The ext_nid
+parameter is the NID of the extension and 'crit' is the critical flag.
+
+4. Context functions.
+
+The following functions set and manipulate an extension context structure.
+The purpose of the extension context is to allow the extension code to
+access various structures relating to the "environment" of the certificate:
+for example the issuers certificate or the certificate request.
+
+void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject,
+                                 X509_REQ *req, X509_CRL *crl, int flags);
+
+This function sets up an X509V3_CTX structure with details of the certificate
+environment: specifically the issuers certificate, the subject certificate,
+the certificate request and the CRL: if these are not relevant or not
+available then they can be set to NULL. The 'flags' parameter should be set
+to zero.
+
+X509V3_set_ctx_test(ctx)
+
+This macro is used to set the 'ctx' structure to a 'test' value: this is to
+allow the syntax of an extension (or configuration file) to be tested.
+
+X509V3_set_ctx_nodb(ctx)
+
+This macro is used when no configuration database is present.
+
+void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH *lhash);
+
+This function is used to set the configuration database when it is an LHASH
+structure: typically a configuration file.
+
+The following functions are used to access a configuration database: they
+should only be used in RAW extensions.
+
+char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section);
+
+This function returns the value of the parameter "name" in "section", or NULL
+if there has been an error.
+
+void X509V3_string_free(X509V3_CTX *ctx, char *str);
+
+This function frees up the string returned by the above function.
+
+STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section);
+
+This function returns a whole section as a STACK_OF(CONF_VALUE) .
+
+void X509V3_section_free( X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section);
+
+This function frees up the STACK returned by the above function.
+
+Note: it is possible to use the extension code with a custom configuration
+database. To do this the "db_meth" element of the X509V3_CTX structure should
+be set to an X509V3_CTX_METHOD structure. This structure contains the following
+function pointers:
+
+char * (*get_string)(void *db, char *section, char *value);
+STACK_OF(CONF_VALUE) * (*get_section)(void *db, char *section);
+void (*free_string)(void *db, char * string);
+void (*free_section)(void *db, STACK_OF(CONF_VALUE) *section);
+
+these will be called and passed the 'db' element in the X509V3_CTX structure
+to access the database. If a given function is not implemented or not required
+it can be set to NULL.
+
+5. String helper functions.
+
+There are several "i2s" and "s2i" functions that convert structures to and
+from ASCII strings. In all the "i2s" cases the returned string should be
+freed using Free() after use. Since some of these are part of other extension
+code they may take a 'method' parameter. Unless otherwise stated it can be
+safely set to NULL.
+
+char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct);
+
+This returns a hex string from an ASN1_OCTET_STRING.
+
+char * i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint);
+char * i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
+
+These return a string decimal representations of an ASN1_INTEGER and an
+ASN1_ENUMERATED type, respectively.
+
+ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
+                                                   X509V3_CTX *ctx, char *str);
+
+This converts an ASCII hex string to an ASN1_OCTET_STRING.
+
+ASN1_INTEGER * s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value);
+
+This converts a decimal ASCII string into an ASN1_INTEGER.
+
+6. Multi valued extension helper functions.
+
+The following functions can be used to manipulate STACKs of CONF_VALUE
+structures, as used by multi valued extensions.
+
+int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool);
+
+This function expects a boolean value in 'value' and sets 'asn1_bool' to
+it. That is it sets it to 0 for FALSE or 0xff for TRUE. The following
+strings are acceptable: "TRUE", "true", "Y", "y", "YES", "yes", "FALSE"
+"false", "N", "n", "NO" or "no".
+
+int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint);
+
+This accepts a decimal integer of arbitrary length and sets an ASN1_INTEGER.
+
+int X509V3_add_value(const char *name, const char *value,
+						STACK_OF(CONF_VALUE) **extlist);
+
+This simply adds a string name and value pair.
+
+int X509V3_add_value_uchar(const char *name, const unsigned char *value,
+                          			STACK_OF(CONF_VALUE) **extlist);
+
+The same as above but for an unsigned character value.
+
+int X509V3_add_value_bool(const char *name, int asn1_bool,
+						STACK_OF(CONF_VALUE) **extlist);
+
+This adds either "TRUE" or "FALSE" depending on the value of 'asn1_bool'
+
+int X509V3_add_value_bool_nf(char *name, int asn1_bool,
+						STACK_OF(CONF_VALUE) **extlist);
+
+This is the same as above except it adds nothing if asn1_bool is FALSE.
+
+int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
+						STACK_OF(CONF_VALUE) **extlist);
+
+This function adds the value of the ASN1_INTEGER in decimal form.
+
+7. Other helper functions.
+
+<to be added>
+
+ADDING CUSTOM EXTENSIONS.
+
+Currently there are three types of supported extensions. 
+
+String extensions are simple strings where the value is placed directly in the
+extensions, and the string returned is printed out.
+
+Multi value extensions are passed a STACK_OF(CONF_VALUE) name and value pairs
+or return a STACK_OF(CONF_VALUE).
+
+Raw extensions are just passed a BIO or a value and it is the extensions
+responsibility to handle all the necessary printing.
+
+There are two ways to add an extension. One is simply as an alias to an already
+existing extension. An alias is an extension that is identical in ASN1 structure
+to an existing extension but has a different OBJECT IDENTIFIER. This can be
+done by calling:
+
+int X509V3_EXT_add_alias(int nid_to, int nid_from);
+
+'nid_to' is the new extension NID and 'nid_from' is the already existing
+extension NID.
+
+Alternatively an extension can be written from scratch. This involves writing
+the ASN1 code to encode and decode the extension and functions to print out and
+generate the extension from strings. The relevant functions are then placed in
+a X509V3_EXT_METHOD structure and int X509V3_EXT_add(X509V3_EXT_METHOD *ext);
+called.
+
+The X509V3_EXT_METHOD structure is described below.
+
+struct {
+int ext_nid;
+int ext_flags;
+X509V3_EXT_NEW ext_new;
+X509V3_EXT_FREE ext_free;
+X509V3_EXT_D2I d2i;
+X509V3_EXT_I2D i2d;
+X509V3_EXT_I2S i2s;
+X509V3_EXT_S2I s2i;
+X509V3_EXT_I2V i2v;
+X509V3_EXT_V2I v2i;
+X509V3_EXT_R2I r2i;
+X509V3_EXT_I2R i2r;
+
+void *usr_data;
+};
+
+The elements have the following meanings.
+
+ext_nid		is the NID of the object identifier of the extension.
+
+ext_flags	is set of flags. Currently the only external flag is
+		X509V3_EXT_MULTILINE which means a multi valued extensions
+		should be printed on separate lines.
+
+usr_data	is an extension specific pointer to any relevant data. This
+		allows extensions to share identical code but have different
+		uses. An example of this is the bit string extension which uses
+		usr_data to contain a list of the bit names.
+
+All the remaining elements are function pointers.
+
+ext_new		is a pointer to a function that allocates memory for the
+		extension ASN1 structure: for example ASN1_OBJECT_new().
+
+ext_free	is a pointer to a function that free up memory of the extension
+		ASN1 structure: for example ASN1_OBJECT_free().
+
+d2i		is the standard ASN1 function that converts a DER buffer into
+		the internal ASN1 structure: for example d2i_ASN1_IA5STRING().
+
+i2d		is the standard ASN1 function that converts the internal
+		structure into the DER representation: for example
+		i2d_ASN1_IA5STRING().
+
+The remaining functions are depend on the type of extension. One i2X and
+one X2i should be set and the rest set to NULL. The types set do not need
+to match up, for example the extension could be set using the multi valued
+v2i function and printed out using the raw i2r.
+
+All functions have the X509V3_EXT_METHOD passed to them in the 'method'
+parameter and an X509V3_CTX structure. Extension code can then access the
+parent structure via the 'method' parameter to for example make use of the value
+of usr_data. If the code needs to use detail relating to the request it can
+use the 'ctx' parameter.
+
+A note should be given here about the 'flags' member of the 'ctx' parameter.
+If it has the value CTX_TEST then the configuration syntax is being checked
+and no actual certificate or CRL exists. Therefore any attempt in the config
+file to access such information should silently succeed. If the syntax is OK
+then it should simply return a (possibly bogus) extension, otherwise it
+should return NULL.
+
+char *i2s(struct v3_ext_method *method, void *ext);
+
+This function takes the internal structure in the ext parameter and returns
+a Malloc'ed string representing its value.
+
+void * s2i(struct v3_ext_method *method, struct v3_ext_ctx *ctx, char *str);
+
+This function takes the string representation in the ext parameter and returns
+an allocated internal structure: ext_free() will be used on this internal
+structure after use.
+
+i2v and v2i handle a STACK_OF(CONF_VALUE):
+
+typedef struct
+{
+        char *section;
+        char *name;
+        char *value;
+} CONF_VALUE;
+
+Only the name and value members are currently used.
+
+STACK_OF(CONF_VALUE) * i2v(struct v3_ext_method *method, void *ext);
+
+This function is passed the internal structure in the ext parameter and
+returns a STACK of CONF_VALUE structures. The values of name, value,
+section and the structure itself will be freed up with Free after use.
+Several helper functions are available to add values to this STACK.
+
+void * v2i(struct v3_ext_method *method, struct v3_ext_ctx *ctx,
+						STACK_OF(CONF_VALUE) *values);
+
+This function takes a STACK_OF(CONF_VALUE) structures and should set the
+values of the external structure. This typically uses the name element to
+determine which structure element to set and the value element to determine
+what to set it to. Several helper functions are available for this
+purpose (see above).
+
+int i2r(struct v3_ext_method *method, void *ext, BIO *out, int indent);
+
+This function is passed the internal extension structure in the ext parameter
+and sends out a human readable version of the extension to out. The 'indent'
+parameter should be noted to determine the necessary amount of indentation
+needed on the output.
+
+void * r2i(struct v3_ext_method *method, struct v3_ext_ctx *ctx, char *str);
+
+This is just passed the string representation of the extension. It is intended
+to be used for more elaborate extensions where the standard single and multi
+valued options are insufficient. They can use the 'ctx' parameter to parse the
+configuration database themselves. See the context functions section for details
+of how to do this.
+
+Note: although this type takes the same parameters as the "r2s" function there
+is a subtle difference. Whereas an "r2i" function can access a configuration
+database an "s2i" function MUST NOT. This is so the internal code can safely
+assume that an "s2i" function will work without a configuration database.
+
+==============================================================================
+                            PKCS#12 Library
+==============================================================================
+
+This section describes the internal PKCS#12 support. There are very few
+differences between the old external library and the new internal code at
+present. This may well change because the external library will not be updated
+much in future.
+
+This version now includes a couple of high level PKCS#12 functions which
+generally "do the right thing" and should make it much easier to handle PKCS#12
+structures.
+
+HIGH LEVEL FUNCTIONS.
+
+For most applications you only need concern yourself with the high level
+functions. They can parse and generate simple PKCS#12 files as produced by
+Netscape and MSIE or indeed any compliant PKCS#12 file containing a single
+private key and certificate pair.
+
+1. Initialisation and cleanup.
+
+No special initialisation is needed for the internal PKCS#12 library: the 
+standard SSLeay_add_all_algorithms() is sufficient. If you do not wish to
+add all algorithms (you should at least add SHA1 though) then you can manually
+initialise the PKCS#12 library with:
+
+PKCS12_PBE_add();
+
+The memory allocated by the PKCS#12 library is freed up when EVP_cleanup() is
+called or it can be directly freed with:
+
+EVP_PBE_cleanup();
+
+after this call (or EVP_cleanup() ) no more PKCS#12 library functions should
+be called.
+
+2. I/O functions.
+
+i2d_PKCS12_bio(bp, p12)
+
+This writes out a PKCS12 structure to a BIO.
+
+i2d_PKCS12_fp(fp, p12)
+
+This is the same but for a FILE pointer.
+
+d2i_PKCS12_bio(bp, p12)
+
+This reads in a PKCS12 structure from a BIO.
+
+d2i_PKCS12_fp(fp, p12)
+
+This is the same but for a FILE pointer.
+
+3. High level functions.
+
+3.1 Parsing with PKCS12_parse().
+
+int PKCS12_parse(PKCS12 *p12, char *pass, EVP_PKEY **pkey, X509 **cert,
+								 STACK **ca);
+
+This function takes a PKCS12 structure and a password (ASCII, null terminated)
+and returns the private key, the corresponding certificate and any CA
+certificates. If any of these is not required it can be passed as a NULL.
+The 'ca' parameter should be either NULL, a pointer to NULL or a valid STACK
+structure. Typically to read in a PKCS#12 file you might do:
+
+p12 = d2i_PKCS12_fp(fp, NULL);
+PKCS12_parse(p12, password, &pkey, &cert, NULL); 	/* CAs not wanted */
+PKCS12_free(p12);
+
+3.2 PKCS#12 creation with PKCS12_create().
+
+PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
+			STACK *ca, int nid_key, int nid_cert, int iter,
+						 int mac_iter, int keytype);
+
+This function will create a PKCS12 structure from a given password, name,
+private key, certificate and optional STACK of CA certificates. The remaining
+5 parameters can be set to 0 and sensible defaults will be used.
+
+The parameters nid_key and nid_cert are the key and certificate encryption
+algorithms, iter is the encryption iteration count, mac_iter is the MAC
+iteration count and keytype is the type of private key. If you really want
+to know what these last 5 parameters do then read the low level section.
+
+Typically to create a PKCS#12 file the following could be used:
+
+p12 = PKCS12_create(pass, "My Certificate", pkey, cert, NULL, 0,0,0,0,0);
+i2d_PKCS12_fp(fp, p12);
+PKCS12_free(p12);
+
+3.3 Changing a PKCS#12 structure password.
+
+int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass);
+
+This changes the password of an already existing PKCS#12 structure. oldpass
+is the old password and newpass is the new one. An error occurs if the old
+password is incorrect.
+
+LOW LEVEL FUNCTIONS.
+
+In some cases the high level functions do not provide the necessary
+functionality. For example if you want to generate or parse more complex
+PKCS#12 files. The sample pkcs12 application uses the low level functions
+to display details about the internal structure of a PKCS#12 file.
+
+Introduction.
+
+This is a brief description of how a PKCS#12 file is represented internally:
+some knowledge of PKCS#12 is assumed.
+
+A PKCS#12 object contains several levels.
+
+At the lowest level is a PKCS12_SAFEBAG. This can contain a certificate, a
+CRL, a private key, encrypted or unencrypted, a set of safebags (so the
+structure can be nested) or other secrets (not documented at present). 
+A safebag can optionally have attributes, currently these are: a unicode
+friendlyName (a Unicode string) or a localKeyID (a string of bytes).
+
+At the next level is an authSafe which is a set of safebags collected into
+a PKCS#7 ContentInfo. This can be just plain data, or encrypted itself.
+
+At the top level is the PKCS12 structure itself which contains a set of
+authSafes in an embedded PKCS#7 Contentinfo of type data. In addition it
+contains a MAC which is a kind of password protected digest to preserve
+integrity (so any unencrypted stuff below can't be tampered with).
+
+The reason for these levels is so various objects can be encrypted in various
+ways. For example you might want to encrypt a set of private keys with
+triple-DES and then include the related certificates either unencrypted or
+with lower encryption. Yes it's the dreaded crypto laws at work again which
+allow strong encryption on private keys and only weak encryption on other
+stuff.
+
+To build one of these things you turn all certificates and keys into safebags
+(with optional attributes). You collect the safebags into (one or more) STACKS
+and convert these into authsafes (encrypted or unencrypted).  The authsafes
+are collected into a STACK and added to a PKCS12 structure.  Finally a MAC
+inserted.
+
+Pulling one apart is basically the reverse process. The MAC is verified against
+the given password. The authsafes are extracted and each authsafe split into
+a set of safebags (possibly involving decryption). Finally the safebags are
+decomposed into the original keys and certificates and the attributes used to
+match up private key and certificate pairs.
+
+Anyway here are the functions that do the dirty work.
+
+1. Construction functions.
+
+1.1 Safebag functions.
+
+M_PKCS12_x5092certbag(x509)
+
+This macro takes an X509 structure and returns a certificate bag. The
+X509 structure can be freed up after calling this function.
+
+M_PKCS12_x509crl2certbag(crl)
+
+As above but for a CRL.
+
+PKCS8_PRIV_KEY_INFO *PKEY2PKCS8(EVP_PKEY *pkey)
+
+Take a private key and convert it into a PKCS#8 PrivateKeyInfo structure.
+Works for both RSA and DSA private keys. NB since the PKCS#8 PrivateKeyInfo
+structure contains a private key data in plain text form it should be free'd
+up as soon as it has been encrypted for security reasons (freeing up the
+structure zeros out the sensitive data). This can be done with
+PKCS8_PRIV_KEY_INFO_free().
+
+PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage)
+
+This sets the key type when a key is imported into MSIE or Outlook 98. Two
+values are currently supported: KEY_EX and KEY_SIG. KEY_EX is an exchange type
+key that can also be used for signing but its size is limited in the export
+versions of MS software to 512 bits, it is also the default. KEY_SIG is a
+signing only key but the keysize is unlimited (well 16K is supposed to work).
+If you are using the domestic version of MSIE then you can ignore this because
+KEY_EX is not limited and can be used for both.
+
+PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8)
+
+Convert a PKCS8 private key structure into a keybag. This routine embeds the
+p8 structure in the keybag so p8 should not be freed up or used after it is
+called.  The p8 structure will be freed up when the safebag is freed.
+
+PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8)
+
+Convert a PKCS#8 structure into a shrouded key bag (encrypted). p8 is not
+embedded and can be freed up after use.
+
+int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen)
+int PKCS12_add_friendlyname(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen)
+
+Add a local key id or a friendlyname to a safebag.
+
+1.2 Authsafe functions.
+
+PKCS7 *PKCS12_pack_p7data(STACK *sk)
+Take a stack of safebags and convert them into an unencrypted authsafe. The
+stack of safebags can be freed up after calling this function.
+
+PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int iter, STACK *bags);
+
+As above but encrypted.
+
+1.3 PKCS12 functions.
+
+PKCS12 *PKCS12_init(int mode)
+
+Initialise a PKCS12 structure (currently mode should be NID_pkcs7_data).
+
+M_PKCS12_pack_authsafes(p12, safes)
+
+This macro takes a STACK of authsafes and adds them to a PKCS#12 structure.
+
+int PKCS12_set_mac(PKCS12 *p12, unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int iter, EVP_MD *md_type);
+
+Add a MAC to a PKCS12 structure. If EVP_MD is NULL use SHA-1, the spec suggests
+that SHA-1 should be used.
+
+2. Extraction Functions.
+
+2.1 Safebags.
+
+M_PKCS12_bag_type(bag)
+
+Return the type of "bag". Returns one of the following
+
+NID_keyBag
+NID_pkcs8ShroudedKeyBag			7
+NID_certBag				8
+NID_crlBag				9
+NID_secretBag				10
+NID_safeContentsBag			11
+
+M_PKCS12_cert_bag_type(bag)
+
+Returns type of certificate bag, following are understood.
+
+NID_x509Certificate			14
+NID_sdsiCertificate			15
+
+M_PKCS12_crl_bag_type(bag)
+
+Returns crl bag type, currently only NID_crlBag is recognised.
+
+M_PKCS12_certbag2x509(bag)
+
+This macro extracts an X509 certificate from a certificate bag.
+
+M_PKCS12_certbag2x509crl(bag)
+
+As above but for a CRL.
+
+EVP_PKEY * PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
+
+Extract a private key from a PKCS8 private key info structure.
+
+M_PKCS12_decrypt_skey(bag, pass, passlen) 
+
+Decrypt a shrouded key bag and return a PKCS8 private key info structure.
+Works with both RSA and DSA keys
+
+char *PKCS12_get_friendlyname(bag)
+
+Returns the friendlyName of a bag if present or NULL if none. The returned
+string is a null terminated ASCII string allocated with Malloc(). It should 
+thus be freed up with Free() after use.
+
+2.2 AuthSafe functions.
+
+M_PKCS12_unpack_p7data(p7)
+
+Extract a STACK of safe bags from a PKCS#7 data ContentInfo.
+
+#define M_PKCS12_unpack_p7encdata(p7, pass, passlen)
+
+As above but for an encrypted content info.
+
+2.3 PKCS12 functions.
+
+M_PKCS12_unpack_authsafes(p12)
+
+Extract a STACK of authsafes from a PKCS12 structure.
+
+M_PKCS12_mac_present(p12)
+
+Check to see if a MAC is present.
+
+int PKCS12_verify_mac(PKCS12 *p12, unsigned char *pass, int passlen)
+
+Verify a MAC on a PKCS12 structure. Returns an error if MAC not present.
+
+
+Notes.
+
+1. All the function return 0 or NULL on error.
+2. Encryption based functions take a common set of parameters. These are
+described below.
+
+pass, passlen
+ASCII password and length. The password on the MAC is called the "integrity
+password" the encryption password is called the "privacy password" in the
+PKCS#12 documentation. The passwords do not have to be the same. If -1 is
+passed for the length it is worked out by the function itself (currently
+this is sometimes done whatever is passed as the length but that may change).
+
+salt, saltlen
+A 'salt' if salt is NULL a random salt is used. If saltlen is also zero a
+default length is used.
+
+iter
+Iteration count. This is a measure of how many times an internal function is
+called to encrypt the data. The larger this value is the longer it takes, it
+makes dictionary attacks on passwords harder. NOTE: Some implementations do
+not support an iteration count on the MAC. If the password for the MAC and
+encryption is the same then there is no point in having a high iteration
+count for encryption if the MAC has no count. The MAC could be attacked
+and the password used for the main decryption.
+
+pbe_nid
+This is the NID of the password based encryption method used. The following are
+supported.
+NID_pbe_WithSHA1And128BitRC4
+NID_pbe_WithSHA1And40BitRC4
+NID_pbe_WithSHA1And3_Key_TripleDES_CBC
+NID_pbe_WithSHA1And2_Key_TripleDES_CBC
+NID_pbe_WithSHA1And128BitRC2_CBC
+NID_pbe_WithSHA1And40BitRC2_CBC
+
+Which you use depends on the implementation you are exporting to. "Export
+grade" (i.e. cryptographically challenged) products cannot support all
+algorithms. Typically you may be able to use any encryption on shrouded key
+bags but they must then be placed in an unencrypted authsafe. Other authsafes
+may only support 40bit encryption. Of course if you are using SSLeay
+throughout you can strongly encrypt everything and have high iteration counts
+on everything.
+
+3. For decryption routines only the password and length are needed.
+
+4. Unlike the external version the nid's of objects are the values of the
+constants: that is NID_certBag is the real nid, therefore there is no 
+PKCS12_obj_offset() function.  Note the object constants are not the same as
+those of the external version. If you use these constants then you will need
+to recompile your code.
+
+5. With the exception of PKCS12_MAKE_KEYBAG(), after calling any function or 
+macro of the form PKCS12_MAKE_SOMETHING(other) the "other" structure can be
+reused or freed up safely.
+
diff --git a/openssl/doc/openssl_button.gif b/openssl/doc/openssl_button.gif
new file mode 100644
index 0000000..3d3c90c
--- /dev/null
+++ b/openssl/doc/openssl_button.gif
Binary files differ
diff --git a/openssl/doc/openssl_button.html b/openssl/doc/openssl_button.html
new file mode 100644
index 0000000..44c91bd
--- /dev/null
+++ b/openssl/doc/openssl_button.html
@@ -0,0 +1,7 @@
+
+<!-- the `Includes OpenSSL Cryptogaphy Software' button      -->
+<!-- freely usable by any application linked against OpenSSL -->
+<a   href="http://www.openssl.org/">
+<img src="openssl_button.gif" 
+     width=102 height=47 border=0></a>
+
diff --git a/openssl/doc/ssl/SSL_CIPHER_get_name.pod b/openssl/doc/ssl/SSL_CIPHER_get_name.pod
new file mode 100644
index 0000000..eb772b5
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CIPHER_get_name.pod
@@ -0,0 +1,112 @@
+=pod
+
+=head1 NAME
+
+SSL_CIPHER_get_name, SSL_CIPHER_get_bits, SSL_CIPHER_get_version, SSL_CIPHER_description - get SSL_CIPHER properties
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher);
+ int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, int *alg_bits);
+ char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher);
+ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int size);
+
+=head1 DESCRIPTION
+
+SSL_CIPHER_get_name() returns a pointer to the name of B<cipher>. If the
+argument is the NULL pointer, a pointer to the constant value "NONE" is
+returned.
+
+SSL_CIPHER_get_bits() returns the number of secret bits used for B<cipher>. If
+B<alg_bits> is not NULL, it contains the number of bits processed by the
+chosen algorithm. If B<cipher> is NULL, 0 is returned.
+
+SSL_CIPHER_get_version() returns the protocol version for B<cipher>, currently
+"SSLv2", "SSLv3", or "TLSv1". If B<cipher> is NULL, "(NONE)" is returned.
+
+SSL_CIPHER_description() returns a textual description of the cipher used
+into the buffer B<buf> of length B<len> provided. B<len> must be at least
+128 bytes, otherwise a pointer to the string "Buffer too small" is
+returned. If B<buf> is NULL, a buffer of 128 bytes is allocated using
+OPENSSL_malloc(). If the allocation fails, a pointer to the string
+"OPENSSL_malloc Error" is returned.
+
+=head1 NOTES
+
+The number of bits processed can be different from the secret bits. An
+export cipher like e.g. EXP-RC4-MD5 has only 40 secret bits. The algorithm
+does use the full 128 bits (which would be returned for B<alg_bits>), of
+which however 88bits are fixed. The search space is hence only 40 bits.
+
+The string returned by SSL_CIPHER_description() in case of success consists
+of cleartext information separated by one or more blanks in the following
+sequence:
+
+=over 4
+
+=item <ciphername>
+
+Textual representation of the cipher name.
+
+=item <protocol version>
+
+Protocol version: B<SSLv2>, B<SSLv3>. The TLSv1 ciphers are flagged with SSLv3.
+
+=item Kx=<key exchange>
+
+Key exchange method: B<RSA> (for export ciphers as B<RSA(512)> or
+B<RSA(1024)>), B<DH> (for export ciphers as B<DH(512)> or B<DH(1024)>),
+B<DH/RSA>, B<DH/DSS>, B<Fortezza>.
+
+=item Au=<authentication>
+
+Authentication method: B<RSA>, B<DSS>, B<DH>, B<None>. None is the
+representation of anonymous ciphers.
+
+=item Enc=<symmetric encryption method>
+
+Encryption method with number of secret bits: B<DES(40)>, B<DES(56)>,
+B<3DES(168)>, B<RC4(40)>, B<RC4(56)>, B<RC4(64)>, B<RC4(128)>,
+B<RC2(40)>, B<RC2(56)>, B<RC2(128)>, B<IDEA(128)>, B<Fortezza>, B<None>.
+
+=item Mac=<message authentication code>
+
+Message digest: B<MD5>, B<SHA1>.
+
+=item <export flag>
+
+If the cipher is flagged exportable with respect to old US crypto
+regulations, the word "B<export>" is printed.
+
+=back
+
+=head1 EXAMPLES
+
+Some examples for the output of SSL_CIPHER_description():
+
+ EDH-RSA-DES-CBC3-SHA    SSLv3 Kx=DH       Au=RSA  Enc=3DES(168) Mac=SHA1
+ EDH-DSS-DES-CBC3-SHA    SSLv3 Kx=DH       Au=DSS  Enc=3DES(168) Mac=SHA1
+ RC4-MD5                 SSLv3 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=MD5
+ EXP-RC4-MD5             SSLv3 Kx=RSA(512) Au=RSA  Enc=RC4(40)   Mac=MD5  export
+
+=head1 BUGS
+
+If SSL_CIPHER_description() is called with B<cipher> being NULL, the
+library crashes.
+
+If SSL_CIPHER_description() cannot handle a built-in cipher, the according
+description of the cipher property is B<unknown>. This case should not
+occur.
+
+=head1 RETURN VALUES
+
+See DESCRIPTION
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_get_current_cipher(3)|SSL_get_current_cipher(3)>,
+L<SSL_get_ciphers(3)|SSL_get_ciphers(3)>, L<ciphers(1)|ciphers(1)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_COMP_add_compression_method.pod b/openssl/doc/ssl/SSL_COMP_add_compression_method.pod
new file mode 100644
index 0000000..42fa66b
--- /dev/null
+++ b/openssl/doc/ssl/SSL_COMP_add_compression_method.pod
@@ -0,0 +1,70 @@
+=pod
+
+=head1 NAME
+
+SSL_COMP_add_compression_method - handle SSL/TLS integrated compression methods
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm);
+
+=head1 DESCRIPTION
+
+SSL_COMP_add_compression_method() adds the compression method B<cm> with
+the identifier B<id> to the list of available compression methods. This
+list is globally maintained for all SSL operations within this application.
+It cannot be set for specific SSL_CTX or SSL objects.
+
+=head1 NOTES
+
+The TLS standard (or SSLv3) allows the integration of compression methods
+into the communication. The TLS RFC does however not specify compression
+methods or their corresponding identifiers, so there is currently no compatible
+way to integrate compression with unknown peers. It is therefore currently not
+recommended to integrate compression into applications. Applications for
+non-public use may agree on certain compression methods. Using different
+compression methods with the same identifier will lead to connection failure.
+
+An OpenSSL client speaking a protocol that allows compression (SSLv3, TLSv1)
+will unconditionally send the list of all compression methods enabled with
+SSL_COMP_add_compression_method() to the server during the handshake.
+Unlike the mechanisms to set a cipher list, there is no method available to
+restrict the list of compression method on a per connection basis.
+
+An OpenSSL server will match the identifiers listed by a client against
+its own compression methods and will unconditionally activate compression
+when a matching identifier is found. There is no way to restrict the list
+of compression methods supported on a per connection basis.
+
+The OpenSSL library has the compression methods B<COMP_rle()> and (when
+especially enabled during compilation) B<COMP_zlib()> available.
+
+=head1 WARNINGS
+
+Once the identities of the compression methods for the TLS protocol have
+been standardized, the compression API will most likely be changed. Using
+it in the current state is not recommended.
+
+=head1 RETURN VALUES
+
+SSL_COMP_add_compression_method() may return the following values:
+
+=over 4
+
+=item 0
+
+The operation succeeded.
+
+=item 1
+
+The operation failed. Check the error queue to find out the reason.
+
+=back
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_add_extra_chain_cert.pod b/openssl/doc/ssl/SSL_CTX_add_extra_chain_cert.pod
new file mode 100644
index 0000000..ee28f5c
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_add_extra_chain_cert.pod
@@ -0,0 +1,39 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_add_extra_chain_cert - add certificate to chain
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ long SSL_CTX_add_extra_chain_cert(SSL_CTX ctx, X509 *x509)
+
+=head1 DESCRIPTION
+
+SSL_CTX_add_extra_chain_cert() adds the certificate B<x509> to the certificate
+chain presented together with the certificate. Several certificates
+can be added one after the other.
+
+=head1 NOTES
+
+When constructing the certificate chain, the chain will be formed from
+these certificates explicitly specified. If no chain is specified,
+the library will try to complete the chain from the available CA
+certificates in the trusted CA storage, see
+L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>.
+
+=head1 RETURN VALUES
+
+SSL_CTX_add_extra_chain_cert() returns 1 on success. Check out the
+error stack to find out the reason for failure otherwise.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>,
+L<SSL_CTX_use_certificate(3)|SSL_CTX_use_certificate(3)>,
+L<SSL_CTX_set_client_cert_cb(3)|SSL_CTX_set_client_cert_cb(3)>,
+L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_add_session.pod b/openssl/doc/ssl/SSL_CTX_add_session.pod
new file mode 100644
index 0000000..82676b2
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_add_session.pod
@@ -0,0 +1,73 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_add_session, SSL_add_session, SSL_CTX_remove_session, SSL_remove_session - manipulate session cache
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c);
+ int SSL_add_session(SSL_CTX *ctx, SSL_SESSION *c);
+
+ int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c);
+ int SSL_remove_session(SSL_CTX *ctx, SSL_SESSION *c);
+
+=head1 DESCRIPTION
+
+SSL_CTX_add_session() adds the session B<c> to the context B<ctx>. The
+reference count for session B<c> is incremented by 1. If a session with
+the same session id already exists, the old session is removed by calling
+L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>.
+
+SSL_CTX_remove_session() removes the session B<c> from the context B<ctx>.
+L<SSL_SESSION_free(3)|SSL_SESSION_free(3)> is called once for B<c>.
+
+SSL_add_session() and SSL_remove_session() are synonyms for their
+SSL_CTX_*() counterparts.
+
+=head1 NOTES
+
+When adding a new session to the internal session cache, it is examined
+whether a session with the same session id already exists. In this case
+it is assumed that both sessions are identical. If the same session is
+stored in a different SSL_SESSION object, The old session is
+removed and replaced by the new session. If the session is actually
+identical (the SSL_SESSION object is identical), SSL_CTX_add_session()
+is a no-op, and the return value is 0.
+
+If a server SSL_CTX is configured with the SSL_SESS_CACHE_NO_INTERNAL_STORE
+flag then the internal cache will not be populated automatically by new
+sessions negotiated by the SSL/TLS implementation, even though the internal
+cache will be searched automatically for session-resume requests (the
+latter can be surpressed by SSL_SESS_CACHE_NO_INTERNAL_LOOKUP). So the
+application can use SSL_CTX_add_session() directly to have full control
+over the sessions that can be resumed if desired.
+
+
+=head1 RETURN VALUES
+
+The following values are returned by all functions:
+
+=over 4
+
+=item 0
+
+ The operation failed. In case of the add operation, it was tried to add
+ the same (identical) session twice. In case of the remove operation, the
+ session was not found in the cache.
+
+=item 1
+ 
+ The operation succeeded.
+
+=back
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>,
+L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
+L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_ctrl.pod b/openssl/doc/ssl/SSL_CTX_ctrl.pod
new file mode 100644
index 0000000..fb6adcf
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_ctrl.pod
@@ -0,0 +1,34 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_ctrl, SSL_CTX_callback_ctrl, SSL_ctrl, SSL_callback_ctrl - internal handling functions for SSL_CTX and SSL objects
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg);
+ long SSL_CTX_callback_ctrl(SSL_CTX *, int cmd, void (*fp)());
+
+ long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg);
+ long SSL_callback_ctrl(SSL *, int cmd, void (*fp)());
+
+=head1 DESCRIPTION
+
+The SSL_*_ctrl() family of functions is used to manipulate settings of
+the SSL_CTX and SSL objects. Depending on the command B<cmd> the arguments
+B<larg>, B<parg>, or B<fp> are evaluated. These functions should never
+be called directly. All functionalities needed are made available via
+other functions or macros.
+
+=head1 RETURN VALUES
+
+The return values of the SSL*_ctrl() functions depend on the command
+supplied via the B<cmd> parameter.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_flush_sessions.pod b/openssl/doc/ssl/SSL_CTX_flush_sessions.pod
new file mode 100644
index 0000000..148c36c
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_flush_sessions.pod
@@ -0,0 +1,49 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_flush_sessions, SSL_flush_sessions - remove expired sessions
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm);
+ void SSL_flush_sessions(SSL_CTX *ctx, long tm);
+
+=head1 DESCRIPTION
+
+SSL_CTX_flush_sessions() causes a run through the session cache of
+B<ctx> to remove sessions expired at time B<tm>.
+
+SSL_flush_sessions() is a synonym for SSL_CTX_flush_sessions().
+
+=head1 NOTES
+
+If enabled, the internal session cache will collect all sessions established
+up to the specified maximum number (see SSL_CTX_sess_set_cache_size()).
+As sessions will not be reused ones they are expired, they should be
+removed from the cache to save resources. This can either be done
+ automatically whenever 255 new sessions were established (see
+L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>)
+or manually by calling SSL_CTX_flush_sessions(). 
+
+The parameter B<tm> specifies the time which should be used for the
+expiration test, in most cases the actual time given by time(0)
+will be used.
+
+SSL_CTX_flush_sessions() will only check sessions stored in the internal
+cache. When a session is found and removed, the remove_session_cb is however
+called to synchronize with the external cache (see
+L<SSL_CTX_sess_set_get_cb(3)|SSL_CTX_sess_set_get_cb(3)>).
+
+=head1 RETURN VALUES
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>,
+L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
+L<SSL_CTX_set_timeout(3)|SSL_CTX_set_timeout(3)>,
+L<SSL_CTX_sess_set_get_cb(3)|SSL_CTX_sess_set_get_cb(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_free.pod b/openssl/doc/ssl/SSL_CTX_free.pod
new file mode 100644
index 0000000..51d8676
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_free.pod
@@ -0,0 +1,41 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_free - free an allocated SSL_CTX object
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_CTX_free(SSL_CTX *ctx);
+
+=head1 DESCRIPTION
+
+SSL_CTX_free() decrements the reference count of B<ctx>, and removes the
+SSL_CTX object pointed to by B<ctx> and frees up the allocated memory if the
+the reference count has reached 0.
+
+It also calls the free()ing procedures for indirectly affected items, if
+applicable: the session cache, the list of ciphers, the list of Client CAs,
+the certificates and keys.
+
+=head1 WARNINGS
+
+If a session-remove callback is set (SSL_CTX_sess_set_remove_cb()), this
+callback will be called for each session being freed from B<ctx>'s
+session cache. This implies, that all corresponding sessions from an
+external session cache are removed as well. If this is not desired, the user
+should explicitly unset the callback by calling
+SSL_CTX_sess_set_remove_cb(B<ctx>, NULL) prior to calling SSL_CTX_free().
+
+=head1 RETURN VALUES
+
+SSL_CTX_free() does not provide diagnostic information.
+
+=head1 SEE ALSO
+
+L<SSL_CTX_new(3)|SSL_CTX_new(3)>, L<ssl(3)|ssl(3)>,
+L<SSL_CTX_sess_set_get_cb(3)|SSL_CTX_sess_set_get_cb(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_get_ex_new_index.pod b/openssl/doc/ssl/SSL_CTX_get_ex_new_index.pod
new file mode 100644
index 0000000..0c40a91
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_get_ex_new_index.pod
@@ -0,0 +1,53 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_get_ex_new_index, SSL_CTX_set_ex_data, SSL_CTX_get_ex_data - internal application specific data functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_CTX_get_ex_new_index(long argl, void *argp,
+                CRYPTO_EX_new *new_func,
+                CRYPTO_EX_dup *dup_func,
+                CRYPTO_EX_free *free_func);
+
+ int SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *arg);
+
+ void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx);
+
+ typedef int new_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                int idx, long argl, void *argp);
+ typedef void free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                int idx, long argl, void *argp);
+ typedef int dup_func(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d,
+                int idx, long argl, void *argp);
+
+=head1 DESCRIPTION
+
+Several OpenSSL structures can have application specific data attached to them.
+These functions are used internally by OpenSSL to manipulate application
+specific data attached to a specific structure.
+
+SSL_CTX_get_ex_new_index() is used to register a new index for application
+specific data.
+
+SSL_CTX_set_ex_data() is used to store application data at B<arg> for B<idx>
+into the B<ctx> object.
+
+SSL_CTX_get_ex_data() is used to retrieve the information for B<idx> from
+B<ctx>.
+
+A detailed description for the B<*_get_ex_new_index()> functionality
+can be found in L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>.
+The B<*_get_ex_data()> and B<*_set_ex_data()> functionality is described in
+L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>,
+L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>,
+L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_get_verify_mode.pod b/openssl/doc/ssl/SSL_CTX_get_verify_mode.pod
new file mode 100644
index 0000000..2a3747e
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_get_verify_mode.pod
@@ -0,0 +1,50 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_get_verify_mode, SSL_get_verify_mode, SSL_CTX_get_verify_depth, SSL_get_verify_depth, SSL_get_verify_callback, SSL_CTX_get_verify_callback - get currently set verification parameters
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
+ int SSL_get_verify_mode(const SSL *ssl);
+ int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
+ int SSL_get_verify_depth(const SSL *ssl);
+ int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int, X509_STORE_CTX *);
+ int (*SSL_get_verify_callback(const SSL *ssl))(int, X509_STORE_CTX *);
+
+=head1 DESCRIPTION
+
+SSL_CTX_get_verify_mode() returns the verification mode currently set in
+B<ctx>.
+
+SSL_get_verify_mode() returns the verification mode currently set in
+B<ssl>.
+
+SSL_CTX_get_verify_depth() returns the verification depth limit currently set
+in B<ctx>. If no limit has been explicitly set, -1 is returned and the
+default value will be used.
+
+SSL_get_verify_depth() returns the verification depth limit currently set
+in B<ssl>. If no limit has been explicitly set, -1 is returned and the
+default value will be used.
+
+SSL_CTX_get_verify_callback() returns a function pointer to the verification
+callback currently set in B<ctx>. If no callback was explicitly set, the
+NULL pointer is returned and the default callback will be used.
+
+SSL_get_verify_callback() returns a function pointer to the verification
+callback currently set in B<ssl>. If no callback was explicitly set, the
+NULL pointer is returned and the default callback will be used.
+
+=head1 RETURN VALUES
+
+See DESCRIPTION
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_load_verify_locations.pod b/openssl/doc/ssl/SSL_CTX_load_verify_locations.pod
new file mode 100644
index 0000000..84a799f
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_load_verify_locations.pod
@@ -0,0 +1,124 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_load_verify_locations - set default locations for trusted CA
+certificates
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
+                                   const char *CApath);
+
+=head1 DESCRIPTION
+
+SSL_CTX_load_verify_locations() specifies the locations for B<ctx>, at
+which CA certificates for verification purposes are located. The certificates
+available via B<CAfile> and B<CApath> are trusted.
+
+=head1 NOTES
+
+If B<CAfile> is not NULL, it points to a file of CA certificates in PEM
+format. The file can contain several CA certificates identified by
+
+ -----BEGIN CERTIFICATE-----
+ ... (CA certificate in base64 encoding) ...
+ -----END CERTIFICATE-----
+
+sequences. Before, between, and after the certificates text is allowed
+which can be used e.g. for descriptions of the certificates.
+
+The B<CAfile> is processed on execution of the SSL_CTX_load_verify_locations()
+function.
+
+If B<CApath> is not NULL, it points to a directory containing CA certificates
+in PEM format. The files each contain one CA certificate. The files are
+looked up by the CA subject name hash value, which must hence be available.
+If more than one CA certificate with the same name hash value exist, the
+extension must be different (e.g. 9d66eef0.0, 9d66eef0.1 etc). The search
+is performed in the ordering of the extension number, regardless of other
+properties of the certificates.
+Use the B<c_rehash> utility to create the necessary links.
+
+The certificates in B<CApath> are only looked up when required, e.g. when
+building the certificate chain or when actually performing the verification
+of a peer certificate.
+
+When looking up CA certificates, the OpenSSL library will first search the
+certificates in B<CAfile>, then those in B<CApath>. Certificate matching
+is done based on the subject name, the key identifier (if present), and the
+serial number as taken from the certificate to be verified. If these data
+do not match, the next certificate will be tried. If a first certificate
+matching the parameters is found, the verification process will be performed;
+no other certificates for the same parameters will be searched in case of
+failure.
+
+In server mode, when requesting a client certificate, the server must send
+the list of CAs of which it will accept client certificates. This list
+is not influenced by the contents of B<CAfile> or B<CApath> and must
+explicitly be set using the
+L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)>
+family of functions.
+
+When building its own certificate chain, an OpenSSL client/server will
+try to fill in missing certificates from B<CAfile>/B<CApath>, if the
+certificate chain was not explicitly specified (see
+L<SSL_CTX_add_extra_chain_cert(3)|SSL_CTX_add_extra_chain_cert(3)>,
+L<SSL_CTX_use_certificate(3)|SSL_CTX_use_certificate(3)>.
+
+=head1 WARNINGS
+
+If several CA certificates matching the name, key identifier, and serial
+number condition are available, only the first one will be examined. This
+may lead to unexpected results if the same CA certificate is available
+with different expiration dates. If a "certificate expired" verification
+error occurs, no other certificate will be searched. Make sure to not
+have expired certificates mixed with valid ones.
+
+=head1 EXAMPLES
+
+Generate a CA certificate file with descriptive text from the CA certificates
+ca1.pem ca2.pem ca3.pem:
+
+ #!/bin/sh
+ rm CAfile.pem
+ for i in ca1.pem ca2.pem ca3.pem ; do
+   openssl x509 -in $i -text >> CAfile.pem
+ done
+
+Prepare the directory /some/where/certs containing several CA certificates
+for use as B<CApath>:
+
+ cd /some/where/certs
+ c_rehash .
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item 0
+
+The operation failed because B<CAfile> and B<CApath> are NULL or the
+processing at one of the locations specified failed. Check the error
+stack to find out the reason.
+
+=item 1
+
+The operation succeeded.
+
+=back
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>,
+L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)>,
+L<SSL_get_client_CA_list(3)|SSL_get_client_CA_list(3)>,
+L<SSL_CTX_use_certificate(3)|SSL_CTX_use_certificate(3)>,
+L<SSL_CTX_add_extra_chain_cert(3)|SSL_CTX_add_extra_chain_cert(3)>,
+L<SSL_CTX_set_cert_store(3)|SSL_CTX_set_cert_store(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_new.pod b/openssl/doc/ssl/SSL_CTX_new.pod
new file mode 100644
index 0000000..73e8c47
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_new.pod
@@ -0,0 +1,94 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_new - create a new SSL_CTX object as framework for TLS/SSL enabled functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ SSL_CTX *SSL_CTX_new(const SSL_METHOD *method);
+
+=head1 DESCRIPTION
+
+SSL_CTX_new() creates a new B<SSL_CTX> object as framework to establish
+TLS/SSL enabled connections.
+
+=head1 NOTES
+
+The SSL_CTX object uses B<method> as connection method. The methods exist
+in a generic type (for client and server use), a server only type, and a
+client only type. B<method> can be of the following types:
+
+=over 4
+
+=item SSLv2_method(void), SSLv2_server_method(void), SSLv2_client_method(void)
+
+A TLS/SSL connection established with these methods will only understand
+the SSLv2 protocol. A client will send out SSLv2 client hello messages
+and will also indicate that it only understand SSLv2. A server will only
+understand SSLv2 client hello messages.
+
+=item SSLv3_method(void), SSLv3_server_method(void), SSLv3_client_method(void)
+
+A TLS/SSL connection established with these methods will only understand the
+SSLv3 protocol. A client will send out SSLv3 client hello messages
+and will indicate that it only understands SSLv3. A server will only understand
+SSLv3 client hello messages. This especially means, that it will
+not understand SSLv2 client hello messages which are widely used for
+compatibility reasons, see SSLv23_*_method().
+
+=item TLSv1_method(void), TLSv1_server_method(void), TLSv1_client_method(void)
+
+A TLS/SSL connection established with these methods will only understand the
+TLSv1 protocol. A client will send out TLSv1 client hello messages
+and will indicate that it only understands TLSv1. A server will only understand
+TLSv1 client hello messages. This especially means, that it will
+not understand SSLv2 client hello messages which are widely used for
+compatibility reasons, see SSLv23_*_method(). It will also not understand
+SSLv3 client hello messages.
+
+=item SSLv23_method(void), SSLv23_server_method(void), SSLv23_client_method(void)
+
+A TLS/SSL connection established with these methods will understand the SSLv2,
+SSLv3, and TLSv1 protocol. A client will send out SSLv2 client hello messages
+and will indicate that it also understands SSLv3 and TLSv1. A server will
+understand SSLv2, SSLv3, and TLSv1 client hello messages. This is the best
+choice when compatibility is a concern.
+
+=back
+
+The list of protocols available can later be limited using the SSL_OP_NO_SSLv2,
+SSL_OP_NO_SSLv3, SSL_OP_NO_TLSv1 options of the B<SSL_CTX_set_options()> or
+B<SSL_set_options()> functions. Using these options it is possible to choose
+e.g. SSLv23_server_method() and be able to negotiate with all possible
+clients, but to only allow newer protocols like SSLv3 or TLSv1.
+
+SSL_CTX_new() initializes the list of ciphers, the session cache setting,
+the callbacks, the keys and certificates, and the options to its default
+values.
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item NULL
+
+The creation of a new SSL_CTX object failed. Check the error stack to
+find out the reason.
+
+=item Pointer to an SSL_CTX object
+
+The return value points to an allocated SSL_CTX object.
+
+=back
+
+=head1 SEE ALSO
+
+L<SSL_CTX_free(3)|SSL_CTX_free(3)>, L<SSL_accept(3)|SSL_accept(3)>,
+L<ssl(3)|ssl(3)>,  L<SSL_set_connect_state(3)|SSL_set_connect_state(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_sess_number.pod b/openssl/doc/ssl/SSL_CTX_sess_number.pod
new file mode 100644
index 0000000..19aa4e2
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_sess_number.pod
@@ -0,0 +1,76 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_sess_number, SSL_CTX_sess_connect, SSL_CTX_sess_connect_good, SSL_CTX_sess_connect_renegotiate, SSL_CTX_sess_accept, SSL_CTX_sess_accept_good, SSL_CTX_sess_accept_renegotiate, SSL_CTX_sess_hits, SSL_CTX_sess_cb_hits, SSL_CTX_sess_misses, SSL_CTX_sess_timeouts, SSL_CTX_sess_cache_full - obtain session cache statistics
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ long SSL_CTX_sess_number(SSL_CTX *ctx);
+ long SSL_CTX_sess_connect(SSL_CTX *ctx);
+ long SSL_CTX_sess_connect_good(SSL_CTX *ctx);
+ long SSL_CTX_sess_connect_renegotiate(SSL_CTX *ctx);
+ long SSL_CTX_sess_accept(SSL_CTX *ctx);
+ long SSL_CTX_sess_accept_good(SSL_CTX *ctx);
+ long SSL_CTX_sess_accept_renegotiate(SSL_CTX *ctx);
+ long SSL_CTX_sess_hits(SSL_CTX *ctx);
+ long SSL_CTX_sess_cb_hits(SSL_CTX *ctx);
+ long SSL_CTX_sess_misses(SSL_CTX *ctx);
+ long SSL_CTX_sess_timeouts(SSL_CTX *ctx);
+ long SSL_CTX_sess_cache_full(SSL_CTX *ctx);
+
+=head1 DESCRIPTION
+
+SSL_CTX_sess_number() returns the current number of sessions in the internal
+session cache.
+
+SSL_CTX_sess_connect() returns the number of started SSL/TLS handshakes in
+client mode.
+
+SSL_CTX_sess_connect_good() returns the number of successfully established
+SSL/TLS sessions in client mode.
+
+SSL_CTX_sess_connect_renegotiate() returns the number of start renegotiations
+in client mode.
+
+SSL_CTX_sess_accept() returns the number of started SSL/TLS handshakes in
+server mode.
+
+SSL_CTX_sess_accept_good() returns the number of successfully established
+SSL/TLS sessions in server mode.
+
+SSL_CTX_sess_accept_renegotiate() returns the number of start renegotiations
+in server mode.
+
+SSL_CTX_sess_hits() returns the number of successfully reused sessions.
+In client mode a session set with L<SSL_set_session(3)|SSL_set_session(3)>
+successfully reused is counted as a hit. In server mode a session successfully
+retrieved from internal or external cache is counted as a hit.
+
+SSL_CTX_sess_cb_hits() returns the number of successfully retrieved sessions
+from the external session cache in server mode.
+
+SSL_CTX_sess_misses() returns the number of sessions proposed by clients
+that were not found in the internal session cache in server mode.
+
+SSL_CTX_sess_timeouts() returns the number of sessions proposed by clients
+and either found in the internal or external session cache in server mode,
+ but that were invalid due to timeout. These sessions are not included in
+the SSL_CTX_sess_hits() count.
+
+SSL_CTX_sess_cache_full() returns the number of sessions that were removed
+because the maximum session cache size was exceeded.
+
+=head1 RETURN VALUES
+
+The functions return the values indicated in the DESCRIPTION section.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_set_session(3)|SSL_set_session(3)>,
+L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>
+L<SSL_CTX_sess_set_cache_size(3)|SSL_CTX_sess_set_cache_size(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_sess_set_cache_size.pod b/openssl/doc/ssl/SSL_CTX_sess_set_cache_size.pod
new file mode 100644
index 0000000..c8b99f4
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_sess_set_cache_size.pod
@@ -0,0 +1,51 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_sess_set_cache_size, SSL_CTX_sess_get_cache_size - manipulate session cache size
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx, long t);
+ long SSL_CTX_sess_get_cache_size(SSL_CTX *ctx);
+
+=head1 DESCRIPTION
+
+SSL_CTX_sess_set_cache_size() sets the size of the internal session cache
+of context B<ctx> to B<t>.
+
+SSL_CTX_sess_get_cache_size() returns the currently valid session cache size.
+
+=head1 NOTES
+
+The internal session cache size is SSL_SESSION_CACHE_MAX_SIZE_DEFAULT,
+currently 1024*20, so that up to 20000 sessions can be held. This size
+can be modified using the SSL_CTX_sess_set_cache_size() call. A special
+case is the size 0, which is used for unlimited size.
+
+When the maximum number of sessions is reached, no more new sessions are
+added to the cache. New space may be added by calling
+L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)> to remove
+expired sessions.
+
+If the size of the session cache is reduced and more sessions are already
+in the session cache, old session will be removed at the next time a
+session shall be added. This removal is not synchronized with the
+expiration of sessions.
+
+=head1 RETURN VALUES
+
+SSL_CTX_sess_set_cache_size() returns the previously valid size.
+
+SSL_CTX_sess_get_cache_size() returns the currently valid size.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>,
+L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
+L<SSL_CTX_sess_number(3)|SSL_CTX_sess_number(3)>,
+L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_sess_set_get_cb.pod b/openssl/doc/ssl/SSL_CTX_sess_set_get_cb.pod
new file mode 100644
index 0000000..b9d54a4
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_sess_set_get_cb.pod
@@ -0,0 +1,87 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_sess_set_new_cb, SSL_CTX_sess_set_remove_cb, SSL_CTX_sess_set_get_cb, SSL_CTX_sess_get_new_cb, SSL_CTX_sess_get_remove_cb, SSL_CTX_sess_get_get_cb - provide callback functions for server side external session caching
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
+			      int (*new_session_cb)(SSL *, SSL_SESSION *));
+ void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
+	   void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *));
+ void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
+	   SSL_SESSION (*get_session_cb)(SSL *, unsigned char *, int, int *));
+
+ int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl, SSL_SESSION *sess);
+ void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(struct ssl_ctx_st *ctx, SSL_SESSION *sess);
+ SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(struct ssl_st *ssl, unsigned char *data, int len, int *copy);
+
+ int (*new_session_cb)(struct ssl_st *ssl, SSL_SESSION *sess);
+ void (*remove_session_cb)(struct ssl_ctx_st *ctx, SSL_SESSION *sess);
+ SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl, unsigned char *data,
+	       int len, int *copy);
+
+=head1 DESCRIPTION
+
+SSL_CTX_sess_set_new_cb() sets the callback function, which is automatically
+called whenever a new session was negotiated.
+
+SSL_CTX_sess_set_remove_cb() sets the callback function, which is
+automatically called whenever a session is removed by the SSL engine,
+because it is considered faulty or the session has become obsolete because
+of exceeding the timeout value.
+
+SSL_CTX_sess_set_get_cb() sets the callback function which is called,
+whenever a SSL/TLS client proposed to resume a session but the session
+could not be found in the internal session cache (see
+L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>).
+(SSL/TLS server only.)
+
+SSL_CTX_sess_get_new_cb(), SSL_CTX_sess_get_remove_cb(), and
+SSL_CTX_sess_get_get_cb() allow to retrieve the function pointers of the
+provided callback functions. If a callback function has not been set,
+the NULL pointer is returned.
+
+=head1 NOTES
+
+In order to allow external session caching, synchronization with the internal
+session cache is realized via callback functions. Inside these callback
+functions, session can be saved to disk or put into a database using the
+L<d2i_SSL_SESSION(3)|d2i_SSL_SESSION(3)> interface.
+
+The new_session_cb() is called, whenever a new session has been negotiated
+and session caching is enabled (see
+L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>).
+The new_session_cb() is passed the B<ssl> connection and the ssl session
+B<sess>. If the callback returns B<0>, the session will be immediately
+removed again.
+
+The remove_session_cb() is called, whenever the SSL engine removes a session
+from the internal cache. This happens when the session is removed because
+it is expired or when a connection was not shutdown cleanly. It also happens
+for all sessions in the internal session cache when
+L<SSL_CTX_free(3)|SSL_CTX_free(3)> is called. The remove_session_cb() is passed
+the B<ctx> and the ssl session B<sess>. It does not provide any feedback.
+
+The get_session_cb() is only called on SSL/TLS servers with the session id
+proposed by the client. The get_session_cb() is always called, also when
+session caching was disabled. The get_session_cb() is passed the
+B<ssl> connection, the session id of length B<length> at the memory location
+B<data>. With the parameter B<copy> the callback can require the
+SSL engine to increment the reference count of the SSL_SESSION object,
+Normally the reference count is not incremented and therefore the
+session must not be explicitly freed with
+L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<d2i_SSL_SESSION(3)|d2i_SSL_SESSION(3)>,
+L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
+L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)>,
+L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>,
+L<SSL_CTX_free(3)|SSL_CTX_free(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_sessions.pod b/openssl/doc/ssl/SSL_CTX_sessions.pod
new file mode 100644
index 0000000..e05aab3
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_sessions.pod
@@ -0,0 +1,34 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_sessions - access internal session cache
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ struct lhash_st *SSL_CTX_sessions(SSL_CTX *ctx);
+
+=head1 DESCRIPTION
+
+SSL_CTX_sessions() returns a pointer to the lhash databases containing the
+internal session cache for B<ctx>.
+
+=head1 NOTES
+
+The sessions in the internal session cache are kept in an
+L<lhash(3)|lhash(3)> type database. It is possible to directly
+access this database e.g. for searching. In parallel, the sessions
+form a linked list which is maintained separately from the
+L<lhash(3)|lhash(3)> operations, so that the database must not be
+modified directly but by using the
+L<SSL_CTX_add_session(3)|SSL_CTX_add_session(3)> family of functions.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<lhash(3)|lhash(3)>,
+L<SSL_CTX_add_session(3)|SSL_CTX_add_session(3)>,
+L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_cert_store.pod b/openssl/doc/ssl/SSL_CTX_set_cert_store.pod
new file mode 100644
index 0000000..6acf0d9
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_cert_store.pod
@@ -0,0 +1,57 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_cert_store, SSL_CTX_get_cert_store - manipulate X509 certificate verification storage
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store);
+ X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_cert_store() sets/replaces the certificate verification storage
+of B<ctx> to/with B<store>. If another X509_STORE object is currently
+set in B<ctx>, it will be X509_STORE_free()ed.
+
+SSL_CTX_get_cert_store() returns a pointer to the current certificate
+verification storage.
+
+=head1 NOTES
+
+In order to verify the certificates presented by the peer, trusted CA
+certificates must be accessed. These CA certificates are made available
+via lookup methods, handled inside the X509_STORE. From the X509_STORE
+the X509_STORE_CTX used when verifying certificates is created.
+
+Typically the trusted certificate store is handled indirectly via using
+L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>.
+Using the SSL_CTX_set_cert_store() and SSL_CTX_get_cert_store() functions
+it is possible to manipulate the X509_STORE object beyond the
+L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>
+call.
+
+Currently no detailed documentation on how to use the X509_STORE
+object is available. Not all members of the X509_STORE are used when
+the verification takes place. So will e.g. the verify_callback() be
+overridden with the verify_callback() set via the
+L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)> family of functions.
+This document must therefore be updated when documentation about the
+X509_STORE object and its handling becomes available.
+
+=head1 RETURN VALUES
+
+SSL_CTX_set_cert_store() does not return diagnostic output.
+
+SSL_CTX_get_cert_store() returns the current setting.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>,
+L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>,
+L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_cert_verify_callback.pod b/openssl/doc/ssl/SSL_CTX_set_cert_verify_callback.pod
new file mode 100644
index 0000000..c0f4f85
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_cert_verify_callback.pod
@@ -0,0 +1,75 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_cert_verify_callback - set peer certificate verification procedure
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*callback)(X509_STORE_CTX *,void *), void *arg);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_cert_verify_callback() sets the verification callback function for
+I<ctx>. SSL objects that are created from I<ctx> inherit the setting valid at
+the time when L<SSL_new(3)|SSL_new(3)> is called.
+
+=head1 NOTES
+
+Whenever a certificate is verified during a SSL/TLS handshake, a verification
+function is called. If the application does not explicitly specify a
+verification callback function, the built-in verification function is used.
+If a verification callback I<callback> is specified via
+SSL_CTX_set_cert_verify_callback(), the supplied callback function is called
+instead. By setting I<callback> to NULL, the default behaviour is restored.
+
+When the verification must be performed, I<callback> will be called with
+the arguments callback(X509_STORE_CTX *x509_store_ctx, void *arg). The 
+argument I<arg> is specified by the application when setting I<callback>.
+
+I<callback> should return 1 to indicate verification success and 0 to
+indicate verification failure. If SSL_VERIFY_PEER is set and I<callback>
+returns 0, the handshake will fail. As the verification procedure may
+allow to continue the connection in case of failure (by always returning 1)
+the verification result must be set in any case using the B<error>
+member of I<x509_store_ctx> so that the calling application will be informed
+about the detailed result of the verification procedure! 
+
+Within I<x509_store_ctx>, I<callback> has access to the I<verify_callback>
+function set using L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>.
+
+=head1 WARNINGS
+
+Do not mix the verification callback described in this function with the
+B<verify_callback> function called during the verification process. The
+latter is set using the L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>
+family of functions.
+
+Providing a complete verification procedure including certificate purpose
+settings etc is a complex task. The built-in procedure is quite powerful
+and in most cases it should be sufficient to modify its behaviour using
+the B<verify_callback> function.
+
+=head1 BUGS
+
+=head1 RETURN VALUES
+
+SSL_CTX_set_cert_verify_callback() does not provide diagnostic information.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>,
+L<SSL_get_verify_result(3)|SSL_get_verify_result(3)>,
+L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>
+
+=head1 HISTORY
+
+Previous to OpenSSL 0.9.7, the I<arg> argument to B<SSL_CTX_set_cert_verify_callback>
+was ignored, and I<callback> was called simply as
+ int (*callback)(X509_STORE_CTX *)
+To compile software written for previous versions of OpenSSL, a dummy
+argument will have to be added to I<callback>.
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_cipher_list.pod b/openssl/doc/ssl/SSL_CTX_set_cipher_list.pod
new file mode 100644
index 0000000..ed64f64
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_cipher_list.pod
@@ -0,0 +1,70 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_cipher_list, SSL_set_cipher_list - choose list of available SSL_CIPHERs
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str);
+ int SSL_set_cipher_list(SSL *ssl, const char *str);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_cipher_list() sets the list of available ciphers for B<ctx>
+using the control string B<str>. The format of the string is described
+in L<ciphers(1)|ciphers(1)>. The list of ciphers is inherited by all
+B<ssl> objects created from B<ctx>.
+
+SSL_set_cipher_list() sets the list of ciphers only for B<ssl>.
+
+=head1 NOTES
+
+The control string B<str> should be universally usable and not depend
+on details of the library configuration (ciphers compiled in). Thus no
+syntax checking takes place. Items that are not recognized, because the
+corresponding ciphers are not compiled in or because they are mistyped,
+are simply ignored. Failure is only flagged if no ciphers could be collected
+at all.
+
+It should be noted, that inclusion of a cipher to be used into the list is
+a necessary condition. On the client side, the inclusion into the list is
+also sufficient. On the server side, additional restrictions apply. All ciphers
+have additional requirements. ADH ciphers don't need a certificate, but
+DH-parameters must have been set. All other ciphers need a corresponding
+certificate and key.
+
+A RSA cipher can only be chosen, when a RSA certificate is available.
+RSA export ciphers with a keylength of 512 bits for the RSA key require
+a temporary 512 bit RSA key, as typically the supplied key has a length
+of 1024 bit (see
+L<SSL_CTX_set_tmp_rsa_callback(3)|SSL_CTX_set_tmp_rsa_callback(3)>).
+RSA ciphers using EDH need a certificate and key and additional DH-parameters
+(see L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>).
+
+A DSA cipher can only be chosen, when a DSA certificate is available.
+DSA ciphers always use DH key exchange and therefore need DH-parameters
+(see L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>).
+
+When these conditions are not met for any cipher in the list (e.g. a
+client only supports export RSA ciphers with a asymmetric key length
+of 512 bits and the server is not configured to use temporary RSA
+keys), the "no shared cipher" (SSL_R_NO_SHARED_CIPHER) error is generated
+and the handshake will fail.
+
+=head1 RETURN VALUES
+
+SSL_CTX_set_cipher_list() and SSL_set_cipher_list() return 1 if any cipher
+could be selected and 0 on complete failure.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_get_ciphers(3)|SSL_get_ciphers(3)>,
+L<SSL_CTX_use_certificate(3)|SSL_CTX_use_certificate(3)>,
+L<SSL_CTX_set_tmp_rsa_callback(3)|SSL_CTX_set_tmp_rsa_callback(3)>,
+L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>,
+L<ciphers(1)|ciphers(1)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_client_CA_list.pod b/openssl/doc/ssl/SSL_CTX_set_client_CA_list.pod
new file mode 100644
index 0000000..632b556
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_client_CA_list.pod
@@ -0,0 +1,94 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_client_CA_list, SSL_set_client_CA_list, SSL_CTX_add_client_CA,
+SSL_add_client_CA - set list of CAs sent to the client when requesting a
+client certificate
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+ 
+ void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *list);
+ void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *list);
+ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *cacert);
+ int SSL_add_client_CA(SSL *ssl, X509 *cacert);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_client_CA_list() sets the B<list> of CAs sent to the client when
+requesting a client certificate for B<ctx>.
+
+SSL_set_client_CA_list() sets the B<list> of CAs sent to the client when
+requesting a client certificate for the chosen B<ssl>, overriding the
+setting valid for B<ssl>'s SSL_CTX object.
+
+SSL_CTX_add_client_CA() adds the CA name extracted from B<cacert> to the
+list of CAs sent to the client when requesting a client certificate for
+B<ctx>.
+
+SSL_add_client_CA() adds the CA name extracted from B<cacert> to the
+list of CAs sent to the client when requesting a client certificate for
+the chosen B<ssl>, overriding the setting valid for B<ssl>'s SSL_CTX object.
+
+=head1 NOTES
+
+When a TLS/SSL server requests a client certificate (see
+B<SSL_CTX_set_verify_options()>), it sends a list of CAs, for which
+it will accept certificates, to the client.
+
+This list must explicitly be set using SSL_CTX_set_client_CA_list() for
+B<ctx> and SSL_set_client_CA_list() for the specific B<ssl>. The list
+specified overrides the previous setting. The CAs listed do not become
+trusted (B<list> only contains the names, not the complete certificates); use
+L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)> 
+to additionally load them for verification.
+
+If the list of acceptable CAs is compiled in a file, the
+L<SSL_load_client_CA_file(3)|SSL_load_client_CA_file(3)>
+function can be used to help importing the necessary data.
+
+SSL_CTX_add_client_CA() and SSL_add_client_CA() can be used to add additional
+items the list of client CAs. If no list was specified before using
+SSL_CTX_set_client_CA_list() or SSL_set_client_CA_list(), a new client
+CA list for B<ctx> or B<ssl> (as appropriate) is opened.
+
+These functions are only useful for TLS/SSL servers.
+
+=head1 RETURN VALUES
+
+SSL_CTX_set_client_CA_list() and SSL_set_client_CA_list() do not return
+diagnostic information.
+
+SSL_CTX_add_client_CA() and SSL_add_client_CA() have the following return
+values:
+
+=over 4
+
+=item 1
+
+The operation succeeded.
+
+=item 0
+
+A failure while manipulating the STACK_OF(X509_NAME) object occurred or
+the X509_NAME could not be extracted from B<cacert>. Check the error stack
+to find out the reason.
+
+=back
+
+=head1 EXAMPLES
+
+Scan all certificates in B<CAfile> and list them as acceptable CAs:
+
+  SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>,
+L<SSL_get_client_CA_list(3)|SSL_get_client_CA_list(3)>,
+L<SSL_load_client_CA_file(3)|SSL_load_client_CA_file(3)>,
+L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_client_cert_cb.pod b/openssl/doc/ssl/SSL_CTX_set_client_cert_cb.pod
new file mode 100644
index 0000000..3465b5c
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_client_cert_cb.pod
@@ -0,0 +1,94 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_client_cert_cb, SSL_CTX_get_client_cert_cb - handle client certificate callback function
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
+ int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+ int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_client_cert_cb() sets the B<client_cert_cb()> callback, that is
+called when a client certificate is requested by a server and no certificate
+was yet set for the SSL object.
+
+When B<client_cert_cb()> is NULL, no callback function is used.
+
+SSL_CTX_get_client_cert_cb() returns a pointer to the currently set callback
+function.
+
+client_cert_cb() is the application defined callback. If it wants to
+set a certificate, a certificate/private key combination must be set
+using the B<x509> and B<pkey> arguments and "1" must be returned. The
+certificate will be installed into B<ssl>, see the NOTES and BUGS sections.
+If no certificate should be set, "0" has to be returned and no certificate
+will be sent. A negative return value will suspend the handshake and the
+handshake function will return immediatly. L<SSL_get_error(3)|SSL_get_error(3)>
+will return SSL_ERROR_WANT_X509_LOOKUP to indicate, that the handshake was
+suspended. The next call to the handshake function will again lead to the call
+of client_cert_cb(). It is the job of the client_cert_cb() to store information
+about the state of the last call, if required to continue.
+
+=head1 NOTES
+
+During a handshake (or renegotiation) a server may request a certificate
+from the client. A client certificate must only be sent, when the server
+did send the request.
+
+When a certificate was set using the
+L<SSL_CTX_use_certificate(3)|SSL_CTX_use_certificate(3)> family of functions,
+it will be sent to the server. The TLS standard requires that only a
+certificate is sent, if it matches the list of acceptable CAs sent by the
+server. This constraint is violated by the default behavior of the OpenSSL
+library. Using the callback function it is possible to implement a proper
+selection routine or to allow a user interaction to choose the certificate to
+be sent.
+
+If a callback function is defined and no certificate was yet defined for the
+SSL object, the callback function will be called.
+If the callback function returns a certificate, the OpenSSL library
+will try to load the private key and certificate data into the SSL
+object using the SSL_use_certificate() and SSL_use_private_key() functions.
+Thus it will permanently install the certificate and key for this SSL
+object. It will not be reset by calling L<SSL_clear(3)|SSL_clear(3)>.
+If the callback returns no certificate, the OpenSSL library will not send
+a certificate.
+
+=head1 BUGS
+
+The client_cert_cb() cannot return a complete certificate chain, it can
+only return one client certificate. If the chain only has a length of 2,
+the root CA certificate may be omitted according to the TLS standard and
+thus a standard conforming answer can be sent to the server. For a
+longer chain, the client must send the complete chain (with the option
+to leave out the root CA certificate). This can only be accomplished by
+either adding the intermediate CA certificates into the trusted
+certificate store for the SSL_CTX object (resulting in having to add
+CA certificates that otherwise maybe would not be trusted), or by adding
+the chain certificates using the
+L<SSL_CTX_add_extra_chain_cert(3)|SSL_CTX_add_extra_chain_cert(3)>
+function, which is only available for the SSL_CTX object as a whole and that
+therefore probably can only apply for one client certificate, making
+the concept of the callback function (to allow the choice from several
+certificates) questionable.
+
+Once the SSL object has been used in conjunction with the callback function,
+the certificate will be set for the SSL object and will not be cleared
+even when L<SSL_clear(3)|SSL_clear(3)> is being called. It is therefore
+mandatory to destroy the SSL object using L<SSL_free(3)|SSL_free(3)>
+and create a new one to return to the previous state.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_CTX_use_certificate(3)|SSL_CTX_use_certificate(3)>,
+L<SSL_CTX_add_extra_chain_cert(3)|SSL_CTX_add_extra_chain_cert(3)>,
+L<SSL_get_client_CA_list(3)|SSL_get_client_CA_list(3)>,
+L<SSL_clear(3)|SSL_clear(3)>, L<SSL_free(3)|SSL_free(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_default_passwd_cb.pod b/openssl/doc/ssl/SSL_CTX_set_default_passwd_cb.pod
new file mode 100644
index 0000000..2b87f01
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_default_passwd_cb.pod
@@ -0,0 +1,76 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_default_passwd_cb, SSL_CTX_set_default_passwd_cb_userdata - set passwd callback for encrypted PEM file handling
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb);
+ void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u);
+
+ int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_default_passwd_cb() sets the default password callback called
+when loading/storing a PEM certificate with encryption.
+
+SSL_CTX_set_default_passwd_cb_userdata() sets a pointer to B<userdata> which
+will be provided to the password callback on invocation.
+
+The pem_passwd_cb(), which must be provided by the application, hands back the
+password to be used during decryption. On invocation a pointer to B<userdata>
+is provided. The pem_passwd_cb must write the password into the provided buffer
+B<buf> which is of size B<size>. The actual length of the password must
+be returned to the calling function. B<rwflag> indicates whether the
+callback is used for reading/decryption (rwflag=0) or writing/encryption
+(rwflag=1).
+
+=head1 NOTES
+
+When loading or storing private keys, a password might be supplied to
+protect the private key. The way this password can be supplied may depend
+on the application. If only one private key is handled, it can be practical
+to have pem_passwd_cb() handle the password dialog interactively. If several
+keys have to be handled, it can be practical to ask for the password once,
+then keep it in memory and use it several times. In the last case, the
+password could be stored into the B<userdata> storage and the
+pem_passwd_cb() only returns the password already stored.
+
+When asking for the password interactively, pem_passwd_cb() can use
+B<rwflag> to check, whether an item shall be encrypted (rwflag=1).
+In this case the password dialog may ask for the same password twice
+for comparison in order to catch typos, that would make decryption
+impossible.
+
+Other items in PEM formatting (certificates) can also be encrypted, it is
+however not usual, as certificate information is considered public.
+
+=head1 RETURN VALUES
+
+SSL_CTX_set_default_passwd_cb() and SSL_CTX_set_default_passwd_cb_userdata()
+do not provide diagnostic information.
+
+=head1 EXAMPLES
+
+The following example returns the password provided as B<userdata> to the
+calling function. The password is considered to be a '\0' terminated
+string. If the password does not fit into the buffer, the password is
+truncated.
+
+ int pem_passwd_cb(char *buf, int size, int rwflag, void *password)
+ {
+  strncpy(buf, (char *)(password), size);
+  buf[size - 1] = '\0';
+  return(strlen(buf));
+ }
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>,
+L<SSL_CTX_use_certificate(3)|SSL_CTX_use_certificate(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_generate_session_id.pod b/openssl/doc/ssl/SSL_CTX_set_generate_session_id.pod
new file mode 100644
index 0000000..798e844
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_generate_session_id.pod
@@ -0,0 +1,150 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_generate_session_id, SSL_set_generate_session_id, SSL_has_matching_session_id - manipulate generation of SSL session IDs (server only)
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ typedef int (*GEN_SESSION_CB)(const SSL *ssl, unsigned char *id,
+                               unsigned int *id_len);
+
+ int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb);
+ int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB, cb);
+ int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
+				 unsigned int id_len);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_generate_session_id() sets the callback function for generating
+new session ids for SSL/TLS sessions for B<ctx> to be B<cb>.
+
+SSL_set_generate_session_id() sets the callback function for generating
+new session ids for SSL/TLS sessions for B<ssl> to be B<cb>.
+
+SSL_has_matching_session_id() checks, whether a session with id B<id>
+(of length B<id_len>) is already contained in the internal session cache
+of the parent context of B<ssl>.
+
+=head1 NOTES
+
+When a new session is established between client and server, the server
+generates a session id. The session id is an arbitrary sequence of bytes.
+The length of the session id is 16 bytes for SSLv2 sessions and between
+1 and 32 bytes for SSLv3/TLSv1. The session id is not security critical
+but must be unique for the server. Additionally, the session id is
+transmitted in the clear when reusing the session so it must not contain
+sensitive information.
+
+Without a callback being set, an OpenSSL server will generate a unique
+session id from pseudo random numbers of the maximum possible length.
+Using the callback function, the session id can be changed to contain
+additional information like e.g. a host id in order to improve load balancing
+or external caching techniques.
+
+The callback function receives a pointer to the memory location to put
+B<id> into and a pointer to the maximum allowed length B<id_len>. The
+buffer at location B<id> is only guaranteed to have the size B<id_len>.
+The callback is only allowed to generate a shorter id and reduce B<id_len>;
+the callback B<must never> increase B<id_len> or write to the location
+B<id> exceeding the given limit.
+
+If a SSLv2 session id is generated and B<id_len> is reduced, it will be
+restored after the callback has finished and the session id will be padded
+with 0x00. It is not recommended to change the B<id_len> for SSLv2 sessions.
+The callback can use the L<SSL_get_version(3)|SSL_get_version(3)> function
+to check, whether the session is of type SSLv2.
+
+The location B<id> is filled with 0x00 before the callback is called, so the
+callback may only fill part of the possible length and leave B<id_len>
+untouched while maintaining reproducibility.
+
+Since the sessions must be distinguished, session ids must be unique.
+Without the callback a random number is used, so that the probability
+of generating the same session id is extremely small (2^128 possible ids
+for an SSLv2 session, 2^256 for SSLv3/TLSv1). In order to assure the
+uniqueness of the generated session id, the callback must call
+SSL_has_matching_session_id() and generate another id if a conflict occurs.
+If an id conflict is not resolved, the handshake will fail.
+If the application codes e.g. a unique host id, a unique process number, and
+a unique sequence number into the session id, uniqueness could easily be
+achieved without randomness added (it should however be taken care that
+no confidential information is leaked this way). If the application can not
+guarantee uniqueness, it is recommended to use the maximum B<id_len> and
+fill in the bytes not used to code special information with random data
+to avoid collisions.
+
+SSL_has_matching_session_id() will only query the internal session cache,
+not the external one. Since the session id is generated before the
+handshake is completed, it is not immediately added to the cache. If
+another thread is using the same internal session cache, a race condition
+can occur in that another thread generates the same session id.
+Collisions can also occur when using an external session cache, since
+the external cache is not tested with SSL_has_matching_session_id()
+and the same race condition applies.
+
+When calling SSL_has_matching_session_id() for an SSLv2 session with
+reduced B<id_len>, the match operation will be performed using the
+fixed length required and with a 0x00 padded id.
+
+The callback must return 0 if it cannot generate a session id for whatever
+reason and return 1 on success.
+
+=head1 EXAMPLES
+
+The callback function listed will generate a session id with the
+server id given, and will fill the rest with pseudo random bytes:
+
+ const char session_id_prefix = "www-18";
+
+ #define MAX_SESSION_ID_ATTEMPTS 10
+ static int generate_session_id(const SSL *ssl, unsigned char *id,
+                              unsigned int *id_len)
+      {
+      unsigned int count = 0;
+      const char *version;
+
+      version = SSL_get_version(ssl);
+      if (!strcmp(version, "SSLv2"))
+	  /* we must not change id_len */;
+
+      do      {
+              RAND_pseudo_bytes(id, *id_len);
+              /* Prefix the session_id with the required prefix. NB: If our
+               * prefix is too long, clip it - but there will be worse effects
+               * anyway, eg. the server could only possibly create 1 session
+               * ID (ie. the prefix!) so all future session negotiations will
+               * fail due to conflicts. */
+              memcpy(id, session_id_prefix,
+                      (strlen(session_id_prefix) < *id_len) ?
+                      strlen(session_id_prefix) : *id_len);
+              }
+      while(SSL_has_matching_session_id(ssl, id, *id_len) &&
+              (++count < MAX_SESSION_ID_ATTEMPTS));
+      if(count >= MAX_SESSION_ID_ATTEMPTS)
+              return 0;
+      return 1;
+      }
+
+
+=head1 RETURN VALUES
+
+SSL_CTX_set_generate_session_id() and SSL_set_generate_session_id()
+always return 1.
+
+SSL_has_matching_session_id() returns 1 if another session with the
+same id is already in the cache.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_get_version(3)|SSL_get_version(3)>
+
+=head1 HISTORY
+
+SSL_CTX_set_generate_session_id(), SSL_set_generate_session_id()
+and SSL_has_matching_session_id() have been introduced in
+OpenSSL 0.9.7.
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_info_callback.pod b/openssl/doc/ssl/SSL_CTX_set_info_callback.pod
new file mode 100644
index 0000000..0b4affd
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_info_callback.pod
@@ -0,0 +1,153 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_info_callback, SSL_CTX_get_info_callback, SSL_set_info_callback, SSL_get_info_callback - handle information callback for SSL connections
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_CTX_set_info_callback(SSL_CTX *ctx, void (*callback)());
+ void (*SSL_CTX_get_info_callback(const SSL_CTX *ctx))();
+
+ void SSL_set_info_callback(SSL *ssl, void (*callback)());
+ void (*SSL_get_info_callback(const SSL *ssl))();
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_info_callback() sets the B<callback> function, that can be used to
+obtain state information for SSL objects created from B<ctx> during connection
+setup and use. The setting for B<ctx> is overridden from the setting for
+a specific SSL object, if specified.
+When B<callback> is NULL, not callback function is used.
+
+SSL_set_info_callback() sets the B<callback> function, that can be used to
+obtain state information for B<ssl> during connection setup and use.
+When B<callback> is NULL, the callback setting currently valid for
+B<ctx> is used.
+
+SSL_CTX_get_info_callback() returns a pointer to the currently set information
+callback function for B<ctx>.
+
+SSL_get_info_callback() returns a pointer to the currently set information
+callback function for B<ssl>.
+
+=head1 NOTES
+
+When setting up a connection and during use, it is possible to obtain state
+information from the SSL/TLS engine. When set, an information callback function
+is called whenever the state changes, an alert appears, or an error occurs.
+
+The callback function is called as B<callback(SSL *ssl, int where, int ret)>.
+The B<where> argument specifies information about where (in which context)
+the callback function was called. If B<ret> is 0, an error condition occurred.
+If an alert is handled, SSL_CB_ALERT is set and B<ret> specifies the alert
+information.
+
+B<where> is a bitmask made up of the following bits:
+
+=over 4
+
+=item SSL_CB_LOOP
+
+Callback has been called to indicate state change inside a loop.
+
+=item SSL_CB_EXIT
+
+Callback has been called to indicate error exit of a handshake function.
+(May be soft error with retry option for non-blocking setups.)
+
+=item SSL_CB_READ
+
+Callback has been called during read operation.
+
+=item SSL_CB_WRITE
+
+Callback has been called during write operation.
+
+=item SSL_CB_ALERT
+
+Callback has been called due to an alert being sent or received.
+
+=item SSL_CB_READ_ALERT               (SSL_CB_ALERT|SSL_CB_READ)
+
+=item SSL_CB_WRITE_ALERT              (SSL_CB_ALERT|SSL_CB_WRITE)
+
+=item SSL_CB_ACCEPT_LOOP              (SSL_ST_ACCEPT|SSL_CB_LOOP)
+
+=item SSL_CB_ACCEPT_EXIT              (SSL_ST_ACCEPT|SSL_CB_EXIT)
+
+=item SSL_CB_CONNECT_LOOP             (SSL_ST_CONNECT|SSL_CB_LOOP)
+
+=item SSL_CB_CONNECT_EXIT             (SSL_ST_CONNECT|SSL_CB_EXIT)
+
+=item SSL_CB_HANDSHAKE_START
+
+Callback has been called because a new handshake is started.
+
+=item SSL_CB_HANDSHAKE_DONE           0x20
+
+Callback has been called because a handshake is finished.
+
+=back
+
+The current state information can be obtained using the
+L<SSL_state_string(3)|SSL_state_string(3)> family of functions.
+
+The B<ret> information can be evaluated using the
+L<SSL_alert_type_string(3)|SSL_alert_type_string(3)> family of functions.
+
+=head1 RETURN VALUES
+
+SSL_set_info_callback() does not provide diagnostic information.
+
+SSL_get_info_callback() returns the current setting.
+
+=head1 EXAMPLES
+
+The following example callback function prints state strings, information
+about alerts being handled and error messages to the B<bio_err> BIO.
+
+ void apps_ssl_info_callback(SSL *s, int where, int ret)
+	{
+	const char *str;
+	int w;
+
+	w=where& ~SSL_ST_MASK;
+
+	if (w & SSL_ST_CONNECT) str="SSL_connect";
+	else if (w & SSL_ST_ACCEPT) str="SSL_accept";
+	else str="undefined";
+
+	if (where & SSL_CB_LOOP)
+		{
+		BIO_printf(bio_err,"%s:%s\n",str,SSL_state_string_long(s));
+		}
+	else if (where & SSL_CB_ALERT)
+		{
+		str=(where & SSL_CB_READ)?"read":"write";
+		BIO_printf(bio_err,"SSL3 alert %s:%s:%s\n",
+			str,
+			SSL_alert_type_string_long(ret),
+			SSL_alert_desc_string_long(ret));
+		}
+	else if (where & SSL_CB_EXIT)
+		{
+		if (ret == 0)
+			BIO_printf(bio_err,"%s:failed in %s\n",
+				str,SSL_state_string_long(s));
+		else if (ret < 0)
+			{
+			BIO_printf(bio_err,"%s:error in %s\n",
+				str,SSL_state_string_long(s));
+			}
+		}
+	}
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_state_string(3)|SSL_state_string(3)>,
+L<SSL_alert_type_string(3)|SSL_alert_type_string(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_max_cert_list.pod b/openssl/doc/ssl/SSL_CTX_set_max_cert_list.pod
new file mode 100644
index 0000000..da68cb9
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_max_cert_list.pod
@@ -0,0 +1,77 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_max_cert_list, SSL_CTX_get_max_cert_list, SSL_set_max_cert_list, SSL_get_max_cert_list, - manipulate allowed for the peer's certificate chain
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ long SSL_CTX_set_max_cert_list(SSL_CTX *ctx, long size);
+ long SSL_CTX_get_max_cert_list(SSL_CTX *ctx);
+
+ long SSL_set_max_cert_list(SSL *ssl, long size);
+ long SSL_get_max_cert_list(SSL *ctx);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_max_cert_list() sets the maximum size allowed for the peer's
+certificate chain for all SSL objects created from B<ctx> to be <size> bytes.
+The SSL objects inherit the setting valid for B<ctx> at the time
+L<SSL_new(3)|SSL_new(3)> is being called.
+
+SSL_CTX_get_max_cert_list() returns the currently set maximum size for B<ctx>.
+
+SSL_set_max_cert_list() sets the maximum size allowed for the peer's
+certificate chain for B<ssl> to be <size> bytes. This setting stays valid
+until a new value is set.
+
+SSL_get_max_cert_list() returns the currently set maximum size for B<ssl>.
+
+=head1 NOTES
+
+During the handshake process, the peer may send a certificate chain.
+The TLS/SSL standard does not give any maximum size of the certificate chain.
+The OpenSSL library handles incoming data by a dynamically allocated buffer.
+In order to prevent this buffer from growing without bounds due to data
+received from a faulty or malicious peer, a maximum size for the certificate
+chain is set.
+
+The default value for the maximum certificate chain size is 100kB (30kB
+on the 16bit DOS platform). This should be sufficient for usual certificate
+chains (OpenSSL's default maximum chain length is 10, see
+L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>, and certificates
+without special extensions have a typical size of 1-2kB).
+
+For special applications it can be necessary to extend the maximum certificate
+chain size allowed to be sent by the peer, see e.g. the work on
+"Internet X.509 Public Key Infrastructure Proxy Certificate Profile"
+and "TLS Delegation Protocol" at http://www.ietf.org/ and
+http://www.globus.org/ .
+
+Under normal conditions it should never be necessary to set a value smaller
+than the default, as the buffer is handled dynamically and only uses the
+memory actually required by the data sent by the peer.
+
+If the maximum certificate chain size allowed is exceeded, the handshake will
+fail with a SSL_R_EXCESSIVE_MESSAGE_SIZE error.
+
+=head1 RETURN VALUES
+
+SSL_CTX_set_max_cert_list() and SSL_set_max_cert_list() return the previously
+set value.
+
+SSL_CTX_get_max_cert_list() and SSL_get_max_cert_list() return the currently
+set value.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>,
+L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>
+
+=head1 HISTORY
+
+SSL*_set/get_max_cert_list() have been introduced in OpenSSL 0.9.7.
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_mode.pod b/openssl/doc/ssl/SSL_CTX_set_mode.pod
new file mode 100644
index 0000000..8cb669d
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_mode.pod
@@ -0,0 +1,91 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_mode, SSL_set_mode, SSL_CTX_get_mode, SSL_get_mode - manipulate SSL engine mode
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ long SSL_CTX_set_mode(SSL_CTX *ctx, long mode);
+ long SSL_set_mode(SSL *ssl, long mode);
+
+ long SSL_CTX_get_mode(SSL_CTX *ctx);
+ long SSL_get_mode(SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_mode() adds the mode set via bitmask in B<mode> to B<ctx>.
+Options already set before are not cleared.
+
+SSL_set_mode() adds the mode set via bitmask in B<mode> to B<ssl>.
+Options already set before are not cleared.
+
+SSL_CTX_get_mode() returns the mode set for B<ctx>.
+
+SSL_get_mode() returns the mode set for B<ssl>.
+
+=head1 NOTES
+
+The following mode changes are available:
+
+=over 4
+
+=item SSL_MODE_ENABLE_PARTIAL_WRITE
+
+Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success
+when just a single record has been written). When not set (the default),
+SSL_write() will only report success once the complete chunk was written.
+Once SSL_write() returns with r, r bytes have been successfully written
+and the next call to SSL_write() must only send the n-r bytes left,
+imitating the behaviour of write().
+
+=item SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER
+
+Make it possible to retry SSL_write() with changed buffer location
+(the buffer contents must stay the same). This is not the default to avoid
+the misconception that non-blocking SSL_write() behaves like
+non-blocking write().
+
+=item SSL_MODE_AUTO_RETRY
+
+Never bother the application with retries if the transport is blocking.
+If a renegotiation take place during normal operation, a
+L<SSL_read(3)|SSL_read(3)> or L<SSL_write(3)|SSL_write(3)> would return
+with -1 and indicate the need to retry with SSL_ERROR_WANT_READ.
+In a non-blocking environment applications must be prepared to handle
+incomplete read/write operations.
+In a blocking environment, applications are not always prepared to
+deal with read/write operations returning without success report. The
+flag SSL_MODE_AUTO_RETRY will cause read/write operations to only
+return after the handshake and successful completion.
+
+=item SSL_MODE_RELEASE_BUFFERS
+
+When we no longer need a read buffer or a write buffer for a given SSL,
+then release the memory we were using to hold it.  Released memory is
+either appended to a list of unused RAM chunks on the SSL_CTX, or simply
+freed if the list of unused chunks would become longer than 
+SSL_CTX->freelist_max_len, which defaults to 32.  Using this flag can
+save around 34k per idle SSL connection.
+This flag has no effect on SSL v2 connections, or on DTLS connections.
+
+=back
+
+=head1 RETURN VALUES
+
+SSL_CTX_set_mode() and SSL_set_mode() return the new mode bitmask
+after adding B<mode>.
+
+SSL_CTX_get_mode() and SSL_get_mode() return the current bitmask.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_read(3)|SSL_read(3)>, L<SSL_write(3)|SSL_write(3)>
+
+=head1 HISTORY
+
+SSL_MODE_AUTO_RETRY as been added in OpenSSL 0.9.6.
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_msg_callback.pod b/openssl/doc/ssl/SSL_CTX_set_msg_callback.pod
new file mode 100644
index 0000000..0015e6e
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_msg_callback.pod
@@ -0,0 +1,99 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_msg_callback, SSL_CTX_set_msg_callback_arg, SSL_set_msg_callback, SSL_get_msg_callback_arg - install callback for observing protocol messages
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
+ void SSL_CTX_set_msg_callback_arg(SSL_CTX *ctx, void *arg);
+
+ void SSL_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
+ void SSL_set_msg_callback_arg(SSL_CTX *ctx, void *arg);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_msg_callback() or SSL_set_msg_callback() can be used to
+define a message callback function I<cb> for observing all SSL/TLS
+protocol messages (such as handshake messages) that are received or
+sent.  SSL_CTX_set_msg_callback_arg() and SSL_set_msg_callback_arg()
+can be used to set argument I<arg> to the callback function, which is
+available for arbitrary application use.
+
+SSL_CTX_set_msg_callback() and SSL_CTX_set_msg_callback_arg() specify
+default settings that will be copied to new B<SSL> objects by
+L<SSL_new(3)|SSL_new(3)>. SSL_set_msg_callback() and
+SSL_set_msg_callback_arg() modify the actual settings of an B<SSL>
+object. Using a B<0> pointer for I<cb> disables the message callback.
+
+When I<cb> is called by the SSL/TLS library for a protocol message,
+the function arguments have the following meaning:
+
+=over 4
+
+=item I<write_p>
+
+This flag is B<0> when a protocol message has been received and B<1>
+when a protocol message has been sent.
+
+=item I<version>
+
+The protocol version according to which the protocol message is
+interpreted by the library. Currently, this is one of
+B<SSL2_VERSION>, B<SSL3_VERSION> and B<TLS1_VERSION> (for SSL 2.0, SSL
+3.0 and TLS 1.0, respectively).
+
+=item I<content_type>
+
+In the case of SSL 2.0, this is always B<0>.  In the case of SSL 3.0
+or TLS 1.0, this is one of the B<ContentType> values defined in the
+protocol specification (B<change_cipher_spec(20)>, B<alert(21)>,
+B<handshake(22)>; but never B<application_data(23)> because the
+callback will only be called for protocol messages).
+
+=item I<buf>, I<len>
+
+I<buf> points to a buffer containing the protocol message, which
+consists of I<len> bytes. The buffer is no longer valid after the
+callback function has returned.
+
+=item I<ssl>
+
+The B<SSL> object that received or sent the message.
+
+=item I<arg>
+
+The user-defined argument optionally defined by
+SSL_CTX_set_msg_callback_arg() or SSL_set_msg_callback_arg().
+
+=back
+
+=head1 NOTES
+
+Protocol messages are passed to the callback function after decryption
+and fragment collection where applicable. (Thus record boundaries are
+not visible.)
+
+If processing a received protocol message results in an error,
+the callback function may not be called.  For example, the callback
+function will never see messages that are considered too large to be
+processed.
+
+Due to automatic protocol version negotiation, I<version> is not
+necessarily the protocol version used by the sender of the message: If
+a TLS 1.0 ClientHello message is received by an SSL 3.0-only server,
+I<version> will be B<SSL3_VERSION>.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>
+
+=head1 HISTORY
+
+SSL_CTX_set_msg_callback(), SSL_CTX_set_msg_callback_arg(),
+SSL_set_msg_callback() and SSL_get_msg_callback_arg() were added in OpenSSL 0.9.7.
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_options.pod b/openssl/doc/ssl/SSL_CTX_set_options.pod
new file mode 100644
index 0000000..cc588f3
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_options.pod
@@ -0,0 +1,346 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_options, SSL_set_options, SSL_CTX_clear_options, SSL_clear_options, SSL_CTX_get_options, SSL_get_options, SSL_get_secure_renegotiation_support - manipulate SSL options
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ long SSL_CTX_set_options(SSL_CTX *ctx, long options);
+ long SSL_set_options(SSL *ssl, long options);
+
+ long SSL_CTX_clear_options(SSL_CTX *ctx, long options);
+ long SSL_clear_options(SSL *ssl, long options);
+
+ long SSL_CTX_get_options(SSL_CTX *ctx);
+ long SSL_get_options(SSL *ssl);
+
+ long SSL_get_secure_renegotiation_support(SSL *ssl);
+
+=head1 DESCRIPTION
+
+Note: all these functions are implemented using macros.
+
+SSL_CTX_set_options() adds the options set via bitmask in B<options> to B<ctx>.
+Options already set before are not cleared!
+
+SSL_set_options() adds the options set via bitmask in B<options> to B<ssl>.
+Options already set before are not cleared!
+
+SSL_CTX_clear_options() clears the options set via bitmask in B<options>
+to B<ctx>.
+
+SSL_clear_options() clears the options set via bitmask in B<options> to B<ssl>.
+
+SSL_CTX_get_options() returns the options set for B<ctx>.
+
+SSL_get_options() returns the options set for B<ssl>.
+
+SSL_get_secure_renegotiation_support() indicates whether the peer supports
+secure renegotiation.
+
+=head1 NOTES
+
+The behaviour of the SSL library can be changed by setting several options.
+The options are coded as bitmasks and can be combined by a logical B<or>
+operation (|).
+
+SSL_CTX_set_options() and SSL_set_options() affect the (external)
+protocol behaviour of the SSL library. The (internal) behaviour of
+the API can be changed by using the similar
+L<SSL_CTX_set_mode(3)|SSL_CTX_set_mode(3)> and SSL_set_mode() functions.
+
+During a handshake, the option settings of the SSL object are used. When
+a new SSL object is created from a context using SSL_new(), the current
+option setting is copied. Changes to B<ctx> do not affect already created
+SSL objects. SSL_clear() does not affect the settings.
+
+The following B<bug workaround> options are available:
+
+=over 4
+
+=item SSL_OP_MICROSOFT_SESS_ID_BUG
+
+www.microsoft.com - when talking SSLv2, if session-id reuse is
+performed, the session-id passed back in the server-finished message
+is different from the one decided upon.
+
+=item SSL_OP_NETSCAPE_CHALLENGE_BUG
+
+Netscape-Commerce/1.12, when talking SSLv2, accepts a 32 byte
+challenge but then appears to only use 16 bytes when generating the
+encryption keys.  Using 16 bytes is ok but it should be ok to use 32.
+According to the SSLv3 spec, one should use 32 bytes for the challenge
+when operating in SSLv2/v3 compatibility mode, but as mentioned above,
+this breaks this server so 16 bytes is the way to go.
+
+=item SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
+
+As of OpenSSL 0.9.8q and 1.0.0c, this option has no effect.
+
+=item SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
+
+...
+
+=item SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
+
+...
+
+=item SSL_OP_MSIE_SSLV2_RSA_PADDING
+
+As of OpenSSL 0.9.7h and 0.9.8a, this option has no effect.
+
+=item SSL_OP_SSLEAY_080_CLIENT_DH_BUG
+
+...
+
+=item SSL_OP_TLS_D5_BUG
+
+...
+
+=item SSL_OP_TLS_BLOCK_PADDING_BUG
+
+...
+
+=item SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
+
+Disables a countermeasure against a SSL 3.0/TLS 1.0 protocol
+vulnerability affecting CBC ciphers, which cannot be handled by some
+broken SSL implementations.  This option has no effect for connections
+using other ciphers.
+
+=item SSL_OP_ALL
+
+All of the above bug workarounds.
+
+=back
+
+It is usually safe to use B<SSL_OP_ALL> to enable the bug workaround
+options if compatibility with somewhat broken implementations is
+desired.
+
+The following B<modifying> options are available:
+
+=over 4
+
+=item SSL_OP_TLS_ROLLBACK_BUG
+
+Disable version rollback attack detection.
+
+During the client key exchange, the client must send the same information
+about acceptable SSL/TLS protocol levels as during the first hello. Some
+clients violate this rule by adapting to the server's answer. (Example:
+the client sends a SSLv2 hello and accepts up to SSLv3.1=TLSv1, the server
+only understands up to SSLv3. In this case the client must still use the
+same SSLv3.1=TLSv1 announcement. Some clients step down to SSLv3 with respect
+to the server's answer and violate the version rollback protection.)
+
+=item SSL_OP_SINGLE_DH_USE
+
+Always create a new key when using temporary/ephemeral DH parameters
+(see L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>).
+This option must be used to prevent small subgroup attacks, when
+the DH parameters were not generated using "strong" primes
+(e.g. when using DSA-parameters, see L<dhparam(1)|dhparam(1)>).
+If "strong" primes were used, it is not strictly necessary to generate
+a new DH key during each handshake but it is also recommended.
+B<SSL_OP_SINGLE_DH_USE> should therefore be enabled whenever
+temporary/ephemeral DH parameters are used.
+
+=item SSL_OP_EPHEMERAL_RSA
+
+Always use ephemeral (temporary) RSA key when doing RSA operations
+(see L<SSL_CTX_set_tmp_rsa_callback(3)|SSL_CTX_set_tmp_rsa_callback(3)>).
+According to the specifications this is only done, when a RSA key
+can only be used for signature operations (namely under export ciphers
+with restricted RSA keylength). By setting this option, ephemeral
+RSA keys are always used. This option breaks compatibility with the
+SSL/TLS specifications and may lead to interoperability problems with
+clients and should therefore never be used. Ciphers with EDH (ephemeral
+Diffie-Hellman) key exchange should be used instead.
+
+=item SSL_OP_CIPHER_SERVER_PREFERENCE
+
+When choosing a cipher, use the server's preferences instead of the client
+preferences. When not set, the SSL server will always follow the clients
+preferences. When set, the SSLv3/TLSv1 server will choose following its
+own preferences. Because of the different protocol, for SSLv2 the server
+will send its list of preferences to the client and the client chooses.
+
+=item SSL_OP_PKCS1_CHECK_1
+
+...
+
+=item SSL_OP_PKCS1_CHECK_2
+
+...
+
+=item SSL_OP_NETSCAPE_CA_DN_BUG
+
+If we accept a netscape connection, demand a client cert, have a
+non-self-signed CA which does not have its CA in netscape, and the
+browser has a cert, it will crash/hang.  Works for 3.x and 4.xbeta 
+
+=item SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
+
+...
+
+=item SSL_OP_NO_SSLv2
+
+Do not use the SSLv2 protocol.
+
+=item SSL_OP_NO_SSLv3
+
+Do not use the SSLv3 protocol.
+
+=item SSL_OP_NO_TLSv1
+
+Do not use the TLSv1 protocol.
+
+=item SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
+
+When performing renegotiation as a server, always start a new session
+(i.e., session resumption requests are only accepted in the initial
+handshake). This option is not needed for clients.
+
+=item SSL_OP_NO_TICKET
+
+Normally clients and servers will, where possible, transparently make use
+of RFC4507bis tickets for stateless session resumption.
+
+If this option is set this functionality is disabled and tickets will
+not be used by clients or servers.
+
+=item SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
+
+Allow legacy insecure renegotiation between OpenSSL and unpatched clients or
+servers. See the B<SECURE RENEGOTIATION> section for more details.
+
+=item SSL_OP_LEGACY_SERVER_CONNECT
+
+Allow legacy insecure renegotiation between OpenSSL and unpatched servers
+B<only>: this option is currently set by default. See the
+B<SECURE RENEGOTIATION> section for more details.
+
+=back
+
+=head1 SECURE RENEGOTIATION
+
+OpenSSL 0.9.8m and later always attempts to use secure renegotiation as
+described in RFC5746. This counters the prefix attack described in
+CVE-2009-3555 and elsewhere.
+
+The deprecated and highly broken SSLv2 protocol does not support
+renegotiation at all: its use is B<strongly> discouraged.
+
+This attack has far reaching consequences which application writers should be
+aware of. In the description below an implementation supporting secure
+renegotiation is referred to as I<patched>. A server not supporting secure
+renegotiation is referred to as I<unpatched>.
+
+The following sections describe the operations permitted by OpenSSL's secure
+renegotiation implementation.
+
+=head2 Patched client and server
+
+Connections and renegotiation are always permitted by OpenSSL implementations.
+
+=head2 Unpatched client and patched OpenSSL server
+
+The initial connection suceeds but client renegotiation is denied by the
+server with a B<no_renegotiation> warning alert if TLS v1.0 is used or a fatal
+B<handshake_failure> alert in SSL v3.0.
+
+If the patched OpenSSL server attempts to renegotiate a fatal
+B<handshake_failure> alert is sent. This is because the server code may be
+unaware of the unpatched nature of the client.
+
+If the option B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION> is set then
+renegotiation B<always> succeeds.
+
+B<NB:> a bug in OpenSSL clients earlier than 0.9.8m (all of which are
+unpatched) will result in the connection hanging if it receives a
+B<no_renegotiation> alert. OpenSSL versions 0.9.8m and later will regard
+a B<no_renegotiation> alert as fatal and respond with a fatal
+B<handshake_failure> alert. This is because the OpenSSL API currently has
+no provision to indicate to an application that a renegotiation attempt
+was refused.
+
+=head2 Patched OpenSSL client and unpatched server.
+
+If the option B<SSL_OP_LEGACY_SERVER_CONNECT> or
+B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION> is set then initial connections
+and renegotiation between patched OpenSSL clients and unpatched servers
+succeeds. If neither option is set then initial connections to unpatched
+servers will fail.
+
+The option B<SSL_OP_LEGACY_SERVER_CONNECT> is currently set by default even
+though it has security implications: otherwise it would be impossible to
+connect to unpatched servers (i.e. all of them initially) and this is clearly
+not acceptable. Renegotiation is permitted because this does not add any
+additional security issues: during an attack clients do not see any
+renegotiations anyway.
+
+As more servers become patched the option B<SSL_OP_LEGACY_SERVER_CONNECT> will
+B<not> be set by default in a future version of OpenSSL.
+
+OpenSSL client applications wishing to ensure they can connect to unpatched
+servers should always B<set> B<SSL_OP_LEGACY_SERVER_CONNECT>
+
+OpenSSL client applications that want to ensure they can B<not> connect to
+unpatched servers (and thus avoid any security issues) should always B<clear>
+B<SSL_OP_LEGACY_SERVER_CONNECT> using SSL_CTX_clear_options() or
+SSL_clear_options().
+
+The difference between the B<SSL_OP_LEGACY_SERVER_CONNECT> and
+B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION> options is that
+B<SSL_OP_LEGACY_SERVER_CONNECT> enables initial connections and secure
+renegotiation between OpenSSL clients and unpatched servers B<only>, while
+B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION> allows initial connections
+and renegotiation between OpenSSL and unpatched clients or servers.
+
+=head1 RETURN VALUES
+
+SSL_CTX_set_options() and SSL_set_options() return the new options bitmask
+after adding B<options>.
+
+SSL_CTX_clear_options() and SSL_clear_options() return the new options bitmask
+after clearing B<options>.
+
+SSL_CTX_get_options() and SSL_get_options() return the current bitmask.
+
+SSL_get_secure_renegotiation_support() returns 1 is the peer supports
+secure renegotiation and 0 if it does not.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>, L<SSL_clear(3)|SSL_clear(3)>,
+L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>,
+L<SSL_CTX_set_tmp_rsa_callback(3)|SSL_CTX_set_tmp_rsa_callback(3)>,
+L<dhparam(1)|dhparam(1)>
+
+=head1 HISTORY
+
+B<SSL_OP_CIPHER_SERVER_PREFERENCE> and
+B<SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION> have been added in
+OpenSSL 0.9.7.
+
+B<SSL_OP_TLS_ROLLBACK_BUG> has been added in OpenSSL 0.9.6 and was automatically
+enabled with B<SSL_OP_ALL>. As of 0.9.7, it is no longer included in B<SSL_OP_ALL>
+and must be explicitly set.
+
+B<SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS> has been added in OpenSSL 0.9.6e.
+Versions up to OpenSSL 0.9.6c do not include the countermeasure that
+can be disabled with this option (in OpenSSL 0.9.6d, it was always
+enabled).
+
+SSL_CTX_clear_options() and SSL_clear_options() were first added in OpenSSL
+0.9.8m.
+
+B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION>, B<SSL_OP_LEGACY_SERVER_CONNECT>
+and the function SSL_get_secure_renegotiation_support() were first added in
+OpenSSL 0.9.8m.
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_psk_client_callback.pod b/openssl/doc/ssl/SSL_CTX_set_psk_client_callback.pod
new file mode 100644
index 0000000..573f89a
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_psk_client_callback.pod
@@ -0,0 +1,81 @@
+=pod
+
+=begin comment
+
+Copyright 2005 Nokia. All rights reserved.
+
+The portions of the attached software ("Contribution") is developed by
+Nokia Corporation and is licensed pursuant to the OpenSSL open source
+license.
+
+The Contribution, originally written by Mika Kousa and Pasi Eronen of
+Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+support (see RFC 4279) to OpenSSL.
+
+No patent licenses or other rights except those expressly stated in
+the OpenSSL open source license shall be deemed granted or received
+expressly, by implication, estoppel, or otherwise.
+
+No assurances are provided by Nokia that the Contribution does not
+infringe the patent or other intellectual property rights of any third
+party or that the license provides you with all the necessary rights
+to make use of the Contribution.
+
+THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+OTHERWISE.
+
+=end comment
+
+=head1 NAME
+
+SSL_CTX_set_psk_client_callback, SSL_set_psk_client_callback - set PSK client callback
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx,
+	unsigned int (*callback)(SSL *ssl, const char *hint,
+	char *identity, unsigned int max_identity_len,
+	unsigned char *psk, unsigned int max_psk_len));
+ void SSL_set_psk_client_callback(SSL *ssl,
+	unsigned int (*callback)(SSL *ssl, const char *hint,
+	char *identity, unsigned int max_identity_len,
+ 	unsigned char *psk, unsigned int max_psk_len));
+
+
+=head1 DESCRIPTION
+
+A client application must provide a callback function which is called
+when the client is sending the ClientKeyExchange message to the server.
+
+The purpose of the callback function is to select the PSK identity and
+the pre-shared key to use during the connection setup phase.
+
+The callback is set using functions SSL_CTX_set_psk_client_callback()
+or SSL_set_psk_client_callback(). The callback function is given the
+connection in parameter B<ssl>, a B<NULL>-terminated PSK identity hint
+sent by the server in parameter B<hint>, a buffer B<identity> of
+length B<max_identity_len> bytes where the the resulting
+B<NULL>-terminated identity is to be stored, and a buffer B<psk> of
+length B<max_psk_len> bytes where the resulting pre-shared key is to
+be stored.
+
+=head1 NOTES
+
+Note that parameter B<hint> given to the callback may be B<NULL>.
+
+=head1 RETURN VALUES
+
+Return values from the client callback are interpreted as follows:
+
+On success (callback found a PSK identity and a pre-shared key to use)
+the length (> 0) of B<psk> in bytes is returned.
+
+Otherwise or on errors callback should return 0. In this case
+the connection setup fails.
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_quiet_shutdown.pod b/openssl/doc/ssl/SSL_CTX_set_quiet_shutdown.pod
new file mode 100644
index 0000000..393f8ff
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_quiet_shutdown.pod
@@ -0,0 +1,63 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_quiet_shutdown, SSL_CTX_get_quiet_shutdown, SSL_set_quiet_shutdown, SSL_get_quiet_shutdown - manipulate shutdown behaviour
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode);
+ int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
+
+ void SSL_set_quiet_shutdown(SSL *ssl, int mode);
+ int SSL_get_quiet_shutdown(const SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_quiet_shutdown() sets the "quiet shutdown" flag for B<ctx> to be
+B<mode>. SSL objects created from B<ctx> inherit the B<mode> valid at the time
+L<SSL_new(3)|SSL_new(3)> is called. B<mode> may be 0 or 1.
+
+SSL_CTX_get_quiet_shutdown() returns the "quiet shutdown" setting of B<ctx>.
+
+SSL_set_quiet_shutdown() sets the "quiet shutdown" flag for B<ssl> to be
+B<mode>. The setting stays valid until B<ssl> is removed with
+L<SSL_free(3)|SSL_free(3)> or SSL_set_quiet_shutdown() is called again.
+It is not changed when L<SSL_clear(3)|SSL_clear(3)> is called.
+B<mode> may be 0 or 1.
+
+SSL_get_quiet_shutdown() returns the "quiet shutdown" setting of B<ssl>.
+
+=head1 NOTES
+
+Normally when a SSL connection is finished, the parties must send out
+"close notify" alert messages using L<SSL_shutdown(3)|SSL_shutdown(3)>
+for a clean shutdown.
+
+When setting the "quiet shutdown" flag to 1, L<SSL_shutdown(3)|SSL_shutdown(3)>
+will set the internal flags to SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN.
+(L<SSL_shutdown(3)|SSL_shutdown(3)> then behaves like
+L<SSL_set_shutdown(3)|SSL_set_shutdown(3)> called with
+SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN.)
+The session is thus considered to be shutdown, but no "close notify" alert
+is sent to the peer. This behaviour violates the TLS standard.
+
+The default is normal shutdown behaviour as described by the TLS standard.
+
+=head1 RETURN VALUES
+
+SSL_CTX_set_quiet_shutdown() and SSL_set_quiet_shutdown() do not return
+diagnostic information.
+
+SSL_CTX_get_quiet_shutdown() and SSL_get_quiet_shutdown return the current
+setting.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_shutdown(3)|SSL_shutdown(3)>,
+L<SSL_set_shutdown(3)|SSL_set_shutdown(3)>, L<SSL_new(3)|SSL_new(3)>,
+L<SSL_clear(3)|SSL_clear(3)>, L<SSL_free(3)|SSL_free(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_session_cache_mode.pod b/openssl/doc/ssl/SSL_CTX_set_session_cache_mode.pod
new file mode 100644
index 0000000..c5d2f43
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_session_cache_mode.pod
@@ -0,0 +1,137 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_session_cache_mode, SSL_CTX_get_session_cache_mode - enable/disable session caching
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ long SSL_CTX_set_session_cache_mode(SSL_CTX ctx, long mode);
+ long SSL_CTX_get_session_cache_mode(SSL_CTX ctx);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_session_cache_mode() enables/disables session caching
+by setting the operational mode for B<ctx> to <mode>.
+
+SSL_CTX_get_session_cache_mode() returns the currently used cache mode.
+
+=head1 NOTES
+
+The OpenSSL library can store/retrieve SSL/TLS sessions for later reuse.
+The sessions can be held in memory for each B<ctx>, if more than one
+SSL_CTX object is being maintained, the sessions are unique for each SSL_CTX
+object.
+
+In order to reuse a session, a client must send the session's id to the
+server. It can only send exactly one id.  The server then either 
+agrees to reuse the session or it starts a full handshake (to create a new
+session).
+
+A server will lookup up the session in its internal session storage. If the
+session is not found in internal storage or lookups for the internal storage
+have been deactivated (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP), the server will try
+the external storage if available.
+
+Since a client may try to reuse a session intended for use in a different
+context, the session id context must be set by the server (see
+L<SSL_CTX_set_session_id_context(3)|SSL_CTX_set_session_id_context(3)>).
+
+The following session cache modes and modifiers are available:
+
+=over 4
+
+=item SSL_SESS_CACHE_OFF
+
+No session caching for client or server takes place.
+
+=item SSL_SESS_CACHE_CLIENT
+
+Client sessions are added to the session cache. As there is no reliable way
+for the OpenSSL library to know whether a session should be reused or which
+session to choose (due to the abstract BIO layer the SSL engine does not
+have details about the connection), the application must select the session
+to be reused by using the L<SSL_set_session(3)|SSL_set_session(3)>
+function. This option is not activated by default.
+
+=item SSL_SESS_CACHE_SERVER
+
+Server sessions are added to the session cache. When a client proposes a
+session to be reused, the server looks for the corresponding session in (first)
+the internal session cache (unless SSL_SESS_CACHE_NO_INTERNAL_LOOKUP is set),
+then (second) in the external cache if available. If the session is found, the
+server will try to reuse the session.  This is the default.
+
+=item SSL_SESS_CACHE_BOTH
+
+Enable both SSL_SESS_CACHE_CLIENT and SSL_SESS_CACHE_SERVER at the same time.
+
+=item SSL_SESS_CACHE_NO_AUTO_CLEAR
+
+Normally the session cache is checked for expired sessions every
+255 connections using the
+L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)> function. Since
+this may lead to a delay which cannot be controlled, the automatic
+flushing may be disabled and
+L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)> can be called
+explicitly by the application.
+
+=item SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
+
+By setting this flag, session-resume operations in an SSL/TLS server will not
+automatically look up sessions in the internal cache, even if sessions are
+automatically stored there. If external session caching callbacks are in use,
+this flag guarantees that all lookups are directed to the external cache.
+As automatic lookup only applies for SSL/TLS servers, the flag has no effect on
+clients.
+
+=item SSL_SESS_CACHE_NO_INTERNAL_STORE
+
+Depending on the presence of SSL_SESS_CACHE_CLIENT and/or SSL_SESS_CACHE_SERVER,
+sessions negotiated in an SSL/TLS handshake may be cached for possible reuse.
+Normally a new session is added to the internal cache as well as any external
+session caching (callback) that is configured for the SSL_CTX. This flag will
+prevent sessions being stored in the internal cache (though the application can
+add them manually using L<SSL_CTX_add_session(3)|SSL_CTX_add_session(3)>). Note:
+in any SSL/TLS servers where external caching is configured, any successful
+session lookups in the external cache (ie. for session-resume requests) would
+normally be copied into the local cache before processing continues - this flag
+prevents these additions to the internal cache as well.
+
+=item SSL_SESS_CACHE_NO_INTERNAL
+
+Enable both SSL_SESS_CACHE_NO_INTERNAL_LOOKUP and
+SSL_SESS_CACHE_NO_INTERNAL_STORE at the same time.
+
+
+=back
+
+The default mode is SSL_SESS_CACHE_SERVER.
+
+=head1 RETURN VALUES
+
+SSL_CTX_set_session_cache_mode() returns the previously set cache mode.
+
+SSL_CTX_get_session_cache_mode() returns the currently set cache mode.
+
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_set_session(3)|SSL_set_session(3)>,
+L<SSL_session_reused(3)|SSL_session_reused(3)>,
+L<SSL_CTX_add_session(3)|SSL_CTX_add_session(3)>,
+L<SSL_CTX_sess_number(3)|SSL_CTX_sess_number(3)>,
+L<SSL_CTX_sess_set_cache_size(3)|SSL_CTX_sess_set_cache_size(3)>,
+L<SSL_CTX_sess_set_get_cb(3)|SSL_CTX_sess_set_get_cb(3)>,
+L<SSL_CTX_set_session_id_context(3)|SSL_CTX_set_session_id_context(3)>,
+L<SSL_CTX_set_timeout(3)|SSL_CTX_set_timeout(3)>,
+L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)>
+
+=head1 HISTORY
+
+SSL_SESS_CACHE_NO_INTERNAL_STORE and SSL_SESS_CACHE_NO_INTERNAL
+were introduced in OpenSSL 0.9.6h.
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_session_id_context.pod b/openssl/doc/ssl/SSL_CTX_set_session_id_context.pod
new file mode 100644
index 0000000..58fc685
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_session_id_context.pod
@@ -0,0 +1,83 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_session_id_context, SSL_set_session_id_context - set context within which session can be reused (server side only)
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
+                                    unsigned int sid_ctx_len);
+ int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx,
+                                unsigned int sid_ctx_len);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_session_id_context() sets the context B<sid_ctx> of length
+B<sid_ctx_len> within which a session can be reused for the B<ctx> object.
+
+SSL_set_session_id_context() sets the context B<sid_ctx> of length
+B<sid_ctx_len> within which a session can be reused for the B<ssl> object.
+
+=head1 NOTES
+
+Sessions are generated within a certain context. When exporting/importing
+sessions with B<i2d_SSL_SESSION>/B<d2i_SSL_SESSION> it would be possible,
+to re-import a session generated from another context (e.g. another
+application), which might lead to malfunctions. Therefore each application
+must set its own session id context B<sid_ctx> which is used to distinguish
+the contexts and is stored in exported sessions. The B<sid_ctx> can be
+any kind of binary data with a given length, it is therefore possible
+to use e.g. the name of the application and/or the hostname and/or service
+name ...
+
+The session id context becomes part of the session. The session id context
+is set by the SSL/TLS server. The SSL_CTX_set_session_id_context() and
+SSL_set_session_id_context() functions are therefore only useful on the
+server side.
+
+OpenSSL clients will check the session id context returned by the server
+when reusing a session.
+
+The maximum length of the B<sid_ctx> is limited to
+B<SSL_MAX_SSL_SESSION_ID_LENGTH>.
+
+=head1 WARNINGS
+
+If the session id context is not set on an SSL/TLS server and client
+certificates are used, stored sessions
+will not be reused but a fatal error will be flagged and the handshake
+will fail.
+
+If a server returns a different session id context to an OpenSSL client
+when reusing a session, an error will be flagged and the handshake will
+fail. OpenSSL servers will always return the correct session id context,
+as an OpenSSL server checks the session id context itself before reusing
+a session as described above.
+
+=head1 RETURN VALUES
+
+SSL_CTX_set_session_id_context() and SSL_set_session_id_context()
+return the following values:
+
+=over 4
+
+=item 0
+
+The length B<sid_ctx_len> of the session id context B<sid_ctx> exceeded
+the maximum allowed length of B<SSL_MAX_SSL_SESSION_ID_LENGTH>. The error
+is logged to the error stack.
+
+=item 1
+
+The operation succeeded.
+
+=back
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_ssl_version.pod b/openssl/doc/ssl/SSL_CTX_set_ssl_version.pod
new file mode 100644
index 0000000..254f2b4
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_ssl_version.pod
@@ -0,0 +1,61 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_ssl_version, SSL_set_ssl_method, SSL_get_ssl_method
+- choose a new TLS/SSL method
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *method);
+ int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
+ const SSL_METHOD *SSL_get_ssl_method(SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_ssl_version() sets a new default TLS/SSL B<method> for SSL objects
+newly created from this B<ctx>. SSL objects already created with
+L<SSL_new(3)|SSL_new(3)> are not affected, except when
+L<SSL_clear(3)|SSL_clear(3)> is being called.
+
+SSL_set_ssl_method() sets a new TLS/SSL B<method> for a particular B<ssl>
+object. It may be reset, when SSL_clear() is called.
+
+SSL_get_ssl_method() returns a function pointer to the TLS/SSL method
+set in B<ssl>.
+
+=head1 NOTES
+
+The available B<method> choices are described in
+L<SSL_CTX_new(3)|SSL_CTX_new(3)>.
+
+When L<SSL_clear(3)|SSL_clear(3)> is called and no session is connected to
+an SSL object, the method of the SSL object is reset to the method currently
+set in the corresponding SSL_CTX object.
+
+=head1 RETURN VALUES
+
+The following return values can occur for SSL_CTX_set_ssl_version()
+and SSL_set_ssl_method():
+
+=over 4
+
+=item 0
+
+The new choice failed, check the error stack to find out the reason.
+
+=item 1
+
+The operation succeeded.
+
+=back
+
+=head1 SEE ALSO
+
+L<SSL_CTX_new(3)|SSL_CTX_new(3)>, L<SSL_new(3)|SSL_new(3)>,
+L<SSL_clear(3)|SSL_clear(3)>, L<ssl(3)|ssl(3)>,
+L<SSL_set_connect_state(3)|SSL_set_connect_state(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_timeout.pod b/openssl/doc/ssl/SSL_CTX_set_timeout.pod
new file mode 100644
index 0000000..e3de27c
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_timeout.pod
@@ -0,0 +1,59 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_timeout, SSL_CTX_get_timeout - manipulate timeout values for session caching
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ long SSL_CTX_set_timeout(SSL_CTX *ctx, long t);
+ long SSL_CTX_get_timeout(SSL_CTX *ctx);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_timeout() sets the timeout for newly created sessions for
+B<ctx> to B<t>. The timeout value B<t> must be given in seconds.
+
+SSL_CTX_get_timeout() returns the currently set timeout value for B<ctx>.
+
+=head1 NOTES
+
+Whenever a new session is created, it is assigned a maximum lifetime. This
+lifetime is specified by storing the creation time of the session and the
+timeout value valid at this time. If the actual time is later than creation
+time plus timeout, the session is not reused.
+
+Due to this realization, all sessions behave according to the timeout value
+valid at the time of the session negotiation. Changes of the timeout value
+do not affect already established sessions.
+
+The expiration time of a single session can be modified using the
+L<SSL_SESSION_get_time(3)|SSL_SESSION_get_time(3)> family of functions.
+
+Expired sessions are removed from the internal session cache, whenever
+L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)> is called, either
+directly by the application or automatically (see
+L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>)
+
+The default value for session timeout is decided on a per protocol
+basis, see L<SSL_get_default_timeout(3)|SSL_get_default_timeout(3)>.
+All currently supported protocols have the same default timeout value
+of 300 seconds.
+
+=head1 RETURN VALUES
+
+SSL_CTX_set_timeout() returns the previously set timeout value.
+
+SSL_CTX_get_timeout() returns the currently set timeout value.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>,
+L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
+L<SSL_SESSION_get_time(3)|SSL_SESSION_get_time(3)>,
+L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)>,
+L<SSL_get_default_timeout(3)|SSL_get_default_timeout(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod b/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod
new file mode 100644
index 0000000..29d1f8a
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod
@@ -0,0 +1,170 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_tmp_dh_callback, SSL_CTX_set_tmp_dh, SSL_set_tmp_dh_callback, SSL_set_tmp_dh - handle DH keys for ephemeral key exchange
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
+            DH *(*tmp_dh_callback)(SSL *ssl, int is_export, int keylength));
+ long SSL_CTX_set_tmp_dh(SSL_CTX *ctx, DH *dh);
+
+ void SSL_set_tmp_dh_callback(SSL_CTX *ctx,
+            DH *(*tmp_dh_callback)(SSL *ssl, int is_export, int keylength));
+ long SSL_set_tmp_dh(SSL *ssl, DH *dh)
+
+ DH *(*tmp_dh_callback)(SSL *ssl, int is_export, int keylength));
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_tmp_dh_callback() sets the callback function for B<ctx> to be
+used when a DH parameters are required to B<tmp_dh_callback>.
+The callback is inherited by all B<ssl> objects created from B<ctx>.
+
+SSL_CTX_set_tmp_dh() sets DH parameters to be used to be B<dh>.
+The key is inherited by all B<ssl> objects created from B<ctx>.
+
+SSL_set_tmp_dh_callback() sets the callback only for B<ssl>.
+
+SSL_set_tmp_dh() sets the parameters only for B<ssl>.
+
+These functions apply to SSL/TLS servers only.
+
+=head1 NOTES
+
+When using a cipher with RSA authentication, an ephemeral DH key exchange
+can take place. Ciphers with DSA keys always use ephemeral DH keys as well.
+In these cases, the session data are negotiated using the
+ephemeral/temporary DH key and the key supplied and certified
+by the certificate chain is only used for signing.
+Anonymous ciphers (without a permanent server key) also use ephemeral DH keys.
+
+Using ephemeral DH key exchange yields forward secrecy, as the connection
+can only be decrypted, when the DH key is known. By generating a temporary
+DH key inside the server application that is lost when the application
+is left, it becomes impossible for an attacker to decrypt past sessions,
+even if he gets hold of the normal (certified) key, as this key was
+only used for signing.
+
+In order to perform a DH key exchange the server must use a DH group
+(DH parameters) and generate a DH key. The server will always generate a new
+DH key during the negotiation, when the DH parameters are supplied via
+callback and/or when the SSL_OP_SINGLE_DH_USE option of
+L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)> is set. It will
+immediately create a DH key, when DH parameters are supplied via
+SSL_CTX_set_tmp_dh() and SSL_OP_SINGLE_DH_USE is not set. In this case,
+it may happen that a key is generated on initialization without later
+being needed, while on the other hand the computer time during the
+negotiation is being saved.
+
+If "strong" primes were used to generate the DH parameters, it is not strictly
+necessary to generate a new key for each handshake but it does improve forward
+secrecy. If it is not assured, that "strong" primes were used (see especially
+the section about DSA parameters below), SSL_OP_SINGLE_DH_USE must be used
+in order to prevent small subgroup attacks. Always using SSL_OP_SINGLE_DH_USE
+has an impact on the computer time needed during negotiation, but it is not
+very large, so application authors/users should consider to always enable
+this option.
+
+As generating DH parameters is extremely time consuming, an application
+should not generate the parameters on the fly but supply the parameters.
+DH parameters can be reused, as the actual key is newly generated during
+the negotiation. The risk in reusing DH parameters is that an attacker
+may specialize on a very often used DH group. Applications should therefore
+generate their own DH parameters during the installation process using the
+openssl L<dhparam(1)|dhparam(1)> application. In order to reduce the computer
+time needed for this generation, it is possible to use DSA parameters
+instead (see L<dhparam(1)|dhparam(1)>), but in this case SSL_OP_SINGLE_DH_USE
+is mandatory.
+
+Application authors may compile in DH parameters. Files dh512.pem,
+dh1024.pem, dh2048.pem, and dh4096 in the 'apps' directory of current
+version of the OpenSSL distribution contain the 'SKIP' DH parameters,
+which use safe primes and were generated verifiably pseudo-randomly.
+These files can be converted into C code using the B<-C> option of the
+L<dhparam(1)|dhparam(1)> application.
+Authors may also generate their own set of parameters using
+L<dhparam(1)|dhparam(1)>, but a user may not be sure how the parameters were
+generated. The generation of DH parameters during installation is therefore
+recommended.
+
+An application may either directly specify the DH parameters or
+can supply the DH parameters via a callback function. The callback approach
+has the advantage, that the callback may supply DH parameters for different
+key lengths.
+
+The B<tmp_dh_callback> is called with the B<keylength> needed and
+the B<is_export> information. The B<is_export> flag is set, when the
+ephemeral DH key exchange is performed with an export cipher.
+
+=head1 EXAMPLES
+
+Handle DH parameters for key lengths of 512 and 1024 bits. (Error handling
+partly left out.)
+
+ ...
+ /* Set up ephemeral DH stuff */
+ DH *dh_512 = NULL;
+ DH *dh_1024 = NULL;
+ FILE *paramfile;
+
+ ...
+ /* "openssl dhparam -out dh_param_512.pem -2 512" */
+ paramfile = fopen("dh_param_512.pem", "r");
+ if (paramfile) {
+   dh_512 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
+   fclose(paramfile);
+ }
+ /* "openssl dhparam -out dh_param_1024.pem -2 1024" */
+ paramfile = fopen("dh_param_1024.pem", "r");
+ if (paramfile) {
+   dh_1024 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
+   fclose(paramfile);
+ }
+ ...
+
+ /* "openssl dhparam -C -2 512" etc... */
+ DH *get_dh512() { ... }
+ DH *get_dh1024() { ... }
+
+ DH *tmp_dh_callback(SSL *s, int is_export, int keylength)
+ {
+    DH *dh_tmp=NULL;
+
+    switch (keylength) {
+    case 512:
+      if (!dh_512)
+        dh_512 = get_dh512();
+      dh_tmp = dh_512;
+      break;
+    case 1024:
+      if (!dh_1024) 
+        dh_1024 = get_dh1024();
+      dh_tmp = dh_1024;
+      break;
+    default:
+      /* Generating a key on the fly is very costly, so use what is there */
+      setup_dh_parameters_like_above();
+    }
+    return(dh_tmp);
+ }
+
+=head1 RETURN VALUES
+
+SSL_CTX_set_tmp_dh_callback() and SSL_set_tmp_dh_callback() do not return
+diagnostic output.
+
+SSL_CTX_set_tmp_dh() and SSL_set_tmp_dh() do return 1 on success and 0
+on failure. Check the error queue to find out the reason of failure.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_CTX_set_cipher_list(3)|SSL_CTX_set_cipher_list(3)>,
+L<SSL_CTX_set_tmp_rsa_callback(3)|SSL_CTX_set_tmp_rsa_callback(3)>,
+L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)>,
+L<ciphers(1)|ciphers(1)>, L<dhparam(1)|dhparam(1)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod b/openssl/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod
new file mode 100644
index 0000000..534643c
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod
@@ -0,0 +1,166 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_tmp_rsa_callback, SSL_CTX_set_tmp_rsa, SSL_CTX_need_tmp_rsa, SSL_set_tmp_rsa_callback, SSL_set_tmp_rsa, SSL_need_tmp_rsa - handle RSA keys for ephemeral key exchange
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
+            RSA *(*tmp_rsa_callback)(SSL *ssl, int is_export, int keylength));
+ long SSL_CTX_set_tmp_rsa(SSL_CTX *ctx, RSA *rsa);
+ long SSL_CTX_need_tmp_rsa(SSL_CTX *ctx);
+
+ void SSL_set_tmp_rsa_callback(SSL_CTX *ctx,
+            RSA *(*tmp_rsa_callback)(SSL *ssl, int is_export, int keylength));
+ long SSL_set_tmp_rsa(SSL *ssl, RSA *rsa)
+ long SSL_need_tmp_rsa(SSL *ssl)
+
+ RSA *(*tmp_rsa_callback)(SSL *ssl, int is_export, int keylength);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_tmp_rsa_callback() sets the callback function for B<ctx> to be
+used when a temporary/ephemeral RSA key is required to B<tmp_rsa_callback>.
+The callback is inherited by all SSL objects newly created from B<ctx>
+with <SSL_new(3)|SSL_new(3)>. Already created SSL objects are not affected.
+
+SSL_CTX_set_tmp_rsa() sets the temporary/ephemeral RSA key to be used to be
+B<rsa>. The key is inherited by all SSL objects newly created from B<ctx>
+with <SSL_new(3)|SSL_new(3)>. Already created SSL objects are not affected.
+
+SSL_CTX_need_tmp_rsa() returns 1, if a temporary/ephemeral RSA key is needed
+for RSA-based strength-limited 'exportable' ciphersuites because a RSA key
+with a keysize larger than 512 bits is installed.
+
+SSL_set_tmp_rsa_callback() sets the callback only for B<ssl>.
+
+SSL_set_tmp_rsa() sets the key only for B<ssl>.
+
+SSL_need_tmp_rsa() returns 1, if a temporary/ephemeral RSA key is needed,
+for RSA-based strength-limited 'exportable' ciphersuites because a RSA key
+with a keysize larger than 512 bits is installed.
+
+These functions apply to SSL/TLS servers only.
+
+=head1 NOTES
+
+When using a cipher with RSA authentication, an ephemeral RSA key exchange
+can take place. In this case the session data are negotiated using the
+ephemeral/temporary RSA key and the RSA key supplied and certified
+by the certificate chain is only used for signing.
+
+Under previous export restrictions, ciphers with RSA keys shorter (512 bits)
+than the usual key length of 1024 bits were created. To use these ciphers
+with RSA keys of usual length, an ephemeral key exchange must be performed,
+as the normal (certified) key cannot be directly used.
+
+Using ephemeral RSA key exchange yields forward secrecy, as the connection
+can only be decrypted, when the RSA key is known. By generating a temporary
+RSA key inside the server application that is lost when the application
+is left, it becomes impossible for an attacker to decrypt past sessions,
+even if he gets hold of the normal (certified) RSA key, as this key was
+used for signing only. The downside is that creating a RSA key is
+computationally expensive.
+
+Additionally, the use of ephemeral RSA key exchange is only allowed in
+the TLS standard, when the RSA key can be used for signing only, that is
+for export ciphers. Using ephemeral RSA key exchange for other purposes
+violates the standard and can break interoperability with clients.
+It is therefore strongly recommended to not use ephemeral RSA key
+exchange and use EDH (Ephemeral Diffie-Hellman) key exchange instead
+in order to achieve forward secrecy (see
+L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>).
+
+On OpenSSL servers ephemeral RSA key exchange is therefore disabled by default
+and must be explicitly enabled  using the SSL_OP_EPHEMERAL_RSA option of
+L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)>, violating the TLS/SSL
+standard. When ephemeral RSA key exchange is required for export ciphers,
+it will automatically be used without this option!
+
+An application may either directly specify the key or can supply the key via
+a callback function. The callback approach has the advantage, that the
+callback may generate the key only in case it is actually needed. As the
+generation of a RSA key is however costly, it will lead to a significant
+delay in the handshake procedure.  Another advantage of the callback function
+is that it can supply keys of different size (e.g. for SSL_OP_EPHEMERAL_RSA
+usage) while the explicit setting of the key is only useful for key size of
+512 bits to satisfy the export restricted ciphers and does give away key length
+if a longer key would be allowed.
+
+The B<tmp_rsa_callback> is called with the B<keylength> needed and
+the B<is_export> information. The B<is_export> flag is set, when the
+ephemeral RSA key exchange is performed with an export cipher.
+
+=head1 EXAMPLES
+
+Generate temporary RSA keys to prepare ephemeral RSA key exchange. As the
+generation of a RSA key costs a lot of computer time, they saved for later
+reuse. For demonstration purposes, two keys for 512 bits and 1024 bits
+respectively are generated.
+
+ ...
+ /* Set up ephemeral RSA stuff */
+ RSA *rsa_512 = NULL;
+ RSA *rsa_1024 = NULL;
+
+ rsa_512 = RSA_generate_key(512,RSA_F4,NULL,NULL);
+ if (rsa_512 == NULL)
+     evaluate_error_queue();
+
+ rsa_1024 = RSA_generate_key(1024,RSA_F4,NULL,NULL);
+ if (rsa_1024 == NULL)
+   evaluate_error_queue();
+
+ ...
+
+ RSA *tmp_rsa_callback(SSL *s, int is_export, int keylength)
+ {
+    RSA *rsa_tmp=NULL;
+
+    switch (keylength) {
+    case 512:
+      if (rsa_512)
+        rsa_tmp = rsa_512;
+      else { /* generate on the fly, should not happen in this example */
+        rsa_tmp = RSA_generate_key(keylength,RSA_F4,NULL,NULL);
+        rsa_512 = rsa_tmp; /* Remember for later reuse */
+      }
+      break;
+    case 1024:
+      if (rsa_1024)
+        rsa_tmp=rsa_1024;
+      else
+        should_not_happen_in_this_example();
+      break;
+    default:
+      /* Generating a key on the fly is very costly, so use what is there */
+      if (rsa_1024)
+        rsa_tmp=rsa_1024;
+      else
+        rsa_tmp=rsa_512; /* Use at least a shorter key */
+    }
+    return(rsa_tmp);
+ }
+
+=head1 RETURN VALUES
+
+SSL_CTX_set_tmp_rsa_callback() and SSL_set_tmp_rsa_callback() do not return
+diagnostic output.
+
+SSL_CTX_set_tmp_rsa() and SSL_set_tmp_rsa() do return 1 on success and 0
+on failure. Check the error queue to find out the reason of failure.
+
+SSL_CTX_need_tmp_rsa() and SSL_need_tmp_rsa() return 1 if a temporary
+RSA key is needed and 0 otherwise.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_CTX_set_cipher_list(3)|SSL_CTX_set_cipher_list(3)>,
+L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)>,
+L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>,
+L<SSL_new(3)|SSL_new(3)>, L<ciphers(1)|ciphers(1)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_set_verify.pod b/openssl/doc/ssl/SSL_CTX_set_verify.pod
new file mode 100644
index 0000000..8156683
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_set_verify.pod
@@ -0,0 +1,294 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_verify, SSL_set_verify, SSL_CTX_set_verify_depth, SSL_set_verify_depth - set peer certificate verification parameters
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
+                         int (*verify_callback)(int, X509_STORE_CTX *));
+ void SSL_set_verify(SSL *s, int mode,
+                     int (*verify_callback)(int, X509_STORE_CTX *));
+ void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth);
+ void SSL_set_verify_depth(SSL *s, int depth);
+
+ int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_verify() sets the verification flags for B<ctx> to be B<mode> and
+specifies the B<verify_callback> function to be used. If no callback function
+shall be specified, the NULL pointer can be used for B<verify_callback>.
+
+SSL_set_verify() sets the verification flags for B<ssl> to be B<mode> and
+specifies the B<verify_callback> function to be used. If no callback function
+shall be specified, the NULL pointer can be used for B<verify_callback>. In
+this case last B<verify_callback> set specifically for this B<ssl> remains. If
+no special B<callback> was set before, the default callback for the underlying
+B<ctx> is used, that was valid at the time B<ssl> was created with
+L<SSL_new(3)|SSL_new(3)>.
+
+SSL_CTX_set_verify_depth() sets the maximum B<depth> for the certificate chain
+verification that shall be allowed for B<ctx>. (See the BUGS section.)
+
+SSL_set_verify_depth() sets the maximum B<depth> for the certificate chain
+verification that shall be allowed for B<ssl>. (See the BUGS section.)
+
+=head1 NOTES
+
+The verification of certificates can be controlled by a set of logically
+or'ed B<mode> flags:
+
+=over 4
+
+=item SSL_VERIFY_NONE
+
+B<Server mode:> the server will not send a client certificate request to the
+client, so the client will not send a certificate.
+
+B<Client mode:> if not using an anonymous cipher (by default disabled), the
+server will send a certificate which will be checked. The result of the
+certificate verification process can be checked after the TLS/SSL handshake
+using the L<SSL_get_verify_result(3)|SSL_get_verify_result(3)> function.
+The handshake will be continued regardless of the verification result.
+
+=item SSL_VERIFY_PEER
+
+B<Server mode:> the server sends a client certificate request to the client.
+The certificate returned (if any) is checked. If the verification process
+fails, the TLS/SSL handshake is
+immediately terminated with an alert message containing the reason for
+the verification failure.
+The behaviour can be controlled by the additional
+SSL_VERIFY_FAIL_IF_NO_PEER_CERT and SSL_VERIFY_CLIENT_ONCE flags.
+
+B<Client mode:> the server certificate is verified. If the verification process
+fails, the TLS/SSL handshake is
+immediately terminated with an alert message containing the reason for
+the verification failure. If no server certificate is sent, because an
+anonymous cipher is used, SSL_VERIFY_PEER is ignored.
+
+=item SSL_VERIFY_FAIL_IF_NO_PEER_CERT
+
+B<Server mode:> if the client did not return a certificate, the TLS/SSL
+handshake is immediately terminated with a "handshake failure" alert.
+This flag must be used together with SSL_VERIFY_PEER.
+
+B<Client mode:> ignored
+
+=item SSL_VERIFY_CLIENT_ONCE
+
+B<Server mode:> only request a client certificate on the initial TLS/SSL
+handshake. Do not ask for a client certificate again in case of a
+renegotiation. This flag must be used together with SSL_VERIFY_PEER.
+
+B<Client mode:> ignored
+
+=back
+
+Exactly one of the B<mode> flags SSL_VERIFY_NONE and SSL_VERIFY_PEER must be
+set at any time.
+
+The actual verification procedure is performed either using the built-in
+verification procedure or using another application provided verification
+function set with
+L<SSL_CTX_set_cert_verify_callback(3)|SSL_CTX_set_cert_verify_callback(3)>.
+The following descriptions apply in the case of the built-in procedure. An
+application provided procedure also has access to the verify depth information
+and the verify_callback() function, but the way this information is used
+may be different.
+
+SSL_CTX_set_verify_depth() and SSL_set_verify_depth() set the limit up
+to which depth certificates in a chain are used during the verification
+procedure. If the certificate chain is longer than allowed, the certificates
+above the limit are ignored. Error messages are generated as if these
+certificates would not be present, most likely a
+X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY will be issued.
+The depth count is "level 0:peer certificate", "level 1: CA certificate",
+"level 2: higher level CA certificate", and so on. Setting the maximum
+depth to 2 allows the levels 0, 1, and 2. The default depth limit is 9,
+allowing for the peer certificate and additional 9 CA certificates.
+
+The B<verify_callback> function is used to control the behaviour when the
+SSL_VERIFY_PEER flag is set. It must be supplied by the application and
+receives two arguments: B<preverify_ok> indicates, whether the verification of
+the certificate in question was passed (preverify_ok=1) or not
+(preverify_ok=0). B<x509_ctx> is a pointer to the complete context used
+for the certificate chain verification.
+
+The certificate chain is checked starting with the deepest nesting level
+(the root CA certificate) and worked upward to the peer's certificate.
+At each level signatures and issuer attributes are checked. Whenever
+a verification error is found, the error number is stored in B<x509_ctx>
+and B<verify_callback> is called with B<preverify_ok>=0. By applying
+X509_CTX_store_* functions B<verify_callback> can locate the certificate
+in question and perform additional steps (see EXAMPLES). If no error is
+found for a certificate, B<verify_callback> is called with B<preverify_ok>=1
+before advancing to the next level.
+
+The return value of B<verify_callback> controls the strategy of the further
+verification process. If B<verify_callback> returns 0, the verification
+process is immediately stopped with "verification failed" state. If
+SSL_VERIFY_PEER is set, a verification failure alert is sent to the peer and
+the TLS/SSL handshake is terminated. If B<verify_callback> returns 1,
+the verification process is continued. If B<verify_callback> always returns
+1, the TLS/SSL handshake will not be terminated with respect to verification
+failures and the connection will be established. The calling process can
+however retrieve the error code of the last verification error using
+L<SSL_get_verify_result(3)|SSL_get_verify_result(3)> or by maintaining its
+own error storage managed by B<verify_callback>.
+
+If no B<verify_callback> is specified, the default callback will be used.
+Its return value is identical to B<preverify_ok>, so that any verification
+failure will lead to a termination of the TLS/SSL handshake with an
+alert message, if SSL_VERIFY_PEER is set.
+
+=head1 BUGS
+
+In client mode, it is not checked whether the SSL_VERIFY_PEER flag
+is set, but whether SSL_VERIFY_NONE is not set. This can lead to
+unexpected behaviour, if the SSL_VERIFY_PEER and SSL_VERIFY_NONE are not
+used as required (exactly one must be set at any time).
+
+The certificate verification depth set with SSL[_CTX]_verify_depth()
+stops the verification at a certain depth. The error message produced
+will be that of an incomplete certificate chain and not
+X509_V_ERR_CERT_CHAIN_TOO_LONG as may be expected.
+
+=head1 RETURN VALUES
+
+The SSL*_set_verify*() functions do not provide diagnostic information.
+
+=head1 EXAMPLES
+
+The following code sequence realizes an example B<verify_callback> function
+that will always continue the TLS/SSL handshake regardless of verification
+failure, if wished. The callback realizes a verification depth limit with
+more informational output.
+
+All verification errors are printed, informations about the certificate chain
+are printed on request.
+The example is realized for a server that does allow but not require client
+certificates.
+
+The example makes use of the ex_data technique to store application data
+into/retrieve application data from the SSL structure
+(see L<SSL_get_ex_new_index(3)|SSL_get_ex_new_index(3)>,
+L<SSL_get_ex_data_X509_STORE_CTX_idx(3)|SSL_get_ex_data_X509_STORE_CTX_idx(3)>).
+
+ ...
+ typedef struct {
+   int verbose_mode;
+   int verify_depth;
+   int always_continue;
+ } mydata_t;
+ int mydata_index;
+ ...
+ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
+ {
+    char    buf[256];
+    X509   *err_cert;
+    int     err, depth;
+    SSL    *ssl;
+    mydata_t *mydata;
+
+    err_cert = X509_STORE_CTX_get_current_cert(ctx);
+    err = X509_STORE_CTX_get_error(ctx);
+    depth = X509_STORE_CTX_get_error_depth(ctx);
+
+    /*
+     * Retrieve the pointer to the SSL of the connection currently treated
+     * and the application specific data stored into the SSL object.
+     */
+    ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
+    mydata = SSL_get_ex_data(ssl, mydata_index);
+
+    X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
+
+    /*
+     * Catch a too long certificate chain. The depth limit set using
+     * SSL_CTX_set_verify_depth() is by purpose set to "limit+1" so
+     * that whenever the "depth>verify_depth" condition is met, we
+     * have violated the limit and want to log this error condition.
+     * We must do it here, because the CHAIN_TOO_LONG error would not
+     * be found explicitly; only errors introduced by cutting off the
+     * additional certificates would be logged.
+     */
+    if (depth > mydata->verify_depth) {
+        preverify_ok = 0;
+        err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
+        X509_STORE_CTX_set_error(ctx, err);
+    } 
+    if (!preverify_ok) {
+        printf("verify error:num=%d:%s:depth=%d:%s\n", err,
+                 X509_verify_cert_error_string(err), depth, buf);
+    }
+    else if (mydata->verbose_mode)
+    {
+        printf("depth=%d:%s\n", depth, buf);
+    }
+
+    /*
+     * At this point, err contains the last verification error. We can use
+     * it for something special
+     */
+    if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT))
+    {
+      X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
+      printf("issuer= %s\n", buf);
+    }
+
+    if (mydata->always_continue)
+      return 1;
+    else
+      return preverify_ok;
+ }
+ ...
+
+ mydata_t mydata;
+
+ ...
+ mydata_index = SSL_get_ex_new_index(0, "mydata index", NULL, NULL, NULL);
+
+ ...
+ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
+                    verify_callback);
+
+ /*
+  * Let the verify_callback catch the verify_depth error so that we get
+  * an appropriate error in the logfile.
+  */
+ SSL_CTX_set_verify_depth(verify_depth + 1);
+
+ /*
+  * Set up the SSL specific data into "mydata" and store it into th SSL
+  * structure.
+  */
+ mydata.verify_depth = verify_depth; ...
+ SSL_set_ex_data(ssl, mydata_index, &mydata);
+					     
+ ...
+ SSL_accept(ssl);	/* check of success left out for clarity */
+ if (peer = SSL_get_peer_certificate(ssl))
+ {
+   if (SSL_get_verify_result(ssl) == X509_V_OK)
+   {
+     /* The client sent a certificate which verified OK */
+   }
+ }
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>,
+L<SSL_CTX_get_verify_mode(3)|SSL_CTX_get_verify_mode(3)>,
+L<SSL_get_verify_result(3)|SSL_get_verify_result(3)>,
+L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>,
+L<SSL_get_peer_certificate(3)|SSL_get_peer_certificate(3)>,
+L<SSL_CTX_set_cert_verify_callback(3)|SSL_CTX_set_cert_verify_callback(3)>,
+L<SSL_get_ex_data_X509_STORE_CTX_idx(3)|SSL_get_ex_data_X509_STORE_CTX_idx(3)>,
+L<SSL_get_ex_new_index(3)|SSL_get_ex_new_index(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_use_certificate.pod b/openssl/doc/ssl/SSL_CTX_use_certificate.pod
new file mode 100644
index 0000000..10be95f
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_use_certificate.pod
@@ -0,0 +1,169 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_use_certificate, SSL_CTX_use_certificate_ASN1, SSL_CTX_use_certificate_file, SSL_use_certificate, SSL_use_certificate_ASN1, SSL_use_certificate_file, SSL_CTX_use_certificate_chain_file, SSL_CTX_use_PrivateKey, SSL_CTX_use_PrivateKey_ASN1, SSL_CTX_use_PrivateKey_file, SSL_CTX_use_RSAPrivateKey, SSL_CTX_use_RSAPrivateKey_ASN1, SSL_CTX_use_RSAPrivateKey_file, SSL_use_PrivateKey_file, SSL_use_PrivateKey_ASN1, SSL_use_PrivateKey, SSL_use_RSAPrivateKey, SSL_use_RSAPrivateKey_ASN1, SSL_use_RSAPrivateKey_file, SSL_CTX_check_private_key, SSL_check_private_key - load certificate and key data
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
+ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, unsigned char *d);
+ int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
+ int SSL_use_certificate(SSL *ssl, X509 *x);
+ int SSL_use_certificate_ASN1(SSL *ssl, unsigned char *d, int len);
+ int SSL_use_certificate_file(SSL *ssl, const char *file, int type);
+
+ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file);
+
+ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
+ int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, unsigned char *d,
+				 long len);
+ int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+ int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
+ int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, unsigned char *d, long len);
+ int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
+ int SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, unsigned char *d, long len);
+ int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type);
+ int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
+ int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len);
+ int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
+
+ int SSL_CTX_check_private_key(const SSL_CTX *ctx);
+ int SSL_check_private_key(const SSL *ssl);
+
+=head1 DESCRIPTION
+
+These functions load the certificates and private keys into the SSL_CTX
+or SSL object, respectively.
+
+The SSL_CTX_* class of functions loads the certificates and keys into the
+SSL_CTX object B<ctx>. The information is passed to SSL objects B<ssl>
+created from B<ctx> with L<SSL_new(3)|SSL_new(3)> by copying, so that
+changes applied to B<ctx> do not propagate to already existing SSL objects.
+
+The SSL_* class of functions only loads certificates and keys into a
+specific SSL object. The specific information is kept, when
+L<SSL_clear(3)|SSL_clear(3)> is called for this SSL object.
+
+SSL_CTX_use_certificate() loads the certificate B<x> into B<ctx>,
+SSL_use_certificate() loads B<x> into B<ssl>. The rest of the
+certificates needed to form the complete certificate chain can be
+specified using the
+L<SSL_CTX_add_extra_chain_cert(3)|SSL_CTX_add_extra_chain_cert(3)>
+function.
+
+SSL_CTX_use_certificate_ASN1() loads the ASN1 encoded certificate from
+the memory location B<d> (with length B<len>) into B<ctx>,
+SSL_use_certificate_ASN1() loads the ASN1 encoded certificate into B<ssl>.
+
+SSL_CTX_use_certificate_file() loads the first certificate stored in B<file>
+into B<ctx>. The formatting B<type> of the certificate must be specified
+from the known types SSL_FILETYPE_PEM, SSL_FILETYPE_ASN1.
+SSL_use_certificate_file() loads the certificate from B<file> into B<ssl>.
+See the NOTES section on why SSL_CTX_use_certificate_chain_file()
+should be preferred.
+
+SSL_CTX_use_certificate_chain_file() loads a certificate chain from 
+B<file> into B<ctx>. The certificates must be in PEM format and must
+be sorted starting with the subject's certificate (actual client or server
+certificate), followed by intermediate CA certificates if applicable, and
+ending at the highest level (root) CA.
+There is no corresponding function working on a single SSL object.
+
+SSL_CTX_use_PrivateKey() adds B<pkey> as private key to B<ctx>.
+SSL_CTX_use_RSAPrivateKey() adds the private key B<rsa> of type RSA
+to B<ctx>. SSL_use_PrivateKey() adds B<pkey> as private key to B<ssl>;
+SSL_use_RSAPrivateKey() adds B<rsa> as private key of type RSA to B<ssl>.
+If a certificate has already been set and the private does not belong
+to the certificate an error is returned. To change a certificate, private
+key pair the new certificate needs to be set with SSL_use_certificate()
+or SSL_CTX_use_certificate() before setting the private key with
+SSL_CTX_use_PrivateKey() or SSL_use_PrivateKey(). 
+
+
+SSL_CTX_use_PrivateKey_ASN1() adds the private key of type B<pk>
+stored at memory location B<d> (length B<len>) to B<ctx>.
+SSL_CTX_use_RSAPrivateKey_ASN1() adds the private key of type RSA
+stored at memory location B<d> (length B<len>) to B<ctx>.
+SSL_use_PrivateKey_ASN1() and SSL_use_RSAPrivateKey_ASN1() add the private
+key to B<ssl>.
+
+SSL_CTX_use_PrivateKey_file() adds the first private key found in
+B<file> to B<ctx>. The formatting B<type> of the certificate must be specified
+from the known types SSL_FILETYPE_PEM, SSL_FILETYPE_ASN1.
+SSL_CTX_use_RSAPrivateKey_file() adds the first private RSA key found in
+B<file> to B<ctx>. SSL_use_PrivateKey_file() adds the first private key found
+in B<file> to B<ssl>; SSL_use_RSAPrivateKey_file() adds the first private
+RSA key found to B<ssl>.
+
+SSL_CTX_check_private_key() checks the consistency of a private key with
+the corresponding certificate loaded into B<ctx>. If more than one
+key/certificate pair (RSA/DSA) is installed, the last item installed will
+be checked. If e.g. the last item was a RSA certificate or key, the RSA
+key/certificate pair will be checked. SSL_check_private_key() performs
+the same check for B<ssl>. If no key/certificate was explicitly added for
+this B<ssl>, the last item added into B<ctx> will be checked.
+
+=head1 NOTES
+  
+The internal certificate store of OpenSSL can hold two private key/certificate
+pairs at a time: one key/certificate of type RSA and one key/certificate
+of type DSA. The certificate used depends on the cipher select, see
+also L<SSL_CTX_set_cipher_list(3)|SSL_CTX_set_cipher_list(3)>.
+
+When reading certificates and private keys from file, files of type
+SSL_FILETYPE_ASN1 (also known as B<DER>, binary encoding) can only contain
+one certificate or private key, consequently 
+SSL_CTX_use_certificate_chain_file() is only applicable to PEM formatting.
+Files of type SSL_FILETYPE_PEM can contain more than one item.
+
+SSL_CTX_use_certificate_chain_file() adds the first certificate found
+in the file to the certificate store. The other certificates are added
+to the store of chain certificates using
+L<SSL_CTX_add_extra_chain_cert(3)|SSL_CTX_add_extra_chain_cert(3)>.
+There exists only one extra chain store, so that the same chain is appended
+to both types of certificates, RSA and DSA! If it is not intended to use
+both type of certificate at the same time, it is recommended to use the
+SSL_CTX_use_certificate_chain_file() instead of the
+SSL_CTX_use_certificate_file() function in order to allow the use of
+complete certificate chains even when no trusted CA storage is used or
+when the CA issuing the certificate shall not be added to the trusted
+CA storage.
+
+If additional certificates are needed to complete the chain during the
+TLS negotiation, CA certificates are additionally looked up in the
+locations of trusted CA certificates, see
+L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>.
+
+The private keys loaded from file can be encrypted. In order to successfully
+load encrypted keys, a function returning the passphrase must have been
+supplied, see
+L<SSL_CTX_set_default_passwd_cb(3)|SSL_CTX_set_default_passwd_cb(3)>.
+(Certificate files might be encrypted as well from the technical point
+of view, it however does not make sense as the data in the certificate
+is considered public anyway.)
+
+=head1 RETURN VALUES
+
+On success, the functions return 1.
+Otherwise check out the error stack to find out the reason.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>, L<SSL_clear(3)|SSL_clear(3)>,
+L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>,
+L<SSL_CTX_set_default_passwd_cb(3)|SSL_CTX_set_default_passwd_cb(3)>,
+L<SSL_CTX_set_cipher_list(3)|SSL_CTX_set_cipher_list(3)>,
+L<SSL_CTX_set_client_cert_cb(3)|SSL_CTX_set_client_cert_cb(3)>,
+L<SSL_CTX_add_extra_chain_cert(3)|SSL_CTX_add_extra_chain_cert(3)>
+
+=head1 HISTORY
+
+Support for DER encoded private keys (SSL_FILETYPE_ASN1) in
+SSL_CTX_use_PrivateKey_file() and SSL_use_PrivateKey_file() was added
+in 0.9.8 .
+
+=cut
diff --git a/openssl/doc/ssl/SSL_CTX_use_psk_identity_hint.pod b/openssl/doc/ssl/SSL_CTX_use_psk_identity_hint.pod
new file mode 100644
index 0000000..b80e25b
--- /dev/null
+++ b/openssl/doc/ssl/SSL_CTX_use_psk_identity_hint.pod
@@ -0,0 +1,102 @@
+=pod
+
+=begin comment
+
+Copyright 2005 Nokia. All rights reserved.
+
+The portions of the attached software ("Contribution") is developed by
+Nokia Corporation and is licensed pursuant to the OpenSSL open source
+license.
+
+The Contribution, originally written by Mika Kousa and Pasi Eronen of
+Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+support (see RFC 4279) to OpenSSL.
+
+No patent licenses or other rights except those expressly stated in
+the OpenSSL open source license shall be deemed granted or received
+expressly, by implication, estoppel, or otherwise.
+
+No assurances are provided by Nokia that the Contribution does not
+infringe the patent or other intellectual property rights of any third
+party or that the license provides you with all the necessary rights
+to make use of the Contribution.
+
+THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+OTHERWISE.
+
+=end comment
+
+=head1 NAME
+
+SSL_CTX_use_psk_identity_hint, SSL_use_psk_identity_hint,
+SSL_CTX_set_psk_server_callback, SSL_set_psk_server_callback - set PSK
+identity hint to use
+
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *hint);
+ int SSL_use_psk_identity_hint(SSL *ssl, const char *hint);
+
+ void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx,
+	unsigned int (*callback)(SSL *ssl, const char *identity,
+	unsigned char *psk, int max_psk_len));
+ void SSL_set_psk_server_callback(SSL *ssl,
+	unsigned int (*callback)(SSL *ssl, const char *identity,
+	unsigned char *psk, int max_psk_len));
+
+
+=head1 DESCRIPTION
+
+SSL_CTX_use_psk_identity_hint() sets the given B<NULL>-terminated PSK
+identity hint B<hint> to SSL context object
+B<ctx>. SSL_use_psk_identity_hint() sets the given B<NULL>-terminated
+PSK identity hint B<hint> to SSL connection object B<ssl>. If B<hint>
+is B<NULL> the current hint from B<ctx> or B<ssl> is deleted.
+
+In the case where PSK identity hint is B<NULL>, the server
+does not send the ServerKeyExchange message to the client.
+
+A server application must provide a callback function which is called
+when the server receives the ClientKeyExchange message from the
+client. The purpose of the callback function is to validate the
+received PSK identity and to fetch the pre-shared key used during the
+connection setup phase. The callback is set using functions
+SSL_CTX_set_psk_server_callback() or
+SSL_set_psk_server_callback(). The callback function is given the
+connection in parameter B<ssl>, B<NULL>-terminated PSK identity sent
+by the client in parameter B<identity>, and a buffer B<psk> of length
+B<max_psk_len> bytes where the pre-shared key is to be stored.
+
+
+=head1 RETURN VALUES
+
+SSL_CTX_use_psk_identity_hint() and SSL_use_psk_identity_hint() return
+1 on success, 0 otherwise.
+
+Return values from the server callback are interpreted as follows:
+
+=item > 0
+
+PSK identity was found and the server callback has provided the PSK
+successfully in parameter B<psk>. Return value is the length of
+B<psk> in bytes. It is an error to return a value greater than
+B<max_psk_len>.
+
+If the PSK identity was not found but the callback instructs the
+protocol to continue anyway, the callback must provide some random
+data to B<psk> and return the length of the random data, so the
+connection will fail with decryption_error before it will be finished
+completely.
+
+=item 0
+
+PSK identity was not found. An "unknown_psk_identity" alert message
+will be sent and the connection setup fails.
+
+=cut
diff --git a/openssl/doc/ssl/SSL_SESSION_free.pod b/openssl/doc/ssl/SSL_SESSION_free.pod
new file mode 100644
index 0000000..110ec73
--- /dev/null
+++ b/openssl/doc/ssl/SSL_SESSION_free.pod
@@ -0,0 +1,55 @@
+=pod
+
+=head1 NAME
+
+SSL_SESSION_free - free an allocated SSL_SESSION structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_SESSION_free(SSL_SESSION *session);
+
+=head1 DESCRIPTION
+
+SSL_SESSION_free() decrements the reference count of B<session> and removes
+the B<SSL_SESSION> structure pointed to by B<session> and frees up the allocated
+memory, if the reference count has reached 0.
+
+=head1 NOTES
+
+SSL_SESSION objects are allocated, when a TLS/SSL handshake operation
+is successfully completed. Depending on the settings, see
+L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
+the SSL_SESSION objects are internally referenced by the SSL_CTX and
+linked into its session cache. SSL objects may be using the SSL_SESSION object;
+as a session may be reused, several SSL objects may be using one SSL_SESSION
+object at the same time. It is therefore crucial to keep the reference
+count (usage information) correct and not delete a SSL_SESSION object
+that is still used, as this may lead to program failures due to
+dangling pointers. These failures may also appear delayed, e.g.
+when an SSL_SESSION object was completely freed as the reference count
+incorrectly became 0, but it is still referenced in the internal
+session cache and the cache list is processed during a
+L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)> operation.
+
+SSL_SESSION_free() must only be called for SSL_SESSION objects, for
+which the reference count was explicitly incremented (e.g.
+by calling SSL_get1_session(), see L<SSL_get_session(3)|SSL_get_session(3)>)
+or when the SSL_SESSION object was generated outside a TLS handshake
+operation, e.g. by using L<d2i_SSL_SESSION(3)|d2i_SSL_SESSION(3)>.
+It must not be called on other SSL_SESSION objects, as this would cause
+incorrect reference counts and therefore program failures.
+
+=head1 RETURN VALUES
+
+SSL_SESSION_free() does not provide diagnostic information.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_get_session(3)|SSL_get_session(3)>,
+L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
+L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)>,
+ L<d2i_SSL_SESSION(3)|d2i_SSL_SESSION(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_SESSION_get_ex_new_index.pod b/openssl/doc/ssl/SSL_SESSION_get_ex_new_index.pod
new file mode 100644
index 0000000..657cda9
--- /dev/null
+++ b/openssl/doc/ssl/SSL_SESSION_get_ex_new_index.pod
@@ -0,0 +1,61 @@
+=pod
+
+=head1 NAME
+
+SSL_SESSION_get_ex_new_index, SSL_SESSION_set_ex_data, SSL_SESSION_get_ex_data - internal application specific data functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_SESSION_get_ex_new_index(long argl, void *argp,
+                CRYPTO_EX_new *new_func,
+                CRYPTO_EX_dup *dup_func,
+                CRYPTO_EX_free *free_func);
+
+ int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx, void *arg);
+
+ void *SSL_SESSION_get_ex_data(const SSL_SESSION *session, int idx);
+
+ typedef int new_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                int idx, long argl, void *argp);
+ typedef void free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                int idx, long argl, void *argp);
+ typedef int dup_func(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d,
+                int idx, long argl, void *argp);
+
+=head1 DESCRIPTION
+
+Several OpenSSL structures can have application specific data attached to them.
+These functions are used internally by OpenSSL to manipulate application
+specific data attached to a specific structure.
+
+SSL_SESSION_get_ex_new_index() is used to register a new index for application
+specific data.
+
+SSL_SESSION_set_ex_data() is used to store application data at B<arg> for B<idx>
+into the B<session> object.
+
+SSL_SESSION_get_ex_data() is used to retrieve the information for B<idx> from
+B<session>.
+
+A detailed description for the B<*_get_ex_new_index()> functionality
+can be found in L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>.
+The B<*_get_ex_data()> and B<*_set_ex_data()> functionality is described in
+L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>.
+
+=head1 WARNINGS
+
+The application data is only maintained for sessions held in memory. The
+application data is not included when dumping the session with
+i2d_SSL_SESSION() (and all functions indirectly calling the dump functions
+like PEM_write_SSL_SESSION() and PEM_write_bio_SSL_SESSION()) and can
+therefore not be restored.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>,
+L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>,
+L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_SESSION_get_time.pod b/openssl/doc/ssl/SSL_SESSION_get_time.pod
new file mode 100644
index 0000000..490337a
--- /dev/null
+++ b/openssl/doc/ssl/SSL_SESSION_get_time.pod
@@ -0,0 +1,64 @@
+=pod
+
+=head1 NAME
+
+SSL_SESSION_get_time, SSL_SESSION_set_time, SSL_SESSION_get_timeout, SSL_SESSION_set_timeout - retrieve and manipulate session time and timeout settings
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ long SSL_SESSION_get_time(const SSL_SESSION *s);
+ long SSL_SESSION_set_time(SSL_SESSION *s, long tm);
+ long SSL_SESSION_get_timeout(const SSL_SESSION *s);
+ long SSL_SESSION_set_timeout(SSL_SESSION *s, long tm);
+
+ long SSL_get_time(const SSL_SESSION *s);
+ long SSL_set_time(SSL_SESSION *s, long tm);
+ long SSL_get_timeout(const SSL_SESSION *s);
+ long SSL_set_timeout(SSL_SESSION *s, long tm);
+
+=head1 DESCRIPTION
+
+SSL_SESSION_get_time() returns the time at which the session B<s> was
+established. The time is given in seconds since the Epoch and therefore
+compatible to the time delivered by the time() call.
+
+SSL_SESSION_set_time() replaces the creation time of the session B<s> with
+the chosen value B<tm>.
+
+SSL_SESSION_get_timeout() returns the timeout value set for session B<s>
+in seconds.
+
+SSL_SESSION_set_timeout() sets the timeout value for session B<s> in seconds
+to B<tm>.
+
+The SSL_get_time(), SSL_set_time(), SSL_get_timeout(), and SSL_set_timeout()
+functions are synonyms for the SSL_SESSION_*() counterparts.
+
+=head1 NOTES
+
+Sessions are expired by examining the creation time and the timeout value.
+Both are set at creation time of the session to the actual time and the
+default timeout value at creation, respectively, as set by
+L<SSL_CTX_set_timeout(3)|SSL_CTX_set_timeout(3)>.
+Using these functions it is possible to extend or shorten the lifetime
+of the session.
+
+=head1 RETURN VALUES
+
+SSL_SESSION_get_time() and SSL_SESSION_get_timeout() return the currently
+valid values.
+
+SSL_SESSION_set_time() and SSL_SESSION_set_timeout() return 1 on success.
+
+If any of the function is passed the NULL pointer for the session B<s>, 
+0 is returned.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>,
+L<SSL_CTX_set_timeout(3)|SSL_CTX_set_timeout(3)>,
+L<SSL_get_default_timeout(3)|SSL_get_default_timeout(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_accept.pod b/openssl/doc/ssl/SSL_accept.pod
new file mode 100644
index 0000000..cc724c0
--- /dev/null
+++ b/openssl/doc/ssl/SSL_accept.pod
@@ -0,0 +1,76 @@
+=pod
+
+=head1 NAME
+
+SSL_accept - wait for a TLS/SSL client to initiate a TLS/SSL handshake
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_accept(SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_accept() waits for a TLS/SSL client to initiate the TLS/SSL handshake.
+The communication channel must already have been set and assigned to the
+B<ssl> by setting an underlying B<BIO>.
+
+=head1 NOTES
+
+The behaviour of SSL_accept() depends on the underlying BIO. 
+
+If the underlying BIO is B<blocking>, SSL_accept() will only return once the
+handshake has been finished or an error occurred, except for SGC (Server
+Gated Cryptography). For SGC, SSL_accept() may return with -1, but
+SSL_get_error() will yield B<SSL_ERROR_WANT_READ/WRITE> and SSL_accept()
+should be called again.
+
+If the underlying BIO is B<non-blocking>, SSL_accept() will also return
+when the underlying BIO could not satisfy the needs of SSL_accept()
+to continue the handshake, indicating the problem by the return value -1.
+In this case a call to SSL_get_error() with the
+return value of SSL_accept() will yield B<SSL_ERROR_WANT_READ> or
+B<SSL_ERROR_WANT_WRITE>. The calling process then must repeat the call after
+taking appropriate action to satisfy the needs of SSL_accept().
+The action depends on the underlying BIO. When using a non-blocking socket,
+nothing is to be done, but select() can be used to check for the required
+condition. When using a buffering BIO, like a BIO pair, data must be written
+into or retrieved out of the BIO before being able to continue.
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item 1
+
+The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been
+established.
+
+=item 0
+
+The TLS/SSL handshake was not successful but was shut down controlled and
+by the specifications of the TLS/SSL protocol. Call SSL_get_error() with the
+return value B<ret> to find out the reason.
+
+=item E<lt>0
+
+The TLS/SSL handshake was not successful because a fatal error occurred either
+at the protocol level or a connection failure occurred. The shutdown was
+not clean. It can also occur of action is need to continue the operation
+for non-blocking BIOs. Call SSL_get_error() with the return value B<ret>
+to find out the reason.
+
+=back
+
+=head1 SEE ALSO
+
+L<SSL_get_error(3)|SSL_get_error(3)>, L<SSL_connect(3)|SSL_connect(3)>,
+L<SSL_shutdown(3)|SSL_shutdown(3)>, L<ssl(3)|ssl(3)>, L<bio(3)|bio(3)>,
+L<SSL_set_connect_state(3)|SSL_set_connect_state(3)>,
+L<SSL_do_handshake(3)|SSL_do_handshake(3)>,
+L<SSL_CTX_new(3)|SSL_CTX_new(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_alert_type_string.pod b/openssl/doc/ssl/SSL_alert_type_string.pod
new file mode 100644
index 0000000..94e28cc
--- /dev/null
+++ b/openssl/doc/ssl/SSL_alert_type_string.pod
@@ -0,0 +1,228 @@
+=pod
+
+=head1 NAME
+
+SSL_alert_type_string, SSL_alert_type_string_long, SSL_alert_desc_string, SSL_alert_desc_string_long - get textual description of alert information
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ const char *SSL_alert_type_string(int value);
+ const char *SSL_alert_type_string_long(int value);
+
+ const char *SSL_alert_desc_string(int value);
+ const char *SSL_alert_desc_string_long(int value);
+
+=head1 DESCRIPTION
+
+SSL_alert_type_string() returns a one letter string indicating the
+type of the alert specified by B<value>.
+
+SSL_alert_type_string_long() returns a string indicating the type of the alert
+specified by B<value>.
+
+SSL_alert_desc_string() returns a two letter string as a short form
+describing the reason of the alert specified by B<value>.
+
+SSL_alert_desc_string_long() returns a string describing the reason
+of the alert specified by B<value>.
+
+=head1 NOTES
+
+When one side of an SSL/TLS communication wants to inform the peer about
+a special situation, it sends an alert. The alert is sent as a special message
+and does not influence the normal data stream (unless its contents results
+in the communication being canceled).
+
+A warning alert is sent, when a non-fatal error condition occurs. The
+"close notify" alert is sent as a warning alert. Other examples for
+non-fatal errors are certificate errors ("certificate expired",
+"unsupported certificate"), for which a warning alert may be sent.
+(The sending party may however decide to send a fatal error.) The
+receiving side may cancel the connection on reception of a warning
+alert on it discretion.
+
+Several alert messages must be sent as fatal alert messages as specified
+by the TLS RFC. A fatal alert always leads to a connection abort.
+
+=head1 RETURN VALUES
+
+The following strings can occur for SSL_alert_type_string() or
+SSL_alert_type_string_long():
+
+=over 4
+
+=item "W"/"warning"
+
+=item "F"/"fatal"
+
+=item "U"/"unknown"
+
+This indicates that no support is available for this alert type.
+Probably B<value> does not contain a correct alert message.
+
+=back
+
+The following strings can occur for SSL_alert_desc_string() or
+SSL_alert_desc_string_long():
+
+=over 4
+
+=item "CN"/"close notify"
+
+The connection shall be closed. This is a warning alert.
+
+=item "UM"/"unexpected message"
+
+An inappropriate message was received. This alert is always fatal
+and should never be observed in communication between proper
+implementations.
+
+=item "BM"/"bad record mac"
+
+This alert is returned if a record is received with an incorrect
+MAC. This message is always fatal.
+
+=item "DF"/"decompression failure"
+
+The decompression function received improper input (e.g. data
+that would expand to excessive length). This message is always
+fatal.
+
+=item "HF"/"handshake failure"
+
+Reception of a handshake_failure alert message indicates that the
+sender was unable to negotiate an acceptable set of security
+parameters given the options available. This is a fatal error.
+
+=item "NC"/"no certificate"
+
+A client, that was asked to send a certificate, does not send a certificate
+(SSLv3 only).
+
+=item "BC"/"bad certificate"
+
+A certificate was corrupt, contained signatures that did not
+verify correctly, etc
+
+=item "UC"/"unsupported certificate"
+
+A certificate was of an unsupported type.
+
+=item "CR"/"certificate revoked"
+
+A certificate was revoked by its signer.
+
+=item "CE"/"certificate expired"
+
+A certificate has expired or is not currently valid.
+
+=item "CU"/"certificate unknown"
+
+Some other (unspecified) issue arose in processing the
+certificate, rendering it unacceptable.
+
+=item "IP"/"illegal parameter"
+
+A field in the handshake was out of range or inconsistent with
+other fields. This is always fatal.
+
+=item "DC"/"decryption failed"
+
+A TLSCiphertext decrypted in an invalid way: either it wasn't an
+even multiple of the block length or its padding values, when
+checked, weren't correct. This message is always fatal.
+
+=item "RO"/"record overflow"
+
+A TLSCiphertext record was received which had a length more than
+2^14+2048 bytes, or a record decrypted to a TLSCompressed record
+with more than 2^14+1024 bytes. This message is always fatal.
+
+=item "CA"/"unknown CA"
+
+A valid certificate chain or partial chain was received, but the
+certificate was not accepted because the CA certificate could not
+be located or couldn't be matched with a known, trusted CA.  This
+message is always fatal.
+
+=item "AD"/"access denied"
+
+A valid certificate was received, but when access control was
+applied, the sender decided not to proceed with negotiation.
+This message is always fatal.
+
+=item "DE"/"decode error"
+
+A message could not be decoded because some field was out of the
+specified range or the length of the message was incorrect. This
+message is always fatal.
+
+=item "CY"/"decrypt error"
+
+A handshake cryptographic operation failed, including being
+unable to correctly verify a signature, decrypt a key exchange,
+or validate a finished message.
+
+=item "ER"/"export restriction"
+
+A negotiation not in compliance with export restrictions was
+detected; for example, attempting to transfer a 1024 bit
+ephemeral RSA key for the RSA_EXPORT handshake method. This
+message is always fatal.
+
+=item "PV"/"protocol version"
+
+The protocol version the client has attempted to negotiate is
+recognized, but not supported. (For example, old protocol
+versions might be avoided for security reasons). This message is
+always fatal.
+
+=item "IS"/"insufficient security"
+
+Returned instead of handshake_failure when a negotiation has
+failed specifically because the server requires ciphers more
+secure than those supported by the client. This message is always
+fatal.
+
+=item "IE"/"internal error"
+
+An internal error unrelated to the peer or the correctness of the
+protocol makes it impossible to continue (such as a memory
+allocation failure). This message is always fatal.
+
+=item "US"/"user canceled"
+
+This handshake is being canceled for some reason unrelated to a
+protocol failure. If the user cancels an operation after the
+handshake is complete, just closing the connection by sending a
+close_notify is more appropriate. This alert should be followed
+by a close_notify. This message is generally a warning.
+
+=item "NR"/"no renegotiation"
+
+Sent by the client in response to a hello request or by the
+server in response to a client hello after initial handshaking.
+Either of these would normally lead to renegotiation; when that
+is not appropriate, the recipient should respond with this alert;
+at that point, the original requester can decide whether to
+proceed with the connection. One case where this would be
+appropriate would be where a server has spawned a process to
+satisfy a request; the process might receive security parameters
+(key length, authentication, etc.) at startup and it might be
+difficult to communicate changes to these parameters after that
+point. This message is always a warning.
+
+=item "UK"/"unknown"
+
+This indicates that no description is available for this alert type.
+Probably B<value> does not contain a correct alert message.
+
+=back
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_CTX_set_info_callback(3)|SSL_CTX_set_info_callback(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_clear.pod b/openssl/doc/ssl/SSL_clear.pod
new file mode 100644
index 0000000..d4df1bf
--- /dev/null
+++ b/openssl/doc/ssl/SSL_clear.pod
@@ -0,0 +1,75 @@
+=pod
+
+=head1 NAME
+
+SSL_clear - reset SSL object to allow another connection
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_clear(SSL *ssl);
+
+=head1 DESCRIPTION
+
+Reset B<ssl> to allow another connection. All settings (method, ciphers,
+BIOs) are kept.
+
+=head1 NOTES
+
+SSL_clear is used to prepare an SSL object for a new connection. While all
+settings are kept, a side effect is the handling of the current SSL session.
+If a session is still B<open>, it is considered bad and will be removed
+from the session cache, as required by RFC2246. A session is considered open,
+if L<SSL_shutdown(3)|SSL_shutdown(3)> was not called for the connection
+or at least L<SSL_set_shutdown(3)|SSL_set_shutdown(3)> was used to
+set the SSL_SENT_SHUTDOWN state.
+
+If a session was closed cleanly, the session object will be kept and all
+settings corresponding. This explicitly means, that e.g. the special method
+used during the session will be kept for the next handshake. So if the
+session was a TLSv1 session, a SSL client object will use a TLSv1 client
+method for the next handshake and a SSL server object will use a TLSv1
+server method, even if SSLv23_*_methods were chosen on startup. This
+will might lead to connection failures (see L<SSL_new(3)|SSL_new(3)>)
+for a description of the method's properties.
+
+=head1 WARNINGS
+
+SSL_clear() resets the SSL object to allow for another connection. The
+reset operation however keeps several settings of the last sessions
+(some of these settings were made automatically during the last
+handshake). It only makes sense for a new connection with the exact
+same peer that shares these settings, and may fail if that peer
+changes its settings between connections. Use the sequence
+L<SSL_get_session(3)|SSL_get_session(3)>;
+L<SSL_new(3)|SSL_new(3)>;
+L<SSL_set_session(3)|SSL_set_session(3)>;
+L<SSL_free(3)|SSL_free(3)>
+instead to avoid such failures
+(or simply L<SSL_free(3)|SSL_free(3)>; L<SSL_new(3)|SSL_new(3)>
+if session reuse is not desired).
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item 0
+
+The SSL_clear() operation could not be performed. Check the error stack to
+find out the reason.
+
+=item 1
+
+The SSL_clear() operation was successful.
+
+=back
+
+L<SSL_new(3)|SSL_new(3)>, L<SSL_free(3)|SSL_free(3)>,
+L<SSL_shutdown(3)|SSL_shutdown(3)>, L<SSL_set_shutdown(3)|SSL_set_shutdown(3)>,
+L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)>, L<ssl(3)|ssl(3)>,
+L<SSL_CTX_set_client_cert_cb(3)|SSL_CTX_set_client_cert_cb(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_connect.pod b/openssl/doc/ssl/SSL_connect.pod
new file mode 100644
index 0000000..cc56ebb
--- /dev/null
+++ b/openssl/doc/ssl/SSL_connect.pod
@@ -0,0 +1,73 @@
+=pod
+
+=head1 NAME
+
+SSL_connect - initiate the TLS/SSL handshake with an TLS/SSL server
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_connect(SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_connect() initiates the TLS/SSL handshake with a server. The communication
+channel must already have been set and assigned to the B<ssl> by setting an
+underlying B<BIO>.
+
+=head1 NOTES
+
+The behaviour of SSL_connect() depends on the underlying BIO. 
+
+If the underlying BIO is B<blocking>, SSL_connect() will only return once the
+handshake has been finished or an error occurred.
+
+If the underlying BIO is B<non-blocking>, SSL_connect() will also return
+when the underlying BIO could not satisfy the needs of SSL_connect()
+to continue the handshake, indicating the problem by the return value -1.
+In this case a call to SSL_get_error() with the
+return value of SSL_connect() will yield B<SSL_ERROR_WANT_READ> or
+B<SSL_ERROR_WANT_WRITE>. The calling process then must repeat the call after
+taking appropriate action to satisfy the needs of SSL_connect().
+The action depends on the underlying BIO. When using a non-blocking socket,
+nothing is to be done, but select() can be used to check for the required
+condition. When using a buffering BIO, like a BIO pair, data must be written
+into or retrieved out of the BIO before being able to continue.
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item 1
+
+The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been
+established.
+
+=item 0
+
+The TLS/SSL handshake was not successful but was shut down controlled and
+by the specifications of the TLS/SSL protocol. Call SSL_get_error() with the
+return value B<ret> to find out the reason.
+
+=item E<lt>0
+
+The TLS/SSL handshake was not successful, because a fatal error occurred either
+at the protocol level or a connection failure occurred. The shutdown was
+not clean. It can also occur of action is need to continue the operation
+for non-blocking BIOs. Call SSL_get_error() with the return value B<ret>
+to find out the reason.
+
+=back
+
+=head1 SEE ALSO
+
+L<SSL_get_error(3)|SSL_get_error(3)>, L<SSL_accept(3)|SSL_accept(3)>,
+L<SSL_shutdown(3)|SSL_shutdown(3)>, L<ssl(3)|ssl(3)>, L<bio(3)|bio(3)>,
+L<SSL_set_connect_state(3)|SSL_set_connect_state(3)>,
+L<SSL_do_handshake(3)|SSL_do_handshake(3)>,
+L<SSL_CTX_new(3)|SSL_CTX_new(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_do_handshake.pod b/openssl/doc/ssl/SSL_do_handshake.pod
new file mode 100644
index 0000000..2435764
--- /dev/null
+++ b/openssl/doc/ssl/SSL_do_handshake.pod
@@ -0,0 +1,75 @@
+=pod
+
+=head1 NAME
+
+SSL_do_handshake - perform a TLS/SSL handshake
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_do_handshake(SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_do_handshake() will wait for a SSL/TLS handshake to take place. If the
+connection is in client mode, the handshake will be started. The handshake
+routines may have to be explicitly set in advance using either
+L<SSL_set_connect_state(3)|SSL_set_connect_state(3)> or
+L<SSL_set_accept_state(3)|SSL_set_accept_state(3)>.
+
+=head1 NOTES
+
+The behaviour of SSL_do_handshake() depends on the underlying BIO.
+
+If the underlying BIO is B<blocking>, SSL_do_handshake() will only return
+once the handshake has been finished or an error occurred, except for SGC
+(Server Gated Cryptography). For SGC, SSL_do_handshake() may return with -1,
+but SSL_get_error() will yield B<SSL_ERROR_WANT_READ/WRITE> and
+SSL_do_handshake() should be called again.
+
+If the underlying BIO is B<non-blocking>, SSL_do_handshake() will also return
+when the underlying BIO could not satisfy the needs of SSL_do_handshake()
+to continue the handshake. In this case a call to SSL_get_error() with the
+return value of SSL_do_handshake() will yield B<SSL_ERROR_WANT_READ> or
+B<SSL_ERROR_WANT_WRITE>. The calling process then must repeat the call after
+taking appropriate action to satisfy the needs of SSL_do_handshake().
+The action depends on the underlying BIO. When using a non-blocking socket,
+nothing is to be done, but select() can be used to check for the required
+condition. When using a buffering BIO, like a BIO pair, data must be written
+into or retrieved out of the BIO before being able to continue.
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item 1
+
+The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been
+established.
+
+=item 0
+
+The TLS/SSL handshake was not successful but was shut down controlled and
+by the specifications of the TLS/SSL protocol. Call SSL_get_error() with the
+return value B<ret> to find out the reason.
+
+=item E<lt>0
+
+The TLS/SSL handshake was not successful because a fatal error occurred either
+at the protocol level or a connection failure occurred. The shutdown was
+not clean. It can also occur of action is need to continue the operation
+for non-blocking BIOs. Call SSL_get_error() with the return value B<ret>
+to find out the reason.
+
+=back
+
+=head1 SEE ALSO
+
+L<SSL_get_error(3)|SSL_get_error(3)>, L<SSL_connect(3)|SSL_connect(3)>,
+L<SSL_accept(3)|SSL_accept(3)>, L<ssl(3)|ssl(3)>, L<bio(3)|bio(3)>,
+L<SSL_set_connect_state(3)|SSL_set_connect_state(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_free.pod b/openssl/doc/ssl/SSL_free.pod
new file mode 100644
index 0000000..13c1abd
--- /dev/null
+++ b/openssl/doc/ssl/SSL_free.pod
@@ -0,0 +1,44 @@
+=pod
+
+=head1 NAME
+
+SSL_free - free an allocated SSL structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_free(SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_free() decrements the reference count of B<ssl>, and removes the SSL
+structure pointed to by B<ssl> and frees up the allocated memory if the
+reference count has reached 0.
+
+=head1 NOTES
+
+SSL_free() also calls the free()ing procedures for indirectly affected items, if
+applicable: the buffering BIO, the read and write BIOs,
+cipher lists specially created for this B<ssl>, the B<SSL_SESSION>.
+Do not explicitly free these indirectly freed up items before or after
+calling SSL_free(), as trying to free things twice may lead to program
+failure.
+
+The ssl session has reference counts from two users: the SSL object, for
+which the reference count is removed by SSL_free() and the internal
+session cache. If the session is considered bad, because
+L<SSL_shutdown(3)|SSL_shutdown(3)> was not called for the connection
+and L<SSL_set_shutdown(3)|SSL_set_shutdown(3)> was not used to set the
+SSL_SENT_SHUTDOWN state, the session will also be removed
+from the session cache as required by RFC2246.
+
+=head1 RETURN VALUES
+
+SSL_free() does not provide diagnostic information.
+
+L<SSL_new(3)|SSL_new(3)>, L<SSL_clear(3)|SSL_clear(3)>,
+L<SSL_shutdown(3)|SSL_shutdown(3)>, L<SSL_set_shutdown(3)|SSL_set_shutdown(3)>,
+L<ssl(3)|ssl(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_get_SSL_CTX.pod b/openssl/doc/ssl/SSL_get_SSL_CTX.pod
new file mode 100644
index 0000000..659c482
--- /dev/null
+++ b/openssl/doc/ssl/SSL_get_SSL_CTX.pod
@@ -0,0 +1,26 @@
+=pod
+
+=head1 NAME
+
+SSL_get_SSL_CTX - get the SSL_CTX from which an SSL is created
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_get_SSL_CTX() returns a pointer to the SSL_CTX object, from which
+B<ssl> was created with L<SSL_new(3)|SSL_new(3)>.
+
+=head1 RETURN VALUES
+
+The pointer to the SSL_CTX object is returned.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_get_ciphers.pod b/openssl/doc/ssl/SSL_get_ciphers.pod
new file mode 100644
index 0000000..aecadd9
--- /dev/null
+++ b/openssl/doc/ssl/SSL_get_ciphers.pod
@@ -0,0 +1,42 @@
+=pod
+
+=head1 NAME
+
+SSL_get_ciphers, SSL_get_cipher_list - get list of available SSL_CIPHERs
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl);
+ const char *SSL_get_cipher_list(const SSL *ssl, int priority);
+
+=head1 DESCRIPTION
+
+SSL_get_ciphers() returns the stack of available SSL_CIPHERs for B<ssl>,
+sorted by preference. If B<ssl> is NULL or no ciphers are available, NULL
+is returned.
+
+SSL_get_cipher_list() returns a pointer to the name of the SSL_CIPHER
+listed for B<ssl> with B<priority>. If B<ssl> is NULL, no ciphers are
+available, or there are less ciphers than B<priority> available, NULL
+is returned.
+
+=head1 NOTES
+
+The details of the ciphers obtained by SSL_get_ciphers() can be obtained using
+the L<SSL_CIPHER_get_name(3)|SSL_CIPHER_get_name(3)> family of functions.
+
+Call SSL_get_cipher_list() with B<priority> starting from 0 to obtain the
+sorted list of available ciphers, until NULL is returned.
+
+=head1 RETURN VALUES
+
+See DESCRIPTION
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_CTX_set_cipher_list(3)|SSL_CTX_set_cipher_list(3)>,
+L<SSL_CIPHER_get_name(3)|SSL_CIPHER_get_name(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_get_client_CA_list.pod b/openssl/doc/ssl/SSL_get_client_CA_list.pod
new file mode 100644
index 0000000..68181b2
--- /dev/null
+++ b/openssl/doc/ssl/SSL_get_client_CA_list.pod
@@ -0,0 +1,53 @@
+=pod
+
+=head1 NAME
+
+SSL_get_client_CA_list, SSL_CTX_get_client_CA_list - get list of client CAs
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s);
+ STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx); 
+
+=head1 DESCRIPTION
+
+SSL_CTX_get_client_CA_list() returns the list of client CAs explicitly set for
+B<ctx> using L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)>.
+
+SSL_get_client_CA_list() returns the list of client CAs explicitly
+set for B<ssl> using SSL_set_client_CA_list() or B<ssl>'s SSL_CTX object with
+L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)>, when in
+server mode. In client mode, SSL_get_client_CA_list returns the list of
+client CAs sent from the server, if any.
+
+=head1 RETURN VALUES
+
+SSL_CTX_set_client_CA_list() and SSL_set_client_CA_list() do not return
+diagnostic information.
+
+SSL_CTX_add_client_CA() and SSL_add_client_CA() have the following return
+values:
+
+=over 4
+
+=item STACK_OF(X509_NAMES)
+
+List of CA names explicitly set (for B<ctx> or in server mode) or send
+by the server (client mode).
+
+=item NULL
+
+No client CA list was explicitly set (for B<ctx> or in server mode) or
+the server did not send a list of CAs (client mode).
+
+=back
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>,
+L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)>,
+L<SSL_CTX_set_client_cert_cb(3)|SSL_CTX_set_client_cert_cb(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_get_current_cipher.pod b/openssl/doc/ssl/SSL_get_current_cipher.pod
new file mode 100644
index 0000000..e5ab124
--- /dev/null
+++ b/openssl/doc/ssl/SSL_get_current_cipher.pod
@@ -0,0 +1,43 @@
+=pod
+
+=head1 NAME
+
+SSL_get_current_cipher, SSL_get_cipher, SSL_get_cipher_name,
+SSL_get_cipher_bits, SSL_get_cipher_version - get SSL_CIPHER of a connection
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl);
+ #define SSL_get_cipher(s) \
+                SSL_CIPHER_get_name(SSL_get_current_cipher(s))
+ #define SSL_get_cipher_name(s) \
+                SSL_CIPHER_get_name(SSL_get_current_cipher(s))
+ #define SSL_get_cipher_bits(s,np) \
+                SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np)
+ #define SSL_get_cipher_version(s) \
+                SSL_CIPHER_get_version(SSL_get_current_cipher(s))
+
+=head1 DESCRIPTION
+
+SSL_get_current_cipher() returns a pointer to an SSL_CIPHER object containing
+the description of the actually used cipher of a connection established with
+the B<ssl> object.
+
+SSL_get_cipher() and SSL_get_cipher_name() are identical macros to obtain the
+name of the currently used cipher. SSL_get_cipher_bits() is a
+macro to obtain the number of secret/algorithm bits used and 
+SSL_get_cipher_version() returns the protocol name.
+See L<SSL_CIPHER_get_name(3)|SSL_CIPHER_get_name(3)> for more details.
+
+=head1 RETURN VALUES
+
+SSL_get_current_cipher() returns the cipher actually used or NULL, when
+no session has been established.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_CIPHER_get_name(3)|SSL_CIPHER_get_name(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_get_default_timeout.pod b/openssl/doc/ssl/SSL_get_default_timeout.pod
new file mode 100644
index 0000000..a648a9b
--- /dev/null
+++ b/openssl/doc/ssl/SSL_get_default_timeout.pod
@@ -0,0 +1,41 @@
+=pod
+
+=head1 NAME
+
+SSL_get_default_timeout - get default session timeout value
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ long SSL_get_default_timeout(const SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_get_default_timeout() returns the default timeout value assigned to
+SSL_SESSION objects negotiated for the protocol valid for B<ssl>.
+
+=head1 NOTES
+
+Whenever a new session is negotiated, it is assigned a timeout value,
+after which it will not be accepted for session reuse. If the timeout
+value was not explicitly set using
+L<SSL_CTX_set_timeout(3)|SSL_CTX_set_timeout(3)>, the hardcoded default
+timeout for the protocol will be used.
+
+SSL_get_default_timeout() return this hardcoded value, which is 300 seconds
+for all currently supported protocols (SSLv2, SSLv3, and TLSv1).
+
+=head1 RETURN VALUES
+
+See description.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>,
+L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
+L<SSL_SESSION_get_time(3)|SSL_SESSION_get_time(3)>,
+L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)>,
+L<SSL_get_default_timeout(3)|SSL_get_default_timeout(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_get_error.pod b/openssl/doc/ssl/SSL_get_error.pod
new file mode 100644
index 0000000..48c6b15
--- /dev/null
+++ b/openssl/doc/ssl/SSL_get_error.pod
@@ -0,0 +1,114 @@
+=pod
+
+=head1 NAME
+
+SSL_get_error - obtain result code for TLS/SSL I/O operation
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_get_error(const SSL *ssl, int ret);
+
+=head1 DESCRIPTION
+
+SSL_get_error() returns a result code (suitable for the C "switch"
+statement) for a preceding call to SSL_connect(), SSL_accept(), SSL_do_handshake(),
+SSL_read(), SSL_peek(), or SSL_write() on B<ssl>.  The value returned by
+that TLS/SSL I/O function must be passed to SSL_get_error() in parameter
+B<ret>.
+
+In addition to B<ssl> and B<ret>, SSL_get_error() inspects the
+current thread's OpenSSL error queue.  Thus, SSL_get_error() must be
+used in the same thread that performed the TLS/SSL I/O operation, and no
+other OpenSSL function calls should appear in between.  The current
+thread's error queue must be empty before the TLS/SSL I/O operation is
+attempted, or SSL_get_error() will not work reliably.
+
+=head1 RETURN VALUES
+
+The following return values can currently occur:
+
+=over 4
+
+=item SSL_ERROR_NONE
+
+The TLS/SSL I/O operation completed.  This result code is returned
+if and only if B<ret E<gt> 0>.
+
+=item SSL_ERROR_ZERO_RETURN
+
+The TLS/SSL connection has been closed.  If the protocol version is SSL 3.0
+or TLS 1.0, this result code is returned only if a closure
+alert has occurred in the protocol, i.e. if the connection has been
+closed cleanly. Note that in this case B<SSL_ERROR_ZERO_RETURN>
+does not necessarily indicate that the underlying transport
+has been closed.
+
+=item SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE
+
+The operation did not complete; the same TLS/SSL I/O function should be
+called again later.  If, by then, the underlying B<BIO> has data
+available for reading (if the result code is B<SSL_ERROR_WANT_READ>)
+or allows writing data (B<SSL_ERROR_WANT_WRITE>), then some TLS/SSL
+protocol progress will take place, i.e. at least part of an TLS/SSL
+record will be read or written.  Note that the retry may again lead to
+a B<SSL_ERROR_WANT_READ> or B<SSL_ERROR_WANT_WRITE> condition.
+There is no fixed upper limit for the number of iterations that
+may be necessary until progress becomes visible at application
+protocol level.
+
+For socket B<BIO>s (e.g. when SSL_set_fd() was used), select() or
+poll() on the underlying socket can be used to find out when the
+TLS/SSL I/O function should be retried.
+
+Caveat: Any TLS/SSL I/O function can lead to either of
+B<SSL_ERROR_WANT_READ> and B<SSL_ERROR_WANT_WRITE>.  In particular,
+SSL_read() or SSL_peek() may want to write data and SSL_write() may want
+to read data.  This is mainly because TLS/SSL handshakes may occur at any
+time during the protocol (initiated by either the client or the server);
+SSL_read(), SSL_peek(), and SSL_write() will handle any pending handshakes.
+
+=item SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT
+
+The operation did not complete; the same TLS/SSL I/O function should be
+called again later. The underlying BIO was not connected yet to the peer
+and the call would block in connect()/accept(). The SSL function should be
+called again when the connection is established. These messages can only
+appear with a BIO_s_connect() or BIO_s_accept() BIO, respectively.
+In order to find out, when the connection has been successfully established,
+on many platforms select() or poll() for writing on the socket file descriptor
+can be used.
+
+=item SSL_ERROR_WANT_X509_LOOKUP
+
+The operation did not complete because an application callback set by
+SSL_CTX_set_client_cert_cb() has asked to be called again.
+The TLS/SSL I/O function should be called again later.
+Details depend on the application.
+
+=item SSL_ERROR_SYSCALL
+
+Some I/O error occurred.  The OpenSSL error queue may contain more
+information on the error.  If the error queue is empty
+(i.e. ERR_get_error() returns 0), B<ret> can be used to find out more
+about the error: If B<ret == 0>, an EOF was observed that violates
+the protocol.  If B<ret == -1>, the underlying B<BIO> reported an
+I/O error (for socket I/O on Unix systems, consult B<errno> for details).
+
+=item SSL_ERROR_SSL
+
+A failure in the SSL library occurred, usually a protocol error.  The
+OpenSSL error queue contains more information on the error.
+
+=back
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<err(3)|err(3)>
+
+=head1 HISTORY
+
+SSL_get_error() was added in SSLeay 0.8.
+
+=cut
diff --git a/openssl/doc/ssl/SSL_get_ex_data_X509_STORE_CTX_idx.pod b/openssl/doc/ssl/SSL_get_ex_data_X509_STORE_CTX_idx.pod
new file mode 100644
index 0000000..165c6a5
--- /dev/null
+++ b/openssl/doc/ssl/SSL_get_ex_data_X509_STORE_CTX_idx.pod
@@ -0,0 +1,61 @@
+=pod
+
+=head1 NAME
+
+SSL_get_ex_data_X509_STORE_CTX_idx - get ex_data index to access SSL structure
+from X509_STORE_CTX
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_get_ex_data_X509_STORE_CTX_idx(void);
+
+=head1 DESCRIPTION
+
+SSL_get_ex_data_X509_STORE_CTX_idx() returns the index number under which
+the pointer to the SSL object is stored into the X509_STORE_CTX object.
+
+=head1 NOTES
+
+Whenever a X509_STORE_CTX object is created for the verification of the
+peers certificate during a handshake, a pointer to the SSL object is
+stored into the X509_STORE_CTX object to identify the connection affected.
+To retrieve this pointer the X509_STORE_CTX_get_ex_data() function can
+be used with the correct index. This index is globally the same for all
+X509_STORE_CTX objects and can be retrieved using
+SSL_get_ex_data_X509_STORE_CTX_idx(). The index value is set when
+SSL_get_ex_data_X509_STORE_CTX_idx() is first called either by the application
+program directly or indirectly during other SSL setup functions or during
+the handshake.
+
+The value depends on other index values defined for X509_STORE_CTX objects
+before the SSL index is created.
+
+=head1 RETURN VALUES
+
+=over 4
+
+=item E<gt>=0
+
+The index value to access the pointer.
+
+=item E<lt>0
+
+An error occurred, check the error stack for a detailed error message.
+
+=back
+
+=head1 EXAMPLES
+
+The index returned from SSL_get_ex_data_X509_STORE_CTX_idx() allows to
+access the SSL object for the connection to be accessed during the
+verify_callback() when checking the peers certificate. Please check
+the example in L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>,
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>,
+L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_get_ex_new_index.pod b/openssl/doc/ssl/SSL_get_ex_new_index.pod
new file mode 100644
index 0000000..228d23d
--- /dev/null
+++ b/openssl/doc/ssl/SSL_get_ex_new_index.pod
@@ -0,0 +1,59 @@
+=pod
+
+=head1 NAME
+
+SSL_get_ex_new_index, SSL_set_ex_data, SSL_get_ex_data - internal application specific data functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_get_ex_new_index(long argl, void *argp,
+                CRYPTO_EX_new *new_func,
+                CRYPTO_EX_dup *dup_func,
+                CRYPTO_EX_free *free_func);
+
+ int SSL_set_ex_data(SSL *ssl, int idx, void *arg);
+
+ void *SSL_get_ex_data(const SSL *ssl, int idx);
+
+ typedef int new_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                int idx, long argl, void *argp);
+ typedef void free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                int idx, long argl, void *argp);
+ typedef int dup_func(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d,
+                int idx, long argl, void *argp);
+
+=head1 DESCRIPTION
+
+Several OpenSSL structures can have application specific data attached to them.
+These functions are used internally by OpenSSL to manipulate application
+specific data attached to a specific structure.
+
+SSL_get_ex_new_index() is used to register a new index for application
+specific data.
+
+SSL_set_ex_data() is used to store application data at B<arg> for B<idx> into
+the B<ssl> object.
+
+SSL_get_ex_data() is used to retrieve the information for B<idx> from
+B<ssl>.
+
+A detailed description for the B<*_get_ex_new_index()> functionality
+can be found in L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>.
+The B<*_get_ex_data()> and B<*_set_ex_data()> functionality is described in
+L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>.
+
+=head1 EXAMPLES
+
+An example on how to use the functionality is included in the example
+verify_callback() in L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>,
+L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>,
+L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>,
+L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_get_fd.pod b/openssl/doc/ssl/SSL_get_fd.pod
new file mode 100644
index 0000000..89260b5
--- /dev/null
+++ b/openssl/doc/ssl/SSL_get_fd.pod
@@ -0,0 +1,44 @@
+=pod
+
+=head1 NAME
+
+SSL_get_fd - get file descriptor linked to an SSL object
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_get_fd(const SSL *ssl);
+ int SSL_get_rfd(const SSL *ssl);
+ int SSL_get_wfd(const SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_get_fd() returns the file descriptor which is linked to B<ssl>.
+SSL_get_rfd() and SSL_get_wfd() return the file descriptors for the
+read or the write channel, which can be different. If the read and the
+write channel are different, SSL_get_fd() will return the file descriptor
+of the read channel.
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item -1
+
+The operation failed, because the underlying BIO is not of the correct type
+(suitable for file descriptors).
+
+=item E<gt>=0
+
+The file descriptor linked to B<ssl>.
+
+=back
+
+=head1 SEE ALSO
+
+L<SSL_set_fd(3)|SSL_set_fd(3)>, L<ssl(3)|ssl(3)> , L<bio(3)|bio(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_get_peer_cert_chain.pod b/openssl/doc/ssl/SSL_get_peer_cert_chain.pod
new file mode 100644
index 0000000..49fb88f
--- /dev/null
+++ b/openssl/doc/ssl/SSL_get_peer_cert_chain.pod
@@ -0,0 +1,52 @@
+=pod
+
+=head1 NAME
+
+SSL_get_peer_cert_chain - get the X509 certificate chain of the peer
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ STACKOF(X509) *SSL_get_peer_cert_chain(const SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_get_peer_cert_chain() returns a pointer to STACKOF(X509) certificates
+forming the certificate chain of the peer. If called on the client side,
+the stack also contains the peer's certificate; if called on the server
+side, the peer's certificate must be obtained separately using
+L<SSL_get_peer_certificate(3)|SSL_get_peer_certificate(3)>.
+If the peer did not present a certificate, NULL is returned.
+
+=head1 NOTES
+
+The peer certificate chain is not necessarily available after reusing
+a session, in which case a NULL pointer is returned.
+
+The reference count of the STACKOF(X509) object is not incremented.
+If the corresponding session is freed, the pointer must not be used
+any longer.
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item NULL
+
+No certificate was presented by the peer or no connection was established
+or the certificate chain is no longer available when a session is reused.
+
+=item Pointer to a STACKOF(X509)
+
+The return value points to the certificate chain presented by the peer.
+
+=back
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_get_peer_certificate(3)|SSL_get_peer_certificate(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_get_peer_certificate.pod b/openssl/doc/ssl/SSL_get_peer_certificate.pod
new file mode 100644
index 0000000..ef7c8be
--- /dev/null
+++ b/openssl/doc/ssl/SSL_get_peer_certificate.pod
@@ -0,0 +1,55 @@
+=pod
+
+=head1 NAME
+
+SSL_get_peer_certificate - get the X509 certificate of the peer
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ X509 *SSL_get_peer_certificate(const SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_get_peer_certificate() returns a pointer to the X509 certificate the
+peer presented. If the peer did not present a certificate, NULL is returned.
+
+=head1 NOTES
+
+Due to the protocol definition, a TLS/SSL server will always send a
+certificate, if present. A client will only send a certificate when
+explicitly requested to do so by the server (see
+L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>). If an anonymous cipher
+is used, no certificates are sent.
+
+That a certificate is returned does not indicate information about the
+verification state, use L<SSL_get_verify_result(3)|SSL_get_verify_result(3)>
+to check the verification state.
+
+The reference count of the X509 object is incremented by one, so that it
+will not be destroyed when the session containing the peer certificate is
+freed. The X509 object must be explicitly freed using X509_free().
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item NULL
+
+No certificate was presented by the peer or no connection was established.
+
+=item Pointer to an X509 certificate
+
+The return value points to the certificate presented by the peer.
+
+=back
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_get_verify_result(3)|SSL_get_verify_result(3)>,
+L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_get_psk_identity.pod b/openssl/doc/ssl/SSL_get_psk_identity.pod
new file mode 100644
index 0000000..fe62916
--- /dev/null
+++ b/openssl/doc/ssl/SSL_get_psk_identity.pod
@@ -0,0 +1,63 @@
+=pod
+
+=begin comment
+
+Copyright 2005 Nokia. All rights reserved.
+
+The portions of the attached software ("Contribution") is developed by
+Nokia Corporation and is licensed pursuant to the OpenSSL open source
+license.
+
+The Contribution, originally written by Mika Kousa and Pasi Eronen of
+Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+support (see RFC 4279) to OpenSSL.
+
+No patent licenses or other rights except those expressly stated in
+the OpenSSL open source license shall be deemed granted or received
+expressly, by implication, estoppel, or otherwise.
+
+No assurances are provided by Nokia that the Contribution does not
+infringe the patent or other intellectual property rights of any third
+party or that the license provides you with all the necessary rights
+to make use of the Contribution.
+
+THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+OTHERWISE.
+
+=end comment
+
+=head1 NAME
+
+SSL_get_psk_identity, SSL_get_psk_identity_hint - get PSK client identity and hint
+
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ const char *SSL_get_psk_identity_hint(const SSL *ssl);
+ const char *SSL_get_psk_identity(const SSL *ssl);
+
+
+=head1 DESCRIPTION
+
+SSL_get_psk_identity_hint() is used to retrieve the PSK identity hint
+used during the connection setup related to SSL object
+B<ssl>. Similarly, SSL_get_psk_identity() is used to retrieve the PSK
+identity used during the connection setup.
+
+
+=head1 RETURN VALUES
+
+If non-B<NULL>, SSL_get_psk_identity_hint() returns the PSK identity
+hint and SSL_get_psk_identity() returns the PSK identity. Both are
+B<NULL>-terminated. SSL_get_psk_identity_hint() may return B<NULL> if
+no PSK identity hint was used during the connection setup.
+
+Note that the return value is valid only during the lifetime of the
+SSL object B<ssl>.
+
+=cut
diff --git a/openssl/doc/ssl/SSL_get_rbio.pod b/openssl/doc/ssl/SSL_get_rbio.pod
new file mode 100644
index 0000000..3d98233
--- /dev/null
+++ b/openssl/doc/ssl/SSL_get_rbio.pod
@@ -0,0 +1,40 @@
+=pod
+
+=head1 NAME
+
+SSL_get_rbio - get BIO linked to an SSL object
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ BIO *SSL_get_rbio(SSL *ssl);
+ BIO *SSL_get_wbio(SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_get_rbio() and SSL_get_wbio() return pointers to the BIOs for the
+read or the write channel, which can be different. The reference count
+of the BIO is not incremented.
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item NULL
+
+No BIO was connected to the SSL object
+
+=item Any other pointer
+
+The BIO linked to B<ssl>.
+
+=back
+
+=head1 SEE ALSO
+
+L<SSL_set_bio(3)|SSL_set_bio(3)>, L<ssl(3)|ssl(3)> , L<bio(3)|bio(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_get_session.pod b/openssl/doc/ssl/SSL_get_session.pod
new file mode 100644
index 0000000..0c41caa
--- /dev/null
+++ b/openssl/doc/ssl/SSL_get_session.pod
@@ -0,0 +1,73 @@
+=pod
+
+=head1 NAME
+
+SSL_get_session - retrieve TLS/SSL session data
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ SSL_SESSION *SSL_get_session(const SSL *ssl);
+ SSL_SESSION *SSL_get0_session(const SSL *ssl);
+ SSL_SESSION *SSL_get1_session(SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_get_session() returns a pointer to the B<SSL_SESSION> actually used in
+B<ssl>. The reference count of the B<SSL_SESSION> is not incremented, so
+that the pointer can become invalid by other operations.
+
+SSL_get0_session() is the same as SSL_get_session().
+
+SSL_get1_session() is the same as SSL_get_session(), but the reference
+count of the B<SSL_SESSION> is incremented by one.
+
+=head1 NOTES
+
+The ssl session contains all information required to re-establish the
+connection without a new handshake.
+
+SSL_get0_session() returns a pointer to the actual session. As the
+reference counter is not incremented, the pointer is only valid while
+the connection is in use. If L<SSL_clear(3)|SSL_clear(3)> or
+L<SSL_free(3)|SSL_free(3)> is called, the session may be removed completely
+(if considered bad), and the pointer obtained will become invalid. Even
+if the session is valid, it can be removed at any time due to timeout
+during L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)>.
+
+If the data is to be kept, SSL_get1_session() will increment the reference
+count, so that the session will not be implicitly removed by other operations
+but stays in memory. In order to remove the session
+L<SSL_SESSION_free(3)|SSL_SESSION_free(3)> must be explicitly called once
+to decrement the reference count again.
+
+SSL_SESSION objects keep internal link information about the session cache
+list, when being inserted into one SSL_CTX object's session cache.
+One SSL_SESSION object, regardless of its reference count, must therefore
+only be used with one SSL_CTX object (and the SSL objects created
+from this SSL_CTX object).
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item NULL
+
+There is no session available in B<ssl>.
+
+=item Pointer to an SSL
+
+The return value points to the data of an SSL session.
+
+=back
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_free(3)|SSL_free(3)>,
+L<SSL_clear(3)|SSL_clear(3)>,
+L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_get_verify_result.pod b/openssl/doc/ssl/SSL_get_verify_result.pod
new file mode 100644
index 0000000..55b56a5
--- /dev/null
+++ b/openssl/doc/ssl/SSL_get_verify_result.pod
@@ -0,0 +1,57 @@
+=pod
+
+=head1 NAME
+
+SSL_get_verify_result - get result of peer certificate verification
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ long SSL_get_verify_result(const SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_get_verify_result() returns the result of the verification of the
+X509 certificate presented by the peer, if any.
+
+=head1 NOTES
+
+SSL_get_verify_result() can only return one error code while the verification
+of a certificate can fail because of many reasons at the same time. Only
+the last verification error that occurred during the processing is available
+from SSL_get_verify_result().
+
+The verification result is part of the established session and is restored
+when a session is reused.
+
+=head1 BUGS
+
+If no peer certificate was presented, the returned result code is
+X509_V_OK. This is because no verification error occurred, it does however
+not indicate success. SSL_get_verify_result() is only useful in connection
+with L<SSL_get_peer_certificate(3)|SSL_get_peer_certificate(3)>.
+
+=head1 RETURN VALUES
+
+The following return values can currently occur:
+
+=over 4
+
+=item X509_V_OK
+
+The verification succeeded or no peer certificate was presented.
+
+=item Any other value
+
+Documented in L<verify(1)|verify(1)>.
+
+=back
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_set_verify_result(3)|SSL_set_verify_result(3)>,
+L<SSL_get_peer_certificate(3)|SSL_get_peer_certificate(3)>,
+L<verify(1)|verify(1)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_get_version.pod b/openssl/doc/ssl/SSL_get_version.pod
new file mode 100644
index 0000000..cc271db
--- /dev/null
+++ b/openssl/doc/ssl/SSL_get_version.pod
@@ -0,0 +1,46 @@
+=pod
+
+=head1 NAME
+
+SSL_get_version - get the protocol version of a connection.
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ const char *SSL_get_version(const SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_get_cipher_version() returns the name of the protocol used for the
+connection B<ssl>.
+
+=head1 RETURN VALUES
+
+The following strings can occur:
+
+=over 4
+
+=item SSLv2
+
+The connection uses the SSLv2 protocol.
+
+=item SSLv3
+
+The connection uses the SSLv3 protocol.
+
+=item TLSv1
+
+The connection uses the TLSv1 protocol.
+
+=item unknown
+
+This indicates that no version has been set (no connection established).
+
+=back
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_library_init.pod b/openssl/doc/ssl/SSL_library_init.pod
new file mode 100644
index 0000000..8766776
--- /dev/null
+++ b/openssl/doc/ssl/SSL_library_init.pod
@@ -0,0 +1,57 @@
+=pod
+
+=head1 NAME
+
+SSL_library_init, OpenSSL_add_ssl_algorithms, SSLeay_add_ssl_algorithms
+- initialize SSL library by registering algorithms
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_library_init(void);
+ #define OpenSSL_add_ssl_algorithms()    SSL_library_init()
+ #define SSLeay_add_ssl_algorithms()     SSL_library_init()
+
+=head1 DESCRIPTION
+
+SSL_library_init() registers the available SSL/TLS ciphers and digests.
+
+OpenSSL_add_ssl_algorithms() and SSLeay_add_ssl_algorithms() are synonyms
+for SSL_library_init().
+
+=head1 NOTES
+
+SSL_library_init() must be called before any other action takes place.
+SSL_library_init() is not reentrant. 
+
+=head1 WARNING
+
+SSL_library_init() adds ciphers and digests used directly and indirectly by
+SSL/TLS.
+
+=head1 EXAMPLES
+
+A typical TLS/SSL application will start with the library initialization,
+and provide readable error messages.
+
+ SSL_load_error_strings();                /* readable error messages */
+ SSL_library_init();                      /* initialize library */
+
+=head1 RETURN VALUES
+
+SSL_library_init() always returns "1", so it is safe to discard the return
+value.
+
+=head1 NOTES
+
+OpenSSL 0.9.8o and 1.0.0a and later added SHA2 algorithms to SSL_library_init().
+Applications which need to use SHA2 in earlier versions of OpenSSL should call
+OpenSSL_add_all_algorithms() as well.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_load_error_strings(3)|SSL_load_error_strings(3)>,
+L<RAND_add(3)|RAND_add(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_load_client_CA_file.pod b/openssl/doc/ssl/SSL_load_client_CA_file.pod
new file mode 100644
index 0000000..02527dc
--- /dev/null
+++ b/openssl/doc/ssl/SSL_load_client_CA_file.pod
@@ -0,0 +1,62 @@
+=pod
+
+=head1 NAME
+
+SSL_load_client_CA_file - load certificate names from file
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
+
+=head1 DESCRIPTION
+
+SSL_load_client_CA_file() reads certificates from B<file> and returns
+a STACK_OF(X509_NAME) with the subject names found.
+
+=head1 NOTES
+
+SSL_load_client_CA_file() reads a file of PEM formatted certificates and
+extracts the X509_NAMES of the certificates found. While the name suggests
+the specific usage as support function for
+L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)>,
+it is not limited to CA certificates.
+
+=head1 EXAMPLES
+
+Load names of CAs from file and use it as a client CA list:
+
+ SSL_CTX *ctx;
+ STACK_OF(X509_NAME) *cert_names;
+
+ ... 
+ cert_names = SSL_load_client_CA_file("/path/to/CAfile.pem");
+ if (cert_names != NULL)
+   SSL_CTX_set_client_CA_list(ctx, cert_names);
+ else
+   error_handling();
+ ...
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item NULL
+
+The operation failed, check out the error stack for the reason.
+
+=item Pointer to STACK_OF(X509_NAME)
+
+Pointer to the subject names of the successfully read certificates.
+
+=back
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>,
+L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_new.pod b/openssl/doc/ssl/SSL_new.pod
new file mode 100644
index 0000000..25300e9
--- /dev/null
+++ b/openssl/doc/ssl/SSL_new.pod
@@ -0,0 +1,44 @@
+=pod
+
+=head1 NAME
+
+SSL_new - create a new SSL structure for a connection
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ SSL *SSL_new(SSL_CTX *ctx);
+
+=head1 DESCRIPTION
+
+SSL_new() creates a new B<SSL> structure which is needed to hold the
+data for a TLS/SSL connection. The new structure inherits the settings
+of the underlying context B<ctx>: connection method (SSLv2/v3/TLSv1),
+options, verification settings, timeout settings.
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item NULL
+
+The creation of a new SSL structure failed. Check the error stack to
+find out the reason.
+
+=item Pointer to an SSL structure
+
+The return value points to an allocated SSL structure.
+
+=back
+
+=head1 SEE ALSO
+
+L<SSL_free(3)|SSL_free(3)>, L<SSL_clear(3)|SSL_clear(3)>,
+L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)>,
+L<SSL_get_SSL_CTX(3)|SSL_get_SSL_CTX(3)>,
+L<ssl(3)|ssl(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_pending.pod b/openssl/doc/ssl/SSL_pending.pod
new file mode 100644
index 0000000..43f2874
--- /dev/null
+++ b/openssl/doc/ssl/SSL_pending.pod
@@ -0,0 +1,43 @@
+=pod
+
+=head1 NAME
+
+SSL_pending - obtain number of readable bytes buffered in an SSL object
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_pending(const SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_pending() returns the number of bytes which are available inside
+B<ssl> for immediate read.
+
+=head1 NOTES
+
+Data are received in blocks from the peer. Therefore data can be buffered
+inside B<ssl> and are ready for immediate retrieval with
+L<SSL_read(3)|SSL_read(3)>.
+
+=head1 RETURN VALUES
+
+The number of bytes pending is returned.
+
+=head1 BUGS
+
+SSL_pending() takes into account only bytes from the TLS/SSL record
+that is currently being processed (if any).  If the B<SSL> object's
+I<read_ahead> flag is set, additional protocol bytes may have been
+read containing more TLS/SSL records; these are ignored by
+SSL_pending().
+
+Up to OpenSSL 0.9.6, SSL_pending() does not check if the record type
+of pending data is application data.
+
+=head1 SEE ALSO
+
+L<SSL_read(3)|SSL_read(3)>, L<ssl(3)|ssl(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_read.pod b/openssl/doc/ssl/SSL_read.pod
new file mode 100644
index 0000000..7038cd2
--- /dev/null
+++ b/openssl/doc/ssl/SSL_read.pod
@@ -0,0 +1,124 @@
+=pod
+
+=head1 NAME
+
+SSL_read - read bytes from a TLS/SSL connection.
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_read(SSL *ssl, void *buf, int num);
+
+=head1 DESCRIPTION
+
+SSL_read() tries to read B<num> bytes from the specified B<ssl> into the
+buffer B<buf>.
+
+=head1 NOTES
+
+If necessary, SSL_read() will negotiate a TLS/SSL session, if
+not already explicitly performed by L<SSL_connect(3)|SSL_connect(3)> or
+L<SSL_accept(3)|SSL_accept(3)>. If the
+peer requests a re-negotiation, it will be performed transparently during
+the SSL_read() operation. The behaviour of SSL_read() depends on the
+underlying BIO. 
+
+For the transparent negotiation to succeed, the B<ssl> must have been
+initialized to client or server mode. This is being done by calling
+L<SSL_set_connect_state(3)|SSL_set_connect_state(3)> or SSL_set_accept_state()
+before the first call to an SSL_read() or L<SSL_write(3)|SSL_write(3)>
+function.
+
+SSL_read() works based on the SSL/TLS records. The data are received in
+records (with a maximum record size of 16kB for SSLv3/TLSv1). Only when a
+record has been completely received, it can be processed (decryption and
+check of integrity). Therefore data that was not retrieved at the last
+call of SSL_read() can still be buffered inside the SSL layer and will be
+retrieved on the next call to SSL_read(). If B<num> is higher than the
+number of bytes buffered, SSL_read() will return with the bytes buffered.
+If no more bytes are in the buffer, SSL_read() will trigger the processing
+of the next record. Only when the record has been received and processed
+completely, SSL_read() will return reporting success. At most the contents
+of the record will be returned. As the size of an SSL/TLS record may exceed
+the maximum packet size of the underlying transport (e.g. TCP), it may
+be necessary to read several packets from the transport layer before the
+record is complete and SSL_read() can succeed.
+
+If the underlying BIO is B<blocking>, SSL_read() will only return, once the
+read operation has been finished or an error occurred, except when a
+renegotiation take place, in which case a SSL_ERROR_WANT_READ may occur. 
+This behaviour can be controlled with the SSL_MODE_AUTO_RETRY flag of the
+L<SSL_CTX_set_mode(3)|SSL_CTX_set_mode(3)> call.
+
+If the underlying BIO is B<non-blocking>, SSL_read() will also return
+when the underlying BIO could not satisfy the needs of SSL_read()
+to continue the operation. In this case a call to
+L<SSL_get_error(3)|SSL_get_error(3)> with the
+return value of SSL_read() will yield B<SSL_ERROR_WANT_READ> or
+B<SSL_ERROR_WANT_WRITE>. As at any time a re-negotiation is possible, a
+call to SSL_read() can also cause write operations! The calling process
+then must repeat the call after taking appropriate action to satisfy the
+needs of SSL_read(). The action depends on the underlying BIO. When using a
+non-blocking socket, nothing is to be done, but select() can be used to check
+for the required condition. When using a buffering BIO, like a BIO pair, data
+must be written into or retrieved out of the BIO before being able to continue.
+
+L<SSL_pending(3)|SSL_pending(3)> can be used to find out whether there
+are buffered bytes available for immediate retrieval. In this case
+SSL_read() can be called without blocking or actually receiving new
+data from the underlying socket.
+
+=head1 WARNING
+
+When an SSL_read() operation has to be repeated because of
+B<SSL_ERROR_WANT_READ> or B<SSL_ERROR_WANT_WRITE>, it must be repeated
+with the same arguments.
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item E<gt>0
+
+The read operation was successful; the return value is the number of
+bytes actually read from the TLS/SSL connection.
+
+=item 0
+
+The read operation was not successful. The reason may either be a clean
+shutdown due to a "close notify" alert sent by the peer (in which case
+the SSL_RECEIVED_SHUTDOWN flag in the ssl shutdown state is set
+(see L<SSL_shutdown(3)|SSL_shutdown(3)>,
+L<SSL_set_shutdown(3)|SSL_set_shutdown(3)>). It is also possible, that
+the peer simply shut down the underlying transport and the shutdown is
+incomplete. Call SSL_get_error() with the return value B<ret> to find out,
+whether an error occurred or the connection was shut down cleanly
+(SSL_ERROR_ZERO_RETURN).
+
+SSLv2 (deprecated) does not support a shutdown alert protocol, so it can
+only be detected, whether the underlying connection was closed. It cannot
+be checked, whether the closure was initiated by the peer or by something
+else.
+
+=item E<lt>0
+
+The read operation was not successful, because either an error occurred
+or action must be taken by the calling process. Call SSL_get_error() with the
+return value B<ret> to find out the reason.
+
+=back
+
+=head1 SEE ALSO
+
+L<SSL_get_error(3)|SSL_get_error(3)>, L<SSL_write(3)|SSL_write(3)>,
+L<SSL_CTX_set_mode(3)|SSL_CTX_set_mode(3)>, L<SSL_CTX_new(3)|SSL_CTX_new(3)>,
+L<SSL_connect(3)|SSL_connect(3)>, L<SSL_accept(3)|SSL_accept(3)>
+L<SSL_set_connect_state(3)|SSL_set_connect_state(3)>,
+L<SSL_pending(3)|SSL_pending(3)>,
+L<SSL_shutdown(3)|SSL_shutdown(3)>, L<SSL_set_shutdown(3)|SSL_set_shutdown(3)>,
+L<ssl(3)|ssl(3)>, L<bio(3)|bio(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_rstate_string.pod b/openssl/doc/ssl/SSL_rstate_string.pod
new file mode 100644
index 0000000..bdb8a1f
--- /dev/null
+++ b/openssl/doc/ssl/SSL_rstate_string.pod
@@ -0,0 +1,59 @@
+=pod
+
+=head1 NAME
+
+SSL_rstate_string, SSL_rstate_string_long - get textual description of state of an SSL object during read operation
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ const char *SSL_rstate_string(SSL *ssl);
+ const char *SSL_rstate_string_long(SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_rstate_string() returns a 2 letter string indicating the current read state
+of the SSL object B<ssl>.
+
+SSL_rstate_string_long() returns a string indicating the current read state of
+the SSL object B<ssl>.
+
+=head1 NOTES
+
+When performing a read operation, the SSL/TLS engine must parse the record,
+consisting of header and body. When working in a blocking environment,
+SSL_rstate_string[_long]() should always return "RD"/"read done".
+
+This function should only seldom be needed in applications.
+
+=head1 RETURN VALUES
+
+SSL_rstate_string() and SSL_rstate_string_long() can return the following
+values:
+
+=over 4
+
+=item "RH"/"read header"
+
+The header of the record is being evaluated.
+
+=item "RB"/"read body"
+
+The body of the record is being evaluated.
+
+=item "RD"/"read done"
+
+The record has been completely processed.
+
+=item "unknown"/"unknown"
+
+The read state is unknown. This should never happen.
+
+=back
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_session_reused.pod b/openssl/doc/ssl/SSL_session_reused.pod
new file mode 100644
index 0000000..da7d062
--- /dev/null
+++ b/openssl/doc/ssl/SSL_session_reused.pod
@@ -0,0 +1,45 @@
+=pod
+
+=head1 NAME
+
+SSL_session_reused - query whether a reused session was negotiated during handshake
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_session_reused(SSL *ssl);
+
+=head1 DESCRIPTION
+
+Query, whether a reused session was negotiated during the handshake.
+
+=head1 NOTES
+
+During the negotiation, a client can propose to reuse a session. The server
+then looks up the session in its cache. If both client and server agree
+on the session, it will be reused and a flag is being set that can be
+queried by the application.
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item 0
+
+A new session was negotiated.
+
+=item 1
+
+A session was reused.
+
+=back
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_set_session(3)|SSL_set_session(3)>,
+L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_set_bio.pod b/openssl/doc/ssl/SSL_set_bio.pod
new file mode 100644
index 0000000..67c9756
--- /dev/null
+++ b/openssl/doc/ssl/SSL_set_bio.pod
@@ -0,0 +1,34 @@
+=pod
+
+=head1 NAME
+
+SSL_set_bio - connect the SSL object with a BIO
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio);
+
+=head1 DESCRIPTION
+
+SSL_set_bio() connects the BIOs B<rbio> and B<wbio> for the read and write
+operations of the TLS/SSL (encrypted) side of B<ssl>.
+
+The SSL engine inherits the behaviour of B<rbio> and B<wbio>, respectively.
+If a BIO is non-blocking, the B<ssl> will also have non-blocking behaviour.
+
+If there was already a BIO connected to B<ssl>, BIO_free() will be called
+(for both the reading and writing side, if different).
+
+=head1 RETURN VALUES
+
+SSL_set_bio() cannot fail.
+
+=head1 SEE ALSO
+
+L<SSL_get_rbio(3)|SSL_get_rbio(3)>,
+L<SSL_connect(3)|SSL_connect(3)>, L<SSL_accept(3)|SSL_accept(3)>,
+L<SSL_shutdown(3)|SSL_shutdown(3)>, L<ssl(3)|ssl(3)>, L<bio(3)|bio(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_set_connect_state.pod b/openssl/doc/ssl/SSL_set_connect_state.pod
new file mode 100644
index 0000000..d88a057
--- /dev/null
+++ b/openssl/doc/ssl/SSL_set_connect_state.pod
@@ -0,0 +1,55 @@
+=pod
+
+=head1 NAME
+
+SSL_set_connect_state, SSL_get_accept_state - prepare SSL object to work in client or server mode
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_set_connect_state(SSL *ssl);
+
+ void SSL_set_accept_state(SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_set_connect_state() sets B<ssl> to work in client mode.
+
+SSL_set_accept_state() sets B<ssl> to work in server mode.
+
+=head1 NOTES
+
+When the SSL_CTX object was created with L<SSL_CTX_new(3)|SSL_CTX_new(3)>,
+it was either assigned a dedicated client method, a dedicated server
+method, or a generic method, that can be used for both client and
+server connections. (The method might have been changed with
+L<SSL_CTX_set_ssl_version(3)|SSL_CTX_set_ssl_version(3)> or
+SSL_set_ssl_method().)
+
+When beginning a new handshake, the SSL engine must know whether it must
+call the connect (client) or accept (server) routines. Even though it may
+be clear from the method chosen, whether client or server mode was
+requested, the handshake routines must be explicitly set.
+
+When using the L<SSL_connect(3)|SSL_connect(3)> or
+L<SSL_accept(3)|SSL_accept(3)> routines, the correct handshake
+routines are automatically set. When performing a transparent negotiation
+using L<SSL_write(3)|SSL_write(3)> or L<SSL_read(3)|SSL_read(3)>, the
+handshake routines must be explicitly set in advance using either
+SSL_set_connect_state() or SSL_set_accept_state().
+
+=head1 RETURN VALUES
+
+SSL_set_connect_state() and SSL_set_accept_state() do not return diagnostic
+information.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>, L<SSL_CTX_new(3)|SSL_CTX_new(3)>,
+L<SSL_connect(3)|SSL_connect(3)>, L<SSL_accept(3)|SSL_accept(3)>,
+L<SSL_write(3)|SSL_write(3)>, L<SSL_read(3)|SSL_read(3)>,
+L<SSL_do_handshake(3)|SSL_do_handshake(3)>,
+L<SSL_CTX_set_ssl_version(3)|SSL_CTX_set_ssl_version(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_set_fd.pod b/openssl/doc/ssl/SSL_set_fd.pod
new file mode 100644
index 0000000..7029112
--- /dev/null
+++ b/openssl/doc/ssl/SSL_set_fd.pod
@@ -0,0 +1,54 @@
+=pod
+
+=head1 NAME
+
+SSL_set_fd - connect the SSL object with a file descriptor
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_set_fd(SSL *ssl, int fd);
+ int SSL_set_rfd(SSL *ssl, int fd);
+ int SSL_set_wfd(SSL *ssl, int fd);
+
+=head1 DESCRIPTION
+
+SSL_set_fd() sets the file descriptor B<fd> as the input/output facility
+for the TLS/SSL (encrypted) side of B<ssl>. B<fd> will typically be the
+socket file descriptor of a network connection.
+
+When performing the operation, a B<socket BIO> is automatically created to
+interface between the B<ssl> and B<fd>. The BIO and hence the SSL engine
+inherit the behaviour of B<fd>. If B<fd> is non-blocking, the B<ssl> will
+also have non-blocking behaviour.
+
+If there was already a BIO connected to B<ssl>, BIO_free() will be called
+(for both the reading and writing side, if different).
+
+SSL_set_rfd() and SSL_set_wfd() perform the respective action, but only
+for the read channel or the write channel, which can be set independently.
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item 0
+
+The operation failed. Check the error stack to find out why.
+
+=item 1
+
+The operation succeeded.
+
+=back
+
+=head1 SEE ALSO
+
+L<SSL_get_fd(3)|SSL_get_fd(3)>, L<SSL_set_bio(3)|SSL_set_bio(3)>,
+L<SSL_connect(3)|SSL_connect(3)>, L<SSL_accept(3)|SSL_accept(3)>,
+L<SSL_shutdown(3)|SSL_shutdown(3)>, L<ssl(3)|ssl(3)> , L<bio(3)|bio(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_set_session.pod b/openssl/doc/ssl/SSL_set_session.pod
new file mode 100644
index 0000000..5f54714
--- /dev/null
+++ b/openssl/doc/ssl/SSL_set_session.pod
@@ -0,0 +1,57 @@
+=pod
+
+=head1 NAME
+
+SSL_set_session - set a TLS/SSL session to be used during TLS/SSL connect
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_set_session(SSL *ssl, SSL_SESSION *session);
+
+=head1 DESCRIPTION
+
+SSL_set_session() sets B<session> to be used when the TLS/SSL connection
+is to be established. SSL_set_session() is only useful for TLS/SSL clients.
+When the session is set, the reference count of B<session> is incremented
+by 1. If the session is not reused, the reference count is decremented
+again during SSL_connect(). Whether the session was reused can be queried
+with the L<SSL_session_reused(3)|SSL_session_reused(3)> call.
+
+If there is already a session set inside B<ssl> (because it was set with
+SSL_set_session() before or because the same B<ssl> was already used for
+a connection), SSL_SESSION_free() will be called for that session.
+
+=head1 NOTES
+
+SSL_SESSION objects keep internal link information about the session cache
+list, when being inserted into one SSL_CTX object's session cache.
+One SSL_SESSION object, regardless of its reference count, must therefore
+only be used with one SSL_CTX object (and the SSL objects created
+from this SSL_CTX object).
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item 0
+
+The operation failed; check the error stack to find out the reason.
+
+=item 1
+
+The operation succeeded.
+
+=back
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>,
+L<SSL_get_session(3)|SSL_get_session(3)>,
+L<SSL_session_reused(3)|SSL_session_reused(3)>,
+L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_set_shutdown.pod b/openssl/doc/ssl/SSL_set_shutdown.pod
new file mode 100644
index 0000000..011a022
--- /dev/null
+++ b/openssl/doc/ssl/SSL_set_shutdown.pod
@@ -0,0 +1,72 @@
+=pod
+
+=head1 NAME
+
+SSL_set_shutdown, SSL_get_shutdown - manipulate shutdown state of an SSL connection
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_set_shutdown(SSL *ssl, int mode);
+
+ int SSL_get_shutdown(const SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_set_shutdown() sets the shutdown state of B<ssl> to B<mode>.
+
+SSL_get_shutdown() returns the shutdown mode of B<ssl>.
+
+=head1 NOTES
+
+The shutdown state of an ssl connection is a bitmask of:
+
+=over 4
+
+=item 0
+
+No shutdown setting, yet.
+
+=item SSL_SENT_SHUTDOWN
+
+A "close notify" shutdown alert was sent to the peer, the connection is being
+considered closed and the session is closed and correct.
+
+=item SSL_RECEIVED_SHUTDOWN
+
+A shutdown alert was received form the peer, either a normal "close notify"
+or a fatal error.
+
+=back
+
+SSL_SENT_SHUTDOWN and SSL_RECEIVED_SHUTDOWN can be set at the same time.
+
+The shutdown state of the connection is used to determine the state of
+the ssl session. If the session is still open, when
+L<SSL_clear(3)|SSL_clear(3)> or L<SSL_free(3)|SSL_free(3)> is called,
+it is considered bad and removed according to RFC2246.
+The actual condition for a correctly closed session is SSL_SENT_SHUTDOWN
+(according to the TLS RFC, it is acceptable to only send the "close notify"
+alert but to not wait for the peer's answer, when the underlying connection
+is closed).
+SSL_set_shutdown() can be used to set this state without sending a
+close alert to the peer (see L<SSL_shutdown(3)|SSL_shutdown(3)>).
+
+If a "close notify" was received, SSL_RECEIVED_SHUTDOWN will be set,
+for setting SSL_SENT_SHUTDOWN the application must however still call
+L<SSL_shutdown(3)|SSL_shutdown(3)> or SSL_set_shutdown() itself.
+
+=head1 RETURN VALUES
+
+SSL_set_shutdown() does not return diagnostic information.
+
+SSL_get_shutdown() returns the current setting.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_shutdown(3)|SSL_shutdown(3)>,
+L<SSL_CTX_set_quiet_shutdown(3)|SSL_CTX_set_quiet_shutdown(3)>,
+L<SSL_clear(3)|SSL_clear(3)>, L<SSL_free(3)|SSL_free(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_set_verify_result.pod b/openssl/doc/ssl/SSL_set_verify_result.pod
new file mode 100644
index 0000000..04ab101
--- /dev/null
+++ b/openssl/doc/ssl/SSL_set_verify_result.pod
@@ -0,0 +1,38 @@
+=pod
+
+=head1 NAME
+
+SSL_set_verify_result - override result of peer certificate verification
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_set_verify_result(SSL *ssl, long verify_result);
+
+=head1 DESCRIPTION
+
+SSL_set_verify_result() sets B<verify_result> of the object B<ssl> to be the
+result of the verification of the X509 certificate presented by the peer,
+if any.
+
+=head1 NOTES
+
+SSL_set_verify_result() overrides the verification result. It only changes
+the verification result of the B<ssl> object. It does not become part of the
+established session, so if the session is to be reused later, the original
+value will reappear.
+
+The valid codes for B<verify_result> are documented in L<verify(1)|verify(1)>.
+
+=head1 RETURN VALUES
+
+SSL_set_verify_result() does not provide a return value.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_get_verify_result(3)|SSL_get_verify_result(3)>,
+L<SSL_get_peer_certificate(3)|SSL_get_peer_certificate(3)>,
+L<verify(1)|verify(1)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_shutdown.pod b/openssl/doc/ssl/SSL_shutdown.pod
new file mode 100644
index 0000000..89911ac
--- /dev/null
+++ b/openssl/doc/ssl/SSL_shutdown.pod
@@ -0,0 +1,125 @@
+=pod
+
+=head1 NAME
+
+SSL_shutdown - shut down a TLS/SSL connection
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_shutdown(SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_shutdown() shuts down an active TLS/SSL connection. It sends the 
+"close notify" shutdown alert to the peer.
+
+=head1 NOTES
+
+SSL_shutdown() tries to send the "close notify" shutdown alert to the peer.
+Whether the operation succeeds or not, the SSL_SENT_SHUTDOWN flag is set and
+a currently open session is considered closed and good and will be kept in the
+session cache for further reuse.
+
+The shutdown procedure consists of 2 steps: the sending of the "close notify"
+shutdown alert and the reception of the peer's "close notify" shutdown
+alert. According to the TLS standard, it is acceptable for an application
+to only send its shutdown alert and then close the underlying connection
+without waiting for the peer's response (this way resources can be saved,
+as the process can already terminate or serve another connection).
+When the underlying connection shall be used for more communications, the
+complete shutdown procedure (bidirectional "close notify" alerts) must be
+performed, so that the peers stay synchronized.
+
+SSL_shutdown() supports both uni- and bidirectional shutdown by its 2 step
+behaviour.
+
+=over 4
+
+=item When the application is the first party to send the "close notify"
+alert, SSL_shutdown() will only send the alert and then set the
+SSL_SENT_SHUTDOWN flag (so that the session is considered good and will
+be kept in cache). SSL_shutdown() will then return with 0. If a unidirectional
+shutdown is enough (the underlying connection shall be closed anyway), this
+first call to SSL_shutdown() is sufficient. In order to complete the
+bidirectional shutdown handshake, SSL_shutdown() must be called again.
+The second call will make SSL_shutdown() wait for the peer's "close notify"
+shutdown alert. On success, the second call to SSL_shutdown() will return
+with 1.
+
+=item If the peer already sent the "close notify" alert B<and> it was
+already processed implicitly inside another function
+(L<SSL_read(3)|SSL_read(3)>), the SSL_RECEIVED_SHUTDOWN flag is set.
+SSL_shutdown() will send the "close notify" alert, set the SSL_SENT_SHUTDOWN
+flag and will immediately return with 1.
+Whether SSL_RECEIVED_SHUTDOWN is already set can be checked using the
+SSL_get_shutdown() (see also L<SSL_set_shutdown(3)|SSL_set_shutdown(3)> call.
+
+=back
+
+It is therefore recommended, to check the return value of SSL_shutdown()
+and call SSL_shutdown() again, if the bidirectional shutdown is not yet
+complete (return value of the first call is 0). As the shutdown is not
+specially handled in the SSLv2 protocol, SSL_shutdown() will succeed on
+the first call.
+
+The behaviour of SSL_shutdown() additionally depends on the underlying BIO. 
+
+If the underlying BIO is B<blocking>, SSL_shutdown() will only return once the
+handshake step has been finished or an error occurred.
+
+If the underlying BIO is B<non-blocking>, SSL_shutdown() will also return
+when the underlying BIO could not satisfy the needs of SSL_shutdown()
+to continue the handshake. In this case a call to SSL_get_error() with the
+return value of SSL_shutdown() will yield B<SSL_ERROR_WANT_READ> or
+B<SSL_ERROR_WANT_WRITE>. The calling process then must repeat the call after
+taking appropriate action to satisfy the needs of SSL_shutdown().
+The action depends on the underlying BIO. When using a non-blocking socket,
+nothing is to be done, but select() can be used to check for the required
+condition. When using a buffering BIO, like a BIO pair, data must be written
+into or retrieved out of the BIO before being able to continue.
+
+SSL_shutdown() can be modified to only set the connection to "shutdown"
+state but not actually send the "close notify" alert messages,
+see L<SSL_CTX_set_quiet_shutdown(3)|SSL_CTX_set_quiet_shutdown(3)>.
+When "quiet shutdown" is enabled, SSL_shutdown() will always succeed
+and return 1.
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item 1
+
+The shutdown was successfully completed. The "close notify" alert was sent
+and the peer's "close notify" alert was received.
+
+=item 0
+
+The shutdown is not yet finished. Call SSL_shutdown() for a second time,
+if a bidirectional shutdown shall be performed.
+The output of L<SSL_get_error(3)|SSL_get_error(3)> may be misleading, as an
+erroneous SSL_ERROR_SYSCALL may be flagged even though no error occurred.
+
+=item -1
+
+The shutdown was not successful because a fatal error occurred either
+at the protocol level or a connection failure occurred. It can also occur if
+action is need to continue the operation for non-blocking BIOs.
+Call L<SSL_get_error(3)|SSL_get_error(3)> with the return value B<ret>
+to find out the reason.
+
+=back
+
+=head1 SEE ALSO
+
+L<SSL_get_error(3)|SSL_get_error(3)>, L<SSL_connect(3)|SSL_connect(3)>,
+L<SSL_accept(3)|SSL_accept(3)>, L<SSL_set_shutdown(3)|SSL_set_shutdown(3)>,
+L<SSL_CTX_set_quiet_shutdown(3)|SSL_CTX_set_quiet_shutdown(3)>,
+L<SSL_clear(3)|SSL_clear(3)>, L<SSL_free(3)|SSL_free(3)>,
+L<ssl(3)|ssl(3)>, L<bio(3)|bio(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_state_string.pod b/openssl/doc/ssl/SSL_state_string.pod
new file mode 100644
index 0000000..fe25d47
--- /dev/null
+++ b/openssl/doc/ssl/SSL_state_string.pod
@@ -0,0 +1,45 @@
+=pod
+
+=head1 NAME
+
+SSL_state_string, SSL_state_string_long - get textual description of state of an SSL object
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ const char *SSL_state_string(const SSL *ssl);
+ const char *SSL_state_string_long(const SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_state_string() returns a 6 letter string indicating the current state
+of the SSL object B<ssl>.
+
+SSL_state_string_long() returns a string indicating the current state of
+the SSL object B<ssl>.
+
+=head1 NOTES
+
+During its use, an SSL objects passes several states. The state is internally
+maintained. Querying the state information is not very informative before
+or when a connection has been established. It however can be of significant
+interest during the handshake.
+
+When using non-blocking sockets, the function call performing the handshake
+may return with SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE condition,
+so that SSL_state_string[_long]() may be called.
+
+For both blocking or non-blocking sockets, the details state information
+can be used within the info_callback function set with the
+SSL_set_info_callback() call.
+
+=head1 RETURN VALUES
+
+Detailed description of possible states to be included later.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_CTX_set_info_callback(3)|SSL_CTX_set_info_callback(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_want.pod b/openssl/doc/ssl/SSL_want.pod
new file mode 100644
index 0000000..c0059c0
--- /dev/null
+++ b/openssl/doc/ssl/SSL_want.pod
@@ -0,0 +1,77 @@
+=pod
+
+=head1 NAME
+
+SSL_want, SSL_want_nothing, SSL_want_read, SSL_want_write, SSL_want_x509_lookup - obtain state information TLS/SSL I/O operation
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_want(const SSL *ssl);
+ int SSL_want_nothing(const SSL *ssl);
+ int SSL_want_read(const SSL *ssl);
+ int SSL_want_write(const SSL *ssl);
+ int SSL_want_x509_lookup(const SSL *ssl);
+
+=head1 DESCRIPTION
+
+SSL_want() returns state information for the SSL object B<ssl>.
+
+The other SSL_want_*() calls are shortcuts for the possible states returned
+by SSL_want().
+
+=head1 NOTES
+
+SSL_want() examines the internal state information of the SSL object. Its
+return values are similar to that of L<SSL_get_error(3)|SSL_get_error(3)>.
+Unlike L<SSL_get_error(3)|SSL_get_error(3)>, which also evaluates the
+error queue, the results are obtained by examining an internal state flag
+only. The information must therefore only be used for normal operation under
+non-blocking I/O. Error conditions are not handled and must be treated
+using L<SSL_get_error(3)|SSL_get_error(3)>.
+
+The result returned by SSL_want() should always be consistent with
+the result of L<SSL_get_error(3)|SSL_get_error(3)>.
+
+=head1 RETURN VALUES
+
+The following return values can currently occur for SSL_want():
+
+=over 4
+
+=item SSL_NOTHING
+
+There is no data to be written or to be read.
+
+=item SSL_WRITING
+
+There are data in the SSL buffer that must be written to the underlying
+B<BIO> layer in order to complete the actual SSL_*() operation.
+A call to L<SSL_get_error(3)|SSL_get_error(3)> should return
+SSL_ERROR_WANT_WRITE.
+
+=item SSL_READING
+
+More data must be read from the underlying B<BIO> layer in order to
+complete the actual SSL_*() operation.
+A call to L<SSL_get_error(3)|SSL_get_error(3)> should return
+SSL_ERROR_WANT_READ.
+
+=item SSL_X509_LOOKUP
+
+The operation did not complete because an application callback set by
+SSL_CTX_set_client_cert_cb() has asked to be called again.
+A call to L<SSL_get_error(3)|SSL_get_error(3)> should return
+SSL_ERROR_WANT_X509_LOOKUP.
+
+=back
+
+SSL_want_nothing(), SSL_want_read(), SSL_want_write(), SSL_want_x509_lookup()
+return 1, when the corresponding condition is true or 0 otherwise.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<err(3)|err(3)>, L<SSL_get_error(3)|SSL_get_error(3)>
+
+=cut
diff --git a/openssl/doc/ssl/SSL_write.pod b/openssl/doc/ssl/SSL_write.pod
new file mode 100644
index 0000000..e013c12
--- /dev/null
+++ b/openssl/doc/ssl/SSL_write.pod
@@ -0,0 +1,109 @@
+=pod
+
+=head1 NAME
+
+SSL_write - write bytes to a TLS/SSL connection.
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_write(SSL *ssl, const void *buf, int num);
+
+=head1 DESCRIPTION
+
+SSL_write() writes B<num> bytes from the buffer B<buf> into the specified
+B<ssl> connection.
+
+=head1 NOTES
+
+If necessary, SSL_write() will negotiate a TLS/SSL session, if
+not already explicitly performed by L<SSL_connect(3)|SSL_connect(3)> or
+L<SSL_accept(3)|SSL_accept(3)>. If the
+peer requests a re-negotiation, it will be performed transparently during
+the SSL_write() operation. The behaviour of SSL_write() depends on the
+underlying BIO. 
+
+For the transparent negotiation to succeed, the B<ssl> must have been
+initialized to client or server mode. This is being done by calling
+L<SSL_set_connect_state(3)|SSL_set_connect_state(3)> or SSL_set_accept_state()
+before the first call to an L<SSL_read(3)|SSL_read(3)> or SSL_write() function.
+
+If the underlying BIO is B<blocking>, SSL_write() will only return, once the
+write operation has been finished or an error occurred, except when a
+renegotiation take place, in which case a SSL_ERROR_WANT_READ may occur. 
+This behaviour can be controlled with the SSL_MODE_AUTO_RETRY flag of the
+L<SSL_CTX_set_mode(3)|SSL_CTX_set_mode(3)> call.
+
+If the underlying BIO is B<non-blocking>, SSL_write() will also return,
+when the underlying BIO could not satisfy the needs of SSL_write()
+to continue the operation. In this case a call to
+L<SSL_get_error(3)|SSL_get_error(3)> with the
+return value of SSL_write() will yield B<SSL_ERROR_WANT_READ> or
+B<SSL_ERROR_WANT_WRITE>. As at any time a re-negotiation is possible, a
+call to SSL_write() can also cause read operations! The calling process
+then must repeat the call after taking appropriate action to satisfy the
+needs of SSL_write(). The action depends on the underlying BIO. When using a
+non-blocking socket, nothing is to be done, but select() can be used to check
+for the required condition. When using a buffering BIO, like a BIO pair, data
+must be written into or retrieved out of the BIO before being able to continue.
+
+SSL_write() will only return with success, when the complete contents
+of B<buf> of length B<num> has been written. This default behaviour
+can be changed with the SSL_MODE_ENABLE_PARTIAL_WRITE option of
+L<SSL_CTX_set_mode(3)|SSL_CTX_set_mode(3)>. When this flag is set,
+SSL_write() will also return with success, when a partial write has been
+successfully completed. In this case the SSL_write() operation is considered
+completed. The bytes are sent and a new SSL_write() operation with a new
+buffer (with the already sent bytes removed) must be started.
+A partial write is performed with the size of a message block, which is
+16kB for SSLv3/TLSv1.
+
+=head1 WARNING
+
+When an SSL_write() operation has to be repeated because of
+B<SSL_ERROR_WANT_READ> or B<SSL_ERROR_WANT_WRITE>, it must be repeated
+with the same arguments.
+
+When calling SSL_write() with num=0 bytes to be sent the behaviour is
+undefined.
+
+=head1 RETURN VALUES
+
+The following return values can occur:
+
+=over 4
+
+=item E<gt>0
+
+The write operation was successful, the return value is the number of
+bytes actually written to the TLS/SSL connection.
+
+=item 0
+
+The write operation was not successful. Probably the underlying connection
+was closed. Call SSL_get_error() with the return value B<ret> to find out,
+whether an error occurred or the connection was shut down cleanly
+(SSL_ERROR_ZERO_RETURN).
+
+SSLv2 (deprecated) does not support a shutdown alert protocol, so it can
+only be detected, whether the underlying connection was closed. It cannot
+be checked, why the closure happened.
+
+=item E<lt>0
+
+The write operation was not successful, because either an error occurred
+or action must be taken by the calling process. Call SSL_get_error() with the
+return value B<ret> to find out the reason.
+
+=back
+
+=head1 SEE ALSO
+
+L<SSL_get_error(3)|SSL_get_error(3)>, L<SSL_read(3)|SSL_read(3)>,
+L<SSL_CTX_set_mode(3)|SSL_CTX_set_mode(3)>, L<SSL_CTX_new(3)|SSL_CTX_new(3)>,
+L<SSL_connect(3)|SSL_connect(3)>, L<SSL_accept(3)|SSL_accept(3)>
+L<SSL_set_connect_state(3)|SSL_set_connect_state(3)>,
+L<ssl(3)|ssl(3)>, L<bio(3)|bio(3)>
+
+=cut
diff --git a/openssl/doc/ssl/d2i_SSL_SESSION.pod b/openssl/doc/ssl/d2i_SSL_SESSION.pod
new file mode 100644
index 0000000..81d2764
--- /dev/null
+++ b/openssl/doc/ssl/d2i_SSL_SESSION.pod
@@ -0,0 +1,66 @@
+=pod
+
+=head1 NAME
+
+d2i_SSL_SESSION, i2d_SSL_SESSION - convert SSL_SESSION object from/to ASN1 representation
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length);
+ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp);
+
+=head1 DESCRIPTION
+
+d2i_SSL_SESSION() transforms the external ASN1 representation of an SSL/TLS
+session, stored as binary data at location B<pp> with length B<length>, into
+an SSL_SESSION object.
+
+i2d_SSL_SESSION() transforms the SSL_SESSION object B<in> into the ASN1
+representation and stores it into the memory location pointed to by B<pp>.
+The length of the resulting ASN1 representation is returned. If B<pp> is
+the NULL pointer, only the length is calculated and returned.
+
+=head1 NOTES
+
+The SSL_SESSION object is built from several malloc()ed parts, it can
+therefore not be moved, copied or stored directly. In order to store
+session data on disk or into a database, it must be transformed into
+a binary ASN1 representation.
+
+When using d2i_SSL_SESSION(), the SSL_SESSION object is automatically
+allocated. The reference count is 1, so that the session must be
+explicitly removed using L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>,
+unless the SSL_SESSION object is completely taken over, when being called
+inside the get_session_cb() (see
+L<SSL_CTX_sess_set_get_cb(3)|SSL_CTX_sess_set_get_cb(3)>).
+
+SSL_SESSION objects keep internal link information about the session cache
+list, when being inserted into one SSL_CTX object's session cache.
+One SSL_SESSION object, regardless of its reference count, must therefore
+only be used with one SSL_CTX object (and the SSL objects created
+from this SSL_CTX object).
+
+When using i2d_SSL_SESSION(), the memory location pointed to by B<pp> must be
+large enough to hold the binary representation of the session. There is no
+known limit on the size of the created ASN1 representation, so the necessary
+amount of space should be obtained by first calling i2d_SSL_SESSION() with
+B<pp=NULL>, and obtain the size needed, then allocate the memory and
+call i2d_SSL_SESSION() again.
+
+=head1 RETURN VALUES
+
+d2i_SSL_SESSION() returns a pointer to the newly allocated SSL_SESSION
+object. In case of failure the NULL-pointer is returned and the error message
+can be retrieved from the error stack.
+
+i2d_SSL_SESSION() returns the size of the ASN1 representation in bytes.
+When the session is not valid, B<0> is returned and no operation is performed.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>,
+L<SSL_CTX_sess_set_get_cb(3)|SSL_CTX_sess_set_get_cb(3)>
+
+=cut
diff --git a/openssl/doc/ssl/ssl.pod b/openssl/doc/ssl/ssl.pod
new file mode 100644
index 0000000..6d3ee24
--- /dev/null
+++ b/openssl/doc/ssl/ssl.pod
@@ -0,0 +1,758 @@
+
+=pod
+
+=head1 NAME
+
+SSL - OpenSSL SSL/TLS library
+
+=head1 SYNOPSIS
+
+=head1 DESCRIPTION
+
+The OpenSSL B<ssl> library implements the Secure Sockets Layer (SSL v2/v3) and
+Transport Layer Security (TLS v1) protocols. It provides a rich API which is
+documented here.
+
+At first the library must be initialized; see
+L<SSL_library_init(3)|SSL_library_init(3)>.
+
+Then an B<SSL_CTX> object is created as a framework to establish
+TLS/SSL enabled connections (see L<SSL_CTX_new(3)|SSL_CTX_new(3)>).
+Various options regarding certificates, algorithms etc. can be set
+in this object.
+
+When a network connection has been created, it can be assigned to an
+B<SSL> object. After the B<SSL> object has been created using
+L<SSL_new(3)|SSL_new(3)>, L<SSL_set_fd(3)|SSL_set_fd(3)> or
+L<SSL_set_bio(3)|SSL_set_bio(3)> can be used to associate the network
+connection with the object.
+
+Then the TLS/SSL handshake is performed using
+L<SSL_accept(3)|SSL_accept(3)> or L<SSL_connect(3)|SSL_connect(3)>
+respectively.
+L<SSL_read(3)|SSL_read(3)> and L<SSL_write(3)|SSL_write(3)> are used
+to read and write data on the TLS/SSL connection.
+L<SSL_shutdown(3)|SSL_shutdown(3)> can be used to shut down the
+TLS/SSL connection.
+
+=head1 DATA STRUCTURES
+
+Currently the OpenSSL B<ssl> library functions deals with the following data
+structures:
+
+=over 4
+
+=item B<SSL_METHOD> (SSL Method)
+
+That's a dispatch structure describing the internal B<ssl> library
+methods/functions which implement the various protocol versions (SSLv1, SSLv2
+and TLSv1). It's needed to create an B<SSL_CTX>.
+
+=item B<SSL_CIPHER> (SSL Cipher)
+
+This structure holds the algorithm information for a particular cipher which
+are a core part of the SSL/TLS protocol. The available ciphers are configured
+on a B<SSL_CTX> basis and the actually used ones are then part of the
+B<SSL_SESSION>.
+
+=item B<SSL_CTX> (SSL Context)
+
+That's the global context structure which is created by a server or client
+once per program life-time and which holds mainly default values for the
+B<SSL> structures which are later created for the connections.
+
+=item B<SSL_SESSION> (SSL Session)
+
+This is a structure containing the current TLS/SSL session details for a
+connection: B<SSL_CIPHER>s, client and server certificates, keys, etc.
+
+=item B<SSL> (SSL Connection)
+
+That's the main SSL/TLS structure which is created by a server or client per
+established connection. This actually is the core structure in the SSL API.
+Under run-time the application usually deals with this structure which has
+links to mostly all other structures.
+
+=back
+
+
+=head1 HEADER FILES
+
+Currently the OpenSSL B<ssl> library provides the following C header files
+containing the prototypes for the data structures and and functions:
+
+=over 4
+
+=item B<ssl.h>
+
+That's the common header file for the SSL/TLS API.  Include it into your
+program to make the API of the B<ssl> library available. It internally
+includes both more private SSL headers and headers from the B<crypto> library.
+Whenever you need hard-core details on the internals of the SSL API, look
+inside this header file.
+
+=item B<ssl2.h>
+
+That's the sub header file dealing with the SSLv2 protocol only.
+I<Usually you don't have to include it explicitly because
+it's already included by ssl.h>.
+
+=item B<ssl3.h>
+
+That's the sub header file dealing with the SSLv3 protocol only.
+I<Usually you don't have to include it explicitly because
+it's already included by ssl.h>.
+
+=item B<ssl23.h>
+
+That's the sub header file dealing with the combined use of the SSLv2 and
+SSLv3 protocols.
+I<Usually you don't have to include it explicitly because
+it's already included by ssl.h>.
+
+=item B<tls1.h>
+
+That's the sub header file dealing with the TLSv1 protocol only.
+I<Usually you don't have to include it explicitly because
+it's already included by ssl.h>.
+
+=back
+
+=head1 API FUNCTIONS
+
+Currently the OpenSSL B<ssl> library exports 214 API functions.
+They are documented in the following:
+
+=head2 DEALING WITH PROTOCOL METHODS
+
+Here we document the various API functions which deal with the SSL/TLS
+protocol methods defined in B<SSL_METHOD> structures.
+
+=over 4
+
+=item const SSL_METHOD *B<SSLv2_client_method>(void);
+
+Constructor for the SSLv2 SSL_METHOD structure for a dedicated client.
+
+=item const SSL_METHOD *B<SSLv2_server_method>(void);
+
+Constructor for the SSLv2 SSL_METHOD structure for a dedicated server.
+
+=item const SSL_METHOD *B<SSLv2_method>(void);
+
+Constructor for the SSLv2 SSL_METHOD structure for combined client and server.
+
+=item const SSL_METHOD *B<SSLv3_client_method>(void);
+
+Constructor for the SSLv3 SSL_METHOD structure for a dedicated client.
+
+=item const SSL_METHOD *B<SSLv3_server_method>(void);
+
+Constructor for the SSLv3 SSL_METHOD structure for a dedicated server.
+
+=item const SSL_METHOD *B<SSLv3_method>(void);
+
+Constructor for the SSLv3 SSL_METHOD structure for combined client and server.
+
+=item const SSL_METHOD *B<TLSv1_client_method>(void);
+
+Constructor for the TLSv1 SSL_METHOD structure for a dedicated client.
+
+=item const SSL_METHOD *B<TLSv1_server_method>(void);
+
+Constructor for the TLSv1 SSL_METHOD structure for a dedicated server.
+
+=item const SSL_METHOD *B<TLSv1_method>(void);
+
+Constructor for the TLSv1 SSL_METHOD structure for combined client and server.
+
+=back
+
+=head2 DEALING WITH CIPHERS
+
+Here we document the various API functions which deal with the SSL/TLS
+ciphers defined in B<SSL_CIPHER> structures.
+
+=over 4
+
+=item char *B<SSL_CIPHER_description>(SSL_CIPHER *cipher, char *buf, int len);
+
+Write a string to I<buf> (with a maximum size of I<len>) containing a human
+readable description of I<cipher>. Returns I<buf>.
+
+=item int B<SSL_CIPHER_get_bits>(SSL_CIPHER *cipher, int *alg_bits);
+
+Determine the number of bits in I<cipher>. Because of export crippled ciphers
+there are two bits: The bits the algorithm supports in general (stored to
+I<alg_bits>) and the bits which are actually used (the return value).
+
+=item const char *B<SSL_CIPHER_get_name>(SSL_CIPHER *cipher);
+
+Return the internal name of I<cipher> as a string. These are the various
+strings defined by the I<SSL2_TXT_xxx>, I<SSL3_TXT_xxx> and I<TLS1_TXT_xxx>
+definitions in the header files.
+
+=item char *B<SSL_CIPHER_get_version>(SSL_CIPHER *cipher);
+
+Returns a string like "C<TLSv1/SSLv3>" or "C<SSLv2>" which indicates the
+SSL/TLS protocol version to which I<cipher> belongs (i.e. where it was defined
+in the specification the first time).
+
+=back
+
+=head2 DEALING WITH PROTOCOL CONTEXTS
+
+Here we document the various API functions which deal with the SSL/TLS
+protocol context defined in the B<SSL_CTX> structure.
+
+=over 4
+
+=item int B<SSL_CTX_add_client_CA>(SSL_CTX *ctx, X509 *x);
+
+=item long B<SSL_CTX_add_extra_chain_cert>(SSL_CTX *ctx, X509 *x509);
+
+=item int B<SSL_CTX_add_session>(SSL_CTX *ctx, SSL_SESSION *c);
+
+=item int B<SSL_CTX_check_private_key>(const SSL_CTX *ctx);
+
+=item long B<SSL_CTX_ctrl>(SSL_CTX *ctx, int cmd, long larg, char *parg);
+
+=item void B<SSL_CTX_flush_sessions>(SSL_CTX *s, long t);
+
+=item void B<SSL_CTX_free>(SSL_CTX *a);
+
+=item char *B<SSL_CTX_get_app_data>(SSL_CTX *ctx);
+
+=item X509_STORE *B<SSL_CTX_get_cert_store>(SSL_CTX *ctx);
+
+=item STACK *B<SSL_CTX_get_client_CA_list>(const SSL_CTX *ctx);
+
+=item int (*B<SSL_CTX_get_client_cert_cb>(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+
+=item char *B<SSL_CTX_get_ex_data>(const SSL_CTX *s, int idx);
+
+=item int B<SSL_CTX_get_ex_new_index>(long argl, char *argp, int (*new_func);(void), int (*dup_func)(void), void (*free_func)(void))
+
+=item void (*B<SSL_CTX_get_info_callback>(SSL_CTX *ctx))(SSL *ssl, int cb, int ret);
+
+=item int B<SSL_CTX_get_quiet_shutdown>(const SSL_CTX *ctx);
+
+=item int B<SSL_CTX_get_session_cache_mode>(SSL_CTX *ctx);
+
+=item long B<SSL_CTX_get_timeout>(const SSL_CTX *ctx);
+
+=item int (*B<SSL_CTX_get_verify_callback>(const SSL_CTX *ctx))(int ok, X509_STORE_CTX *ctx);
+
+=item int B<SSL_CTX_get_verify_mode>(SSL_CTX *ctx);
+
+=item int B<SSL_CTX_load_verify_locations>(SSL_CTX *ctx, char *CAfile, char *CApath);
+
+=item long B<SSL_CTX_need_tmp_RSA>(SSL_CTX *ctx);
+
+=item SSL_CTX *B<SSL_CTX_new>(const SSL_METHOD *meth);
+
+=item int B<SSL_CTX_remove_session>(SSL_CTX *ctx, SSL_SESSION *c);
+
+=item int B<SSL_CTX_sess_accept>(SSL_CTX *ctx);
+
+=item int B<SSL_CTX_sess_accept_good>(SSL_CTX *ctx);
+
+=item int B<SSL_CTX_sess_accept_renegotiate>(SSL_CTX *ctx);
+
+=item int B<SSL_CTX_sess_cache_full>(SSL_CTX *ctx);
+
+=item int B<SSL_CTX_sess_cb_hits>(SSL_CTX *ctx);
+
+=item int B<SSL_CTX_sess_connect>(SSL_CTX *ctx);
+
+=item int B<SSL_CTX_sess_connect_good>(SSL_CTX *ctx);
+
+=item int B<SSL_CTX_sess_connect_renegotiate>(SSL_CTX *ctx);
+
+=item int B<SSL_CTX_sess_get_cache_size>(SSL_CTX *ctx);
+
+=item SSL_SESSION *(*B<SSL_CTX_sess_get_get_cb>(SSL_CTX *ctx))(SSL *ssl, unsigned char *data, int len, int *copy);
+
+=item int (*B<SSL_CTX_sess_get_new_cb>(SSL_CTX *ctx)(SSL *ssl, SSL_SESSION *sess);
+
+=item void (*B<SSL_CTX_sess_get_remove_cb>(SSL_CTX *ctx)(SSL_CTX *ctx, SSL_SESSION *sess);
+
+=item int B<SSL_CTX_sess_hits>(SSL_CTX *ctx);
+
+=item int B<SSL_CTX_sess_misses>(SSL_CTX *ctx);
+
+=item int B<SSL_CTX_sess_number>(SSL_CTX *ctx);
+
+=item void B<SSL_CTX_sess_set_cache_size>(SSL_CTX *ctx,t);
+
+=item void B<SSL_CTX_sess_set_get_cb>(SSL_CTX *ctx, SSL_SESSION *(*cb)(SSL *ssl, unsigned char *data, int len, int *copy));
+
+=item void B<SSL_CTX_sess_set_new_cb>(SSL_CTX *ctx, int (*cb)(SSL *ssl, SSL_SESSION *sess));
+
+=item void B<SSL_CTX_sess_set_remove_cb>(SSL_CTX *ctx, void (*cb)(SSL_CTX *ctx, SSL_SESSION *sess));
+
+=item int B<SSL_CTX_sess_timeouts>(SSL_CTX *ctx);
+
+=item LHASH *B<SSL_CTX_sessions>(SSL_CTX *ctx);
+
+=item void B<SSL_CTX_set_app_data>(SSL_CTX *ctx, void *arg);
+
+=item void B<SSL_CTX_set_cert_store>(SSL_CTX *ctx, X509_STORE *cs);
+
+=item void B<SSL_CTX_set_cert_verify_cb>(SSL_CTX *ctx, int (*cb)(), char *arg)
+
+=item int B<SSL_CTX_set_cipher_list>(SSL_CTX *ctx, char *str);
+
+=item void B<SSL_CTX_set_client_CA_list>(SSL_CTX *ctx, STACK *list);
+
+=item void B<SSL_CTX_set_client_cert_cb>(SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
+
+=item void B<SSL_CTX_set_default_passwd_cb>(SSL_CTX *ctx, int (*cb);(void))
+
+=item void B<SSL_CTX_set_default_read_ahead>(SSL_CTX *ctx, int m);
+
+=item int B<SSL_CTX_set_default_verify_paths>(SSL_CTX *ctx);
+
+=item int B<SSL_CTX_set_ex_data>(SSL_CTX *s, int idx, char *arg);
+
+=item void B<SSL_CTX_set_info_callback>(SSL_CTX *ctx, void (*cb)(SSL *ssl, int cb, int ret));
+
+=item void B<SSL_CTX_set_msg_callback>(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
+
+=item void B<SSL_CTX_set_msg_callback_arg>(SSL_CTX *ctx, void *arg);
+
+=item void B<SSL_CTX_set_options>(SSL_CTX *ctx, unsigned long op);
+
+=item void B<SSL_CTX_set_quiet_shutdown>(SSL_CTX *ctx, int mode);
+
+=item void B<SSL_CTX_set_session_cache_mode>(SSL_CTX *ctx, int mode);
+
+=item int B<SSL_CTX_set_ssl_version>(SSL_CTX *ctx, const SSL_METHOD *meth);
+
+=item void B<SSL_CTX_set_timeout>(SSL_CTX *ctx, long t);
+
+=item long B<SSL_CTX_set_tmp_dh>(SSL_CTX* ctx, DH *dh);
+
+=item long B<SSL_CTX_set_tmp_dh_callback>(SSL_CTX *ctx, DH *(*cb)(void));
+
+=item long B<SSL_CTX_set_tmp_rsa>(SSL_CTX *ctx, RSA *rsa);
+
+=item SSL_CTX_set_tmp_rsa_callback
+
+C<long B<SSL_CTX_set_tmp_rsa_callback>(SSL_CTX *B<ctx>, RSA *(*B<cb>)(SSL *B<ssl>, int B<export>, int B<keylength>));>
+
+Sets the callback which will be called when a temporary private key is
+required. The B<C<export>> flag will be set if the reason for needing
+a temp key is that an export ciphersuite is in use, in which case,
+B<C<keylength>> will contain the required keylength in bits. Generate a key of
+appropriate size (using ???) and return it.
+
+=item SSL_set_tmp_rsa_callback
+
+long B<SSL_set_tmp_rsa_callback>(SSL *ssl, RSA *(*cb)(SSL *ssl, int export, int keylength));
+
+The same as B<SSL_CTX_set_tmp_rsa_callback>, except it operates on an SSL
+session instead of a context.
+
+=item void B<SSL_CTX_set_verify>(SSL_CTX *ctx, int mode, int (*cb);(void))
+
+=item int B<SSL_CTX_use_PrivateKey>(SSL_CTX *ctx, EVP_PKEY *pkey);
+
+=item int B<SSL_CTX_use_PrivateKey_ASN1>(int type, SSL_CTX *ctx, unsigned char *d, long len);
+
+=item int B<SSL_CTX_use_PrivateKey_file>(SSL_CTX *ctx, char *file, int type);
+
+=item int B<SSL_CTX_use_RSAPrivateKey>(SSL_CTX *ctx, RSA *rsa);
+
+=item int B<SSL_CTX_use_RSAPrivateKey_ASN1>(SSL_CTX *ctx, unsigned char *d, long len);
+
+=item int B<SSL_CTX_use_RSAPrivateKey_file>(SSL_CTX *ctx, char *file, int type);
+
+=item int B<SSL_CTX_use_certificate>(SSL_CTX *ctx, X509 *x);
+
+=item int B<SSL_CTX_use_certificate_ASN1>(SSL_CTX *ctx, int len, unsigned char *d);
+
+=item int B<SSL_CTX_use_certificate_file>(SSL_CTX *ctx, char *file, int type);
+
+=item void B<SSL_CTX_set_psk_client_callback>(SSL_CTX *ctx, unsigned int (*callback)(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len));
+
+=item int B<SSL_CTX_use_psk_identity_hint>(SSL_CTX *ctx, const char *hint);
+
+=item void B<SSL_CTX_set_psk_server_callback>(SSL_CTX *ctx, unsigned int (*callback)(SSL *ssl, const char *identity, unsigned char *psk, int max_psk_len));
+
+
+
+
+=back
+
+=head2 DEALING WITH SESSIONS
+
+Here we document the various API functions which deal with the SSL/TLS
+sessions defined in the B<SSL_SESSION> structures.
+
+=over 4
+
+=item int B<SSL_SESSION_cmp>(const SSL_SESSION *a, const SSL_SESSION *b);
+
+=item void B<SSL_SESSION_free>(SSL_SESSION *ss);
+
+=item char *B<SSL_SESSION_get_app_data>(SSL_SESSION *s);
+
+=item char *B<SSL_SESSION_get_ex_data>(const SSL_SESSION *s, int idx);
+
+=item int B<SSL_SESSION_get_ex_new_index>(long argl, char *argp, int (*new_func);(void), int (*dup_func)(void), void (*free_func)(void))
+
+=item long B<SSL_SESSION_get_time>(const SSL_SESSION *s);
+
+=item long B<SSL_SESSION_get_timeout>(const SSL_SESSION *s);
+
+=item unsigned long B<SSL_SESSION_hash>(const SSL_SESSION *a);
+
+=item SSL_SESSION *B<SSL_SESSION_new>(void);
+
+=item int B<SSL_SESSION_print>(BIO *bp, const SSL_SESSION *x);
+
+=item int B<SSL_SESSION_print_fp>(FILE *fp, const SSL_SESSION *x);
+
+=item void B<SSL_SESSION_set_app_data>(SSL_SESSION *s, char *a);
+
+=item int B<SSL_SESSION_set_ex_data>(SSL_SESSION *s, int idx, char *arg);
+
+=item long B<SSL_SESSION_set_time>(SSL_SESSION *s, long t);
+
+=item long B<SSL_SESSION_set_timeout>(SSL_SESSION *s, long t);
+
+=back
+
+=head2 DEALING WITH CONNECTIONS
+
+Here we document the various API functions which deal with the SSL/TLS
+connection defined in the B<SSL> structure.
+
+=over 4
+
+=item int B<SSL_accept>(SSL *ssl);
+
+=item int B<SSL_add_dir_cert_subjects_to_stack>(STACK *stack, const char *dir);
+
+=item int B<SSL_add_file_cert_subjects_to_stack>(STACK *stack, const char *file);
+
+=item int B<SSL_add_client_CA>(SSL *ssl, X509 *x);
+
+=item char *B<SSL_alert_desc_string>(int value);
+
+=item char *B<SSL_alert_desc_string_long>(int value);
+
+=item char *B<SSL_alert_type_string>(int value);
+
+=item char *B<SSL_alert_type_string_long>(int value);
+
+=item int B<SSL_check_private_key>(const SSL *ssl);
+
+=item void B<SSL_clear>(SSL *ssl);
+
+=item long B<SSL_clear_num_renegotiations>(SSL *ssl);
+
+=item int B<SSL_connect>(SSL *ssl);
+
+=item void B<SSL_copy_session_id>(SSL *t, const SSL *f);
+
+=item long B<SSL_ctrl>(SSL *ssl, int cmd, long larg, char *parg);
+
+=item int B<SSL_do_handshake>(SSL *ssl);
+
+=item SSL *B<SSL_dup>(SSL *ssl);
+
+=item STACK *B<SSL_dup_CA_list>(STACK *sk);
+
+=item void B<SSL_free>(SSL *ssl);
+
+=item SSL_CTX *B<SSL_get_SSL_CTX>(const SSL *ssl);
+
+=item char *B<SSL_get_app_data>(SSL *ssl);
+
+=item X509 *B<SSL_get_certificate>(const SSL *ssl);
+
+=item const char *B<SSL_get_cipher>(const SSL *ssl);
+
+=item int B<SSL_get_cipher_bits>(const SSL *ssl, int *alg_bits);
+
+=item char *B<SSL_get_cipher_list>(const SSL *ssl, int n);
+
+=item char *B<SSL_get_cipher_name>(const SSL *ssl);
+
+=item char *B<SSL_get_cipher_version>(const SSL *ssl);
+
+=item STACK *B<SSL_get_ciphers>(const SSL *ssl);
+
+=item STACK *B<SSL_get_client_CA_list>(const SSL *ssl);
+
+=item SSL_CIPHER *B<SSL_get_current_cipher>(SSL *ssl);
+
+=item long B<SSL_get_default_timeout>(const SSL *ssl);
+
+=item int B<SSL_get_error>(const SSL *ssl, int i);
+
+=item char *B<SSL_get_ex_data>(const SSL *ssl, int idx);
+
+=item int B<SSL_get_ex_data_X509_STORE_CTX_idx>(void);
+
+=item int B<SSL_get_ex_new_index>(long argl, char *argp, int (*new_func);(void), int (*dup_func)(void), void (*free_func)(void))
+
+=item int B<SSL_get_fd>(const SSL *ssl);
+
+=item void (*B<SSL_get_info_callback>(const SSL *ssl);)()
+
+=item STACK *B<SSL_get_peer_cert_chain>(const SSL *ssl);
+
+=item X509 *B<SSL_get_peer_certificate>(const SSL *ssl);
+
+=item EVP_PKEY *B<SSL_get_privatekey>(SSL *ssl);
+
+=item int B<SSL_get_quiet_shutdown>(const SSL *ssl);
+
+=item BIO *B<SSL_get_rbio>(const SSL *ssl);
+
+=item int B<SSL_get_read_ahead>(const SSL *ssl);
+
+=item SSL_SESSION *B<SSL_get_session>(const SSL *ssl);
+
+=item char *B<SSL_get_shared_ciphers>(const SSL *ssl, char *buf, int len);
+
+=item int B<SSL_get_shutdown>(const SSL *ssl);
+
+=item const SSL_METHOD *B<SSL_get_ssl_method>(SSL *ssl);
+
+=item int B<SSL_get_state>(const SSL *ssl);
+
+=item long B<SSL_get_time>(const SSL *ssl);
+
+=item long B<SSL_get_timeout>(const SSL *ssl);
+
+=item int (*B<SSL_get_verify_callback>(const SSL *ssl))(int,X509_STORE_CTX *)
+
+=item int B<SSL_get_verify_mode>(const SSL *ssl);
+
+=item long B<SSL_get_verify_result>(const SSL *ssl);
+
+=item char *B<SSL_get_version>(const SSL *ssl);
+
+=item BIO *B<SSL_get_wbio>(const SSL *ssl);
+
+=item int B<SSL_in_accept_init>(SSL *ssl);
+
+=item int B<SSL_in_before>(SSL *ssl);
+
+=item int B<SSL_in_connect_init>(SSL *ssl);
+
+=item int B<SSL_in_init>(SSL *ssl);
+
+=item int B<SSL_is_init_finished>(SSL *ssl);
+
+=item STACK *B<SSL_load_client_CA_file>(char *file);
+
+=item void B<SSL_load_error_strings>(void);
+
+=item SSL *B<SSL_new>(SSL_CTX *ctx);
+
+=item long B<SSL_num_renegotiations>(SSL *ssl);
+
+=item int B<SSL_peek>(SSL *ssl, void *buf, int num);
+
+=item int B<SSL_pending>(const SSL *ssl);
+
+=item int B<SSL_read>(SSL *ssl, void *buf, int num);
+
+=item int B<SSL_renegotiate>(SSL *ssl);
+
+=item char *B<SSL_rstate_string>(SSL *ssl);
+
+=item char *B<SSL_rstate_string_long>(SSL *ssl);
+
+=item long B<SSL_session_reused>(SSL *ssl);
+
+=item void B<SSL_set_accept_state>(SSL *ssl);
+
+=item void B<SSL_set_app_data>(SSL *ssl, char *arg);
+
+=item void B<SSL_set_bio>(SSL *ssl, BIO *rbio, BIO *wbio);
+
+=item int B<SSL_set_cipher_list>(SSL *ssl, char *str);
+
+=item void B<SSL_set_client_CA_list>(SSL *ssl, STACK *list);
+
+=item void B<SSL_set_connect_state>(SSL *ssl);
+
+=item int B<SSL_set_ex_data>(SSL *ssl, int idx, char *arg);
+
+=item int B<SSL_set_fd>(SSL *ssl, int fd);
+
+=item void B<SSL_set_info_callback>(SSL *ssl, void (*cb);(void))
+
+=item void B<SSL_set_msg_callback>(SSL *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
+
+=item void B<SSL_set_msg_callback_arg>(SSL *ctx, void *arg);
+
+=item void B<SSL_set_options>(SSL *ssl, unsigned long op);
+
+=item void B<SSL_set_quiet_shutdown>(SSL *ssl, int mode);
+
+=item void B<SSL_set_read_ahead>(SSL *ssl, int yes);
+
+=item int B<SSL_set_rfd>(SSL *ssl, int fd);
+
+=item int B<SSL_set_session>(SSL *ssl, SSL_SESSION *session);
+
+=item void B<SSL_set_shutdown>(SSL *ssl, int mode);
+
+=item int B<SSL_set_ssl_method>(SSL *ssl, const SSL_METHOD *meth);
+
+=item void B<SSL_set_time>(SSL *ssl, long t);
+
+=item void B<SSL_set_timeout>(SSL *ssl, long t);
+
+=item void B<SSL_set_verify>(SSL *ssl, int mode, int (*callback);(void))
+
+=item void B<SSL_set_verify_result>(SSL *ssl, long arg);
+
+=item int B<SSL_set_wfd>(SSL *ssl, int fd);
+
+=item int B<SSL_shutdown>(SSL *ssl);
+
+=item int B<SSL_state>(const SSL *ssl);
+
+=item char *B<SSL_state_string>(const SSL *ssl);
+
+=item char *B<SSL_state_string_long>(const SSL *ssl);
+
+=item long B<SSL_total_renegotiations>(SSL *ssl);
+
+=item int B<SSL_use_PrivateKey>(SSL *ssl, EVP_PKEY *pkey);
+
+=item int B<SSL_use_PrivateKey_ASN1>(int type, SSL *ssl, unsigned char *d, long len);
+
+=item int B<SSL_use_PrivateKey_file>(SSL *ssl, char *file, int type);
+
+=item int B<SSL_use_RSAPrivateKey>(SSL *ssl, RSA *rsa);
+
+=item int B<SSL_use_RSAPrivateKey_ASN1>(SSL *ssl, unsigned char *d, long len);
+
+=item int B<SSL_use_RSAPrivateKey_file>(SSL *ssl, char *file, int type);
+
+=item int B<SSL_use_certificate>(SSL *ssl, X509 *x);
+
+=item int B<SSL_use_certificate_ASN1>(SSL *ssl, int len, unsigned char *d);
+
+=item int B<SSL_use_certificate_file>(SSL *ssl, char *file, int type);
+
+=item int B<SSL_version>(const SSL *ssl);
+
+=item int B<SSL_want>(const SSL *ssl);
+
+=item int B<SSL_want_nothing>(const SSL *ssl);
+
+=item int B<SSL_want_read>(const SSL *ssl);
+
+=item int B<SSL_want_write>(const SSL *ssl);
+
+=item int B<SSL_want_x509_lookup>(const SSL *ssl);
+
+=item int B<SSL_write>(SSL *ssl, const void *buf, int num);
+
+=item void B<SSL_set_psk_client_callback>(SSL *ssl, unsigned int (*callback)(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len));
+
+=item int B<SSL_use_psk_identity_hint>(SSL *ssl, const char *hint);
+
+=item void B<SSL_set_psk_server_callback>(SSL *ssl, unsigned int (*callback)(SSL *ssl, const char *identity, unsigned char *psk, int max_psk_len));
+
+=item const char *B<SSL_get_psk_identity_hint>(SSL *ssl);
+
+=item const char *B<SSL_get_psk_identity>(SSL *ssl);
+
+=back
+
+=head1 SEE ALSO
+
+L<openssl(1)|openssl(1)>, L<crypto(3)|crypto(3)>,
+L<SSL_accept(3)|SSL_accept(3)>, L<SSL_clear(3)|SSL_clear(3)>,
+L<SSL_connect(3)|SSL_connect(3)>,
+L<SSL_CIPHER_get_name(3)|SSL_CIPHER_get_name(3)>,
+L<SSL_COMP_add_compression_method(3)|SSL_COMP_add_compression_method(3)>,
+L<SSL_CTX_add_extra_chain_cert(3)|SSL_CTX_add_extra_chain_cert(3)>,
+L<SSL_CTX_add_session(3)|SSL_CTX_add_session(3)>,
+L<SSL_CTX_ctrl(3)|SSL_CTX_ctrl(3)>,
+L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)>,
+L<SSL_CTX_get_ex_new_index(3)|SSL_CTX_get_ex_new_index(3)>,
+L<SSL_CTX_get_verify_mode(3)|SSL_CTX_get_verify_mode(3)>,
+L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>
+L<SSL_CTX_new(3)|SSL_CTX_new(3)>,
+L<SSL_CTX_sess_number(3)|SSL_CTX_sess_number(3)>,
+L<SSL_CTX_sess_set_cache_size(3)|SSL_CTX_sess_set_cache_size(3)>,
+L<SSL_CTX_sess_set_get_cb(3)|SSL_CTX_sess_set_get_cb(3)>,
+L<SSL_CTX_sessions(3)|SSL_CTX_sessions(3)>,
+L<SSL_CTX_set_cert_store(3)|SSL_CTX_set_cert_store(3)>,
+L<SSL_CTX_set_cert_verify_callback(3)|SSL_CTX_set_cert_verify_callback(3)>,
+L<SSL_CTX_set_cipher_list(3)|SSL_CTX_set_cipher_list(3)>,
+L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)>,
+L<SSL_CTX_set_client_cert_cb(3)|SSL_CTX_set_client_cert_cb(3)>,
+L<SSL_CTX_set_default_passwd_cb(3)|SSL_CTX_set_default_passwd_cb(3)>,
+L<SSL_CTX_set_generate_session_id(3)|SSL_CTX_set_generate_session_id(3)>,
+L<SSL_CTX_set_info_callback(3)|SSL_CTX_set_info_callback(3)>,
+L<SSL_CTX_set_max_cert_list(3)|SSL_CTX_set_max_cert_list(3)>,
+L<SSL_CTX_set_mode(3)|SSL_CTX_set_mode(3)>,
+L<SSL_CTX_set_msg_callback(3)|SSL_CTX_set_msg_callback(3)>,
+L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)>,
+L<SSL_CTX_set_quiet_shutdown(3)|SSL_CTX_set_quiet_shutdown(3)>,
+L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
+L<SSL_CTX_set_session_id_context(3)|SSL_CTX_set_session_id_context(3)>,
+L<SSL_CTX_set_ssl_version(3)|SSL_CTX_set_ssl_version(3)>,
+L<SSL_CTX_set_timeout(3)|SSL_CTX_set_timeout(3)>,
+L<SSL_CTX_set_tmp_rsa_callback(3)|SSL_CTX_set_tmp_rsa_callback(3)>,
+L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>,
+L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>,
+L<SSL_CTX_use_certificate(3)|SSL_CTX_use_certificate(3)>,
+L<SSL_alert_type_string(3)|SSL_alert_type_string(3)>,
+L<SSL_do_handshake(3)|SSL_do_handshake(3)>,
+L<SSL_get_SSL_CTX(3)|SSL_get_SSL_CTX(3)>,
+L<SSL_get_ciphers(3)|SSL_get_ciphers(3)>,
+L<SSL_get_client_CA_list(3)|SSL_get_client_CA_list(3)>,
+L<SSL_get_default_timeout(3)|SSL_get_default_timeout(3)>,
+L<SSL_get_error(3)|SSL_get_error(3)>,
+L<SSL_get_ex_data_X509_STORE_CTX_idx(3)|SSL_get_ex_data_X509_STORE_CTX_idx(3)>,
+L<SSL_get_ex_new_index(3)|SSL_get_ex_new_index(3)>,
+L<SSL_get_fd(3)|SSL_get_fd(3)>,
+L<SSL_get_peer_cert_chain(3)|SSL_get_peer_cert_chain(3)>,
+L<SSL_get_rbio(3)|SSL_get_rbio(3)>,
+L<SSL_get_session(3)|SSL_get_session(3)>,
+L<SSL_get_verify_result(3)|SSL_get_verify_result(3)>,
+L<SSL_get_version(3)|SSL_get_version(3)>,
+L<SSL_library_init(3)|SSL_library_init(3)>,
+L<SSL_load_client_CA_file(3)|SSL_load_client_CA_file(3)>,
+L<SSL_new(3)|SSL_new(3)>,
+L<SSL_pending(3)|SSL_pending(3)>,
+L<SSL_read(3)|SSL_read(3)>,
+L<SSL_rstate_string(3)|SSL_rstate_string(3)>,
+L<SSL_session_reused(3)|SSL_session_reused(3)>,
+L<SSL_set_bio(3)|SSL_set_bio(3)>,
+L<SSL_set_connect_state(3)|SSL_set_connect_state(3)>,
+L<SSL_set_fd(3)|SSL_set_fd(3)>,
+L<SSL_set_session(3)|SSL_set_session(3)>,
+L<SSL_set_shutdown(3)|SSL_set_shutdown(3)>,
+L<SSL_shutdown(3)|SSL_shutdown(3)>,
+L<SSL_state_string(3)|SSL_state_string(3)>,
+L<SSL_want(3)|SSL_want(3)>,
+L<SSL_write(3)|SSL_write(3)>,
+L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>,
+L<SSL_SESSION_get_ex_new_index(3)|SSL_SESSION_get_ex_new_index(3)>,
+L<SSL_SESSION_get_time(3)|SSL_SESSION_get_time(3)>,
+L<d2i_SSL_SESSION(3)|d2i_SSL_SESSION(3)>,
+L<SSL_CTX_set_psk_client_callback(3)|SSL_CTX_set_psk_client_callback(3)>,
+L<SSL_CTX_use_psk_identity_hint(3)|SSL_CTX_use_psk_identity_hint(3)>,
+L<SSL_get_psk_identity(3)|SSL_get_psk_identity(3)>
+
+=head1 HISTORY
+
+The L<ssl(3)|ssl(3)> document appeared in OpenSSL 0.9.2
+
+=cut
+
diff --git a/openssl/doc/ssleay.txt b/openssl/doc/ssleay.txt
new file mode 100644
index 0000000..4d2e714
--- /dev/null
+++ b/openssl/doc/ssleay.txt
@@ -0,0 +1,7030 @@
+
+Bundle of old SSLeay documentation files [OBSOLETE!]
+
+*** WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! ***
+
+OBSOLETE means that nothing in this document should be trusted.  This
+document is provided mostly for historical purposes (it wasn't even up
+to date at the time SSLeay 0.8.1 was released) and as inspiration.  If
+you copy some snippet of code from this document, please _check_ that
+it really is correct from all points of view.  For example, you can
+check with the other documents in this directory tree, or by comparing
+with relevant parts of the include files.
+
+People have done the mistake of trusting what's written here.  Please
+don't do that.
+
+*** WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! ***
+
+
+==== readme ========================================================
+
+This is the old 0.6.6 docuementation.  Most of the cipher stuff is still
+relevent but I'm working (very slowly) on new documentation.
+The current version can be found online at
+
+http://www.cryptsoft.com/ssleay/doc
+
+==== API.doc ========================================================
+
+SSL - SSLv2/v3/v23 etc.
+
+BIO - methods and how they plug together
+
+MEM - memory allocation callback
+
+CRYPTO - locking for threads
+
+EVP - Ciphers/Digests/signatures
+
+RSA - methods
+
+X509 - certificate retrieval
+
+X509 - validation
+
+X509 - X509v3 extensions
+
+Objects - adding object identifiers
+
+ASN.1 - parsing
+
+PEM - parsing
+
+==== ssl/readme =====================================================
+
+22 Jun 1996
+This file belongs in ../apps, but I'll leave it here because it deals
+with SSL :-)  It is rather dated but it gives you an idea of how
+things work.
+===
+
+17 Jul 1995
+I have been changing things quite a bit and have not fully updated
+this file, so take what you read with a grain of salt
+eric
+===
+The s_client and s_server programs can be used to test SSL capable
+IP/port addresses and the verification of the X509 certificates in use
+by these services.  I strongly advise having a look at the code to get
+an idea of how to use the authentication under SSLeay.  Any feedback
+on changes and improvements would be greatly accepted.
+
+This file will probably be gibberish unless you have read
+rfc1421, rfc1422, rfc1423 and rfc1424 which describe PEM
+authentication.
+
+A Brief outline (and examples) how to use them to do so.
+
+NOTE:
+The environment variable SSL_CIPER is used to specify the prefered
+cipher to use, play around with setting it's value to combinations of
+RC4-MD5, EXP-RC4-MD5, CBC-DES-MD5, CBC3-DES-MD5, CFB-DES-NULL
+in a : separated list.
+
+This directory contains 3 X509 certificates which can be used by these programs.
+client.pem: a file containing a certificate and private key to be used
+	by s_client.
+server.pem :a file containing a certificate and private key to be used
+	by s_server.
+eay1024.pem:the certificate used to sign client.pem and server.pem.
+	This would be your CA's certificate.  There is also a link
+	from the file a8556381.0 to eay1024.PEM.  The value a8556381
+	is returned by 'x509 -hash -noout <eay1024.pem' and is the
+	value used by X509 verification routines to 'find' this
+	certificte when search a directory for it.
+	[the above is not true any more, the CA cert is 
+	 ../certs/testca.pem which is signed by ../certs/mincomca.pem]
+
+When testing the s_server, you may get
+bind: Address already in use
+errors.  These indicate the port is still being held by the unix
+kernel and you are going to have to wait for it to let go of it.  If
+this is the case, remember to use the port commands on the s_server and
+s_client to talk on an alternative port.
+
+=====
+s_client.
+This program can be used to connect to any IP/hostname:port that is
+talking SSL.  Once connected, it will attempt to authenticate the
+certificate it was passed and if everything works as expected, a 2
+directional channel will be open.  Any text typed will be sent to the
+other end.  type Q<cr> to exit.  Flags are as follows.
+-host arg	: Arg is the host or IP address to connect to.
+-port arg	: Arg is the port to connect to (https is 443).
+-verify arg	: Turn on authentication of the server certificate.
+		: Arg specifies the 'depth', this will covered below.
+-cert arg	: The optional certificate to use.  This certificate
+		: will be returned to the server if the server
+		: requests it for client authentication.
+-key arg	: The private key that matches the certificate
+		: specified by the -cert option.  If this is not
+		: specified (but -cert is), the -cert file will be
+		: searched for the Private key.  Both files are
+		: assumed to be in PEM format.
+-CApath arg	: When to look for certificates when 'verifying' the
+		: certificate from the server.
+-CAfile arg	: A file containing certificates to be used for
+		: 'verifying' the server certificate.
+-reconnect	: Once a connection has been made, drop it and
+		: reconnect with same session-id.  This is for testing :-).
+
+The '-verify n' parameter specifies not only to verify the servers
+certificate but to also only take notice of 'n' levels.  The best way
+to explain is to show via examples.
+Given
+s_server -cert server.PEM is running.
+
+s_client
+	CONNECTED
+	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
+	issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
+	verify error:num=1:unable to get issuer certificate
+	verify return:1
+	CIPHER is CBC-DES-MD5
+What has happened is that the 'SSLeay demo server' certificate's
+issuer ('CA') could not be found but because verify is not on, we
+don't care and the connection has been made anyway.  It is now 'up'
+using CBC-DES-MD5 mode.  This is an unauthenticate secure channel.
+You may not be talking to the right person but the data going to them
+is encrypted.
+
+s_client -verify 0
+	CONNECTED
+	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
+	issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
+	verify error:num=1:unable to get issuer certificate
+	verify return:1
+	CIPHER is CBC-DES-MD5
+We are 'verifying' but only to depth 0, so since the 'SSLeay demo server'
+certificate passed the date and checksum, we are happy to proceed.
+
+s_client -verify 1
+	CONNECTED
+	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
+	issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
+	verify error:num=1:unable to get issuer certificate
+	verify return:0
+	ERROR
+	verify error:unable to get issuer certificate
+In this case we failed to make the connection because we could not
+authenticate the certificate because we could not find the
+'CA' certificate.
+
+s_client -verify 1 -CAfile eay1024.PEM
+	CONNECTED
+	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
+	verify return:1
+	depth=1 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
+	verify return:1
+	CIPHER is CBC-DES-MD5
+We loaded the certificates from the file eay1024.PEM.  Everything
+checked out and so we made the connection.
+
+s_client -verify 1 -CApath .
+	CONNECTED
+	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
+	verify return:1
+	depth=1 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
+	verify return:1
+	CIPHER is CBC-DES-MD5
+We looked in out local directory for issuer certificates and 'found'
+a8556381.0 and so everything is ok.
+
+It is worth noting that 'CA' is a self certified certificate.  If you
+are passed one of these, it will fail to 'verify' at depth 0 because
+we need to lookup the certifier of a certificate from some information
+that we trust and keep locally.
+
+SSL_CIPHER=CBC3-DES-MD5:RC4-MD5
+export SSL_CIPHER
+s_client -verify 10 -CApath . -reconnect
+	CONNECTED
+	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
+	verify return:1
+	depth=1 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
+	verify return:1
+	drop the connection and reconnect with the same session id
+	CIPHER is CBC3-DES-MD5
+This has done a full connection and then re-estabished it with the
+same session id but a new socket.  No RSA stuff occures on the second
+connection.  Note that we said we would prefer to use CBC3-DES-MD5
+encryption and so, since the server supports it, we are.
+
+=====
+s_server
+This program accepts SSL connections on a specified port
+Once connected, it will estabish an SSL connection and optionaly
+attempt to authenticate the client.  A 2 directional channel will be
+open.  Any text typed will be sent to the other end.  Type Q<cr> to exit.
+Flags are as follows.
+-port arg	: Arg is the port to listen on.
+-verify arg	: Turn on authentication of the client if they have a
+		: certificate.  Arg specifies the 'depth'.
+-Verify arg	: Turn on authentication of the client. If they don't
+		: have a valid certificate, drop the connection.
+-cert arg	: The certificate to use.  This certificate
+		: will be passed to the client.  If it is not
+		: specified, it will default to server.PEM
+-key arg	: The private key that matches the certificate
+		: specified by the -cert option.  If this is not
+		: specified (but -cert is), the -cert file will be
+		: searched for the Private key.  Both files are
+		: assumed to be in PEM format.  Default is server.PEM
+-CApath arg	: When to look for certificates when 'verifying' the
+		: certificate from the client.
+-CAfile arg	: A file containing certificates to be used for
+		: 'verifying' the client certificate.
+
+For the following 'demo'  I will specify the s_server command and
+the s_client command and then list the output from the s_server.
+s_server
+s_client
+	CONNECTED
+	CIPHER is CBC-DES-MD5
+Everything up and running
+
+s_server -verify 0
+s_client  
+	CONNECTED
+	CIPHER is CBC-DES-MD5
+Ok since no certificate was returned and we don't care.
+
+s_server -verify 0
+./s_client -cert client.PEM
+	CONNECTED
+	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo client
+	issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
+	verify error:num=1:unable to get issuer certificate
+	verify return:1
+	CIPHER is CBC-DES-MD5
+Ok since we were only verifying to level 0
+
+s_server -verify 4
+s_client -cert client.PEM
+	CONNECTED
+	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo client
+	issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
+	verify error:num=1:unable to get issuer certificate
+	verify return:0
+	ERROR
+	verify error:unable to get issuer certificate
+Bad because we could not authenticate the returned certificate.
+
+s_server -verify 4 -CApath .
+s_client -cert client.PEM
+	CONNECTED
+	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo client
+	verify return:1
+	depth=1 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
+	verify return:1
+	CIPHER is CBC-DES-MD5
+Ok because we could authenticate the returned certificate :-).
+
+s_server -Verify 0 -CApath .
+s_client
+	CONNECTED
+	ERROR
+	SSL error:function is:REQUEST_CERTIFICATE
+		 :error is   :client end did not return a certificate
+Error because no certificate returned.
+
+s_server -Verify 4 -CApath .
+s_client -cert client.PEM
+	CONNECTED
+	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo client
+	verify return:1
+	depth=1 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
+	verify return:1
+	CIPHER is CBC-DES-MD5
+Full authentication of the client.
+
+So in summary to do full authentication of both ends
+s_server -Verify 9 -CApath .
+s_client -cert client.PEM -CApath . -verify 9
+From the server side
+	CONNECTED
+	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo client
+	verify return:1
+	depth=1 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
+	verify return:1
+	CIPHER is CBC-DES-MD5
+From the client side
+	CONNECTED
+	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
+	verify return:1
+	depth=1 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
+	verify return:1
+	CIPHER is CBC-DES-MD5
+
+For general probing of the 'internet https' servers for the
+distribution area, run
+s_client -host www.netscape.com -port 443 -verify 4 -CApath ../rsa/hash
+Then enter
+GET /
+and you should be talking to the https server on that host.
+
+www.rsa.com was refusing to respond to connections on 443 when I was
+testing.
+
+have fun :-).
+
+eric
+
+==== a_verify.doc ========================================================
+
+From eay@mincom.com Fri Oct  4 18:29:06 1996
+Received: by orb.mincom.oz.au id AA29080
+  (5.65c/IDA-1.4.4 for eay); Fri, 4 Oct 1996 08:29:07 +1000
+Date: Fri, 4 Oct 1996 08:29:06 +1000 (EST)
+From: Eric Young <eay@mincom.oz.au>
+X-Sender: eay@orb
+To: wplatzer <wplatzer@iaik.tu-graz.ac.at>
+Cc: Eric Young <eay@mincom.oz.au>, SSL Mailing List <ssl-users@mincom.com>
+Subject: Re: Netscape's Public Key
+In-Reply-To: <19961003134837.NTM0049@iaik.tu-graz.ac.at>
+Message-Id: <Pine.SOL.3.91.961004081346.8018K-100000@orb>
+Mime-Version: 1.0
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+Status: RO
+X-Status: 
+
+On Thu, 3 Oct 1996, wplatzer wrote:
+> I get Public Key from Netscape (Gold 3.0b4), but cannot do anything
+> with it... It looks like (asn1parse):
+> 
+> 0:d=0 hl=3 l=180 cons: SEQUENCE
+> 3:d=1 hl=2 l= 96 cons: SEQUENCE
+> 5:d=2 hl=2 l= 92 cons: SEQUENCE
+> 7:d=3 hl=2 l= 13 cons: SEQUENCE
+> 9:d=4 hl=2 l= 9 prim: OBJECT :rsaEncryption
+> 20:d=4 hl=2 l= 0 prim: NULL
+> 22:d=3 hl=2 l= 75 prim: BIT STRING
+> 99:d=2 hl=2 l= 0 prim: IA5STRING :
+> 101:d=1 hl=2 l= 13 cons: SEQUENCE
+> 103:d=2 hl=2 l= 9 prim: OBJECT :md5withRSAEncryption
+> 114:d=2 hl=2 l= 0 prim: NULL
+> 116:d=1 hl=2 l= 65 prim: BIT STRING
+> 
+> The first BIT STRING is the public key and the second BIT STRING is 
+> the signature.
+> But a public key consists of the public exponent and the modulus. Are 
+> both numbers in the first BIT STRING?
+> Is there a document simply describing this coding stuff (checking 
+> signature, get the public key, etc.)?
+
+Minimal in SSLeay.  If you want to see what the modulus and exponent are,
+try asn1parse -offset 25 -length 75 <key.pem
+asn1parse will currently stuff up on the 'length 75' part (fixed in next 
+release) but it will print the stuff.  If you are after more 
+documentation on ASN.1, have a look at www.rsa.com and get their PKCS 
+documents, most of my initial work on SSLeay was done using them.
+
+As for SSLeay,
+util/crypto.num and util/ssl.num are lists of all exported functions in 
+the library (but not macros :-(.
+
+The ones for extracting public keys from certificates and certificate 
+requests are EVP_PKEY *      X509_REQ_extract_key(X509_REQ *req);
+EVP_PKEY *      X509_extract_key(X509 *x509);
+
+To verify a signature on a signed ASN.1 object
+int X509_verify(X509 *a,EVP_PKEY *key);
+int X509_REQ_verify(X509_REQ *a,EVP_PKEY *key);
+int X509_CRL_verify(X509_CRL *a,EVP_PKEY *key);
+int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a,EVP_PKEY *key);
+
+I should mention that EVP_PKEY can be used to hold a public or a private key,
+since for  things like RSA and DSS, a public key is just a subset of what 
+is stored for the private key.
+
+To sign any of the above structures
+
+int X509_sign(X509 *a,EVP_PKEY *key,EVP_MD *md);
+int X509_REQ_sign(X509_REQ *a,EVP_PKEY *key,EVP_MD *md);
+int X509_CRL_sign(X509_CRL *a,EVP_PKEY *key,EVP_MD *md);
+int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *a,EVP_PKEY *key,EVP_MD *md);
+
+where md is the message digest to sign with.
+
+There are all defined in x509.h and all the _sign and _verify functions are
+actually macros to the ASN1_sign() and ASN1_verify() functions.
+These functions will put the correct algorithm identifiers in the correct 
+places in the structures.
+
+eric
+--
+Eric Young                  | BOOL is tri-state according to Bill Gates.
+AARNet: eay@mincom.oz.au    | RTFM Win32 GetMessage().
+
+==== x509 =======================================================
+
+X509_verify()
+X509_sign()
+
+X509_get_version()
+X509_get_serialNumber()
+X509_get_issuer()
+X509_get_subject()
+X509_get_notBefore()
+X509_get_notAfter()
+X509_get_pubkey()
+
+X509_set_version()
+X509_set_serialNumber()
+X509_set_issuer()
+X509_set_subject()
+X509_set_notBefore()
+X509_set_notAfter()
+X509_set_pubkey()
+
+X509_get_extensions()
+X509_set_extensions()
+
+X509_EXTENSIONS_clear()
+X509_EXTENSIONS_retrieve()
+X509_EXTENSIONS_add()
+X509_EXTENSIONS_delete()
+
+==== x509 attribute ================================================
+
+PKCS7
+	STACK of X509_ATTRIBUTES
+		ASN1_OBJECT
+		STACK of ASN1_TYPE
+
+So it is
+
+p7.xa[].obj
+p7.xa[].data[]
+
+get_obj_by_nid(STACK , nid)
+get_num_by_nid(STACK , nid)
+get_data_by_nid(STACK , nid, index)
+
+X509_ATTRIBUTE *X509_ATTRIBUTE_new(void );
+void		X509_ATTRIBUTE_free(X509_ATTRIBUTE *a);
+
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **ex,
+			int nid, STACK *value);
+
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **ex,
+			int nid, STACK *value);
+
+int		X509_ATTRIBUTE_set_object(X509_ATTRIBUTE *ex,ASN1_OBJECT *obj);
+int		X509_ATTRIBUTE_add_data(X509_ATTRIBUTE *ex, int index,
+			ASN1_TYPE *value);
+
+ASN1_OBJECT *	X509_ATTRIBUTE_get_object(X509_ATTRIBUTE *ex);
+int 		X509_ATTRIBUTE_get_num(X509_ATTRIBUTE *ne);
+ASN1_TYPE *	X509_ATTRIBUTE_get_data(X509_ATTRIBUTE *ne,int index);
+
+ASN1_TYPE *	X509_ATTRIBUTE_get_data_by_NID(X509_ATTRIBUTE *ne,
+			ASN1_OBJECT *obj);
+
+X509_ATTRIBUTE *PKCS7_get_s_att_by_NID(PKCS7 *p7,int nid);
+X509_ATTRIBUTE *PKCS7_get_u_att_by_NID(PKCS7 *p7,int nid);
+
+==== x509 v3 ========================================================
+
+The 'new' system.
+
+The X509_EXTENSION_METHOD includes extensions and attributes and/or names. 
+Basically everthing that can be added to an X509 with an OID identifying it.
+
+It operates via 2 methods per object id.
+int a2i_XXX(X509 *x,char *str,int len);
+int i2a_XXX(BIO *bp,X509 *x);
+
+The a2i_XXX function will add the object with a value converted from the
+string into the X509.  Len can be -1 in which case the length is calculated
+via strlen(str).   Applications can always use direct knowledge to load and
+unload the relevent objects themselves.
+
+i2a_XXX will print to the passed BIO, a text representation of the
+relevet object.  Use a memory BIO if you want it printed to a buffer :-).
+
+X509_add_by_NID(X509 *x,int nid,char *str,int len);
+X509_add_by_OBJ(X509 *x,ASN1_OBJECT *obj,char *str,int len);
+
+X509_print_by_name(BIO *bp,X509 *x);
+X509_print_by_NID(BIO *bp,X509 *x);
+X509_print_by_OBJ(BIO *bp,X509 *x);
+
+==== verify ========================================================
+
+X509_verify_cert_chain(
+	CERT_STORE *cert_store,
+	STACK /* X509 */ *certs,
+	int *verify_result,
+	int (*verify_error_callback)()
+	char *argument_to_callback, /* SSL */
+
+app_verify_callback(
+	char *app_verify_arg, /* from SSL_CTX */
+	STACK /* X509 */ *certs,
+	int *verify_result,
+	int (*verify_error_callback)()
+	SSL *s,
+
+int X509_verify_cert(
+	CERT_STORE *cert_store,
+	X509 *x509,
+	int *verify_result,
+	int (*verify_error_callback)(),
+	char *arg,
+
+==== apps.doc ========================================================
+
+The applications
+
+Ok, where to begin....
+In the begining, when SSLeay was small (April 1995), there
+were but few applications, they did happily cohabit in
+the one bin directory.  Then over time, they did multiply and grow,
+and they started to look like microsoft software; 500k to print 'hello world'.
+A new approach was needed.  They were coalessed into one 'Monolithic'
+application, ssleay.  This one program is composed of many programs that
+can all be compiled independantly.
+
+ssleay has 3 modes of operation.
+1) If the ssleay binary has the name of one of its component programs, it
+executes that program and then exits.  This can be achieved by using hard or
+symbolic links, or failing that, just renaming the binary.
+2) If the first argument to ssleay is the name of one of the component
+programs, that program runs that program and then exits.
+3) If there are no arguments, ssleay enters a 'command' mode.  Each line is
+interpreted as a program name plus arguments.  After each 'program' is run,
+ssleay returns to the comand line.
+
+dgst	- message digests
+enc	- encryption and base64 encoding
+
+ans1parse - 'pulls' appart ASN.1 encoded objects like certificates.
+
+dh	- Diffle-Hellman parameter manipulation.
+rsa	- RSA manipulations.
+crl	- Certificate revokion list manipulations
+x509	- X509 cert fiddles, including signing.
+pkcs7	- pkcs7 manipulation, only DER versions right now.
+
+genrsa	- generate an RSA private key.
+gendh	- Generate a set of Diffle-Hellman parameters.
+req	- Generate a PKCS#10 object, a certificate request.
+
+s_client - SSL client program
+s_server - SSL server program
+s_time	 - A SSL protocol timing program
+s_mult	 - Another SSL server, but it multiplexes
+	   connections.
+s_filter - under development
+
+errstr	- Convert SSLeay error numbers to strings.
+ca	- Sign certificate requests, and generate
+	  certificate revokion lists
+crl2pkcs7 - put a crl and certifcates into a pkcs7 object.
+speed	- Benchmark the ciphers.
+verify	- Check certificates
+hashdir - under development
+
+[ there a now a few more options, play with the program to see what they
+  are ]
+
+==== asn1.doc ========================================================
+
+The ASN.1 Routines.
+
+ASN.1 is a specification for how to encode structured 'data' in binary form.
+The approach I have take to the manipulation of structures and their encoding
+into ASN.1 is as follows.
+
+For each distinct structure there are 4 function of the following form
+TYPE *TYPE_new(void);
+void TYPE_free(TYPE *);
+TYPE *d2i_TYPE(TYPE **a,unsigned char **pp,long length);
+long i2d_TYPE(TYPE *a,unsigned char **pp); 	/* CHECK RETURN VALUE */
+
+where TYPE is the type of the 'object'.  The TYPE that have these functions
+can be in one of 2 forms, either the internal C malloc()ed data structure
+or in the DER (a variant of ASN.1 encoding) binary encoding which is just
+an array of unsigned bytes.  The 'i2d' functions converts from the internal
+form to the DER form and the 'd2i' functions convert from the DER form to
+the internal form.
+
+The 'new' function returns a malloc()ed version of the structure with all
+substructures either created or left as NULL pointers.  For 'optional'
+fields, they are normally left as NULL to indicate no value.  For variable
+size sub structures (often 'SET OF' or 'SEQUENCE OF' in ASN.1 syntax) the
+STACK data type is used to hold the values.  Have a read of stack.doc
+and have a look at the relevant header files to see what I mean.  If there
+is an error while malloc()ing the structure, NULL is returned.
+
+The 'free' function will free() all the sub components of a particular
+structure.  If any of those sub components have been 'removed', replace
+them with NULL pointers, the 'free' functions are tolerant of NULL fields.
+
+The 'd2i' function copies a binary representation into a C structure.  It
+operates as follows.  'a' is a pointer to a pointer to
+the structure to populate, 'pp' is a pointer to a pointer to where the DER
+byte string is located and 'length' is the length of the '*pp' data.
+If there are no errors, a pointer to the populated structure is returned.
+If there is an error, NULL is returned.  Errors can occur because of
+malloc() failures but normally they will be due to syntax errors in the DER
+encoded data being parsed. It is also an error if there was an
+attempt to read more that 'length' bytes from '*p'.  If
+everything works correctly, the value in '*p' is updated
+to point at the location just beyond where the DER
+structure was read from.  In this way, chained calls to 'd2i' type
+functions can be made, with the pointer into the 'data' array being
+'walked' along the input byte array.
+Depending on the value passed for 'a', different things will be done.  If
+'a' is NULL, a new structure will be malloc()ed and returned.  If '*a' is
+NULL, a new structure will be malloc()ed and put into '*a' and returned.
+If '*a' is not NULL, the structure in '*a' will be populated, or in the
+case of an error, free()ed and then returned.
+Having these semantics means that a structure
+can call a 'd2i' function to populate a field and if the field is currently
+NULL, the structure will be created.
+
+The 'i2d' function type is used to copy a C structure to a byte array.
+The parameter 'a' is the structure to convert and '*p' is where to put it.
+As for the 'd2i' type structure, 'p' is updated to point after the last
+byte written.  If p is NULL, no data is written.  The function also returns
+the number of bytes written.  Where this becomes useful is that if the
+function is called with a NULL 'p' value, the length is returned.  This can
+then be used to malloc() an array of bytes and then the same function can
+be recalled passing the malloced array to be written to. e.g.
+
+int len;
+unsigned char *bytes,*p;
+len=i2d_X509(x,NULL);	/* get the size of the ASN1 encoding of 'x' */
+if ((bytes=(unsigned char *)malloc(len)) == NULL)
+	goto err;
+p=bytes;
+i2d_X509(x,&p);
+
+Please note that a new variable, 'p' was passed to i2d_X509.  After the
+call to i2d_X509 p has been incremented by len bytes.
+
+Now the reason for this functional organisation is that it allows nested
+structures to be built up by calling these functions as required.  There
+are various macros used to help write the general 'i2d', 'd2i', 'new' and
+'free' functions.  They are discussed in another file and would only be
+used by some-one wanting to add new structures to the library.  As you
+might be able to guess, the process of writing ASN.1 files can be a bit CPU
+expensive for complex structures.  I'm willing to live with this since the
+simpler library code make my life easier and hopefully most programs using
+these routines will have their execution profiles dominated by cipher or
+message digest routines.
+What follows is a list of 'TYPE' values and the corresponding ASN.1
+structure and where it is used.
+
+TYPE			ASN.1
+ASN1_INTEGER		INTEGER
+ASN1_BIT_STRING		BIT STRING
+ASN1_OCTET_STRING	OCTET STRING
+ASN1_OBJECT		OBJECT IDENTIFIER
+ASN1_PRINTABLESTRING	PrintableString
+ASN1_T61STRING		T61String
+ASN1_IA5STRING		IA5String
+ASN1_UTCTIME		UTCTime
+ASN1_TYPE		Any of the above mentioned types plus SEQUENCE and SET
+
+Most of the above mentioned types are actualled stored in the
+ASN1_BIT_STRING type and macros are used to differentiate between them.
+The 3 types used are
+
+typedef struct asn1_object_st
+	{
+	/* both null if a dynamic ASN1_OBJECT, one is
+	 * defined if a 'static' ASN1_OBJECT */
+	char *sn,*ln;
+	int nid;
+	int length;
+	unsigned char *data;
+	} ASN1_OBJECT;
+This is used to store ASN1 OBJECTS.  Read 'objects.doc' for details ono
+routines to manipulate this structure.  'sn' and 'ln' are used to hold text
+strings that represent the object (short name and long or lower case name).
+These are used by the 'OBJ' library.  'nid' is a number used by the OBJ
+library to uniquely identify objects.  The ASN1 routines will populate the
+'length' and 'data' fields which will contain the bit string representing
+the object.
+
+typedef struct asn1_bit_string_st
+	{
+	int length;
+	int type;
+	unsigned char *data;
+	} ASN1_BIT_STRING;
+This structure is used to hold all the other base ASN1 types except for
+ASN1_UTCTIME (which is really just a 'char *').  Length is the number of
+bytes held in data and type is the ASN1 type of the object (there is a list
+in asn1.h).
+
+typedef struct asn1_type_st
+	{
+	int type;
+	union	{
+		char *ptr;
+		ASN1_INTEGER *		integer;
+		ASN1_BIT_STRING *	bit_string;
+		ASN1_OCTET_STRING *	octet_string;
+		ASN1_OBJECT *		object;
+		ASN1_PRINTABLESTRING *	printablestring;
+		ASN1_T61STRING *	t61string;
+		ASN1_IA5STRING *	ia5string;
+		ASN1_UTCTIME *		utctime;
+		ASN1_BIT_STRING *	set;
+		ASN1_BIT_STRING *	sequence;
+		} value;
+	} ASN1_TYPE;
+This structure is used in a few places when 'any' type of object can be
+expected.
+
+X509			Certificate
+X509_CINF		CertificateInfo
+X509_ALGOR		AlgorithmIdentifier
+X509_NAME		Name			
+X509_NAME_ENTRY		A single sub component of the name.
+X509_VAL		Validity
+X509_PUBKEY		SubjectPublicKeyInfo
+The above mentioned types are declared in x509.h. They are all quite
+straight forward except for the X509_NAME/X509_NAME_ENTRY pair.
+A X509_NAME is a STACK (see stack.doc) of X509_NAME_ENTRY's.
+typedef struct X509_name_entry_st
+	{
+	ASN1_OBJECT *object;
+	ASN1_BIT_STRING *value;
+	int set;
+	int size; 	/* temp variable */
+	} X509_NAME_ENTRY;
+The size is a temporary variable used by i2d_NAME and set is the set number
+for the particular NAME_ENTRY.  A X509_NAME is encoded as a sequence of
+sequence of sets.  Normally each set contains only a single item.
+Sometimes it contains more.  Normally throughout this library there will be
+only one item per set.  The set field contains the 'set' that this entry is
+a member of.  So if you have just created a X509_NAME structure and
+populated it with X509_NAME_ENTRYs, you should then traverse the X509_NAME
+(which is just a STACK) and set the 'set/' field to incrementing numbers.
+For more details on why this is done, read the ASN.1 spec for Distinguished
+Names.
+
+X509_REQ		CertificateRequest
+X509_REQ_INFO		CertificateRequestInfo
+These are used to hold certificate requests.
+
+X509_CRL		CertificateRevocationList
+These are used to hold a certificate revocation list
+
+RSAPrivateKey		PrivateKeyInfo
+RSAPublicKey		PublicKeyInfo
+Both these 'function groups' operate on 'RSA' structures (see rsa.doc).
+The difference is that the RSAPublicKey operations only manipulate the m
+and e fields in the RSA structure.
+
+DSAPrivateKey		DSS private key
+DSAPublicKey		DSS public key
+Both these 'function groups' operate on 'DSS' structures (see dsa.doc).
+The difference is that the RSAPublicKey operations only manipulate the 
+XXX fields in the DSA structure.
+
+DHparams		DHParameter
+This is used to hold the p and g value for The Diffie-Hellman operation.
+The function deal with the 'DH' strucure (see dh.doc).
+
+Now all of these function types can be used with several other functions to give
+quite useful set of general manipulation routines.  Normally one would
+not uses these functions directly but use them via macros. 
+
+char *ASN1_dup(int (*i2d)(),char *(*d2i)(),char *x);
+'x' is the input structure case to a 'char *', 'i2d' is the 'i2d_TYPE'
+function for the type that 'x' is and d2i is the 'd2i_TYPE' function for the
+type that 'x' is.  As is obvious from the parameters, this function
+duplicates the strucutre by transforming it into the DER form and then
+re-loading it into a new strucutre and returning the new strucutre.  This
+is obviously a bit cpu intensive but when faced with a complex dynamic
+structure this is the simplest programming approach.  There are macros for
+duplicating the major data types but is simple to add extras.
+
+char *ASN1_d2i_fp(char *(*new)(),char *(*d2i)(),FILE *fp,unsigned char **x);
+'x' is a pointer to a pointer of the 'desired type'.  new and d2i are the
+corresponding 'TYPE_new' and 'd2i_TYPE' functions for the type and 'fp' is
+an open file pointer to read from.  This function reads from 'fp' as much
+data as it can and then uses 'd2i' to parse the bytes to load and return
+the parsed strucutre in 'x' (if it was non-NULL) and to actually return the
+strucutre.  The behavior of 'x' is as per all the other d2i functions.
+
+char *ASN1_d2i_bio(char *(*new)(),char *(*d2i)(),BIO *fp,unsigned char **x);
+The 'BIO' is the new IO type being used in SSLeay (see bio.doc).  This
+function is the same as ASN1_d2i_fp() except for the BIO argument.
+ASN1_d2i_fp() actually calls this function.
+
+int ASN1_i2d_fp(int (*i2d)(),FILE *out,unsigned char *x);
+'x' is converted to bytes by 'i2d' and then written to 'out'.  ASN1_i2d_fp
+and ASN1_d2i_fp are not really symetric since ASN1_i2d_fp will read all
+available data from the file pointer before parsing a single item while
+ASN1_i2d_fp can be used to write a sequence of data objects.  To read a
+series of objects from a file I would sugest loading the file into a buffer
+and calling the relevent 'd2i' functions.
+
+char *ASN1_d2i_bio(char *(*new)(),char *(*d2i)(),BIO *fp,unsigned char **x);
+This function is the same as ASN1_i2d_fp() except for the BIO argument.
+ASN1_i2d_fp() actually calls this function.
+
+char *	PEM_ASN1_read(char *(*d2i)(),char *name,FILE *fp,char **x,int (*cb)());
+This function will read the next PEM encoded (base64) object of the same
+type as 'x' (loaded by the d2i function).  'name' is the name that is in
+the '-----BEGIN name-----' that designates the start of that object type.
+If the data is encrypted, 'cb' will be called to prompt for a password.  If
+it is NULL a default function will be used to prompt from the password.
+'x' is delt with as per the standard 'd2i' function interface.  This
+function can be used to read a series of objects from a file.  While any
+data type can be encrypted (see PEM_ASN1_write) only RSA private keys tend
+to be encrypted.
+
+char *	PEM_ASN1_read_bio(char *(*d2i)(),char *name,BIO *fp,
+	char **x,int (*cb)());
+Same as PEM_ASN1_read() except using a BIO.  This is called by
+PEM_ASN1_read().
+
+int	PEM_ASN1_write(int (*i2d)(),char *name,FILE *fp,char *x,EVP_CIPHER *enc,
+		unsigned char *kstr,int klen,int (*callback)());
+
+int	PEM_ASN1_write_bio(int (*i2d)(),char *name,BIO *fp,
+		char *x,EVP_CIPHER *enc,unsigned char *kstr,int klen,
+		int (*callback)());
+
+int ASN1_sign(int (*i2d)(), X509_ALGOR *algor1, X509_ALGOR *algor2,
+	ASN1_BIT_STRING *signature, char *data, RSA *rsa, EVP_MD *type);
+int ASN1_verify(int (*i2d)(), X509_ALGOR *algor1,
+	ASN1_BIT_STRING *signature,char *data, RSA *rsa);
+
+int ASN1_BIT_STRING_cmp(ASN1_BIT_STRING *a, ASN1_BIT_STRING *b);
+ASN1_BIT_STRING *ASN1_BIT_STRING_type_new(int type );
+
+int ASN1_UTCTIME_check(ASN1_UTCTIME *a);
+void ASN1_UTCTIME_print(BIO *fp,ASN1_UTCTIME *a);
+ASN1_UTCTIME *ASN1_UTCTIME_dup(ASN1_UTCTIME *a);
+
+ASN1_BIT_STRING *d2i_asn1_print_type(ASN1_BIT_STRING **a,unsigned char **pp,
+		long length,int type);
+
+int		i2d_ASN1_SET(STACK *a, unsigned char **pp,
+			int (*func)(), int ex_tag, int ex_class);
+STACK *		d2i_ASN1_SET(STACK **a, unsigned char **pp, long length,
+			char *(*func)(), int ex_tag, int ex_class);
+
+int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *object);
+int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
+int a2i_ASN1_INTEGER(BIO *bp,ASN1_INTEGER *bs,char *buf,int size);
+
+int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
+long ASN1_INTEGER_get(ASN1_INTEGER *a);
+ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai);
+BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai,BIGNUM *bn);
+
+/* given a string, return the correct type.  Max is the maximum number
+ * of bytes to parse.  It stops parsing when 'max' bytes have been
+ * processed or a '\0' is hit */
+int ASN1_PRINTABLE_type(unsigned char *s,int max);
+
+void ASN1_parse(BIO *fp,unsigned char *pp,long len);
+
+int i2d_ASN1_bytes(ASN1_BIT_STRING *a, unsigned char **pp, int tag, int class);
+ASN1_BIT_STRING *d2i_ASN1_bytes(ASN1_OCTET_STRING **a, unsigned char **pp,
+	long length, int Ptag, int Pclass);
+
+/* PARSING */
+int asn1_Finish(ASN1_CTX *c);
+
+/* SPECIALS */
+int ASN1_get_object(unsigned char **pp, long *plength, int *ptag,
+	int *pclass, long omax);
+int ASN1_check_infinite_end(unsigned char **p,long len);
+void ASN1_put_object(unsigned char **pp, int constructed, int length,
+	int tag, int class);
+int ASN1_object_size(int constructed, int length, int tag);
+
+X509 *	X509_get_cert(CERTIFICATE_CTX *ctx,X509_NAME * name,X509 *tmp_x509);
+int  	X509_add_cert(CERTIFICATE_CTX *ctx,X509 *);
+
+char *	X509_cert_verify_error_string(int n);
+int 	X509_add_cert_file(CERTIFICATE_CTX *c,char *file, int type);
+char *	X509_gmtime (char *s, long adj);
+int	X509_add_cert_dir (CERTIFICATE_CTX *c,char *dir, int type);
+int	X509_load_verify_locations (CERTIFICATE_CTX *ctx,
+		char *file_env, char *dir_env);
+int	X509_set_default_verify_paths(CERTIFICATE_CTX *cts);
+X509 *	X509_new_D2i_X509(int len, unsigned char *p);
+char *	X509_get_default_cert_area(void );
+char *	X509_get_default_cert_dir(void );
+char *	X509_get_default_cert_file(void );
+char *	X509_get_default_cert_dir_env(void );
+char *	X509_get_default_cert_file_env(void );
+char *	X509_get_default_private_dir(void );
+X509_REQ *X509_X509_TO_req(X509 *x, RSA *rsa);
+int	X509_cert_verify(CERTIFICATE_CTX *ctx,X509 *xs, int (*cb)()); 
+
+CERTIFICATE_CTX *CERTIFICATE_CTX_new();
+void CERTIFICATE_CTX_free(CERTIFICATE_CTX *c);
+
+void X509_NAME_print(BIO *fp, X509_NAME *name, int obase);
+int		X509_print_fp(FILE *fp,X509 *x);
+int		X509_print(BIO *fp,X509 *x);
+
+X509_INFO *	X509_INFO_new(void);
+void		X509_INFO_free(X509_INFO *a);
+
+char *		X509_NAME_oneline(X509_NAME *a);
+
+#define X509_verify(x,rsa)
+#define X509_REQ_verify(x,rsa)
+#define X509_CRL_verify(x,rsa)
+
+#define X509_sign(x,rsa,md)
+#define X509_REQ_sign(x,rsa,md)
+#define X509_CRL_sign(x,rsa,md)
+
+#define X509_dup(x509)
+#define d2i_X509_fp(fp,x509)
+#define i2d_X509_fp(fp,x509)
+#define d2i_X509_bio(bp,x509)
+#define i2d_X509_bio(bp,x509)
+
+#define X509_CRL_dup(crl)
+#define d2i_X509_CRL_fp(fp,crl)
+#define i2d_X509_CRL_fp(fp,crl)
+#define d2i_X509_CRL_bio(bp,crl)
+#define i2d_X509_CRL_bio(bp,crl)
+
+#define X509_REQ_dup(req)
+#define d2i_X509_REQ_fp(fp,req)
+#define i2d_X509_REQ_fp(fp,req)
+#define d2i_X509_REQ_bio(bp,req)
+#define i2d_X509_REQ_bio(bp,req)
+
+#define RSAPrivateKey_dup(rsa)
+#define d2i_RSAPrivateKey_fp(fp,rsa)
+#define i2d_RSAPrivateKey_fp(fp,rsa)
+#define d2i_RSAPrivateKey_bio(bp,rsa)
+#define i2d_RSAPrivateKey_bio(bp,rsa)
+
+#define X509_NAME_dup(xn)
+#define X509_NAME_ENTRY_dup(ne)
+
+void X509_REQ_print_fp(FILE *fp,X509_REQ *req);
+void X509_REQ_print(BIO *fp,X509_REQ *req);
+
+RSA *X509_REQ_extract_key(X509_REQ *req);
+RSA *X509_extract_key(X509 *x509);
+
+int		X509_issuer_and_serial_cmp(X509 *a, X509 *b);
+unsigned long	X509_issuer_and_serial_hash(X509 *a);
+
+X509_NAME *	X509_get_issuer_name(X509 *a);
+int		X509_issuer_name_cmp(X509 *a, X509 *b);
+unsigned long	X509_issuer_name_hash(X509 *a);
+
+X509_NAME *	X509_get_subject_name(X509 *a);
+int		X509_subject_name_cmp(X509 *a,X509 *b);
+unsigned long	X509_subject_name_hash(X509 *x);
+
+int		X509_NAME_cmp (X509_NAME *a, X509_NAME *b);
+unsigned long	X509_NAME_hash(X509_NAME *x);
+
+
+==== bio.doc ========================================================
+
+BIO Routines
+
+This documentation is rather sparse, you are probably best 
+off looking at the code for specific details.
+
+The BIO library is a IO abstraction that was originally 
+inspired by the need to have callbacks to perform IO to FILE 
+pointers when using Windows 3.1 DLLs.  There are two types 
+of BIO; a source/sink type and a filter type.
+The source/sink methods are as follows:
+-	BIO_s_mem()  memory buffer - a read/write byte array that
+	grows until memory runs out :-).
+-	BIO_s_file()  FILE pointer - A wrapper around the normal 
+	'FILE *' commands, good for use with stdin/stdout.
+-	BIO_s_fd()  File descriptor - A wrapper around file 
+	descriptors, often used with pipes.
+-	BIO_s_socket()  Socket - Used around sockets.  It is 
+	mostly in the Microsoft world that sockets are different 
+	from file descriptors and there are all those ugly winsock 
+	commands.
+-	BIO_s_null()  Null - read nothing and write nothing.; a 
+	useful endpoint for filter type BIO's specifically things 
+	like the message digest BIO.
+
+The filter types are
+-	BIO_f_buffer()  IO buffering - does output buffering into 
+	larger chunks and performs input buffering to allow gets() 
+	type functions.
+-	BIO_f_md()  Message digest - a transparent filter that can 
+	be asked to return a message digest for the data that has 
+	passed through it.
+-	BIO_f_cipher()  Encrypt or decrypt all data passing 
+	through the filter.
+-	BIO_f_base64()  Base64 decode on read and encode on write.
+-	BIO_f_ssl()  A filter that performs SSL encryption on the 
+	data sent through it.
+
+Base BIO functions.
+The BIO library has a set of base functions that are 
+implemented for each particular type.  Filter BIOs will 
+normally call the equivalent function on the source/sink BIO 
+that they are layered on top of after they have performed 
+some modification to the data stream.  Multiple filter BIOs 
+can be 'push' into a stack of modifers, so to read from a 
+file, unbase64 it, then decrypt it, a BIO_f_cipher, 
+BIO_f_base64 and a BIO_s_file would probably be used.  If a 
+sha-1 and md5 message digest needed to be generated, a stack 
+two BIO_f_md() BIOs and a BIO_s_null() BIO could be used.
+The base functions are
+-	BIO *BIO_new(BIO_METHOD *type); Create  a new BIO of  type 'type'.
+-	int BIO_free(BIO *a); Free a BIO structure.  Depending on 
+	the configuration, this will free the underlying data 
+	object for a source/sink BIO.
+-	int BIO_read(BIO *b, char *data, int len); Read upto 'len' 
+	bytes into 'data'. 
+-	int BIO_gets(BIO *bp,char *buf, int size); Depending on 
+	the BIO, this can either be a 'get special' or a get one 
+	line of data, as per fgets();
+-	int BIO_write(BIO *b, char *data, int len); Write 'len' 
+	bytes from 'data' to the 'b' BIO.
+-	int BIO_puts(BIO *bp,char *buf); Either a 'put special' or 
+	a write null terminated string as per fputs().
+-	long BIO_ctrl(BIO *bp,int cmd,long larg,char *parg);  A 
+	control function which is used to manipulate the BIO 
+	structure and modify it's state and or report on it.  This 
+	function is just about never used directly, rather it 
+	should be used in conjunction with BIO_METHOD specific 
+	macros.
+-	BIO *BIO_push(BIO *new_top, BIO *old); new_top is apped to the
+	top of the 'old' BIO list.  new_top should be a filter BIO.
+	All writes will go through 'new_top' first and last on read.
+	'old' is returned.
+-	BIO *BIO_pop(BIO *bio); the new topmost BIO is returned, NULL if
+	there are no more.
+
+If a particular low level BIO method is not supported 
+(normally BIO_gets()), -2 will be returned if that method is 
+called.  Otherwise the IO methods (read, write, gets, puts) 
+will return the number of bytes read or written, and 0 or -1 
+for error (or end of input).  For the -1 case, 
+BIO_should_retry(bio) can be called to determine if it was a 
+genuine error or a temporary problem.  -2 will also be 
+returned if the BIO has not been initalised yet, in all 
+cases, the correct error codes are set (accessible via the 
+ERR library).
+
+
+The following functions are convenience functions:
+-	int BIO_printf(BIO *bio, char * format, ..);  printf but 
+	to a BIO handle.
+-	long BIO_ctrl_int(BIO *bp,int cmd,long larg,int iarg); a 
+	convenience function to allow a different argument types 
+	to be passed to BIO_ctrl().
+-	int BIO_dump(BIO *b,char *bytes,int len); output 'len' 
+	bytes from 'bytes' in a hex dump debug format.
+-	long BIO_debug_callback(BIO *bio, int cmd, char *argp, int 
+	argi, long argl, long ret) - a default debug BIO callback, 
+	this is mentioned below.  To use this one normally has to 
+	use the BIO_set_callback_arg() function to assign an 
+	output BIO for the callback to use.
+-	BIO *BIO_find_type(BIO *bio,int type); when there is a 'stack'
+	of BIOs, this function scan the list and returns the first
+	that is of type 'type', as listed in buffer.h under BIO_TYPE_XXX.
+-	void BIO_free_all(BIO *bio); Free the bio and all other BIOs
+	in the list.  It walks the bio->next_bio list.
+
+
+
+Extra commands are normally implemented as macros calling BIO_ctrl().
+-	BIO_number_read(BIO *bio) - the number of bytes processed 
+	by BIO_read(bio,.).
+-	BIO_number_written(BIO *bio) - the number of bytes written 
+	by BIO_write(bio,.).
+-	BIO_reset(BIO *bio) - 'reset' the BIO.
+-	BIO_eof(BIO *bio) - non zero if we are at the current end 
+	of input.
+-	BIO_set_close(BIO *bio, int close_flag) - set the close flag.
+-	BIO_get_close(BIO *bio) - return the close flag.
+	BIO_pending(BIO *bio) - return the number of bytes waiting 
+	to be read (normally buffered internally).
+-	BIO_flush(BIO *bio) - output any data waiting to be output.
+-	BIO_should_retry(BIO *io) - after a BIO_read/BIO_write 
+	operation returns 0 or -1, a call to this function will 
+	return non zero if you should retry the call later (this 
+	is for non-blocking IO).
+-	BIO_should_read(BIO *io) - we should retry when data can 
+	be read.
+-	BIO_should_write(BIO *io) - we should retry when data can 
+	be written.
+-	BIO_method_name(BIO *io) - return a string for the method name.
+-	BIO_method_type(BIO *io) - return the unique ID of the BIO method.
+-	BIO_set_callback(BIO *io,  long (*callback)(BIO *io, int 
+	cmd, char *argp, int argi, long argl, long ret); - sets 
+	the debug callback.
+-	BIO_get_callback(BIO *io) - return the assigned function 
+	as mentioned above.
+-	BIO_set_callback_arg(BIO *io, char *arg)  - assign some 
+	data against the BIO.  This is normally used by the debug 
+	callback but could in reality be used for anything.  To 
+	get an idea of how all this works, have a look at the code 
+	in the default debug callback mentioned above.  The 
+	callback can modify the return values.
+
+Details of the BIO_METHOD structure.
+typedef struct bio_method_st
+        {
+	int type;
+	char *name;
+	int (*bwrite)();
+	int (*bread)();
+	int (*bputs)();
+	int (*bgets)();
+	long (*ctrl)();
+	int (*create)();
+	int (*destroy)();
+	} BIO_METHOD;
+
+The 'type' is the numeric type of the BIO, these are listed in buffer.h;
+'Name' is a textual representation of the BIO 'type'.
+The 7 function pointers point to the respective function 
+methods, some of which can be NULL if not implemented.
+The BIO structure
+typedef struct bio_st
+	{
+	BIO_METHOD *method;
+	long (*callback)(BIO * bio, int mode, char *argp, int 
+		argi, long argl, long ret);
+	char *cb_arg; /* first argument for the callback */
+	int init;
+	int shutdown;
+	int flags;      /* extra storage */
+	int num;
+	char *ptr;
+	struct bio_st *next_bio; /* used by filter BIOs */
+	int references;
+	unsigned long num_read;
+	unsigned long num_write;
+	} BIO;
+
+-	'Method' is the BIO method.
+-	'callback', when configured, is called before and after 
+	each BIO method is called for that particular BIO.  This 
+	is intended primarily for debugging and of informational feedback.
+-	'init' is 0 when the BIO can be used for operation.  
+	Often, after a BIO is created, a number of operations may 
+	need to be performed before it is available for use.  An 
+	example is for BIO_s_sock().  A socket needs to be 
+	assigned to the BIO before it can be used.
+-	'shutdown', this flag indicates if the underlying 
+	communication primitive being used should be closed/freed 
+	when the BIO is closed.
+-	'flags' is used to hold extra state.  It is primarily used 
+	to hold information about why a non-blocking operation 
+	failed and to record startup protocol information for the 
+	SSL BIO.
+-	'num' and 'ptr' are used to hold instance specific state 
+	like file descriptors or local data structures.
+-	'next_bio' is used by filter BIOs to hold the pointer of the
+	next BIO in the chain. written data is sent to this BIO and
+	data read is taken from it.
+-	'references' is used to indicate the number of pointers to 
+	this structure.  This needs to be '1' before a call to 
+	BIO_free() is made if the BIO_free() function is to 
+	actually free() the structure, otherwise the reference 
+	count is just decreased.  The actual BIO subsystem does 
+	not really use this functionality but it is useful when 
+	used in more advanced applicaion.
+-	num_read and num_write are the total number of bytes 
+	read/written via the 'read()' and 'write()' methods.
+
+BIO_ctrl operations.
+The following is the list of standard commands passed as the 
+second parameter to BIO_ctrl() and should be supported by 
+all BIO as best as possible.  Some are optional, some are 
+manditory, in any case, where is makes sense, a filter BIO 
+should pass such requests to underlying BIO's.
+-	BIO_CTRL_RESET	- Reset the BIO back to an initial state.
+-	BIO_CTRL_EOF	- return 0 if we are not at the end of input, 
+	non 0 if we are.
+-	BIO_CTRL_INFO	- BIO specific special command, normal
+	information return.
+-	BIO_CTRL_SET	- set IO specific parameter.
+-	BIO_CTRL_GET	- get IO specific parameter.
+-	BIO_CTRL_GET_CLOSE - Get the close on BIO_free() flag, one 
+	of BIO_CLOSE or BIO_NOCLOSE.
+-	BIO_CTRL_SET_CLOSE - Set the close on BIO_free() flag.
+-	BIO_CTRL_PENDING - Return the number of bytes available 
+	for instant reading
+-	BIO_CTRL_FLUSH	- Output pending data, return number of bytes output.
+-	BIO_CTRL_SHOULD_RETRY - After an IO error (-1 returned) 
+	should we 'retry' when IO is possible on the underlying IO object.
+-	BIO_CTRL_RETRY_TYPE - What kind of IO are we waiting on.
+
+The following command is a special BIO_s_file() specific option.
+-	BIO_CTRL_SET_FILENAME - specify a file to open for IO.
+
+The BIO_CTRL_RETRY_TYPE needs a little more explanation.  
+When performing non-blocking IO, or say reading on a memory 
+BIO, when no data is present (or cannot be written), 
+BIO_read() and/or BIO_write() will return -1.  
+BIO_should_retry(bio) will return true if this is due to an 
+IO condition rather than an actual error.  In the case of 
+BIO_s_mem(), a read when there is no data will return -1 and 
+a should retry when there is more 'read' data.
+The retry type is deduced from 2 macros
+BIO_should_read(bio) and BIO_should_write(bio).
+Now while it may appear obvious that a BIO_read() failure 
+should indicate that a retry should be performed when more 
+read data is available, this is often not true when using 
+things like an SSL BIO.  During the SSL protocol startup 
+multiple reads and writes are performed, triggered by any 
+SSL_read or SSL_write.
+So to write code that will transparently handle either a 
+socket or SSL BIO,
+	i=BIO_read(bio,..)
+	if (I == -1)
+		{
+		if (BIO_should_retry(bio))
+			{
+			if (BIO_should_read(bio))
+				{
+				/* call us again when BIO can be read */
+				}
+			if (BIO_should_write(bio))
+				{
+				/* call us again when BIO can be written */
+				}
+			}
+		}
+
+At this point in time only read and write conditions can be 
+used but in the future I can see the situation for other 
+conditions, specifically with SSL there could be a condition 
+of a X509 certificate lookup taking place and so the non-
+blocking BIO_read would require a retry when the certificate 
+lookup subsystem has finished it's lookup.  This is all 
+makes more sense and is easy to use in a event loop type 
+setup.
+When using the SSL BIO, either SSL_read() or SSL_write()s 
+can be called during the protocol startup and things will 
+still work correctly.
+The nice aspect of the use of the BIO_should_retry() macro 
+is that all the errno codes that indicate a non-fatal error 
+are encapsulated in one place.  The Windows specific error 
+codes and WSAGetLastError() calls are also hidden from the 
+application.
+
+Notes on each BIO method.
+Normally buffer.h is just required but depending on the 
+BIO_METHOD, ssl.h or evp.h will also be required.
+
+BIO_METHOD *BIO_s_mem(void);
+-	BIO_set_mem_buf(BIO *bio, BUF_MEM *bm, int close_flag) - 
+	set the underlying BUF_MEM structure for the BIO to use.
+-	BIO_get_mem_ptr(BIO *bio, char **pp) - if pp is not NULL, 
+	set it to point to the memory array and return the number 
+	of bytes available.
+A read/write BIO.  Any data written is appended to the 
+memory array and any read is read from the front.  This BIO 
+can be used for read/write at the same time. BIO_gets() is 
+supported in the fgets() sense.
+BIO_CTRL_INFO can be used to retrieve pointers to the memory 
+buffer and it's length.
+
+BIO_METHOD *BIO_s_file(void);
+-	BIO_set_fp(BIO *bio, FILE *fp, int close_flag) - set 'FILE *' to use.
+-	BIO_get_fp(BIO *bio, FILE **fp) - get the 'FILE *' in use.
+-	BIO_read_filename(BIO *bio, char *name) - read from file.
+-	BIO_write_filename(BIO *bio, char *name) - write to file.
+-	BIO_append_filename(BIO *bio, char *name) - append to file.
+This BIO sits over the normal system fread()/fgets() type 
+functions. Gets() is supported.  This BIO in theory could be 
+used for read and write but it is best to think of each BIO 
+of this type as either a read or a write BIO, not both.
+
+BIO_METHOD *BIO_s_socket(void);
+BIO_METHOD *BIO_s_fd(void);
+-	BIO_sock_should_retry(int i) - the underlying function 
+	used to determine if a call should be retried; the 
+	argument is the '0' or '-1' returned by the previous BIO 
+	operation.
+-	BIO_fd_should_retry(int i) - same as the 
+-	BIO_sock_should_retry() except that it is different internally.
+-	BIO_set_fd(BIO *bio, int fd, int close_flag) - set the 
+	file descriptor to use
+-	BIO_get_fd(BIO *bio, int *fd) - get the file descriptor.
+These two methods are very similar.  Gets() is not 
+supported, if you want this functionality, put a 
+BIO_f_buffer() onto it.  This BIO is bi-directional if the 
+underlying file descriptor is.  This is normally the case 
+for sockets but not the case for stdio descriptors.
+
+BIO_METHOD *BIO_s_null(void);
+Read and write as much data as you like, it all disappears 
+into this BIO.
+
+BIO_METHOD *BIO_f_buffer(void);
+-	BIO_get_buffer_num_lines(BIO *bio) - return the number of 
+	complete lines in the buffer.
+-	BIO_set_buffer_size(BIO *bio, long size) - set the size of 
+	the buffers.
+This type performs input and output buffering.  It performs 
+both at the same time.  The size of the buffer can be set 
+via the set buffer size option.  Data buffered for output is 
+only written when the buffer fills.
+
+BIO_METHOD *BIO_f_ssl(void);
+-	BIO_set_ssl(BIO *bio, SSL *ssl, int close_flag) - the SSL 
+	structure to use.
+-	BIO_get_ssl(BIO *bio, SSL **ssl) - get the SSL structure 
+	in use.
+The SSL bio is a little different from normal BIOs because 
+the underlying SSL structure is a little different.  A SSL 
+structure performs IO via a read and write BIO.  These can 
+be different and are normally set via the
+SSL_set_rbio()/SSL_set_wbio() calls.  The SSL_set_fd() calls 
+are just wrappers that create socket BIOs and then call 
+SSL_set_bio() where the read and write BIOs are the same.  
+The BIO_push() operation makes the SSLs IO BIOs the same, so 
+make sure the BIO pushed is capable of two directional 
+traffic.  If it is not, you will have to install the BIOs 
+via the more conventional SSL_set_bio() call.  BIO_pop() will retrieve
+the 'SSL read' BIO.
+
+BIO_METHOD *BIO_f_md(void);
+-	BIO_set_md(BIO *bio, EVP_MD *md) - set the message digest 
+	to use.
+-	BIO_get_md(BIO *bio, EVP_MD **mdp) - return the digest 
+	method in use in mdp, return 0 if not set yet.
+-	BIO_reset() reinitializes the digest (EVP_DigestInit()) 
+	and passes the reset to the underlying BIOs.
+All data read or written via BIO_read() or BIO_write() to 
+this BIO will be added to the calculated digest.  This 
+implies that this BIO is only one directional.  If read and 
+write operations are performed, two separate BIO_f_md() BIOs 
+are reuqired to generate digests on both the input and the 
+output.  BIO_gets(BIO *bio, char *md, int size) will place the 
+generated digest into 'md' and return the number of bytes.  
+The EVP_MAX_MD_SIZE should probably be used to size the 'md' 
+array.  Reading the digest will also reset it.
+
+BIO_METHOD *BIO_f_cipher(void);
+-	BIO_reset() reinitializes the cipher.
+-	BIO_flush() should be called when the last bytes have been 
+	output to flush the final block of block ciphers.
+-	BIO_get_cipher_status(BIO *b), when called after the last 
+	read from a cipher BIO, returns non-zero if the data 
+	decrypted correctly, otherwise, 0.
+-	BIO_set_cipher(BIO *b, EVP_CIPHER *c, unsigned char *key, 
+	unsigned char *iv, int encrypt)   This function is used to 
+	setup a cipher BIO.  The length of key and iv are 
+	specified by the choice of EVP_CIPHER.  Encrypt is 1 to 
+	encrypt and 0 to decrypt.
+
+BIO_METHOD *BIO_f_base64(void);
+-	BIO_flush() should be called when the last bytes have been output.
+This BIO base64 encodes when writing and base64 decodes when 
+reading.  It will scan the input until a suitable begin line 
+is found.  After reading data, BIO_reset() will reset the 
+BIO to start scanning again.  Do not mix reading and writing 
+on the same base64 BIO.  It is meant as a single stream BIO.
+
+Directions	type
+both		BIO_s_mem()
+one/both	BIO_s_file()
+both		BIO_s_fd()
+both		BIO_s_socket() 
+both		BIO_s_null()
+both		BIO_f_buffer()
+one		BIO_f_md()  
+one		BIO_f_cipher()  
+one		BIO_f_base64()  
+both		BIO_f_ssl()
+
+It is easy to mix one and two directional BIOs, all one has 
+to do is to keep two separate BIO pointers for reading and 
+writing and be careful about usage of underlying BIOs.  The 
+SSL bio by it's very nature has to be two directional but 
+the BIO_push() command will push the one BIO into the SSL 
+BIO for both reading and writing.
+
+The best example program to look at is apps/enc.c and/or perhaps apps/dgst.c.
+
+
+==== blowfish.doc ========================================================
+
+The Blowfish library.
+
+Blowfish is a block cipher that operates on 64bit (8 byte) quantities.  It
+uses variable size key, but 128bit (16 byte) key would normally be considered
+good.  It can be used in all the modes that DES can be used.  This
+library implements the ecb, cbc, cfb64, ofb64 modes.
+
+Blowfish is quite a bit faster that DES, and much faster than IDEA or
+RC2.  It is one of the faster block ciphers.
+
+For all calls that have an 'input' and 'output' variables, they can be the
+same.
+
+This library requires the inclusion of 'blowfish.h'.
+
+All of the encryption functions take what is called an BF_KEY as an 
+argument.  An BF_KEY is an expanded form of the Blowfish key.
+For all modes of the Blowfish algorithm, the BF_KEY used for
+decryption is the same one that was used for encryption.
+
+The define BF_ENCRYPT is passed to specify encryption for the functions
+that require an encryption/decryption flag. BF_DECRYPT is passed to
+specify decryption.
+
+Please note that any of the encryption modes specified in my DES library
+could be used with Blowfish.  I have only implemented ecb, cbc, cfb64 and
+ofb64 for the following reasons.
+- ecb is the basic Blowfish encryption.
+- cbc is the normal 'chaining' form for block ciphers.
+- cfb64 can be used to encrypt single characters, therefore input and output
+  do not need to be a multiple of 8.
+- ofb64 is similar to cfb64 but is more like a stream cipher, not as
+  secure (not cipher feedback) but it does not have an encrypt/decrypt mode.
+- If you want triple Blowfish, thats 384 bits of key and you must be totally
+  obsessed with security.  Still, if you want it, it is simple enough to
+  copy the function from the DES library and change the des_encrypt to
+  BF_encrypt; an exercise left for the paranoid reader :-).
+
+The functions are as follows:
+
+void BF_set_key(
+BF_KEY *ks;
+int len;
+unsigned char *key;
+        BF_set_key converts an 'len' byte key into a BF_KEY.
+        A 'ks' is an expanded form of the 'key' which is used to
+        perform actual encryption.  It can be regenerated from the Blowfish key
+        so it only needs to be kept when encryption or decryption is about
+        to occur.  Don't save or pass around BF_KEY's since they
+        are CPU architecture dependent, 'key's are not.  Blowfish is an
+	interesting cipher in that it can be used with a variable length
+	key.  'len' is the length of 'key' to be used as the key.
+	A 'len' of 16 is recomended by me, but blowfish can use upto
+	72 bytes.  As a warning, blowfish has a very very slow set_key
+	function, it actually runs BF_encrypt 521 times.
+	
+void BF_encrypt(unsigned long *data, BF_KEY *key);
+void BF_decrypt(unsigned long *data, BF_KEY *key);
+	These are the Blowfish encryption function that gets called by just
+	about every other Blowfish routine in the library.  You should not
+	use this function except to implement 'modes' of Blowfish.
+	I say this because the
+	functions that call this routine do the conversion from 'char *' to
+	long, and this needs to be done to make sure 'non-aligned' memory
+	access do not occur.
+	Data is a pointer to 2 unsigned long's and key is the
+	BF_KEY to use. 
+
+void BF_ecb_encrypt(
+unsigned char *in,
+unsigned char *out,
+BF_KEY *key,
+int encrypt);
+	This is the basic Electronic Code Book form of Blowfish (in DES this
+	mode is called Electronic Code Book so I'm going to use the term
+	for blowfish as well.
+	Input is encrypted into output using the key represented by
+	key.  Depending on the encrypt, encryption or
+	decryption occurs.  Input is 8 bytes long and output is 8 bytes.
+	
+void BF_cbc_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+BF_KEY *ks,
+unsigned char *ivec,
+int encrypt);
+	This routine implements Blowfish in Cipher Block Chaining mode.
+	Input, which should be a multiple of 8 bytes is encrypted
+	(or decrypted) to output which will also be a multiple of 8 bytes.
+	The number of bytes is in length (and from what I've said above,
+	should be a multiple of 8).  If length is not a multiple of 8, bad 
+	things will probably happen.  ivec is the initialisation vector.
+	This function updates iv after each call so that it can be passed to
+	the next call to BF_cbc_encrypt().
+	
+void BF_cfb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+BF_KEY *schedule,
+unsigned char *ivec,
+int *num,
+int encrypt);
+	This is one of the more useful functions in this Blowfish library, it
+	implements CFB mode of Blowfish with 64bit feedback.
+	This allows you to encrypt an arbitrary number of bytes,
+	you do not require 8 byte padding.  Each call to this
+	routine will encrypt the input bytes to output and then update ivec
+	and num.  Num contains 'how far' we are though ivec.
+	'Encrypt' is used to indicate encryption or decryption.
+	CFB64 mode operates by using the cipher to generate a stream
+	of bytes which is used to encrypt the plain text.
+	The cipher text is then encrypted to generate the next 64 bits to
+	be xored (incrementally) with the next 64 bits of plain
+	text.  As can be seen from this, to encrypt or decrypt,
+	the same 'cipher stream' needs to be generated but the way the next
+	block of data is gathered for encryption is different for
+	encryption and decryption.
+	
+void BF_ofb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+BF_KEY *schedule,
+unsigned char *ivec,
+int *num);
+	This functions implements OFB mode of Blowfish with 64bit feedback.
+	This allows you to encrypt an arbitrary number of bytes,
+	you do not require 8 byte padding.  Each call to this
+	routine will encrypt the input bytes to output and then update ivec
+	and num.  Num contains 'how far' we are though ivec.
+	This is in effect a stream cipher, there is no encryption or
+	decryption mode.
+	
+For reading passwords, I suggest using des_read_pw_string() from my DES library.
+To generate a password from a text string, I suggest using MD5 (or MD2) to
+produce a 16 byte message digest that can then be passed directly to
+BF_set_key().
+
+=====
+For more information about the specific Blowfish modes in this library
+(ecb, cbc, cfb and ofb), read the section entitled 'Modes of DES' from the
+documentation on my DES library.  What is said about DES is directly
+applicable for Blowfish.
+
+
+==== bn.doc ========================================================
+
+The Big Number library.
+
+#include "bn.h" when using this library.
+
+This big number library was written for use in implementing the RSA and DH
+public key encryption algorithms.  As such, features such as negative
+numbers have not been extensively tested but they should work as expected.
+This library uses dynamic memory allocation for storing its data structures
+and so there are no limit on the size of the numbers manipulated by these
+routines but there is always the requirement to check return codes from
+functions just in case a memory allocation error has occurred.
+
+The basic object in this library is a BIGNUM.  It is used to hold a single
+large integer.  This type should be considered opaque and fields should not
+be modified or accessed directly.
+typedef struct bignum_st
+	{
+	int top;	/* Index of last used d. */
+	BN_ULONG *d;	/* Pointer to an array of 'BITS2' bit chunks. */
+	int max;	/* Size of the d array. */
+	int neg;
+	} BIGNUM;
+The big number is stored in a malloced array of BN_ULONG's.  A BN_ULONG can
+be either 16, 32 or 64 bits in size, depending on the 'number of  bits'
+specified in bn.h. 
+The 'd' field is this array.  'max' is the size of the 'd' array that has
+been allocated.  'top' is the 'last' entry being used, so for a value of 4,
+bn.d[0]=4 and bn.top=1.  'neg' is 1 if the number is negative.
+When a BIGNUM is '0', the 'd' field can be NULL and top == 0.
+
+Various routines in this library require the use of 'temporary' BIGNUM
+variables during their execution.  Due to the use of dynamic memory
+allocation to create BIGNUMs being rather expensive when used in
+conjunction with repeated subroutine calls, the BN_CTX structure is
+used.  This structure contains BN_CTX BIGNUMs.  BN_CTX
+is the maximum number of temporary BIGNUMs any publicly exported 
+function will use.
+
+#define BN_CTX	12
+typedef struct bignum_ctx
+	{
+	int tos;			/* top of stack */
+	BIGNUM *bn[BN_CTX];	/* The variables */
+	} BN_CTX;
+
+The functions that follow have been grouped according to function.  Most
+arithmetic functions return a result in the first argument, sometimes this
+first argument can also be an input parameter, sometimes it cannot.  These
+restrictions are documented.
+
+extern BIGNUM *BN_value_one;
+There is one variable defined by this library, a BIGNUM which contains the
+number 1.  This variable is useful for use in comparisons and assignment.
+
+Get Size functions.
+
+int BN_num_bits(BIGNUM *a);
+	This function returns the size of 'a' in bits.
+	
+int BN_num_bytes(BIGNUM *a);
+	This function (macro) returns the size of 'a' in bytes.
+	For conversion of BIGNUMs to byte streams, this is the number of
+	bytes the output string will occupy.  If the output byte
+	format specifies that the 'top' bit indicates if the number is
+	signed, so an extra '0' byte is required if the top bit on a
+	positive number is being written, it is upto the application to
+	make this adjustment.  Like I said at the start, I don't
+	really support negative numbers :-).
+
+Creation/Destruction routines.
+
+BIGNUM *BN_new();
+	Return a new BIGNUM object.  The number initially has a value of 0.  If
+	there is an error, NULL is returned.
+	
+void	BN_free(BIGNUM *a);
+	Free()s a BIGNUM.
+	
+void	BN_clear(BIGNUM *a);
+	Sets 'a' to a value of 0 and also zeros all unused allocated
+	memory.  This function is used to clear a variable of 'sensitive'
+	data that was held in it.
+	
+void	BN_clear_free(BIGNUM *a);
+	This function zeros the memory used by 'a' and then free()'s it.
+	This function should be used to BN_free() BIGNUMS that have held
+	sensitive numeric values like RSA private key values.  Both this
+	function and BN_clear tend to only be used by RSA and DH routines.
+
+BN_CTX *BN_CTX_new(void);
+	Returns a new BN_CTX.  NULL on error.
+	
+void	BN_CTX_free(BN_CTX *c);
+	Free a BN_CTX structure.  The BIGNUMs in 'c' are BN_clear_free()ed.
+	
+BIGNUM *bn_expand(BIGNUM *b, int bits);
+	This is an internal function that should not normally be used.  It
+	ensures that 'b' has enough room for a 'bits' bit number.  It is
+	mostly used by the various BIGNUM routines.  If there is an error,
+	NULL is returned. if not, 'b' is returned.
+	
+BIGNUM *BN_copy(BIGNUM *to, BIGNUM *from);
+	The 'from' is copied into 'to'.  NULL is returned if there is an
+	error, otherwise 'to' is returned.
+
+BIGNUM *BN_dup(BIGNUM *a);
+	A new BIGNUM is created and returned containing the value of 'a'.
+	NULL is returned on error.
+
+Comparison and Test Functions.
+
+int BN_is_zero(BIGNUM *a)
+	Return 1 if 'a' is zero, else 0.
+
+int BN_is_one(a)
+	Return 1 is 'a' is one, else 0.
+
+int BN_is_word(a,w)
+	Return 1 if 'a' == w, else 0.  'w' is a BN_ULONG.
+
+int BN_cmp(BIGNUM *a, BIGNUM *b);
+	Return -1 if 'a' is less than 'b', 0 if 'a' and 'b' are the same
+	and 1 is 'a' is greater than 'b'.  This is a signed comparison.
+	
+int BN_ucmp(BIGNUM *a, BIGNUM *b);
+	This function is the same as BN_cmp except that the comparison
+	ignores the sign of the numbers.
+	
+Arithmetic Functions
+For all of these functions, 0 is returned if there is an error and 1 is
+returned for success.  The return value should always be checked.  eg.
+if (!BN_add(r,a,b)) goto err;
+Unless explicitly mentioned, the 'return' value can be one of the
+'parameters' to the function.
+
+int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b);
+	Add 'a' and 'b' and return the result in 'r'.  This is r=a+b.
+	
+int BN_sub(BIGNUM *r, BIGNUM *a, BIGNUM *b);
+	Subtract 'a' from 'b' and put the result in 'r'. This is r=a-b.
+	
+int BN_lshift(BIGNUM *r, BIGNUM *a, int n);
+	Shift 'a' left by 'n' bits.  This is r=a*(2^n).
+	
+int BN_lshift1(BIGNUM *r, BIGNUM *a);
+	Shift 'a' left by 1 bit.  This form is more efficient than
+	BN_lshift(r,a,1).  This is r=a*2.
+	
+int BN_rshift(BIGNUM *r, BIGNUM *a, int n);
+	Shift 'a' right by 'n' bits.  This is r=int(a/(2^n)).
+	
+int BN_rshift1(BIGNUM *r, BIGNUM *a);
+	Shift 'a' right by 1 bit.  This form is more efficient than
+	BN_rshift(r,a,1).  This is r=int(a/2).
+	
+int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b);
+	Multiply a by b and return the result in 'r'. 'r' must not be
+	either 'a' or 'b'.  It has to be a different BIGNUM.
+	This is r=a*b.
+
+int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx);
+	Multiply a by a and return the result in 'r'. 'r' must not be
+	'a'.  This function is alot faster than BN_mul(r,a,a).  This is r=a*a.
+
+int BN_div(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BIGNUM *d, BN_CTX *ctx);
+	Divide 'm' by 'd' and return the result in 'dv' and the remainder
+	in 'rem'.  Either of 'dv' or 'rem' can be NULL in which case that
+	value is not returned.  'ctx' needs to be passed as a source of
+	temporary BIGNUM variables.
+	This is dv=int(m/d), rem=m%d.
+	
+int BN_mod(BIGNUM *rem, BIGNUM *m, BIGNUM *d, BN_CTX *ctx);
+	Find the remainder of 'm' divided by 'd' and return it in 'rem'.
+	'ctx' holds the temporary BIGNUMs required by this function.
+	This function is more efficient than BN_div(NULL,rem,m,d,ctx);
+	This is rem=m%d.
+
+int BN_mod_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *m,BN_CTX *ctx);
+	Multiply 'a' by 'b' and return the remainder when divided by 'm'.
+	'ctx' holds the temporary BIGNUMs required by this function.
+	This is r=(a*b)%m.
+
+int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,BN_CTX *ctx);
+	Raise 'a' to the 'p' power and return the remainder when divided by
+	'm'.  'ctx' holds the temporary BIGNUMs required by this function.
+	This is r=(a^p)%m.
+
+int BN_reciprocal(BIGNUM *r, BIGNUM *m, BN_CTX *ctx);
+	Return the reciprocal of 'm'.  'ctx' holds the temporary variables
+	required.  This function returns -1 on error, otherwise it returns
+	the number of bits 'r' is shifted left to make 'r' into an integer.
+	This number of bits shifted is required in BN_mod_mul_reciprocal().
+	This is r=(1/m)<<(BN_num_bits(m)+1).
+	
+int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BIGNUM *m, 
+	BIGNUM *i, int nb, BN_CTX *ctx);
+	This function is used to perform an efficient BN_mod_mul()
+	operation.  If one is going to repeatedly perform BN_mod_mul() with
+	the same modulus is worth calculating the reciprocal of the modulus
+	and then using this function.  This operation uses the fact that
+	a/b == a*r where r is the reciprocal of b.  On modern computers
+	multiplication is very fast and big number division is very slow.
+	'x' is multiplied by 'y' and then divided by 'm' and the remainder
+	is returned.  'i' is the reciprocal of 'm' and 'nb' is the number
+	of bits as returned from BN_reciprocal().  Normal usage is as follows.
+	bn=BN_reciprocal(i,m);
+	for (...)
+		{ BN_mod_mul_reciprocal(r,x,y,m,i,bn,ctx); }
+	This is r=(x*y)%m.  Internally it is approximately
+	r=(x*y)-m*(x*y/m) or r=(x*y)-m*((x*y*i) >> bn)
+	This function is used in BN_mod_exp() and BN_is_prime().
+
+Assignment Operations
+
+int BN_one(BIGNUM *a)
+	Set 'a' to hold the value one.
+	This is a=1.
+	
+int BN_zero(BIGNUM *a)
+	Set 'a' to hold the value zero.
+	This is a=0.
+	
+int BN_set_word(BIGNUM *a, unsigned long w);
+	Set 'a' to hold the value of 'w'.  'w' is an unsigned long.
+	This is a=w.
+
+unsigned long BN_get_word(BIGNUM *a);
+	Returns 'a' in an unsigned long.  Not remarkably, often 'a' will
+	be bigger than a word, in which case 0xffffffffL is returned.
+
+Word Operations
+These functions are much more efficient that the normal bignum arithmetic
+operations.
+
+BN_ULONG BN_mod_word(BIGNUM *a, unsigned long w);
+	Return the remainder of 'a' divided by 'w'.
+	This is return(a%w).
+	
+int BN_add_word(BIGNUM *a, unsigned long w);
+	Add 'w' to 'a'.  This function does not take the sign of 'a' into
+	account.  This is a+=w;
+	
+Bit operations.
+
+int BN_is_bit_set(BIGNUM *a, int n);
+	This function return 1 if bit 'n' is set in 'a' else 0.
+
+int BN_set_bit(BIGNUM *a, int n);
+	This function sets bit 'n' to 1 in 'a'. 
+	This is a&= ~(1<<n);
+
+int BN_clear_bit(BIGNUM *a, int n);
+	This function sets bit 'n' to zero in 'a'.  Return 0 if less
+	than 'n' bits in 'a' else 1.  This is a&= ~(1<<n);
+
+int BN_mask_bits(BIGNUM *a, int n);
+	Truncate 'a' to n bits long.  This is a&= ~((~0)<<n)
+
+Format conversion routines.
+
+BIGNUM *BN_bin2bn(unsigned char *s, int len,BIGNUM *ret);
+	This function converts 'len' bytes in 's' into a BIGNUM which
+	is put in 'ret'.  If ret is NULL, a new BIGNUM is created.
+	Either this new BIGNUM or ret is returned.  The number is
+	assumed to be in bigendian form in 's'.  By this I mean that
+	to 'ret' is created as follows for 'len' == 5.
+	ret = s[0]*2^32 + s[1]*2^24 + s[2]*2^16 + s[3]*2^8 + s[4];
+	This function cannot be used to convert negative numbers.  It
+	is always assumed the number is positive.  The application
+	needs to diddle the 'neg' field of th BIGNUM its self.
+	The better solution would be to save the numbers in ASN.1 format
+	since this is a defined standard for storing big numbers.
+	Look at the functions
+
+	ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai);
+	BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai,BIGNUM *bn);
+	int i2d_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp);
+	ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a,unsigned char **pp,
+		long length;
+
+int BN_bn2bin(BIGNUM *a, unsigned char *to);
+	This function converts 'a' to a byte string which is put into
+	'to'.  The representation is big-endian in that the most
+	significant byte of 'a' is put into to[0].  This function
+	returns the number of bytes used to hold 'a'.  BN_num_bytes(a)
+	would return the same value and can be used to determine how
+	large 'to' needs to be.  If the number is negative, this
+	information is lost.  Since this library was written to
+	manipulate large positive integers, the inability to save and
+	restore them is not considered to be a problem by me :-).
+	As for BN_bin2bn(), look at the ASN.1 integer encoding funtions
+	for SSLeay.  They use BN_bin2bn() and BN_bn2bin() internally.
+	
+char *BN_bn2ascii(BIGNUM *a);
+	This function returns a malloc()ed string that contains the
+	ascii hexadecimal encoding of 'a'.  The number is in bigendian
+	format with a '-' in front if the number is negative.
+
+int BN_ascii2bn(BIGNUM **bn, char *a);
+	The inverse of BN_bn2ascii.  The function returns the number of
+	characters from 'a' were processed in generating a the bignum.
+	error is inticated by 0 being returned.  The number is a
+	hex digit string, optionally with a leading '-'.  If *bn
+	is null, a BIGNUM is created and returned via that variable.
+	
+int BN_print_fp(FILE *fp, BIGNUM *a);
+	'a' is printed to file pointer 'fp'.  It is in the same format
+	that is output from BN_bn2ascii().  0 is returned on error,
+	1 if things are ok.
+
+int BN_print(BIO *bp, BIGNUM *a);
+	Same as BN_print except that the output is done to the SSLeay libraries
+	BIO routines.  BN_print_fp() actually calls this function.
+
+Miscellaneous Routines.
+
+int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
+	This function returns in 'rnd' a random BIGNUM that is bits
+	long.  If bottom is 1, the number returned is odd.  If top is set,
+	the top 2 bits of the number are set.  This is useful because if
+	this is set, 2 'n; bit numbers multiplied together will return a 2n
+	bit number.  If top was not set, they could produce a 2n-1 bit
+	number.
+
+BIGNUM *BN_mod_inverse(BIGNUM *a, BIGNUM *n,BN_CTX *ctx);
+	This function create a new BIGNUM and returns it.  This number
+	is the inverse mod 'n' of 'a'.  By this it is meant that the
+	returned value 'r' satisfies (a*r)%n == 1.  This function is
+	used in the generation of RSA keys.  'ctx', as per usual,
+	is used to hold temporary variables that are required by the
+	function.  NULL is returned on error.
+
+int BN_gcd(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_CTX *ctx);
+	'r' has the greatest common divisor of 'a' and 'b'.  'ctx' is
+	used for temporary variables and 0 is returned on error.
+
+int BN_is_prime(BIGNUM *p,int nchecks,void (*callback)(),BN_CTX *ctx,
+	char *cb_arg);
+	This function is used to check if a BIGNUM ('p') is prime.
+	It performs this test by using the Miller-Rabin randomised
+	primality test.  This is a probalistic test that requires a
+	number of rounds to ensure the number is prime to a high
+	degree of probability.  Since this can take quite some time, a
+	callback function can be passed and it will be called each
+	time 'p' passes a round of the prime testing.  'callback' will
+	be called as follows, callback(1,n,cb_arg) where n is the number of
+	the round, just passed.  As per usual 'ctx' contains temporary
+	variables used.  If ctx is NULL, it does not matter, a local version
+	will be malloced.  This parameter is present to save some mallocing
+	inside the function but probably could be removed.
+	0 is returned on error.
+	'ncheck' is the number of Miller-Rabin tests to run.  It is
+	suggested to use the value 'BN_prime_checks' by default.
+
+BIGNUM *BN_generate_prime(
+int bits,
+int strong,
+BIGNUM *a,
+BIGNUM *rems,
+void (*callback)());
+char *cb_arg
+	This function is used to generate prime numbers.  It returns a
+	new BIGNUM that has a high probability of being a prime.
+	'bits' is the number of bits that
+	are to be in the prime.  If 'strong' is true, the returned prime
+	will also be a strong prime ((p-1)/2 is also prime).
+	While searching for the prime ('p'), we
+	can add the requirement that the prime fill the following
+	condition p%a == rem.  This can be used to help search for
+	primes with specific features, which is required when looking
+	for primes suitable for use with certain 'g' values in the
+	Diffie-Hellman key exchange algorithm.  If 'a' is NULL,
+	this condition is not checked.  If rem is NULL, rem is assumed
+	to be 1.  Since this search for a prime
+	can take quite some time, if callback is not NULL, it is called
+	in the following situations.
+	We have a suspected prime (from a quick sieve),
+	callback(0,sus_prime++,cb_arg). Each item to be passed to BN_is_prime().
+	callback(1,round++,cb_arg).  Each successful 'round' in BN_is_prime().
+	callback(2,round,cb_arg). For each successful BN_is_prime() test.
+
+Hints
+-----
+
+DSA wants 64*32 to use word mont mul, but RSA wants to use full.
+
+==== callback.doc ========================================================
+
+Callback functions used in SSLeay.
+
+--------------------------
+The BIO library.  
+
+Each BIO structure can have a callback defined against it.  This callback is
+called 2 times for each BIO 'function'.  It is passed 6 parameters.
+BIO_debug_callback() is an example callback which is defined in
+crypto/buffer/bio_cb.c and is used in apps/dgst.c  This is intended mostly
+for debuging or to notify the application of IO.
+
+long BIO_debug_callback(BIO *bio,int cmd,char *argp,int argi,long argl,
+	long ret);
+bio is the BIO being called, cmd is the type of BIO function being called.
+Look at the BIO_CB_* defines in buffer.h.  Argp and argi are the arguments
+passed to BIO_read(), BIO_write, BIO_gets(), BIO_puts().  In the case of
+BIO_ctrl(), argl is also defined.  The first time the callback is called,
+before the underlying function has been executed, 0 is passed as 'ret', and
+if the return code from the callback is not > 0, the call is aborted
+and the returned <= 0 value is returned.
+The second time the callback is called, the 'cmd' value also has
+BIO_CB_RETURN logically 'or'ed with it.  The 'ret' value is the value returned
+from the actuall function call and whatever the callback returns is returned
+from the BIO function.
+
+BIO_set_callback(b,cb) can be used to set the callback function
+(b is a BIO), and BIO_set_callback_arg(b,arg) can be used to
+set the cb_arg argument in the BIO strucutre.  This field is only intended
+to be used by application, primarily in the callback function since it is
+accessable since the BIO is passed.
+
+--------------------------
+The PEM library.
+
+The pem library only really uses one type of callback,
+static int def_callback(char *buf, int num, int verify);
+which is used to return a password string if required.
+'buf' is the buffer to put the string in.  'num' is the size of 'buf'
+and 'verify' is used to indicate that the password should be checked.
+This last flag is mostly used when reading a password for encryption.
+
+For all of these functions, a NULL callback will call the above mentioned
+default callback.  This default function does not work under Windows 3.1.
+For other machines, it will use an application defined prompt string
+(EVP_set_pw_prompt(), which defines a library wide prompt string)
+if defined, otherwise it will use it's own PEM password prompt.
+It will then call EVP_read_pw_string() to get a password from the console.
+If your application wishes to use nice fancy windows to retrieve passwords,
+replace this function.  The callback should return the number of bytes read
+into 'buf'.  If the number of bytes <= 0, it is considered an error.
+
+Functions that take this callback are listed below.  For the 'read' type
+functions, the callback will only be required if the PEM data is encrypted.
+
+For the Write functions, normally a password can be passed in 'kstr', of
+'klen' bytes which will be used if the 'enc' cipher is not NULL.  If
+'kstr' is NULL, the callback will be used to retrieve a password.
+
+int PEM_do_header (EVP_CIPHER_INFO *cipher, unsigned char *data,long *len,
+	int (*callback)());
+char *PEM_ASN1_read_bio(char *(*d2i)(),char *name,BIO *bp,char **x,int (*cb)());
+char *PEM_ASN1_read(char *(*d2i)(),char *name,FILE *fp,char **x,int (*cb)());
+int PEM_ASN1_write_bio(int (*i2d)(),char *name,BIO *bp,char *x,
+	EVP_CIPHER *enc,unsigned char *kstr,int klen,int (*callback)());
+int PEM_ASN1_write(int (*i2d)(),char *name,FILE *fp,char *x,
+	EVP_CIPHER *enc,unsigned char *kstr,int klen,int (*callback)());
+STACK *PEM_X509_INFO_read(FILE *fp, STACK *sk, int (*cb)());
+STACK *PEM_X509_INFO_read_bio(BIO *fp, STACK *sk, int (*cb)());
+
+#define	PEM_write_RSAPrivateKey(fp,x,enc,kstr,klen,cb)
+#define	PEM_write_DSAPrivateKey(fp,x,enc,kstr,klen,cb)
+#define	PEM_write_bio_RSAPrivateKey(bp,x,enc,kstr,klen,cb)
+#define	PEM_write_bio_DSAPrivateKey(bp,x,enc,kstr,klen,cb)
+#define	PEM_read_SSL_SESSION(fp,x,cb)
+#define	PEM_read_X509(fp,x,cb)
+#define	PEM_read_X509_REQ(fp,x,cb)
+#define	PEM_read_X509_CRL(fp,x,cb)
+#define	PEM_read_RSAPrivateKey(fp,x,cb)
+#define	PEM_read_DSAPrivateKey(fp,x,cb)
+#define	PEM_read_PrivateKey(fp,x,cb)
+#define	PEM_read_PKCS7(fp,x,cb)
+#define	PEM_read_DHparams(fp,x,cb)
+#define	PEM_read_bio_SSL_SESSION(bp,x,cb)
+#define	PEM_read_bio_X509(bp,x,cb)
+#define	PEM_read_bio_X509_REQ(bp,x,cb)
+#define	PEM_read_bio_X509_CRL(bp,x,cb)
+#define	PEM_read_bio_RSAPrivateKey(bp,x,cb)
+#define	PEM_read_bio_DSAPrivateKey(bp,x,cb)
+#define	PEM_read_bio_PrivateKey(bp,x,cb)
+#define	PEM_read_bio_PKCS7(bp,x,cb)
+#define	PEM_read_bio_DHparams(bp,x,cb)
+int i2d_Netscape_RSA(RSA *a, unsigned char **pp, int (*cb)());
+RSA *d2i_Netscape_RSA(RSA **a, unsigned char **pp, long length, int (*cb)());
+
+Now you will notice that macros like
+#define PEM_write_X509(fp,x) \
+                PEM_ASN1_write((int (*)())i2d_X509,PEM_STRING_X509,fp, \
+		                        (char *)x, NULL,NULL,0,NULL)
+Don't do encryption normally.  If you want to PEM encrypt your X509 structure,
+either just call PEM_ASN1_write directly or just define your own
+macro variant.  As you can see, this macro just sets all encryption related
+parameters to NULL.
+
+
+--------------------------
+The SSL library.
+
+#define SSL_set_info_callback(ssl,cb)
+#define SSL_CTX_set_info_callback(ctx,cb)
+void callback(SSL *ssl,int location,int ret)
+This callback is called each time around the SSL_connect()/SSL_accept() 
+state machine.  So it will be called each time the SSL protocol progresses.
+It is mostly present for use when debugging.  When SSL_connect() or
+SSL_accept() return, the location flag is SSL_CB_ACCEPT_EXIT or
+SSL_CB_CONNECT_EXIT and 'ret' is the value about to be returned.
+Have a look at the SSL_CB_* defines in ssl.h.  If an info callback is defined
+against the SSL_CTX, it is called unless there is one set against the SSL.
+Have a look at
+void client_info_callback() in apps/s_client() for an example.
+
+Certificate verification.
+void SSL_set_verify(SSL *s, int mode, int (*callback) ());
+void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,int (*callback)());
+This callback is used to help verify client and server X509 certificates.
+It is actually passed to X509_cert_verify(), along with the SSL structure
+so you have to read about X509_cert_verify() :-).  The SSL_CTX version is used
+if the SSL version is not defined.  X509_cert_verify() is the function used
+by the SSL part of the library to verify certificates.  This function is
+nearly always defined by the application.
+
+void SSL_CTX_set_cert_verify_cb(SSL_CTX *ctx, int (*cb)(),char *arg);
+int callback(char *arg,SSL *s,X509 *xs,STACK *cert_chain);
+This call is used to replace the SSLeay certificate verification code.
+The 'arg' is kept in the SSL_CTX and is passed to the callback.
+If the callback returns 0, the certificate is rejected, otherwise it
+is accepted.  The callback is replacing the X509_cert_verify() call.
+This feature is not often used, but if you wished to implement
+some totally different certificate authentication system, this 'hook' is
+vital.
+
+SSLeay keeps a cache of session-ids against each SSL_CTX.  These callbacks can
+be used to notify the application when a SSL_SESSION is added to the cache
+or to retrieve a SSL_SESSION that is not in the cache from the application.
+#define SSL_CTX_sess_set_get_cb(ctx,cb)
+SSL_SESSION *callback(SSL *s,char *session_id,int session_id_len,int *copy);
+If defined, this callback is called to return the SESSION_ID for the
+session-id in 'session_id', of 'session_id_len' bytes.  'copy' is set to 1
+if the server is to 'take a copy' of the SSL_SESSION structure.  It is 0
+if the SSL_SESSION is being 'passed in' so the SSLeay library is now
+responsible for 'free()ing' the structure.  Basically it is used to indicate
+if the reference count on the SSL_SESSION structure needs to be incremented.
+
+#define SSL_CTX_sess_set_new_cb(ctx,cb)
+int callback(SSL *s, SSL_SESSION *sess);
+When a new connection is established, if the SSL_SESSION is going to be added
+to the cache, this callback is called.  Return 1 if a 'copy' is required,
+otherwise, return 0.  This return value just causes the reference count
+to be incremented (on return of a 1), this means the application does
+not need to worry about incrementing the refernece count (and the
+locking that implies in a multi-threaded application).
+
+void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx,int (*cb)());
+This sets the SSL password reading function.
+It is mostly used for windowing applications
+and used by PEM_read_bio_X509() and PEM_read_bio_RSAPrivateKey()
+calls inside the SSL library.   The only reason this is present is because the
+calls to PEM_* functions is hidden in the SSLeay library so you have to
+pass in the callback some how.
+
+#define SSL_CTX_set_client_cert_cb(ctx,cb)
+int callback(SSL *s,X509 **x509, EVP_PKEY **pkey);
+Called when a client certificate is requested but there is not one set
+against the SSL_CTX or the SSL.  If the callback returns 1, x509 and
+pkey need to point to valid data.  The library will free these when
+required so if the application wants to keep these around, increment
+their reference counts.  If 0 is returned, no client cert is
+available.  If -1 is returned, it is assumed that the callback needs
+to be called again at a later point in time.  SSL_connect will return
+-1 and SSL_want_x509_lookup(ssl) returns true.  Remember that
+application data can be attached to an SSL structure via the
+SSL_set_app_data(SSL *ssl,char *data) call.
+
+--------------------------
+The X509 library.
+
+int X509_cert_verify(CERTIFICATE_CTX *ctx,X509 *xs, int (*cb)(),
+	int *error,char *arg,STACK *cert_chain);
+int verify_callback(int ok,X509 *xs,X509 *xi,int depth,int error,char *arg,
+	STACK *cert_chain);
+
+X509_cert_verify() is used to authenticate X509 certificates.  The 'ctx' holds
+the details of the various caches and files used to locate certificates.
+'xs' is the certificate to verify and 'cb' is the application callback (more
+detail later).  'error' will be set to the error code and 'arg' is passed
+to the 'cb' callback.  Look at the VERIFY_* defines in crypto/x509/x509.h
+
+When ever X509_cert_verify() makes a 'negative' decision about a
+certitificate, the callback is called.  If everything checks out, the
+callback is called with 'VERIFY_OK' or 'VERIFY_ROOT_OK' (for a self
+signed cert that is not the passed certificate).
+
+The callback is passed the X509_cert_verify opinion of the certificate 
+in 'ok', the certificate in 'xs', the issuer certificate in 'xi',
+the 'depth' of the certificate in the verification 'chain', the
+VERIFY_* code in 'error' and the argument passed to X509_cert_verify()
+in 'arg'. cert_chain is a list of extra certs to use if they are not
+in the cache.
+
+The callback can be used to look at the error reason, and then return 0
+for an 'error' or '1' for ok.  This will override the X509_cert_verify()
+opinion of the certificates validity.  Processing will continue depending on
+the return value.  If one just wishes to use the callback for informational
+reason, just return the 'ok' parameter.
+
+--------------------------
+The BN and DH library.
+
+BIGNUM *BN_generate_prime(int bits,int strong,BIGNUM *add,
+	BIGNUM *rem,void (*callback)(int,int));
+int BN_is_prime(BIGNUM *p,int nchecks,void (*callback)(int,int),
+
+Read doc/bn.doc for the description of these 2.
+
+DH *DH_generate_parameters(int prime_len,int generator,
+	void (*callback)(int,int));
+Read doc/bn.doc for the description of the callback, since it is just passed
+to BN_generate_prime(), except that it is also called as
+callback(3,0) by this function.
+
+--------------------------
+The CRYPTO library.
+
+void CRYPTO_set_locking_callback(void (*func)(int mode,int type,char *file,
+	int line));
+void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,
+	int type,char *file, int line));
+void CRYPTO_set_id_callback(unsigned long (*func)(void));
+
+Read threads.doc for info on these ones.
+
+
+==== cipher.doc ========================================================
+
+The Cipher subroutines.
+
+These routines require "evp.h" to be included.
+
+These functions are a higher level interface to the various cipher
+routines found in this library.  As such, they allow the same code to be
+used to encrypt and decrypt via different ciphers with only a change
+in an initial parameter.  These routines also provide buffering for block
+ciphers.
+
+These routines all take a pointer to the following structure to specify
+which cipher to use.  If you wish to use a new cipher with these routines,
+you would probably be best off looking an how an existing cipher is
+implemented and copying it.  At this point in time, I'm not going to go
+into many details.  This structure should be considered opaque
+
+typedef struct pem_cipher_st
+	{
+	int type;
+	int block_size;
+	int key_len;
+	int iv_len;
+	void (*enc_init)();	/* init for encryption */
+	void (*dec_init)();	/* init for decryption */
+	void (*do_cipher)();	/* encrypt data */
+	} EVP_CIPHER;
+	
+The type field is the object NID of the cipher type
+(read the section on Objects for an explanation of what a NID is).
+The cipher block_size is how many bytes need to be passed
+to the cipher at a time.  Key_len is the
+length of the key the cipher requires and iv_len is the length of the
+initialisation vector required.  enc_init is the function
+called to initialise the ciphers context for encryption and dec_init is the
+function to initialise for decryption (they need to be different, especially
+for the IDEA cipher).
+
+One reason for specifying the Cipher via a pointer to a structure
+is that if you only use des-cbc, only the des-cbc routines will
+be included when you link the program.  If you passed an integer
+that specified which cipher to use, the routine that mapped that
+integer to a set of cipher functions would cause all the ciphers
+to be link into the code.  This setup also allows new ciphers
+to be added by the application (with some restrictions).
+
+The thirteen ciphers currently defined in this library are
+
+EVP_CIPHER *EVP_des_ecb();     /* DES in ecb mode,     iv=0, block=8, key= 8 */
+EVP_CIPHER *EVP_des_ede();     /* DES in ecb ede mode, iv=0, block=8, key=16 */
+EVP_CIPHER *EVP_des_ede3();    /* DES in ecb ede mode, iv=0, block=8, key=24 */
+EVP_CIPHER *EVP_des_cfb();     /* DES in cfb mode,     iv=8, block=1, key= 8 */
+EVP_CIPHER *EVP_des_ede_cfb(); /* DES in ede cfb mode, iv=8, block=1, key=16 */
+EVP_CIPHER *EVP_des_ede3_cfb();/* DES in ede cfb mode, iv=8, block=1, key=24 */
+EVP_CIPHER *EVP_des_ofb();     /* DES in ofb mode,     iv=8, block=1, key= 8 */
+EVP_CIPHER *EVP_des_ede_ofb(); /* DES in ede ofb mode, iv=8, block=1, key=16 */
+EVP_CIPHER *EVP_des_ede3_ofb();/* DES in ede ofb mode, iv=8, block=1, key=24 */
+EVP_CIPHER *EVP_des_cbc();     /* DES in cbc mode,     iv=8, block=8, key= 8 */
+EVP_CIPHER *EVP_des_ede_cbc(); /* DES in cbc ede mode, iv=8, block=8, key=16 */
+EVP_CIPHER *EVP_des_ede3_cbc();/* DES in cbc ede mode, iv=8, block=8, key=24 */
+EVP_CIPHER *EVP_desx_cbc();    /* DES in desx cbc mode,iv=8, block=8, key=24 */
+EVP_CIPHER *EVP_rc4();         /* RC4,                 iv=0, block=1, key=16 */
+EVP_CIPHER *EVP_idea_ecb();    /* IDEA in ecb mode,    iv=0, block=8, key=16 */
+EVP_CIPHER *EVP_idea_cfb();    /* IDEA in cfb mode,    iv=8, block=1, key=16 */
+EVP_CIPHER *EVP_idea_ofb();    /* IDEA in ofb mode,    iv=8, block=1, key=16 */
+EVP_CIPHER *EVP_idea_cbc();    /* IDEA in cbc mode,    iv=8, block=8, key=16 */
+EVP_CIPHER *EVP_rc2_ecb();     /* RC2 in ecb mode,     iv=0, block=8, key=16 */
+EVP_CIPHER *EVP_rc2_cfb();     /* RC2 in cfb mode,     iv=8, block=1, key=16 */
+EVP_CIPHER *EVP_rc2_ofb();     /* RC2 in ofb mode,     iv=8, block=1, key=16 */
+EVP_CIPHER *EVP_rc2_cbc();     /* RC2 in cbc mode,     iv=8, block=8, key=16 */
+EVP_CIPHER *EVP_bf_ecb();      /* Blowfish in ecb mode,iv=0, block=8, key=16 */
+EVP_CIPHER *EVP_bf_cfb();      /* Blowfish in cfb mode,iv=8, block=1, key=16 */
+EVP_CIPHER *EVP_bf_ofb();      /* Blowfish in ofb mode,iv=8, block=1, key=16 */
+EVP_CIPHER *EVP_bf_cbc();      /* Blowfish in cbc mode,iv=8, block=8, key=16 */
+
+The meaning of the compound names is as follows.
+des	The base cipher is DES.
+idea	The base cipher is IDEA
+rc4	The base cipher is RC4-128
+rc2	The base cipher is RC2-128
+ecb	Electronic Code Book form of the cipher.
+cbc	Cipher Block Chaining form of the cipher.
+cfb	64 bit Cipher Feedback form of the cipher.
+ofb	64 bit Output Feedback form of the cipher.
+ede	The cipher is used in Encrypt, Decrypt, Encrypt mode.  The first
+	and last keys are the same.
+ede3	The cipher is used in Encrypt, Decrypt, Encrypt mode.
+
+All the Cipher routines take a EVP_CIPHER_CTX pointer as an argument.
+The state of the cipher is kept in this structure.
+
+typedef struct EVP_CIPHER_Ctx_st
+	{
+	EVP_CIPHER *cipher;
+	int encrypt;		/* encrypt or decrypt */
+	int buf_len;		/* number we have left */
+	unsigned char buf[8];
+	union	{
+		.... /* cipher specific stuff */
+		} c;
+	} EVP_CIPHER_CTX;
+
+Cipher is a pointer the the EVP_CIPHER for the current context.  The encrypt
+flag indicates encryption or decryption.  buf_len is the number of bytes
+currently being held in buf.
+The 'c' union holds the cipher specify context.
+
+The following functions are to be used.
+
+int EVP_read_pw_string(
+char *buf,
+int len,
+char *prompt,
+int verify,
+	This function is the same as des_read_pw_string() (des.doc).
+
+void EVP_set_pw_prompt(char *prompt);
+	This function sets the 'default' prompt to use to use in
+	EVP_read_pw_string when the prompt parameter is NULL.  If the
+	prompt parameter is NULL, this 'default prompt' feature is turned
+	off.  Be warned, this is a global variable so weird things
+	will happen if it is used under Win16 and care must be taken
+	with a multi-threaded version of the library.
+
+char *EVP_get_pw_prompt();
+	This returns a pointer to the default prompt string.  NULL
+	if it is not set.
+
+int EVP_BytesToKey(
+EVP_CIPHER *type,
+EVP_MD *md,
+unsigned char *salt,
+unsigned char *data,
+int datal,
+int count,
+unsigned char *key,
+unsigned char *iv);
+	This function is used to generate a key and an initialisation vector
+	for a specified cipher from a key string and a salt.  Type
+	specifies the cipher the 'key' is being generated for.  Md is the
+	message digest algorithm to use to generate the key and iv.  The salt
+	is an optional 8 byte object that is used to help seed the key
+	generator.
+	If the salt value is NULL, it is just not used.  Datal is the
+	number of bytes to use from 'data' in the key generation.  
+	This function returns the key size for the specified cipher, if
+	data is NULL, this value is returns and no other
+	computation is performed.  Count is
+	the number of times to loop around the key generator.  I would
+	suggest leaving it's value as 1.  Key and iv are the structures to
+	place the returning iv and key in.  If they are NULL, no value is
+	generated for that particular value.
+	The algorithm used is as follows
+	
+	/* M[] is an array of message digests
+	 * MD() is the message digest function */
+	M[0]=MD(data . salt);
+	for (i=1; i<count; i++) M[0]=MD(M[0]);
+
+	i=1
+	while (data still needed for key and iv)
+		{
+		M[i]=MD(M[i-1] . data . salt);
+		for (i=1; i<count; i++) M[i]=MD(M[i]);
+		i++;
+		}
+
+	If the salt is NULL, it is not used.
+	The digests are concatenated together.
+	M = M[0] . M[1] . M[2] .......
+
+	For key= 8, iv=8 => key=M[0.. 8], iv=M[ 9 .. 16].
+	For key=16, iv=0 => key=M[0..16].
+	For key=16, iv=8 => key=M[0..16], iv=M[17 .. 24].
+	For key=24, iv=8 => key=M[0..24], iv=M[25 .. 32].
+
+	This routine will produce DES-CBC keys and iv that are compatible
+	with the PKCS-5 standard when md2 or md5 are used.  If md5 is
+	used, the salt is NULL and count is 1, this routine will produce
+	the password to key mapping normally used with RC4.
+	I have attempted to logically extend the PKCS-5 standard to
+	generate keys and iv for ciphers that require more than 16 bytes,
+	if anyone knows what the correct standard is, please inform me.
+	When using sha or sha1, things are a bit different under this scheme,
+	since sha produces a 20 byte digest.  So for ciphers requiring
+	24 bits of data, 20 will come from the first MD and 4 will
+	come from the second.
+
+	I have considered having a separate function so this 'routine'
+	can be used without the requirement of passing a EVP_CIPHER *,
+	but I have decided to not bother.  If you wish to use the
+	function without official EVP_CIPHER structures, just declare
+	a local one and set the key_len and iv_len fields to the
+	length you desire.
+
+The following routines perform encryption and decryption 'by parts'.  By
+this I mean that there are groups of 3 routines.  An Init function that is
+used to specify a cipher and initialise data structures.  An Update routine
+that does encryption/decryption, one 'chunk' at a time.  And finally a
+'Final' function that finishes the encryption/decryption process.
+All these functions take a EVP_CIPHER pointer to specify which cipher to
+encrypt/decrypt with.  They also take a EVP_CIPHER_CTX object as an
+argument.  This structure is used to hold the state information associated
+with the operation in progress.
+
+void EVP_EncryptInit(
+EVP_CIPHER_CTX *ctx,
+EVP_CIPHER *type,
+unsigned char *key,
+unsigned char *iv);
+	This function initialise a EVP_CIPHER_CTX for encryption using the
+	cipher passed in the 'type' field.  The cipher is initialised to use
+	'key' as the key and 'iv' for the initialisation vector (if one is
+	required).  If the type, key or iv is NULL, the value currently in the
+	EVP_CIPHER_CTX is reused.  So to perform several decrypt
+	using the same cipher, key and iv, initialise with the cipher,
+	key and iv the first time and then for subsequent calls,
+	reuse 'ctx' but pass NULL for type, key and iv.  You must make sure
+	to pass a key that is large enough for a particular cipher.  I
+	would suggest using the EVP_BytesToKey() function.
+
+void EVP_EncryptUpdate(
+EVP_CIPHER_CTX *ctx,
+unsigned char *out,
+int *outl,
+unsigned char *in,
+int inl);
+	This function takes 'inl' bytes from 'in' and outputs bytes
+	encrypted by the cipher 'ctx' was initialised with into 'out'.  The
+	number of bytes written to 'out' is put into outl.  If a particular
+	cipher encrypts in blocks, less or more bytes than input may be
+	output.  Currently the largest block size used by supported ciphers
+	is 8 bytes, so 'out' should have room for 'inl+7' bytes.  Normally
+	EVP_EncryptInit() is called once, followed by lots and lots of
+	calls to EVP_EncryptUpdate, followed by a single EVP_EncryptFinal
+	call.
+
+void EVP_EncryptFinal(
+EVP_CIPHER_CTX *ctx,
+unsigned char *out,
+int *outl);
+	Because quite a large number of ciphers are block ciphers, there is
+	often an incomplete block to write out at the end of the
+	encryption.  EVP_EncryptFinal() performs processing on this last
+	block.  The last block in encoded in such a way that it is possible
+	to determine how many bytes in the last block are valid.  For 8 byte
+	block size ciphers, if only 5 bytes in the last block are valid, the
+	last three bytes will be filled with the value 3.  If only 2 were
+	valid, the other 6 would be filled with sixes.  If all 8 bytes are
+	valid, a extra 8 bytes are appended to the cipher stream containing
+	nothing but 8 eights.  These last bytes are output into 'out' and
+	the number of bytes written is put into 'outl'  These last bytes
+	are output into 'out' and the number of bytes written is put into
+	'outl'.  This form of block cipher finalisation is compatible with
+	PKCS-5.  Please remember that even if you are using ciphers like
+	RC4 that has no blocking and so the function will not write
+	anything into 'out', it would still be a good idea to pass a
+	variable for 'out' that can hold 8 bytes just in case the cipher is
+	changed some time in the future.  It should also be remembered
+	that the EVP_CIPHER_CTX contains the password and so when one has
+	finished encryption with a particular EVP_CIPHER_CTX, it is good
+	practice to zero the structure 
+	(ie. memset(ctx,0,sizeof(EVP_CIPHER_CTX)).
+	
+void EVP_DecryptInit(
+EVP_CIPHER_CTX *ctx,
+EVP_CIPHER *type,
+unsigned char *key,
+unsigned char *iv);
+	This function is basically the same as EVP_EncryptInit() accept that
+	is prepares the EVP_CIPHER_CTX for decryption.
+
+void EVP_DecryptUpdate(
+EVP_CIPHER_CTX *ctx,
+unsigned char *out,
+int *outl,
+unsigned char *in,
+int inl);
+	This function is basically the same as EVP_EncryptUpdate()
+	except that it performs decryption.  There is one
+	fundamental difference though.  'out' can not be the same as
+	'in' for any ciphers with a block size greater than 1 if more
+	than one call to EVP_DecryptUpdate() will be made.  This
+	is because this routine can hold a 'partial' block between
+	calls.  When a partial block is decrypted (due to more bytes
+	being passed via this function, they will be written to 'out'
+	overwriting the input bytes in 'in' that have not been read
+	yet.  From this it should also be noted that 'out' should
+	be at least one 'block size' larger than 'inl'.  This problem
+	only occurs on the second and subsequent call to
+	EVP_DecryptUpdate() when using a block cipher.
+
+int EVP_DecryptFinal(
+EVP_CIPHER_CTX *ctx,
+unsigned char *out,
+int *outl);
+	This function is different to EVP_EncryptFinal in that it 'removes'
+	any padding bytes appended when the data was encrypted.  Due to the
+	way in which 1 to 8 bytes may have been appended when encryption
+	using a block cipher, 'out' can end up with 0 to 7 bytes being put
+	into it.  When decoding the padding bytes, it is possible to detect
+	an incorrect decryption.  If the decryption appears to be wrong, 0
+	is returned.  If everything seems ok, 1 is returned.  For ciphers
+	with a block size of 1 (RC4), this function would normally not
+	return any bytes and would always return 1.  Just because this
+	function returns 1 does not mean the decryption was correct. It
+	would normally be wrong due to either the wrong key/iv or
+	corruption of the cipher data fed to EVP_DecryptUpdate().
+	As for EVP_EncryptFinal, it is a good idea to zero the
+	EVP_CIPHER_CTX after use since the structure contains the key used
+	to decrypt the data.
+	
+The following Cipher routines are convenience routines that call either
+EVP_EncryptXxx or EVP_DecryptXxx depending on weather the EVP_CIPHER_CTX
+was setup to encrypt or decrypt.  
+
+void EVP_CipherInit(
+EVP_CIPHER_CTX *ctx,
+EVP_CIPHER *type,
+unsigned char *key,
+unsigned char *iv,
+int enc);
+	This function take arguments that are the same as EVP_EncryptInit()
+	and EVP_DecryptInit() except for the extra 'enc' flag.  If 1, the
+	EVP_CIPHER_CTX is setup for encryption, if 0, decryption.
+
+void EVP_CipherUpdate(
+EVP_CIPHER_CTX *ctx,
+unsigned char *out,
+int *outl,
+unsigned char *in,
+int inl);
+	Again this function calls either EVP_EncryptUpdate() or
+	EVP_DecryptUpdate() depending on state in the 'ctx' structure.
+	As noted for EVP_DecryptUpdate(), when this routine is used
+	for decryption with block ciphers, 'out' should not be the
+	same as 'in'.
+
+int EVP_CipherFinal(
+EVP_CIPHER_CTX *ctx,
+unsigned char *outm,
+int *outl);
+	This routine call EVP_EncryptFinal() or EVP_DecryptFinal()
+	depending on the state information in 'ctx'.  1 is always returned
+	if the mode is encryption, otherwise the return value is the return
+	value of EVP_DecryptFinal().
+
+==== cipher.m ========================================================
+
+Date: Tue, 15 Oct 1996 08:16:14 +1000 (EST)
+From: Eric Young <eay@mincom.com>
+X-Sender: eay@orb
+To: Roland Haring <rharing@tandem.cl>
+Cc: ssl-users@mincom.com
+Subject: Re: Symmetric encryption with ssleay
+In-Reply-To: <m0vBpyq-00001aC@tandemnet.tandem.cl>
+Message-Id: <Pine.SOL.3.91.961015075623.11394A-100000@orb>
+Mime-Version: 1.0
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+Sender: ssl-lists-owner@mincom.com
+Precedence: bulk
+Status: RO
+X-Status: 
+
+On Fri, 11 Oct 1996, Roland Haring wrote:
+> THE_POINT:
+> 	Would somebody be so kind to give me the minimum basic 
+> 	calls I need to do to libcrypto.a to get some text encrypted
+> 	and decrypted again? ...hopefully with code included to do
+> 	base64 encryption and decryption ... e.g. that sign-it.c code
+> 	posted some while ago was a big help :-) (please, do not point
+> 	me to apps/enc.c where I suspect my Heissenbug to be hidden :-)
+
+Ok, the base64 encoding stuff in 'enc.c' does the wrong thing sometimes 
+when the data is less than a line long (this is for decoding).  I'll dig 
+up the exact fix today and post it.  I am taking longer on 0.6.5 than I 
+intended so I'll just post this patch.
+
+The documentation to read is in
+doc/cipher.doc,
+doc/encode.doc (very sparse :-).
+and perhaps
+doc/digest.doc,
+
+The basic calls to encrypt with say triple DES are
+
+Given
+char key[EVP_MAX_KEY_LENGTH];
+char iv[EVP_MAX_IV_LENGTH];
+EVP_CIPHER_CTX ctx;
+unsigned char out[512+8];
+int outl;
+
+/* optional generation of key/iv data from text password using md5
+ * via an upward compatable verson of PKCS#5. */
+EVP_BytesToKey(EVP_des_ede3_cbc,EVP_md5,NULL,passwd,strlen(passwd),
+	key,iv);
+
+/* Initalise the EVP_CIPHER_CTX */
+EVP_EncryptInit(ctx,EVP_des_ede3_cbc,key,iv);
+
+while (....)
+	{
+	/* This is processing 512 bytes at a time, the bytes are being
+	 * copied into 'out', outl bytes are output.  'out' should not be the
+	 * same as 'in' for reasons mentioned in the documentation. */
+	EVP_EncryptUpdate(ctx,out,&outl,in,512);
+	}
+
+/* Output the last 'block'.  If the cipher is a block cipher, the last
+ * block is encoded in such a way so that a wrong decryption will normally be
+ * detected - again, one of the PKCS standards. */
+
+EVP_EncryptFinal(ctx,out,&outl);
+
+To decrypt, use the EVP_DecryptXXXXX functions except that EVP_DecryptFinal()
+will return 0 if the decryption fails (only detectable on block ciphers).
+
+You can also use
+EVP_CipherInit()
+EVP_CipherUpdate()
+EVP_CipherFinal()
+which does either encryption or decryption depending on an extra 
+parameter to EVP_CipherInit().
+
+
+To do the base64 encoding,
+EVP_EncodeInit()
+EVP_EncodeUpdate()
+EVP_EncodeFinal()
+
+EVP_DecodeInit()
+EVP_DecodeUpdate()
+EVP_DecodeFinal()
+
+where the encoding is quite simple, but the decoding can be a bit more 
+fun (due to dud input).
+
+EVP_DecodeUpdate() returns -1 for an error on an input line, 0 if the 
+'last line' was just processed, and 1 if more lines should be submitted.
+
+EVP_DecodeFinal() returns -1 for an error or 1 if things are ok.
+
+So the loop becomes
+EVP_DecodeInit(....)
+for (;;)
+	{
+	i=EVP_DecodeUpdate(....);
+	if (i < 0) goto err;
+
+	/* process the data */
+
+	if (i == 0) break;
+	}
+EVP_DecodeFinal(....);
+/* process the data */
+
+The problem in 'enc.c' is that I was stuff the processing up after the 
+EVP_DecodeFinal(...) when the for(..) loop was not being run (one line of 
+base64 data) and this was because 'enc.c' tries to scan over a file until
+it hits the first valid base64 encoded line.
+
+hope this helps a bit.
+eric
+--
+Eric Young                  | BOOL is tri-state according to Bill Gates.
+AARNet: eay@mincom.oz.au    | RTFM Win32 GetMessage().
+
+==== conf.doc ========================================================
+
+The CONF library.
+
+The CONF library is a simple set of routines that can be used to configure
+programs.  It is a superset of the genenv() function with some extra
+structure.
+
+The library consists of 5 functions.
+
+LHASH *CONF_load(LHASH *config,char *file);
+This function is called to load in a configuration file.  Multiple
+configuration files can be loaded, with each subsequent 'load' overwriting
+any already defined 'variables'.  If there is an error, NULL is returned.
+If config is NULL, a new LHASH structure is created and returned, otherwise
+the new data in the 'file' is loaded into the 'config' structure.
+
+void CONF_free(LHASH *config);
+This function free()s the data in config.
+
+char *CONF_get_string(LHASH *config,char *section,char *name);
+This function returns the string found in 'config' that corresponds to the
+'section' and 'name' specified.  Classes and the naming system used will be
+discussed later in this document.  If the variable is not defined, an NULL
+is returned.
+
+long CONF_get_long(LHASH *config,char *section, char *name);
+This function is the same as CONF_get_string() except that it converts the
+string to an long and returns it.  If variable is not a number or the
+variable does not exist, 0 is returned.  This is a little problematic but I
+don't know of a simple way around it.
+
+STACK *CONF_get_section(LHASH *config, char *section);
+This function returns a 'stack' of CONF_VALUE items that are all the
+items defined in a particular section.  DO NOT free() any of the
+variable returned.  They will disappear when CONF_free() is called.
+
+The 'lookup' model.
+The configuration file is divided into 'sections'.  Each section is started by
+a line of the form '[ section ]'.  All subsequent variable definitions are
+of this section.  A variable definition is a simple alpha-numeric name
+followed by an '=' and then the data.  A section or variable name can be
+described by a regular expression of the following form '[A-Za-z0-9_]+'.
+The value of the variable is the text after the '=' until the end of the
+line, stripped of leading and trailing white space.
+At this point I should mention that a '#' is a comment character, \ is the
+escape character, and all three types of quote can be used to stop any
+special interpretation of the data.
+Now when the data is being loaded, variable expansion can occur.  This is
+done by expanding any $NAME sequences into the value represented by the
+variable NAME.  If the variable is not in the current section, the different
+section can be specified by using the $SECTION::NAME form.  The ${NAME} form
+also works and is very useful for expanding variables inside strings.
+
+When a variable is looked up, there are 2 special section. 'default', which
+is the initial section, and 'ENV' which is the processes environment
+variables (accessed via getenv()).  When a variable is looked up, it is
+first 'matched' with it's section (if one was specified), if this fails, the
+'default' section is matched.
+If the 'lhash' variable passed was NULL, the environment is searched.
+
+Now why do we bother with sections?  So we can have multiple programs using
+the same configuration file, or multiple instances of the same program
+using different variables.  It also provides a nice mechanism to override
+the processes environment variables (eg ENV::HOME=/tmp).  If there is a
+program specific variable missing, we can have default values.
+Multiple configuration files can be loaded, with each new value clearing
+any predefined values.  A system config file can provide 'default' values,
+and application/usr specific files can provide overriding values.
+
+Examples
+
+# This is a simple example
+SSLEAY_HOME	= /usr/local/ssl
+ENV::PATH	= $SSLEAY_HOME/bin:$PATH	# override my path
+
+[X509]
+cert_dir	= $SSLEAY_HOME/certs	# /usr/local/ssl/certs
+
+[SSL]
+CIPHER		= DES-EDE-MD5:RC4-MD5
+USER_CERT	= $HOME/${USER}di'r 5'	# /home/eay/eaydir 5
+USER_CERT	= $HOME/\${USER}di\'r	# /home/eay/${USER}di'r
+USER_CERT	= "$HOME/${US"ER}di\'r	# $HOME/${USER}di'r
+
+TEST		= 1234\
+5678\
+9ab					# TEST=123456789ab
+TTT		= 1234\n\n		# TTT=1234<nl><nl>
+
+
+
+==== des.doc ========================================================
+
+The DES library.
+
+Please note that this library was originally written to operate with
+eBones, a version of Kerberos that had had encryption removed when it left
+the USA and then put back in.  As such there are some routines that I will
+advise not using but they are still in the library for historical reasons.
+For all calls that have an 'input' and 'output' variables, they can be the
+same.
+
+This library requires the inclusion of 'des.h'.
+
+All of the encryption functions take what is called a des_key_schedule as an 
+argument.  A des_key_schedule is an expanded form of the des key.
+A des_key is 8 bytes of odd parity, the type used to hold the key is a
+des_cblock.  A des_cblock is an array of 8 bytes, often in this library
+description I will refer to input bytes when the function specifies
+des_cblock's as input or output, this just means that the variable should
+be a multiple of 8 bytes.
+
+The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to
+specify decryption.  The functions and global variable are as follows:
+
+int des_check_key;
+	DES keys are supposed to be odd parity.  If this variable is set to
+	a non-zero value, des_set_key() will check that the key has odd
+	parity and is not one of the known weak DES keys.  By default this
+	variable is turned off;
+	
+void des_set_odd_parity(
+des_cblock *key );
+	This function takes a DES key (8 bytes) and sets the parity to odd.
+	
+int des_is_weak_key(
+des_cblock *key );
+	This function returns a non-zero value if the DES key passed is a
+	weak, DES key.  If it is a weak key, don't use it, try a different
+	one.  If you are using 'random' keys, the chances of hitting a weak
+	key are 1/2^52 so it is probably not worth checking for them.
+	
+int des_set_key(
+des_cblock *key,
+des_key_schedule schedule);
+	Des_set_key converts an 8 byte DES key into a des_key_schedule.
+	A des_key_schedule is an expanded form of the key which is used to
+	perform actual encryption.  It can be regenerated from the DES key
+	so it only needs to be kept when encryption or decryption is about
+	to occur.  Don't save or pass around des_key_schedule's since they
+	are CPU architecture dependent, DES keys are not.  If des_check_key
+	is non zero, zero is returned if the key has the wrong parity or
+	the key is a weak key, else 1 is returned.
+	
+int des_key_sched(
+des_cblock *key,
+des_key_schedule schedule);
+	An alternative name for des_set_key().
+
+int des_rw_mode;		/* defaults to DES_PCBC_MODE */
+	This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default).
+	This specifies the function to use in the enc_read() and enc_write()
+	functions.
+
+void des_encrypt(
+unsigned long *data,
+des_key_schedule ks,
+int enc);
+	This is the DES encryption function that gets called by just about
+	every other DES routine in the library.  You should not use this
+	function except to implement 'modes' of DES.  I say this because the
+	functions that call this routine do the conversion from 'char *' to
+	long, and this needs to be done to make sure 'non-aligned' memory
+	access do not occur.  The characters are loaded 'little endian',
+	have a look at my source code for more details on how I use this
+	function.
+	Data is a pointer to 2 unsigned long's and ks is the
+	des_key_schedule to use.  enc, is non zero specifies encryption,
+	zero if decryption.
+
+void des_encrypt2(
+unsigned long *data,
+des_key_schedule ks,
+int enc);
+	This functions is the same as des_encrypt() except that the DES
+	initial permutation (IP) and final permutation (FP) have been left
+	out.  As for des_encrypt(), you should not use this function.
+	It is used by the routines in my library that implement triple DES.
+	IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same
+	as des_encrypt() des_encrypt() des_encrypt() except faster :-).
+
+void des_ecb_encrypt(
+des_cblock *input,
+des_cblock *output,
+des_key_schedule ks,
+int enc);
+	This is the basic Electronic Code Book form of DES, the most basic
+	form.  Input is encrypted into output using the key represented by
+	ks.  If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise
+	decryption occurs.  Input is 8 bytes long and output is 8 bytes.
+	(the des_cblock structure is 8 chars).
+	
+void des_ecb3_encrypt(
+des_cblock *input,
+des_cblock *output,
+des_key_schedule ks1,
+des_key_schedule ks2,
+des_key_schedule ks3,
+int enc);
+	This is the 3 key EDE mode of ECB DES.  What this means is that 
+	the 8 bytes of input is encrypted with ks1, decrypted with ks2 and
+	then encrypted again with ks3, before being put into output;
+	C=E(ks3,D(ks2,E(ks1,M))).  There is a macro, des_ecb2_encrypt()
+	that only takes 2 des_key_schedules that implements,
+	C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1.
+	
+void des_cbc_encrypt(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule ks,
+des_cblock *ivec,
+int enc);
+	This routine implements DES in Cipher Block Chaining mode.
+	Input, which should be a multiple of 8 bytes is encrypted
+	(or decrypted) to output which will also be a multiple of 8 bytes.
+	The number of bytes is in length (and from what I've said above,
+	should be a multiple of 8).  If length is not a multiple of 8, I'm
+	not being held responsible :-).  ivec is the initialisation vector.
+	This function does not modify this variable.  To correctly implement
+	cbc mode, you need to do one of 2 things; copy the last 8 bytes of
+	cipher text for use as the next ivec in your application,
+	or use des_ncbc_encrypt(). 
+	Only this routine has this problem with updating the ivec, all
+	other routines that are implementing cbc mode update ivec.
+	
+void des_ncbc_encrypt(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule sk,
+des_cblock *ivec,
+int enc);
+	For historical reasons, des_cbc_encrypt() did not update the
+	ivec with the value requires so that subsequent calls to
+	des_cbc_encrypt() would 'chain'.  This was needed so that the same
+	'length' values would not need to be used when decrypting.
+	des_ncbc_encrypt() does the right thing.  It is the same as
+	des_cbc_encrypt accept that ivec is updates with the correct value
+	to pass in subsequent calls to des_ncbc_encrypt().  I advise using
+	des_ncbc_encrypt() instead of des_cbc_encrypt();
+
+void des_xcbc_encrypt(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule sk,
+des_cblock *ivec,
+des_cblock *inw,
+des_cblock *outw,
+int enc);
+	This is RSA's DESX mode of DES.  It uses inw and outw to
+	'whiten' the encryption.  inw and outw are secret (unlike the iv)
+	and are as such, part of the key.  So the key is sort of 24 bytes.
+	This is much better than cbc des.
+	
+void des_3cbc_encrypt(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule sk1,
+des_key_schedule sk2,
+des_cblock *ivec1,
+des_cblock *ivec2,
+int enc);
+	This function is flawed, do not use it.  I have left it in the
+	library because it is used in my des(1) program and will function
+	correctly when used by des(1).  If I removed the function, people
+	could end up unable to decrypt files.
+	This routine implements outer triple cbc encryption using 2 ks and
+	2 ivec's.  Use des_ede2_cbc_encrypt() instead.
+	
+void des_ede3_cbc_encrypt(
+des_cblock *input,
+des_cblock *output, 
+long length,
+des_key_schedule ks1,
+des_key_schedule ks2, 
+des_key_schedule ks3, 
+des_cblock *ivec,
+int enc);
+	This function implements outer triple CBC DES encryption with 3
+	keys.  What this means is that each 'DES' operation
+	inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))).
+	Again, this is cbc mode so an ivec is requires.
+	This mode is used by SSL.
+	There is also a des_ede2_cbc_encrypt() that only uses 2
+	des_key_schedule's, the first being reused for the final
+	encryption.  C=E(ks1,D(ks2,E(ks1,M))).  This form of triple DES
+	is used by the RSAref library.
+	
+void des_pcbc_encrypt(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule ks,
+des_cblock *ivec,
+int enc);
+	This is Propagating Cipher Block Chaining mode of DES.  It is used
+	by Kerberos v4.  It's parameters are the same as des_ncbc_encrypt().
+	
+void des_cfb_encrypt(
+unsigned char *in,
+unsigned char *out,
+int numbits,
+long length,
+des_key_schedule ks,
+des_cblock *ivec,
+int enc);
+	Cipher Feedback Back mode of DES.  This implementation 'feeds back'
+	in numbit blocks.  The input (and output) is in multiples of numbits
+	bits.  numbits should to be a multiple of 8 bits.  Length is the
+	number of bytes input.  If numbits is not a multiple of 8 bits,
+	the extra bits in the bytes will be considered padding.  So if
+	numbits is 12, for each 2 input bytes, the 4 high bits of the
+	second byte will be ignored.  So to encode 72 bits when using
+	a numbits of 12 take 12 bytes.  To encode 72 bits when using
+	numbits of 9 will take 16 bytes.  To encode 80 bits when using
+	numbits of 16 will take 10 bytes. etc, etc.  This padding will
+	apply to both input and output.
+
+	
+void des_cfb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+des_key_schedule ks,
+des_cblock *ivec,
+int *num,
+int enc);
+	This is one of the more useful functions in this DES library, it
+	implements CFB mode of DES with 64bit feedback.  Why is this
+	useful you ask?  Because this routine will allow you to encrypt an
+	arbitrary number of bytes, no 8 byte padding.  Each call to this
+	routine will encrypt the input bytes to output and then update ivec
+	and num.  num contains 'how far' we are though ivec.  If this does
+	not make much sense, read more about cfb mode of DES :-).
+	
+void des_ede3_cfb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+des_key_schedule ks1,
+des_key_schedule ks2,
+des_key_schedule ks3,
+des_cblock *ivec,
+int *num,
+int enc);
+	Same as des_cfb64_encrypt() accept that the DES operation is
+	triple DES.  As usual, there is a macro for
+	des_ede2_cfb64_encrypt() which reuses ks1.
+
+void des_ofb_encrypt(
+unsigned char *in,
+unsigned char *out,
+int numbits,
+long length,
+des_key_schedule ks,
+des_cblock *ivec);
+	This is a implementation of Output Feed Back mode of DES.  It is
+	the same as des_cfb_encrypt() in that numbits is the size of the
+	units dealt with during input and output (in bits).
+	
+void des_ofb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+des_key_schedule ks,
+des_cblock *ivec,
+int *num);
+	The same as des_cfb64_encrypt() except that it is Output Feed Back
+	mode.
+
+void des_ede3_ofb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+des_key_schedule ks1,
+des_key_schedule ks2,
+des_key_schedule ks3,
+des_cblock *ivec,
+int *num);
+	Same as des_ofb64_encrypt() accept that the DES operation is
+	triple DES.  As usual, there is a macro for
+	des_ede2_ofb64_encrypt() which reuses ks1.
+
+int des_read_pw_string(
+char *buf,
+int length,
+char *prompt,
+int verify);
+	This routine is used to get a password from the terminal with echo
+	turned off.  Buf is where the string will end up and length is the
+	size of buf.  Prompt is a string presented to the 'user' and if
+	verify is set, the key is asked for twice and unless the 2 copies
+	match, an error is returned.  A return code of -1 indicates a
+	system error, 1 failure due to use interaction, and 0 is success.
+
+unsigned long des_cbc_cksum(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule ks,
+des_cblock *ivec);
+	This function produces an 8 byte checksum from input that it puts in
+	output and returns the last 4 bytes as a long.  The checksum is
+	generated via cbc mode of DES in which only the last 8 byes are
+	kept.  I would recommend not using this function but instead using
+	the EVP_Digest routines, or at least using MD5 or SHA.  This
+	function is used by Kerberos v4 so that is why it stays in the
+	library.
+	
+char *des_fcrypt(
+const char *buf,
+const char *salt
+char *ret);
+	This is my fast version of the unix crypt(3) function.  This version
+	takes only a small amount of space relative to other fast
+	crypt() implementations.  This is different to the normal crypt
+	in that the third parameter is the buffer that the return value
+	is written into.  It needs to be at least 14 bytes long.  This
+	function is thread safe, unlike the normal crypt.
+
+char *crypt(
+const char *buf,
+const char *salt);
+	This function calls des_fcrypt() with a static array passed as the
+	third parameter.  This emulates the normal non-thread safe semantics
+	of crypt(3).
+
+void des_string_to_key(
+char *str,
+des_cblock *key);
+	This function takes str and converts it into a DES key.  I would
+	recommend using MD5 instead and use the first 8 bytes of output.
+	When I wrote the first version of these routines back in 1990, MD5
+	did not exist but I feel these routines are still sound.  This
+	routines is compatible with the one in MIT's libdes.
+	
+void des_string_to_2keys(
+char *str,
+des_cblock *key1,
+des_cblock *key2);
+	This function takes str and converts it into 2 DES keys.
+	I would recommend using MD5 and using the 16 bytes as the 2 keys.
+	I have nothing against these 2 'string_to_key' routines, it's just
+	that if you say that your encryption key is generated by using the
+	16 bytes of an MD5 hash, every-one knows how you generated your
+	keys.
+
+int des_read_password(
+des_cblock *key,
+char *prompt,
+int verify);
+	This routine combines des_read_pw_string() with des_string_to_key().
+
+int des_read_2passwords(
+des_cblock *key1,
+des_cblock *key2,
+char *prompt,
+int verify);
+	This routine combines des_read_pw_string() with des_string_to_2key().
+
+void des_random_seed(
+des_cblock key);
+	This routine sets a starting point for des_random_key().
+	
+void des_random_key(
+des_cblock ret);
+	This function return a random key.  Make sure to 'seed' the random
+	number generator (with des_random_seed()) before using this function.
+	I personally now use a MD5 based random number system.
+
+int des_enc_read(
+int fd,
+char *buf,
+int len,
+des_key_schedule ks,
+des_cblock *iv);
+	This function will write to a file descriptor the encrypted data
+	from buf.  This data will be preceded by a 4 byte 'byte count' and
+	will be padded out to 8 bytes.  The encryption is either CBC of
+	PCBC depending on the value of des_rw_mode.  If it is DES_PCBC_MODE,
+	pcbc is used, if DES_CBC_MODE, cbc is used.  The default is to use
+	DES_PCBC_MODE.
+
+int des_enc_write(
+int fd,
+char *buf,
+int len,
+des_key_schedule ks,
+des_cblock *iv);
+	This routines read stuff written by des_enc_read() and decrypts it.
+	I have used these routines quite a lot but I don't believe they are
+	suitable for non-blocking io.  If you are after a full
+	authentication/encryption over networks, have a look at SSL instead.
+
+unsigned long des_quad_cksum(
+des_cblock *input,
+des_cblock *output,
+long length,
+int out_count,
+des_cblock *seed);
+	This is a function from Kerberos v4 that is not anything to do with
+	DES but was needed.  It is a cksum that is quicker to generate than
+	des_cbc_cksum();  I personally would use MD5 routines now.
+=====
+Modes of DES
+Quite a bit of the following information has been taken from
+	AS 2805.5.2
+	Australian Standard
+	Electronic funds transfer - Requirements for interfaces,
+	Part 5.2: Modes of operation for an n-bit block cipher algorithm
+	Appendix A
+
+There are several different modes in which DES can be used, they are
+as follows.
+
+Electronic Codebook Mode (ECB) (des_ecb_encrypt())
+- 64 bits are enciphered at a time.
+- The order of the blocks can be rearranged without detection.
+- The same plaintext block always produces the same ciphertext block
+  (for the same key) making it vulnerable to a 'dictionary attack'.
+- An error will only affect one ciphertext block.
+
+Cipher Block Chaining Mode (CBC) (des_cbc_encrypt())
+- a multiple of 64 bits are enciphered at a time.
+- The CBC mode produces the same ciphertext whenever the same
+  plaintext is encrypted using the same key and starting variable.
+- The chaining operation makes the ciphertext blocks dependent on the
+  current and all preceding plaintext blocks and therefore blocks can not
+  be rearranged.
+- The use of different starting variables prevents the same plaintext
+  enciphering to the same ciphertext.
+- An error will affect the current and the following ciphertext blocks.
+
+Cipher Feedback Mode (CFB) (des_cfb_encrypt())
+- a number of bits (j) <= 64 are enciphered at a time.
+- The CFB mode produces the same ciphertext whenever the same
+  plaintext is encrypted using the same key and starting variable.
+- The chaining operation makes the ciphertext variables dependent on the
+  current and all preceding variables and therefore j-bit variables are
+  chained together and can not be rearranged.
+- The use of different starting variables prevents the same plaintext
+  enciphering to the same ciphertext.
+- The strength of the CFB mode depends on the size of k (maximal if
+  j == k).  In my implementation this is always the case.
+- Selection of a small value for j will require more cycles through
+  the encipherment algorithm per unit of plaintext and thus cause
+  greater processing overheads.
+- Only multiples of j bits can be enciphered.
+- An error will affect the current and the following ciphertext variables.
+
+Output Feedback Mode (OFB) (des_ofb_encrypt())
+- a number of bits (j) <= 64 are enciphered at a time.
+- The OFB mode produces the same ciphertext whenever the same
+  plaintext enciphered using the same key and starting variable.  More
+  over, in the OFB mode the same key stream is produced when the same
+  key and start variable are used.  Consequently, for security reasons
+  a specific start variable should be used only once for a given key.
+- The absence of chaining makes the OFB more vulnerable to specific attacks.
+- The use of different start variables values prevents the same
+  plaintext enciphering to the same ciphertext, by producing different
+  key streams.
+- Selection of a small value for j will require more cycles through
+  the encipherment algorithm per unit of plaintext and thus cause
+  greater processing overheads.
+- Only multiples of j bits can be enciphered.
+- OFB mode of operation does not extend ciphertext errors in the
+  resultant plaintext output.  Every bit error in the ciphertext causes
+  only one bit to be in error in the deciphered plaintext.
+- OFB mode is not self-synchronising.  If the two operation of
+  encipherment and decipherment get out of synchronism, the system needs
+  to be re-initialised.
+- Each re-initialisation should use a value of the start variable
+ different from the start variable values used before with the same
+ key.  The reason for this is that an identical bit stream would be
+ produced each time from the same parameters.  This would be
+ susceptible to a ' known plaintext' attack.
+
+Triple ECB Mode (des_ecb3_encrypt())
+- Encrypt with key1, decrypt with key2 and encrypt with key3 again.
+- As for ECB encryption but increases the key length to 168 bits.
+  There are theoretic attacks that can be used that make the effective
+  key length 112 bits, but this attack also requires 2^56 blocks of
+  memory, not very likely, even for the NSA.
+- If both keys are the same it is equivalent to encrypting once with
+  just one key.
+- If the first and last key are the same, the key length is 112 bits.
+  There are attacks that could reduce the key space to 55 bit's but it
+  requires 2^56 blocks of memory.
+- If all 3 keys are the same, this is effectively the same as normal
+  ecb mode.
+
+Triple CBC Mode (des_ede3_cbc_encrypt())
+- Encrypt with key1, decrypt with key2 and then encrypt with key3.
+- As for CBC encryption but increases the key length to 168 bits with
+  the same restrictions as for triple ecb mode.
+
+==== digest.doc ========================================================
+
+
+The Message Digest subroutines.
+
+These routines require "evp.h" to be included.
+
+These functions are a higher level interface to the various message digest
+routines found in this library.  As such, they allow the same code to be
+used to digest via different algorithms with only a change in an initial
+parameter.  They are basically just a front-end to the MD2, MD5, SHA
+and SHA1
+routines.
+
+These routines all take a pointer to the following structure to specify
+which message digest algorithm to use.
+typedef struct evp_md_st
+	{
+	int type;
+	int pkey_type;
+	int md_size;
+	void (*init)();
+	void (*update)();
+	void (*final)();
+
+	int required_pkey_type; /*EVP_PKEY_xxx */
+	int (*sign)();
+	int (*verify)();
+	} EVP_MD;
+
+If additional message digest algorithms are to be supported, a structure of
+this type needs to be declared and populated and then the Digest routines
+can be used with that algorithm.  The type field is the object NID of the
+digest type (read the section on Objects for an explanation).  The pkey_type
+is the Object type to use when the a message digest is generated by there
+routines and then is to be signed with the pkey algorithm.  Md_size is
+the size of the message digest returned.  Init, update
+and final are the relevant functions to perform the message digest function
+by parts.  One reason for specifying the message digest to use via this
+mechanism is that if you only use md5, only the md5 routines will
+be included in you linked program.  If you passed an integer
+that specified which message digest to use, the routine that mapped that
+integer to a set of message digest functions would cause all the message
+digests functions to be link into the code.  This setup also allows new
+message digest functions to be added by the application.
+
+The six message digests defined in this library are
+
+EVP_MD *EVP_md2(void);	/* RSA sign/verify */
+EVP_MD *EVP_md5(void);	/* RSA sign/verify */
+EVP_MD *EVP_sha(void);	/* RSA sign/verify */
+EVP_MD *EVP_sha1(void);	/* RSA sign/verify */
+EVP_MD *EVP_dss(void);	/* DSA sign/verify */
+EVP_MD *EVP_dss1(void);	/* DSA sign/verify */
+
+All the message digest routines take a EVP_MD_CTX pointer as an argument.
+The state of the message digest is kept in this structure.
+
+typedef struct pem_md_ctx_st
+	{
+	EVP_MD *digest;
+	union	{
+		unsigned char base[4]; /* this is used in my library as a
+					* 'pointer' to all union elements
+					* structures. */
+		MD2_CTX md2;
+		MD5_CTX md5;
+		SHA_CTX sha;
+		} md;
+	} EVP_MD_CTX;
+
+The Digest functions are as follows.
+
+void EVP_DigestInit(
+EVP_MD_CTX *ctx,
+EVP_MD *type);
+	This function is used to initialise the EVP_MD_CTX.  The message
+	digest that will associated with 'ctx' is specified by 'type'.
+
+void EVP_DigestUpdate(
+EVP_MD_CTX *ctx,
+unsigned char *data,
+unsigned int cnt);
+	This function is used to pass more data to the message digest
+	function.  'cnt' bytes are digested from 'data'.
+
+void EVP_DigestFinal(
+EVP_MD_CTX *ctx,
+unsigned char *md,
+unsigned int *len);
+	This function finishes the digestion and puts the message digest
+	into 'md'.  The length of the message digest is put into len;
+	EVP_MAX_MD_SIZE is the size of the largest message digest that
+	can be returned from this function.  Len can be NULL if the
+	size of the digest is not required.
+	
+
+==== encode.doc ========================================================
+
+
+void    EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
+void    EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,
+		int *outl,unsigned char *in,int inl);
+void    EVP_EncodeFinal(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl);
+int     EVP_EncodeBlock(unsigned char *t, unsigned char *f, int n);
+
+void    EVP_DecodeInit(EVP_ENCODE_CTX *ctx);
+int     EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl,
+		unsigned char *in, int inl);
+int     EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned
+		char *out, int *outl);
+int     EVP_DecodeBlock(unsigned char *t, unsigned
+		char *f, int n);
+
+
+==== envelope.doc ========================================================
+
+The following routines are use to create 'digital' envelopes.
+By this I mean that they perform various 'higher' level cryptographic
+functions.  Have a read of 'cipher.doc' and 'digest.doc' since those
+routines are used by these functions.
+cipher.doc contains documentation about the cipher part of the
+envelope library and digest.doc contatins the description of the
+message digests supported.
+
+To 'sign' a document involves generating a message digest and then encrypting
+the digest with an private key.
+
+#define EVP_SignInit(a,b)		EVP_DigestInit(a,b)
+#define EVP_SignUpdate(a,b,c)		EVP_DigestUpdate(a,b,c)
+Due to the fact this operation is basically just an extended message
+digest, the first 2 functions are macro calls to Digest generating
+functions.
+
+int     EVP_SignFinal(
+EVP_MD_CTX *ctx,
+unsigned char *md,
+unsigned int *s,
+EVP_PKEY *pkey);
+	This finalisation function finishes the generation of the message
+digest and then encrypts the digest (with the correct message digest 
+object identifier) with the EVP_PKEY private key.  'ctx' is the message digest
+context.  'md' will end up containing the encrypted message digest.  This
+array needs to be EVP_PKEY_size(pkey) bytes long.  's' will actually
+contain the exact length.  'pkey' of course is the private key.  It is
+one of EVP_PKEY_RSA or EVP_PKEY_DSA type.
+If there is an error, 0 is returned, otherwise 1.
+		
+Verify is used to check an signed message digest.
+
+#define EVP_VerifyInit(a,b)		EVP_DigestInit(a,b)
+#define EVP_VerifyUpdate(a,b,c)		EVP_DigestUpdate(a,b,c)
+Since the first step is to generate a message digest, the first 2 functions
+are macros.
+
+int EVP_VerifyFinal(
+EVP_MD_CTX *ctx,
+unsigned char *md,
+unsigned int s,
+EVP_PKEY *pkey);
+	This function finishes the generation of the message digest and then
+compares it with the supplied encrypted message digest.  'md' contains the
+'s' bytes of encrypted message digest.  'pkey' is used to public key decrypt
+the digest.  It is then compared with the message digest just generated.
+If they match, 1 is returned else 0.
+
+int	EVP_SealInit(EVP_CIPHER_CTX *ctx, EVP_CIPHER *type, unsigned char **ek,
+		int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk);
+Must have at least one public key, error is 0.  I should also mention that
+the buffers pointed to by 'ek' need to be EVP_PKEY_size(pubk[n]) is size.
+
+#define EVP_SealUpdate(a,b,c,d,e)	EVP_EncryptUpdate(a,b,c,d,e)	
+void	EVP_SealFinal(EVP_CIPHER_CTX *ctx,unsigned char *out,int *outl);
+
+
+int	EVP_OpenInit(EVP_CIPHER_CTX *ctx,EVP_CIPHER *type,unsigned char *ek,
+		int ekl,unsigned char *iv,EVP_PKEY *priv);
+0 on failure
+
+#define EVP_OpenUpdate(a,b,c,d,e)	EVP_DecryptUpdate(a,b,c,d,e)
+
+int	EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+Decrypt final return code
+
+
+==== error.doc ========================================================
+
+The error routines.
+
+The 'error' system I've implemented is intended to server 2 purpose, to
+record the reason why a command failed and to record where in the libraries
+the failure occurred.  It is more or less setup to record a 'trace' of which
+library components were being traversed when the error occurred.
+
+When an error is recorded, it is done so a as single unsigned long which is
+composed of three parts.  The top byte is the 'library' number, the middle
+12 bytes is the function code, and the bottom 12 bits is the 'reason' code.
+
+Each 'library', or should a say, 'section' of the SSLeay library has a
+different unique 'library' error number.  Each function in the library has
+a number that is unique for that library.  Each 'library' also has a number
+for each 'error reason' that is only unique for that 'library'.
+
+Due to the way these error routines record a 'error trace', there is an
+array per thread that is used to store the error codes.
+The various functions in this library are used to access
+and manipulate this array.
+
+void ERR_put_error(int lib, int func,int reason);
+	This routine records an error in library 'lib', function 'func'
+and reason 'reason'.  As errors get 'put' into the buffer, they wrap
+around and overwrite old errors if too many are written.  It is assumed
+that the last errors are the most important.
+
+unsigned long ERR_get_error(void );
+	This function returns the last error added to the error buffer.
+In effect it is popping the value off the buffer so repeated calls will
+continue to return values until there are no more errors to return in which
+case 0 is returned.
+
+unsigned long ERR_peek_error(void );
+	This function returns the value of the last error added to the
+error buffer but does not 'pop' it from the buffer.
+
+void ERR_clear_error(void );
+	This function clears the error buffer, discarding all unread
+errors.
+
+While the above described error system obviously produces lots of different
+error number, a method for 'reporting' these errors in a human readable
+form is required.  To achieve this, each library has the option of
+'registering' error strings.
+
+typedef struct ERR_string_data_st
+	{
+	unsigned long error;
+	char *string;
+	} ERR_STRING_DATA;
+
+The 'ERR_STRING_DATA' contains an error code and the corresponding text
+string.  To add new function error strings for a library, the
+ERR_STRING_DATA needs to be 'registered' with the library.
+
+void ERR_load_strings(unsigned long lib,ERR_STRING_DATA *err);
+	This function 'registers' the array of ERR_STRING_DATA pointed to by
+'err' as error text strings for the error library 'lib'.
+
+void ERR_free_strings(void);
+	This function free()s all the loaded error strings.
+
+char *ERR_error_string(unsigned long error,char *buf);
+	This function returns a text string that is a human readable
+version of the error represented by 'error'.  Buff should be at least 120
+bytes long and if it is NULL, the return value is a pointer to a static
+variable that will contain the error string, otherwise 'buf' is returned.
+If there is not a text string registered for a particular error, a text
+string containing the error number is returned instead.
+
+void ERR_print_errors(BIO *bp);
+void ERR_print_errors_fp(FILE *fp);
+	This function is a convenience routine that prints the error string
+for each error until all errors have been accounted for.
+
+char *ERR_lib_error_string(unsigned long e);
+char *ERR_func_error_string(unsigned long e);
+char *ERR_reason_error_string(unsigned long e);
+The above three functions return the 3 different components strings for the
+error 'e'.  ERR_error_string() uses these functions.
+
+void ERR_load_ERR_strings(void );
+	This function 'registers' the error strings for the 'ERR' module.
+
+void ERR_load_crypto_strings(void );
+	This function 'register' the error strings for just about every
+library in the SSLeay package except for the SSL routines.  There is no
+need to ever register any error text strings and you will probably save in
+program size.  If on the other hand you do 'register' all errors, it is
+quite easy to determine why a particular routine failed.
+
+As a final footnote as to why the error system is designed as it is.
+1) I did not want a single 'global' error code.
+2) I wanted to know which subroutine a failure occurred in.
+3) For Windows NT etc, it should be simple to replace the 'key' routines
+   with code to pass error codes back to the application.
+4) I wanted the option of meaningful error text strings.
+
+Late breaking news - the changes to support threads.
+
+Each 'thread' has an 'ERR_STATE' state associated with it.
+ERR_STATE *ERR_get_state(void ) will return the 'state' for the calling
+thread/process.
+
+ERR_remove_state(unsigned long pid); will 'free()' this state.  If pid == 0
+the current 'thread/process' will have it's error state removed.
+If you do not remove the error state of a thread, this could be considered a
+form of memory leak, so just after 'reaping' a thread that has died,
+call ERR_remove_state(pid).
+
+Have a read of thread.doc for more details for what is required for
+multi-threading support.  All the other error routines will
+work correctly when using threads.
+
+
+==== idea.doc ========================================================
+
+The IDEA library.
+IDEA is a block cipher that operates on 64bit (8 byte) quantities.  It
+uses a 128bit (16 byte) key.  It can be used in all the modes that DES can
+be used.  This library implements the ecb, cbc, cfb64 and ofb64 modes.
+
+For all calls that have an 'input' and 'output' variables, they can be the
+same.
+
+This library requires the inclusion of 'idea.h'.
+
+All of the encryption functions take what is called an IDEA_KEY_SCHEDULE as an 
+argument.  An IDEA_KEY_SCHEDULE is an expanded form of the idea key.
+For all modes of the IDEA algorithm, the IDEA_KEY_SCHEDULE used for
+decryption is different to the one used for encryption.
+
+The define IDEA_ENCRYPT is passed to specify encryption for the functions
+that require an encryption/decryption flag. IDEA_DECRYPT is passed to
+specify decryption.  For some mode there is no encryption/decryption
+flag since this is determined by the IDEA_KEY_SCHEDULE.
+
+So to encrypt you would do the following
+idea_set_encrypt_key(key,encrypt_ks);
+idea_ecb_encrypt(...,encrypt_ks);
+idea_cbc_encrypt(....,encrypt_ks,...,IDEA_ENCRYPT);
+
+To Decrypt
+idea_set_encrypt_key(key,encrypt_ks);
+idea_set_decrypt_key(encrypt_ks,decrypt_ks);
+idea_ecb_encrypt(...,decrypt_ks);
+idea_cbc_encrypt(....,decrypt_ks,...,IDEA_DECRYPT);
+
+Please note that any of the encryption modes specified in my DES library
+could be used with IDEA.  I have only implemented ecb, cbc, cfb64 and
+ofb64 for the following reasons.
+- ecb is the basic IDEA encryption.
+- cbc is the normal 'chaining' form for block ciphers.
+- cfb64 can be used to encrypt single characters, therefore input and output
+  do not need to be a multiple of 8.
+- ofb64 is similar to cfb64 but is more like a stream cipher, not as
+  secure (not cipher feedback) but it does not have an encrypt/decrypt mode.
+- If you want triple IDEA, thats 384 bits of key and you must be totally
+  obsessed with security.  Still, if you want it, it is simple enough to
+  copy the function from the DES library and change the des_encrypt to
+  idea_encrypt; an exercise left for the paranoid reader :-).
+
+The functions are as follows:
+
+void idea_set_encrypt_key(
+unsigned char *key;
+IDEA_KEY_SCHEDULE *ks);
+	idea_set_encrypt_key converts a 16 byte IDEA key into an
+	IDEA_KEY_SCHEDULE.  The IDEA_KEY_SCHEDULE is an expanded form of
+	the key which can be used to perform IDEA encryption.
+	An IDEA_KEY_SCHEDULE is an expanded form of the key which is used to
+	perform actual encryption.  It can be regenerated from the IDEA key
+	so it only needs to be kept when encryption is about
+	to occur.  Don't save or pass around IDEA_KEY_SCHEDULE's since they
+	are CPU architecture dependent, IDEA keys are not.
+	
+void idea_set_decrypt_key(
+IDEA_KEY_SCHEDULE *encrypt_ks,
+IDEA_KEY_SCHEDULE *decrypt_ks);
+	This functions converts an encryption IDEA_KEY_SCHEDULE into a
+	decryption IDEA_KEY_SCHEDULE.  For all decryption, this conversion
+	of the key must be done.  In some modes of IDEA, an
+	encryption/decryption flag is also required, this is because these
+	functions involve block chaining and the way this is done changes
+	depending on which of encryption of decryption is being done.
+	Please note that there is no quick way to generate the decryption
+	key schedule other than generating the encryption key schedule and
+	then converting it.
+
+void idea_encrypt(
+unsigned long *data,
+IDEA_KEY_SCHEDULE *ks);
+	This is the IDEA encryption function that gets called by just about
+	every other IDEA routine in the library.  You should not use this
+	function except to implement 'modes' of IDEA.  I say this because the
+	functions that call this routine do the conversion from 'char *' to
+	long, and this needs to be done to make sure 'non-aligned' memory
+	access do not occur.
+	Data is a pointer to 2 unsigned long's and ks is the
+	IDEA_KEY_SCHEDULE to use.  Encryption or decryption depends on the
+	IDEA_KEY_SCHEDULE.
+
+void idea_ecb_encrypt(
+unsigned char *input,
+unsigned char *output,
+IDEA_KEY_SCHEDULE *ks);
+	This is the basic Electronic Code Book form of IDEA (in DES this
+	mode is called Electronic Code Book so I'm going to use the term
+	for idea as well :-).
+	Input is encrypted into output using the key represented by
+	ks.  Depending on the IDEA_KEY_SCHEDULE, encryption or
+	decryption occurs.  Input is 8 bytes long and output is 8 bytes.
+	
+void idea_cbc_encrypt(
+unsigned char *input,
+unsigned char *output,
+long length,
+IDEA_KEY_SCHEDULE *ks,
+unsigned char *ivec,
+int enc);
+	This routine implements IDEA in Cipher Block Chaining mode.
+	Input, which should be a multiple of 8 bytes is encrypted
+	(or decrypted) to output which will also be a multiple of 8 bytes.
+	The number of bytes is in length (and from what I've said above,
+	should be a multiple of 8).  If length is not a multiple of 8, bad 
+	things will probably happen.  ivec is the initialisation vector.
+	This function updates iv after each call so that it can be passed to
+	the next call to idea_cbc_encrypt().
+	
+void idea_cfb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+des_key_schedule ks,
+des_cblock *ivec,
+int *num,
+int enc);
+	This is one of the more useful functions in this IDEA library, it
+	implements CFB mode of IDEA with 64bit feedback.
+	This allows you to encrypt an arbitrary number of bytes,
+	you do not require 8 byte padding.  Each call to this
+	routine will encrypt the input bytes to output and then update ivec
+	and num.  Num contains 'how far' we are though ivec.
+	Enc is used to indicate encryption or decryption.
+	One very important thing to remember is that when decrypting, use
+	the encryption form of the key.
+	CFB64 mode operates by using the cipher to
+	generate a stream of bytes which is used to encrypt the plain text.
+	The cipher text is then encrypted to generate the next 64 bits to
+	be xored (incrementally) with the next 64 bits of plain
+	text.  As can be seen from this, to encrypt or decrypt,
+	the same 'cipher stream' needs to be generated but the way the next
+	block of data is gathered for encryption is different for
+	encryption and decryption.  What this means is that to encrypt
+	idea_set_encrypt_key(key,ks);
+	idea_cfb64_encrypt(...,ks,..,IDEA_ENCRYPT)
+	do decrypt
+	idea_set_encrypt_key(key,ks)
+	idea_cfb64_encrypt(...,ks,...,IDEA_DECRYPT)
+	Note: The same IDEA_KEY_SCHEDULE but different encryption flags.
+	For idea_cbc or idea_ecb, idea_set_decrypt_key() would need to be
+	used to generate the IDEA_KEY_SCHEDULE for decryption.
+	The reason I'm stressing this point is that I just wasted 3 hours
+	today trying to decrypt using this mode and the decryption form of
+	the key :-(.
+	
+void idea_ofb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+des_key_schedule ks,
+des_cblock *ivec,
+int *num);
+	This functions implements OFB mode of IDEA with 64bit feedback.
+	This allows you to encrypt an arbitrary number of bytes,
+	you do not require 8 byte padding.  Each call to this
+	routine will encrypt the input bytes to output and then update ivec
+	and num.  Num contains 'how far' we are though ivec.
+	This is in effect a stream cipher, there is no encryption or
+	decryption mode.  The same key and iv should be used to
+	encrypt and decrypt.
+	
+For reading passwords, I suggest using des_read_pw_string() from my DES library.
+To generate a password from a text string, I suggest using MD5 (or MD2) to
+produce a 16 byte message digest that can then be passed directly to
+idea_set_encrypt_key().
+
+=====
+For more information about the specific IDEA modes in this library
+(ecb, cbc, cfb and ofb), read the section entitled 'Modes of DES' from the
+documentation on my DES library.  What is said about DES is directly
+applicable for IDEA.
+
+
+==== legal.doc ========================================================
+
+From eay@mincom.com Thu Jun 27 00:25:45 1996
+Received: by orb.mincom.oz.au id AA15821
+  (5.65c/IDA-1.4.4 for eay); Wed, 26 Jun 1996 14:25:45 +1000
+Date: Wed, 26 Jun 1996 14:25:45 +1000 (EST)
+From: Eric Young <eay@mincom.oz.au>
+X-Sender: eay@orb
+To: Ken Toll <ktoll@ren.digitalage.com>
+Cc: Eric Young <eay@mincom.oz.au>, ssl-talk@netscape.com
+Subject: Re: Unidentified subject!
+In-Reply-To: <9606261950.ZM28943@ren.digitalage.com>
+Message-Id: <Pine.SOL.3.91.960626131156.28573K-100000@orb>
+Mime-Version: 1.0
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+Status: O
+X-Status: 
+
+
+This is a little off topic but since SSLeay is a free implementation of
+the SSLv2 protocol, I feel it is worth responding on the topic of if it 
+is actually legal for Americans to use free cryptographic software.
+
+On Wed, 26 Jun 1996, Ken Toll wrote:
+> Is the U.S the only country that SSLeay cannot be used commercially 
+> (because of RSAref) or is that going to be an issue with every country 
+> that a client/server application (non-web browser/server) is deployed 
+> and sold?
+
+>From what I understand, the software patents that apply to algorithms 
+like RSA and DH only apply in the USA.  The IDEA algorithm I believe is 
+patened in europe (USA?), but considing how little it is used by other SSL 
+implementations, it quite easily be left out of the SSLeay build
+(this can be done with a compile flag).
+
+Actually if the RSA patent did apply outside the USA, it could be rather
+interesting since RSA is not alowed to let RSA toolkits outside of the USA
+[1], and since these are the only forms that they will alow the algorithm
+to be used in, it would mean that non-one outside of the USA could produce
+public key software which would be a very strong statment for
+international patent law to make :-).  This logic is a little flawed but
+it still points out some of the more interesting permutations of USA
+patent law and ITAR restrictions. 
+
+Inside the USA there is also the unresolved issue of RC4/RC2 which were
+made public on sci.crypt in Sep 1994 (RC4) and Feb 1996 (RC2).  I have
+copies of the origional postings if people are interested.  RSA I believe 
+claim that they were 'trade-secrets' and that some-one broke an NDA in 
+revealing them.  Other claim they reverse engineered the algorithms from 
+compiled binaries.  If the algorithms were reverse engineered, I believe 
+RSA had no legal leg to stand on.  If an NDA was broken, I don't know.
+Regardless, RSA, I believe, is willing to go to court over the issue so 
+licencing is probably the best idea, or at least talk to them.
+If there are people who actually know more about this, pease let me know, I 
+don't want to vilify or spread miss-information if I can help it.
+
+If you are not producing a web browser, it is easy to build SSLeay with
+RC2/RC4 removed. Since RC4 is the defacto standard cipher in 
+all web software (and it is damn fast) it is more or less required for 
+www use. For non www use of SSL, especially for an application where 
+interoperability with other vendors is not critical just leave it out.
+
+Removing IDEA, RC2 and RC4 would only leave DES and Triple DES but 
+they should be ok.  Considing that Triple DES can encrypt at rates of
+410k/sec on a pentium 100, and 940k/sec on a P6/200, this is quite 
+reasonable performance.  Single DES clocks in at 1160k/s and 2467k/s
+respectivly is actually quite fast for those not so paranoid (56 bit key).[1]
+
+> Is it possible to get a certificate for commercial use outside of the U.S.?
+yes.
+
+Thawte Consulting issues certificates (they are the people who sell the
+	Sioux httpd server and are based in South Africa)
+Verisign will issue certificates for Sioux (sold from South Africa), so this
+	proves that they will issue certificate for OS use if they are
+	happy with the quality of the software.
+
+(The above mentioned companies just the ones that I know for sure are issuing
+ certificates outside the USA).
+
+There is always the point that if you are using SSL for an intra net, 
+SSLeay provides programs that can be used so you can issue your own 
+certificates.  They need polishing but at least it is a good starting point.
+
+I am not doing anything outside Australian law by implementing these
+algorithms (to the best of my knowedge).  It is another example of how 
+the world legal system does not cope with the internet very well.
+
+I may start making shared libraries available (I have now got DLL's for 
+Windows).  This will mean that distributions into the usa could be 
+shipped with a version with a reduced cipher set and the versions outside 
+could use the DLL/shared library with all the ciphers (and without RSAref).
+
+This could be completly hidden from the application, so this would not 
+even require a re-linking.
+
+This is the reverse of what people were talking about doing to get around 
+USA export regulations :-)
+
+eric
+
+[1]:	The RSAref2.0 tookit is available on at least 3 ftp sites in Europe
+	and one in South Africa.
+
+[2]:	Since I always get questions when I post benchmark numbers :-),
+	DES performace figures are in 1000's of bytes per second in cbc 
+	mode using an 8192 byte buffer.  The pentium 100 was running Windows NT 
+	3.51 DLLs and the 686/200 was running NextStep.
+	I quote pentium 100 benchmarks because it is basically the
+	'entry level' computer that most people buy for personal use.
+	Windows 95 is the OS shipping on those boxes, so I'll give
+	NT numbers (the same Win32 runtime environment).  The 686
+	numbers are present as an indication of where we will be in a
+	few years.
+--
+Eric Young                  | BOOL is tri-state according to Bill Gates.
+AARNet: eay@mincom.oz.au    | RTFM Win32 GetMessage().
+
+
+
+==== lhash.doc ========================================================
+
+The LHASH library.
+
+I wrote this library in 1991 and have since forgotten why I called it lhash.
+It implements a hash table from an article I read at the
+time from 'Communications of the ACM'.  What makes this hash
+table different is that as the table fills, the hash table is
+increased (or decreased) in size via realloc().
+When a 'resize' is done, instead of all hashes being redistributed over
+twice as many 'buckets', one bucket is split.  So when an 'expand' is done,
+there is only a minimal cost to redistribute some values.  Subsequent
+inserts will cause more single 'bucket' redistributions but there will
+never be a sudden large cost due to redistributing all the 'buckets'.
+
+The state for a particular hash table is kept in the LHASH structure.
+The LHASH structure also records statistics about most aspects of accessing
+the hash table.  This is mostly a legacy of my writing this library for
+the reasons of implementing what looked like a nice algorithm rather than
+for a particular software product.
+
+Internal stuff you probably don't want to know about.
+The decision to increase or decrease the hash table size is made depending
+on the 'load' of the hash table.  The load is the number of items in the
+hash table divided by the size of the hash table.  The default values are
+as follows.  If (hash->up_load < load) => expand.
+if (hash->down_load > load) =>  contract.  The 'up_load' has a default value of
+1 and 'down_load' has a default value of 2.  These numbers can be modified
+by the application by just playing with the 'up_load' and 'down_load'
+variables.  The 'load' is kept in a form which is multiplied by 256.  So
+hash->up_load=8*256; will cause a load of 8 to be set.
+
+If you are interested in performance the field to watch is
+num_comp_calls.  The hash library keeps track of the 'hash' value for
+each item so when a lookup is done, the 'hashes' are compared, if
+there is a match, then a full compare is done, and
+hash->num_comp_calls is incremented.  If num_comp_calls is not equal
+to num_delete plus num_retrieve it means that your hash function is
+generating hashes that are the same for different values.  It is
+probably worth changing your hash function if this is the case because
+even if your hash table has 10 items in a 'bucked', it can be searched
+with 10 'unsigned long' compares and 10 linked list traverses.  This
+will be much less expensive that 10 calls to you compare function.
+
+LHASH *lh_new(
+unsigned long (*hash)(),
+int (*cmp)());
+	This function is used to create a new LHASH structure.  It is passed
+	function pointers that are used to store and retrieve values passed
+	into the hash table.  The 'hash'
+	function is a hashing function that will return a hashed value of
+	it's passed structure.  'cmp' is passed 2 parameters, it returns 0
+	is they are equal, otherwise, non zero.
+	If there are any problems (usually malloc failures), NULL is
+	returned, otherwise a new LHASH structure is returned.  The
+	hash value is normally truncated to a power of 2, so make sure
+	that your hash function returns well mixed low order bits.
+	
+void lh_free(
+LHASH *lh);
+	This function free()s a LHASH structure.  If there is malloced
+	data in the hash table, it will not be freed.  Consider using the
+	lh_doall function to deallocate any remaining entries in the hash
+	table.
+	
+char *lh_insert(
+LHASH *lh,
+char *data);
+	This function inserts the data pointed to by data into the lh hash
+	table.  If there is already and entry in the hash table entry, the
+	value being replaced is returned.  A NULL is returned if the new
+	entry does not clash with an entry already in the table (the normal
+	case) or on a malloc() failure (perhaps I should change this....).
+	The 'char *data' is exactly what is passed to the hash and
+	comparison functions specified in lh_new().
+	
+char *lh_delete(
+LHASH *lh,
+char *data);
+	This routine deletes an entry from the hash table.  The value being
+	deleted is returned.  NULL is returned if there is no such value in
+	the hash table.
+
+char *lh_retrieve(
+LHASH *lh,
+char *data);
+	If 'data' is in the hash table it is returned, else NULL is
+	returned.  The way these routines would normally be uses is that a
+	dummy structure would have key fields populated and then
+	ret=lh_retrieve(hash,&dummy);.  Ret would now be a pointer to a fully
+	populated structure.
+
+void lh_doall(
+LHASH *lh,
+void (*func)(char *a));
+	This function will, for every entry in the hash table, call function
+	'func' with the data item as parameters.
+	This function can be quite useful when used as follows.
+	void cleanup(STUFF *a)
+		{ STUFF_free(a); }
+	lh_doall(hash,cleanup);
+	lh_free(hash);
+	This can be used to free all the entries, lh_free() then
+	cleans up the 'buckets' that point to nothing.  Be careful
+	when doing this.  If you delete entries from the hash table,
+	in the call back function, the table may decrease in size,
+	moving item that you are
+	currently on down lower in the hash table.  This could cause
+	some entries to be skipped.  The best solution to this problem
+	is to set lh->down_load=0 before you start.  This will stop
+	the hash table ever being decreased in size.
+
+void lh_doall_arg(
+LHASH *lh;
+void(*func)(char *a,char *arg));
+char *arg;
+	This function is the same as lh_doall except that the function
+	called will be passed 'arg' as the second argument.
+	
+unsigned long lh_strhash(
+char *c);
+	This function is a demo string hashing function.  Since the LHASH
+	routines would normally be passed structures, this routine would
+	not normally be passed to lh_new(), rather it would be used in the
+	function passed to lh_new().
+
+The next three routines print out various statistics about the state of the
+passed hash table.  These numbers are all kept in the lhash structure.
+
+void lh_stats(
+LHASH *lh,
+FILE *out);
+	This function prints out statistics on the size of the hash table,
+	how many entries are in it, and the number and result of calls to
+	the routines in this library.
+
+void lh_node_stats(
+LHASH *lh,
+FILE *out);
+	For each 'bucket' in the hash table, the number of entries is
+	printed.
+	
+void lh_node_usage_stats(
+LHASH *lh,
+FILE *out);
+	This function prints out a short summary of the state of the hash
+	table.  It prints what I call the 'load' and the 'actual load'.
+	The load is the average number of data items per 'bucket' in the
+	hash table.  The 'actual load' is the average number of items per
+	'bucket', but only for buckets which contain entries.  So the
+	'actual load' is the average number of searches that will need to
+	find an item in the hash table, while the 'load' is the average number
+	that will be done to record a miss.
+
+==== md2.doc ========================================================
+
+The MD2 library.
+MD2 is a message digest algorithm that can be used to condense an arbitrary
+length message down to a 16 byte hash.  The functions all need to be passed
+a MD2_CTX which is used to hold the MD2 context during multiple MD2_Update()
+function calls.  The normal method of use for this library is as follows
+
+MD2_Init(...);
+MD2_Update(...);
+...
+MD2_Update(...);
+MD2_Final(...);
+
+This library requires the inclusion of 'md2.h'.
+
+The main negative about MD2 is that it is slow, especially when compared
+to MD5.
+
+The functions are as follows:
+
+void MD2_Init(
+MD2_CTX *c);
+	This function needs to be called to initiate a MD2_CTX structure for
+	use.
+	
+void MD2_Update(
+MD2_CTX *c;
+unsigned char *data;
+unsigned long len);
+	This updates the message digest context being generated with 'len'
+	bytes from the 'data' pointer.  The number of bytes can be any
+	length.
+
+void MD2_Final(
+unsigned char *md;
+MD2_CTX *c;
+	This function is called when a message digest of the data digested
+	with MD2_Update() is wanted.  The message digest is put in the 'md'
+	array and is MD2_DIGEST_LENGTH (16) bytes long.
+
+unsigned char *MD2(
+unsigned long n;
+unsigned char *d;
+unsigned char *md;
+	This function performs a MD2_Init(), followed by a MD2_Update()
+	followed by a MD2_Final() (using a local MD2_CTX).
+	The resulting digest is put into 'md' if it is not NULL.
+	Regardless of the value of 'md', the message
+	digest is returned from the function.  If 'md' was NULL, the message
+	digest returned is being stored in a static structure.
+
+==== md5.doc ========================================================
+
+The MD5 library.
+MD5 is a message digest algorithm that can be used to condense an arbitrary
+length message down to a 16 byte hash.  The functions all need to be passed
+a MD5_CTX which is used to hold the MD5 context during multiple MD5_Update()
+function calls.  This library also contains random number routines that are
+based on MD5
+
+The normal method of use for this library is as follows
+
+MD5_Init(...);
+MD5_Update(...);
+...
+MD5_Update(...);
+MD5_Final(...);
+
+This library requires the inclusion of 'md5.h'.
+
+The functions are as follows:
+
+void MD5_Init(
+MD5_CTX *c);
+	This function needs to be called to initiate a MD5_CTX structure for
+	use.
+	
+void MD5_Update(
+MD5_CTX *c;
+unsigned char *data;
+unsigned long len);
+	This updates the message digest context being generated with 'len'
+	bytes from the 'data' pointer.  The number of bytes can be any
+	length.
+
+void MD5_Final(
+unsigned char *md;
+MD5_CTX *c;
+	This function is called when a message digest of the data digested
+	with MD5_Update() is wanted.  The message digest is put in the 'md'
+	array and is MD5_DIGEST_LENGTH (16) bytes long.
+
+unsigned char *MD5(
+unsigned char *d;
+unsigned long n;
+unsigned char *md;
+	This function performs a MD5_Init(), followed by a MD5_Update()
+	followed by a MD5_Final() (using a local MD5_CTX).
+	The resulting digest is put into 'md' if it is not NULL.
+	Regardless of the value of 'md', the message
+	digest is returned from the function.  If 'md' was NULL, the message
+	digest returned is being stored in a static structure.
+
+
+==== memory.doc ========================================================
+
+In the interests of debugging SSLeay, there is an option to compile
+using some simple memory leak checking.
+
+All malloc(), free() and realloc() calls in SSLeay now go via
+Malloc(), Free() and Realloc() (except those in crypto/lhash).
+
+If CRYPTO_MDEBUG is defined, these calls are #defined to
+CRYPTO_malloc(), CRYPTO_free() and CRYPTO_realloc().
+If it is not defined, they are #defined to malloc(), free() and realloc().
+
+the CRYPTO_malloc() routines by default just call the underlying library
+functons.
+
+If CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) is called, memory leak detection is
+turned on.  CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) turns it off.
+
+When turned on, each Malloc() or Realloc() call is recored along with the file
+and line number from where the call was made.   (This is done using the
+lhash library which always uses normal system malloc(3) routines).
+
+void CRYPTO_mem_leaks(BIO *b);
+void CRYPTO_mem_leaks_fp(FILE *fp);
+These both print out the list of memory that has not been free()ed.
+This will probably be rather hard to read, but if you look for the 'top level'
+structure allocation, this will often give an idea as to what is not being
+free()ed.  I don't expect people to use this stuff normally.
+
+==== ca.1 ========================================================
+
+From eay@orb.mincom.oz.au Thu Dec 28 23:56:45 1995
+Received: by orb.mincom.oz.au id AA07374
+  (5.65c/IDA-1.4.4 for eay); Thu, 28 Dec 1995 13:56:45 +1000
+Date: Thu, 28 Dec 1995 13:56:45 +1000 (EST)
+From: Eric Young <eay@mincom.oz.au>
+X-Sender: eay@orb
+To: sameer <sameer@c2.org>
+Cc: ssleay@mincom.oz.au
+Subject: Re: 'ca'
+In-Reply-To: <199512230440.UAA23410@infinity.c2.org>
+Message-Id: <Pine.SOL.3.91.951228133525.7269A-100000@orb>
+Mime-Version: 1.0
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+Status: RO
+X-Status: 
+
+On Fri, 22 Dec 1995, sameer wrote:
+> 	I could use documentation on 'ca'. Thanks.
+
+Very quickly.
+The ca program uses the ssleay.conf file for most of its configuration
+
+./ca -help
+
+ -verbose        - Talk alot while doing things
+ -config file    - A config file. If you don't want to use the
+		   default config file
+ -name arg       - The particular CA definition to use
+	In the config file, the section to use for parameters.  This lets 
+	multiple setups to be contained in the one file.  By default, the 
+	default_ca variable is looked up in the [ ca ] section.  So in the 
+	shipped ssleay.conf, the CA definition used is CA_default.  It could be 
+	any other name.
+ -gencrl days    - Generate a new CRL, days is when the next CRL is due
+	This will generate a new certificate revocion list.
+ -days arg       - number of days to certify the certificate for
+	When certifiying certificates, this is the number of days to use.
+ -md arg         - md to use, one of md2, md5, sha or sha1
+ -policy arg     - The CA 'policy' to support
+	I'll describe this later, but there are 2 policies definied in the 
+	shipped ssleay.conf
+ -keyfile arg    - PEM RSA private key file
+ -key arg        - key to decode the RSA private key if it is encrypted
+	since we need to keep the CA's RSA key encrypted
+ -cert           - The CA certificate
+ -in file        - The input PEM encoded certificate request(s)
+ -out file       - Where to put the output file(s)
+ -outdir dir     - Where to put output certificates
+	The -out options concatinates all the output certificied
+	certificates to one file, -outdir puts them in a directory,
+	named by serial number.
+ -infiles ....   - The last argument, requests to process
+	The certificate requests to process, -in is the same.
+
+Just about all the above have default values defined in ssleay.conf.
+
+The key variables in ssleay.conf are (for the pariticular '-name' being 
+used, in the default, it is CA_default).
+
+dir is where all the CA database stuff is kept.
+certs is where all the previously issued certificates are kept.
+The database is a simple text database containing the following tab separated 
+fields.
+status: a value of 'R' - revoked, 'E' -expired or 'V' valid.
+issued date:  When the certificate was certified.
+revoked date:  When it was revoked, blank if not revoked.
+serial number:  The certificate serial number.
+certificate:	Where the certificate is located.
+CN:	The name of the certificate.
+
+The demo file has quite a few made up values it it.  The last 2 were 
+added by the ca program and are acurate.
+The CA program does not update the 'certificate' file correctly right now.
+The serial field should be unique as should the CN/status combination.
+The ca program checks these at startup.  What still needs to be 
+wrtten is a program to 'regenerate' the data base file from the issued 
+certificate list (and a CRL list).
+
+Back to the CA_default variables.
+
+Most of the variables are commented.
+
+policy is the default policy.
+
+Ok for policies, they define the order and which fields must be present 
+in the certificate request and what gets filled in.
+
+So a value of
+countryName             = match
+means that the country name must match the CA certificate.
+organizationalUnitName  = optional
+The org.Unit,Name does not have to be present and
+commonName              = supplied
+commonName must be supplied in the certificate request.
+
+For the 'policy_match' polocy, the order of the attributes in the 
+generated certiticate would be
+countryName
+stateOrProvinceName
+organizationName
+organizationalUnitName
+commonName
+emailAddress
+
+Have a play, it sort of makes sense.  If you think about how the persona 
+requests operate, it is similar to the 'policy_match' policy and the
+'policy_anything' is similar to what versign is doing.
+
+I hope this helps a bit.  Some backend scripts are definitly needed to 
+update the database and to make certificate revocion easy.  All 
+certificates issued should also be kept forever (or until they expire?)
+
+hope this helps
+eric (who has to run off an buy some cheap knee pads for the caving in 4 
+days time :-)
+
+--
+Eric Young                  | Signature removed since it was generating
+AARNet: eay@mincom.oz.au    | more followups than the message contents :-)
+
+
+==== ms3-ca.doc ========================================================
+
+Date: Mon, 9 Jun 97 08:00:33 +0200
+From: Holger.Reif@PrakInf.TU-Ilmenau.DE (Holger Reif)
+Subject: ms3-ca.doc
+Organization: TU Ilmenau, Fak. IA, FG Telematik
+Content-Length: 14575
+Status: RO
+X-Status: 
+
+Loading client certs into MSIE 3.01
+===================================
+
+This document contains all the information necessary to successfully set up 
+some scripts to issue client certs to Microsoft Internet Explorer. It 
+includes the required knowledge about the model MSIE uses for client 
+certification and includes complete sample scripts ready to play with. The 
+scripts were tested against a modified ca program of SSLeay 0.6.6 and should 
+work with the regular ca program that comes with version 0.8.0. I haven't 
+tested against MSIE 4.0
+
+You can use the information contained in this document in either way you 
+want. However if you feel it saved you a lot of time I ask you to be as fair 
+as to mention my name: Holger Reif <reif@prakinf.tu-ilmenau.de>.
+
+1.) The model used by MSIE
+--------------------------
+
+The Internet Explorer doesn't come with a embedded engine for installing 
+client certs like Netscape's Navigator. It rather uses the CryptoAPI (CAPI) 
+defined by Microsoft. CAPI comes with WindowsNT 4.0 or is installed together 
+with Internet Explorer since 3.01. The advantage of this approach is a higher 
+flexibility because the certificates in the (per user) system open 
+certificate store may be used by other applications as well. The drawback 
+however is that you need to do a bit more work to get a client cert issued.
+
+CAPI defines functions which will handle basic cryptographic work, eg. 
+generating keys, encrypting some data, signing text or building a certificate 
+request. The procedure is as follows: A CAPI function generates you a key 
+pair and saves it into the certificate store. After that one builds a 
+Distinguished Name. Together with that key pair another CAPI function forms a 
+PKCS#10 request which you somehow need to submit to a CA. Finally the issued 
+cert is given to a yet another CAPI function which saves it into the 
+certificate store.
+
+The certificate store with the user's keys and certs is in the registry. You 
+will find it under HKEY_CURRENT_USER/Software/Microsoft/Cryptography/ (I 
+leave it to you as a little exercise to figure out what all the entries mean 
+;-). Note that the keys are protected only with the user's usual Windows 
+login password.
+
+2.) The practical usage
+-----------------------
+
+Unfortunatly since CAPI is a system API you can't access its functions from 
+HTML code directly. For this purpose Microsoft provides a wrapper called 
+certenr3.dll. This DLL accesses the CAPI functions and provides an interface 
+usable from Visual Basic Script. One needs to install that library on the 
+computer which wants to have client cert. The easiest way is to load it as an 
+ActiveX control (certenr3.dll is properly authenticode signed by MS ;-). If 
+you have ever enrolled e cert request at a CA you will have installed it.
+
+At time of writing certenr3.dll is contained in 
+http://www.microsoft.com/workshop/prog/security/csa/certenr3.exe. It comes 
+with an README file which explains the available functions. It is labeled 
+beta but every CA seems to use it anyway. The license.txt allows you the 
+usage for your own purposes (as far as I understood) and a somehow limited 
+distribution. 
+
+The two functions of main interest are GenerateKeyPair and AcceptCredentials. 
+For complete explanation of all possible parameters see the README file. Here 
+are only minimal required parameters and their values.
+
+GenerateKeyPair(sessionID, FASLE, szName, 0, "ClientAuth", TRUE, FALSE, 1)
+- sessionID is a (locally to that computer) unique string to correlate the 
+generated key pair with a cert installed later.
+- szName is the DN of the form "C=DE; S=Thueringen; L=Ilmenau; CN=Holger 
+Reif; 1.2.840.113549.1.9.1=reif@prakinf.tu-ilmenau.de". Note that S is the 
+abreviation for StateOrProvince. The recognized abreviation include CN, O, C, 
+OU, G, I, L, S, T. If the abreviation is unknown (eg. for PKCS#9 email addr) 
+you need to use the full object identifier. The starting point for searching 
+them could be crypto/objects.h since all OIDs know to SSLeay are listed 
+there.
+- note: the possible ninth parameter which should give a default name to the 
+certificate storage location doesn't seem to work. Changes to the constant 
+values in the call above doesn't seem to make sense. You can't generate 
+PKCS#10 extensions with that function.
+
+The result of GenerateKeyPair is the base64 encoded PKCS#10 request. However 
+it has a little strange format that SSLeay doesn't accept. (BTW I feel the 
+decision of rejecting that format as standard conforming.) It looks like 
+follows:
+	1st line with 76 chars
+	2nd line with 76 chars
+	...
+	(n-2)th line with 76 chars
+	(n-1)th line contains a multiple of 4 chars less then 76 (possible 
+empty)
+	(n)th line has zero or 4 chars (then with 1 or 2 equal signs - the 
+		original text's lenght wasn'T a multiple of 3) 
+	The line separator has two chars: 0x0d 0x0a
+
+AcceptCredentials(sessionID, credentials, 0, FALSE)
+- sessionID needs to be the same as while generating the key pair
+- credentials is the base64 encoded PKCS#7 object containing the cert. 
+
+CRL's and CA certs are not required simply just the client cert. (It seems to 
+me that both are not even checked somehow.) The only format of the base64 
+encoded object I succesfully used was all characters in a very long string 
+without line feeds or carriage returns. (Hey, it doesn't matter, only a 
+computer reads it!)
+
+The result should be S_OK. For error handling see the example that comes with 
+certenr3.dll.
+
+A note about ASN.1 character encodings. certenr3.dll seems to know only about 
+2 of them: UniversalString and PrintableString. First it is definitely wrong 
+for an email address which is IA5STRING (checked by ssleay's ca). Second 
+unfortunately MSIE (at least until version 3.02) can't handle UniversalString 
+correctly - they just blow up you cert store! Therefore ssleay's ca (starting 
+from version 0.8.0) tries to convert the encodings automatically to IA5STRING 
+or TeletexString. The beef is it will work only for the latin-1 (western) 
+charset. Microsoft still has to do abit of homework...
+
+3.) An example
+--------------
+
+At least you need two steps: generating the key & request and then installing 
+the certificate. A real world CA would have some more steps involved, eg. 
+accepting some license. Note that both scripts shown below are just 
+experimental state without any warrenty!
+
+First how to generate a request. Note that we can't use a static page because 
+of the sessionID. I generate it from system time plus pid and hope it is 
+unique enough. Your are free to feed it through md5 to get more impressive 
+ID's ;-) Then the intended text is read in with sed which inserts the 
+sessionID. 
+
+-----BEGIN ms-enroll.cgi-----
+#!/bin/sh
+SESSION_ID=`date '+%y%m%d%H%M%S'`$$
+echo Content-type: text/html
+echo
+sed s/template_for_sessId/$SESSION_ID/ <<EOF
+<HTML><HEAD>
+<TITLE>Certificate Enrollment Test Page</TITLE>
+</HEAD><BODY>
+
+<OBJECT
+    classid="clsid:33BEC9E0-F78F-11cf-B782-00C04FD7BF43"
+    codebase=certenr3.dll
+    id=certHelper
+    >
+</OBJECT>
+
+<CENTER>
+<H2>enrollment for a personal cert</H2>
+<BR><HR WIDTH=50%><BR><P>
+<FORM NAME="MSIE_Enrollment" ACTION="ms-gencert.cgi" ENCTYPE=x-www-form-
+encoded METHOD=POST>
+<TABLE>
+    <TR><TD>Country</TD><TD><INPUT NAME="Country" VALUE=""></TD></TR>
+    <TR><TD>State</TD><TD><INPUT NAME="StateOrProvince" VALUE=""></TD></TR>
+    <TR><TD>Location</TD><TD><INPUT NAME="Location" VALUE=""></TD></TR>
+    <TR><TD>Organization</TD><TD><INPUT NAME="Organization" 
+VALUE=""></TD></TR>
+    <TR><TD>Organizational Unit</TD>
+        <TD><INPUT NAME="OrganizationalUnit" VALUE=""></TD></TR>
+    <TR><TD>Name</TD><TD><INPUT NAME="CommonName" VALUE=""></TD></TR>
+    <TR><TD>eMail Address</TD>
+        <TD><INPUT NAME="EmailAddress" VALUE=""></TD></TR>
+    <TR><TD></TD>
+        <TD><INPUT TYPE="BUTTON" NAME="submit" VALUE="Beantragen"></TD></TR>
+</TABLE>
+	<INPUT TYPE="hidden" NAME="SessionId" VALUE="template_for_sessId">
+	<INPUT TYPE="hidden" NAME="Request" VALUE="">
+</FORM>
+<BR><HR WIDTH=50%><BR><P>
+</CENTER>
+
+<SCRIPT LANGUAGE=VBS>
+    Dim DN
+
+    Sub Submit_OnClick
+	Dim TheForm
+	Set TheForm = Document.MSIE_Enrollment
+	sessionId	= TheForm.SessionId.value
+	reqHardware     = FALSE
+	C		= TheForm.Country.value
+	SP		= TheForm.StateOrProvince.value
+	L		= TheForm.Location.value
+	O		= TheForm.Organization.value
+	OU		= TheForm.OrganizationalUnit.value
+	CN              = TheForm.CommonName.value
+	Email		= TheForm.EmailAddress.value
+        szPurpose       = "ClientAuth"
+        doAcceptanceUINow   = FALSE
+        doOnline        = TRUE
+
+	DN = ""
+
+	Call Add_RDN("C", C)
+	Call Add_RDN("S", SP)
+	Call Add_RDN("L", L)
+	Call Add_RDN("O", O)
+	Call Add_RDN("OU", OU)
+	Call Add_RDN("CN", CN)
+	Call Add_RDN("1.2.840.113549.1.9.1", Email)
+		      ' rsadsi
+				     ' pkcs
+				       ' pkcs9
+					 ' eMailAddress
+        On Error Resume Next
+        sz10 = certHelper.GenerateKeyPair(sessionId, _
+                FALSE, DN, 0, ClientAuth, FASLE, TRUE, 1)_
+        theError = Err.Number
+        On Error Goto 0
+        if (sz10 = Empty OR theError <> 0) Then
+            sz = "The error '" & Hex(theError) & "' occurred." & chr(13) & _
+                chr(10) & "Your credentials could not be generated."
+            result = MsgBox(sz, 0, "Credentials Enrollment")
+            Exit Sub
+	else 
+	    TheForm.Request.value = sz10
+	    TheForm.Submit
+        end if
+    End Sub
+
+    Sub Add_RDN(sn, value)
+	if (value <> "") then
+	    if (DN <> "") then
+		DN = DN & "; "
+	    end if
+	    DN = DN & sn & "=" & value
+	end if
+    End Sub
+</SCRIPT>
+</BODY>
+</HTML>
+EOF
+-----END ms-enroll.cgi-----
+
+Second, how to extract the request and feed the certificate back? We need to 
+"normalize" the base64 encoding of the PKCS#10 format which means 
+regenerating the lines and wrapping with BEGIN and END line. This is done by 
+gawk. The request is taken by ca the normal way. Then the cert needs to be 
+packed into a PKCS#7 structure (note: the use of a CRL is necessary for 
+crl2pkcs7 as of version 0.6.6. Starting with 0.8.0 it it might probably be 
+ommited). Finally we need to format the PKCS#7 object and generate the HTML 
+text. I use two templates to have a clearer script.
+
+1st note: postit2 is slightly modified from a program I found at ncsa's ftp 
+site. Grab it from http://www.easterngraphics.com/certs/IX9704/postit2.c. You 
+need utils.c from there too.
+
+2nd note: I'm note quite sure wether the gawk script really handles all 
+possible inputs for the request right! Today I don't use this construction 
+anymore myself.
+
+3d note: the cert must be of version 3! This could be done with the nsComment 
+line in ssleay.cnf...
+
+------BEGIN ms-gencert.cgi-----
+#!/bin/sh
+FILE="/tmp/"`date '+%y%m%d%H%M%S'-`$$
+rm -f "$FILE".*
+
+HOME=`pwd`; export HOME  # as ssleay.cnf insists on having such an env var
+cd /usr/local/ssl #where demoCA (as named in ssleay.conf) is located
+
+postit2 -s " " -i 0x0d > "$FILE".inp  # process the FORM vars
+
+SESSION_ID=`gawk '$1 == "SessionId" { print $2; exit }' "$FILE".inp`
+
+gawk \
+	'BEGIN { \
+		OFS = ""; \
+		print "-----BEGIN CERTIFICATE REQUEST-----"; \
+		req_seen=0 \
+	} \
+	$1 == "Request" { \
+		req_seen=1; \
+		if (length($2) == 72) print($2); \
+		lastline=$2; \
+		next; \
+	} \
+	{ \
+		if (req_seen == 1) { \
+			if (length($1) >= 72) print($1); \
+			else if (length(lastline) < 72) { \
+				req_seen=0; \
+				print (lastline,$1); \
+			} \
+		lastline=$1; \
+		} \
+	} \
+	END { \
+		print "-----END CERTIFICATE REQUEST-----"; \
+	}' > "$FILE".pem < "$FILE".inp 
+
+ssleay ca -batch -in "$FILE".pem -key passwd -out "$FILE".out
+ssleay crl2pkcs7 -certfile "$FILE".out -out "$FILE".pkcs7 -in demoCA/crl.pem
+
+sed s/template_for_sessId/$SESSION_ID/ <ms-enroll2a.html >"$FILE".cert
+/usr/local/bin/gawk \
+	'BEGIN	{ \
+		OFS = ""; \
+		dq = sprintf("%c",34); \
+	} \
+	$0 ~ "PKCS7" { next; } \
+	{ \
+		print dq$0dq" & _"; \
+	}' <"$FILE".pkcs7 >> "$FILE".cert
+cat  ms-enroll2b.html >>"$FILE".cert
+
+echo Content-type: text/html
+echo Content-length: `wc -c "$FILE".cert`
+echo
+cat "$FILE".cert
+rm -f "$FILE".*
+-----END ms-gencert.cgi-----
+
+----BEGIN ms-enroll2a.html----
+<HTML><HEAD><TITLE>Certificate Acceptance Test Page</TITLE></HEAD><BODY>
+
+<OBJECT
+    classid="clsid:33BEC9E0-F78F-11cf-B782-00C04FD7BF43"
+    codebase=certenr3.dll
+    id=certHelper
+    >
+</OBJECT>
+
+<CENTER>
+<H2>Your personal certificate</H2>
+<BR><HR WIDTH=50%><BR><P>
+Press the button!
+<P><INPUT TYPE=BUTTON VALUE="Nimm mich!" NAME="InstallCert">
+</CENTER>
+<BR><HR WIDTH=50%><BR>
+
+<SCRIPT LANGUAGE=VBS>
+    Sub InstallCert_OnClick
+
+	sessionId	= "template_for_sessId"
+credentials = "" & _
+----END ms-enroll2a.html----
+
+----BEGIN ms-enroll2b.html----
+""
+        On Error Resume Next
+        result = certHelper.AcceptCredentials(sessionId, credentials, 0, 
+FALSE)
+        if (IsEmpty(result)) Then
+           sz = "The error '" & Err.Number & "' occurred." & chr(13) & 
+chr(10) & "This Digital ID could not be registered."
+           msgOut = MsgBox(sz, 0, "Credentials Registration Error")
+           navigate "error.html"
+        else
+           sz = "Digital ID successfully registered."
+           msgOut = MsgBox(sz, 0, "Credentials Registration")
+           navigate "success.html"
+        end if
+	Exit Sub
+    End Sub
+</SCRIPT>
+</BODY>
+</HTML>
+----END ms-enroll2b.html----
+
+4.) What do do with the cert?
+-----------------------------
+
+The cert is visible (without restarting MSIE) under the following menu:
+View->Options->Security->Personal certs. You can examine it's contents at 
+least partially.
+
+To use it for client authentication you need to use SSL3.0 (fortunately 
+SSLeay supports it with 0.8.0). Furthermore MSIE is told to only supports a 
+kind of automatic selection of certs (I personally wasn't able to test it 
+myself). But there is a requirement that the issuer of the server cert and 
+the issuer of the client cert needs to be the same (according to a developer 
+from MS). Which means: you need may more then one cert to talk to all 
+servers...
+
+I'm sure we will get a bit more experience after ApacheSSL is available for 
+SSLeay 0.8.8.
+
+
+I hope you enjoyed reading and that in future questions on this topic will 
+rarely appear on ssl-users@moncom.com ;-)
+
+Ilmenau, 9th of June 1997
+Holger Reif <reif@prakinf.tu-ilmenau.de>
+-- 
+read you later  -  Holger Reif
+----------------------------------------  Signaturprojekt Deutsche Einheit
+TU Ilmenau - Informatik - Telematik                      (Verdamp lang her)
+Holger.Reif@PrakInf.TU-Ilmenau.DE         Alt wie ein Baum werden, um ueber
+http://Remus.PrakInf.TU-Ilmenau.DE/Reif/  alle 7 Bruecken gehen zu koennen
+
+
+==== ns-ca.doc ========================================================
+
+The following documentation was supplied by Jeff Barber, who provided the
+patch to the CA program to add this functionality.
+
+eric
+--
+Jeff Barber                                Email: jeffb@issl.atl.hp.com
+
+Hewlett Packard                            Phone: (404) 648-9503
+Internet and System Security Lab           Fax:   (404) 648-9516
+
+                         oo
+---------------------cut /\ here for ns-ca.doc ------------------------------
+
+This document briefly describes how to use SSLeay to implement a 
+certificate authority capable of dynamically serving up client
+certificates for version 3.0 beta 5 (and presumably later) versions of
+the Netscape Navigator.  Before describing how this is done, it's
+important to understand a little about how the browser implements its
+client certificate support.  This is documented in some detail in the
+URLs based at <URL:http://home.netscape.com/eng/security/certs.html>.
+Here's a brief overview:
+
+-	The Navigator supports a new HTML tag "KEYGEN" which will cause
+	the browser to generate an RSA key pair when you submit a form
+	containing the tag.  The public key, along with an optional
+	challenge (supposedly provided for use in certificate revocation
+	but I don't use it) is signed, DER-encoded, base-64 encoded
+	and sent to the web server as the value of the variable
+	whose NAME is provided in the KEYGEN tag.  The private key is
+	stored by the browser in a local key database.
+
+	This "Signed Public Key And Challenge" (SPKAC) arrives formatted
+	into 64 character lines (which are of course URL-encoded when 
+	sent via HTTP -- i.e. spaces, newlines and most punctuatation are
+	encoded as "%HH" where HH is the hex equivalent of the ASCII code).
+	Note that the SPKAC does not contain the other usual attributes
+	of a certificate request, especially the subject name fields.
+	These must be otherwise encoded in the form for submission along
+	with the SPKAC.
+
+-	Either immediately (in response to this form submission), or at
+	some later date (a real CA will probably verify your identity in
+	some way before issuing the certificate), a web server can send a
+	certificate based on the public key and other attributes back to
+	the browser by encoding it in DER (the binary form) and sending it
+	to the browser as MIME type:
+	"Content-type: application/x-x509-user-cert"
+
+	The browser uses the public key encoded in the certificate to
+	associate the certificate with the appropriate private key in
+	its local key database.  Now, the certificate is "installed".
+
+-	When a server wants to require authentication based on client
+	certificates, it uses the right signals via the SSL protocol to
+	trigger the Navigator to ask you which certificate you want to
+	send.  Whether the certificate is accepted is dependent on CA
+	certificates and so forth installed in the server and is beyond
+	the scope of this document.
+
+
+Now, here's how the SSLeay package can be used to provide client 
+certficates:
+
+-	You prepare a file for input to the SSLeay ca application.
+	The file contains a number of "name = value" pairs that identify
+	the subject.  The names here are the same subject name component
+	identifiers used in the CA section of the lib/ssleay.conf file,
+	such as "emailAddress", "commonName" "organizationName" and so
+	forth.  Both the long version and the short version (e.g. "Email",
+	"CN", "O") can be used.
+
+	One more name is supported: this one is "SPKAC".  Its value
+	is simply the value of the base-64 encoded SPKAC sent by the
+	browser (with all the newlines and other space charaters
+	removed -- and newline escapes are NOT supported).
+
+	[ As of SSLeay 0.6.4, multiple lines are supported.
+	  Put a \ at the end of each line and it will be joined with the
+	  previous line with the '\n' removed - eay ]
+	
+	Here's a sample input file:
+
+C = US
+SP = Georgia
+O = Some Organization, Inc.
+OU = Netscape Compatibility Group
+CN = John X. Doe
+Email = jxdoe@someorg.com
+SPKAC = MIG0MGAwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAwmk6FMJ4uAVIYbcvIOx5+bDGTfvL8X5gE+R67ccMk6rCSGbVQz2cetyQtnI+VIs0NwdD6wjuSuVtVFbLoHonowIDAQABFgAwDQYJKoZIhvcNAQEEBQADQQBFZDUWFl6BJdomtN1Bi53mwijy1rRgJ4YirF15yBEDM3DjAQkKXHYOIX+qpz4KXKnl6EYxTnGSFL5wWt8X2iyx
+
+-	You execute the ca command (either from a CGI program run out of
+	the web server, or as a later manual task) giving it the above
+	file as input.  For example, if the file were named /tmp/cert.req,
+	you'd run:
+	$SSLDIR/bin/ca -spkac /tmp/cert.req -out /tmp/cert
+
+	The output is in DER format (binary) if a -out argument is 
+	provided, as above; otherwise, it's in the PEM format (base-64
+	encoded DER).  Also, the "-batch" switch is implied by the
+	"-spkac" so you don't get asked whether to complete the signing
+	(probably it shouldn't work this way but I was only interested
+	in hacking together an online CA that could be used for issuing
+	test certificates).
+
+	The "-spkac" capability doesn't support multiple files (I think).
+
+	Any CHALLENGE provided in the SPKAC is simply ignored.
+
+	The interactions between the identification fields you provide
+	and those identified in your lib/ssleay.conf are the same as if
+	you did an ordinary "ca -in infile -out outfile" -- that is, if
+	something is marked as required in the ssleay.conf file and it
+	isn't found in the -spkac file, the certificate won't be issued.
+
+-	Now, you pick up the output from /tmp/cert and pass it back to
+	the Navigator prepending the Content-type string described earlier.
+
+-	In order to run the ca command out of a CGI program, you must
+	provide a password to decrypt the CA's private key.  You can
+	do this by using "echo MyKeyPassword | $SSLDIR/bin/ca ..."
+	I think there's a way to not encrypt the key file in the first
+	place, but I didn't see how to do that, so I made a small change
+	to the library that allows the password to be accepted from a pipe.
+	Either way is UTTERLY INSECURE and a real CA would never do that.
+
+	[ You can use the 'ssleay rsa' command to remove the password
+	  from the private key, or you can use the '-key' option to the
+	  ca command to specify the decryption key on the command line
+	  or use the -nodes option when generating the key.
+	  ca will try to clear the command line version of the password
+	  but for quite a few operating systems, this is not possible.
+	  - eric ]
+
+So, what do you have to do to make use of this stuff to create an online 
+demo CA capability with SSLeay?
+
+1	Create an HTML form for your users.  The form should contain
+	fields for all of the required or optional fields in ssleay.conf.
+	The form must contain a KEYGEN tag somewhere with at least a NAME
+	attribute.
+
+2	Create a CGI program to process the form input submitted by the
+	browser.  The CGI program must URL-decode the variables and create
+	the file described above, containing subject identification info
+	as well as the SPKAC block.  It should then run the the ca program
+	with the -spkac option.  If it works (check the exit status),
+	return the new certificate with the appropriate MIME type.  If not,
+	return the output of the ca command with MIME type "text/plain".
+
+3	Set up your web server to accept connections signed by your demo
+	CA.  This probably involves obtaining the PEM-encoded CA certificate
+	(ordinarily in $SSLDIR/CA/cacert.pem) and installing it into a
+	server database.  See your server manual for instructions.
+
+
+==== obj.doc ========================================================
+
+The Object library.
+
+As part of my Crypto library, I found I required a method of identifying various
+objects.  These objects normally had 3 different values associated with
+them, a short text name, a long (or lower case) text name, and an
+ASN.1 Object Identifier (which is a sequence of numbers).
+This library contains a static list of objects and functions to lookup
+according to one type and to return the other types.
+
+To use these routines, 'Object.h' needs to be included.
+
+For each supported object, #define entries are defined as follows
+#define SN_Algorithm			"Algorithm"
+#define LN_algorithm			"algorithm"
+#define NID_algorithm			38
+#define OBJ_algorithm			1L,3L,14L,3L,2L
+
+SN_  stands for short name.
+LN_  stands for either long name or lowercase name.
+NID_ stands for Numeric ID.  I each object has a unique NID and this
+     should be used internally to identify objects.
+OBJ_ stands for ASN.1 Object Identifier or ASN1_OBJECT as defined in the
+     ASN1 routines.  These values are used in ASN1 encoding.
+
+The following functions are to be used to return pointers into a static
+definition of these types.  What this means is "don't try to free() any
+pointers returned from these functions.
+
+ASN1_OBJECT *OBJ_nid2obj(
+int n);
+	Return the ASN1_OBJECT that corresponds to a NID of n.
+	
+char *OBJ_nid2ln(
+int n);
+	Return the long/lower case name of the object represented by the
+	NID of n.
+	
+char *OBJ_nid2sn(
+int n);
+	Return the short name for the object represented by the NID of n.
+
+ASN1_OBJECT *OBJ_dup(
+ASN1_OBJECT *o);
+	Duplicate and return a new ASN1_OBJECT that is the same as the
+	passed parameter.
+	
+int OBJ_obj2nid(
+ASN1_OBJECT *o);
+	Given ASN1_OBJECT o, return the NID that corresponds.
+	
+int OBJ_ln2nid(
+char *s);
+	Given the long/lower case name 's', return the NID of the object.
+	
+int OBJ_sn2nid(
+char *s);
+	Given the short name 's', return the NID of the object.
+	
+char *OBJ_bsearch(
+char *key,
+char *base,
+int num,
+int size,
+int (*cmp)());
+	Since I have come across a few platforms that do not have the
+	bsearch() function, OBJ_bsearch is my version of that function.
+	Feel free to use this function, but you may as well just use the
+	normal system bsearch(3) if it is present.  This version also
+	has tolerance of being passed NULL pointers.
+
+==== keys ===========================================================
+
+EVP_PKEY_DSA
+EVP_PKEY_DSA2
+EVP_PKEY_DSA3
+EVP_PKEY_DSA4
+
+EVP_PKEY_RSA
+EVP_PKEY_RSA2
+
+valid DSA pkey types
+	NID_dsa
+	NID_dsaWithSHA
+	NID_dsaWithSHA1
+	NID_dsaWithSHA1_2
+
+valid RSA pkey types
+	NID_rsaEncryption
+	NID_rsa
+
+NID_dsaWithSHA	NID_dsaWithSHA			DSA		SHA
+NID_dsa		NID_dsaWithSHA1			DSA		SHA1
+NID_md2		NID_md2WithRSAEncryption	RSA-pkcs1	MD2
+NID_md5		NID_md5WithRSAEncryption	RSA-pkcs1	MD5
+NID_mdc2	NID_mdc2WithRSA			RSA-none	MDC2
+NID_ripemd160	NID_ripemd160WithRSA		RSA-pkcs1	RIPEMD160
+NID_sha		NID_shaWithRSAEncryption	RSA-pkcs1	SHA
+NID_sha1	NID_sha1WithRSAEncryption	RSA-pkcs1	SHA1
+
+==== rand.doc ========================================================
+
+My Random number library.
+
+These routines can be used to generate pseudo random numbers and can be
+used to 'seed' the pseudo random number generator (RNG).  The RNG make no
+effort to reproduce the same random number stream with each execution.
+Various other routines in the SSLeay library 'seed' the RNG when suitable
+'random' input data is available.  Read the section at the end for details
+on the design of the RNG.
+
+void RAND_bytes(
+unsigned char *buf,
+int num);
+	This routine puts 'num' random bytes into 'buf'.  One should make
+	sure RAND_seed() has been called before using this routine.
+	
+void RAND_seed(
+unsigned char *buf,
+int num);
+	This routine adds more 'seed' data the RNG state.  'num' bytes
+	are added to the RNG state, they are taken from 'buf'.  This
+	routine can be called with sensitive data such as user entered
+	passwords.  This sensitive data is in no way recoverable from
+	the RAND library routines or state.  Try to pass as much data
+	from 'random' sources as possible into the RNG via this function.
+	Also strongly consider using the RAND_load_file() and
+	RAND_write_file() routines.
+
+void RAND_cleanup();
+	When a program has finished with the RAND library, if it so
+	desires, it can 'zero' all RNG state.
+	
+The following 3 routines are convenience routines that can be used to
+'save' and 'restore' data from/to the RNG and it's state.
+Since the more 'random' data that is feed as seed data the better, why not
+keep it around between executions of the program?  Of course the
+application should pass more 'random' data in via RAND_seed() and 
+make sure no-one can read the 'random' data file.
+	
+char *RAND_file_name(
+char *buf,
+int size);
+	This routine returns a 'default' name for the location of a 'rand'
+	file.  The 'rand' file should keep a sequence of random bytes used
+	to initialise the RNG.  The filename is put in 'buf'.  Buf is 'size'
+	bytes long.  Buf is returned if things go well, if they do not,
+	NULL is returned.  The 'rand' file name is generated in the
+	following way.  First, if there is a 'RANDFILE' environment
+	variable, it is returned.  Second, if there is a 'HOME' environment
+	variable, $HOME/.rand is returned.  Third, NULL is returned.  NULL
+	is also returned if a buf would overflow.
+
+int RAND_load_file(
+char *file,
+long number);
+	This function 'adds' the 'file' into the RNG state.  It does this by
+	doing a RAND_seed() on the value returned from a stat() system call
+	on the file and if 'number' is non-zero, upto 'number' bytes read
+	from the file.  The number of bytes passed to RAND_seed() is returned.
+
+int RAND_write_file(
+char *file),
+	RAND_write_file() writes N random bytes to the file 'file', where
+	N is the size of the internal RND state (currently 1k).
+	This is a suitable method of saving RNG state for reloading via
+	RAND_load_file().
+
+What follows is a description of this RNG and a description of the rational
+behind it's design.
+
+It should be noted that this RNG is intended to be used to generate
+'random' keys for various ciphers including generation of DH and RSA keys.  
+
+It should also be noted that I have just created a system that I am happy with.
+It may be overkill but that does not worry me.  I have not spent that much
+time on this algorithm so if there are glaring errors, please let me know.
+Speed has not been a consideration in the design of these routines.
+
+First up I will state the things I believe I need for a good RNG.
+1) A good hashing algorithm to mix things up and to convert the RNG 'state'
+   to random numbers.
+2) An initial source of random 'state'.
+3) The state should be very large.  If the RNG is being used to generate
+   4096 bit RSA keys, 2 2048 bit random strings are required (at a minimum).
+   If your RNG state only has 128 bits, you are obviously limiting the
+   search space to 128 bits, not 2048.  I'm probably getting a little
+   carried away on this last point but it does indicate that it may not be
+   a bad idea to keep quite a lot of RNG state.  It should be easier to
+   break a cipher than guess the RNG seed data.
+4) Any RNG seed data should influence all subsequent random numbers
+   generated.  This implies that any random seed data entered will have
+   an influence on all subsequent random numbers generated.
+5) When using data to seed the RNG state, the data used should not be
+   extractable from the RNG state.  I believe this should be a
+   requirement because one possible source of 'secret' semi random
+   data would be a private key or a password.  This data must
+   not be disclosed by either subsequent random numbers or a
+   'core' dump left by a program crash.
+6) Given the same initial 'state', 2 systems should deviate in their RNG state
+   (and hence the random numbers generated) over time if at all possible.
+7) Given the random number output stream, it should not be possible to determine
+   the RNG state or the next random number.
+
+
+The algorithm is as follows.
+
+There is global state made up of a 1023 byte buffer (the 'state'), a
+working message digest ('md') and a counter ('count').
+
+Whenever seed data is added, it is inserted into the 'state' as
+follows.
+	The input is chopped up into units of 16 bytes (or less for
+	the last block).  Each of these blocks is run through the MD5
+	message digest.  The data passed to the MD5 digest is the
+	current 'md', the same number of bytes from the 'state'
+	(the location determined by in incremented looping index) as
+	the current 'block' and the new key data 'block'.  The result
+	of this is kept in 'md' and also xored into the 'state' at the
+	same locations that were used as input into the MD5.
+	I believe this system addresses points 1 (MD5), 3 (the 'state'),
+	4 (via the 'md'), 5 (by the use of MD5 and xor).
+
+When bytes are extracted from the RNG, the following process is used.
+For each group of 8 bytes (or less), we do the following,
+	Input into MD5, the top 8 bytes from 'md', the byte that are
+	to be overwritten by the random bytes and bytes from the
+	'state' (incrementing looping index).  From this digest output
+	(which is kept in 'md'), the top (upto) 8 bytes are
+	returned to the caller and the bottom (upto) 8 bytes are xored
+	into the 'state'.
+	Finally, after we have finished 'generation' random bytes for the
+	called, 'count' (which is incremented) and 'md' are fed into MD5 and
+	the results are kept in 'md'.
+	I believe the above addressed points 1 (use of MD5), 6 (by
+	hashing into the 'state' the 'old' data from the caller that
+	is about to be overwritten) and 7 (by not using the 8 bytes
+	given to the caller to update the 'state', but they are used
+	to update 'md').
+
+So of the points raised, only 2 is not addressed, but sources of
+random data will always be a problem.
+	
+
+==== rc2.doc ========================================================
+
+The RC2 library.
+
+RC2 is a block cipher that operates on 64bit (8 byte) quantities.  It
+uses variable size key, but 128bit (16 byte) key would normally be considered
+good.  It can be used in all the modes that DES can be used.  This
+library implements the ecb, cbc, cfb64, ofb64 modes.
+
+I have implemented this library from an article posted to sci.crypt on
+11-Feb-1996.  I personally don't know how far to trust the RC2 cipher.
+While it is capable of having a key of any size, not much reseach has
+publically been done on it at this point in time (Apr-1996)
+since the cipher has only been public for a few months :-)
+It is of a similar speed to DES and IDEA, so unless it is required for
+meeting some standard (SSLv2, perhaps S/MIME), it would probably be advisable
+to stick to IDEA, or for the paranoid, Tripple DES.
+
+Mind you, having said all that, I should mention that I just read alot and
+implement ciphers, I'm a 'babe in the woods' when it comes to evaluating
+ciphers :-).
+
+For all calls that have an 'input' and 'output' variables, they can be the
+same.
+
+This library requires the inclusion of 'rc2.h'.
+
+All of the encryption functions take what is called an RC2_KEY as an 
+argument.  An RC2_KEY is an expanded form of the RC2 key.
+For all modes of the RC2 algorithm, the RC2_KEY used for
+decryption is the same one that was used for encryption.
+
+The define RC2_ENCRYPT is passed to specify encryption for the functions
+that require an encryption/decryption flag. RC2_DECRYPT is passed to
+specify decryption.
+
+Please note that any of the encryption modes specified in my DES library
+could be used with RC2.  I have only implemented ecb, cbc, cfb64 and
+ofb64 for the following reasons.
+- ecb is the basic RC2 encryption.
+- cbc is the normal 'chaining' form for block ciphers.
+- cfb64 can be used to encrypt single characters, therefore input and output
+  do not need to be a multiple of 8.
+- ofb64 is similar to cfb64 but is more like a stream cipher, not as
+  secure (not cipher feedback) but it does not have an encrypt/decrypt mode.
+- If you want triple RC2, thats 384 bits of key and you must be totally
+  obsessed with security.  Still, if you want it, it is simple enough to
+  copy the function from the DES library and change the des_encrypt to
+  RC2_encrypt; an exercise left for the paranoid reader :-).
+
+The functions are as follows:
+
+void RC2_set_key(
+RC2_KEY *ks;
+int len;
+unsigned char *key;
+int bits;
+        RC2_set_key converts an 'len' byte key into a RC2_KEY.
+        A 'ks' is an expanded form of the 'key' which is used to
+        perform actual encryption.  It can be regenerated from the RC2 key
+        so it only needs to be kept when encryption or decryption is about
+        to occur.  Don't save or pass around RC2_KEY's since they
+        are CPU architecture dependent, 'key's are not.  RC2 is an
+	interesting cipher in that it can be used with a variable length
+	key.  'len' is the length of 'key' to be used as the key.
+	A 'len' of 16 is recomended.  The 'bits' argument is an
+	interesting addition which I only found out about in Aug 96.
+	BSAFE uses this parameter to 'limit' the number of bits used
+	for the key.  To use the 'key' unmodified, set bits to 1024.
+	This is what old versions of my RC2 library did (SSLeay 0.6.3).
+	RSAs BSAFE library sets this parameter to be 128 if 128 bit
+	keys are being used.  So to be compatable with BSAFE, set it
+	to 128, if you don't want to reduce RC2's key length, leave it
+	at 1024.
+	
+void RC2_encrypt(
+unsigned long *data,
+RC2_KEY *key,
+int encrypt);
+	This is the RC2 encryption function that gets called by just about
+	every other RC2 routine in the library.  You should not use this
+	function except to implement 'modes' of RC2.  I say this because the
+	functions that call this routine do the conversion from 'char *' to
+	long, and this needs to be done to make sure 'non-aligned' memory
+	access do not occur.
+	Data is a pointer to 2 unsigned long's and key is the
+	RC2_KEY to use.  Encryption or decryption is indicated by 'encrypt'.
+	which can have the values RC2_ENCRYPT or RC2_DECRYPT.
+
+void RC2_ecb_encrypt(
+unsigned char *in,
+unsigned char *out,
+RC2_KEY *key,
+int encrypt);
+	This is the basic Electronic Code Book form of RC2 (in DES this
+	mode is called Electronic Code Book so I'm going to use the term
+	for rc2 as well.
+	Input is encrypted into output using the key represented by
+	key.  Depending on the encrypt, encryption or
+	decryption occurs.  Input is 8 bytes long and output is 8 bytes.
+	
+void RC2_cbc_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+RC2_KEY *ks,
+unsigned char *ivec,
+int encrypt);
+	This routine implements RC2 in Cipher Block Chaining mode.
+	Input, which should be a multiple of 8 bytes is encrypted
+	(or decrypted) to output which will also be a multiple of 8 bytes.
+	The number of bytes is in length (and from what I've said above,
+	should be a multiple of 8).  If length is not a multiple of 8, bad 
+	things will probably happen.  ivec is the initialisation vector.
+	This function updates iv after each call so that it can be passed to
+	the next call to RC2_cbc_encrypt().
+	
+void RC2_cfb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+RC2_KEY *schedule,
+unsigned char *ivec,
+int *num,
+int encrypt);
+	This is one of the more useful functions in this RC2 library, it
+	implements CFB mode of RC2 with 64bit feedback.
+	This allows you to encrypt an arbitrary number of bytes,
+	you do not require 8 byte padding.  Each call to this
+	routine will encrypt the input bytes to output and then update ivec
+	and num.  Num contains 'how far' we are though ivec.
+	'Encrypt' is used to indicate encryption or decryption.
+	CFB64 mode operates by using the cipher to generate a stream
+	of bytes which is used to encrypt the plain text.
+	The cipher text is then encrypted to generate the next 64 bits to
+	be xored (incrementally) with the next 64 bits of plain
+	text.  As can be seen from this, to encrypt or decrypt,
+	the same 'cipher stream' needs to be generated but the way the next
+	block of data is gathered for encryption is different for
+	encryption and decryption.
+	
+void RC2_ofb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+RC2_KEY *schedule,
+unsigned char *ivec,
+int *num);
+	This functions implements OFB mode of RC2 with 64bit feedback.
+	This allows you to encrypt an arbitrary number of bytes,
+	you do not require 8 byte padding.  Each call to this
+	routine will encrypt the input bytes to output and then update ivec
+	and num.  Num contains 'how far' we are though ivec.
+	This is in effect a stream cipher, there is no encryption or
+	decryption mode.
+	
+For reading passwords, I suggest using des_read_pw_string() from my DES library.
+To generate a password from a text string, I suggest using MD5 (or MD2) to
+produce a 16 byte message digest that can then be passed directly to
+RC2_set_key().
+
+=====
+For more information about the specific RC2 modes in this library
+(ecb, cbc, cfb and ofb), read the section entitled 'Modes of DES' from the
+documentation on my DES library.  What is said about DES is directly
+applicable for RC2.
+
+
+==== rc4.doc ========================================================
+
+The RC4 library.
+RC4 is a stream cipher that operates on a byte stream.  It can be used with
+any length key but I would recommend normally using 16 bytes.
+
+This library requires the inclusion of 'rc4.h'.
+
+The RC4 encryption function takes what is called an RC4_KEY as an argument.
+The RC4_KEY is generated by the RC4_set_key function from the key bytes.
+
+RC4, being a stream cipher, does not have an encryption or decryption mode.
+It produces a stream of bytes that the input stream is xor'ed against and
+so decryption is just a case of 'encrypting' again with the same key.
+
+I have only put in one 'mode' for RC4 which is the normal one.  This means
+there is no initialisation vector and there is no feedback of the cipher
+text into the cipher.  This implies that you should not ever use the
+same key twice if you can help it.  If you do, you leave yourself open to
+known plain text attacks; if you know the plain text and
+corresponding cipher text in one message, all messages that used the same
+key can have the cipher text decoded for the corresponding positions in the
+cipher stream.
+
+The main positive feature of RC4 is that it is a very fast cipher; about 4
+times faster that DES.  This makes it ideally suited to protocols where the
+key is randomly chosen, like SSL.
+
+The functions are as follows:
+
+void RC4_set_key(
+RC4_KEY *key;
+int len;
+unsigned char *data);
+	This function initialises the RC4_KEY structure with the key passed
+	in 'data', which is 'len' bytes long.  The key data can be any
+	length but 16 bytes seems to be a good number.
+
+void RC4(
+RC4_KEY *key;
+unsigned long len;
+unsigned char *in;
+unsigned char *out);
+	Do the actual RC4 encryption/decryption.  Using the 'key', 'len'
+	bytes are transformed from 'in' to 'out'.  As mentioned above,
+	decryption is the operation as encryption.
+
+==== ref.doc ========================================================
+
+I have lots more references etc, and will update this list in the future,
+30 Aug 1996 - eay
+
+
+SSL	The SSL Protocol - from Netscapes.
+
+RC4	Newsgroups: sci.crypt
+	From: sterndark@netcom.com (David Sterndark)
+	Subject: RC4 Algorithm revealed.
+	Message-ID: <sternCvKL4B.Hyy@netcom.com>
+
+RC2	Newsgroups: sci.crypt
+	From: pgut01@cs.auckland.ac.nz (Peter Gutmann)
+	Subject: Specification for Ron Rivests Cipher No.2
+	Message-ID: <4fk39f$f70@net.auckland.ac.nz>
+
+MD2	RFC1319 The MD2 Message-Digest Algorithm
+MD5	RFC1321 The MD5 Message-Digest Algorithm
+
+X509 Certificates
+	RFC1421 Privacy Enhancement for Internet Electronic Mail: Part I
+	RFC1422 Privacy Enhancement for Internet Electronic Mail: Part II
+	RFC1423 Privacy Enhancement for Internet Electronic Mail: Part III
+	RFC1424 Privacy Enhancement for Internet Electronic Mail: Part IV
+
+RSA and various standard encoding
+	PKCS#1 RSA Encryption Standard
+	PKCS#5 Password-Based Encryption Standard
+	PKCS#7 Cryptographic Message Syntax Standard
+	A Layman's Guide to a Subset of ASN.1, BER, and DER
+	An Overview of the PKCS Standards
+	Some Examples of the PKCS Standards
+
+IDEA	Chapter 3 The Block Cipher IDEA
+
+RSA, prime number generation and bignum algorithms
+	Introduction To Algorithms,
+	Thomas Cormen, Charles Leiserson, Ronald Rivest,
+	Section 29 Arithmetic Circuits
+	Section 33 Number-Theoretic Algorithms
+
+Fast Private Key algorithm
+	Fast Decipherment Algorithm for RSA Public-Key Cryptosystem
+	J.-J. Quisquater and C. Couvreur, Electronics Letters,
+	14th October 1982, Vol. 18 No. 21
+
+Prime number generation and bignum algorithms.
+	PGP-2.3a
+
+==== rsa.doc ========================================================
+
+The RSA encryption and utility routines.
+
+The RSA routines are built on top of a big number library (the BN library).
+There are support routines in the X509 library for loading and manipulating
+the various objects in the RSA library.  When errors are returned, read
+about the ERR library for how to access the error codes.
+
+All RSA encryption is done according to the PKCS-1 standard which is
+compatible with PEM and RSAref.  This means that any values being encrypted
+must be less than the size of the modulus in bytes, minus 10, bytes long.
+
+This library uses RAND_bytes()() for it's random data, make sure to feed
+RAND_seed() with lots of interesting and varied data before using these
+routines.
+
+The RSA library has one specific data type, the RSA structure.
+It is composed of 8 BIGNUM variables (see the BN library for details) and
+can hold either a private RSA key or a public RSA key.
+Some RSA libraries have different structures for public and private keys, I
+don't.  For my libraries, a public key is determined by the fact that the
+RSA->d value is NULL.  These routines will operate on any size RSA keys.
+While I'm sure 4096 bit keys are very very secure, they take a lot longer
+to process that 1024 bit keys :-).
+
+The function in the RSA library are as follows.
+
+RSA *RSA_new();
+	This function creates a new RSA object.  The sub-fields of the RSA
+	type are also malloced so you should always use this routine to
+	create RSA variables.
+	
+void RSA_free(
+RSA *rsa);
+	This function 'frees' an RSA structure.  This routine should always
+	be used to free the RSA structure since it will also 'free' any
+	sub-fields of the RSA type that need freeing.
+	
+int RSA_size(
+RSA *rsa);	
+	This function returns the size of the RSA modulus in bytes.  Why do
+	I need this you may ask, well the reason is that when you encrypt
+	with RSA, the output string will be the size of the RSA modulus.
+	So the output for the RSA_encrypt and the input for the RSA_decrypt
+	routines need to be RSA_size() bytes long, because this is how many
+	bytes are expected.
+	
+For the following 4 RSA encryption routines, it should be noted that
+RSA_private_decrypt() should be used on the output from 
+RSA_public_encrypt() and RSA_public_decrypt() should be used on
+the output from RSA_private_encrypt().
+	
+int RSA_public_encrypt(
+int from_len;
+unsigned char *from	
+unsigned char *to	
+RSA *rsa);
+	This function implements RSA public encryption, the rsa variable
+	should be a public key (but can be a private key).  'from_len'
+	bytes taken from 'from' and encrypted and put into 'to'.  'to' needs
+	to be at least RSA_size(rsa) bytes long.  The number of bytes
+	written into 'to' is returned.  -1 is returned on an error.  The
+	operation performed is
+	to = from^rsa->e mod rsa->n.
+	
+int RSA_private_encrypt(
+int from_len;
+unsigned char *from	
+unsigned char *to	
+RSA *rsa);
+	This function implements RSA private encryption, the rsa variable
+	should be a private key.  'from_len' bytes taken from
+	'from' and encrypted and put into 'to'.  'to' needs
+	to be at least RSA_size(rsa) bytes long.  The number of bytes
+	written into 'to' is returned.  -1 is returned on an error.  The
+	operation performed is
+	to = from^rsa->d mod rsa->n.
+
+int RSA_public_decrypt(
+int from_len;
+unsigned char *from	
+unsigned char *to	
+RSA *rsa);
+	This function implements RSA public decryption, the rsa variable
+	should be a public key (but can be a private key).  'from_len'
+	bytes are taken from 'from' and decrypted.  The decrypted data is
+	put into 'to'.  The number of bytes encrypted is returned.  -1 is
+	returned to indicate an error. The operation performed is
+	to = from^rsa->e mod rsa->n.
+
+int RSA_private_decrypt(
+int from_len;
+unsigned char *from	
+unsigned char *to	
+RSA *rsa);
+	This function implements RSA private decryption, the rsa variable
+	should be a private key.  'from_len' bytes are taken
+	from 'from' and decrypted.  The decrypted data is
+	put into 'to'.  The number of bytes encrypted is returned.  -1 is
+	returned to indicate an error. The operation performed is
+	to = from^rsa->d mod rsa->n.
+
+int RSA_mod_exp(
+BIGNUM *n;
+BIGNUM *p;
+RSA *rsa);
+	Normally you will never use this routine.
+	This is really an internal function which is called by
+	RSA_private_encrypt() and RSA_private_decrypt().  It performs
+	n=n^p mod rsa->n except that it uses the 5 extra variables in the
+	RSA structure to make this more efficient.
+	
+RSA *RSA_generate_key(
+int bits;
+unsigned long e;
+void (*callback)();
+char *cb_arg;
+	This routine is used to generate RSA private keys.  It takes
+	quite a period of time to run and should only be used to
+	generate initial private keys that should then be stored
+	for later use.  The passed callback function 
+	will be called periodically so that feedback can be given
+	as to how this function is progressing.
+	'bits' is the length desired for the modulus, so it would be 1024
+	to generate a 1024 bit private key.
+	'e' is the value to use for the public exponent 'e'.  Traditionally
+	it is set to either 3 or 0x10001.
+	The callback function (if not NULL) is called in the following
+	situations.
+	when we have generated a suspected prime number to test,
+	callback(0,num1++,cb_arg).  When it passes a prime number test,
+	callback(1,num2++,cb_arg).  When it is rejected as one of
+	the 2 primes required due to gcd(prime,e value) != 0,
+	callback(2,num3++,cb_arg).  When finally accepted as one
+	of the 2 primes, callback(3,num4++,cb_arg).
+
+
+==== rsaref.doc ========================================================
+
+This package can be compiled to use the RSAref library.
+This library is not allowed outside of the USA but inside the USA it is
+claimed by RSA to be the only RSA public key library that can be used
+besides BSAFE..
+
+There are 2 files, rsaref/rsaref.c and rsaref/rsaref.h that contain the glue
+code to use RSAref.  These files were written by looking at the PGP
+source code and seeing which routines it used to access RSAref.
+I have also been sent by some-one a copy of the RSAref header file that
+contains the library error codes.
+
+[ Jun 1996 update - I have recently gotten hold of RSAref 2.0 from
+  South Africa and have been doing some performace tests. ]
+	
+They have now been tested against the recently announced RSAEURO
+library.
+
+There are 2 ways to use SSLeay and RSAref.  First, to build so that
+the programs must be linked with RSAref, add '-DRSAref' to CFLAG in the top
+level makefile and -lrsaref (or where ever you are keeping RSAref) to
+EX_LIBS.
+
+To build a makefile via util/mk1mf.pl to do this, use the 'rsaref' option.
+
+The second method is to build as per normal and link applications with
+the RSAglue library.  The correct library order would be
+cc -o cmd cmd.o -lssl -lRSAglue -lcrypto -lrsaref -ldes
+The RSAglue library is built in the rsa directory and is NOT
+automatically installed.
+
+Be warned that the RSAEURO library, that is claimed to be compatible
+with RSAref contains a different value for the maximum number of bits
+supported.  This changes structure sizes and so if you are using
+RSAEURO, change the value of RSAref_MAX_BITS in rsa/rsaref.h
+
+
+==== s_mult.doc ========================================================
+
+s_mult is a test program I hacked up on a Sunday for testing non-blocking
+IO.  It has a select loop at it's centre that handles multiple readers
+and writers.
+
+Try the following command
+ssleay s_mult -echo -nbio -ssl -v
+echo - sends any sent text back to the sender
+nbio - turns on non-blocking IO
+ssl  - accept SSL connections, default is normal text
+v    - print lots
+	type Q<cr> to quit
+
+In another window, run the following
+ssleay s_client -pause </etc/termcap
+
+The pause option puts in a 1 second pause in each read(2)/write(2) call
+so the other end will have read()s fail.
+
+==== session.doc ========================================================
+
+I have just checked over and re-worked the session stuff.
+The following brief example will ignore all setup information to do with
+authentication.
+
+Things operate as follows.
+
+The SSL environment has a 'context', a SSL_CTX structure.  This holds the
+cached SSL_SESSIONS (which can be reused) and the certificate lookup
+information.  Each SSL structure needs to be associated with a SSL_CTX.
+Normally only one SSL_CTX structure is needed per program.
+
+SSL_CTX *SSL_CTX_new(void ); 
+void    SSL_CTX_free(SSL_CTX *);
+These 2 functions create and destroy SSL_CTX structures
+
+The SSL_CTX has a session_cache_mode which is by default,
+in SSL_SESS_CACHE_SERVER mode.  What this means is that the library
+will automatically add new session-id's to the cache upon successful
+SSL_accept() calls.
+If SSL_SESS_CACHE_CLIENT is set, then client certificates are also added
+to the cache.
+SSL_set_session_cache_mode(ctx,mode)  will set the 'mode' and
+SSL_get_session_cache_mode(ctx) will get the cache 'mode'.
+The modes can be
+SSL_SESS_CACHE_OFF	- no caching
+SSL_SESS_CACHE_CLIENT	- only SSL_connect()
+SSL_SESS_CACHE_SERVER	- only SSL_accept()
+SSL_SESS_NO_CACHE_BOTH	- Either SSL_accept() or SSL_connect().
+If SSL_SESS_CACHE_NO_AUTO_CLEAR is set, old timed out sessions are
+not automatically removed each 255, SSL_connect()s or SSL_accept()s.
+
+By default, upon every 255 successful SSL_connect() or SSL_accept()s,
+the cache is flush.  Please note that this could be expensive on
+a heavily loaded SSL server, in which case, turn this off and
+clear the cache of old entries 'manually' (with one of the functions
+listed below) every few hours.  Perhaps I should up this number, it is hard
+to say.  Remember, the '255' new calls is just a mechanism to get called
+every now and then, in theory at most 255 new session-id's will have been
+added but if 100 are added every minute, you would still have
+500 in the cache before any would start being flushed (assuming a 3 minute
+timeout)..
+
+int SSL_CTX_sess_hits(SSL_CTX *ctx);
+int SSL_CTX_sess_misses(SSL_CTX *ctx);
+int SSL_CTX_sess_timeouts(SSL_CTX *ctx);
+These 3 functions return statistics about the SSL_CTX.  These 3 are the
+number of session id reuses.  hits is the number of reuses, misses are the
+number of lookups that failed, and timeouts is the number of cached
+entries ignored because they had timeouted.
+
+ctx->new_session_cb is a function pointer to a function of type
+int new_session_callback(SSL *ssl,SSL_SESSION *new);
+This function, if set in the SSL_CTX structure is called whenever a new
+SSL_SESSION is added to the cache.  If the callback returns non-zero, it
+means that the application will have to do a SSL_SESSION_free()
+on the structure (this is
+to do with the cache keeping the reference counts correct, without the
+application needing to know about it.
+The 'active' parameter is the current SSL session for which this connection
+was created.
+
+void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,int (*cb)());
+to set the callback,
+int (*cb)() SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)
+to get the callback.
+
+If the 'get session' callback is set, when a session id is looked up and
+it is not in the session-id cache, this callback is called.  The callback is
+of the form
+SSL_SESSION *get_session_callback(unsigned char *sess_id,int sess_id_len,
+	int *copy);
+
+The get_session_callback is intended to return null if no session id is found.
+The reference count on the SSL_SESSION in incremented by the SSL library,
+if copy is 1.  Otherwise, the reference count is not modified.
+
+void SSL_CTX_sess_set_get_cb(ctx,cb) sets the callback and
+int (*cb)()SSL_CTX_sess_get_get_cb(ctx) returns the callback.
+
+These callbacks are basically intended to be used by processes to
+send their session-id's to other processes.  I currently have not implemented
+non-blocking semantics for these callbacks, it is upto the application
+to make the callbacks efficient if they require blocking (perhaps
+by 'saving' them and then 'posting them' when control returns from
+the SSL_accept().
+
+LHASH *SSL_CTX_sessions(SSL_CTX *ctx)
+This returns the session cache.  The lhash strucutre can be accessed for
+statistics about the cache.
+
+void lh_stats(LHASH *lh, FILE *out);
+void lh_node_stats(LHASH *lh, FILE *out);
+void lh_node_usage_stats(LHASH *lh, FILE *out);
+
+can be used to print details about it's activity and current state.
+You can also delve directly into the lhash structure for 14 different
+counters that are kept against the structure.  When I wrote the lhash library,
+I was interested in gathering statistics :-).
+Have a read of doc/lhash.doc in the SSLeay distribution area for more details
+on the lhash library.
+
+Now as mentioned ealier, when a SSL is created, it needs a SSL_CTX.
+SSL *   SSL_new(SSL_CTX *);
+
+This stores a session.  A session is secret information shared between 2
+SSL contexts.  It will only be created if both ends of the connection have
+authenticated their peer to their satisfaction.  It basically contains
+the information required to use a particular secret key cipher.
+
+To retrieve the SSL_CTX being used by a SSL,
+SSL_CTX *SSL_get_SSL_CTX(SSL *s);
+
+Now when a SSL session is established between to programs, the 'session'
+information that is cached in the SSL_CTX can me manipulated by the
+following functions.
+int SSL_set_session(SSL *s, SSL_SESSION *session);
+This will set the SSL_SESSION to use for the next SSL_connect().  If you use
+this function on an already 'open' established SSL connection, 'bad things
+will happen'.  This function is meaning-less when used on a ssl strucutre
+that is just about to be used in a SSL_accept() call since the
+SSL_accept() will either create a new session or retrieve one from the
+cache.
+
+SSL_SESSION *SSL_get_session(SSL *s);
+This will return the SSL_SESSION for the current SSL, NULL if there is
+no session associated with the SSL structure.
+
+The SSL sessions are kept in the SSL_CTX in a hash table, to remove a
+session
+void    SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c);
+and to add one
+int    SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
+SSL_CTX_add_session() returns 1 if the session was already in the cache (so it
+was not added).
+Whenever a new session is created via SSL_connect()/SSL_accept(),
+they are automatically added to the cache, depending on the session_cache_mode
+settings.  SSL_set_session()
+does not add it to the cache.  Just call SSL_CTX_add_session() if you do want the
+session added.  For a 'client' this would not normally be the case.
+SSL_CTX_add_session() is not normally ever used, except for doing 'evil' things
+which the next 2 funtions help you do.
+
+int     i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
+SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a,unsigned char **pp,long length);
+These 2 functions are in the standard ASN1 library form and can be used to
+load and save to a byte format, the SSL_SESSION structure.
+With these functions, you can save and read these structures to a files or
+arbitary byte string.
+The PEM_write_SSL_SESSION(fp,x) and PEM_read_SSL_SESSION(fp,x,cb) will
+write to a file pointer in base64 encoding.
+
+What you can do with this, is pass session information between separate
+processes.  Please note, that you will probably also need to modify the
+timeout information on the SSL_SESSIONs.
+
+long SSL_get_time(SSL_SESSION *s)
+will return the 'time' that the session
+was loaded.  The timeout is relative to this time.  This information is
+saved when the SSL_SESSION is converted to binarary but it is stored
+in as a unix long, which is rather OS dependant, but easy to convert back.
+
+long SSL_set_time(SSL_SESSION *s,long t) will set the above mentioned time.
+The time value is just the value returned from time(3), and should really
+be defined by be to be time_t.
+
+long SSL_get_timeout(SSL_SESSION *s);
+long SSL_set_timeout(SSL_SESSION *s,long t);
+These 2 retrieve and set the timeout which is just a number of secconds
+from the 'SSL_get_time()' value.  When this time period has elapesed,
+the session will no longer be in the cache (well it will actually be removed
+the next time it is attempted to be retrieved, so you could 'bump'
+the timeout so it remains valid).
+The 'time' and 'timeout' are set on a session when it is created, not reset
+each time it is reused.  If you did wish to 'bump it', just after establishing
+a connection, do a
+SSL_set_time(ssl,time(NULL));
+
+You can also use
+SSL_CTX_set_timeout(SSL_CTX *ctx,unsigned long t) and
+SSL_CTX_get_timeout(SSL_CTX *ctx) to manipulate the default timeouts for
+all SSL connections created against a SSL_CTX.  If you set a timeout in
+an SSL_CTX, all new SSL's created will inherit the timeout.  It can be over
+written by the SSL_set_timeout(SSL *s,unsigned long t) function call.
+If you 'set' the timeout back to 0, the system default will be used.
+
+SSL_SESSION *SSL_SESSION_new();
+void SSL_SESSION_free(SSL_SESSION *ses);
+These 2 functions are used to create and dispose of SSL_SESSION functions.
+You should not ever normally need to use them unless you are using 
+i2d_SSL_SESSION() and/or d2i_SSL_SESSION().  If you 'load' a SSL_SESSION
+via d2i_SSL_SESSION(), you will need to SSL_SESSION_free() it.
+Both SSL_set_session() and SSL_CTX_add_session() will 'take copies' of the
+structure (via reference counts) when it is passed to them.
+
+SSL_CTX_flush_sessions(ctx,time);
+The first function will clear all sessions from the cache, which have expired
+relative to 'time' (which could just be time(NULL)).
+
+SSL_CTX_flush_sessions(ctx,0);
+This is a special case that clears everything.
+
+As a final comment, a 'session' is not enough to establish a new
+connection.  If a session has timed out, a certificate and private key
+need to have been associated with the SSL structure.
+SSL_copy_session_id(SSL *to,SSL *from); will copy not only the session
+strucutre but also the private key and certificate associated with
+'from'.
+
+EXAMPLES.
+
+So lets play at being a weird SSL server.
+
+/* setup a context */
+ctx=SSL_CTX_new();
+
+/* Lets load some session from binary into the cache, why one would do
+ * this is not toally clear, but passing between programs does make sense
+ * Perhaps you are using 4096 bit keys and are happy to keep them
+ * valid for a week, to avoid the RSA overhead of 15 seconds, I'm not toally
+ * sure, perhaps this is a process called from an SSL inetd and this is being 
+ * passed to the application. */
+session=d2i_SSL_SESSION(....)
+SSL_CTX_add_session(ctx,session);
+
+/* Lets even add a session from a file */
+session=PEM_read_SSL_SESSION(....)
+SSL_CTX_add_session(ctx,session);
+
+/* create a new SSL structure */
+ssl=SSL_new(ctx);
+
+/* At this point we want to be able to 'create' new session if
+ * required, so we need a certificate and RSAkey. */
+SSL_use_RSAPrivateKey_file(ssl,...)
+SSL_use_certificate_file(ssl,...)
+
+/* Now since we are a server, it make little sence to load a session against
+ * the ssl strucutre since a SSL_accept() will either create a new session or
+ * grab an existing one from the cache. */
+
+/* grab a socket descriptor */
+fd=accept(...);
+
+/* associated it with the ssl strucutre */
+SSL_set_fd(ssl,fd);
+
+SSL_accept(ssl); /* 'do' SSL using out cert and RSA key */
+
+/* Lets print out the session details or lets save it to a file,
+ * perhaps with a secret key cipher, so that we can pass it to the FBI
+ * when they want to decode the session :-).  While we have RSA
+ * this does not matter much but when I do SSLv3, this will allow a mechanism
+ * for the server/client to record the information needed to decode
+ * the traffic that went over the wire, even when using Diffie-Hellman */
+PEM_write_SSL_SESSION(SSL_get_session(ssl),stdout,....)
+
+Lets 'connect' back to the caller using the same session id.
+
+ssl2=SSL_new(ctx);
+fd2=connect(them);
+SSL_set_fd(ssl2,fd2);
+SSL_set_session(ssl2,SSL_get_session(ssl));
+SSL_connect(ssl2);
+
+/* what the hell, lets accept no more connections using this session */
+SSL_CTX_remove_session(SSL_get_SSL_CTX(ssl),SSL_get_session(ssl));
+
+/* we could have just as easily used ssl2 since they both are using the
+ * same session.
+ * You will note that both ssl and ssl2 are still using the session, and
+ * the SSL_SESSION structure will be free()ed when both ssl and ssl2
+ * finish using the session.  Also note that you could continue to initiate
+ * connections using this session by doing SSL_get_session(ssl) to get the
+ * existing session, but SSL_accept() will not be able to find it to
+ * use for incoming connections.
+ * Of corse, the session will timeout at the far end and it will no
+ * longer be accepted after a while.  The time and timeout are ignored except
+ * by SSL_accept(). */
+
+/* Since we have had our server running for 10 weeks, and memory is getting
+ * short, perhaps we should clear the session cache to remove those
+ * 100000 session entries that have expired.  Some may consider this
+ * a memory leak :-) */
+
+SSL_CTX_flush_sessions(ctx,time(NULL));
+
+/* Ok, after a bit more time we wish to flush all sessions from the cache
+ * so that all new connections will be authenticated and incure the
+ * public key operation overhead */
+
+SSL_CTX_flush_sessions(ctx,0);
+
+/* As a final note, to copy everything to do with a SSL, use */
+SSL_copy_session_id(SSL *to,SSL *from);
+/* as this also copies the certificate and RSA key so new session can
+ * be established using the same details */
+
+
+==== sha.doc ========================================================
+
+The SHA (Secure Hash Algorithm) library.
+SHA is a message digest algorithm that can be used to condense an arbitrary
+length message down to a 20 byte hash.  The functions all need to be passed
+a SHA_CTX which is used to hold the SHA context during multiple SHA_Update()
+function calls.  The normal method of use for this library is as follows
+This library contains both SHA and SHA-1 digest algorithms.  SHA-1 is
+an update to SHA (which should really be called SHA-0 now) which
+tweaks the algorithm slightly.  The SHA-1 algorithm is used by simply
+using SHA1_Init(), SHA1_Update(), SHA1_Final() and SHA1() instead of the
+SHA*() calls
+
+SHA_Init(...);
+SHA_Update(...);
+...
+SHA_Update(...);
+SHA_Final(...);
+
+This library requires the inclusion of 'sha.h'.
+
+The functions are as follows:
+
+void SHA_Init(
+SHA_CTX *c);
+	This function needs to be called to initiate a SHA_CTX structure for
+	use.
+	
+void SHA_Update(
+SHA_CTX *c;
+unsigned char *data;
+unsigned long len);
+	This updates the message digest context being generated with 'len'
+	bytes from the 'data' pointer.  The number of bytes can be any
+	length.
+
+void SHA_Final(
+unsigned char *md;
+SHA_CTX *c;
+	This function is called when a message digest of the data digested
+	with SHA_Update() is wanted.  The message digest is put in the 'md'
+	array and is SHA_DIGEST_LENGTH (20) bytes long.
+
+unsigned char *SHA(
+unsigned char *d;
+unsigned long n;
+unsigned char *md;
+	This function performs a SHA_Init(), followed by a SHA_Update()
+	followed by a SHA_Final() (using a local SHA_CTX).
+	The resulting digest is put into 'md' if it is not NULL.
+	Regardless of the value of 'md', the message
+	digest is returned from the function.  If 'md' was NULL, the message
+	digest returned is being stored in a static structure.
+	
+
+==== speed.doc ========================================================
+
+To get an idea of the performance of this library, use
+ssleay speed
+
+perl util/sp-diff.pl file1 file2
+
+will print out the relative differences between the 2 files which are
+expected to be the output from the speed program.
+
+The performace of the library is very dependant on the Compiler
+quality and various flags used to build.
+
+---
+
+These are some numbers I did comparing RSAref and SSLeay on a Pentium 100.
+[ These numbers are all out of date, as of SSL - 0.6.1 the RSA
+operations are about 2 times faster, so check the version number ]
+
+RSA performance.
+
+SSLeay 0.6.0
+Pentium 100, 32meg, Windows NT Workstation 3.51
+linux - gcc v 2.7.0 -O3 -fomit-frame-pointer -m486
+and
+Windows NT  - Windows NT 3.51 - Visual C++ 4.1   - 586 code + 32bit assember
+Windows 3.1 - Windows NT 3.51 - Visual C++ 1.52c - 286 code + 32bit assember
+NT Dos Shell- Windows NT 3.51 - Visual C++ 1.52c - 286 code + 16bit assember
+
+Times are how long it takes to do an RSA private key operation.
+
+	       512bits 1024bits
+-------------------------------
+SSLeay NT dll	0.042s   0.202s see above
+SSLeay linux	0.046s   0.218s	Assember inner loops (normal build) 
+SSLeay linux	0.067s   0.380s Pure C code with BN_LLONG defined
+SSLeay W3.1 dll	0.108s 	 0.478s see above
+SSLeay linux	0.109s   0.713s C without BN_LLONG.
+RSAref2.0 linux	0.149s   0.936s
+SSLeay MS-DOS	0.197s   1.049s see above
+
+486DX66, 32meg, Windows NT Server 3.51
+	       512bits 1024bits
+-------------------------------
+SSLeay NT dll   0.084s	 0.495s	<- SSLeay 0.6.3
+SSLeay NT dll   0.154s   0.882s
+SSLeay W3.1 dll 0.335s   1.538s
+SSLeay MS-DOS	0.490s   2.790s
+
+What I find cute is that I'm still faster than RSAref when using standard C,
+without using the 'long long' data type :-), %35 faster for 512bit and we
+scale up to 3.2 times faster for the 'default linux' build.  I should mention
+that people should 'try' to use either x86-lnx.s (elf), x86-lnxa.s or
+x86-sol.s for any x86 based unix they are building on.  The only problems
+with be with syntax but the performance gain is quite large, especially for
+servers.  The code is very simple, you just need to modify the 'header'.
+
+The message is, if you are stuck using RSAref, the RSA performance will be
+bad. Considering the code was compiled for a pentium, the 486DX66 number
+would indicate 'Use RSAref and turn you Pentium 100 into a 486DX66' :-). 
+[ As of verson 0.6.1, it would be correct to say 'turn you pentium 100
+ into a 486DX33' :-) ]
+
+I won't tell people if the DLL's are using RSAref or my stuff if no-one
+asks :-).
+
+eric
+
+PS while I know I could speed things up further, I will probably not do
+   so due to the effort involved.  I did do some timings on the
+   SSLeay bignum format -> RSAref number format conversion that occurs
+   each time RSAref is used by SSLeay, and the numbers are trivial.
+   0.00012s a call for 512bit vs 0.149s for the time spent in the function.
+   0.00018s for 1024bit vs 0.938s.  Insignificant.
+   So the 'way to go', to support faster RSA libraries, if people are keen,
+   is to write 'glue' code in a similar way that I do for RSAref and send it
+   to me :-).
+   My base library still has the advantage of being able to operate on 
+   any size numbers, and is not that far from the performance from the
+   leaders in the field. (-%30?)
+   [ Well as of 0.6.1 I am now the leader in the filed on x86 (we at
+     least very close :-) ]
+
+   I suppose I should also mention some other numbers RSAref numbers, again
+   on my Pentium.
+		DES CBC		EDE-DES		MD5
+   RSAref linux	 830k/s		 302k/s		4390k/s
+   SSLeay linux  855k/s          319k/s        10025k/s
+   SSLeay NT	1158k/s		 410k/s	       10470k/s
+   SSLeay w31	 378k/s		 143k/s         2383k/s (fully 16bit)
+
+   Got to admit that Visual C++ 4.[01] is a damn fine compiler :-)
+--
+Eric Young                  | BOOL is tri-state according to Bill Gates.
+AARNet: eay@cryptsoft.com   | RTFM Win32 GetMessage().
+
+
+
+
+==== ssl-ciph.doc ========================================================
+
+This is a quick high level summery of how things work now.
+
+Each SSLv2 and SSLv3 cipher is composed of 4 major attributes plus a few extra
+minor ones.
+
+They are 'The key exchange algorithm', which is RSA for SSLv2 but can also
+be Diffle-Hellman for SSLv3.
+
+An 'Authenticion algorithm', which can be RSA, Diffle-Helman, DSS or
+none.
+
+The cipher
+
+The MAC digest.
+
+A cipher can also be an export cipher and is either an SSLv2 or a
+SSLv3 ciphers.
+
+To specify which ciphers to use, one can either specify all the ciphers,
+one at a time, or use 'aliases' to specify the preference and order for
+the ciphers.
+
+There are a large number of aliases, but the most importaint are
+kRSA, kDHr, kDHd and kEDH for key exchange types.
+
+aRSA, aDSS, aNULL and aDH for authentication
+DES, 3DES, RC4, RC2, IDEA and eNULL for ciphers
+MD5, SHA0 and SHA1 digests
+
+Now where this becomes interesting is that these can be put together to
+specify the order and ciphers you wish to use.
+
+To speed this up there are also aliases for certian groups of ciphers.
+The main ones are
+SSLv2	- all SSLv2 ciphers
+SSLv3	- all SSLv3 ciphers
+EXP	- all export ciphers
+LOW	- all low strngth ciphers (no export ciphers, normally single DES)
+MEDIUM	- 128 bit encryption
+HIGH	- Triple DES
+
+These aliases can be joined in a : separated list which specifies to
+add ciphers, move them to the current location and delete them.
+
+A simpler way to look at all of this is to use the 'ssleay ciphers -v' command.
+The default library cipher spec is
+!ADH:RC4+RSA:HIGH:MEDIUM:LOW:EXP:+SSLv2:+EXP
+which means, first, remove from consideration any ciphers that do not
+authenticate.  Next up, use ciphers using RC4 and RSA.  Next include the HIGH,
+MEDIUM and the LOW security ciphers.  Finish up by adding all the export
+ciphers on the end, then 'pull' all the SSLv2 and export ciphers to
+the end of the list.
+
+The results are
+$ ssleay ciphers -v '!ADH:RC4+RSA:HIGH:MEDIUM:LOW:EXP:+SSLv2:+EXP'
+
+RC4-SHA                 SSLv3 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=SHA1
+RC4-MD5                 SSLv3 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=MD5 
+EDH-RSA-DES-CBC3-SHA    SSLv3 Kx=DH       Au=RSA  Enc=3DES(168) Mac=SHA1
+EDH-DSS-DES-CBC3-SHA    SSLv3 Kx=DH       Au=DSS  Enc=3DES(168) Mac=SHA1
+DES-CBC3-SHA            SSLv3 Kx=RSA      Au=RSA  Enc=3DES(168) Mac=SHA1
+IDEA-CBC-MD5            SSLv3 Kx=RSA      Au=RSA  Enc=IDEA(128) Mac=SHA1
+EDH-RSA-DES-CBC-SHA     SSLv3 Kx=DH       Au=RSA  Enc=DES(56)   Mac=SHA1
+EDH-DSS-DES-CBC-SHA     SSLv3 Kx=DH       Au=DSS  Enc=DES(56)   Mac=SHA1
+DES-CBC-SHA             SSLv3 Kx=RSA      Au=RSA  Enc=DES(56)   Mac=SHA1
+DES-CBC3-MD5            SSLv2 Kx=RSA      Au=RSA  Enc=3DES(168) Mac=MD5 
+DES-CBC-MD5             SSLv2 Kx=RSA      Au=RSA  Enc=DES(56)   Mac=MD5 
+IDEA-CBC-MD5            SSLv2 Kx=RSA      Au=RSA  Enc=IDEA(128) Mac=MD5 
+RC2-CBC-MD5             SSLv2 Kx=RSA      Au=RSA  Enc=RC2(128)  Mac=MD5 
+RC4-MD5                 SSLv2 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=MD5 
+EXP-EDH-RSA-DES-CBC     SSLv3 Kx=DH(512)  Au=RSA  Enc=DES(40)   Mac=SHA1 export
+EXP-EDH-DSS-DES-CBC-SHA SSLv3 Kx=DH(512)  Au=DSS  Enc=DES(40)   Mac=SHA1 export
+EXP-DES-CBC-SHA         SSLv3 Kx=RSA(512) Au=RSA  Enc=DES(40)   Mac=SHA1 export
+EXP-RC2-CBC-MD5         SSLv3 Kx=RSA(512) Au=RSA  Enc=RC2(40)   Mac=MD5  export
+EXP-RC4-MD5             SSLv3 Kx=RSA(512) Au=RSA  Enc=RC4(40)   Mac=MD5  export
+EXP-RC2-CBC-MD5         SSLv2 Kx=RSA(512) Au=RSA  Enc=RC2(40)   Mac=MD5  export
+EXP-RC4-MD5             SSLv2 Kx=RSA(512) Au=RSA  Enc=RC4(40)   Mac=MD5  export
+
+I would recoment people use the 'ssleay ciphers -v "text"'
+command to check what they are going to use.
+
+Anyway, I'm falling asleep here so I'll do some more tomorrow.
+
+eric
+
+==== ssl.doc ========================================================
+
+SSL_CTX_sessions(SSL_CTX *ctx) - the session-id hash table.
+
+/* Session-id cache stats */
+SSL_CTX_sess_number
+SSL_CTX_sess_connect
+SSL_CTX_sess_connect_good
+SSL_CTX_sess_accept
+SSL_CTX_sess_accept_good
+SSL_CTX_sess_hits
+SSL_CTX_sess_cb_hits
+SSL_CTX_sess_misses
+SSL_CTX_sess_timeouts
+
+/* Session-id application notification callbacks */
+SSL_CTX_sess_set_new_cb
+SSL_CTX_sess_get_new_cb
+SSL_CTX_sess_set_get_cb
+SSL_CTX_sess_get_get_cb
+
+/* Session-id cache operation mode */
+SSL_CTX_set_session_cache_mode
+SSL_CTX_get_session_cache_mode
+
+/* Set default timeout values to use. */
+SSL_CTX_set_timeout
+SSL_CTX_get_timeout
+
+/* Global  SSL initalisation informational callback */
+SSL_CTX_set_info_callback
+SSL_CTX_get_info_callback
+SSL_set_info_callback
+SSL_get_info_callback
+
+/* If the SSL_accept/SSL_connect returned with -1, these indicate when
+ * we should re-call *.
+SSL_want
+SSL_want_nothing
+SSL_want_read
+SSL_want_write
+SSL_want_x509_lookup
+
+/* Where we are in SSL initalisation, used in non-blocking, perhaps
+ * have a look at ssl/bio_ssl.c */
+SSL_state
+SSL_is_init_finished
+SSL_in_init
+SSL_in_connect_init
+SSL_in_accept_init
+
+/* Used to set the 'inital' state so SSL_in_connect_init and SSL_in_accept_init
+ * can be used to work out which function to call. */
+SSL_set_connect_state
+SSL_set_accept_state
+
+/* Where to look for certificates for authentication */
+SSL_set_default_verify_paths /* calles SSL_load_verify_locations */
+SSL_load_verify_locations
+
+/* get info from an established connection */
+SSL_get_session
+SSL_get_certificate
+SSL_get_SSL_CTX
+
+SSL_CTX_new
+SSL_CTX_free
+SSL_new
+SSL_clear
+SSL_free
+
+SSL_CTX_set_cipher_list
+SSL_get_cipher
+SSL_set_cipher_list
+SSL_get_cipher_list
+SSL_get_shared_ciphers
+
+SSL_accept
+SSL_connect
+SSL_read
+SSL_write
+
+SSL_debug
+
+SSL_get_read_ahead
+SSL_set_read_ahead
+SSL_set_verify
+
+SSL_pending
+
+SSL_set_fd
+SSL_set_rfd
+SSL_set_wfd
+SSL_set_bio
+SSL_get_fd
+SSL_get_rbio
+SSL_get_wbio
+
+SSL_use_RSAPrivateKey
+SSL_use_RSAPrivateKey_ASN1
+SSL_use_RSAPrivateKey_file
+SSL_use_PrivateKey
+SSL_use_PrivateKey_ASN1
+SSL_use_PrivateKey_file
+SSL_use_certificate
+SSL_use_certificate_ASN1
+SSL_use_certificate_file
+
+ERR_load_SSL_strings
+SSL_load_error_strings
+
+/* human readable version of the 'state' of the SSL connection. */
+SSL_state_string
+SSL_state_string_long
+/* These 2 report what kind of IO operation the library was trying to
+ * perform last.  Probably not very usefull. */
+SSL_rstate_string
+SSL_rstate_string_long
+
+SSL_get_peer_certificate
+
+SSL_SESSION_new
+SSL_SESSION_print_fp
+SSL_SESSION_print
+SSL_SESSION_free
+i2d_SSL_SESSION
+d2i_SSL_SESSION
+
+SSL_get_time
+SSL_set_time
+SSL_get_timeout
+SSL_set_timeout
+SSL_copy_session_id
+SSL_set_session
+SSL_CTX_add_session
+SSL_CTX_remove_session
+SSL_CTX_flush_sessions
+
+BIO_f_ssl
+
+/* used to hold information as to why a certificate verification failed */
+SSL_set_verify_result
+SSL_get_verify_result
+
+/* can be used by the application to associate data with an SSL structure.
+ * It needs to be 'free()ed' by the application */
+SSL_set_app_data
+SSL_get_app_data
+
+/* The following all set values that are kept in the SSL_CTX but
+ * are used as the default values when an SSL session is created.
+ * They are over writen by the relevent SSL_xxxx functions */
+
+/* SSL_set_verify */
+void SSL_CTX_set_default_verify
+
+/* This callback, if set, totaly overrides the normal SSLeay verification
+ * functions and should return 1 on success and 0 on failure */
+void SSL_CTX_set_cert_verify_callback
+
+/* The following are the same as the equivilent SSL_xxx functions.
+ * Only one copy of this information is kept and if a particular
+ * SSL structure has a local override, it is totally separate structure.
+ */
+int SSL_CTX_use_RSAPrivateKey
+int SSL_CTX_use_RSAPrivateKey_ASN1
+int SSL_CTX_use_RSAPrivateKey_file
+int SSL_CTX_use_PrivateKey
+int SSL_CTX_use_PrivateKey_ASN1
+int SSL_CTX_use_PrivateKey_file
+int SSL_CTX_use_certificate
+int SSL_CTX_use_certificate_ASN1
+int SSL_CTX_use_certificate_file
+
+
+==== ssl_ctx.doc ========================================================
+
+This is now a bit dated, quite a few of the SSL_ functions could be
+SSL_CTX_ functions.  I will update this in the future. 30 Aug 1996
+
+From eay@orb.mincom.oz.au Mon Dec 11 21:37:08 1995
+Received: by orb.mincom.oz.au id AA00696
+  (5.65c/IDA-1.4.4 for eay); Mon, 11 Dec 1995 11:37:08 +1000
+Date: Mon, 11 Dec 1995 11:37:08 +1000 (EST)
+From: Eric Young <eay@mincom.oz.au>
+X-Sender: eay@orb
+To: sameer <sameer@c2.org>
+Cc: Eric Young <eay@mincom.oz.au>
+Subject: Re: PEM_readX509 oesn't seem to be working
+In-Reply-To: <199512110102.RAA12521@infinity.c2.org>
+Message-Id: <Pine.SOL.3.91.951211112115.28608D-100000@orb>
+Mime-Version: 1.0
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+Status: RO
+X-Status: 
+
+On Sun, 10 Dec 1995, sameer wrote:
+> 	OK, that's solved. I've found out that it is saying "no
+> certificate set" in SSL_accept because s->conn == NULL
+> so there is some place I need to initialize s->conn that I am
+> not initializing it.
+
+The full order of things for a server should be.
+
+ctx=SSL_CTX_new();
+
+/* The next line should not really be using ctx->cert but I'll leave it 
+ * this way right now... I don't want a X509_ routine to know about an SSL
+ * structure, there should be an SSL_load_verify_locations... hmm, I may 
+ * add it tonight.
+ */
+X509_load_verify_locations(ctx->cert,CAfile,CApath);
+
+/* Ok now for each new connection we do the following */
+con=SSL_new(ctx);
+SSL_set_fd(con,s);
+SSL_set_verify(con,verify,verify_callback);
+
+/* set the certificate and private key to use. */
+SSL_use_certificate_ASN1(con,X509_certificate);
+SSL_use_RSAPrivateKey_ASN1(con,RSA_private_key);
+
+SSL_accept(con);
+
+SSL_read(con)/SSL_write(con);
+
+There is a bit more than that but that is basically the structure.
+
+Create a context and specify where to lookup certificates.
+
+foreach connection
+	{
+	create a SSL structure
+	set the certificate and private key
+	do a SSL_accept
+	
+	we should now be ok
+	}
+
+eric
+--
+Eric Young                  | Signature removed since it was generating
+AARNet: eay@mincom.oz.au    | more followups than the message contents :-)
+
+
+
+==== ssleay.doc ========================================================
+
+SSLeay: a cryptographic kitchen sink.
+
+1st December 1995
+Way back at the start of April 1995, I was looking for a mindless
+programming project.  A friend of mine (Tim Hudson) said "why don't you do SSL,
+it has DES encryption in it and I would not mind using it in a SSL telnet".
+While it was true I had written a DES library in previous years, litle
+did I know what an expansive task SSL would turn into.
+
+First of all, the SSL protocol contains DES encryption.  Well and good.  My
+DES library was fast and portable.  It also contained the RSA's RC4 stream
+cipher.  Again, not a problem, some-one had just posted to sci.crypt
+something that was claimed to be RC4.  It also contained IDEA, I had the
+specifications, not a problem to implement.  MD5, an RFC, trivial, at most
+I could spend a week or so trying to see if I could speed up the
+implementation.  All in all a nice set of ciphers.
+Then the first 'expantion of the scope', RSA public key
+encryption.  Since I did not knowing a thing about public key encryption
+or number theory, this appeared quite a daunting task.  Just writing a
+big number library would be problomatic in itself, let alone making it fast.
+At this point the scope of 'implementing SSL' expands eponentialy.
+First of all, the RSA private keys  were being kept in ASN.1 format.
+Thankfully the RSA PKCS series of documents explains this format.  So I now
+needed to be able to encode and decode arbitary ASN.1 objects.  The Public
+keys were embeded in X509 certificates.  Hmm... these are not only
+ASN.1 objects but they make up a heirachy of authentication.  To
+authenticate a X509 certificate one needs to retrieve it's issuers
+certificate etc etc.  Hmm..., so I also need to implement some kind
+of certificate management software.  I would also have to implement
+software to authenticate certificates.  At this point the support code made
+the SSL part of my library look quite small.
+Around this time, the first version of SSLeay was released.
+
+Ah, but here was the problem, I was not happy with the code so far.  As may
+have become obvious, I had been treating all of this as a learning
+exersize, so I have completely written the library myself.  As such, due
+to the way it had grown like a fungus, much of the library was not
+'elagent' or neat.  There were global and static variables all over the
+place, the SSL part did not even handle non-blocking IO.
+The Great rewrite began.
+
+As of this point in time, the 'Great rewrite' has almost finished.  So what
+follows is an approximate list of what is actually SSLeay 0.5.0
+
+/********* This needs to be updated for 0.6.0+ *************/
+
+---
+The library contains the following routines.  Please note that most of these
+functions are not specfic for SSL or any other particular cipher
+implementation.  I have tried to make all the routines as general purpose
+as possible.  So you should not think of this library as an SSL
+implemtation, but rather as a library of cryptographic functions
+that also contains SSL.  I refer to each of these function groupings as
+libraries since they are often capable of functioning as independant
+libraries
+
+First up, the general ciphers and message digests supported by the library.
+
+MD2	rfc???, a standard 'by parts' interface to this algorithm.
+MD5	rfc???, the same type of interface as for the MD2 library except a
+	different algorithm.
+SHA	THe Secure Hash Algorithm.  Again the same type of interface as
+	MD2/MD5 except the digest is 20 bytes.
+SHA1	The 'revised' version of SHA.  Just about identical to SHA except
+	for one tweak of an inner loop.
+DES	This is my libdes library that has been floating around for the last
+	few years.  It has been enhanced for no other reason than completeness.
+	It now supports ecb, cbc, cfb, ofb, cfb64, ofb64 in normal mode and
+	triple DES modes of ecb, cbc, cfb64 and ofb64.  cfb64 and ofb64 are
+	functional interfaces to the 64 bit modes of cfb and ofb used in
+	such a way thay they function as single character interfaces.
+RC4	The RSA Inc. stream cipher.
+RC2	The RSA Inc. block cipher.
+IDEA	An implmentation of the IDEA cipher, the library supports ecb, cbc,
+	cfb64 and ofb64 modes of operation.
+
+Now all the above mentioned ciphers and digests libraries support high
+speed, minimal 'crap in the way' type interfaces.  For fastest and
+lowest level access, these routines should be used directly.
+
+Now there was also the matter of public key crypto systems.  These are
+based on large integer arithmatic.
+
+BN	This is my large integer library.  It supports all the normal
+	arithmentic operations.  It uses malloc extensivly and as such has
+	no limits of the size of the numbers being manipulated.  If you
+	wish to use 4000 bit RSA moduli, these routines will handle it.
+	This library also contains routines to 'generate' prime numbers and
+	to test for primality.  The RSA and DH libraries sit on top of this
+	library.  As of this point in time, I don't support SHA, but
+	when I do add it, it will just sit on top of the routines contained
+	in this library.
+RSA	This implements the RSA public key algorithm.  It also contains
+	routines that will generate a new private/public key pair.
+	All the RSA functions conform to the PKCS#1 standard.
+DH	This is an implementation of the
+	Diffie-Hellman protocol.  There are all the require routines for
+	the protocol, plus extra routines that can be used to generate a
+	strong prime for use with a specified generator.  While this last
+	routine is not generally required by applications implementing DH,
+	It is present for completeness and because I thing it is much
+	better to be able to 'generate' your own 'magic' numbers as oposed
+	to using numbers suplied by others.  I conform to the PKCS#3
+	standard where required.
+
+You may have noticed the preceeding section mentions the 'generation' of
+prime numbers.  Now this requries the use of 'random numbers'. 
+
+RAND	This psuedo-random number library is based on MD5 at it's core
+	and a large internal state (2k bytes).  Once you have entered enough
+	seed data into this random number algorithm I don't feel
+	you will ever need to worry about it generating predictable output.
+	Due to the way I am writing a portable library, I have left the
+	issue of how to get good initial random seed data upto the
+	application but I do have support routines for saving and loading a
+	persistant random number state for use between program runs.
+	
+Now to make all these ciphers easier to use, a higher level
+interface was required.  In this form, the same function would be used to
+encrypt 'by parts', via any one of the above mentioned ciphers.
+
+EVP	The Digital EnVeloPe library is quite large.  At it's core are
+	function to perform encryption and decryption by parts while using
+	an initial parameter to specify which of the 17 different ciphers
+	or 4 different message digests to use.  On top of these are implmented
+	the digital signature functions, sign, verify, seal and open.
+	Base64 encoding of binary data is also done in this library.
+
+PEM	rfc???? describe the format for Privacy Enhanced eMail.
+	As part of this standard, methods of encoding digital enveloped
+	data is an ascii format are defined.  As such, I use a form of these
+	to encode enveloped data.  While at this point in time full support
+	for PEM has not been built into the library, a minimal subset of
+	the secret key and Base64 encoding is present.  These reoutines are
+	mostly used to Ascii encode binary data with a 'type' associated
+	with it and perhaps details of private key encryption used to
+	encrypt the data.
+	
+PKCS7	This is another Digital Envelope encoding standard which uses ASN.1
+	to encode the data.  At this point in time, while there are some
+	routines to encode and decode this binary format, full support is
+	not present.
+	
+As Mentioned, above, there are several different ways to encode
+data structures.
+
+ASN1	This library is more a set of primatives used to encode the packing
+	and unpacking of data structures.  It is used by the X509
+	certificate standard and by the PKCS standards which are used by
+	this library.  It also contains routines for duplicating and signing
+	the structures asocisated with X509.
+	
+X509	The X509 library contains routines for packing and unpacking,
+	verifying and just about every thing else you would want to do with
+	X509 certificates.
+
+PKCS7	PKCS-7 is a standard for encoding digital envelope data
+	structures.  At this point in time the routines will load and save
+	DER forms of these structees.  They need to be re-worked to support
+	the BER form which is the normal way PKCS-7 is encoded.  If the
+	previous 2 sentances don't make much sense, don't worry, this
+	library is not used by this version of SSLeay anyway.
+
+OBJ	ASN.1 uses 'object identifiers' to identify objects.  A set of
+	functions were requred to translate from ASN.1 to an intenger, to a
+	character string.  This library provieds these translations
+	
+Now I mentioned an X509 library.  X509 specified a hieachy of certificates
+which needs to be traversed to authenticate particular certificates.
+
+METH	This library is used to push 'methods' of retrieving certificates
+	into the library.  There are some supplied 'methods' with SSLeay
+	but applications can add new methods if they so desire.
+	This library has not been finished and is not being used in this
+	version.
+	
+Now all the above are required for use in the initial point of this project.
+
+SSL	The SSL protocol.  This is a full implmentation of SSL v 2.  It
+	support both server and client authentication.  SSL v 3 support
+	will be added when the SSL v 3 specification is released in it's
+	final form.
+
+Now quite a few of the above mentioned libraries rely on a few 'complex'
+data structures.  For each of these I have a library.
+
+Lhash	This is a hash table library which is used extensivly.
+
+STACK	An implemetation of a Stack data structure.
+
+BUF	A simple character array structure that also support a function to
+	check that the array is greater that a certain size, if it is not,
+	it is realloced so that is it.
+	
+TXT_DB	A simple memory based text file data base.  The application can specify
+	unique indexes that will be enforced at update time.
+
+CONF	Most of the programs written for this library require a configuration
+	file.  Instead of letting programs constantly re-implment this
+	subsystem, the CONF library provides a consistant and flexable
+	interface to not only configuration files but also environment
+	variables.
+
+But what about when something goes wrong?
+The one advantage (and perhaps disadvantage) of all of these
+functions being in one library was the ability to implement a
+single error reporting system.
+	
+ERR	This library is used to report errors.  The error system records
+	library number, function number (in the library) and reason
+	number.  Multiple errors can be reported so that an 'error' trace
+	is created.  The errors can be printed in numeric or textual form.
+
+
+==== ssluse.doc ========================================================
+
+We have an SSL_CTX which contains global information for lots of
+SSL connections.  The session-id cache and the certificate verificate cache.
+It also contains default values for use when certificates are used.
+
+SSL_CTX
+	default cipher list
+	session-id cache
+	certificate cache
+	default session-id timeout period
+	New session-id callback
+	Required session-id callback
+	session-id stats
+	Informational callback
+	Callback that is set, overrides the SSLeay X509 certificate
+	  verification
+	The default Certificate/Private Key pair
+	Default read ahead mode.
+	Default verify mode and verify callback.  These are not used
+	  if the over ride callback mentioned above is used.
+	
+Each SSL can have the following defined for it before a connection is made.
+
+Certificate
+Private key
+Ciphers to use
+Certificate verify mode and callback
+IO object to use in the comunication.
+Some 'read-ahead' mode information.
+A previous session-id to re-use.
+
+A connection is made by using SSL_connect or SSL_accept.
+When non-blocking IO is being used, there are functions that can be used
+to determin where and why the SSL_connect or SSL_accept did not complete.
+This information can be used to recall the functions when the 'error'
+condition has dissapeared.
+
+After the connection has been made, information can be retrived about the
+SSL session and the session-id values that have been decided upon.
+The 'peer' certificate can be retrieved.
+
+The session-id values include
+'start time'
+'timeout length'
+
+
+
+==== stack.doc ========================================================
+
+The stack data structure is used to store an ordered list of objects.
+It is basically misnamed to call it a stack but it can function that way
+and that is what I originally used it for.  Due to the way element
+pointers are kept in a malloc()ed array, the most efficient way to use this
+structure is to add and delete elements from the end via sk_pop() and
+sk_push().  If you wish to do 'lookups' sk_find() is quite efficient since
+it will sort the stack (if required) and then do a binary search to lookup 
+the requested item.  This sorting occurs automatically so just sk_push()
+elements on the stack and don't worry about the order.  Do remember that if
+you do a sk_find(), the order of the elements will change.
+
+You should never need to 'touch' this structure directly.
+typedef struct stack_st
+	{
+	unsigned int num;
+	char **data;
+	int sorted;
+
+	unsigned int num_alloc;
+	int (*comp)();
+	} STACK;
+
+'num' holds the number of elements in the stack, 'data' is the array of
+elements.  'sorted' is 1 is the list has been sorted, 0 if not.
+
+num_alloc is the number of 'nodes' allocated in 'data'.  When num becomes
+larger than num_alloc, data is realloced to a larger size.
+If 'comp' is set, it is a function that is used to compare 2 of the items
+in the stack.  The function should return -1, 0 or 1, depending on the
+ordering.
+
+#define sk_num(sk)	((sk)->num)
+#define sk_value(sk,n)	((sk)->data[n])
+
+These 2 macros should be used to access the number of elements in the
+'stack' and to access a pointer to one of the values.
+
+STACK *sk_new(int (*c)());
+	This creates a new stack.  If 'c', the comparison function, is not
+specified, the various functions that operate on a sorted 'stack' will not
+work (sk_find()).  NULL is returned on failure.
+
+void sk_free(STACK *);
+	This function free()'s a stack structure.  The elements in the
+stack will not be freed so one should 'pop' and free all elements from the
+stack before calling this function or call sk_pop_free() instead.
+
+void sk_pop_free(STACK *st; void (*func)());
+	This function calls 'func' for each element on the stack, passing
+the element as the argument.  sk_free() is then called to free the 'stack'
+structure.
+
+int sk_insert(STACK *sk,char *data,int where);
+	This function inserts 'data' into stack 'sk' at location 'where'.
+If 'where' is larger that the number of elements in the stack, the element
+is put at the end.  This function tends to be used by other 'stack'
+functions.  Returns 0 on failure, otherwise the number of elements in the
+new stack.
+
+char *sk_delete(STACK *st,int loc);
+	Remove the item a location 'loc' from the stack and returns it.
+Returns NULL if the 'loc' is out of range.
+
+char *sk_delete_ptr(STACK *st, char *p);
+	If the data item pointed to by 'p' is in the stack, it is deleted
+from the stack and returned.  NULL is returned if the element is not in the
+stack.
+
+int sk_find(STACK *st,char *data);
+	Returns the location that contains a value that is equal to 
+the 'data' item.  If the comparison function was not set, this function
+does a linear search.  This function actually qsort()s the stack if it is not
+in order and then uses bsearch() to do the initial search.  If the
+search fails,, -1 is returned.  For mutliple items with the same
+value, the index of the first in the array is returned.
+
+int sk_push(STACK *st,char *data);
+	Append 'data' to the stack.  0 is returned if there is a failure
+(due to a malloc failure), else 1.  This is 
+sk_insert(st,data,sk_num(st));
+
+int sk_unshift(STACK *st,char *data);
+	Prepend 'data' to the front (location 0) of the stack.  This is
+sk_insert(st,data,0);
+
+char *sk_shift(STACK *st);
+	Return and delete from the stack the first element in the stack.
+This is sk_delete(st,0);
+
+char *sk_pop(STACK *st);
+	Return and delete the last element on the stack.  This is
+sk_delete(st,sk_num(sk)-1);
+
+void sk_zero(STACK *st);
+	Removes all items from the stack.  It does not 'free'
+pointers but is a quick way to clear a 'stack of references'.
+
+==== threads.doc ========================================================
+
+How to compile SSLeay for multi-threading.
+
+Well basically it is quite simple, set the compiler flags and build.
+I have only really done much testing under Solaris and Windows NT.
+If you library supports localtime_r() and gmtime_r() add,
+-DTHREADS to the makefile parameters.  You can probably survive with out
+this define unless you are going to have multiple threads generating
+certificates at once.  It will not affect the SSL side of things.
+
+The approach I have taken to doing locking is to make the application provide
+callbacks to perform locking and so that the SSLeay library can distinguish
+between threads (for the error state).
+
+To have a look at an example program, 'cd mt; vi mttest.c'.
+To build under solaris, sh solaris.sh, for Windows NT or Windows 95,
+win32.bat
+
+This will build mttest which will fire up 10 threads that talk SSL
+to each other 10 times.
+To enable everything to work, the application needs to call
+
+CRYPTO_set_id_callback(id_function);
+CRYPTO_set_locking_callback(locking_function);
+
+before any multithreading is started.
+id_function does not need to be defined under Windows NT or 95, the
+correct function will be called if it is not.  Under unix, getpid()
+is call if the id_callback is not defined, for Solaris this is wrong
+(since threads id's are not pid's) but under Linux it is correct
+(threads are just processes sharing the data segement).
+
+The locking_callback is used to perform locking by the SSLeay library.
+eg.
+
+void solaris_locking_callback(mode,type,file,line)
+int mode;
+int type;
+char *file;
+int line;
+	{
+	if (mode & CRYPTO_LOCK)
+		mutex_lock(&(lock_cs[type]));
+	else
+		mutex_unlock(&(lock_cs[type]));
+	}
+
+Now in this case I have used mutexes instead of read/write locks, since they
+are faster and there are not many read locks in SSLeay, you may as well
+always use write locks.  file and line are __FILE__ and __LINE__ from
+the compile and can be usefull when debugging.
+
+Now as you can see, 'type' can be one of a range of values, these values are
+defined in crypto/crypto.h
+CRYPTO_get_lock_name(type) will return a text version of what the lock is.
+There are CRYPTO_NUM_LOCKS locks required, so under solaris, the setup
+for multi-threading can be
+
+static mutex_t lock_cs[CRYPTO_NUM_LOCKS];
+
+void thread_setup()
+	{
+	int i;
+
+	for (i=0; i<CRYPTO_NUM_LOCKS; i++)
+		mutex_init(&(lock_cs[i]),USYNC_THREAD,NULL);
+	CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id);
+	CRYPTO_set_locking_callback((void (*)())solaris_locking_callback);
+	}
+
+As a final note, under Windows NT or Windows 95, you have to be careful
+not to mix the various threaded, unthreaded and debug libraries.
+Normally if they are mixed incorrectly, mttest will crash just after printing
+out some usage statistics at the end.  This is because the
+different system libraries use different malloc routines and if
+data is malloc()ed inside crypt32.dll or ssl32.dll and then free()ed by a
+different library malloc, things get very confused.
+
+The default SSLeay DLL builds use /MD, so if you use this on your
+application, things will work as expected.  If you use /MDd,
+you will probably have to rebuild SSLeay using this flag.
+I should modify util/mk1mf.pl so it does all this correctly, but 
+this has not been done yet.
+
+One last warning.  Because locking overheads are actually quite large, the
+statistics collected against the SSL_CTX for successfull connections etc
+are not locked when updated.  This does make it possible for these
+values to be slightly lower than they should be, if you are
+running multithreaded on a multi-processor box, but this does not really
+matter much.
+
+
+==== txt_db.doc ========================================================
+
+TXT_DB, a simple text based in memory database.
+
+It holds rows of ascii data, for which the only special character is '\0'.
+The rows can be of an unlimited length.
+
+==== why.doc ========================================================
+
+This file is more of a note for other people who wish to understand why
+the build environment is the way it is :-).
+
+The include files 'depend' as follows.
+Each of 
+crypto/*/*.c includes crypto/cryptlib.h
+ssl/*.c include ssl/ssl_locl.h
+apps/*.c include apps/apps.h
+crypto/cryptlib.h, ssl/ssl_locl.h and apps/apps.h
+all include e_os.h which contains OS/environment specific information.
+If you need to add something todo with a particular environment,
+add it to this file.  It is worth remembering that quite a few libraries,
+like lhash, des, md, sha etc etc do not include crypto/cryptlib.h.  This
+is because these libraries should be 'independantly compilable' and so I
+try to keep them this way.
+e_os.h is not so much a part of SSLeay, as the placing in one spot all the
+evil OS dependant muck.
+
+I wanted to automate as many things as possible.  This includes
+error number generation.  A
+make errors
+will scan the source files for error codes, append them to the correct
+header files, and generate the functions to print the text version
+of the error numbers.  So don't even think about adding error numbers by
+hand, put them in the form
+XXXerr(XXXX_F_XXXX,YYYY_R_YYYY);
+on line and it will be automatically picked up my a make errors.
+
+In a similar vein, programs to be added into ssleay in the apps directory
+just need to have an entry added to E_EXE in makefile.ssl and
+everthing will work as expected.  Don't edit progs.h by hand.
+
+make links re-generates the symbolic links that are used.  The reason why
+I keep everything in its own directory, and don't put all the
+test programs and header files in 'test' and 'include' is because I want
+to keep the 'sub-libraries' independant.  I still 'pull' out
+indervidual libraries for use in specific projects where the code is
+required.  I have used the 'lhash' library in just about every software
+project I have worked on :-).
+
+make depend generates dependancies and
+make dclean removes them.
+
+You will notice that I use perl quite a bit when I could be using 'sed'.
+The reason I decided to do this was to just stick to one 'extra' program.
+For Windows NT, I have perl and no sed.
+
+The util/mk1mf.pl program can be used to generate a single makefile.
+I use this because makefiles under Microsoft are horrific.
+Each C compiler seems to have different linker formats, which have
+to be used because the retarted C compilers explode when you do
+cl -o file *.o.
+
+Now some would argue that I should just use the single makefile.  I don't
+like it during develoment for 2 reasons.  First, the actuall make
+command takes a long time.  For my current setup, if I'm in
+crypto/bn and I type make, only the crypto/bn directory gets rebuilt,
+which is nice when you are modifying prototypes in bn.h which
+half the SSLeay depends on.  The second is that to add a new souce file
+I just plonk it in at the required spot in the local makefile.  This
+then alows me to keep things local, I don't need to modify a 'global'
+tables (the make for unix, the make for NT, the make for w31...).
+When I am ripping apart a library structure, it is nice to only
+have to worry about one directory :-).
+
+Having said all this, for the hell of it I put together 2 files that
+#include all the souce code (generated by doing a ls */*.o after a build).
+crypto.c takes only 30 seconds to build under NT and 2 minutes under linux
+for my pentium100.  Much faster that the normal build :-).
+Again, the problem is that when using libraries, every program linked
+to libcrypto.a would suddenly get 330k of library when it may only need
+1k.  This technique does look like a nice way to do shared libraries though.
+
+Oh yes, as a final note, to 'build' a distribution, I just type
+make dist.
+This cleans and packages everything.  The directory needs to be called
+SSLeay since the make does a 'cd ..' and renames and tars things up.
+
+==== req.1 ========================================================
+
+The 'req' command is used to manipulate and deal with pkcs#10
+certificate requests.
+
+It's default mode of operation is to load a certificate and then
+write it out again.
+
+By default the 'req' is read from stdin in 'PEM' format.
+The -inform option can be used to specify 'pem' format or 'der'
+format.  PEM format is the base64 encoding of the DER format.
+
+By default 'req' then writes the request back out. -outform can be used
+to indicate the desired output format, be it 'pem' or 'der'.
+
+To specify an input file, use the '-in' option and the '-out' option
+can be used to specify the output file.
+
+If you wish to perform a command and not output the certificate
+request afterwards, use the '-noout' option.
+
+When a certificate is loaded, it can be printed in a human readable
+ascii format via the '-text' option.
+
+To check that the signature on a certificate request is correct, use
+the '-verify' option to make sure that the private key contained in the
+certificate request corresponds to the signature.
+
+Besides the default mode, there is also the 'generate a certificate
+request' mode.  There are several flags that trigger this mode.
+
+-new will generate a new RSA key (if required) and then prompts
+the user for details for the certificate request.
+-newkey has an argument that is the number of bits to make the new
+key.  This function also triggers '-new'.
+
+The '-new' option can have a key to use specified instead of having to
+load one, '-key' is used to specify the file containg the key.
+-keyform can be used to specify the format of the key.  Only
+'pem' and 'der' formats are supported, later, 'netscape' format may be added.
+
+Finally there is the '-x509' options which makes req output a self
+signed x509 certificate instead of a certificate request.
+
+Now as you may have noticed, there are lots of default options that
+cannot be specified via the command line.  They are held in a 'template'
+or 'configuration file'.  The -config option specifies which configuration
+file to use.  See conf.doc for details on the syntax of this file.
+
+The req command uses the 'req' section of the config file.
+
+---
+# The following variables are defined.  For this example I will populate
+# the various values
+[ req ]
+default_bits	= 512		# default number of bits to use.
+default_keyfile	= testkey.pem	# Where to write the generated keyfile
+				# if not specified.
+distinguished_name= req_dn	# The section that contains the
+				# information about which 'object' we
+				# want to put in the DN.
+attributes	= req_attr	# The objects we want for the
+				# attributes field.
+encrypt_rsa_key	= no		# Should we encrypt newly generated
+				# keys.  I strongly recommend 'yes'.
+
+# The distinguished name section.  For the following entries, the
+# object names must exist in the SSLeay header file objects.h.  If they
+# do not, they will be silently ignored.  The entries have the following
+# format.
+# <object_name>		=> string to prompt with
+# <object_name>_default	=> default value for people
+# <object_name>_value	=> Automatically use this value for this field.
+# <object_name>_min	=> minimum number of characters for data (def. 0)
+# <object_name>_max	=> maximum number of characters for data (def. inf.)
+# All of these entries are optional except for the first one.
+[ req_dn ]
+countryName			= Country Name (2 letter code)
+countryName_default		= AU
+
+stateOrProvinceName		= State or Province Name (full name)
+stateOrProvinceName_default	= Queensland
+
+localityName			= Locality Name (eg, city)
+
+organizationName		= Organization Name (eg, company)
+organizationName_default	= Mincom Pty Ltd
+
+organizationalUnitName		= Organizational Unit Name (eg, section)
+organizationalUnitName_default	= MTR
+
+commonName			= Common Name (eg, YOUR name)
+commonName_max			= 64
+
+emailAddress			= Email Address
+emailAddress_max		= 40
+
+# The next section is the attributes section.  This is exactly the
+# same as for the previous section except that the resulting objects are
+# put in the attributes field. 
+[ req_attr ]
+challengePassword		= A challenge password
+challengePassword_min		= 4
+challengePassword_max		= 20
+
+unstructuredName		= An optional company name
+
+----
+Also note that the order that attributes appear in this file is the
+order they will be put into the distinguished name.
+
+Once this request has been generated, it can be sent to a CA for
+certifying.
+
+----
+A few quick examples....
+
+To generate a new request and a new key
+req -new
+
+To generate a new request and a 1058 bit key
+req -newkey 1058
+
+To generate a new request using a pre-existing key
+req -new -key key.pem
+
+To generate a self signed x509 certificate from a certificate
+request using a supplied key, and we want to see the text form of the
+output certificate (which we will put in the file selfSign.pem
+req -x509 -in req.pem -key key.pem -text -out selfSign.pem
+
+Verify that the signature is correct on a certificate request.
+req -verify -in req.pem
+
+Verify that the signature was made using a specified public key.
+req -verify -in req.pem -key key.pem
+
+Print the contents of a certificate request
+req -text -in req.pem
+
+==== danger ========================================================
+
+If you specify a SSLv2 cipher, and the mode is SSLv23 and the server
+can talk SSLv3, it will claim there is no cipher since you should be
+using SSLv3.
+
+When tracing debug stuff, remember BIO_s_socket() is different to
+BIO_s_connect().
+
+BSD/OS assember is not working
+
diff --git a/openssl/doc/standards.txt b/openssl/doc/standards.txt
new file mode 100644
index 0000000..7bada8d
--- /dev/null
+++ b/openssl/doc/standards.txt
@@ -0,0 +1,285 @@
+Standards related to OpenSSL
+============================
+
+[Please, this is currently a draft.  I made a first try at finding
+ documents that describe parts of what OpenSSL implements.  There are
+ big gaps, and I've most certainly done something wrong.  Please
+ correct whatever is...  Also, this note should be removed when this
+ file is reaching a somewhat correct state.        -- Richard Levitte]
+
+
+All pointers in here will be either URL's or blobs of text borrowed
+from miscellaneous indexes, like rfc-index.txt (index of RFCs),
+1id-index.txt (index of Internet drafts) and the like.
+
+To find the latest possible RFCs, it's recommended to either browse
+ftp://ftp.isi.edu/in-notes/ or go to http://www.rfc-editor.org/ and
+use the search mechanism found there.
+To find the latest possible Internet drafts, it's recommended to
+browse ftp://ftp.isi.edu/internet-drafts/.
+To find the latest possible PKCS, it's recommended to browse
+http://www.rsasecurity.com/rsalabs/pkcs/.
+
+
+Implemented:
+------------
+
+These are documents that describe things that are implemented (in
+whole or at least great parts) in OpenSSL.
+
+1319 The MD2 Message-Digest Algorithm. B. Kaliski. April 1992.
+     (Format: TXT=25661 bytes) (Status: INFORMATIONAL)
+
+1320 The MD4 Message-Digest Algorithm. R. Rivest. April 1992. (Format:
+     TXT=32407 bytes) (Status: INFORMATIONAL)
+
+1321 The MD5 Message-Digest Algorithm. R. Rivest. April 1992. (Format:
+     TXT=35222 bytes) (Status: INFORMATIONAL)
+
+2246 The TLS Protocol Version 1.0. T. Dierks, C. Allen. January 1999.
+     (Format: TXT=170401 bytes) (Status: PROPOSED STANDARD)
+
+2268 A Description of the RC2(r) Encryption Algorithm. R. Rivest.
+     January 1998. (Format: TXT=19048 bytes) (Status: INFORMATIONAL)
+
+2315 PKCS 7: Cryptographic Message Syntax Version 1.5. B. Kaliski.
+     March 1998. (Format: TXT=69679 bytes) (Status: INFORMATIONAL)
+
+PKCS#8: Private-Key Information Syntax Standard
+
+PKCS#12: Personal Information Exchange Syntax Standard, version 1.0.
+
+2560 X.509 Internet Public Key Infrastructure Online Certificate
+     Status Protocol - OCSP. M. Myers, R. Ankney, A. Malpani, S. Galperin,
+     C. Adams. June 1999. (Format: TXT=43243 bytes) (Status: PROPOSED
+     STANDARD)
+
+2712 Addition of Kerberos Cipher Suites to Transport Layer Security
+     (TLS). A. Medvinsky, M. Hur. October 1999. (Format: TXT=13763 bytes)
+     (Status: PROPOSED STANDARD)
+
+2898 PKCS #5: Password-Based Cryptography Specification Version 2.0.
+     B. Kaliski. September 2000. (Format: TXT=68692 bytes) (Status:
+     INFORMATIONAL)
+
+2986 PKCS #10: Certification Request Syntax Specification Version 1.7.
+     M. Nystrom, B. Kaliski. November 2000. (Format: TXT=27794 bytes)
+     (Obsoletes RFC2314) (Status: INFORMATIONAL)
+
+3174 US Secure Hash Algorithm 1 (SHA1). D. Eastlake 3rd, P. Jones.
+     September 2001. (Format: TXT=35525 bytes) (Status: INFORMATIONAL)
+
+3161 Internet X.509 Public Key Infrastructure, Time-Stamp Protocol (TSP)
+     C. Adams, P. Cain, D. Pinkas, R. Zuccherato. August 2001
+     (Status: PROPOSED STANDARD)
+
+3268 Advanced Encryption Standard (AES) Ciphersuites for Transport
+     Layer Security (TLS). P. Chown. June 2002. (Format: TXT=13530 bytes)
+     (Status: PROPOSED STANDARD)
+
+3279 Algorithms and Identifiers for the Internet X.509 Public Key
+     Infrastructure Certificate and Certificate Revocation List (CRL)
+     Profile. L. Bassham, W. Polk, R. Housley. April 2002. (Format:
+     TXT=53833 bytes) (Status: PROPOSED STANDARD)
+
+3280 Internet X.509 Public Key Infrastructure Certificate and
+     Certificate Revocation List (CRL) Profile. R. Housley, W. Polk, W.
+     Ford, D. Solo. April 2002. (Format: TXT=295556 bytes) (Obsoletes
+     RFC2459) (Status: PROPOSED STANDARD)
+
+3447 Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography
+     Specifications Version 2.1. J. Jonsson, B. Kaliski. February 2003.
+     (Format: TXT=143173 bytes) (Obsoletes RFC2437) (Status:           
+     INFORMATIONAL)                                         
+
+3713 A Description of the Camellia Encryption Algorithm. M. Matsui,
+     J. Nakajima, S. Moriai. April 2004. (Format: TXT=25031 bytes)
+     (Status: INFORMATIONAL)
+
+3820 Internet X.509 Public Key Infrastructure (PKI) Proxy Certificate
+     Profile. S. Tuecke, V. Welch, D. Engert, L. Pearlman, M. Thompson.
+     June 2004. (Format: TXT=86374 bytes) (Status: PROPOSED STANDARD)
+
+4132 Addition of Camellia Cipher Suites to Transport Layer Security
+     (TLS). S. Moriai, A. Kato, M. Kanda. July 2005. (Format: TXT=13590
+     bytes) (Status: PROPOSED STANDARD)
+
+4162 Addition of SEED Cipher Suites to Transport Layer Security (TLS).
+     H.J. Lee, J.H. Yoon, J.I. Lee. August 2005. (Format: TXT=10578 bytes)
+     (Status: PROPOSED STANDARD)
+
+4269 The SEED Encryption Algorithm. H.J. Lee, S.J. Lee, J.H. Yoon,
+     D.H. Cheon, J.I. Lee. December 2005. (Format: TXT=34390 bytes)
+     (Obsoletes RFC4009) (Status: INFORMATIONAL)
+
+
+Related:
+--------
+
+These are documents that are close to OpenSSL, for example the
+STARTTLS documents.
+
+1421 Privacy Enhancement for Internet Electronic Mail: Part I: Message
+     Encryption and Authentication Procedures. J. Linn. February 1993.
+     (Format: TXT=103894 bytes) (Obsoletes RFC1113) (Status: PROPOSED
+     STANDARD)
+
+1422 Privacy Enhancement for Internet Electronic Mail: Part II:
+     Certificate-Based Key Management. S. Kent. February 1993. (Format:
+     TXT=86085 bytes) (Obsoletes RFC1114) (Status: PROPOSED STANDARD)
+
+1423 Privacy Enhancement for Internet Electronic Mail: Part III:
+     Algorithms, Modes, and Identifiers. D. Balenson. February 1993.
+     (Format: TXT=33277 bytes) (Obsoletes RFC1115) (Status: PROPOSED
+     STANDARD)
+
+1424 Privacy Enhancement for Internet Electronic Mail: Part IV: Key
+     Certification and Related Services. B. Kaliski. February 1993.
+     (Format: TXT=17537 bytes) (Status: PROPOSED STANDARD)
+
+2025 The Simple Public-Key GSS-API Mechanism (SPKM). C. Adams. October
+     1996. (Format: TXT=101692 bytes) (Status: PROPOSED STANDARD)
+
+2510 Internet X.509 Public Key Infrastructure Certificate Management
+     Protocols. C. Adams, S. Farrell. March 1999. (Format: TXT=158178
+     bytes) (Status: PROPOSED STANDARD)
+
+2511 Internet X.509 Certificate Request Message Format. M. Myers, C.
+     Adams, D. Solo, D. Kemp. March 1999. (Format: TXT=48278 bytes)
+     (Status: PROPOSED STANDARD)
+
+2527 Internet X.509 Public Key Infrastructure Certificate Policy and
+     Certification Practices Framework. S. Chokhani, W. Ford. March 1999.
+     (Format: TXT=91860 bytes) (Status: INFORMATIONAL)
+
+2538 Storing Certificates in the Domain Name System (DNS). D. Eastlake
+     3rd, O. Gudmundsson. March 1999. (Format: TXT=19857 bytes) (Status:
+     PROPOSED STANDARD)
+
+2539 Storage of Diffie-Hellman Keys in the Domain Name System (DNS).
+     D. Eastlake 3rd. March 1999. (Format: TXT=21049 bytes) (Status:
+     PROPOSED STANDARD)
+
+2559 Internet X.509 Public Key Infrastructure Operational Protocols -
+     LDAPv2. S. Boeyen, T. Howes, P. Richard. April 1999. (Format:
+     TXT=22889 bytes) (Updates RFC1778) (Status: PROPOSED STANDARD)
+
+2585 Internet X.509 Public Key Infrastructure Operational Protocols:
+     FTP and HTTP. R. Housley, P. Hoffman. May 1999. (Format: TXT=14813
+     bytes) (Status: PROPOSED STANDARD)
+
+2587 Internet X.509 Public Key Infrastructure LDAPv2 Schema. S.
+     Boeyen, T. Howes, P. Richard. June 1999. (Format: TXT=15102 bytes)
+     (Status: PROPOSED STANDARD)
+
+2595 Using TLS with IMAP, POP3 and ACAP. C. Newman. June 1999.
+     (Format: TXT=32440 bytes) (Status: PROPOSED STANDARD)
+
+2631 Diffie-Hellman Key Agreement Method. E. Rescorla. June 1999.
+     (Format: TXT=25932 bytes) (Status: PROPOSED STANDARD)
+
+2632 S/MIME Version 3 Certificate Handling. B. Ramsdell, Ed.. June
+     1999. (Format: TXT=27925 bytes) (Status: PROPOSED STANDARD)
+
+2716 PPP EAP TLS Authentication Protocol. B. Aboba, D. Simon. October
+     1999. (Format: TXT=50108 bytes) (Status: EXPERIMENTAL)
+
+2773 Encryption using KEA and SKIPJACK. R. Housley, P. Yee, W. Nace.
+     February 2000. (Format: TXT=20008 bytes) (Updates RFC0959) (Status:
+     EXPERIMENTAL)
+
+2797 Certificate Management Messages over CMS. M. Myers, X. Liu, J.
+     Schaad, J. Weinstein. April 2000. (Format: TXT=103357 bytes) (Status:
+     PROPOSED STANDARD)
+
+2817 Upgrading to TLS Within HTTP/1.1. R. Khare, S. Lawrence. May
+     2000. (Format: TXT=27598 bytes) (Updates RFC2616) (Status: PROPOSED
+     STANDARD)
+
+2818 HTTP Over TLS. E. Rescorla. May 2000. (Format: TXT=15170 bytes)
+     (Status: INFORMATIONAL)
+
+2876 Use of the KEA and SKIPJACK Algorithms in CMS. J. Pawling. July
+     2000. (Format: TXT=29265 bytes) (Status: INFORMATIONAL)
+
+2984 Use of the CAST-128 Encryption Algorithm in CMS. C. Adams.
+     October 2000. (Format: TXT=11591 bytes) (Status: PROPOSED STANDARD)
+
+2985 PKCS #9: Selected Object Classes and Attribute Types Version 2.0.
+     M. Nystrom, B. Kaliski. November 2000. (Format: TXT=70703 bytes)
+     (Status: INFORMATIONAL)
+
+3029 Internet X.509 Public Key Infrastructure Data Validation and
+     Certification Server Protocols. C. Adams, P. Sylvester, M. Zolotarev,
+     R. Zuccherato. February 2001. (Format: TXT=107347 bytes) (Status:
+     EXPERIMENTAL)
+
+3039 Internet X.509 Public Key Infrastructure Qualified Certificates
+     Profile. S. Santesson, W. Polk, P. Barzin, M. Nystrom. January 2001.
+     (Format: TXT=67619 bytes) (Status: PROPOSED STANDARD)
+
+3058 Use of the IDEA Encryption Algorithm in CMS. S. Teiwes, P.
+     Hartmann, D. Kuenzi. February 2001. (Format: TXT=17257 bytes)
+     (Status: INFORMATIONAL)
+
+3161 Internet X.509 Public Key Infrastructure Time-Stamp Protocol
+     (TSP). C. Adams, P. Cain, D. Pinkas, R. Zuccherato. August 2001.
+     (Format: TXT=54585 bytes) (Status: PROPOSED STANDARD)
+
+3185 Reuse of CMS Content Encryption Keys. S. Farrell, S. Turner.
+     October 2001. (Format: TXT=20404 bytes) (Status: PROPOSED STANDARD)
+
+3207 SMTP Service Extension for Secure SMTP over Transport Layer
+     Security. P. Hoffman. February 2002. (Format: TXT=18679 bytes)
+     (Obsoletes RFC2487) (Status: PROPOSED STANDARD)
+
+3217 Triple-DES and RC2 Key Wrapping. R. Housley. December 2001.
+     (Format: TXT=19855 bytes) (Status: INFORMATIONAL)
+
+3274 Compressed Data Content Type for Cryptographic Message Syntax
+     (CMS). P. Gutmann. June 2002. (Format: TXT=11276 bytes) (Status:
+     PROPOSED STANDARD)
+
+3278 Use of Elliptic Curve Cryptography (ECC) Algorithms in
+     Cryptographic Message Syntax (CMS). S. Blake-Wilson, D. Brown, P.
+     Lambert. April 2002. (Format: TXT=33779 bytes) (Status:
+     INFORMATIONAL)
+
+3281 An Internet Attribute Certificate Profile for Authorization. S.
+     Farrell, R. Housley. April 2002. (Format: TXT=90580 bytes) (Status:
+     PROPOSED STANDARD)
+
+3369 Cryptographic Message Syntax (CMS). R. Housley. August 2002.
+     (Format: TXT=113975 bytes) (Obsoletes RFC2630, RFC3211) (Status:
+     PROPOSED STANDARD)
+
+3370 Cryptographic Message Syntax (CMS) Algorithms. R. Housley. August
+     2002. (Format: TXT=51001 bytes) (Obsoletes RFC2630, RFC3211) (Status:
+     PROPOSED STANDARD)
+
+3377 Lightweight Directory Access Protocol (v3): Technical
+     Specification. J. Hodges, R. Morgan. September 2002. (Format:
+     TXT=9981 bytes) (Updates RFC2251, RFC2252, RFC2253, RFC2254, RFC2255,
+     RFC2256, RFC2829, RFC2830) (Status: PROPOSED STANDARD)
+
+3394 Advanced Encryption Standard (AES) Key Wrap Algorithm. J. Schaad,
+     R. Housley. September 2002. (Format: TXT=73072 bytes) (Status:
+     INFORMATIONAL)
+
+3436 Transport Layer Security over Stream Control Transmission
+     Protocol. A. Jungmaier, E. Rescorla, M. Tuexen. December 2002.
+     (Format: TXT=16333 bytes) (Status: PROPOSED STANDARD)
+
+3657 Use of the Camellia Encryption Algorithm in Cryptographic 
+     Message Syntax (CMS). S. Moriai, A. Kato. January 2004.
+     (Format: TXT=26282 bytes) (Status: PROPOSED STANDARD)
+
+"Securing FTP with TLS", 01/27/2000, <draft-murray-auth-ftp-ssl-05.txt>  
+ 
+
+To be implemented:
+------------------
+
+These are documents that describe things that are planed to be
+implemented in the hopefully short future.
+
diff --git a/openssl/e_os.h b/openssl/e_os.h
new file mode 100644
index 0000000..5ceeeeb
--- /dev/null
+++ b/openssl/e_os.h
@@ -0,0 +1,746 @@
+/* e_os.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_E_OS_H
+#define HEADER_E_OS_H
+
+#include <openssl/opensslconf.h>
+
+#include <openssl/e_os2.h>
+/* <openssl/e_os2.h> contains what we can justify to make visible
+ * to the outside; this file e_os.h is not part of the exported
+ * interface. */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Used to checking reference counts, most while doing perl5 stuff :-) */
+#ifdef REF_PRINT
+#undef REF_PRINT
+#define REF_PRINT(a,b)	fprintf(stderr,"%08X:%4d:%s\n",(int)b,b->references,a)
+#endif
+
+#ifndef DEVRANDOM
+/* set this to a comma-separated list of 'random' device files to try out.
+ * My default, we will try to read at least one of these files */
+#define DEVRANDOM "/dev/urandom","/dev/random","/dev/srandom"
+#endif
+#ifndef DEVRANDOM_EGD
+/* set this to a comma-seperated list of 'egd' sockets to try out. These
+ * sockets will be tried in the order listed in case accessing the device files
+ * listed in DEVRANDOM did not return enough entropy. */
+#define DEVRANDOM_EGD "/var/run/egd-pool","/dev/egd-pool","/etc/egd-pool","/etc/entropy"
+#endif
+
+#if defined(OPENSSL_SYS_VXWORKS)
+#  define NO_SYS_PARAM_H
+#  define NO_CHMOD
+#  define NO_SYSLOG
+#endif
+  
+#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC)
+# if macintosh==1
+#  ifndef MAC_OS_GUSI_SOURCE
+#    define MAC_OS_pre_X
+#    define NO_SYS_TYPES_H
+     typedef long ssize_t;
+#  endif
+#  define NO_SYS_PARAM_H
+#  define NO_CHMOD
+#  define NO_SYSLOG
+#  undef  DEVRANDOM
+#  define GETPID_IS_MEANINGLESS
+# endif
+#endif
+
+/********************************************************************
+ The Microsoft section
+ ********************************************************************/
+/* The following is used because of the small stack in some
+ * Microsoft operating systems */
+#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYSNAME_WIN32)
+#  define MS_STATIC	static
+#else
+#  define MS_STATIC
+#endif
+
+#if defined(OPENSSL_SYS_WIN32) && !defined(WIN32)
+#  define WIN32
+#endif
+#if defined(OPENSSL_SYS_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(OPENSSL_SYS_MSDOS) && !defined(MSDOS)
+#  define MSDOS
+#endif
+
+#if defined(MSDOS) && !defined(GETPID_IS_MEANINGLESS)
+#  define GETPID_IS_MEANINGLESS
+#endif
+
+#ifdef WIN32
+#define get_last_sys_error()	GetLastError()
+#define clear_sys_error()	SetLastError(0)
+#if !defined(WINNT)
+#define WIN_CONSOLE_BUG
+#endif
+#else
+#define get_last_sys_error()	errno
+#define clear_sys_error()	errno=0
+#endif
+
+#if defined(WINDOWS)
+#define get_last_socket_error()	WSAGetLastError()
+#define clear_socket_error()	WSASetLastError(0)
+#define readsocket(s,b,n)	recv((s),(b),(n),0)
+#define writesocket(s,b,n)	send((s),(b),(n),0)
+#elif defined(__DJGPP__)
+#define WATT32
+#define get_last_socket_error()	errno
+#define clear_socket_error()	errno=0
+#define closesocket(s)		close_s(s)
+#define readsocket(s,b,n)	read_s(s,b,n)
+#define writesocket(s,b,n)	send(s,b,n,0)
+#elif defined(MAC_OS_pre_X)
+#define get_last_socket_error()	errno
+#define clear_socket_error()	errno=0
+#define closesocket(s)		MacSocket_close(s)
+#define readsocket(s,b,n)	MacSocket_recv((s),(b),(n),true)
+#define writesocket(s,b,n)	MacSocket_send((s),(b),(n))
+#elif defined(OPENSSL_SYS_VMS)
+#define get_last_socket_error() errno
+#define clear_socket_error()    errno=0
+#define ioctlsocket(a,b,c)      ioctl(a,b,c)
+#define closesocket(s)          close(s)
+#define readsocket(s,b,n)       recv((s),(b),(n),0)
+#define writesocket(s,b,n)      send((s),(b),(n),0)
+#elif defined(OPENSSL_SYS_VXWORKS)
+#define get_last_socket_error()	errno
+#define clear_socket_error()	errno=0
+#define ioctlsocket(a,b,c)	    ioctl((a),(b),(int)(c))
+#define closesocket(s)		    close(s)
+#define readsocket(s,b,n)	    read((s),(b),(n))
+#define writesocket(s,b,n)	    write((s),(char *)(b),(n))
+#elif defined(OPENSSL_SYS_BEOS_R5)
+#define get_last_socket_error() errno
+#define clear_socket_error()    errno=0
+#define FIONBIO SO_NONBLOCK
+#define ioctlsocket(a,b,c)		  setsockopt((a),SOL_SOCKET,(b),(c),sizeof(*(c)))
+#define readsocket(s,b,n)       recv((s),(b),(n),0)
+#define writesocket(s,b,n)      send((s),(b),(n),0)
+#elif defined(OPENSSL_SYS_NETWARE)
+#if defined(NETWARE_BSDSOCK)
+#define get_last_socket_error() errno
+#define clear_socket_error()    errno=0
+#define closesocket(s)          close(s)
+#define ioctlsocket(a,b,c)      ioctl(a,b,c)
+#if defined(NETWARE_LIBC)
+#define readsocket(s,b,n)       recv((s),(b),(n),0)
+#define writesocket(s,b,n)      send((s),(b),(n),0)
+#else
+#define readsocket(s,b,n)       recv((s),(char*)(b),(n),0)
+#define writesocket(s,b,n)      send((s),(char*)(b),(n),0)
+#endif
+#else
+#define get_last_socket_error()	WSAGetLastError()
+#define clear_socket_error()	WSASetLastError(0)
+#define readsocket(s,b,n)		recv((s),(b),(n),0)
+#define writesocket(s,b,n)		send((s),(b),(n),0)
+#endif
+#else
+#define get_last_socket_error()	errno
+#define clear_socket_error()	errno=0
+#define ioctlsocket(a,b,c)	ioctl(a,b,c)
+#define closesocket(s)		close(s)
+#define readsocket(s,b,n)	read((s),(b),(n))
+#define writesocket(s,b,n)	write((s),(b),(n))
+#endif
+
+#ifdef WIN16 /* never the case */
+#  define MS_CALLBACK	_far _loadds
+#  define MS_FAR	_far
+#else
+#  define MS_CALLBACK
+#  define MS_FAR
+#endif
+
+#ifdef OPENSSL_NO_STDIO
+#  undef OPENSSL_NO_FP_API
+#  define OPENSSL_NO_FP_API
+#endif
+
+#if (defined(WINDOWS) || defined(MSDOS))
+
+#  ifdef __DJGPP__
+#    include <unistd.h>
+#    include <sys/stat.h>
+#    include <sys/socket.h>
+#    include <tcp.h>
+#    include <netdb.h>
+#    define _setmode setmode
+#    define _O_TEXT O_TEXT
+#    define _O_BINARY O_BINARY
+#    undef DEVRANDOM
+#    define DEVRANDOM "/dev/urandom\x24"
+#  endif /* __DJGPP__ */
+
+#  ifndef S_IFDIR
+#    define S_IFDIR	_S_IFDIR
+#  endif
+
+#  ifndef S_IFMT
+#    define S_IFMT	_S_IFMT
+#  endif
+
+#  if !defined(WINNT) && !defined(__DJGPP__)
+#    define NO_SYSLOG
+#  endif
+#  define NO_DIRENT
+
+#  ifdef WINDOWS
+#    if !defined(_WIN32_WCE) && !defined(_WIN32_WINNT)
+       /*
+	* Defining _WIN32_WINNT here in e_os.h implies certain "discipline."
+	* Most notably we ought to check for availability of each specific
+	* routine with GetProcAddress() and/or guard NT-specific calls with
+	* GetVersion() < 0x80000000. One can argue that in latter "or" case
+	* we ought to /DELAYLOAD some .DLLs in order to protect ourselves
+	* against run-time link errors. This doesn't seem to be necessary,
+	* because it turned out that already Windows 95, first non-NT Win32
+	* implementation, is equipped with at least NT 3.51 stubs, dummy
+	* routines with same name, but which do nothing. Meaning that it's
+	* apparently sufficient to guard "vanilla" NT calls with GetVersion
+	* alone, while NT 4.0 and above interfaces ought to be linked with
+	* GetProcAddress at run-time.
+	*/
+#      define _WIN32_WINNT 0x0400
+#    endif
+#    if !defined(OPENSSL_NO_SOCK) && defined(_WIN32_WINNT)
+       /*
+        * Just like defining _WIN32_WINNT including winsock2.h implies
+        * certain "discipline" for maintaining [broad] binary compatibility.
+        * As long as structures are invariant among Winsock versions,
+        * it's sufficient to check for specific Winsock2 API availability
+        * at run-time [DSO_global_lookup is recommended]...
+        */
+#      include <winsock2.h>
+#      include <ws2tcpip.h>
+       /* yes, they have to be #included prior to <windows.h> */
+#    endif
+#    include <windows.h>
+#    include <stdio.h>
+#    include <stddef.h>
+#    include <errno.h>
+#    include <string.h>
+#    ifdef _WIN64
+#      define strlen(s) _strlen31(s)
+/* cut strings to 2GB */
+static unsigned int _strlen31(const char *str)
+	{
+	unsigned int len=0;
+	while (*str && len<0x80000000U) str++, len++;
+	return len&0x7FFFFFFF;
+	}
+#    endif
+#    include <malloc.h>
+#    if defined(_MSC_VER) && _MSC_VER<=1200 && defined(_MT) && defined(isspace)
+       /* compensate for bug in VC6 ctype.h */
+#      undef isspace
+#      undef isdigit
+#      undef isalnum
+#      undef isupper
+#      undef isxdigit
+#    endif
+#    if defined(_MSC_VER) && !defined(_DLL) && defined(stdin)
+#      if _MSC_VER>=1300
+#        undef stdin
+#        undef stdout
+#        undef stderr
+         FILE *__iob_func();
+#        define stdin  (&__iob_func()[0])
+#        define stdout (&__iob_func()[1])
+#        define stderr (&__iob_func()[2])
+#      elif defined(I_CAN_LIVE_WITH_LNK4049)
+#        undef stdin
+#        undef stdout
+#        undef stderr
+         /* pre-1300 has __p__iob(), but it's available only in msvcrt.lib,
+          * or in other words with /MD. Declaring implicit import, i.e.
+          * with _imp_ prefix, works correctly with all compiler options,
+	  * but without /MD results in LINK warning LNK4049:
+	  * 'locally defined symbol "__iob" imported'.
+          */
+         extern FILE *_imp___iob;
+#        define stdin  (&_imp___iob[0])
+#        define stdout (&_imp___iob[1])
+#        define stderr (&_imp___iob[2])
+#      endif
+#    endif
+#  endif
+#  include <io.h>
+#  include <fcntl.h>
+
+#  ifdef OPENSSL_SYS_WINCE
+#    define OPENSSL_NO_POSIX_IO
+#  endif
+
+#  define ssize_t long
+
+#  if defined (__BORLANDC__)
+#    define _setmode setmode
+#    define _O_TEXT O_TEXT
+#    define _O_BINARY O_BINARY
+#    define _int64 __int64
+#    define _kbhit kbhit
+#  endif
+
+#  define EXIT(n) exit(n)
+#  define LIST_SEPARATOR_CHAR ';'
+#  ifndef X_OK
+#    define X_OK	0
+#  endif
+#  ifndef W_OK
+#    define W_OK	2
+#  endif
+#  ifndef R_OK
+#    define R_OK	4
+#  endif
+#  define OPENSSL_CONF	"openssl.cnf"
+#  define SSLEAY_CONF	OPENSSL_CONF
+#  define NUL_DEV	"nul"
+#  define RFILE		".rnd"
+#  ifdef OPENSSL_SYS_WINCE
+#    define DEFAULT_HOME  ""
+#  else
+#    define DEFAULT_HOME  "C:"
+#  endif
+
+#else /* The non-microsoft world */
+
+#  ifdef OPENSSL_SYS_VMS
+#    define VMS 1
+  /* some programs don't include stdlib, so exit() and others give implicit 
+     function warnings */
+#    include <stdlib.h>
+#    if defined(__DECC)
+#      include <unistd.h>
+#    else
+#      include <unixlib.h>
+#    endif
+#    define OPENSSL_CONF	"openssl.cnf"
+#    define SSLEAY_CONF		OPENSSL_CONF
+#    define RFILE		".rnd"
+#    define LIST_SEPARATOR_CHAR ','
+#    define NUL_DEV		"NLA0:"
+  /* We don't have any well-defined random devices on VMS, yet... */
+#    undef DEVRANDOM
+  /* We need to do this since VMS has the following coding on status codes:
+
+     Bits 0-2: status type: 0 = warning, 1 = success, 2 = error, 3 = info ...
+               The important thing to know is that odd numbers are considered
+	       good, while even ones are considered errors.
+     Bits 3-15: actual status number
+     Bits 16-27: facility number.  0 is considered "unknown"
+     Bits 28-31: control bits.  If bit 28 is set, the shell won't try to
+                 output the message (which, for random codes, just looks ugly)
+
+     So, what we do here is to change 0 to 1 to get the default success status,
+     and everything else is shifted up to fit into the status number field, and
+     the status is tagged as an error, which I believe is what is wanted here.
+     -- Richard Levitte
+  */
+#    define EXIT(n)		do { int __VMS_EXIT = n; \
+                                     if (__VMS_EXIT == 0) \
+				       __VMS_EXIT = 1; \
+				     else \
+				       __VMS_EXIT = (n << 3) | 2; \
+                                     __VMS_EXIT |= 0x10000000; \
+				     exit(__VMS_EXIT); } while(0)
+#    define NO_SYS_PARAM_H
+
+#  elif defined(OPENSSL_SYS_NETWARE)
+#    include <fcntl.h>
+#    include <unistd.h>
+#    define NO_SYS_TYPES_H
+#    undef  DEVRANDOM
+#    ifdef NETWARE_CLIB
+#      define getpid GetThreadID
+       extern int GetThreadID(void);
+/* #      include <conio.h> */
+       extern int kbhit(void);
+#    else
+#      include <screen.h>
+#    endif
+#    define NO_SYSLOG
+#    define _setmode setmode
+#    define _kbhit kbhit
+#    define _O_TEXT O_TEXT
+#    define _O_BINARY O_BINARY
+#    define OPENSSL_CONF   "openssl.cnf"
+#    define SSLEAY_CONF    OPENSSL_CONF
+#    define RFILE    ".rnd"
+#    define LIST_SEPARATOR_CHAR ';'
+#    define EXIT(n)  { if (n) printf("ERROR: %d\n", (int)n); exit(n); }
+
+#  else
+     /* !defined VMS */
+#    ifdef OPENSSL_SYS_MPE
+#      define NO_SYS_PARAM_H
+#    endif
+#    ifdef OPENSSL_UNISTD
+#      include OPENSSL_UNISTD
+#    else
+#      include <unistd.h>
+#    endif
+#    ifndef NO_SYS_TYPES_H
+#      include <sys/types.h>
+#    endif
+#    if defined(NeXT) || defined(OPENSSL_SYS_NEWS4)
+#      define pid_t int /* pid_t is missing on NEXTSTEP/OPENSTEP
+                         * (unless when compiling with -D_POSIX_SOURCE,
+                         * which doesn't work for us) */
+#    endif
+#    if defined(NeXT) || defined(OPENSSL_SYS_NEWS4) || defined(OPENSSL_SYS_SUNOS)
+#      define ssize_t int /* ditto */
+#    endif
+#    ifdef OPENSSL_SYS_NEWS4 /* setvbuf is missing on mips-sony-bsd */
+#      define setvbuf(a, b, c, d) setbuffer((a), (b), (d))
+       typedef unsigned long clock_t;
+#    endif
+#    ifdef OPENSSL_SYS_WIN32_CYGWIN
+#      include <io.h>
+#      include <fcntl.h>
+#    endif
+
+#    define OPENSSL_CONF	"openssl.cnf"
+#    define SSLEAY_CONF		OPENSSL_CONF
+#    define RFILE		".rnd"
+#    define LIST_SEPARATOR_CHAR ':'
+#    define NUL_DEV		"/dev/null"
+#    define EXIT(n)		exit(n)
+#  endif
+
+#  define SSLeay_getpid()	getpid()
+
+#endif
+
+
+/*************/
+
+#ifdef USE_SOCKETS
+#  if defined(WINDOWS) || defined(MSDOS)
+      /* windows world */
+
+#    ifdef OPENSSL_NO_SOCK
+#      define SSLeay_Write(a,b,c)	(-1)
+#      define SSLeay_Read(a,b,c)	(-1)
+#      define SHUTDOWN(fd)		close(fd)
+#      define SHUTDOWN2(fd)		close(fd)
+#    elif !defined(__DJGPP__)
+#      if defined(_WIN32_WCE) && _WIN32_WCE<410
+#        define getservbyname _masked_declaration_getservbyname
+#      endif
+#      if !defined(IPPROTO_IP)
+         /* winsock[2].h was included already? */
+#        include <winsock.h>
+#      endif
+#      ifdef getservbyname
+#        undef getservbyname
+         /* this is used to be wcecompat/include/winsock_extras.h */
+         struct servent* PASCAL getservbyname(const char*,const char*);
+#      endif
+
+#      ifdef _WIN64
+/*
+ * Even though sizeof(SOCKET) is 8, it's safe to cast it to int, because
+ * the value constitutes an index in per-process table of limited size
+ * and not a real pointer.
+ */
+#        define socket(d,t,p)	((int)socket(d,t,p))
+#        define accept(s,f,l)	((int)accept(s,f,l))
+#      endif
+#      define SSLeay_Write(a,b,c)	send((a),(b),(c),0)
+#      define SSLeay_Read(a,b,c)	recv((a),(b),(c),0)
+#      define SHUTDOWN(fd)		{ shutdown((fd),0); closesocket(fd); }
+#      define SHUTDOWN2(fd)		{ shutdown((fd),2); closesocket(fd); }
+#    else
+#      define SSLeay_Write(a,b,c)	write_s(a,b,c,0)
+#      define SSLeay_Read(a,b,c)	read_s(a,b,c)
+#      define SHUTDOWN(fd)		close_s(fd)
+#      define SHUTDOWN2(fd)		close_s(fd)
+#    endif
+
+#  elif defined(MAC_OS_pre_X)
+
+#    include "MacSocket.h"
+#    define SSLeay_Write(a,b,c)		MacSocket_send((a),(b),(c))
+#    define SSLeay_Read(a,b,c)		MacSocket_recv((a),(b),(c),true)
+#    define SHUTDOWN(fd)		MacSocket_close(fd)
+#    define SHUTDOWN2(fd)		MacSocket_close(fd)
+
+#  elif defined(OPENSSL_SYS_NETWARE)
+         /* NetWare uses the WinSock2 interfaces by default, but can be configured for BSD
+         */
+#      if defined(NETWARE_BSDSOCK)
+#        include <sys/socket.h>
+#        include <netinet/in.h>
+#        include <sys/time.h>
+#        if defined(NETWARE_CLIB)
+#          include <sys/bsdskt.h>
+#        else
+#          include <sys/select.h>
+#        endif
+#        define INVALID_SOCKET (int)(~0)
+#      else
+#        include <novsock2.h>
+#      endif
+#      define SSLeay_Write(a,b,c)   send((a),(b),(c),0)
+#      define SSLeay_Read(a,b,c) recv((a),(b),(c),0)
+#      define SHUTDOWN(fd)    { shutdown((fd),0); closesocket(fd); }
+#      define SHUTDOWN2(fd)      { shutdown((fd),2); closesocket(fd); }
+
+#  else
+
+#    ifndef NO_SYS_PARAM_H
+#      include <sys/param.h>
+#    endif
+#    ifdef OPENSSL_SYS_VXWORKS
+#      include <time.h> 
+#    elif !defined(OPENSSL_SYS_MPE)
+#      include <sys/time.h> /* Needed under linux for FD_XXX */
+#    endif
+
+#    include <netdb.h>
+#    if defined(OPENSSL_SYS_VMS_NODECC)
+#      include <socket.h>
+#      include <in.h>
+#      include <inet.h>
+#    else
+#      include <sys/socket.h>
+#      ifdef FILIO_H
+#        include <sys/filio.h> /* Added for FIONBIO under unixware */
+#      endif
+#      include <netinet/in.h>
+#      if !defined(OPENSSL_SYS_BEOS_R5)
+#      include <arpa/inet.h>
+#    endif
+#    endif
+
+#    if defined(NeXT) || defined(_NEXT_SOURCE)
+#      include <sys/fcntl.h>
+#      include <sys/types.h>
+#    endif
+
+#    ifdef OPENSSL_SYS_AIX
+#      include <sys/select.h>
+#    endif
+
+#    ifdef __QNX__
+#      include <sys/select.h>
+#    endif
+
+#    if defined(sun)
+#      include <sys/filio.h>
+#    else
+#      ifndef VMS
+#        include <sys/ioctl.h>
+#      else
+	 /* ioctl is only in VMS > 7.0 and when socketshr is not used */
+#        if !defined(TCPIP_TYPE_SOCKETSHR) && defined(__VMS_VER) && (__VMS_VER > 70000000)
+#          include <sys/ioctl.h>
+#        endif
+#      endif
+#    endif
+
+#    ifdef VMS
+#      include <unixio.h>
+#      if defined(TCPIP_TYPE_SOCKETSHR)
+#        include <socketshr.h>
+#      endif
+#    endif
+
+#    define SSLeay_Read(a,b,c)     read((a),(b),(c))
+#    define SSLeay_Write(a,b,c)    write((a),(b),(c))
+#    define SHUTDOWN(fd)    { shutdown((fd),0); closesocket((fd)); }
+#    define SHUTDOWN2(fd)   { shutdown((fd),2); closesocket((fd)); }
+#    ifndef INVALID_SOCKET
+#    define INVALID_SOCKET	(-1)
+#    endif /* INVALID_SOCKET */
+#  endif
+
+/* Some IPv6 implementations are broken, disable them in known bad
+ * versions.
+ */
+#  if !defined(OPENSSL_USE_IPV6)
+#    if defined(AF_INET6) && !defined(OPENSSL_SYS_BEOS_BONE) && !defined(NETWARE_CLIB)
+#      define OPENSSL_USE_IPV6 1
+#    else
+#      define OPENSSL_USE_IPV6 0
+#    endif
+#  endif
+
+#endif
+
+#if defined(__ultrix)
+#  ifndef ssize_t
+#    define ssize_t int 
+#  endif
+#endif
+
+#if defined(sun) && !defined(__svr4__) && !defined(__SVR4)
+  /* include headers first, so our defines don't break it */
+#include <stdlib.h>
+#include <string.h>
+  /* bcopy can handle overlapping moves according to SunOS 4.1.4 manpage */
+# define memmove(s1,s2,n) bcopy((s2),(s1),(n))
+# define strtoul(s,e,b) ((unsigned long int)strtol((s),(e),(b)))
+extern char *sys_errlist[]; extern int sys_nerr;
+# define strerror(errnum) \
+	(((errnum)<0 || (errnum)>=sys_nerr) ? NULL : sys_errlist[errnum])
+  /* Being signed SunOS 4.x memcpy breaks ASN1_OBJECT table lookup */
+#include "crypto/o_str.h"
+# define memcmp OPENSSL_memcmp
+#endif
+
+#ifndef OPENSSL_EXIT
+# if defined(MONOLITH) && !defined(OPENSSL_C)
+#  define OPENSSL_EXIT(n) return(n)
+# else
+#  define OPENSSL_EXIT(n) do { EXIT(n); return(n); } while(0)
+# endif
+#endif
+
+/***********************************************/
+
+#define DG_GCC_BUG	/* gcc < 2.6.3 on DGUX */
+
+#ifdef sgi
+#define IRIX_CC_BUG	/* all version of IRIX I've tested (4.* 5.*) */
+#endif
+#ifdef OPENSSL_SYS_SNI
+#define IRIX_CC_BUG	/* CDS++ up to V2.0Bsomething suffered from the same bug.*/
+#endif
+
+#if defined(OPENSSL_SYS_WINDOWS)
+#  define strcasecmp _stricmp
+#  define strncasecmp _strnicmp
+#elif defined(OPENSSL_SYS_VMS)
+/* VMS below version 7.0 doesn't have strcasecmp() */
+#  include "o_str.h"
+#  define strcasecmp OPENSSL_strcasecmp
+#  define strncasecmp OPENSSL_strncasecmp
+#  define OPENSSL_IMPLEMENTS_strncasecmp
+#elif defined(OPENSSL_SYS_OS2) && defined(__EMX__)
+#  define strcasecmp stricmp
+#  define strncasecmp strnicmp
+#elif defined(OPENSSL_SYS_NETWARE)
+#  include <string.h>
+#  if defined(NETWARE_CLIB)
+#    define strcasecmp stricmp
+#    define strncasecmp strnicmp
+#  endif /* NETWARE_CLIB */
+#endif
+
+#if defined(OPENSSL_SYS_OS2) && defined(__EMX__)
+# include <io.h>
+# include <fcntl.h>
+# define NO_SYSLOG
+#endif
+
+/* vxworks */
+#if defined(OPENSSL_SYS_VXWORKS)
+#include <ioLib.h>
+#include <tickLib.h>
+#include <sysLib.h>
+
+#define TTY_STRUCT int
+
+#define sleep(a) taskDelay((a) * sysClkRateGet())
+
+#include <vxWorks.h>
+#include <sockLib.h>
+#include <taskLib.h>
+
+#define getpid taskIdSelf
+
+/* NOTE: these are implemented by helpers in database app!
+ * if the database is not linked, we need to implement them
+ * elswhere */
+struct hostent *gethostbyname(const char *name);
+struct hostent *gethostbyaddr(const char *addr, int length, int type);
+struct servent *getservbyname(const char *name, const char *proto);
+
+#endif
+/* end vxworks */
+
+/* beos */
+#if defined(OPENSSL_SYS_BEOS_R5)
+#define SO_ERROR 0
+#define NO_SYS_UN
+#define IPPROTO_IP 0
+#include <OS.h>
+#endif
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/openssl/e_os2.h b/openssl/e_os2.h
new file mode 100644
index 0000000..d30724d
--- /dev/null
+++ b/openssl/e_os2.h
@@ -0,0 +1,295 @@
+/* e_os2.h */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/opensslconf.h>
+
+#ifndef HEADER_E_OS2_H
+#define HEADER_E_OS2_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************
+ * Detect operating systems.  This probably needs completing.
+ * The result is that at least one OPENSSL_SYS_os macro should be defined.
+ * However, if none is defined, Unix is assumed.
+ **/
+
+#define OPENSSL_SYS_UNIX
+
+/* ----------------------- Macintosh, before MacOS X ----------------------- */
+#if defined(__MWERKS__) && defined(macintosh) || defined(OPENSSL_SYSNAME_MAC)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_MACINTOSH_CLASSIC
+#endif
+
+/* ----------------------- NetWare ----------------------------------------- */
+#if defined(NETWARE) || defined(OPENSSL_SYSNAME_NETWARE)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_NETWARE
+#endif
+
+/* ---------------------- Microsoft operating systems ---------------------- */
+
+/* Note that MSDOS actually denotes 32-bit environments running on top of
+   MS-DOS, such as DJGPP one. */
+#if defined(OPENSSL_SYSNAME_MSDOS)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_MSDOS
+#endif
+
+/* For 32 bit environment, there seems to be the CygWin environment and then
+   all the others that try to do the same thing Microsoft does... */
+#if defined(OPENSSL_SYSNAME_UWIN)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_WIN32_UWIN
+#else
+# if defined(__CYGWIN32__) || defined(OPENSSL_SYSNAME_CYGWIN32)
+#  undef OPENSSL_SYS_UNIX
+#  define OPENSSL_SYS_WIN32_CYGWIN
+# else
+#  if defined(_WIN32) || defined(OPENSSL_SYSNAME_WIN32)
+#   undef OPENSSL_SYS_UNIX
+#   define OPENSSL_SYS_WIN32
+#  endif
+#  if defined(OPENSSL_SYSNAME_WINNT)
+#   undef OPENSSL_SYS_UNIX
+#   define OPENSSL_SYS_WINNT
+#  endif
+#  if defined(OPENSSL_SYSNAME_WINCE)
+#   undef OPENSSL_SYS_UNIX
+#   define OPENSSL_SYS_WINCE
+#  endif
+# endif
+#endif
+
+/* Anything that tries to look like Microsoft is "Windows" */
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_WINDOWS
+# ifndef OPENSSL_SYS_MSDOS
+#  define OPENSSL_SYS_MSDOS
+# endif
+#endif
+
+/* DLL settings.  This part is a bit tough, because it's up to the application
+   implementor how he or she will link the application, so it requires some
+   macro to be used. */
+#ifdef OPENSSL_SYS_WINDOWS
+# ifndef OPENSSL_OPT_WINDLL
+#  if defined(_WINDLL) /* This is used when building OpenSSL to indicate that
+                          DLL linkage should be used */
+#   define OPENSSL_OPT_WINDLL
+#  endif
+# endif
+#endif
+
+/* -------------------------------- OpenVMS -------------------------------- */
+#if defined(__VMS) || defined(VMS) || defined(OPENSSL_SYSNAME_VMS)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_VMS
+# if defined(__DECC)
+#  define OPENSSL_SYS_VMS_DECC
+# elif defined(__DECCXX)
+#  define OPENSSL_SYS_VMS_DECC
+#  define OPENSSL_SYS_VMS_DECCXX
+# else
+#  define OPENSSL_SYS_VMS_NODECC
+# endif
+#endif
+
+/* --------------------------------- OS/2 ---------------------------------- */
+#if defined(__EMX__) || defined(__OS2__)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_OS2
+#endif
+
+/* --------------------------------- Unix ---------------------------------- */
+#ifdef OPENSSL_SYS_UNIX
+# if defined(linux) || defined(__linux__) || defined(OPENSSL_SYSNAME_LINUX)
+#  define OPENSSL_SYS_LINUX
+# endif
+# ifdef OPENSSL_SYSNAME_MPE
+#  define OPENSSL_SYS_MPE
+# endif
+# ifdef OPENSSL_SYSNAME_SNI
+#  define OPENSSL_SYS_SNI
+# endif
+# ifdef OPENSSL_SYSNAME_ULTRASPARC
+#  define OPENSSL_SYS_ULTRASPARC
+# endif
+# ifdef OPENSSL_SYSNAME_NEWS4
+#  define OPENSSL_SYS_NEWS4
+# endif
+# ifdef OPENSSL_SYSNAME_MACOSX
+#  define OPENSSL_SYS_MACOSX
+# endif
+# ifdef OPENSSL_SYSNAME_MACOSX_RHAPSODY
+#  define OPENSSL_SYS_MACOSX_RHAPSODY
+#  define OPENSSL_SYS_MACOSX
+# endif
+# ifdef OPENSSL_SYSNAME_SUNOS
+#  define OPENSSL_SYS_SUNOS
+#endif
+# if defined(_CRAY) || defined(OPENSSL_SYSNAME_CRAY)
+#  define OPENSSL_SYS_CRAY
+# endif
+# if defined(_AIX) || defined(OPENSSL_SYSNAME_AIX)
+#  define OPENSSL_SYS_AIX
+# endif
+#endif
+
+/* --------------------------------- VOS ----------------------------------- */
+#if defined(__VOS__) || defined(OPENSSL_SYSNAME_VOS)
+# define OPENSSL_SYS_VOS
+#ifdef __HPPA__
+# define OPENSSL_SYS_VOS_HPPA
+#endif
+#ifdef __IA32__
+# define OPENSSL_SYS_VOS_IA32
+#endif
+#endif
+
+/* ------------------------------- VxWorks --------------------------------- */
+#ifdef OPENSSL_SYSNAME_VXWORKS
+# define OPENSSL_SYS_VXWORKS
+#endif
+
+/* --------------------------------- BeOS ---------------------------------- */
+#if defined(__BEOS__)
+# define OPENSSL_SYS_BEOS
+# include <sys/socket.h>
+# if defined(BONE_VERSION)
+#  define OPENSSL_SYS_BEOS_BONE
+# else
+#  define OPENSSL_SYS_BEOS_R5
+# endif
+#endif
+
+/**
+ * That's it for OS-specific stuff
+ *****************************************************************************/
+
+
+/* Specials for I/O an exit */
+#ifdef OPENSSL_SYS_MSDOS
+# define OPENSSL_UNISTD_IO <io.h>
+# define OPENSSL_DECLARE_EXIT extern void exit(int);
+#else
+# define OPENSSL_UNISTD_IO OPENSSL_UNISTD
+# define OPENSSL_DECLARE_EXIT /* declared in unistd.h */
+#endif
+
+/* Definitions of OPENSSL_GLOBAL and OPENSSL_EXTERN, to define and declare
+   certain global symbols that, with some compilers under VMS, have to be
+   defined and declared explicitely with globaldef and globalref.
+   Definitions of OPENSSL_EXPORT and OPENSSL_IMPORT, to define and declare
+   DLL exports and imports for compilers under Win32.  These are a little
+   more complicated to use.  Basically, for any library that exports some
+   global variables, the following code must be present in the header file
+   that declares them, before OPENSSL_EXTERN is used:
+
+   #ifdef SOME_BUILD_FLAG_MACRO
+   # undef OPENSSL_EXTERN
+   # define OPENSSL_EXTERN OPENSSL_EXPORT
+   #endif
+
+   The default is to have OPENSSL_EXPORT, OPENSSL_IMPORT and OPENSSL_GLOBAL
+   have some generally sensible values, and for OPENSSL_EXTERN to have the
+   value OPENSSL_IMPORT.
+*/
+
+#if defined(OPENSSL_SYS_VMS_NODECC)
+# define OPENSSL_EXPORT globalref
+# define OPENSSL_IMPORT globalref
+# define OPENSSL_GLOBAL globaldef
+#elif defined(OPENSSL_SYS_WINDOWS) && defined(OPENSSL_OPT_WINDLL)
+# define OPENSSL_EXPORT extern __declspec(dllexport)
+# define OPENSSL_IMPORT extern __declspec(dllimport)
+# define OPENSSL_GLOBAL
+#else
+# define OPENSSL_EXPORT extern
+# define OPENSSL_IMPORT extern
+# define OPENSSL_GLOBAL
+#endif
+#define OPENSSL_EXTERN OPENSSL_IMPORT
+
+/* Macros to allow global variables to be reached through function calls when
+   required (if a shared library version requires it, for example.
+   The way it's done allows definitions like this:
+
+	// in foobar.c
+	OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0)
+	// in foobar.h
+	OPENSSL_DECLARE_GLOBAL(int,foobar);
+	#define foobar OPENSSL_GLOBAL_REF(foobar)
+*/
+#ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION
+# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value)			\
+	type *_shadow_##name(void)					\
+	{ static type _hide_##name=value; return &_hide_##name; }
+# define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void)
+# define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name()))
+#else
+# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) OPENSSL_GLOBAL type _shadow_##name=value;
+# define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name
+# define OPENSSL_GLOBAL_REF(name) _shadow_##name
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/Makefile b/openssl/engines/Makefile
new file mode 100644
index 0000000..2fa9534
--- /dev/null
+++ b/openssl/engines/Makefile
@@ -0,0 +1,335 @@
+#
+# OpenSSL/engines/Makefile
+#
+
+DIR=	engines
+TOP=	..
+CC=	cc
+INCLUDES= -I../include
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+ENGDIRS= ccgost
+
+RECURSIVE_MAKE=	[ -z "$(ENGDIRS)" ] || for i in $(ENGDIRS) ; do \
+		    (cd $$i && echo "making $$target in $(DIR)/$$i..." && \
+		    $(MAKE) -e TOP=../.. DIR=$$i $$target ) || exit 1; \
+		done;
+
+PEX_LIBS=
+EX_LIBS=
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile engines.com install.com engine_vector.mar
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBNAMES= 4758cca aep atalla cswift gmp chil nuron sureware ubsec padlock capi
+
+LIBSRC=	e_4758cca.c \
+	e_aep.c \
+	e_atalla.c \
+	e_cswift.c \
+	e_gmp.c \
+	e_chil.c \
+	e_nuron.c \
+	e_sureware.c \
+	e_ubsec.c \
+	e_padlock.c \
+	e_capi.c
+LIBOBJ= e_4758cca.o \
+	e_aep.o \
+	e_atalla.o \
+	e_cswift.o \
+	e_gmp.o \
+	e_chil.o \
+	e_nuron.o \
+	e_sureware.o \
+	e_ubsec.o \
+	e_padlock.o \
+	e_capi.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= 
+HEADER=	e_4758cca_err.c e_4758cca_err.h \
+	e_aep_err.c e_aep_err.h \
+	e_atalla_err.c e_atalla_err.h \
+	e_cswift_err.c e_cswift_err.h \
+	e_gmp_err.c e_gmp_err.h \
+	e_chil_err.c e_chil_err.h \
+	e_nuron_err.c e_nuron_err.h \
+	e_sureware_err.c e_sureware_err.h \
+	e_ubsec_err.c e_ubsec_err.h \
+	e_capi_err.c e_capi_err.h
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ..; $(MAKE) DIRS=$(DIR) all)
+
+all:	lib subdirs
+
+lib:	$(LIBOBJ)
+	@if [ -n "$(SHARED_LIBS)" ]; then \
+		set -e; \
+		for l in $(LIBNAMES); do \
+			$(MAKE) -f ../Makefile.shared -e \
+				LIBNAME=$$l LIBEXTRAS=e_$$l.o \
+				LIBDEPS='-L.. -lcrypto $(EX_LIBS)' \
+				link_o.$(SHLIB_TARGET); \
+		done; \
+	else \
+		$(AR) $(LIB) $(LIBOBJ); \
+		$(RANLIB) $(LIB) || echo Never mind.; \
+	fi; \
+	touch lib
+
+subdirs:
+	echo $(EDIRS)
+	@target=all; $(RECURSIVE_MAKE)
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+	@target=files; $(RECURSIVE_MAKE)
+
+links:
+	@target=links; $(RECURSIVE_MAKE)
+
+# XXXXX This currently only works on systems that use .so as suffix
+# for shared libraries as well as for Cygwin which uses the
+# dlfcn_name_converter and therefore stores the engines with .so suffix, too.
+# XXXXX This was extended to HP-UX dl targets, which use .sl suffix.
+# XXXXX This was extended to mingw targets, which use eay32.dll suffix without lib as prefix.
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@if [ -n "$(SHARED_LIBS)" ]; then \
+		set -e; \
+		$(PERL) $(TOP)/util/mkdir-p.pl $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines; \
+		for l in $(LIBNAMES); do \
+			( echo installing $$l; \
+			  pfx=lib; \
+			  if [ "$(PLATFORM)" != "Cygwin" ]; then \
+				case "$(CFLAGS)" in \
+				*DSO_BEOS*)	sfx=".so";;	\
+				*DSO_DLFCN*)	sfx=`expr "$(SHLIB_EXT)" : '.*\(\.[a-z][a-z]*\)' \| ".so"`;;	\
+				*DSO_DL*)	sfx=".sl";;	\
+				*DSO_WIN32*)	sfx="eay32.dll"; pfx=;;	\
+				*)		sfx=".bad";;	\
+				esac; \
+				cp $$pfx$$l$$sfx $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx.new; \
+			  else \
+				sfx=".so"; \
+				cp cyg$$l.dll $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx.new; \
+			  fi; \
+			  chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx.new; \
+			  mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx ); \
+		done; \
+	fi
+	@target=install; $(RECURSIVE_MAKE)
+
+tags:
+	ctags $(SRC)
+
+errors:
+	set -e; for l in $(LIBNAMES); do \
+		$(PERL) ../util/mkerr.pl -conf e_$$l.ec \
+			-nostatic -staticloader -write e_$$l.c; \
+	done
+	(cd ccgost; $(MAKE) PERL=$(PERL) errors)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+	@target=lint; $(RECURSIVE_MAKE)
+
+depend:
+	@if [ -z "$(THIS)" ]; then \
+	    $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
+	fi
+	@[ -z "$(THIS)" ] || $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+	@[ -z "$(THIS)" ] || (set -e; target=depend; $(RECURSIVE_MAKE) )
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+	@target=dclean; $(RECURSIVE_MAKE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+	@target=clean; $(RECURSIVE_MAKE)
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+e_4758cca.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_4758cca.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_4758cca.o: ../include/openssl/crypto.h ../include/openssl/dso.h
+e_4758cca.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+e_4758cca.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+e_4758cca.o: ../include/openssl/engine.h ../include/openssl/err.h
+e_4758cca.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+e_4758cca.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+e_4758cca.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+e_4758cca.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+e_4758cca.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+e_4758cca.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+e_4758cca.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+e_4758cca.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+e_4758cca.o: e_4758cca.c e_4758cca_err.c e_4758cca_err.h
+e_4758cca.o: vendor_defns/hw_4758_cca.h
+e_aep.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_aep.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_aep.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+e_aep.o: ../include/openssl/dsa.h ../include/openssl/dso.h
+e_aep.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+e_aep.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+e_aep.o: ../include/openssl/engine.h ../include/openssl/err.h
+e_aep.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+e_aep.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+e_aep.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+e_aep.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+e_aep.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+e_aep.o: ../include/openssl/sha.h ../include/openssl/stack.h
+e_aep.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
+e_aep.o: ../include/openssl/x509_vfy.h e_aep.c e_aep_err.c e_aep_err.h
+e_aep.o: vendor_defns/aep.h
+e_atalla.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_atalla.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_atalla.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+e_atalla.o: ../include/openssl/dsa.h ../include/openssl/dso.h
+e_atalla.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+e_atalla.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+e_atalla.o: ../include/openssl/engine.h ../include/openssl/err.h
+e_atalla.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+e_atalla.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+e_atalla.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+e_atalla.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+e_atalla.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+e_atalla.o: ../include/openssl/sha.h ../include/openssl/stack.h
+e_atalla.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
+e_atalla.o: ../include/openssl/x509_vfy.h e_atalla.c e_atalla_err.c
+e_atalla.o: e_atalla_err.h vendor_defns/atalla.h
+e_capi.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_capi.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_capi.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+e_capi.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+e_capi.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+e_capi.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+e_capi.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+e_capi.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+e_capi.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+e_capi.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+e_capi.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+e_capi.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h e_capi.c
+e_chil.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_chil.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_chil.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+e_chil.o: ../include/openssl/dso.h ../include/openssl/e_os2.h
+e_chil.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+e_chil.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+e_chil.o: ../include/openssl/err.h ../include/openssl/evp.h
+e_chil.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+e_chil.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+e_chil.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+e_chil.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+e_chil.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+e_chil.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+e_chil.o: ../include/openssl/sha.h ../include/openssl/stack.h
+e_chil.o: ../include/openssl/symhacks.h ../include/openssl/ui.h
+e_chil.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h e_chil.c
+e_chil.o: e_chil_err.c e_chil_err.h vendor_defns/hwcryptohook.h
+e_cswift.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_cswift.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_cswift.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+e_cswift.o: ../include/openssl/dsa.h ../include/openssl/dso.h
+e_cswift.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+e_cswift.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+e_cswift.o: ../include/openssl/engine.h ../include/openssl/err.h
+e_cswift.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+e_cswift.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+e_cswift.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+e_cswift.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+e_cswift.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+e_cswift.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+e_cswift.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+e_cswift.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h e_cswift.c
+e_cswift.o: e_cswift_err.c e_cswift_err.h vendor_defns/cswift.h
+e_gmp.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_gmp.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_gmp.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+e_gmp.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+e_gmp.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+e_gmp.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+e_gmp.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+e_gmp.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+e_gmp.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+e_gmp.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+e_gmp.o: ../include/openssl/sha.h ../include/openssl/stack.h
+e_gmp.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
+e_gmp.o: ../include/openssl/x509_vfy.h e_gmp.c
+e_nuron.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_nuron.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_nuron.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+e_nuron.o: ../include/openssl/dsa.h ../include/openssl/dso.h
+e_nuron.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+e_nuron.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+e_nuron.o: ../include/openssl/engine.h ../include/openssl/err.h
+e_nuron.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+e_nuron.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+e_nuron.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+e_nuron.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+e_nuron.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+e_nuron.o: ../include/openssl/sha.h ../include/openssl/stack.h
+e_nuron.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
+e_nuron.o: ../include/openssl/x509_vfy.h e_nuron.c e_nuron_err.c e_nuron_err.h
+e_padlock.o: ../include/openssl/aes.h ../include/openssl/asn1.h
+e_padlock.o: ../include/openssl/bio.h ../include/openssl/buffer.h
+e_padlock.o: ../include/openssl/crypto.h ../include/openssl/dso.h
+e_padlock.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+e_padlock.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+e_padlock.o: ../include/openssl/engine.h ../include/openssl/err.h
+e_padlock.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+e_padlock.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+e_padlock.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+e_padlock.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+e_padlock.o: ../include/openssl/rand.h ../include/openssl/safestack.h
+e_padlock.o: ../include/openssl/sha.h ../include/openssl/stack.h
+e_padlock.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
+e_padlock.o: ../include/openssl/x509_vfy.h e_padlock.c
+e_sureware.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_sureware.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_sureware.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+e_sureware.o: ../include/openssl/dsa.h ../include/openssl/dso.h
+e_sureware.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+e_sureware.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+e_sureware.o: ../include/openssl/engine.h ../include/openssl/err.h
+e_sureware.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+e_sureware.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+e_sureware.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+e_sureware.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+e_sureware.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+e_sureware.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+e_sureware.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+e_sureware.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+e_sureware.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+e_sureware.o: e_sureware.c e_sureware_err.c e_sureware_err.h
+e_sureware.o: vendor_defns/sureware.h
+e_ubsec.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_ubsec.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_ubsec.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+e_ubsec.o: ../include/openssl/dsa.h ../include/openssl/dso.h
+e_ubsec.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+e_ubsec.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+e_ubsec.o: ../include/openssl/engine.h ../include/openssl/err.h
+e_ubsec.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+e_ubsec.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+e_ubsec.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+e_ubsec.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+e_ubsec.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+e_ubsec.o: ../include/openssl/sha.h ../include/openssl/stack.h
+e_ubsec.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
+e_ubsec.o: ../include/openssl/x509_vfy.h e_ubsec.c e_ubsec_err.c e_ubsec_err.h
+e_ubsec.o: vendor_defns/hw_ubsec.h
diff --git a/openssl/engines/alpha.opt b/openssl/engines/alpha.opt
new file mode 100644
index 0000000..1dc71bf
--- /dev/null
+++ b/openssl/engines/alpha.opt
@@ -0,0 +1 @@
+SYMBOL_VECTOR=(bind_engine=PROCEDURE,v_check=PROCEDURE)
diff --git a/openssl/engines/axp.opt b/openssl/engines/axp.opt
new file mode 100644
index 0000000..1dc71bf
--- /dev/null
+++ b/openssl/engines/axp.opt
@@ -0,0 +1 @@
+SYMBOL_VECTOR=(bind_engine=PROCEDURE,v_check=PROCEDURE)
diff --git a/openssl/engines/capierr.bat b/openssl/engines/capierr.bat
new file mode 100644
index 0000000..274ffac
--- /dev/null
+++ b/openssl/engines/capierr.bat
@@ -0,0 +1 @@
+perl ../util/mkerr.pl -conf e_capi.ec -nostatic -staticloader -write e_capi.c
diff --git a/openssl/engines/ccgost/Makefile b/openssl/engines/ccgost/Makefile
new file mode 100644
index 0000000..dadb523
--- /dev/null
+++ b/openssl/engines/ccgost/Makefile
@@ -0,0 +1,275 @@
+DIR=ccgost
+TOP=../..
+CC=cc
+INCLUDES= -I../../include
+CFLAG=-g
+MAKEFILE= Makefile
+AR= ar r
+CFLAGS= $(INCLUDES) $(CFLAG)
+LIB=$(TOP)/libcrypto.a
+
+LIBSRC= gost2001.c gost2001_keyx.c gost89.c gost94_keyx.c gost_ameth.c gost_asn1.c gost_crypt.c gost_ctl.c gost_eng.c gosthash.c gost_keywrap.c gost_md.c gost_params.c gost_pmeth.c gost_sign.c
+
+LIBOBJ= e_gost_err.o gost2001_keyx.o gost2001.o gost89.o gost94_keyx.o gost_ameth.o gost_asn1.o gost_crypt.o gost_ctl.o gost_eng.o gosthash.o gost_keywrap.o gost_md.o gost_params.o gost_pmeth.o gost_sign.o
+
+SRC=$(LIBSRC)
+
+LIBNAME=gost
+
+top: 
+	(cd $(TOP); $(MAKE) DIRS=engines EDIRS=$(DIR) sub_all)
+
+all: lib
+
+tags:
+	ctags $(SRC)
+
+errors:
+	$(PERL) ../../util/mkerr.pl -conf gost.ec -nostatic -write $(SRC)
+
+lib: $(LIBOBJ)
+	if [ -n "$(SHARED_LIBS)" ]; then \
+		$(MAKE) -f $(TOP)/Makefile.shared -e \
+			LIBNAME=$(LIBNAME) \
+			LIBEXTRAS='$(LIBOBJ)' \
+			LIBDEPS='-L$(TOP) -lcrypto' \
+			link_o.$(SHLIB_TARGET); \
+	else \
+		$(AR) $(LIB) $(LIBOBJ); \
+	fi
+	@touch lib
+
+install:
+	[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	if [ -n "$(SHARED_LIBS)" ]; then \
+		set -e; \
+		echo installing $(LIBNAME); \
+		pfx=lib; \
+		if [ "$(PLATFORM)" != "Cygwin" ]; then \
+			case "$(CFLAGS)" in \
+			*DSO_BEOS*) sfx=".so";; \
+			*DSO_DLFCN*) sfx=`expr "$(SHLIB_EXT)" : '.*\(\.[a-z][a-z]*\)' \| ".so"`;; \
+			*DSO_DL*) sfx=".sl";; \
+			*DSO_WIN32*) sfx="eay32.dll"; pfx=;; \
+			*) sfx=".bad";; \
+			esac; \
+			cp $${pfx}$(LIBNAME)$$sfx $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new; \
+		else \
+			sfx=".so"; \
+			cp cyg$(LIBNAME).dll $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new; \
+		fi; \
+		chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new; \
+		mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx; \
+	fi
+
+links:
+
+tests:
+
+depend:
+	@if [ -z "$(THIS)" ]; then \
+	    $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
+	else \
+	    $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC); \
+	fi
+
+files:
+
+
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff *.so *.sl *.dll
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+gost2001.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+gost2001.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+gost2001.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+gost2001.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+gost2001.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+gost2001.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+gost2001.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+gost2001.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+gost2001.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+gost2001.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+gost2001.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+gost2001.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+gost2001.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+gost2001.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+gost2001.o: e_gost_err.h gost2001.c gost89.h gost_lcl.h gost_params.h
+gost2001.o: gosthash.h
+gost2001_keyx.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+gost2001_keyx.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+gost2001_keyx.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+gost2001_keyx.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+gost2001_keyx.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+gost2001_keyx.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+gost2001_keyx.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+gost2001_keyx.o: ../../include/openssl/obj_mac.h
+gost2001_keyx.o: ../../include/openssl/objects.h
+gost2001_keyx.o: ../../include/openssl/opensslconf.h
+gost2001_keyx.o: ../../include/openssl/opensslv.h
+gost2001_keyx.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+gost2001_keyx.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+gost2001_keyx.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+gost2001_keyx.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+gost2001_keyx.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost2001_keyx.c
+gost2001_keyx.o: gost2001_keyx.h gost89.h gost_keywrap.h gost_lcl.h gosthash.h
+gost89.o: gost89.c gost89.h
+gost94_keyx.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+gost94_keyx.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+gost94_keyx.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+gost94_keyx.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+gost94_keyx.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+gost94_keyx.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+gost94_keyx.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
+gost94_keyx.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+gost94_keyx.o: ../../include/openssl/objects.h
+gost94_keyx.o: ../../include/openssl/opensslconf.h
+gost94_keyx.o: ../../include/openssl/opensslv.h
+gost94_keyx.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+gost94_keyx.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+gost94_keyx.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+gost94_keyx.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+gost94_keyx.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost89.h
+gost94_keyx.o: gost94_keyx.c gost_keywrap.h gost_lcl.h gosthash.h
+gost_ameth.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+gost_ameth.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+gost_ameth.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+gost_ameth.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+gost_ameth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+gost_ameth.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+gost_ameth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+gost_ameth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+gost_ameth.o: ../../include/openssl/objects.h
+gost_ameth.o: ../../include/openssl/opensslconf.h
+gost_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+gost_ameth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+gost_ameth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+gost_ameth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+gost_ameth.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost89.h
+gost_ameth.o: gost_ameth.c gost_lcl.h gost_params.h gosthash.h
+gost_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+gost_asn1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+gost_asn1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+gost_asn1.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+gost_asn1.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+gost_asn1.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+gost_asn1.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+gost_asn1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+gost_asn1.o: ../../include/openssl/opensslconf.h
+gost_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+gost_asn1.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+gost_asn1.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+gost_asn1.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+gost_asn1.o: ../../include/openssl/x509_vfy.h gost89.h gost_asn1.c gost_lcl.h
+gost_asn1.o: gosthash.h
+gost_crypt.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+gost_crypt.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+gost_crypt.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+gost_crypt.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+gost_crypt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+gost_crypt.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+gost_crypt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+gost_crypt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+gost_crypt.o: ../../include/openssl/opensslconf.h
+gost_crypt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+gost_crypt.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+gost_crypt.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+gost_crypt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+gost_crypt.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+gost_crypt.o: e_gost_err.h gost89.h gost_crypt.c gost_lcl.h gosthash.h
+gost_ctl.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+gost_ctl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+gost_ctl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+gost_ctl.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+gost_ctl.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+gost_ctl.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+gost_ctl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+gost_ctl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+gost_ctl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+gost_ctl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+gost_ctl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+gost_ctl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+gost_ctl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+gost_ctl.o: ../../include/openssl/x509_vfy.h gost89.h gost_ctl.c gost_lcl.h
+gost_ctl.o: gosthash.h
+gost_eng.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+gost_eng.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+gost_eng.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+gost_eng.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+gost_eng.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+gost_eng.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+gost_eng.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+gost_eng.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+gost_eng.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+gost_eng.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+gost_eng.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+gost_eng.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+gost_eng.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+gost_eng.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost89.h gost_eng.c
+gost_eng.o: gost_lcl.h gosthash.h
+gost_keywrap.o: gost89.h gost_keywrap.c gost_keywrap.h
+gost_md.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+gost_md.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+gost_md.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+gost_md.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+gost_md.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+gost_md.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+gost_md.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+gost_md.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+gost_md.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+gost_md.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+gost_md.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+gost_md.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+gost_md.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+gost_md.o: e_gost_err.h gost89.h gost_lcl.h gost_md.c gosthash.h
+gost_params.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+gost_params.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+gost_params.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+gost_params.o: ../../include/openssl/opensslconf.h
+gost_params.o: ../../include/openssl/opensslv.h
+gost_params.o: ../../include/openssl/ossl_typ.h
+gost_params.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+gost_params.o: ../../include/openssl/symhacks.h gost_params.c gost_params.h
+gost_pmeth.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+gost_pmeth.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+gost_pmeth.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
+gost_pmeth.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+gost_pmeth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+gost_pmeth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+gost_pmeth.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
+gost_pmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+gost_pmeth.o: ../../include/openssl/objects.h
+gost_pmeth.o: ../../include/openssl/opensslconf.h
+gost_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+gost_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+gost_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+gost_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+gost_pmeth.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+gost_pmeth.o: e_gost_err.h gost89.h gost_lcl.h gost_params.h gost_pmeth.c
+gost_pmeth.o: gosthash.h
+gost_sign.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+gost_sign.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+gost_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+gost_sign.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+gost_sign.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+gost_sign.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+gost_sign.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+gost_sign.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+gost_sign.o: ../../include/openssl/opensslconf.h
+gost_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+gost_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+gost_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+gost_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+gost_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+gost_sign.o: e_gost_err.h gost89.h gost_lcl.h gost_params.h gost_sign.c
+gost_sign.o: gosthash.h
+gosthash.o: gost89.h gosthash.c gosthash.h
diff --git a/openssl/engines/ccgost/README.gost b/openssl/engines/ccgost/README.gost
new file mode 100644
index 0000000..c96cccc
--- /dev/null
+++ b/openssl/engines/ccgost/README.gost
@@ -0,0 +1,300 @@
+GOST ENGINE
+
+This engine provides implementation of Russian cryptography standard.
+This is also an example of adding new cryptoalgorithms into OpenSSL
+without changing its core. If OpenSSL is compiled with dynamic engine
+support, new algorithms can be added even without recompilation of
+OpenSSL and applications which use it.
+
+ALGORITHMS SUPPORTED
+
+GOST R 34.10-94 and GOST R 34.10-2001 - digital signature algorithms.
+   Also support key exchange based on public keys. See RFC 4357 for
+   details of VKO key exchange algorithm. These algorithms use
+   256 bit private keys. Public keys are 1024 bit for 94 and 512 bit for
+   2001 (which is elliptic-curve based). Key exchange algorithms
+   (VKO R 34.10) are supported on these keys too.
+   
+GOST R 34.11-94  Message digest algorithm. 256-bit hash value
+
+GOST 28147-89 - Symmetric cipher  with 256-bit key. Various modes are
+   defined in the standard, but only CFB and CNT modes are implemented
+   in the engine. To make statistical analysis more difficult, key
+   meshing is supported (see RFC 4357).
+
+GOST 28147-89 MAC mode. Message authentication code. While most MAC
+    algorithms  out there are based on hash functions using HMAC
+	algorithm, this algoritm is based on symmetric cipher. 
+	It has 256-bit symmetric key and only 32 bits of MAC value
+	(while HMAC has same key size and value size). 
+
+	It is implemented as combination of EVP_PKEY type and EVP_MD type.
+
+USAGE OF THESE ALGORITHMS
+
+This engine is designed to allow usage of this algorithms in the
+high-level openssl functions, such as PKI, S/MIME and TLS.
+
+See RFC 4490 for S/MIME with GOST algorithms and RFC 4491 for PKI.
+TLS support is implemented according IETF
+draft-chudov-cryptopro-cptls-03.txt and is compatible with
+CryptoPro CSP 3.0 and 3.6 as well as with MagPro CSP. 
+GOST ciphersuites implemented in CryptoPro CSP 2.0 are not supported
+because they use ciphersuite numbers used now by AES ciphersuites.
+
+To use the engine you have to load it via openssl configuration
+file. Applications should read openssl configuration file or provide
+their own means to load engines. Also, applications which operate with
+private keys, should use generic EVP_PKEY API instead of using RSA or
+other algorithm-specific API.
+
+CONFIGURATION FILE
+
+Configuration file should include following statement in the global
+section, i.e. before first bracketed section header (see config(5) for details)
+
+   openssl_conf = openssl_def
+
+where openssl_def is name of the section in configuration file which
+describes global defaults.
+
+This section should contain following statement:
+
+   [openssl_def]
+   engines = engine_section
+
+which points to the section which describes list of the engines to be
+loaded. This section should contain:
+
+	[engine_section]
+	gost = gost_section
+
+And section which describes configuration of the engine should contain
+
+	[gost_section]
+	engine_id = gost
+	dynamic_path = /usr/lib/ssl/engines/libgost.so
+	default_algorithms = ALL
+	CRYPT_PARAMS = id-Gost28147-89-CryptoPro-A-ParamSet
+
+Where engine_id parameter specifies name of engine (should be "gost").
+dynamic_path is a location of the loadable shared library implementing the
+engine. If the engine is compiled statically or is located in the OpenSSL
+engines directory, this line can be omitted. 
+default_algorithms parameter specifies that all algorithms, provided by
+engine, should be used.
+
+The CRYPT_PARAMS parameter is engine-specific. It allows the user to choose
+between different parameter sets of symmetric cipher algorithm. RFC 4357
+specifies several parameters for the GOST 28147-89 algorithm, but OpenSSL
+doesn't provide user interface to choose one when encrypting. So use engine
+configuration parameter instead.
+
+Value of this parameter can be either short name, defined in OpenSSL
+obj_dat.h header file or numeric representation of OID, defined in RFC
+4357. 
+
+USAGE WITH COMMAND LINE openssl UTILITY
+
+1. Generation of private key
+
+	openssl genpkey -algorithm gost2001 -pkeyopt paramset:A -out seckey.pem
+
+  Use -algorithm option to specify algorithm.
+  Use -pkeyopt option to pass paramset to algorithm. The following paramsets
+  are supported by 
+  	gost94: 0,A,B,C,D,XA,XB,XC
+	gost2001: 0,A,B,C,XA,XB
+  You can also use numeric representation of OID as to destinate
+  paramset.
+
+  Paramsets starting with X are intended to use for key exchange keys.
+  Paramsets without X are for digital signature keys.
+
+  Paramset for both algorithms 0 is the test paramset which should be used
+  only for test purposes.
+
+There are no algorithm-specific things with generation of certificate
+request once you have a private key.
+
+2. Generation of certificate request along with private/public keypar
+
+   openssl req -newkey gost2001 -pkeyopt paramset:A
+
+   Syntax of -pkeyopt parameter is identical with genpkey command.
+
+   You can also use oldstyle syntax -newkey gost2001:paramfile, but in
+   this case you should create parameter file first. 
+
+   It can be created with
+
+   openssl genpkey -genparam -algorithm gost2001 -pkeyopt paramset:A\
+      -out paramfile.
+
+3. S/MIME operations
+
+If you want to send encrypted mail using GOST algorithms, don't forget
+to specify -gost89 as encryption algorithm for OpenSSL smime command.
+While OpenSSL is clever enough to find out that GOST R 34.11-94 digest
+must be used for digital signing with GOST private key, it have no way
+to derive symmetric encryption algorithm from key exchange keys.
+
+4. TLS operations
+
+OpenSSL supports all four ciphersuites defined in the IETF draft.
+Once you've loaded GOST key and certificate into your TLS server,
+ciphersuites which use GOST 28147-89 encryption are enabled.
+
+Ciphersuites with NULL encryption should be enabled explicitely if
+needed.
+
+GOST2001-GOST89-GOST89 Uses GOST R 34.10-2001 for auth and key exchange
+		GOST 28147-89 for encryption and GOST 28147-89 MAC
+GOST94-GOST89-GOST89 Uses GOST R 34.10-94 for auth and key exchange
+		GOST 28147-89 for encryption and GOST 28147-89 MAC
+GOST2001-NULL-GOST94 Uses GOST R 34.10-2001 for auth and key exchange,
+        no encryption and HMAC, based on GOST R 34.11-94
+GOST94-NULL-GOST94 Uses GOST R 34.10-94 for auth and key exchange,
+        no encryption and HMAC, based on GOST R 34.11-94
+
+Gost 94 and gost 2001 keys can be used simultaneously in the TLS server.
+RSA, DSA and EC keys can be used simultaneously with GOST keys, if
+server implementation supports loading more than two private
+key/certificate pairs. In this case ciphersuites which use any of loaded
+keys would be supported and clients can negotiate ones they wish.
+
+This allows creation of TLS servers which use GOST ciphersuites for
+Russian clients and RSA/DSA ciphersuites for foreign clients.
+
+5. Calculation of digests and symmetric encryption
+ OpenSSL provides specific commands (like sha1, aes etc) for calculation
+ of digests and symmetric encryption. Since such commands cannot be
+ added dynamically, no such commands are provided for GOST algorithms.
+ Use generic commands 'dgst' and 'enc'.
+
+ Calculation of GOST R 34.11-94 message digest
+
+ openssl dgst -md_gost94 datafile
+
+ Note that GOST R 34.11-94 specifies that digest value should be
+ interpreted as little-endian number, but OpenSSL outputs just hex dump
+ of digest value.
+
+ So, to obtain correct digest value, such as produced by gostsum utility
+ included in the engine distribution, bytes of output should be
+ reversed.
+ 
+ Calculation of HMAC based on GOST R 34.11-94
+
+ openssl dgst -md_gost94 -mac hmac -macopt key:<32 bytes of key> datafile
+  
+  (or use hexkey if key contain NUL bytes)
+ Calculation of GOST 28147 MAC
+
+ openssl dgst -mac gost-mac -macopt key:<32 bytes of key> datafile
+
+ Note absense of an option that specifies digest algorithm. gost-mac
+ algorithm supports only one digest (which is actually part of
+ implementation of this mac) and OpenSSL is clever enough to find out
+ this.
+
+ Encryption with GOST 28147 CFB mode
+ openssl enc -gost89 -out encrypted-file -in plain-text-file -k <passphrase>  
+ Encryption with GOST 28147 CNT mode
+ openssl enc -gost89-cnt -out encrypted-file -in plain-text-file -k <passphrase>
+
+
+6. Encrypting private keys and PKCS12
+
+To produce PKCS12 files compatible with MagPro CSP, you need to use
+GOST algorithm for encryption of PKCS12 file and also GOST R 34.11-94
+hash to derive key from password.
+
+openssl pksc12 -export -inkey gost.pem -in gost_cert.pem -keypbe gost89\
+   -certpbe gost89 -macalg md_gost94
+ 
+7. Testing speed of symmetric ciphers.
+   
+To test performance of GOST symmetric ciphers you should use -evp switch
+of the openssl speed command. Engine-provided ciphers couldn't be
+accessed by cipher-specific functions, only via generic evp interface
+
+ openssl speed -evp gost89
+ openssl speed -evp gost89-cnt
+
+
+PROGRAMMING INTERFACES DETAILS
+
+Applications never should access engine directly. They only use provided
+EVP_PKEY API. But there are some details, which should be taken into
+account.
+
+EVP provides two kinds of API for key exchange:
+
+1. EVP_PKEY_encrypt/EVP_PKEY_decrypt functions, intended to use with
+	RSA-like public key encryption algorithms
+
+2. EVP_PKEY_derive, intended to use with Diffie-Hellman-like shared key
+computing algorithms.
+
+Although VKO R 34.10 algorithms, described in the RFC 4357 are
+definitely second case, engine provides BOTH API for GOST R 34.10 keys.
+
+EVP_PKEY_derive just invokes appropriate VKO algorithm and computes
+256 bit shared key. VKO R 34.10-2001 requires 64 bits of random user key
+material (UKM). This UKM should be transmitted to other party, so it is
+not generated inside derive function.
+
+It should be set by EVP_PKEY_CTX_ctrl function using
+EVP_PKEY_CTRL_SET_IV command after call of EVP_PKEY_derive_init, but
+before EVP_PKEY_derive.
+	unsigned char ukm[8];
+	RAND_bytes(ukm,8);
+   EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_DERIVE, 8, ukm)
+
+EVP_PKEY_encrypt encrypts provided session key with VKO shared key and
+packs it into GOST key transport structure, described in the RFC 4490.
+
+It typically uses ephemeral key pair to compute shared key and packs its
+public part along with encrypted key. So, for most cases use of 
+EVP_PKEY_encrypt/EVP_PKEY_decrypt with GOST keys is almost same as with
+RSA.
+
+However, if peerkey field in the EVP_PKEY_CTX structure is set (using
+EVP_PKEY_derive_set_peerkey function) to EVP_PKEY structure which has private
+key and uses same parameters as the public key from which this EVP_PKEY_CTX is
+created, EVP_PKEY_encrypt will use this private key to compute shared key and
+set ephemeral key in the GOST_key_transport structure to NULL. In this case
+pkey and peerkey fields in the EVP_PKEY_CTX are used upside-down.
+
+If EVP_PKEY_decrypt encounters GOST_key_transport structure with NULL
+public key field, it tries to use peerkey field from the context to
+compute shared key. In this case peerkey field should really contain
+peer public key.
+
+Encrypt operation supports EVP_PKEY_CTRL_SET_IV operation as well.
+It can be used when some specific restriction on UKM are imposed by
+higher level protocol. For instance, description of GOST ciphersuites
+requires UKM to be derived from shared secret. 
+
+If UKM is not set by this control command, encrypt operation would
+generate random UKM.
+
+
+This sources include implementation of GOST 28147-89 and GOST R 34.11-94
+which are completely indepentent from OpenSSL and can be used separately
+(files gost89.c, gost89.h, gosthash.c, gosthash.h) Utility gostsum (file
+gostsum.c) is provided as example of such separate usage. This is
+program, simular to md5sum and sha1sum utilities, but calculates GOST R
+34.11-94 hash.
+
+Makefile doesn't include rule for compiling gostsum.
+Use command
+
+$(CC) -o gostsum gostsum.c gost89.c gosthash.c
+where $(CC) is name of your C compiler.
+
+Implementations of GOST R 34.10-xx, including VKO algorithms heavily
+depends on OpenSSL BIGNUM and Elliptic Curve libraries.
+
+
diff --git a/openssl/engines/ccgost/e_gost_err.c b/openssl/engines/ccgost/e_gost_err.c
new file mode 100644
index 0000000..9a79a37
--- /dev/null
+++ b/openssl/engines/ccgost/e_gost_err.c
@@ -0,0 +1,212 @@
+/* e_gost_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2009 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "e_gost_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA GOST_str_functs[]=
+	{
+{ERR_FUNC(GOST_F_DECODE_GOST_ALGOR_PARAMS),	"DECODE_GOST_ALGOR_PARAMS"},
+{ERR_FUNC(GOST_F_ENCODE_GOST_ALGOR_PARAMS),	"ENCODE_GOST_ALGOR_PARAMS"},
+{ERR_FUNC(GOST_F_FILL_GOST2001_PARAMS),	"FILL_GOST2001_PARAMS"},
+{ERR_FUNC(GOST_F_FILL_GOST94_PARAMS),	"FILL_GOST94_PARAMS"},
+{ERR_FUNC(GOST_F_GET_ENCRYPTION_PARAMS),	"GET_ENCRYPTION_PARAMS"},
+{ERR_FUNC(GOST_F_GOST2001_COMPUTE_PUBLIC),	"GOST2001_COMPUTE_PUBLIC"},
+{ERR_FUNC(GOST_F_GOST2001_DO_SIGN),	"GOST2001_DO_SIGN"},
+{ERR_FUNC(GOST_F_GOST2001_DO_VERIFY),	"GOST2001_DO_VERIFY"},
+{ERR_FUNC(GOST_F_GOST2001_KEYGEN),	"GOST2001_KEYGEN"},
+{ERR_FUNC(GOST_F_GOST89_GET_ASN1_PARAMETERS),	"GOST89_GET_ASN1_PARAMETERS"},
+{ERR_FUNC(GOST_F_GOST89_SET_ASN1_PARAMETERS),	"GOST89_SET_ASN1_PARAMETERS"},
+{ERR_FUNC(GOST_F_GOST94_COMPUTE_PUBLIC),	"GOST94_COMPUTE_PUBLIC"},
+{ERR_FUNC(GOST_F_GOST_CIPHER_CTL),	"GOST_CIPHER_CTL"},
+{ERR_FUNC(GOST_F_GOST_DO_SIGN),	"GOST_DO_SIGN"},
+{ERR_FUNC(GOST_F_GOST_DO_VERIFY),	"GOST_DO_VERIFY"},
+{ERR_FUNC(GOST_F_GOST_IMIT_CTRL),	"GOST_IMIT_CTRL"},
+{ERR_FUNC(GOST_F_GOST_IMIT_FINAL),	"GOST_IMIT_FINAL"},
+{ERR_FUNC(GOST_F_GOST_IMIT_UPDATE),	"GOST_IMIT_UPDATE"},
+{ERR_FUNC(GOST_F_PARAM_COPY_GOST01),	"PARAM_COPY_GOST01"},
+{ERR_FUNC(GOST_F_PARAM_COPY_GOST94),	"PARAM_COPY_GOST94"},
+{ERR_FUNC(GOST_F_PKEY_GOST01CP_DECRYPT),	"PKEY_GOST01CP_DECRYPT"},
+{ERR_FUNC(GOST_F_PKEY_GOST01CP_ENCRYPT),	"PKEY_GOST01CP_ENCRYPT"},
+{ERR_FUNC(GOST_F_PKEY_GOST01CP_KEYGEN),	"PKEY_GOST01CP_KEYGEN"},
+{ERR_FUNC(GOST_F_PKEY_GOST01_PARAMGEN),	"PKEY_GOST01_PARAMGEN"},
+{ERR_FUNC(GOST_F_PKEY_GOST2001_DERIVE),	"PKEY_GOST2001_DERIVE"},
+{ERR_FUNC(GOST_F_PKEY_GOST94CP_DECRYPT),	"PKEY_GOST94CP_DECRYPT"},
+{ERR_FUNC(GOST_F_PKEY_GOST94CP_ENCRYPT),	"PKEY_GOST94CP_ENCRYPT"},
+{ERR_FUNC(GOST_F_PKEY_GOST94CP_KEYGEN),	"PKEY_GOST94CP_KEYGEN"},
+{ERR_FUNC(GOST_F_PKEY_GOST94_PARAMGEN),	"PKEY_GOST94_PARAMGEN"},
+{ERR_FUNC(GOST_F_PKEY_GOST_CTRL),	"PKEY_GOST_CTRL"},
+{ERR_FUNC(GOST_F_PKEY_GOST_CTRL01_STR),	"PKEY_GOST_CTRL01_STR"},
+{ERR_FUNC(GOST_F_PKEY_GOST_CTRL94_STR),	"PKEY_GOST_CTRL94_STR"},
+{ERR_FUNC(GOST_F_PKEY_GOST_MAC_CTRL),	"PKEY_GOST_MAC_CTRL"},
+{ERR_FUNC(GOST_F_PKEY_GOST_MAC_CTRL_STR),	"PKEY_GOST_MAC_CTRL_STR"},
+{ERR_FUNC(GOST_F_PKEY_GOST_MAC_KEYGEN),	"PKEY_GOST_MAC_KEYGEN"},
+{ERR_FUNC(GOST_F_PRINT_GOST_01),	"PRINT_GOST_01"},
+{ERR_FUNC(GOST_F_PRIV_DECODE_GOST),	"PRIV_DECODE_GOST"},
+{ERR_FUNC(GOST_F_PUB_DECODE_GOST01),	"PUB_DECODE_GOST01"},
+{ERR_FUNC(GOST_F_PUB_DECODE_GOST94),	"PUB_DECODE_GOST94"},
+{ERR_FUNC(GOST_F_PUB_ENCODE_GOST01),	"PUB_ENCODE_GOST01"},
+{ERR_FUNC(GOST_F_UNPACK_CC_SIGNATURE),	"UNPACK_CC_SIGNATURE"},
+{ERR_FUNC(GOST_F_UNPACK_CP_SIGNATURE),	"UNPACK_CP_SIGNATURE"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA GOST_str_reasons[]=
+	{
+{ERR_REASON(GOST_R_BAD_KEY_PARAMETERS_FORMAT),"bad key parameters format"},
+{ERR_REASON(GOST_R_BAD_PKEY_PARAMETERS_FORMAT),"bad pkey parameters format"},
+{ERR_REASON(GOST_R_CANNOT_PACK_EPHEMERAL_KEY),"cannot pack ephemeral key"},
+{ERR_REASON(GOST_R_CTRL_CALL_FAILED)     ,"ctrl call failed"},
+{ERR_REASON(GOST_R_ERROR_COMPUTING_SHARED_KEY),"error computing shared key"},
+{ERR_REASON(GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO),"error packing key transport info"},
+{ERR_REASON(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO),"error parsing key transport info"},
+{ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS),"incompatible algorithms"},
+{ERR_REASON(GOST_R_INCOMPATIBLE_PEER_KEY),"incompatible peer key"},
+{ERR_REASON(GOST_R_INVALID_CIPHER_PARAMS),"invalid cipher params"},
+{ERR_REASON(GOST_R_INVALID_CIPHER_PARAM_OID),"invalid cipher param oid"},
+{ERR_REASON(GOST_R_INVALID_DIGEST_TYPE)  ,"invalid digest type"},
+{ERR_REASON(GOST_R_INVALID_GOST94_PARMSET),"invalid gost94 parmset"},
+{ERR_REASON(GOST_R_INVALID_IV_LENGTH)    ,"invalid iv length"},
+{ERR_REASON(GOST_R_INVALID_MAC_KEY_LENGTH),"invalid mac key length"},
+{ERR_REASON(GOST_R_INVALID_PARAMSET)     ,"invalid paramset"},
+{ERR_REASON(GOST_R_KEY_IS_NOT_INITALIZED),"key is not initalized"},
+{ERR_REASON(GOST_R_KEY_IS_NOT_INITIALIZED),"key is not initialized"},
+{ERR_REASON(GOST_R_KEY_PARAMETERS_MISSING),"key parameters missing"},
+{ERR_REASON(GOST_R_MAC_KEY_NOT_SET)      ,"mac key not set"},
+{ERR_REASON(GOST_R_MALLOC_FAILURE)       ,"malloc failure"},
+{ERR_REASON(GOST_R_NO_MEMORY)            ,"no memory"},
+{ERR_REASON(GOST_R_NO_PARAMETERS_SET)    ,"no parameters set"},
+{ERR_REASON(GOST_R_NO_PEER_KEY)          ,"no peer key"},
+{ERR_REASON(GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR),"no private part of non ephemeral keypair"},
+{ERR_REASON(GOST_R_PUBLIC_KEY_UNDEFINED) ,"public key undefined"},
+{ERR_REASON(GOST_R_RANDOM_GENERATOR_ERROR),"random generator error"},
+{ERR_REASON(GOST_R_RANDOM_GENERATOR_FAILURE),"random generator failure"},
+{ERR_REASON(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED),"random number generator failed"},
+{ERR_REASON(GOST_R_SIGNATURE_MISMATCH)   ,"signature mismatch"},
+{ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q),"signature parts greater than q"},
+{ERR_REASON(GOST_R_UKM_NOT_SET)          ,"ukm not set"},
+{ERR_REASON(GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND),"unsupported cipher ctl command"},
+{ERR_REASON(GOST_R_UNSUPPORTED_PARAMETER_SET),"unsupported parameter set"},
+{0,NULL}
+	};
+
+#endif
+
+#ifdef GOST_LIB_NAME
+static ERR_STRING_DATA GOST_lib_name[]=
+        {
+{0	,GOST_LIB_NAME},
+{0,NULL}
+	};
+#endif
+
+
+static int GOST_lib_error_code=0;
+static int GOST_error_init=1;
+
+void ERR_load_GOST_strings(void)
+	{
+	if (GOST_lib_error_code == 0)
+		GOST_lib_error_code=ERR_get_next_error_library();
+
+	if (GOST_error_init)
+		{
+		GOST_error_init=0;
+#ifndef OPENSSL_NO_ERR
+		ERR_load_strings(GOST_lib_error_code,GOST_str_functs);
+		ERR_load_strings(GOST_lib_error_code,GOST_str_reasons);
+#endif
+
+#ifdef GOST_LIB_NAME
+		GOST_lib_name->error = ERR_PACK(GOST_lib_error_code,0,0);
+		ERR_load_strings(0,GOST_lib_name);
+#endif
+		}
+	}
+
+void ERR_unload_GOST_strings(void)
+	{
+	if (GOST_error_init == 0)
+		{
+#ifndef OPENSSL_NO_ERR
+		ERR_unload_strings(GOST_lib_error_code,GOST_str_functs);
+		ERR_unload_strings(GOST_lib_error_code,GOST_str_reasons);
+#endif
+
+#ifdef GOST_LIB_NAME
+		ERR_unload_strings(0,GOST_lib_name);
+#endif
+		GOST_error_init=1;
+		}
+	}
+
+void ERR_GOST_error(int function, int reason, char *file, int line)
+	{
+	if (GOST_lib_error_code == 0)
+		GOST_lib_error_code=ERR_get_next_error_library();
+	ERR_PUT_error(GOST_lib_error_code,function,reason,file,line);
+	}
diff --git a/openssl/engines/ccgost/e_gost_err.h b/openssl/engines/ccgost/e_gost_err.h
new file mode 100644
index 0000000..6dc5000
--- /dev/null
+++ b/openssl/engines/ccgost/e_gost_err.h
@@ -0,0 +1,156 @@
+/* ====================================================================
+ * Copyright (c) 2001-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_GOST_ERR_H
+#define HEADER_GOST_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_GOST_strings(void);
+void ERR_unload_GOST_strings(void);
+void ERR_GOST_error(int function, int reason, char *file, int line);
+#define GOSTerr(f,r) ERR_GOST_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the GOST functions. */
+
+/* Function codes. */
+#define GOST_F_DECODE_GOST_ALGOR_PARAMS			 99
+#define GOST_F_ENCODE_GOST_ALGOR_PARAMS			 100
+#define GOST_F_FILL_GOST2001_PARAMS			 101
+#define GOST_F_FILL_GOST94_PARAMS			 102
+#define GOST_F_GET_ENCRYPTION_PARAMS			 103
+#define GOST_F_GOST2001_COMPUTE_PUBLIC			 104
+#define GOST_F_GOST2001_DO_SIGN				 105
+#define GOST_F_GOST2001_DO_VERIFY			 106
+#define GOST_F_GOST2001_KEYGEN				 107
+#define GOST_F_GOST89_GET_ASN1_PARAMETERS		 108
+#define GOST_F_GOST89_SET_ASN1_PARAMETERS		 109
+#define GOST_F_GOST94_COMPUTE_PUBLIC			 110
+#define GOST_F_GOST_CIPHER_CTL				 111
+#define GOST_F_GOST_DO_SIGN				 112
+#define GOST_F_GOST_DO_VERIFY				 113
+#define GOST_F_GOST_IMIT_CTRL				 114
+#define GOST_F_GOST_IMIT_FINAL				 140
+#define GOST_F_GOST_IMIT_UPDATE				 115
+#define GOST_F_PARAM_COPY_GOST01			 116
+#define GOST_F_PARAM_COPY_GOST94			 117
+#define GOST_F_PKEY_GOST01CP_DECRYPT			 118
+#define GOST_F_PKEY_GOST01CP_ENCRYPT			 119
+#define GOST_F_PKEY_GOST01CP_KEYGEN			 120
+#define GOST_F_PKEY_GOST01_PARAMGEN			 138
+#define GOST_F_PKEY_GOST2001_DERIVE			 121
+#define GOST_F_PKEY_GOST94CP_DECRYPT			 122
+#define GOST_F_PKEY_GOST94CP_ENCRYPT			 123
+#define GOST_F_PKEY_GOST94CP_KEYGEN			 124
+#define GOST_F_PKEY_GOST94_PARAMGEN			 139
+#define GOST_F_PKEY_GOST_CTRL				 125
+#define GOST_F_PKEY_GOST_CTRL01_STR			 126
+#define GOST_F_PKEY_GOST_CTRL94_STR			 127
+#define GOST_F_PKEY_GOST_MAC_CTRL			 128
+#define GOST_F_PKEY_GOST_MAC_CTRL_STR			 129
+#define GOST_F_PKEY_GOST_MAC_KEYGEN			 130
+#define GOST_F_PRINT_GOST_01				 131
+#define GOST_F_PRIV_DECODE_GOST				 132
+#define GOST_F_PUB_DECODE_GOST01			 133
+#define GOST_F_PUB_DECODE_GOST94			 134
+#define GOST_F_PUB_ENCODE_GOST01			 135
+#define GOST_F_UNPACK_CC_SIGNATURE			 136
+#define GOST_F_UNPACK_CP_SIGNATURE			 137
+
+/* Reason codes. */
+#define GOST_R_BAD_KEY_PARAMETERS_FORMAT		 99
+#define GOST_R_BAD_PKEY_PARAMETERS_FORMAT		 100
+#define GOST_R_CANNOT_PACK_EPHEMERAL_KEY		 101
+#define GOST_R_CTRL_CALL_FAILED				 132
+#define GOST_R_ERROR_COMPUTING_SHARED_KEY		 102
+#define GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO		 103
+#define GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO		 104
+#define GOST_R_INCOMPATIBLE_ALGORITHMS			 105
+#define GOST_R_INCOMPATIBLE_PEER_KEY			 131
+#define GOST_R_INVALID_CIPHER_PARAMS			 106
+#define GOST_R_INVALID_CIPHER_PARAM_OID			 107
+#define GOST_R_INVALID_DIGEST_TYPE			 108
+#define GOST_R_INVALID_GOST94_PARMSET			 109
+#define GOST_R_INVALID_IV_LENGTH			 110
+#define GOST_R_INVALID_MAC_KEY_LENGTH			 111
+#define GOST_R_INVALID_PARAMSET				 112
+#define GOST_R_KEY_IS_NOT_INITALIZED			 113
+#define GOST_R_KEY_IS_NOT_INITIALIZED			 114
+#define GOST_R_KEY_PARAMETERS_MISSING			 115
+#define GOST_R_MAC_KEY_NOT_SET				 116
+#define GOST_R_MALLOC_FAILURE				 117
+#define GOST_R_NO_MEMORY				 118
+#define GOST_R_NO_PARAMETERS_SET			 119
+#define GOST_R_NO_PEER_KEY				 120
+#define GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR	 121
+#define GOST_R_PUBLIC_KEY_UNDEFINED			 122
+#define GOST_R_RANDOM_GENERATOR_ERROR			 123
+#define GOST_R_RANDOM_GENERATOR_FAILURE			 124
+#define GOST_R_RANDOM_NUMBER_GENERATOR_FAILED		 125
+#define GOST_R_SIGNATURE_MISMATCH			 126
+#define GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q		 127
+#define GOST_R_UKM_NOT_SET				 128
+#define GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND		 129
+#define GOST_R_UNSUPPORTED_PARAMETER_SET		 130
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/ccgost/e_gost_err.proto b/openssl/engines/ccgost/e_gost_err.proto
new file mode 100644
index 0000000..c57bd1b
--- /dev/null
+++ b/openssl/engines/ccgost/e_gost_err.proto
@@ -0,0 +1,61 @@
+/* ====================================================================
+ * Copyright (c) 2001-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_GOST_ERR_H
+#define HEADER_GOST_ERR_H
+
+#define GOST_LIB_NAME "GOST engine"
+#ifdef __cplusplus
+ extern "C" {
+#endif
diff --git a/openssl/engines/ccgost/gost.ec b/openssl/engines/ccgost/gost.ec
new file mode 100644
index 0000000..6c2c85e
--- /dev/null
+++ b/openssl/engines/ccgost/gost.ec
@@ -0,0 +1,5 @@
+L GOST 			e_gost_err.h			e_gost_err.c
+L NONE    		asymm.h    			NONE
+L NONE    		md.h    			NONE
+L NONE    		crypt.h    			NONE
+L NONE			gostkeyx.h			NONE
diff --git a/openssl/engines/ccgost/gost2001.c b/openssl/engines/ccgost/gost2001.c
new file mode 100644
index 0000000..dacd82d
--- /dev/null
+++ b/openssl/engines/ccgost/gost2001.c
@@ -0,0 +1,343 @@
+/**********************************************************************
+ *                          gost2001.c                                *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *         This file is distributed under the same license as OpenSSL *
+ *                                                                    *
+ *          Implementation of GOST R 34.10-2001      				  *
+ *          Requires OpenSSL 0.9.9 for compilation                    *
+ **********************************************************************/
+#include "gost_lcl.h"
+#include "gost_params.h"
+#include <string.h>
+#include <openssl/rand.h>
+#include <openssl/ecdsa.h>
+#include <openssl/err.h>
+#include "e_gost_err.h"
+#ifdef DEBUG_SIGN
+extern 
+void dump_signature(const char *message,const unsigned char *buffer,size_t len);
+void dump_dsa_sig(const char *message, DSA_SIG *sig);
+#else
+
+#define dump_signature(a,b,c)
+#define dump_dsa_sig(a,b)
+#endif
+
+/*
+ * Fills EC_KEY structure hidden in the app_data field of DSA structure
+ * with parameter information, extracted from parameter array in
+ * params.c file.
+ *
+ * Also fils DSA->q field with copy of EC_GROUP order field to make
+ * DSA_size function work
+ */ 
+int fill_GOST2001_params(EC_KEY *eckey, int nid)
+	{
+	R3410_2001_params *params = R3410_2001_paramset;
+	EC_GROUP *grp=NULL;
+	BIGNUM *p=NULL,*q=NULL,*a=NULL,*b=NULL,*x=NULL,*y=NULL;
+	EC_POINT *P=NULL;
+	BN_CTX *ctx=BN_CTX_new();
+	int ok=0;
+	
+	BN_CTX_start(ctx);
+	p=BN_CTX_get(ctx);
+	a=BN_CTX_get(ctx);
+	b=BN_CTX_get(ctx);
+	x=BN_CTX_get(ctx);
+	y=BN_CTX_get(ctx);
+	q=BN_CTX_get(ctx);
+	while (params->nid!=NID_undef && params->nid != nid) params++;
+	if (params->nid == NID_undef)
+		{
+		GOSTerr(GOST_F_FILL_GOST2001_PARAMS,GOST_R_UNSUPPORTED_PARAMETER_SET);
+		goto err;
+		}	
+	BN_hex2bn(&p,params->p);
+	BN_hex2bn(&a,params->a);
+	BN_hex2bn(&b,params->b);
+	
+	grp = EC_GROUP_new_curve_GFp(p,a,b,ctx);
+
+	P = EC_POINT_new(grp);
+
+	BN_hex2bn(&x,params->x);
+	BN_hex2bn(&y,params->y);
+	EC_POINT_set_affine_coordinates_GFp(grp,P,x,y,ctx);
+	BN_hex2bn(&q,params->q);
+#ifdef DEBUG_KEYS
+	fprintf(stderr,"Set params index %d oid %s\nq=",
+		(params-R3410_2001_paramset),OBJ_nid2sn(params->nid));
+	BN_print_fp(stderr,q);
+	fprintf(stderr,"\n");
+#endif	
+
+	EC_GROUP_set_generator(grp,P,q,NULL);
+	EC_GROUP_set_curve_name(grp,params->nid);
+
+	EC_KEY_set_group(eckey,grp);
+	ok=1;
+	err:
+	EC_POINT_free(P);
+	EC_GROUP_free(grp);
+	BN_CTX_end(ctx);
+	BN_CTX_free(ctx);
+	return ok;
+	}	
+
+
+/*
+ * Computes gost2001 signature as DSA_SIG structure 
+ *
+ *
+ */ 
+DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey)
+	{
+	DSA_SIG *newsig = NULL;
+	BIGNUM *md = hashsum2bn(dgst);
+	BIGNUM *order = NULL;
+	const EC_GROUP *group;
+	const BIGNUM *priv_key;
+	BIGNUM *r=NULL,*s=NULL,*X=NULL,*tmp=NULL,*tmp2=NULL, *k=NULL,*e=NULL;
+	EC_POINT *C=NULL;
+	BN_CTX *ctx = BN_CTX_new();	
+	BN_CTX_start(ctx);
+	OPENSSL_assert(dlen==32);
+	newsig=DSA_SIG_new();
+	if (!newsig) 
+		{
+		GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_NO_MEMORY);
+		goto err;
+		}	
+	group = EC_KEY_get0_group(eckey);
+	order=BN_CTX_get(ctx);
+	EC_GROUP_get_order(group,order,ctx);
+	priv_key = EC_KEY_get0_private_key(eckey);
+	e = BN_CTX_get(ctx);
+	BN_mod(e,md,order,ctx);
+#ifdef DEBUG_SIGN
+	fprintf(stderr,"digest as bignum=");
+	BN_print_fp(stderr,md);
+	fprintf(stderr,"\ndigest mod q=");
+	BN_print_fp(stderr,e);
+	fprintf(stderr,"\n");
+#endif		
+	if (BN_is_zero(e))
+		{
+		BN_one(e);
+		}   
+	k =BN_CTX_get(ctx);
+	C=EC_POINT_new(group);
+	do 
+		{
+		do 
+			{
+			if (!BN_rand_range(k,order)) 
+				{
+				GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
+				DSA_SIG_free(newsig);
+				newsig = NULL;
+				goto err;
+				}	
+			if (!EC_POINT_mul(group,C,k,NULL,NULL,ctx))
+				{
+				GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
+				DSA_SIG_free(newsig);
+				newsig = NULL;
+				goto err;
+				}	
+			if (!X) X=BN_CTX_get(ctx);
+			if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx))
+				{
+				GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
+				DSA_SIG_free(newsig);
+				newsig = NULL;
+				goto err;
+				}	
+			if (!r) r=BN_CTX_get(ctx);
+			BN_nnmod(r,X,order,ctx);
+			}
+		while (BN_is_zero(r));
+		/* s =  (r*priv_key+k*e) mod order */
+		if (!tmp) tmp = BN_CTX_get(ctx);
+		BN_mod_mul(tmp,priv_key,r,order,ctx);
+		if (!tmp2) tmp2 = BN_CTX_get(ctx);
+		BN_mod_mul(tmp2,k,e,order,ctx);
+		if (!s) s=BN_CTX_get(ctx);
+		BN_mod_add(s,tmp,tmp2,order,ctx);
+		}
+	while (BN_is_zero(s));	
+
+	newsig->s=BN_dup(s);
+	newsig->r=BN_dup(r);
+	err:			
+	BN_CTX_end(ctx);
+	BN_CTX_free(ctx);
+	EC_POINT_free(C);
+	BN_free(md);
+	return newsig;
+	}
+/*
+ * Verifies gost 2001 signature
+ *
+ */ 
+int gost2001_do_verify(const unsigned char *dgst,int dgst_len,
+	DSA_SIG *sig, EC_KEY *ec)
+	{
+	BN_CTX *ctx=BN_CTX_new();
+	const EC_GROUP *group = EC_KEY_get0_group(ec);
+	BIGNUM *order;
+	BIGNUM *md = NULL,*e=NULL,*R=NULL,*v=NULL,*z1=NULL,*z2=NULL;
+	BIGNUM *X=NULL,*tmp=NULL;
+	EC_POINT *C = NULL;
+	const EC_POINT *pub_key=NULL;
+	int ok=0;
+
+	BN_CTX_start(ctx);
+	order = BN_CTX_get(ctx);
+	e = BN_CTX_get(ctx);
+	z1 = BN_CTX_get(ctx);
+	z2 = BN_CTX_get(ctx);
+	tmp = BN_CTX_get(ctx);
+	X= BN_CTX_get(ctx);	
+	R=BN_CTX_get(ctx);
+	v=BN_CTX_get(ctx);
+	
+	EC_GROUP_get_order(group,order,ctx);
+	pub_key = EC_KEY_get0_public_key(ec);
+	if (BN_is_zero(sig->s) || BN_is_zero(sig->r) ||
+		(BN_cmp(sig->s,order)>=1) || (BN_cmp(sig->r,order)>=1)) 
+		{
+		GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
+		goto err;
+
+		}
+	md = hashsum2bn(dgst);
+
+	BN_mod(e,md,order,ctx);
+#ifdef DEBUG_SIGN
+	fprintf(stderr,"digest as bignum: ");
+	BN_print_fp(stderr,md);
+	fprintf(stderr,"\ndigest mod q: ");
+	BN_print_fp(stderr,e);
+#endif	
+	if (BN_is_zero(e)) BN_one(e);
+	v=BN_mod_inverse(v,e,order,ctx);
+	BN_mod_mul(z1,sig->s,v,order,ctx);
+	BN_sub(tmp,order,sig->r);
+	BN_mod_mul(z2,tmp,v,order,ctx);
+#ifdef DEBUG_SIGN
+	fprintf(stderr,"\nInverted digest value: ");
+	BN_print_fp(stderr,v);
+	fprintf(stderr,"\nz1: ");
+	BN_print_fp(stderr,z1);
+	fprintf(stderr,"\nz2: ");
+	BN_print_fp(stderr,z2);
+#endif	
+	C = EC_POINT_new(group);
+	if (!EC_POINT_mul(group,C,z1,pub_key,z2,ctx)) 
+		{	
+		GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB);
+		goto err;
+		}	
+	if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx)) 
+		{
+		GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB);
+		goto err;
+		}
+	BN_mod(R,X,order,ctx);
+#ifdef DEBUG_SIGN
+	fprintf(stderr,"\nX=");
+	BN_print_fp(stderr,X);
+	fprintf(stderr,"\nX mod q=");
+	BN_print_fp(stderr,R);
+	fprintf(stderr,"\n");
+#endif	
+	if (BN_cmp(R,sig->r)!=0)
+		{
+		GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH);
+		}
+	else
+		{
+		ok = 1;
+		}
+	err:
+	EC_POINT_free(C);
+	BN_CTX_end(ctx);
+	BN_CTX_free(ctx);
+	BN_free(md);
+	return ok;
+	}
+/*
+ * Computes GOST R 34.10-2001 public key
+ *
+ *
+ */ 
+int gost2001_compute_public(EC_KEY *ec) 
+	{
+	const EC_GROUP *group = EC_KEY_get0_group(ec);
+	EC_POINT *pub_key=NULL;
+	const BIGNUM *priv_key=NULL;
+	BN_CTX *ctx=NULL;
+	int ok=0;
+
+	if (!group)
+		{
+		GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITIALIZED);
+		return 0;
+		}	
+	ctx=BN_CTX_new();
+	BN_CTX_start(ctx);
+	if (!(priv_key=EC_KEY_get0_private_key(ec))) 
+		{
+		GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
+		goto err;
+		}	
+
+	pub_key = EC_POINT_new(group);
+	if (!EC_POINT_mul(group,pub_key,priv_key,NULL,NULL,ctx)) 
+		{
+		GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
+		goto err;
+		}	
+	if (!EC_KEY_set_public_key(ec,pub_key))
+		{
+		GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
+		goto err;
+		}	
+	ok = 256;
+	err:
+	BN_CTX_end(ctx);
+	EC_POINT_free(pub_key);
+	BN_CTX_free(ctx);
+	return ok;
+	}
+/*
+ * 
+ * Generates GOST R 34.10-2001 keypair
+ *
+ *
+ */ 
+int gost2001_keygen(EC_KEY *ec)
+	{
+	BIGNUM *order = BN_new(),*d=BN_new();
+	const EC_GROUP *group = EC_KEY_get0_group(ec);
+	EC_GROUP_get_order(group,order,NULL);
+	
+	do 
+		{
+		if (!BN_rand_range(d,order)) 
+			{
+			GOSTerr(GOST_F_GOST2001_KEYGEN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
+			BN_free(d);
+			BN_free(order);
+			return 0;
+			}	
+		}
+	while (BN_is_zero(d));
+	EC_KEY_set_private_key(ec,d);
+	BN_free(d);
+	BN_free(order);
+	return gost2001_compute_public(ec);
+	}
+
diff --git a/openssl/engines/ccgost/gost2001_keyx.c b/openssl/engines/ccgost/gost2001_keyx.c
new file mode 100644
index 0000000..c748102
--- /dev/null
+++ b/openssl/engines/ccgost/gost2001_keyx.c
@@ -0,0 +1,308 @@
+/**********************************************************************
+ *                          gost_keyx.c                               *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *         This file is distributed under the same license as OpenSSL *
+ *                                                                    *
+ *   VK0 34.10-2001 key exchange and GOST R 34.10-2001                *
+ *   based PKCS7/SMIME support                                        *
+ *          Requires OpenSSL 0.9.9 for compilation                    *
+ **********************************************************************/
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <string.h>
+#include <openssl/objects.h>
+#include "gost89.h"
+#include "gosthash.h"
+#include "e_gost_err.h"
+#include "gost_keywrap.h"
+#include "gost_lcl.h"
+#include "gost2001_keyx.h"
+
+
+
+/* Implementation of CryptoPro VKO 34.10-2001 algorithm */
+static int VKO_compute_key(unsigned char *shared_key,size_t shared_key_size,const EC_POINT *pub_key,EC_KEY *priv_key,const unsigned char *ukm)
+	{
+	unsigned char ukm_be[8],databuf[64],hashbuf[64];
+	BIGNUM *UKM=NULL,*p=NULL,*order=NULL,*X=NULL,*Y=NULL;
+	const BIGNUM* key=EC_KEY_get0_private_key(priv_key);
+	EC_POINT *pnt=EC_POINT_new(EC_KEY_get0_group(priv_key));
+	int i;
+	gost_hash_ctx hash_ctx;
+	BN_CTX *ctx = BN_CTX_new();
+
+	for (i=0;i<8;i++)
+		{
+		ukm_be[7-i]=ukm[i];
+		}
+	BN_CTX_start(ctx);
+	UKM=getbnfrombuf(ukm_be,8);
+	p=BN_CTX_get(ctx);
+	order = BN_CTX_get(ctx);
+	X=BN_CTX_get(ctx);
+	Y=BN_CTX_get(ctx);
+	EC_GROUP_get_order(EC_KEY_get0_group(priv_key),order,ctx);
+	BN_mod_mul(p,key,UKM,order,ctx);	
+	EC_POINT_mul(EC_KEY_get0_group(priv_key),pnt,NULL,pub_key,p,ctx);
+	EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(priv_key),
+		pnt,X,Y,ctx);
+	/*Serialize elliptic curve point same way as we do it when saving
+	 * key */
+	store_bignum(Y,databuf,32);
+	store_bignum(X,databuf+32,32);
+ 	/* And reverse byte order of whole buffer */
+	for (i=0;i<64;i++)
+		{
+		hashbuf[63-i]=databuf[i];
+		}
+	init_gost_hash_ctx(&hash_ctx,&GostR3411_94_CryptoProParamSet);
+	start_hash(&hash_ctx);
+	hash_block(&hash_ctx,hashbuf,64);
+	finish_hash(&hash_ctx,shared_key);
+	done_gost_hash_ctx(&hash_ctx);
+	BN_free(UKM);
+	BN_CTX_end(ctx);
+	BN_CTX_free(ctx);
+	EC_POINT_free(pnt);
+	return 32;
+	}
+
+
+/*
+ * EVP_PKEY_METHOD callback derive. Implements VKO R 34.10-2001
+ * algorithm
+ */
+int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
+{
+	/* Public key of peer in the ctx field peerkey
+	 * Our private key in the ctx pkey
+	 * ukm is in the algorithm specific context data
+	 */
+	EVP_PKEY *my_key = EVP_PKEY_CTX_get0_pkey(ctx);
+	EVP_PKEY *peer_key = EVP_PKEY_CTX_get0_peerkey(ctx);
+	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+	
+	if (!data->shared_ukm) {
+		GOSTerr(GOST_F_PKEY_GOST2001_DERIVE, GOST_R_UKM_NOT_SET);
+		return 0;
+	}	
+
+	if (key == NULL) {
+		*keylen = 32;
+		return 32;
+	}	
+	
+	*keylen=VKO_compute_key(key, 32, EC_KEY_get0_public_key(EVP_PKEY_get0(peer_key)),
+		(EC_KEY *)EVP_PKEY_get0(my_key),data->shared_ukm);
+	return 1;	
+}
+
+
+
+
+/*  
+ * EVP_PKEY_METHOD callback encrypt  
+ * Implementation of GOST2001 key transport, cryptocom variation 
+ */
+/* Generates ephemeral key based on pubk algorithm
+ * computes shared key using VKO and returns filled up
+ * GOST_KEY_TRANSPORT structure
+ */
+
+/*  
+ * EVP_PKEY_METHOD callback encrypt  
+ * Implementation of GOST2001 key transport, cryptopo variation 
+ */
+
+int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len, const unsigned char *key,size_t key_len) 
+	{
+	GOST_KEY_TRANSPORT *gkt=NULL; 
+	EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx);
+	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx);
+	const struct gost_cipher_info *param=get_encryption_params(NULL);
+	unsigned char ukm[8], shared_key[32], crypted_key[44];
+	int ret=0;
+	int key_is_ephemeral=1;
+	gost_ctx cctx;
+	EVP_PKEY *sec_key=EVP_PKEY_CTX_get0_peerkey(pctx);
+	if (data->shared_ukm) 
+		{
+		memcpy(ukm, data->shared_ukm,8);
+		} 
+	else if (out) 
+		{
+		
+		if (RAND_bytes(ukm,8)<=0)
+			{
+			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
+				GOST_R_RANDOM_GENERATOR_FAILURE);
+			return 0;
+			}	
+		}	
+	/* Check for private key in the peer_key of context */	
+	if (sec_key) 
+		{
+		key_is_ephemeral=0;
+		if (!gost_get0_priv_key(sec_key)) 
+			{
+			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
+			GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR);
+			goto err;
+			}	
+		} 
+	else 
+		{
+		key_is_ephemeral=1;
+		if (out) 
+			{
+			sec_key = EVP_PKEY_new();
+			EVP_PKEY_assign(sec_key,EVP_PKEY_base_id(pubk),EC_KEY_new());
+			EVP_PKEY_copy_parameters(sec_key,pubk);
+			if (!gost2001_keygen(EVP_PKEY_get0(sec_key))) 
+				{
+				goto err;
+				}	
+			}
+		}
+	if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param ==  gost_cipher_list)
+		{
+		param= gost_cipher_list+1;
+		}	
+    if (out) 
+		{
+		VKO_compute_key(shared_key,32,EC_KEY_get0_public_key(EVP_PKEY_get0(pubk)),EVP_PKEY_get0(sec_key),ukm);
+		gost_init(&cctx,param->sblock);	
+		keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key);
+		}
+	gkt = GOST_KEY_TRANSPORT_new();
+	if (!gkt)
+		{
+		goto err;
+		}	
+	if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv,
+			ukm,8))
+		{
+		goto err;
+		}	
+	if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4))
+		{
+		goto err;
+		}
+	if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32))
+		{
+		goto err;
+		}
+	if (key_is_ephemeral) {	
+		if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,out?sec_key:pubk))
+			{
+			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
+					GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
+			goto err;
+			}	
+	}		
+	ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
+	gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
+	if (key_is_ephemeral && sec_key) EVP_PKEY_free(sec_key);
+	if (!key_is_ephemeral)
+		{
+		/* Set control "public key from client certificate used" */
+		if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
+			{
+			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
+				GOST_R_CTRL_CALL_FAILED);
+			goto err;
+			}
+		}
+	if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt,out?&out:NULL))>0) ret =1;
+	GOST_KEY_TRANSPORT_free(gkt);
+	return ret;	
+	err:		
+	if (key_is_ephemeral && sec_key) EVP_PKEY_free(sec_key);
+	GOST_KEY_TRANSPORT_free(gkt);
+	return -1;
+	}
+/*  
+ * EVP_PKEY_METHOD callback decrypt  
+ * Implementation of GOST2001 key transport, cryptopo variation 
+ */
+int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key, size_t * key_len, const unsigned char *in, size_t in_len)
+	{
+	const unsigned char *p = in;
+	EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx);
+	GOST_KEY_TRANSPORT *gkt = NULL;
+	int ret=0;	
+	unsigned char wrappedKey[44];
+	unsigned char sharedKey[32];
+	gost_ctx ctx;
+	const struct gost_cipher_info *param=NULL;
+	EVP_PKEY *eph_key=NULL, *peerkey=NULL;
+
+	if (!key)
+		{
+		*key_len = 32;
+		return 1;
+		}	
+	gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
+		in_len);
+	if (!gkt)
+		{
+		GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
+		return -1;
+		}	
+
+	/* If key transport structure contains public key, use it */
+	eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key);
+	if (eph_key)
+		{
+		if (EVP_PKEY_derive_set_peer(pctx, eph_key) <= 0)
+			{
+			GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
+				GOST_R_INCOMPATIBLE_PEER_KEY);
+			goto err;
+			}
+		}
+	else
+		{
+		/* Set control "public key from client certificate used" */
+		if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
+			{
+			GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
+				GOST_R_CTRL_CALL_FAILED);
+			goto err;
+			}
+		}
+	peerkey = EVP_PKEY_CTX_get0_peerkey(pctx);
+	if (!peerkey)
+		{
+		GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
+			GOST_R_NO_PEER_KEY);
+		goto err;
+		}
+		
+	param = get_encryption_params(gkt->key_agreement_info->cipher);
+    if(!param){
+        goto err;
+    }
+
+	gost_init(&ctx,param->sblock);	
+	OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8);
+	memcpy(wrappedKey,gkt->key_agreement_info->eph_iv->data,8);
+	OPENSSL_assert(gkt->key_info->encrypted_key->length==32);
+	memcpy(wrappedKey+8,gkt->key_info->encrypted_key->data,32);
+	OPENSSL_assert(gkt->key_info->imit->length==4);
+	memcpy(wrappedKey+40,gkt->key_info->imit->data,4);	
+	VKO_compute_key(sharedKey,32,EC_KEY_get0_public_key(EVP_PKEY_get0(peerkey)),
+		EVP_PKEY_get0(priv),wrappedKey);
+	if (!keyUnwrapCryptoPro(&ctx,sharedKey,wrappedKey,key))
+		{
+		GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
+			GOST_R_ERROR_COMPUTING_SHARED_KEY);
+		goto err;
+		}	
+				
+	ret=1;
+err:	
+	if (eph_key) EVP_PKEY_free(eph_key);
+	if (gkt) GOST_KEY_TRANSPORT_free(gkt);
+	return ret;
+	}
diff --git a/openssl/engines/ccgost/gost2001_keyx.h b/openssl/engines/ccgost/gost2001_keyx.h
new file mode 100644
index 0000000..a014d9c
--- /dev/null
+++ b/openssl/engines/ccgost/gost2001_keyx.h
@@ -0,0 +1,10 @@
+GOST_KEY_TRANSPORT *
+make_rfc4490_keytransport_2001(EVP_PKEY *pubk, BIGNUM *eph_key,
+                               const unsigned char *key, size_t keylen,
+                               unsigned char *ukm, size_t ukm_len);
+
+int decrypt_rfc4490_shared_key_2001(EVP_PKEY *priv,
+                                    GOST_KEY_TRANSPORT *gkt,
+                                    unsigned char *key_buf,
+                                    int key_buf_len) ;
+
diff --git a/openssl/engines/ccgost/gost89.c b/openssl/engines/ccgost/gost89.c
new file mode 100644
index 0000000..7ebae0f
--- /dev/null
+++ b/openssl/engines/ccgost/gost89.c
@@ -0,0 +1,409 @@
+/**********************************************************************
+ *                        gost89.c                                    *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *         This file is distributed under the same license as OpenSSL *
+ *                                                                    *
+ *          Implementation of GOST 28147-89 encryption algorithm      *
+ *            No OpenSSL libraries required to compile and use        *
+ *                              this code                             *
+ **********************************************************************/ 
+#include <string.h>
+#include "gost89.h"
+/* Substitution blocks from RFC 4357 
+   
+   Note: our implementation of gost 28147-89 algorithm 
+   uses S-box matrix rotated 90 degrees counterclockwise, relative to 
+   examples given in RFC.
+  
+
+*/
+
+/* Substitution blocks from test examples for GOST R 34.11-94*/
+gost_subst_block GostR3411_94_TestParamSet = {
+	{0X1,0XF,0XD,0X0,0X5,0X7,0XA,0X4,0X9,0X2,0X3,0XE,0X6,0XB,0X8,0XC},
+	{0XD,0XB,0X4,0X1,0X3,0XF,0X5,0X9,0X0,0XA,0XE,0X7,0X6,0X8,0X2,0XC},
+	{0X4,0XB,0XA,0X0,0X7,0X2,0X1,0XD,0X3,0X6,0X8,0X5,0X9,0XC,0XF,0XE},
+	{0X6,0XC,0X7,0X1,0X5,0XF,0XD,0X8,0X4,0XA,0X9,0XE,0X0,0X3,0XB,0X2},
+	{0X7,0XD,0XA,0X1,0X0,0X8,0X9,0XF,0XE,0X4,0X6,0XC,0XB,0X2,0X5,0X3},
+	{0X5,0X8,0X1,0XD,0XA,0X3,0X4,0X2,0XE,0XF,0XC,0X7,0X6,0X0,0X9,0XB},
+	{0XE,0XB,0X4,0XC,0X6,0XD,0XF,0XA,0X2,0X3,0X8,0X1,0X0,0X7,0X5,0X9},
+	{0X4,0XA,0X9,0X2,0XD,0X8,0X0,0XE,0X6,0XB,0X1,0XC,0X7,0XF,0X5,0X3}
+	};  
+/* Substitution blocks for hash function 1.2.643.2.9.1.6.1  */
+gost_subst_block GostR3411_94_CryptoProParamSet= {
+	{0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC},
+	{0xD,0xE,0x4,0x1,0x7,0x0,0x5,0xA,0x3,0xC,0x8,0xF,0x6,0x2,0x9,0xB},
+	{0x7,0x6,0x2,0x4,0xD,0x9,0xF,0x0,0xA,0x1,0x5,0xB,0x8,0xE,0xC,0x3},
+	{0x7,0x6,0x4,0xB,0x9,0xC,0x2,0xA,0x1,0x8,0x0,0xE,0xF,0xD,0x3,0x5},
+	{0x4,0xA,0x7,0xC,0x0,0xF,0x2,0x8,0xE,0x1,0x6,0x5,0xD,0xB,0x9,0x3},
+	{0x7,0xF,0xC,0xE,0x9,0x4,0x1,0x0,0x3,0xB,0x5,0x2,0x6,0xA,0x8,0xD},
+	{0x5,0xF,0x4,0x0,0x2,0xD,0xB,0x9,0x1,0x7,0x6,0x3,0xC,0xE,0xA,0x8},
+	{0xA,0x4,0x5,0x6,0x8,0x1,0x3,0x7,0xD,0xC,0xE,0x0,0x9,0x2,0xB,0xF}
+	} ;
+
+/* Test paramset from GOST 28147 */
+gost_subst_block Gost28147_TestParamSet =
+	{
+	{0xC,0x6,0x5,0x2,0xB,0x0,0x9,0xD,0x3,0xE,0x7,0xA,0xF,0x4,0x1,0x8},
+	{0x9,0xB,0xC,0x0,0x3,0x6,0x7,0x5,0x4,0x8,0xE,0xF,0x1,0xA,0x2,0xD},
+	{0x8,0xF,0x6,0xB,0x1,0x9,0xC,0x5,0xD,0x3,0x7,0xA,0x0,0xE,0x2,0x4},
+	{0x3,0xE,0x5,0x9,0x6,0x8,0x0,0xD,0xA,0xB,0x7,0xC,0x2,0x1,0xF,0x4},
+	{0xE,0x9,0xB,0x2,0x5,0xF,0x7,0x1,0x0,0xD,0xC,0x6,0xA,0x4,0x3,0x8},
+	{0xD,0x8,0xE,0xC,0x7,0x3,0x9,0xA,0x1,0x5,0x2,0x4,0x6,0xF,0x0,0xB},
+	{0xC,0x9,0xF,0xE,0x8,0x1,0x3,0xA,0x2,0x7,0x4,0xD,0x6,0x0,0xB,0x5},
+	{0x4,0x2,0xF,0x5,0x9,0x1,0x0,0x8,0xE,0x3,0xB,0xC,0xD,0x7,0xA,0x6}
+	};
+
+
+
+
+/* 1.2.643.2.2.31.1 */
+gost_subst_block Gost28147_CryptoProParamSetA= {
+	{0xB,0xA,0xF,0x5,0x0,0xC,0xE,0x8,0x6,0x2,0x3,0x9,0x1,0x7,0xD,0x4},
+	{0x1,0xD,0x2,0x9,0x7,0xA,0x6,0x0,0x8,0xC,0x4,0x5,0xF,0x3,0xB,0xE},
+	{0x3,0xA,0xD,0xC,0x1,0x2,0x0,0xB,0x7,0x5,0x9,0x4,0x8,0xF,0xE,0x6},
+	{0xB,0x5,0x1,0x9,0x8,0xD,0xF,0x0,0xE,0x4,0x2,0x3,0xC,0x7,0xA,0x6},
+	{0xE,0x7,0xA,0xC,0xD,0x1,0x3,0x9,0x0,0x2,0xB,0x4,0xF,0x8,0x5,0x6},
+	{0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9},
+	{0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1},
+	{0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5}
+	};
+/* 1.2.643.2.2.31.2 */
+gost_subst_block Gost28147_CryptoProParamSetB= 
+	{
+	{0x0,0x4,0xB,0xE,0x8,0x3,0x7,0x1,0xA,0x2,0x9,0x6,0xF,0xD,0x5,0xC},
+	{0x5,0x2,0xA,0xB,0x9,0x1,0xC,0x3,0x7,0x4,0xD,0x0,0x6,0xF,0x8,0xE},
+	{0x8,0x3,0x2,0x6,0x4,0xD,0xE,0xB,0xC,0x1,0x7,0xF,0xA,0x0,0x9,0x5},
+	{0x2,0x7,0xC,0xF,0x9,0x5,0xA,0xB,0x1,0x4,0x0,0xD,0x6,0x8,0xE,0x3},
+	{0x7,0x5,0x0,0xD,0xB,0x6,0x1,0x2,0x3,0xA,0xC,0xF,0x4,0xE,0x9,0x8},
+	{0xE,0xC,0x0,0xA,0x9,0x2,0xD,0xB,0x7,0x5,0x8,0xF,0x3,0x6,0x1,0x4},
+	{0x0,0x1,0x2,0xA,0x4,0xD,0x5,0xC,0x9,0x7,0x3,0xF,0xB,0x8,0x6,0xE},
+	{0x8,0x4,0xB,0x1,0x3,0x5,0x0,0x9,0x2,0xE,0xA,0xC,0xD,0x6,0x7,0xF}
+	};
+/* 1.2.643.2.2.31.3 */
+gost_subst_block Gost28147_CryptoProParamSetC= 
+	{
+	{0x7,0x4,0x0,0x5,0xA,0x2,0xF,0xE,0xC,0x6,0x1,0xB,0xD,0x9,0x3,0x8},
+	{0xA,0x9,0x6,0x8,0xD,0xE,0x2,0x0,0xF,0x3,0x5,0xB,0x4,0x1,0xC,0x7},
+	{0xC,0x9,0xB,0x1,0x8,0xE,0x2,0x4,0x7,0x3,0x6,0x5,0xA,0x0,0xF,0xD},
+	{0x8,0xD,0xB,0x0,0x4,0x5,0x1,0x2,0x9,0x3,0xC,0xE,0x6,0xF,0xA,0x7},
+	{0x3,0x6,0x0,0x1,0x5,0xD,0xA,0x8,0xB,0x2,0x9,0x7,0xE,0xF,0xC,0x4},
+	{0x8,0x2,0x5,0x0,0x4,0x9,0xF,0xA,0x3,0x7,0xC,0xD,0x6,0xE,0x1,0xB},
+	{0x0,0x1,0x7,0xD,0xB,0x4,0x5,0x2,0x8,0xE,0xF,0xC,0x9,0xA,0x6,0x3},
+	{0x1,0xB,0xC,0x2,0x9,0xD,0x0,0xF,0x4,0x5,0x8,0xE,0xA,0x7,0x6,0x3}
+	};
+
+/* 1.2.643.2.2.31.4 */ 
+gost_subst_block Gost28147_CryptoProParamSetD=
+	{
+	{0x1,0xA,0x6,0x8,0xF,0xB,0x0,0x4,0xC,0x3,0x5,0x9,0x7,0xD,0x2,0xE},
+	{0x3,0x0,0x6,0xF,0x1,0xE,0x9,0x2,0xD,0x8,0xC,0x4,0xB,0xA,0x5,0x7},
+	{0x8,0x0,0xF,0x3,0x2,0x5,0xE,0xB,0x1,0xA,0x4,0x7,0xC,0x9,0xD,0x6},
+	{0x0,0xC,0x8,0x9,0xD,0x2,0xA,0xB,0x7,0x3,0x6,0x5,0x4,0xE,0xF,0x1},
+	{0x1,0x5,0xE,0xC,0xA,0x7,0x0,0xD,0x6,0x2,0xB,0x4,0x9,0x3,0xF,0x8},
+	{0x1,0xC,0xB,0x0,0xF,0xE,0x6,0x5,0xA,0xD,0x4,0x8,0x9,0x3,0x7,0x2},
+	{0xB,0x6,0x3,0x4,0xC,0xF,0xE,0x2,0x7,0xD,0x8,0x0,0x5,0xA,0x9,0x1},
+	{0xF,0xC,0x2,0xA,0x6,0x4,0x5,0x0,0x7,0x9,0xE,0xD,0x1,0xB,0x8,0x3}
+	};
+
+
+const byte CryptoProKeyMeshingKey[]={
+	0x69, 0x00, 0x72, 0x22,   0x64, 0xC9, 0x04, 0x23,
+    0x8D, 0x3A, 0xDB, 0x96,   0x46, 0xE9, 0x2A, 0xC4,
+    0x18, 0xFE, 0xAC, 0x94,   0x00, 0xED, 0x07, 0x12,
+    0xC0, 0x86, 0xDC, 0xC2,   0xEF, 0x4C, 0xA9, 0x2B
+	};	
+/* Initialization of gost_ctx subst blocks*/
+static void kboxinit(gost_ctx *c, const gost_subst_block *b)
+	{ 
+	int i; 
+	
+	for (i = 0; i < 256; i++)
+		{
+		c->k87[i] = (b->k8[i>>4] <<4 | b->k7 [i &15])<<24;
+		c->k65[i] = (b->k6[i>>4] << 4 | b->k5 [i &15])<<16;
+		c->k43[i] = (b->k4[i>>4] <<4  | b->k3 [i &15])<<8;
+		c->k21[i] = b->k2[i>>4] <<4  | b->k1 [i &15];
+
+		}
+	}
+
+/* Part of GOST 28147 algorithm moved into separate function */
+static word32 f(gost_ctx *c,word32 x) 
+	{
+	x = c->k87[x>>24 & 255] | c->k65[x>>16 & 255]| 
+		c->k43[x>> 8 & 255] | c->k21[x & 255]; 
+	/* Rotate left 11 bits */ 
+	return x<<11 | x>>(32-11);
+	}
+/* Low-level encryption routine - encrypts one 64 bit block*/
+void gostcrypt(gost_ctx *c, const byte *in, byte *out)
+	{ 
+	register word32 n1, n2; /* As named in the GOST */ 
+	n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24); 
+	n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<24); 
+	/* Instead of swapping halves, swap names each round */ 
+ 	 
+	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); 
+	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); 
+	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); 
+	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); 
+  
+	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
+	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
+	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
+	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
+                               
+	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
+	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
+	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
+	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
+                               
+	n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
+	n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
+	n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
+	n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
+ 
+	out[0] = (byte)(n2&0xff);  out[1] = (byte)((n2>>8)&0xff);
+	out[2] = (byte)((n2>>16)&0xff); out[3]=(byte)(n2>>24); 
+	out[4] = (byte)(n1&0xff);  out[5] = (byte)((n1>>8)&0xff);
+	out[6] = (byte)((n1>>16)&0xff); out[7] = (byte)(n1>>24);
+	} 
+/* Low-level decryption routine. Decrypts one 64-bit block */
+void gostdecrypt(gost_ctx *c, const byte *in,byte *out)
+	{ 
+	register word32 n1, n2; /* As named in the GOST */ 
+	n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24); 
+	n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<24); 
+	
+	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); 
+	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); 
+	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
+	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); 
+	
+	n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
+	n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
+	n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
+	n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
+	
+	n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
+	n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
+	n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
+	n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
+	
+	n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
+	n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
+	n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
+	n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
+
+	out[0] = (byte)(n2&0xff);  out[1] = (byte)((n2>>8)&0xff);
+	out[2] = (byte)((n2>>16)&0xff); out[3]=(byte)(n2>>24);
+	out[4] = (byte)(n1&0xff);  out[5] = (byte)((n1>>8)&0xff);
+	out[6] = (byte)((n1>>16)&0xff); out[7] = (byte)(n1>>24);
+	} 
+
+/* Encrypts several blocks in ECB mode */
+void gost_enc(gost_ctx *c,const byte *clear,byte *cipher, int blocks)
+	{ 
+	int i; 
+	for(i=0;i<blocks;i++)
+		{ 
+		gostcrypt(c,clear,cipher); 
+		clear+=8;
+		cipher+=8;
+		}
+	}
+/* Decrypts several blocks in ECB mode */
+void gost_dec(gost_ctx *c, const byte *cipher,byte *clear, int blocks)
+	{ 
+	int i; 
+	for(i=0;i<blocks;i++)
+		{ 
+		gostdecrypt(c,cipher,clear); 
+		clear+=8; 
+		cipher+=8;
+		}
+	}
+
+/* Encrypts several full blocks in CFB mode using 8byte IV */
+void gost_enc_cfb(gost_ctx *ctx,const byte *iv,const byte *clear,byte *cipher, int blocks)
+	{
+	byte cur_iv[8];
+	byte gamma[8];
+	int i,j;
+	const byte *in;
+	byte *out;
+	memcpy(cur_iv,iv,8);
+	for(i=0,in=clear,out=cipher;i<blocks;i++,in+=8,out+=8)
+		{
+		gostcrypt(ctx,cur_iv,gamma);
+		for (j=0;j<8;j++)
+			{
+			cur_iv[j]=out[j]=in[j]^gamma[j];
+			}
+		}	
+	}	
+/* Decrypts several full blocks in CFB mode using 8byte IV */
+void gost_dec_cfb(gost_ctx *ctx,const byte *iv,const byte *cipher,byte *clear,  int blocks)
+	{
+	byte cur_iv[8];
+	byte gamma[8];
+	int i,j;
+	const byte *in;
+	byte *out;
+	memcpy(cur_iv,iv,8);
+	for(i=0,in=cipher,out=clear;i<blocks;i++,in+=8,out+=8)
+		{
+		gostcrypt(ctx,cur_iv,gamma);
+		for (j=0;j<8;j++)
+			{
+			out[j]=(cur_iv[j]=in[j])^gamma[j];
+			}
+		}	
+	}	
+
+/* Encrypts one block using specified key */
+void gost_enc_with_key(gost_ctx *c,byte *key,byte *inblock,byte *outblock) 
+	{
+	gost_key(c,key);
+	gostcrypt(c,inblock,outblock);
+	}
+
+/* Set 256 bit  key into context */
+void gost_key(gost_ctx *c, const byte *k) 
+	{ 
+	int i,j; 
+	for(i=0,j=0;i<8;i++,j+=4)
+		{
+		c->k[i]=k[j]|(k[j+1]<<8)|(k[j+2]<<16)|(k[j+3]<<24);
+		}		
+	} 
+
+/* Retrieve 256-bit key from context */
+void gost_get_key(gost_ctx *c, byte *k) 
+	{
+	int i,j; 
+	for(i=0,j=0;i<8;i++,j+=4)
+		{
+		k[j]=(byte)(c->k[i]& 0xFF);
+		k[j+1]=(byte)((c->k[i]>>8 )&0xFF);
+		k[j+2]=(byte)((c->k[i]>>16) &0xFF);
+		k[j+3]=(byte)((c->k[i]>>24) &0xFF);
+		}		
+	}
+
+/* Initalize context. Provides default value for subst_block */
+void gost_init(gost_ctx *c, const gost_subst_block *b)
+	{ 	
+	if(!b)
+		{
+		b=&GostR3411_94_TestParamSet;
+		}	
+	kboxinit(c,b); 
+	}
+
+/* Cleans up key from context */
+void gost_destroy(gost_ctx *c)
+	{ 
+	int i; for(i=0;i<8;i++) c->k[i]=0; 
+	} 
+
+/* Compute GOST 28147 mac block 
+ * 
+ * Parameters
+ *   gost_ctx *c - context initalized with substitution blocks and key
+ *   buffer - 8-byte mac state buffer
+ *   block 8-byte block to process.
+ * */
+void mac_block(gost_ctx *c,byte *buffer,const  byte *block)
+	{
+	register word32 n1, n2; /* As named in the GOST */ 
+	int i;
+	for (i=0; i<8; i++)
+		{
+		buffer[i]^=block[i];
+		}	  
+	n1 = buffer[0]|(buffer[1]<<8)|(buffer[2]<<16)|(buffer[3]<<24); 
+	n2 = buffer[4]|(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24); 
+	/* Instead of swapping halves, swap names each round */ 
+ 	 
+	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); 
+	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); 
+	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); 
+	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); 
+  
+	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
+	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
+	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
+	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
+
+	buffer[0] = (byte)(n1&0xff);  buffer[1] = (byte)((n1>>8)&0xff);
+	buffer[2] = (byte)((n1>>16)&0xff); buffer[3] = (byte)(n1>>24);
+	buffer[4] = (byte)(n2&0xff);  buffer[5] = (byte)((n2>>8)&0xff);
+	buffer[6] = (byte)((n2>>16)&0xff); buffer[7] = (byte)(n2>>24);
+	}
+
+/* Get mac with specified number of bits from MAC state buffer */
+void get_mac(byte *buffer,int nbits,byte *out)
+	{
+	int nbytes= nbits >> 3;
+	int rembits = nbits & 7;
+	int mask =rembits?((1<rembits)-1):0;
+	int i;
+	for (i=0;i<nbytes;i++) out[i]=buffer[i];
+	if (rembits) out[i]=buffer[i]&mask;
+	}	
+
+/* Compute mac of specified length (in bits) from data. 
+ * Context should be initialized with key and subst blocks */
+int gost_mac(gost_ctx *ctx,int mac_len,const unsigned char *data,
+	unsigned int data_len,unsigned char *mac) 
+	{
+	byte buffer[8]={0,0,0,0,0,0,0,0};
+	byte buf2[8];
+	unsigned int i;
+	for (i=0;i+8<=data_len;i+=8) 
+		mac_block(ctx,buffer,data+i);
+	if (i<data_len)
+		{
+		memset(buf2,0,8);
+		memcpy(buf2,data+i,data_len-i);
+		mac_block(ctx,buffer,buf2);
+		}	
+	get_mac(buffer,mac_len,mac);
+	return 1;
+	}
+
+/* Compute MAC with non-zero IV. Used in some RFC 4357 algorithms */
+int gost_mac_iv(gost_ctx *ctx,int mac_len,const unsigned char *iv,const unsigned char *data,
+	unsigned int data_len,unsigned char *mac) 
+	{
+	byte buffer[8];
+	byte buf2[8];
+	unsigned int i;
+	memcpy (buffer,iv,8);
+	for (i=0;i+8<=data_len;i+=8) 
+		mac_block(ctx,buffer,data+i);
+	if (i<data_len)
+		{
+		memset(buf2,0,8);
+		memcpy(buf2,data+i,data_len-i);
+		mac_block(ctx,buffer,buf2);
+		}	
+	get_mac(buffer,mac_len,mac);
+	return 1;
+	}
+
+/* Implements key meshing algorithm by modifing ctx and IV in place */
+void cryptopro_key_meshing(gost_ctx *ctx, unsigned char *iv)
+	{
+	unsigned char newkey[32],newiv[8];
+	/* Set static keymeshing key */
+	/* "Decrypt" key with keymeshing key */
+	gost_dec(ctx,CryptoProKeyMeshingKey,newkey,4);
+	/* set new key */
+	gost_key(ctx,newkey);
+	/* Encrypt iv with new key */
+	gostcrypt(ctx,iv,newiv);
+	memcpy(iv,newiv,8);
+	}
diff --git a/openssl/engines/ccgost/gost89.h b/openssl/engines/ccgost/gost89.h
new file mode 100644
index 0000000..2157852
--- /dev/null
+++ b/openssl/engines/ccgost/gost89.h
@@ -0,0 +1,96 @@
+/**********************************************************************
+ *                        gost89.h                                    *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *     This file is distributed under the same license as OpenSSL     *
+ *                                                                    *
+ *          Declarations for GOST 28147-89 encryption algorithm       *
+ *            No OpenSSL libraries required to compile and use        *
+ *                       this code                                    *
+ **********************************************************************/            
+#ifndef GOST89_H
+#define GOST89_H
+
+/* Typedef for unsigned 32-bit integer */
+#if __LONG_MAX__ > 2147483647L 
+typedef unsigned int u4; 
+#else 
+typedef unsigned long u4; 
+#endif 
+/* Typedef for unsigned 8-bit integer */
+typedef unsigned char byte; 
+
+/* Internal representation of GOST substitution blocks */
+typedef struct {
+		byte k8[16];
+		byte k7[16];
+		byte k6[16];
+		byte k5[16];
+		byte k4[16];
+		byte k3[16];
+		byte k2[16];
+		byte k1[16];
+} gost_subst_block;		
+
+
+/* Cipher context includes key and preprocessed  substitution block */
+typedef struct { 
+		u4 k[8]; 
+		/* Constant s-boxes -- set up in gost_init(). */ 
+		u4 k87[256],k65[256],k43[256],k21[256]; 
+} gost_ctx; 
+/* Note: encrypt and decrypt expect full blocks--padding blocks is 
+         caller's responsibility. All bulk encryption is done in 
+		 ECB mode by these calls. Other modes may be added easily 
+		 enough.                                            */
+/* Encrypt several full blocks in ECB mode */
+void gost_enc(gost_ctx *ctx, const byte *clear,byte *cipher, int blocks); 
+/* Decrypt several full blocks in ECB mode */
+void gost_dec(gost_ctx *ctx, const byte *cipher,byte *clear, int blocks); 
+/* Encrypts several full blocks in CFB mode using 8byte IV */
+void gost_enc_cfb(gost_ctx *ctx,const byte *iv,const byte *clear,byte *cipher,int  blocks);
+/* Decrypts several full blocks in CFB mode using 8byte IV */
+void gost_dec_cfb(gost_ctx *ctx,const byte *iv,const byte *cipher,byte *clear,int  blocks);
+
+/* Encrypt one  block */
+void gostcrypt(gost_ctx *c, const byte *in, byte *out);
+/* Decrypt one  block */
+void gostdecrypt(gost_ctx *c, const byte *in,byte *out);
+/* Set key into context */
+void gost_key(gost_ctx *ctx, const byte *key); 
+/* Get key from context */
+void gost_get_key(gost_ctx *ctx, byte *key);
+/* Set S-blocks into context */
+void gost_init(gost_ctx *ctx, const gost_subst_block *subst_block); 
+/* Clean up context */
+void gost_destroy(gost_ctx *ctx);
+/* Intermediate function used for calculate hash */
+void gost_enc_with_key(gost_ctx *,byte *key,byte *inblock,byte *outblock);
+/* Compute MAC of given length in bits from data */
+int gost_mac(gost_ctx *ctx,int hmac_len,const unsigned char *data,
+		unsigned int data_len,unsigned char *hmac) ;
+/* Compute MAC of given length in bits from data, using non-zero 8-byte
+ * IV (non-standard, for use in CryptoPro key transport only */
+int gost_mac_iv(gost_ctx *ctx,int hmac_len,const unsigned char *iv,const unsigned char *data,
+		unsigned int data_len,unsigned char *hmac) ;
+/* Perform one step of MAC calculation like gostcrypt */
+void mac_block(gost_ctx *c,byte *buffer,const  byte *block); 
+/* Extracts MAC value from mac state buffer */
+void get_mac(byte *buffer,int nbits,byte *out);
+/* Implements cryptopro key meshing algorithm. Expect IV to be 8-byte size*/
+void cryptopro_key_meshing(gost_ctx *ctx, unsigned char *iv);
+/* Parameter sets specified in RFC 4357 */
+extern gost_subst_block GostR3411_94_TestParamSet;
+extern gost_subst_block GostR3411_94_CryptoProParamSet;
+extern gost_subst_block Gost28147_TestParamSet;
+extern gost_subst_block Gost28147_CryptoProParamSetA;
+extern gost_subst_block Gost28147_CryptoProParamSetB;
+extern gost_subst_block Gost28147_CryptoProParamSetC;
+extern gost_subst_block Gost28147_CryptoProParamSetD;
+extern const byte CryptoProKeyMeshingKey[]; 
+#if __LONG_MAX__ > 2147483647L 
+typedef unsigned int word32; 
+#else 
+typedef unsigned long word32; 
+#endif 
+
+#endif
diff --git a/openssl/engines/ccgost/gost94_keyx.c b/openssl/engines/ccgost/gost94_keyx.c
new file mode 100644
index 0000000..0d7d3ff
--- /dev/null
+++ b/openssl/engines/ccgost/gost94_keyx.c
@@ -0,0 +1,291 @@
+/**********************************************************************
+ *                             gost94_keyx.c                          *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *         This file is distributed under the same license as OpenSSL *
+ *                                                                    *
+ *     Implements generation and parsing of GOST_KEY_TRANSPORT for    *
+ *     			GOST R 34.10-94 algorithms                            *
+ *																	  *
+ *          Requires OpenSSL 0.9.9 for compilation                    *
+ **********************************************************************/
+#include <string.h>
+#include <openssl/dh.h>
+#include <openssl/rand.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+
+#include "gost89.h"
+#include "gosthash.h"
+#include "e_gost_err.h"
+#include "gost_keywrap.h"
+#include "gost_lcl.h"
+/* Common functions for both 94 and 2001 key exchange schemes */
+/* Implementation of the Diffi-Hellman key agreement scheme based on
+ * GOST-94 keys */
+
+/* Computes Diffie-Hellman key and stores it into buffer in
+ * little-endian byte order as expected by both versions of GOST 94
+ * algorithm
+ */
+static int compute_pair_key_le(unsigned char *pair_key,BIGNUM *pub_key,DH *dh) 
+	{
+	unsigned char be_key[128];
+	int i,key_size;
+	key_size=DH_compute_key(be_key,pub_key,dh);
+	if (!key_size) return 0;
+	memset(pair_key,0,128);
+	for (i=0;i<key_size;i++)
+		{
+		pair_key[i]=be_key[key_size-1-i];
+		}
+	return key_size;	
+	}	
+
+/*
+ * Computes 256 bit Key exchange key as specified in RFC 4357 
+ */
+static int make_cp_exchange_key(BIGNUM *priv_key,EVP_PKEY *pubk, unsigned char *shared_key)
+	{
+	unsigned char dh_key [128];
+	int ret;
+	gost_hash_ctx hash_ctx;
+	DH *dh = DH_new();
+	
+	if (!dh)
+		return 0;
+	memset(dh_key,0,128);
+	dh->g = BN_dup(pubk->pkey.dsa->g);
+	dh->p = BN_dup(pubk->pkey.dsa->p);
+	dh->priv_key = BN_dup(priv_key);
+	ret=compute_pair_key_le(dh_key,((DSA *)(EVP_PKEY_get0(pubk)))->pub_key,dh) ;
+	DH_free(dh);
+	if (!ret)	return 0;
+	init_gost_hash_ctx(&hash_ctx,&GostR3411_94_CryptoProParamSet);
+	start_hash(&hash_ctx);
+	hash_block(&hash_ctx,dh_key,128);
+	finish_hash(&hash_ctx,shared_key);
+	done_gost_hash_ctx(&hash_ctx);
+	return 1;
+	}
+
+/* EVP_PKEY_METHOD callback derive. Implements VKO R 34.10-94 */
+
+int pkey_gost94_derive(EVP_PKEY_CTX *ctx,unsigned char *key,size_t *keylen)
+	{
+		EVP_PKEY *pubk = EVP_PKEY_CTX_get0_peerkey(ctx);
+		EVP_PKEY *mykey = EVP_PKEY_CTX_get0_pkey(ctx);
+		*keylen = 32;
+		if (key == NULL) return 1;
+
+		return make_cp_exchange_key(gost_get0_priv_key(mykey), pubk, key);
+	}
+
+/* EVP_PKEY_METHOD callback encrypt for
+ * GOST R 34.10-94 cryptopro modification
+ */
+
+
+int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* key, size_t key_len ) 
+	{
+	GOST_KEY_TRANSPORT *gkt=NULL;
+	unsigned char shared_key[32], ukm[8],crypted_key[44];
+	const struct gost_cipher_info *param=get_encryption_params(NULL);
+	EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(ctx);
+	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+	gost_ctx cctx;
+	int key_is_ephemeral=1;
+	EVP_PKEY *mykey = EVP_PKEY_CTX_get0_peerkey(ctx);
+
+	/* Do not use vizir cipher parameters with cryptopro */
+	if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param ==  gost_cipher_list)
+		{
+		param= gost_cipher_list+1;
+		}	
+
+	if (mykey) 
+		{
+		/* If key already set, it is not ephemeral */
+		key_is_ephemeral=0;
+		if (!gost_get0_priv_key(mykey)) 
+			{
+			GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
+			GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR);
+			goto err;
+			}	
+		} 
+	else 
+		{
+		/* Otherwise generate ephemeral key */
+		key_is_ephemeral = 1;
+		if (out) 
+			{
+			mykey = EVP_PKEY_new();
+			EVP_PKEY_assign(mykey, EVP_PKEY_base_id(pubk),DSA_new());
+			EVP_PKEY_copy_parameters(mykey,pubk);
+			if (!gost_sign_keygen(EVP_PKEY_get0(mykey))) 
+				{
+				goto err;
+				}	
+			}
+		}	
+	if (out)
+		make_cp_exchange_key(gost_get0_priv_key(mykey),pubk,shared_key);
+	if (data->shared_ukm) 
+		{
+		memcpy(ukm,data->shared_ukm,8);
+		}
+	else if (out) 
+		{	
+		if (RAND_bytes(ukm,8)<=0)
+			{
+			GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
+					GOST_R_RANDOM_GENERATOR_FAILURE);
+			goto err;
+			}	
+		}
+		
+	if (out) {
+		gost_init(&cctx,param->sblock);
+		keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key);
+	}	
+	gkt = GOST_KEY_TRANSPORT_new();
+	if (!gkt)
+		{
+		goto memerr;
+		}	
+	if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv,
+			ukm,8))
+		{
+		goto memerr;
+		}	
+	if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4))
+		{
+		goto memerr;
+		}
+	if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32))
+		{
+		goto memerr;
+		}
+	if (key_is_ephemeral) {	
+	if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,out?mykey:pubk))
+		{
+		GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
+		goto err;
+		}
+		if (out) EVP_PKEY_free(mykey);
+	}	
+	ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
+	gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
+	*outlen = i2d_GOST_KEY_TRANSPORT(gkt,out?&out:NULL);
+	if (*outlen <= 0)
+		{
+		GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO);
+		goto err;
+		}
+	if (!key_is_ephemeral)
+		{
+		/* Set control "public key from client certificate used" */
+		if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
+			{
+			GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
+				GOST_R_CTRL_CALL_FAILED);
+			goto err;
+			}
+		}
+	GOST_KEY_TRANSPORT_free(gkt);
+	return 1;	
+	memerr:
+		if (key_is_ephemeral) {
+			EVP_PKEY_free(mykey);
+		}	
+	GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
+		GOST_R_MALLOC_FAILURE);
+	err:		
+	GOST_KEY_TRANSPORT_free(gkt);
+	return -1;
+	}
+
+	
+/* EVP_PLEY_METHOD callback decrypt for
+ * GOST R 34.10-94 cryptopro modification
+ */
+int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *key_len,const unsigned char *in, size_t in_len) {
+	const unsigned char *p = in;
+	GOST_KEY_TRANSPORT *gkt = NULL;
+	unsigned char wrappedKey[44];
+	unsigned char sharedKey[32];
+	gost_ctx cctx;
+	const struct gost_cipher_info *param=NULL;
+	EVP_PKEY *eph_key=NULL, *peerkey=NULL;
+	EVP_PKEY *priv= EVP_PKEY_CTX_get0_pkey(ctx); 
+	
+	if (!key)
+		{
+		*key_len = 32;
+		return 1;
+		}	
+	
+	gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
+		in_len);
+	if (!gkt)
+		{
+		GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
+		return 0;
+		}	
+	eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key);
+	if (eph_key)
+		{
+		if (EVP_PKEY_derive_set_peer(ctx, eph_key) <= 0)
+			{
+			GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
+				GOST_R_INCOMPATIBLE_PEER_KEY);
+			goto err;
+			}
+		}
+	else
+		{
+		/* Set control "public key from client certificate used" */
+		if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
+			{
+			GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
+				GOST_R_CTRL_CALL_FAILED);
+			goto err;
+			}
+		}
+	peerkey = EVP_PKEY_CTX_get0_peerkey(ctx);
+	if (!peerkey)
+		{
+		GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
+			GOST_R_NO_PEER_KEY);
+		goto err;
+		}
+
+	param = get_encryption_params(gkt->key_agreement_info->cipher);
+    if(!param){
+        goto err;
+    }
+	
+	gost_init(&cctx,param->sblock);	
+	OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8);
+	memcpy(wrappedKey,gkt->key_agreement_info->eph_iv->data,8);
+	OPENSSL_assert(gkt->key_info->encrypted_key->length==32);
+	memcpy(wrappedKey+8,gkt->key_info->encrypted_key->data,32);
+	OPENSSL_assert(gkt->key_info->imit->length==4);
+	memcpy(wrappedKey+40,gkt->key_info->imit->data,4);	
+	make_cp_exchange_key(gost_get0_priv_key(priv),peerkey,sharedKey);
+	if (!keyUnwrapCryptoPro(&cctx,sharedKey,wrappedKey,key))
+		{
+		GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
+			GOST_R_ERROR_COMPUTING_SHARED_KEY);
+		goto err;
+		}	
+				
+	EVP_PKEY_free(eph_key);
+	GOST_KEY_TRANSPORT_free(gkt);
+	return 1;
+err:
+	EVP_PKEY_free(eph_key);
+	GOST_KEY_TRANSPORT_free(gkt);
+	return -1;
+	}	
+
diff --git a/openssl/engines/ccgost/gost_ameth.c b/openssl/engines/ccgost/gost_ameth.c
new file mode 100644
index 0000000..e6c2839
--- /dev/null
+++ b/openssl/engines/ccgost/gost_ameth.c
@@ -0,0 +1,908 @@
+/**********************************************************************
+ *                          gost_ameth.c                              *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *         This file is distributed under the same license as OpenSSL *
+ *                                                                    *
+ *       Implementation of RFC 4490/4491 ASN1 method                  *
+ *       for OpenSSL                                                  *
+ *          Requires OpenSSL 0.9.9 for compilation                    *
+ **********************************************************************/
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include "gost_params.h"
+#include "gost_lcl.h"
+#include "e_gost_err.h"
+
+int gost94_nid_by_params(DSA *p) 
+	{
+	R3410_params *gost_params;
+	BIGNUM *q=BN_new();
+	for (gost_params = R3410_paramset;gost_params->q!=NULL; gost_params++) 
+		{
+		BN_dec2bn(&q,gost_params->q);
+		if (!BN_cmp(q,p->q)) 
+			{
+			BN_free(q);
+			return gost_params->nid;
+			}
+		}	
+	BN_free(q);
+	return NID_undef;
+	}
+
+static ASN1_STRING  *encode_gost_algor_params(const EVP_PKEY *key)
+	{
+	ASN1_STRING *params = ASN1_STRING_new();
+	GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new();
+	int pkey_param_nid = NID_undef;
+
+	if (!params || !gkp) 
+		{
+		GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
+			ERR_R_MALLOC_FAILURE);
+		ASN1_STRING_free(params);
+		params = NULL;
+		goto err;
+		}	
+	switch (EVP_PKEY_base_id(key)) 
+		{
+		case NID_id_GostR3410_2001:
+			pkey_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)key)));
+			break;
+		case NID_id_GostR3410_94:
+			pkey_param_nid = (int) gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key));
+			if (pkey_param_nid == NID_undef) 
+				{
+				GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
+					GOST_R_INVALID_GOST94_PARMSET);
+				ASN1_STRING_free(params);
+				params=NULL;
+				goto err;
+				}	
+			break;
+		}	
+	gkp->key_params = OBJ_nid2obj(pkey_param_nid);
+	gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet);
+	/*gkp->cipher_params = OBJ_nid2obj(cipher_param_nid);*/
+	params->length = i2d_GOST_KEY_PARAMS(gkp, &params->data);
+	if (params->length <=0 ) 
+		{
+		GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
+			ERR_R_MALLOC_FAILURE);
+		ASN1_STRING_free(params);
+		params = NULL;
+		goto err;
+		}
+	params ->type = V_ASN1_SEQUENCE;
+	err:
+	GOST_KEY_PARAMS_free(gkp);
+	return params;
+	}
+
+/* Parses GOST algorithm parameters from X509_ALGOR and
+ * modifies pkey setting NID and parameters
+ */
+static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg) 
+	{
+	ASN1_OBJECT *palg_obj =NULL;
+	int ptype = V_ASN1_UNDEF;
+	int pkey_nid = NID_undef,param_nid = NID_undef;
+        void *_pval;
+	ASN1_STRING *pval = NULL;
+	const unsigned char  *p;
+	GOST_KEY_PARAMS *gkp = NULL;
+
+	X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg);
+        pval = _pval;
+	if (ptype != V_ASN1_SEQUENCE) 
+		{
+		GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
+			GOST_R_BAD_KEY_PARAMETERS_FORMAT);
+		return 0;
+		}	
+	p=pval->data;
+	pkey_nid = OBJ_obj2nid(palg_obj);
+
+	gkp = d2i_GOST_KEY_PARAMS(NULL,&p,pval->length);
+	if (!gkp) 
+		{
+		GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
+			GOST_R_BAD_PKEY_PARAMETERS_FORMAT);
+		return 0;
+		}	
+	param_nid = OBJ_obj2nid(gkp->key_params);
+	GOST_KEY_PARAMS_free(gkp);
+	EVP_PKEY_set_type(pkey,pkey_nid);
+	switch (pkey_nid) 
+		{
+		case NID_id_GostR3410_94:
+		{
+		DSA *dsa= EVP_PKEY_get0(pkey);
+		if (!dsa) 
+			{
+			dsa = DSA_new();
+			if (!EVP_PKEY_assign(pkey,pkey_nid,dsa)) return 0;
+			}
+		if (!fill_GOST94_params(dsa,param_nid)) return 0;
+		break;
+		}
+		case NID_id_GostR3410_2001:
+		{
+		EC_KEY *ec = EVP_PKEY_get0(pkey);
+		if (!ec) 
+			{
+			ec = EC_KEY_new();
+			if (!EVP_PKEY_assign(pkey,pkey_nid,ec)) return 0;
+			}
+		if (!fill_GOST2001_params(ec,param_nid)) return 0;
+		}
+		}
+
+	return 1;
+	}
+
+static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv) 
+	{
+	switch (EVP_PKEY_base_id(pkey)) 
+		{
+		case NID_id_GostR3410_94:
+		{
+		DSA *dsa = EVP_PKEY_get0(pkey);
+		if (!dsa) 
+			{
+			dsa = DSA_new();
+			EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),dsa);
+			}	
+		dsa->priv_key = BN_dup(priv);
+		if (!EVP_PKEY_missing_parameters(pkey)) 
+			gost94_compute_public(dsa);
+		break;
+		}	
+		case NID_id_GostR3410_2001:
+		{
+		EC_KEY *ec = EVP_PKEY_get0(pkey);
+		if (!ec) 
+			{
+			ec = EC_KEY_new();
+			EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),ec);
+			}	
+		if (!EC_KEY_set_private_key(ec,priv)) return 0;
+		if (!EVP_PKEY_missing_parameters(pkey)) 
+			gost2001_compute_public(ec);
+		break;
+		}
+		}
+	return 1;		
+	}
+BIGNUM* gost_get0_priv_key(const EVP_PKEY *pkey) 
+	{
+	switch (EVP_PKEY_base_id(pkey)) 
+		{
+		case NID_id_GostR3410_94:
+		{
+		DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey);
+		if (!dsa) 
+			{
+			return NULL;
+			}	
+		if (!dsa->priv_key) return NULL;
+		return dsa->priv_key;
+		break;
+		}	
+		case NID_id_GostR3410_2001:
+		{
+		EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey);
+		const BIGNUM* priv;
+		if (!ec) 
+			{
+			return NULL;
+			}	
+		if (!(priv=EC_KEY_get0_private_key(ec))) return NULL;
+		return (BIGNUM *)priv;
+		break;
+		}
+		}
+	return NULL;		
+	}
+
+static int pkey_ctrl_gost(EVP_PKEY *pkey, int op,
+	long arg1, void *arg2)
+	{
+	switch (op)
+		{
+		case ASN1_PKEY_CTRL_PKCS7_SIGN:
+			if (arg1 == 0) 
+				{
+				X509_ALGOR *alg1 = NULL, *alg2 = NULL;
+				int nid = EVP_PKEY_base_id(pkey);
+				PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO*)arg2, 
+					NULL, &alg1, &alg2);
+				X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94),
+					V_ASN1_NULL, 0);
+				if (nid == NID_undef) 
+					{
+					return (-1);
+					}
+				X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
+				}
+			return 1;
+		case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
+			if (arg1 == 0)
+				{
+				X509_ALGOR *alg;
+				ASN1_STRING * params = encode_gost_algor_params(pkey);
+				if (!params) 
+					{
+					return -1;
+					}
+				PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO*)arg2, &alg);
+				X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type),
+					V_ASN1_SEQUENCE, params);
+				}
+			return 1;
+		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+			*(int *)arg2 = NID_id_GostR3411_94;
+			return 2;
+		}
+	
+	return -2;
+	}
+/*----------------------- free functions * ------------------------------*/
+static void pkey_free_gost94(EVP_PKEY *key) 
+	{
+	if (key->pkey.dsa) 
+		{
+		DSA_free(key->pkey.dsa);
+		}
+	}
+
+static void pkey_free_gost01(EVP_PKEY *key) 
+	{
+	if (key->pkey.ec) 
+		{
+		EC_KEY_free(key->pkey.ec);
+		}
+	}	
+
+/* ------------------ private key functions  -----------------------------*/
+static int priv_decode_gost( EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) 
+	{
+	const unsigned char *pkey_buf = NULL,*p=NULL;
+	int priv_len = 0;
+	BIGNUM *pk_num=NULL;
+	int ret =0;
+	X509_ALGOR *palg =NULL;
+	ASN1_OBJECT *palg_obj = NULL;
+	ASN1_INTEGER *priv_key=NULL;
+
+	if (!PKCS8_pkey_get0(&palg_obj,&pkey_buf,&priv_len,&palg,p8inf)) 
+		return 0;
+	p = pkey_buf;
+	if (!decode_gost_algor_params(pk,palg)) 
+		{
+		return 0;
+		}
+	if (V_ASN1_OCTET_STRING == *p) 
+		{
+		/* New format - Little endian octet string */
+		unsigned char rev_buf[32];
+		int i;
+		ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL,&p,priv_len);
+		if (!s||s->length !=32) 
+			{
+			GOSTerr(GOST_F_PRIV_DECODE_GOST,
+				EVP_R_DECODE_ERROR);
+			return 0;	
+			}
+		for (i=0;i<32;i++)
+			{
+			rev_buf[31-i]=s->data[i];
+			}
+		ASN1_STRING_free(s);
+		pk_num = getbnfrombuf(rev_buf,32);
+		} 
+	else
+		{
+		priv_key=d2i_ASN1_INTEGER(NULL,&p,priv_len);
+		if (!priv_key) return 0;
+		ret= ((pk_num =  ASN1_INTEGER_to_BN(priv_key, NULL))!=NULL) ;
+		ASN1_INTEGER_free(priv_key);
+		if (!ret)
+			{
+			GOSTerr(GOST_F_PRIV_DECODE_GOST,
+				EVP_R_DECODE_ERROR);
+			return 0;	
+			}
+		}
+
+	ret= gost_set_priv_key(pk,pk_num);
+	BN_free(pk_num);
+	return ret;
+	}
+
+/* ----------------------------------------------------------------------*/
+static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk)
+	{
+	ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
+	ASN1_STRING *params = encode_gost_algor_params(pk);
+	unsigned char *priv_buf = NULL;
+	int priv_len;
+
+	ASN1_INTEGER *asn1key=NULL;
+	if (!params) 
+		{
+		return 0;
+		}
+	asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk),NULL);
+	priv_len = i2d_ASN1_INTEGER(asn1key,&priv_buf);
+	ASN1_INTEGER_free(asn1key);
+	return PKCS8_pkey_set0(p8,algobj,0,V_ASN1_SEQUENCE,params,
+		priv_buf,priv_len);
+	}
+/* --------- printing keys --------------------------------*/
+static int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent,
+	ASN1_PCTX *pctx, int type) 
+	{
+	int param_nid = NID_undef;
+
+	if (type == 2) 
+		{
+		BIGNUM *key;
+
+		if (!BIO_indent(out,indent,128)) return 0;
+		BIO_printf(out,"Private key: ");
+		key = gost_get0_priv_key(pkey);
+		if (!key) 
+			BIO_printf(out,"<undefined>");
+		else 
+			BN_print(out,key);
+		BIO_printf(out,"\n");
+		}
+	if (type >= 1)
+		{
+		BIGNUM *pubkey;
+		
+		pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key;
+		BIO_indent(out,indent,128);
+		BIO_printf(out,"Public key: ");
+		BN_print(out,pubkey);
+		BIO_printf(out,"\n");
+	}	
+
+	param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey));
+	BIO_indent(out,indent,128);
+	BIO_printf(out, "Parameter set: %s\n",OBJ_nid2ln(param_nid));
+	return 1;
+}
+
+static int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
+	ASN1_PCTX *pctx) 
+	{
+	return print_gost_94(out, pkey, indent, pctx,0);
+	}
+
+static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
+	ASN1_PCTX *pctx)
+	{
+	return print_gost_94(out,pkey, indent, pctx,1);
+	}
+static int priv_print_gost94(BIO *out,const EVP_PKEY *pkey, int indent,
+	ASN1_PCTX *pctx) 
+	{
+	return print_gost_94(out,pkey,indent,pctx,2);
+	}
+
+static int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent,
+	ASN1_PCTX *pctx, int type)
+	{
+	int param_nid = NID_undef;
+	if (type == 2) 
+		{
+		BIGNUM *key;
+
+		if (!BIO_indent(out,indent,128)) return 0;
+		BIO_printf(out,"Private key: ");
+		key = gost_get0_priv_key(pkey);
+		if (!key) 
+			BIO_printf(out,"<undefined)");
+		else 
+			BN_print(out,key);
+		BIO_printf(out,"\n");
+		}
+	if (type >= 1) 
+		{
+		BN_CTX *ctx = BN_CTX_new();
+		BIGNUM *X,*Y;
+		const EC_POINT *pubkey;
+		const EC_GROUP *group;
+
+		if (!ctx) 
+			{
+			GOSTerr(GOST_F_PRINT_GOST_01,ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		BN_CTX_start(ctx);
+		X = BN_CTX_get(ctx);
+		Y = BN_CTX_get(ctx);
+		pubkey = EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey));
+		group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey));
+		if (!EC_POINT_get_affine_coordinates_GFp(group,pubkey,X,Y,ctx)) 
+			{
+			GOSTerr(GOST_F_PRINT_GOST_01,ERR_R_EC_LIB);
+			BN_CTX_free(ctx);
+			return 0;
+			}
+		if (!BIO_indent(out,indent,128)) return 0;
+		BIO_printf(out,"Public key:\n");
+		if (!BIO_indent(out,indent+3,128)) return 0;
+		BIO_printf(out,"X:");
+		BN_print(out,X);
+		BIO_printf(out,"\n");
+		BIO_indent(out,indent+3,128);
+		BIO_printf(out,"Y:");
+		BN_print(out,Y);
+		BIO_printf(out,"\n");
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+		}
+
+	param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey)));
+	if (!BIO_indent(out,indent,128)) return 0;
+	BIO_printf(out,"Parameter set: %s\n",OBJ_nid2ln(param_nid));
+	return 1;
+}
+static int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
+	ASN1_PCTX *pctx) 
+	{	
+	return print_gost_01(out,pkey,indent,pctx,0);
+	}
+static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
+	ASN1_PCTX *pctx)
+	{
+	return print_gost_01(out,pkey, indent, pctx,1);
+	}
+static int priv_print_gost01(BIO *out,const EVP_PKEY *pkey, int indent,
+	ASN1_PCTX *pctx) 
+	{
+	return print_gost_01(out,pkey,indent,pctx,2);
+	}
+/* ---------------------------------------------------------------------*/
+static int param_missing_gost94(const EVP_PKEY *pk) 
+	{
+	const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
+	if (!dsa) return 1;
+	if (!dsa->q) return 1;
+	return 0;
+	}
+
+static int param_missing_gost01(const EVP_PKEY *pk) 
+	{
+	const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
+	if (!ec) return 1;
+	if (!EC_KEY_get0_group(ec)) return 1;
+	return 0;
+	}
+
+static int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from) 
+	{
+	const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from);
+	DSA *dto = EVP_PKEY_get0(to);
+	if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) 
+		{
+		GOSTerr(GOST_F_PARAM_COPY_GOST94,
+			GOST_R_INCOMPATIBLE_ALGORITHMS);
+		return 0;
+		}	
+	if (!dfrom) 
+		{
+		GOSTerr(GOST_F_PARAM_COPY_GOST94,
+			GOST_R_KEY_PARAMETERS_MISSING);
+		return 0;
+		}	
+	if (!dto) 
+		{
+		dto = DSA_new();
+		EVP_PKEY_assign(to,EVP_PKEY_base_id(from),dto);
+		}	
+#define COPYBIGNUM(a,b,x) if (a->x) BN_free(a->x); a->x=BN_dup(b->x);	
+	COPYBIGNUM(dto,dfrom,p)
+		COPYBIGNUM(dto,dfrom,q)
+		COPYBIGNUM(dto,dfrom,g)
+
+		if (dto->priv_key) 
+			gost94_compute_public(dto);
+	return 1;	
+	}
+static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) 
+	{
+	EC_KEY *eto = EVP_PKEY_get0(to);
+	const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from);
+	if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) 
+		{
+		GOSTerr(GOST_F_PARAM_COPY_GOST01,
+			GOST_R_INCOMPATIBLE_ALGORITHMS);
+		return 0;
+		}	
+	if (!efrom) 
+		{
+		GOSTerr(GOST_F_PARAM_COPY_GOST01,
+			GOST_R_KEY_PARAMETERS_MISSING);
+		return 0;
+		}	
+	if (!eto) 
+		{
+		eto = EC_KEY_new();
+		EVP_PKEY_assign(to,EVP_PKEY_base_id(from),eto);
+		}	
+	EC_KEY_set_group(eto,EC_KEY_get0_group(efrom));
+	if (EC_KEY_get0_private_key(eto)) 
+		{
+		gost2001_compute_public(eto);
+		}
+	return 1;
+	}
+
+static int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) 
+	{
+	const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a);
+	const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
+	if (!BN_cmp(da->q,db->q)) return 1;
+	return 0;
+	}
+
+static int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 
+	{
+	if (EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)a)))==
+		EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)b)))) 
+		{
+		return 1;
+		}
+	return 0;
+
+	}
+
+/* ---------- Public key functions * --------------------------------------*/
+static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub)
+	{
+	X509_ALGOR *palg = NULL;
+	const unsigned char *pubkey_buf = NULL;
+	unsigned char *databuf;
+	ASN1_OBJECT *palgobj = NULL;
+	int pub_len,i,j;
+	DSA *dsa;
+	ASN1_OCTET_STRING *octet= NULL;
+
+	if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len,
+			&palg, pub)) return 0;
+	EVP_PKEY_assign(pk,OBJ_obj2nid(palgobj),NULL);	
+	if (!decode_gost_algor_params(pk,palg)) return 0;
+	octet = d2i_ASN1_OCTET_STRING(NULL,&pubkey_buf,pub_len);
+	if (!octet) 
+		{
+		GOSTerr(GOST_F_PUB_DECODE_GOST94,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}	
+	databuf = OPENSSL_malloc(octet->length);
+	for (i=0,j=octet->length-1;i<octet->length;i++,j--)
+		{
+		databuf[j]=octet->data[i];
+		}	
+	dsa = EVP_PKEY_get0(pk);
+	dsa->pub_key=BN_bin2bn(databuf,octet->length,NULL);
+	ASN1_OCTET_STRING_free(octet);
+	OPENSSL_free(databuf);
+	return 1;
+
+	}
+
+static int pub_encode_gost94(X509_PUBKEY *pub,const EVP_PKEY *pk)
+	{
+	ASN1_OBJECT *algobj = NULL;
+	ASN1_OCTET_STRING *octet = NULL;
+	void *pval = NULL;
+	unsigned char *buf=NULL,*databuf,*sptr;
+	int i,j,data_len,ret=0;
+
+	int ptype = V_ASN1_UNDEF;
+	DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
+	algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
+	if (pk->save_parameters) 
+		{
+		ASN1_STRING *params = encode_gost_algor_params(pk);
+		pval = params;
+		ptype = V_ASN1_SEQUENCE;
+		}	
+	data_len = BN_num_bytes(dsa->pub_key);
+	databuf = OPENSSL_malloc(data_len);
+	BN_bn2bin(dsa->pub_key,databuf);
+	octet = ASN1_OCTET_STRING_new();
+	ASN1_STRING_set(octet,NULL,data_len);
+	sptr = ASN1_STRING_data(octet);
+	for (i=0,j=data_len-1; i< data_len;i++,j--)
+		{
+		sptr[i]=databuf[j];
+		}
+	OPENSSL_free(databuf);
+	ret = i2d_ASN1_OCTET_STRING(octet,&buf);
+	ASN1_BIT_STRING_free(octet);
+	if (ret <0)  return 0;
+	return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret);
+	}
+
+static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub)
+	{
+	X509_ALGOR *palg = NULL;
+	const unsigned char *pubkey_buf = NULL;
+	unsigned char *databuf;
+	ASN1_OBJECT *palgobj = NULL;
+	int pub_len,i,j;
+	EC_POINT *pub_key;
+	BIGNUM *X,*Y;
+	ASN1_OCTET_STRING *octet= NULL;
+	int len;
+	const EC_GROUP *group;
+
+	if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len,
+			&palg, pub)) return 0;
+	EVP_PKEY_assign(pk,OBJ_obj2nid(palgobj),NULL);	
+	if (!decode_gost_algor_params(pk,palg)) return 0;
+	group = EC_KEY_get0_group(EVP_PKEY_get0(pk));
+	octet = d2i_ASN1_OCTET_STRING(NULL,&pubkey_buf,pub_len);
+	if (!octet) 
+		{
+		GOSTerr(GOST_F_PUB_DECODE_GOST01,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}	
+	databuf = OPENSSL_malloc(octet->length);
+	for (i=0,j=octet->length-1;i<octet->length;i++,j--)
+		{
+		databuf[j]=octet->data[i];
+		}
+	len=octet->length/2;
+	ASN1_OCTET_STRING_free(octet);	
+	
+	Y= getbnfrombuf(databuf,len);
+	X= getbnfrombuf(databuf+len,len);
+	OPENSSL_free(databuf);
+	pub_key = EC_POINT_new(group);
+	if (!EC_POINT_set_affine_coordinates_GFp(group
+			,pub_key,X,Y,NULL))
+		{
+		GOSTerr(GOST_F_PUB_DECODE_GOST01,
+			ERR_R_EC_LIB);
+		EC_POINT_free(pub_key);
+		BN_free(X);
+		BN_free(Y);
+		return 0;
+		}	
+	BN_free(X);
+	BN_free(Y);
+	if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk),pub_key))
+		{
+		GOSTerr(GOST_F_PUB_DECODE_GOST01,
+			ERR_R_EC_LIB);
+		EC_POINT_free(pub_key);
+		return 0;
+		}	
+	EC_POINT_free(pub_key);
+	return 1;
+
+	}
+
+static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk)
+	{
+	ASN1_OBJECT *algobj = NULL;
+	ASN1_OCTET_STRING *octet = NULL;
+	void *pval = NULL;
+	unsigned char *buf=NULL,*databuf,*sptr;
+	int i,j,data_len,ret=0;
+	const EC_POINT *pub_key;
+	BIGNUM *X,*Y,*order;
+	const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
+	int ptype = V_ASN1_UNDEF;
+
+	algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
+	if (pk->save_parameters) 
+		{
+		ASN1_STRING *params = encode_gost_algor_params(pk);
+		pval = params;
+		ptype = V_ASN1_SEQUENCE;
+		}
+	order = BN_new();
+	EC_GROUP_get_order(EC_KEY_get0_group(ec),order,NULL);
+	pub_key=EC_KEY_get0_public_key(ec);
+	if (!pub_key) 
+		{
+		GOSTerr(GOST_F_PUB_ENCODE_GOST01,
+			GOST_R_PUBLIC_KEY_UNDEFINED);
+		return 0;
+		}	
+	X=BN_new();
+	Y=BN_new();
+	EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec),
+		pub_key,X,Y,NULL);
+	data_len = 2*BN_num_bytes(order);
+	BN_free(order);
+	databuf = OPENSSL_malloc(data_len);
+	memset(databuf,0,data_len);
+	
+	store_bignum(X,databuf+data_len/2,data_len/2);
+	store_bignum(Y,databuf,data_len/2);
+
+	BN_free(X);
+	BN_free(Y);
+	octet = ASN1_OCTET_STRING_new();
+	ASN1_STRING_set(octet,NULL,data_len);
+	sptr=ASN1_STRING_data(octet);
+    for (i=0,j=data_len-1;i<data_len;i++,j--) 
+		{
+        sptr[i]=databuf[j];
+		}
+    OPENSSL_free(databuf);
+	ret = i2d_ASN1_OCTET_STRING(octet,&buf);
+	ASN1_BIT_STRING_free(octet);
+	if (ret <0)  return 0;
+	return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret);
+	}
+
+static int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b)
+	{
+	const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a);
+	const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
+	if (da && db && da->pub_key && db->pub_key
+		&& !BN_cmp(da->pub_key,db->pub_key)) 
+		{
+		return 1;
+		}		
+	return 0;
+	}
+
+static int pub_cmp_gost01(const EVP_PKEY *a,const EVP_PKEY *b)
+	{
+	const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a);
+	const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b);
+	const EC_POINT *ka,*kb;
+	int ret=0;
+	if (!ea || !eb) return 0;
+	ka = EC_KEY_get0_public_key(ea);
+	kb = EC_KEY_get0_public_key(eb);
+	if (!ka || !kb) return 0;
+	ret = (0==EC_POINT_cmp(EC_KEY_get0_group(ea),ka,kb,NULL)) ;
+	return ret;
+	}
+
+
+
+
+static int pkey_size_gost(const EVP_PKEY *pk)
+	{
+	return 64;
+	}
+
+static int pkey_bits_gost(const EVP_PKEY *pk)
+	{
+	return 256;
+	}
+/*------------------------ ASN1 METHOD for GOST MAC  -------------------*/
+static void  mackey_free_gost(EVP_PKEY *pk)
+	{
+		if (pk->pkey.ptr) {
+			OPENSSL_free(pk->pkey.ptr);
+		}	
+	}
+static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+	switch (op)
+		{
+		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+			*(int *)arg2 = NID_id_Gost28147_89_MAC;
+			return 2;
+		}
+	return -2;
+}	
+
+static int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 
+{
+   int nid=gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey));
+   return i2d_ASN1_OBJECT(OBJ_nid2obj(nid),pder);
+}
+static int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 
+{
+   int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey)));
+   return i2d_ASN1_OBJECT(OBJ_nid2obj(nid),pder);
+}
+
+static int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
+{
+	ASN1_OBJECT *obj=NULL;
+	DSA *dsa = EVP_PKEY_get0(pkey);
+	int nid;
+	if (d2i_ASN1_OBJECT(&obj,pder,derlen)==NULL) {
+		return 0;
+	}
+	nid = OBJ_obj2nid(obj);
+	ASN1_OBJECT_free(obj);
+	if (!dsa) 
+		{
+		dsa=DSA_new();
+		if (!EVP_PKEY_assign(pkey,NID_id_GostR3410_94,dsa)) return 0;
+		}
+	if (!fill_GOST94_params(dsa,nid)) return 0;
+	return 1;
+}	
+
+static int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) {
+	ASN1_OBJECT *obj=NULL;
+	int nid;
+	EC_KEY *ec = EVP_PKEY_get0(pkey);
+	if (d2i_ASN1_OBJECT(&obj,pder,derlen)==NULL) {
+		return 0;
+	}
+	nid = OBJ_obj2nid(obj);
+	ASN1_OBJECT_free(obj);
+	if (!ec) 
+		{
+		ec = EC_KEY_new();
+		if (!EVP_PKEY_assign(pkey,NID_id_GostR3410_2001,ec)) return 0;
+		}	
+	if (!fill_GOST2001_params(ec, nid)) return 0;
+	return 1;
+}	
+
+
+
+
+
+/* ----------------------------------------------------------------------*/
+int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pemstr, const char* info) 
+	{
+	*ameth =	EVP_PKEY_asn1_new(nid, 
+		ASN1_PKEY_SIGPARAM_NULL, pemstr, info); 
+	if (!*ameth) return 0;
+	switch (nid) 
+		{
+		case NID_id_GostR3410_94:
+			EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost94);
+			EVP_PKEY_asn1_set_private (*ameth, 
+				priv_decode_gost, priv_encode_gost, 
+				priv_print_gost94);
+
+			EVP_PKEY_asn1_set_param (*ameth, 
+				gost94_param_decode, gost94_param_encode,
+				param_missing_gost94, param_copy_gost94, 
+				param_cmp_gost94,param_print_gost94 );
+			EVP_PKEY_asn1_set_public (*ameth,
+				pub_decode_gost94, pub_encode_gost94,
+				pub_cmp_gost94, pub_print_gost94,
+				pkey_size_gost, pkey_bits_gost);
+	
+			EVP_PKEY_asn1_set_ctrl (*ameth, pkey_ctrl_gost);
+			break;
+		case NID_id_GostR3410_2001:
+			EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost01);
+			EVP_PKEY_asn1_set_private (*ameth, 
+				priv_decode_gost, priv_encode_gost, 
+				priv_print_gost01);
+
+			EVP_PKEY_asn1_set_param (*ameth, 
+				gost2001_param_decode, gost2001_param_encode,
+				param_missing_gost01, param_copy_gost01, 
+				param_cmp_gost01, param_print_gost01);
+			EVP_PKEY_asn1_set_public (*ameth,
+				pub_decode_gost01, pub_encode_gost01,
+				pub_cmp_gost01, pub_print_gost01,
+				pkey_size_gost, pkey_bits_gost);
+	
+			EVP_PKEY_asn1_set_ctrl (*ameth, pkey_ctrl_gost);
+			break;
+		case NID_id_Gost28147_89_MAC:
+			EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost);
+			EVP_PKEY_asn1_set_ctrl(*ameth,mac_ctrl_gost);	
+			break;
+		}		
+	return 1;
+	}
diff --git a/openssl/engines/ccgost/gost_asn1.c b/openssl/engines/ccgost/gost_asn1.c
new file mode 100644
index 0000000..318ecfc
--- /dev/null
+++ b/openssl/engines/ccgost/gost_asn1.c
@@ -0,0 +1,55 @@
+/**********************************************************************
+ *                          gost_keytrans.c                           *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *         This file is distributed under the same license as OpenSSL *
+ *                                                                    *
+ *   ASN1 structure definition for GOST key transport                 *
+ *          Requires OpenSSL 0.9.9 for compilation                    *
+ **********************************************************************/
+#include <stdio.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "gost_lcl.h"
+
+ASN1_NDEF_SEQUENCE(GOST_KEY_TRANSPORT) = {
+	ASN1_SIMPLE(GOST_KEY_TRANSPORT, key_info, GOST_KEY_INFO),
+	ASN1_IMP(GOST_KEY_TRANSPORT, key_agreement_info, GOST_KEY_AGREEMENT_INFO, 0)
+} ASN1_NDEF_SEQUENCE_END(GOST_KEY_TRANSPORT)
+
+IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT)
+
+ASN1_NDEF_SEQUENCE(GOST_KEY_INFO) = {
+	ASN1_SIMPLE(GOST_KEY_INFO, encrypted_key, ASN1_OCTET_STRING),
+	ASN1_SIMPLE(GOST_KEY_INFO, imit,          ASN1_OCTET_STRING)
+} ASN1_NDEF_SEQUENCE_END(GOST_KEY_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_INFO)
+
+ASN1_NDEF_SEQUENCE(GOST_KEY_AGREEMENT_INFO) = {
+	ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, cipher, ASN1_OBJECT),
+	ASN1_IMP_OPT(GOST_KEY_AGREEMENT_INFO, ephem_key, X509_PUBKEY, 0),
+	ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, eph_iv, ASN1_OCTET_STRING)
+} ASN1_NDEF_SEQUENCE_END(GOST_KEY_AGREEMENT_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO)
+
+ASN1_NDEF_SEQUENCE(GOST_KEY_PARAMS) = {
+	ASN1_SIMPLE(GOST_KEY_PARAMS, key_params, ASN1_OBJECT),
+	ASN1_SIMPLE(GOST_KEY_PARAMS, hash_params, ASN1_OBJECT),
+	ASN1_OPT(GOST_KEY_PARAMS, cipher_params, ASN1_OBJECT),
+} ASN1_NDEF_SEQUENCE_END(GOST_KEY_PARAMS)
+
+IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_PARAMS)
+
+ASN1_NDEF_SEQUENCE(GOST_CIPHER_PARAMS) = {
+	ASN1_SIMPLE(GOST_CIPHER_PARAMS, iv, ASN1_OCTET_STRING),
+	ASN1_SIMPLE(GOST_CIPHER_PARAMS, enc_param_set, ASN1_OBJECT),
+} ASN1_NDEF_SEQUENCE_END(GOST_CIPHER_PARAMS)
+
+IMPLEMENT_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS)
+
+ASN1_NDEF_SEQUENCE(GOST_CLIENT_KEY_EXCHANGE_PARAMS) = { /*FIXME incomplete*/
+	ASN1_SIMPLE(GOST_CLIENT_KEY_EXCHANGE_PARAMS, gkt, GOST_KEY_TRANSPORT)
+} ASN1_NDEF_SEQUENCE_END(GOST_CLIENT_KEY_EXCHANGE_PARAMS)
+
+IMPLEMENT_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS)
diff --git a/openssl/engines/ccgost/gost_crypt.c b/openssl/engines/ccgost/gost_crypt.c
new file mode 100644
index 0000000..cde58c0
--- /dev/null
+++ b/openssl/engines/ccgost/gost_crypt.c
@@ -0,0 +1,617 @@
+/**********************************************************************
+ *                          gost_crypt.c                              *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *         This file is distributed under the same license as OpenSSL *
+ *                                                                    *
+ *       OpenSSL interface to GOST 28147-89 cipher functions          *
+ *          Requires OpenSSL 0.9.9 for compilation                    *
+ **********************************************************************/
+#include <string.h>
+#include "gost89.h"
+#include <openssl/rand.h>
+#include "e_gost_err.h"
+#include "gost_lcl.h"
+static int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, 
+	const unsigned char *iv, int enc);
+static int	gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+	const unsigned char *iv, int enc);
+/* Handles block of data in CFB mode */			
+static int	gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
+	const unsigned char *in, size_t inl);
+/* Handles block of data in CNT mode */			
+static int	gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out,
+	const unsigned char *in, size_t inl);
+/* Cleanup function */			
+static int gost_cipher_cleanup(EVP_CIPHER_CTX *);
+/* set/get cipher parameters */
+static int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params);
+static int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params);
+/* Control function */
+static int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr);
+
+EVP_CIPHER cipher_gost = 
+	{
+	NID_id_Gost28147_89,
+	1,/*block_size*/
+	32,/*key_size*/
+	8,/*iv_len */
+	EVP_CIPH_CFB_MODE| EVP_CIPH_NO_PADDING |
+	EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
+	gost_cipher_init,
+	gost_cipher_do_cfb,
+	gost_cipher_cleanup,
+	sizeof(struct ossl_gost_cipher_ctx),/* ctx_size */
+	gost89_set_asn1_parameters,
+	gost89_get_asn1_parameters,
+	gost_cipher_ctl,
+	NULL,
+	};
+
+EVP_CIPHER cipher_gost_cpacnt = 
+	{
+	NID_gost89_cnt,
+	1,/*block_size*/
+	32,/*key_size*/
+	8,/*iv_len */
+	EVP_CIPH_OFB_MODE| EVP_CIPH_NO_PADDING |
+	EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
+	gost_cipher_init_cpa,
+	gost_cipher_do_cnt,
+	gost_cipher_cleanup,
+	sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */
+	gost89_set_asn1_parameters,
+	gost89_get_asn1_parameters,
+	gost_cipher_ctl,
+	NULL,
+	};
+
+/* Implementation of GOST 28147-89 in MAC (imitovstavka) mode */
+/* Init functions which set specific parameters */
+static int gost_imit_init_cpa(EVP_MD_CTX *ctx);
+/* process block of data */
+static int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count);
+/* Return computed value */
+static int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md);
+/* Copies context */
+static int gost_imit_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from);
+static int gost_imit_cleanup(EVP_MD_CTX *ctx);
+/* Control function, knows how to set MAC key.*/
+static int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr);
+
+EVP_MD imit_gost_cpa =
+	{
+	NID_id_Gost28147_89_MAC,
+	NID_undef,
+	4,
+	0,
+	gost_imit_init_cpa,
+	gost_imit_update,
+	gost_imit_final,
+	gost_imit_copy,
+	gost_imit_cleanup,
+	NULL,
+	NULL,
+	{0,0,0,0,0},
+	8,
+	sizeof(struct ossl_gost_imit_ctx), 
+	gost_imit_ctrl
+	};
+
+/* 
+ * Correspondence between gost parameter OIDs and substitution blocks
+ * NID field is filed by register_gost_NID function in engine.c
+ * upon engine initialization
+ */
+
+struct gost_cipher_info gost_cipher_list[]=
+	{
+/* NID */  /* Subst block */          /* Key meshing*/
+/*{NID_id_GostR3411_94_CryptoProParamSet,&GostR3411_94_CryptoProParamSet,0},*/
+	{NID_id_Gost28147_89_cc,&GostR3411_94_CryptoProParamSet,0},
+	{NID_id_Gost28147_89_CryptoPro_A_ParamSet,&Gost28147_CryptoProParamSetA,1},
+	{NID_id_Gost28147_89_CryptoPro_B_ParamSet,&Gost28147_CryptoProParamSetB,1},
+	{NID_id_Gost28147_89_CryptoPro_C_ParamSet,&Gost28147_CryptoProParamSetC,1},
+	{NID_id_Gost28147_89_CryptoPro_D_ParamSet,&Gost28147_CryptoProParamSetD,1},
+	{NID_id_Gost28147_89_TestParamSet,&Gost28147_TestParamSet,1},
+	{NID_undef,NULL,0}
+	};	
+
+/*  get encryption parameters from crypto network settings
+	FIXME For now we use environment var CRYPT_PARAMS as place to 
+	store these settings. Actually, it is better to use engine control   command, read from configuration file to set them */
+const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj)
+	{
+	int nid;
+	struct gost_cipher_info *param;
+	if (!obj)
+		{
+		const char * params = get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS);
+		if (!params || !strlen(params)) 
+			return &gost_cipher_list[1];
+
+		nid = OBJ_txt2nid(params);
+		if (nid == NID_undef)
+			{
+			GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,
+				GOST_R_INVALID_CIPHER_PARAM_OID);
+			return NULL;
+			}	
+		}
+	else
+		{
+		nid= OBJ_obj2nid(obj);
+		}
+	for (param=gost_cipher_list;param->sblock!=NULL && param->nid!=nid; 
+		 param++);
+	if (!param->sblock)
+		{
+		GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,GOST_R_INVALID_CIPHER_PARAMS);
+		return NULL;
+		}	
+	return param;
+	}
+
+/* Sets cipher param from paramset NID. */
+static int gost_cipher_set_param(struct ossl_gost_cipher_ctx *c,int nid)
+	{
+	const struct gost_cipher_info *param;
+	param=get_encryption_params((nid==NID_undef?NULL:OBJ_nid2obj(nid)));
+	if (!param) return 0;
+	
+	c->paramNID = param->nid;
+	c->key_meshing=param->key_meshing;
+	c->count=0;
+	gost_init(&(c->cctx), param->sblock);
+	return 1;
+	}
+
+/* Initializes EVP_CIPHER_CTX by paramset NID */
+static int gost_cipher_init_param(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+	const unsigned char *iv, int enc, int paramNID,int mode)
+	{
+	struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
+	if (ctx->app_data == NULL)
+		{
+		if (!gost_cipher_set_param(c,paramNID)) return 0;
+		ctx->app_data = ctx->cipher_data;
+		}
+	if (key) gost_key(&(c->cctx),key);
+	if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+	memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
+	return 1;
+	}	
+
+static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+	const unsigned char *iv, int enc)
+	{
+	struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
+	gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
+	c->key_meshing=1;
+	c->count=0;
+	if(key) gost_key(&(c->cctx),key);
+	if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+	memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
+	return 1;
+	}
+
+/* Initializes EVP_CIPHER_CTX with default values */
+int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+	const unsigned char *iv, int enc)
+	{
+	return gost_cipher_init_param(ctx,key,iv,enc,NID_undef,EVP_CIPH_CFB_MODE);
+	}	
+/* Wrapper around gostcrypt function from gost89.c which perform
+ * key meshing when nesseccary 
+ */
+static void gost_crypt_mesh (void *ctx,unsigned char *iv,unsigned char *buf)
+	{
+	struct ossl_gost_cipher_ctx *c = ctx;
+	if (c->count&&c->key_meshing && c->count%1024==0)
+		{
+		cryptopro_key_meshing(&(c->cctx),iv);
+		}	
+	gostcrypt(&(c->cctx),iv,buf);
+	c->count+=8;
+	}
+
+static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf)
+	{
+	struct ossl_gost_cipher_ctx *c = ctx;
+	word32 g,go;
+	unsigned char buf1[8];
+	if (c->count && c->key_meshing && c->count %1024 ==0)
+		{
+		cryptopro_key_meshing(&(c->cctx),iv);
+		}
+	if (c->count==0)
+		{
+		gostcrypt(&(c->cctx),iv,buf1);
+		}
+	else
+		{
+		memcpy(buf1,iv,8);
+		}	
+	g = buf1[0]|(buf1[1]<<8)|(buf1[2]<<16)|(buf1[3]<<24);
+	g += 0x01010101;
+	buf1[0]=(unsigned char)(g&0xff);
+	buf1[1]=(unsigned char)((g>>8)&0xff);
+	buf1[2]=(unsigned char)((g>>16)&0xff);
+	buf1[3]=(unsigned char)((g>>24)&0xff);
+	g = buf1[4]|(buf1[5]<<8)|(buf1[6]<<16)|(buf1[7]<<24);
+	go = g;
+	g += 0x01010104;
+	if (go > g)      /*  overflow*/
+		g++;
+	buf1[4]=(unsigned char)(g&0xff);
+	buf1[5]=(unsigned char)((g>>8)&0xff);
+	buf1[6]=(unsigned char)((g>>16)&0xff);
+	buf1[7]=(unsigned char)((g>>24)&0xff);
+	memcpy(iv,buf1,8);
+	gostcrypt(&(c->cctx),buf1,buf);
+	c->count +=8;
+	}
+
+/* GOST encryption in CFB mode */
+int	gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
+	const unsigned char *in, size_t inl)
+	{
+	const unsigned char *in_ptr=in;
+	unsigned char *out_ptr=out;
+	size_t i=0;
+	size_t j=0;
+/* process partial block if any */
+	if (ctx->num) 
+		{
+		for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++) 
+			{
+			if (!ctx->encrypt) ctx->buf[j+8]=*in_ptr;
+			*out_ptr=ctx->buf[j]^(*in_ptr);
+			if (ctx->encrypt) ctx->buf[j+8]=*out_ptr;
+			}	
+		if (j==8)
+			{
+			memcpy(ctx->iv,ctx->buf+8,8);
+			ctx->num=0;
+			}
+		else
+			{
+			ctx->num=j;
+			return 1;
+			}	
+		}	
+
+	for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8)
+		{
+		/*block cipher current iv */
+		gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
+		/*xor next block of input text with it and output it*/
+		/*output this block */
+		if (!ctx->encrypt) memcpy(ctx->iv,in_ptr,8);
+		for (j=0;j<8;j++)
+			{
+			out_ptr[j]=ctx->buf[j]^in_ptr[j];
+			}	
+		/* Encrypt */
+		/* Next iv is next block of cipher text*/
+		if (ctx->encrypt) memcpy(ctx->iv,out_ptr,8);
+		}
+/* Process rest of buffer */
+	if (i<inl)
+		{
+		gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
+		if (!ctx->encrypt) memcpy(ctx->buf+8,in_ptr,inl-i);
+		for (j=0;i<inl;j++,i++)
+			{
+			out_ptr[j]=ctx->buf[j]^in_ptr[j];
+			}			
+		ctx->num = j;
+		if (ctx->encrypt) memcpy(ctx->buf+8,out_ptr,j);
+		}
+	else
+		{
+		ctx->num = 0;
+		}	
+	return 1;
+	}
+
+static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out,
+	const unsigned char *in, size_t inl)
+	{
+	const unsigned char *in_ptr=in;
+	unsigned char *out_ptr=out;
+	size_t i=0;
+	size_t j;
+/* process partial block if any */
+	if (ctx->num) 
+		{
+		for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++) 
+			{
+			*out_ptr=ctx->buf[j]^(*in_ptr);
+			}	
+		if (j==8)
+			{
+			ctx->num=0;
+			}
+		else
+			{
+			ctx->num=j;
+			return 1;
+			}	
+		}	
+
+	for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8)
+		{
+		/*block cipher current iv */
+		/* Encrypt */
+		gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
+		/*xor next block of input text with it and output it*/
+		/*output this block */
+		for (j=0;j<8;j++)
+			{
+			out_ptr[j]=ctx->buf[j]^in_ptr[j];
+			}	
+		}
+/* Process rest of buffer */
+	if (i<inl)
+		{
+		gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
+		for (j=0;i<inl;j++,i++)
+			{
+			out_ptr[j]=ctx->buf[j]^in_ptr[j];
+			}			
+		ctx->num = j;
+		}
+	else
+		{
+		ctx->num = 0;
+		}	
+	return 1;
+	}
+
+/* Cleaning up of EVP_CIPHER_CTX */
+int gost_cipher_cleanup(EVP_CIPHER_CTX *ctx) 
+	{
+	gost_destroy(&((struct ossl_gost_cipher_ctx *)ctx->cipher_data)->cctx);
+	ctx->app_data = NULL;
+	return 1;
+	}	
+
+/* Control function for gost cipher */
+int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr)
+	{
+	switch (type)
+		{
+		case EVP_CTRL_RAND_KEY:
+		{
+		if (RAND_bytes((unsigned char *)ptr,ctx->key_len)<=0)
+			{
+			GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_RANDOM_GENERATOR_ERROR);
+			return -1;
+			}
+		break;
+		}
+		case EVP_CTRL_PBE_PRF_NID:
+			if (ptr) {
+				*((int *)ptr)=  NID_id_HMACGostR3411_94;
+				return 1;
+			} else {
+				return 0;
+			}	
+				
+		default:
+			GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
+			return -1;
+		}
+	return 1;
+	}
+
+/* Set cipher parameters from ASN1 structure */
+int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params)
+	{
+	int len=0;
+	unsigned char *buf=NULL;
+	unsigned char *p=NULL;
+	struct ossl_gost_cipher_ctx *c = ctx->cipher_data;
+	GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new();
+	ASN1_OCTET_STRING *os = NULL;
+	if (!gcp)
+		{
+		GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
+		return 0;
+		}
+	if (!ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len))
+		{
+		GOST_CIPHER_PARAMS_free(gcp);
+		GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
+		return 0;
+		}
+	ASN1_OBJECT_free(gcp->enc_param_set);
+	gcp->enc_param_set = OBJ_nid2obj(c->paramNID);
+
+	len = i2d_GOST_CIPHER_PARAMS(gcp, NULL);
+	p = buf = (unsigned char*)OPENSSL_malloc(len);
+	if (!buf)
+		{
+		GOST_CIPHER_PARAMS_free(gcp);
+		GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
+		return 0;
+		}
+	i2d_GOST_CIPHER_PARAMS(gcp, &p);
+	GOST_CIPHER_PARAMS_free(gcp);
+
+	os = ASN1_OCTET_STRING_new();
+
+	if(!os || !ASN1_OCTET_STRING_set(os, buf, len))
+		{
+		OPENSSL_free(buf);
+		GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
+		return 0;
+		}
+	OPENSSL_free(buf);
+
+	ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
+	return 1;
+	}
+
+/* Store parameters into ASN1 structure */
+int  gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params)
+	{
+	int ret = -1;
+	int len; 
+	GOST_CIPHER_PARAMS *gcp = NULL;
+	unsigned char *p;
+	struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
+	if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE)
+		{
+		return ret;
+		}
+
+	p = params->value.sequence->data;
+
+	gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p,
+		params->value.sequence->length);
+
+	len = gcp->iv->length;
+	if (len != ctx->cipher->iv_len)
+		{
+		GOST_CIPHER_PARAMS_free(gcp);
+		GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS,
+			GOST_R_INVALID_IV_LENGTH);
+		return -1;
+		}
+	if (!gost_cipher_set_param(c,OBJ_obj2nid(gcp->enc_param_set)))
+		{
+		GOST_CIPHER_PARAMS_free(gcp);
+		return -1;
+		}
+	memcpy(ctx->oiv, gcp->iv->data, len);
+
+	GOST_CIPHER_PARAMS_free(gcp);
+
+	return 1;
+	}
+
+
+int gost_imit_init_cpa(EVP_MD_CTX *ctx)
+	{
+	struct ossl_gost_imit_ctx *c = ctx->md_data;
+	memset(c->buffer,0,sizeof(c->buffer));
+	memset(c->partial_block,0,sizeof(c->partial_block));
+	c->count = 0;
+	c->bytes_left=0;
+	c->key_meshing=1;
+	gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
+	return 1;
+	}
+
+static void mac_block_mesh(struct ossl_gost_imit_ctx *c,const unsigned char *data)
+	{
+	unsigned char buffer[8];
+	/* We are using local buffer for iv because CryptoPro doesn't 
+	 * interpret internal state of MAC algorithm as iv during keymeshing
+	 * (but does initialize internal state from iv in key transport
+	 */
+	if (c->key_meshing&& c->count && c->count %1024 ==0)
+		{
+		cryptopro_key_meshing(&(c->cctx),buffer);
+		}
+	mac_block(&(c->cctx),c->buffer,data);
+	c->count +=8;
+	}
+
+int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count)
+	{
+	struct ossl_gost_imit_ctx *c = ctx->md_data;
+	const unsigned char *p = data;
+	size_t bytes = count,i;
+	if (!(c->key_set)) {
+		GOSTerr(GOST_F_GOST_IMIT_UPDATE, GOST_R_MAC_KEY_NOT_SET);
+		return 0;
+	}
+	if (c->bytes_left)
+		{
+		for (i=c->bytes_left;i<8&&bytes>0;bytes--,i++,p++)
+			{
+			c->partial_block[i]=*p;
+			}
+		if (i==8)
+			{
+			mac_block_mesh(c,c->partial_block);
+			}
+		else
+			{
+			c->bytes_left = i;
+			return 1;
+			}		
+		}	
+	while (bytes>8)
+		{
+		mac_block_mesh(c,p);
+		p+=8;
+		bytes-=8;
+		}
+	if (bytes>0)
+		{
+		memcpy(c->partial_block,p,bytes);
+		}	
+	c->bytes_left=bytes;
+	return 1;
+	}
+
+int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md)
+	{
+	struct ossl_gost_imit_ctx *c = ctx->md_data;
+	if (!c->key_set) {
+		GOSTerr(GOST_F_GOST_IMIT_FINAL, GOST_R_MAC_KEY_NOT_SET);
+		return 0;
+	}
+	if (c->bytes_left)
+		{
+		int i;
+		for (i=c->bytes_left;i<8;i++)
+			{
+			c->partial_block[i]=0;
+			}
+		mac_block_mesh(c,c->partial_block);
+		}
+	get_mac(c->buffer,32,md);
+	return 1;
+	}
+
+int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr)
+	{
+	switch (type)
+		{
+		case EVP_MD_CTRL_KEY_LEN:
+			*((unsigned int*)(ptr)) = 32;
+			return 1;
+		case EVP_MD_CTRL_SET_KEY:
+		{
+		if (arg!=32) {
+			GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH);
+			return 0;
+		}
+
+		gost_key(&(((struct ossl_gost_imit_ctx*)(ctx->md_data))->cctx),ptr)	;
+		((struct ossl_gost_imit_ctx*)(ctx->md_data))->key_set = 1;
+		return 1;
+
+		}
+		default:
+			return 0;
+		}		
+	}
+
+int gost_imit_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
+	{
+	memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_imit_ctx));
+	return 1;
+	}
+
+/* Clean up imit ctx */
+int gost_imit_cleanup(EVP_MD_CTX *ctx)
+	{
+	memset(ctx->md_data,0,sizeof(struct ossl_gost_imit_ctx));
+	return 1;
+	}
+
diff --git a/openssl/engines/ccgost/gost_ctl.c b/openssl/engines/ccgost/gost_ctl.c
new file mode 100644
index 0000000..d3cd171
--- /dev/null
+++ b/openssl/engines/ccgost/gost_ctl.c
@@ -0,0 +1,89 @@
+/**********************************************************************
+ *                        gost_ctl.c                                  *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *       This file is distributed under the same license as OpenSSL   *
+ *                                                                    *
+ *        Implementation of control commands for GOST engine          *
+ *            OpenSSL 0.9.9 libraries required                        *
+ **********************************************************************/            
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/engine.h>
+#include <openssl/buffer.h>
+#include "gost_lcl.h"
+
+static char *gost_params[GOST_PARAM_MAX+1]={NULL};
+static const char *gost_envnames[]={"CRYPT_PARAMS"};
+const ENGINE_CMD_DEFN gost_cmds[]=
+	{
+/*	{ GOST_CTRL_RNG,
+	"RNG",
+	"Type of random number generator to use",
+	ENGINE_CMD_FLAG_STRING
+	},
+	{ GOST_CTRL_RNG_PARAMS,
+	"RNG_PARAMS",
+	"Parameter for random number generator",
+	ENGINE_CMD_FLAG_STRING
+	},
+*/	  { GOST_CTRL_CRYPT_PARAMS,
+		"CRYPT_PARAMS",
+		"OID of default GOST 28147-89 parameters",
+		ENGINE_CMD_FLAG_STRING
+			},
+{0,NULL,NULL,0}
+	};
+
+void gost_param_free() 
+{
+	int i;
+	for (i=0;i<=GOST_PARAM_MAX;i++) 
+		if (gost_params[i]!=NULL) 
+			{
+			OPENSSL_free(gost_params[i]);
+			gost_params[i]=NULL;
+			}
+		
+}
+
+int gost_control_func(ENGINE *e,int cmd,long i, void *p, void (*f)(void))
+	{
+	int param = cmd-ENGINE_CMD_BASE;
+	int ret=0;
+	if (param <0 || param >GOST_PARAM_MAX) return -1;
+	ret=gost_set_default_param(param,p);
+	return ret;
+	}
+
+const char *get_gost_engine_param(int param) 
+	{
+	char *tmp;
+	if (param <0 || param >GOST_PARAM_MAX) return NULL;
+	if (gost_params[param]!=NULL) 
+		{
+		return gost_params[param];
+		}
+	tmp = getenv(gost_envnames[param]);
+	if (tmp) 
+		{
+		if (gost_params[param]) OPENSSL_free(gost_params[param]);
+		gost_params[param] = BUF_strdup(tmp);
+		return gost_params[param];
+		}	
+	return NULL;
+	}	
+
+int gost_set_default_param(int param, const char *value) 
+	{
+	const char *tmp;
+	if (param <0 || param >GOST_PARAM_MAX) return 0;
+	tmp = getenv(gost_envnames[param]);
+	/* if there is value in the environment, use it, else -passed string * */
+	if (!tmp) tmp=value;
+	if (gost_params[param]) OPENSSL_free(gost_params[param]);
+	gost_params[param] = BUF_strdup(tmp);
+
+	return 1;
+	}	
diff --git a/openssl/engines/ccgost/gost_eng.c b/openssl/engines/ccgost/gost_eng.c
new file mode 100644
index 0000000..d2cbe3b
--- /dev/null
+++ b/openssl/engines/ccgost/gost_eng.c
@@ -0,0 +1,273 @@
+/**********************************************************************
+ *                          gost_eng.c                                *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *         This file is distributed under the same license as OpenSSL *
+ *                                                                    *
+ *              Main file of GOST engine                              *
+ *       for OpenSSL                                                  *
+ *          Requires OpenSSL 0.9.9 for compilation                    *
+ **********************************************************************/
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/engine.h>
+#include <openssl/obj_mac.h>
+#include "e_gost_err.h"
+#include "gost_lcl.h"
+static const char *engine_gost_id = "gost";
+static const char *engine_gost_name = "Reference implementation of GOST engine";
+
+/* Symmetric cipher and digest function registrar */
+
+static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
+	const int **nids, int nid);
+
+static int gost_digests(ENGINE *e, const EVP_MD **digest,
+	const int **nids, int ind);
+
+static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth,
+	const int **nids, int nid);
+
+static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
+	const int **nids, int nid);
+
+static int gost_cipher_nids[] =
+    {NID_id_Gost28147_89, NID_gost89_cnt,0};
+
+static int gost_digest_nids[] =
+	{NID_id_GostR3411_94,NID_id_Gost28147_89_MAC, 0};
+
+static int gost_pkey_meth_nids[] = 
+	{NID_id_GostR3410_94,
+	 NID_id_GostR3410_2001, NID_id_Gost28147_89_MAC, 0};
+
+static EVP_PKEY_METHOD *pmeth_GostR3410_94 = NULL,
+	 *pmeth_GostR3410_2001 = NULL,
+	*pmeth_Gost28147_MAC = NULL;
+
+static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_94 = NULL,
+	*ameth_GostR3410_2001 = NULL,
+	*ameth_Gost28147_MAC = NULL;
+
+
+static int gost_engine_init(ENGINE *e)
+	{ 
+	return 1;
+	}
+
+static int gost_engine_finish(ENGINE *e)
+	{ 
+	return 1;
+	}
+
+static int gost_engine_destroy(ENGINE *e)
+	{ 
+	gost_param_free();
+	return 1;
+	}
+
+static int bind_gost (ENGINE *e,const char *id) 
+	{
+	int ret = 0;
+	if (id && strcmp(id, engine_gost_id)) return 0;
+
+	if (!ENGINE_set_id(e, engine_gost_id)) 
+		{
+		printf("ENGINE_set_id failed\n"); 
+		goto end;
+		}	
+	if (!ENGINE_set_name(e, engine_gost_name)) 
+		{
+		printf("ENGINE_set_name failed\n");
+		goto end;
+		}	
+	if (!ENGINE_set_digests(e, gost_digests)) 
+		{
+		printf("ENGINE_set_digests failed\n");
+		goto end;
+		}	
+	if (! ENGINE_set_ciphers(e, gost_ciphers)) 
+		{
+		printf("ENGINE_set_ciphers failed\n");
+		goto end;
+		}	
+	if (! ENGINE_set_pkey_meths(e, gost_pkey_meths)) 
+		{
+		printf("ENGINE_set_pkey_meths failed\n");
+		goto end;
+		}	
+	if (! ENGINE_set_pkey_asn1_meths(e, gost_pkey_asn1_meths)) 
+		{
+		printf("ENGINE_set_pkey_asn1_meths failed\n");
+		goto end;
+		}	
+	/* Control function and commands */
+	if (!ENGINE_set_cmd_defns(e,gost_cmds)) 
+		{
+		fprintf(stderr,"ENGINE_set_cmd_defns failed\n");
+		goto end;
+		}	
+	if (!ENGINE_set_ctrl_function(e,gost_control_func)) 
+		{
+		fprintf(stderr,"ENGINE_set_ctrl_func failed\n");
+		goto end;
+		}	
+	if ( ! ENGINE_set_destroy_function(e, gost_engine_destroy)
+		|| ! ENGINE_set_init_function(e,gost_engine_init)
+		|| ! ENGINE_set_finish_function(e,gost_engine_finish))
+		{
+		goto end;
+		}
+
+	if (!register_ameth_gost(NID_id_GostR3410_94, &ameth_GostR3410_94, "GOST94", "GOST R 34.10-94")) goto end;
+	if (!register_ameth_gost(NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001", "GOST R 34.10-2001")) goto end;
+	if (!register_ameth_gost(NID_id_Gost28147_89_MAC, &ameth_Gost28147_MAC,
+		"GOST-MAC", "GOST 28147-89 MAC")) goto end;
+
+	if (!register_pmeth_gost(NID_id_GostR3410_94, &pmeth_GostR3410_94, 0)) goto end;
+	if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0)) goto end;
+	if (!register_pmeth_gost(NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0))
+		goto end;
+	if ( ! ENGINE_register_ciphers(e)
+		|| ! ENGINE_register_digests(e)
+		|| ! ENGINE_register_pkey_meths(e)
+		/* These two actually should go in LIST_ADD command */
+		|| ! EVP_add_cipher(&cipher_gost)
+		|| ! EVP_add_cipher(&cipher_gost_cpacnt)
+		|| ! EVP_add_digest(&digest_gost)
+		|| ! EVP_add_digest(&imit_gost_cpa)
+		)
+		{
+		goto end;
+		}
+
+	ERR_load_GOST_strings();
+	ret = 1;
+	end:
+	return ret;
+	}	
+
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+IMPLEMENT_DYNAMIC_BIND_FN(bind_gost)
+IMPLEMENT_DYNAMIC_CHECK_FN()
+#endif  /* ndef OPENSSL_NO_DYNAMIC_ENGINE */
+
+static int gost_digests(ENGINE *e, const EVP_MD **digest,
+	const int **nids, int nid)
+	{ 
+	int ok =1 ;
+	if (!digest) 
+		{
+		*nids = gost_digest_nids;
+		return 2; 
+		}
+	/*printf("Digest no %d requested\n",nid);*/
+	if(nid == NID_id_GostR3411_94) 
+		{
+		*digest = &digest_gost;
+		}
+	else if (nid == NID_id_Gost28147_89_MAC) 
+		{
+		*digest = &imit_gost_cpa;
+		}
+	else
+		{
+		ok =0;
+		*digest = NULL;
+		}
+	return ok;
+	}	
+	
+static int gost_ciphers (ENGINE *e,const EVP_CIPHER **cipher,
+	const int **nids, int nid) 
+	{
+	int ok = 1;
+	if (!cipher) 
+		{
+		*nids = gost_cipher_nids;
+		return 2; /* two ciphers are supported */
+		}
+
+	if(nid == NID_id_Gost28147_89) 
+		{
+		*cipher = &cipher_gost;
+		}
+	else if  (nid == NID_gost89_cnt) 
+		{
+		*cipher = &cipher_gost_cpacnt;
+		}
+	else	
+		{
+		ok = 0;
+		*cipher = NULL;
+		}
+	return ok;
+	}	
+
+static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth,
+	const int **nids, int nid)
+	{
+	if (!pmeth) 
+		{
+		*nids = gost_pkey_meth_nids;
+		return 3;
+		}
+
+	switch (nid) 
+		{
+		case NID_id_GostR3410_94: *pmeth = pmeth_GostR3410_94; return 1;
+		case NID_id_GostR3410_2001: *pmeth = pmeth_GostR3410_2001; return 1;
+		case NID_id_Gost28147_89_MAC: *pmeth = pmeth_Gost28147_MAC; return 1;
+		default:;
+		}
+	
+	*pmeth = NULL;
+	return 0;
+	}
+
+static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
+	const int **nids, int nid)
+	{
+	if (!ameth) 
+		{
+		*nids = gost_pkey_meth_nids;
+		return 3;
+		}
+	switch (nid) 
+		{
+		case NID_id_GostR3410_94: *ameth = ameth_GostR3410_94; return 1;
+		case NID_id_GostR3410_2001: *ameth = ameth_GostR3410_2001; return 1;
+		case NID_id_Gost28147_89_MAC: *ameth = ameth_Gost28147_MAC; return 1;
+	
+		default:;
+		}
+	
+	*ameth = NULL;
+	return 0;
+	}
+
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+static ENGINE *engine_gost(void)
+	{	
+	ENGINE *ret = ENGINE_new();
+	if (!ret)
+		return NULL;
+	if (!bind_gost(ret,engine_gost_id)) 
+		{
+		ENGINE_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+	
+void ENGINE_load_gost(void)
+	{
+	ENGINE *toadd =engine_gost();
+	if (!toadd) return;
+	ENGINE_add(toadd);
+	ENGINE_free(toadd);
+	ERR_clear_error();
+	}
+#endif	
+
diff --git a/openssl/engines/ccgost/gost_keywrap.c b/openssl/engines/ccgost/gost_keywrap.c
new file mode 100644
index 0000000..c618f6d
--- /dev/null
+++ b/openssl/engines/ccgost/gost_keywrap.c
@@ -0,0 +1,109 @@
+/**********************************************************************
+ *                          keywrap.c                                 *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *         This file is distributed under the same license as OpenSSL *
+ *                                                                    *
+ * Implementation of CryptoPro key wrap algorithm, as defined in      *
+ *               RFC 4357 p 6.3 and 6.4                               *
+ *                  Doesn't need OpenSSL                              *
+ **********************************************************************/
+#include <string.h>
+#include "gost89.h"
+#include "gost_keywrap.h"
+
+/* Diversifies key using random UserKey Material
+ * Implements RFC 4357 p 6.5 key diversification algorithm 
+ * 
+ * inputKey - 32byte key to be diversified
+ * ukm - 8byte user key material
+ * outputKey - 32byte buffer to store diversified key 
+ *
+ */
+void keyDiversifyCryptoPro(gost_ctx *ctx,const unsigned char *inputKey, const unsigned char *ukm, unsigned char *outputKey)
+	{
+
+	u4 k,s1,s2;
+	int i,j,mask;
+	unsigned char S[8];
+	memcpy(outputKey,inputKey,32);
+	for (i=0;i<8;i++) 
+		{
+		/* Make array of integers from key */
+		/* Compute IV S*/
+		s1=0,s2=0;
+		for (j=0,mask=1;j<8;j++,mask<<=1) 
+			{
+			k=((u4)outputKey[4*j])|(outputKey[4*j+1]<<8)|
+				(outputKey[4*j+2]<<16)|(outputKey[4*j+3]<<24);
+			if (mask & ukm[i]) 
+				{
+				s1+=k;
+				}
+			else 
+				{
+				s2+=k;
+				}
+			}
+		S[0]=(unsigned char)(s1&0xff);
+		S[1]=(unsigned char)((s1>>8)&0xff);
+		S[2]=(unsigned char)((s1>>16)&0xff);
+		S[3]=(unsigned char)((s1>>24)&0xff); 
+		S[4]=(unsigned char)(s2&0xff);
+		S[5]=(unsigned char)((s2>>8)&0xff);
+		S[6]=(unsigned char)((s2>>16)&0xff);
+		S[7]=(unsigned char)((s2>>24)&0xff); 
+		gost_key(ctx,outputKey);
+		gost_enc_cfb(ctx,S,outputKey,outputKey,4);
+		}
+	}	
+	
+
+/*
+ * Wraps key using RFC 4357 6.3
+ * ctx - gost encryption context, initialized with some S-boxes 
+ * keyExchangeKey (KEK) 32-byte (256-bit) shared key
+ * ukm - 8 byte (64 bit) user key material, 
+ * sessionKey - 32-byte (256-bit) key to be wrapped
+ * wrappedKey - 44-byte buffer to store wrapped key
+ */ 
+
+int keyWrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey, const unsigned char *ukm,
+	const	unsigned char *sessionKey, unsigned char *wrappedKey) 
+	{
+	unsigned char kek_ukm[32];
+	keyDiversifyCryptoPro(ctx,keyExchangeKey,ukm,kek_ukm);
+	gost_key(ctx,kek_ukm);
+	memcpy(wrappedKey,ukm,8);
+	gost_enc(ctx,sessionKey,wrappedKey+8,4);
+	gost_mac_iv(ctx,32,ukm,sessionKey,32,wrappedKey+40);
+	return 1;
+	}
+/*
+ * Unwraps key using RFC 4357 6.4
+ * ctx - gost encryption context, initialized with some S-boxes 
+ * keyExchangeKey 32-byte shared key
+ * wrappedKey  44 byte key to be unwrapped (concatenation of 8-byte UKM,
+ * 32 byte  encrypted key and 4 byte MAC  
+ * 
+ * sessionKEy - 32byte buffer to store sessionKey in
+ * Returns 1 if key is decrypted successfully, and 0 if MAC doesn't match
+ */ 
+
+int keyUnwrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey,
+	const unsigned char *wrappedKey, unsigned char *sessionKey) 
+	{
+	unsigned char kek_ukm[32],cek_mac[4];
+	keyDiversifyCryptoPro(ctx,keyExchangeKey,wrappedKey 
+		/* First 8 bytes of wrapped Key is ukm */
+		,kek_ukm);
+	gost_key(ctx,kek_ukm);
+	gost_dec(ctx,wrappedKey+8,sessionKey,4);
+	gost_mac_iv(ctx,32,wrappedKey,sessionKey,32,cek_mac);
+	if (memcmp(cek_mac,wrappedKey+40,4)) 
+		{
+		return 0;
+		}		
+	return 1;		
+	}	
+
+
diff --git a/openssl/engines/ccgost/gost_keywrap.h b/openssl/engines/ccgost/gost_keywrap.h
new file mode 100644
index 0000000..37c2a0f
--- /dev/null
+++ b/openssl/engines/ccgost/gost_keywrap.h
@@ -0,0 +1,56 @@
+/**********************************************************************
+ *                         gost_keywrap.h                             *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *       This file is distributed under the same license as OpenSSL   *
+ *                                                                    *
+ * Implementation of CryptoPro key wrap algorithm, as defined in      *
+ * RFC 4357 p 6.3 and 6.4                                             *
+ * Doesn't need OpenSSL                                               *
+ **********************************************************************/
+#ifndef GOST_KEYWRAP_H
+#define GOST_KEYWRAP_H
+#include <string.h>
+#include "gost89.h"
+/* Diversifies key using random UserKey Material
+ * Implements RFC 4357 p 6.5 key diversification algorithm 
+ * 
+ * inputKey - 32byte key to be diversified
+ * ukm - 8byte user key material
+ * outputKey - 32byte buffer to store diversified key 
+ *
+ */
+void keyDiversifyCryptoPro(gost_ctx *ctx,
+	const unsigned char *inputKey, 
+	const unsigned char *ukm, 
+	unsigned char *outputKey);
+/*
+ * Wraps key using RFC 4357 6.3
+ * ctx - gost encryption context, initialized with some S-boxes 
+ * keyExchangeKey (KEK) 32-byte (256-bit) shared key
+ * ukm - 8 byte (64 bit) user key material, 
+ * sessionKey - 32-byte (256-bit) key to be wrapped
+ * wrappedKey - 44-byte buffer to store wrapped key
+ */ 
+
+int keyWrapCryptoPro(gost_ctx *ctx,
+	const unsigned char *keyExchangeKey, 
+	const unsigned char *ukm,
+	const	unsigned char *sessionKey, 
+	unsigned char *wrappedKey) ;
+/*
+ * Unwraps key using RFC 4357 6.4
+ * ctx - gost encryption context, initialized with some S-boxes 
+ * keyExchangeKey 32-byte shared key
+ * wrappedKey  44 byte key to be unwrapped (concatenation of 8-byte UKM,
+ * 32 byte  encrypted key and 4 byte MAC  
+ * 
+ * sessionKEy - 32byte buffer to store sessionKey in
+ * Returns 1 if key is decrypted successfully, and 0 if MAC doesn't match
+ */ 
+
+
+int keyUnwrapCryptoPro(gost_ctx *ctx,
+	const unsigned char *keyExchangeKey,
+	const unsigned char *wrappedKey, 
+	unsigned char *sessionKey) ;
+#endif
diff --git a/openssl/engines/ccgost/gost_lcl.h b/openssl/engines/ccgost/gost_lcl.h
new file mode 100644
index 0000000..437a48c
--- /dev/null
+++ b/openssl/engines/ccgost/gost_lcl.h
@@ -0,0 +1,218 @@
+#ifndef GOST_TOOLS_H
+#define GOST_TOOLS_H
+/**********************************************************************
+ *                        gost_lcl.h                                  *
+ *             Copyright (c) 2006 Cryptocom LTD                       *
+ *       This file is distributed under the same license as OpenSSL   *
+ *                                                                    *
+ *         Internal declarations  used in GOST engine                *
+ *         OpenSSL 0.9.9 libraries required to compile and use        *
+ *                              this code                             *
+ **********************************************************************/ 
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/dsa.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/engine.h>
+#include <openssl/ec.h>
+#include "gost89.h"
+#include "gosthash.h"
+/* Control commands */
+#define GOST_PARAM_CRYPT_PARAMS 0
+#define GOST_PARAM_MAX 0
+#define GOST_CTRL_CRYPT_PARAMS (ENGINE_CMD_BASE+GOST_PARAM_CRYPT_PARAMS)
+
+	extern const ENGINE_CMD_DEFN gost_cmds[];
+	int gost_control_func(ENGINE *e,int cmd, long i, void *p, void (*f)(void));
+	const char *get_gost_engine_param(int param);	
+	int gost_set_default_param(int param, const char *value); 
+	void gost_param_free(void);
+
+/* method registration */
+
+	int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pemstr, const char* info);
+	int register_pmeth_gost (int id, EVP_PKEY_METHOD **pmeth, int flags);
+
+/* Gost-specific pmeth control-function parameters */
+/* For GOST R34.10 parameters */
+#define param_ctrl_string "paramset"
+#define EVP_PKEY_CTRL_GOST_PARAMSET (EVP_PKEY_ALG_CTRL+1)
+/* For GOST 28147 MAC */
+#define key_ctrl_string "key"
+#define hexkey_ctrl_string "hexkey"
+#define EVP_PKEY_CTRL_GOST_MAC_HEXKEY (EVP_PKEY_ALG_CTRL+3)
+/* Pmeth internal representation */
+	struct gost_pmeth_data {
+   	    int sign_param_nid; /* Should be set whenever parameters are filled */
+		EVP_MD *md;
+		unsigned char *shared_ukm;
+		int peer_key_used;
+	};
+
+	struct gost_mac_pmeth_data {
+		int key_set;
+		EVP_MD *md;
+		unsigned char key[32];
+	}	;
+/* GOST-specific ASN1 structures */
+
+
+typedef struct {
+	ASN1_OCTET_STRING *encrypted_key;
+	ASN1_OCTET_STRING *imit;
+} GOST_KEY_INFO;
+
+DECLARE_ASN1_FUNCTIONS(GOST_KEY_INFO)
+
+typedef struct {
+	ASN1_OBJECT *cipher;
+	X509_PUBKEY *ephem_key;
+	ASN1_OCTET_STRING *eph_iv;
+} GOST_KEY_AGREEMENT_INFO;
+
+DECLARE_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO)
+	
+typedef struct {
+	GOST_KEY_INFO *key_info;
+	GOST_KEY_AGREEMENT_INFO *key_agreement_info;
+} GOST_KEY_TRANSPORT;
+
+DECLARE_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT)
+
+typedef struct { /* FIXME incomplete */
+	GOST_KEY_TRANSPORT *gkt;
+} GOST_CLIENT_KEY_EXCHANGE_PARAMS;
+
+/* Hacks to shorten symbols to 31 characters or less, or OpenVMS.
+   This mimics what's done in symhacks.h, but since this is a very
+   local header file, I prefered to put this hack directly here.
+   -- Richard Levitte */
+#ifdef OPENSSL_SYS_VMS
+#undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_it
+#define GOST_CLIENT_KEY_EXCHANGE_PARAMS_it	GOST_CLIENT_KEY_EXC_PARAMS_it
+#undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_new
+#define GOST_CLIENT_KEY_EXCHANGE_PARAMS_new	GOST_CLIENT_KEY_EXC_PARAMS_new
+#undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_free
+#define GOST_CLIENT_KEY_EXCHANGE_PARAMS_free	GOST_CLIENT_KEY_EXC_PARAMS_free
+#undef d2i_GOST_CLIENT_KEY_EXCHANGE_PARAMS
+#define d2i_GOST_CLIENT_KEY_EXCHANGE_PARAMS	d2i_GOST_CLIENT_KEY_EXC_PARAMS
+#undef i2d_GOST_CLIENT_KEY_EXCHANGE_PARAMS
+#define i2d_GOST_CLIENT_KEY_EXCHANGE_PARAMS	i2d_GOST_CLIENT_KEY_EXC_PARAMS
+#endif /* End of hack */
+DECLARE_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS)
+typedef struct {
+	ASN1_OBJECT *key_params;
+	ASN1_OBJECT *hash_params;
+	ASN1_OBJECT *cipher_params;
+} GOST_KEY_PARAMS;
+
+DECLARE_ASN1_FUNCTIONS(GOST_KEY_PARAMS)
+
+typedef struct {
+	ASN1_OCTET_STRING *iv;
+	ASN1_OBJECT *enc_param_set;
+} GOST_CIPHER_PARAMS; 
+
+DECLARE_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS)
+/*============== Message digest  and cipher related structures  ==========*/
+	 /* Structure used as EVP_MD_CTX-md_data. 
+	  * It allows to avoid storing in the md-data pointers to
+	  * dynamically allocated memory.
+	  *
+	  * I cannot invent better way to avoid memory leaks, because
+	  * openssl insist on invoking Init on Final-ed digests, and there
+	  * is no reliable way to find out whether pointer in the passed
+	  * md_data is valid or not.
+	  * */
+struct ossl_gost_digest_ctx {
+	gost_hash_ctx dctx;
+	gost_ctx cctx;
+};	
+/* EVP_MD structure for GOST R 34.11 */
+extern EVP_MD digest_gost;
+/* EVP_MD structure for GOST 28147 in MAC mode */
+extern EVP_MD imit_gost_cpa;
+/* Cipher context used for EVP_CIPHER operation */
+struct ossl_gost_cipher_ctx {
+	int paramNID;
+	off_t count;
+	int key_meshing;
+	gost_ctx cctx;
+};	
+/* Structure to map parameter NID to S-block */
+struct gost_cipher_info {
+	int nid;
+	gost_subst_block *sblock;
+	int key_meshing;
+};
+/* Context for MAC */
+struct ossl_gost_imit_ctx {
+	gost_ctx cctx;
+	unsigned char buffer[8];
+	unsigned char partial_block[8];
+	off_t count;
+	int key_meshing;
+	int bytes_left;
+	int key_set;
+};	
+/* Table which maps parameter NID to S-blocks */
+extern struct gost_cipher_info gost_cipher_list[];
+/* Find encryption params from ASN1_OBJECT */
+const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj);
+/* Implementation of GOST 28147-89 cipher in CFB and CNT modes */
+extern EVP_CIPHER cipher_gost;
+extern EVP_CIPHER cipher_gost_cpacnt;
+#define EVP_MD_CTRL_KEY_LEN (EVP_MD_CTRL_ALG_CTRL+3)
+#define EVP_MD_CTRL_SET_KEY (EVP_MD_CTRL_ALG_CTRL+4)
+/* EVP_PKEY_METHOD key encryption callbacks */
+/* From gost94_keyx.c */
+int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* key, size_t key_len );
+
+int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* in, size_t in_len );
+/* From gost2001_keyx.c */
+int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* key, size_t key_len );
+
+int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* in, size_t in_len );
+/* derive functions */
+/* From gost2001_keyx.c */
+int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
+/* From gost94_keyx.c */
+int pkey_gost94_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
+/* Internal functions for signature algorithms */
+int fill_GOST94_params(DSA *dsa,int nid);
+int fill_GOST2001_params(EC_KEY *eckey, int nid);
+int gost_sign_keygen(DSA *dsa) ;
+int gost2001_keygen(EC_KEY *ec) ;
+
+DSA_SIG *gost_do_sign(const unsigned char *dgst,int dlen, DSA *dsa) ;
+DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey);
+
+int gost_do_verify(const unsigned char *dgst, int dgst_len,
+		DSA_SIG *sig, DSA *dsa) ;
+int gost2001_do_verify(const unsigned char *dgst,int dgst_len,
+			DSA_SIG *sig, EC_KEY *ec);
+int gost2001_compute_public(EC_KEY *ec) ;
+int gost94_compute_public(DSA *dsa) ;
+/*============== miscellaneous functions============================= */
+/* from gost_sign.c */
+/* Convert GOST R 34.11 hash sum to bignum according to standard */
+BIGNUM *hashsum2bn(const unsigned char *dgst) ;
+/* Store bignum in byte array of given length, prepending by zeros
+ * if nesseccary */
+int store_bignum(BIGNUM *bn, unsigned char *buf,int len);
+/* Read bignum, which can have few MSB all-zeros    from buffer*/ 
+BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len);
+/* Pack GOST R 34.10 signature according to CryptoPro rules */
+int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen); 
+/* Unpack GOST R 34.10 signature according to CryptoPro rules */
+DSA_SIG *unpack_cp_signature(const unsigned char *sig,size_t siglen) ;
+/* from ameth.c */
+/* Get private key as BIGNUM from both R 34.10-94 and R 34.10-2001  keys*/
+/* Returns pointer into EVP_PKEY structure */
+BIGNUM* gost_get0_priv_key(const EVP_PKEY *pkey) ;
+/* Find NID by GOST 94 parameters */
+int gost94_nid_by_params(DSA *p) ;
+
+
+#endif
diff --git a/openssl/engines/ccgost/gost_md.c b/openssl/engines/ccgost/gost_md.c
new file mode 100644
index 0000000..417e108
--- /dev/null
+++ b/openssl/engines/ccgost/gost_md.c
@@ -0,0 +1,75 @@
+/**********************************************************************
+ *                          md_gost.c                                 *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *         This file is distributed under the same license as OpenSSL *
+ *                                                                    *
+ *       OpenSSL interface to GOST R 34.11-94 hash functions          *
+ *          Requires OpenSSL 0.9.9 for compilation                    *
+ **********************************************************************/
+#include <string.h>
+#include "gost_lcl.h"
+#include "gosthash.h"
+#include "e_gost_err.h"
+
+/* implementation of GOST 34.11 hash function See gost_md.c*/
+static int gost_digest_init(EVP_MD_CTX *ctx);
+static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count);
+static int gost_digest_final(EVP_MD_CTX *ctx,unsigned char *md);
+static int gost_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from);
+static int gost_digest_cleanup(EVP_MD_CTX *ctx);
+
+EVP_MD digest_gost=  
+	{
+	NID_id_GostR3411_94,
+	NID_undef,
+	32,
+	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE,
+	gost_digest_init,
+	gost_digest_update,
+	gost_digest_final,
+	gost_digest_copy,
+	gost_digest_cleanup,
+	NULL,
+	NULL,
+	{NID_undef,NID_undef,0,0,0},
+	32,
+	sizeof(struct ossl_gost_digest_ctx ),
+	NULL
+	};
+
+int gost_digest_init(EVP_MD_CTX *ctx) 
+	{
+	struct ossl_gost_digest_ctx *c = ctx->md_data;
+	memset(&(c->dctx),0,sizeof(gost_hash_ctx));
+	gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet);
+	c->dctx.cipher_ctx= &(c->cctx);
+	return 1;
+	}
+
+int gost_digest_update(EVP_MD_CTX *ctx,const void *data,size_t count) 
+	{
+	return hash_block((gost_hash_ctx *)ctx->md_data,data,count);	
+	}
+
+int gost_digest_final(EVP_MD_CTX *ctx,unsigned char *md)
+	{
+	return finish_hash((gost_hash_ctx *)ctx->md_data,md);
+	
+	}
+
+int gost_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) 
+	{
+	struct ossl_gost_digest_ctx *md_ctx=to->md_data;
+	if (to->md_data && from->md_data) {
+		memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_digest_ctx));
+		md_ctx->dctx.cipher_ctx=&(md_ctx->cctx);
+	}
+	return 1;
+	}		
+
+int gost_digest_cleanup(EVP_MD_CTX *ctx) 
+	{
+	if (ctx->md_data)
+	memset(ctx->md_data,0,sizeof(struct ossl_gost_digest_ctx));
+	return 1;
+	}	
diff --git a/openssl/engines/ccgost/gost_params.c b/openssl/engines/ccgost/gost_params.c
new file mode 100644
index 0000000..40fc343
--- /dev/null
+++ b/openssl/engines/ccgost/gost_params.c
@@ -0,0 +1,198 @@
+/**********************************************************************
+ *                        params.c                                    *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *         This file is distributed under the same license as OpenSSL *
+ *                                                                    *
+ * Definitions of GOST R 34.10 parameter sets, defined in RFC 4357    *
+ *         OpenSSL 0.9.9 libraries required to compile and use        *
+ *                              this code                             *
+ **********************************************************************/ 
+#include "gost_params.h"
+#include <openssl/objects.h>
+/* Parameters of GOST 34.10 */
+
+R3410_params R3410_paramset[]={
+/* Paramset A */
+{NID_id_GostR3410_94_CryptoPro_A_ParamSet,
+"100997906755055304772081815535925224869"
+"8410825720534578748235158755771479905292727772441528526992987964833"
+"5669968284202797289605274717317548059048560713474685214192868091256"
+"1502802222185647539190902656116367847270145019066794290930185446216"
+"3997308722217328898303231940973554032134009725883228768509467406639"
+"62",
+"127021248288932417465907042777176443525"
+"7876535089165358128175072657050312609850984974231883334834011809259"
+"9999512098893413065920561499672425412104927434935707492031276956145"
+"1689224110579311248812610229678534638401693520013288995000362260684"
+"2227508135323070045173416336850045410625869714168836867788425378203"
+"83",
+"683631961449557007844441656118272528951"
+"02170888761442055095051287550314083023"},
+{NID_id_GostR3410_94_CryptoPro_B_ParamSet,
+"429418261486158041438734477379555023926"
+"7234596860714306679811299408947123142002706038521669956384871995765"
+"7284814898909770759462613437669456364882730370838934791080835932647"
+"9767786019153434744009610342313166725786869204821949328786333602033"
+"8479709268434224762105576023501613261478065276102850944540333865234"
+"1",
+"139454871199115825601409655107690713107"
+"0417070599280317977580014543757653577229840941243685222882398330391"
+"1468164807668823692122073732267216074074777170091113455043205380464"
+"7694904686120113087816240740184800477047157336662926249423571248823"
+"9685422217536601433914856808405203368594584948031873412885804895251"
+"63",
+"79885141663410976897627118935756323747307951916507639758300472692338873533959"
+},
+{NID_id_GostR3410_94_CryptoPro_C_ParamSet,
+"816552717970881016017893191415300348226"
+"2544051353358162468249467681876621283478212884286545844013955142622"
+"2087723485023722868022275009502224827866201744494021697716482008353"
+"6398202298024892620480898699335508064332313529725332208819456895108"
+"5155178100221003459370588291073071186553005962149936840737128710832"
+"3",
+"110624679233511963040518952417017040248"
+"5862954819831383774196396298584395948970608956170224210628525560327"
+"8638246716655439297654402921844747893079518669992827880792192992701"
+"1428546551433875806377110443534293554066712653034996277099320715774"
+"3542287621283671843703709141350171945045805050291770503634517804938"
+"01",
+"113468861199819350564868233378875198043"
+"267947776488510997961231672532899549103"
+},
+{NID_id_GostR3410_94_CryptoPro_D_ParamSet,
+"756976611021707301782128757801610628085"
+"5283803109571158829574281419208532589041660017017859858216341400371"
+"4687551412794400562878935266630754392677014598582103365983119173924"
+"4732511225464712252386803315902707727668715343476086350472025298282"
+"7271461690125050616858238384366331089777463541013033926723743254833"
+"7",
+"905457649621929965904290958774625315611"
+"3056083907389766971404812524422262512556054474620855996091570786713"
+"5849550236741915584185990627801066465809510095784713989819413820871"
+"5964648914493053407920737078890520482730623038837767710173664838239"
+"8574828787891286471201460474326612697849693665518073864436497893214"
+"9",
+"108988435796353506912374591498972192620"
+"190487557619582334771735390599299211593"
+},
+
+{NID_id_GostR3410_94_CryptoPro_XchA_ParamSet,
+"1335318132727206734338595199483190012179423759678474868994823595993"
+"6964252873471246159040332773182141032801252925387191478859899310331"
+"0567744136196364803064721377826656898686468463277710150809401182608"
+"7702016153249904683329312949209127762411378780302243557466062839716"
+"59376426832674269780880061631528163475887",
+"14201174159756348119636828602231808974327613839524373876287257344192"
+"74593935127189736311660784676003608489466235676257952827747192122419"
+"29071046134208380636394084512691828894000571524625445295769349356752"
+"72895683154177544176313938445719175509684710784659566254794231229333"
+"8483924514339614727760681880609734239",
+"91771529896554605945588149018382750217296858393520724172743325725474"
+"374979801"
+},
+{NID_id_GostR3410_94_CryptoPro_XchB_ParamSet,
+"8890864727828423151699995801875757891031463338652579140051973659"
+"3048131440685857067369829407947744496306656291505503608252399443"
+"7900272386749145996230867832228661977543992816745254823298629859"
+"8753575466286051738837854736167685769017780335804511440773337196"
+"2538423532919394477873664752824509986617878992443177",
+"1028946126624994859676552074360530315217970499989304888248413244"
+"8474923022758470167998871003604670704877377286176171227694098633"
+"1539089568784129110109512690503345393869871295783467257264868341"
+"7200196629860561193666752429682367397084815179752036423595736533"
+"68957392061769855284593965042530895046088067160269433",
+"9109671391802626916582318050603555673628769498182593088388796888"
+"5281641595199"
+},
+{NID_id_GostR3410_94_CryptoPro_XchC_ParamSet,
+"4430618464297584182473135030809859326863990650118941756995270074"
+"8609973181426950235239623239110557450826919295792878938752101867"
+"7047181623251027516953100431855964837602657827828194249605561893"
+"6965865325513137194483136247773653468410118796740709840825496997"
+"9375560722345106704721086025979309968763193072908334",
+"1246996366993477513607147265794064436203408861395055989217248455"
+"7299870737698999651480662364723992859320868822848751165438350943"
+"3276647222625940615560580450040947211826027729977563540237169063"
+"0448079715771649447778447000597419032457722226253269698374446528"
+"35352729304393746106576383349151001715930924115499549",
+"6787876137336591234380295020065682527118129468050147943114675429"
+"4748422492761"
+},
+
+
+{NID_undef,NULL, NULL, NULL}
+};
+	
+R3410_2001_params R3410_2001_paramset[]={
+	/* default_cc_sign01_param 1.2.643.2.9.1.8.1 */
+	{NID_id_GostR3410_2001_ParamSet_cc,
+	/* A */	
+	"C0000000000000000000000000000000000000000000000000000000000003c4",
+	/* B */
+	"2d06B4265ebc749ff7d0f1f1f88232e81632e9088fd44b7787d5e407e955080c",
+	/* P */
+	"C0000000000000000000000000000000000000000000000000000000000003C7",
+	/* Q */
+	"5fffffffffffffffffffffffffffffff606117a2f4bde428b7458a54b6e87b85",
+	/* X */
+	"2",
+	/* Y */
+	"a20e034bf8813ef5c18d01105e726a17eb248b264ae9706f440bedc8ccb6b22c"
+	},
+	/* 1.2.643.2.2.35.0 */
+	{NID_id_GostR3410_2001_TestParamSet,
+	"7",
+	"5FBFF498AA938CE739B8E022FBAFEF40563F6E6A3472FC2A514C0CE9DAE23B7E",
+	"8000000000000000000000000000000000000000000000000000000000000431",
+	"8000000000000000000000000000000150FE8A1892976154C59CFC193ACCF5B3",
+	"2",
+	"08E2A8A0E65147D4BD6316030E16D19C85C97F0A9CA267122B96ABBCEA7E8FC8"
+	},
+	/*1.2.643.2.2.35.1*/
+	{NID_id_GostR3410_2001_CryptoPro_A_ParamSet,
+	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94",
+	"a6",
+	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97",
+	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893",
+	"1",
+	"8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"
+	},
+	/*1.2.643.2.2.35.2*/
+	{NID_id_GostR3410_2001_CryptoPro_B_ParamSet,	
+	"8000000000000000000000000000000000000000000000000000000000000C96",
+	"3E1AF419A269A5F866A7D3C25C3DF80AE979259373FF2B182F49D4CE7E1BBC8B",
+	"8000000000000000000000000000000000000000000000000000000000000C99",
+	"800000000000000000000000000000015F700CFFF1A624E5E497161BCC8A198F",
+	"1",	
+	"3FA8124359F96680B83D1C3EB2C070E5C545C9858D03ECFB744BF8D717717EFC"
+	},
+	/*1.2.643.2.2.35.3*/
+	{NID_id_GostR3410_2001_CryptoPro_C_ParamSet,
+	"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598",
+	"805a",
+	"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B",
+	"9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9",
+	"0",
+	"41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67"
+	},
+	/*1.2.643.2.2.36.0*/
+	{NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet,
+	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94",
+	"a6",
+	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97",
+	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893",
+	"1",
+	"8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"
+	},
+	/*1.2.643.2.2.36.1*/
+	{NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet,
+	"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598",
+	"805a",
+	"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B",
+	"9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9",
+	"0",
+	"41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67"
+	},
+	{ 0,NULL,NULL,NULL,NULL,NULL,NULL
+	}
+};
diff --git a/openssl/engines/ccgost/gost_params.h b/openssl/engines/ccgost/gost_params.h
new file mode 100644
index 0000000..4c3f556
--- /dev/null
+++ b/openssl/engines/ccgost/gost_params.h
@@ -0,0 +1,34 @@
+/**********************************************************************
+ *                        gost_params.h                               *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *       This file is distributed under the same license as OpenSSL   *
+ *                                                                    *
+ *       Declaration of structures used to represent  GOST R 34.10    *
+ * 	               parameter sets, defined in RFC 4357                *
+ *         OpenSSL 0.9.9 libraries required to compile and use        *
+ *                              this code                             *
+ **********************************************************************/ 
+#ifndef GOST_PARAMSET_H
+#define GOST_PARAMSET_H
+typedef struct R3410 {
+		int nid;
+		char *a;
+		char *p;
+		char *q;
+} R3410_params;
+
+extern R3410_params R3410_paramset[];
+
+typedef struct R3410_2001 {
+		int nid;
+		char *a;
+		char *b;
+		char *p;
+		char *q;
+		char *x;
+		char *y;
+} R3410_2001_params;
+
+extern R3410_2001_params R3410_2001_paramset[];
+
+#endif
diff --git a/openssl/engines/ccgost/gost_pmeth.c b/openssl/engines/ccgost/gost_pmeth.c
new file mode 100644
index 0000000..caaea99
--- /dev/null
+++ b/openssl/engines/ccgost/gost_pmeth.c
@@ -0,0 +1,621 @@
+/**********************************************************************
+ *                          gost_pmeth.c                              *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *         This file is distributed under the same license as OpenSSL *
+ *                                                                    *
+ *   Implementation of RFC 4357 (GOST R 34.10) Publick key method     *
+ *       for OpenSSL                                                  *
+ *          Requires OpenSSL 0.9.9 for compilation                    *
+ **********************************************************************/
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/ec.h>
+#include <openssl/x509v3.h> /*For string_to_hex */
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "gost_params.h"
+#include "gost_lcl.h"
+#include "e_gost_err.h"
+/*-------init, cleanup, copy - uniform for all algs  ---------------*/
+/* Allocates new gost_pmeth_data structure and assigns it as data */
+static int pkey_gost_init(EVP_PKEY_CTX *ctx)
+	{
+	struct gost_pmeth_data *data;
+	EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
+	data = OPENSSL_malloc(sizeof(struct gost_pmeth_data));
+	if (!data) return 0;
+	memset(data,0,sizeof(struct gost_pmeth_data));
+	if (pkey && EVP_PKEY_get0(pkey)) 
+		{
+		switch (EVP_PKEY_base_id(pkey)) {
+		case NID_id_GostR3410_94:
+		  data->sign_param_nid = gost94_nid_by_params(EVP_PKEY_get0(pkey));
+		  break;
+		case NID_id_GostR3410_2001:
+		   data->sign_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey)));
+		break;
+		default:
+			return 0;
+		}	  
+		}
+	EVP_PKEY_CTX_set_data(ctx,data);
+	return 1;
+	}
+
+/* Copies contents of gost_pmeth_data structure */
+static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+	{
+	struct gost_pmeth_data *dst_data,*src_data;
+	if (!pkey_gost_init(dst))
+		{
+		return 0;
+		}
+	src_data = EVP_PKEY_CTX_get_data(src);
+	dst_data = EVP_PKEY_CTX_get_data(dst);
+	*dst_data = *src_data;
+	if (src_data -> shared_ukm) {
+		dst_data->shared_ukm=NULL;
+	}	
+	return 1;
+	}
+
+/* Frees up gost_pmeth_data structure */
+static void pkey_gost_cleanup (EVP_PKEY_CTX *ctx)
+	{
+	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+	if (data->shared_ukm) OPENSSL_free(data->shared_ukm);
+	OPENSSL_free(data);
+	}	
+
+/* --------------------- control functions  ------------------------------*/
+static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+	{
+	struct gost_pmeth_data *pctx = (struct gost_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);
+	switch (type)
+		{
+		case EVP_PKEY_CTRL_MD:
+		{
+		if (EVP_MD_type((const EVP_MD *)p2) != NID_id_GostR3411_94)
+			{
+			GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE);
+			return 0;
+			}
+		pctx->md = (EVP_MD *)p2;
+		return 1;
+		}
+		break;
+
+		case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
+		case EVP_PKEY_CTRL_PKCS7_DECRYPT:
+		case EVP_PKEY_CTRL_PKCS7_SIGN:
+			return 1;
+
+		case EVP_PKEY_CTRL_GOST_PARAMSET:
+			pctx->sign_param_nid = (int)p1;
+			return 1;
+		case EVP_PKEY_CTRL_SET_IV:
+			pctx->shared_ukm=OPENSSL_malloc((int)p1);
+			memcpy(pctx->shared_ukm,p2,(int) p1);
+			return 1;
+		case EVP_PKEY_CTRL_PEER_KEY:
+			if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */
+				return 1;
+			if (p1 == 2)		/* TLS: peer key used? */
+				return pctx->peer_key_used;
+			if (p1 == 3)		/* TLS: peer key used! */
+				return (pctx->peer_key_used = 1);
+			return -2;
+		}
+	return -2;
+	}
+
+
+static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx,
+	const char *type, const char *value)
+	{
+	int param_nid=0;
+	if(!strcmp(type, param_ctrl_string))
+		{
+		if (!value)
+			{
+			return 0;
+			}
+		if (strlen(value) == 1)
+			{
+			switch(toupper(value[0]))
+				{
+				case 'A':
+					param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet;
+					break;
+				case 'B':
+					param_nid = NID_id_GostR3410_94_CryptoPro_B_ParamSet;
+					break;
+				case 'C':
+					param_nid = NID_id_GostR3410_94_CryptoPro_C_ParamSet;
+					break;
+				case 'D':
+					param_nid = NID_id_GostR3410_94_CryptoPro_D_ParamSet;
+					break;
+				default:
+					return 0;
+					break;
+				}
+			}
+		else if ((strlen(value) == 2) && (toupper(value[0]) == 'X'))
+			{
+			switch (toupper(value[1]))
+				{
+				case 'A':
+					param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet;
+					break;
+				case 'B':
+					param_nid = NID_id_GostR3410_94_CryptoPro_XchB_ParamSet;
+					break;
+				case 'C':
+					param_nid = NID_id_GostR3410_94_CryptoPro_XchC_ParamSet;
+					break;
+				default:
+					return 0;
+					break;
+				}
+			}
+		else
+			{
+			R3410_params *p = R3410_paramset;
+			param_nid = OBJ_txt2nid(value);
+			if (param_nid == NID_undef)
+				{
+				return 0;
+				}
+			for (;p->nid != NID_undef;p++)
+				{
+				if (p->nid == param_nid) break;
+				}
+			if (p->nid == NID_undef)
+				{
+				GOSTerr(GOST_F_PKEY_GOST_CTRL94_STR,
+					GOST_R_INVALID_PARAMSET);
+				return 0;
+				}
+			}
+
+		return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
+			param_nid, NULL);
+		}
+	return -2;
+	}
+
+static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx,
+	const char *type, const char *value)
+	{
+	int param_nid=0;
+	if(!strcmp(type, param_ctrl_string))
+		{
+		if (!value)
+			{
+			return 0;
+			}
+		if (strlen(value) == 1)
+			{
+			switch(toupper(value[0]))
+				{
+				case 'A':
+					param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet;
+					break;	
+				case 'B':
+					param_nid = NID_id_GostR3410_2001_CryptoPro_B_ParamSet;
+					break;
+				case 'C':
+					param_nid = NID_id_GostR3410_2001_CryptoPro_C_ParamSet;
+					break;
+				case '0':
+					param_nid = NID_id_GostR3410_2001_TestParamSet;
+					break;
+				default:
+					return 0;
+					break;
+				}
+			}
+		else if ((strlen(value) == 2) && (toupper(value[0]) == 'X'))
+			{
+			switch (toupper(value[1]))
+				{
+				case 'A':
+					param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet;
+					break;
+				case 'B':
+					param_nid = NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet;
+					break;
+				default:
+					return 0;
+					break;
+				}
+			}
+		else
+			{
+			R3410_2001_params *p = R3410_2001_paramset;
+			param_nid = OBJ_txt2nid(value);
+			if (param_nid == NID_undef)
+				{
+				return 0;
+				}
+			for (;p->nid != NID_undef;p++)
+				{
+				if (p->nid == param_nid) break;
+				}
+			if (p->nid == NID_undef)
+				{
+				GOSTerr(GOST_F_PKEY_GOST_CTRL01_STR,
+					GOST_R_INVALID_PARAMSET);
+				return 0;
+				}
+			}
+
+		return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
+			param_nid, NULL);
+		}
+	return -2;
+	}
+
+/* --------------------- key generation  --------------------------------*/
+
+static int pkey_gost_paramgen_init(EVP_PKEY_CTX *ctx) {
+	return 1;
+}	
+static int pkey_gost94_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 
+	{
+	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+	DSA *dsa=NULL;
+	if (data->sign_param_nid == NID_undef)
+		{
+			GOSTerr(GOST_F_PKEY_GOST94_PARAMGEN,
+				GOST_R_NO_PARAMETERS_SET);
+			return 0;
+		}
+	dsa = DSA_new();
+	if (!fill_GOST94_params(dsa,data->sign_param_nid))
+		{
+		DSA_free(dsa);
+		return 0;
+		}
+	EVP_PKEY_assign(pkey,NID_id_GostR3410_94,dsa);
+	return 1;
+	}
+static int pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+	EC_KEY *ec=NULL;
+
+	if (data->sign_param_nid == NID_undef)
+		{
+			GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN,
+				GOST_R_NO_PARAMETERS_SET);
+			return 0;
+		}
+	if (!ec) 	
+		ec = EC_KEY_new();
+	if (!fill_GOST2001_params(ec,data->sign_param_nid))
+		{
+		EC_KEY_free(ec);
+		return 0;
+		}
+	EVP_PKEY_assign(pkey,NID_id_GostR3410_2001,ec);
+	return 1;
+	}
+
+/* Generates Gost_R3410_94_cp key */
+static int pkey_gost94cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+	DSA *dsa;
+	if (!pkey_gost94_paramgen(ctx,pkey)) return 0;
+	dsa = EVP_PKEY_get0(pkey);
+	gost_sign_keygen(dsa);
+	return 1;
+	}
+
+/* Generates GOST_R3410 2001 key and assigns it using specified type */
+static int pkey_gost01cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+	EC_KEY *ec;
+    if (!pkey_gost01_paramgen(ctx,pkey)) return 0;
+	ec = EVP_PKEY_get0(pkey);
+	gost2001_keygen(ec);
+	return 1;
+	}
+
+
+
+/* ----------- sign callbacks --------------------------------------*/
+
+static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+	const unsigned char *tbs, size_t tbs_len)
+	{
+	DSA_SIG *unpacked_sig=NULL;
+	EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
+	if (!siglen) return 0;
+	if (!sig)
+		{
+		*siglen= 64; /* better to check size of pkey->pkey.dsa-q */
+		return 1;
+		}	
+	unpacked_sig = gost_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
+	if (!unpacked_sig)
+		{
+		return 0;
+		}
+	return pack_sign_cp(unpacked_sig,32,sig,siglen);
+	}
+
+static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+	const unsigned char *tbs, size_t tbs_len)
+	{
+	DSA_SIG *unpacked_sig=NULL;
+	EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
+	if (!siglen) return 0;
+	if (!sig)
+		{
+		*siglen= 64; /* better to check size of curve order*/
+		return 1;
+		}	
+	unpacked_sig = gost2001_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
+	if (!unpacked_sig)
+		{
+		return 0;
+		}
+	return pack_sign_cp(unpacked_sig,32,sig,siglen);
+	}
+
+/* ------------------- verify callbacks ---------------------------*/
+
+static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
+	size_t siglen, const unsigned char *tbs, size_t tbs_len)
+	{
+	int ok = 0;
+	EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
+	DSA_SIG *s=unpack_cp_signature(sig,siglen);
+	if (!s) return 0;
+	if (pub_key) ok = gost_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
+	DSA_SIG_free(s);
+	return ok;
+	}
+
+
+static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
+	size_t siglen, const unsigned char *tbs, size_t tbs_len)
+	{
+	int ok = 0;
+	EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
+	DSA_SIG *s=unpack_cp_signature(sig,siglen);
+	if (!s) return 0;
+#ifdef DEBUG_SIGN	
+	fprintf(stderr,"R=");
+	BN_print_fp(stderr,s->r);
+	fprintf(stderr,"\nS=");
+	BN_print_fp(stderr,s->s);
+	fprintf(stderr,"\n");
+#endif	
+	if (pub_key) ok = gost2001_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
+	DSA_SIG_free(s);
+	return ok;
+	}
+
+/* ------------- encrypt init -------------------------------------*/
+/* Generates ephermeral key */
+static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx)
+	{
+	return 1;
+	}
+/* --------------- Derive init ------------------------------------*/
+static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx)
+{
+	return 1;
+}
+/* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/
+static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx)
+	{
+	struct gost_mac_pmeth_data *data;
+	data = OPENSSL_malloc(sizeof(struct gost_mac_pmeth_data));
+	if (!data) return 0;
+	memset(data,0,sizeof(struct gost_mac_pmeth_data));
+	EVP_PKEY_CTX_set_data(ctx,data);
+	return 1;
+	}	
+static void pkey_gost_mac_cleanup (EVP_PKEY_CTX *ctx)
+	{
+	struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+	OPENSSL_free(data);
+	}	
+static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+	{
+	struct gost_mac_pmeth_data *dst_data,*src_data;
+	if (!pkey_gost_mac_init(dst))
+		{
+		return 0;
+		}
+	src_data = EVP_PKEY_CTX_get_data(src);
+	dst_data = EVP_PKEY_CTX_get_data(dst);
+	*dst_data = *src_data;
+	return 1;
+	}
+	
+static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+	{
+	struct gost_mac_pmeth_data *data =
+(struct gost_mac_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);
+
+	switch (type)
+		{
+		case EVP_PKEY_CTRL_MD:
+		{
+		if (EVP_MD_type((const EVP_MD *)p2) != NID_id_Gost28147_89_MAC)
+			{
+			GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_DIGEST_TYPE);
+			return 0;
+			}
+		data->md = (EVP_MD *)p2;
+		return 1;
+		}
+		break;
+
+		case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
+		case EVP_PKEY_CTRL_PKCS7_DECRYPT:
+		case EVP_PKEY_CTRL_PKCS7_SIGN:
+			return 1;
+		case EVP_PKEY_CTRL_SET_MAC_KEY:
+			if (p1 != 32) 
+				{
+				GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
+					GOST_R_INVALID_MAC_KEY_LENGTH);
+				return 0;
+				}
+
+			memcpy(data->key,p2,32);
+			data->key_set = 1;
+			return 1;
+		case EVP_PKEY_CTRL_DIGESTINIT:
+			{ 
+			EVP_MD_CTX *mctx = p2;
+			void *key;
+			if (!data->key_set)
+				{ 
+				EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
+				if (!pkey) 
+					{
+					GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET);
+					return 0;
+					}
+				key = EVP_PKEY_get0(pkey);
+				if (!key) 
+					{
+					GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET);
+					return 0;
+					}
+				} else {
+				key = &(data->key);
+				}
+			return mctx->digest->md_ctrl(mctx,EVP_MD_CTRL_SET_KEY,32,key);
+			}  
+		}	
+	return -2;
+	}
+static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
+	const char *type, const char *value)
+	{
+	if (!strcmp(type, key_ctrl_string)) 
+		{
+		if (strlen(value)!=32) 
+			{
+			GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
+				GOST_R_INVALID_MAC_KEY_LENGTH);
+			return 0;	
+			}
+		return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
+			32,(char *)value);
+		}
+	if (!strcmp(type, hexkey_ctrl_string)) 
+		{
+			long keylen; int ret;
+			unsigned char *keybuf=string_to_hex(value,&keylen);
+			if (keylen != 32) 
+				{
+				GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
+					GOST_R_INVALID_MAC_KEY_LENGTH);
+				return 0;	
+				}
+			ret= pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
+				32,keybuf);
+			OPENSSL_free(keybuf);
+			return ret;
+	
+		}
+	return -2;
+	}	
+
+static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+		struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+		unsigned char *keydata;
+		if (!data->key_set) 
+		{
+			GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN,GOST_R_MAC_KEY_NOT_SET);
+			return 0;
+		}
+		keydata = OPENSSL_malloc(32);
+		memcpy(keydata,data->key,32);
+		EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata);
+		return 1;
+	}
+
+static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
+	{
+	return 1;
+}
+
+static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, EVP_MD_CTX *mctx)
+	{
+		unsigned int tmpsiglen=*siglen; /* for platforms where sizeof(int)!=sizeof(size_t)*/
+		int ret;
+		if (!sig) 
+			{
+			*siglen = 4;
+			return 1;
+			}
+		ret=EVP_DigestFinal_ex(mctx,sig,&tmpsiglen);
+		*siglen = tmpsiglen;
+		return ret;
+	}
+/* ----------------------------------------------------------------*/
+int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags)
+	{
+	*pmeth = EVP_PKEY_meth_new(id, flags);
+	if (!*pmeth) return 0;
+
+	switch (id)
+		{
+		case NID_id_GostR3410_94:
+			EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl94_str);
+			EVP_PKEY_meth_set_keygen(*pmeth,NULL,pkey_gost94cp_keygen);
+			EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost94_cp_sign);
+			EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost94_cp_verify);
+			EVP_PKEY_meth_set_encrypt(*pmeth,
+				pkey_gost_encrypt_init, pkey_GOST94cp_encrypt);
+			EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cp_decrypt);
+			EVP_PKEY_meth_set_derive(*pmeth,
+				pkey_gost_derive_init, pkey_gost94_derive);
+			EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,pkey_gost94_paramgen);	
+			break;
+		case NID_id_GostR3410_2001:
+			EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl01_str);
+			EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost01_cp_sign);
+			EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost01_cp_verify);
+
+			EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost01cp_keygen);
+
+			EVP_PKEY_meth_set_encrypt(*pmeth,
+				pkey_gost_encrypt_init, pkey_GOST01cp_encrypt);
+			EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cp_decrypt);
+			EVP_PKEY_meth_set_derive(*pmeth,
+				pkey_gost_derive_init, pkey_gost2001_derive);
+			EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,pkey_gost01_paramgen);	
+			break;
+		case NID_id_Gost28147_89_MAC:
+			EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_mac_ctrl, pkey_gost_mac_ctrl_str);
+			EVP_PKEY_meth_set_signctx(*pmeth,pkey_gost_mac_signctx_init, pkey_gost_mac_signctx);
+			EVP_PKEY_meth_set_keygen(*pmeth,NULL, pkey_gost_mac_keygen);
+			EVP_PKEY_meth_set_init(*pmeth,pkey_gost_mac_init);
+			EVP_PKEY_meth_set_cleanup(*pmeth,pkey_gost_mac_cleanup);
+			EVP_PKEY_meth_set_copy(*pmeth,pkey_gost_mac_copy);
+			return 1;
+		default: /*Unsupported method*/
+			return 0;
+		}
+	EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init);
+	EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_cleanup);
+
+	EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_copy);
+	/*FIXME derive etc...*/
+	
+	return 1;
+	}
+
diff --git a/openssl/engines/ccgost/gost_sign.c b/openssl/engines/ccgost/gost_sign.c
new file mode 100644
index 0000000..4095654
--- /dev/null
+++ b/openssl/engines/ccgost/gost_sign.c
@@ -0,0 +1,321 @@
+/**********************************************************************
+ *                          gost_sign.c                               *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *         This file is distributed under the same license as OpenSSL *
+ *                                                                    *
+ *       Implementation of GOST R 34.10-94 signature algorithm        *
+ *       for OpenSSL                                                  *
+ *          Requires OpenSSL 0.9.9 for compilation                    *
+ **********************************************************************/
+#include <string.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/evp.h>
+
+#include "gost_params.h"
+#include "gost_lcl.h"
+#include "e_gost_err.h"
+
+#ifdef DEBUG_SIGN
+void dump_signature(const char *message,const unsigned char *buffer,size_t len)
+	{
+	size_t i;
+	fprintf(stderr,"signature %s Length=%d",message,len);
+	for (i=0; i<len; i++)
+		{
+		if (i% 16 ==0) fputc('\n',stderr);
+		fprintf (stderr," %02x",buffer[i]);
+		}
+	fprintf(stderr,"\nEnd of signature\n");
+	}
+
+void dump_dsa_sig(const char *message, DSA_SIG *sig)
+	{
+	fprintf(stderr,"%s\nR=",message);
+	BN_print_fp(stderr,sig->r);
+	fprintf(stderr,"\nS=");
+	BN_print_fp(stderr,sig->s);
+	fprintf(stderr,"\n");
+	}
+
+#else
+
+#define dump_signature(a,b,c)
+#define dump_dsa_sig(a,b)
+#endif
+
+/*
+ * Computes signature and returns it as DSA_SIG structure
+ */
+DSA_SIG *gost_do_sign(const unsigned char *dgst,int dlen, DSA *dsa)
+	{
+	BIGNUM *k=NULL,*tmp=NULL,*tmp2=NULL;
+	DSA_SIG *newsig = DSA_SIG_new();
+	BIGNUM *md = hashsum2bn(dgst);
+	/* check if H(M) mod q is zero */
+	BN_CTX *ctx=BN_CTX_new();
+	BN_CTX_start(ctx);
+	if (!newsig)
+		{
+		GOSTerr(GOST_F_GOST_DO_SIGN,GOST_R_NO_MEMORY);
+		goto err;
+		}	
+	tmp=BN_CTX_get(ctx);
+	k = BN_CTX_get(ctx);
+	tmp2 = BN_CTX_get(ctx);
+	BN_mod(tmp,md,dsa->q,ctx);
+	if (BN_is_zero(tmp))
+		{
+		BN_one(md);
+		}	
+	do
+		{
+		do
+			{
+			/*Generate random number k less than q*/
+			BN_rand_range(k,dsa->q);
+			/* generate r = (a^x mod p) mod q */
+			BN_mod_exp(tmp,dsa->g, k, dsa->p,ctx);
+			if (!(newsig->r)) newsig->r=BN_new();
+			BN_mod(newsig->r,tmp,dsa->q,ctx);
+			}
+		while (BN_is_zero(newsig->r));
+		/* generate s = (xr + k(Hm)) mod q */
+		BN_mod_mul(tmp,dsa->priv_key,newsig->r,dsa->q,ctx);
+		BN_mod_mul(tmp2,k,md,dsa->q,ctx);
+		if (!newsig->s) newsig->s=BN_new();
+		BN_mod_add(newsig->s,tmp,tmp2,dsa->q,ctx);
+		}
+	while (BN_is_zero(newsig->s));		
+	err:
+	BN_free(md);
+	BN_CTX_end(ctx);
+	BN_CTX_free(ctx);
+	return newsig;
+	}	
+
+
+/*
+ * Packs signature according to Cryptocom rules
+ * and frees up DSA_SIG structure
+ */
+/*
+int pack_sign_cc(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen)
+	{
+	*siglen = 2*order;
+	memset(sig,0,*siglen);
+	store_bignum(s->r, sig,order);
+	store_bignum(s->s, sig + order,order);
+	dump_signature("serialized",sig,*siglen);
+	DSA_SIG_free(s);
+	return 1;
+	}
+*/
+/*
+ * Packs signature according to Cryptopro rules
+ * and frees up DSA_SIG structure
+ */
+int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen)
+	{
+	*siglen = 2*order;
+	memset(sig,0,*siglen);
+	store_bignum(s->s, sig, order);
+	store_bignum(s->r, sig+order,order);
+	dump_signature("serialized",sig,*siglen);
+	DSA_SIG_free(s);
+	return 1;
+	}
+
+/*
+ * Verifies signature passed as DSA_SIG structure
+ *
+ */
+
+int gost_do_verify(const unsigned char *dgst, int dgst_len,
+	DSA_SIG *sig, DSA *dsa)
+	{
+	BIGNUM *md, *tmp=NULL;
+	BIGNUM *q2=NULL;
+	BIGNUM *u=NULL,*v=NULL,*z1=NULL,*z2=NULL;
+	BIGNUM *tmp2=NULL,*tmp3=NULL;
+	int ok;
+	BN_CTX *ctx = BN_CTX_new();
+
+	BN_CTX_start(ctx);
+	if (BN_cmp(sig->s,dsa->q)>=1||
+		BN_cmp(sig->r,dsa->q)>=1)
+		{
+		GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
+		return 0;
+		}
+	md=hashsum2bn(dgst);
+	
+	tmp=BN_CTX_get(ctx);
+	v=BN_CTX_get(ctx);
+	q2=BN_CTX_get(ctx);
+	z1=BN_CTX_get(ctx);
+	z2=BN_CTX_get(ctx);
+	tmp2=BN_CTX_get(ctx);
+	tmp3=BN_CTX_get(ctx);
+	u = BN_CTX_get(ctx);
+	
+	BN_mod(tmp,md,dsa->q,ctx);
+	if (BN_is_zero(tmp))
+		{
+		BN_one(md);
+		}
+	BN_copy(q2,dsa->q);
+	BN_sub_word(q2,2);
+	BN_mod_exp(v,md,q2,dsa->q,ctx);
+	BN_mod_mul(z1,sig->s,v,dsa->q,ctx);
+	BN_sub(tmp,dsa->q,sig->r);
+	BN_mod_mul(z2,tmp,v,dsa->p,ctx);
+	BN_mod_exp(tmp,dsa->g,z1,dsa->p,ctx);
+	BN_mod_exp(tmp2,dsa->pub_key,z2,dsa->p,ctx);
+	BN_mod_mul(tmp3,tmp,tmp2,dsa->p,ctx);
+	BN_mod(u,tmp3,dsa->q,ctx);
+	ok= BN_cmp(u,sig->r);
+	
+	BN_free(md);
+	BN_CTX_end(ctx);
+	BN_CTX_free(ctx);
+	if (ok!=0)
+		{
+		GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH);
+		}	
+	return (ok==0);
+	}
+
+/*
+ * Computes public keys for GOST R 34.10-94 algorithm
+ *
+ */
+int gost94_compute_public(DSA *dsa)
+	{
+	/* Now fill algorithm parameters with correct values */
+	BN_CTX *ctx = BN_CTX_new();
+	if (!dsa->g)
+		{
+		GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITALIZED);
+		return 0;
+		}	
+	/* Compute public key  y = a^x mod p */
+	dsa->pub_key=BN_new();
+	BN_mod_exp(dsa->pub_key, dsa->g,dsa->priv_key,dsa->p,ctx);
+	BN_CTX_free(ctx);
+	return 1;
+	}
+
+/*
+ * Fill GOST 94 params, searching them in R3410_paramset array
+ * by nid of paramset
+ *
+ */
+int fill_GOST94_params(DSA *dsa,int nid)
+	{
+	R3410_params *params=R3410_paramset;
+	while (params->nid!=NID_undef && params->nid !=nid) params++;
+	if (params->nid == NID_undef)
+		{
+		GOSTerr(GOST_F_FILL_GOST94_PARAMS,GOST_R_UNSUPPORTED_PARAMETER_SET);
+		return 0;
+		}	
+#define dump_signature(a,b,c)
+	if (dsa->p) { BN_free(dsa->p); }
+	dsa->p=NULL;
+	BN_dec2bn(&(dsa->p),params->p);
+	if (dsa->q) { BN_free(dsa->q); }
+	dsa->q=NULL;
+	BN_dec2bn(&(dsa->q),params->q);
+	if (dsa->g) { BN_free(dsa->g); }
+	dsa->g=NULL;
+	BN_dec2bn(&(dsa->g),params->a);
+	return 1;
+	}	
+
+/*
+ *  Generate GOST R 34.10-94 keypair
+ *
+ *
+ */
+int gost_sign_keygen(DSA *dsa)
+	{
+	dsa->priv_key = BN_new();
+	BN_rand_range(dsa->priv_key,dsa->q);
+	return gost94_compute_public( dsa);
+	}
+
+/* Unpack signature according to cryptocom rules  */
+/*
+DSA_SIG *unpack_cc_signature(const unsigned char *sig,size_t siglen)
+	{
+	DSA_SIG *s;
+	s = DSA_SIG_new();
+	if (s == NULL)
+		{
+		GOSTerr(GOST_F_UNPACK_CC_SIGNATURE,GOST_R_NO_MEMORY);
+		return(NULL);
+		}
+	s->r = getbnfrombuf(sig, siglen/2);
+	s->s = getbnfrombuf(sig + siglen/2, siglen/2);
+	return s;
+	}
+*/
+/* Unpack signature according to cryptopro rules  */
+DSA_SIG *unpack_cp_signature(const unsigned char *sig,size_t siglen)
+	{
+	DSA_SIG *s;
+
+	s = DSA_SIG_new();
+	if (s == NULL)
+		{
+		GOSTerr(GOST_F_UNPACK_CP_SIGNATURE,GOST_R_NO_MEMORY);
+		return NULL;
+		}
+	s->s = getbnfrombuf(sig , siglen/2);
+	s->r = getbnfrombuf(sig + siglen/2, siglen/2);
+	return s;
+	}
+
+/* Convert little-endian byte array into bignum */
+BIGNUM *hashsum2bn(const unsigned char *dgst)
+	{
+	unsigned char buf[32];
+	int i;
+	for (i=0;i<32;i++)
+		{
+		buf[31-i]=dgst[i];
+		}
+	return getbnfrombuf(buf,32);
+	}
+
+/* Convert byte buffer to bignum, skipping leading zeros*/
+BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len)
+	{
+	while (*buf==0&&len>0)
+		{
+		buf++; len--;
+		}
+	if (len)
+		{
+		return BN_bin2bn(buf,len,NULL);
+		}
+	else
+		{
+		BIGNUM *b=BN_new();
+		BN_zero(b);
+		return b;
+		}
+	}
+
+/* Pack bignum into byte buffer of given size, filling all leading bytes
+ * by zeros */
+int store_bignum(BIGNUM *bn, unsigned char *buf,int len)
+	{
+	int bytes = BN_num_bytes(bn);
+	if (bytes>len) return 0;
+	memset(buf,0,len);
+	BN_bn2bin(bn,buf+len-bytes);
+	return 1;
+	}	
diff --git a/openssl/engines/ccgost/gosthash.c b/openssl/engines/ccgost/gosthash.c
new file mode 100644
index 0000000..a5c0662
--- /dev/null
+++ b/openssl/engines/ccgost/gosthash.c
@@ -0,0 +1,255 @@
+/**********************************************************************
+ *                          gosthash.c                                *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *         This file is distributed under the same license as OpenSSL *
+ *                                                                    *
+ *    Implementation of GOST R 34.11-94 hash function                 *
+ *       uses on gost89.c and gost89.h Doesn't need OpenSSL           *
+ **********************************************************************/
+#include <string.h>
+
+#include "gost89.h"
+#include "gosthash.h"
+
+
+/* Use OPENSSL_malloc for memory allocation if compiled with 
+ * -DOPENSSL_BUILD, and libc malloc otherwise
+ */
+#ifndef MYALLOC
+# ifdef OPENSSL_BUILD
+#  include <openssl/crypto.h>
+#  define MYALLOC(size) OPENSSL_malloc(size)
+#  define MYFREE(ptr) OPENSSL_free(ptr)
+# else
+#  define MYALLOC(size) malloc(size)
+#  define MYFREE(ptr) free(ptr)
+# endif
+#endif
+/* Following functions are various bit meshing routines used in
+ * GOST R 34.11-94 algorithms */
+static void swap_bytes (byte *w, byte *k) 
+	{
+	int i,j;
+	for (i=0;i<4;i++)	
+		for (j=0;j<8;j++) 
+			k[i+4*j]=w[8*i+j];
+
+	}
+
+/* was A_A */
+static void circle_xor8 (const byte *w, byte *k) 
+	{
+	byte buf[8];
+	int i;
+	memcpy(buf,w,8);
+	memcpy(k,w+8,24);
+	for(i=0;i<8;i++) 
+		k[i+24]=buf[i]^k[i];
+	}
+
+/* was R_R */
+static void transform_3 (byte *data) 
+	{
+	unsigned short int acc;
+	acc=(data[0]^data[2]^data[4]^data[6]^data[24]^data[30])|
+		((data[1]^data[3]^data[5]^data[7]^data[25]^data[31])<<8);
+	memmove(data,data+2,30);
+	data[30]=acc&0xff;
+	data[31]=acc>>8;
+	}
+
+/* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/
+static int add_blocks(int n,byte *left, const byte *right) 
+	{
+	int i;
+	int carry=0;
+	int sum;
+	for (i=0;i<n;i++) 
+		{
+	   	sum=(int)left[i]+(int)right[i]+carry;
+		left[i]=sum & 0xff;
+		carry=sum>>8;
+		}
+	return carry;
+	} 
+
+/* Xor two sequences of bytes */
+static void xor_blocks (byte *result,const byte *a,const byte *b,size_t len)
+	{
+	size_t i;
+	for (i=0;i<len;i++) result[i]=a[i]^b[i];
+	}	
+
+/* 
+ * 	Calculate H(i+1) = Hash(Hi,Mi) 
+ * 	Where H and M are 32 bytes long
+ */
+static int hash_step(gost_ctx *c,byte *H,const byte *M) 
+	{
+	byte U[32],W[32],V[32],S[32],Key[32];
+	int i;
+	/* Compute first key */
+	xor_blocks(W,H,M,32);
+	swap_bytes(W,Key);
+	/* Encrypt first 8 bytes of H with first key*/
+	gost_enc_with_key(c,Key,H,S);
+	/* Compute second key*/
+	circle_xor8(H,U);
+	circle_xor8(M,V);
+	circle_xor8(V,V);
+	xor_blocks(W,U,V,32);
+	swap_bytes(W,Key);
+	/* encrypt second 8 bytes of H with second key*/
+	gost_enc_with_key(c,Key,H+8,S+8);
+	/* compute third key */
+	circle_xor8(U,U);
+	U[31]=~U[31]; U[29]=~U[29]; U[28]=~U[28]; U[24]=~U[24];
+	U[23]=~U[23]; U[20]=~U[20]; U[18]=~U[18]; U[17]=~U[17];
+	U[14]=~U[14]; U[12]=~U[12]; U[10]=~U[10]; U[ 8]=~U[ 8];
+	U[ 7]=~U[ 7]; U[ 5]=~U[ 5]; U[ 3]=~U[ 3]; U[ 1]=~U[ 1];
+	circle_xor8(V,V);
+	circle_xor8(V,V);
+	xor_blocks(W,U,V,32);
+	swap_bytes(W,Key);
+	/* encrypt third 8 bytes of H with third key*/
+	gost_enc_with_key(c,Key,H+16,S+16);
+	/* Compute fourth key */
+	circle_xor8(U,U);
+	circle_xor8(V,V);
+	circle_xor8(V,V);
+	xor_blocks(W,U,V,32);
+	swap_bytes(W,Key);
+	/* Encrypt last 8 bytes with fourth key */
+	gost_enc_with_key(c,Key,H+24,S+24);
+	for (i=0;i<12;i++) 
+		transform_3(S);
+	xor_blocks(S,S,M,32);
+	transform_3(S);
+	xor_blocks(S,S,H,32);
+	for (i=0;i<61;i++) 
+		transform_3(S);
+	memcpy(H,S,32);
+	return 1;
+	}
+
+/* Initialize gost_hash ctx - cleans up temporary structures and
+ * set up substitution blocks
+ */
+int init_gost_hash_ctx(gost_hash_ctx *ctx, const gost_subst_block *subst_block)
+	{	
+	memset(ctx,0,sizeof(gost_hash_ctx));
+	ctx->cipher_ctx = (gost_ctx *)MYALLOC(sizeof(gost_ctx));
+	if (!ctx->cipher_ctx)
+		{
+		return 0;
+		}		
+	gost_init(ctx->cipher_ctx,subst_block);
+	return 1;
+	}
+
+/*
+ * Free cipher CTX if it is dynamically allocated. Do not use
+ * if cipher ctx is statically allocated as in OpenSSL implementation of
+ * GOST hash algroritm
+ *
+ */ 
+void done_gost_hash_ctx(gost_hash_ctx *ctx) 
+	{
+	/* No need to use gost_destroy, because cipher keys are not really
+	 * secret when hashing */
+	MYFREE(ctx->cipher_ctx);
+	}
+
+/*
+ * reset state of hash context to begin hashing new message
+ */
+int start_hash(gost_hash_ctx *ctx)
+	{
+	if (!ctx->cipher_ctx) return 0;
+	memset(&(ctx->H),0,32);
+	memset(&(ctx->S),0,32);
+	ctx->len = 0L;
+	ctx->left=0;
+	return 1;
+	}
+
+/*
+ * Hash block of arbitrary length
+ *
+ *
+ */
+int hash_block(gost_hash_ctx *ctx,const byte *block, size_t length)
+	{
+	const byte *curptr=block;
+	const byte *barrier=block+(length-32);/* Last byte we can safely hash*/
+	if (ctx->left)
+		{
+		/*There are some bytes from previous step*/
+		unsigned int add_bytes = 32-ctx->left;
+		if (add_bytes>length)
+			{
+			add_bytes = length;
+			}	
+		memcpy(&(ctx->remainder[ctx->left]),block,add_bytes);
+		ctx->left+=add_bytes;
+		if (ctx->left<32)
+			{
+			return 1;
+			}	
+		curptr=block+add_bytes;
+		hash_step(ctx->cipher_ctx,ctx->H,ctx->remainder);
+		add_blocks(32,ctx->S,ctx->remainder);
+		ctx->len+=32;
+		ctx->left=0;
+		}
+	while (curptr<=barrier)
+		{	
+		hash_step(ctx->cipher_ctx,ctx->H,curptr);
+			
+		add_blocks(32,ctx->S,curptr);
+		ctx->len+=32;
+		curptr+=32;
+		}	
+	if (curptr!=block+length)
+		{
+		ctx->left=block+length-curptr;
+		memcpy(ctx->remainder,curptr,ctx->left);
+		}	
+	return 1;	
+	}
+
+/*
+ * Compute hash value from current state of ctx
+ * state of hash ctx becomes invalid and cannot be used for further
+ * hashing.
+ */ 
+int finish_hash(gost_hash_ctx *ctx,byte *hashval)
+	{
+	byte buf[32];
+	byte H[32];
+	byte S[32];
+	ghosthash_len fin_len=ctx->len;
+	byte *bptr;
+	memcpy(H,ctx->H,32);
+	memcpy(S,ctx->S,32);
+	if (ctx->left)
+		{
+		memset(buf,0,32);
+		memcpy(buf,ctx->remainder,ctx->left);
+		hash_step(ctx->cipher_ctx,H,buf);
+		add_blocks(32,S,buf);
+		fin_len+=ctx->left;
+		}
+	memset(buf,0,32);
+	bptr=buf;
+	fin_len<<=3; /* Hash length in BITS!!*/
+	while(fin_len>0)
+		{
+		*(bptr++)=(byte)(fin_len&0xFF);
+		fin_len>>=8;
+		};
+	hash_step(ctx->cipher_ctx,H,buf);
+	hash_step(ctx->cipher_ctx,H,S);
+	memcpy(hashval,H,32);
+	return 1;
+	}
diff --git a/openssl/engines/ccgost/gosthash.h b/openssl/engines/ccgost/gosthash.h
new file mode 100644
index 0000000..4a2e441
--- /dev/null
+++ b/openssl/engines/ccgost/gosthash.h
@@ -0,0 +1,48 @@
+/**********************************************************************
+ *                          gosthash.h                                *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *       This file is distributed under the same license as OpenSSL   *
+ *                                                                    *
+ *    Declaration of GOST R 34.11-94 hash functions                   *
+ *       uses  and gost89.h Doesn't need OpenSSL                      *
+ **********************************************************************/
+#ifndef GOSTHASH_H
+#define GOSTHASH_H
+#include "gost89.h"
+#include <stdlib.h>
+
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
+typedef __int64 ghosthash_len;
+#elif defined(__arch64__)
+typedef long ghosthash_len;
+#else
+typedef long long ghosthash_len;
+#endif
+
+typedef struct gost_hash_ctx {
+		ghosthash_len len;
+		gost_ctx *cipher_ctx;
+		int left;
+		byte H[32];
+		byte S[32];
+		byte remainder[32];
+} gost_hash_ctx;		
+
+
+/* Initalizes gost hash ctx, including creation of gost cipher ctx */
+
+int init_gost_hash_ctx(gost_hash_ctx *ctx, const gost_subst_block *subst_block);
+void done_gost_hash_ctx(gost_hash_ctx *ctx);
+
+/* Cleans up all fields, except cipher ctx preparing ctx for computing
+ * of new hash value */
+int start_hash(gost_hash_ctx *ctx);
+
+/* Hashes block of data */
+int hash_block(gost_hash_ctx *ctx, const byte *block, size_t length);
+
+/* Finalizes computation of hash  and fills buffer (which should be at
+ * least 32 bytes long) with value of computed hash. */
+int finish_hash(gost_hash_ctx *ctx, byte *hashval);
+
+#endif	
diff --git a/openssl/engines/ccgost/gostsum.c b/openssl/engines/ccgost/gostsum.c
new file mode 100644
index 0000000..d57112e
--- /dev/null
+++ b/openssl/engines/ccgost/gostsum.c
@@ -0,0 +1,210 @@
+/**********************************************************************
+ *                        gostsum.c                                   *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *         This file is distributed under the same license as OpenSSL *
+ *                                                                    *
+ *        Almost drop-in replacement for md5sum and sha1sum           *
+ *          which computes GOST R 34.11-94 hashsum instead            *
+ *                                                                    *
+ **********************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <string.h>
+#include "gosthash.h"
+#define BUF_SIZE 262144
+int hash_file(gost_hash_ctx *ctx,char *filename,char *sum,int mode);
+int hash_stream(gost_hash_ctx *ctx,int fd, char *sum);
+int get_line(FILE *f,char *hash,char *filename);
+void help()
+	{
+	fprintf(stderr,"gostsum [-bvt] [-c [file]]| [files]\n"
+		"\t-c check message digests (default is generate)\n"
+		"\t-v verbose, print file names when checking\n"
+		"\t-b read files in binary mode\n"
+		"\t-t use test GOST paramset (default is CryptoPro paramset)\n"
+		"The input for -c should be the list of message digests and file names\n"
+		"that is printed on stdout by this program when it generates digests.\n");
+	exit(3);
+	}
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+int main(int argc,char **argv)
+	{
+	int c,i;
+	int verbose=0;
+	int errors=0;
+	int open_mode = O_RDONLY;
+	gost_subst_block *b=  &GostR3411_94_CryptoProParamSet;
+	FILE *check_file = NULL;
+	gost_hash_ctx ctx;
+	
+	while( (c=getopt(argc,argv,"bc::tv"))!=-1)
+		{
+		switch (c)
+			{
+			case 'v': verbose=1; break;
+			case 't': b= &GostR3411_94_TestParamSet; break;
+			case 'b': open_mode |= O_BINARY; break;
+			case 'c':
+				if (optarg)
+					{
+					check_file = fopen(optarg,"r");
+					if (!check_file)
+						{
+						perror(optarg);
+						exit(2);
+						}
+					}
+				else
+					{
+				  	check_file= stdin;
+					}
+				break;
+			default:
+				fprintf(stderr,"invalid option %c",optopt);
+				help();
+			}
+		}
+	init_gost_hash_ctx(&ctx,b);
+	if (check_file)
+		{
+		char inhash[65],calcsum[65],filename[PATH_MAX];
+		int failcount=0,count=0;;
+		if (check_file==stdin && optind<argc)
+			{
+			check_file=fopen(argv[optind],"r");
+			if (!check_file)
+				{	
+				perror(argv[optind]);
+				exit(2);
+				}
+			}	
+		while (get_line(check_file,inhash,filename))
+			{
+			if (!hash_file(&ctx,filename,calcsum,open_mode))
+				{
+				exit (2);
+				}	
+			count++;
+			if (!strncmp(calcsum,inhash,65))
+				{
+				if (verbose)
+					{
+					fprintf(stderr,"%s\tOK\n",filename);
+					}
+				}
+			else
+				{
+				if (verbose)
+					{
+					fprintf(stderr,"%s\tFAILED\n",filename);
+					}
+				else
+					{
+					fprintf(stderr,"%s: GOST hash sum check failed for '%s'\n",
+						argv[0],filename);
+					}
+				failcount++;
+				}
+			}	
+		if (verbose && failcount)
+			{
+			fprintf(stderr,"%s: %d of %d file(f) failed GOST hash sum check\n",
+				argv[0],failcount,count);
+			}
+		exit (failcount?1:0);
+		}
+	if (optind==argc)
+		{
+		char sum[65];
+		if (!hash_stream(&ctx,fileno(stdin),sum))
+			{
+			perror("stdin");
+			exit(1);
+			}	
+		printf("%s -\n",sum);
+		exit(0);
+		}	
+	for (i=optind;i<argc;i++)
+		{
+		char sum[65];
+		if (!hash_file(&ctx,argv[i],sum,open_mode))
+			{
+			errors++;
+			}
+		else
+			{	
+			printf("%s %s\n",sum,argv[i]);
+			}
+		}	
+	exit(errors?1:0);	
+	}
+
+int hash_file(gost_hash_ctx *ctx,char *filename,char *sum,int mode)
+	{
+	int fd;
+	if ((fd=open(filename,mode))<0)
+		{
+		perror(filename);
+		return 0;
+		}
+	if (!hash_stream(ctx,fd,sum))
+		{
+		perror(filename);
+		return 0;
+		}	
+	close(fd);
+	return 1;
+	}
+
+int hash_stream(gost_hash_ctx *ctx,int fd, char *sum)
+	{
+	unsigned char buffer[BUF_SIZE];
+	ssize_t bytes;
+	int i;
+	start_hash(ctx);
+	while ((bytes=read(fd,buffer,BUF_SIZE))>0)
+		{
+		hash_block(ctx,buffer,bytes);
+		}
+	if (bytes<0)
+		{
+		return 0;
+		}	
+	finish_hash(ctx,buffer);
+	for (i=0;i<32;i++)
+		{
+		sprintf(sum+2*i,"%02x",buffer[31-i]);
+		}
+	return 1;
+	}	
+	
+int get_line(FILE *f,char *hash,char *filename)
+	{
+	int i;
+	if (fread(hash,1,64,f)<64) return 0;
+	hash[64]=0;
+	for (i=0;i<64;i++)
+		{
+		if (hash[i]<'0' || (hash[i]>'9' && hash[i]<'A') || (hash[i]>'F'
+				&& hash[i]<'a')||hash[i]>'f')
+			{
+			fprintf(stderr,"Not a hash value '%s'\n",hash);
+			return 0;
+			}
+		}	
+	if (fgetc(f)!=' ')
+		{
+		fprintf(stderr,"Malformed input line\n");
+		return 0;
+		}
+	i=strlen(fgets(filename,PATH_MAX,f));
+	while (filename[--i]=='\n'||filename[i]=='\r') filename[i]=0;
+	return 1;
+	}	
diff --git a/openssl/engines/e_4758cca.c b/openssl/engines/e_4758cca.c
new file mode 100644
index 0000000..443182b
--- /dev/null
+++ b/openssl/engines/e_4758cca.c
@@ -0,0 +1,987 @@
+/* Author: Maurice Gittens <maurice@gittens.nl>                       */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/dso.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/engine.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_4758_CCA
+
+#ifdef FLAT_INC
+#include "hw_4758_cca.h"
+#else
+#include "vendor_defns/hw_4758_cca.h"
+#endif
+
+#include "e_4758cca_err.c"
+
+static int ibm_4758_cca_destroy(ENGINE *e);
+static int ibm_4758_cca_init(ENGINE *e);
+static int ibm_4758_cca_finish(ENGINE *e);
+static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+
+/* rsa functions */
+/*---------------*/
+#ifndef OPENSSL_NO_RSA
+static int cca_rsa_pub_enc(int flen, const unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+static int cca_rsa_priv_dec(int flen, const unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
+		unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
+static int cca_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
+	const unsigned char *sigbuf, unsigned int siglen, const RSA *rsa);
+
+/* utility functions */
+/*-----------------------*/
+static EVP_PKEY *ibm_4758_load_privkey(ENGINE*, const char*,
+		UI_METHOD *ui_method, void *callback_data);
+static EVP_PKEY *ibm_4758_load_pubkey(ENGINE*, const char*,
+		UI_METHOD *ui_method, void *callback_data);
+
+static int getModulusAndExponent(const unsigned char *token, long *exponentLength,
+		unsigned char *exponent, long *modulusLength,
+		long *modulusFieldLength, unsigned char *modulus);
+#endif
+
+/* RAND number functions */
+/*-----------------------*/
+static int cca_get_random_bytes(unsigned char*, int);
+static int cca_random_status(void);
+
+#ifndef OPENSSL_NO_RSA
+static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
+		int idx,long argl, void *argp);
+#endif
+
+/* Function pointers for CCA verbs */
+/*---------------------------------*/
+#ifndef OPENSSL_NO_RSA
+static F_KEYRECORDREAD keyRecordRead;
+static F_DIGITALSIGNATUREGENERATE digitalSignatureGenerate;
+static F_DIGITALSIGNATUREVERIFY digitalSignatureVerify;
+static F_PUBLICKEYEXTRACT publicKeyExtract;
+static F_PKAENCRYPT pkaEncrypt;
+static F_PKADECRYPT pkaDecrypt;
+#endif
+static F_RANDOMNUMBERGENERATE randomNumberGenerate;
+
+/* static variables */
+/*------------------*/
+static const char *CCA4758_LIB_NAME = NULL;
+static const char *get_CCA4758_LIB_NAME(void)
+	{
+	if(CCA4758_LIB_NAME)
+		return CCA4758_LIB_NAME;
+	return CCA_LIB_NAME;
+	}
+static void free_CCA4758_LIB_NAME(void)
+	{
+	if(CCA4758_LIB_NAME)
+		OPENSSL_free((void*)CCA4758_LIB_NAME);
+	CCA4758_LIB_NAME = NULL;
+	}
+static long set_CCA4758_LIB_NAME(const char *name)
+	{
+	free_CCA4758_LIB_NAME();
+	return (((CCA4758_LIB_NAME = BUF_strdup(name)) != NULL) ? 1 : 0);
+	}
+#ifndef OPENSSL_NO_RSA
+static const char* n_keyRecordRead = CSNDKRR;
+static const char* n_digitalSignatureGenerate = CSNDDSG;
+static const char* n_digitalSignatureVerify = CSNDDSV;
+static const char* n_publicKeyExtract = CSNDPKX;
+static const char* n_pkaEncrypt = CSNDPKE;
+static const char* n_pkaDecrypt = CSNDPKD;
+#endif
+static const char* n_randomNumberGenerate = CSNBRNG;
+
+#ifndef OPENSSL_NO_RSA
+static int hndidx = -1;
+#endif
+static DSO *dso = NULL;
+
+/* openssl engine initialization structures */
+/*------------------------------------------*/
+
+#define CCA4758_CMD_SO_PATH		ENGINE_CMD_BASE
+static const ENGINE_CMD_DEFN	cca4758_cmd_defns[] = {
+	{CCA4758_CMD_SO_PATH,
+		"SO_PATH",
+		"Specifies the path to the '4758cca' shared library",
+		ENGINE_CMD_FLAG_STRING},
+	{0, NULL, NULL, 0}
+	};
+
+#ifndef OPENSSL_NO_RSA
+static RSA_METHOD ibm_4758_cca_rsa =
+	{
+	"IBM 4758 CCA RSA method",
+	cca_rsa_pub_enc,
+	NULL,
+	NULL,
+	cca_rsa_priv_dec,
+	NULL, /*rsa_mod_exp,*/
+	NULL, /*mod_exp_mont,*/
+	NULL, /* init */
+	NULL, /* finish */
+	RSA_FLAG_SIGN_VER,	  /* flags */
+	NULL, /* app_data */
+	cca_rsa_sign, /* rsa_sign */
+	cca_rsa_verify, /* rsa_verify */
+	NULL /* rsa_keygen */
+	};
+#endif
+
+static RAND_METHOD ibm_4758_cca_rand =
+	{
+	/* "IBM 4758 RAND method", */
+	NULL, /* seed */
+	cca_get_random_bytes, /* get random bytes from the card */
+	NULL, /* cleanup */
+	NULL, /* add */
+	cca_get_random_bytes, /* pseudo rand */
+	cca_random_status, /* status */
+	};
+
+static const char *engine_4758_cca_id = "4758cca";
+static const char *engine_4758_cca_name = "IBM 4758 CCA hardware engine support";
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE 
+/* Compatibility hack, the dynamic library uses this form in the path */
+static const char *engine_4758_cca_id_alt = "4758_cca";
+#endif
+
+/* engine implementation */
+/*-----------------------*/
+static int bind_helper(ENGINE *e)
+	{
+	if(!ENGINE_set_id(e, engine_4758_cca_id) ||
+			!ENGINE_set_name(e, engine_4758_cca_name) ||
+#ifndef OPENSSL_NO_RSA
+			!ENGINE_set_RSA(e, &ibm_4758_cca_rsa) ||
+#endif
+			!ENGINE_set_RAND(e, &ibm_4758_cca_rand) ||
+			!ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) ||
+			!ENGINE_set_init_function(e, ibm_4758_cca_init) ||
+			!ENGINE_set_finish_function(e, ibm_4758_cca_finish) ||
+			!ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) ||
+#ifndef OPENSSL_NO_RSA
+			!ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) ||
+			!ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) ||
+#endif
+			!ENGINE_set_cmd_defns(e, cca4758_cmd_defns))
+		return 0;
+	/* Ensure the error handling is set up */
+	ERR_load_CCA4758_strings();
+	return 1;
+	}
+
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+static ENGINE *engine_4758_cca(void)
+	{
+	ENGINE *ret = ENGINE_new();
+	if(!ret)
+		return NULL;
+	if(!bind_helper(ret))
+		{
+		ENGINE_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+void ENGINE_load_4758cca(void)
+	{
+	ENGINE *e_4758 = engine_4758_cca();
+	if (!e_4758) return;
+	ENGINE_add(e_4758);
+	ENGINE_free(e_4758);
+	ERR_clear_error();   
+	}
+#endif
+
+static int ibm_4758_cca_destroy(ENGINE *e)
+	{
+	ERR_unload_CCA4758_strings();
+	free_CCA4758_LIB_NAME();
+	return 1;
+	}
+
+static int ibm_4758_cca_init(ENGINE *e)
+	{
+	if(dso)
+		{
+		CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_ALREADY_LOADED);
+		goto err;
+		}
+
+	dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0);
+	if(!dso)
+		{
+		CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
+		goto err;
+		}
+
+#ifndef OPENSSL_NO_RSA
+	if(!(keyRecordRead = (F_KEYRECORDREAD)
+				DSO_bind_func(dso, n_keyRecordRead)) ||
+			!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
+				DSO_bind_func(dso, n_randomNumberGenerate)) ||
+			!(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)
+				DSO_bind_func(dso, n_digitalSignatureGenerate)) ||
+			!(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)
+				DSO_bind_func(dso, n_digitalSignatureVerify)) ||
+			!(publicKeyExtract = (F_PUBLICKEYEXTRACT)
+				DSO_bind_func(dso, n_publicKeyExtract)) ||
+			!(pkaEncrypt = (F_PKAENCRYPT)
+				DSO_bind_func(dso, n_pkaEncrypt)) ||
+			!(pkaDecrypt = (F_PKADECRYPT)
+				DSO_bind_func(dso, n_pkaDecrypt)))
+		{
+		CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
+		goto err;
+		}
+#else
+	if(!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
+				DSO_bind_func(dso, n_randomNumberGenerate)))
+		{
+		CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
+		goto err;
+		}
+#endif
+
+#ifndef OPENSSL_NO_RSA
+	hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle",
+		NULL, NULL, cca_ex_free);
+#endif
+
+	return 1;
+err:
+	if(dso)
+		DSO_free(dso);
+	dso = NULL;
+
+#ifndef OPENSSL_NO_RSA
+	keyRecordRead = (F_KEYRECORDREAD)0;
+	digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)0;
+	digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0;
+	publicKeyExtract = (F_PUBLICKEYEXTRACT)0;
+	pkaEncrypt = (F_PKAENCRYPT)0;
+	pkaDecrypt = (F_PKADECRYPT)0;
+#endif
+	randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
+	return 0;
+	}
+
+static int ibm_4758_cca_finish(ENGINE *e)
+	{
+	free_CCA4758_LIB_NAME();
+	if(!dso)
+		{
+		CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
+				CCA4758_R_NOT_LOADED);
+		return 0;
+		}
+	if(!DSO_free(dso))
+		{
+		CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
+				CCA4758_R_UNIT_FAILURE);
+		return 0;
+		}
+	dso = NULL;
+#ifndef OPENSSL_NO_RSA
+	keyRecordRead = (F_KEYRECORDREAD)0;
+	randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
+	digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)0;
+	digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0;
+	publicKeyExtract = (F_PUBLICKEYEXTRACT)0;
+	pkaEncrypt = (F_PKAENCRYPT)0;
+	pkaDecrypt = (F_PKADECRYPT)0;
+#endif
+	randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
+	return 1;
+	}
+
+static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+	{
+	int initialised = ((dso == NULL) ? 0 : 1);
+	switch(cmd)
+		{
+	case CCA4758_CMD_SO_PATH:
+		if(p == NULL)
+			{
+			CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
+					ERR_R_PASSED_NULL_PARAMETER);
+			return 0;
+			}
+		if(initialised)
+			{
+			CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
+					CCA4758_R_ALREADY_LOADED);
+			return 0;
+			}
+		return set_CCA4758_LIB_NAME((const char *)p);
+	default:
+		break;
+		}
+	CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
+			CCA4758_R_COMMAND_NOT_IMPLEMENTED);
+	return 0;
+	}
+
+#ifndef OPENSSL_NO_RSA
+
+#define MAX_CCA_PKA_TOKEN_SIZE 2500
+
+static EVP_PKEY *ibm_4758_load_privkey(ENGINE* e, const char* key_id,
+			UI_METHOD *ui_method, void *callback_data)
+	{
+	RSA *rtmp = NULL;
+	EVP_PKEY *res = NULL;
+	unsigned char* keyToken = NULL;
+	unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE];
+	long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
+	long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
+	long returnCode;
+	long reasonCode;
+	long exitDataLength = 0;
+	long ruleArrayLength = 0;
+	unsigned char exitData[8];
+	unsigned char ruleArray[8];
+	unsigned char keyLabel[64];
+	unsigned long keyLabelLength = strlen(key_id);
+	unsigned char modulus[256];
+	long modulusFieldLength = sizeof(modulus);
+	long modulusLength = 0;
+	unsigned char exponent[256];
+	long exponentLength = sizeof(exponent);
+
+	if (keyLabelLength > sizeof(keyLabel))
+		{
+		CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
+		CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+		return NULL;
+		}
+
+	memset(keyLabel,' ', sizeof(keyLabel));
+	memcpy(keyLabel, key_id, keyLabelLength);
+
+	keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
+	if (!keyToken)
+		{
+		CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
+				ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	keyRecordRead(&returnCode, &reasonCode, &exitDataLength,
+		exitData, &ruleArrayLength, ruleArray, keyLabel,
+		&keyTokenLength, keyToken+sizeof(long));
+
+	if (returnCode)
+		{
+		CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
+			CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
+		goto err;
+		}
+
+	publicKeyExtract(&returnCode, &reasonCode, &exitDataLength,
+		exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
+		keyToken+sizeof(long), &pubKeyTokenLength, pubKeyToken);
+
+	if (returnCode)
+		{
+		CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
+			CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
+		goto err;
+		}
+
+	if (!getModulusAndExponent(pubKeyToken, &exponentLength,
+			exponent, &modulusLength, &modulusFieldLength,
+			modulus))
+		{
+		CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
+			CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
+		goto err;
+		}
+
+	(*(long*)keyToken) = keyTokenLength;
+	rtmp = RSA_new_method(e);
+	RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
+
+	rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
+	rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
+	rtmp->flags |= RSA_FLAG_EXT_PKEY;
+
+	res = EVP_PKEY_new();
+	EVP_PKEY_assign_RSA(res, rtmp);
+
+	return res;
+err:
+	if (keyToken)
+		OPENSSL_free(keyToken);
+	return NULL;
+	}
+
+static EVP_PKEY *ibm_4758_load_pubkey(ENGINE* e, const char* key_id,
+			UI_METHOD *ui_method, void *callback_data)
+	{
+	RSA *rtmp = NULL;
+	EVP_PKEY *res = NULL;
+	unsigned char* keyToken = NULL;
+	long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
+	long returnCode;
+	long reasonCode;
+	long exitDataLength = 0;
+	long ruleArrayLength = 0;
+	unsigned char exitData[8];
+	unsigned char ruleArray[8];
+	unsigned char keyLabel[64];
+	unsigned long keyLabelLength = strlen(key_id);
+	unsigned char modulus[512];
+	long modulusFieldLength = sizeof(modulus);
+	long modulusLength = 0;
+	unsigned char exponent[512];
+	long exponentLength = sizeof(exponent);
+
+	if (keyLabelLength > sizeof(keyLabel))
+		{
+		CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
+			CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+		return NULL;
+		}
+
+	memset(keyLabel,' ', sizeof(keyLabel));
+	memcpy(keyLabel, key_id, keyLabelLength);
+
+	keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
+	if (!keyToken)
+		{
+		CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
+				ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData,
+		&ruleArrayLength, ruleArray, keyLabel, &keyTokenLength,
+		keyToken+sizeof(long));
+
+	if (returnCode)
+		{
+		CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
+				ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (!getModulusAndExponent(keyToken+sizeof(long), &exponentLength,
+			exponent, &modulusLength, &modulusFieldLength, modulus))
+		{
+		CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
+			CCA4758_R_FAILED_LOADING_PUBLIC_KEY);
+		goto err;
+		}
+
+	(*(long*)keyToken) = keyTokenLength;
+	rtmp = RSA_new_method(e);
+	RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
+	rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
+	rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
+	rtmp->flags |= RSA_FLAG_EXT_PKEY;
+	res = EVP_PKEY_new();
+	EVP_PKEY_assign_RSA(res, rtmp);
+
+	return res;
+err:
+	if (keyToken)
+		OPENSSL_free(keyToken);
+	return NULL;
+	}
+
+static int cca_rsa_pub_enc(int flen, const unsigned char *from,
+			unsigned char *to, RSA *rsa,int padding)
+	{
+	long returnCode;
+	long reasonCode;
+	long lflen = flen;
+	long exitDataLength = 0;
+	unsigned char exitData[8];
+	long ruleArrayLength = 1;
+	unsigned char ruleArray[8] = "PKCS-1.2";
+	long dataStructureLength = 0;
+	unsigned char dataStructure[8];
+	long outputLength = RSA_size(rsa);
+	long keyTokenLength;
+	unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
+
+	keyTokenLength = *(long*)keyToken;
+	keyToken+=sizeof(long);
+
+	pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
+		&ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
+		&dataStructureLength, dataStructure, &keyTokenLength,
+		keyToken, &outputLength, to);
+
+	if (returnCode || reasonCode)
+		return -(returnCode << 16 | reasonCode);
+	return outputLength;
+	}
+
+static int cca_rsa_priv_dec(int flen, const unsigned char *from,
+			unsigned char *to, RSA *rsa,int padding)
+	{
+	long returnCode;
+	long reasonCode;
+	long lflen = flen;
+	long exitDataLength = 0;
+	unsigned char exitData[8];
+	long ruleArrayLength = 1;
+	unsigned char ruleArray[8] = "PKCS-1.2";
+	long dataStructureLength = 0;
+	unsigned char dataStructure[8];
+	long outputLength = RSA_size(rsa);
+	long keyTokenLength;
+	unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
+
+	keyTokenLength = *(long*)keyToken;
+	keyToken+=sizeof(long);
+
+	pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
+		&ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
+		&dataStructureLength, dataStructure, &keyTokenLength,
+		keyToken, &outputLength, to);
+
+	return (returnCode | reasonCode) ? 0 : 1;
+	}
+
+#define SSL_SIG_LEN 36
+
+static int cca_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
+	const unsigned char *sigbuf, unsigned int siglen, const RSA *rsa)
+	{
+	long returnCode;
+	long reasonCode;
+	long lsiglen = siglen;
+	long exitDataLength = 0;
+	unsigned char exitData[8];
+	long ruleArrayLength = 1;
+	unsigned char ruleArray[8] = "PKCS-1.1";
+	long keyTokenLength;
+	unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
+	long length = SSL_SIG_LEN;
+	long keyLength ;
+	unsigned char *hashBuffer = NULL;
+	X509_SIG sig;
+	ASN1_TYPE parameter;
+	X509_ALGOR algorithm;
+	ASN1_OCTET_STRING digest;
+
+	keyTokenLength = *(long*)keyToken;
+	keyToken+=sizeof(long);
+
+	if (type == NID_md5 || type == NID_sha1)
+		{
+		sig.algor = &algorithm;
+		algorithm.algorithm = OBJ_nid2obj(type);
+
+		if (!algorithm.algorithm)
+			{
+			CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
+				CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
+			return 0;
+			}
+
+		if (!algorithm.algorithm->length)
+			{
+			CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
+				CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
+			return 0;
+			}
+
+		parameter.type = V_ASN1_NULL;
+		parameter.value.ptr = NULL;
+		algorithm.parameter = &parameter;
+
+		sig.digest = &digest;
+		sig.digest->data = (unsigned char*)m;
+		sig.digest->length = m_len;
+
+		length = i2d_X509_SIG(&sig, NULL);
+		}
+
+	keyLength = RSA_size(rsa);
+
+	if (length - RSA_PKCS1_PADDING > keyLength)
+		{
+		CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
+			CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+		return 0;
+		}
+
+	switch (type)
+		{
+		case NID_md5_sha1 :
+			if (m_len != SSL_SIG_LEN)
+				{
+				CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
+				CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+				return 0;
+				}
+
+			hashBuffer = (unsigned char *)m;
+			length = m_len;
+			break;
+		case NID_md5 :
+			{
+			unsigned char *ptr;
+			ptr = hashBuffer = OPENSSL_malloc(
+					(unsigned int)keyLength+1);
+			if (!hashBuffer)
+				{
+				CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
+						ERR_R_MALLOC_FAILURE);
+				return 0;
+				}
+
+			i2d_X509_SIG(&sig, &ptr);
+			}
+			break;
+		case NID_sha1 :
+			{
+			unsigned char *ptr;
+			ptr = hashBuffer = OPENSSL_malloc(
+					(unsigned int)keyLength+1);
+			if (!hashBuffer)
+				{
+				CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
+						ERR_R_MALLOC_FAILURE);
+				return 0;
+				}
+			i2d_X509_SIG(&sig, &ptr);
+			}
+			break;
+		default:
+			return 0;
+		}
+
+	digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength,
+		exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
+		keyToken, &length, hashBuffer, &lsiglen,
+						(unsigned char *)sigbuf);
+
+	if (type == NID_sha1 || type == NID_md5)
+		{
+		OPENSSL_cleanse(hashBuffer, keyLength+1);
+		OPENSSL_free(hashBuffer);
+		}
+
+	return ((returnCode || reasonCode) ? 0 : 1);
+	}
+
+#define SSL_SIG_LEN 36
+
+static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
+		unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
+	{
+	long returnCode;
+	long reasonCode;
+	long exitDataLength = 0;
+	unsigned char exitData[8];
+	long ruleArrayLength = 1;
+	unsigned char ruleArray[8] = "PKCS-1.1";
+	long outputLength=256;
+	long outputBitLength;
+	long keyTokenLength;
+	unsigned char *hashBuffer = NULL;
+	unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
+	long length = SSL_SIG_LEN;
+	long keyLength ;
+	X509_SIG sig;
+	ASN1_TYPE parameter;
+	X509_ALGOR algorithm;
+	ASN1_OCTET_STRING digest;
+
+	keyTokenLength = *(long*)keyToken;
+	keyToken+=sizeof(long);
+
+	if (type == NID_md5 || type == NID_sha1)
+		{
+		sig.algor = &algorithm;
+		algorithm.algorithm = OBJ_nid2obj(type);
+
+		if (!algorithm.algorithm)
+			{
+			CCA4758err(CCA4758_F_CCA_RSA_SIGN,
+				CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
+			return 0;
+			}
+
+		if (!algorithm.algorithm->length)
+			{
+			CCA4758err(CCA4758_F_CCA_RSA_SIGN,
+				CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
+			return 0;
+			}
+
+		parameter.type = V_ASN1_NULL;
+		parameter.value.ptr = NULL;
+		algorithm.parameter = &parameter;
+
+		sig.digest = &digest;
+		sig.digest->data = (unsigned char*)m;
+		sig.digest->length = m_len;
+
+		length = i2d_X509_SIG(&sig, NULL);
+		}
+
+	keyLength = RSA_size(rsa);
+
+	if (length - RSA_PKCS1_PADDING > keyLength)
+		{
+		CCA4758err(CCA4758_F_CCA_RSA_SIGN,
+			CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+		return 0;
+		}
+
+	switch (type)
+		{
+		case NID_md5_sha1 :
+			if (m_len != SSL_SIG_LEN)
+				{
+				CCA4758err(CCA4758_F_CCA_RSA_SIGN,
+				CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+				return 0;
+				}
+			hashBuffer = (unsigned char*)m;
+			length = m_len;
+			break;
+		case NID_md5 :
+			{
+			unsigned char *ptr;
+			ptr = hashBuffer = OPENSSL_malloc(
+					(unsigned int)keyLength+1);
+			if (!hashBuffer)
+				{
+				CCA4758err(CCA4758_F_CCA_RSA_SIGN,
+						ERR_R_MALLOC_FAILURE);
+				return 0;
+				}
+			i2d_X509_SIG(&sig, &ptr);
+			}
+			break;
+		case NID_sha1 :
+			{
+			unsigned char *ptr;
+			ptr = hashBuffer = OPENSSL_malloc(
+					(unsigned int)keyLength+1);
+			if (!hashBuffer)
+				{
+				CCA4758err(CCA4758_F_CCA_RSA_SIGN,
+						ERR_R_MALLOC_FAILURE);
+				return 0;
+				}
+			i2d_X509_SIG(&sig, &ptr);
+			}
+			break;
+		default:
+			return 0;
+		}
+
+	digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength,
+		exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
+		keyToken, &length, hashBuffer, &outputLength, &outputBitLength,
+		sigret);
+
+	if (type == NID_sha1 || type == NID_md5)
+		{
+		OPENSSL_cleanse(hashBuffer, keyLength+1);
+		OPENSSL_free(hashBuffer);
+		}
+
+	*siglen = outputLength;
+
+	return ((returnCode || reasonCode) ? 0 : 1);
+	}
+
+static int getModulusAndExponent(const unsigned char*token, long *exponentLength,
+		unsigned char *exponent, long *modulusLength, long *modulusFieldLength,
+		unsigned char *modulus)
+	{
+	unsigned long len;
+
+	if (*token++ != (char)0x1E) /* internal PKA token? */
+		return 0;
+
+	if (*token++) /* token version must be zero */
+		return 0;
+
+	len = *token++;
+	len = len << 8;
+	len |= (unsigned char)*token++;
+
+	token += 4; /* skip reserved bytes */
+
+	if (*token++ == (char)0x04)
+		{
+		if (*token++) /* token version must be zero */
+			return 0;
+
+		len = *token++;
+		len = len << 8;
+		len |= (unsigned char)*token++;
+
+		token+=2; /* skip reserved section */
+
+		len = *token++;
+		len = len << 8;
+		len |= (unsigned char)*token++;
+
+		*exponentLength = len;
+
+		len = *token++;
+		len = len << 8;
+		len |= (unsigned char)*token++;
+
+		*modulusLength = len;
+
+		len = *token++;
+		len = len << 8;
+		len |= (unsigned char)*token++;
+
+		*modulusFieldLength = len;
+
+		memcpy(exponent, token, *exponentLength);
+		token+= *exponentLength;
+
+		memcpy(modulus, token, *modulusFieldLength);
+		return 1;
+		}
+	return 0;
+	}
+
+#endif /* OPENSSL_NO_RSA */
+
+static int cca_random_status(void)
+	{
+	return 1;
+	}
+
+static int cca_get_random_bytes(unsigned char* buf, int num)
+	{
+	long ret_code;
+	long reason_code;
+	long exit_data_length;
+	unsigned char exit_data[4];
+	unsigned char form[] = "RANDOM  ";
+	unsigned char rand_buf[8];
+
+	while(num >= (int)sizeof(rand_buf))
+		{
+		randomNumberGenerate(&ret_code, &reason_code, &exit_data_length,
+			exit_data, form, rand_buf);
+		if (ret_code)
+			return 0;
+		num -= sizeof(rand_buf);
+		memcpy(buf, rand_buf, sizeof(rand_buf));
+		buf += sizeof(rand_buf);
+		}
+
+	if (num)
+		{
+		randomNumberGenerate(&ret_code, &reason_code, NULL, NULL,
+			form, rand_buf);
+		if (ret_code)
+			return 0;
+		memcpy(buf, rand_buf, num);
+		}
+
+	return 1;
+	}
+
+#ifndef OPENSSL_NO_RSA
+static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx,
+		long argl, void *argp)
+	{
+	if (item)
+		OPENSSL_free(item);
+	}
+#endif
+
+/* Goo to handle building as a dynamic engine */
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE 
+static int bind_fn(ENGINE *e, const char *id)
+	{
+	if(id && (strcmp(id, engine_4758_cca_id) != 0) &&
+			(strcmp(id, engine_4758_cca_id_alt) != 0))
+		return 0;
+	if(!bind_helper(e))
+		return 0;
+	return 1;
+	}       
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
+
+#endif /* !OPENSSL_NO_HW_4758_CCA */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_4758cca.ec b/openssl/engines/e_4758cca.ec
new file mode 100644
index 0000000..f30ed02
--- /dev/null
+++ b/openssl/engines/e_4758cca.ec
@@ -0,0 +1 @@
+L CCA4758	e_4758cca_err.h		e_4758cca_err.c
diff --git a/openssl/engines/e_4758cca_err.c b/openssl/engines/e_4758cca_err.c
new file mode 100644
index 0000000..6ecdc6e
--- /dev/null
+++ b/openssl/engines/e_4758cca_err.c
@@ -0,0 +1,153 @@
+/* e_4758cca_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "e_4758cca_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA CCA4758_str_functs[]=
+	{
+{ERR_FUNC(CCA4758_F_CCA_RSA_SIGN),	"CCA_RSA_SIGN"},
+{ERR_FUNC(CCA4758_F_CCA_RSA_VERIFY),	"CCA_RSA_VERIFY"},
+{ERR_FUNC(CCA4758_F_IBM_4758_CCA_CTRL),	"IBM_4758_CCA_CTRL"},
+{ERR_FUNC(CCA4758_F_IBM_4758_CCA_FINISH),	"IBM_4758_CCA_FINISH"},
+{ERR_FUNC(CCA4758_F_IBM_4758_CCA_INIT),	"IBM_4758_CCA_INIT"},
+{ERR_FUNC(CCA4758_F_IBM_4758_LOAD_PRIVKEY),	"IBM_4758_LOAD_PRIVKEY"},
+{ERR_FUNC(CCA4758_F_IBM_4758_LOAD_PUBKEY),	"IBM_4758_LOAD_PUBKEY"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA CCA4758_str_reasons[]=
+	{
+{ERR_REASON(CCA4758_R_ALREADY_LOADED)    ,"already loaded"},
+{ERR_REASON(CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD),"asn1 oid unknown for md"},
+{ERR_REASON(CCA4758_R_COMMAND_NOT_IMPLEMENTED),"command not implemented"},
+{ERR_REASON(CCA4758_R_DSO_FAILURE)       ,"dso failure"},
+{ERR_REASON(CCA4758_R_FAILED_LOADING_PRIVATE_KEY),"failed loading private key"},
+{ERR_REASON(CCA4758_R_FAILED_LOADING_PUBLIC_KEY),"failed loading public key"},
+{ERR_REASON(CCA4758_R_NOT_LOADED)        ,"not loaded"},
+{ERR_REASON(CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL),"size too large or too small"},
+{ERR_REASON(CCA4758_R_UNIT_FAILURE)      ,"unit failure"},
+{ERR_REASON(CCA4758_R_UNKNOWN_ALGORITHM_TYPE),"unknown algorithm type"},
+{0,NULL}
+	};
+
+#endif
+
+#ifdef CCA4758_LIB_NAME
+static ERR_STRING_DATA CCA4758_lib_name[]=
+        {
+{0	,CCA4758_LIB_NAME},
+{0,NULL}
+	};
+#endif
+
+
+static int CCA4758_lib_error_code=0;
+static int CCA4758_error_init=1;
+
+static void ERR_load_CCA4758_strings(void)
+	{
+	if (CCA4758_lib_error_code == 0)
+		CCA4758_lib_error_code=ERR_get_next_error_library();
+
+	if (CCA4758_error_init)
+		{
+		CCA4758_error_init=0;
+#ifndef OPENSSL_NO_ERR
+		ERR_load_strings(CCA4758_lib_error_code,CCA4758_str_functs);
+		ERR_load_strings(CCA4758_lib_error_code,CCA4758_str_reasons);
+#endif
+
+#ifdef CCA4758_LIB_NAME
+		CCA4758_lib_name->error = ERR_PACK(CCA4758_lib_error_code,0,0);
+		ERR_load_strings(0,CCA4758_lib_name);
+#endif
+		}
+	}
+
+static void ERR_unload_CCA4758_strings(void)
+	{
+	if (CCA4758_error_init == 0)
+		{
+#ifndef OPENSSL_NO_ERR
+		ERR_unload_strings(CCA4758_lib_error_code,CCA4758_str_functs);
+		ERR_unload_strings(CCA4758_lib_error_code,CCA4758_str_reasons);
+#endif
+
+#ifdef CCA4758_LIB_NAME
+		ERR_unload_strings(0,CCA4758_lib_name);
+#endif
+		CCA4758_error_init=1;
+		}
+	}
+
+static void ERR_CCA4758_error(int function, int reason, char *file, int line)
+	{
+	if (CCA4758_lib_error_code == 0)
+		CCA4758_lib_error_code=ERR_get_next_error_library();
+	ERR_PUT_error(CCA4758_lib_error_code,function,reason,file,line);
+	}
diff --git a/openssl/engines/e_4758cca_err.h b/openssl/engines/e_4758cca_err.h
new file mode 100644
index 0000000..26087ed
--- /dev/null
+++ b/openssl/engines/e_4758cca_err.h
@@ -0,0 +1,97 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_CCA4758_ERR_H
+#define HEADER_CCA4758_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_CCA4758_strings(void);
+static void ERR_unload_CCA4758_strings(void);
+static void ERR_CCA4758_error(int function, int reason, char *file, int line);
+#define CCA4758err(f,r) ERR_CCA4758_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the CCA4758 functions. */
+
+/* Function codes. */
+#define CCA4758_F_CCA_RSA_SIGN				 105
+#define CCA4758_F_CCA_RSA_VERIFY			 106
+#define CCA4758_F_IBM_4758_CCA_CTRL			 100
+#define CCA4758_F_IBM_4758_CCA_FINISH			 101
+#define CCA4758_F_IBM_4758_CCA_INIT			 102
+#define CCA4758_F_IBM_4758_LOAD_PRIVKEY			 103
+#define CCA4758_F_IBM_4758_LOAD_PUBKEY			 104
+
+/* Reason codes. */
+#define CCA4758_R_ALREADY_LOADED			 100
+#define CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD		 101
+#define CCA4758_R_COMMAND_NOT_IMPLEMENTED		 102
+#define CCA4758_R_DSO_FAILURE				 103
+#define CCA4758_R_FAILED_LOADING_PRIVATE_KEY		 104
+#define CCA4758_R_FAILED_LOADING_PUBLIC_KEY		 105
+#define CCA4758_R_NOT_LOADED				 106
+#define CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL		 107
+#define CCA4758_R_UNIT_FAILURE				 108
+#define CCA4758_R_UNKNOWN_ALGORITHM_TYPE		 109
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_aep.c b/openssl/engines/e_aep.c
new file mode 100644
index 0000000..d7f89e5
--- /dev/null
+++ b/openssl/engines/e_aep.c
@@ -0,0 +1,1140 @@
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <openssl/bn.h>
+#include <string.h>
+
+#include <openssl/e_os2.h>
+#if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) || defined(__MINGW32__)
+#include <sys/types.h>
+#include <unistd.h>
+#else
+#include <process.h>
+typedef int pid_t;
+#endif
+
+#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
+#define getpid GetThreadID
+extern int GetThreadID(void);
+#elif defined(_WIN32) && !defined(__WATCOMC__)
+#define getpid _getpid
+#endif
+
+#include <openssl/crypto.h>
+#include <openssl/dso.h>
+#include <openssl/engine.h>
+#include <openssl/buffer.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_AEP
+#ifdef FLAT_INC
+#include "aep.h"
+#else
+#include "vendor_defns/aep.h"
+#endif
+
+#define AEP_LIB_NAME "aep engine"
+#define FAIL_TO_SW 0x10101010
+
+#include "e_aep_err.c"
+
+static int aep_init(ENGINE *e);
+static int aep_finish(ENGINE *e);
+static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+static int aep_destroy(ENGINE *e);
+
+static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR hConnection);
+static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection);
+static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection);
+static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use);
+
+/* BIGNUM stuff */
+#ifndef OPENSSL_NO_RSA
+static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx);
+
+static AEP_RV aep_mod_exp_crt(BIGNUM *r,const  BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *q, const BIGNUM *dmp1,const BIGNUM *dmq1,
+	const BIGNUM *iqmp, BN_CTX *ctx);
+#endif
+
+/* RSA stuff */
+#ifndef OPENSSL_NO_RSA
+static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+#endif
+
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+#ifndef OPENSSL_NO_RSA
+static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#endif
+
+/* DSA stuff */
+#ifndef OPENSSL_NO_DSA
+static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
+	BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
+	BN_CTX *ctx, BN_MONT_CTX *in_mont);
+
+static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+	const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+	BN_MONT_CTX *m_ctx);
+#endif
+
+/* DH stuff */
+/* This function is aliased to mod_exp (with the DH and mont dropped). */
+#ifndef OPENSSL_NO_DH
+static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
+	const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#endif
+
+/* rand stuff   */
+#ifdef AEPRAND
+static int aep_rand(unsigned char *buf, int num);
+static int aep_rand_status(void);
+#endif
+
+/* Bignum conversion stuff */
+static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize);
+static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
+	unsigned char* AEP_BigNum);
+static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize,
+	unsigned char* AEP_BigNum);
+
+/* The definitions for control commands specific to this engine */
+#define AEP_CMD_SO_PATH		ENGINE_CMD_BASE
+static const ENGINE_CMD_DEFN aep_cmd_defns[] =
+	{
+	{ AEP_CMD_SO_PATH,
+	  "SO_PATH",
+	  "Specifies the path to the 'aep' shared library",
+	  ENGINE_CMD_FLAG_STRING
+	},
+	{0, NULL, NULL, 0}
+	};
+
+#ifndef OPENSSL_NO_RSA
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD aep_rsa =
+	{
+	"Aep RSA method",
+	NULL,                /*rsa_pub_encrypt*/
+	NULL,                /*rsa_pub_decrypt*/
+	NULL,                /*rsa_priv_encrypt*/
+	NULL,                /*rsa_priv_encrypt*/
+	aep_rsa_mod_exp,     /*rsa_mod_exp*/
+	aep_mod_exp_mont,    /*bn_mod_exp*/
+	NULL,                /*init*/
+	NULL,                /*finish*/
+	0,                   /*flags*/
+	NULL,                /*app_data*/
+	NULL,                /*rsa_sign*/
+	NULL,                /*rsa_verify*/
+	NULL                 /*rsa_keygen*/
+	};
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* Our internal DSA_METHOD that we provide pointers to */
+static DSA_METHOD aep_dsa =
+	{
+	"Aep DSA method",
+	NULL,                /* dsa_do_sign */
+	NULL,                /* dsa_sign_setup */
+	NULL,                /* dsa_do_verify */
+	aep_dsa_mod_exp,     /* dsa_mod_exp */
+	aep_mod_exp_dsa,     /* bn_mod_exp */
+	NULL,                /* init */
+	NULL,                /* finish */
+	0,                   /* flags */
+	NULL,                /* app_data */
+	NULL,                /* dsa_paramgen */
+	NULL                 /* dsa_keygen */
+	};
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* Our internal DH_METHOD that we provide pointers to */
+static DH_METHOD aep_dh =
+	{
+	"Aep DH method",
+	NULL,
+	NULL,
+	aep_mod_exp_dh,
+	NULL,
+	NULL,
+	0,
+	NULL,
+	NULL
+	};
+#endif
+
+#ifdef AEPRAND
+/* our internal RAND_method that we provide pointers to  */
+static RAND_METHOD aep_random =
+	{
+	/*"AEP RAND method", */
+	NULL,
+	aep_rand,
+	NULL,
+	NULL,
+	aep_rand,
+	aep_rand_status,
+	};
+#endif
+
+/*Define an array of structures to hold connections*/
+static AEP_CONNECTION_ENTRY aep_app_conn_table[MAX_PROCESS_CONNECTIONS];
+
+/*Used to determine if this is a new process*/
+static pid_t    recorded_pid = 0;
+
+#ifdef AEPRAND
+static AEP_U8   rand_block[RAND_BLK_SIZE];
+static AEP_U32  rand_block_bytes = 0;
+#endif
+
+/* Constants used when creating the ENGINE */
+static const char *engine_aep_id = "aep";
+static const char *engine_aep_name = "Aep hardware engine support";
+
+static int max_key_len = 2176;
+
+
+/* This internal function is used by ENGINE_aep() and possibly by the
+ * "dynamic" ENGINE support too */
+static int bind_aep(ENGINE *e)
+	{
+#ifndef OPENSSL_NO_RSA
+	const RSA_METHOD  *meth1;
+#endif
+#ifndef OPENSSL_NO_DSA
+	const DSA_METHOD  *meth2;
+#endif
+#ifndef OPENSSL_NO_DH
+	const DH_METHOD	  *meth3;
+#endif
+
+	if(!ENGINE_set_id(e, engine_aep_id) ||
+		!ENGINE_set_name(e, engine_aep_name) ||
+#ifndef OPENSSL_NO_RSA
+		!ENGINE_set_RSA(e, &aep_rsa) ||
+#endif
+#ifndef OPENSSL_NO_DSA
+		!ENGINE_set_DSA(e, &aep_dsa) ||
+#endif
+#ifndef OPENSSL_NO_DH
+		!ENGINE_set_DH(e, &aep_dh) ||
+#endif
+#ifdef AEPRAND
+		!ENGINE_set_RAND(e, &aep_random) ||
+#endif
+		!ENGINE_set_init_function(e, aep_init) ||
+		!ENGINE_set_destroy_function(e, aep_destroy) ||
+		!ENGINE_set_finish_function(e, aep_finish) ||
+		!ENGINE_set_ctrl_function(e, aep_ctrl) ||
+		!ENGINE_set_cmd_defns(e, aep_cmd_defns))
+		return 0;
+
+#ifndef OPENSSL_NO_RSA
+	/* We know that the "PKCS1_SSLeay()" functions hook properly
+	 * to the aep-specific mod_exp and mod_exp_crt so we use
+	 * those functions. NB: We don't use ENGINE_openssl() or
+	 * anything "more generic" because something like the RSAref
+	 * code may not hook properly, and if you own one of these
+	 * cards then you have the right to do RSA operations on it
+	 * anyway! */
+	meth1 = RSA_PKCS1_SSLeay();
+	aep_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+	aep_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+	aep_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+	aep_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+#endif
+
+
+#ifndef OPENSSL_NO_DSA
+	/* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
+	 * bits. */
+	meth2 = DSA_OpenSSL();
+	aep_dsa.dsa_do_sign    = meth2->dsa_do_sign;
+	aep_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
+	aep_dsa.dsa_do_verify  = meth2->dsa_do_verify;
+
+	aep_dsa = *DSA_get_default_method(); 
+	aep_dsa.dsa_mod_exp = aep_dsa_mod_exp; 
+	aep_dsa.bn_mod_exp = aep_mod_exp_dsa;
+#endif
+
+#ifndef OPENSSL_NO_DH
+	/* Much the same for Diffie-Hellman */
+	meth3 = DH_OpenSSL();
+	aep_dh.generate_key = meth3->generate_key;
+	aep_dh.compute_key  = meth3->compute_key;
+	aep_dh.bn_mod_exp   = meth3->bn_mod_exp;
+#endif
+
+	/* Ensure the aep error handling is set up */
+	ERR_load_AEPHK_strings();
+
+	return 1;
+}
+
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_helper(ENGINE *e, const char *id)
+	{
+	if(id && (strcmp(id, engine_aep_id) != 0))
+		return 0;
+	if(!bind_aep(e))
+		return 0;
+	return 1;
+	}       
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
+#else
+static ENGINE *engine_aep(void)
+	{
+	ENGINE *ret = ENGINE_new();
+	if(!ret)
+		return NULL;
+	if(!bind_aep(ret))
+		{
+		ENGINE_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+void ENGINE_load_aep(void)
+	{
+	/* Copied from eng_[openssl|dyn].c */
+	ENGINE *toadd = engine_aep();
+	if(!toadd) return;
+	ENGINE_add(toadd);
+	ENGINE_free(toadd);
+	ERR_clear_error();
+	}
+#endif
+
+/* This is a process-global DSO handle used for loading and unloading
+ * the Aep library. NB: This is only set (or unset) during an
+ * init() or finish() call (reference counts permitting) and they're
+ * operating with global locks, so this should be thread-safe
+ * implicitly. */
+static DSO *aep_dso = NULL;
+
+/* These are the static string constants for the DSO file name and the function
+ * symbol names to bind to. 
+*/
+static const char *AEP_LIBNAME = NULL;
+static const char *get_AEP_LIBNAME(void)
+	{
+	if(AEP_LIBNAME)
+		return AEP_LIBNAME;
+	return "aep";
+	}
+static void free_AEP_LIBNAME(void)
+	{
+	if(AEP_LIBNAME)
+		OPENSSL_free((void*)AEP_LIBNAME);
+	AEP_LIBNAME = NULL;
+	}
+static long set_AEP_LIBNAME(const char *name)
+	{
+	free_AEP_LIBNAME();
+	return ((AEP_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
+	}
+
+static const char *AEP_F1    = "AEP_ModExp";
+static const char *AEP_F2    = "AEP_ModExpCrt";
+#ifdef AEPRAND
+static const char *AEP_F3    = "AEP_GenRandom";
+#endif
+static const char *AEP_F4    = "AEP_Finalize";
+static const char *AEP_F5    = "AEP_Initialize";
+static const char *AEP_F6    = "AEP_OpenConnection";
+static const char *AEP_F7    = "AEP_SetBNCallBacks";
+static const char *AEP_F8    = "AEP_CloseConnection";
+
+/* These are the function pointers that are (un)set when the library has
+ * successfully (un)loaded. */
+static t_AEP_OpenConnection    *p_AEP_OpenConnection  = NULL;
+static t_AEP_CloseConnection   *p_AEP_CloseConnection = NULL;
+static t_AEP_ModExp            *p_AEP_ModExp          = NULL;
+static t_AEP_ModExpCrt         *p_AEP_ModExpCrt       = NULL;
+#ifdef AEPRAND
+static t_AEP_GenRandom         *p_AEP_GenRandom       = NULL;
+#endif
+static t_AEP_Initialize        *p_AEP_Initialize      = NULL;
+static t_AEP_Finalize          *p_AEP_Finalize        = NULL;
+static t_AEP_SetBNCallBacks    *p_AEP_SetBNCallBacks  = NULL;
+
+/* (de)initialisation functions. */
+static int aep_init(ENGINE *e)
+	{
+	t_AEP_ModExp          *p1;
+	t_AEP_ModExpCrt       *p2;
+#ifdef AEPRAND
+	t_AEP_GenRandom       *p3;
+#endif
+	t_AEP_Finalize        *p4;
+	t_AEP_Initialize      *p5;
+	t_AEP_OpenConnection  *p6;
+	t_AEP_SetBNCallBacks  *p7;
+	t_AEP_CloseConnection *p8;
+
+	int to_return = 0;
+ 
+	if(aep_dso != NULL)
+		{
+		AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_ALREADY_LOADED);
+		goto err;
+		}
+	/* Attempt to load libaep.so. */
+
+	aep_dso = DSO_load(NULL, get_AEP_LIBNAME(), NULL, 0);
+  
+	if(aep_dso == NULL)
+		{
+		AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
+		goto err;
+		}
+
+	if(	!(p1 = (t_AEP_ModExp *)     DSO_bind_func( aep_dso,AEP_F1))  ||
+		!(p2 = (t_AEP_ModExpCrt*)   DSO_bind_func( aep_dso,AEP_F2))  ||
+#ifdef AEPRAND
+		!(p3 = (t_AEP_GenRandom*)   DSO_bind_func( aep_dso,AEP_F3))  ||
+#endif
+		!(p4 = (t_AEP_Finalize*)    DSO_bind_func( aep_dso,AEP_F4))  ||
+		!(p5 = (t_AEP_Initialize*)  DSO_bind_func( aep_dso,AEP_F5))  ||
+		!(p6 = (t_AEP_OpenConnection*) DSO_bind_func( aep_dso,AEP_F6))  ||
+		!(p7 = (t_AEP_SetBNCallBacks*) DSO_bind_func( aep_dso,AEP_F7))  ||
+		!(p8 = (t_AEP_CloseConnection*) DSO_bind_func( aep_dso,AEP_F8)))
+		{
+		AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
+		goto err;
+		}
+
+	/* Copy the pointers */
+  
+	p_AEP_ModExp           = p1;
+	p_AEP_ModExpCrt        = p2;
+#ifdef AEPRAND
+	p_AEP_GenRandom        = p3;
+#endif
+	p_AEP_Finalize         = p4;
+	p_AEP_Initialize       = p5;
+	p_AEP_OpenConnection   = p6;
+	p_AEP_SetBNCallBacks   = p7;
+	p_AEP_CloseConnection  = p8;
+ 
+	to_return = 1;
+ 
+	return to_return;
+
+ err: 
+
+	if(aep_dso)
+		DSO_free(aep_dso);
+	aep_dso = NULL;
+		
+	p_AEP_OpenConnection    = NULL;
+	p_AEP_ModExp            = NULL;
+	p_AEP_ModExpCrt         = NULL;
+#ifdef AEPRAND
+	p_AEP_GenRandom         = NULL;
+#endif
+	p_AEP_Initialize        = NULL;
+	p_AEP_Finalize          = NULL;
+	p_AEP_SetBNCallBacks    = NULL;
+	p_AEP_CloseConnection   = NULL;
+
+	return to_return;
+	}
+
+/* Destructor (complements the "ENGINE_aep()" constructor) */
+static int aep_destroy(ENGINE *e)
+	{
+	free_AEP_LIBNAME();
+	ERR_unload_AEPHK_strings();
+	return 1;
+	}
+
+static int aep_finish(ENGINE *e)
+	{
+	int to_return = 0, in_use;
+	AEP_RV rv;
+
+	if(aep_dso == NULL)
+		{
+		AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_NOT_LOADED);
+		goto err;
+		}
+
+	rv = aep_close_all_connections(0, &in_use);
+	if (rv != AEP_R_OK)
+		{
+		AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CLOSE_HANDLES_FAILED);
+		goto err;
+		}
+	if (in_use)
+		{
+		AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CONNECTIONS_IN_USE);
+		goto err;
+		}
+
+	rv = p_AEP_Finalize();
+	if (rv != AEP_R_OK)
+		{
+		AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_FINALIZE_FAILED);
+		goto err;
+		}
+
+	if(!DSO_free(aep_dso))
+		{
+		AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_UNIT_FAILURE);
+		goto err;
+		}
+
+	aep_dso = NULL;
+	p_AEP_CloseConnection   = NULL;
+	p_AEP_OpenConnection    = NULL;
+	p_AEP_ModExp            = NULL;
+	p_AEP_ModExpCrt         = NULL;
+#ifdef AEPRAND
+	p_AEP_GenRandom         = NULL;
+#endif
+	p_AEP_Initialize        = NULL;
+	p_AEP_Finalize          = NULL;
+	p_AEP_SetBNCallBacks    = NULL;
+
+	to_return = 1;
+ err:
+	return to_return;
+	}
+
+static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+	{
+	int initialised = ((aep_dso == NULL) ? 0 : 1);
+	switch(cmd)
+		{
+	case AEP_CMD_SO_PATH:
+		if(p == NULL)
+			{
+			AEPHKerr(AEPHK_F_AEP_CTRL,
+				ERR_R_PASSED_NULL_PARAMETER);
+			return 0;
+			}
+		if(initialised)
+			{
+			AEPHKerr(AEPHK_F_AEP_CTRL,
+				AEPHK_R_ALREADY_LOADED);
+			return 0;
+			}
+		return set_AEP_LIBNAME((const char*)p);
+	default:
+		break;
+		}
+	AEPHKerr(AEPHK_F_AEP_CTRL,AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+	return 0;
+	}
+
+static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx)
+	{
+	int to_return = 0;
+	int 	r_len = 0;
+	AEP_CONNECTION_HNDL hConnection;
+	AEP_RV rv;
+	
+	r_len = BN_num_bits(m);
+
+	/* Perform in software if modulus is too large for hardware. */
+
+	if (r_len > max_key_len){
+		AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+		return BN_mod_exp(r, a, p, m, ctx);
+	} 
+
+	/*Grab a connection from the pool*/
+	rv = aep_get_connection(&hConnection);
+	if (rv != AEP_R_OK)
+		{     
+		AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_GET_HANDLE_FAILED);
+		return BN_mod_exp(r, a, p, m, ctx);
+		}
+
+	/*To the card with the mod exp*/
+	rv = p_AEP_ModExp(hConnection,(void*)a, (void*)p,(void*)m, (void*)r,NULL);
+
+	if (rv !=  AEP_R_OK)
+		{
+		AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_MOD_EXP_FAILED);
+		rv = aep_close_connection(hConnection);
+		return BN_mod_exp(r, a, p, m, ctx);
+		}
+
+	/*Return the connection to the pool*/
+	rv = aep_return_connection(hConnection);
+	if (rv != AEP_R_OK)
+		{
+		AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_RETURN_CONNECTION_FAILED); 
+		goto err;
+		}
+
+	to_return = 1;
+ err:
+	return to_return;
+	}
+	
+#ifndef OPENSSL_NO_RSA
+static AEP_RV aep_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *q, const BIGNUM *dmp1,
+	const BIGNUM *dmq1,const BIGNUM *iqmp, BN_CTX *ctx)
+	{
+	AEP_RV rv = AEP_R_OK;
+	AEP_CONNECTION_HNDL hConnection;
+
+	/*Grab a connection from the pool*/
+	rv = aep_get_connection(&hConnection);
+	if (rv != AEP_R_OK)
+		{
+		AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_GET_HANDLE_FAILED);
+		return FAIL_TO_SW;
+		}
+
+	/*To the card with the mod exp*/
+	rv = p_AEP_ModExpCrt(hConnection,(void*)a, (void*)p, (void*)q, (void*)dmp1,(void*)dmq1,
+		(void*)iqmp,(void*)r,NULL);
+	if (rv != AEP_R_OK)
+		{
+		AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_MOD_EXP_CRT_FAILED);
+		rv = aep_close_connection(hConnection);
+		return FAIL_TO_SW;
+		}
+
+	/*Return the connection to the pool*/
+	rv = aep_return_connection(hConnection);
+	if (rv != AEP_R_OK)
+		{
+		AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_RETURN_CONNECTION_FAILED); 
+		goto err;
+		}
+ 
+ err:
+	return rv;
+	}
+#endif
+	
+
+#ifdef AEPRAND
+static int aep_rand(unsigned char *buf,int len )
+	{
+	AEP_RV rv = AEP_R_OK;
+	AEP_CONNECTION_HNDL hConnection;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+
+	/*Can the request be serviced with what's already in the buffer?*/
+	if (len <= rand_block_bytes)
+		{
+		memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
+		rand_block_bytes -= len;
+		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+		}
+	else
+		/*If not the get another block of random bytes*/
+		{
+		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+
+		rv = aep_get_connection(&hConnection);
+		if (rv !=  AEP_R_OK)
+			{ 
+			AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_HANDLE_FAILED);             
+			goto err_nounlock;
+			}
+
+		if (len > RAND_BLK_SIZE)
+			{
+			rv = p_AEP_GenRandom(hConnection, len, 2, buf, NULL);
+			if (rv !=  AEP_R_OK)
+				{  
+				AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED); 
+				goto err_nounlock;
+				}
+			}
+		else
+			{
+			CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+
+			rv = p_AEP_GenRandom(hConnection, RAND_BLK_SIZE, 2, &rand_block[0], NULL);
+			if (rv !=  AEP_R_OK)
+				{       
+				AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED); 
+	      
+				goto err;
+				}
+
+			rand_block_bytes = RAND_BLK_SIZE;
+
+			memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
+			rand_block_bytes -= len;
+
+			CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+			}
+
+		rv = aep_return_connection(hConnection);
+		if (rv != AEP_R_OK)
+			{
+			AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED); 
+	  
+			goto err_nounlock;
+			}
+		}
+  
+	return 1;
+ err:
+	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ err_nounlock:
+	return 0;
+	}
+	
+static int aep_rand_status(void)
+{
+	return 1;
+}
+#endif
+
+#ifndef OPENSSL_NO_RSA
+static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+	{
+	int to_return = 0;
+	AEP_RV rv = AEP_R_OK;
+
+	if (!aep_dso)
+		{
+		AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_NOT_LOADED);
+		goto err;
+		}
+
+	/*See if we have all the necessary bits for a crt*/
+	if (rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp)
+		{
+		rv =  aep_mod_exp_crt(r0,I,rsa->p,rsa->q, rsa->dmp1,rsa->dmq1,rsa->iqmp,ctx);
+
+		if (rv == FAIL_TO_SW){
+			const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+			to_return = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
+			goto err;
+		}
+		else if (rv != AEP_R_OK)
+			goto err;
+		}
+	else
+		{
+		if (!rsa->d || !rsa->n)
+			{
+			AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_MISSING_KEY_COMPONENTS);
+			goto err;
+			}
+ 
+		rv = aep_mod_exp(r0,I,rsa->d,rsa->n,ctx);
+		if  (rv != AEP_R_OK)
+			goto err;
+	
+		}
+
+	to_return = 1;
+
+ err:
+	return to_return;
+}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
+	BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
+	BN_CTX *ctx, BN_MONT_CTX *in_mont)
+	{
+	BIGNUM t;
+	int to_return = 0;
+	BN_init(&t);
+
+	/* let rr = a1 ^ p1 mod m */
+	if (!aep_mod_exp(rr,a1,p1,m,ctx)) goto end;
+	/* let t = a2 ^ p2 mod m */
+	if (!aep_mod_exp(&t,a2,p2,m,ctx)) goto end;
+	/* let rr = rr * t mod m */
+	if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
+	to_return = 1;
+ end: 
+	BN_free(&t);
+	return to_return;
+	}
+
+static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+	const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+	BN_MONT_CTX *m_ctx)
+	{  
+	return aep_mod_exp(r, a, p, m, ctx); 
+	}
+#endif
+
+#ifndef OPENSSL_NO_RSA
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+	{
+	return aep_mod_exp(r, a, p, m, ctx);
+	}
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
+	const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+	BN_MONT_CTX *m_ctx)
+	{
+	return aep_mod_exp(r, a, p, m, ctx);
+	}
+#endif
+
+static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection)
+	{
+	int count;
+	AEP_RV rv = AEP_R_OK;
+
+	/*Get the current process id*/
+	pid_t curr_pid;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+
+	curr_pid = getpid();
+
+	/*Check if this is the first time this is being called from the current
+	  process*/
+	if (recorded_pid != curr_pid)
+		{
+		/*Remember our pid so we can check if we're in a new process*/
+		recorded_pid = curr_pid;
+
+		/*Call Finalize to make sure we have not inherited some data
+		  from a parent process*/
+		p_AEP_Finalize();
+     
+		/*Initialise the AEP API*/
+		rv = p_AEP_Initialize(NULL);
+
+		if (rv != AEP_R_OK)
+			{
+			AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_INIT_FAILURE);
+			recorded_pid = 0;
+			goto end;
+			}
+
+		/*Set the AEP big num call back functions*/
+		rv = p_AEP_SetBNCallBacks(&GetBigNumSize, &MakeAEPBigNum,
+			&ConvertAEPBigNum);
+
+		if (rv != AEP_R_OK)
+			{
+			AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_SETBNCALLBACK_FAILURE);
+			recorded_pid = 0;
+			goto end;
+			}
+
+#ifdef AEPRAND
+		/*Reset the rand byte count*/
+		rand_block_bytes = 0;
+#endif
+
+		/*Init the structures*/
+		for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
+			{
+			aep_app_conn_table[count].conn_state = NotConnected;
+			aep_app_conn_table[count].conn_hndl  = 0;
+			}
+
+		/*Open a connection*/
+		rv = p_AEP_OpenConnection(phConnection);
+
+		if (rv != AEP_R_OK)
+			{
+			AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
+			recorded_pid = 0;
+			goto end;
+			}
+
+		aep_app_conn_table[0].conn_state = InUse;
+		aep_app_conn_table[0].conn_hndl = *phConnection;
+		goto end;
+		}
+	/*Check the existing connections to see if we can find a free one*/
+	for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
+		{
+		if (aep_app_conn_table[count].conn_state == Connected)
+			{
+			aep_app_conn_table[count].conn_state = InUse;
+			*phConnection = aep_app_conn_table[count].conn_hndl;
+			goto end;
+			}
+		}
+	/*If no connections available, we're going to have to try
+	  to open a new one*/
+	for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
+		{
+		if (aep_app_conn_table[count].conn_state == NotConnected)
+			{
+			/*Open a connection*/
+			rv = p_AEP_OpenConnection(phConnection);
+
+			if (rv != AEP_R_OK)
+				{	      
+				AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
+				goto end;
+				}
+
+			aep_app_conn_table[count].conn_state = InUse;
+			aep_app_conn_table[count].conn_hndl = *phConnection;
+			goto end;
+			}
+		}
+	rv = AEP_R_GENERAL_ERROR;
+ end:
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	return rv;
+	}
+
+
+static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection)
+	{
+	int count;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+
+	/*Find the connection item that matches this connection handle*/
+	for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
+		{
+		if (aep_app_conn_table[count].conn_hndl == hConnection)
+			{
+			aep_app_conn_table[count].conn_state = Connected;
+			break;
+			}
+		}
+
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+
+	return AEP_R_OK;
+	}
+
+static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection)
+	{
+	int count;
+	AEP_RV rv = AEP_R_OK;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+
+	/*Find the connection item that matches this connection handle*/
+	for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
+		{
+		if (aep_app_conn_table[count].conn_hndl == hConnection)
+			{
+			rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
+			if (rv != AEP_R_OK)
+				goto end;
+			aep_app_conn_table[count].conn_state = NotConnected;
+			aep_app_conn_table[count].conn_hndl  = 0;
+			break;
+			}
+		}
+
+ end:
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	return rv;
+	}
+
+static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use)
+	{
+	int count;
+	AEP_RV rv = AEP_R_OK;
+
+	*in_use = 0;
+	if (use_engine_lock) CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
+		{
+		switch (aep_app_conn_table[count].conn_state)
+			{
+		case Connected:
+			rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
+			if (rv != AEP_R_OK)
+				goto end;
+			aep_app_conn_table[count].conn_state = NotConnected;
+			aep_app_conn_table[count].conn_hndl  = 0;
+			break;
+		case InUse:
+			(*in_use)++;
+			break;
+		case NotConnected:
+			break;
+			}
+		}
+ end:
+	if (use_engine_lock) CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	return rv;
+	}
+
+/*BigNum call back functions, used to convert OpenSSL bignums into AEP bignums.
+  Note only 32bit Openssl build support*/
+
+static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize)
+	{
+	BIGNUM* bn;
+
+	/*Cast the ArbBigNum pointer to our BIGNUM struct*/
+	bn = (BIGNUM*) ArbBigNum;
+
+#ifdef SIXTY_FOUR_BIT_LONG
+	*BigNumSize = bn->top << 3;
+#else
+	/*Size of the bignum in bytes is equal to the bn->top (no of 32 bit
+	  words) multiplies by 4*/
+	*BigNumSize = bn->top << 2;
+#endif
+
+	return AEP_R_OK;
+	}
+
+static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
+	unsigned char* AEP_BigNum)
+	{
+	BIGNUM* bn;
+
+#ifndef SIXTY_FOUR_BIT_LONG
+	unsigned char* buf;
+	int i;
+#endif
+
+	/*Cast the ArbBigNum pointer to our BIGNUM struct*/
+	bn = (BIGNUM*) ArbBigNum;
+
+#ifdef SIXTY_FOUR_BIT_LONG
+  	memcpy(AEP_BigNum, bn->d, BigNumSize);
+#else
+	/*Must copy data into a (monotone) least significant byte first format
+	  performing endian conversion if necessary*/
+	for(i=0;i<bn->top;i++)
+		{
+		buf = (unsigned char*)&bn->d[i];
+
+		*((AEP_U32*)AEP_BigNum) = (AEP_U32)
+			((unsigned) buf[1] << 8 | buf[0]) |
+			((unsigned) buf[3] << 8 | buf[2])  << 16;
+
+		AEP_BigNum += 4;
+		}
+#endif
+
+	return AEP_R_OK;
+	}
+
+/*Turn an AEP Big Num back to a user big num*/
+static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize,
+	unsigned char* AEP_BigNum)
+	{
+	BIGNUM* bn;
+#ifndef SIXTY_FOUR_BIT_LONG
+	int i;
+#endif
+
+	bn = (BIGNUM*)ArbBigNum;
+
+	/*Expand the result bn so that it can hold our big num.
+	  Size is in bits*/
+	bn_expand(bn, (int)(BigNumSize << 3));
+
+#ifdef SIXTY_FOUR_BIT_LONG
+	bn->top = BigNumSize >> 3;
+	
+	if((BigNumSize & 7) != 0)
+		bn->top++;
+
+	memset(bn->d, 0, bn->top << 3);	
+
+	memcpy(bn->d, AEP_BigNum, BigNumSize);
+#else
+	bn->top = BigNumSize >> 2;
+ 
+	for(i=0;i<bn->top;i++)
+		{
+		bn->d[i] = (AEP_U32)
+			((unsigned) AEP_BigNum[3] << 8 | AEP_BigNum[2]) << 16 |
+			((unsigned) AEP_BigNum[1] << 8 | AEP_BigNum[0]);
+		AEP_BigNum += 4;
+		}
+#endif
+
+	return AEP_R_OK;
+}	
+	
+#endif /* !OPENSSL_NO_HW_AEP */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_aep.ec b/openssl/engines/e_aep.ec
new file mode 100644
index 0000000..8eae642
--- /dev/null
+++ b/openssl/engines/e_aep.ec
@@ -0,0 +1 @@
+L AEPHK		e_aep_err.h			e_aep_err.c
diff --git a/openssl/engines/e_aep_err.c b/openssl/engines/e_aep_err.c
new file mode 100644
index 0000000..3f95881
--- /dev/null
+++ b/openssl/engines/e_aep_err.c
@@ -0,0 +1,161 @@
+/* e_aep_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "e_aep_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA AEPHK_str_functs[]=
+	{
+{ERR_FUNC(AEPHK_F_AEP_CTRL),	"AEP_CTRL"},
+{ERR_FUNC(AEPHK_F_AEP_FINISH),	"AEP_FINISH"},
+{ERR_FUNC(AEPHK_F_AEP_GET_CONNECTION),	"AEP_GET_CONNECTION"},
+{ERR_FUNC(AEPHK_F_AEP_INIT),	"AEP_INIT"},
+{ERR_FUNC(AEPHK_F_AEP_MOD_EXP),	"AEP_MOD_EXP"},
+{ERR_FUNC(AEPHK_F_AEP_MOD_EXP_CRT),	"AEP_MOD_EXP_CRT"},
+{ERR_FUNC(AEPHK_F_AEP_RAND),	"AEP_RAND"},
+{ERR_FUNC(AEPHK_F_AEP_RSA_MOD_EXP),	"AEP_RSA_MOD_EXP"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA AEPHK_str_reasons[]=
+	{
+{ERR_REASON(AEPHK_R_ALREADY_LOADED)      ,"already loaded"},
+{ERR_REASON(AEPHK_R_CLOSE_HANDLES_FAILED),"close handles failed"},
+{ERR_REASON(AEPHK_R_CONNECTIONS_IN_USE)  ,"connections in use"},
+{ERR_REASON(AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
+{ERR_REASON(AEPHK_R_FINALIZE_FAILED)     ,"finalize failed"},
+{ERR_REASON(AEPHK_R_GET_HANDLE_FAILED)   ,"get handle failed"},
+{ERR_REASON(AEPHK_R_GET_RANDOM_FAILED)   ,"get random failed"},
+{ERR_REASON(AEPHK_R_INIT_FAILURE)        ,"init failure"},
+{ERR_REASON(AEPHK_R_MISSING_KEY_COMPONENTS),"missing key components"},
+{ERR_REASON(AEPHK_R_MOD_EXP_CRT_FAILED)  ,"mod exp crt failed"},
+{ERR_REASON(AEPHK_R_MOD_EXP_FAILED)      ,"mod exp failed"},
+{ERR_REASON(AEPHK_R_NOT_LOADED)          ,"not loaded"},
+{ERR_REASON(AEPHK_R_OK)                  ,"ok"},
+{ERR_REASON(AEPHK_R_RETURN_CONNECTION_FAILED),"return connection failed"},
+{ERR_REASON(AEPHK_R_SETBNCALLBACK_FAILURE),"setbncallback failure"},
+{ERR_REASON(AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL),"size too large or too small"},
+{ERR_REASON(AEPHK_R_UNIT_FAILURE)        ,"unit failure"},
+{0,NULL}
+	};
+
+#endif
+
+#ifdef AEPHK_LIB_NAME
+static ERR_STRING_DATA AEPHK_lib_name[]=
+        {
+{0	,AEPHK_LIB_NAME},
+{0,NULL}
+	};
+#endif
+
+
+static int AEPHK_lib_error_code=0;
+static int AEPHK_error_init=1;
+
+static void ERR_load_AEPHK_strings(void)
+	{
+	if (AEPHK_lib_error_code == 0)
+		AEPHK_lib_error_code=ERR_get_next_error_library();
+
+	if (AEPHK_error_init)
+		{
+		AEPHK_error_init=0;
+#ifndef OPENSSL_NO_ERR
+		ERR_load_strings(AEPHK_lib_error_code,AEPHK_str_functs);
+		ERR_load_strings(AEPHK_lib_error_code,AEPHK_str_reasons);
+#endif
+
+#ifdef AEPHK_LIB_NAME
+		AEPHK_lib_name->error = ERR_PACK(AEPHK_lib_error_code,0,0);
+		ERR_load_strings(0,AEPHK_lib_name);
+#endif
+		}
+	}
+
+static void ERR_unload_AEPHK_strings(void)
+	{
+	if (AEPHK_error_init == 0)
+		{
+#ifndef OPENSSL_NO_ERR
+		ERR_unload_strings(AEPHK_lib_error_code,AEPHK_str_functs);
+		ERR_unload_strings(AEPHK_lib_error_code,AEPHK_str_reasons);
+#endif
+
+#ifdef AEPHK_LIB_NAME
+		ERR_unload_strings(0,AEPHK_lib_name);
+#endif
+		AEPHK_error_init=1;
+		}
+	}
+
+static void ERR_AEPHK_error(int function, int reason, char *file, int line)
+	{
+	if (AEPHK_lib_error_code == 0)
+		AEPHK_lib_error_code=ERR_get_next_error_library();
+	ERR_PUT_error(AEPHK_lib_error_code,function,reason,file,line);
+	}
diff --git a/openssl/engines/e_aep_err.h b/openssl/engines/e_aep_err.h
new file mode 100644
index 0000000..35b2e74
--- /dev/null
+++ b/openssl/engines/e_aep_err.h
@@ -0,0 +1,105 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_AEPHK_ERR_H
+#define HEADER_AEPHK_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_AEPHK_strings(void);
+static void ERR_unload_AEPHK_strings(void);
+static void ERR_AEPHK_error(int function, int reason, char *file, int line);
+#define AEPHKerr(f,r) ERR_AEPHK_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the AEPHK functions. */
+
+/* Function codes. */
+#define AEPHK_F_AEP_CTRL				 100
+#define AEPHK_F_AEP_FINISH				 101
+#define AEPHK_F_AEP_GET_CONNECTION			 102
+#define AEPHK_F_AEP_INIT				 103
+#define AEPHK_F_AEP_MOD_EXP				 104
+#define AEPHK_F_AEP_MOD_EXP_CRT				 105
+#define AEPHK_F_AEP_RAND				 106
+#define AEPHK_F_AEP_RSA_MOD_EXP				 107
+
+/* Reason codes. */
+#define AEPHK_R_ALREADY_LOADED				 100
+#define AEPHK_R_CLOSE_HANDLES_FAILED			 101
+#define AEPHK_R_CONNECTIONS_IN_USE			 102
+#define AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED		 103
+#define AEPHK_R_FINALIZE_FAILED				 104
+#define AEPHK_R_GET_HANDLE_FAILED			 105
+#define AEPHK_R_GET_RANDOM_FAILED			 106
+#define AEPHK_R_INIT_FAILURE				 107
+#define AEPHK_R_MISSING_KEY_COMPONENTS			 108
+#define AEPHK_R_MOD_EXP_CRT_FAILED			 109
+#define AEPHK_R_MOD_EXP_FAILED				 110
+#define AEPHK_R_NOT_LOADED				 111
+#define AEPHK_R_OK					 112
+#define AEPHK_R_RETURN_CONNECTION_FAILED		 113
+#define AEPHK_R_SETBNCALLBACK_FAILURE			 114
+#define AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL		 116
+#define AEPHK_R_UNIT_FAILURE				 115
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_atalla.c b/openssl/engines/e_atalla.c
new file mode 100644
index 0000000..fabaa86
--- /dev/null
+++ b/openssl/engines/e_atalla.c
@@ -0,0 +1,607 @@
+/* crypto/engine/hw_atalla.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/dso.h>
+#include <openssl/engine.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_ATALLA
+
+#ifdef FLAT_INC
+#include "atalla.h"
+#else
+#include "vendor_defns/atalla.h"
+#endif
+
+#define ATALLA_LIB_NAME "atalla engine"
+#include "e_atalla_err.c"
+
+static int atalla_destroy(ENGINE *e);
+static int atalla_init(ENGINE *e);
+static int atalla_finish(ENGINE *e);
+static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+
+/* BIGNUM stuff */
+static int atalla_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx);
+
+#ifndef OPENSSL_NO_RSA
+/* RSA stuff */
+static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int atalla_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* DSA stuff */
+static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
+		BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
+		BN_CTX *ctx, BN_MONT_CTX *in_mont);
+static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+		BN_MONT_CTX *m_ctx);
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* DH stuff */
+/* This function is alised to mod_exp (with the DH and mont dropped). */
+static int atalla_mod_exp_dh(const DH *dh, BIGNUM *r,
+		const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#endif
+
+/* The definitions for control commands specific to this engine */
+#define ATALLA_CMD_SO_PATH		ENGINE_CMD_BASE
+static const ENGINE_CMD_DEFN atalla_cmd_defns[] = {
+	{ATALLA_CMD_SO_PATH,
+		"SO_PATH",
+		"Specifies the path to the 'atasi' shared library",
+		ENGINE_CMD_FLAG_STRING},
+	{0, NULL, NULL, 0}
+	};
+
+#ifndef OPENSSL_NO_RSA
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD atalla_rsa =
+	{
+	"Atalla RSA method",
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	atalla_rsa_mod_exp,
+	atalla_mod_exp_mont,
+	NULL,
+	NULL,
+	0,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+	};
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* Our internal DSA_METHOD that we provide pointers to */
+static DSA_METHOD atalla_dsa =
+	{
+	"Atalla DSA method",
+	NULL, /* dsa_do_sign */
+	NULL, /* dsa_sign_setup */
+	NULL, /* dsa_do_verify */
+	atalla_dsa_mod_exp, /* dsa_mod_exp */
+	atalla_mod_exp_dsa, /* bn_mod_exp */
+	NULL, /* init */
+	NULL, /* finish */
+	0, /* flags */
+	NULL, /* app_data */
+	NULL, /* dsa_paramgen */
+	NULL /* dsa_keygen */
+	};
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* Our internal DH_METHOD that we provide pointers to */
+static DH_METHOD atalla_dh =
+	{
+	"Atalla DH method",
+	NULL,
+	NULL,
+	atalla_mod_exp_dh,
+	NULL,
+	NULL,
+	0,
+	NULL,
+	NULL
+	};
+#endif
+
+/* Constants used when creating the ENGINE */
+static const char *engine_atalla_id = "atalla";
+static const char *engine_atalla_name = "Atalla hardware engine support";
+
+/* This internal function is used by ENGINE_atalla() and possibly by the
+ * "dynamic" ENGINE support too */
+static int bind_helper(ENGINE *e)
+	{
+#ifndef OPENSSL_NO_RSA
+	const RSA_METHOD *meth1;
+#endif
+#ifndef OPENSSL_NO_DSA
+	const DSA_METHOD *meth2;
+#endif
+#ifndef OPENSSL_NO_DH
+	const DH_METHOD *meth3;
+#endif
+	if(!ENGINE_set_id(e, engine_atalla_id) ||
+			!ENGINE_set_name(e, engine_atalla_name) ||
+#ifndef OPENSSL_NO_RSA
+			!ENGINE_set_RSA(e, &atalla_rsa) ||
+#endif
+#ifndef OPENSSL_NO_DSA
+			!ENGINE_set_DSA(e, &atalla_dsa) ||
+#endif
+#ifndef OPENSSL_NO_DH
+			!ENGINE_set_DH(e, &atalla_dh) ||
+#endif
+			!ENGINE_set_destroy_function(e, atalla_destroy) ||
+			!ENGINE_set_init_function(e, atalla_init) ||
+			!ENGINE_set_finish_function(e, atalla_finish) ||
+			!ENGINE_set_ctrl_function(e, atalla_ctrl) ||
+			!ENGINE_set_cmd_defns(e, atalla_cmd_defns))
+		return 0;
+
+#ifndef OPENSSL_NO_RSA
+	/* We know that the "PKCS1_SSLeay()" functions hook properly
+	 * to the atalla-specific mod_exp and mod_exp_crt so we use
+	 * those functions. NB: We don't use ENGINE_openssl() or
+	 * anything "more generic" because something like the RSAref
+	 * code may not hook properly, and if you own one of these
+	 * cards then you have the right to do RSA operations on it
+	 * anyway! */ 
+	meth1 = RSA_PKCS1_SSLeay();
+	atalla_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+	atalla_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+	atalla_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+	atalla_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+#endif
+
+#ifndef OPENSSL_NO_DSA
+	/* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
+	 * bits. */
+	meth2 = DSA_OpenSSL();
+	atalla_dsa.dsa_do_sign = meth2->dsa_do_sign;
+	atalla_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
+	atalla_dsa.dsa_do_verify = meth2->dsa_do_verify;
+#endif
+
+#ifndef OPENSSL_NO_DH
+	/* Much the same for Diffie-Hellman */
+	meth3 = DH_OpenSSL();
+	atalla_dh.generate_key = meth3->generate_key;
+	atalla_dh.compute_key = meth3->compute_key;
+#endif
+
+	/* Ensure the atalla error handling is set up */
+	ERR_load_ATALLA_strings();
+	return 1;
+	}
+
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+static ENGINE *engine_atalla(void)
+	{
+	ENGINE *ret = ENGINE_new();
+	if(!ret)
+		return NULL;
+	if(!bind_helper(ret))
+		{
+		ENGINE_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+void ENGINE_load_atalla(void)
+	{
+	/* Copied from eng_[openssl|dyn].c */
+	ENGINE *toadd = engine_atalla();
+	if(!toadd) return;
+	ENGINE_add(toadd);
+	ENGINE_free(toadd);
+	ERR_clear_error();
+	}
+#endif
+
+/* This is a process-global DSO handle used for loading and unloading
+ * the Atalla library. NB: This is only set (or unset) during an
+ * init() or finish() call (reference counts permitting) and they're
+ * operating with global locks, so this should be thread-safe
+ * implicitly. */
+static DSO *atalla_dso = NULL;
+
+/* These are the function pointers that are (un)set when the library has
+ * successfully (un)loaded. */
+static tfnASI_GetHardwareConfig *p_Atalla_GetHardwareConfig = NULL;
+static tfnASI_RSAPrivateKeyOpFn *p_Atalla_RSAPrivateKeyOpFn = NULL;
+static tfnASI_GetPerformanceStatistics *p_Atalla_GetPerformanceStatistics = NULL;
+
+/* These are the static string constants for the DSO file name and the function
+ * symbol names to bind to. Regrettably, the DSO name on *nix appears to be
+ * "atasi.so" rather than something more consistent like "libatasi.so". At the
+ * time of writing, I'm not sure what the file name on win32 is but clearly
+ * native name translation is not possible (eg libatasi.so on *nix, and
+ * atasi.dll on win32). For the purposes of testing, I have created a symbollic
+ * link called "libatasi.so" so that we can use native name-translation - a
+ * better solution will be needed. */
+static const char *ATALLA_LIBNAME = NULL;
+static const char *get_ATALLA_LIBNAME(void)
+	{
+		if(ATALLA_LIBNAME)
+			return ATALLA_LIBNAME;
+		return "atasi";
+	}
+static void free_ATALLA_LIBNAME(void)
+	{
+		if(ATALLA_LIBNAME)
+			OPENSSL_free((void*)ATALLA_LIBNAME);
+		ATALLA_LIBNAME = NULL;
+	}
+static long set_ATALLA_LIBNAME(const char *name)
+	{
+	free_ATALLA_LIBNAME();
+	return (((ATALLA_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
+	}
+static const char *ATALLA_F1 = "ASI_GetHardwareConfig";
+static const char *ATALLA_F2 = "ASI_RSAPrivateKeyOpFn";
+static const char *ATALLA_F3 = "ASI_GetPerformanceStatistics";
+
+/* Destructor (complements the "ENGINE_atalla()" constructor) */
+static int atalla_destroy(ENGINE *e)
+	{
+	free_ATALLA_LIBNAME();
+	/* Unload the atalla error strings so any error state including our
+	 * functs or reasons won't lead to a segfault (they simply get displayed
+	 * without corresponding string data because none will be found). */
+	ERR_unload_ATALLA_strings();
+	return 1;
+	}
+
+/* (de)initialisation functions. */
+static int atalla_init(ENGINE *e)
+	{
+	tfnASI_GetHardwareConfig *p1;
+	tfnASI_RSAPrivateKeyOpFn *p2;
+	tfnASI_GetPerformanceStatistics *p3;
+	/* Not sure of the origin of this magic value, but Ben's code had it
+	 * and it seemed to have been working for a few people. :-) */
+	unsigned int config_buf[1024];
+
+	if(atalla_dso != NULL)
+		{
+		ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_ALREADY_LOADED);
+		goto err;
+		}
+	/* Attempt to load libatasi.so/atasi.dll/whatever. Needs to be
+	 * changed unfortunately because the Atalla drivers don't have
+	 * standard library names that can be platform-translated well. */
+	/* TODO: Work out how to actually map to the names the Atalla
+	 * drivers really use - for now a symbollic link needs to be
+	 * created on the host system from libatasi.so to atasi.so on
+	 * unix variants. */
+	atalla_dso = DSO_load(NULL, get_ATALLA_LIBNAME(), NULL, 0);
+	if(atalla_dso == NULL)
+		{
+		ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_NOT_LOADED);
+		goto err;
+		}
+	if(!(p1 = (tfnASI_GetHardwareConfig *)DSO_bind_func(
+				atalla_dso, ATALLA_F1)) ||
+			!(p2 = (tfnASI_RSAPrivateKeyOpFn *)DSO_bind_func(
+				atalla_dso, ATALLA_F2)) ||
+			!(p3 = (tfnASI_GetPerformanceStatistics *)DSO_bind_func(
+				atalla_dso, ATALLA_F3)))
+		{
+		ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_NOT_LOADED);
+		goto err;
+		}
+	/* Copy the pointers */
+	p_Atalla_GetHardwareConfig = p1;
+	p_Atalla_RSAPrivateKeyOpFn = p2;
+	p_Atalla_GetPerformanceStatistics = p3;
+	/* Perform a basic test to see if there's actually any unit
+	 * running. */
+	if(p1(0L, config_buf) != 0)
+		{
+		ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_UNIT_FAILURE);
+		goto err;
+		}
+	/* Everything's fine. */
+	return 1;
+err:
+	if(atalla_dso)
+		DSO_free(atalla_dso);
+	atalla_dso = NULL;
+	p_Atalla_GetHardwareConfig = NULL;
+	p_Atalla_RSAPrivateKeyOpFn = NULL;
+	p_Atalla_GetPerformanceStatistics = NULL;
+	return 0;
+	}
+
+static int atalla_finish(ENGINE *e)
+	{
+	free_ATALLA_LIBNAME();
+	if(atalla_dso == NULL)
+		{
+		ATALLAerr(ATALLA_F_ATALLA_FINISH,ATALLA_R_NOT_LOADED);
+		return 0;
+		}
+	if(!DSO_free(atalla_dso))
+		{
+		ATALLAerr(ATALLA_F_ATALLA_FINISH,ATALLA_R_UNIT_FAILURE);
+		return 0;
+		}
+	atalla_dso = NULL;
+	p_Atalla_GetHardwareConfig = NULL;
+	p_Atalla_RSAPrivateKeyOpFn = NULL;
+	p_Atalla_GetPerformanceStatistics = NULL;
+	return 1;
+	}
+
+static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+	{
+	int initialised = ((atalla_dso == NULL) ? 0 : 1);
+	switch(cmd)
+		{
+	case ATALLA_CMD_SO_PATH:
+		if(p == NULL)
+			{
+			ATALLAerr(ATALLA_F_ATALLA_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+			return 0;
+			}
+		if(initialised)
+			{
+			ATALLAerr(ATALLA_F_ATALLA_CTRL,ATALLA_R_ALREADY_LOADED);
+			return 0;
+			}
+		return set_ATALLA_LIBNAME((const char *)p);
+	default:
+		break;
+		}
+	ATALLAerr(ATALLA_F_ATALLA_CTRL,ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+	return 0;
+	}
+
+static int atalla_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			const BIGNUM *m, BN_CTX *ctx)
+	{
+	/* I need somewhere to store temporary serialised values for
+	 * use with the Atalla API calls. A neat cheat - I'll use
+	 * BIGNUMs from the BN_CTX but access their arrays directly as
+	 * byte arrays <grin>. This way I don't have to clean anything
+	 * up. */
+	BIGNUM *modulus;
+	BIGNUM *exponent;
+	BIGNUM *argument;
+	BIGNUM *result;
+	RSAPrivateKey keydata;
+	int to_return, numbytes;
+
+	modulus = exponent = argument = result = NULL;
+	to_return = 0; /* expect failure */
+
+	if(!atalla_dso)
+		{
+		ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_NOT_LOADED);
+		goto err;
+		}
+	/* Prepare the params */
+	BN_CTX_start(ctx);
+	modulus = BN_CTX_get(ctx);
+	exponent = BN_CTX_get(ctx);
+	argument = BN_CTX_get(ctx);
+	result = BN_CTX_get(ctx);
+	if (!result)
+		{
+		ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_BN_CTX_FULL);
+		goto err;
+		}
+	if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, m->top) ||
+	   !bn_wexpand(argument, m->top) || !bn_wexpand(result, m->top))
+		{
+		ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_BN_EXPAND_FAIL);
+		goto err;
+		}
+	/* Prepare the key-data */
+	memset(&keydata, 0,sizeof keydata);
+	numbytes = BN_num_bytes(m);
+	memset(exponent->d, 0, numbytes);
+	memset(modulus->d, 0, numbytes);
+	BN_bn2bin(p, (unsigned char *)exponent->d + numbytes - BN_num_bytes(p));
+	BN_bn2bin(m, (unsigned char *)modulus->d + numbytes - BN_num_bytes(m));
+	keydata.privateExponent.data = (unsigned char *)exponent->d;
+	keydata.privateExponent.len = numbytes;
+	keydata.modulus.data = (unsigned char *)modulus->d;
+	keydata.modulus.len = numbytes;
+	/* Prepare the argument */
+	memset(argument->d, 0, numbytes);
+	memset(result->d, 0, numbytes);
+	BN_bn2bin(a, (unsigned char *)argument->d + numbytes - BN_num_bytes(a));
+	/* Perform the operation */
+	if(p_Atalla_RSAPrivateKeyOpFn(&keydata, (unsigned char *)result->d,
+			(unsigned char *)argument->d,
+			keydata.modulus.len) != 0)
+		{
+		ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_REQUEST_FAILED);
+		goto err;
+		}
+	/* Convert the response */
+	BN_bin2bn((unsigned char *)result->d, numbytes, r);
+	to_return = 1;
+err:
+	BN_CTX_end(ctx);
+	return to_return;
+	}
+
+#ifndef OPENSSL_NO_RSA
+static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+	{
+	int to_return = 0;
+
+	if(!atalla_dso)
+		{
+		ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP,ATALLA_R_NOT_LOADED);
+		goto err;
+		}
+	if(!rsa->d || !rsa->n)
+		{
+		ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP,ATALLA_R_MISSING_KEY_COMPONENTS);
+		goto err;
+		}
+	to_return = atalla_mod_exp(r0, I, rsa->d, rsa->n, ctx);
+err:
+	return to_return;
+	}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* This code was liberated and adapted from the commented-out code in
+ * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration
+ * (it doesn't have a CRT form for RSA), this function means that an
+ * Atalla system running with a DSA server certificate can handshake
+ * around 5 or 6 times faster/more than an equivalent system running with
+ * RSA. Just check out the "signs" statistics from the RSA and DSA parts
+ * of "openssl speed -engine atalla dsa1024 rsa1024". */
+static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
+		BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
+		BN_CTX *ctx, BN_MONT_CTX *in_mont)
+	{
+	BIGNUM t;
+	int to_return = 0;
+ 
+	BN_init(&t);
+	/* let rr = a1 ^ p1 mod m */
+	if (!atalla_mod_exp(rr,a1,p1,m,ctx)) goto end;
+	/* let t = a2 ^ p2 mod m */
+	if (!atalla_mod_exp(&t,a2,p2,m,ctx)) goto end;
+	/* let rr = rr * t mod m */
+	if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
+	to_return = 1;
+end:
+	BN_free(&t);
+	return to_return;
+	}
+
+static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+		BN_MONT_CTX *m_ctx)
+	{
+	return atalla_mod_exp(r, a, p, m, ctx);
+	}
+#endif
+
+#ifndef OPENSSL_NO_RSA
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int atalla_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+	{
+	return atalla_mod_exp(r, a, p, m, ctx);
+	}
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int atalla_mod_exp_dh(const DH *dh, BIGNUM *r,
+		const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+	{
+	return atalla_mod_exp(r, a, p, m, ctx);
+	}
+#endif
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library. */
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_fn(ENGINE *e, const char *id)
+	{
+	if(id && (strcmp(id, engine_atalla_id) != 0))
+		return 0;
+	if(!bind_helper(e))
+		return 0;
+	return 1;
+	}
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
+
+#endif /* !OPENSSL_NO_HW_ATALLA */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_atalla.ec b/openssl/engines/e_atalla.ec
new file mode 100644
index 0000000..1d735e1
--- /dev/null
+++ b/openssl/engines/e_atalla.ec
@@ -0,0 +1 @@
+L ATALLA	e_atalla_err.h			e_atalla_err.c
diff --git a/openssl/engines/e_atalla_err.c b/openssl/engines/e_atalla_err.c
new file mode 100644
index 0000000..fd3e004
--- /dev/null
+++ b/openssl/engines/e_atalla_err.c
@@ -0,0 +1,149 @@
+/* e_atalla_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "e_atalla_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA ATALLA_str_functs[]=
+	{
+{ERR_FUNC(ATALLA_F_ATALLA_CTRL),	"ATALLA_CTRL"},
+{ERR_FUNC(ATALLA_F_ATALLA_FINISH),	"ATALLA_FINISH"},
+{ERR_FUNC(ATALLA_F_ATALLA_INIT),	"ATALLA_INIT"},
+{ERR_FUNC(ATALLA_F_ATALLA_MOD_EXP),	"ATALLA_MOD_EXP"},
+{ERR_FUNC(ATALLA_F_ATALLA_RSA_MOD_EXP),	"ATALLA_RSA_MOD_EXP"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA ATALLA_str_reasons[]=
+	{
+{ERR_REASON(ATALLA_R_ALREADY_LOADED)     ,"already loaded"},
+{ERR_REASON(ATALLA_R_BN_CTX_FULL)        ,"bn ctx full"},
+{ERR_REASON(ATALLA_R_BN_EXPAND_FAIL)     ,"bn expand fail"},
+{ERR_REASON(ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
+{ERR_REASON(ATALLA_R_MISSING_KEY_COMPONENTS),"missing key components"},
+{ERR_REASON(ATALLA_R_NOT_LOADED)         ,"not loaded"},
+{ERR_REASON(ATALLA_R_REQUEST_FAILED)     ,"request failed"},
+{ERR_REASON(ATALLA_R_UNIT_FAILURE)       ,"unit failure"},
+{0,NULL}
+	};
+
+#endif
+
+#ifdef ATALLA_LIB_NAME
+static ERR_STRING_DATA ATALLA_lib_name[]=
+        {
+{0	,ATALLA_LIB_NAME},
+{0,NULL}
+	};
+#endif
+
+
+static int ATALLA_lib_error_code=0;
+static int ATALLA_error_init=1;
+
+static void ERR_load_ATALLA_strings(void)
+	{
+	if (ATALLA_lib_error_code == 0)
+		ATALLA_lib_error_code=ERR_get_next_error_library();
+
+	if (ATALLA_error_init)
+		{
+		ATALLA_error_init=0;
+#ifndef OPENSSL_NO_ERR
+		ERR_load_strings(ATALLA_lib_error_code,ATALLA_str_functs);
+		ERR_load_strings(ATALLA_lib_error_code,ATALLA_str_reasons);
+#endif
+
+#ifdef ATALLA_LIB_NAME
+		ATALLA_lib_name->error = ERR_PACK(ATALLA_lib_error_code,0,0);
+		ERR_load_strings(0,ATALLA_lib_name);
+#endif
+		}
+	}
+
+static void ERR_unload_ATALLA_strings(void)
+	{
+	if (ATALLA_error_init == 0)
+		{
+#ifndef OPENSSL_NO_ERR
+		ERR_unload_strings(ATALLA_lib_error_code,ATALLA_str_functs);
+		ERR_unload_strings(ATALLA_lib_error_code,ATALLA_str_reasons);
+#endif
+
+#ifdef ATALLA_LIB_NAME
+		ERR_unload_strings(0,ATALLA_lib_name);
+#endif
+		ATALLA_error_init=1;
+		}
+	}
+
+static void ERR_ATALLA_error(int function, int reason, char *file, int line)
+	{
+	if (ATALLA_lib_error_code == 0)
+		ATALLA_lib_error_code=ERR_get_next_error_library();
+	ERR_PUT_error(ATALLA_lib_error_code,function,reason,file,line);
+	}
diff --git a/openssl/engines/e_atalla_err.h b/openssl/engines/e_atalla_err.h
new file mode 100644
index 0000000..36e09bf
--- /dev/null
+++ b/openssl/engines/e_atalla_err.h
@@ -0,0 +1,93 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_ATALLA_ERR_H
+#define HEADER_ATALLA_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_ATALLA_strings(void);
+static void ERR_unload_ATALLA_strings(void);
+static void ERR_ATALLA_error(int function, int reason, char *file, int line);
+#define ATALLAerr(f,r) ERR_ATALLA_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the ATALLA functions. */
+
+/* Function codes. */
+#define ATALLA_F_ATALLA_CTRL				 100
+#define ATALLA_F_ATALLA_FINISH				 101
+#define ATALLA_F_ATALLA_INIT				 102
+#define ATALLA_F_ATALLA_MOD_EXP				 103
+#define ATALLA_F_ATALLA_RSA_MOD_EXP			 104
+
+/* Reason codes. */
+#define ATALLA_R_ALREADY_LOADED				 100
+#define ATALLA_R_BN_CTX_FULL				 101
+#define ATALLA_R_BN_EXPAND_FAIL				 102
+#define ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED		 103
+#define ATALLA_R_MISSING_KEY_COMPONENTS			 104
+#define ATALLA_R_NOT_LOADED				 105
+#define ATALLA_R_REQUEST_FAILED				 106
+#define ATALLA_R_UNIT_FAILURE				 107
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_capi.c b/openssl/engines/e_capi.c
new file mode 100644
index 0000000..24b620f
--- /dev/null
+++ b/openssl/engines/e_capi.c
@@ -0,0 +1,1824 @@
+/* engines/e_capi.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+
+#ifdef OPENSSL_SYS_WIN32
+#ifndef OPENSSL_NO_CAPIENG
+
+#include <openssl/rsa.h>
+
+#include <windows.h>
+
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0400
+#endif
+
+#include <wincrypt.h>
+
+/*
+ * This module uses several "new" interfaces, among which is
+ * CertGetCertificateContextProperty. CERT_KEY_PROV_INFO_PROP_ID is
+ * one of possible values you can pass to function in question. By
+ * checking if it's defined we can see if wincrypt.h and accompanying
+ * crypt32.lib are in shape. The native MingW32 headers up to and
+ * including __W32API_VERSION 3.14 lack of struct DSSPUBKEY and the
+ * defines CERT_STORE_PROV_SYSTEM_A and CERT_STORE_READONLY_FLAG,
+ * so we check for these too and avoid compiling.
+ * Yes, it's rather "weak" test and if compilation fails,
+ * then re-configure with -DOPENSSL_NO_CAPIENG.
+ */
+#if defined(CERT_KEY_PROV_INFO_PROP_ID) && \
+    defined(CERT_STORE_PROV_SYSTEM_A) && \
+    defined(CERT_STORE_READONLY_FLAG)
+# define __COMPILE_CAPIENG
+#endif /* CERT_KEY_PROV_INFO_PROP_ID */
+#endif /* OPENSSL_NO_CAPIENG */
+#endif /* OPENSSL_SYS_WIN32 */
+
+#ifdef __COMPILE_CAPIENG
+
+#undef X509_EXTENSIONS
+#undef X509_CERT_PAIR
+
+/* Definitions which may be missing from earlier version of headers */
+#ifndef CERT_STORE_OPEN_EXISTING_FLAG
+#define CERT_STORE_OPEN_EXISTING_FLAG                   0x00004000
+#endif
+
+#ifndef CERT_STORE_CREATE_NEW_FLAG
+#define CERT_STORE_CREATE_NEW_FLAG                      0x00002000
+#endif
+
+#ifndef CERT_SYSTEM_STORE_CURRENT_USER
+#define CERT_SYSTEM_STORE_CURRENT_USER			0x00010000
+#endif 
+
+#include <openssl/engine.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+
+#include "e_capi_err.h"
+#include "e_capi_err.c"
+
+
+static const char *engine_capi_id = "capi";
+static const char *engine_capi_name = "CryptoAPI ENGINE";
+
+typedef struct CAPI_CTX_st CAPI_CTX;
+typedef struct CAPI_KEY_st CAPI_KEY;
+
+static void capi_addlasterror(void);
+static void capi_adderror(DWORD err);
+
+static void CAPI_trace(CAPI_CTX *ctx, char *format, ...);
+
+static int capi_list_providers(CAPI_CTX *ctx, BIO *out);
+static int capi_list_containers(CAPI_CTX *ctx, BIO *out);
+int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *storename);
+void capi_free_key(CAPI_KEY *key);
+
+static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE hstore);
+
+CAPI_KEY *capi_find_key(CAPI_CTX *ctx, const char *id);
+
+static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data);
+static int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len,
+             unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
+static int capi_rsa_priv_enc(int flen, const unsigned char *from,
+                unsigned char *to, RSA *rsa, int padding);
+static int capi_rsa_priv_dec(int flen, const unsigned char *from,
+                unsigned char *to, RSA *rsa, int padding);
+static int capi_rsa_free(RSA *rsa);
+
+static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
+							DSA *dsa);
+static int capi_dsa_free(DSA *dsa);
+
+static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
+	STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
+	STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data);
+
+static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
+#ifdef OPENSSL_CAPIENG_DIALOG
+static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
+#endif
+
+typedef PCCERT_CONTEXT (WINAPI *CERTDLG)(HCERTSTORE, HWND, LPCWSTR,
+						LPCWSTR, DWORD, DWORD,
+						void *);
+typedef HWND (WINAPI *GETCONSWIN)(void);
+
+/* This structure contains CAPI ENGINE specific data:
+ * it contains various global options and affects how
+ * other functions behave.
+ */
+
+#define CAPI_DBG_TRACE	2
+#define CAPI_DBG_ERROR	1
+
+struct CAPI_CTX_st {
+	int debug_level;
+	char *debug_file;
+	/* Parameters to use for container lookup */
+	DWORD keytype;
+	LPSTR cspname;
+	DWORD csptype;
+	/* Certificate store name to use */
+	LPSTR storename;
+	LPSTR ssl_client_store;
+	/* System store flags */
+	DWORD store_flags;
+
+/* Lookup string meanings in load_private_key */
+/* Substring of subject: uses "storename" */
+#define CAPI_LU_SUBSTR		1
+/* Friendly name: uses storename */
+#define CAPI_LU_FNAME		2
+/* Container name: uses cspname, keytype */
+#define CAPI_LU_CONTNAME	3
+	int lookup_method;
+/* Info to dump with dumpcerts option */
+/* Issuer and serial name strings */
+#define CAPI_DMP_SUMMARY	0x1
+/* Friendly name */
+#define CAPI_DMP_FNAME		0x2
+/* Full X509_print dump */
+#define CAPI_DMP_FULL		0x4
+/* Dump PEM format certificate */
+#define CAPI_DMP_PEM		0x8
+/* Dump pseudo key (if possible) */
+#define CAPI_DMP_PSKEY		0x10
+/* Dump key info (if possible) */
+#define CAPI_DMP_PKEYINFO	0x20
+
+	DWORD dump_flags;
+	int (*client_cert_select)(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
+
+	CERTDLG certselectdlg;
+	GETCONSWIN getconswindow;
+};
+
+
+static CAPI_CTX *capi_ctx_new();
+static void capi_ctx_free(CAPI_CTX *ctx);
+static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int check);
+static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx);
+
+#define CAPI_CMD_LIST_CERTS		ENGINE_CMD_BASE
+#define CAPI_CMD_LOOKUP_CERT		(ENGINE_CMD_BASE + 1)
+#define CAPI_CMD_DEBUG_LEVEL		(ENGINE_CMD_BASE + 2)
+#define CAPI_CMD_DEBUG_FILE		(ENGINE_CMD_BASE + 3)
+#define CAPI_CMD_KEYTYPE		(ENGINE_CMD_BASE + 4)
+#define CAPI_CMD_LIST_CSPS		(ENGINE_CMD_BASE + 5)
+#define CAPI_CMD_SET_CSP_IDX		(ENGINE_CMD_BASE + 6)
+#define CAPI_CMD_SET_CSP_NAME		(ENGINE_CMD_BASE + 7)
+#define CAPI_CMD_SET_CSP_TYPE		(ENGINE_CMD_BASE + 8)
+#define CAPI_CMD_LIST_CONTAINERS	(ENGINE_CMD_BASE + 9)
+#define CAPI_CMD_LIST_OPTIONS		(ENGINE_CMD_BASE + 10)
+#define CAPI_CMD_LOOKUP_METHOD		(ENGINE_CMD_BASE + 11)
+#define CAPI_CMD_STORE_NAME		(ENGINE_CMD_BASE + 12)
+#define CAPI_CMD_STORE_FLAGS		(ENGINE_CMD_BASE + 13)
+
+static const ENGINE_CMD_DEFN capi_cmd_defns[] = {
+	{CAPI_CMD_LIST_CERTS,
+		"list_certs",
+		"List all certificates in store",
+		ENGINE_CMD_FLAG_NO_INPUT},
+	{CAPI_CMD_LOOKUP_CERT,
+		"lookup_cert",
+		"Lookup and output certificates",
+		ENGINE_CMD_FLAG_STRING},
+	{CAPI_CMD_DEBUG_LEVEL,
+		"debug_level",
+		"debug level (1=errors, 2=trace)",
+		ENGINE_CMD_FLAG_NUMERIC},
+	{CAPI_CMD_DEBUG_FILE,
+		"debug_file",
+		"debugging filename)",
+		ENGINE_CMD_FLAG_STRING},
+	{CAPI_CMD_KEYTYPE,
+		"key_type",
+		"Key type: 1=AT_KEYEXCHANGE (default), 2=AT_SIGNATURE",
+		ENGINE_CMD_FLAG_NUMERIC},
+	{CAPI_CMD_LIST_CSPS,
+		"list_csps",
+		"List all CSPs",
+		ENGINE_CMD_FLAG_NO_INPUT},
+	{CAPI_CMD_SET_CSP_IDX,
+		"csp_idx",
+		"Set CSP by index",
+		ENGINE_CMD_FLAG_NUMERIC},
+	{CAPI_CMD_SET_CSP_NAME,
+		"csp_name",
+		"Set CSP name, (default CSP used if not specified)",
+		ENGINE_CMD_FLAG_STRING},
+	{CAPI_CMD_SET_CSP_TYPE,
+		"csp_type",
+		"Set CSP type, (default RSA_PROV_FULL)",
+		ENGINE_CMD_FLAG_NUMERIC},
+	{CAPI_CMD_LIST_CONTAINERS,
+		"list_containers",
+		"list container names",
+		ENGINE_CMD_FLAG_NO_INPUT},
+	{CAPI_CMD_LIST_OPTIONS,
+		"list_options",
+		"Set list options (1=summary,2=friendly name, 4=full printout, 8=PEM output, 16=XXX, "
+		"32=private key info)",
+		ENGINE_CMD_FLAG_NUMERIC},
+	{CAPI_CMD_LOOKUP_METHOD,
+		"lookup_method",
+		"Set key lookup method (1=substring, 2=friendlyname, 3=container name)",
+		ENGINE_CMD_FLAG_NUMERIC},
+	{CAPI_CMD_STORE_NAME,
+		"store_name",
+		"certificate store name, default \"MY\"",
+		ENGINE_CMD_FLAG_STRING},
+	{CAPI_CMD_STORE_FLAGS,
+		"store_flags",
+		"Certificate store flags: 1 = system store",
+		ENGINE_CMD_FLAG_NUMERIC},
+
+	{0, NULL, NULL, 0}
+	};
+
+static int capi_idx = -1;
+static int rsa_capi_idx = -1;
+static int dsa_capi_idx = -1;
+static int cert_capi_idx = -1;
+
+static int capi_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+	{
+	int ret = 1;
+	CAPI_CTX *ctx;
+	BIO *out;
+	if (capi_idx == -1)
+		{
+		CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_ENGINE_NOT_INITIALIZED);
+		return 0;
+		}
+	ctx = ENGINE_get_ex_data(e, capi_idx);
+	out = BIO_new_fp(stdout, BIO_NOCLOSE);
+	switch (cmd)
+		{
+		case CAPI_CMD_LIST_CSPS:
+		ret = capi_list_providers(ctx, out);
+		break;
+
+		case CAPI_CMD_LIST_CERTS:
+		ret = capi_list_certs(ctx, out, NULL);
+		break;
+
+		case CAPI_CMD_LOOKUP_CERT:
+		ret = capi_list_certs(ctx, out, p);
+		break;
+
+		case CAPI_CMD_LIST_CONTAINERS:
+		ret = capi_list_containers(ctx, out);
+		break;
+
+		case CAPI_CMD_STORE_NAME:
+		if (ctx->storename)
+			OPENSSL_free(ctx->storename);
+		ctx->storename = BUF_strdup(p);
+		CAPI_trace(ctx, "Setting store name to %s\n", p);
+		break;
+
+		case CAPI_CMD_STORE_FLAGS:
+		if (i & 1)
+			{
+			ctx->store_flags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
+			ctx->store_flags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
+			}
+		else
+			{
+			ctx->store_flags |= CERT_SYSTEM_STORE_CURRENT_USER;
+			ctx->store_flags &= ~CERT_SYSTEM_STORE_LOCAL_MACHINE;
+			}
+		CAPI_trace(ctx, "Setting flags to %d\n", i);
+		break;
+
+		case CAPI_CMD_DEBUG_LEVEL:
+		ctx->debug_level = (int)i;
+		CAPI_trace(ctx, "Setting debug level to %d\n", ctx->debug_level);
+		break;
+
+		case CAPI_CMD_DEBUG_FILE:
+		ctx->debug_file = BUF_strdup(p);
+		CAPI_trace(ctx, "Setting debug file to %s\n", ctx->debug_file);
+		break;
+
+		case CAPI_CMD_KEYTYPE:
+		ctx->keytype = i;
+		CAPI_trace(ctx, "Setting key type to %d\n", ctx->keytype);
+		break;
+
+		case CAPI_CMD_SET_CSP_IDX:
+		ret = capi_ctx_set_provname_idx(ctx, i);
+		break;
+
+		case CAPI_CMD_LIST_OPTIONS:
+		ctx->dump_flags = i;
+		break;
+
+		case CAPI_CMD_LOOKUP_METHOD:
+		if (i < 1 || i > 3)
+			{
+			CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_INVALID_LOOKUP_METHOD);
+			return 0;
+			}
+		ctx->lookup_method = i;
+		break;
+
+		case CAPI_CMD_SET_CSP_NAME:
+		ret = capi_ctx_set_provname(ctx, p, ctx->csptype, 1);
+		break;
+
+		case CAPI_CMD_SET_CSP_TYPE:
+		ctx->csptype = i;
+		break;
+
+		default:
+		CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_UNKNOWN_COMMAND);
+		ret = 0;
+	}
+
+	BIO_free(out);
+	return ret;
+
+	}
+
+static RSA_METHOD capi_rsa_method =
+	{
+	"CryptoAPI RSA method",
+	0,				/* pub_enc */
+	0,				/* pub_dec */
+	capi_rsa_priv_enc,		/* priv_enc */
+	capi_rsa_priv_dec,		/* priv_dec */
+	0,				/* rsa_mod_exp */
+	0,				/* bn_mod_exp */
+	0,				/* init	*/
+	capi_rsa_free,			/* finish */
+	RSA_FLAG_SIGN_VER, 		/* flags */
+	NULL,				/* app_data */
+	capi_rsa_sign,			/* rsa_sign */
+	0				/* rsa_verify */
+	};
+
+static DSA_METHOD capi_dsa_method =
+	{
+	"CryptoAPI DSA method",
+	capi_dsa_do_sign,		/* dsa_do_sign */
+	0,				/* dsa_sign_setup */
+	0,				/* dsa_do_verify */
+	0,				/* dsa_mod_exp */
+	0,				/* bn_mod_exp */
+	0,				/* init	*/
+	capi_dsa_free,			/* finish */
+	0, 				/* flags */
+	NULL,				/* app_data */
+	0,				/* dsa_paramgen */
+	0				/* dsa_keygen */
+	};
+
+static int capi_init(ENGINE *e)
+	{
+	CAPI_CTX *ctx;
+	const RSA_METHOD *ossl_rsa_meth;
+	const DSA_METHOD *ossl_dsa_meth;
+	capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0);
+	cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0);
+
+	ctx = capi_ctx_new();
+	if (!ctx || (capi_idx < 0))
+		goto memerr;
+
+	ENGINE_set_ex_data(e, capi_idx, ctx);
+	/* Setup RSA_METHOD */
+	rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
+	ossl_rsa_meth = RSA_PKCS1_SSLeay();
+	capi_rsa_method.rsa_pub_enc = ossl_rsa_meth->rsa_pub_enc;
+	capi_rsa_method.rsa_pub_dec = ossl_rsa_meth->rsa_pub_dec;
+	capi_rsa_method.rsa_mod_exp = ossl_rsa_meth->rsa_mod_exp;
+	capi_rsa_method.bn_mod_exp = ossl_rsa_meth->bn_mod_exp;
+
+	/* Setup DSA Method */
+	dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
+	ossl_dsa_meth = DSA_OpenSSL();
+	capi_dsa_method.dsa_do_verify = ossl_dsa_meth->dsa_do_verify;
+	capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp;
+	capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp;
+
+#ifdef OPENSSL_CAPIENG_DIALOG
+	{
+	HMODULE cryptui = LoadLibrary(TEXT("CRYPTUI.DLL"));
+	HMODULE kernel = GetModuleHandle(TEXT("KERNEL32.DLL"));
+	if (cryptui)
+		ctx->certselectdlg = (CERTDLG)GetProcAddress(cryptui, "CryptUIDlgSelectCertificateFromStore");
+	if (kernel)
+		ctx->getconswindow = (GETCONSWIN)GetProcAddress(kernel, "GetConsoleWindow");
+	if (cryptui && !OPENSSL_isservice())
+		ctx->client_cert_select = cert_select_dialog;
+	}
+#endif
+		
+
+	return 1;
+
+	memerr:
+	CAPIerr(CAPI_F_CAPI_INIT, ERR_R_MALLOC_FAILURE);
+	return 0;
+
+	return 1;
+	}
+
+static int capi_destroy(ENGINE *e)
+	{
+	ERR_unload_CAPI_strings();
+	return 1;
+	}
+
+static int capi_finish(ENGINE *e)
+	{
+	CAPI_CTX *ctx;
+	ctx = ENGINE_get_ex_data(e, capi_idx);
+	capi_ctx_free(ctx);
+	ENGINE_set_ex_data(e, capi_idx, NULL);
+	return 1;
+	}
+
+
+/* CryptoAPI key application data. This contains
+ * a handle to the private key container (for sign operations)
+ * and a handle to the key (for decrypt operations).
+ */
+
+struct CAPI_KEY_st
+	{
+	/* Associated certificate context (if any) */
+	PCCERT_CONTEXT pcert;
+	HCRYPTPROV hprov;
+	HCRYPTKEY key;
+	DWORD keyspec;
+	};
+
+static int bind_capi(ENGINE *e)
+	{
+	if (!ENGINE_set_id(e, engine_capi_id)
+		|| !ENGINE_set_name(e, engine_capi_name)
+		|| !ENGINE_set_init_function(e, capi_init)
+		|| !ENGINE_set_finish_function(e, capi_finish)
+		|| !ENGINE_set_destroy_function(e, capi_destroy)
+		|| !ENGINE_set_RSA(e, &capi_rsa_method)
+		|| !ENGINE_set_DSA(e, &capi_dsa_method)
+		|| !ENGINE_set_load_privkey_function(e, capi_load_privkey)
+		|| !ENGINE_set_load_ssl_client_cert_function(e,
+						capi_load_ssl_client_cert)
+		|| !ENGINE_set_cmd_defns(e, capi_cmd_defns)
+		|| !ENGINE_set_ctrl_function(e, capi_ctrl))
+			return 0;
+	ERR_load_CAPI_strings();
+
+	return 1;
+
+	}
+
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_helper(ENGINE *e, const char *id)
+	{
+	if(id && (strcmp(id, engine_capi_id) != 0))
+		return 0;
+	if(!bind_capi(e))
+		return 0;
+	return 1;
+	}       
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
+#else
+static ENGINE *engine_capi(void)
+	{
+	ENGINE *ret = ENGINE_new();
+	if(!ret)
+		return NULL;
+	if(!bind_capi(ret))
+		{
+		ENGINE_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+void ENGINE_load_capi(void)
+	{
+	/* Copied from eng_[openssl|dyn].c */
+	ENGINE *toadd = engine_capi();
+	if(!toadd) return;
+	ENGINE_add(toadd);
+	ENGINE_free(toadd);
+	ERR_clear_error();
+	}
+#endif
+
+
+static int lend_tobn(BIGNUM *bn, unsigned char *bin, int binlen)
+	{
+	int i;
+	/* Reverse buffer in place: since this is a keyblob structure
+	 * that will be freed up after conversion anyway it doesn't 
+	 * matter if we change it.
+	 */
+	for(i = 0; i < binlen / 2; i++)
+		{
+		unsigned char c;
+		c = bin[i];
+		bin[i] = bin[binlen - i - 1];
+		bin[binlen - i - 1] = c;
+		}
+
+	if (!BN_bin2bn(bin, binlen, bn))
+		return 0;
+	return 1;
+	}
+
+/* Given a CAPI_KEY get an EVP_PKEY structure */
+
+static EVP_PKEY *capi_get_pkey(ENGINE *eng, CAPI_KEY *key)
+	{
+	unsigned char *pubkey = NULL;
+	DWORD len;
+	BLOBHEADER *bh;
+	RSA *rkey = NULL;
+	DSA *dkey = NULL;
+	EVP_PKEY *ret = NULL;
+	if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, NULL, &len))
+		{
+		CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR);
+		capi_addlasterror();
+		return NULL;
+		}
+
+	pubkey = OPENSSL_malloc(len);
+
+	if (!pubkey)
+		goto memerr;
+
+	if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, pubkey, &len))
+		{
+		CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_ERROR);
+		capi_addlasterror();
+		goto err;
+		}
+
+	bh = (BLOBHEADER *)pubkey;
+	if (bh->bType != PUBLICKEYBLOB)
+		{
+		CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB);
+		goto err;
+		}
+	if (bh->aiKeyAlg == CALG_RSA_SIGN || bh->aiKeyAlg == CALG_RSA_KEYX)
+		{
+		RSAPUBKEY *rp;
+		DWORD rsa_modlen;
+		unsigned char *rsa_modulus;
+		rp = (RSAPUBKEY *)(bh + 1);
+		if (rp->magic != 0x31415352)
+			{
+			char magstr[10];
+			BIO_snprintf(magstr, 10, "%lx", rp->magic);
+			CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER);
+			ERR_add_error_data(2, "magic=0x", magstr);
+			goto err;
+			}
+		rsa_modulus = (unsigned char *)(rp + 1);
+		rkey = RSA_new_method(eng);
+		if (!rkey)
+			goto memerr;
+
+		rkey->e = BN_new();
+		rkey->n = BN_new();
+
+		if (!rkey->e || !rkey->n)
+			goto memerr;
+
+		if (!BN_set_word(rkey->e, rp->pubexp))
+			goto memerr;
+
+		rsa_modlen = rp->bitlen / 8;
+		if (!lend_tobn(rkey->n, rsa_modulus, rsa_modlen))
+			goto memerr;
+
+		RSA_set_ex_data(rkey, rsa_capi_idx, key);
+
+		if (!(ret = EVP_PKEY_new()))
+			goto memerr;
+
+		EVP_PKEY_assign_RSA(ret, rkey);
+		rkey = NULL;
+
+		}
+	else if (bh->aiKeyAlg == CALG_DSS_SIGN)
+		{
+		DSSPUBKEY *dp;
+		DWORD dsa_plen;
+		unsigned char *btmp;
+		dp = (DSSPUBKEY *)(bh + 1);
+		if (dp->magic != 0x31535344)
+			{
+			char magstr[10];
+			BIO_snprintf(magstr, 10, "%lx", dp->magic);
+			CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER);
+			ERR_add_error_data(2, "magic=0x", magstr);
+			goto err;
+			}
+		dsa_plen = dp->bitlen / 8;
+		btmp = (unsigned char *)(dp + 1);
+		dkey = DSA_new_method(eng);
+		if (!dkey)
+			goto memerr;
+		dkey->p = BN_new();
+		dkey->q = BN_new();
+		dkey->g = BN_new();
+		dkey->pub_key = BN_new();
+		if (!dkey->p || !dkey->q || !dkey->g || !dkey->pub_key)
+			goto memerr;
+		if (!lend_tobn(dkey->p, btmp, dsa_plen))
+			goto memerr;
+		btmp += dsa_plen;
+		if (!lend_tobn(dkey->q, btmp, 20))
+			goto memerr;
+		btmp += 20;
+		if (!lend_tobn(dkey->g, btmp, dsa_plen))
+			goto memerr;
+		btmp += dsa_plen;
+		if (!lend_tobn(dkey->pub_key, btmp, dsa_plen))
+			goto memerr;
+		btmp += dsa_plen;
+
+		DSA_set_ex_data(dkey, dsa_capi_idx, key);
+
+		if (!(ret = EVP_PKEY_new()))
+			goto memerr;
+
+		EVP_PKEY_assign_DSA(ret, dkey);
+		dkey = NULL;
+		}
+	else
+		{
+		char algstr[10];
+		BIO_snprintf(algstr, 10, "%lx", bh->aiKeyAlg);
+		CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM);
+		ERR_add_error_data(2, "aiKeyAlg=0x", algstr);
+		goto err;
+		}
+
+
+	err:
+	if (pubkey)
+		OPENSSL_free(pubkey);
+	if (!ret)
+		{
+		if (rkey)
+			RSA_free(rkey);
+		if (dkey)
+			DSA_free(dkey);
+		}
+
+	return ret;
+
+memerr:
+	CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_MALLOC_FAILURE);
+	goto err;
+
+	}
+
+static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data)
+	{
+	CAPI_CTX *ctx;
+	CAPI_KEY *key;
+	EVP_PKEY *ret;
+	ctx = ENGINE_get_ex_data(eng, capi_idx);
+
+	if (!ctx)
+		{
+		CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_CANT_FIND_CAPI_CONTEXT);
+		return NULL;
+		}
+
+	key = capi_find_key(ctx, key_id);
+
+	if (!key)
+		return NULL;
+
+	ret = capi_get_pkey(eng, key);
+
+	if (!ret)
+		capi_free_key(key);
+	return ret;
+
+	}
+
+/* CryptoAPI RSA operations */
+
+int capi_rsa_priv_enc(int flen, const unsigned char *from,
+                unsigned char *to, RSA *rsa, int padding)
+	{
+	CAPIerr(CAPI_F_CAPI_RSA_PRIV_ENC, CAPI_R_FUNCTION_NOT_SUPPORTED);
+	return -1;
+	}
+
+int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len,
+             unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
+	{
+	ALG_ID alg;
+	HCRYPTHASH hash;
+	DWORD slen;
+	unsigned int i;
+	int ret = -1;
+	CAPI_KEY *capi_key;
+	CAPI_CTX *ctx;
+
+	ctx = ENGINE_get_ex_data(rsa->engine, capi_idx);
+
+	CAPI_trace(ctx, "Called CAPI_rsa_sign()\n");
+
+	capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
+	if (!capi_key)
+		{
+		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_GET_KEY);
+		return -1;
+		}
+/* Convert the signature type to a CryptoAPI algorithm ID */
+	switch(dtype)
+		{
+	case NID_sha1:
+		alg = CALG_SHA1;
+		break;
+
+	case NID_md5:
+		alg = CALG_MD5;
+		break;
+
+	case NID_md5_sha1:
+		alg = CALG_SSL3_SHAMD5;
+		break;
+	default:
+		{
+		char algstr[10];
+		BIO_snprintf(algstr, 10, "%lx", dtype);
+		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_UNSUPPORTED_ALGORITHM_NID);
+		ERR_add_error_data(2, "NID=0x", algstr);
+		return -1;
+		}
+	}
+
+
+
+/* Create the hash object */
+	if(!CryptCreateHash(capi_key->hprov, alg, 0, 0, &hash))
+		{
+		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
+		capi_addlasterror();
+		return -1;
+		}
+/* Set the hash value to the value passed */
+
+	if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)m, 0))
+		{
+		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
+		capi_addlasterror();
+		goto err;
+		}
+
+
+/* Finally sign it */
+	slen = RSA_size(rsa);
+	if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, sigret, &slen))
+		{
+		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH);
+		capi_addlasterror();
+		goto err;
+		}
+	else
+		{
+		ret = 1;
+		/* Inplace byte reversal of signature */
+		for(i = 0; i < slen / 2; i++)
+			{
+			unsigned char c;
+			c = sigret[i];
+			sigret[i] = sigret[slen - i - 1];
+			sigret[slen - i - 1] = c;
+			}
+		*siglen = slen;
+		}
+
+	/* Now cleanup */
+
+err:
+	CryptDestroyHash(hash);
+
+	return ret;
+	}
+
+int capi_rsa_priv_dec(int flen, const unsigned char *from,
+                unsigned char *to, RSA *rsa, int padding)
+	{
+	int i;
+	unsigned char *tmpbuf;
+	CAPI_KEY *capi_key;
+	CAPI_CTX *ctx;
+	ctx = ENGINE_get_ex_data(rsa->engine, capi_idx);
+
+	CAPI_trace(ctx, "Called capi_rsa_priv_dec()\n");
+
+
+	capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
+	if (!capi_key)
+		{
+		CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_CANT_GET_KEY);
+		return -1;
+		}
+
+	if(padding != RSA_PKCS1_PADDING)
+		{
+		char errstr[10];
+		BIO_snprintf(errstr, 10, "%d", padding);
+		CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_UNSUPPORTED_PADDING);
+		ERR_add_error_data(2, "padding=", errstr);
+		return -1;
+		}
+
+	/* Create temp reverse order version of input */
+	if(!(tmpbuf = OPENSSL_malloc(flen)) ) 
+		{
+		CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, ERR_R_MALLOC_FAILURE);
+		return -1;
+		}
+	for(i = 0; i < flen; i++)
+		tmpbuf[flen - i - 1] = from[i];
+	
+	/* Finally decrypt it */
+	if(!CryptDecrypt(capi_key->key, 0, TRUE, 0, tmpbuf, &flen))
+		{
+		CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_DECRYPT_ERROR);
+		capi_addlasterror();
+		OPENSSL_free(tmpbuf);
+		return -1;
+		} 
+	else memcpy(to, tmpbuf, flen);
+
+	OPENSSL_free(tmpbuf);
+
+	return flen;
+	}
+
+static int capi_rsa_free(RSA *rsa)
+	{
+	CAPI_KEY *capi_key;
+	capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
+	capi_free_key(capi_key);
+	RSA_set_ex_data(rsa, rsa_capi_idx, 0);
+	return 1;
+	}
+
+/* CryptoAPI DSA operations */
+
+static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
+								DSA *dsa)
+	{
+	HCRYPTHASH hash;
+	DWORD slen;
+	DSA_SIG *ret = NULL;
+	CAPI_KEY *capi_key;
+	CAPI_CTX *ctx;
+	unsigned char csigbuf[40];
+
+	ctx = ENGINE_get_ex_data(dsa->engine, capi_idx);
+
+	CAPI_trace(ctx, "Called CAPI_dsa_do_sign()\n");
+
+	capi_key = DSA_get_ex_data(dsa, dsa_capi_idx);
+
+	if (!capi_key)
+		{
+		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_GET_KEY);
+		return NULL;
+		}
+
+	if (dlen != 20)
+		{
+		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_INVALID_DIGEST_LENGTH);
+		return NULL;
+		}
+
+	/* Create the hash object */
+	if(!CryptCreateHash(capi_key->hprov, CALG_SHA1, 0, 0, &hash))
+		{
+		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
+		capi_addlasterror();
+		return NULL;
+		}
+
+	/* Set the hash value to the value passed */
+	if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)digest, 0))
+		{
+		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
+		capi_addlasterror();
+		goto err;
+		}
+
+
+	/* Finally sign it */
+	slen = sizeof(csigbuf);
+	if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen))
+		{
+		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_ERROR_SIGNING_HASH);
+		capi_addlasterror();
+		goto err;
+		}
+	else
+		{
+		ret = DSA_SIG_new();
+		if (!ret)
+			goto err;
+		ret->r = BN_new();
+		ret->s = BN_new();
+		if (!ret->r || !ret->s)
+			goto err;
+		if (!lend_tobn(ret->r, csigbuf, 20)
+			|| !lend_tobn(ret->s, csigbuf + 20, 20))
+			{
+			DSA_SIG_free(ret);
+			ret = NULL;
+			goto err;
+			}
+		}
+
+	/* Now cleanup */
+
+err:
+	OPENSSL_cleanse(csigbuf, 40);
+	CryptDestroyHash(hash);
+	return ret;
+	}
+
+static int capi_dsa_free(DSA *dsa)
+	{
+	CAPI_KEY *capi_key;
+	capi_key = DSA_get_ex_data(dsa, dsa_capi_idx);
+	capi_free_key(capi_key);
+	DSA_set_ex_data(dsa, dsa_capi_idx, 0);
+	return 1;
+	}
+
+static void capi_vtrace(CAPI_CTX *ctx, int level, char *format, va_list argptr)
+	{
+	BIO *out;
+
+	if (!ctx || (ctx->debug_level < level) || (!ctx->debug_file))
+		return;
+	out = BIO_new_file(ctx->debug_file, "a+");
+	BIO_vprintf(out, format, argptr);
+	BIO_free(out);
+	}
+
+static void CAPI_trace(CAPI_CTX *ctx, char *format, ...)
+	{
+	va_list args;
+	va_start(args, format);
+	capi_vtrace(ctx, CAPI_DBG_TRACE, format, args);
+	va_end(args);
+	}
+
+static void capi_addlasterror(void)
+	{
+	capi_adderror(GetLastError());
+	}
+
+static void capi_adderror(DWORD err)
+	{
+	char errstr[10];
+	BIO_snprintf(errstr, 10, "%lX", err);
+	ERR_add_error_data(2, "Error code= 0x", errstr);
+	}
+
+static char *wide_to_asc(LPWSTR wstr)
+	{
+	char *str;
+	int len_0,sz;
+
+	if (!wstr)
+		return NULL;
+	len_0 = (int)wcslen(wstr)+1;	/* WideCharToMultiByte expects int */
+        sz = WideCharToMultiByte(CP_ACP,0,wstr,len_0,NULL,0,NULL,NULL);
+	if (!sz)
+		{
+		CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR);
+		return NULL;
+		}
+	str = OPENSSL_malloc(sz);
+	if (!str)
+		{
+		CAPIerr(CAPI_F_WIDE_TO_ASC, ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+	if (!WideCharToMultiByte(CP_ACP,0,wstr,len_0,str,sz,NULL,NULL))
+		{
+		OPENSSL_free(str);
+		CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR);
+		return NULL;
+		}
+	return str;
+	}
+
+static int capi_get_provname(CAPI_CTX *ctx, LPSTR *pname, DWORD *ptype, DWORD idx)
+	{
+	LPSTR name;
+	DWORD len, err;
+	CAPI_trace(ctx, "capi_get_provname, index=%d\n", idx);
+	if (!CryptEnumProvidersA(idx, NULL, 0, ptype, NULL, &len))
+		{
+		err = GetLastError();
+		if (err == ERROR_NO_MORE_ITEMS)
+			return 2;
+		CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR);
+		capi_adderror(err);
+		return 0;
+		}
+	name = OPENSSL_malloc(len);
+	if (!CryptEnumProvidersA(idx, NULL, 0, ptype, name, &len))
+		{
+		err = GetLastError();
+		if (err == ERROR_NO_MORE_ITEMS)
+			return 2;
+		CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR);
+		capi_adderror(err);
+		return 0;
+		}
+	*pname = name;
+	CAPI_trace(ctx, "capi_get_provname, returned name=%s, type=%d\n", name, *ptype);
+
+	return 1;
+	}
+
+static int capi_list_providers(CAPI_CTX *ctx, BIO *out)
+	{
+	DWORD idx, ptype;
+	int ret;
+	LPSTR provname = NULL;
+	CAPI_trace(ctx, "capi_list_providers\n");
+	BIO_printf(out, "Available CSPs:\n");
+	for(idx = 0; ; idx++)
+		{
+		ret = capi_get_provname(ctx, &provname, &ptype, idx);
+		if (ret == 2)
+			break;
+		if (ret == 0)
+			break;
+		BIO_printf(out, "%d. %s, type %d\n", idx, provname, ptype);
+		OPENSSL_free(provname);
+		}
+	return 1;
+	}
+
+static int capi_list_containers(CAPI_CTX *ctx, BIO *out)
+	{
+	int ret = 1;
+	HCRYPTPROV hprov;
+	DWORD err, idx, flags, buflen = 0, clen;
+	LPSTR cname;
+	CAPI_trace(ctx, "Listing containers CSP=%s, type = %d\n", ctx->cspname, ctx->csptype);
+	if (!CryptAcquireContextA(&hprov, NULL, ctx->cspname, ctx->csptype, CRYPT_VERIFYCONTEXT))
+		{
+		CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
+		capi_addlasterror();
+		return 0;
+		}
+	if (!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, NULL, &buflen, CRYPT_FIRST))
+		{
+		CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
+		capi_addlasterror();
+		return 0;
+		}
+	CAPI_trace(ctx, "Got max container len %d\n", buflen);
+	if (buflen == 0)
+		buflen = 1024;
+	cname = OPENSSL_malloc(buflen);
+	if (!cname)
+		{
+		CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	for (idx = 0;;idx++)
+		{
+		clen = buflen;
+		cname[0] = 0;
+
+		if (idx == 0)
+			flags = CRYPT_FIRST;
+		else
+			flags = 0;
+		if(!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, cname, &clen, flags))
+			{
+			err = GetLastError();
+			if (err == ERROR_NO_MORE_ITEMS)
+				goto done;
+			CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
+			capi_adderror(err);
+			goto err;
+			}
+		CAPI_trace(ctx, "Container name %s, len=%d, index=%d, flags=%d\n", cname, clen, idx, flags);
+		if (!cname[0] && (clen == buflen))
+			{
+			CAPI_trace(ctx, "Enumerate bug: using workaround\n");
+			goto done;
+			}
+		BIO_printf(out, "%d. %s\n", idx, cname);
+		}
+	err:
+
+	ret = 0;
+
+	done:
+	if (cname)
+		OPENSSL_free(cname);
+	CryptReleaseContext(hprov, 0);
+
+	return ret;
+	}
+
+CRYPT_KEY_PROV_INFO *capi_get_prov_info(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
+	{
+	DWORD len;
+	CRYPT_KEY_PROV_INFO *pinfo;
+	
+	if(!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len))
+		return NULL;
+	pinfo = OPENSSL_malloc(len);
+	if (!pinfo)
+		{
+		CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+	if(!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len))
+		{
+		CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO);
+		capi_addlasterror();
+		OPENSSL_free(pinfo);
+		return NULL;
+		}
+	return pinfo;
+	}
+
+static void capi_dump_prov_info(CAPI_CTX *ctx, BIO *out, CRYPT_KEY_PROV_INFO *pinfo)
+	{
+	char *provname = NULL, *contname = NULL;
+	if (!pinfo)
+		{
+		BIO_printf(out, "  No Private Key\n");
+		return;
+		}
+	provname = wide_to_asc(pinfo->pwszProvName);
+	contname = wide_to_asc(pinfo->pwszContainerName);
+	if (!provname || !contname)
+		goto err;
+
+	BIO_printf(out, "  Private Key Info:\n");
+	BIO_printf(out, "    Provider Name:  %s, Provider Type %d\n", provname, pinfo->dwProvType);
+	BIO_printf(out, "    Container Name: %s, Key Type %d\n", contname, pinfo->dwKeySpec);
+	err:
+	if (provname)
+		OPENSSL_free(provname);
+	if (contname)
+		OPENSSL_free(contname);
+	}
+
+char * capi_cert_get_fname(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
+	{
+	LPWSTR wfname;
+	DWORD dlen;
+
+	CAPI_trace(ctx, "capi_cert_get_fname\n");
+	if (!CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dlen))
+		return NULL;
+	wfname = OPENSSL_malloc(dlen);
+	if (CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, wfname, &dlen))
+		{
+		char *fname = wide_to_asc(wfname);
+		OPENSSL_free(wfname);
+		return fname;
+		}
+	CAPIerr(CAPI_F_CAPI_CERT_GET_FNAME, CAPI_R_ERROR_GETTING_FRIENDLY_NAME);
+	capi_addlasterror();
+
+	OPENSSL_free(wfname);
+	return NULL;
+	}
+
+
+void capi_dump_cert(CAPI_CTX *ctx, BIO *out, PCCERT_CONTEXT cert)
+	{
+	X509 *x;
+	unsigned char *p;
+	unsigned long flags = ctx->dump_flags;
+	if (flags & CAPI_DMP_FNAME)
+		{
+		char *fname;
+		fname = capi_cert_get_fname(ctx, cert);
+		if (fname)
+			{
+			BIO_printf(out, "  Friendly Name \"%s\"\n", fname);
+			OPENSSL_free(fname);
+			}
+		else
+			BIO_printf(out, "  <No Friendly Name>\n");
+		}
+
+	p = cert->pbCertEncoded;
+	x = d2i_X509(NULL, &p, cert->cbCertEncoded);
+	if (!x)
+		BIO_printf(out, "  <Can't parse certificate>\n");
+	if (flags & CAPI_DMP_SUMMARY)
+		{
+		BIO_printf(out, "  Subject: ");
+		X509_NAME_print_ex(out, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
+		BIO_printf(out, "\n  Issuer: ");
+		X509_NAME_print_ex(out, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE);
+		BIO_printf(out, "\n");
+		}
+	if (flags & CAPI_DMP_FULL)
+		X509_print_ex(out, x, XN_FLAG_ONELINE,0);
+
+	if (flags & CAPI_DMP_PKEYINFO)
+		{
+		CRYPT_KEY_PROV_INFO *pinfo;
+		pinfo = capi_get_prov_info(ctx, cert);
+		capi_dump_prov_info(ctx, out, pinfo);
+		if (pinfo)
+			OPENSSL_free(pinfo);
+		}
+
+	if (flags & CAPI_DMP_PEM)
+		PEM_write_bio_X509(out, x);
+	X509_free(x);
+	}
+
+HCERTSTORE capi_open_store(CAPI_CTX *ctx, char *storename)
+	{
+	HCERTSTORE hstore;
+
+	if (!storename)
+		storename = ctx->storename;
+	if (!storename)
+		storename = "MY";
+	CAPI_trace(ctx, "Opening certificate store %s\n", storename);
+
+	hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0, 
+				ctx->store_flags, storename);
+	if (!hstore)
+		{
+		CAPIerr(CAPI_F_CAPI_OPEN_STORE, CAPI_R_ERROR_OPENING_STORE);
+		capi_addlasterror();
+		}
+	return hstore;
+	}
+
+int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *id)
+	{
+	char *storename;
+	int idx;
+	int ret = 1;
+	HCERTSTORE hstore;
+	PCCERT_CONTEXT cert = NULL;
+
+	storename = ctx->storename;
+	if (!storename)
+		storename = "MY";
+	CAPI_trace(ctx, "Listing certs for store %s\n", storename);
+
+	hstore = capi_open_store(ctx, storename);
+	if (!hstore)
+		return 0;
+	if (id)
+		{
+		cert = capi_find_cert(ctx, id, hstore);
+		if (!cert)
+			{
+			ret = 0;
+			goto err;
+			}
+		capi_dump_cert(ctx, out, cert);
+		CertFreeCertificateContext(cert);
+		}
+	else
+		{
+		for(idx = 0;;idx++)
+			{
+			LPWSTR fname = NULL;
+			cert = CertEnumCertificatesInStore(hstore, cert);
+			if (!cert)
+				break;
+			BIO_printf(out, "Certificate %d\n", idx);
+			capi_dump_cert(ctx, out, cert);
+			}
+		}
+	err:
+	CertCloseStore(hstore, 0);
+	return ret;
+	}
+
+static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE hstore)
+	{
+	PCCERT_CONTEXT cert = NULL;
+	char *fname = NULL;
+	int match;
+	switch(ctx->lookup_method)
+		{
+		case CAPI_LU_SUBSTR:
+			return CertFindCertificateInStore(hstore,
+					X509_ASN_ENCODING, 0,
+					CERT_FIND_SUBJECT_STR_A, id, NULL);
+		case CAPI_LU_FNAME:
+			for(;;)
+				{
+				cert = CertEnumCertificatesInStore(hstore, cert);
+				if (!cert)
+					return NULL;
+				fname = capi_cert_get_fname(ctx, cert);
+				if (fname)
+					{
+					if (strcmp(fname, id))
+						match = 0;
+					else
+						match = 1;
+					OPENSSL_free(fname);
+					if (match)
+						return cert;
+					}
+				}
+		default:
+			return NULL;
+		}
+	}
+
+static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const char *contname, char *provname, DWORD ptype, DWORD keyspec)
+	{
+	CAPI_KEY *key;
+	key = OPENSSL_malloc(sizeof(CAPI_KEY));
+	CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", 
+						contname, provname, ptype);
+	if (!CryptAcquireContextA(&key->hprov, contname, provname, ptype, 0))
+		{
+		CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
+		capi_addlasterror();
+		goto err;
+		}
+	if (!CryptGetUserKey(key->hprov, keyspec, &key->key))
+		{
+		CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR);
+		capi_addlasterror();
+		CryptReleaseContext(key->hprov, 0);
+		goto err;
+		}
+	key->keyspec = keyspec;
+	key->pcert = NULL;
+	return key;
+
+	err:
+	OPENSSL_free(key);
+	return NULL;
+	}
+
+static CAPI_KEY *capi_get_cert_key(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
+	{
+	CAPI_KEY *key = NULL;
+	CRYPT_KEY_PROV_INFO *pinfo = NULL;
+	char *provname = NULL, *contname = NULL;
+	pinfo = capi_get_prov_info(ctx, cert);
+	if (!pinfo)
+		goto err;
+	provname = wide_to_asc(pinfo->pwszProvName);
+	contname = wide_to_asc(pinfo->pwszContainerName);
+	if (!provname || !contname)
+		goto err;
+	key = capi_get_key(ctx, contname, provname,
+				pinfo->dwProvType, pinfo->dwKeySpec);
+
+	err:
+	if (pinfo)
+		OPENSSL_free(pinfo);
+	if (provname)
+		OPENSSL_free(provname);
+	if (contname)
+		OPENSSL_free(contname);
+	return key;
+	}
+
+CAPI_KEY *capi_find_key(CAPI_CTX *ctx, const char *id)
+	{
+	PCCERT_CONTEXT cert;
+	HCERTSTORE hstore;
+	CAPI_KEY *key = NULL;
+	switch (ctx->lookup_method)
+		{
+		case CAPI_LU_SUBSTR:
+		case CAPI_LU_FNAME:
+		hstore = capi_open_store(ctx, NULL);
+		if (!hstore)
+			return NULL;
+		cert = capi_find_cert(ctx, id, hstore);
+		if (cert)
+			{
+			key = capi_get_cert_key(ctx, cert);
+			CertFreeCertificateContext(cert);
+			}
+		CertCloseStore(hstore, 0);
+		break;
+
+		case CAPI_LU_CONTNAME:
+		key = capi_get_key(ctx, id, ctx->cspname, ctx->csptype,
+							ctx->keytype);
+		break;
+		}
+
+	return key;
+	}
+
+void capi_free_key(CAPI_KEY *key)
+	{
+	if (!key)
+		return;
+	CryptDestroyKey(key->key);
+	CryptReleaseContext(key->hprov, 0);
+	if (key->pcert)
+		CertFreeCertificateContext(key->pcert);
+	OPENSSL_free(key);
+	}
+
+
+/* Initialize a CAPI_CTX structure */
+
+static CAPI_CTX *capi_ctx_new()
+	{
+	CAPI_CTX *ctx;
+	ctx = OPENSSL_malloc(sizeof(CAPI_CTX));
+	if (!ctx)
+		{
+		CAPIerr(CAPI_F_CAPI_CTX_NEW, ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+	ctx->cspname = NULL;
+	ctx->csptype = PROV_RSA_FULL;
+	ctx->dump_flags = CAPI_DMP_SUMMARY|CAPI_DMP_FNAME;
+	ctx->keytype = AT_KEYEXCHANGE;
+	ctx->storename = NULL;
+	ctx->ssl_client_store = NULL;
+	ctx->store_flags = CERT_STORE_OPEN_EXISTING_FLAG |
+				CERT_STORE_READONLY_FLAG |
+				CERT_SYSTEM_STORE_CURRENT_USER;
+	ctx->lookup_method = CAPI_LU_SUBSTR;
+	ctx->debug_level = 0;
+	ctx->debug_file = NULL;
+	ctx->client_cert_select = cert_select_simple;
+	return ctx;
+	}
+
+static void capi_ctx_free(CAPI_CTX *ctx)
+	{
+	CAPI_trace(ctx, "Calling capi_ctx_free with %lx\n", ctx);
+	if (!ctx)
+		return;
+	if (ctx->cspname)
+		OPENSSL_free(ctx->cspname);
+	if (ctx->debug_file)
+		OPENSSL_free(ctx->debug_file);
+	if (ctx->storename)
+		OPENSSL_free(ctx->storename);
+	if (ctx->ssl_client_store)
+		OPENSSL_free(ctx->ssl_client_store);
+	OPENSSL_free(ctx);
+	}
+
+static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int check)
+	{
+	CAPI_trace(ctx, "capi_ctx_set_provname, name=%s, type=%d\n", pname, type);
+	if (check)
+		{
+		HCRYPTPROV hprov;
+		if (!CryptAcquireContextA(&hprov, NULL, pname, type,
+						CRYPT_VERIFYCONTEXT))
+			{
+			CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
+			capi_addlasterror();
+			return 0;
+			}
+		CryptReleaseContext(hprov, 0);
+		}
+	ctx->cspname = BUF_strdup(pname);
+	ctx->csptype = type;
+	return 1;
+	}
+
+static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx)
+	{
+	LPSTR pname;
+	DWORD type;
+	if (capi_get_provname(ctx, &pname, &type, idx) != 1)
+		return 0;
+	return capi_ctx_set_provname(ctx, pname, type, 0);
+	}
+
+static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x)
+	{
+	int i;
+	X509_NAME *nm;
+	/* Special case: empty list: match anything */
+	if (sk_X509_NAME_num(ca_dn) <= 0)
+		return 1;
+	for (i = 0; i < sk_X509_NAME_num(ca_dn); i++)
+		{
+		nm = sk_X509_NAME_value(ca_dn, i);
+		if (!X509_NAME_cmp(nm, X509_get_issuer_name(x)))
+				return 1;
+		}
+	return 0;
+	}
+
+
+
+static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
+	STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
+	STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data)
+	{
+	STACK_OF(X509) *certs = NULL;
+	X509 *x;
+	char *storename;
+	const char *p;
+	int i, client_cert_idx;
+	HCERTSTORE hstore;
+	PCCERT_CONTEXT cert = NULL, excert = NULL;
+	CAPI_CTX *ctx;
+	CAPI_KEY *key;
+	ctx = ENGINE_get_ex_data(e, capi_idx);
+
+	*pcert = NULL;
+	*pkey = NULL;
+
+	storename = ctx->ssl_client_store;
+	if (!storename)
+		storename = "MY";
+
+	hstore = capi_open_store(ctx, storename);
+	if (!hstore)
+		return 0;
+	/* Enumerate all certificates collect any matches */
+	for(i = 0;;i++)
+		{
+		cert = CertEnumCertificatesInStore(hstore, cert);
+		if (!cert)
+			break;
+		p = cert->pbCertEncoded;
+		x = d2i_X509(NULL, &p, cert->cbCertEncoded);
+		if (!x)
+			{
+			CAPI_trace(ctx, "Can't Parse Certificate %d\n", i);
+			continue;
+			}
+		if (cert_issuer_match(ca_dn, x)
+			&& X509_check_purpose(x, X509_PURPOSE_SSL_CLIENT, 0))
+			{
+			key = capi_get_cert_key(ctx, cert);
+			if (!key)
+				{
+				X509_free(x);
+				continue;
+				}
+			/* Match found: attach extra data to it so
+			 * we can retrieve the key later.
+			 */
+			excert = CertDuplicateCertificateContext(cert);
+			key->pcert = excert;
+			X509_set_ex_data(x, cert_capi_idx, key);
+
+			if (!certs)
+				certs = sk_X509_new_null();
+
+			sk_X509_push(certs, x);
+			}
+		else
+			X509_free(x);
+
+		}
+
+	if (cert)
+		CertFreeCertificateContext(cert);
+	if (hstore)
+		CertCloseStore(hstore, 0);
+
+	if (!certs)
+		return 0;
+
+
+	/* Select the appropriate certificate */
+
+	client_cert_idx = ctx->client_cert_select(e, ssl, certs);
+
+	/* Set the selected certificate and free the rest */
+
+	for(i = 0; i < sk_X509_num(certs); i++)
+		{
+		x = sk_X509_value(certs, i);
+		if (i == client_cert_idx)
+			*pcert = x;
+		else
+			{
+			key = X509_get_ex_data(x, cert_capi_idx);
+			capi_free_key(key);
+			X509_free(x);
+			}
+		}
+
+	sk_X509_free(certs);
+
+	if (!*pcert)
+		return 0;
+
+	/* Setup key for selected certificate */
+
+	key = X509_get_ex_data(*pcert, cert_capi_idx);
+	*pkey = capi_get_pkey(e, key);
+	X509_set_ex_data(*pcert, cert_capi_idx, NULL);
+
+	return 1;
+
+	}
+
+
+/* Simple client cert selection function: always select first */
+
+static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
+	{
+	return 0;
+	}
+
+#ifdef OPENSSL_CAPIENG_DIALOG
+
+/* More complex cert selection function, using standard function
+ * CryptUIDlgSelectCertificateFromStore() to produce a dialog box.
+ */
+
+/* Definitions which are in cryptuiapi.h but this is not present in older
+ * versions of headers.
+ */
+
+#ifndef CRYPTUI_SELECT_LOCATION_COLUMN
+#define CRYPTUI_SELECT_LOCATION_COLUMN                   0x000000010
+#define CRYPTUI_SELECT_INTENDEDUSE_COLUMN                0x000000004
+#endif
+
+#define dlg_title L"OpenSSL Application SSL Client Certificate Selection"
+#define dlg_prompt L"Select a certificate to use for authentication"
+#define dlg_columns	 CRYPTUI_SELECT_LOCATION_COLUMN \
+			|CRYPTUI_SELECT_INTENDEDUSE_COLUMN
+
+static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
+	{
+	X509 *x;
+	HCERTSTORE dstore;
+	PCCERT_CONTEXT cert;
+	CAPI_CTX *ctx;
+	CAPI_KEY *key;
+	HWND hwnd;
+	int i, idx = -1;
+	if (sk_X509_num(certs) == 1)
+		return 0;
+	ctx = ENGINE_get_ex_data(e, capi_idx);
+	/* Create an in memory store of certificates */
+	dstore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
+					CERT_STORE_CREATE_NEW_FLAG, NULL);
+	if (!dstore)
+		{
+		CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_CREATING_STORE);
+		capi_addlasterror();
+		goto err;
+		}
+	/* Add all certificates to store */
+	for(i = 0; i < sk_X509_num(certs); i++)
+		{
+		x = sk_X509_value(certs, i);
+		key = X509_get_ex_data(x, cert_capi_idx);
+
+		if (!CertAddCertificateContextToStore(dstore, key->pcert,
+						CERT_STORE_ADD_NEW, NULL))
+			{
+			CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_ADDING_CERT);
+			capi_addlasterror();
+			goto err;
+			}
+
+		}
+	hwnd = GetForegroundWindow();
+	if (!hwnd)
+		hwnd = GetActiveWindow();
+	if (!hwnd && ctx->getconswindow)
+		hwnd = ctx->getconswindow();
+	/* Call dialog to select one */
+	cert = ctx->certselectdlg(dstore, hwnd, dlg_title, dlg_prompt,
+						dlg_columns, 0, NULL);
+
+	/* Find matching cert from list */
+	if (cert)
+		{
+		for(i = 0; i < sk_X509_num(certs); i++)
+			{
+			x = sk_X509_value(certs, i);
+			key = X509_get_ex_data(x, cert_capi_idx);
+			if (CertCompareCertificate(
+				X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+					cert->pCertInfo,
+					key->pcert->pCertInfo))
+				{
+				idx = i;
+				break;
+				}
+			}
+		}
+
+	err:
+	if (dstore)
+		CertCloseStore(dstore, 0);
+	return idx;
+
+	}
+#endif
+
+#else /* !__COMPILE_CAPIENG */
+#include <openssl/engine.h>
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+OPENSSL_EXPORT
+int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
+OPENSSL_EXPORT
+int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
+IMPLEMENT_DYNAMIC_CHECK_FN()
+#else
+void ENGINE_load_capi(void){}
+#endif
+#endif
diff --git a/openssl/engines/e_capi.ec b/openssl/engines/e_capi.ec
new file mode 100644
index 0000000..d2ad668
--- /dev/null
+++ b/openssl/engines/e_capi.ec
@@ -0,0 +1 @@
+L       CAPI    e_capi_err.h e_capi_err.c
diff --git a/openssl/engines/e_capi_err.c b/openssl/engines/e_capi_err.c
new file mode 100644
index 0000000..a1fbd04
--- /dev/null
+++ b/openssl/engines/e_capi_err.c
@@ -0,0 +1,184 @@
+/* e_capi_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2009 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "e_capi_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA CAPI_str_functs[]=
+	{
+{ERR_FUNC(CAPI_F_CAPI_CERT_GET_FNAME),	"CAPI_CERT_GET_FNAME"},
+{ERR_FUNC(CAPI_F_CAPI_CTRL),	"CAPI_CTRL"},
+{ERR_FUNC(CAPI_F_CAPI_CTX_NEW),	"CAPI_CTX_NEW"},
+{ERR_FUNC(CAPI_F_CAPI_CTX_SET_PROVNAME),	"CAPI_CTX_SET_PROVNAME"},
+{ERR_FUNC(CAPI_F_CAPI_DSA_DO_SIGN),	"CAPI_DSA_DO_SIGN"},
+{ERR_FUNC(CAPI_F_CAPI_GET_KEY),	"CAPI_GET_KEY"},
+{ERR_FUNC(CAPI_F_CAPI_GET_PKEY),	"CAPI_GET_PKEY"},
+{ERR_FUNC(CAPI_F_CAPI_GET_PROVNAME),	"CAPI_GET_PROVNAME"},
+{ERR_FUNC(CAPI_F_CAPI_GET_PROV_INFO),	"CAPI_GET_PROV_INFO"},
+{ERR_FUNC(CAPI_F_CAPI_INIT),	"CAPI_INIT"},
+{ERR_FUNC(CAPI_F_CAPI_LIST_CONTAINERS),	"CAPI_LIST_CONTAINERS"},
+{ERR_FUNC(CAPI_F_CAPI_LOAD_PRIVKEY),	"CAPI_LOAD_PRIVKEY"},
+{ERR_FUNC(CAPI_F_CAPI_OPEN_STORE),	"CAPI_OPEN_STORE"},
+{ERR_FUNC(CAPI_F_CAPI_RSA_PRIV_DEC),	"CAPI_RSA_PRIV_DEC"},
+{ERR_FUNC(CAPI_F_CAPI_RSA_PRIV_ENC),	"CAPI_RSA_PRIV_ENC"},
+{ERR_FUNC(CAPI_F_CAPI_RSA_SIGN),	"CAPI_RSA_SIGN"},
+{ERR_FUNC(CAPI_F_CERT_SELECT_DIALOG),	"CERT_SELECT_DIALOG"},
+{ERR_FUNC(CAPI_F_CLIENT_CERT_SELECT),	"CLIENT_CERT_SELECT"},
+{ERR_FUNC(CAPI_F_WIDE_TO_ASC),	"WIDE_TO_ASC"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA CAPI_str_reasons[]=
+	{
+{ERR_REASON(CAPI_R_CANT_CREATE_HASH_OBJECT),"cant create hash object"},
+{ERR_REASON(CAPI_R_CANT_FIND_CAPI_CONTEXT),"cant find capi context"},
+{ERR_REASON(CAPI_R_CANT_GET_KEY)         ,"cant get key"},
+{ERR_REASON(CAPI_R_CANT_SET_HASH_VALUE)  ,"cant set hash value"},
+{ERR_REASON(CAPI_R_CRYPTACQUIRECONTEXT_ERROR),"cryptacquirecontext error"},
+{ERR_REASON(CAPI_R_CRYPTENUMPROVIDERS_ERROR),"cryptenumproviders error"},
+{ERR_REASON(CAPI_R_DECRYPT_ERROR)        ,"decrypt error"},
+{ERR_REASON(CAPI_R_ENGINE_NOT_INITIALIZED),"engine not initialized"},
+{ERR_REASON(CAPI_R_ENUMCONTAINERS_ERROR) ,"enumcontainers error"},
+{ERR_REASON(CAPI_R_ERROR_ADDING_CERT)    ,"error adding cert"},
+{ERR_REASON(CAPI_R_ERROR_CREATING_STORE) ,"error creating store"},
+{ERR_REASON(CAPI_R_ERROR_GETTING_FRIENDLY_NAME),"error getting friendly name"},
+{ERR_REASON(CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO),"error getting key provider info"},
+{ERR_REASON(CAPI_R_ERROR_OPENING_STORE)  ,"error opening store"},
+{ERR_REASON(CAPI_R_ERROR_SIGNING_HASH)   ,"error signing hash"},
+{ERR_REASON(CAPI_R_FUNCTION_NOT_SUPPORTED),"function not supported"},
+{ERR_REASON(CAPI_R_GETUSERKEY_ERROR)     ,"getuserkey error"},
+{ERR_REASON(CAPI_R_INVALID_DIGEST_LENGTH),"invalid digest length"},
+{ERR_REASON(CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER),"invalid dsa public key blob magic number"},
+{ERR_REASON(CAPI_R_INVALID_LOOKUP_METHOD),"invalid lookup method"},
+{ERR_REASON(CAPI_R_INVALID_PUBLIC_KEY_BLOB),"invalid public key blob"},
+{ERR_REASON(CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER),"invalid rsa public key blob magic number"},
+{ERR_REASON(CAPI_R_PUBKEY_EXPORT_ERROR)  ,"pubkey export error"},
+{ERR_REASON(CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR),"pubkey export length error"},
+{ERR_REASON(CAPI_R_UNKNOWN_COMMAND)      ,"unknown command"},
+{ERR_REASON(CAPI_R_UNSUPPORTED_ALGORITHM_NID),"unsupported algorithm nid"},
+{ERR_REASON(CAPI_R_UNSUPPORTED_PADDING)  ,"unsupported padding"},
+{ERR_REASON(CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM),"unsupported public key algorithm"},
+{ERR_REASON(CAPI_R_WIN32_ERROR)          ,"win32 error"},
+{0,NULL}
+	};
+
+#endif
+
+#ifdef CAPI_LIB_NAME
+static ERR_STRING_DATA CAPI_lib_name[]=
+        {
+{0	,CAPI_LIB_NAME},
+{0,NULL}
+	};
+#endif
+
+
+static int CAPI_lib_error_code=0;
+static int CAPI_error_init=1;
+
+static void ERR_load_CAPI_strings(void)
+	{
+	if (CAPI_lib_error_code == 0)
+		CAPI_lib_error_code=ERR_get_next_error_library();
+
+	if (CAPI_error_init)
+		{
+		CAPI_error_init=0;
+#ifndef OPENSSL_NO_ERR
+		ERR_load_strings(CAPI_lib_error_code,CAPI_str_functs);
+		ERR_load_strings(CAPI_lib_error_code,CAPI_str_reasons);
+#endif
+
+#ifdef CAPI_LIB_NAME
+		CAPI_lib_name->error = ERR_PACK(CAPI_lib_error_code,0,0);
+		ERR_load_strings(0,CAPI_lib_name);
+#endif
+		}
+	}
+
+static void ERR_unload_CAPI_strings(void)
+	{
+	if (CAPI_error_init == 0)
+		{
+#ifndef OPENSSL_NO_ERR
+		ERR_unload_strings(CAPI_lib_error_code,CAPI_str_functs);
+		ERR_unload_strings(CAPI_lib_error_code,CAPI_str_reasons);
+#endif
+
+#ifdef CAPI_LIB_NAME
+		ERR_unload_strings(0,CAPI_lib_name);
+#endif
+		CAPI_error_init=1;
+		}
+	}
+
+static void ERR_CAPI_error(int function, int reason, char *file, int line)
+	{
+	if (CAPI_lib_error_code == 0)
+		CAPI_lib_error_code=ERR_get_next_error_library();
+	ERR_PUT_error(CAPI_lib_error_code,function,reason,file,line);
+	}
diff --git a/openssl/engines/e_capi_err.h b/openssl/engines/e_capi_err.h
new file mode 100644
index 0000000..efa7001
--- /dev/null
+++ b/openssl/engines/e_capi_err.h
@@ -0,0 +1,128 @@
+/* ====================================================================
+ * Copyright (c) 2001-2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_CAPI_ERR_H
+#define HEADER_CAPI_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_CAPI_strings(void);
+static void ERR_unload_CAPI_strings(void);
+static void ERR_CAPI_error(int function, int reason, char *file, int line);
+#define CAPIerr(f,r) ERR_CAPI_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the CAPI functions. */
+
+/* Function codes. */
+#define CAPI_F_CAPI_CERT_GET_FNAME			 99
+#define CAPI_F_CAPI_CTRL				 100
+#define CAPI_F_CAPI_CTX_NEW				 101
+#define CAPI_F_CAPI_CTX_SET_PROVNAME			 102
+#define CAPI_F_CAPI_DSA_DO_SIGN				 114
+#define CAPI_F_CAPI_GET_KEY				 103
+#define CAPI_F_CAPI_GET_PKEY				 115
+#define CAPI_F_CAPI_GET_PROVNAME			 104
+#define CAPI_F_CAPI_GET_PROV_INFO			 105
+#define CAPI_F_CAPI_INIT				 106
+#define CAPI_F_CAPI_LIST_CONTAINERS			 107
+#define CAPI_F_CAPI_LOAD_PRIVKEY			 108
+#define CAPI_F_CAPI_OPEN_STORE				 109
+#define CAPI_F_CAPI_RSA_PRIV_DEC			 110
+#define CAPI_F_CAPI_RSA_PRIV_ENC			 111
+#define CAPI_F_CAPI_RSA_SIGN				 112
+#define CAPI_F_CERT_SELECT_DIALOG			 117
+#define CAPI_F_CLIENT_CERT_SELECT			 116
+#define CAPI_F_WIDE_TO_ASC				 113
+
+/* Reason codes. */
+#define CAPI_R_CANT_CREATE_HASH_OBJECT			 99
+#define CAPI_R_CANT_FIND_CAPI_CONTEXT			 100
+#define CAPI_R_CANT_GET_KEY				 101
+#define CAPI_R_CANT_SET_HASH_VALUE			 102
+#define CAPI_R_CRYPTACQUIRECONTEXT_ERROR		 103
+#define CAPI_R_CRYPTENUMPROVIDERS_ERROR			 104
+#define CAPI_R_DECRYPT_ERROR				 105
+#define CAPI_R_ENGINE_NOT_INITIALIZED			 106
+#define CAPI_R_ENUMCONTAINERS_ERROR			 107
+#define CAPI_R_ERROR_ADDING_CERT			 125
+#define CAPI_R_ERROR_CREATING_STORE			 126
+#define CAPI_R_ERROR_GETTING_FRIENDLY_NAME		 108
+#define CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO		 109
+#define CAPI_R_ERROR_OPENING_STORE			 110
+#define CAPI_R_ERROR_SIGNING_HASH			 111
+#define CAPI_R_FUNCTION_NOT_SUPPORTED			 112
+#define CAPI_R_GETUSERKEY_ERROR				 113
+#define CAPI_R_INVALID_DIGEST_LENGTH			 124
+#define CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER	 122
+#define CAPI_R_INVALID_LOOKUP_METHOD			 114
+#define CAPI_R_INVALID_PUBLIC_KEY_BLOB			 115
+#define CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER	 123
+#define CAPI_R_PUBKEY_EXPORT_ERROR			 116
+#define CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR		 117
+#define CAPI_R_UNKNOWN_COMMAND				 118
+#define CAPI_R_UNSUPPORTED_ALGORITHM_NID		 119
+#define CAPI_R_UNSUPPORTED_PADDING			 120
+#define CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM		 121
+#define CAPI_R_WIN32_ERROR				 127
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_chil.c b/openssl/engines/e_chil.c
new file mode 100644
index 0000000..fdc2100
--- /dev/null
+++ b/openssl/engines/e_chil.c
@@ -0,0 +1,1356 @@
+/* crypto/engine/e_chil.c -*- mode: C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org), Geoff Thorpe
+ * (geoff@geoffthorpe.net) and Dr Stephen N Henson (steve@openssl.org)
+ * for the OpenSSL project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/pem.h>
+#include <openssl/dso.h>
+#include <openssl/engine.h>
+#include <openssl/ui.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_CHIL
+
+/* Attribution notice: nCipher have said several times that it's OK for
+ * us to implement a general interface to their boxes, and recently declared
+ * their HWCryptoHook to be public, and therefore available for us to use.
+ * Thanks, nCipher.
+ *
+ * The hwcryptohook.h included here is from May 2000.
+ * [Richard Levitte]
+ */
+#ifdef FLAT_INC
+#include "hwcryptohook.h"
+#else
+#include "vendor_defns/hwcryptohook.h"
+#endif
+
+#define HWCRHK_LIB_NAME "CHIL engine"
+#include "e_chil_err.c"
+
+static int hwcrhk_destroy(ENGINE *e);
+static int hwcrhk_init(ENGINE *e);
+static int hwcrhk_finish(ENGINE *e);
+static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)); 
+
+/* Functions to handle mutexes */
+static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*);
+static int hwcrhk_mutex_lock(HWCryptoHook_Mutex*);
+static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex*);
+static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*);
+
+/* BIGNUM stuff */
+static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx);
+
+#ifndef OPENSSL_NO_RSA
+/* RSA stuff */
+static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+static int hwcrhk_rsa_finish(RSA *rsa);
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* DH stuff */
+/* This function is alised to mod_exp (with the DH and mont dropped). */
+static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
+	const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#endif
+
+/* RAND stuff */
+static int hwcrhk_rand_bytes(unsigned char *buf, int num);
+static int hwcrhk_rand_status(void);
+
+/* KM stuff */
+static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data);
+static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data);
+
+/* Interaction stuff */
+static int hwcrhk_insert_card(const char *prompt_info,
+	const char *wrong_info,
+	HWCryptoHook_PassphraseContext *ppctx,
+	HWCryptoHook_CallerContext *cactx);
+static int hwcrhk_get_pass(const char *prompt_info,
+	int *len_io, char *buf,
+	HWCryptoHook_PassphraseContext *ppctx,
+	HWCryptoHook_CallerContext *cactx);
+static void hwcrhk_log_message(void *logstr, const char *message);
+
+/* The definitions for control commands specific to this engine */
+#define HWCRHK_CMD_SO_PATH		ENGINE_CMD_BASE
+#define HWCRHK_CMD_FORK_CHECK		(ENGINE_CMD_BASE + 1)
+#define HWCRHK_CMD_THREAD_LOCKING	(ENGINE_CMD_BASE + 2)
+#define HWCRHK_CMD_SET_USER_INTERFACE   (ENGINE_CMD_BASE + 3)
+#define HWCRHK_CMD_SET_CALLBACK_DATA    (ENGINE_CMD_BASE + 4)
+static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = {
+	{HWCRHK_CMD_SO_PATH,
+		"SO_PATH",
+		"Specifies the path to the 'hwcrhk' shared library",
+		ENGINE_CMD_FLAG_STRING},
+	{HWCRHK_CMD_FORK_CHECK,
+		"FORK_CHECK",
+		"Turns fork() checking on (non-zero) or off (zero)",
+		ENGINE_CMD_FLAG_NUMERIC},
+	{HWCRHK_CMD_THREAD_LOCKING,
+		"THREAD_LOCKING",
+		"Turns thread-safe locking on (zero) or off (non-zero)",
+		ENGINE_CMD_FLAG_NUMERIC},
+	{HWCRHK_CMD_SET_USER_INTERFACE,
+		"SET_USER_INTERFACE",
+		"Set the global user interface (internal)",
+		ENGINE_CMD_FLAG_INTERNAL},
+	{HWCRHK_CMD_SET_CALLBACK_DATA,
+		"SET_CALLBACK_DATA",
+		"Set the global user interface extra data (internal)",
+		ENGINE_CMD_FLAG_INTERNAL},
+	{0, NULL, NULL, 0}
+	};
+
+#ifndef OPENSSL_NO_RSA
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD hwcrhk_rsa =
+	{
+	"CHIL RSA method",
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	hwcrhk_rsa_mod_exp,
+	hwcrhk_mod_exp_mont,
+	NULL,
+	hwcrhk_rsa_finish,
+	0,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+	};
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* Our internal DH_METHOD that we provide pointers to */
+static DH_METHOD hwcrhk_dh =
+	{
+	"CHIL DH method",
+	NULL,
+	NULL,
+	hwcrhk_mod_exp_dh,
+	NULL,
+	NULL,
+	0,
+	NULL,
+	NULL
+	};
+#endif
+
+static RAND_METHOD hwcrhk_rand =
+	{
+	/* "CHIL RAND method", */
+	NULL,
+	hwcrhk_rand_bytes,
+	NULL,
+	NULL,
+	hwcrhk_rand_bytes,
+	hwcrhk_rand_status,
+	};
+
+/* Constants used when creating the ENGINE */
+static const char *engine_hwcrhk_id = "chil";
+static const char *engine_hwcrhk_name = "CHIL hardware engine support";
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE 
+/* Compatibility hack, the dynamic library uses this form in the path */
+static const char *engine_hwcrhk_id_alt = "ncipher";
+#endif
+
+/* Internal stuff for HWCryptoHook */
+
+/* Some structures needed for proper use of thread locks */
+/* hwcryptohook.h has some typedefs that turn struct HWCryptoHook_MutexValue
+   into HWCryptoHook_Mutex */
+struct HWCryptoHook_MutexValue
+	{
+	int lockid;
+	};
+
+/* hwcryptohook.h has some typedefs that turn
+   struct HWCryptoHook_PassphraseContextValue
+   into HWCryptoHook_PassphraseContext */
+struct HWCryptoHook_PassphraseContextValue
+	{
+        UI_METHOD *ui_method;
+	void *callback_data;
+	};
+
+/* hwcryptohook.h has some typedefs that turn
+   struct HWCryptoHook_CallerContextValue
+   into HWCryptoHook_CallerContext */
+struct HWCryptoHook_CallerContextValue
+	{
+	pem_password_cb *password_callback; /* Deprecated!  Only present for
+                                               backward compatibility! */
+        UI_METHOD *ui_method;
+	void *callback_data;
+	};
+
+/* The MPI structure in HWCryptoHook is pretty compatible with OpenSSL
+   BIGNUM's, so lets define a couple of conversion macros */
+#define BN2MPI(mp, bn) \
+    {mp.size = bn->top * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
+#define MPI2BN(bn, mp) \
+    {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
+
+static BIO *logstream = NULL;
+static int disable_mutex_callbacks = 0;
+
+/* One might wonder why these are needed, since one can pass down at least
+   a UI_METHOD and a pointer to callback data to the key-loading functions.
+   The thing is that the ModExp and RSAImmed functions can load keys as well,
+   if the data they get is in a special, nCipher-defined format (hint: if you
+   look at the private exponent of the RSA data as a string, you'll see this
+   string: "nCipher KM tool key id", followed by some bytes, followed a key
+   identity string, followed by more bytes.  This happens when you use "embed"
+   keys instead of "hwcrhk" keys).  Unfortunately, those functions do not take
+   any passphrase or caller context, and our functions can't really take any
+   callback data either.  Still, the "insert_card" and "get_passphrase"
+   callbacks may be called down the line, and will need to know what user
+   interface callbacks to call, and having callback data from the application
+   may be a nice thing as well, so we need to keep track of that globally. */
+static HWCryptoHook_CallerContext password_context = { NULL, NULL, NULL };
+
+/* Stuff to pass to the HWCryptoHook library */
+static HWCryptoHook_InitInfo hwcrhk_globals = {
+	HWCryptoHook_InitFlags_SimpleForkCheck,	/* Flags */
+	&logstream,		/* logstream */
+	sizeof(BN_ULONG),	/* limbsize */
+	0,			/* mslimb first: false for BNs */
+	-1,			/* msbyte first: use native */
+	0,			/* Max mutexes, 0 = no small limit */
+	0,			/* Max simultaneous, 0 = default */
+
+	/* The next few are mutex stuff: we write wrapper functions
+	   around the OS mutex functions.  We initialise them to 0
+	   here, and change that to actual function pointers in hwcrhk_init()
+	   if dynamic locks are supported (that is, if the application
+	   programmer has made sure of setting up callbacks bafore starting
+	   this engine) *and* if disable_mutex_callbacks hasn't been set by
+	   a call to ENGINE_ctrl(ENGINE_CTRL_CHIL_NO_LOCKING). */
+	sizeof(HWCryptoHook_Mutex),
+	0,
+	0,
+	0,
+	0,
+
+	/* The next few are condvar stuff: we write wrapper functions
+	   round the OS functions.  Currently not implemented and not
+	   and absolute necessity even in threaded programs, therefore
+	   0'ed.  Will hopefully be implemented some day, since it
+	   enhances the efficiency of HWCryptoHook.  */
+	0, /* sizeof(HWCryptoHook_CondVar), */
+	0, /* hwcrhk_cv_init, */
+	0, /* hwcrhk_cv_wait, */
+	0, /* hwcrhk_cv_signal, */
+	0, /* hwcrhk_cv_broadcast, */
+	0, /* hwcrhk_cv_destroy, */
+
+	hwcrhk_get_pass,	/* pass phrase */
+	hwcrhk_insert_card,	/* insert a card */
+	hwcrhk_log_message	/* Log message */
+};
+
+
+/* Now, to our own code */
+
+/* This internal function is used by ENGINE_chil() and possibly by the
+ * "dynamic" ENGINE support too */
+static int bind_helper(ENGINE *e)
+	{
+#ifndef OPENSSL_NO_RSA
+	const RSA_METHOD *meth1;
+#endif
+#ifndef OPENSSL_NO_DH
+	const DH_METHOD *meth2;
+#endif
+	if(!ENGINE_set_id(e, engine_hwcrhk_id) ||
+			!ENGINE_set_name(e, engine_hwcrhk_name) ||
+#ifndef OPENSSL_NO_RSA
+			!ENGINE_set_RSA(e, &hwcrhk_rsa) ||
+#endif
+#ifndef OPENSSL_NO_DH
+			!ENGINE_set_DH(e, &hwcrhk_dh) ||
+#endif
+			!ENGINE_set_RAND(e, &hwcrhk_rand) ||
+			!ENGINE_set_destroy_function(e, hwcrhk_destroy) ||
+			!ENGINE_set_init_function(e, hwcrhk_init) ||
+			!ENGINE_set_finish_function(e, hwcrhk_finish) ||
+			!ENGINE_set_ctrl_function(e, hwcrhk_ctrl) ||
+			!ENGINE_set_load_privkey_function(e, hwcrhk_load_privkey) ||
+			!ENGINE_set_load_pubkey_function(e, hwcrhk_load_pubkey) ||
+			!ENGINE_set_cmd_defns(e, hwcrhk_cmd_defns))
+		return 0;
+
+#ifndef OPENSSL_NO_RSA
+	/* We know that the "PKCS1_SSLeay()" functions hook properly
+	 * to the cswift-specific mod_exp and mod_exp_crt so we use
+	 * those functions. NB: We don't use ENGINE_openssl() or
+	 * anything "more generic" because something like the RSAref
+	 * code may not hook properly, and if you own one of these
+	 * cards then you have the right to do RSA operations on it
+	 * anyway! */ 
+	meth1 = RSA_PKCS1_SSLeay();
+	hwcrhk_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+	hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+	hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+	hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+#endif
+
+#ifndef OPENSSL_NO_DH
+	/* Much the same for Diffie-Hellman */
+	meth2 = DH_OpenSSL();
+	hwcrhk_dh.generate_key = meth2->generate_key;
+	hwcrhk_dh.compute_key = meth2->compute_key;
+#endif
+
+	/* Ensure the hwcrhk error handling is set up */
+	ERR_load_HWCRHK_strings();
+	return 1;
+	}
+
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+static ENGINE *engine_chil(void)
+	{
+	ENGINE *ret = ENGINE_new();
+	if(!ret)
+		return NULL;
+	if(!bind_helper(ret))
+		{
+		ENGINE_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+void ENGINE_load_chil(void)
+	{
+	/* Copied from eng_[openssl|dyn].c */
+	ENGINE *toadd = engine_chil();
+	if(!toadd) return;
+	ENGINE_add(toadd);
+	ENGINE_free(toadd);
+	ERR_clear_error();
+	}
+#endif
+
+/* This is a process-global DSO handle used for loading and unloading
+ * the HWCryptoHook library. NB: This is only set (or unset) during an
+ * init() or finish() call (reference counts permitting) and they're
+ * operating with global locks, so this should be thread-safe
+ * implicitly. */
+static DSO *hwcrhk_dso = NULL;
+static HWCryptoHook_ContextHandle hwcrhk_context = 0;
+#ifndef OPENSSL_NO_RSA
+static int hndidx_rsa = -1;    /* Index for KM handle.  Not really used yet. */
+#endif
+
+/* These are the function pointers that are (un)set when the library has
+ * successfully (un)loaded. */
+static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL;
+static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL;
+static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL;
+#ifndef OPENSSL_NO_RSA
+static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL;
+#endif
+static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL;
+#ifndef OPENSSL_NO_RSA
+static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL;
+static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL;
+static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL;
+#endif
+static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL;
+
+/* Used in the DSO operations. */
+static const char *HWCRHK_LIBNAME = NULL;
+static void free_HWCRHK_LIBNAME(void)
+	{
+	if(HWCRHK_LIBNAME)
+		OPENSSL_free((void*)HWCRHK_LIBNAME);
+	HWCRHK_LIBNAME = NULL;
+	}
+static const char *get_HWCRHK_LIBNAME(void)
+	{
+	if(HWCRHK_LIBNAME)
+		return HWCRHK_LIBNAME;
+	return "nfhwcrhk";
+	}
+static long set_HWCRHK_LIBNAME(const char *name)
+	{
+	free_HWCRHK_LIBNAME();
+	return (((HWCRHK_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
+	}
+static const char *n_hwcrhk_Init = "HWCryptoHook_Init";
+static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish";
+static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp";
+#ifndef OPENSSL_NO_RSA
+static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA";
+#endif
+static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes";
+#ifndef OPENSSL_NO_RSA
+static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey";
+static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey";
+static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey";
+#endif
+static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT";
+
+/* HWCryptoHook library functions and mechanics - these are used by the
+ * higher-level functions further down. NB: As and where there's no
+ * error checking, take a look lower down where these functions are
+ * called, the checking and error handling is probably down there. */
+
+/* utility function to obtain a context */
+static int get_context(HWCryptoHook_ContextHandle *hac,
+        HWCryptoHook_CallerContext *cac)
+	{
+	char tempbuf[1024];
+	HWCryptoHook_ErrMsgBuf rmsg;
+
+	rmsg.buf = tempbuf;
+	rmsg.size = sizeof(tempbuf);
+
+        *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg,
+		cac);
+	if (!*hac)
+                return 0;
+        return 1;
+	}
+ 
+/* similarly to release one. */
+static void release_context(HWCryptoHook_ContextHandle hac)
+	{
+	p_hwcrhk_Finish(hac);
+	}
+
+/* Destructor (complements the "ENGINE_chil()" constructor) */
+static int hwcrhk_destroy(ENGINE *e)
+	{
+	free_HWCRHK_LIBNAME();
+	ERR_unload_HWCRHK_strings();
+	return 1;
+	}
+
+/* (de)initialisation functions. */
+static int hwcrhk_init(ENGINE *e)
+	{
+	HWCryptoHook_Init_t *p1;
+	HWCryptoHook_Finish_t *p2;
+	HWCryptoHook_ModExp_t *p3;
+#ifndef OPENSSL_NO_RSA
+	HWCryptoHook_RSA_t *p4;
+	HWCryptoHook_RSALoadKey_t *p5;
+	HWCryptoHook_RSAGetPublicKey_t *p6;
+	HWCryptoHook_RSAUnloadKey_t *p7;
+#endif
+	HWCryptoHook_RandomBytes_t *p8;
+	HWCryptoHook_ModExpCRT_t *p9;
+
+	if(hwcrhk_dso != NULL)
+		{
+		HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_ALREADY_LOADED);
+		goto err;
+		}
+	/* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */
+	hwcrhk_dso = DSO_load(NULL, get_HWCRHK_LIBNAME(), NULL, 0);
+	if(hwcrhk_dso == NULL)
+		{
+		HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE);
+		goto err;
+		}
+	if(!(p1 = (HWCryptoHook_Init_t *)
+			DSO_bind_func(hwcrhk_dso, n_hwcrhk_Init)) ||
+		!(p2 = (HWCryptoHook_Finish_t *)
+			DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) ||
+		!(p3 = (HWCryptoHook_ModExp_t *)
+			DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) ||
+#ifndef OPENSSL_NO_RSA
+		!(p4 = (HWCryptoHook_RSA_t *)
+			DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) ||
+		!(p5 = (HWCryptoHook_RSALoadKey_t *)
+			DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSALoadKey)) ||
+		!(p6 = (HWCryptoHook_RSAGetPublicKey_t *)
+			DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) ||
+		!(p7 = (HWCryptoHook_RSAUnloadKey_t *)
+			DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) ||
+#endif
+		!(p8 = (HWCryptoHook_RandomBytes_t *)
+			DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) ||
+		!(p9 = (HWCryptoHook_ModExpCRT_t *)
+			DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT)))
+		{
+		HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE);
+		goto err;
+		}
+	/* Copy the pointers */
+	p_hwcrhk_Init = p1;
+	p_hwcrhk_Finish = p2;
+	p_hwcrhk_ModExp = p3;
+#ifndef OPENSSL_NO_RSA
+	p_hwcrhk_RSA = p4;
+	p_hwcrhk_RSALoadKey = p5;
+	p_hwcrhk_RSAGetPublicKey = p6;
+	p_hwcrhk_RSAUnloadKey = p7;
+#endif
+	p_hwcrhk_RandomBytes = p8;
+	p_hwcrhk_ModExpCRT = p9;
+
+	/* Check if the application decided to support dynamic locks,
+	   and if it does, use them. */
+	if (disable_mutex_callbacks == 0)
+		{
+		if (CRYPTO_get_dynlock_create_callback() != NULL &&
+			CRYPTO_get_dynlock_lock_callback() != NULL &&
+			CRYPTO_get_dynlock_destroy_callback() != NULL)
+			{
+			hwcrhk_globals.mutex_init = hwcrhk_mutex_init;
+			hwcrhk_globals.mutex_acquire = hwcrhk_mutex_lock;
+			hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock;
+			hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy;
+			}
+		}
+
+	/* Try and get a context - if not, we may have a DSO but no
+	 * accelerator! */
+	if(!get_context(&hwcrhk_context, &password_context))
+		{
+		HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_UNIT_FAILURE);
+		goto err;
+		}
+	/* Everything's fine. */
+#ifndef OPENSSL_NO_RSA
+	if (hndidx_rsa == -1)
+		hndidx_rsa = RSA_get_ex_new_index(0,
+			"nFast HWCryptoHook RSA key handle",
+			NULL, NULL, NULL);
+#endif
+	return 1;
+err:
+	if(hwcrhk_dso)
+		DSO_free(hwcrhk_dso);
+	hwcrhk_dso = NULL;
+	p_hwcrhk_Init = NULL;
+	p_hwcrhk_Finish = NULL;
+	p_hwcrhk_ModExp = NULL;
+#ifndef OPENSSL_NO_RSA
+	p_hwcrhk_RSA = NULL;
+	p_hwcrhk_RSALoadKey = NULL;
+	p_hwcrhk_RSAGetPublicKey = NULL;
+	p_hwcrhk_RSAUnloadKey = NULL;
+#endif
+	p_hwcrhk_ModExpCRT = NULL;
+	p_hwcrhk_RandomBytes = NULL;
+	return 0;
+	}
+
+static int hwcrhk_finish(ENGINE *e)
+	{
+	int to_return = 1;
+	free_HWCRHK_LIBNAME();
+	if(hwcrhk_dso == NULL)
+		{
+		HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_NOT_LOADED);
+		to_return = 0;
+		goto err;
+		}
+	release_context(hwcrhk_context);
+	if(!DSO_free(hwcrhk_dso))
+		{
+		HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_DSO_FAILURE);
+		to_return = 0;
+		goto err;
+		}
+ err:
+	if (logstream)
+		BIO_free(logstream);
+	hwcrhk_dso = NULL;
+	p_hwcrhk_Init = NULL;
+	p_hwcrhk_Finish = NULL;
+	p_hwcrhk_ModExp = NULL;
+#ifndef OPENSSL_NO_RSA
+	p_hwcrhk_RSA = NULL;
+	p_hwcrhk_RSALoadKey = NULL;
+	p_hwcrhk_RSAGetPublicKey = NULL;
+	p_hwcrhk_RSAUnloadKey = NULL;
+#endif
+	p_hwcrhk_ModExpCRT = NULL;
+	p_hwcrhk_RandomBytes = NULL;
+	return to_return;
+	}
+
+static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+	{
+	int to_return = 1;
+
+	switch(cmd)
+		{
+	case HWCRHK_CMD_SO_PATH:
+		if(hwcrhk_dso)
+			{
+			HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_ALREADY_LOADED);
+			return 0;
+			}
+		if(p == NULL)
+			{
+			HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+			return 0;
+			}
+		return set_HWCRHK_LIBNAME((const char *)p);
+	case ENGINE_CTRL_SET_LOGSTREAM:
+		{
+		BIO *bio = (BIO *)p;
+
+		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+		if (logstream)
+			{
+			BIO_free(logstream);
+			logstream = NULL;
+			}
+		if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1)
+			logstream = bio;
+		else
+			HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_BIO_WAS_FREED);
+		}
+		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		break;
+	case ENGINE_CTRL_SET_PASSWORD_CALLBACK:
+		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+		password_context.password_callback = (pem_password_cb *)f;
+		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		break;
+	case ENGINE_CTRL_SET_USER_INTERFACE:
+	case HWCRHK_CMD_SET_USER_INTERFACE:
+		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+		password_context.ui_method = (UI_METHOD *)p;
+		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		break;
+	case ENGINE_CTRL_SET_CALLBACK_DATA:
+	case HWCRHK_CMD_SET_CALLBACK_DATA:
+		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+		password_context.callback_data = p;
+		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		break;
+	/* this enables or disables the "SimpleForkCheck" flag used in the
+	 * initialisation structure. */
+	case ENGINE_CTRL_CHIL_SET_FORKCHECK:
+	case HWCRHK_CMD_FORK_CHECK:
+		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+		if(i)
+			hwcrhk_globals.flags |=
+				HWCryptoHook_InitFlags_SimpleForkCheck;
+		else
+			hwcrhk_globals.flags &=
+				~HWCryptoHook_InitFlags_SimpleForkCheck;
+		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		break;
+	/* This will prevent the initialisation function from "installing"
+	 * the mutex-handling callbacks, even if they are available from
+	 * within the library (or were provided to the library from the
+	 * calling application). This is to remove any baggage for
+	 * applications not using multithreading. */
+	case ENGINE_CTRL_CHIL_NO_LOCKING:
+		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+		disable_mutex_callbacks = 1;
+		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		break;
+	case HWCRHK_CMD_THREAD_LOCKING:
+		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+		disable_mutex_callbacks = ((i == 0) ? 0 : 1);
+		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		break;
+
+	/* The command isn't understood by this engine */
+	default:
+		HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,
+			HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+		to_return = 0;
+		break;
+		}
+
+	return to_return;
+	}
+
+static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data)
+	{
+#ifndef OPENSSL_NO_RSA
+	RSA *rtmp = NULL;
+#endif
+	EVP_PKEY *res = NULL;
+#ifndef OPENSSL_NO_RSA
+	HWCryptoHook_MPI e, n;
+	HWCryptoHook_RSAKeyHandle *hptr;
+#endif
+#if !defined(OPENSSL_NO_RSA)
+	char tempbuf[1024];
+	HWCryptoHook_ErrMsgBuf rmsg;
+	HWCryptoHook_PassphraseContext ppctx;
+#endif
+
+#if !defined(OPENSSL_NO_RSA)
+	rmsg.buf = tempbuf;
+	rmsg.size = sizeof(tempbuf);
+#endif
+
+	if(!hwcrhk_context)
+		{
+		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
+			HWCRHK_R_NOT_INITIALISED);
+		goto err;
+		}
+#ifndef OPENSSL_NO_RSA
+	hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle));
+	if (!hptr)
+		{
+		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
+			ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+        ppctx.ui_method = ui_method;
+	ppctx.callback_data = callback_data;
+	if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr,
+		&rmsg, &ppctx))
+		{
+		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
+			HWCRHK_R_CHIL_ERROR);
+		ERR_add_error_data(1,rmsg.buf);
+		goto err;
+		}
+	if (!*hptr)
+		{
+		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
+			HWCRHK_R_NO_KEY);
+		goto err;
+		}
+#endif
+#ifndef OPENSSL_NO_RSA
+	rtmp = RSA_new_method(eng);
+	RSA_set_ex_data(rtmp, hndidx_rsa, (char *)hptr);
+	rtmp->e = BN_new();
+	rtmp->n = BN_new();
+	rtmp->flags |= RSA_FLAG_EXT_PKEY;
+	MPI2BN(rtmp->e, e);
+	MPI2BN(rtmp->n, n);
+	if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)
+		!= HWCRYPTOHOOK_ERROR_MPISIZE)
+		{
+		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,HWCRHK_R_CHIL_ERROR);
+		ERR_add_error_data(1,rmsg.buf);
+		goto err;
+		}
+
+	bn_expand2(rtmp->e, e.size/sizeof(BN_ULONG));
+	bn_expand2(rtmp->n, n.size/sizeof(BN_ULONG));
+	MPI2BN(rtmp->e, e);
+	MPI2BN(rtmp->n, n);
+
+	if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg))
+		{
+		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
+			HWCRHK_R_CHIL_ERROR);
+		ERR_add_error_data(1,rmsg.buf);
+		goto err;
+		}
+	rtmp->e->top = e.size / sizeof(BN_ULONG);
+	bn_fix_top(rtmp->e);
+	rtmp->n->top = n.size / sizeof(BN_ULONG);
+	bn_fix_top(rtmp->n);
+
+	res = EVP_PKEY_new();
+	EVP_PKEY_assign_RSA(res, rtmp);
+#endif
+
+        if (!res)
+                HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
+                        HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED);
+
+	return res;
+ err:
+#ifndef OPENSSL_NO_RSA
+	if (rtmp)
+		RSA_free(rtmp);
+#endif
+	return NULL;
+	}
+
+static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data)
+	{
+	EVP_PKEY *res = NULL;
+
+#ifndef OPENSSL_NO_RSA
+        res = hwcrhk_load_privkey(eng, key_id,
+                ui_method, callback_data);
+#endif
+
+	if (res)
+		switch(res->type)
+			{
+#ifndef OPENSSL_NO_RSA
+		case EVP_PKEY_RSA:
+			{
+			RSA *rsa = NULL;
+
+			CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
+			rsa = res->pkey.rsa;
+			res->pkey.rsa = RSA_new();
+			res->pkey.rsa->n = rsa->n;
+			res->pkey.rsa->e = rsa->e;
+			rsa->n = NULL;
+			rsa->e = NULL;
+			CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+			RSA_free(rsa);
+			}
+			break;
+#endif
+		default:
+			HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,
+				HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+			goto err;
+			}
+
+	return res;
+ err:
+	if (res)
+		EVP_PKEY_free(res);
+	return NULL;
+	}
+
+/* A little mod_exp */
+static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			const BIGNUM *m, BN_CTX *ctx)
+	{
+	char tempbuf[1024];
+	HWCryptoHook_ErrMsgBuf rmsg;
+	/* Since HWCryptoHook_MPI is pretty compatible with BIGNUM's,
+	   we use them directly, plus a little macro magic.  We only
+	   thing we need to make sure of is that enough space is allocated. */
+	HWCryptoHook_MPI m_a, m_p, m_n, m_r;
+	int to_return, ret;
+ 
+	to_return = 0; /* expect failure */
+	rmsg.buf = tempbuf;
+	rmsg.size = sizeof(tempbuf);
+
+	if(!hwcrhk_context)
+		{
+		HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_NOT_INITIALISED);
+		goto err;
+		}
+	/* Prepare the params */
+	bn_expand2(r, m->top);	/* Check for error !! */
+	BN2MPI(m_a, a);
+	BN2MPI(m_p, p);
+	BN2MPI(m_n, m);
+	MPI2BN(r, m_r);
+
+	/* Perform the operation */
+	ret = p_hwcrhk_ModExp(hwcrhk_context, m_a, m_p, m_n, &m_r, &rmsg);
+
+	/* Convert the response */
+	r->top = m_r.size / sizeof(BN_ULONG);
+	bn_fix_top(r);
+
+	if (ret < 0)
+		{
+		/* FIXME: When this error is returned, HWCryptoHook is
+		   telling us that falling back to software computation
+		   might be a good thing. */
+		if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
+			{
+			HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FALLBACK);
+			}
+		else
+			{
+			HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FAILED);
+			}
+		ERR_add_error_data(1,rmsg.buf);
+		goto err;
+		}
+
+	to_return = 1;
+err:
+	return to_return;
+	}
+
+#ifndef OPENSSL_NO_RSA 
+static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+	{
+	char tempbuf[1024];
+	HWCryptoHook_ErrMsgBuf rmsg;
+	HWCryptoHook_RSAKeyHandle *hptr;
+	int to_return = 0, ret;
+
+	rmsg.buf = tempbuf;
+	rmsg.size = sizeof(tempbuf);
+
+	if(!hwcrhk_context)
+		{
+		HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,HWCRHK_R_NOT_INITIALISED);
+		goto err;
+		}
+
+	/* This provides support for nForce keys.  Since that's opaque data
+	   all we do is provide a handle to the proper key and let HWCryptoHook
+	   take care of the rest. */
+	if ((hptr = (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx_rsa))
+		!= NULL)
+		{
+		HWCryptoHook_MPI m_a, m_r;
+
+		if(!rsa->n)
+			{
+			HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
+				HWCRHK_R_MISSING_KEY_COMPONENTS);
+			goto err;
+			}
+
+		/* Prepare the params */
+		bn_expand2(r, rsa->n->top); /* Check for error !! */
+		BN2MPI(m_a, I);
+		MPI2BN(r, m_r);
+
+		/* Perform the operation */
+		ret = p_hwcrhk_RSA(m_a, *hptr, &m_r, &rmsg);
+
+		/* Convert the response */
+		r->top = m_r.size / sizeof(BN_ULONG);
+		bn_fix_top(r);
+
+		if (ret < 0)
+			{
+			/* FIXME: When this error is returned, HWCryptoHook is
+			   telling us that falling back to software computation
+			   might be a good thing. */
+			if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
+				{
+				HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
+					HWCRHK_R_REQUEST_FALLBACK);
+				}
+			else
+				{
+				HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
+					HWCRHK_R_REQUEST_FAILED);
+				}
+			ERR_add_error_data(1,rmsg.buf);
+			goto err;
+			}
+		}
+	else
+		{
+		HWCryptoHook_MPI m_a, m_p, m_q, m_dmp1, m_dmq1, m_iqmp, m_r;
+
+		if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
+			{
+			HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
+				HWCRHK_R_MISSING_KEY_COMPONENTS);
+			goto err;
+			}
+
+		/* Prepare the params */
+		bn_expand2(r, rsa->n->top); /* Check for error !! */
+		BN2MPI(m_a, I);
+		BN2MPI(m_p, rsa->p);
+		BN2MPI(m_q, rsa->q);
+		BN2MPI(m_dmp1, rsa->dmp1);
+		BN2MPI(m_dmq1, rsa->dmq1);
+		BN2MPI(m_iqmp, rsa->iqmp);
+		MPI2BN(r, m_r);
+
+		/* Perform the operation */
+		ret = p_hwcrhk_ModExpCRT(hwcrhk_context, m_a, m_p, m_q,
+			m_dmp1, m_dmq1, m_iqmp, &m_r, &rmsg);
+
+		/* Convert the response */
+		r->top = m_r.size / sizeof(BN_ULONG);
+		bn_fix_top(r);
+
+		if (ret < 0)
+			{
+			/* FIXME: When this error is returned, HWCryptoHook is
+			   telling us that falling back to software computation
+			   might be a good thing. */
+			if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
+				{
+				HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
+					HWCRHK_R_REQUEST_FALLBACK);
+				}
+			else
+				{
+				HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
+					HWCRHK_R_REQUEST_FAILED);
+				}
+			ERR_add_error_data(1,rmsg.buf);
+			goto err;
+			}
+		}
+	/* If we're here, we must be here with some semblance of success :-) */
+	to_return = 1;
+err:
+	return to_return;
+	}
+#endif
+
+#ifndef OPENSSL_NO_RSA
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+	{
+	return hwcrhk_mod_exp(r, a, p, m, ctx);
+	}
+
+static int hwcrhk_rsa_finish(RSA *rsa)
+	{
+	HWCryptoHook_RSAKeyHandle *hptr;
+
+	hptr = RSA_get_ex_data(rsa, hndidx_rsa);
+	if (hptr)
+                {
+                p_hwcrhk_RSAUnloadKey(*hptr, NULL);
+                OPENSSL_free(hptr);
+		RSA_set_ex_data(rsa, hndidx_rsa, NULL);
+                }
+	return 1;
+	}
+
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
+		const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+	{
+	return hwcrhk_mod_exp(r, a, p, m, ctx);
+	}
+#endif
+
+/* Random bytes are good */
+static int hwcrhk_rand_bytes(unsigned char *buf, int num)
+	{
+	char tempbuf[1024];
+	HWCryptoHook_ErrMsgBuf rmsg;
+	int to_return = 0; /* assume failure */
+	int ret;
+
+	rmsg.buf = tempbuf;
+	rmsg.size = sizeof(tempbuf);
+
+	if(!hwcrhk_context)
+		{
+		HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,HWCRHK_R_NOT_INITIALISED);
+		goto err;
+		}
+
+	ret = p_hwcrhk_RandomBytes(hwcrhk_context, buf, num, &rmsg);
+	if (ret < 0)
+		{
+		/* FIXME: When this error is returned, HWCryptoHook is
+		   telling us that falling back to software computation
+		   might be a good thing. */
+		if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
+			{
+			HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,
+				HWCRHK_R_REQUEST_FALLBACK);
+			}
+		else
+			{
+			HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,
+				HWCRHK_R_REQUEST_FAILED);
+			}
+		ERR_add_error_data(1,rmsg.buf);
+		goto err;
+		}
+	to_return = 1;
+ err:
+	return to_return;
+	}
+
+static int hwcrhk_rand_status(void)
+	{
+	return 1;
+	}
+
+/* Mutex calls: since the HWCryptoHook model closely follows the POSIX model
+ * these just wrap the POSIX functions and add some logging.
+ */
+
+static int hwcrhk_mutex_init(HWCryptoHook_Mutex* mt,
+	HWCryptoHook_CallerContext *cactx)
+	{
+	mt->lockid = CRYPTO_get_new_dynlockid();
+	if (mt->lockid == 0)
+		return 1; /* failure */
+	return 0; /* success */
+	}
+
+static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt)
+	{
+	CRYPTO_w_lock(mt->lockid);
+	return 0;
+	}
+
+static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt)
+	{
+	CRYPTO_w_unlock(mt->lockid);
+	}
+
+static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex *mt)
+	{
+	CRYPTO_destroy_dynlockid(mt->lockid);
+	}
+
+static int hwcrhk_get_pass(const char *prompt_info,
+	int *len_io, char *buf,
+	HWCryptoHook_PassphraseContext *ppctx,
+	HWCryptoHook_CallerContext *cactx)
+	{
+	pem_password_cb *callback = NULL;
+	void *callback_data = NULL;
+        UI_METHOD *ui_method = NULL;
+	/* Despite what the documentation says prompt_info can be
+	 * an empty string.
+	 */
+	if (prompt_info && !*prompt_info)
+		prompt_info = NULL;
+
+        if (cactx)
+                {
+                if (cactx->ui_method)
+                        ui_method = cactx->ui_method;
+		if (cactx->password_callback)
+			callback = cactx->password_callback;
+		if (cactx->callback_data)
+			callback_data = cactx->callback_data;
+                }
+	if (ppctx)
+		{
+                if (ppctx->ui_method)
+                        {
+                        ui_method = ppctx->ui_method;
+                        callback = NULL;
+                        }
+		if (ppctx->callback_data)
+			callback_data = ppctx->callback_data;
+		}
+	if (callback == NULL && ui_method == NULL)
+		{
+		HWCRHKerr(HWCRHK_F_HWCRHK_GET_PASS,HWCRHK_R_NO_CALLBACK);
+		return -1;
+		}
+
+        if (ui_method)
+                {
+                UI *ui = UI_new_method(ui_method);
+                if (ui)
+                        {
+                        int ok;
+                        char *prompt = UI_construct_prompt(ui,
+                                "pass phrase", prompt_info);
+
+                        ok = UI_add_input_string(ui,prompt,
+                                UI_INPUT_FLAG_DEFAULT_PWD,
+				buf,0,(*len_io) - 1);
+                        UI_add_user_data(ui, callback_data);
+			UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
+
+			if (ok >= 0)
+				do
+					{
+					ok=UI_process(ui);
+					}
+				while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
+
+                        if (ok >= 0)
+                                *len_io = strlen(buf);
+
+                        UI_free(ui);
+                        OPENSSL_free(prompt);
+                        }
+                }
+        else
+                {
+                *len_io = callback(buf, *len_io, 0, callback_data);
+                }
+	if(!*len_io)
+		return -1;
+	return 0;
+	}
+
+static int hwcrhk_insert_card(const char *prompt_info,
+		      const char *wrong_info,
+		      HWCryptoHook_PassphraseContext *ppctx,
+		      HWCryptoHook_CallerContext *cactx)
+        {
+        int ok = -1;
+        UI *ui;
+	void *callback_data = NULL;
+        UI_METHOD *ui_method = NULL;
+
+        if (cactx)
+                {
+                if (cactx->ui_method)
+                        ui_method = cactx->ui_method;
+		if (cactx->callback_data)
+			callback_data = cactx->callback_data;
+                }
+	if (ppctx)
+		{
+                if (ppctx->ui_method)
+                        ui_method = ppctx->ui_method;
+		if (ppctx->callback_data)
+			callback_data = ppctx->callback_data;
+		}
+	if (ui_method == NULL)
+		{
+		HWCRHKerr(HWCRHK_F_HWCRHK_INSERT_CARD,
+			HWCRHK_R_NO_CALLBACK);
+		return -1;
+		}
+
+	ui = UI_new_method(ui_method);
+
+	if (ui)
+		{
+		char answer;
+		char buf[BUFSIZ];
+		/* Despite what the documentation says wrong_info can be
+	 	 * an empty string.
+		 */
+		if (wrong_info && *wrong_info)
+			BIO_snprintf(buf, sizeof(buf)-1,
+				"Current card: \"%s\"\n", wrong_info);
+		else
+			buf[0] = 0;
+		ok = UI_dup_info_string(ui, buf);
+		if (ok >= 0 && prompt_info)
+			{
+			BIO_snprintf(buf, sizeof(buf)-1,
+				"Insert card \"%s\"", prompt_info);
+			ok = UI_dup_input_boolean(ui, buf,
+				"\n then hit <enter> or C<enter> to cancel\n",
+				"\r\n", "Cc", UI_INPUT_FLAG_ECHO, &answer);
+			}
+		UI_add_user_data(ui, callback_data);
+
+		if (ok >= 0)
+			ok = UI_process(ui);
+		UI_free(ui);
+
+		if (ok == -2 || (ok >= 0 && answer == 'C'))
+			ok = 1;
+		else if (ok < 0)
+			ok = -1;
+		else
+			ok = 0;
+		}
+	return ok;
+	}
+
+static void hwcrhk_log_message(void *logstr, const char *message)
+	{
+	BIO *lstream = NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_BIO);
+	if (logstr)
+		lstream=*(BIO **)logstr;
+	if (lstream)
+		{
+		BIO_printf(lstream, "%s\n", message);
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
+	}
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library. */	   
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_fn(ENGINE *e, const char *id)
+	{
+	if(id && (strcmp(id, engine_hwcrhk_id) != 0) &&
+			(strcmp(id, engine_hwcrhk_id_alt) != 0))
+		return 0;
+	if(!bind_helper(e))
+		return 0;
+	return 1;
+	}       
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
+
+#endif /* !OPENSSL_NO_HW_CHIL */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_chil.ec b/openssl/engines/e_chil.ec
new file mode 100644
index 0000000..b5a76e1
--- /dev/null
+++ b/openssl/engines/e_chil.ec
@@ -0,0 +1 @@
+L HWCRHK	e_chil_err.h			e_chil_err.c
diff --git a/openssl/engines/e_chil_err.c b/openssl/engines/e_chil_err.c
new file mode 100644
index 0000000..c5983b2
--- /dev/null
+++ b/openssl/engines/e_chil_err.c
@@ -0,0 +1,160 @@
+/* e_chil_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "e_chil_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA HWCRHK_str_functs[]=
+	{
+{ERR_FUNC(HWCRHK_F_HWCRHK_CTRL),	"HWCRHK_CTRL"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_FINISH),	"HWCRHK_FINISH"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_GET_PASS),	"HWCRHK_GET_PASS"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_INIT),	"HWCRHK_INIT"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_INSERT_CARD),	"HWCRHK_INSERT_CARD"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_LOAD_PRIVKEY),	"HWCRHK_LOAD_PRIVKEY"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_LOAD_PUBKEY),	"HWCRHK_LOAD_PUBKEY"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_MOD_EXP),	"HWCRHK_MOD_EXP"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_RAND_BYTES),	"HWCRHK_RAND_BYTES"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_RSA_MOD_EXP),	"HWCRHK_RSA_MOD_EXP"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA HWCRHK_str_reasons[]=
+	{
+{ERR_REASON(HWCRHK_R_ALREADY_LOADED)     ,"already loaded"},
+{ERR_REASON(HWCRHK_R_BIO_WAS_FREED)      ,"bio was freed"},
+{ERR_REASON(HWCRHK_R_CHIL_ERROR)         ,"chil error"},
+{ERR_REASON(HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
+{ERR_REASON(HWCRHK_R_DSO_FAILURE)        ,"dso failure"},
+{ERR_REASON(HWCRHK_R_MISSING_KEY_COMPONENTS),"missing key components"},
+{ERR_REASON(HWCRHK_R_NOT_INITIALISED)    ,"not initialised"},
+{ERR_REASON(HWCRHK_R_NOT_LOADED)         ,"not loaded"},
+{ERR_REASON(HWCRHK_R_NO_CALLBACK)        ,"no callback"},
+{ERR_REASON(HWCRHK_R_NO_KEY)             ,"no key"},
+{ERR_REASON(HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED),"private key algorithms disabled"},
+{ERR_REASON(HWCRHK_R_REQUEST_FAILED)     ,"request failed"},
+{ERR_REASON(HWCRHK_R_REQUEST_FALLBACK)   ,"request fallback"},
+{ERR_REASON(HWCRHK_R_UNIT_FAILURE)       ,"unit failure"},
+{0,NULL}
+	};
+
+#endif
+
+#ifdef HWCRHK_LIB_NAME
+static ERR_STRING_DATA HWCRHK_lib_name[]=
+        {
+{0	,HWCRHK_LIB_NAME},
+{0,NULL}
+	};
+#endif
+
+
+static int HWCRHK_lib_error_code=0;
+static int HWCRHK_error_init=1;
+
+static void ERR_load_HWCRHK_strings(void)
+	{
+	if (HWCRHK_lib_error_code == 0)
+		HWCRHK_lib_error_code=ERR_get_next_error_library();
+
+	if (HWCRHK_error_init)
+		{
+		HWCRHK_error_init=0;
+#ifndef OPENSSL_NO_ERR
+		ERR_load_strings(HWCRHK_lib_error_code,HWCRHK_str_functs);
+		ERR_load_strings(HWCRHK_lib_error_code,HWCRHK_str_reasons);
+#endif
+
+#ifdef HWCRHK_LIB_NAME
+		HWCRHK_lib_name->error = ERR_PACK(HWCRHK_lib_error_code,0,0);
+		ERR_load_strings(0,HWCRHK_lib_name);
+#endif
+		}
+	}
+
+static void ERR_unload_HWCRHK_strings(void)
+	{
+	if (HWCRHK_error_init == 0)
+		{
+#ifndef OPENSSL_NO_ERR
+		ERR_unload_strings(HWCRHK_lib_error_code,HWCRHK_str_functs);
+		ERR_unload_strings(HWCRHK_lib_error_code,HWCRHK_str_reasons);
+#endif
+
+#ifdef HWCRHK_LIB_NAME
+		ERR_unload_strings(0,HWCRHK_lib_name);
+#endif
+		HWCRHK_error_init=1;
+		}
+	}
+
+static void ERR_HWCRHK_error(int function, int reason, char *file, int line)
+	{
+	if (HWCRHK_lib_error_code == 0)
+		HWCRHK_lib_error_code=ERR_get_next_error_library();
+	ERR_PUT_error(HWCRHK_lib_error_code,function,reason,file,line);
+	}
diff --git a/openssl/engines/e_chil_err.h b/openssl/engines/e_chil_err.h
new file mode 100644
index 0000000..3c42a02
--- /dev/null
+++ b/openssl/engines/e_chil_err.h
@@ -0,0 +1,104 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_HWCRHK_ERR_H
+#define HEADER_HWCRHK_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_HWCRHK_strings(void);
+static void ERR_unload_HWCRHK_strings(void);
+static void ERR_HWCRHK_error(int function, int reason, char *file, int line);
+#define HWCRHKerr(f,r) ERR_HWCRHK_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the HWCRHK functions. */
+
+/* Function codes. */
+#define HWCRHK_F_HWCRHK_CTRL				 100
+#define HWCRHK_F_HWCRHK_FINISH				 101
+#define HWCRHK_F_HWCRHK_GET_PASS			 102
+#define HWCRHK_F_HWCRHK_INIT				 103
+#define HWCRHK_F_HWCRHK_INSERT_CARD			 104
+#define HWCRHK_F_HWCRHK_LOAD_PRIVKEY			 105
+#define HWCRHK_F_HWCRHK_LOAD_PUBKEY			 106
+#define HWCRHK_F_HWCRHK_MOD_EXP				 107
+#define HWCRHK_F_HWCRHK_RAND_BYTES			 108
+#define HWCRHK_F_HWCRHK_RSA_MOD_EXP			 109
+
+/* Reason codes. */
+#define HWCRHK_R_ALREADY_LOADED				 100
+#define HWCRHK_R_BIO_WAS_FREED				 101
+#define HWCRHK_R_CHIL_ERROR				 102
+#define HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED		 103
+#define HWCRHK_R_DSO_FAILURE				 104
+#define HWCRHK_R_MISSING_KEY_COMPONENTS			 105
+#define HWCRHK_R_NOT_INITIALISED			 106
+#define HWCRHK_R_NOT_LOADED				 107
+#define HWCRHK_R_NO_CALLBACK				 108
+#define HWCRHK_R_NO_KEY					 109
+#define HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED	 110
+#define HWCRHK_R_REQUEST_FAILED				 111
+#define HWCRHK_R_REQUEST_FALLBACK			 112
+#define HWCRHK_R_UNIT_FAILURE				 113
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_cswift.c b/openssl/engines/e_cswift.c
new file mode 100644
index 0000000..2e64ff3
--- /dev/null
+++ b/openssl/engines/e_cswift.c
@@ -0,0 +1,1129 @@
+/* crypto/engine/hw_cswift.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/dso.h>
+#include <openssl/engine.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_CSWIFT
+
+/* Attribution notice: Rainbow have generously allowed me to reproduce
+ * the necessary definitions here from their API. This means the support
+ * can build independently of whether application builders have the
+ * API or hardware. This will allow developers to easily produce software
+ * that has latent hardware support for any users that have accelerators
+ * installed, without the developers themselves needing anything extra.
+ *
+ * I have only clipped the parts from the CryptoSwift header files that
+ * are (or seem) relevant to the CryptoSwift support code. This is
+ * simply to keep the file sizes reasonable.
+ * [Geoff]
+ */
+#ifdef FLAT_INC
+#include "cswift.h"
+#else
+#include "vendor_defns/cswift.h"
+#endif
+
+#define CSWIFT_LIB_NAME "cswift engine"
+#include "e_cswift_err.c"
+
+#define DECIMAL_SIZE(type)	((sizeof(type)*8+2)/3+1)
+
+static int cswift_destroy(ENGINE *e);
+static int cswift_init(ENGINE *e);
+static int cswift_finish(ENGINE *e);
+static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+#ifndef OPENSSL_NO_RSA
+static int cswift_bn_32copy(SW_LARGENUMBER * out, const BIGNUM * in);
+#endif
+
+/* BIGNUM stuff */
+static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx);
+#ifndef OPENSSL_NO_RSA
+static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
+		const BIGNUM *iqmp, BN_CTX *ctx);
+#endif
+
+#ifndef OPENSSL_NO_RSA
+/* RSA stuff */
+static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* DSA stuff */
+static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
+				DSA_SIG *sig, DSA *dsa);
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* DH stuff */
+/* This function is alised to mod_exp (with the DH and mont dropped). */
+static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
+		const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#endif
+
+/* RAND stuff */
+static int cswift_rand_bytes(unsigned char *buf, int num);
+static int cswift_rand_status(void);
+
+/* The definitions for control commands specific to this engine */
+#define CSWIFT_CMD_SO_PATH		ENGINE_CMD_BASE
+static const ENGINE_CMD_DEFN cswift_cmd_defns[] = {
+	{CSWIFT_CMD_SO_PATH,
+		"SO_PATH",
+		"Specifies the path to the 'cswift' shared library",
+		ENGINE_CMD_FLAG_STRING},
+	{0, NULL, NULL, 0}
+	};
+
+#ifndef OPENSSL_NO_RSA
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD cswift_rsa =
+	{
+	"CryptoSwift RSA method",
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	cswift_rsa_mod_exp,
+	cswift_mod_exp_mont,
+	NULL,
+	NULL,
+	0,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+	};
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* Our internal DSA_METHOD that we provide pointers to */
+static DSA_METHOD cswift_dsa =
+	{
+	"CryptoSwift DSA method",
+	cswift_dsa_sign,
+	NULL, /* dsa_sign_setup */
+	cswift_dsa_verify,
+	NULL, /* dsa_mod_exp */
+	NULL, /* bn_mod_exp */
+	NULL, /* init */
+	NULL, /* finish */
+	0, /* flags */
+	NULL, /* app_data */
+	NULL, /* dsa_paramgen */
+	NULL /* dsa_keygen */
+	};
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* Our internal DH_METHOD that we provide pointers to */
+static DH_METHOD cswift_dh =
+	{
+	"CryptoSwift DH method",
+	NULL,
+	NULL,
+	cswift_mod_exp_dh,
+	NULL,
+	NULL,
+	0,
+	NULL,
+	NULL
+	};
+#endif
+
+static RAND_METHOD cswift_random =
+    {
+    /* "CryptoSwift RAND method", */
+    NULL,
+    cswift_rand_bytes,
+    NULL,
+    NULL,
+    cswift_rand_bytes,
+    cswift_rand_status,
+    };
+
+
+/* Constants used when creating the ENGINE */
+static const char *engine_cswift_id = "cswift";
+static const char *engine_cswift_name = "CryptoSwift hardware engine support";
+
+/* This internal function is used by ENGINE_cswift() and possibly by the
+ * "dynamic" ENGINE support too */
+static int bind_helper(ENGINE *e)
+	{
+#ifndef OPENSSL_NO_RSA
+	const RSA_METHOD *meth1;
+#endif
+#ifndef OPENSSL_NO_DH
+	const DH_METHOD *meth2;
+#endif
+	if(!ENGINE_set_id(e, engine_cswift_id) ||
+			!ENGINE_set_name(e, engine_cswift_name) ||
+#ifndef OPENSSL_NO_RSA
+			!ENGINE_set_RSA(e, &cswift_rsa) ||
+#endif
+#ifndef OPENSSL_NO_DSA
+			!ENGINE_set_DSA(e, &cswift_dsa) ||
+#endif
+#ifndef OPENSSL_NO_DH
+			!ENGINE_set_DH(e, &cswift_dh) ||
+#endif
+			!ENGINE_set_RAND(e, &cswift_random) ||
+			!ENGINE_set_destroy_function(e, cswift_destroy) ||
+			!ENGINE_set_init_function(e, cswift_init) ||
+			!ENGINE_set_finish_function(e, cswift_finish) ||
+			!ENGINE_set_ctrl_function(e, cswift_ctrl) ||
+			!ENGINE_set_cmd_defns(e, cswift_cmd_defns))
+		return 0;
+
+#ifndef OPENSSL_NO_RSA
+	/* We know that the "PKCS1_SSLeay()" functions hook properly
+	 * to the cswift-specific mod_exp and mod_exp_crt so we use
+	 * those functions. NB: We don't use ENGINE_openssl() or
+	 * anything "more generic" because something like the RSAref
+	 * code may not hook properly, and if you own one of these
+	 * cards then you have the right to do RSA operations on it
+	 * anyway! */ 
+	meth1 = RSA_PKCS1_SSLeay();
+	cswift_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+	cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+	cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+	cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+#endif
+
+#ifndef OPENSSL_NO_DH
+	/* Much the same for Diffie-Hellman */
+	meth2 = DH_OpenSSL();
+	cswift_dh.generate_key = meth2->generate_key;
+	cswift_dh.compute_key = meth2->compute_key;
+#endif
+
+	/* Ensure the cswift error handling is set up */
+	ERR_load_CSWIFT_strings();
+	return 1;
+	}
+
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+static ENGINE *engine_cswift(void)
+	{
+	ENGINE *ret = ENGINE_new();
+	if(!ret)
+		return NULL;
+	if(!bind_helper(ret))
+		{
+		ENGINE_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+void ENGINE_load_cswift(void)
+	{
+	/* Copied from eng_[openssl|dyn].c */
+	ENGINE *toadd = engine_cswift();
+	if(!toadd) return;
+	ENGINE_add(toadd);
+	ENGINE_free(toadd);
+	ERR_clear_error();
+	}
+#endif
+
+/* This is a process-global DSO handle used for loading and unloading
+ * the CryptoSwift library. NB: This is only set (or unset) during an
+ * init() or finish() call (reference counts permitting) and they're
+ * operating with global locks, so this should be thread-safe
+ * implicitly. */
+static DSO *cswift_dso = NULL;
+
+/* These are the function pointers that are (un)set when the library has
+ * successfully (un)loaded. */
+t_swAcquireAccContext *p_CSwift_AcquireAccContext = NULL;
+t_swAttachKeyParam *p_CSwift_AttachKeyParam = NULL;
+t_swSimpleRequest *p_CSwift_SimpleRequest = NULL;
+t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL;
+
+/* Used in the DSO operations. */
+static const char *CSWIFT_LIBNAME = NULL;
+static const char *get_CSWIFT_LIBNAME(void)
+	{
+	if(CSWIFT_LIBNAME)
+		return CSWIFT_LIBNAME;
+	return "swift";
+	}
+static void free_CSWIFT_LIBNAME(void)
+	{
+	if(CSWIFT_LIBNAME)
+		OPENSSL_free((void*)CSWIFT_LIBNAME);
+	CSWIFT_LIBNAME = NULL;
+	}
+static long set_CSWIFT_LIBNAME(const char *name)
+	{
+	free_CSWIFT_LIBNAME();
+	return (((CSWIFT_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
+	}
+static const char *CSWIFT_F1 = "swAcquireAccContext";
+static const char *CSWIFT_F2 = "swAttachKeyParam";
+static const char *CSWIFT_F3 = "swSimpleRequest";
+static const char *CSWIFT_F4 = "swReleaseAccContext";
+
+
+/* CryptoSwift library functions and mechanics - these are used by the
+ * higher-level functions further down. NB: As and where there's no
+ * error checking, take a look lower down where these functions are
+ * called, the checking and error handling is probably down there. */
+
+/* utility function to obtain a context */
+static int get_context(SW_CONTEXT_HANDLE *hac)
+	{
+        SW_STATUS status;
+ 
+        status = p_CSwift_AcquireAccContext(hac);
+        if(status != SW_OK)
+                return 0;
+        return 1;
+	}
+ 
+/* similarly to release one. */
+static void release_context(SW_CONTEXT_HANDLE hac)
+	{
+        p_CSwift_ReleaseAccContext(hac);
+	}
+
+/* Destructor (complements the "ENGINE_cswift()" constructor) */
+static int cswift_destroy(ENGINE *e)
+	{
+	free_CSWIFT_LIBNAME();
+	ERR_unload_CSWIFT_strings();
+	return 1;
+	}
+
+/* (de)initialisation functions. */
+static int cswift_init(ENGINE *e)
+	{
+        SW_CONTEXT_HANDLE hac;
+        t_swAcquireAccContext *p1;
+        t_swAttachKeyParam *p2;
+        t_swSimpleRequest *p3;
+        t_swReleaseAccContext *p4;
+
+	if(cswift_dso != NULL)
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_ALREADY_LOADED);
+		goto err;
+		}
+	/* Attempt to load libswift.so/swift.dll/whatever. */
+	cswift_dso = DSO_load(NULL, get_CSWIFT_LIBNAME(), NULL, 0);
+	if(cswift_dso == NULL)
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
+		goto err;
+		}
+	if(!(p1 = (t_swAcquireAccContext *)
+				DSO_bind_func(cswift_dso, CSWIFT_F1)) ||
+			!(p2 = (t_swAttachKeyParam *)
+				DSO_bind_func(cswift_dso, CSWIFT_F2)) ||
+			!(p3 = (t_swSimpleRequest *)
+				DSO_bind_func(cswift_dso, CSWIFT_F3)) ||
+			!(p4 = (t_swReleaseAccContext *)
+				DSO_bind_func(cswift_dso, CSWIFT_F4)))
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
+		goto err;
+		}
+	/* Copy the pointers */
+	p_CSwift_AcquireAccContext = p1;
+	p_CSwift_AttachKeyParam = p2;
+	p_CSwift_SimpleRequest = p3;
+	p_CSwift_ReleaseAccContext = p4;
+	/* Try and get a context - if not, we may have a DSO but no
+	 * accelerator! */
+	if(!get_context(&hac))
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_UNIT_FAILURE);
+		goto err;
+		}
+	release_context(hac);
+	/* Everything's fine. */
+	return 1;
+err:
+	if(cswift_dso)
+	{
+		DSO_free(cswift_dso);
+		cswift_dso = NULL;
+	}
+	p_CSwift_AcquireAccContext = NULL;
+	p_CSwift_AttachKeyParam = NULL;
+	p_CSwift_SimpleRequest = NULL;
+	p_CSwift_ReleaseAccContext = NULL;
+	return 0;
+	}
+
+static int cswift_finish(ENGINE *e)
+	{
+	free_CSWIFT_LIBNAME();
+	if(cswift_dso == NULL)
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_NOT_LOADED);
+		return 0;
+		}
+	if(!DSO_free(cswift_dso))
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_UNIT_FAILURE);
+		return 0;
+		}
+	cswift_dso = NULL;
+	p_CSwift_AcquireAccContext = NULL;
+	p_CSwift_AttachKeyParam = NULL;
+	p_CSwift_SimpleRequest = NULL;
+	p_CSwift_ReleaseAccContext = NULL;
+	return 1;
+	}
+
+static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+	{
+	int initialised = ((cswift_dso == NULL) ? 0 : 1);
+	switch(cmd)
+		{
+	case CSWIFT_CMD_SO_PATH:
+		if(p == NULL)
+			{
+			CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+			return 0;
+			}
+		if(initialised)
+			{
+			CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_ALREADY_LOADED);
+			return 0;
+			}
+		return set_CSWIFT_LIBNAME((const char *)p);
+	default:
+		break;
+		}
+	CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+	return 0;
+	}
+
+/* Un petit mod_exp */
+static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			const BIGNUM *m, BN_CTX *ctx)
+	{
+	/* I need somewhere to store temporary serialised values for
+	 * use with the CryptoSwift API calls. A neat cheat - I'll use
+	 * BIGNUMs from the BN_CTX but access their arrays directly as
+	 * byte arrays <grin>. This way I don't have to clean anything
+	 * up. */
+	BIGNUM *modulus;
+	BIGNUM *exponent;
+	BIGNUM *argument;
+	BIGNUM *result;
+	SW_STATUS sw_status;
+	SW_LARGENUMBER arg, res;
+	SW_PARAM sw_param;
+	SW_CONTEXT_HANDLE hac;
+	int to_return, acquired;
+ 
+	modulus = exponent = argument = result = NULL;
+	to_return = 0; /* expect failure */
+	acquired = 0;
+ 
+	if(!get_context(&hac))
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_UNIT_FAILURE);
+		goto err;
+		}
+	acquired = 1;
+	/* Prepare the params */
+	BN_CTX_start(ctx);
+	modulus = BN_CTX_get(ctx);
+	exponent = BN_CTX_get(ctx);
+	argument = BN_CTX_get(ctx);
+	result = BN_CTX_get(ctx);
+	if(!result)
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_CTX_FULL);
+		goto err;
+		}
+	if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) ||
+		!bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top))
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_EXPAND_FAIL);
+		goto err;
+		}
+	sw_param.type = SW_ALG_EXP;
+	sw_param.up.exp.modulus.nbytes = BN_bn2bin(m,
+		(unsigned char *)modulus->d);
+	sw_param.up.exp.modulus.value = (unsigned char *)modulus->d;
+	sw_param.up.exp.exponent.nbytes = BN_bn2bin(p,
+		(unsigned char *)exponent->d);
+	sw_param.up.exp.exponent.value = (unsigned char *)exponent->d;
+	/* Attach the key params */
+	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
+	switch(sw_status)
+		{
+	case SW_OK:
+		break;
+	case SW_ERR_INPUT_SIZE:
+		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BAD_KEY_SIZE);
+		goto err;
+	default:
+		{
+		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
+		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
+		sprintf(tmpbuf, "%ld", sw_status);
+		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+		}
+		goto err;
+		}
+	/* Prepare the argument and response */
+	arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
+	arg.value = (unsigned char *)argument->d;
+	res.nbytes = BN_num_bytes(m);
+	memset(result->d, 0, res.nbytes);
+	res.value = (unsigned char *)result->d;
+	/* Perform the operation */
+	if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1,
+		&res, 1)) != SW_OK)
+		{
+		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
+		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
+		sprintf(tmpbuf, "%ld", sw_status);
+		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+		goto err;
+		}
+	/* Convert the response */
+	BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
+	to_return = 1;
+err:
+	if(acquired)
+		release_context(hac);
+	BN_CTX_end(ctx);
+	return to_return;
+	}
+
+
+#ifndef OPENSSL_NO_RSA
+int cswift_bn_32copy(SW_LARGENUMBER * out, const BIGNUM * in)
+{
+	int mod;
+	int numbytes = BN_num_bytes(in);
+
+	mod = 0;
+	while( ((out->nbytes = (numbytes+mod)) % 32) )
+	{
+		mod++;
+	}
+	out->value = (unsigned char*)OPENSSL_malloc(out->nbytes);
+	if(!out->value)
+	{
+		return 0;
+	}
+	BN_bn2bin(in, &out->value[mod]);
+	if(mod)
+		memset(out->value, 0, mod);
+
+	return 1;
+}
+#endif
+
+#ifndef OPENSSL_NO_RSA
+/* Un petit mod_exp chinois */
+static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			const BIGNUM *q, const BIGNUM *dmp1,
+			const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx)
+	{
+	SW_STATUS sw_status;
+	SW_LARGENUMBER arg, res;
+	SW_PARAM sw_param;
+	SW_CONTEXT_HANDLE hac;
+	BIGNUM *result = NULL;
+	BIGNUM *argument = NULL;
+	int to_return = 0; /* expect failure */
+	int acquired = 0;
+
+	sw_param.up.crt.p.value = NULL;
+	sw_param.up.crt.q.value = NULL;
+	sw_param.up.crt.dmp1.value = NULL;
+	sw_param.up.crt.dmq1.value = NULL;
+	sw_param.up.crt.iqmp.value = NULL;
+ 
+	if(!get_context(&hac))
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_UNIT_FAILURE);
+		goto err;
+		}
+	acquired = 1;
+
+	/* Prepare the params */
+	argument = BN_new();
+	result = BN_new();
+	if(!result || !argument)
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_CTX_FULL);
+		goto err;
+		}
+
+
+	sw_param.type = SW_ALG_CRT;
+	/************************************************************************/
+	/* 04/02/2003                                                           */
+	/* Modified by Frederic Giudicelli (deny-all.com) to overcome the       */
+	/* limitation of cswift with values not a multiple of 32                */
+	/************************************************************************/
+	if(!cswift_bn_32copy(&sw_param.up.crt.p, p))
+	{
+		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
+		goto err;
+	}
+	if(!cswift_bn_32copy(&sw_param.up.crt.q, q))
+	{
+		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
+		goto err;
+	}
+	if(!cswift_bn_32copy(&sw_param.up.crt.dmp1, dmp1))
+	{
+		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
+		goto err;
+	}
+	if(!cswift_bn_32copy(&sw_param.up.crt.dmq1, dmq1))
+	{
+		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
+		goto err;
+	}
+	if(!cswift_bn_32copy(&sw_param.up.crt.iqmp, iqmp))
+	{
+		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
+		goto err;
+	}
+	if(	!bn_wexpand(argument, a->top) ||
+			!bn_wexpand(result, p->top + q->top))
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
+		goto err;
+		}
+
+	/* Attach the key params */
+	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
+	switch(sw_status)
+		{
+	case SW_OK:
+		break;
+	case SW_ERR_INPUT_SIZE:
+		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BAD_KEY_SIZE);
+		goto err;
+	default:
+		{
+		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
+		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
+		sprintf(tmpbuf, "%ld", sw_status);
+		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+		}
+		goto err;
+		}
+	/* Prepare the argument and response */
+	arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
+	arg.value = (unsigned char *)argument->d;
+	res.nbytes = 2 * BN_num_bytes(p);
+	memset(result->d, 0, res.nbytes);
+	res.value = (unsigned char *)result->d;
+	/* Perform the operation */
+	if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1,
+		&res, 1)) != SW_OK)
+		{
+		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
+		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
+		sprintf(tmpbuf, "%ld", sw_status);
+		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+		goto err;
+		}
+	/* Convert the response */
+	BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
+	to_return = 1;
+err:
+	if(sw_param.up.crt.p.value)
+		OPENSSL_free(sw_param.up.crt.p.value);
+	if(sw_param.up.crt.q.value)
+		OPENSSL_free(sw_param.up.crt.q.value);
+	if(sw_param.up.crt.dmp1.value)
+		OPENSSL_free(sw_param.up.crt.dmp1.value);
+	if(sw_param.up.crt.dmq1.value)
+		OPENSSL_free(sw_param.up.crt.dmq1.value);
+	if(sw_param.up.crt.iqmp.value)
+		OPENSSL_free(sw_param.up.crt.iqmp.value);
+	if(result)
+		BN_free(result);
+	if(argument)
+		BN_free(argument);
+	if(acquired)
+		release_context(hac);
+	return to_return;
+	}
+#endif
+ 
+#ifndef OPENSSL_NO_RSA
+static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+	{
+	int to_return = 0;
+	const RSA_METHOD * def_rsa_method;
+
+	if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_RSA_MOD_EXP,CSWIFT_R_MISSING_KEY_COMPONENTS);
+		goto err;
+		}
+
+	/* Try the limits of RSA (2048 bits) */
+	if(BN_num_bytes(rsa->p) > 128 ||
+		BN_num_bytes(rsa->q) > 128 ||
+		BN_num_bytes(rsa->dmp1) > 128 ||
+		BN_num_bytes(rsa->dmq1) > 128 ||
+		BN_num_bytes(rsa->iqmp) > 128)
+	{
+#ifdef RSA_NULL
+		def_rsa_method=RSA_null_method();
+#else
+#if 0
+		def_rsa_method=RSA_PKCS1_RSAref();
+#else
+		def_rsa_method=RSA_PKCS1_SSLeay();
+#endif
+#endif
+		if(def_rsa_method)
+			return def_rsa_method->rsa_mod_exp(r0, I, rsa, ctx);
+	}
+
+	to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
+		rsa->dmq1, rsa->iqmp, ctx);
+err:
+	return to_return;
+	}
+
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+	{
+	const RSA_METHOD * def_rsa_method;
+
+	/* Try the limits of RSA (2048 bits) */
+	if(BN_num_bytes(r) > 256 ||
+		BN_num_bytes(a) > 256 ||
+		BN_num_bytes(m) > 256)
+	{
+#ifdef RSA_NULL
+		def_rsa_method=RSA_null_method();
+#else
+#if 0
+		def_rsa_method=RSA_PKCS1_RSAref();
+#else
+		def_rsa_method=RSA_PKCS1_SSLeay();
+#endif
+#endif
+		if(def_rsa_method)
+			return def_rsa_method->bn_mod_exp(r, a, p, m, ctx, m_ctx);
+	}
+
+	return cswift_mod_exp(r, a, p, m, ctx);
+	}
+#endif	/* OPENSSL_NO_RSA */
+
+#ifndef OPENSSL_NO_DSA
+static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+	{
+	SW_CONTEXT_HANDLE hac;
+	SW_PARAM sw_param;
+	SW_STATUS sw_status;
+	SW_LARGENUMBER arg, res;
+	BN_CTX *ctx;
+	BIGNUM *dsa_p = NULL;
+	BIGNUM *dsa_q = NULL;
+	BIGNUM *dsa_g = NULL;
+	BIGNUM *dsa_key = NULL;
+	BIGNUM *result = NULL;
+	DSA_SIG *to_return = NULL;
+	int acquired = 0;
+
+	if((ctx = BN_CTX_new()) == NULL)
+		goto err;
+	if(!get_context(&hac))
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_UNIT_FAILURE);
+		goto err;
+		}
+	acquired = 1;
+	/* Prepare the params */
+	BN_CTX_start(ctx);
+	dsa_p = BN_CTX_get(ctx);
+	dsa_q = BN_CTX_get(ctx);
+	dsa_g = BN_CTX_get(ctx);
+	dsa_key = BN_CTX_get(ctx);
+	result = BN_CTX_get(ctx);
+	if(!result)
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_CTX_FULL);
+		goto err;
+		}
+	if(!bn_wexpand(dsa_p, dsa->p->top) ||
+			!bn_wexpand(dsa_q, dsa->q->top) ||
+			!bn_wexpand(dsa_g, dsa->g->top) ||
+			!bn_wexpand(dsa_key, dsa->priv_key->top) ||
+			!bn_wexpand(result, dsa->p->top))
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_EXPAND_FAIL);
+		goto err;
+		}
+	sw_param.type = SW_ALG_DSA;
+	sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
+				(unsigned char *)dsa_p->d);
+	sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
+	sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
+				(unsigned char *)dsa_q->d);
+	sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
+	sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
+				(unsigned char *)dsa_g->d);
+	sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
+	sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->priv_key,
+				(unsigned char *)dsa_key->d);
+	sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
+	/* Attach the key params */
+	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
+	switch(sw_status)
+		{
+	case SW_OK:
+		break;
+	case SW_ERR_INPUT_SIZE:
+		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BAD_KEY_SIZE);
+		goto err;
+	default:
+		{
+		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
+		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
+		sprintf(tmpbuf, "%ld", sw_status);
+		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+		}
+		goto err;
+		}
+	/* Prepare the argument and response */
+	arg.nbytes = dlen;
+	arg.value = (unsigned char *)dgst;
+	res.nbytes = BN_num_bytes(dsa->p);
+	memset(result->d, 0, res.nbytes);
+	res.value = (unsigned char *)result->d;
+	/* Perform the operation */
+	sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_SIGN, &arg, 1,
+		&res, 1);
+	if(sw_status != SW_OK)
+		{
+		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
+		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
+		sprintf(tmpbuf, "%ld", sw_status);
+		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+		goto err;
+		}
+	/* Convert the response */
+	if((to_return = DSA_SIG_new()) == NULL)
+		goto err;
+	to_return->r = BN_bin2bn((unsigned char *)result->d, 20, NULL);
+	to_return->s = BN_bin2bn((unsigned char *)result->d + 20, 20, NULL);
+
+err:
+	if(acquired)
+		release_context(hac);
+	if(ctx)
+		{
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+		}
+	return to_return;
+	}
+
+static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
+				DSA_SIG *sig, DSA *dsa)
+	{
+	SW_CONTEXT_HANDLE hac;
+	SW_PARAM sw_param;
+	SW_STATUS sw_status;
+	SW_LARGENUMBER arg[2], res;
+	unsigned long sig_result;
+	BN_CTX *ctx;
+	BIGNUM *dsa_p = NULL;
+	BIGNUM *dsa_q = NULL;
+	BIGNUM *dsa_g = NULL;
+	BIGNUM *dsa_key = NULL;
+	BIGNUM *argument = NULL;
+	int to_return = -1;
+	int acquired = 0;
+
+	if((ctx = BN_CTX_new()) == NULL)
+		goto err;
+	if(!get_context(&hac))
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_UNIT_FAILURE);
+		goto err;
+		}
+	acquired = 1;
+	/* Prepare the params */
+	BN_CTX_start(ctx);
+	dsa_p = BN_CTX_get(ctx);
+	dsa_q = BN_CTX_get(ctx);
+	dsa_g = BN_CTX_get(ctx);
+	dsa_key = BN_CTX_get(ctx);
+	argument = BN_CTX_get(ctx);
+	if(!argument)
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_CTX_FULL);
+		goto err;
+		}
+	if(!bn_wexpand(dsa_p, dsa->p->top) ||
+			!bn_wexpand(dsa_q, dsa->q->top) ||
+			!bn_wexpand(dsa_g, dsa->g->top) ||
+			!bn_wexpand(dsa_key, dsa->pub_key->top) ||
+			!bn_wexpand(argument, 40))
+		{
+		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_EXPAND_FAIL);
+		goto err;
+		}
+	sw_param.type = SW_ALG_DSA;
+	sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
+				(unsigned char *)dsa_p->d);
+	sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
+	sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
+				(unsigned char *)dsa_q->d);
+	sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
+	sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
+				(unsigned char *)dsa_g->d);
+	sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
+	sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->pub_key,
+				(unsigned char *)dsa_key->d);
+	sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
+	/* Attach the key params */
+	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
+	switch(sw_status)
+		{
+	case SW_OK:
+		break;
+	case SW_ERR_INPUT_SIZE:
+		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BAD_KEY_SIZE);
+		goto err;
+	default:
+		{
+		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
+		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
+		sprintf(tmpbuf, "%ld", sw_status);
+		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+		}
+		goto err;
+		}
+	/* Prepare the argument and response */
+	arg[0].nbytes = dgst_len;
+	arg[0].value = (unsigned char *)dgst;
+	arg[1].nbytes = 40;
+	arg[1].value = (unsigned char *)argument->d;
+	memset(arg[1].value, 0, 40);
+	BN_bn2bin(sig->r, arg[1].value + 20 - BN_num_bytes(sig->r));
+	BN_bn2bin(sig->s, arg[1].value + 40 - BN_num_bytes(sig->s));
+	res.nbytes = 4; /* unsigned long */
+	res.value = (unsigned char *)(&sig_result);
+	/* Perform the operation */
+	sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_VERIFY, arg, 2,
+		&res, 1);
+	if(sw_status != SW_OK)
+		{
+		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
+		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
+		sprintf(tmpbuf, "%ld", sw_status);
+		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+		goto err;
+		}
+	/* Convert the response */
+	to_return = ((sig_result == 0) ? 0 : 1);
+
+err:
+	if(acquired)
+		release_context(hac);
+	if(ctx)
+		{
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+		}
+	return to_return;
+	}
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
+		const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+	{
+	return cswift_mod_exp(r, a, p, m, ctx);
+	}
+#endif
+
+/* Random bytes are good */
+static int cswift_rand_bytes(unsigned char *buf, int num)
+{
+	SW_CONTEXT_HANDLE hac;
+	SW_STATUS swrc;
+	SW_LARGENUMBER largenum;
+	int acquired = 0;
+	int to_return = 0; /* assume failure */
+	unsigned char buf32[1024];
+
+
+	if (!get_context(&hac))
+	{
+		CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_UNIT_FAILURE);
+		goto err;
+	}
+	acquired = 1;
+
+	/************************************************************************/
+	/* 04/02/2003                                                           */
+	/* Modified by Frederic Giudicelli (deny-all.com) to overcome the       */
+	/* limitation of cswift with values not a multiple of 32                */
+	/************************************************************************/
+
+	while(num >= (int)sizeof(buf32))
+	{
+		largenum.value = buf;
+		largenum.nbytes = sizeof(buf32);
+		/* tell CryptoSwift how many bytes we want and where we want it.
+		 * Note: - CryptoSwift cannot do more than 4096 bytes at a time.
+		 *       - CryptoSwift can only do multiple of 32-bits. */
+		swrc = p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1);
+		if (swrc != SW_OK)
+		{
+			char tmpbuf[20];
+			CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_REQUEST_FAILED);
+			sprintf(tmpbuf, "%ld", swrc);
+			ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf);
+			goto err;
+		}
+		buf += sizeof(buf32);
+		num -= sizeof(buf32);
+	}
+	if(num)
+	{
+		largenum.nbytes = sizeof(buf32);
+		largenum.value = buf32;
+		swrc = p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1);
+		if (swrc != SW_OK)
+		{
+			char tmpbuf[20];
+			CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_REQUEST_FAILED);
+			sprintf(tmpbuf, "%ld", swrc);
+			ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf);
+			goto err;
+		}
+		memcpy(buf, largenum.value, num);
+	}
+
+	to_return = 1;  /* success */
+err:
+	if (acquired)
+		release_context(hac);
+
+	return to_return;
+}
+
+static int cswift_rand_status(void)
+{
+	return 1;
+}
+
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library. */
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_fn(ENGINE *e, const char *id)
+	{
+	if(id && (strcmp(id, engine_cswift_id) != 0))
+		return 0;
+	if(!bind_helper(e))
+		return 0;
+	return 1;
+	}       
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
+
+#endif /* !OPENSSL_NO_HW_CSWIFT */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_cswift.ec b/openssl/engines/e_cswift.ec
new file mode 100644
index 0000000..a7f9d11
--- /dev/null
+++ b/openssl/engines/e_cswift.ec
@@ -0,0 +1 @@
+L CSWIFT	e_cswift_err.h			e_cswift_err.c
diff --git a/openssl/engines/e_cswift_err.c b/openssl/engines/e_cswift_err.c
new file mode 100644
index 0000000..c7942a3
--- /dev/null
+++ b/openssl/engines/e_cswift_err.c
@@ -0,0 +1,154 @@
+/* e_cswift_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "e_cswift_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA CSWIFT_str_functs[]=
+	{
+{ERR_FUNC(CSWIFT_F_CSWIFT_CTRL),	"CSWIFT_CTRL"},
+{ERR_FUNC(CSWIFT_F_CSWIFT_DSA_SIGN),	"CSWIFT_DSA_SIGN"},
+{ERR_FUNC(CSWIFT_F_CSWIFT_DSA_VERIFY),	"CSWIFT_DSA_VERIFY"},
+{ERR_FUNC(CSWIFT_F_CSWIFT_FINISH),	"CSWIFT_FINISH"},
+{ERR_FUNC(CSWIFT_F_CSWIFT_INIT),	"CSWIFT_INIT"},
+{ERR_FUNC(CSWIFT_F_CSWIFT_MOD_EXP),	"CSWIFT_MOD_EXP"},
+{ERR_FUNC(CSWIFT_F_CSWIFT_MOD_EXP_CRT),	"CSWIFT_MOD_EXP_CRT"},
+{ERR_FUNC(CSWIFT_F_CSWIFT_RAND_BYTES),	"CSWIFT_RAND_BYTES"},
+{ERR_FUNC(CSWIFT_F_CSWIFT_RSA_MOD_EXP),	"CSWIFT_RSA_MOD_EXP"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA CSWIFT_str_reasons[]=
+	{
+{ERR_REASON(CSWIFT_R_ALREADY_LOADED)     ,"already loaded"},
+{ERR_REASON(CSWIFT_R_BAD_KEY_SIZE)       ,"bad key size"},
+{ERR_REASON(CSWIFT_R_BN_CTX_FULL)        ,"bn ctx full"},
+{ERR_REASON(CSWIFT_R_BN_EXPAND_FAIL)     ,"bn expand fail"},
+{ERR_REASON(CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
+{ERR_REASON(CSWIFT_R_MISSING_KEY_COMPONENTS),"missing key components"},
+{ERR_REASON(CSWIFT_R_NOT_LOADED)         ,"not loaded"},
+{ERR_REASON(CSWIFT_R_REQUEST_FAILED)     ,"request failed"},
+{ERR_REASON(CSWIFT_R_UNIT_FAILURE)       ,"unit failure"},
+{0,NULL}
+	};
+
+#endif
+
+#ifdef CSWIFT_LIB_NAME
+static ERR_STRING_DATA CSWIFT_lib_name[]=
+        {
+{0	,CSWIFT_LIB_NAME},
+{0,NULL}
+	};
+#endif
+
+
+static int CSWIFT_lib_error_code=0;
+static int CSWIFT_error_init=1;
+
+static void ERR_load_CSWIFT_strings(void)
+	{
+	if (CSWIFT_lib_error_code == 0)
+		CSWIFT_lib_error_code=ERR_get_next_error_library();
+
+	if (CSWIFT_error_init)
+		{
+		CSWIFT_error_init=0;
+#ifndef OPENSSL_NO_ERR
+		ERR_load_strings(CSWIFT_lib_error_code,CSWIFT_str_functs);
+		ERR_load_strings(CSWIFT_lib_error_code,CSWIFT_str_reasons);
+#endif
+
+#ifdef CSWIFT_LIB_NAME
+		CSWIFT_lib_name->error = ERR_PACK(CSWIFT_lib_error_code,0,0);
+		ERR_load_strings(0,CSWIFT_lib_name);
+#endif
+		}
+	}
+
+static void ERR_unload_CSWIFT_strings(void)
+	{
+	if (CSWIFT_error_init == 0)
+		{
+#ifndef OPENSSL_NO_ERR
+		ERR_unload_strings(CSWIFT_lib_error_code,CSWIFT_str_functs);
+		ERR_unload_strings(CSWIFT_lib_error_code,CSWIFT_str_reasons);
+#endif
+
+#ifdef CSWIFT_LIB_NAME
+		ERR_unload_strings(0,CSWIFT_lib_name);
+#endif
+		CSWIFT_error_init=1;
+		}
+	}
+
+static void ERR_CSWIFT_error(int function, int reason, char *file, int line)
+	{
+	if (CSWIFT_lib_error_code == 0)
+		CSWIFT_lib_error_code=ERR_get_next_error_library();
+	ERR_PUT_error(CSWIFT_lib_error_code,function,reason,file,line);
+	}
diff --git a/openssl/engines/e_cswift_err.h b/openssl/engines/e_cswift_err.h
new file mode 100644
index 0000000..69c2a9f
--- /dev/null
+++ b/openssl/engines/e_cswift_err.h
@@ -0,0 +1,98 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_CSWIFT_ERR_H
+#define HEADER_CSWIFT_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_CSWIFT_strings(void);
+static void ERR_unload_CSWIFT_strings(void);
+static void ERR_CSWIFT_error(int function, int reason, char *file, int line);
+#define CSWIFTerr(f,r) ERR_CSWIFT_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the CSWIFT functions. */
+
+/* Function codes. */
+#define CSWIFT_F_CSWIFT_CTRL				 100
+#define CSWIFT_F_CSWIFT_DSA_SIGN			 101
+#define CSWIFT_F_CSWIFT_DSA_VERIFY			 102
+#define CSWIFT_F_CSWIFT_FINISH				 103
+#define CSWIFT_F_CSWIFT_INIT				 104
+#define CSWIFT_F_CSWIFT_MOD_EXP				 105
+#define CSWIFT_F_CSWIFT_MOD_EXP_CRT			 106
+#define CSWIFT_F_CSWIFT_RAND_BYTES			 108
+#define CSWIFT_F_CSWIFT_RSA_MOD_EXP			 107
+
+/* Reason codes. */
+#define CSWIFT_R_ALREADY_LOADED				 100
+#define CSWIFT_R_BAD_KEY_SIZE				 101
+#define CSWIFT_R_BN_CTX_FULL				 102
+#define CSWIFT_R_BN_EXPAND_FAIL				 103
+#define CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED		 104
+#define CSWIFT_R_MISSING_KEY_COMPONENTS			 105
+#define CSWIFT_R_NOT_LOADED				 106
+#define CSWIFT_R_REQUEST_FAILED				 107
+#define CSWIFT_R_UNIT_FAILURE				 108
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_gmp.c b/openssl/engines/e_gmp.c
new file mode 100644
index 0000000..a3d4715
--- /dev/null
+++ b/openssl/engines/e_gmp.c
@@ -0,0 +1,480 @@
+/* crypto/engine/e_gmp.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2003.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* This engine is not (currently) compiled in by default. Do enable it,
+ * reconfigure OpenSSL with "enable-gmp -lgmp". The GMP libraries and
+ * headers must reside in one of the paths searched by the compiler/linker,
+ * otherwise paths must be specified - eg. try configuring with
+ * "enable-gmp -I<includepath> -L<libpath> -lgmp". YMMV. */
+
+/* As for what this does - it's a largely unoptimised implementation of an
+ * ENGINE that uses the GMP library to perform RSA private key operations. To
+ * obtain more information about what "unoptimised" means, see my original mail
+ * on the subject (though ignore the build instructions which have since
+ * changed);
+ *
+ *    http://www.mail-archive.com/openssl-dev@openssl.org/msg12227.html
+ *
+ * On my athlon system at least, it appears the builtin OpenSSL code is now
+ * slightly faster, which is to say that the RSA-related MPI performance
+ * between OpenSSL's BIGNUM and GMP's mpz implementations is probably pretty
+ * balanced for this chip, and so the performance degradation in this ENGINE by
+ * having to convert to/from GMP formats (and not being able to cache
+ * montgomery forms) is probably the difference. However, if some unconfirmed
+ * reports from users is anything to go by, the situation on some other
+ * chipsets might be a good deal more favourable to the GMP version (eg. PPC).
+ * Feedback welcome. */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/engine.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_GMP
+
+#include <gmp.h>
+
+#define E_GMP_LIB_NAME "gmp engine"
+#include "e_gmp_err.c"
+
+static int e_gmp_destroy(ENGINE *e);
+static int e_gmp_init(ENGINE *e);
+static int e_gmp_finish(ENGINE *e);
+static int e_gmp_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)); 
+
+#ifndef OPENSSL_NO_RSA
+/* RSA stuff */
+static int e_gmp_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+static int e_gmp_rsa_finish(RSA *r);
+#endif
+
+/* The definitions for control commands specific to this engine */
+/* #define E_GMP_CMD_SO_PATH		ENGINE_CMD_BASE */
+static const ENGINE_CMD_DEFN e_gmp_cmd_defns[] = {
+#if 0
+	{E_GMP_CMD_SO_PATH,
+		"SO_PATH",
+		"Specifies the path to the 'e_gmp' shared library",
+		ENGINE_CMD_FLAG_STRING},
+#endif
+	{0, NULL, NULL, 0}
+	};
+
+#ifndef OPENSSL_NO_RSA
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD e_gmp_rsa =
+	{
+	"GMP RSA method",
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	e_gmp_rsa_mod_exp,
+	NULL,
+	NULL,
+	e_gmp_rsa_finish,
+	/* These flags initialise montgomery crud that GMP ignores, however it
+	 * makes sure the public key ops (which are done in openssl) don't seem
+	 * *slower* than usual :-) */
+	RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE,
+	NULL,
+	NULL,
+	NULL
+	};
+#endif
+
+/* Constants used when creating the ENGINE */
+static const char *engine_e_gmp_id = "gmp";
+static const char *engine_e_gmp_name = "GMP engine support";
+
+/* This internal function is used by ENGINE_gmp() and possibly by the
+ * "dynamic" ENGINE support too */
+static int bind_helper(ENGINE *e)
+	{
+#ifndef OPENSSL_NO_RSA
+	const RSA_METHOD *meth1;
+#endif
+	if(!ENGINE_set_id(e, engine_e_gmp_id) ||
+			!ENGINE_set_name(e, engine_e_gmp_name) ||
+#ifndef OPENSSL_NO_RSA
+			!ENGINE_set_RSA(e, &e_gmp_rsa) ||
+#endif
+			!ENGINE_set_destroy_function(e, e_gmp_destroy) ||
+			!ENGINE_set_init_function(e, e_gmp_init) ||
+			!ENGINE_set_finish_function(e, e_gmp_finish) ||
+			!ENGINE_set_ctrl_function(e, e_gmp_ctrl) ||
+			!ENGINE_set_cmd_defns(e, e_gmp_cmd_defns))
+		return 0;
+
+#ifndef OPENSSL_NO_RSA
+	meth1 = RSA_PKCS1_SSLeay();
+	e_gmp_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+	e_gmp_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+	e_gmp_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+	e_gmp_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+	e_gmp_rsa.bn_mod_exp = meth1->bn_mod_exp;
+#endif
+
+	/* Ensure the e_gmp error handling is set up */
+	ERR_load_GMP_strings();
+	return 1;
+	}
+
+static ENGINE *engine_gmp(void)
+	{
+	ENGINE *ret = ENGINE_new();
+	if(!ret)
+		return NULL;
+	if(!bind_helper(ret))
+		{
+		ENGINE_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+void ENGINE_load_gmp(void)
+	{
+	/* Copied from eng_[openssl|dyn].c */
+	ENGINE *toadd = engine_gmp();
+	if(!toadd) return;
+	ENGINE_add(toadd);
+	ENGINE_free(toadd);
+	ERR_clear_error();
+	}
+
+#ifndef OPENSSL_NO_RSA
+/* Used to attach our own key-data to an RSA structure */
+static int hndidx_rsa = -1;
+#endif
+
+static int e_gmp_destroy(ENGINE *e)
+	{
+	ERR_unload_GMP_strings();
+	return 1;
+	}
+
+/* (de)initialisation functions. */
+static int e_gmp_init(ENGINE *e)
+	{
+#ifndef OPENSSL_NO_RSA
+	if (hndidx_rsa == -1)
+		hndidx_rsa = RSA_get_ex_new_index(0,
+			"GMP-based RSA key handle",
+			NULL, NULL, NULL);
+#endif
+	if (hndidx_rsa == -1)
+		return 0;
+	return 1;
+	}
+
+static int e_gmp_finish(ENGINE *e)
+	{
+	return 1;
+	}
+
+static int e_gmp_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+	{
+	int to_return = 1;
+
+	switch(cmd)
+		{
+#if 0
+	case E_GMP_CMD_SO_PATH:
+		/* ... */
+#endif
+	/* The command isn't understood by this engine */
+	default:
+		GMPerr(GMP_F_E_GMP_CTRL,
+			GMP_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+		to_return = 0;
+		break;
+		}
+
+	return to_return;
+	}
+
+
+/* Most often limb sizes will be the same. If not, we use hex conversion
+ * which is neat, but extremely inefficient. */
+static int bn2gmp(const BIGNUM *bn, mpz_t g)
+	{
+	bn_check_top(bn);
+	if(((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) &&
+			(BN_BITS2 == GMP_NUMB_BITS)) 
+		{
+		/* The common case */
+		if(!_mpz_realloc (g, bn->top))
+			return 0;
+		memcpy(&g->_mp_d[0], &bn->d[0], bn->top * sizeof(bn->d[0]));
+		g->_mp_size = bn->top;
+		if(bn->neg)
+			g->_mp_size = -g->_mp_size;
+		return 1;
+		}
+	else
+		{
+		int toret;
+		char *tmpchar = BN_bn2hex(bn);
+		if(!tmpchar) return 0;
+		toret = (mpz_set_str(g, tmpchar, 16) == 0 ? 1 : 0);
+		OPENSSL_free(tmpchar);
+		return toret;
+		}
+	}
+
+static int gmp2bn(mpz_t g, BIGNUM *bn)
+	{
+	if(((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) &&
+			(BN_BITS2 == GMP_NUMB_BITS))
+		{
+		/* The common case */
+		int s = (g->_mp_size >= 0) ? g->_mp_size : -g->_mp_size;
+		BN_zero(bn);
+		if(bn_expand2 (bn, s) == NULL)
+			return 0;
+		bn->top = s;
+		memcpy(&bn->d[0], &g->_mp_d[0], s * sizeof(bn->d[0]));
+		bn_correct_top(bn);
+		bn->neg = g->_mp_size >= 0 ? 0 : 1;
+		return 1;
+		}
+	else
+		{
+		int toret;
+		char *tmpchar = OPENSSL_malloc(mpz_sizeinbase(g, 16) + 10);
+		if(!tmpchar) return 0;
+		mpz_get_str(tmpchar, 16, g);
+		toret = BN_hex2bn(&bn, tmpchar);
+		OPENSSL_free(tmpchar);
+		return toret;
+		}
+	}
+
+#ifndef OPENSSL_NO_RSA 
+typedef struct st_e_gmp_rsa_ctx
+	{
+	int public_only;
+	mpz_t n;
+	mpz_t d;
+	mpz_t e;
+	mpz_t p;
+	mpz_t q;
+	mpz_t dmp1;
+	mpz_t dmq1;
+	mpz_t iqmp;
+	mpz_t r0, r1, I0, m1;
+	} E_GMP_RSA_CTX;
+
+static E_GMP_RSA_CTX *e_gmp_get_rsa(RSA *rsa)
+	{
+	E_GMP_RSA_CTX *hptr = RSA_get_ex_data(rsa, hndidx_rsa);
+	if(hptr) return hptr;
+	hptr = OPENSSL_malloc(sizeof(E_GMP_RSA_CTX));
+	if(!hptr) return NULL;
+	/* These inits could probably be replaced by more intelligent
+	 * mpz_init2() versions, to reduce malloc-thrashing. */
+	mpz_init(hptr->n);
+	mpz_init(hptr->d);
+	mpz_init(hptr->e);
+	mpz_init(hptr->p);
+	mpz_init(hptr->q);
+	mpz_init(hptr->dmp1);
+	mpz_init(hptr->dmq1);
+	mpz_init(hptr->iqmp);
+	mpz_init(hptr->r0);
+	mpz_init(hptr->r1);
+	mpz_init(hptr->I0);
+	mpz_init(hptr->m1);
+	if(!bn2gmp(rsa->n, hptr->n) || !bn2gmp(rsa->e, hptr->e))
+		goto err;
+	if(!rsa->p || !rsa->q || !rsa->d || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
+		{
+		hptr->public_only = 1;
+		return hptr;
+		}
+	if(!bn2gmp(rsa->d, hptr->d) || !bn2gmp(rsa->p, hptr->p) ||
+			!bn2gmp(rsa->q, hptr->q) || !bn2gmp(rsa->dmp1, hptr->dmp1) ||
+			!bn2gmp(rsa->dmq1, hptr->dmq1) || !bn2gmp(rsa->iqmp, hptr->iqmp))
+		goto err;
+	hptr->public_only = 0;
+	RSA_set_ex_data(rsa, hndidx_rsa, hptr);
+	return hptr;
+err:
+	mpz_clear(hptr->n);
+	mpz_clear(hptr->d);
+	mpz_clear(hptr->e);
+	mpz_clear(hptr->p);
+	mpz_clear(hptr->q);
+	mpz_clear(hptr->dmp1);
+	mpz_clear(hptr->dmq1);
+	mpz_clear(hptr->iqmp);
+	mpz_clear(hptr->r0);
+	mpz_clear(hptr->r1);
+	mpz_clear(hptr->I0);
+	mpz_clear(hptr->m1);
+	OPENSSL_free(hptr);
+	return NULL;
+	}
+
+static int e_gmp_rsa_finish(RSA *rsa)
+	{
+	E_GMP_RSA_CTX *hptr = RSA_get_ex_data(rsa, hndidx_rsa);
+	if(!hptr) return 0;
+	mpz_clear(hptr->n);
+	mpz_clear(hptr->d);
+	mpz_clear(hptr->e);
+	mpz_clear(hptr->p);
+	mpz_clear(hptr->q);
+	mpz_clear(hptr->dmp1);
+	mpz_clear(hptr->dmq1);
+	mpz_clear(hptr->iqmp);
+	mpz_clear(hptr->r0);
+	mpz_clear(hptr->r1);
+	mpz_clear(hptr->I0);
+	mpz_clear(hptr->m1);
+	OPENSSL_free(hptr);
+	RSA_set_ex_data(rsa, hndidx_rsa, NULL);
+	return 1;
+	}
+
+static int e_gmp_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+	{
+	E_GMP_RSA_CTX *hptr;
+	int to_return = 0;
+
+	hptr = e_gmp_get_rsa(rsa);
+	if(!hptr)
+		{
+		GMPerr(GMP_F_E_GMP_RSA_MOD_EXP,
+				GMP_R_KEY_CONTEXT_ERROR);
+		return 0;
+		}
+	if(hptr->public_only)
+		{
+		GMPerr(GMP_F_E_GMP_RSA_MOD_EXP,
+				GMP_R_MISSING_KEY_COMPONENTS);
+		return 0;
+		}
+
+	/* ugh!!! */
+	if(!bn2gmp(I, hptr->I0))
+		return 0;
+
+	/* This is basically the CRT logic in crypto/rsa/rsa_eay.c reworded into
+	 * GMP-speak. It may be that GMP's API facilitates cleaner formulations
+	 * of this stuff, eg. better handling of negatives, or functions that
+	 * combine operations. */
+
+	mpz_mod(hptr->r1, hptr->I0, hptr->q);
+	mpz_powm(hptr->m1, hptr->r1, hptr->dmq1, hptr->q);
+
+	mpz_mod(hptr->r1, hptr->I0, hptr->p);
+	mpz_powm(hptr->r0, hptr->r1, hptr->dmp1, hptr->p);
+
+	mpz_sub(hptr->r0, hptr->r0, hptr->m1);
+
+	if(mpz_sgn(hptr->r0) < 0)
+		mpz_add(hptr->r0, hptr->r0, hptr->p);
+	mpz_mul(hptr->r1, hptr->r0, hptr->iqmp);
+	mpz_mod(hptr->r0, hptr->r1, hptr->p);
+
+	if(mpz_sgn(hptr->r0) < 0)
+		mpz_add(hptr->r0, hptr->r0, hptr->p);
+	mpz_mul(hptr->r1, hptr->r0, hptr->q);
+	mpz_add(hptr->r0, hptr->r1, hptr->m1);
+
+	/* ugh!!! */
+	if(gmp2bn(hptr->r0, r))
+		to_return = 1;
+
+	return 1;
+	}
+#endif
+
+#endif /* !OPENSSL_NO_GMP */
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library. */	   
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+IMPLEMENT_DYNAMIC_CHECK_FN()
+#ifndef OPENSSL_NO_GMP
+static int bind_fn(ENGINE *e, const char *id)
+	{
+	if(id && (strcmp(id, engine_e_gmp_id) != 0))
+		return 0;
+	if(!bind_helper(e))
+		return 0;
+	return 1;
+	}       
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#else
+OPENSSL_EXPORT
+int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
+OPENSSL_EXPORT
+int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
+#endif
+#endif /* !OPENSSL_NO_DYNAMIC_ENGINE */
+
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_gmp.ec b/openssl/engines/e_gmp.ec
new file mode 100644
index 0000000..72ec447
--- /dev/null
+++ b/openssl/engines/e_gmp.ec
@@ -0,0 +1 @@
+L GMP		e_gmp_err.h			e_gmp_err.c
diff --git a/openssl/engines/e_gmp_err.c b/openssl/engines/e_gmp_err.c
new file mode 100644
index 0000000..61db956
--- /dev/null
+++ b/openssl/engines/e_gmp_err.c
@@ -0,0 +1,141 @@
+/* e_gmp_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "e_gmp_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA GMP_str_functs[]=
+	{
+{ERR_FUNC(GMP_F_E_GMP_CTRL),	"E_GMP_CTRL"},
+{ERR_FUNC(GMP_F_E_GMP_RSA_MOD_EXP),	"E_GMP_RSA_MOD_EXP"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA GMP_str_reasons[]=
+	{
+{ERR_REASON(GMP_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
+{ERR_REASON(GMP_R_KEY_CONTEXT_ERROR)     ,"key context error"},
+{ERR_REASON(GMP_R_MISSING_KEY_COMPONENTS),"missing key components"},
+{0,NULL}
+	};
+
+#endif
+
+#ifdef GMP_LIB_NAME
+static ERR_STRING_DATA GMP_lib_name[]=
+        {
+{0	,GMP_LIB_NAME},
+{0,NULL}
+	};
+#endif
+
+
+static int GMP_lib_error_code=0;
+static int GMP_error_init=1;
+
+static void ERR_load_GMP_strings(void)
+	{
+	if (GMP_lib_error_code == 0)
+		GMP_lib_error_code=ERR_get_next_error_library();
+
+	if (GMP_error_init)
+		{
+		GMP_error_init=0;
+#ifndef OPENSSL_NO_ERR
+		ERR_load_strings(GMP_lib_error_code,GMP_str_functs);
+		ERR_load_strings(GMP_lib_error_code,GMP_str_reasons);
+#endif
+
+#ifdef GMP_LIB_NAME
+		GMP_lib_name->error = ERR_PACK(GMP_lib_error_code,0,0);
+		ERR_load_strings(0,GMP_lib_name);
+#endif
+		}
+	}
+
+static void ERR_unload_GMP_strings(void)
+	{
+	if (GMP_error_init == 0)
+		{
+#ifndef OPENSSL_NO_ERR
+		ERR_unload_strings(GMP_lib_error_code,GMP_str_functs);
+		ERR_unload_strings(GMP_lib_error_code,GMP_str_reasons);
+#endif
+
+#ifdef GMP_LIB_NAME
+		ERR_unload_strings(0,GMP_lib_name);
+#endif
+		GMP_error_init=1;
+		}
+	}
+
+static void ERR_GMP_error(int function, int reason, char *file, int line)
+	{
+	if (GMP_lib_error_code == 0)
+		GMP_lib_error_code=ERR_get_next_error_library();
+	ERR_PUT_error(GMP_lib_error_code,function,reason,file,line);
+	}
diff --git a/openssl/engines/e_gmp_err.h b/openssl/engines/e_gmp_err.h
new file mode 100644
index 0000000..dd05dfd
--- /dev/null
+++ b/openssl/engines/e_gmp_err.h
@@ -0,0 +1,85 @@
+/* ====================================================================
+ * Copyright (c) 2001-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_GMP_ERR_H
+#define HEADER_GMP_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_GMP_strings(void);
+static void ERR_unload_GMP_strings(void);
+static void ERR_GMP_error(int function, int reason, char *file, int line);
+#define GMPerr(f,r) ERR_GMP_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the GMP functions. */
+
+/* Function codes. */
+#define GMP_F_E_GMP_CTRL				 100
+#define GMP_F_E_GMP_RSA_MOD_EXP				 101
+
+/* Reason codes. */
+#define GMP_R_CTRL_COMMAND_NOT_IMPLEMENTED		 100
+#define GMP_R_KEY_CONTEXT_ERROR				 101
+#define GMP_R_MISSING_KEY_COMPONENTS			 102
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_nuron.c b/openssl/engines/e_nuron.c
new file mode 100644
index 0000000..4c2537c
--- /dev/null
+++ b/openssl/engines/e_nuron.c
@@ -0,0 +1,434 @@
+/* crypto/engine/hw_nuron.c */
+/* Written by Ben Laurie for the OpenSSL Project, leaning heavily on Geoff
+ * Thorpe's Atalla implementation.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/dso.h>
+#include <openssl/engine.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_NURON
+
+#define NURON_LIB_NAME "nuron engine"
+#include "e_nuron_err.c"
+
+static const char *NURON_LIBNAME = NULL;
+static const char *get_NURON_LIBNAME(void)
+	{
+	if(NURON_LIBNAME)
+		return NURON_LIBNAME;
+	return "nuronssl";
+	}
+static void free_NURON_LIBNAME(void)
+	{
+	if(NURON_LIBNAME)
+		OPENSSL_free((void*)NURON_LIBNAME);
+	NURON_LIBNAME = NULL;
+	}
+static long set_NURON_LIBNAME(const char *name)
+	{
+	free_NURON_LIBNAME();
+	return (((NURON_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
+	}
+static const char *NURON_F1 = "nuron_mod_exp";
+
+/* The definitions for control commands specific to this engine */
+#define NURON_CMD_SO_PATH		ENGINE_CMD_BASE
+static const ENGINE_CMD_DEFN nuron_cmd_defns[] = {
+	{NURON_CMD_SO_PATH,
+		"SO_PATH",
+		"Specifies the path to the 'nuronssl' shared library",
+		ENGINE_CMD_FLAG_STRING},
+	{0, NULL, NULL, 0}
+	};
+
+typedef int tfnModExp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,const BIGNUM *m);
+static tfnModExp *pfnModExp = NULL;
+
+static DSO *pvDSOHandle = NULL;
+
+static int nuron_destroy(ENGINE *e)
+	{
+	free_NURON_LIBNAME();
+	ERR_unload_NURON_strings();
+	return 1;
+	}
+
+static int nuron_init(ENGINE *e)
+	{
+	if(pvDSOHandle != NULL)
+		{
+		NURONerr(NURON_F_NURON_INIT,NURON_R_ALREADY_LOADED);
+		return 0;
+		}
+
+	pvDSOHandle = DSO_load(NULL, get_NURON_LIBNAME(), NULL,
+		DSO_FLAG_NAME_TRANSLATION_EXT_ONLY);
+	if(!pvDSOHandle)
+		{
+		NURONerr(NURON_F_NURON_INIT,NURON_R_DSO_NOT_FOUND);
+		return 0;
+		}
+
+	pfnModExp = (tfnModExp *)DSO_bind_func(pvDSOHandle, NURON_F1);
+	if(!pfnModExp)
+		{
+		NURONerr(NURON_F_NURON_INIT,NURON_R_DSO_FUNCTION_NOT_FOUND);
+		return 0;
+		}
+
+	return 1;
+	}
+
+static int nuron_finish(ENGINE *e)
+	{
+	free_NURON_LIBNAME();
+	if(pvDSOHandle == NULL)
+		{
+		NURONerr(NURON_F_NURON_FINISH,NURON_R_NOT_LOADED);
+		return 0;
+		}
+	if(!DSO_free(pvDSOHandle))
+		{
+		NURONerr(NURON_F_NURON_FINISH,NURON_R_DSO_FAILURE);
+		return 0;
+		}
+	pvDSOHandle=NULL;
+	pfnModExp=NULL;
+	return 1;
+	}
+
+static int nuron_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+	{
+	int initialised = ((pvDSOHandle == NULL) ? 0 : 1);
+	switch(cmd)
+		{
+	case NURON_CMD_SO_PATH:
+		if(p == NULL)
+			{
+			NURONerr(NURON_F_NURON_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+			return 0;
+			}
+		if(initialised)
+			{
+			NURONerr(NURON_F_NURON_CTRL,NURON_R_ALREADY_LOADED);
+			return 0;
+			}
+		return set_NURON_LIBNAME((const char *)p);
+	default:
+		break;
+		}
+	NURONerr(NURON_F_NURON_CTRL,NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+	return 0;
+}
+
+static int nuron_mod_exp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,
+			 const BIGNUM *m,BN_CTX *ctx)
+	{
+	if(!pvDSOHandle)
+		{
+		NURONerr(NURON_F_NURON_MOD_EXP,NURON_R_NOT_LOADED);
+		return 0;
+		}
+	return pfnModExp(r,a,p,m);
+	}
+
+#ifndef OPENSSL_NO_RSA
+static int nuron_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+	{
+	return nuron_mod_exp(r0,I,rsa->d,rsa->n,ctx);
+	}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* This code was liberated and adapted from the commented-out code in
+ * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration
+ * (it doesn't have a CRT form for RSA), this function means that an
+ * Atalla system running with a DSA server certificate can handshake
+ * around 5 or 6 times faster/more than an equivalent system running with
+ * RSA. Just check out the "signs" statistics from the RSA and DSA parts
+ * of "openssl speed -engine atalla dsa1024 rsa1024". */
+static int nuron_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
+			     BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
+			     BN_CTX *ctx, BN_MONT_CTX *in_mont)
+	{
+	BIGNUM t;
+	int to_return = 0;
+ 
+	BN_init(&t);
+	/* let rr = a1 ^ p1 mod m */
+	if (!nuron_mod_exp(rr,a1,p1,m,ctx))
+		goto end;
+	/* let t = a2 ^ p2 mod m */
+	if (!nuron_mod_exp(&t,a2,p2,m,ctx))
+		goto end;
+	/* let rr = rr * t mod m */
+	if (!BN_mod_mul(rr,rr,&t,m,ctx))
+		goto end;
+	to_return = 1;
+end:
+	BN_free(&t);
+	return to_return;
+	}
+
+
+static int nuron_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+			     const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+			     BN_MONT_CTX *m_ctx)
+	{
+	return nuron_mod_exp(r, a, p, m, ctx);
+	}
+#endif
+
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+#ifndef OPENSSL_NO_RSA
+static int nuron_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			      const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+	{
+	return nuron_mod_exp(r, a, p, m, ctx);
+	}
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int nuron_mod_exp_dh(const DH *dh, BIGNUM *r,
+		const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+	{
+	return nuron_mod_exp(r, a, p, m, ctx);
+	}
+#endif
+
+#ifndef OPENSSL_NO_RSA
+static RSA_METHOD nuron_rsa =
+	{
+	"Nuron RSA method",
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	nuron_rsa_mod_exp,
+	nuron_mod_exp_mont,
+	NULL,
+	NULL,
+	0,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+	};
+#endif
+
+#ifndef OPENSSL_NO_DSA
+static DSA_METHOD nuron_dsa =
+	{
+	"Nuron DSA method",
+	NULL, /* dsa_do_sign */
+	NULL, /* dsa_sign_setup */
+	NULL, /* dsa_do_verify */
+	nuron_dsa_mod_exp, /* dsa_mod_exp */
+	nuron_mod_exp_dsa, /* bn_mod_exp */
+	NULL, /* init */
+	NULL, /* finish */
+	0, /* flags */
+	NULL, /* app_data */
+	NULL, /* dsa_paramgen */
+	NULL /* dsa_keygen */
+	};
+#endif
+
+#ifndef OPENSSL_NO_DH
+static DH_METHOD nuron_dh =
+	{
+	"Nuron DH method",
+	NULL,
+	NULL,
+	nuron_mod_exp_dh,
+	NULL,
+	NULL,
+	0,
+	NULL,
+	NULL
+	};
+#endif
+
+/* Constants used when creating the ENGINE */
+static const char *engine_nuron_id = "nuron";
+static const char *engine_nuron_name = "Nuron hardware engine support";
+
+/* This internal function is used by ENGINE_nuron() and possibly by the
+ * "dynamic" ENGINE support too */
+static int bind_helper(ENGINE *e)
+	{
+#ifndef OPENSSL_NO_RSA
+	const RSA_METHOD *meth1;
+#endif
+#ifndef OPENSSL_NO_DSA
+	const DSA_METHOD *meth2;
+#endif
+#ifndef OPENSSL_NO_DH
+	const DH_METHOD *meth3;
+#endif
+	if(!ENGINE_set_id(e, engine_nuron_id) ||
+			!ENGINE_set_name(e, engine_nuron_name) ||
+#ifndef OPENSSL_NO_RSA
+			!ENGINE_set_RSA(e, &nuron_rsa) ||
+#endif
+#ifndef OPENSSL_NO_DSA
+			!ENGINE_set_DSA(e, &nuron_dsa) ||
+#endif
+#ifndef OPENSSL_NO_DH
+			!ENGINE_set_DH(e, &nuron_dh) ||
+#endif
+			!ENGINE_set_destroy_function(e, nuron_destroy) ||
+			!ENGINE_set_init_function(e, nuron_init) ||
+			!ENGINE_set_finish_function(e, nuron_finish) ||
+			!ENGINE_set_ctrl_function(e, nuron_ctrl) ||
+			!ENGINE_set_cmd_defns(e, nuron_cmd_defns))
+		return 0;
+
+#ifndef OPENSSL_NO_RSA
+	/* We know that the "PKCS1_SSLeay()" functions hook properly
+	 * to the nuron-specific mod_exp and mod_exp_crt so we use
+	 * those functions. NB: We don't use ENGINE_openssl() or
+	 * anything "more generic" because something like the RSAref
+	 * code may not hook properly, and if you own one of these
+	 * cards then you have the right to do RSA operations on it
+	 * anyway! */ 
+	meth1=RSA_PKCS1_SSLeay();
+	nuron_rsa.rsa_pub_enc=meth1->rsa_pub_enc;
+	nuron_rsa.rsa_pub_dec=meth1->rsa_pub_dec;
+	nuron_rsa.rsa_priv_enc=meth1->rsa_priv_enc;
+	nuron_rsa.rsa_priv_dec=meth1->rsa_priv_dec;
+#endif
+
+#ifndef OPENSSL_NO_DSA
+	/* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
+	 * bits. */
+	meth2=DSA_OpenSSL();
+	nuron_dsa.dsa_do_sign=meth2->dsa_do_sign;
+	nuron_dsa.dsa_sign_setup=meth2->dsa_sign_setup;
+	nuron_dsa.dsa_do_verify=meth2->dsa_do_verify;
+#endif
+
+#ifndef OPENSSL_NO_DH
+	/* Much the same for Diffie-Hellman */
+	meth3=DH_OpenSSL();
+	nuron_dh.generate_key=meth3->generate_key;
+	nuron_dh.compute_key=meth3->compute_key;
+#endif
+
+	/* Ensure the nuron error handling is set up */
+	ERR_load_NURON_strings();
+	return 1;
+	}
+
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+static ENGINE *engine_nuron(void)
+	{
+	ENGINE *ret = ENGINE_new();
+	if(!ret)
+		return NULL;
+	if(!bind_helper(ret))
+		{
+		ENGINE_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+void ENGINE_load_nuron(void)
+	{
+	/* Copied from eng_[openssl|dyn].c */
+	ENGINE *toadd = engine_nuron();
+	if(!toadd) return;
+	ENGINE_add(toadd);
+	ENGINE_free(toadd);
+	ERR_clear_error();
+	}
+#endif
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library. */	   
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_fn(ENGINE *e, const char *id)
+	{
+	if(id && (strcmp(id, engine_nuron_id) != 0))
+		return 0;
+	if(!bind_helper(e))
+		return 0;
+	return 1;
+	}       
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
+
+#endif /* !OPENSSL_NO_HW_NURON */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_nuron.ec b/openssl/engines/e_nuron.ec
new file mode 100644
index 0000000..cfa430d
--- /dev/null
+++ b/openssl/engines/e_nuron.ec
@@ -0,0 +1 @@
+L NURON		e_nuron_err.h			e_nuron_err.c
diff --git a/openssl/engines/e_nuron_err.c b/openssl/engines/e_nuron_err.c
new file mode 100644
index 0000000..9a7864f
--- /dev/null
+++ b/openssl/engines/e_nuron_err.c
@@ -0,0 +1,146 @@
+/* e_nuron_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "e_nuron_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA NURON_str_functs[]=
+	{
+{ERR_FUNC(NURON_F_NURON_CTRL),	"NURON_CTRL"},
+{ERR_FUNC(NURON_F_NURON_FINISH),	"NURON_FINISH"},
+{ERR_FUNC(NURON_F_NURON_INIT),	"NURON_INIT"},
+{ERR_FUNC(NURON_F_NURON_MOD_EXP),	"NURON_MOD_EXP"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA NURON_str_reasons[]=
+	{
+{ERR_REASON(NURON_R_ALREADY_LOADED)      ,"already loaded"},
+{ERR_REASON(NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
+{ERR_REASON(NURON_R_DSO_FAILURE)         ,"dso failure"},
+{ERR_REASON(NURON_R_DSO_FUNCTION_NOT_FOUND),"dso function not found"},
+{ERR_REASON(NURON_R_DSO_NOT_FOUND)       ,"dso not found"},
+{ERR_REASON(NURON_R_NOT_LOADED)          ,"not loaded"},
+{0,NULL}
+	};
+
+#endif
+
+#ifdef NURON_LIB_NAME
+static ERR_STRING_DATA NURON_lib_name[]=
+        {
+{0	,NURON_LIB_NAME},
+{0,NULL}
+	};
+#endif
+
+
+static int NURON_lib_error_code=0;
+static int NURON_error_init=1;
+
+static void ERR_load_NURON_strings(void)
+	{
+	if (NURON_lib_error_code == 0)
+		NURON_lib_error_code=ERR_get_next_error_library();
+
+	if (NURON_error_init)
+		{
+		NURON_error_init=0;
+#ifndef OPENSSL_NO_ERR
+		ERR_load_strings(NURON_lib_error_code,NURON_str_functs);
+		ERR_load_strings(NURON_lib_error_code,NURON_str_reasons);
+#endif
+
+#ifdef NURON_LIB_NAME
+		NURON_lib_name->error = ERR_PACK(NURON_lib_error_code,0,0);
+		ERR_load_strings(0,NURON_lib_name);
+#endif
+		}
+	}
+
+static void ERR_unload_NURON_strings(void)
+	{
+	if (NURON_error_init == 0)
+		{
+#ifndef OPENSSL_NO_ERR
+		ERR_unload_strings(NURON_lib_error_code,NURON_str_functs);
+		ERR_unload_strings(NURON_lib_error_code,NURON_str_reasons);
+#endif
+
+#ifdef NURON_LIB_NAME
+		ERR_unload_strings(0,NURON_lib_name);
+#endif
+		NURON_error_init=1;
+		}
+	}
+
+static void ERR_NURON_error(int function, int reason, char *file, int line)
+	{
+	if (NURON_lib_error_code == 0)
+		NURON_lib_error_code=ERR_get_next_error_library();
+	ERR_PUT_error(NURON_lib_error_code,function,reason,file,line);
+	}
diff --git a/openssl/engines/e_nuron_err.h b/openssl/engines/e_nuron_err.h
new file mode 100644
index 0000000..219babb
--- /dev/null
+++ b/openssl/engines/e_nuron_err.h
@@ -0,0 +1,90 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_NURON_ERR_H
+#define HEADER_NURON_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_NURON_strings(void);
+static void ERR_unload_NURON_strings(void);
+static void ERR_NURON_error(int function, int reason, char *file, int line);
+#define NURONerr(f,r) ERR_NURON_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the NURON functions. */
+
+/* Function codes. */
+#define NURON_F_NURON_CTRL				 100
+#define NURON_F_NURON_FINISH				 101
+#define NURON_F_NURON_INIT				 102
+#define NURON_F_NURON_MOD_EXP				 103
+
+/* Reason codes. */
+#define NURON_R_ALREADY_LOADED				 100
+#define NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED		 101
+#define NURON_R_DSO_FAILURE				 102
+#define NURON_R_DSO_FUNCTION_NOT_FOUND			 103
+#define NURON_R_DSO_NOT_FOUND				 104
+#define NURON_R_NOT_LOADED				 105
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_padlock.c b/openssl/engines/e_padlock.c
new file mode 100644
index 0000000..7d09419
--- /dev/null
+++ b/openssl/engines/e_padlock.c
@@ -0,0 +1,1233 @@
+/* 
+ * Support for VIA PadLock Advanced Cryptography Engine (ACE)
+ * Written by Michal Ludvig <michal@logix.cz>
+ *            http://www.logix.cz/michal
+ *
+ * Big thanks to Andy Polyakov for a help with optimization, 
+ * assembler fixes, port to MS Windows and a lot of other 
+ * valuable work on this engine!
+ */
+
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/opensslconf.h>
+#include <openssl/crypto.h>
+#include <openssl/dso.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_AES
+#include <openssl/aes.h>
+#endif
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_PADLOCK
+
+/* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */
+#if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
+#  ifndef OPENSSL_NO_DYNAMIC_ENGINE
+#    define DYNAMIC_ENGINE
+#  endif
+#elif (OPENSSL_VERSION_NUMBER >= 0x00907000L)
+#  ifdef ENGINE_DYNAMIC_SUPPORT
+#    define DYNAMIC_ENGINE
+#  endif
+#else
+#  error "Only OpenSSL >= 0.9.7 is supported"
+#endif
+
+/* VIA PadLock AES is available *ONLY* on some x86 CPUs.
+   Not only that it doesn't exist elsewhere, but it
+   even can't be compiled on other platforms!
+ 
+   In addition, because of the heavy use of inline assembler,
+   compiler choice is limited to GCC and Microsoft C. */
+#undef COMPILE_HW_PADLOCK
+#if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM)
+# if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \
+     (defined(_MSC_VER) && defined(_M_IX86))
+#  define COMPILE_HW_PADLOCK
+static ENGINE *ENGINE_padlock (void);
+# endif
+#endif
+
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+
+void ENGINE_load_padlock (void)
+{
+/* On non-x86 CPUs it just returns. */
+#ifdef COMPILE_HW_PADLOCK
+	ENGINE *toadd = ENGINE_padlock ();
+	if (!toadd) return;
+	ENGINE_add (toadd);
+	ENGINE_free (toadd);
+	ERR_clear_error ();
+#endif
+}
+
+#endif
+
+#ifdef COMPILE_HW_PADLOCK
+/* We do these includes here to avoid header problems on platforms that
+   do not have the VIA padlock anyway... */
+#include <stdlib.h>
+#ifdef _WIN32
+# include <malloc.h>
+# ifndef alloca
+#  define alloca _alloca
+# endif
+#elif defined(__GNUC__)
+# ifndef alloca
+#  define alloca(s) __builtin_alloca(s)
+# endif
+#endif
+
+/* Function for ENGINE detection and control */
+static int padlock_available(void);
+static int padlock_init(ENGINE *e);
+
+/* RNG Stuff */
+static RAND_METHOD padlock_rand;
+
+/* Cipher Stuff */
+#ifndef OPENSSL_NO_AES
+static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
+#endif
+
+/* Engine names */
+static const char *padlock_id = "padlock";
+static char padlock_name[100];
+
+/* Available features */
+static int padlock_use_ace = 0;	/* Advanced Cryptography Engine */
+static int padlock_use_rng = 0;	/* Random Number Generator */
+#ifndef OPENSSL_NO_AES
+static int padlock_aes_align_required = 1;
+#endif
+
+/* ===== Engine "management" functions ===== */
+
+/* Prepare the ENGINE structure for registration */
+static int
+padlock_bind_helper(ENGINE *e)
+{
+	/* Check available features */
+	padlock_available();
+
+#if 1	/* disable RNG for now, see commentary in vicinity of RNG code */
+	padlock_use_rng=0;
+#endif
+
+	/* Generate a nice engine name with available features */
+	BIO_snprintf(padlock_name, sizeof(padlock_name),
+		"VIA PadLock (%s, %s)", 
+		 padlock_use_rng ? "RNG" : "no-RNG",
+		 padlock_use_ace ? "ACE" : "no-ACE");
+
+	/* Register everything or return with an error */ 
+	if (!ENGINE_set_id(e, padlock_id) ||
+	    !ENGINE_set_name(e, padlock_name) ||
+
+	    !ENGINE_set_init_function(e, padlock_init) ||
+#ifndef OPENSSL_NO_AES
+	    (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) ||
+#endif
+	    (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) {
+		return 0;
+	}
+
+	/* Everything looks good */
+	return 1;
+}
+
+/* Constructor */
+static ENGINE *
+ENGINE_padlock(void)
+{
+	ENGINE *eng = ENGINE_new();
+
+	if (!eng) {
+		return NULL;
+	}
+
+	if (!padlock_bind_helper(eng)) {
+		ENGINE_free(eng);
+		return NULL;
+	}
+
+	return eng;
+}
+
+/* Check availability of the engine */
+static int
+padlock_init(ENGINE *e)
+{
+	return (padlock_use_rng || padlock_use_ace);
+}
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library.
+ */
+#ifdef DYNAMIC_ENGINE
+static int
+padlock_bind_fn(ENGINE *e, const char *id)
+{
+	if (id && (strcmp(id, padlock_id) != 0)) {
+		return 0;
+	}
+
+	if (!padlock_bind_helper(e))  {
+		return 0;
+	}
+
+	return 1;
+}
+
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn)
+#endif /* DYNAMIC_ENGINE */
+
+/* ===== Here comes the "real" engine ===== */
+
+#ifndef OPENSSL_NO_AES
+/* Some AES-related constants */
+#define AES_BLOCK_SIZE		16
+#define AES_KEY_SIZE_128	16
+#define AES_KEY_SIZE_192	24
+#define AES_KEY_SIZE_256	32
+
+/* Here we store the status information relevant to the 
+   current context. */
+/* BIG FAT WARNING:
+ * 	Inline assembler in PADLOCK_XCRYPT_ASM()
+ * 	depends on the order of items in this structure.
+ * 	Don't blindly modify, reorder, etc!
+ */
+struct padlock_cipher_data
+{
+	unsigned char iv[AES_BLOCK_SIZE];	/* Initialization vector */
+	union {	unsigned int pad[4];
+		struct {
+			int rounds:4;
+			int dgst:1;	/* n/a in C3 */
+			int align:1;	/* n/a in C3 */
+			int ciphr:1;	/* n/a in C3 */
+			unsigned int keygen:1;
+			int interm:1;
+			unsigned int encdec:1;
+			int ksize:2;
+		} b;
+	} cword;		/* Control word */
+	AES_KEY ks;		/* Encryption key */
+};
+
+/*
+ * Essentially this variable belongs in thread local storage.
+ * Having this variable global on the other hand can only cause
+ * few bogus key reloads [if any at all on single-CPU system],
+ * so we accept the penatly...
+ */
+static volatile struct padlock_cipher_data *padlock_saved_context;
+#endif
+
+/*
+ * =======================================================
+ * Inline assembler section(s).
+ * =======================================================
+ * Order of arguments is chosen to facilitate Windows port
+ * using __fastcall calling convention. If you wish to add
+ * more routines, keep in mind that first __fastcall
+ * argument is passed in %ecx and second - in %edx.
+ * =======================================================
+ */
+#if defined(__GNUC__) && __GNUC__>=2
+/*
+ * As for excessive "push %ebx"/"pop %ebx" found all over.
+ * When generating position-independent code GCC won't let
+ * us use "b" in assembler templates nor even respect "ebx"
+ * in "clobber description." Therefore the trouble...
+ */
+
+/* Helper function - check if a CPUID instruction
+   is available on this CPU */
+static int
+padlock_insn_cpuid_available(void)
+{
+	int result = -1;
+
+	/* We're checking if the bit #21 of EFLAGS 
+	   can be toggled. If yes = CPUID is available. */
+	asm volatile (
+		"pushf\n"
+		"popl %%eax\n"
+		"xorl $0x200000, %%eax\n"
+		"movl %%eax, %%ecx\n"
+		"andl $0x200000, %%ecx\n"
+		"pushl %%eax\n"
+		"popf\n"
+		"pushf\n"
+		"popl %%eax\n"
+		"andl $0x200000, %%eax\n"
+		"xorl %%eax, %%ecx\n"
+		"movl %%ecx, %0\n"
+		: "=r" (result) : : "eax", "ecx");
+	
+	return (result == 0);
+}
+
+/* Load supported features of the CPU to see if
+   the PadLock is available. */
+static int
+padlock_available(void)
+{
+	char vendor_string[16];
+	unsigned int eax, edx;
+
+	/* First check if the CPUID instruction is available at all... */
+	if (! padlock_insn_cpuid_available())
+		return 0;
+
+	/* Are we running on the Centaur (VIA) CPU? */
+	eax = 0x00000000;
+	vendor_string[12] = 0;
+	asm volatile (
+		"pushl	%%ebx\n"
+		"cpuid\n"
+		"movl	%%ebx,(%%edi)\n"
+		"movl	%%edx,4(%%edi)\n"
+		"movl	%%ecx,8(%%edi)\n"
+		"popl	%%ebx"
+		: "+a"(eax) : "D"(vendor_string) : "ecx", "edx");
+	if (strcmp(vendor_string, "CentaurHauls") != 0)
+		return 0;
+
+	/* Check for Centaur Extended Feature Flags presence */
+	eax = 0xC0000000;
+	asm volatile ("pushl %%ebx; cpuid; popl	%%ebx"
+		: "+a"(eax) : : "ecx", "edx");
+	if (eax < 0xC0000001)
+		return 0;
+
+	/* Read the Centaur Extended Feature Flags */
+	eax = 0xC0000001;
+	asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
+		: "+a"(eax), "=d"(edx) : : "ecx");
+
+	/* Fill up some flags */
+	padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6));
+	padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2));
+
+	return padlock_use_ace + padlock_use_rng;
+}
+
+#ifndef OPENSSL_NO_AES
+/* Our own htonl()/ntohl() */
+static inline void
+padlock_bswapl(AES_KEY *ks)
+{
+	size_t i = sizeof(ks->rd_key)/sizeof(ks->rd_key[0]);
+	unsigned int *key = ks->rd_key;
+
+	while (i--) {
+		asm volatile ("bswapl %0" : "+r"(*key));
+		key++;
+	}
+}
+#endif
+
+/* Force key reload from memory to the CPU microcode.
+   Loading EFLAGS from the stack clears EFLAGS[30] 
+   which does the trick. */
+static inline void
+padlock_reload_key(void)
+{
+	asm volatile ("pushfl; popfl");
+}
+
+#ifndef OPENSSL_NO_AES
+/*
+ * This is heuristic key context tracing. At first one
+ * believes that one should use atomic swap instructions,
+ * but it's not actually necessary. Point is that if
+ * padlock_saved_context was changed by another thread
+ * after we've read it and before we compare it with cdata,
+ * our key *shall* be reloaded upon thread context switch
+ * and we are therefore set in either case...
+ */
+static inline void
+padlock_verify_context(struct padlock_cipher_data *cdata)
+{
+	asm volatile (
+	"pushfl\n"
+"	btl	$30,(%%esp)\n"
+"	jnc	1f\n"
+"	cmpl	%2,%1\n"
+"	je	1f\n"
+"	popfl\n"
+"	subl	$4,%%esp\n"
+"1:	addl	$4,%%esp\n"
+"	movl	%2,%0"
+	:"+m"(padlock_saved_context)
+	: "r"(padlock_saved_context), "r"(cdata) : "cc");
+}
+
+/* Template for padlock_xcrypt_* modes */
+/* BIG FAT WARNING: 
+ * 	The offsets used with 'leal' instructions
+ * 	describe items of the 'padlock_cipher_data'
+ * 	structure.
+ */
+#define PADLOCK_XCRYPT_ASM(name,rep_xcrypt)	\
+static inline void *name(size_t cnt,		\
+	struct padlock_cipher_data *cdata,	\
+	void *out, const void *inp) 		\
+{	void *iv; 				\
+	asm volatile ( "pushl	%%ebx\n"	\
+		"	leal	16(%0),%%edx\n"	\
+		"	leal	32(%0),%%ebx\n"	\
+			rep_xcrypt "\n"		\
+		"	popl	%%ebx"		\
+		: "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \
+		: "0"(cdata), "1"(cnt), "2"(out), "3"(inp)  \
+		: "edx", "cc", "memory");	\
+	return iv;				\
+}
+
+/* Generate all functions with appropriate opcodes */
+PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8")	/* rep xcryptecb */
+PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0")	/* rep xcryptcbc */
+PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0")	/* rep xcryptcfb */
+PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8")	/* rep xcryptofb */
+#endif
+
+/* The RNG call itself */
+static inline unsigned int
+padlock_xstore(void *addr, unsigned int edx_in)
+{
+	unsigned int eax_out;
+
+	asm volatile (".byte 0x0f,0xa7,0xc0"	/* xstore */
+	    : "=a"(eax_out),"=m"(*(unsigned *)addr)
+	    : "D"(addr), "d" (edx_in)
+	    );
+
+	return eax_out;
+}
+
+/* Why not inline 'rep movsd'? I failed to find information on what
+ * value in Direction Flag one can expect and consequently have to
+ * apply "better-safe-than-sorry" approach and assume "undefined."
+ * I could explicitly clear it and restore the original value upon
+ * return from padlock_aes_cipher, but it's presumably too much
+ * trouble for too little gain...
+ *
+ * In case you wonder 'rep xcrypt*' instructions above are *not*
+ * affected by the Direction Flag and pointers advance toward
+ * larger addresses unconditionally.
+ */ 
+static inline unsigned char *
+padlock_memcpy(void *dst,const void *src,size_t n)
+{
+	long       *d=dst;
+	const long *s=src;
+
+	n /= sizeof(*d);
+	do { *d++ = *s++; } while (--n);
+
+	return dst;
+}
+
+#elif defined(_MSC_VER)
+/*
+ * Unlike GCC these are real functions. In order to minimize impact
+ * on performance we adhere to __fastcall calling convention in
+ * order to get two first arguments passed through %ecx and %edx.
+ * Which kind of suits very well, as instructions in question use
+ * both %ecx and %edx as input:-)
+ */
+#define REP_XCRYPT(code)		\
+	_asm _emit 0xf3			\
+	_asm _emit 0x0f _asm _emit 0xa7	\
+	_asm _emit code
+
+/* BIG FAT WARNING: 
+ * 	The offsets used with 'lea' instructions
+ * 	describe items of the 'padlock_cipher_data'
+ * 	structure.
+ */
+#define PADLOCK_XCRYPT_ASM(name,code)	\
+static void * __fastcall 		\
+	name (size_t cnt, void *cdata,	\
+	void *outp, const void *inp)	\
+{	_asm	mov	eax,edx		\
+	_asm	lea	edx,[eax+16]	\
+	_asm	lea	ebx,[eax+32]	\
+	_asm	mov	edi,outp	\
+	_asm	mov	esi,inp		\
+	REP_XCRYPT(code)		\
+}
+
+PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb,0xc8)
+PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc,0xd0)
+PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb,0xe0)
+PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb,0xe8)
+
+static int __fastcall
+padlock_xstore(void *outp,unsigned int code)
+{	_asm	mov	edi,ecx
+	_asm _emit 0x0f _asm _emit 0xa7 _asm _emit 0xc0
+}
+
+static void __fastcall
+padlock_reload_key(void)
+{	_asm pushfd _asm popfd		}
+
+static void __fastcall
+padlock_verify_context(void *cdata)
+{	_asm	{
+		pushfd
+		bt	DWORD PTR[esp],30
+		jnc	skip
+		cmp	ecx,padlock_saved_context
+		je	skip
+		popfd
+		sub	esp,4
+	skip:	add	esp,4
+		mov	padlock_saved_context,ecx
+		}
+}
+
+static int
+padlock_available(void)
+{	_asm	{
+		pushfd
+		pop	eax
+		mov	ecx,eax
+		xor	eax,1<<21
+		push	eax
+		popfd
+		pushfd
+		pop	eax
+		xor	eax,ecx
+		bt	eax,21
+		jnc	noluck
+		mov	eax,0
+		cpuid
+		xor	eax,eax
+		cmp	ebx,'tneC'
+		jne	noluck
+		cmp	edx,'Hrua'
+		jne	noluck
+		cmp	ecx,'slua'
+		jne	noluck
+		mov	eax,0xC0000000
+		cpuid
+		mov	edx,eax
+		xor	eax,eax
+		cmp	edx,0xC0000001
+		jb	noluck
+		mov	eax,0xC0000001
+		cpuid
+		xor	eax,eax
+		bt	edx,6
+		jnc	skip_a
+		bt	edx,7
+		jnc	skip_a
+		mov	padlock_use_ace,1
+		inc	eax
+	skip_a:	bt	edx,2
+		jnc	skip_r
+		bt	edx,3
+		jnc	skip_r
+		mov	padlock_use_rng,1
+		inc	eax
+	skip_r:
+	noluck:
+		}
+}
+
+static void __fastcall
+padlock_bswapl(void *key)
+{	_asm	{
+		pushfd
+		cld
+		mov	esi,ecx
+		mov	edi,ecx
+		mov	ecx,60
+	up:	lodsd
+		bswap	eax
+		stosd
+		loop	up
+		popfd
+		}
+}
+
+/* MS actually specifies status of Direction Flag and compiler even
+ * manages to compile following as 'rep movsd' all by itself...
+ */
+#define padlock_memcpy(o,i,n) ((unsigned char *)memcpy((o),(i),(n)&~3U))
+#endif
+
+/* ===== AES encryption/decryption ===== */
+#ifndef OPENSSL_NO_AES
+
+#if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
+#define NID_aes_128_cfb	NID_aes_128_cfb128
+#endif
+
+#if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)
+#define NID_aes_128_ofb	NID_aes_128_ofb128
+#endif
+
+#if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)
+#define NID_aes_192_cfb	NID_aes_192_cfb128
+#endif
+
+#if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)
+#define NID_aes_192_ofb	NID_aes_192_ofb128
+#endif
+
+#if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)
+#define NID_aes_256_cfb	NID_aes_256_cfb128
+#endif
+
+#if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)
+#define NID_aes_256_ofb	NID_aes_256_ofb128
+#endif
+
+/* List of supported ciphers. */
+static int padlock_cipher_nids[] = {
+	NID_aes_128_ecb,
+	NID_aes_128_cbc,
+	NID_aes_128_cfb,
+	NID_aes_128_ofb,
+
+	NID_aes_192_ecb,
+	NID_aes_192_cbc,
+	NID_aes_192_cfb,
+	NID_aes_192_ofb,
+
+	NID_aes_256_ecb,
+	NID_aes_256_cbc,
+	NID_aes_256_cfb,
+	NID_aes_256_ofb,
+};
+static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/
+				      sizeof(padlock_cipher_nids[0]));
+
+/* Function prototypes ... */
+static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+				const unsigned char *iv, int enc);
+static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			      const unsigned char *in, size_t nbytes);
+
+#define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) +		\
+	( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F )	)
+#define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\
+	NEAREST_ALIGNED(ctx->cipher_data))
+
+#define EVP_CIPHER_block_size_ECB	AES_BLOCK_SIZE
+#define EVP_CIPHER_block_size_CBC	AES_BLOCK_SIZE
+#define EVP_CIPHER_block_size_OFB	1
+#define EVP_CIPHER_block_size_CFB	1
+
+/* Declaring so many ciphers by hand would be a pain.
+   Instead introduce a bit of preprocessor magic :-) */
+#define	DECLARE_AES_EVP(ksize,lmode,umode)	\
+static const EVP_CIPHER padlock_aes_##ksize##_##lmode = {	\
+	NID_aes_##ksize##_##lmode,		\
+	EVP_CIPHER_block_size_##umode,	\
+	AES_KEY_SIZE_##ksize,		\
+	AES_BLOCK_SIZE,			\
+	0 | EVP_CIPH_##umode##_MODE,	\
+	padlock_aes_init_key,		\
+	padlock_aes_cipher,		\
+	NULL,				\
+	sizeof(struct padlock_cipher_data) + 16,	\
+	EVP_CIPHER_set_asn1_iv,		\
+	EVP_CIPHER_get_asn1_iv,		\
+	NULL,				\
+	NULL				\
+}
+
+DECLARE_AES_EVP(128,ecb,ECB);
+DECLARE_AES_EVP(128,cbc,CBC);
+DECLARE_AES_EVP(128,cfb,CFB);
+DECLARE_AES_EVP(128,ofb,OFB);
+
+DECLARE_AES_EVP(192,ecb,ECB);
+DECLARE_AES_EVP(192,cbc,CBC);
+DECLARE_AES_EVP(192,cfb,CFB);
+DECLARE_AES_EVP(192,ofb,OFB);
+
+DECLARE_AES_EVP(256,ecb,ECB);
+DECLARE_AES_EVP(256,cbc,CBC);
+DECLARE_AES_EVP(256,cfb,CFB);
+DECLARE_AES_EVP(256,ofb,OFB);
+
+static int
+padlock_ciphers (ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid)
+{
+	/* No specific cipher => return a list of supported nids ... */
+	if (!cipher) {
+		*nids = padlock_cipher_nids;
+		return padlock_cipher_nids_num;
+	}
+
+	/* ... or the requested "cipher" otherwise */
+	switch (nid) {
+	  case NID_aes_128_ecb:
+	    *cipher = &padlock_aes_128_ecb;
+	    break;
+	  case NID_aes_128_cbc:
+	    *cipher = &padlock_aes_128_cbc;
+	    break;
+	  case NID_aes_128_cfb:
+	    *cipher = &padlock_aes_128_cfb;
+	    break;
+	  case NID_aes_128_ofb:
+	    *cipher = &padlock_aes_128_ofb;
+	    break;
+
+	  case NID_aes_192_ecb:
+	    *cipher = &padlock_aes_192_ecb;
+	    break;
+	  case NID_aes_192_cbc:
+	    *cipher = &padlock_aes_192_cbc;
+	    break;
+	  case NID_aes_192_cfb:
+	    *cipher = &padlock_aes_192_cfb;
+	    break;
+	  case NID_aes_192_ofb:
+	    *cipher = &padlock_aes_192_ofb;
+	    break;
+
+	  case NID_aes_256_ecb:
+	    *cipher = &padlock_aes_256_ecb;
+	    break;
+	  case NID_aes_256_cbc:
+	    *cipher = &padlock_aes_256_cbc;
+	    break;
+	  case NID_aes_256_cfb:
+	    *cipher = &padlock_aes_256_cfb;
+	    break;
+	  case NID_aes_256_ofb:
+	    *cipher = &padlock_aes_256_ofb;
+	    break;
+
+	  default:
+	    /* Sorry, we don't support this NID */
+	    *cipher = NULL;
+	    return 0;
+	}
+
+	return 1;
+}
+
+/* Prepare the encryption key for PadLock usage */
+static int
+padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key,
+		      const unsigned char *iv, int enc)
+{
+	struct padlock_cipher_data *cdata;
+	int key_len = EVP_CIPHER_CTX_key_length(ctx) * 8;
+
+	if (key==NULL) return 0;	/* ERROR */
+
+	cdata = ALIGNED_CIPHER_DATA(ctx);
+	memset(cdata, 0, sizeof(struct padlock_cipher_data));
+
+	/* Prepare Control word. */
+	if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
+		cdata->cword.b.encdec = 0;
+	else
+		cdata->cword.b.encdec = (ctx->encrypt == 0);
+	cdata->cword.b.rounds = 10 + (key_len - 128) / 32;
+	cdata->cword.b.ksize = (key_len - 128) / 64;
+
+	switch(key_len) {
+		case 128:
+			/* PadLock can generate an extended key for
+			   AES128 in hardware */
+			memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128);
+			cdata->cword.b.keygen = 0;
+			break;
+
+		case 192:
+		case 256:
+			/* Generate an extended AES key in software.
+			   Needed for AES192/AES256 */
+			/* Well, the above applies to Stepping 8 CPUs
+			   and is listed as hardware errata. They most
+			   likely will fix it at some point and then
+			   a check for stepping would be due here. */
+			if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE ||
+			    EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE ||
+			    enc)
+				AES_set_encrypt_key(key, key_len, &cdata->ks);
+			else
+				AES_set_decrypt_key(key, key_len, &cdata->ks);
+#ifndef AES_ASM
+			/* OpenSSL C functions use byte-swapped extended key. */
+			padlock_bswapl(&cdata->ks);
+#endif
+			cdata->cword.b.keygen = 1;
+			break;
+
+		default:
+			/* ERROR */
+			return 0;
+	}
+
+	/*
+	 * This is done to cover for cases when user reuses the
+	 * context for new key. The catch is that if we don't do
+	 * this, padlock_eas_cipher might proceed with old key...
+	 */
+	padlock_reload_key ();
+
+	return 1;
+}
+
+/* 
+ * Simplified version of padlock_aes_cipher() used when
+ * 1) both input and output buffers are at aligned addresses.
+ * or when
+ * 2) running on a newer CPU that doesn't require aligned buffers.
+ */
+static int
+padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
+		const unsigned char *in_arg, size_t nbytes)
+{
+	struct padlock_cipher_data *cdata;
+	void  *iv;
+
+	cdata = ALIGNED_CIPHER_DATA(ctx);
+	padlock_verify_context(cdata);
+
+	switch (EVP_CIPHER_CTX_mode(ctx)) {
+	case EVP_CIPH_ECB_MODE:
+		padlock_xcrypt_ecb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
+		break;
+
+	case EVP_CIPH_CBC_MODE:
+		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
+		iv = padlock_xcrypt_cbc(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
+		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
+		break;
+
+	case EVP_CIPH_CFB_MODE:
+		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
+		iv = padlock_xcrypt_cfb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
+		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
+		break;
+
+	case EVP_CIPH_OFB_MODE:
+		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
+		padlock_xcrypt_ofb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
+		memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
+		break;
+
+	default:
+		return 0;
+	}
+
+	memset(cdata->iv, 0, AES_BLOCK_SIZE);
+
+	return 1;
+}
+
+#ifndef  PADLOCK_CHUNK
+# define PADLOCK_CHUNK	512	/* Must be a power of 2 larger than 16 */
+#endif
+#if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1)
+# error "insane PADLOCK_CHUNK..."
+#endif
+
+/* Re-align the arguments to 16-Bytes boundaries and run the 
+   encryption function itself. This function is not AES-specific. */
+static int
+padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
+		   const unsigned char *in_arg, size_t nbytes)
+{
+	struct padlock_cipher_data *cdata;
+	const  void *inp;
+	unsigned char  *out;
+	void  *iv;
+	int    inp_misaligned, out_misaligned, realign_in_loop;
+	size_t chunk, allocated=0;
+
+	/* ctx->num is maintained in byte-oriented modes,
+	   such as CFB and OFB... */
+	if ((chunk = ctx->num)) { /* borrow chunk variable */
+		unsigned char *ivp=ctx->iv;
+
+		switch (EVP_CIPHER_CTX_mode(ctx)) {
+		case EVP_CIPH_CFB_MODE:
+			if (chunk >= AES_BLOCK_SIZE)
+				return 0; /* bogus value */
+
+			if (ctx->encrypt)
+				while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
+					ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk];
+					chunk++, nbytes--;
+				}
+			else	while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
+					unsigned char c = *(in_arg++);
+					*(out_arg++) = c ^ ivp[chunk];
+					ivp[chunk++] = c, nbytes--;
+				}
+
+			ctx->num = chunk%AES_BLOCK_SIZE;
+			break;
+		case EVP_CIPH_OFB_MODE:
+			if (chunk >= AES_BLOCK_SIZE)
+				return 0; /* bogus value */
+
+			while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
+				*(out_arg++) = *(in_arg++) ^ ivp[chunk];
+				chunk++, nbytes--;
+			}
+
+			ctx->num = chunk%AES_BLOCK_SIZE;
+			break;
+		}
+	}
+
+	if (nbytes == 0)
+		return 1;
+#if 0
+	if (nbytes % AES_BLOCK_SIZE)
+		return 0; /* are we expected to do tail processing? */
+#else
+	/* nbytes is always multiple of AES_BLOCK_SIZE in ECB and CBC
+	   modes and arbitrary value in byte-oriented modes, such as
+	   CFB and OFB... */
+#endif
+
+	/* VIA promises CPUs that won't require alignment in the future.
+	   For now padlock_aes_align_required is initialized to 1 and
+	   the condition is never met... */
+	/* C7 core is capable to manage unaligned input in non-ECB[!]
+	   mode, but performance penalties appear to be approximately
+	   same as for software alignment below or ~3x. They promise to
+	   improve it in the future, but for now we can just as well
+	   pretend that it can only handle aligned input... */
+	if (!padlock_aes_align_required && (nbytes%AES_BLOCK_SIZE)==0)
+		return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
+
+	inp_misaligned = (((size_t)in_arg) & 0x0F);
+	out_misaligned = (((size_t)out_arg) & 0x0F);
+
+	/* Note that even if output is aligned and input not,
+	 * I still prefer to loop instead of copy the whole
+	 * input and then encrypt in one stroke. This is done
+	 * in order to improve L1 cache utilization... */
+	realign_in_loop = out_misaligned|inp_misaligned;
+
+	if (!realign_in_loop && (nbytes%AES_BLOCK_SIZE)==0)
+		return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
+
+	/* this takes one "if" out of the loops */
+	chunk  = nbytes;
+	chunk %= PADLOCK_CHUNK;
+	if (chunk==0) chunk = PADLOCK_CHUNK;
+
+	if (out_misaligned) {
+		/* optmize for small input */
+		allocated = (chunk<nbytes?PADLOCK_CHUNK:nbytes);
+		out = alloca(0x10 + allocated);
+		out = NEAREST_ALIGNED(out);
+	}
+	else
+		out = out_arg;
+
+	cdata = ALIGNED_CIPHER_DATA(ctx);
+	padlock_verify_context(cdata);
+
+	switch (EVP_CIPHER_CTX_mode(ctx)) {
+	case EVP_CIPH_ECB_MODE:
+		do	{
+			if (inp_misaligned)
+				inp = padlock_memcpy(out, in_arg, chunk);
+			else
+				inp = in_arg;
+			in_arg += chunk;
+
+			padlock_xcrypt_ecb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
+
+			if (out_misaligned)
+				out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
+			else
+				out     = out_arg+=chunk;
+
+			nbytes -= chunk;
+			chunk   = PADLOCK_CHUNK;
+		} while (nbytes);
+		break;
+
+	case EVP_CIPH_CBC_MODE:
+		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
+		goto cbc_shortcut;
+		do	{
+			if (iv != cdata->iv)
+				memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
+			chunk = PADLOCK_CHUNK;
+		cbc_shortcut: /* optimize for small input */
+			if (inp_misaligned)
+				inp = padlock_memcpy(out, in_arg, chunk);
+			else
+				inp = in_arg;
+			in_arg += chunk;
+
+			iv = padlock_xcrypt_cbc(chunk/AES_BLOCK_SIZE, cdata, out, inp);
+
+			if (out_misaligned)
+				out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
+			else
+				out     = out_arg+=chunk;
+
+		} while (nbytes -= chunk);
+		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
+		break;
+
+	case EVP_CIPH_CFB_MODE:
+		memcpy (iv = cdata->iv, ctx->iv, AES_BLOCK_SIZE);
+		chunk &= ~(AES_BLOCK_SIZE-1);
+		if (chunk)	goto cfb_shortcut;
+		else		goto cfb_skiploop;
+		do	{
+			if (iv != cdata->iv)
+				memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
+			chunk = PADLOCK_CHUNK;
+		cfb_shortcut: /* optimize for small input */
+			if (inp_misaligned)
+				inp = padlock_memcpy(out, in_arg, chunk);
+			else
+				inp = in_arg;
+			in_arg += chunk;
+
+			iv = padlock_xcrypt_cfb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
+
+			if (out_misaligned)
+				out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
+			else
+				out     = out_arg+=chunk;
+
+			nbytes -= chunk;
+		} while (nbytes >= AES_BLOCK_SIZE);
+
+		cfb_skiploop:
+		if (nbytes) {
+			unsigned char *ivp = cdata->iv;
+
+			if (iv != ivp) {
+				memcpy(ivp, iv, AES_BLOCK_SIZE);
+				iv = ivp;
+			}
+			ctx->num = nbytes;
+			if (cdata->cword.b.encdec) {
+				cdata->cword.b.encdec=0;
+				padlock_reload_key();
+				padlock_xcrypt_ecb(1,cdata,ivp,ivp);
+				cdata->cword.b.encdec=1;
+				padlock_reload_key();
+				while(nbytes) {
+					unsigned char c = *(in_arg++);
+					*(out_arg++) = c ^ *ivp;
+					*(ivp++) = c, nbytes--;
+				}
+			}
+			else {	padlock_reload_key();
+				padlock_xcrypt_ecb(1,cdata,ivp,ivp);
+				padlock_reload_key();
+				while (nbytes) {
+					*ivp = *(out_arg++) = *(in_arg++) ^ *ivp;
+					ivp++, nbytes--;
+				}
+			}
+		}
+
+		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
+		break;
+
+	case EVP_CIPH_OFB_MODE:
+		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
+		chunk &= ~(AES_BLOCK_SIZE-1);
+		if (chunk) do	{
+			if (inp_misaligned)
+				inp = padlock_memcpy(out, in_arg, chunk);
+			else
+				inp = in_arg;
+			in_arg += chunk;
+
+			padlock_xcrypt_ofb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
+
+			if (out_misaligned)
+				out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
+			else
+				out     = out_arg+=chunk;
+
+			nbytes -= chunk;
+			chunk   = PADLOCK_CHUNK;
+		} while (nbytes >= AES_BLOCK_SIZE);
+
+		if (nbytes) {
+			unsigned char *ivp = cdata->iv;
+
+			ctx->num = nbytes;
+			padlock_reload_key();	/* empirically found */
+			padlock_xcrypt_ecb(1,cdata,ivp,ivp);
+			padlock_reload_key();	/* empirically found */
+			while (nbytes) {
+				*(out_arg++) = *(in_arg++) ^ *ivp;
+				ivp++, nbytes--;
+			}
+		}
+
+		memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
+		break;
+
+	default:
+		return 0;
+	}
+
+	/* Clean the realign buffer if it was used */
+	if (out_misaligned) {
+		volatile unsigned long *p=(void *)out;
+		size_t   n = allocated/sizeof(*p);
+		while (n--) *p++=0;
+	}
+
+	memset(cdata->iv, 0, AES_BLOCK_SIZE);
+
+	return 1;
+}
+
+#endif /* OPENSSL_NO_AES */
+
+/* ===== Random Number Generator ===== */
+/*
+ * This code is not engaged. The reason is that it does not comply
+ * with recommendations for VIA RNG usage for secure applications
+ * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it
+ * provide meaningful error control...
+ */
+/* Wrapper that provides an interface between the API and 
+   the raw PadLock RNG */
+static int
+padlock_rand_bytes(unsigned char *output, int count)
+{
+	unsigned int eax, buf;
+
+	while (count >= 8) {
+		eax = padlock_xstore(output, 0);
+		if (!(eax&(1<<6)))	return 0; /* RNG disabled */
+		/* this ---vv--- covers DC bias, Raw Bits and String Filter */
+		if (eax&(0x1F<<10))	return 0;
+		if ((eax&0x1F)==0)	continue; /* no data, retry... */
+		if ((eax&0x1F)!=8)	return 0; /* fatal failure...  */
+		output += 8;
+		count  -= 8;
+	}
+	while (count > 0) {
+		eax = padlock_xstore(&buf, 3);
+		if (!(eax&(1<<6)))	return 0; /* RNG disabled */
+		/* this ---vv--- covers DC bias, Raw Bits and String Filter */
+		if (eax&(0x1F<<10))	return 0;
+		if ((eax&0x1F)==0)	continue; /* no data, retry... */
+		if ((eax&0x1F)!=1)	return 0; /* fatal failure...  */
+		*output++ = (unsigned char)buf;
+		count--;
+	}
+	*(volatile unsigned int *)&buf=0;
+
+	return 1;
+}
+
+/* Dummy but necessary function */
+static int
+padlock_rand_status(void)
+{
+	return 1;
+}
+
+/* Prepare structure for registration */
+static RAND_METHOD padlock_rand = {
+	NULL,			/* seed */
+	padlock_rand_bytes,	/* bytes */
+	NULL,			/* cleanup */
+	NULL,			/* add */
+	padlock_rand_bytes,	/* pseudorand */
+	padlock_rand_status,	/* rand status */
+};
+
+#else  /* !COMPILE_HW_PADLOCK */
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+OPENSSL_EXPORT
+int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
+OPENSSL_EXPORT
+int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
+IMPLEMENT_DYNAMIC_CHECK_FN()
+#endif
+#endif /* COMPILE_HW_PADLOCK */
+
+#endif /* !OPENSSL_NO_HW_PADLOCK */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_padlock.ec b/openssl/engines/e_padlock.ec
new file mode 100644
index 0000000..5c8a1d2
--- /dev/null
+++ b/openssl/engines/e_padlock.ec
@@ -0,0 +1 @@
+L PADLOCK	e_padlock_err.h			e_padlock_err.c
diff --git a/openssl/engines/e_sureware.c b/openssl/engines/e_sureware.c
new file mode 100644
index 0000000..cd0fa4c
--- /dev/null
+++ b/openssl/engines/e_sureware.c
@@ -0,0 +1,1055 @@
+/* Written by Corinne Dive-Reclus(cdive@baltimore.com)
+* 
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer. 
+*
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in
+*    the documentation and/or other materials provided with the
+*    distribution.
+*
+* 3. All advertising materials mentioning features or use of this
+*    software must display the following acknowledgment:
+*    "This product includes software developed by the OpenSSL Project
+*    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+*
+* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+*    endorse or promote products derived from this software without
+*    prior written permission. For written permission, please contact
+*    licensing@OpenSSL.org.
+*
+* 5. Products derived from this software may not be called "OpenSSL"
+*    nor may "OpenSSL" appear in their names without prior written
+*    permission of the OpenSSL Project.
+*
+* 6. Redistributions of any form whatsoever must retain the following
+*    acknowledgment:
+*    "This product includes software developed by the OpenSSL Project
+*    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+*
+* Written by Corinne Dive-Reclus(cdive@baltimore.com)
+*
+* Copyright@2001 Baltimore Technologies Ltd.
+* All right Reserved.
+*																								*	
+*		THIS FILE IS PROVIDED BY BALTIMORE TECHNOLOGIES ``AS IS'' AND																			*
+*		ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE					* 
+*		IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE				*
+*		ARE DISCLAIMED.  IN NO EVENT SHALL BALTIMORE TECHNOLOGIES BE LIABLE						*
+*		FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL				*
+*		DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS					*
+*		OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)					*
+*		HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT				*
+*		LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY				*
+*		OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF					*
+*		SUCH DAMAGE.																			*
+====================================================================*/
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/pem.h>
+#include <openssl/dso.h>
+#include <openssl/engine.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_SUREWARE
+
+#ifdef FLAT_INC
+#include "sureware.h"
+#else
+#include "vendor_defns/sureware.h"
+#endif
+
+#define SUREWARE_LIB_NAME "sureware engine"
+#include "e_sureware_err.c"
+
+static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+static int surewarehk_destroy(ENGINE *e);
+static int surewarehk_init(ENGINE *e);
+static int surewarehk_finish(ENGINE *e);
+static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx);
+
+/* RSA stuff */
+#ifndef OPENSSL_NO_RSA
+static int surewarehk_rsa_priv_dec(int flen,const unsigned char *from,unsigned char *to,
+			RSA *rsa,int padding);
+static int surewarehk_rsa_sign(int flen,const unsigned char *from,unsigned char *to,
+			    RSA *rsa,int padding);
+#endif
+
+/* RAND stuff */
+static int surewarehk_rand_bytes(unsigned char *buf, int num);
+static void surewarehk_rand_seed(const void *buf, int num);
+static void surewarehk_rand_add(const void *buf, int num, double entropy);
+
+/* KM stuff */
+static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data);
+static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data);
+static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
+	int idx,long argl, void *argp);
+#if 0
+static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
+	int idx,long argl, void *argp);
+#endif
+
+#ifndef OPENSSL_NO_RSA
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int surewarehk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+{
+	return surewarehk_modexp(r, a, p, m, ctx);
+}
+
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD surewarehk_rsa =
+	{
+	"SureWare RSA method",
+	NULL, /* pub_enc*/
+	NULL, /* pub_dec*/
+	surewarehk_rsa_sign, /* our rsa_sign is OpenSSL priv_enc*/
+	surewarehk_rsa_priv_dec, /* priv_dec*/
+	NULL, /*mod_exp*/
+	surewarehk_mod_exp_mont, /*mod_exp_mongomery*/
+	NULL, /* init*/
+	NULL, /* finish*/
+	0,	/* RSA flag*/
+	NULL, 
+	NULL, /* OpenSSL sign*/
+	NULL, /* OpenSSL verify*/
+	NULL  /* keygen */
+	};
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* Our internal DH_METHOD that we provide pointers to */
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int surewarehk_modexp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
+	const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+{
+	return surewarehk_modexp(r, a, p, m, ctx);
+}
+
+static DH_METHOD surewarehk_dh =
+	{
+	"SureWare DH method",
+	NULL,/*gen_key*/
+	NULL,/*agree,*/
+	surewarehk_modexp_dh, /*dh mod exp*/
+	NULL, /* init*/
+	NULL, /* finish*/
+	0,    /* flags*/
+	NULL,
+	NULL
+	};
+#endif
+
+static RAND_METHOD surewarehk_rand =
+	{
+	/* "SureWare RAND method", */
+	surewarehk_rand_seed,
+	surewarehk_rand_bytes,
+	NULL,/*cleanup*/
+	surewarehk_rand_add,
+	surewarehk_rand_bytes,
+	NULL,/*rand_status*/
+	};
+
+#ifndef OPENSSL_NO_DSA
+/* DSA stuff */
+static	DSA_SIG * surewarehk_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+static int surewarehk_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
+		BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
+		BN_CTX *ctx, BN_MONT_CTX *in_mont)
+{
+	BIGNUM t;
+	int to_return = 0;
+	BN_init(&t);
+	/* let rr = a1 ^ p1 mod m */
+	if (!surewarehk_modexp(rr,a1,p1,m,ctx)) goto end;
+	/* let t = a2 ^ p2 mod m */
+	if (!surewarehk_modexp(&t,a2,p2,m,ctx)) goto end;
+	/* let rr = rr * t mod m */
+	if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
+	to_return = 1;
+end:
+	BN_free(&t);
+	return to_return;
+}
+
+static DSA_METHOD surewarehk_dsa =
+	{
+	 "SureWare DSA method", 
+	surewarehk_dsa_do_sign,
+	NULL,/*sign setup*/
+	NULL,/*verify,*/
+	surewarehk_dsa_mod_exp,/*mod exp*/
+	NULL,/*bn mod exp*/
+	NULL, /*init*/
+	NULL,/*finish*/
+	0,
+	NULL,
+	NULL,
+	NULL
+	};
+#endif
+
+static const char *engine_sureware_id = "sureware";
+static const char *engine_sureware_name = "SureWare hardware engine support";
+
+/* Now, to our own code */
+
+/* As this is only ever called once, there's no need for locking
+ * (indeed - the lock will already be held by our caller!!!) */
+static int bind_sureware(ENGINE *e)
+{
+#ifndef OPENSSL_NO_RSA
+	const RSA_METHOD *meth1;
+#endif
+#ifndef OPENSSL_NO_DSA
+	const DSA_METHOD *meth2;
+#endif
+#ifndef OPENSSL_NO_DH
+	const DH_METHOD *meth3;
+#endif
+
+	if(!ENGINE_set_id(e, engine_sureware_id) ||
+	   !ENGINE_set_name(e, engine_sureware_name) ||
+#ifndef OPENSSL_NO_RSA
+	   !ENGINE_set_RSA(e, &surewarehk_rsa) ||
+#endif
+#ifndef OPENSSL_NO_DSA
+	   !ENGINE_set_DSA(e, &surewarehk_dsa) ||
+#endif
+#ifndef OPENSSL_NO_DH
+	   !ENGINE_set_DH(e, &surewarehk_dh) ||
+#endif
+	   !ENGINE_set_RAND(e, &surewarehk_rand) ||
+	   !ENGINE_set_destroy_function(e, surewarehk_destroy) ||
+	   !ENGINE_set_init_function(e, surewarehk_init) ||
+	   !ENGINE_set_finish_function(e, surewarehk_finish) ||
+	   !ENGINE_set_ctrl_function(e, surewarehk_ctrl) ||
+	   !ENGINE_set_load_privkey_function(e, surewarehk_load_privkey) ||
+	   !ENGINE_set_load_pubkey_function(e, surewarehk_load_pubkey))
+	  return 0;
+
+#ifndef OPENSSL_NO_RSA
+	/* We know that the "PKCS1_SSLeay()" functions hook properly
+	 * to the cswift-specific mod_exp and mod_exp_crt so we use
+	 * those functions. NB: We don't use ENGINE_openssl() or
+	 * anything "more generic" because something like the RSAref
+	 * code may not hook properly, and if you own one of these
+	 * cards then you have the right to do RSA operations on it
+	 * anyway! */ 
+	meth1 = RSA_PKCS1_SSLeay();
+	if (meth1)
+	{
+		surewarehk_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+		surewarehk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+	}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+	/* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
+	 * bits. */
+	meth2 = DSA_OpenSSL();
+	if (meth2)
+	{
+		surewarehk_dsa.dsa_do_verify = meth2->dsa_do_verify;
+	}
+#endif
+
+#ifndef OPENSSL_NO_DH
+	/* Much the same for Diffie-Hellman */
+	meth3 = DH_OpenSSL();
+	if (meth3)
+	{
+		surewarehk_dh.generate_key = meth3->generate_key;
+		surewarehk_dh.compute_key = meth3->compute_key;
+	}
+#endif
+
+	/* Ensure the sureware error handling is set up */
+	ERR_load_SUREWARE_strings();
+	return 1;
+}
+
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_helper(ENGINE *e, const char *id)
+	{
+	if(id && (strcmp(id, engine_sureware_id) != 0))
+		return 0;
+	if(!bind_sureware(e))
+		return 0;
+	return 1;
+	}       
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
+#else
+static ENGINE *engine_sureware(void)
+	{
+	ENGINE *ret = ENGINE_new();
+	if(!ret)
+		return NULL;
+	if(!bind_sureware(ret))
+		{
+		ENGINE_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+void ENGINE_load_sureware(void)
+	{
+	/* Copied from eng_[openssl|dyn].c */
+	ENGINE *toadd = engine_sureware();
+	if(!toadd) return;
+	ENGINE_add(toadd);
+	ENGINE_free(toadd);
+	ERR_clear_error();
+	}
+#endif
+
+/* This is a process-global DSO handle used for loading and unloading
+ * the SureWareHook library. NB: This is only set (or unset) during an
+ * init() or finish() call (reference counts permitting) and they're
+ * operating with global locks, so this should be thread-safe
+ * implicitly. */
+static DSO *surewarehk_dso = NULL;
+#ifndef OPENSSL_NO_RSA
+static int rsaHndidx = -1;	/* Index for KM handle.  Not really used yet. */
+#endif
+#ifndef OPENSSL_NO_DSA
+static int dsaHndidx = -1;	/* Index for KM handle.  Not really used yet. */
+#endif
+
+/* These are the function pointers that are (un)set when the library has
+ * successfully (un)loaded. */
+static SureWareHook_Init_t *p_surewarehk_Init = NULL;
+static SureWareHook_Finish_t *p_surewarehk_Finish = NULL;
+static SureWareHook_Rand_Bytes_t *p_surewarehk_Rand_Bytes = NULL;
+static SureWareHook_Rand_Seed_t *p_surewarehk_Rand_Seed = NULL;
+static SureWareHook_Load_Privkey_t *p_surewarehk_Load_Privkey = NULL;
+static SureWareHook_Info_Pubkey_t *p_surewarehk_Info_Pubkey = NULL;
+static SureWareHook_Load_Rsa_Pubkey_t *p_surewarehk_Load_Rsa_Pubkey = NULL;
+static SureWareHook_Load_Dsa_Pubkey_t *p_surewarehk_Load_Dsa_Pubkey = NULL;
+static SureWareHook_Free_t *p_surewarehk_Free=NULL;
+static SureWareHook_Rsa_Priv_Dec_t *p_surewarehk_Rsa_Priv_Dec=NULL;
+static SureWareHook_Rsa_Sign_t *p_surewarehk_Rsa_Sign=NULL;
+static SureWareHook_Dsa_Sign_t *p_surewarehk_Dsa_Sign=NULL;
+static SureWareHook_Mod_Exp_t *p_surewarehk_Mod_Exp=NULL;
+
+/* Used in the DSO operations. */
+static const char *surewarehk_LIBNAME = "SureWareHook";
+static const char *n_surewarehk_Init = "SureWareHook_Init";
+static const char *n_surewarehk_Finish = "SureWareHook_Finish";
+static const char *n_surewarehk_Rand_Bytes="SureWareHook_Rand_Bytes";
+static const char *n_surewarehk_Rand_Seed="SureWareHook_Rand_Seed";
+static const char *n_surewarehk_Load_Privkey="SureWareHook_Load_Privkey";
+static const char *n_surewarehk_Info_Pubkey="SureWareHook_Info_Pubkey";
+static const char *n_surewarehk_Load_Rsa_Pubkey="SureWareHook_Load_Rsa_Pubkey";
+static const char *n_surewarehk_Load_Dsa_Pubkey="SureWareHook_Load_Dsa_Pubkey";
+static const char *n_surewarehk_Free="SureWareHook_Free";
+static const char *n_surewarehk_Rsa_Priv_Dec="SureWareHook_Rsa_Priv_Dec";
+static const char *n_surewarehk_Rsa_Sign="SureWareHook_Rsa_Sign";
+static const char *n_surewarehk_Dsa_Sign="SureWareHook_Dsa_Sign";
+static const char *n_surewarehk_Mod_Exp="SureWareHook_Mod_Exp";
+static BIO *logstream = NULL;
+
+/* SureWareHook library functions and mechanics - these are used by the
+ * higher-level functions further down. NB: As and where there's no
+ * error checking, take a look lower down where these functions are
+ * called, the checking and error handling is probably down there. 
+*/
+static int threadsafe=1;
+static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+{
+	int to_return = 1;
+
+	switch(cmd)
+	{
+		case ENGINE_CTRL_SET_LOGSTREAM:
+		{
+			BIO *bio = (BIO *)p;
+			CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+			if (logstream)
+			{
+				BIO_free(logstream);
+				logstream = NULL;
+			}
+			if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1)
+				logstream = bio;
+			else
+				SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL,SUREWARE_R_BIO_WAS_FREED);
+		}
+		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		break;
+	/* This will prevent the initialisation function from "installing"
+	 * the mutex-handling callbacks, even if they are available from
+	 * within the library (or were provided to the library from the
+	 * calling application). This is to remove any baggage for
+	 * applications not using multithreading. */
+	case ENGINE_CTRL_CHIL_NO_LOCKING:
+		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+		threadsafe = 0;
+		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		break;
+
+	/* The command isn't understood by this engine */
+	default:
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL,
+			ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+		to_return = 0;
+		break;
+		}
+
+	return to_return;
+}
+
+/* Destructor (complements the "ENGINE_surewarehk()" constructor) */
+static int surewarehk_destroy(ENGINE *e)
+{
+	ERR_unload_SUREWARE_strings();
+	return 1;
+}
+
+/* (de)initialisation functions. */
+static int surewarehk_init(ENGINE *e)
+{
+	char msg[64]="ENGINE_init";
+	SureWareHook_Init_t *p1=NULL;
+	SureWareHook_Finish_t *p2=NULL;
+	SureWareHook_Rand_Bytes_t *p3=NULL;
+	SureWareHook_Rand_Seed_t *p4=NULL;
+	SureWareHook_Load_Privkey_t *p5=NULL;
+	SureWareHook_Load_Rsa_Pubkey_t *p6=NULL;
+	SureWareHook_Free_t *p7=NULL;
+	SureWareHook_Rsa_Priv_Dec_t *p8=NULL;
+	SureWareHook_Rsa_Sign_t *p9=NULL;
+	SureWareHook_Dsa_Sign_t *p12=NULL;
+	SureWareHook_Info_Pubkey_t *p13=NULL;
+	SureWareHook_Load_Dsa_Pubkey_t *p14=NULL;
+	SureWareHook_Mod_Exp_t *p15=NULL;
+
+	if(surewarehk_dso != NULL)
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_ALREADY_LOADED);
+		goto err;
+	}
+	/* Attempt to load libsurewarehk.so/surewarehk.dll/whatever. */
+	surewarehk_dso = DSO_load(NULL, surewarehk_LIBNAME, NULL, 0);
+	if(surewarehk_dso == NULL)
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_DSO_FAILURE);
+		goto err;
+	}
+	if(!(p1=(SureWareHook_Init_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Init)) ||
+	   !(p2=(SureWareHook_Finish_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Finish)) ||
+	   !(p3=(SureWareHook_Rand_Bytes_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rand_Bytes)) ||
+	   !(p4=(SureWareHook_Rand_Seed_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rand_Seed)) ||
+	   !(p5=(SureWareHook_Load_Privkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Privkey)) ||
+	   !(p6=(SureWareHook_Load_Rsa_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Rsa_Pubkey)) ||
+	   !(p7=(SureWareHook_Free_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Free)) ||
+	   !(p8=(SureWareHook_Rsa_Priv_Dec_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rsa_Priv_Dec)) ||
+	   !(p9=(SureWareHook_Rsa_Sign_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rsa_Sign)) ||
+	   !(p12=(SureWareHook_Dsa_Sign_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Dsa_Sign)) ||
+	   !(p13=(SureWareHook_Info_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Info_Pubkey)) ||
+	   !(p14=(SureWareHook_Load_Dsa_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Dsa_Pubkey)) ||
+	   !(p15=(SureWareHook_Mod_Exp_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Mod_Exp)))
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_DSO_FAILURE);
+		goto err;
+	}
+	/* Copy the pointers */
+	p_surewarehk_Init = p1;
+	p_surewarehk_Finish = p2;
+	p_surewarehk_Rand_Bytes = p3;
+	p_surewarehk_Rand_Seed = p4;
+	p_surewarehk_Load_Privkey = p5;
+	p_surewarehk_Load_Rsa_Pubkey = p6;
+	p_surewarehk_Free = p7;
+	p_surewarehk_Rsa_Priv_Dec = p8;
+	p_surewarehk_Rsa_Sign = p9;
+	p_surewarehk_Dsa_Sign = p12;
+	p_surewarehk_Info_Pubkey = p13;
+	p_surewarehk_Load_Dsa_Pubkey = p14;
+	p_surewarehk_Mod_Exp = p15;
+	/* Contact the hardware and initialises it. */
+	if(p_surewarehk_Init(msg,threadsafe)==SUREWAREHOOK_ERROR_UNIT_FAILURE)
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,SUREWARE_R_UNIT_FAILURE);
+		goto err;
+	}
+	if(p_surewarehk_Init(msg,threadsafe)==SUREWAREHOOK_ERROR_UNIT_FAILURE)
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,SUREWARE_R_UNIT_FAILURE);
+		goto err;
+	}
+	/* try to load the default private key, if failed does not return a failure but
+           wait for an explicit ENGINE_load_privakey */
+	surewarehk_load_privkey(e,NULL,NULL,NULL);
+
+	/* Everything's fine. */
+#ifndef OPENSSL_NO_RSA
+	if (rsaHndidx == -1)
+		rsaHndidx = RSA_get_ex_new_index(0,
+						"SureWareHook RSA key handle",
+						NULL, NULL, surewarehk_ex_free);
+#endif
+#ifndef OPENSSL_NO_DSA
+	if (dsaHndidx == -1)
+		dsaHndidx = DSA_get_ex_new_index(0,
+						"SureWareHook DSA key handle",
+						NULL, NULL, surewarehk_ex_free);
+#endif
+
+	return 1;
+err:
+	if(surewarehk_dso)
+		DSO_free(surewarehk_dso);
+	surewarehk_dso = NULL;
+	p_surewarehk_Init = NULL;
+	p_surewarehk_Finish = NULL;
+	p_surewarehk_Rand_Bytes = NULL;
+	p_surewarehk_Rand_Seed = NULL;
+	p_surewarehk_Load_Privkey = NULL;
+	p_surewarehk_Load_Rsa_Pubkey = NULL;
+	p_surewarehk_Free = NULL;
+	p_surewarehk_Rsa_Priv_Dec = NULL;
+	p_surewarehk_Rsa_Sign = NULL;
+	p_surewarehk_Dsa_Sign = NULL;
+	p_surewarehk_Info_Pubkey = NULL;
+	p_surewarehk_Load_Dsa_Pubkey = NULL;
+	p_surewarehk_Mod_Exp = NULL;
+	return 0;
+}
+
+static int surewarehk_finish(ENGINE *e)
+{
+	int to_return = 1;
+	if(surewarehk_dso == NULL)
+		{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH,ENGINE_R_NOT_LOADED);
+		to_return = 0;
+		goto err;
+		}
+	p_surewarehk_Finish();
+	if(!DSO_free(surewarehk_dso))
+		{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH,ENGINE_R_DSO_FAILURE);
+		to_return = 0;
+		goto err;
+		}
+ err:
+	if (logstream)
+		BIO_free(logstream);
+	surewarehk_dso = NULL;
+	p_surewarehk_Init = NULL;
+	p_surewarehk_Finish = NULL;
+	p_surewarehk_Rand_Bytes = NULL;
+	p_surewarehk_Rand_Seed = NULL;
+	p_surewarehk_Load_Privkey = NULL;
+	p_surewarehk_Load_Rsa_Pubkey = NULL;
+	p_surewarehk_Free = NULL;
+	p_surewarehk_Rsa_Priv_Dec = NULL;
+	p_surewarehk_Rsa_Sign = NULL;
+	p_surewarehk_Dsa_Sign = NULL;
+	p_surewarehk_Info_Pubkey = NULL;
+	p_surewarehk_Load_Dsa_Pubkey = NULL;
+	p_surewarehk_Mod_Exp = NULL;
+	return to_return;
+}
+
+static void surewarehk_error_handling(char *const msg,int func,int ret)
+{
+	switch (ret)
+	{
+		case SUREWAREHOOK_ERROR_UNIT_FAILURE:
+			ENGINEerr(func,SUREWARE_R_UNIT_FAILURE);
+			break;
+		case SUREWAREHOOK_ERROR_FALLBACK:
+			ENGINEerr(func,SUREWARE_R_REQUEST_FALLBACK);
+			break;
+		case SUREWAREHOOK_ERROR_DATA_SIZE:
+			ENGINEerr(func,SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+			break;
+		case SUREWAREHOOK_ERROR_INVALID_PAD:
+			ENGINEerr(func,SUREWARE_R_PADDING_CHECK_FAILED);
+			break;
+		default:
+			ENGINEerr(func,SUREWARE_R_REQUEST_FAILED);
+			break;
+		case 1:/*nothing*/
+			msg[0]='\0';
+	}
+	if (*msg)
+	{
+		ERR_add_error_data(1,msg);
+		if (logstream)
+		{
+			CRYPTO_w_lock(CRYPTO_LOCK_BIO);
+			BIO_write(logstream, msg, strlen(msg));
+			CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
+		}
+	}
+}
+
+static int surewarehk_rand_bytes(unsigned char *buf, int num)
+{
+	int ret=0;
+	char msg[64]="ENGINE_rand_bytes";
+	if(!p_surewarehk_Rand_Bytes)
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_BYTES,ENGINE_R_NOT_INITIALISED);
+	}
+	else
+	{
+		ret = p_surewarehk_Rand_Bytes(msg,buf, num);
+		surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RAND_BYTES,ret);
+	}
+	return ret==1 ? 1 : 0;
+}
+
+static void surewarehk_rand_seed(const void *buf, int num)
+{
+	int ret=0;
+	char msg[64]="ENGINE_rand_seed";
+	if(!p_surewarehk_Rand_Seed)
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_SEED,ENGINE_R_NOT_INITIALISED);
+	}
+	else
+	{
+		ret = p_surewarehk_Rand_Seed(msg,buf, num);
+		surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RAND_SEED,ret);
+	}
+}
+
+static void surewarehk_rand_add(const void *buf, int num, double entropy)
+{
+	surewarehk_rand_seed(buf,num);
+}
+
+static EVP_PKEY* sureware_load_public(ENGINE *e,const char *key_id,char *hptr,unsigned long el,char keytype)
+{
+	EVP_PKEY *res = NULL;
+#ifndef OPENSSL_NO_RSA
+	RSA *rsatmp = NULL;
+#endif
+#ifndef OPENSSL_NO_DSA
+	DSA *dsatmp=NULL;
+#endif
+	char msg[64]="sureware_load_public";
+	int ret=0;
+	if(!p_surewarehk_Load_Rsa_Pubkey || !p_surewarehk_Load_Dsa_Pubkey)
+	{
+		SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_NOT_INITIALISED);
+		goto err;
+	}
+	switch (keytype)
+	{
+#ifndef OPENSSL_NO_RSA
+	case 1: /*RSA*/
+		/* set private external reference */
+		rsatmp = RSA_new_method(e);
+		RSA_set_ex_data(rsatmp,rsaHndidx,hptr);
+		rsatmp->flags |= RSA_FLAG_EXT_PKEY;
+
+		/* set public big nums*/
+		rsatmp->e = BN_new();
+		rsatmp->n = BN_new();
+		bn_expand2(rsatmp->e, el/sizeof(BN_ULONG));
+		bn_expand2(rsatmp->n, el/sizeof(BN_ULONG));
+		if (!rsatmp->e || rsatmp->e->dmax!=(int)(el/sizeof(BN_ULONG))|| 
+			!rsatmp->n || rsatmp->n->dmax!=(int)(el/sizeof(BN_ULONG)))
+			goto err;
+		ret=p_surewarehk_Load_Rsa_Pubkey(msg,key_id,el,
+						 (unsigned long *)rsatmp->n->d,
+						 (unsigned long *)rsatmp->e->d);
+		surewarehk_error_handling(msg,SUREWARE_F_SUREWARE_LOAD_PUBLIC,ret);
+		if (ret!=1)
+		{
+			SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
+			goto err;
+		}
+		/* normalise pub e and pub n */
+		rsatmp->e->top=el/sizeof(BN_ULONG);
+		bn_fix_top(rsatmp->e);
+		rsatmp->n->top=el/sizeof(BN_ULONG);
+		bn_fix_top(rsatmp->n);
+		/* create an EVP object: engine + rsa key */
+		res = EVP_PKEY_new();
+		EVP_PKEY_assign_RSA(res, rsatmp);
+		break;
+#endif
+
+#ifndef OPENSSL_NO_DSA
+	case 2:/*DSA*/
+		/* set private/public external reference */
+		dsatmp = DSA_new_method(e);
+		DSA_set_ex_data(dsatmp,dsaHndidx,hptr);
+		/*dsatmp->flags |= DSA_FLAG_EXT_PKEY;*/
+
+		/* set public key*/
+		dsatmp->pub_key = BN_new();
+		dsatmp->p = BN_new();
+		dsatmp->q = BN_new();
+		dsatmp->g = BN_new();
+		bn_expand2(dsatmp->pub_key, el/sizeof(BN_ULONG));
+		bn_expand2(dsatmp->p, el/sizeof(BN_ULONG));
+		bn_expand2(dsatmp->q, 20/sizeof(BN_ULONG));
+		bn_expand2(dsatmp->g, el/sizeof(BN_ULONG));
+		if (!dsatmp->pub_key || dsatmp->pub_key->dmax!=(int)(el/sizeof(BN_ULONG))|| 
+			!dsatmp->p || dsatmp->p->dmax!=(int)(el/sizeof(BN_ULONG)) ||
+			!dsatmp->q || dsatmp->q->dmax!=20/sizeof(BN_ULONG) ||
+			!dsatmp->g || dsatmp->g->dmax!=(int)(el/sizeof(BN_ULONG)))
+			goto err;
+
+		ret=p_surewarehk_Load_Dsa_Pubkey(msg,key_id,el,
+						 (unsigned long *)dsatmp->pub_key->d, 
+						 (unsigned long *)dsatmp->p->d,
+						 (unsigned long *)dsatmp->q->d,
+						 (unsigned long *)dsatmp->g->d);
+		surewarehk_error_handling(msg,SUREWARE_F_SUREWARE_LOAD_PUBLIC,ret);
+		if (ret!=1)
+		{
+			SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
+			goto err;
+		}
+		/* set parameters */
+		/* normalise pubkey and parameters in case of */
+		dsatmp->pub_key->top=el/sizeof(BN_ULONG);
+		bn_fix_top(dsatmp->pub_key);
+		dsatmp->p->top=el/sizeof(BN_ULONG);
+		bn_fix_top(dsatmp->p);
+		dsatmp->q->top=20/sizeof(BN_ULONG);
+		bn_fix_top(dsatmp->q);
+		dsatmp->g->top=el/sizeof(BN_ULONG);
+		bn_fix_top(dsatmp->g);
+
+		/* create an EVP object: engine + rsa key */
+		res = EVP_PKEY_new();
+		EVP_PKEY_assign_DSA(res, dsatmp);
+		break;
+#endif
+
+	default:
+		SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
+		goto err;
+	}
+	return res;
+ err:
+#ifndef OPENSSL_NO_RSA
+	if (rsatmp)
+		RSA_free(rsatmp);
+#endif
+#ifndef OPENSSL_NO_DSA
+	if (dsatmp)
+		DSA_free(dsatmp);
+#endif
+	return NULL;
+}
+
+static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id,
+					 UI_METHOD *ui_method, void *callback_data)
+{
+	EVP_PKEY *res = NULL;
+	int ret=0;
+	unsigned long el=0;
+	char *hptr=NULL;
+	char keytype=0;
+	char msg[64]="ENGINE_load_privkey";
+
+	if(!p_surewarehk_Load_Privkey)
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY,ENGINE_R_NOT_INITIALISED);
+	}
+	else
+	{
+		ret=p_surewarehk_Load_Privkey(msg,key_id,&hptr,&el,&keytype);
+		if (ret!=1)
+		{
+			SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY,ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
+			ERR_add_error_data(1,msg);		
+		}
+		else
+			res=sureware_load_public(e,key_id,hptr,el,keytype);
+	}
+	return res;
+}
+
+static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id,
+					 UI_METHOD *ui_method, void *callback_data)
+{
+	EVP_PKEY *res = NULL;
+	int ret=0;
+	unsigned long el=0;
+	char *hptr=NULL;
+	char keytype=0;
+	char msg[64]="ENGINE_load_pubkey";
+
+	if(!p_surewarehk_Info_Pubkey)
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY,ENGINE_R_NOT_INITIALISED);
+	}
+	else
+	{
+		/* call once to identify if DSA or RSA */
+		ret=p_surewarehk_Info_Pubkey(msg,key_id,&el,&keytype);
+		if (ret!=1)
+		{
+			SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY,ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
+			ERR_add_error_data(1,msg);
+		}
+		else
+			res=sureware_load_public(e,key_id,hptr,el,keytype);
+	}
+	return res;
+}
+
+/* This cleans up an RSA/DSA KM key(do not destroy the key into the hardware)
+, called when ex_data is freed */
+static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
+	int idx,long argl, void *argp)
+{
+	if(!p_surewarehk_Free)
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_EX_FREE,ENGINE_R_NOT_INITIALISED);
+	}
+	else
+		p_surewarehk_Free((char *)item,0);
+}
+
+#if 0
+/* not currently used (bug?) */
+/* This cleans up an DH KM key (destroys the key into hardware), 
+called when ex_data is freed */
+static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
+	int idx,long argl, void *argp)
+{
+	if(!p_surewarehk_Free)
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_DH_EX_FREE,ENGINE_R_NOT_INITIALISED);
+	}
+	else
+		p_surewarehk_Free((char *)item,1);
+}
+#endif
+
+/*
+* return number of decrypted bytes
+*/
+#ifndef OPENSSL_NO_RSA
+static int surewarehk_rsa_priv_dec(int flen,const unsigned char *from,unsigned char *to,
+			RSA *rsa,int padding)
+{
+	int ret=0,tlen;
+	char *buf=NULL,*hptr=NULL;
+	char msg[64]="ENGINE_rsa_priv_dec";
+	if (!p_surewarehk_Rsa_Priv_Dec)
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ENGINE_R_NOT_INITIALISED);
+	}
+	/* extract ref to private key */
+	else if (!(hptr=RSA_get_ex_data(rsa, rsaHndidx)))
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,SUREWARE_R_MISSING_KEY_COMPONENTS);
+		goto err;
+	}
+	/* analyse what padding we can do into the hardware */
+	if (padding==RSA_PKCS1_PADDING)
+	{
+		/* do it one shot */
+		ret=p_surewarehk_Rsa_Priv_Dec(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_PKCS1_PAD);
+		surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ret);
+		if (ret!=1)
+			goto err;
+		ret=tlen;
+	}
+	else /* do with no padding into hardware */
+	{
+		ret=p_surewarehk_Rsa_Priv_Dec(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_NO_PAD);
+		surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ret);
+		if (ret!=1)
+			goto err;
+		/* intermediate buffer for padding */
+		if ((buf=OPENSSL_malloc(tlen)) == NULL)
+		{
+			SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		memcpy(buf,to,tlen);/* transfert to into buf */
+		switch (padding) /* check padding in software */
+		{
+#ifndef OPENSSL_NO_SHA
+		case RSA_PKCS1_OAEP_PADDING:
+			ret=RSA_padding_check_PKCS1_OAEP(to,tlen,(unsigned char *)buf,tlen,tlen,NULL,0);
+			break;
+#endif
+ 		case RSA_SSLV23_PADDING:
+			ret=RSA_padding_check_SSLv23(to,tlen,(unsigned char *)buf,flen,tlen);
+			break;
+		case RSA_NO_PADDING:
+			ret=RSA_padding_check_none(to,tlen,(unsigned char *)buf,flen,tlen);
+			break;
+		default:
+			SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,SUREWARE_R_UNKNOWN_PADDING_TYPE);
+			goto err;
+		}
+		if (ret < 0)
+			SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,SUREWARE_R_PADDING_CHECK_FAILED);
+	}
+err:
+	if (buf)
+	{
+		OPENSSL_cleanse(buf,tlen);
+		OPENSSL_free(buf);
+	}
+	return ret;
+}
+
+/*
+* Does what OpenSSL rsa_priv_enc does.
+*/
+static int surewarehk_rsa_sign(int flen,const unsigned char *from,unsigned char *to,
+			    RSA *rsa,int padding)
+{
+	int ret=0,tlen;
+	char *hptr=NULL;
+	char msg[64]="ENGINE_rsa_sign";
+	if (!p_surewarehk_Rsa_Sign)
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN,ENGINE_R_NOT_INITIALISED);
+	}
+	/* extract ref to private key */
+	else if (!(hptr=RSA_get_ex_data(rsa, rsaHndidx)))
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN,SUREWARE_R_MISSING_KEY_COMPONENTS);
+	}
+	else
+	{
+		switch (padding)
+		{
+		case RSA_PKCS1_PADDING: /* do it in one shot */
+			ret=p_surewarehk_Rsa_Sign(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_PKCS1_PAD);
+			surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_SIGN,ret);
+			break;
+		case RSA_NO_PADDING:
+		default:
+			SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN,SUREWARE_R_UNKNOWN_PADDING_TYPE);
+		}
+	}
+	return ret==1 ? tlen : ret;
+}
+
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* DSA sign and verify */
+static	DSA_SIG * surewarehk_dsa_do_sign(const unsigned char *from, int flen, DSA *dsa)
+{
+	int ret=0;
+	char *hptr=NULL;
+	DSA_SIG *psign=NULL;
+	char msg[64]="ENGINE_dsa_do_sign";
+	if (!p_surewarehk_Dsa_Sign)
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ENGINE_R_NOT_INITIALISED);
+		goto err;
+	}
+	/* extract ref to private key */
+	else if (!(hptr=DSA_get_ex_data(dsa, dsaHndidx)))
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,SUREWARE_R_MISSING_KEY_COMPONENTS);
+		goto err;
+	}
+	else
+	{
+		if((psign = DSA_SIG_new()) == NULL)
+		{
+			SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		psign->r=BN_new();
+		psign->s=BN_new();
+		bn_expand2(psign->r, 20/sizeof(BN_ULONG));
+		bn_expand2(psign->s, 20/sizeof(BN_ULONG));
+		if (!psign->r || psign->r->dmax!=20/sizeof(BN_ULONG) ||
+			!psign->s || psign->s->dmax!=20/sizeof(BN_ULONG))
+			goto err;
+		ret=p_surewarehk_Dsa_Sign(msg,flen,from,
+					  (unsigned long *)psign->r->d,
+					  (unsigned long *)psign->s->d,
+					  hptr);
+		surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ret);
+	}
+	psign->r->top=20/sizeof(BN_ULONG);
+	bn_fix_top(psign->r);
+	psign->s->top=20/sizeof(BN_ULONG);
+	bn_fix_top(psign->s);
+
+err:	
+	if (psign)
+	{
+		DSA_SIG_free(psign);
+		psign=NULL;
+	}
+	return psign;
+}
+#endif
+
+static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			     const BIGNUM *m, BN_CTX *ctx)
+{
+	int ret=0;
+	char msg[64]="ENGINE_modexp";
+	if (!p_surewarehk_Mod_Exp)
+	{
+		SUREWAREerr(SUREWARE_F_SUREWAREHK_MODEXP,ENGINE_R_NOT_INITIALISED);
+	}
+	else
+	{
+		bn_expand2(r,m->top);
+		if (r && r->dmax==m->top)
+		{
+			/* do it*/
+			ret=p_surewarehk_Mod_Exp(msg,
+						 m->top*sizeof(BN_ULONG),
+						 (unsigned long *)m->d,
+						 p->top*sizeof(BN_ULONG),
+						 (unsigned long *)p->d,
+						 a->top*sizeof(BN_ULONG),
+						 (unsigned long *)a->d,
+						 (unsigned long *)r->d);
+			surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_MODEXP,ret);
+			if (ret==1)
+			{
+				/* normalise result */
+				r->top=m->top;
+				bn_fix_top(r);
+			}
+		}
+	}
+	return ret;
+}
+#endif /* !OPENSSL_NO_HW_SureWare */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_sureware.ec b/openssl/engines/e_sureware.ec
new file mode 100644
index 0000000..3d266b8
--- /dev/null
+++ b/openssl/engines/e_sureware.ec
@@ -0,0 +1 @@
+L SUREWARE	e_sureware_err.h		e_sureware_err.c
diff --git a/openssl/engines/e_sureware_err.c b/openssl/engines/e_sureware_err.c
new file mode 100644
index 0000000..d4ca68c
--- /dev/null
+++ b/openssl/engines/e_sureware_err.c
@@ -0,0 +1,158 @@
+/* e_sureware_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "e_sureware_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA SUREWARE_str_functs[]=
+	{
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_CTRL),	"SUREWAREHK_CTRL"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_DH_EX_FREE),	"SUREWAREHK_DH_EX_FREE"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN),	"SUREWAREHK_DSA_DO_SIGN"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_EX_FREE),	"SUREWAREHK_EX_FREE"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_FINISH),	"SUREWAREHK_FINISH"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_INIT),	"SUREWAREHK_INIT"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY),	"SUREWAREHK_LOAD_PRIVKEY"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY),	"SUREWAREHK_LOAD_PUBKEY"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_MODEXP),	"SUREWAREHK_MODEXP"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_RAND_BYTES),	"SUREWAREHK_RAND_BYTES"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_RAND_SEED),	"SUREWAREHK_RAND_SEED"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC),	"SUREWAREHK_RSA_PRIV_DEC"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_RSA_SIGN),	"SUREWAREHK_RSA_SIGN"},
+{ERR_FUNC(SUREWARE_F_SUREWARE_LOAD_PUBLIC),	"SUREWARE_LOAD_PUBLIC"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA SUREWARE_str_reasons[]=
+	{
+{ERR_REASON(SUREWARE_R_BIO_WAS_FREED)    ,"bio was freed"},
+{ERR_REASON(SUREWARE_R_MISSING_KEY_COMPONENTS),"missing key components"},
+{ERR_REASON(SUREWARE_R_PADDING_CHECK_FAILED),"padding check failed"},
+{ERR_REASON(SUREWARE_R_REQUEST_FAILED)   ,"request failed"},
+{ERR_REASON(SUREWARE_R_REQUEST_FALLBACK) ,"request fallback"},
+{ERR_REASON(SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL),"size too large or too small"},
+{ERR_REASON(SUREWARE_R_UNIT_FAILURE)     ,"unit failure"},
+{ERR_REASON(SUREWARE_R_UNKNOWN_PADDING_TYPE),"unknown padding type"},
+{0,NULL}
+	};
+
+#endif
+
+#ifdef SUREWARE_LIB_NAME
+static ERR_STRING_DATA SUREWARE_lib_name[]=
+        {
+{0	,SUREWARE_LIB_NAME},
+{0,NULL}
+	};
+#endif
+
+
+static int SUREWARE_lib_error_code=0;
+static int SUREWARE_error_init=1;
+
+static void ERR_load_SUREWARE_strings(void)
+	{
+	if (SUREWARE_lib_error_code == 0)
+		SUREWARE_lib_error_code=ERR_get_next_error_library();
+
+	if (SUREWARE_error_init)
+		{
+		SUREWARE_error_init=0;
+#ifndef OPENSSL_NO_ERR
+		ERR_load_strings(SUREWARE_lib_error_code,SUREWARE_str_functs);
+		ERR_load_strings(SUREWARE_lib_error_code,SUREWARE_str_reasons);
+#endif
+
+#ifdef SUREWARE_LIB_NAME
+		SUREWARE_lib_name->error = ERR_PACK(SUREWARE_lib_error_code,0,0);
+		ERR_load_strings(0,SUREWARE_lib_name);
+#endif
+		}
+	}
+
+static void ERR_unload_SUREWARE_strings(void)
+	{
+	if (SUREWARE_error_init == 0)
+		{
+#ifndef OPENSSL_NO_ERR
+		ERR_unload_strings(SUREWARE_lib_error_code,SUREWARE_str_functs);
+		ERR_unload_strings(SUREWARE_lib_error_code,SUREWARE_str_reasons);
+#endif
+
+#ifdef SUREWARE_LIB_NAME
+		ERR_unload_strings(0,SUREWARE_lib_name);
+#endif
+		SUREWARE_error_init=1;
+		}
+	}
+
+static void ERR_SUREWARE_error(int function, int reason, char *file, int line)
+	{
+	if (SUREWARE_lib_error_code == 0)
+		SUREWARE_lib_error_code=ERR_get_next_error_library();
+	ERR_PUT_error(SUREWARE_lib_error_code,function,reason,file,line);
+	}
diff --git a/openssl/engines/e_sureware_err.h b/openssl/engines/e_sureware_err.h
new file mode 100644
index 0000000..ec8ed0c
--- /dev/null
+++ b/openssl/engines/e_sureware_err.h
@@ -0,0 +1,102 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_SUREWARE_ERR_H
+#define HEADER_SUREWARE_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_SUREWARE_strings(void);
+static void ERR_unload_SUREWARE_strings(void);
+static void ERR_SUREWARE_error(int function, int reason, char *file, int line);
+#define SUREWAREerr(f,r) ERR_SUREWARE_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the SUREWARE functions. */
+
+/* Function codes. */
+#define SUREWARE_F_SUREWAREHK_CTRL			 100
+#define SUREWARE_F_SUREWAREHK_DH_EX_FREE		 112
+#define SUREWARE_F_SUREWAREHK_DSA_DO_SIGN		 101
+#define SUREWARE_F_SUREWAREHK_EX_FREE			 102
+#define SUREWARE_F_SUREWAREHK_FINISH			 103
+#define SUREWARE_F_SUREWAREHK_INIT			 104
+#define SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY		 105
+#define SUREWARE_F_SUREWAREHK_LOAD_PUBKEY		 113
+#define SUREWARE_F_SUREWAREHK_MODEXP			 107
+#define SUREWARE_F_SUREWAREHK_RAND_BYTES		 108
+#define SUREWARE_F_SUREWAREHK_RAND_SEED			 109
+#define SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC		 110
+#define SUREWARE_F_SUREWAREHK_RSA_SIGN			 111
+#define SUREWARE_F_SUREWARE_LOAD_PUBLIC			 106
+
+/* Reason codes. */
+#define SUREWARE_R_BIO_WAS_FREED			 100
+#define SUREWARE_R_MISSING_KEY_COMPONENTS		 105
+#define SUREWARE_R_PADDING_CHECK_FAILED			 106
+#define SUREWARE_R_REQUEST_FAILED			 101
+#define SUREWARE_R_REQUEST_FALLBACK			 102
+#define SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL		 103
+#define SUREWARE_R_UNIT_FAILURE				 104
+#define SUREWARE_R_UNKNOWN_PADDING_TYPE			 107
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_ubsec.c b/openssl/engines/e_ubsec.c
new file mode 100644
index 0000000..aa5709b
--- /dev/null
+++ b/openssl/engines/e_ubsec.c
@@ -0,0 +1,1069 @@
+/* crypto/engine/hw_ubsec.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ *
+ * Cloned shamelessly by Joe Tardo. 
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/dso.h>
+#include <openssl/engine.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_UBSEC
+
+#ifdef FLAT_INC
+#include "hw_ubsec.h"
+#else
+#include "vendor_defns/hw_ubsec.h"
+#endif
+
+#define UBSEC_LIB_NAME "ubsec engine"
+#include "e_ubsec_err.c"
+
+#define FAIL_TO_SOFTWARE -15
+
+static int ubsec_destroy(ENGINE *e);
+static int ubsec_init(ENGINE *e);
+static int ubsec_finish(ENGINE *e);
+static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx);
+#ifndef OPENSSL_NO_RSA
+static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			const BIGNUM *q, const BIGNUM *dp,
+			const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx);
+static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#endif
+#ifndef OPENSSL_NO_DSA
+#ifdef NOT_USED
+static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
+		BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
+		BN_CTX *ctx, BN_MONT_CTX *in_mont);
+static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+		BN_MONT_CTX *m_ctx);
+#endif
+static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
+                                DSA_SIG *sig, DSA *dsa);
+#endif
+#ifndef OPENSSL_NO_DH
+static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
+		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+		BN_MONT_CTX *m_ctx);
+static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh);
+static int ubsec_dh_generate_key(DH *dh);
+#endif
+
+#ifdef NOT_USED
+static int ubsec_rand_bytes(unsigned char *buf, int num);
+static int ubsec_rand_status(void);
+#endif
+
+#define UBSEC_CMD_SO_PATH		ENGINE_CMD_BASE
+static const ENGINE_CMD_DEFN ubsec_cmd_defns[] = {
+	{UBSEC_CMD_SO_PATH,
+		"SO_PATH",
+		"Specifies the path to the 'ubsec' shared library",
+		ENGINE_CMD_FLAG_STRING},
+	{0, NULL, NULL, 0}
+	};
+
+#ifndef OPENSSL_NO_RSA
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD ubsec_rsa =
+	{
+	"UBSEC RSA method",
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	ubsec_rsa_mod_exp,
+	ubsec_mod_exp_mont,
+	NULL,
+	NULL,
+	0,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+	};
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* Our internal DSA_METHOD that we provide pointers to */
+static DSA_METHOD ubsec_dsa =
+	{
+	"UBSEC DSA method",
+	ubsec_dsa_do_sign, /* dsa_do_sign */
+	NULL, /* dsa_sign_setup */
+	ubsec_dsa_verify, /* dsa_do_verify */
+	NULL, /* ubsec_dsa_mod_exp */ /* dsa_mod_exp */
+	NULL, /* ubsec_mod_exp_dsa */ /* bn_mod_exp */
+	NULL, /* init */
+	NULL, /* finish */
+	0, /* flags */
+	NULL, /* app_data */
+	NULL, /* dsa_paramgen */
+	NULL /* dsa_keygen */
+	};
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* Our internal DH_METHOD that we provide pointers to */
+static DH_METHOD ubsec_dh =
+	{
+	"UBSEC DH method",
+	ubsec_dh_generate_key,
+	ubsec_dh_compute_key,
+	ubsec_mod_exp_dh,
+	NULL,
+	NULL,
+	0,
+	NULL,
+	NULL
+	};
+#endif
+
+/* Constants used when creating the ENGINE */
+static const char *engine_ubsec_id = "ubsec";
+static const char *engine_ubsec_name = "UBSEC hardware engine support";
+
+/* This internal function is used by ENGINE_ubsec() and possibly by the
+ * "dynamic" ENGINE support too */
+static int bind_helper(ENGINE *e)
+	{
+#ifndef OPENSSL_NO_RSA
+	const RSA_METHOD *meth1;
+#endif
+#ifndef OPENSSL_NO_DH
+#ifndef HAVE_UBSEC_DH
+	const DH_METHOD *meth3;
+#endif /* HAVE_UBSEC_DH */
+#endif
+	if(!ENGINE_set_id(e, engine_ubsec_id) ||
+			!ENGINE_set_name(e, engine_ubsec_name) ||
+#ifndef OPENSSL_NO_RSA
+			!ENGINE_set_RSA(e, &ubsec_rsa) ||
+#endif
+#ifndef OPENSSL_NO_DSA
+			!ENGINE_set_DSA(e, &ubsec_dsa) ||
+#endif
+#ifndef OPENSSL_NO_DH
+			!ENGINE_set_DH(e, &ubsec_dh) ||
+#endif
+			!ENGINE_set_destroy_function(e, ubsec_destroy) ||
+			!ENGINE_set_init_function(e, ubsec_init) ||
+			!ENGINE_set_finish_function(e, ubsec_finish) ||
+			!ENGINE_set_ctrl_function(e, ubsec_ctrl) ||
+			!ENGINE_set_cmd_defns(e, ubsec_cmd_defns))
+		return 0;
+
+#ifndef OPENSSL_NO_RSA
+	/* We know that the "PKCS1_SSLeay()" functions hook properly
+	 * to the Broadcom-specific mod_exp and mod_exp_crt so we use
+	 * those functions. NB: We don't use ENGINE_openssl() or
+	 * anything "more generic" because something like the RSAref
+	 * code may not hook properly, and if you own one of these
+	 * cards then you have the right to do RSA operations on it
+	 * anyway! */ 
+	meth1 = RSA_PKCS1_SSLeay();
+	ubsec_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+	ubsec_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+	ubsec_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+	ubsec_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+#endif
+
+#ifndef OPENSSL_NO_DH
+#ifndef HAVE_UBSEC_DH
+	/* Much the same for Diffie-Hellman */
+	meth3 = DH_OpenSSL();
+	ubsec_dh.generate_key = meth3->generate_key;
+	ubsec_dh.compute_key = meth3->compute_key;
+#endif /* HAVE_UBSEC_DH */
+#endif
+
+	/* Ensure the ubsec error handling is set up */
+	ERR_load_UBSEC_strings();
+	return 1;
+	}
+
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+static ENGINE *engine_ubsec(void)
+	{
+	ENGINE *ret = ENGINE_new();
+	if(!ret)
+		return NULL;
+	if(!bind_helper(ret))
+		{
+		ENGINE_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+void ENGINE_load_ubsec(void)
+	{
+	/* Copied from eng_[openssl|dyn].c */
+	ENGINE *toadd = engine_ubsec();
+	if(!toadd) return;
+	ENGINE_add(toadd);
+	ENGINE_free(toadd);
+	ERR_clear_error();
+	}
+#endif
+
+/* This is a process-global DSO handle used for loading and unloading
+ * the UBSEC library. NB: This is only set (or unset) during an
+ * init() or finish() call (reference counts permitting) and they're
+ * operating with global locks, so this should be thread-safe
+ * implicitly. */
+
+static DSO *ubsec_dso = NULL;
+
+/* These are the function pointers that are (un)set when the library has
+ * successfully (un)loaded. */
+
+static t_UBSEC_ubsec_bytes_to_bits *p_UBSEC_ubsec_bytes_to_bits = NULL;
+static t_UBSEC_ubsec_bits_to_bytes *p_UBSEC_ubsec_bits_to_bytes = NULL;
+static t_UBSEC_ubsec_open *p_UBSEC_ubsec_open = NULL;
+static t_UBSEC_ubsec_close *p_UBSEC_ubsec_close = NULL;
+#ifndef OPENSSL_NO_DH
+static t_UBSEC_diffie_hellman_generate_ioctl 
+	*p_UBSEC_diffie_hellman_generate_ioctl = NULL;
+static t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl = NULL;
+#endif
+#ifndef OPENSSL_NO_RSA
+static t_UBSEC_rsa_mod_exp_ioctl *p_UBSEC_rsa_mod_exp_ioctl = NULL;
+static t_UBSEC_rsa_mod_exp_crt_ioctl *p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
+#endif
+#ifndef OPENSSL_NO_DSA
+static t_UBSEC_dsa_sign_ioctl *p_UBSEC_dsa_sign_ioctl = NULL;
+static t_UBSEC_dsa_verify_ioctl *p_UBSEC_dsa_verify_ioctl = NULL;
+#endif
+static t_UBSEC_math_accelerate_ioctl *p_UBSEC_math_accelerate_ioctl = NULL;
+static t_UBSEC_rng_ioctl *p_UBSEC_rng_ioctl = NULL;
+static t_UBSEC_max_key_len_ioctl *p_UBSEC_max_key_len_ioctl = NULL;
+
+static int max_key_len = 1024;  /* ??? */
+
+/* 
+ * These are the static string constants for the DSO file name and the function
+ * symbol names to bind to. 
+ */
+
+static const char *UBSEC_LIBNAME = NULL;
+static const char *get_UBSEC_LIBNAME(void)
+	{
+	if(UBSEC_LIBNAME)
+		return UBSEC_LIBNAME;
+	return "ubsec";
+	}
+static void free_UBSEC_LIBNAME(void)
+	{
+	if(UBSEC_LIBNAME)
+		OPENSSL_free((void*)UBSEC_LIBNAME);
+	UBSEC_LIBNAME = NULL;
+	}
+static long set_UBSEC_LIBNAME(const char *name)
+	{
+	free_UBSEC_LIBNAME();
+	return (((UBSEC_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
+	}
+static const char *UBSEC_F1 = "ubsec_bytes_to_bits";
+static const char *UBSEC_F2 = "ubsec_bits_to_bytes";
+static const char *UBSEC_F3 = "ubsec_open";
+static const char *UBSEC_F4 = "ubsec_close";
+#ifndef OPENSSL_NO_DH
+static const char *UBSEC_F5 = "diffie_hellman_generate_ioctl";
+static const char *UBSEC_F6 = "diffie_hellman_agree_ioctl";
+#endif
+/* #ifndef OPENSSL_NO_RSA */
+static const char *UBSEC_F7 = "rsa_mod_exp_ioctl";
+static const char *UBSEC_F8 = "rsa_mod_exp_crt_ioctl";
+/* #endif */
+#ifndef OPENSSL_NO_DSA
+static const char *UBSEC_F9 = "dsa_sign_ioctl";
+static const char *UBSEC_F10 = "dsa_verify_ioctl";
+#endif
+static const char *UBSEC_F11 = "math_accelerate_ioctl";
+static const char *UBSEC_F12 = "rng_ioctl";
+static const char *UBSEC_F13 = "ubsec_max_key_len_ioctl";
+
+/* Destructor (complements the "ENGINE_ubsec()" constructor) */
+static int ubsec_destroy(ENGINE *e)
+	{
+	free_UBSEC_LIBNAME();
+	ERR_unload_UBSEC_strings();
+	return 1;
+	}
+
+/* (de)initialisation functions. */
+static int ubsec_init(ENGINE *e)
+	{
+	t_UBSEC_ubsec_bytes_to_bits *p1;
+	t_UBSEC_ubsec_bits_to_bytes *p2;
+	t_UBSEC_ubsec_open *p3;
+	t_UBSEC_ubsec_close *p4;
+#ifndef OPENSSL_NO_DH
+	t_UBSEC_diffie_hellman_generate_ioctl *p5;
+	t_UBSEC_diffie_hellman_agree_ioctl *p6;
+#endif
+/* #ifndef OPENSSL_NO_RSA */
+	t_UBSEC_rsa_mod_exp_ioctl *p7;
+	t_UBSEC_rsa_mod_exp_crt_ioctl *p8;
+/* #endif */
+#ifndef OPENSSL_NO_DSA
+	t_UBSEC_dsa_sign_ioctl *p9;
+	t_UBSEC_dsa_verify_ioctl *p10;
+#endif
+	t_UBSEC_math_accelerate_ioctl *p11;
+	t_UBSEC_rng_ioctl *p12;
+        t_UBSEC_max_key_len_ioctl *p13;
+	int fd = 0;
+
+	if(ubsec_dso != NULL)
+		{
+		UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_ALREADY_LOADED);
+		goto err;
+		}
+	/* 
+	 * Attempt to load libubsec.so/ubsec.dll/whatever. 
+	 */
+	ubsec_dso = DSO_load(NULL, get_UBSEC_LIBNAME(), NULL, 0);
+	if(ubsec_dso == NULL)
+		{
+		UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
+		goto err;
+		}
+
+	if (
+	!(p1 = (t_UBSEC_ubsec_bytes_to_bits *) DSO_bind_func(ubsec_dso, UBSEC_F1)) ||
+	!(p2 = (t_UBSEC_ubsec_bits_to_bytes *) DSO_bind_func(ubsec_dso, UBSEC_F2)) ||
+	!(p3 = (t_UBSEC_ubsec_open *) DSO_bind_func(ubsec_dso, UBSEC_F3)) ||
+	!(p4 = (t_UBSEC_ubsec_close *) DSO_bind_func(ubsec_dso, UBSEC_F4)) ||
+#ifndef OPENSSL_NO_DH
+	!(p5 = (t_UBSEC_diffie_hellman_generate_ioctl *) 
+				DSO_bind_func(ubsec_dso, UBSEC_F5)) ||
+	!(p6 = (t_UBSEC_diffie_hellman_agree_ioctl *) 
+				DSO_bind_func(ubsec_dso, UBSEC_F6)) ||
+#endif
+/* #ifndef OPENSSL_NO_RSA */
+	!(p7 = (t_UBSEC_rsa_mod_exp_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F7)) ||
+	!(p8 = (t_UBSEC_rsa_mod_exp_crt_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F8)) ||
+/* #endif */
+#ifndef OPENSSL_NO_DSA
+	!(p9 = (t_UBSEC_dsa_sign_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F9)) ||
+	!(p10 = (t_UBSEC_dsa_verify_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F10)) ||
+#endif
+	!(p11 = (t_UBSEC_math_accelerate_ioctl *) 
+				DSO_bind_func(ubsec_dso, UBSEC_F11)) ||
+	!(p12 = (t_UBSEC_rng_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F12)) ||
+        !(p13 = (t_UBSEC_max_key_len_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F13)))
+		{
+		UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
+		goto err;
+		}
+
+	/* Copy the pointers */
+	p_UBSEC_ubsec_bytes_to_bits = p1;
+	p_UBSEC_ubsec_bits_to_bytes = p2;
+	p_UBSEC_ubsec_open = p3;
+	p_UBSEC_ubsec_close = p4;
+#ifndef OPENSSL_NO_DH
+	p_UBSEC_diffie_hellman_generate_ioctl = p5;
+	p_UBSEC_diffie_hellman_agree_ioctl = p6;
+#endif
+#ifndef OPENSSL_NO_RSA
+	p_UBSEC_rsa_mod_exp_ioctl = p7;
+	p_UBSEC_rsa_mod_exp_crt_ioctl = p8;
+#endif
+#ifndef OPENSSL_NO_DSA
+	p_UBSEC_dsa_sign_ioctl = p9;
+	p_UBSEC_dsa_verify_ioctl = p10;
+#endif
+	p_UBSEC_math_accelerate_ioctl = p11;
+	p_UBSEC_rng_ioctl = p12;
+        p_UBSEC_max_key_len_ioctl = p13;
+
+	/* Perform an open to see if there's actually any unit running. */
+	if (((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0) && (p_UBSEC_max_key_len_ioctl(fd, &max_key_len) == 0))
+	{
+	   p_UBSEC_ubsec_close(fd);
+	   return 1;
+	}
+	else
+	{
+	  UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
+	}
+
+err:
+	if(ubsec_dso)
+		DSO_free(ubsec_dso);
+	ubsec_dso = NULL;
+	p_UBSEC_ubsec_bytes_to_bits = NULL;
+	p_UBSEC_ubsec_bits_to_bytes = NULL;
+	p_UBSEC_ubsec_open = NULL;
+	p_UBSEC_ubsec_close = NULL;
+#ifndef OPENSSL_NO_DH
+	p_UBSEC_diffie_hellman_generate_ioctl = NULL;
+	p_UBSEC_diffie_hellman_agree_ioctl = NULL;
+#endif
+#ifndef OPENSSL_NO_RSA
+	p_UBSEC_rsa_mod_exp_ioctl = NULL;
+	p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
+#endif
+#ifndef OPENSSL_NO_DSA
+	p_UBSEC_dsa_sign_ioctl = NULL;
+	p_UBSEC_dsa_verify_ioctl = NULL;
+#endif
+	p_UBSEC_math_accelerate_ioctl = NULL;
+	p_UBSEC_rng_ioctl = NULL;
+        p_UBSEC_max_key_len_ioctl = NULL;
+
+	return 0;
+	}
+
+static int ubsec_finish(ENGINE *e)
+	{
+	free_UBSEC_LIBNAME();
+	if(ubsec_dso == NULL)
+		{
+		UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_NOT_LOADED);
+		return 0;
+		}
+	if(!DSO_free(ubsec_dso))
+		{
+		UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_DSO_FAILURE);
+		return 0;
+		}
+	ubsec_dso = NULL;
+	p_UBSEC_ubsec_bytes_to_bits = NULL;
+	p_UBSEC_ubsec_bits_to_bytes = NULL;
+	p_UBSEC_ubsec_open = NULL;
+	p_UBSEC_ubsec_close = NULL;
+#ifndef OPENSSL_NO_DH
+	p_UBSEC_diffie_hellman_generate_ioctl = NULL;
+	p_UBSEC_diffie_hellman_agree_ioctl = NULL;
+#endif
+#ifndef OPENSSL_NO_RSA
+	p_UBSEC_rsa_mod_exp_ioctl = NULL;
+	p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
+#endif
+#ifndef OPENSSL_NO_DSA
+	p_UBSEC_dsa_sign_ioctl = NULL;
+	p_UBSEC_dsa_verify_ioctl = NULL;
+#endif
+	p_UBSEC_math_accelerate_ioctl = NULL;
+	p_UBSEC_rng_ioctl = NULL;
+        p_UBSEC_max_key_len_ioctl = NULL;
+	return 1;
+	}
+
+static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+	{
+	int initialised = ((ubsec_dso == NULL) ? 0 : 1);
+	switch(cmd)
+		{
+	case UBSEC_CMD_SO_PATH:
+		if(p == NULL)
+			{
+			UBSECerr(UBSEC_F_UBSEC_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+			return 0;
+			}
+		if(initialised)
+			{
+			UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_ALREADY_LOADED);
+			return 0;
+			}
+		return set_UBSEC_LIBNAME((const char *)p);
+	default:
+		break;
+		}
+	UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+	return 0;
+	}
+
+static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx)
+	{
+	int 	y_len = 0;
+	int 	fd;
+
+	if(ubsec_dso == NULL)
+	{
+		UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_NOT_LOADED);
+		return 0;
+	}
+
+	/* Check if hardware can't handle this argument. */
+	y_len = BN_num_bits(m);
+	if (y_len > max_key_len) {
+		UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+                return BN_mod_exp(r, a, p, m, ctx);
+	} 
+
+	if(!bn_wexpand(r, m->top))
+	{
+		UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_BN_EXPAND_FAIL);
+		return 0;
+	}
+
+	if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
+		fd = 0;
+		UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_UNIT_FAILURE);
+                return BN_mod_exp(r, a, p, m, ctx);
+	}
+
+	if (p_UBSEC_rsa_mod_exp_ioctl(fd, (unsigned char *)a->d, BN_num_bits(a),
+		(unsigned char *)m->d, BN_num_bits(m), (unsigned char *)p->d, 
+		BN_num_bits(p), (unsigned char *)r->d, &y_len) != 0)
+	{
+		UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED);
+                p_UBSEC_ubsec_close(fd);
+
+                return BN_mod_exp(r, a, p, m, ctx);
+	}
+
+	p_UBSEC_ubsec_close(fd);
+
+	r->top = (BN_num_bits(m)+BN_BITS2-1)/BN_BITS2;
+	return 1;
+	}
+
+#ifndef OPENSSL_NO_RSA
+static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+	{
+	int to_return = 0;
+
+	if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
+		{
+		UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP, UBSEC_R_MISSING_KEY_COMPONENTS);
+		goto err;
+		}
+
+	to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
+		    rsa->dmq1, rsa->iqmp, ctx);
+	if (to_return == FAIL_TO_SOFTWARE)
+	{
+	  /*
+	   * Do in software as hardware failed.
+	   */
+	   const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+	   to_return = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
+	}
+err:
+	return to_return;
+	}
+
+static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			const BIGNUM *q, const BIGNUM *dp,
+			const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx)
+	{
+	int	y_len,
+		fd;
+
+	y_len = BN_num_bits(p) + BN_num_bits(q);
+
+	/* Check if hardware can't handle this argument. */
+	if (y_len > max_key_len) {
+		UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+		return FAIL_TO_SOFTWARE;
+	} 
+
+	if (!bn_wexpand(r, p->top + q->top + 1)) {
+		UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_BN_EXPAND_FAIL);
+		return 0;
+	}
+
+	if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
+		fd = 0;
+		UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_UNIT_FAILURE);
+		return FAIL_TO_SOFTWARE;
+	}
+
+	if (p_UBSEC_rsa_mod_exp_crt_ioctl(fd,
+		(unsigned char *)a->d, BN_num_bits(a), 
+		(unsigned char *)qinv->d, BN_num_bits(qinv),
+		(unsigned char *)dp->d, BN_num_bits(dp),
+		(unsigned char *)p->d, BN_num_bits(p),
+		(unsigned char *)dq->d, BN_num_bits(dq),
+		(unsigned char *)q->d, BN_num_bits(q),
+		(unsigned char *)r->d,  &y_len) != 0) {
+		UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_REQUEST_FAILED);
+                p_UBSEC_ubsec_close(fd);
+		return FAIL_TO_SOFTWARE;
+	}
+
+	p_UBSEC_ubsec_close(fd);
+
+	r->top = (BN_num_bits(p) + BN_num_bits(q) + BN_BITS2 - 1)/BN_BITS2;
+	return 1;
+}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+#ifdef NOT_USED
+static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
+		BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
+		BN_CTX *ctx, BN_MONT_CTX *in_mont)
+	{
+	BIGNUM t;
+	int to_return = 0;
+ 
+	BN_init(&t);
+	/* let rr = a1 ^ p1 mod m */
+	if (!ubsec_mod_exp(rr,a1,p1,m,ctx)) goto end;
+	/* let t = a2 ^ p2 mod m */
+	if (!ubsec_mod_exp(&t,a2,p2,m,ctx)) goto end;
+	/* let rr = rr * t mod m */
+	if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
+	to_return = 1;
+end:
+	BN_free(&t);
+	return to_return;
+	}
+
+static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+		BN_MONT_CTX *m_ctx)
+	{
+	return ubsec_mod_exp(r, a, p, m, ctx);
+	}
+#endif
+#endif
+
+#ifndef OPENSSL_NO_RSA
+
+/*
+ * This function is aliased to mod_exp (with the mont stuff dropped).
+ */
+static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+        {
+	int ret = 0;
+
+ 	/* Do in software if the key is too large for the hardware. */
+	if (BN_num_bits(m) > max_key_len)
+                {
+		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+		ret = (*meth->bn_mod_exp)(r, a, p, m, ctx, m_ctx);
+                }
+        else
+                {
+		ret = ubsec_mod_exp(r, a, p, m, ctx);
+                }
+	
+	return ret;
+        }
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
+		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+		BN_MONT_CTX *m_ctx)
+	{
+	return ubsec_mod_exp(r, a, p, m, ctx);
+	}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+	{
+	DSA_SIG *to_return = NULL;
+	int s_len = 160, r_len = 160, d_len, fd;
+	BIGNUM m, *r=NULL, *s=NULL;
+
+	BN_init(&m);
+
+	s = BN_new();
+	r = BN_new();
+	if ((s == NULL) || (r==NULL))
+		goto err;
+
+	d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dlen);
+
+        if(!bn_wexpand(r, (160+BN_BITS2-1)/BN_BITS2) ||
+       	   (!bn_wexpand(s, (160+BN_BITS2-1)/BN_BITS2))) {
+		UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
+		goto err;
+	}
+
+	if (BN_bin2bn(dgst,dlen,&m) == NULL) {
+		UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
+		goto err;
+	} 
+
+	if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
+                const DSA_METHOD *meth;
+		fd = 0;
+		UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_UNIT_FAILURE);
+                meth = DSA_OpenSSL();
+                to_return =  meth->dsa_do_sign(dgst, dlen, dsa);
+		goto err;
+	}
+
+	if (p_UBSEC_dsa_sign_ioctl(fd, 0, /* compute hash before signing */
+		(unsigned char *)dgst, d_len,
+		NULL, 0,  /* compute random value */
+		(unsigned char *)dsa->p->d, BN_num_bits(dsa->p), 
+		(unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
+		(unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
+		(unsigned char *)dsa->priv_key->d, BN_num_bits(dsa->priv_key),
+		(unsigned char *)r->d, &r_len,
+		(unsigned char *)s->d, &s_len ) != 0) {
+                const DSA_METHOD *meth;
+
+		UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_REQUEST_FAILED);
+                p_UBSEC_ubsec_close(fd);
+                meth = DSA_OpenSSL();
+                to_return = meth->dsa_do_sign(dgst, dlen, dsa);
+
+		goto err;
+	}
+
+	p_UBSEC_ubsec_close(fd);
+
+	r->top = (160+BN_BITS2-1)/BN_BITS2;
+	s->top = (160+BN_BITS2-1)/BN_BITS2;
+
+	to_return = DSA_SIG_new();
+	if(to_return == NULL) {
+		UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
+		goto err;
+	}
+
+	to_return->r = r;
+	to_return->s = s;
+
+err:
+	if (!to_return) {
+		if (r) BN_free(r);
+		if (s) BN_free(s);
+	}                                 
+	BN_clear_free(&m);
+	return to_return;
+}
+
+static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
+                                DSA_SIG *sig, DSA *dsa)
+	{
+	int v_len, d_len;
+	int to_return = 0;
+	int fd;
+	BIGNUM v, *pv = &v;
+
+	BN_init(&v);
+
+	if(!bn_wexpand(pv, dsa->p->top)) {
+		UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_BN_EXPAND_FAIL);
+		goto err;
+	}
+
+	v_len = BN_num_bits(dsa->p);
+
+	d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len);
+
+	if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
+                const DSA_METHOD *meth;
+		fd = 0;
+		UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_UNIT_FAILURE);
+                meth = DSA_OpenSSL();
+                to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
+		goto err;
+	}
+
+	if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */
+		(unsigned char *)dgst, d_len,
+		(unsigned char *)dsa->p->d, BN_num_bits(dsa->p), 
+		(unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
+		(unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
+		(unsigned char *)dsa->pub_key->d, BN_num_bits(dsa->pub_key),
+		(unsigned char *)sig->r->d, BN_num_bits(sig->r),
+		(unsigned char *)sig->s->d, BN_num_bits(sig->s),
+		(unsigned char *)v.d, &v_len) != 0) {
+                const DSA_METHOD *meth;
+		UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_REQUEST_FAILED);
+                p_UBSEC_ubsec_close(fd);
+
+                meth = DSA_OpenSSL();
+                to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
+
+		goto err;
+	}
+
+	p_UBSEC_ubsec_close(fd);
+
+	to_return = 1;
+err:
+	BN_clear_free(&v);
+	return to_return;
+	}
+#endif
+
+#ifndef OPENSSL_NO_DH
+static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh)
+        {
+        int      ret      = -1,
+                 k_len,
+                 fd;
+
+        k_len = BN_num_bits(dh->p);
+
+        if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
+                {
+                const DH_METHOD *meth;
+                UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_UNIT_FAILURE);
+                meth = DH_OpenSSL();
+                ret = meth->compute_key(key, pub_key, dh);
+                goto err;
+                }
+
+        if (p_UBSEC_diffie_hellman_agree_ioctl(fd,
+                                               (unsigned char *)dh->priv_key->d, BN_num_bits(dh->priv_key),
+                                               (unsigned char *)pub_key->d, BN_num_bits(pub_key),
+                                               (unsigned char *)dh->p->d, BN_num_bits(dh->p),
+                                               key, &k_len) != 0)
+                {
+                /* Hardware's a no go, failover to software */
+                const DH_METHOD *meth;
+                UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_REQUEST_FAILED);
+                p_UBSEC_ubsec_close(fd);
+
+                meth = DH_OpenSSL();
+                ret = meth->compute_key(key, pub_key, dh);
+
+                goto err;
+                }
+
+        p_UBSEC_ubsec_close(fd);
+
+        ret = p_UBSEC_ubsec_bits_to_bytes(k_len);
+err:
+        return ret;
+        }
+
+static int ubsec_dh_generate_key(DH *dh)
+        {
+        int      ret               = 0,
+                 random_bits       = 0,
+                 pub_key_len       = 0,
+                 priv_key_len      = 0,
+                 fd;
+        BIGNUM   *pub_key          = NULL;
+        BIGNUM   *priv_key         = NULL;
+
+        /* 
+         *  How many bits should Random x be? dh_key.c
+         *  sets the range from 0 to num_bits(modulus) ???
+         */
+
+        if (dh->priv_key == NULL)
+                {
+                priv_key = BN_new();
+                if (priv_key == NULL) goto err;
+                priv_key_len = BN_num_bits(dh->p);
+                if(bn_wexpand(priv_key, dh->p->top) == NULL) goto err;
+                do
+                        if (!BN_rand_range(priv_key, dh->p)) goto err;
+                while (BN_is_zero(priv_key));
+                random_bits = BN_num_bits(priv_key);
+                }
+        else
+                {
+                priv_key = dh->priv_key;
+                }
+
+        if (dh->pub_key == NULL)
+                {
+                pub_key = BN_new();
+                pub_key_len = BN_num_bits(dh->p);
+                if(bn_wexpand(pub_key, dh->p->top) == NULL) goto err;
+                if(pub_key == NULL) goto err;
+                }
+        else
+                {
+                pub_key = dh->pub_key;
+                }
+
+        if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
+                {
+                const DH_METHOD *meth;
+                UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_UNIT_FAILURE);
+                meth = DH_OpenSSL();
+                ret = meth->generate_key(dh);
+                goto err;
+                }
+
+        if (p_UBSEC_diffie_hellman_generate_ioctl(fd,
+                                                  (unsigned char *)priv_key->d, &priv_key_len,
+                                                  (unsigned char *)pub_key->d,  &pub_key_len,
+                                                  (unsigned char *)dh->g->d, BN_num_bits(dh->g),
+                                                  (unsigned char *)dh->p->d, BN_num_bits(dh->p),
+                                                  0, 0, random_bits) != 0)
+                {
+                /* Hardware's a no go, failover to software */
+                const DH_METHOD *meth;
+
+                UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_REQUEST_FAILED);
+                p_UBSEC_ubsec_close(fd);
+
+                meth = DH_OpenSSL();
+                ret = meth->generate_key(dh);
+
+                goto err;
+                }
+
+        p_UBSEC_ubsec_close(fd);
+
+        dh->pub_key = pub_key;
+        dh->pub_key->top = (pub_key_len + BN_BITS2-1) / BN_BITS2;
+        dh->priv_key = priv_key;
+        dh->priv_key->top = (priv_key_len + BN_BITS2-1) / BN_BITS2;
+
+        ret = 1;
+err:
+        return ret;
+        }
+#endif
+
+#ifdef NOT_USED
+static int ubsec_rand_bytes(unsigned char * buf,
+                            int num)
+        {
+        int      ret      = 0,
+                 fd;
+
+        if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
+                {
+                const RAND_METHOD *meth;
+                UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_UNIT_FAILURE);
+                num = p_UBSEC_ubsec_bits_to_bytes(num);
+                meth = RAND_SSLeay();
+                meth->seed(buf, num);
+                ret = meth->bytes(buf, num);
+                goto err;
+                }
+
+        num *= 8; /* bytes to bits */
+
+        if (p_UBSEC_rng_ioctl(fd,
+                              UBSEC_RNG_DIRECT,
+                              buf,
+                              &num) != 0)
+                {
+                /* Hardware's a no go, failover to software */
+                const RAND_METHOD *meth;
+
+                UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_REQUEST_FAILED);
+                p_UBSEC_ubsec_close(fd);
+
+                num = p_UBSEC_ubsec_bits_to_bytes(num);
+                meth = RAND_SSLeay();
+                meth->seed(buf, num);
+                ret = meth->bytes(buf, num);
+
+                goto err;
+                }
+
+        p_UBSEC_ubsec_close(fd);
+
+        ret = 1;
+err:
+        return(ret);
+        }
+
+
+static int ubsec_rand_status(void)
+	{
+	return 0;
+	}
+#endif
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library. */
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_fn(ENGINE *e, const char *id)
+	{
+	if(id && (strcmp(id, engine_ubsec_id) != 0))
+		return 0;
+	if(!bind_helper(e))
+		return 0;
+	return 1;
+	}
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
+
+#endif /* !OPENSSL_NO_HW_UBSEC */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_ubsec.ec b/openssl/engines/e_ubsec.ec
new file mode 100644
index 0000000..99b9233
--- /dev/null
+++ b/openssl/engines/e_ubsec.ec
@@ -0,0 +1 @@
+L UBSEC		e_ubsec_err.h			e_ubsec_err.c
diff --git a/openssl/engines/e_ubsec_err.c b/openssl/engines/e_ubsec_err.c
new file mode 100644
index 0000000..14c3d61
--- /dev/null
+++ b/openssl/engines/e_ubsec_err.c
@@ -0,0 +1,157 @@
+/* e_ubsec_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "e_ubsec_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA UBSEC_str_functs[]=
+	{
+{ERR_FUNC(UBSEC_F_UBSEC_CTRL),	"UBSEC_CTRL"},
+{ERR_FUNC(UBSEC_F_UBSEC_DH_COMPUTE_KEY),	"UBSEC_DH_COMPUTE_KEY"},
+{ERR_FUNC(UBSEC_F_UBSEC_DH_GENERATE_KEY),	"UBSEC_DH_GENERATE_KEY"},
+{ERR_FUNC(UBSEC_F_UBSEC_DSA_DO_SIGN),	"UBSEC_DSA_DO_SIGN"},
+{ERR_FUNC(UBSEC_F_UBSEC_DSA_VERIFY),	"UBSEC_DSA_VERIFY"},
+{ERR_FUNC(UBSEC_F_UBSEC_FINISH),	"UBSEC_FINISH"},
+{ERR_FUNC(UBSEC_F_UBSEC_INIT),	"UBSEC_INIT"},
+{ERR_FUNC(UBSEC_F_UBSEC_MOD_EXP),	"UBSEC_MOD_EXP"},
+{ERR_FUNC(UBSEC_F_UBSEC_MOD_EXP_CRT),	"UBSEC_MOD_EXP_CRT"},
+{ERR_FUNC(UBSEC_F_UBSEC_RAND_BYTES),	"UBSEC_RAND_BYTES"},
+{ERR_FUNC(UBSEC_F_UBSEC_RSA_MOD_EXP),	"UBSEC_RSA_MOD_EXP"},
+{ERR_FUNC(UBSEC_F_UBSEC_RSA_MOD_EXP_CRT),	"UBSEC_RSA_MOD_EXP_CRT"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA UBSEC_str_reasons[]=
+	{
+{ERR_REASON(UBSEC_R_ALREADY_LOADED)      ,"already loaded"},
+{ERR_REASON(UBSEC_R_BN_EXPAND_FAIL)      ,"bn expand fail"},
+{ERR_REASON(UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
+{ERR_REASON(UBSEC_R_DSO_FAILURE)         ,"dso failure"},
+{ERR_REASON(UBSEC_R_MISSING_KEY_COMPONENTS),"missing key components"},
+{ERR_REASON(UBSEC_R_NOT_LOADED)          ,"not loaded"},
+{ERR_REASON(UBSEC_R_REQUEST_FAILED)      ,"request failed"},
+{ERR_REASON(UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL),"size too large or too small"},
+{ERR_REASON(UBSEC_R_UNIT_FAILURE)        ,"unit failure"},
+{0,NULL}
+	};
+
+#endif
+
+#ifdef UBSEC_LIB_NAME
+static ERR_STRING_DATA UBSEC_lib_name[]=
+        {
+{0	,UBSEC_LIB_NAME},
+{0,NULL}
+	};
+#endif
+
+
+static int UBSEC_lib_error_code=0;
+static int UBSEC_error_init=1;
+
+static void ERR_load_UBSEC_strings(void)
+	{
+	if (UBSEC_lib_error_code == 0)
+		UBSEC_lib_error_code=ERR_get_next_error_library();
+
+	if (UBSEC_error_init)
+		{
+		UBSEC_error_init=0;
+#ifndef OPENSSL_NO_ERR
+		ERR_load_strings(UBSEC_lib_error_code,UBSEC_str_functs);
+		ERR_load_strings(UBSEC_lib_error_code,UBSEC_str_reasons);
+#endif
+
+#ifdef UBSEC_LIB_NAME
+		UBSEC_lib_name->error = ERR_PACK(UBSEC_lib_error_code,0,0);
+		ERR_load_strings(0,UBSEC_lib_name);
+#endif
+		}
+	}
+
+static void ERR_unload_UBSEC_strings(void)
+	{
+	if (UBSEC_error_init == 0)
+		{
+#ifndef OPENSSL_NO_ERR
+		ERR_unload_strings(UBSEC_lib_error_code,UBSEC_str_functs);
+		ERR_unload_strings(UBSEC_lib_error_code,UBSEC_str_reasons);
+#endif
+
+#ifdef UBSEC_LIB_NAME
+		ERR_unload_strings(0,UBSEC_lib_name);
+#endif
+		UBSEC_error_init=1;
+		}
+	}
+
+static void ERR_UBSEC_error(int function, int reason, char *file, int line)
+	{
+	if (UBSEC_lib_error_code == 0)
+		UBSEC_lib_error_code=ERR_get_next_error_library();
+	ERR_PUT_error(UBSEC_lib_error_code,function,reason,file,line);
+	}
diff --git a/openssl/engines/e_ubsec_err.h b/openssl/engines/e_ubsec_err.h
new file mode 100644
index 0000000..b10b238
--- /dev/null
+++ b/openssl/engines/e_ubsec_err.h
@@ -0,0 +1,101 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_UBSEC_ERR_H
+#define HEADER_UBSEC_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_UBSEC_strings(void);
+static void ERR_unload_UBSEC_strings(void);
+static void ERR_UBSEC_error(int function, int reason, char *file, int line);
+#define UBSECerr(f,r) ERR_UBSEC_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the UBSEC functions. */
+
+/* Function codes. */
+#define UBSEC_F_UBSEC_CTRL				 100
+#define UBSEC_F_UBSEC_DH_COMPUTE_KEY			 101
+#define UBSEC_F_UBSEC_DH_GENERATE_KEY			 111
+#define UBSEC_F_UBSEC_DSA_DO_SIGN			 102
+#define UBSEC_F_UBSEC_DSA_VERIFY			 103
+#define UBSEC_F_UBSEC_FINISH				 104
+#define UBSEC_F_UBSEC_INIT				 105
+#define UBSEC_F_UBSEC_MOD_EXP				 106
+#define UBSEC_F_UBSEC_MOD_EXP_CRT			 110
+#define UBSEC_F_UBSEC_RAND_BYTES			 107
+#define UBSEC_F_UBSEC_RSA_MOD_EXP			 108
+#define UBSEC_F_UBSEC_RSA_MOD_EXP_CRT			 109
+
+/* Reason codes. */
+#define UBSEC_R_ALREADY_LOADED				 100
+#define UBSEC_R_BN_EXPAND_FAIL				 101
+#define UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED		 102
+#define UBSEC_R_DSO_FAILURE				 103
+#define UBSEC_R_MISSING_KEY_COMPONENTS			 104
+#define UBSEC_R_NOT_LOADED				 105
+#define UBSEC_R_REQUEST_FAILED				 106
+#define UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL		 107
+#define UBSEC_R_UNIT_FAILURE				 108
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/engine_vector.mar b/openssl/engines/engine_vector.mar
new file mode 100644
index 0000000..7d968e7
--- /dev/null
+++ b/openssl/engines/engine_vector.mar
@@ -0,0 +1,24 @@
+;
+; Transfer vector for VAX shareable image
+;
+	.TITLE ENGINE
+	.IDENT /ENGINE/
+;
+; Define macro to assist in building transfer vector entries.  Each entry
+; should take no more than 8 bytes.
+;
+	.MACRO FTRANSFER_ENTRY routine
+	.ALIGN QUAD
+	.TRANSFER routine
+	.MASK	routine
+	JMP	routine+2
+	.ENDM FTRANSFER_ENTRY
+;
+; Place entries in own program section.
+;
+	.PSECT $$ENGINE,QUAD,PIC,USR,CON,REL,LCL,SHR,EXE,RD,NOWRT
+ENGINE_xfer:
+	FTRANSFER_ENTRY bind_engine
+	FTRANSFER_ENTRY v_check
+	.BLKB 32768-<.-ENGINE_xfer>	; 64 pages total.
+	.END
diff --git a/openssl/engines/ia64.opt b/openssl/engines/ia64.opt
new file mode 100644
index 0000000..1dc71bf
--- /dev/null
+++ b/openssl/engines/ia64.opt
@@ -0,0 +1 @@
+SYMBOL_VECTOR=(bind_engine=PROCEDURE,v_check=PROCEDURE)
diff --git a/openssl/engines/makeengines.com b/openssl/engines/makeengines.com
new file mode 100644
index 0000000..6329fbb
--- /dev/null
+++ b/openssl/engines/makeengines.com
@@ -0,0 +1,1125 @@
+$!
+$!  MAKEENGINES.COM
+$!  Written By:  Richard Levitte
+$!               richard@levitte.org
+$!
+$!  This command file compiles and creates the various engines in form
+$!  of shared images.  They are placed in [.xxx.EXE.ENGINES], where "xxx"
+$!  is ALPHA, IA64 or VAX, depending on your hardware.
+$!
+$!  P1	if this is ENGINES or ALL, the engines will build, otherwise not.
+$!
+$!  P2	DEBUG or NODEBUG to compile with or without debugger information.
+$!
+$!  P3  VAXC		for VAX C
+$!	DECC		for DEC C
+$!	GNUC		for GNU C (untested)
+$!
+$!  P4	if defined, sets the TCP/IP libraries to use.  UCX or TCPIP is
+$!	used by default since most other implementations come with a
+$!	compatibility library.  The value must be one of the following:
+$!
+$!	UCX		for UCX
+$!	SOCKETSHR	for SOCKETSHR+NETLIB
+$!	TCPIP		for TCPIP (post UCX)
+$!
+$!  P5	if defined, tells the compiler not to use special threads.
+$!
+$!  P6	if defined, denotes which engines to build.  If not defined,
+$!	all available engines are built.
+$!
+$!  P7, if defined, specifies the C pointer size.  Ignored on VAX.
+$!      ("64=ARGV" gives more efficient code with HP C V7.3 or newer.)
+$!      Supported values are:
+$!
+$!	""	Compile with default (/NOPOINTER_SIZE)
+$!	32	Compile with /POINTER_SIZE=32 (SHORT)
+$!	64	Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV])
+$!               (Automatically select ARGV if compiler supports it.)
+$!      64=      Compile with /POINTER_SIZE=64 (LONG).
+$!      64=ARGV  Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV).
+$!
+$!  P8, if defined, specifies a directory where ZLIB files (zlib.h,
+$!  libz.olb) may be found.  Optionally, a non-default object library
+$!  name may be included ("dev:[dir]libz_64.olb", for example).
+$!
+$!-----------------------------------------------------------------------------
+$!
+$! Announce/identify.
+$!
+$ proc = f$environment( "procedure")
+$ write sys$output "@@@ "+ -
+   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
+$!
+$ on control_c then goto exit
+$!
+$! Set the default TCP/IP library to link against if needed
+$!
+$ TCPIP_LIB = ""
+$ ZLIB_LIB = ""
+$!
+$! Check What Architecture We Are Using.
+$!
+$ IF (F$GETSYI("CPU").LT.128)
+$ THEN
+$!
+$!  The Architecture Is VAX.
+$!
+$   ARCH = "VAX"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  The Architecture Is Alpha, IA64 or whatever comes in the future.
+$!
+$   ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
+$   IF (ARCH .EQS. "") THEN ARCH = "UNK"
+$!
+$! End The Architecture Check.
+$!
+$ ENDIF
+$!
+$ ARCHD = ARCH
+$ LIB32 = "32"
+$ OPT_FILE = ""
+$ POINTER_SIZE = ""
+$!
+$! Set the names of the engines we want to build
+$! NOTE: Some might think this list ugly.  However, it's made this way to
+$! reflect the LIBNAMES variable in Makefile as closely as possible,
+$! thereby making it fairly easy to verify that the lists are the same.
+$! NOTE: gmp isn't built, as it's mostly a test engine and brings in another
+$! library that isn't necessarely ported to VMS.
+$!
+$ ENGINES = "," + P6
+$ IF ENGINES .EQS. "," THEN -
+	ENGINES = ",4758cca,aep,atalla,cswift,chil,nuron,sureware,ubsec,padlock,"
+$!
+$! GOST requires a 64-bit integer type, unavailable on VAX.
+$!
+$ IF (ARCH .NES. "VAX") THEN -
+       ENGINES = ENGINES+ ",ccgost"
+$!
+$! Check options.
+$!
+$ OPT_PHASE = P1
+$ ACCEPT_PHASE = "ALL,ENGINES"
+$ OPT_DEBUG = P2
+$ OPT_COMPILER = P3
+$ OPT_TCPIP_LIB = P4
+$ OPT_SPECIAL_THREADS = P5
+$ OPT_POINTER_SIZE = P7
+$ ZLIB = P8
+$
+$ GOSUB CHECK_OPTIONS
+$!
+$! Set the goal directories, and create them if necessary
+$!
+$ OBJ_DIR := SYS$DISK:[-.'ARCHD'.OBJ.ENGINES]
+$ EXE_DIR := SYS$DISK:[-.'ARCHD'.EXE.ENGINES]
+$ IF F$PARSE(OBJ_DIR) .EQS. "" THEN CREATE/DIRECTORY 'OBJ_DIR'
+$ IF F$PARSE(EXE_DIR) .EQS. "" THEN CREATE/DIRECTORY 'EXE_DIR'
+$!
+$! Set the goal files, and create them if necessary
+$!
+$ CRYPTO_LIB := SYS$DISK:[-.'ARCHD'.EXE.CRYPTO]SSL_LIBCRYPTO'LIB32'.OLB
+$ IF F$SEARCH(CRYPTO_LIB) .EQS. "" THEN LIBRARY/CREATE/OBJECT 'CRYPTO_LIB'
+$!
+$! Specify the destination directory in any /MAP option.
+$!
+$ if (LINKMAP .eqs. "MAP")
+$ then
+$   LINKMAP = LINKMAP+ "=''EXE_DIR'"
+$ endif
+$!
+$! Add the location prefix to the linker options file name.
+$!
+$ if (OPT_FILE .nes. "")
+$ then
+$   OPT_FILE = EXE_DIR+ OPT_FILE
+$ endif
+$!
+$! Initialise.
+$!
+$ GOSUB INITIALISE
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Define what goes into each engine.  VAX includes a transfer vector.
+$!
+$ ENGINE_ = ""
+$ TV_OBJ = ""
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$   ENGINE_ = "engine_vector.mar"
+$   TV_OBJ_NAME = OBJ_DIR + F$PARSE(ENGINE_,,,"NAME","SYNTAX_ONLY") + ".OBJ"
+$   TV_OBJ = ",''TV_OBJ_NAME'"
+$ ENDIF
+$ ENGINE_4758CCA = "e_4758cca"
+$ ENGINE_aep = "e_aep"
+$ ENGINE_atalla = "e_atalla"
+$ ENGINE_cswift = "e_cswift"
+$ ENGINE_chil = "e_chil"
+$ ENGINE_nuron = "e_nuron"
+$ ENGINE_sureware = "e_sureware"
+$ ENGINE_ubsec = "e_ubsec"
+$ ENGINE_padlock = "e_padlock"
+$
+$ ENGINE_ccgost_SUBDIR = "ccgost"
+$ ENGINE_ccgost = "e_gost_err,gost2001_keyx,gost2001,gost89,gost94_keyx,"+ -
+		  "gost_ameth,gost_asn1,gost_crypt,gost_ctl,gost_eng,"+ -
+		  "gosthash,gost_keywrap,gost_md,gost_params,gost_pmeth,"+ -
+		  "gost_sign"
+$!
+$! Define which programs need to be linked with a TCP/IP library
+$!
+$ TCPIP_ENGINES = ",,"
+$ IF COMPILER .EQS. "VAXC" THEN -
+     TCPIP_ENGINES = ",,"
+$!
+$! Set up two loops, one that keeps track of the engines,
+$! and one that keeps track of all the files going into
+$! the current engine.
+$!
+$! Here's the start of the engine loop.
+$!
+$ ENGINE_COUNTER = 0
+$ ENGINE_NEXT:
+$!
+$! Extract the current engine name, and if we've reached the end, stop
+$!
+$ ENGINE_NAME = F$ELEMENT(ENGINE_COUNTER,",",ENGINES)
+$ IF (ENGINE_NAME.EQS.",") THEN GOTO ENGINE_DONE
+$!
+$ ENGINE_COUNTER = ENGINE_COUNTER + 1
+$!
+$! Set up the engine library names.
+$!
+$ LIB_ENGINE = "ENGINE_" + ENGINE_NAME
+$!
+$! Check if the library module name actually is defined
+$!
+$ IF F$TYPE('LIB_ENGINE') .EQS. ""
+$ THEN
+$   WRITE SYS$ERROR ""
+$   WRITE SYS$ERROR "The module ",ENGINE_NAME," does not exist.  Continuing..."
+$   WRITE SYS$ERROR ""
+$   GOTO ENGINE_NEXT
+$ ENDIF
+$!
+$! Talk to the user
+$!
+$ IF ENGINE_NAME .NES. ""
+$ THEN
+$   WRITE SYS$OUTPUT "Compiling The ",ENGINE_NAME," Library Files. (",BUILDALL,")"
+$ ELSE
+$   WRITE SYS$OUTPUT "Compiling Support Files. (",BUILDALL,")"
+$ ENDIF
+$!
+$! Create a .OPT file for the object files (for a real engine name).
+$!
+$ IF ENGINE_NAME .NES. ""
+$ THEN
+$   OPEN /WRITE OBJECTS 'EXE_DIR''ENGINE_NAME'.OPT
+$ ENDIF
+$!
+$! Here's the start of per-engine module loop.
+$!
+$ FILE_COUNTER = 0
+$ FILE_NEXT:
+$!
+$! Extract the file name from the file list, and if we've reached the end, stop
+$!
+$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",'LIB_ENGINE')
+$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
+$!
+$ FILE_COUNTER = FILE_COUNTER + 1
+$!
+$ IF FILE_NAME .EQS. "" THEN GOTO FILE_NEXT
+$!
+$! Set up the source and object reference
+$!
+$ IF F$TYPE('LIB_ENGINE'_SUBDIR) .EQS. ""
+$ THEN
+$     SOURCE_FILE = F$PARSE(FILE_NAME,"SYS$DISK:[].C",,,"SYNTAX_ONLY")
+$ ELSE
+$     SOURCE_FILE = F$PARSE(FILE_NAME,"SYS$DISK:[."+'LIB_ENGINE'_SUBDIR+"].C",,,"SYNTAX_ONLY")
+$ ENDIF
+$ OBJECT_FILE = OBJ_DIR + F$PARSE(FILE_NAME,,,"NAME","SYNTAX_ONLY") + ".OBJ"
+$!
+$! If we get some problem, we just go on trying to build the next module.
+$ ON WARNING THEN GOTO FILE_NEXT
+$!
+$! Check if the module we want to compile is actually there.
+$!
+$ IF F$SEARCH(SOURCE_FILE) .EQS. ""
+$ THEN
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Doesn't Exist."
+$   WRITE SYS$OUTPUT ""
+$   GOTO EXIT
+$ ENDIF
+$!
+$! Talk to the user.
+$!
+$ WRITE SYS$OUTPUT "	",FILE_NAME,""
+$!
+$! Do the dirty work.
+$!
+$ ON ERROR THEN GOTO FILE_NEXT
+$ IF F$EDIT(F$PARSE(SOURCE_FILE,,,"TYPE","SYNTAX_ONLY"),"UPCASE") .EQS. ".MAR"
+$ THEN
+$   MACRO/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ELSE
+$   CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ENDIF
+$!
+$! Write the entry to the .OPT file (for a real engine name).
+$!
+$ IF ENGINE_NAME .NES. ""
+$ THEN
+$   WRITE OBJECTS OBJECT_FILE
+$ ENDIF
+$!
+$! Next file
+$!
+$ GOTO FILE_NEXT
+$!
+$ FILE_DONE:
+$!
+$! Do not link the support files.
+$!
+$ IF ENGINE_NAME .EQS. "" THEN GOTO ENGINE_NEXT
+$!
+$! Close the linker options file (for a real engine name).
+$!
+$ CLOSE OBJECTS
+$!
+$! Now, there are two ways to handle this.  We can either build 
+$! shareable images or stick the engine object file into libcrypto.
+$! For now, the latter is NOT supported.
+$!
+$!!!!! LIBRARY/REPLACE 'CRYPTO_LIB' 'OBJECT_FILE'
+$!
+$! For shareable libraries, we need to do things a little differently
+$! depending on if we link with a TCP/IP library or not.
+$!
+$ ENGINE_OPT := SYS$DISK:[]'ARCH'.OPT
+$ LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' /SHARE='EXE_DIR''ENGINE_NAME'.EXE -
+   'EXE_DIR''ENGINE_NAME'.OPT /OPTIONS -
+   'TV_OBJ', -
+   'CRYPTO_LIB' /LIBRARY, -
+   'ENGINE_OPT' /OPTIONS -
+   'TCPIP_LIB' -
+   'ZLIB_LIB' -
+   ,'OPT_FILE' /OPTIONS
+$!
+$! Next engine
+$!
+$ GOTO ENGINE_NEXT
+$!
+$ ENGINE_DONE:
+$!
+$! Talk to the user
+$!
+$ WRITE SYS$OUTPUT "All Done..."
+$ EXIT:
+$ GOSUB CLEANUP
+$ EXIT
+$!
+$! Check For The Link Option FIle.
+$!
+$ CHECK_OPT_FILE:
+$!
+$! Check To See If We Need To Make A VAX C Option File.
+$!
+$ IF (COMPILER.EQS."VAXC")
+$ THEN
+$!
+$!  Check To See If We Already Have A VAX C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    We Need A VAX C Linker Option File.
+$!
+$     CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against 
+! The Sharable VAX C Runtime Library.
+!
+SYS$SHARE:VAXCRTL.EXE/SHARE
+$EOD
+$!
+$!  End The Option File Check.
+$!
+$   ENDIF
+$!
+$! End The VAXC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A GNU C Option File.
+$!
+$ IF (COMPILER.EQS."GNUC")
+$ THEN
+$!
+$!  Check To See If We Already Have A GNU C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    We Need A GNU C Linker Option File.
+$!
+$     CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against 
+! The Sharable C Runtime Library.
+!
+GNU_CC:[000000]GCCLIB/LIBRARY
+SYS$SHARE:VAXCRTL/SHARE
+$EOD
+$!
+$!  End The Option File Check.
+$!
+$   ENDIF
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A DEC C Option File.
+$!
+$ IF (COMPILER.EQS."DECC")
+$ THEN
+$!
+$!  Check To See If We Already Have A DEC C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    Figure Out If We Need A non-VAX Or A VAX Linker Option File.
+$!
+$     IF ARCH .EQS. "VAX"
+$     THEN
+$!
+$!      We Need A DEC C Linker Option File For VAX.
+$!
+$       CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against 
+! The Sharable DEC C Runtime Library.
+!
+SYS$SHARE:DECC$SHR.EXE/SHARE
+$EOD
+$!
+$!    Else...
+$!
+$     ELSE
+$!
+$!      Create The non-VAX Linker Option File.
+$!
+$       CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File For non-VAX To Link Against 
+! The Sharable C Runtime Library.
+!
+SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
+SYS$SHARE:CMA$OPEN_RTL/SHARE
+$EOD
+$!
+$!    End The DEC C Option File Check.
+$!
+$     ENDIF
+$!
+$!  End The Option File Search.
+$!
+$   ENDIF
+$!
+$! End The DEC C Check.
+$!
+$ ENDIF
+$!
+$!  Tell The User What Linker Option File We Are Using.
+$!
+$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."	
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$!
+$! Check The User's Options.
+$!
+$ CHECK_OPTIONS:
+$!
+$! Check To See If OPT_PHASE Is Blank.
+$!
+$ IF (OPT_PHASE.EQS."ALL")
+$ THEN
+$!
+$!   OPT_PHASE Is Blank, So Build Everything.
+$!
+$    BUILDALL = "ALL"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  Else, Check To See If OPT_PHASE Has A Valid Argument.
+$!
+$   IF ("," + ACCEPT_PHASE + ",") - ("," + OPT_PHASE + ",") -
+       .NES. ("," + ACCEPT_PHASE + ",")
+$   THEN
+$!
+$!    A Valid Argument.
+$!
+$     BUILDALL = OPT_PHASE
+$!
+$!  Else...
+$!
+$   ELSE
+$!
+$!    Tell The User We Don't Know What They Want.
+$!
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The option ",OPT_PHASE," is invalid.  The valid options are:"
+$     WRITE SYS$OUTPUT ""
+$     IF ("," + ACCEPT_PHASE + ",") - ",ALL," -
+	.NES. ("," + ACCEPT_PHASE + ",") THEN -
+	WRITE SYS$OUTPUT "    ALL      :  just build everything."
+$     IF ("," + ACCEPT_PHASE + ",") - ",ENGINES," -
+	.NES. ("," + ACCEPT_PHASE + ",") THEN -
+	WRITE SYS$OUTPUT "    ENGINES  :  to compile just the [.xxx.EXE.ENGINES]*.EXE hareable images."
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT " where 'xxx' stands for:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "    ALPHA[64]:  Alpha architecture."
+$     WRITE SYS$OUTPUT "    IA64[64] :  IA64 architecture."
+$     WRITE SYS$OUTPUT "    VAX      :  VAX architecture."
+$     WRITE SYS$OUTPUT ""
+$!
+$!    Time To EXIT.
+$!
+$     EXIT
+$!
+$!  End The Valid Argument Check.
+$!
+$   ENDIF
+$!
+$! End The OPT_PHASE Check.
+$!
+$ ENDIF
+$!
+$! Check To See If OPT_DEBUG Is Blank.
+$!
+$ IF (OPT_DEBUG.EQS."NODEBUG")
+$ THEN
+$!
+$!  OPT_DEBUG Is NODEBUG, So Compile Without The Debugger Information.
+$!
+$   DEBUGGER = "NODEBUG"
+$   LINKMAP = "NOMAP"
+$   TRACEBACK = "NOTRACEBACK" 
+$   GCC_OPTIMIZE = "OPTIMIZE"
+$   CC_OPTIMIZE = "OPTIMIZE"
+$   MACRO_OPTIMIZE = "OPTIMIZE"
+$   WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
+$   WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
+$ ELSE
+$!
+$!  Check To See If We Are To Compile With Debugger Information.
+$!
+$   IF (OPT_DEBUG.EQS."DEBUG")
+$   THEN
+$!
+$!    Compile With Debugger Information.
+$!
+$     DEBUGGER = "DEBUG"
+$     LINKMAP = "MAP"
+$     TRACEBACK = "TRACEBACK"
+$     GCC_OPTIMIZE = "NOOPTIMIZE"
+$     CC_OPTIMIZE = "NOOPTIMIZE"
+$     MACRO_OPTIMIZE = "NOOPTIMIZE"
+$     WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
+$     WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
+$   ELSE 
+$!
+$!    They Entered An Invalid Option.
+$!
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ",OPT_DEBUG," Is Invalid.  The Valid Options Are:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "     DEBUG   :  Compile With The Debugger Information."
+$     WRITE SYS$OUTPUT "     NODEBUG :  Compile Without The Debugger Information."
+$     WRITE SYS$OUTPUT ""
+$!
+$!    Time To EXIT.
+$!
+$     EXIT
+$!
+$!  End The Valid Argument Check.
+$!
+$   ENDIF
+$!
+$! End The OPT_DEBUG Check.
+$!
+$ ENDIF
+$!
+$! Special Threads For OpenVMS v7.1 Or Later
+$!
+$! Written By:  Richard Levitte
+$!              richard@levitte.org
+$!
+$!
+$! Check To See If We Have A Option For OPT_SPECIAL_THREADS.
+$!
+$ IF (OPT_SPECIAL_THREADS.EQS."")
+$ THEN
+$!
+$!  Get The Version Of VMS We Are Using.
+$!
+$   ISSEVEN :=
+$   TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
+$   TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
+$!
+$!  Check To See If The VMS Version Is v7.1 Or Later.
+$!
+$   IF (TMP.GE.71)
+$   THEN
+$!
+$!    We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
+$!
+$     ISSEVEN := ,PTHREAD_USE_D4
+$!
+$!  End The VMS Version Check.
+$!
+$   ENDIF
+$!
+$! End The OPT_SPECIAL_THREADS Check.
+$!
+$ ENDIF
+$!
+$! Check OPT_POINTER_SIZE (P7).
+$!
+$ IF (OPT_POINTER_SIZE .NES. "") .AND. (ARCH .NES. "VAX")
+$ THEN
+$!
+$   IF (OPT_POINTER_SIZE .EQS. "32")
+$   THEN
+$     POINTER_SIZE = " /POINTER_SIZE=32"
+$   ELSE
+$     POINTER_SIZE = F$EDIT( OPT_POINTER_SIZE, "COLLAPSE, UPCASE")
+$     IF ((POINTER_SIZE .EQS. "64") .OR. -
+       (POINTER_SIZE .EQS. "64=") .OR. -
+       (POINTER_SIZE .EQS. "64=ARGV"))
+$     THEN
+$       ARCHD = ARCH+ "_64"
+$       LIB32 = ""
+$       POINTER_SIZE = " /POINTER_SIZE=64"
+$     ELSE
+$!
+$!      Tell The User Entered An Invalid Option.
+$!
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT "The Option ", OPT_POINTER_SIZE, -
+         " Is Invalid.  The Valid Options Are:"
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT -
+         "    """"       :  Compile with default (short) pointers."
+$       WRITE SYS$OUTPUT -
+         "    32       :  Compile with 32-bit (short) pointers."
+$       WRITE SYS$OUTPUT -
+         "    64       :  Compile with 64-bit (long) pointers (auto ARGV)."
+$       WRITE SYS$OUTPUT -
+         "    64=      :  Compile with 64-bit (long) pointers (no ARGV)."
+$       WRITE SYS$OUTPUT -
+         "    64=ARGV  :  Compile with 64-bit (long) pointers (ARGV)."
+$       WRITE SYS$OUTPUT ""
+$! 
+$!      Time To EXIT.
+$!
+$       EXIT
+$!
+$     ENDIF
+$!
+$   ENDIF
+$!
+$! End The OPT_POINTER_SIZE Check.
+$!
+$ ENDIF
+$!
+$! Set basic C compiler /INCLUDE directories.
+$!
+$ CC_INCLUDES = "SYS$DISK:[],SYS$DISK:[.VENDOR_DEFNS]"
+$!
+$! Check To See If OPT_COMPILER Is Blank.
+$!
+$ IF (OPT_COMPILER.EQS."")
+$ THEN
+$!
+$!  O.K., The User Didn't Specify A Compiler, Let's Try To
+$!  Find Out Which One To Use.
+$!
+$!  Check To See If We Have GNU C.
+$!
+$   IF (F$TRNLNM("GNU_CC").NES."")
+$   THEN
+$!
+$!    Looks Like GNUC, Set To Use GNUC.
+$!
+$     OPT_COMPILER = "GNUC"
+$!
+$!  Else...
+$!
+$   ELSE
+$!
+$!    Check To See If We Have VAXC Or DECC.
+$!
+$     IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
+$     THEN 
+$!
+$!      Looks Like DECC, Set To Use DECC.
+$!
+$       OPT_COMPILER = "DECC"
+$!
+$!    Else...
+$!
+$     ELSE
+$!
+$!      Looks Like VAXC, Set To Use VAXC.
+$!
+$       OPT_COMPILER = "VAXC"
+$!
+$!    End The VAXC Compiler Check.
+$!
+$     ENDIF
+$!
+$!  End The DECC & VAXC Compiler Check.
+$!
+$   ENDIF
+$!
+$!  End The Compiler Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have A Option For OPT_TCPIP_LIB.
+$!
+$ IF (OPT_TCPIP_LIB.EQS."")
+$ THEN
+$!
+$!  Find out what socket library we have available
+$!
+$   IF F$PARSE("SOCKETSHR:") .NES. ""
+$   THEN
+$!
+$!    We have SOCKETSHR, and it is my opinion that it's the best to use.
+$!
+$     OPT_TCPIP_LIB = "SOCKETSHR"
+$!
+$!    Tell the user
+$!
+$     WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
+$!
+$!    Else, let's look for something else
+$!
+$   ELSE
+$!
+$!    Like UCX (the reason to do this before Multinet is that the UCX
+$!    emulation is easier to use...)
+$!
+$     IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
+	 .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
+	 .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
+$     THEN
+$!
+$!	Last resort: a UCX or UCX-compatible library
+$!
+$	OPT_TCPIP_LIB = "UCX"
+$!
+$!      Tell the user
+$!
+$       WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
+$!
+$!	That was all...
+$!
+$     ENDIF
+$   ENDIF
+$ ENDIF
+$!
+$! Set Up Initial CC Definitions, Possibly With User Ones
+$!
+$ CCDEFS = "TCPIP_TYPE_''OPT_TCPIP_LIB',DSO_VMS"
+$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
+$ CCEXTRAFLAGS = ""
+$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
+$ CCDISABLEWARNINGS = "" !!! "LONGLONGTYPE,LONGLONGSUFX"
+$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
+	CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
+$!
+$! Check To See If We Have A ZLIB Option.
+$!
+$ IF (ZLIB .NES. "")
+$ THEN
+$!
+$!  Check for expected ZLIB files.
+$!
+$   err = 0
+$   file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY")
+$   if (f$search( file1) .eqs. "")
+$   then
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
+$     WRITE SYS$OUTPUT "    Can't find header: ''file1'"
+$     err = 1
+$   endif
+$   file1 = f$parse( "A.;", ZLIB)- "A.;"
+$!
+$   file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY")
+$   if (f$search( file2) .eqs. "")
+$   then
+$     if (err .eq. 0)
+$     then
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
+$     endif
+$     WRITE SYS$OUTPUT "    Can't find library: ''file2'"
+$     WRITE SYS$OUTPUT ""
+$     err = err+ 2
+$   endif
+$   if (err .eq. 1)
+$   then
+$     WRITE SYS$OUTPUT ""
+$   endif
+$!
+$   if (err .ne. 0)
+$   then
+$     EXIT
+$   endif
+$!
+$   CCDEFS = """ZLIB=1"", "+ CCDEFS
+$   CC_INCLUDES = CC_INCLUDES+ ", "+ file1
+$   ZLIB_LIB = ", ''file2' /library"
+$!
+$!  Print info
+$!
+$   WRITE SYS$OUTPUT "ZLIB library spec: ", file2
+$!
+$! End The ZLIB Check.
+$!
+$ ENDIF
+$!
+$!  Check To See If The User Entered A Valid Parameter.
+$!
+$ IF (OPT_COMPILER.EQS."VAXC").OR.(OPT_COMPILER.EQS."DECC").OR.(OPT_COMPILER.EQS."GNUC")
+$ THEN
+$!
+$!    Check To See If The User Wanted DECC.
+$!
+$   IF (OPT_COMPILER.EQS."DECC")
+$   THEN
+$!
+$!    Looks Like DECC, Set To Use DECC.
+$!
+$     COMPILER = "DECC"
+$!
+$!    Tell The User We Are Using DECC.
+$!
+$     WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$!    Use DECC...
+$!
+$     CC = "CC"
+$     IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
+	 THEN CC = "CC/DECC"
+$     CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ -
+       "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + -
+       " /INCLUDE=(''CC_INCLUDES') " + -
+       CCEXTRAFLAGS
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "VAX_DECC_OPTIONS.OPT"
+$!
+$!  End DECC Check.
+$!
+$   ENDIF
+$!
+$!  Check To See If We Are To Use VAXC.
+$!
+$   IF (OPT_COMPILER.EQS."VAXC")
+$   THEN
+$!
+$!    Looks Like VAXC, Set To Use VAXC.
+$!
+$     COMPILER = "VAXC"
+$!
+$!    Tell The User We Are Using VAX C.
+$!
+$     WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$!    Compile Using VAXC.
+$!
+$     CC = "CC"
+$     IF ARCH.NES."VAX"
+$     THEN
+$	WRITE SYS$OUTPUT "There is no VAX C on Alpha!"
+$	EXIT
+$     ENDIF
+$     IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
+$     CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+	   "/INCLUDE=(''CC_INCLUDES')" + -
+	   CCEXTRAFLAGS
+$     CCDEFS = """VAXC""," + CCDEFS
+$!
+$!    Define <sys> As SYS$COMMON:[SYSLIB]
+$!
+$     DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "VAX_VAXC_OPTIONS.OPT"
+$!
+$!  End VAXC Check
+$!
+$   ENDIF
+$!
+$!  Check To See If We Are To Use GNU C.
+$!
+$   IF (OPT_COMPILER.EQS."GNUC")
+$   THEN
+$!
+$!    Looks Like GNUC, Set To Use GNUC.
+$!
+$     COMPILER = "GNUC"
+$!
+$!    Tell The User We Are Using GNUC.
+$!
+$     WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$!    Use GNU C...
+$!
+$     CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+	   "/INCLUDE=(''CC_INCLUDES')" + -
+	   CCEXTRAFLAGS
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "VAX_GNUC_OPTIONS.OPT"
+$!
+$!  End The GNU C Check.
+$!
+$   ENDIF
+$!
+$!  Set up default defines
+$!
+$   CCDEFS = """FLAT_INC=1""," + CCDEFS
+$!
+$!  Finish up the definition of CC.
+$!
+$   IF COMPILER .EQS. "DECC"
+$   THEN
+$     IF CCDISABLEWARNINGS .NES. ""
+$     THEN
+$       CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
+$     ENDIF
+$   ELSE
+$     CCDISABLEWARNINGS = ""
+$   ENDIF
+$   CC = CC + " /DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
+$!
+$!  Show user the result
+$!
+$   WRITE/SYMBOL SYS$OUTPUT "Main C Compiling Command: ",CC
+$!
+$!  Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$!  Tell The User We Don't Know What They Want.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The Option ",OPT_COMPILER," Is Invalid.  The Valid Options Are:"
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "    VAXC  :  To Compile With VAX C."
+$   WRITE SYS$OUTPUT "    DECC  :  To Compile With DEC C."
+$   WRITE SYS$OUTPUT "    GNUC  :  To Compile With GNU C."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Time To EXIT.
+$!
+$   EXIT
+$!
+$! End The Valid Argument Check.
+$!
+$ ENDIF
+$!
+$! Build a MACRO command for the architecture at hand
+$!
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$   MACRO = "MACRO/''DEBUGGER'"
+$ ELSE
+$   MACRO = "MACRO/MIGRATION/''DEBUGGER'/''MACRO_OPTIMIZE'"
+$ ENDIF
+$!
+$!  Show user the result
+$!
+$ WRITE/SYMBOL SYS$OUTPUT "Main MACRO Compiling Command: ",MACRO
+$!
+$! Time to check the contents, and to make sure we get the correct library.
+$!
+$ IF OPT_TCPIP_LIB.EQS."SOCKETSHR" .OR. OPT_TCPIP_LIB.EQS."MULTINET" -
+     .OR. OPT_TCPIP_LIB.EQS."UCX" .OR. OPT_TCPIP_LIB.EQS."TCPIP" -
+     .OR. OPT_TCPIP_LIB.EQS."NONE"
+$ THEN
+$!
+$!  Check to see if SOCKETSHR was chosen
+$!
+$   IF OPT_TCPIP_LIB.EQS."SOCKETSHR"
+$   THEN
+$!
+$!    Set the library to use SOCKETSHR
+$!
+$     TCPIP_LIB = ",SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
+$!
+$!    Done with SOCKETSHR
+$!
+$   ENDIF
+$!
+$!  Check to see if MULTINET was chosen
+$!
+$   IF OPT_TCPIP_LIB.EQS."MULTINET"
+$   THEN
+$!
+$!    Set the library to use UCX emulation.
+$!
+$     OPT_TCPIP_LIB = "UCX"
+$!
+$!    Done with MULTINET
+$!
+$   ENDIF
+$!
+$!  Check to see if UCX was chosen
+$!
+$   IF OPT_TCPIP_LIB.EQS."UCX"
+$   THEN
+$!
+$!    Set the library to use UCX.
+$!
+$     TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
+$     IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
+$     THEN
+$       TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS"
+$     ELSE
+$       IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
+	  TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS"
+$     ENDIF
+$!
+$!    Done with UCX
+$!
+$   ENDIF
+$!
+$!  Check to see if TCPIP was chosen
+$!
+$   IF OPT_TCPIP_LIB.EQS."TCPIP"
+$   THEN
+$!
+$!    Set the library to use TCPIP (post UCX).
+$!
+$     TCPIP_LIB = ",SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
+$!
+$!    Done with TCPIP
+$!
+$   ENDIF
+$!
+$!  Check to see if NONE was chosen
+$!
+$   IF OPT_TCPIP_LIB.EQS."NONE"
+$   THEN
+$!
+$!    Do not use a TCPIP library.
+$!
+$     TCPIP_LIB = ""
+$!
+$!    Done with TCPIP
+$!
+$   ENDIF
+$!
+$!  Print info
+$!
+$   WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB- ","
+$!
+$!  Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$!  Tell The User We Don't Know What They Want.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The Option ",OPT_TCPIP_LIB," Is Invalid.  The Valid Options Are:"
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "    SOCKETSHR  :  To link with SOCKETSHR TCP/IP library."
+$   WRITE SYS$OUTPUT "    UCX        :  To link with UCX TCP/IP library."
+$   WRITE SYS$OUTPUT "    TCPIP      :  To link with TCPIP (post UCX) TCP/IP library."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Time To EXIT.
+$!
+$   EXIT
+$!
+$!  Done with TCP/IP libraries
+$!
+$ ENDIF
+$!
+$!  Time To RETURN...
+$!
+$ RETURN
+$!
+$ INITIALISE:
+$!
+$! Save old value of the logical name OPENSSL
+$!
+$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
+$!
+$! Save directory information
+$!
+$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
+$ __HERE = F$EDIT(__HERE,"UPCASE")
+$ __TOP = __HERE - "ENGINES]"
+$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
+$!
+$! Set up the logical name OPENSSL to point at the include directory
+$!
+$ DEFINE OPENSSL /NOLOG '__INCLUDE'
+$!
+$! Done
+$!
+$ RETURN
+$!
+$ CLEANUP:
+$!
+$! Restore the saved logical name OPENSSL, if it had a value.
+$!
+$ if (f$type( __SAVE_OPENSSL) .nes. "")
+$ then
+$   IF __SAVE_OPENSSL .EQS. ""
+$   THEN
+$     DEASSIGN OPENSSL
+$   ELSE
+$     DEFINE /NOLOG OPENSSL '__SAVE_OPENSSL'
+$   ENDIF
+$ endif
+$!
+$! Close any open files.
+$!
+$ if (f$trnlnm( "objects", "LNM$PROCESS", 0, "SUPERVISOR") .nes. "") then -
+   close objects
+$!
+$! Done
+$!
+$ RETURN
+$!
diff --git a/openssl/engines/vax.opt b/openssl/engines/vax.opt
new file mode 100644
index 0000000..72e6bd8
--- /dev/null
+++ b/openssl/engines/vax.opt
@@ -0,0 +1,9 @@
+!
+! Ensure transfer vector is at beginning of image
+!
+CLUSTER=FIRST
+COLLECT=FIRST,$$ENGINE
+!
+! make psects nonshareable so image can be installed.
+!
+PSECT_ATTR=$CHAR_STRING_CONSTANTS,NOWRT
diff --git a/openssl/engines/vendor_defns/aep.h b/openssl/engines/vendor_defns/aep.h
new file mode 100644
index 0000000..5e9754f
--- /dev/null
+++ b/openssl/engines/vendor_defns/aep.h
@@ -0,0 +1,178 @@
+/* This header declares the necessary definitions for using the exponentiation
+ * acceleration capabilities, and rnd number generation of the AEP card. 
+ *
+ */
+
+/*
+ *
+ * Some AEP defines
+ *
+ */
+
+/*Successful return value*/
+#define AEP_R_OK                                0x00000000
+
+/*Miscelleanous unsuccessful return value*/
+#define AEP_R_GENERAL_ERROR                     0x10000001
+
+/*Insufficient host memory*/
+#define AEP_R_HOST_MEMORY                       0x10000002
+
+#define AEP_R_FUNCTION_FAILED                   0x10000006
+
+/*Invalid arguments in function call*/
+#define AEP_R_ARGUMENTS_BAD                     0x10020000
+
+#define AEP_R_NO_TARGET_RESOURCES				0x10030000
+
+/*Error occuring on socket operation*/
+#define AEP_R_SOCKERROR							0x10000010
+
+/*Socket has been closed from the other end*/
+#define AEP_R_SOCKEOF							0x10000011
+
+/*Invalid handles*/
+#define AEP_R_CONNECTION_HANDLE_INVALID         0x100000B3
+
+#define AEP_R_TRANSACTION_HANDLE_INVALID		0x10040000
+
+/*Transaction has not yet returned from accelerator*/
+#define AEP_R_TRANSACTION_NOT_READY				0x00010000
+
+/*There is already a thread waiting on this transaction*/
+#define AEP_R_TRANSACTION_CLAIMED				0x10050000
+
+/*The transaction timed out*/
+#define AEP_R_TIMED_OUT							0x10060000
+
+#define AEP_R_FXN_NOT_IMPLEMENTED				0x10070000
+
+#define AEP_R_TARGET_ERROR						0x10080000
+
+/*Error in the AEP daemon process*/
+#define AEP_R_DAEMON_ERROR						0x10090000
+
+/*Invalid ctx id*/
+#define AEP_R_INVALID_CTX_ID					0x10009000
+
+#define AEP_R_NO_KEY_MANAGER					0x1000a000
+
+/*Error obtaining a mutex*/
+#define AEP_R_MUTEX_BAD                         0x000001A0
+
+/*Fxn call before AEP_Initialise ot after AEP_Finialise*/
+#define AEP_R_AEPAPI_NOT_INITIALIZED			0x10000190
+
+/*AEP_Initialise has already been called*/
+#define AEP_R_AEPAPI_ALREADY_INITIALIZED		0x10000191
+
+/*Maximum number of connections to daemon reached*/
+#define AEP_R_NO_MORE_CONNECTION_HNDLS			0x10000200
+
+/*
+ *
+ * Some AEP Type definitions
+ *
+ */
+
+/* an unsigned 8-bit value */
+typedef unsigned char				AEP_U8;
+
+/* an unsigned 8-bit character */
+typedef char					AEP_CHAR;
+
+/* a BYTE-sized Boolean flag */
+typedef AEP_U8					AEP_BBOOL;
+
+/*Unsigned value, at least 16 bits long*/
+typedef unsigned short				AEP_U16;
+
+/* an unsigned value, at least 32 bits long */
+#ifdef SIXTY_FOUR_BIT_LONG
+typedef unsigned int				AEP_U32;
+#else
+typedef unsigned long				AEP_U32;
+#endif
+
+#ifdef SIXTY_FOUR_BIT_LONG
+typedef unsigned long				AEP_U64;
+#else
+typedef struct { unsigned long l1, l2; }	AEP_U64;
+#endif
+
+/* at least 32 bits; each bit is a Boolean flag */
+typedef AEP_U32			AEP_FLAGS;
+
+typedef AEP_U8	    	*AEP_U8_PTR;
+typedef AEP_CHAR    	*AEP_CHAR_PTR;
+typedef AEP_U32			*AEP_U32_PTR;
+typedef AEP_U64			*AEP_U64_PTR;
+typedef void        	*AEP_VOID_PTR;
+
+/* Pointer to a AEP_VOID_PTR-- i.e., pointer to pointer to void */
+typedef AEP_VOID_PTR 	*AEP_VOID_PTR_PTR;
+
+/*Used to identify an AEP connection handle*/
+typedef AEP_U32					AEP_CONNECTION_HNDL;
+
+/*Pointer to an AEP connection handle*/
+typedef AEP_CONNECTION_HNDL 	*AEP_CONNECTION_HNDL_PTR;
+
+/*Used by an application (in conjunction with the apps process id) to 
+identify an individual transaction*/
+typedef AEP_U32					AEP_TRANSACTION_ID;
+
+/*Pointer to an applications transaction identifier*/
+typedef AEP_TRANSACTION_ID 		*AEP_TRANSACTION_ID_PTR;
+
+/*Return value type*/
+typedef AEP_U32					AEP_RV;
+
+#define MAX_PROCESS_CONNECTIONS 256
+
+#define RAND_BLK_SIZE 1024
+
+typedef enum{
+        NotConnected=   0,
+        Connected=              1,
+        InUse=                  2
+} AEP_CONNECTION_STATE;
+
+
+typedef struct AEP_CONNECTION_ENTRY{
+        AEP_CONNECTION_STATE    conn_state;
+        AEP_CONNECTION_HNDL     conn_hndl;
+} AEP_CONNECTION_ENTRY;
+
+
+typedef AEP_RV t_AEP_OpenConnection(AEP_CONNECTION_HNDL_PTR phConnection);
+typedef AEP_RV t_AEP_CloseConnection(AEP_CONNECTION_HNDL hConnection);
+
+typedef AEP_RV t_AEP_ModExp(AEP_CONNECTION_HNDL hConnection,
+			    AEP_VOID_PTR pA, AEP_VOID_PTR pP,
+			    AEP_VOID_PTR pN,
+			    AEP_VOID_PTR pResult,
+			    AEP_TRANSACTION_ID* pidTransID);
+
+typedef AEP_RV t_AEP_ModExpCrt(AEP_CONNECTION_HNDL hConnection,
+			       AEP_VOID_PTR pA, AEP_VOID_PTR pP,
+			       AEP_VOID_PTR pQ,
+			       AEP_VOID_PTR pDmp1, AEP_VOID_PTR pDmq1,
+			       AEP_VOID_PTR pIqmp,
+			       AEP_VOID_PTR pResult,
+			       AEP_TRANSACTION_ID* pidTransID);
+
+#ifdef AEPRAND
+typedef AEP_RV t_AEP_GenRandom(AEP_CONNECTION_HNDL hConnection,
+			       AEP_U32 Len,
+			       AEP_U32 Type,
+			       AEP_VOID_PTR pResult,
+			       AEP_TRANSACTION_ID* pidTransID);
+#endif
+
+typedef AEP_RV t_AEP_Initialize(AEP_VOID_PTR pInitArgs);
+typedef AEP_RV t_AEP_Finalize(void);
+typedef AEP_RV t_AEP_SetBNCallBacks(AEP_RV (*GetBigNumSizeFunc)(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize),
+				    AEP_RV (*MakeAEPBigNumFunc)(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize, unsigned char* AEP_BigNum),
+				    AEP_RV (*ConverAEPBigNumFunc)(void* ArbBigNum, AEP_U32 BigNumSize, unsigned char* AEP_BigNum));
+
diff --git a/openssl/engines/vendor_defns/atalla.h b/openssl/engines/vendor_defns/atalla.h
new file mode 100644
index 0000000..149970d
--- /dev/null
+++ b/openssl/engines/vendor_defns/atalla.h
@@ -0,0 +1,48 @@
+/* This header declares the necessary definitions for using the exponentiation
+ * acceleration capabilities of Atalla cards. The only cryptographic operation
+ * is performed by "ASI_RSAPrivateKeyOpFn" and this takes a structure that
+ * defines an "RSA private key". However, it is really only performing a
+ * regular mod_exp using the supplied modulus and exponent - no CRT form is
+ * being used. Hence, it is a generic mod_exp function in disguise, and we use
+ * it as such.
+ *
+ * Thanks to the people at Atalla for letting me know these definitions are
+ * fine and that they can be reproduced here.
+ *
+ * Geoff.
+ */
+
+typedef struct ItemStr
+	{
+	unsigned char *data;
+	int len;
+	} Item;
+
+typedef struct RSAPrivateKeyStr
+	{
+	void *reserved;
+	Item version;
+	Item modulus;
+	Item publicExponent;
+	Item privateExponent;
+	Item prime[2];
+	Item exponent[2];
+	Item coefficient;
+	} RSAPrivateKey;
+
+/* Predeclare the function pointer types that we dynamically load from the DSO.
+ * These use the same names and form that Ben's original support code had (in
+ * crypto/bn/bn_exp.c) unless of course I've inadvertently changed the style
+ * somewhere along the way!
+ */
+
+typedef int tfnASI_GetPerformanceStatistics(int reset_flag,
+					unsigned int *ret_buf);
+
+typedef int tfnASI_GetHardwareConfig(long card_num, unsigned int *ret_buf);
+
+typedef int tfnASI_RSAPrivateKeyOpFn(RSAPrivateKey * rsaKey,
+					unsigned char *output,
+					unsigned char *input,
+					unsigned int modulus_len);
+
diff --git a/openssl/engines/vendor_defns/cswift.h b/openssl/engines/vendor_defns/cswift.h
new file mode 100644
index 0000000..6007932
--- /dev/null
+++ b/openssl/engines/vendor_defns/cswift.h
@@ -0,0 +1,234 @@
+/* Attribution notice: Rainbow have generously allowed me to reproduce
+ * the necessary definitions here from their API. This means the support
+ * can build independently of whether application builders have the
+ * API or hardware. This will allow developers to easily produce software
+ * that has latent hardware support for any users that have accelertors
+ * installed, without the developers themselves needing anything extra.
+ *
+ * I have only clipped the parts from the CryptoSwift header files that
+ * are (or seem) relevant to the CryptoSwift support code. This is
+ * simply to keep the file sizes reasonable.
+ * [Geoff]
+ */
+
+
+/* NB: These type widths do *not* seem right in general, in particular
+ * they're not terribly friendly to 64-bit architectures (unsigned long)
+ * will be 64-bit on IA-64 for a start. I'm leaving these alone as they
+ * agree with Rainbow's API and this will only be called into question
+ * on platforms with Rainbow support anyway! ;-) */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef long              SW_STATUS;              /* status           */
+typedef unsigned char     SW_BYTE;                /* 8 bit byte       */
+typedef unsigned short    SW_U16;                 /* 16 bit number    */
+#if defined(_IRIX)
+#include <sgidefs.h>
+typedef __uint32_t        SW_U32;
+#else
+typedef unsigned long     SW_U32;                 /* 32 bit integer   */
+#endif
+ 
+#if defined(OPENSSL_SYS_WIN32)
+  typedef struct _SW_U64 {
+      SW_U32 low32;
+      SW_U32 high32;
+  } SW_U64;                                         /* 64 bit integer   */
+#elif defined(OPENSSL_SYS_MACINTOSH_CLASSIC)
+  typedef longlong SW_U64
+#else /* Unix variants */
+  typedef struct _SW_U64 {
+      SW_U32 low32;
+      SW_U32 high32;
+  } SW_U64;                                         /* 64 bit integer   */
+#endif
+
+/* status codes */
+#define SW_OK                 (0L)
+#define SW_ERR_BASE           (-10000L)
+#define SW_ERR_NO_CARD        (SW_ERR_BASE-1) /* The Card is not present   */
+#define SW_ERR_CARD_NOT_READY (SW_ERR_BASE-2) /* The card has not powered  */
+                                              /*    up yet                 */
+#define SW_ERR_TIME_OUT       (SW_ERR_BASE-3) /* Execution of a command    */
+                                              /*    time out               */
+#define SW_ERR_NO_EXECUTE     (SW_ERR_BASE-4) /* The Card failed to        */
+                                              /*    execute the command    */
+#define SW_ERR_INPUT_NULL_PTR (SW_ERR_BASE-5) /* a required pointer is     */
+                                              /*    NULL                   */
+#define SW_ERR_INPUT_SIZE     (SW_ERR_BASE-6) /* size is invalid, too      */
+                                              /*    small, too large.      */
+#define SW_ERR_INVALID_HANDLE (SW_ERR_BASE-7) /* Invalid SW_ACC_CONTEXT    */
+                                              /*    handle                 */
+#define SW_ERR_PENDING        (SW_ERR_BASE-8) /* A request is already out- */
+                                              /*    standing at this       */
+                                              /*    context handle         */
+#define SW_ERR_AVAILABLE      (SW_ERR_BASE-9) /* A result is available.    */
+#define SW_ERR_NO_PENDING     (SW_ERR_BASE-10)/* No request is pending.    */
+#define SW_ERR_NO_MEMORY      (SW_ERR_BASE-11)/* Not enough memory         */
+#define SW_ERR_BAD_ALGORITHM  (SW_ERR_BASE-12)/* Invalid algorithm type    */
+                                              /*    in SW_PARAM structure  */
+#define SW_ERR_MISSING_KEY    (SW_ERR_BASE-13)/* No key is associated with */
+                                              /*    context.               */
+                                              /*    swAttachKeyParam() is  */
+                                              /*    not called.            */
+#define SW_ERR_KEY_CMD_MISMATCH \
+                              (SW_ERR_BASE-14)/* Cannot perform requested  */
+                                              /*    SW_COMMAND_CODE since  */
+                                              /*    key attached via       */
+                                              /*    swAttachKeyParam()     */
+                                              /*    cannot be used for this*/
+                                              /*    SW_COMMAND_CODE.       */
+#define SW_ERR_NOT_IMPLEMENTED \
+                              (SW_ERR_BASE-15)/* Not implemented           */
+#define SW_ERR_BAD_COMMAND    (SW_ERR_BASE-16)/* Bad command code          */
+#define SW_ERR_BAD_ITEM_SIZE  (SW_ERR_BASE-17)/* too small or too large in */
+                                              /*    the "initems" or       */
+                                              /*    "outitems".            */
+#define SW_ERR_BAD_ACCNUM     (SW_ERR_BASE-18)/* Bad accelerator number    */
+#define SW_ERR_SELFTEST_FAIL  (SW_ERR_BASE-19)/* At least one of the self  */
+                                              /*    test fail, look at the */
+                                              /*    selfTestBitmap in      */
+                                              /*    SW_ACCELERATOR_INFO for*/
+                                              /*    details.               */
+#define SW_ERR_MISALIGN       (SW_ERR_BASE-20)/* Certain alogrithms require*/
+                                              /*    key materials aligned  */
+                                              /*    in certain order, e.g. */
+                                              /*    128 bit for CRT        */
+#define SW_ERR_OUTPUT_NULL_PTR \
+                              (SW_ERR_BASE-21)/* a required pointer is     */
+                                              /*    NULL                   */
+#define SW_ERR_OUTPUT_SIZE \
+                              (SW_ERR_BASE-22)/* size is invalid, too      */
+                                              /*    small, too large.      */
+#define SW_ERR_FIRMWARE_CHECKSUM \
+                              (SW_ERR_BASE-23)/* firmware checksum mismatch*/
+                                              /*    download failed.       */
+#define SW_ERR_UNKNOWN_FIRMWARE \
+                              (SW_ERR_BASE-24)/* unknown firmware error    */
+#define SW_ERR_INTERRUPT      (SW_ERR_BASE-25)/* request is abort when     */
+                                              /*    it's waiting to be     */
+                                              /*    completed.             */
+#define SW_ERR_NVWRITE_FAIL   (SW_ERR_BASE-26)/* error in writing to Non-  */
+                                              /*    volatile memory        */
+#define SW_ERR_NVWRITE_RANGE  (SW_ERR_BASE-27)/* out of range error in     */
+                                              /*    writing to NV memory   */
+#define SW_ERR_RNG_ERROR      (SW_ERR_BASE-28)/* Random Number Generation  */
+                                              /*    failure                */
+#define SW_ERR_DSS_FAILURE    (SW_ERR_BASE-29)/* DSS Sign or Verify failure*/
+#define SW_ERR_MODEXP_FAILURE (SW_ERR_BASE-30)/* Failure in various math   */
+                                              /*    calculations           */
+#define SW_ERR_ONBOARD_MEMORY (SW_ERR_BASE-31)/* Error in accessing on -   */
+                                              /*    board memory           */
+#define SW_ERR_FIRMWARE_VERSION \
+                              (SW_ERR_BASE-32)/* Wrong version in firmware */
+                                              /*    update                 */
+#define SW_ERR_ZERO_WORKING_ACCELERATOR \
+                              (SW_ERR_BASE-44)/* All accelerators are bad  */
+
+
+  /* algorithm type */
+#define SW_ALG_CRT          1
+#define SW_ALG_EXP          2
+#define SW_ALG_DSA          3
+#define SW_ALG_NVDATA       4
+
+  /* command code */
+#define SW_CMD_MODEXP_CRT   1 /* perform Modular Exponentiation using  */
+                              /*  Chinese Remainder Theorem (CRT)      */
+#define SW_CMD_MODEXP       2 /* perform Modular Exponentiation        */
+#define SW_CMD_DSS_SIGN     3 /* perform DSS sign                      */
+#define SW_CMD_DSS_VERIFY   4 /* perform DSS verify                    */
+#define SW_CMD_RAND         5 /* perform random number generation      */
+#define SW_CMD_NVREAD       6 /* perform read to nonvolatile RAM       */
+#define SW_CMD_NVWRITE      7 /* perform write to nonvolatile RAM      */
+
+typedef SW_U32            SW_ALGTYPE;             /* alogrithm type   */
+typedef SW_U32            SW_STATE;               /* state            */
+typedef SW_U32            SW_COMMAND_CODE;        /* command code     */
+typedef SW_U32            SW_COMMAND_BITMAP[4];   /* bitmap           */
+
+typedef struct _SW_LARGENUMBER {
+    SW_U32    nbytes;       /* number of bytes in the buffer "value"  */
+    SW_BYTE*  value;        /* the large integer as a string of       */
+                            /*   bytes in network (big endian) order  */
+} SW_LARGENUMBER;               
+
+#if defined(OPENSSL_SYS_WIN32)
+    #include <windows.h>
+    typedef HANDLE          SW_OSHANDLE;          /* handle to kernel object */
+    #define SW_OS_INVALID_HANDLE  INVALID_HANDLE_VALUE
+    #define SW_CALLCONV _stdcall
+#elif defined(OPENSSL_SYS_MACINTOSH_CLASSIC)
+    /* async callback mechanisms */
+    /* swiftCallbackLevel */
+    #define SW_MAC_CALLBACK_LEVEL_NO         0		
+    #define SW_MAC_CALLBACK_LEVEL_HARDWARE   1	/* from the hardware ISR */
+    #define SW_MAC_CALLBACK_LEVEL_SECONDARY  2	/* as secondary ISR */
+    typedef int             SW_MAC_CALLBACK_LEVEL;
+    typedef int             SW_OSHANDLE;
+    #define SW_OS_INVALID_HANDLE  (-1)
+    #define SW_CALLCONV
+#else /* Unix variants */
+    typedef int             SW_OSHANDLE;          /* handle to driver */
+    #define SW_OS_INVALID_HANDLE  (-1)
+    #define SW_CALLCONV
+#endif 
+
+typedef struct _SW_CRT {
+    SW_LARGENUMBER  p;      /* prime number p                         */
+    SW_LARGENUMBER  q;      /* prime number q                         */
+    SW_LARGENUMBER  dmp1;   /* exponent1                              */
+    SW_LARGENUMBER  dmq1;   /* exponent2                              */
+    SW_LARGENUMBER  iqmp;   /* CRT coefficient                        */
+} SW_CRT;
+
+typedef struct _SW_EXP {
+    SW_LARGENUMBER  modulus; /* modulus                                */
+    SW_LARGENUMBER  exponent;/* exponent                               */
+} SW_EXP;
+
+typedef struct _SW_DSA {
+    SW_LARGENUMBER  p;      /*                                        */
+    SW_LARGENUMBER  q;      /*                                        */
+    SW_LARGENUMBER  g;      /*                                        */
+    SW_LARGENUMBER  key;    /* private/public key                     */
+} SW_DSA;
+
+typedef struct _SW_NVDATA {
+    SW_U32 accnum;          /* accelerator board number               */
+    SW_U32 offset;          /* offset in byte                         */
+} SW_NVDATA;
+
+typedef struct _SW_PARAM {
+    SW_ALGTYPE    type;     /* type of the alogrithm                  */
+    union {
+        SW_CRT    crt;
+        SW_EXP    exp;
+        SW_DSA    dsa;
+        SW_NVDATA nvdata;
+    } up;
+} SW_PARAM;
+
+typedef SW_U32 SW_CONTEXT_HANDLE; /* opaque context handle */
+
+
+/* Now the OpenSSL bits, these function types are the for the function
+ * pointers that will bound into the Rainbow shared libraries. */
+typedef SW_STATUS SW_CALLCONV t_swAcquireAccContext(SW_CONTEXT_HANDLE *hac);
+typedef SW_STATUS SW_CALLCONV t_swAttachKeyParam(SW_CONTEXT_HANDLE hac,
+                                                SW_PARAM *key_params);
+typedef SW_STATUS SW_CALLCONV t_swSimpleRequest(SW_CONTEXT_HANDLE hac,
+                                                SW_COMMAND_CODE cmd,
+                				SW_LARGENUMBER pin[],
+                                		SW_U32 pin_count,
+                                                SW_LARGENUMBER pout[],
+                				SW_U32 pout_count);
+typedef SW_STATUS SW_CALLCONV t_swReleaseAccContext(SW_CONTEXT_HANDLE hac);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
diff --git a/openssl/engines/vendor_defns/hw_4758_cca.h b/openssl/engines/vendor_defns/hw_4758_cca.h
new file mode 100644
index 0000000..296636e
--- /dev/null
+++ b/openssl/engines/vendor_defns/hw_4758_cca.h
@@ -0,0 +1,149 @@
+/**********************************************************************/
+/*                                                                    */
+/*  Prototypes of the CCA verbs used by the 4758 CCA openssl driver   */
+/*                                                                    */
+/*  Maurice Gittens <maurice@gittens.nl>                              */
+/*                                                                    */
+/**********************************************************************/
+
+#ifndef __HW_4758_CCA__
+#define __HW_4758_CCA__
+
+/*
+ *  Only WIN32 support for now
+ */
+#if defined(WIN32)
+
+  #define CCA_LIB_NAME "CSUNSAPI"
+
+  #define CSNDPKX   "CSNDPKX_32"
+  #define CSNDKRR   "CSNDKRR_32"
+  #define CSNDPKE   "CSNDPKE_32"
+  #define CSNDPKD   "CSNDPKD_32"
+  #define CSNDDSV   "CSNDDSV_32"
+  #define CSNDDSG   "CSNDDSG_32"
+  #define CSNBRNG   "CSNBRNG_32"
+
+  #define SECURITYAPI __stdcall
+#else
+    /* Fixme!!         
+      Find out the values of these constants for other platforms.
+    */
+  #define CCA_LIB_NAME "CSUNSAPI"
+
+  #define CSNDPKX   "CSNDPKX"
+  #define CSNDKRR   "CSNDKRR"
+  #define CSNDPKE   "CSNDPKE"
+  #define CSNDPKD   "CSNDPKD"
+  #define CSNDDSV   "CSNDDSV"
+  #define CSNDDSG   "CSNDDSG"
+  #define CSNBRNG   "CSNBRNG"
+
+  #define SECURITYAPI
+#endif
+
+/*
+ * security API prototypes
+ */
+
+/* PKA Key Record Read */
+typedef void (SECURITYAPI *F_KEYRECORDREAD)
+             (long          * return_code,
+              long          * reason_code,
+              long          * exit_data_length,
+              unsigned char * exit_data,
+              long          * rule_array_count,
+              unsigned char * rule_array,
+              unsigned char * key_label,
+              long          * key_token_length,
+              unsigned char * key_token);
+
+/* Random Number Generate */
+typedef void (SECURITYAPI *F_RANDOMNUMBERGENERATE)
+             (long          * return_code,
+              long          * reason_code,
+              long          * exit_data_length,
+              unsigned char * exit_data,
+              unsigned char * form,
+              unsigned char * random_number);
+
+/* Digital Signature Generate */
+typedef void (SECURITYAPI *F_DIGITALSIGNATUREGENERATE)
+             (long          * return_code,
+              long          * reason_code,
+              long          * exit_data_length,
+              unsigned char * exit_data,
+              long          * rule_array_count,
+              unsigned char * rule_array,
+              long          * PKA_private_key_id_length,
+              unsigned char * PKA_private_key_id,
+              long          * hash_length,
+              unsigned char * hash,
+              long          * signature_field_length,
+              long          * signature_bit_length,
+              unsigned char * signature_field);
+
+/* Digital Signature Verify */
+typedef void (SECURITYAPI *F_DIGITALSIGNATUREVERIFY)(
+              long          * return_code,
+              long          * reason_code,
+              long          * exit_data_length,
+              unsigned char * exit_data,
+              long          * rule_array_count,
+              unsigned char * rule_array,
+              long          * PKA_public_key_id_length,
+              unsigned char * PKA_public_key_id,
+              long          * hash_length,
+              unsigned char * hash,
+              long          * signature_field_length,
+              unsigned char * signature_field);
+
+/* PKA Public Key Extract */
+typedef void (SECURITYAPI *F_PUBLICKEYEXTRACT)(
+              long          * return_code,
+              long          * reason_code,
+              long          * exit_data_length,
+              unsigned char * exit_data,
+              long          * rule_array_count,
+              unsigned char * rule_array,
+              long          * source_key_identifier_length,
+              unsigned char * source_key_identifier,
+              long          * target_key_token_length,
+              unsigned char * target_key_token);
+
+/* PKA Encrypt */
+typedef void   (SECURITYAPI *F_PKAENCRYPT)
+               (long          *  return_code,
+                 long          *  reason_code,
+                 long          *  exit_data_length,
+                 unsigned char *  exit_data,
+                 long          *  rule_array_count,
+                 unsigned char *  rule_array,
+                 long          *  key_value_length,
+                 unsigned char *  key_value,
+                 long          *  data_struct_length,
+                 unsigned char *  data_struct,
+                 long          *  RSA_public_key_length,
+                 unsigned char *  RSA_public_key,
+                 long          *  RSA_encipher_length,
+                 unsigned char *  RSA_encipher );
+
+/* PKA Decrypt */
+typedef void    (SECURITYAPI *F_PKADECRYPT)
+                (long          *  return_code,
+                 long          *  reason_code,
+                 long          *  exit_data_length,
+                 unsigned char *  exit_data,
+                 long          *  rule_array_count,
+                 unsigned char *  rule_array,
+                 long          *  enciphered_key_length,
+                 unsigned char *  enciphered_key,
+                 long          *  data_struct_length,
+                 unsigned char *  data_struct,
+                 long          *  RSA_private_key_length,
+                 unsigned char *  RSA_private_key,
+                 long          *  key_value_length,
+                 unsigned char *  key_value    );
+
+
+#endif
diff --git a/openssl/engines/vendor_defns/hw_ubsec.h b/openssl/engines/vendor_defns/hw_ubsec.h
new file mode 100644
index 0000000..b6619d4
--- /dev/null
+++ b/openssl/engines/vendor_defns/hw_ubsec.h
@@ -0,0 +1,100 @@
+/******************************************************************************
+ *
+ *  Copyright 2000
+ *  Broadcom Corporation
+ *  16215 Alton Parkway
+ *  PO Box 57013
+ *  Irvine CA 92619-7013
+ *
+ *****************************************************************************/
+/* 
+ * Broadcom Corporation uBSec SDK 
+ */
+/*
+ * Character device header file.
+ */
+/*
+ * Revision History:
+ *
+ * October 2000 JTT Created.
+ */
+
+#define MAX_PUBLIC_KEY_BITS (1024)
+#define MAX_PUBLIC_KEY_BYTES (1024/8)
+#define SHA_BIT_SIZE  (160)
+#define MAX_CRYPTO_KEY_LENGTH 24
+#define MAX_MAC_KEY_LENGTH 64
+#define UBSEC_CRYPTO_DEVICE_NAME ((unsigned char *)"/dev/ubscrypt")
+#define UBSEC_KEY_DEVICE_NAME ((unsigned char *)"/dev/ubskey")
+
+/* Math command types. */
+#define UBSEC_MATH_MODADD 0x0001
+#define UBSEC_MATH_MODSUB 0x0002
+#define UBSEC_MATH_MODMUL 0x0004
+#define UBSEC_MATH_MODEXP 0x0008
+#define UBSEC_MATH_MODREM 0x0010
+#define UBSEC_MATH_MODINV 0x0020
+
+typedef long ubsec_MathCommand_t;
+typedef long ubsec_RNGCommand_t;
+
+typedef struct ubsec_crypto_context_s {
+	unsigned int	flags;
+	unsigned char	crypto[MAX_CRYPTO_KEY_LENGTH];
+	unsigned char 	auth[MAX_MAC_KEY_LENGTH];
+} ubsec_crypto_context_t, *ubsec_crypto_context_p;
+
+/* 
+ * Predeclare the function pointer types that we dynamically load from the DSO.
+ */
+
+typedef int t_UBSEC_ubsec_bytes_to_bits(unsigned char *n, int bytes);
+
+typedef int t_UBSEC_ubsec_bits_to_bytes(int bits);
+
+typedef int t_UBSEC_ubsec_open(unsigned char *device);
+
+typedef int t_UBSEC_ubsec_close(int fd);
+
+typedef int t_UBSEC_diffie_hellman_generate_ioctl (int fd,
+	unsigned char *x, int *x_len, unsigned char *y, int *y_len, 
+	unsigned char *g, int g_len, unsigned char *m, int m_len,
+	unsigned char *userX, int userX_len, int random_bits);
+
+typedef int t_UBSEC_diffie_hellman_agree_ioctl (int fd,
+	unsigned char *x, int x_len, unsigned char *y, int y_len, 
+	unsigned char *m, int m_len, unsigned char *k, int *k_len);
+
+typedef int t_UBSEC_rsa_mod_exp_ioctl (int fd,
+	unsigned char *x, int x_len, unsigned char *m, int m_len,
+	unsigned char *e, int e_len, unsigned char *y, int *y_len);
+
+typedef int t_UBSEC_rsa_mod_exp_crt_ioctl (int fd,
+	unsigned char *x, int x_len, unsigned char *qinv, int qinv_len,
+	unsigned char *edq, int edq_len, unsigned char *q, int q_len,
+	unsigned char *edp, int edp_len, unsigned char *p, int p_len,
+	unsigned char *y, int *y_len);
+
+typedef int t_UBSEC_dsa_sign_ioctl (int fd,
+	int hash, unsigned char *data, int data_len, 
+	unsigned char *rndom, int random_len, 
+	unsigned char *p, int p_len, unsigned char *q, int q_len,
+	unsigned char *g, int g_len, unsigned char *key, int key_len,
+	unsigned char *r, int *r_len, unsigned char *s, int *s_len);
+
+typedef int t_UBSEC_dsa_verify_ioctl (int fd,
+	int hash, unsigned char *data, int data_len,
+	unsigned char *p, int p_len, unsigned char *q, int q_len,
+	unsigned char *g, int g_len, unsigned char *key, int key_len,
+	unsigned char *r, int r_len, unsigned char *s, int s_len,
+	unsigned char *v, int *v_len);
+
+typedef int t_UBSEC_math_accelerate_ioctl(int fd, ubsec_MathCommand_t command,
+	unsigned char *ModN, int *ModN_len, unsigned char *ExpE, int *ExpE_len, 
+	unsigned char *ParamA, int *ParamA_len, unsigned char *ParamB, int *ParamB_len,
+	unsigned char *Result, int *Result_len);
+
+typedef int t_UBSEC_rng_ioctl(int fd, ubsec_RNGCommand_t command,
+	unsigned char *Result, int *Result_len);
+
+typedef int t_UBSEC_max_key_len_ioctl(int fd, int *max_key_len);
diff --git a/openssl/engines/vendor_defns/hwcryptohook.h b/openssl/engines/vendor_defns/hwcryptohook.h
new file mode 100644
index 0000000..482f1f2
--- /dev/null
+++ b/openssl/engines/vendor_defns/hwcryptohook.h
@@ -0,0 +1,486 @@
+/*
+ * ModExp / RSA (with/without KM) plugin API
+ *
+ * The application will load a dynamic library which
+ * exports entrypoint(s) defined in this file.
+ *
+ * This set of entrypoints provides only a multithreaded,
+ * synchronous-within-each-thread, facility.
+ *
+ *
+ * This file is Copyright 1998-2000 nCipher Corporation Limited.
+ *
+ * Redistribution and use in source and binary forms, with opr without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the copyright notice,
+ *    this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions, and the following
+ *    disclaimer, in the documentation and/or other materials provided
+ *    with the distribution
+ *
+ * IN NO EVENT SHALL NCIPHER CORPORATION LIMITED (`NCIPHER') AND/OR
+ * ANY OTHER AUTHORS OR DISTRIBUTORS OF THIS FILE BE LIABLE for any
+ * damages arising directly or indirectly from this file, its use or
+ * this licence.  Without prejudice to the generality of the
+ * foregoing: all liability shall be excluded for direct, indirect,
+ * special, incidental, consequential or other damages or any loss of
+ * profits, business, revenue goodwill or anticipated savings;
+ * liability shall be excluded even if nCipher or anyone else has been
+ * advised of the possibility of damage.  In any event, if the
+ * exclusion of liability is not effective, the liability of nCipher
+ * or any author or distributor shall be limited to the lesser of the
+ * price paid and 1,000 pounds sterling. This licence only fails to
+ * exclude or limit liability for death or personal injury arising out
+ * of negligence, and only to the extent that such an exclusion or
+ * limitation is not effective.
+ *
+ * NCIPHER AND THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ALL
+ * AND ANY WARRANTIES (WHETHER EXPRESS OR IMPLIED), including, but not
+ * limited to, any implied warranties of merchantability, fitness for
+ * a particular purpose, satisfactory quality, and/or non-infringement
+ * of any third party rights.
+ *
+ * US Government use: This software and documentation is Commercial
+ * Computer Software and Computer Software Documentation, as defined in
+ * sub-paragraphs (a)(1) and (a)(5) of DFAR 252.227-7014, "Rights in
+ * Noncommercial Computer Software and Noncommercial Computer Software
+ * Documentation."  Use, duplication or disclosure by the Government is
+ * subject to the terms and conditions specified here.
+ *
+ * By using or distributing this file you will be accepting these
+ * terms and conditions, including the limitation of liability and
+ * lack of warranty.  If you do not wish to accept these terms and
+ * conditions, DO NOT USE THE FILE.
+ *
+ *
+ * The actual dynamically loadable plugin, and the library files for
+ * static linking, which are also provided in some distributions, are
+ * not covered by the licence described above.  You should have
+ * received a separate licence with terms and conditions for these
+ * library files; if you received the library files without a licence,
+ * please contact nCipher.
+ *
+ *
+ * $Id: hwcryptohook.h,v 1.1 2002/10/11 17:10:59 levitte Exp $
+ */
+
+#ifndef HWCRYPTOHOOK_H
+#define HWCRYPTOHOOK_H
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#ifndef HWCRYPTOHOOK_DECLARE_APPTYPES
+#define HWCRYPTOHOOK_DECLARE_APPTYPES 1
+#endif
+
+#define HWCRYPTOHOOK_ERROR_FAILED   -1
+#define HWCRYPTOHOOK_ERROR_FALLBACK -2
+#define HWCRYPTOHOOK_ERROR_MPISIZE  -3
+
+#if HWCRYPTOHOOK_DECLARE_APPTYPES
+
+/* These structs are defined by the application and opaque to the
+ * crypto plugin.  The application may define these as it sees fit.
+ * Default declarations are provided here, but the application may
+ *  #define HWCRYPTOHOOK_DECLARE_APPTYPES 0
+ * to prevent these declarations, and instead provide its own
+ * declarations of these types.  (Pointers to them must still be
+ * ordinary pointers to structs or unions, or the resulting combined
+ * program will have a type inconsistency.)
+ */
+typedef struct HWCryptoHook_MutexValue HWCryptoHook_Mutex;
+typedef struct HWCryptoHook_CondVarValue HWCryptoHook_CondVar;
+typedef struct HWCryptoHook_PassphraseContextValue HWCryptoHook_PassphraseContext;
+typedef struct HWCryptoHook_CallerContextValue HWCryptoHook_CallerContext;
+
+#endif /* HWCRYPTOHOOK_DECLARE_APPTYPES */
+
+/* These next two structs are opaque to the application.  The crypto
+ * plugin will return pointers to them; the caller simply manipulates
+ * the pointers.
+ */
+typedef struct HWCryptoHook_Context *HWCryptoHook_ContextHandle;
+typedef struct HWCryptoHook_RSAKey *HWCryptoHook_RSAKeyHandle;
+
+typedef struct {
+  char *buf;
+  size_t size;
+} HWCryptoHook_ErrMsgBuf;
+/* Used for error reporting.  When a HWCryptoHook function fails it
+ * will return a sentinel value (0 for pointer-valued functions, or a
+ * negative number, usually HWCRYPTOHOOK_ERROR_FAILED, for
+ * integer-valued ones).  It will, if an ErrMsgBuf is passed, also put
+ * an error message there.
+ * 
+ * size is the size of the buffer, and will not be modified.  If you
+ * pass 0 for size you must pass 0 for buf, and nothing will be
+ * recorded (just as if you passed 0 for the struct pointer).
+ * Messages written to the buffer will always be null-terminated, even
+ * when truncated to fit within size bytes.
+ *
+ * The contents of the buffer are not defined if there is no error.
+ */
+
+typedef struct HWCryptoHook_MPIStruct {
+  unsigned char *buf;
+  size_t size;
+} HWCryptoHook_MPI;
+/* When one of these is returned, a pointer is passed to the function.
+ * At call, size is the space available.  Afterwards it is updated to
+ * be set to the actual length (which may be more than the space available,
+ * if there was not enough room and the result was truncated).
+ * buf (the pointer) is not updated.
+ *
+ * size is in bytes and may be zero at call or return, but must be a
+ * multiple of the limb size.  Zero limbs at the MS end are not
+ * permitted.
+ */
+
+#define HWCryptoHook_InitFlags_FallbackModExp    0x0002UL
+#define HWCryptoHook_InitFlags_FallbackRSAImmed  0x0004UL
+/* Enable requesting fallback to software in case of problems with the
+ * hardware support.  This indicates to the crypto provider that the
+ * application is prepared to fall back to software operation if the
+ * ModExp* or RSAImmed* functions return HWCRYPTOHOOK_ERROR_FALLBACK.
+ * Without this flag those calls will never return
+ * HWCRYPTOHOOK_ERROR_FALLBACK.  The flag will also cause the crypto
+ * provider to avoid repeatedly attempting to contact dead hardware
+ * within a short interval, if appropriate.
+ */
+
+#define HWCryptoHook_InitFlags_SimpleForkCheck   0x0010UL
+/* Without _SimpleForkCheck the library is allowed to assume that the
+ * application will not fork and call the library in the child(ren).
+ *
+ * When it is specified, this is allowed.  However, after a fork
+ * neither parent nor child may unload any loaded keys or call
+ * _Finish.  Instead, they should call exit (or die with a signal)
+ * without calling _Finish.  After all the children have died the
+ * parent may unload keys or call _Finish.
+ *
+ * This flag only has any effect on UN*X platforms.
+ */
+
+typedef struct {
+  unsigned long flags;
+  void *logstream; /* usually a FILE*.  See below. */
+
+  size_t limbsize; /* bignum format - size of radix type, must be power of 2 */
+  int mslimbfirst; /* 0 or 1 */
+  int msbytefirst; /* 0 or 1; -1 = native */
+
+  /* All the callback functions should return 0 on success, or a
+   * nonzero integer (whose value will be visible in the error message
+   * put in the buffer passed to the call).
+   *
+   * If a callback is not available pass a null function pointer.
+   *
+   * The callbacks may not call down again into the crypto plugin.
+   */
+  
+  /* For thread-safety.  Set everything to 0 if you promise only to be
+   * singlethreaded.  maxsimultaneous is the number of calls to
+   * ModExp[Crt]/RSAImmed{Priv,Pub}/RSA.  If you don't know what to
+   * put there then say 0 and the hook library will use a default.
+   *
+   * maxmutexes is a small limit on the number of simultaneous mutexes
+   * which will be requested by the library.  If there is no small
+   * limit, set it to 0.  If the crypto plugin cannot create the
+   * advertised number of mutexes the calls to its functions may fail.
+   * If a low number of mutexes is advertised the plugin will try to
+   * do the best it can.  Making larger numbers of mutexes available
+   * may improve performance and parallelism by reducing contention
+   * over critical sections.  Unavailability of any mutexes, implying
+   * single-threaded operation, should be indicated by the setting
+   * mutex_init et al to 0.
+   */
+  int maxmutexes;
+  int maxsimultaneous;
+  size_t mutexsize;
+  int (*mutex_init)(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext *cactx);
+  int (*mutex_acquire)(HWCryptoHook_Mutex*);
+  void (*mutex_release)(HWCryptoHook_Mutex*);
+  void (*mutex_destroy)(HWCryptoHook_Mutex*);
+
+  /* For greater efficiency, can use condition vars internally for
+   * synchronisation.  In this case maxsimultaneous is ignored, but
+   * the other mutex stuff must be available.  In singlethreaded
+   * programs, set everything to 0.
+   */
+  size_t condvarsize;
+  int (*condvar_init)(HWCryptoHook_CondVar*, HWCryptoHook_CallerContext *cactx);
+  int (*condvar_wait)(HWCryptoHook_CondVar*, HWCryptoHook_Mutex*);
+  void (*condvar_signal)(HWCryptoHook_CondVar*);
+  void (*condvar_broadcast)(HWCryptoHook_CondVar*);
+  void (*condvar_destroy)(HWCryptoHook_CondVar*);
+  
+  /* The semantics of acquiring and releasing mutexes and broadcasting
+   * and waiting on condition variables are expected to be those from
+   * POSIX threads (pthreads).  The mutexes may be (in pthread-speak)
+   * fast mutexes, recursive mutexes, or nonrecursive ones.
+   * 
+   * The _release/_signal/_broadcast and _destroy functions must
+   * always succeed when given a valid argument; if they are given an
+   * invalid argument then the program (crypto plugin + application)
+   * has an internal error, and they should abort the program.
+   */
+
+  int (*getpassphrase)(const char *prompt_info,
+                       int *len_io, char *buf,
+                       HWCryptoHook_PassphraseContext *ppctx,
+                       HWCryptoHook_CallerContext *cactx);
+  /* Passphrases and the prompt_info, if they contain high-bit-set
+   * characters, are UTF-8.  The prompt_info may be a null pointer if
+   * no prompt information is available (it should not be an empty
+   * string).  It will not contain text like `enter passphrase';
+   * instead it might say something like `Operator Card for John
+   * Smith' or `SmartCard in nFast Module #1, Slot #1'.
+   *
+   * buf points to a buffer in which to return the passphrase; on
+   * entry *len_io is the length of the buffer.  It should be updated
+   * by the callback.  The returned passphrase should not be
+   * null-terminated by the callback.
+   */
+  
+  int (*getphystoken)(const char *prompt_info,
+                      const char *wrong_info,
+                      HWCryptoHook_PassphraseContext *ppctx,
+                      HWCryptoHook_CallerContext *cactx);
+  /* Requests that the human user physically insert a different
+   * smartcard, DataKey, etc.  The plugin should check whether the
+   * currently inserted token(s) are appropriate, and if they are it
+   * should not make this call.
+   *
+   * prompt_info is as before.  wrong_info is a description of the
+   * currently inserted token(s) so that the user is told what
+   * something is.  wrong_info, like prompt_info, may be null, but
+   * should not be an empty string.  Its contents should be
+   * syntactically similar to that of prompt_info. 
+   */
+  
+  /* Note that a single LoadKey operation might cause several calls to
+   * getpassphrase and/or requestphystoken.  If requestphystoken is
+   * not provided (ie, a null pointer is passed) then the plugin may
+   * not support loading keys for which authorisation by several cards
+   * is required.  If getpassphrase is not provided then cards with
+   * passphrases may not be supported.
+   *
+   * getpassphrase and getphystoken do not need to check that the
+   * passphrase has been entered correctly or the correct token
+   * inserted; the crypto plugin will do that.  If this is not the
+   * case then the crypto plugin is responsible for calling these
+   * routines again as appropriate until the correct token(s) and
+   * passphrase(s) are supplied as required, or until any retry limits
+   * implemented by the crypto plugin are reached.
+   *
+   * In either case, the application must allow the user to say `no'
+   * or `cancel' to indicate that they do not know the passphrase or
+   * have the appropriate token; this should cause the callback to
+   * return nonzero indicating error.
+   */
+
+  void (*logmessage)(void *logstream, const char *message);
+  /* A log message will be generated at least every time something goes
+   * wrong and an ErrMsgBuf is filled in (or would be if one was
+   * provided).  Other diagnostic information may be written there too,
+   * including more detailed reasons for errors which are reported in an
+   * ErrMsgBuf.
+   *
+   * When a log message is generated, this callback is called.  It
+   * should write a message to the relevant logging arrangements.
+   *
+   * The message string passed will be null-terminated and may be of arbitrary
+   * length.  It will not be prefixed by the time and date, nor by the
+   * name of the library that is generating it - if this is required,
+   * the logmessage callback must do it.  The message will not have a
+   * trailing newline (though it may contain internal newlines).
+   *
+   * If a null pointer is passed for logmessage a default function is
+   * used.  The default function treats logstream as a FILE* which has
+   * been converted to a void*.  If logstream is 0 it does nothing.
+   * Otherwise it prepends the date and time and library name and
+   * writes the message to logstream.  Each line will be prefixed by a
+   * descriptive string containing the date, time and identity of the
+   * crypto plugin.  Errors on the logstream are not reported
+   * anywhere, and the default function doesn't flush the stream, so
+   * the application must set the buffering how it wants it.
+   *
+   * The crypto plugin may also provide a facility to have copies of
+   * log messages sent elsewhere, and or for adjusting the verbosity
+   * of the log messages; any such facilities will be configured by
+   * external means.
+   */
+
+} HWCryptoHook_InitInfo;
+
+typedef
+HWCryptoHook_ContextHandle HWCryptoHook_Init_t(const HWCryptoHook_InitInfo *initinfo,
+                                               size_t initinfosize,
+                                               const HWCryptoHook_ErrMsgBuf *errors,
+                                               HWCryptoHook_CallerContext *cactx);
+extern HWCryptoHook_Init_t HWCryptoHook_Init;
+
+/* Caller should set initinfosize to the size of the HWCryptoHook struct,
+ * so it can be extended later.
+ *
+ * On success, a message for display or logging by the server,
+ * including the name and version number of the plugin, will be filled
+ * in into *errors; on failure *errors is used for error handling, as
+ * usual.
+ */
+
+/* All these functions return 0 on success, HWCRYPTOHOOK_ERROR_FAILED
+ * on most failures.  HWCRYPTOHOOK_ERROR_MPISIZE means at least one of
+ * the output MPI buffer(s) was too small; the sizes of all have been
+ * set to the desired size (and for those where the buffer was large
+ * enough, the value may have been copied in), and no error message
+ * has been recorded.
+ *
+ * You may pass 0 for the errors struct.  In any case, unless you set
+ * _NoStderr at init time then messages may be reported to stderr.
+ */
+
+/* The RSAImmed* functions (and key managed RSA) only work with
+ * modules which have an RSA patent licence - currently that means KM
+ * units; the ModExp* ones work with all modules, so you need a patent
+ * licence in the software in the US.  They are otherwise identical.
+ */
+
+typedef
+void HWCryptoHook_Finish_t(HWCryptoHook_ContextHandle hwctx);
+extern HWCryptoHook_Finish_t HWCryptoHook_Finish;
+/* You must not have any calls going or keys loaded when you call this. */
+
+typedef
+int HWCryptoHook_RandomBytes_t(HWCryptoHook_ContextHandle hwctx,
+                               unsigned char *buf, size_t len,
+                               const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RandomBytes_t HWCryptoHook_RandomBytes;
+
+typedef
+int HWCryptoHook_ModExp_t(HWCryptoHook_ContextHandle hwctx,
+                          HWCryptoHook_MPI a,
+                          HWCryptoHook_MPI p,
+                          HWCryptoHook_MPI n,
+                          HWCryptoHook_MPI *r,
+                          const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_ModExp_t HWCryptoHook_ModExp;
+
+typedef
+int HWCryptoHook_RSAImmedPub_t(HWCryptoHook_ContextHandle hwctx,
+                               HWCryptoHook_MPI m,
+                               HWCryptoHook_MPI e,
+                               HWCryptoHook_MPI n,
+                               HWCryptoHook_MPI *r,
+                               const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RSAImmedPub_t HWCryptoHook_RSAImmedPub;
+
+typedef
+int HWCryptoHook_ModExpCRT_t(HWCryptoHook_ContextHandle hwctx,
+                             HWCryptoHook_MPI a,
+                             HWCryptoHook_MPI p,
+                             HWCryptoHook_MPI q,
+                             HWCryptoHook_MPI dmp1,
+                             HWCryptoHook_MPI dmq1,
+                             HWCryptoHook_MPI iqmp,
+                             HWCryptoHook_MPI *r,
+                             const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_ModExpCRT_t HWCryptoHook_ModExpCRT;
+
+typedef
+int HWCryptoHook_RSAImmedPriv_t(HWCryptoHook_ContextHandle hwctx,
+                                HWCryptoHook_MPI m,
+                                HWCryptoHook_MPI p,
+                                HWCryptoHook_MPI q,
+                                HWCryptoHook_MPI dmp1,
+                                HWCryptoHook_MPI dmq1,
+                                HWCryptoHook_MPI iqmp,
+                                HWCryptoHook_MPI *r,
+                                const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RSAImmedPriv_t HWCryptoHook_RSAImmedPriv;
+
+/* The RSAImmed* and ModExp* functions may return E_FAILED or
+ * E_FALLBACK for failure.
+ *
+ * E_FAILED means the failure is permanent and definite and there
+ *    should be no attempt to fall back to software.  (Eg, for some
+ *    applications, which support only the acceleration-only
+ *    functions, the `key material' may actually be an encoded key
+ *    identifier, and doing the operation in software would give wrong
+ *    answers.)
+ *
+ * E_FALLBACK means that doing the computation in software would seem
+ *    reasonable.  If an application pays attention to this and is
+ *    able to fall back, it should also set the Fallback init flags.
+ */
+
+typedef
+int HWCryptoHook_RSALoadKey_t(HWCryptoHook_ContextHandle hwctx,
+                              const char *key_ident,
+                              HWCryptoHook_RSAKeyHandle *keyhandle_r,
+                              const HWCryptoHook_ErrMsgBuf *errors,
+                              HWCryptoHook_PassphraseContext *ppctx);
+extern HWCryptoHook_RSALoadKey_t HWCryptoHook_RSALoadKey;
+/* The key_ident is a null-terminated string configured by the
+ * user via the application's usual configuration mechanisms.
+ * It is provided to the user by the crypto provider's key management
+ * system.  The user must be able to enter at least any string of between
+ * 1 and 1023 characters inclusive, consisting of printable 7-bit
+ * ASCII characters.  The provider should avoid using
+ * any characters except alphanumerics and the punctuation
+ * characters  _ - + . / @ ~  (the user is expected to be able
+ * to enter these without quoting).  The string may be case-sensitive.
+ * The application may allow the user to enter other NULL-terminated strings,
+ * and the provider must cope (returning an error if the string is not
+ * valid).
+ *
+ * If the key does not exist, no error is recorded and 0 is returned;
+ * keyhandle_r will be set to 0 instead of to a key handle.
+ */
+
+typedef
+int HWCryptoHook_RSAGetPublicKey_t(HWCryptoHook_RSAKeyHandle k,
+                                   HWCryptoHook_MPI *n,
+                                   HWCryptoHook_MPI *e,
+                                   const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RSAGetPublicKey_t HWCryptoHook_RSAGetPublicKey;
+/* The crypto plugin will not store certificates.
+ *
+ * Although this function for acquiring the public key value is
+ * provided, it is not the purpose of this API to deal fully with the
+ * handling of the public key.
+ *
+ * It is expected that the crypto supplier's key generation program
+ * will provide general facilities for producing X.509
+ * self-certificates and certificate requests in PEM format.  These
+ * will be given to the user so that they can configure them in the
+ * application, send them to CAs, or whatever.
+ *
+ * In case this kind of certificate handling is not appropriate, the
+ * crypto supplier's key generation program should be able to be
+ * configured not to generate such a self-certificate or certificate
+ * request.  Then the application will need to do all of this, and
+ * will need to store and handle the public key and certificates
+ * itself.
+ */
+
+typedef
+int HWCryptoHook_RSAUnloadKey_t(HWCryptoHook_RSAKeyHandle k,
+                                const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RSAUnloadKey_t HWCryptoHook_RSAUnloadKey;
+/* Might fail due to locking problems, or other serious internal problems. */
+
+typedef
+int HWCryptoHook_RSA_t(HWCryptoHook_MPI m,
+                       HWCryptoHook_RSAKeyHandle k,
+                       HWCryptoHook_MPI *r,
+                       const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RSA_t HWCryptoHook_RSA;
+/* RSA private key operation (sign or decrypt) - raw, unpadded. */
+
+#endif /*HWCRYPTOHOOK_H*/
diff --git a/openssl/engines/vendor_defns/sureware.h b/openssl/engines/vendor_defns/sureware.h
new file mode 100644
index 0000000..e46b000
--- /dev/null
+++ b/openssl/engines/vendor_defns/sureware.h
@@ -0,0 +1,239 @@
+/*
+* Written by Corinne Dive-Reclus(cdive@baltimore.com)
+*
+* Copyright@2001 Baltimore Technologies Ltd.
+*																								*	
+*		THIS FILE IS PROVIDED BY BALTIMORE TECHNOLOGIES ``AS IS'' AND																			*
+*		ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE					* 
+*		IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE				*
+*		ARE DISCLAIMED.  IN NO EVENT SHALL BALTIMORE TECHNOLOGIES BE LIABLE						*
+*		FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL				*
+*		DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS					*
+*		OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)					*
+*		HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT				*
+*		LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY				*
+*		OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF					*
+*		SUCH DAMAGE.																			*
+*
+* 
+*/
+#ifdef WIN32
+#define SW_EXPORT	__declspec ( dllexport )
+#else
+#define SW_EXPORT
+#endif
+
+/*
+*	List of exposed SureWare errors
+*/
+#define SUREWAREHOOK_ERROR_FAILED		-1
+#define SUREWAREHOOK_ERROR_FALLBACK		-2
+#define SUREWAREHOOK_ERROR_UNIT_FAILURE -3
+#define SUREWAREHOOK_ERROR_DATA_SIZE -4
+#define SUREWAREHOOK_ERROR_INVALID_PAD -5
+/*
+* -----------------WARNING-----------------------------------
+* In all the following functions:
+* msg is a string with at least 24 bytes free.
+* A 24 bytes string will be concatenated to the existing content of msg. 
+*/
+/*
+*	SureWare Initialisation function
+*	in param threadsafe, if !=0, thread safe enabled
+*	return SureWareHOOK_ERROR_UNIT_FAILURE if failure, 1 if success
+*/
+typedef int SureWareHook_Init_t(char*const msg,int threadsafe);
+extern SW_EXPORT SureWareHook_Init_t SureWareHook_Init;
+/*
+*	SureWare Finish function
+*/
+typedef void SureWareHook_Finish_t(void);
+extern SW_EXPORT SureWareHook_Finish_t SureWareHook_Finish;
+/*
+*	 PRE_CONDITION:
+*		DO NOT CALL ANY OF THE FOLLOWING FUNCTIONS IN CASE OF INIT FAILURE
+*/
+/*
+*	SureWare RAND Bytes function
+*	In case of failure, the content of buf is unpredictable.
+*	return 1 if success
+*			SureWareHOOK_ERROR_FALLBACK if function not available in hardware
+*			SureWareHOOK_ERROR_FAILED if error while processing
+*			SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
+*			SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
+*
+*	in/out param buf : a num bytes long buffer where random bytes will be put
+*	in param num : the number of bytes into buf
+*/
+typedef int SureWareHook_Rand_Bytes_t(char*const msg,unsigned char *buf, int num);
+extern SW_EXPORT SureWareHook_Rand_Bytes_t SureWareHook_Rand_Bytes;
+
+/*
+*	SureWare RAND Seed function
+*	Adds some seed to the Hardware Random Number Generator
+*	return 1 if success
+*			SureWareHOOK_ERROR_FALLBACK if function not available in hardware
+*			SureWareHOOK_ERROR_FAILED if error while processing
+*			SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
+*			SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
+*
+*	in param buf : the seed to add into the HRNG
+*	in param num : the number of bytes into buf
+*/
+typedef int SureWareHook_Rand_Seed_t(char*const msg,const void *buf, int num);
+extern SW_EXPORT SureWareHook_Rand_Seed_t SureWareHook_Rand_Seed;
+
+/*
+*	SureWare Load Private Key function
+*	return 1 if success
+*			SureWareHOOK_ERROR_FAILED if error while processing
+*	No hardware is contact for this function.
+*
+*	in param key_id :the name of the private protected key file without the extension
+						".sws"
+*	out param hptr : a pointer to a buffer allocated by SureWare_Hook
+*	out param num: the effective key length in bytes
+*	out param keytype: 1 if RSA 2 if DSA
+*/
+typedef int SureWareHook_Load_Privkey_t(char*const msg,const char *key_id,char **hptr,unsigned long *num,char *keytype);
+extern SW_EXPORT SureWareHook_Load_Privkey_t SureWareHook_Load_Privkey;
+
+/*
+*	SureWare Info Public Key function
+*	return 1 if success
+*			SureWareHOOK_ERROR_FAILED if error while processing
+*	No hardware is contact for this function.
+*
+*	in param key_id :the name of the private protected key file without the extension
+						".swp"
+*	out param hptr : a pointer to a buffer allocated by SureWare_Hook
+*	out param num: the effective key length in bytes
+*	out param keytype: 1 if RSA 2 if DSA
+*/
+typedef int SureWareHook_Info_Pubkey_t(char*const msg,const char *key_id,unsigned long *num,
+										char *keytype);
+extern SW_EXPORT SureWareHook_Info_Pubkey_t SureWareHook_Info_Pubkey;
+
+/*
+*	SureWare Load Public Key function
+*	return 1 if success
+*			SureWareHOOK_ERROR_FAILED if error while processing
+*	No hardware is contact for this function.
+*
+*	in param key_id :the name of the public protected key file without the extension
+						".swp"
+*	in param num : the bytes size of n and e
+*	out param n: where to write modulus in bn format
+*	out param e: where to write exponent in bn format
+*/
+typedef int SureWareHook_Load_Rsa_Pubkey_t(char*const msg,const char *key_id,unsigned long num,
+										unsigned long *n, unsigned long *e);
+extern SW_EXPORT SureWareHook_Load_Rsa_Pubkey_t SureWareHook_Load_Rsa_Pubkey;
+
+/*
+*	SureWare Load DSA Public Key function
+*	return 1 if success
+*			SureWareHOOK_ERROR_FAILED if error while processing
+*	No hardware is contact for this function.
+*
+*	in param key_id :the name of the public protected key file without the extension
+						".swp"
+*	in param num : the bytes size of n and e
+*	out param pub: where to write pub key in bn format
+*	out param p: where to write prime in bn format
+*	out param q: where to write sunprime (length 20 bytes) in bn format
+*	out param g: where to write base in bn format
+*/
+typedef int SureWareHook_Load_Dsa_Pubkey_t(char*const msg,const char *key_id,unsigned long num,
+										unsigned long *pub, unsigned long *p,unsigned long*q,
+										unsigned long *g);
+extern SW_EXPORT SureWareHook_Load_Dsa_Pubkey_t SureWareHook_Load_Dsa_Pubkey;
+
+/*
+*	SureWare Free function
+*	Destroy the key into the hardware if destroy==1
+*/
+typedef void SureWareHook_Free_t(char *p,int destroy);
+extern SW_EXPORT SureWareHook_Free_t SureWareHook_Free;
+
+#define SUREWARE_PKCS1_PAD 1
+#define SUREWARE_ISO9796_PAD 2
+#define SUREWARE_NO_PAD 0
+/*
+* SureWare RSA Private Decryption
+* return 1 if success
+*			SureWareHOOK_ERROR_FAILED if error while processing
+*			SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
+*			SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
+*
+*	in param flen : byte size of from and to
+*	in param from : encrypted data buffer, should be a not-null valid pointer
+*	out param tlen: byte size of decrypted data, if error, unexpected value
+*	out param to : decrypted data buffer, should be a not-null valid pointer
+*   in param prsa: a protected key pointer, should be a not-null valid pointer
+*   int padding: padding id as follow
+*					SUREWARE_PKCS1_PAD
+*					SUREWARE_NO_PAD
+*
+*/
+typedef int SureWareHook_Rsa_Priv_Dec_t(char*const msg,int flen,unsigned char *from,
+										int *tlen,unsigned char *to,
+										char *prsa,int padding);
+extern SW_EXPORT SureWareHook_Rsa_Priv_Dec_t SureWareHook_Rsa_Priv_Dec;
+/*
+* SureWare RSA Signature
+* return 1 if success
+*			SureWareHOOK_ERROR_FAILED if error while processing
+*			SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
+*			SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
+*
+*	in param flen : byte size of from and to
+*	in param from : encrypted data buffer, should be a not-null valid pointer
+*	out param tlen: byte size of decrypted data, if error, unexpected value
+*	out param to : decrypted data buffer, should be a not-null valid pointer
+*   in param prsa: a protected key pointer, should be a not-null valid pointer
+*   int padding: padding id as follow
+*					SUREWARE_PKCS1_PAD
+*					SUREWARE_ISO9796_PAD
+*
+*/
+typedef int SureWareHook_Rsa_Sign_t(char*const msg,int flen,unsigned char *from,
+										int *tlen,unsigned char *to,
+										char *prsa,int padding);
+extern SW_EXPORT SureWareHook_Rsa_Sign_t SureWareHook_Rsa_Sign;
+/*
+* SureWare DSA Signature
+* return 1 if success
+*			SureWareHOOK_ERROR_FAILED if error while processing
+*			SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
+*			SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
+*
+*	in param flen : byte size of from and to
+*	in param from : encrypted data buffer, should be a not-null valid pointer
+*	out param to : decrypted data buffer, should be a 40bytes valid pointer
+*   in param pdsa: a protected key pointer, should be a not-null valid pointer
+*
+*/
+typedef int SureWareHook_Dsa_Sign_t(char*const msg,int flen,const unsigned char *from,
+										unsigned long *r,unsigned long *s,char *pdsa);
+extern SW_EXPORT SureWareHook_Dsa_Sign_t SureWareHook_Dsa_Sign;
+
+
+/*
+* SureWare Mod Exp
+* return 1 if success
+*			SureWareHOOK_ERROR_FAILED if error while processing
+*			SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
+*			SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
+*
+*	mod and res are mlen bytes long.
+*	exp is elen bytes long
+*	data is dlen bytes long
+*	mlen,elen and dlen are all multiple of sizeof(unsigned long)
+*/
+typedef int SureWareHook_Mod_Exp_t(char*const msg,int mlen,const unsigned long *mod,
+									int elen,const unsigned long *exponent,
+									int dlen,unsigned long *data,
+									unsigned long *res);
+extern SW_EXPORT SureWareHook_Mod_Exp_t SureWareHook_Mod_Exp;
+
diff --git a/openssl/include/openssl/aes.h b/openssl/include/openssl/aes.h
new file mode 100644
index 0000000..f646d41
--- /dev/null
+++ b/openssl/include/openssl/aes.h
@@ -0,0 +1 @@
+#include "../../crypto/aes/aes.h"
diff --git a/openssl/include/openssl/asn1.h b/openssl/include/openssl/asn1.h
new file mode 100644
index 0000000..5432ed8
--- /dev/null
+++ b/openssl/include/openssl/asn1.h
@@ -0,0 +1 @@
+#include "../../crypto/asn1/asn1.h"
diff --git a/openssl/include/openssl/asn1_mac.h b/openssl/include/openssl/asn1_mac.h
new file mode 100644
index 0000000..214787c
--- /dev/null
+++ b/openssl/include/openssl/asn1_mac.h
@@ -0,0 +1 @@
+#include "../../crypto/asn1/asn1_mac.h"
diff --git a/openssl/include/openssl/asn1t.h b/openssl/include/openssl/asn1t.h
new file mode 100644
index 0000000..4de87a9
--- /dev/null
+++ b/openssl/include/openssl/asn1t.h
@@ -0,0 +1 @@
+#include "../../crypto/asn1/asn1t.h"
diff --git a/openssl/include/openssl/bio.h b/openssl/include/openssl/bio.h
new file mode 100644
index 0000000..34f8a2d
--- /dev/null
+++ b/openssl/include/openssl/bio.h
@@ -0,0 +1 @@
+#include "../../crypto/bio/bio.h"
diff --git a/openssl/include/openssl/blowfish.h b/openssl/include/openssl/blowfish.h
new file mode 100644
index 0000000..8d515fe
--- /dev/null
+++ b/openssl/include/openssl/blowfish.h
@@ -0,0 +1 @@
+#include "../../crypto/bf/blowfish.h"
diff --git a/openssl/include/openssl/bn.h b/openssl/include/openssl/bn.h
new file mode 100644
index 0000000..f47d65a
--- /dev/null
+++ b/openssl/include/openssl/bn.h
@@ -0,0 +1 @@
+#include "../../crypto/bn/bn.h"
diff --git a/openssl/include/openssl/buffer.h b/openssl/include/openssl/buffer.h
new file mode 100644
index 0000000..1d2c2a2
--- /dev/null
+++ b/openssl/include/openssl/buffer.h
@@ -0,0 +1 @@
+#include "../../crypto/buffer/buffer.h"
diff --git a/openssl/include/openssl/camellia.h b/openssl/include/openssl/camellia.h
new file mode 100644
index 0000000..5a0a141
--- /dev/null
+++ b/openssl/include/openssl/camellia.h
@@ -0,0 +1 @@
+#include "../../crypto/camellia/camellia.h"
diff --git a/openssl/include/openssl/cast.h b/openssl/include/openssl/cast.h
new file mode 100644
index 0000000..12cf92c
--- /dev/null
+++ b/openssl/include/openssl/cast.h
@@ -0,0 +1 @@
+#include "../../crypto/cast/cast.h"
diff --git a/openssl/include/openssl/cms.h b/openssl/include/openssl/cms.h
new file mode 100644
index 0000000..8687c7f
--- /dev/null
+++ b/openssl/include/openssl/cms.h
@@ -0,0 +1 @@
+#include "../../crypto/cms/cms.h"
diff --git a/openssl/include/openssl/comp.h b/openssl/include/openssl/comp.h
new file mode 100644
index 0000000..d14e36c
--- /dev/null
+++ b/openssl/include/openssl/comp.h
@@ -0,0 +1 @@
+#include "../../crypto/comp/comp.h"
diff --git a/openssl/include/openssl/conf.h b/openssl/include/openssl/conf.h
new file mode 100644
index 0000000..3882c82
--- /dev/null
+++ b/openssl/include/openssl/conf.h
@@ -0,0 +1 @@
+#include "../../crypto/conf/conf.h"
diff --git a/openssl/include/openssl/conf_api.h b/openssl/include/openssl/conf_api.h
new file mode 100644
index 0000000..0393357
--- /dev/null
+++ b/openssl/include/openssl/conf_api.h
@@ -0,0 +1 @@
+#include "../../crypto/conf/conf_api.h"
diff --git a/openssl/include/openssl/crypto.h b/openssl/include/openssl/crypto.h
new file mode 100644
index 0000000..7e3d91e
--- /dev/null
+++ b/openssl/include/openssl/crypto.h
@@ -0,0 +1 @@
+#include "../../crypto/crypto.h"
diff --git a/openssl/include/openssl/des.h b/openssl/include/openssl/des.h
new file mode 100644
index 0000000..1d6631e
--- /dev/null
+++ b/openssl/include/openssl/des.h
@@ -0,0 +1 @@
+#include "../../crypto/des/des.h"
diff --git a/openssl/include/openssl/des_old.h b/openssl/include/openssl/des_old.h
new file mode 100644
index 0000000..e582873
--- /dev/null
+++ b/openssl/include/openssl/des_old.h
@@ -0,0 +1 @@
+#include "../../crypto/des/des_old.h"
diff --git a/openssl/include/openssl/dh.h b/openssl/include/openssl/dh.h
new file mode 100644
index 0000000..f70a767
--- /dev/null
+++ b/openssl/include/openssl/dh.h
@@ -0,0 +1 @@
+#include "../../crypto/dh/dh.h"
diff --git a/openssl/include/openssl/dsa.h b/openssl/include/openssl/dsa.h
new file mode 100644
index 0000000..0365acf
--- /dev/null
+++ b/openssl/include/openssl/dsa.h
@@ -0,0 +1 @@
+#include "../../crypto/dsa/dsa.h"
diff --git a/openssl/include/openssl/dso.h b/openssl/include/openssl/dso.h
new file mode 100644
index 0000000..f3c8de2
--- /dev/null
+++ b/openssl/include/openssl/dso.h
@@ -0,0 +1 @@
+#include "../../crypto/dso/dso.h"
diff --git a/openssl/include/openssl/dtls1.h b/openssl/include/openssl/dtls1.h
new file mode 100644
index 0000000..ac8ab57
--- /dev/null
+++ b/openssl/include/openssl/dtls1.h
@@ -0,0 +1 @@
+#include "../../ssl/dtls1.h"
diff --git a/openssl/include/openssl/e_os2.h b/openssl/include/openssl/e_os2.h
new file mode 100644
index 0000000..ab3f1ee
--- /dev/null
+++ b/openssl/include/openssl/e_os2.h
@@ -0,0 +1 @@
+#include "../../e_os2.h"
diff --git a/openssl/include/openssl/ebcdic.h b/openssl/include/openssl/ebcdic.h
new file mode 100644
index 0000000..6dedc70
--- /dev/null
+++ b/openssl/include/openssl/ebcdic.h
@@ -0,0 +1 @@
+#include "../../crypto/ebcdic.h"
diff --git a/openssl/include/openssl/ec.h b/openssl/include/openssl/ec.h
new file mode 100644
index 0000000..7d20614
--- /dev/null
+++ b/openssl/include/openssl/ec.h
@@ -0,0 +1 @@
+#include "../../crypto/ec/ec.h"
diff --git a/openssl/include/openssl/ecdh.h b/openssl/include/openssl/ecdh.h
new file mode 100644
index 0000000..ad6e3dc
--- /dev/null
+++ b/openssl/include/openssl/ecdh.h
@@ -0,0 +1 @@
+#include "../../crypto/ecdh/ecdh.h"
diff --git a/openssl/include/openssl/ecdsa.h b/openssl/include/openssl/ecdsa.h
new file mode 100644
index 0000000..da45123
--- /dev/null
+++ b/openssl/include/openssl/ecdsa.h
@@ -0,0 +1 @@
+#include "../../crypto/ecdsa/ecdsa.h"
diff --git a/openssl/include/openssl/engine.h b/openssl/include/openssl/engine.h
new file mode 100644
index 0000000..2dceaac
--- /dev/null
+++ b/openssl/include/openssl/engine.h
@@ -0,0 +1 @@
+#include "../../crypto/engine/engine.h"
diff --git a/openssl/include/openssl/err.h b/openssl/include/openssl/err.h
new file mode 100644
index 0000000..caf89a9
--- /dev/null
+++ b/openssl/include/openssl/err.h
@@ -0,0 +1 @@
+#include "../../crypto/err/err.h"
diff --git a/openssl/include/openssl/evp.h b/openssl/include/openssl/evp.h
new file mode 100644
index 0000000..dd7bcda
--- /dev/null
+++ b/openssl/include/openssl/evp.h
@@ -0,0 +1 @@
+#include "../../crypto/evp/evp.h"
diff --git a/openssl/include/openssl/hmac.h b/openssl/include/openssl/hmac.h
new file mode 100644
index 0000000..202128b
--- /dev/null
+++ b/openssl/include/openssl/hmac.h
@@ -0,0 +1 @@
+#include "../../crypto/hmac/hmac.h"
diff --git a/openssl/include/openssl/idea.h b/openssl/include/openssl/idea.h
new file mode 100644
index 0000000..bdf697d
--- /dev/null
+++ b/openssl/include/openssl/idea.h
@@ -0,0 +1 @@
+#include "../../crypto/idea/idea.h"
diff --git a/openssl/include/openssl/krb5_asn.h b/openssl/include/openssl/krb5_asn.h
new file mode 100644
index 0000000..0d3feea
--- /dev/null
+++ b/openssl/include/openssl/krb5_asn.h
@@ -0,0 +1 @@
+#include "../../crypto/krb5/krb5_asn.h"
diff --git a/openssl/include/openssl/kssl.h b/openssl/include/openssl/kssl.h
new file mode 100644
index 0000000..719634a
--- /dev/null
+++ b/openssl/include/openssl/kssl.h
@@ -0,0 +1 @@
+#include "../../ssl/kssl.h"
diff --git a/openssl/include/openssl/lhash.h b/openssl/include/openssl/lhash.h
new file mode 100644
index 0000000..2d3db87
--- /dev/null
+++ b/openssl/include/openssl/lhash.h
@@ -0,0 +1 @@
+#include "../../crypto/lhash/lhash.h"
diff --git a/openssl/include/openssl/md2.h b/openssl/include/openssl/md2.h
new file mode 100644
index 0000000..4c3398c
--- /dev/null
+++ b/openssl/include/openssl/md2.h
@@ -0,0 +1 @@
+#include "../../crypto/md2/md2.h"
diff --git a/openssl/include/openssl/md4.h b/openssl/include/openssl/md4.h
new file mode 100644
index 0000000..611806e
--- /dev/null
+++ b/openssl/include/openssl/md4.h
@@ -0,0 +1 @@
+#include "../../crypto/md4/md4.h"
diff --git a/openssl/include/openssl/md5.h b/openssl/include/openssl/md5.h
new file mode 100644
index 0000000..aa8cd0b
--- /dev/null
+++ b/openssl/include/openssl/md5.h
@@ -0,0 +1 @@
+#include "../../crypto/md5/md5.h"
diff --git a/openssl/include/openssl/mdc2.h b/openssl/include/openssl/mdc2.h
new file mode 100644
index 0000000..ac284a1
--- /dev/null
+++ b/openssl/include/openssl/mdc2.h
@@ -0,0 +1 @@
+#include "../../crypto/mdc2/mdc2.h"
diff --git a/openssl/include/openssl/modes.h b/openssl/include/openssl/modes.h
new file mode 100644
index 0000000..f57fcfe
--- /dev/null
+++ b/openssl/include/openssl/modes.h
@@ -0,0 +1 @@
+#include "../../crypto/modes/modes.h"
diff --git a/openssl/include/openssl/obj_mac.h b/openssl/include/openssl/obj_mac.h
new file mode 100644
index 0000000..3890fa9
--- /dev/null
+++ b/openssl/include/openssl/obj_mac.h
@@ -0,0 +1 @@
+#include "../../crypto/objects/obj_mac.h"
diff --git a/openssl/include/openssl/objects.h b/openssl/include/openssl/objects.h
new file mode 100644
index 0000000..5365a04
--- /dev/null
+++ b/openssl/include/openssl/objects.h
@@ -0,0 +1 @@
+#include "../../crypto/objects/objects.h"
diff --git a/openssl/include/openssl/ocsp.h b/openssl/include/openssl/ocsp.h
new file mode 100644
index 0000000..50e2885
--- /dev/null
+++ b/openssl/include/openssl/ocsp.h
@@ -0,0 +1 @@
+#include "../../crypto/ocsp/ocsp.h"
diff --git a/openssl/include/openssl/opensslv.h b/openssl/include/openssl/opensslv.h
new file mode 100644
index 0000000..c39a0c3
--- /dev/null
+++ b/openssl/include/openssl/opensslv.h
@@ -0,0 +1 @@
+#include "../../crypto/opensslv.h"
diff --git a/openssl/include/openssl/ossl_typ.h b/openssl/include/openssl/ossl_typ.h
new file mode 100644
index 0000000..ddd7e58
--- /dev/null
+++ b/openssl/include/openssl/ossl_typ.h
@@ -0,0 +1 @@
+#include "../../crypto/ossl_typ.h"
diff --git a/openssl/include/openssl/pem.h b/openssl/include/openssl/pem.h
new file mode 100644
index 0000000..5bcc5c5
--- /dev/null
+++ b/openssl/include/openssl/pem.h
@@ -0,0 +1 @@
+#include "../../crypto/pem/pem.h"
diff --git a/openssl/include/openssl/pem2.h b/openssl/include/openssl/pem2.h
new file mode 100644
index 0000000..bcd3acf
--- /dev/null
+++ b/openssl/include/openssl/pem2.h
@@ -0,0 +1 @@
+#include "../../crypto/pem/pem2.h"
diff --git a/openssl/include/openssl/pkcs12.h b/openssl/include/openssl/pkcs12.h
new file mode 100644
index 0000000..0b5fbbf
--- /dev/null
+++ b/openssl/include/openssl/pkcs12.h
@@ -0,0 +1 @@
+#include "../../crypto/pkcs12/pkcs12.h"
diff --git a/openssl/include/openssl/pkcs7.h b/openssl/include/openssl/pkcs7.h
new file mode 100644
index 0000000..2e19d7c
--- /dev/null
+++ b/openssl/include/openssl/pkcs7.h
@@ -0,0 +1 @@
+#include "../../crypto/pkcs7/pkcs7.h"
diff --git a/openssl/include/openssl/pqueue.h b/openssl/include/openssl/pqueue.h
new file mode 100644
index 0000000..9681ff5
--- /dev/null
+++ b/openssl/include/openssl/pqueue.h
@@ -0,0 +1 @@
+#include "../../crypto/pqueue/pqueue.h"
diff --git a/openssl/include/openssl/rand.h b/openssl/include/openssl/rand.h
new file mode 100644
index 0000000..9d1521b
--- /dev/null
+++ b/openssl/include/openssl/rand.h
@@ -0,0 +1 @@
+#include "../../crypto/rand/rand.h"
diff --git a/openssl/include/openssl/rc2.h b/openssl/include/openssl/rc2.h
new file mode 100644
index 0000000..f2f2bd1
--- /dev/null
+++ b/openssl/include/openssl/rc2.h
@@ -0,0 +1 @@
+#include "../../crypto/rc2/rc2.h"
diff --git a/openssl/include/openssl/rc4.h b/openssl/include/openssl/rc4.h
new file mode 100644
index 0000000..306de2f
--- /dev/null
+++ b/openssl/include/openssl/rc4.h
@@ -0,0 +1 @@
+#include "../../crypto/rc4/rc4.h"
diff --git a/openssl/include/openssl/ripemd.h b/openssl/include/openssl/ripemd.h
new file mode 100644
index 0000000..11351fc
--- /dev/null
+++ b/openssl/include/openssl/ripemd.h
@@ -0,0 +1 @@
+#include "../../crypto/ripemd/ripemd.h"
diff --git a/openssl/include/openssl/rsa.h b/openssl/include/openssl/rsa.h
new file mode 100644
index 0000000..975e5d3
--- /dev/null
+++ b/openssl/include/openssl/rsa.h
@@ -0,0 +1 @@
+#include "../../crypto/rsa/rsa.h"
diff --git a/openssl/include/openssl/safestack.h b/openssl/include/openssl/safestack.h
new file mode 100644
index 0000000..8a282b8
--- /dev/null
+++ b/openssl/include/openssl/safestack.h
@@ -0,0 +1 @@
+#include "../../crypto/stack/safestack.h"
diff --git a/openssl/include/openssl/seed.h b/openssl/include/openssl/seed.h
new file mode 100644
index 0000000..bbbf596
--- /dev/null
+++ b/openssl/include/openssl/seed.h
@@ -0,0 +1 @@
+#include "../../crypto/seed/seed.h"
diff --git a/openssl/include/openssl/sha.h b/openssl/include/openssl/sha.h
new file mode 100644
index 0000000..ab9d94c
--- /dev/null
+++ b/openssl/include/openssl/sha.h
@@ -0,0 +1 @@
+#include "../../crypto/sha/sha.h"
diff --git a/openssl/include/openssl/ssl.h b/openssl/include/openssl/ssl.h
new file mode 100644
index 0000000..0b0589c
--- /dev/null
+++ b/openssl/include/openssl/ssl.h
@@ -0,0 +1 @@
+#include "../../ssl/ssl.h"
diff --git a/openssl/include/openssl/ssl2.h b/openssl/include/openssl/ssl2.h
new file mode 100644
index 0000000..11b2205
--- /dev/null
+++ b/openssl/include/openssl/ssl2.h
@@ -0,0 +1 @@
+#include "../../ssl/ssl2.h"
diff --git a/openssl/include/openssl/ssl23.h b/openssl/include/openssl/ssl23.h
new file mode 100644
index 0000000..fe4dae6
--- /dev/null
+++ b/openssl/include/openssl/ssl23.h
@@ -0,0 +1 @@
+#include "../../ssl/ssl23.h"
diff --git a/openssl/include/openssl/ssl3.h b/openssl/include/openssl/ssl3.h
new file mode 100644
index 0000000..0fb66a6
--- /dev/null
+++ b/openssl/include/openssl/ssl3.h
@@ -0,0 +1 @@
+#include "../../ssl/ssl3.h"
diff --git a/openssl/include/openssl/stack.h b/openssl/include/openssl/stack.h
new file mode 100644
index 0000000..295968c
--- /dev/null
+++ b/openssl/include/openssl/stack.h
@@ -0,0 +1 @@
+#include "../../crypto/stack/stack.h"
diff --git a/openssl/include/openssl/store.h b/openssl/include/openssl/store.h
new file mode 100644
index 0000000..84dc39f
--- /dev/null
+++ b/openssl/include/openssl/store.h
@@ -0,0 +1 @@
+#include "../../crypto/store/store.h"
diff --git a/openssl/include/openssl/symhacks.h b/openssl/include/openssl/symhacks.h
new file mode 100644
index 0000000..f946f4f
--- /dev/null
+++ b/openssl/include/openssl/symhacks.h
@@ -0,0 +1 @@
+#include "../../crypto/symhacks.h"
diff --git a/openssl/include/openssl/tls1.h b/openssl/include/openssl/tls1.h
new file mode 100644
index 0000000..c43a70f
--- /dev/null
+++ b/openssl/include/openssl/tls1.h
@@ -0,0 +1 @@
+#include "../../ssl/tls1.h"
diff --git a/openssl/include/openssl/ts.h b/openssl/include/openssl/ts.h
new file mode 100644
index 0000000..fe8a2cb
--- /dev/null
+++ b/openssl/include/openssl/ts.h
@@ -0,0 +1 @@
+#include "../../crypto/ts/ts.h"
diff --git a/openssl/include/openssl/txt_db.h b/openssl/include/openssl/txt_db.h
new file mode 100644
index 0000000..167621b
--- /dev/null
+++ b/openssl/include/openssl/txt_db.h
@@ -0,0 +1 @@
+#include "../../crypto/txt_db/txt_db.h"
diff --git a/openssl/include/openssl/ui.h b/openssl/include/openssl/ui.h
new file mode 100644
index 0000000..43dd3ae
--- /dev/null
+++ b/openssl/include/openssl/ui.h
@@ -0,0 +1 @@
+#include "../../crypto/ui/ui.h"
diff --git a/openssl/include/openssl/ui_compat.h b/openssl/include/openssl/ui_compat.h
new file mode 100644
index 0000000..c83f160
--- /dev/null
+++ b/openssl/include/openssl/ui_compat.h
@@ -0,0 +1 @@
+#include "../../crypto/ui/ui_compat.h"
diff --git a/openssl/include/openssl/whrlpool.h b/openssl/include/openssl/whrlpool.h
new file mode 100644
index 0000000..e2424fa
--- /dev/null
+++ b/openssl/include/openssl/whrlpool.h
@@ -0,0 +1 @@
+#include "../../crypto/whrlpool/whrlpool.h"
diff --git a/openssl/include/openssl/x509.h b/openssl/include/openssl/x509.h
new file mode 100644
index 0000000..a4651a2
--- /dev/null
+++ b/openssl/include/openssl/x509.h
@@ -0,0 +1 @@
+#include "../../crypto/x509/x509.h"
diff --git a/openssl/include/openssl/x509_vfy.h b/openssl/include/openssl/x509_vfy.h
new file mode 100644
index 0000000..b897aa0
--- /dev/null
+++ b/openssl/include/openssl/x509_vfy.h
@@ -0,0 +1 @@
+#include "../../crypto/x509/x509_vfy.h"
diff --git a/openssl/include/openssl/x509v3.h b/openssl/include/openssl/x509v3.h
new file mode 100644
index 0000000..363795e
--- /dev/null
+++ b/openssl/include/openssl/x509v3.h
@@ -0,0 +1 @@
+#include "../../crypto/x509v3/x509v3.h"
diff --git a/openssl/install.com b/openssl/install.com
new file mode 100644
index 0000000..6a0ea2d
--- /dev/null
+++ b/openssl/install.com
@@ -0,0 +1,136 @@
+$! INSTALL.COM -- Installs the files in a given directory tree
+$!
+$! Author: Richard Levitte <richard@levitte.org>
+$! Time of creation: 22-MAY-1998 10:13
+$!
+$! P1  root of the directory tree
+$! P2  "64" for 64-bit pointers.
+$!
+$!
+$! Announce/identify.
+$!
+$ proc = f$environment( "procedure")
+$ write sys$output "@@@ "+ -
+   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
+$!
+$ def_orig = f$environment( "default")
+$ on error then goto tidy
+$ on control_c then goto tidy
+$!
+$ if (p1 .eqs. "")
+$ then
+$   write sys$output "First argument missing."
+$   write sys$output -
+     "It should be the directory where you want things installed."
+$   exit
+$ endif
+$!
+$ if (f$getsyi("cpu") .lt. 128)
+$ then
+$   arch = "VAX"
+$ else
+$   arch = f$edit( f$getsyi( "arch_name"), "upcase")
+$   if (arch .eqs. "") then arch = "UNK"
+$ endif
+$!
+$ archd = arch
+$!
+$ if (p2 .nes. "")
+$ then
+$   if (p2 .eqs. "64")
+$   then
+$     archd = arch+ "_64"
+$   else
+$     if (p2 .nes. "32")
+$     then
+$       write sys$output "Second argument invalid."
+$       write sys$output "It should be "32", "64", or nothing."
+$       exit
+$     endif
+$   endif
+$ endif
+$!
+$ root = f$parse( p1, "[]A.;0", , , "syntax_only, no_conceal") - "A.;0"
+$ root_dev = f$parse( root, , , "device", "syntax_only")
+$ root_dir = f$parse( root, , , "directory", "syntax_only") -
+		   - ".][000000" - "[000000." - "][" - "[" - "]"
+$ root = root_dev + "[" + root_dir
+$!
+$ define /nolog wrk_sslroot 'root'.] /trans=conc
+$ define /nolog wrk_sslcerts wrk_sslroot:[certs]
+$ define /nolog wrk_sslinclude wrk_sslroot:[include]
+$ define /nolog wrk_ssllib wrk_sslroot:[lib]
+$ define /nolog wrk_sslprivate wrk_sslroot:[private]
+$ define /nolog wrk_sslxexe wrk_sslroot:['archd'_exe]
+$ define /nolog wrk_sslxlib wrk_sslroot:['arch'_lib]
+$!
+$! Exhibit the destination directory.
+$!
+$ write sys$output "   Installing to (WRK_SSLROOT) ="
+$ write sys$output "    ''f$trnlnm( "wrk_sslroot")'"
+$ write sys$output ""
+$!
+$ if f$parse("wrk_sslroot:[000000]") .eqs. "" then -
+   create /directory /log wrk_sslroot:[000000]
+$ if f$parse("wrk_sslxexe:") .eqs. "" then -
+   create /directory /log wrk_sslxexe:
+$ if f$parse("wrk_sslxlib:") .eqs. "" then -
+   create /directory /log wrk_sslxlib:
+$ if f$parse("wrk_ssllib:") .eqs. "" then -
+   create /directory /log wrk_ssllib:
+$ if f$parse("wrk_sslinclude:") .eqs. "" then -
+   create /directory /log wrk_sslinclude:
+$ if f$parse("wrk_sslcerts:") .eqs. "" then -
+   create /directory /log wrk_sslcerts:
+$ if f$parse("wrk_sslprivate:") .eqs. "" then -
+   create /directory /log wrk_sslprivate:
+$ if f$parse("wrk_sslroot:[VMS]") .EQS. "" THEN -
+   create /directory /log wrk_sslroot:[VMS]
+$!
+$ sdirs := CRYPTO, SSL, APPS, VMS !!!, RSAREF, TEST, TOOLS
+$ exheader := e_os2.h
+$!
+$ copy /protection = w:re 'exheader' wrk_sslinclude: /log
+$!
+$ i = 0
+$ loop_sdirs: 
+$   d = f$edit( f$element(i, ",", sdirs), "trim")
+$   i = i + 1
+$   if d .eqs. "," then goto loop_sdirs_end
+$   write sys$output "Installing ", d, " files."
+$   set default [.'d']
+$   @ install-'d'.com 'root'] 'p2'
+$   set default 'def_orig'
+$ goto loop_sdirs
+$ loop_sdirs_end:
+$!
+$ write sys$output ""
+$ write sys$output "	Installation done!"
+$ write sys$output ""
+$ if (f$search( root+ "...]*.*;-1") .nes. "")
+$ then
+$   write sys$output "	You might want to purge ", root, "...]"
+$   write sys$output ""
+$ endif
+$!
+$ tidy:
+$!
+$ set default 'def_orig'
+$!
+$ call deass wrk_sslroot
+$ call deass wrk_sslcerts
+$ call deass wrk_sslinclude
+$ call deass wrk_ssllib
+$ call deass wrk_sslprivate
+$ call deass wrk_sslxexe
+$ call deass wrk_sslxlib
+$!
+$ exit
+$!
+$ deass: subroutine
+$ if (f$trnlnm( p1, "LNM$PROCESS") .nes. "")
+$ then
+$   deassign /process 'p1'
+$ endif
+$ endsubroutine
+$!
diff --git a/openssl/makevms.com b/openssl/makevms.com
new file mode 100755
index 0000000..eb22f20
--- /dev/null
+++ b/openssl/makevms.com
@@ -0,0 +1,1533 @@
+$!
+$! MAKEVMS.COM
+$! Original Author:  UNKNOWN
+$! Rewritten By:  Robert Byer
+$!                Vice-President
+$!                A-Com Computing, Inc.
+$!                byer@mail.all-net.net
+$!
+$! Changes by Richard Levitte <richard@levitte.org>
+$!	      Zoltan Arpadffy <zoli@polarhome.com>
+$!
+$! This procedure creates the SSL libraries of "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB"
+$! "[.xxx.EXE.SSL]LIBSSL.OLB"
+$! The "xxx" denotes the machine architecture of ALPHA, IA64 or VAX.
+$!
+$! This procedures accepts two command line options listed below.
+$!
+$! P1 specifies one of the following build options:
+$!
+$!      ALL       Just build "everything".
+$!      CONFIG    Just build the "[.CRYPTO._xxx]OPENSSLCONF.H" file.
+$!      BUILDINF  Just build the "[.CRYPTO._xxx]BUILDINF.H" file.
+$!      SOFTLINKS Just fix the Unix soft links.
+$!      BUILDALL  Same as ALL, except CONFIG, BUILDINF and SOFTILNKS aren't done.
+$!      CRYPTO    Just build the "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" library.
+$!      CRYPTO/x  Just build the x part of the
+$!                "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" library.
+$!      SSL       Just build the "[.xxx.EXE.SSL]LIBSSL.OLB" library.
+$!      SSL_TASK  Just build the "[.xxx.EXE.SSL]SSL_TASK.EXE" program.
+$!      TEST      Just build the "[.xxx.EXE.TEST]" test programs for OpenSSL.
+$!      APPS      Just build the "[.xxx.EXE.APPS]" application programs for OpenSSL.
+$!      ENGINES   Just build the "[.xxx.EXE.ENGINES]" application programs for OpenSSL.
+$!
+$! P2, if defined, specifies the C pointer size.  Ignored on VAX.
+$!      ("64=ARGV" gives more efficient code with HP C V7.3 or newer.)
+$!      Supported values are:
+$!
+$!      ""       Compile with default (/NOPOINTER_SIZE).
+$!      32       Compile with /POINTER_SIZE=32 (SHORT).
+$!      64       Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV]).
+$!               (Automatically select ARGV if compiler supports it.)
+$!      64=      Compile with /POINTER_SIZE=64 (LONG).
+$!      64=ARGV  Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV).
+$!
+$! P3 specifies DEBUG or NODEBUG, to compile with or without debugging
+$!    information.
+$!
+$! P4 specifies which compiler to try to compile under.
+$!
+$!	  VAXC	 For VAX C.
+$!	  DECC	 For DEC C.
+$!	  GNUC	 For GNU C.
+$!	  LINK   To only link the programs from existing object files.
+$!               (not yet implemented)
+$!
+$! If you don't specify a compiler, it will try to determine which
+$! "C" compiler to use.
+$!
+$! P5, if defined, sets a TCP/IP library to use, through one of the following
+$! keywords:
+$!
+$!	UCX		for UCX or UCX emulation
+$!	TCPIP		for TCP/IP Services or TCP/IP Services emulation
+$!			(this is prefered over UCX)
+$!	SOCKETSHR	for SOCKETSHR+NETLIB
+$!	NONE		to avoid specifying which TCP/IP implementation to
+$!			use at build time (this works with DEC C).  This is
+$!			the default.
+$!
+$! P6, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up).
+$!
+$! P7, if defined, specifies a directory where ZLIB files (zlib.h,
+$! libz.olb) may be found.  Optionally, a non-default object library
+$! name may be included ("dev:[dir]libz_64.olb", for example).
+$!
+$!
+$! Announce/identify.
+$!
+$ proc = f$environment( "procedure")
+$ write sys$output "@@@ "+ -
+   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
+$!
+$ DEF_ORIG = F$ENVIRONMENT( "DEFAULT")
+$ ON ERROR THEN GOTO TIDY
+$ ON CONTROL_C THEN GOTO TIDY
+$!
+$! Check if we're in a batch job, and make sure we get to 
+$! the directory this script is in
+$!
+$ IF F$MODE() .EQS. "BATCH"
+$ THEN
+$   COMNAME=F$ENVIRONMENT("PROCEDURE")
+$   COMPATH=F$PARSE("A.;",COMNAME) - "A.;"
+$   SET DEF 'COMPATH'
+$ ENDIF
+$!
+$! Check What Architecture We Are Using.
+$!
+$ IF (F$GETSYI("CPU").LT.128)
+$ THEN
+$!
+$!  The Architecture Is VAX.
+$!
+$   ARCH = "VAX"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  The Architecture Is Alpha, IA64 or whatever comes in the future.
+$!
+$   ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
+$   IF (ARCH .EQS. "") THEN ARCH = "UNK"
+$!
+$! End The Architecture Check.
+$!
+$ ENDIF
+$!
+$ ARCHD = ARCH
+$ LIB32 = "32"
+$ POINTER_SIZE = ""
+$!
+$! Get VMS version.
+$!
+$ VMS_VERSION = f$edit( f$getsyi( "VERSION"), "TRIM")
+$!
+$! Check To Make Sure We Have Valid Command Line Parameters.
+$!
+$ GOSUB CHECK_OPTIONS
+$!
+$! Check To See What We Are To Do.
+$!
+$ IF (BUILDCOMMAND.EQS."ALL")
+$ THEN
+$!
+$!  Start with building the OpenSSL configuration file.
+$!
+$   GOSUB CONFIG
+$!
+$!  Create The "BUILDINF.H" Include File.
+$!
+$   GOSUB BUILDINF
+$!
+$!  Fix The Unix Softlinks.
+$!
+$   GOSUB SOFTLINKS
+$!
+$ ENDIF
+$!
+$ IF (BUILDCOMMAND.EQS."ALL".OR.BUILDCOMMAND.EQS."BUILDALL")
+$ THEN
+$!
+$!  Build The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library.
+$!
+$   GOSUB CRYPTO
+$!
+$!  Build The [.xxx.EXE.SSL]LIBSSL.OLB Library.
+$!
+$   GOSUB SSL
+$!
+$!  Build The [.xxx.EXE.SSL]SSL_TASK.EXE DECNet SSL Engine.
+$!
+$   GOSUB SSL_TASK
+$!
+$!  Build The [.xxx.EXE.TEST] OpenSSL Test Utilities.
+$!
+$   GOSUB TEST
+$!
+$!  Build The [.xxx.EXE.APPS] OpenSSL Application Utilities.
+$!
+$   GOSUB APPS
+$!
+$!  Build The [.xxx.EXE.ENGINES] OpenSSL Shareable Engines.
+$!
+$   GOSUB ENGINES
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!    Build Just What The User Wants Us To Build.
+$!
+$     GOSUB 'BUILDCOMMAND'
+$!
+$ ENDIF
+$!
+$! Time To EXIT.
+$!
+$ GOTO TIDY
+$!
+$! Rebuild The [.CRYPTO._xxx]OPENSSLCONF.H" file.
+$!
+$ CONFIG:
+$!
+$! Tell The User We Are Creating The [.CRYPTO._xxx]OPENSSLCONF.H File.
+$!
+$ WRITE SYS$OUTPUT "Creating [.CRYPTO.''ARCHD']OPENSSLCONF.H Include File."
+$!
+$! First, make sure the directory exists.
+$!
+$ IF F$PARSE("SYS$DISK:[.CRYPTO.''ARCHD']") .EQS. "" THEN -
+     CREATE/DIRECTORY SYS$DISK:[.CRYPTO.'ARCHD']
+$!
+$! Different tar/UnZip versions/option may have named the file differently
+$ IF F$SEARCH("[.crypto]opensslconf.h_in") .NES. ""
+$ THEN
+$   OPENSSLCONF_H_IN = "[.crypto]opensslconf.h_in"
+$ ELSE
+$   IF F$SEARCH( "[.crypto]opensslconf_h.in") .NES. ""
+$   THEN
+$     OPENSSLCONF_H_IN = "[.crypto]opensslconf_h.in"
+$   ELSE
+$     ! For ODS-5
+$     IF F$SEARCH( "[.crypto]opensslconf.h.in") .NES. ""
+$     THEN
+$       OPENSSLCONF_H_IN = "[.crypto]opensslconf.h.in"
+$     ELSE
+$       WRITE SYS$ERROR "Couldn't find a [.crypto]opensslconf.h.in.  Exiting!"
+$       $STATUS = %X00018294 ! "%RMS-F-FNF, file not found".
+$       GOTO TIDY
+$     ENDIF
+$   ENDIF
+$ ENDIF
+$!
+$! Create The [.CRYPTO._xxx]OPENSSLCONF.H File.
+$! Make sure it has the right format.
+$!
+$ OSCH_NAME = "SYS$DISK:[.CRYPTO.''ARCHD']OPENSSLCONF.H"
+$ CREATE /FDL=SYS$INPUT: 'OSCH_NAME'
+RECORD
+        FORMAT stream_lf
+$ OPEN /APPEND H_FILE 'OSCH_NAME'
+$!
+$! Write The [.CRYPTO._xxx]OPENSSLCONF.H File.
+$!
+$ WRITE H_FILE "/* This file was automatically built using makevms.com */"
+$ WRITE H_FILE "/* and ''OPENSSLCONF_H_IN' */"
+$!
+$! Write a few macros that indicate how this system was built.
+$!
+$ WRITE H_FILE ""
+$ WRITE H_FILE "#ifndef OPENSSL_SYS_VMS"
+$ WRITE H_FILE "# define OPENSSL_SYS_VMS"
+$ WRITE H_FILE "#endif"
+$
+$! One of the best way to figure out what the list should be is to do
+$! the following on a Unix system:
+$!   grep OPENSSL_NO_ crypto/*/*.h ssl/*.h engines/*.h engines/*/*.h|grep ':# *if'|sed -e 's/^.*def //'|sort|uniq
+$! For that reason, the list will also always end up in alphabetical order
+$ CONFIG_LOGICALS := AES,-
+		     ASM,INLINE_ASM,-
+		     BF,-
+		     BIO,-
+		     BUFFER,-
+		     BUF_FREELISTS,-
+		     CAMELLIA,-
+		     CAST,-
+		     CMS,-
+		     COMP,-
+		     DEPRECATED,-
+		     DES,-
+		     DGRAM,-
+		     DH,-
+		     DSA,-
+		     EC,-
+		     ECDH,-
+		     ECDSA,-
+		     ENGINE,-
+		     ERR,-
+		     EVP,-
+		     FP_API,-
+		     GMP,-
+		     GOST,-
+		     HASH_COMP,-
+		     HMAC,-
+		     IDEA,-
+		     JPAKE,-
+		     KRB5,-
+		     LHASH,-
+		     MD2,-
+		     MD4,-
+		     MD5,-
+		     MDC2,-
+		     OCSP,-
+		     PSK,-
+		     RC2,-
+		     RC4,-
+		     RC5,-
+		     RFC3779,-
+		     RIPEMD,-
+		     RSA,-
+		     SEED,-
+		     SHA,-
+		     SHA0,-
+		     SHA1,-
+		     SHA256,-
+		     SHA512,-
+		     SOCK,-
+		     SSL2,-
+		     STACK,-
+		     STATIC_ENGINE,-
+		     STDIO,-
+		     STORE,-
+		     TLSEXT,-
+		     WHIRLPOOL,-
+		     X509
+$! Add a few that we know about
+$ CONFIG_LOGICALS := 'CONFIG_LOGICALS',-
+		     THREADS
+$! The following rules, which dictate how some algorithm choices affect
+$! others, are picked from Configure.
+$! Quick syntax:
+$!  list = item[ ; list]
+$!  item = algos / dependents
+$!  algos = algo [, algos]
+$!  dependents = dependent [, dependents]
+$! When a list of algos is specified in one item, it means that they must
+$! all be disabled for the rule to apply.
+$! When a list of dependents is specified in one item, it means that they
+$! will all be disabled if the rule applies.
+$! Rules are checked sequentially.  If a rule disables an algorithm, it will
+$! affect all following rules that depend on that algorithm being disabled.
+$! To force something to be enabled or disabled, have no algorithms in the
+$! algos part.
+$ CONFIG_DISABLE_RULES := RIJNDAEL/AES;-
+			  DES/MDC2;-
+			  EC/ECDSA,ECDH;-
+			  MD5/SSL2,SSL3,TLS1;-
+			  SHA/SSL3,TLS1;-
+			  RSA/SSL2;-
+			  RSA,DSA/SSL2;-
+			  DH/SSL3,TLS1;-
+			  TLS1/TLSEXT;-
+			  EC/GOST;-
+			  DSA/GOST;-
+			  DH/GOST;-
+			  /STATIC_ENGINE;-
+			  /KRB5
+$ CONFIG_ENABLE_RULES := ZLIB_DYNAMIC/ZLIB;-
+			 /THREADS
+$
+$! Architecture specific rule addtions
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$   ! Disable algorithms that require 64-bit integers in C
+$   CONFIG_DISABLE_RULES = CONFIG_DISABLE_RULES + -
+			   ";/GOST" + -
+			   ";/WHIRLPOOL"
+$ ENDIF
+$
+$ CONFIG_LOG_I = 0
+$ CONFIG_LOG_LOOP1:
+$   CONFIG_LOG_E = F$EDIT(F$ELEMENT(CONFIG_LOG_I,",",CONFIG_LOGICALS),"TRIM")
+$   CONFIG_LOG_I = CONFIG_LOG_I + 1
+$   IF CONFIG_LOG_E .EQS. "" THEN GOTO CONFIG_LOG_LOOP1
+$   IF CONFIG_LOG_E .EQS. "," THEN GOTO CONFIG_LOG_LOOP1_END
+$   IF F$TRNLNM("OPENSSL_NO_"+CONFIG_LOG_E)
+$   THEN
+$       CONFIG_DISABLED_'CONFIG_LOG_E' := YES
+$       CONFIG_ENABLED_'CONFIG_LOG_E' := NO
+$	CONFIG_CHANGED_'CONFIG_LOG_E' := YES
+$   ELSE
+$       CONFIG_DISABLED_'CONFIG_LOG_E' := NO
+$       CONFIG_ENABLED_'CONFIG_LOG_E' := YES
+$	! Because all algorithms are assumed enabled by default
+$	CONFIG_CHANGED_'CONFIG_LOG_E' := NO
+$   ENDIF
+$   GOTO CONFIG_LOG_LOOP1
+$ CONFIG_LOG_LOOP1_END:
+$
+$! Apply cascading disable rules
+$ CONFIG_DISABLE_I = 0
+$ CONFIG_DISABLE_LOOP0:
+$   CONFIG_DISABLE_E = F$EDIT(F$ELEMENT(CONFIG_DISABLE_I,";", -
+     CONFIG_DISABLE_RULES),"TRIM")
+$   CONFIG_DISABLE_I = CONFIG_DISABLE_I + 1
+$   IF CONFIG_DISABLE_E .EQS. "" THEN GOTO CONFIG_DISABLE_LOOP0
+$   IF CONFIG_DISABLE_E .EQS. ";" THEN GOTO CONFIG_DISABLE_LOOP0_END
+$
+$   CONFIG_DISABLE_ALGOS = F$EDIT(F$ELEMENT(0,"/",CONFIG_DISABLE_E),"TRIM")
+$   CONFIG_DISABLE_DEPENDENTS = F$EDIT(F$ELEMENT(1,"/",CONFIG_DISABLE_E),"TRIM")
+$   TO_DISABLE := YES
+$   CONFIG_ALGO_I = 0
+$   CONFIG_DISABLE_LOOP1:
+$     CONFIG_ALGO_E = F$EDIT(F$ELEMENT(CONFIG_ALGO_I,",", -
+       CONFIG_DISABLE_ALGOS),"TRIM")
+$     CONFIG_ALGO_I = CONFIG_ALGO_I + 1
+$     IF CONFIG_ALGO_E .EQS. "" THEN GOTO CONFIG_DISABLE_LOOP1
+$     IF CONFIG_ALGO_E .EQS. "," THEN GOTO CONFIG_DISABLE_LOOP1_END
+$     IF F$TYPE(CONFIG_DISABLED_'CONFIG_ALGO_E') .EQS. ""
+$     THEN
+$	TO_DISABLE := NO
+$     ELSE
+$	IF .NOT. CONFIG_DISABLED_'CONFIG_ALGO_E' THEN TO_DISABLE := NO
+$     ENDIF
+$     GOTO CONFIG_DISABLE_LOOP1
+$   CONFIG_DISABLE_LOOP1_END:
+$
+$   IF TO_DISABLE
+$   THEN
+$     CONFIG_DEPENDENT_I = 0
+$     CONFIG_DISABLE_LOOP2:
+$	CONFIG_DEPENDENT_E = F$EDIT(F$ELEMENT(CONFIG_DEPENDENT_I,",", -
+         CONFIG_DISABLE_DEPENDENTS),"TRIM")
+$	CONFIG_DEPENDENT_I = CONFIG_DEPENDENT_I + 1
+$	IF CONFIG_DEPENDENT_E .EQS. "" THEN GOTO CONFIG_DISABLE_LOOP2
+$	IF CONFIG_DEPENDENT_E .EQS. "," THEN GOTO CONFIG_DISABLE_LOOP2_END
+$       CONFIG_DISABLED_'CONFIG_DEPENDENT_E' := YES
+$       CONFIG_ENABLED_'CONFIG_DEPENDENT_E' := NO
+$	! Better not to assume defaults at this point...
+$	CONFIG_CHANGED_'CONFIG_DEPENDENT_E' := YES
+$	WRITE SYS$ERROR -
+         "''CONFIG_DEPENDENT_E' disabled by rule ''CONFIG_DISABLE_E'"
+$	GOTO CONFIG_DISABLE_LOOP2
+$     CONFIG_DISABLE_LOOP2_END:
+$   ENDIF
+$   GOTO CONFIG_DISABLE_LOOP0
+$ CONFIG_DISABLE_LOOP0_END:
+$	
+$! Apply cascading enable rules
+$ CONFIG_ENABLE_I = 0
+$ CONFIG_ENABLE_LOOP0:
+$   CONFIG_ENABLE_E = F$EDIT(F$ELEMENT(CONFIG_ENABLE_I,";", -
+     CONFIG_ENABLE_RULES),"TRIM")
+$   CONFIG_ENABLE_I = CONFIG_ENABLE_I + 1
+$   IF CONFIG_ENABLE_E .EQS. "" THEN GOTO CONFIG_ENABLE_LOOP0
+$   IF CONFIG_ENABLE_E .EQS. ";" THEN GOTO CONFIG_ENABLE_LOOP0_END
+$
+$   CONFIG_ENABLE_ALGOS = F$EDIT(F$ELEMENT(0,"/",CONFIG_ENABLE_E),"TRIM")
+$   CONFIG_ENABLE_DEPENDENTS = F$EDIT(F$ELEMENT(1,"/",CONFIG_ENABLE_E),"TRIM")
+$   TO_ENABLE := YES
+$   CONFIG_ALGO_I = 0
+$   CONFIG_ENABLE_LOOP1:
+$     CONFIG_ALGO_E = F$EDIT(F$ELEMENT(CONFIG_ALGO_I,",", -
+       CONFIG_ENABLE_ALGOS),"TRIM")
+$     CONFIG_ALGO_I = CONFIG_ALGO_I + 1
+$     IF CONFIG_ALGO_E .EQS. "" THEN GOTO CONFIG_ENABLE_LOOP1
+$     IF CONFIG_ALGO_E .EQS. "," THEN GOTO CONFIG_ENABLE_LOOP1_END
+$     IF F$TYPE(CONFIG_ENABLED_'CONFIG_ALGO_E') .EQS. ""
+$     THEN
+$	TO_ENABLE := NO
+$     ELSE
+$	IF .NOT. CONFIG_ENABLED_'CONFIG_ALGO_E' THEN TO_ENABLE := NO
+$     ENDIF
+$     GOTO CONFIG_ENABLE_LOOP1
+$   CONFIG_ENABLE_LOOP1_END:
+$
+$   IF TO_ENABLE
+$   THEN
+$     CONFIG_DEPENDENT_I = 0
+$     CONFIG_ENABLE_LOOP2:
+$	CONFIG_DEPENDENT_E = F$EDIT(F$ELEMENT(CONFIG_DEPENDENT_I,",", -
+         CONFIG_ENABLE_DEPENDENTS),"TRIM")
+$	CONFIG_DEPENDENT_I = CONFIG_DEPENDENT_I + 1
+$	IF CONFIG_DEPENDENT_E .EQS. "" THEN GOTO CONFIG_ENABLE_LOOP2
+$	IF CONFIG_DEPENDENT_E .EQS. "," THEN GOTO CONFIG_ENABLE_LOOP2_END
+$       CONFIG_DISABLED_'CONFIG_DEPENDENT_E' := NO
+$       CONFIG_ENABLED_'CONFIG_DEPENDENT_E' := YES
+$	! Better not to assume defaults at this point...
+$	CONFIG_CHANGED_'CONFIG_DEPENDENT_E' := YES
+$	WRITE SYS$ERROR -
+         "''CONFIG_DEPENDENT_E' enabled by rule ''CONFIG_ENABLE_E'"
+$	GOTO CONFIG_ENABLE_LOOP2
+$     CONFIG_ENABLE_LOOP2_END:
+$   ENDIF
+$   GOTO CONFIG_ENABLE_LOOP0
+$ CONFIG_ENABLE_LOOP0_END:
+$
+$! Write to the configuration
+$ CONFIG_LOG_I = 0
+$ CONFIG_LOG_LOOP2:
+$   CONFIG_LOG_E = F$EDIT(F$ELEMENT(CONFIG_LOG_I,",",CONFIG_LOGICALS),"TRIM")
+$   CONFIG_LOG_I = CONFIG_LOG_I + 1
+$   IF CONFIG_LOG_E .EQS. "" THEN GOTO CONFIG_LOG_LOOP2
+$   IF CONFIG_LOG_E .EQS. "," THEN GOTO CONFIG_LOG_LOOP2_END
+$   IF CONFIG_CHANGED_'CONFIG_LOG_E'
+$   THEN
+$     IF CONFIG_DISABLED_'CONFIG_LOG_E'
+$     THEN
+$	WRITE H_FILE "#ifndef OPENSSL_NO_",CONFIG_LOG_E
+$	WRITE H_FILE "# define OPENSSL_NO_",CONFIG_LOG_E
+$	WRITE H_FILE "#endif"
+$     ELSE
+$	WRITE H_FILE "#ifndef OPENSSL_",CONFIG_LOG_E
+$	WRITE H_FILE "# define OPENSSL_",CONFIG_LOG_E
+$	WRITE H_FILE "#endif"
+$     ENDIF
+$   ENDIF
+$   GOTO CONFIG_LOG_LOOP2
+$ CONFIG_LOG_LOOP2_END:
+$!
+$ WRITE H_FILE ""
+$ WRITE H_FILE "/* 2011-02-23 SMS."
+$ WRITE H_FILE " * On VMS (V8.3), setvbuf() doesn't support a 64-bit"
+$ WRITE H_FILE " * ""in"" pointer, and the help says:"
+$ WRITE H_FILE " *       Please note that the previously documented"
+$ WRITE H_FILE " *       value _IONBF is not supported."
+$ WRITE H_FILE " * So, skip it on VMS."
+$ WRITE H_FILE " */"
+$ WRITE H_FILE "#define OPENSSL_NO_SETVBUF_IONBF"
+$ WRITE H_FILE ""
+$!
+$! Add in the common "crypto/opensslconf.h.in".
+$!
+$ TYPE 'OPENSSLCONF_H_IN' /OUTPUT=H_FILE:
+$!
+$ IF ARCH .NES. "VAX"
+$ THEN
+$!
+$!  Write the non-VAX specific data
+$!
+$   WRITE H_FILE "#if defined(HEADER_RC4_H)"
+$   WRITE H_FILE "#undef RC4_INT"
+$   WRITE H_FILE "#define RC4_INT unsigned int"
+$   WRITE H_FILE "#undef RC4_CHUNK"
+$   WRITE H_FILE "#define RC4_CHUNK unsigned long long"
+$   WRITE H_FILE "#endif"
+$!
+$   WRITE H_FILE "#if defined(HEADER_DES_LOCL_H)"
+$   WRITE H_FILE "#undef DES_LONG"
+$   WRITE H_FILE "#define DES_LONG unsigned int"
+$   WRITE H_FILE "#undef DES_PTR"
+$   WRITE H_FILE "#define DES_PTR"
+$   WRITE H_FILE "#undef DES_RISC1"
+$   WRITE H_FILE "#undef DES_RISC2"
+$   WRITE H_FILE "#define DES_RISC1"
+$   WRITE H_FILE "#undef DES_UNROLL"
+$   WRITE H_FILE "#define DES_UNROLL"
+$   WRITE H_FILE "#endif"
+$!
+$   WRITE H_FILE "#if defined(HEADER_BN_H)"
+$   WRITE H_FILE "#undef BN_LLONG"	! Never define with SIXTY_FOUR_BIT
+$   WRITE H_FILE "#undef SIXTY_FOUR_BIT_LONG"
+$   WRITE H_FILE "#undef SIXTY_FOUR_BIT"
+$   WRITE H_FILE "#define SIXTY_FOUR_BIT"
+$   WRITE H_FILE "#undef THIRTY_TWO_BIT"
+$   WRITE H_FILE "#undef SIXTEEN_BIT"
+$   WRITE H_FILE "#undef EIGHT_BIT"
+$   WRITE H_FILE "#endif"
+$
+$   WRITE H_FILE "#undef OPENSSL_EXPORT_VAR_AS_FUNCTION"
+$!
+$!  Else...
+$!
+$ ELSE
+$!
+$!  Write the VAX specific data
+$!
+$   WRITE H_FILE "#if defined(HEADER_RC4_H)"
+$   WRITE H_FILE "#undef RC4_INT"
+$   WRITE H_FILE "#define RC4_INT unsigned char"
+$   WRITE H_FILE "#undef RC4_CHUNK"
+$   WRITE H_FILE "#define RC4_CHUNK unsigned long"
+$   WRITE H_FILE "#endif"
+$!
+$   WRITE H_FILE "#if defined(HEADER_DES_LOCL_H)"
+$   WRITE H_FILE "#undef DES_LONG"
+$   WRITE H_FILE "#define DES_LONG unsigned long"
+$   WRITE H_FILE "#undef DES_PTR"
+$   WRITE H_FILE "#define DES_PTR"
+$   WRITE H_FILE "#undef DES_RISC1"
+$   WRITE H_FILE "#undef DES_RISC2"
+$   WRITE H_FILE "#undef DES_UNROLL"
+$   WRITE H_FILE "#endif"
+$!
+$   WRITE H_FILE "#if defined(HEADER_BN_H)"
+$   WRITE H_FILE "#undef BN_LLONG"	! VAX C/DEC C doesn't have long long
+$   WRITE H_FILE "#undef SIXTY_FOUR_BIT_LONG"
+$   WRITE H_FILE "#undef SIXTY_FOUR_BIT"
+$   WRITE H_FILE "#undef THIRTY_TWO_BIT"
+$   WRITE H_FILE "#define THIRTY_TWO_BIT"
+$   WRITE H_FILE "#undef SIXTEEN_BIT"
+$   WRITE H_FILE "#undef EIGHT_BIT"
+$   WRITE H_FILE "#endif"
+$!
+$! Oddly enough, the following symbol is tested in crypto/sha/sha512.c
+$! before sha.h gets included (and HEADER_SHA_H defined), so we will not
+$! protect this one...
+$   WRITE H_FILE "#undef OPENSSL_NO_SHA512"
+$   WRITE H_FILE "#define OPENSSL_NO_SHA512"
+$!
+$   WRITE H_FILE "#undef OPENSSL_EXPORT_VAR_AS_FUNCTION"
+$   WRITE H_FILE "#define OPENSSL_EXPORT_VAR_AS_FUNCTION"
+$!
+$!  End
+$!
+$ ENDIF
+$!
+$! Close the [.CRYPTO._xxx]OPENSSLCONF.H file
+$!
+$ CLOSE H_FILE
+$!
+$! Purge The [.CRYPTO._xxx]OPENSSLCONF.H file
+$!
+$ PURGE SYS$DISK:[.CRYPTO.'ARCHD']OPENSSLCONF.H
+$!
+$! That's All, Time To RETURN.
+$!
+$ RETURN
+$!
+$! Rebuild The "[.CRYPTO._xxx]BUILDINF.H" file.
+$!
+$ BUILDINF:
+$!
+$! Tell The User We Are Creating The [.CRYPTO._xxx]BUILDINF.H File.
+$!
+$ WRITE SYS$OUTPUT "Creating [.CRYPTO.''ARCHD']BUILDINF.H Include File."
+$!
+$! Create The [.CRYPTO._xxx]BUILDINF.H File.
+$!
+$ BIH_NAME = "SYS$DISK:[.CRYPTO.''ARCHD']BUILDINF.H"
+$ CREATE /FDL=SYS$INPUT: 'BIH_NAME'
+RECORD
+        FORMAT stream_lf
+$!
+$ OPEN /APPEND H_FILE 'bih_name'
+$!
+$! Get The Current Date & Time.
+$!
+$ TIME = F$TIME()
+$!
+$! Write The [.CRYPTO._xxx]BUILDINF.H File.
+$!
+$ CFLAGS = ""
+$ if (POINTER_SIZE .nes. "")
+$ then
+$   CFLAGS = CFLAGS+ "/POINTER_SIZE=''POINTER_SIZE'"
+$ endif
+$ if (ZLIB .nes. "")
+$ then
+$   if (CFLAGS .nes. "") then CFLAGS = CFLAGS+ " "
+$   CFLAGS = CFLAGS+ "/DEFINE=ZLIB"
+$ endif
+$! 
+$ WRITE H_FILE "#define CFLAGS ""''CFLAGS'"""
+$ WRITE H_FILE "#define PLATFORM ""VMS ''ARCHD' ''VMS_VERSION'"""
+$ WRITE H_FILE "#define DATE ""''TIME'"" "
+$!
+$! Close The [.CRYPTO._xxx]BUILDINF.H File.
+$!
+$ CLOSE H_FILE
+$!
+$! Purge The [.CRYPTO._xxx]BUILDINF.H File.
+$!
+$ PURGE SYS$DISK:[.CRYPTO.'ARCHD']BUILDINF.H
+$!
+$! Delete [.CRYPTO]BUILDINF.H File, as there might be some residue from Unix.
+$!
+$ IF F$SEARCH("[.CRYPTO]BUILDINF.H") .NES. "" THEN -
+     DELETE SYS$DISK:[.CRYPTO]BUILDINF.H;*
+$!
+$! That's All, Time To RETURN.
+$!
+$ RETURN
+$!
+$! Copy a lot of files around.
+$!
+$ SOFTLINKS: 
+$!
+$!!!! Tell The User We Are Partly Rebuilding The [.APPS] Directory.
+$!!!!
+$!!! WRITE SYS$OUTPUT "Rebuilding The '[.APPS]MD4.C' File."
+$!!!!
+$!!! DELETE SYS$DISK:[.APPS]MD4.C;*
+$!!!!
+$!!!! Copy MD4.C from [.CRYPTO.MD4] into [.APPS]
+$!!!!
+$!!! COPY SYS$DISK:[.CRYPTO.MD4]MD4.C SYS$DISK:[.APPS]
+$!
+$! Ensure that the [.include.openssl] directory contains a full set of
+$! real header files.  The distribution kit may have left real or fake
+$! symlinks there.  Rather than think about what's there, simply delete
+$! the destination files (fake or real symlinks) before copying the real
+$! header files in.  (Copying a real header file onto a real symlink
+$! merely duplicates the real header file at its source.)
+$!
+$! Tell The User We Are Rebuilding The [.include.openssl] Directory.
+$!
+$ WRITE SYS$OUTPUT "Rebuilding The '[.include.openssl]' Directory."
+$!
+$! First, make sure the directory exists.  If it did exist, delete all
+$! the existing header files (or fake or real symlinks).
+$!
+$ if f$parse( "sys$disk:[.include.openssl]") .eqs. ""
+$ then
+$   create /directory sys$disk:[.include.openssl]
+$ else
+$   delete sys$disk:[.include.openssl]*.h;*
+$ endif
+$!
+$! Copy All The ".H" Files From The Main Directory.
+$!
+$ EXHEADER := e_os2.h
+$ copy 'exheader' sys$disk:[.include.openssl]
+$!
+$! Copy All The ".H" Files From The [.CRYPTO] Directory Tree.
+$!
+$ SDIRS := , -
+   'ARCHD', -
+   OBJECTS, -
+   MD2, MD4, MD5, SHA, MDC2, HMAC, RIPEMD, WHRLPOOL, -
+   DES, AES, RC2, RC4, RC5, IDEA, BF, CAST, CAMELLIA, SEED, MODES, -
+   BN, EC, RSA, DSA, ECDSA, DH, ECDH, DSO, ENGINE, -
+   BUFFER, BIO, STACK, LHASH, RAND, ERR, -
+   EVP, ASN1, PEM, X509, X509V3, CONF, TXT_DB, PKCS7, PKCS12, -
+   COMP, OCSP, UI, KRB5, -
+   STORE, CMS, PQUEUE, TS, JPAKE
+$!
+$ EXHEADER_ := crypto.h, opensslv.h, ebcdic.h, symhacks.h, ossl_typ.h
+$ EXHEADER_'ARCHD' := opensslconf.h
+$ EXHEADER_OBJECTS := objects.h, obj_mac.h
+$ EXHEADER_MD2 := md2.h
+$ EXHEADER_MD4 := md4.h
+$ EXHEADER_MD5 := md5.h
+$ EXHEADER_SHA := sha.h
+$ EXHEADER_MDC2 := mdc2.h
+$ EXHEADER_HMAC := hmac.h
+$ EXHEADER_RIPEMD := ripemd.h
+$ EXHEADER_WHRLPOOL := whrlpool.h
+$ EXHEADER_DES := des.h, des_old.h
+$ EXHEADER_AES := aes.h
+$ EXHEADER_RC2 := rc2.h
+$ EXHEADER_RC4 := rc4.h
+$ EXHEADER_RC5 := rc5.h
+$ EXHEADER_IDEA := idea.h
+$ EXHEADER_BF := blowfish.h
+$ EXHEADER_CAST := cast.h
+$ EXHEADER_CAMELLIA := camellia.h
+$ EXHEADER_SEED := seed.h
+$ EXHEADER_MODES := modes.h
+$ EXHEADER_BN := bn.h
+$ EXHEADER_EC := ec.h
+$ EXHEADER_RSA := rsa.h
+$ EXHEADER_DSA := dsa.h
+$ EXHEADER_ECDSA := ecdsa.h
+$ EXHEADER_DH := dh.h
+$ EXHEADER_ECDH := ecdh.h
+$ EXHEADER_DSO := dso.h
+$ EXHEADER_ENGINE := engine.h
+$ EXHEADER_BUFFER := buffer.h
+$ EXHEADER_BIO := bio.h
+$ EXHEADER_STACK := stack.h, safestack.h
+$ EXHEADER_LHASH := lhash.h
+$ EXHEADER_RAND := rand.h
+$ EXHEADER_ERR := err.h
+$ EXHEADER_EVP := evp.h
+$ EXHEADER_ASN1 := asn1.h, asn1_mac.h, asn1t.h
+$ EXHEADER_PEM := pem.h, pem2.h
+$ EXHEADER_X509 := x509.h, x509_vfy.h
+$ EXHEADER_X509V3 := x509v3.h
+$ EXHEADER_CONF := conf.h, conf_api.h
+$ EXHEADER_TXT_DB := txt_db.h
+$ EXHEADER_PKCS7 := pkcs7.h
+$ EXHEADER_PKCS12 := pkcs12.h
+$ EXHEADER_COMP := comp.h
+$ EXHEADER_OCSP := ocsp.h
+$ EXHEADER_UI := ui.h, ui_compat.h
+$ EXHEADER_KRB5 := krb5_asn.h
+$!!! EXHEADER_STORE := store.h, str_compat.h
+$ EXHEADER_STORE := store.h
+$ EXHEADER_CMS := cms.h
+$ EXHEADER_PQUEUE := pqueue.h
+$ EXHEADER_TS := ts.h
+$ EXHEADER_JPAKE := jpake.h
+$!
+$ i = 0
+$ loop_sdirs:
+$   sdir = f$edit( f$element( i, ",", sdirs), "trim")
+$   i = i + 1
+$   if (sdir .eqs. ",") then goto loop_sdirs_end
+$   hdr_list = exheader_'sdir'
+$   if (sdir .nes. "") then sdir = "."+ sdir
+$   copy [.crypto'sdir']'hdr_list' sys$disk:[.include.openssl]
+$ goto loop_sdirs
+$ loop_sdirs_end:
+$!
+$! Copy All The ".H" Files From The [.SSL] Directory.
+$!
+$! (keep these in the same order as ssl/Makefile)
+$ EXHEADER := ssl.h, ssl2.h, ssl3.h, ssl23.h, tls1.h, dtls1.h, kssl.h
+$ copy sys$disk:[.ssl]'exheader' sys$disk:[.include.openssl]
+$!
+$! Purge the [.include.openssl] header files.
+$!
+$ purge sys$disk:[.include.openssl]*.h
+$!
+$! That's All, Time To RETURN.
+$!
+$ RETURN
+$!
+$! Build The "[.xxx.EXE.CRYPTO]SSL_LIBCRYPTO''LIB32'.OLB" Library.
+$!
+$ CRYPTO:
+$!
+$! Tell The User What We Are Doing.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT -
+   "Building The [.",ARCHD,".EXE.CRYPTO]SSL_LIBCRYPTO''LIB32'.OLB Library."
+$!
+$! Go To The [.CRYPTO] Directory.
+$!
+$ SET DEFAULT SYS$DISK:[.CRYPTO]
+$!
+$! Build The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library.
+$!  
+$ @CRYPTO-LIB LIBRARY 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" -
+   "''ISSEVEN'" "''BUILDPART'" "''POINTER_SIZE'" "''ZLIB'"
+$!
+$! Build The [.xxx.EXE.CRYPTO]*.EXE Test Applications.
+$!  
+$ @CRYPTO-LIB APPS 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" -
+   "''ISSEVEN'" "''BUILDPART'" "''POINTER_SIZE'" "''ZLIB'"
+$!
+$! Go Back To The Main Directory.
+$!
+$ SET DEFAULT [-]
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$!
+$! Build The "[.xxx.EXE.SSL]SSL_LIBSSL''LIB32'.OLB" Library.
+$!
+$ SSL:
+$!
+$! Tell The User What We Are Doing.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT -
+   "Building The [.",ARCHD,".EXE.SSL]SSL_LIBSSL''LIB32'.OLB Library."
+$!
+$! Go To The [.SSL] Directory.
+$!
+$ SET DEFAULT SYS$DISK:[.SSL]
+$!
+$! Build The [.xxx.EXE.SSL]LIBSSL.OLB Library.
+$!
+$ @SSL-LIB LIBRARY 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" -
+   "''ISSEVEN'" "''POINTER_SIZE'" "''ZLIB'"
+$!
+$! Go Back To The Main Directory.
+$!
+$ SET DEFAULT [-]
+$!
+$! Time To Return.
+$!
+$ RETURN
+$!
+$! Build The "[.xxx.EXE.SSL]SSL_TASK.EXE" Program.
+$!
+$ SSL_TASK:
+$!
+$! Tell The User What We Are Doing.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT -
+   "Building DECNet Based SSL Engine, [.",ARCHD,".EXE.SSL]SSL_TASK.EXE"
+$!
+$! Go To The [.SSL] Directory.
+$!
+$ SET DEFAULT SYS$DISK:[.SSL]
+$!
+$! Build The [.xxx.EXE.SSL]SSL_TASK.EXE
+$!
+$ @SSL-LIB SSL_TASK 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" -
+   "''ISSEVEN'" "''POINTER_SIZE'" "''ZLIB'"
+$!
+$! Go Back To The Main Directory.
+$!
+$ SET DEFAULT [-]
+$!
+$! That's All, Time To RETURN.
+$!
+$ RETURN
+$!
+$! Build The OpenSSL Test Programs.
+$!
+$ TEST:
+$!
+$! Tell The User What We Are Doing.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Building The OpenSSL [.",ARCHD,".EXE.TEST] Test Utilities."
+$!
+$! Go To The [.TEST] Directory.
+$!
+$ SET DEFAULT SYS$DISK:[.TEST]
+$!
+$! Build The Test Programs.
+$!
+$ @MAKETESTS 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" -
+   "''POINTER_SIZE'" "''ZLIB'"
+$!
+$! Go Back To The Main Directory.
+$!
+$ SET DEFAULT [-]
+$!
+$! That's All, Time To RETURN.
+$!
+$ RETURN
+$!
+$! Build The OpenSSL Application Programs.
+$!
+$ APPS:
+$!
+$! Tell The User What We Are Doing.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Building OpenSSL [.",ARCHD,".EXE.APPS] Applications."
+$!
+$! Go To The [.APPS] Directory.
+$!
+$ SET DEFAULT SYS$DISK:[.APPS]
+$!
+$! Build The Application Programs.
+$!
+$ @MAKEAPPS 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" -
+   "" "''POINTER_SIZE'" "''ZLIB'"
+$!
+$! Go Back To The Main Directory.
+$!
+$ SET DEFAULT [-]
+$!
+$! That's All, Time To RETURN.
+$!
+$ RETURN
+$!
+$! Build The OpenSSL Application Programs.
+$!
+$ ENGINES:
+$!
+$! Tell The User What We Are Doing.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Building OpenSSL [.",ARCHD,".EXE.ENGINES] Engines."
+$!
+$! Go To The [.ENGINES] Directory.
+$!
+$ SET DEFAULT SYS$DISK:[.ENGINES]
+$!
+$! Build The Application Programs.
+$!
+$ @MAKEENGINES ENGINES 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" -
+   "''ISSEVEN'" "''BUILDPART'" "''POINTER_SIZE'" "''ZLIB'"
+$!
+$! Go Back To The Main Directory.
+$!
+$ SET DEFAULT [-]
+$!
+$! That's All, Time To RETURN.
+$!
+$ RETURN
+$!
+$! Check The User's Options.
+$!
+$ CHECK_OPTIONS:
+$!
+$! Check if there's a "part", and separate it out
+$!
+$ BUILDPART = F$ELEMENT(1,"/",P1)
+$ IF BUILDPART .EQS. "/"
+$ THEN
+$   BUILDPART = ""
+$ ELSE
+$   P1 = F$EXTRACT(0,F$LENGTH(P1) - F$LENGTH(BUILDPART) - 1, P1)
+$ ENDIF
+$!
+$! Check To See If P1 Is Blank.
+$!
+$ IF (P1.EQS."ALL")
+$ THEN
+$!
+$!   P1 Is ALL, So Build Everything.
+$!
+$    BUILDCOMMAND = "ALL"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  Else, Check To See If P1 Has A Valid Argument.
+$!
+$   IF (P1.EQS."CONFIG").OR.(P1.EQS."BUILDINF").OR.(P1.EQS."SOFTLINKS") -
+       .OR.(P1.EQS."BUILDALL") -
+       .OR.(P1.EQS."CRYPTO").OR.(P1.EQS."SSL") -
+       .OR.(P1.EQS."SSL_TASK").OR.(P1.EQS."TEST").OR.(P1.EQS."APPS") -
+       .OR.(P1.EQS."ENGINES")
+$   THEN
+$!
+$!    A Valid Argument.
+$!
+$     BUILDCOMMAND = P1
+$!
+$!  Else...
+$!
+$   ELSE
+$!
+$!    Tell The User We Don't Know What They Want.
+$!
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "USAGE:   @MAKEVMS.COM [Target] [Pointer size] [Debug option] <Compiler>"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "Example: @MAKEVMS.COM ALL """" NODEBUG "
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Target ",P1," Is Invalid.  The Valid Target Options Are:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "    ALL      :  Just Build Everything."
+$     WRITE SYS$OUTPUT "    CONFIG   :  Just build the [.CRYPTO._xxx]OPENSSLCONF.H file."
+$     WRITE SYS$OUTPUT "    BUILDINF :  Just build the [.CRYPTO._xxx]BUILDINF.H file."
+$     WRITE SYS$OUTPUT "    SOFTLINKS:  Just Fix The Unix soft links."
+$     WRITE SYS$OUTPUT "    BUILDALL :  Same as ALL, except CONFIG, BUILDINF and SOFTILNKS aren't done."
+$     WRITE SYS$OUTPUT "    CRYPTO   :  To Build Just The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library."
+$     WRITE SYS$OUTPUT "    CRYPTO/x :  To Build Just The x Part Of The"
+$     WRITE SYS$OUTPUT "                [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library."
+$     WRITE SYS$OUTPUT "    SSL      :  To Build Just The [.xxx.EXE.SSL]LIBSSL.OLB Library."
+$     WRITE SYS$OUTPUT "    SSL_TASK :  To Build Just The [.xxx.EXE.SSL]SSL_TASK.EXE Program."
+$     WRITE SYS$OUTPUT "    TEST     :  To Build Just The OpenSSL Test Programs."
+$     WRITE SYS$OUTPUT "    APPS     :  To Build Just The OpenSSL Application Programs."
+$     WRITE SYS$OUTPUT "    ENGINES  :  To Build Just The ENGINES"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT " Where 'xxx' Stands For:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "    ALPHA[64]:  Alpha Architecture."
+$     WRITE SYS$OUTPUT "    IA64[64] :  IA64 Architecture."
+$     WRITE SYS$OUTPUT "    VAX      :  VAX Architecture."
+$     WRITE SYS$OUTPUT ""
+$!
+$!    Time To EXIT.
+$!
+$     GOTO TIDY
+$!
+$!  End The Valid Argument Check.
+$!
+$   ENDIF
+$!
+$! End The P1 Check.
+$!
+$ ENDIF
+$!
+$! Check P2 (POINTER_SIZE).
+$!
+$ IF (P2 .NES. "") .AND. (ARCH .NES. "VAX")
+$ THEN
+$!
+$   IF (P2 .EQS. "32")
+$   THEN
+$     POINTER_SIZE = "32"
+$   ELSE
+$     POINTER_SIZE = F$EDIT( P2, "COLLAPSE, UPCASE")
+$     IF ((POINTER_SIZE .EQS. "64") .OR. -
+       (POINTER_SIZE .EQS. "64=") .OR. -
+       (POINTER_SIZE .EQS. "64=ARGV"))
+$     THEN
+$       ARCHD = ARCH+ "_64"
+$       LIB32 = ""
+$     ELSE
+$!
+$!      Tell The User Entered An Invalid Option.
+$!
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT "The Option ", P2, -
+         " Is Invalid.  The Valid Options Are:"
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT -
+         "    """"       :  Compile with default (short) pointers."
+$       WRITE SYS$OUTPUT -
+         "    32       :  Compile with 32-bit (short) pointers."
+$       WRITE SYS$OUTPUT -
+         "    64       :  Compile with 64-bit (long) pointers (auto ARGV)."
+$       WRITE SYS$OUTPUT -
+         "    64=      :  Compile with 64-bit (long) pointers (no ARGV)."
+$       WRITE SYS$OUTPUT -
+         "    64=ARGV  :  Compile with 64-bit (long) pointers (ARGV)."
+$       WRITE SYS$OUTPUT ""
+$! 
+$!      Time To EXIT.
+$!
+$       GOTO TIDY
+$!
+$     ENDIF
+$!
+$   ENDIF
+$!
+$! End The P2 (POINTER_SIZE) Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P3 Is Blank.
+$!
+$ IF (P3.EQS."NODEBUG")
+$ THEN
+$!
+$!   P3 Is NODEBUG, So Compile Without Debugger Information.
+$!
+$    DEBUGGER = "NODEBUG"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  Check To See If We Are To Compile With Debugger Information.
+$!
+$   IF (P3.EQS."DEBUG")
+$   THEN
+$!
+$!    Compile With Debugger Information.
+$!
+$     DEBUGGER = "DEBUG"
+$!
+$!  Else...
+$!
+$   ELSE
+$!
+$!    Tell The User Entered An Invalid Option.
+$!
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ",P3," Is Invalid.  The Valid Options Are:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "    DEBUG    :  Compile With The Debugger Information."
+$     WRITE SYS$OUTPUT "    NODEBUG  :  Compile Without The Debugger Information."
+$     WRITE SYS$OUTPUT ""
+$!
+$!    Time To EXIT.
+$!
+$     GOTO TIDY
+$!
+$!  End The Valid Argument Check.
+$!
+$   ENDIF
+$!
+$! End The P3 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P4 Is Blank.
+$!
+$ IF (P4.EQS."")
+$ THEN
+$!
+$!  O.K., The User Didn't Specify A Compiler, Let's Try To
+$!  Find Out Which One To Use.
+$!
+$!  Check To See If We Have GNU C.
+$!
+$   IF (F$TRNLNM("GNU_CC").NES."")
+$   THEN
+$!
+$!    Looks Like GNUC, Set To Use GNUC.
+$!
+$     COMPILER = "GNUC"
+$!
+$!    Tell The User We Are Using GNUC.
+$!
+$     WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$!  End The GNU C Compiler Check.
+$!
+$   ENDIF
+$!
+$!  Check To See If We Have VAXC Or DECC.
+$!
+$   IF (F$GETSYI("CPU").GE.128).OR.(F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC")
+$   THEN 
+$!
+$!    Looks Like DECC, Set To Use DECC.
+$!
+$     COMPILER = "DECC"
+$!
+$!    Tell The User We Are Using DECC.
+$!
+$     WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$!  Else...
+$!
+$   ELSE
+$!
+$!    Looks Like VAXC, Set To Use VAXC.
+$!
+$     COMPILER = "VAXC"
+$!
+$!    Tell The User We Are Using VAX C.
+$!
+$     WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$!  End The DECC & VAXC Compiler Check.
+$!
+$   ENDIF
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  Check To See If The User Entered A Valid Parameter.
+$!
+$   IF (P4.EQS."VAXC").OR.(P4.EQS."DECC").OR.(P4.EQS."GNUC")!.OR.(P4.EQS."LINK")
+$   THEN
+$!
+$!    Check To See If The User Wanted To Just LINK.
+$!
+$     IF (P4.EQS."LINK")
+$     THEN
+$!
+$!      Looks Like LINK-only
+$!
+$       COMPILER = "LINK"
+$!
+$!      Tell The User We Are Only Linking.
+$!
+$       WRITE SYS$OUTPUT "LINK Only.  This actually NOT YET SUPPORTED!"
+$!
+$!    End LINK Check.
+$!
+$     ENDIF
+$!
+$!    Check To See If The User Wanted DECC.
+$!
+$     IF (P4.EQS."DECC")
+$     THEN
+$!
+$!      Looks Like DECC, Set To Use DECC.
+$!
+$       COMPILER = "DECC"
+$!
+$!      Tell The User We Are Using DECC.
+$!
+$       WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$!    End DECC Check.
+$!
+$     ENDIF
+$!
+$!    Check To See If We Are To Use VAXC.
+$!
+$     IF (P4.EQS."VAXC")
+$     THEN
+$!
+$!      Looks Like VAXC, Set To Use VAXC.
+$!
+$       COMPILER = "VAXC"
+$!
+$!      Tell The User We Are Using VAX C.
+$!
+$       WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$!    End VAXC Check
+$!
+$     ENDIF
+$!
+$!    Check To See If We Are To Use GNU C.
+$!
+$     IF (P4.EQS."GNUC")
+$     THEN
+$!
+$!      Looks Like GNUC, Set To Use GNUC.
+$!
+$       COMPILER = "GNUC"
+$!
+$!      Tell The User We Are Using GNUC.
+$!
+$       WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$!    End The GNU C Check.
+$!
+$     ENDIF
+$!
+$!  Else The User Entered An Invalid Argument.
+$!
+$   ELSE
+$!
+$!    Tell The User We Don't Know What They Want.
+$!
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ",P4," Is Invalid.  The Valid Options Are:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "    VAXC  :  To Compile With VAX C."
+$     WRITE SYS$OUTPUT "    DECC  :  To Compile With DEC C."
+$     WRITE SYS$OUTPUT "    GNUC  :  To Compile With GNU C."
+$     WRITE SYS$OUTPUT ""
+$!
+$!    Time To EXIT.
+$!
+$     GOTO TIDY
+$!
+$!  End The Valid Argument Check.
+$!
+$   ENDIF
+$!
+$! End The P4 Check.
+$!
+$ ENDIF
+$!
+$! Time to check the contents of P5, and to make sure we get the correct
+$! library.
+$!
+$ IF P5.EQS."SOCKETSHR" .OR. P5.EQS."MULTINET" .OR. P5.EQS."UCX" -
+     .OR. P5.EQS."TCPIP" .OR. P5.EQS."NONE"
+$ THEN
+$!
+$!  Check to see if SOCKETSHR was chosen
+$!
+$   IF P5.EQS."SOCKETSHR"
+$   THEN
+$!
+$!    Set the library to use SOCKETSHR
+$!
+$     TCPIP_LIB = "SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
+$!
+$!    Tell the user
+$!
+$     WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
+$!
+$!    Done with SOCKETSHR
+$!
+$   ENDIF
+$!
+$!  Check to see if MULTINET was chosen
+$!
+$   IF P5.EQS."MULTINET"
+$   THEN
+$!
+$!    Set the library to use UCX emulation.
+$!
+$     P5 = "UCX"
+$!
+$!    Tell the user
+$!
+$     WRITE SYS$OUTPUT "Using MultiNet via UCX emulation for TCP/IP"
+$!
+$!    Done with MULTINET
+$!
+$   ENDIF
+$!
+$!  Check to see if UCX was chosen
+$!
+$   IF P5.EQS."UCX"
+$   THEN
+$!
+$!    Set the library to use UCX.
+$!
+$     TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
+$!
+$!    Tell the user
+$!
+$     WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
+$!
+$!    Done with UCX
+$!
+$   ENDIF
+$!
+$!  Check to see if TCPIP was chosen
+$!
+$   IF P5.EQS."TCPIP"
+$   THEN
+$!
+$!    Set the library to use TCPIP (post UCX).
+$!
+$     TCPIP_LIB = "SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
+$!
+$!    Tell the user
+$!
+$     WRITE SYS$OUTPUT "Using TCPIP (post UCX) for TCP/IP"
+$!
+$!    Done with TCPIP
+$!
+$   ENDIF
+$!
+$!  Check to see if NONE was chosen
+$!
+$   IF P5.EQS."NONE"
+$   THEN
+$!
+$!    Do not use a TCPIP library.
+$!
+$     TCPIP_LIB = ""
+$!
+$!    Tell the user
+$!
+$     WRITE SYS$OUTPUT "A specific TCPIP library will not be used."
+$!
+$!    Done with NONE.
+$!
+$   ENDIF
+$!
+$!  Set the TCPIP_TYPE symbol
+$!
+$   TCPIP_TYPE = P5
+$!
+$!  Print info
+$!
+$   WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB
+$!
+$!  Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$   IF P5 .NES. ""
+$   THEN
+$!
+$!    Tell The User We Don't Know What They Want.
+$!
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ",P5," Is Invalid.  The Valid Options Are:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "    SOCKETSHR  :  To link with SOCKETSHR TCP/IP library."
+$     WRITE SYS$OUTPUT "    UCX        :  To link with UCX TCP/IP library."
+$     WRITE SYS$OUTPUT "    TCPIP      :  To link with TCPIP TCP/IP (post UCX) library."
+$     WRITE SYS$OUTPUT "    NONE       :  To not link with a specific TCP/IP library."
+$     WRITE SYS$OUTPUT ""
+$!
+$!    Time To EXIT.
+$!
+$     GOTO TIDY
+$   ELSE
+$!
+$! If TCPIP is not defined, then hardcode it to make
+$! it clear that no TCPIP is desired.
+$!
+$     IF P5 .EQS. ""
+$     THEN
+$       TCPIP_LIB = ""
+$       TCPIP_TYPE = "NONE"
+$     ELSE
+$!
+$!    Set the TCPIP_TYPE symbol
+$!
+$       TCPIP_TYPE = P5
+$     ENDIF
+$   ENDIF
+$!
+$!  Done with TCP/IP libraries
+$!
+$ ENDIF
+$!
+$! Special Threads For OpenVMS v7.1 Or Later
+$!
+$! Written By:  Richard Levitte
+$!              richard@levitte.org
+$!
+$!
+$! Check To See If We Have A Option For P6.
+$!
+$ IF (P6.EQS."")
+$ THEN
+$!
+$!  Get The Version Of VMS We Are Using.
+$!
+$   ISSEVEN :=
+$   TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,VMS_VERSION))
+$   TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
+$!
+$!  Check To See If The VMS Version Is v7.1 Or Later.
+$!
+$   IF (TMP.GE.71)
+$   THEN
+$!
+$!    We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
+$!
+$     ISSEVEN := ,PTHREAD_USE_D4
+$!
+$!  End The VMS Version Check.
+$!
+$   ENDIF
+$!
+$! End The P6 Check.
+$!
+$ ENDIF
+$!
+$!
+$! Check To See If We Have A ZLIB Option.
+$!
+$ ZLIB = P7
+$ IF (ZLIB .NES. "")
+$ THEN
+$!
+$!  Check for expected ZLIB files.
+$!
+$   err = 0
+$   file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY")
+$   if (f$search( file1) .eqs. "")
+$   then
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
+$     WRITE SYS$OUTPUT "    Can't find header: ''file1'"
+$     err = 1
+$   endif
+$!
+$   file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY")
+$   if (f$search( file2) .eqs. "")
+$   then
+$     if (err .eq. 0)
+$     then
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
+$     endif
+$     WRITE SYS$OUTPUT "    Can't find library: ''file2'"
+$     WRITE SYS$OUTPUT ""
+$     err = err+ 2
+$   endif
+$   if (err .eq. 1)
+$   then
+$     WRITE SYS$OUTPUT ""
+$   endif
+$!
+$   if (err .ne. 0)
+$   then
+$     GOTO TIDY
+$   endif
+$!
+$!  Print info
+$!
+$   WRITE SYS$OUTPUT "ZLIB library spec: ", file2
+$!
+$! End The ZLIB Check.
+$!
+$ ENDIF
+$!
+$!  Time To RETURN...
+$!
+$ RETURN
+$!
+$ TIDY:
+$!
+$! Close any open files.
+$!
+$ if (f$trnlnm( "h_file", "LNM$PROCESS", 0, "SUPERVISOR") .nes. "") then -
+   close h_file
+$!
+$! Restore the original default device:[directory].
+$!
+$ SET DEFAULT 'DEF_ORIG'
+$!
+$ EXIT
+$!
diff --git a/openssl/ms/.rnd b/openssl/ms/.rnd
new file mode 100644
index 0000000..0566b46
--- /dev/null
+++ b/openssl/ms/.rnd
Binary files differ
diff --git a/openssl/ms/32all.bat b/openssl/ms/32all.bat
new file mode 100755
index 0000000..aaab9b0
--- /dev/null
+++ b/openssl/ms/32all.bat
@@ -0,0 +1,20 @@
+set OPTS=no-asm
+
+perl Configure VC-WIN32
+perl util\mkfiles.pl >MINFO
+perl util\mk1mf.pl %OPTS% debug VC-WIN32 >d32.mak
+perl util\mk1mf.pl %OPTS% VC-WIN32 >32.mak
+perl util\mk1mf.pl %OPTS% debug dll VC-WIN32 >d32dll.mak
+perl util\mk1mf.pl %OPTS% dll VC-WIN32 >32dll.mak
+perl util\mkdef.pl 32 libeay > ms\libeay32.def
+perl util\mkdef.pl 32 ssleay > ms\ssleay32.def
+
+nmake -f d32.mak
+@if errorlevel 1 goto end
+nmake -f 32.mak
+@if errorlevel 1 goto end
+nmake -f d32dll.mak
+@if errorlevel 1 goto end
+nmake -f 32dll.mak
+
+:end
diff --git a/openssl/ms/README b/openssl/ms/README
new file mode 100644
index 0000000..07f1925
--- /dev/null
+++ b/openssl/ms/README
@@ -0,0 +1,13 @@
+Run these makefiles from the top level as in
+nmake -f ms\makefilename
+to build with visual C++ 4.[01].
+
+The results will be in the out directory.
+
+These makefiles and def files were generated by typing
+
+perl util\mk1mf.pl VC-NT >ms/nt.mak
+perl util\mk1mf.pl VC-NT dll >ms/ntdll.mak
+
+perl util\mkdef.pl 32 crypto > ms/crypto32.def
+perl util\mkdef.pl 32 ssl > ms/ssl32.def
diff --git a/openssl/ms/applink.c b/openssl/ms/applink.c
new file mode 100644
index 0000000..54a0a64
--- /dev/null
+++ b/openssl/ms/applink.c
@@ -0,0 +1,94 @@
+#define APPLINK_STDIN	1
+#define APPLINK_STDOUT	2
+#define APPLINK_STDERR	3
+#define APPLINK_FPRINTF	4
+#define APPLINK_FGETS	5
+#define APPLINK_FREAD	6
+#define APPLINK_FWRITE	7
+#define APPLINK_FSETMOD	8
+#define APPLINK_FEOF	9
+#define APPLINK_FCLOSE 	10	/* should not be used */
+
+#define APPLINK_FOPEN	11	/* solely for completeness */
+#define APPLINK_FSEEK	12
+#define APPLINK_FTELL	13
+#define APPLINK_FFLUSH	14
+#define APPLINK_FERROR	15
+#define APPLINK_CLEARERR 16
+#define APPLINK_FILENO	17	/* to be used with below */
+
+#define APPLINK_OPEN	18	/* formally can't be used, as flags can vary */
+#define APPLINK_READ	19
+#define APPLINK_WRITE	20
+#define APPLINK_LSEEK	21
+#define APPLINK_CLOSE	22
+#define APPLINK_MAX	22	/* always same as last macro */
+
+#ifndef APPMACROS_ONLY
+#include <stdio.h>
+#include <io.h>
+#include <fcntl.h>
+
+static void *app_stdin(void)		{ return stdin;  }
+static void *app_stdout(void)		{ return stdout; }
+static void *app_stderr(void)		{ return stderr; }
+static int   app_feof(FILE *fp)		{ return feof(fp); }
+static int   app_ferror(FILE *fp)	{ return ferror(fp); }
+static void  app_clearerr(FILE *fp)	{ clearerr(fp); }
+static int   app_fileno(FILE *fp)	{ return _fileno(fp); }
+static int   app_fsetmod(FILE *fp,char mod)
+{ return _setmode (_fileno(fp),mod=='b'?_O_BINARY:_O_TEXT); }
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+__declspec(dllexport)
+void **
+#if defined(__BORLANDC__)
+__stdcall	/* __stdcall appears to be the only way to get the name
+		 * decoration right with Borland C. Otherwise it works
+		 * purely incidentally, as we pass no parameters. */
+#else
+__cdecl
+#endif
+OPENSSL_Applink(void)
+{ static int once=1;
+  static void *OPENSSL_ApplinkTable[APPLINK_MAX+1]={(void *)APPLINK_MAX};
+
+    if (once)
+    {	OPENSSL_ApplinkTable[APPLINK_STDIN]	= app_stdin;
+	OPENSSL_ApplinkTable[APPLINK_STDOUT]	= app_stdout;
+	OPENSSL_ApplinkTable[APPLINK_STDERR]	= app_stderr;
+	OPENSSL_ApplinkTable[APPLINK_FPRINTF]	= fprintf;
+	OPENSSL_ApplinkTable[APPLINK_FGETS]	= fgets;
+	OPENSSL_ApplinkTable[APPLINK_FREAD]	= fread;
+	OPENSSL_ApplinkTable[APPLINK_FWRITE]	= fwrite;
+	OPENSSL_ApplinkTable[APPLINK_FSETMOD]	= app_fsetmod;
+	OPENSSL_ApplinkTable[APPLINK_FEOF]	= app_feof;
+	OPENSSL_ApplinkTable[APPLINK_FCLOSE]	= fclose;
+
+	OPENSSL_ApplinkTable[APPLINK_FOPEN]	= fopen;
+	OPENSSL_ApplinkTable[APPLINK_FSEEK]	= fseek;
+	OPENSSL_ApplinkTable[APPLINK_FTELL]	= ftell;
+	OPENSSL_ApplinkTable[APPLINK_FFLUSH]	= fflush;
+	OPENSSL_ApplinkTable[APPLINK_FERROR]	= app_ferror;
+	OPENSSL_ApplinkTable[APPLINK_CLEARERR]	= app_clearerr;
+	OPENSSL_ApplinkTable[APPLINK_FILENO]	= app_fileno;
+
+	OPENSSL_ApplinkTable[APPLINK_OPEN]	= _open;
+	OPENSSL_ApplinkTable[APPLINK_READ]	= _read;
+	OPENSSL_ApplinkTable[APPLINK_WRITE]	= _write;
+	OPENSSL_ApplinkTable[APPLINK_LSEEK]	= _lseek;
+	OPENSSL_ApplinkTable[APPLINK_CLOSE]	= _close;
+
+	once = 0;
+    }
+
+  return OPENSSL_ApplinkTable;
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/ms/bcb4.bat b/openssl/ms/bcb4.bat
new file mode 100755
index 0000000..00fb9e8
--- /dev/null
+++ b/openssl/ms/bcb4.bat
@@ -0,0 +1,6 @@
+perl Configure BC-32
+perl util\mkfiles.pl > MINFO
+
+@rem create make file
+perl util\mk1mf.pl no-asm BC-NT > bcb.mak
+
diff --git a/openssl/ms/certCA.srl b/openssl/ms/certCA.srl
new file mode 100644
index 0000000..2cfaa3b
--- /dev/null
+++ b/openssl/ms/certCA.srl
@@ -0,0 +1 @@
+1D
diff --git a/openssl/ms/certCA.ss b/openssl/ms/certCA.ss
new file mode 100644
index 0000000..b48c657
--- /dev/null
+++ b/openssl/ms/certCA.ss
@@ -0,0 +1,10 @@
+-----BEGIN CERTIFICATE-----
+MIIBXDCCAQYCAQAwDQYJKoZIhvcNAQEEBQAwOTELMAkGA1UEBhMCQVUxFzAVBgNV
+BAoTDkRvZGd5IEJyb3RoZXJzMREwDwYDVQQDEwhEb2RneSBDQTAeFw05ODA3MjEw
+NjUwMTZaFw05ODA4MjAwNjUwMTZaMDkxCzAJBgNVBAYTAkFVMRcwFQYDVQQKEw5E
+b2RneSBCcm90aGVyczERMA8GA1UEAxMIRG9kZ3kgQ0EwXDANBgkqhkiG9w0BAQEF
+AANLADBIAkEA0DQLenM/ncK6CwSEJhOO1WfZUPUEi4pvos9fHW459jh3rRDADgi3
+fiCYxoRVSQhvB47kDZ3ViNg5yrDhy7F9ywIDAQABMA0GCSqGSIb3DQEBBAUAA0EA
+S564l3SBxJ+QcIXthGGDyP5zkxTf/1fHfelW9LNgu6lZTdy9Dlp/NecPekzRmZEM
+WiGXGkKNeuo8PsnGJHP9Qg==
+-----END CERTIFICATE-----
diff --git a/openssl/ms/certU.ss b/openssl/ms/certU.ss
new file mode 100644
index 0000000..095ea14
--- /dev/null
+++ b/openssl/ms/certU.ss
@@ -0,0 +1,10 @@
+-----BEGIN CERTIFICATE-----
+MIIBcTCCARsCARwwDQYJKoZIhvcNAQEEBQAwOTELMAkGA1UEBhMCQVUxFzAVBgNV
+BAoTDkRvZGd5IEJyb3RoZXJzMREwDwYDVQQDEwhEb2RneSBDQTAeFw05ODA3MjEw
+NjUwMjdaFw05ODA4MjAwNjUwMjdaME4xCzAJBgNVBAYTAkFVMRcwFQYDVQQKEw5E
+b2RneSBCcm90aGVyczESMBAGA1UEAxMJQnJvdGhlciAxMRIwEAYDVQQDEwlCcm90
+aGVyIDIwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA0e4qorOr/zuLB9NvRaXhJVaI
+HaGGasa7eMAjVPitWAXkN+DxXiGH1CnMgQraKiYzsEVP15xtxkevEvK5jJpOwwID
+AQABMA0GCSqGSIb3DQEBBAUAA0EAZhcPV+SWwaszFuDTYc6fUurcV9OeXUqoxSQy
+MnLZPTyWubHbbkUr9fUfdf7Cc7dFqGzag05VHkNQUS9VjMzjIQ==
+-----END CERTIFICATE-----
diff --git a/openssl/ms/cmp.pl b/openssl/ms/cmp.pl
new file mode 100644
index 0000000..95b257f
--- /dev/null
+++ b/openssl/ms/cmp.pl
@@ -0,0 +1,47 @@
+#!/usr/local/bin/perl
+
+($#ARGV == 1) || die "usage: cmp.pl <file1> <file2>\n";
+
+open(IN0,"<$ARGV[0]") || die "unable to open $ARGV[0]\n";
+open(IN1,"<$ARGV[1]") || die "unable to open $ARGV[1]\n";
+binmode IN0;
+binmode IN1;
+
+$tot=0;
+$ret=1;
+for (;;)
+	{
+	$n1=sysread(IN0,$b1,4096);
+	$n2=sysread(IN1,$b2,4096);
+
+	last if ($n1 != $n2);
+	last if ($b1 ne $b2);
+	last if ($n1 < 0);
+	if ($n1 == 0)
+		{
+		$ret=0;
+		last;
+		}
+	$tot+=$n1;
+	}
+
+close(IN0);
+close(IN1);
+if ($ret)
+	{
+	printf STDERR "$ARGV[0] and $ARGV[1] are different\n";
+	@a1=unpack("C*",$b1);
+	@a2=unpack("C*",$b2);
+	for ($i=0; $i<=$#a1; $i++)
+		{
+		if ($a1[$i] ne $a2[$i])
+			{
+			printf "%02X %02X <<\n",$a1[$i],$a2[$i];
+			last;
+			}
+		}
+	$nm=$tot+$n1;
+	$tot+=$i+1;
+	printf STDERR "diff at char $tot of $nm\n";
+	}
+exit($ret);
diff --git a/openssl/ms/do_ms.bat b/openssl/ms/do_ms.bat
new file mode 100755
index 0000000..55014d3
--- /dev/null
+++ b/openssl/ms/do_ms.bat
@@ -0,0 +1,11 @@
+
+perl util\mkfiles.pl >MINFO
+perl util\mk1mf.pl no-asm VC-WIN32 >ms\nt.mak
+perl util\mk1mf.pl dll no-asm VC-WIN32 >ms\ntdll.mak
+if x%OSVERSION% == x goto skipce
+perl util\mk1mf.pl no-asm VC-CE >ms\ce.mak
+perl util\mk1mf.pl dll no-asm VC-CE >ms\cedll.mak
+:skipce
+
+perl util\mkdef.pl 32 libeay > ms\libeay32.def
+perl util\mkdef.pl 32 ssleay > ms\ssleay32.def
diff --git a/openssl/ms/do_nasm.bat b/openssl/ms/do_nasm.bat
new file mode 100755
index 0000000..7b3f3ed
--- /dev/null
+++ b/openssl/ms/do_nasm.bat
@@ -0,0 +1,8 @@
+
+perl util\mkfiles.pl >MINFO
+perl util\mk1mf.pl nasm VC-WIN32 >ms\nt.mak
+perl util\mk1mf.pl dll nasm VC-WIN32 >ms\ntdll.mak
+perl util\mk1mf.pl nasm BC-NT >ms\bcb.mak
+
+perl util\mkdef.pl 32 libeay > ms\libeay32.def
+perl util\mkdef.pl 32 ssleay > ms\ssleay32.def
diff --git a/openssl/ms/do_nt.bat b/openssl/ms/do_nt.bat
new file mode 100755
index 0000000..e2d525e
--- /dev/null
+++ b/openssl/ms/do_nt.bat
@@ -0,0 +1,7 @@
+
+perl util\mkfiles.pl >MINFO
+perl util\mk1mf.pl no-asm VC-NT >ms\nt.mak
+perl util\mk1mf.pl dll no-asm VC-NT >ms\ntdll.mak
+
+perl util\mkdef.pl libeay NT > ms\libeay32.def
+perl util\mkdef.pl ssleay NT > ms\ssleay32.def
diff --git a/openssl/ms/do_win64a.bat b/openssl/ms/do_win64a.bat
new file mode 100755
index 0000000..495f1ea
--- /dev/null
+++ b/openssl/ms/do_win64a.bat
@@ -0,0 +1,9 @@
+
+perl util\mkfiles.pl >MINFO
+perl ms\uplink.pl win64a > ms\uptable.asm
+ml64 -c -Foms\uptable.obj ms\uptable.asm
+perl util\mk1mf.pl no-asm VC-WIN64A >ms\nt.mak
+perl util\mk1mf.pl dll no-asm VC-WIN64A >ms\ntdll.mak
+
+perl util\mkdef.pl 32 libeay > ms\libeay32.def
+perl util\mkdef.pl 32 ssleay > ms\ssleay32.def
diff --git a/openssl/ms/do_win64i.bat b/openssl/ms/do_win64i.bat
new file mode 100755
index 0000000..15ebcaa
--- /dev/null
+++ b/openssl/ms/do_win64i.bat
@@ -0,0 +1,9 @@
+
+perl util\mkfiles.pl >MINFO
+perl ms\uplink.pl win64i > ms\uptable.asm
+ias -o ms\uptable.obj ms\uptable.asm
+perl util\mk1mf.pl no-asm VC-WIN64I >ms\nt.mak
+perl util\mk1mf.pl dll no-asm VC-WIN64I >ms\ntdll.mak
+
+perl util\mkdef.pl 32 libeay > ms\libeay32.def
+perl util\mkdef.pl 32 ssleay > ms\ssleay32.def
diff --git a/openssl/ms/keyCA.ss b/openssl/ms/keyCA.ss
new file mode 100644
index 0000000..933c2cd
--- /dev/null
+++ b/openssl/ms/keyCA.ss
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOwIBAAJBANA0C3pzP53CugsEhCYTjtVn2VD1BIuKb6LPXx1uOfY4d60QwA4I
+t34gmMaEVUkIbweO5A2d1YjYOcqw4cuxfcsCAwEAAQJAOT9WOKEfyN0WEpl3TJDs
+ITmgw2XbjhLOh1HFsW3xegWlaOuhL/wGamz7n7zzL/RQF3JP/VvpGk2F8VD9JhwT
+wQIhAPmqM3fLttBoCQuwQRdIPfB7Ps3THqx6N8AJ04z3I1ejAiEA1XyDd7bLpWrw
+/oA8CmR4b/KCGfvRwAL/Qej/rQliw7kCIQCYRzSvO8ScpuflhjKdZcXJuRJcbgnG
+f6Ejc5rh3xdiawIhALMmLdzEFNjXiSzIx5mg/kBTLUJIw5dx7GqO8B9xBORhAiA5
+oTN/hgvvrkkmRsHQpNBmzAEGBzhMEEq9lD6ZWrTSRg==
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/ms/keyU.ss b/openssl/ms/keyU.ss
new file mode 100644
index 0000000..05d356e
--- /dev/null
+++ b/openssl/ms/keyU.ss
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBPAIBAAJBANHuKqKzq/87iwfTb0Wl4SVWiB2hhmrGu3jAI1T4rVgF5Dfg8V4h
+h9QpzIEK2iomM7BFT9ecbcZHrxLyuYyaTsMCAwEAAQJBAIxtM6n4ZCJscxj+D13Y
+k13Fn3Gqvd6pJ3ijlj7dxh6tRBBQ3W9qmQflyvEc81giI2XtbVYBOEJKtJ1cWWZm
+gAkCIQDpEoOuc4KCI5ti6aMJvtxlXWNHbkXCxtbeIjH4+FnH9QIhAOaU3XVeWWOK
+PnnO87KniDjHQqWLnooivDGRK+FUKeDXAiEA2MjEvFVqFVvDIsxHPkBNROcI+Z6i
+ulkx76kErBtrfqUCIHN5uBLQZmngUPuFtiwRlLoCqJDphENfs+oK7vPQx4xPAiEA
+hnY2Ulrpld83IG6bUs95Loc8Fk81hez5YwmhsFEXVtk=
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/ms/mingw32.bat b/openssl/ms/mingw32.bat
new file mode 100644
index 0000000..06b5733
--- /dev/null
+++ b/openssl/ms/mingw32.bat
@@ -0,0 +1,90 @@
+@rem OpenSSL with Mingw32+GNU as
+@rem ---------------------------
+
+perl Configure mingw %1 %2 %3 %4 %5 %6 %7 %8
+
+@echo off
+
+perl -e "exit 1 if '%1' eq 'no-asm'"
+if errorlevel 1 goto noasm
+
+echo Generating x86 for GNU assember
+
+echo Bignum
+cd crypto\bn\asm
+perl bn-586.pl gaswin > bn-win32.s
+perl co-586.pl gaswin > co-win32.s
+cd ..\..\..
+
+echo DES
+cd crypto\des\asm
+perl des-586.pl gaswin > d-win32.s
+cd ..\..\..
+
+echo crypt
+cd crypto\des\asm
+perl crypt586.pl gaswin > y-win32.s
+cd ..\..\..
+
+echo Blowfish
+cd crypto\bf\asm
+perl bf-586.pl gaswin > b-win32.s
+cd ..\..\..
+
+echo CAST5
+cd crypto\cast\asm
+perl cast-586.pl gaswin > c-win32.s
+cd ..\..\..
+
+echo RC4
+cd crypto\rc4\asm
+perl rc4-586.pl gaswin > r4-win32.s
+cd ..\..\..
+
+echo MD5
+cd crypto\md5\asm
+perl md5-586.pl gaswin > m5-win32.s
+cd ..\..\..
+
+echo SHA1
+cd crypto\sha\asm
+perl sha1-586.pl gaswin > s1-win32.s
+cd ..\..\..
+
+echo RIPEMD160
+cd crypto\ripemd\asm
+perl rmd-586.pl gaswin > rm-win32.s
+cd ..\..\..
+
+echo RC5\32
+cd crypto\rc5\asm
+perl rc5-586.pl gaswin > r5-win32.s
+cd ..\..\..
+
+:noasm
+
+echo Generating makefile
+perl util\mkfiles.pl >MINFO
+perl util\mk1mf.pl gaswin Mingw32 >ms\mingw32a.mak
+echo Generating DLL definition files
+perl util\mkdef.pl 32 libeay >ms\libeay32.def
+if errorlevel 1 goto end
+perl util\mkdef.pl 32 ssleay >ms\ssleay32.def
+if errorlevel 1 goto end
+
+rem copy ms\tlhelp32.h outinc
+
+echo Building the libraries
+mingw32-make -f ms/mingw32a.mak
+if errorlevel 1 goto end
+
+echo Generating the DLLs and input libraries
+dllwrap --dllname libeay32.dll --output-lib out/libeay32.a --def ms/libeay32.def out/libcrypto.a -lws2_32 -lgdi32
+if errorlevel 1 goto end
+dllwrap --dllname libssl32.dll --output-lib out/libssl32.a --def ms/ssleay32.def out/libssl.a out/libeay32.a
+if errorlevel 1 goto end
+
+echo Done compiling OpenSSL
+
+:end
+
diff --git a/openssl/ms/mw.bat b/openssl/ms/mw.bat
new file mode 100644
index 0000000..35e00a4
--- /dev/null
+++ b/openssl/ms/mw.bat
@@ -0,0 +1,26 @@
+@rem OpenSSL with Mingw32
+@rem --------------------
+
+@rem Makefile
+perl util\mkfiles.pl >MINFO
+perl util\mk1mf.pl Mingw32 >ms\mingw32.mak
+@rem DLL definition files
+perl util\mkdef.pl 32 libeay >ms\libeay32.def
+if errorlevel 1 goto end
+perl util\mkdef.pl 32 ssleay >ms\ssleay32.def
+if errorlevel 1 goto end
+
+@rem Build the libraries
+make -f ms/mingw32.mak
+if errorlevel 1 goto end
+
+@rem Generate the DLLs and input libraries
+dllwrap --dllname libeay32.dll --output-lib out/libeay32.a --def ms/libeay32.def out/libcrypto.a -lws2_32 -lgdi32
+if errorlevel 1 goto end
+dllwrap --dllname libssl32.dll --output-lib out/libssl32.a --def ms/ssleay32.def out/libssl.a out/libeay32.a
+if errorlevel 1 goto end
+
+echo Done compiling OpenSSL
+
+:end
+
diff --git a/openssl/ms/req2CA.ss b/openssl/ms/req2CA.ss
new file mode 100644
index 0000000..d061fb2
--- /dev/null
+++ b/openssl/ms/req2CA.ss
@@ -0,0 +1,29 @@
+Certificate Request:
+    Data:
+        Version: 0 (0x0)
+        Subject: C=AU, O=Dodgy Brothers, CN=Dodgy CA
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (512 bit)
+                Modulus (512 bit):
+                    00:d0:34:0b:7a:73:3f:9d:c2:ba:0b:04:84:26:13:
+                    8e:d5:67:d9:50:f5:04:8b:8a:6f:a2:cf:5f:1d:6e:
+                    39:f6:38:77:ad:10:c0:0e:08:b7:7e:20:98:c6:84:
+                    55:49:08:6f:07:8e:e4:0d:9d:d5:88:d8:39:ca:b0:
+                    e1:cb:b1:7d:cb
+                Exponent: 65537 (0x10001)
+        Attributes:
+            a0:00
+    Signature Algorithm: md5WithRSAEncryption
+        8d:15:e6:8e:49:0f:07:fb:e0:72:ad:f0:04:9a:c8:5d:e7:1b:
+        ed:99:c9:c3:3c:f5:8e:4d:a1:5e:e1:40:75:2c:24:f0:c6:dd:
+        10:87:35:26:1d:cc:79:3f:a2:c6:a0:04:c8:52:78:ed:26:32:
+        d3:1b:a7:cd:5e:8c:55:92:dd:88
+-----BEGIN CERTIFICATE REQUEST-----
+MIHzMIGeAgEAMDkxCzAJBgNVBAYTAkFVMRcwFQYDVQQKEw5Eb2RneSBCcm90aGVy
+czERMA8GA1UEAxMIRG9kZ3kgQ0EwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA0DQL
+enM/ncK6CwSEJhOO1WfZUPUEi4pvos9fHW459jh3rRDADgi3fiCYxoRVSQhvB47k
+DZ3ViNg5yrDhy7F9ywIDAQABoAAwDQYJKoZIhvcNAQEEBQADQQCNFeaOSQ8H++By
+rfAEmshd5xvtmcnDPPWOTaFe4UB1LCTwxt0QhzUmHcx5P6LGoATIUnjtJjLTG6fN
+XoxVkt2I
+-----END CERTIFICATE REQUEST-----
diff --git a/openssl/ms/reqCA.ss b/openssl/ms/reqCA.ss
new file mode 100644
index 0000000..1f7138c
--- /dev/null
+++ b/openssl/ms/reqCA.ss
@@ -0,0 +1,8 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIHzMIGeAgEAMDkxCzAJBgNVBAYTAkFVMRcwFQYDVQQKEw5Eb2RneSBCcm90aGVy
+czERMA8GA1UEAxMIRG9kZ3kgQ0EwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA0DQL
+enM/ncK6CwSEJhOO1WfZUPUEi4pvos9fHW459jh3rRDADgi3fiCYxoRVSQhvB47k
+DZ3ViNg5yrDhy7F9ywIDAQABoAAwDQYJKoZIhvcNAQEFBQADQQA5DZSZgDXs8flG
+GZf4SGr8QpqkxSu9bZOYp/ySuz1khj7aupBrvZBmqZcZx4ZjAUN7UQpMWu2gyfKa
+mAiiLPFN
+-----END CERTIFICATE REQUEST-----
diff --git a/openssl/ms/reqU.ss b/openssl/ms/reqU.ss
new file mode 100644
index 0000000..91cce59
--- /dev/null
+++ b/openssl/ms/reqU.ss
@@ -0,0 +1,8 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBCDCBswIBADBOMQswCQYDVQQGEwJBVTEXMBUGA1UEChMORG9kZ3kgQnJvdGhl
+cnMxEjAQBgNVBAMTCUJyb3RoZXIgMTESMBAGA1UEAxMJQnJvdGhlciAyMFwwDQYJ
+KoZIhvcNAQEBBQADSwAwSAJBANHuKqKzq/87iwfTb0Wl4SVWiB2hhmrGu3jAI1T4
+rVgF5Dfg8V4hh9QpzIEK2iomM7BFT9ecbcZHrxLyuYyaTsMCAwEAAaAAMA0GCSqG
+SIb3DQEBAgUAA0EAhB0p6LbiVq+XshLo5sBQN0rsROC1OgWrdS6ZUmMaigOKK069
+r1o+dGwbM5VCYGTZf0PW9OtGuArGct0laL5h4w==
+-----END CERTIFICATE REQUEST-----
diff --git a/openssl/ms/speed32.bat b/openssl/ms/speed32.bat
new file mode 100755
index 0000000..95f7ce9
--- /dev/null
+++ b/openssl/ms/speed32.bat
@@ -0,0 +1,37 @@
+set makefile=ms\nt.mak
+
+perl Configure b
+del tmp\*.obj
+nmake -f %makefile%
+nmake -f %makefile%
+nmake -f %makefile%
+out\ssleay version -v -b -f >speed.1
+out\ssleay speed >speed.1l
+
+perl Configure bl-4c-2c
+del tmp\rc4*.obj tmp\bn*.obj tmp\md2_dgst.obj
+nmake -f %makefile%
+nmake -f %makefile%
+nmake -f %makefile%
+out\ssleay speed rc4 rsa md2 >speed.2l
+
+perl Configure bl-4c-ri
+del tmp\rc4*.obj
+nmake -f %makefile%
+nmake -f %makefile%
+nmake -f %makefile%
+out\ssleay speed rc4 >speed.3l
+
+perl Configure b2-is-ri-dp
+del tmp\i_*.obj tmp\rc4*.obj tmp\ecb_enc.obj tmp\bn*.obj
+nmake -f %makefile%
+nmake -f %makefile%
+nmake -f %makefile%
+out\ssleay speed rsa rc4 idea des >speed.4l
+
+type speed.1 >speed.log
+type speed.1l >>speed.log
+perl util\sp-diff.pl speed.1l speed.2l >>speed.log
+perl util\sp-diff.pl speed.1l speed.3l >>speed.log
+perl util\sp-diff.pl speed.1l speed.4l >>speed.log
+
diff --git a/openssl/ms/tenc.bat b/openssl/ms/tenc.bat
new file mode 100755
index 0000000..a4fa7f3
--- /dev/null
+++ b/openssl/ms/tenc.bat
@@ -0,0 +1,14 @@
+rem called by testenc
+
+echo test %1 %2 %3 %4 %5 %6 
+%ssleay% %1 %2 %3 %4 %5 %6 -e -bufsize 113 -k test -in %input% -out %tmp1%
+%ssleay% %1 %2 %3 %4 %5 %6 -d -bufsize 157 -k test -in %tmp1% -out %out1%
+%cmp% %input% %out1%
+if errorlevel 1 goto err
+
+echo test base64 %1 %2 %3 %4 %5 %6 
+%ssleay% %1 %2 %3 %4 %5 %6 -a -e -bufsize 113 -k test -in %input% -out %tmp1%
+%ssleay% %1 %2 %3 %4 %5 %6 -a -d -bufsize 157 -k test -in %tmp1% -out %out1%
+%cmp% %input% %out1%
+
+:err
diff --git a/openssl/ms/tencce.bat b/openssl/ms/tencce.bat
new file mode 100644
index 0000000..c8b1acd
--- /dev/null
+++ b/openssl/ms/tencce.bat
@@ -0,0 +1,19 @@
+rem called by testencce
+
+echo test %1 %2 %3 %4 %5 %6 
+cecopy %input% CE:\OpenSSL
+cerun CE:\OpenSSL\%ssleay% %1 %2 %3 %4 %5 %6 -e -bufsize 113 -k test -in \OpenSSL\%input% -out \OpenSSL\%tmp1%
+cerun CE:\OpenSSL\%ssleay% %1 %2 %3 %4 %5 %6 -d -bufsize 157 -k test -in \OpenSSL\%tmp1% -out \OpenSSL\%out1%
+del %out1% >nul 2>&1
+cecopy CE:\OpenSSL\%out1% .
+%cmp% %input% %out1%
+if errorlevel 1 goto err
+
+echo test base64 %1 %2 %3 %4 %5 %6 
+cerun CE:\OpenSSL\%ssleay% %1 %2 %3 %4 %5 %6 -a -e -bufsize 113 -k test -in \OpenSSL\%input% -out \OpenSSL\%tmp1%
+cerun CE:\OpenSSL\%ssleay% %1 %2 %3 %4 %5 %6 -a -d -bufsize 157 -k test -in \OpenSSL\%tmp1% -out \OpenSSL\%out1%
+del %out1% >nul 2>&1
+cecopy CE:\OpenSSL\%out1% .
+%cmp% %input% %out1%
+
+:err
diff --git a/openssl/ms/test.bat b/openssl/ms/test.bat
new file mode 100755
index 0000000..f490546
--- /dev/null
+++ b/openssl/ms/test.bat
@@ -0,0 +1,185 @@
+@echo off
+
+set test=..\ms
+set opath=%PATH%
+PATH=..\ms;%PATH%
+set OPENSSL_CONF=..\apps\openssl.cnf
+
+rem run this from inside the bin directory
+
+echo rsa_test
+rsa_test
+if errorlevel 1 goto done
+
+echo destest
+destest
+if errorlevel 1 goto done
+
+echo ideatest
+ideatest
+if errorlevel 1 goto done
+
+echo bftest
+bftest
+if errorlevel 1 goto done
+
+echo shatest
+shatest
+if errorlevel 1 goto done
+
+echo sha1test
+sha1test
+if errorlevel 1 goto done
+
+echo md5test
+md5test
+if errorlevel 1 goto done
+
+echo rc2test
+rc2test
+if errorlevel 1 goto done
+
+echo rc4test
+rc4test
+if errorlevel 1 goto done
+
+echo randtest
+randtest
+if errorlevel 1 goto done
+
+echo dhtest
+dhtest
+if errorlevel 1 goto done
+
+echo exptest
+exptest
+if errorlevel 1 goto done
+
+echo dsatest
+dsatest
+if errorlevel 1 goto done
+
+echo ectest
+ectest
+if errorlevel 1 goto done
+
+echo testenc
+call %test%\testenc openssl
+if errorlevel 1 goto done
+
+echo testpem
+call %test%\testpem openssl
+if errorlevel 1 goto done
+
+echo testss
+call %test%\testss openssl
+if errorlevel 1 goto done
+
+set SSL_TEST=ssltest -key keyU.ss -cert certU.ss -c_key keyU.ss -c_cert certU.ss -CAfile certCA.ss
+
+echo test sslv2
+ssltest -ssl2
+if errorlevel 1 goto done
+
+echo test sslv2 with server authentication
+%SSL_TEST% -ssl2 -server_auth
+if errorlevel 1 goto done
+
+echo test sslv2 with client authentication
+%SSL_TEST% -ssl2 -client_auth
+if errorlevel 1 goto done
+
+echo test sslv2 with both client and server authentication
+%SSL_TEST% -ssl2 -server_auth -client_auth
+if errorlevel 1 goto done
+
+echo test sslv3
+ssltest -ssl3
+if errorlevel 1 goto done
+
+echo test sslv3 with server authentication
+%SSL_TEST% -ssl3 -server_auth
+if errorlevel 1 goto done
+
+echo test sslv3 with client authentication
+%SSL_TEST% -ssl3 -client_auth
+if errorlevel 1 goto done
+
+echo test sslv3 with both client and server authentication
+%SSL_TEST% -ssl3 -server_auth -client_auth
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3
+ssltest
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3 with server authentication
+%SSL_TEST% -server_auth
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3 with client authentication
+%SSL_TEST% -client_auth
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3 with both client and server authentication
+%SSL_TEST% -server_auth -client_auth
+if errorlevel 1 goto done
+
+echo test sslv2 via BIO pair
+ssltest -bio_pair -ssl2
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3 with 1024 bit DHE via BIO pair
+ssltest -bio_pair -dhe1024dsa -v
+if errorlevel 1 goto done
+
+echo test sslv2 with server authentication via BIO pair
+%SSL_TEST% -bio_pair -ssl2 -server_auth
+if errorlevel 1 goto done
+
+echo test sslv2 with client authentication via BIO pair
+%SSL_TEST% -bio_pair -ssl2 -client_auth
+if errorlevel 1 goto done
+
+echo test sslv2 with both client and server authentication via BIO pair
+%SSL_TEST% -bio_pair -ssl2 -server_auth -client_auth
+if errorlevel 1 goto done
+
+echo test sslv3 via BIO pair
+ssltest -bio_pair -ssl3
+if errorlevel 1 goto done
+
+echo test sslv3 with server authentication via BIO pair
+%SSL_TEST% -bio_pair -ssl3 -server_auth
+if errorlevel 1 goto done
+
+echo test sslv3 with client authentication  via BIO pair
+%SSL_TEST% -bio_pair -ssl3 -client_auth
+if errorlevel 1 goto done
+
+echo test sslv3 with both client and server authentication via BIO pair
+%SSL_TEST% -bio_pair -ssl3 -server_auth -client_auth
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3 via BIO pair
+ssltest -bio_pair
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3 with server authentication
+%SSL_TEST% -bio_pair -server_auth
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3 with client authentication via BIO pair
+%SSL_TEST% -bio_pair -client_auth
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3 with both client and server authentication via BIO pair
+%SSL_TEST% -bio_pair -server_auth -client_auth
+if errorlevel 1 goto done
+
+echo passed all tests
+goto end
+:done
+echo problems.....
+:end
+PATH=%opath%
diff --git a/openssl/ms/testce.bat b/openssl/ms/testce.bat
new file mode 100644
index 0000000..2ab010b
--- /dev/null
+++ b/openssl/ms/testce.bat
@@ -0,0 +1,234 @@
+@echo off
+
+cemkdir CE:\OpenSSL
+
+set test=..\ms
+set opath=%PATH%
+PATH=..\ms;%PATH%
+cecopy ..\apps\openssl.cnf CE:\OpenSSL
+set OPENSSL_CONF=\OpenSSL\openssl.cnf
+set HOME=\OpenSSL
+set CERUN_PASS_ENV=OPENSSL_CONF HOME
+
+rem run this from inside the bin directory
+
+rem Copy the DLL's (though they'll only exist if we're in out32dll)
+if exist libeay32.dll cecopy libeay32.dll CE:\OpenSSL
+if exist ssleay32.dll cecopy ssleay32.dll CE:\OpenSSL
+
+echo rsa_test
+call %test%\testce2 rsa_test
+if errorlevel 1 goto done
+
+echo destest
+call %test%\testce2 destest
+if errorlevel 1 goto done
+
+echo ideatest
+call %test%\testce2 ideatest
+if errorlevel 1 goto done
+
+echo bftest
+call %test%\testce2 bftest
+if errorlevel 1 goto done
+
+echo shatest
+call %test%\testce2 shatest
+if errorlevel 1 goto done
+
+echo sha1test
+call %test%\testce2 sha1test
+if errorlevel 1 goto done
+
+echo md5test
+call %test%\testce2 md5test
+if errorlevel 1 goto done
+
+echo md2test
+call %test%\testce2 md2test
+if errorlevel 1 goto done
+
+echo mdc2test
+call %test%\testce2 mdc2test
+if errorlevel 1 goto done
+
+echo rc2test
+call %test%\testce2 rc2test
+if errorlevel 1 goto done
+
+echo rc4test
+call %test%\testce2 rc4test
+if errorlevel 1 goto done
+
+echo randtest
+call %test%\testce2 randtest
+if errorlevel 1 goto done
+
+echo dhtest
+call %test%\testce2 dhtest
+if errorlevel 1 goto done
+
+echo exptest
+call %test%\testce2 exptest
+if errorlevel 1 goto done
+
+echo dsatest
+call %test%\testce2 dsatest
+if errorlevel 1 goto done
+
+echo testenc
+call %test%\testencce openssl.exe
+if errorlevel 1 goto done
+
+echo testpem
+call %test%\testpemce openssl.exe
+if errorlevel 1 goto done
+
+cecopy openssl.exe CE:\OpenSSL
+
+echo verify
+copy ..\certs\*.pem cert.tmp >nul
+cecopy cert.tmp CE:\OpenSSL
+cemkdir CE:\OpenSSL\certs
+rem cecopy ..\certs\*.pem CE:\OpenSSL\certs
+cecopy ..\certs\ca-cert.pem CE:\OpenSSL\certs
+cecopy ..\certs\dsa-ca.pem CE:\OpenSSL\certs
+cecopy ..\certs\dsa-pca.pem CE:\OpenSSL\certs
+cecopy ..\certs\factory.pem CE:\OpenSSL\certs
+cecopy ..\certs\ICE-CA.pem CE:\OpenSSL\certs
+cecopy ..\certs\ICE-root.pem CE:\OpenSSL\certs
+cecopy ..\certs\ICE-user.pem CE:\OpenSSL\certs
+cecopy ..\certs\nortelCA.pem CE:\OpenSSL\certs
+cecopy ..\certs\pca-cert.pem CE:\OpenSSL\certs
+cecopy ..\certs\RegTP-4R.pem CE:\OpenSSL\certs
+cecopy ..\certs\RegTP-5R.pem CE:\OpenSSL\certs
+cecopy ..\certs\RegTP-6R.pem CE:\OpenSSL\certs
+cecopy ..\certs\rsa-cca.pem CE:\OpenSSL\certs
+cecopy ..\certs\thawteCb.pem CE:\OpenSSL\certs
+cecopy ..\certs\thawteCp.pem CE:\OpenSSL\certs
+cecopy ..\certs\timCA.pem CE:\OpenSSL\certs
+cecopy ..\certs\tjhCA.pem CE:\OpenSSL\certs
+cecopy ..\certs\vsign1.pem CE:\OpenSSL\certs
+cecopy ..\certs\vsign2.pem CE:\OpenSSL\certs
+cecopy ..\certs\vsign3.pem CE:\OpenSSL\certs
+cecopy ..\certs\vsignss.pem CE:\OpenSSL\certs
+cecopy ..\certs\vsigntca.pem CE:\OpenSSL\certs
+cerun CE:\OpenSSL\openssl verify -CAfile \OpenSSL\cert.tmp \OpenSSL\certs\*.pem
+
+echo testss
+call %test%\testssce openssl.exe
+if errorlevel 1 goto done
+
+cecopy ssltest.exe CE:\OpenSSL
+cecopy ..\apps\server.pem CE:\OpenSSL
+cecopy ..\apps\client.pem CE:\OpenSSL
+
+echo test sslv2
+cerun CE:\OpenSSL\ssltest -ssl2
+if errorlevel 1 goto done
+
+echo test sslv2 with server authentication
+cerun CE:\OpenSSL\ssltest -ssl2 -server_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+echo test sslv2 with client authentication
+cerun CE:\OpenSSL\ssltest -ssl2 -client_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+echo test sslv2 with both client and server authentication
+cerun CE:\OpenSSL\ssltest -ssl2 -server_auth -client_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+echo test sslv3
+cerun CE:\OpenSSL\ssltest -ssl3
+if errorlevel 1 goto done
+
+echo test sslv3 with server authentication
+cerun CE:\OpenSSL\ssltest -ssl3 -server_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+echo test sslv3 with client authentication
+cerun CE:\OpenSSL\ssltest -ssl3 -client_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+echo test sslv3 with both client and server authentication
+cerun CE:\OpenSSL\ssltest -ssl3 -server_auth -client_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3
+cerun CE:\OpenSSL\ssltest
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3 with server authentication
+cerun CE:\OpenSSL\ssltest -server_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3 with client authentication
+cerun CE:\OpenSSL\ssltest -client_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3 with both client and server authentication
+cerun CE:\OpenSSL\ssltest -server_auth -client_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+echo test sslv2 via BIO pair
+cerun CE:\OpenSSL\ssltest -bio_pair -ssl2
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3 with 1024 bit DHE via BIO pair
+cerun CE:\OpenSSL\ssltest -bio_pair -dhe1024dsa -v
+if errorlevel 1 goto done
+
+echo test sslv2 with server authentication via BIO pair
+cerun CE:\OpenSSL\ssltest -bio_pair -ssl2 -server_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+echo test sslv2 with client authentication via BIO pair
+cerun CE:\OpenSSL\ssltest -bio_pair -ssl2 -client_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+echo test sslv2 with both client and server authentication via BIO pair
+cerun CE:\OpenSSL\ssltest -bio_pair -ssl2 -server_auth -client_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+echo test sslv3 via BIO pair
+cerun CE:\OpenSSL\ssltest -bio_pair -ssl3
+if errorlevel 1 goto done
+
+echo test sslv3 with server authentication via BIO pair
+cerun CE:\OpenSSL\ssltest -bio_pair -ssl3 -server_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+echo test sslv3 with client authentication  via BIO pair
+cerun CE:\OpenSSL\ssltest -bio_pair -ssl3 -client_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+echo test sslv3 with both client and server authentication via BIO pair
+cerun CE:\OpenSSL\ssltest -bio_pair -ssl3 -server_auth -client_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3 via BIO pair
+cerun CE:\OpenSSL\ssltest
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3 with server authentication
+cerun CE:\OpenSSL\ssltest -bio_pair -server_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3 with client authentication via BIO pair
+cerun CE:\OpenSSL\ssltest -bio_pair -client_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+echo test sslv2/sslv3 with both client and server authentication via BIO pair
+cerun CE:\OpenSSL\ssltest -bio_pair -server_auth -client_auth -CAfile \OpenSSL\cert.tmp
+if errorlevel 1 goto done
+
+del cert.tmp
+
+echo passed all tests
+goto end
+:done
+echo problems.....
+:end
+PATH=%opath%
+
diff --git a/openssl/ms/testce2.bat b/openssl/ms/testce2.bat
new file mode 100644
index 0000000..24265b9
--- /dev/null
+++ b/openssl/ms/testce2.bat
@@ -0,0 +1,2 @@
+cecopy %1.exe CE:\OpenSSL
+cerun CE:\OpenSSL\%1 %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/openssl/ms/testenc.bat b/openssl/ms/testenc.bat
new file mode 100755
index 0000000..f8e9093
--- /dev/null
+++ b/openssl/ms/testenc.bat
@@ -0,0 +1,94 @@
+@echo off
+echo start testenc
+
+path=..\ms;%path%
+set ssleay=%1%
+set input=..\ms\testenc.bat
+set tmp1=..\ms\cipher.out
+set out1=..\ms\clear.out
+set cmp=perl ..\ms\cmp.pl
+
+cd
+call tenc.bat enc
+if errorlevel 1 goto err
+
+call tenc.bat rc4
+if errorlevel 1 goto err
+
+call tenc.bat des-cfb
+if errorlevel 1 goto err
+
+call tenc.bat des-ede-cfb
+if errorlevel 1 goto err
+
+call tenc.bat des-ede3-cfb
+if errorlevel 1 goto err
+
+call tenc.bat des-ofb
+if errorlevel 1 goto err
+
+call tenc.bat des-ede-ofb
+if errorlevel 1 goto err
+
+call tenc.bat des-ede3-ofb
+if errorlevel 1 goto err
+
+call tenc.bat des-ecb
+if errorlevel 1 goto err
+
+call tenc.bat des-ede
+if errorlevel 1 goto err
+
+call tenc.bat des-ede3
+if errorlevel 1 goto err
+
+call tenc.bat des-cbc
+if errorlevel 1 goto err
+
+call tenc.bat des-ede-cbc
+if errorlevel 1 goto err
+
+call tenc.bat des-ede3-cbc
+if errorlevel 1 goto err
+
+call tenc.bat idea-ecb
+if errorlevel 1 goto err
+
+call tenc.bat idea-cfb
+if errorlevel 1 goto err
+
+call tenc.bat idea-ofb
+if errorlevel 1 goto err
+
+call tenc.bat idea-cbc
+if errorlevel 1 goto err
+
+call tenc.bat rc2-ecb
+if errorlevel 1 goto err
+
+call tenc.bat rc2-cfb
+if errorlevel 1 goto err
+
+call tenc.bat rc2-ofb
+if errorlevel 1 goto err
+
+call tenc.bat rc2-cbc
+if errorlevel 1 goto err
+
+call tenc.bat bf-ecb
+if errorlevel 1 goto err
+
+call tenc.bat bf-cfb
+if errorlevel 1 goto err
+
+call tenc.bat bf-ofb
+if errorlevel 1 goto err
+
+call tenc.bat bf-cbc
+if errorlevel 1 goto err
+
+echo OK
+del %out1%
+del %tmp1%
+:err
+
diff --git a/openssl/ms/testencce.bat b/openssl/ms/testencce.bat
new file mode 100644
index 0000000..1da3e08
--- /dev/null
+++ b/openssl/ms/testencce.bat
@@ -0,0 +1,97 @@
+@echo off
+echo start testenc
+
+path=..\ms;%path%
+set ssleay=%1%
+copy ..\ms\testenc.bat >nul
+set input=testenc.bat
+set tmp1=cipher.out
+set out1=clear.out
+set cmp=perl ..\ms\cmp.pl
+
+cecopy %ssleay% CE:\OpenSSL
+
+cd
+call tencce.bat enc
+if errorlevel 1 goto err
+
+call tencce.bat rc4
+if errorlevel 1 goto err
+
+call tencce.bat des-cfb
+if errorlevel 1 goto err
+
+call tencce.bat des-ede-cfb
+if errorlevel 1 goto err
+
+call tencce.bat des-ede3-cfb
+if errorlevel 1 goto err
+
+call tencce.bat des-ofb
+if errorlevel 1 goto err
+
+call tencce.bat des-ede-ofb
+if errorlevel 1 goto err
+
+call tencce.bat des-ede3-ofb
+if errorlevel 1 goto err
+
+call tencce.bat des-ecb
+if errorlevel 1 goto err
+
+call tencce.bat des-ede
+if errorlevel 1 goto err
+
+call tencce.bat des-ede3
+if errorlevel 1 goto err
+
+call tencce.bat des-cbc
+if errorlevel 1 goto err
+
+call tencce.bat des-ede-cbc
+if errorlevel 1 goto err
+
+call tencce.bat des-ede3-cbc
+if errorlevel 1 goto err
+
+call tencce.bat idea-ecb
+if errorlevel 1 goto err
+
+call tencce.bat idea-cfb
+if errorlevel 1 goto err
+
+call tencce.bat idea-ofb
+if errorlevel 1 goto err
+
+call tencce.bat idea-cbc
+if errorlevel 1 goto err
+
+call tencce.bat rc2-ecb
+if errorlevel 1 goto err
+
+call tencce.bat rc2-cfb
+if errorlevel 1 goto err
+
+call tencce.bat rc2-ofb
+if errorlevel 1 goto err
+
+call tencce.bat rc2-cbc
+if errorlevel 1 goto err
+
+call tencce.bat bf-ecb
+if errorlevel 1 goto err
+
+call tencce.bat bf-cfb
+if errorlevel 1 goto err
+
+call tencce.bat bf-ofb
+if errorlevel 1 goto err
+
+call tencce.bat bf-cbc
+if errorlevel 1 goto err
+
+echo OK
+del %out1% >nul 2>&1
+del %tmp1% >nul 2>&1
+:err
+
diff --git a/openssl/ms/testpem.bat b/openssl/ms/testpem.bat
new file mode 100755
index 0000000..8b2e844
--- /dev/null
+++ b/openssl/ms/testpem.bat
@@ -0,0 +1,32 @@
+@echo off
+set ssleay=%1%
+set tmp1=pem.out
+set cmp=fc.exe
+
+call tpem.bat crl ..\test\testcrl.pem
+if errorlevel 1 goto err
+
+call tpem.bat pkcs7 ..\test\testp7.pem
+if errorlevel 1 goto err
+
+call tpem.bat req ..\test\testreq2.pem
+if errorlevel 1 goto err
+
+call tpem.bat rsa ..\test\testrsa.pem
+if errorlevel 1 goto err
+
+call tpem.bat x509 ..\test\testx509.pem
+if errorlevel 1 goto err
+
+call tpem.bat x509 ..\test\v3-cert1.pem
+if errorlevel 1 goto err
+
+call tpem.bat x509 ..\test\v3-cert1.pem
+if errorlevel 1 goto err
+
+call tpem.bat sess_id ..\test\testsid.pem
+if errorlevel 1 goto err
+
+echo OK
+del %tmp1%
+:err
diff --git a/openssl/ms/testpemce.bat b/openssl/ms/testpemce.bat
new file mode 100644
index 0000000..ac64a79
--- /dev/null
+++ b/openssl/ms/testpemce.bat
@@ -0,0 +1,42 @@
+@echo off
+set ssleay=%1%
+set tmp1=pem.out
+set cmp=fc.exe
+
+cecopy %ssleay% CE:\OpenSSL
+
+copy ..\test\testcrl.pem >nul
+call tpemce.bat crl testcrl.pem
+if errorlevel 1 goto err
+
+copy ..\test\testp7.pem >nul
+call tpemce.bat pkcs7 testp7.pem
+if errorlevel 1 goto err
+
+copy ..\test\testreq2.pem >nul
+call tpemce.bat req testreq2.pem
+if errorlevel 1 goto err
+
+copy ..\test\testrsa.pem >nul
+call tpemce.bat rsa testrsa.pem
+if errorlevel 1 goto err
+
+copy ..\test\testx509.pem >nul
+call tpemce.bat x509 testx509.pem
+if errorlevel 1 goto err
+
+copy ..\test\v3-cert1.pem >nul
+call tpemce.bat x509 v3-cert1.pem
+if errorlevel 1 goto err
+
+copy ..\test\v3-cert1.pem >nul
+call tpemce.bat x509 v3-cert1.pem
+if errorlevel 1 goto err
+
+copy ..\test\testsid.pem >nul
+call tpemce.bat sess_id testsid.pem
+if errorlevel 1 goto err
+
+echo OK
+del %tmp1% >nul 2>&1
+:err
diff --git a/openssl/ms/testss.bat b/openssl/ms/testss.bat
new file mode 100755
index 0000000..5afa131
--- /dev/null
+++ b/openssl/ms/testss.bat
@@ -0,0 +1,98 @@
+@echo off
+
+rem set ssleay=..\out\ssleay
+set ssleay=%1
+
+set reqcmd=%ssleay% req
+set x509cmd=%ssleay% x509 -sha1
+set verifycmd=%ssleay% verify
+
+set CAkey=keyCA.ss
+set CAcert=certCA.ss
+set CAserial=certCA.srl
+set CAreq=reqCA.ss
+set CAconf=..\test\CAss.cnf
+set CAreq2=req2CA.ss	
+
+set Uconf=..\test\Uss.cnf
+set Ukey=keyU.ss
+set Ureq=reqU.ss
+set Ucert=certU.ss
+
+echo make a certificate request using 'req'
+%reqcmd% -config %CAconf% -out %CAreq% -keyout %CAkey% -new
+if errorlevel 1 goto e_req
+
+echo convert the certificate request into a self signed certificate using 'x509'
+%x509cmd% -CAcreateserial -in %CAreq% -days 30 -req -out %CAcert% -signkey %CAkey% >err.ss
+if errorlevel 1 goto e_x509
+
+echo --
+echo convert a certificate into a certificate request using 'x509'
+%x509cmd% -in %CAcert% -x509toreq -signkey %CAkey% -out %CAreq2% >err.ss
+if errorlevel 1 goto e_x509_2
+
+%reqcmd% -verify -in %CAreq% -noout
+if errorlevel 1 goto e_vrfy_1
+
+%reqcmd% -verify -in %CAreq2% -noout
+if errorlevel 1 goto e_vrfy_2
+
+%verifycmd% -CAfile %CAcert% %CAcert%
+if errorlevel 1 goto e_vrfy_3
+
+echo --
+echo make another certificate request using 'req'
+%reqcmd% -config %Uconf% -out %Ureq% -keyout %Ukey% -new >err.ss
+if errorlevel 1 goto e_req_gen
+
+echo --
+echo sign certificate request with the just created CA via 'x509'
+%x509cmd% -CAcreateserial -in %Ureq% -days 30 -req -out %Ucert% -CA %CAcert% -CAkey %CAkey% -CAserial %CAserial%
+if errorlevel 1 goto e_x_sign
+
+%verifycmd% -CAfile %CAcert% %Ucert%
+echo --
+echo Certificate details
+%x509cmd% -subject -issuer -startdate -enddate -noout -in %Ucert%
+
+echo Everything appeared to work
+echo --
+echo The generated CA certificate is %CAcert%
+echo The generated CA private key is %CAkey%
+echo The current CA signing serial number is in %CAserial%
+
+echo The generated user certificate is %Ucert%
+echo The generated user private key is %Ukey%
+echo --
+
+del err.ss
+
+goto end
+
+:e_req
+echo error using 'req' to generate a certificate request
+goto end
+:e_x509
+echo error using 'x509' to self sign a certificate request
+goto end
+:e_x509_2
+echo error using 'x509' convert a certificate to a certificate request
+goto end
+:e_vrfy_1
+echo first generated request is invalid
+goto end
+:e_vrfy_2
+echo second generated request is invalid
+goto end
+:e_vrfy_3
+echo first generated cert is invalid
+goto end
+:e_req_gen
+echo error using 'req' to generate a certificate request
+goto end
+:e_x_sign
+echo error using 'x509' to sign a certificate request
+goto end
+
+:end
diff --git a/openssl/ms/testssce.bat b/openssl/ms/testssce.bat
new file mode 100644
index 0000000..18381ed
--- /dev/null
+++ b/openssl/ms/testssce.bat
@@ -0,0 +1,104 @@
+rem set ssleay=..\out\ssleay
+set ssleay=%1
+
+set reqcmd=%ssleay% req
+set x509cmd=%ssleay% x509
+set verifycmd=%ssleay% verify
+
+set CAkey=\OpenSSL\keyCA.ss
+set CAcert=\OpenSSL\certCA.ss
+set CAserial=\OpenSSL\certCA.srl
+set CAreq=\OpenSSL\reqCA.ss
+cecopy ..\test\CAss.cnf CE:\OpenSSL
+set CAconf=\OpenSSL\CAss.cnf
+set CAreq2=\OpenSSL\req2CA.ss	
+
+cecopy ..\test\Uss.cnf CE:\OpenSSL
+set Uconf=\OpenSSL\Uss.cnf
+set Ukey=\OpenSSL\keyU.ss
+set Ureq=\OpenSSL\reqU.ss
+set Ucert=\OpenSSL\certU.ss
+
+echo make a certificate request using 'req'
+cerun CE:\OpenSSL\%reqcmd% -config %CAconf% -out %CAreq% -keyout %CAkey% -new
+if errorlevel 1 goto e_req
+
+echo convert the certificate request into a self signed certificate using 'x509'
+cerun CE:\OpenSSL\%x509cmd% -CAcreateserial -in %CAreq% -days 30 -req -out %CAcert% -signkey %CAkey% "> \OpenSSL\err.ss"
+if errorlevel 1 goto e_x509
+
+echo --
+echo convert a certificate into a certificate request using 'x509'
+cerun CE:\OpenSSL\%x509cmd% -in %CAcert% -x509toreq -signkey %CAkey% -out %CAreq2% "> \OpenSSL\err.ss"
+if errorlevel 1 goto e_x509_2
+
+cerun CE:\OpenSSL\%reqcmd% -verify -in %CAreq% -noout
+if errorlevel 1 goto e_vrfy_1
+
+cerun CE:\OpenSSL\%reqcmd% -verify -in %CAreq2% -noout
+if errorlevel 1 goto e_vrfy_2
+
+cerun CE:\OpenSSL\%verifycmd% -CAfile %CAcert% %CAcert%
+if errorlevel 1 goto e_vrfy_3
+
+echo --
+echo make another certificate request using 'req'
+cerun CE:\OpenSSL\%reqcmd% -config %Uconf% -out %Ureq% -keyout %Ukey% -new "> \OpenSSL\err.ss"
+if errorlevel 1 goto e_req_gen
+
+echo --
+echo sign certificate request with the just created CA via 'x509'
+cerun CE:\OpenSSL\%x509cmd% -CAcreateserial -in %Ureq% -days 30 -req -out %Ucert% -CA %CAcert% -CAkey %CAkey% -CAserial %CAserial%
+if errorlevel 1 goto e_x_sign
+
+cerun CE:\OpenSSL\%verifycmd% -CAfile %CAcert% %Ucert%
+echo --
+echo Certificate details
+cerun CE:\OpenSSL\%x509cmd% -subject -issuer -startdate -enddate -noout -in %Ucert%
+
+cecopy CE:%CAcert% .
+cecopy CE:%CAkey% .
+cecopy CE:%CAserial% .
+cecopy CE:%Ucert% .
+cecopy CE:%Ukey% .
+
+echo Everything appeared to work
+echo --
+echo The generated CA certificate is %CAcert%
+echo The generated CA private key is %CAkey%
+echo The current CA signing serial number is in %CAserial%
+
+echo The generated user certificate is %Ucert%
+echo The generated user private key is %Ukey%
+echo --
+
+cedel CE:\OpenSSL\err.ss
+
+goto end
+
+:e_req
+echo error using 'req' to generate a certificate request
+goto end
+:e_x509
+echo error using 'x509' to self sign a certificate request
+goto end
+:e_x509_2
+echo error using 'x509' convert a certificate to a certificate request
+goto end
+:e_vrfy_1
+echo first generated request is invalid
+goto end
+:e_vrfy_2
+echo second generated request is invalid
+goto end
+:e_vrfy_3
+echo first generated cert is invalid
+goto end
+:e_req_gen
+echo error using 'req' to generate a certificate request
+goto end
+:e_x_sign
+echo error using 'x509' to sign a certificate request
+goto end
+
+:end
diff --git a/openssl/ms/tlhelp32.h b/openssl/ms/tlhelp32.h
new file mode 100644
index 0000000..8f4222e
--- /dev/null
+++ b/openssl/ms/tlhelp32.h
@@ -0,0 +1,136 @@
+/*
+	tlhelp32.h - Include file for Tool help functions.
+
+	Written by Mumit Khan <khan@nanotech.wisc.edu>
+
+	This file is part of a free library for the Win32 API. 
+
+	This library is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+*/
+#ifndef _TLHELP32_H
+#define _TLHELP32_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define HF32_DEFAULT	1
+#define HF32_SHARED	2
+#define LF32_FIXED	0x1
+#define LF32_FREE	0x2
+#define LF32_MOVEABLE	0x4
+#define MAX_MODULE_NAME32	255
+#define TH32CS_SNAPHEAPLIST	0x1
+#define TH32CS_SNAPPROCESS	0x2
+#define TH32CS_SNAPTHREAD	0x4
+#define TH32CS_SNAPMODULE	0x8
+#define TH32CS_SNAPALL	(TH32CS_SNAPHEAPLIST|TH32CS_SNAPPROCESS|TH32CS_SNAPTHREAD|TH32CS_SNAPMODULE)
+#define TH32CS_INHERIT	0x80000000
+typedef struct tagHEAPLIST32 {
+	DWORD dwSize;
+	DWORD th32ProcessID;
+	DWORD th32HeapID;
+	DWORD dwFlags;
+} HEAPLIST32,*PHEAPLIST32,*LPHEAPLIST32;
+typedef struct tagHEAPENTRY32 {
+	DWORD dwSize;
+	HANDLE hHandle;
+	DWORD dwAddress;
+	DWORD dwBlockSize;
+	DWORD dwFlags;
+	DWORD dwLockCount;
+	DWORD dwResvd;
+	DWORD th32ProcessID;
+	DWORD th32HeapID;
+} HEAPENTRY32,*PHEAPENTRY32,*LPHEAPENTRY32;
+typedef struct tagPROCESSENTRY32W {
+	DWORD dwSize;
+	DWORD cntUsage;
+	DWORD th32ProcessID;
+	DWORD th32DefaultHeapID;
+	DWORD th32ModuleID;
+	DWORD cntThreads;
+	DWORD th32ParentProcessID;
+	LONG pcPriClassBase;
+	DWORD dwFlags;
+	WCHAR szExeFile[MAX_PATH];
+} PROCESSENTRY32W,*PPROCESSENTRY32W,*LPPROCESSENTRY32W;
+typedef struct tagPROCESSENTRY32 {
+	DWORD dwSize;
+	DWORD cntUsage;
+	DWORD th32ProcessID;
+	DWORD th32DefaultHeapID;
+	DWORD th32ModuleID;
+	DWORD cntThreads;
+	DWORD th32ParentProcessID;
+	LONG pcPriClassBase;
+	DWORD dwFlags;
+	CHAR  szExeFile[MAX_PATH];
+} PROCESSENTRY32,*PPROCESSENTRY32,*LPPROCESSENTRY32;
+typedef struct tagTHREADENTRY32 {
+	DWORD dwSize;
+	DWORD cntUsage;
+	DWORD th32ThreadID;
+	DWORD th32OwnerProcessID;
+	LONG tpBasePri;
+	LONG tpDeltaPri;
+	DWORD dwFlags;
+} THREADENTRY32,*PTHREADENTRY32,*LPTHREADENTRY32;
+typedef struct tagMODULEENTRY32W {
+	DWORD dwSize;
+	DWORD th32ModuleID;
+	DWORD th32ProcessID;
+	DWORD GlblcntUsage;
+	DWORD ProccntUsage;
+	BYTE *modBaseAddr;
+	DWORD modBaseSize;
+	HMODULE hModule; 
+	WCHAR szModule[MAX_MODULE_NAME32 + 1];
+	WCHAR szExePath[MAX_PATH];
+} MODULEENTRY32W,*PMODULEENTRY32W,*LPMODULEENTRY32W;
+typedef struct tagMODULEENTRY32 {
+	DWORD dwSize;
+	DWORD th32ModuleID;
+	DWORD th32ProcessID;
+	DWORD GlblcntUsage;
+	DWORD ProccntUsage;
+	BYTE *modBaseAddr;
+	DWORD modBaseSize;
+	HMODULE hModule;
+	char szModule[MAX_MODULE_NAME32 + 1];
+	char szExePath[MAX_PATH];
+} MODULEENTRY32,*PMODULEENTRY32,*LPMODULEENTRY32;
+BOOL WINAPI Heap32First(LPHEAPENTRY32,DWORD,DWORD);
+BOOL WINAPI Heap32ListFirst(HANDLE,LPHEAPLIST32);
+BOOL WINAPI Heap32ListNext(HANDLE,LPHEAPLIST32);
+BOOL WINAPI Heap32Next(LPHEAPENTRY32);
+BOOL WINAPI Module32First(HANDLE,LPMODULEENTRY32);
+BOOL WINAPI Module32FirstW(HANDLE,LPMODULEENTRY32W);
+BOOL WINAPI Module32Next(HANDLE,LPMODULEENTRY32);
+BOOL WINAPI Module32NextW(HANDLE,LPMODULEENTRY32W);
+BOOL WINAPI Process32First(HANDLE,LPPROCESSENTRY32);
+BOOL WINAPI Process32FirstW(HANDLE,LPPROCESSENTRY32W);
+BOOL WINAPI Process32Next(HANDLE,LPPROCESSENTRY32);
+BOOL WINAPI Process32NextW(HANDLE,LPPROCESSENTRY32W);
+BOOL WINAPI Thread32First(HANDLE,LPTHREADENTRY32);
+BOOL WINAPI Thread32Next(HANDLE,LPTHREADENTRY32);
+BOOL WINAPI Toolhelp32ReadProcessMemory(DWORD,LPCVOID,LPVOID,DWORD,LPDWORD);
+HANDLE WINAPI CreateToolhelp32Snapshot(DWORD,DWORD);
+#ifdef UNICODE
+#define LPMODULEENTRY32 LPMODULEENTRY32W
+#define LPPROCESSENTRY32 LPPROCESSENTRY32W
+#define MODULEENTRY32 MODULEENTRY32W
+#define Module32First Module32FirstW
+#define Module32Next Module32NextW
+#define PMODULEENTRY32 PMODULEENTRY32W
+#define PPROCESSENTRY32 PPROCESSENTRY32W
+#define PROCESSENTRY32 PROCESSENTRY32W
+#define Process32First Process32FirstW
+#define Process32Next Process32NextW
+#endif /* UNICODE */
+#ifdef __cplusplus
+}
+#endif
+#endif /* _TLHELP32_H */
+
diff --git a/openssl/ms/tpem.bat b/openssl/ms/tpem.bat
new file mode 100755
index 0000000..cd01792
--- /dev/null
+++ b/openssl/ms/tpem.bat
@@ -0,0 +1,6 @@
+rem called by testpem
+
+echo test %1 %2
+%ssleay% %1 -in %2 -out %tmp1%
+%cmp% %2 %tmp1%
+
diff --git a/openssl/ms/tpemce.bat b/openssl/ms/tpemce.bat
new file mode 100644
index 0000000..483f559
--- /dev/null
+++ b/openssl/ms/tpemce.bat
@@ -0,0 +1,8 @@
+rem called by testpemce
+
+echo test %1 %2
+cecopy %2 CE:\OpenSSL
+cerun CE:\OpenSSL\%ssleay% %1 -in \OpenSSL\%2 -out \OpenSSL\%tmp1%
+del %tmp1% >nul 2>&1
+cecopy CE:\OpenSSL\%tmp1% .
+%cmp% %2 %tmp1%
diff --git a/openssl/ms/uplink-common.pl b/openssl/ms/uplink-common.pl
new file mode 100644
index 0000000..1d20e6e
--- /dev/null
+++ b/openssl/ms/uplink-common.pl
@@ -0,0 +1,22 @@
+#!/usr/bin/env perl
+#
+# pull APPLINK_MAX value from applink.c...
+$applink_c=$0;
+$applink_c=~s|[^/\\]+$||g;
+$applink_c.="applink.c";
+open(INPUT,$applink_c) || die "can't open $applink_c: $!";
+@max=grep {/APPLINK_MAX\s+(\d+)/} <INPUT>;
+close(INPUT);
+($#max==0) or die "can't find APPLINK_MAX in $applink_c";
+
+$max[0]=~/APPLINK_MAX\s+(\d+)/;
+$N=$1;	# number of entries in OPENSSL_UplinkTable not including
+	# OPENSSL_UplinkTable[0], which contains this value...
+
+1;
+
+# Idea is to fill the OPENSSL_UplinkTable with pointers to stubs
+# which invoke 'void OPENSSL_Uplink (ULONG_PTR *table,int index)';
+# and then dereference themselves. Latter shall result in endless
+# loop *unless* OPENSSL_Uplink does not replace 'table[index]' with
+# something else, e.g. as 'table[index]=unimplemented;'...
diff --git a/openssl/ms/uplink-ia64.pl b/openssl/ms/uplink-ia64.pl
new file mode 100644
index 0000000..4204c73
--- /dev/null
+++ b/openssl/ms/uplink-ia64.pl
@@ -0,0 +1,50 @@
+#!/usr/bin/env perl
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}.");
+
+require "uplink-common.pl";
+
+local $V=8;	# max number of args uplink functions may accept...
+my $loc0 = "r".(32+$V);
+print <<___;
+.text
+.global	OPENSSL_Uplink#
+.type	OPENSSL_Uplink#,\@function
+
+___
+for ($i=1;$i<=$N;$i++) {
+print <<___;
+.proc	lazy$i#
+lazy$i:
+	.prologue
+{ .mii;	.save	ar.pfs,$loc0
+	alloc	loc0=ar.pfs,$V,3,2,0
+	.save	b0,loc1
+	mov	loc1=b0
+	addl	loc2=\@ltoff(OPENSSL_UplinkTable#),gp	};;
+	.body
+{ .mmi;	ld8	out0=[loc2]
+	mov	out1=$i					};;
+{ .mib;	add	loc2=8*$i,out0
+	br.call.sptk.many	b0=OPENSSL_Uplink#	};;
+{ .mmi;	ld8	r31=[loc2];;
+	ld8	r30=[r31],8				};;
+{ .mii;	ld8	gp=[r31]
+	mov	b6=r30
+	mov	b0=loc1					};;
+{ .mib;	mov	ar.pfs=loc0
+	br.many	b6					};;
+.endp	lazy$i#
+
+___
+}
+print <<___;
+.data
+.global OPENSSL_UplinkTable#
+OPENSSL_UplinkTable:    data8   $N      // amount of following entries
+___
+for ($i=1;$i<=$N;$i++) {   print "      data8   \@fptr(lazy$i#)\n";   }
+print <<___;
+.size   OPENSSL_UplinkTable,.-OPENSSL_UplinkTable#
+___
diff --git a/openssl/ms/uplink-x86.pl b/openssl/ms/uplink-x86.pl
new file mode 100644
index 0000000..0dffc14
--- /dev/null
+++ b/openssl/ms/uplink-x86.pl
@@ -0,0 +1,33 @@
+#!/usr/bin/env perl
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC, "${dir}.", "${dir}../crypto/perlasm");
+require "x86asm.pl";
+
+require "uplink-common.pl";
+
+&asm_init($ARGV[0],"uplink-x86");
+
+&external_label("OPENSSL_Uplink");
+&public_label("OPENSSL_UplinkTable");
+
+for ($i=1;$i<=$N;$i++) {
+&function_begin_B("_\$lazy${i}");
+	&lea	("eax",&DWP(&label("OPENSSL_UplinkTable")));
+	&push	("eax");
+	&push	($i);
+	&call	(&label("OPENSSL_Uplink"));
+	&add	("esp",8);
+	&pop	("eax");
+	&jmp_ptr(&DWP(4*$i,"eax"));
+&function_end_B("_\$lazy${i}");
+}
+
+&dataseg();
+&align(4);
+&set_label("OPENSSL_UplinkTable");
+&data_word($N);
+for ($i=1;$i<=$N;$i++) {
+&data_word(&label("_\$lazy${i}"));
+}
+&asm_finish();
diff --git a/openssl/ms/uplink-x86_64.pl b/openssl/ms/uplink-x86_64.pl
new file mode 100644
index 0000000..9acbf6b
--- /dev/null
+++ b/openssl/ms/uplink-x86_64.pl
@@ -0,0 +1,64 @@
+#!/usr/bin/env perl
+
+$output=shift;
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+open STDOUT,"| $^X ${dir}../crypto/perlasm/x86_64-xlate.pl $output";
+push(@INC,"${dir}.");
+
+require "uplink-common.pl";
+
+$prefix="_lazy";
+
+print <<___;
+.text
+.extern	OPENSSL_Uplink
+.globl	OPENSSL_UplinkTable
+___
+for ($i=1;$i<=$N;$i++) {
+print <<___;
+.type	$prefix${i},\@abi-omnipotent
+.align	16
+$prefix${i}:
+	.byte	0x48,0x83,0xEC,0x28	# sub rsp,40
+	mov	%rcx,48(%rsp)
+	mov	%rdx,56(%rsp)
+	mov	%r8,64(%rsp)
+	mov	%r9,72(%rsp)
+	lea	OPENSSL_UplinkTable(%rip),%rcx
+	mov	\$$i,%rdx
+	call	OPENSSL_Uplink
+	mov	48(%rsp),%rcx
+	mov	56(%rsp),%rdx
+	mov	64(%rsp),%r8
+	mov	72(%rsp),%r9
+	lea	OPENSSL_UplinkTable(%rip),%rax
+	add	\$40,%rsp
+	jmp	*8*$i(%rax)
+$prefix${i}_end:
+.size	$prefix${i},.-$prefix${i}
+___
+}
+print <<___;
+.data
+OPENSSL_UplinkTable:
+        .quad   $N
+___
+for ($i=1;$i<=$N;$i++) {   print "      .quad   $prefix$i\n";   }
+print <<___;
+.section	.pdata,"r"
+.align		4
+___
+for ($i=1;$i<=$N;$i++) {
+print <<___;
+	.rva	$prefix${i},$prefix${i}_end,${prefix}_unwind_info
+___
+}
+print <<___;
+.section	.xdata,"r"
+.align		8
+${prefix}_unwind_info:
+	.byte	0x01,0x04,0x01,0x00
+	.byte	0x04,0x42,0x00,0x00
+___
+
+close STDOUT;
diff --git a/openssl/ms/uplink.c b/openssl/ms/uplink.c
new file mode 100644
index 0000000..6d59cb1
--- /dev/null
+++ b/openssl/ms/uplink.c
@@ -0,0 +1,117 @@
+#if (defined(_WIN64) || defined(_WIN32_WCE)) && !defined(UNICODE)
+#define UNICODE
+#endif
+#if defined(UNICODE) && !defined(_UNICODE)
+#define _UNICODE
+#endif
+#if defined(_UNICODE) && !defined(UNICODE)
+#define UNICODE
+#endif
+
+#include <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+#include "uplink.h"
+void OPENSSL_showfatal(const char *,...);
+
+static TCHAR msg[128];
+
+static void unimplemented (void)
+{   OPENSSL_showfatal (sizeof(TCHAR)==sizeof(char)?"%s\n":"%S\n",msg);
+    ExitProcess (1);
+}
+
+void OPENSSL_Uplink (volatile void **table, int index)
+{ static HMODULE volatile apphandle=NULL;
+  static void ** volatile applinktable=NULL;
+  int len;
+  void (*func)(void)=unimplemented;
+  HANDLE h;
+  void **p;
+
+    /* Note that the below code is not MT-safe in respect to msg
+     * buffer, but what's the worst thing that can happen? Error
+     * message might be misleading or corrupted. As error condition
+     * is fatal and should never be risen, I accept the risk... */
+    /* One can argue that I should have used InterlockedExchangePointer
+     * or something to update static variables and table[]. Well,
+     * store instructions are as atomic as they can get and assigned
+     * values are effectively constant... So that volatile qualifier
+     * should be sufficient [it prohibits compiler to reorder memory
+     * access instructions]. */
+    do {
+	len = _sntprintf (msg,sizeof(msg)/sizeof(TCHAR),
+			  _T("OPENSSL_Uplink(%p,%02X): "),table,index);
+	_tcscpy (msg+len,_T("unimplemented function"));
+
+	if ((h=apphandle)==NULL)
+	{   if  ((h=GetModuleHandle(NULL))==NULL)
+	    {	apphandle=(HMODULE)-1;
+		_tcscpy (msg+len,_T("no host application"));
+		break;
+	    }
+	    apphandle = h;
+	}
+	if ((h=apphandle)==(HMODULE)-1) /* revalidate */
+	    break;
+
+	if (applinktable==NULL)
+	{ void**(*applink)();
+
+	    applink=(void**(*)())GetProcAddress(h,"OPENSSL_Applink");
+	    if (applink==NULL)
+	    {	apphandle=(HMODULE)-1;
+		_tcscpy (msg+len,_T("no OPENSSL_Applink"));
+		break;
+	    }
+	    p = (*applink)();
+	    if (p==NULL)
+	    {	apphandle=(HMODULE)-1;
+		_tcscpy (msg+len,_T("no ApplinkTable"));
+		break;
+	    }
+	    applinktable = p;
+	}
+	else
+	    p = applinktable;
+
+	if (index > (int)p[0])
+	    break;
+
+	if (p[index]) func = p[index];
+    } while (0);
+
+    table[index] = func;
+}    
+
+#if defined(_MSC_VER) && defined(_M_IX86) && !defined(OPENSSL_NO_INLINE_ASM)
+#define LAZY(i)		\
+__declspec(naked) static void lazy##i (void) { 	\
+	_asm	push i				\
+	_asm	push OFFSET OPENSSL_UplinkTable	\
+	_asm	call OPENSSL_Uplink		\
+	_asm	add  esp,8			\
+	_asm	jmp  OPENSSL_UplinkTable+4*i	}
+
+#if APPLINK_MAX>25
+#error "Add more stubs..."
+#endif
+/* make some in advance... */
+LAZY(1)  LAZY(2)  LAZY(3)  LAZY(4)  LAZY(5)
+LAZY(6)  LAZY(7)  LAZY(8)  LAZY(9)  LAZY(10)
+LAZY(11) LAZY(12) LAZY(13) LAZY(14) LAZY(15)
+LAZY(16) LAZY(17) LAZY(18) LAZY(19) LAZY(20)
+LAZY(21) LAZY(22) LAZY(23) LAZY(24) LAZY(25)
+void *OPENSSL_UplinkTable[] = {
+	(void *)APPLINK_MAX,
+	lazy1, lazy2, lazy3, lazy4, lazy5,
+	lazy6, lazy7, lazy8, lazy9, lazy10,
+	lazy11,lazy12,lazy13,lazy14,lazy15,
+	lazy16,lazy17,lazy18,lazy19,lazy20,
+	lazy21,lazy22,lazy23,lazy24,lazy25,
+};
+#endif
+
+#ifdef SELFTEST
+main() {  UP_fprintf(UP_stdout,"hello, world!\n"); }
+#endif
diff --git a/openssl/ms/uplink.h b/openssl/ms/uplink.h
new file mode 100644
index 0000000..a4a67d3
--- /dev/null
+++ b/openssl/ms/uplink.h
@@ -0,0 +1,29 @@
+#define APPMACROS_ONLY
+#include "applink.c"
+
+extern void *OPENSSL_UplinkTable[];
+
+#define UP_stdin  (*(void *(*)(void))OPENSSL_UplinkTable[APPLINK_STDIN])()
+#define UP_stdout (*(void *(*)(void))OPENSSL_UplinkTable[APPLINK_STDOUT])()
+#define UP_stderr (*(void *(*)(void))OPENSSL_UplinkTable[APPLINK_STDERR])()
+#define UP_fprintf (*(int (*)(void *,const char *,...))OPENSSL_UplinkTable[APPLINK_FPRINTF])
+#define UP_fgets  (*(char *(*)(char *,int,void *))OPENSSL_UplinkTable[APPLINK_FGETS])
+#define UP_fread  (*(size_t (*)(void *,size_t,size_t,void *))OPENSSL_UplinkTable[APPLINK_FREAD])
+#define UP_fwrite (*(size_t (*)(const void *,size_t,size_t,void *))OPENSSL_UplinkTable[APPLINK_FWRITE])
+#define UP_fsetmod (*(int (*)(void *,char))OPENSSL_UplinkTable[APPLINK_FSETMOD])
+#define UP_feof   (*(int (*)(void *))OPENSSL_UplinkTable[APPLINK_FEOF])
+#define UP_fclose (*(int (*)(void *))OPENSSL_UplinkTable[APPLINK_FCLOSE])
+
+#define UP_fopen  (*(void *(*)(const char *,const char *))OPENSSL_UplinkTable[APPLINK_FOPEN])
+#define UP_fseek  (*(int (*)(void *,long,int))OPENSSL_UplinkTable[APPLINK_FSEEK])
+#define UP_ftell  (*(long (*)(void *))OPENSSL_UplinkTable[APPLINK_FTELL])
+#define UP_fflush (*(int (*)(void *))OPENSSL_UplinkTable[APPLINK_FFLUSH])
+#define UP_ferror (*(int (*)(void *))OPENSSL_UplinkTable[APPLINK_FERROR])
+#define UP_clearerr (*(void (*)(void *))OPENSSL_UplinkTable[APPLINK_CLEARERR])
+#define UP_fileno (*(int (*)(void *))OPENSSL_UplinkTable[APPLINK_FILENO])
+
+#define UP_open   (*(int (*)(const char *,int,...))OPENSSL_UplinkTable[APPLINK_OPEN])
+#define UP_read   (*(ssize_t (*)(int,void *,size_t))OPENSSL_UplinkTable[APPLINK_READ])
+#define UP_write  (*(ssize_t (*)(int,const void *,size_t))OPENSSL_UplinkTable[APPLINK_WRITE])
+#define UP_lseek  (*(long (*)(int,long,int))OPENSSL_UplinkTable[APPLINK_LSEEK])
+#define UP_close  (*(int (*)(int))OPENSSL_UplinkTable[APPLINK_CLOSE])
diff --git a/openssl/ms/uplink.pl b/openssl/ms/uplink.pl
new file mode 100755
index 0000000..102400e
--- /dev/null
+++ b/openssl/ms/uplink.pl
@@ -0,0 +1,204 @@
+#!/usr/bin/env perl
+#
+# For Microsoft CL this is implemented as inline assembler. So that
+# even though this script can generate even Win32 code, we'll be
+# using it primarily to generate Win64 modules. Both IA-64 and AMD64
+# are supported...
+
+# pull APPLINK_MAX value from applink.c...
+$applink_c=$0;
+$applink_c=~s|[^/\\]+$||g;
+$applink_c.="applink.c";
+open(INPUT,$applink_c) || die "can't open $applink_c: $!";
+@max=grep {/APPLINK_MAX\s+(\d+)/} <INPUT>;
+close(INPUT);
+($#max==0) or die "can't find APPLINK_MAX in $applink_c";
+
+$max[0]=~/APPLINK_MAX\s+(\d+)/;
+$N=$1;	# number of entries in OPENSSL_UplinkTable not including
+	# OPENSSL_UplinkTable[0], which contains this value...
+
+# Idea is to fill the OPENSSL_UplinkTable with pointers to stubs
+# which invoke 'void OPENSSL_Uplink (ULONG_PTR *table,int index)';
+# and then dereference themselves. Latter shall result in endless
+# loop *unless* OPENSSL_Uplink does not replace 'table[index]' with
+# something else, e.g. as 'table[index]=unimplemented;'...
+
+$arg = shift;
+#( defined shift || open STDOUT,">$arg" ) || die "can't open $arg: $!";
+
+if ($arg =~ /win32n/)	{ ia32nasm();  }
+elsif ($arg =~ /win32/)	{ ia32masm();  }
+elsif ($arg =~ /coff/)	{ ia32gas();   }
+elsif ($arg =~ /win64i/ or $arg =~ /ia64/)	{ ia64ias();   }
+elsif ($arg =~ /win64a/ or $arg =~ /amd64/)	{ amd64masm(); }
+else	{ die "nonsense $arg"; }
+
+sub ia32gas() {
+print <<___;
+.text
+___
+for ($i=1;$i<=$N;$i++) {
+print <<___;
+.def	.Lazy$i;	.scl	3;	.type	32;	.endef
+.align	4
+.Lazy$i:
+	pushl	\$$i
+	pushl	\$_OPENSSL_UplinkTable
+	call	_OPENSSL_Uplink
+	addl	\$8,%esp
+	jmp	*(_OPENSSL_UplinkTable+4*$i)
+___
+}
+print <<___;
+.data
+.align	4
+.globl  _OPENSSL_UplinkTable
+_OPENSSL_UplinkTable:
+	.long	$N
+___
+for ($i=1;$i<=$N;$i++) {   print "	.long	.Lazy$i\n";   }
+}
+
+sub ia32masm() {
+print <<___;
+.386P
+.model	FLAT
+
+_DATA	SEGMENT
+PUBLIC	_OPENSSL_UplinkTable
+_OPENSSL_UplinkTable	DD	$N	; amount of following entries
+___
+for ($i=1;$i<=$N;$i++) {   print "	DD	FLAT:\$lazy$i\n";   }
+print <<___;
+_DATA	ENDS
+
+_TEXT	SEGMENT
+EXTRN	_OPENSSL_Uplink:NEAR
+___
+for ($i=1;$i<=$N;$i++) {
+print <<___;
+ALIGN	4
+\$lazy$i	PROC NEAR
+	push	$i
+	push	OFFSET FLAT:_OPENSSL_UplinkTable
+	call	_OPENSSL_Uplink
+	add	esp,8
+	jmp	DWORD PTR _OPENSSL_UplinkTable+4*$i
+\$lazy$i	ENDP
+___
+}
+print <<___;
+ALIGN	4
+_TEXT	ENDS
+END
+___
+}
+
+sub ia32nasm() {
+print <<___;
+SEGMENT	.data
+GLOBAL	_OPENSSL_UplinkTable
+_OPENSSL_UplinkTable	DD	$N	; amount of following entries
+___
+for ($i=1;$i<=$N;$i++) {   print "	DD	\$lazy$i\n";   }
+print <<___;
+
+SEGMENT	.text
+EXTERN	_OPENSSL_Uplink
+___
+for ($i=1;$i<=$N;$i++) {
+print <<___;
+ALIGN	4
+\$lazy$i:
+	push	$i
+	push	_OPENSSL_UplinkTable
+	call	_OPENSSL_Uplink
+	add	esp,8
+	jmp	[_OPENSSL_UplinkTable+4*$i]
+___
+}
+print <<___;
+ALIGN	4
+END
+___
+}
+
+sub ia64ias () {
+local $V=8;	# max number of args uplink functions may accept...
+print <<___;
+.data
+.global	OPENSSL_UplinkTable#
+OPENSSL_UplinkTable:	data8	$N	// amount of following entries
+___
+for ($i=1;$i<=$N;$i++) {   print "	data8	\@fptr(lazy$i#)\n";   }
+print <<___;
+.size	OPENSSL_UplinkTable,.-OPENSSL_UplinkTable#
+
+.text
+.global	OPENSSL_Uplink#
+.type	OPENSSL_Uplink#,\@function
+___
+for ($i=1;$i<=$N;$i++) {
+print <<___;
+.proc	lazy$i
+lazy$i:
+{ .mii;	alloc	loc0=ar.pfs,$V,3,2,0
+	mov	loc1=b0
+	addl	loc2=\@ltoff(OPENSSL_UplinkTable#),gp	};;
+{ .mmi;	ld8	out0=[loc2]
+	mov	out1=$i					};;
+{ .mib;	adds	loc2=8*$i,out0
+	br.call.sptk.many	b0=OPENSSL_Uplink#	};;
+{ .mmi;	ld8	r31=[loc2];;
+	ld8	r30=[r31],8				};;
+{ .mii;	ld8	gp=[r31]
+	mov	b6=r30
+	mov	b0=loc1					};;
+{ .mib; mov	ar.pfs=loc0
+	br.many	b6					};;
+.endp	lazy$i#
+___
+}
+}
+
+sub amd64masm() {
+print <<___;
+_DATA	SEGMENT
+PUBLIC	OPENSSL_UplinkTable
+OPENSSL_UplinkTable	DQ	$N
+___
+for ($i=1;$i<=$N;$i++) {   print "	DQ	\$lazy$i\n";   }
+print <<___;
+_DATA	ENDS
+
+_TEXT	SEGMENT
+EXTERN	OPENSSL_Uplink:PROC
+___
+for ($i=1;$i<=$N;$i++) {
+print <<___;
+ALIGN	4
+\$lazy$i	PROC
+	push	r9
+	push	r8
+	push	rdx
+	push	rcx
+	sub	rsp,40
+	lea	rcx,OFFSET OPENSSL_UplinkTable
+	mov	rdx,$i
+	call	OPENSSL_Uplink
+	add	rsp,40
+	pop	rcx
+	pop	rdx
+	pop	r8
+	pop	r9
+	jmp	QWORD PTR OPENSSL_UplinkTable+8*$i
+\$lazy$i	ENDP
+___
+}
+print <<___;
+_TEXT	ENDS
+END
+___
+}
+
diff --git a/openssl/ms/x86asm.bat b/openssl/ms/x86asm.bat
new file mode 100755
index 0000000..03563c6
--- /dev/null
+++ b/openssl/ms/x86asm.bat
@@ -0,0 +1,57 @@
+
+@echo off
+echo Generating x86 assember
+
+echo Bignum
+cd crypto\bn\asm
+perl x86.pl win32n > bn-win32.asm
+cd ..\..\..
+
+echo DES
+cd crypto\des\asm
+perl des-586.pl win32n > d-win32.asm
+cd ..\..\..
+
+echo "crypt(3)"
+
+cd crypto\des\asm
+perl crypt586.pl win32n > y-win32.asm
+cd ..\..\..
+
+echo Blowfish
+
+cd crypto\bf\asm
+perl bf-586.pl win32n > b-win32.asm
+cd ..\..\..
+
+echo CAST5
+cd crypto\cast\asm
+perl cast-586.pl win32n > c-win32.asm
+cd ..\..\..
+
+echo RC4
+cd crypto\rc4\asm
+perl rc4-586.pl win32n > r4-win32.asm
+cd ..\..\..
+
+echo MD5
+cd crypto\md5\asm
+perl md5-586.pl win32n > m5-win32.asm
+cd ..\..\..
+
+echo SHA1
+cd crypto\sha\asm
+perl sha1-586.pl win32n > s1-win32.asm
+cd ..\..\..
+
+echo RIPEMD160
+cd crypto\ripemd\asm
+perl rmd-586.pl win32n > rm-win32.asm
+cd ..\..\..
+
+echo RC5\32
+cd crypto\rc5\asm
+perl rc5-586.pl win32n > r5-win32.asm
+cd ..\..\..
+
+echo on
diff --git a/openssl/openssl.doxy b/openssl/openssl.doxy
new file mode 100644
index 0000000..479c311
--- /dev/null
+++ b/openssl/openssl.doxy
@@ -0,0 +1,7 @@
+PROJECT_NAME=OpenSSL
+GENERATE_LATEX=no
+OUTPUT_DIRECTORY=doxygen
+INPUT=ssl include
+FILE_PATTERNS=*.c *.h
+RECURSIVE=yes
+PREDEFINED=DOXYGEN
diff --git a/openssl/openssl.spec b/openssl/openssl.spec
new file mode 100644
index 0000000..703cea2
--- /dev/null
+++ b/openssl/openssl.spec
@@ -0,0 +1,213 @@
+%define _unpackaged_files_terminate_build 0
+%define libmaj 1
+%define libmin 0
+%define librel 0
+%define librev f
+Release: 1
+
+%define openssldir /var/ssl
+
+Summary: Secure Sockets Layer and cryptography libraries and tools
+Name: openssl
+#Version: %{libmaj}.%{libmin}.%{librel}
+Version: %{libmaj}.%{libmin}.%{librel}%{librev}
+Source0: ftp://ftp.openssl.org/source/%{name}-%{version}.tar.gz
+Copyright: Freely distributable
+Group: System Environment/Libraries
+Provides: SSL
+URL: http://www.openssl.org/
+Packager: Damien Miller <djm@mindrot.org>
+BuildRoot:   /var/tmp/%{name}-%{version}-root
+
+%description
+The OpenSSL Project is a collaborative effort to develop a robust,
+commercial-grade, fully featured, and Open Source toolkit implementing the
+Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1)
+protocols as well as a full-strength general purpose cryptography library.
+The project is managed by a worldwide community of volunteers that use the
+Internet to communicate, plan, and develop the OpenSSL tookit and its related
+documentation. 
+
+OpenSSL is based on the excellent SSLeay library developed from Eric A.
+Young and Tim J. Hudson.  The OpenSSL toolkit is licensed under an
+Apache-style licence, which basically means that you are free to get and
+use it for commercial and non-commercial purposes. 
+
+This package contains the base OpenSSL cryptography and SSL/TLS 
+libraries and tools.
+
+%package devel
+Summary: Secure Sockets Layer and cryptography static libraries and headers
+Group: Development/Libraries
+Requires: openssl
+%description devel
+The OpenSSL Project is a collaborative effort to develop a robust,
+commercial-grade, fully featured, and Open Source toolkit implementing the
+Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1)
+protocols as well as a full-strength general purpose cryptography library.
+The project is managed by a worldwide community of volunteers that use the
+Internet to communicate, plan, and develop the OpenSSL tookit and its related
+documentation. 
+
+OpenSSL is based on the excellent SSLeay library developed from Eric A.
+Young and Tim J. Hudson.  The OpenSSL toolkit is licensed under an
+Apache-style licence, which basically means that you are free to get and
+use it for commercial and non-commercial purposes. 
+
+This package contains the the OpenSSL cryptography and SSL/TLS 
+static libraries and header files required when developing applications.
+
+%package doc
+Summary: OpenSSL miscellaneous files
+Group: Documentation
+Requires: openssl
+%description doc
+The OpenSSL Project is a collaborative effort to develop a robust,
+commercial-grade, fully featured, and Open Source toolkit implementing the
+Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1)
+protocols as well as a full-strength general purpose cryptography library.
+The project is managed by a worldwide community of volunteers that use the
+Internet to communicate, plan, and develop the OpenSSL tookit and its related
+documentation. 
+
+OpenSSL is based on the excellent SSLeay library developed from Eric A.
+Young and Tim J. Hudson.  The OpenSSL toolkit is licensed under an
+Apache-style licence, which basically means that you are free to get and
+use it for commercial and non-commercial purposes. 
+
+This package contains the the OpenSSL cryptography and SSL/TLS extra
+documentation and POD files from which the man pages were produced.
+
+%prep
+
+%setup -q
+
+%build 
+
+%define CONFIG_FLAGS -DSSL_ALLOW_ADH --prefix=/usr --openssldir=%{openssldir}
+
+perl util/perlpath.pl /usr/bin/perl
+
+%ifarch i386 i486 i586 i686
+./Configure %{CONFIG_FLAGS} linux-elf shared
+%endif
+%ifarch ppc
+./Configure %{CONFIG_FLAGS} linux-ppc shared
+%endif
+%ifarch alpha
+./Configure %{CONFIG_FLAGS} linux-alpha shared
+%endif
+%ifarch x86_64
+./Configure %{CONFIG_FLAGS} linux-x86_64 shared
+%endif
+LD_LIBRARY_PATH=`pwd` make
+LD_LIBRARY_PATH=`pwd` make rehash
+LD_LIBRARY_PATH=`pwd` make test
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make MANDIR=/usr/man MANSUFFIX=ssl INSTALL_PREFIX="$RPM_BUILD_ROOT" install
+
+# Make backwards-compatibility symlink to ssleay
+ln -sf /usr/bin/openssl $RPM_BUILD_ROOT/usr/bin/ssleay
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files 
+%defattr(0644,root,root,0755)
+%doc CHANGES CHANGES.SSLeay LICENSE NEWS README
+
+%attr(0755,root,root) /usr/bin/*
+%attr(0755,root,root) /usr/lib/*.so*
+%attr(0755,root,root) %{openssldir}/misc/*
+%attr(0644,root,root) /usr/man/man[157]/*
+
+%config %attr(0644,root,root) %{openssldir}/openssl.cnf 
+%dir %attr(0755,root,root) %{openssldir}/certs
+%dir %attr(0755,root,root) %{openssldir}/misc
+%dir %attr(0750,root,root) %{openssldir}/private
+
+%files devel
+%defattr(0644,root,root,0755)
+%doc CHANGES CHANGES.SSLeay LICENSE NEWS README
+
+%attr(0644,root,root) /usr/lib/*.a
+%attr(0644,root,root) /usr/lib/pkgconfig/openssl.pc
+%attr(0644,root,root) /usr/include/openssl/*
+%attr(0644,root,root) /usr/man/man[3]/*
+
+%files doc
+%defattr(0644,root,root,0755)
+%doc CHANGES CHANGES.SSLeay LICENSE NEWS README
+%doc doc
+
+%post
+ldconfig
+
+%postun
+ldconfig
+
+%changelog
+* Sun Jun  6 2005 Richard Levitte <richard@levitte.org>
+- Remove the incorrect installation of '%{openssldir}/lib'.
+* Wed May  7 2003 Richard Levitte <richard@levitte.org>
+- Add /usr/lib/pkgconfig/openssl.pc to the development section.
+* Thu Mar 22 2001 Richard Levitte <richard@levitte.org>
+- Removed redundant subsection that re-installed libcrypto.a and libssl.a
+  as well.  Also remove RSAref stuff completely, since it's not needed
+  any more.
+* Thu Mar 15 2001 Jeremiah Johnson <jjohnson@penguincomputing.com>
+- Removed redundant subsection that re-installed libcrypto.so.0.9.6 and
+  libssl.so.0.9.6.  As well as the subsection that created symlinks for
+  these.  make install handles all this.
+* Sat Oct 21 2000 Horms <horms@vergenet.net>
+- Make sure symlinks are created by using -f flag to ln.
+  Otherwise some .so libraries are copied rather than
+  linked in the resulting binary RPM. This causes the package
+  to be larger than neccessary and makes ldconfig complain.
+* Fri Oct 13 2000 Horms <horms@vergenet.net>
+- Make defattr is set for files in all packages so packages built as
+  non-root will still be installed with files owned by root.
+* Thu Sep 14 2000 Richard Levitte <richard@levitte.org>
+- Changed to adapt to the new (supported) way of making shared libraries
+- Installs all static libraries, not just libRSAglue.a
+- Extra documents now end up in a separate document package
+* Sun Feb 27 2000 Damien Miller <djm@mindrot.org>
+- Merged patches to spec
+- Updated to 0.9.5beta2 (now with manpages)
+* Sat Feb  5 2000 Michal Jaegermann <michal@harddata.com>
+- added 'linux-alpha' to configuration
+- fixed nasty absolute links
+* Tue Jan 25 2000 Bennett Todd <bet@rahul.net>
+- Added -DSSL_ALLOW_ADH, bumped Release to 4
+* Thu Oct 14 1999 Damien Miller <djm@mindrot.org>
+- Set default permissions
+- Removed documentation from devel sub-package
+* Thu Sep 30 1999 Damien Miller <djm@mindrot.org>
+- Added "make test" stage
+- GPG signed
+* Tue Sep 10 1999 Damien Miller <damien@ibs.com.au>
+- Updated to version 0.9.4
+* Tue May 25 1999 Damien Miller <damien@ibs.com.au>
+- Updated to version 0.9.3
+- Added attributes for all files
+- Paramatised openssl directory
+* Sat Mar 20 1999 Carlo M. Arenas Belon <carenas@jmconsultores.com.pe>
+- Added "official" bnrec patch and taking other out
+- making a link from ssleay to openssl binary
+- putting all changelog together on SPEC file
+* Fri Mar  5 1999 Henri Gomez <gomez@slib.fr>
+- Added bnrec patch
+* Tue Dec 29 1998 Jonathan Ruano <kobalt@james.encomix.es>
+- minimum spec and patches changes for openssl
+- modified for openssl sources
+* Sat Aug  8 1998 Khimenko Victor <khim@sch57.msk.ru>
+- shared library creating process honours $RPM_OPT_FLAGS
+- shared libarry supports threads (as well as static library)
+* Wed Jul 22 1998 Khimenko Victor <khim@sch57.msk.ru>
+- building of shared library completely reworked
+* Tue Jul 21 1998 Khimenko Victor <khim@sch57.msk.ru>
+- RPM is BuildRoot'ed
+* Tue Feb 10 1998 Khimenko Victor <khim@sch57.msk.ru>
+- all stuff is moved out of /usr/local
diff --git a/openssl/os2/OS2-EMX.cmd b/openssl/os2/OS2-EMX.cmd
new file mode 100644
index 0000000..5924b50
--- /dev/null
+++ b/openssl/os2/OS2-EMX.cmd
@@ -0,0 +1,102 @@
+@echo off
+
+perl Configure OS2-EMX
+perl util\mkfiles.pl > MINFO
+
+@rem create make file
+perl util\mk1mf.pl OS2-EMX > OS2-EMX.mak
+perl util\mk1mf.pl dll OS2-EMX > OS2-EMX-DLL.mak
+
+echo Generating export definition files
+perl util\mkdef.pl crypto OS2 > os2\crypto.def
+perl util\mkdef.pl ssl OS2 > os2\ssl.def
+
+echo Generating x86 for GNU assember
+
+echo Bignum
+cd crypto\bn\asm
+rem perl x86.pl a.out > bn-os2.asm
+perl bn-586.pl a.out > bn-os2.asm 
+perl co-586.pl a.out > co-os2.asm 
+cd ..\..\..
+
+echo DES
+cd crypto\des\asm
+perl des-586.pl a.out > d-os2.asm
+cd ..\..\..
+
+echo crypt(3)
+cd crypto\des\asm
+perl crypt586.pl a.out > y-os2.asm
+cd ..\..\..
+
+echo Blowfish
+cd crypto\bf\asm
+perl bf-586.pl a.out > b-os2.asm
+cd ..\..\..
+
+echo CAST5
+cd crypto\cast\asm
+perl cast-586.pl a.out > c-os2.asm
+cd ..\..\..
+
+echo RC4
+cd crypto\rc4\asm
+perl rc4-586.pl a.out > r4-os2.asm
+cd ..\..\..
+
+echo MD5
+cd crypto\md5\asm
+perl md5-586.pl a.out > m5-os2.asm
+cd ..\..\..
+
+echo SHA1
+cd crypto\sha\asm
+perl sha1-586.pl a.out > s1-os2.asm
+cd ..\..\..
+
+echo RIPEMD160
+cd crypto\ripemd\asm
+perl rmd-586.pl a.out > rm-os2.asm
+cd ..\..\..
+
+echo RC5\32
+cd crypto\rc5\asm
+perl rc5-586.pl a.out > r5-os2.asm
+cd ..\..\..
+
+cd os2
+
+if exist noname\backward_ssl.def goto nomkdir
+mkdir noname
+:nomkdir
+
+perl backwardify.pl		crypto.def	>backward_crypto.def
+perl backwardify.pl		ssl.def		>backward_ssl.def
+perl backwardify.pl -noname	crypto.def	>noname\backward_crypto.def
+perl backwardify.pl -noname	ssl.def		>noname\backward_ssl.def
+
+echo Creating backward compatibility forwarder dlls:
+echo  crypto.dll
+gcc -Zomf -Zdll -Zcrtdll -o crypto.dll backward_crypto.def 2>&1 | grep -v L4085
+echo  ssl.dll
+gcc -Zomf -Zdll -Zcrtdll -o ssl.dll backward_ssl.def 2>&1 | grep -v L4085
+
+echo Creating smaller backward compatibility forwarder dlls:
+echo These DLLs are not good for runtime resolution of symbols.
+echo  noname\crypto.dll
+gcc -Zomf -Zdll -Zcrtdll -o noname/crypto.dll noname/backward_crypto.def 2>&1 | grep -v L4085
+echo  noname\ssl.dll
+gcc -Zomf -Zdll -Zcrtdll -o noname/ssl.dll noname/backward_ssl.def 2>&1 | grep -v L4085
+
+echo Compressing forwarders (it is ok if lxlite is not found):
+lxlite *.dll noname/*.dll
+
+cd ..
+
+echo Now run:
+echo For static build:
+echo  make -f OS2-EMX.mak
+echo For dynamic build:
+echo  make -f OS2-EMX-DLL.mak
+echo then rename crypto.dll to cryptssl.dll, ssl.dll to open_ssl.dll
diff --git a/openssl/os2/backwardify.pl b/openssl/os2/backwardify.pl
new file mode 100644
index 0000000..272423c
--- /dev/null
+++ b/openssl/os2/backwardify.pl
@@ -0,0 +1,32 @@
+#!/usr/bin/perl -w
+use strict;
+
+# Use as $0
+# Use as $0 -noname
+
+my $did_library;
+my $did_description;
+my $do_exports;
+my @imports;
+my $noname = (@ARGV and $ARGV[0] eq '-noname' and shift);
+while (<>) {
+  unless ($did_library) {
+    s/\b(cryptssl)\b/crypto/ and $did_library = $1 if /^LIBRARY\s+cryptssl\b/;
+    s/\b(open_ssl)\b/ssl/    and $did_library = $1 if /^LIBRARY\s+open_ssl\b/;
+  }
+  unless ($did_description) {
+    s&^(DESCRIPTION\s+(['"])).*&${1}\@#www.openssl.org/:#\@forwarder DLL for pre-0.9.7c+ OpenSSL to the new dll naming scheme$2& and $did_description++;
+  }
+  if ($do_exports) {{
+    last unless /\S/;
+    warn, last unless /^ \s* ( \w+ ) \s+ \@(\d+)\s*$/x;
+    push @imports, [$1, $2];
+    s/$/ NONAME/ if $noname;
+  }}
+  $do_exports++ if not $do_exports and /^EXPORTS/;
+  print $_;
+}
+print "IMPORTS\n";
+for my $imp (@imports) {
+  print "\t$imp->[0]=$did_library.$imp->[1]\n";
+}
diff --git a/openssl/shlib/Makefile.hpux10-cc b/openssl/shlib/Makefile.hpux10-cc
new file mode 100644
index 0000000..89c28dc
--- /dev/null
+++ b/openssl/shlib/Makefile.hpux10-cc
@@ -0,0 +1,34 @@
+# Makefile.hpux-cc
+
+major=0.9.8
+
+slib=libssl
+sh_slib=$(slib).sl.$(major)
+
+clib=libcrypto
+sh_clib=$(clib).sl.$(major)
+
+all : $(clib).sl $(slib).sl
+
+
+$(clib)_pic.a : $(clib).a
+	echo "Copying $? to $@"
+	cp -p $? $@
+
+$(slib)_pic.a : $(slib).a
+	echo "Copying $? to $@"
+	cp -p $? $@
+
+$(sh_clib) : $(clib)_pic.a
+	ld -b -s -z +h $@ -o $@ -Fl $(clib)_pic.a -ldld -lc 
+
+$(clib).sl : $(sh_clib)
+	rm -f $@
+	ln -s $? $@
+
+$(sh_slib) : $(slib)_pic.a $(clib).sl
+	ld -b -s -z +h $@ -o $@ -Fl $(slib)_pic.a -ldld -lc
+        
+$(slib).sl : $(sh_slib)
+	rm -f $@
+	ln -s $? $@
diff --git a/openssl/shlib/README b/openssl/shlib/README
new file mode 100644
index 0000000..fea07a5
--- /dev/null
+++ b/openssl/shlib/README
@@ -0,0 +1 @@
+Only the windows NT and, linux builds have been tested for SSLeay 0.8.0
diff --git a/openssl/shlib/hpux10-cc.sh b/openssl/shlib/hpux10-cc.sh
new file mode 100644
index 0000000..ceeb8c5
--- /dev/null
+++ b/openssl/shlib/hpux10-cc.sh
@@ -0,0 +1,92 @@
+#!/usr/bin/sh
+#
+# Run this script from the OpenSSL root directory:
+# sh shlib/hpux10-cc.sh
+# 
+# HP-UX (10.20) shared library installation:
+# Compile and install OpenSSL with best possible optimization:
+# - shared libraries are compiled and installed with +O4 optimization
+# - executable(s) are compiled and installed with +O4 optimization
+# - static libraries are compiled and installed with +O3 optimization,
+#   to avoid the time consuming +O4 link-time optimization when using
+#   these libraries. (The shared libs are already optimized during build
+#   at +O4.)
+#
+# This script must be run with appropriate privileges to install into
+# /usr/local/ssl. HP-UX prevents used executables and shared libraries
+# from being deleted or overwritten. Stop all processes using already
+# installed items of OpenSSL.
+#
+# WARNING: At high optimization levels, HP's ANSI-C compiler can chew up
+#          large amounts of memory and CPU time. Make sure to have at least
+#          128MB of RAM available and that your kernel is configured to allow
+#          at least 128MB data size (maxdsiz parameter which can be obtained
+#          by multiplying 'echo maxdsiz/D | adb -k /stand/vmunix /dev/kmem'
+#          by 'getconf PAGE_SIZE').
+#          The installation process can take several hours, even on fast
+#          machines. +O4 optimization of the libcrypto.sl shared library may
+#          take 1 hour on a C200 (200MHz PA8200 CPU), +O3 compilation of
+#          fcrypt_b.c can take 20 minutes on this machine. Stay patient.
+#
+# SITEFLAGS: site specific flags. I do use +DAportable, since I have to
+# support older PA1.1-type CPUs. Your mileage may vary.
+# +w1 enables enhanced warnings, useful when working with snaphots.
+#
+SITEFLAGS="+DAportable +w1"
+#
+# Set the default additions to build with HP-UX.
+# -D_REENTRANT must/should be defined on HP-UX manually, since we do call
+# Configure directly.
+# +Oall increases the optimization done.
+#
+MYFLAGS="-D_REENTRANT +Oall $SITEFLAGS"
+
+# Configure for pic and build the static pic libraries
+perl5 Configure no-shared hpux-parisc-cc-o4 +Z ${MYFLAGS}
+make clean
+make DIRS="crypto ssl"
+# Rename the static pic libs and build dynamic libraries from them
+# Be prepared to see a lot of warnings about shared libraries being built
+# with optimizations higher than +O2. When using these libraries, it is
+# not possible to replace internal library functions with functions from
+# the program to be linked.
+#
+make -f shlib/Makefile.hpux10-cc
+
+# Copy the libraries to /usr/local/ssl/lib (they have to be in their
+# final location when linking applications).
+# If the directories are still there, no problem.
+mkdir /usr/local
+mkdir /usr/local/ssl
+mkdir /usr/local/ssl/lib
+chmod 444 lib*_pic.a
+chmod 555 lib*.sl.0.9.8
+cp -p lib*_pic.a lib*.sl.0.9.8 /usr/local/ssl/lib
+(cd /usr/local/ssl/lib ; ln -sf libcrypto.sl.0.9.8 libcrypto.sl ; ln -sf libssl.sl.0.9.8 libssl.sl)
+
+# Reconfigure without pic to compile the executables. Unfortunately, while
+# performing this task we have to recompile the library components, even
+# though we use the already installed shared libs anyway.
+#
+perl5 Configure no-shared hpux-parisc-cc-o4 ${MYFLAGS}
+
+make clean
+
+# Hack the Makefiles to pick up the dynamic libraries during linking
+#
+sed 's/^PEX_LIBS=.*$/PEX_LIBS=-L\/usr\/local\/ssl\/lib/' Makefile.ssl >xxx; mv xxx Makefile.ssl
+sed 's/-L\.\.//' apps/Makefile.ssl >xxx; mv xxx apps/Makefile.ssl
+sed 's/-L\.\.//' test/Makefile.ssl >xxx; mv xxx test/Makefile.ssl
+# Build the static libs and the executables in one make.
+make
+# Install everything
+make install
+
+# Finally build the static libs with +O3. This time we only need the libraries,
+# once created, they are simply copied into place.
+#
+perl5 Configure no-shared hpux-parisc-cc ${MYFLAGS}
+make clean
+make DIRS="crypto ssl"
+chmod 644 libcrypto.a libssl.a
+cp -p libcrypto.a libssl.a /usr/local/ssl/lib
diff --git a/openssl/shlib/irix.sh b/openssl/shlib/irix.sh
new file mode 100644
index 0000000..22e4e6a
--- /dev/null
+++ b/openssl/shlib/irix.sh
@@ -0,0 +1,7 @@
+FLAGS="-DTERMIOS -O2 -mips2 -DB_ENDIAN -fomit-frame-pointer -Wall -Iinclude"
+SHFLAGS="-DPIC -fpic"
+
+gcc -c -Icrypto $SHFLAGS $FLAGS -o crypto.o crypto/crypto.c
+ld -shared -o libcrypto.so crypto.o
+gcc -c -Issl $SHFLAGS $FLAGS -o ssl.o ssl/ssl.c
+ld -shared -o libssl.so ssl.o
diff --git a/openssl/shlib/sco5-shared-gcc.sh b/openssl/shlib/sco5-shared-gcc.sh
new file mode 100755
index 0000000..fe4a457
--- /dev/null
+++ b/openssl/shlib/sco5-shared-gcc.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+major="0"
+minor="9.7b"
+
+slib=libssl
+sh_slib=$slib.so.$major.$minor
+
+clib=libcrypto
+sh_clib=$clib.so.$major.$minor
+
+FLAGS="-O3 -fomit-frame-pointer"
+SHFLAGS="-DPIC -fPIC"
+
+touch $sh_clib
+touch $sh_slib
+
+echo collecting all object files for $clib.so
+OBJS=
+find . -name \*.o -print > allobjs
+for obj in `ar t libcrypto.a`
+do
+	OBJS="$OBJS `grep $obj allobjs`"
+done
+
+echo linking $clib.so
+gcc -G -o $sh_clib -h $sh_clib $OBJS -lnsl -lsocket
+
+rm -f $clib.so
+ln -s $sh_clib $clib.so
+
+echo collecting all object files for $slib.so
+OBJS=
+for obj in `ar t libssl.a`
+do
+	OBJS="$OBJS `grep $obj allobjs`"
+done
+
+echo linking $slib.so
+gcc -G -o $sh_slib -h $sh_slib $OBJS -L. -lcrypto
+
+rm -f $slib.so
+ln -s $sh_slib $slib.so
+
+mv libRSAglue.a libRSAglue.a.orig
+mv libcrypto.a  libcrypto.a.orig
+mv libssl.a     libssl.a.orig
+
diff --git a/openssl/shlib/sco5-shared-installed b/openssl/shlib/sco5-shared-installed
new file mode 100755
index 0000000..5099028
--- /dev/null
+++ b/openssl/shlib/sco5-shared-installed
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+major="0"
+minor="9.7b"
+
+slib=libssl
+sh_slib=$slib.so.$major.$minor
+
+clib=libcrypto
+sh_clib=$clib.so.$major.$minor
+
+# If you want them in /usr/local/lib then change INSTALLTOP to point there.
+#INSTALLTOP=/usr/local/ssl/lib
+INSTALLTOP=/usr/local/lib
+
+cp -p $sh_clib $INSTALLTOP
+cp -p $sh_slib $INSTALLTOP
+
+PWD=`pwd`
+cd $INSTALLTOP
+rm -f $INSTALLTOP/$clib.so
+ln -s $INSTALLTOP/$sh_clib $clib.so
+
+rm -f $INSTALLTOP/$slib.so
+ln -s $INSTALLTOP/$sh_slib $slib.so
+
+cd $PWD
+
diff --git a/openssl/shlib/sco5-shared.sh b/openssl/shlib/sco5-shared.sh
new file mode 100755
index 0000000..b3365d9
--- /dev/null
+++ b/openssl/shlib/sco5-shared.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+major="0"
+minor="9.7b"
+
+slib=libssl
+sh_slib=$slib.so.$major.$minor
+
+clib=libcrypto
+sh_clib=$clib.so.$major.$minor
+
+FLAGS="-O -DFILIO_H -Kalloca"
+SHFLAGS="-Kpic -DPIC"
+
+touch $sh_clib
+touch $sh_slib
+
+echo collecting all object files for $clib.so
+OBJS=
+find . -name \*.o -print > allobjs
+for obj in `ar t libcrypto.a`
+do
+	OBJS="$OBJS `grep $obj allobjs`"
+done
+
+echo linking $clib.so
+cc -G -o $sh_clib -h $sh_clib $OBJS -lnsl -lsocket
+
+rm -f $clib.so
+ln -s $sh_clib $clib.so
+
+echo collecting all object files for $slib.so
+OBJS=
+for obj in `ar t libssl.a`
+do
+	OBJS="$OBJS `grep $obj allobjs`"
+done
+
+echo linking $slib.so
+cc -G -o $sh_slib -h $sh_slib $OBJS -L. -lcrypto
+
+rm -f $slib.so
+ln -s $sh_slib $slib.so
+
+mv libRSAglue.a libRSAglue.a.orig
+mv libcrypto.a  libcrypto.a.orig
+mv libssl.a     libssl.a.orig
+
diff --git a/openssl/shlib/solaris-sc4.sh b/openssl/shlib/solaris-sc4.sh
new file mode 100755
index 0000000..b0766b3
--- /dev/null
+++ b/openssl/shlib/solaris-sc4.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+major="1"
+
+slib=libssl
+sh_slib=$slib.so.$major
+
+clib=libcrypto
+sh_clib=$clib.so.$major
+
+echo collecting all object files for $clib.so
+OBJS=
+find . -name \*.o -print > allobjs
+for obj in `ar t libcrypto.a`
+do
+	OBJS="$OBJS `grep $obj allobjs`"
+done
+
+echo linking $clib.so
+cc -G -o $sh_clib -h $sh_clib $OBJS -lnsl -lsocket
+
+rm -f $clib.so
+ln -s $sh_clib $clib.so
+
+echo collecting all object files for $slib.so
+OBJS=
+for obj in `ar t libssl.a`
+do
+	OBJS="$OBJS `grep $obj allobjs`"
+done
+
+echo linking $slib.so
+cc -G -o $sh_slib -h $sh_slib $OBJS -L. -lcrypto
+	
+rm -f $slib.so
+ln -s $sh_slib $slib.so
+
+rm -f allobjs
+
+mv libRSAglue.a libRSAglue.a.orig
+mv libcrypto.a  libcrypto.a.orig
+mv libssl.a     libssl.a.orig 
diff --git a/openssl/shlib/solaris.sh b/openssl/shlib/solaris.sh
new file mode 100644
index 0000000..03475f1
--- /dev/null
+++ b/openssl/shlib/solaris.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+echo "#define DATE      \"`date`\"" >crypto/date.h
+
+major="0"
+minor="8.0"
+slib=libssl
+clib=libcrypto
+CC=gcc
+CPP='gcc -E'
+AS=as
+#FLAGS='-DTERMIO -O3 -DL_ENDIAN -fomit-frame-pointer -mv8 -Wall'
+FLAGS='-DTERMIO -g2 -ggdb -DL_ENDIAN -Wall -DREF_CHECK -DCRYPTO_MDEBUG'
+INCLUDE='-Iinclude -Icrypto -Issl'
+SHFLAGS='-DPIC -fpic'
+
+CFLAGS="$FLAGS $INCLUDE $SHFLAGS"
+ASM_OBJ="";
+
+echo compiling bignum assember
+$AS -o bn_asm.o crypto/bn/asm/sparc.s
+CFLAGS="$CFLAGS -DBN_ASM"
+ASM_OBJ="$ASM_OBJ bn_asm.o"
+
+echo compiling $clib
+$CC -c $CFLAGS -DCFLAGS="\"$FLAGS\"" -o crypto.o crypto/crypto.c
+
+echo linking $clib.so
+gcc $CFLAGS -shared -o $clib.so.$major.$minor crypto.o $ASM_OBJ -lnsl -lsocket
+
+echo compiling $slib.so
+$CC -c $CFLAGS -o ssl.o ssl/ssl.c
+
+echo building $slib.so
+gcc $CFLAGS -shared -o $slib.so ssl.o -L. -lcrypto
+
diff --git a/openssl/shlib/sun.sh b/openssl/shlib/sun.sh
new file mode 100644
index 0000000..a890bbd
--- /dev/null
+++ b/openssl/shlib/sun.sh
@@ -0,0 +1,8 @@
+FLAGS="-DTERMIO -O3 -DB_ENDIAN -fomit-frame-pointer -mv8 -Wall -Iinclude"
+SHFLAGS="-DPIC -fpic"
+
+gcc -c -Icrypto $SHFLAGS -fpic $FLAGS -o crypto.o crypto/crypto.c
+ld -G -z text -o libcrypto.so crypto.o
+
+gcc -c -Issl $SHFLAGS $FLAGS -o ssl.o ssl/ssl.c
+ld -G -z text -o libssl.so ssl.o
diff --git a/openssl/shlib/svr5-shared-gcc.sh b/openssl/shlib/svr5-shared-gcc.sh
new file mode 100755
index 0000000..c5d0cc5
--- /dev/null
+++ b/openssl/shlib/svr5-shared-gcc.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/sh
+
+major="0"
+minor="9.7b"
+
+slib=libssl
+sh_slib=$slib.so.$major.$minor
+
+clib=libcrypto
+sh_clib=$clib.so.$major.$minor
+
+FLAGS="-O3 -DFILIO_H -fomit-frame-pointer -pthread"
+SHFLAGS="-DPIC -fPIC"
+
+touch $sh_clib
+touch $sh_slib
+
+echo collecting all object files for $clib.so
+OBJS=
+find . -name \*.o -print > allobjs
+for obj in `ar t libcrypto.a`
+do
+	OBJS="$OBJS `grep $obj allobjs`"
+done
+
+echo linking $clib.so
+gcc -G -o $sh_clib -h $sh_clib $OBJS -lnsl -lsocket
+
+rm -f $clib.so
+ln -s $sh_clib $clib.so
+
+echo collecting all object files for $slib.so
+OBJS=
+for obj in `ar t libssl.a`
+do
+	OBJS="$OBJS `grep $obj allobjs`"
+done
+
+echo linking $slib.so
+gcc -G -o $sh_slib -h $sh_slib $OBJS -L. -lcrypto
+
+rm -f $slib.so
+ln -s $sh_slib $slib.so
+
+mv libRSAglue.a libRSAglue.a.orig
+mv libcrypto.a  libcrypto.a.orig
+mv libssl.a     libssl.a.orig
+
diff --git a/openssl/shlib/svr5-shared-installed b/openssl/shlib/svr5-shared-installed
new file mode 100755
index 0000000..b1def35
--- /dev/null
+++ b/openssl/shlib/svr5-shared-installed
@@ -0,0 +1,27 @@
+#!/usr/bin/sh
+
+major="0"
+minor="9.7b"
+
+slib=libssl
+sh_slib=$slib.so.$major.$minor
+
+clib=libcrypto
+sh_clib=$clib.so.$major.$minor
+
+# If you want them in /usr/local/lib then change INSTALLTOP to point there.
+#INSTALLTOP=/usr/local/ssl/lib
+INSTALLTOP=/usr/local/lib
+
+cp -p $sh_clib $INSTALLTOP
+cp -p $sh_slib $INSTALLTOP
+
+PWD=`pwd`
+cd $INSTALLTOP
+rm -f $INSTALLTOP/$clib.so
+ln -s $INSTALLTOP/$sh_clib $clib.so
+
+rm -f $INSTALLTOP/$slib.so
+ln -s $INSTALLTOP/$sh_slib $slib.so
+
+cd $PWD
diff --git a/openssl/shlib/svr5-shared.sh b/openssl/shlib/svr5-shared.sh
new file mode 100755
index 0000000..9edf26e
--- /dev/null
+++ b/openssl/shlib/svr5-shared.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/sh
+
+major="0"
+minor="9.7b"
+
+slib=libssl
+sh_slib=$slib.so.$major.$minor
+
+clib=libcrypto
+sh_clib=$clib.so.$major.$minor
+
+FLAGS="-O -DFILIO_H -Kalloca -Kthread"
+SHFLAGS="-Kpic -DPIC"
+
+touch $sh_clib
+touch $sh_slib
+
+echo collecting all object files for $clib.so
+OBJS=
+find . -name \*.o -print > allobjs
+for obj in `ar t libcrypto.a`
+do
+	OBJS="$OBJS `grep $obj allobjs`"
+done
+
+echo linking $clib.so
+cc -G -o $sh_clib -h $sh_clib $OBJS -lnsl -lsocket
+
+rm -f $clib.so
+ln -s $sh_clib $clib.so
+
+echo collecting all object files for $slib.so
+OBJS=
+for obj in `ar t libssl.a`
+do
+	OBJS="$OBJS `grep $obj allobjs`"
+done
+
+echo linking $slib.so
+cc -G -o $sh_slib -h $sh_slib $OBJS -L. -lcrypto
+
+rm -f $slib.so
+ln -s $sh_slib $slib.so
+
+mv libRSAglue.a libRSAglue.a.orig
+mv libcrypto.a  libcrypto.a.orig
+mv libssl.a     libssl.a.orig
+
diff --git a/openssl/shlib/win32.bat b/openssl/shlib/win32.bat
new file mode 100755
index 0000000..2b0faaa
--- /dev/null
+++ b/openssl/shlib/win32.bat
@@ -0,0 +1,18 @@
+rem win32 dll build
+
+set OPTIONS1=-DDES_ASM -DBN_ASM -DBF_ASM -DFLAT_INC -Iout -Itmp -DL_ENDIAN
+set OPTIONS2=/W3 /WX /Ox /Gs0 /GF /Gy /nologo
+
+set OPTIONS=%OPTIONS1% %OPTIONS2%
+
+rem ml /coff /c crypto\bf\asm\b-win32.asm
+rem ml /coff /c crypto\des\asm\c-win32.asm
+rem ml /coff /c crypto\des\asm\d-win32.asm
+rem ml /coff /c crypto\bn\asm\x86nt32.asm
+
+cl /Focrypto.obj -DWIN32 %OPTIONS% -c crypto\crypto.c
+cl /Fossl.obj -DWIN32 %OPTIONS% -c ssl\ssl.c
+cl /Foeay.obj -DWIN32 %OPTIONS% -c apps\eay.c
+
+cl /Fessleay.exe %OPTIONS% eay.obj ssl.obj crypto.obj crypto\bf\asm\b-win32.obj crypto\des\asm\c-win32.obj crypto\des\asm\d-win32.obj crypto\bn\asm\x86nt32.obj user32.lib gdi32.lib ws2_32.lib
+
diff --git a/openssl/shlib/win32dll.bat b/openssl/shlib/win32dll.bat
new file mode 100755
index 0000000..844e353
--- /dev/null
+++ b/openssl/shlib/win32dll.bat
@@ -0,0 +1,13 @@
+rem win32 dll build
+
+set OPTIONS1=-DDES_ASM -DBN_ASM -DBF_ASM -DFLAT_INC -Iout -Itmp -DL_ENDIAN
+set OPTIONS2=/W3 /WX /Ox /Gf /nologo
+
+set OPTIONS=%OPTIONS1% %OPTIONS2%
+
+cl /Felibeay32.dll /GD /MD /LD -DWIN32 %OPTIONS% ms\libeay32.def crypto\crypto.c crypto\bf\asm\b-win32.obj crypto\des\asm\c-win32.obj crypto\des\asm\d-win32.obj crypto\bn\asm\x86nt32.obj user32.lib gdi32.lib ws2_32.lib
+
+cl /Fessleay32.dll /GD /MD /LD -DWIN32 %OPTIONS% ms\ssleay32.def ssl\ssl.c libeay32.lib
+
+cl /Fessleay.exe /MD -DWIN32 %OPTIONS% apps\eay.c ssleay32.lib libeay32.lib user32.lib ws2_32.lib
+
diff --git a/openssl/ssl/Makefile b/openssl/ssl/Makefile
new file mode 100644
index 0000000..2b275fa
--- /dev/null
+++ b/openssl/ssl/Makefile
@@ -0,0 +1,975 @@
+#
+# OpenSSL/ssl/Makefile
+#
+
+DIR=	ssl
+TOP=	..
+CC=	cc
+INCLUDES= -I../crypto -I$(TOP) -I../include $(KRB5_INCLUDES)
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+# KRB5 stuff
+KRB5_INCLUDES=
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile README ssl-lib.com install.com
+TEST=ssltest.c
+APPS=
+
+LIB=$(TOP)/libssl.a
+SHARED_LIB= libssl$(SHLIB_EXT)
+LIBSRC=	\
+	s2_meth.c   s2_srvr.c s2_clnt.c  s2_lib.c  s2_enc.c s2_pkt.c \
+	s3_meth.c   s3_srvr.c s3_clnt.c  s3_lib.c  s3_enc.c s3_pkt.c s3_both.c \
+	s23_meth.c s23_srvr.c s23_clnt.c s23_lib.c          s23_pkt.c \
+	t1_meth.c   t1_srvr.c t1_clnt.c  t1_lib.c  t1_enc.c \
+	d1_meth.c   d1_srvr.c d1_clnt.c  d1_lib.c  d1_pkt.c \
+	d1_both.c d1_enc.c \
+	ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \
+	ssl_ciph.c ssl_stat.c ssl_rsa.c \
+	ssl_asn1.c ssl_txt.c ssl_algs.c \
+	bio_ssl.c ssl_err.c kssl.c t1_reneg.c
+LIBOBJ= \
+	s2_meth.o  s2_srvr.o  s2_clnt.o  s2_lib.o  s2_enc.o s2_pkt.o \
+	s3_meth.o  s3_srvr.o  s3_clnt.o  s3_lib.o  s3_enc.o s3_pkt.o s3_both.o \
+	s23_meth.o s23_srvr.o s23_clnt.o s23_lib.o          s23_pkt.o \
+	t1_meth.o   t1_srvr.o t1_clnt.o  t1_lib.o  t1_enc.o \
+	d1_meth.o   d1_srvr.o d1_clnt.o  d1_lib.o  d1_pkt.o \
+	d1_both.o d1_enc.o \
+	ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \
+	ssl_ciph.o ssl_stat.o ssl_rsa.o \
+	ssl_asn1.o ssl_txt.o ssl_algs.o \
+	bio_ssl.o ssl_err.o kssl.o t1_reneg.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= ssl.h ssl2.h ssl3.h ssl23.h tls1.h dtls1.h kssl.h
+HEADER=	$(EXHEADER) ssl_locl.h kssl_lcl.h
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ..; $(MAKE) DIRS=$(DIR) all)
+
+all:	shared
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+shared: lib
+	if [ -n "$(SHARED_LIBS)" ]; then \
+		(cd ..; $(MAKE) $(SHARED_LIB)); \
+	fi
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@if [ -z "$(THIS)" ]; then \
+	    $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
+	else \
+	    $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC); \
+	fi
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+bio_ssl.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+bio_ssl.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+bio_ssl.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
+bio_ssl.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+bio_ssl.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+bio_ssl.o: ../include/openssl/err.h ../include/openssl/evp.h
+bio_ssl.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+bio_ssl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+bio_ssl.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+bio_ssl.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+bio_ssl.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+bio_ssl.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+bio_ssl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+bio_ssl.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+bio_ssl.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+bio_ssl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+bio_ssl.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+bio_ssl.o: ../include/openssl/x509_vfy.h bio_ssl.c
+d1_both.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+d1_both.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+d1_both.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+d1_both.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+d1_both.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+d1_both.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+d1_both.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+d1_both.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+d1_both.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+d1_both.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+d1_both.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+d1_both.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+d1_both.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+d1_both.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+d1_both.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+d1_both.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+d1_both.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+d1_both.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+d1_both.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_both.c
+d1_both.o: ssl_locl.h
+d1_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+d1_clnt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+d1_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
+d1_clnt.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+d1_clnt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+d1_clnt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+d1_clnt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+d1_clnt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+d1_clnt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+d1_clnt.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+d1_clnt.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+d1_clnt.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+d1_clnt.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+d1_clnt.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+d1_clnt.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+d1_clnt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+d1_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+d1_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+d1_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+d1_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+d1_clnt.o: ../include/openssl/x509_vfy.h d1_clnt.c kssl_lcl.h ssl_locl.h
+d1_enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+d1_enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+d1_enc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+d1_enc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+d1_enc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+d1_enc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+d1_enc.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+d1_enc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+d1_enc.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+d1_enc.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+d1_enc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+d1_enc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+d1_enc.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+d1_enc.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+d1_enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+d1_enc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+d1_enc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+d1_enc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+d1_enc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+d1_enc.o: ../include/openssl/x509_vfy.h d1_enc.c ssl_locl.h
+d1_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+d1_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+d1_lib.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+d1_lib.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+d1_lib.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+d1_lib.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+d1_lib.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+d1_lib.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+d1_lib.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+d1_lib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+d1_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+d1_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+d1_lib.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+d1_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+d1_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+d1_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+d1_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+d1_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+d1_lib.o: ../include/openssl/x509_vfy.h d1_lib.c ssl_locl.h
+d1_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+d1_meth.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+d1_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+d1_meth.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+d1_meth.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+d1_meth.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+d1_meth.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+d1_meth.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+d1_meth.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+d1_meth.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+d1_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+d1_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+d1_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+d1_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+d1_meth.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+d1_meth.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+d1_meth.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+d1_meth.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+d1_meth.o: ../include/openssl/x509_vfy.h d1_meth.c ssl_locl.h
+d1_pkt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+d1_pkt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+d1_pkt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+d1_pkt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+d1_pkt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+d1_pkt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+d1_pkt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+d1_pkt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+d1_pkt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+d1_pkt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+d1_pkt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+d1_pkt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+d1_pkt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+d1_pkt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+d1_pkt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+d1_pkt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+d1_pkt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+d1_pkt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+d1_pkt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_pkt.c
+d1_pkt.o: ssl_locl.h
+d1_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+d1_srvr.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+d1_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
+d1_srvr.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+d1_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+d1_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+d1_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+d1_srvr.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+d1_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+d1_srvr.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+d1_srvr.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+d1_srvr.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+d1_srvr.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+d1_srvr.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+d1_srvr.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+d1_srvr.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+d1_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+d1_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+d1_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+d1_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+d1_srvr.o: ../include/openssl/x509_vfy.h d1_srvr.c ssl_locl.h
+kssl.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+kssl.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+kssl.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
+kssl.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+kssl.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+kssl.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+kssl.o: ../include/openssl/krb5_asn.h ../include/openssl/kssl.h
+kssl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+kssl.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+kssl.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+kssl.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+kssl.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+kssl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+kssl.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+kssl.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+kssl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+kssl.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+kssl.o: ../include/openssl/x509_vfy.h kssl.c kssl_lcl.h
+s23_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s23_clnt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s23_clnt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s23_clnt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s23_clnt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s23_clnt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s23_clnt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s23_clnt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s23_clnt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s23_clnt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s23_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s23_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s23_clnt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s23_clnt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s23_clnt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s23_clnt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s23_clnt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s23_clnt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s23_clnt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_clnt.c
+s23_clnt.o: ssl_locl.h
+s23_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s23_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s23_lib.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s23_lib.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s23_lib.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s23_lib.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s23_lib.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s23_lib.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s23_lib.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s23_lib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s23_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s23_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s23_lib.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s23_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s23_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s23_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s23_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s23_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s23_lib.o: ../include/openssl/x509_vfy.h s23_lib.c ssl_locl.h
+s23_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s23_meth.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s23_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s23_meth.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s23_meth.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s23_meth.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s23_meth.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s23_meth.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s23_meth.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s23_meth.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s23_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s23_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s23_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s23_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s23_meth.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s23_meth.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s23_meth.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s23_meth.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s23_meth.o: ../include/openssl/x509_vfy.h s23_meth.c ssl_locl.h
+s23_pkt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s23_pkt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s23_pkt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s23_pkt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s23_pkt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s23_pkt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s23_pkt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s23_pkt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s23_pkt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s23_pkt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s23_pkt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s23_pkt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s23_pkt.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s23_pkt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s23_pkt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s23_pkt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s23_pkt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s23_pkt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s23_pkt.o: ../include/openssl/x509_vfy.h s23_pkt.c ssl_locl.h
+s23_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s23_srvr.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s23_srvr.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s23_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s23_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s23_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s23_srvr.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s23_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s23_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s23_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s23_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s23_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s23_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s23_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s23_srvr.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s23_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s23_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s23_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s23_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_srvr.c
+s23_srvr.o: ssl_locl.h
+s2_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s2_clnt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s2_clnt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s2_clnt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s2_clnt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s2_clnt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s2_clnt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s2_clnt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s2_clnt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s2_clnt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s2_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s2_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s2_clnt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s2_clnt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s2_clnt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s2_clnt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s2_clnt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s2_clnt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s2_clnt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_clnt.c
+s2_clnt.o: ssl_locl.h
+s2_enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s2_enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s2_enc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s2_enc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s2_enc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s2_enc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s2_enc.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s2_enc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s2_enc.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s2_enc.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s2_enc.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s2_enc.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s2_enc.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s2_enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s2_enc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s2_enc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s2_enc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s2_enc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s2_enc.o: ../include/openssl/x509_vfy.h s2_enc.c ssl_locl.h
+s2_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s2_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s2_lib.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s2_lib.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s2_lib.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s2_lib.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s2_lib.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s2_lib.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s2_lib.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+s2_lib.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+s2_lib.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+s2_lib.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+s2_lib.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+s2_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s2_lib.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s2_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s2_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s2_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s2_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_lib.c
+s2_lib.o: ssl_locl.h
+s2_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s2_meth.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s2_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s2_meth.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s2_meth.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s2_meth.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s2_meth.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s2_meth.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s2_meth.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s2_meth.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s2_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s2_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s2_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s2_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s2_meth.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s2_meth.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s2_meth.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s2_meth.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s2_meth.o: ../include/openssl/x509_vfy.h s2_meth.c ssl_locl.h
+s2_pkt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s2_pkt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s2_pkt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s2_pkt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s2_pkt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s2_pkt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s2_pkt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s2_pkt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s2_pkt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s2_pkt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s2_pkt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s2_pkt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s2_pkt.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s2_pkt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s2_pkt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s2_pkt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s2_pkt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s2_pkt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s2_pkt.o: ../include/openssl/x509_vfy.h s2_pkt.c ssl_locl.h
+s2_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s2_srvr.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s2_srvr.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s2_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s2_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s2_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s2_srvr.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s2_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s2_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s2_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s2_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s2_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s2_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s2_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s2_srvr.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s2_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s2_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s2_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s2_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_srvr.c
+s2_srvr.o: ssl_locl.h
+s3_both.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s3_both.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s3_both.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s3_both.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s3_both.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s3_both.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s3_both.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s3_both.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s3_both.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s3_both.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s3_both.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s3_both.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s3_both.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s3_both.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s3_both.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s3_both.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s3_both.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s3_both.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s3_both.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_both.c
+s3_both.o: ssl_locl.h
+s3_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s3_clnt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+s3_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
+s3_clnt.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+s3_clnt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s3_clnt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s3_clnt.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+s3_clnt.o: ../include/openssl/err.h ../include/openssl/evp.h
+s3_clnt.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+s3_clnt.o: ../include/openssl/lhash.h ../include/openssl/md5.h
+s3_clnt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s3_clnt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s3_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s3_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s3_clnt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s3_clnt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s3_clnt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s3_clnt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s3_clnt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s3_clnt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s3_clnt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl_lcl.h
+s3_clnt.o: s3_clnt.c ssl_locl.h
+s3_enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s3_enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s3_enc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s3_enc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s3_enc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s3_enc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s3_enc.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s3_enc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s3_enc.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+s3_enc.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+s3_enc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+s3_enc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+s3_enc.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+s3_enc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s3_enc.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s3_enc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s3_enc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s3_enc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s3_enc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_enc.c
+s3_enc.o: ssl_locl.h
+s3_lib.o: ../crypto/ec/ec_lcl.h ../e_os.h ../include/openssl/asn1.h
+s3_lib.o: ../include/openssl/bio.h ../include/openssl/bn.h
+s3_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s3_lib.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+s3_lib.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
+s3_lib.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+s3_lib.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+s3_lib.o: ../include/openssl/err.h ../include/openssl/evp.h
+s3_lib.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+s3_lib.o: ../include/openssl/lhash.h ../include/openssl/md5.h
+s3_lib.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s3_lib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s3_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s3_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s3_lib.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s3_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s3_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s3_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s3_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s3_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s3_lib.o: ../include/openssl/x509_vfy.h kssl_lcl.h s3_lib.c ssl_locl.h
+s3_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s3_meth.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s3_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s3_meth.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s3_meth.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s3_meth.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s3_meth.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s3_meth.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s3_meth.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s3_meth.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s3_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s3_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s3_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s3_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s3_meth.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s3_meth.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s3_meth.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s3_meth.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s3_meth.o: ../include/openssl/x509_vfy.h s3_meth.c ssl_locl.h
+s3_pkt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s3_pkt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s3_pkt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s3_pkt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s3_pkt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s3_pkt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s3_pkt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s3_pkt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s3_pkt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s3_pkt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s3_pkt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s3_pkt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s3_pkt.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s3_pkt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s3_pkt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s3_pkt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s3_pkt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s3_pkt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s3_pkt.o: ../include/openssl/x509_vfy.h s3_pkt.c ssl_locl.h
+s3_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+s3_srvr.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+s3_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
+s3_srvr.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+s3_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s3_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s3_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s3_srvr.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+s3_srvr.o: ../include/openssl/krb5_asn.h ../include/openssl/kssl.h
+s3_srvr.o: ../include/openssl/lhash.h ../include/openssl/md5.h
+s3_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s3_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s3_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s3_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s3_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s3_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s3_srvr.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s3_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s3_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s3_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s3_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl_lcl.h
+s3_srvr.o: s3_srvr.c ssl_locl.h
+ssl_algs.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ssl_algs.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ssl_algs.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+ssl_algs.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ssl_algs.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ssl_algs.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+ssl_algs.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+ssl_algs.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+ssl_algs.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ssl_algs.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ssl_algs.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ssl_algs.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ssl_algs.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+ssl_algs.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssl_algs.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_algs.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_algs.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_algs.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_algs.o: ../include/openssl/x509_vfy.h ssl_algs.c ssl_locl.h
+ssl_asn1.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/asn1_mac.h
+ssl_asn1.o: ../include/openssl/bio.h ../include/openssl/buffer.h
+ssl_asn1.o: ../include/openssl/comp.h ../include/openssl/crypto.h
+ssl_asn1.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
+ssl_asn1.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ssl_asn1.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+ssl_asn1.o: ../include/openssl/err.h ../include/openssl/evp.h
+ssl_asn1.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+ssl_asn1.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ssl_asn1.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+ssl_asn1.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ssl_asn1.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+ssl_asn1.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+ssl_asn1.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+ssl_asn1.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+ssl_asn1.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ssl_asn1.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ssl_asn1.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ssl_asn1.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_asn1.c
+ssl_asn1.o: ssl_locl.h
+ssl_cert.o: ../crypto/o_dir.h ../e_os.h ../include/openssl/asn1.h
+ssl_cert.o: ../include/openssl/bio.h ../include/openssl/bn.h
+ssl_cert.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ssl_cert.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+ssl_cert.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+ssl_cert.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ssl_cert.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ssl_cert.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+ssl_cert.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+ssl_cert.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+ssl_cert.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ssl_cert.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ssl_cert.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ssl_cert.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ssl_cert.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+ssl_cert.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssl_cert.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_cert.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_cert.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_cert.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_cert.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h
+ssl_cert.o: ssl_cert.c ssl_locl.h
+ssl_ciph.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ssl_ciph.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ssl_ciph.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+ssl_ciph.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ssl_ciph.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ssl_ciph.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+ssl_ciph.o: ../include/openssl/err.h ../include/openssl/evp.h
+ssl_ciph.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+ssl_ciph.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ssl_ciph.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+ssl_ciph.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ssl_ciph.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+ssl_ciph.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+ssl_ciph.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+ssl_ciph.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+ssl_ciph.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ssl_ciph.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ssl_ciph.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ssl_ciph.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_ciph.c
+ssl_ciph.o: ssl_locl.h
+ssl_err.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+ssl_err.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ssl_err.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
+ssl_err.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ssl_err.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+ssl_err.o: ../include/openssl/err.h ../include/openssl/evp.h
+ssl_err.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+ssl_err.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ssl_err.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+ssl_err.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ssl_err.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+ssl_err.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+ssl_err.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssl_err.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_err.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_err.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_err.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_err.o: ../include/openssl/x509_vfy.h ssl_err.c
+ssl_err2.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+ssl_err2.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ssl_err2.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
+ssl_err2.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ssl_err2.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+ssl_err2.o: ../include/openssl/err.h ../include/openssl/evp.h
+ssl_err2.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+ssl_err2.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ssl_err2.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+ssl_err2.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ssl_err2.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+ssl_err2.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+ssl_err2.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssl_err2.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_err2.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_err2.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_err2.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_err2.o: ../include/openssl/x509_vfy.h ssl_err2.c
+ssl_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ssl_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ssl_lib.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+ssl_lib.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+ssl_lib.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ssl_lib.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ssl_lib.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+ssl_lib.o: ../include/openssl/err.h ../include/openssl/evp.h
+ssl_lib.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+ssl_lib.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ssl_lib.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+ssl_lib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ssl_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ssl_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ssl_lib.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+ssl_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+ssl_lib.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+ssl_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ssl_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ssl_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ssl_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+ssl_lib.o: ../include/openssl/x509v3.h kssl_lcl.h ssl_lib.c ssl_locl.h
+ssl_rsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ssl_rsa.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ssl_rsa.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+ssl_rsa.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ssl_rsa.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ssl_rsa.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+ssl_rsa.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+ssl_rsa.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+ssl_rsa.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ssl_rsa.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ssl_rsa.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ssl_rsa.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ssl_rsa.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+ssl_rsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssl_rsa.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_rsa.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_rsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_rsa.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_rsa.o: ../include/openssl/x509_vfy.h ssl_locl.h ssl_rsa.c
+ssl_sess.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ssl_sess.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ssl_sess.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+ssl_sess.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ssl_sess.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ssl_sess.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+ssl_sess.o: ../include/openssl/err.h ../include/openssl/evp.h
+ssl_sess.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+ssl_sess.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ssl_sess.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+ssl_sess.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ssl_sess.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+ssl_sess.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+ssl_sess.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+ssl_sess.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssl_sess.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_sess.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_sess.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_sess.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_sess.o: ../include/openssl/x509_vfy.h ssl_locl.h ssl_sess.c
+ssl_stat.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ssl_stat.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ssl_stat.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+ssl_stat.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ssl_stat.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ssl_stat.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+ssl_stat.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+ssl_stat.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+ssl_stat.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ssl_stat.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ssl_stat.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ssl_stat.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ssl_stat.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+ssl_stat.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssl_stat.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_stat.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_stat.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_stat.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_stat.o: ../include/openssl/x509_vfy.h ssl_locl.h ssl_stat.c
+ssl_txt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ssl_txt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ssl_txt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+ssl_txt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ssl_txt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ssl_txt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+ssl_txt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+ssl_txt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+ssl_txt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ssl_txt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ssl_txt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ssl_txt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ssl_txt.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+ssl_txt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssl_txt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_txt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_txt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_txt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_txt.o: ../include/openssl/x509_vfy.h ssl_locl.h ssl_txt.c
+t1_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+t1_clnt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+t1_clnt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+t1_clnt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+t1_clnt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+t1_clnt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+t1_clnt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+t1_clnt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+t1_clnt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+t1_clnt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+t1_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+t1_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+t1_clnt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+t1_clnt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+t1_clnt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+t1_clnt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+t1_clnt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+t1_clnt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+t1_clnt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
+t1_clnt.o: t1_clnt.c
+t1_enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+t1_enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+t1_enc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+t1_enc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+t1_enc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+t1_enc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+t1_enc.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+t1_enc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+t1_enc.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+t1_enc.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+t1_enc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+t1_enc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+t1_enc.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+t1_enc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+t1_enc.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+t1_enc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+t1_enc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+t1_enc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+t1_enc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
+t1_enc.o: t1_enc.c
+t1_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+t1_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+t1_lib.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+t1_lib.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
+t1_lib.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+t1_lib.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+t1_lib.o: ../include/openssl/err.h ../include/openssl/evp.h
+t1_lib.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+t1_lib.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+t1_lib.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+t1_lib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+t1_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+t1_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+t1_lib.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+t1_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+t1_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+t1_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+t1_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+t1_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+t1_lib.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h ssl_locl.h
+t1_lib.o: t1_lib.c
+t1_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+t1_meth.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+t1_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+t1_meth.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+t1_meth.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+t1_meth.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+t1_meth.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+t1_meth.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+t1_meth.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+t1_meth.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+t1_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+t1_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+t1_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+t1_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+t1_meth.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+t1_meth.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+t1_meth.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+t1_meth.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+t1_meth.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_meth.c
+t1_reneg.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+t1_reneg.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+t1_reneg.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+t1_reneg.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+t1_reneg.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+t1_reneg.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+t1_reneg.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+t1_reneg.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+t1_reneg.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+t1_reneg.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+t1_reneg.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+t1_reneg.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+t1_reneg.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+t1_reneg.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+t1_reneg.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+t1_reneg.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+t1_reneg.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+t1_reneg.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+t1_reneg.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_reneg.c
+t1_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+t1_srvr.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+t1_srvr.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+t1_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+t1_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+t1_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+t1_srvr.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+t1_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+t1_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+t1_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+t1_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+t1_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+t1_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+t1_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+t1_srvr.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+t1_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+t1_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+t1_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+t1_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
+t1_srvr.o: t1_srvr.c
diff --git a/openssl/ssl/bio_ssl.c b/openssl/ssl/bio_ssl.c
new file mode 100644
index 0000000..eedac8a
--- /dev/null
+++ b/openssl/ssl/bio_ssl.c
@@ -0,0 +1,603 @@
+/* ssl/bio_ssl.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <openssl/crypto.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+static int ssl_write(BIO *h, const char *buf, int num);
+static int ssl_read(BIO *h, char *buf, int size);
+static int ssl_puts(BIO *h, const char *str);
+static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int ssl_new(BIO *h);
+static int ssl_free(BIO *data);
+static long ssl_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+typedef struct bio_ssl_st
+	{
+	SSL *ssl; /* The ssl handle :-) */
+	/* re-negotiate every time the total number of bytes is this size */
+	int num_renegotiates;
+	unsigned long renegotiate_count;
+	unsigned long byte_count;
+	unsigned long renegotiate_timeout;
+	unsigned long last_time;
+	} BIO_SSL;
+
+static BIO_METHOD methods_sslp=
+	{
+	BIO_TYPE_SSL,"ssl",
+	ssl_write,
+	ssl_read,
+	ssl_puts,
+	NULL, /* ssl_gets, */
+	ssl_ctrl,
+	ssl_new,
+	ssl_free,
+	ssl_callback_ctrl,
+	};
+
+BIO_METHOD *BIO_f_ssl(void)
+	{
+	return(&methods_sslp);
+	}
+
+static int ssl_new(BIO *bi)
+	{
+	BIO_SSL *bs;
+
+	bs=(BIO_SSL *)OPENSSL_malloc(sizeof(BIO_SSL));
+	if (bs == NULL)
+		{
+		BIOerr(BIO_F_SSL_NEW,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	memset(bs,0,sizeof(BIO_SSL));
+	bi->init=0;
+	bi->ptr=(char *)bs;
+	bi->flags=0;
+	return(1);
+	}
+
+static int ssl_free(BIO *a)
+	{
+	BIO_SSL *bs;
+
+	if (a == NULL) return(0);
+	bs=(BIO_SSL *)a->ptr;
+	if (bs->ssl != NULL) SSL_shutdown(bs->ssl);
+	if (a->shutdown)
+		{
+		if (a->init && (bs->ssl != NULL))
+			SSL_free(bs->ssl);
+		a->init=0;
+		a->flags=0;
+		}
+	if (a->ptr != NULL)
+		OPENSSL_free(a->ptr);
+	return(1);
+	}
+	
+static int ssl_read(BIO *b, char *out, int outl)
+	{
+	int ret=1;
+	BIO_SSL *sb;
+	SSL *ssl;
+	int retry_reason=0;
+	int r=0;
+
+	if (out == NULL) return(0);
+	sb=(BIO_SSL *)b->ptr;
+	ssl=sb->ssl;
+
+	BIO_clear_retry_flags(b);
+
+#if 0
+	if (!SSL_is_init_finished(ssl))
+		{
+/*		ret=SSL_do_handshake(ssl); */
+		if (ret > 0)
+			{
+
+			outflags=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY);
+			ret= -1;
+			goto end;
+			}
+		}
+#endif
+/*	if (ret > 0) */
+	ret=SSL_read(ssl,out,outl);
+
+	switch (SSL_get_error(ssl,ret))
+		{
+	case SSL_ERROR_NONE:
+		if (ret <= 0) break;
+		if (sb->renegotiate_count > 0)
+			{
+			sb->byte_count+=ret;
+			if (sb->byte_count > sb->renegotiate_count)
+				{
+				sb->byte_count=0;
+				sb->num_renegotiates++;
+				SSL_renegotiate(ssl);
+				r=1;
+				}
+			}
+		if ((sb->renegotiate_timeout > 0) && (!r))
+			{
+			unsigned long tm;
+
+			tm=(unsigned long)time(NULL);
+			if (tm > sb->last_time+sb->renegotiate_timeout)
+				{
+				sb->last_time=tm;
+				sb->num_renegotiates++;
+				SSL_renegotiate(ssl);
+				}
+			}
+
+		break;
+	case SSL_ERROR_WANT_READ:
+		BIO_set_retry_read(b);
+		break;
+	case SSL_ERROR_WANT_WRITE:
+		BIO_set_retry_write(b);
+		break;
+	case SSL_ERROR_WANT_X509_LOOKUP:
+		BIO_set_retry_special(b);
+		retry_reason=BIO_RR_SSL_X509_LOOKUP;
+		break;
+	case SSL_ERROR_WANT_ACCEPT:
+		BIO_set_retry_special(b);
+		retry_reason=BIO_RR_ACCEPT;
+		break;
+	case SSL_ERROR_WANT_CONNECT:
+		BIO_set_retry_special(b);
+		retry_reason=BIO_RR_CONNECT;
+		break;
+	case SSL_ERROR_SYSCALL:
+	case SSL_ERROR_SSL:
+	case SSL_ERROR_ZERO_RETURN:
+	default:
+		break;
+		}
+
+	b->retry_reason=retry_reason;
+	return(ret);
+	}
+
+static int ssl_write(BIO *b, const char *out, int outl)
+	{
+	int ret,r=0;
+	int retry_reason=0;
+	SSL *ssl;
+	BIO_SSL *bs;
+
+	if (out == NULL) return(0);
+	bs=(BIO_SSL *)b->ptr;
+	ssl=bs->ssl;
+
+	BIO_clear_retry_flags(b);
+
+/*	ret=SSL_do_handshake(ssl);
+	if (ret > 0) */
+	ret=SSL_write(ssl,out,outl);
+
+	switch (SSL_get_error(ssl,ret))
+		{
+	case SSL_ERROR_NONE:
+		if (ret <= 0) break;
+		if (bs->renegotiate_count > 0)
+			{
+			bs->byte_count+=ret;
+			if (bs->byte_count > bs->renegotiate_count)
+				{
+				bs->byte_count=0;
+				bs->num_renegotiates++;
+				SSL_renegotiate(ssl);
+				r=1;
+				}
+			}
+		if ((bs->renegotiate_timeout > 0) && (!r))
+			{
+			unsigned long tm;
+
+			tm=(unsigned long)time(NULL);
+			if (tm > bs->last_time+bs->renegotiate_timeout)
+				{
+				bs->last_time=tm;
+				bs->num_renegotiates++;
+				SSL_renegotiate(ssl);
+				}
+			}
+		break;
+	case SSL_ERROR_WANT_WRITE:
+		BIO_set_retry_write(b);
+		break;
+	case SSL_ERROR_WANT_READ:
+		BIO_set_retry_read(b);
+		break;
+	case SSL_ERROR_WANT_X509_LOOKUP:
+		BIO_set_retry_special(b);
+		retry_reason=BIO_RR_SSL_X509_LOOKUP;
+		break;
+	case SSL_ERROR_WANT_CONNECT:
+		BIO_set_retry_special(b);
+		retry_reason=BIO_RR_CONNECT;
+	case SSL_ERROR_SYSCALL:
+	case SSL_ERROR_SSL:
+	default:
+		break;
+		}
+
+	b->retry_reason=retry_reason;
+	return(ret);
+	}
+
+static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
+	{
+	SSL **sslp,*ssl;
+	BIO_SSL *bs;
+	BIO *dbio,*bio;
+	long ret=1;
+
+	bs=(BIO_SSL *)b->ptr;
+	ssl=bs->ssl;
+	if ((ssl == NULL)  && (cmd != BIO_C_SET_SSL))
+		return(0);
+	switch (cmd)
+		{
+	case BIO_CTRL_RESET:
+		SSL_shutdown(ssl);
+
+		if (ssl->handshake_func == ssl->method->ssl_connect)
+			SSL_set_connect_state(ssl);
+		else if (ssl->handshake_func == ssl->method->ssl_accept)
+			SSL_set_accept_state(ssl);
+
+		SSL_clear(ssl);
+
+		if (b->next_bio != NULL)
+			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+		else if (ssl->rbio != NULL)
+			ret=BIO_ctrl(ssl->rbio,cmd,num,ptr);
+		else
+			ret=1;
+		break;
+	case BIO_CTRL_INFO:
+		ret=0;
+		break;
+	case BIO_C_SSL_MODE:
+		if (num) /* client mode */
+			SSL_set_connect_state(ssl);
+		else
+			SSL_set_accept_state(ssl);
+		break;
+	case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT:
+		ret=bs->renegotiate_timeout;
+		if (num < 60) num=5;
+		bs->renegotiate_timeout=(unsigned long)num;
+		bs->last_time=(unsigned long)time(NULL);
+		break;
+	case BIO_C_SET_SSL_RENEGOTIATE_BYTES:
+		ret=bs->renegotiate_count;
+		if ((long)num >=512)
+			bs->renegotiate_count=(unsigned long)num;
+		break;
+	case BIO_C_GET_SSL_NUM_RENEGOTIATES:
+		ret=bs->num_renegotiates;
+		break;
+	case BIO_C_SET_SSL:
+		if (ssl != NULL)
+			{
+			ssl_free(b);
+			if (!ssl_new(b))
+				return 0;
+			}
+		b->shutdown=(int)num;
+		ssl=(SSL *)ptr;
+		((BIO_SSL *)b->ptr)->ssl=ssl;
+		bio=SSL_get_rbio(ssl);
+		if (bio != NULL)
+			{
+			if (b->next_bio != NULL)
+				BIO_push(bio,b->next_bio);
+			b->next_bio=bio;
+			CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO);
+			}
+		b->init=1;
+		break;
+	case BIO_C_GET_SSL:
+		if (ptr != NULL)
+			{
+			sslp=(SSL **)ptr;
+			*sslp=ssl;
+			}
+		else
+			ret=0;
+		break;
+	case BIO_CTRL_GET_CLOSE:
+		ret=b->shutdown;
+		break;
+	case BIO_CTRL_SET_CLOSE:
+		b->shutdown=(int)num;
+		break;
+	case BIO_CTRL_WPENDING:
+		ret=BIO_ctrl(ssl->wbio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_PENDING:
+		ret=SSL_pending(ssl);
+		if (ret == 0)
+			ret=BIO_pending(ssl->rbio);
+		break;
+	case BIO_CTRL_FLUSH:
+		BIO_clear_retry_flags(b);
+		ret=BIO_ctrl(ssl->wbio,cmd,num,ptr);
+		BIO_copy_next_retry(b);
+		break;
+	case BIO_CTRL_PUSH:
+		if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio))
+			{
+			SSL_set_bio(ssl,b->next_bio,b->next_bio);
+			CRYPTO_add(&b->next_bio->references,1,CRYPTO_LOCK_BIO);
+			}
+		break;
+	case BIO_CTRL_POP:
+		/* Only detach if we are the BIO explicitly being popped */
+		if (b == ptr)
+			{
+			/* Shouldn't happen in practice because the
+			 * rbio and wbio are the same when pushed.
+			 */
+			if (ssl->rbio != ssl->wbio)
+				BIO_free_all(ssl->wbio);
+			if (b->next_bio != NULL)
+				CRYPTO_add(&b->next_bio->references,-1,CRYPTO_LOCK_BIO);
+			ssl->wbio=NULL;
+			ssl->rbio=NULL;
+			}
+		break;
+	case BIO_C_DO_STATE_MACHINE:
+		BIO_clear_retry_flags(b);
+
+		b->retry_reason=0;
+		ret=(int)SSL_do_handshake(ssl);
+
+		switch (SSL_get_error(ssl,(int)ret))
+			{
+		case SSL_ERROR_WANT_READ:
+			BIO_set_flags(b,
+				BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY);
+			break;
+		case SSL_ERROR_WANT_WRITE:
+			BIO_set_flags(b,
+				BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY);
+			break;
+		case SSL_ERROR_WANT_CONNECT:
+			BIO_set_flags(b,
+				BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY);
+			b->retry_reason=b->next_bio->retry_reason;
+			break;
+		default:
+			break;
+			}
+		break;
+	case BIO_CTRL_DUP:
+		dbio=(BIO *)ptr;
+		if (((BIO_SSL *)dbio->ptr)->ssl != NULL)
+			SSL_free(((BIO_SSL *)dbio->ptr)->ssl);
+		((BIO_SSL *)dbio->ptr)->ssl=SSL_dup(ssl);
+		((BIO_SSL *)dbio->ptr)->renegotiate_count=
+			((BIO_SSL *)b->ptr)->renegotiate_count;
+		((BIO_SSL *)dbio->ptr)->byte_count=
+			((BIO_SSL *)b->ptr)->byte_count;
+		((BIO_SSL *)dbio->ptr)->renegotiate_timeout=
+			((BIO_SSL *)b->ptr)->renegotiate_timeout;
+		((BIO_SSL *)dbio->ptr)->last_time=
+			((BIO_SSL *)b->ptr)->last_time;
+		ret=(((BIO_SSL *)dbio->ptr)->ssl != NULL);
+		break;
+	case BIO_C_GET_FD:
+		ret=BIO_ctrl(ssl->rbio,cmd,num,ptr);
+		break;
+	case BIO_CTRL_SET_CALLBACK:
+		{
+#if 0 /* FIXME: Should this be used?  -- Richard Levitte */
+		SSLerr(SSL_F_SSL_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		ret = -1;
+#else
+		ret=0;
+#endif
+		}
+		break;
+	case BIO_CTRL_GET_CALLBACK:
+		{
+		void (**fptr)(const SSL *xssl,int type,int val);
+
+		fptr=(void (**)(const SSL *xssl,int type,int val))ptr;
+		*fptr=SSL_get_info_callback(ssl);
+		}
+		break;
+	default:
+		ret=BIO_ctrl(ssl->rbio,cmd,num,ptr);
+		break;
+		}
+	return(ret);
+	}
+
+static long ssl_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+	{
+	SSL *ssl;
+	BIO_SSL *bs;
+	long ret=1;
+
+	bs=(BIO_SSL *)b->ptr;
+	ssl=bs->ssl;
+	switch (cmd)
+		{
+	case BIO_CTRL_SET_CALLBACK:
+		{
+		/* FIXME: setting this via a completely different prototype
+		   seems like a crap idea */
+		SSL_set_info_callback(ssl,(void (*)(const SSL *,int,int))fp);
+		}
+		break;
+	default:
+		ret=BIO_callback_ctrl(ssl->rbio,cmd,fp);
+		break;
+		}
+	return(ret);
+	}
+
+static int ssl_puts(BIO *bp, const char *str)
+	{
+	int n,ret;
+
+	n=strlen(str);
+	ret=BIO_write(bp,str,n);
+	return(ret);
+	}
+
+BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx)
+	{
+#ifndef OPENSSL_NO_SOCK
+	BIO *ret=NULL,*buf=NULL,*ssl=NULL;
+
+	if ((buf=BIO_new(BIO_f_buffer())) == NULL)
+		return(NULL);
+	if ((ssl=BIO_new_ssl_connect(ctx)) == NULL)
+		goto err;
+	if ((ret=BIO_push(buf,ssl)) == NULL)
+		goto err;
+	return(ret);
+err:
+	if (buf != NULL) BIO_free(buf);
+	if (ssl != NULL) BIO_free(ssl);
+#endif
+	return(NULL);
+	}
+
+BIO *BIO_new_ssl_connect(SSL_CTX *ctx)
+	{
+	BIO *ret=NULL,*con=NULL,*ssl=NULL;
+
+	if ((con=BIO_new(BIO_s_connect())) == NULL)
+		return(NULL);
+	if ((ssl=BIO_new_ssl(ctx,1)) == NULL)
+		goto err;
+	if ((ret=BIO_push(ssl,con)) == NULL)
+		goto err;
+	return(ret);
+err:
+	if (con != NULL) BIO_free(con);
+	return(NULL);
+	}
+
+BIO *BIO_new_ssl(SSL_CTX *ctx, int client)
+	{
+	BIO *ret;
+	SSL *ssl;
+
+	if ((ret=BIO_new(BIO_f_ssl())) == NULL)
+		return(NULL);
+	if ((ssl=SSL_new(ctx)) == NULL)
+		{
+		BIO_free(ret);
+		return(NULL);
+		}
+	if (client)
+		SSL_set_connect_state(ssl);
+	else
+		SSL_set_accept_state(ssl);
+		
+	BIO_set_ssl(ret,ssl,BIO_CLOSE);
+	return(ret);
+	}
+
+int BIO_ssl_copy_session_id(BIO *t, BIO *f)
+	{
+	t=BIO_find_type(t,BIO_TYPE_SSL);
+	f=BIO_find_type(f,BIO_TYPE_SSL);
+	if ((t == NULL) || (f == NULL))
+		return(0);
+	if (	(((BIO_SSL *)t->ptr)->ssl == NULL) || 
+		(((BIO_SSL *)f->ptr)->ssl == NULL))
+		return(0);
+	SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl,((BIO_SSL *)f->ptr)->ssl);
+	return(1);
+	}
+
+void BIO_ssl_shutdown(BIO *b)
+	{
+	SSL *s;
+
+	while (b != NULL)
+		{
+		if (b->method->type == BIO_TYPE_SSL)
+			{
+			s=((BIO_SSL *)b->ptr)->ssl;
+			SSL_shutdown(s);
+			break;
+			}
+		b=b->next_bio;
+		}
+	}
diff --git a/openssl/ssl/d1_both.c b/openssl/ssl/d1_both.c
new file mode 100644
index 0000000..9f898d6
--- /dev/null
+++ b/openssl/ssl/d1_both.c
@@ -0,0 +1,1419 @@
+/* ssl/d1_both.c */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <limits.h>
+#include <string.h>
+#include <stdio.h>
+#include "ssl_locl.h"
+#include <openssl/buffer.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+#define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8)
+
+#define RSMBLY_BITMASK_MARK(bitmask, start, end) { \
+			if ((end) - (start) <= 8) { \
+				long ii; \
+				for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \
+			} else { \
+				long ii; \
+				bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \
+				for (ii = (((start) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++) bitmask[ii] = 0xff; \
+				bitmask[(((end) - 1) >> 3)] |= bitmask_end_values[((end) & 7)]; \
+			} }
+
+#define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \
+			long ii; \
+			OPENSSL_assert((msg_len) > 0); \
+			is_complete = 1; \
+			if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \
+			if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \
+				if (bitmask[ii] != 0xff) { is_complete = 0; break; } }
+
+#if 0
+#define RSMBLY_BITMASK_PRINT(bitmask, msg_len) { \
+			long ii; \
+			printf("bitmask: "); for (ii = 0; ii < (msg_len); ii++) \
+			printf("%d ", (bitmask[ii >> 3] & (1 << (ii & 7))) >> (ii & 7)); \
+			printf("\n"); }
+#endif
+
+static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80};
+static unsigned char bitmask_end_values[]   = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f};
+
+/* XDTLS:  figure out the right values */
+static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};
+
+static unsigned int dtls1_guess_mtu(unsigned int curr_mtu);
+static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, 
+	unsigned long frag_len);
+static unsigned char *dtls1_write_message_header(SSL *s,
+	unsigned char *p);
+static void dtls1_set_message_header_int(SSL *s, unsigned char mt,
+	unsigned long len, unsigned short seq_num, unsigned long frag_off, 
+	unsigned long frag_len);
+static long dtls1_get_message_fragment(SSL *s, int st1, int stn, 
+	long max, int *ok);
+
+static hm_fragment *
+dtls1_hm_fragment_new(unsigned long frag_len, int reassembly)
+	{
+	hm_fragment *frag = NULL;
+	unsigned char *buf = NULL;
+	unsigned char *bitmask = NULL;
+
+	frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment));
+	if ( frag == NULL)
+		return NULL;
+
+	if (frag_len)
+		{
+		buf = (unsigned char *)OPENSSL_malloc(frag_len);
+		if ( buf == NULL)
+			{
+			OPENSSL_free(frag);
+			return NULL;
+			}
+		}
+
+	/* zero length fragment gets zero frag->fragment */
+	frag->fragment = buf;
+
+	/* Initialize reassembly bitmask if necessary */
+	if (reassembly)
+		{
+		bitmask = (unsigned char *)OPENSSL_malloc(RSMBLY_BITMASK_SIZE(frag_len));
+		if (bitmask == NULL)
+			{
+			if (buf != NULL) OPENSSL_free(buf);
+			OPENSSL_free(frag);
+			return NULL;
+			}
+		memset(bitmask, 0, RSMBLY_BITMASK_SIZE(frag_len));
+		}
+
+	frag->reassembly = bitmask;
+
+	return frag;
+	}
+
+static void
+dtls1_hm_fragment_free(hm_fragment *frag)
+	{
+	if (frag->fragment) OPENSSL_free(frag->fragment);
+	if (frag->reassembly) OPENSSL_free(frag->reassembly);
+	OPENSSL_free(frag);
+	}
+
+/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
+int dtls1_do_write(SSL *s, int type)
+	{
+	int ret;
+	int curr_mtu;
+	unsigned int len, frag_off, mac_size, blocksize;
+
+	/* AHA!  Figure out the MTU, and stick to the right size */
+	if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
+		{
+		s->d1->mtu = 
+			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
+
+		/* I've seen the kernel return bogus numbers when it doesn't know
+		 * (initial write), so just make sure we have a reasonable number */
+		if ( s->d1->mtu < dtls1_min_mtu())
+			{
+			s->d1->mtu = 0;
+			s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
+			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, 
+				s->d1->mtu, NULL);
+			}
+		}
+#if 0 
+	mtu = s->d1->mtu;
+
+	fprintf(stderr, "using MTU = %d\n", mtu);
+
+	mtu -= (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
+
+	curr_mtu = mtu - BIO_wpending(SSL_get_wbio(s));
+
+	if ( curr_mtu > 0)
+		mtu = curr_mtu;
+	else if ( ( ret = BIO_flush(SSL_get_wbio(s))) <= 0)
+		return ret;
+
+	if ( BIO_wpending(SSL_get_wbio(s)) + s->init_num >= mtu)
+		{
+		ret = BIO_flush(SSL_get_wbio(s));
+		if ( ret <= 0)
+			return ret;
+		mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
+		}
+#endif
+
+	OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu());  /* should have something reasonable now */
+
+	if ( s->init_off == 0  && type == SSL3_RT_HANDSHAKE)
+		OPENSSL_assert(s->init_num == 
+			(int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
+
+	if (s->write_hash)
+		mac_size = EVP_MD_CTX_size(s->write_hash);
+	else
+		mac_size = 0;
+
+	if (s->enc_write_ctx && 
+		(EVP_CIPHER_mode( s->enc_write_ctx->cipher) & EVP_CIPH_CBC_MODE))
+		blocksize = 2 * EVP_CIPHER_block_size(s->enc_write_ctx->cipher);
+	else
+		blocksize = 0;
+
+	frag_off = 0;
+	while( s->init_num)
+		{
+		curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - 
+			DTLS1_RT_HEADER_LENGTH - mac_size - blocksize;
+
+		if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH)
+			{
+			/* grr.. we could get an error if MTU picked was wrong */
+			ret = BIO_flush(SSL_get_wbio(s));
+			if ( ret <= 0)
+				return ret;
+			curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH -
+				mac_size - blocksize;
+			}
+
+		if ( s->init_num > curr_mtu)
+			len = curr_mtu;
+		else
+			len = s->init_num;
+
+
+		/* XDTLS: this function is too long.  split out the CCS part */
+		if ( type == SSL3_RT_HANDSHAKE)
+			{
+			if ( s->init_off != 0)
+				{
+				OPENSSL_assert(s->init_off > DTLS1_HM_HEADER_LENGTH);
+				s->init_off -= DTLS1_HM_HEADER_LENGTH;
+				s->init_num += DTLS1_HM_HEADER_LENGTH;
+
+				/* write atleast DTLS1_HM_HEADER_LENGTH bytes */
+				if ( len <= DTLS1_HM_HEADER_LENGTH)  
+					len += DTLS1_HM_HEADER_LENGTH;
+				}
+
+			dtls1_fix_message_header(s, frag_off, 
+				len - DTLS1_HM_HEADER_LENGTH);
+
+			dtls1_write_message_header(s, (unsigned char *)&s->init_buf->data[s->init_off]);
+
+			OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH);
+			}
+
+		ret=dtls1_write_bytes(s,type,&s->init_buf->data[s->init_off],
+			len);
+		if (ret < 0)
+			{
+			/* might need to update MTU here, but we don't know
+			 * which previous packet caused the failure -- so can't
+			 * really retransmit anything.  continue as if everything
+			 * is fine and wait for an alert to handle the
+			 * retransmit 
+			 */
+			if ( BIO_ctrl(SSL_get_wbio(s),
+				BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0 )
+				s->d1->mtu = BIO_ctrl(SSL_get_wbio(s),
+					BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
+			else
+				return(-1);
+			}
+		else
+			{
+
+			/* bad if this assert fails, only part of the handshake
+			 * message got sent.  but why would this happen? */
+			OPENSSL_assert(len == (unsigned int)ret);
+
+			if (type == SSL3_RT_HANDSHAKE && ! s->d1->retransmitting)
+				{
+				/* should not be done for 'Hello Request's, but in that case
+				 * we'll ignore the result anyway */
+				unsigned char *p = (unsigned char *)&s->init_buf->data[s->init_off];
+				const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
+				int xlen;
+
+				if (frag_off == 0 && s->version != DTLS1_BAD_VER)
+					{
+					/* reconstruct message header is if it
+					 * is being sent in single fragment */
+					*p++ = msg_hdr->type;
+					l2n3(msg_hdr->msg_len,p);
+					s2n (msg_hdr->seq,p);
+					l2n3(0,p);
+					l2n3(msg_hdr->msg_len,p);
+					p  -= DTLS1_HM_HEADER_LENGTH;
+					xlen = ret;
+					}
+				else
+					{
+					p  += DTLS1_HM_HEADER_LENGTH;
+					xlen = ret - DTLS1_HM_HEADER_LENGTH;
+					}
+
+				ssl3_finish_mac(s, p, xlen);
+				}
+
+			if (ret == s->init_num)
+				{
+				if (s->msg_callback)
+					s->msg_callback(1, s->version, type, s->init_buf->data, 
+						(size_t)(s->init_off + s->init_num), s, 
+						s->msg_callback_arg);
+
+				s->init_off = 0;  /* done writing this message */
+				s->init_num = 0;
+
+				return(1);
+				}
+			s->init_off+=ret;
+			s->init_num-=ret;
+			frag_off += (ret -= DTLS1_HM_HEADER_LENGTH);
+			}
+		}
+	return(0);
+	}
+
+
+/* Obtain handshake message of message type 'mt' (any if mt == -1),
+ * maximum acceptable body length 'max'.
+ * Read an entire handshake message.  Handshake messages arrive in
+ * fragments.
+ */
+long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
+	{
+	int i, al;
+	struct hm_header_st *msg_hdr;
+	unsigned char *p;
+	unsigned long msg_len;
+
+	/* s3->tmp is used to store messages that are unexpected, caused
+	 * by the absence of an optional handshake message */
+	if (s->s3->tmp.reuse_message)
+		{
+		s->s3->tmp.reuse_message=0;
+		if ((mt >= 0) && (s->s3->tmp.message_type != mt))
+			{
+			al=SSL_AD_UNEXPECTED_MESSAGE;
+			SSLerr(SSL_F_DTLS1_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
+			goto f_err;
+			}
+		*ok=1;
+		s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
+		s->init_num = (int)s->s3->tmp.message_size;
+		return s->init_num;
+		}
+
+	msg_hdr = &s->d1->r_msg_hdr;
+	memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
+
+again:
+	i = dtls1_get_message_fragment(s, st1, stn, max, ok);
+	if ( i == DTLS1_HM_BAD_FRAGMENT ||
+		i == DTLS1_HM_FRAGMENT_RETRY)  /* bad fragment received */
+		goto again;
+	else if ( i <= 0 && !*ok)
+		return i;
+
+	p = (unsigned char *)s->init_buf->data;
+	msg_len = msg_hdr->msg_len;
+
+	/* reconstruct message header */
+	*(p++) = msg_hdr->type;
+	l2n3(msg_len,p);
+	s2n (msg_hdr->seq,p);
+	l2n3(0,p);
+	l2n3(msg_len,p);
+	if (s->version != DTLS1_BAD_VER) {
+		p       -= DTLS1_HM_HEADER_LENGTH;
+		msg_len += DTLS1_HM_HEADER_LENGTH;
+	}
+
+	ssl3_finish_mac(s, p, msg_len);
+	if (s->msg_callback)
+		s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
+			p, msg_len,
+			s, s->msg_callback_arg);
+
+	memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
+
+	/* Don't change sequence numbers while listening */
+	if (!s->d1->listen)
+		s->d1->handshake_read_seq++;
+
+	s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
+	return s->init_num;
+
+f_err:
+	ssl3_send_alert(s,SSL3_AL_FATAL,al);
+	*ok = 0;
+	return -1;
+	}
+
+
+static int dtls1_preprocess_fragment(SSL *s,struct hm_header_st *msg_hdr,int max)
+	{
+	size_t frag_off,frag_len,msg_len;
+
+	msg_len  = msg_hdr->msg_len;
+	frag_off = msg_hdr->frag_off;
+	frag_len = msg_hdr->frag_len;
+
+	/* sanity checking */
+	if ( (frag_off+frag_len) > msg_len)
+		{
+		SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
+		return SSL_AD_ILLEGAL_PARAMETER;
+		}
+
+	if ( (frag_off+frag_len) > (unsigned long)max)
+		{
+		SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
+		return SSL_AD_ILLEGAL_PARAMETER;
+		}
+
+	if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */
+		{
+		/* msg_len is limited to 2^24, but is effectively checked
+		 * against max above */
+		if (!BUF_MEM_grow_clean(s->init_buf,msg_len+DTLS1_HM_HEADER_LENGTH))
+			{
+			SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,ERR_R_BUF_LIB);
+			return SSL_AD_INTERNAL_ERROR;
+			}
+
+		s->s3->tmp.message_size  = msg_len;
+		s->d1->r_msg_hdr.msg_len = msg_len;
+		s->s3->tmp.message_type  = msg_hdr->type;
+		s->d1->r_msg_hdr.type    = msg_hdr->type;
+		s->d1->r_msg_hdr.seq     = msg_hdr->seq;
+		}
+	else if (msg_len != s->d1->r_msg_hdr.msg_len)
+		{
+		/* They must be playing with us! BTW, failure to enforce
+		 * upper limit would open possibility for buffer overrun. */
+		SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
+		return SSL_AD_ILLEGAL_PARAMETER;
+		}
+
+	return 0; /* no error */
+	}
+
+
+static int
+dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
+	{
+	/* (0) check whether the desired fragment is available
+	 * if so:
+	 * (1) copy over the fragment to s->init_buf->data[]
+	 * (2) update s->init_num
+	 */
+	pitem *item;
+	hm_fragment *frag;
+	int al;
+
+	*ok = 0;
+	item = pqueue_peek(s->d1->buffered_messages);
+	if ( item == NULL)
+		return 0;
+
+	frag = (hm_fragment *)item->data;
+	
+	/* Don't return if reassembly still in progress */
+	if (frag->reassembly != NULL)
+		return 0;
+
+	if ( s->d1->handshake_read_seq == frag->msg_header.seq)
+		{
+		unsigned long frag_len = frag->msg_header.frag_len;
+		pqueue_pop(s->d1->buffered_messages);
+
+		al=dtls1_preprocess_fragment(s,&frag->msg_header,max);
+
+		if (al==0) /* no alert */
+			{
+			unsigned char *p = (unsigned char *)s->init_buf->data+DTLS1_HM_HEADER_LENGTH;
+			memcpy(&p[frag->msg_header.frag_off],
+				frag->fragment,frag->msg_header.frag_len);
+			}
+
+		dtls1_hm_fragment_free(frag);
+		pitem_free(item);
+
+		if (al==0)
+			{
+			*ok = 1;
+			return frag_len;
+			}
+
+		ssl3_send_alert(s,SSL3_AL_FATAL,al);
+		s->init_num = 0;
+		*ok = 0;
+		return -1;
+		}
+	else
+		return 0;
+	}
+
+
+static int
+dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
+	{
+	hm_fragment *frag = NULL;
+	pitem *item = NULL;
+	int i = -1, is_complete;
+	unsigned char seq64be[8];
+	unsigned long frag_len = msg_hdr->frag_len, max_len;
+
+	if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len)
+		goto err;
+
+	/* Determine maximum allowed message size. Depends on (user set)
+	 * maximum certificate length, but 16k is minimum.
+	 */
+	if (DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH < s->max_cert_list)
+		max_len = s->max_cert_list;
+	else
+		max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
+
+	if ((msg_hdr->frag_off+frag_len) > max_len)
+		goto err;
+
+	/* Try to find item in queue */
+	memset(seq64be,0,sizeof(seq64be));
+	seq64be[6] = (unsigned char) (msg_hdr->seq>>8);
+	seq64be[7] = (unsigned char) msg_hdr->seq;
+	item = pqueue_find(s->d1->buffered_messages, seq64be);
+
+	if (item == NULL)
+		{
+		frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1);
+		if ( frag == NULL)
+			goto err;
+		memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
+		frag->msg_header.frag_len = frag->msg_header.msg_len;
+		frag->msg_header.frag_off = 0;
+		}
+	else
+		frag = (hm_fragment*) item->data;
+
+	/* If message is already reassembled, this must be a
+	 * retransmit and can be dropped.
+	 */
+	if (frag->reassembly == NULL)
+		{
+		unsigned char devnull [256];
+
+		while (frag_len)
+			{
+			i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
+				devnull,
+				frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0);
+			if (i<=0) goto err;
+			frag_len -= i;
+			}
+		return DTLS1_HM_FRAGMENT_RETRY;
+		}
+
+	/* read the body of the fragment (header has already been read */
+	i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
+		frag->fragment + msg_hdr->frag_off,frag_len,0);
+	if (i<=0 || (unsigned long)i!=frag_len)
+		goto err;
+
+	RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off,
+	                    (long)(msg_hdr->frag_off + frag_len));
+
+	RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len,
+	                           is_complete);
+
+	if (is_complete)
+		{
+		OPENSSL_free(frag->reassembly);
+		frag->reassembly = NULL;
+		}
+
+	if (item == NULL)
+		{
+		memset(seq64be,0,sizeof(seq64be));
+		seq64be[6] = (unsigned char)(msg_hdr->seq>>8);
+		seq64be[7] = (unsigned char)(msg_hdr->seq);
+
+		item = pitem_new(seq64be, frag);
+		if (item == NULL)
+			{
+			goto err;
+			i = -1;
+			}
+
+		pqueue_insert(s->d1->buffered_messages, item);
+		}
+
+	return DTLS1_HM_FRAGMENT_RETRY;
+
+err:
+	if (frag != NULL) dtls1_hm_fragment_free(frag);
+	if (item != NULL) OPENSSL_free(item);
+	*ok = 0;
+	return i;
+	}
+
+
+static int
+dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
+{
+	int i=-1;
+	hm_fragment *frag = NULL;
+	pitem *item = NULL;
+	unsigned char seq64be[8];
+	unsigned long frag_len = msg_hdr->frag_len;
+
+	if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len)
+		goto err;
+
+	/* Try to find item in queue, to prevent duplicate entries */
+	memset(seq64be,0,sizeof(seq64be));
+	seq64be[6] = (unsigned char) (msg_hdr->seq>>8);
+	seq64be[7] = (unsigned char) msg_hdr->seq;
+	item = pqueue_find(s->d1->buffered_messages, seq64be);
+
+	/* If we already have an entry and this one is a fragment,
+	 * don't discard it and rather try to reassemble it.
+	 */
+	if (item != NULL && frag_len < msg_hdr->msg_len)
+		item = NULL;
+
+	/* Discard the message if sequence number was already there, is
+	 * too far in the future, already in the queue or if we received
+	 * a FINISHED before the SERVER_HELLO, which then must be a stale
+	 * retransmit.
+	 */
+	if (msg_hdr->seq <= s->d1->handshake_read_seq ||
+		msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL ||
+		(s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED))
+		{
+		unsigned char devnull [256];
+
+		while (frag_len)
+			{
+			i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
+				devnull,
+				frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0);
+			if (i<=0) goto err;
+			frag_len -= i;
+			}
+		}
+	else
+		{
+		if (frag_len && frag_len < msg_hdr->msg_len)
+			return dtls1_reassemble_fragment(s, msg_hdr, ok);
+
+		frag = dtls1_hm_fragment_new(frag_len, 0);
+		if ( frag == NULL)
+			goto err;
+
+		memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
+
+		if (frag_len)
+			{
+			/* read the body of the fragment (header has already been read */
+			i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
+				frag->fragment,frag_len,0);
+			if (i<=0 || (unsigned long)i!=frag_len)
+				goto err;
+			}
+
+		memset(seq64be,0,sizeof(seq64be));
+		seq64be[6] = (unsigned char)(msg_hdr->seq>>8);
+		seq64be[7] = (unsigned char)(msg_hdr->seq);
+
+		item = pitem_new(seq64be, frag);
+		if ( item == NULL)
+			goto err;
+
+		pqueue_insert(s->d1->buffered_messages, item);
+		}
+
+	return DTLS1_HM_FRAGMENT_RETRY;
+
+err:
+	if ( frag != NULL) dtls1_hm_fragment_free(frag);
+	if ( item != NULL) OPENSSL_free(item);
+	*ok = 0;
+	return i;
+	}
+
+
+static long
+dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
+	{
+	unsigned char wire[DTLS1_HM_HEADER_LENGTH];
+	unsigned long len, frag_off, frag_len;
+	int i,al;
+	struct hm_header_st msg_hdr;
+
+	/* see if we have the required fragment already */
+	if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok)
+		{
+		if (*ok)	s->init_num = frag_len;
+		return frag_len;
+		}
+
+	/* read handshake message header */
+	i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,wire,
+		DTLS1_HM_HEADER_LENGTH, 0);
+	if (i <= 0) 	/* nbio, or an error */
+		{
+		s->rwstate=SSL_READING;
+		*ok = 0;
+		return i;
+		}
+	/* Handshake fails if message header is incomplete */
+	if (i != DTLS1_HM_HEADER_LENGTH)
+		{
+		al=SSL_AD_UNEXPECTED_MESSAGE;
+		SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE);
+		goto f_err;
+		}
+
+	/* parse the message fragment header */
+	dtls1_get_message_header(wire, &msg_hdr);
+
+	/* 
+	 * if this is a future (or stale) message it gets buffered
+	 * (or dropped)--no further processing at this time
+	 * While listening, we accept seq 1 (ClientHello with cookie)
+	 * although we're still expecting seq 0 (ClientHello)
+	 */
+	if (msg_hdr.seq != s->d1->handshake_read_seq && !(s->d1->listen && msg_hdr.seq == 1))
+		return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);
+
+	len = msg_hdr.msg_len;
+	frag_off = msg_hdr.frag_off;
+	frag_len = msg_hdr.frag_len;
+
+	if (frag_len && frag_len < len)
+		return dtls1_reassemble_fragment(s, &msg_hdr, ok);
+
+	if (!s->server && s->d1->r_msg_hdr.frag_off == 0 &&
+		wire[0] == SSL3_MT_HELLO_REQUEST)
+		{
+		/* The server may always send 'Hello Request' messages --
+		 * we are doing a handshake anyway now, so ignore them
+		 * if their format is correct. Does not count for
+		 * 'Finished' MAC. */
+		if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0)
+			{
+			if (s->msg_callback)
+				s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, 
+					wire, DTLS1_HM_HEADER_LENGTH, s, 
+					s->msg_callback_arg);
+			
+			s->init_num = 0;
+			return dtls1_get_message_fragment(s, st1, stn,
+				max, ok);
+			}
+		else /* Incorrectly formated Hello request */
+			{
+			al=SSL_AD_UNEXPECTED_MESSAGE;
+			SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE);
+			goto f_err;
+			}
+		}
+
+	if ((al=dtls1_preprocess_fragment(s,&msg_hdr,max)))
+		goto f_err;
+
+	/* XDTLS:  ressurect this when restart is in place */
+	s->state=stn;
+
+	if ( frag_len > 0)
+		{
+		unsigned char *p=(unsigned char *)s->init_buf->data+DTLS1_HM_HEADER_LENGTH;
+
+		i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
+			&p[frag_off],frag_len,0);
+		/* XDTLS:  fix this--message fragments cannot span multiple packets */
+		if (i <= 0)
+			{
+			s->rwstate=SSL_READING;
+			*ok = 0;
+			return i;
+			}
+		}
+	else
+		i = 0;
+
+	/* XDTLS:  an incorrectly formatted fragment should cause the 
+	 * handshake to fail */
+	if (i != (int)frag_len)
+		{
+		al=SSL3_AD_ILLEGAL_PARAMETER;
+		SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL3_AD_ILLEGAL_PARAMETER);
+		goto f_err;
+		}
+
+	*ok = 1;
+
+	/* Note that s->init_num is *not* used as current offset in
+	 * s->init_buf->data, but as a counter summing up fragments'
+	 * lengths: as soon as they sum up to handshake packet
+	 * length, we assume we have got all the fragments. */
+	s->init_num = frag_len;
+	return frag_len;
+
+f_err:
+	ssl3_send_alert(s,SSL3_AL_FATAL,al);
+	s->init_num = 0;
+
+	*ok=0;
+	return(-1);
+	}
+
+int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen)
+	{
+	unsigned char *p,*d;
+	int i;
+	unsigned long l;
+
+	if (s->state == a)
+		{
+		d=(unsigned char *)s->init_buf->data;
+		p= &(d[DTLS1_HM_HEADER_LENGTH]);
+
+		i=s->method->ssl3_enc->final_finish_mac(s,
+			sender,slen,s->s3->tmp.finish_md);
+		s->s3->tmp.finish_md_len = i;
+		memcpy(p, s->s3->tmp.finish_md, i);
+		p+=i;
+		l=i;
+
+	/* Copy the finished so we can use it for
+	 * renegotiation checks
+	 */
+	if(s->type == SSL_ST_CONNECT)
+		{
+		OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+		memcpy(s->s3->previous_client_finished, 
+		       s->s3->tmp.finish_md, i);
+		s->s3->previous_client_finished_len=i;
+		}
+	else
+		{
+		OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+		memcpy(s->s3->previous_server_finished, 
+		       s->s3->tmp.finish_md, i);
+		s->s3->previous_server_finished_len=i;
+		}
+
+#ifdef OPENSSL_SYS_WIN16
+		/* MSVC 1.5 does not clear the top bytes of the word unless
+		 * I do this.
+		 */
+		l&=0xffff;
+#endif
+
+		d = dtls1_set_message_header(s, d, SSL3_MT_FINISHED, l, 0, l);
+		s->init_num=(int)l+DTLS1_HM_HEADER_LENGTH;
+		s->init_off=0;
+
+		/* buffer the message to handle re-xmits */
+		dtls1_buffer_message(s, 0);
+
+		s->state=b;
+		}
+
+	/* SSL3_ST_SEND_xxxxxx_HELLO_B */
+	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
+	}
+
+/* for these 2 messages, we need to
+ * ssl->enc_read_ctx			re-init
+ * ssl->s3->read_sequence		zero
+ * ssl->s3->read_mac_secret		re-init
+ * ssl->session->read_sym_enc		assign
+ * ssl->session->read_compression	assign
+ * ssl->session->read_hash		assign
+ */
+int dtls1_send_change_cipher_spec(SSL *s, int a, int b)
+	{ 
+	unsigned char *p;
+
+	if (s->state == a)
+		{
+		p=(unsigned char *)s->init_buf->data;
+		*p++=SSL3_MT_CCS;
+		s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
+		s->init_num=DTLS1_CCS_HEADER_LENGTH;
+
+		if (s->version == DTLS1_BAD_VER) {
+			s->d1->next_handshake_write_seq++;
+			s2n(s->d1->handshake_write_seq,p);
+			s->init_num+=2;
+		}
+
+		s->init_off=0;
+
+		dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, 
+			s->d1->handshake_write_seq, 0, 0);
+
+		/* buffer the message to handle re-xmits */
+		dtls1_buffer_message(s, 1);
+
+		s->state=b;
+		}
+
+	/* SSL3_ST_CW_CHANGE_B */
+	return(dtls1_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
+	}
+
+static int dtls1_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
+	{
+	int n;
+	unsigned char *p;
+
+	n=i2d_X509(x,NULL);
+	if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3)))
+		{
+		SSLerr(SSL_F_DTLS1_ADD_CERT_TO_BUF,ERR_R_BUF_LIB);
+		return 0;
+		}
+	p=(unsigned char *)&(buf->data[*l]);
+	l2n3(n,p);
+	i2d_X509(x,&p);
+	*l+=n+3;
+
+	return 1;
+	}
+unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
+	{
+	unsigned char *p;
+	int i;
+	unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH;
+	BUF_MEM *buf;
+
+	/* TLSv1 sends a chain with nothing in it, instead of an alert */
+	buf=s->init_buf;
+	if (!BUF_MEM_grow_clean(buf,10))
+		{
+		SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
+		return(0);
+		}
+	if (x != NULL)
+		{
+		X509_STORE_CTX xs_ctx;
+
+		if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL))
+  			{
+  			SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
+  			return(0);
+  			}
+  
+		X509_verify_cert(&xs_ctx);
+		/* Don't leave errors in the queue */
+		ERR_clear_error();
+		for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
+  			{
+			x = sk_X509_value(xs_ctx.chain, i);
+
+			if (!dtls1_add_cert_to_buf(buf, &l, x))
+  				{
+				X509_STORE_CTX_cleanup(&xs_ctx);
+				return 0;
+  				}
+  			}
+  		X509_STORE_CTX_cleanup(&xs_ctx);
+  		}
+  	/* Thawte special :-) */
+	for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
+		{
+		x=sk_X509_value(s->ctx->extra_certs,i);
+		if (!dtls1_add_cert_to_buf(buf, &l, x))
+			return 0;
+		}
+
+	l-= (3 + DTLS1_HM_HEADER_LENGTH);
+
+	p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]);
+	l2n3(l,p);
+	l+=3;
+	p=(unsigned char *)&(buf->data[0]);
+	p = dtls1_set_message_header(s, p, SSL3_MT_CERTIFICATE, l, 0, l);
+
+	l+=DTLS1_HM_HEADER_LENGTH;
+	return(l);
+	}
+
+int dtls1_read_failed(SSL *s, int code)
+	{
+	if ( code > 0)
+		{
+		fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__);
+		return 1;
+		}
+
+	if (!dtls1_is_timer_expired(s))
+		{
+		/* not a timeout, none of our business, 
+		   let higher layers handle this.  in fact it's probably an error */
+		return code;
+		}
+
+	if ( ! SSL_in_init(s))  /* done, no need to send a retransmit */
+		{
+		BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
+		return code;
+		}
+
+#if 0 /* for now, each alert contains only one record number */
+	item = pqueue_peek(state->rcvd_records);
+	if ( item )
+		{
+		/* send an alert immediately for all the missing records */
+		}
+	else
+#endif
+
+#if 0  /* no more alert sending, just retransmit the last set of messages */
+	if ( state->timeout.read_timeouts >= DTLS1_TMO_READ_COUNT)
+		ssl3_send_alert(s,SSL3_AL_WARNING,
+			DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
+#endif
+
+	return dtls1_handle_timeout(s);
+	}
+
+int
+dtls1_get_queue_priority(unsigned short seq, int is_ccs)
+	{
+	/* The index of the retransmission queue actually is the message sequence number,
+	 * since the queue only contains messages of a single handshake. However, the
+	 * ChangeCipherSpec has no message sequence number and so using only the sequence
+	 * will result in the CCS and Finished having the same index. To prevent this,
+	 * the sequence number is multiplied by 2. In case of a CCS 1 is subtracted.
+	 * This does not only differ CSS and Finished, it also maintains the order of the
+	 * index (important for priority queues) and fits in the unsigned short variable.
+	 */	
+	return seq * 2 - is_ccs;
+	}
+
+int
+dtls1_retransmit_buffered_messages(SSL *s)
+	{
+	pqueue sent = s->d1->sent_messages;
+	piterator iter;
+	pitem *item;
+	hm_fragment *frag;
+	int found = 0;
+
+	iter = pqueue_iterator(sent);
+
+	for ( item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter))
+		{
+		frag = (hm_fragment *)item->data;
+			if ( dtls1_retransmit_message(s,
+				(unsigned short)dtls1_get_queue_priority(frag->msg_header.seq, frag->msg_header.is_ccs),
+				0, &found) <= 0 && found)
+			{
+			fprintf(stderr, "dtls1_retransmit_message() failed\n");
+			return -1;
+			}
+		}
+
+	return 1;
+	}
+
+int
+dtls1_buffer_message(SSL *s, int is_ccs)
+	{
+	pitem *item;
+	hm_fragment *frag;
+	unsigned char seq64be[8];
+
+	/* this function is called immediately after a message has 
+	 * been serialized */
+	OPENSSL_assert(s->init_off == 0);
+
+	frag = dtls1_hm_fragment_new(s->init_num, 0);
+
+	memcpy(frag->fragment, s->init_buf->data, s->init_num);
+
+	if ( is_ccs)
+		{
+		OPENSSL_assert(s->d1->w_msg_hdr.msg_len + 
+			       ((s->version==DTLS1_VERSION)?DTLS1_CCS_HEADER_LENGTH:3) == (unsigned int)s->init_num);
+		}
+	else
+		{
+		OPENSSL_assert(s->d1->w_msg_hdr.msg_len + 
+			DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num);
+		}
+
+	frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len;
+	frag->msg_header.seq = s->d1->w_msg_hdr.seq;
+	frag->msg_header.type = s->d1->w_msg_hdr.type;
+	frag->msg_header.frag_off = 0;
+	frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len;
+	frag->msg_header.is_ccs = is_ccs;
+
+	/* save current state*/
+	frag->msg_header.saved_retransmit_state.enc_write_ctx = s->enc_write_ctx;
+	frag->msg_header.saved_retransmit_state.write_hash = s->write_hash;
+	frag->msg_header.saved_retransmit_state.compress = s->compress;
+	frag->msg_header.saved_retransmit_state.session = s->session;
+	frag->msg_header.saved_retransmit_state.epoch = s->d1->w_epoch;
+	
+	memset(seq64be,0,sizeof(seq64be));
+	seq64be[6] = (unsigned char)(dtls1_get_queue_priority(frag->msg_header.seq,
+														  frag->msg_header.is_ccs)>>8);
+	seq64be[7] = (unsigned char)(dtls1_get_queue_priority(frag->msg_header.seq,
+														  frag->msg_header.is_ccs));
+
+	item = pitem_new(seq64be, frag);
+	if ( item == NULL)
+		{
+		dtls1_hm_fragment_free(frag);
+		return 0;
+		}
+
+#if 0
+	fprintf( stderr, "buffered messge: \ttype = %xx\n", msg_buf->type);
+	fprintf( stderr, "\t\t\t\t\tlen = %d\n", msg_buf->len);
+	fprintf( stderr, "\t\t\t\t\tseq_num = %d\n", msg_buf->seq_num);
+#endif
+
+	pqueue_insert(s->d1->sent_messages, item);
+	return 1;
+	}
+
+int
+dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
+	int *found)
+	{
+	int ret;
+	/* XDTLS: for now assuming that read/writes are blocking */
+	pitem *item;
+	hm_fragment *frag ;
+	unsigned long header_length;
+	unsigned char seq64be[8];
+	struct dtls1_retransmit_state saved_state;
+	unsigned char save_write_sequence[8];
+
+	/*
+	  OPENSSL_assert(s->init_num == 0);
+	  OPENSSL_assert(s->init_off == 0);
+	 */
+
+	/* XDTLS:  the requested message ought to be found, otherwise error */
+	memset(seq64be,0,sizeof(seq64be));
+	seq64be[6] = (unsigned char)(seq>>8);
+	seq64be[7] = (unsigned char)seq;
+
+	item = pqueue_find(s->d1->sent_messages, seq64be);
+	if ( item == NULL)
+		{
+		fprintf(stderr, "retransmit:  message %d non-existant\n", seq);
+		*found = 0;
+		return 0;
+		}
+
+	*found = 1;
+	frag = (hm_fragment *)item->data;
+
+	if ( frag->msg_header.is_ccs)
+		header_length = DTLS1_CCS_HEADER_LENGTH;
+	else
+		header_length = DTLS1_HM_HEADER_LENGTH;
+
+	memcpy(s->init_buf->data, frag->fragment, 
+		frag->msg_header.msg_len + header_length);
+		s->init_num = frag->msg_header.msg_len + header_length;
+
+	dtls1_set_message_header_int(s, frag->msg_header.type, 
+		frag->msg_header.msg_len, frag->msg_header.seq, 0, 
+		frag->msg_header.frag_len);
+
+	/* save current state */
+	saved_state.enc_write_ctx = s->enc_write_ctx;
+	saved_state.write_hash = s->write_hash;
+	saved_state.compress = s->compress;
+	saved_state.session = s->session;
+	saved_state.epoch = s->d1->w_epoch;
+	saved_state.epoch = s->d1->w_epoch;
+	
+	s->d1->retransmitting = 1;
+	
+	/* restore state in which the message was originally sent */
+	s->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx;
+	s->write_hash = frag->msg_header.saved_retransmit_state.write_hash;
+	s->compress = frag->msg_header.saved_retransmit_state.compress;
+	s->session = frag->msg_header.saved_retransmit_state.session;
+	s->d1->w_epoch = frag->msg_header.saved_retransmit_state.epoch;
+	
+	if (frag->msg_header.saved_retransmit_state.epoch == saved_state.epoch - 1)
+	{
+		memcpy(save_write_sequence, s->s3->write_sequence, sizeof(s->s3->write_sequence));
+		memcpy(s->s3->write_sequence, s->d1->last_write_sequence, sizeof(s->s3->write_sequence));
+	}
+	
+	ret = dtls1_do_write(s, frag->msg_header.is_ccs ? 
+						 SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE);
+	
+	/* restore current state */
+	s->enc_write_ctx = saved_state.enc_write_ctx;
+	s->write_hash = saved_state.write_hash;
+	s->compress = saved_state.compress;
+	s->session = saved_state.session;
+	s->d1->w_epoch = saved_state.epoch;
+	
+	if (frag->msg_header.saved_retransmit_state.epoch == saved_state.epoch - 1)
+	{
+		memcpy(s->d1->last_write_sequence, s->s3->write_sequence, sizeof(s->s3->write_sequence));
+		memcpy(s->s3->write_sequence, save_write_sequence, sizeof(s->s3->write_sequence));
+	}
+
+	s->d1->retransmitting = 0;
+
+	(void)BIO_flush(SSL_get_wbio(s));
+	return ret;
+	}
+
+/* call this function when the buffered messages are no longer needed */
+void
+dtls1_clear_record_buffer(SSL *s)
+	{
+	pitem *item;
+
+	for(item = pqueue_pop(s->d1->sent_messages);
+		item != NULL; item = pqueue_pop(s->d1->sent_messages))
+		{
+		dtls1_hm_fragment_free((hm_fragment *)item->data);
+		pitem_free(item);
+		}
+	}
+
+
+unsigned char *
+dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt,
+			unsigned long len, unsigned long frag_off, unsigned long frag_len)
+	{
+	/* Don't change sequence numbers while listening */
+	if (frag_off == 0 && !s->d1->listen)
+		{
+		s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
+		s->d1->next_handshake_write_seq++;
+		}
+
+	dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq,
+		frag_off, frag_len);
+
+	return p += DTLS1_HM_HEADER_LENGTH;
+	}
+
+
+/* don't actually do the writing, wait till the MTU has been retrieved */
+static void
+dtls1_set_message_header_int(SSL *s, unsigned char mt,
+			    unsigned long len, unsigned short seq_num, unsigned long frag_off,
+			    unsigned long frag_len)
+	{
+	struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
+
+	msg_hdr->type = mt;
+	msg_hdr->msg_len = len;
+	msg_hdr->seq = seq_num;
+	msg_hdr->frag_off = frag_off;
+	msg_hdr->frag_len = frag_len;
+	}
+
+static void
+dtls1_fix_message_header(SSL *s, unsigned long frag_off,
+			unsigned long frag_len)
+	{
+	struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
+
+	msg_hdr->frag_off = frag_off;
+	msg_hdr->frag_len = frag_len;
+	}
+
+static unsigned char *
+dtls1_write_message_header(SSL *s, unsigned char *p)
+	{
+	struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
+
+	*p++ = msg_hdr->type;
+	l2n3(msg_hdr->msg_len, p);
+
+	s2n(msg_hdr->seq, p);
+	l2n3(msg_hdr->frag_off, p);
+	l2n3(msg_hdr->frag_len, p);
+
+	return p;
+	}
+
+unsigned int 
+dtls1_min_mtu(void)
+	{
+	return (g_probable_mtu[(sizeof(g_probable_mtu) / 
+		sizeof(g_probable_mtu[0])) - 1]);
+	}
+
+static unsigned int 
+dtls1_guess_mtu(unsigned int curr_mtu)
+	{
+	unsigned int i;
+
+	if ( curr_mtu == 0 )
+		return g_probable_mtu[0] ;
+
+	for ( i = 0; i < sizeof(g_probable_mtu)/sizeof(g_probable_mtu[0]); i++)
+		if ( curr_mtu > g_probable_mtu[i])
+			return g_probable_mtu[i];
+
+	return curr_mtu;
+	}
+
+void
+dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
+	{
+	memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
+	msg_hdr->type = *(data++);
+	n2l3(data, msg_hdr->msg_len);
+
+	n2s(data, msg_hdr->seq);
+	n2l3(data, msg_hdr->frag_off);
+	n2l3(data, msg_hdr->frag_len);
+	}
+
+void
+dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr)
+	{
+	memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st));
+
+	ccs_hdr->type = *(data++);
+	}
diff --git a/openssl/ssl/d1_clnt.c b/openssl/ssl/d1_clnt.c
new file mode 100644
index 0000000..5776671
--- /dev/null
+++ b/openssl/ssl/d1_clnt.c
@@ -0,0 +1,1542 @@
+/* ssl/d1_clnt.c */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "ssl_locl.h"
+#ifndef OPENSSL_NO_KRB5
+#include "kssl_lcl.h"
+#endif
+#include <openssl/buffer.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/md5.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+
+static const SSL_METHOD *dtls1_get_client_method(int ver);
+static int dtls1_get_hello_verify(SSL *s);
+
+static const SSL_METHOD *dtls1_get_client_method(int ver)
+	{
+	if (ver == DTLS1_VERSION || ver == DTLS1_BAD_VER)
+		return(DTLSv1_client_method());
+	else
+		return(NULL);
+	}
+
+IMPLEMENT_dtls1_meth_func(DTLSv1_client_method,
+			ssl_undefined_function,
+			dtls1_connect,
+			dtls1_get_client_method)
+
+int dtls1_connect(SSL *s)
+	{
+	BUF_MEM *buf=NULL;
+	unsigned long Time=(unsigned long)time(NULL);
+	void (*cb)(const SSL *ssl,int type,int val)=NULL;
+	int ret= -1;
+	int new_state,state,skip=0;;
+
+	RAND_add(&Time,sizeof(Time),0);
+	ERR_clear_error();
+	clear_sys_error();
+
+	if (s->info_callback != NULL)
+		cb=s->info_callback;
+	else if (s->ctx->info_callback != NULL)
+		cb=s->ctx->info_callback;
+	
+	s->in_handshake++;
+	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); 
+
+	for (;;)
+		{
+		state=s->state;
+
+		switch(s->state)
+			{
+		case SSL_ST_RENEGOTIATE:
+			s->new_session=1;
+			s->state=SSL_ST_CONNECT;
+			s->ctx->stats.sess_connect_renegotiate++;
+			/* break */
+		case SSL_ST_BEFORE:
+		case SSL_ST_CONNECT:
+		case SSL_ST_BEFORE|SSL_ST_CONNECT:
+		case SSL_ST_OK|SSL_ST_CONNECT:
+
+			s->server=0;
+			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
+
+			if ((s->version & 0xff00 ) != (DTLS1_VERSION & 0xff00) &&
+			    (s->version & 0xff00 ) != (DTLS1_BAD_VER & 0xff00))
+				{
+				SSLerr(SSL_F_DTLS1_CONNECT, ERR_R_INTERNAL_ERROR);
+				ret = -1;
+				goto end;
+				}
+				
+			/* s->version=SSL3_VERSION; */
+			s->type=SSL_ST_CONNECT;
+
+			if (s->init_buf == NULL)
+				{
+				if ((buf=BUF_MEM_new()) == NULL)
+					{
+					ret= -1;
+					goto end;
+					}
+				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
+					{
+					ret= -1;
+					goto end;
+					}
+				s->init_buf=buf;
+				buf=NULL;
+				}
+
+			if (!ssl3_setup_buffers(s)) { ret= -1; goto end; }
+
+			/* setup buffing BIO */
+			if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; }
+
+			/* don't push the buffering BIO quite yet */
+
+			s->state=SSL3_ST_CW_CLNT_HELLO_A;
+			s->ctx->stats.sess_connect++;
+			s->init_num=0;
+			/* mark client_random uninitialized */
+			memset(s->s3->client_random,0,sizeof(s->s3->client_random));
+			s->d1->send_cookie = 0;
+			s->hit = 0;
+			break;
+
+		case SSL3_ST_CW_CLNT_HELLO_A:
+		case SSL3_ST_CW_CLNT_HELLO_B:
+
+			s->shutdown=0;
+
+			/* every DTLS ClientHello resets Finished MAC */
+			ssl3_init_finished_mac(s);
+
+			dtls1_start_timer(s);
+			ret=dtls1_client_hello(s);
+			if (ret <= 0) goto end;
+
+			if ( s->d1->send_cookie)
+				{
+				s->state=SSL3_ST_CW_FLUSH;
+				s->s3->tmp.next_state=SSL3_ST_CR_SRVR_HELLO_A;
+				}
+			else
+				s->state=SSL3_ST_CR_SRVR_HELLO_A;
+
+			s->init_num=0;
+
+			/* turn on buffering for the next lot of output */
+			if (s->bbio != s->wbio)
+				s->wbio=BIO_push(s->bbio,s->wbio);
+
+			break;
+
+		case SSL3_ST_CR_SRVR_HELLO_A:
+		case SSL3_ST_CR_SRVR_HELLO_B:
+			ret=ssl3_get_server_hello(s);
+			if (ret <= 0) goto end;
+			else
+				{
+				dtls1_stop_timer(s);
+				if (s->hit)
+					s->state=SSL3_ST_CR_FINISHED_A;
+				else
+					s->state=DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A;
+				}
+			s->init_num=0;
+			break;
+
+		case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
+		case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
+
+			ret = dtls1_get_hello_verify(s);
+			if ( ret <= 0)
+				goto end;
+			dtls1_stop_timer(s);
+			if ( s->d1->send_cookie) /* start again, with a cookie */
+				s->state=SSL3_ST_CW_CLNT_HELLO_A;
+			else
+				s->state = SSL3_ST_CR_CERT_A;
+			s->init_num = 0;
+			break;
+
+		case SSL3_ST_CR_CERT_A:
+		case SSL3_ST_CR_CERT_B:
+#ifndef OPENSSL_NO_TLSEXT
+			ret=ssl3_check_finished(s);
+			if (ret <= 0) goto end;
+			if (ret == 2)
+				{
+				s->hit = 1;
+				if (s->tlsext_ticket_expected)
+					s->state=SSL3_ST_CR_SESSION_TICKET_A;
+				else
+					s->state=SSL3_ST_CR_FINISHED_A;
+				s->init_num=0;
+				break;
+				}
+#endif
+			/* Check if it is anon DH or PSK */
+			if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
+			    !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
+				{
+				ret=ssl3_get_server_certificate(s);
+				if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_TLSEXT
+				if (s->tlsext_status_expected)
+					s->state=SSL3_ST_CR_CERT_STATUS_A;
+				else
+					s->state=SSL3_ST_CR_KEY_EXCH_A;
+				}
+			else
+				{
+				skip = 1;
+				s->state=SSL3_ST_CR_KEY_EXCH_A;
+				}
+#else
+				}
+			else
+				skip=1;
+
+			s->state=SSL3_ST_CR_KEY_EXCH_A;
+#endif
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_CR_KEY_EXCH_A:
+		case SSL3_ST_CR_KEY_EXCH_B:
+			ret=ssl3_get_key_exchange(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_CR_CERT_REQ_A;
+			s->init_num=0;
+
+			/* at this point we check that we have the
+			 * required stuff from the server */
+			if (!ssl3_check_cert_and_algorithm(s))
+				{
+				ret= -1;
+				goto end;
+				}
+			break;
+
+		case SSL3_ST_CR_CERT_REQ_A:
+		case SSL3_ST_CR_CERT_REQ_B:
+			ret=ssl3_get_certificate_request(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_CR_SRVR_DONE_A;
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_CR_SRVR_DONE_A:
+		case SSL3_ST_CR_SRVR_DONE_B:
+			ret=ssl3_get_server_done(s);
+			if (ret <= 0) goto end;
+			if (s->s3->tmp.cert_req)
+				s->state=SSL3_ST_CW_CERT_A;
+			else
+				s->state=SSL3_ST_CW_KEY_EXCH_A;
+			s->init_num=0;
+
+			break;
+
+		case SSL3_ST_CW_CERT_A:
+		case SSL3_ST_CW_CERT_B:
+		case SSL3_ST_CW_CERT_C:
+		case SSL3_ST_CW_CERT_D:
+			dtls1_start_timer(s);
+			ret=dtls1_send_client_certificate(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_CW_KEY_EXCH_A;
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_CW_KEY_EXCH_A:
+		case SSL3_ST_CW_KEY_EXCH_B:
+			dtls1_start_timer(s);
+			ret=dtls1_send_client_key_exchange(s);
+			if (ret <= 0) goto end;
+			/* EAY EAY EAY need to check for DH fix cert
+			 * sent back */
+			/* For TLS, cert_req is set to 2, so a cert chain
+			 * of nothing is sent, but no verify packet is sent */
+			if (s->s3->tmp.cert_req == 1)
+				{
+				s->state=SSL3_ST_CW_CERT_VRFY_A;
+				}
+			else
+				{
+				s->state=SSL3_ST_CW_CHANGE_A;
+				s->s3->change_cipher_spec=0;
+				}
+
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_CW_CERT_VRFY_A:
+		case SSL3_ST_CW_CERT_VRFY_B:
+			dtls1_start_timer(s);
+			ret=dtls1_send_client_verify(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_CW_CHANGE_A;
+			s->init_num=0;
+			s->s3->change_cipher_spec=0;
+			break;
+
+		case SSL3_ST_CW_CHANGE_A:
+		case SSL3_ST_CW_CHANGE_B:
+			if (!s->hit)
+				dtls1_start_timer(s);
+			ret=dtls1_send_change_cipher_spec(s,
+				SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_CW_FINISHED_A;
+			s->init_num=0;
+
+			s->session->cipher=s->s3->tmp.new_cipher;
+#ifdef OPENSSL_NO_COMP
+			s->session->compress_meth=0;
+#else
+			if (s->s3->tmp.new_compression == NULL)
+				s->session->compress_meth=0;
+			else
+				s->session->compress_meth=
+					s->s3->tmp.new_compression->id;
+#endif
+			if (!s->method->ssl3_enc->setup_key_block(s))
+				{
+				ret= -1;
+				goto end;
+				}
+
+			if (!s->method->ssl3_enc->change_cipher_state(s,
+				SSL3_CHANGE_CIPHER_CLIENT_WRITE))
+				{
+				ret= -1;
+				goto end;
+				}
+			
+			dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
+			break;
+
+		case SSL3_ST_CW_FINISHED_A:
+		case SSL3_ST_CW_FINISHED_B:
+			if (!s->hit)
+				dtls1_start_timer(s);
+			ret=dtls1_send_finished(s,
+				SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,
+				s->method->ssl3_enc->client_finished_label,
+				s->method->ssl3_enc->client_finished_label_len);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_CW_FLUSH;
+
+			/* clear flags */
+			s->s3->flags&= ~SSL3_FLAGS_POP_BUFFER;
+			if (s->hit)
+				{
+				s->s3->tmp.next_state=SSL_ST_OK;
+				if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED)
+					{
+					s->state=SSL_ST_OK;
+					s->s3->flags|=SSL3_FLAGS_POP_BUFFER;
+					s->s3->delay_buf_pop_ret=0;
+					}
+				}
+			else
+				{
+#ifndef OPENSSL_NO_TLSEXT
+				/* Allow NewSessionTicket if ticket expected */
+				if (s->tlsext_ticket_expected)
+					s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
+				else
+#endif
+				
+				s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
+				}
+			s->init_num=0;
+			break;
+
+#ifndef OPENSSL_NO_TLSEXT
+		case SSL3_ST_CR_SESSION_TICKET_A:
+		case SSL3_ST_CR_SESSION_TICKET_B:
+			ret=ssl3_get_new_session_ticket(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_CR_FINISHED_A;
+			s->init_num=0;
+		break;
+
+		case SSL3_ST_CR_CERT_STATUS_A:
+		case SSL3_ST_CR_CERT_STATUS_B:
+			ret=ssl3_get_cert_status(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_CR_KEY_EXCH_A;
+			s->init_num=0;
+		break;
+#endif
+
+		case SSL3_ST_CR_FINISHED_A:
+		case SSL3_ST_CR_FINISHED_B:
+			s->d1->change_cipher_spec_ok = 1;
+			ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
+				SSL3_ST_CR_FINISHED_B);
+			if (ret <= 0) goto end;
+			dtls1_stop_timer(s);
+
+			if (s->hit)
+				s->state=SSL3_ST_CW_CHANGE_A;
+			else
+				s->state=SSL_ST_OK;
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_CW_FLUSH:
+			s->rwstate=SSL_WRITING;
+			if (BIO_flush(s->wbio) <= 0)
+				{
+				ret= -1;
+				goto end;
+				}
+			s->rwstate=SSL_NOTHING;
+			s->state=s->s3->tmp.next_state;
+			break;
+
+		case SSL_ST_OK:
+			/* clean a few things up */
+			ssl3_cleanup_key_block(s);
+
+#if 0
+			if (s->init_buf != NULL)
+				{
+				BUF_MEM_free(s->init_buf);
+				s->init_buf=NULL;
+				}
+#endif
+
+			/* If we are not 'joining' the last two packets,
+			 * remove the buffering now */
+			if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER))
+				ssl_free_wbio_buffer(s);
+			/* else do it later in ssl3_write */
+
+			s->init_num=0;
+			s->new_session=0;
+
+			ssl_update_cache(s,SSL_SESS_CACHE_CLIENT);
+			if (s->hit) s->ctx->stats.sess_hit++;
+
+			ret=1;
+			/* s->server=0; */
+			s->handshake_func=dtls1_connect;
+			s->ctx->stats.sess_connect_good++;
+
+			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
+
+			/* done with handshaking */
+			s->d1->handshake_read_seq  = 0;
+			s->d1->next_handshake_write_seq = 0;
+			goto end;
+			/* break; */
+			
+		default:
+			SSLerr(SSL_F_DTLS1_CONNECT,SSL_R_UNKNOWN_STATE);
+			ret= -1;
+			goto end;
+			/* break; */
+			}
+
+		/* did we do anything */
+		if (!s->s3->tmp.reuse_message && !skip)
+			{
+			if (s->debug)
+				{
+				if ((ret=BIO_flush(s->wbio)) <= 0)
+					goto end;
+				}
+
+			if ((cb != NULL) && (s->state != state))
+				{
+				new_state=s->state;
+				s->state=state;
+				cb(s,SSL_CB_CONNECT_LOOP,1);
+				s->state=new_state;
+				}
+			}
+		skip=0;
+		}
+end:
+	s->in_handshake--;
+	if (buf != NULL)
+		BUF_MEM_free(buf);
+	if (cb != NULL)
+		cb(s,SSL_CB_CONNECT_EXIT,ret);
+	return(ret);
+	}
+
+int dtls1_client_hello(SSL *s)
+	{
+	unsigned char *buf;
+	unsigned char *p,*d;
+	unsigned int i,j;
+	unsigned long Time,l;
+	SSL_COMP *comp;
+
+	buf=(unsigned char *)s->init_buf->data;
+	if (s->state == SSL3_ST_CW_CLNT_HELLO_A)
+		{
+		SSL_SESSION *sess = s->session;
+		if ((s->session == NULL) ||
+			(s->session->ssl_version != s->version) ||
+#ifdef OPENSSL_NO_TLSEXT
+			!sess->session_id_length ||
+#else
+			(!sess->session_id_length && !sess->tlsext_tick) ||
+#endif
+			(s->session->not_resumable))
+			{
+		        if (!s->session_creation_enabled)
+				{
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+				SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
+				goto err;
+				}
+			if (!ssl_get_new_session(s,0))
+				goto err;
+			}
+		/* else use the pre-loaded session */
+
+		p=s->s3->client_random;
+
+		/* if client_random is initialized, reuse it, we are
+		 * required to use same upon reply to HelloVerify */
+		for (i=0;p[i]=='\0' && i<sizeof(s->s3->client_random);i++) ;
+		if (i==sizeof(s->s3->client_random))
+			{
+			Time=(unsigned long)time(NULL);	/* Time */
+			l2n(Time,p);
+			RAND_pseudo_bytes(p,sizeof(s->s3->client_random)-4);
+			}
+
+		/* Do the message type and length last */
+		d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
+
+		*(p++)=s->version>>8;
+		*(p++)=s->version&0xff;
+		s->client_version=s->version;
+
+		/* Random stuff */
+		memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
+		p+=SSL3_RANDOM_SIZE;
+
+		/* Session ID */
+		if (s->new_session)
+			i=0;
+		else
+			i=s->session->session_id_length;
+		*(p++)=i;
+		if (i != 0)
+			{
+			if (i > sizeof s->session->session_id)
+				{
+				SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+			memcpy(p,s->session->session_id,i);
+			p+=i;
+			}
+		
+		/* cookie stuff */
+		if ( s->d1->cookie_len > sizeof(s->d1->cookie))
+			{
+			SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+		*(p++) = s->d1->cookie_len;
+		memcpy(p, s->d1->cookie, s->d1->cookie_len);
+		p += s->d1->cookie_len;
+
+		/* Ciphers supported */
+		i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),0);
+		if (i == 0)
+			{
+			SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
+			goto err;
+			}
+		s2n(i,p);
+		p+=i;
+
+		/* COMPRESSION */
+		if (s->ctx->comp_methods == NULL)
+			j=0;
+		else
+			j=sk_SSL_COMP_num(s->ctx->comp_methods);
+		*(p++)=1+j;
+		for (i=0; i<j; i++)
+			{
+			comp=sk_SSL_COMP_value(s->ctx->comp_methods,i);
+			*(p++)=comp->id;
+			}
+		*(p++)=0; /* Add the NULL method */
+
+#ifndef OPENSSL_NO_TLSEXT
+		if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
+			{
+			SSLerr(SSL_F_DTLS1_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+#endif		
+
+		l=(p-d);
+		d=buf;
+
+		d = dtls1_set_message_header(s, d, SSL3_MT_CLIENT_HELLO, l, 0, l);
+
+		s->state=SSL3_ST_CW_CLNT_HELLO_B;
+		/* number of bytes to write */
+		s->init_num=p-buf;
+		s->init_off=0;
+
+		/* buffer the message to handle re-xmits */
+		dtls1_buffer_message(s, 0);
+		}
+
+	/* SSL3_ST_CW_CLNT_HELLO_B */
+	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
+err:
+	return(-1);
+	}
+
+static int dtls1_get_hello_verify(SSL *s)
+	{
+	int n, al, ok = 0;
+	unsigned char *data;
+	unsigned int cookie_len;
+
+	n=s->method->ssl_get_message(s,
+		DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A,
+		DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B,
+		-1,
+		s->max_cert_list,
+		&ok);
+
+	if (!ok) return((int)n);
+
+	if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST)
+		{
+		s->d1->send_cookie = 0;
+		s->s3->tmp.reuse_message=1;
+		return(1);
+		}
+
+	data = (unsigned char *)s->init_msg;
+
+	if ((data[0] != (s->version>>8)) || (data[1] != (s->version&0xff)))
+		{
+		SSLerr(SSL_F_DTLS1_GET_HELLO_VERIFY,SSL_R_WRONG_SSL_VERSION);
+		s->version=(s->version&0xff00)|data[1];
+		al = SSL_AD_PROTOCOL_VERSION;
+		goto f_err;
+		}
+	data+=2;
+
+	cookie_len = *(data++);
+	if ( cookie_len > sizeof(s->d1->cookie))
+		{
+		al=SSL_AD_ILLEGAL_PARAMETER;
+		goto f_err;
+		}
+
+	memcpy(s->d1->cookie, data, cookie_len);
+	s->d1->cookie_len = cookie_len;
+
+	s->d1->send_cookie = 1;
+	return 1;
+
+f_err:
+	ssl3_send_alert(s, SSL3_AL_FATAL, al);
+	return -1;
+	}
+
+int dtls1_send_client_key_exchange(SSL *s)
+	{
+	unsigned char *p,*d;
+	int n;
+	unsigned long alg_k;
+#ifndef OPENSSL_NO_RSA
+	unsigned char *q;
+	EVP_PKEY *pkey=NULL;
+#endif
+#ifndef OPENSSL_NO_KRB5
+        KSSL_ERR kssl_err;
+#endif /* OPENSSL_NO_KRB5 */
+#ifndef OPENSSL_NO_ECDH
+	EC_KEY *clnt_ecdh = NULL;
+	const EC_POINT *srvr_ecpoint = NULL;
+	EVP_PKEY *srvr_pub_pkey = NULL;
+	unsigned char *encodedPoint = NULL;
+	int encoded_pt_len = 0;
+	BN_CTX * bn_ctx = NULL;
+#endif
+
+	if (s->state == SSL3_ST_CW_KEY_EXCH_A)
+		{
+		d=(unsigned char *)s->init_buf->data;
+		p= &(d[DTLS1_HM_HEADER_LENGTH]);
+		
+		alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
+
+                /* Fool emacs indentation */
+                if (0) {}
+#ifndef OPENSSL_NO_RSA
+		else if (alg_k & SSL_kRSA)
+			{
+			RSA *rsa;
+			unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
+
+			if (s->session->sess_cert->peer_rsa_tmp != NULL)
+				rsa=s->session->sess_cert->peer_rsa_tmp;
+			else
+				{
+				pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
+				if ((pkey == NULL) ||
+					(pkey->type != EVP_PKEY_RSA) ||
+					(pkey->pkey.rsa == NULL))
+					{
+					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+					goto err;
+					}
+				rsa=pkey->pkey.rsa;
+				EVP_PKEY_free(pkey);
+				}
+				
+			tmp_buf[0]=s->client_version>>8;
+			tmp_buf[1]=s->client_version&0xff;
+			if (RAND_bytes(&(tmp_buf[2]),sizeof tmp_buf-2) <= 0)
+					goto err;
+
+			s->session->master_key_length=sizeof tmp_buf;
+
+			q=p;
+			/* Fix buf for TLS and [incidentally] DTLS */
+			if (s->version > SSL3_VERSION)
+				p+=2;
+			n=RSA_public_encrypt(sizeof tmp_buf,
+				tmp_buf,p,rsa,RSA_PKCS1_PADDING);
+#ifdef PKCS1_CHECK
+			if (s->options & SSL_OP_PKCS1_CHECK_1) p[1]++;
+			if (s->options & SSL_OP_PKCS1_CHECK_2) tmp_buf[0]=0x70;
+#endif
+			if (n <= 0)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_ENCRYPT);
+				goto err;
+				}
+
+			/* Fix buf for TLS and [incidentally] DTLS */
+			if (s->version > SSL3_VERSION)
+				{
+				s2n(n,q);
+				n+=2;
+				}
+
+			s->session->master_key_length=
+				s->method->ssl3_enc->generate_master_secret(s,
+					s->session->master_key,
+					tmp_buf,sizeof tmp_buf);
+			OPENSSL_cleanse(tmp_buf,sizeof tmp_buf);
+			}
+#endif
+#ifndef OPENSSL_NO_KRB5
+		else if (alg_k & SSL_kKRB5)
+                        {
+                        krb5_error_code	krb5rc;
+                        KSSL_CTX	*kssl_ctx = s->kssl_ctx;
+                        /*  krb5_data	krb5_ap_req;  */
+                        krb5_data	*enc_ticket;
+                        krb5_data	authenticator, *authp = NULL;
+			EVP_CIPHER_CTX	ciph_ctx;
+			const EVP_CIPHER *enc = NULL;
+			unsigned char	iv[EVP_MAX_IV_LENGTH];
+			unsigned char	tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
+			unsigned char	epms[SSL_MAX_MASTER_KEY_LENGTH 
+						+ EVP_MAX_IV_LENGTH];
+			int 		padl, outl = sizeof(epms);
+
+			EVP_CIPHER_CTX_init(&ciph_ctx);
+
+#ifdef KSSL_DEBUG
+                        printf("ssl3_send_client_key_exchange(%lx & %lx)\n",
+                                alg_k, SSL_kKRB5);
+#endif	/* KSSL_DEBUG */
+
+			authp = NULL;
+#ifdef KRB5SENDAUTH
+			if (KRB5SENDAUTH)  authp = &authenticator;
+#endif	/* KRB5SENDAUTH */
+
+                        krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp,
+				&kssl_err);
+			enc = kssl_map_enc(kssl_ctx->enctype);
+                        if (enc == NULL)
+                            goto err;
+#ifdef KSSL_DEBUG
+                        {
+                        printf("kssl_cget_tkt rtn %d\n", krb5rc);
+                        if (krb5rc && kssl_err.text)
+			  printf("kssl_cget_tkt kssl_err=%s\n", kssl_err.text);
+                        }
+#endif	/* KSSL_DEBUG */
+
+                        if (krb5rc)
+                                {
+                                ssl3_send_alert(s,SSL3_AL_FATAL,
+						SSL_AD_HANDSHAKE_FAILURE);
+                                SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
+						kssl_err.reason);
+                                goto err;
+                                }
+
+			/*  20010406 VRS - Earlier versions used KRB5 AP_REQ
+			**  in place of RFC 2712 KerberosWrapper, as in:
+			**
+                        **  Send ticket (copy to *p, set n = length)
+                        **  n = krb5_ap_req.length;
+                        **  memcpy(p, krb5_ap_req.data, krb5_ap_req.length);
+                        **  if (krb5_ap_req.data)  
+                        **    kssl_krb5_free_data_contents(NULL,&krb5_ap_req);
+                        **
+			**  Now using real RFC 2712 KerberosWrapper
+			**  (Thanks to Simon Wilkinson <sxw@sxw.org.uk>)
+			**  Note: 2712 "opaque" types are here replaced
+			**  with a 2-byte length followed by the value.
+			**  Example:
+			**  KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms
+			**  Where "xx xx" = length bytes.  Shown here with
+			**  optional authenticator omitted.
+			*/
+
+			/*  KerberosWrapper.Ticket		*/
+			s2n(enc_ticket->length,p);
+			memcpy(p, enc_ticket->data, enc_ticket->length);
+			p+= enc_ticket->length;
+			n = enc_ticket->length + 2;
+
+			/*  KerberosWrapper.Authenticator	*/
+			if (authp  &&  authp->length)  
+				{
+				s2n(authp->length,p);
+				memcpy(p, authp->data, authp->length);
+				p+= authp->length;
+				n+= authp->length + 2;
+				
+				free(authp->data);
+				authp->data = NULL;
+				authp->length = 0;
+				}
+			else
+				{
+				s2n(0,p);/*  null authenticator length	*/
+				n+=2;
+				}
+ 
+			if (RAND_bytes(tmp_buf,sizeof tmp_buf) <= 0)
+			    goto err;
+
+			/*  20010420 VRS.  Tried it this way; failed.
+			**	EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,NULL);
+			**	EVP_CIPHER_CTX_set_key_length(&ciph_ctx,
+			**				kssl_ctx->length);
+			**	EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv);
+			*/
+
+			memset(iv, 0, sizeof iv);  /* per RFC 1510 */
+			EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,
+				kssl_ctx->key,iv);
+			EVP_EncryptUpdate(&ciph_ctx,epms,&outl,tmp_buf,
+				sizeof tmp_buf);
+			EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl);
+			outl += padl;
+			if (outl > (int)sizeof epms)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+			EVP_CIPHER_CTX_cleanup(&ciph_ctx);
+
+			/*  KerberosWrapper.EncryptedPreMasterSecret	*/
+			s2n(outl,p);
+			memcpy(p, epms, outl);
+			p+=outl;
+			n+=outl + 2;
+
+                        s->session->master_key_length=
+                                s->method->ssl3_enc->generate_master_secret(s,
+					s->session->master_key,
+					tmp_buf, sizeof tmp_buf);
+
+			OPENSSL_cleanse(tmp_buf, sizeof tmp_buf);
+			OPENSSL_cleanse(epms, outl);
+                        }
+#endif
+#ifndef OPENSSL_NO_DH
+		else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
+			{
+			DH *dh_srvr,*dh_clnt;
+
+			if (s->session->sess_cert->peer_dh_tmp != NULL)
+				dh_srvr=s->session->sess_cert->peer_dh_tmp;
+			else
+				{
+				/* we get them from the cert */
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_DH_PARAMETERS);
+				goto err;
+				}
+			
+			/* generate a new random key */
+			if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
+				goto err;
+				}
+			if (!DH_generate_key(dh_clnt))
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
+				goto err;
+				}
+
+			/* use the 'p' output buffer for the DH key, but
+			 * make sure to clear it out afterwards */
+
+			n=DH_compute_key(p,dh_srvr->pub_key,dh_clnt);
+
+			if (n <= 0)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
+				goto err;
+				}
+
+			/* generate master key from the result */
+			s->session->master_key_length=
+				s->method->ssl3_enc->generate_master_secret(s,
+					s->session->master_key,p,n);
+			/* clean up */
+			memset(p,0,n);
+
+			/* send off the data */
+			n=BN_num_bytes(dh_clnt->pub_key);
+			s2n(n,p);
+			BN_bn2bin(dh_clnt->pub_key,p);
+			n+=2;
+
+			DH_free(dh_clnt);
+
+			/* perhaps clean things up a bit EAY EAY EAY EAY*/
+			}
+#endif
+#ifndef OPENSSL_NO_ECDH 
+		else if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe))
+			{
+			const EC_GROUP *srvr_group = NULL;
+			EC_KEY *tkey;
+			int ecdh_clnt_cert = 0;
+			int field_size = 0;
+
+			/* Did we send out the client's
+			 * ECDH share for use in premaster
+			 * computation as part of client certificate?
+			 * If so, set ecdh_clnt_cert to 1.
+			 */
+			if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->cert != NULL)) 
+				{
+				/* XXX: For now, we do not support client
+				 * authentication using ECDH certificates.
+				 * To add such support, one needs to add
+				 * code that checks for appropriate 
+				 * conditions and sets ecdh_clnt_cert to 1.
+				 * For example, the cert have an ECC
+				 * key on the same curve as the server's
+				 * and the key should be authorized for
+				 * key agreement.
+				 *
+				 * One also needs to add code in ssl3_connect
+				 * to skip sending the certificate verify
+				 * message.
+				 *
+				 * if ((s->cert->key->privatekey != NULL) &&
+				 *     (s->cert->key->privatekey->type ==
+				 *      EVP_PKEY_EC) && ...)
+				 * ecdh_clnt_cert = 1;
+				 */
+				}
+
+			if (s->session->sess_cert->peer_ecdh_tmp != NULL)
+				{
+				tkey = s->session->sess_cert->peer_ecdh_tmp;
+				}
+			else
+				{
+				/* Get the Server Public Key from Cert */
+				srvr_pub_pkey = X509_get_pubkey(s->session-> \
+				    sess_cert->peer_pkeys[SSL_PKEY_ECC].x509);
+				if ((srvr_pub_pkey == NULL) ||
+				    (srvr_pub_pkey->type != EVP_PKEY_EC) ||
+				    (srvr_pub_pkey->pkey.ec == NULL))
+					{
+					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
+					    ERR_R_INTERNAL_ERROR);
+					goto err;
+					}
+
+				tkey = srvr_pub_pkey->pkey.ec;
+				}
+
+			srvr_group   = EC_KEY_get0_group(tkey);
+			srvr_ecpoint = EC_KEY_get0_public_key(tkey);
+
+			if ((srvr_group == NULL) || (srvr_ecpoint == NULL))
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
+				    ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+
+			if ((clnt_ecdh=EC_KEY_new()) == NULL) 
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+
+			if (!EC_KEY_set_group(clnt_ecdh, srvr_group))
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB);
+				goto err;
+				}
+			if (ecdh_clnt_cert) 
+				{ 
+				/* Reuse key info from our certificate
+				 * We only need our private key to perform
+				 * the ECDH computation.
+				 */
+				const BIGNUM *priv_key;
+				tkey = s->cert->key->privatekey->pkey.ec;
+				priv_key = EC_KEY_get0_private_key(tkey);
+				if (priv_key == NULL)
+					{
+					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+					goto err;
+					}
+				if (!EC_KEY_set_private_key(clnt_ecdh, priv_key))
+					{
+					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB);
+					goto err;
+					}
+				}
+			else 
+				{
+				/* Generate a new ECDH key pair */
+				if (!(EC_KEY_generate_key(clnt_ecdh)))
+					{
+					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB);
+					goto err;
+					}
+				}
+
+			/* use the 'p' output buffer for the ECDH key, but
+			 * make sure to clear it out afterwards
+			 */
+
+			field_size = EC_GROUP_get_degree(srvr_group);
+			if (field_size <= 0)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, 
+				       ERR_R_ECDH_LIB);
+				goto err;
+				}
+			n=ECDH_compute_key(p, (field_size+7)/8, srvr_ecpoint, clnt_ecdh, NULL);
+			if (n <= 0)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, 
+				       ERR_R_ECDH_LIB);
+				goto err;
+				}
+
+			/* generate master key from the result */
+			s->session->master_key_length = s->method->ssl3_enc \
+			    -> generate_master_secret(s, 
+				s->session->master_key,
+				p, n);
+
+			memset(p, 0, n); /* clean up */
+
+			if (ecdh_clnt_cert) 
+				{
+				/* Send empty client key exch message */
+				n = 0;
+				}
+			else 
+				{
+				/* First check the size of encoding and
+				 * allocate memory accordingly.
+				 */
+				encoded_pt_len = 
+				    EC_POINT_point2oct(srvr_group, 
+					EC_KEY_get0_public_key(clnt_ecdh), 
+					POINT_CONVERSION_UNCOMPRESSED, 
+					NULL, 0, NULL);
+
+				encodedPoint = (unsigned char *) 
+				    OPENSSL_malloc(encoded_pt_len * 
+					sizeof(unsigned char)); 
+				bn_ctx = BN_CTX_new();
+				if ((encodedPoint == NULL) || 
+				    (bn_ctx == NULL)) 
+					{
+					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+					goto err;
+					}
+
+				/* Encode the public key */
+				n = EC_POINT_point2oct(srvr_group, 
+				    EC_KEY_get0_public_key(clnt_ecdh), 
+				    POINT_CONVERSION_UNCOMPRESSED, 
+				    encodedPoint, encoded_pt_len, bn_ctx);
+
+				*p = n; /* length of encoded point */
+				/* Encoded point will be copied here */
+				p += 1; 
+				/* copy the point */
+				memcpy((unsigned char *)p, encodedPoint, n);
+				/* increment n to account for length field */
+				n += 1; 
+				}
+
+			/* Free allocated memory */
+			BN_CTX_free(bn_ctx);
+			if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
+			if (clnt_ecdh != NULL) 
+				 EC_KEY_free(clnt_ecdh);
+			EVP_PKEY_free(srvr_pub_pkey);
+			}
+#endif /* !OPENSSL_NO_ECDH */
+
+#ifndef OPENSSL_NO_PSK
+		else if (alg_k & SSL_kPSK)
+			{
+			char identity[PSK_MAX_IDENTITY_LEN];
+			unsigned char *t = NULL;
+			unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4];
+			unsigned int pre_ms_len = 0, psk_len = 0;
+			int psk_err = 1;
+
+			n = 0;
+			if (s->psk_client_callback == NULL)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
+					SSL_R_PSK_NO_CLIENT_CB);
+				goto err;
+				}
+
+			psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint,
+				identity, PSK_MAX_IDENTITY_LEN,
+				psk_or_pre_ms, sizeof(psk_or_pre_ms));
+			if (psk_len > PSK_MAX_PSK_LEN)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
+					ERR_R_INTERNAL_ERROR);
+				goto psk_err;
+				}
+			else if (psk_len == 0)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
+					SSL_R_PSK_IDENTITY_NOT_FOUND);
+				goto psk_err;
+				}
+
+			/* create PSK pre_master_secret */
+			pre_ms_len = 2+psk_len+2+psk_len;
+			t = psk_or_pre_ms;
+			memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len);
+			s2n(psk_len, t);
+			memset(t, 0, psk_len);
+			t+=psk_len;
+			s2n(psk_len, t);
+
+			if (s->session->psk_identity_hint != NULL)
+				OPENSSL_free(s->session->psk_identity_hint);
+			s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint);
+			if (s->ctx->psk_identity_hint != NULL &&
+				s->session->psk_identity_hint == NULL)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
+					ERR_R_MALLOC_FAILURE);
+				goto psk_err;
+				}
+
+			if (s->session->psk_identity != NULL)
+				OPENSSL_free(s->session->psk_identity);
+			s->session->psk_identity = BUF_strdup(identity);
+			if (s->session->psk_identity == NULL)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
+					ERR_R_MALLOC_FAILURE);
+				goto psk_err;
+				}
+
+			s->session->master_key_length =
+				s->method->ssl3_enc->generate_master_secret(s,
+					s->session->master_key,
+					psk_or_pre_ms, pre_ms_len); 
+			n = strlen(identity);
+			s2n(n, p);
+			memcpy(p, identity, n);
+			n+=2;
+			psk_err = 0;
+		psk_err:
+			OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN);
+			OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
+			if (psk_err != 0)
+				{
+				ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+				goto err;
+				}
+			}
+#endif
+		else
+			{
+			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+			SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+		
+		d = dtls1_set_message_header(s, d,
+		SSL3_MT_CLIENT_KEY_EXCHANGE, n, 0, n);
+		/*
+		 *(d++)=SSL3_MT_CLIENT_KEY_EXCHANGE;
+		 l2n3(n,d);
+		 l2n(s->d1->handshake_write_seq,d);
+		 s->d1->handshake_write_seq++;
+		*/
+		
+		s->state=SSL3_ST_CW_KEY_EXCH_B;
+		/* number of bytes to write */
+		s->init_num=n+DTLS1_HM_HEADER_LENGTH;
+		s->init_off=0;
+
+		/* buffer the message to handle re-xmits */
+		dtls1_buffer_message(s, 0);
+		}
+	
+	/* SSL3_ST_CW_KEY_EXCH_B */
+	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
+err:
+#ifndef OPENSSL_NO_ECDH
+	BN_CTX_free(bn_ctx);
+	if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
+	if (clnt_ecdh != NULL) 
+		EC_KEY_free(clnt_ecdh);
+	EVP_PKEY_free(srvr_pub_pkey);
+#endif
+	return(-1);
+	}
+
+int dtls1_send_client_verify(SSL *s)
+	{
+	unsigned char *p,*d;
+	unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
+	EVP_PKEY *pkey;
+#ifndef OPENSSL_NO_RSA
+	unsigned u=0;
+#endif
+	unsigned long n;
+#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
+	int j;
+#endif
+
+	if (s->state == SSL3_ST_CW_CERT_VRFY_A)
+		{
+		d=(unsigned char *)s->init_buf->data;
+		p= &(d[DTLS1_HM_HEADER_LENGTH]);
+		pkey=s->cert->key->privatekey;
+
+		s->method->ssl3_enc->cert_verify_mac(s,
+		NID_sha1,
+			&(data[MD5_DIGEST_LENGTH]));
+
+#ifndef OPENSSL_NO_RSA
+		if (pkey->type == EVP_PKEY_RSA)
+			{
+			s->method->ssl3_enc->cert_verify_mac(s,
+				NID_md5,
+				&(data[0]));
+			if (RSA_sign(NID_md5_sha1, data,
+					 MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH,
+					&(p[2]), &u, pkey->pkey.rsa) <= 0 )
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_RSA_LIB);
+				goto err;
+				}
+			s2n(u,p);
+			n=u+2;
+			}
+		else
+#endif
+#ifndef OPENSSL_NO_DSA
+			if (pkey->type == EVP_PKEY_DSA)
+			{
+			if (!DSA_sign(pkey->save_type,
+				&(data[MD5_DIGEST_LENGTH]),
+				SHA_DIGEST_LENGTH,&(p[2]),
+				(unsigned int *)&j,pkey->pkey.dsa))
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_DSA_LIB);
+				goto err;
+				}
+			s2n(j,p);
+			n=j+2;
+			}
+		else
+#endif
+#ifndef OPENSSL_NO_ECDSA
+			if (pkey->type == EVP_PKEY_EC)
+			{
+			if (!ECDSA_sign(pkey->save_type,
+				&(data[MD5_DIGEST_LENGTH]),
+				SHA_DIGEST_LENGTH,&(p[2]),
+				(unsigned int *)&j,pkey->pkey.ec))
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,
+				    ERR_R_ECDSA_LIB);
+				goto err;
+				}
+			s2n(j,p);
+			n=j+2;
+			}
+		else
+#endif
+			{
+			SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+
+		d = dtls1_set_message_header(s, d,
+			SSL3_MT_CERTIFICATE_VERIFY, n, 0, n) ;
+
+		s->init_num=(int)n+DTLS1_HM_HEADER_LENGTH;
+		s->init_off=0;
+
+		/* buffer the message to handle re-xmits */
+		dtls1_buffer_message(s, 0);
+
+		s->state = SSL3_ST_CW_CERT_VRFY_B;
+		}
+
+	/* s->state = SSL3_ST_CW_CERT_VRFY_B */
+	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
+err:
+	return(-1);
+	}
+
+int dtls1_send_client_certificate(SSL *s)
+	{
+	X509 *x509=NULL;
+	EVP_PKEY *pkey=NULL;
+	int i;
+	unsigned long l;
+
+	if (s->state ==	SSL3_ST_CW_CERT_A)
+		{
+		if ((s->cert == NULL) ||
+			(s->cert->key->x509 == NULL) ||
+			(s->cert->key->privatekey == NULL))
+			s->state=SSL3_ST_CW_CERT_B;
+		else
+			s->state=SSL3_ST_CW_CERT_C;
+		}
+
+	/* We need to get a client cert */
+	if (s->state == SSL3_ST_CW_CERT_B)
+		{
+		/* If we get an error, we need to
+		 * ssl->rwstate=SSL_X509_LOOKUP; return(-1);
+		 * We then get retied later */
+		i=0;
+		i = ssl_do_client_cert_cb(s, &x509, &pkey);
+		if (i < 0)
+			{
+			s->rwstate=SSL_X509_LOOKUP;
+			return(-1);
+			}
+		s->rwstate=SSL_NOTHING;
+		if ((i == 1) && (pkey != NULL) && (x509 != NULL))
+			{
+			s->state=SSL3_ST_CW_CERT_B;
+			if (	!SSL_use_certificate(s,x509) ||
+				!SSL_use_PrivateKey(s,pkey))
+				i=0;
+			}
+		else if (i == 1)
+			{
+			i=0;
+			SSLerr(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
+			}
+
+		if (x509 != NULL) X509_free(x509);
+		if (pkey != NULL) EVP_PKEY_free(pkey);
+		if (i == 0)
+			{
+			if (s->version == SSL3_VERSION)
+				{
+				s->s3->tmp.cert_req=0;
+				ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_NO_CERTIFICATE);
+				return(1);
+				}
+			else
+				{
+				s->s3->tmp.cert_req=2;
+				}
+			}
+
+		/* Ok, we have a cert */
+		s->state=SSL3_ST_CW_CERT_C;
+		}
+
+	if (s->state == SSL3_ST_CW_CERT_C)
+		{
+		s->state=SSL3_ST_CW_CERT_D;
+		l=dtls1_output_cert_chain(s,
+			(s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509);
+		s->init_num=(int)l;
+		s->init_off=0;
+
+		/* set header called by dtls1_output_cert_chain() */
+
+		/* buffer the message to handle re-xmits */
+		dtls1_buffer_message(s, 0);
+		}
+	/* SSL3_ST_CW_CERT_D */
+	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
+	}
+
+
diff --git a/openssl/ssl/d1_enc.c b/openssl/ssl/d1_enc.c
new file mode 100644
index 0000000..becbab9
--- /dev/null
+++ b/openssl/ssl/d1_enc.c
@@ -0,0 +1,289 @@
+/* ssl/d1_enc.c */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "ssl_locl.h"
+#ifndef OPENSSL_NO_COMP
+#include <openssl/comp.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/md5.h>
+#include <openssl/rand.h>
+#ifdef KSSL_DEBUG
+#include <openssl/des.h>
+#endif
+
+int dtls1_enc(SSL *s, int send)
+	{
+	SSL3_RECORD *rec;
+	EVP_CIPHER_CTX *ds;
+	unsigned long l;
+	int bs,i,ii,j,k,n=0;
+	const EVP_CIPHER *enc;
+
+	if (send)
+		{
+		if (EVP_MD_CTX_md(s->write_hash))
+			{
+			n=EVP_MD_CTX_size(s->write_hash);
+			if (n < 0)
+				return -1;
+			}
+		ds=s->enc_write_ctx;
+		rec= &(s->s3->wrec);
+		if (s->enc_write_ctx == NULL)
+			enc=NULL;
+		else
+			{
+			enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
+			if ( rec->data != rec->input)
+				/* we can't write into the input stream */
+				fprintf(stderr, "%s:%d: rec->data != rec->input\n",
+					__FILE__, __LINE__);
+			else if ( EVP_CIPHER_block_size(ds->cipher) > 1)
+				{
+				if (RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher)) <= 0)
+					return -1;
+				}
+			}
+		}
+	else
+		{
+		if (EVP_MD_CTX_md(s->read_hash))
+			{
+			n=EVP_MD_CTX_size(s->read_hash);
+			if (n < 0)
+				return -1;
+			}
+		ds=s->enc_read_ctx;
+		rec= &(s->s3->rrec);
+		if (s->enc_read_ctx == NULL)
+			enc=NULL;
+		else
+			enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
+		}
+
+#ifdef KSSL_DEBUG
+	printf("dtls1_enc(%d)\n", send);
+#endif    /* KSSL_DEBUG */
+
+	if ((s->session == NULL) || (ds == NULL) ||
+		(enc == NULL))
+		{
+		memmove(rec->data,rec->input,rec->length);
+		rec->input=rec->data;
+		}
+	else
+		{
+		l=rec->length;
+		bs=EVP_CIPHER_block_size(ds->cipher);
+
+		if ((bs != 1) && send)
+			{
+			i=bs-((int)l%bs);
+
+			/* Add weird padding of upto 256 bytes */
+
+			/* we need to add 'i' padding bytes of value j */
+			j=i-1;
+			if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG)
+				{
+				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
+					j++;
+				}
+			for (k=(int)l; k<(int)(l+i); k++)
+				rec->input[k]=j;
+			l+=i;
+			rec->length+=i;
+			}
+
+#ifdef KSSL_DEBUG
+		{
+                unsigned long ui;
+		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
+                        ds,rec->data,rec->input,l);
+		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
+                        ds->buf_len, ds->cipher->key_len,
+                        DES_KEY_SZ, DES_SCHEDULE_SZ,
+                        ds->cipher->iv_len);
+		printf("\t\tIV: ");
+		for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
+		printf("\n");
+		printf("\trec->input=");
+		for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
+		printf("\n");
+		}
+#endif	/* KSSL_DEBUG */
+
+		if (!send)
+			{
+			if (l == 0 || l%bs != 0)
+				return -1;
+			}
+		
+		EVP_Cipher(ds,rec->data,rec->input,l);
+
+#ifdef KSSL_DEBUG
+		{
+                unsigned long i;
+                printf("\trec->data=");
+		for (i=0; i<l; i++)
+                        printf(" %02x", rec->data[i]);  printf("\n");
+                }
+#endif	/* KSSL_DEBUG */
+
+		if ((bs != 1) && !send)
+			{
+			ii=i=rec->data[l-1]; /* padding_length */
+			i++;
+			if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG)
+				{
+				/* First packet is even in size, so check */
+				if ((memcmp(s->s3->read_sequence,
+					"\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1))
+					s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
+				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
+					i--;
+				}
+			/* TLS 1.0 does not bound the number of padding bytes by the block size.
+			 * All of them must have value 'padding_length'. */
+			if (i > (int)rec->length)
+				{
+				/* Incorrect padding. SSLerr() and ssl3_alert are done
+				 * by caller: we don't want to reveal whether this is
+				 * a decryption error or a MAC verification failure
+				 * (see http://www.openssl.org/~bodo/tls-cbc.txt) 
+				 */
+				return -1;
+				}
+			for (j=(int)(l-i); j<(int)l; j++)
+				{
+				if (rec->data[j] != ii)
+					{
+					/* Incorrect padding */
+					return -1;
+					}
+				}
+			rec->length-=i;
+
+			rec->data += bs;    /* skip the implicit IV */
+			rec->input += bs;
+			rec->length -= bs;
+			}
+		}
+	return(1);
+	}
+
diff --git a/openssl/ssl/d1_lib.c b/openssl/ssl/d1_lib.c
new file mode 100644
index 0000000..a94290a
--- /dev/null
+++ b/openssl/ssl/d1_lib.c
@@ -0,0 +1,451 @@
+/* ssl/d1_lib.c */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#define USE_SOCKETS
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
+#include <sys/timeb.h>
+#endif
+
+static void get_current_time(struct timeval *t);
+const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT;
+int dtls1_listen(SSL *s, struct sockaddr *client);
+
+SSL3_ENC_METHOD DTLSv1_enc_data={
+    dtls1_enc,
+	tls1_mac,
+	tls1_setup_key_block,
+	tls1_generate_master_secret,
+	tls1_change_cipher_state,
+	tls1_final_finish_mac,
+	TLS1_FINISH_MAC_LENGTH,
+	tls1_cert_verify_mac,
+	TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
+	TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
+	tls1_alert_code,
+	tls1_export_keying_material,
+	};
+
+long dtls1_default_timeout(void)
+	{
+	/* 2 hours, the 24 hours mentioned in the DTLSv1 spec
+	 * is way too long for http, the cache would over fill */
+	return(60*60*2);
+	}
+
+int dtls1_new(SSL *s)
+	{
+	DTLS1_STATE *d1;
+
+	if (!ssl3_new(s)) return(0);
+	if ((d1=OPENSSL_malloc(sizeof *d1)) == NULL) return (0);
+	memset(d1,0, sizeof *d1);
+
+	/* d1->handshake_epoch=0; */
+
+	d1->unprocessed_rcds.q=pqueue_new();
+	d1->processed_rcds.q=pqueue_new();
+	d1->buffered_messages = pqueue_new();
+	d1->sent_messages=pqueue_new();
+	d1->buffered_app_data.q=pqueue_new();
+
+	if ( s->server)
+		{
+		d1->cookie_len = sizeof(s->d1->cookie);
+		}
+
+	if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q 
+        || ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q)
+		{
+        if ( d1->unprocessed_rcds.q) pqueue_free(d1->unprocessed_rcds.q);
+        if ( d1->processed_rcds.q) pqueue_free(d1->processed_rcds.q);
+        if ( d1->buffered_messages) pqueue_free(d1->buffered_messages);
+		if ( d1->sent_messages) pqueue_free(d1->sent_messages);
+		if ( d1->buffered_app_data.q) pqueue_free(d1->buffered_app_data.q);
+		OPENSSL_free(d1);
+		return (0);
+		}
+
+	s->d1=d1;
+	s->method->ssl_clear(s);
+	return(1);
+	}
+
+static void dtls1_clear_queues(SSL *s)
+	{
+    pitem *item = NULL;
+    hm_fragment *frag = NULL;
+	DTLS1_RECORD_DATA *rdata;
+
+    while( (item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL)
+        {
+		rdata = (DTLS1_RECORD_DATA *) item->data;
+		if (rdata->rbuf.buf)
+			{
+			OPENSSL_free(rdata->rbuf.buf);
+			}
+        OPENSSL_free(item->data);
+        pitem_free(item);
+        }
+
+    while( (item = pqueue_pop(s->d1->processed_rcds.q)) != NULL)
+        {
+		rdata = (DTLS1_RECORD_DATA *) item->data;
+		if (rdata->rbuf.buf)
+			{
+			OPENSSL_free(rdata->rbuf.buf);
+			}
+        OPENSSL_free(item->data);
+        pitem_free(item);
+        }
+
+    while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL)
+        {
+        frag = (hm_fragment *)item->data;
+        OPENSSL_free(frag->fragment);
+        OPENSSL_free(frag);
+        pitem_free(item);
+        }
+
+    while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL)
+        {
+        frag = (hm_fragment *)item->data;
+        OPENSSL_free(frag->fragment);
+        OPENSSL_free(frag);
+        pitem_free(item);
+        }
+
+	while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
+		{
+		frag = (hm_fragment *)item->data;
+		OPENSSL_free(frag->fragment);
+		OPENSSL_free(frag);
+		pitem_free(item);
+		}
+	}
+
+void dtls1_free(SSL *s)
+	{
+	ssl3_free(s);
+
+	dtls1_clear_queues(s);
+
+    pqueue_free(s->d1->unprocessed_rcds.q);
+    pqueue_free(s->d1->processed_rcds.q);
+    pqueue_free(s->d1->buffered_messages);
+	pqueue_free(s->d1->sent_messages);
+	pqueue_free(s->d1->buffered_app_data.q);
+
+	OPENSSL_free(s->d1);
+	}
+
+void dtls1_clear(SSL *s)
+	{
+    pqueue unprocessed_rcds;
+    pqueue processed_rcds;
+    pqueue buffered_messages;
+	pqueue sent_messages;
+	pqueue buffered_app_data;
+	unsigned int mtu;
+
+	if (s->d1)
+		{
+		unprocessed_rcds = s->d1->unprocessed_rcds.q;
+		processed_rcds = s->d1->processed_rcds.q;
+		buffered_messages = s->d1->buffered_messages;
+		sent_messages = s->d1->sent_messages;
+		buffered_app_data = s->d1->buffered_app_data.q;
+		mtu = s->d1->mtu;
+
+		dtls1_clear_queues(s);
+
+		memset(s->d1, 0, sizeof(*(s->d1)));
+
+		if (s->server)
+			{
+			s->d1->cookie_len = sizeof(s->d1->cookie);
+			}
+
+		if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)
+			{
+			s->d1->mtu = mtu;
+			}
+
+		s->d1->unprocessed_rcds.q = unprocessed_rcds;
+		s->d1->processed_rcds.q = processed_rcds;
+		s->d1->buffered_messages = buffered_messages;
+		s->d1->sent_messages = sent_messages;
+		s->d1->buffered_app_data.q = buffered_app_data;
+		}
+
+	ssl3_clear(s);
+	if (s->options & SSL_OP_CISCO_ANYCONNECT)
+		s->version=DTLS1_BAD_VER;
+	else
+		s->version=DTLS1_VERSION;
+	}
+
+long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
+	{
+	int ret=0;
+
+	switch (cmd)
+		{
+	case DTLS_CTRL_GET_TIMEOUT:
+		if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL)
+			{
+			ret = 1;
+			}
+		break;
+	case DTLS_CTRL_HANDLE_TIMEOUT:
+		ret = dtls1_handle_timeout(s);
+		break;
+	case DTLS_CTRL_LISTEN:
+		ret = dtls1_listen(s, parg);
+		break;
+
+	default:
+		ret = ssl3_ctrl(s, cmd, larg, parg);
+		break;
+		}
+	return(ret);
+	}
+
+/*
+ * As it's impossible to use stream ciphers in "datagram" mode, this
+ * simple filter is designed to disengage them in DTLS. Unfortunately
+ * there is no universal way to identify stream SSL_CIPHER, so we have
+ * to explicitly list their SSL_* codes. Currently RC4 is the only one
+ * available, but if new ones emerge, they will have to be added...
+ */
+const SSL_CIPHER *dtls1_get_cipher(unsigned int u)
+	{
+	const SSL_CIPHER *ciph = ssl3_get_cipher(u);
+
+	if (ciph != NULL)
+		{
+		if (ciph->algorithm_enc == SSL_RC4)
+			return NULL;
+		}
+
+	return ciph;
+	}
+
+void dtls1_start_timer(SSL *s)
+	{
+	/* If timer is not set, initialize duration with 1 second */
+	if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0)
+		{
+		s->d1->timeout_duration = 1;
+		}
+	
+	/* Set timeout to current time */
+	get_current_time(&(s->d1->next_timeout));
+
+	/* Add duration to current time */
+	s->d1->next_timeout.tv_sec += s->d1->timeout_duration;
+	BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
+	}
+
+struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft)
+	{
+	struct timeval timenow;
+
+	/* If no timeout is set, just return NULL */
+	if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0)
+		{
+		return NULL;
+		}
+
+	/* Get current time */
+	get_current_time(&timenow);
+
+	/* If timer already expired, set remaining time to 0 */
+	if (s->d1->next_timeout.tv_sec < timenow.tv_sec ||
+		(s->d1->next_timeout.tv_sec == timenow.tv_sec &&
+		 s->d1->next_timeout.tv_usec <= timenow.tv_usec))
+		{
+		memset(timeleft, 0, sizeof(struct timeval));
+		return timeleft;
+		}
+
+	/* Calculate time left until timer expires */
+	memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval));
+	timeleft->tv_sec -= timenow.tv_sec;
+	timeleft->tv_usec -= timenow.tv_usec;
+	if (timeleft->tv_usec < 0)
+		{
+		timeleft->tv_sec--;
+		timeleft->tv_usec += 1000000;
+		}
+
+	/* If remaining time is less than 15 ms, set it to 0
+	 * to prevent issues because of small devergences with
+	 * socket timeouts.
+	 */
+	if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000)
+		{
+		memset(timeleft, 0, sizeof(struct timeval));
+		}
+	
+
+	return timeleft;
+	}
+
+int dtls1_is_timer_expired(SSL *s)
+	{
+	struct timeval timeleft;
+
+	/* Get time left until timeout, return false if no timer running */
+	if (dtls1_get_timeout(s, &timeleft) == NULL)
+		{
+		return 0;
+		}
+
+	/* Return false if timer is not expired yet */
+	if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0)
+		{
+		return 0;
+		}
+
+	/* Timer expired, so return true */	
+	return 1;
+	}
+
+void dtls1_double_timeout(SSL *s)
+	{
+	s->d1->timeout_duration *= 2;
+	if (s->d1->timeout_duration > 60)
+		s->d1->timeout_duration = 60;
+	dtls1_start_timer(s);
+	}
+
+void dtls1_stop_timer(SSL *s)
+	{
+	/* Reset everything */
+	memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
+	s->d1->timeout_duration = 1;
+	BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
+	/* Clear retransmission buffer */
+	dtls1_clear_record_buffer(s);
+	}
+
+int dtls1_handle_timeout(SSL *s)
+	{
+	DTLS1_STATE *state;
+
+	/* if no timer is expired, don't do anything */
+	if (!dtls1_is_timer_expired(s))
+		{
+		return 0;
+		}
+
+	dtls1_double_timeout(s);
+	state = s->d1;
+	state->timeout.num_alerts++;
+	if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
+		{
+		/* fail the connection, enough alerts have been sent */
+		SSLerr(SSL_F_DTLS1_HANDLE_TIMEOUT,SSL_R_READ_TIMEOUT_EXPIRED);
+		return -1;
+		}
+
+	state->timeout.read_timeouts++;
+	if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
+		{
+		state->timeout.read_timeouts = 1;
+		}
+
+	dtls1_start_timer(s);
+	return dtls1_retransmit_buffered_messages(s);
+	}
+
+static void get_current_time(struct timeval *t)
+{
+#ifdef OPENSSL_SYS_WIN32
+	struct _timeb tb;
+	_ftime(&tb);
+	t->tv_sec = (long)tb.time;
+	t->tv_usec = (long)tb.millitm * 1000;
+#elif defined(OPENSSL_SYS_VMS)
+	struct timeb tb;
+	ftime(&tb);
+	t->tv_sec = (long)tb.time;
+	t->tv_usec = (long)tb.millitm * 1000;
+#else
+	gettimeofday(t, NULL);
+#endif
+}
+
+int dtls1_listen(SSL *s, struct sockaddr *client)
+	{
+	int ret;
+
+	SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
+	s->d1->listen = 1;
+
+	ret = SSL_accept(s);
+	if (ret <= 0) return ret;
+	
+	(void) BIO_dgram_get_peer(SSL_get_rbio(s), client);
+	return 1;
+	}
diff --git a/openssl/ssl/d1_meth.c b/openssl/ssl/d1_meth.c
new file mode 100644
index 0000000..5c4004b
--- /dev/null
+++ b/openssl/ssl/d1_meth.c
@@ -0,0 +1,77 @@
+/* ssl/d1_meth.h */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+
+static const SSL_METHOD *dtls1_get_method(int ver);
+static const SSL_METHOD *dtls1_get_method(int ver)
+	{
+	if (ver == DTLS1_VERSION)
+		return(DTLSv1_method());
+	else
+		return(NULL);
+	}
+
+IMPLEMENT_dtls1_meth_func(DTLSv1_method,
+			dtls1_accept,
+			dtls1_connect,
+			dtls1_get_method)
+
diff --git a/openssl/ssl/d1_pkt.c b/openssl/ssl/d1_pkt.c
new file mode 100644
index 0000000..3927dad
--- /dev/null
+++ b/openssl/ssl/d1_pkt.c
@@ -0,0 +1,1806 @@
+/* ssl/d1_pkt.c */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "ssl_locl.h"
+#include <openssl/evp.h>
+#include <openssl/buffer.h>
+#include <openssl/pqueue.h>
+#include <openssl/rand.h>
+
+/* mod 128 saturating subtract of two 64-bit values in big-endian order */
+static int satsub64be(const unsigned char *v1,const unsigned char *v2)
+{	int ret,sat,brw,i;
+
+	if (sizeof(long) == 8) do
+	{	const union { long one; char little; } is_endian = {1};
+		long l;
+
+		if (is_endian.little)			break;
+		/* not reached on little-endians */
+		/* following test is redundant, because input is
+		 * always aligned, but I take no chances... */
+		if (((size_t)v1|(size_t)v2)&0x7)	break;
+
+		l  = *((long *)v1);
+		l -= *((long *)v2);
+		if (l>128)		return 128;
+		else if (l<-128)	return -128;
+		else			return (int)l;
+	} while (0);
+
+	ret = (int)v1[7]-(int)v2[7];
+	sat = 0;
+	brw = ret>>8;	/* brw is either 0 or -1 */
+	if (ret & 0x80)
+	{	for (i=6;i>=0;i--)
+		{	brw += (int)v1[i]-(int)v2[i];
+			sat |= ~brw;
+			brw >>= 8;
+		}
+	}
+	else
+	{	for (i=6;i>=0;i--)
+		{	brw += (int)v1[i]-(int)v2[i];
+			sat |= brw;
+			brw >>= 8;
+		}
+	}
+	brw <<= 8;	/* brw is either 0 or -256 */
+
+	if (sat&0xff)	return brw | 0x80;
+	else		return brw + (ret&0xFF);
+}
+
+static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, 
+	int len, int peek);
+static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap);
+static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap);
+static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, 
+    unsigned int *is_next_epoch);
+#if 0
+static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr,
+	unsigned short *priority, unsigned long *offset);
+#endif
+static int dtls1_buffer_record(SSL *s, record_pqueue *q,
+	unsigned char *priority);
+static int dtls1_process_record(SSL *s);
+static void dtls1_clear_timeouts(SSL *s);
+
+/* copy buffered record into SSL structure */
+static int
+dtls1_copy_record(SSL *s, pitem *item)
+    {
+    DTLS1_RECORD_DATA *rdata;
+
+    rdata = (DTLS1_RECORD_DATA *)item->data;
+    
+    if (s->s3->rbuf.buf != NULL)
+        OPENSSL_free(s->s3->rbuf.buf);
+    
+    s->packet = rdata->packet;
+    s->packet_length = rdata->packet_length;
+    memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER));
+    memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD));
+	
+	/* Set proper sequence number for mac calculation */
+	memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6);
+    
+    return(1);
+    }
+
+
+static int
+dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
+	{
+	DTLS1_RECORD_DATA *rdata;
+	pitem *item;
+
+	/* Limit the size of the queue to prevent DOS attacks */
+	if (pqueue_size(queue->q) >= 100)
+		return 0;
+		
+	rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA));
+	item = pitem_new(priority, rdata);
+	if (rdata == NULL || item == NULL)
+		{
+		if (rdata != NULL) OPENSSL_free(rdata);
+		if (item != NULL) pitem_free(item);
+		
+		SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
+		return(0);
+		}
+	
+	rdata->packet = s->packet;
+	rdata->packet_length = s->packet_length;
+	memcpy(&(rdata->rbuf), &(s->s3->rbuf), sizeof(SSL3_BUFFER));
+	memcpy(&(rdata->rrec), &(s->s3->rrec), sizeof(SSL3_RECORD));
+
+	item->data = rdata;
+
+	/* insert should not fail, since duplicates are dropped */
+	if (pqueue_insert(queue->q, item) == NULL)
+		{
+		OPENSSL_free(rdata);
+		pitem_free(item);
+		return(0);
+		}
+
+	s->packet = NULL;
+	s->packet_length = 0;
+	memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER));
+	memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD));
+	
+	if (!ssl3_setup_buffers(s))
+		{
+		SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
+		OPENSSL_free(rdata);
+		pitem_free(item);
+		return(0);
+		}
+	
+	return(1);
+	}
+
+
+static int
+dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue)
+    {
+    pitem *item;
+
+    item = pqueue_pop(queue->q);
+    if (item)
+        {
+        dtls1_copy_record(s, item);
+
+        OPENSSL_free(item->data);
+		pitem_free(item);
+
+        return(1);
+        }
+
+    return(0);
+    }
+
+
+/* retrieve a buffered record that belongs to the new epoch, i.e., not processed 
+ * yet */
+#define dtls1_get_unprocessed_record(s) \
+                   dtls1_retrieve_buffered_record((s), \
+                   &((s)->d1->unprocessed_rcds))
+
+/* retrieve a buffered record that belongs to the current epoch, ie, processed */
+#define dtls1_get_processed_record(s) \
+                   dtls1_retrieve_buffered_record((s), \
+                   &((s)->d1->processed_rcds))
+
+static int
+dtls1_process_buffered_records(SSL *s)
+    {
+    pitem *item;
+    
+    item = pqueue_peek(s->d1->unprocessed_rcds.q);
+    if (item)
+        {
+        /* Check if epoch is current. */
+        if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch)
+            return(1);  /* Nothing to do. */
+        
+        /* Process all the records. */
+        while (pqueue_peek(s->d1->unprocessed_rcds.q))
+            {
+            dtls1_get_unprocessed_record(s);
+            if ( ! dtls1_process_record(s))
+                return(0);
+            dtls1_buffer_record(s, &(s->d1->processed_rcds), 
+                s->s3->rrec.seq_num);
+            }
+        }
+
+    /* sync epoch numbers once all the unprocessed records 
+     * have been processed */
+    s->d1->processed_rcds.epoch = s->d1->r_epoch;
+    s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1;
+
+    return(1);
+    }
+
+
+#if 0
+
+static int
+dtls1_get_buffered_record(SSL *s)
+	{
+	pitem *item;
+	PQ_64BIT priority = 
+		(((PQ_64BIT)s->d1->handshake_read_seq) << 32) | 
+		((PQ_64BIT)s->d1->r_msg_hdr.frag_off);
+	
+	if ( ! SSL_in_init(s))  /* if we're not (re)negotiating, 
+							   nothing buffered */
+		return 0;
+
+
+	item = pqueue_peek(s->d1->rcvd_records);
+	if (item && item->priority == priority)
+		{
+		/* Check if we've received the record of interest.  It must be
+		 * a handshake record, since data records as passed up without
+		 * buffering */
+		DTLS1_RECORD_DATA *rdata;
+		item = pqueue_pop(s->d1->rcvd_records);
+		rdata = (DTLS1_RECORD_DATA *)item->data;
+		
+		if (s->s3->rbuf.buf != NULL)
+			OPENSSL_free(s->s3->rbuf.buf);
+		
+		s->packet = rdata->packet;
+		s->packet_length = rdata->packet_length;
+		memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER));
+		memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD));
+		
+		OPENSSL_free(item->data);
+		pitem_free(item);
+		
+		/* s->d1->next_expected_seq_num++; */
+		return(1);
+		}
+	
+	return 0;
+	}
+
+#endif
+
+static int
+dtls1_process_record(SSL *s)
+{
+	int i,al;
+	int clear=0;
+	int enc_err;
+	SSL_SESSION *sess;
+	SSL3_RECORD *rr;
+	unsigned int mac_size;
+	unsigned char md[EVP_MAX_MD_SIZE];
+	int decryption_failed_or_bad_record_mac = 0;
+
+
+	rr= &(s->s3->rrec);
+	sess = s->session;
+
+	/* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
+	 * and we have that many bytes in s->packet
+	 */
+	rr->input= &(s->packet[DTLS1_RT_HEADER_LENGTH]);
+
+	/* ok, we can now read from 's->packet' data into 'rr'
+	 * rr->input points at rr->length bytes, which
+	 * need to be copied into rr->data by either
+	 * the decryption or by the decompression
+	 * When the data is 'copied' into the rr->data buffer,
+	 * rr->input will be pointed at the new buffer */ 
+
+	/* We now have - encrypted [ MAC [ compressed [ plain ] ] ]
+	 * rr->length bytes of encrypted compressed stuff. */
+
+	/* check is not needed I believe */
+	if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)
+		{
+		al=SSL_AD_RECORD_OVERFLOW;
+		SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
+		goto f_err;
+		}
+
+	/* decrypt in place in 'rr->input' */
+	rr->data=rr->input;
+
+	enc_err = s->method->ssl3_enc->enc(s,0);
+	if (enc_err <= 0)
+		{
+		/* To minimize information leaked via timing, we will always
+		 * perform all computations before discarding the message.
+		 */
+		decryption_failed_or_bad_record_mac = 1;
+		}
+
+#ifdef TLS_DEBUG
+printf("dec %d\n",rr->length);
+{ unsigned int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); }
+printf("\n");
+#endif
+
+	/* r->length is now the compressed data plus mac */
+	if (	(sess == NULL) ||
+		(s->enc_read_ctx == NULL) ||
+		(s->read_hash == NULL))
+		clear=1;
+
+	if (!clear)
+		{
+		/* !clear => s->read_hash != NULL => mac_size != -1 */
+		int t;
+		t=EVP_MD_CTX_size(s->read_hash);
+		OPENSSL_assert(t >= 0);
+		mac_size=t;
+
+		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size)
+			{
+#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */
+			al=SSL_AD_RECORD_OVERFLOW;
+			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
+			goto f_err;
+#else
+			decryption_failed_or_bad_record_mac = 1;
+#endif			
+			}
+		/* check the MAC for rr->input (it's in mac_size bytes at the tail) */
+		if (rr->length < mac_size)
+			{
+#if 0 /* OK only for stream ciphers */
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT);
+			goto f_err;
+#else
+			decryption_failed_or_bad_record_mac = 1;
+#endif
+			}
+		rr->length-=mac_size;
+		i=s->method->ssl3_enc->mac(s,md,0);
+		if (i < 0 || memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
+			{
+			decryption_failed_or_bad_record_mac = 1;
+			}
+		}
+
+	if (decryption_failed_or_bad_record_mac)
+		{
+		/* decryption failed, silently discard message */
+		rr->length = 0;
+		s->packet_length = 0;
+		goto err;
+		}
+
+	/* r->length is now just compressed */
+	if (s->expand != NULL)
+		{
+		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH)
+			{
+			al=SSL_AD_RECORD_OVERFLOW;
+			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG);
+			goto f_err;
+			}
+		if (!ssl3_do_uncompress(s))
+			{
+			al=SSL_AD_DECOMPRESSION_FAILURE;
+			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_BAD_DECOMPRESSION);
+			goto f_err;
+			}
+		}
+
+	if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH)
+		{
+		al=SSL_AD_RECORD_OVERFLOW;
+		SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DATA_LENGTH_TOO_LONG);
+		goto f_err;
+		}
+
+	rr->off=0;
+	/* So at this point the following is true
+	 * ssl->s3->rrec.type 	is the type of record
+	 * ssl->s3->rrec.length	== number of bytes in record
+	 * ssl->s3->rrec.off	== offset to first valid byte
+	 * ssl->s3->rrec.data	== where to take bytes from, increment
+	 *			   after use :-).
+	 */
+
+	/* we have pulled in a full packet so zero things */
+	s->packet_length=0;
+	dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */
+	return(1);
+
+f_err:
+	ssl3_send_alert(s,SSL3_AL_FATAL,al);
+err:
+	return(0);
+}
+
+
+/* Call this to get a new input record.
+ * It will return <= 0 if more data is needed, normally due to an error
+ * or non-blocking IO.
+ * When it finishes, one packet has been decoded and can be found in
+ * ssl->s3->rrec.type    - is the type of record
+ * ssl->s3->rrec.data, 	 - data
+ * ssl->s3->rrec.length, - number of bytes
+ */
+/* used only by dtls1_read_bytes */
+int dtls1_get_record(SSL *s)
+	{
+	int ssl_major,ssl_minor;
+	int i,n;
+	SSL3_RECORD *rr;
+	unsigned char *p = NULL;
+	unsigned short version;
+	DTLS1_BITMAP *bitmap;
+	unsigned int is_next_epoch;
+
+	rr= &(s->s3->rrec);
+
+	/* The epoch may have changed.  If so, process all the
+	 * pending records.  This is a non-blocking operation. */
+	dtls1_process_buffered_records(s);
+
+	/* if we're renegotiating, then there may be buffered records */
+	if (dtls1_get_processed_record(s))
+		return 1;
+
+	/* get something from the wire */
+again:
+	/* check if we have the header */
+	if (	(s->rstate != SSL_ST_READ_BODY) ||
+		(s->packet_length < DTLS1_RT_HEADER_LENGTH)) 
+		{
+		n=ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, s->s3->rbuf.len, 0);
+		/* read timeout is handled by dtls1_read_bytes */
+		if (n <= 0) return(n); /* error or non-blocking */
+
+		/* this packet contained a partial record, dump it */
+		if (s->packet_length != DTLS1_RT_HEADER_LENGTH)
+			{
+			s->packet_length = 0;
+			goto again;
+			}
+
+		s->rstate=SSL_ST_READ_BODY;
+
+		p=s->packet;
+
+		/* Pull apart the header into the DTLS1_RECORD */
+		rr->type= *(p++);
+		ssl_major= *(p++);
+		ssl_minor= *(p++);
+		version=(ssl_major<<8)|ssl_minor;
+
+		/* sequence number is 64 bits, with top 2 bytes = epoch */ 
+		n2s(p,rr->epoch);
+
+		memcpy(&(s->s3->read_sequence[2]), p, 6);
+		p+=6;
+
+		n2s(p,rr->length);
+
+		/* Lets check version */
+		if (!s->first_packet)
+			{
+			if (version != s->version)
+				{
+				/* unexpected version, silently discard */
+				rr->length = 0;
+				s->packet_length = 0;
+				goto again;
+				}
+			}
+
+		if ((version & 0xff00) != (s->version & 0xff00))
+			{
+			/* wrong version, silently discard record */
+			rr->length = 0;
+			s->packet_length = 0;
+			goto again;
+			}
+
+		if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)
+			{
+			/* record too long, silently discard it */
+			rr->length = 0;
+			s->packet_length = 0;
+			goto again;
+			}
+
+		/* If we receive a valid record larger than the current buffer size,
+		 * allocate some memory for it.
+		 */
+		if (rr->length > s->s3->rbuf.len - DTLS1_RT_HEADER_LENGTH)
+			{
+			unsigned char *pp;
+			unsigned int newlen = rr->length + DTLS1_RT_HEADER_LENGTH;
+			if ((pp=OPENSSL_realloc(s->s3->rbuf.buf, newlen))==NULL)
+				{
+				SSLerr(SSL_F_DTLS1_GET_RECORD,ERR_R_MALLOC_FAILURE);
+				return(-1);
+				}
+			p = pp + (p - s->s3->rbuf.buf);
+			s->s3->rbuf.buf=pp;
+			s->s3->rbuf.len=newlen;
+			s->packet= &(s->s3->rbuf.buf[0]);
+			}
+
+		/* now s->rstate == SSL_ST_READ_BODY */
+		}
+
+	/* s->rstate == SSL_ST_READ_BODY, get and decode the data */
+
+	if (rr->length > s->packet_length-DTLS1_RT_HEADER_LENGTH)
+		{
+		/* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
+		i=rr->length;
+		n=ssl3_read_n(s,i,i,1);
+		if (n <= 0) return(n); /* error or non-blocking io */
+
+		/* this packet contained a partial record, dump it */
+		if ( n != i)
+			{
+			rr->length = 0;
+			s->packet_length = 0;
+			goto again;
+			}
+
+		/* now n == rr->length,
+		 * and s->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length */
+		}
+	s->rstate=SSL_ST_READ_HEADER; /* set state for later operations */
+
+	/* match epochs.  NULL means the packet is dropped on the floor */
+	bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
+	if ( bitmap == NULL)
+		{
+		rr->length = 0;
+		s->packet_length = 0;  /* dump this record */
+		goto again;   /* get another record */
+		}
+
+	/* Check whether this is a repeat, or aged record.
+	 * Don't check if we're listening and this message is
+	 * a ClientHello. They can look as if they're replayed,
+	 * since they arrive from different connections and
+	 * would be dropped unnecessarily.
+	 */
+	if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
+		*p == SSL3_MT_CLIENT_HELLO) &&
+		!dtls1_record_replay_check(s, bitmap))
+		{
+		rr->length = 0;
+		s->packet_length=0; /* dump this record */
+		goto again;     /* get another record */
+		}
+
+	/* just read a 0 length packet */
+	if (rr->length == 0) goto again;
+
+	/* If this record is from the next epoch (either HM or ALERT),
+	 * and a handshake is currently in progress, buffer it since it
+	 * cannot be processed at this time. However, do not buffer
+	 * anything while listening.
+	 */
+	if (is_next_epoch)
+		{
+		if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen)
+			{
+			dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
+			}
+		rr->length = 0;
+		s->packet_length = 0;
+		goto again;
+		}
+
+	if (!dtls1_process_record(s))
+		{
+		rr->length = 0;
+		s->packet_length = 0;  /* dump this record */
+		goto again;   /* get another record */
+		}
+
+	dtls1_clear_timeouts(s);  /* done waiting */
+	return(1);
+
+	}
+
+/* Return up to 'len' payload bytes received in 'type' records.
+ * 'type' is one of the following:
+ *
+ *   -  SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
+ *   -  SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
+ *   -  0 (during a shutdown, no data has to be returned)
+ *
+ * If we don't have stored data to work from, read a SSL/TLS record first
+ * (possibly multiple records if we still don't have anything to return).
+ *
+ * This function must handle any surprises the peer may have for us, such as
+ * Alert records (e.g. close_notify), ChangeCipherSpec records (not really
+ * a surprise, but handled as if it were), or renegotiation requests.
+ * Also if record payloads contain fragments too small to process, we store
+ * them until there is enough for the respective protocol (the record protocol
+ * may use arbitrary fragmentation and even interleaving):
+ *     Change cipher spec protocol
+ *             just 1 byte needed, no need for keeping anything stored
+ *     Alert protocol
+ *             2 bytes needed (AlertLevel, AlertDescription)
+ *     Handshake protocol
+ *             4 bytes needed (HandshakeType, uint24 length) -- we just have
+ *             to detect unexpected Client Hello and Hello Request messages
+ *             here, anything else is handled by higher layers
+ *     Application data protocol
+ *             none of our business
+ */
+int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
+	{
+	int al,i,j,ret;
+	unsigned int n;
+	SSL3_RECORD *rr;
+	void (*cb)(const SSL *ssl,int type2,int val)=NULL;
+
+	if (s->s3->rbuf.buf == NULL) /* Not initialized yet */
+		if (!ssl3_setup_buffers(s))
+			return(-1);
+
+    /* XXX: check what the second '&& type' is about */
+	if ((type && (type != SSL3_RT_APPLICATION_DATA) && 
+		(type != SSL3_RT_HANDSHAKE) && type) ||
+	    (peek && (type != SSL3_RT_APPLICATION_DATA)))
+		{
+		SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
+		return -1;
+		}
+
+	/* check whether there's a handshake message (client hello?) waiting */
+	if ( (ret = have_handshake_fragment(s, type, buf, len, peek)))
+		return ret;
+
+	/* Now s->d1->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */
+
+	if (!s->in_handshake && SSL_in_init(s))
+		{
+		/* type == SSL3_RT_APPLICATION_DATA */
+		i=s->handshake_func(s);
+		if (i < 0) return(i);
+		if (i == 0)
+			{
+			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
+			return(-1);
+			}
+		}
+
+start:
+	s->rwstate=SSL_NOTHING;
+
+	/* s->s3->rrec.type	    - is the type of record
+	 * s->s3->rrec.data,    - data
+	 * s->s3->rrec.off,     - offset into 'data' for next read
+	 * s->s3->rrec.length,  - number of bytes. */
+	rr = &(s->s3->rrec);
+
+	/* We are not handshaking and have no data yet,
+	 * so process data buffered during the last handshake
+	 * in advance, if any.
+	 */
+	if (s->state == SSL_ST_OK && rr->length == 0)
+		{
+		pitem *item;
+		item = pqueue_pop(s->d1->buffered_app_data.q);
+		if (item)
+			{
+			dtls1_copy_record(s, item);
+
+			OPENSSL_free(item->data);
+			pitem_free(item);
+			}
+		}
+
+	/* Check for timeout */
+	if (dtls1_handle_timeout(s) > 0)
+		goto start;
+
+	/* get new packet if necessary */
+	if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY))
+		{
+		ret=dtls1_get_record(s);
+		if (ret <= 0) 
+			{
+			ret = dtls1_read_failed(s, ret);
+			/* anything other than a timeout is an error */
+			if (ret <= 0)  
+				return(ret);
+			else
+				goto start;
+			}
+		}
+
+	/* we now have a packet which can be read and processed */
+
+	if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
+	                               * reset by ssl3_get_finished */
+		&& (rr->type != SSL3_RT_HANDSHAKE))
+		{
+		/* We now have application data between CCS and Finished.
+		 * Most likely the packets were reordered on their way, so
+		 * buffer the application data for later processing rather
+		 * than dropping the connection.
+		 */
+		dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num);
+		rr->length = 0;
+		goto start;
+		}
+
+	/* If the other end has shut down, throw anything we read away
+	 * (even in 'peek' mode) */
+	if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
+		{
+		rr->length=0;
+		s->rwstate=SSL_NOTHING;
+		return(0);
+		}
+
+
+	if (type == rr->type) /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */
+		{
+		/* make sure that we are not getting application data when we
+		 * are doing a handshake for the first time */
+		if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
+			(s->enc_read_ctx == NULL))
+			{
+			al=SSL_AD_UNEXPECTED_MESSAGE;
+			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_APP_DATA_IN_HANDSHAKE);
+			goto f_err;
+			}
+
+		if (len <= 0) return(len);
+
+		if ((unsigned int)len > rr->length)
+			n = rr->length;
+		else
+			n = (unsigned int)len;
+
+		memcpy(buf,&(rr->data[rr->off]),n);
+		if (!peek)
+			{
+			rr->length-=n;
+			rr->off+=n;
+			if (rr->length == 0)
+				{
+				s->rstate=SSL_ST_READ_HEADER;
+				rr->off=0;
+				}
+			}
+		return(n);
+		}
+
+
+	/* If we get here, then type != rr->type; if we have a handshake
+	 * message, then it was unexpected (Hello Request or Client Hello). */
+
+	/* In case of record types for which we have 'fragment' storage,
+	 * fill that so that we can process the data at a fixed place.
+	 */
+		{
+		unsigned int k, dest_maxlen = 0;
+		unsigned char *dest = NULL;
+		unsigned int *dest_len = NULL;
+
+		if (rr->type == SSL3_RT_HANDSHAKE)
+			{
+			dest_maxlen = sizeof s->d1->handshake_fragment;
+			dest = s->d1->handshake_fragment;
+			dest_len = &s->d1->handshake_fragment_len;
+			}
+		else if (rr->type == SSL3_RT_ALERT)
+			{
+			dest_maxlen = sizeof(s->d1->alert_fragment);
+			dest = s->d1->alert_fragment;
+			dest_len = &s->d1->alert_fragment_len;
+			}
+		/* else it's a CCS message, or application data or wrong */
+		else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC)
+			{
+			/* Application data while renegotiating
+			 * is allowed. Try again reading.
+			 */
+			if (rr->type == SSL3_RT_APPLICATION_DATA)
+				{
+				BIO *bio;
+				s->s3->in_read_app_data=2;
+				bio=SSL_get_rbio(s);
+				s->rwstate=SSL_READING;
+				BIO_clear_retry_flags(bio);
+				BIO_set_retry_read(bio);
+				return(-1);
+				}
+
+			/* Not certain if this is the right error handling */
+			al=SSL_AD_UNEXPECTED_MESSAGE;
+			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
+			goto f_err;
+			}
+
+		if (dest_maxlen > 0)
+			{
+            /* XDTLS:  In a pathalogical case, the Client Hello
+             *  may be fragmented--don't always expect dest_maxlen bytes */
+			if ( rr->length < dest_maxlen)
+				{
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+				/*
+				 * for normal alerts rr->length is 2, while
+				 * dest_maxlen is 7 if we were to handle this
+				 * non-existing alert...
+				 */
+				FIX ME
+#endif
+				s->rstate=SSL_ST_READ_HEADER;
+				rr->length = 0;
+				goto start;
+				}
+
+			/* now move 'n' bytes: */
+			for ( k = 0; k < dest_maxlen; k++)
+				{
+				dest[k] = rr->data[rr->off++];
+				rr->length--;
+				}
+			*dest_len = dest_maxlen;
+			}
+		}
+
+	/* s->d1->handshake_fragment_len == 12  iff  rr->type == SSL3_RT_HANDSHAKE;
+	 * s->d1->alert_fragment_len == 7      iff  rr->type == SSL3_RT_ALERT.
+	 * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */
+
+	/* If we are a client, check for an incoming 'Hello Request': */
+	if ((!s->server) &&
+		(s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) &&
+		(s->d1->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
+		(s->session != NULL) && (s->session->cipher != NULL))
+		{
+		s->d1->handshake_fragment_len = 0;
+
+		if ((s->d1->handshake_fragment[1] != 0) ||
+			(s->d1->handshake_fragment[2] != 0) ||
+			(s->d1->handshake_fragment[3] != 0))
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_HELLO_REQUEST);
+			goto err;
+			}
+
+		/* no need to check sequence number on HELLO REQUEST messages */
+
+		if (s->msg_callback)
+			s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, 
+				s->d1->handshake_fragment, 4, s, s->msg_callback_arg);
+
+		if (SSL_is_init_finished(s) &&
+			!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
+			!s->s3->renegotiate)
+			{
+			ssl3_renegotiate(s);
+			if (ssl3_renegotiate_check(s))
+				{
+				i=s->handshake_func(s);
+				if (i < 0) return(i);
+				if (i == 0)
+					{
+					SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
+					return(-1);
+					}
+
+				if (!(s->mode & SSL_MODE_AUTO_RETRY))
+					{
+					if (s->s3->rbuf.left == 0) /* no read-ahead left? */
+						{
+						BIO *bio;
+						/* In the case where we try to read application data,
+						 * but we trigger an SSL handshake, we return -1 with
+						 * the retry option set.  Otherwise renegotiation may
+						 * cause nasty problems in the blocking world */
+						s->rwstate=SSL_READING;
+						bio=SSL_get_rbio(s);
+						BIO_clear_retry_flags(bio);
+						BIO_set_retry_read(bio);
+						return(-1);
+						}
+					}
+				}
+			}
+		/* we either finished a handshake or ignored the request,
+		 * now try again to obtain the (application) data we were asked for */
+		goto start;
+		}
+
+	if (s->d1->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH)
+		{
+		int alert_level = s->d1->alert_fragment[0];
+		int alert_descr = s->d1->alert_fragment[1];
+
+		s->d1->alert_fragment_len = 0;
+
+		if (s->msg_callback)
+			s->msg_callback(0, s->version, SSL3_RT_ALERT, 
+				s->d1->alert_fragment, 2, s, s->msg_callback_arg);
+
+		if (s->info_callback != NULL)
+			cb=s->info_callback;
+		else if (s->ctx->info_callback != NULL)
+			cb=s->ctx->info_callback;
+
+		if (cb != NULL)
+			{
+			j = (alert_level << 8) | alert_descr;
+			cb(s, SSL_CB_READ_ALERT, j);
+			}
+
+		if (alert_level == 1) /* warning */
+			{
+			s->s3->warn_alert = alert_descr;
+			if (alert_descr == SSL_AD_CLOSE_NOTIFY)
+				{
+				s->shutdown |= SSL_RECEIVED_SHUTDOWN;
+				return(0);
+				}
+#if 0
+            /* XXX: this is a possible improvement in the future */
+			/* now check if it's a missing record */
+			if (alert_descr == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)
+				{
+				unsigned short seq;
+				unsigned int frag_off;
+				unsigned char *p = &(s->d1->alert_fragment[2]);
+
+				n2s(p, seq);
+				n2l3(p, frag_off);
+
+				dtls1_retransmit_message(s,
+										 dtls1_get_queue_priority(frag->msg_header.seq, 0),
+										 frag_off, &found);
+				if ( ! found  && SSL_in_init(s))
+					{
+					/* fprintf( stderr,"in init = %d\n", SSL_in_init(s)); */
+					/* requested a message not yet sent, 
+					   send an alert ourselves */
+					ssl3_send_alert(s,SSL3_AL_WARNING,
+						DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
+					}
+				}
+#endif
+			}
+		else if (alert_level == 2) /* fatal */
+			{
+			char tmp[16];
+
+			s->rwstate=SSL_NOTHING;
+			s->s3->fatal_alert = alert_descr;
+			SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);
+			BIO_snprintf(tmp,sizeof tmp,"%d",alert_descr);
+			ERR_add_error_data(2,"SSL alert number ",tmp);
+			s->shutdown|=SSL_RECEIVED_SHUTDOWN;
+			SSL_CTX_remove_session(s->ctx,s->session);
+			return(0);
+			}
+		else
+			{
+			al=SSL_AD_ILLEGAL_PARAMETER;
+			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNKNOWN_ALERT_TYPE);
+			goto f_err;
+			}
+
+		goto start;
+		}
+
+	if (s->shutdown & SSL_SENT_SHUTDOWN) /* but we have not received a shutdown */
+		{
+		s->rwstate=SSL_NOTHING;
+		rr->length=0;
+		return(0);
+		}
+
+	if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
+		{
+		struct ccs_header_st ccs_hdr;
+		unsigned int ccs_hdr_len = DTLS1_CCS_HEADER_LENGTH;
+
+		dtls1_get_ccs_header(rr->data, &ccs_hdr);
+
+		if (s->version == DTLS1_BAD_VER)
+			ccs_hdr_len = 3;
+
+		/* 'Change Cipher Spec' is just a single byte, so we know
+		 * exactly what the record payload has to look like */
+		/* XDTLS: check that epoch is consistent */
+		if (	(rr->length != ccs_hdr_len) || 
+			(rr->off != 0) || (rr->data[0] != SSL3_MT_CCS))
+			{
+			i=SSL_AD_ILLEGAL_PARAMETER;
+			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC);
+			goto err;
+			}
+
+		rr->length=0;
+
+		if (s->msg_callback)
+			s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, 
+				rr->data, 1, s, s->msg_callback_arg);
+
+		/* We can't process a CCS now, because previous handshake
+		 * messages are still missing, so just drop it.
+		 */
+		if (!s->d1->change_cipher_spec_ok)
+			{
+			goto start;
+			}
+
+		s->d1->change_cipher_spec_ok = 0;
+
+		s->s3->change_cipher_spec=1;
+		if (!ssl3_do_change_cipher_spec(s))
+			goto err;
+
+		/* do this whenever CCS is processed */
+		dtls1_reset_seq_numbers(s, SSL3_CC_READ);
+
+		if (s->version == DTLS1_BAD_VER)
+			s->d1->handshake_read_seq++;
+
+		goto start;
+		}
+
+	/* Unexpected handshake message (Client Hello, or protocol violation) */
+	if ((s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && 
+		!s->in_handshake)
+		{
+		struct hm_header_st msg_hdr;
+		
+		/* this may just be a stale retransmit */
+		dtls1_get_message_header(rr->data, &msg_hdr);
+		if( rr->epoch != s->d1->r_epoch)
+			{
+			rr->length = 0;
+			goto start;
+			}
+
+		/* If we are server, we may have a repeated FINISHED of the
+		 * client here, then retransmit our CCS and FINISHED.
+		 */
+		if (msg_hdr.type == SSL3_MT_FINISHED)
+			{
+			dtls1_retransmit_buffered_messages(s);
+			rr->length = 0;
+			goto start;
+			}
+
+		if (((s->state&SSL_ST_MASK) == SSL_ST_OK) &&
+			!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS))
+			{
+#if 0 /* worked only because C operator preferences are not as expected (and
+       * because this is not really needed for clients except for detecting
+       * protocol violations): */
+			s->state=SSL_ST_BEFORE|(s->server)
+				?SSL_ST_ACCEPT
+				:SSL_ST_CONNECT;
+#else
+			s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
+#endif
+			s->new_session=1;
+			}
+		i=s->handshake_func(s);
+		if (i < 0) return(i);
+		if (i == 0)
+			{
+			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
+			return(-1);
+			}
+
+		if (!(s->mode & SSL_MODE_AUTO_RETRY))
+			{
+			if (s->s3->rbuf.left == 0) /* no read-ahead left? */
+				{
+				BIO *bio;
+				/* In the case where we try to read application data,
+				 * but we trigger an SSL handshake, we return -1 with
+				 * the retry option set.  Otherwise renegotiation may
+				 * cause nasty problems in the blocking world */
+				s->rwstate=SSL_READING;
+				bio=SSL_get_rbio(s);
+				BIO_clear_retry_flags(bio);
+				BIO_set_retry_read(bio);
+				return(-1);
+				}
+			}
+		goto start;
+		}
+
+	switch (rr->type)
+		{
+	default:
+#ifndef OPENSSL_NO_TLS
+		/* TLS just ignores unknown message types */
+		if (s->version == TLS1_VERSION)
+			{
+			rr->length = 0;
+			goto start;
+			}
+#endif
+		al=SSL_AD_UNEXPECTED_MESSAGE;
+		SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
+		goto f_err;
+	case SSL3_RT_CHANGE_CIPHER_SPEC:
+	case SSL3_RT_ALERT:
+	case SSL3_RT_HANDSHAKE:
+		/* we already handled all of these, with the possible exception
+		 * of SSL3_RT_HANDSHAKE when s->in_handshake is set, but that
+		 * should not happen when type != rr->type */
+		al=SSL_AD_UNEXPECTED_MESSAGE;
+		SSLerr(SSL_F_DTLS1_READ_BYTES,ERR_R_INTERNAL_ERROR);
+		goto f_err;
+	case SSL3_RT_APPLICATION_DATA:
+		/* At this point, we were expecting handshake data,
+		 * but have application data.  If the library was
+		 * running inside ssl3_read() (i.e. in_read_app_data
+		 * is set) and it makes sense to read application data
+		 * at this point (session renegotiation not yet started),
+		 * we will indulge it.
+		 */
+		if (s->s3->in_read_app_data &&
+			(s->s3->total_renegotiations != 0) &&
+			((
+				(s->state & SSL_ST_CONNECT) &&
+				(s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&
+				(s->state <= SSL3_ST_CR_SRVR_HELLO_A)
+				) || (
+					(s->state & SSL_ST_ACCEPT) &&
+					(s->state <= SSL3_ST_SW_HELLO_REQ_A) &&
+					(s->state >= SSL3_ST_SR_CLNT_HELLO_A)
+					)
+				))
+			{
+			s->s3->in_read_app_data=2;
+			return(-1);
+			}
+		else
+			{
+			al=SSL_AD_UNEXPECTED_MESSAGE;
+			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
+			goto f_err;
+			}
+		}
+	/* not reached */
+
+f_err:
+	ssl3_send_alert(s,SSL3_AL_FATAL,al);
+err:
+	return(-1);
+	}
+
+int
+dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len)
+	{
+	int i;
+
+	if (SSL_in_init(s) && !s->in_handshake)
+		{
+		i=s->handshake_func(s);
+		if (i < 0) return(i);
+		if (i == 0)
+			{
+			SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
+			return -1;
+			}
+		}
+
+	if (len > SSL3_RT_MAX_PLAIN_LENGTH)
+		{
+			SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,SSL_R_DTLS_MESSAGE_TOO_BIG);
+			return -1;
+		}
+
+	i = dtls1_write_bytes(s, type, buf_, len);
+	return i;
+	}
+
+
+	/* this only happens when a client hello is received and a handshake 
+	 * is started. */
+static int
+have_handshake_fragment(SSL *s, int type, unsigned char *buf, 
+	int len, int peek)
+	{
+	
+	if ((type == SSL3_RT_HANDSHAKE) && (s->d1->handshake_fragment_len > 0))
+		/* (partially) satisfy request from storage */
+		{
+		unsigned char *src = s->d1->handshake_fragment;
+		unsigned char *dst = buf;
+		unsigned int k,n;
+		
+		/* peek == 0 */
+		n = 0;
+		while ((len > 0) && (s->d1->handshake_fragment_len > 0))
+			{
+			*dst++ = *src++;
+			len--; s->d1->handshake_fragment_len--;
+			n++;
+			}
+		/* move any remaining fragment bytes: */
+		for (k = 0; k < s->d1->handshake_fragment_len; k++)
+			s->d1->handshake_fragment[k] = *src++;
+		return n;
+		}
+	
+	return 0;
+	}
+
+
+
+
+/* Call this to write data in records of type 'type'
+ * It will return <= 0 if not all data has been sent or non-blocking IO.
+ */
+int dtls1_write_bytes(SSL *s, int type, const void *buf, int len)
+	{
+	int i;
+
+	OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
+	s->rwstate=SSL_NOTHING;
+	i=do_dtls1_write(s, type, buf, len, 0);
+	return i;
+	}
+
+int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, int create_empty_fragment)
+	{
+	unsigned char *p,*pseq;
+	int i,mac_size,clear=0;
+	int prefix_len = 0;
+	SSL3_RECORD *wr;
+	SSL3_BUFFER *wb;
+	SSL_SESSION *sess;
+	int bs;
+	unsigned int len_with_overhead = len + SSL3_RT_DEFAULT_WRITE_OVERHEAD;
+
+	/* first check if there is a SSL3_BUFFER still being written
+	 * out.  This will happen with non blocking IO */
+	if (s->s3->wbuf.left != 0)
+		{
+		OPENSSL_assert(0); /* XDTLS:  want to see if we ever get here */
+		return(ssl3_write_pending(s,type,buf,len));
+		}
+
+	if (s->s3->wbuf.len < len_with_overhead)
+		{
+		if ((p=OPENSSL_realloc(s->s3->wbuf.buf, len_with_overhead)) == NULL) {
+			SSLerr(SSL_F_DO_DTLS1_WRITE,ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		s->s3->wbuf.buf = p;
+		s->s3->wbuf.len = len_with_overhead;
+		}
+
+	/* If we have an alert to send, lets send it */
+	if (s->s3->alert_dispatch)
+		{
+		i=s->method->ssl_dispatch_alert(s);
+		if (i <= 0)
+			return(i);
+		/* if it went, fall through and send more stuff */
+		}
+
+	if (len == 0 && !create_empty_fragment)
+		return 0;
+
+	wr= &(s->s3->wrec);
+	wb= &(s->s3->wbuf);
+	sess=s->session;
+
+	if (	(sess == NULL) ||
+		(s->enc_write_ctx == NULL) ||
+		(EVP_MD_CTX_md(s->write_hash) == NULL))
+		clear=1;
+
+	if (clear)
+		mac_size=0;
+	else
+		{
+		mac_size=EVP_MD_CTX_size(s->write_hash);
+		if (mac_size < 0)
+			goto err;
+		}
+
+	/* DTLS implements explicit IV, so no need for empty fragments */
+#if 0
+	/* 'create_empty_fragment' is true only when this function calls itself */
+	if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done
+	    && SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
+		{
+		/* countermeasure against known-IV weakness in CBC ciphersuites
+		 * (see http://www.openssl.org/~bodo/tls-cbc.txt) 
+		 */
+
+		if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA)
+			{
+			/* recursive function call with 'create_empty_fragment' set;
+			 * this prepares and buffers the data for an empty fragment
+			 * (these 'prefix_len' bytes are sent out later
+			 * together with the actual payload) */
+			prefix_len = s->method->do_ssl_write(s, type, buf, 0, 1);
+			if (prefix_len <= 0)
+				goto err;
+
+			if (s->s3->wbuf.len < (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE)
+				{
+				/* insufficient space */
+				SSLerr(SSL_F_DO_DTLS1_WRITE, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+			}
+		
+		s->s3->empty_fragment_done = 1;
+		}
+#endif
+	p = wb->buf + prefix_len;
+
+	/* write the header */
+
+	*(p++)=type&0xff;
+	wr->type=type;
+
+	*(p++)=(s->version>>8);
+	*(p++)=s->version&0xff;
+
+	/* field where we are to write out packet epoch, seq num and len */
+	pseq=p; 
+	p+=10;
+
+	/* lets setup the record stuff. */
+
+	/* Make space for the explicit IV in case of CBC.
+	 * (this is a bit of a boundary violation, but what the heck).
+	 */
+	if ( s->enc_write_ctx && 
+		(EVP_CIPHER_mode( s->enc_write_ctx->cipher ) & EVP_CIPH_CBC_MODE))
+		bs = EVP_CIPHER_block_size(s->enc_write_ctx->cipher);
+	else
+		bs = 0;
+
+	wr->data=p + bs;  /* make room for IV in case of CBC */
+	wr->length=(int)len;
+	wr->input=(unsigned char *)buf;
+
+	/* we now 'read' from wr->input, wr->length bytes into
+	 * wr->data */
+
+	/* first we compress */
+	if (s->compress != NULL)
+		{
+		if (!ssl3_do_compress(s))
+			{
+			SSLerr(SSL_F_DO_DTLS1_WRITE,SSL_R_COMPRESSION_FAILURE);
+			goto err;
+			}
+		}
+	else
+		{
+		memcpy(wr->data,wr->input,wr->length);
+		wr->input=wr->data;
+		}
+
+	/* we should still have the output to wr->data and the input
+	 * from wr->input.  Length should be wr->length.
+	 * wr->data still points in the wb->buf */
+
+	if (mac_size != 0)
+		{
+		if(s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1) < 0)
+			goto err;
+		wr->length+=mac_size;
+		}
+
+	/* this is true regardless of mac size */
+	wr->input=p;
+	wr->data=p;
+
+
+	/* ssl3_enc can only have an error on read */
+	if (bs)	/* bs != 0 in case of CBC */
+		{
+		RAND_pseudo_bytes(p,bs);
+		/* master IV and last CBC residue stand for
+		 * the rest of randomness */
+		wr->length += bs;
+		}
+
+	s->method->ssl3_enc->enc(s,1);
+
+	/* record length after mac and block padding */
+/*	if (type == SSL3_RT_APPLICATION_DATA ||
+	(type == SSL3_RT_ALERT && ! SSL_in_init(s))) */
+	
+	/* there's only one epoch between handshake and app data */
+	
+	s2n(s->d1->w_epoch, pseq);
+
+	/* XDTLS: ?? */
+/*	else
+	s2n(s->d1->handshake_epoch, pseq); */
+
+	memcpy(pseq, &(s->s3->write_sequence[2]), 6);
+	pseq+=6;
+	s2n(wr->length,pseq);
+
+	/* we should now have
+	 * wr->data pointing to the encrypted data, which is
+	 * wr->length long */
+	wr->type=type; /* not needed but helps for debugging */
+	wr->length+=DTLS1_RT_HEADER_LENGTH;
+
+#if 0  /* this is now done at the message layer */
+	/* buffer the record, making it easy to handle retransmits */
+	if ( type == SSL3_RT_HANDSHAKE || type == SSL3_RT_CHANGE_CIPHER_SPEC)
+		dtls1_buffer_record(s, wr->data, wr->length, 
+			*((PQ_64BIT *)&(s->s3->write_sequence[0])));
+#endif
+
+	ssl3_record_sequence_update(&(s->s3->write_sequence[0]));
+
+	if (create_empty_fragment)
+		{
+		/* we are in a recursive call;
+		 * just return the length, don't write out anything here
+		 */
+		return wr->length;
+		}
+
+	/* now let's set up wb */
+	wb->left = prefix_len + wr->length;
+	wb->offset = 0;
+
+	/* memorize arguments so that ssl3_write_pending can detect bad write retries later */
+	s->s3->wpend_tot=len;
+	s->s3->wpend_buf=buf;
+	s->s3->wpend_type=type;
+	s->s3->wpend_ret=len;
+
+	/* we now just need to write the buffer */
+	return ssl3_write_pending(s,type,buf,len);
+err:
+	return -1;
+	}
+
+
+
+static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap)
+	{
+	int cmp;
+	unsigned int shift;
+	const unsigned char *seq = s->s3->read_sequence;
+
+	cmp = satsub64be(seq,bitmap->max_seq_num);
+	if (cmp > 0)
+		{
+		memcpy (s->s3->rrec.seq_num,seq,8);
+		return 1; /* this record in new */
+		}
+	shift = -cmp;
+	if (shift >= sizeof(bitmap->map)*8)
+		return 0; /* stale, outside the window */
+	else if (bitmap->map & (1UL<<shift))
+		return 0; /* record previously received */
+
+	memcpy (s->s3->rrec.seq_num,seq,8);
+	return 1;
+	}
+
+
+static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap)
+	{
+	int cmp;
+	unsigned int shift;
+	const unsigned char *seq = s->s3->read_sequence;
+
+	cmp = satsub64be(seq,bitmap->max_seq_num);
+	if (cmp > 0)
+		{
+		shift = cmp;
+		if (shift < sizeof(bitmap->map)*8)
+			bitmap->map <<= shift, bitmap->map |= 1UL;
+		else
+			bitmap->map = 1UL;
+		memcpy(bitmap->max_seq_num,seq,8);
+		}
+	else	{
+		shift = -cmp;
+		if (shift < sizeof(bitmap->map)*8)
+			bitmap->map |= 1UL<<shift;
+		}
+	}
+
+
+int dtls1_dispatch_alert(SSL *s)
+	{
+	int i,j;
+	void (*cb)(const SSL *ssl,int type,int val)=NULL;
+	unsigned char buf[DTLS1_AL_HEADER_LENGTH];
+	unsigned char *ptr = &buf[0];
+
+	s->s3->alert_dispatch=0;
+
+	memset(buf, 0x00, sizeof(buf));
+	*ptr++ = s->s3->send_alert[0];
+	*ptr++ = s->s3->send_alert[1];
+
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+	if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)
+		{	
+		s2n(s->d1->handshake_read_seq, ptr);
+#if 0
+		if ( s->d1->r_msg_hdr.frag_off == 0)  /* waiting for a new msg */
+
+		else
+			s2n(s->d1->r_msg_hdr.seq, ptr); /* partial msg read */
+#endif
+
+#if 0
+		fprintf(stderr, "s->d1->handshake_read_seq = %d, s->d1->r_msg_hdr.seq = %d\n",s->d1->handshake_read_seq,s->d1->r_msg_hdr.seq);
+#endif
+		l2n3(s->d1->r_msg_hdr.frag_off, ptr);
+		}
+#endif
+
+	i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0);
+	if (i <= 0)
+		{
+		s->s3->alert_dispatch=1;
+		/* fprintf( stderr, "not done with alert\n" ); */
+		}
+	else
+		{
+		if (s->s3->send_alert[0] == SSL3_AL_FATAL
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+		    || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+#endif
+		    )
+			(void)BIO_flush(s->wbio);
+
+		if (s->msg_callback)
+			s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, 
+				2, s, s->msg_callback_arg);
+
+		if (s->info_callback != NULL)
+			cb=s->info_callback;
+		else if (s->ctx->info_callback != NULL)
+			cb=s->ctx->info_callback;
+
+		if (cb != NULL)
+			{
+			j=(s->s3->send_alert[0]<<8)|s->s3->send_alert[1];
+			cb(s,SSL_CB_WRITE_ALERT,j);
+			}
+		}
+	return(i);
+	}
+
+
+static DTLS1_BITMAP *
+dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, unsigned int *is_next_epoch)
+    {
+    
+    *is_next_epoch = 0;
+
+    /* In current epoch, accept HM, CCS, DATA, & ALERT */
+    if (rr->epoch == s->d1->r_epoch)
+        return &s->d1->bitmap;
+
+    /* Only HM and ALERT messages can be from the next epoch */
+    else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) &&
+        (rr->type == SSL3_RT_HANDSHAKE ||
+            rr->type == SSL3_RT_ALERT))
+        {
+        *is_next_epoch = 1;
+        return &s->d1->next_bitmap;
+        }
+
+    return NULL;
+    }
+
+#if 0
+static int
+dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, unsigned short *priority,
+	unsigned long *offset)
+	{
+
+	/* alerts are passed up immediately */
+	if ( rr->type == SSL3_RT_APPLICATION_DATA ||
+		rr->type == SSL3_RT_ALERT)
+		return 0;
+
+	/* Only need to buffer if a handshake is underway.
+	 * (this implies that Hello Request and Client Hello are passed up
+	 * immediately) */
+	if ( SSL_in_init(s))
+		{
+		unsigned char *data = rr->data;
+		/* need to extract the HM/CCS sequence number here */
+		if ( rr->type == SSL3_RT_HANDSHAKE ||
+			rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
+			{
+			unsigned short seq_num;
+			struct hm_header_st msg_hdr;
+			struct ccs_header_st ccs_hdr;
+
+			if ( rr->type == SSL3_RT_HANDSHAKE)
+				{
+				dtls1_get_message_header(data, &msg_hdr);
+				seq_num = msg_hdr.seq;
+				*offset = msg_hdr.frag_off;
+				}
+			else
+				{
+				dtls1_get_ccs_header(data, &ccs_hdr);
+				seq_num = ccs_hdr.seq;
+				*offset = 0;
+				}
+				
+			/* this is either a record we're waiting for, or a
+			 * retransmit of something we happened to previously 
+			 * receive (higher layers will drop the repeat silently */
+			if ( seq_num < s->d1->handshake_read_seq)
+				return 0;
+			if (rr->type == SSL3_RT_HANDSHAKE && 
+				seq_num == s->d1->handshake_read_seq &&
+				msg_hdr.frag_off < s->d1->r_msg_hdr.frag_off)
+				return 0;
+			else if ( seq_num == s->d1->handshake_read_seq &&
+				(rr->type == SSL3_RT_CHANGE_CIPHER_SPEC ||
+					msg_hdr.frag_off == s->d1->r_msg_hdr.frag_off))
+				return 0;
+			else
+				{
+				*priority = seq_num;
+				return 1;
+				}
+			}
+		else /* unknown record type */
+			return 0;
+		}
+
+	return 0;
+	}
+#endif
+
+void
+dtls1_reset_seq_numbers(SSL *s, int rw)
+	{
+	unsigned char *seq;
+	unsigned int seq_bytes = sizeof(s->s3->read_sequence);
+
+	if ( rw & SSL3_CC_READ)
+		{
+		seq = s->s3->read_sequence;
+		s->d1->r_epoch++;
+		memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP));
+		memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP));
+		}
+	else
+		{
+		seq = s->s3->write_sequence;
+		memcpy(s->d1->last_write_sequence, seq, sizeof(s->s3->write_sequence));
+		s->d1->w_epoch++;
+		}
+
+	memset(seq, 0x00, seq_bytes);
+	}
+
+
+static void
+dtls1_clear_timeouts(SSL *s)
+	{
+	memset(&(s->d1->timeout), 0x00, sizeof(struct dtls1_timeout_st));
+	}
diff --git a/openssl/ssl/d1_srvr.c b/openssl/ssl/d1_srvr.c
new file mode 100644
index 0000000..149983b
--- /dev/null
+++ b/openssl/ssl/d1_srvr.c
@@ -0,0 +1,1563 @@
+/* ssl/d1_srvr.c */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "ssl_locl.h"
+#include <openssl/buffer.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/md5.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+
+static const SSL_METHOD *dtls1_get_server_method(int ver);
+static int dtls1_send_hello_verify_request(SSL *s);
+
+static const SSL_METHOD *dtls1_get_server_method(int ver)
+	{
+	if (ver == DTLS1_VERSION)
+		return(DTLSv1_server_method());
+	else
+		return(NULL);
+	}
+
+IMPLEMENT_dtls1_meth_func(DTLSv1_server_method,
+			dtls1_accept,
+			ssl_undefined_function,
+			dtls1_get_server_method)
+
+int dtls1_accept(SSL *s)
+	{
+	BUF_MEM *buf;
+	unsigned long Time=(unsigned long)time(NULL);
+	void (*cb)(const SSL *ssl,int type,int val)=NULL;
+	unsigned long alg_k;
+	int ret= -1;
+	int new_state,state,skip=0;
+	int listen;
+
+	RAND_add(&Time,sizeof(Time),0);
+	ERR_clear_error();
+	clear_sys_error();
+
+	if (s->info_callback != NULL)
+		cb=s->info_callback;
+	else if (s->ctx->info_callback != NULL)
+		cb=s->ctx->info_callback;
+	
+	listen = s->d1->listen;
+
+	/* init things to blank */
+	s->in_handshake++;
+	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
+
+	s->d1->listen = listen;
+
+	if (s->cert == NULL)
+		{
+		SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
+		return(-1);
+		}
+
+	for (;;)
+		{
+		state=s->state;
+
+		switch (s->state)
+			{
+		case SSL_ST_RENEGOTIATE:
+			s->new_session=1;
+			/* s->state=SSL_ST_ACCEPT; */
+
+		case SSL_ST_BEFORE:
+		case SSL_ST_ACCEPT:
+		case SSL_ST_BEFORE|SSL_ST_ACCEPT:
+		case SSL_ST_OK|SSL_ST_ACCEPT:
+
+			s->server=1;
+			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
+
+			if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00))
+				{
+				SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR);
+				return -1;
+				}
+			s->type=SSL_ST_ACCEPT;
+
+			if (s->init_buf == NULL)
+				{
+				if ((buf=BUF_MEM_new()) == NULL)
+					{
+					ret= -1;
+					goto end;
+					}
+				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
+					{
+					ret= -1;
+					goto end;
+					}
+				s->init_buf=buf;
+				}
+
+			if (!ssl3_setup_buffers(s))
+				{
+				ret= -1;
+				goto end;
+				}
+
+			s->init_num=0;
+
+			if (s->state != SSL_ST_RENEGOTIATE)
+				{
+				/* Ok, we now need to push on a buffering BIO so that
+				 * the output is sent in a way that TCP likes :-)
+				 */
+				if (!ssl_init_wbio_buffer(s,1)) { ret= -1; goto end; }
+
+				ssl3_init_finished_mac(s);
+				s->state=SSL3_ST_SR_CLNT_HELLO_A;
+				s->ctx->stats.sess_accept++;
+				}
+			else
+				{
+				/* s->state == SSL_ST_RENEGOTIATE,
+				 * we will just send a HelloRequest */
+				s->ctx->stats.sess_accept_renegotiate++;
+				s->state=SSL3_ST_SW_HELLO_REQ_A;
+				}
+
+			break;
+
+		case SSL3_ST_SW_HELLO_REQ_A:
+		case SSL3_ST_SW_HELLO_REQ_B:
+
+			s->shutdown=0;
+			dtls1_start_timer(s);
+			ret=dtls1_send_hello_request(s);
+			if (ret <= 0) goto end;
+			s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C;
+			s->state=SSL3_ST_SW_FLUSH;
+			s->init_num=0;
+
+			ssl3_init_finished_mac(s);
+			break;
+
+		case SSL3_ST_SW_HELLO_REQ_C:
+			s->state=SSL_ST_OK;
+			break;
+
+		case SSL3_ST_SR_CLNT_HELLO_A:
+		case SSL3_ST_SR_CLNT_HELLO_B:
+		case SSL3_ST_SR_CLNT_HELLO_C:
+
+			s->shutdown=0;
+			ret=ssl3_get_client_hello(s);
+			if (ret <= 0) goto end;
+			dtls1_stop_timer(s);
+
+			if (ret == 1 && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE))
+				s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A;
+			else
+				s->state = SSL3_ST_SW_SRVR_HELLO_A;
+
+			s->init_num=0;
+
+			/* Reflect ClientHello sequence to remain stateless while listening */
+			if (listen)
+				{
+				memcpy(s->s3->write_sequence, s->s3->read_sequence, sizeof(s->s3->write_sequence));
+				}
+
+			/* If we're just listening, stop here */
+			if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A)
+				{
+				ret = 2;
+				s->d1->listen = 0;
+				/* Set expected sequence numbers
+				 * to continue the handshake.
+				 */
+				s->d1->handshake_read_seq = 2;
+				s->d1->handshake_write_seq = 1;
+				s->d1->next_handshake_write_seq = 1;
+				goto end;
+				}
+			
+			break;
+			
+		case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
+		case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
+
+			ret = dtls1_send_hello_verify_request(s);
+			if ( ret <= 0) goto end;
+			s->state=SSL3_ST_SW_FLUSH;
+			s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A;
+
+			/* HelloVerifyRequest resets Finished MAC */
+			if (s->version != DTLS1_BAD_VER)
+				ssl3_init_finished_mac(s);
+			break;
+			
+		case SSL3_ST_SW_SRVR_HELLO_A:
+		case SSL3_ST_SW_SRVR_HELLO_B:
+			s->new_session = 2;
+			dtls1_start_timer(s);
+			ret=dtls1_send_server_hello(s);
+			if (ret <= 0) goto end;
+
+#ifndef OPENSSL_NO_TLSEXT
+			if (s->hit)
+				{
+				if (s->tlsext_ticket_expected)
+					s->state=SSL3_ST_SW_SESSION_TICKET_A;
+				else
+					s->state=SSL3_ST_SW_CHANGE_A;
+				}
+#else
+			if (s->hit)
+					s->state=SSL3_ST_SW_CHANGE_A;
+#endif
+			else
+				s->state=SSL3_ST_SW_CERT_A;
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_SW_CERT_A:
+		case SSL3_ST_SW_CERT_B:
+			/* Check if it is anon DH or normal PSK */
+			if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
+				&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
+				{
+				dtls1_start_timer(s);
+				ret=dtls1_send_server_certificate(s);
+				if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_TLSEXT
+				if (s->tlsext_status_expected)
+					s->state=SSL3_ST_SW_CERT_STATUS_A;
+				else
+					s->state=SSL3_ST_SW_KEY_EXCH_A;
+				}
+			else
+				{
+				skip = 1;
+				s->state=SSL3_ST_SW_KEY_EXCH_A;
+				}
+#else
+				}
+			else
+				skip=1;
+
+			s->state=SSL3_ST_SW_KEY_EXCH_A;
+#endif
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_SW_KEY_EXCH_A:
+		case SSL3_ST_SW_KEY_EXCH_B:
+			alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+
+			/* clear this, it may get reset by
+			 * send_server_key_exchange */
+			if ((s->options & SSL_OP_EPHEMERAL_RSA)
+#ifndef OPENSSL_NO_KRB5
+				&& !(alg_k & SSL_kKRB5)
+#endif /* OPENSSL_NO_KRB5 */
+				)
+				/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
+				 * even when forbidden by protocol specs
+				 * (handshake may fail as clients are not required to
+				 * be able to handle this) */
+				s->s3->tmp.use_rsa_tmp=1;
+			else
+				s->s3->tmp.use_rsa_tmp=0;
+
+			/* only send if a DH key exchange or
+			 * RSA but we have a sign only certificate */
+			if (s->s3->tmp.use_rsa_tmp
+			/* PSK: send ServerKeyExchange if PSK identity
+			 * hint if provided */
+#ifndef OPENSSL_NO_PSK
+			    || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint)
+#endif
+			    || (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
+			    || (alg_k & SSL_kEECDH)
+			    || ((alg_k & SSL_kRSA)
+				&& (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
+				    || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
+					&& EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
+					)
+				    )
+				)
+			    )
+				{
+				dtls1_start_timer(s);
+				ret=dtls1_send_server_key_exchange(s);
+				if (ret <= 0) goto end;
+				}
+			else
+				skip=1;
+
+			s->state=SSL3_ST_SW_CERT_REQ_A;
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_SW_CERT_REQ_A:
+		case SSL3_ST_SW_CERT_REQ_B:
+			if (/* don't request cert unless asked for it: */
+				!(s->verify_mode & SSL_VERIFY_PEER) ||
+				/* if SSL_VERIFY_CLIENT_ONCE is set,
+				 * don't request cert during re-negotiation: */
+				((s->session->peer != NULL) &&
+				 (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
+				/* never request cert in anonymous ciphersuites
+				 * (see section "Certificate request" in SSL 3 drafts
+				 * and in RFC 2246): */
+				((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
+				 /* ... except when the application insists on verification
+				  * (against the specs, but s3_clnt.c accepts this for SSL 3) */
+				 !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
+				 /* never request cert in Kerberos ciphersuites */
+				(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)
+				/* With normal PSK Certificates and
+				 * Certificate Requests are omitted */
+				|| (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
+				{
+				/* no cert request */
+				skip=1;
+				s->s3->tmp.cert_request=0;
+				s->state=SSL3_ST_SW_SRVR_DONE_A;
+				}
+			else
+				{
+				s->s3->tmp.cert_request=1;
+				dtls1_start_timer(s);
+				ret=dtls1_send_certificate_request(s);
+				if (ret <= 0) goto end;
+#ifndef NETSCAPE_HANG_BUG
+				s->state=SSL3_ST_SW_SRVR_DONE_A;
+#else
+				s->state=SSL3_ST_SW_FLUSH;
+				s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
+#endif
+				s->init_num=0;
+				}
+			break;
+
+		case SSL3_ST_SW_SRVR_DONE_A:
+		case SSL3_ST_SW_SRVR_DONE_B:
+			dtls1_start_timer(s);
+			ret=dtls1_send_server_done(s);
+			if (ret <= 0) goto end;
+			s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
+			s->state=SSL3_ST_SW_FLUSH;
+			s->init_num=0;
+			break;
+		
+		case SSL3_ST_SW_FLUSH:
+			s->rwstate=SSL_WRITING;
+			if (BIO_flush(s->wbio) <= 0)
+				{
+				ret= -1;
+				goto end;
+				}
+			s->rwstate=SSL_NOTHING;
+			s->state=s->s3->tmp.next_state;
+			break;
+
+		case SSL3_ST_SR_CERT_A:
+		case SSL3_ST_SR_CERT_B:
+			/* Check for second client hello (MS SGC) */
+			ret = ssl3_check_client_hello(s);
+			if (ret <= 0)
+				goto end;
+			dtls1_stop_timer(s);
+			if (ret == 2)
+				s->state = SSL3_ST_SR_CLNT_HELLO_C;
+			else {
+				/* could be sent for a DH cert, even if we
+				 * have not asked for it :-) */
+				ret=ssl3_get_client_certificate(s);
+				if (ret <= 0) goto end;
+				dtls1_stop_timer(s);
+				s->init_num=0;
+				s->state=SSL3_ST_SR_KEY_EXCH_A;
+			}
+			break;
+
+		case SSL3_ST_SR_KEY_EXCH_A:
+		case SSL3_ST_SR_KEY_EXCH_B:
+			ret=ssl3_get_client_key_exchange(s);
+			if (ret <= 0) goto end;
+			dtls1_stop_timer(s);
+			s->state=SSL3_ST_SR_CERT_VRFY_A;
+			s->init_num=0;
+
+			if (ret == 2)
+				{
+				/* For the ECDH ciphersuites when
+				 * the client sends its ECDH pub key in
+				 * a certificate, the CertificateVerify
+				 * message is not sent.
+				 */
+				s->state=SSL3_ST_SR_FINISHED_A;
+				s->init_num = 0;
+				}
+			else
+				{
+				s->state=SSL3_ST_SR_CERT_VRFY_A;
+				s->init_num=0;
+
+				/* We need to get hashes here so if there is
+				 * a client cert, it can be verified */ 
+				s->method->ssl3_enc->cert_verify_mac(s,
+					NID_md5,
+					&(s->s3->tmp.cert_verify_md[0]));
+				s->method->ssl3_enc->cert_verify_mac(s,
+					NID_sha1,
+					&(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]));
+				}
+			break;
+
+		case SSL3_ST_SR_CERT_VRFY_A:
+		case SSL3_ST_SR_CERT_VRFY_B:
+
+			s->d1->change_cipher_spec_ok = 1;
+			/* we should decide if we expected this one */
+			ret=ssl3_get_cert_verify(s);
+			if (ret <= 0) goto end;
+			dtls1_stop_timer(s);
+
+			s->state=SSL3_ST_SR_FINISHED_A;
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_SR_FINISHED_A:
+		case SSL3_ST_SR_FINISHED_B:
+			s->d1->change_cipher_spec_ok = 1;
+			ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
+				SSL3_ST_SR_FINISHED_B);
+			if (ret <= 0) goto end;
+			dtls1_stop_timer(s);
+			if (s->hit)
+				s->state=SSL_ST_OK;
+#ifndef OPENSSL_NO_TLSEXT
+			else if (s->tlsext_ticket_expected)
+				s->state=SSL3_ST_SW_SESSION_TICKET_A;
+#endif
+			else
+				s->state=SSL3_ST_SW_CHANGE_A;
+			s->init_num=0;
+			break;
+
+#ifndef OPENSSL_NO_TLSEXT
+		case SSL3_ST_SW_SESSION_TICKET_A:
+		case SSL3_ST_SW_SESSION_TICKET_B:
+			ret=dtls1_send_newsession_ticket(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_SW_CHANGE_A;
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_SW_CERT_STATUS_A:
+		case SSL3_ST_SW_CERT_STATUS_B:
+			ret=ssl3_send_cert_status(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_SW_KEY_EXCH_A;
+			s->init_num=0;
+			break;
+
+#endif
+
+		case SSL3_ST_SW_CHANGE_A:
+		case SSL3_ST_SW_CHANGE_B:
+
+			s->session->cipher=s->s3->tmp.new_cipher;
+			if (!s->method->ssl3_enc->setup_key_block(s))
+				{ ret= -1; goto end; }
+
+			ret=dtls1_send_change_cipher_spec(s,
+				SSL3_ST_SW_CHANGE_A,SSL3_ST_SW_CHANGE_B);
+
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_SW_FINISHED_A;
+			s->init_num=0;
+
+			if (!s->method->ssl3_enc->change_cipher_state(s,
+				SSL3_CHANGE_CIPHER_SERVER_WRITE))
+				{
+				ret= -1;
+				goto end;
+				}
+
+			dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
+			break;
+
+		case SSL3_ST_SW_FINISHED_A:
+		case SSL3_ST_SW_FINISHED_B:
+			ret=dtls1_send_finished(s,
+				SSL3_ST_SW_FINISHED_A,SSL3_ST_SW_FINISHED_B,
+				s->method->ssl3_enc->server_finished_label,
+				s->method->ssl3_enc->server_finished_label_len);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_SW_FLUSH;
+			if (s->hit)
+				s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
+			else
+				s->s3->tmp.next_state=SSL_ST_OK;
+			s->init_num=0;
+			break;
+
+		case SSL_ST_OK:
+			/* clean a few things up */
+			ssl3_cleanup_key_block(s);
+
+#if 0
+			BUF_MEM_free(s->init_buf);
+			s->init_buf=NULL;
+#endif
+
+			/* remove buffering on output */
+			ssl_free_wbio_buffer(s);
+
+			s->init_num=0;
+
+			if (s->new_session == 2) /* skipped if we just sent a HelloRequest */
+				{
+				/* actually not necessarily a 'new' session unless
+				 * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */
+				
+				s->new_session=0;
+				
+				ssl_update_cache(s,SSL_SESS_CACHE_SERVER);
+				
+				s->ctx->stats.sess_accept_good++;
+				/* s->server=1; */
+				s->handshake_func=dtls1_accept;
+
+				if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
+				}
+			
+			ret = 1;
+
+			/* done handshaking, next message is client hello */
+			s->d1->handshake_read_seq = 0;
+			/* next message is server hello */
+			s->d1->handshake_write_seq = 0;
+			s->d1->next_handshake_write_seq = 0;
+			goto end;
+			/* break; */
+
+		default:
+			SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_UNKNOWN_STATE);
+			ret= -1;
+			goto end;
+			/* break; */
+			}
+		
+		if (!s->s3->tmp.reuse_message && !skip)
+			{
+			if (s->debug)
+				{
+				if ((ret=BIO_flush(s->wbio)) <= 0)
+					goto end;
+				}
+
+
+			if ((cb != NULL) && (s->state != state))
+				{
+				new_state=s->state;
+				s->state=state;
+				cb(s,SSL_CB_ACCEPT_LOOP,1);
+				s->state=new_state;
+				}
+			}
+		skip=0;
+		}
+end:
+	/* BIO_flush(s->wbio); */
+
+	s->in_handshake--;
+	if (cb != NULL)
+		cb(s,SSL_CB_ACCEPT_EXIT,ret);
+	return(ret);
+	}
+
+int dtls1_send_hello_request(SSL *s)
+	{
+	unsigned char *p;
+
+	if (s->state == SSL3_ST_SW_HELLO_REQ_A)
+		{
+		p=(unsigned char *)s->init_buf->data;
+		p = dtls1_set_message_header(s, p, SSL3_MT_HELLO_REQUEST, 0, 0, 0);
+
+		s->state=SSL3_ST_SW_HELLO_REQ_B;
+		/* number of bytes to write */
+		s->init_num=DTLS1_HM_HEADER_LENGTH;
+		s->init_off=0;
+
+		/* no need to buffer this message, since there are no retransmit 
+		 * requests for it */
+		}
+
+	/* SSL3_ST_SW_HELLO_REQ_B */
+	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
+	}
+
+int dtls1_send_hello_verify_request(SSL *s)
+	{
+	unsigned int msg_len;
+	unsigned char *msg, *buf, *p;
+
+	if (s->state == DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A)
+		{
+		buf = (unsigned char *)s->init_buf->data;
+
+		msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]);
+		*(p++) = s->version >> 8;
+		*(p++) = s->version & 0xFF;
+
+		if (s->ctx->app_gen_cookie_cb == NULL ||
+		     s->ctx->app_gen_cookie_cb(s, s->d1->cookie,
+			 &(s->d1->cookie_len)) == 0)
+			{
+			SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST,ERR_R_INTERNAL_ERROR);
+			return 0;
+			}
+
+		*(p++) = (unsigned char) s->d1->cookie_len;
+		memcpy(p, s->d1->cookie, s->d1->cookie_len);
+		p += s->d1->cookie_len;
+		msg_len = p - msg;
+
+		dtls1_set_message_header(s, buf,
+			DTLS1_MT_HELLO_VERIFY_REQUEST, msg_len, 0, msg_len);
+
+		s->state=DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B;
+		/* number of bytes to write */
+		s->init_num=p-buf;
+		s->init_off=0;
+		}
+
+	/* s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */
+	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
+	}
+
+int dtls1_send_server_hello(SSL *s)
+	{
+	unsigned char *buf;
+	unsigned char *p,*d;
+	int i;
+	unsigned int sl;
+	unsigned long l,Time;
+
+	if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
+		{
+		buf=(unsigned char *)s->init_buf->data;
+		p=s->s3->server_random;
+		Time=(unsigned long)time(NULL);			/* Time */
+		l2n(Time,p);
+		RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-sizeof(Time));
+		/* Do the message type and length last */
+		d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
+
+		*(p++)=s->version>>8;
+		*(p++)=s->version&0xff;
+
+		/* Random stuff */
+		memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
+		p+=SSL3_RANDOM_SIZE;
+
+		/* now in theory we have 3 options to sending back the
+		 * session id.  If it is a re-use, we send back the
+		 * old session-id, if it is a new session, we send
+		 * back the new session-id or we send back a 0 length
+		 * session-id if we want it to be single use.
+		 * Currently I will not implement the '0' length session-id
+		 * 12-Jan-98 - I'll now support the '0' length stuff.
+		 */
+		if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER))
+			s->session->session_id_length=0;
+
+		sl=s->session->session_id_length;
+		if (sl > sizeof s->session->session_id)
+			{
+			SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
+			return -1;
+			}
+		*(p++)=sl;
+		memcpy(p,s->session->session_id,sl);
+		p+=sl;
+
+		/* put the cipher */
+		if (s->s3->tmp.new_cipher == NULL)
+			return -1;
+		i=ssl3_put_cipher_by_char(s->s3->tmp.new_cipher,p);
+		p+=i;
+
+		/* put the compression method */
+#ifdef OPENSSL_NO_COMP
+		*(p++)=0;
+#else
+		if (s->s3->tmp.new_compression == NULL)
+			*(p++)=0;
+		else
+			*(p++)=s->s3->tmp.new_compression->id;
+#endif
+
+#ifndef OPENSSL_NO_TLSEXT
+		if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
+			{
+			SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
+			return -1;
+			}
+#endif
+
+		/* do the header */
+		l=(p-d);
+		d=buf;
+
+		d = dtls1_set_message_header(s, d, SSL3_MT_SERVER_HELLO, l, 0, l);
+
+		s->state=SSL3_ST_SW_SRVR_HELLO_B;
+		/* number of bytes to write */
+		s->init_num=p-buf;
+		s->init_off=0;
+
+		/* buffer the message to handle re-xmits */
+		dtls1_buffer_message(s, 0);
+		}
+
+	/* SSL3_ST_SW_SRVR_HELLO_B */
+	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
+	}
+
+int dtls1_send_server_done(SSL *s)
+	{
+	unsigned char *p;
+
+	if (s->state == SSL3_ST_SW_SRVR_DONE_A)
+		{
+		p=(unsigned char *)s->init_buf->data;
+
+		/* do the header */
+		p = dtls1_set_message_header(s, p, SSL3_MT_SERVER_DONE, 0, 0, 0);
+
+		s->state=SSL3_ST_SW_SRVR_DONE_B;
+		/* number of bytes to write */
+		s->init_num=DTLS1_HM_HEADER_LENGTH;
+		s->init_off=0;
+
+		/* buffer the message to handle re-xmits */
+		dtls1_buffer_message(s, 0);
+		}
+
+	/* SSL3_ST_SW_SRVR_DONE_B */
+	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
+	}
+
+int dtls1_send_server_key_exchange(SSL *s)
+	{
+#ifndef OPENSSL_NO_RSA
+	unsigned char *q;
+	int j,num;
+	RSA *rsa;
+	unsigned char md_buf[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
+	unsigned int u;
+#endif
+#ifndef OPENSSL_NO_DH
+	DH *dh=NULL,*dhp;
+#endif
+#ifndef OPENSSL_NO_ECDH
+	EC_KEY *ecdh=NULL, *ecdhp;
+	unsigned char *encodedPoint = NULL;
+	int encodedlen = 0;
+	int curve_id = 0;
+	BN_CTX *bn_ctx = NULL; 
+#endif
+	EVP_PKEY *pkey;
+	unsigned char *p,*d;
+	int al,i;
+	unsigned long type;
+	int n;
+	CERT *cert;
+	BIGNUM *r[4];
+	int nr[4],kn;
+	BUF_MEM *buf;
+	EVP_MD_CTX md_ctx;
+
+	EVP_MD_CTX_init(&md_ctx);
+	if (s->state == SSL3_ST_SW_KEY_EXCH_A)
+		{
+		type=s->s3->tmp.new_cipher->algorithm_mkey;
+		cert=s->cert;
+
+		buf=s->init_buf;
+
+		r[0]=r[1]=r[2]=r[3]=NULL;
+		n=0;
+#ifndef OPENSSL_NO_RSA
+		if (type & SSL_kRSA)
+			{
+			rsa=cert->rsa_tmp;
+			if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL))
+				{
+				rsa=s->cert->rsa_tmp_cb(s,
+				      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
+				      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
+				if(rsa == NULL)
+				{
+					al=SSL_AD_HANDSHAKE_FAILURE;
+					SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_ERROR_GENERATING_TMP_RSA_KEY);
+					goto f_err;
+				}
+				RSA_up_ref(rsa);
+				cert->rsa_tmp=rsa;
+				}
+			if (rsa == NULL)
+				{
+				al=SSL_AD_HANDSHAKE_FAILURE;
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_KEY);
+				goto f_err;
+				}
+			r[0]=rsa->n;
+			r[1]=rsa->e;
+			s->s3->tmp.use_rsa_tmp=1;
+			}
+		else
+#endif
+#ifndef OPENSSL_NO_DH
+			if (type & SSL_kEDH)
+			{
+			dhp=cert->dh_tmp;
+			if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL))
+				dhp=s->cert->dh_tmp_cb(s,
+				      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
+				      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
+			if (dhp == NULL)
+				{
+				al=SSL_AD_HANDSHAKE_FAILURE;
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);
+				goto f_err;
+				}
+
+			if (s->s3->tmp.dh != NULL)
+				{
+				DH_free(dh);
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+
+			if ((dh=DHparams_dup(dhp)) == NULL)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
+				goto err;
+				}
+
+			s->s3->tmp.dh=dh;
+			if ((dhp->pub_key == NULL ||
+			     dhp->priv_key == NULL ||
+			     (s->options & SSL_OP_SINGLE_DH_USE)))
+				{
+				if(!DH_generate_key(dh))
+				    {
+				    SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
+					   ERR_R_DH_LIB);
+				    goto err;
+				    }
+				}
+			else
+				{
+				dh->pub_key=BN_dup(dhp->pub_key);
+				dh->priv_key=BN_dup(dhp->priv_key);
+				if ((dh->pub_key == NULL) ||
+					(dh->priv_key == NULL))
+					{
+					SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
+					goto err;
+					}
+				}
+			r[0]=dh->p;
+			r[1]=dh->g;
+			r[2]=dh->pub_key;
+			}
+		else 
+#endif
+#ifndef OPENSSL_NO_ECDH
+			if (type & SSL_kEECDH)
+			{
+			const EC_GROUP *group;
+
+			ecdhp=cert->ecdh_tmp;
+			if ((ecdhp == NULL) && (s->cert->ecdh_tmp_cb != NULL))
+				{
+				ecdhp=s->cert->ecdh_tmp_cb(s,
+				      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
+				      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
+				}
+			if (ecdhp == NULL)
+				{
+				al=SSL_AD_HANDSHAKE_FAILURE;
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY);
+				goto f_err;
+				}
+
+			if (s->s3->tmp.ecdh != NULL)
+				{
+				EC_KEY_free(s->s3->tmp.ecdh); 
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+
+			/* Duplicate the ECDH structure. */
+			if (ecdhp == NULL)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
+				goto err;
+				}
+			if ((ecdh = EC_KEY_dup(ecdhp)) == NULL)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
+				goto err;
+				}
+
+			s->s3->tmp.ecdh=ecdh;
+			if ((EC_KEY_get0_public_key(ecdh) == NULL) ||
+			    (EC_KEY_get0_private_key(ecdh) == NULL) ||
+			    (s->options & SSL_OP_SINGLE_ECDH_USE))
+				{
+				if(!EC_KEY_generate_key(ecdh))
+				    {
+				    SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
+				    goto err;
+				    }
+				}
+
+			if (((group = EC_KEY_get0_group(ecdh)) == NULL) ||
+			    (EC_KEY_get0_public_key(ecdh)  == NULL) ||
+			    (EC_KEY_get0_private_key(ecdh) == NULL))
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
+				goto err;
+				}
+
+			if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
+			    (EC_GROUP_get_degree(group) > 163)) 
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER);
+				goto err;
+				}
+
+			/* XXX: For now, we only support ephemeral ECDH
+			 * keys over named (not generic) curves. For 
+			 * supported named curves, curve_id is non-zero.
+			 */
+			if ((curve_id = 
+			    tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group)))
+			    == 0)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
+				goto err;
+				}
+
+			/* Encode the public key.
+			 * First check the size of encoding and
+			 * allocate memory accordingly.
+			 */
+			encodedlen = EC_POINT_point2oct(group, 
+			    EC_KEY_get0_public_key(ecdh),
+			    POINT_CONVERSION_UNCOMPRESSED, 
+			    NULL, 0, NULL);
+
+			encodedPoint = (unsigned char *) 
+			    OPENSSL_malloc(encodedlen*sizeof(unsigned char)); 
+			bn_ctx = BN_CTX_new();
+			if ((encodedPoint == NULL) || (bn_ctx == NULL))
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+
+
+			encodedlen = EC_POINT_point2oct(group, 
+			    EC_KEY_get0_public_key(ecdh), 
+			    POINT_CONVERSION_UNCOMPRESSED, 
+			    encodedPoint, encodedlen, bn_ctx);
+
+			if (encodedlen == 0) 
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
+				goto err;
+				}
+
+			BN_CTX_free(bn_ctx);  bn_ctx=NULL;
+
+			/* XXX: For now, we only support named (not 
+			 * generic) curves in ECDH ephemeral key exchanges.
+			 * In this situation, we need four additional bytes
+			 * to encode the entire ServerECDHParams
+			 * structure. 
+			 */
+			n = 4 + encodedlen;
+
+			/* We'll generate the serverKeyExchange message
+			 * explicitly so we can set these to NULLs
+			 */
+			r[0]=NULL;
+			r[1]=NULL;
+			r[2]=NULL;
+			r[3]=NULL;
+			}
+		else 
+#endif /* !OPENSSL_NO_ECDH */
+#ifndef OPENSSL_NO_PSK
+			if (type & SSL_kPSK)
+				{
+				/* reserve size for record length and PSK identity hint*/
+				n+=2+strlen(s->ctx->psk_identity_hint);
+				}
+			else
+#endif /* !OPENSSL_NO_PSK */
+			{
+			al=SSL_AD_HANDSHAKE_FAILURE;
+			SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
+			goto f_err;
+			}
+		for (i=0; r[i] != NULL; i++)
+			{
+			nr[i]=BN_num_bytes(r[i]);
+			n+=2+nr[i];
+			}
+
+		if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
+			&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
+			{
+			if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher))
+				== NULL)
+				{
+				al=SSL_AD_DECODE_ERROR;
+				goto f_err;
+				}
+			kn=EVP_PKEY_size(pkey);
+			}
+		else
+			{
+			pkey=NULL;
+			kn=0;
+			}
+
+		if (!BUF_MEM_grow_clean(buf,n+DTLS1_HM_HEADER_LENGTH+kn))
+			{
+			SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF);
+			goto err;
+			}
+		d=(unsigned char *)s->init_buf->data;
+		p= &(d[DTLS1_HM_HEADER_LENGTH]);
+
+		for (i=0; r[i] != NULL; i++)
+			{
+			s2n(nr[i],p);
+			BN_bn2bin(r[i],p);
+			p+=nr[i];
+			}
+
+#ifndef OPENSSL_NO_ECDH
+		if (type & SSL_kEECDH) 
+			{
+			/* XXX: For now, we only support named (not generic) curves.
+			 * In this situation, the serverKeyExchange message has:
+			 * [1 byte CurveType], [2 byte CurveName]
+			 * [1 byte length of encoded point], followed by
+			 * the actual encoded point itself
+			 */
+			*p = NAMED_CURVE_TYPE;
+			p += 1;
+			*p = 0;
+			p += 1;
+			*p = curve_id;
+			p += 1;
+			*p = encodedlen;
+			p += 1;
+			memcpy((unsigned char*)p, 
+			    (unsigned char *)encodedPoint, 
+			    encodedlen);
+			OPENSSL_free(encodedPoint);
+			p += encodedlen;
+			}
+#endif
+
+#ifndef OPENSSL_NO_PSK
+		if (type & SSL_kPSK)
+			{
+			/* copy PSK identity hint */
+			s2n(strlen(s->ctx->psk_identity_hint), p); 
+			strncpy((char *)p, s->ctx->psk_identity_hint, strlen(s->ctx->psk_identity_hint));
+			p+=strlen(s->ctx->psk_identity_hint);
+			}
+#endif
+
+		/* not anonymous */
+		if (pkey != NULL)
+			{
+			/* n is the length of the params, they start at
+			 * &(d[DTLS1_HM_HEADER_LENGTH]) and p points to the space
+			 * at the end. */
+#ifndef OPENSSL_NO_RSA
+			if (pkey->type == EVP_PKEY_RSA)
+				{
+				q=md_buf;
+				j=0;
+				for (num=2; num > 0; num--)
+					{
+					EVP_DigestInit_ex(&md_ctx,(num == 2)
+						?s->ctx->md5:s->ctx->sha1, NULL);
+					EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
+					EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
+					EVP_DigestUpdate(&md_ctx,&(d[DTLS1_HM_HEADER_LENGTH]),n);
+					EVP_DigestFinal_ex(&md_ctx,q,
+						(unsigned int *)&i);
+					q+=i;
+					j+=i;
+					}
+				if (RSA_sign(NID_md5_sha1, md_buf, j,
+					&(p[2]), &u, pkey->pkey.rsa) <= 0)
+					{
+					SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_RSA);
+					goto err;
+					}
+				s2n(u,p);
+				n+=u+2;
+				}
+			else
+#endif
+#if !defined(OPENSSL_NO_DSA)
+				if (pkey->type == EVP_PKEY_DSA)
+				{
+				/* lets do DSS */
+				EVP_SignInit_ex(&md_ctx,EVP_dss1(), NULL);
+				EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
+				EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
+				EVP_SignUpdate(&md_ctx,&(d[DTLS1_HM_HEADER_LENGTH]),n);
+				if (!EVP_SignFinal(&md_ctx,&(p[2]),
+					(unsigned int *)&i,pkey))
+					{
+					SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_DSA);
+					goto err;
+					}
+				s2n(i,p);
+				n+=i+2;
+				}
+			else
+#endif
+#if !defined(OPENSSL_NO_ECDSA)
+				if (pkey->type == EVP_PKEY_EC)
+				{
+				/* let's do ECDSA */
+				EVP_SignInit_ex(&md_ctx,EVP_ecdsa(), NULL);
+				EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
+				EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
+				EVP_SignUpdate(&md_ctx,&(d[DTLS1_HM_HEADER_LENGTH]),n);
+				if (!EVP_SignFinal(&md_ctx,&(p[2]),
+					(unsigned int *)&i,pkey))
+					{
+					SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_ECDSA);
+					goto err;
+					}
+				s2n(i,p);
+				n+=i+2;
+				}
+			else
+#endif
+				{
+				/* Is this error check actually needed? */
+				al=SSL_AD_HANDSHAKE_FAILURE;
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_PKEY_TYPE);
+				goto f_err;
+				}
+			}
+
+		d = dtls1_set_message_header(s, d,
+			SSL3_MT_SERVER_KEY_EXCHANGE, n, 0, n);
+
+		/* we should now have things packed up, so lets send
+		 * it off */
+		s->init_num=n+DTLS1_HM_HEADER_LENGTH;
+		s->init_off=0;
+
+		/* buffer the message to handle re-xmits */
+		dtls1_buffer_message(s, 0);
+		}
+
+	s->state = SSL3_ST_SW_KEY_EXCH_B;
+	EVP_MD_CTX_cleanup(&md_ctx);
+	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
+f_err:
+	ssl3_send_alert(s,SSL3_AL_FATAL,al);
+err:
+#ifndef OPENSSL_NO_ECDH
+	if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
+	BN_CTX_free(bn_ctx);
+#endif
+	EVP_MD_CTX_cleanup(&md_ctx);
+	return(-1);
+	}
+
+int dtls1_send_certificate_request(SSL *s)
+	{
+	unsigned char *p,*d;
+	int i,j,nl,off,n;
+	STACK_OF(X509_NAME) *sk=NULL;
+	X509_NAME *name;
+	BUF_MEM *buf;
+	unsigned int msg_len;
+
+	if (s->state == SSL3_ST_SW_CERT_REQ_A)
+		{
+		buf=s->init_buf;
+
+		d=p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]);
+
+		/* get the list of acceptable cert types */
+		p++;
+		n=ssl3_get_req_cert_type(s,p);
+		d[0]=n;
+		p+=n;
+		n++;
+
+		off=n;
+		p+=2;
+		n+=2;
+
+		sk=SSL_get_client_CA_list(s);
+		nl=0;
+		if (sk != NULL)
+			{
+			for (i=0; i<sk_X509_NAME_num(sk); i++)
+				{
+				name=sk_X509_NAME_value(sk,i);
+				j=i2d_X509_NAME(name,NULL);
+				if (!BUF_MEM_grow_clean(buf,DTLS1_HM_HEADER_LENGTH+n+j+2))
+					{
+					SSLerr(SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB);
+					goto err;
+					}
+				p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH+n]);
+				if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG))
+					{
+					s2n(j,p);
+					i2d_X509_NAME(name,&p);
+					n+=2+j;
+					nl+=2+j;
+					}
+				else
+					{
+					d=p;
+					i2d_X509_NAME(name,&p);
+					j-=2; s2n(j,d); j+=2;
+					n+=j;
+					nl+=j;
+					}
+				}
+			}
+		/* else no CA names */
+		p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH+off]);
+		s2n(nl,p);
+
+		d=(unsigned char *)buf->data;
+		*(d++)=SSL3_MT_CERTIFICATE_REQUEST;
+		l2n3(n,d);
+		s2n(s->d1->handshake_write_seq,d);
+		s->d1->handshake_write_seq++;
+
+		/* we should now have things packed up, so lets send
+		 * it off */
+
+		s->init_num=n+DTLS1_HM_HEADER_LENGTH;
+		s->init_off=0;
+#ifdef NETSCAPE_HANG_BUG
+/* XXX: what to do about this? */
+		p=(unsigned char *)s->init_buf->data + s->init_num;
+
+		/* do the header */
+		*(p++)=SSL3_MT_SERVER_DONE;
+		*(p++)=0;
+		*(p++)=0;
+		*(p++)=0;
+		s->init_num += 4;
+#endif
+
+		/* XDTLS:  set message header ? */
+		msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH;
+		dtls1_set_message_header(s, (void *)s->init_buf->data,
+			SSL3_MT_CERTIFICATE_REQUEST, msg_len, 0, msg_len);
+
+		/* buffer the message to handle re-xmits */
+		dtls1_buffer_message(s, 0);
+
+		s->state = SSL3_ST_SW_CERT_REQ_B;
+		}
+
+	/* SSL3_ST_SW_CERT_REQ_B */
+	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
+err:
+	return(-1);
+	}
+
+int dtls1_send_server_certificate(SSL *s)
+	{
+	unsigned long l;
+	X509 *x;
+
+	if (s->state == SSL3_ST_SW_CERT_A)
+		{
+		x=ssl_get_server_send_cert(s);
+		if (x == NULL)
+			{
+			/* VRS: allow null cert if auth == KRB5 */
+			if ((s->s3->tmp.new_cipher->algorithm_mkey != SSL_kKRB5) ||
+			    (s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5))
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
+				return(0);
+				}
+			}
+
+		l=dtls1_output_cert_chain(s,x);
+		s->state=SSL3_ST_SW_CERT_B;
+		s->init_num=(int)l;
+		s->init_off=0;
+
+		/* buffer the message to handle re-xmits */
+		dtls1_buffer_message(s, 0);
+		}
+
+	/* SSL3_ST_SW_CERT_B */
+	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
+	}
+
+#ifndef OPENSSL_NO_TLSEXT
+int dtls1_send_newsession_ticket(SSL *s)
+	{
+	if (s->state == SSL3_ST_SW_SESSION_TICKET_A)
+		{
+		unsigned char *p, *senc, *macstart;
+		int len, slen;
+		unsigned int hlen, msg_len;
+		EVP_CIPHER_CTX ctx;
+		HMAC_CTX hctx;
+		SSL_CTX *tctx = s->initial_ctx;
+		unsigned char iv[EVP_MAX_IV_LENGTH];
+		unsigned char key_name[16];
+
+		/* get session encoding length */
+		slen = i2d_SSL_SESSION(s->session, NULL);
+		/* Some length values are 16 bits, so forget it if session is
+ 		 * too long
+ 		 */
+		if (slen > 0xFF00)
+			return -1;
+		/* Grow buffer if need be: the length calculation is as
+ 		 * follows 12 (DTLS handshake message header) +
+ 		 * 4 (ticket lifetime hint) + 2 (ticket length) +
+ 		 * 16 (key name) + max_iv_len (iv length) +
+ 		 * session_length + max_enc_block_size (max encrypted session
+ 		 * length) + max_md_size (HMAC).
+ 		 */
+		if (!BUF_MEM_grow(s->init_buf,
+			DTLS1_HM_HEADER_LENGTH + 22 + EVP_MAX_IV_LENGTH +
+			EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen))
+			return -1;
+		senc = OPENSSL_malloc(slen);
+		if (!senc)
+			return -1;
+		p = senc;
+		i2d_SSL_SESSION(s->session, &p);
+
+		p=(unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]);
+		EVP_CIPHER_CTX_init(&ctx);
+		HMAC_CTX_init(&hctx);
+		/* Initialize HMAC and cipher contexts. If callback present
+		 * it does all the work otherwise use generated values
+		 * from parent ctx.
+		 */
+		if (tctx->tlsext_ticket_key_cb)
+			{
+			if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
+							 &hctx, 1) < 0)
+				{
+				OPENSSL_free(senc);
+				return -1;
+				}
+			}
+		else
+			{
+			RAND_pseudo_bytes(iv, 16);
+			EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
+					tctx->tlsext_tick_aes_key, iv);
+			HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
+					tlsext_tick_md(), NULL);
+			memcpy(key_name, tctx->tlsext_tick_key_name, 16);
+			}
+		l2n(s->session->tlsext_tick_lifetime_hint, p);
+		/* Skip ticket length for now */
+		p += 2;
+		/* Output key name */
+		macstart = p;
+		memcpy(p, key_name, 16);
+		p += 16;
+		/* output IV */
+		memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx));
+		p += EVP_CIPHER_CTX_iv_length(&ctx);
+		/* Encrypt session data */
+		EVP_EncryptUpdate(&ctx, p, &len, senc, slen);
+		p += len;
+		EVP_EncryptFinal(&ctx, p, &len);
+		p += len;
+		EVP_CIPHER_CTX_cleanup(&ctx);
+
+		HMAC_Update(&hctx, macstart, p - macstart);
+		HMAC_Final(&hctx, p, &hlen);
+		HMAC_CTX_cleanup(&hctx);
+
+		p += hlen;
+		/* Now write out lengths: p points to end of data written */
+		/* Total length */
+		len = p - (unsigned char *)(s->init_buf->data);
+		/* Ticket length */
+		p=(unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]) + 4;
+		s2n(len - DTLS1_HM_HEADER_LENGTH - 6, p);
+
+		/* number of bytes to write */
+		s->init_num= len;
+		s->state=SSL3_ST_SW_SESSION_TICKET_B;
+		s->init_off=0;
+		OPENSSL_free(senc);
+
+		/* XDTLS:  set message header ? */
+		msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH;
+		dtls1_set_message_header(s, (void *)s->init_buf->data,
+			SSL3_MT_NEWSESSION_TICKET, msg_len, 0, msg_len);
+
+		/* buffer the message to handle re-xmits */
+		dtls1_buffer_message(s, 0);
+		}
+
+	/* SSL3_ST_SW_SESSION_TICKET_B */
+	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
+	}
+#endif
diff --git a/openssl/ssl/dtls1.h b/openssl/ssl/dtls1.h
new file mode 100644
index 0000000..2900d1d
--- /dev/null
+++ b/openssl/ssl/dtls1.h
@@ -0,0 +1,267 @@
+/* ssl/dtls1.h */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_DTLS1_H 
+#define HEADER_DTLS1_H 
+
+#include <openssl/buffer.h>
+#include <openssl/pqueue.h>
+#ifdef OPENSSL_SYS_VMS
+#include <resource.h>
+#include <sys/timeb.h>
+#endif
+#ifdef OPENSSL_SYS_WIN32
+/* Needed for struct timeval */
+#include <winsock.h>
+#elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_)
+#include <sys/timeval.h>
+#else
+#include <sys/time.h>
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define DTLS1_VERSION			0xFEFF
+#define DTLS1_BAD_VER			0x0100
+
+#if 0
+/* this alert description is not specified anywhere... */
+#define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE    110
+#endif
+
+/* lengths of messages */
+#define DTLS1_COOKIE_LENGTH                     256
+
+#define DTLS1_RT_HEADER_LENGTH                  13
+
+#define DTLS1_HM_HEADER_LENGTH                  12
+
+#define DTLS1_HM_BAD_FRAGMENT                   -2
+#define DTLS1_HM_FRAGMENT_RETRY                 -3
+
+#define DTLS1_CCS_HEADER_LENGTH                  1
+
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+#define DTLS1_AL_HEADER_LENGTH                   7
+#else
+#define DTLS1_AL_HEADER_LENGTH                   2
+#endif
+
+
+typedef struct dtls1_bitmap_st
+	{
+	unsigned long map;		/* track 32 packets on 32-bit systems
+					   and 64 - on 64-bit systems */
+	unsigned char max_seq_num[8];	/* max record number seen so far,
+					   64-bit value in big-endian
+					   encoding */
+	} DTLS1_BITMAP;
+
+struct dtls1_retransmit_state
+	{
+	EVP_CIPHER_CTX *enc_write_ctx;	/* cryptographic state */
+	EVP_MD_CTX *write_hash;			/* used for mac generation */
+#ifndef OPENSSL_NO_COMP
+	COMP_CTX *compress;				/* compression */
+#else
+	char *compress;	
+#endif
+	SSL_SESSION *session;
+	unsigned short epoch;
+	};
+
+struct hm_header_st
+	{
+	unsigned char type;
+	unsigned long msg_len;
+	unsigned short seq;
+	unsigned long frag_off;
+	unsigned long frag_len;
+	unsigned int is_ccs;
+	struct dtls1_retransmit_state saved_retransmit_state;
+	};
+
+struct ccs_header_st
+	{
+	unsigned char type;
+	unsigned short seq;
+	};
+
+struct dtls1_timeout_st
+	{
+	/* Number of read timeouts so far */
+	unsigned int read_timeouts;
+	
+	/* Number of write timeouts so far */
+	unsigned int write_timeouts;
+	
+	/* Number of alerts received so far */
+	unsigned int num_alerts;
+	};
+
+typedef struct record_pqueue_st
+	{
+	unsigned short epoch;
+	pqueue q;
+	} record_pqueue;
+
+typedef struct hm_fragment_st
+	{
+	struct hm_header_st msg_header;
+	unsigned char *fragment;
+	unsigned char *reassembly;
+	} hm_fragment;
+
+typedef struct dtls1_state_st
+	{
+	unsigned int send_cookie;
+	unsigned char cookie[DTLS1_COOKIE_LENGTH];
+	unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH];
+	unsigned int cookie_len;
+
+	/* 
+	 * The current data and handshake epoch.  This is initially
+	 * undefined, and starts at zero once the initial handshake is
+	 * completed 
+	 */
+	unsigned short r_epoch;
+	unsigned short w_epoch;
+
+	/* records being received in the current epoch */
+	DTLS1_BITMAP bitmap;
+
+	/* renegotiation starts a new set of sequence numbers */
+	DTLS1_BITMAP next_bitmap;
+
+	/* handshake message numbers */
+	unsigned short handshake_write_seq;
+	unsigned short next_handshake_write_seq;
+
+	unsigned short handshake_read_seq;
+
+	/* save last sequence number for retransmissions */
+	unsigned char last_write_sequence[8];
+
+	/* Received handshake records (processed and unprocessed) */
+	record_pqueue unprocessed_rcds;
+	record_pqueue processed_rcds;
+
+	/* Buffered handshake messages */
+	pqueue buffered_messages;
+
+	/* Buffered (sent) handshake records */
+	pqueue sent_messages;
+
+	/* Buffered application records.
+	 * Only for records between CCS and Finished
+	 * to prevent either protocol violation or
+	 * unnecessary message loss.
+	 */
+	record_pqueue buffered_app_data;
+
+	/* Is set when listening for new connections with dtls1_listen() */
+	unsigned int listen;
+
+	unsigned int mtu; /* max DTLS packet size */
+
+	struct hm_header_st w_msg_hdr;
+	struct hm_header_st r_msg_hdr;
+
+	struct dtls1_timeout_st timeout;
+
+	/* Indicates when the last handshake msg sent will timeout */
+	struct timeval next_timeout;
+
+	/* Timeout duration */
+	unsigned short timeout_duration;
+
+	/* storage for Alert/Handshake protocol data received but not
+	 * yet processed by ssl3_read_bytes: */
+	unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH];
+	unsigned int alert_fragment_len;
+	unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH];
+	unsigned int handshake_fragment_len;
+
+	unsigned int retransmitting;
+	unsigned int change_cipher_spec_ok;
+
+	} DTLS1_STATE;
+
+typedef struct dtls1_record_data_st
+	{
+	unsigned char *packet;
+	unsigned int   packet_length;
+	SSL3_BUFFER    rbuf;
+	SSL3_RECORD    rrec;
+	} DTLS1_RECORD_DATA;
+
+
+/* Timeout multipliers (timeout slice is defined in apps/timeouts.h */
+#define DTLS1_TMO_READ_COUNT                      2
+#define DTLS1_TMO_WRITE_COUNT                     2
+
+#define DTLS1_TMO_ALERT_COUNT                     12
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/openssl/ssl/install-ssl.com b/openssl/ssl/install-ssl.com
new file mode 100644
index 0000000..1bd6cca
--- /dev/null
+++ b/openssl/ssl/install-ssl.com
@@ -0,0 +1,136 @@
+$! INSTALL-SSL.COM -- Installs the files in a given directory tree
+$!
+$! Author: Richard Levitte <richard@levitte.org>
+$! Time of creation: 22-MAY-1998 10:13
+$!
+$! P1  root of the directory tree
+$! P2  "64" for 64-bit pointers.
+$!
+$!
+$! Announce/identify.
+$!
+$ proc = f$environment( "procedure")
+$ write sys$output "@@@ "+ -
+   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
+$!
+$ on error then goto tidy
+$ on control_c then goto tidy
+$!
+$ if p1 .eqs. ""
+$ then
+$   write sys$output "First argument missing."
+$   write sys$output -
+     "It should be the directory where you want things installed."
+$   exit
+$ endif
+$!
+$ if (f$getsyi( "cpu") .lt. 128)
+$ then
+$     arch = "VAX"
+$ else
+$     arch = f$edit( f$getsyi( "arch_name"), "upcase")
+$     if (arch .eqs. "") then arch = "UNK"
+$ endif
+$!
+$ archd = arch
+$ lib32 = "32"
+$ shr = "_SHR32"
+$!
+$ if (p2 .nes. "")
+$ then
+$   if (p2 .eqs. "64")
+$   then
+$     archd = arch+ "_64"
+$     lib32 = ""
+$     shr = "_SHR"
+$   else
+$     if (p2 .nes. "32")
+$     then
+$       write sys$output "Second argument invalid."
+$       write sys$output "It should be "32", "64", or nothing."
+$       exit
+$     endif
+$   endif
+$ endif
+$!
+$ root = f$parse( p1, "[]A.;0", , , "syntax_only, no_conceal") - "A.;0"
+$ root_dev = f$parse(root,,,"device","syntax_only")
+$ root_dir = f$parse(root,,,"directory","syntax_only") - -
+   "[000000." - "][" - "[" - "]"
+$ root = root_dev + "[" + root_dir
+$!
+$ define /nolog wrk_sslroot 'root'.] /trans=conc
+$ define /nolog wrk_sslinclude wrk_sslroot:[include]
+$ define /nolog wrk_sslxexe wrk_sslroot:['archd'_exe]
+$ define /nolog wrk_sslxlib wrk_sslroot:['arch'_lib]
+$!
+$ if f$parse("wrk_sslroot:[000000]") .eqs. "" then -
+   create /directory /log wrk_sslroot:[000000]
+$ if f$parse("wrk_sslinclude:") .eqs. "" then -
+   create /directory /log wrk_sslinclude:
+$ if f$parse("wrk_sslxexe:") .eqs. "" then -
+   create /directory /log wrk_sslxexe:
+$ if f$parse("wrk_sslxlib:") .eqs. "" then -
+   create /directory /log wrk_sslxlib:
+$!
+$ exheader := ssl.h, ssl2.h, ssl3.h, ssl23.h, tls1.h, dtls1.h, kssl.h
+$ e_exe := ssl_task
+$ libs := ssl_libssl
+$!
+$ xexe_dir := [-.'archd'.exe.ssl]
+$!
+$ copy /protection = w:re 'exheader' wrk_sslinclude: /log
+$!
+$ i = 0
+$ loop_exe:
+$   e = f$edit( f$element( i, ",", e_exe), "trim")
+$   i = i + 1
+$   if e .eqs. "," then goto loop_exe_end
+$   set noon
+$   file = xexe_dir+ e+ ".exe"
+$   if f$search( file) .nes. ""
+$   then
+$     copy /protection = w:re 'file' wrk_sslxexe: /log
+$   endif
+$   set on
+$ goto loop_exe
+$ loop_exe_end:
+$!
+$ i = 0
+$ loop_lib: 
+$   e = f$edit(f$element(i, ",", libs),"trim")
+$   i = i + 1
+$   if e .eqs. "," then goto loop_lib_end
+$   set noon
+$! Object library.
+$   file = xexe_dir+ e+ lib32+ ".olb"
+$   if f$search( file) .nes. ""
+$   then
+$     copy /protection = w:re 'file' wrk_sslxlib: /log
+$   endif
+$! Shareable image.
+$   file = xexe_dir+ e+ shr+ ".exe"
+$   if f$search( file) .nes. ""
+$   then
+$     copy /protection = w:re 'file' wrk_sslxlib: /log
+$   endif
+$   set on
+$ goto loop_lib
+$ loop_lib_end:
+$!
+$ tidy:
+$!
+$ call deass wrk_sslroot
+$ call deass wrk_sslinclude
+$ call deass wrk_sslxexe
+$ call deass wrk_sslxlib
+$!
+$ exit
+$!
+$ deass: subroutine
+$ if (f$trnlnm( p1, "LNM$PROCESS") .nes. "")
+$ then
+$   deassign /process 'p1'
+$ endif
+$ endsubroutine
+$!
diff --git a/openssl/ssl/kssl.c b/openssl/ssl/kssl.c
new file mode 100644
index 0000000..b820e37
--- /dev/null
+++ b/openssl/ssl/kssl.c
@@ -0,0 +1,2205 @@
+/* ssl/kssl.c -*- mode: C; c-file-style: "eay" -*- */
+/* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+/*  ssl/kssl.c  --  Routines to support (& debug) Kerberos5 auth for openssl
+**
+**  19990701	VRS 	Started.
+**  200011??	Jeffrey Altman, Richard Levitte
+**          		Generalized for Heimdal, Newer MIT, & Win32.
+**          		Integrated into main OpenSSL 0.9.7 snapshots.
+**  20010413	Simon Wilkinson, VRS
+**          		Real RFC2712 KerberosWrapper replaces AP_REQ.
+*/
+
+#include <openssl/opensslconf.h>
+
+#include <string.h>
+
+#define KRB5_PRIVATE	1
+
+#include <openssl/ssl.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/krb5_asn.h>
+#include "kssl_lcl.h"
+
+#ifndef OPENSSL_NO_KRB5
+
+#ifndef ENOMEM
+#define ENOMEM KRB5KRB_ERR_GENERIC
+#endif
+
+/* 
+ * When OpenSSL is built on Windows, we do not want to require that
+ * the Kerberos DLLs be available in order for the OpenSSL DLLs to
+ * work.  Therefore, all Kerberos routines are loaded at run time
+ * and we do not link to a .LIB file.
+ */
+
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
+/* 
+ * The purpose of the following pre-processor statements is to provide
+ * compatibility with different releases of MIT Kerberos for Windows.
+ * All versions up to 1.2 used macros.  But macros do not allow for
+ * a binary compatible interface for DLLs.  Therefore, all macros are
+ * being replaced by function calls.  The following code will allow
+ * an OpenSSL DLL built on Windows to work whether or not the macro
+ * or function form of the routines are utilized.
+ */
+#ifdef  krb5_cc_get_principal
+#define NO_DEF_KRB5_CCACHE
+#undef  krb5_cc_get_principal
+#endif
+#define krb5_cc_get_principal    kssl_krb5_cc_get_principal
+
+#define krb5_free_data_contents  kssl_krb5_free_data_contents   
+#define krb5_free_context        kssl_krb5_free_context         
+#define krb5_auth_con_free       kssl_krb5_auth_con_free        
+#define krb5_free_principal      kssl_krb5_free_principal       
+#define krb5_mk_req_extended     kssl_krb5_mk_req_extended      
+#define krb5_get_credentials     kssl_krb5_get_credentials      
+#define krb5_cc_default          kssl_krb5_cc_default           
+#define krb5_sname_to_principal  kssl_krb5_sname_to_principal   
+#define krb5_init_context        kssl_krb5_init_context         
+#define krb5_free_ticket         kssl_krb5_free_ticket          
+#define krb5_rd_req              kssl_krb5_rd_req               
+#define krb5_kt_default          kssl_krb5_kt_default           
+#define krb5_kt_resolve          kssl_krb5_kt_resolve           
+/* macros in mit 1.2.2 and earlier; functions in mit 1.2.3 and greater */
+#ifndef krb5_kt_close
+#define krb5_kt_close            kssl_krb5_kt_close
+#endif /* krb5_kt_close */
+#ifndef krb5_kt_get_entry
+#define krb5_kt_get_entry        kssl_krb5_kt_get_entry
+#endif /* krb5_kt_get_entry */
+#define krb5_auth_con_init       kssl_krb5_auth_con_init        
+
+#define krb5_principal_compare   kssl_krb5_principal_compare
+#define krb5_decrypt_tkt_part    kssl_krb5_decrypt_tkt_part
+#define krb5_timeofday           kssl_krb5_timeofday
+#define krb5_rc_default          kssl_krb5_rc_default
+
+#ifdef krb5_rc_initialize
+#undef krb5_rc_initialize
+#endif
+#define krb5_rc_initialize   kssl_krb5_rc_initialize
+
+#ifdef krb5_rc_get_lifespan
+#undef krb5_rc_get_lifespan
+#endif
+#define krb5_rc_get_lifespan kssl_krb5_rc_get_lifespan
+
+#ifdef krb5_rc_destroy
+#undef krb5_rc_destroy
+#endif
+#define krb5_rc_destroy      kssl_krb5_rc_destroy
+
+#define valid_cksumtype      kssl_valid_cksumtype
+#define krb5_checksum_size   kssl_krb5_checksum_size
+#define krb5_kt_free_entry   kssl_krb5_kt_free_entry
+#define krb5_auth_con_setrcache  kssl_krb5_auth_con_setrcache
+#define krb5_auth_con_getrcache  kssl_krb5_auth_con_getrcache
+#define krb5_get_server_rcache   kssl_krb5_get_server_rcache
+
+/* Prototypes for built in stubs */
+void kssl_krb5_free_data_contents(krb5_context, krb5_data *);
+void kssl_krb5_free_principal(krb5_context, krb5_principal );
+krb5_error_code kssl_krb5_kt_resolve(krb5_context,
+                                     krb5_const char *,
+                                     krb5_keytab *);
+krb5_error_code kssl_krb5_kt_default(krb5_context,
+                                     krb5_keytab *);
+krb5_error_code kssl_krb5_free_ticket(krb5_context, krb5_ticket *);
+krb5_error_code kssl_krb5_rd_req(krb5_context, krb5_auth_context *, 
+                                 krb5_const krb5_data *,
+                                 krb5_const_principal, krb5_keytab, 
+                                 krb5_flags *,krb5_ticket **);
+
+krb5_boolean kssl_krb5_principal_compare(krb5_context, krb5_const_principal,
+                                         krb5_const_principal);
+krb5_error_code kssl_krb5_mk_req_extended(krb5_context,
+                                          krb5_auth_context  *,
+                                          krb5_const krb5_flags,
+                                          krb5_data  *,
+                                          krb5_creds  *,
+                                          krb5_data  * );
+krb5_error_code kssl_krb5_init_context(krb5_context *);
+void kssl_krb5_free_context(krb5_context);
+krb5_error_code kssl_krb5_cc_default(krb5_context,krb5_ccache  *);
+krb5_error_code kssl_krb5_sname_to_principal(krb5_context,
+                                             krb5_const char  *,
+                                             krb5_const char  *,
+                                             krb5_int32,
+                                             krb5_principal  *);
+krb5_error_code kssl_krb5_get_credentials(krb5_context,
+                                          krb5_const krb5_flags,
+                                          krb5_ccache,
+                                          krb5_creds  *,
+                                          krb5_creds  *  *);
+krb5_error_code kssl_krb5_auth_con_init(krb5_context,
+                                        krb5_auth_context  *);
+krb5_error_code kssl_krb5_cc_get_principal(krb5_context context, 
+                                           krb5_ccache cache,
+                                           krb5_principal *principal);
+krb5_error_code kssl_krb5_auth_con_free(krb5_context,krb5_auth_context);
+size_t kssl_krb5_checksum_size(krb5_context context,krb5_cksumtype ctype);
+krb5_boolean kssl_valid_cksumtype(krb5_cksumtype ctype);
+krb5_error_code krb5_kt_free_entry(krb5_context,krb5_keytab_entry FAR * );
+krb5_error_code kssl_krb5_auth_con_setrcache(krb5_context, 
+                                             krb5_auth_context, 
+                                             krb5_rcache);
+krb5_error_code kssl_krb5_get_server_rcache(krb5_context, 
+                                            krb5_const krb5_data *,
+                                            krb5_rcache *);
+krb5_error_code kssl_krb5_auth_con_getrcache(krb5_context, 
+                                             krb5_auth_context,
+                                             krb5_rcache *);
+
+/* Function pointers (almost all Kerberos functions are _stdcall) */
+static void (_stdcall *p_krb5_free_data_contents)(krb5_context, krb5_data *)
+	=NULL;
+static void (_stdcall *p_krb5_free_principal)(krb5_context, krb5_principal )
+	=NULL;
+static krb5_error_code(_stdcall *p_krb5_kt_resolve)
+			(krb5_context, krb5_const char *, krb5_keytab *)=NULL;
+static krb5_error_code (_stdcall *p_krb5_kt_default)(krb5_context,
+                                                     krb5_keytab *)=NULL;
+static krb5_error_code (_stdcall *p_krb5_free_ticket)(krb5_context, 
+                                                      krb5_ticket *)=NULL;
+static krb5_error_code (_stdcall *p_krb5_rd_req)(krb5_context, 
+                                                 krb5_auth_context *, 
+                                                 krb5_const krb5_data *,
+                                                 krb5_const_principal, 
+                                                 krb5_keytab, krb5_flags *,
+                                                 krb5_ticket **)=NULL;
+static krb5_error_code (_stdcall *p_krb5_mk_req_extended)
+			(krb5_context, krb5_auth_context *,
+			 krb5_const krb5_flags, krb5_data *, krb5_creds *,
+			 krb5_data * )=NULL;
+static krb5_error_code (_stdcall *p_krb5_init_context)(krb5_context *)=NULL;
+static void (_stdcall *p_krb5_free_context)(krb5_context)=NULL;
+static krb5_error_code (_stdcall *p_krb5_cc_default)(krb5_context,
+                                                     krb5_ccache  *)=NULL;
+static krb5_error_code (_stdcall *p_krb5_sname_to_principal)
+			(krb5_context, krb5_const char *, krb5_const char *,
+			 krb5_int32, krb5_principal *)=NULL;
+static krb5_error_code (_stdcall *p_krb5_get_credentials)
+			(krb5_context, krb5_const krb5_flags, krb5_ccache,
+			 krb5_creds *, krb5_creds **)=NULL;
+static krb5_error_code (_stdcall *p_krb5_auth_con_init)
+			(krb5_context, krb5_auth_context *)=NULL;
+static krb5_error_code (_stdcall *p_krb5_cc_get_principal)
+			(krb5_context context, krb5_ccache cache,
+			 krb5_principal *principal)=NULL;
+static krb5_error_code (_stdcall *p_krb5_auth_con_free)
+			(krb5_context, krb5_auth_context)=NULL;
+static krb5_error_code (_stdcall *p_krb5_decrypt_tkt_part)
+                        (krb5_context, krb5_const krb5_keyblock *,
+                                           krb5_ticket *)=NULL;
+static krb5_error_code (_stdcall *p_krb5_timeofday)
+                        (krb5_context context, krb5_int32 *timeret)=NULL;
+static krb5_error_code (_stdcall *p_krb5_rc_default)
+                        (krb5_context context, krb5_rcache *rc)=NULL;
+static krb5_error_code (_stdcall *p_krb5_rc_initialize)
+                        (krb5_context context, krb5_rcache rc,
+                                     krb5_deltat lifespan)=NULL;
+static krb5_error_code (_stdcall *p_krb5_rc_get_lifespan)
+                        (krb5_context context, krb5_rcache rc,
+                                       krb5_deltat *lifespan)=NULL;
+static krb5_error_code (_stdcall *p_krb5_rc_destroy)
+                        (krb5_context context, krb5_rcache rc)=NULL;
+static krb5_boolean (_stdcall *p_krb5_principal_compare)
+                     (krb5_context, krb5_const_principal, krb5_const_principal)=NULL;
+static size_t (_stdcall *p_krb5_checksum_size)(krb5_context context,krb5_cksumtype ctype)=NULL;
+static krb5_boolean (_stdcall *p_valid_cksumtype)(krb5_cksumtype ctype)=NULL;
+static krb5_error_code (_stdcall *p_krb5_kt_free_entry)
+                        (krb5_context,krb5_keytab_entry * )=NULL;
+static krb5_error_code (_stdcall * p_krb5_auth_con_setrcache)(krb5_context, 
+                                                               krb5_auth_context, 
+                                                               krb5_rcache)=NULL;
+static krb5_error_code (_stdcall * p_krb5_get_server_rcache)(krb5_context, 
+                                                              krb5_const krb5_data *, 
+                                                              krb5_rcache *)=NULL;
+static krb5_error_code (* p_krb5_auth_con_getrcache)(krb5_context, 
+                                                      krb5_auth_context,
+                                                      krb5_rcache *)=NULL;
+static krb5_error_code (_stdcall * p_krb5_kt_close)(krb5_context context, 
+                                                    krb5_keytab keytab)=NULL;
+static krb5_error_code (_stdcall * p_krb5_kt_get_entry)(krb5_context context, 
+                                                        krb5_keytab keytab,
+                       krb5_const_principal principal, krb5_kvno vno,
+                       krb5_enctype enctype, krb5_keytab_entry *entry)=NULL;
+static int krb5_loaded = 0;     /* only attempt to initialize func ptrs once */
+
+/* Function to Load the Kerberos 5 DLL and initialize function pointers */
+void
+load_krb5_dll(void)
+	{
+	HANDLE hKRB5_32;
+    
+	krb5_loaded++;
+	hKRB5_32 = LoadLibrary(TEXT("KRB5_32"));
+	if (!hKRB5_32)
+		return;
+
+	(FARPROC) p_krb5_free_data_contents =
+		GetProcAddress( hKRB5_32, "krb5_free_data_contents" );
+	(FARPROC) p_krb5_free_context =
+		GetProcAddress( hKRB5_32, "krb5_free_context" );
+	(FARPROC) p_krb5_auth_con_free =
+		GetProcAddress( hKRB5_32, "krb5_auth_con_free" );
+	(FARPROC) p_krb5_free_principal =
+		GetProcAddress( hKRB5_32, "krb5_free_principal" );
+	(FARPROC) p_krb5_mk_req_extended =
+		GetProcAddress( hKRB5_32, "krb5_mk_req_extended" );
+	(FARPROC) p_krb5_get_credentials =
+		GetProcAddress( hKRB5_32, "krb5_get_credentials" );
+	(FARPROC) p_krb5_cc_get_principal =
+		GetProcAddress( hKRB5_32, "krb5_cc_get_principal" );
+	(FARPROC) p_krb5_cc_default =
+		GetProcAddress( hKRB5_32, "krb5_cc_default" );
+	(FARPROC) p_krb5_sname_to_principal =
+		GetProcAddress( hKRB5_32, "krb5_sname_to_principal" );
+	(FARPROC) p_krb5_init_context =
+		GetProcAddress( hKRB5_32, "krb5_init_context" );
+	(FARPROC) p_krb5_free_ticket =
+		GetProcAddress( hKRB5_32, "krb5_free_ticket" );
+	(FARPROC) p_krb5_rd_req =
+		GetProcAddress( hKRB5_32, "krb5_rd_req" );
+	(FARPROC) p_krb5_principal_compare =
+		GetProcAddress( hKRB5_32, "krb5_principal_compare" );
+	(FARPROC) p_krb5_decrypt_tkt_part =
+		GetProcAddress( hKRB5_32, "krb5_decrypt_tkt_part" );
+	(FARPROC) p_krb5_timeofday =
+		GetProcAddress( hKRB5_32, "krb5_timeofday" );
+	(FARPROC) p_krb5_rc_default =
+		GetProcAddress( hKRB5_32, "krb5_rc_default" );
+	(FARPROC) p_krb5_rc_initialize =
+		GetProcAddress( hKRB5_32, "krb5_rc_initialize" );
+	(FARPROC) p_krb5_rc_get_lifespan =
+		GetProcAddress( hKRB5_32, "krb5_rc_get_lifespan" );
+	(FARPROC) p_krb5_rc_destroy =
+		GetProcAddress( hKRB5_32, "krb5_rc_destroy" );
+	(FARPROC) p_krb5_kt_default =
+		GetProcAddress( hKRB5_32, "krb5_kt_default" );
+	(FARPROC) p_krb5_kt_resolve =
+		GetProcAddress( hKRB5_32, "krb5_kt_resolve" );
+	(FARPROC) p_krb5_auth_con_init =
+		GetProcAddress( hKRB5_32, "krb5_auth_con_init" );
+        (FARPROC) p_valid_cksumtype =
+                GetProcAddress( hKRB5_32, "valid_cksumtype" );
+        (FARPROC) p_krb5_checksum_size =
+                GetProcAddress( hKRB5_32, "krb5_checksum_size" );
+        (FARPROC) p_krb5_kt_free_entry =
+                GetProcAddress( hKRB5_32, "krb5_kt_free_entry" );
+        (FARPROC) p_krb5_auth_con_setrcache =
+                GetProcAddress( hKRB5_32, "krb5_auth_con_setrcache" );
+        (FARPROC) p_krb5_get_server_rcache =
+                GetProcAddress( hKRB5_32, "krb5_get_server_rcache" );
+        (FARPROC) p_krb5_auth_con_getrcache =
+                GetProcAddress( hKRB5_32, "krb5_auth_con_getrcache" );
+        (FARPROC) p_krb5_kt_close =
+                GetProcAddress( hKRB5_32, "krb5_kt_close" );
+        (FARPROC) p_krb5_kt_get_entry =
+                GetProcAddress( hKRB5_32, "krb5_kt_get_entry" );
+	}
+
+/* Stubs for each function to be dynamicly loaded */
+void
+kssl_krb5_free_data_contents(krb5_context CO, krb5_data  * data)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_free_data_contents )
+		p_krb5_free_data_contents(CO,data);
+	}
+
+krb5_error_code
+kssl_krb5_mk_req_extended (krb5_context CO,
+                          krb5_auth_context  * pACO,
+                          krb5_const krb5_flags F,
+                          krb5_data  * pD1,
+                          krb5_creds  * pC,
+                          krb5_data  * pD2)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_mk_req_extended )
+		return(p_krb5_mk_req_extended(CO,pACO,F,pD1,pC,pD2));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+krb5_error_code
+kssl_krb5_auth_con_init(krb5_context CO,
+                       krb5_auth_context  * pACO)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_auth_con_init )
+		return(p_krb5_auth_con_init(CO,pACO));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+krb5_error_code
+kssl_krb5_auth_con_free (krb5_context CO,
+                        krb5_auth_context ACO)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_auth_con_free )
+		return(p_krb5_auth_con_free(CO,ACO));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+krb5_error_code
+kssl_krb5_get_credentials(krb5_context CO,
+                         krb5_const krb5_flags F,
+                         krb5_ccache CC,
+                         krb5_creds  * pCR,
+                         krb5_creds  ** ppCR)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_get_credentials )
+		return(p_krb5_get_credentials(CO,F,CC,pCR,ppCR));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+krb5_error_code
+kssl_krb5_sname_to_principal(krb5_context CO,
+                            krb5_const char  * pC1,
+                            krb5_const char  * pC2,
+                            krb5_int32 I,
+                            krb5_principal  * pPR)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_sname_to_principal )
+		return(p_krb5_sname_to_principal(CO,pC1,pC2,I,pPR));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+
+krb5_error_code
+kssl_krb5_cc_default(krb5_context CO,
+                    krb5_ccache  * pCC)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_cc_default )
+		return(p_krb5_cc_default(CO,pCC));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+
+krb5_error_code
+kssl_krb5_init_context(krb5_context * pCO)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_init_context )
+		return(p_krb5_init_context(pCO));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+
+void
+kssl_krb5_free_context(krb5_context CO)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_free_context )
+		p_krb5_free_context(CO);
+	}
+
+void
+kssl_krb5_free_principal(krb5_context c, krb5_principal p)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_free_principal )
+		p_krb5_free_principal(c,p);
+	}
+
+krb5_error_code
+kssl_krb5_kt_resolve(krb5_context con,
+                    krb5_const char * sz,
+                    krb5_keytab * kt)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_kt_resolve )
+		return(p_krb5_kt_resolve(con,sz,kt));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+
+krb5_error_code
+kssl_krb5_kt_default(krb5_context con,
+                    krb5_keytab * kt)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_kt_default )
+		return(p_krb5_kt_default(con,kt));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+
+krb5_error_code
+kssl_krb5_free_ticket(krb5_context con,
+                     krb5_ticket * kt)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_free_ticket )
+		return(p_krb5_free_ticket(con,kt));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+
+krb5_error_code
+kssl_krb5_rd_req(krb5_context con, krb5_auth_context * pacon,
+                krb5_const krb5_data * data,
+                krb5_const_principal princ, krb5_keytab keytab,
+                krb5_flags * flags, krb5_ticket ** pptkt)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_rd_req )
+		return(p_krb5_rd_req(con,pacon,data,princ,keytab,flags,pptkt));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+
+krb5_boolean
+krb5_principal_compare(krb5_context con, krb5_const_principal princ1,
+                krb5_const_principal princ2)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_principal_compare )
+		return(p_krb5_principal_compare(con,princ1,princ2));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+
+krb5_error_code
+krb5_decrypt_tkt_part(krb5_context con, krb5_const krb5_keyblock *keys,
+                krb5_ticket *ticket)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_decrypt_tkt_part )
+		return(p_krb5_decrypt_tkt_part(con,keys,ticket));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+
+krb5_error_code
+krb5_timeofday(krb5_context con, krb5_int32 *timeret)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_timeofday )
+		return(p_krb5_timeofday(con,timeret));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+
+krb5_error_code
+krb5_rc_default(krb5_context con, krb5_rcache *rc)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_rc_default )
+		return(p_krb5_rc_default(con,rc));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+
+krb5_error_code
+krb5_rc_initialize(krb5_context con, krb5_rcache rc, krb5_deltat lifespan)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_rc_initialize )
+		return(p_krb5_rc_initialize(con, rc, lifespan));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+
+krb5_error_code
+krb5_rc_get_lifespan(krb5_context con, krb5_rcache rc, krb5_deltat *lifespanp)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_rc_get_lifespan )
+		return(p_krb5_rc_get_lifespan(con, rc, lifespanp));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+
+krb5_error_code
+krb5_rc_destroy(krb5_context con, krb5_rcache rc)
+	{
+	if (!krb5_loaded)
+		load_krb5_dll();
+
+	if ( p_krb5_rc_destroy )
+		return(p_krb5_rc_destroy(con, rc));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+
+size_t 
+krb5_checksum_size(krb5_context context,krb5_cksumtype ctype)
+        {
+        if (!krb5_loaded)
+                load_krb5_dll();
+
+        if ( p_krb5_checksum_size )
+                return(p_krb5_checksum_size(context, ctype));
+        else
+                return KRB5KRB_ERR_GENERIC;
+        }
+
+krb5_boolean 
+valid_cksumtype(krb5_cksumtype ctype)
+        {
+        if (!krb5_loaded)
+                load_krb5_dll();
+
+        if ( p_valid_cksumtype )
+                return(p_valid_cksumtype(ctype));
+        else
+                return KRB5KRB_ERR_GENERIC;
+        }
+
+krb5_error_code 
+krb5_kt_free_entry(krb5_context con,krb5_keytab_entry * entry)
+        {
+        if (!krb5_loaded)
+                load_krb5_dll();
+
+        if ( p_krb5_kt_free_entry )
+                return(p_krb5_kt_free_entry(con,entry));
+        else
+                return KRB5KRB_ERR_GENERIC;
+        }
+                 
+/* Structure definitions  */
+#ifndef NO_DEF_KRB5_CCACHE
+#ifndef krb5_x
+#define krb5_x(ptr,args) ((ptr)?((*(ptr)) args):(abort(),1))
+#define krb5_xc(ptr,args) ((ptr)?((*(ptr)) args):(abort(),(char*)0))
+#endif 
+
+typedef	krb5_pointer	krb5_cc_cursor;	/* cursor for sequential lookup */
+
+typedef struct _krb5_ccache
+	{
+	krb5_magic magic;
+	struct _krb5_cc_ops FAR *ops;
+	krb5_pointer data;
+	} *krb5_ccache;
+
+typedef struct _krb5_cc_ops
+	{
+	krb5_magic magic;
+	char  *prefix;
+	char  * (KRB5_CALLCONV *get_name)
+		(krb5_context, krb5_ccache);
+	krb5_error_code (KRB5_CALLCONV *resolve)
+		(krb5_context, krb5_ccache  *, const char  *);
+	krb5_error_code (KRB5_CALLCONV *gen_new)
+		(krb5_context, krb5_ccache  *);
+	krb5_error_code (KRB5_CALLCONV *init)
+		(krb5_context, krb5_ccache, krb5_principal);
+	krb5_error_code (KRB5_CALLCONV *destroy)
+		(krb5_context, krb5_ccache);
+	krb5_error_code (KRB5_CALLCONV *close)
+		(krb5_context, krb5_ccache);
+	krb5_error_code (KRB5_CALLCONV *store)
+		(krb5_context, krb5_ccache, krb5_creds  *);
+	krb5_error_code (KRB5_CALLCONV *retrieve)
+		(krb5_context, krb5_ccache,
+		krb5_flags, krb5_creds  *, krb5_creds  *);
+	krb5_error_code (KRB5_CALLCONV *get_princ)
+		(krb5_context, krb5_ccache, krb5_principal  *);
+	krb5_error_code (KRB5_CALLCONV *get_first)
+		(krb5_context, krb5_ccache, krb5_cc_cursor  *);
+	krb5_error_code (KRB5_CALLCONV *get_next)
+		(krb5_context, krb5_ccache,
+		krb5_cc_cursor  *, krb5_creds  *);
+	krb5_error_code (KRB5_CALLCONV *end_get)
+		(krb5_context, krb5_ccache, krb5_cc_cursor  *);
+	krb5_error_code (KRB5_CALLCONV *remove_cred)
+		(krb5_context, krb5_ccache,
+		krb5_flags, krb5_creds  *);
+	krb5_error_code (KRB5_CALLCONV *set_flags)
+		(krb5_context, krb5_ccache, krb5_flags);
+	} krb5_cc_ops;
+#endif /* NO_DEF_KRB5_CCACHE */
+
+krb5_error_code 
+kssl_krb5_cc_get_principal
+    (krb5_context context, krb5_ccache cache,
+      krb5_principal *principal)
+	{
+	if ( p_krb5_cc_get_principal )
+		return(p_krb5_cc_get_principal(context,cache,principal));
+	else
+		return(krb5_x
+			((cache)->ops->get_princ,(context, cache, principal)));
+	}
+
+krb5_error_code
+kssl_krb5_auth_con_setrcache(krb5_context con, krb5_auth_context acon,
+                             krb5_rcache rcache)
+        {
+        if ( p_krb5_auth_con_setrcache )
+                 return(p_krb5_auth_con_setrcache(con,acon,rcache));
+        else
+                 return KRB5KRB_ERR_GENERIC;
+        }
+
+krb5_error_code
+kssl_krb5_get_server_rcache(krb5_context con, krb5_const krb5_data * data,
+                            krb5_rcache * rcache) 
+        {
+	if ( p_krb5_get_server_rcache )
+		return(p_krb5_get_server_rcache(con,data,rcache));
+	else
+		return KRB5KRB_ERR_GENERIC;
+        }
+
+krb5_error_code
+kssl_krb5_auth_con_getrcache(krb5_context con, krb5_auth_context acon,
+                             krb5_rcache * prcache)
+        {
+	if ( p_krb5_auth_con_getrcache )
+		return(p_krb5_auth_con_getrcache(con,acon, prcache));
+	else
+		return KRB5KRB_ERR_GENERIC;
+	}
+ 
+krb5_error_code
+kssl_krb5_kt_close(krb5_context context, krb5_keytab keytab)
+	{
+	if ( p_krb5_kt_close )
+		return(p_krb5_kt_close(context,keytab));
+	else 
+		return KRB5KRB_ERR_GENERIC;
+	}
+
+krb5_error_code
+kssl_krb5_kt_get_entry(krb5_context context, krb5_keytab keytab,
+                       krb5_const_principal principal, krb5_kvno vno,
+                       krb5_enctype enctype, krb5_keytab_entry *entry)
+	{
+	if ( p_krb5_kt_get_entry )
+		return(p_krb5_kt_get_entry(context,keytab,principal,vno,enctype,entry));
+	else
+		return KRB5KRB_ERR_GENERIC;
+        }
+#endif  /* OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32 */
+
+
+/* memory allocation functions for non-temporary storage
+ * (e.g. stuff that gets saved into the kssl context) */
+static void* kssl_calloc(size_t nmemb, size_t size)
+{
+	void* p;
+	
+	p=OPENSSL_malloc(nmemb*size);
+	if (p){
+		memset(p, 0, nmemb*size);
+	}
+	return p;
+}
+
+#define kssl_malloc(size) OPENSSL_malloc((size))
+#define kssl_realloc(ptr, size) OPENSSL_realloc(ptr, size)
+#define kssl_free(ptr) OPENSSL_free((ptr))
+
+
+char
+*kstring(char *string)
+        {
+        static char	*null = "[NULL]";
+
+	return ((string == NULL)? null: string);
+        }
+
+/*	Given KRB5 enctype (basically DES or 3DES),
+**	return closest match openssl EVP_ encryption algorithm.
+**	Return NULL for unknown or problematic (krb5_dk_encrypt) enctypes.
+**	Assume ENCTYPE_*_RAW (krb5_raw_encrypt) are OK.
+*/
+const EVP_CIPHER *
+kssl_map_enc(krb5_enctype enctype)
+        {
+	switch (enctype)
+		{
+	case ENCTYPE_DES_HMAC_SHA1:		/*    EVP_des_cbc();       */
+	case ENCTYPE_DES_CBC_CRC:
+	case ENCTYPE_DES_CBC_MD4:
+	case ENCTYPE_DES_CBC_MD5:
+	case ENCTYPE_DES_CBC_RAW:
+				return EVP_des_cbc();
+				break;
+	case ENCTYPE_DES3_CBC_SHA1:		/*    EVP_des_ede3_cbc();  */
+	case ENCTYPE_DES3_CBC_SHA:
+	case ENCTYPE_DES3_CBC_RAW:
+				return EVP_des_ede3_cbc();
+				break;
+	default:                return NULL;
+				break;
+		}
+	}
+
+
+/*	Return true:1 if p "looks like" the start of the real authenticator
+**	described in kssl_skip_confound() below.  The ASN.1 pattern is
+**	"62 xx 30 yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and
+**	xx and yy are possibly multi-byte length fields.
+*/
+static int 	kssl_test_confound(unsigned char *p)
+	{
+	int 	len = 2;
+	int 	xx = 0, yy = 0;
+
+	if (*p++ != 0x62)  return 0;
+	if (*p > 0x82)  return 0;
+	switch(*p)  {
+		case 0x82:  p++;          xx = (*p++ << 8);  xx += *p++;  break;
+		case 0x81:  p++;          xx =  *p++;  break;
+		case 0x80:  return 0;
+		default:    xx = *p++;  break;
+		}
+	if (*p++ != 0x30)  return 0;
+	if (*p > 0x82)  return 0;
+	switch(*p)  {
+		case 0x82:  p++; len+=2;  yy = (*p++ << 8);  yy += *p++;  break;
+		case 0x81:  p++; len++;   yy =  *p++;  break;
+		case 0x80:  return 0;
+		default:    yy = *p++;  break;
+		}
+
+	return (xx - len == yy)? 1: 0;
+	}
+
+/*	Allocate, fill, and return cksumlens array of checksum lengths.
+**	This array holds just the unique elements from the krb5_cksumarray[].
+**	array[n] == 0 signals end of data.
+**
+**      The krb5_cksumarray[] was an internal variable that has since been
+**      replaced by a more general method for storing the data.  It should
+**      not be used.  Instead we use real API calls and make a guess for 
+**      what the highest assigned CKSUMTYPE_ constant is.  As of 1.2.2
+**      it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3).  So we will use 0x0010.
+*/
+static size_t  *populate_cksumlens(void)
+	{
+	int 		i, j, n;
+	static size_t 	*cklens = NULL;
+
+#ifdef KRB5_MIT_OLD11
+	n = krb5_max_cksum;
+#else
+	n = 0x0010;
+#endif	/* KRB5_MIT_OLD11 */
+ 
+#ifdef KRB5CHECKAUTH
+	if (!cklens && !(cklens = (size_t *) calloc(sizeof(int),n+1)))  return NULL;
+
+	for (i=0; i < n; i++)  {
+		if (!valid_cksumtype(i))  continue;	/*  array has holes  */
+		for (j=0; j < n; j++)  {
+			if (cklens[j] == 0)  {
+				cklens[j] = krb5_checksum_size(NULL,i);
+				break;		/*  krb5 elem was new: add   */
+				}
+			if (cklens[j] == krb5_checksum_size(NULL,i))  {
+				break;		/*  ignore duplicate elements */
+				}
+			}
+		}
+#endif	/* KRB5CHECKAUTH */
+
+	return cklens;
+	}
+
+/*	Return pointer to start of real authenticator within authenticator, or
+**	return NULL on error.
+**	Decrypted authenticator looks like this:
+**		[0 or 8 byte confounder] [4-24 byte checksum] [real authent'r]
+**	This hackery wouldn't be necessary if MIT KRB5 1.0.6 had the
+**	krb5_auth_con_getcksumtype() function advertised in its krb5.h.
+*/
+unsigned char	*kssl_skip_confound(krb5_enctype etype, unsigned char *a)
+	{
+	int 		i, conlen;
+	size_t		cklen;
+	static size_t 	*cksumlens = NULL;
+	unsigned char	*test_auth;
+
+	conlen = (etype)? 8: 0;
+
+	if (!cksumlens  &&  !(cksumlens = populate_cksumlens()))  return NULL;
+	for (i=0; (cklen = cksumlens[i]) != 0; i++)
+		{
+		test_auth = a + conlen + cklen;
+		if (kssl_test_confound(test_auth))  return test_auth;
+		}
+
+	return NULL;
+	}
+
+
+/*	Set kssl_err error info when reason text is a simple string
+**		kssl_err = struct { int reason; char text[KSSL_ERR_MAX+1]; }
+*/
+void
+kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text)
+        {
+	if (kssl_err == NULL)  return;
+
+	kssl_err->reason = reason;
+	BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, "%s", text);
+	return;
+        }
+
+
+/*	Display contents of krb5_data struct, for debugging
+*/
+void
+print_krb5_data(char *label, krb5_data *kdata)
+        {
+	int i;
+
+	printf("%s[%d] ", label, kdata->length);
+	for (i=0; i < (int)kdata->length; i++)
+                {
+		if (0 &&  isprint((int) kdata->data[i]))
+                        printf(	"%c ",  kdata->data[i]);
+		else
+                        printf(	"%02x ", (unsigned char) kdata->data[i]);
+		}
+	printf("\n");
+        }
+
+
+/*	Display contents of krb5_authdata struct, for debugging
+*/
+void
+print_krb5_authdata(char *label, krb5_authdata **adata)
+        {
+	if (adata == NULL)
+                {
+		printf("%s, authdata==0\n", label);
+		return;
+		}
+	printf("%s [%p]\n", label, (void *)adata);
+#if 0
+	{
+        int 	i;
+	printf("%s[at%d:%d] ", label, adata->ad_type, adata->length);
+	for (i=0; i < adata->length; i++)
+                {
+                printf((isprint(adata->contents[i]))? "%c ": "%02x",
+                        adata->contents[i]);
+		}
+	printf("\n");
+	}
+#endif
+	}
+
+
+/*	Display contents of krb5_keyblock struct, for debugging
+*/
+void
+print_krb5_keyblock(char *label, krb5_keyblock *keyblk)
+        {
+	int i;
+
+	if (keyblk == NULL)
+                {
+		printf("%s, keyblk==0\n", label);
+		return;
+		}
+#ifdef KRB5_HEIMDAL
+	printf("%s\n\t[et%d:%d]: ", label, keyblk->keytype,
+					   keyblk->keyvalue->length);
+	for (i=0; i < (int)keyblk->keyvalue->length; i++)
+                {
+		printf("%02x",(unsigned char *)(keyblk->keyvalue->contents)[i]);
+		}
+	printf("\n");
+#else
+	printf("%s\n\t[et%d:%d]: ", label, keyblk->enctype, keyblk->length);
+	for (i=0; i < (int)keyblk->length; i++)
+                {
+		printf("%02x",keyblk->contents[i]);
+		}
+	printf("\n");
+#endif
+        }
+
+
+/*	Display contents of krb5_principal_data struct, for debugging
+**	(krb5_principal is typedef'd == krb5_principal_data *)
+*/
+static void
+print_krb5_princ(char *label, krb5_principal_data *princ)
+        {
+	int i, ui, uj;
+
+	printf("%s principal Realm: ", label);
+	if (princ == NULL)  return;
+	for (ui=0; ui < (int)princ->realm.length; ui++)  putchar(princ->realm.data[ui]);
+	printf(" (nametype %d) has %d strings:\n", princ->type,princ->length);
+	for (i=0; i < (int)princ->length; i++)
+                {
+		printf("\t%d [%d]: ", i, princ->data[i].length);
+		for (uj=0; uj < (int)princ->data[i].length; uj++)  {
+			putchar(princ->data[i].data[uj]);
+			}
+		printf("\n");
+		}
+	return;
+        }
+
+
+/*	Given krb5 service (typically "kssl") and hostname in kssl_ctx,
+**	Return encrypted Kerberos ticket for service @ hostname.
+**	If authenp is non-NULL, also return encrypted authenticator,
+**	whose data should be freed by caller.
+**	(Originally was: Create Kerberos AP_REQ message for SSL Client.)
+**
+**	19990628	VRS 	Started; Returns Kerberos AP_REQ message.
+**	20010409	VRS 	Modified for RFC2712; Returns enc tkt.
+**	20010606	VRS 	May also return optional authenticator.
+*/
+krb5_error_code
+kssl_cget_tkt(	/* UPDATE */	KSSL_CTX *kssl_ctx,
+                /* OUT    */	krb5_data **enc_ticketp,
+                /* UPDATE */	krb5_data *authenp,
+                /* OUT    */	KSSL_ERR *kssl_err)
+	{
+	krb5_error_code		krb5rc = KRB5KRB_ERR_GENERIC;
+	krb5_context		krb5context = NULL;
+	krb5_auth_context	krb5auth_context = NULL;
+	krb5_ccache 		krb5ccdef = NULL;
+	krb5_creds		krb5creds, *krb5credsp = NULL;
+	krb5_data		krb5_app_req;
+
+	kssl_err_set(kssl_err, 0, "");
+	memset((char *)&krb5creds, 0, sizeof(krb5creds));
+
+	if (!kssl_ctx)
+                {
+		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                        "No kssl_ctx defined.\n");
+		goto err;
+		}
+	else if (!kssl_ctx->service_host)
+                {
+		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                        "kssl_ctx service_host undefined.\n");
+		goto err;
+		}
+
+	if ((krb5rc = krb5_init_context(&krb5context)) != 0)
+                {
+		BIO_snprintf(kssl_err->text,KSSL_ERR_MAX,
+                        "krb5_init_context() fails: %d\n", krb5rc);
+		kssl_err->reason = SSL_R_KRB5_C_INIT;
+		goto err;
+		}
+
+	if ((krb5rc = krb5_sname_to_principal(krb5context,
+                kssl_ctx->service_host,
+                (kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC,
+                KRB5_NT_SRV_HST, &krb5creds.server)) != 0)
+                {
+		BIO_snprintf(kssl_err->text,KSSL_ERR_MAX,
+                        "krb5_sname_to_principal() fails for %s/%s\n",
+                        kssl_ctx->service_host,
+                        (kssl_ctx->service_name)? kssl_ctx->service_name:
+						  KRB5SVC);
+		kssl_err->reason = SSL_R_KRB5_C_INIT;
+		goto err;
+		}
+
+	if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0)
+                {
+		kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC,
+                        "krb5_cc_default fails.\n");
+		goto err;
+		}
+
+	if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef,
+                &krb5creds.client)) != 0)
+                {
+		kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC,
+                        "krb5_cc_get_principal() fails.\n");
+		goto err;
+		}
+
+	if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef,
+                &krb5creds, &krb5credsp)) != 0)
+                {
+		kssl_err_set(kssl_err, SSL_R_KRB5_C_GET_CRED,
+                        "krb5_get_credentials() fails.\n");
+		goto err;
+		}
+
+	*enc_ticketp = &krb5credsp->ticket;
+#ifdef KRB5_HEIMDAL
+	kssl_ctx->enctype = krb5credsp->session.keytype;
+#else
+	kssl_ctx->enctype = krb5credsp->keyblock.enctype;
+#endif
+
+	krb5rc = KRB5KRB_ERR_GENERIC;
+	/*	caller should free data of krb5_app_req  */
+	/*  20010406 VRS deleted for real KerberosWrapper
+	**  20010605 VRS reinstated to offer Authenticator to KerberosWrapper
+	*/
+	krb5_app_req.length = 0;
+	if (authenp)
+                {
+		krb5_data	krb5in_data;
+		const unsigned char	*p;
+		long		arlen;
+		KRB5_APREQBODY	*ap_req;
+
+		authenp->length = 0;
+		krb5in_data.data = NULL;
+		krb5in_data.length = 0;
+		if ((krb5rc = krb5_mk_req_extended(krb5context,
+			&krb5auth_context, 0, &krb5in_data, krb5credsp,
+			&krb5_app_req)) != 0)
+			{
+			kssl_err_set(kssl_err, SSL_R_KRB5_C_MK_REQ,
+				"krb5_mk_req_extended() fails.\n");
+			goto err;
+			}
+
+		arlen = krb5_app_req.length;
+		p = (unsigned char *)krb5_app_req.data;
+		ap_req = (KRB5_APREQBODY *) d2i_KRB5_APREQ(NULL, &p, arlen);
+		if (ap_req)
+			{
+			authenp->length = i2d_KRB5_ENCDATA(
+					ap_req->authenticator, NULL);
+			if (authenp->length  && 
+				(authenp->data = malloc(authenp->length)))
+				{
+				unsigned char	*adp = (unsigned char *)authenp->data;
+				authenp->length = i2d_KRB5_ENCDATA(
+						ap_req->authenticator, &adp);
+				}
+			}
+
+		if (ap_req)  KRB5_APREQ_free((KRB5_APREQ *) ap_req);
+		if (krb5_app_req.length)  
+                        kssl_krb5_free_data_contents(krb5context,&krb5_app_req);
+		}
+#ifdef KRB5_HEIMDAL
+	if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->session))
+                {
+		kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT,
+                        "kssl_ctx_setkey() fails.\n");
+		}
+#else
+	if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->keyblock))
+                {
+		kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT,
+                        "kssl_ctx_setkey() fails.\n");
+		}
+#endif
+	else	krb5rc = 0;
+
+ err:
+#ifdef KSSL_DEBUG
+	kssl_ctx_show(kssl_ctx);
+#endif	/* KSSL_DEBUG */
+
+	if (krb5creds.client)	krb5_free_principal(krb5context,
+							krb5creds.client);
+	if (krb5creds.server)	krb5_free_principal(krb5context,
+							krb5creds.server);
+	if (krb5auth_context)	krb5_auth_con_free(krb5context,
+							krb5auth_context);
+	if (krb5context)	krb5_free_context(krb5context);
+	return (krb5rc);
+	}
+
+
+/*  Given d2i_-decoded asn1ticket, allocate and return a new krb5_ticket.
+**  Return Kerberos error code and kssl_err struct on error.
+**  Allocates krb5_ticket and krb5_principal; caller should free these.
+**
+**	20010410	VRS	Implemented krb5_decode_ticket() as
+**				old_krb5_decode_ticket(). Missing from MIT1.0.6.
+**	20010615	VRS 	Re-cast as openssl/asn1 d2i_*() functions.
+**				Re-used some of the old krb5_decode_ticket()
+**				code here.  This tkt should alloc/free just
+**				like the real thing.
+*/
+static krb5_error_code
+kssl_TKT2tkt(	/* IN     */	krb5_context	krb5context,
+		/* IN     */	KRB5_TKTBODY	*asn1ticket,
+		/* OUT    */	krb5_ticket	**krb5ticket,
+		/* OUT    */	KSSL_ERR *kssl_err  )
+        {
+        krb5_error_code			krb5rc = KRB5KRB_ERR_GENERIC;
+	krb5_ticket 			*new5ticket = NULL;
+	ASN1_GENERALSTRING		*gstr_svc, *gstr_host;
+
+	*krb5ticket = NULL;
+
+	if (asn1ticket == NULL  ||  asn1ticket->realm == NULL  ||
+		asn1ticket->sname == NULL  || 
+		sk_ASN1_GENERALSTRING_num(asn1ticket->sname->namestring) < 2)
+		{
+		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
+			"Null field in asn1ticket.\n");
+		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
+		return KRB5KRB_ERR_GENERIC;
+		}
+
+	if ((new5ticket = (krb5_ticket *) calloc(1, sizeof(krb5_ticket)))==NULL)
+		{
+		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
+			"Unable to allocate new krb5_ticket.\n");
+		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
+		return ENOMEM;		/*  or  KRB5KRB_ERR_GENERIC;	*/
+		}
+
+	gstr_svc  = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 0);
+	gstr_host = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 1);
+
+	if ((krb5rc = kssl_build_principal_2(krb5context,
+			&new5ticket->server,
+			asn1ticket->realm->length, (char *)asn1ticket->realm->data,
+			gstr_svc->length,  (char *)gstr_svc->data,
+			gstr_host->length, (char *)gstr_host->data)) != 0)
+		{
+		free(new5ticket);
+		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
+			"Error building ticket server principal.\n");
+		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
+		return krb5rc;		/*  or  KRB5KRB_ERR_GENERIC;	*/
+		}
+
+	krb5_princ_type(krb5context, new5ticket->server) =
+			asn1ticket->sname->nametype->data[0];
+	new5ticket->enc_part.enctype = asn1ticket->encdata->etype->data[0];
+	new5ticket->enc_part.kvno = asn1ticket->encdata->kvno->data[0];
+	new5ticket->enc_part.ciphertext.length =
+			asn1ticket->encdata->cipher->length;
+	if ((new5ticket->enc_part.ciphertext.data =
+		calloc(1, asn1ticket->encdata->cipher->length)) == NULL)
+		{
+		free(new5ticket);
+		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
+			"Error allocating cipher in krb5ticket.\n");
+		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
+		return KRB5KRB_ERR_GENERIC;
+		}
+	else
+		{
+		memcpy(new5ticket->enc_part.ciphertext.data,
+			asn1ticket->encdata->cipher->data,
+			asn1ticket->encdata->cipher->length);
+		}
+
+	*krb5ticket = new5ticket;
+	return 0;
+	}
+
+
+/*	Given krb5 service name in KSSL_CTX *kssl_ctx (typically "kssl"),
+**		and krb5 AP_REQ message & message length,
+**	Return Kerberos session key and client principle
+**		to SSL Server in KSSL_CTX *kssl_ctx.
+**
+**	19990702	VRS 	Started.
+*/
+krb5_error_code
+kssl_sget_tkt(	/* UPDATE */	KSSL_CTX		*kssl_ctx,
+		/* IN     */	krb5_data		*indata,
+		/* OUT    */	krb5_ticket_times	*ttimes,
+		/* OUT    */	KSSL_ERR		*kssl_err  )
+        {
+        krb5_error_code			krb5rc = KRB5KRB_ERR_GENERIC;
+        static krb5_context		krb5context = NULL;
+	static krb5_auth_context	krb5auth_context = NULL;
+	krb5_ticket 			*krb5ticket = NULL;
+	KRB5_TKTBODY 			*asn1ticket = NULL;
+	const unsigned char		*p;
+	krb5_keytab 			krb5keytab = NULL;
+	krb5_keytab_entry		kt_entry;
+	krb5_principal			krb5server;
+        krb5_rcache                     rcache = NULL;
+
+	kssl_err_set(kssl_err, 0, "");
+
+	if (!kssl_ctx)
+                {
+		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+			"No kssl_ctx defined.\n");
+		goto err;
+		}
+
+#ifdef KSSL_DEBUG
+	printf("in kssl_sget_tkt(%s)\n", kstring(kssl_ctx->service_name));
+#endif	/* KSSL_DEBUG */
+
+	if (!krb5context  &&  (krb5rc = krb5_init_context(&krb5context)))
+                {
+		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                        "krb5_init_context() fails.\n");
+		goto err;
+		}
+	if (krb5auth_context  &&
+		(krb5rc = krb5_auth_con_free(krb5context, krb5auth_context)))
+                {
+		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                        "krb5_auth_con_free() fails.\n");
+		goto err;
+		}
+	else  krb5auth_context = NULL;
+	if (!krb5auth_context  &&
+		(krb5rc = krb5_auth_con_init(krb5context, &krb5auth_context)))
+                {
+		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                        "krb5_auth_con_init() fails.\n");
+		goto err;
+		}
+
+ 
+	if ((krb5rc = krb5_auth_con_getrcache(krb5context, krb5auth_context,
+		&rcache)))
+		{
+ 		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+			"krb5_auth_con_getrcache() fails.\n");
+ 		goto err;
+		}
+ 
+	if ((krb5rc = krb5_sname_to_principal(krb5context, NULL,
+                (kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC,
+                KRB5_NT_SRV_HST, &krb5server)) != 0)
+                {
+		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                        "krb5_sname_to_principal() fails.\n");
+		goto err;
+		}
+
+	if (rcache == NULL) 
+                {
+                if ((krb5rc = krb5_get_server_rcache(krb5context,
+			krb5_princ_component(krb5context, krb5server, 0),
+			&rcache)))
+                        {
+		        kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                                "krb5_get_server_rcache() fails.\n");
+                  	goto err;
+                        }
+                }
+
+        if ((krb5rc = krb5_auth_con_setrcache(krb5context, krb5auth_context, rcache)))
+                {
+                kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+			"krb5_auth_con_setrcache() fails.\n");
+                goto err;
+                }
+
+
+	/*	kssl_ctx->keytab_file == NULL ==> use Kerberos default
+	*/
+	if (kssl_ctx->keytab_file)
+		{
+		krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file,
+                        &krb5keytab);
+		if (krb5rc)
+			{
+			kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+				"krb5_kt_resolve() fails.\n");
+			goto err;
+			}
+		}
+	else
+		{
+                krb5rc = krb5_kt_default(krb5context,&krb5keytab);
+                if (krb5rc)
+			{
+			kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 
+				"krb5_kt_default() fails.\n");
+			goto err;
+			}
+		}
+
+	/*	Actual Kerberos5 krb5_recvauth() has initial conversation here
+	**	o	check KRB5_SENDAUTH_BADAUTHVERS
+	**		unless KRB5_RECVAUTH_SKIP_VERSION
+	**	o	check KRB5_SENDAUTH_BADAPPLVERS
+	**	o	send "0" msg if all OK
+	*/
+
+	/*  20010411 was using AP_REQ instead of true KerberosWrapper
+	**
+	**  if ((krb5rc = krb5_rd_req(krb5context, &krb5auth_context,
+	**			&krb5in_data, krb5server, krb5keytab,
+	**			&ap_option, &krb5ticket)) != 0)  { Error }
+	*/
+
+	p = (unsigned char *)indata->data;
+	if ((asn1ticket = (KRB5_TKTBODY *) d2i_KRB5_TICKET(NULL, &p,
+						(long) indata->length)) == NULL)
+		{
+		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
+			"d2i_KRB5_TICKET() ASN.1 decode failure.\n");
+		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
+		goto err;
+		}
+	
+	/* Was:  krb5rc = krb5_decode_ticket(krb5in_data,&krb5ticket)) != 0) */
+	if ((krb5rc = kssl_TKT2tkt(krb5context, asn1ticket, &krb5ticket,
+					kssl_err)) != 0)
+		{
+		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
+			"Error converting ASN.1 ticket to krb5_ticket.\n");
+		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
+		goto err;
+		}
+
+	if (! krb5_principal_compare(krb5context, krb5server,
+						  krb5ticket->server))  {
+		krb5rc = KRB5_PRINC_NOMATCH;
+		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
+			"server principal != ticket principal\n");
+		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
+		goto err;
+		}
+	if ((krb5rc = krb5_kt_get_entry(krb5context, krb5keytab,
+			krb5ticket->server, krb5ticket->enc_part.kvno,
+			krb5ticket->enc_part.enctype, &kt_entry)) != 0)  {
+		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
+			"krb5_kt_get_entry() fails with %x.\n", krb5rc);
+		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
+		goto err;
+		}
+	if ((krb5rc = krb5_decrypt_tkt_part(krb5context, &kt_entry.key,
+			krb5ticket)) != 0)  {
+		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
+			"krb5_decrypt_tkt_part() failed.\n");
+		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
+		goto err;
+		}
+	else  {
+		krb5_kt_free_entry(krb5context, &kt_entry);
+#ifdef KSSL_DEBUG
+		{
+		int i; krb5_address **paddr = krb5ticket->enc_part2->caddrs;
+		printf("Decrypted ticket fields:\n");
+		printf("\tflags: %X, transit-type: %X",
+			krb5ticket->enc_part2->flags,
+			krb5ticket->enc_part2->transited.tr_type);
+		print_krb5_data("\ttransit-data: ",
+			&(krb5ticket->enc_part2->transited.tr_contents));
+		printf("\tcaddrs: %p, authdata: %p\n",
+			krb5ticket->enc_part2->caddrs,
+			krb5ticket->enc_part2->authorization_data);
+		if (paddr)
+			{
+			printf("\tcaddrs:\n");
+			for (i=0; paddr[i] != NULL; i++)
+				{
+				krb5_data d;
+				d.length=paddr[i]->length;
+				d.data=paddr[i]->contents;
+				print_krb5_data("\t\tIP: ", &d);
+				}
+			}
+		printf("\tstart/auth/end times: %d / %d / %d\n",
+			krb5ticket->enc_part2->times.starttime,
+			krb5ticket->enc_part2->times.authtime,
+			krb5ticket->enc_part2->times.endtime);
+		}
+#endif	/* KSSL_DEBUG */
+		}
+
+	krb5rc = KRB5_NO_TKT_SUPPLIED;
+	if (!krb5ticket  ||	!krb5ticket->enc_part2  ||
+                !krb5ticket->enc_part2->client  ||
+                !krb5ticket->enc_part2->client->data  ||
+                !krb5ticket->enc_part2->session)
+                {
+                kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
+                        "bad ticket from krb5_rd_req.\n");
+		}
+	else if (kssl_ctx_setprinc(kssl_ctx, KSSL_CLIENT,
+		 &krb5ticket->enc_part2->client->realm,
+		 krb5ticket->enc_part2->client->data,
+		 krb5ticket->enc_part2->client->length))
+                {
+		kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
+                        "kssl_ctx_setprinc() fails.\n");
+		}
+	else if (kssl_ctx_setkey(kssl_ctx, krb5ticket->enc_part2->session))
+                {
+		kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
+                        "kssl_ctx_setkey() fails.\n");
+		}
+	else if (krb5ticket->enc_part2->flags & TKT_FLG_INVALID)
+                {
+		krb5rc = KRB5KRB_AP_ERR_TKT_INVALID;
+                kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
+                        "invalid ticket from krb5_rd_req.\n");
+		}
+	else	krb5rc = 0;
+
+	kssl_ctx->enctype	= krb5ticket->enc_part.enctype;
+	ttimes->authtime	= krb5ticket->enc_part2->times.authtime;
+	ttimes->starttime	= krb5ticket->enc_part2->times.starttime;
+	ttimes->endtime 	= krb5ticket->enc_part2->times.endtime;
+	ttimes->renew_till	= krb5ticket->enc_part2->times.renew_till;
+
+ err:
+#ifdef KSSL_DEBUG
+	kssl_ctx_show(kssl_ctx);
+#endif	/* KSSL_DEBUG */
+
+	if (asn1ticket) 	KRB5_TICKET_free((KRB5_TICKET *) asn1ticket);
+        if (krb5keytab)         krb5_kt_close(krb5context, krb5keytab);
+	if (krb5ticket) 	krb5_free_ticket(krb5context, krb5ticket);
+	if (krb5server) 	krb5_free_principal(krb5context, krb5server);
+	return (krb5rc);
+        }
+
+
+/*	Allocate & return a new kssl_ctx struct.
+*/
+KSSL_CTX	*
+kssl_ctx_new(void)
+        {
+	return ((KSSL_CTX *) kssl_calloc(1, sizeof(KSSL_CTX)));
+        }
+
+
+/*	Frees a kssl_ctx struct and any allocated memory it holds.
+**	Returns NULL.
+*/
+KSSL_CTX	*
+kssl_ctx_free(KSSL_CTX *kssl_ctx)
+        {
+	if (kssl_ctx == NULL)  return kssl_ctx;
+
+	if (kssl_ctx->key)  		OPENSSL_cleanse(kssl_ctx->key,
+							      kssl_ctx->length);
+	if (kssl_ctx->key)  		kssl_free(kssl_ctx->key);
+	if (kssl_ctx->client_princ) 	kssl_free(kssl_ctx->client_princ);
+	if (kssl_ctx->service_host) 	kssl_free(kssl_ctx->service_host);
+	if (kssl_ctx->service_name) 	kssl_free(kssl_ctx->service_name);
+	if (kssl_ctx->keytab_file) 	kssl_free(kssl_ctx->keytab_file);
+
+	kssl_free(kssl_ctx);
+	return (KSSL_CTX *) NULL;
+        }
+
+
+/*	Given an array of (krb5_data *) entity (and optional realm),
+**	set the plain (char *) client_princ or service_host member
+**	of the kssl_ctx struct.
+*/
+krb5_error_code
+kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which,
+        krb5_data *realm, krb5_data *entity, int nentities)
+        {
+	char	**princ;
+	int 	length;
+	int i;
+
+	if (kssl_ctx == NULL  ||  entity == NULL)  return KSSL_CTX_ERR;
+
+	switch (which)
+                {
+        case KSSL_CLIENT:	princ = &kssl_ctx->client_princ;	break;
+        case KSSL_SERVER:	princ = &kssl_ctx->service_host;	break;
+        default:		return KSSL_CTX_ERR;			break;
+		}
+	if (*princ)  kssl_free(*princ);
+
+	/* Add up all the entity->lengths */
+	length = 0;
+	for (i=0; i < nentities; i++)
+		{
+		length += entity[i].length;
+		}
+	/* Add in space for the '/' character(s) (if any) */
+	length += nentities-1;
+	/* Space for the ('@'+realm+NULL | NULL) */
+	length += ((realm)? realm->length + 2: 1);
+
+	if ((*princ = kssl_calloc(1, length)) == NULL)
+		return KSSL_CTX_ERR;
+	else
+		{
+		for (i = 0; i < nentities; i++)
+			{
+			strncat(*princ, entity[i].data, entity[i].length);
+			if (i < nentities-1)
+				{
+				strcat (*princ, "/");
+				}
+			}
+		if (realm)
+                        {
+			strcat (*princ, "@");
+			(void) strncat(*princ, realm->data, realm->length);
+			}
+		}
+
+	return KSSL_CTX_OK;
+        }
+
+
+/*	Set one of the plain (char *) string members of the kssl_ctx struct.
+**	Default values should be:
+**		which == KSSL_SERVICE	=>	"khost" (KRB5SVC)
+**		which == KSSL_KEYTAB	=>	"/etc/krb5.keytab" (KRB5KEYTAB)
+*/
+krb5_error_code
+kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text)
+        {
+	char	**string;
+
+	if (!kssl_ctx)  return KSSL_CTX_ERR;
+
+	switch (which)
+                {
+        case KSSL_SERVICE:	string = &kssl_ctx->service_name;	break;
+        case KSSL_SERVER:	string = &kssl_ctx->service_host;	break;
+        case KSSL_CLIENT:	string = &kssl_ctx->client_princ;	break;
+        case KSSL_KEYTAB:	string = &kssl_ctx->keytab_file;	break;
+        default:		return KSSL_CTX_ERR;			break;
+		}
+	if (*string)  kssl_free(*string);
+
+	if (!text)
+                {
+		*string = '\0';
+		return KSSL_CTX_OK;
+		}
+
+	if ((*string = kssl_calloc(1, strlen(text) + 1)) == NULL)
+		return KSSL_CTX_ERR;
+	else
+		strcpy(*string, text);
+
+	return KSSL_CTX_OK;
+        }
+
+
+/*	Copy the Kerberos session key from a (krb5_keyblock *) to a kssl_ctx
+**	struct.  Clear kssl_ctx->key if Kerberos session key is NULL.
+*/
+krb5_error_code
+kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session)
+        {
+	int 		length;
+	krb5_enctype	enctype;
+	krb5_octet FAR	*contents = NULL;
+
+	if (!kssl_ctx)  return KSSL_CTX_ERR;
+
+	if (kssl_ctx->key)
+                {
+		OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length);
+		kssl_free(kssl_ctx->key);
+		}
+
+	if (session)
+                {
+
+#ifdef KRB5_HEIMDAL
+		length = session->keyvalue->length;
+		enctype = session->keytype;
+		contents = session->keyvalue->contents;
+#else
+		length = session->length;
+		enctype = session->enctype;
+		contents = session->contents;
+#endif
+		kssl_ctx->enctype = enctype;
+		kssl_ctx->length  = length;
+		}
+	else
+                {
+		kssl_ctx->enctype = ENCTYPE_UNKNOWN;
+		kssl_ctx->length  = 0;
+		return KSSL_CTX_OK;
+		}
+
+	if ((kssl_ctx->key =
+                (krb5_octet FAR *) kssl_calloc(1, kssl_ctx->length)) == NULL)
+                {
+		kssl_ctx->length  = 0;
+		return KSSL_CTX_ERR;
+		}
+	else
+		memcpy(kssl_ctx->key, contents, length);
+
+	return KSSL_CTX_OK;
+        }
+
+
+/*	Display contents of kssl_ctx struct
+*/
+void
+kssl_ctx_show(KSSL_CTX *kssl_ctx)
+        {
+	int 	i;
+
+	printf("kssl_ctx: ");
+	if (kssl_ctx == NULL)
+                {
+		printf("NULL\n");
+		return;
+		}
+	else
+		printf("%p\n", (void *)kssl_ctx);
+
+	printf("\tservice:\t%s\n",
+                (kssl_ctx->service_name)? kssl_ctx->service_name: "NULL");
+	printf("\tclient:\t%s\n",
+                (kssl_ctx->client_princ)? kssl_ctx->client_princ: "NULL");
+	printf("\tserver:\t%s\n",
+                (kssl_ctx->service_host)? kssl_ctx->service_host: "NULL");
+	printf("\tkeytab:\t%s\n",
+                (kssl_ctx->keytab_file)? kssl_ctx->keytab_file: "NULL");
+	printf("\tkey [%d:%d]:\t",
+                kssl_ctx->enctype, kssl_ctx->length);
+
+	for (i=0; i < kssl_ctx->length  &&  kssl_ctx->key; i++)
+                {
+		printf("%02x", kssl_ctx->key[i]);
+		}
+	printf("\n");
+	return;
+        }
+
+    int 
+    kssl_keytab_is_available(KSSL_CTX *kssl_ctx)
+{
+    krb5_context		krb5context = NULL;
+    krb5_keytab 		krb5keytab = NULL;
+    krb5_keytab_entry           entry;
+    krb5_principal              princ = NULL;
+    krb5_error_code  		krb5rc = KRB5KRB_ERR_GENERIC;
+    int rc = 0;
+
+    if ((krb5rc = krb5_init_context(&krb5context)))
+        return(0);
+
+    /*	kssl_ctx->keytab_file == NULL ==> use Kerberos default
+    */
+    if (kssl_ctx->keytab_file)
+    {
+        krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file,
+                                  &krb5keytab);
+        if (krb5rc)
+            goto exit;
+    }
+    else
+    {
+        krb5rc = krb5_kt_default(krb5context,&krb5keytab);
+        if (krb5rc)
+            goto exit;
+    }
+
+    /* the host key we are looking for */
+    krb5rc = krb5_sname_to_principal(krb5context, NULL, 
+                                     kssl_ctx->service_name ? kssl_ctx->service_name: KRB5SVC,
+                                     KRB5_NT_SRV_HST, &princ);
+
+    if (krb5rc)
+	goto exit;
+
+    krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, 
+                                princ,
+                                0 /* IGNORE_VNO */,
+                                0 /* IGNORE_ENCTYPE */,
+                                &entry);
+    if ( krb5rc == KRB5_KT_NOTFOUND ) {
+        rc = 1;
+        goto exit;
+    } else if ( krb5rc )
+        goto exit;
+    
+    krb5_kt_free_entry(krb5context, &entry);
+    rc = 1;
+
+  exit:
+    if (krb5keytab)     krb5_kt_close(krb5context, krb5keytab);
+    if (princ)          krb5_free_principal(krb5context, princ);
+    if (krb5context)	krb5_free_context(krb5context);
+    return(rc);
+}
+
+int 
+kssl_tgt_is_available(KSSL_CTX *kssl_ctx)
+        {
+        krb5_error_code		krb5rc = KRB5KRB_ERR_GENERIC;
+        krb5_context		krb5context = NULL;
+        krb5_ccache 		krb5ccdef = NULL;
+        krb5_creds		krb5creds, *krb5credsp = NULL;
+        int                     rc = 0;
+
+        memset((char *)&krb5creds, 0, sizeof(krb5creds));
+
+        if (!kssl_ctx)
+            return(0);
+
+        if (!kssl_ctx->service_host)
+            return(0);
+
+        if ((krb5rc = krb5_init_context(&krb5context)) != 0)
+            goto err;
+
+        if ((krb5rc = krb5_sname_to_principal(krb5context,
+                                              kssl_ctx->service_host,
+                                              (kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC,
+                                              KRB5_NT_SRV_HST, &krb5creds.server)) != 0)
+            goto err;
+
+        if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0)
+            goto err;
+
+        if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef,
+                                             &krb5creds.client)) != 0)
+            goto err;
+
+        if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef,
+                                            &krb5creds, &krb5credsp)) != 0)
+            goto err;
+
+        rc = 1;
+
+      err:
+#ifdef KSSL_DEBUG
+	kssl_ctx_show(kssl_ctx);
+#endif	/* KSSL_DEBUG */
+
+	if (krb5creds.client)	krb5_free_principal(krb5context, krb5creds.client);
+	if (krb5creds.server)	krb5_free_principal(krb5context, krb5creds.server);
+	if (krb5context)	krb5_free_context(krb5context);
+        return(rc);
+	}
+
+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_WIN32)
+void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data)
+	{
+#ifdef KRB5_HEIMDAL
+	data->length = 0;
+        if (data->data)
+            free(data->data);
+#elif defined(KRB5_MIT_OLD11)
+	if (data->data)  {
+		krb5_xfree(data->data);
+		data->data = 0;
+		}
+#else
+	krb5_free_data_contents(NULL, data);
+#endif
+	}
+#endif /* !OPENSSL_SYS_WINDOWS && !OPENSSL_SYS_WIN32 */
+
+
+/*  Given pointers to KerberosTime and struct tm structs, convert the
+**  KerberosTime string to struct tm.  Note that KerberosTime is a
+**  ASN1_GENERALIZEDTIME value, constrained to GMT with no fractional
+**  seconds as defined in RFC 1510.
+**  Return pointer to the (partially) filled in struct tm on success,
+**  return NULL on failure.
+*/
+static struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm)
+	{
+	char 		c, *p;
+
+	if (!k_tm)  return NULL;
+	if (gtime == NULL  ||  gtime->length < 14)  return NULL;
+	if (gtime->data == NULL)  return NULL;
+
+	p = (char *)&gtime->data[14];
+
+	c = *p;	 *p = '\0';  p -= 2;  k_tm->tm_sec  = atoi(p);      *(p+2) = c;
+	c = *p;	 *p = '\0';  p -= 2;  k_tm->tm_min  = atoi(p);      *(p+2) = c;
+	c = *p;	 *p = '\0';  p -= 2;  k_tm->tm_hour = atoi(p);      *(p+2) = c;
+	c = *p;	 *p = '\0';  p -= 2;  k_tm->tm_mday = atoi(p);      *(p+2) = c;
+	c = *p;	 *p = '\0';  p -= 2;  k_tm->tm_mon  = atoi(p)-1;    *(p+2) = c;
+	c = *p;	 *p = '\0';  p -= 4;  k_tm->tm_year = atoi(p)-1900; *(p+4) = c;
+
+	return k_tm;
+	}
+
+
+/*  Helper function for kssl_validate_times().
+**  We need context->clockskew, but krb5_context is an opaque struct.
+**  So we try to sneek the clockskew out through the replay cache.
+**	If that fails just return a likely default (300 seconds).
+*/
+static krb5_deltat get_rc_clockskew(krb5_context context)
+	{
+	krb5_rcache 	rc;
+	krb5_deltat 	clockskew;
+
+	if (krb5_rc_default(context, &rc))  return KSSL_CLOCKSKEW;
+	if (krb5_rc_initialize(context, rc, 0))  return KSSL_CLOCKSKEW;
+	if (krb5_rc_get_lifespan(context, rc, &clockskew))  {
+		clockskew = KSSL_CLOCKSKEW;
+		}
+	(void) krb5_rc_destroy(context, rc);
+	return clockskew;
+	}
+
+
+/*  kssl_validate_times() combines (and more importantly exposes)
+**  the MIT KRB5 internal function krb5_validate_times() and the
+**  in_clock_skew() macro.  The authenticator client time is checked
+**  to be within clockskew secs of the current time and the current
+**  time is checked to be within the ticket start and expire times.
+**  Either check may be omitted by supplying a NULL value.
+**  Returns 0 for valid times, SSL_R_KRB5* error codes otherwise.
+**  See Also: (Kerberos source)/krb5/lib/krb5/krb/valid_times.c
+**  20010420 VRS
+*/
+krb5_error_code  kssl_validate_times(	krb5_timestamp atime,
+					krb5_ticket_times *ttimes)
+	{
+	krb5_deltat 	skew;
+	krb5_timestamp	start, now;
+	krb5_error_code	rc;
+	krb5_context	context;
+
+	if ((rc = krb5_init_context(&context)))	 return SSL_R_KRB5_S_BAD_TICKET;
+	skew = get_rc_clockskew(context); 
+	if ((rc = krb5_timeofday(context,&now))) return SSL_R_KRB5_S_BAD_TICKET;
+	krb5_free_context(context);
+
+	if (atime  &&  labs(atime - now) >= skew)  return SSL_R_KRB5_S_TKT_SKEW;
+
+	if (! ttimes)  return 0;
+
+	start = (ttimes->starttime != 0)? ttimes->starttime: ttimes->authtime;
+	if (start - now > skew)  return SSL_R_KRB5_S_TKT_NYV;
+	if ((now - ttimes->endtime) > skew)  return SSL_R_KRB5_S_TKT_EXPIRED;
+
+#ifdef KSSL_DEBUG
+	printf("kssl_validate_times: %d |<-  | %d - %d | < %d  ->| %d\n",
+		start, atime, now, skew, ttimes->endtime);
+#endif	/* KSSL_DEBUG */
+
+	return 0;
+	}
+
+
+/*  Decode and decrypt given DER-encoded authenticator, then pass
+**  authenticator ctime back in *atimep (or 0 if time unavailable).
+**  Returns krb5_error_code and kssl_err on error.  A NULL 
+**  authenticator (authentp->length == 0) is not considered an error.
+**  Note that kssl_check_authent() makes use of the KRB5 session key;
+**  you must call kssl_sget_tkt() to get the key before calling this routine.
+*/
+krb5_error_code  kssl_check_authent(
+			/* IN     */	KSSL_CTX	*kssl_ctx,
+                        /* IN     */   	krb5_data	*authentp,
+			/* OUT    */	krb5_timestamp	*atimep,
+			/* OUT    */    KSSL_ERR	*kssl_err  )
+	{
+        krb5_error_code		krb5rc = 0;
+	KRB5_ENCDATA		*dec_authent = NULL;
+	KRB5_AUTHENTBODY	*auth = NULL;
+	krb5_enctype		enctype;
+	EVP_CIPHER_CTX		ciph_ctx;
+	const EVP_CIPHER	*enc = NULL;
+	unsigned char		iv[EVP_MAX_IV_LENGTH];
+	const unsigned char	*p;
+	unsigned char		*unenc_authent;
+	int 			outl, unencbufsize;
+	struct tm		tm_time, *tm_l, *tm_g;
+	time_t			now, tl, tg, tr, tz_offset;
+
+	EVP_CIPHER_CTX_init(&ciph_ctx);
+	*atimep = 0;
+	kssl_err_set(kssl_err, 0, "");
+
+#ifndef KRB5CHECKAUTH
+	authentp = NULL;
+#else
+#if	KRB5CHECKAUTH == 0
+	authentp = NULL;
+#endif
+#endif	/* KRB5CHECKAUTH */
+
+	if (authentp == NULL  ||  authentp->length == 0)  return 0;
+
+#ifdef KSSL_DEBUG
+        {
+        unsigned int ui;
+	printf("kssl_check_authent: authenticator[%d]:\n",authentp->length);
+	p = authentp->data; 
+	for (ui=0; ui < authentp->length; ui++)  printf("%02x ",p[ui]);
+	printf("\n");
+        }
+#endif	/* KSSL_DEBUG */
+
+	unencbufsize = 2 * authentp->length;
+	if ((unenc_authent = calloc(1, unencbufsize)) == NULL)
+		{
+		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+			"Unable to allocate authenticator buffer.\n");
+		krb5rc = KRB5KRB_ERR_GENERIC;
+		goto err;
+		}
+
+	p = (unsigned char *)authentp->data;
+	if ((dec_authent = d2i_KRB5_ENCDATA(NULL, &p,
+					(long) authentp->length)) == NULL) 
+		{
+		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                        "Error decoding authenticator.\n");
+		krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+		goto err;
+		}
+
+	enctype = dec_authent->etype->data[0];	/* should = kssl_ctx->enctype */
+#if !defined(KRB5_MIT_OLD11)
+            switch ( enctype ) {
+            case ENCTYPE_DES3_CBC_SHA1:		/*    EVP_des_ede3_cbc();  */
+            case ENCTYPE_DES3_CBC_SHA:
+            case ENCTYPE_DES3_CBC_RAW:
+                krb5rc = 0;                     /* Skip, can't handle derived keys */
+                goto err;
+            }
+#endif
+	enc = kssl_map_enc(enctype);
+	memset(iv, 0, sizeof iv);       /* per RFC 1510 */
+
+	if (enc == NULL)
+		{
+		/*  Disable kssl_check_authent for ENCTYPE_DES3_CBC_SHA1.
+		**  This enctype indicates the authenticator was encrypted
+		**  using key-usage derived keys which openssl cannot decrypt.
+		*/
+		goto err;
+		}
+
+        if (!EVP_CipherInit(&ciph_ctx,enc,kssl_ctx->key,iv,0))
+                {
+                kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                        "EVP_CipherInit error decrypting authenticator.\n");
+                krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+                goto err;
+                }
+        outl = dec_authent->cipher->length;
+        if (!EVP_Cipher(&ciph_ctx,unenc_authent,dec_authent->cipher->data,outl))
+                {
+                kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                        "EVP_Cipher error decrypting authenticator.\n");
+                krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+                goto err;
+                }
+        EVP_CIPHER_CTX_cleanup(&ciph_ctx);
+
+#ifdef KSSL_DEBUG
+	{
+	int padl;
+	printf("kssl_check_authent: decrypted authenticator[%d] =\n", outl);
+	for (padl=0; padl < outl; padl++) printf("%02x ",unenc_authent[padl]);
+	printf("\n");
+	}
+#endif	/* KSSL_DEBUG */
+
+	if ((p = kssl_skip_confound(enctype, unenc_authent)) == NULL)
+		{
+		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                        "confounded by authenticator.\n");
+		krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+		goto err;
+		}
+	outl -= p - unenc_authent;
+
+	if ((auth = (KRB5_AUTHENTBODY *) d2i_KRB5_AUTHENT(NULL, &p,
+							  (long) outl))==NULL)
+		{
+		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                        "Error decoding authenticator body.\n");
+		krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+		goto err;
+		}
+
+	memset(&tm_time,0,sizeof(struct tm));
+	if (k_gmtime(auth->ctime, &tm_time)  &&
+		((tr = mktime(&tm_time)) != (time_t)(-1)))
+ 		{
+ 		now  = time(&now);
+ 		tm_l = localtime(&now); 	tl = mktime(tm_l);
+ 		tm_g = gmtime(&now);		tg = mktime(tm_g);
+ 		tz_offset = tg - tl;
+
+		*atimep = (krb5_timestamp)(tr - tz_offset);
+ 		}
+
+#ifdef KSSL_DEBUG
+	printf("kssl_check_authent: returns %d for client time ", *atimep);
+	if (auth && auth->ctime && auth->ctime->length && auth->ctime->data)
+		printf("%.*s\n", auth->ctime->length, auth->ctime->data);
+	else	printf("NULL\n");
+#endif	/* KSSL_DEBUG */
+
+ err:
+	if (auth)		KRB5_AUTHENT_free((KRB5_AUTHENT *) auth);
+	if (dec_authent)	KRB5_ENCDATA_free(dec_authent);
+	if (unenc_authent)	free(unenc_authent);
+	EVP_CIPHER_CTX_cleanup(&ciph_ctx);
+	return krb5rc;
+	}
+
+
+/*  Replaces krb5_build_principal_ext(), with varargs length == 2 (svc, host),
+**  because I dont't know how to stub varargs.
+**  Returns krb5_error_code == ENOMEM on alloc error, otherwise
+**  passes back newly constructed principal, which should be freed by caller.
+*/
+krb5_error_code  kssl_build_principal_2(
+			/* UPDATE */	krb5_context	context,
+			/* OUT    */	krb5_principal	*princ,
+			/* IN     */	int rlen,  const char *realm,
+			/* IN	  */	int slen,  const char *svc,
+			/* IN	  */	int hlen,  const char *host)
+	{
+	krb5_data		*p_data = NULL;
+	krb5_principal		new_p = NULL;
+        char			*new_r = NULL;
+
+	if ((p_data = (krb5_data *) calloc(2, sizeof(krb5_data))) == NULL  ||
+	    (new_p = (krb5_principal) calloc(1, sizeof(krb5_principal_data)))
+			== NULL)  goto err;
+	new_p->length = 2;
+	new_p->data = p_data;
+
+	if ((new_r = calloc(1, rlen + 1)) == NULL)  goto err;
+	memcpy(new_r, realm, rlen);
+	krb5_princ_set_realm_length(context, new_p, rlen);
+	krb5_princ_set_realm_data(context, new_p, new_r);
+
+	if ((new_p->data[0].data = calloc(1, slen + 1)) == NULL)  goto err;
+	memcpy(new_p->data[0].data, svc, slen);
+	new_p->data[0].length = slen;
+
+	if ((new_p->data[1].data = calloc(1, hlen + 1)) == NULL)  goto err;
+	memcpy(new_p->data[1].data, host, hlen);
+	new_p->data[1].length = hlen;
+	
+	krb5_princ_type(context, new_p) = KRB5_NT_UNKNOWN;
+	*princ = new_p;
+	return 0;
+
+ err:
+	if (new_p  &&  new_p[0].data)	free(new_p[0].data);
+	if (new_p  &&  new_p[1].data)	free(new_p[1].data);
+	if (new_p)	free(new_p);
+	if (new_r)	free(new_r);
+	return ENOMEM;
+	}
+
+
+#else /* !OPENSSL_NO_KRB5 */
+
+#if defined(PEDANTIC) || defined(OPENSSL_SYS_VMS)
+static void *dummy=&dummy;
+#endif
+
+#endif	/* !OPENSSL_NO_KRB5	*/
+
diff --git a/openssl/ssl/kssl.h b/openssl/ssl/kssl.h
new file mode 100644
index 0000000..a3d20e1
--- /dev/null
+++ b/openssl/ssl/kssl.h
@@ -0,0 +1,179 @@
+/* ssl/kssl.h -*- mode: C; c-file-style: "eay" -*- */
+/* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project 2000.
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+**	19990701	VRS 	Started.
+*/
+
+#ifndef	KSSL_H
+#define	KSSL_H
+
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_NO_KRB5
+
+#include <stdio.h>
+#include <ctype.h>
+#include <krb5.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+**	Depending on which KRB5 implementation used, some types from
+**	the other may be missing.  Resolve that here and now
+*/
+#ifdef KRB5_HEIMDAL
+typedef unsigned char krb5_octet;
+#define FAR
+#else
+
+#ifndef FAR
+#define FAR
+#endif
+
+#endif
+
+/*	Uncomment this to debug kssl problems or
+**	to trace usage of the Kerberos session key
+**
+**	#define		KSSL_DEBUG
+*/
+
+#ifndef	KRB5SVC
+#define KRB5SVC	"host"
+#endif
+
+#ifndef	KRB5KEYTAB
+#define KRB5KEYTAB	"/etc/krb5.keytab"
+#endif
+
+#ifndef KRB5SENDAUTH
+#define KRB5SENDAUTH	1
+#endif
+
+#ifndef KRB5CHECKAUTH
+#define KRB5CHECKAUTH	1
+#endif
+
+#ifndef KSSL_CLOCKSKEW
+#define	KSSL_CLOCKSKEW	300;
+#endif
+
+#define	KSSL_ERR_MAX	255
+typedef struct kssl_err_st  {
+	int  reason;
+	char text[KSSL_ERR_MAX+1];
+	} KSSL_ERR;
+
+
+/*	Context for passing
+**		(1) Kerberos session key to SSL, and
+**		(2)	Config data between application and SSL lib
+*/
+typedef struct kssl_ctx_st
+        {
+                                /*	used by:    disposition:            */
+	char *service_name;	/*	C,S	    default ok (kssl)       */
+	char *service_host;	/*	C	    input, REQUIRED         */
+	char *client_princ;	/*	S	    output from krb5 ticket */
+	char *keytab_file;	/*      S	    NULL (/etc/krb5.keytab) */
+	char *cred_cache;	/*	C	    NULL (default)          */
+	krb5_enctype enctype;
+	int length;
+	krb5_octet FAR *key;
+	} KSSL_CTX;
+
+#define	KSSL_CLIENT 	1
+#define KSSL_SERVER 	2
+#define	KSSL_SERVICE	3
+#define	KSSL_KEYTAB 	4
+
+#define KSSL_CTX_OK 	0
+#define KSSL_CTX_ERR	1
+#define KSSL_NOMEM	2
+
+/* Public (for use by applications that use OpenSSL with Kerberos 5 support */
+krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text);
+KSSL_CTX *kssl_ctx_new(void);
+KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx);
+void kssl_ctx_show(KSSL_CTX *kssl_ctx);
+krb5_error_code kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which,
+        krb5_data *realm, krb5_data *entity, int nentities);
+krb5_error_code	kssl_cget_tkt(KSSL_CTX *kssl_ctx,  krb5_data **enc_tktp,
+        krb5_data *authenp, KSSL_ERR *kssl_err);
+krb5_error_code	kssl_sget_tkt(KSSL_CTX *kssl_ctx,  krb5_data *indata,
+        krb5_ticket_times *ttimes, KSSL_ERR *kssl_err);
+krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session);
+void	kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text);
+void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data);
+krb5_error_code  kssl_build_principal_2(krb5_context context,
+			krb5_principal *princ, int rlen, const char *realm,
+			int slen, const char *svc, int hlen, const char *host);
+krb5_error_code  kssl_validate_times(krb5_timestamp atime,
+					krb5_ticket_times *ttimes);
+krb5_error_code  kssl_check_authent(KSSL_CTX *kssl_ctx, krb5_data *authentp,
+			            krb5_timestamp *atimep, KSSL_ERR *kssl_err);
+unsigned char	*kssl_skip_confound(krb5_enctype enctype, unsigned char *authn);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif	/* OPENSSL_NO_KRB5	*/
+#endif	/* KSSL_H 	*/
diff --git a/openssl/ssl/kssl_lcl.h b/openssl/ssl/kssl_lcl.h
new file mode 100644
index 0000000..c039c91
--- /dev/null
+++ b/openssl/ssl/kssl_lcl.h
@@ -0,0 +1,87 @@
+/* ssl/kssl.h -*- mode: C; c-file-style: "eay" -*- */
+/* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project 2000.
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef	KSSL_LCL_H
+#define	KSSL_LCL_H
+
+#include <openssl/kssl.h>
+
+#ifndef OPENSSL_NO_KRB5
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Private (internal to OpenSSL) */
+void print_krb5_data(char *label, krb5_data *kdata);
+void print_krb5_authdata(char *label, krb5_authdata **adata);
+void print_krb5_keyblock(char *label, krb5_keyblock *keyblk);
+
+char *kstring(char *string);
+char *knumber(int len, krb5_octet *contents);
+
+const EVP_CIPHER *kssl_map_enc(krb5_enctype enctype);
+
+int kssl_keytab_is_available(KSSL_CTX *kssl_ctx);
+int kssl_tgt_is_available(KSSL_CTX *kssl_ctx);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif	/* OPENSSL_NO_KRB5	*/
+#endif	/* KSSL_LCL_H 	*/
diff --git a/openssl/ssl/s23_clnt.c b/openssl/ssl/s23_clnt.c
new file mode 100644
index 0000000..f41fe3a
--- /dev/null
+++ b/openssl/ssl/s23_clnt.c
@@ -0,0 +1,703 @@
+/* ssl/s23_clnt.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "ssl_locl.h"
+#include <openssl/buffer.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+
+static const SSL_METHOD *ssl23_get_client_method(int ver);
+static int ssl23_client_hello(SSL *s);
+static int ssl23_get_server_hello(SSL *s);
+static const SSL_METHOD *ssl23_get_client_method(int ver)
+	{
+#ifndef OPENSSL_NO_SSL2
+	if (ver == SSL2_VERSION)
+		return(SSLv2_client_method());
+#endif
+	if (ver == SSL3_VERSION)
+		return(SSLv3_client_method());
+	else if (ver == TLS1_VERSION)
+		return(TLSv1_client_method());
+	else
+		return(NULL);
+	}
+
+IMPLEMENT_ssl23_meth_func(SSLv23_client_method,
+			ssl_undefined_function,
+			ssl23_connect,
+			ssl23_get_client_method)
+
+int ssl23_connect(SSL *s)
+	{
+	BUF_MEM *buf=NULL;
+	unsigned long Time=(unsigned long)time(NULL);
+	void (*cb)(const SSL *ssl,int type,int val)=NULL;
+	int ret= -1;
+	int new_state,state;
+
+	RAND_add(&Time,sizeof(Time),0);
+	ERR_clear_error();
+	clear_sys_error();
+
+	if (s->info_callback != NULL)
+		cb=s->info_callback;
+	else if (s->ctx->info_callback != NULL)
+		cb=s->ctx->info_callback;
+	
+	s->in_handshake++;
+	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); 
+
+	for (;;)
+		{
+		state=s->state;
+
+		switch(s->state)
+			{
+		case SSL_ST_BEFORE:
+		case SSL_ST_CONNECT:
+		case SSL_ST_BEFORE|SSL_ST_CONNECT:
+		case SSL_ST_OK|SSL_ST_CONNECT:
+
+			if (s->session != NULL)
+				{
+				SSLerr(SSL_F_SSL23_CONNECT,SSL_R_SSL23_DOING_SESSION_ID_REUSE);
+				ret= -1;
+				goto end;
+				}
+			s->server=0;
+			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
+
+			/* s->version=TLS1_VERSION; */
+			s->type=SSL_ST_CONNECT;
+
+			if (s->init_buf == NULL)
+				{
+				if ((buf=BUF_MEM_new()) == NULL)
+					{
+					ret= -1;
+					goto end;
+					}
+				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
+					{
+					ret= -1;
+					goto end;
+					}
+				s->init_buf=buf;
+				buf=NULL;
+				}
+
+			if (!ssl3_setup_buffers(s)) { ret= -1; goto end; }
+
+			ssl3_init_finished_mac(s);
+
+			s->state=SSL23_ST_CW_CLNT_HELLO_A;
+			s->ctx->stats.sess_connect++;
+			s->init_num=0;
+			break;
+
+		case SSL23_ST_CW_CLNT_HELLO_A:
+		case SSL23_ST_CW_CLNT_HELLO_B:
+
+			s->shutdown=0;
+			ret=ssl23_client_hello(s);
+			if (ret <= 0) goto end;
+			s->state=SSL23_ST_CR_SRVR_HELLO_A;
+			s->init_num=0;
+
+			break;
+
+		case SSL23_ST_CR_SRVR_HELLO_A:
+		case SSL23_ST_CR_SRVR_HELLO_B:
+			ret=ssl23_get_server_hello(s);
+			if (ret >= 0) cb=NULL;
+			goto end;
+			/* break; */
+
+		default:
+			SSLerr(SSL_F_SSL23_CONNECT,SSL_R_UNKNOWN_STATE);
+			ret= -1;
+			goto end;
+			/* break; */
+			}
+
+		if (s->debug) { (void)BIO_flush(s->wbio); }
+
+		if ((cb != NULL) && (s->state != state))
+			{
+			new_state=s->state;
+			s->state=state;
+			cb(s,SSL_CB_CONNECT_LOOP,1);
+			s->state=new_state;
+			}
+		}
+end:
+	s->in_handshake--;
+	if (buf != NULL)
+		BUF_MEM_free(buf);
+	if (cb != NULL)
+		cb(s,SSL_CB_CONNECT_EXIT,ret);
+	return(ret);
+	}
+
+static int ssl23_no_ssl2_ciphers(SSL *s)
+	{
+	SSL_CIPHER *cipher;
+	STACK_OF(SSL_CIPHER) *ciphers;
+	int i;
+	ciphers = SSL_get_ciphers(s);
+	for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++)
+		{
+		cipher = sk_SSL_CIPHER_value(ciphers, i);
+		if (cipher->algorithm_ssl == SSL_SSLV2)
+			return 0;
+		}
+	return 1;
+	}
+
+static int ssl23_client_hello(SSL *s)
+	{
+	unsigned char *buf;
+	unsigned char *p,*d;
+	int i,ch_len;
+	unsigned long Time,l;
+	int ssl2_compat;
+	int version = 0, version_major, version_minor;
+#ifndef OPENSSL_NO_COMP
+	int j;
+	SSL_COMP *comp;
+#endif
+	int ret;
+
+	ssl2_compat = (s->options & SSL_OP_NO_SSLv2) ? 0 : 1;
+
+	if (ssl2_compat && ssl23_no_ssl2_ciphers(s))
+		ssl2_compat = 0;
+
+	if (!(s->options & SSL_OP_NO_TLSv1))
+		{
+		version = TLS1_VERSION;
+		}
+	else if (!(s->options & SSL_OP_NO_SSLv3))
+		{
+		version = SSL3_VERSION;
+		}
+	else if (!(s->options & SSL_OP_NO_SSLv2))
+		{
+		version = SSL2_VERSION;
+		}
+#ifndef OPENSSL_NO_TLSEXT
+	if (version != SSL2_VERSION)
+		{
+		/* have to disable SSL 2.0 compatibility if we need TLS extensions */
+
+		if (s->tlsext_hostname != NULL)
+			ssl2_compat = 0;
+		if (s->tlsext_status_type != -1)
+			ssl2_compat = 0;
+#ifdef TLSEXT_TYPE_opaque_prf_input
+		if (s->ctx->tlsext_opaque_prf_input_callback != 0 || s->tlsext_opaque_prf_input != NULL)
+			ssl2_compat = 0;
+#endif
+		}
+#endif
+
+	buf=(unsigned char *)s->init_buf->data;
+	if (s->state == SSL23_ST_CW_CLNT_HELLO_A)
+		{
+#if 0
+		/* don't reuse session-id's */
+		if (!ssl_get_new_session(s,0))
+			{
+			return(-1);
+			}
+#endif
+
+		p=s->s3->client_random;
+		Time=(unsigned long)time(NULL);		/* Time */
+		l2n(Time,p);
+		if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
+			return -1;
+
+		if (version == TLS1_VERSION)
+			{
+			version_major = TLS1_VERSION_MAJOR;
+			version_minor = TLS1_VERSION_MINOR;
+			}
+		else if (version == SSL3_VERSION)
+			{
+			version_major = SSL3_VERSION_MAJOR;
+			version_minor = SSL3_VERSION_MINOR;
+			}
+		else if (version == SSL2_VERSION)
+			{
+			version_major = SSL2_VERSION_MAJOR;
+			version_minor = SSL2_VERSION_MINOR;
+			}
+		else
+			{
+			SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_PROTOCOLS_AVAILABLE);
+			return(-1);
+			}
+
+		s->client_version = version;
+
+		if (ssl2_compat)
+			{
+			/* create SSL 2.0 compatible Client Hello */
+
+			/* two byte record header will be written last */
+			d = &(buf[2]);
+			p = d + 9; /* leave space for message type, version, individual length fields */
+
+			*(d++) = SSL2_MT_CLIENT_HELLO;
+			*(d++) = version_major;
+			*(d++) = version_minor;
+			
+			/* Ciphers supported */
+			i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),p,0);
+			if (i == 0)
+				{
+				/* no ciphers */
+				SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
+				return -1;
+				}
+			s2n(i,d);
+			p+=i;
+			
+			/* put in the session-id length (zero since there is no reuse) */
+#if 0
+			s->session->session_id_length=0;
+#endif
+			s2n(0,d);
+
+			if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG)
+				ch_len=SSL2_CHALLENGE_LENGTH;
+			else
+				ch_len=SSL2_MAX_CHALLENGE_LENGTH;
+
+			/* write out sslv2 challenge */
+			/* Note that ch_len must be <= SSL3_RANDOM_SIZE (32),
+			   because it is one of SSL2_MAX_CHALLENGE_LENGTH (32)
+			   or SSL2_MAX_CHALLENGE_LENGTH (16), but leave the
+			   check in for futurproofing */
+			if (SSL3_RANDOM_SIZE < ch_len)
+				i=SSL3_RANDOM_SIZE;
+			else
+				i=ch_len;
+			s2n(i,d);
+			memset(&(s->s3->client_random[0]),0,SSL3_RANDOM_SIZE);
+			if (RAND_pseudo_bytes(&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i) <= 0)
+				return -1;
+
+			memcpy(p,&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i);
+			p+=i;
+
+			i= p- &(buf[2]);
+			buf[0]=((i>>8)&0xff)|0x80;
+			buf[1]=(i&0xff);
+
+			/* number of bytes to write */
+			s->init_num=i+2;
+			s->init_off=0;
+
+			ssl3_finish_mac(s,&(buf[2]),i);
+			}
+		else
+			{
+			/* create Client Hello in SSL 3.0/TLS 1.0 format */
+
+			/* do the record header (5 bytes) and handshake message header (4 bytes) last */
+			d = p = &(buf[9]);
+			
+			*(p++) = version_major;
+			*(p++) = version_minor;
+
+			/* Random stuff */
+			memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
+			p += SSL3_RANDOM_SIZE;
+
+			/* Session ID (zero since there is no reuse) */
+			*(p++) = 0;
+
+			/* Ciphers supported (using SSL 3.0/TLS 1.0 format) */
+			i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),ssl3_put_cipher_by_char);
+			if (i == 0)
+				{
+				SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
+				return -1;
+				}
+			s2n(i,p);
+			p+=i;
+
+			/* COMPRESSION */
+#ifdef OPENSSL_NO_COMP
+			*(p++)=1;
+#else
+			if ((s->options & SSL_OP_NO_COMPRESSION)
+						|| !s->ctx->comp_methods)
+				j=0;
+			else
+				j=sk_SSL_COMP_num(s->ctx->comp_methods);
+			*(p++)=1+j;
+			for (i=0; i<j; i++)
+				{
+				comp=sk_SSL_COMP_value(s->ctx->comp_methods,i);
+				*(p++)=comp->id;
+				}
+#endif
+			*(p++)=0; /* Add the NULL method */
+
+#ifndef OPENSSL_NO_TLSEXT
+			/* TLS extensions*/
+			if (ssl_prepare_clienthello_tlsext(s) <= 0)
+				{
+				SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
+				return -1;
+				}
+			if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
+				{
+				SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
+				return -1;
+				}
+#endif
+			
+			l = p-d;
+
+			/* fill in 4-byte handshake header */
+			d=&(buf[5]);
+			*(d++)=SSL3_MT_CLIENT_HELLO;
+			l2n3(l,d);
+
+			l += 4;
+
+			if (l > SSL3_RT_MAX_PLAIN_LENGTH)
+				{
+				SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
+				return -1;
+				}
+			
+			/* fill in 5-byte record header */
+			d=buf;
+			*(d++) = SSL3_RT_HANDSHAKE;
+			*(d++) = version_major;
+			*(d++) = version_minor; /* arguably we should send the *lowest* suported version here
+			                         * (indicating, e.g., TLS 1.0 in "SSL 3.0 format") */
+			s2n((int)l,d);
+
+			/* number of bytes to write */
+			s->init_num=p-buf;
+			s->init_off=0;
+
+			ssl3_finish_mac(s,&(buf[5]), s->init_num - 5);
+			}
+
+		s->state=SSL23_ST_CW_CLNT_HELLO_B;
+		s->init_off=0;
+		}
+
+	/* SSL3_ST_CW_CLNT_HELLO_B */
+	ret = ssl23_write_bytes(s);
+
+	if ((ret >= 2) && s->msg_callback)
+		{
+		/* Client Hello has been sent; tell msg_callback */
+
+		if (ssl2_compat)
+			s->msg_callback(1, SSL2_VERSION, 0, s->init_buf->data+2, ret-2, s, s->msg_callback_arg);
+		else
+			s->msg_callback(1, version, SSL3_RT_HANDSHAKE, s->init_buf->data+5, ret-5, s, s->msg_callback_arg);
+		}
+
+	return ret;
+	}
+
+static int ssl23_get_server_hello(SSL *s)
+	{
+	char buf[8];
+	unsigned char *p;
+	int i;
+	int n;
+
+	n=ssl23_read_bytes(s,7);
+
+	if (n != 7) return(n);
+	p=s->packet;
+
+	memcpy(buf,p,n);
+
+	if ((p[0] & 0x80) && (p[2] == SSL2_MT_SERVER_HELLO) &&
+		(p[5] == 0x00) && (p[6] == 0x02))
+		{
+#ifdef OPENSSL_NO_SSL2
+		SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
+		goto err;
+#else
+		/* we are talking sslv2 */
+		/* we need to clean up the SSLv3 setup and put in the
+		 * sslv2 stuff. */
+		int ch_len;
+
+		if (s->options & SSL_OP_NO_SSLv2)
+			{
+			SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
+			goto err;
+			}
+		if (s->s2 == NULL)
+			{
+			if (!ssl2_new(s))
+				goto err;
+			}
+		else
+			ssl2_clear(s);
+
+		if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG)
+			ch_len=SSL2_CHALLENGE_LENGTH;
+		else
+			ch_len=SSL2_MAX_CHALLENGE_LENGTH;
+
+		/* write out sslv2 challenge */
+		/* Note that ch_len must be <= SSL3_RANDOM_SIZE (32), because
+		   it is one of SSL2_MAX_CHALLENGE_LENGTH (32) or
+		   SSL2_MAX_CHALLENGE_LENGTH (16), but leave the check in for
+		   futurproofing */
+		i=(SSL3_RANDOM_SIZE < ch_len)
+			?SSL3_RANDOM_SIZE:ch_len;
+		s->s2->challenge_length=i;
+		memcpy(s->s2->challenge,
+			&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i);
+
+		if (s->s3 != NULL) ssl3_free(s);
+
+		if (!BUF_MEM_grow_clean(s->init_buf,
+			SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
+			{
+			SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,ERR_R_BUF_LIB);
+			goto err;
+			}
+
+		s->state=SSL2_ST_GET_SERVER_HELLO_A;
+		if (!(s->client_version == SSL2_VERSION))
+			/* use special padding (SSL 3.0 draft/RFC 2246, App. E.2) */
+			s->s2->ssl2_rollback=1;
+
+		/* setup the 7 bytes we have read so we get them from
+		 * the sslv2 buffer */
+		s->rstate=SSL_ST_READ_HEADER;
+		s->packet_length=n;
+		s->packet= &(s->s2->rbuf[0]);
+		memcpy(s->packet,buf,n);
+		s->s2->rbuf_left=n;
+		s->s2->rbuf_offs=0;
+
+		/* we have already written one */
+		s->s2->write_sequence=1;
+
+		s->method=SSLv2_client_method();
+		s->handshake_func=s->method->ssl_connect;
+#endif
+		}
+	else if (p[1] == SSL3_VERSION_MAJOR &&
+	         (p[2] == SSL3_VERSION_MINOR || p[2] == TLS1_VERSION_MINOR) &&
+	         ((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) ||
+	          (p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2)))
+		{
+		/* we have sslv3 or tls1 (server hello or alert) */
+
+		if ((p[2] == SSL3_VERSION_MINOR) &&
+			!(s->options & SSL_OP_NO_SSLv3))
+			{
+			s->version=SSL3_VERSION;
+			s->method=SSLv3_client_method();
+			}
+		else if ((p[2] == TLS1_VERSION_MINOR) &&
+			!(s->options & SSL_OP_NO_TLSv1))
+			{
+			s->version=TLS1_VERSION;
+			s->method=TLSv1_client_method();
+			}
+		else
+			{
+			SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
+			goto err;
+			}
+
+		if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING)
+			{
+			/* fatal alert */
+
+			void (*cb)(const SSL *ssl,int type,int val)=NULL;
+			int j;
+
+			if (s->info_callback != NULL)
+				cb=s->info_callback;
+			else if (s->ctx->info_callback != NULL)
+				cb=s->ctx->info_callback;
+ 
+			i=p[5];
+			if (cb != NULL)
+				{
+				j=(i<<8)|p[6];
+				cb(s,SSL_CB_READ_ALERT,j);
+				}
+			
+			if (s->msg_callback)
+				s->msg_callback(0, s->version, SSL3_RT_ALERT, p+5, 2, s, s->msg_callback_arg);
+
+			s->rwstate=SSL_NOTHING;
+			SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_AD_REASON_OFFSET+p[6]);
+			goto err;
+			}
+
+		if (!ssl_init_wbio_buffer(s,1)) goto err;
+
+		/* we are in this state */
+		s->state=SSL3_ST_CR_SRVR_HELLO_A;
+
+		/* put the 7 bytes we have read into the input buffer
+		 * for SSLv3 */
+		s->rstate=SSL_ST_READ_HEADER;
+		s->packet_length=n;
+		if (s->s3->rbuf.buf == NULL)
+			if (!ssl3_setup_read_buffer(s))
+				goto err;
+		s->packet= &(s->s3->rbuf.buf[0]);
+		memcpy(s->packet,buf,n);
+		s->s3->rbuf.left=n;
+		s->s3->rbuf.offset=0;
+
+		s->handshake_func=s->method->ssl_connect;
+		}
+	else
+		{
+		SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNKNOWN_PROTOCOL);
+		goto err;
+		}
+	s->init_num=0;
+
+	/* Since, if we are sending a ssl23 client hello, we are not
+	 * reusing a session-id */
+        if (!s->session_creation_enabled)
+		{
+		if (!(s->client_version == SSL2_VERSION))
+			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+		SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
+		goto err;
+		}
+	if (!ssl_get_new_session(s,0))
+		goto err;
+
+	return(SSL_connect(s));
+err:
+	return(-1);
+	}
diff --git a/openssl/ssl/s23_lib.c b/openssl/ssl/s23_lib.c
new file mode 100644
index 0000000..3bf7283
--- /dev/null
+++ b/openssl/ssl/s23_lib.c
@@ -0,0 +1,187 @@
+/* ssl/s23_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+
+long ssl23_default_timeout(void)
+	{
+	return(300);
+	}
+
+int ssl23_num_ciphers(void)
+	{
+	return(ssl3_num_ciphers()
+#ifndef OPENSSL_NO_SSL2
+	       + ssl2_num_ciphers()
+#endif
+	    );
+	}
+
+const SSL_CIPHER *ssl23_get_cipher(unsigned int u)
+	{
+	unsigned int uu=ssl3_num_ciphers();
+
+	if (u < uu)
+		return(ssl3_get_cipher(u));
+	else
+#ifndef OPENSSL_NO_SSL2
+		return(ssl2_get_cipher(u-uu));
+#else
+		return(NULL);
+#endif
+	}
+
+/* This function needs to check if the ciphers required are actually
+ * available */
+const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p)
+	{
+	const SSL_CIPHER *cp;
+
+	cp=ssl3_get_cipher_by_char(p);
+#ifndef OPENSSL_NO_SSL2
+	if (cp == NULL)
+		cp=ssl2_get_cipher_by_char(p);
+#endif
+	return(cp);
+	}
+
+int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
+	{
+	long l;
+
+	/* We can write SSLv2 and SSLv3 ciphers */
+	if (p != NULL)
+		{
+		l=c->id;
+		p[0]=((unsigned char)(l>>16L))&0xFF;
+		p[1]=((unsigned char)(l>> 8L))&0xFF;
+		p[2]=((unsigned char)(l     ))&0xFF;
+		}
+	return(3);
+	}
+
+int ssl23_read(SSL *s, void *buf, int len)
+	{
+	int n;
+
+	clear_sys_error();
+	if (SSL_in_init(s) && (!s->in_handshake))
+		{
+		n=s->handshake_func(s);
+		if (n < 0) return(n);
+		if (n == 0)
+			{
+			SSLerr(SSL_F_SSL23_READ,SSL_R_SSL_HANDSHAKE_FAILURE);
+			return(-1);
+			}
+		return(SSL_read(s,buf,len));
+		}
+	else
+		{
+		ssl_undefined_function(s);
+		return(-1);
+		}
+	}
+
+int ssl23_peek(SSL *s, void *buf, int len)
+	{
+	int n;
+
+	clear_sys_error();
+	if (SSL_in_init(s) && (!s->in_handshake))
+		{
+		n=s->handshake_func(s);
+		if (n < 0) return(n);
+		if (n == 0)
+			{
+			SSLerr(SSL_F_SSL23_PEEK,SSL_R_SSL_HANDSHAKE_FAILURE);
+			return(-1);
+			}
+		return(SSL_peek(s,buf,len));
+		}
+	else
+		{
+		ssl_undefined_function(s);
+		return(-1);
+		}
+	}
+
+int ssl23_write(SSL *s, const void *buf, int len)
+	{
+	int n;
+
+	clear_sys_error();
+	if (SSL_in_init(s) && (!s->in_handshake))
+		{
+		n=s->handshake_func(s);
+		if (n < 0) return(n);
+		if (n == 0)
+			{
+			SSLerr(SSL_F_SSL23_WRITE,SSL_R_SSL_HANDSHAKE_FAILURE);
+			return(-1);
+			}
+		return(SSL_write(s,buf,len));
+		}
+	else
+		{
+		ssl_undefined_function(s);
+		return(-1);
+		}
+	}
diff --git a/openssl/ssl/s23_meth.c b/openssl/ssl/s23_meth.c
new file mode 100644
index 0000000..c6099ef
--- /dev/null
+++ b/openssl/ssl/s23_meth.c
@@ -0,0 +1,88 @@
+/* ssl/s23_meth.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+
+static const SSL_METHOD *ssl23_get_method(int ver);
+static const SSL_METHOD *ssl23_get_method(int ver)
+	{
+#ifndef OPENSSL_NO_SSL2
+	if (ver == SSL2_VERSION)
+		return(SSLv2_method());
+	else
+#endif
+#ifndef OPENSSL_NO_SSL3
+	if (ver == SSL3_VERSION)
+		return(SSLv3_method());
+	else
+#endif
+#ifndef OPENSSL_NO_TLS1
+	if (ver == TLS1_VERSION)
+		return(TLSv1_method());
+	else
+#endif
+		return(NULL);
+	}
+
+IMPLEMENT_ssl23_meth_func(SSLv23_method,
+			ssl23_accept,
+			ssl23_connect,
+			ssl23_get_method)
+
diff --git a/openssl/ssl/s23_pkt.c b/openssl/ssl/s23_pkt.c
new file mode 100644
index 0000000..4ca6a1b
--- /dev/null
+++ b/openssl/ssl/s23_pkt.c
@@ -0,0 +1,117 @@
+/* ssl/s23_pkt.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "ssl_locl.h"
+#include <openssl/evp.h>
+#include <openssl/buffer.h>
+
+int ssl23_write_bytes(SSL *s)
+	{
+	int i,num,tot;
+	char *buf;
+
+	buf=s->init_buf->data;
+	tot=s->init_off;
+	num=s->init_num;
+	for (;;)
+		{
+		s->rwstate=SSL_WRITING;
+		i=BIO_write(s->wbio,&(buf[tot]),num);
+		if (i <= 0)
+			{
+			s->init_off=tot;
+			s->init_num=num;
+			return(i);
+			}
+		s->rwstate=SSL_NOTHING;
+		if (i == num) return(tot+i);
+
+		num-=i;
+		tot+=i;
+		}
+	}
+
+/* return regularly only when we have read (at least) 'n' bytes */
+int ssl23_read_bytes(SSL *s, int n)
+	{
+	unsigned char *p;
+	int j;
+
+	if (s->packet_length < (unsigned int)n)
+		{
+		p=s->packet;
+
+		for (;;)
+			{
+			s->rwstate=SSL_READING;
+			j=BIO_read(s->rbio,(char *)&(p[s->packet_length]),
+				n-s->packet_length);
+			if (j <= 0)
+				return(j);
+			s->rwstate=SSL_NOTHING;
+			s->packet_length+=j;
+			if (s->packet_length >= (unsigned int)n)
+				return(s->packet_length);
+			}
+		}
+	return(n);
+	}
+
diff --git a/openssl/ssl/s23_srvr.c b/openssl/ssl/s23_srvr.c
new file mode 100644
index 0000000..e22879c
--- /dev/null
+++ b/openssl/ssl/s23_srvr.c
@@ -0,0 +1,599 @@
+/* ssl/s23_srvr.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "ssl_locl.h"
+#include <openssl/buffer.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+
+static const SSL_METHOD *ssl23_get_server_method(int ver);
+int ssl23_get_client_hello(SSL *s);
+static const SSL_METHOD *ssl23_get_server_method(int ver)
+	{
+#ifndef OPENSSL_NO_SSL2
+	if (ver == SSL2_VERSION)
+		return(SSLv2_server_method());
+#endif
+	if (ver == SSL3_VERSION)
+		return(SSLv3_server_method());
+	else if (ver == TLS1_VERSION)
+		return(TLSv1_server_method());
+	else
+		return(NULL);
+	}
+
+IMPLEMENT_ssl23_meth_func(SSLv23_server_method,
+			ssl23_accept,
+			ssl_undefined_function,
+			ssl23_get_server_method)
+
+int ssl23_accept(SSL *s)
+	{
+	BUF_MEM *buf;
+	unsigned long Time=(unsigned long)time(NULL);
+	void (*cb)(const SSL *ssl,int type,int val)=NULL;
+	int ret= -1;
+	int new_state,state;
+
+	RAND_add(&Time,sizeof(Time),0);
+	ERR_clear_error();
+	clear_sys_error();
+
+	if (s->info_callback != NULL)
+		cb=s->info_callback;
+	else if (s->ctx->info_callback != NULL)
+		cb=s->ctx->info_callback;
+	
+	s->in_handshake++;
+	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); 
+
+	for (;;)
+		{
+		state=s->state;
+
+		switch(s->state)
+			{
+		case SSL_ST_BEFORE:
+		case SSL_ST_ACCEPT:
+		case SSL_ST_BEFORE|SSL_ST_ACCEPT:
+		case SSL_ST_OK|SSL_ST_ACCEPT:
+
+			s->server=1;
+			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
+
+			/* s->version=SSL3_VERSION; */
+			s->type=SSL_ST_ACCEPT;
+
+			if (s->init_buf == NULL)
+				{
+				if ((buf=BUF_MEM_new()) == NULL)
+					{
+					ret= -1;
+					goto end;
+					}
+				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
+					{
+					ret= -1;
+					goto end;
+					}
+				s->init_buf=buf;
+				}
+
+			ssl3_init_finished_mac(s);
+
+			s->state=SSL23_ST_SR_CLNT_HELLO_A;
+			s->ctx->stats.sess_accept++;
+			s->init_num=0;
+			break;
+
+		case SSL23_ST_SR_CLNT_HELLO_A:
+		case SSL23_ST_SR_CLNT_HELLO_B:
+
+			s->shutdown=0;
+			ret=ssl23_get_client_hello(s);
+			if (ret >= 0) cb=NULL;
+			goto end;
+			/* break; */
+
+		default:
+			SSLerr(SSL_F_SSL23_ACCEPT,SSL_R_UNKNOWN_STATE);
+			ret= -1;
+			goto end;
+			/* break; */
+			}
+
+		if ((cb != NULL) && (s->state != state))
+			{
+			new_state=s->state;
+			s->state=state;
+			cb(s,SSL_CB_ACCEPT_LOOP,1);
+			s->state=new_state;
+			}
+		}
+end:
+	s->in_handshake--;
+	if (cb != NULL)
+		cb(s,SSL_CB_ACCEPT_EXIT,ret);
+	return(ret);
+	}
+
+
+int ssl23_get_client_hello(SSL *s)
+	{
+	char buf_space[11]; /* Request this many bytes in initial read.
+	                     * We can detect SSL 3.0/TLS 1.0 Client Hellos
+	                     * ('type == 3') correctly only when the following
+	                     * is in a single record, which is not guaranteed by
+	                     * the protocol specification:
+	                     * Byte  Content
+	                     *  0     type            \
+	                     *  1/2   version          > record header
+	                     *  3/4   length          /
+	                     *  5     msg_type        \
+	                     *  6-8   length           > Client Hello message
+	                     *  9/10  client_version  /
+	                     */
+	char *buf= &(buf_space[0]);
+	unsigned char *p,*d,*d_len,*dd;
+	unsigned int i;
+	unsigned int csl,sil,cl;
+	int n=0,j;
+	int type=0;
+	int v[2];
+
+	if (s->state ==	SSL23_ST_SR_CLNT_HELLO_A)
+		{
+		/* read the initial header */
+		v[0]=v[1]=0;
+
+		if (!ssl3_setup_buffers(s)) goto err;
+
+		n=ssl23_read_bytes(s, sizeof buf_space);
+		if (n != sizeof buf_space) return(n); /* n == -1 || n == 0 */
+
+		p=s->packet;
+
+		memcpy(buf,p,n);
+
+		if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO))
+			{
+			/*
+			 * SSLv2 header
+			 */
+			if ((p[3] == 0x00) && (p[4] == 0x02))
+				{
+				v[0]=p[3]; v[1]=p[4];
+				/* SSLv2 */
+				if (!(s->options & SSL_OP_NO_SSLv2))
+					type=1;
+				}
+			else if (p[3] == SSL3_VERSION_MAJOR)
+				{
+				v[0]=p[3]; v[1]=p[4];
+				/* SSLv3/TLSv1 */
+				if (p[4] >= TLS1_VERSION_MINOR)
+					{
+					if (!(s->options & SSL_OP_NO_TLSv1))
+						{
+						s->version=TLS1_VERSION;
+						/* type=2; */ /* done later to survive restarts */
+						s->state=SSL23_ST_SR_CLNT_HELLO_B;
+						}
+					else if (!(s->options & SSL_OP_NO_SSLv3))
+						{
+						s->version=SSL3_VERSION;
+						/* type=2; */
+						s->state=SSL23_ST_SR_CLNT_HELLO_B;
+						}
+					else if (!(s->options & SSL_OP_NO_SSLv2))
+						{
+						type=1;
+						}
+					}
+				else if (!(s->options & SSL_OP_NO_SSLv3))
+					{
+					s->version=SSL3_VERSION;
+					/* type=2; */
+					s->state=SSL23_ST_SR_CLNT_HELLO_B;
+					}
+				else if (!(s->options & SSL_OP_NO_SSLv2))
+					type=1;
+
+				}
+			}
+		else if ((p[0] == SSL3_RT_HANDSHAKE) &&
+			 (p[1] == SSL3_VERSION_MAJOR) &&
+			 (p[5] == SSL3_MT_CLIENT_HELLO) &&
+			 ((p[3] == 0 && p[4] < 5 /* silly record length? */)
+				|| (p[9] >= p[1])))
+			{
+			/*
+			 * SSLv3 or tls1 header
+			 */
+			
+			v[0]=p[1]; /* major version (= SSL3_VERSION_MAJOR) */
+			/* We must look at client_version inside the Client Hello message
+			 * to get the correct minor version.
+			 * However if we have only a pathologically small fragment of the
+			 * Client Hello message, this would be difficult, and we'd have
+			 * to read more records to find out.
+			 * No known SSL 3.0 client fragments ClientHello like this,
+			 * so we simply assume TLS 1.0 to avoid protocol version downgrade
+			 * attacks. */
+			if (p[3] == 0 && p[4] < 6)
+				{
+#if 0
+				SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_SMALL);
+				goto err;
+#else
+				v[1] = TLS1_VERSION_MINOR;
+#endif
+				}
+			/* if major version number > 3 set minor to a value
+			 * which will use the highest version 3 we support.
+			 * If TLS 2.0 ever appears we will need to revise
+			 * this....
+			 */
+			else if (p[9] > SSL3_VERSION_MAJOR)
+				v[1]=0xff;
+			else
+				v[1]=p[10]; /* minor version according to client_version */
+			if (v[1] >= TLS1_VERSION_MINOR)
+				{
+				if (!(s->options & SSL_OP_NO_TLSv1))
+					{
+					s->version=TLS1_VERSION;
+					type=3;
+					}
+				else if (!(s->options & SSL_OP_NO_SSLv3))
+					{
+					s->version=SSL3_VERSION;
+					type=3;
+					}
+				}
+			else
+				{
+				/* client requests SSL 3.0 */
+				if (!(s->options & SSL_OP_NO_SSLv3))
+					{
+					s->version=SSL3_VERSION;
+					type=3;
+					}
+				else if (!(s->options & SSL_OP_NO_TLSv1))
+					{
+					/* we won't be able to use TLS of course,
+					 * but this will send an appropriate alert */
+					s->version=TLS1_VERSION;
+					type=3;
+					}
+				}
+			}
+		else if ((strncmp("GET ", (char *)p,4) == 0) ||
+			 (strncmp("POST ",(char *)p,5) == 0) ||
+			 (strncmp("HEAD ",(char *)p,5) == 0) ||
+			 (strncmp("PUT ", (char *)p,4) == 0))
+			{
+			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_HTTP_REQUEST);
+			goto err;
+			}
+		else if (strncmp("CONNECT",(char *)p,7) == 0)
+			{
+			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_HTTPS_PROXY_REQUEST);
+			goto err;
+			}
+		}
+
+	if (s->state == SSL23_ST_SR_CLNT_HELLO_B)
+		{
+		/* we have SSLv3/TLSv1 in an SSLv2 header
+		 * (other cases skip this state) */
+
+		type=2;
+		p=s->packet;
+		v[0] = p[3]; /* == SSL3_VERSION_MAJOR */
+		v[1] = p[4];
+
+/* The SSL2 protocol allows n to be larger, just pick
+ * a reasonable buffer size. */
+#if SSL3_RT_DEFAULT_PACKET_SIZE < 1024*4 - SSL3_RT_DEFAULT_WRITE_OVERHEAD
+#error "SSL3_RT_DEFAULT_PACKET_SIZE is too small."
+#endif
+		n=((p[0]&0x7f)<<8)|p[1];
+		if (n > SSL3_RT_DEFAULT_PACKET_SIZE - 2)
+			{
+			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE);
+			goto err;
+			}
+
+		j=ssl23_read_bytes(s,n+2);
+		if (j <= 0) return(j);
+
+		ssl3_finish_mac(s, s->packet+2, s->packet_length-2);
+		if (s->msg_callback)
+			s->msg_callback(0, SSL2_VERSION, 0, s->packet+2, s->packet_length-2, s, s->msg_callback_arg); /* CLIENT-HELLO */
+
+		p=s->packet;
+		p+=5;
+		n2s(p,csl);
+		n2s(p,sil);
+		n2s(p,cl);
+		d=(unsigned char *)s->init_buf->data;
+		if ((csl+sil+cl+11) != s->packet_length) /* We can't have TLS extensions in SSL 2.0 format
+		                                          * Client Hello, can we? Error condition should be
+		                                          * '>' otherweise */
+			{
+			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_LENGTH_MISMATCH);
+			goto err;
+			}
+
+		/* record header: msg_type ... */
+		*(d++) = SSL3_MT_CLIENT_HELLO;
+		/* ... and length (actual value will be written later) */
+		d_len = d;
+		d += 3;
+
+		/* client_version */
+		*(d++) = SSL3_VERSION_MAJOR; /* == v[0] */
+		*(d++) = v[1];
+
+		/* lets populate the random area */
+		/* get the challenge_length */
+		i=(cl > SSL3_RANDOM_SIZE)?SSL3_RANDOM_SIZE:cl;
+		memset(d,0,SSL3_RANDOM_SIZE);
+		memcpy(&(d[SSL3_RANDOM_SIZE-i]),&(p[csl+sil]),i);
+		d+=SSL3_RANDOM_SIZE;
+
+		/* no session-id reuse */
+		*(d++)=0;
+
+		/* ciphers */
+		j=0;
+		dd=d;
+		d+=2;
+		for (i=0; i<csl; i+=3)
+			{
+			if (p[i] != 0) continue;
+			*(d++)=p[i+1];
+			*(d++)=p[i+2];
+			j+=2;
+			}
+		s2n(j,dd);
+
+		/* COMPRESSION */
+		*(d++)=1;
+		*(d++)=0;
+		
+#if 0
+                /* copy any remaining data with may be extensions */
+	        p = p+csl+sil+cl;
+		while (p <  s->packet+s->packet_length)
+			{
+			*(d++)=*(p++);
+			}
+#endif
+
+		i = (d-(unsigned char *)s->init_buf->data) - 4;
+		l2n3((long)i, d_len);
+
+		/* get the data reused from the init_buf */
+		s->s3->tmp.reuse_message=1;
+		s->s3->tmp.message_type=SSL3_MT_CLIENT_HELLO;
+		s->s3->tmp.message_size=i;
+		}
+
+	/* imaginary new state (for program structure): */
+	/* s->state = SSL23_SR_CLNT_HELLO_C */
+
+	if (type == 1)
+		{
+#ifdef OPENSSL_NO_SSL2
+		SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
+		goto err;
+#else
+		/* we are talking sslv2 */
+		/* we need to clean up the SSLv3/TLSv1 setup and put in the
+		 * sslv2 stuff. */
+
+		if (s->s2 == NULL)
+			{
+			if (!ssl2_new(s))
+				goto err;
+			}
+		else
+			ssl2_clear(s);
+
+		if (s->s3 != NULL) ssl3_free(s);
+
+		if (!BUF_MEM_grow_clean(s->init_buf,
+			SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
+			{
+			goto err;
+			}
+
+		s->state=SSL2_ST_GET_CLIENT_HELLO_A;
+		if (s->options & SSL_OP_NO_TLSv1 && s->options & SSL_OP_NO_SSLv3)
+			s->s2->ssl2_rollback=0;
+		else
+			/* reject SSL 2.0 session if client supports SSL 3.0 or TLS 1.0
+			 * (SSL 3.0 draft/RFC 2246, App. E.2) */
+			s->s2->ssl2_rollback=1;
+
+		/* setup the n bytes we have read so we get them from
+		 * the sslv2 buffer */
+		s->rstate=SSL_ST_READ_HEADER;
+		s->packet_length=n;
+		s->packet= &(s->s2->rbuf[0]);
+		memcpy(s->packet,buf,n);
+		s->s2->rbuf_left=n;
+		s->s2->rbuf_offs=0;
+
+		s->method=SSLv2_server_method();
+		s->handshake_func=s->method->ssl_accept;
+#endif
+		}
+
+	if ((type == 2) || (type == 3))
+		{
+		/* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */
+
+		if (!ssl_init_wbio_buffer(s,1)) goto err;
+
+		/* we are in this state */
+		s->state=SSL3_ST_SR_CLNT_HELLO_A;
+
+		if (type == 3)
+			{
+			/* put the 'n' bytes we have read into the input buffer
+			 * for SSLv3 */
+			s->rstate=SSL_ST_READ_HEADER;
+			s->packet_length=n;
+			if (s->s3->rbuf.buf == NULL)
+				if (!ssl3_setup_read_buffer(s))
+					goto err;
+
+			s->packet= &(s->s3->rbuf.buf[0]);
+			memcpy(s->packet,buf,n);
+			s->s3->rbuf.left=n;
+			s->s3->rbuf.offset=0;
+			}
+		else
+			{
+			s->packet_length=0;
+			s->s3->rbuf.left=0;
+			s->s3->rbuf.offset=0;
+			}
+
+		if (s->version == TLS1_VERSION)
+			s->method = TLSv1_server_method();
+		else
+			s->method = SSLv3_server_method();
+#if 0 /* ssl3_get_client_hello does this */
+		s->client_version=(v[0]<<8)|v[1];
+#endif
+		s->handshake_func=s->method->ssl_accept;
+		}
+	
+	if ((type < 1) || (type > 3))
+		{
+		/* bad, very bad */
+		SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNKNOWN_PROTOCOL);
+		goto err;
+		}
+	s->init_num=0;
+
+	if (buf != buf_space) OPENSSL_free(buf);
+	return(SSL_accept(s));
+err:
+	if (buf != buf_space) OPENSSL_free(buf);
+	return(-1);
+	}
diff --git a/openssl/ssl/s2_clnt.c b/openssl/ssl/s2_clnt.c
new file mode 100644
index 0000000..00ac158
--- /dev/null
+++ b/openssl/ssl/s2_clnt.c
@@ -0,0 +1,1125 @@
+/* ssl/s2_clnt.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "ssl_locl.h"
+#ifndef OPENSSL_NO_SSL2
+#include <stdio.h>
+#include <openssl/rand.h>
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+
+static const SSL_METHOD *ssl2_get_client_method(int ver);
+static int get_server_finished(SSL *s);
+static int get_server_verify(SSL *s);
+static int get_server_hello(SSL *s);
+static int client_hello(SSL *s); 
+static int client_master_key(SSL *s);
+static int client_finished(SSL *s);
+static int client_certificate(SSL *s);
+static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from,
+	unsigned char *to,int padding);
+#define BREAK	break
+
+static const SSL_METHOD *ssl2_get_client_method(int ver)
+	{
+	if (ver == SSL2_VERSION)
+		return(SSLv2_client_method());
+	else
+		return(NULL);
+	}
+
+IMPLEMENT_ssl2_meth_func(SSLv2_client_method,
+			ssl_undefined_function,
+			ssl2_connect,
+			ssl2_get_client_method)
+
+int ssl2_connect(SSL *s)
+	{
+	unsigned long l=(unsigned long)time(NULL);
+	BUF_MEM *buf=NULL;
+	int ret= -1;
+	void (*cb)(const SSL *ssl,int type,int val)=NULL;
+	int new_state,state;
+
+	RAND_add(&l,sizeof(l),0);
+	ERR_clear_error();
+	clear_sys_error();
+
+	if (s->info_callback != NULL)
+		cb=s->info_callback;
+	else if (s->ctx->info_callback != NULL)
+		cb=s->ctx->info_callback;
+
+	/* init things to blank */
+	s->in_handshake++;
+	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
+
+	for (;;)
+		{
+		state=s->state;
+
+		switch (s->state)
+			{
+		case SSL_ST_BEFORE:
+		case SSL_ST_CONNECT:
+		case SSL_ST_BEFORE|SSL_ST_CONNECT:
+		case SSL_ST_OK|SSL_ST_CONNECT:
+
+			s->server=0;
+			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
+
+			s->version=SSL2_VERSION;
+			s->type=SSL_ST_CONNECT;
+
+			buf=s->init_buf;
+			if ((buf == NULL) && ((buf=BUF_MEM_new()) == NULL))
+				{
+				ret= -1;
+				goto end;
+				}
+			if (!BUF_MEM_grow(buf,
+				SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
+				{
+				if (buf == s->init_buf)
+					buf=NULL;
+				ret= -1;
+				goto end;
+				}
+			s->init_buf=buf;
+			buf=NULL;
+			s->init_num=0;
+			s->state=SSL2_ST_SEND_CLIENT_HELLO_A;
+			s->ctx->stats.sess_connect++;
+			s->handshake_func=ssl2_connect;
+			BREAK;
+
+		case SSL2_ST_SEND_CLIENT_HELLO_A:
+		case SSL2_ST_SEND_CLIENT_HELLO_B:
+			s->shutdown=0;
+			ret=client_hello(s);
+			if (ret <= 0) goto end;
+			s->init_num=0;
+			s->state=SSL2_ST_GET_SERVER_HELLO_A;
+			BREAK;
+		
+		case SSL2_ST_GET_SERVER_HELLO_A:
+		case SSL2_ST_GET_SERVER_HELLO_B:
+			ret=get_server_hello(s);
+			if (ret <= 0) goto end;
+			s->init_num=0;
+			if (!s->hit) /* new session */
+				{
+				s->state=SSL2_ST_SEND_CLIENT_MASTER_KEY_A;
+				BREAK; 
+				}
+			else
+				{
+				s->state=SSL2_ST_CLIENT_START_ENCRYPTION;
+				break;
+				}
+	
+		case SSL2_ST_SEND_CLIENT_MASTER_KEY_A:
+		case SSL2_ST_SEND_CLIENT_MASTER_KEY_B:
+			ret=client_master_key(s);
+			if (ret <= 0) goto end;
+			s->init_num=0;
+			s->state=SSL2_ST_CLIENT_START_ENCRYPTION;
+			break;
+
+		case SSL2_ST_CLIENT_START_ENCRYPTION:
+			/* Ok, we now have all the stuff needed to
+			 * start encrypting, so lets fire it up :-) */
+			if (!ssl2_enc_init(s,1))
+				{
+				ret= -1;
+				goto end;
+				}
+			s->s2->clear_text=0;
+			s->state=SSL2_ST_SEND_CLIENT_FINISHED_A;
+			break;
+
+		case SSL2_ST_SEND_CLIENT_FINISHED_A:
+		case SSL2_ST_SEND_CLIENT_FINISHED_B:
+			ret=client_finished(s);
+			if (ret <= 0) goto end;
+			s->init_num=0;
+			s->state=SSL2_ST_GET_SERVER_VERIFY_A;
+			break;
+
+		case SSL2_ST_GET_SERVER_VERIFY_A:
+		case SSL2_ST_GET_SERVER_VERIFY_B:
+			ret=get_server_verify(s);
+			if (ret <= 0) goto end;
+			s->init_num=0;
+			s->state=SSL2_ST_GET_SERVER_FINISHED_A;
+			break;
+
+		case SSL2_ST_GET_SERVER_FINISHED_A:
+		case SSL2_ST_GET_SERVER_FINISHED_B:
+			ret=get_server_finished(s);
+			if (ret <= 0) goto end;
+			break;
+
+		case SSL2_ST_SEND_CLIENT_CERTIFICATE_A:
+		case SSL2_ST_SEND_CLIENT_CERTIFICATE_B:
+		case SSL2_ST_SEND_CLIENT_CERTIFICATE_C:
+		case SSL2_ST_SEND_CLIENT_CERTIFICATE_D:
+		case SSL2_ST_X509_GET_CLIENT_CERTIFICATE:
+			ret=client_certificate(s);
+			if (ret <= 0) goto end;
+			s->init_num=0;
+			s->state=SSL2_ST_GET_SERVER_FINISHED_A;
+			break;
+
+		case SSL_ST_OK:
+			if (s->init_buf != NULL)
+				{
+				BUF_MEM_free(s->init_buf);
+				s->init_buf=NULL;
+				}
+			s->init_num=0;
+		/*	ERR_clear_error();*/
+
+			/* If we want to cache session-ids in the client
+			 * and we successfully add the session-id to the
+			 * cache, and there is a callback, then pass it out.
+			 * 26/11/96 - eay - only add if not a re-used session.
+			 */
+
+			ssl_update_cache(s,SSL_SESS_CACHE_CLIENT);
+			if (s->hit) s->ctx->stats.sess_hit++;
+
+			ret=1;
+			/* s->server=0; */
+			s->ctx->stats.sess_connect_good++;
+
+			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
+
+			goto end;
+			/* break; */
+		default:
+			SSLerr(SSL_F_SSL2_CONNECT,SSL_R_UNKNOWN_STATE);
+			return(-1);
+			/* break; */
+			}
+
+		if ((cb != NULL) && (s->state != state))
+			{
+			new_state=s->state;
+			s->state=state;
+			cb(s,SSL_CB_CONNECT_LOOP,1);
+			s->state=new_state;
+			}
+		}
+end:
+	s->in_handshake--;
+	if (buf != NULL)
+		BUF_MEM_free(buf);
+	if (cb != NULL) 
+		cb(s,SSL_CB_CONNECT_EXIT,ret);
+	return(ret);
+	}
+
+static int get_server_hello(SSL *s)
+	{
+	unsigned char *buf;
+	unsigned char *p;
+	int i,j;
+	unsigned long len;
+	STACK_OF(SSL_CIPHER) *sk=NULL,*cl, *prio, *allow;
+
+	buf=(unsigned char *)s->init_buf->data;
+	p=buf;
+	if (s->state == SSL2_ST_GET_SERVER_HELLO_A)
+		{
+		i=ssl2_read(s,(char *)&(buf[s->init_num]),11-s->init_num);
+		if (i < (11-s->init_num)) 
+			return(ssl2_part_read(s,SSL_F_GET_SERVER_HELLO,i));
+		s->init_num = 11;
+
+		if (*(p++) != SSL2_MT_SERVER_HELLO)
+			{
+			if (p[-1] != SSL2_MT_ERROR)
+				{
+				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+				SSLerr(SSL_F_GET_SERVER_HELLO,
+					SSL_R_READ_WRONG_PACKET_TYPE);
+				}
+			else
+				SSLerr(SSL_F_GET_SERVER_HELLO,
+					SSL_R_PEER_ERROR);
+			return(-1);
+			}
+#ifdef __APPLE_CC__
+		/* The Rhapsody 5.5 (a.k.a. MacOS X) compiler bug
+		 * workaround. <appro@fy.chalmers.se> */
+		s->hit=(i=*(p++))?1:0;
+#else
+		s->hit=(*(p++))?1:0;
+#endif
+		s->s2->tmp.cert_type= *(p++);
+		n2s(p,i);
+		if (i < s->version) s->version=i;
+		n2s(p,i); s->s2->tmp.cert_length=i;
+		n2s(p,i); s->s2->tmp.csl=i;
+		n2s(p,i); s->s2->tmp.conn_id_length=i;
+		s->state=SSL2_ST_GET_SERVER_HELLO_B;
+		}
+
+	/* SSL2_ST_GET_SERVER_HELLO_B */
+	len = 11 + (unsigned long)s->s2->tmp.cert_length + (unsigned long)s->s2->tmp.csl + (unsigned long)s->s2->tmp.conn_id_length;
+	if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
+		{
+		SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_MESSAGE_TOO_LONG);
+		return -1;
+		}
+	j = (int)len - s->init_num;
+	i = ssl2_read(s,(char *)&(buf[s->init_num]),j);
+	if (i != j) return(ssl2_part_read(s,SSL_F_GET_SERVER_HELLO,i));
+	if (s->msg_callback)
+		s->msg_callback(0, s->version, 0, buf, (size_t)len, s, s->msg_callback_arg); /* SERVER-HELLO */
+
+	/* things are looking good */
+
+	p = buf + 11;
+	if (s->hit)
+		{
+		if (s->s2->tmp.cert_length != 0) 
+			{
+			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CERT_LENGTH_NOT_ZERO);
+			return(-1);
+			}
+		if (s->s2->tmp.cert_type != 0)
+			{
+			if (!(s->options &
+				SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG))
+				{
+				SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CERT_TYPE_NOT_ZERO);
+				return(-1);
+				}
+			}
+		if (s->s2->tmp.csl != 0)
+			{
+			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CIPHER_LIST_NOT_ZERO);
+			return(-1);
+			}
+		}
+	else
+		{
+#ifdef undef
+		/* very bad */
+		memset(s->session->session_id,0,
+			SSL_MAX_SSL_SESSION_ID_LENGTH_IN_BYTES);
+		s->session->session_id_length=0;
+		*/
+#endif
+
+		/* we need to do this in case we were trying to reuse a 
+		 * client session but others are already reusing it.
+		 * If this was a new 'blank' session ID, the session-id
+		 * length will still be 0 */
+		if (s->session->session_id_length > 0)
+			{
+			if (!ssl_get_new_session(s,0))
+				{
+				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+				return(-1);
+				}
+			}
+
+		if (ssl2_set_certificate(s,s->s2->tmp.cert_type,
+			s->s2->tmp.cert_length,p) <= 0)
+			{
+			ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
+			return(-1);
+			}
+		p+=s->s2->tmp.cert_length;
+
+		if (s->s2->tmp.csl == 0)
+			{
+			ssl2_return_error(s,SSL2_PE_NO_CIPHER);
+			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_NO_CIPHER_LIST);
+			return(-1);
+			}
+
+		/* We have just received a list of ciphers back from the
+		 * server.  We need to get the ones that match, then select
+		 * the one we want the most :-). */
+
+		/* load the ciphers */
+		sk=ssl_bytes_to_cipher_list(s,p,s->s2->tmp.csl,
+					    &s->session->ciphers);
+		p+=s->s2->tmp.csl;
+		if (sk == NULL)
+			{
+			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+			SSLerr(SSL_F_GET_SERVER_HELLO,ERR_R_MALLOC_FAILURE);
+			return(-1);
+			}
+
+		(void)sk_SSL_CIPHER_set_cmp_func(sk,ssl_cipher_ptr_id_cmp);
+
+		/* get the array of ciphers we will accept */
+		cl=SSL_get_ciphers(s);
+		(void)sk_SSL_CIPHER_set_cmp_func(cl,ssl_cipher_ptr_id_cmp);
+
+		/*
+		 * If server preference flag set, choose the first
+		 * (highest priority) cipher the server sends, otherwise
+		 * client preference has priority.
+		 */
+		if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
+		    {
+		    prio = sk;
+		    allow = cl;
+		    }
+		else
+		    {
+		    prio = cl;
+		    allow = sk;
+		    }
+		/* In theory we could have ciphers sent back that we
+		 * don't want to use but that does not matter since we
+		 * will check against the list we originally sent and
+		 * for performance reasons we should not bother to match
+		 * the two lists up just to check. */
+		for (i=0; i<sk_SSL_CIPHER_num(prio); i++)
+			{
+			if (sk_SSL_CIPHER_find(allow,
+					     sk_SSL_CIPHER_value(prio,i)) >= 0)
+				break;
+			}
+
+		if (i >= sk_SSL_CIPHER_num(prio))
+			{
+			ssl2_return_error(s,SSL2_PE_NO_CIPHER);
+			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_NO_CIPHER_MATCH);
+			return(-1);
+			}
+		s->session->cipher=sk_SSL_CIPHER_value(prio,i);
+
+
+		if (s->session->peer != NULL) /* can't happen*/
+			{
+			ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
+			SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
+			return(-1);
+			}
+
+		s->session->peer = s->session->sess_cert->peer_key->x509;
+		/* peer_key->x509 has been set by ssl2_set_certificate. */
+		CRYPTO_add(&s->session->peer->references, 1, CRYPTO_LOCK_X509);
+		}
+
+	if (s->session->sess_cert == NULL 
+      || s->session->peer != s->session->sess_cert->peer_key->x509)
+		/* can't happen */
+		{
+		ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
+		SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
+		return(-1);
+		}
+		
+	s->s2->conn_id_length=s->s2->tmp.conn_id_length;
+	if (s->s2->conn_id_length > sizeof s->s2->conn_id)
+		{
+		ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
+		SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_SSL2_CONNECTION_ID_TOO_LONG);
+		return -1;
+		}
+	memcpy(s->s2->conn_id,p,s->s2->tmp.conn_id_length);
+	return(1);
+	}
+
+static int client_hello(SSL *s)
+	{
+	unsigned char *buf;
+	unsigned char *p,*d;
+/*	CIPHER **cipher;*/
+	int i,n,j;
+
+	buf=(unsigned char *)s->init_buf->data;
+	if (s->state == SSL2_ST_SEND_CLIENT_HELLO_A)
+		{
+		if ((s->session == NULL) ||
+			(s->session->ssl_version != s->version))
+			{
+			if (!ssl_get_new_session(s,0))
+				{
+				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+				return(-1);
+				}
+			}
+		/* else use the pre-loaded session */
+
+		p=buf;					/* header */
+		d=p+9;					/* data section */
+		*(p++)=SSL2_MT_CLIENT_HELLO;		/* type */
+		s2n(SSL2_VERSION,p);			/* version */
+		n=j=0;
+
+		n=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),d,0);
+		d+=n;
+
+		if (n == 0)
+			{
+			SSLerr(SSL_F_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
+			return(-1);
+			}
+
+		s2n(n,p);			/* cipher spec num bytes */
+
+		if ((s->session->session_id_length > 0) &&
+			(s->session->session_id_length <=
+			SSL2_MAX_SSL_SESSION_ID_LENGTH))
+			{
+			i=s->session->session_id_length;
+			s2n(i,p);		/* session id length */
+			memcpy(d,s->session->session_id,(unsigned int)i);
+			d+=i;
+			}
+		else
+			{
+			s2n(0,p);
+			}
+
+		s->s2->challenge_length=SSL2_CHALLENGE_LENGTH;
+		s2n(SSL2_CHALLENGE_LENGTH,p);		/* challenge length */
+		/*challenge id data*/
+		if (RAND_pseudo_bytes(s->s2->challenge,SSL2_CHALLENGE_LENGTH) <= 0)
+			return -1;
+		memcpy(d,s->s2->challenge,SSL2_CHALLENGE_LENGTH);
+		d+=SSL2_CHALLENGE_LENGTH;
+
+		s->state=SSL2_ST_SEND_CLIENT_HELLO_B;
+		s->init_num=d-buf;
+		s->init_off=0;
+		}
+	/* SSL2_ST_SEND_CLIENT_HELLO_B */
+	return(ssl2_do_write(s));
+	}
+
+static int client_master_key(SSL *s)
+	{
+	unsigned char *buf;
+	unsigned char *p,*d;
+	int clear,enc,karg,i;
+	SSL_SESSION *sess;
+	const EVP_CIPHER *c;
+	const EVP_MD *md;
+
+	buf=(unsigned char *)s->init_buf->data;
+	if (s->state == SSL2_ST_SEND_CLIENT_MASTER_KEY_A)
+		{
+
+		if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL))
+			{
+			ssl2_return_error(s,SSL2_PE_NO_CIPHER);
+			SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
+			return(-1);
+			}
+		sess=s->session;
+		p=buf;
+		d=p+10;
+		*(p++)=SSL2_MT_CLIENT_MASTER_KEY;/* type */
+
+		i=ssl_put_cipher_by_char(s,sess->cipher,p);
+		p+=i;
+
+		/* make key_arg data */
+		i=EVP_CIPHER_iv_length(c);
+		sess->key_arg_length=i;
+		if (i > SSL_MAX_KEY_ARG_LENGTH)
+			{
+			ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
+			SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
+			return -1;
+			}
+		if (i > 0)
+			if (RAND_pseudo_bytes(sess->key_arg,i) <= 0)
+				return -1;
+
+		/* make a master key */
+		i=EVP_CIPHER_key_length(c);
+		sess->master_key_length=i;
+		if (i > 0)
+			{
+			if (i > (int)sizeof(sess->master_key))
+				{
+				ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
+				SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
+				return -1;
+				}
+			if (RAND_bytes(sess->master_key,i) <= 0)
+				{
+				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+				return(-1);
+				}
+			}
+
+		if (sess->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC)
+			enc=8;
+		else if (SSL_C_IS_EXPORT(sess->cipher))
+			enc=5;
+		else
+			enc=i;
+
+		if ((int)i < enc)
+			{
+			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+			SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_CIPHER_TABLE_SRC_ERROR);
+			return(-1);
+			}
+		clear=i-enc;
+		s2n(clear,p);
+		memcpy(d,sess->master_key,(unsigned int)clear);
+		d+=clear;
+
+		enc=ssl_rsa_public_encrypt(sess->sess_cert,enc,
+			&(sess->master_key[clear]),d,
+			(s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);
+		if (enc <= 0)
+			{
+			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+			SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PUBLIC_KEY_ENCRYPT_ERROR);
+			return(-1);
+			}
+#ifdef PKCS1_CHECK
+		if (s->options & SSL_OP_PKCS1_CHECK_1) d[1]++;
+		if (s->options & SSL_OP_PKCS1_CHECK_2)
+			sess->master_key[clear]++;
+#endif
+		s2n(enc,p);
+		d+=enc;
+		karg=sess->key_arg_length;	
+		s2n(karg,p); /* key arg size */
+		if (karg > (int)sizeof(sess->key_arg))
+			{
+			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+			SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
+			return -1;
+			}
+		memcpy(d,sess->key_arg,(unsigned int)karg);
+		d+=karg;
+
+		s->state=SSL2_ST_SEND_CLIENT_MASTER_KEY_B;
+		s->init_num=d-buf;
+		s->init_off=0;
+		}
+
+	/* SSL2_ST_SEND_CLIENT_MASTER_KEY_B */
+	return(ssl2_do_write(s));
+	}
+
+static int client_finished(SSL *s)
+	{
+	unsigned char *p;
+
+	if (s->state == SSL2_ST_SEND_CLIENT_FINISHED_A)
+		{
+		p=(unsigned char *)s->init_buf->data;
+		*(p++)=SSL2_MT_CLIENT_FINISHED;
+		if (s->s2->conn_id_length > sizeof s->s2->conn_id)
+			{
+			SSLerr(SSL_F_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR);
+			return -1;
+			}
+		memcpy(p,s->s2->conn_id,(unsigned int)s->s2->conn_id_length);
+
+		s->state=SSL2_ST_SEND_CLIENT_FINISHED_B;
+		s->init_num=s->s2->conn_id_length+1;
+		s->init_off=0;
+		}
+	return(ssl2_do_write(s));
+	}
+
+/* read the data and then respond */
+static int client_certificate(SSL *s)
+	{
+	unsigned char *buf;
+	unsigned char *p,*d;
+	int i;
+	unsigned int n;
+	int cert_ch_len;
+	unsigned char *cert_ch;
+
+	buf=(unsigned char *)s->init_buf->data;
+
+	/* We have a cert associated with the SSL, so attach it to
+	 * the session if it does not have one */
+
+	if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_A)
+		{
+		i=ssl2_read(s,(char *)&(buf[s->init_num]),
+			SSL2_MAX_CERT_CHALLENGE_LENGTH+2-s->init_num);
+		if (i<(SSL2_MIN_CERT_CHALLENGE_LENGTH+2-s->init_num))
+			return(ssl2_part_read(s,SSL_F_CLIENT_CERTIFICATE,i));
+		s->init_num += i;
+		if (s->msg_callback)
+			s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, s->msg_callback_arg); /* REQUEST-CERTIFICATE */
+
+		/* type=buf[0]; */
+		/* type eq x509 */
+		if (buf[1] != SSL2_AT_MD5_WITH_RSA_ENCRYPTION)
+			{
+			ssl2_return_error(s,SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE);
+			SSLerr(SSL_F_CLIENT_CERTIFICATE,SSL_R_BAD_AUTHENTICATION_TYPE);
+			return(-1);
+			}
+
+		if ((s->cert == NULL) ||
+			(s->cert->key->x509 == NULL) ||
+			(s->cert->key->privatekey == NULL))
+			{
+			s->state=SSL2_ST_X509_GET_CLIENT_CERTIFICATE;
+			}
+		else
+			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_C;
+		}
+
+	cert_ch = buf + 2;
+	cert_ch_len = s->init_num - 2;
+
+	if (s->state == SSL2_ST_X509_GET_CLIENT_CERTIFICATE)
+		{
+		X509 *x509=NULL;
+		EVP_PKEY *pkey=NULL;
+
+		/* If we get an error we need to
+		 * ssl->rwstate=SSL_X509_LOOKUP;
+		 * return(error);
+		 * We should then be retried when things are ok and we
+		 * can get a cert or not */
+
+		i=0;
+		if (s->ctx->client_cert_cb != NULL)
+			{
+			i=s->ctx->client_cert_cb(s,&(x509),&(pkey));
+			}
+
+		if (i < 0)
+			{
+			s->rwstate=SSL_X509_LOOKUP;
+			return(-1);
+			}
+		s->rwstate=SSL_NOTHING;
+
+		if ((i == 1) && (pkey != NULL) && (x509 != NULL))
+			{
+			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_C;
+			if (	!SSL_use_certificate(s,x509) || 
+				!SSL_use_PrivateKey(s,pkey))
+				{
+				i=0;
+				}
+			X509_free(x509);
+			EVP_PKEY_free(pkey);
+			}
+		else if (i == 1)
+			{
+			if (x509 != NULL) X509_free(x509);
+			if (pkey != NULL) EVP_PKEY_free(pkey);
+			SSLerr(SSL_F_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
+			i=0;
+			}
+
+		if (i == 0)
+			{
+			/* We have no client certificate to respond with
+			 * so send the correct error message back */
+			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_B;
+			p=buf;
+			*(p++)=SSL2_MT_ERROR;
+			s2n(SSL2_PE_NO_CERTIFICATE,p);
+			s->init_off=0;
+			s->init_num=3;
+			/* Write is done at the end */
+			}
+		}
+
+	if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_B)
+		{
+		return(ssl2_do_write(s));
+		}
+
+	if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_C)
+		{
+		EVP_MD_CTX ctx;
+
+		/* ok, now we calculate the checksum
+		 * do it first so we can reuse buf :-) */
+		p=buf;
+		EVP_MD_CTX_init(&ctx);
+		EVP_SignInit_ex(&ctx,s->ctx->rsa_md5, NULL);
+		EVP_SignUpdate(&ctx,s->s2->key_material,
+			       s->s2->key_material_length);
+		EVP_SignUpdate(&ctx,cert_ch,(unsigned int)cert_ch_len);
+		i=i2d_X509(s->session->sess_cert->peer_key->x509,&p);
+		/* Don't update the signature if it fails - FIXME: probably should handle this better */
+		if(i > 0)
+			EVP_SignUpdate(&ctx,buf,(unsigned int)i);
+
+		p=buf;
+		d=p+6;
+		*(p++)=SSL2_MT_CLIENT_CERTIFICATE;
+		*(p++)=SSL2_CT_X509_CERTIFICATE;
+		n=i2d_X509(s->cert->key->x509,&d);
+		s2n(n,p);
+
+		if (!EVP_SignFinal(&ctx,d,&n,s->cert->key->privatekey))
+			{
+			/* this is not good.  If things have failed it
+			 * means there so something wrong with the key.
+			 * We will continue with a 0 length signature
+			 */
+			}
+		EVP_MD_CTX_cleanup(&ctx);
+		s2n(n,p);
+		d+=n;
+
+		s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_D;
+		s->init_num=d-buf;
+		s->init_off=0;
+		}
+	/* if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_D) */
+	return(ssl2_do_write(s));
+	}
+
+static int get_server_verify(SSL *s)
+	{
+	unsigned char *p;
+	int i, n, len;
+
+	p=(unsigned char *)s->init_buf->data;
+	if (s->state == SSL2_ST_GET_SERVER_VERIFY_A)
+		{
+		i=ssl2_read(s,(char *)&(p[s->init_num]),1-s->init_num);
+		if (i < (1-s->init_num)) 
+			return(ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i));
+		s->init_num += i;
+
+		s->state= SSL2_ST_GET_SERVER_VERIFY_B;
+		if (*p != SSL2_MT_SERVER_VERIFY)
+			{
+			if (p[0] != SSL2_MT_ERROR)
+				{
+				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+				SSLerr(SSL_F_GET_SERVER_VERIFY,
+					SSL_R_READ_WRONG_PACKET_TYPE);
+				}
+			else
+				{
+				SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_PEER_ERROR);
+				/* try to read the error message */
+				i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num);
+				return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i);
+				}
+			return(-1);
+			}
+		}
+	
+	p=(unsigned char *)s->init_buf->data;
+	len = 1 + s->s2->challenge_length;
+	n =  len - s->init_num;
+	i = ssl2_read(s,(char *)&(p[s->init_num]),n);
+	if (i < n)
+		return(ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i));
+	if (s->msg_callback)
+		s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* SERVER-VERIFY */
+	p += 1;
+
+	if (memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0)
+		{
+		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+		SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_CHALLENGE_IS_DIFFERENT);
+		return(-1);
+		}
+	return(1);
+	}
+
+static int get_server_finished(SSL *s)
+	{
+	unsigned char *buf;
+	unsigned char *p;
+	int i, n, len;
+
+	buf=(unsigned char *)s->init_buf->data;
+	p=buf;
+	if (s->state == SSL2_ST_GET_SERVER_FINISHED_A)
+		{
+		i=ssl2_read(s,(char *)&(buf[s->init_num]),1-s->init_num);
+		if (i < (1-s->init_num))
+			return(ssl2_part_read(s,SSL_F_GET_SERVER_FINISHED,i));
+		s->init_num += i;
+
+		if (*p == SSL2_MT_REQUEST_CERTIFICATE)
+			{
+			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_A;
+			return(1);
+			}
+		else if (*p != SSL2_MT_SERVER_FINISHED)
+			{
+			if (p[0] != SSL2_MT_ERROR)
+				{
+				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+				SSLerr(SSL_F_GET_SERVER_FINISHED,SSL_R_READ_WRONG_PACKET_TYPE);
+				}
+			else
+				{
+				SSLerr(SSL_F_GET_SERVER_FINISHED,SSL_R_PEER_ERROR);
+				/* try to read the error message */
+				i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num);
+				return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i);
+				}
+			return(-1);
+			}
+		s->state=SSL2_ST_GET_SERVER_FINISHED_B;
+		}
+
+	len = 1 + SSL2_SSL_SESSION_ID_LENGTH;
+	n = len - s->init_num;
+	i = ssl2_read(s,(char *)&(buf[s->init_num]), n);
+	if (i < n) /* XXX could be shorter than SSL2_SSL_SESSION_ID_LENGTH, that's the maximum */
+		return(ssl2_part_read(s,SSL_F_GET_SERVER_FINISHED,i));
+	s->init_num += i;
+	if (s->msg_callback)
+		s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, s->msg_callback_arg); /* SERVER-FINISHED */
+
+	if (!s->hit) /* new session */
+		{
+		/* new session-id */
+		/* Make sure we were not trying to re-use an old SSL_SESSION
+		 * or bad things can happen */
+		/* ZZZZZZZZZZZZZ */
+		s->session->session_id_length=SSL2_SSL_SESSION_ID_LENGTH;
+		memcpy(s->session->session_id,p+1,SSL2_SSL_SESSION_ID_LENGTH);
+		}
+	else
+		{
+		if (!(s->options & SSL_OP_MICROSOFT_SESS_ID_BUG))
+			{
+			if ((s->session->session_id_length > sizeof s->session->session_id)
+			    || (0 != memcmp(buf + 1, s->session->session_id,
+			                    (unsigned int)s->session->session_id_length)))
+				{
+				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+				SSLerr(SSL_F_GET_SERVER_FINISHED,SSL_R_SSL_SESSION_ID_IS_DIFFERENT);
+				return(-1);
+				}
+			}
+		}
+	s->state = SSL_ST_OK;
+	return(1);
+	}
+
+/* loads in the certificate from the server */
+int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data)
+	{
+	STACK_OF(X509) *sk=NULL;
+	EVP_PKEY *pkey=NULL;
+	SESS_CERT *sc=NULL;
+	int i;
+	X509 *x509=NULL;
+	int ret=0;
+	
+	x509=d2i_X509(NULL,&data,(long)len);
+	if (x509 == NULL)
+		{
+		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,ERR_R_X509_LIB);
+		goto err;
+		}
+
+	if ((sk=sk_X509_new_null()) == NULL || !sk_X509_push(sk,x509))
+		{
+		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	i=ssl_verify_cert_chain(s,sk);
+		
+	if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0))
+		{
+		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED);
+		goto err;
+		}
+	ERR_clear_error(); /* but we keep s->verify_result */
+	s->session->verify_result = s->verify_result;
+
+	/* server's cert for this session */
+	sc=ssl_sess_cert_new();
+	if (sc == NULL)
+		{
+		ret= -1;
+		goto err;
+		}
+	if (s->session->sess_cert) ssl_sess_cert_free(s->session->sess_cert);
+	s->session->sess_cert=sc;
+
+	sc->peer_pkeys[SSL_PKEY_RSA_ENC].x509=x509;
+	sc->peer_key= &(sc->peer_pkeys[SSL_PKEY_RSA_ENC]);
+
+	pkey=X509_get_pubkey(x509);
+	x509=NULL;
+	if (pkey == NULL)
+		{
+		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY);
+		goto err;
+		}
+	if (pkey->type != EVP_PKEY_RSA)
+		{
+		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_PUBLIC_KEY_NOT_RSA);
+		goto err;
+		}
+
+	if (!ssl_set_peer_cert_type(sc,SSL2_CT_X509_CERTIFICATE))
+		goto err;
+	ret=1;
+err:
+	sk_X509_free(sk);
+	X509_free(x509);
+	EVP_PKEY_free(pkey);
+	return(ret);
+	}
+
+static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from,
+	     unsigned char *to, int padding)
+	{
+	EVP_PKEY *pkey=NULL;
+	int i= -1;
+
+	if ((sc == NULL) || (sc->peer_key->x509 == NULL) ||
+		((pkey=X509_get_pubkey(sc->peer_key->x509)) == NULL))
+		{
+		SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT,SSL_R_NO_PUBLICKEY);
+		return(-1);
+		}
+	if (pkey->type != EVP_PKEY_RSA)
+		{
+		SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT,SSL_R_PUBLIC_KEY_IS_NOT_RSA);
+		goto end;
+		}
+
+	/* we have the public key */
+	i=RSA_public_encrypt(len,from,to,pkey->pkey.rsa,padding);
+	if (i < 0)
+		SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT,ERR_R_RSA_LIB);
+end:
+	EVP_PKEY_free(pkey);
+	return(i);
+	}
+#else /* !OPENSSL_NO_SSL2 */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/ssl/s2_enc.c b/openssl/ssl/s2_enc.c
new file mode 100644
index 0000000..ff3395f
--- /dev/null
+++ b/openssl/ssl/s2_enc.c
@@ -0,0 +1,193 @@
+/* ssl/s2_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "ssl_locl.h"
+#ifndef OPENSSL_NO_SSL2
+#include <stdio.h>
+
+int ssl2_enc_init(SSL *s, int client)
+	{
+	/* Max number of bytes needed */
+	EVP_CIPHER_CTX *rs,*ws;
+	const EVP_CIPHER *c;
+	const EVP_MD *md;
+	int num;
+
+	if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL))
+		{
+		ssl2_return_error(s,SSL2_PE_NO_CIPHER);
+		SSLerr(SSL_F_SSL2_ENC_INIT,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
+		return(0);
+		}
+	ssl_replace_hash(&s->read_hash,md);
+	ssl_replace_hash(&s->write_hash,md);
+
+	if ((s->enc_read_ctx == NULL) &&
+		((s->enc_read_ctx=(EVP_CIPHER_CTX *)
+		OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL))
+		goto err;
+
+	/* make sure it's intialized in case the malloc for enc_write_ctx fails
+	 * and we exit with an error */
+	rs= s->enc_read_ctx;
+	EVP_CIPHER_CTX_init(rs);
+
+	if ((s->enc_write_ctx == NULL) &&
+		((s->enc_write_ctx=(EVP_CIPHER_CTX *)
+		OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL))
+		goto err;
+
+	ws= s->enc_write_ctx;
+	EVP_CIPHER_CTX_init(ws);
+
+	num=c->key_len;
+	s->s2->key_material_length=num*2;
+	OPENSSL_assert(s->s2->key_material_length <= sizeof s->s2->key_material);
+
+	if (ssl2_generate_key_material(s) <= 0)
+		return 0;
+
+	OPENSSL_assert(c->iv_len <= (int)sizeof(s->session->key_arg));
+	EVP_EncryptInit_ex(ws,c,NULL,&(s->s2->key_material[(client)?num:0]),
+		s->session->key_arg);
+	EVP_DecryptInit_ex(rs,c,NULL,&(s->s2->key_material[(client)?0:num]),
+		s->session->key_arg);
+	s->s2->read_key=  &(s->s2->key_material[(client)?0:num]);
+	s->s2->write_key= &(s->s2->key_material[(client)?num:0]);
+	return(1);
+err:
+	SSLerr(SSL_F_SSL2_ENC_INIT,ERR_R_MALLOC_FAILURE);
+	return(0);
+	}
+
+/* read/writes from s->s2->mac_data using length for encrypt and 
+ * decrypt.  It sets s->s2->padding and s->[rw]length
+ * if we are encrypting */
+void ssl2_enc(SSL *s, int send)
+	{
+	EVP_CIPHER_CTX *ds;
+	unsigned long l;
+	int bs;
+
+	if (send)
+		{
+		ds=s->enc_write_ctx;
+		l=s->s2->wlength;
+		}
+	else
+		{
+		ds=s->enc_read_ctx;
+		l=s->s2->rlength;
+		}
+
+	/* check for NULL cipher */
+	if (ds == NULL) return;
+
+
+	bs=ds->cipher->block_size;
+	/* This should be using (bs-1) and bs instead of 7 and 8, but
+	 * what the hell. */
+	if (bs == 8)
+		l=(l+7)/8*8;
+
+	EVP_Cipher(ds,s->s2->mac_data,s->s2->mac_data,l);
+	}
+
+void ssl2_mac(SSL *s, unsigned char *md, int send)
+	{
+	EVP_MD_CTX c;
+	unsigned char sequence[4],*p,*sec,*act;
+	unsigned long seq;
+	unsigned int len;
+
+	if (send)
+		{
+		seq=s->s2->write_sequence;
+		sec=s->s2->write_key;
+		len=s->s2->wact_data_length;
+		act=s->s2->wact_data;
+		}
+	else
+		{
+		seq=s->s2->read_sequence;
+		sec=s->s2->read_key;
+		len=s->s2->ract_data_length;
+		act=s->s2->ract_data;
+		}
+
+	p= &(sequence[0]);
+	l2n(seq,p);
+
+	/* There has to be a MAC algorithm. */
+	EVP_MD_CTX_init(&c);
+	EVP_MD_CTX_copy(&c, s->read_hash);
+	EVP_DigestUpdate(&c,sec,
+		EVP_CIPHER_CTX_key_length(s->enc_read_ctx));
+	EVP_DigestUpdate(&c,act,len); 
+	/* the above line also does the pad data */
+	EVP_DigestUpdate(&c,sequence,4); 
+	EVP_DigestFinal_ex(&c,md,NULL);
+	EVP_MD_CTX_cleanup(&c);
+	}
+#else /* !OPENSSL_NO_SSL2 */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/ssl/s2_lib.c b/openssl/ssl/s2_lib.c
new file mode 100644
index 0000000..9914604
--- /dev/null
+++ b/openssl/ssl/s2_lib.c
@@ -0,0 +1,556 @@
+/* ssl/s2_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "ssl_locl.h"
+#ifndef OPENSSL_NO_SSL2
+#include <stdio.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/md5.h>
+
+const char ssl2_version_str[]="SSLv2" OPENSSL_VERSION_PTEXT;
+
+#define SSL2_NUM_CIPHERS (sizeof(ssl2_ciphers)/sizeof(SSL_CIPHER))
+
+/* list of available SSLv2 ciphers (sorted by id) */
+OPENSSL_GLOBAL const SSL_CIPHER ssl2_ciphers[]={
+#if 0
+/* NULL_WITH_MD5 v3 */
+	{
+	1,
+	SSL2_TXT_NULL_WITH_MD5,
+	SSL2_CK_NULL_WITH_MD5,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_eNULL,
+	SSL_MD5,
+	SSL_SSLV2,
+	SSL_EXPORT|SSL_EXP40|SSL_STRONG_NONE,
+	0,
+	0,
+	0,
+	},
+#endif
+
+/* RC4_128_WITH_MD5 */
+	{
+	1,
+	SSL2_TXT_RC4_128_WITH_MD5,
+	SSL2_CK_RC4_128_WITH_MD5,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV2,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	0,
+	128,
+	128,
+	},
+
+/* RC4_128_EXPORT40_WITH_MD5 */
+	{
+	1,
+	SSL2_TXT_RC4_128_EXPORT40_WITH_MD5,
+	SSL2_CK_RC4_128_EXPORT40_WITH_MD5,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV2,
+	SSL_EXPORT|SSL_EXP40,
+	SSL2_CF_5_BYTE_ENC,
+	40,
+	128,
+	},
+
+/* RC2_128_CBC_WITH_MD5 */
+	{
+	1,
+	SSL2_TXT_RC2_128_CBC_WITH_MD5,
+	SSL2_CK_RC2_128_CBC_WITH_MD5,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC2,
+	SSL_MD5,
+	SSL_SSLV2,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	0,
+	128,
+	128,
+	},
+
+/* RC2_128_CBC_EXPORT40_WITH_MD5 */
+	{
+	1,
+	SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5,
+	SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC2,
+	SSL_MD5,
+	SSL_SSLV2,
+	SSL_EXPORT|SSL_EXP40,
+	SSL2_CF_5_BYTE_ENC,
+	40,
+	128,
+	},
+
+#ifndef OPENSSL_NO_IDEA
+/* IDEA_128_CBC_WITH_MD5 */
+	{
+	1,
+	SSL2_TXT_IDEA_128_CBC_WITH_MD5,
+	SSL2_CK_IDEA_128_CBC_WITH_MD5,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_IDEA,
+	SSL_MD5,
+	SSL_SSLV2,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	0,
+	128,
+	128,
+	},
+#endif
+
+/* DES_64_CBC_WITH_MD5 */
+	{
+	1,
+	SSL2_TXT_DES_64_CBC_WITH_MD5,
+	SSL2_CK_DES_64_CBC_WITH_MD5,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_DES,
+	SSL_MD5,
+	SSL_SSLV2,
+	SSL_NOT_EXP|SSL_LOW,
+	0,
+	56,
+	56,
+	},
+
+/* DES_192_EDE3_CBC_WITH_MD5 */
+	{
+	1,
+	SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5,
+	SSL2_CK_DES_192_EDE3_CBC_WITH_MD5,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_3DES,
+	SSL_MD5,
+	SSL_SSLV2,
+	SSL_NOT_EXP|SSL_HIGH,
+	0,
+	168,
+	168,
+	},
+
+#if 0
+/* RC4_64_WITH_MD5 */
+	{
+	1,
+	SSL2_TXT_RC4_64_WITH_MD5,
+	SSL2_CK_RC4_64_WITH_MD5,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV2,
+	SSL_NOT_EXP|SSL_LOW,
+	SSL2_CF_8_BYTE_ENC,
+	64,
+	64,
+	},
+#endif
+
+#if 0
+/* NULL SSLeay (testing) */
+	{	
+	0,
+	SSL2_TXT_NULL,
+	SSL2_CK_NULL,
+	0,
+	0,
+	0,
+	0,
+	SSL_SSLV2,
+	SSL_STRONG_NONE,
+	0,
+	0,
+	0,
+	},
+#endif
+
+/* end of list :-) */
+	};
+
+long ssl2_default_timeout(void)
+	{
+	return(300);
+	}
+
+int ssl2_num_ciphers(void)
+	{
+	return(SSL2_NUM_CIPHERS);
+	}
+
+const SSL_CIPHER *ssl2_get_cipher(unsigned int u)
+	{
+	if (u < SSL2_NUM_CIPHERS)
+		return(&(ssl2_ciphers[SSL2_NUM_CIPHERS-1-u]));
+	else
+		return(NULL);
+	}
+
+int ssl2_pending(const SSL *s)
+	{
+	return SSL_in_init(s) ? 0 : s->s2->ract_data_length;
+	}
+
+int ssl2_new(SSL *s)
+	{
+	SSL2_STATE *s2;
+
+	if ((s2=OPENSSL_malloc(sizeof *s2)) == NULL) goto err;
+	memset(s2,0,sizeof *s2);
+
+#if SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER + 3 > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2
+#  error "assertion failed"
+#endif
+
+	if ((s2->rbuf=OPENSSL_malloc(
+		SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2)) == NULL) goto err;
+	/* wbuf needs one byte more because when using two-byte headers,
+	 * we leave the first byte unused in do_ssl_write (s2_pkt.c) */
+	if ((s2->wbuf=OPENSSL_malloc(
+		SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+3)) == NULL) goto err;
+	s->s2=s2;
+
+	ssl2_clear(s);
+	return(1);
+err:
+	if (s2 != NULL)
+		{
+		if (s2->wbuf != NULL) OPENSSL_free(s2->wbuf);
+		if (s2->rbuf != NULL) OPENSSL_free(s2->rbuf);
+		OPENSSL_free(s2);
+		}
+	return(0);
+	}
+
+void ssl2_free(SSL *s)
+	{
+	SSL2_STATE *s2;
+
+	if(s == NULL)
+	    return;
+
+	s2=s->s2;
+	if (s2->rbuf != NULL) OPENSSL_free(s2->rbuf);
+	if (s2->wbuf != NULL) OPENSSL_free(s2->wbuf);
+	OPENSSL_cleanse(s2,sizeof *s2);
+	OPENSSL_free(s2);
+	s->s2=NULL;
+	}
+
+void ssl2_clear(SSL *s)
+	{
+	SSL2_STATE *s2;
+	unsigned char *rbuf,*wbuf;
+
+	s2=s->s2;
+
+	rbuf=s2->rbuf;
+	wbuf=s2->wbuf;
+
+	memset(s2,0,sizeof *s2);
+
+	s2->rbuf=rbuf;
+	s2->wbuf=wbuf;
+	s2->clear_text=1;
+	s->packet=s2->rbuf;
+	s->version=SSL2_VERSION;
+	s->packet_length=0;
+	}
+
+long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg)
+	{
+	int ret=0;
+
+	switch(cmd)
+		{
+	case SSL_CTRL_GET_SESSION_REUSED:
+		ret=s->hit;
+		break;
+	default:
+		break;
+		}
+	return(ret);
+	}
+
+long ssl2_callback_ctrl(SSL *s, int cmd, void (*fp)(void))
+	{
+	return(0);
+	}
+
+long ssl2_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
+	{
+	return(0);
+	}
+
+long ssl2_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
+	{
+	return(0);
+	}
+
+/* This function needs to check if the ciphers required are actually
+ * available */
+const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p)
+	{
+	SSL_CIPHER c;
+	const SSL_CIPHER *cp;
+	unsigned long id;
+
+	id=0x02000000L|((unsigned long)p[0]<<16L)|
+		((unsigned long)p[1]<<8L)|(unsigned long)p[2];
+	c.id=id;
+	cp = OBJ_bsearch_ssl_cipher_id(&c, ssl2_ciphers, SSL2_NUM_CIPHERS);
+	if ((cp == NULL) || (cp->valid == 0))
+		return NULL;
+	else
+		return cp;
+	}
+
+int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
+	{
+	long l;
+
+	if (p != NULL)
+		{
+		l=c->id;
+		if ((l & 0xff000000) != 0x02000000) return(0);
+		p[0]=((unsigned char)(l>>16L))&0xFF;
+		p[1]=((unsigned char)(l>> 8L))&0xFF;
+		p[2]=((unsigned char)(l     ))&0xFF;
+		}
+	return(3);
+	}
+
+int ssl2_generate_key_material(SSL *s)
+	{
+	unsigned int i;
+	EVP_MD_CTX ctx;
+	unsigned char *km;
+	unsigned char c='0';
+	const EVP_MD *md5;
+	int md_size;
+
+	md5 = EVP_md5();
+
+#ifdef CHARSET_EBCDIC
+	c = os_toascii['0']; /* Must be an ASCII '0', not EBCDIC '0',
+				see SSLv2 docu */
+#endif
+	EVP_MD_CTX_init(&ctx);
+	km=s->s2->key_material;
+
+ 	if (s->session->master_key_length < 0 ||
+			s->session->master_key_length > (int)sizeof(s->session->master_key))
+ 		{
+ 		SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR);
+ 		return 0;
+ 		}
+	md_size = EVP_MD_size(md5);
+	if (md_size < 0)
+	    return 0;
+	for (i=0; i<s->s2->key_material_length; i += md_size)
+		{
+		if (((km - s->s2->key_material) + md_size) >
+				(int)sizeof(s->s2->key_material))
+			{
+			/* EVP_DigestFinal_ex() below would write beyond buffer */
+			SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR);
+			return 0;
+			}
+
+		EVP_DigestInit_ex(&ctx, md5, NULL);
+
+		OPENSSL_assert(s->session->master_key_length >= 0
+		    && s->session->master_key_length
+		    < (int)sizeof(s->session->master_key));
+		EVP_DigestUpdate(&ctx,s->session->master_key,s->session->master_key_length);
+		EVP_DigestUpdate(&ctx,&c,1);
+		c++;
+		EVP_DigestUpdate(&ctx,s->s2->challenge,s->s2->challenge_length);
+		EVP_DigestUpdate(&ctx,s->s2->conn_id,s->s2->conn_id_length);
+		EVP_DigestFinal_ex(&ctx,km,NULL);
+		km += md_size;
+		}
+
+	EVP_MD_CTX_cleanup(&ctx);
+	return 1;
+	}
+
+void ssl2_return_error(SSL *s, int err)
+	{
+	if (!s->error)
+		{
+		s->error=3;
+		s->error_code=err;
+
+		ssl2_write_error(s);
+		}
+	}
+
+
+void ssl2_write_error(SSL *s)
+	{
+	unsigned char buf[3];
+	int i,error;
+
+	buf[0]=SSL2_MT_ERROR;
+	buf[1]=(s->error_code>>8)&0xff;
+	buf[2]=(s->error_code)&0xff;
+
+/*	state=s->rwstate;*/
+
+	error=s->error; /* number of bytes left to write */
+	s->error=0;
+	OPENSSL_assert(error >= 0 && error <= (int)sizeof(buf));
+	i=ssl2_write(s,&(buf[3-error]),error);
+
+/*	if (i == error) s->rwstate=state; */
+
+	if (i < 0)
+		s->error=error;
+	else
+		{
+		s->error=error-i;
+
+		if (s->error == 0)
+			if (s->msg_callback)
+				s->msg_callback(1, s->version, 0, buf, 3, s, s->msg_callback_arg); /* ERROR */
+		}
+	}
+
+int ssl2_shutdown(SSL *s)
+	{
+	s->shutdown=(SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+	return(1);
+	}
+#else /* !OPENSSL_NO_SSL2 */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/ssl/s2_meth.c b/openssl/ssl/s2_meth.c
new file mode 100644
index 0000000..f0e8ca5
--- /dev/null
+++ b/openssl/ssl/s2_meth.c
@@ -0,0 +1,84 @@
+/* ssl/s2_meth.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "ssl_locl.h"
+#ifndef OPENSSL_NO_SSL2
+#include <stdio.h>
+#include <openssl/objects.h>
+
+static const SSL_METHOD *ssl2_get_method(int ver);
+static const SSL_METHOD *ssl2_get_method(int ver)
+	{
+	if (ver == SSL2_VERSION)
+		return(SSLv2_method());
+	else
+		return(NULL);
+	}
+
+IMPLEMENT_ssl2_meth_func(SSLv2_method,
+			 ssl2_accept,
+			 ssl2_connect,
+			 ssl2_get_method)
+
+#else /* !OPENSSL_NO_SSL2 */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/ssl/s2_pkt.c b/openssl/ssl/s2_pkt.c
new file mode 100644
index 0000000..ac963b2
--- /dev/null
+++ b/openssl/ssl/s2_pkt.c
@@ -0,0 +1,744 @@
+/* ssl/s2_pkt.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "ssl_locl.h"
+#ifndef OPENSSL_NO_SSL2
+#include <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+
+static int read_n(SSL *s,unsigned int n,unsigned int max,unsigned int extend);
+static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len);
+static int write_pending(SSL *s, const unsigned char *buf, unsigned int len);
+static int ssl_mt_error(int n);
+
+
+/* SSL 2.0 imlementation for SSL_read/SSL_peek -
+ * This routine will return 0 to len bytes, decrypted etc if required.
+ */
+static int ssl2_read_internal(SSL *s, void *buf, int len, int peek)
+	{
+	int n;
+	unsigned char mac[MAX_MAC_SIZE];
+	unsigned char *p;
+	int i;
+	int mac_size;
+
+ ssl2_read_again:
+	if (SSL_in_init(s) && !s->in_handshake)
+		{
+		n=s->handshake_func(s);
+		if (n < 0) return(n);
+		if (n == 0)
+			{
+			SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_SSL_HANDSHAKE_FAILURE);
+			return(-1);
+			}
+		}
+
+	clear_sys_error();
+	s->rwstate=SSL_NOTHING;
+	if (len <= 0) return(len);
+
+	if (s->s2->ract_data_length != 0) /* read from buffer */
+		{
+		if (len > s->s2->ract_data_length)
+			n=s->s2->ract_data_length;
+		else
+			n=len;
+
+		memcpy(buf,s->s2->ract_data,(unsigned int)n);
+		if (!peek)
+			{
+			s->s2->ract_data_length-=n;
+			s->s2->ract_data+=n;
+			if (s->s2->ract_data_length == 0)
+				s->rstate=SSL_ST_READ_HEADER;
+			}
+
+		return(n);
+		}
+
+	/* s->s2->ract_data_length == 0
+	 * 
+	 * Fill the buffer, then goto ssl2_read_again.
+	 */
+
+	if (s->rstate == SSL_ST_READ_HEADER)
+		{
+		if (s->first_packet)
+			{
+			n=read_n(s,5,SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2,0);
+			if (n <= 0) return(n); /* error or non-blocking */
+			s->first_packet=0;
+			p=s->packet;
+			if (!((p[0] & 0x80) && (
+				(p[2] == SSL2_MT_CLIENT_HELLO) ||
+				(p[2] == SSL2_MT_SERVER_HELLO))))
+				{
+				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_NON_SSLV2_INITIAL_PACKET);
+				return(-1);
+				}
+			}
+		else
+			{
+			n=read_n(s,2,SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2,0);
+			if (n <= 0) return(n); /* error or non-blocking */
+			}
+		/* part read stuff */
+
+		s->rstate=SSL_ST_READ_BODY;
+		p=s->packet;
+		/* Do header */
+		/*s->s2->padding=0;*/
+		s->s2->escape=0;
+		s->s2->rlength=(((unsigned int)p[0])<<8)|((unsigned int)p[1]);
+		if ((p[0] & TWO_BYTE_BIT))		/* Two byte header? */
+			{
+			s->s2->three_byte_header=0;
+			s->s2->rlength&=TWO_BYTE_MASK;	
+			}
+		else
+			{
+			s->s2->three_byte_header=1;
+			s->s2->rlength&=THREE_BYTE_MASK;
+
+			/* security >s2->escape */
+			s->s2->escape=((p[0] & SEC_ESC_BIT))?1:0;
+			}
+		}
+
+	if (s->rstate == SSL_ST_READ_BODY)
+		{
+		n=s->s2->rlength+2+s->s2->three_byte_header;
+		if (n > (int)s->packet_length)
+			{
+			n-=s->packet_length;
+			i=read_n(s,(unsigned int)n,(unsigned int)n,1);
+			if (i <= 0) return(i); /* ERROR */
+			}
+
+		p= &(s->packet[2]);
+		s->rstate=SSL_ST_READ_HEADER;
+		if (s->s2->three_byte_header)
+			s->s2->padding= *(p++);
+		else	s->s2->padding=0;
+
+		/* Data portion */
+		if (s->s2->clear_text)
+			{
+			mac_size = 0;
+			s->s2->mac_data=p;
+			s->s2->ract_data=p;
+			if (s->s2->padding)
+				{
+				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_ILLEGAL_PADDING);
+				return(-1);
+				}
+			}
+		else
+			{
+			mac_size=EVP_MD_CTX_size(s->read_hash);
+			if (mac_size < 0)
+				return -1;
+			OPENSSL_assert(mac_size <= MAX_MAC_SIZE);
+			s->s2->mac_data=p;
+			s->s2->ract_data= &p[mac_size];
+			if (s->s2->padding + mac_size > s->s2->rlength)
+				{
+				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_ILLEGAL_PADDING);
+				return(-1);
+				}
+			}
+
+		s->s2->ract_data_length=s->s2->rlength;
+		/* added a check for length > max_size in case
+		 * encryption was not turned on yet due to an error */
+		if ((!s->s2->clear_text) &&
+			(s->s2->rlength >= (unsigned int)mac_size))
+			{
+			ssl2_enc(s,0);
+			s->s2->ract_data_length-=mac_size;
+			ssl2_mac(s,mac,0);
+			s->s2->ract_data_length-=s->s2->padding;
+			if (	(memcmp(mac,s->s2->mac_data,
+				(unsigned int)mac_size) != 0) ||
+				(s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0))
+				{
+				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_MAC_DECODE);
+				return(-1);
+				}
+			}
+		INC32(s->s2->read_sequence); /* expect next number */
+		/* s->s2->ract_data is now available for processing */
+
+		/* Possibly the packet that we just read had 0 actual data bytes.
+		 * (SSLeay/OpenSSL itself never sends such packets; see ssl2_write.)
+		 * In this case, returning 0 would be interpreted by the caller
+		 * as indicating EOF, so it's not a good idea.  Instead, we just
+		 * continue reading; thus ssl2_read_internal may have to process
+		 * multiple packets before it can return.
+		 *
+		 * [Note that using select() for blocking sockets *never* guarantees
+		 * that the next SSL_read will not block -- the available
+		 * data may contain incomplete packets, and except for SSL 2,
+		 * renegotiation can confuse things even more.] */
+
+		goto ssl2_read_again; /* This should really be
+		                       * "return ssl2_read(s,buf,len)",
+		                       * but that would allow for
+		                       * denial-of-service attacks if a
+		                       * C compiler is used that does not
+		                       * recognize end-recursion. */
+		}
+	else
+		{
+		SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_STATE);
+			return(-1);
+		}
+	}
+
+int ssl2_read(SSL *s, void *buf, int len)
+	{
+	return ssl2_read_internal(s, buf, len, 0);
+	}
+
+int ssl2_peek(SSL *s, void *buf, int len)
+	{
+	return ssl2_read_internal(s, buf, len, 1);
+	}
+
+static int read_n(SSL *s, unsigned int n, unsigned int max,
+	     unsigned int extend)
+	{
+	int i,off,newb;
+
+	/* if there is stuff still in the buffer from a previous read,
+	 * and there is more than we want, take some. */
+	if (s->s2->rbuf_left >= (int)n)
+		{
+		if (extend)
+			s->packet_length+=n;
+		else
+			{
+			s->packet= &(s->s2->rbuf[s->s2->rbuf_offs]);
+			s->packet_length=n;
+			}
+		s->s2->rbuf_left-=n;
+		s->s2->rbuf_offs+=n;
+		return(n);
+		}
+
+	if (!s->read_ahead) max=n;
+	if (max > (unsigned int)(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2))
+		max=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2;
+	
+
+	/* Else we want more than we have.
+	 * First, if there is some left or we want to extend */
+	off=0;
+	if ((s->s2->rbuf_left != 0) || ((s->packet_length != 0) && extend))
+		{
+		newb=s->s2->rbuf_left;
+		if (extend)
+			{
+			off=s->packet_length;
+			if (s->packet != s->s2->rbuf)
+				memcpy(s->s2->rbuf,s->packet,
+					(unsigned int)newb+off);
+			}
+		else if (s->s2->rbuf_offs != 0)
+			{
+			memcpy(s->s2->rbuf,&(s->s2->rbuf[s->s2->rbuf_offs]),
+				(unsigned int)newb);
+			s->s2->rbuf_offs=0;
+			}
+		s->s2->rbuf_left=0;
+		}
+	else
+		newb=0;
+
+	/* off is the offset to start writing too.
+	 * r->s2->rbuf_offs is the 'unread data', now 0. 
+	 * newb is the number of new bytes so far
+	 */
+	s->packet=s->s2->rbuf;
+	while (newb < (int)n)
+		{
+		clear_sys_error();
+		if (s->rbio != NULL)
+			{
+			s->rwstate=SSL_READING;
+			i=BIO_read(s->rbio,(char *)&(s->s2->rbuf[off+newb]),
+				max-newb);
+			}
+		else
+			{
+			SSLerr(SSL_F_READ_N,SSL_R_READ_BIO_NOT_SET);
+			i= -1;
+			}
+#ifdef PKT_DEBUG
+		if (s->debug & 0x01) sleep(1);
+#endif
+		if (i <= 0)
+			{
+			s->s2->rbuf_left+=newb;
+			return(i);
+			}
+		newb+=i;
+		}
+
+	/* record unread data */
+	if (newb > (int)n)
+		{
+		s->s2->rbuf_offs=n+off;
+		s->s2->rbuf_left=newb-n;
+		}
+	else
+		{
+		s->s2->rbuf_offs=0;
+		s->s2->rbuf_left=0;
+		}
+	if (extend)
+		s->packet_length+=n;
+	else
+		s->packet_length=n;
+	s->rwstate=SSL_NOTHING;
+	return(n);
+	}
+
+int ssl2_write(SSL *s, const void *_buf, int len)
+	{
+	const unsigned char *buf=_buf;
+	unsigned int n,tot;
+	int i;
+
+	if (SSL_in_init(s) && !s->in_handshake)
+		{
+		i=s->handshake_func(s);
+		if (i < 0) return(i);
+		if (i == 0)
+			{
+			SSLerr(SSL_F_SSL2_WRITE,SSL_R_SSL_HANDSHAKE_FAILURE);
+			return(-1);
+			}
+		}
+
+	if (s->error)
+		{
+		ssl2_write_error(s);
+		if (s->error)
+			return(-1);
+		}
+
+	clear_sys_error();
+	s->rwstate=SSL_NOTHING;
+	if (len <= 0) return(len);
+
+	tot=s->s2->wnum;
+	s->s2->wnum=0;
+
+	n=(len-tot);
+	for (;;)
+		{
+		i=n_do_ssl_write(s,&(buf[tot]),n);
+		if (i <= 0)
+			{
+			s->s2->wnum=tot;
+			return(i);
+			}
+		if ((i == (int)n) ||
+			(s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))
+			{
+			return(tot+i);
+			}
+		
+		n-=i;
+		tot+=i;
+		}
+	}
+
+static int write_pending(SSL *s, const unsigned char *buf, unsigned int len)
+	{
+	int i;
+
+	/* s->s2->wpend_len != 0 MUST be true. */
+
+	/* check that they have given us the same buffer to
+	 * write */
+	if ((s->s2->wpend_tot > (int)len) ||
+		((s->s2->wpend_buf != buf) &&
+		 !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)))
+		{
+		SSLerr(SSL_F_WRITE_PENDING,SSL_R_BAD_WRITE_RETRY);
+		return(-1);
+		}
+
+	for (;;)
+		{
+		clear_sys_error();
+		if (s->wbio != NULL)
+			{
+			s->rwstate=SSL_WRITING;
+			i=BIO_write(s->wbio,
+				(char *)&(s->s2->write_ptr[s->s2->wpend_off]),
+				(unsigned int)s->s2->wpend_len);
+			}
+		else
+			{
+			SSLerr(SSL_F_WRITE_PENDING,SSL_R_WRITE_BIO_NOT_SET);
+			i= -1;
+			}
+#ifdef PKT_DEBUG
+		if (s->debug & 0x01) sleep(1);
+#endif
+		if (i == s->s2->wpend_len)
+			{
+			s->s2->wpend_len=0;
+			s->rwstate=SSL_NOTHING;
+			return(s->s2->wpend_ret);
+			}
+		else if (i <= 0)
+			return(i);
+		s->s2->wpend_off+=i;
+		s->s2->wpend_len-=i;
+		}
+	}
+
+static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
+	{
+	unsigned int j,k,olen,p,bs;
+	int mac_size;
+	register unsigned char *pp;
+
+	olen=len;
+
+	/* first check if there is data from an encryption waiting to
+	 * be sent - it must be sent because the other end is waiting.
+	 * This will happen with non-blocking IO.  We print it and then
+	 * return.
+	 */
+	if (s->s2->wpend_len != 0) return(write_pending(s,buf,len));
+
+	/* set mac_size to mac size */
+	if (s->s2->clear_text)
+		mac_size=0;
+	else
+		{
+		mac_size=EVP_MD_CTX_size(s->write_hash);
+		if (mac_size < 0)
+			return -1;
+		}
+
+	/* lets set the pad p */
+	if (s->s2->clear_text)
+		{
+		if (len > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER)
+			len=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER;
+		p=0;
+		s->s2->three_byte_header=0;
+		/* len=len; */
+		}
+	else
+		{
+		bs=EVP_CIPHER_CTX_block_size(s->enc_read_ctx);
+		j=len+mac_size;
+		/* Two-byte headers allow for a larger record length than
+		 * three-byte headers, but we can't use them if we need
+		 * padding or if we have to set the escape bit. */
+		if ((j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) &&
+			(!s->s2->escape))
+			{
+			if (j > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER)
+				j=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER;
+			/* set k to the max number of bytes with 2
+			 * byte header */
+			k=j-(j%bs);
+			/* how many data bytes? */
+			len=k-mac_size; 
+			s->s2->three_byte_header=0;
+			p=0;
+			}
+		else if ((bs <= 1) && (!s->s2->escape))
+			{
+			/* j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, thus
+			 * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER */
+			s->s2->three_byte_header=0;
+			p=0;
+			}
+		else /* we may have to use a 3 byte header */
+			{
+			/* If s->s2->escape is not set, then
+			 * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, and thus
+			 * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER. */
+			p=(j%bs);
+			p=(p == 0)?0:(bs-p);
+			if (s->s2->escape)
+				{
+				s->s2->three_byte_header=1;
+				if (j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
+					j=SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER;
+				}
+			else
+				s->s2->three_byte_header=(p == 0)?0:1;
+			}
+		}
+
+	/* Now
+	 *      j <= SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER
+	 * holds, and if s->s2->three_byte_header is set, then even
+	 *      j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER.
+	 */
+
+	/* mac_size is the number of MAC bytes
+	 * len is the number of data bytes we are going to send
+	 * p is the number of padding bytes
+	 * (if it is a two-byte header, then p == 0) */
+
+	s->s2->wlength=len;
+	s->s2->padding=p;
+	s->s2->mac_data= &(s->s2->wbuf[3]);
+	s->s2->wact_data= &(s->s2->wbuf[3+mac_size]);
+	/* we copy the data into s->s2->wbuf */
+	memcpy(s->s2->wact_data,buf,len);
+	if (p)
+		memset(&(s->s2->wact_data[len]),0,p); /* arbitrary padding */
+
+	if (!s->s2->clear_text)
+		{
+		s->s2->wact_data_length=len+p;
+		ssl2_mac(s,s->s2->mac_data,1);
+		s->s2->wlength+=p+mac_size;
+		ssl2_enc(s,1);
+		}
+
+	/* package up the header */
+	s->s2->wpend_len=s->s2->wlength;
+	if (s->s2->three_byte_header) /* 3 byte header */
+		{
+		pp=s->s2->mac_data;
+		pp-=3;
+		pp[0]=(s->s2->wlength>>8)&(THREE_BYTE_MASK>>8);
+		if (s->s2->escape) pp[0]|=SEC_ESC_BIT;
+		pp[1]=s->s2->wlength&0xff;
+		pp[2]=s->s2->padding;
+		s->s2->wpend_len+=3;
+		}
+	else
+		{
+		pp=s->s2->mac_data;
+		pp-=2;
+		pp[0]=((s->s2->wlength>>8)&(TWO_BYTE_MASK>>8))|TWO_BYTE_BIT;
+		pp[1]=s->s2->wlength&0xff;
+		s->s2->wpend_len+=2;
+		}
+	s->s2->write_ptr=pp;
+	
+	INC32(s->s2->write_sequence); /* expect next number */
+
+	/* lets try to actually write the data */
+	s->s2->wpend_tot=olen;
+	s->s2->wpend_buf=buf;
+
+	s->s2->wpend_ret=len;
+
+	s->s2->wpend_off=0;
+	return(write_pending(s,buf,olen));
+	}
+
+int ssl2_part_read(SSL *s, unsigned long f, int i)
+	{
+	unsigned char *p;
+	int j;
+
+	if (i < 0)
+		{
+		/* ssl2_return_error(s); */
+		/* for non-blocking io,
+		 * this is not necessarily fatal */
+		return(i);
+		}
+	else
+		{
+		s->init_num+=i;
+
+		/* Check for error.  While there are recoverable errors,
+		 * this function is not called when those must be expected;
+		 * any error detected here is fatal. */
+		if (s->init_num >= 3)
+			{
+			p=(unsigned char *)s->init_buf->data;
+			if (p[0] == SSL2_MT_ERROR)
+				{
+				j=(p[1]<<8)|p[2];
+				SSLerr((int)f,ssl_mt_error(j));
+				s->init_num -= 3;
+				if (s->init_num > 0)
+					memmove(p, p+3, s->init_num);
+				}
+			}
+
+		/* If it's not an error message, we have some error anyway --
+		 * the message was shorter than expected.  This too is treated
+		 * as fatal (at least if SSL_get_error is asked for its opinion). */
+		return(0);
+		}
+	}
+
+int ssl2_do_write(SSL *s)
+	{
+	int ret;
+
+	ret=ssl2_write(s,&s->init_buf->data[s->init_off],s->init_num);
+	if (ret == s->init_num)
+		{
+		if (s->msg_callback)
+			s->msg_callback(1, s->version, 0, s->init_buf->data, (size_t)(s->init_off + s->init_num), s, s->msg_callback_arg);
+		return(1);
+		}
+	if (ret < 0)
+		return(-1);
+	s->init_off+=ret;
+	s->init_num-=ret;
+	return(0);
+	}
+
+static int ssl_mt_error(int n)
+	{
+	int ret;
+
+	switch (n)
+		{
+	case SSL2_PE_NO_CIPHER:
+		ret=SSL_R_PEER_ERROR_NO_CIPHER;
+		break;
+	case SSL2_PE_NO_CERTIFICATE:
+		ret=SSL_R_PEER_ERROR_NO_CERTIFICATE;
+		break;
+	case SSL2_PE_BAD_CERTIFICATE:
+		ret=SSL_R_PEER_ERROR_CERTIFICATE;
+		break;
+	case SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE:
+		ret=SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE;
+		break;
+	default:
+		ret=SSL_R_UNKNOWN_REMOTE_ERROR_TYPE;
+		break;
+		}
+	return(ret);
+	}
+#else /* !OPENSSL_NO_SSL2 */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/ssl/s2_srvr.c b/openssl/ssl/s2_srvr.c
new file mode 100644
index 0000000..bc885e8
--- /dev/null
+++ b/openssl/ssl/s2_srvr.c
@@ -0,0 +1,1142 @@
+/* ssl/s2_srvr.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "ssl_locl.h"
+#ifndef OPENSSL_NO_SSL2
+#include <stdio.h>
+#include <openssl/bio.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+
+static const SSL_METHOD *ssl2_get_server_method(int ver);
+static int get_client_master_key(SSL *s);
+static int get_client_hello(SSL *s);
+static int server_hello(SSL *s); 
+static int get_client_finished(SSL *s);
+static int server_verify(SSL *s);
+static int server_finish(SSL *s);
+static int request_certificate(SSL *s);
+static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from,
+	unsigned char *to,int padding);
+#define BREAK	break
+
+static const SSL_METHOD *ssl2_get_server_method(int ver)
+	{
+	if (ver == SSL2_VERSION)
+		return(SSLv2_server_method());
+	else
+		return(NULL);
+	}
+
+IMPLEMENT_ssl2_meth_func(SSLv2_server_method,
+			ssl2_accept,
+			ssl_undefined_function,
+			ssl2_get_server_method)
+
+int ssl2_accept(SSL *s)
+	{
+	unsigned long l=(unsigned long)time(NULL);
+	BUF_MEM *buf=NULL;
+	int ret= -1;
+	long num1;
+	void (*cb)(const SSL *ssl,int type,int val)=NULL;
+	int new_state,state;
+
+	RAND_add(&l,sizeof(l),0);
+	ERR_clear_error();
+	clear_sys_error();
+
+	if (s->info_callback != NULL)
+		cb=s->info_callback;
+	else if (s->ctx->info_callback != NULL)
+		cb=s->ctx->info_callback;
+
+	/* init things to blank */
+	s->in_handshake++;
+	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
+
+	if (s->cert == NULL)
+		{
+		SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
+		return(-1);
+		}
+
+	clear_sys_error();
+	for (;;)
+		{
+		state=s->state;
+
+		switch (s->state)
+			{
+		case SSL_ST_BEFORE:
+		case SSL_ST_ACCEPT:
+		case SSL_ST_BEFORE|SSL_ST_ACCEPT:
+		case SSL_ST_OK|SSL_ST_ACCEPT:
+
+			s->server=1;
+			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
+
+			s->version=SSL2_VERSION;
+			s->type=SSL_ST_ACCEPT;
+
+			buf=s->init_buf;
+			if ((buf == NULL) && ((buf=BUF_MEM_new()) == NULL))
+				{ ret= -1; goto end; }
+			if (!BUF_MEM_grow(buf,(int)
+				SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
+				{ ret= -1; goto end; }
+			s->init_buf=buf;
+			s->init_num=0;
+			s->ctx->stats.sess_accept++;
+			s->handshake_func=ssl2_accept;
+			s->state=SSL2_ST_GET_CLIENT_HELLO_A;
+			BREAK;
+
+		case SSL2_ST_GET_CLIENT_HELLO_A:
+		case SSL2_ST_GET_CLIENT_HELLO_B:
+		case SSL2_ST_GET_CLIENT_HELLO_C:
+			s->shutdown=0;
+			ret=get_client_hello(s);
+			if (ret <= 0) goto end;
+			s->init_num=0;
+			s->state=SSL2_ST_SEND_SERVER_HELLO_A;
+			BREAK;
+
+		case SSL2_ST_SEND_SERVER_HELLO_A:
+		case SSL2_ST_SEND_SERVER_HELLO_B:
+			ret=server_hello(s);
+			if (ret <= 0) goto end;
+			s->init_num=0;
+			if (!s->hit)
+				{
+				s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_A;
+				BREAK;
+				}
+			else
+				{
+				s->state=SSL2_ST_SERVER_START_ENCRYPTION;
+				BREAK;
+				}
+		case SSL2_ST_GET_CLIENT_MASTER_KEY_A:
+		case SSL2_ST_GET_CLIENT_MASTER_KEY_B:
+			ret=get_client_master_key(s);
+			if (ret <= 0) goto end;
+			s->init_num=0;
+			s->state=SSL2_ST_SERVER_START_ENCRYPTION;
+			BREAK;
+
+		case SSL2_ST_SERVER_START_ENCRYPTION:
+			/* Ok we how have sent all the stuff needed to
+			 * start encrypting, the next packet back will
+			 * be encrypted. */
+			if (!ssl2_enc_init(s,0))
+				{ ret= -1; goto end; }
+			s->s2->clear_text=0;
+			s->state=SSL2_ST_SEND_SERVER_VERIFY_A;
+			BREAK;
+
+		case SSL2_ST_SEND_SERVER_VERIFY_A:
+		case SSL2_ST_SEND_SERVER_VERIFY_B:
+			ret=server_verify(s);
+			if (ret <= 0) goto end;
+			s->init_num=0;
+			if (s->hit)
+				{
+				/* If we are in here, we have been
+				 * buffering the output, so we need to
+				 * flush it and remove buffering from
+				 * future traffic */
+				s->state=SSL2_ST_SEND_SERVER_VERIFY_C;
+				BREAK;
+				}
+			else
+				{
+				s->state=SSL2_ST_GET_CLIENT_FINISHED_A;
+				break;
+				}
+
+ 		case SSL2_ST_SEND_SERVER_VERIFY_C:
+ 			/* get the number of bytes to write */
+ 			num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);
+ 			if (num1 > 0)
+ 				{
+				s->rwstate=SSL_WRITING;
+ 				num1=BIO_flush(s->wbio);
+ 				if (num1 <= 0) { ret= -1; goto end; }
+				s->rwstate=SSL_NOTHING;
+				}
+
+ 			/* flushed and now remove buffering */
+ 			s->wbio=BIO_pop(s->wbio);
+
+ 			s->state=SSL2_ST_GET_CLIENT_FINISHED_A;
+  			BREAK;
+
+		case SSL2_ST_GET_CLIENT_FINISHED_A:
+		case SSL2_ST_GET_CLIENT_FINISHED_B:
+			ret=get_client_finished(s);
+			if (ret <= 0)
+				goto end;
+			s->init_num=0;
+			s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_A;
+			BREAK;
+
+		case SSL2_ST_SEND_REQUEST_CERTIFICATE_A:
+		case SSL2_ST_SEND_REQUEST_CERTIFICATE_B:
+		case SSL2_ST_SEND_REQUEST_CERTIFICATE_C:
+		case SSL2_ST_SEND_REQUEST_CERTIFICATE_D:
+			/* don't do a 'request certificate' if we
+			 * don't want to, or we already have one, and
+			 * we only want to do it once. */
+			if (!(s->verify_mode & SSL_VERIFY_PEER) ||
+				((s->session->peer != NULL) &&
+				(s->verify_mode & SSL_VERIFY_CLIENT_ONCE)))
+				{
+				s->state=SSL2_ST_SEND_SERVER_FINISHED_A;
+				break;
+				}
+			else
+				{
+				ret=request_certificate(s);
+				if (ret <= 0) goto end;
+				s->init_num=0;
+				s->state=SSL2_ST_SEND_SERVER_FINISHED_A;
+				}
+			BREAK;
+
+		case SSL2_ST_SEND_SERVER_FINISHED_A:
+		case SSL2_ST_SEND_SERVER_FINISHED_B:
+			ret=server_finish(s);
+			if (ret <= 0) goto end;
+			s->init_num=0;
+			s->state=SSL_ST_OK;
+			break;
+
+		case SSL_ST_OK:
+			BUF_MEM_free(s->init_buf);
+			ssl_free_wbio_buffer(s);
+			s->init_buf=NULL;
+			s->init_num=0;
+		/*	ERR_clear_error();*/
+
+			ssl_update_cache(s,SSL_SESS_CACHE_SERVER);
+
+			s->ctx->stats.sess_accept_good++;
+			/* s->server=1; */
+			ret=1;
+
+			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
+
+			goto end;
+			/* BREAK; */
+
+		default:
+			SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_UNKNOWN_STATE);
+			ret= -1;
+			goto end;
+			/* BREAK; */
+			}
+		
+		if ((cb != NULL) && (s->state != state))
+			{
+			new_state=s->state;
+			s->state=state;
+			cb(s,SSL_CB_ACCEPT_LOOP,1);
+			s->state=new_state;
+			}
+		}
+end:
+	s->in_handshake--;
+	if (cb != NULL)
+		cb(s,SSL_CB_ACCEPT_EXIT,ret);
+	return(ret);
+	}
+
+static int get_client_master_key(SSL *s)
+	{
+	int is_export,i,n,keya,ek;
+	unsigned long len;
+	unsigned char *p;
+	const SSL_CIPHER *cp;
+	const EVP_CIPHER *c;
+	const EVP_MD *md;
+
+	p=(unsigned char *)s->init_buf->data;
+	if (s->state == SSL2_ST_GET_CLIENT_MASTER_KEY_A)
+		{
+		i=ssl2_read(s,(char *)&(p[s->init_num]),10-s->init_num);
+
+		if (i < (10-s->init_num))
+			return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i));
+		s->init_num = 10;
+
+		if (*(p++) != SSL2_MT_CLIENT_MASTER_KEY)
+			{
+			if (p[-1] != SSL2_MT_ERROR)
+				{
+				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+				SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_READ_WRONG_PACKET_TYPE);
+				}
+			else
+				SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_PEER_ERROR);
+			return(-1);
+			}
+
+		cp=ssl2_get_cipher_by_char(p);
+		if (cp == NULL)
+			{
+			ssl2_return_error(s,SSL2_PE_NO_CIPHER);
+			SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH);
+			return(-1);
+			}
+		s->session->cipher= cp;
+
+		p+=3;
+		n2s(p,i); s->s2->tmp.clear=i;
+		n2s(p,i); s->s2->tmp.enc=i;
+		n2s(p,i);
+		if(i > SSL_MAX_KEY_ARG_LENGTH)
+			{
+			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+			SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG);
+			return -1;
+			}
+		s->session->key_arg_length=i;
+		s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_B;
+		}
+
+	/* SSL2_ST_GET_CLIENT_MASTER_KEY_B */
+	p=(unsigned char *)s->init_buf->data;
+	if (s->init_buf->length < SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
+		{
+		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
+		return -1;
+		}
+	keya=s->session->key_arg_length;
+	len = 10 + (unsigned long)s->s2->tmp.clear + (unsigned long)s->s2->tmp.enc + (unsigned long)keya;
+	if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
+		{
+		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_MESSAGE_TOO_LONG);
+		return -1;
+		}
+	n = (int)len - s->init_num;
+	i = ssl2_read(s,(char *)&(p[s->init_num]),n);
+	if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i));
+	if (s->msg_callback)
+		s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-MASTER-KEY */
+	p += 10;
+
+	memcpy(s->session->key_arg,&(p[s->s2->tmp.clear+s->s2->tmp.enc]),
+		(unsigned int)keya);
+
+	if (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL)
+		{
+		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_NO_PRIVATEKEY);
+		return(-1);
+		}
+	i=ssl_rsa_private_decrypt(s->cert,s->s2->tmp.enc,
+		&(p[s->s2->tmp.clear]),&(p[s->s2->tmp.clear]),
+		(s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);
+
+	is_export=SSL_C_IS_EXPORT(s->session->cipher);
+	
+	if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL))
+		{
+		ssl2_return_error(s,SSL2_PE_NO_CIPHER);
+		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
+		return(0);
+		}
+
+	if (s->session->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC)
+		{
+		is_export=1;
+		ek=8;
+		}
+	else
+		ek=5;
+
+	/* bad decrypt */
+#if 1
+	/* If a bad decrypt, continue with protocol but with a
+	 * random master secret (Bleichenbacher attack) */
+	if ((i < 0) ||
+		((!is_export && (i != EVP_CIPHER_key_length(c)))
+		|| (is_export && ((i != ek) || (s->s2->tmp.clear+(unsigned int)i !=
+			(unsigned int)EVP_CIPHER_key_length(c))))))
+		{
+		ERR_clear_error();
+		if (is_export)
+			i=ek;
+		else
+			i=EVP_CIPHER_key_length(c);
+		if (RAND_pseudo_bytes(p,i) <= 0)
+			return 0;
+		}
+#else
+	if (i < 0)
+		{
+		error=1;
+		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_RSA_DECRYPT);
+		}
+	/* incorrect number of key bytes for non export cipher */
+	else if ((!is_export && (i != EVP_CIPHER_key_length(c)))
+		|| (is_export && ((i != ek) || (s->s2->tmp.clear+i !=
+			EVP_CIPHER_key_length(c)))))
+		{
+		error=1;
+		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_WRONG_NUMBER_OF_KEY_BITS);
+		}
+	if (error)
+		{
+		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+		return(-1);
+		}
+#endif
+
+	if (is_export) i+=s->s2->tmp.clear;
+
+	if (i > SSL_MAX_MASTER_KEY_LENGTH)
+		{
+		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
+		return -1;
+		}
+	s->session->master_key_length=i;
+	memcpy(s->session->master_key,p,(unsigned int)i);
+	return(1);
+	}
+
+static int get_client_hello(SSL *s)
+	{
+	int i,n;
+	unsigned long len;
+	unsigned char *p;
+	STACK_OF(SSL_CIPHER) *cs; /* a stack of SSL_CIPHERS */
+	STACK_OF(SSL_CIPHER) *cl; /* the ones we want to use */
+	STACK_OF(SSL_CIPHER) *prio, *allow;
+	int z;
+
+	/* This is a bit of a hack to check for the correct packet
+	 * type the first time round. */
+	if (s->state == SSL2_ST_GET_CLIENT_HELLO_A)
+		{
+		s->first_packet=1;
+		s->state=SSL2_ST_GET_CLIENT_HELLO_B;
+		}
+
+	p=(unsigned char *)s->init_buf->data;
+	if (s->state == SSL2_ST_GET_CLIENT_HELLO_B)
+		{
+		i=ssl2_read(s,(char *)&(p[s->init_num]),9-s->init_num);
+		if (i < (9-s->init_num)) 
+			return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i));
+		s->init_num = 9;
+	
+		if (*(p++) != SSL2_MT_CLIENT_HELLO)
+			{
+			if (p[-1] != SSL2_MT_ERROR)
+				{
+				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+				SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_READ_WRONG_PACKET_TYPE);
+				}
+			else
+				SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_PEER_ERROR);
+			return(-1);
+			}
+		n2s(p,i);
+		if (i < s->version) s->version=i;
+		n2s(p,i); s->s2->tmp.cipher_spec_length=i;
+		n2s(p,i); s->s2->tmp.session_id_length=i;
+		n2s(p,i); s->s2->challenge_length=i;
+		if (	(i < SSL2_MIN_CHALLENGE_LENGTH) ||
+			(i > SSL2_MAX_CHALLENGE_LENGTH))
+			{
+			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+			SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_INVALID_CHALLENGE_LENGTH);
+			return(-1);
+			}
+		s->state=SSL2_ST_GET_CLIENT_HELLO_C;
+		}
+
+	/* SSL2_ST_GET_CLIENT_HELLO_C */
+	p=(unsigned char *)s->init_buf->data;
+	len = 9 + (unsigned long)s->s2->tmp.cipher_spec_length + (unsigned long)s->s2->challenge_length + (unsigned long)s->s2->tmp.session_id_length;
+	if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
+		{
+		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+		SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_MESSAGE_TOO_LONG);
+		return -1;
+		}
+	n = (int)len - s->init_num;
+	i = ssl2_read(s,(char *)&(p[s->init_num]),n);
+	if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i));
+	if (s->msg_callback)
+		s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-HELLO */
+	p += 9;
+
+	/* get session-id before cipher stuff so we can get out session
+	 * structure if it is cached */
+	/* session-id */
+	if ((s->s2->tmp.session_id_length != 0) && 
+		(s->s2->tmp.session_id_length != SSL2_SSL_SESSION_ID_LENGTH))
+		{
+		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+		SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_BAD_SSL_SESSION_ID_LENGTH);
+		return(-1);
+		}
+
+	if (s->s2->tmp.session_id_length == 0)
+		{
+		if (!ssl_get_new_session(s,1))
+			{
+			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+			return(-1);
+			}
+		}
+	else
+		{
+		i=ssl_get_prev_session(s,&(p[s->s2->tmp.cipher_spec_length]),
+			s->s2->tmp.session_id_length, NULL);
+		if (i == 1)
+			{ /* previous session */
+			s->hit=1;
+			}
+		else if (i == -1)
+			{
+			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+			return(-1);
+			}
+		else
+			{
+			if (s->cert == NULL)
+				{
+				ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
+				SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_NO_CERTIFICATE_SET);
+				return(-1);
+				}
+
+			if (!ssl_get_new_session(s,1))
+				{
+				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+				return(-1);
+				}
+			}
+		}
+
+	if (!s->hit)
+		{
+		cs=ssl_bytes_to_cipher_list(s,p,s->s2->tmp.cipher_spec_length,
+			&s->session->ciphers);
+		if (cs == NULL) goto mem_err;
+
+		cl=SSL_get_ciphers(s);
+
+		if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
+		    {
+		    prio=sk_SSL_CIPHER_dup(cl);
+		    if (prio == NULL) goto mem_err;
+		    allow = cs;
+		    }
+		else
+		    {
+		    prio = cs;
+		    allow = cl;
+		    }
+		for (z=0; z<sk_SSL_CIPHER_num(prio); z++)
+			{
+			if (sk_SSL_CIPHER_find(allow,sk_SSL_CIPHER_value(prio,z)) < 0)
+				{
+				(void)sk_SSL_CIPHER_delete(prio,z);
+				z--;
+				}
+			}
+		if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
+		    {
+		    sk_SSL_CIPHER_free(s->session->ciphers);
+		    s->session->ciphers = prio;
+		    }
+		/* s->session->ciphers should now have a list of
+		 * ciphers that are on both the client and server.
+		 * This list is ordered by the order the client sent
+		 * the ciphers or in the order of the server's preference
+		 * if SSL_OP_CIPHER_SERVER_PREFERENCE was set.
+		 */
+		}
+	p+=s->s2->tmp.cipher_spec_length;
+	/* done cipher selection */
+
+	/* session id extracted already */
+	p+=s->s2->tmp.session_id_length;
+
+	/* challenge */
+	if (s->s2->challenge_length > sizeof s->s2->challenge)
+		{
+		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+		SSLerr(SSL_F_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
+		return -1;
+		}
+	memcpy(s->s2->challenge,p,(unsigned int)s->s2->challenge_length);
+	return(1);
+mem_err:
+	SSLerr(SSL_F_GET_CLIENT_HELLO,ERR_R_MALLOC_FAILURE);
+	return(0);
+	}
+
+static int server_hello(SSL *s)
+	{
+	unsigned char *p,*d;
+	int n,hit;
+
+	p=(unsigned char *)s->init_buf->data;
+	if (s->state == SSL2_ST_SEND_SERVER_HELLO_A)
+		{
+		d=p+11;
+		*(p++)=SSL2_MT_SERVER_HELLO;		/* type */
+		hit=s->hit;
+		*(p++)=(unsigned char)hit;
+#if 1
+		if (!hit)
+			{
+			if (s->session->sess_cert != NULL)
+				/* This can't really happen because get_client_hello
+				 * has called ssl_get_new_session, which does not set
+				 * sess_cert. */
+				ssl_sess_cert_free(s->session->sess_cert);
+			s->session->sess_cert = ssl_sess_cert_new();
+			if (s->session->sess_cert == NULL)
+				{
+				SSLerr(SSL_F_SERVER_HELLO, ERR_R_MALLOC_FAILURE);
+				return(-1);
+				}
+			}
+		/* If 'hit' is set, then s->sess_cert may be non-NULL or NULL,
+		 * depending on whether it survived in the internal cache
+		 * or was retrieved from an external cache.
+		 * If it is NULL, we cannot put any useful data in it anyway,
+		 * so we don't touch it.
+		 */
+
+#else /* That's what used to be done when cert_st and sess_cert_st were
+	   * the same. */
+		if (!hit)
+			{			/* else add cert to session */
+			CRYPTO_add(&s->cert->references,1,CRYPTO_LOCK_SSL_CERT);
+			if (s->session->sess_cert != NULL)
+				ssl_cert_free(s->session->sess_cert);
+			s->session->sess_cert=s->cert;		
+			}
+		else	/* We have a session id-cache hit, if the
+			 * session-id has no certificate listed against
+			 * the 'cert' structure, grab the 'old' one
+			 * listed against the SSL connection */
+			{
+			if (s->session->sess_cert == NULL)
+				{
+				CRYPTO_add(&s->cert->references,1,
+					CRYPTO_LOCK_SSL_CERT);
+				s->session->sess_cert=s->cert;
+				}
+			}
+#endif
+
+		if (s->cert == NULL)
+			{
+			ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
+			SSLerr(SSL_F_SERVER_HELLO,SSL_R_NO_CERTIFICATE_SPECIFIED);
+			return(-1);
+			}
+
+		if (hit)
+			{
+			*(p++)=0;		/* no certificate type */
+			s2n(s->version,p);	/* version */
+			s2n(0,p);		/* cert len */
+			s2n(0,p);		/* ciphers len */
+			}
+		else
+			{
+			/* EAY EAY */
+			/* put certificate type */
+			*(p++)=SSL2_CT_X509_CERTIFICATE;
+			s2n(s->version,p);	/* version */
+			n=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
+			s2n(n,p);		/* certificate length */
+			i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&d);
+			n=0;
+			
+			/* lets send out the ciphers we like in the
+			 * prefered order */
+			n=ssl_cipher_list_to_bytes(s,s->session->ciphers,d,0);
+			d+=n;
+			s2n(n,p);		/* add cipher length */
+			}
+
+		/* make and send conn_id */
+		s2n(SSL2_CONNECTION_ID_LENGTH,p);	/* add conn_id length */
+		s->s2->conn_id_length=SSL2_CONNECTION_ID_LENGTH;
+		if (RAND_pseudo_bytes(s->s2->conn_id,(int)s->s2->conn_id_length) <= 0)
+			return -1;
+		memcpy(d,s->s2->conn_id,SSL2_CONNECTION_ID_LENGTH);
+		d+=SSL2_CONNECTION_ID_LENGTH;
+
+		s->state=SSL2_ST_SEND_SERVER_HELLO_B;
+		s->init_num=d-(unsigned char *)s->init_buf->data;
+		s->init_off=0;
+		}
+	/* SSL2_ST_SEND_SERVER_HELLO_B */
+ 	/* If we are using TCP/IP, the performance is bad if we do 2
+ 	 * writes without a read between them.  This occurs when
+ 	 * Session-id reuse is used, so I will put in a buffering module
+ 	 */
+ 	if (s->hit)
+ 		{
+		if (!ssl_init_wbio_buffer(s,1)) return(-1);
+ 		}
+ 
+	return(ssl2_do_write(s));
+	}
+
+static int get_client_finished(SSL *s)
+	{
+	unsigned char *p;
+	int i, n;
+	unsigned long len;
+
+	p=(unsigned char *)s->init_buf->data;
+	if (s->state == SSL2_ST_GET_CLIENT_FINISHED_A)
+		{
+		i=ssl2_read(s,(char *)&(p[s->init_num]),1-s->init_num);
+		if (i < 1-s->init_num)
+			return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i));
+		s->init_num += i;
+
+		if (*p != SSL2_MT_CLIENT_FINISHED)
+			{
+			if (*p != SSL2_MT_ERROR)
+				{
+				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+				SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_READ_WRONG_PACKET_TYPE);
+				}
+			else
+				{
+				SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_PEER_ERROR);
+				/* try to read the error message */
+				i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num);
+				return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i);
+				}
+			return(-1);
+			}
+		s->state=SSL2_ST_GET_CLIENT_FINISHED_B;
+		}
+
+	/* SSL2_ST_GET_CLIENT_FINISHED_B */
+	if (s->s2->conn_id_length > sizeof s->s2->conn_id)
+		{
+		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+		SSLerr(SSL_F_GET_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR);
+		return -1;
+		}
+	len = 1 + (unsigned long)s->s2->conn_id_length;
+	n = (int)len - s->init_num;
+	i = ssl2_read(s,(char *)&(p[s->init_num]),n);
+	if (i < n)
+		{
+		return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i));
+		}
+	if (s->msg_callback)
+		s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* CLIENT-FINISHED */
+	p += 1;
+	if (memcmp(p,s->s2->conn_id,s->s2->conn_id_length) != 0)
+		{
+		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+		SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_CONNECTION_ID_IS_DIFFERENT);
+		return(-1);
+		}
+	return(1);
+	}
+
+static int server_verify(SSL *s)
+	{
+	unsigned char *p;
+
+	if (s->state == SSL2_ST_SEND_SERVER_VERIFY_A)
+		{
+		p=(unsigned char *)s->init_buf->data;
+		*(p++)=SSL2_MT_SERVER_VERIFY;
+		if (s->s2->challenge_length > sizeof s->s2->challenge)
+			{
+			SSLerr(SSL_F_SERVER_VERIFY, ERR_R_INTERNAL_ERROR);
+			return -1;
+			}
+		memcpy(p,s->s2->challenge,(unsigned int)s->s2->challenge_length);
+		/* p+=s->s2->challenge_length; */
+
+		s->state=SSL2_ST_SEND_SERVER_VERIFY_B;
+		s->init_num=s->s2->challenge_length+1;
+		s->init_off=0;
+		}
+	return(ssl2_do_write(s));
+	}
+
+static int server_finish(SSL *s)
+	{
+	unsigned char *p;
+
+	if (s->state == SSL2_ST_SEND_SERVER_FINISHED_A)
+		{
+		p=(unsigned char *)s->init_buf->data;
+		*(p++)=SSL2_MT_SERVER_FINISHED;
+
+		if (s->session->session_id_length > sizeof s->session->session_id)
+			{
+			SSLerr(SSL_F_SERVER_FINISH, ERR_R_INTERNAL_ERROR);
+			return -1;
+			}
+		memcpy(p,s->session->session_id, (unsigned int)s->session->session_id_length);
+		/* p+=s->session->session_id_length; */
+
+		s->state=SSL2_ST_SEND_SERVER_FINISHED_B;
+		s->init_num=s->session->session_id_length+1;
+		s->init_off=0;
+		}
+
+	/* SSL2_ST_SEND_SERVER_FINISHED_B */
+	return(ssl2_do_write(s));
+	}
+
+/* send the request and check the response */
+static int request_certificate(SSL *s)
+	{
+	const unsigned char *cp;
+	unsigned char *p,*p2,*buf2;
+	unsigned char *ccd;
+	int i,j,ctype,ret= -1;
+	unsigned long len;
+	X509 *x509=NULL;
+	STACK_OF(X509) *sk=NULL;
+
+	ccd=s->s2->tmp.ccl;
+	if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_A)
+		{
+		p=(unsigned char *)s->init_buf->data;
+		*(p++)=SSL2_MT_REQUEST_CERTIFICATE;
+		*(p++)=SSL2_AT_MD5_WITH_RSA_ENCRYPTION;
+		if (RAND_pseudo_bytes(ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0)
+			return -1;
+		memcpy(p,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
+
+		s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_B;
+		s->init_num=SSL2_MIN_CERT_CHALLENGE_LENGTH+2;
+		s->init_off=0;
+		}
+
+	if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_B)
+		{
+		i=ssl2_do_write(s);
+		if (i <= 0)
+			{
+			ret=i;
+			goto end;
+			}
+
+		s->init_num=0;
+		s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_C;
+		}
+
+	if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_C)
+		{
+		p=(unsigned char *)s->init_buf->data;
+		i=ssl2_read(s,(char *)&(p[s->init_num]),6-s->init_num); /* try to read 6 octets ... */
+		if (i < 3-s->init_num) /* ... but don't call ssl2_part_read now if we got at least 3
+		                        * (probably NO-CERTIFICATE-ERROR) */
+			{
+			ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i);
+			goto end;
+			}
+		s->init_num += i;
+
+		if ((s->init_num >= 3) && (p[0] == SSL2_MT_ERROR))
+			{
+			n2s(p,i);
+			if (i != SSL2_PE_NO_CERTIFICATE)
+				{
+				/* not the error message we expected -- let ssl2_part_read handle it */
+				s->init_num -= 3;
+				ret = ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE, 3);
+				goto end;
+				}
+
+			if (s->msg_callback)
+				s->msg_callback(0, s->version, 0, p, 3, s, s->msg_callback_arg); /* ERROR */
+
+			/* this is the one place where we can recover from an SSL 2.0 error */
+
+			if (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
+				{
+				ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
+				SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
+				goto end;
+				}
+			ret=1;
+			goto end;
+			}
+		if ((*(p++) != SSL2_MT_CLIENT_CERTIFICATE) || (s->init_num < 6))
+			{
+			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+			SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_SHORT_READ);
+			goto end;
+			}
+		if (s->init_num != 6)
+			{
+			SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_INTERNAL_ERROR);
+			goto end;
+			}
+		
+		/* ok we have a response */
+		/* certificate type, there is only one right now. */
+		ctype= *(p++);
+		if (ctype != SSL2_AT_MD5_WITH_RSA_ENCRYPTION)
+			{
+			ssl2_return_error(s,SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE);
+			SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_RESPONSE_ARGUMENT);
+			goto end;
+			}
+		n2s(p,i); s->s2->tmp.clen=i;
+		n2s(p,i); s->s2->tmp.rlen=i;
+		s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_D;
+		}
+
+	/* SSL2_ST_SEND_REQUEST_CERTIFICATE_D */
+	p=(unsigned char *)s->init_buf->data;
+	len = 6 + (unsigned long)s->s2->tmp.clen + (unsigned long)s->s2->tmp.rlen;
+	if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
+		{
+		SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_MESSAGE_TOO_LONG);
+		goto end;
+		}
+	j = (int)len - s->init_num;
+	i = ssl2_read(s,(char *)&(p[s->init_num]),j);
+	if (i < j) 
+		{
+		ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i);
+		goto end;
+		}
+	if (s->msg_callback)
+		s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* CLIENT-CERTIFICATE */
+	p += 6;
+
+	cp = p;
+	x509=(X509 *)d2i_X509(NULL,&cp,(long)s->s2->tmp.clen);
+	if (x509 == NULL)
+		{
+		SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_X509_LIB);
+		goto msg_end;
+		}
+
+	if (((sk=sk_X509_new_null()) == NULL) || (!sk_X509_push(sk,x509)))
+		{
+		SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE);
+		goto msg_end;
+		}
+
+	i=ssl_verify_cert_chain(s,sk);
+
+	if (i > 0)	/* we like the packet, now check the chksum */
+		{
+		EVP_MD_CTX ctx;
+		EVP_PKEY *pkey=NULL;
+
+		EVP_MD_CTX_init(&ctx);
+		EVP_VerifyInit_ex(&ctx,s->ctx->rsa_md5, NULL);
+		EVP_VerifyUpdate(&ctx,s->s2->key_material,
+				 s->s2->key_material_length);
+		EVP_VerifyUpdate(&ctx,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
+
+		i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
+		buf2=OPENSSL_malloc((unsigned int)i);
+		if (buf2 == NULL)
+			{
+			SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE);
+			goto msg_end;
+			}
+		p2=buf2;
+		i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2);
+		EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i);
+		OPENSSL_free(buf2);
+
+		pkey=X509_get_pubkey(x509);
+		if (pkey == NULL) goto end;
+		i=EVP_VerifyFinal(&ctx,cp,s->s2->tmp.rlen,pkey);
+		EVP_PKEY_free(pkey);
+		EVP_MD_CTX_cleanup(&ctx);
+
+		if (i > 0)
+			{
+			if (s->session->peer != NULL)
+				X509_free(s->session->peer);
+			s->session->peer=x509;
+			CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
+			s->session->verify_result = s->verify_result;
+			ret=1;
+			goto end;
+			}
+		else
+			{
+			SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_CHECKSUM);
+			goto msg_end;
+			}
+		}
+	else
+		{
+msg_end:
+		ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
+		}
+end:
+	sk_X509_free(sk);
+	X509_free(x509);
+	return(ret);
+	}
+
+static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from,
+	     unsigned char *to, int padding)
+	{
+	RSA *rsa;
+	int i;
+
+	if ((c == NULL) || (c->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL))
+		{
+		SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_NO_PRIVATEKEY);
+		return(-1);
+		}
+	if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey->type != EVP_PKEY_RSA)
+		{
+		SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_PUBLIC_KEY_IS_NOT_RSA);
+		return(-1);
+		}
+	rsa=c->pkeys[SSL_PKEY_RSA_ENC].privatekey->pkey.rsa;
+
+	/* we have the public key */
+	i=RSA_private_decrypt(len,from,to,rsa,padding);
+	if (i < 0)
+		SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,ERR_R_RSA_LIB);
+	return(i);
+	}
+#else /* !OPENSSL_NO_SSL2 */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/ssl/s3_both.c b/openssl/ssl/s3_both.c
new file mode 100644
index 0000000..508e390
--- /dev/null
+++ b/openssl/ssl/s3_both.c
@@ -0,0 +1,867 @@
+/* ssl/s3_both.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include <limits.h>
+#include <string.h>
+#include <stdio.h>
+#include "ssl_locl.h"
+#include <openssl/buffer.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
+int ssl3_do_write(SSL *s, int type)
+	{
+	int ret;
+
+	ret=ssl3_write_bytes(s,type,&s->init_buf->data[s->init_off],
+	                     s->init_num);
+	if (ret < 0) return(-1);
+	if (type == SSL3_RT_HANDSHAKE)
+		/* should not be done for 'Hello Request's, but in that case
+		 * we'll ignore the result anyway */
+		ssl3_finish_mac(s,(unsigned char *)&s->init_buf->data[s->init_off],ret);
+	
+	if (ret == s->init_num)
+		{
+		if (s->msg_callback)
+			s->msg_callback(1, s->version, type, s->init_buf->data, (size_t)(s->init_off + s->init_num), s, s->msg_callback_arg);
+		return(1);
+		}
+	s->init_off+=ret;
+	s->init_num-=ret;
+	return(0);
+	}
+
+int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
+	{
+	unsigned char *p,*d;
+	int i;
+	unsigned long l;
+
+	if (s->state == a)
+		{
+		d=(unsigned char *)s->init_buf->data;
+		p= &(d[4]);
+
+		i=s->method->ssl3_enc->final_finish_mac(s,
+			sender,slen,s->s3->tmp.finish_md);
+		s->s3->tmp.finish_md_len = i;
+		memcpy(p, s->s3->tmp.finish_md, i);
+		p+=i;
+		l=i;
+
+                /* Copy the finished so we can use it for
+                   renegotiation checks */
+                if(s->type == SSL_ST_CONNECT)
+                        {
+                         OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+                         memcpy(s->s3->previous_client_finished, 
+                             s->s3->tmp.finish_md, i);
+                         s->s3->previous_client_finished_len=i;
+                        }
+                else
+                        {
+                        OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+                        memcpy(s->s3->previous_server_finished, 
+                            s->s3->tmp.finish_md, i);
+                        s->s3->previous_server_finished_len=i;
+                        }
+
+#ifdef OPENSSL_SYS_WIN16
+		/* MSVC 1.5 does not clear the top bytes of the word unless
+		 * I do this.
+		 */
+		l&=0xffff;
+#endif
+
+		*(d++)=SSL3_MT_FINISHED;
+		l2n3(l,d);
+		s->init_num=(int)l+4;
+		s->init_off=0;
+
+		s->state=b;
+		}
+
+	/* SSL3_ST_SEND_xxxxxx_HELLO_B */
+	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
+	}
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+/* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen to far. */
+static void ssl3_take_mac(SSL *s)
+	{
+	const char *sender;
+	int slen;
+
+	if (s->state & SSL_ST_CONNECT)
+		{
+		sender=s->method->ssl3_enc->server_finished_label;
+		slen=s->method->ssl3_enc->server_finished_label_len;
+		}
+	else
+		{
+		sender=s->method->ssl3_enc->client_finished_label;
+		slen=s->method->ssl3_enc->client_finished_label_len;
+		}
+
+	s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
+		sender,slen,s->s3->tmp.peer_finish_md);
+	}
+#endif
+
+int ssl3_get_finished(SSL *s, int a, int b)
+	{
+	int al,i,ok;
+	long n;
+	unsigned char *p;
+
+#ifdef OPENSSL_NO_NEXTPROTONEG
+	/* the mac has already been generated when we received the
+	 * change cipher spec message and is in s->s3->tmp.peer_finish_md
+	 */ 
+#endif
+
+	n=s->method->ssl_get_message(s,
+		a,
+		b,
+		SSL3_MT_FINISHED,
+		64, /* should actually be 36+4 :-) */
+		&ok);
+
+	if (!ok) return((int)n);
+
+	/* If this occurs, we have missed a message */
+	if (!s->s3->change_cipher_spec)
+		{
+		al=SSL_AD_UNEXPECTED_MESSAGE;
+		SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_GOT_A_FIN_BEFORE_A_CCS);
+		goto f_err;
+		}
+	s->s3->change_cipher_spec=0;
+
+	p = (unsigned char *)s->init_msg;
+	i = s->s3->tmp.peer_finish_md_len;
+
+	if (i != n)
+		{
+		al=SSL_AD_DECODE_ERROR;
+		SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_BAD_DIGEST_LENGTH);
+		goto f_err;
+		}
+
+	if (memcmp(p, s->s3->tmp.peer_finish_md, i) != 0)
+		{
+		al=SSL_AD_DECRYPT_ERROR;
+		SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_DIGEST_CHECK_FAILED);
+		goto f_err;
+		}
+
+        /* Copy the finished so we can use it for
+           renegotiation checks */
+        if(s->type == SSL_ST_ACCEPT)
+                {
+                OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+                memcpy(s->s3->previous_client_finished, 
+                    s->s3->tmp.peer_finish_md, i);
+                s->s3->previous_client_finished_len=i;
+                }
+        else
+                {
+                OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+                memcpy(s->s3->previous_server_finished, 
+                    s->s3->tmp.peer_finish_md, i);
+                s->s3->previous_server_finished_len=i;
+                }
+
+	return(1);
+f_err:
+	ssl3_send_alert(s,SSL3_AL_FATAL,al);
+	return(0);
+	}
+
+/* for these 2 messages, we need to
+ * ssl->enc_read_ctx			re-init
+ * ssl->s3->read_sequence		zero
+ * ssl->s3->read_mac_secret		re-init
+ * ssl->session->read_sym_enc		assign
+ * ssl->session->read_compression	assign
+ * ssl->session->read_hash		assign
+ */
+int ssl3_send_change_cipher_spec(SSL *s, int a, int b)
+	{ 
+	unsigned char *p;
+
+	if (s->state == a)
+		{
+		p=(unsigned char *)s->init_buf->data;
+		*p=SSL3_MT_CCS;
+		s->init_num=1;
+		s->init_off=0;
+
+		s->state=b;
+		}
+
+	/* SSL3_ST_CW_CHANGE_B */
+	return(ssl3_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
+	}
+
+static int ssl3_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
+	{
+	int n;
+	unsigned char *p;
+
+	n=i2d_X509(x,NULL);
+	if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3)))
+		{
+		SSLerr(SSL_F_SSL3_ADD_CERT_TO_BUF,ERR_R_BUF_LIB);
+		return(-1);
+		}
+	p=(unsigned char *)&(buf->data[*l]);
+	l2n3(n,p);
+	i2d_X509(x,&p);
+	*l+=n+3;
+
+	return(0);
+	}
+
+unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
+	{
+	unsigned char *p;
+	int i;
+	unsigned long l=7;
+	BUF_MEM *buf;
+	int no_chain;
+	STACK_OF(X509) *cert_chain;
+
+	cert_chain = SSL_get_certificate_chain(s, x);
+
+	if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs || cert_chain)
+		no_chain = 1;
+	else
+		no_chain = 0;
+
+	/* TLSv1 sends a chain with nothing in it, instead of an alert */
+	buf=s->init_buf;
+	if (!BUF_MEM_grow_clean(buf,10))
+		{
+		SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
+		return(0);
+		}
+	if (x != NULL)
+		{
+		if (no_chain)
+			{
+			if (ssl3_add_cert_to_buf(buf, &l, x))
+				return(0);
+			}
+		else
+			{
+			X509_STORE_CTX xs_ctx;
+
+			if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL))
+				{
+				SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
+				return(0);
+				}
+			X509_verify_cert(&xs_ctx);
+			/* Don't leave errors in the queue */
+			ERR_clear_error();
+			for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
+				{
+				x = sk_X509_value(xs_ctx.chain, i);
+
+				if (ssl3_add_cert_to_buf(buf, &l, x))
+					{
+					X509_STORE_CTX_cleanup(&xs_ctx);
+					return 0;
+					}
+				}
+			X509_STORE_CTX_cleanup(&xs_ctx);
+			}
+		}
+	/* Thawte special :-) */
+	for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
+		{
+		x=sk_X509_value(s->ctx->extra_certs,i);
+		if (ssl3_add_cert_to_buf(buf, &l, x))
+			return(0);
+		}
+
+	for (i=0; i<sk_X509_num(cert_chain); i++)
+		if (ssl3_add_cert_to_buf(buf, &l, sk_X509_value(cert_chain,i)))
+			return(0);
+
+	l-=7;
+	p=(unsigned char *)&(buf->data[4]);
+	l2n3(l,p);
+	l+=3;
+	p=(unsigned char *)&(buf->data[0]);
+	*(p++)=SSL3_MT_CERTIFICATE;
+	l2n3(l,p);
+	l+=4;
+	return(l);
+	}
+
+/* Obtain handshake message of message type 'mt' (any if mt == -1),
+ * maximum acceptable body length 'max'.
+ * The first four bytes (msg_type and length) are read in state 'st1',
+ * the body is read in state 'stn'.
+ */
+long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
+	{
+	unsigned char *p;
+	unsigned long l;
+	long n;
+	int i,al;
+
+	if (s->s3->tmp.reuse_message)
+		{
+		s->s3->tmp.reuse_message=0;
+		if ((mt >= 0) && (s->s3->tmp.message_type != mt))
+			{
+			al=SSL_AD_UNEXPECTED_MESSAGE;
+			SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
+			goto f_err;
+			}
+		*ok=1;
+		s->init_msg = s->init_buf->data + 4;
+		s->init_num = (int)s->s3->tmp.message_size;
+		return s->init_num;
+		}
+
+	p=(unsigned char *)s->init_buf->data;
+
+	if (s->state == st1) /* s->init_num < 4 */
+		{
+		int skip_message;
+
+		do
+			{
+			while (s->init_num < 4)
+				{
+				i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
+					&p[s->init_num],4 - s->init_num, 0);
+				if (i <= 0)
+					{
+					s->rwstate=SSL_READING;
+					*ok = 0;
+					return i;
+					}
+				s->init_num+=i;
+				}
+			
+			skip_message = 0;
+			if (!s->server)
+				if (p[0] == SSL3_MT_HELLO_REQUEST)
+					/* The server may always send 'Hello Request' messages --
+					 * we are doing a handshake anyway now, so ignore them
+					 * if their format is correct. Does not count for
+					 * 'Finished' MAC. */
+					if (p[1] == 0 && p[2] == 0 &&p[3] == 0)
+						{
+						s->init_num = 0;
+						skip_message = 1;
+
+						if (s->msg_callback)
+							s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, p, 4, s, s->msg_callback_arg);
+						}
+			}
+		while (skip_message);
+
+		/* s->init_num == 4 */
+
+		if ((mt >= 0) && (*p != mt))
+			{
+			al=SSL_AD_UNEXPECTED_MESSAGE;
+			SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
+			goto f_err;
+			}
+		if ((mt < 0) && (*p == SSL3_MT_CLIENT_HELLO) &&
+					(st1 == SSL3_ST_SR_CERT_A) &&
+					(stn == SSL3_ST_SR_CERT_B))
+			{
+			/* At this point we have got an MS SGC second client
+			 * hello (maybe we should always allow the client to
+			 * start a new handshake?). We need to restart the mac.
+			 * Don't increment {num,total}_renegotiations because
+			 * we have not completed the handshake. */
+			ssl3_init_finished_mac(s);
+			}
+
+		s->s3->tmp.message_type= *(p++);
+
+		n2l3(p,l);
+		if (l > (unsigned long)max)
+			{
+			al=SSL_AD_ILLEGAL_PARAMETER;
+			SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE);
+			goto f_err;
+			}
+		if (l > (INT_MAX-4)) /* BUF_MEM_grow takes an 'int' parameter */
+			{
+			al=SSL_AD_ILLEGAL_PARAMETER;
+			SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE);
+			goto f_err;
+			}
+		if (l && !BUF_MEM_grow_clean(s->init_buf,(int)l+4))
+			{
+			SSLerr(SSL_F_SSL3_GET_MESSAGE,ERR_R_BUF_LIB);
+			goto err;
+			}
+		s->s3->tmp.message_size=l;
+		s->state=stn;
+
+		s->init_msg = s->init_buf->data + 4;
+		s->init_num = 0;
+		}
+
+	/* next state (stn) */
+	p = s->init_msg;
+	n = s->s3->tmp.message_size - s->init_num;
+	while (n > 0)
+		{
+		i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num],n,0);
+		if (i <= 0)
+			{
+			s->rwstate=SSL_READING;
+			*ok = 0;
+			return i;
+			}
+		s->init_num += i;
+		n -= i;
+		}
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+	/* If receiving Finished, record MAC of prior handshake messages for
+	 * Finished verification. */
+	if (*s->init_buf->data == SSL3_MT_FINISHED)
+		ssl3_take_mac(s);
+#endif
+
+	/* Feed this message into MAC computation. */
+	ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
+	if (s->msg_callback)
+		s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, (size_t)s->init_num + 4, s, s->msg_callback_arg);
+	*ok=1;
+	return s->init_num;
+f_err:
+	ssl3_send_alert(s,SSL3_AL_FATAL,al);
+err:
+	*ok=0;
+	return(-1);
+	}
+
+int ssl_cert_type(X509 *x, EVP_PKEY *pkey)
+	{
+	EVP_PKEY *pk;
+	int ret= -1,i;
+
+	if (pkey == NULL)
+		pk=X509_get_pubkey(x);
+	else
+		pk=pkey;
+	if (pk == NULL) goto err;
+
+	i=pk->type;
+	if (i == EVP_PKEY_RSA)
+		{
+		ret=SSL_PKEY_RSA_ENC;
+		}
+	else if (i == EVP_PKEY_DSA)
+		{
+		ret=SSL_PKEY_DSA_SIGN;
+		}
+#ifndef OPENSSL_NO_EC
+	else if (i == EVP_PKEY_EC)
+		{
+		ret = SSL_PKEY_ECC;
+		}	
+#endif
+	else if (i == NID_id_GostR3410_94 || i == NID_id_GostR3410_94_cc) 
+		{
+		ret = SSL_PKEY_GOST94;
+		}
+	else if (i == NID_id_GostR3410_2001 || i == NID_id_GostR3410_2001_cc) 
+		{
+		ret = SSL_PKEY_GOST01;
+		}
+err:
+	if(!pkey) EVP_PKEY_free(pk);
+	return(ret);
+	}
+
+int ssl_verify_alarm_type(long type)
+	{
+	int al;
+
+	switch(type)
+		{
+	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+	case X509_V_ERR_UNABLE_TO_GET_CRL:
+	case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
+		al=SSL_AD_UNKNOWN_CA;
+		break;
+	case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
+	case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
+	case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
+	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+	case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
+	case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
+	case X509_V_ERR_CERT_NOT_YET_VALID:
+	case X509_V_ERR_CRL_NOT_YET_VALID:
+	case X509_V_ERR_CERT_UNTRUSTED:
+	case X509_V_ERR_CERT_REJECTED:
+		al=SSL_AD_BAD_CERTIFICATE;
+		break;
+	case X509_V_ERR_CERT_SIGNATURE_FAILURE:
+	case X509_V_ERR_CRL_SIGNATURE_FAILURE:
+		al=SSL_AD_DECRYPT_ERROR;
+		break;
+	case X509_V_ERR_CERT_HAS_EXPIRED:
+	case X509_V_ERR_CRL_HAS_EXPIRED:
+		al=SSL_AD_CERTIFICATE_EXPIRED;
+		break;
+	case X509_V_ERR_CERT_REVOKED:
+		al=SSL_AD_CERTIFICATE_REVOKED;
+		break;
+	case X509_V_ERR_OUT_OF_MEM:
+		al=SSL_AD_INTERNAL_ERROR;
+		break;
+	case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+	case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
+	case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
+	case X509_V_ERR_CERT_CHAIN_TOO_LONG:
+	case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+	case X509_V_ERR_INVALID_CA:
+		al=SSL_AD_UNKNOWN_CA;
+		break;
+	case X509_V_ERR_APPLICATION_VERIFICATION:
+		al=SSL_AD_HANDSHAKE_FAILURE;
+		break;
+	case X509_V_ERR_INVALID_PURPOSE:
+		al=SSL_AD_UNSUPPORTED_CERTIFICATE;
+		break;
+	default:
+		al=SSL_AD_CERTIFICATE_UNKNOWN;
+		break;
+		}
+	return(al);
+	}
+
+#ifndef OPENSSL_NO_BUF_FREELISTS
+/* On some platforms, malloc() performance is bad enough that you can't just
+ * free() and malloc() buffers all the time, so we need to use freelists from
+ * unused buffers.  Currently, each freelist holds memory chunks of only a
+ * given size (list->chunklen); other sized chunks are freed and malloced.
+ * This doesn't help much if you're using many different SSL option settings
+ * with a given context.  (The options affecting buffer size are
+ * max_send_fragment, read buffer vs write buffer,
+ * SSL_OP_MICROSOFT_BIG_WRITE_BUFFER, SSL_OP_NO_COMPRESSION, and
+ * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS.)  Using a separate freelist for every
+ * possible size is not an option, since max_send_fragment can take on many
+ * different values.
+ *
+ * If you are on a platform with a slow malloc(), and you're using SSL
+ * connections with many different settings for these options, and you need to
+ * use the SSL_MOD_RELEASE_BUFFERS feature, you have a few options:
+ *    - Link against a faster malloc implementation.
+ *    - Use a separate SSL_CTX for each option set.
+ *    - Improve this code.
+ */
+static void *
+freelist_extract(SSL_CTX *ctx, int for_read, int sz)
+	{
+	SSL3_BUF_FREELIST *list;
+	SSL3_BUF_FREELIST_ENTRY *ent = NULL;
+	void *result = NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+	list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist;
+	if (list != NULL && sz == (int)list->chunklen)
+		ent = list->head;
+	if (ent != NULL)
+		{
+		list->head = ent->next;
+		result = ent;
+		if (--list->len == 0)
+			list->chunklen = 0;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+	if (!result)
+		result = OPENSSL_malloc(sz);
+	return result;
+}
+
+static void
+freelist_insert(SSL_CTX *ctx, int for_read, size_t sz, void *mem)
+	{
+	SSL3_BUF_FREELIST *list;
+	SSL3_BUF_FREELIST_ENTRY *ent;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+	list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist;
+	if (list != NULL &&
+	    (sz == list->chunklen || list->chunklen == 0) &&
+	    list->len < ctx->freelist_max_len &&
+	    sz >= sizeof(*ent))
+		{
+		list->chunklen = sz;
+		ent = mem;
+		ent->next = list->head;
+		list->head = ent;
+		++list->len;
+		mem = NULL;
+		}
+
+	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+	if (mem)
+		OPENSSL_free(mem);
+	}
+#else
+#define freelist_extract(c,fr,sz) OPENSSL_malloc(sz)
+#define freelist_insert(c,fr,sz,m) OPENSSL_free(m)
+#endif
+
+int ssl3_setup_read_buffer(SSL *s)
+	{
+	unsigned char *p;
+	size_t len,align=0,headerlen;
+	
+	if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
+		headerlen = DTLS1_RT_HEADER_LENGTH;
+	else
+		headerlen = SSL3_RT_HEADER_LENGTH;
+
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+	align = (-SSL3_RT_HEADER_LENGTH)&(SSL3_ALIGN_PAYLOAD-1);
+#endif
+
+	if (s->s3->rbuf.buf == NULL)
+		{
+		if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)
+			{
+			len = SSL3_RT_DEFAULT_PACKET_SIZE;
+			}
+  		else
+			{
+			len = SSL3_RT_MAX_PLAIN_LENGTH
+				+ SSL3_RT_MAX_ENCRYPTED_OVERHEAD
+				+ headerlen + align;
+			if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
+				{
+				s->s3->init_extra = 1;
+				len += SSL3_RT_MAX_EXTRA;
+				}
+			}
+#ifndef OPENSSL_NO_COMP
+		if (!(s->options & SSL_OP_NO_COMPRESSION))
+			len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
+#endif
+		if ((p=freelist_extract(s->ctx, 1, len)) == NULL)
+			goto err;
+		s->s3->rbuf.buf = p;
+		s->s3->rbuf.len = len;
+		}
+
+	s->packet= &(s->s3->rbuf.buf[0]);
+	return 1;
+
+err:
+	SSLerr(SSL_F_SSL3_SETUP_READ_BUFFER,ERR_R_MALLOC_FAILURE);
+	return 0;
+	}
+
+int ssl3_setup_write_buffer(SSL *s)
+	{
+	unsigned char *p;
+	size_t len,align=0,headerlen;
+
+	if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
+		headerlen = DTLS1_RT_HEADER_LENGTH + 1;
+	else
+		headerlen = SSL3_RT_HEADER_LENGTH;
+
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+	align = (-SSL3_RT_HEADER_LENGTH)&(SSL3_ALIGN_PAYLOAD-1);
+#endif
+
+	if (s->s3->wbuf.buf == NULL)
+		{
+		if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)
+			{
+			len = SSL3_RT_DEFAULT_PACKET_SIZE;
+			}
+  		else
+			{
+			len = s->max_send_fragment;
+			}
+		len += 0
+			+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
+			+ headerlen + align;
+#ifndef OPENSSL_NO_COMP
+		if (!(s->options & SSL_OP_NO_COMPRESSION))
+			len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
+#endif
+		if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
+			len += headerlen + align
+				+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
+		if ((p=freelist_extract(s->ctx, 0, len)) == NULL)
+			goto err;
+		s->s3->wbuf.buf = p;
+		s->s3->wbuf.len = len;
+		}
+
+	return 1;
+
+err:
+	SSLerr(SSL_F_SSL3_SETUP_WRITE_BUFFER,ERR_R_MALLOC_FAILURE);
+	return 0;
+	}
+
+
+int ssl3_setup_buffers(SSL *s)
+	{
+	if (!ssl3_setup_read_buffer(s))
+		return 0;
+	if (!ssl3_setup_write_buffer(s))
+		return 0;
+	return 1;
+	}
+
+int ssl3_release_write_buffer(SSL *s)
+	{
+	if (s->s3->wbuf.buf != NULL)
+		{
+		freelist_insert(s->ctx, 0, s->s3->wbuf.len, s->s3->wbuf.buf);
+		s->s3->wbuf.buf = NULL;
+		}
+	return 1;
+	}
+
+int ssl3_release_read_buffer(SSL *s)
+	{
+	if (s->s3->rbuf.buf != NULL)
+		{
+		freelist_insert(s->ctx, 1, s->s3->rbuf.len, s->s3->rbuf.buf);
+		s->s3->rbuf.buf = NULL;
+		}
+	return 1;
+	}
diff --git a/openssl/ssl/s3_clnt.c b/openssl/ssl/s3_clnt.c
new file mode 100644
index 0000000..04d6e5b
--- /dev/null
+++ b/openssl/ssl/s3_clnt.c
@@ -0,0 +1,3153 @@
+/* ssl/s3_clnt.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * ECC cipher suite support in OpenSSL originally written by
+ * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include "ssl_locl.h"
+#include "kssl_lcl.h"
+#include <openssl/buffer.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/md5.h>
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+static const SSL_METHOD *ssl3_get_client_method(int ver);
+static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b);
+
+static const SSL_METHOD *ssl3_get_client_method(int ver)
+	{
+	if (ver == SSL3_VERSION)
+		return(SSLv3_client_method());
+	else
+		return(NULL);
+	}
+
+IMPLEMENT_ssl3_meth_func(SSLv3_client_method,
+			ssl_undefined_function,
+			ssl3_connect,
+			ssl3_get_client_method)
+
+int ssl3_connect(SSL *s)
+	{
+	BUF_MEM *buf=NULL;
+	unsigned long Time=(unsigned long)time(NULL);
+	void (*cb)(const SSL *ssl,int type,int val)=NULL;
+	int ret= -1;
+	int new_state,state,skip=0;
+
+	RAND_add(&Time,sizeof(Time),0);
+	ERR_clear_error();
+	clear_sys_error();
+
+	if (s->info_callback != NULL)
+		cb=s->info_callback;
+	else if (s->ctx->info_callback != NULL)
+		cb=s->ctx->info_callback;
+	
+	s->in_handshake++;
+	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); 
+#if 0	/* Send app data in separate packet, otherwise, some particular site
+	 * (only one site so far) closes the socket.
+	 * Note: there is a very small chance that two TCP packets
+	 * could be arriving at server combined into a single TCP packet,
+	 * then trigger that site to break. We haven't encounter that though.
+	 */
+	if (SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH)
+		{
+		/* Send app data along with CCS/Finished */
+		s->s3->flags |= SSL3_FLAGS_DELAY_CLIENT_FINISHED;
+		}
+#endif
+
+	for (;;)
+		{
+		state=s->state;
+
+		switch(s->state)
+			{
+		case SSL_ST_RENEGOTIATE:
+			s->new_session=1;
+			s->state=SSL_ST_CONNECT;
+			s->ctx->stats.sess_connect_renegotiate++;
+			/* break */
+		case SSL_ST_BEFORE:
+		case SSL_ST_CONNECT:
+		case SSL_ST_BEFORE|SSL_ST_CONNECT:
+		case SSL_ST_OK|SSL_ST_CONNECT:
+
+			s->server=0;
+			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
+
+			if ((s->version & 0xff00 ) != 0x0300)
+				{
+				SSLerr(SSL_F_SSL3_CONNECT, ERR_R_INTERNAL_ERROR);
+				ret = -1;
+				goto end;
+				}
+				
+			/* s->version=SSL3_VERSION; */
+			s->type=SSL_ST_CONNECT;
+
+			if (s->init_buf == NULL)
+				{
+				if ((buf=BUF_MEM_new()) == NULL)
+					{
+					ret= -1;
+					goto end;
+					}
+				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
+					{
+					ret= -1;
+					goto end;
+					}
+				s->init_buf=buf;
+				buf=NULL;
+				}
+
+			if (!ssl3_setup_buffers(s)) { ret= -1; goto end; }
+
+			/* setup buffing BIO */
+			if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; }
+
+			/* don't push the buffering BIO quite yet */
+
+			ssl3_init_finished_mac(s);
+
+			s->state=SSL3_ST_CW_CLNT_HELLO_A;
+			s->ctx->stats.sess_connect++;
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_CW_CLNT_HELLO_A:
+		case SSL3_ST_CW_CLNT_HELLO_B:
+
+			s->shutdown=0;
+			ret=ssl3_client_hello(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_CR_SRVR_HELLO_A;
+			s->init_num=0;
+
+			/* turn on buffering for the next lot of output */
+			if (s->bbio != s->wbio)
+				s->wbio=BIO_push(s->bbio,s->wbio);
+
+			break;
+
+		case SSL3_ST_CR_SRVR_HELLO_A:
+		case SSL3_ST_CR_SRVR_HELLO_B:
+			ret=ssl3_get_server_hello(s);
+			if (ret <= 0) goto end;
+
+			if (s->hit)
+				s->state=SSL3_ST_CR_FINISHED_A;
+			else
+				s->state=SSL3_ST_CR_CERT_A;
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_CR_CERT_A:
+		case SSL3_ST_CR_CERT_B:
+#ifndef OPENSSL_NO_TLSEXT
+			ret=ssl3_check_finished(s);
+			if (ret <= 0) goto end;
+			if (ret == 2)
+				{
+				s->hit = 1;
+				if (s->tlsext_ticket_expected)
+					s->state=SSL3_ST_CR_SESSION_TICKET_A;
+				else
+					s->state=SSL3_ST_CR_FINISHED_A;
+				s->init_num=0;
+				break;
+				}
+#endif
+			/* Check if it is anon DH/ECDH */
+			/* or PSK */
+			if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
+			    !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
+				{
+				ret=ssl3_get_server_certificate(s);
+				if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_TLSEXT
+				if (s->tlsext_status_expected)
+					s->state=SSL3_ST_CR_CERT_STATUS_A;
+				else
+					s->state=SSL3_ST_CR_KEY_EXCH_A;
+				}
+			else
+				{
+				skip = 1;
+				s->state=SSL3_ST_CR_KEY_EXCH_A;
+				}
+#else
+				}
+			else
+				skip=1;
+
+			s->state=SSL3_ST_CR_KEY_EXCH_A;
+#endif
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_CR_KEY_EXCH_A:
+		case SSL3_ST_CR_KEY_EXCH_B:
+			ret=ssl3_get_key_exchange(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_CR_CERT_REQ_A;
+			s->init_num=0;
+
+			/* at this point we check that we have the
+			 * required stuff from the server */
+			if (!ssl3_check_cert_and_algorithm(s))
+				{
+				ret= -1;
+				goto end;
+				}
+			break;
+
+		case SSL3_ST_CR_CERT_REQ_A:
+		case SSL3_ST_CR_CERT_REQ_B:
+			ret=ssl3_get_certificate_request(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_CR_SRVR_DONE_A;
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_CR_SRVR_DONE_A:
+		case SSL3_ST_CR_SRVR_DONE_B:
+			ret=ssl3_get_server_done(s);
+			if (ret <= 0) goto end;
+			if (s->s3->tmp.cert_req)
+				s->state=SSL3_ST_CW_CERT_A;
+			else
+				s->state=SSL3_ST_CW_KEY_EXCH_A;
+			s->init_num=0;
+
+			break;
+
+		case SSL3_ST_CW_CERT_A:
+		case SSL3_ST_CW_CERT_B:
+		case SSL3_ST_CW_CERT_C:
+		case SSL3_ST_CW_CERT_D:
+			ret=ssl3_send_client_certificate(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_CW_KEY_EXCH_A;
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_CW_KEY_EXCH_A:
+		case SSL3_ST_CW_KEY_EXCH_B:
+			ret=ssl3_send_client_key_exchange(s);
+			if (ret <= 0) goto end;
+			/* EAY EAY EAY need to check for DH fix cert
+			 * sent back */
+			/* For TLS, cert_req is set to 2, so a cert chain
+			 * of nothing is sent, but no verify packet is sent */
+			/* XXX: For now, we do not support client 
+			 * authentication in ECDH cipher suites with
+			 * ECDH (rather than ECDSA) certificates.
+			 * We need to skip the certificate verify 
+			 * message when client's ECDH public key is sent 
+			 * inside the client certificate.
+			 */
+			if (s->s3->tmp.cert_req == 1)
+				{
+				s->state=SSL3_ST_CW_CERT_VRFY_A;
+				}
+			else
+				{
+				s->state=SSL3_ST_CW_CHANGE_A;
+				s->s3->change_cipher_spec=0;
+				}
+			if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY)
+				{
+				s->state=SSL3_ST_CW_CHANGE_A;
+				s->s3->change_cipher_spec=0;
+				}
+
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_CW_CERT_VRFY_A:
+		case SSL3_ST_CW_CERT_VRFY_B:
+			ret=ssl3_send_client_verify(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_CW_CHANGE_A;
+			s->init_num=0;
+			s->s3->change_cipher_spec=0;
+			break;
+
+		case SSL3_ST_CW_CHANGE_A:
+		case SSL3_ST_CW_CHANGE_B:
+			ret=ssl3_send_change_cipher_spec(s,
+				SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
+			if (ret <= 0) goto end;
+
+#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
+			s->state=SSL3_ST_CW_FINISHED_A;
+#else
+			if (s->next_proto_negotiated)
+				s->state=SSL3_ST_CW_NEXT_PROTO_A;
+			else
+				s->state=SSL3_ST_CW_FINISHED_A;
+#endif
+
+			s->init_num=0;
+
+			s->session->cipher=s->s3->tmp.new_cipher;
+#ifdef OPENSSL_NO_COMP
+			s->session->compress_meth=0;
+#else
+			if (s->s3->tmp.new_compression == NULL)
+				s->session->compress_meth=0;
+			else
+				s->session->compress_meth=
+					s->s3->tmp.new_compression->id;
+#endif
+			if (!s->method->ssl3_enc->setup_key_block(s))
+				{
+				ret= -1;
+				goto end;
+				}
+
+			if (!s->method->ssl3_enc->change_cipher_state(s,
+				SSL3_CHANGE_CIPHER_CLIENT_WRITE))
+				{
+				ret= -1;
+				goto end;
+				}
+
+			break;
+
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+		case SSL3_ST_CW_NEXT_PROTO_A:
+		case SSL3_ST_CW_NEXT_PROTO_B:
+			ret=ssl3_send_next_proto(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_CW_FINISHED_A;
+			break;
+#endif
+
+		case SSL3_ST_CW_FINISHED_A:
+		case SSL3_ST_CW_FINISHED_B:
+			ret=ssl3_send_finished(s,
+				SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,
+				s->method->ssl3_enc->client_finished_label,
+				s->method->ssl3_enc->client_finished_label_len);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_CW_FLUSH;
+
+			/* clear flags */
+			s->s3->flags&= ~SSL3_FLAGS_POP_BUFFER;
+			if (s->hit)
+				{
+				s->s3->tmp.next_state=SSL_ST_OK;
+				if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED)
+					{
+					s->state=SSL_ST_OK;
+					s->s3->flags|=SSL3_FLAGS_POP_BUFFER;
+					s->s3->delay_buf_pop_ret=0;
+					}
+				}
+			else
+				{
+				if ((SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH) && SSL_get_cipher_bits(s, NULL) >= 128
+				    && s->s3->previous_server_finished_len == 0 /* no cutthrough on renegotiation (would complicate the state machine) */
+				   )
+					{
+					if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED)
+						{
+						s->state=SSL3_ST_CUTTHROUGH_COMPLETE;
+						s->s3->flags|=SSL3_FLAGS_POP_BUFFER;
+						s->s3->delay_buf_pop_ret=0;
+						}
+					else
+						{
+						s->s3->tmp.next_state=SSL3_ST_CUTTHROUGH_COMPLETE;
+						}
+					}
+				else
+					{
+#ifndef OPENSSL_NO_TLSEXT
+					/* Allow NewSessionTicket if ticket expected */
+					if (s->tlsext_ticket_expected)
+						s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
+					else
+#endif
+						s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
+					}
+				}
+			s->init_num=0;
+			break;
+
+#ifndef OPENSSL_NO_TLSEXT
+		case SSL3_ST_CR_SESSION_TICKET_A:
+		case SSL3_ST_CR_SESSION_TICKET_B:
+			ret=ssl3_get_new_session_ticket(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_CR_FINISHED_A;
+			s->init_num=0;
+		break;
+
+		case SSL3_ST_CR_CERT_STATUS_A:
+		case SSL3_ST_CR_CERT_STATUS_B:
+			ret=ssl3_get_cert_status(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_CR_KEY_EXCH_A;
+			s->init_num=0;
+		break;
+#endif
+
+		case SSL3_ST_CR_FINISHED_A:
+		case SSL3_ST_CR_FINISHED_B:
+
+			ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
+				SSL3_ST_CR_FINISHED_B);
+			if (ret <= 0) goto end;
+
+			if (s->hit)
+				s->state=SSL3_ST_CW_CHANGE_A;
+			else
+				s->state=SSL_ST_OK;
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_CW_FLUSH:
+			s->rwstate=SSL_WRITING;
+			if (BIO_flush(s->wbio) <= 0)
+				{
+				ret= -1;
+				goto end;
+				}
+			s->rwstate=SSL_NOTHING;
+			s->state=s->s3->tmp.next_state;
+			break;
+
+		case SSL3_ST_CUTTHROUGH_COMPLETE:
+#ifndef OPENSSL_NO_TLSEXT
+			/* Allow NewSessionTicket if ticket expected */
+			if (s->tlsext_ticket_expected)
+				s->state=SSL3_ST_CR_SESSION_TICKET_A;
+			else
+#endif
+				s->state=SSL3_ST_CR_FINISHED_A;
+
+			/* SSL_write() will take care of flushing buffered data if
+			 * DELAY_CLIENT_FINISHED is set.
+			 */
+			if (!(s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED))
+				ssl_free_wbio_buffer(s);
+			ret = 1;
+			goto end;
+			/* break; */
+
+		case SSL_ST_OK:
+			/* clean a few things up */
+			ssl3_cleanup_key_block(s);
+
+			if (s->init_buf != NULL)
+				{
+				BUF_MEM_free(s->init_buf);
+				s->init_buf=NULL;
+				}
+
+			/* If we are not 'joining' the last two packets,
+			 * remove the buffering now */
+			if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER))
+				ssl_free_wbio_buffer(s);
+			/* else do it later in ssl3_write */
+
+			s->init_num=0;
+			s->new_session=0;
+
+			ssl_update_cache(s,SSL_SESS_CACHE_CLIENT);
+			if (s->hit) s->ctx->stats.sess_hit++;
+
+			ret=1;
+			/* s->server=0; */
+			s->handshake_func=ssl3_connect;
+			s->ctx->stats.sess_connect_good++;
+
+			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
+
+			goto end;
+			/* break; */
+			
+		default:
+			SSLerr(SSL_F_SSL3_CONNECT,SSL_R_UNKNOWN_STATE);
+			ret= -1;
+			goto end;
+			/* break; */
+			}
+
+		/* did we do anything */
+		if (!s->s3->tmp.reuse_message && !skip)
+			{
+			if (s->debug)
+				{
+				if ((ret=BIO_flush(s->wbio)) <= 0)
+					goto end;
+				}
+
+			if ((cb != NULL) && (s->state != state))
+				{
+				new_state=s->state;
+				s->state=state;
+				cb(s,SSL_CB_CONNECT_LOOP,1);
+				s->state=new_state;
+				}
+			}
+		skip=0;
+		}
+end:
+	s->in_handshake--;
+	if (buf != NULL)
+		BUF_MEM_free(buf);
+	if (cb != NULL)
+		cb(s,SSL_CB_CONNECT_EXIT,ret);
+	return(ret);
+	}
+
+
+int ssl3_client_hello(SSL *s)
+	{
+	unsigned char *buf;
+	unsigned char *p,*d;
+	int i;
+	unsigned long Time,l;
+#ifndef OPENSSL_NO_COMP
+	int j;
+	SSL_COMP *comp;
+#endif
+
+	buf=(unsigned char *)s->init_buf->data;
+	if (s->state == SSL3_ST_CW_CLNT_HELLO_A)
+		{
+		SSL_SESSION *sess = s->session;
+		if ((sess == NULL) ||
+			(sess->ssl_version != s->version) ||
+#ifdef OPENSSL_NO_TLSEXT
+			!sess->session_id_length ||
+#else
+			(!sess->session_id_length && !sess->tlsext_tick) ||
+#endif
+			(sess->not_resumable))
+			{
+		        if (!s->session_creation_enabled)
+				{
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+				SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
+				goto err;
+				}
+			if (!ssl_get_new_session(s,0))
+				goto err;
+			}
+		/* else use the pre-loaded session */
+
+		p=s->s3->client_random;
+		Time=(unsigned long)time(NULL);			/* Time */
+		l2n(Time,p);
+		if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
+			goto err;
+
+		/* Do the message type and length last */
+		d=p= &(buf[4]);
+
+		*(p++)=s->version>>8;
+		*(p++)=s->version&0xff;
+		s->client_version=s->version;
+
+		/* Random stuff */
+		memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
+		p+=SSL3_RANDOM_SIZE;
+
+		/* Session ID */
+		if (s->new_session)
+			i=0;
+		else
+			i=s->session->session_id_length;
+		*(p++)=i;
+		if (i != 0)
+			{
+			if (i > (int)sizeof(s->session->session_id))
+				{
+				SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+			memcpy(p,s->session->session_id,i);
+			p+=i;
+			}
+		
+		/* Ciphers supported */
+		i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),0);
+		if (i == 0)
+			{
+			SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
+			goto err;
+			}
+		s2n(i,p);
+		p+=i;
+
+		/* COMPRESSION */
+#ifdef OPENSSL_NO_COMP
+		*(p++)=1;
+#else
+
+		if ((s->options & SSL_OP_NO_COMPRESSION)
+					|| !s->ctx->comp_methods)
+			j=0;
+		else
+			j=sk_SSL_COMP_num(s->ctx->comp_methods);
+		*(p++)=1+j;
+		for (i=0; i<j; i++)
+			{
+			comp=sk_SSL_COMP_value(s->ctx->comp_methods,i);
+			*(p++)=comp->id;
+			}
+#endif
+		*(p++)=0; /* Add the NULL method */
+
+#ifndef OPENSSL_NO_TLSEXT
+		/* TLS extensions*/
+		if (ssl_prepare_clienthello_tlsext(s) <= 0)
+			{
+			SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
+			goto err;
+			}
+		if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
+			{
+			SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+#endif
+		
+		l=(p-d);
+		d=buf;
+		*(d++)=SSL3_MT_CLIENT_HELLO;
+		l2n3(l,d);
+
+		s->state=SSL3_ST_CW_CLNT_HELLO_B;
+		/* number of bytes to write */
+		s->init_num=p-buf;
+		s->init_off=0;
+		}
+
+	/* SSL3_ST_CW_CLNT_HELLO_B */
+	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
+err:
+	return(-1);
+	}
+
+int ssl3_get_server_hello(SSL *s)
+	{
+	STACK_OF(SSL_CIPHER) *sk;
+	const SSL_CIPHER *c;
+	unsigned char *p,*d;
+	int i,al,ok;
+	unsigned int j;
+	long n;
+#ifndef OPENSSL_NO_COMP
+	SSL_COMP *comp;
+#endif
+
+	n=s->method->ssl_get_message(s,
+		SSL3_ST_CR_SRVR_HELLO_A,
+		SSL3_ST_CR_SRVR_HELLO_B,
+		-1,
+		20000, /* ?? */
+		&ok);
+
+	if (!ok) return((int)n);
+
+	if ( SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
+		{
+		if ( s->s3->tmp.message_type == DTLS1_MT_HELLO_VERIFY_REQUEST)
+			{
+			if ( s->d1->send_cookie == 0)
+				{
+				s->s3->tmp.reuse_message = 1;
+				return 1;
+				}
+			else /* already sent a cookie */
+				{
+				al=SSL_AD_UNEXPECTED_MESSAGE;
+				SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_MESSAGE_TYPE);
+				goto f_err;
+				}
+			}
+		}
+	
+	if ( s->s3->tmp.message_type != SSL3_MT_SERVER_HELLO)
+		{
+		al=SSL_AD_UNEXPECTED_MESSAGE;
+		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_MESSAGE_TYPE);
+		goto f_err;
+		}
+
+	d=p=(unsigned char *)s->init_msg;
+
+	if ((p[0] != (s->version>>8)) || (p[1] != (s->version&0xff)))
+		{
+		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_SSL_VERSION);
+		s->version=(s->version&0xff00)|p[1];
+		al=SSL_AD_PROTOCOL_VERSION;
+		goto f_err;
+		}
+	p+=2;
+
+	/* load the server hello data */
+	/* load the server random */
+	memcpy(s->s3->server_random,p,SSL3_RANDOM_SIZE);
+	p+=SSL3_RANDOM_SIZE;
+
+	/* get the session-id */
+	j= *(p++);
+
+	if ((j > sizeof s->session->session_id) || (j > SSL3_SESSION_ID_SIZE))
+		{
+		al=SSL_AD_ILLEGAL_PARAMETER;
+		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SSL3_SESSION_ID_TOO_LONG);
+		goto f_err;
+		}
+
+#ifndef OPENSSL_NO_TLSEXT
+	/* check if we want to resume the session based on external pre-shared secret */
+	if (s->version >= TLS1_VERSION && s->tls_session_secret_cb)
+		{
+		SSL_CIPHER *pref_cipher=NULL;
+		s->session->master_key_length=sizeof(s->session->master_key);
+		if (s->tls_session_secret_cb(s, s->session->master_key,
+					     &s->session->master_key_length,
+					     NULL, &pref_cipher,
+					     s->tls_session_secret_cb_arg))
+			{
+			s->session->cipher = pref_cipher ?
+				pref_cipher : ssl_get_cipher_by_char(s, p+j);
+			}
+		}
+#endif /* OPENSSL_NO_TLSEXT */
+
+	if (j != 0 && j == s->session->session_id_length
+	    && memcmp(p,s->session->session_id,j) == 0)
+	    {
+	    if(s->sid_ctx_length != s->session->sid_ctx_length
+	       || memcmp(s->session->sid_ctx,s->sid_ctx,s->sid_ctx_length))
+		{
+		/* actually a client application bug */
+		al=SSL_AD_ILLEGAL_PARAMETER;
+		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
+		goto f_err;
+		}
+	    s->hit=1;
+	    }
+	else	/* a miss or crap from the other end */
+		{
+		/* If we were trying for session-id reuse, make a new
+		 * SSL_SESSION so we don't stuff up other people */
+		s->hit=0;
+		if (s->session->session_id_length > 0)
+			{
+		        if (!s->session_creation_enabled)
+				{
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+				SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
+				goto err;
+				}
+			if (!ssl_get_new_session(s,0))
+				{
+				al=SSL_AD_INTERNAL_ERROR;
+				goto f_err;
+				}
+			}
+		s->session->session_id_length=j;
+		memcpy(s->session->session_id,p,j); /* j could be 0 */
+		}
+	p+=j;
+	c=ssl_get_cipher_by_char(s,p);
+	if (c == NULL)
+		{
+		/* unknown cipher */
+		al=SSL_AD_ILLEGAL_PARAMETER;
+		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNKNOWN_CIPHER_RETURNED);
+		goto f_err;
+		}
+	p+=ssl_put_cipher_by_char(s,NULL,NULL);
+
+	sk=ssl_get_ciphers_by_id(s);
+	i=sk_SSL_CIPHER_find(sk,c);
+	if (i < 0)
+		{
+		/* we did not say we would use this cipher */
+		al=SSL_AD_ILLEGAL_PARAMETER;
+		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED);
+		goto f_err;
+		}
+
+	/* Depending on the session caching (internal/external), the cipher
+	   and/or cipher_id values may not be set. Make sure that
+	   cipher_id is set and use it for comparison. */
+	if (s->session->cipher)
+		s->session->cipher_id = s->session->cipher->id;
+	if (s->hit && (s->session->cipher_id != c->id))
+		{
+/* Workaround is now obsolete */
+#if 0
+		if (!(s->options &
+			SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG))
+#endif
+			{
+			al=SSL_AD_ILLEGAL_PARAMETER;
+			SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
+			goto f_err;
+			}
+		}
+	s->s3->tmp.new_cipher=c;
+	if (!ssl3_digest_cached_records(s))
+		goto f_err;
+
+	/* lets get the compression algorithm */
+	/* COMPRESSION */
+#ifdef OPENSSL_NO_COMP
+	if (*(p++) != 0)
+		{
+		al=SSL_AD_ILLEGAL_PARAMETER;
+		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+		goto f_err;
+		}
+	/* If compression is disabled we'd better not try to resume a session
+	 * using compression.
+	 */
+	if (s->session->compress_meth != 0)
+		{
+		al=SSL_AD_INTERNAL_ERROR;
+		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_INCONSISTENT_COMPRESSION);
+		goto f_err;
+		}
+#else
+	j= *(p++);
+	if (s->hit && j != s->session->compress_meth)
+		{
+		al=SSL_AD_ILLEGAL_PARAMETER;
+		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED);
+		goto f_err;
+		}
+	if (j == 0)
+		comp=NULL;
+	else if (s->options & SSL_OP_NO_COMPRESSION)
+		{
+		al=SSL_AD_ILLEGAL_PARAMETER;
+		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_COMPRESSION_DISABLED);
+		goto f_err;
+		}
+	else
+		comp=ssl3_comp_find(s->ctx->comp_methods,j);
+	
+	if ((j != 0) && (comp == NULL))
+		{
+		al=SSL_AD_ILLEGAL_PARAMETER;
+		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+		goto f_err;
+		}
+	else
+		{
+		s->s3->tmp.new_compression=comp;
+		}
+#endif
+
+#ifndef OPENSSL_NO_TLSEXT
+	/* TLS extensions*/
+	if (s->version >= SSL3_VERSION)
+		{
+		if (!ssl_parse_serverhello_tlsext(s,&p,d,n, &al))
+			{
+			/* 'al' set by ssl_parse_serverhello_tlsext */
+			SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_PARSE_TLSEXT);
+			goto f_err; 
+			}
+		if (ssl_check_serverhello_tlsext(s) <= 0)
+			{
+			SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT);
+				goto err;
+			}
+		}
+#endif
+
+	if (p != (d+n))
+		{
+		/* wrong packet length */
+		al=SSL_AD_DECODE_ERROR;
+		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_PACKET_LENGTH);
+		goto f_err;
+		}
+
+	return(1);
+f_err:
+	ssl3_send_alert(s,SSL3_AL_FATAL,al);
+err:
+	return(-1);
+	}
+
+int ssl3_get_server_certificate(SSL *s)
+	{
+	int al,i,ok,ret= -1;
+	unsigned long n,nc,llen,l;
+	X509 *x=NULL;
+	const unsigned char *q,*p;
+	unsigned char *d;
+	STACK_OF(X509) *sk=NULL;
+	SESS_CERT *sc;
+	EVP_PKEY *pkey=NULL;
+	int need_cert = 1; /* VRS: 0=> will allow null cert if auth == KRB5 */
+
+	n=s->method->ssl_get_message(s,
+		SSL3_ST_CR_CERT_A,
+		SSL3_ST_CR_CERT_B,
+		-1,
+		s->max_cert_list,
+		&ok);
+
+	if (!ok) return((int)n);
+
+	if ((s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) ||
+		((s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) && 
+		(s->s3->tmp.message_type == SSL3_MT_SERVER_DONE)))
+		{
+		s->s3->tmp.reuse_message=1;
+		return(1);
+		}
+
+	if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE)
+		{
+		al=SSL_AD_UNEXPECTED_MESSAGE;
+		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_BAD_MESSAGE_TYPE);
+		goto f_err;
+		}
+	p=d=(unsigned char *)s->init_msg;
+
+	if ((sk=sk_X509_new_null()) == NULL)
+		{
+		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	n2l3(p,llen);
+	if (llen+3 != n)
+		{
+		al=SSL_AD_DECODE_ERROR;
+		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_LENGTH_MISMATCH);
+		goto f_err;
+		}
+	for (nc=0; nc<llen; )
+		{
+		n2l3(p,l);
+		if ((l+nc+3) > llen)
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH);
+			goto f_err;
+			}
+
+		q=p;
+		x=d2i_X509(NULL,&q,l);
+		if (x == NULL)
+			{
+			al=SSL_AD_BAD_CERTIFICATE;
+			SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,ERR_R_ASN1_LIB);
+			goto f_err;
+			}
+		if (q != (p+l))
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH);
+			goto f_err;
+			}
+		if (!sk_X509_push(sk,x))
+			{
+			SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		x=NULL;
+		nc+=l+3;
+		p=q;
+		}
+
+	i=ssl_verify_cert_chain(s,sk);
+	if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0)
+#ifndef OPENSSL_NO_KRB5
+	    && !((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) &&
+		 (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
+#endif /* OPENSSL_NO_KRB5 */
+		)
+		{
+		al=ssl_verify_alarm_type(s->verify_result);
+		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED);
+		goto f_err; 
+		}
+	ERR_clear_error(); /* but we keep s->verify_result */
+
+	sc=ssl_sess_cert_new();
+	if (sc == NULL) goto err;
+
+	if (s->session->sess_cert) ssl_sess_cert_free(s->session->sess_cert);
+	s->session->sess_cert=sc;
+
+	sc->cert_chain=sk;
+	/* Inconsistency alert: cert_chain does include the peer's
+	 * certificate, which we don't include in s3_srvr.c */
+	x=sk_X509_value(sk,0);
+	sk=NULL;
+ 	/* VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end*/
+
+	pkey=X509_get_pubkey(x);
+
+	/* VRS: allow null cert if auth == KRB5 */
+	need_cert = ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) &&
+	            (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
+	            ? 0 : 1;
+
+#ifdef KSSL_DEBUG
+	printf("pkey,x = %p, %p\n", pkey,x);
+	printf("ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x,pkey));
+	printf("cipher, alg, nc = %s, %lx, %lx, %d\n", s->s3->tmp.new_cipher->name,
+		s->s3->tmp.new_cipher->algorithm_mkey, s->s3->tmp.new_cipher->algorithm_auth, need_cert);
+#endif    /* KSSL_DEBUG */
+
+	if (need_cert && ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey)))
+		{
+		x=NULL;
+		al=SSL3_AL_FATAL;
+		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
+			SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
+		goto f_err;
+		}
+
+	i=ssl_cert_type(x,pkey);
+	if (need_cert && i < 0)
+		{
+		x=NULL;
+		al=SSL3_AL_FATAL;
+		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
+			SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+		goto f_err;
+		}
+
+	if (need_cert)
+		{
+		sc->peer_cert_type=i;
+		CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
+		/* Why would the following ever happen?
+		 * We just created sc a couple of lines ago. */
+		if (sc->peer_pkeys[i].x509 != NULL)
+			X509_free(sc->peer_pkeys[i].x509);
+		sc->peer_pkeys[i].x509=x;
+		sc->peer_key= &(sc->peer_pkeys[i]);
+
+		if (s->session->peer != NULL)
+			X509_free(s->session->peer);
+		CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
+		s->session->peer=x;
+		}
+	else
+		{
+		sc->peer_cert_type=i;
+		sc->peer_key= NULL;
+
+		if (s->session->peer != NULL)
+			X509_free(s->session->peer);
+		s->session->peer=NULL;
+		}
+	s->session->verify_result = s->verify_result;
+
+	x=NULL;
+	ret=1;
+
+	if (0)
+		{
+f_err:
+		ssl3_send_alert(s,SSL3_AL_FATAL,al);
+		}
+err:
+	EVP_PKEY_free(pkey);
+	X509_free(x);
+	sk_X509_pop_free(sk,X509_free);
+	return(ret);
+	}
+
+int ssl3_get_key_exchange(SSL *s)
+	{
+#ifndef OPENSSL_NO_RSA
+	unsigned char *q,md_buf[EVP_MAX_MD_SIZE*2];
+#endif
+	EVP_MD_CTX md_ctx;
+	unsigned char *param,*p;
+	int al,i,j,param_len,ok;
+	long n,alg_k,alg_a;
+	EVP_PKEY *pkey=NULL;
+#ifndef OPENSSL_NO_RSA
+	RSA *rsa=NULL;
+#endif
+#ifndef OPENSSL_NO_DH
+	DH *dh=NULL;
+#endif
+#ifndef OPENSSL_NO_ECDH
+	EC_KEY *ecdh = NULL;
+	BN_CTX *bn_ctx = NULL;
+	EC_POINT *srvr_ecpoint = NULL;
+	int curve_nid = 0;
+	int encoded_pt_len = 0;
+#endif
+
+	/* use same message size as in ssl3_get_certificate_request()
+	 * as ServerKeyExchange message may be skipped */
+	n=s->method->ssl_get_message(s,
+		SSL3_ST_CR_KEY_EXCH_A,
+		SSL3_ST_CR_KEY_EXCH_B,
+		-1,
+		s->max_cert_list,
+		&ok);
+	if (!ok) return((int)n);
+
+	if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE)
+		{
+#ifndef OPENSSL_NO_PSK
+		/* In plain PSK ciphersuite, ServerKeyExchange can be
+		   omitted if no identity hint is sent. Set
+		   session->sess_cert anyway to avoid problems
+		   later.*/
+		if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
+			{
+			s->session->sess_cert=ssl_sess_cert_new();
+			if (s->ctx->psk_identity_hint)
+				OPENSSL_free(s->ctx->psk_identity_hint);
+			s->ctx->psk_identity_hint = NULL;
+			}
+#endif
+		s->s3->tmp.reuse_message=1;
+		return(1);
+		}
+
+	param=p=(unsigned char *)s->init_msg;
+	if (s->session->sess_cert != NULL)
+		{
+#ifndef OPENSSL_NO_RSA
+		if (s->session->sess_cert->peer_rsa_tmp != NULL)
+			{
+			RSA_free(s->session->sess_cert->peer_rsa_tmp);
+			s->session->sess_cert->peer_rsa_tmp=NULL;
+			}
+#endif
+#ifndef OPENSSL_NO_DH
+		if (s->session->sess_cert->peer_dh_tmp)
+			{
+			DH_free(s->session->sess_cert->peer_dh_tmp);
+			s->session->sess_cert->peer_dh_tmp=NULL;
+			}
+#endif
+#ifndef OPENSSL_NO_ECDH
+		if (s->session->sess_cert->peer_ecdh_tmp)
+			{
+			EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp);
+			s->session->sess_cert->peer_ecdh_tmp=NULL;
+			}
+#endif
+		}
+	else
+		{
+		s->session->sess_cert=ssl_sess_cert_new();
+		}
+
+	param_len=0;
+	alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
+	alg_a=s->s3->tmp.new_cipher->algorithm_auth;
+	EVP_MD_CTX_init(&md_ctx);
+
+#ifndef OPENSSL_NO_PSK
+	if (alg_k & SSL_kPSK)
+		{
+		char tmp_id_hint[PSK_MAX_IDENTITY_LEN+1];
+
+		al=SSL_AD_HANDSHAKE_FAILURE;
+		n2s(p,i);
+		param_len=i+2;
+		/* Store PSK identity hint for later use, hint is used
+		 * in ssl3_send_client_key_exchange.  Assume that the
+		 * maximum length of a PSK identity hint can be as
+		 * long as the maximum length of a PSK identity. */
+		if (i > PSK_MAX_IDENTITY_LEN)
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+				SSL_R_DATA_LENGTH_TOO_LONG);
+			goto f_err;
+			}
+		if (param_len > n)
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+				SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH);
+			goto f_err;
+			}
+		/* If received PSK identity hint contains NULL
+		 * characters, the hint is truncated from the first
+		 * NULL. p may not be ending with NULL, so create a
+		 * NULL-terminated string. */
+		memcpy(tmp_id_hint, p, i);
+		memset(tmp_id_hint+i, 0, PSK_MAX_IDENTITY_LEN+1-i);
+		if (s->ctx->psk_identity_hint != NULL)
+			OPENSSL_free(s->ctx->psk_identity_hint);
+		s->ctx->psk_identity_hint = BUF_strdup(tmp_id_hint);
+		if (s->ctx->psk_identity_hint == NULL)
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
+			goto f_err;
+			}	   
+
+		p+=i;
+		n-=param_len;
+		}
+	else
+#endif /* !OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_RSA
+	if (alg_k & SSL_kRSA)
+		{
+		if ((rsa=RSA_new()) == NULL)
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		n2s(p,i);
+		param_len=i+2;
+		if (param_len > n)
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_MODULUS_LENGTH);
+			goto f_err;
+			}
+		if (!(rsa->n=BN_bin2bn(p,i,rsa->n)))
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+			goto err;
+			}
+		p+=i;
+
+		n2s(p,i);
+		param_len+=i+2;
+		if (param_len > n)
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_E_LENGTH);
+			goto f_err;
+			}
+		if (!(rsa->e=BN_bin2bn(p,i,rsa->e)))
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+			goto err;
+			}
+		p+=i;
+		n-=param_len;
+
+		/* this should be because we are using an export cipher */
+		if (alg_a & SSL_aRSA)
+			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
+		else
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+		s->session->sess_cert->peer_rsa_tmp=rsa;
+		rsa=NULL;
+		}
+#else /* OPENSSL_NO_RSA */
+	if (0)
+		;
+#endif
+#ifndef OPENSSL_NO_DH
+	else if (alg_k & SSL_kEDH)
+		{
+		if ((dh=DH_new()) == NULL)
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_DH_LIB);
+			goto err;
+			}
+		n2s(p,i);
+		param_len=i+2;
+		if (param_len > n)
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_P_LENGTH);
+			goto f_err;
+			}
+		if (!(dh->p=BN_bin2bn(p,i,NULL)))
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+			goto err;
+			}
+		p+=i;
+
+		n2s(p,i);
+		param_len+=i+2;
+		if (param_len > n)
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_G_LENGTH);
+			goto f_err;
+			}
+		if (!(dh->g=BN_bin2bn(p,i,NULL)))
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+			goto err;
+			}
+		p+=i;
+
+		n2s(p,i);
+		param_len+=i+2;
+		if (param_len > n)
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_PUB_KEY_LENGTH);
+			goto f_err;
+			}
+		if (!(dh->pub_key=BN_bin2bn(p,i,NULL)))
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+			goto err;
+			}
+		p+=i;
+		n-=param_len;
+
+#ifndef OPENSSL_NO_RSA
+		if (alg_a & SSL_aRSA)
+			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
+#else
+		if (0)
+			;
+#endif
+#ifndef OPENSSL_NO_DSA
+		else if (alg_a & SSL_aDSS)
+			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].x509);
+#endif
+		/* else anonymous DH, so no certificate or pkey. */
+
+		s->session->sess_cert->peer_dh_tmp=dh;
+		dh=NULL;
+		}
+	else if ((alg_k & SSL_kDHr) || (alg_k & SSL_kDHd))
+		{
+		al=SSL_AD_ILLEGAL_PARAMETER;
+		SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER);
+		goto f_err;
+		}
+#endif /* !OPENSSL_NO_DH */
+
+#ifndef OPENSSL_NO_ECDH
+	else if (alg_k & SSL_kEECDH)
+		{
+		EC_GROUP *ngroup;
+		const EC_GROUP *group;
+
+		if ((ecdh=EC_KEY_new()) == NULL)
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+
+		/* Extract elliptic curve parameters and the
+		 * server's ephemeral ECDH public key.
+		 * Keep accumulating lengths of various components in
+		 * param_len and make sure it never exceeds n.
+		 */
+
+		/* XXX: For now we only support named (not generic) curves
+		 * and the ECParameters in this case is just three bytes.
+		 */
+		param_len=3;
+		if ((param_len > n) ||
+		    (*p != NAMED_CURVE_TYPE) || 
+		    ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0)) 
+			{
+			al=SSL_AD_INTERNAL_ERROR;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
+			goto f_err;
+			}
+
+		ngroup = EC_GROUP_new_by_curve_name(curve_nid);
+		if (ngroup == NULL)
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_EC_LIB);
+			goto err;
+			}
+		if (EC_KEY_set_group(ecdh, ngroup) == 0)
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_EC_LIB);
+			goto err;
+			}
+		EC_GROUP_free(ngroup);
+
+		group = EC_KEY_get0_group(ecdh);
+
+		if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
+		    (EC_GROUP_get_degree(group) > 163))
+			{
+			al=SSL_AD_EXPORT_RESTRICTION;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER);
+			goto f_err;
+			}
+
+		p+=3;
+
+		/* Next, get the encoded ECPoint */
+		if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) ||
+		    ((bn_ctx = BN_CTX_new()) == NULL))
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+
+		encoded_pt_len = *p;  /* length of encoded point */
+		p+=1;
+		param_len += (1 + encoded_pt_len);
+		if ((param_len > n) ||
+		    (EC_POINT_oct2point(group, srvr_ecpoint, 
+			p, encoded_pt_len, bn_ctx) == 0))
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_ECPOINT);
+			goto f_err;
+			}
+
+		n-=param_len;
+		p+=encoded_pt_len;
+
+		/* The ECC/TLS specification does not mention
+		 * the use of DSA to sign ECParameters in the server
+		 * key exchange message. We do support RSA and ECDSA.
+		 */
+		if (0) ;
+#ifndef OPENSSL_NO_RSA
+		else if (alg_a & SSL_aRSA)
+			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
+#endif
+#ifndef OPENSSL_NO_ECDSA
+		else if (alg_a & SSL_aECDSA)
+			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_ECC].x509);
+#endif
+		/* else anonymous ECDH, so no certificate or pkey. */
+		EC_KEY_set_public_key(ecdh, srvr_ecpoint);
+		s->session->sess_cert->peer_ecdh_tmp=ecdh;
+		ecdh=NULL;
+		BN_CTX_free(bn_ctx);
+		bn_ctx = NULL;
+		EC_POINT_free(srvr_ecpoint);
+		srvr_ecpoint = NULL;
+		}
+	else if (alg_k)
+		{
+		al=SSL_AD_UNEXPECTED_MESSAGE;
+		SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
+		goto f_err;
+		}
+#endif /* !OPENSSL_NO_ECDH */
+
+
+	/* p points to the next byte, there are 'n' bytes left */
+
+	/* if it was signed, check the signature */
+	if (pkey != NULL)
+		{
+		n2s(p,i);
+		n-=2;
+		j=EVP_PKEY_size(pkey);
+
+		if ((i != n) || (n > j) || (n <= 0))
+			{
+			/* wrong packet length */
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_WRONG_SIGNATURE_LENGTH);
+			goto f_err;
+			}
+
+#ifndef OPENSSL_NO_RSA
+		if (pkey->type == EVP_PKEY_RSA)
+			{
+			int num;
+
+			j=0;
+			q=md_buf;
+			for (num=2; num > 0; num--)
+				{
+				EVP_DigestInit_ex(&md_ctx,(num == 2)
+					?s->ctx->md5:s->ctx->sha1, NULL);
+				EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
+				EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
+				EVP_DigestUpdate(&md_ctx,param,param_len);
+				EVP_DigestFinal_ex(&md_ctx,q,(unsigned int *)&i);
+				q+=i;
+				j+=i;
+				}
+			i=RSA_verify(NID_md5_sha1, md_buf, j, p, n,
+								pkey->pkey.rsa);
+			if (i < 0)
+				{
+				al=SSL_AD_DECRYPT_ERROR;
+				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT);
+				goto f_err;
+				}
+			if (i == 0)
+				{
+				/* bad signature */
+				al=SSL_AD_DECRYPT_ERROR;
+				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SIGNATURE);
+				goto f_err;
+				}
+			}
+		else
+#endif
+#ifndef OPENSSL_NO_DSA
+			if (pkey->type == EVP_PKEY_DSA)
+			{
+			/* lets do DSS */
+			EVP_VerifyInit_ex(&md_ctx,EVP_dss1(), NULL);
+			EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
+			EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
+			EVP_VerifyUpdate(&md_ctx,param,param_len);
+			if (EVP_VerifyFinal(&md_ctx,p,(int)n,pkey) <= 0)
+				{
+				/* bad signature */
+				al=SSL_AD_DECRYPT_ERROR;
+				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SIGNATURE);
+				goto f_err;
+				}
+			}
+		else
+#endif
+#ifndef OPENSSL_NO_ECDSA
+			if (pkey->type == EVP_PKEY_EC)
+			{
+			/* let's do ECDSA */
+			EVP_VerifyInit_ex(&md_ctx,EVP_ecdsa(), NULL);
+			EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
+			EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
+			EVP_VerifyUpdate(&md_ctx,param,param_len);
+			if (EVP_VerifyFinal(&md_ctx,p,(int)n,pkey) <= 0)
+				{
+				/* bad signature */
+				al=SSL_AD_DECRYPT_ERROR;
+				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SIGNATURE);
+				goto f_err;
+				}
+			}
+		else
+#endif
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+		}
+	else
+		{
+		if (!(alg_a & SSL_aNULL) && !(alg_k & SSL_kPSK))
+			/* aNULL or kPSK do not need public keys */
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+		/* still data left over */
+		if (n != 0)
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_EXTRA_DATA_IN_MESSAGE);
+			goto f_err;
+			}
+		}
+	EVP_PKEY_free(pkey);
+	EVP_MD_CTX_cleanup(&md_ctx);
+	return(1);
+f_err:
+	ssl3_send_alert(s,SSL3_AL_FATAL,al);
+err:
+	EVP_PKEY_free(pkey);
+#ifndef OPENSSL_NO_RSA
+	if (rsa != NULL)
+		RSA_free(rsa);
+#endif
+#ifndef OPENSSL_NO_DH
+	if (dh != NULL)
+		DH_free(dh);
+#endif
+#ifndef OPENSSL_NO_ECDH
+	BN_CTX_free(bn_ctx);
+	EC_POINT_free(srvr_ecpoint);
+	if (ecdh != NULL)
+		EC_KEY_free(ecdh);
+#endif
+	EVP_MD_CTX_cleanup(&md_ctx);
+	return(-1);
+	}
+
+int ssl3_get_certificate_request(SSL *s)
+	{
+	int ok,ret=0;
+	unsigned long n,nc,l;
+	unsigned int llen,ctype_num,i;
+	X509_NAME *xn=NULL;
+	const unsigned char *p,*q;
+	unsigned char *d;
+	STACK_OF(X509_NAME) *ca_sk=NULL;
+
+	n=s->method->ssl_get_message(s,
+		SSL3_ST_CR_CERT_REQ_A,
+		SSL3_ST_CR_CERT_REQ_B,
+		-1,
+		s->max_cert_list,
+		&ok);
+
+	if (!ok) return((int)n);
+
+	s->s3->tmp.cert_req=0;
+
+	if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE)
+		{
+		s->s3->tmp.reuse_message=1;
+		return(1);
+		}
+
+	if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST)
+		{
+		ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
+		SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_WRONG_MESSAGE_TYPE);
+		goto err;
+		}
+
+	/* TLS does not like anon-DH with client cert */
+	if (s->version > SSL3_VERSION)
+		{
+		if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
+			{
+			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
+			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER);
+			goto err;
+			}
+		}
+
+	p=d=(unsigned char *)s->init_msg;
+
+	if ((ca_sk=sk_X509_NAME_new(ca_dn_cmp)) == NULL)
+		{
+		SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	/* get the certificate types */
+	ctype_num= *(p++);
+	if (ctype_num > SSL3_CT_NUMBER)
+		ctype_num=SSL3_CT_NUMBER;
+	for (i=0; i<ctype_num; i++)
+		s->s3->tmp.ctype[i]= p[i];
+	p+=ctype_num;
+
+	/* get the CA RDNs */
+	n2s(p,llen);
+#if 0
+{
+FILE *out;
+out=fopen("/tmp/vsign.der","w");
+fwrite(p,1,llen,out);
+fclose(out);
+}
+#endif
+
+	if ((llen+ctype_num+2+1) != n)
+		{
+		ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
+		SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_LENGTH_MISMATCH);
+		goto err;
+		}
+
+	for (nc=0; nc<llen; )
+		{
+		n2s(p,l);
+		if ((l+nc+2) > llen)
+			{
+			if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG))
+				goto cont; /* netscape bugs */
+			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
+			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_CA_DN_TOO_LONG);
+			goto err;
+			}
+
+		q=p;
+
+		if ((xn=d2i_X509_NAME(NULL,&q,l)) == NULL)
+			{
+			/* If netscape tolerance is on, ignore errors */
+			if (s->options & SSL_OP_NETSCAPE_CA_DN_BUG)
+				goto cont;
+			else
+				{
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
+				SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,ERR_R_ASN1_LIB);
+				goto err;
+				}
+			}
+
+		if (q != (p+l))
+			{
+			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
+			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_CA_DN_LENGTH_MISMATCH);
+			goto err;
+			}
+		if (!sk_X509_NAME_push(ca_sk,xn))
+			{
+			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+
+		p+=l;
+		nc+=l+2;
+		}
+
+	if (0)
+		{
+cont:
+		ERR_clear_error();
+		}
+
+	/* we should setup a certificate to return.... */
+	s->s3->tmp.cert_req=1;
+	s->s3->tmp.ctype_num=ctype_num;
+	if (s->s3->tmp.ca_names != NULL)
+		sk_X509_NAME_pop_free(s->s3->tmp.ca_names,X509_NAME_free);
+	s->s3->tmp.ca_names=ca_sk;
+	ca_sk=NULL;
+
+	ret=1;
+err:
+	if (ca_sk != NULL) sk_X509_NAME_pop_free(ca_sk,X509_NAME_free);
+	return(ret);
+	}
+
+static int ca_dn_cmp(const X509_NAME * const *a, const X509_NAME * const *b)
+	{
+	return(X509_NAME_cmp(*a,*b));
+	}
+#ifndef OPENSSL_NO_TLSEXT
+int ssl3_get_new_session_ticket(SSL *s)
+	{
+	int ok,al,ret=0, ticklen;
+	long n;
+	const unsigned char *p;
+	unsigned char *d;
+
+	n=s->method->ssl_get_message(s,
+		SSL3_ST_CR_SESSION_TICKET_A,
+		SSL3_ST_CR_SESSION_TICKET_B,
+		-1,
+		16384,
+		&ok);
+
+	if (!ok)
+		return((int)n);
+
+	if (s->s3->tmp.message_type == SSL3_MT_FINISHED)
+		{
+		s->s3->tmp.reuse_message=1;
+		return(1);
+		}
+	if (s->s3->tmp.message_type != SSL3_MT_NEWSESSION_TICKET)
+		{
+		al=SSL_AD_UNEXPECTED_MESSAGE;
+		SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_BAD_MESSAGE_TYPE);
+		goto f_err;
+		}
+	if (n < 6)
+		{
+		/* need at least ticket_lifetime_hint + ticket length */
+		al = SSL_AD_DECODE_ERROR;
+		SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
+		goto f_err;
+		}
+
+	p=d=(unsigned char *)s->init_msg;
+	n2l(p, s->session->tlsext_tick_lifetime_hint);
+	n2s(p, ticklen);
+	/* ticket_lifetime_hint + ticket_length + ticket */
+	if (ticklen + 6 != n)
+		{
+		al = SSL_AD_DECODE_ERROR;
+		SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
+		goto f_err;
+		}
+	if (s->session->tlsext_tick)
+		{
+		OPENSSL_free(s->session->tlsext_tick);
+		s->session->tlsext_ticklen = 0;
+		}
+	s->session->tlsext_tick = OPENSSL_malloc(ticklen);
+	if (!s->session->tlsext_tick)
+		{
+		SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	memcpy(s->session->tlsext_tick, p, ticklen);
+	s->session->tlsext_ticklen = ticklen;
+	/* There are two ways to detect a resumed ticket sesion.
+	 * One is to set an appropriate session ID and then the server
+	 * must return a match in ServerHello. This allows the normal
+	 * client session ID matching to work and we know much 
+	 * earlier that the ticket has been accepted.
+	 * 
+	 * The other way is to set zero length session ID when the
+	 * ticket is presented and rely on the handshake to determine
+	 * session resumption.
+	 *
+	 * We choose the former approach because this fits in with
+	 * assumptions elsewhere in OpenSSL. The session ID is set
+	 * to the SHA256 (or SHA1 is SHA256 is disabled) hash of the
+	 * ticket.
+	 */ 
+	EVP_Digest(p, ticklen,
+			s->session->session_id, &s->session->session_id_length,
+#ifndef OPENSSL_NO_SHA256
+							EVP_sha256(), NULL);
+#else
+							EVP_sha1(), NULL);
+#endif
+	ret=1;
+	return(ret);
+f_err:
+	ssl3_send_alert(s,SSL3_AL_FATAL,al);
+err:
+	return(-1);
+	}
+
+int ssl3_get_cert_status(SSL *s)
+	{
+	int ok, al;
+	unsigned long resplen,n;
+	const unsigned char *p;
+
+	n=s->method->ssl_get_message(s,
+		SSL3_ST_CR_CERT_STATUS_A,
+		SSL3_ST_CR_CERT_STATUS_B,
+		SSL3_MT_CERTIFICATE_STATUS,
+		16384,
+		&ok);
+
+	if (!ok) return((int)n);
+	if (n < 4)
+		{
+		/* need at least status type + length */
+		al = SSL_AD_DECODE_ERROR;
+		SSLerr(SSL_F_SSL3_GET_CERT_STATUS,SSL_R_LENGTH_MISMATCH);
+		goto f_err;
+		}
+	p = (unsigned char *)s->init_msg;
+	if (*p++ != TLSEXT_STATUSTYPE_ocsp)
+		{
+		al = SSL_AD_DECODE_ERROR;
+		SSLerr(SSL_F_SSL3_GET_CERT_STATUS,SSL_R_UNSUPPORTED_STATUS_TYPE);
+		goto f_err;
+		}
+	n2l3(p, resplen);
+	if (resplen + 4 != n)
+		{
+		al = SSL_AD_DECODE_ERROR;
+		SSLerr(SSL_F_SSL3_GET_CERT_STATUS,SSL_R_LENGTH_MISMATCH);
+		goto f_err;
+		}
+	if (s->tlsext_ocsp_resp)
+		OPENSSL_free(s->tlsext_ocsp_resp);
+	s->tlsext_ocsp_resp = BUF_memdup(p, resplen);
+	if (!s->tlsext_ocsp_resp)
+		{
+		al = SSL_AD_INTERNAL_ERROR;
+		SSLerr(SSL_F_SSL3_GET_CERT_STATUS,ERR_R_MALLOC_FAILURE);
+		goto f_err;
+		}
+	s->tlsext_ocsp_resplen = resplen;
+	if (s->ctx->tlsext_status_cb)
+		{
+		int ret;
+		ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
+		if (ret == 0)
+			{
+			al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
+			SSLerr(SSL_F_SSL3_GET_CERT_STATUS,SSL_R_INVALID_STATUS_RESPONSE);
+			goto f_err;
+			}
+		if (ret < 0)
+			{
+			al = SSL_AD_INTERNAL_ERROR;
+			SSLerr(SSL_F_SSL3_GET_CERT_STATUS,ERR_R_MALLOC_FAILURE);
+			goto f_err;
+			}
+		}
+	return 1;
+f_err:
+	ssl3_send_alert(s,SSL3_AL_FATAL,al);
+	return(-1);
+	}
+#endif
+
+int ssl3_get_server_done(SSL *s)
+	{
+	int ok,ret=0;
+	long n;
+
+	n=s->method->ssl_get_message(s,
+		SSL3_ST_CR_SRVR_DONE_A,
+		SSL3_ST_CR_SRVR_DONE_B,
+		SSL3_MT_SERVER_DONE,
+		30, /* should be very small, like 0 :-) */
+		&ok);
+
+	if (!ok) return((int)n);
+	if (n > 0)
+		{
+		/* should contain no data */
+		ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
+		SSLerr(SSL_F_SSL3_GET_SERVER_DONE,SSL_R_LENGTH_MISMATCH);
+		return -1;
+		}
+	ret=1;
+	return(ret);
+	}
+
+
+int ssl3_send_client_key_exchange(SSL *s)
+	{
+	unsigned char *p,*d;
+	int n;
+	unsigned long alg_k;
+#ifndef OPENSSL_NO_RSA
+	unsigned char *q;
+	EVP_PKEY *pkey=NULL;
+#endif
+#ifndef OPENSSL_NO_KRB5
+	KSSL_ERR kssl_err;
+#endif /* OPENSSL_NO_KRB5 */
+#ifndef OPENSSL_NO_ECDH
+	EC_KEY *clnt_ecdh = NULL;
+	const EC_POINT *srvr_ecpoint = NULL;
+	EVP_PKEY *srvr_pub_pkey = NULL;
+	unsigned char *encodedPoint = NULL;
+	int encoded_pt_len = 0;
+	BN_CTX * bn_ctx = NULL;
+#endif
+
+	if (s->state == SSL3_ST_CW_KEY_EXCH_A)
+		{
+		d=(unsigned char *)s->init_buf->data;
+		p= &(d[4]);
+
+		alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
+
+		/* Fool emacs indentation */
+		if (0) {}
+#ifndef OPENSSL_NO_RSA
+		else if (alg_k & SSL_kRSA)
+			{
+			RSA *rsa;
+			unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
+
+			if (s->session->sess_cert->peer_rsa_tmp != NULL)
+				rsa=s->session->sess_cert->peer_rsa_tmp;
+			else
+				{
+				pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
+				if ((pkey == NULL) ||
+					(pkey->type != EVP_PKEY_RSA) ||
+					(pkey->pkey.rsa == NULL))
+					{
+					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+					goto err;
+					}
+				rsa=pkey->pkey.rsa;
+				EVP_PKEY_free(pkey);
+				}
+				
+			tmp_buf[0]=s->client_version>>8;
+			tmp_buf[1]=s->client_version&0xff;
+			if (RAND_bytes(&(tmp_buf[2]),sizeof tmp_buf-2) <= 0)
+					goto err;
+
+			s->session->master_key_length=sizeof tmp_buf;
+
+			q=p;
+			/* Fix buf for TLS and beyond */
+			if (s->version > SSL3_VERSION)
+				p+=2;
+			n=RSA_public_encrypt(sizeof tmp_buf,
+				tmp_buf,p,rsa,RSA_PKCS1_PADDING);
+#ifdef PKCS1_CHECK
+			if (s->options & SSL_OP_PKCS1_CHECK_1) p[1]++;
+			if (s->options & SSL_OP_PKCS1_CHECK_2) tmp_buf[0]=0x70;
+#endif
+			if (n <= 0)
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_ENCRYPT);
+				goto err;
+				}
+
+			/* Fix buf for TLS and beyond */
+			if (s->version > SSL3_VERSION)
+				{
+				s2n(n,q);
+				n+=2;
+				}
+
+			s->session->master_key_length=
+				s->method->ssl3_enc->generate_master_secret(s,
+					s->session->master_key,
+					tmp_buf,sizeof tmp_buf);
+			OPENSSL_cleanse(tmp_buf,sizeof tmp_buf);
+			}
+#endif
+#ifndef OPENSSL_NO_KRB5
+		else if (alg_k & SSL_kKRB5)
+			{
+			krb5_error_code	krb5rc;
+			KSSL_CTX	*kssl_ctx = s->kssl_ctx;
+			/*  krb5_data	krb5_ap_req;  */
+			krb5_data	*enc_ticket;
+			krb5_data	authenticator, *authp = NULL;
+			EVP_CIPHER_CTX	ciph_ctx;
+			const EVP_CIPHER *enc = NULL;
+			unsigned char	iv[EVP_MAX_IV_LENGTH];
+			unsigned char	tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
+			unsigned char	epms[SSL_MAX_MASTER_KEY_LENGTH 
+						+ EVP_MAX_IV_LENGTH];
+			int 		padl, outl = sizeof(epms);
+
+			EVP_CIPHER_CTX_init(&ciph_ctx);
+
+#ifdef KSSL_DEBUG
+			printf("ssl3_send_client_key_exchange(%lx & %lx)\n",
+				alg_k, SSL_kKRB5);
+#endif	/* KSSL_DEBUG */
+
+			authp = NULL;
+#ifdef KRB5SENDAUTH
+			if (KRB5SENDAUTH)  authp = &authenticator;
+#endif	/* KRB5SENDAUTH */
+
+			krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp,
+				&kssl_err);
+			enc = kssl_map_enc(kssl_ctx->enctype);
+			if (enc == NULL)
+			    goto err;
+#ifdef KSSL_DEBUG
+			{
+			printf("kssl_cget_tkt rtn %d\n", krb5rc);
+			if (krb5rc && kssl_err.text)
+			  printf("kssl_cget_tkt kssl_err=%s\n", kssl_err.text);
+			}
+#endif	/* KSSL_DEBUG */
+
+			if (krb5rc)
+				{
+				ssl3_send_alert(s,SSL3_AL_FATAL,
+						SSL_AD_HANDSHAKE_FAILURE);
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+						kssl_err.reason);
+				goto err;
+				}
+
+			/*  20010406 VRS - Earlier versions used KRB5 AP_REQ
+			**  in place of RFC 2712 KerberosWrapper, as in:
+			**
+			**  Send ticket (copy to *p, set n = length)
+			**  n = krb5_ap_req.length;
+			**  memcpy(p, krb5_ap_req.data, krb5_ap_req.length);
+			**  if (krb5_ap_req.data)  
+			**    kssl_krb5_free_data_contents(NULL,&krb5_ap_req);
+			**
+			**  Now using real RFC 2712 KerberosWrapper
+			**  (Thanks to Simon Wilkinson <sxw@sxw.org.uk>)
+			**  Note: 2712 "opaque" types are here replaced
+			**  with a 2-byte length followed by the value.
+			**  Example:
+			**  KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms
+			**  Where "xx xx" = length bytes.  Shown here with
+			**  optional authenticator omitted.
+			*/
+
+			/*  KerberosWrapper.Ticket		*/
+			s2n(enc_ticket->length,p);
+			memcpy(p, enc_ticket->data, enc_ticket->length);
+			p+= enc_ticket->length;
+			n = enc_ticket->length + 2;
+
+			/*  KerberosWrapper.Authenticator	*/
+			if (authp  &&  authp->length)  
+				{
+				s2n(authp->length,p);
+				memcpy(p, authp->data, authp->length);
+				p+= authp->length;
+				n+= authp->length + 2;
+				
+				free(authp->data);
+				authp->data = NULL;
+				authp->length = 0;
+				}
+			else
+				{
+				s2n(0,p);/*  null authenticator length	*/
+				n+=2;
+				}
+ 
+			    tmp_buf[0]=s->client_version>>8;
+			    tmp_buf[1]=s->client_version&0xff;
+			    if (RAND_bytes(&(tmp_buf[2]),sizeof tmp_buf-2) <= 0)
+				goto err;
+
+			/*  20010420 VRS.  Tried it this way; failed.
+			**	EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,NULL);
+			**	EVP_CIPHER_CTX_set_key_length(&ciph_ctx,
+			**				kssl_ctx->length);
+			**	EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv);
+			*/
+
+			memset(iv, 0, sizeof iv);  /* per RFC 1510 */
+			EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,
+				kssl_ctx->key,iv);
+			EVP_EncryptUpdate(&ciph_ctx,epms,&outl,tmp_buf,
+				sizeof tmp_buf);
+			EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl);
+			outl += padl;
+			if (outl > (int)sizeof epms)
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+			EVP_CIPHER_CTX_cleanup(&ciph_ctx);
+
+			/*  KerberosWrapper.EncryptedPreMasterSecret	*/
+			s2n(outl,p);
+			memcpy(p, epms, outl);
+			p+=outl;
+			n+=outl + 2;
+
+			s->session->master_key_length=
+				s->method->ssl3_enc->generate_master_secret(s,
+					s->session->master_key,
+					tmp_buf, sizeof tmp_buf);
+
+			OPENSSL_cleanse(tmp_buf, sizeof tmp_buf);
+			OPENSSL_cleanse(epms, outl);
+			}
+#endif
+#ifndef OPENSSL_NO_DH
+		else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
+			{
+			DH *dh_srvr,*dh_clnt;
+
+			if (s->session->sess_cert == NULL) 
+				{
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
+				goto err;
+				}
+
+			if (s->session->sess_cert->peer_dh_tmp != NULL)
+				dh_srvr=s->session->sess_cert->peer_dh_tmp;
+			else
+				{
+				/* we get them from the cert */
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_DH_PARAMETERS);
+				goto err;
+				}
+			
+			/* generate a new random key */
+			if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL)
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
+				goto err;
+				}
+			if (!DH_generate_key(dh_clnt))
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
+				DH_free(dh_clnt);
+				goto err;
+				}
+
+			/* use the 'p' output buffer for the DH key, but
+			 * make sure to clear it out afterwards */
+
+			n=DH_compute_key(p,dh_srvr->pub_key,dh_clnt);
+
+			if (n <= 0)
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
+				DH_free(dh_clnt);
+				goto err;
+				}
+
+			/* generate master key from the result */
+			s->session->master_key_length=
+				s->method->ssl3_enc->generate_master_secret(s,
+					s->session->master_key,p,n);
+			/* clean up */
+			memset(p,0,n);
+
+			/* send off the data */
+			n=BN_num_bytes(dh_clnt->pub_key);
+			s2n(n,p);
+			BN_bn2bin(dh_clnt->pub_key,p);
+			n+=2;
+
+			DH_free(dh_clnt);
+
+			/* perhaps clean things up a bit EAY EAY EAY EAY*/
+			}
+#endif
+
+#ifndef OPENSSL_NO_ECDH 
+		else if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe))
+			{
+			const EC_GROUP *srvr_group = NULL;
+			EC_KEY *tkey;
+			int ecdh_clnt_cert = 0;
+			int field_size = 0;
+
+			/* Did we send out the client's
+			 * ECDH share for use in premaster
+			 * computation as part of client certificate?
+			 * If so, set ecdh_clnt_cert to 1.
+			 */
+			if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->cert != NULL)) 
+				{
+				/* XXX: For now, we do not support client
+				 * authentication using ECDH certificates.
+				 * To add such support, one needs to add
+				 * code that checks for appropriate 
+				 * conditions and sets ecdh_clnt_cert to 1.
+				 * For example, the cert have an ECC
+				 * key on the same curve as the server's
+				 * and the key should be authorized for
+				 * key agreement.
+				 *
+				 * One also needs to add code in ssl3_connect
+				 * to skip sending the certificate verify
+				 * message.
+				 *
+				 * if ((s->cert->key->privatekey != NULL) &&
+				 *     (s->cert->key->privatekey->type ==
+				 *      EVP_PKEY_EC) && ...)
+				 * ecdh_clnt_cert = 1;
+				 */
+				}
+
+			if (s->session->sess_cert->peer_ecdh_tmp != NULL)
+				{
+				tkey = s->session->sess_cert->peer_ecdh_tmp;
+				}
+			else
+				{
+				/* Get the Server Public Key from Cert */
+				srvr_pub_pkey = X509_get_pubkey(s->session-> \
+				    sess_cert->peer_pkeys[SSL_PKEY_ECC].x509);
+				if ((srvr_pub_pkey == NULL) ||
+				    (srvr_pub_pkey->type != EVP_PKEY_EC) ||
+				    (srvr_pub_pkey->pkey.ec == NULL))
+					{
+					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+					    ERR_R_INTERNAL_ERROR);
+					goto err;
+					}
+
+				tkey = srvr_pub_pkey->pkey.ec;
+				}
+
+			srvr_group   = EC_KEY_get0_group(tkey);
+			srvr_ecpoint = EC_KEY_get0_public_key(tkey);
+
+			if ((srvr_group == NULL) || (srvr_ecpoint == NULL))
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+				    ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+
+			if ((clnt_ecdh=EC_KEY_new()) == NULL) 
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+
+			if (!EC_KEY_set_group(clnt_ecdh, srvr_group))
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB);
+				goto err;
+				}
+			if (ecdh_clnt_cert) 
+				{ 
+				/* Reuse key info from our certificate
+				 * We only need our private key to perform
+				 * the ECDH computation.
+				 */
+				const BIGNUM *priv_key;
+				tkey = s->cert->key->privatekey->pkey.ec;
+				priv_key = EC_KEY_get0_private_key(tkey);
+				if (priv_key == NULL)
+					{
+					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+					goto err;
+					}
+				if (!EC_KEY_set_private_key(clnt_ecdh, priv_key))
+					{
+					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB);
+					goto err;
+					}
+				}
+			else 
+				{
+				/* Generate a new ECDH key pair */
+				if (!(EC_KEY_generate_key(clnt_ecdh)))
+					{
+					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB);
+					goto err;
+					}
+				}
+
+			/* use the 'p' output buffer for the ECDH key, but
+			 * make sure to clear it out afterwards
+			 */
+
+			field_size = EC_GROUP_get_degree(srvr_group);
+			if (field_size <= 0)
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, 
+				       ERR_R_ECDH_LIB);
+				goto err;
+				}
+			n=ECDH_compute_key(p, (field_size+7)/8, srvr_ecpoint, clnt_ecdh, NULL);
+			if (n <= 0)
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, 
+				       ERR_R_ECDH_LIB);
+				goto err;
+				}
+
+			/* generate master key from the result */
+			s->session->master_key_length = s->method->ssl3_enc \
+			    -> generate_master_secret(s, 
+				s->session->master_key,
+				p, n);
+
+			memset(p, 0, n); /* clean up */
+
+			if (ecdh_clnt_cert) 
+				{
+				/* Send empty client key exch message */
+				n = 0;
+				}
+			else 
+				{
+				/* First check the size of encoding and
+				 * allocate memory accordingly.
+				 */
+				encoded_pt_len = 
+				    EC_POINT_point2oct(srvr_group, 
+					EC_KEY_get0_public_key(clnt_ecdh), 
+					POINT_CONVERSION_UNCOMPRESSED, 
+					NULL, 0, NULL);
+
+				encodedPoint = (unsigned char *) 
+				    OPENSSL_malloc(encoded_pt_len * 
+					sizeof(unsigned char)); 
+				bn_ctx = BN_CTX_new();
+				if ((encodedPoint == NULL) || 
+				    (bn_ctx == NULL)) 
+					{
+					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+					goto err;
+					}
+
+				/* Encode the public key */
+				n = EC_POINT_point2oct(srvr_group, 
+				    EC_KEY_get0_public_key(clnt_ecdh), 
+				    POINT_CONVERSION_UNCOMPRESSED, 
+				    encodedPoint, encoded_pt_len, bn_ctx);
+
+				*p = n; /* length of encoded point */
+				/* Encoded point will be copied here */
+				p += 1; 
+				/* copy the point */
+				memcpy((unsigned char *)p, encodedPoint, n);
+				/* increment n to account for length field */
+				n += 1; 
+				}
+
+			/* Free allocated memory */
+			BN_CTX_free(bn_ctx);
+			if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
+			if (clnt_ecdh != NULL) 
+				 EC_KEY_free(clnt_ecdh);
+			EVP_PKEY_free(srvr_pub_pkey);
+			}
+#endif /* !OPENSSL_NO_ECDH */
+		else if (alg_k & SSL_kGOST) 
+			{
+			/* GOST key exchange message creation */
+			EVP_PKEY_CTX *pkey_ctx;
+			X509 *peer_cert; 
+			size_t msglen;
+			unsigned int md_len;
+			int keytype;
+			unsigned char premaster_secret[32],shared_ukm[32], tmp[256];
+			EVP_MD_CTX *ukm_hash;
+			EVP_PKEY *pub_key;
+
+			/* Get server sertificate PKEY and create ctx from it */
+			peer_cert=s->session->sess_cert->peer_pkeys[(keytype=SSL_PKEY_GOST01)].x509;
+			if (!peer_cert) 
+				peer_cert=s->session->sess_cert->peer_pkeys[(keytype=SSL_PKEY_GOST94)].x509;
+			if (!peer_cert)		{
+					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER);
+					goto err;
+				}	
+				
+			pkey_ctx=EVP_PKEY_CTX_new(pub_key=X509_get_pubkey(peer_cert),NULL);
+			/* If we have send a certificate, and certificate key
+
+			 * parameters match those of server certificate, use
+			 * certificate key for key exchange
+			 */
+
+			 /* Otherwise, generate ephemeral key pair */
+					
+			EVP_PKEY_encrypt_init(pkey_ctx);
+			  /* Generate session key */	
+		    RAND_bytes(premaster_secret,32);
+			/* If we have client certificate, use its secret as peer key */
+			if (s->s3->tmp.cert_req && s->cert->key->privatekey) {
+				if (EVP_PKEY_derive_set_peer(pkey_ctx,s->cert->key->privatekey) <=0) {
+					/* If there was an error - just ignore it. Ephemeral key
+					* would be used
+					*/
+					ERR_clear_error();
+				}
+			}			
+			/* Compute shared IV and store it in algorithm-specific
+			 * context data */
+			ukm_hash = EVP_MD_CTX_create();
+			EVP_DigestInit(ukm_hash,EVP_get_digestbynid(NID_id_GostR3411_94));
+			EVP_DigestUpdate(ukm_hash,s->s3->client_random,SSL3_RANDOM_SIZE);
+			EVP_DigestUpdate(ukm_hash,s->s3->server_random,SSL3_RANDOM_SIZE);
+			EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len);
+			EVP_MD_CTX_destroy(ukm_hash);
+			if (EVP_PKEY_CTX_ctrl(pkey_ctx,-1,EVP_PKEY_OP_ENCRYPT,EVP_PKEY_CTRL_SET_IV,
+				8,shared_ukm)<0) {
+					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+						SSL_R_LIBRARY_BUG);
+					goto err;
+				}	
+			/* Make GOST keytransport blob message */
+			/*Encapsulate it into sequence */
+			*(p++)=V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED;
+			msglen=255;
+			if (EVP_PKEY_encrypt(pkey_ctx,tmp,&msglen,premaster_secret,32)<0) {
+			SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+					SSL_R_LIBRARY_BUG);
+				goto err;
+			}
+			if (msglen >= 0x80)
+				{
+				*(p++)=0x81;
+				*(p++)= msglen & 0xff;
+				n=msglen+3;
+				}
+			else
+				{
+				*(p++)= msglen & 0xff;
+				n=msglen+2;
+				}
+			memcpy(p, tmp, msglen);
+			/* Check if pubkey from client certificate was used */
+			if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0)
+				{
+				/* Set flag "skip certificate verify" */
+				s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY;
+				}
+			EVP_PKEY_CTX_free(pkey_ctx);
+			s->session->master_key_length=
+				s->method->ssl3_enc->generate_master_secret(s,
+					s->session->master_key,premaster_secret,32);
+			EVP_PKEY_free(pub_key);
+
+			}
+#ifndef OPENSSL_NO_PSK
+		else if (alg_k & SSL_kPSK)
+			{
+			char identity[PSK_MAX_IDENTITY_LEN];
+			unsigned char *t = NULL;
+			unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4];
+			unsigned int pre_ms_len = 0, psk_len = 0;
+			int psk_err = 1;
+
+			n = 0;
+			if (s->psk_client_callback == NULL)
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+					SSL_R_PSK_NO_CLIENT_CB);
+				goto err;
+				}
+
+			psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint,
+				identity, PSK_MAX_IDENTITY_LEN,
+				psk_or_pre_ms, sizeof(psk_or_pre_ms));
+			if (psk_len > PSK_MAX_PSK_LEN)
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+					ERR_R_INTERNAL_ERROR);
+				goto psk_err;
+				}
+			else if (psk_len == 0)
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+					SSL_R_PSK_IDENTITY_NOT_FOUND);
+				goto psk_err;
+				}
+
+			/* create PSK pre_master_secret */
+			pre_ms_len = 2+psk_len+2+psk_len;
+			t = psk_or_pre_ms;
+			memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len);
+			s2n(psk_len, t);
+			memset(t, 0, psk_len);
+			t+=psk_len;
+			s2n(psk_len, t);
+
+			if (s->session->psk_identity_hint != NULL)
+				OPENSSL_free(s->session->psk_identity_hint);
+			s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint);
+			if (s->ctx->psk_identity_hint != NULL &&
+				s->session->psk_identity_hint == NULL)
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+					ERR_R_MALLOC_FAILURE);
+				goto psk_err;
+				}
+
+			if (s->session->psk_identity != NULL)
+				OPENSSL_free(s->session->psk_identity);
+			s->session->psk_identity = BUF_strdup(identity);
+			if (s->session->psk_identity == NULL)
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+					ERR_R_MALLOC_FAILURE);
+				goto psk_err;
+				}
+
+			s->session->master_key_length =
+				s->method->ssl3_enc->generate_master_secret(s,
+					s->session->master_key,
+					psk_or_pre_ms, pre_ms_len); 
+			n = strlen(identity);
+			s2n(n, p);
+			memcpy(p, identity, n);
+			n+=2;
+			psk_err = 0;
+		psk_err:
+			OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN);
+			OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
+			if (psk_err != 0)
+				{
+				ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+				goto err;
+				}
+			}
+#endif
+		else
+			{
+			ssl3_send_alert(s, SSL3_AL_FATAL,
+			    SSL_AD_HANDSHAKE_FAILURE);
+			SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+			    ERR_R_INTERNAL_ERROR);
+			goto err;
+			}
+		
+		*(d++)=SSL3_MT_CLIENT_KEY_EXCHANGE;
+		l2n3(n,d);
+
+		s->state=SSL3_ST_CW_KEY_EXCH_B;
+		/* number of bytes to write */
+		s->init_num=n+4;
+		s->init_off=0;
+		}
+
+	/* SSL3_ST_CW_KEY_EXCH_B */
+	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
+err:
+#ifndef OPENSSL_NO_ECDH
+	BN_CTX_free(bn_ctx);
+	if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
+	if (clnt_ecdh != NULL) 
+		EC_KEY_free(clnt_ecdh);
+	EVP_PKEY_free(srvr_pub_pkey);
+#endif
+	return(-1);
+	}
+
+int ssl3_send_client_verify(SSL *s)
+	{
+	unsigned char *p,*d;
+	unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
+	EVP_PKEY *pkey;
+	EVP_PKEY_CTX *pctx=NULL;
+#ifndef OPENSSL_NO_RSA
+	unsigned u=0;
+#endif
+	unsigned long n;
+	int j;
+
+	if (s->state == SSL3_ST_CW_CERT_VRFY_A)
+		{
+		d=(unsigned char *)s->init_buf->data;
+		p= &(d[4]);
+		pkey=s->cert->key->privatekey;
+/* Create context from key and test if sha1 is allowed as digest */
+		pctx = EVP_PKEY_CTX_new(pkey,NULL);
+		EVP_PKEY_sign_init(pctx);
+		if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1())>0)
+			{
+			s->method->ssl3_enc->cert_verify_mac(s,
+						NID_sha1,
+						&(data[MD5_DIGEST_LENGTH]));
+			}
+		else
+			{
+			ERR_clear_error();
+			}
+#ifndef OPENSSL_NO_RSA
+		if (pkey->type == EVP_PKEY_RSA)
+			{
+			s->method->ssl3_enc->cert_verify_mac(s,
+				NID_md5,
+			 	&(data[0]));
+			if (RSA_sign(NID_md5_sha1, data,
+					 MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH,
+					&(p[2]), &u, pkey->pkey.rsa) <= 0 )
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_RSA_LIB);
+				goto err;
+				}
+			s2n(u,p);
+			n=u+2;
+			}
+		else
+#endif
+#ifndef OPENSSL_NO_DSA
+			if (pkey->type == EVP_PKEY_DSA)
+			{
+			if (!DSA_sign(pkey->save_type,
+				&(data[MD5_DIGEST_LENGTH]),
+				SHA_DIGEST_LENGTH,&(p[2]),
+				(unsigned int *)&j,pkey->pkey.dsa))
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_DSA_LIB);
+				goto err;
+				}
+			s2n(j,p);
+			n=j+2;
+			}
+		else
+#endif
+#ifndef OPENSSL_NO_ECDSA
+			if (pkey->type == EVP_PKEY_EC)
+			{
+			if (!ECDSA_sign(pkey->save_type,
+				&(data[MD5_DIGEST_LENGTH]),
+				SHA_DIGEST_LENGTH,&(p[2]),
+				(unsigned int *)&j,pkey->pkey.ec))
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
+				    ERR_R_ECDSA_LIB);
+				goto err;
+				}
+			s2n(j,p);
+			n=j+2;
+			}
+		else
+#endif
+		if (pkey->type == NID_id_GostR3410_94 || pkey->type == NID_id_GostR3410_2001) 
+		{
+		unsigned char signbuf[64];
+		int i;
+		size_t sigsize=64;
+		s->method->ssl3_enc->cert_verify_mac(s,
+			NID_id_GostR3411_94,
+			data);
+		if (EVP_PKEY_sign(pctx, signbuf, &sigsize, data, 32) <= 0) {
+			SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
+			ERR_R_INTERNAL_ERROR);
+			goto err;
+		}
+		for (i=63,j=0; i>=0; j++, i--) {
+			p[2+j]=signbuf[i];
+		}	
+		s2n(j,p);
+		n=j+2;
+		}
+		else
+		{
+			SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_INTERNAL_ERROR);
+			goto err;
+		}
+		*(d++)=SSL3_MT_CERTIFICATE_VERIFY;
+		l2n3(n,d);
+
+		s->state=SSL3_ST_CW_CERT_VRFY_B;
+		s->init_num=(int)n+4;
+		s->init_off=0;
+		}
+	EVP_PKEY_CTX_free(pctx);
+	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
+err:
+	EVP_PKEY_CTX_free(pctx);
+	return(-1);
+	}
+
+int ssl3_send_client_certificate(SSL *s)
+	{
+	X509 *x509=NULL;
+	EVP_PKEY *pkey=NULL;
+	int i;
+	unsigned long l;
+
+	if (s->state ==	SSL3_ST_CW_CERT_A)
+		{
+		if ((s->cert == NULL) ||
+			(s->cert->key->x509 == NULL) ||
+			(s->cert->key->privatekey == NULL))
+			s->state=SSL3_ST_CW_CERT_B;
+		else
+			s->state=SSL3_ST_CW_CERT_C;
+		}
+
+	/* We need to get a client cert */
+	if (s->state == SSL3_ST_CW_CERT_B)
+		{
+		/* If we get an error, we need to
+		 * ssl->rwstate=SSL_X509_LOOKUP; return(-1);
+		 * We then get retied later */
+		i=0;
+		i = ssl_do_client_cert_cb(s, &x509, &pkey);
+		if (i < 0)
+			{
+			s->rwstate=SSL_X509_LOOKUP;
+			return(-1);
+			}
+		s->rwstate=SSL_NOTHING;
+		if ((i == 1) && (pkey != NULL) && (x509 != NULL))
+			{
+			s->state=SSL3_ST_CW_CERT_B;
+			if (	!SSL_use_certificate(s,x509) ||
+				!SSL_use_PrivateKey(s,pkey))
+				i=0;
+			}
+		else if (i == 1)
+			{
+			i=0;
+			SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
+			}
+
+		if (x509 != NULL) X509_free(x509);
+		if (pkey != NULL) EVP_PKEY_free(pkey);
+		if (i == 0)
+			{
+			if (s->version == SSL3_VERSION)
+				{
+				s->s3->tmp.cert_req=0;
+				ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_NO_CERTIFICATE);
+				return(1);
+				}
+			else
+				{
+				s->s3->tmp.cert_req=2;
+				}
+			}
+
+		/* Ok, we have a cert */
+		s->state=SSL3_ST_CW_CERT_C;
+		}
+
+	if (s->state == SSL3_ST_CW_CERT_C)
+		{
+		s->state=SSL3_ST_CW_CERT_D;
+		l=ssl3_output_cert_chain(s,
+			(s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509);
+		s->init_num=(int)l;
+		s->init_off=0;
+		}
+	/* SSL3_ST_CW_CERT_D */
+	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
+	}
+
+#define has_bits(i,m)	(((i)&(m)) == (m))
+
+int ssl3_check_cert_and_algorithm(SSL *s)
+	{
+	int i,idx;
+	long alg_k,alg_a;
+	EVP_PKEY *pkey=NULL;
+	SESS_CERT *sc;
+#ifndef OPENSSL_NO_RSA
+	RSA *rsa;
+#endif
+#ifndef OPENSSL_NO_DH
+	DH *dh;
+#endif
+
+	alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
+	alg_a=s->s3->tmp.new_cipher->algorithm_auth;
+
+	/* we don't have a certificate */
+	if ((alg_a & (SSL_aDH|SSL_aNULL|SSL_aKRB5)) || (alg_k & SSL_kPSK))
+		return(1);
+
+	sc=s->session->sess_cert;
+	if (sc == NULL)
+		{
+		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,ERR_R_INTERNAL_ERROR);
+		goto err;
+		}
+
+#ifndef OPENSSL_NO_RSA
+	rsa=s->session->sess_cert->peer_rsa_tmp;
+#endif
+#ifndef OPENSSL_NO_DH
+	dh=s->session->sess_cert->peer_dh_tmp;
+#endif
+
+	/* This is the passed certificate */
+
+	idx=sc->peer_cert_type;
+#ifndef OPENSSL_NO_ECDH
+	if (idx == SSL_PKEY_ECC)
+		{
+		if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509,
+		    s->s3->tmp.new_cipher) == 0) 
+			{ /* check failed */
+			SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_BAD_ECC_CERT);
+			goto f_err;
+			}
+		else 
+			{
+			return 1;
+			}
+		}
+#endif
+	pkey=X509_get_pubkey(sc->peer_pkeys[idx].x509);
+	i=X509_certificate_type(sc->peer_pkeys[idx].x509,pkey);
+	EVP_PKEY_free(pkey);
+
+	
+	/* Check that we have a certificate if we require one */
+	if ((alg_a & SSL_aRSA) && !has_bits(i,EVP_PK_RSA|EVP_PKT_SIGN))
+		{
+		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_RSA_SIGNING_CERT);
+		goto f_err;
+		}
+#ifndef OPENSSL_NO_DSA
+	else if ((alg_a & SSL_aDSS) && !has_bits(i,EVP_PK_DSA|EVP_PKT_SIGN))
+		{
+		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DSA_SIGNING_CERT);
+		goto f_err;
+		}
+#endif
+#ifndef OPENSSL_NO_RSA
+	if ((alg_k & SSL_kRSA) &&
+		!(has_bits(i,EVP_PK_RSA|EVP_PKT_ENC) || (rsa != NULL)))
+		{
+		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_RSA_ENCRYPTING_CERT);
+		goto f_err;
+		}
+#endif
+#ifndef OPENSSL_NO_DH
+	if ((alg_k & SSL_kEDH) &&
+		!(has_bits(i,EVP_PK_DH|EVP_PKT_EXCH) || (dh != NULL)))
+		{
+		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_KEY);
+		goto f_err;
+		}
+	else if ((alg_k & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA))
+		{
+		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_RSA_CERT);
+		goto f_err;
+		}
+#ifndef OPENSSL_NO_DSA
+	else if ((alg_k & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA))
+		{
+		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_DSA_CERT);
+		goto f_err;
+		}
+#endif
+#endif
+
+	if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i,EVP_PKT_EXP))
+		{
+#ifndef OPENSSL_NO_RSA
+		if (alg_k & SSL_kRSA)
+			{
+			if (rsa == NULL
+			    || RSA_size(rsa)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher))
+				{
+				SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_EXPORT_TMP_RSA_KEY);
+				goto f_err;
+				}
+			}
+		else
+#endif
+#ifndef OPENSSL_NO_DH
+			if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
+			    {
+			    if (dh == NULL
+				|| DH_size(dh)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher))
+				{
+				SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_EXPORT_TMP_DH_KEY);
+				goto f_err;
+				}
+			}
+		else
+#endif
+			{
+			SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
+			goto f_err;
+			}
+		}
+	return(1);
+f_err:
+	ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+err:
+	return(0);
+	}
+
+/* Check to see if handshake is full or resumed. Usually this is just a
+ * case of checking to see if a cache hit has occurred. In the case of
+ * session tickets we have to check the next message to be sure.
+ */
+
+#ifndef OPENSSL_NO_TLSEXT
+# ifndef OPENSSL_NO_NEXTPROTONEG
+int ssl3_send_next_proto(SSL *s)
+	{
+	unsigned int len, padding_len;
+	unsigned char *d;
+
+	if (s->state == SSL3_ST_CW_NEXT_PROTO_A)
+		{
+		len = s->next_proto_negotiated_len;
+		padding_len = 32 - ((len + 2) % 32);
+		d = (unsigned char *)s->init_buf->data;
+		d[4] = len;
+		memcpy(d + 5, s->next_proto_negotiated, len);
+		d[5 + len] = padding_len;
+		memset(d + 6 + len, 0, padding_len);
+		*(d++)=SSL3_MT_NEXT_PROTO;
+		l2n3(2 + len + padding_len, d);
+		s->state = SSL3_ST_CW_NEXT_PROTO_B;
+		s->init_num = 4 + 2 + len + padding_len;
+		s->init_off = 0;
+		}
+
+	return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+	}
+# endif
+
+int ssl3_check_finished(SSL *s)
+	{
+	int ok;
+	long n;
+	/* If we have no ticket it cannot be a resumed session. */
+	if (!s->session->tlsext_tick)
+		return 1;
+	/* this function is called when we really expect a Certificate
+	 * message, so permit appropriate message length */
+	n=s->method->ssl_get_message(s,
+		SSL3_ST_CR_CERT_A,
+		SSL3_ST_CR_CERT_B,
+		-1,
+		s->max_cert_list,
+		&ok);
+	if (!ok) return((int)n);
+	s->s3->tmp.reuse_message = 1;
+	if ((s->s3->tmp.message_type == SSL3_MT_FINISHED)
+		|| (s->s3->tmp.message_type == SSL3_MT_NEWSESSION_TICKET))
+		return 2;
+
+	return 1;
+	}
+#endif
+
+int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
+	{
+	int i = 0;
+#ifndef OPENSSL_NO_ENGINE
+	if (s->ctx->client_cert_engine)
+		{
+		i = ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s,
+						SSL_get_client_CA_list(s),
+						px509, ppkey, NULL, NULL, NULL);
+		if (i != 0)
+			return i;
+		}
+#endif
+	if (s->ctx->client_cert_cb)
+		i = s->ctx->client_cert_cb(s,px509,ppkey);
+	return i;
+	}
diff --git a/openssl/ssl/s3_enc.c b/openssl/ssl/s3_enc.c
new file mode 100644
index 0000000..b145970
--- /dev/null
+++ b/openssl/ssl/s3_enc.c
@@ -0,0 +1,849 @@
+/* ssl/s3_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include "ssl_locl.h"
+#include <openssl/evp.h>
+#include <openssl/md5.h>
+
+static unsigned char ssl3_pad_1[48]={
+	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36 };
+
+static unsigned char ssl3_pad_2[48]={
+	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
+	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
+	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
+	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
+	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
+	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c };
+static int ssl3_handshake_mac(SSL *s, int md_nid,
+	const char *sender, int len, unsigned char *p);
+static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
+	{
+	EVP_MD_CTX m5;
+	EVP_MD_CTX s1;
+	unsigned char buf[16],smd[SHA_DIGEST_LENGTH];
+	unsigned char c='A';
+	unsigned int i,j,k;
+
+#ifdef CHARSET_EBCDIC
+	c = os_toascii[c]; /*'A' in ASCII */
+#endif
+	k=0;
+	EVP_MD_CTX_init(&m5);
+	EVP_MD_CTX_init(&s1);
+	for (i=0; (int)i<num; i+=MD5_DIGEST_LENGTH)
+		{
+		k++;
+		if (k > sizeof buf)
+			{
+			/* bug: 'buf' is too small for this ciphersuite */
+			SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR);
+			return 0;
+			}
+		
+		for (j=0; j<k; j++)
+			buf[j]=c;
+		c++;
+		EVP_DigestInit_ex(&s1,EVP_sha1(), NULL);
+		EVP_DigestUpdate(&s1,buf,k);
+		EVP_DigestUpdate(&s1,s->session->master_key,
+			s->session->master_key_length);
+		EVP_DigestUpdate(&s1,s->s3->server_random,SSL3_RANDOM_SIZE);
+		EVP_DigestUpdate(&s1,s->s3->client_random,SSL3_RANDOM_SIZE);
+		EVP_DigestFinal_ex(&s1,smd,NULL);
+
+		EVP_DigestInit_ex(&m5,EVP_md5(), NULL);
+		EVP_DigestUpdate(&m5,s->session->master_key,
+			s->session->master_key_length);
+		EVP_DigestUpdate(&m5,smd,SHA_DIGEST_LENGTH);
+		if ((int)(i+MD5_DIGEST_LENGTH) > num)
+			{
+			EVP_DigestFinal_ex(&m5,smd,NULL);
+			memcpy(km,smd,(num-i));
+			}
+		else
+			EVP_DigestFinal_ex(&m5,km,NULL);
+
+		km+=MD5_DIGEST_LENGTH;
+		}
+	OPENSSL_cleanse(smd,SHA_DIGEST_LENGTH);
+	EVP_MD_CTX_cleanup(&m5);
+	EVP_MD_CTX_cleanup(&s1);
+	return 1;
+	}
+
+int ssl3_change_cipher_state(SSL *s, int which)
+	{
+	unsigned char *p,*mac_secret;
+	unsigned char exp_key[EVP_MAX_KEY_LENGTH];
+	unsigned char exp_iv[EVP_MAX_IV_LENGTH];
+	unsigned char *ms,*key,*iv,*er1,*er2;
+	EVP_CIPHER_CTX *dd;
+	const EVP_CIPHER *c;
+#ifndef OPENSSL_NO_COMP
+	COMP_METHOD *comp;
+#endif
+	const EVP_MD *m;
+	EVP_MD_CTX md;
+	int is_exp,n,i,j,k,cl;
+	int reuse_dd = 0;
+
+	is_exp=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
+	c=s->s3->tmp.new_sym_enc;
+	m=s->s3->tmp.new_hash;
+	/* m == NULL will lead to a crash later */
+	OPENSSL_assert(m);
+#ifndef OPENSSL_NO_COMP
+	if (s->s3->tmp.new_compression == NULL)
+		comp=NULL;
+	else
+		comp=s->s3->tmp.new_compression->method;
+#endif
+
+	if (which & SSL3_CC_READ)
+		{
+		if (s->enc_read_ctx != NULL)
+			reuse_dd = 1;
+		else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
+			goto err;
+		else
+			/* make sure it's intialized in case we exit later with an error */
+			EVP_CIPHER_CTX_init(s->enc_read_ctx);
+		dd= s->enc_read_ctx;
+
+		ssl_replace_hash(&s->read_hash,m);
+#ifndef OPENSSL_NO_COMP
+		/* COMPRESS */
+		if (s->expand != NULL)
+			{
+			COMP_CTX_free(s->expand);
+			s->expand=NULL;
+			}
+		if (comp != NULL)
+			{
+			s->expand=COMP_CTX_new(comp);
+			if (s->expand == NULL)
+				{
+				SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
+				goto err2;
+				}
+			if (s->s3->rrec.comp == NULL)
+				s->s3->rrec.comp=(unsigned char *)
+					OPENSSL_malloc(SSL3_RT_MAX_PLAIN_LENGTH);
+			if (s->s3->rrec.comp == NULL)
+				goto err;
+			}
+#endif
+		memset(&(s->s3->read_sequence[0]),0,8);
+		mac_secret= &(s->s3->read_mac_secret[0]);
+		}
+	else
+		{
+		if (s->enc_write_ctx != NULL)
+			reuse_dd = 1;
+		else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
+			goto err;
+		else
+			/* make sure it's intialized in case we exit later with an error */
+			EVP_CIPHER_CTX_init(s->enc_write_ctx);
+		dd= s->enc_write_ctx;
+		ssl_replace_hash(&s->write_hash,m);
+#ifndef OPENSSL_NO_COMP
+		/* COMPRESS */
+		if (s->compress != NULL)
+			{
+			COMP_CTX_free(s->compress);
+			s->compress=NULL;
+			}
+		if (comp != NULL)
+			{
+			s->compress=COMP_CTX_new(comp);
+			if (s->compress == NULL)
+				{
+				SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
+				goto err2;
+				}
+			}
+#endif
+		memset(&(s->s3->write_sequence[0]),0,8);
+		mac_secret= &(s->s3->write_mac_secret[0]);
+		}
+
+	if (reuse_dd)
+		EVP_CIPHER_CTX_cleanup(dd);
+
+	p=s->s3->tmp.key_block;
+	i=EVP_MD_size(m);
+	if (i < 0)
+		goto err2;
+	cl=EVP_CIPHER_key_length(c);
+	j=is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
+		 cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
+	/* Was j=(is_exp)?5:EVP_CIPHER_key_length(c); */
+	k=EVP_CIPHER_iv_length(c);
+	if (	(which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
+		(which == SSL3_CHANGE_CIPHER_SERVER_READ))
+		{
+		ms=  &(p[ 0]); n=i+i;
+		key= &(p[ n]); n+=j+j;
+		iv=  &(p[ n]); n+=k+k;
+		er1= &(s->s3->client_random[0]);
+		er2= &(s->s3->server_random[0]);
+		}
+	else
+		{
+		n=i;
+		ms=  &(p[ n]); n+=i+j;
+		key= &(p[ n]); n+=j+k;
+		iv=  &(p[ n]); n+=k;
+		er1= &(s->s3->server_random[0]);
+		er2= &(s->s3->client_random[0]);
+		}
+
+	if (n > s->s3->tmp.key_block_length)
+		{
+		SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR);
+		goto err2;
+		}
+
+	EVP_MD_CTX_init(&md);
+	memcpy(mac_secret,ms,i);
+	if (is_exp)
+		{
+		/* In here I set both the read and write key/iv to the
+		 * same value since only the correct one will be used :-).
+		 */
+		EVP_DigestInit_ex(&md,EVP_md5(), NULL);
+		EVP_DigestUpdate(&md,key,j);
+		EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE);
+		EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE);
+		EVP_DigestFinal_ex(&md,&(exp_key[0]),NULL);
+		key= &(exp_key[0]);
+
+		if (k > 0)
+			{
+			EVP_DigestInit_ex(&md,EVP_md5(), NULL);
+			EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE);
+			EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE);
+			EVP_DigestFinal_ex(&md,&(exp_iv[0]),NULL);
+			iv= &(exp_iv[0]);
+			}
+		}
+
+	s->session->key_arg_length=0;
+
+	EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
+
+	OPENSSL_cleanse(&(exp_key[0]),sizeof(exp_key));
+	OPENSSL_cleanse(&(exp_iv[0]),sizeof(exp_iv));
+	EVP_MD_CTX_cleanup(&md);
+	return(1);
+err:
+	SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE);
+err2:
+	return(0);
+	}
+
+int ssl3_setup_key_block(SSL *s)
+	{
+	unsigned char *p;
+	const EVP_CIPHER *c;
+	const EVP_MD *hash;
+	int num;
+	int ret = 0;
+	SSL_COMP *comp;
+
+	if (s->s3->tmp.key_block_length != 0)
+		return(1);
+
+	if (!ssl_cipher_get_evp(s->session,&c,&hash,NULL,NULL,&comp))
+		{
+		SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
+		return(0);
+		}
+
+	s->s3->tmp.new_sym_enc=c;
+	s->s3->tmp.new_hash=hash;
+#ifdef OPENSSL_NO_COMP
+	s->s3->tmp.new_compression=NULL;
+#else
+	s->s3->tmp.new_compression=comp;
+#endif
+
+	num=EVP_MD_size(hash);
+	if (num < 0)
+		return 0;
+
+	num=EVP_CIPHER_key_length(c)+num+EVP_CIPHER_iv_length(c);
+	num*=2;
+
+	ssl3_cleanup_key_block(s);
+
+	if ((p=OPENSSL_malloc(num)) == NULL)
+		goto err;
+
+	s->s3->tmp.key_block_length=num;
+	s->s3->tmp.key_block=p;
+
+	ret = ssl3_generate_key_block(s,p,num);
+
+	if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
+		{
+		/* enable vulnerability countermeasure for CBC ciphers with
+		 * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
+		 */
+		s->s3->need_empty_fragments = 1;
+
+		if (s->session->cipher != NULL)
+			{
+			if (s->session->cipher->algorithm_enc == SSL_eNULL)
+				s->s3->need_empty_fragments = 0;
+			
+#ifndef OPENSSL_NO_RC4
+			if (s->session->cipher->algorithm_enc == SSL_RC4)
+				s->s3->need_empty_fragments = 0;
+#endif
+			}
+		}
+
+	return ret;
+		
+err:
+	SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
+	return(0);
+	}
+
+void ssl3_cleanup_key_block(SSL *s)
+	{
+	if (s->s3->tmp.key_block != NULL)
+		{
+		OPENSSL_cleanse(s->s3->tmp.key_block,
+			s->s3->tmp.key_block_length);
+		OPENSSL_free(s->s3->tmp.key_block);
+		s->s3->tmp.key_block=NULL;
+		}
+	s->s3->tmp.key_block_length=0;
+	}
+
+int ssl3_enc(SSL *s, int send)
+	{
+	SSL3_RECORD *rec;
+	EVP_CIPHER_CTX *ds;
+	unsigned long l;
+	int bs,i;
+	const EVP_CIPHER *enc;
+
+	if (send)
+		{
+		ds=s->enc_write_ctx;
+		rec= &(s->s3->wrec);
+		if (s->enc_write_ctx == NULL)
+			enc=NULL;
+		else
+			enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
+		}
+	else
+		{
+		ds=s->enc_read_ctx;
+		rec= &(s->s3->rrec);
+		if (s->enc_read_ctx == NULL)
+			enc=NULL;
+		else
+			enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
+		}
+
+	if ((s->session == NULL) || (ds == NULL) ||
+		(enc == NULL))
+		{
+		memmove(rec->data,rec->input,rec->length);
+		rec->input=rec->data;
+		}
+	else
+		{
+		l=rec->length;
+		bs=EVP_CIPHER_block_size(ds->cipher);
+
+		/* COMPRESS */
+
+		if ((bs != 1) && send)
+			{
+			i=bs-((int)l%bs);
+
+			/* we need to add 'i-1' padding bytes */
+			l+=i;
+			/* the last of these zero bytes will be overwritten
+			 * with the padding length. */
+			memset(&rec->input[rec->length], 0, i);
+			rec->length+=i;
+			rec->input[l-1]=(i-1);
+			}
+		
+		if (!send)
+			{
+			if (l == 0 || l%bs != 0)
+				{
+				SSLerr(SSL_F_SSL3_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED);
+				return 0;
+				}
+			/* otherwise, rec->length >= bs */
+			}
+		
+		EVP_Cipher(ds,rec->data,rec->input,l);
+
+		if ((bs != 1) && !send)
+			{
+			i=rec->data[l-1]+1;
+			/* SSL 3.0 bounds the number of padding bytes by the block size;
+			 * padding bytes (except the last one) are arbitrary */
+			if (i > bs)
+				{
+				/* Incorrect padding. SSLerr() and ssl3_alert are done
+				 * by caller: we don't want to reveal whether this is
+				 * a decryption error or a MAC verification failure
+				 * (see http://www.openssl.org/~bodo/tls-cbc.txt) */
+				return -1;
+				}
+			/* now i <= bs <= rec->length */
+			rec->length-=i;
+			}
+		}
+	return(1);
+	}
+
+void ssl3_init_finished_mac(SSL *s)
+	{
+	if (s->s3->handshake_buffer) BIO_free(s->s3->handshake_buffer);
+	if (s->s3->handshake_dgst) ssl3_free_digest_list(s);
+    s->s3->handshake_buffer=BIO_new(BIO_s_mem());	
+	(void)BIO_set_close(s->s3->handshake_buffer,BIO_CLOSE);
+	}
+
+void ssl3_free_digest_list(SSL *s) 
+	{
+	int i;
+	if (!s->s3->handshake_dgst) return;
+	for (i=0;i<SSL_MAX_DIGEST;i++) 
+		{
+		if (s->s3->handshake_dgst[i])
+			EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]);
+		}
+	OPENSSL_free(s->s3->handshake_dgst);
+	s->s3->handshake_dgst=NULL;
+	}	
+		
+
+
+void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
+	{
+	if (s->s3->handshake_buffer) 
+		{
+		BIO_write (s->s3->handshake_buffer,(void *)buf,len);
+		} 
+	else 
+		{
+		int i;
+		for (i=0;i< SSL_MAX_DIGEST;i++) 
+			{
+			if (s->s3->handshake_dgst[i]!= NULL)
+			EVP_DigestUpdate(s->s3->handshake_dgst[i],buf,len);
+			}
+		}	
+	}
+
+int ssl3_digest_cached_records(SSL *s)
+	{
+	int i;
+	long mask;
+	const EVP_MD *md;
+	long hdatalen;
+	void *hdata;
+
+	/* Allocate handshake_dgst array */
+	ssl3_free_digest_list(s);
+	s->s3->handshake_dgst = OPENSSL_malloc(SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *));
+	memset(s->s3->handshake_dgst,0,SSL_MAX_DIGEST *sizeof(EVP_MD_CTX *));
+	hdatalen = BIO_get_mem_data(s->s3->handshake_buffer,&hdata);
+	if (hdatalen <= 0)
+		{
+		SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, SSL_R_BAD_HANDSHAKE_LENGTH);
+		return 0;
+		}
+
+	/* Loop through bitso of algorithm2 field and create MD_CTX-es */
+	for (i=0;ssl_get_handshake_digest(i,&mask,&md); i++) 
+		{
+		if ((mask & s->s3->tmp.new_cipher->algorithm2) && md) 
+			{
+			s->s3->handshake_dgst[i]=EVP_MD_CTX_create();
+			EVP_DigestInit_ex(s->s3->handshake_dgst[i],md,NULL);
+			EVP_DigestUpdate(s->s3->handshake_dgst[i],hdata,hdatalen);
+			} 
+		else 
+			{	
+			s->s3->handshake_dgst[i]=NULL;
+			}
+		}
+	/* Free handshake_buffer BIO */
+	BIO_free(s->s3->handshake_buffer);
+	s->s3->handshake_buffer = NULL;
+
+	return 1;
+	}
+
+int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p)
+	{
+	return(ssl3_handshake_mac(s,md_nid,NULL,0,p));
+	}
+int ssl3_final_finish_mac(SSL *s, 
+	     const char *sender, int len, unsigned char *p)
+	{
+	int ret;
+	ret=ssl3_handshake_mac(s,NID_md5,sender,len,p);
+	p+=ret;
+	ret+=ssl3_handshake_mac(s,NID_sha1,sender,len,p);
+	return(ret);
+	}
+static int ssl3_handshake_mac(SSL *s, int md_nid,
+	     const char *sender, int len, unsigned char *p)
+	{
+	unsigned int ret;
+	int npad,n;
+	unsigned int i;
+	unsigned char md_buf[EVP_MAX_MD_SIZE];
+	EVP_MD_CTX ctx,*d=NULL;
+
+	if (s->s3->handshake_buffer) 
+		if (!ssl3_digest_cached_records(s))
+			return 0;
+
+	/* Search for digest of specified type in the handshake_dgst
+	 * array*/
+	for (i=0;i<SSL_MAX_DIGEST;i++) 
+		{
+		  if (s->s3->handshake_dgst[i]&&EVP_MD_CTX_type(s->s3->handshake_dgst[i])==md_nid) 
+		  	{
+		  	d=s->s3->handshake_dgst[i];
+			break;
+			}
+		}
+	if (!d) {
+		SSLerr(SSL_F_SSL3_HANDSHAKE_MAC,SSL_R_NO_REQUIRED_DIGEST);
+		return 0;
+	}	
+	EVP_MD_CTX_init(&ctx);
+	EVP_MD_CTX_copy_ex(&ctx,d);
+	n=EVP_MD_CTX_size(&ctx);
+	if (n < 0)
+		return 0;
+
+	npad=(48/n)*n;
+	if (sender != NULL)
+		EVP_DigestUpdate(&ctx,sender,len);
+	EVP_DigestUpdate(&ctx,s->session->master_key,
+		s->session->master_key_length);
+	EVP_DigestUpdate(&ctx,ssl3_pad_1,npad);
+	EVP_DigestFinal_ex(&ctx,md_buf,&i);
+
+	EVP_DigestInit_ex(&ctx,EVP_MD_CTX_md(&ctx), NULL);
+	EVP_DigestUpdate(&ctx,s->session->master_key,
+		s->session->master_key_length);
+	EVP_DigestUpdate(&ctx,ssl3_pad_2,npad);
+	EVP_DigestUpdate(&ctx,md_buf,i);
+	EVP_DigestFinal_ex(&ctx,p,&ret);
+
+	EVP_MD_CTX_cleanup(&ctx);
+
+	return((int)ret);
+	}
+
+int n_ssl3_mac(SSL *ssl, unsigned char *md, int send)
+	{
+	SSL3_RECORD *rec;
+	unsigned char *mac_sec,*seq;
+	EVP_MD_CTX md_ctx;
+	const EVP_MD_CTX *hash;
+	unsigned char *p,rec_char;
+	unsigned int md_size;
+	int npad;
+	int t;
+
+	if (send)
+		{
+		rec= &(ssl->s3->wrec);
+		mac_sec= &(ssl->s3->write_mac_secret[0]);
+		seq= &(ssl->s3->write_sequence[0]);
+		hash=ssl->write_hash;
+		}
+	else
+		{
+		rec= &(ssl->s3->rrec);
+		mac_sec= &(ssl->s3->read_mac_secret[0]);
+		seq= &(ssl->s3->read_sequence[0]);
+		hash=ssl->read_hash;
+		}
+
+	t=EVP_MD_CTX_size(hash);
+	if (t < 0)
+		return -1;
+	md_size=t;
+	npad=(48/md_size)*md_size;
+
+	/* Chop the digest off the end :-) */
+	EVP_MD_CTX_init(&md_ctx);
+
+	EVP_MD_CTX_copy_ex( &md_ctx,hash);
+	EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
+	EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad);
+	EVP_DigestUpdate(&md_ctx,seq,8);
+	rec_char=rec->type;
+	EVP_DigestUpdate(&md_ctx,&rec_char,1);
+	p=md;
+	s2n(rec->length,p);
+	EVP_DigestUpdate(&md_ctx,md,2);
+	EVP_DigestUpdate(&md_ctx,rec->input,rec->length);
+	EVP_DigestFinal_ex( &md_ctx,md,NULL);
+
+	EVP_MD_CTX_copy_ex( &md_ctx,hash);
+	EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
+	EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad);
+	EVP_DigestUpdate(&md_ctx,md,md_size);
+	EVP_DigestFinal_ex( &md_ctx,md,&md_size);
+
+	EVP_MD_CTX_cleanup(&md_ctx);
+
+	ssl3_record_sequence_update(seq);
+	return(md_size);
+	}
+
+void ssl3_record_sequence_update(unsigned char *seq)
+	{
+	int i;
+
+	for (i=7; i>=0; i--)
+		{
+		++seq[i];
+		if (seq[i] != 0) break; 
+		}
+	}
+
+int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
+	     int len)
+	{
+	static const unsigned char *salt[3]={
+#ifndef CHARSET_EBCDIC
+		(const unsigned char *)"A",
+		(const unsigned char *)"BB",
+		(const unsigned char *)"CCC",
+#else
+		(const unsigned char *)"\x41",
+		(const unsigned char *)"\x42\x42",
+		(const unsigned char *)"\x43\x43\x43",
+#endif
+		};
+	unsigned char buf[EVP_MAX_MD_SIZE];
+	EVP_MD_CTX ctx;
+	int i,ret=0;
+	unsigned int n;
+
+	EVP_MD_CTX_init(&ctx);
+	for (i=0; i<3; i++)
+		{
+		EVP_DigestInit_ex(&ctx,s->ctx->sha1, NULL);
+		EVP_DigestUpdate(&ctx,salt[i],strlen((const char *)salt[i]));
+		EVP_DigestUpdate(&ctx,p,len);
+		EVP_DigestUpdate(&ctx,&(s->s3->client_random[0]),
+			SSL3_RANDOM_SIZE);
+		EVP_DigestUpdate(&ctx,&(s->s3->server_random[0]),
+			SSL3_RANDOM_SIZE);
+		EVP_DigestFinal_ex(&ctx,buf,&n);
+
+		EVP_DigestInit_ex(&ctx,s->ctx->md5, NULL);
+		EVP_DigestUpdate(&ctx,p,len);
+		EVP_DigestUpdate(&ctx,buf,n);
+		EVP_DigestFinal_ex(&ctx,out,&n);
+		out+=n;
+		ret+=n;
+		}
+	EVP_MD_CTX_cleanup(&ctx);
+	return(ret);
+	}
+
+int ssl3_alert_code(int code)
+	{
+	switch (code)
+		{
+	case SSL_AD_CLOSE_NOTIFY:	return(SSL3_AD_CLOSE_NOTIFY);
+	case SSL_AD_UNEXPECTED_MESSAGE:	return(SSL3_AD_UNEXPECTED_MESSAGE);
+	case SSL_AD_BAD_RECORD_MAC:	return(SSL3_AD_BAD_RECORD_MAC);
+	case SSL_AD_DECRYPTION_FAILED:	return(SSL3_AD_BAD_RECORD_MAC);
+	case SSL_AD_RECORD_OVERFLOW:	return(SSL3_AD_BAD_RECORD_MAC);
+	case SSL_AD_DECOMPRESSION_FAILURE:return(SSL3_AD_DECOMPRESSION_FAILURE);
+	case SSL_AD_HANDSHAKE_FAILURE:	return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_NO_CERTIFICATE:	return(SSL3_AD_NO_CERTIFICATE);
+	case SSL_AD_BAD_CERTIFICATE:	return(SSL3_AD_BAD_CERTIFICATE);
+	case SSL_AD_UNSUPPORTED_CERTIFICATE:return(SSL3_AD_UNSUPPORTED_CERTIFICATE);
+	case SSL_AD_CERTIFICATE_REVOKED:return(SSL3_AD_CERTIFICATE_REVOKED);
+	case SSL_AD_CERTIFICATE_EXPIRED:return(SSL3_AD_CERTIFICATE_EXPIRED);
+	case SSL_AD_CERTIFICATE_UNKNOWN:return(SSL3_AD_CERTIFICATE_UNKNOWN);
+	case SSL_AD_ILLEGAL_PARAMETER:	return(SSL3_AD_ILLEGAL_PARAMETER);
+	case SSL_AD_UNKNOWN_CA:		return(SSL3_AD_BAD_CERTIFICATE);
+	case SSL_AD_ACCESS_DENIED:	return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_DECODE_ERROR:	return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_DECRYPT_ERROR:	return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_EXPORT_RESTRICTION:	return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_PROTOCOL_VERSION:	return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_INSUFFICIENT_SECURITY:return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_INTERNAL_ERROR:	return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_USER_CANCELLED:	return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_NO_RENEGOTIATION:	return(-1); /* Don't send it :-) */
+	case SSL_AD_UNSUPPORTED_EXTENSION: return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_CERTIFICATE_UNOBTAINABLE: return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_UNRECOGNIZED_NAME:	return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
+	default:			return(-1);
+		}
+	}
+
diff --git a/openssl/ssl/s3_lib.c b/openssl/ssl/s3_lib.c
new file mode 100644
index 0000000..72d3f1f
--- /dev/null
+++ b/openssl/ssl/s3_lib.c
@@ -0,0 +1,3363 @@
+/* ssl/s3_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * ECC cipher suite support in OpenSSL originally written by
+ * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+#include "kssl_lcl.h"
+#ifndef OPENSSL_NO_TLSEXT
+#ifndef OPENSSL_NO_EC
+#include "../crypto/ec/ec_lcl.h"
+#endif /* OPENSSL_NO_EC */
+#endif /* OPENSSL_NO_TLSEXT */
+#include <openssl/md5.h>
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+
+const char ssl3_version_str[]="SSLv3" OPENSSL_VERSION_PTEXT;
+
+#define SSL3_NUM_CIPHERS	(sizeof(ssl3_ciphers)/sizeof(SSL_CIPHER))
+
+/* list of available SSLv3 ciphers (sorted by id) */
+OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
+
+/* The RSA ciphers */
+/* Cipher 01 */
+	{
+	1,
+	SSL3_TXT_RSA_NULL_MD5,
+	SSL3_CK_RSA_NULL_MD5,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_eNULL,
+	SSL_MD5,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	0,
+	0,
+	},
+
+/* Cipher 02 */
+	{
+	1,
+	SSL3_TXT_RSA_NULL_SHA,
+	SSL3_CK_RSA_NULL_SHA,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_eNULL,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	0,
+	0,
+	},
+
+/* Cipher 03 */
+	{
+	1,
+	SSL3_TXT_RSA_RC4_40_MD5,
+	SSL3_CK_RSA_RC4_40_MD5,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
+	SSL_EXPORT|SSL_EXP40,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	40,
+	128,
+	},
+
+/* Cipher 04 */
+	{
+	1,
+	SSL3_TXT_RSA_RC4_128_MD5,
+	SSL3_CK_RSA_RC4_128_MD5,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+/* Cipher 05 */
+	{
+	1,
+	SSL3_TXT_RSA_RC4_128_SHA,
+	SSL3_CK_RSA_RC4_128_SHA,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+/* Cipher 06 */
+	{
+	1,
+	SSL3_TXT_RSA_RC2_40_MD5,
+	SSL3_CK_RSA_RC2_40_MD5,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC2,
+	SSL_MD5,
+	SSL_SSLV3,
+	SSL_EXPORT|SSL_EXP40,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	40,
+	128,
+	},
+
+/* Cipher 07 */
+#ifndef OPENSSL_NO_IDEA
+	{
+	1,
+	SSL3_TXT_RSA_IDEA_128_SHA,
+	SSL3_CK_RSA_IDEA_128_SHA,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_IDEA,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+#endif
+
+/* Cipher 08 */
+	{
+	1,
+	SSL3_TXT_RSA_DES_40_CBC_SHA,
+	SSL3_CK_RSA_DES_40_CBC_SHA,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_EXPORT|SSL_EXP40,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	40,
+	56,
+	},
+
+/* Cipher 09 */
+	{
+	1,
+	SSL3_TXT_RSA_DES_64_CBC_SHA,
+	SSL3_CK_RSA_DES_64_CBC_SHA,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_LOW,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	56,
+	},
+
+/* Cipher 0A */
+	{
+	1,
+	SSL3_TXT_RSA_DES_192_CBC3_SHA,
+	SSL3_CK_RSA_DES_192_CBC3_SHA,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+/* The DH ciphers */
+/* Cipher 0B */
+	{
+	0,
+	SSL3_TXT_DH_DSS_DES_40_CBC_SHA,
+	SSL3_CK_DH_DSS_DES_40_CBC_SHA,
+	SSL_kDHd,
+	SSL_aDH,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_EXPORT|SSL_EXP40,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	40,
+	56,
+	},
+
+/* Cipher 0C */
+	{
+	0, /* not implemented (non-ephemeral DH) */
+	SSL3_TXT_DH_DSS_DES_64_CBC_SHA,
+	SSL3_CK_DH_DSS_DES_64_CBC_SHA,
+	SSL_kDHd,
+	SSL_aDH,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_LOW,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	56,
+	},
+
+/* Cipher 0D */
+	{
+	0, /* not implemented (non-ephemeral DH) */
+	SSL3_TXT_DH_DSS_DES_192_CBC3_SHA,
+	SSL3_CK_DH_DSS_DES_192_CBC3_SHA,
+	SSL_kDHd,
+	SSL_aDH,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+/* Cipher 0E */
+	{
+	0, /* not implemented (non-ephemeral DH) */
+	SSL3_TXT_DH_RSA_DES_40_CBC_SHA,
+	SSL3_CK_DH_RSA_DES_40_CBC_SHA,
+	SSL_kDHr,
+	SSL_aDH,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_EXPORT|SSL_EXP40,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	40,
+	56,
+	},
+
+/* Cipher 0F */
+	{
+	0, /* not implemented (non-ephemeral DH) */
+	SSL3_TXT_DH_RSA_DES_64_CBC_SHA,
+	SSL3_CK_DH_RSA_DES_64_CBC_SHA,
+	SSL_kDHr,
+	SSL_aDH,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_LOW,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	56,
+	},
+
+/* Cipher 10 */
+	{
+	0, /* not implemented (non-ephemeral DH) */
+	SSL3_TXT_DH_RSA_DES_192_CBC3_SHA,
+	SSL3_CK_DH_RSA_DES_192_CBC3_SHA,
+	SSL_kDHr,
+	SSL_aDH,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+/* The Ephemeral DH ciphers */
+/* Cipher 11 */
+	{
+	1,
+	SSL3_TXT_EDH_DSS_DES_40_CBC_SHA,
+	SSL3_CK_EDH_DSS_DES_40_CBC_SHA,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_EXPORT|SSL_EXP40,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	40,
+	56,
+	},
+
+/* Cipher 12 */
+	{
+	1,
+	SSL3_TXT_EDH_DSS_DES_64_CBC_SHA,
+	SSL3_CK_EDH_DSS_DES_64_CBC_SHA,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_LOW,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	56,
+	},
+
+/* Cipher 13 */
+	{
+	1,
+	SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA,
+	SSL3_CK_EDH_DSS_DES_192_CBC3_SHA,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+/* Cipher 14 */
+	{
+	1,
+	SSL3_TXT_EDH_RSA_DES_40_CBC_SHA,
+	SSL3_CK_EDH_RSA_DES_40_CBC_SHA,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_EXPORT|SSL_EXP40,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	40,
+	56,
+	},
+
+/* Cipher 15 */
+	{
+	1,
+	SSL3_TXT_EDH_RSA_DES_64_CBC_SHA,
+	SSL3_CK_EDH_RSA_DES_64_CBC_SHA,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_LOW,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	56,
+	},
+
+/* Cipher 16 */
+	{
+	1,
+	SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA,
+	SSL3_CK_EDH_RSA_DES_192_CBC3_SHA,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+/* Cipher 17 */
+	{
+	1,
+	SSL3_TXT_ADH_RC4_40_MD5,
+	SSL3_CK_ADH_RC4_40_MD5,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
+	SSL_EXPORT|SSL_EXP40,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	40,
+	128,
+	},
+
+/* Cipher 18 */
+	{
+	1,
+	SSL3_TXT_ADH_RC4_128_MD5,
+	SSL3_CK_ADH_RC4_128_MD5,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+/* Cipher 19 */
+	{
+	1,
+	SSL3_TXT_ADH_DES_40_CBC_SHA,
+	SSL3_CK_ADH_DES_40_CBC_SHA,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_EXPORT|SSL_EXP40,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	40,
+	128,
+	},
+
+/* Cipher 1A */
+	{
+	1,
+	SSL3_TXT_ADH_DES_64_CBC_SHA,
+	SSL3_CK_ADH_DES_64_CBC_SHA,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_LOW,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	56,
+	},
+
+/* Cipher 1B */
+	{
+	1,
+	SSL3_TXT_ADH_DES_192_CBC_SHA,
+	SSL3_CK_ADH_DES_192_CBC_SHA,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+/* Fortezza ciphersuite from SSL 3.0 spec */
+#if 0
+/* Cipher 1C */
+	{
+	0,
+	SSL3_TXT_FZA_DMS_NULL_SHA,
+	SSL3_CK_FZA_DMS_NULL_SHA,
+	SSL_kFZA,
+	SSL_aFZA,
+	SSL_eNULL,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	0,
+	0,
+	},
+
+/* Cipher 1D */
+	{
+	0,
+	SSL3_TXT_FZA_DMS_FZA_SHA,
+	SSL3_CK_FZA_DMS_FZA_SHA,
+	SSL_kFZA,
+	SSL_aFZA,
+	SSL_eFZA,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	0,
+	0,
+	},
+
+/* Cipher 1E */
+	{
+	0,
+	SSL3_TXT_FZA_DMS_RC4_SHA,
+	SSL3_CK_FZA_DMS_RC4_SHA,
+	SSL_kFZA,
+	SSL_aFZA,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+#endif
+
+#ifndef OPENSSL_NO_KRB5
+/* The Kerberos ciphers*/
+/* Cipher 1E */
+	{
+	1,
+	SSL3_TXT_KRB5_DES_64_CBC_SHA,
+	SSL3_CK_KRB5_DES_64_CBC_SHA,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_LOW,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	56,
+	},
+
+/* Cipher 1F */
+	{
+	1,
+	SSL3_TXT_KRB5_DES_192_CBC3_SHA,
+	SSL3_CK_KRB5_DES_192_CBC3_SHA,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+/* Cipher 20 */
+	{
+	1,
+	SSL3_TXT_KRB5_RC4_128_SHA,
+	SSL3_CK_KRB5_RC4_128_SHA,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+/* Cipher 21 */
+	{
+	1,
+	SSL3_TXT_KRB5_IDEA_128_CBC_SHA,
+	SSL3_CK_KRB5_IDEA_128_CBC_SHA,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_IDEA,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+/* Cipher 22 */
+	{
+	1,
+	SSL3_TXT_KRB5_DES_64_CBC_MD5,
+	SSL3_CK_KRB5_DES_64_CBC_MD5,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_DES,
+	SSL_MD5,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_LOW,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	56,
+	},
+
+/* Cipher 23 */
+	{
+	1,
+	SSL3_TXT_KRB5_DES_192_CBC3_MD5,
+	SSL3_CK_KRB5_DES_192_CBC3_MD5,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_3DES,
+	SSL_MD5,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+/* Cipher 24 */
+	{
+	1,
+	SSL3_TXT_KRB5_RC4_128_MD5,
+	SSL3_CK_KRB5_RC4_128_MD5,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+/* Cipher 25 */
+	{
+	1,
+	SSL3_TXT_KRB5_IDEA_128_CBC_MD5,
+	SSL3_CK_KRB5_IDEA_128_CBC_MD5,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_IDEA,
+	SSL_MD5,
+	SSL_SSLV3,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+/* Cipher 26 */
+	{
+	1,
+	SSL3_TXT_KRB5_DES_40_CBC_SHA,
+	SSL3_CK_KRB5_DES_40_CBC_SHA,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_EXPORT|SSL_EXP40,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	40,
+	56,
+	},
+
+/* Cipher 27 */
+	{
+	1,
+	SSL3_TXT_KRB5_RC2_40_CBC_SHA,
+	SSL3_CK_KRB5_RC2_40_CBC_SHA,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_RC2,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_EXPORT|SSL_EXP40,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	40,
+	128,
+	},
+
+/* Cipher 28 */
+	{
+	1,
+	SSL3_TXT_KRB5_RC4_40_SHA,
+	SSL3_CK_KRB5_RC4_40_SHA,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_SSLV3,
+	SSL_EXPORT|SSL_EXP40,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	40,
+	128,
+	},
+
+/* Cipher 29 */
+	{
+	1,
+	SSL3_TXT_KRB5_DES_40_CBC_MD5,
+	SSL3_CK_KRB5_DES_40_CBC_MD5,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_DES,
+	SSL_MD5,
+	SSL_SSLV3,
+	SSL_EXPORT|SSL_EXP40,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	40,
+	56,
+	},
+
+/* Cipher 2A */
+	{
+	1,
+	SSL3_TXT_KRB5_RC2_40_CBC_MD5,
+	SSL3_CK_KRB5_RC2_40_CBC_MD5,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_RC2,
+	SSL_MD5,
+	SSL_SSLV3,
+	SSL_EXPORT|SSL_EXP40,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	40,
+	128,
+	},
+
+/* Cipher 2B */
+	{
+	1,
+	SSL3_TXT_KRB5_RC4_40_MD5,
+	SSL3_CK_KRB5_RC4_40_MD5,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
+	SSL_EXPORT|SSL_EXP40,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	40,
+	128,
+	},
+#endif	/* OPENSSL_NO_KRB5 */
+
+/* New AES ciphersuites */
+/* Cipher 2F */
+	{
+	1,
+	TLS1_TXT_RSA_WITH_AES_128_SHA,
+	TLS1_CK_RSA_WITH_AES_128_SHA,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+/* Cipher 30 */
+	{
+	0,
+	TLS1_TXT_DH_DSS_WITH_AES_128_SHA,
+	TLS1_CK_DH_DSS_WITH_AES_128_SHA,
+	SSL_kDHd,
+	SSL_aDH,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+/* Cipher 31 */
+	{
+	0,
+	TLS1_TXT_DH_RSA_WITH_AES_128_SHA,
+	TLS1_CK_DH_RSA_WITH_AES_128_SHA,
+	SSL_kDHr,
+	SSL_aDH,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+/* Cipher 32 */
+	{
+	1,
+	TLS1_TXT_DHE_DSS_WITH_AES_128_SHA,
+	TLS1_CK_DHE_DSS_WITH_AES_128_SHA,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+/* Cipher 33 */
+	{
+	1,
+	TLS1_TXT_DHE_RSA_WITH_AES_128_SHA,
+	TLS1_CK_DHE_RSA_WITH_AES_128_SHA,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+/* Cipher 34 */
+	{
+	1,
+	TLS1_TXT_ADH_WITH_AES_128_SHA,
+	TLS1_CK_ADH_WITH_AES_128_SHA,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+/* Cipher 35 */
+	{
+	1,
+	TLS1_TXT_RSA_WITH_AES_256_SHA,
+	TLS1_CK_RSA_WITH_AES_256_SHA,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+/* Cipher 36 */
+	{
+	0,
+	TLS1_TXT_DH_DSS_WITH_AES_256_SHA,
+	TLS1_CK_DH_DSS_WITH_AES_256_SHA,
+	SSL_kDHd,
+	SSL_aDH,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+
+/* Cipher 37 */
+	{
+	0, /* not implemented (non-ephemeral DH) */
+	TLS1_TXT_DH_RSA_WITH_AES_256_SHA,
+	TLS1_CK_DH_RSA_WITH_AES_256_SHA,
+	SSL_kDHr,
+	SSL_aDH,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+
+/* Cipher 38 */
+	{
+	1,
+	TLS1_TXT_DHE_DSS_WITH_AES_256_SHA,
+	TLS1_CK_DHE_DSS_WITH_AES_256_SHA,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+
+/* Cipher 39 */
+	{
+	1,
+	TLS1_TXT_DHE_RSA_WITH_AES_256_SHA,
+	TLS1_CK_DHE_RSA_WITH_AES_256_SHA,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+
+	/* Cipher 3A */
+	{
+	1,
+	TLS1_TXT_ADH_WITH_AES_256_SHA,
+	TLS1_CK_ADH_WITH_AES_256_SHA,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+
+#ifndef OPENSSL_NO_CAMELLIA
+	/* Camellia ciphersuites from RFC4132 (128-bit portion) */
+
+	/* Cipher 41 */
+	{
+	1,
+	TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA,
+	TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher 42 */
+	{
+	0, /* not implemented (non-ephemeral DH) */
+	TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA,
+	TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA,
+	SSL_kDHd,
+	SSL_aDH,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher 43 */
+	{
+	0, /* not implemented (non-ephemeral DH) */
+	TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA,
+	TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA,
+	SSL_kDHr,
+	SSL_aDH,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher 44 */
+	{
+	1,
+	TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
+	TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher 45 */
+	{
+	1,
+	TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
+	TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher 46 */
+	{
+	1,
+	TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA,
+	TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+#endif /* OPENSSL_NO_CAMELLIA */
+
+#if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES
+	/* New TLS Export CipherSuites from expired ID */
+#if 0
+	/* Cipher 60 */
+	{
+	1,
+	TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5,
+	TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_TLSV1,
+	SSL_EXPORT|SSL_EXP56,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	128,
+	},
+
+	/* Cipher 61 */
+	{
+	1,
+	TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5,
+	TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC2,
+	SSL_MD5,
+	SSL_TLSV1,
+	SSL_EXPORT|SSL_EXP56,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	128,
+	},
+#endif
+
+	/* Cipher 62 */
+	{
+	1,
+	TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA,
+	TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_EXPORT|SSL_EXP56,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	56,
+	},
+
+	/* Cipher 63 */
+	{
+	1,
+	TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
+	TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_EXPORT|SSL_EXP56,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	56,
+	},
+
+	/* Cipher 64 */
+	{
+	1,
+	TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA,
+	TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_EXPORT|SSL_EXP56,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	128,
+	},
+
+	/* Cipher 65 */
+	{
+	1,
+	TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
+	TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_EXPORT|SSL_EXP56,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	128,
+	},
+
+	/* Cipher 66 */
+	{
+	1,
+	TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA,
+	TLS1_CK_DHE_DSS_WITH_RC4_128_SHA,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+#endif
+	{
+	1,
+	"GOST94-GOST89-GOST89",
+	0x3000080,
+	SSL_kGOST,
+	SSL_aGOST94,
+	SSL_eGOST2814789CNT,
+	SSL_GOST89MAC,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94|TLS1_STREAM_MAC,
+	256,
+	256
+	},
+	{
+	1,
+	"GOST2001-GOST89-GOST89",
+	0x3000081,
+	SSL_kGOST,
+	SSL_aGOST01,
+	SSL_eGOST2814789CNT,
+	SSL_GOST89MAC,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94|TLS1_STREAM_MAC,
+	256,
+	256
+	},
+	{
+	1,
+	"GOST94-NULL-GOST94",
+	0x3000082,
+	SSL_kGOST,
+	SSL_aGOST94,
+	SSL_eNULL,
+	SSL_GOST94,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94,
+	0,
+	0
+	},
+	{
+	1,
+	"GOST2001-NULL-GOST94",
+	0x3000083,
+	SSL_kGOST,
+	SSL_aGOST01,
+	SSL_eNULL,
+	SSL_GOST94,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94,
+	0,
+	0
+	},
+
+#ifndef OPENSSL_NO_CAMELLIA
+	/* Camellia ciphersuites from RFC4132 (256-bit portion) */
+
+	/* Cipher 84 */
+	{
+	1,
+	TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA,
+	TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+	/* Cipher 85 */
+	{
+	0, /* not implemented (non-ephemeral DH) */
+	TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA,
+	TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA,
+	SSL_kDHd,
+	SSL_aDH,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+
+	/* Cipher 86 */
+	{
+	0, /* not implemented (non-ephemeral DH) */
+	TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA,
+	TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA,
+	SSL_kDHr,
+	SSL_aDH,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+
+	/* Cipher 87 */
+	{
+	1,
+	TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
+	TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+
+	/* Cipher 88 */
+	{
+	1,
+	TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
+	TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+
+	/* Cipher 89 */
+	{
+	1,
+	TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA,
+	TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+#endif /* OPENSSL_NO_CAMELLIA */
+
+#ifndef OPENSSL_NO_PSK
+	/* Cipher 8A */
+	{
+	1,
+	TLS1_TXT_PSK_WITH_RC4_128_SHA,
+	TLS1_CK_PSK_WITH_RC4_128_SHA,
+	SSL_kPSK,
+	SSL_aPSK,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher 8B */
+	{
+	1,
+	TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA,
+	TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA,
+	SSL_kPSK,
+	SSL_aPSK,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+	/* Cipher 8C */
+	{
+	1,
+	TLS1_TXT_PSK_WITH_AES_128_CBC_SHA,
+	TLS1_CK_PSK_WITH_AES_128_CBC_SHA,
+	SSL_kPSK,
+	SSL_aPSK,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher 8D */
+	{
+	1,
+	TLS1_TXT_PSK_WITH_AES_256_CBC_SHA,
+	TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
+	SSL_kPSK,
+	SSL_aPSK,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+#endif  /* OPENSSL_NO_PSK */
+
+#ifndef OPENSSL_NO_SEED
+	/* SEED ciphersuites from RFC4162 */
+
+	/* Cipher 96 */
+	{
+	1,
+	TLS1_TXT_RSA_WITH_SEED_SHA,
+	TLS1_CK_RSA_WITH_SEED_SHA,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher 97 */
+	{
+	0, /* not implemented (non-ephemeral DH) */
+	TLS1_TXT_DH_DSS_WITH_SEED_SHA,
+	TLS1_CK_DH_DSS_WITH_SEED_SHA,
+	SSL_kDHd,
+	SSL_aDH,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher 98 */
+	{
+	0, /* not implemented (non-ephemeral DH) */
+	TLS1_TXT_DH_RSA_WITH_SEED_SHA,
+	TLS1_CK_DH_RSA_WITH_SEED_SHA,
+	SSL_kDHr,
+	SSL_aDH,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher 99 */
+	{
+	1,
+	TLS1_TXT_DHE_DSS_WITH_SEED_SHA,
+	TLS1_CK_DHE_DSS_WITH_SEED_SHA,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher 9A */
+	{
+	1,
+	TLS1_TXT_DHE_RSA_WITH_SEED_SHA,
+	TLS1_CK_DHE_RSA_WITH_SEED_SHA,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher 9B */
+	{
+	1,
+	TLS1_TXT_ADH_WITH_SEED_SHA,
+	TLS1_CK_ADH_WITH_SEED_SHA,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+#endif /* OPENSSL_NO_SEED */
+
+#ifndef OPENSSL_NO_ECDH
+	/* Cipher C001 */
+	{
+	1,
+	TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA,
+	TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA,
+	SSL_kECDHe,
+	SSL_aECDH,
+	SSL_eNULL,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	0,
+	0,
+	},
+
+	/* Cipher C002 */
+	{
+	1,
+	TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA,
+	TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA,
+	SSL_kECDHe,
+	SSL_aECDH,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher C003 */
+	{
+	1,
+	TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA,
+	TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA,
+	SSL_kECDHe,
+	SSL_aECDH,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+	/* Cipher C004 */
+	{
+	1,
+	TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
+	TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
+	SSL_kECDHe,
+	SSL_aECDH,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher C005 */
+	{
+	1,
+	TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
+	TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
+	SSL_kECDHe,
+	SSL_aECDH,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+
+	/* Cipher C006 */
+	{
+	1,
+	TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA,
+	TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA,
+	SSL_kEECDH,
+	SSL_aECDSA,
+	SSL_eNULL,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	0,
+	0,
+	},
+
+	/* Cipher C007 */
+	{
+	1,
+	TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA,
+	TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA,
+	SSL_kEECDH,
+	SSL_aECDSA,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher C008 */
+	{
+	1,
+	TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA,
+	TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA,
+	SSL_kEECDH,
+	SSL_aECDSA,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+	/* Cipher C009 */
+	{
+	1,
+	TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+	TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+	SSL_kEECDH,
+	SSL_aECDSA,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher C00A */
+	{
+	1,
+	TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+	TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+	SSL_kEECDH,
+	SSL_aECDSA,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+
+	/* Cipher C00B */
+	{
+	1,
+	TLS1_TXT_ECDH_RSA_WITH_NULL_SHA,
+	TLS1_CK_ECDH_RSA_WITH_NULL_SHA,
+	SSL_kECDHr,
+	SSL_aECDH,
+	SSL_eNULL,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	0,
+	0,
+	},
+
+	/* Cipher C00C */
+	{
+	1,
+	TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA,
+	TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA,
+	SSL_kECDHr,
+	SSL_aECDH,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher C00D */
+	{
+	1,
+	TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA,
+	TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA,
+	SSL_kECDHr,
+	SSL_aECDH,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+	/* Cipher C00E */
+	{
+	1,
+	TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA,
+	TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA,
+	SSL_kECDHr,
+	SSL_aECDH,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher C00F */
+	{
+	1,
+	TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA,
+	TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA,
+	SSL_kECDHr,
+	SSL_aECDH,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+
+	/* Cipher C010 */
+	{
+	1,
+	TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA,
+	TLS1_CK_ECDHE_RSA_WITH_NULL_SHA,
+	SSL_kEECDH,
+	SSL_aRSA,
+	SSL_eNULL,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	0,
+	0,
+	},
+
+	/* Cipher C011 */
+	{
+	1,
+	TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA,
+	TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA,
+	SSL_kEECDH,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher C012 */
+	{
+	1,
+	TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA,
+	TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA,
+	SSL_kEECDH,
+	SSL_aRSA,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+	/* Cipher C013 */
+	{
+	1,
+	TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+	TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+	SSL_kEECDH,
+	SSL_aRSA,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher C014 */
+	{
+	1,
+	TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+	TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+	SSL_kEECDH,
+	SSL_aRSA,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+
+	/* Cipher C015 */
+	{
+	1,
+	TLS1_TXT_ECDH_anon_WITH_NULL_SHA,
+	TLS1_CK_ECDH_anon_WITH_NULL_SHA,
+	SSL_kEECDH,
+	SSL_aNULL,
+	SSL_eNULL,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	0,
+	0,
+	},
+
+	/* Cipher C016 */
+	{
+	1,
+	TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA,
+	TLS1_CK_ECDH_anon_WITH_RC4_128_SHA,
+	SSL_kEECDH,
+	SSL_aNULL,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher C017 */
+	{
+	1,
+	TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA,
+	TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA,
+	SSL_kEECDH,
+	SSL_aNULL,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+	/* Cipher C018 */
+	{
+	1,
+	TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA,
+	TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA,
+	SSL_kEECDH,
+	SSL_aNULL,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher C019 */
+	{
+	1,
+	TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA,
+	TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA,
+	SSL_kEECDH,
+	SSL_aNULL,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+#endif	/* OPENSSL_NO_ECDH */
+
+#ifdef TEMP_GOST_TLS
+/* Cipher FF00 */
+	{
+	1,
+	"GOST-MD5",
+	0x0300ff00,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_eGOST2814789CNT,
+	SSL_MD5,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+	{
+	1,
+	"GOST-GOST94",
+	0x0300ff01,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_eGOST2814789CNT,
+	SSL_GOST94,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256
+	},
+	{
+	1,
+	"GOST-GOST89MAC",
+	0x0300ff02,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_eGOST2814789CNT,
+	SSL_GOST89MAC,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256
+	},
+	{
+	1,
+	"GOST-GOST89STREAM",
+	0x0300ff03,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_eGOST2814789CNT,
+	SSL_GOST89MAC,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF|TLS1_STREAM_MAC,
+	256,
+	256
+	},
+#endif
+
+/* end of list */
+	};
+
+SSL3_ENC_METHOD SSLv3_enc_data={
+	ssl3_enc,
+	n_ssl3_mac,
+	ssl3_setup_key_block,
+	ssl3_generate_master_secret,
+	ssl3_change_cipher_state,
+	ssl3_final_finish_mac,
+	MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH,
+	ssl3_cert_verify_mac,
+	SSL3_MD_CLIENT_FINISHED_CONST,4,
+	SSL3_MD_SERVER_FINISHED_CONST,4,
+	ssl3_alert_code,
+	(int (*)(SSL *, unsigned char *, size_t, const char *,
+		 size_t, const unsigned char *, size_t,
+		 int use_context)) ssl_undefined_function,
+	};
+
+long ssl3_default_timeout(void)
+	{
+	/* 2 hours, the 24 hours mentioned in the SSLv3 spec
+	 * is way too long for http, the cache would over fill */
+	return(60*60*2);
+	}
+
+int ssl3_num_ciphers(void)
+	{
+	return(SSL3_NUM_CIPHERS);
+	}
+
+const SSL_CIPHER *ssl3_get_cipher(unsigned int u)
+	{
+	if (u < SSL3_NUM_CIPHERS)
+		return(&(ssl3_ciphers[SSL3_NUM_CIPHERS-1-u]));
+	else
+		return(NULL);
+	}
+
+int ssl3_pending(const SSL *s)
+	{
+	if (s->rstate == SSL_ST_READ_BODY)
+		return 0;
+	
+	return (s->s3->rrec.type == SSL3_RT_APPLICATION_DATA) ? s->s3->rrec.length : 0;
+	}
+
+int ssl3_new(SSL *s)
+	{
+	SSL3_STATE *s3;
+
+	if ((s3=OPENSSL_malloc(sizeof *s3)) == NULL) goto err;
+	memset(s3,0,sizeof *s3);
+	memset(s3->rrec.seq_num,0,sizeof(s3->rrec.seq_num));
+	memset(s3->wrec.seq_num,0,sizeof(s3->wrec.seq_num));
+
+	s->s3=s3;
+
+	s->method->ssl_clear(s);
+	return(1);
+err:
+	return(0);
+	}
+
+void ssl3_free(SSL *s)
+	{
+	if(s == NULL)
+	    return;
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	if (s->s3->client_opaque_prf_input != NULL)
+		OPENSSL_free(s->s3->client_opaque_prf_input);
+	if (s->s3->server_opaque_prf_input != NULL)
+		OPENSSL_free(s->s3->server_opaque_prf_input);
+#endif
+
+	ssl3_cleanup_key_block(s);
+	if (s->s3->rbuf.buf != NULL)
+		ssl3_release_read_buffer(s);
+	if (s->s3->wbuf.buf != NULL)
+		ssl3_release_write_buffer(s);
+	if (s->s3->rrec.comp != NULL)
+		OPENSSL_free(s->s3->rrec.comp);
+#ifndef OPENSSL_NO_DH
+	if (s->s3->tmp.dh != NULL)
+		DH_free(s->s3->tmp.dh);
+#endif
+#ifndef OPENSSL_NO_ECDH
+	if (s->s3->tmp.ecdh != NULL)
+		EC_KEY_free(s->s3->tmp.ecdh);
+#endif
+
+	if (s->s3->tmp.ca_names != NULL)
+		sk_X509_NAME_pop_free(s->s3->tmp.ca_names,X509_NAME_free);
+	if (s->s3->handshake_buffer) {
+		BIO_free(s->s3->handshake_buffer);
+	}
+	if (s->s3->handshake_dgst) ssl3_free_digest_list(s);
+	OPENSSL_cleanse(s->s3,sizeof *s->s3);
+	OPENSSL_free(s->s3);
+	s->s3=NULL;
+	}
+
+void ssl3_clear(SSL *s)
+	{
+	unsigned char *rp,*wp;
+	size_t rlen, wlen;
+	int init_extra;
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	if (s->s3->client_opaque_prf_input != NULL)
+		OPENSSL_free(s->s3->client_opaque_prf_input);
+	s->s3->client_opaque_prf_input = NULL;
+	if (s->s3->server_opaque_prf_input != NULL)
+		OPENSSL_free(s->s3->server_opaque_prf_input);
+	s->s3->server_opaque_prf_input = NULL;
+#endif
+
+	ssl3_cleanup_key_block(s);
+	if (s->s3->tmp.ca_names != NULL)
+		sk_X509_NAME_pop_free(s->s3->tmp.ca_names,X509_NAME_free);
+
+	if (s->s3->rrec.comp != NULL)
+		{
+		OPENSSL_free(s->s3->rrec.comp);
+		s->s3->rrec.comp=NULL;
+		}
+#ifndef OPENSSL_NO_DH
+	if (s->s3->tmp.dh != NULL)
+		{
+		DH_free(s->s3->tmp.dh);
+		s->s3->tmp.dh = NULL;
+		}
+#endif
+#ifndef OPENSSL_NO_ECDH
+	if (s->s3->tmp.ecdh != NULL)
+		{
+		EC_KEY_free(s->s3->tmp.ecdh);
+		s->s3->tmp.ecdh = NULL;
+		}
+#endif
+
+	rp = s->s3->rbuf.buf;
+	wp = s->s3->wbuf.buf;
+	rlen = s->s3->rbuf.len;
+ 	wlen = s->s3->wbuf.len;
+	init_extra = s->s3->init_extra;
+	if (s->s3->handshake_buffer) {
+		BIO_free(s->s3->handshake_buffer);
+		s->s3->handshake_buffer = NULL;
+	}
+	if (s->s3->handshake_dgst) {
+		ssl3_free_digest_list(s);
+	}	
+	memset(s->s3,0,sizeof *s->s3);
+	s->s3->rbuf.buf = rp;
+	s->s3->wbuf.buf = wp;
+	s->s3->rbuf.len = rlen;
+ 	s->s3->wbuf.len = wlen;
+	s->s3->init_extra = init_extra;
+
+	ssl_free_wbio_buffer(s);
+
+	s->packet_length=0;
+	s->s3->renegotiate=0;
+	s->s3->total_renegotiations=0;
+	s->s3->num_renegotiations=0;
+	s->s3->in_read_app_data=0;
+	s->version=SSL3_VERSION;
+
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+	if (s->next_proto_negotiated)
+		{
+		OPENSSL_free(s->next_proto_negotiated);
+		s->next_proto_negotiated = NULL;
+		s->next_proto_negotiated_len = 0;
+		}
+#endif
+	}
+
+long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
+	{
+	int ret=0;
+
+#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_RSA)
+	if (
+#ifndef OPENSSL_NO_RSA
+	    cmd == SSL_CTRL_SET_TMP_RSA ||
+	    cmd == SSL_CTRL_SET_TMP_RSA_CB ||
+#endif
+#ifndef OPENSSL_NO_DSA
+	    cmd == SSL_CTRL_SET_TMP_DH ||
+	    cmd == SSL_CTRL_SET_TMP_DH_CB ||
+#endif
+		0)
+		{
+		if (!ssl_cert_inst(&s->cert))
+		    	{
+			SSLerr(SSL_F_SSL3_CTRL, ERR_R_MALLOC_FAILURE);
+			return(0);
+			}
+		}
+#endif
+
+	switch (cmd)
+		{
+	case SSL_CTRL_GET_SESSION_REUSED:
+		ret=s->hit;
+		break;
+	case SSL_CTRL_GET_CLIENT_CERT_REQUEST:
+		break;
+	case SSL_CTRL_GET_NUM_RENEGOTIATIONS:
+		ret=s->s3->num_renegotiations;
+		break;
+	case SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS:
+		ret=s->s3->num_renegotiations;
+		s->s3->num_renegotiations=0;
+		break;
+	case SSL_CTRL_GET_TOTAL_RENEGOTIATIONS:
+		ret=s->s3->total_renegotiations;
+		break;
+	case SSL_CTRL_GET_FLAGS:
+		ret=(int)(s->s3->flags);
+		break;
+#ifndef OPENSSL_NO_RSA
+	case SSL_CTRL_NEED_TMP_RSA:
+		if ((s->cert != NULL) && (s->cert->rsa_tmp == NULL) &&
+		    ((s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) ||
+		     (EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey) > (512/8))))
+			ret = 1;
+		break;
+	case SSL_CTRL_SET_TMP_RSA:
+		{
+			RSA *rsa = (RSA *)parg;
+			if (rsa == NULL)
+				{
+				SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER);
+				return(ret);
+				}
+			if ((rsa = RSAPrivateKey_dup(rsa)) == NULL)
+				{
+				SSLerr(SSL_F_SSL3_CTRL, ERR_R_RSA_LIB);
+				return(ret);
+				}
+			if (s->cert->rsa_tmp != NULL)
+				RSA_free(s->cert->rsa_tmp);
+			s->cert->rsa_tmp = rsa;
+			ret = 1;
+		}
+		break;
+	case SSL_CTRL_SET_TMP_RSA_CB:
+		{
+		SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return(ret);
+		}
+		break;
+#endif
+#ifndef OPENSSL_NO_DH
+	case SSL_CTRL_SET_TMP_DH:
+		{
+			DH *dh = (DH *)parg;
+			if (dh == NULL)
+				{
+				SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER);
+				return(ret);
+				}
+			if ((dh = DHparams_dup(dh)) == NULL)
+				{
+				SSLerr(SSL_F_SSL3_CTRL, ERR_R_DH_LIB);
+				return(ret);
+				}
+			if (!(s->options & SSL_OP_SINGLE_DH_USE))
+				{
+				if (!DH_generate_key(dh))
+					{
+					DH_free(dh);
+					SSLerr(SSL_F_SSL3_CTRL, ERR_R_DH_LIB);
+					return(ret);
+					}
+				}
+			if (s->cert->dh_tmp != NULL)
+				DH_free(s->cert->dh_tmp);
+			s->cert->dh_tmp = dh;
+			ret = 1;
+		}
+		break;
+	case SSL_CTRL_SET_TMP_DH_CB:
+		{
+		SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return(ret);
+		}
+		break;
+#endif
+#ifndef OPENSSL_NO_ECDH
+	case SSL_CTRL_SET_TMP_ECDH:
+		{
+		EC_KEY *ecdh = NULL;
+ 			
+		if (parg == NULL)
+			{
+			SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER);
+			return(ret);
+			}
+		if (!EC_KEY_up_ref((EC_KEY *)parg))
+			{
+			SSLerr(SSL_F_SSL3_CTRL,ERR_R_ECDH_LIB);
+			return(ret);
+			}
+		ecdh = (EC_KEY *)parg;
+		if (!(s->options & SSL_OP_SINGLE_ECDH_USE))
+			{
+			if (!EC_KEY_generate_key(ecdh))
+				{
+				EC_KEY_free(ecdh);
+				SSLerr(SSL_F_SSL3_CTRL,ERR_R_ECDH_LIB);
+				return(ret);
+				}
+			}
+		if (s->cert->ecdh_tmp != NULL)
+			EC_KEY_free(s->cert->ecdh_tmp);
+		s->cert->ecdh_tmp = ecdh;
+		ret = 1;
+		}
+		break;
+	case SSL_CTRL_SET_TMP_ECDH_CB:
+		{
+		SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return(ret);
+		}
+		break;
+#endif /* !OPENSSL_NO_ECDH */
+#ifndef OPENSSL_NO_TLSEXT
+	case SSL_CTRL_SET_TLSEXT_HOSTNAME:
+ 		if (larg == TLSEXT_NAMETYPE_host_name)
+			{
+			if (s->tlsext_hostname != NULL) 
+				OPENSSL_free(s->tlsext_hostname);
+			s->tlsext_hostname = NULL;
+
+			ret = 1;
+			if (parg == NULL) 
+				break;
+			if (strlen((char *)parg) > TLSEXT_MAXLEN_host_name)
+				{
+				SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME);
+				return 0;
+				}
+			if ((s->tlsext_hostname = BUF_strdup((char *)parg)) == NULL)
+				{
+				SSLerr(SSL_F_SSL3_CTRL, ERR_R_INTERNAL_ERROR);
+				return 0;
+				}
+			}
+		else
+			{
+			SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE);
+			return 0;
+			}
+ 		break;
+	case SSL_CTRL_SET_TLSEXT_DEBUG_ARG:
+		s->tlsext_debug_arg=parg;
+		ret = 1;
+		break;
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT:
+		if (larg > 12288) /* actual internal limit is 2^16 for the complete hello message
+		                   * (including the cert chain and everything) */
+			{
+			SSLerr(SSL_F_SSL3_CTRL, SSL_R_OPAQUE_PRF_INPUT_TOO_LONG);
+			break;
+			}
+		if (s->tlsext_opaque_prf_input != NULL)
+			OPENSSL_free(s->tlsext_opaque_prf_input);
+		if ((size_t)larg == 0)
+			s->tlsext_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
+		else
+			s->tlsext_opaque_prf_input = BUF_memdup(parg, (size_t)larg);
+		if (s->tlsext_opaque_prf_input != NULL)
+			{
+			s->tlsext_opaque_prf_input_len = (size_t)larg;
+			ret = 1;
+			}
+		else
+			s->tlsext_opaque_prf_input_len = 0;
+		break;
+#endif
+
+	case SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE:
+		s->tlsext_status_type=larg;
+		ret = 1;
+		break;
+
+	case SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS:
+		*(STACK_OF(X509_EXTENSION) **)parg = s->tlsext_ocsp_exts;
+		ret = 1;
+		break;
+
+	case SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS:
+		s->tlsext_ocsp_exts = parg;
+		ret = 1;
+		break;
+
+	case SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS:
+		*(STACK_OF(OCSP_RESPID) **)parg = s->tlsext_ocsp_ids;
+		ret = 1;
+		break;
+
+	case SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS:
+		s->tlsext_ocsp_ids = parg;
+		ret = 1;
+		break;
+
+	case SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP:
+		*(unsigned char **)parg = s->tlsext_ocsp_resp;
+		return s->tlsext_ocsp_resplen;
+		
+	case SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP:
+		if (s->tlsext_ocsp_resp)
+			OPENSSL_free(s->tlsext_ocsp_resp);
+		s->tlsext_ocsp_resp = parg;
+		s->tlsext_ocsp_resplen = larg;
+		ret = 1;
+		break;
+
+#endif /* !OPENSSL_NO_TLSEXT */
+	default:
+		break;
+		}
+	return(ret);
+	}
+
+long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp)(void))
+	{
+	int ret=0;
+
+#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_RSA)
+	if (
+#ifndef OPENSSL_NO_RSA
+	    cmd == SSL_CTRL_SET_TMP_RSA_CB ||
+#endif
+#ifndef OPENSSL_NO_DSA
+	    cmd == SSL_CTRL_SET_TMP_DH_CB ||
+#endif
+		0)
+		{
+		if (!ssl_cert_inst(&s->cert))
+			{
+			SSLerr(SSL_F_SSL3_CALLBACK_CTRL, ERR_R_MALLOC_FAILURE);
+			return(0);
+			}
+		}
+#endif
+
+	switch (cmd)
+		{
+#ifndef OPENSSL_NO_RSA
+	case SSL_CTRL_SET_TMP_RSA_CB:
+		{
+		s->cert->rsa_tmp_cb = (RSA *(*)(SSL *, int, int))fp;
+		}
+		break;
+#endif
+#ifndef OPENSSL_NO_DH
+	case SSL_CTRL_SET_TMP_DH_CB:
+		{
+		s->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
+		}
+		break;
+#endif
+#ifndef OPENSSL_NO_ECDH
+	case SSL_CTRL_SET_TMP_ECDH_CB:
+		{
+		s->cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp;
+		}
+		break;
+#endif
+#ifndef OPENSSL_NO_TLSEXT
+	case SSL_CTRL_SET_TLSEXT_DEBUG_CB:
+		s->tlsext_debug_cb=(void (*)(SSL *,int ,int,
+					unsigned char *, int, void *))fp;
+		break;
+#endif
+	default:
+		break;
+		}
+	return(ret);
+	}
+
+long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
+	{
+	CERT *cert;
+
+	cert=ctx->cert;
+
+	switch (cmd)
+		{
+#ifndef OPENSSL_NO_RSA
+	case SSL_CTRL_NEED_TMP_RSA:
+		if (	(cert->rsa_tmp == NULL) &&
+			((cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) ||
+			 (EVP_PKEY_size(cert->pkeys[SSL_PKEY_RSA_ENC].privatekey) > (512/8)))
+			)
+			return(1);
+		else
+			return(0);
+		/* break; */
+	case SSL_CTRL_SET_TMP_RSA:
+		{
+		RSA *rsa;
+		int i;
+
+		rsa=(RSA *)parg;
+		i=1;
+		if (rsa == NULL)
+			i=0;
+		else
+			{
+			if ((rsa=RSAPrivateKey_dup(rsa)) == NULL)
+				i=0;
+			}
+		if (!i)
+			{
+			SSLerr(SSL_F_SSL3_CTX_CTRL,ERR_R_RSA_LIB);
+			return(0);
+			}
+		else
+			{
+			if (cert->rsa_tmp != NULL)
+				RSA_free(cert->rsa_tmp);
+			cert->rsa_tmp=rsa;
+			return(1);
+			}
+		}
+		/* break; */
+	case SSL_CTRL_SET_TMP_RSA_CB:
+		{
+		SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return(0);
+		}
+		break;
+#endif
+#ifndef OPENSSL_NO_DH
+	case SSL_CTRL_SET_TMP_DH:
+		{
+		DH *new=NULL,*dh;
+
+		dh=(DH *)parg;
+		if ((new=DHparams_dup(dh)) == NULL)
+			{
+			SSLerr(SSL_F_SSL3_CTX_CTRL,ERR_R_DH_LIB);
+			return 0;
+			}
+		if (!(ctx->options & SSL_OP_SINGLE_DH_USE))
+			{
+			if (!DH_generate_key(new))
+				{
+				SSLerr(SSL_F_SSL3_CTX_CTRL,ERR_R_DH_LIB);
+				DH_free(new);
+				return 0;
+				}
+			}
+		if (cert->dh_tmp != NULL)
+			DH_free(cert->dh_tmp);
+		cert->dh_tmp=new;
+		return 1;
+		}
+		/*break; */
+	case SSL_CTRL_SET_TMP_DH_CB:
+		{
+		SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return(0);
+		}
+		break;
+#endif
+#ifndef OPENSSL_NO_ECDH
+	case SSL_CTRL_SET_TMP_ECDH:
+		{
+		EC_KEY *ecdh = NULL;
+ 			
+		if (parg == NULL)
+			{
+			SSLerr(SSL_F_SSL3_CTX_CTRL,ERR_R_ECDH_LIB);
+			return 0;
+			}
+		ecdh = EC_KEY_dup((EC_KEY *)parg);
+		if (ecdh == NULL)
+			{
+			SSLerr(SSL_F_SSL3_CTX_CTRL,ERR_R_EC_LIB);
+			return 0;
+			}
+		if (!(ctx->options & SSL_OP_SINGLE_ECDH_USE))
+			{
+			if (!EC_KEY_generate_key(ecdh))
+				{
+				EC_KEY_free(ecdh);
+				SSLerr(SSL_F_SSL3_CTX_CTRL,ERR_R_ECDH_LIB);
+				return 0;
+				}
+			}
+
+		if (cert->ecdh_tmp != NULL)
+			{
+			EC_KEY_free(cert->ecdh_tmp);
+			}
+		cert->ecdh_tmp = ecdh;
+		return 1;
+		}
+		/* break; */
+	case SSL_CTRL_SET_TMP_ECDH_CB:
+		{
+		SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return(0);
+		}
+		break;
+#endif /* !OPENSSL_NO_ECDH */
+#ifndef OPENSSL_NO_TLSEXT
+	case SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG:
+		ctx->tlsext_servername_arg=parg;
+		break;
+	case SSL_CTRL_SET_TLSEXT_TICKET_KEYS:
+	case SSL_CTRL_GET_TLSEXT_TICKET_KEYS:
+		{
+		unsigned char *keys = parg;
+		if (!keys)
+			return 48;
+		if (larg != 48)
+			{
+			SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_TICKET_KEYS_LENGTH);
+			return 0;
+			}
+		if (cmd == SSL_CTRL_SET_TLSEXT_TICKET_KEYS)
+			{
+			memcpy(ctx->tlsext_tick_key_name, keys, 16);
+			memcpy(ctx->tlsext_tick_hmac_key, keys + 16, 16);
+			memcpy(ctx->tlsext_tick_aes_key, keys + 32, 16);
+			}
+		else
+			{
+			memcpy(keys, ctx->tlsext_tick_key_name, 16);
+			memcpy(keys + 16, ctx->tlsext_tick_hmac_key, 16);
+			memcpy(keys + 32, ctx->tlsext_tick_aes_key, 16);
+			}
+		return 1;
+		}
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG:
+		ctx->tlsext_opaque_prf_input_callback_arg = parg;
+		return 1;
+#endif
+
+	case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG:
+		ctx->tlsext_status_arg=parg;
+		return 1;
+		break;
+
+#endif /* !OPENSSL_NO_TLSEXT */
+
+	/* A Thawte special :-) */
+	case SSL_CTRL_EXTRA_CHAIN_CERT:
+		if (ctx->extra_certs == NULL)
+			{
+			if ((ctx->extra_certs=sk_X509_new_null()) == NULL)
+				return(0);
+			}
+		sk_X509_push(ctx->extra_certs,(X509 *)parg);
+		break;
+
+	default:
+		return(0);
+		}
+	return(1);
+	}
+
+long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
+	{
+	CERT *cert;
+
+	cert=ctx->cert;
+
+	switch (cmd)
+		{
+#ifndef OPENSSL_NO_RSA
+	case SSL_CTRL_SET_TMP_RSA_CB:
+		{
+		cert->rsa_tmp_cb = (RSA *(*)(SSL *, int, int))fp;
+		}
+		break;
+#endif
+#ifndef OPENSSL_NO_DH
+	case SSL_CTRL_SET_TMP_DH_CB:
+		{
+		cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
+		}
+		break;
+#endif
+#ifndef OPENSSL_NO_ECDH
+	case SSL_CTRL_SET_TMP_ECDH_CB:
+		{
+		cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp;
+		}
+		break;
+#endif
+#ifndef OPENSSL_NO_TLSEXT
+	case SSL_CTRL_SET_TLSEXT_SERVERNAME_CB:
+		ctx->tlsext_servername_callback=(int (*)(SSL *,int *,void *))fp;
+		break;
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB:
+		ctx->tlsext_opaque_prf_input_callback = (int (*)(SSL *,void *, size_t, void *))fp;
+		break;
+#endif
+
+	case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB:
+		ctx->tlsext_status_cb=(int (*)(SSL *,void *))fp;
+		break;
+
+	case SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB:
+		ctx->tlsext_ticket_key_cb=(int (*)(SSL *,unsigned char  *,
+						unsigned char *,
+						EVP_CIPHER_CTX *,
+						HMAC_CTX *, int))fp;
+		break;
+
+#endif
+	default:
+		return(0);
+		}
+	return(1);
+	}
+
+/* This function needs to check if the ciphers required are actually
+ * available */
+const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p)
+	{
+	SSL_CIPHER c;
+	const SSL_CIPHER *cp;
+	unsigned long id;
+
+	id=0x03000000L|((unsigned long)p[0]<<8L)|(unsigned long)p[1];
+	c.id=id;
+	cp = OBJ_bsearch_ssl_cipher_id(&c, ssl3_ciphers, SSL3_NUM_CIPHERS);
+	if (cp == NULL || cp->valid == 0)
+		return NULL;
+	else
+		return cp;
+	}
+
+int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
+	{
+	long l;
+
+	if (p != NULL)
+		{
+		l=c->id;
+		if ((l & 0xff000000) != 0x03000000) return(0);
+		p[0]=((unsigned char)(l>> 8L))&0xFF;
+		p[1]=((unsigned char)(l     ))&0xFF;
+		}
+	return(2);
+	}
+
+SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
+	     STACK_OF(SSL_CIPHER) *srvr)
+	{
+	SSL_CIPHER *c,*ret=NULL;
+	STACK_OF(SSL_CIPHER) *prio, *allow;
+	int i,ii,ok;
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_EC)
+	unsigned int j;
+	int ec_ok, ec_nid;
+	unsigned char ec_search1 = 0, ec_search2 = 0;
+#endif
+	CERT *cert;
+	unsigned long alg_k,alg_a,mask_k,mask_a,emask_k,emask_a;
+
+	/* Let's see which ciphers we can support */
+	cert=s->cert;
+
+#if 0
+	/* Do not set the compare functions, because this may lead to a
+	 * reordering by "id". We want to keep the original ordering.
+	 * We may pay a price in performance during sk_SSL_CIPHER_find(),
+	 * but would have to pay with the price of sk_SSL_CIPHER_dup().
+	 */
+	sk_SSL_CIPHER_set_cmp_func(srvr, ssl_cipher_ptr_id_cmp);
+	sk_SSL_CIPHER_set_cmp_func(clnt, ssl_cipher_ptr_id_cmp);
+#endif
+
+#ifdef CIPHER_DEBUG
+	printf("Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), (void *)srvr);
+	for(i=0 ; i < sk_SSL_CIPHER_num(srvr) ; ++i)
+		{
+		c=sk_SSL_CIPHER_value(srvr,i);
+		printf("%p:%s\n",(void *)c,c->name);
+		}
+	printf("Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), (void *)clnt);
+	for(i=0 ; i < sk_SSL_CIPHER_num(clnt) ; ++i)
+	    {
+	    c=sk_SSL_CIPHER_value(clnt,i);
+	    printf("%p:%s\n",(void *)c,c->name);
+	    }
+#endif
+
+	if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
+		{
+		prio = srvr;
+		allow = clnt;
+		}
+	else
+		{
+		prio = clnt;
+		allow = srvr;
+		}
+
+	for (i=0; i<sk_SSL_CIPHER_num(prio); i++)
+		{
+		c=sk_SSL_CIPHER_value(prio,i);
+
+		ssl_set_cert_masks(cert,c);
+		mask_k = cert->mask_k;
+		mask_a = cert->mask_a;
+		emask_k = cert->export_mask_k;
+		emask_a = cert->export_mask_a;
+			
+#ifdef KSSL_DEBUG
+/*		printf("ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);*/
+#endif    /* KSSL_DEBUG */
+
+		alg_k=c->algorithm_mkey;
+		alg_a=c->algorithm_auth;
+
+#ifndef OPENSSL_NO_KRB5
+		if (alg_k & SSL_kKRB5)
+			{
+			if ( !kssl_keytab_is_available(s->kssl_ctx) )
+			    continue;
+			}
+#endif /* OPENSSL_NO_KRB5 */
+#ifndef OPENSSL_NO_PSK
+		/* with PSK there must be server callback set */
+		if ((alg_k & SSL_kPSK) && s->psk_server_callback == NULL)
+			continue;
+#endif /* OPENSSL_NO_PSK */
+
+		if (SSL_C_IS_EXPORT(c))
+			{
+			ok = (alg_k & emask_k) && (alg_a & emask_a);
+#ifdef CIPHER_DEBUG
+			printf("%d:[%08lX:%08lX:%08lX:%08lX]%p:%s (export)\n",ok,alg_k,alg_a,emask_k,emask_a,
+			       (void *)c,c->name);
+#endif
+			}
+		else
+			{
+			ok = (alg_k & mask_k) && (alg_a & mask_a);
+#ifdef CIPHER_DEBUG
+			printf("%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n",ok,alg_k,alg_a,mask_k,mask_a,(void *)c,
+			       c->name);
+#endif
+			}
+
+#ifndef OPENSSL_NO_TLSEXT
+#ifndef OPENSSL_NO_EC
+		if (
+			/* if we are considering an ECC cipher suite that uses our certificate */
+			(alg_a & SSL_aECDSA || alg_a & SSL_aECDH)
+			/* and we have an ECC certificate */
+			&& (s->cert->pkeys[SSL_PKEY_ECC].x509 != NULL)
+			/* and the client specified a Supported Point Formats extension */
+			&& ((s->session->tlsext_ecpointformatlist_length > 0) && (s->session->tlsext_ecpointformatlist != NULL))
+			/* and our certificate's point is compressed */
+			&& (
+				(s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info != NULL)
+				&& (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key != NULL)
+				&& (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key != NULL)
+				&& (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data != NULL)
+				&& (
+					(*(s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data) == POINT_CONVERSION_COMPRESSED)
+					|| (*(s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data) == POINT_CONVERSION_COMPRESSED + 1)
+					)
+				)
+		)
+			{
+			ec_ok = 0;
+			/* if our certificate's curve is over a field type that the client does not support
+			 * then do not allow this cipher suite to be negotiated */
+			if (
+				(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec != NULL)
+				&& (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group != NULL)
+				&& (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth != NULL)
+				&& (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_prime_field)
+			)
+				{
+				for (j = 0; j < s->session->tlsext_ecpointformatlist_length; j++)
+					{
+					if (s->session->tlsext_ecpointformatlist[j] == TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime)
+						{
+						ec_ok = 1;
+						break;
+						}
+					}
+				}
+			else if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_characteristic_two_field)
+				{
+				for (j = 0; j < s->session->tlsext_ecpointformatlist_length; j++)
+					{
+					if (s->session->tlsext_ecpointformatlist[j] == TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2)
+						{
+						ec_ok = 1;
+						break;
+						}
+					}
+				}
+			ok = ok && ec_ok;
+			}
+		if (
+			/* if we are considering an ECC cipher suite that uses our certificate */
+			(alg_a & SSL_aECDSA || alg_a & SSL_aECDH)
+			/* and we have an ECC certificate */
+			&& (s->cert->pkeys[SSL_PKEY_ECC].x509 != NULL)
+			/* and the client specified an EllipticCurves extension */
+			&& ((s->session->tlsext_ellipticcurvelist_length > 0) && (s->session->tlsext_ellipticcurvelist != NULL))
+		)
+			{
+			ec_ok = 0;
+			if (
+				(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec != NULL)
+				&& (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group != NULL)
+			)
+				{
+				ec_nid = EC_GROUP_get_curve_name(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group);
+				if ((ec_nid == 0)
+					&& (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth != NULL)
+				)
+					{
+					if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_prime_field)
+						{
+						ec_search1 = 0xFF;
+						ec_search2 = 0x01;
+						}
+					else if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_characteristic_two_field)
+						{
+						ec_search1 = 0xFF;
+						ec_search2 = 0x02;
+						}
+					}
+				else
+					{
+					ec_search1 = 0x00;
+					ec_search2 = tls1_ec_nid2curve_id(ec_nid);
+					}
+				if ((ec_search1 != 0) || (ec_search2 != 0))
+					{
+					for (j = 0; j < s->session->tlsext_ellipticcurvelist_length / 2; j++)
+						{
+						if ((s->session->tlsext_ellipticcurvelist[2*j] == ec_search1) && (s->session->tlsext_ellipticcurvelist[2*j+1] == ec_search2))
+							{
+							ec_ok = 1;
+							break;
+							}
+						}
+					}
+				}
+			ok = ok && ec_ok;
+			}
+		if (
+			/* if we are considering an ECC cipher suite that uses an ephemeral EC key */
+			(alg_k & SSL_kEECDH)
+			/* and we have an ephemeral EC key */
+			&& (s->cert->ecdh_tmp != NULL)
+			/* and the client specified an EllipticCurves extension */
+			&& ((s->session->tlsext_ellipticcurvelist_length > 0) && (s->session->tlsext_ellipticcurvelist != NULL))
+		)
+			{
+			ec_ok = 0;
+			if (s->cert->ecdh_tmp->group != NULL)
+				{
+				ec_nid = EC_GROUP_get_curve_name(s->cert->ecdh_tmp->group);
+				if ((ec_nid == 0)
+					&& (s->cert->ecdh_tmp->group->meth != NULL)
+				)
+					{
+					if (EC_METHOD_get_field_type(s->cert->ecdh_tmp->group->meth) == NID_X9_62_prime_field)
+						{
+						ec_search1 = 0xFF;
+						ec_search2 = 0x01;
+						}
+					else if (EC_METHOD_get_field_type(s->cert->ecdh_tmp->group->meth) == NID_X9_62_characteristic_two_field)
+						{
+						ec_search1 = 0xFF;
+						ec_search2 = 0x02;
+						}
+					}
+				else
+					{
+					ec_search1 = 0x00;
+					ec_search2 = tls1_ec_nid2curve_id(ec_nid);
+					}
+				if ((ec_search1 != 0) || (ec_search2 != 0))
+					{
+					for (j = 0; j < s->session->tlsext_ellipticcurvelist_length / 2; j++)
+						{
+						if ((s->session->tlsext_ellipticcurvelist[2*j] == ec_search1) && (s->session->tlsext_ellipticcurvelist[2*j+1] == ec_search2))
+							{
+							ec_ok = 1;
+							break;
+							}
+						}
+					}
+				}
+			ok = ok && ec_ok;
+			}
+#endif /* OPENSSL_NO_EC */
+#endif /* OPENSSL_NO_TLSEXT */
+
+		if (!ok) continue;
+		ii=sk_SSL_CIPHER_find(allow,c);
+		if (ii >= 0)
+			{
+			ret=sk_SSL_CIPHER_value(allow,ii);
+			break;
+			}
+		}
+	return(ret);
+	}
+
+int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
+	{
+	int ret=0;
+	unsigned long alg_k;
+
+	alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+
+#ifndef OPENSSL_NO_GOST
+	if (s->version >= TLS1_VERSION)
+		{
+		if (alg_k & SSL_kGOST)
+			{
+			p[ret++]=TLS_CT_GOST94_SIGN;
+			p[ret++]=TLS_CT_GOST01_SIGN;
+			return(ret);
+			}
+		}
+#endif
+
+#ifndef OPENSSL_NO_DH
+	if (alg_k & (SSL_kDHr|SSL_kEDH))
+		{
+#  ifndef OPENSSL_NO_RSA
+		p[ret++]=SSL3_CT_RSA_FIXED_DH;
+#  endif
+#  ifndef OPENSSL_NO_DSA
+		p[ret++]=SSL3_CT_DSS_FIXED_DH;
+#  endif
+		}
+	if ((s->version == SSL3_VERSION) &&
+		(alg_k & (SSL_kEDH|SSL_kDHd|SSL_kDHr)))
+		{
+#  ifndef OPENSSL_NO_RSA
+		p[ret++]=SSL3_CT_RSA_EPHEMERAL_DH;
+#  endif
+#  ifndef OPENSSL_NO_DSA
+		p[ret++]=SSL3_CT_DSS_EPHEMERAL_DH;
+#  endif
+		}
+#endif /* !OPENSSL_NO_DH */
+#ifndef OPENSSL_NO_RSA
+	p[ret++]=SSL3_CT_RSA_SIGN;
+#endif
+#ifndef OPENSSL_NO_DSA
+	p[ret++]=SSL3_CT_DSS_SIGN;
+#endif
+#ifndef OPENSSL_NO_ECDH
+	if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->version >= TLS1_VERSION))
+		{
+		p[ret++]=TLS_CT_RSA_FIXED_ECDH;
+		p[ret++]=TLS_CT_ECDSA_FIXED_ECDH;
+		}
+#endif
+
+#ifndef OPENSSL_NO_ECDSA
+	/* ECDSA certs can be used with RSA cipher suites as well 
+	 * so we don't need to check for SSL_kECDH or SSL_kEECDH
+	 */
+	if (s->version >= TLS1_VERSION)
+		{
+		p[ret++]=TLS_CT_ECDSA_SIGN;
+		}
+#endif	
+	return(ret);
+	}
+
+int ssl3_shutdown(SSL *s)
+	{
+	int ret;
+
+	/* Don't do anything much if we have not done the handshake or
+	 * we don't want to send messages :-) */
+	if ((s->quiet_shutdown) || (s->state == SSL_ST_BEFORE))
+		{
+		s->shutdown=(SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+		return(1);
+		}
+
+	if (!(s->shutdown & SSL_SENT_SHUTDOWN))
+		{
+		s->shutdown|=SSL_SENT_SHUTDOWN;
+#if 1
+		ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_CLOSE_NOTIFY);
+#endif
+		/* our shutdown alert has been sent now, and if it still needs
+	 	 * to be written, s->s3->alert_dispatch will be true */
+	 	if (s->s3->alert_dispatch)
+	 		return(-1);	/* return WANT_WRITE */
+		}
+	else if (s->s3->alert_dispatch)
+		{
+		/* resend it if not sent */
+#if 1
+		ret=s->method->ssl_dispatch_alert(s);
+		if(ret == -1)
+			{
+			/* we only get to return -1 here the 2nd/Nth
+			 * invocation, we must  have already signalled
+			 * return 0 upon a previous invoation,
+			 * return WANT_WRITE */
+			return(ret);
+			}
+#endif
+		}
+	else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN))
+		{
+		/* If we are waiting for a close from our peer, we are closed */
+		s->method->ssl_read_bytes(s,0,NULL,0,0);
+		if(!(s->shutdown & SSL_RECEIVED_SHUTDOWN))
+			{
+			return(-1);	/* return WANT_READ */
+			}
+		}
+
+	if ((s->shutdown == (SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN)) &&
+		!s->s3->alert_dispatch)
+		return(1);
+	else
+		return(0);
+	}
+
+int ssl3_write(SSL *s, const void *buf, int len)
+	{
+	int ret,n;
+
+#if 0
+	if (s->shutdown & SSL_SEND_SHUTDOWN)
+		{
+		s->rwstate=SSL_NOTHING;
+		return(0);
+		}
+#endif
+	clear_sys_error();
+	if (s->s3->renegotiate) ssl3_renegotiate_check(s);
+
+	/* This is an experimental flag that sends the
+	 * last handshake message in the same packet as the first
+	 * use data - used to see if it helps the TCP protocol during
+	 * session-id reuse */
+	/* The second test is because the buffer may have been removed */
+	if ((s->s3->flags & SSL3_FLAGS_POP_BUFFER) && (s->wbio == s->bbio))
+		{
+		/* First time through, we write into the buffer */
+		if (s->s3->delay_buf_pop_ret == 0)
+			{
+			ret=ssl3_write_bytes(s,SSL3_RT_APPLICATION_DATA,
+					     buf,len);
+			if (ret <= 0) return(ret);
+
+			s->s3->delay_buf_pop_ret=ret;
+			}
+
+		s->rwstate=SSL_WRITING;
+		n=BIO_flush(s->wbio);
+		if (n <= 0) return(n);
+		s->rwstate=SSL_NOTHING;
+
+		/* We have flushed the buffer, so remove it */
+		ssl_free_wbio_buffer(s);
+		s->s3->flags&= ~SSL3_FLAGS_POP_BUFFER;
+
+		ret=s->s3->delay_buf_pop_ret;
+		s->s3->delay_buf_pop_ret=0;
+		}
+	else
+		{
+		ret=s->method->ssl_write_bytes(s,SSL3_RT_APPLICATION_DATA,
+			buf,len);
+		if (ret <= 0) return(ret);
+		}
+
+	return(ret);
+	}
+
+static int ssl3_read_internal(SSL *s, void *buf, int len, int peek)
+	{
+	int n,ret;
+	
+	clear_sys_error();
+	if ((s->s3->flags & SSL3_FLAGS_POP_BUFFER) && (s->wbio == s->bbio))
+		{
+		/* Deal with an application that calls SSL_read() when handshake data
+		 * is yet to be written.
+		 */
+		if (BIO_wpending(s->wbio) > 0)
+			{
+			s->rwstate=SSL_WRITING;
+			n=BIO_flush(s->wbio);
+			if (n <= 0) return(n);
+			s->rwstate=SSL_NOTHING;
+			}
+		}
+	if (s->s3->renegotiate) ssl3_renegotiate_check(s);
+	s->s3->in_read_app_data=1;
+	ret=s->method->ssl_read_bytes(s,SSL3_RT_APPLICATION_DATA,buf,len,peek);
+	if ((ret == -1) && (s->s3->in_read_app_data == 2))
+		{
+		/* ssl3_read_bytes decided to call s->handshake_func, which
+		 * called ssl3_read_bytes to read handshake data.
+		 * However, ssl3_read_bytes actually found application data
+		 * and thinks that application data makes sense here; so disable
+		 * handshake processing and try to read application data again. */
+		s->in_handshake++;
+		ret=s->method->ssl_read_bytes(s,SSL3_RT_APPLICATION_DATA,buf,len,peek);
+		s->in_handshake--;
+		}
+	else
+		s->s3->in_read_app_data=0;
+
+	return(ret);
+	}
+
+int ssl3_read(SSL *s, void *buf, int len)
+	{
+	return ssl3_read_internal(s, buf, len, 0);
+	}
+
+int ssl3_peek(SSL *s, void *buf, int len)
+	{
+	return ssl3_read_internal(s, buf, len, 1);
+	}
+
+int ssl3_renegotiate(SSL *s)
+	{
+	if (s->handshake_func == NULL)
+		return(1);
+
+	if (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)
+		return(0);
+
+	s->s3->renegotiate=1;
+	return(1);
+	}
+
+int ssl3_renegotiate_check(SSL *s)
+	{
+	int ret=0;
+
+	if (s->s3->renegotiate)
+		{
+		if (	(s->s3->rbuf.left == 0) &&
+			(s->s3->wbuf.left == 0) &&
+			!SSL_in_init(s))
+			{
+/*
+if we are the server, and we have sent a 'RENEGOTIATE' message, we
+need to go to SSL_ST_ACCEPT.
+*/
+			/* SSL_ST_ACCEPT */
+			s->state=SSL_ST_RENEGOTIATE;
+			s->s3->renegotiate=0;
+			s->s3->num_renegotiations++;
+			s->s3->total_renegotiations++;
+			ret=1;
+			}
+		}
+	return(ret);
+	}
+
diff --git a/openssl/ssl/s3_meth.c b/openssl/ssl/s3_meth.c
new file mode 100644
index 0000000..cdddb17
--- /dev/null
+++ b/openssl/ssl/s3_meth.c
@@ -0,0 +1,77 @@
+/* ssl/s3_meth.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+
+static const SSL_METHOD *ssl3_get_method(int ver);
+static const SSL_METHOD *ssl3_get_method(int ver)
+	{
+	if (ver == SSL3_VERSION)
+		return(SSLv3_method());
+	else 
+		return(NULL);
+	}
+
+IMPLEMENT_ssl3_meth_func(SSLv3_method,
+			 ssl3_accept,
+			 ssl3_connect,
+			 ssl3_get_method)
+
+
diff --git a/openssl/ssl/s3_pkt.c b/openssl/ssl/s3_pkt.c
new file mode 100644
index 0000000..0d3874a
--- /dev/null
+++ b/openssl/ssl/s3_pkt.c
@@ -0,0 +1,1502 @@
+/* ssl/s3_pkt.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "ssl_locl.h"
+#include <openssl/evp.h>
+#include <openssl/buffer.h>
+
+static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+			 unsigned int len, int create_empty_fragment);
+static int ssl3_get_record(SSL *s);
+
+int ssl3_read_n(SSL *s, int n, int max, int extend)
+	{
+	/* If extend == 0, obtain new n-byte packet; if extend == 1, increase
+	 * packet by another n bytes.
+	 * The packet will be in the sub-array of s->s3->rbuf.buf specified
+	 * by s->packet and s->packet_length.
+	 * (If s->read_ahead is set, 'max' bytes may be stored in rbuf
+	 * [plus s->packet_length bytes if extend == 1].)
+	 */
+	int i,len,left;
+	long align=0;
+	unsigned char *pkt;
+	SSL3_BUFFER *rb;
+
+	if (n <= 0) return n;
+
+	rb    = &(s->s3->rbuf);
+	if (rb->buf == NULL)
+		if (!ssl3_setup_read_buffer(s))
+			return -1;
+
+	left  = rb->left;
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+	align = (long)rb->buf + SSL3_RT_HEADER_LENGTH;
+	align = (-align)&(SSL3_ALIGN_PAYLOAD-1);
+#endif
+
+	if (!extend)
+		{
+		/* start with empty packet ... */
+		if (left == 0)
+			rb->offset = align;
+		else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH)
+			{
+			/* check if next packet length is large
+			 * enough to justify payload alignment... */
+			pkt = rb->buf + rb->offset;
+			if (pkt[0] == SSL3_RT_APPLICATION_DATA
+			    && (pkt[3]<<8|pkt[4]) >= 128)
+				{
+				/* Note that even if packet is corrupted
+				 * and its length field is insane, we can
+				 * only be led to wrong decision about
+				 * whether memmove will occur or not.
+				 * Header values has no effect on memmove
+				 * arguments and therefore no buffer
+				 * overrun can be triggered. */
+				memmove (rb->buf+align,pkt,left);
+				rb->offset = align;
+				}
+			}
+		s->packet = rb->buf + rb->offset;
+		s->packet_length = 0;
+		/* ... now we can act as if 'extend' was set */
+		}
+
+	/* For DTLS/UDP reads should not span multiple packets
+	 * because the read operation returns the whole packet
+	 * at once (as long as it fits into the buffer). */
+	if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
+		{
+		if (left > 0 && n > left)
+			n = left;
+		}
+
+	/* if there is enough in the buffer from a previous read, take some */
+	if (left >= n)
+		{
+		s->packet_length+=n;
+		rb->left=left-n;
+		rb->offset+=n;
+		return(n);
+		}
+
+	/* else we need to read more data */
+
+	len = s->packet_length;
+	pkt = rb->buf+align;
+	/* Move any available bytes to front of buffer:
+	 * 'len' bytes already pointed to by 'packet',
+	 * 'left' extra ones at the end */
+	if (s->packet != pkt) /* len > 0 */
+		{
+		memmove(pkt, s->packet, len+left);
+		s->packet = pkt;
+		rb->offset = len + align;
+		}
+
+	if (n > (int)(rb->len - rb->offset)) /* does not happen */
+		{
+		SSLerr(SSL_F_SSL3_READ_N,ERR_R_INTERNAL_ERROR);
+		return -1;
+		}
+
+	if (!s->read_ahead)
+		/* ignore max parameter */
+		max = n;
+	else
+		{
+		if (max < n)
+			max = n;
+		if (max > (int)(rb->len - rb->offset))
+			max = rb->len - rb->offset;
+		}
+
+	while (left < n)
+		{
+		/* Now we have len+left bytes at the front of s->s3->rbuf.buf
+		 * and need to read in more until we have len+n (up to
+		 * len+max if possible) */
+
+		clear_sys_error();
+		if (s->rbio != NULL)
+			{
+			s->rwstate=SSL_READING;
+			i=BIO_read(s->rbio,pkt+len+left, max-left);
+			}
+		else
+			{
+			SSLerr(SSL_F_SSL3_READ_N,SSL_R_READ_BIO_NOT_SET);
+			i = -1;
+			}
+
+		if (i <= 0)
+			{
+			rb->left = left;
+			if (s->mode & SSL_MODE_RELEASE_BUFFERS &&
+			    SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
+				if (len+left == 0)
+					ssl3_release_read_buffer(s);
+			return(i);
+			}
+		left+=i;
+		/* reads should *never* span multiple packets for DTLS because
+		 * the underlying transport protocol is message oriented as opposed
+		 * to byte oriented as in the TLS case. */
+		if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
+			{
+			if (n > left)
+				n = left; /* makes the while condition false */
+			}
+		}
+
+	/* done reading, now the book-keeping */
+	rb->offset += n;
+	rb->left = left - n;
+	s->packet_length += n;
+	s->rwstate=SSL_NOTHING;
+	return(n);
+	}
+
+/* Call this to get a new input record.
+ * It will return <= 0 if more data is needed, normally due to an error
+ * or non-blocking IO.
+ * When it finishes, one packet has been decoded and can be found in
+ * ssl->s3->rrec.type    - is the type of record
+ * ssl->s3->rrec.data, 	 - data
+ * ssl->s3->rrec.length, - number of bytes
+ */
+/* used only by ssl3_read_bytes */
+static int ssl3_get_record(SSL *s)
+	{
+	int ssl_major,ssl_minor,al;
+	int enc_err,n,i,ret= -1;
+	SSL3_RECORD *rr;
+	SSL_SESSION *sess;
+	unsigned char *p;
+	unsigned char md[EVP_MAX_MD_SIZE];
+	short version;
+	int mac_size;
+	int clear=0;
+	size_t extra;
+	int decryption_failed_or_bad_record_mac = 0;
+	unsigned char *mac = NULL;
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+	long align=SSL3_ALIGN_PAYLOAD;
+#else
+	long align=0;
+#endif
+
+	rr= &(s->s3->rrec);
+	sess=s->session;
+
+	if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
+		extra=SSL3_RT_MAX_EXTRA;
+	else
+		extra=0;
+	if (!(SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) &&
+		extra && !s->s3->init_extra)
+		{
+		/* An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER
+		 * set after ssl3_setup_buffers() was done */
+		SSLerr(SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR);
+		return -1;
+		}
+
+again:
+	/* check if we have the header */
+	if (	(s->rstate != SSL_ST_READ_BODY) ||
+		(s->packet_length < SSL3_RT_HEADER_LENGTH)) 
+		{
+		n=ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, s->s3->rbuf.len, 0);
+		if (n <= 0) return(n); /* error or non-blocking */
+		s->rstate=SSL_ST_READ_BODY;
+
+		p=s->packet;
+
+		/* Pull apart the header into the SSL3_RECORD */
+		rr->type= *(p++);
+		ssl_major= *(p++);
+		ssl_minor= *(p++);
+		version=(ssl_major<<8)|ssl_minor;
+		n2s(p,rr->length);
+#if 0
+fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length);
+#endif
+
+		/* Lets check version */
+		if (!s->first_packet)
+			{
+			if (version != s->version)
+				{
+				SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
+                                if ((s->version & 0xFF00) == (version & 0xFF00))
+                                	/* Send back error using their minor version number :-) */
+					s->version = (unsigned short)version;
+				al=SSL_AD_PROTOCOL_VERSION;
+				goto f_err;
+				}
+			}
+
+		if ((version>>8) != SSL3_VERSION_MAJOR)
+			{
+			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
+			goto err;
+			}
+
+		/* If we receive a valid record larger than the current buffer size,
+		 * allocate some memory for it.
+		 */
+		if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH - align)
+			{
+			if ((p=OPENSSL_realloc(s->s3->rbuf.buf, rr->length + SSL3_RT_HEADER_LENGTH + align))==NULL)
+				{
+				SSLerr(SSL_F_SSL3_GET_RECORD,ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			s->s3->rbuf.buf=p;
+			s->s3->rbuf.len=rr->length + SSL3_RT_HEADER_LENGTH + align;
+			s->packet= &(s->s3->rbuf.buf[0]);
+			}
+
+		if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH)
+			{
+			al=SSL_AD_RECORD_OVERFLOW;
+			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG);
+			goto f_err;
+			}
+
+		/* now s->rstate == SSL_ST_READ_BODY */
+		}
+
+	/* s->rstate == SSL_ST_READ_BODY, get and decode the data */
+
+	if (rr->length > s->packet_length-SSL3_RT_HEADER_LENGTH)
+		{
+		/* now s->packet_length == SSL3_RT_HEADER_LENGTH */
+		i=rr->length;
+		n=ssl3_read_n(s,i,i,1);
+		if (n <= 0) return(n); /* error or non-blocking io */
+		/* now n == rr->length,
+		 * and s->packet_length == SSL3_RT_HEADER_LENGTH + rr->length */
+		}
+
+	s->rstate=SSL_ST_READ_HEADER; /* set state for later operations */
+
+	/* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
+	 * and we have that many bytes in s->packet
+	 */
+	rr->input= &(s->packet[SSL3_RT_HEADER_LENGTH]);
+
+	/* ok, we can now read from 's->packet' data into 'rr'
+	 * rr->input points at rr->length bytes, which
+	 * need to be copied into rr->data by either
+	 * the decryption or by the decompression
+	 * When the data is 'copied' into the rr->data buffer,
+	 * rr->input will be pointed at the new buffer */ 
+
+	/* We now have - encrypted [ MAC [ compressed [ plain ] ] ]
+	 * rr->length bytes of encrypted compressed stuff. */
+
+	/* check is not needed I believe */
+	if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH+extra)
+		{
+		al=SSL_AD_RECORD_OVERFLOW;
+		SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
+		goto f_err;
+		}
+
+	/* decrypt in place in 'rr->input' */
+	rr->data=rr->input;
+
+	enc_err = s->method->ssl3_enc->enc(s,0);
+	if (enc_err <= 0)
+		{
+		if (enc_err == 0)
+			/* SSLerr() and ssl3_send_alert() have been called */
+			goto err;
+
+		/* Otherwise enc_err == -1, which indicates bad padding
+		 * (rec->length has not been changed in this case).
+		 * To minimize information leaked via timing, we will perform
+		 * the MAC computation anyway. */
+		decryption_failed_or_bad_record_mac = 1;
+		}
+
+#ifdef TLS_DEBUG
+printf("dec %d\n",rr->length);
+{ unsigned int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); }
+printf("\n");
+#endif
+
+	/* r->length is now the compressed data plus mac */
+	if (	(sess == NULL) ||
+		(s->enc_read_ctx == NULL) ||
+		(EVP_MD_CTX_md(s->read_hash) == NULL))
+		clear=1;
+
+	if (!clear)
+		{
+		/* !clear => s->read_hash != NULL => mac_size != -1 */
+		mac_size=EVP_MD_CTX_size(s->read_hash);
+		OPENSSL_assert(mac_size >= 0);
+
+		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size)
+			{
+#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */
+			al=SSL_AD_RECORD_OVERFLOW;
+			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
+			goto f_err;
+#else
+			decryption_failed_or_bad_record_mac = 1;
+#endif			
+			}
+		/* check the MAC for rr->input (it's in mac_size bytes at the tail) */
+		if (rr->length >= (unsigned int)mac_size)
+			{
+			rr->length -= mac_size;
+			mac = &rr->data[rr->length];
+			}
+		else
+			{
+			/* record (minus padding) is too short to contain a MAC */
+#if 0 /* OK only for stream ciphers */
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT);
+			goto f_err;
+#else
+			decryption_failed_or_bad_record_mac = 1;
+			rr->length = 0;
+#endif
+			}
+		i=s->method->ssl3_enc->mac(s,md,0);
+		if (i < 0 || mac == NULL || memcmp(md, mac, (size_t)mac_size) != 0)
+			{
+			decryption_failed_or_bad_record_mac = 1;
+			}
+		}
+
+	if (decryption_failed_or_bad_record_mac)
+		{
+		/* A separate 'decryption_failed' alert was introduced with TLS 1.0,
+		 * SSL 3.0 only has 'bad_record_mac'.  But unless a decryption
+		 * failure is directly visible from the ciphertext anyway,
+		 * we should not reveal which kind of error occured -- this
+		 * might become visible to an attacker (e.g. via a logfile) */
+		al=SSL_AD_BAD_RECORD_MAC;
+		SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
+		goto f_err;
+		}
+
+	/* r->length is now just compressed */
+	if (s->expand != NULL)
+		{
+		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra)
+			{
+			al=SSL_AD_RECORD_OVERFLOW;
+			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG);
+			goto f_err;
+			}
+		if (!ssl3_do_uncompress(s))
+			{
+			al=SSL_AD_DECOMPRESSION_FAILURE;
+			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BAD_DECOMPRESSION);
+			goto f_err;
+			}
+		}
+
+	if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH+extra)
+		{
+		al=SSL_AD_RECORD_OVERFLOW;
+		SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DATA_LENGTH_TOO_LONG);
+		goto f_err;
+		}
+
+	rr->off=0;
+	/* So at this point the following is true
+	 * ssl->s3->rrec.type 	is the type of record
+	 * ssl->s3->rrec.length	== number of bytes in record
+	 * ssl->s3->rrec.off	== offset to first valid byte
+	 * ssl->s3->rrec.data	== where to take bytes from, increment
+	 *			   after use :-).
+	 */
+
+	/* we have pulled in a full packet so zero things */
+	s->packet_length=0;
+
+	/* just read a 0 length packet */
+	if (rr->length == 0) goto again;
+
+#if 0
+fprintf(stderr, "Ultimate Record type=%d, Length=%d\n", rr->type, rr->length);
+#endif
+
+	return(1);
+
+f_err:
+	ssl3_send_alert(s,SSL3_AL_FATAL,al);
+err:
+	return(ret);
+	}
+
+int ssl3_do_uncompress(SSL *ssl)
+	{
+#ifndef OPENSSL_NO_COMP
+	int i;
+	SSL3_RECORD *rr;
+
+	rr= &(ssl->s3->rrec);
+	i=COMP_expand_block(ssl->expand,rr->comp,
+		SSL3_RT_MAX_PLAIN_LENGTH,rr->data,(int)rr->length);
+	if (i < 0)
+		return(0);
+	else
+		rr->length=i;
+	rr->data=rr->comp;
+#endif
+	return(1);
+	}
+
+int ssl3_do_compress(SSL *ssl)
+	{
+#ifndef OPENSSL_NO_COMP
+	int i;
+	SSL3_RECORD *wr;
+
+	wr= &(ssl->s3->wrec);
+	i=COMP_compress_block(ssl->compress,wr->data,
+		SSL3_RT_MAX_COMPRESSED_LENGTH,
+		wr->input,(int)wr->length);
+	if (i < 0)
+		return(0);
+	else
+		wr->length=i;
+
+	wr->input=wr->data;
+#endif
+	return(1);
+	}
+
+/* Call this to write data in records of type 'type'
+ * It will return <= 0 if not all data has been sent or non-blocking IO.
+ */
+int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
+	{
+	const unsigned char *buf=buf_;
+	unsigned int tot,n,nw;
+	int i;
+	unsigned int max_plain_length;
+
+	s->rwstate=SSL_NOTHING;
+	tot=s->s3->wnum;
+	s->s3->wnum=0;
+
+	if (SSL_in_init(s) && !s->in_handshake)
+		{
+		i=s->handshake_func(s);
+		if (i < 0) return(i);
+		if (i == 0)
+			{
+			SSLerr(SSL_F_SSL3_WRITE_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
+			return -1;
+			}
+		}
+
+	n=(len-tot);
+	for (;;)
+		{
+		if (type == SSL3_RT_APPLICATION_DATA && (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS))
+			max_plain_length = SSL3_RT_DEFAULT_PLAIN_LENGTH;
+		else
+			max_plain_length = s->max_send_fragment;
+
+		if (n > max_plain_length)
+			nw = max_plain_length;
+		else
+			nw=n;
+
+		i=do_ssl3_write(s, type, &(buf[tot]), nw, 0);
+		if (i <= 0)
+			{
+			s->s3->wnum=tot;
+			return i;
+			}
+
+		if ((i == (int)n) ||
+			(type == SSL3_RT_APPLICATION_DATA &&
+			 (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)))
+			{
+			/* next chunk of data should get another prepended empty fragment
+			 * in ciphersuites with known-IV weakness: */
+			s->s3->empty_fragment_done = 0;
+			
+			return tot+i;
+			}
+
+		n-=i;
+		tot+=i;
+		}
+	}
+
+static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+			 unsigned int len, int create_empty_fragment)
+	{
+	unsigned char *p,*plen;
+	int i,mac_size,clear=0;
+	int prefix_len=0;
+	long align=0;
+	SSL3_RECORD *wr;
+	SSL3_BUFFER *wb=&(s->s3->wbuf);
+	SSL_SESSION *sess;
+
+ 	if (wb->buf == NULL)
+		if (!ssl3_setup_write_buffer(s))
+			return -1;
+
+	/* first check if there is a SSL3_BUFFER still being written
+	 * out.  This will happen with non blocking IO */
+	if (wb->left != 0)
+		return(ssl3_write_pending(s,type,buf,len));
+
+	/* If we have an alert to send, lets send it */
+	if (s->s3->alert_dispatch)
+		{
+		i=s->method->ssl_dispatch_alert(s);
+		if (i <= 0)
+			return(i);
+		/* if it went, fall through and send more stuff */
+		}
+
+	if (len == 0 && !create_empty_fragment)
+		return 0;
+
+	wr= &(s->s3->wrec);
+	sess=s->session;
+
+	if (	(sess == NULL) ||
+		(s->enc_write_ctx == NULL) ||
+		(EVP_MD_CTX_md(s->write_hash) == NULL))
+		clear=1;
+
+	if (clear)
+		mac_size=0;
+	else
+		{
+		mac_size=EVP_MD_CTX_size(s->write_hash);
+		if (mac_size < 0)
+			goto err;
+		}
+
+	/* 'create_empty_fragment' is true only when this function calls itself */
+	if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done)
+		{
+		/* countermeasure against known-IV weakness in CBC ciphersuites
+		 * (see http://www.openssl.org/~bodo/tls-cbc.txt) */
+
+		if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA)
+			{
+			/* recursive function call with 'create_empty_fragment' set;
+			 * this prepares and buffers the data for an empty fragment
+			 * (these 'prefix_len' bytes are sent out later
+			 * together with the actual payload) */
+			prefix_len = do_ssl3_write(s, type, buf, 0, 1);
+			if (prefix_len <= 0)
+				goto err;
+
+			if (prefix_len >
+		(SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD))
+				{
+				/* insufficient space */
+				SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+			}
+		
+		s->s3->empty_fragment_done = 1;
+		}
+
+	/* resize if necessary to hold the data. */
+	if (len + SSL3_RT_DEFAULT_WRITE_OVERHEAD > wb->len)
+		{
+		if ((p=OPENSSL_realloc(wb->buf, len + SSL3_RT_DEFAULT_WRITE_OVERHEAD))==NULL)
+			{
+			SSLerr(SSL_F_DO_SSL3_WRITE,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		wb->buf = p;
+		wb->len = len + SSL3_RT_DEFAULT_WRITE_OVERHEAD;
+		}
+
+	if (create_empty_fragment)
+		{
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+		/* extra fragment would be couple of cipher blocks,
+		 * which would be multiple of SSL3_ALIGN_PAYLOAD, so
+		 * if we want to align the real payload, then we can
+		 * just pretent we simply have two headers. */
+		align = (long)wb->buf + 2*SSL3_RT_HEADER_LENGTH;
+		align = (-align)&(SSL3_ALIGN_PAYLOAD-1);
+#endif
+		p = wb->buf + align;
+		wb->offset  = align;
+		}
+	else if (prefix_len)
+		{
+		p = wb->buf + wb->offset + prefix_len;
+		}
+	else
+		{
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+		align = (long)wb->buf + SSL3_RT_HEADER_LENGTH;
+		align = (-align)&(SSL3_ALIGN_PAYLOAD-1);
+#endif
+		p = wb->buf + align;
+		wb->offset  = align;
+		}
+
+	/* write the header */
+
+	*(p++)=type&0xff;
+	wr->type=type;
+
+	*(p++)=(s->version>>8);
+	*(p++)=s->version&0xff;
+
+	/* field where we are to write out packet length */
+	plen=p; 
+	p+=2;
+
+	/* lets setup the record stuff. */
+	wr->data=p;
+	wr->length=(int)len;
+	wr->input=(unsigned char *)buf;
+
+	/* we now 'read' from wr->input, wr->length bytes into
+	 * wr->data */
+
+	/* first we compress */
+	if (s->compress != NULL)
+		{
+		if (!ssl3_do_compress(s))
+			{
+			SSLerr(SSL_F_DO_SSL3_WRITE,SSL_R_COMPRESSION_FAILURE);
+			goto err;
+			}
+		}
+	else
+		{
+		memcpy(wr->data,wr->input,wr->length);
+		wr->input=wr->data;
+		}
+
+	/* we should still have the output to wr->data and the input
+	 * from wr->input.  Length should be wr->length.
+	 * wr->data still points in the wb->buf */
+
+	if (mac_size != 0)
+		{
+		if (s->method->ssl3_enc->mac(s,&(p[wr->length]),1) < 0)
+			goto err;
+		wr->length+=mac_size;
+		wr->input=p;
+		wr->data=p;
+		}
+
+	/* ssl3_enc can only have an error on read */
+	s->method->ssl3_enc->enc(s,1);
+
+	/* record length after mac and block padding */
+	s2n(wr->length,plen);
+
+	/* we should now have
+	 * wr->data pointing to the encrypted data, which is
+	 * wr->length long */
+	wr->type=type; /* not needed but helps for debugging */
+	wr->length+=SSL3_RT_HEADER_LENGTH;
+
+	if (create_empty_fragment)
+		{
+		/* we are in a recursive call;
+		 * just return the length, don't write out anything here
+		 */
+		return wr->length;
+		}
+
+	/* now let's set up wb */
+	wb->left = prefix_len + wr->length;
+
+	/* memorize arguments so that ssl3_write_pending can detect bad write retries later */
+	s->s3->wpend_tot=len;
+	s->s3->wpend_buf=buf;
+	s->s3->wpend_type=type;
+	s->s3->wpend_ret=len;
+
+	/* we now just need to write the buffer */
+	return ssl3_write_pending(s,type,buf,len);
+err:
+	return -1;
+	}
+
+/* if s->s3->wbuf.left != 0, we need to call this */
+int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
+	unsigned int len)
+	{
+	int i;
+	SSL3_BUFFER *wb=&(s->s3->wbuf);
+
+/* XXXX */
+	if ((s->s3->wpend_tot > (int)len)
+		|| ((s->s3->wpend_buf != buf) &&
+			!(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER))
+		|| (s->s3->wpend_type != type))
+		{
+		SSLerr(SSL_F_SSL3_WRITE_PENDING,SSL_R_BAD_WRITE_RETRY);
+		return(-1);
+		}
+
+	for (;;)
+		{
+		clear_sys_error();
+		if (s->wbio != NULL)
+			{
+			s->rwstate=SSL_WRITING;
+			i=BIO_write(s->wbio,
+				(char *)&(wb->buf[wb->offset]),
+				(unsigned int)wb->left);
+			}
+		else
+			{
+			SSLerr(SSL_F_SSL3_WRITE_PENDING,SSL_R_BIO_NOT_SET);
+			i= -1;
+			}
+		if (i == wb->left)
+			{
+			wb->left=0;
+			wb->offset+=i;
+			if (s->mode & SSL_MODE_RELEASE_BUFFERS &&
+			    SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
+				ssl3_release_write_buffer(s);
+			s->rwstate=SSL_NOTHING;
+			return(s->s3->wpend_ret);
+			}
+		else if (i <= 0) {
+			if (s->version == DTLS1_VERSION ||
+			    s->version == DTLS1_BAD_VER) {
+				/* For DTLS, just drop it. That's kind of the whole
+				   point in using a datagram service */
+				wb->left = 0;
+			}
+			return(i);
+		}
+		wb->offset+=i;
+		wb->left-=i;
+		}
+	}
+
+/* Return up to 'len' payload bytes received in 'type' records.
+ * 'type' is one of the following:
+ *
+ *   -  SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
+ *   -  SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
+ *   -  0 (during a shutdown, no data has to be returned)
+ *
+ * If we don't have stored data to work from, read a SSL/TLS record first
+ * (possibly multiple records if we still don't have anything to return).
+ *
+ * This function must handle any surprises the peer may have for us, such as
+ * Alert records (e.g. close_notify), ChangeCipherSpec records (not really
+ * a surprise, but handled as if it were), or renegotiation requests.
+ * Also if record payloads contain fragments too small to process, we store
+ * them until there is enough for the respective protocol (the record protocol
+ * may use arbitrary fragmentation and even interleaving):
+ *     Change cipher spec protocol
+ *             just 1 byte needed, no need for keeping anything stored
+ *     Alert protocol
+ *             2 bytes needed (AlertLevel, AlertDescription)
+ *     Handshake protocol
+ *             4 bytes needed (HandshakeType, uint24 length) -- we just have
+ *             to detect unexpected Client Hello and Hello Request messages
+ *             here, anything else is handled by higher layers
+ *     Application data protocol
+ *             none of our business
+ */
+int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
+	{
+	int al,i,j,ret;
+	unsigned int n;
+	SSL3_RECORD *rr;
+	void (*cb)(const SSL *ssl,int type2,int val)=NULL;
+
+	if (s->s3->rbuf.buf == NULL) /* Not initialized yet */
+		if (!ssl3_setup_read_buffer(s))
+			return(-1);
+
+	if ((type && (type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE) && type) ||
+	    (peek && (type != SSL3_RT_APPLICATION_DATA)))
+		{
+		SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR);
+		return -1;
+		}
+
+	if ((type == SSL3_RT_HANDSHAKE) && (s->s3->handshake_fragment_len > 0))
+		/* (partially) satisfy request from storage */
+		{
+		unsigned char *src = s->s3->handshake_fragment;
+		unsigned char *dst = buf;
+		unsigned int k;
+
+		/* peek == 0 */
+		n = 0;
+		while ((len > 0) && (s->s3->handshake_fragment_len > 0))
+			{
+			*dst++ = *src++;
+			len--; s->s3->handshake_fragment_len--;
+			n++;
+			}
+		/* move any remaining fragment bytes: */
+		for (k = 0; k < s->s3->handshake_fragment_len; k++)
+			s->s3->handshake_fragment[k] = *src++;
+		return n;
+	}
+
+	/* Now s->s3->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */
+
+	if (!s->in_handshake && SSL_in_init(s))
+		{
+		/* type == SSL3_RT_APPLICATION_DATA */
+		i=s->handshake_func(s);
+		if (i < 0) return(i);
+		if (i == 0)
+			{
+			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
+			return(-1);
+			}
+		}
+start:
+	s->rwstate=SSL_NOTHING;
+
+	/* s->s3->rrec.type	    - is the type of record
+	 * s->s3->rrec.data,    - data
+	 * s->s3->rrec.off,     - offset into 'data' for next read
+	 * s->s3->rrec.length,  - number of bytes. */
+	rr = &(s->s3->rrec);
+
+	/* get new packet if necessary */
+	if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY))
+		{
+		ret=ssl3_get_record(s);
+		if (ret <= 0) return(ret);
+		}
+
+	/* we now have a packet which can be read and processed */
+
+	if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
+	                               * reset by ssl3_get_finished */
+		&& (rr->type != SSL3_RT_HANDSHAKE))
+		{
+		al=SSL_AD_UNEXPECTED_MESSAGE;
+		SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
+		goto f_err;
+		}
+
+	/* If the other end has shut down, throw anything we read away
+	 * (even in 'peek' mode) */
+	if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
+		{
+		rr->length=0;
+		s->rwstate=SSL_NOTHING;
+		return(0);
+		}
+
+
+	if (type == rr->type) /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */
+		{
+		/* make sure that we are not getting application data when we
+		 * are doing a handshake for the first time */
+		if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
+			(s->enc_read_ctx == NULL))
+			{
+			al=SSL_AD_UNEXPECTED_MESSAGE;
+			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_APP_DATA_IN_HANDSHAKE);
+			goto f_err;
+			}
+
+		if (len <= 0) return(len);
+
+		if ((unsigned int)len > rr->length)
+			n = rr->length;
+		else
+			n = (unsigned int)len;
+
+		memcpy(buf,&(rr->data[rr->off]),n);
+		if (!peek)
+			{
+			rr->length-=n;
+			rr->off+=n;
+			if (rr->length == 0)
+				{
+				s->rstate=SSL_ST_READ_HEADER;
+				rr->off=0;
+				if (s->mode & SSL_MODE_RELEASE_BUFFERS)
+					ssl3_release_read_buffer(s);
+				}
+			}
+		return(n);
+		}
+
+
+	/* If we get here, then type != rr->type; if we have a handshake
+	 * message, then it was unexpected (Hello Request or Client Hello). */
+
+	/* In case of record types for which we have 'fragment' storage,
+	 * fill that so that we can process the data at a fixed place.
+	 */
+		{
+		unsigned int dest_maxlen = 0;
+		unsigned char *dest = NULL;
+		unsigned int *dest_len = NULL;
+
+		if (rr->type == SSL3_RT_HANDSHAKE)
+			{
+			dest_maxlen = sizeof s->s3->handshake_fragment;
+			dest = s->s3->handshake_fragment;
+			dest_len = &s->s3->handshake_fragment_len;
+			}
+		else if (rr->type == SSL3_RT_ALERT)
+			{
+			dest_maxlen = sizeof s->s3->alert_fragment;
+			dest = s->s3->alert_fragment;
+			dest_len = &s->s3->alert_fragment_len;
+			}
+
+		if (dest_maxlen > 0)
+			{
+			n = dest_maxlen - *dest_len; /* available space in 'dest' */
+			if (rr->length < n)
+				n = rr->length; /* available bytes */
+
+			/* now move 'n' bytes: */
+			while (n-- > 0)
+				{
+				dest[(*dest_len)++] = rr->data[rr->off++];
+				rr->length--;
+				}
+
+			if (*dest_len < dest_maxlen)
+				goto start; /* fragment was too small */
+			}
+		}
+
+	/* s->s3->handshake_fragment_len == 4  iff  rr->type == SSL3_RT_HANDSHAKE;
+	 * s->s3->alert_fragment_len == 2      iff  rr->type == SSL3_RT_ALERT.
+	 * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */
+
+	/* If we are a client, check for an incoming 'Hello Request': */
+	if ((!s->server) &&
+		(s->s3->handshake_fragment_len >= 4) &&
+		(s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
+		(s->session != NULL) && (s->session->cipher != NULL))
+		{
+		s->s3->handshake_fragment_len = 0;
+
+		if ((s->s3->handshake_fragment[1] != 0) ||
+			(s->s3->handshake_fragment[2] != 0) ||
+			(s->s3->handshake_fragment[3] != 0))
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_HELLO_REQUEST);
+			goto f_err;
+			}
+
+		if (s->msg_callback)
+			s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->s3->handshake_fragment, 4, s, s->msg_callback_arg);
+
+		if (SSL_is_init_finished(s) &&
+			!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
+			!s->s3->renegotiate)
+			{
+			ssl3_renegotiate(s);
+			if (ssl3_renegotiate_check(s))
+				{
+				i=s->handshake_func(s);
+				if (i < 0) return(i);
+				if (i == 0)
+					{
+					SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
+					return(-1);
+					}
+
+				if (!(s->mode & SSL_MODE_AUTO_RETRY))
+					{
+					if (s->s3->rbuf.left == 0) /* no read-ahead left? */
+						{
+						BIO *bio;
+						/* In the case where we try to read application data,
+						 * but we trigger an SSL handshake, we return -1 with
+						 * the retry option set.  Otherwise renegotiation may
+						 * cause nasty problems in the blocking world */
+						s->rwstate=SSL_READING;
+						bio=SSL_get_rbio(s);
+						BIO_clear_retry_flags(bio);
+						BIO_set_retry_read(bio);
+						return(-1);
+						}
+					}
+				}
+			}
+		/* we either finished a handshake or ignored the request,
+		 * now try again to obtain the (application) data we were asked for */
+		goto start;
+		}
+	/* If we are a server and get a client hello when renegotiation isn't
+	 * allowed send back a no renegotiation alert and carry on.
+	 * WARNING: experimental code, needs reviewing (steve)
+	 */
+	if (s->server &&
+		SSL_is_init_finished(s) &&
+    		!s->s3->send_connection_binding &&
+		(s->version > SSL3_VERSION) &&
+		(s->s3->handshake_fragment_len >= 4) &&
+		(s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) &&
+		(s->session != NULL) && (s->session->cipher != NULL) &&
+		!(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+		
+		{
+		/*s->s3->handshake_fragment_len = 0;*/
+		rr->length = 0;
+		ssl3_send_alert(s,SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
+		goto start;
+		}
+	if (s->s3->alert_fragment_len >= 2)
+		{
+		int alert_level = s->s3->alert_fragment[0];
+		int alert_descr = s->s3->alert_fragment[1];
+
+		s->s3->alert_fragment_len = 0;
+
+		if (s->msg_callback)
+			s->msg_callback(0, s->version, SSL3_RT_ALERT, s->s3->alert_fragment, 2, s, s->msg_callback_arg);
+
+		if (s->info_callback != NULL)
+			cb=s->info_callback;
+		else if (s->ctx->info_callback != NULL)
+			cb=s->ctx->info_callback;
+
+		if (cb != NULL)
+			{
+			j = (alert_level << 8) | alert_descr;
+			cb(s, SSL_CB_READ_ALERT, j);
+			}
+
+		if (alert_level == 1) /* warning */
+			{
+			s->s3->warn_alert = alert_descr;
+			if (alert_descr == SSL_AD_CLOSE_NOTIFY)
+				{
+				s->shutdown |= SSL_RECEIVED_SHUTDOWN;
+				return(0);
+				}
+			/* This is a warning but we receive it if we requested
+			 * renegotiation and the peer denied it. Terminate with
+			 * a fatal alert because if application tried to
+			 * renegotiatie it presumably had a good reason and
+			 * expects it to succeed.
+			 *
+			 * In future we might have a renegotiation where we
+			 * don't care if the peer refused it where we carry on.
+			 */
+			else if (alert_descr == SSL_AD_NO_RENEGOTIATION)
+				{
+				al = SSL_AD_HANDSHAKE_FAILURE;
+				SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_NO_RENEGOTIATION);
+				goto f_err;
+				}
+			}
+		else if (alert_level == 2) /* fatal */
+			{
+			char tmp[16];
+
+			s->rwstate=SSL_NOTHING;
+			s->s3->fatal_alert = alert_descr;
+			SSLerr(SSL_F_SSL3_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);
+			BIO_snprintf(tmp,sizeof tmp,"%d",alert_descr);
+			ERR_add_error_data(2,"SSL alert number ",tmp);
+			s->shutdown|=SSL_RECEIVED_SHUTDOWN;
+			SSL_CTX_remove_session(s->ctx,s->session);
+			return(0);
+			}
+		else
+			{
+			al=SSL_AD_ILLEGAL_PARAMETER;
+			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNKNOWN_ALERT_TYPE);
+			goto f_err;
+			}
+
+		goto start;
+		}
+
+	if (s->shutdown & SSL_SENT_SHUTDOWN) /* but we have not received a shutdown */
+		{
+		s->rwstate=SSL_NOTHING;
+		rr->length=0;
+		return(0);
+		}
+
+	if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
+		{
+		/* 'Change Cipher Spec' is just a single byte, so we know
+		 * exactly what the record payload has to look like */
+		if (	(rr->length != 1) || (rr->off != 0) ||
+			(rr->data[0] != SSL3_MT_CCS))
+			{
+			al=SSL_AD_ILLEGAL_PARAMETER;
+			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC);
+			goto f_err;
+			}
+
+		/* Check we have a cipher to change to */
+		if (s->s3->tmp.new_cipher == NULL)
+			{
+			al=SSL_AD_UNEXPECTED_MESSAGE;
+			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_CCS_RECEIVED_EARLY);
+			goto f_err;
+			}
+
+		rr->length=0;
+
+		if (s->msg_callback)
+			s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, rr->data, 1, s, s->msg_callback_arg);
+
+		s->s3->change_cipher_spec=1;
+		if (!ssl3_do_change_cipher_spec(s))
+			goto err;
+		else
+			goto start;
+		}
+
+	/* Unexpected handshake message (Client Hello, or protocol violation) */
+	if ((s->s3->handshake_fragment_len >= 4) &&	!s->in_handshake)
+		{
+		if (((s->state&SSL_ST_MASK) == SSL_ST_OK) &&
+			!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS))
+			{
+#if 0 /* worked only because C operator preferences are not as expected (and
+       * because this is not really needed for clients except for detecting
+       * protocol violations): */
+			s->state=SSL_ST_BEFORE|(s->server)
+				?SSL_ST_ACCEPT
+				:SSL_ST_CONNECT;
+#else
+			s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
+#endif
+			s->new_session=1;
+			}
+		i=s->handshake_func(s);
+		if (i < 0) return(i);
+		if (i == 0)
+			{
+			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
+			return(-1);
+			}
+
+		if (!(s->mode & SSL_MODE_AUTO_RETRY))
+			{
+			if (s->s3->rbuf.left == 0) /* no read-ahead left? */
+				{
+				BIO *bio;
+				/* In the case where we try to read application data,
+				 * but we trigger an SSL handshake, we return -1 with
+				 * the retry option set.  Otherwise renegotiation may
+				 * cause nasty problems in the blocking world */
+				s->rwstate=SSL_READING;
+				bio=SSL_get_rbio(s);
+				BIO_clear_retry_flags(bio);
+				BIO_set_retry_read(bio);
+				return(-1);
+				}
+			}
+		goto start;
+		}
+
+	switch (rr->type)
+		{
+	default:
+#ifndef OPENSSL_NO_TLS
+		/* TLS just ignores unknown message types */
+		if (s->version == TLS1_VERSION)
+			{
+			rr->length = 0;
+			goto start;
+			}
+#endif
+		al=SSL_AD_UNEXPECTED_MESSAGE;
+		SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
+		goto f_err;
+	case SSL3_RT_CHANGE_CIPHER_SPEC:
+	case SSL3_RT_ALERT:
+	case SSL3_RT_HANDSHAKE:
+		/* we already handled all of these, with the possible exception
+		 * of SSL3_RT_HANDSHAKE when s->in_handshake is set, but that
+		 * should not happen when type != rr->type */
+		al=SSL_AD_UNEXPECTED_MESSAGE;
+		SSLerr(SSL_F_SSL3_READ_BYTES,ERR_R_INTERNAL_ERROR);
+		goto f_err;
+	case SSL3_RT_APPLICATION_DATA:
+		/* At this point, we were expecting handshake data,
+		 * but have application data.  If the library was
+		 * running inside ssl3_read() (i.e. in_read_app_data
+		 * is set) and it makes sense to read application data
+		 * at this point (session renegotiation not yet started),
+		 * we will indulge it.
+		 */
+		if (s->s3->in_read_app_data &&
+			(s->s3->total_renegotiations != 0) &&
+			((
+				(s->state & SSL_ST_CONNECT) &&
+				(s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&
+				(s->state <= SSL3_ST_CR_SRVR_HELLO_A)
+				) || (
+					(s->state & SSL_ST_ACCEPT) &&
+					(s->state <= SSL3_ST_SW_HELLO_REQ_A) &&
+					(s->state >= SSL3_ST_SR_CLNT_HELLO_A)
+					)
+				))
+			{
+			s->s3->in_read_app_data=2;
+			return(-1);
+			}
+		else
+			{
+			al=SSL_AD_UNEXPECTED_MESSAGE;
+			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
+			goto f_err;
+			}
+		}
+	/* not reached */
+
+f_err:
+	ssl3_send_alert(s,SSL3_AL_FATAL,al);
+err:
+	return(-1);
+	}
+
+int ssl3_do_change_cipher_spec(SSL *s)
+	{
+	int i;
+#ifdef OPENSSL_NO_NEXTPROTONEG
+	const char *sender;
+	int slen;
+#endif
+
+	if (s->state & SSL_ST_ACCEPT)
+		i=SSL3_CHANGE_CIPHER_SERVER_READ;
+	else
+		i=SSL3_CHANGE_CIPHER_CLIENT_READ;
+
+	if (s->s3->tmp.key_block == NULL)
+		{
+		if (s->session == NULL) 
+			{
+			/* might happen if dtls1_read_bytes() calls this */
+			SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY);
+			return (0);
+			}
+
+		s->session->cipher=s->s3->tmp.new_cipher;
+		if (!s->method->ssl3_enc->setup_key_block(s)) return(0);
+		}
+
+	if (!s->method->ssl3_enc->change_cipher_state(s,i))
+		return(0);
+
+#ifdef OPENSSL_NO_NEXTPROTONEG
+	/* we have to record the message digest at
+	 * this point so we can get it before we read
+	 * the finished message */
+	if (s->state & SSL_ST_CONNECT)
+		{
+		sender=s->method->ssl3_enc->server_finished_label;
+		slen=s->method->ssl3_enc->server_finished_label_len;
+		}
+	else
+		{
+		sender=s->method->ssl3_enc->client_finished_label;
+		slen=s->method->ssl3_enc->client_finished_label_len;
+		}
+
+	s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
+		sender,slen,s->s3->tmp.peer_finish_md);
+#endif
+
+	return(1);
+	}
+
+int ssl3_send_alert(SSL *s, int level, int desc)
+	{
+	/* Map tls/ssl alert value to correct one */
+	desc=s->method->ssl3_enc->alert_value(desc);
+	if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION)
+		desc = SSL_AD_HANDSHAKE_FAILURE; /* SSL 3.0 does not have protocol_version alerts */
+	if (desc < 0) return -1;
+	/* If a fatal one, remove from cache */
+	if ((level == 2) && (s->session != NULL))
+		SSL_CTX_remove_session(s->ctx,s->session);
+
+	s->s3->alert_dispatch=1;
+	s->s3->send_alert[0]=level;
+	s->s3->send_alert[1]=desc;
+	if (s->s3->wbuf.left == 0) /* data still being written out? */
+		return s->method->ssl_dispatch_alert(s);
+	/* else data is still being written out, we will get written
+	 * some time in the future */
+	return -1;
+	}
+
+int ssl3_dispatch_alert(SSL *s)
+	{
+	int i,j;
+	void (*cb)(const SSL *ssl,int type,int val)=NULL;
+
+	s->s3->alert_dispatch=0;
+	i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2, 0);
+	if (i <= 0)
+		{
+		s->s3->alert_dispatch=1;
+		}
+	else
+		{
+		/* Alert sent to BIO.  If it is important, flush it now.
+		 * If the message does not get sent due to non-blocking IO,
+		 * we will not worry too much. */
+		if (s->s3->send_alert[0] == SSL3_AL_FATAL)
+			(void)BIO_flush(s->wbio);
+
+		if (s->msg_callback)
+			s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, 2, s, s->msg_callback_arg);
+
+		if (s->info_callback != NULL)
+			cb=s->info_callback;
+		else if (s->ctx->info_callback != NULL)
+			cb=s->ctx->info_callback;
+
+		if (cb != NULL)
+			{
+			j=(s->s3->send_alert[0]<<8)|s->s3->send_alert[1];
+			cb(s,SSL_CB_WRITE_ALERT,j);
+			}
+		}
+	return(i);
+	}
diff --git a/openssl/ssl/s3_srvr.c b/openssl/ssl/s3_srvr.c
new file mode 100644
index 0000000..41e597f
--- /dev/null
+++ b/openssl/ssl/s3_srvr.c
@@ -0,0 +1,3325 @@
+/* ssl/s3_srvr.c -*- mode:C; c-file-style: "eay" -*- */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * ECC cipher suite support in OpenSSL originally written by
+ * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#define REUSE_CIPHER_BUG
+#define NETSCAPE_HANG_BUG
+
+#include <stdio.h>
+#include "ssl_locl.h"
+#include "kssl_lcl.h"
+#include <openssl/buffer.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_KRB5
+#include <openssl/krb5_asn.h>
+#endif
+#include <openssl/md5.h>
+
+static const SSL_METHOD *ssl3_get_server_method(int ver);
+
+static const SSL_METHOD *ssl3_get_server_method(int ver)
+	{
+	if (ver == SSL3_VERSION)
+		return(SSLv3_server_method());
+	else
+		return(NULL);
+	}
+
+IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
+			ssl3_accept,
+			ssl_undefined_function,
+			ssl3_get_server_method)
+
+int ssl3_accept(SSL *s)
+	{
+	BUF_MEM *buf;
+	unsigned long alg_k,Time=(unsigned long)time(NULL);
+	void (*cb)(const SSL *ssl,int type,int val)=NULL;
+	int ret= -1;
+	int new_state,state,skip=0;
+
+	RAND_add(&Time,sizeof(Time),0);
+	ERR_clear_error();
+	clear_sys_error();
+
+	if (s->info_callback != NULL)
+		cb=s->info_callback;
+	else if (s->ctx->info_callback != NULL)
+		cb=s->ctx->info_callback;
+
+	/* init things to blank */
+	s->in_handshake++;
+	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
+
+	if (s->cert == NULL)
+		{
+		SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
+		return(-1);
+		}
+
+	for (;;)
+		{
+		state=s->state;
+
+		switch (s->state)
+			{
+		case SSL_ST_RENEGOTIATE:
+			s->new_session=1;
+			/* s->state=SSL_ST_ACCEPT; */
+
+		case SSL_ST_BEFORE:
+		case SSL_ST_ACCEPT:
+		case SSL_ST_BEFORE|SSL_ST_ACCEPT:
+		case SSL_ST_OK|SSL_ST_ACCEPT:
+
+			s->server=1;
+			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
+
+			if ((s->version>>8) != 3)
+				{
+				SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
+				return -1;
+				}
+			s->type=SSL_ST_ACCEPT;
+
+			if (s->init_buf == NULL)
+				{
+				if ((buf=BUF_MEM_new()) == NULL)
+					{
+					ret= -1;
+					goto end;
+					}
+				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
+					{
+					ret= -1;
+					goto end;
+					}
+				s->init_buf=buf;
+				}
+
+			if (!ssl3_setup_buffers(s))
+				{
+				ret= -1;
+				goto end;
+				}
+
+			s->init_num=0;
+			s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
+
+			if (s->state != SSL_ST_RENEGOTIATE)
+				{
+				/* Ok, we now need to push on a buffering BIO so that
+				 * the output is sent in a way that TCP likes :-)
+				 */
+				if (!ssl_init_wbio_buffer(s,1)) { ret= -1; goto end; }
+				
+				ssl3_init_finished_mac(s);
+				s->state=SSL3_ST_SR_CLNT_HELLO_A;
+				s->ctx->stats.sess_accept++;
+				}
+			else if (!s->s3->send_connection_binding &&
+				!(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+				{
+				/* Server attempting to renegotiate with
+				 * client that doesn't support secure
+				 * renegotiation.
+				 */
+				SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+				ret = -1;
+				goto end;
+				}
+			else
+				{
+				/* s->state == SSL_ST_RENEGOTIATE,
+				 * we will just send a HelloRequest */
+				s->ctx->stats.sess_accept_renegotiate++;
+				s->state=SSL3_ST_SW_HELLO_REQ_A;
+				}
+			break;
+
+		case SSL3_ST_SW_HELLO_REQ_A:
+		case SSL3_ST_SW_HELLO_REQ_B:
+
+			s->shutdown=0;
+			ret=ssl3_send_hello_request(s);
+			if (ret <= 0) goto end;
+			s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C;
+			s->state=SSL3_ST_SW_FLUSH;
+			s->init_num=0;
+
+			ssl3_init_finished_mac(s);
+			break;
+
+		case SSL3_ST_SW_HELLO_REQ_C:
+			s->state=SSL_ST_OK;
+			break;
+
+		case SSL3_ST_SR_CLNT_HELLO_A:
+		case SSL3_ST_SR_CLNT_HELLO_B:
+		case SSL3_ST_SR_CLNT_HELLO_C:
+
+			s->shutdown=0;
+			ret=ssl3_get_client_hello(s);
+			if (ret <= 0) goto end;
+			
+			s->new_session = 2;
+			s->state=SSL3_ST_SW_SRVR_HELLO_A;
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_SW_SRVR_HELLO_A:
+		case SSL3_ST_SW_SRVR_HELLO_B:
+			ret=ssl3_send_server_hello(s);
+			if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_TLSEXT
+			if (s->hit)
+				{
+				if (s->tlsext_ticket_expected)
+					s->state=SSL3_ST_SW_SESSION_TICKET_A;
+				else
+					s->state=SSL3_ST_SW_CHANGE_A;
+				}
+#else
+			if (s->hit)
+					s->state=SSL3_ST_SW_CHANGE_A;
+#endif
+			else
+				s->state=SSL3_ST_SW_CERT_A;
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_SW_CERT_A:
+		case SSL3_ST_SW_CERT_B:
+			/* Check if it is anon DH or anon ECDH, */
+			/* normal PSK or KRB5 */
+			if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
+				&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
+				&& !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
+				{
+				ret=ssl3_send_server_certificate(s);
+				if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_TLSEXT
+				if (s->tlsext_status_expected)
+					s->state=SSL3_ST_SW_CERT_STATUS_A;
+				else
+					s->state=SSL3_ST_SW_KEY_EXCH_A;
+				}
+			else
+				{
+				skip = 1;
+				s->state=SSL3_ST_SW_KEY_EXCH_A;
+				}
+#else
+				}
+			else
+				skip=1;
+
+			s->state=SSL3_ST_SW_KEY_EXCH_A;
+#endif
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_SW_KEY_EXCH_A:
+		case SSL3_ST_SW_KEY_EXCH_B:
+			alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+
+			/* clear this, it may get reset by
+			 * send_server_key_exchange */
+			if ((s->options & SSL_OP_EPHEMERAL_RSA)
+#ifndef OPENSSL_NO_KRB5
+				&& !(alg_k & SSL_kKRB5)
+#endif /* OPENSSL_NO_KRB5 */
+				)
+				/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
+				 * even when forbidden by protocol specs
+				 * (handshake may fail as clients are not required to
+				 * be able to handle this) */
+				s->s3->tmp.use_rsa_tmp=1;
+			else
+				s->s3->tmp.use_rsa_tmp=0;
+
+
+			/* only send if a DH key exchange, fortezza or
+			 * RSA but we have a sign only certificate
+			 *
+			 * PSK: may send PSK identity hints
+			 *
+			 * For ECC ciphersuites, we send a serverKeyExchange
+			 * message only if the cipher suite is either
+			 * ECDH-anon or ECDHE. In other cases, the
+			 * server certificate contains the server's
+			 * public key for key exchange.
+			 */
+			if (s->s3->tmp.use_rsa_tmp
+			/* PSK: send ServerKeyExchange if PSK identity
+			 * hint if provided */
+#ifndef OPENSSL_NO_PSK
+			    || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint)
+#endif
+			    || (alg_k & (SSL_kDHr|SSL_kDHd|SSL_kEDH))
+			    || (alg_k & SSL_kEECDH)
+			    || ((alg_k & SSL_kRSA)
+				&& (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
+				    || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
+					&& EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
+					)
+				    )
+				)
+			    )
+				{
+				ret=ssl3_send_server_key_exchange(s);
+				if (ret <= 0) goto end;
+				}
+			else
+				skip=1;
+
+			s->state=SSL3_ST_SW_CERT_REQ_A;
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_SW_CERT_REQ_A:
+		case SSL3_ST_SW_CERT_REQ_B:
+			if (/* don't request cert unless asked for it: */
+				!(s->verify_mode & SSL_VERIFY_PEER) ||
+				/* if SSL_VERIFY_CLIENT_ONCE is set,
+				 * don't request cert during re-negotiation: */
+				((s->session->peer != NULL) &&
+				 (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
+				/* never request cert in anonymous ciphersuites
+				 * (see section "Certificate request" in SSL 3 drafts
+				 * and in RFC 2246): */
+				((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
+				 /* ... except when the application insists on verification
+				  * (against the specs, but s3_clnt.c accepts this for SSL 3) */
+				 !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
+				 /* never request cert in Kerberos ciphersuites */
+				(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)
+				/* With normal PSK Certificates and
+				 * Certificate Requests are omitted */
+				|| (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
+				{
+				/* no cert request */
+				skip=1;
+				s->s3->tmp.cert_request=0;
+				s->state=SSL3_ST_SW_SRVR_DONE_A;
+				}
+			else
+				{
+				s->s3->tmp.cert_request=1;
+				ret=ssl3_send_certificate_request(s);
+				if (ret <= 0) goto end;
+#ifndef NETSCAPE_HANG_BUG
+				s->state=SSL3_ST_SW_SRVR_DONE_A;
+#else
+				s->state=SSL3_ST_SW_FLUSH;
+				s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
+#endif
+				s->init_num=0;
+				}
+			break;
+
+		case SSL3_ST_SW_SRVR_DONE_A:
+		case SSL3_ST_SW_SRVR_DONE_B:
+			ret=ssl3_send_server_done(s);
+			if (ret <= 0) goto end;
+			s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
+			s->state=SSL3_ST_SW_FLUSH;
+			s->init_num=0;
+			break;
+		
+		case SSL3_ST_SW_FLUSH:
+
+			/* This code originally checked to see if
+			 * any data was pending using BIO_CTRL_INFO
+			 * and then flushed. This caused problems
+			 * as documented in PR#1939. The proposed
+			 * fix doesn't completely resolve this issue
+			 * as buggy implementations of BIO_CTRL_PENDING
+			 * still exist. So instead we just flush
+			 * unconditionally.
+			 */
+
+			s->rwstate=SSL_WRITING;
+			if (BIO_flush(s->wbio) <= 0)
+				{
+				ret= -1;
+				goto end;
+				}
+			s->rwstate=SSL_NOTHING;
+
+			s->state=s->s3->tmp.next_state;
+			break;
+
+		case SSL3_ST_SR_CERT_A:
+		case SSL3_ST_SR_CERT_B:
+			/* Check for second client hello (MS SGC) */
+			ret = ssl3_check_client_hello(s);
+			if (ret <= 0)
+				goto end;
+			if (ret == 2)
+				s->state = SSL3_ST_SR_CLNT_HELLO_C;
+			else {
+				if (s->s3->tmp.cert_request)
+					{
+					ret=ssl3_get_client_certificate(s);
+					if (ret <= 0) goto end;
+					}
+				s->init_num=0;
+				s->state=SSL3_ST_SR_KEY_EXCH_A;
+			}
+			break;
+
+		case SSL3_ST_SR_KEY_EXCH_A:
+		case SSL3_ST_SR_KEY_EXCH_B:
+			ret=ssl3_get_client_key_exchange(s);
+			if (ret <= 0)
+				goto end;
+			if (ret == 2)
+				{
+				/* For the ECDH ciphersuites when
+				 * the client sends its ECDH pub key in
+				 * a certificate, the CertificateVerify
+				 * message is not sent.
+				 * Also for GOST ciphersuites when
+				 * the client uses its key from the certificate
+				 * for key exchange.
+				 */
+#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
+				s->state=SSL3_ST_SR_FINISHED_A;
+#else
+				if (s->s3->next_proto_neg_seen)
+					s->state=SSL3_ST_SR_NEXT_PROTO_A;
+				else
+					s->state=SSL3_ST_SR_FINISHED_A;
+#endif
+				s->init_num = 0;
+				}
+			else
+				{
+				int offset=0;
+				int dgst_num;
+
+				s->state=SSL3_ST_SR_CERT_VRFY_A;
+				s->init_num=0;
+
+				/* We need to get hashes here so if there is
+				 * a client cert, it can be verified
+				 * FIXME - digest processing for CertificateVerify
+				 * should be generalized. But it is next step
+				 */
+				if (s->s3->handshake_buffer)
+					if (!ssl3_digest_cached_records(s))
+						return -1;
+				for (dgst_num=0; dgst_num<SSL_MAX_DIGEST;dgst_num++)	
+					if (s->s3->handshake_dgst[dgst_num]) 
+						{
+						int dgst_size;
+
+						s->method->ssl3_enc->cert_verify_mac(s,EVP_MD_CTX_type(s->s3->handshake_dgst[dgst_num]),&(s->s3->tmp.cert_verify_md[offset]));
+						dgst_size=EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]);
+						if (dgst_size < 0)
+							{
+							ret = -1;
+							goto end;
+							}
+						offset+=dgst_size;
+						}		
+				}
+			break;
+
+		case SSL3_ST_SR_CERT_VRFY_A:
+		case SSL3_ST_SR_CERT_VRFY_B:
+
+			/* we should decide if we expected this one */
+			ret=ssl3_get_cert_verify(s);
+			if (ret <= 0) goto end;
+
+#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
+			s->state=SSL3_ST_SR_FINISHED_A;
+#else
+			if (s->s3->next_proto_neg_seen)
+				s->state=SSL3_ST_SR_NEXT_PROTO_A;
+			else
+				s->state=SSL3_ST_SR_FINISHED_A;
+#endif
+			s->init_num=0;
+			break;
+
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+		case SSL3_ST_SR_NEXT_PROTO_A:
+		case SSL3_ST_SR_NEXT_PROTO_B:
+			ret=ssl3_get_next_proto(s);
+			if (ret <= 0) goto end;
+			s->init_num = 0;
+			s->state=SSL3_ST_SR_FINISHED_A;
+			break;
+#endif
+
+		case SSL3_ST_SR_FINISHED_A:
+		case SSL3_ST_SR_FINISHED_B:
+			ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
+				SSL3_ST_SR_FINISHED_B);
+			if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_TLSEXT
+			if (s->tlsext_ticket_expected)
+				s->state=SSL3_ST_SW_SESSION_TICKET_A;
+			else if (s->hit)
+				s->state=SSL_ST_OK;
+#else
+			if (s->hit)
+				s->state=SSL_ST_OK;
+#endif
+			else
+				s->state=SSL3_ST_SW_CHANGE_A;
+			s->init_num=0;
+			break;
+
+#ifndef OPENSSL_NO_TLSEXT
+		case SSL3_ST_SW_SESSION_TICKET_A:
+		case SSL3_ST_SW_SESSION_TICKET_B:
+			ret=ssl3_send_newsession_ticket(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_SW_CHANGE_A;
+			s->init_num=0;
+			break;
+
+		case SSL3_ST_SW_CERT_STATUS_A:
+		case SSL3_ST_SW_CERT_STATUS_B:
+			ret=ssl3_send_cert_status(s);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_SW_KEY_EXCH_A;
+			s->init_num=0;
+			break;
+
+#endif
+
+		case SSL3_ST_SW_CHANGE_A:
+		case SSL3_ST_SW_CHANGE_B:
+
+			s->session->cipher=s->s3->tmp.new_cipher;
+			if (!s->method->ssl3_enc->setup_key_block(s))
+				{ ret= -1; goto end; }
+
+			ret=ssl3_send_change_cipher_spec(s,
+				SSL3_ST_SW_CHANGE_A,SSL3_ST_SW_CHANGE_B);
+
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_SW_FINISHED_A;
+			s->init_num=0;
+
+			if (!s->method->ssl3_enc->change_cipher_state(s,
+				SSL3_CHANGE_CIPHER_SERVER_WRITE))
+				{
+				ret= -1;
+				goto end;
+				}
+
+			break;
+
+		case SSL3_ST_SW_FINISHED_A:
+		case SSL3_ST_SW_FINISHED_B:
+			ret=ssl3_send_finished(s,
+				SSL3_ST_SW_FINISHED_A,SSL3_ST_SW_FINISHED_B,
+				s->method->ssl3_enc->server_finished_label,
+				s->method->ssl3_enc->server_finished_label_len);
+			if (ret <= 0) goto end;
+			s->state=SSL3_ST_SW_FLUSH;
+			if (s->hit)
+				{
+#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
+				s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
+#else
+				if (s->s3->next_proto_neg_seen)
+					s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A;
+				else
+					s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
+#endif
+				}
+			else
+				s->s3->tmp.next_state=SSL_ST_OK;
+			s->init_num=0;
+			break;
+
+		case SSL_ST_OK:
+			/* clean a few things up */
+			ssl3_cleanup_key_block(s);
+
+			BUF_MEM_free(s->init_buf);
+			s->init_buf=NULL;
+
+			/* remove buffering on output */
+			ssl_free_wbio_buffer(s);
+
+			s->init_num=0;
+
+			if (s->new_session == 2) /* skipped if we just sent a HelloRequest */
+				{
+				/* actually not necessarily a 'new' session unless
+				 * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */
+				
+				s->new_session=0;
+				
+				ssl_update_cache(s,SSL_SESS_CACHE_SERVER);
+				
+				s->ctx->stats.sess_accept_good++;
+				/* s->server=1; */
+				s->handshake_func=ssl3_accept;
+
+				if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
+				}
+			
+			ret = 1;
+			goto end;
+			/* break; */
+
+		default:
+			SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_UNKNOWN_STATE);
+			ret= -1;
+			goto end;
+			/* break; */
+			}
+		
+		if (!s->s3->tmp.reuse_message && !skip)
+			{
+			if (s->debug)
+				{
+				if ((ret=BIO_flush(s->wbio)) <= 0)
+					goto end;
+				}
+
+
+			if ((cb != NULL) && (s->state != state))
+				{
+				new_state=s->state;
+				s->state=state;
+				cb(s,SSL_CB_ACCEPT_LOOP,1);
+				s->state=new_state;
+				}
+			}
+		skip=0;
+		}
+end:
+	/* BIO_flush(s->wbio); */
+
+	s->in_handshake--;
+	if (cb != NULL)
+		cb(s,SSL_CB_ACCEPT_EXIT,ret);
+	return(ret);
+	}
+
+int ssl3_send_hello_request(SSL *s)
+	{
+	unsigned char *p;
+
+	if (s->state == SSL3_ST_SW_HELLO_REQ_A)
+		{
+		p=(unsigned char *)s->init_buf->data;
+		*(p++)=SSL3_MT_HELLO_REQUEST;
+		*(p++)=0;
+		*(p++)=0;
+		*(p++)=0;
+
+		s->state=SSL3_ST_SW_HELLO_REQ_B;
+		/* number of bytes to write */
+		s->init_num=4;
+		s->init_off=0;
+		}
+
+	/* SSL3_ST_SW_HELLO_REQ_B */
+	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
+	}
+
+int ssl3_check_client_hello(SSL *s)
+	{
+	int ok;
+	long n;
+
+	/* We only allow the client to restart the handshake once per
+	 * negotiation. */
+	if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE)
+		{
+		SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS);
+		return -1;
+		}
+
+	/* this function is called when we really expect a Certificate message,
+	 * so permit appropriate message length */
+	n=s->method->ssl_get_message(s,
+		SSL3_ST_SR_CERT_A,
+		SSL3_ST_SR_CERT_B,
+		-1,
+		s->max_cert_list,
+		&ok);
+	if (!ok) return((int)n);
+	s->s3->tmp.reuse_message = 1;
+	if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
+		{
+		/* Throw away what we have done so far in the current handshake,
+		 * which will now be aborted. (A full SSL_clear would be too much.) */
+#ifndef OPENSSL_NO_DH
+		if (s->s3->tmp.dh != NULL)
+			{
+			DH_free(s->s3->tmp.dh);
+			s->s3->tmp.dh = NULL;
+			}
+#endif
+#ifndef OPENSSL_NO_ECDH
+		if (s->s3->tmp.ecdh != NULL)
+			{
+			EC_KEY_free(s->s3->tmp.ecdh);
+			s->s3->tmp.ecdh = NULL;
+			}
+#endif
+		s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE;
+		return 2;
+		}
+	return 1;
+}
+
+int ssl3_get_client_hello(SSL *s)
+	{
+	int i,j,ok,al,ret= -1;
+	unsigned int cookie_len;
+	long n;
+	unsigned long id;
+	unsigned char *p,*d,*q;
+	SSL_CIPHER *c;
+#ifndef OPENSSL_NO_COMP
+	SSL_COMP *comp=NULL;
+#endif
+	STACK_OF(SSL_CIPHER) *ciphers=NULL;
+
+	/* We do this so that we will respond with our native type.
+	 * If we are TLSv1 and we get SSLv3, we will respond with TLSv1,
+	 * This down switching should be handled by a different method.
+	 * If we are SSLv3, we will respond with SSLv3, even if prompted with
+	 * TLSv1.
+	 */
+	if (s->state == SSL3_ST_SR_CLNT_HELLO_A)
+		{
+		s->state=SSL3_ST_SR_CLNT_HELLO_B;
+		}
+	s->first_packet=1;
+	n=s->method->ssl_get_message(s,
+		SSL3_ST_SR_CLNT_HELLO_B,
+		SSL3_ST_SR_CLNT_HELLO_C,
+		SSL3_MT_CLIENT_HELLO,
+		SSL3_RT_MAX_PLAIN_LENGTH,
+		&ok);
+
+	if (!ok) return((int)n);
+	s->first_packet=0;
+	d=p=(unsigned char *)s->init_msg;
+
+	/* use version from inside client hello, not from record header
+	 * (may differ: see RFC 2246, Appendix E, second paragraph) */
+	s->client_version=(((int)p[0])<<8)|(int)p[1];
+	p+=2;
+
+	if ((s->version == DTLS1_VERSION && s->client_version > s->version) ||
+	    (s->version != DTLS1_VERSION && s->client_version < s->version))
+		{
+		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER);
+		if ((s->client_version>>8) == SSL3_VERSION_MAJOR)
+			{
+			/* similar to ssl3_get_record, send alert using remote version number */
+			s->version = s->client_version;
+			}
+		al = SSL_AD_PROTOCOL_VERSION;
+		goto f_err;
+		}
+
+	/* If we require cookies and this ClientHello doesn't
+	 * contain one, just return since we do not want to
+	 * allocate any memory yet. So check cookie length...
+	 */
+	if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)
+		{
+		unsigned int session_length, cookie_length;
+		
+		session_length = *(p + SSL3_RANDOM_SIZE);
+		cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1);
+
+		if (cookie_length == 0)
+			return 1;
+		}
+
+	/* load the client random */
+	memcpy(s->s3->client_random,p,SSL3_RANDOM_SIZE);
+	p+=SSL3_RANDOM_SIZE;
+
+	/* get the session-id */
+	j= *(p++);
+
+	s->hit=0;
+	/* Versions before 0.9.7 always allow session reuse during renegotiation
+	 * (i.e. when s->new_session is true), option
+	 * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is new with 0.9.7.
+	 * Maybe this optional behaviour should always have been the default,
+	 * but we cannot safely change the default behaviour (or new applications
+	 * might be written that become totally unsecure when compiled with
+	 * an earlier library version)
+	 */
+	if ((s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)))
+		{
+	        if (!s->session_creation_enabled)
+			{
+			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
+			goto err;
+		}
+		if (!ssl_get_new_session(s,1))
+			goto err;
+		}
+	else
+		{
+		i=ssl_get_prev_session(s, p, j, d + n);
+		if (i == 1)
+			{ /* previous session */
+			s->hit=1;
+			}
+		else if (i == -1)
+			goto err;
+		else /* i == 0 */
+			{
+		        if (!s->session_creation_enabled)
+				{
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+				SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
+				goto err;
+				}
+			if (!ssl_get_new_session(s,1))
+				goto err;
+			}
+		}
+
+	p+=j;
+
+	if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
+		{
+		/* cookie stuff */
+		cookie_len = *(p++);
+
+		/* 
+		 * The ClientHello may contain a cookie even if the
+		 * HelloVerify message has not been sent--make sure that it
+		 * does not cause an overflow.
+		 */
+		if ( cookie_len > sizeof(s->d1->rcvd_cookie))
+			{
+			/* too much data */
+			al = SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);
+			goto f_err;
+			}
+
+		/* verify the cookie if appropriate option is set. */
+		if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) &&
+			cookie_len > 0)
+			{
+			memcpy(s->d1->rcvd_cookie, p, cookie_len);
+
+			if ( s->ctx->app_verify_cookie_cb != NULL)
+				{
+				if ( s->ctx->app_verify_cookie_cb(s, s->d1->rcvd_cookie,
+					cookie_len) == 0)
+					{
+					al=SSL_AD_HANDSHAKE_FAILURE;
+					SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, 
+						SSL_R_COOKIE_MISMATCH);
+					goto f_err;
+					}
+				/* else cookie verification succeeded */
+				}
+			else if ( memcmp(s->d1->rcvd_cookie, s->d1->cookie, 
+						  s->d1->cookie_len) != 0) /* default verification */
+				{
+					al=SSL_AD_HANDSHAKE_FAILURE;
+					SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, 
+						SSL_R_COOKIE_MISMATCH);
+					goto f_err;
+				}
+
+			ret = 2;
+			}
+
+		p += cookie_len;
+		}
+
+	n2s(p,i);
+	if ((i == 0) && (j != 0))
+		{
+		/* we need a cipher if we are not resuming a session */
+		al=SSL_AD_ILLEGAL_PARAMETER;
+		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_CIPHERS_SPECIFIED);
+		goto f_err;
+		}
+	if ((p+i) >= (d+n))
+		{
+		/* not enough data */
+		al=SSL_AD_DECODE_ERROR;
+		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH);
+		goto f_err;
+		}
+	if ((i > 0) && (ssl_bytes_to_cipher_list(s,p,i,&(ciphers))
+		== NULL))
+		{
+		goto err;
+		}
+	p+=i;
+
+	/* If it is a hit, check that the cipher is in the list */
+	if ((s->hit) && (i > 0))
+		{
+		j=0;
+		id=s->session->cipher->id;
+
+#ifdef CIPHER_DEBUG
+		printf("client sent %d ciphers\n",sk_num(ciphers));
+#endif
+		for (i=0; i<sk_SSL_CIPHER_num(ciphers); i++)
+			{
+			c=sk_SSL_CIPHER_value(ciphers,i);
+#ifdef CIPHER_DEBUG
+			printf("client [%2d of %2d]:%s\n",
+				i,sk_num(ciphers),SSL_CIPHER_get_name(c));
+#endif
+			if (c->id == id)
+				{
+				j=1;
+				break;
+				}
+			}
+/* Disabled because it can be used in a ciphersuite downgrade
+ * attack: CVE-2010-4180.
+ */
+#if 0
+		if (j == 0 && (s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_SSL_CIPHER_num(ciphers) == 1))
+			{
+			/* Special case as client bug workaround: the previously used cipher may
+			 * not be in the current list, the client instead might be trying to
+			 * continue using a cipher that before wasn't chosen due to server
+			 * preferences.  We'll have to reject the connection if the cipher is not
+			 * enabled, though. */
+			c = sk_SSL_CIPHER_value(ciphers, 0);
+			if (sk_SSL_CIPHER_find(SSL_get_ciphers(s), c) >= 0)
+				{
+				s->session->cipher = c;
+				j = 1;
+				}
+			}
+#endif
+		if (j == 0)
+			{
+			/* we need to have the cipher in the cipher
+			 * list if we are asked to reuse it */
+			al=SSL_AD_ILLEGAL_PARAMETER;
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_REQUIRED_CIPHER_MISSING);
+			goto f_err;
+			}
+		}
+
+	/* compression */
+	i= *(p++);
+	if ((p+i) > (d+n))
+		{
+		/* not enough data */
+		al=SSL_AD_DECODE_ERROR;
+		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH);
+		goto f_err;
+		}
+	q=p;
+	for (j=0; j<i; j++)
+		{
+		if (p[j] == 0) break;
+		}
+
+	p+=i;
+	if (j >= i)
+		{
+		/* no compress */
+		al=SSL_AD_DECODE_ERROR;
+		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_COMPRESSION_SPECIFIED);
+		goto f_err;
+		}
+
+#ifndef OPENSSL_NO_TLSEXT
+	/* TLS extensions*/
+	if (s->version >= SSL3_VERSION)
+		{
+		if (!ssl_parse_clienthello_tlsext(s,&p,d,n, &al))
+			{
+			/* 'al' set by ssl_parse_clienthello_tlsext */
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PARSE_TLSEXT);
+			goto f_err;
+			}
+		}
+		if (ssl_check_clienthello_tlsext(s) <= 0) {
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
+			goto err;
+		}
+
+	/* Check if we want to use external pre-shared secret for this
+	 * handshake for not reused session only. We need to generate
+	 * server_random before calling tls_session_secret_cb in order to allow
+	 * SessionTicket processing to use it in key derivation. */
+	{
+		unsigned long Time;
+		unsigned char *pos;
+		Time=(unsigned long)time(NULL);			/* Time */
+		pos=s->s3->server_random;
+		l2n(Time,pos);
+		if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0)
+			{
+			al=SSL_AD_INTERNAL_ERROR;
+			goto f_err;
+			}
+	}
+
+	if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb)
+		{
+		SSL_CIPHER *pref_cipher=NULL;
+
+		s->session->master_key_length=sizeof(s->session->master_key);
+		if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
+			ciphers, &pref_cipher, s->tls_session_secret_cb_arg))
+			{
+			s->hit=1;
+			s->session->ciphers=ciphers;
+			s->session->verify_result=X509_V_OK;
+
+			ciphers=NULL;
+
+			/* check if some cipher was preferred by call back */
+			pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
+			if (pref_cipher == NULL)
+				{
+				al=SSL_AD_HANDSHAKE_FAILURE;
+				SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);
+				goto f_err;
+				}
+
+			s->session->cipher=pref_cipher;
+
+			if (s->cipher_list)
+				sk_SSL_CIPHER_free(s->cipher_list);
+
+			if (s->cipher_list_by_id)
+				sk_SSL_CIPHER_free(s->cipher_list_by_id);
+
+			s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
+			s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
+			}
+		}
+#endif
+
+	/* Worst case, we will use the NULL compression, but if we have other
+	 * options, we will now look for them.  We have i-1 compression
+	 * algorithms from the client, starting at q. */
+	s->s3->tmp.new_compression=NULL;
+#ifndef OPENSSL_NO_COMP
+	/* This only happens if we have a cache hit */
+	if (s->session->compress_meth != 0)
+		{
+		int m, comp_id = s->session->compress_meth;
+		/* Perform sanity checks on resumed compression algorithm */
+		/* Can't disable compression */
+		if (s->options & SSL_OP_NO_COMPRESSION)
+			{
+			al=SSL_AD_INTERNAL_ERROR;
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INCONSISTENT_COMPRESSION);
+			goto f_err;
+			}
+		/* Look for resumed compression method */
+		for (m = 0; m < sk_SSL_COMP_num(s->ctx->comp_methods); m++)
+			{
+			comp=sk_SSL_COMP_value(s->ctx->comp_methods,m);
+			if (comp_id == comp->id)
+				{
+				s->s3->tmp.new_compression=comp;
+				break;
+				}
+			}
+		if (s->s3->tmp.new_compression == NULL)
+			{
+			al=SSL_AD_INTERNAL_ERROR;
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INVALID_COMPRESSION_ALGORITHM);
+			goto f_err;
+			}
+		/* Look for resumed method in compression list */
+		for (m = 0; m < i; m++)
+			{
+			if (q[m] == comp_id)
+				break;
+			}
+		if (m >= i)
+			{
+			al=SSL_AD_ILLEGAL_PARAMETER;
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING);
+			goto f_err;
+			}
+		}
+	else if (s->hit)
+		comp = NULL;
+	else if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods)
+		{ /* See if we have a match */
+		int m,nn,o,v,done=0;
+
+		nn=sk_SSL_COMP_num(s->ctx->comp_methods);
+		for (m=0; m<nn; m++)
+			{
+			comp=sk_SSL_COMP_value(s->ctx->comp_methods,m);
+			v=comp->id;
+			for (o=0; o<i; o++)
+				{
+				if (v == q[o])
+					{
+					done=1;
+					break;
+					}
+				}
+			if (done) break;
+			}
+		if (done)
+			s->s3->tmp.new_compression=comp;
+		else
+			comp=NULL;
+		}
+#else
+	/* If compression is disabled we'd better not try to resume a session
+	 * using compression.
+	 */
+	if (s->session->compress_meth != 0)
+		{
+		al=SSL_AD_INTERNAL_ERROR;
+		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INCONSISTENT_COMPRESSION);
+		goto f_err;
+		}
+#endif
+
+	/* Given s->session->ciphers and SSL_get_ciphers, we must
+	 * pick a cipher */
+
+	if (!s->hit)
+		{
+#ifdef OPENSSL_NO_COMP
+		s->session->compress_meth=0;
+#else
+		s->session->compress_meth=(comp == NULL)?0:comp->id;
+#endif
+		if (s->session->ciphers != NULL)
+			sk_SSL_CIPHER_free(s->session->ciphers);
+		s->session->ciphers=ciphers;
+		if (ciphers == NULL)
+			{
+			al=SSL_AD_ILLEGAL_PARAMETER;
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_CIPHERS_PASSED);
+			goto f_err;
+			}
+		ciphers=NULL;
+		c=ssl3_choose_cipher(s,s->session->ciphers,
+				     SSL_get_ciphers(s));
+
+		if (c == NULL)
+			{
+			al=SSL_AD_HANDSHAKE_FAILURE;
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);
+			goto f_err;
+			}
+		s->s3->tmp.new_cipher=c;
+		}
+	else
+		{
+		/* Session-id reuse */
+#ifdef REUSE_CIPHER_BUG
+		STACK_OF(SSL_CIPHER) *sk;
+		SSL_CIPHER *nc=NULL;
+		SSL_CIPHER *ec=NULL;
+
+		if (s->options & SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG)
+			{
+			sk=s->session->ciphers;
+			for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
+				{
+				c=sk_SSL_CIPHER_value(sk,i);
+				if (c->algorithm_enc & SSL_eNULL)
+					nc=c;
+				if (SSL_C_IS_EXPORT(c))
+					ec=c;
+				}
+			if (nc != NULL)
+				s->s3->tmp.new_cipher=nc;
+			else if (ec != NULL)
+				s->s3->tmp.new_cipher=ec;
+			else
+				s->s3->tmp.new_cipher=s->session->cipher;
+			}
+		else
+#endif
+		s->s3->tmp.new_cipher=s->session->cipher;
+		}
+
+	if (!ssl3_digest_cached_records(s))
+		goto f_err;
+	
+	/* we now have the following setup. 
+	 * client_random
+	 * cipher_list 		- our prefered list of ciphers
+	 * ciphers 		- the clients prefered list of ciphers
+	 * compression		- basically ignored right now
+	 * ssl version is set	- sslv3
+	 * s->session		- The ssl session has been setup.
+	 * s->hit		- session reuse flag
+	 * s->tmp.new_cipher	- the new cipher to use.
+	 */
+
+	if (ret < 0) ret=1;
+	if (0)
+		{
+f_err:
+		ssl3_send_alert(s,SSL3_AL_FATAL,al);
+		}
+err:
+	if (ciphers != NULL) sk_SSL_CIPHER_free(ciphers);
+	return(ret);
+	}
+
+int ssl3_send_server_hello(SSL *s)
+	{
+	unsigned char *buf;
+	unsigned char *p,*d;
+	int i,sl;
+	unsigned long l;
+#ifdef OPENSSL_NO_TLSEXT
+	unsigned long Time;
+#endif
+
+	if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
+		{
+		buf=(unsigned char *)s->init_buf->data;
+#ifdef OPENSSL_NO_TLSEXT
+		p=s->s3->server_random;
+		/* Generate server_random if it was not needed previously */
+		Time=(unsigned long)time(NULL);			/* Time */
+		l2n(Time,p);
+		if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
+			return -1;
+#endif
+		/* Do the message type and length last */
+		d=p= &(buf[4]);
+
+		*(p++)=s->version>>8;
+		*(p++)=s->version&0xff;
+
+		/* Random stuff */
+		memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
+		p+=SSL3_RANDOM_SIZE;
+
+		/* now in theory we have 3 options to sending back the
+		 * session id.  If it is a re-use, we send back the
+		 * old session-id, if it is a new session, we send
+		 * back the new session-id or we send back a 0 length
+		 * session-id if we want it to be single use.
+		 * Currently I will not implement the '0' length session-id
+		 * 12-Jan-98 - I'll now support the '0' length stuff.
+		 *
+		 * We also have an additional case where stateless session
+		 * resumption is successful: we always send back the old
+		 * session id. In this case s->hit is non zero: this can
+		 * only happen if stateless session resumption is succesful
+		 * if session caching is disabled so existing functionality
+		 * is unaffected.
+		 */
+		if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)
+			&& !s->hit)
+			s->session->session_id_length=0;
+
+		sl=s->session->session_id_length;
+		if (sl > (int)sizeof(s->session->session_id))
+			{
+			SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
+			return -1;
+			}
+		*(p++)=sl;
+		memcpy(p,s->session->session_id,sl);
+		p+=sl;
+
+		/* put the cipher */
+		i=ssl3_put_cipher_by_char(s->s3->tmp.new_cipher,p);
+		p+=i;
+
+		/* put the compression method */
+#ifdef OPENSSL_NO_COMP
+			*(p++)=0;
+#else
+		if (s->s3->tmp.new_compression == NULL)
+			*(p++)=0;
+		else
+			*(p++)=s->s3->tmp.new_compression->id;
+#endif
+#ifndef OPENSSL_NO_TLSEXT
+		if (ssl_prepare_serverhello_tlsext(s) <= 0)
+			{
+			SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT);
+			return -1;
+			}
+		if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
+			{
+			SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
+			return -1;
+			}
+#endif
+		/* do the header */
+		l=(p-d);
+		d=buf;
+		*(d++)=SSL3_MT_SERVER_HELLO;
+		l2n3(l,d);
+
+		s->state=SSL3_ST_SW_SRVR_HELLO_B;
+		/* number of bytes to write */
+		s->init_num=p-buf;
+		s->init_off=0;
+		}
+
+	/* SSL3_ST_SW_SRVR_HELLO_B */
+	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
+	}
+
+int ssl3_send_server_done(SSL *s)
+	{
+	unsigned char *p;
+
+	if (s->state == SSL3_ST_SW_SRVR_DONE_A)
+		{
+		p=(unsigned char *)s->init_buf->data;
+
+		/* do the header */
+		*(p++)=SSL3_MT_SERVER_DONE;
+		*(p++)=0;
+		*(p++)=0;
+		*(p++)=0;
+
+		s->state=SSL3_ST_SW_SRVR_DONE_B;
+		/* number of bytes to write */
+		s->init_num=4;
+		s->init_off=0;
+		}
+
+	/* SSL3_ST_SW_SRVR_DONE_B */
+	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
+	}
+
+int ssl3_send_server_key_exchange(SSL *s)
+	{
+#ifndef OPENSSL_NO_RSA
+	unsigned char *q;
+	int j,num;
+	RSA *rsa;
+	unsigned char md_buf[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
+	unsigned int u;
+#endif
+#ifndef OPENSSL_NO_DH
+	DH *dh=NULL,*dhp;
+#endif
+#ifndef OPENSSL_NO_ECDH
+	EC_KEY *ecdh=NULL, *ecdhp;
+	unsigned char *encodedPoint = NULL;
+	int encodedlen = 0;
+	int curve_id = 0;
+	BN_CTX *bn_ctx = NULL; 
+#endif
+	EVP_PKEY *pkey;
+	unsigned char *p,*d;
+	int al,i;
+	unsigned long type;
+	int n;
+	CERT *cert;
+	BIGNUM *r[4];
+	int nr[4],kn;
+	BUF_MEM *buf;
+	EVP_MD_CTX md_ctx;
+
+	EVP_MD_CTX_init(&md_ctx);
+	if (s->state == SSL3_ST_SW_KEY_EXCH_A)
+		{
+		type=s->s3->tmp.new_cipher->algorithm_mkey;
+		cert=s->cert;
+
+		buf=s->init_buf;
+
+		r[0]=r[1]=r[2]=r[3]=NULL;
+		n=0;
+#ifndef OPENSSL_NO_RSA
+		if (type & SSL_kRSA)
+			{
+			rsa=cert->rsa_tmp;
+			if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL))
+				{
+				rsa=s->cert->rsa_tmp_cb(s,
+				      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
+				      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
+				if(rsa == NULL)
+				{
+					al=SSL_AD_HANDSHAKE_FAILURE;
+					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_ERROR_GENERATING_TMP_RSA_KEY);
+					goto f_err;
+				}
+				RSA_up_ref(rsa);
+				cert->rsa_tmp=rsa;
+				}
+			if (rsa == NULL)
+				{
+				al=SSL_AD_HANDSHAKE_FAILURE;
+				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_KEY);
+				goto f_err;
+				}
+			r[0]=rsa->n;
+			r[1]=rsa->e;
+			s->s3->tmp.use_rsa_tmp=1;
+			}
+		else
+#endif
+#ifndef OPENSSL_NO_DH
+			if (type & SSL_kEDH)
+			{
+			dhp=cert->dh_tmp;
+			if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL))
+				dhp=s->cert->dh_tmp_cb(s,
+				      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
+				      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
+			if (dhp == NULL)
+				{
+				al=SSL_AD_HANDSHAKE_FAILURE;
+				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);
+				goto f_err;
+				}
+
+			if (s->s3->tmp.dh != NULL)
+				{
+				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+
+			if ((dh=DHparams_dup(dhp)) == NULL)
+				{
+				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
+				goto err;
+				}
+
+			s->s3->tmp.dh=dh;
+			if ((dhp->pub_key == NULL ||
+			     dhp->priv_key == NULL ||
+			     (s->options & SSL_OP_SINGLE_DH_USE)))
+				{
+				if(!DH_generate_key(dh))
+				    {
+				    SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
+					   ERR_R_DH_LIB);
+				    goto err;
+				    }
+				}
+			else
+				{
+				dh->pub_key=BN_dup(dhp->pub_key);
+				dh->priv_key=BN_dup(dhp->priv_key);
+				if ((dh->pub_key == NULL) ||
+					(dh->priv_key == NULL))
+					{
+					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
+					goto err;
+					}
+				}
+			r[0]=dh->p;
+			r[1]=dh->g;
+			r[2]=dh->pub_key;
+			}
+		else 
+#endif
+#ifndef OPENSSL_NO_ECDH
+			if (type & SSL_kEECDH)
+			{
+			const EC_GROUP *group;
+
+			ecdhp=cert->ecdh_tmp;
+			if ((ecdhp == NULL) && (s->cert->ecdh_tmp_cb != NULL))
+				{
+				ecdhp=s->cert->ecdh_tmp_cb(s,
+				      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
+				      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
+				}
+			if (ecdhp == NULL)
+				{
+				al=SSL_AD_HANDSHAKE_FAILURE;
+				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY);
+				goto f_err;
+				}
+
+			if (s->s3->tmp.ecdh != NULL)
+				{
+				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+
+			/* Duplicate the ECDH structure. */
+			if (ecdhp == NULL)
+				{
+				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
+				goto err;
+				}
+			if ((ecdh = EC_KEY_dup(ecdhp)) == NULL)
+				{
+				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
+				goto err;
+				}
+
+			s->s3->tmp.ecdh=ecdh;
+			if ((EC_KEY_get0_public_key(ecdh) == NULL) ||
+			    (EC_KEY_get0_private_key(ecdh) == NULL) ||
+			    (s->options & SSL_OP_SINGLE_ECDH_USE))
+				{
+				if(!EC_KEY_generate_key(ecdh))
+				    {
+				    SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
+				    goto err;
+				    }
+				}
+
+			if (((group = EC_KEY_get0_group(ecdh)) == NULL) ||
+			    (EC_KEY_get0_public_key(ecdh)  == NULL) ||
+			    (EC_KEY_get0_private_key(ecdh) == NULL))
+				{
+				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
+				goto err;
+				}
+
+			if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
+			    (EC_GROUP_get_degree(group) > 163)) 
+				{
+				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER);
+				goto err;
+				}
+
+			/* XXX: For now, we only support ephemeral ECDH
+			 * keys over named (not generic) curves. For 
+			 * supported named curves, curve_id is non-zero.
+			 */
+			if ((curve_id = 
+			    tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group)))
+			    == 0)
+				{
+				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
+				goto err;
+				}
+
+			/* Encode the public key.
+			 * First check the size of encoding and
+			 * allocate memory accordingly.
+			 */
+			encodedlen = EC_POINT_point2oct(group, 
+			    EC_KEY_get0_public_key(ecdh),
+			    POINT_CONVERSION_UNCOMPRESSED, 
+			    NULL, 0, NULL);
+
+			encodedPoint = (unsigned char *) 
+			    OPENSSL_malloc(encodedlen*sizeof(unsigned char)); 
+			bn_ctx = BN_CTX_new();
+			if ((encodedPoint == NULL) || (bn_ctx == NULL))
+				{
+				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+
+
+			encodedlen = EC_POINT_point2oct(group, 
+			    EC_KEY_get0_public_key(ecdh), 
+			    POINT_CONVERSION_UNCOMPRESSED, 
+			    encodedPoint, encodedlen, bn_ctx);
+
+			if (encodedlen == 0) 
+				{
+				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
+				goto err;
+				}
+
+			BN_CTX_free(bn_ctx);  bn_ctx=NULL;
+
+			/* XXX: For now, we only support named (not 
+			 * generic) curves in ECDH ephemeral key exchanges.
+			 * In this situation, we need four additional bytes
+			 * to encode the entire ServerECDHParams
+			 * structure. 
+			 */
+			n = 4 + encodedlen;
+
+			/* We'll generate the serverKeyExchange message
+			 * explicitly so we can set these to NULLs
+			 */
+			r[0]=NULL;
+			r[1]=NULL;
+			r[2]=NULL;
+			r[3]=NULL;
+			}
+		else 
+#endif /* !OPENSSL_NO_ECDH */
+#ifndef OPENSSL_NO_PSK
+			if (type & SSL_kPSK)
+				{
+				/* reserve size for record length and PSK identity hint*/
+				n+=2+strlen(s->ctx->psk_identity_hint);
+				}
+			else
+#endif /* !OPENSSL_NO_PSK */
+			{
+			al=SSL_AD_HANDSHAKE_FAILURE;
+			SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
+			goto f_err;
+			}
+		for (i=0; r[i] != NULL; i++)
+			{
+			nr[i]=BN_num_bytes(r[i]);
+			n+=2+nr[i];
+			}
+
+		if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
+			&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
+			{
+			if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher))
+				== NULL)
+				{
+				al=SSL_AD_DECODE_ERROR;
+				goto f_err;
+				}
+			kn=EVP_PKEY_size(pkey);
+			}
+		else
+			{
+			pkey=NULL;
+			kn=0;
+			}
+
+		if (!BUF_MEM_grow_clean(buf,n+4+kn))
+			{
+			SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF);
+			goto err;
+			}
+		d=(unsigned char *)s->init_buf->data;
+		p= &(d[4]);
+
+		for (i=0; r[i] != NULL; i++)
+			{
+			s2n(nr[i],p);
+			BN_bn2bin(r[i],p);
+			p+=nr[i];
+			}
+
+#ifndef OPENSSL_NO_ECDH
+		if (type & SSL_kEECDH) 
+			{
+			/* XXX: For now, we only support named (not generic) curves.
+			 * In this situation, the serverKeyExchange message has:
+			 * [1 byte CurveType], [2 byte CurveName]
+			 * [1 byte length of encoded point], followed by
+			 * the actual encoded point itself
+			 */
+			*p = NAMED_CURVE_TYPE;
+			p += 1;
+			*p = 0;
+			p += 1;
+			*p = curve_id;
+			p += 1;
+			*p = encodedlen;
+			p += 1;
+			memcpy((unsigned char*)p, 
+			    (unsigned char *)encodedPoint, 
+			    encodedlen);
+			OPENSSL_free(encodedPoint);
+			encodedPoint = NULL;
+			p += encodedlen;
+			}
+#endif
+
+#ifndef OPENSSL_NO_PSK
+		if (type & SSL_kPSK)
+			{
+			/* copy PSK identity hint */
+			s2n(strlen(s->ctx->psk_identity_hint), p); 
+			strncpy((char *)p, s->ctx->psk_identity_hint, strlen(s->ctx->psk_identity_hint));
+			p+=strlen(s->ctx->psk_identity_hint);
+			}
+#endif
+
+		/* not anonymous */
+		if (pkey != NULL)
+			{
+			/* n is the length of the params, they start at &(d[4])
+			 * and p points to the space at the end. */
+#ifndef OPENSSL_NO_RSA
+			if (pkey->type == EVP_PKEY_RSA)
+				{
+				q=md_buf;
+				j=0;
+				for (num=2; num > 0; num--)
+					{
+					EVP_DigestInit_ex(&md_ctx,(num == 2)
+						?s->ctx->md5:s->ctx->sha1, NULL);
+					EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
+					EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
+					EVP_DigestUpdate(&md_ctx,&(d[4]),n);
+					EVP_DigestFinal_ex(&md_ctx,q,
+						(unsigned int *)&i);
+					q+=i;
+					j+=i;
+					}
+				if (RSA_sign(NID_md5_sha1, md_buf, j,
+					&(p[2]), &u, pkey->pkey.rsa) <= 0)
+					{
+					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_RSA);
+					goto err;
+					}
+				s2n(u,p);
+				n+=u+2;
+				}
+			else
+#endif
+#if !defined(OPENSSL_NO_DSA)
+				if (pkey->type == EVP_PKEY_DSA)
+				{
+				/* lets do DSS */
+				EVP_SignInit_ex(&md_ctx,EVP_dss1(), NULL);
+				EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
+				EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
+				EVP_SignUpdate(&md_ctx,&(d[4]),n);
+				if (!EVP_SignFinal(&md_ctx,&(p[2]),
+					(unsigned int *)&i,pkey))
+					{
+					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_DSA);
+					goto err;
+					}
+				s2n(i,p);
+				n+=i+2;
+				}
+			else
+#endif
+#if !defined(OPENSSL_NO_ECDSA)
+				if (pkey->type == EVP_PKEY_EC)
+				{
+				/* let's do ECDSA */
+				EVP_SignInit_ex(&md_ctx,EVP_ecdsa(), NULL);
+				EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
+				EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
+				EVP_SignUpdate(&md_ctx,&(d[4]),n);
+				if (!EVP_SignFinal(&md_ctx,&(p[2]),
+					(unsigned int *)&i,pkey))
+					{
+					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_ECDSA);
+					goto err;
+					}
+				s2n(i,p);
+				n+=i+2;
+				}
+			else
+#endif
+				{
+				/* Is this error check actually needed? */
+				al=SSL_AD_HANDSHAKE_FAILURE;
+				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_PKEY_TYPE);
+				goto f_err;
+				}
+			}
+
+		*(d++)=SSL3_MT_SERVER_KEY_EXCHANGE;
+		l2n3(n,d);
+
+		/* we should now have things packed up, so lets send
+		 * it off */
+		s->init_num=n+4;
+		s->init_off=0;
+		}
+
+	s->state = SSL3_ST_SW_KEY_EXCH_B;
+	EVP_MD_CTX_cleanup(&md_ctx);
+	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
+f_err:
+	ssl3_send_alert(s,SSL3_AL_FATAL,al);
+err:
+#ifndef OPENSSL_NO_ECDH
+	if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
+	BN_CTX_free(bn_ctx);
+#endif
+	EVP_MD_CTX_cleanup(&md_ctx);
+	return(-1);
+	}
+
+int ssl3_send_certificate_request(SSL *s)
+	{
+	unsigned char *p,*d;
+	int i,j,nl,off,n;
+	STACK_OF(X509_NAME) *sk=NULL;
+	X509_NAME *name;
+	BUF_MEM *buf;
+
+	if (s->state == SSL3_ST_SW_CERT_REQ_A)
+		{
+		buf=s->init_buf;
+
+		d=p=(unsigned char *)&(buf->data[4]);
+
+		/* get the list of acceptable cert types */
+		p++;
+		n=ssl3_get_req_cert_type(s,p);
+		d[0]=n;
+		p+=n;
+		n++;
+
+		off=n;
+		p+=2;
+		n+=2;
+
+		sk=SSL_get_client_CA_list(s);
+		nl=0;
+		if (sk != NULL)
+			{
+			for (i=0; i<sk_X509_NAME_num(sk); i++)
+				{
+				name=sk_X509_NAME_value(sk,i);
+				j=i2d_X509_NAME(name,NULL);
+				if (!BUF_MEM_grow_clean(buf,4+n+j+2))
+					{
+					SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB);
+					goto err;
+					}
+				p=(unsigned char *)&(buf->data[4+n]);
+				if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG))
+					{
+					s2n(j,p);
+					i2d_X509_NAME(name,&p);
+					n+=2+j;
+					nl+=2+j;
+					}
+				else
+					{
+					d=p;
+					i2d_X509_NAME(name,&p);
+					j-=2; s2n(j,d); j+=2;
+					n+=j;
+					nl+=j;
+					}
+				}
+			}
+		/* else no CA names */
+		p=(unsigned char *)&(buf->data[4+off]);
+		s2n(nl,p);
+
+		d=(unsigned char *)buf->data;
+		*(d++)=SSL3_MT_CERTIFICATE_REQUEST;
+		l2n3(n,d);
+
+		/* we should now have things packed up, so lets send
+		 * it off */
+
+		s->init_num=n+4;
+		s->init_off=0;
+#ifdef NETSCAPE_HANG_BUG
+		p=(unsigned char *)s->init_buf->data + s->init_num;
+
+		/* do the header */
+		*(p++)=SSL3_MT_SERVER_DONE;
+		*(p++)=0;
+		*(p++)=0;
+		*(p++)=0;
+		s->init_num += 4;
+#endif
+
+		s->state = SSL3_ST_SW_CERT_REQ_B;
+		}
+
+	/* SSL3_ST_SW_CERT_REQ_B */
+	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
+err:
+	return(-1);
+	}
+
+int ssl3_get_client_key_exchange(SSL *s)
+	{
+	int i,al,ok;
+	long n;
+	unsigned long alg_k;
+	unsigned char *p;
+#ifndef OPENSSL_NO_RSA
+	RSA *rsa=NULL;
+	EVP_PKEY *pkey=NULL;
+#endif
+#ifndef OPENSSL_NO_DH
+	BIGNUM *pub=NULL;
+	DH *dh_srvr;
+#endif
+#ifndef OPENSSL_NO_KRB5
+	KSSL_ERR kssl_err;
+#endif /* OPENSSL_NO_KRB5 */
+
+#ifndef OPENSSL_NO_ECDH
+	EC_KEY *srvr_ecdh = NULL;
+	EVP_PKEY *clnt_pub_pkey = NULL;
+	EC_POINT *clnt_ecpoint = NULL;
+	BN_CTX *bn_ctx = NULL; 
+#endif
+
+	n=s->method->ssl_get_message(s,
+		SSL3_ST_SR_KEY_EXCH_A,
+		SSL3_ST_SR_KEY_EXCH_B,
+		SSL3_MT_CLIENT_KEY_EXCHANGE,
+		2048, /* ??? */
+		&ok);
+
+	if (!ok) return((int)n);
+	p=(unsigned char *)s->init_msg;
+
+	alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
+
+#ifndef OPENSSL_NO_RSA
+	if (alg_k & SSL_kRSA)
+		{
+		/* FIX THIS UP EAY EAY EAY EAY */
+		if (s->s3->tmp.use_rsa_tmp)
+			{
+			if ((s->cert != NULL) && (s->cert->rsa_tmp != NULL))
+				rsa=s->cert->rsa_tmp;
+			/* Don't do a callback because rsa_tmp should
+			 * be sent already */
+			if (rsa == NULL)
+				{
+				al=SSL_AD_HANDSHAKE_FAILURE;
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_PKEY);
+				goto f_err;
+
+				}
+			}
+		else
+			{
+			pkey=s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey;
+			if (	(pkey == NULL) ||
+				(pkey->type != EVP_PKEY_RSA) ||
+				(pkey->pkey.rsa == NULL))
+				{
+				al=SSL_AD_HANDSHAKE_FAILURE;
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_RSA_CERTIFICATE);
+				goto f_err;
+				}
+			rsa=pkey->pkey.rsa;
+			}
+
+		/* TLS and [incidentally] DTLS{0xFEFF} */
+		if (s->version > SSL3_VERSION && s->version != DTLS1_BAD_VER)
+			{
+			n2s(p,i);
+			if (n != i+2)
+				{
+				if (!(s->options & SSL_OP_TLS_D5_BUG))
+					{
+					SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
+					goto err;
+					}
+				else
+					p-=2;
+				}
+			else
+				n=i;
+			}
+
+		i=RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
+
+		al = -1;
+		
+		if (i != SSL_MAX_MASTER_KEY_LENGTH)
+			{
+			al=SSL_AD_DECODE_ERROR;
+			/* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); */
+			}
+
+		if ((al == -1) && !((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff))))
+			{
+			/* The premaster secret must contain the same version number as the
+			 * ClientHello to detect version rollback attacks (strangely, the
+			 * protocol does not offer such protection for DH ciphersuites).
+			 * However, buggy clients exist that send the negotiated protocol
+			 * version instead if the server does not support the requested
+			 * protocol version.
+			 * If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */
+			if (!((s->options & SSL_OP_TLS_ROLLBACK_BUG) &&
+				(p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff))))
+				{
+				al=SSL_AD_DECODE_ERROR;
+				/* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_PROTOCOL_VERSION_NUMBER); */
+
+				/* The Klima-Pokorny-Rosa extension of Bleichenbacher's attack
+				 * (http://eprint.iacr.org/2003/052/) exploits the version
+				 * number check as a "bad version oracle" -- an alert would
+				 * reveal that the plaintext corresponding to some ciphertext
+				 * made up by the adversary is properly formatted except
+				 * that the version number is wrong.  To avoid such attacks,
+				 * we should treat this just like any other decryption error. */
+				}
+			}
+
+		if (al != -1)
+			{
+			/* Some decryption failure -- use random value instead as countermeasure
+			 * against Bleichenbacher's attack on PKCS #1 v1.5 RSA padding
+			 * (see RFC 2246, section 7.4.7.1). */
+			ERR_clear_error();
+			i = SSL_MAX_MASTER_KEY_LENGTH;
+			p[0] = s->client_version >> 8;
+			p[1] = s->client_version & 0xff;
+			if (RAND_pseudo_bytes(p+2, i-2) <= 0) /* should be RAND_bytes, but we cannot work around a failure */
+				goto err;
+			}
+	
+		s->session->master_key_length=
+			s->method->ssl3_enc->generate_master_secret(s,
+				s->session->master_key,
+				p,i);
+		OPENSSL_cleanse(p,i);
+		}
+	else
+#endif
+#ifndef OPENSSL_NO_DH
+		if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
+		{
+		n2s(p,i);
+		if (n != i+2)
+			{
+			if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG))
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
+				goto err;
+				}
+			else
+				{
+				p-=2;
+				i=(int)n;
+				}
+			}
+
+		if (n == 0L) /* the parameters are in the cert */
+			{
+			al=SSL_AD_HANDSHAKE_FAILURE;
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_DECODE_DH_CERTS);
+			goto f_err;
+			}
+		else
+			{
+			if (s->s3->tmp.dh == NULL)
+				{
+				al=SSL_AD_HANDSHAKE_FAILURE;
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);
+				goto f_err;
+				}
+			else
+				dh_srvr=s->s3->tmp.dh;
+			}
+
+		pub=BN_bin2bn(p,i,NULL);
+		if (pub == NULL)
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BN_LIB);
+			goto err;
+			}
+
+		i=DH_compute_key(p,pub,dh_srvr);
+
+		if (i <= 0)
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
+			BN_clear_free(pub);
+			goto err;
+			}
+
+		DH_free(s->s3->tmp.dh);
+		s->s3->tmp.dh=NULL;
+
+		BN_clear_free(pub);
+		pub=NULL;
+		s->session->master_key_length=
+			s->method->ssl3_enc->generate_master_secret(s,
+				s->session->master_key,p,i);
+		OPENSSL_cleanse(p,i);
+		}
+	else
+#endif
+#ifndef OPENSSL_NO_KRB5
+	if (alg_k & SSL_kKRB5)
+		{
+		krb5_error_code		krb5rc;
+		krb5_data		enc_ticket;
+		krb5_data		authenticator;
+		krb5_data		enc_pms;
+		KSSL_CTX		*kssl_ctx = s->kssl_ctx;
+		EVP_CIPHER_CTX		ciph_ctx;
+		const EVP_CIPHER	*enc = NULL;
+		unsigned char		iv[EVP_MAX_IV_LENGTH];
+		unsigned char		pms[SSL_MAX_MASTER_KEY_LENGTH
+					       + EVP_MAX_BLOCK_LENGTH];
+		int		     padl, outl;
+		krb5_timestamp		authtime = 0;
+		krb5_ticket_times	ttimes;
+
+		EVP_CIPHER_CTX_init(&ciph_ctx);
+
+		if (!kssl_ctx)  kssl_ctx = kssl_ctx_new();
+
+		n2s(p,i);
+		enc_ticket.length = i;
+
+		if (n < (long)(enc_ticket.length + 6))
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				SSL_R_DATA_LENGTH_TOO_LONG);
+			goto err;
+			}
+
+		enc_ticket.data = (char *)p;
+		p+=enc_ticket.length;
+
+		n2s(p,i);
+		authenticator.length = i;
+
+		if (n < (long)(enc_ticket.length + authenticator.length + 6))
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				SSL_R_DATA_LENGTH_TOO_LONG);
+			goto err;
+			}
+
+		authenticator.data = (char *)p;
+		p+=authenticator.length;
+
+		n2s(p,i);
+		enc_pms.length = i;
+		enc_pms.data = (char *)p;
+		p+=enc_pms.length;
+
+		/* Note that the length is checked again below,
+		** after decryption
+		*/
+		if(enc_pms.length > sizeof pms)
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+			       SSL_R_DATA_LENGTH_TOO_LONG);
+			goto err;
+			}
+
+		if (n != (long)(enc_ticket.length + authenticator.length +
+						enc_pms.length + 6))
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				SSL_R_DATA_LENGTH_TOO_LONG);
+			goto err;
+			}
+
+		if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes,
+					&kssl_err)) != 0)
+			{
+#ifdef KSSL_DEBUG
+			printf("kssl_sget_tkt rtn %d [%d]\n",
+				krb5rc, kssl_err.reason);
+			if (kssl_err.text)
+				printf("kssl_err text= %s\n", kssl_err.text);
+#endif	/* KSSL_DEBUG */
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				kssl_err.reason);
+			goto err;
+			}
+
+		/*  Note: no authenticator is not considered an error,
+		**  but will return authtime == 0.
+		*/
+		if ((krb5rc = kssl_check_authent(kssl_ctx, &authenticator,
+					&authtime, &kssl_err)) != 0)
+			{
+#ifdef KSSL_DEBUG
+			printf("kssl_check_authent rtn %d [%d]\n",
+				krb5rc, kssl_err.reason);
+			if (kssl_err.text)
+				printf("kssl_err text= %s\n", kssl_err.text);
+#endif	/* KSSL_DEBUG */
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				kssl_err.reason);
+			goto err;
+			}
+
+		if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0)
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, krb5rc);
+			goto err;
+			}
+
+#ifdef KSSL_DEBUG
+		kssl_ctx_show(kssl_ctx);
+#endif	/* KSSL_DEBUG */
+
+		enc = kssl_map_enc(kssl_ctx->enctype);
+		if (enc == NULL)
+		    goto err;
+
+		memset(iv, 0, sizeof iv);	/* per RFC 1510 */
+
+		if (!EVP_DecryptInit_ex(&ciph_ctx,enc,NULL,kssl_ctx->key,iv))
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				SSL_R_DECRYPTION_FAILED);
+			goto err;
+			}
+		if (!EVP_DecryptUpdate(&ciph_ctx, pms,&outl,
+					(unsigned char *)enc_pms.data, enc_pms.length))
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				SSL_R_DECRYPTION_FAILED);
+			goto err;
+			}
+		if (outl > SSL_MAX_MASTER_KEY_LENGTH)
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				SSL_R_DATA_LENGTH_TOO_LONG);
+			goto err;
+			}
+		if (!EVP_DecryptFinal_ex(&ciph_ctx,&(pms[outl]),&padl))
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				SSL_R_DECRYPTION_FAILED);
+			goto err;
+			}
+		outl += padl;
+		if (outl > SSL_MAX_MASTER_KEY_LENGTH)
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				SSL_R_DATA_LENGTH_TOO_LONG);
+			goto err;
+			}
+		if (!((pms[0] == (s->client_version>>8)) && (pms[1] == (s->client_version & 0xff))))
+		    {
+		    /* The premaster secret must contain the same version number as the
+		     * ClientHello to detect version rollback attacks (strangely, the
+		     * protocol does not offer such protection for DH ciphersuites).
+		     * However, buggy clients exist that send random bytes instead of
+		     * the protocol version.
+		     * If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. 
+		     * (Perhaps we should have a separate BUG value for the Kerberos cipher)
+		     */
+		    if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG))
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+			       SSL_AD_DECODE_ERROR);
+			goto err;
+			}
+		    }
+
+		EVP_CIPHER_CTX_cleanup(&ciph_ctx);
+
+		s->session->master_key_length=
+			s->method->ssl3_enc->generate_master_secret(s,
+				s->session->master_key, pms, outl);
+
+		if (kssl_ctx->client_princ)
+			{
+			size_t len = strlen(kssl_ctx->client_princ);
+			if ( len < SSL_MAX_KRB5_PRINCIPAL_LENGTH ) 
+				{
+				s->session->krb5_client_princ_len = len;
+				memcpy(s->session->krb5_client_princ,kssl_ctx->client_princ,len);
+				}
+			}
+
+
+		/*  Was doing kssl_ctx_free() here,
+		**  but it caused problems for apache.
+		**  kssl_ctx = kssl_ctx_free(kssl_ctx);
+		**  if (s->kssl_ctx)  s->kssl_ctx = NULL;
+		*/
+		}
+	else
+#endif	/* OPENSSL_NO_KRB5 */
+
+#ifndef OPENSSL_NO_ECDH
+		if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe))
+		{
+		int ret = 1;
+		int field_size = 0;
+		const EC_KEY   *tkey;
+		const EC_GROUP *group;
+		const BIGNUM *priv_key;
+
+		/* initialize structures for server's ECDH key pair */
+		if ((srvr_ecdh = EC_KEY_new()) == NULL) 
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+			    ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+
+		/* Let's get server private key and group information */
+		if (alg_k & (SSL_kECDHr|SSL_kECDHe))
+			{ 
+			/* use the certificate */
+			tkey = s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec;
+			}
+		else
+			{
+			/* use the ephermeral values we saved when
+			 * generating the ServerKeyExchange msg.
+			 */
+			tkey = s->s3->tmp.ecdh;
+			}
+
+		group    = EC_KEY_get0_group(tkey);
+		priv_key = EC_KEY_get0_private_key(tkey);
+
+		if (!EC_KEY_set_group(srvr_ecdh, group) ||
+		    !EC_KEY_set_private_key(srvr_ecdh, priv_key))
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+			       ERR_R_EC_LIB);
+			goto err;
+			}
+
+		/* Let's get client's public key */
+		if ((clnt_ecpoint = EC_POINT_new(group)) == NULL)
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+			    ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+
+		if (n == 0L) 
+			{
+			/* Client Publickey was in Client Certificate */
+
+			 if (alg_k & SSL_kEECDH)
+				 {
+				 al=SSL_AD_HANDSHAKE_FAILURE;
+				 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY);
+				 goto f_err;
+				 }
+			if (((clnt_pub_pkey=X509_get_pubkey(s->session->peer))
+			    == NULL) || 
+			    (clnt_pub_pkey->type != EVP_PKEY_EC))
+				{
+				/* XXX: For now, we do not support client
+				 * authentication using ECDH certificates
+				 * so this branch (n == 0L) of the code is
+				 * never executed. When that support is
+				 * added, we ought to ensure the key 
+				 * received in the certificate is 
+				 * authorized for key agreement.
+				 * ECDH_compute_key implicitly checks that
+				 * the two ECDH shares are for the same
+				 * group.
+				 */
+			   	al=SSL_AD_HANDSHAKE_FAILURE;
+			   	SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				    SSL_R_UNABLE_TO_DECODE_ECDH_CERTS);
+			   	goto f_err;
+			   	}
+
+			if (EC_POINT_copy(clnt_ecpoint,
+			    EC_KEY_get0_public_key(clnt_pub_pkey->pkey.ec)) == 0)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+					ERR_R_EC_LIB);
+				goto err;
+				}
+			ret = 2; /* Skip certificate verify processing */
+			}
+		else
+			{
+			/* Get client's public key from encoded point
+			 * in the ClientKeyExchange message.
+			 */
+			if ((bn_ctx = BN_CTX_new()) == NULL)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				    ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+
+			/* Get encoded point length */
+			i = *p; 
+			p += 1;
+			if (n != 1 + i)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				    ERR_R_EC_LIB);
+				goto err;
+				}
+			if (EC_POINT_oct2point(group, 
+			    clnt_ecpoint, p, i, bn_ctx) == 0)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				    ERR_R_EC_LIB);
+				goto err;
+				}
+			/* p is pointing to somewhere in the buffer
+			 * currently, so set it to the start 
+			 */ 
+			p=(unsigned char *)s->init_buf->data;
+			}
+
+		/* Compute the shared pre-master secret */
+		field_size = EC_GROUP_get_degree(group);
+		if (field_size <= 0)
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, 
+			       ERR_R_ECDH_LIB);
+			goto err;
+			}
+		i = ECDH_compute_key(p, (field_size+7)/8, clnt_ecpoint, srvr_ecdh, NULL);
+		if (i <= 0)
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+			    ERR_R_ECDH_LIB);
+			goto err;
+			}
+
+		EVP_PKEY_free(clnt_pub_pkey);
+		EC_POINT_free(clnt_ecpoint);
+		EC_KEY_free(srvr_ecdh);
+		BN_CTX_free(bn_ctx);
+		EC_KEY_free(s->s3->tmp.ecdh);
+		s->s3->tmp.ecdh = NULL; 
+
+		/* Compute the master secret */
+		s->session->master_key_length = s->method->ssl3_enc-> \
+		    generate_master_secret(s, s->session->master_key, p, i);
+		
+		OPENSSL_cleanse(p, i);
+		return (ret);
+		}
+	else
+#endif
+#ifndef OPENSSL_NO_PSK
+		if (alg_k & SSL_kPSK)
+			{
+			unsigned char *t = NULL;
+			unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4];
+			unsigned int pre_ms_len = 0, psk_len = 0;
+			int psk_err = 1;
+			char tmp_id[PSK_MAX_IDENTITY_LEN+1];
+
+			al=SSL_AD_HANDSHAKE_FAILURE;
+
+			n2s(p,i);
+			if (n != i+2)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+					SSL_R_LENGTH_MISMATCH);
+				goto psk_err;
+				}
+			if (i > PSK_MAX_IDENTITY_LEN)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+					SSL_R_DATA_LENGTH_TOO_LONG);
+				goto psk_err;
+				}
+			if (s->psk_server_callback == NULL)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				       SSL_R_PSK_NO_SERVER_CB);
+				goto psk_err;
+				}
+
+			/* Create guaranteed NULL-terminated identity
+			 * string for the callback */
+			memcpy(tmp_id, p, i);
+			memset(tmp_id+i, 0, PSK_MAX_IDENTITY_LEN+1-i);
+			psk_len = s->psk_server_callback(s, tmp_id,
+				psk_or_pre_ms, sizeof(psk_or_pre_ms));
+			OPENSSL_cleanse(tmp_id, PSK_MAX_IDENTITY_LEN+1);
+
+			if (psk_len > PSK_MAX_PSK_LEN)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+					ERR_R_INTERNAL_ERROR);
+				goto psk_err;
+				}
+			else if (psk_len == 0)
+				{
+				/* PSK related to the given identity not found */
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				       SSL_R_PSK_IDENTITY_NOT_FOUND);
+				al=SSL_AD_UNKNOWN_PSK_IDENTITY;
+				goto psk_err;
+				}
+
+			/* create PSK pre_master_secret */
+			pre_ms_len=2+psk_len+2+psk_len;
+			t = psk_or_pre_ms;
+			memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len);
+			s2n(psk_len, t);
+			memset(t, 0, psk_len);
+			t+=psk_len;
+			s2n(psk_len, t);
+
+			if (s->session->psk_identity != NULL)
+				OPENSSL_free(s->session->psk_identity);
+			s->session->psk_identity = BUF_strdup((char *)p);
+			if (s->session->psk_identity == NULL)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+					ERR_R_MALLOC_FAILURE);
+				goto psk_err;
+				}
+
+			if (s->session->psk_identity_hint != NULL)
+				OPENSSL_free(s->session->psk_identity_hint);
+			s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint);
+			if (s->ctx->psk_identity_hint != NULL &&
+				s->session->psk_identity_hint == NULL)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+					ERR_R_MALLOC_FAILURE);
+				goto psk_err;
+				}
+
+			s->session->master_key_length=
+				s->method->ssl3_enc->generate_master_secret(s,
+					s->session->master_key, psk_or_pre_ms, pre_ms_len);
+			psk_err = 0;
+		psk_err:
+			OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
+			if (psk_err != 0)
+				goto f_err;
+			}
+		else
+#endif
+		if (alg_k & SSL_kGOST) 
+			{
+			int ret = 0;
+			EVP_PKEY_CTX *pkey_ctx;
+			EVP_PKEY *client_pub_pkey = NULL, *pk = NULL;
+			unsigned char premaster_secret[32], *start;
+			size_t outlen=32, inlen;
+			unsigned long alg_a;
+
+			/* Get our certificate private key*/
+			alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+			if (alg_a & SSL_aGOST94)
+				pk = s->cert->pkeys[SSL_PKEY_GOST94].privatekey;
+			else if (alg_a & SSL_aGOST01)
+				pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey;
+
+			pkey_ctx = EVP_PKEY_CTX_new(pk,NULL);
+			EVP_PKEY_decrypt_init(pkey_ctx);
+			/* If client certificate is present and is of the same type, maybe
+			 * use it for key exchange.  Don't mind errors from
+			 * EVP_PKEY_derive_set_peer, because it is completely valid to use
+			 * a client certificate for authorization only. */
+			client_pub_pkey = X509_get_pubkey(s->session->peer);
+			if (client_pub_pkey)
+				{
+				if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0)
+					ERR_clear_error();
+				}
+			/* Decrypt session key */
+			if ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED))) 
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
+				goto gerr;
+				}
+			if (p[1] == 0x81)
+				{
+				start = p+3;
+				inlen = p[2];
+				}
+			else if (p[1] < 0x80)
+				{
+				start = p+2;
+				inlen = p[1];
+				}
+			else
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
+				goto gerr;
+				}
+			if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0) 
+
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
+				goto gerr;
+				}
+			/* Generate master secret */
+			s->session->master_key_length=
+				s->method->ssl3_enc->generate_master_secret(s,
+					s->session->master_key,premaster_secret,32);
+			/* Check if pubkey from client certificate was used */
+			if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0)
+				ret = 2;
+			else
+				ret = 1;
+		gerr:
+			EVP_PKEY_free(client_pub_pkey);
+			EVP_PKEY_CTX_free(pkey_ctx);
+			if (ret)
+				return ret;
+			else
+				goto err;
+			}
+		else
+		{
+		al=SSL_AD_HANDSHAKE_FAILURE;
+		SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				SSL_R_UNKNOWN_CIPHER_TYPE);
+		goto f_err;
+		}
+
+	return(1);
+f_err:
+	ssl3_send_alert(s,SSL3_AL_FATAL,al);
+#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH)
+err:
+#endif
+#ifndef OPENSSL_NO_ECDH
+	EVP_PKEY_free(clnt_pub_pkey);
+	EC_POINT_free(clnt_ecpoint);
+	if (srvr_ecdh != NULL) 
+		EC_KEY_free(srvr_ecdh);
+	BN_CTX_free(bn_ctx);
+#endif
+	return(-1);
+	}
+
+int ssl3_get_cert_verify(SSL *s)
+	{
+	EVP_PKEY *pkey=NULL;
+	unsigned char *p;
+	int al,ok,ret=0;
+	long n;
+	int type=0,i,j;
+	X509 *peer;
+
+	n=s->method->ssl_get_message(s,
+		SSL3_ST_SR_CERT_VRFY_A,
+		SSL3_ST_SR_CERT_VRFY_B,
+		-1,
+		514, /* 514? */
+		&ok);
+
+	if (!ok) return((int)n);
+
+	if (s->session->peer != NULL)
+		{
+		peer=s->session->peer;
+		pkey=X509_get_pubkey(peer);
+		type=X509_certificate_type(peer,pkey);
+		}
+	else
+		{
+		peer=NULL;
+		pkey=NULL;
+		}
+
+	if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY)
+		{
+		s->s3->tmp.reuse_message=1;
+		if ((peer != NULL) && (type | EVP_PKT_SIGN))
+			{
+			al=SSL_AD_UNEXPECTED_MESSAGE;
+			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE);
+			goto f_err;
+			}
+		ret=1;
+		goto end;
+		}
+
+	if (peer == NULL)
+		{
+		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_NO_CLIENT_CERT_RECEIVED);
+		al=SSL_AD_UNEXPECTED_MESSAGE;
+		goto f_err;
+		}
+
+	if (!(type & EVP_PKT_SIGN))
+		{
+		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE);
+		al=SSL_AD_ILLEGAL_PARAMETER;
+		goto f_err;
+		}
+
+	if (s->s3->change_cipher_spec)
+		{
+		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_CCS_RECEIVED_EARLY);
+		al=SSL_AD_UNEXPECTED_MESSAGE;
+		goto f_err;
+		}
+
+	/* we now have a signature that we need to verify */
+	p=(unsigned char *)s->init_msg;
+	/* Check for broken implementations of GOST ciphersuites */
+	/* If key is GOST and n is exactly 64, it is bare
+	 * signature without length field */
+	if (n==64 && (pkey->type==NID_id_GostR3410_94 ||
+		pkey->type == NID_id_GostR3410_2001) )
+		{
+		i=64;
+		} 
+	else 
+		{	
+		n2s(p,i);
+		n-=2;
+		if (i > n)
+			{
+			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_LENGTH_MISMATCH);
+			al=SSL_AD_DECODE_ERROR;
+			goto f_err;
+			}
+    	}
+	j=EVP_PKEY_size(pkey);
+	if ((i > j) || (n > j) || (n <= 0))
+		{
+		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_WRONG_SIGNATURE_SIZE);
+		al=SSL_AD_DECODE_ERROR;
+		goto f_err;
+		}
+
+#ifndef OPENSSL_NO_RSA 
+	if (pkey->type == EVP_PKEY_RSA)
+		{
+		i=RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md,
+			MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH, p, i, 
+							pkey->pkey.rsa);
+		if (i < 0)
+			{
+			al=SSL_AD_DECRYPT_ERROR;
+			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_RSA_DECRYPT);
+			goto f_err;
+			}
+		if (i == 0)
+			{
+			al=SSL_AD_DECRYPT_ERROR;
+			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_RSA_SIGNATURE);
+			goto f_err;
+			}
+		}
+	else
+#endif
+#ifndef OPENSSL_NO_DSA
+		if (pkey->type == EVP_PKEY_DSA)
+		{
+		j=DSA_verify(pkey->save_type,
+			&(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
+			SHA_DIGEST_LENGTH,p,i,pkey->pkey.dsa);
+		if (j <= 0)
+			{
+			/* bad signature */
+			al=SSL_AD_DECRYPT_ERROR;
+			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_DSA_SIGNATURE);
+			goto f_err;
+			}
+		}
+	else
+#endif
+#ifndef OPENSSL_NO_ECDSA
+		if (pkey->type == EVP_PKEY_EC)
+		{
+		j=ECDSA_verify(pkey->save_type,
+			&(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
+			SHA_DIGEST_LENGTH,p,i,pkey->pkey.ec);
+		if (j <= 0)
+			{
+			/* bad signature */
+			al=SSL_AD_DECRYPT_ERROR;
+			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,
+			    SSL_R_BAD_ECDSA_SIGNATURE);
+			goto f_err;
+			}
+		}
+	else
+#endif
+	if (pkey->type == NID_id_GostR3410_94 || pkey->type == NID_id_GostR3410_2001)
+		{   unsigned char signature[64];
+			int idx;
+			EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey,NULL);
+			EVP_PKEY_verify_init(pctx);
+			if (i!=64) {
+				fprintf(stderr,"GOST signature length is %d",i);
+			}	
+			for (idx=0;idx<64;idx++) {
+				signature[63-idx]=p[idx];
+			}	
+			j=EVP_PKEY_verify(pctx,signature,64,s->s3->tmp.cert_verify_md,32);
+			EVP_PKEY_CTX_free(pctx);
+			if (j<=0) 
+				{
+				al=SSL_AD_DECRYPT_ERROR;
+				SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,
+					SSL_R_BAD_ECDSA_SIGNATURE);
+				goto f_err;
+				}	
+		}
+	else	
+		{
+		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,ERR_R_INTERNAL_ERROR);
+		al=SSL_AD_UNSUPPORTED_CERTIFICATE;
+		goto f_err;
+		}
+
+
+	ret=1;
+	if (0)
+		{
+f_err:
+		ssl3_send_alert(s,SSL3_AL_FATAL,al);
+		}
+end:
+	EVP_PKEY_free(pkey);
+	return(ret);
+	}
+
+int ssl3_get_client_certificate(SSL *s)
+	{
+	int i,ok,al,ret= -1;
+	X509 *x=NULL;
+	unsigned long l,nc,llen,n;
+	const unsigned char *p,*q;
+	unsigned char *d;
+	STACK_OF(X509) *sk=NULL;
+
+	n=s->method->ssl_get_message(s,
+		SSL3_ST_SR_CERT_A,
+		SSL3_ST_SR_CERT_B,
+		-1,
+		s->max_cert_list,
+		&ok);
+
+	if (!ok) return((int)n);
+
+	if	(s->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE)
+		{
+		if (	(s->verify_mode & SSL_VERIFY_PEER) &&
+			(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT))
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
+			al=SSL_AD_HANDSHAKE_FAILURE;
+			goto f_err;
+			}
+		/* If tls asked for a client cert, the client must return a 0 list */
+		if ((s->version > SSL3_VERSION) && s->s3->tmp.cert_request)
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST);
+			al=SSL_AD_UNEXPECTED_MESSAGE;
+			goto f_err;
+			}
+		s->s3->tmp.reuse_message=1;
+		return(1);
+		}
+
+	if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE)
+		{
+		al=SSL_AD_UNEXPECTED_MESSAGE;
+		SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_WRONG_MESSAGE_TYPE);
+		goto f_err;
+		}
+	p=d=(unsigned char *)s->init_msg;
+
+	if ((sk=sk_X509_new_null()) == NULL)
+		{
+		SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	n2l3(p,llen);
+	if (llen+3 != n)
+		{
+		al=SSL_AD_DECODE_ERROR;
+		SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_LENGTH_MISMATCH);
+		goto f_err;
+		}
+	for (nc=0; nc<llen; )
+		{
+		n2l3(p,l);
+		if ((l+nc+3) > llen)
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH);
+			goto f_err;
+			}
+
+		q=p;
+		x=d2i_X509(NULL,&p,l);
+		if (x == NULL)
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,ERR_R_ASN1_LIB);
+			goto err;
+			}
+		if (p != (q+l))
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH);
+			goto f_err;
+			}
+		if (!sk_X509_push(sk,x))
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		x=NULL;
+		nc+=l+3;
+		}
+
+	if (sk_X509_num(sk) <= 0)
+		{
+		/* TLS does not mind 0 certs returned */
+		if (s->version == SSL3_VERSION)
+			{
+			al=SSL_AD_HANDSHAKE_FAILURE;
+			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATES_RETURNED);
+			goto f_err;
+			}
+		/* Fail for TLS only if we required a certificate */
+		else if ((s->verify_mode & SSL_VERIFY_PEER) &&
+			 (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT))
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
+			al=SSL_AD_HANDSHAKE_FAILURE;
+			goto f_err;
+			}
+		}
+	else
+		{
+		i=ssl_verify_cert_chain(s,sk);
+		if (i <= 0)
+			{
+			al=ssl_verify_alarm_type(s->verify_result);
+			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATE_RETURNED);
+			goto f_err;
+			}
+		}
+
+	if (s->session->peer != NULL) /* This should not be needed */
+		X509_free(s->session->peer);
+	s->session->peer=sk_X509_shift(sk);
+	s->session->verify_result = s->verify_result;
+
+	/* With the current implementation, sess_cert will always be NULL
+	 * when we arrive here. */
+	if (s->session->sess_cert == NULL)
+		{
+		s->session->sess_cert = ssl_sess_cert_new();
+		if (s->session->sess_cert == NULL)
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+	if (s->session->sess_cert->cert_chain != NULL)
+		sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free);
+	s->session->sess_cert->cert_chain=sk;
+	/* Inconsistency alert: cert_chain does *not* include the
+	 * peer's own certificate, while we do include it in s3_clnt.c */
+
+	sk=NULL;
+
+	ret=1;
+	if (0)
+		{
+f_err:
+		ssl3_send_alert(s,SSL3_AL_FATAL,al);
+		}
+err:
+	if (x != NULL) X509_free(x);
+	if (sk != NULL) sk_X509_pop_free(sk,X509_free);
+	return(ret);
+	}
+
+int ssl3_send_server_certificate(SSL *s)
+	{
+	unsigned long l;
+	X509 *x;
+
+	if (s->state == SSL3_ST_SW_CERT_A)
+		{
+		x=ssl_get_server_send_cert(s);
+		if (x == NULL)
+			{
+			/* VRS: allow null cert if auth == KRB5 */
+			if ((s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5) ||
+			    (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5))
+				{
+				SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
+				return(0);
+				}
+			}
+
+		l=ssl3_output_cert_chain(s,x);
+		s->state=SSL3_ST_SW_CERT_B;
+		s->init_num=(int)l;
+		s->init_off=0;
+		}
+
+	/* SSL3_ST_SW_CERT_B */
+	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
+	}
+#ifndef OPENSSL_NO_TLSEXT
+int ssl3_send_newsession_ticket(SSL *s)
+	{
+	if (s->state == SSL3_ST_SW_SESSION_TICKET_A)
+		{
+		unsigned char *p, *senc, *macstart;
+		int len, slen;
+		unsigned int hlen;
+		EVP_CIPHER_CTX ctx;
+		HMAC_CTX hctx;
+		SSL_CTX *tctx = s->initial_ctx;
+		unsigned char iv[EVP_MAX_IV_LENGTH];
+		unsigned char key_name[16];
+
+		/* get session encoding length */
+		slen = i2d_SSL_SESSION(s->session, NULL);
+		/* Some length values are 16 bits, so forget it if session is
+ 		 * too long
+ 		 */
+		if (slen > 0xFF00)
+			return -1;
+		/* Grow buffer if need be: the length calculation is as
+ 		 * follows 1 (size of message name) + 3 (message length
+ 		 * bytes) + 4 (ticket lifetime hint) + 2 (ticket length) +
+ 		 * 16 (key name) + max_iv_len (iv length) +
+ 		 * session_length + max_enc_block_size (max encrypted session
+ 		 * length) + max_md_size (HMAC).
+ 		 */
+		if (!BUF_MEM_grow(s->init_buf,
+			26 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH +
+			EVP_MAX_MD_SIZE + slen))
+			return -1;
+		senc = OPENSSL_malloc(slen);
+		if (!senc)
+			return -1;
+		p = senc;
+		i2d_SSL_SESSION(s->session, &p);
+
+		p=(unsigned char *)s->init_buf->data;
+		/* do the header */
+		*(p++)=SSL3_MT_NEWSESSION_TICKET;
+		/* Skip message length for now */
+		p += 3;
+		EVP_CIPHER_CTX_init(&ctx);
+		HMAC_CTX_init(&hctx);
+		/* Initialize HMAC and cipher contexts. If callback present
+		 * it does all the work otherwise use generated values
+		 * from parent ctx.
+		 */
+		if (tctx->tlsext_ticket_key_cb)
+			{
+			if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
+							 &hctx, 1) < 0)
+				{
+				OPENSSL_free(senc);
+				return -1;
+				}
+			}
+		else
+			{
+			RAND_pseudo_bytes(iv, 16);
+			EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
+					tctx->tlsext_tick_aes_key, iv);
+			HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
+					tlsext_tick_md(), NULL);
+			memcpy(key_name, tctx->tlsext_tick_key_name, 16);
+			}
+		l2n(s->session->tlsext_tick_lifetime_hint, p);
+		/* Skip ticket length for now */
+		p += 2;
+		/* Output key name */
+		macstart = p;
+		memcpy(p, key_name, 16);
+		p += 16;
+		/* output IV */
+		memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx));
+		p += EVP_CIPHER_CTX_iv_length(&ctx);
+		/* Encrypt session data */
+		EVP_EncryptUpdate(&ctx, p, &len, senc, slen);
+		p += len;
+		EVP_EncryptFinal(&ctx, p, &len);
+		p += len;
+		EVP_CIPHER_CTX_cleanup(&ctx);
+
+		HMAC_Update(&hctx, macstart, p - macstart);
+		HMAC_Final(&hctx, p, &hlen);
+		HMAC_CTX_cleanup(&hctx);
+
+		p += hlen;
+		/* Now write out lengths: p points to end of data written */
+		/* Total length */
+		len = p - (unsigned char *)s->init_buf->data;
+		p=(unsigned char *)s->init_buf->data + 1;
+		l2n3(len - 4, p); /* Message length */
+		p += 4;
+		s2n(len - 10, p);  /* Ticket length */
+
+		/* number of bytes to write */
+		s->init_num= len;
+		s->state=SSL3_ST_SW_SESSION_TICKET_B;
+		s->init_off=0;
+		OPENSSL_free(senc);
+		}
+
+	/* SSL3_ST_SW_SESSION_TICKET_B */
+	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
+	}
+
+int ssl3_send_cert_status(SSL *s)
+	{
+	if (s->state == SSL3_ST_SW_CERT_STATUS_A)
+		{
+		unsigned char *p;
+		/* Grow buffer if need be: the length calculation is as
+ 		 * follows 1 (message type) + 3 (message length) +
+ 		 * 1 (ocsp response type) + 3 (ocsp response length)
+ 		 * + (ocsp response)
+ 		 */
+		if (!BUF_MEM_grow(s->init_buf, 8 + s->tlsext_ocsp_resplen))
+			return -1;
+
+		p=(unsigned char *)s->init_buf->data;
+
+		/* do the header */
+		*(p++)=SSL3_MT_CERTIFICATE_STATUS;
+		/* message length */
+		l2n3(s->tlsext_ocsp_resplen + 4, p);
+		/* status type */
+		*(p++)= s->tlsext_status_type;
+		/* length of OCSP response */
+		l2n3(s->tlsext_ocsp_resplen, p);
+		/* actual response */
+		memcpy(p, s->tlsext_ocsp_resp, s->tlsext_ocsp_resplen);
+		/* number of bytes to write */
+		s->init_num = 8 + s->tlsext_ocsp_resplen;
+		s->state=SSL3_ST_SW_CERT_STATUS_B;
+		s->init_off = 0;
+		}
+
+	/* SSL3_ST_SW_CERT_STATUS_B */
+	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
+	}
+
+# ifndef OPENSSL_NO_NPN
+/* ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. It
+ * sets the next_proto member in s if found */
+int ssl3_get_next_proto(SSL *s)
+	{
+	int ok;
+	unsigned proto_len, padding_len;
+	long n;
+	const unsigned char *p;
+
+	/* Clients cannot send a NextProtocol message if we didn't see the
+	 * extension in their ClientHello */
+	if (!s->s3->next_proto_neg_seen)
+		{
+		SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION);
+		return -1;
+		}
+
+	n=s->method->ssl_get_message(s,
+		SSL3_ST_SR_NEXT_PROTO_A,
+		SSL3_ST_SR_NEXT_PROTO_B,
+		SSL3_MT_NEXT_PROTO,
+		514,  /* See the payload format below */
+		&ok);
+
+	if (!ok)
+		return((int)n);
+
+	/* s->state doesn't reflect whether ChangeCipherSpec has been received
+	 * in this handshake, but s->s3->change_cipher_spec does (will be reset
+	 * by ssl3_get_finished). */
+	if (!s->s3->change_cipher_spec)
+		{
+		SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS);
+		return -1;
+		}
+
+	if (n < 2)
+		return 0;  /* The body must be > 1 bytes long */
+
+	p=(unsigned char *)s->init_msg;
+
+	/* The payload looks like:
+	 *   uint8 proto_len;
+	 *   uint8 proto[proto_len];
+	 *   uint8 padding_len;
+	 *   uint8 padding[padding_len];
+	 */
+	proto_len = p[0];
+	if (proto_len + 2 > s->init_num)
+		return 0;
+	padding_len = p[proto_len + 1];
+	if (proto_len + padding_len + 2 != s->init_num)
+		return 0;
+
+	s->next_proto_negotiated = OPENSSL_malloc(proto_len);
+	if (!s->next_proto_negotiated)
+		{
+		SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	memcpy(s->next_proto_negotiated, p + 1, proto_len);
+	s->next_proto_negotiated_len = proto_len;
+
+	return 1;
+	}
+# endif
+#endif
diff --git a/openssl/ssl/ssl-lib.com b/openssl/ssl/ssl-lib.com
new file mode 100644
index 0000000..180f3a2
--- /dev/null
+++ b/openssl/ssl/ssl-lib.com
@@ -0,0 +1,1214 @@
+$!
+$!  SSL-LIB.COM
+$!  Written By:  Robert Byer
+$!               Vice-President
+$!               A-Com Computing, Inc.
+$!               byer@mail.all-net.net
+$!
+$!  Changes by Richard Levitte <richard@levitte.org>
+$!
+$!  This command file compiles and creates the "[.xxx.EXE.SSL]LIBSSL.OLB" 
+$!  library for OpenSSL.  The "xxx" denotes the machine architecture of
+$!  ALPHA, IA64 or VAX.
+$!
+$!  It is written to detect what type of machine you are compiling on
+$!  (i.e. ALPHA or VAX) and which "C" compiler you have (i.e. VAXC, DECC 
+$!  or GNU C) or you can specify which compiler to use.
+$!
+$!  Specify the following as P1 to build just that part or ALL to just
+$!  build everything.
+$!
+$!    		LIBRARY    To just compile the [.xxx.EXE.SSL]LIBSSL.OLB Library.
+$!    		SSL_TASK   To just compile the [.xxx.EXE.SSL]SSL_TASK.EXE
+$!
+$!  Specify DEBUG or NODEBUG as P2 to compile with or without debugger
+$!  information.
+$!
+$!  Specify which compiler at P3 to try to compile under.
+$!
+$!	   VAXC	 For VAX C.
+$!	   DECC	 For DEC C.
+$!	   GNUC	 For GNU C.
+$!
+$!  If you don't specify a compiler, it will try to determine which
+$!  "C" compiler to use.
+$!
+$!  P4, if defined, sets a TCP/IP library to use, through one of the following
+$!  keywords:
+$!
+$!	UCX		for UCX
+$!	TCPIP		for TCPIP (post UCX)
+$!	SOCKETSHR	for SOCKETSHR+NETLIB
+$!
+$!  P5, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
+$!
+$!  P6, if defined, specifies the C pointer size.  Ignored on VAX.
+$!      ("64=ARGV" gives more efficient code with HP C V7.3 or newer.)
+$!      Supported values are:
+$!
+$!      ""       Compile with default (/NOPOINTER_SIZE)
+$!      32       Compile with /POINTER_SIZE=32 (SHORT)
+$!      64       Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV])
+$!               (Automatically select ARGV if compiler supports it.)
+$!      64=      Compile with /POINTER_SIZE=64 (LONG).
+$!      64=ARGV  Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV).
+$!
+$!  P7, if defined, specifies a directory where ZLIB files (zlib.h,
+$!  libz.olb) may be found.  Optionally, a non-default object library
+$!  name may be included ("dev:[dir]libz_64.olb", for example).
+$!
+$!
+$! Announce/identify.
+$!
+$ proc = f$environment( "procedure")
+$ write sys$output "@@@ "+ -
+   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
+$!
+$! Define A TCP/IP Library That We Will Need To Link To.
+$! (That Is, If We Need To Link To One.)
+$!
+$ TCPIP_LIB = ""
+$ ZLIB_LIB = ""
+$!
+$! Check What Architecture We Are Using.
+$!
+$ IF (F$GETSYI("CPU").LT.128)
+$ THEN
+$!
+$!  The Architecture Is VAX.
+$!
+$   ARCH = "VAX"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  The Architecture Is Alpha, IA64 or whatever comes in the future.
+$!
+$   ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
+$   IF (ARCH .EQS. "") THEN ARCH = "UNK"
+$!
+$! End The Architecture Check.
+$!
+$ ENDIF
+$!
+$ ARCHD = ARCH
+$ LIB32 = "32"
+$ OPT_FILE = ""
+$ POINTER_SIZE = ""
+$!
+$! Check To Make Sure We Have Valid Command Line Parameters.
+$!
+$ GOSUB CHECK_OPTIONS
+$!
+$! Define The OBJ and EXE Directories.
+$!
+$ OBJ_DIR := SYS$DISK:[-.'ARCHD'.OBJ.SSL]
+$ EXE_DIR := SYS$DISK:[-.'ARCHD'.EXE.SSL]
+$!
+$! Specify the destination directory in any /MAP option.
+$!
+$ if (LINKMAP .eqs. "MAP")
+$ then
+$   LINKMAP = LINKMAP+ "=''EXE_DIR'"
+$ endif
+$!
+$! Add the location prefix to the linker options file name.
+$!
+$ if (OPT_FILE .nes. "")
+$ then
+$   OPT_FILE = EXE_DIR+ OPT_FILE
+$ endif
+$!
+$! Initialise logical names and such
+$!
+$ GOSUB INITIALISE
+$!
+$! Tell The User What Kind of Machine We Run On.
+$!
+$ WRITE SYS$OUTPUT "Host system architecture: ''ARCHD'"
+$!
+$! Check To See If The Architecture Specific OBJ Directory Exists.
+$!
+$ IF (F$PARSE(OBJ_DIR).EQS."")
+$ THEN
+$!
+$!  It Dosen't Exist, So Create It.
+$!
+$   CREATE/DIR 'OBJ_DIR'
+$!
+$! End The Architecture Specific OBJ Directory Check.
+$!
+$ ENDIF
+$!
+$! Check To See If The Architecture Specific Directory Exists.
+$!
+$ IF (F$PARSE(EXE_DIR).EQS."")
+$ THEN
+$!
+$!  It Dosen't Exist, So Create It.
+$!
+$   CREATE/DIR 'EXE_DIR'
+$!
+$! End The Architecture Specific Directory Check.
+$!
+$ ENDIF
+$!
+$! Define The Library Name.
+$!
+$ SSL_LIB := 'EXE_DIR'SSL_LIBSSL'LIB32'.OLB
+$!
+$! Define The CRYPTO-LIB We Are To Use.
+$!
+$ CRYPTO_LIB := SYS$DISK:[-.'ARCHD'.EXE.CRYPTO]SSL_LIBCRYPTO'LIB32'.OLB
+$!
+$! Set up exceptional compilations.
+$!
+$ CC5_SHOWN = 0
+$!
+$! Check To See What We Are To Do.
+$!
+$ IF (BUILDALL.EQS."TRUE")
+$ THEN
+$!
+$!  Since Nothing Special Was Specified, Do Everything.
+$!
+$   GOSUB LIBRARY
+$   GOSUB SSL_TASK
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  Build Just What The User Wants Us To Build.
+$!
+$   GOSUB 'BUILDALL'
+$!
+$! End The BUILDALL Check.
+$!
+$ ENDIF
+$!
+$! Time To EXIT.
+$!
+$ EXIT:
+$ GOSUB CLEANUP
+$ EXIT   
+$!
+$! Compile The Library.
+$!
+$ LIBRARY:
+$!
+$! Check To See If We Already Have A "[.xxx.EXE.SSL]SSL_LIBSSL''LIB32'.OLB" Library...
+$!
+$ IF (F$SEARCH(SSL_LIB).EQS."")
+$ THEN
+$!
+$! Guess Not, Create The Library.
+$!
+$   LIBRARY/CREATE/OBJECT 'SSL_LIB'
+$!
+$! End The Library Exist Check.
+$!
+$ ENDIF
+$!
+$! Define The Different SSL "library" Files.
+$!
+$ LIB_SSL = "s2_meth,s2_srvr,s2_clnt,s2_lib,s2_enc,s2_pkt,"+ -
+	    "s3_meth,s3_srvr,s3_clnt,s3_lib,s3_enc,s3_pkt,s3_both,"+ -
+	    "s23_meth,s23_srvr,s23_clnt,s23_lib,s23_pkt,"+ -
+	    "t1_meth,t1_srvr,t1_clnt,t1_lib,t1_enc,"+ -
+	    "d1_meth,d1_srvr,d1_clnt,d1_lib,d1_pkt,"+ -
+	    "d1_both,d1_enc,"+ -
+	    "ssl_lib,ssl_err2,ssl_cert,ssl_sess,"+ -
+	    "ssl_ciph,ssl_stat,ssl_rsa,"+ -
+	    "ssl_asn1,ssl_txt,ssl_algs,"+ -
+	    "bio_ssl,ssl_err,kssl,t1_reneg"
+$!
+$ COMPILEWITH_CC5 = ""
+$!
+$! Tell The User That We Are Compiling The Library.
+$!
+$ WRITE SYS$OUTPUT "Building The ",SSL_LIB," Library."
+$!
+$! Define A File Counter And Set It To "0"
+$!
+$ FILE_COUNTER = 0
+$!
+$! Top Of The File Loop.
+$!
+$ NEXT_FILE:
+$!
+$! O.K, Extract The File Name From The File List.
+$!
+$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",LIB_SSL)
+$!
+$! Check To See If We Are At The End Of The File List.
+$!
+$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
+$!
+$! Increment The Counter.
+$!
+$ FILE_COUNTER = FILE_COUNTER + 1
+$!
+$! Create The Source File Name.
+$!
+$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME + ".C"
+$!
+$! Create The Object File Name.
+$!
+$ OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ"
+$ ON WARNING THEN GOTO NEXT_FILE
+$!
+$! Check To See If The File We Want To Compile Is Actually There.
+$!
+$ IF (F$SEARCH(SOURCE_FILE).EQS."")
+$ THEN
+$!
+$!  Tell The User That The File Dosen't Exist.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Exit The Build.
+$!
+$   EXIT
+$!
+$! End The File Exists Check.
+$!
+$ ENDIF
+$!
+$!  Tell The User What File We Are Compiling.
+$!
+$ WRITE SYS$OUTPUT "	",FILE_NAME,".c"
+$!
+$! Compile The File.
+$!
+$ ON ERROR THEN GOTO NEXT_FILE
+$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$!
+$! Add It To The Library.
+$!
+$ LIBRARY/REPLACE/OBJECT 'SSL_LIB' 'OBJECT_FILE'
+$!
+$! Time To Clean Up The Object File.
+$!
+$ DELETE 'OBJECT_FILE';*
+$!
+$! Go Back And Get The Next File Name.
+$!
+$ GOTO NEXT_FILE
+$!
+$! All Done With This Library.
+$!
+$ FILE_DONE:
+$!
+$! Tell The User That We Are All Done.
+$!
+$ WRITE SYS$OUTPUT "Library ",SSL_LIB," Compiled."
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$ SSL_TASK:
+$!
+$! Check To See If We Have The Proper Libraries.
+$!
+$ GOSUB LIB_CHECK
+$!
+$! Check To See If We Have A Linker Option File.
+$!
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Check To See If The File We Want To Compile Is Actually There.
+$!
+$ IF (F$SEARCH("SYS$DISK:[]SSL_TASK.C").EQS."")
+$ THEN
+$!
+$!  Tell The User That The File Dosen't Exist.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The File SSL_TASK.C Dosen't Exist."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Exit The Build.
+$!
+$   EXIT
+$!
+$! End The SSL_TASK.C File Check.
+$!
+$ ENDIF
+$!
+$ COMPILEWITH_CC5 = "" !!! ",ssl_task,"
+$!
+$! Tell The User We Are Creating The SSL_TASK.
+$!
+$! Tell The User We Are Creating The SSL_TASK.
+$!
+$ WRITE SYS$OUTPUT "Creating SSL_TASK OSU HTTP SSL Engine."	
+$!
+$!  Tell The User What File We Are Compiling.
+$!
+$ FILE_NAME = "ssl_task"
+$ WRITE SYS$OUTPUT "	",FILE_NAME,".c"
+$!
+$! Compile The File.
+$!
+$ ON ERROR THEN GOTO SSL_TASK_END
+$!
+$ FILE_NAME0 = ","+ F$ELEMENT(0,".",FILE_NAME)+ ","
+$ IF COMPILEWITH_CC5 - FILE_NAME0 .NES. COMPILEWITH_CC5
+$ THEN
+$   if (.not. CC5_SHOWN)
+$   then
+$     CC5_SHOWN = 1
+$     write sys$output "        \Using special rule (5)"
+$     x = "    "+ CC5
+$     write /symbol sys$output x
+$   endif
+$   CC5 /OBJECT='OBJ_DIR''FILE_NAME'.OBJ SYS$DISK:[]'FILE_NAME'.C
+$ ELSE
+$   CC /OBJECT='OBJ_DIR''FILE_NAME'.OBJ SYS$DISK:[]'FILE_NAME'.C
+$ ENDIF
+$!
+$! Link The Program.
+$!
+$ LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' /EXE='EXE_DIR'SSL_TASK.EXE -
+   'OBJ_DIR'SSL_TASK.OBJ, -
+   'SSL_LIB'/LIBRARY, -
+   'CRYPTO_LIB'/LIBRARY -
+   'TCPIP_LIB' -
+   'ZLIB_LIB' -
+   ,'OPT_FILE' /OPTIONS
+$!
+$! Time To Return.
+$!
+$SSL_TASK_END:
+$ RETURN
+$!
+$! Check For The Link Option FIle.
+$!
+$ CHECK_OPT_FILE:
+$!
+$! Check To See If We Need To Make A VAX C Option File.
+$!
+$ IF (COMPILER.EQS."VAXC")
+$ THEN
+$!
+$!  Check To See If We Already Have A VAX C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    We Need A VAX C Linker Option File.
+$!
+$     CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against 
+! The Sharable VAX C Runtime Library.
+!
+SYS$SHARE:VAXCRTL.EXE/SHARE
+$EOD
+$!
+$!  End The Option File Check.
+$!
+$   ENDIF
+$!
+$! End The VAXC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A GNU C Option File.
+$!
+$ IF (COMPILER.EQS."GNUC")
+$ THEN
+$!
+$!  Check To See If We Already Have A GNU C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    We Need A GNU C Linker Option File.
+$!
+$     CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against 
+! The Sharable C Runtime Library.
+!
+GNU_CC:[000000]GCCLIB/LIBRARY
+SYS$SHARE:VAXCRTL/SHARE
+$EOD
+$!
+$!  End The Option File Check.
+$!
+$   ENDIF
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A DEC C Option File.
+$!
+$ IF (COMPILER.EQS."DECC")
+$ THEN
+$!
+$!  Check To See If We Already Have A DEC C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    Figure Out If We Need A non-VAX Or A VAX Linker Option File.
+$!
+$     IF (ARCH.EQS."VAX")
+$     THEN
+$!
+$!      We Need A DEC C Linker Option File For VAX.
+$!
+$       CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against 
+! The Sharable DEC C Runtime Library.
+!
+SYS$SHARE:DECC$SHR.EXE/SHARE
+$EOD
+$!
+$!    Else...
+$!
+$     ELSE
+$!
+$!      Create The non-VAX Linker Option File.
+$!
+$       CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File For non-VAX To Link Against 
+! The Sharable C Runtime Library.
+!
+SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
+SYS$SHARE:CMA$OPEN_RTL/SHARE
+$EOD
+$!
+$!    End The DEC C Option File Check.
+$!
+$     ENDIF
+$!
+$!  End The Option File Search.
+$!
+$   ENDIF
+$!
+$! End The DEC C Check.
+$!
+$ ENDIF
+$!
+$!  Tell The User What Linker Option File We Are Using.
+$!
+$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."	
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$ LIB_CHECK:
+$!
+$! Look For The VAX Library LIBSSL.OLB.
+$!
+$ IF (F$SEARCH(SSL_LIB).EQS."")
+$ THEN
+$!
+$!  Tell The User We Can't Find The LIBSSL.OLB Library.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"."
+$   WRITE SYS$OUTPUT "We Can't Link Without It."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Since We Can't Link Without It, Exit.
+$!
+$   EXIT
+$!
+$! End The LIBSSL.OLB Library Check.
+$!
+$ ENDIF
+$!
+$! Look For The Library LIBCRYPTO.OLB.
+$!
+$ IF (F$SEARCH(CRYPTO_LIB).EQS."")
+$ THEN
+$!
+$!  Tell The User We Can't Find The LIBCRYPTO.OLB Library.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"."
+$   WRITE SYS$OUTPUT "We Can't Link Without It."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Since We Can't Link Without It, Exit.
+$!
+$   EXIT
+$!
+$! End The LIBCRYPTO.OLB Library Check.
+$!
+$ ENDIF
+$!
+$! Time To Return.
+$!
+$ RETURN
+$!
+$! Check The User's Options.
+$!
+$ CHECK_OPTIONS:
+$!
+$! Check To See If P1 Is Blank.
+$!
+$ IF (P1.EQS."ALL")
+$ THEN
+$!
+$!   P1 Is Blank, So Build Everything.
+$!
+$    BUILDALL = "TRUE"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  Else, Check To See If P1 Has A Valid Argument.
+$!
+$   IF (P1.EQS."LIBRARY").OR.(P1.EQS."SSL_TASK")
+$   THEN
+$!
+$!    A Valid Argument.
+$!
+$     BUILDALL = P1
+$!
+$!  Else...
+$!
+$   ELSE
+$!
+$!    Tell The User We Don't Know What They Want.
+$!
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ",P1," Is Invalid.  The Valid Options Are:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "    ALL      :  Just Build Everything."
+$     WRITE SYS$OUTPUT "    LIBRARY  :  To Compile Just The [.xxx.EXE.SSL]LIBSSL.OLB Library."
+$     WRITE SYS$OUTPUT "    SSL_TASK :  To Compile Just The [.xxx.EXE.SSL]SSL_TASK.EXE Program."
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT " Where 'xxx' Stands For:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "    ALPHA[64]:  Alpha Architecture."
+$     WRITE SYS$OUTPUT "    IA64[64] :  IA64 Architecture."
+$     WRITE SYS$OUTPUT "    VAX      :  VAX Architecture."
+$     WRITE SYS$OUTPUT ""
+$!
+$!    Time To EXIT.
+$!
+$     EXIT
+$!
+$!  End The Valid Argument Check.
+$!
+$   ENDIF
+$!
+$! End The P1 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P2 Is Blank.
+$!
+$ IF (P2.EQS."NODEBUG")
+$ THEN
+$!
+$!  P2 Is NODEBUG, So Compile Without Debugger Information.
+$!
+$   DEBUGGER  = "NODEBUG"
+$   LINKMAP = "NOMAP"
+$   TRACEBACK = "NOTRACEBACK" 
+$   GCC_OPTIMIZE = "OPTIMIZE"
+$   CC_OPTIMIZE = "OPTIMIZE"
+$   WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
+$   WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  Check To See If We Are To Compile With Debugger Information.
+$!
+$   IF (P2.EQS."DEBUG")
+$   THEN
+$!
+$!    Compile With Debugger Information.
+$!
+$     DEBUGGER  = "DEBUG"
+$     LINKMAP = "MAP"
+$     TRACEBACK = "TRACEBACK"
+$     GCC_OPTIMIZE = "NOOPTIMIZE"
+$     CC_OPTIMIZE = "NOOPTIMIZE"
+$     WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
+$     WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
+$   ELSE
+$!
+$!    Tell The User Entered An Invalid Option.
+$!
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ",P2," Is Invalid.  The Valid Options Are:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "    DEBUG    :  Compile With The Debugger Information."
+$     WRITE SYS$OUTPUT "    NODEBUG  :  Compile Without The Debugger Information."
+$     WRITE SYS$OUTPUT ""
+$!
+$!    Time To EXIT.
+$!
+$     EXIT
+$!
+$!  End The Valid Argument Check.
+$!
+$   ENDIF
+$!
+$! End The P2 Check.
+$!
+$ ENDIF
+$!
+$! Special Threads For OpenVMS v7.1 Or Later
+$!
+$! Written By:  Richard Levitte
+$!              richard@levitte.org
+$!
+$!
+$! Check To See If We Have A Option For P5.
+$!
+$ IF (P5.EQS."")
+$ THEN
+$!
+$!  Get The Version Of VMS We Are Using.
+$!
+$   ISSEVEN :=
+$   TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
+$   TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
+$!
+$!  Check To See If The VMS Version Is v7.1 Or Later.
+$!
+$   IF (TMP.GE.71)
+$   THEN
+$!
+$!    We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
+$!
+$     ISSEVEN := ,PTHREAD_USE_D4
+$!
+$!  End The VMS Version Check.
+$!
+$   ENDIF
+$!
+$! End The P5 Check.
+$!
+$ ENDIF
+$!
+$! Check P6 (POINTER_SIZE).
+$!
+$ IF (P6 .NES. "") .AND. (ARCH .NES. "VAX")
+$ THEN
+$!
+$   IF (P6 .EQS. "32")
+$   THEN
+$     POINTER_SIZE = " /POINTER_SIZE=32"
+$   ELSE
+$     POINTER_SIZE = F$EDIT( P6, "COLLAPSE, UPCASE")
+$     IF ((POINTER_SIZE .EQS. "64") .OR. -
+       (POINTER_SIZE .EQS. "64=") .OR. -
+       (POINTER_SIZE .EQS. "64=ARGV"))
+$     THEN
+$       ARCHD = ARCH+ "_64"
+$       LIB32 = ""
+$       POINTER_SIZE = " /POINTER_SIZE=64"
+$     ELSE
+$!
+$!      Tell The User Entered An Invalid Option.
+$!
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT "The Option ", P6, -
+         " Is Invalid.  The Valid Options Are:"
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT -
+         "    """"       :  Compile with default (short) pointers."
+$       WRITE SYS$OUTPUT -
+         "    32       :  Compile with 32-bit (short) pointers."
+$       WRITE SYS$OUTPUT -
+         "    64       :  Compile with 64-bit (long) pointers (auto ARGV)."
+$       WRITE SYS$OUTPUT -
+         "    64=      :  Compile with 64-bit (long) pointers (no ARGV)."
+$       WRITE SYS$OUTPUT -
+         "    64=ARGV  :  Compile with 64-bit (long) pointers (ARGV)."
+$       WRITE SYS$OUTPUT ""
+$! 
+$!      Time To EXIT.
+$!
+$       EXIT
+$!
+$     ENDIF
+$!
+$   ENDIF
+$!
+$! End The P6 (POINTER_SIZE) Check.
+$!
+$ ENDIF
+$!
+$! Set basic C compiler /INCLUDE directories.
+$!
+$ CC_INCLUDES = "SYS$DISK:[-.CRYPTO],SYS$DISK:[-]"
+$!
+$! Check To See If P3 Is Blank.
+$!
+$ IF (P3.EQS."")
+$ THEN
+$!
+$!  O.K., The User Didn't Specify A Compiler, Let's Try To
+$!  Find Out Which One To Use.
+$!
+$!  Check To See If We Have GNU C.
+$!
+$   IF (F$TRNLNM("GNU_CC").NES."")
+$   THEN
+$!
+$!    Looks Like GNUC, Set To Use GNUC.
+$!
+$     P3 = "GNUC"
+$!
+$!  End The GNU C Compiler Check.
+$!
+$   ELSE
+$!
+$!  Check To See If We Have VAXC Or DECC.
+$!
+$     IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
+$     THEN 
+$!
+$!      Looks Like DECC, Set To Use DECC.
+$!
+$       P3 = "DECC"
+$!
+$!      Else...
+$!
+$     ELSE
+$!
+$!      Looks Like VAXC, Set To Use VAXC.
+$!
+$       P3 = "VAXC"
+$!
+$!    End The VAXC Compiler Check.
+$!
+$     ENDIF
+$!
+$!  End The DECC & VAXC Compiler Check.
+$!
+$   ENDIF
+$!
+$!  End The Compiler Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have A Option For P4.
+$!
+$ IF (P4.EQS."")
+$ THEN
+$!
+$!  Find out what socket library we have available
+$!
+$   IF F$PARSE("SOCKETSHR:") .NES. ""
+$   THEN
+$!
+$!    We have SOCKETSHR, and it is my opinion that it's the best to use.
+$!
+$     P4 = "SOCKETSHR"
+$!
+$!    Tell the user
+$!
+$     WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
+$!
+$!    Else, let's look for something else
+$!
+$   ELSE
+$!
+$!    Like UCX (the reason to do this before Multinet is that the UCX
+$!    emulation is easier to use...)
+$!
+$     IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
+	 .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
+	 .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
+$     THEN
+$!
+$!	Last resort: a UCX or UCX-compatible library
+$!
+$	P4 = "UCX"
+$!
+$!      Tell the user
+$!
+$       WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
+$!
+$!	That was all...
+$!
+$     ENDIF
+$   ENDIF
+$ ENDIF
+$!
+$! Set Up Initial CC Definitions, Possibly With User Ones
+$!
+$ CCDEFS = "TCPIP_TYPE_''P4'"
+$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
+$ CCEXTRAFLAGS = ""
+$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
+$ CCDISABLEWARNINGS = "" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
+$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
+	CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
+$!
+$! Check To See If We Have A ZLIB Option.
+$!
+$ ZLIB = P7
+$ IF (ZLIB .NES. "")
+$ THEN
+$!
+$!  Check for expected ZLIB files.
+$!
+$   err = 0
+$   file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY")
+$   if (f$search( file1) .eqs. "")
+$   then
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
+$     WRITE SYS$OUTPUT "    Can't find header: ''file1'"
+$     err = 1
+$   endif
+$   file1 = f$parse( "A.;", ZLIB)- "A.;"
+$!
+$   file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY")
+$   if (f$search( file2) .eqs. "")
+$   then
+$     if (err .eq. 0)
+$     then
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
+$     endif
+$     WRITE SYS$OUTPUT "    Can't find library: ''file2'"
+$     WRITE SYS$OUTPUT ""
+$     err = err+ 2
+$   endif
+$   if (err .eq. 1)
+$   then
+$     WRITE SYS$OUTPUT ""
+$   endif
+$!
+$   if (err .ne. 0)
+$   then
+$     EXIT
+$   endif
+$!
+$   CCDEFS = """ZLIB=1"", "+ CCDEFS
+$   CC_INCLUDES = CC_INCLUDES+ ", "+ file1
+$   ZLIB_LIB = ", ''file2' /library"
+$!
+$!  Print info
+$!
+$   WRITE SYS$OUTPUT "ZLIB library spec: ", file2
+$!
+$! End The ZLIB Check.
+$!
+$ ENDIF
+$!
+$!  Check To See If The User Entered A Valid Parameter.
+$!
+$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC")
+$ THEN
+$!
+$!  Check To See If The User Wanted DECC.
+$!
+$   IF (P3.EQS."DECC")
+$   THEN
+$!
+$!    Looks Like DECC, Set To Use DECC.
+$!
+$     COMPILER = "DECC"
+$!
+$!    Tell The User We Are Using DECC.
+$!
+$     WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$!    Use DECC...
+$!
+$     CC = "CC"
+$     IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
+	 THEN CC = "CC/DECC"
+$     CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ -
+       "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + -
+       " /INCLUDE=(''CC_INCLUDES') " + CCEXTRAFLAGS
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "VAX_DECC_OPTIONS.OPT"
+$!
+$!  End DECC Check.
+$!
+$   ENDIF
+$!
+$!  Check To See If We Are To Use VAXC.
+$!
+$   IF (P3.EQS."VAXC")
+$   THEN
+$!
+$!    Looks Like VAXC, Set To Use VAXC.
+$!
+$     COMPILER = "VAXC"
+$!
+$!    Tell The User We Are Using VAX C.
+$!
+$     WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$!    Compile Using VAXC.
+$!
+$     CC = "CC"
+$     IF ARCH.NES."VAX"
+$     THEN
+$	WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
+$	EXIT
+$     ENDIF
+$     IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
+$     CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+	   "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
+$     CCDEFS = CCDEFS + ",""VAXC"""
+$!
+$!    Define <sys> As SYS$COMMON:[SYSLIB]
+$!
+$     DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "VAX_VAXC_OPTIONS.OPT"
+$!
+$!  End VAXC Check
+$!
+$   ENDIF
+$!
+$!  Check To See If We Are To Use GNU C.
+$!
+$   IF (P3.EQS."GNUC")
+$   THEN
+$!
+$!    Looks Like GNUC, Set To Use GNUC.
+$!
+$     COMPILER = "GNUC"
+$!
+$!    Tell The User We Are Using GNUC.
+$!
+$     WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$!    Use GNU C...
+$!
+$     IF F$TYPE(GCC) .EQS. "" THEN GCC := GCC
+$     CC = GCC+"/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+	   "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "VAX_GNUC_OPTIONS.OPT"
+$!
+$!  End The GNU C Check.
+$!
+$   ENDIF
+$!
+$!  Set up default defines
+$!
+$   CCDEFS = """FLAT_INC=1""," + CCDEFS
+$!
+$!  Finish up the definition of CC.
+$!
+$   IF COMPILER .EQS. "DECC"
+$   THEN
+$     IF CCDISABLEWARNINGS .EQS. ""
+$     THEN
+$       CC4DISABLEWARNINGS = "DOLLARID"
+$     ELSE
+$       CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
+$       CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
+$     ENDIF
+$     CC4DISABLEWARNINGS = " /WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
+$   ELSE
+$     CCDISABLEWARNINGS = ""
+$     CC4DISABLEWARNINGS = ""
+$   ENDIF
+$   CC2 = CC + " /DEFINE=(" + CCDEFS + ",_POSIX_C_SOURCE)" + CCDISABLEWARNINGS
+$   CC3 = CC + " /DEFINE=(" + CCDEFS + ISSEVEN + ")" + CCDISABLEWARNINGS
+$   CC = CC + " /DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
+$   IF COMPILER .EQS. "DECC"
+$   THEN
+$     CC4 = CC - CCDISABLEWARNINGS + CC4DISABLEWARNINGS
+$     CC5 = CC3 - CCDISABLEWARNINGS + CC4DISABLEWARNINGS
+$   ELSE
+$     CC4 = CC
+$     CC5 = CC3
+$   ENDIF
+$!
+$!  Show user the result
+$!
+$   WRITE/SYMBOL SYS$OUTPUT "Main Compiling Command: ",CC
+$!
+$!  Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$!  Tell The User We Don't Know What They Want.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The Option ",P3," Is Invalid.  The Valid Options Are:"
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "    VAXC  :  To Compile With VAX C."
+$   WRITE SYS$OUTPUT "    DECC  :  To Compile With DEC C."
+$   WRITE SYS$OUTPUT "    GNUC  :  To Compile With GNU C."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Time To EXIT.
+$!
+$   EXIT
+$ ENDIF
+$!
+$! Time to check the contents, and to make sure we get the correct library.
+$!
+$ IF P4.EQS."SOCKETSHR" .OR. P4.EQS."MULTINET" .OR. P4.EQS."UCX" -
+     .OR. P4.EQS."TCPIP" .OR. P4.EQS."NONE"
+$ THEN
+$!
+$!  Check to see if SOCKETSHR was chosen
+$!
+$   IF P4.EQS."SOCKETSHR"
+$   THEN
+$!
+$!    Set the library to use SOCKETSHR
+$!
+$     TCPIP_LIB = ",SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
+$!
+$!    Done with SOCKETSHR
+$!
+$   ENDIF
+$!
+$!  Check to see if MULTINET was chosen
+$!
+$   IF P4.EQS."MULTINET"
+$   THEN
+$!
+$!    Set the library to use UCX emulation.
+$!
+$     P4 = "UCX"
+$!
+$!    Done with MULTINET
+$!
+$   ENDIF
+$!
+$!  Check to see if UCX was chosen
+$!
+$   IF P4.EQS."UCX"
+$   THEN
+$!
+$!    Set the library to use UCX.
+$!
+$     TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
+$     IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
+$     THEN
+$       TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS"
+$     ELSE
+$       IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
+	  TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS"
+$     ENDIF
+$!
+$!    Done with UCX
+$!
+$   ENDIF
+$!
+$!  Check to see if TCPIP was chosen
+$!
+$   IF P4.EQS."TCPIP"
+$   THEN
+$!
+$!    Set the library to use TCPIP (post UCX).
+$!
+$     TCPIP_LIB = ",SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
+$!
+$!    Done with TCPIP
+$!
+$   ENDIF
+$!
+$!  Check to see if NONE was chosen
+$!
+$   IF P4.EQS."NONE"
+$   THEN
+$!
+$!    Do not use a TCPIP library.
+$!
+$     TCPIP_LIB = ""
+$!
+$!    Done with NONE
+$!
+$   ENDIF
+$!
+$!  Print info
+$!
+$   WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB- ","
+$!
+$!  Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$!  Tell The User We Don't Know What They Want.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The Option ",P4," Is Invalid.  The Valid Options Are:"
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "    SOCKETSHR  :  To link with SOCKETSHR TCP/IP library."
+$   WRITE SYS$OUTPUT "    UCX        :  To link with UCX TCP/IP library."
+$   WRITE SYS$OUTPUT "    TCPIP      :  To link with TCPIP (post UCX) TCP/IP library."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Time To EXIT.
+$!
+$   EXIT
+$!
+$!  Done with TCP/IP libraries
+$!
+$ ENDIF
+$!
+$!  Time To RETURN...
+$!
+$ RETURN
+$!
+$ INITIALISE:
+$!
+$! Save old value of the logical name OPENSSL
+$!
+$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
+$!
+$! Save directory information
+$!
+$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
+$ __HERE = F$EDIT(__HERE,"UPCASE")
+$ __TOP = __HERE - "SSL]"
+$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
+$!
+$! Set up the logical name OPENSSL to point at the include directory
+$!
+$ DEFINE OPENSSL/NOLOG '__INCLUDE'
+$!
+$! Done
+$!
+$ RETURN
+$!
+$ CLEANUP:
+$!
+$! Restore the logical name OPENSSL if it had a value
+$!
+$ IF __SAVE_OPENSSL .EQS. ""
+$ THEN
+$   DEASSIGN OPENSSL
+$ ELSE
+$   DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL'
+$ ENDIF
+$!
+$! Done
+$!
+$ RETURN
diff --git a/openssl/ssl/ssl.h b/openssl/ssl/ssl.h
new file mode 100644
index 0000000..fdcab6f
--- /dev/null
+++ b/openssl/ssl/ssl.h
@@ -0,0 +1,2386 @@
+/* ssl/ssl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#ifndef HEADER_SSL_H 
+#define HEADER_SSL_H 
+
+#include <openssl/e_os2.h>
+
+#ifndef OPENSSL_NO_COMP
+#include <openssl/comp.h>
+#endif
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#ifndef OPENSSL_NO_DEPRECATED
+#ifndef OPENSSL_NO_X509
+#include <openssl/x509.h>
+#endif
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+#include <openssl/buffer.h>
+#endif
+#include <openssl/pem.h>
+#include <openssl/hmac.h>
+
+#include <openssl/kssl.h>
+#include <openssl/safestack.h>
+#include <openssl/symhacks.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* SSLeay version number for ASN.1 encoding of the session information */
+/* Version 0 - initial version
+ * Version 1 - added the optional peer certificate
+ */
+#define SSL_SESSION_ASN1_VERSION 0x0001
+
+/* text strings for the ciphers */
+#define SSL_TXT_NULL_WITH_MD5		SSL2_TXT_NULL_WITH_MD5			
+#define SSL_TXT_RC4_128_WITH_MD5	SSL2_TXT_RC4_128_WITH_MD5		
+#define SSL_TXT_RC4_128_EXPORT40_WITH_MD5 SSL2_TXT_RC4_128_EXPORT40_WITH_MD5	
+#define SSL_TXT_RC2_128_CBC_WITH_MD5	SSL2_TXT_RC2_128_CBC_WITH_MD5		
+#define SSL_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5	
+#define SSL_TXT_IDEA_128_CBC_WITH_MD5	SSL2_TXT_IDEA_128_CBC_WITH_MD5		
+#define SSL_TXT_DES_64_CBC_WITH_MD5	SSL2_TXT_DES_64_CBC_WITH_MD5		
+#define SSL_TXT_DES_64_CBC_WITH_SHA	SSL2_TXT_DES_64_CBC_WITH_SHA		
+#define SSL_TXT_DES_192_EDE3_CBC_WITH_MD5 SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5	
+#define SSL_TXT_DES_192_EDE3_CBC_WITH_SHA SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA	
+
+/*    VRS Additional Kerberos5 entries
+ */
+#define SSL_TXT_KRB5_DES_64_CBC_SHA   SSL3_TXT_KRB5_DES_64_CBC_SHA
+#define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA
+#define SSL_TXT_KRB5_RC4_128_SHA      SSL3_TXT_KRB5_RC4_128_SHA
+#define SSL_TXT_KRB5_IDEA_128_CBC_SHA SSL3_TXT_KRB5_IDEA_128_CBC_SHA
+#define SSL_TXT_KRB5_DES_64_CBC_MD5   SSL3_TXT_KRB5_DES_64_CBC_MD5       
+#define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5       
+#define SSL_TXT_KRB5_RC4_128_MD5      SSL3_TXT_KRB5_RC4_128_MD5
+#define SSL_TXT_KRB5_IDEA_128_CBC_MD5 SSL3_TXT_KRB5_IDEA_128_CBC_MD5 
+
+#define SSL_TXT_KRB5_DES_40_CBC_SHA   SSL3_TXT_KRB5_DES_40_CBC_SHA 
+#define SSL_TXT_KRB5_RC2_40_CBC_SHA   SSL3_TXT_KRB5_RC2_40_CBC_SHA 
+#define SSL_TXT_KRB5_RC4_40_SHA	      SSL3_TXT_KRB5_RC4_40_SHA
+#define SSL_TXT_KRB5_DES_40_CBC_MD5   SSL3_TXT_KRB5_DES_40_CBC_MD5 
+#define SSL_TXT_KRB5_RC2_40_CBC_MD5   SSL3_TXT_KRB5_RC2_40_CBC_MD5 
+#define SSL_TXT_KRB5_RC4_40_MD5	      SSL3_TXT_KRB5_RC4_40_MD5
+
+#define SSL_TXT_KRB5_DES_40_CBC_SHA   SSL3_TXT_KRB5_DES_40_CBC_SHA
+#define SSL_TXT_KRB5_DES_40_CBC_MD5   SSL3_TXT_KRB5_DES_40_CBC_MD5
+#define SSL_TXT_KRB5_DES_64_CBC_SHA   SSL3_TXT_KRB5_DES_64_CBC_SHA
+#define SSL_TXT_KRB5_DES_64_CBC_MD5   SSL3_TXT_KRB5_DES_64_CBC_MD5
+#define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA
+#define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5
+#define SSL_MAX_KRB5_PRINCIPAL_LENGTH  256
+
+#define SSL_MAX_SSL_SESSION_ID_LENGTH		32
+#define SSL_MAX_SID_CTX_LENGTH			32
+
+#define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES	(512/8)
+#define SSL_MAX_KEY_ARG_LENGTH			8
+#define SSL_MAX_MASTER_KEY_LENGTH		48
+
+
+/* These are used to specify which ciphers to use and not to use */
+
+#define SSL_TXT_EXP40		"EXPORT40"
+#define SSL_TXT_EXP56		"EXPORT56"
+#define SSL_TXT_LOW		"LOW"
+#define SSL_TXT_MEDIUM		"MEDIUM"
+#define SSL_TXT_HIGH		"HIGH"
+#define SSL_TXT_FIPS		"FIPS"
+
+#define SSL_TXT_kFZA		"kFZA" /* unused! */
+#define	SSL_TXT_aFZA		"aFZA" /* unused! */
+#define SSL_TXT_eFZA		"eFZA" /* unused! */
+#define SSL_TXT_FZA		"FZA"  /* unused! */
+
+#define	SSL_TXT_aNULL		"aNULL"
+#define	SSL_TXT_eNULL		"eNULL"
+#define	SSL_TXT_NULL		"NULL"
+
+#define SSL_TXT_kRSA		"kRSA"
+#define SSL_TXT_kDHr		"kDHr" /* no such ciphersuites supported! */
+#define SSL_TXT_kDHd		"kDHd" /* no such ciphersuites supported! */
+#define SSL_TXT_kDH 		"kDH"  /* no such ciphersuites supported! */
+#define SSL_TXT_kEDH		"kEDH"
+#define SSL_TXT_kKRB5     	"kKRB5"
+#define SSL_TXT_kECDHr		"kECDHr"
+#define SSL_TXT_kECDHe		"kECDHe"
+#define SSL_TXT_kECDH		"kECDH"
+#define SSL_TXT_kEECDH		"kEECDH"
+#define SSL_TXT_kPSK            "kPSK"
+#define SSL_TXT_kGOST		"kGOST"
+
+#define	SSL_TXT_aRSA		"aRSA"
+#define	SSL_TXT_aDSS		"aDSS"
+#define	SSL_TXT_aDH		"aDH" /* no such ciphersuites supported! */
+#define	SSL_TXT_aECDH		"aECDH"
+#define SSL_TXT_aKRB5     	"aKRB5"
+#define SSL_TXT_aECDSA		"aECDSA"
+#define SSL_TXT_aPSK            "aPSK"
+#define SSL_TXT_aGOST94	"aGOST94"
+#define SSL_TXT_aGOST01 "aGOST01"
+#define SSL_TXT_aGOST  "aGOST"
+
+#define	SSL_TXT_DSS		"DSS"
+#define SSL_TXT_DH		"DH"
+#define SSL_TXT_EDH		"EDH" /* same as "kEDH:-ADH" */
+#define SSL_TXT_ADH		"ADH"
+#define SSL_TXT_RSA		"RSA"
+#define SSL_TXT_ECDH		"ECDH"
+#define SSL_TXT_EECDH		"EECDH" /* same as "kEECDH:-AECDH" */
+#define SSL_TXT_AECDH		"AECDH"
+#define SSL_TXT_ECDSA		"ECDSA"
+#define SSL_TXT_KRB5      	"KRB5"
+#define SSL_TXT_PSK             "PSK"
+
+#define SSL_TXT_DES		"DES"
+#define SSL_TXT_3DES		"3DES"
+#define SSL_TXT_RC4		"RC4"
+#define SSL_TXT_RC2		"RC2"
+#define SSL_TXT_IDEA		"IDEA"
+#define SSL_TXT_SEED		"SEED"
+#define SSL_TXT_AES128		"AES128"
+#define SSL_TXT_AES256		"AES256"
+#define SSL_TXT_AES		"AES"
+#define SSL_TXT_CAMELLIA128	"CAMELLIA128"
+#define SSL_TXT_CAMELLIA256	"CAMELLIA256"
+#define SSL_TXT_CAMELLIA	"CAMELLIA"
+
+#define SSL_TXT_MD5		"MD5"
+#define SSL_TXT_SHA1		"SHA1"
+#define SSL_TXT_SHA		"SHA" /* same as "SHA1" */
+#define SSL_TXT_GOST94		"GOST94" 
+#define SSL_TXT_GOST89MAC		"GOST89MAC" 
+
+#define SSL_TXT_SSLV2		"SSLv2"
+#define SSL_TXT_SSLV3		"SSLv3"
+#define SSL_TXT_TLSV1		"TLSv1"
+
+#define SSL_TXT_EXP		"EXP"
+#define SSL_TXT_EXPORT		"EXPORT"
+
+#define SSL_TXT_ALL		"ALL"
+
+/*
+ * COMPLEMENTOF* definitions. These identifiers are used to (de-select)
+ * ciphers normally not being used.
+ * Example: "RC4" will activate all ciphers using RC4 including ciphers
+ * without authentication, which would normally disabled by DEFAULT (due
+ * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT"
+ * will make sure that it is also disabled in the specific selection.
+ * COMPLEMENTOF* identifiers are portable between version, as adjustments
+ * to the default cipher setup will also be included here.
+ *
+ * COMPLEMENTOFDEFAULT does not experience the same special treatment that
+ * DEFAULT gets, as only selection is being done and no sorting as needed
+ * for DEFAULT.
+ */
+#define SSL_TXT_CMPALL		"COMPLEMENTOFALL"
+#define SSL_TXT_CMPDEF		"COMPLEMENTOFDEFAULT"
+
+/* The following cipher list is used by default.
+ * It also is substituted when an application-defined cipher list string
+ * starts with 'DEFAULT'. */
+#define SSL_DEFAULT_CIPHER_LIST	"ALL:!aNULL:!eNULL:!SSLv2"
+/* As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always
+ * starts with a reasonable order, and all we have to do for DEFAULT is
+ * throwing out anonymous and unencrypted ciphersuites!
+ * (The latter are not actually enabled by ALL, but "ALL:RSA" would enable
+ * some of them.)
+ */
+
+/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */
+#define SSL_SENT_SHUTDOWN	1
+#define SSL_RECEIVED_SHUTDOWN	2
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if (defined(OPENSSL_NO_RSA) || defined(OPENSSL_NO_MD5)) && !defined(OPENSSL_NO_SSL2)
+#define OPENSSL_NO_SSL2
+#endif
+
+#define SSL_FILETYPE_ASN1	X509_FILETYPE_ASN1
+#define SSL_FILETYPE_PEM	X509_FILETYPE_PEM
+
+/* This is needed to stop compilers complaining about the
+ * 'struct ssl_st *' function parameters used to prototype callbacks
+ * in SSL_CTX. */
+typedef struct ssl_st *ssl_crock_st;
+typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT;
+
+/* used to hold info on the particular ciphers used */
+typedef struct ssl_cipher_st
+	{
+	int valid;
+	const char *name;		/* text name */
+	unsigned long id;		/* id, 4 bytes, first is version */
+
+	/* changed in 0.9.9: these four used to be portions of a single value 'algorithms' */
+	unsigned long algorithm_mkey;	/* key exchange algorithm */
+	unsigned long algorithm_auth;	/* server authentication */
+	unsigned long algorithm_enc;	/* symmetric encryption */
+	unsigned long algorithm_mac;	/* symmetric authentication */
+	unsigned long algorithm_ssl;	/* (major) protocol version */
+
+	unsigned long algo_strength;	/* strength and export flags */
+	unsigned long algorithm2;	/* Extra flags */
+	int strength_bits;		/* Number of bits really used */
+	int alg_bits;			/* Number of bits for algorithm */
+	} SSL_CIPHER;
+
+DECLARE_STACK_OF(SSL_CIPHER)
+
+typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, int len, void *arg);
+typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg);
+
+/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
+typedef struct ssl_method_st
+	{
+	int version;
+	int (*ssl_new)(SSL *s);
+	void (*ssl_clear)(SSL *s);
+	void (*ssl_free)(SSL *s);
+	int (*ssl_accept)(SSL *s);
+	int (*ssl_connect)(SSL *s);
+	int (*ssl_read)(SSL *s,void *buf,int len);
+	int (*ssl_peek)(SSL *s,void *buf,int len);
+	int (*ssl_write)(SSL *s,const void *buf,int len);
+	int (*ssl_shutdown)(SSL *s);
+	int (*ssl_renegotiate)(SSL *s);
+	int (*ssl_renegotiate_check)(SSL *s);
+	long (*ssl_get_message)(SSL *s, int st1, int stn, int mt, long
+		max, int *ok);
+	int (*ssl_read_bytes)(SSL *s, int type, unsigned char *buf, int len, 
+		int peek);
+	int (*ssl_write_bytes)(SSL *s, int type, const void *buf_, int len);
+	int (*ssl_dispatch_alert)(SSL *s);
+	long (*ssl_ctrl)(SSL *s,int cmd,long larg,void *parg);
+	long (*ssl_ctx_ctrl)(SSL_CTX *ctx,int cmd,long larg,void *parg);
+	const SSL_CIPHER *(*get_cipher_by_char)(const unsigned char *ptr);
+	int (*put_cipher_by_char)(const SSL_CIPHER *cipher,unsigned char *ptr);
+	int (*ssl_pending)(const SSL *s);
+	int (*num_ciphers)(void);
+	const SSL_CIPHER *(*get_cipher)(unsigned ncipher);
+	const struct ssl_method_st *(*get_ssl_method)(int version);
+	long (*get_timeout)(void);
+	struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */
+	int (*ssl_version)(void);
+	long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)(void));
+	long (*ssl_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)(void));
+	} SSL_METHOD;
+
+/* Lets make this into an ASN.1 type structure as follows
+ * SSL_SESSION_ID ::= SEQUENCE {
+ *	version 		INTEGER,	-- structure version number
+ *	SSLversion 		INTEGER,	-- SSL version number
+ *	Cipher 			OCTET STRING,	-- the 3 byte cipher ID
+ *	Session_ID 		OCTET STRING,	-- the Session ID
+ *	Master_key 		OCTET STRING,	-- the master key
+ *	KRB5_principal		OCTET STRING	-- optional Kerberos principal
+ *	Key_Arg [ 0 ] IMPLICIT	OCTET STRING,	-- the optional Key argument
+ *	Time [ 1 ] EXPLICIT	INTEGER,	-- optional Start Time
+ *	Timeout [ 2 ] EXPLICIT	INTEGER,	-- optional Timeout ins seconds
+ *	Peer [ 3 ] EXPLICIT	X509,		-- optional Peer Certificate
+ *	Session_ID_context [ 4 ] EXPLICIT OCTET STRING,   -- the Session ID context
+ *	Verify_result [ 5 ] EXPLICIT INTEGER,   -- X509_V_... code for `Peer'
+ *	HostName [ 6 ] EXPLICIT OCTET STRING,   -- optional HostName from servername TLS extension 
+ *	ECPointFormatList [ 7 ] OCTET STRING,     -- optional EC point format list from TLS extension
+ *	PSK_identity_hint [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity hint
+ *	PSK_identity [ 9 ] EXPLICIT OCTET STRING -- optional PSK identity
+ *	}
+ * Look in ssl/ssl_asn1.c for more details
+ * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-).
+ */
+typedef struct ssl_session_st
+	{
+	int ssl_version;	/* what ssl version session info is
+				 * being kept in here? */
+
+	/* only really used in SSLv2 */
+	unsigned int key_arg_length;
+	unsigned char key_arg[SSL_MAX_KEY_ARG_LENGTH];
+	int master_key_length;
+	unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
+	/* session_id - valid? */
+	unsigned int session_id_length;
+	unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
+	/* this is used to determine whether the session is being reused in
+	 * the appropriate context. It is up to the application to set this,
+	 * via SSL_new */
+	unsigned int sid_ctx_length;
+	unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+
+#ifndef OPENSSL_NO_KRB5
+        unsigned int krb5_client_princ_len;
+        unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH];
+#endif /* OPENSSL_NO_KRB5 */
+#ifndef OPENSSL_NO_PSK
+	char *psk_identity_hint;
+	char *psk_identity;
+#endif
+	int not_resumable;
+
+	/* The cert is the certificate used to establish this connection */
+	struct sess_cert_st /* SESS_CERT */ *sess_cert;
+
+	/* This is the cert for the other end.
+	 * On clients, it will be the same as sess_cert->peer_key->x509
+	 * (the latter is not enough as sess_cert is not retained
+	 * in the external representation of sessions, see ssl_asn1.c). */
+	X509 *peer;
+	/* when app_verify_callback accepts a session where the peer's certificate
+	 * is not ok, we must remember the error for session reuse: */
+	long verify_result; /* only for servers */
+
+	int references;
+	long timeout;
+	long time;
+
+	unsigned int compress_meth;	/* Need to lookup the method */
+
+	const SSL_CIPHER *cipher;
+	unsigned long cipher_id;	/* when ASN.1 loaded, this
+					 * needs to be used to load
+					 * the 'cipher' structure */
+
+	STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */
+
+	CRYPTO_EX_DATA ex_data; /* application specific data */
+
+	/* These are used to make removal of session-ids more
+	 * efficient and to implement a maximum cache size. */
+	struct ssl_session_st *prev,*next;
+#ifndef OPENSSL_NO_TLSEXT
+	char *tlsext_hostname;
+#ifndef OPENSSL_NO_EC
+	size_t tlsext_ecpointformatlist_length;
+	unsigned char *tlsext_ecpointformatlist; /* peer's list */
+	size_t tlsext_ellipticcurvelist_length;
+	unsigned char *tlsext_ellipticcurvelist; /* peer's list */
+#endif /* OPENSSL_NO_EC */
+	/* RFC4507 info */
+	unsigned char *tlsext_tick;	/* Session ticket */
+	size_t	tlsext_ticklen;		/* Session ticket length */	
+	long tlsext_tick_lifetime_hint;	/* Session lifetime hint in seconds */
+#endif
+	} SSL_SESSION;
+
+
+#define SSL_OP_MICROSOFT_SESS_ID_BUG			0x00000001L
+#define SSL_OP_NETSCAPE_CHALLENGE_BUG			0x00000002L
+/* Allow initial connection to servers that don't support RI */
+#define SSL_OP_LEGACY_SERVER_CONNECT			0x00000004L
+#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG		0x00000008L
+#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG		0x00000010L
+#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER		0x00000020L
+#define SSL_OP_MSIE_SSLV2_RSA_PADDING			0x00000040L /* no effect since 0.9.7h and 0.9.8b */
+#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG			0x00000080L
+#define SSL_OP_TLS_D5_BUG				0x00000100L
+#define SSL_OP_TLS_BLOCK_PADDING_BUG			0x00000200L
+
+/* Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added
+ * in OpenSSL 0.9.6d.  Usually (depending on the application protocol)
+ * the workaround is not needed.  Unfortunately some broken SSL/TLS
+ * implementations cannot handle it at all, which is why we include
+ * it in SSL_OP_ALL. */
+#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS              0x00000800L /* added in 0.9.6e */
+
+/* SSL_OP_ALL: various bug workarounds that should be rather harmless.
+ *             This used to be 0x000FFFFFL before 0.9.7. */
+#define SSL_OP_ALL					0x80000FFFL
+
+/* DTLS options */
+#define SSL_OP_NO_QUERY_MTU                 0x00001000L
+/* Turn on Cookie Exchange (on relevant for servers) */
+#define SSL_OP_COOKIE_EXCHANGE              0x00002000L
+/* Don't use RFC4507 ticket extension */
+#define SSL_OP_NO_TICKET	            0x00004000L
+/* Use Cisco's "speshul" version of DTLS_BAD_VER (as client)  */
+#define SSL_OP_CISCO_ANYCONNECT		    0x00008000L
+
+/* As server, disallow session resumption on renegotiation */
+#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION	0x00010000L
+/* Don't use compression even if supported */
+#define SSL_OP_NO_COMPRESSION				0x00020000L
+/* Permit unsafe legacy renegotiation */
+#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION	0x00040000L
+/* If set, always create a new key when using tmp_ecdh parameters */
+#define SSL_OP_SINGLE_ECDH_USE				0x00080000L
+/* If set, always create a new key when using tmp_dh parameters */
+#define SSL_OP_SINGLE_DH_USE				0x00100000L
+/* Set to always use the tmp_rsa key when doing RSA operations,
+ * even when this violates protocol specs */
+#define SSL_OP_EPHEMERAL_RSA				0x00200000L
+/* Set on servers to choose the cipher according to the server's
+ * preferences */
+#define SSL_OP_CIPHER_SERVER_PREFERENCE			0x00400000L
+/* If set, a server will allow a client to issue a SSLv3.0 version number
+ * as latest version supported in the premaster secret, even when TLSv1.0
+ * (version 3.1) was announced in the client hello. Normally this is
+ * forbidden to prevent version rollback attacks. */
+#define SSL_OP_TLS_ROLLBACK_BUG				0x00800000L
+
+#define SSL_OP_NO_SSLv2					0x01000000L
+#define SSL_OP_NO_SSLv3					0x02000000L
+#define SSL_OP_NO_TLSv1					0x04000000L
+
+/* The next flag deliberately changes the ciphertest, this is a check
+ * for the PKCS#1 attack */
+#define SSL_OP_PKCS1_CHECK_1				0x08000000L
+#define SSL_OP_PKCS1_CHECK_2				0x10000000L
+#define SSL_OP_NETSCAPE_CA_DN_BUG			0x20000000L
+#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG		0x40000000L
+/* Make server add server-hello extension from early version of
+ * cryptopro draft, when GOST ciphersuite is negotiated. 
+ * Required for interoperability with CryptoPro CSP 3.x 
+ */
+#define SSL_OP_CRYPTOPRO_TLSEXT_BUG			0x80000000L
+
+/* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success
+ * when just a single record has been written): */
+#define SSL_MODE_ENABLE_PARTIAL_WRITE       0x00000001L
+/* Make it possible to retry SSL_write() with changed buffer location
+ * (buffer contents must stay the same!); this is not the default to avoid
+ * the misconception that non-blocking SSL_write() behaves like
+ * non-blocking write(): */
+#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L
+/* Never bother the application with retries if the transport
+ * is blocking: */
+#define SSL_MODE_AUTO_RETRY 0x00000004L
+/* Don't attempt to automatically build certificate chain */
+#define SSL_MODE_NO_AUTO_CHAIN 0x00000008L
+/* Save RAM by releasing read and write buffers when they're empty. (SSL3 and
+ * TLS only.)  "Released" buffers are put onto a free-list in the context
+ * or just freed (depending on the context's setting for freelist_max_len). */
+#define SSL_MODE_RELEASE_BUFFERS 0x00000010L
+/* Use small read and write buffers: (a) lazy allocate read buffers for
+ * large incoming records, and (b) limit the size of outgoing records. */
+#define SSL_MODE_SMALL_BUFFERS 0x00000020L
+/* When set, clients may send application data before receipt of CCS
+ * and Finished.  This mode enables full-handshakes to 'complete' in
+ * one RTT. */
+#define SSL_MODE_HANDSHAKE_CUTTHROUGH 0x00000040L
+
+/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
+ * they cannot be used to clear bits. */
+
+#define SSL_CTX_set_options(ctx,op) \
+	SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
+#define SSL_CTX_clear_options(ctx,op) \
+	SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_OPTIONS,(op),NULL)
+#define SSL_CTX_get_options(ctx) \
+	SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL)
+#define SSL_set_options(ssl,op) \
+	SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL)
+#define SSL_clear_options(ssl,op) \
+	SSL_ctrl((ssl),SSL_CTRL_CLEAR_OPTIONS,(op),NULL)
+#define SSL_get_options(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_OPTIONS,0,NULL)
+
+#define SSL_CTX_set_mode(ctx,op) \
+	SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
+#define SSL_CTX_clear_mode(ctx,op) \
+	SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL)
+#define SSL_CTX_get_mode(ctx) \
+	SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL)
+#define SSL_clear_mode(ssl,op) \
+	SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL)
+#define SSL_set_mode(ssl,op) \
+	SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL)
+#define SSL_get_mode(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL)
+#define SSL_set_mtu(ssl, mtu) \
+        SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL)
+
+#define SSL_get_secure_renegotiation_support(ssl) \
+	SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL)
+
+void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
+void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
+#define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
+#define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
+
+
+
+#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
+#define SSL_MAX_CERT_LIST_DEFAULT 1024*30 /* 30k max cert list :-) */
+#else
+#define SSL_MAX_CERT_LIST_DEFAULT 1024*100 /* 100k max cert list :-) */
+#endif
+
+#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT	(1024*20)
+
+/* This callback type is used inside SSL_CTX, SSL, and in the functions that set
+ * them. It is used to override the generation of SSL/TLS session IDs in a
+ * server. Return value should be zero on an error, non-zero to proceed. Also,
+ * callbacks should themselves check if the id they generate is unique otherwise
+ * the SSL handshake will fail with an error - callbacks can do this using the
+ * 'ssl' value they're passed by;
+ *      SSL_has_matching_session_id(ssl, id, *id_len)
+ * The length value passed in is set at the maximum size the session ID can be.
+ * In SSLv2 this is 16 bytes, whereas SSLv3/TLSv1 it is 32 bytes. The callback
+ * can alter this length to be less if desired, but under SSLv2 session IDs are
+ * supposed to be fixed at 16 bytes so the id will be padded after the callback
+ * returns in this case. It is also an error for the callback to set the size to
+ * zero. */
+typedef int (*GEN_SESSION_CB)(const SSL *ssl, unsigned char *id,
+				unsigned int *id_len);
+
+typedef struct ssl_comp_st
+	{
+	int id;
+	const char *name;
+#ifndef OPENSSL_NO_COMP
+	COMP_METHOD *method;
+#else
+	char *method;
+#endif
+	} SSL_COMP;
+
+DECLARE_STACK_OF(SSL_COMP)
+DECLARE_LHASH_OF(SSL_SESSION);
+
+struct ssl_ctx_st
+	{
+	const SSL_METHOD *method;
+
+	STACK_OF(SSL_CIPHER) *cipher_list;
+	/* same as above but sorted for lookup */
+	STACK_OF(SSL_CIPHER) *cipher_list_by_id;
+
+	struct x509_store_st /* X509_STORE */ *cert_store;
+	LHASH_OF(SSL_SESSION) *sessions;
+	/* Most session-ids that will be cached, default is
+	 * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. */
+	unsigned long session_cache_size;
+	struct ssl_session_st *session_cache_head;
+	struct ssl_session_st *session_cache_tail;
+
+	/* This can have one of 2 values, ored together,
+	 * SSL_SESS_CACHE_CLIENT,
+	 * SSL_SESS_CACHE_SERVER,
+	 * Default is SSL_SESSION_CACHE_SERVER, which means only
+	 * SSL_accept which cache SSL_SESSIONS. */
+	int session_cache_mode;
+
+	/* If timeout is not 0, it is the default timeout value set
+	 * when SSL_new() is called.  This has been put in to make
+	 * life easier to set things up */
+	long session_timeout;
+
+	/* If this callback is not null, it will be called each
+	 * time a session id is added to the cache.  If this function
+	 * returns 1, it means that the callback will do a
+	 * SSL_SESSION_free() when it has finished using it.  Otherwise,
+	 * on 0, it means the callback has finished with it.
+	 * If remove_session_cb is not null, it will be called when
+	 * a session-id is removed from the cache.  After the call,
+	 * OpenSSL will SSL_SESSION_free() it. */
+	int (*new_session_cb)(struct ssl_st *ssl,SSL_SESSION *sess);
+	void (*remove_session_cb)(struct ssl_ctx_st *ctx,SSL_SESSION *sess);
+	SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl,
+		unsigned char *data,int len,int *copy);
+
+	struct
+		{
+		int sess_connect;	/* SSL new conn - started */
+		int sess_connect_renegotiate;/* SSL reneg - requested */
+		int sess_connect_good;	/* SSL new conne/reneg - finished */
+		int sess_accept;	/* SSL new accept - started */
+		int sess_accept_renegotiate;/* SSL reneg - requested */
+		int sess_accept_good;	/* SSL accept/reneg - finished */
+		int sess_miss;		/* session lookup misses  */
+		int sess_timeout;	/* reuse attempt on timeouted session */
+		int sess_cache_full;	/* session removed due to full cache */
+		int sess_hit;		/* session reuse actually done */
+		int sess_cb_hit;	/* session-id that was not
+					 * in the cache was
+					 * passed back via the callback.  This
+					 * indicates that the application is
+					 * supplying session-id's from other
+					 * processes - spooky :-) */
+		} stats;
+
+	int references;
+
+	/* if defined, these override the X509_verify_cert() calls */
+	int (*app_verify_callback)(X509_STORE_CTX *, void *);
+	void *app_verify_arg;
+	/* before OpenSSL 0.9.7, 'app_verify_arg' was ignored
+	 * ('app_verify_callback' was called with just one argument) */
+
+	/* Default password callback. */
+	pem_password_cb *default_passwd_callback;
+
+	/* Default password callback user data. */
+	void *default_passwd_callback_userdata;
+
+	/* get client cert callback */
+	int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+
+    /* cookie generate callback */
+    int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, 
+        unsigned int *cookie_len);
+
+    /* verify cookie callback */
+    int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, 
+        unsigned int cookie_len);
+
+	CRYPTO_EX_DATA ex_data;
+
+	const EVP_MD *rsa_md5;/* For SSLv2 - name is 'ssl2-md5' */
+	const EVP_MD *md5;	/* For SSLv3/TLSv1 'ssl3-md5' */
+	const EVP_MD *sha1;   /* For SSLv3/TLSv1 'ssl3->sha1' */
+
+	STACK_OF(X509) *extra_certs;
+	STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */
+
+
+	/* Default values used when no per-SSL value is defined follow */
+
+	void (*info_callback)(const SSL *ssl,int type,int val); /* used if SSL's info_callback is NULL */
+
+	/* what we put in client cert requests */
+	STACK_OF(X509_NAME) *client_CA;
+
+
+	/* Default values to use in SSL structures follow (these are copied by SSL_new) */
+
+	unsigned long options;
+	unsigned long mode;
+	long max_cert_list;
+
+	struct cert_st /* CERT */ *cert;
+	int read_ahead;
+
+	/* callback that allows applications to peek at protocol messages */
+	void (*msg_callback)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg);
+	void *msg_callback_arg;
+
+	int verify_mode;
+	unsigned int sid_ctx_length;
+	unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+	int (*default_verify_callback)(int ok,X509_STORE_CTX *ctx); /* called 'verify_callback' in the SSL */
+
+	/* Default generate session ID callback. */
+	GEN_SESSION_CB generate_session_id;
+
+	X509_VERIFY_PARAM *param;
+
+#if 0
+	int purpose;		/* Purpose setting */
+	int trust;		/* Trust setting */
+#endif
+
+	int quiet_shutdown;
+
+	/* Maximum amount of data to send in one fragment.
+	 * actual record size can be more than this due to
+	 * padding and MAC overheads.
+	 */
+	unsigned int max_send_fragment;
+
+#ifndef OPENSSL_ENGINE
+	/* Engine to pass requests for client certs to
+	 */
+	ENGINE *client_cert_engine;
+#endif
+
+#ifndef OPENSSL_NO_TLSEXT
+	/* TLS extensions servername callback */
+	int (*tlsext_servername_callback)(SSL*, int *, void *);
+	void *tlsext_servername_arg;
+	/* RFC 4507 session ticket keys */
+	unsigned char tlsext_tick_key_name[16];
+	unsigned char tlsext_tick_hmac_key[16];
+	unsigned char tlsext_tick_aes_key[16];
+	/* Callback to support customisation of ticket key setting */
+	int (*tlsext_ticket_key_cb)(SSL *ssl,
+					unsigned char *name, unsigned char *iv,
+					EVP_CIPHER_CTX *ectx,
+ 					HMAC_CTX *hctx, int enc);
+
+	/* certificate status request info */
+	/* Callback for status request */
+	int (*tlsext_status_cb)(SSL *ssl, void *arg);
+	void *tlsext_status_arg;
+
+	/* draft-rescorla-tls-opaque-prf-input-00.txt information */
+	int (*tlsext_opaque_prf_input_callback)(SSL *, void *peerinput, size_t len, void *arg);
+	void *tlsext_opaque_prf_input_callback_arg;
+
+# ifndef OPENSSL_NO_NEXTPROTONEG
+	/* Next protocol negotiation information */
+	/* (for experimental NPN extension). */
+
+	/* For a server, this contains a callback function by which the set of
+	 * advertised protocols can be provided. */
+	int (*next_protos_advertised_cb)(SSL *s, const unsigned char **buf,
+			                 unsigned int *len, void *arg);
+	void *next_protos_advertised_cb_arg;
+	/* For a client, this contains a callback function that selects the
+	 * next protocol from the list provided by the server. */
+	int (*next_proto_select_cb)(SSL *s, unsigned char **out,
+				    unsigned char *outlen,
+				    const unsigned char *in,
+				    unsigned int inlen,
+				    void *arg);
+	void *next_proto_select_cb_arg;
+# endif
+#endif
+
+#ifndef OPENSSL_NO_PSK
+	char *psk_identity_hint;
+	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, char *identity,
+		unsigned int max_identity_len, unsigned char *psk,
+		unsigned int max_psk_len);
+	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
+		unsigned char *psk, unsigned int max_psk_len);
+#endif
+
+#ifndef OPENSSL_NO_BUF_FREELISTS
+#define SSL_MAX_BUF_FREELIST_LEN_DEFAULT 32
+	unsigned int freelist_max_len;
+	struct ssl3_buf_freelist_st *wbuf_freelist;
+	struct ssl3_buf_freelist_st *rbuf_freelist;
+#endif
+	};
+
+#define SSL_SESS_CACHE_OFF			0x0000
+#define SSL_SESS_CACHE_CLIENT			0x0001
+#define SSL_SESS_CACHE_SERVER			0x0002
+#define SSL_SESS_CACHE_BOTH	(SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER)
+#define SSL_SESS_CACHE_NO_AUTO_CLEAR		0x0080
+/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */
+#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP	0x0100
+#define SSL_SESS_CACHE_NO_INTERNAL_STORE	0x0200
+#define SSL_SESS_CACHE_NO_INTERNAL \
+	(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE)
+
+LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
+#define SSL_CTX_sess_number(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL)
+#define SSL_CTX_sess_connect(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL)
+#define SSL_CTX_sess_connect_good(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL)
+#define SSL_CTX_sess_connect_renegotiate(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL)
+#define SSL_CTX_sess_accept(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL)
+#define SSL_CTX_sess_accept_renegotiate(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL)
+#define SSL_CTX_sess_accept_good(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL)
+#define SSL_CTX_sess_hits(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL)
+#define SSL_CTX_sess_cb_hits(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL)
+#define SSL_CTX_sess_misses(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL)
+#define SSL_CTX_sess_timeouts(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL)
+#define SSL_CTX_sess_cache_full(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL)
+
+void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, int (*new_session_cb)(struct ssl_st *ssl,SSL_SESSION *sess));
+int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl, SSL_SESSION *sess);
+void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, void (*remove_session_cb)(struct ssl_ctx_st *ctx,SSL_SESSION *sess));
+void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(struct ssl_ctx_st *ctx, SSL_SESSION *sess);
+void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl, unsigned char *data,int len,int *copy));
+SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(struct ssl_st *ssl, unsigned char *Data, int len, int *copy);
+void SSL_CTX_set_info_callback(SSL_CTX *ctx, void (*cb)(const SSL *ssl,int type,int val));
+void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val);
+void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
+int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+#ifndef OPENSSL_NO_ENGINE
+int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e);
+#endif
+void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len));
+void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len));
+#ifndef OPENSSL_NO_NEXTPROTONEG
+void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s,
+					   int (*cb) (SSL *ssl,
+						      const unsigned char **out,
+						      unsigned int *outlen,
+						      void *arg), void *arg);
+void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s,
+				      int (*cb) (SSL *ssl, unsigned char **out,
+						 unsigned char *outlen,
+						 const unsigned char *in,
+						 unsigned int inlen, void *arg),
+				      void *arg);
+
+int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
+			  const unsigned char *in, unsigned int inlen,
+			  const unsigned char *client, unsigned int client_len);
+void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
+				    unsigned *len);
+
+#define OPENSSL_NPN_UNSUPPORTED	0
+#define OPENSSL_NPN_NEGOTIATED	1
+#define OPENSSL_NPN_NO_OVERLAP	2
+
+#endif
+
+#ifndef OPENSSL_NO_PSK
+/* the maximum length of the buffer given to callbacks containing the
+ * resulting identity/psk */
+#define PSK_MAX_IDENTITY_LEN 128
+#define PSK_MAX_PSK_LEN 256
+void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, 
+	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, 
+		char *identity, unsigned int max_identity_len, unsigned char *psk,
+		unsigned int max_psk_len));
+void SSL_set_psk_client_callback(SSL *ssl, 
+	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, 
+		char *identity, unsigned int max_identity_len, unsigned char *psk,
+		unsigned int max_psk_len));
+void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, 
+	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
+		unsigned char *psk, unsigned int max_psk_len));
+void SSL_set_psk_server_callback(SSL *ssl,
+	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
+		unsigned char *psk, unsigned int max_psk_len));
+int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint);
+int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint);
+const char *SSL_get_psk_identity_hint(const SSL *s);
+const char *SSL_get_psk_identity(const SSL *s);
+#endif
+
+#define SSL_NOTHING	1
+#define SSL_WRITING	2
+#define SSL_READING	3
+#define SSL_X509_LOOKUP	4
+
+/* These will only be used when doing non-blocking IO */
+#define SSL_want_nothing(s)	(SSL_want(s) == SSL_NOTHING)
+#define SSL_want_read(s)	(SSL_want(s) == SSL_READING)
+#define SSL_want_write(s)	(SSL_want(s) == SSL_WRITING)
+#define SSL_want_x509_lookup(s)	(SSL_want(s) == SSL_X509_LOOKUP)
+
+#define SSL_MAC_FLAG_READ_MAC_STREAM 1
+#define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
+
+struct ssl_st
+	{
+	/* protocol version
+	 * (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, DTLS1_VERSION)
+	 */
+	int version;
+	int type; /* SSL_ST_CONNECT or SSL_ST_ACCEPT */
+
+	const SSL_METHOD *method; /* SSLv3 */
+
+	/* There are 2 BIO's even though they are normally both the
+	 * same.  This is so data can be read and written to different
+	 * handlers */
+
+#ifndef OPENSSL_NO_BIO
+	BIO *rbio; /* used by SSL_read */
+	BIO *wbio; /* used by SSL_write */
+	BIO *bbio; /* used during session-id reuse to concatenate
+		    * messages */
+#else
+	char *rbio; /* used by SSL_read */
+	char *wbio; /* used by SSL_write */
+	char *bbio;
+#endif
+	/* This holds a variable that indicates what we were doing
+	 * when a 0 or -1 is returned.  This is needed for
+	 * non-blocking IO so we know what request needs re-doing when
+	 * in SSL_accept or SSL_connect */
+	int rwstate;
+
+	/* true when we are actually in SSL_accept() or SSL_connect() */
+	int in_handshake;
+	int (*handshake_func)(SSL *);
+
+	/* Imagine that here's a boolean member "init" that is
+	 * switched as soon as SSL_set_{accept/connect}_state
+	 * is called for the first time, so that "state" and
+	 * "handshake_func" are properly initialized.  But as
+	 * handshake_func is == 0 until then, we use this
+	 * test instead of an "init" member.
+	 */
+
+	int server;	/* are we the server side? - mostly used by SSL_clear*/
+
+	int new_session;/* 1 if we are to use a new session.
+	                 * 2 if we are a server and are inside a handshake
+	                 *   (i.e. not just sending a HelloRequest)
+	                 * NB: For servers, the 'new' session may actually be a previously
+	                 * cached session or even the previous session unless
+	                 * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */
+	int quiet_shutdown;/* don't send shutdown packets */
+	int shutdown;	/* we have shut things down, 0x01 sent, 0x02
+			 * for received */
+	int state;	/* where we are */
+	int rstate;	/* where we are when reading */
+
+	BUF_MEM *init_buf;	/* buffer used during init */
+	void *init_msg;   	/* pointer to handshake message body, set by ssl3_get_message() */
+	int init_num;		/* amount read/written */
+	int init_off;		/* amount read/written */
+
+	/* used internally to point at a raw packet */
+	unsigned char *packet;
+	unsigned int packet_length;
+
+	struct ssl2_state_st *s2; /* SSLv2 variables */
+	struct ssl3_state_st *s3; /* SSLv3 variables */
+	struct dtls1_state_st *d1; /* DTLSv1 variables */
+
+	int read_ahead;		/* Read as many input bytes as possible
+	               	 	 * (for non-blocking reads) */
+
+	/* callback that allows applications to peek at protocol messages */
+	void (*msg_callback)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg);
+	void *msg_callback_arg;
+
+	int hit;		/* reusing a previous session */
+
+	X509_VERIFY_PARAM *param;
+
+#if 0
+	int purpose;		/* Purpose setting */
+	int trust;		/* Trust setting */
+#endif
+
+	/* crypto */
+	STACK_OF(SSL_CIPHER) *cipher_list;
+	STACK_OF(SSL_CIPHER) *cipher_list_by_id;
+
+	/* These are the ones being used, the ones in SSL_SESSION are
+	 * the ones to be 'copied' into these ones */
+	int mac_flags; 
+	EVP_CIPHER_CTX *enc_read_ctx;		/* cryptographic state */
+	EVP_MD_CTX *read_hash;		/* used for mac generation */
+#ifndef OPENSSL_NO_COMP
+	COMP_CTX *expand;			/* uncompress */
+#else
+	char *expand;
+#endif
+
+	EVP_CIPHER_CTX *enc_write_ctx;		/* cryptographic state */
+	EVP_MD_CTX *write_hash;		/* used for mac generation */
+#ifndef OPENSSL_NO_COMP
+	COMP_CTX *compress;			/* compression */
+#else
+	char *compress;	
+#endif
+
+	/* session info */
+
+	/* client cert? */
+	/* This is used to hold the server certificate used */
+	struct cert_st /* CERT */ *cert;
+
+	/* the session_id_context is used to ensure sessions are only reused
+	 * in the appropriate context */
+	unsigned int sid_ctx_length;
+	unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+
+	/* This can also be in the session once a session is established */
+	SSL_SESSION *session;
+
+        /* This can be disabled to prevent the use of uncached sessions */
+	int session_creation_enabled;
+
+	/* Default generate session ID callback. */
+	GEN_SESSION_CB generate_session_id;
+
+	/* Used in SSL2 and SSL3 */
+	int verify_mode;	/* 0 don't care about verify failure.
+				 * 1 fail if verify fails */
+	int (*verify_callback)(int ok,X509_STORE_CTX *ctx); /* fail if callback returns 0 */
+
+	void (*info_callback)(const SSL *ssl,int type,int val); /* optional informational callback */
+
+	int error;		/* error bytes to be written */
+	int error_code;		/* actual code */
+
+#ifndef OPENSSL_NO_KRB5
+	KSSL_CTX *kssl_ctx;     /* Kerberos 5 context */
+#endif	/* OPENSSL_NO_KRB5 */
+
+#ifndef OPENSSL_NO_PSK
+	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, char *identity,
+		unsigned int max_identity_len, unsigned char *psk,
+		unsigned int max_psk_len);
+	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
+		unsigned char *psk, unsigned int max_psk_len);
+#endif
+
+	SSL_CTX *ctx;
+	/* set this flag to 1 and a sleep(1) is put into all SSL_read()
+	 * and SSL_write() calls, good for nbio debuging :-) */
+	int debug;	
+
+	/* extra application data */
+	long verify_result;
+	CRYPTO_EX_DATA ex_data;
+
+	/* for server side, keep the list of CA_dn we can use */
+	STACK_OF(X509_NAME) *client_CA;
+
+	int references;
+	unsigned long options; /* protocol behaviour */
+	unsigned long mode; /* API behaviour */
+	long max_cert_list;
+	int first_packet;
+	int client_version;	/* what was passed, used for
+				 * SSLv3/TLS rollback check */
+	unsigned int max_send_fragment;
+#ifndef OPENSSL_NO_TLSEXT
+	/* TLS extension debug callback */
+	void (*tlsext_debug_cb)(SSL *s, int client_server, int type,
+					unsigned char *data, int len,
+					void *arg);
+	void *tlsext_debug_arg;
+	char *tlsext_hostname;
+	int servername_done;   /* no further mod of servername 
+	                          0 : call the servername extension callback.
+	                          1 : prepare 2, allow last ack just after in server callback.
+	                          2 : don't call servername callback, no ack in server hello
+	                       */
+	/* certificate status request info */
+	/* Status type or -1 if no status type */
+	int tlsext_status_type;
+	/* Expect OCSP CertificateStatus message */
+	int tlsext_status_expected;
+	/* OCSP status request only */
+	STACK_OF(OCSP_RESPID) *tlsext_ocsp_ids;
+	X509_EXTENSIONS *tlsext_ocsp_exts;
+	/* OCSP response received or to be sent */
+	unsigned char *tlsext_ocsp_resp;
+	int tlsext_ocsp_resplen;
+
+	/* RFC4507 session ticket expected to be received or sent */
+	int tlsext_ticket_expected;
+#ifndef OPENSSL_NO_EC
+	size_t tlsext_ecpointformatlist_length;
+	unsigned char *tlsext_ecpointformatlist; /* our list */
+	size_t tlsext_ellipticcurvelist_length;
+	unsigned char *tlsext_ellipticcurvelist; /* our list */
+#endif /* OPENSSL_NO_EC */
+
+	/* draft-rescorla-tls-opaque-prf-input-00.txt information to be used for handshakes */
+	void *tlsext_opaque_prf_input;
+	size_t tlsext_opaque_prf_input_len;
+
+	/* TLS Session Ticket extension override */
+	TLS_SESSION_TICKET_EXT *tlsext_session_ticket;
+
+	/* TLS Session Ticket extension callback */
+	tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb;
+	void *tls_session_ticket_ext_cb_arg;
+
+	/* TLS pre-shared secret session resumption */
+	tls_session_secret_cb_fn tls_session_secret_cb;
+	void *tls_session_secret_cb_arg;
+
+	SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+	/* Next protocol negotiation. For the client, this is the protocol that
+	 * we sent in NextProtocol and is set when handling ServerHello
+	 * extensions.
+	 *
+	 * For a server, this is the client's selected_protocol from
+	 * NextProtocol and is set when handling the NextProtocol message,
+	 * before the Finished message. */
+	unsigned char *next_proto_negotiated;
+	unsigned char next_proto_negotiated_len;
+#endif
+
+#define session_ctx initial_ctx
+#else
+#define session_ctx ctx
+#endif /* OPENSSL_NO_TLSEXT */
+	};
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <openssl/ssl2.h>
+#include <openssl/ssl3.h>
+#include <openssl/tls1.h> /* This is mostly sslv3 with a few tweaks */
+#include <openssl/dtls1.h> /* Datagram TLS */
+#include <openssl/ssl23.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* compatibility */
+#define SSL_set_app_data(s,arg)		(SSL_set_ex_data(s,0,(char *)arg))
+#define SSL_get_app_data(s)		(SSL_get_ex_data(s,0))
+#define SSL_SESSION_set_app_data(s,a)	(SSL_SESSION_set_ex_data(s,0,(char *)a))
+#define SSL_SESSION_get_app_data(s)	(SSL_SESSION_get_ex_data(s,0))
+#define SSL_CTX_get_app_data(ctx)	(SSL_CTX_get_ex_data(ctx,0))
+#define SSL_CTX_set_app_data(ctx,arg)	(SSL_CTX_set_ex_data(ctx,0,(char *)arg))
+
+/* The following are the possible values for ssl->state are are
+ * used to indicate where we are up to in the SSL connection establishment.
+ * The macros that follow are about the only things you should need to use
+ * and even then, only when using non-blocking IO.
+ * It can also be useful to work out where you were when the connection
+ * failed */
+
+#define SSL_ST_CONNECT			0x1000
+#define SSL_ST_ACCEPT			0x2000
+#define SSL_ST_MASK			0x0FFF
+#define SSL_ST_INIT			(SSL_ST_CONNECT|SSL_ST_ACCEPT)
+#define SSL_ST_BEFORE			0x4000
+#define SSL_ST_OK			0x03
+#define SSL_ST_RENEGOTIATE		(0x04|SSL_ST_INIT)
+
+#define SSL_CB_LOOP			0x01
+#define SSL_CB_EXIT			0x02
+#define SSL_CB_READ			0x04
+#define SSL_CB_WRITE			0x08
+#define SSL_CB_ALERT			0x4000 /* used in callback */
+#define SSL_CB_READ_ALERT		(SSL_CB_ALERT|SSL_CB_READ)
+#define SSL_CB_WRITE_ALERT		(SSL_CB_ALERT|SSL_CB_WRITE)
+#define SSL_CB_ACCEPT_LOOP		(SSL_ST_ACCEPT|SSL_CB_LOOP)
+#define SSL_CB_ACCEPT_EXIT		(SSL_ST_ACCEPT|SSL_CB_EXIT)
+#define SSL_CB_CONNECT_LOOP		(SSL_ST_CONNECT|SSL_CB_LOOP)
+#define SSL_CB_CONNECT_EXIT		(SSL_ST_CONNECT|SSL_CB_EXIT)
+#define SSL_CB_HANDSHAKE_START		0x10
+#define SSL_CB_HANDSHAKE_DONE		0x20
+
+/* Is the SSL_connection established? */
+#define SSL_get_state(a)		SSL_state(a)
+#define SSL_is_init_finished(a)		(SSL_state(a) == SSL_ST_OK)
+#define SSL_in_init(a)			((SSL_state(a)&SSL_ST_INIT) && \
+                                  !SSL_cutthrough_complete(a))
+#define SSL_in_before(a)		(SSL_state(a)&SSL_ST_BEFORE)
+#define SSL_in_connect_init(a)		(SSL_state(a)&SSL_ST_CONNECT)
+#define SSL_in_accept_init(a)		(SSL_state(a)&SSL_ST_ACCEPT)
+int SSL_cutthrough_complete(const SSL *s);
+
+/* The following 2 states are kept in ssl->rstate when reads fail,
+ * you should not need these */
+#define SSL_ST_READ_HEADER			0xF0
+#define SSL_ST_READ_BODY			0xF1
+#define SSL_ST_READ_DONE			0xF2
+
+/* Obtain latest Finished message
+ *   -- that we sent (SSL_get_finished)
+ *   -- that we expected from peer (SSL_get_peer_finished).
+ * Returns length (0 == no Finished so far), copies up to 'count' bytes. */
+size_t SSL_get_finished(const SSL *s, void *buf, size_t count);
+size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
+
+/* use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options
+ * are 'ored' with SSL_VERIFY_PEER if they are desired */
+#define SSL_VERIFY_NONE			0x00
+#define SSL_VERIFY_PEER			0x01
+#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT	0x02
+#define SSL_VERIFY_CLIENT_ONCE		0x04
+
+#define OpenSSL_add_ssl_algorithms()	SSL_library_init()
+#define SSLeay_add_ssl_algorithms()	SSL_library_init()
+
+/* this is for backward compatibility */
+#if 0 /* NEW_SSLEAY */
+#define SSL_CTX_set_default_verify(a,b,c) SSL_CTX_set_verify(a,b,c)
+#define SSL_set_pref_cipher(c,n)	SSL_set_cipher_list(c,n)
+#define SSL_add_session(a,b)            SSL_CTX_add_session((a),(b))
+#define SSL_remove_session(a,b)		SSL_CTX_remove_session((a),(b))
+#define SSL_flush_sessions(a,b)		SSL_CTX_flush_sessions((a),(b))
+#endif
+/* More backward compatibility */
+#define SSL_get_cipher(s) \
+		SSL_CIPHER_get_name(SSL_get_current_cipher(s))
+#define SSL_get_cipher_bits(s,np) \
+		SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np)
+#define SSL_get_cipher_version(s) \
+		SSL_CIPHER_get_version(SSL_get_current_cipher(s))
+#define SSL_get_cipher_name(s) \
+		SSL_CIPHER_get_name(SSL_get_current_cipher(s))
+#define SSL_get_time(a)		SSL_SESSION_get_time(a)
+#define SSL_set_time(a,b)	SSL_SESSION_set_time((a),(b))
+#define SSL_get_timeout(a)	SSL_SESSION_get_timeout(a)
+#define SSL_set_timeout(a,b)	SSL_SESSION_set_timeout((a),(b))
+
+#define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id)
+#define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id)
+
+DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
+
+#define SSL_AD_REASON_OFFSET		1000 /* offset to get SSL_R_... value from SSL_AD_... */
+
+/* These alert types are for SSLv3 and TLSv1 */
+#define SSL_AD_CLOSE_NOTIFY		SSL3_AD_CLOSE_NOTIFY
+#define SSL_AD_UNEXPECTED_MESSAGE	SSL3_AD_UNEXPECTED_MESSAGE /* fatal */
+#define SSL_AD_BAD_RECORD_MAC		SSL3_AD_BAD_RECORD_MAC     /* fatal */
+#define SSL_AD_DECRYPTION_FAILED	TLS1_AD_DECRYPTION_FAILED
+#define SSL_AD_RECORD_OVERFLOW		TLS1_AD_RECORD_OVERFLOW
+#define SSL_AD_DECOMPRESSION_FAILURE	SSL3_AD_DECOMPRESSION_FAILURE/* fatal */
+#define SSL_AD_HANDSHAKE_FAILURE	SSL3_AD_HANDSHAKE_FAILURE/* fatal */
+#define SSL_AD_NO_CERTIFICATE		SSL3_AD_NO_CERTIFICATE /* Not for TLS */
+#define SSL_AD_BAD_CERTIFICATE		SSL3_AD_BAD_CERTIFICATE
+#define SSL_AD_UNSUPPORTED_CERTIFICATE	SSL3_AD_UNSUPPORTED_CERTIFICATE
+#define SSL_AD_CERTIFICATE_REVOKED	SSL3_AD_CERTIFICATE_REVOKED
+#define SSL_AD_CERTIFICATE_EXPIRED	SSL3_AD_CERTIFICATE_EXPIRED
+#define SSL_AD_CERTIFICATE_UNKNOWN	SSL3_AD_CERTIFICATE_UNKNOWN
+#define SSL_AD_ILLEGAL_PARAMETER	SSL3_AD_ILLEGAL_PARAMETER   /* fatal */
+#define SSL_AD_UNKNOWN_CA		TLS1_AD_UNKNOWN_CA	/* fatal */
+#define SSL_AD_ACCESS_DENIED		TLS1_AD_ACCESS_DENIED	/* fatal */
+#define SSL_AD_DECODE_ERROR		TLS1_AD_DECODE_ERROR	/* fatal */
+#define SSL_AD_DECRYPT_ERROR		TLS1_AD_DECRYPT_ERROR
+#define SSL_AD_EXPORT_RESTRICTION	TLS1_AD_EXPORT_RESTRICTION/* fatal */
+#define SSL_AD_PROTOCOL_VERSION		TLS1_AD_PROTOCOL_VERSION /* fatal */
+#define SSL_AD_INSUFFICIENT_SECURITY	TLS1_AD_INSUFFICIENT_SECURITY/* fatal */
+#define SSL_AD_INTERNAL_ERROR		TLS1_AD_INTERNAL_ERROR	/* fatal */
+#define SSL_AD_USER_CANCELLED		TLS1_AD_USER_CANCELLED
+#define SSL_AD_NO_RENEGOTIATION		TLS1_AD_NO_RENEGOTIATION
+#define SSL_AD_UNSUPPORTED_EXTENSION	TLS1_AD_UNSUPPORTED_EXTENSION
+#define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE
+#define SSL_AD_UNRECOGNIZED_NAME	TLS1_AD_UNRECOGNIZED_NAME
+#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
+#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
+#define SSL_AD_UNKNOWN_PSK_IDENTITY     TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
+
+#define SSL_ERROR_NONE			0
+#define SSL_ERROR_SSL			1
+#define SSL_ERROR_WANT_READ		2
+#define SSL_ERROR_WANT_WRITE		3
+#define SSL_ERROR_WANT_X509_LOOKUP	4
+#define SSL_ERROR_SYSCALL		5 /* look at error stack/return value/errno */
+#define SSL_ERROR_ZERO_RETURN		6
+#define SSL_ERROR_WANT_CONNECT		7
+#define SSL_ERROR_WANT_ACCEPT		8
+
+#define SSL_CTRL_NEED_TMP_RSA			1
+#define SSL_CTRL_SET_TMP_RSA			2
+#define SSL_CTRL_SET_TMP_DH			3
+#define SSL_CTRL_SET_TMP_ECDH			4
+#define SSL_CTRL_SET_TMP_RSA_CB			5
+#define SSL_CTRL_SET_TMP_DH_CB			6
+#define SSL_CTRL_SET_TMP_ECDH_CB		7
+
+#define SSL_CTRL_GET_SESSION_REUSED		8
+#define SSL_CTRL_GET_CLIENT_CERT_REQUEST	9
+#define SSL_CTRL_GET_NUM_RENEGOTIATIONS		10
+#define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS	11
+#define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS	12
+#define SSL_CTRL_GET_FLAGS			13
+#define SSL_CTRL_EXTRA_CHAIN_CERT		14
+
+#define SSL_CTRL_SET_MSG_CALLBACK               15
+#define SSL_CTRL_SET_MSG_CALLBACK_ARG           16
+
+/* only applies to datagram connections */
+#define SSL_CTRL_SET_MTU                17
+/* Stats */
+#define SSL_CTRL_SESS_NUMBER			20
+#define SSL_CTRL_SESS_CONNECT			21
+#define SSL_CTRL_SESS_CONNECT_GOOD		22
+#define SSL_CTRL_SESS_CONNECT_RENEGOTIATE	23
+#define SSL_CTRL_SESS_ACCEPT			24
+#define SSL_CTRL_SESS_ACCEPT_GOOD		25
+#define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE	26
+#define SSL_CTRL_SESS_HIT			27
+#define SSL_CTRL_SESS_CB_HIT			28
+#define SSL_CTRL_SESS_MISSES			29
+#define SSL_CTRL_SESS_TIMEOUTS			30
+#define SSL_CTRL_SESS_CACHE_FULL		31
+#define SSL_CTRL_OPTIONS			32
+#define SSL_CTRL_MODE				33
+
+#define SSL_CTRL_GET_READ_AHEAD			40
+#define SSL_CTRL_SET_READ_AHEAD			41
+#define SSL_CTRL_SET_SESS_CACHE_SIZE		42
+#define SSL_CTRL_GET_SESS_CACHE_SIZE		43
+#define SSL_CTRL_SET_SESS_CACHE_MODE		44
+#define SSL_CTRL_GET_SESS_CACHE_MODE		45
+
+#define SSL_CTRL_GET_MAX_CERT_LIST		50
+#define SSL_CTRL_SET_MAX_CERT_LIST		51
+
+#define SSL_CTRL_SET_MAX_SEND_FRAGMENT		52
+
+/* see tls1.h for macros based on these */
+#ifndef OPENSSL_NO_TLSEXT
+#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB	53
+#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG	54
+#define SSL_CTRL_SET_TLSEXT_HOSTNAME		55
+#define SSL_CTRL_SET_TLSEXT_DEBUG_CB		56
+#define SSL_CTRL_SET_TLSEXT_DEBUG_ARG		57
+#define SSL_CTRL_GET_TLSEXT_TICKET_KEYS		58
+#define SSL_CTRL_SET_TLSEXT_TICKET_KEYS		59
+#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT	60
+#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB	61
+#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62
+#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB	63
+#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG	64
+#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE	65
+#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS	66
+#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS	67
+#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS	68
+#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS	69
+#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP	70
+#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP	71
+
+#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB	72
+#endif
+
+#define DTLS_CTRL_GET_TIMEOUT		73
+#define DTLS_CTRL_HANDLE_TIMEOUT	74
+#define DTLS_CTRL_LISTEN			75
+
+#define SSL_CTRL_GET_RI_SUPPORT			76
+#define SSL_CTRL_CLEAR_OPTIONS			77
+#define SSL_CTRL_CLEAR_MODE			78
+
+#define DTLSv1_get_timeout(ssl, arg) \
+	SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
+#define DTLSv1_handle_timeout(ssl) \
+	SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL)
+#define DTLSv1_listen(ssl, peer) \
+	SSL_ctrl(ssl,DTLS_CTRL_LISTEN,0, (void *)peer)
+
+#define SSL_session_reused(ssl) \
+	SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL)
+#define SSL_num_renegotiations(ssl) \
+	SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL)
+#define SSL_clear_num_renegotiations(ssl) \
+	SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL)
+#define SSL_total_renegotiations(ssl) \
+	SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL)
+
+#define SSL_CTX_need_tmp_RSA(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL)
+#define SSL_CTX_set_tmp_rsa(ctx,rsa) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa)
+#define SSL_CTX_set_tmp_dh(ctx,dh) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
+#define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+
+#define SSL_need_tmp_RSA(ssl) \
+	SSL_ctrl(ssl,SSL_CTRL_NEED_TMP_RSA,0,NULL)
+#define SSL_set_tmp_rsa(ssl,rsa) \
+	SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa)
+#define SSL_set_tmp_dh(ssl,dh) \
+	SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
+#define SSL_set_tmp_ecdh(ssl,ecdh) \
+	SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+
+#define SSL_CTX_add_extra_chain_cert(ctx,x509) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509)
+
+#ifndef OPENSSL_NO_BIO
+BIO_METHOD *BIO_f_ssl(void);
+BIO *BIO_new_ssl(SSL_CTX *ctx,int client);
+BIO *BIO_new_ssl_connect(SSL_CTX *ctx);
+BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx);
+int BIO_ssl_copy_session_id(BIO *to,BIO *from);
+void BIO_ssl_shutdown(BIO *ssl_bio);
+
+#endif
+
+int	SSL_CTX_set_cipher_list(SSL_CTX *,const char *str);
+SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth);
+void	SSL_CTX_free(SSL_CTX *);
+long SSL_CTX_set_timeout(SSL_CTX *ctx,long t);
+long SSL_CTX_get_timeout(const SSL_CTX *ctx);
+X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
+void SSL_CTX_set_cert_store(SSL_CTX *,X509_STORE *);
+int SSL_want(const SSL *s);
+int	SSL_clear(SSL *s);
+
+void	SSL_CTX_flush_sessions(SSL_CTX *ctx,long tm);
+
+const SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
+int	SSL_CIPHER_get_bits(const SSL_CIPHER *c,int *alg_bits);
+char *	SSL_CIPHER_get_version(const SSL_CIPHER *c);
+const char *	SSL_CIPHER_get_name(const SSL_CIPHER *c);
+const char *	SSL_CIPHER_authentication_method(const SSL_CIPHER *c);
+
+int	SSL_get_fd(const SSL *s);
+int	SSL_get_rfd(const SSL *s);
+int	SSL_get_wfd(const SSL *s);
+const char  * SSL_get_cipher_list(const SSL *s,int n);
+char *	SSL_get_shared_ciphers(const SSL *s, char *buf, int len);
+int	SSL_get_read_ahead(const SSL * s);
+int	SSL_pending(const SSL *s);
+const char *	SSL_authentication_method(const SSL *c);
+#ifndef OPENSSL_NO_SOCK
+int	SSL_set_fd(SSL *s, int fd);
+int	SSL_set_rfd(SSL *s, int fd);
+int	SSL_set_wfd(SSL *s, int fd);
+#endif
+#ifndef OPENSSL_NO_BIO
+void	SSL_set_bio(SSL *s, BIO *rbio,BIO *wbio);
+BIO *	SSL_get_rbio(const SSL *s);
+BIO *	SSL_get_wbio(const SSL *s);
+#endif
+int	SSL_set_cipher_list(SSL *s, const char *str);
+int	SSL_set_cipher_lists(SSL *s, STACK_OF(SSL_CIPHER) *sk);
+void	SSL_set_read_ahead(SSL *s, int yes);
+int	SSL_get_verify_mode(const SSL *s);
+int	SSL_get_verify_depth(const SSL *s);
+int	(*SSL_get_verify_callback(const SSL *s))(int,X509_STORE_CTX *);
+void	SSL_set_verify(SSL *s, int mode,
+		       int (*callback)(int ok,X509_STORE_CTX *ctx));
+void	SSL_set_verify_depth(SSL *s, int depth);
+#ifndef OPENSSL_NO_RSA
+int	SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
+#endif
+int	SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len);
+int	SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
+int	SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len);
+int	SSL_use_certificate(SSL *ssl, X509 *x);
+int	SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
+int	SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain);
+STACK_OF(X509) * SSL_get_certificate_chain(SSL *ssl, X509 *x);
+
+#ifndef OPENSSL_NO_STDIO
+int	SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
+int	SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type);
+int	SSL_use_certificate_file(SSL *ssl, const char *file, int type);
+int	SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+int	SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+int	SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
+int	SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); /* PEM type */
+STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
+int	SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
+					    const char *file);
+#ifndef OPENSSL_SYS_VMS
+#ifndef OPENSSL_SYS_MACINTOSH_CLASSIC /* XXXXX: Better scheme needed! [was: #ifndef MAC_OS_pre_X] */
+int	SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
+					   const char *dir);
+#endif
+#endif
+
+#endif
+
+void	SSL_load_error_strings(void );
+const char *SSL_state_string(const SSL *s);
+const char *SSL_rstate_string(const SSL *s);
+const char *SSL_state_string_long(const SSL *s);
+const char *SSL_rstate_string_long(const SSL *s);
+long	SSL_SESSION_get_time(const SSL_SESSION *s);
+long	SSL_SESSION_set_time(SSL_SESSION *s, long t);
+long	SSL_SESSION_get_timeout(const SSL_SESSION *s);
+long	SSL_SESSION_set_timeout(SSL_SESSION *s, long t);
+void	SSL_copy_session_id(SSL *to,const SSL *from);
+
+SSL_SESSION *SSL_SESSION_new(void);
+const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
+					unsigned int *len);
+const char *	SSL_SESSION_get_version(const SSL_SESSION *s);
+#ifndef OPENSSL_NO_FP_API
+int	SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
+#endif
+#ifndef OPENSSL_NO_BIO
+int	SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses);
+#endif
+void	SSL_SESSION_free(SSL_SESSION *ses);
+int	i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
+int	SSL_set_session(SSL *to, SSL_SESSION *session);
+void	SSL_set_session_creation_enabled(SSL *, int);
+int	SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
+int	SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c);
+int	SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
+int	SSL_set_generate_session_id(SSL *, GEN_SESSION_CB);
+int	SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
+					unsigned int id_len);
+SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a,const unsigned char **pp,
+			     long length);
+
+#ifdef HEADER_X509_H
+X509 *	SSL_get_peer_certificate(const SSL *s);
+#endif
+
+STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s);
+
+int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
+int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
+int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int,X509_STORE_CTX *);
+void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,
+			int (*callback)(int, X509_STORE_CTX *));
+void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth);
+void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *,void *), void *arg);
+#ifndef OPENSSL_NO_RSA
+int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
+#endif
+int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len);
+int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
+int SSL_CTX_use_PrivateKey_ASN1(int pk,SSL_CTX *ctx,
+	const unsigned char *d, long len);
+int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
+int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d);
+
+void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb);
+void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u);
+
+int SSL_CTX_check_private_key(const SSL_CTX *ctx);
+int SSL_check_private_key(const SSL *ctx);
+
+int	SSL_CTX_set_session_id_context(SSL_CTX *ctx,const unsigned char *sid_ctx,
+				       unsigned int sid_ctx_len);
+
+SSL *	SSL_new(SSL_CTX *ctx);
+int	SSL_set_session_id_context(SSL *ssl,const unsigned char *sid_ctx,
+				   unsigned int sid_ctx_len);
+
+int SSL_CTX_set_purpose(SSL_CTX *s, int purpose);
+int SSL_set_purpose(SSL *s, int purpose);
+int SSL_CTX_set_trust(SSL_CTX *s, int trust);
+int SSL_set_trust(SSL *s, int trust);
+
+int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
+int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);
+
+void	SSL_free(SSL *ssl);
+int 	SSL_accept(SSL *ssl);
+int 	SSL_connect(SSL *ssl);
+int 	SSL_read(SSL *ssl,void *buf,int num);
+int 	SSL_peek(SSL *ssl,void *buf,int num);
+int 	SSL_write(SSL *ssl,const void *buf,int num);
+long	SSL_ctrl(SSL *ssl,int cmd, long larg, void *parg);
+long	SSL_callback_ctrl(SSL *, int, void (*)(void));
+long	SSL_CTX_ctrl(SSL_CTX *ctx,int cmd, long larg, void *parg);
+long	SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void));
+
+int	SSL_get_error(const SSL *s,int ret_code);
+const char *SSL_get_version(const SSL *s);
+
+/* This sets the 'default' SSL version that SSL_new() will create */
+int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);
+
+#ifndef OPENSSL_NO_SSL2
+const SSL_METHOD *SSLv2_method(void);		/* SSLv2 */
+const SSL_METHOD *SSLv2_server_method(void);	/* SSLv2 */
+const SSL_METHOD *SSLv2_client_method(void);	/* SSLv2 */
+#endif
+
+const SSL_METHOD *SSLv3_method(void);		/* SSLv3 */
+const SSL_METHOD *SSLv3_server_method(void);	/* SSLv3 */
+const SSL_METHOD *SSLv3_client_method(void);	/* SSLv3 */
+
+const SSL_METHOD *SSLv23_method(void);	/* SSLv3 but can rollback to v2 */
+const SSL_METHOD *SSLv23_server_method(void);	/* SSLv3 but can rollback to v2 */
+const SSL_METHOD *SSLv23_client_method(void);	/* SSLv3 but can rollback to v2 */
+
+const SSL_METHOD *TLSv1_method(void);		/* TLSv1.0 */
+const SSL_METHOD *TLSv1_server_method(void);	/* TLSv1.0 */
+const SSL_METHOD *TLSv1_client_method(void);	/* TLSv1.0 */
+
+const SSL_METHOD *DTLSv1_method(void);		/* DTLSv1.0 */
+const SSL_METHOD *DTLSv1_server_method(void);	/* DTLSv1.0 */
+const SSL_METHOD *DTLSv1_client_method(void);	/* DTLSv1.0 */
+
+STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
+
+int SSL_do_handshake(SSL *s);
+int SSL_renegotiate(SSL *s);
+int SSL_renegotiate_pending(SSL *s);
+int SSL_shutdown(SSL *s);
+
+const SSL_METHOD *SSL_get_ssl_method(SSL *s);
+int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
+const char *SSL_alert_type_string_long(int value);
+const char *SSL_alert_type_string(int value);
+const char *SSL_alert_desc_string_long(int value);
+const char *SSL_alert_desc_string(int value);
+
+void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list);
+void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list);
+STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s);
+STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s);
+int SSL_add_client_CA(SSL *ssl,X509 *x);
+int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x);
+
+void SSL_set_connect_state(SSL *s);
+void SSL_set_accept_state(SSL *s);
+
+long SSL_get_default_timeout(const SSL *s);
+
+int SSL_library_init(void );
+
+char *SSL_CIPHER_description(const SSL_CIPHER *,char *buf,int size);
+STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk);
+
+SSL *SSL_dup(SSL *ssl);
+
+X509 *SSL_get_certificate(const SSL *ssl);
+/* EVP_PKEY */ struct evp_pkey_st *SSL_get_privatekey(SSL *ssl);
+
+void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx,int mode);
+int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
+void SSL_set_quiet_shutdown(SSL *ssl,int mode);
+int SSL_get_quiet_shutdown(const SSL *ssl);
+void SSL_set_shutdown(SSL *ssl,int mode);
+int SSL_get_shutdown(const SSL *ssl);
+int SSL_version(const SSL *ssl);
+int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
+int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
+	const char *CApath);
+#define SSL_get0_session SSL_get_session /* just peek at pointer */
+SSL_SESSION *SSL_get_session(const SSL *ssl);
+SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */
+SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
+SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx);
+void SSL_set_info_callback(SSL *ssl,
+			   void (*cb)(const SSL *ssl,int type,int val));
+void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl,int type,int val);
+int SSL_state(const SSL *ssl);
+
+void SSL_set_verify_result(SSL *ssl,long v);
+long SSL_get_verify_result(const SSL *ssl);
+
+int SSL_set_ex_data(SSL *ssl,int idx,void *data);
+void *SSL_get_ex_data(const SSL *ssl,int idx);
+int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+
+int SSL_SESSION_set_ex_data(SSL_SESSION *ss,int idx,void *data);
+void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss,int idx);
+int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+
+int SSL_CTX_set_ex_data(SSL_CTX *ssl,int idx,void *data);
+void *SSL_CTX_get_ex_data(const SSL_CTX *ssl,int idx);
+int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+
+int SSL_get_ex_data_X509_STORE_CTX_idx(void );
+
+#define SSL_CTX_sess_set_cache_size(ctx,t) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL)
+#define SSL_CTX_sess_get_cache_size(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL)
+#define SSL_CTX_set_session_cache_mode(ctx,m) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL)
+#define SSL_CTX_get_session_cache_mode(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL)
+
+#define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx)
+#define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m)
+#define SSL_CTX_get_read_ahead(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL)
+#define SSL_CTX_set_read_ahead(ctx,m) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL)
+#define SSL_CTX_get_max_cert_list(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
+#define SSL_CTX_set_max_cert_list(ctx,m) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
+#define SSL_get_max_cert_list(ssl) \
+	SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
+#define SSL_set_max_cert_list(ssl,m) \
+	SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
+
+#define SSL_CTX_set_max_send_fragment(ctx,m) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL)
+#define SSL_set_max_send_fragment(ssl,m) \
+	SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL)
+
+     /* NB: the keylength is only applicable when is_export is true */
+#ifndef OPENSSL_NO_RSA
+void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
+				  RSA *(*cb)(SSL *ssl,int is_export,
+					     int keylength));
+
+void SSL_set_tmp_rsa_callback(SSL *ssl,
+				  RSA *(*cb)(SSL *ssl,int is_export,
+					     int keylength));
+#endif
+#ifndef OPENSSL_NO_DH
+void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
+				 DH *(*dh)(SSL *ssl,int is_export,
+					   int keylength));
+void SSL_set_tmp_dh_callback(SSL *ssl,
+				 DH *(*dh)(SSL *ssl,int is_export,
+					   int keylength));
+#endif
+#ifndef OPENSSL_NO_ECDH
+void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,
+				 EC_KEY *(*ecdh)(SSL *ssl,int is_export,
+					   int keylength));
+void SSL_set_tmp_ecdh_callback(SSL *ssl,
+				 EC_KEY *(*ecdh)(SSL *ssl,int is_export,
+					   int keylength));
+#endif
+
+#ifndef OPENSSL_NO_COMP
+const COMP_METHOD *SSL_get_current_compression(SSL *s);
+const COMP_METHOD *SSL_get_current_expansion(SSL *s);
+const char *SSL_COMP_get_name(const COMP_METHOD *comp);
+STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void);
+int SSL_COMP_add_compression_method(int id,COMP_METHOD *cm);
+#else
+const void *SSL_get_current_compression(SSL *s);
+const void *SSL_get_current_expansion(SSL *s);
+const char *SSL_COMP_get_name(const void *comp);
+void *SSL_COMP_get_compression_methods(void);
+int SSL_COMP_add_compression_method(int id,void *cm);
+#endif
+
+/* TLS extensions functions */
+int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len);
+
+int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
+				  void *arg);
+
+/* Pre-shared secret session resumption functions */
+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_SSL_strings(void);
+
+/* Error codes for the SSL functions. */
+
+/* Function codes. */
+#define SSL_F_CLIENT_CERTIFICATE			 100
+#define SSL_F_CLIENT_FINISHED				 167
+#define SSL_F_CLIENT_HELLO				 101
+#define SSL_F_CLIENT_MASTER_KEY				 102
+#define SSL_F_D2I_SSL_SESSION				 103
+#define SSL_F_DO_DTLS1_WRITE				 245
+#define SSL_F_DO_SSL3_WRITE				 104
+#define SSL_F_DTLS1_ACCEPT				 246
+#define SSL_F_DTLS1_ADD_CERT_TO_BUF			 295
+#define SSL_F_DTLS1_BUFFER_RECORD			 247
+#define SSL_F_DTLS1_CLIENT_HELLO			 248
+#define SSL_F_DTLS1_CONNECT				 249
+#define SSL_F_DTLS1_ENC					 250
+#define SSL_F_DTLS1_GET_HELLO_VERIFY			 251
+#define SSL_F_DTLS1_GET_MESSAGE				 252
+#define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT		 253
+#define SSL_F_DTLS1_GET_RECORD				 254
+#define SSL_F_DTLS1_HANDLE_TIMEOUT			 297
+#define SSL_F_DTLS1_OUTPUT_CERT_CHAIN			 255
+#define SSL_F_DTLS1_PREPROCESS_FRAGMENT			 288
+#define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE		 256
+#define SSL_F_DTLS1_PROCESS_RECORD			 257
+#define SSL_F_DTLS1_READ_BYTES				 258
+#define SSL_F_DTLS1_READ_FAILED				 259
+#define SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST		 260
+#define SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE		 261
+#define SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE		 262
+#define SSL_F_DTLS1_SEND_CLIENT_VERIFY			 263
+#define SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST		 264
+#define SSL_F_DTLS1_SEND_SERVER_CERTIFICATE		 265
+#define SSL_F_DTLS1_SEND_SERVER_HELLO			 266
+#define SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE		 267
+#define SSL_F_DTLS1_WRITE_APP_DATA_BYTES		 268
+#define SSL_F_GET_CLIENT_FINISHED			 105
+#define SSL_F_GET_CLIENT_HELLO				 106
+#define SSL_F_GET_CLIENT_MASTER_KEY			 107
+#define SSL_F_GET_SERVER_FINISHED			 108
+#define SSL_F_GET_SERVER_HELLO				 109
+#define SSL_F_GET_SERVER_VERIFY				 110
+#define SSL_F_I2D_SSL_SESSION				 111
+#define SSL_F_READ_N					 112
+#define SSL_F_REQUEST_CERTIFICATE			 113
+#define SSL_F_SERVER_FINISH				 239
+#define SSL_F_SERVER_HELLO				 114
+#define SSL_F_SERVER_VERIFY				 240
+#define SSL_F_SSL23_ACCEPT				 115
+#define SSL_F_SSL23_CLIENT_HELLO			 116
+#define SSL_F_SSL23_CONNECT				 117
+#define SSL_F_SSL23_GET_CLIENT_HELLO			 118
+#define SSL_F_SSL23_GET_SERVER_HELLO			 119
+#define SSL_F_SSL23_PEEK				 237
+#define SSL_F_SSL23_READ				 120
+#define SSL_F_SSL23_WRITE				 121
+#define SSL_F_SSL2_ACCEPT				 122
+#define SSL_F_SSL2_CONNECT				 123
+#define SSL_F_SSL2_ENC_INIT				 124
+#define SSL_F_SSL2_GENERATE_KEY_MATERIAL		 241
+#define SSL_F_SSL2_PEEK					 234
+#define SSL_F_SSL2_READ					 125
+#define SSL_F_SSL2_READ_INTERNAL			 236
+#define SSL_F_SSL2_SET_CERTIFICATE			 126
+#define SSL_F_SSL2_WRITE				 127
+#define SSL_F_SSL3_ACCEPT				 128
+#define SSL_F_SSL3_ADD_CERT_TO_BUF			 296
+#define SSL_F_SSL3_CALLBACK_CTRL			 233
+#define SSL_F_SSL3_CHANGE_CIPHER_STATE			 129
+#define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM		 130
+#define SSL_F_SSL3_CHECK_CLIENT_HELLO			 304
+#define SSL_F_SSL3_CLIENT_HELLO				 131
+#define SSL_F_SSL3_CONNECT				 132
+#define SSL_F_SSL3_CTRL					 213
+#define SSL_F_SSL3_CTX_CTRL				 133
+#define SSL_F_SSL3_DIGEST_CACHED_RECORDS		 293
+#define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC		 292
+#define SSL_F_SSL3_ENC					 134
+#define SSL_F_SSL3_GENERATE_KEY_BLOCK			 238
+#define SSL_F_SSL3_GET_CERTIFICATE_REQUEST		 135
+#define SSL_F_SSL3_GET_CERT_STATUS			 289
+#define SSL_F_SSL3_GET_CERT_VERIFY			 136
+#define SSL_F_SSL3_GET_CLIENT_CERTIFICATE		 137
+#define SSL_F_SSL3_GET_CLIENT_HELLO			 138
+#define SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE		 139
+#define SSL_F_SSL3_GET_FINISHED				 140
+#define SSL_F_SSL3_GET_KEY_EXCHANGE			 141
+#define SSL_F_SSL3_GET_MESSAGE				 142
+#define SSL_F_SSL3_GET_NEW_SESSION_TICKET		 283
+#define SSL_F_SSL3_GET_NEXT_PROTO			 304
+#define SSL_F_SSL3_GET_RECORD				 143
+#define SSL_F_SSL3_GET_SERVER_CERTIFICATE		 144
+#define SSL_F_SSL3_GET_SERVER_DONE			 145
+#define SSL_F_SSL3_GET_SERVER_HELLO			 146
+#define SSL_F_SSL3_HANDSHAKE_MAC			 285
+#define SSL_F_SSL3_NEW_SESSION_TICKET			 287
+#define SSL_F_SSL3_OUTPUT_CERT_CHAIN			 147
+#define SSL_F_SSL3_PEEK					 235
+#define SSL_F_SSL3_READ_BYTES				 148
+#define SSL_F_SSL3_READ_N				 149
+#define SSL_F_SSL3_SEND_CERTIFICATE_REQUEST		 150
+#define SSL_F_SSL3_SEND_CLIENT_CERTIFICATE		 151
+#define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE		 152
+#define SSL_F_SSL3_SEND_CLIENT_VERIFY			 153
+#define SSL_F_SSL3_SEND_SERVER_CERTIFICATE		 154
+#define SSL_F_SSL3_SEND_SERVER_HELLO			 242
+#define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE		 155
+#define SSL_F_SSL3_SETUP_KEY_BLOCK			 157
+#define SSL_F_SSL3_SETUP_READ_BUFFER			 156
+#define SSL_F_SSL3_SETUP_WRITE_BUFFER			 291
+#define SSL_F_SSL3_WRITE_BYTES				 158
+#define SSL_F_SSL3_WRITE_PENDING			 159
+#define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT	 298
+#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT		 277
+#define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK	 215
+#define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK	 216
+#define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT	 299
+#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT		 278
+#define SSL_F_SSL_BAD_METHOD				 160
+#define SSL_F_SSL_BYTES_TO_CIPHER_LIST			 161
+#define SSL_F_SSL_CERT_DUP				 221
+#define SSL_F_SSL_CERT_INST				 222
+#define SSL_F_SSL_CERT_INSTANTIATE			 214
+#define SSL_F_SSL_CERT_NEW				 162
+#define SSL_F_SSL_CHECK_PRIVATE_KEY			 163
+#define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT		 280
+#define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG		 279
+#define SSL_F_SSL_CIPHER_PROCESS_RULESTR		 230
+#define SSL_F_SSL_CIPHER_STRENGTH_SORT			 231
+#define SSL_F_SSL_CLEAR					 164
+#define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD		 165
+#define SSL_F_SSL_CREATE_CIPHER_LIST			 166
+#define SSL_F_SSL_CTRL					 232
+#define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY			 168
+#define SSL_F_SSL_CTX_NEW				 169
+#define SSL_F_SSL_CTX_SET_CIPHER_LIST			 269
+#define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE		 290
+#define SSL_F_SSL_CTX_SET_PURPOSE			 226
+#define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT		 219
+#define SSL_F_SSL_CTX_SET_SSL_VERSION			 170
+#define SSL_F_SSL_CTX_SET_TRUST				 229
+#define SSL_F_SSL_CTX_USE_CERTIFICATE			 171
+#define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1		 172
+#define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE	 220
+#define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE		 173
+#define SSL_F_SSL_CTX_USE_PRIVATEKEY			 174
+#define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1		 175
+#define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE		 176
+#define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT		 272
+#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY			 177
+#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1		 178
+#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE		 179
+#define SSL_F_SSL_DO_HANDSHAKE				 180
+#define SSL_F_SSL_GET_NEW_SESSION			 181
+#define SSL_F_SSL_GET_PREV_SESSION			 217
+#define SSL_F_SSL_GET_SERVER_SEND_CERT			 182
+#define SSL_F_SSL_GET_SIGN_PKEY				 183
+#define SSL_F_SSL_INIT_WBIO_BUFFER			 184
+#define SSL_F_SSL_LOAD_CLIENT_CA_FILE			 185
+#define SSL_F_SSL_NEW					 186
+#define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT	 300
+#define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT		 302
+#define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT	 301
+#define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT		 303
+#define SSL_F_SSL_PEEK					 270
+#define SSL_F_TLS1_EXPORT_KEYING_MATERIAL		 312
+#define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT		 281
+#define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT		 282
+#define SSL_F_SSL_READ					 223
+#define SSL_F_SSL_RSA_PRIVATE_DECRYPT			 187
+#define SSL_F_SSL_RSA_PUBLIC_ENCRYPT			 188
+#define SSL_F_SSL_SESSION_NEW				 189
+#define SSL_F_SSL_SESSION_PRINT_FP			 190
+#define SSL_F_SSL_SESS_CERT_NEW				 225
+#define SSL_F_SSL_SET_CERT				 191
+#define SSL_F_SSL_SET_CIPHER_LIST			 271
+#define SSL_F_SSL_SET_FD				 192
+#define SSL_F_SSL_SET_PKEY				 193
+#define SSL_F_SSL_SET_PURPOSE				 227
+#define SSL_F_SSL_SET_RFD				 194
+#define SSL_F_SSL_SET_SESSION				 195
+#define SSL_F_SSL_SET_SESSION_ID_CONTEXT		 218
+#define SSL_F_SSL_SET_SESSION_TICKET_EXT		 294
+#define SSL_F_SSL_SET_TRUST				 228
+#define SSL_F_SSL_SET_WFD				 196
+#define SSL_F_SSL_SHUTDOWN				 224
+#define SSL_F_SSL_UNDEFINED_CONST_FUNCTION		 243
+#define SSL_F_SSL_UNDEFINED_FUNCTION			 197
+#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION		 244
+#define SSL_F_SSL_USE_CERTIFICATE			 198
+#define SSL_F_SSL_USE_CERTIFICATE_ASN1			 199
+#define SSL_F_SSL_USE_CERTIFICATE_CHAIN			 2000
+#define SSL_F_SSL_USE_CERTIFICATE_FILE			 200
+#define SSL_F_SSL_USE_PRIVATEKEY			 201
+#define SSL_F_SSL_USE_PRIVATEKEY_ASN1			 202
+#define SSL_F_SSL_USE_PRIVATEKEY_FILE			 203
+#define SSL_F_SSL_USE_PSK_IDENTITY_HINT			 273
+#define SSL_F_SSL_USE_RSAPRIVATEKEY			 204
+#define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1		 205
+#define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE		 206
+#define SSL_F_SSL_VERIFY_CERT_CHAIN			 207
+#define SSL_F_SSL_WRITE					 208
+#define SSL_F_TLS1_CERT_VERIFY_MAC			 286
+#define SSL_F_TLS1_CHANGE_CIPHER_STATE			 209
+#define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT		 274
+#define SSL_F_TLS1_ENC					 210
+#define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT		 275
+#define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT		 276
+#define SSL_F_TLS1_PRF					 284
+#define SSL_F_TLS1_SETUP_KEY_BLOCK			 211
+#define SSL_F_WRITE_PENDING				 212
+
+/* Reason codes. */
+#define SSL_R_APP_DATA_IN_HANDSHAKE			 100
+#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272
+#define SSL_R_BAD_ALERT_RECORD				 101
+#define SSL_R_BAD_AUTHENTICATION_TYPE			 102
+#define SSL_R_BAD_CHANGE_CIPHER_SPEC			 103
+#define SSL_R_BAD_CHECKSUM				 104
+#define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK		 106
+#define SSL_R_BAD_DECOMPRESSION				 107
+#define SSL_R_BAD_DH_G_LENGTH				 108
+#define SSL_R_BAD_DH_PUB_KEY_LENGTH			 109
+#define SSL_R_BAD_DH_P_LENGTH				 110
+#define SSL_R_BAD_DIGEST_LENGTH				 111
+#define SSL_R_BAD_DSA_SIGNATURE				 112
+#define SSL_R_BAD_ECC_CERT				 304
+#define SSL_R_BAD_ECDSA_SIGNATURE			 305
+#define SSL_R_BAD_ECPOINT				 306
+#define SSL_R_BAD_HANDSHAKE_LENGTH			 332
+#define SSL_R_BAD_HELLO_REQUEST				 105
+#define SSL_R_BAD_LENGTH				 271
+#define SSL_R_BAD_MAC_DECODE				 113
+#define SSL_R_BAD_MAC_LENGTH				 333
+#define SSL_R_BAD_MESSAGE_TYPE				 114
+#define SSL_R_BAD_PACKET_LENGTH				 115
+#define SSL_R_BAD_PROTOCOL_VERSION_NUMBER		 116
+#define SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH		 316
+#define SSL_R_BAD_RESPONSE_ARGUMENT			 117
+#define SSL_R_BAD_RSA_DECRYPT				 118
+#define SSL_R_BAD_RSA_ENCRYPT				 119
+#define SSL_R_BAD_RSA_E_LENGTH				 120
+#define SSL_R_BAD_RSA_MODULUS_LENGTH			 121
+#define SSL_R_BAD_RSA_SIGNATURE				 122
+#define SSL_R_BAD_SIGNATURE				 123
+#define SSL_R_BAD_SSL_FILETYPE				 124
+#define SSL_R_BAD_SSL_SESSION_ID_LENGTH			 125
+#define SSL_R_BAD_STATE					 126
+#define SSL_R_BAD_WRITE_RETRY				 127
+#define SSL_R_BIO_NOT_SET				 128
+#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG			 129
+#define SSL_R_BN_LIB					 130
+#define SSL_R_CA_DN_LENGTH_MISMATCH			 131
+#define SSL_R_CA_DN_TOO_LONG				 132
+#define SSL_R_CCS_RECEIVED_EARLY			 133
+#define SSL_R_CERTIFICATE_VERIFY_FAILED			 134
+#define SSL_R_CERT_LENGTH_MISMATCH			 135
+#define SSL_R_CHALLENGE_IS_DIFFERENT			 136
+#define SSL_R_CIPHER_CODE_WRONG_LENGTH			 137
+#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE		 138
+#define SSL_R_CIPHER_TABLE_SRC_ERROR			 139
+#define SSL_R_CLIENTHELLO_TLSEXT			 226
+#define SSL_R_COMPRESSED_LENGTH_TOO_LONG		 140
+#define SSL_R_COMPRESSION_DISABLED			 343
+#define SSL_R_COMPRESSION_FAILURE			 141
+#define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE	 307
+#define SSL_R_COMPRESSION_LIBRARY_ERROR			 142
+#define SSL_R_CONNECTION_ID_IS_DIFFERENT		 143
+#define SSL_R_CONNECTION_TYPE_NOT_SET			 144
+#define SSL_R_COOKIE_MISMATCH				 308
+#define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED		 145
+#define SSL_R_DATA_LENGTH_TOO_LONG			 146
+#define SSL_R_DECRYPTION_FAILED				 147
+#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC	 281
+#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG		 148
+#define SSL_R_DIGEST_CHECK_FAILED			 149
+#define SSL_R_DTLS_MESSAGE_TOO_BIG			 334
+#define SSL_R_DUPLICATE_COMPRESSION_ID			 309
+#define SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT		 317
+#define SSL_R_ECC_CERT_NOT_FOR_SIGNING			 318
+#define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE	 322
+#define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE	 323
+#define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER		 310
+#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG			 150
+#define SSL_R_ERROR_GENERATING_TMP_RSA_KEY		 282
+#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST		 151
+#define SSL_R_EXCESSIVE_MESSAGE_SIZE			 152
+#define SSL_R_EXTRA_DATA_IN_MESSAGE			 153
+#define SSL_R_GOT_A_FIN_BEFORE_A_CCS			 154
+#define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS		 346
+#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION		 347
+#define SSL_R_HTTPS_PROXY_REQUEST			 155
+#define SSL_R_HTTP_REQUEST				 156
+#define SSL_R_ILLEGAL_PADDING				 283
+#define SSL_R_INCONSISTENT_COMPRESSION			 340
+#define SSL_R_INVALID_CHALLENGE_LENGTH			 158
+#define SSL_R_INVALID_COMMAND				 280
+#define SSL_R_INVALID_COMPRESSION_ALGORITHM		 341
+#define SSL_R_INVALID_PURPOSE				 278
+#define SSL_R_INVALID_STATUS_RESPONSE			 328
+#define SSL_R_INVALID_TICKET_KEYS_LENGTH		 325
+#define SSL_R_INVALID_TRUST				 279
+#define SSL_R_KEY_ARG_TOO_LONG				 284
+#define SSL_R_KRB5					 285
+#define SSL_R_KRB5_C_CC_PRINC				 286
+#define SSL_R_KRB5_C_GET_CRED				 287
+#define SSL_R_KRB5_C_INIT				 288
+#define SSL_R_KRB5_C_MK_REQ				 289
+#define SSL_R_KRB5_S_BAD_TICKET				 290
+#define SSL_R_KRB5_S_INIT				 291
+#define SSL_R_KRB5_S_RD_REQ				 292
+#define SSL_R_KRB5_S_TKT_EXPIRED			 293
+#define SSL_R_KRB5_S_TKT_NYV				 294
+#define SSL_R_KRB5_S_TKT_SKEW				 295
+#define SSL_R_LENGTH_MISMATCH				 159
+#define SSL_R_LENGTH_TOO_SHORT				 160
+#define SSL_R_LIBRARY_BUG				 274
+#define SSL_R_LIBRARY_HAS_NO_CIPHERS			 161
+#define SSL_R_MESSAGE_TOO_LONG				 296
+#define SSL_R_MISSING_DH_DSA_CERT			 162
+#define SSL_R_MISSING_DH_KEY				 163
+#define SSL_R_MISSING_DH_RSA_CERT			 164
+#define SSL_R_MISSING_DSA_SIGNING_CERT			 165
+#define SSL_R_MISSING_EXPORT_TMP_DH_KEY			 166
+#define SSL_R_MISSING_EXPORT_TMP_RSA_KEY		 167
+#define SSL_R_MISSING_RSA_CERTIFICATE			 168
+#define SSL_R_MISSING_RSA_ENCRYPTING_CERT		 169
+#define SSL_R_MISSING_RSA_SIGNING_CERT			 170
+#define SSL_R_MISSING_TMP_DH_KEY			 171
+#define SSL_R_MISSING_TMP_ECDH_KEY			 311
+#define SSL_R_MISSING_TMP_RSA_KEY			 172
+#define SSL_R_MISSING_TMP_RSA_PKEY			 173
+#define SSL_R_MISSING_VERIFY_MESSAGE			 174
+#define SSL_R_MULTIPLE_SGC_RESTARTS			 346
+#define SSL_R_NON_SSLV2_INITIAL_PACKET			 175
+#define SSL_R_NO_CERTIFICATES_RETURNED			 176
+#define SSL_R_NO_CERTIFICATE_ASSIGNED			 177
+#define SSL_R_NO_CERTIFICATE_RETURNED			 178
+#define SSL_R_NO_CERTIFICATE_SET			 179
+#define SSL_R_NO_CERTIFICATE_SPECIFIED			 180
+#define SSL_R_NO_CIPHERS_AVAILABLE			 181
+#define SSL_R_NO_CIPHERS_PASSED				 182
+#define SSL_R_NO_CIPHERS_SPECIFIED			 183
+#define SSL_R_NO_CIPHER_LIST				 184
+#define SSL_R_NO_CIPHER_MATCH				 185
+#define SSL_R_NO_CLIENT_CERT_METHOD			 331
+#define SSL_R_NO_CLIENT_CERT_RECEIVED			 186
+#define SSL_R_NO_COMPRESSION_SPECIFIED			 187
+#define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER		 330
+#define SSL_R_NO_METHOD_SPECIFIED			 188
+#define SSL_R_NO_PRIVATEKEY				 189
+#define SSL_R_NO_PRIVATE_KEY_ASSIGNED			 190
+#define SSL_R_NO_PROTOCOLS_AVAILABLE			 191
+#define SSL_R_NO_PUBLICKEY				 192
+#define SSL_R_NO_RENEGOTIATION				 339
+#define SSL_R_NO_REQUIRED_DIGEST			 324
+#define SSL_R_NO_SHARED_CIPHER				 193
+#define SSL_R_NO_VERIFY_CALLBACK			 194
+#define SSL_R_NULL_SSL_CTX				 195
+#define SSL_R_NULL_SSL_METHOD_PASSED			 196
+#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED		 197
+#define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344
+#define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE		 297
+#define SSL_R_OPAQUE_PRF_INPUT_TOO_LONG			 327
+#define SSL_R_PACKET_LENGTH_TOO_LONG			 198
+#define SSL_R_PARSE_TLSEXT				 227
+#define SSL_R_PATH_TOO_LONG				 270
+#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE		 199
+#define SSL_R_PEER_ERROR				 200
+#define SSL_R_PEER_ERROR_CERTIFICATE			 201
+#define SSL_R_PEER_ERROR_NO_CERTIFICATE			 202
+#define SSL_R_PEER_ERROR_NO_CIPHER			 203
+#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE	 204
+#define SSL_R_PRE_MAC_LENGTH_TOO_LONG			 205
+#define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS		 206
+#define SSL_R_PROTOCOL_IS_SHUTDOWN			 207
+#define SSL_R_PSK_IDENTITY_NOT_FOUND			 223
+#define SSL_R_PSK_NO_CLIENT_CB				 224
+#define SSL_R_PSK_NO_SERVER_CB				 225
+#define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR			 208
+#define SSL_R_PUBLIC_KEY_IS_NOT_RSA			 209
+#define SSL_R_PUBLIC_KEY_NOT_RSA			 210
+#define SSL_R_READ_BIO_NOT_SET				 211
+#define SSL_R_READ_TIMEOUT_EXPIRED			 312
+#define SSL_R_READ_WRONG_PACKET_TYPE			 212
+#define SSL_R_RECORD_LENGTH_MISMATCH			 213
+#define SSL_R_RECORD_TOO_LARGE				 214
+#define SSL_R_RECORD_TOO_SMALL				 298
+#define SSL_R_RENEGOTIATE_EXT_TOO_LONG			 335
+#define SSL_R_RENEGOTIATION_ENCODING_ERR		 336
+#define SSL_R_RENEGOTIATION_MISMATCH			 337
+#define SSL_R_REQUIRED_CIPHER_MISSING			 215
+#define SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING	 342
+#define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO		 216
+#define SSL_R_REUSE_CERT_TYPE_NOT_ZERO			 217
+#define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO		 218
+#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING		 345
+#define SSL_R_SERVERHELLO_TLSEXT			 275
+#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED		 277
+#define SSL_R_SESSION_MAY_NOT_BE_CREATED		 2000
+#define SSL_R_SHORT_READ				 219
+#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE	 220
+#define SSL_R_SSL23_DOING_SESSION_ID_REUSE		 221
+#define SSL_R_SSL2_CONNECTION_ID_TOO_LONG		 299
+#define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT		 321
+#define SSL_R_SSL3_EXT_INVALID_SERVERNAME		 319
+#define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE		 320
+#define SSL_R_SSL3_SESSION_ID_TOO_LONG			 300
+#define SSL_R_SSL3_SESSION_ID_TOO_SHORT			 222
+#define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE		 1042
+#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC		 1020
+#define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED		 1045
+#define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED		 1044
+#define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN		 1046
+#define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE		 1030
+#define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE		 1040
+#define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER		 1047
+#define SSL_R_SSLV3_ALERT_NO_CERTIFICATE		 1041
+#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE		 1010
+#define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE	 1043
+#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION	 228
+#define SSL_R_SSL_HANDSHAKE_FAILURE			 229
+#define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS		 230
+#define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED		 301
+#define SSL_R_SSL_SESSION_ID_CONFLICT			 302
+#define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG		 273
+#define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH		 303
+#define SSL_R_SSL_SESSION_ID_IS_DIFFERENT		 231
+#define SSL_R_TLSV1_ALERT_ACCESS_DENIED			 1049
+#define SSL_R_TLSV1_ALERT_DECODE_ERROR			 1050
+#define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED		 1021
+#define SSL_R_TLSV1_ALERT_DECRYPT_ERROR			 1051
+#define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION		 1060
+#define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY		 1071
+#define SSL_R_TLSV1_ALERT_INTERNAL_ERROR		 1080
+#define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION		 1100
+#define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION		 1070
+#define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW		 1022
+#define SSL_R_TLSV1_ALERT_UNKNOWN_CA			 1048
+#define SSL_R_TLSV1_ALERT_USER_CANCELLED		 1090
+#define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE		 1114
+#define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE	 1113
+#define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE		 1111
+#define SSL_R_TLSV1_UNRECOGNIZED_NAME			 1112
+#define SSL_R_TLSV1_UNSUPPORTED_EXTENSION		 1110
+#define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER	 232
+#define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL		 367
+#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST		 157
+#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233
+#define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG	 234
+#define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER		 235
+#define SSL_R_UNABLE_TO_DECODE_DH_CERTS			 236
+#define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS		 313
+#define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY		 237
+#define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS		 238
+#define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS		 314
+#define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS	 239
+#define SSL_R_UNABLE_TO_FIND_SSL_METHOD			 240
+#define SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES		 241
+#define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES		 242
+#define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES		 243
+#define SSL_R_UNEXPECTED_MESSAGE			 244
+#define SSL_R_UNEXPECTED_RECORD				 245
+#define SSL_R_UNINITIALIZED				 276
+#define SSL_R_UNKNOWN_ALERT_TYPE			 246
+#define SSL_R_UNKNOWN_CERTIFICATE_TYPE			 247
+#define SSL_R_UNKNOWN_CIPHER_RETURNED			 248
+#define SSL_R_UNKNOWN_CIPHER_TYPE			 249
+#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE			 250
+#define SSL_R_UNKNOWN_PKEY_TYPE				 251
+#define SSL_R_UNKNOWN_PROTOCOL				 252
+#define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE			 253
+#define SSL_R_UNKNOWN_SSL_VERSION			 254
+#define SSL_R_UNKNOWN_STATE				 255
+#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED	 338
+#define SSL_R_UNSUPPORTED_CIPHER			 256
+#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM		 257
+#define SSL_R_UNSUPPORTED_DIGEST_TYPE			 326
+#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE		 315
+#define SSL_R_UNSUPPORTED_PROTOCOL			 258
+#define SSL_R_UNSUPPORTED_SSL_VERSION			 259
+#define SSL_R_UNSUPPORTED_STATUS_TYPE			 329
+#define SSL_R_WRITE_BIO_NOT_SET				 260
+#define SSL_R_WRONG_CIPHER_RETURNED			 261
+#define SSL_R_WRONG_MESSAGE_TYPE			 262
+#define SSL_R_WRONG_NUMBER_OF_KEY_BITS			 263
+#define SSL_R_WRONG_SIGNATURE_LENGTH			 264
+#define SSL_R_WRONG_SIGNATURE_SIZE			 265
+#define SSL_R_WRONG_SSL_VERSION				 266
+#define SSL_R_WRONG_VERSION_NUMBER			 267
+#define SSL_R_X509_LIB					 268
+#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS		 269
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/ssl/ssl2.h b/openssl/ssl/ssl2.h
new file mode 100644
index 0000000..99a52ea
--- /dev/null
+++ b/openssl/ssl/ssl2.h
@@ -0,0 +1,268 @@
+/* ssl/ssl2.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_SSL2_H 
+#define HEADER_SSL2_H 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Protocol Version Codes */
+#define SSL2_VERSION		0x0002
+#define SSL2_VERSION_MAJOR	0x00
+#define SSL2_VERSION_MINOR	0x02
+/* #define SSL2_CLIENT_VERSION	0x0002 */
+/* #define SSL2_SERVER_VERSION	0x0002 */
+
+/* Protocol Message Codes */
+#define SSL2_MT_ERROR			0
+#define SSL2_MT_CLIENT_HELLO		1
+#define SSL2_MT_CLIENT_MASTER_KEY	2
+#define SSL2_MT_CLIENT_FINISHED		3
+#define SSL2_MT_SERVER_HELLO		4
+#define SSL2_MT_SERVER_VERIFY		5
+#define SSL2_MT_SERVER_FINISHED		6
+#define SSL2_MT_REQUEST_CERTIFICATE	7
+#define SSL2_MT_CLIENT_CERTIFICATE	8
+
+/* Error Message Codes */
+#define SSL2_PE_UNDEFINED_ERROR		0x0000
+#define SSL2_PE_NO_CIPHER		0x0001
+#define SSL2_PE_NO_CERTIFICATE		0x0002
+#define SSL2_PE_BAD_CERTIFICATE		0x0004
+#define SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006
+
+/* Cipher Kind Values */
+#define SSL2_CK_NULL_WITH_MD5			0x02000000 /* v3 */
+#define SSL2_CK_RC4_128_WITH_MD5		0x02010080
+#define SSL2_CK_RC4_128_EXPORT40_WITH_MD5	0x02020080
+#define SSL2_CK_RC2_128_CBC_WITH_MD5		0x02030080
+#define SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5	0x02040080
+#define SSL2_CK_IDEA_128_CBC_WITH_MD5		0x02050080
+#define SSL2_CK_DES_64_CBC_WITH_MD5		0x02060040
+#define SSL2_CK_DES_64_CBC_WITH_SHA		0x02060140 /* v3 */
+#define SSL2_CK_DES_192_EDE3_CBC_WITH_MD5	0x020700c0
+#define SSL2_CK_DES_192_EDE3_CBC_WITH_SHA	0x020701c0 /* v3 */
+#define SSL2_CK_RC4_64_WITH_MD5			0x02080080 /* MS hack */
+ 
+#define SSL2_CK_DES_64_CFB64_WITH_MD5_1		0x02ff0800 /* SSLeay */
+#define SSL2_CK_NULL				0x02ff0810 /* SSLeay */
+
+#define SSL2_TXT_DES_64_CFB64_WITH_MD5_1	"DES-CFB-M1"
+#define SSL2_TXT_NULL_WITH_MD5			"NULL-MD5"
+#define SSL2_TXT_RC4_128_WITH_MD5		"RC4-MD5"
+#define SSL2_TXT_RC4_128_EXPORT40_WITH_MD5	"EXP-RC4-MD5"
+#define SSL2_TXT_RC2_128_CBC_WITH_MD5		"RC2-CBC-MD5"
+#define SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5	"EXP-RC2-CBC-MD5"
+#define SSL2_TXT_IDEA_128_CBC_WITH_MD5		"IDEA-CBC-MD5"
+#define SSL2_TXT_DES_64_CBC_WITH_MD5		"DES-CBC-MD5"
+#define SSL2_TXT_DES_64_CBC_WITH_SHA		"DES-CBC-SHA"
+#define SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5	"DES-CBC3-MD5"
+#define SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA	"DES-CBC3-SHA"
+#define SSL2_TXT_RC4_64_WITH_MD5		"RC4-64-MD5"
+
+#define SSL2_TXT_NULL				"NULL"
+
+/* Flags for the SSL_CIPHER.algorithm2 field */
+#define SSL2_CF_5_BYTE_ENC			0x01
+#define SSL2_CF_8_BYTE_ENC			0x02
+
+/* Certificate Type Codes */
+#define SSL2_CT_X509_CERTIFICATE		0x01
+
+/* Authentication Type Code */
+#define SSL2_AT_MD5_WITH_RSA_ENCRYPTION		0x01
+
+#define SSL2_MAX_SSL_SESSION_ID_LENGTH		32
+
+/* Upper/Lower Bounds */
+#define SSL2_MAX_MASTER_KEY_LENGTH_IN_BITS	256
+#ifdef OPENSSL_SYS_MPE
+#define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER	29998u
+#else
+#define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER	32767u  /* 2^15-1 */
+#endif
+#define SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER	16383 /* 2^14-1 */
+
+#define SSL2_CHALLENGE_LENGTH	16
+/*#define SSL2_CHALLENGE_LENGTH	32 */
+#define SSL2_MIN_CHALLENGE_LENGTH	16
+#define SSL2_MAX_CHALLENGE_LENGTH	32
+#define SSL2_CONNECTION_ID_LENGTH	16
+#define SSL2_MAX_CONNECTION_ID_LENGTH	16
+#define SSL2_SSL_SESSION_ID_LENGTH	16
+#define SSL2_MAX_CERT_CHALLENGE_LENGTH	32
+#define SSL2_MIN_CERT_CHALLENGE_LENGTH	16
+#define SSL2_MAX_KEY_MATERIAL_LENGTH	24
+
+#ifndef HEADER_SSL_LOCL_H
+#define  CERT		char
+#endif
+
+typedef struct ssl2_state_st
+	{
+	int three_byte_header;
+	int clear_text;		/* clear text */
+	int escape;		/* not used in SSLv2 */
+	int ssl2_rollback;	/* used if SSLv23 rolled back to SSLv2 */
+
+	/* non-blocking io info, used to make sure the same
+	 * args were passwd */
+	unsigned int wnum;	/* number of bytes sent so far */
+	int wpend_tot;
+	const unsigned char *wpend_buf;
+
+	int wpend_off;	/* offset to data to write */
+	int wpend_len; 	/* number of bytes passwd to write */
+	int wpend_ret; 	/* number of bytes to return to caller */
+
+	/* buffer raw data */
+	int rbuf_left;
+	int rbuf_offs;
+	unsigned char *rbuf;
+	unsigned char *wbuf;
+
+	unsigned char *write_ptr;/* used to point to the start due to
+				  * 2/3 byte header. */
+
+	unsigned int padding;
+	unsigned int rlength; /* passed to ssl2_enc */
+	int ract_data_length; /* Set when things are encrypted. */
+	unsigned int wlength; /* passed to ssl2_enc */
+	int wact_data_length; /* Set when things are decrypted. */
+	unsigned char *ract_data;
+	unsigned char *wact_data;
+	unsigned char *mac_data;
+
+	unsigned char *read_key;
+	unsigned char *write_key;
+
+		/* Stuff specifically to do with this SSL session */
+	unsigned int challenge_length;
+	unsigned char challenge[SSL2_MAX_CHALLENGE_LENGTH];
+	unsigned int conn_id_length;
+	unsigned char conn_id[SSL2_MAX_CONNECTION_ID_LENGTH];
+	unsigned int key_material_length;
+	unsigned char key_material[SSL2_MAX_KEY_MATERIAL_LENGTH*2];
+
+	unsigned long read_sequence;
+	unsigned long write_sequence;
+
+	struct	{
+		unsigned int conn_id_length;
+		unsigned int cert_type;	
+		unsigned int cert_length;
+		unsigned int csl; 
+		unsigned int clear;
+		unsigned int enc; 
+		unsigned char ccl[SSL2_MAX_CERT_CHALLENGE_LENGTH];
+		unsigned int cipher_spec_length;
+		unsigned int session_id_length;
+		unsigned int clen;
+		unsigned int rlen;
+		} tmp;
+	} SSL2_STATE;
+
+/* SSLv2 */
+/* client */
+#define SSL2_ST_SEND_CLIENT_HELLO_A		(0x10|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_HELLO_B		(0x11|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_HELLO_A		(0x20|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_HELLO_B		(0x21|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_MASTER_KEY_A	(0x30|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_MASTER_KEY_B	(0x31|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_FINISHED_A		(0x40|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_FINISHED_B		(0x41|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_CERTIFICATE_A	(0x50|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_CERTIFICATE_B	(0x51|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_CERTIFICATE_C	(0x52|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_CERTIFICATE_D	(0x53|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_VERIFY_A		(0x60|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_VERIFY_B		(0x61|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_FINISHED_A		(0x70|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_FINISHED_B		(0x71|SSL_ST_CONNECT)
+#define SSL2_ST_CLIENT_START_ENCRYPTION		(0x80|SSL_ST_CONNECT)
+#define SSL2_ST_X509_GET_CLIENT_CERTIFICATE	(0x90|SSL_ST_CONNECT)
+/* server */
+#define SSL2_ST_GET_CLIENT_HELLO_A		(0x10|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_HELLO_B		(0x11|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_HELLO_C		(0x12|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_HELLO_A		(0x20|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_HELLO_B		(0x21|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_MASTER_KEY_A		(0x30|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_MASTER_KEY_B		(0x31|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_VERIFY_A		(0x40|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_VERIFY_B		(0x41|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_VERIFY_C		(0x42|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_FINISHED_A		(0x50|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_FINISHED_B		(0x51|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_FINISHED_A		(0x60|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_FINISHED_B		(0x61|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_REQUEST_CERTIFICATE_A	(0x70|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_REQUEST_CERTIFICATE_B	(0x71|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_REQUEST_CERTIFICATE_C	(0x72|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_REQUEST_CERTIFICATE_D	(0x73|SSL_ST_ACCEPT)
+#define SSL2_ST_SERVER_START_ENCRYPTION		(0x80|SSL_ST_ACCEPT)
+#define SSL2_ST_X509_GET_SERVER_CERTIFICATE	(0x90|SSL_ST_ACCEPT)
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/openssl/ssl/ssl23.h b/openssl/ssl/ssl23.h
new file mode 100644
index 0000000..d322898
--- /dev/null
+++ b/openssl/ssl/ssl23.h
@@ -0,0 +1,83 @@
+/* ssl/ssl23.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_SSL23_H 
+#define HEADER_SSL23_H 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*client */
+/* write to server */
+#define SSL23_ST_CW_CLNT_HELLO_A	(0x210|SSL_ST_CONNECT)
+#define SSL23_ST_CW_CLNT_HELLO_B	(0x211|SSL_ST_CONNECT)
+/* read from server */
+#define SSL23_ST_CR_SRVR_HELLO_A	(0x220|SSL_ST_CONNECT)
+#define SSL23_ST_CR_SRVR_HELLO_B	(0x221|SSL_ST_CONNECT)
+
+/* server */
+/* read from client */
+#define SSL23_ST_SR_CLNT_HELLO_A	(0x210|SSL_ST_ACCEPT)
+#define SSL23_ST_SR_CLNT_HELLO_B	(0x211|SSL_ST_ACCEPT)
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/openssl/ssl/ssl3.h b/openssl/ssl/ssl3.h
new file mode 100644
index 0000000..d6425e5
--- /dev/null
+++ b/openssl/ssl/ssl3.h
@@ -0,0 +1,675 @@
+/* ssl/ssl3.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_SSL3_H 
+#define HEADER_SSL3_H 
+
+#ifndef OPENSSL_NO_COMP
+#include <openssl/comp.h>
+#endif
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include <openssl/ssl.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Signalling cipher suite value: from draft-ietf-tls-renegotiation-03.txt */
+#define SSL3_CK_SCSV				0x030000FF
+
+#define SSL3_CK_RSA_NULL_MD5			0x03000001
+#define SSL3_CK_RSA_NULL_SHA			0x03000002
+#define SSL3_CK_RSA_RC4_40_MD5 			0x03000003
+#define SSL3_CK_RSA_RC4_128_MD5			0x03000004
+#define SSL3_CK_RSA_RC4_128_SHA			0x03000005
+#define SSL3_CK_RSA_RC2_40_MD5			0x03000006
+#define SSL3_CK_RSA_IDEA_128_SHA		0x03000007
+#define SSL3_CK_RSA_DES_40_CBC_SHA		0x03000008
+#define SSL3_CK_RSA_DES_64_CBC_SHA		0x03000009
+#define SSL3_CK_RSA_DES_192_CBC3_SHA		0x0300000A
+
+#define SSL3_CK_DH_DSS_DES_40_CBC_SHA		0x0300000B
+#define SSL3_CK_DH_DSS_DES_64_CBC_SHA		0x0300000C
+#define SSL3_CK_DH_DSS_DES_192_CBC3_SHA 	0x0300000D
+#define SSL3_CK_DH_RSA_DES_40_CBC_SHA		0x0300000E
+#define SSL3_CK_DH_RSA_DES_64_CBC_SHA		0x0300000F
+#define SSL3_CK_DH_RSA_DES_192_CBC3_SHA 	0x03000010
+
+#define SSL3_CK_EDH_DSS_DES_40_CBC_SHA		0x03000011
+#define SSL3_CK_EDH_DSS_DES_64_CBC_SHA		0x03000012
+#define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA	0x03000013
+#define SSL3_CK_EDH_RSA_DES_40_CBC_SHA		0x03000014
+#define SSL3_CK_EDH_RSA_DES_64_CBC_SHA		0x03000015
+#define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA	0x03000016
+
+#define SSL3_CK_ADH_RC4_40_MD5			0x03000017
+#define SSL3_CK_ADH_RC4_128_MD5			0x03000018
+#define SSL3_CK_ADH_DES_40_CBC_SHA		0x03000019
+#define SSL3_CK_ADH_DES_64_CBC_SHA		0x0300001A
+#define SSL3_CK_ADH_DES_192_CBC_SHA		0x0300001B
+
+#if 0
+	#define SSL3_CK_FZA_DMS_NULL_SHA		0x0300001C
+	#define SSL3_CK_FZA_DMS_FZA_SHA			0x0300001D
+	#if 0 /* Because it clashes with KRB5, is never used any more, and is safe
+		 to remove according to David Hopwood <david.hopwood@zetnet.co.uk>
+		 of the ietf-tls list */
+	#define SSL3_CK_FZA_DMS_RC4_SHA			0x0300001E
+	#endif
+#endif
+
+/*    VRS Additional Kerberos5 entries
+ */
+#define SSL3_CK_KRB5_DES_64_CBC_SHA		0x0300001E
+#define SSL3_CK_KRB5_DES_192_CBC3_SHA		0x0300001F
+#define SSL3_CK_KRB5_RC4_128_SHA		0x03000020
+#define SSL3_CK_KRB5_IDEA_128_CBC_SHA	       	0x03000021
+#define SSL3_CK_KRB5_DES_64_CBC_MD5       	0x03000022
+#define SSL3_CK_KRB5_DES_192_CBC3_MD5       	0x03000023
+#define SSL3_CK_KRB5_RC4_128_MD5	       	0x03000024
+#define SSL3_CK_KRB5_IDEA_128_CBC_MD5 		0x03000025
+
+#define SSL3_CK_KRB5_DES_40_CBC_SHA 		0x03000026
+#define SSL3_CK_KRB5_RC2_40_CBC_SHA 		0x03000027
+#define SSL3_CK_KRB5_RC4_40_SHA	 		0x03000028
+#define SSL3_CK_KRB5_DES_40_CBC_MD5 		0x03000029
+#define SSL3_CK_KRB5_RC2_40_CBC_MD5 		0x0300002A
+#define SSL3_CK_KRB5_RC4_40_MD5	 		0x0300002B
+
+#define SSL3_TXT_RSA_NULL_MD5			"NULL-MD5"
+#define SSL3_TXT_RSA_NULL_SHA			"NULL-SHA"
+#define SSL3_TXT_RSA_RC4_40_MD5 		"EXP-RC4-MD5"
+#define SSL3_TXT_RSA_RC4_128_MD5		"RC4-MD5"
+#define SSL3_TXT_RSA_RC4_128_SHA		"RC4-SHA"
+#define SSL3_TXT_RSA_RC2_40_MD5			"EXP-RC2-CBC-MD5"
+#define SSL3_TXT_RSA_IDEA_128_SHA		"IDEA-CBC-SHA"
+#define SSL3_TXT_RSA_DES_40_CBC_SHA		"EXP-DES-CBC-SHA"
+#define SSL3_TXT_RSA_DES_64_CBC_SHA		"DES-CBC-SHA"
+#define SSL3_TXT_RSA_DES_192_CBC3_SHA		"DES-CBC3-SHA"
+
+#define SSL3_TXT_DH_DSS_DES_40_CBC_SHA		"EXP-DH-DSS-DES-CBC-SHA"
+#define SSL3_TXT_DH_DSS_DES_64_CBC_SHA		"DH-DSS-DES-CBC-SHA"
+#define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA 	"DH-DSS-DES-CBC3-SHA"
+#define SSL3_TXT_DH_RSA_DES_40_CBC_SHA		"EXP-DH-RSA-DES-CBC-SHA"
+#define SSL3_TXT_DH_RSA_DES_64_CBC_SHA		"DH-RSA-DES-CBC-SHA"
+#define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA 	"DH-RSA-DES-CBC3-SHA"
+
+#define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA		"EXP-EDH-DSS-DES-CBC-SHA"
+#define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA		"EDH-DSS-DES-CBC-SHA"
+#define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA	"EDH-DSS-DES-CBC3-SHA"
+#define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA		"EXP-EDH-RSA-DES-CBC-SHA"
+#define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA		"EDH-RSA-DES-CBC-SHA"
+#define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA	"EDH-RSA-DES-CBC3-SHA"
+
+#define SSL3_TXT_ADH_RC4_40_MD5			"EXP-ADH-RC4-MD5"
+#define SSL3_TXT_ADH_RC4_128_MD5		"ADH-RC4-MD5"
+#define SSL3_TXT_ADH_DES_40_CBC_SHA		"EXP-ADH-DES-CBC-SHA"
+#define SSL3_TXT_ADH_DES_64_CBC_SHA		"ADH-DES-CBC-SHA"
+#define SSL3_TXT_ADH_DES_192_CBC_SHA		"ADH-DES-CBC3-SHA"
+
+#if 0
+	#define SSL3_TXT_FZA_DMS_NULL_SHA		"FZA-NULL-SHA"
+	#define SSL3_TXT_FZA_DMS_FZA_SHA		"FZA-FZA-CBC-SHA"
+	#define SSL3_TXT_FZA_DMS_RC4_SHA		"FZA-RC4-SHA"
+#endif
+
+#define SSL3_TXT_KRB5_DES_64_CBC_SHA		"KRB5-DES-CBC-SHA"
+#define SSL3_TXT_KRB5_DES_192_CBC3_SHA		"KRB5-DES-CBC3-SHA"
+#define SSL3_TXT_KRB5_RC4_128_SHA		"KRB5-RC4-SHA"
+#define SSL3_TXT_KRB5_IDEA_128_CBC_SHA	       	"KRB5-IDEA-CBC-SHA"
+#define SSL3_TXT_KRB5_DES_64_CBC_MD5       	"KRB5-DES-CBC-MD5"
+#define SSL3_TXT_KRB5_DES_192_CBC3_MD5       	"KRB5-DES-CBC3-MD5"
+#define SSL3_TXT_KRB5_RC4_128_MD5		"KRB5-RC4-MD5"
+#define SSL3_TXT_KRB5_IDEA_128_CBC_MD5 		"KRB5-IDEA-CBC-MD5"
+
+#define SSL3_TXT_KRB5_DES_40_CBC_SHA 		"EXP-KRB5-DES-CBC-SHA"
+#define SSL3_TXT_KRB5_RC2_40_CBC_SHA 		"EXP-KRB5-RC2-CBC-SHA"
+#define SSL3_TXT_KRB5_RC4_40_SHA	 	"EXP-KRB5-RC4-SHA"
+#define SSL3_TXT_KRB5_DES_40_CBC_MD5 		"EXP-KRB5-DES-CBC-MD5"
+#define SSL3_TXT_KRB5_RC2_40_CBC_MD5 		"EXP-KRB5-RC2-CBC-MD5"
+#define SSL3_TXT_KRB5_RC4_40_MD5	 	"EXP-KRB5-RC4-MD5"
+
+#define SSL3_SSL_SESSION_ID_LENGTH		32
+#define SSL3_MAX_SSL_SESSION_ID_LENGTH		32
+
+#define SSL3_MASTER_SECRET_SIZE			48
+#define SSL3_RANDOM_SIZE			32
+#define SSL3_SESSION_ID_SIZE			32
+#define SSL3_RT_HEADER_LENGTH			5
+
+#ifndef SSL3_ALIGN_PAYLOAD
+ /* Some will argue that this increases memory footprint, but it's
+  * not actually true. Point is that malloc has to return at least
+  * 64-bit aligned pointers, meaning that allocating 5 bytes wastes
+  * 3 bytes in either case. Suggested pre-gaping simply moves these
+  * wasted bytes from the end of allocated region to its front,
+  * but makes data payload aligned, which improves performance:-) */
+# define SSL3_ALIGN_PAYLOAD			8
+#else
+# if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0
+#  error "insane SSL3_ALIGN_PAYLOAD"
+#  undef SSL3_ALIGN_PAYLOAD
+# endif
+#endif
+
+/* This is the maximum MAC (digest) size used by the SSL library.
+ * Currently maximum of 20 is used by SHA1, but we reserve for
+ * future extension for 512-bit hashes.
+ */
+
+#define SSL3_RT_MAX_MD_SIZE			64
+
+/* Maximum block size used in all ciphersuites. Currently 16 for AES.
+ */
+
+#define	SSL_RT_MAX_CIPHER_BLOCK_SIZE		16
+
+#define SSL3_RT_MAX_EXTRA			(16384)
+
+/* Default buffer length used for writen records.  Thus a generated record
+ * will contain plaintext no larger than this value. */
+#define SSL3_RT_DEFAULT_PLAIN_LENGTH	2048
+/* Maximum plaintext length: defined by SSL/TLS standards */
+#define SSL3_RT_MAX_PLAIN_LENGTH		16384
+/* Maximum compression overhead: defined by SSL/TLS standards */
+#define SSL3_RT_MAX_COMPRESSED_OVERHEAD		1024
+
+/* The standards give a maximum encryption overhead of 1024 bytes.
+ * In practice the value is lower than this. The overhead is the maximum
+ * number of padding bytes (256) plus the mac size.
+ */
+#define SSL3_RT_MAX_ENCRYPTED_OVERHEAD	(256 + SSL3_RT_MAX_MD_SIZE)
+
+/* OpenSSL currently only uses a padding length of at most one block so
+ * the send overhead is smaller.
+ */
+
+#define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \
+			(SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE)
+
+/* If compression isn't used don't include the compression overhead */
+
+#ifdef OPENSSL_NO_COMP
+#define SSL3_RT_MAX_COMPRESSED_LENGTH		SSL3_RT_MAX_PLAIN_LENGTH
+#else
+#define SSL3_RT_MAX_COMPRESSED_LENGTH	\
+		(SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD)
+#endif
+#define SSL3_RT_MAX_ENCRYPTED_LENGTH	\
+		(SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH)
+#define SSL3_RT_MAX_PACKET_SIZE		\
+		(SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
+
+/* Extra space for empty fragment, headers, MAC, and padding. */
+#define SSL3_RT_DEFAULT_WRITE_OVERHEAD  256
+#define SSL3_RT_DEFAULT_PACKET_SIZE     4096 - SSL3_RT_DEFAULT_WRITE_OVERHEAD
+#if SSL3_RT_DEFAULT_PLAIN_LENGTH + SSL3_RT_DEFAULT_WRITE_OVERHEAD > SSL3_RT_DEFAULT_PACKET_SIZE
+#error "Insufficient space allocated for write buffers."
+#endif
+
+#define SSL3_MD_CLIENT_FINISHED_CONST	"\x43\x4C\x4E\x54"
+#define SSL3_MD_SERVER_FINISHED_CONST	"\x53\x52\x56\x52"
+
+#define SSL3_VERSION			0x0300
+#define SSL3_VERSION_MAJOR		0x03
+#define SSL3_VERSION_MINOR		0x00
+
+#define SSL3_RT_CHANGE_CIPHER_SPEC	20
+#define SSL3_RT_ALERT			21
+#define SSL3_RT_HANDSHAKE		22
+#define SSL3_RT_APPLICATION_DATA	23
+
+#define SSL3_AL_WARNING			1
+#define SSL3_AL_FATAL			2
+
+#define SSL3_AD_CLOSE_NOTIFY		 0
+#define SSL3_AD_UNEXPECTED_MESSAGE	10	/* fatal */
+#define SSL3_AD_BAD_RECORD_MAC		20	/* fatal */
+#define SSL3_AD_DECOMPRESSION_FAILURE	30	/* fatal */
+#define SSL3_AD_HANDSHAKE_FAILURE	40	/* fatal */
+#define SSL3_AD_NO_CERTIFICATE		41
+#define SSL3_AD_BAD_CERTIFICATE		42
+#define SSL3_AD_UNSUPPORTED_CERTIFICATE	43
+#define SSL3_AD_CERTIFICATE_REVOKED	44
+#define SSL3_AD_CERTIFICATE_EXPIRED	45
+#define SSL3_AD_CERTIFICATE_UNKNOWN	46
+#define SSL3_AD_ILLEGAL_PARAMETER	47	/* fatal */
+
+typedef struct ssl3_record_st
+	{
+/*r */	int type;               /* type of record */
+/*rw*/	unsigned int length;    /* How many bytes available */
+/*r */	unsigned int off;       /* read/write offset into 'buf' */
+/*rw*/	unsigned char *data;    /* pointer to the record data */
+/*rw*/	unsigned char *input;   /* where the decode bytes are */
+/*r */	unsigned char *comp;    /* only used with decompression - malloc()ed */
+/*r */  unsigned long epoch;    /* epoch number, needed by DTLS1 */
+/*r */  unsigned char seq_num[8]; /* sequence number, needed by DTLS1 */
+	} SSL3_RECORD;
+
+typedef struct ssl3_buffer_st
+	{
+	unsigned char *buf;     /* at least SSL3_RT_MAX_PACKET_SIZE bytes,
+	                         * see ssl3_setup_buffers() */
+	size_t len;             /* buffer size */
+	int offset;             /* where to 'copy from' */
+	int left;               /* how many bytes left */
+	} SSL3_BUFFER;
+
+#define SSL3_CT_RSA_SIGN			1
+#define SSL3_CT_DSS_SIGN			2
+#define SSL3_CT_RSA_FIXED_DH			3
+#define SSL3_CT_DSS_FIXED_DH			4
+#define SSL3_CT_RSA_EPHEMERAL_DH		5
+#define SSL3_CT_DSS_EPHEMERAL_DH		6
+#define SSL3_CT_FORTEZZA_DMS			20
+/* SSL3_CT_NUMBER is used to size arrays and it must be large
+ * enough to contain all of the cert types defined either for
+ * SSLv3 and TLSv1.
+ */
+#define SSL3_CT_NUMBER			9
+
+
+#define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS	0x0001
+#define SSL3_FLAGS_DELAY_CLIENT_FINISHED	0x0002
+#define SSL3_FLAGS_POP_BUFFER			0x0004
+#define TLS1_FLAGS_TLS_PADDING_BUG		0x0008
+#define TLS1_FLAGS_SKIP_CERT_VERIFY		0x0010
+ 
+/* SSL3_FLAGS_SGC_RESTART_DONE is set when we
+ * restart a handshake because of MS SGC and so prevents us
+ * from restarting the handshake in a loop. It's reset on a
+ * renegotiation, so effectively limits the client to one restart
+ * per negotiation. This limits the possibility of a DDoS
+ * attack where the client handshakes in a loop using SGC to
+ * restart. Servers which permit renegotiation can still be
+ * effected, but we can't prevent that.
+ */
+#define SSL3_FLAGS_SGC_RESTART_DONE		0x0040
+
+typedef struct ssl3_state_st
+	{
+	long flags;
+	int delay_buf_pop_ret;
+
+	unsigned char read_sequence[8];
+	int read_mac_secret_size;
+	unsigned char read_mac_secret[EVP_MAX_MD_SIZE];
+	unsigned char write_sequence[8];
+	int write_mac_secret_size;
+	unsigned char write_mac_secret[EVP_MAX_MD_SIZE];
+
+	unsigned char server_random[SSL3_RANDOM_SIZE];
+	unsigned char client_random[SSL3_RANDOM_SIZE];
+
+	/* flags for countermeasure against known-IV weakness */
+	int need_empty_fragments;
+	int empty_fragment_done;
+
+	/* The value of 'extra' when the buffers were initialized */
+	int init_extra;
+
+	SSL3_BUFFER rbuf;	/* read IO goes into here */
+	SSL3_BUFFER wbuf;	/* write IO goes into here */
+
+	SSL3_RECORD rrec;	/* each decoded record goes in here */
+	SSL3_RECORD wrec;	/* goes out from here */
+
+	/* storage for Alert/Handshake protocol data received but not
+	 * yet processed by ssl3_read_bytes: */
+	unsigned char alert_fragment[2];
+	unsigned int alert_fragment_len;
+	unsigned char handshake_fragment[4];
+	unsigned int handshake_fragment_len;
+
+	/* partial write - check the numbers match */
+	unsigned int wnum;	/* number of bytes sent so far */
+	int wpend_tot;		/* number bytes written */
+	int wpend_type;
+	int wpend_ret;		/* number of bytes submitted */
+	const unsigned char *wpend_buf;
+
+	/* used during startup, digest all incoming/outgoing packets */
+	BIO *handshake_buffer;
+	/* When set of handshake digests is determined, buffer is hashed
+	 * and freed and MD_CTX-es for all required digests are stored in
+	 * this array */
+	EVP_MD_CTX **handshake_dgst;
+	/* this is set whenerver we see a change_cipher_spec message
+	 * come in when we are not looking for one */
+	int change_cipher_spec;
+
+	int warn_alert;
+	int fatal_alert;
+	/* we allow one fatal and one warning alert to be outstanding,
+	 * send close alert via the warning alert */
+	int alert_dispatch;
+	unsigned char send_alert[2];
+
+	/* This flag is set when we should renegotiate ASAP, basically when
+	 * there is no more data in the read or write buffers */
+	int renegotiate;
+	int total_renegotiations;
+	int num_renegotiations;
+
+	int in_read_app_data;
+
+	/* Opaque PRF input as used for the current handshake.
+	 * These fields are used only if TLSEXT_TYPE_opaque_prf_input is defined
+	 * (otherwise, they are merely present to improve binary compatibility) */
+	void *client_opaque_prf_input;
+	size_t client_opaque_prf_input_len;
+	void *server_opaque_prf_input;
+	size_t server_opaque_prf_input_len;
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+	/* Set if we saw the Next Protocol Negotiation extension from
+	   our peer. */
+	int next_proto_neg_seen;
+#endif
+
+	struct	{
+		/* actually only needs to be 16+20 */
+		unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2];
+
+		/* actually only need to be 16+20 for SSLv3 and 12 for TLS */
+		unsigned char finish_md[EVP_MAX_MD_SIZE*2];
+		int finish_md_len;
+		unsigned char peer_finish_md[EVP_MAX_MD_SIZE*2];
+		int peer_finish_md_len;
+		
+		unsigned long message_size;
+		int message_type;
+
+		/* used to hold the new cipher we are going to use */
+		const SSL_CIPHER *new_cipher;
+#ifndef OPENSSL_NO_DH
+		DH *dh;
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+		EC_KEY *ecdh; /* holds short lived ECDH key */
+#endif
+
+		/* used when SSL_ST_FLUSH_DATA is entered */
+		int next_state;			
+
+		int reuse_message;
+
+		/* used for certificate requests */
+		int cert_req;
+		int ctype_num;
+		char ctype[SSL3_CT_NUMBER];
+		STACK_OF(X509_NAME) *ca_names;
+
+		int use_rsa_tmp;
+
+		int key_block_length;
+		unsigned char *key_block;
+
+		const EVP_CIPHER *new_sym_enc;
+		const EVP_MD *new_hash;
+		int new_mac_pkey_type;
+		int new_mac_secret_size;
+#ifndef OPENSSL_NO_COMP
+		const SSL_COMP *new_compression;
+#else
+		char *new_compression;
+#endif
+		int cert_request;
+		} tmp;
+
+        /* Connection binding to prevent renegotiation attacks */
+        unsigned char previous_client_finished[EVP_MAX_MD_SIZE];
+        unsigned char previous_client_finished_len;
+        unsigned char previous_server_finished[EVP_MAX_MD_SIZE];
+        unsigned char previous_server_finished_len;
+        int send_connection_binding; /* TODOEKR */
+	} SSL3_STATE;
+
+
+/* SSLv3 */
+/*client */
+/* extra state */
+#define SSL3_ST_CW_FLUSH		(0x100|SSL_ST_CONNECT)
+#define SSL3_ST_CUTTHROUGH_COMPLETE	(0x101|SSL_ST_CONNECT)
+/* write to server */
+#define SSL3_ST_CW_CLNT_HELLO_A		(0x110|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CLNT_HELLO_B		(0x111|SSL_ST_CONNECT)
+/* read from server */
+#define SSL3_ST_CR_SRVR_HELLO_A		(0x120|SSL_ST_CONNECT)
+#define SSL3_ST_CR_SRVR_HELLO_B		(0x121|SSL_ST_CONNECT)
+#define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A (0x126|SSL_ST_CONNECT)
+#define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B (0x127|SSL_ST_CONNECT)
+#define SSL3_ST_CR_CERT_A		(0x130|SSL_ST_CONNECT)
+#define SSL3_ST_CR_CERT_B		(0x131|SSL_ST_CONNECT)
+#define SSL3_ST_CR_KEY_EXCH_A		(0x140|SSL_ST_CONNECT)
+#define SSL3_ST_CR_KEY_EXCH_B		(0x141|SSL_ST_CONNECT)
+#define SSL3_ST_CR_CERT_REQ_A		(0x150|SSL_ST_CONNECT)
+#define SSL3_ST_CR_CERT_REQ_B		(0x151|SSL_ST_CONNECT)
+#define SSL3_ST_CR_SRVR_DONE_A		(0x160|SSL_ST_CONNECT)
+#define SSL3_ST_CR_SRVR_DONE_B		(0x161|SSL_ST_CONNECT)
+/* write to server */
+#define SSL3_ST_CW_CERT_A		(0x170|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CERT_B		(0x171|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CERT_C		(0x172|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CERT_D		(0x173|SSL_ST_CONNECT)
+#define SSL3_ST_CW_KEY_EXCH_A		(0x180|SSL_ST_CONNECT)
+#define SSL3_ST_CW_KEY_EXCH_B		(0x181|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CERT_VRFY_A		(0x190|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CERT_VRFY_B		(0x191|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CHANGE_A		(0x1A0|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CHANGE_B		(0x1A1|SSL_ST_CONNECT)
+#ifndef OPENSSL_NO_NEXTPROTONEG
+#define SSL3_ST_CW_NEXT_PROTO_A		(0x200|SSL_ST_CONNECT)
+#define SSL3_ST_CW_NEXT_PROTO_B		(0x201|SSL_ST_CONNECT)
+#endif
+#define SSL3_ST_CW_FINISHED_A		(0x1B0|SSL_ST_CONNECT)
+#define SSL3_ST_CW_FINISHED_B		(0x1B1|SSL_ST_CONNECT)
+/* read from server */
+#define SSL3_ST_CR_CHANGE_A		(0x1C0|SSL_ST_CONNECT)
+#define SSL3_ST_CR_CHANGE_B		(0x1C1|SSL_ST_CONNECT)
+#define SSL3_ST_CR_FINISHED_A		(0x1D0|SSL_ST_CONNECT)
+#define SSL3_ST_CR_FINISHED_B		(0x1D1|SSL_ST_CONNECT)
+#define SSL3_ST_CR_SESSION_TICKET_A	(0x1E0|SSL_ST_CONNECT)
+#define SSL3_ST_CR_SESSION_TICKET_B	(0x1E1|SSL_ST_CONNECT)
+#define SSL3_ST_CR_CERT_STATUS_A	(0x1F0|SSL_ST_CONNECT)
+#define SSL3_ST_CR_CERT_STATUS_B	(0x1F1|SSL_ST_CONNECT)
+
+/* server */
+/* extra state */
+#define SSL3_ST_SW_FLUSH		(0x100|SSL_ST_ACCEPT)
+/* read from client */
+/* Do not change the number values, they do matter */
+#define SSL3_ST_SR_CLNT_HELLO_A		(0x110|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CLNT_HELLO_B		(0x111|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CLNT_HELLO_C		(0x112|SSL_ST_ACCEPT)
+/* write to client */
+#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT)
+#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_HELLO_REQ_A		(0x120|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_HELLO_REQ_B		(0x121|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_HELLO_REQ_C		(0x122|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_SRVR_HELLO_A		(0x130|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_SRVR_HELLO_B		(0x131|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_CERT_A		(0x140|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_CERT_B		(0x141|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_KEY_EXCH_A		(0x150|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_KEY_EXCH_B		(0x151|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_CERT_REQ_A		(0x160|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_CERT_REQ_B		(0x161|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_SRVR_DONE_A		(0x170|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_SRVR_DONE_B		(0x171|SSL_ST_ACCEPT)
+/* read from client */
+#define SSL3_ST_SR_CERT_A		(0x180|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CERT_B		(0x181|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_KEY_EXCH_A		(0x190|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_KEY_EXCH_B		(0x191|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CERT_VRFY_A		(0x1A0|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CERT_VRFY_B		(0x1A1|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CHANGE_A		(0x1B0|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CHANGE_B		(0x1B1|SSL_ST_ACCEPT)
+#ifndef OPENSSL_NO_NEXTPROTONEG
+#define SSL3_ST_SR_NEXT_PROTO_A		(0x210|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_NEXT_PROTO_B		(0x211|SSL_ST_ACCEPT)
+#endif
+#define SSL3_ST_SR_FINISHED_A		(0x1C0|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_FINISHED_B		(0x1C1|SSL_ST_ACCEPT)
+/* write to client */
+#define SSL3_ST_SW_CHANGE_A		(0x1D0|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_CHANGE_B		(0x1D1|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_FINISHED_A		(0x1E0|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_FINISHED_B		(0x1E1|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_SESSION_TICKET_A	(0x1F0|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_SESSION_TICKET_B	(0x1F1|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_CERT_STATUS_A	(0x200|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_CERT_STATUS_B	(0x201|SSL_ST_ACCEPT)
+
+#define SSL3_MT_HELLO_REQUEST			0
+#define SSL3_MT_CLIENT_HELLO			1
+#define SSL3_MT_SERVER_HELLO			2
+#define	SSL3_MT_NEWSESSION_TICKET		4
+#define SSL3_MT_CERTIFICATE			11
+#define SSL3_MT_SERVER_KEY_EXCHANGE		12
+#define SSL3_MT_CERTIFICATE_REQUEST		13
+#define SSL3_MT_SERVER_DONE			14
+#define SSL3_MT_CERTIFICATE_VERIFY		15
+#define SSL3_MT_CLIENT_KEY_EXCHANGE		16
+#define SSL3_MT_FINISHED			20
+#define SSL3_MT_CERTIFICATE_STATUS		22
+#ifndef OPENSSL_NO_NEXTPROTONEG
+#define SSL3_MT_NEXT_PROTO			67
+#endif
+#define DTLS1_MT_HELLO_VERIFY_REQUEST    3
+
+
+#define SSL3_MT_CCS				1
+
+/* These are used when changing over to a new cipher */
+#define SSL3_CC_READ		0x01
+#define SSL3_CC_WRITE		0x02
+#define SSL3_CC_CLIENT		0x10
+#define SSL3_CC_SERVER		0x20
+#define SSL3_CHANGE_CIPHER_CLIENT_WRITE	(SSL3_CC_CLIENT|SSL3_CC_WRITE)	
+#define SSL3_CHANGE_CIPHER_SERVER_READ	(SSL3_CC_SERVER|SSL3_CC_READ)
+#define SSL3_CHANGE_CIPHER_CLIENT_READ	(SSL3_CC_CLIENT|SSL3_CC_READ)
+#define SSL3_CHANGE_CIPHER_SERVER_WRITE	(SSL3_CC_SERVER|SSL3_CC_WRITE)
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/ssl/ssl_algs.c b/openssl/ssl/ssl_algs.c
new file mode 100644
index 0000000..0967b2d
--- /dev/null
+++ b/openssl/ssl/ssl_algs.c
@@ -0,0 +1,140 @@
+/* ssl/ssl_algs.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/objects.h>
+#include <openssl/lhash.h>
+#include "ssl_locl.h"
+
+int SSL_library_init(void)
+	{
+
+#ifndef OPENSSL_NO_DES
+	EVP_add_cipher(EVP_des_cbc());
+	EVP_add_cipher(EVP_des_ede3_cbc());
+#endif
+#ifndef OPENSSL_NO_IDEA
+	EVP_add_cipher(EVP_idea_cbc());
+#endif
+#ifndef OPENSSL_NO_RC4
+	EVP_add_cipher(EVP_rc4());
+#endif  
+#ifndef OPENSSL_NO_RC2
+	EVP_add_cipher(EVP_rc2_cbc());
+	/* Not actually used for SSL/TLS but this makes PKCS#12 work
+	 * if an application only calls SSL_library_init().
+	 */
+	EVP_add_cipher(EVP_rc2_40_cbc());
+#endif
+#ifndef OPENSSL_NO_AES
+	EVP_add_cipher(EVP_aes_128_cbc());
+	EVP_add_cipher(EVP_aes_192_cbc());
+	EVP_add_cipher(EVP_aes_256_cbc());
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+	EVP_add_cipher(EVP_camellia_128_cbc());
+	EVP_add_cipher(EVP_camellia_256_cbc());
+#endif
+
+#ifndef OPENSSL_NO_SEED
+	EVP_add_cipher(EVP_seed_cbc());
+#endif
+  
+#ifndef OPENSSL_NO_MD5
+	EVP_add_digest(EVP_md5());
+	EVP_add_digest_alias(SN_md5,"ssl2-md5");
+	EVP_add_digest_alias(SN_md5,"ssl3-md5");
+#endif
+#ifndef OPENSSL_NO_SHA
+	EVP_add_digest(EVP_sha1()); /* RSA with sha1 */
+	EVP_add_digest_alias(SN_sha1,"ssl3-sha1");
+	EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA);
+#endif
+#ifndef OPENSSL_NO_SHA256
+	EVP_add_digest(EVP_sha224());
+	EVP_add_digest(EVP_sha256());
+#endif
+#ifndef OPENSSL_NO_SHA512
+	EVP_add_digest(EVP_sha384());
+	EVP_add_digest(EVP_sha512());
+#endif
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_DSA)
+	EVP_add_digest(EVP_dss1()); /* DSA with sha1 */
+	EVP_add_digest_alias(SN_dsaWithSHA1,SN_dsaWithSHA1_2);
+	EVP_add_digest_alias(SN_dsaWithSHA1,"DSS1");
+	EVP_add_digest_alias(SN_dsaWithSHA1,"dss1");
+#endif
+#ifndef OPENSSL_NO_ECDSA
+	EVP_add_digest(EVP_ecdsa());
+#endif
+	/* If you want support for phased out ciphers, add the following */
+#if 0
+	EVP_add_digest(EVP_sha());
+	EVP_add_digest(EVP_dss());
+#endif
+#ifndef OPENSSL_NO_COMP
+	/* This will initialise the built-in compression algorithms.
+	   The value returned is a STACK_OF(SSL_COMP), but that can
+	   be discarded safely */
+	(void)SSL_COMP_get_compression_methods();
+#endif
+	/* initialize cipher/digest methods table */
+	ssl_load_ciphers();
+	return(1);
+	}
+
diff --git a/openssl/ssl/ssl_asn1.c b/openssl/ssl/ssl_asn1.c
new file mode 100644
index 0000000..d7f4c60
--- /dev/null
+++ b/openssl/ssl/ssl_asn1.c
@@ -0,0 +1,592 @@
+/* ssl/ssl_asn1.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "ssl_locl.h"
+#include <openssl/asn1_mac.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+typedef struct ssl_session_asn1_st
+	{
+	ASN1_INTEGER version;
+	ASN1_INTEGER ssl_version;
+	ASN1_OCTET_STRING cipher;
+	ASN1_OCTET_STRING comp_id;
+	ASN1_OCTET_STRING master_key;
+	ASN1_OCTET_STRING session_id;
+	ASN1_OCTET_STRING session_id_context;
+	ASN1_OCTET_STRING key_arg;
+#ifndef OPENSSL_NO_KRB5
+        ASN1_OCTET_STRING krb5_princ;
+#endif /* OPENSSL_NO_KRB5 */
+	ASN1_INTEGER time;
+	ASN1_INTEGER timeout;
+	ASN1_INTEGER verify_result;
+#ifndef OPENSSL_NO_TLSEXT
+	ASN1_OCTET_STRING tlsext_hostname;
+	ASN1_INTEGER tlsext_tick_lifetime;
+	ASN1_OCTET_STRING tlsext_tick;
+#endif /* OPENSSL_NO_TLSEXT */
+#ifndef OPENSSL_NO_PSK
+	ASN1_OCTET_STRING psk_identity_hint;
+	ASN1_OCTET_STRING psk_identity;
+#endif /* OPENSSL_NO_PSK */
+	} SSL_SESSION_ASN1;
+
+int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
+	{
+#define LSIZE2 (sizeof(long)*2)
+	int v1=0,v2=0,v3=0,v4=0,v5=0,v7=0,v8=0;
+	unsigned char buf[4],ibuf1[LSIZE2],ibuf2[LSIZE2];
+	unsigned char ibuf3[LSIZE2],ibuf4[LSIZE2],ibuf5[LSIZE2];
+#ifndef OPENSSL_NO_TLSEXT
+	int v6=0,v9=0,v10=0;
+	unsigned char ibuf6[LSIZE2];
+#endif
+#ifndef OPENSSL_NO_COMP
+	unsigned char cbuf;
+	int v11=0;
+#endif
+	long l;
+	SSL_SESSION_ASN1 a;
+	M_ASN1_I2D_vars(in);
+
+	if ((in == NULL) || ((in->cipher == NULL) && (in->cipher_id == 0)))
+		return(0);
+
+	/* Note that I cheat in the following 2 assignments.  I know
+	 * that if the ASN1_INTEGER passed to ASN1_INTEGER_set
+	 * is > sizeof(long)+1, the buffer will not be re-OPENSSL_malloc()ed.
+	 * This is a bit evil but makes things simple, no dynamic allocation
+	 * to clean up :-) */
+	a.version.length=LSIZE2;
+	a.version.type=V_ASN1_INTEGER;
+	a.version.data=ibuf1;
+	ASN1_INTEGER_set(&(a.version),SSL_SESSION_ASN1_VERSION);
+
+	a.ssl_version.length=LSIZE2;
+	a.ssl_version.type=V_ASN1_INTEGER;
+	a.ssl_version.data=ibuf2;
+	ASN1_INTEGER_set(&(a.ssl_version),in->ssl_version);
+
+	a.cipher.type=V_ASN1_OCTET_STRING;
+	a.cipher.data=buf;
+
+	if (in->cipher == NULL)
+		l=in->cipher_id;
+	else
+		l=in->cipher->id;
+	if (in->ssl_version == SSL2_VERSION)
+		{
+		a.cipher.length=3;
+		buf[0]=((unsigned char)(l>>16L))&0xff;
+		buf[1]=((unsigned char)(l>> 8L))&0xff;
+		buf[2]=((unsigned char)(l     ))&0xff;
+		}
+	else
+		{
+		a.cipher.length=2;
+		buf[0]=((unsigned char)(l>>8L))&0xff;
+		buf[1]=((unsigned char)(l    ))&0xff;
+		}
+
+#ifndef OPENSSL_NO_COMP
+	if (in->compress_meth)
+		{
+		cbuf = (unsigned char)in->compress_meth;
+		a.comp_id.length = 1;
+		a.comp_id.type = V_ASN1_OCTET_STRING;
+		a.comp_id.data = &cbuf;
+		}
+#endif
+
+	a.master_key.length=in->master_key_length;
+	a.master_key.type=V_ASN1_OCTET_STRING;
+	a.master_key.data=in->master_key;
+
+	a.session_id.length=in->session_id_length;
+	a.session_id.type=V_ASN1_OCTET_STRING;
+	a.session_id.data=in->session_id;
+
+	a.session_id_context.length=in->sid_ctx_length;
+	a.session_id_context.type=V_ASN1_OCTET_STRING;
+	a.session_id_context.data=in->sid_ctx;
+
+	a.key_arg.length=in->key_arg_length;
+	a.key_arg.type=V_ASN1_OCTET_STRING;
+	a.key_arg.data=in->key_arg;
+
+#ifndef OPENSSL_NO_KRB5
+	if (in->krb5_client_princ_len)
+		{
+		a.krb5_princ.length=in->krb5_client_princ_len;
+		a.krb5_princ.type=V_ASN1_OCTET_STRING;
+		a.krb5_princ.data=in->krb5_client_princ;
+		}
+#endif /* OPENSSL_NO_KRB5 */
+
+	if (in->time != 0L)
+		{
+		a.time.length=LSIZE2;
+		a.time.type=V_ASN1_INTEGER;
+		a.time.data=ibuf3;
+		ASN1_INTEGER_set(&(a.time),in->time);
+		}
+
+	if (in->timeout != 0L)
+		{
+		a.timeout.length=LSIZE2;
+		a.timeout.type=V_ASN1_INTEGER;
+		a.timeout.data=ibuf4;
+		ASN1_INTEGER_set(&(a.timeout),in->timeout);
+		}
+
+	if (in->verify_result != X509_V_OK)
+		{
+		a.verify_result.length=LSIZE2;
+		a.verify_result.type=V_ASN1_INTEGER;
+		a.verify_result.data=ibuf5;
+		ASN1_INTEGER_set(&a.verify_result,in->verify_result);
+		}
+
+#ifndef OPENSSL_NO_TLSEXT
+	if (in->tlsext_hostname)
+                {
+                a.tlsext_hostname.length=strlen(in->tlsext_hostname);
+                a.tlsext_hostname.type=V_ASN1_OCTET_STRING;
+                a.tlsext_hostname.data=(unsigned char *)in->tlsext_hostname;
+                }
+	if (in->tlsext_tick)
+                {
+                a.tlsext_tick.length= in->tlsext_ticklen;
+                a.tlsext_tick.type=V_ASN1_OCTET_STRING;
+                a.tlsext_tick.data=(unsigned char *)in->tlsext_tick;
+                }
+	if (in->tlsext_tick_lifetime_hint > 0)
+		{
+		a.tlsext_tick_lifetime.length=LSIZE2;
+		a.tlsext_tick_lifetime.type=V_ASN1_INTEGER;
+		a.tlsext_tick_lifetime.data=ibuf6;
+		ASN1_INTEGER_set(&a.tlsext_tick_lifetime,in->tlsext_tick_lifetime_hint);
+		}
+#endif /* OPENSSL_NO_TLSEXT */
+#ifndef OPENSSL_NO_PSK
+	if (in->psk_identity_hint)
+		{
+		a.psk_identity_hint.length=strlen(in->psk_identity_hint);
+		a.psk_identity_hint.type=V_ASN1_OCTET_STRING;
+		a.psk_identity_hint.data=(unsigned char *)(in->psk_identity_hint);
+		}
+	if (in->psk_identity)
+		{
+		a.psk_identity.length=strlen(in->psk_identity);
+		a.psk_identity.type=V_ASN1_OCTET_STRING;
+		a.psk_identity.data=(unsigned char *)(in->psk_identity);
+		}
+#endif /* OPENSSL_NO_PSK */
+
+	M_ASN1_I2D_len(&(a.version),		i2d_ASN1_INTEGER);
+	M_ASN1_I2D_len(&(a.ssl_version),	i2d_ASN1_INTEGER);
+	M_ASN1_I2D_len(&(a.cipher),		i2d_ASN1_OCTET_STRING);
+	M_ASN1_I2D_len(&(a.session_id),		i2d_ASN1_OCTET_STRING);
+	M_ASN1_I2D_len(&(a.master_key),		i2d_ASN1_OCTET_STRING);
+#ifndef OPENSSL_NO_KRB5
+	if (in->krb5_client_princ_len)
+        	M_ASN1_I2D_len(&(a.krb5_princ),	i2d_ASN1_OCTET_STRING);
+#endif /* OPENSSL_NO_KRB5 */
+	if (in->key_arg_length > 0)
+		M_ASN1_I2D_len_IMP_opt(&(a.key_arg),i2d_ASN1_OCTET_STRING);
+	if (in->time != 0L)
+		M_ASN1_I2D_len_EXP_opt(&(a.time),i2d_ASN1_INTEGER,1,v1);
+	if (in->timeout != 0L)
+		M_ASN1_I2D_len_EXP_opt(&(a.timeout),i2d_ASN1_INTEGER,2,v2);
+	if (in->peer != NULL)
+		M_ASN1_I2D_len_EXP_opt(in->peer,i2d_X509,3,v3);
+	M_ASN1_I2D_len_EXP_opt(&a.session_id_context,i2d_ASN1_OCTET_STRING,4,v4);
+	if (in->verify_result != X509_V_OK)
+		M_ASN1_I2D_len_EXP_opt(&(a.verify_result),i2d_ASN1_INTEGER,5,v5);
+
+#ifndef OPENSSL_NO_TLSEXT
+	if (in->tlsext_tick_lifetime_hint > 0)
+      	 	M_ASN1_I2D_len_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER,9,v9);
+	if (in->tlsext_tick)
+        	M_ASN1_I2D_len_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING,10,v10);
+	if (in->tlsext_hostname)
+        	M_ASN1_I2D_len_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING,6,v6);
+#ifndef OPENSSL_NO_COMP
+	if (in->compress_meth)
+        	M_ASN1_I2D_len_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11);
+#endif
+#endif /* OPENSSL_NO_TLSEXT */
+#ifndef OPENSSL_NO_PSK
+	if (in->psk_identity_hint)
+        	M_ASN1_I2D_len_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING,7,v7);
+	if (in->psk_identity)
+        	M_ASN1_I2D_len_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8);
+#endif /* OPENSSL_NO_PSK */
+
+	M_ASN1_I2D_seq_total();
+
+	M_ASN1_I2D_put(&(a.version),		i2d_ASN1_INTEGER);
+	M_ASN1_I2D_put(&(a.ssl_version),	i2d_ASN1_INTEGER);
+	M_ASN1_I2D_put(&(a.cipher),		i2d_ASN1_OCTET_STRING);
+	M_ASN1_I2D_put(&(a.session_id),		i2d_ASN1_OCTET_STRING);
+	M_ASN1_I2D_put(&(a.master_key),		i2d_ASN1_OCTET_STRING);
+#ifndef OPENSSL_NO_KRB5
+	if (in->krb5_client_princ_len)
+        	M_ASN1_I2D_put(&(a.krb5_princ),	i2d_ASN1_OCTET_STRING);
+#endif /* OPENSSL_NO_KRB5 */
+	if (in->key_arg_length > 0)
+		M_ASN1_I2D_put_IMP_opt(&(a.key_arg),i2d_ASN1_OCTET_STRING,0);
+	if (in->time != 0L)
+		M_ASN1_I2D_put_EXP_opt(&(a.time),i2d_ASN1_INTEGER,1,v1);
+	if (in->timeout != 0L)
+		M_ASN1_I2D_put_EXP_opt(&(a.timeout),i2d_ASN1_INTEGER,2,v2);
+	if (in->peer != NULL)
+		M_ASN1_I2D_put_EXP_opt(in->peer,i2d_X509,3,v3);
+	M_ASN1_I2D_put_EXP_opt(&a.session_id_context,i2d_ASN1_OCTET_STRING,4,
+			       v4);
+	if (in->verify_result != X509_V_OK)
+		M_ASN1_I2D_put_EXP_opt(&a.verify_result,i2d_ASN1_INTEGER,5,v5);
+#ifndef OPENSSL_NO_TLSEXT
+	if (in->tlsext_hostname)
+        	M_ASN1_I2D_put_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING,6,v6);
+#endif /* OPENSSL_NO_TLSEXT */
+#ifndef OPENSSL_NO_PSK
+	if (in->psk_identity_hint)
+		M_ASN1_I2D_put_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING,7,v7);
+	if (in->psk_identity)
+		M_ASN1_I2D_put_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8);
+#endif /* OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_TLSEXT
+	if (in->tlsext_tick_lifetime_hint > 0)
+      	 	M_ASN1_I2D_put_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER,9,v9);
+	if (in->tlsext_tick)
+        	M_ASN1_I2D_put_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING,10,v10);
+#endif /* OPENSSL_NO_TLSEXT */
+#ifndef OPENSSL_NO_COMP
+	if (in->compress_meth)
+        	M_ASN1_I2D_put_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11);
+#endif
+	M_ASN1_I2D_finish();
+	}
+
+SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
+			     long length)
+	{
+	int ssl_version=0,i;
+	long id;
+	ASN1_INTEGER ai,*aip;
+	ASN1_OCTET_STRING os,*osp;
+	M_ASN1_D2I_vars(a,SSL_SESSION *,SSL_SESSION_new);
+
+	aip= &ai;
+	osp= &os;
+
+	M_ASN1_D2I_Init();
+	M_ASN1_D2I_start_sequence();
+
+	ai.data=NULL; ai.length=0;
+	M_ASN1_D2I_get_x(ASN1_INTEGER,aip,d2i_ASN1_INTEGER);
+	if (ai.data != NULL) { OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; }
+
+	/* we don't care about the version right now :-) */
+	M_ASN1_D2I_get_x(ASN1_INTEGER,aip,d2i_ASN1_INTEGER);
+	ssl_version=(int)ASN1_INTEGER_get(aip);
+	ret->ssl_version=ssl_version;
+	if (ai.data != NULL) { OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; }
+
+	os.data=NULL; os.length=0;
+	M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING);
+	if (ssl_version == SSL2_VERSION)
+		{
+		if (os.length != 3)
+			{
+			c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH;
+			goto err;
+			}
+		id=0x02000000L|
+			((unsigned long)os.data[0]<<16L)|
+			((unsigned long)os.data[1]<< 8L)|
+			 (unsigned long)os.data[2];
+		}
+	else if ((ssl_version>>8) >= SSL3_VERSION_MAJOR)
+		{
+		if (os.length != 2)
+			{
+			c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH;
+			goto err;
+			}
+		id=0x03000000L|
+			((unsigned long)os.data[0]<<8L)|
+			 (unsigned long)os.data[1];
+		}
+	else
+		{
+		c.error=SSL_R_UNKNOWN_SSL_VERSION;
+		goto err;
+		}
+	
+	ret->cipher=NULL;
+	ret->cipher_id=id;
+
+	M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING);
+	if ((ssl_version>>8) >= SSL3_VERSION_MAJOR)
+		i=SSL3_MAX_SSL_SESSION_ID_LENGTH;
+	else /* if (ssl_version>>8 == SSL2_VERSION_MAJOR) */
+		i=SSL2_MAX_SSL_SESSION_ID_LENGTH;
+
+	if (os.length > i)
+		os.length = i;
+	if (os.length > (int)sizeof(ret->session_id)) /* can't happen */
+		os.length = sizeof(ret->session_id);
+
+	ret->session_id_length=os.length;
+	OPENSSL_assert(os.length <= (int)sizeof(ret->session_id));
+	memcpy(ret->session_id,os.data,os.length);
+
+	M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING);
+	if (os.length > SSL_MAX_MASTER_KEY_LENGTH)
+		ret->master_key_length=SSL_MAX_MASTER_KEY_LENGTH;
+	else
+		ret->master_key_length=os.length;
+	memcpy(ret->master_key,os.data,ret->master_key_length);
+
+	os.length=0;
+
+#ifndef OPENSSL_NO_KRB5
+	os.length=0;
+	M_ASN1_D2I_get_opt(osp,d2i_ASN1_OCTET_STRING,V_ASN1_OCTET_STRING);
+	if (os.data)
+		{
+        	if (os.length > SSL_MAX_KRB5_PRINCIPAL_LENGTH)
+            		ret->krb5_client_princ_len=0;
+		else
+			ret->krb5_client_princ_len=os.length;
+		memcpy(ret->krb5_client_princ,os.data,ret->krb5_client_princ_len);
+		OPENSSL_free(os.data);
+		os.data = NULL;
+		os.length = 0;
+		}
+	else
+		ret->krb5_client_princ_len=0;
+#endif /* OPENSSL_NO_KRB5 */
+
+	M_ASN1_D2I_get_IMP_opt(osp,d2i_ASN1_OCTET_STRING,0,V_ASN1_OCTET_STRING);
+	if (os.length > SSL_MAX_KEY_ARG_LENGTH)
+		ret->key_arg_length=SSL_MAX_KEY_ARG_LENGTH;
+	else
+		ret->key_arg_length=os.length;
+	memcpy(ret->key_arg,os.data,ret->key_arg_length);
+	if (os.data != NULL) OPENSSL_free(os.data);
+
+	ai.length=0;
+	M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,1);
+	if (ai.data != NULL)
+		{
+		ret->time=ASN1_INTEGER_get(aip);
+		OPENSSL_free(ai.data); ai.data=NULL; ai.length=0;
+		}
+	else
+		ret->time=(unsigned long)time(NULL);
+
+	ai.length=0;
+	M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,2);
+	if (ai.data != NULL)
+		{
+		ret->timeout=ASN1_INTEGER_get(aip);
+		OPENSSL_free(ai.data); ai.data=NULL; ai.length=0;
+		}
+	else
+		ret->timeout=3;
+
+	if (ret->peer != NULL)
+		{
+		X509_free(ret->peer);
+		ret->peer=NULL;
+		}
+	M_ASN1_D2I_get_EXP_opt(ret->peer,d2i_X509,3);
+
+	os.length=0;
+	os.data=NULL;
+	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,4);
+
+	if(os.data != NULL)
+	    {
+	    if (os.length > SSL_MAX_SID_CTX_LENGTH)
+		{
+		c.error=SSL_R_BAD_LENGTH;
+		goto err;
+		}
+	    else
+		{
+		ret->sid_ctx_length=os.length;
+		memcpy(ret->sid_ctx,os.data,os.length);
+		}
+	    OPENSSL_free(os.data); os.data=NULL; os.length=0;
+	    }
+	else
+	    ret->sid_ctx_length=0;
+
+	ai.length=0;
+	M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,5);
+	if (ai.data != NULL)
+		{
+		ret->verify_result=ASN1_INTEGER_get(aip);
+		OPENSSL_free(ai.data); ai.data=NULL; ai.length=0;
+		}
+	else
+		ret->verify_result=X509_V_OK;
+
+#ifndef OPENSSL_NO_TLSEXT
+	os.length=0;
+	os.data=NULL;
+	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,6);
+	if (os.data)
+		{
+		ret->tlsext_hostname = BUF_strndup((char *)os.data, os.length);
+		OPENSSL_free(os.data);
+		os.data = NULL;
+		os.length = 0;
+		}
+	else
+		ret->tlsext_hostname=NULL;
+#endif /* OPENSSL_NO_TLSEXT */
+
+#ifndef OPENSSL_NO_PSK
+	os.length=0;
+	os.data=NULL;
+	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,7);
+	if (os.data)
+		{
+		ret->psk_identity_hint = BUF_strndup((char *)os.data, os.length);
+		OPENSSL_free(os.data);
+		os.data = NULL;
+		os.length = 0;
+		}
+	else
+		ret->psk_identity_hint=NULL;
+#endif /* OPENSSL_NO_PSK */
+
+#ifndef OPENSSL_NO_TLSEXT
+	ai.length=0;
+	M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,9);
+	if (ai.data != NULL)
+		{
+		ret->tlsext_tick_lifetime_hint=ASN1_INTEGER_get(aip);
+		OPENSSL_free(ai.data); ai.data=NULL; ai.length=0;
+		}
+	else if (ret->tlsext_ticklen && ret->session_id_length)
+		ret->tlsext_tick_lifetime_hint = -1;
+	else
+		ret->tlsext_tick_lifetime_hint=0;
+	os.length=0;
+	os.data=NULL;
+	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,10);
+	if (os.data)
+		{
+		ret->tlsext_tick = os.data;
+		ret->tlsext_ticklen = os.length;
+		os.data = NULL;
+		os.length = 0;
+		}
+	else
+		ret->tlsext_tick=NULL;
+#endif /* OPENSSL_NO_TLSEXT */
+#ifndef OPENSSL_NO_COMP
+	os.length=0;
+	os.data=NULL;
+	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,11);
+	if (os.data)
+		{
+		ret->compress_meth = os.data[0];
+		OPENSSL_free(os.data);
+		os.data = NULL;
+		}
+#endif
+
+	M_ASN1_D2I_Finish(a,SSL_SESSION_free,SSL_F_D2I_SSL_SESSION);
+	}
diff --git a/openssl/ssl/ssl_cert.c b/openssl/ssl/ssl_cert.c
new file mode 100644
index 0000000..27256ee
--- /dev/null
+++ b/openssl/ssl/ssl_cert.c
@@ -0,0 +1,834 @@
+/*! \file ssl/ssl_cert.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include <stdio.h>
+
+#include "e_os.h"
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include "o_dir.h"
+#include <openssl/objects.h>
+#include <openssl/bio.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#include <openssl/bn.h>
+#include "ssl_locl.h"
+
+int SSL_get_ex_data_X509_STORE_CTX_idx(void)
+	{
+	static volatile int ssl_x509_store_ctx_idx= -1;
+	int got_write_lock = 0;
+
+	CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
+
+	if (ssl_x509_store_ctx_idx < 0)
+		{
+		CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
+		CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+		got_write_lock = 1;
+		
+		if (ssl_x509_store_ctx_idx < 0)
+			{
+			ssl_x509_store_ctx_idx=X509_STORE_CTX_get_ex_new_index(
+				0,"SSL for verify callback",NULL,NULL,NULL);
+			}
+		}
+
+	if (got_write_lock)
+		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+	else
+		CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
+	
+	return ssl_x509_store_ctx_idx;
+	}
+
+CERT *ssl_cert_new(void)
+	{
+	CERT *ret;
+
+	ret=(CERT *)OPENSSL_malloc(sizeof(CERT));
+	if (ret == NULL)
+		{
+		SSLerr(SSL_F_SSL_CERT_NEW,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	memset(ret,0,sizeof(CERT));
+
+	ret->key= &(ret->pkeys[SSL_PKEY_RSA_ENC]);
+	ret->references=1;
+
+	return(ret);
+	}
+
+CERT *ssl_cert_dup(CERT *cert)
+	{
+	CERT *ret;
+	int i;
+
+	ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
+	if (ret == NULL)
+		{
+		SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+
+	memset(ret, 0, sizeof(CERT));
+
+	ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
+	/* or ret->key = ret->pkeys + (cert->key - cert->pkeys),
+	 * if you find that more readable */
+
+	ret->valid = cert->valid;
+	ret->mask_k = cert->mask_k;
+	ret->mask_a = cert->mask_a;
+	ret->export_mask_k = cert->export_mask_k;
+	ret->export_mask_a = cert->export_mask_a;
+
+#ifndef OPENSSL_NO_RSA
+	if (cert->rsa_tmp != NULL)
+		{
+		RSA_up_ref(cert->rsa_tmp);
+		ret->rsa_tmp = cert->rsa_tmp;
+		}
+	ret->rsa_tmp_cb = cert->rsa_tmp_cb;
+#endif
+
+#ifndef OPENSSL_NO_DH
+	if (cert->dh_tmp != NULL)
+		{
+		ret->dh_tmp = DHparams_dup(cert->dh_tmp);
+		if (ret->dh_tmp == NULL)
+			{
+			SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB);
+			goto err;
+			}
+		if (cert->dh_tmp->priv_key)
+			{
+			BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
+			if (!b)
+				{
+				SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
+				goto err;
+				}
+			ret->dh_tmp->priv_key = b;
+			}
+		if (cert->dh_tmp->pub_key)
+			{
+			BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
+			if (!b)
+				{
+				SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
+				goto err;
+				}
+			ret->dh_tmp->pub_key = b;
+			}
+		}
+	ret->dh_tmp_cb = cert->dh_tmp_cb;
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+	if (cert->ecdh_tmp)
+		{
+		ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp);
+		if (ret->ecdh_tmp == NULL)
+			{
+			SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB);
+			goto err;
+			}
+		}
+	ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
+#endif
+
+	for (i = 0; i < SSL_PKEY_NUM; i++)
+		{
+		if (cert->pkeys[i].x509 != NULL)
+			{
+			ret->pkeys[i].x509 = cert->pkeys[i].x509;
+			CRYPTO_add(&ret->pkeys[i].x509->references, 1,
+				CRYPTO_LOCK_X509);
+			}
+		
+		if (cert->pkeys[i].privatekey != NULL)
+			{
+			ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
+			CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
+				CRYPTO_LOCK_EVP_PKEY);
+
+			switch(i) 
+				{
+				/* If there was anything special to do for
+				 * certain types of keys, we'd do it here.
+				 * (Nothing at the moment, I think.) */
+
+			case SSL_PKEY_RSA_ENC:
+			case SSL_PKEY_RSA_SIGN:
+				/* We have an RSA key. */
+				break;
+				
+			case SSL_PKEY_DSA_SIGN:
+				/* We have a DSA key. */
+				break;
+				
+			case SSL_PKEY_DH_RSA:
+			case SSL_PKEY_DH_DSA:
+				/* We have a DH key. */
+				break;
+
+			case SSL_PKEY_ECC:
+				/* We have an ECC key */
+				break;
+
+			default:
+				/* Can't happen. */
+				SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG);
+				}
+			}
+		}
+	
+	/* ret->extra_certs *should* exist, but currently the own certificate
+	 * chain is held inside SSL_CTX */
+
+	ret->references=1;
+
+	return(ret);
+	
+#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
+err:
+#endif
+#ifndef OPENSSL_NO_RSA
+	if (ret->rsa_tmp != NULL)
+		RSA_free(ret->rsa_tmp);
+#endif
+#ifndef OPENSSL_NO_DH
+	if (ret->dh_tmp != NULL)
+		DH_free(ret->dh_tmp);
+#endif
+#ifndef OPENSSL_NO_ECDH
+	if (ret->ecdh_tmp != NULL)
+		EC_KEY_free(ret->ecdh_tmp);
+#endif
+
+	for (i = 0; i < SSL_PKEY_NUM; i++)
+		{
+		if (ret->pkeys[i].x509 != NULL)
+			X509_free(ret->pkeys[i].x509);
+		if (ret->pkeys[i].privatekey != NULL)
+			EVP_PKEY_free(ret->pkeys[i].privatekey);
+		}
+
+	return NULL;
+	}
+
+
+void ssl_cert_free(CERT *c)
+	{
+	int i;
+
+	if(c == NULL)
+	    return;
+
+	i=CRYPTO_add(&c->references,-1,CRYPTO_LOCK_SSL_CERT);
+#ifdef REF_PRINT
+	REF_PRINT("CERT",c);
+#endif
+	if (i > 0) return;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"ssl_cert_free, bad reference count\n");
+		abort(); /* ok */
+		}
+#endif
+
+#ifndef OPENSSL_NO_RSA
+	if (c->rsa_tmp) RSA_free(c->rsa_tmp);
+#endif
+#ifndef OPENSSL_NO_DH
+	if (c->dh_tmp) DH_free(c->dh_tmp);
+#endif
+#ifndef OPENSSL_NO_ECDH
+	if (c->ecdh_tmp) EC_KEY_free(c->ecdh_tmp);
+#endif
+
+	for (i=0; i<SSL_PKEY_NUM; i++)
+		{
+		if (c->pkeys[i].x509 != NULL)
+			X509_free(c->pkeys[i].x509);
+		if (c->pkeys[i].privatekey != NULL)
+			EVP_PKEY_free(c->pkeys[i].privatekey);
+#if 0
+		if (c->pkeys[i].publickey != NULL)
+			EVP_PKEY_free(c->pkeys[i].publickey);
+#endif
+		}
+	OPENSSL_free(c);
+	}
+
+int ssl_cert_inst(CERT **o)
+	{
+	/* Create a CERT if there isn't already one
+	 * (which cannot really happen, as it is initially created in
+	 * SSL_CTX_new; but the earlier code usually allows for that one
+	 * being non-existant, so we follow that behaviour, as it might
+	 * turn out that there actually is a reason for it -- but I'm
+	 * not sure that *all* of the existing code could cope with
+	 * s->cert being NULL, otherwise we could do without the
+	 * initialization in SSL_CTX_new).
+	 */
+	
+	if (o == NULL) 
+		{
+		SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	if (*o == NULL)
+		{
+		if ((*o = ssl_cert_new()) == NULL)
+			{
+			SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE);
+			return(0);
+			}
+		}
+	return(1);
+	}
+
+
+SESS_CERT *ssl_sess_cert_new(void)
+	{
+	SESS_CERT *ret;
+
+	ret = OPENSSL_malloc(sizeof *ret);
+	if (ret == NULL)
+		{
+		SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+
+	memset(ret, 0 ,sizeof *ret);
+	ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]);
+	ret->references = 1;
+
+	return ret;
+	}
+
+void ssl_sess_cert_free(SESS_CERT *sc)
+	{
+	int i;
+
+	if (sc == NULL)
+		return;
+
+	i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT);
+#ifdef REF_PRINT
+	REF_PRINT("SESS_CERT", sc);
+#endif
+	if (i > 0)
+		return;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"ssl_sess_cert_free, bad reference count\n");
+		abort(); /* ok */
+		}
+#endif
+
+	/* i == 0 */
+	if (sc->cert_chain != NULL)
+		sk_X509_pop_free(sc->cert_chain, X509_free);
+	for (i = 0; i < SSL_PKEY_NUM; i++)
+		{
+		if (sc->peer_pkeys[i].x509 != NULL)
+			X509_free(sc->peer_pkeys[i].x509);
+#if 0 /* We don't have the peer's private key.  These lines are just
+	   * here as a reminder that we're still using a not-quite-appropriate
+	   * data structure. */
+		if (sc->peer_pkeys[i].privatekey != NULL)
+			EVP_PKEY_free(sc->peer_pkeys[i].privatekey);
+#endif
+		}
+
+#ifndef OPENSSL_NO_RSA
+	if (sc->peer_rsa_tmp != NULL)
+		RSA_free(sc->peer_rsa_tmp);
+#endif
+#ifndef OPENSSL_NO_DH
+	if (sc->peer_dh_tmp != NULL)
+		DH_free(sc->peer_dh_tmp);
+#endif
+#ifndef OPENSSL_NO_ECDH
+	if (sc->peer_ecdh_tmp != NULL)
+		EC_KEY_free(sc->peer_ecdh_tmp);
+#endif
+
+	OPENSSL_free(sc);
+	}
+
+int ssl_set_peer_cert_type(SESS_CERT *sc,int type)
+	{
+	sc->peer_cert_type = type;
+	return(1);
+	}
+
+int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
+	{
+	X509 *x;
+	int i;
+	X509_STORE_CTX ctx;
+
+	if ((sk == NULL) || (sk_X509_num(sk) == 0))
+		return(0);
+
+	x=sk_X509_value(sk,0);
+	if(!X509_STORE_CTX_init(&ctx,s->ctx->cert_store,x,sk))
+		{
+		SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,ERR_R_X509_LIB);
+		return(0);
+		}
+#if 0
+	if (SSL_get_verify_depth(s) >= 0)
+		X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s));
+#endif
+	X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(),s);
+
+	/* We need to inherit the verify parameters. These can be determined by
+	 * the context: if its a server it will verify SSL client certificates
+	 * or vice versa.
+	 */
+
+	X509_STORE_CTX_set_default(&ctx,
+				s->server ? "ssl_client" : "ssl_server");
+	/* Anything non-default in "param" should overwrite anything in the
+	 * ctx.
+	 */
+	X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
+
+	if (s->verify_callback)
+		X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
+
+	if (s->ctx->app_verify_callback != NULL)
+#if 1 /* new with OpenSSL 0.9.7 */
+		i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); 
+#else
+		i=s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */
+#endif
+	else
+		{
+#ifndef OPENSSL_NO_X509_VERIFY
+		i=X509_verify_cert(&ctx);
+#else
+		i=0;
+		ctx.error=X509_V_ERR_APPLICATION_VERIFICATION;
+		SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,SSL_R_NO_VERIFY_CALLBACK);
+#endif
+		}
+
+	s->verify_result=ctx.error;
+	X509_STORE_CTX_cleanup(&ctx);
+
+	return(i);
+	}
+
+static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,STACK_OF(X509_NAME) *name_list)
+	{
+	if (*ca_list != NULL)
+		sk_X509_NAME_pop_free(*ca_list,X509_NAME_free);
+
+	*ca_list=name_list;
+	}
+
+STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk)
+	{
+	int i;
+	STACK_OF(X509_NAME) *ret;
+	X509_NAME *name;
+
+	ret=sk_X509_NAME_new_null();
+	for (i=0; i<sk_X509_NAME_num(sk); i++)
+		{
+		name=X509_NAME_dup(sk_X509_NAME_value(sk,i));
+		if ((name == NULL) || !sk_X509_NAME_push(ret,name))
+			{
+			sk_X509_NAME_pop_free(ret,X509_NAME_free);
+			return(NULL);
+			}
+		}
+	return(ret);
+	}
+
+void SSL_set_client_CA_list(SSL *s,STACK_OF(X509_NAME) *name_list)
+	{
+	set_client_CA_list(&(s->client_CA),name_list);
+	}
+
+void SSL_CTX_set_client_CA_list(SSL_CTX *ctx,STACK_OF(X509_NAME) *name_list)
+	{
+	set_client_CA_list(&(ctx->client_CA),name_list);
+	}
+
+STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
+	{
+	return(ctx->client_CA);
+	}
+
+STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s)
+	{
+	if (s->type == SSL_ST_CONNECT)
+		{ /* we are in the client */
+		if (((s->version>>8) == SSL3_VERSION_MAJOR) &&
+			(s->s3 != NULL))
+			return(s->s3->tmp.ca_names);
+		else
+			return(NULL);
+		}
+	else
+		{
+		if (s->client_CA != NULL)
+			return(s->client_CA);
+		else
+			return(s->ctx->client_CA);
+		}
+	}
+
+static int add_client_CA(STACK_OF(X509_NAME) **sk,X509 *x)
+	{
+	X509_NAME *name;
+
+	if (x == NULL) return(0);
+	if ((*sk == NULL) && ((*sk=sk_X509_NAME_new_null()) == NULL))
+		return(0);
+		
+	if ((name=X509_NAME_dup(X509_get_subject_name(x))) == NULL)
+		return(0);
+
+	if (!sk_X509_NAME_push(*sk,name))
+		{
+		X509_NAME_free(name);
+		return(0);
+		}
+	return(1);
+	}
+
+int SSL_add_client_CA(SSL *ssl,X509 *x)
+	{
+	return(add_client_CA(&(ssl->client_CA),x));
+	}
+
+int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x)
+	{
+	return(add_client_CA(&(ctx->client_CA),x));
+	}
+
+static int xname_cmp(const X509_NAME * const *a, const X509_NAME * const *b)
+	{
+	return(X509_NAME_cmp(*a,*b));
+	}
+
+#ifndef OPENSSL_NO_STDIO
+/*!
+ * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed;
+ * it doesn't really have anything to do with clients (except that a common use
+ * for a stack of CAs is to send it to the client). Actually, it doesn't have
+ * much to do with CAs, either, since it will load any old cert.
+ * \param file the file containing one or more certs.
+ * \return a ::STACK containing the certs.
+ */
+STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file)
+	{
+	BIO *in;
+	X509 *x=NULL;
+	X509_NAME *xn=NULL;
+	STACK_OF(X509_NAME) *ret = NULL,*sk;
+
+	sk=sk_X509_NAME_new(xname_cmp);
+
+	in=BIO_new(BIO_s_file_internal());
+
+	if ((sk == NULL) || (in == NULL))
+		{
+		SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	
+	if (!BIO_read_filename(in,file))
+		goto err;
+
+	for (;;)
+		{
+		if (PEM_read_bio_X509(in,&x,NULL,NULL) == NULL)
+			break;
+		if (ret == NULL)
+			{
+			ret = sk_X509_NAME_new_null();
+			if (ret == NULL)
+				{
+				SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE,ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			}
+		if ((xn=X509_get_subject_name(x)) == NULL) goto err;
+		/* check for duplicates */
+		xn=X509_NAME_dup(xn);
+		if (xn == NULL) goto err;
+		if (sk_X509_NAME_find(sk,xn) >= 0)
+			X509_NAME_free(xn);
+		else
+			{
+			sk_X509_NAME_push(sk,xn);
+			sk_X509_NAME_push(ret,xn);
+			}
+		}
+
+	if (0)
+		{
+err:
+		if (ret != NULL) sk_X509_NAME_pop_free(ret,X509_NAME_free);
+		ret=NULL;
+		}
+	if (sk != NULL) sk_X509_NAME_free(sk);
+	if (in != NULL) BIO_free(in);
+	if (x != NULL) X509_free(x);
+	if (ret != NULL)
+		ERR_clear_error();
+	return(ret);
+	}
+#endif
+
+/*!
+ * Add a file of certs to a stack.
+ * \param stack the stack to add to.
+ * \param file the file to add from. All certs in this file that are not
+ * already in the stack will be added.
+ * \return 1 for success, 0 for failure. Note that in the case of failure some
+ * certs may have been added to \c stack.
+ */
+
+int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
+					const char *file)
+	{
+	BIO *in;
+	X509 *x=NULL;
+	X509_NAME *xn=NULL;
+	int ret=1;
+	int (*oldcmp)(const X509_NAME * const *a, const X509_NAME * const *b);
+	
+	oldcmp=sk_X509_NAME_set_cmp_func(stack,xname_cmp);
+	
+	in=BIO_new(BIO_s_file_internal());
+	
+	if (in == NULL)
+		{
+		SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	
+	if (!BIO_read_filename(in,file))
+		goto err;
+	
+	for (;;)
+		{
+		if (PEM_read_bio_X509(in,&x,NULL,NULL) == NULL)
+			break;
+		if ((xn=X509_get_subject_name(x)) == NULL) goto err;
+		xn=X509_NAME_dup(xn);
+		if (xn == NULL) goto err;
+		if (sk_X509_NAME_find(stack,xn) >= 0)
+			X509_NAME_free(xn);
+		else
+			sk_X509_NAME_push(stack,xn);
+		}
+
+	ERR_clear_error();
+
+	if (0)
+		{
+err:
+		ret=0;
+		}
+	if(in != NULL)
+		BIO_free(in);
+	if(x != NULL)
+		X509_free(x);
+	
+	(void)sk_X509_NAME_set_cmp_func(stack,oldcmp);
+
+	return ret;
+	}
+
+/*!
+ * Add a directory of certs to a stack.
+ * \param stack the stack to append to.
+ * \param dir the directory to append from. All files in this directory will be
+ * examined as potential certs. Any that are acceptable to
+ * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be
+ * included.
+ * \return 1 for success, 0 for failure. Note that in the case of failure some
+ * certs may have been added to \c stack.
+ */
+
+int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
+				       const char *dir)
+	{
+	OPENSSL_DIR_CTX *d = NULL;
+	const char *filename;
+	int ret = 0;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_READDIR);
+
+	/* Note that a side effect is that the CAs will be sorted by name */
+
+	while((filename = OPENSSL_DIR_read(&d, dir)))
+		{
+		char buf[1024];
+		int r;
+
+		if(strlen(dir)+strlen(filename)+2 > sizeof buf)
+			{
+			SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,SSL_R_PATH_TOO_LONG);
+			goto err;
+			}
+
+#ifdef OPENSSL_SYS_VMS
+		r = BIO_snprintf(buf,sizeof buf,"%s%s",dir,filename);
+#else
+		r = BIO_snprintf(buf,sizeof buf,"%s/%s",dir,filename);
+#endif
+		if (r <= 0 || r >= (int)sizeof(buf))
+			goto err;
+		if(!SSL_add_file_cert_subjects_to_stack(stack,buf))
+			goto err;
+		}
+
+	if (errno)
+		{
+		SYSerr(SYS_F_OPENDIR, get_last_sys_error());
+		ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
+		SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB);
+		goto err;
+		}
+
+	ret = 1;
+
+err:
+	if (d) OPENSSL_DIR_end(&d);
+	CRYPTO_w_unlock(CRYPTO_LOCK_READDIR);
+	return ret;
+	}
+
diff --git a/openssl/ssl/ssl_ciph.c b/openssl/ssl/ssl_ciph.c
new file mode 100644
index 0000000..462c45a
--- /dev/null
+++ b/openssl/ssl/ssl_ciph.c
@@ -0,0 +1,1793 @@
+/* ssl/ssl_ciph.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include <openssl/objects.h>
+#ifndef OPENSSL_NO_COMP
+#include <openssl/comp.h>
+#endif
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include "ssl_locl.h"
+
+#define SSL_ENC_DES_IDX		0
+#define SSL_ENC_3DES_IDX	1
+#define SSL_ENC_RC4_IDX		2
+#define SSL_ENC_RC2_IDX		3
+#define SSL_ENC_IDEA_IDX	4
+#define SSL_ENC_NULL_IDX	5
+#define SSL_ENC_AES128_IDX	6
+#define SSL_ENC_AES256_IDX	7
+#define SSL_ENC_CAMELLIA128_IDX	8
+#define SSL_ENC_CAMELLIA256_IDX	9
+#define SSL_ENC_GOST89_IDX	10
+#define SSL_ENC_SEED_IDX    	11
+#define SSL_ENC_NUM_IDX		12
+
+
+static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={
+	NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
+	};
+
+#define SSL_COMP_NULL_IDX	0
+#define SSL_COMP_ZLIB_IDX	1
+#define SSL_COMP_NUM_IDX	2
+
+static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL;
+
+#define SSL_MD_MD5_IDX	0
+#define SSL_MD_SHA1_IDX	1
+#define SSL_MD_GOST94_IDX 2
+#define SSL_MD_GOST89MAC_IDX 3
+/*Constant SSL_MAX_DIGEST equal to size of digests array should be 
+ * defined in the
+ * ssl_locl.h */
+#define SSL_MD_NUM_IDX	SSL_MAX_DIGEST 
+static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={
+	NULL,NULL,NULL,NULL
+	};
+/* PKEY_TYPE for GOST89MAC is known in advance, but, because
+ * implementation is engine-provided, we'll fill it only if
+ * corresponding EVP_PKEY_METHOD is found 
+ */
+static int  ssl_mac_pkey_id[SSL_MD_NUM_IDX]={
+	EVP_PKEY_HMAC,EVP_PKEY_HMAC,EVP_PKEY_HMAC,NID_undef
+	};
+
+static int ssl_mac_secret_size[SSL_MD_NUM_IDX]={
+	0,0,0,0
+	};
+
+static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX]={
+	SSL_HANDSHAKE_MAC_MD5,SSL_HANDSHAKE_MAC_SHA,
+	SSL_HANDSHAKE_MAC_GOST94,0
+	};
+
+#define CIPHER_ADD	1
+#define CIPHER_KILL	2
+#define CIPHER_DEL	3
+#define CIPHER_ORD	4
+#define CIPHER_SPECIAL	5
+
+typedef struct cipher_order_st
+	{
+	const SSL_CIPHER *cipher;
+	int active;
+	int dead;
+	struct cipher_order_st *next,*prev;
+	} CIPHER_ORDER;
+
+static const SSL_CIPHER cipher_aliases[]={
+	/* "ALL" doesn't include eNULL (must be specifically enabled) */
+	{0,SSL_TXT_ALL,0,     0,0,~SSL_eNULL,0,0,0,0,0,0},
+	/* "COMPLEMENTOFALL" */
+	{0,SSL_TXT_CMPALL,0,  0,0,SSL_eNULL,0,0,0,0,0,0},
+
+	/* "COMPLEMENTOFDEFAULT" (does *not* include ciphersuites not found in ALL!) */
+	{0,SSL_TXT_CMPDEF,0,  SSL_kEDH|SSL_kEECDH,SSL_aNULL,~SSL_eNULL,0,0,0,0,0,0},
+
+	/* key exchange aliases
+	 * (some of those using only a single bit here combine
+	 * multiple key exchange algs according to the RFCs,
+	 * e.g. kEDH combines DHE_DSS and DHE_RSA) */
+	{0,SSL_TXT_kRSA,0,    SSL_kRSA,  0,0,0,0,0,0,0,0},
+
+	{0,SSL_TXT_kDHr,0,    SSL_kDHr,  0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */
+	{0,SSL_TXT_kDHd,0,    SSL_kDHd,  0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */
+	{0,SSL_TXT_kDH,0,     SSL_kDHr|SSL_kDHd,0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */
+	{0,SSL_TXT_kEDH,0,    SSL_kEDH,  0,0,0,0,0,0,0,0},
+	{0,SSL_TXT_DH,0,      SSL_kDHr|SSL_kDHd|SSL_kEDH,0,0,0,0,0,0,0,0},
+
+	{0,SSL_TXT_kKRB5,0,   SSL_kKRB5, 0,0,0,0,0,0,0,0},
+
+	{0,SSL_TXT_kECDHr,0,  SSL_kECDHr,0,0,0,0,0,0,0,0},
+	{0,SSL_TXT_kECDHe,0,  SSL_kECDHe,0,0,0,0,0,0,0,0},
+	{0,SSL_TXT_kECDH,0,   SSL_kECDHr|SSL_kECDHe,0,0,0,0,0,0,0,0},
+	{0,SSL_TXT_kEECDH,0,  SSL_kEECDH,0,0,0,0,0,0,0,0},
+	{0,SSL_TXT_ECDH,0,    SSL_kECDHr|SSL_kECDHe|SSL_kEECDH,0,0,0,0,0,0,0,0},
+
+        {0,SSL_TXT_kPSK,0,    SSL_kPSK,  0,0,0,0,0,0,0,0},
+	{0,SSL_TXT_kGOST,0, SSL_kGOST,0,0,0,0,0,0,0,0},
+
+	/* server authentication aliases */
+	{0,SSL_TXT_aRSA,0,    0,SSL_aRSA,  0,0,0,0,0,0,0},
+	{0,SSL_TXT_aDSS,0,    0,SSL_aDSS,  0,0,0,0,0,0,0},
+	{0,SSL_TXT_DSS,0,     0,SSL_aDSS,   0,0,0,0,0,0,0},
+	{0,SSL_TXT_aKRB5,0,   0,SSL_aKRB5, 0,0,0,0,0,0,0},
+	{0,SSL_TXT_aNULL,0,   0,SSL_aNULL, 0,0,0,0,0,0,0},
+	{0,SSL_TXT_aDH,0,     0,SSL_aDH,   0,0,0,0,0,0,0}, /* no such ciphersuites supported! */
+	{0,SSL_TXT_aECDH,0,   0,SSL_aECDH, 0,0,0,0,0,0,0},
+	{0,SSL_TXT_aECDSA,0,  0,SSL_aECDSA,0,0,0,0,0,0,0},
+	{0,SSL_TXT_ECDSA,0,   0,SSL_aECDSA, 0,0,0,0,0,0,0},
+        {0,SSL_TXT_aPSK,0,    0,SSL_aPSK,  0,0,0,0,0,0,0},
+	{0,SSL_TXT_aGOST94,0,0,SSL_aGOST94,0,0,0,0,0,0,0},
+	{0,SSL_TXT_aGOST01,0,0,SSL_aGOST01,0,0,0,0,0,0,0},
+	{0,SSL_TXT_aGOST,0,0,SSL_aGOST94|SSL_aGOST01,0,0,0,0,0,0,0},
+
+	/* aliases combining key exchange and server authentication */
+	{0,SSL_TXT_EDH,0,     SSL_kEDH,~SSL_aNULL,0,0,0,0,0,0,0},
+	{0,SSL_TXT_EECDH,0,   SSL_kEECDH,~SSL_aNULL,0,0,0,0,0,0,0},
+	{0,SSL_TXT_NULL,0,    0,0,SSL_eNULL, 0,0,0,0,0,0},
+	{0,SSL_TXT_KRB5,0,    SSL_kKRB5,SSL_aKRB5,0,0,0,0,0,0,0},
+	{0,SSL_TXT_RSA,0,     SSL_kRSA,SSL_aRSA,0,0,0,0,0,0,0},
+	{0,SSL_TXT_ADH,0,     SSL_kEDH,SSL_aNULL,0,0,0,0,0,0,0},
+	{0,SSL_TXT_AECDH,0,   SSL_kEECDH,SSL_aNULL,0,0,0,0,0,0,0},
+        {0,SSL_TXT_PSK,0,     SSL_kPSK,SSL_aPSK,0,0,0,0,0,0,0},
+
+
+	/* symmetric encryption aliases */
+	{0,SSL_TXT_DES,0,     0,0,SSL_DES,   0,0,0,0,0,0},
+	{0,SSL_TXT_3DES,0,    0,0,SSL_3DES,  0,0,0,0,0,0},
+	{0,SSL_TXT_RC4,0,     0,0,SSL_RC4,   0,0,0,0,0,0},
+	{0,SSL_TXT_RC2,0,     0,0,SSL_RC2,   0,0,0,0,0,0},
+	{0,SSL_TXT_IDEA,0,    0,0,SSL_IDEA,  0,0,0,0,0,0},
+	{0,SSL_TXT_SEED,0,    0,0,SSL_SEED,  0,0,0,0,0,0},
+	{0,SSL_TXT_eNULL,0,   0,0,SSL_eNULL, 0,0,0,0,0,0},
+	{0,SSL_TXT_AES128,0,  0,0,SSL_AES128,0,0,0,0,0,0},
+	{0,SSL_TXT_AES256,0,  0,0,SSL_AES256,0,0,0,0,0,0},
+	{0,SSL_TXT_AES,0,     0,0,SSL_AES128|SSL_AES256,0,0,0,0,0,0},
+	{0,SSL_TXT_CAMELLIA128,0,0,0,SSL_CAMELLIA128,0,0,0,0,0,0},
+	{0,SSL_TXT_CAMELLIA256,0,0,0,SSL_CAMELLIA256,0,0,0,0,0,0},
+	{0,SSL_TXT_CAMELLIA   ,0,0,0,SSL_CAMELLIA128|SSL_CAMELLIA256,0,0,0,0,0,0},
+
+	/* MAC aliases */	
+	{0,SSL_TXT_MD5,0,     0,0,0,SSL_MD5,   0,0,0,0,0},
+	{0,SSL_TXT_SHA1,0,    0,0,0,SSL_SHA1,  0,0,0,0,0},
+	{0,SSL_TXT_SHA,0,     0,0,0,SSL_SHA1,  0,0,0,0,0},
+	{0,SSL_TXT_GOST94,0,     0,0,0,SSL_GOST94,  0,0,0,0,0},
+	{0,SSL_TXT_GOST89MAC,0,     0,0,0,SSL_GOST89MAC,  0,0,0,0,0},
+
+	/* protocol version aliases */
+	{0,SSL_TXT_SSLV2,0,   0,0,0,0,SSL_SSLV2, 0,0,0,0},
+	{0,SSL_TXT_SSLV3,0,   0,0,0,0,SSL_SSLV3, 0,0,0,0},
+	{0,SSL_TXT_TLSV1,0,   0,0,0,0,SSL_TLSV1, 0,0,0,0},
+
+	/* export flag */
+	{0,SSL_TXT_EXP,0,     0,0,0,0,0,SSL_EXPORT,0,0,0},
+	{0,SSL_TXT_EXPORT,0,  0,0,0,0,0,SSL_EXPORT,0,0,0},
+
+	/* strength classes */
+	{0,SSL_TXT_EXP40,0,   0,0,0,0,0,SSL_EXP40, 0,0,0},
+	{0,SSL_TXT_EXP56,0,   0,0,0,0,0,SSL_EXP56, 0,0,0},
+	{0,SSL_TXT_LOW,0,     0,0,0,0,0,SSL_LOW,   0,0,0},
+	{0,SSL_TXT_MEDIUM,0,  0,0,0,0,0,SSL_MEDIUM,0,0,0},
+	{0,SSL_TXT_HIGH,0,    0,0,0,0,0,SSL_HIGH,  0,0,0},
+	/* FIPS 140-2 approved ciphersuite */
+	{0,SSL_TXT_FIPS,0,    0,0,~SSL_eNULL,0,0,SSL_FIPS,  0,0,0},
+	};
+/* Search for public key algorithm with given name and 
+ * return its pkey_id if it is available. Otherwise return 0
+ */
+#ifdef OPENSSL_NO_ENGINE
+
+static int get_optional_pkey_id(const char *pkey_name)
+	{
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	int pkey_id=0;
+	ameth = EVP_PKEY_asn1_find_str(NULL,pkey_name,-1);
+	if (ameth) 
+		{
+		EVP_PKEY_asn1_get0_info(&pkey_id, NULL,NULL,NULL,NULL,ameth);
+		}		
+	return pkey_id;
+	}
+
+#else
+
+static int get_optional_pkey_id(const char *pkey_name)
+	{
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	ENGINE *tmpeng = NULL;
+	int pkey_id=0;
+	ameth = EVP_PKEY_asn1_find_str(&tmpeng,pkey_name,-1);
+	if (ameth)
+		{
+		EVP_PKEY_asn1_get0_info(&pkey_id, NULL,NULL,NULL,NULL,ameth);
+		}
+	if (tmpeng) ENGINE_finish(tmpeng);
+	return pkey_id;
+	}
+
+#endif
+
+void ssl_load_ciphers(void)
+	{
+	ssl_cipher_methods[SSL_ENC_DES_IDX]= 
+		EVP_get_cipherbyname(SN_des_cbc);
+	ssl_cipher_methods[SSL_ENC_3DES_IDX]=
+		EVP_get_cipherbyname(SN_des_ede3_cbc);
+	ssl_cipher_methods[SSL_ENC_RC4_IDX]=
+		EVP_get_cipherbyname(SN_rc4);
+	ssl_cipher_methods[SSL_ENC_RC2_IDX]= 
+		EVP_get_cipherbyname(SN_rc2_cbc);
+#ifndef OPENSSL_NO_IDEA
+	ssl_cipher_methods[SSL_ENC_IDEA_IDX]= 
+		EVP_get_cipherbyname(SN_idea_cbc);
+#else
+	ssl_cipher_methods[SSL_ENC_IDEA_IDX]= NULL;
+#endif
+	ssl_cipher_methods[SSL_ENC_AES128_IDX]=
+	  EVP_get_cipherbyname(SN_aes_128_cbc);
+	ssl_cipher_methods[SSL_ENC_AES256_IDX]=
+	  EVP_get_cipherbyname(SN_aes_256_cbc);
+	ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX]=
+	  EVP_get_cipherbyname(SN_camellia_128_cbc);
+	ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX]=
+	  EVP_get_cipherbyname(SN_camellia_256_cbc);
+	ssl_cipher_methods[SSL_ENC_GOST89_IDX]=
+	  EVP_get_cipherbyname(SN_gost89_cnt);
+	ssl_cipher_methods[SSL_ENC_SEED_IDX]=
+	  EVP_get_cipherbyname(SN_seed_cbc);
+
+	ssl_digest_methods[SSL_MD_MD5_IDX]=
+		EVP_get_digestbyname(SN_md5);
+	ssl_mac_secret_size[SSL_MD_MD5_IDX]=
+		EVP_MD_size(ssl_digest_methods[SSL_MD_MD5_IDX]);
+	OPENSSL_assert(ssl_mac_secret_size[SSL_MD_MD5_IDX] >= 0);
+	ssl_digest_methods[SSL_MD_SHA1_IDX]=
+		EVP_get_digestbyname(SN_sha1);
+	ssl_mac_secret_size[SSL_MD_SHA1_IDX]=
+		EVP_MD_size(ssl_digest_methods[SSL_MD_SHA1_IDX]);
+	OPENSSL_assert(ssl_mac_secret_size[SSL_MD_SHA1_IDX] >= 0);
+	ssl_digest_methods[SSL_MD_GOST94_IDX]=
+		EVP_get_digestbyname(SN_id_GostR3411_94);
+	if (ssl_digest_methods[SSL_MD_GOST94_IDX])
+		{	
+		ssl_mac_secret_size[SSL_MD_GOST94_IDX]=
+			EVP_MD_size(ssl_digest_methods[SSL_MD_GOST94_IDX]);
+		OPENSSL_assert(ssl_mac_secret_size[SSL_MD_GOST94_IDX] >= 0);
+		}
+	ssl_digest_methods[SSL_MD_GOST89MAC_IDX]=
+		EVP_get_digestbyname(SN_id_Gost28147_89_MAC);
+		ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id("gost-mac");
+		if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]) {
+			ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX]=32;
+		}		
+
+	}
+#ifndef OPENSSL_NO_COMP
+
+static int sk_comp_cmp(const SSL_COMP * const *a,
+			const SSL_COMP * const *b)
+	{
+	return((*a)->id-(*b)->id);
+	}
+
+static void load_builtin_compressions(void)
+	{
+	int got_write_lock = 0;
+
+	CRYPTO_r_lock(CRYPTO_LOCK_SSL);
+	if (ssl_comp_methods == NULL)
+		{
+		CRYPTO_r_unlock(CRYPTO_LOCK_SSL);
+		CRYPTO_w_lock(CRYPTO_LOCK_SSL);
+		got_write_lock = 1;
+		
+		if (ssl_comp_methods == NULL)
+			{
+			SSL_COMP *comp = NULL;
+
+			MemCheck_off();
+			ssl_comp_methods=sk_SSL_COMP_new(sk_comp_cmp);
+			if (ssl_comp_methods != NULL)
+				{
+				comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP));
+				if (comp != NULL)
+					{
+					comp->method=COMP_zlib();
+					if (comp->method
+						&& comp->method->type == NID_undef)
+						OPENSSL_free(comp);
+					else
+						{
+						comp->id=SSL_COMP_ZLIB_IDX;
+						comp->name=comp->method->name;
+						sk_SSL_COMP_push(ssl_comp_methods,comp);
+						}
+					}
+					sk_SSL_COMP_sort(ssl_comp_methods);
+				}
+			MemCheck_on();
+			}
+		}
+	
+	if (got_write_lock)
+		CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
+	else
+		CRYPTO_r_unlock(CRYPTO_LOCK_SSL);
+	}
+#endif
+
+int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
+	     const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size,SSL_COMP **comp)
+	{
+	int i;
+	const SSL_CIPHER *c;
+
+	c=s->cipher;
+	if (c == NULL) return(0);
+	if (comp != NULL)
+		{
+		SSL_COMP ctmp;
+#ifndef OPENSSL_NO_COMP
+		load_builtin_compressions();
+#endif
+
+		*comp=NULL;
+		ctmp.id=s->compress_meth;
+		if (ssl_comp_methods != NULL)
+			{
+			i=sk_SSL_COMP_find(ssl_comp_methods,&ctmp);
+			if (i >= 0)
+				*comp=sk_SSL_COMP_value(ssl_comp_methods,i);
+			else
+				*comp=NULL;
+			}
+		}
+
+	if ((enc == NULL) || (md == NULL)) return(0);
+
+	switch (c->algorithm_enc)
+		{
+	case SSL_DES:
+		i=SSL_ENC_DES_IDX;
+		break;
+	case SSL_3DES:
+		i=SSL_ENC_3DES_IDX;
+		break;
+	case SSL_RC4:
+		i=SSL_ENC_RC4_IDX;
+		break;
+	case SSL_RC2:
+		i=SSL_ENC_RC2_IDX;
+		break;
+	case SSL_IDEA:
+		i=SSL_ENC_IDEA_IDX;
+		break;
+	case SSL_eNULL:
+		i=SSL_ENC_NULL_IDX;
+		break;
+	case SSL_AES128:
+		i=SSL_ENC_AES128_IDX;
+		break;
+	case SSL_AES256:
+		i=SSL_ENC_AES256_IDX;
+		break;
+	case SSL_CAMELLIA128:
+		i=SSL_ENC_CAMELLIA128_IDX;
+		break;
+	case SSL_CAMELLIA256:
+		i=SSL_ENC_CAMELLIA256_IDX;
+		break;
+	case SSL_eGOST2814789CNT:
+		i=SSL_ENC_GOST89_IDX;
+		break;
+	case SSL_SEED:
+		i=SSL_ENC_SEED_IDX;
+		break;
+	default:
+		i= -1;
+		break;
+		}
+
+	if ((i < 0) || (i > SSL_ENC_NUM_IDX))
+		*enc=NULL;
+	else
+		{
+		if (i == SSL_ENC_NULL_IDX)
+			*enc=EVP_enc_null();
+		else
+			*enc=ssl_cipher_methods[i];
+		}
+
+	switch (c->algorithm_mac)
+		{
+	case SSL_MD5:
+		i=SSL_MD_MD5_IDX;
+		break;
+	case SSL_SHA1:
+		i=SSL_MD_SHA1_IDX;
+		break;
+	case SSL_GOST94:
+		i = SSL_MD_GOST94_IDX;
+		break;
+	case SSL_GOST89MAC:
+		i = SSL_MD_GOST89MAC_IDX;
+		break;
+	default:
+		i= -1;
+		break;
+		}
+	if ((i < 0) || (i > SSL_MD_NUM_IDX))
+	{
+		*md=NULL; 
+		if (mac_pkey_type!=NULL) *mac_pkey_type = NID_undef;
+		if (mac_secret_size!=NULL) *mac_secret_size = 0;
+
+	}
+	else
+	{
+		*md=ssl_digest_methods[i];
+		if (mac_pkey_type!=NULL) *mac_pkey_type = ssl_mac_pkey_id[i];
+		if (mac_secret_size!=NULL) *mac_secret_size = ssl_mac_secret_size[i];
+	}	
+
+	if ((*enc != NULL) && (*md != NULL) && (!mac_pkey_type||*mac_pkey_type != NID_undef))
+		return(1);
+	else
+		return(0);
+	}
+
+int ssl_get_handshake_digest(int idx, long *mask, const EVP_MD **md) 
+{
+	if (idx <0||idx>=SSL_MD_NUM_IDX) 
+		{
+		return 0;
+		}
+	if (ssl_handshake_digest_flag[idx]==0) return 0;
+	*mask = ssl_handshake_digest_flag[idx];
+	*md = ssl_digest_methods[idx];
+	return 1;
+}
+
+#define ITEM_SEP(a) \
+	(((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ','))
+
+static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr,
+	     CIPHER_ORDER **tail)
+	{
+	if (curr == *tail) return;
+	if (curr == *head)
+		*head=curr->next;
+	if (curr->prev != NULL)
+		curr->prev->next=curr->next;
+	if (curr->next != NULL)
+		curr->next->prev=curr->prev;
+	(*tail)->next=curr;
+	curr->prev= *tail;
+	curr->next=NULL;
+	*tail=curr;
+	}
+
+static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr,
+	     CIPHER_ORDER **tail)
+	{
+	if (curr == *head) return;
+	if (curr == *tail)
+		*tail=curr->prev;
+	if (curr->next != NULL)
+		curr->next->prev=curr->prev;
+	if (curr->prev != NULL)
+		curr->prev->next=curr->next;
+	(*head)->prev=curr;
+	curr->next= *head;
+	curr->prev=NULL;
+	*head=curr;
+	}
+
+static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, unsigned long *enc, unsigned long *mac, unsigned long *ssl)
+	{
+	*mkey = 0;
+	*auth = 0;
+	*enc = 0;
+	*mac = 0;
+	*ssl = 0;
+
+#ifdef OPENSSL_NO_RSA
+	*mkey |= SSL_kRSA;
+	*auth |= SSL_aRSA;
+#endif
+#ifdef OPENSSL_NO_DSA
+	*auth |= SSL_aDSS;
+#endif
+	*mkey |= SSL_kDHr|SSL_kDHd; /* no such ciphersuites supported! */
+	*auth |= SSL_aDH;
+#ifdef OPENSSL_NO_DH
+	*mkey |= SSL_kDHr|SSL_kDHd|SSL_kEDH;
+	*auth |= SSL_aDH;
+#endif
+#ifdef OPENSSL_NO_KRB5
+	*mkey |= SSL_kKRB5;
+	*auth |= SSL_aKRB5;
+#endif
+#ifdef OPENSSL_NO_ECDSA
+	*auth |= SSL_aECDSA;
+#endif
+#ifdef OPENSSL_NO_ECDH
+	*mkey |= SSL_kECDHe|SSL_kECDHr;
+	*auth |= SSL_aECDH;
+#endif
+#ifdef OPENSSL_NO_PSK
+	*mkey |= SSL_kPSK;
+	*auth |= SSL_aPSK;
+#endif
+	/* Check for presence of GOST 34.10 algorithms, and if they
+	 * do not present, disable  appropriate auth and key exchange */
+	if (!get_optional_pkey_id("gost94")) {
+		*auth |= SSL_aGOST94;
+	}
+	if (!get_optional_pkey_id("gost2001")) {
+		*auth |= SSL_aGOST01;
+	}
+	/* Disable GOST key exchange if no GOST signature algs are available * */
+	if ((*auth & (SSL_aGOST94|SSL_aGOST01)) == (SSL_aGOST94|SSL_aGOST01)) {
+		*mkey |= SSL_kGOST;
+	}	
+#ifdef SSL_FORBID_ENULL
+	*enc |= SSL_eNULL;
+#endif
+		
+
+
+	*enc |= (ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL) ? SSL_DES :0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES:0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 :0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES128:0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES256:0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? SSL_CAMELLIA128:0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == NULL) ? SSL_CAMELLIA256:0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_GOST89_IDX] == NULL) ? SSL_eGOST2814789CNT:0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_SEED_IDX] == NULL) ? SSL_SEED:0;
+
+	*mac |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0;
+	*mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0;
+	*mac |= (ssl_digest_methods[SSL_MD_GOST94_IDX] == NULL) ? SSL_GOST94:0;
+	*mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL || ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]==NID_undef)? SSL_GOST89MAC:0;
+
+	}
+
+static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
+                int num_of_ciphers,
+                unsigned long disabled_mkey, unsigned long disabled_auth,
+                unsigned long disabled_enc, unsigned long disabled_mac,
+                unsigned long disabled_ssl,
+                CIPHER_ORDER *co_list,
+                CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
+	{
+	int i, co_list_num;
+	const SSL_CIPHER *c;
+
+	/*
+	 * We have num_of_ciphers descriptions compiled in, depending on the
+	 * method selected (SSLv2 and/or SSLv3, TLSv1 etc).
+	 * These will later be sorted in a linked list with at most num
+	 * entries.
+	 */
+
+	/* Get the initial list of ciphers */
+	co_list_num = 0;	/* actual count of ciphers */
+	for (i = 0; i < num_of_ciphers; i++)
+		{
+		c = ssl_method->get_cipher(i);
+		/* drop those that use any of that is not available */
+		if ((c != NULL) && c->valid &&
+		    !(c->algorithm_mkey & disabled_mkey) &&
+		    !(c->algorithm_auth & disabled_auth) &&
+		    !(c->algorithm_enc & disabled_enc) &&
+		    !(c->algorithm_mac & disabled_mac) &&
+		    !(c->algorithm_ssl & disabled_ssl))
+			{
+			co_list[co_list_num].cipher = c;
+			co_list[co_list_num].next = NULL;
+			co_list[co_list_num].prev = NULL;
+			co_list[co_list_num].active = 0;
+			co_list_num++;
+#ifdef KSSL_DEBUG
+			printf("\t%d: %s %lx %lx %lx\n",i,c->name,c->id,c->algorithm_mkey,c->algorithm_auth);
+#endif	/* KSSL_DEBUG */
+			/*
+			if (!sk_push(ca_list,(char *)c)) goto err;
+			*/
+			}
+		}
+
+	/*
+	 * Prepare linked list from list entries
+	 */	
+	if (co_list_num > 0)
+		{
+		co_list[0].prev = NULL;
+
+		if (co_list_num > 1)
+			{
+			co_list[0].next = &co_list[1];
+			
+			for (i = 1; i < co_list_num - 1; i++)
+				{
+				co_list[i].prev = &co_list[i - 1];
+				co_list[i].next = &co_list[i + 1];
+				}
+
+			co_list[co_list_num - 1].prev = &co_list[co_list_num - 2];
+			}
+		
+		co_list[co_list_num - 1].next = NULL;
+
+		*head_p = &co_list[0];
+		*tail_p = &co_list[co_list_num - 1];
+		}
+	}
+
+static void ssl_cipher_collect_aliases(const SSL_CIPHER **ca_list,
+                        int num_of_group_aliases,
+                        unsigned long disabled_mkey, unsigned long disabled_auth,
+                        unsigned long disabled_enc, unsigned long disabled_mac,
+                        unsigned long disabled_ssl,
+			CIPHER_ORDER *head)
+	{
+	CIPHER_ORDER *ciph_curr;
+	const SSL_CIPHER **ca_curr;
+	int i;
+	unsigned long mask_mkey = ~disabled_mkey;
+	unsigned long mask_auth = ~disabled_auth;
+	unsigned long mask_enc = ~disabled_enc;
+	unsigned long mask_mac = ~disabled_mac;
+	unsigned long mask_ssl = ~disabled_ssl;
+
+	/*
+	 * First, add the real ciphers as already collected
+	 */
+	ciph_curr = head;
+	ca_curr = ca_list;
+	while (ciph_curr != NULL)
+		{
+		*ca_curr = ciph_curr->cipher;
+		ca_curr++;
+		ciph_curr = ciph_curr->next;
+		}
+
+	/*
+	 * Now we add the available ones from the cipher_aliases[] table.
+	 * They represent either one or more algorithms, some of which
+	 * in any affected category must be supported (set in enabled_mask),
+	 * or represent a cipher strength value (will be added in any case because algorithms=0).
+	 */
+	for (i = 0; i < num_of_group_aliases; i++)
+		{
+		unsigned long algorithm_mkey = cipher_aliases[i].algorithm_mkey;
+		unsigned long algorithm_auth = cipher_aliases[i].algorithm_auth;
+		unsigned long algorithm_enc = cipher_aliases[i].algorithm_enc;
+		unsigned long algorithm_mac = cipher_aliases[i].algorithm_mac;
+		unsigned long algorithm_ssl = cipher_aliases[i].algorithm_ssl;
+
+		if (algorithm_mkey)
+			if ((algorithm_mkey & mask_mkey) == 0)
+				continue;
+	
+		if (algorithm_auth)
+			if ((algorithm_auth & mask_auth) == 0)
+				continue;
+		
+		if (algorithm_enc)
+			if ((algorithm_enc & mask_enc) == 0)
+				continue;
+		
+		if (algorithm_mac)
+			if ((algorithm_mac & mask_mac) == 0)
+				continue;
+		
+		if (algorithm_ssl)
+			if ((algorithm_ssl & mask_ssl) == 0)
+				continue;
+		
+		*ca_curr = (SSL_CIPHER *)(cipher_aliases + i);
+		ca_curr++;
+		}
+
+	*ca_curr = NULL;	/* end of list */
+	}
+
+static void ssl_cipher_apply_rule(unsigned long cipher_id,
+                unsigned long alg_mkey, unsigned long alg_auth,
+                unsigned long alg_enc, unsigned long alg_mac,
+                unsigned long alg_ssl,
+		unsigned long algo_strength,
+		int rule, int strength_bits,
+		CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
+	{
+	CIPHER_ORDER *head, *tail, *curr, *curr2, *last;
+	const SSL_CIPHER *cp;
+	int reverse = 0;
+
+#ifdef CIPHER_DEBUG
+	printf("Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d)\n",
+		rule, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength, strength_bits);
+#endif
+
+	if (rule == CIPHER_DEL)
+		reverse = 1; /* needed to maintain sorting between currently deleted ciphers */
+
+	head = *head_p;
+	tail = *tail_p;
+
+	if (reverse)
+		{
+		curr = tail;
+		last = head;
+		}
+	else
+		{
+		curr = head;
+		last = tail;
+		}
+
+	curr2 = curr;
+	for (;;)
+		{
+		if ((curr == NULL) || (curr == last)) break;
+		curr = curr2;
+		curr2 = reverse ? curr->prev : curr->next;
+
+		cp = curr->cipher;
+
+		/*
+		 * Selection criteria is either the value of strength_bits
+		 * or the algorithms used.
+		 */
+		if (strength_bits >= 0)
+			{
+			if (strength_bits != cp->strength_bits)
+				continue;
+			}
+		else
+			{
+#ifdef CIPHER_DEBUG
+			printf("\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", cp->name, cp->algorithm_mkey, cp->algorithm_auth, cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, cp->algo_strength);
+#endif
+
+			if (alg_mkey && !(alg_mkey & cp->algorithm_mkey))
+				continue;
+			if (alg_auth && !(alg_auth & cp->algorithm_auth))
+				continue;
+			if (alg_enc && !(alg_enc & cp->algorithm_enc))
+				continue;
+			if (alg_mac && !(alg_mac & cp->algorithm_mac))
+				continue;
+			if (alg_ssl && !(alg_ssl & cp->algorithm_ssl))
+				continue;
+			if ((algo_strength & SSL_EXP_MASK) && !(algo_strength & SSL_EXP_MASK & cp->algo_strength))
+				continue;
+			if ((algo_strength & SSL_STRONG_MASK) && !(algo_strength & SSL_STRONG_MASK & cp->algo_strength))
+				continue;
+			}
+
+#ifdef CIPHER_DEBUG
+		printf("Action = %d\n", rule);
+#endif
+
+		/* add the cipher if it has not been added yet. */
+		if (rule == CIPHER_ADD)
+			{
+			/* reverse == 0 */
+			if (!curr->active)
+				{
+				ll_append_tail(&head, curr, &tail);
+				curr->active = 1;
+				}
+			}
+		/* Move the added cipher to this location */
+		else if (rule == CIPHER_ORD)
+			{
+			/* reverse == 0 */
+			if (curr->active)
+				{
+				ll_append_tail(&head, curr, &tail);
+				}
+			}
+		else if	(rule == CIPHER_DEL)
+			{
+			/* reverse == 1 */
+			if (curr->active)
+				{
+				/* most recently deleted ciphersuites get best positions
+				 * for any future CIPHER_ADD (note that the CIPHER_DEL loop
+				 * works in reverse to maintain the order) */
+				ll_append_head(&head, curr, &tail);
+				curr->active = 0;
+				}
+			}
+		else if (rule == CIPHER_KILL)
+			{
+			/* reverse == 0 */
+			if (head == curr)
+				head = curr->next;
+			else
+				curr->prev->next = curr->next;
+			if (tail == curr)
+				tail = curr->prev;
+			curr->active = 0;
+			if (curr->next != NULL)
+				curr->next->prev = curr->prev;
+			if (curr->prev != NULL)
+				curr->prev->next = curr->next;
+			curr->next = NULL;
+			curr->prev = NULL;
+			}
+		}
+
+	*head_p = head;
+	*tail_p = tail;
+	}
+
+static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
+				    CIPHER_ORDER **tail_p)
+	{
+	int max_strength_bits, i, *number_uses;
+	CIPHER_ORDER *curr;
+
+	/*
+	 * This routine sorts the ciphers with descending strength. The sorting
+	 * must keep the pre-sorted sequence, so we apply the normal sorting
+	 * routine as '+' movement to the end of the list.
+	 */
+	max_strength_bits = 0;
+	curr = *head_p;
+	while (curr != NULL)
+		{
+		if (curr->active &&
+		    (curr->cipher->strength_bits > max_strength_bits))
+		    max_strength_bits = curr->cipher->strength_bits;
+		curr = curr->next;
+		}
+
+	number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int));
+	if (!number_uses)
+		{
+		SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int));
+
+	/*
+	 * Now find the strength_bits values actually used
+	 */
+	curr = *head_p;
+	while (curr != NULL)
+		{
+		if (curr->active)
+			number_uses[curr->cipher->strength_bits]++;
+		curr = curr->next;
+		}
+	/*
+	 * Go through the list of used strength_bits values in descending
+	 * order.
+	 */
+	for (i = max_strength_bits; i >= 0; i--)
+		if (number_uses[i] > 0)
+			ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p, tail_p);
+
+	OPENSSL_free(number_uses);
+	return(1);
+	}
+
+static int ssl_cipher_process_rulestr(const char *rule_str,
+                CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p,
+                const SSL_CIPHER **ca_list)
+	{
+	unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength;
+	const char *l, *buf;
+	int j, multi, found, rule, retval, ok, buflen;
+	unsigned long cipher_id = 0;
+	char ch;
+
+	retval = 1;
+	l = rule_str;
+	for (;;)
+		{
+		ch = *l;
+
+		if (ch == '\0')
+			break;		/* done */
+		if (ch == '-')
+			{ rule = CIPHER_DEL; l++; }
+		else if (ch == '+')
+			{ rule = CIPHER_ORD; l++; }
+		else if (ch == '!')
+			{ rule = CIPHER_KILL; l++; }
+		else if (ch == '@')
+			{ rule = CIPHER_SPECIAL; l++; }
+		else
+			{ rule = CIPHER_ADD; }
+
+		if (ITEM_SEP(ch))
+			{
+			l++;
+			continue;
+			}
+
+		alg_mkey = 0;
+		alg_auth = 0;
+		alg_enc = 0;
+		alg_mac = 0;
+		alg_ssl = 0;
+		algo_strength = 0;
+
+		for (;;)
+			{
+			ch = *l;
+			buf = l;
+			buflen = 0;
+#ifndef CHARSET_EBCDIC
+			while (	((ch >= 'A') && (ch <= 'Z')) ||
+				((ch >= '0') && (ch <= '9')) ||
+				((ch >= 'a') && (ch <= 'z')) ||
+				 (ch == '-'))
+#else
+			while (	isalnum(ch) || (ch == '-'))
+#endif
+				 {
+				 ch = *(++l);
+				 buflen++;
+				 }
+
+			if (buflen == 0)
+				{
+				/*
+				 * We hit something we cannot deal with,
+				 * it is no command or separator nor
+				 * alphanumeric, so we call this an error.
+				 */
+				SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
+				       SSL_R_INVALID_COMMAND);
+				retval = found = 0;
+				l++;
+				break;
+				}
+
+			if (rule == CIPHER_SPECIAL)
+				{
+				found = 0; /* unused -- avoid compiler warning */
+				break;	/* special treatment */
+				}
+
+			/* check for multi-part specification */
+			if (ch == '+')
+				{
+				multi=1;
+				l++;
+				}
+			else
+				multi=0;
+
+			/*
+			 * Now search for the cipher alias in the ca_list. Be careful
+			 * with the strncmp, because the "buflen" limitation
+			 * will make the rule "ADH:SOME" and the cipher
+			 * "ADH-MY-CIPHER" look like a match for buflen=3.
+			 * So additionally check whether the cipher name found
+			 * has the correct length. We can save a strlen() call:
+			 * just checking for the '\0' at the right place is
+			 * sufficient, we have to strncmp() anyway. (We cannot
+			 * use strcmp(), because buf is not '\0' terminated.)
+			 */
+			j = found = 0;
+			cipher_id = 0;
+			while (ca_list[j])
+				{
+				if (!strncmp(buf, ca_list[j]->name, buflen) &&
+				    (ca_list[j]->name[buflen] == '\0'))
+					{
+					found = 1;
+					break;
+					}
+				else
+					j++;
+				}
+
+			if (!found)
+				break;	/* ignore this entry */
+
+			if (ca_list[j]->algorithm_mkey)
+				{
+				if (alg_mkey)
+					{
+					alg_mkey &= ca_list[j]->algorithm_mkey;
+					if (!alg_mkey) { found = 0; break; }
+					}
+				else
+					alg_mkey = ca_list[j]->algorithm_mkey;
+				}
+
+			if (ca_list[j]->algorithm_auth)
+				{
+				if (alg_auth)
+					{
+					alg_auth &= ca_list[j]->algorithm_auth;
+					if (!alg_auth) { found = 0; break; }
+					}
+				else
+					alg_auth = ca_list[j]->algorithm_auth;
+				}
+			
+			if (ca_list[j]->algorithm_enc)
+				{
+				if (alg_enc)
+					{
+					alg_enc &= ca_list[j]->algorithm_enc;
+					if (!alg_enc) { found = 0; break; }
+					}
+				else
+					alg_enc = ca_list[j]->algorithm_enc;
+				}
+						
+			if (ca_list[j]->algorithm_mac)
+				{
+				if (alg_mac)
+					{
+					alg_mac &= ca_list[j]->algorithm_mac;
+					if (!alg_mac) { found = 0; break; }
+					}
+				else
+					alg_mac = ca_list[j]->algorithm_mac;
+				}
+			
+			if (ca_list[j]->algo_strength & SSL_EXP_MASK)
+				{
+				if (algo_strength & SSL_EXP_MASK)
+					{
+					algo_strength &= (ca_list[j]->algo_strength & SSL_EXP_MASK) | ~SSL_EXP_MASK;
+					if (!(algo_strength & SSL_EXP_MASK)) { found = 0; break; }
+					}
+				else
+					algo_strength |= ca_list[j]->algo_strength & SSL_EXP_MASK;
+				}
+
+			if (ca_list[j]->algo_strength & SSL_STRONG_MASK)
+				{
+				if (algo_strength & SSL_STRONG_MASK)
+					{
+					algo_strength &= (ca_list[j]->algo_strength & SSL_STRONG_MASK) | ~SSL_STRONG_MASK;
+					if (!(algo_strength & SSL_STRONG_MASK)) { found = 0; break; }
+					}
+				else
+					algo_strength |= ca_list[j]->algo_strength & SSL_STRONG_MASK;
+				}
+			
+			if (ca_list[j]->valid)
+				{
+				/* explicit ciphersuite found; its protocol version
+				 * does not become part of the search pattern!*/
+
+				cipher_id = ca_list[j]->id;
+				}
+			else
+				{
+				/* not an explicit ciphersuite; only in this case, the
+				 * protocol version is considered part of the search pattern */
+
+				if (ca_list[j]->algorithm_ssl)
+					{
+					if (alg_ssl)
+						{
+						alg_ssl &= ca_list[j]->algorithm_ssl;
+						if (!alg_ssl) { found = 0; break; }
+						}
+					else
+						alg_ssl = ca_list[j]->algorithm_ssl;
+					}
+				}
+			
+			if (!multi) break;
+			}
+
+		/*
+		 * Ok, we have the rule, now apply it
+		 */
+		if (rule == CIPHER_SPECIAL)
+			{	/* special command */
+			ok = 0;
+			if ((buflen == 8) &&
+				!strncmp(buf, "STRENGTH", 8))
+				ok = ssl_cipher_strength_sort(head_p, tail_p);
+			else
+				SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
+					SSL_R_INVALID_COMMAND);
+			if (ok == 0)
+				retval = 0;
+			/*
+			 * We do not support any "multi" options
+			 * together with "@", so throw away the
+			 * rest of the command, if any left, until
+			 * end or ':' is found.
+			 */
+			while ((*l != '\0') && !ITEM_SEP(*l))
+				l++;
+			}
+		else if (found)
+			{
+			ssl_cipher_apply_rule(cipher_id,
+				alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength,
+				rule, -1, head_p, tail_p);
+			}
+		else
+			{
+			while ((*l != '\0') && !ITEM_SEP(*l))
+				l++;
+			}
+		if (*l == '\0') break; /* done */
+		}
+
+	return(retval);
+	}
+
+STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
+		STACK_OF(SSL_CIPHER) **cipher_list,
+		STACK_OF(SSL_CIPHER) **cipher_list_by_id,
+		const char *rule_str)
+	{
+	int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;
+	unsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl;
+	STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list;
+	const char *rule_p;
+	CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
+	const SSL_CIPHER **ca_list = NULL;
+
+	/*
+	 * Return with error if nothing to do.
+	 */
+	if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL)
+		return NULL;
+
+	/*
+	 * To reduce the work to do we only want to process the compiled
+	 * in algorithms, so we first get the mask of disabled ciphers.
+	 */
+	ssl_cipher_get_disabled(&disabled_mkey, &disabled_auth, &disabled_enc, &disabled_mac, &disabled_ssl);
+
+	/*
+	 * Now we have to collect the available ciphers from the compiled
+	 * in ciphers. We cannot get more than the number compiled in, so
+	 * it is used for allocation.
+	 */
+	num_of_ciphers = ssl_method->num_ciphers();
+#ifdef KSSL_DEBUG
+	printf("ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers);
+#endif    /* KSSL_DEBUG */
+	co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers);
+	if (co_list == NULL)
+		{
+		SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
+		return(NULL);	/* Failure */
+		}
+
+	ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers,
+	                           disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl,
+	                           co_list, &head, &tail);
+
+
+	/* Now arrange all ciphers by preference: */
+
+	/* Everything else being equal, prefer ephemeral ECDH over other key exchange mechanisms */
+	ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
+	ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);
+
+	/* AES is our preferred symmetric cipher */
+	ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
+
+	/* Temporarily enable everything else for sorting */
+	ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
+
+	/* Low priority for MD5 */
+	ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head, &tail);
+
+	/* Move anonymous ciphers to the end.  Usually, these will remain disabled.
+	 * (For applications that allow them, they aren't too bad, but we prefer
+	 * authenticated ciphers.) */
+	ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
+
+	/* Move ciphers without forward secrecy to the end */
+	ssl_cipher_apply_rule(0, 0, SSL_aECDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
+	/* ssl_cipher_apply_rule(0, 0, SSL_aDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); */
+	ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
+	ssl_cipher_apply_rule(0, SSL_kPSK, 0,0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
+	ssl_cipher_apply_rule(0, SSL_kKRB5, 0,0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
+
+	/* RC4 is sort-of broken -- move the the end */
+	ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
+
+	/* Now sort by symmetric encryption strength.  The above ordering remains
+	 * in force within each class */
+	if (!ssl_cipher_strength_sort(&head, &tail))
+		{
+		OPENSSL_free(co_list);
+		return NULL;
+		}
+
+	/* Now disable everything (maintaining the ordering!) */
+	ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);
+
+
+	/*
+	 * We also need cipher aliases for selecting based on the rule_str.
+	 * There might be two types of entries in the rule_str: 1) names
+	 * of ciphers themselves 2) aliases for groups of ciphers.
+	 * For 1) we need the available ciphers and for 2) the cipher
+	 * groups of cipher_aliases added together in one list (otherwise
+	 * we would be happy with just the cipher_aliases table).
+	 */
+	num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER);
+	num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;
+	ca_list = OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max);
+	if (ca_list == NULL)
+		{
+		OPENSSL_free(co_list);
+		SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
+		return(NULL);	/* Failure */
+		}
+	ssl_cipher_collect_aliases(ca_list, num_of_group_aliases,
+	                           disabled_mkey, disabled_auth, disabled_enc,
+				   disabled_mac, disabled_ssl, head);
+
+	/*
+	 * If the rule_string begins with DEFAULT, apply the default rule
+	 * before using the (possibly available) additional rules.
+	 */
+	ok = 1;
+	rule_p = rule_str;
+	if (strncmp(rule_str,"DEFAULT",7) == 0)
+		{
+		ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST,
+			&head, &tail, ca_list);
+		rule_p += 7;
+		if (*rule_p == ':')
+			rule_p++;
+		}
+
+	if (ok && (strlen(rule_p) > 0))
+		ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list);
+
+	OPENSSL_free((void *)ca_list);	/* Not needed anymore */
+
+	if (!ok)
+		{	/* Rule processing failure */
+		OPENSSL_free(co_list);
+		return(NULL);
+		}
+	
+	/*
+	 * Allocate new "cipherstack" for the result, return with error
+	 * if we cannot get one.
+	 */
+	if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL)
+		{
+		OPENSSL_free(co_list);
+		return(NULL);
+		}
+
+	/*
+	 * The cipher selection for the list is done. The ciphers are added
+	 * to the resulting precedence to the STACK_OF(SSL_CIPHER).
+	 */
+	for (curr = head; curr != NULL; curr = curr->next)
+		{
+		if (curr->active)
+			{
+			sk_SSL_CIPHER_push(cipherstack, curr->cipher);
+#ifdef CIPHER_DEBUG
+			printf("<%s>\n",curr->cipher->name);
+#endif
+			}
+		}
+	OPENSSL_free(co_list);	/* Not needed any longer */
+
+	tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack);
+	if (tmp_cipher_list == NULL)
+		{
+		sk_SSL_CIPHER_free(cipherstack);
+		return NULL;
+		}
+	if (*cipher_list != NULL)
+		sk_SSL_CIPHER_free(*cipher_list);
+	*cipher_list = cipherstack;
+	if (*cipher_list_by_id != NULL)
+		sk_SSL_CIPHER_free(*cipher_list_by_id);
+	*cipher_list_by_id = tmp_cipher_list;
+	(void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp);
+
+	sk_SSL_CIPHER_sort(*cipher_list_by_id);
+	return(cipherstack);
+	}
+
+char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
+	{
+	int is_export,pkl,kl;
+	const char *ver,*exp_str;
+	const char *kx,*au,*enc,*mac;
+	unsigned long alg_mkey,alg_auth,alg_enc,alg_mac,alg_ssl,alg2;
+#ifdef KSSL_DEBUG
+	static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx/%lx/%lx/%lx/%lx\n";
+#else
+	static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n";
+#endif /* KSSL_DEBUG */
+
+	alg_mkey = cipher->algorithm_mkey;
+	alg_auth = cipher->algorithm_auth;
+	alg_enc = cipher->algorithm_enc;
+	alg_mac = cipher->algorithm_mac;
+	alg_ssl = cipher->algorithm_ssl;
+
+	alg2=cipher->algorithm2;
+
+	is_export=SSL_C_IS_EXPORT(cipher);
+	pkl=SSL_C_EXPORT_PKEYLENGTH(cipher);
+	kl=SSL_C_EXPORT_KEYLENGTH(cipher);
+	exp_str=is_export?" export":"";
+	
+	if (alg_ssl & SSL_SSLV2)
+		ver="SSLv2";
+	else if (alg_ssl & SSL_SSLV3)
+		ver="SSLv3";
+	else
+		ver="unknown";
+
+	switch (alg_mkey)
+		{
+	case SSL_kRSA:
+		kx=is_export?(pkl == 512 ? "RSA(512)" : "RSA(1024)"):"RSA";
+		break;
+	case SSL_kDHr:
+		kx="DH/RSA";
+		break;
+	case SSL_kDHd:
+		kx="DH/DSS";
+		break;
+        case SSL_kKRB5:
+		kx="KRB5";
+		break;
+	case SSL_kEDH:
+		kx=is_export?(pkl == 512 ? "DH(512)" : "DH(1024)"):"DH";
+		break;
+	case SSL_kECDHr:
+		kx="ECDH/RSA";
+		break;
+	case SSL_kECDHe:
+		kx="ECDH/ECDSA";
+		break;
+	case SSL_kEECDH:
+		kx="ECDH";
+		break;
+	case SSL_kPSK:
+		kx="PSK";
+		break;
+	default:
+		kx="unknown";
+		}
+
+	switch (alg_auth)
+		{
+	case SSL_aRSA:
+		au="RSA";
+		break;
+	case SSL_aDSS:
+		au="DSS";
+		break;
+	case SSL_aDH:
+		au="DH";
+		break;
+        case SSL_aKRB5:
+		au="KRB5";
+		break;
+        case SSL_aECDH:
+		au="ECDH";
+		break;
+	case SSL_aNULL:
+		au="None";
+		break;
+	case SSL_aECDSA:
+		au="ECDSA";
+		break;
+	case SSL_aPSK:
+		au="PSK";
+		break;
+	default:
+		au="unknown";
+		break;
+		}
+
+	switch (alg_enc)
+		{
+	case SSL_DES:
+		enc=(is_export && kl == 5)?"DES(40)":"DES(56)";
+		break;
+	case SSL_3DES:
+		enc="3DES(168)";
+		break;
+	case SSL_RC4:
+		enc=is_export?(kl == 5 ? "RC4(40)" : "RC4(56)")
+		  :((alg2&SSL2_CF_8_BYTE_ENC)?"RC4(64)":"RC4(128)");
+		break;
+	case SSL_RC2:
+		enc=is_export?(kl == 5 ? "RC2(40)" : "RC2(56)"):"RC2(128)";
+		break;
+	case SSL_IDEA:
+		enc="IDEA(128)";
+		break;
+	case SSL_eNULL:
+		enc="None";
+		break;
+	case SSL_AES128:
+		enc="AES(128)";
+		break;
+	case SSL_AES256:
+		enc="AES(256)";
+		break;
+	case SSL_CAMELLIA128:
+		enc="Camellia(128)";
+		break;
+	case SSL_CAMELLIA256:
+		enc="Camellia(256)";
+		break;
+	case SSL_SEED:
+		enc="SEED(128)";
+		break;
+	default:
+		enc="unknown";
+		break;
+		}
+
+	switch (alg_mac)
+		{
+	case SSL_MD5:
+		mac="MD5";
+		break;
+	case SSL_SHA1:
+		mac="SHA1";
+		break;
+	default:
+		mac="unknown";
+		break;
+		}
+
+	if (buf == NULL)
+		{
+		len=128;
+		buf=OPENSSL_malloc(len);
+		if (buf == NULL) return("OPENSSL_malloc Error");
+		}
+	else if (len < 128)
+		return("Buffer too small");
+
+#ifdef KSSL_DEBUG
+	BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp_str,alg_mkey,alg_auth,alg_enc,alg_mac,alg_ssl);
+#else
+	BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp_str);
+#endif /* KSSL_DEBUG */
+	return(buf);
+	}
+
+char *SSL_CIPHER_get_version(const SSL_CIPHER *c)
+	{
+	int i;
+
+	if (c == NULL) return("(NONE)");
+	i=(int)(c->id>>24L);
+	if (i == 3)
+		return("TLSv1/SSLv3");
+	else if (i == 2)
+		return("SSLv2");
+	else
+		return("unknown");
+	}
+
+/* return the actual cipher being used */
+const char *SSL_CIPHER_get_name(const SSL_CIPHER *c)
+	{
+	if (c != NULL)
+		return(c->name);
+	return("(NONE)");
+	}
+
+/* number of bits for symmetric cipher */
+int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits)
+	{
+	int ret=0;
+
+	if (c != NULL)
+		{
+		if (alg_bits != NULL) *alg_bits = c->alg_bits;
+		ret = c->strength_bits;
+		}
+	return(ret);
+	}
+
+/* return string version of key exchange algorithm */
+const char* SSL_CIPHER_authentication_method(const SSL_CIPHER* cipher)
+	{
+	switch (cipher->algorithm_mkey)
+		{
+	case SSL_kRSA:
+		return SSL_TXT_RSA;
+	case SSL_kDHr:
+		return SSL_TXT_DH "_" SSL_TXT_RSA;
+	case SSL_kDHd:
+		return SSL_TXT_DH "_" SSL_TXT_DSS;
+	case SSL_kEDH:
+		switch (cipher->algorithm_auth)
+			{
+		case SSL_aDSS:
+			return "DHE_" SSL_TXT_DSS;
+		case SSL_aRSA:
+			return "DHE_" SSL_TXT_RSA;
+		case SSL_aNULL:
+			return SSL_TXT_DH "_anon";
+		default:
+			return "UNKNOWN";
+                        }
+	case SSL_kKRB5:
+		return SSL_TXT_KRB5;
+	case SSL_kECDHr:
+		return SSL_TXT_ECDH "_" SSL_TXT_RSA;
+	case SSL_kECDHe:
+		return SSL_TXT_ECDH "_" SSL_TXT_ECDSA;
+	case SSL_kEECDH:
+		switch (cipher->algorithm_auth)
+			{
+		case SSL_aECDSA:
+			return "ECDHE_" SSL_TXT_ECDSA;
+		case SSL_aRSA:
+			return "ECDHE_" SSL_TXT_RSA;
+		case SSL_aNULL:
+			return SSL_TXT_ECDH "_anon";
+		default:
+			return "UNKNOWN";
+                        }
+        default:
+		return "UNKNOWN";
+		}
+	}
+
+SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n)
+	{
+	SSL_COMP *ctmp;
+	int i,nn;
+
+	if ((n == 0) || (sk == NULL)) return(NULL);
+	nn=sk_SSL_COMP_num(sk);
+	for (i=0; i<nn; i++)
+		{
+		ctmp=sk_SSL_COMP_value(sk,i);
+		if (ctmp->id == n)
+			return(ctmp);
+		}
+	return(NULL);
+	}
+
+#ifdef OPENSSL_NO_COMP
+void *SSL_COMP_get_compression_methods(void)
+	{
+	return NULL;
+	}
+int SSL_COMP_add_compression_method(int id, void *cm)
+	{
+	return 1;
+	}
+
+const char *SSL_COMP_get_name(const void *comp)
+	{
+	return NULL;
+	}
+#else
+STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)
+	{
+	load_builtin_compressions();
+	return(ssl_comp_methods);
+	}
+
+int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm)
+	{
+	SSL_COMP *comp;
+
+        if (cm == NULL || cm->type == NID_undef)
+                return 1;
+
+	/* According to draft-ietf-tls-compression-04.txt, the
+	   compression number ranges should be the following:
+
+	   0 to 63:    methods defined by the IETF
+	   64 to 192:  external party methods assigned by IANA
+	   193 to 255: reserved for private use */
+	if (id < 193 || id > 255)
+		{
+		SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE);
+		return 0;
+		}
+
+	MemCheck_off();
+	comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP));
+	comp->id=id;
+	comp->method=cm;
+	load_builtin_compressions();
+	if (ssl_comp_methods
+		&& sk_SSL_COMP_find(ssl_comp_methods,comp) >= 0)
+		{
+		OPENSSL_free(comp);
+		MemCheck_on();
+		SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,SSL_R_DUPLICATE_COMPRESSION_ID);
+		return(1);
+		}
+	else if ((ssl_comp_methods == NULL)
+		|| !sk_SSL_COMP_push(ssl_comp_methods,comp))
+		{
+		OPENSSL_free(comp);
+		MemCheck_on();
+		SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,ERR_R_MALLOC_FAILURE);
+		return(1);
+		}
+	else
+		{
+		MemCheck_on();
+		return(0);
+		}
+	}
+
+const char *SSL_COMP_get_name(const COMP_METHOD *comp)
+	{
+	if (comp)
+		return comp->name;
+	return NULL;
+	}
+
+#endif
diff --git a/openssl/ssl/ssl_err.c b/openssl/ssl/ssl_err.c
new file mode 100644
index 0000000..4fcd5c0
--- /dev/null
+++ b/openssl/ssl/ssl_err.c
@@ -0,0 +1,577 @@
+/* ssl/ssl_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_SSL,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_SSL,0,reason)
+
+static ERR_STRING_DATA SSL_str_functs[]=
+	{
+{ERR_FUNC(SSL_F_CLIENT_CERTIFICATE),	"CLIENT_CERTIFICATE"},
+{ERR_FUNC(SSL_F_CLIENT_FINISHED),	"CLIENT_FINISHED"},
+{ERR_FUNC(SSL_F_CLIENT_HELLO),	"CLIENT_HELLO"},
+{ERR_FUNC(SSL_F_CLIENT_MASTER_KEY),	"CLIENT_MASTER_KEY"},
+{ERR_FUNC(SSL_F_D2I_SSL_SESSION),	"d2i_SSL_SESSION"},
+{ERR_FUNC(SSL_F_DO_DTLS1_WRITE),	"DO_DTLS1_WRITE"},
+{ERR_FUNC(SSL_F_DO_SSL3_WRITE),	"DO_SSL3_WRITE"},
+{ERR_FUNC(SSL_F_DTLS1_ACCEPT),	"DTLS1_ACCEPT"},
+{ERR_FUNC(SSL_F_DTLS1_ADD_CERT_TO_BUF),	"DTLS1_ADD_CERT_TO_BUF"},
+{ERR_FUNC(SSL_F_DTLS1_BUFFER_RECORD),	"DTLS1_BUFFER_RECORD"},
+{ERR_FUNC(SSL_F_DTLS1_CLIENT_HELLO),	"DTLS1_CLIENT_HELLO"},
+{ERR_FUNC(SSL_F_DTLS1_CONNECT),	"DTLS1_CONNECT"},
+{ERR_FUNC(SSL_F_DTLS1_ENC),	"DTLS1_ENC"},
+{ERR_FUNC(SSL_F_DTLS1_GET_HELLO_VERIFY),	"DTLS1_GET_HELLO_VERIFY"},
+{ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE),	"DTLS1_GET_MESSAGE"},
+{ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT),	"DTLS1_GET_MESSAGE_FRAGMENT"},
+{ERR_FUNC(SSL_F_DTLS1_GET_RECORD),	"DTLS1_GET_RECORD"},
+{ERR_FUNC(SSL_F_DTLS1_HANDLE_TIMEOUT),	"DTLS1_HANDLE_TIMEOUT"},
+{ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN),	"DTLS1_OUTPUT_CERT_CHAIN"},
+{ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT),	"DTLS1_PREPROCESS_FRAGMENT"},
+{ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE),	"DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"},
+{ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD),	"DTLS1_PROCESS_RECORD"},
+{ERR_FUNC(SSL_F_DTLS1_READ_BYTES),	"DTLS1_READ_BYTES"},
+{ERR_FUNC(SSL_F_DTLS1_READ_FAILED),	"DTLS1_READ_FAILED"},
+{ERR_FUNC(SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST),	"DTLS1_SEND_CERTIFICATE_REQUEST"},
+{ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE),	"DTLS1_SEND_CLIENT_CERTIFICATE"},
+{ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE),	"DTLS1_SEND_CLIENT_KEY_EXCHANGE"},
+{ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_VERIFY),	"DTLS1_SEND_CLIENT_VERIFY"},
+{ERR_FUNC(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST),	"DTLS1_SEND_HELLO_VERIFY_REQUEST"},
+{ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE),	"DTLS1_SEND_SERVER_CERTIFICATE"},
+{ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_HELLO),	"DTLS1_SEND_SERVER_HELLO"},
+{ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE),	"DTLS1_SEND_SERVER_KEY_EXCHANGE"},
+{ERR_FUNC(SSL_F_DTLS1_WRITE_APP_DATA_BYTES),	"DTLS1_WRITE_APP_DATA_BYTES"},
+{ERR_FUNC(SSL_F_GET_CLIENT_FINISHED),	"GET_CLIENT_FINISHED"},
+{ERR_FUNC(SSL_F_GET_CLIENT_HELLO),	"GET_CLIENT_HELLO"},
+{ERR_FUNC(SSL_F_GET_CLIENT_MASTER_KEY),	"GET_CLIENT_MASTER_KEY"},
+{ERR_FUNC(SSL_F_GET_SERVER_FINISHED),	"GET_SERVER_FINISHED"},
+{ERR_FUNC(SSL_F_GET_SERVER_HELLO),	"GET_SERVER_HELLO"},
+{ERR_FUNC(SSL_F_GET_SERVER_VERIFY),	"GET_SERVER_VERIFY"},
+{ERR_FUNC(SSL_F_I2D_SSL_SESSION),	"i2d_SSL_SESSION"},
+{ERR_FUNC(SSL_F_READ_N),	"READ_N"},
+{ERR_FUNC(SSL_F_REQUEST_CERTIFICATE),	"REQUEST_CERTIFICATE"},
+{ERR_FUNC(SSL_F_SERVER_FINISH),	"SERVER_FINISH"},
+{ERR_FUNC(SSL_F_SERVER_HELLO),	"SERVER_HELLO"},
+{ERR_FUNC(SSL_F_SERVER_VERIFY),	"SERVER_VERIFY"},
+{ERR_FUNC(SSL_F_SSL23_ACCEPT),	"SSL23_ACCEPT"},
+{ERR_FUNC(SSL_F_SSL23_CLIENT_HELLO),	"SSL23_CLIENT_HELLO"},
+{ERR_FUNC(SSL_F_SSL23_CONNECT),	"SSL23_CONNECT"},
+{ERR_FUNC(SSL_F_SSL23_GET_CLIENT_HELLO),	"SSL23_GET_CLIENT_HELLO"},
+{ERR_FUNC(SSL_F_SSL23_GET_SERVER_HELLO),	"SSL23_GET_SERVER_HELLO"},
+{ERR_FUNC(SSL_F_SSL23_PEEK),	"SSL23_PEEK"},
+{ERR_FUNC(SSL_F_SSL23_READ),	"SSL23_READ"},
+{ERR_FUNC(SSL_F_SSL23_WRITE),	"SSL23_WRITE"},
+{ERR_FUNC(SSL_F_SSL2_ACCEPT),	"SSL2_ACCEPT"},
+{ERR_FUNC(SSL_F_SSL2_CONNECT),	"SSL2_CONNECT"},
+{ERR_FUNC(SSL_F_SSL2_ENC_INIT),	"SSL2_ENC_INIT"},
+{ERR_FUNC(SSL_F_SSL2_GENERATE_KEY_MATERIAL),	"SSL2_GENERATE_KEY_MATERIAL"},
+{ERR_FUNC(SSL_F_SSL2_PEEK),	"SSL2_PEEK"},
+{ERR_FUNC(SSL_F_SSL2_READ),	"SSL2_READ"},
+{ERR_FUNC(SSL_F_SSL2_READ_INTERNAL),	"SSL2_READ_INTERNAL"},
+{ERR_FUNC(SSL_F_SSL2_SET_CERTIFICATE),	"SSL2_SET_CERTIFICATE"},
+{ERR_FUNC(SSL_F_SSL2_WRITE),	"SSL2_WRITE"},
+{ERR_FUNC(SSL_F_SSL3_ACCEPT),	"SSL3_ACCEPT"},
+{ERR_FUNC(SSL_F_SSL3_ADD_CERT_TO_BUF),	"SSL3_ADD_CERT_TO_BUF"},
+{ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL),	"SSL3_CALLBACK_CTRL"},
+{ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE),	"SSL3_CHANGE_CIPHER_STATE"},
+{ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM),	"SSL3_CHECK_CERT_AND_ALGORITHM"},
+{ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO),	"SSL3_CHECK_CLIENT_HELLO"},
+{ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO),	"SSL3_CLIENT_HELLO"},
+{ERR_FUNC(SSL_F_SSL3_CONNECT),	"SSL3_CONNECT"},
+{ERR_FUNC(SSL_F_SSL3_CTRL),	"SSL3_CTRL"},
+{ERR_FUNC(SSL_F_SSL3_CTX_CTRL),	"SSL3_CTX_CTRL"},
+{ERR_FUNC(SSL_F_SSL3_DIGEST_CACHED_RECORDS),	"SSL3_DIGEST_CACHED_RECORDS"},
+{ERR_FUNC(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC),	"SSL3_DO_CHANGE_CIPHER_SPEC"},
+{ERR_FUNC(SSL_F_SSL3_ENC),	"SSL3_ENC"},
+{ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK),	"SSL3_GENERATE_KEY_BLOCK"},
+{ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST),	"SSL3_GET_CERTIFICATE_REQUEST"},
+{ERR_FUNC(SSL_F_SSL3_GET_CERT_STATUS),	"SSL3_GET_CERT_STATUS"},
+{ERR_FUNC(SSL_F_SSL3_GET_CERT_VERIFY),	"SSL3_GET_CERT_VERIFY"},
+{ERR_FUNC(SSL_F_SSL3_GET_CLIENT_CERTIFICATE),	"SSL3_GET_CLIENT_CERTIFICATE"},
+{ERR_FUNC(SSL_F_SSL3_GET_CLIENT_HELLO),	"SSL3_GET_CLIENT_HELLO"},
+{ERR_FUNC(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE),	"SSL3_GET_CLIENT_KEY_EXCHANGE"},
+{ERR_FUNC(SSL_F_SSL3_GET_FINISHED),	"SSL3_GET_FINISHED"},
+{ERR_FUNC(SSL_F_SSL3_GET_KEY_EXCHANGE),	"SSL3_GET_KEY_EXCHANGE"},
+{ERR_FUNC(SSL_F_SSL3_GET_MESSAGE),	"SSL3_GET_MESSAGE"},
+{ERR_FUNC(SSL_F_SSL3_GET_NEW_SESSION_TICKET),	"SSL3_GET_NEW_SESSION_TICKET"},
+{ERR_FUNC(SSL_F_SSL3_GET_NEXT_PROTO),	"SSL3_GET_NEXT_PROTO"},
+{ERR_FUNC(SSL_F_SSL3_GET_RECORD),	"SSL3_GET_RECORD"},
+{ERR_FUNC(SSL_F_SSL3_GET_SERVER_CERTIFICATE),	"SSL3_GET_SERVER_CERTIFICATE"},
+{ERR_FUNC(SSL_F_SSL3_GET_SERVER_DONE),	"SSL3_GET_SERVER_DONE"},
+{ERR_FUNC(SSL_F_SSL3_GET_SERVER_HELLO),	"SSL3_GET_SERVER_HELLO"},
+{ERR_FUNC(SSL_F_SSL3_HANDSHAKE_MAC),	"ssl3_handshake_mac"},
+{ERR_FUNC(SSL_F_SSL3_NEW_SESSION_TICKET),	"SSL3_NEW_SESSION_TICKET"},
+{ERR_FUNC(SSL_F_SSL3_OUTPUT_CERT_CHAIN),	"SSL3_OUTPUT_CERT_CHAIN"},
+{ERR_FUNC(SSL_F_SSL3_PEEK),	"SSL3_PEEK"},
+{ERR_FUNC(SSL_F_SSL3_READ_BYTES),	"SSL3_READ_BYTES"},
+{ERR_FUNC(SSL_F_SSL3_READ_N),	"SSL3_READ_N"},
+{ERR_FUNC(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST),	"SSL3_SEND_CERTIFICATE_REQUEST"},
+{ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE),	"SSL3_SEND_CLIENT_CERTIFICATE"},
+{ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE),	"SSL3_SEND_CLIENT_KEY_EXCHANGE"},
+{ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_VERIFY),	"SSL3_SEND_CLIENT_VERIFY"},
+{ERR_FUNC(SSL_F_SSL3_SEND_SERVER_CERTIFICATE),	"SSL3_SEND_SERVER_CERTIFICATE"},
+{ERR_FUNC(SSL_F_SSL3_SEND_SERVER_HELLO),	"SSL3_SEND_SERVER_HELLO"},
+{ERR_FUNC(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE),	"SSL3_SEND_SERVER_KEY_EXCHANGE"},
+{ERR_FUNC(SSL_F_SSL3_SETUP_KEY_BLOCK),	"SSL3_SETUP_KEY_BLOCK"},
+{ERR_FUNC(SSL_F_SSL3_SETUP_READ_BUFFER),	"SSL3_SETUP_READ_BUFFER"},
+{ERR_FUNC(SSL_F_SSL3_SETUP_WRITE_BUFFER),	"SSL3_SETUP_WRITE_BUFFER"},
+{ERR_FUNC(SSL_F_SSL3_WRITE_BYTES),	"SSL3_WRITE_BYTES"},
+{ERR_FUNC(SSL_F_SSL3_WRITE_PENDING),	"SSL3_WRITE_PENDING"},
+{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT),	"SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT"},
+{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT),	"SSL_ADD_CLIENTHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK),	"SSL_add_dir_cert_subjects_to_stack"},
+{ERR_FUNC(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK),	"SSL_add_file_cert_subjects_to_stack"},
+{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT),	"SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT"},
+{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT),	"SSL_ADD_SERVERHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_SSL_BAD_METHOD),	"SSL_BAD_METHOD"},
+{ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST),	"SSL_BYTES_TO_CIPHER_LIST"},
+{ERR_FUNC(SSL_F_SSL_CERT_DUP),	"SSL_CERT_DUP"},
+{ERR_FUNC(SSL_F_SSL_CERT_INST),	"SSL_CERT_INST"},
+{ERR_FUNC(SSL_F_SSL_CERT_INSTANTIATE),	"SSL_CERT_INSTANTIATE"},
+{ERR_FUNC(SSL_F_SSL_CERT_NEW),	"SSL_CERT_NEW"},
+{ERR_FUNC(SSL_F_SSL_CHECK_PRIVATE_KEY),	"SSL_check_private_key"},
+{ERR_FUNC(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT),	"SSL_CHECK_SERVERHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG),	"SSL_CHECK_SRVR_ECC_CERT_AND_ALG"},
+{ERR_FUNC(SSL_F_SSL_CIPHER_PROCESS_RULESTR),	"SSL_CIPHER_PROCESS_RULESTR"},
+{ERR_FUNC(SSL_F_SSL_CIPHER_STRENGTH_SORT),	"SSL_CIPHER_STRENGTH_SORT"},
+{ERR_FUNC(SSL_F_SSL_CLEAR),	"SSL_clear"},
+{ERR_FUNC(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD),	"SSL_COMP_add_compression_method"},
+{ERR_FUNC(SSL_F_SSL_CREATE_CIPHER_LIST),	"SSL_CREATE_CIPHER_LIST"},
+{ERR_FUNC(SSL_F_SSL_CTRL),	"SSL_ctrl"},
+{ERR_FUNC(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY),	"SSL_CTX_check_private_key"},
+{ERR_FUNC(SSL_F_SSL_CTX_NEW),	"SSL_CTX_new"},
+{ERR_FUNC(SSL_F_SSL_CTX_SET_CIPHER_LIST),	"SSL_CTX_set_cipher_list"},
+{ERR_FUNC(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE),	"SSL_CTX_set_client_cert_engine"},
+{ERR_FUNC(SSL_F_SSL_CTX_SET_PURPOSE),	"SSL_CTX_set_purpose"},
+{ERR_FUNC(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT),	"SSL_CTX_set_session_id_context"},
+{ERR_FUNC(SSL_F_SSL_CTX_SET_SSL_VERSION),	"SSL_CTX_set_ssl_version"},
+{ERR_FUNC(SSL_F_SSL_CTX_SET_TRUST),	"SSL_CTX_set_trust"},
+{ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE),	"SSL_CTX_use_certificate"},
+{ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1),	"SSL_CTX_use_certificate_ASN1"},
+{ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE),	"SSL_CTX_use_certificate_chain_file"},
+{ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE),	"SSL_CTX_use_certificate_file"},
+{ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY),	"SSL_CTX_use_PrivateKey"},
+{ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1),	"SSL_CTX_use_PrivateKey_ASN1"},
+{ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE),	"SSL_CTX_use_PrivateKey_file"},
+{ERR_FUNC(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT),	"SSL_CTX_use_psk_identity_hint"},
+{ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY),	"SSL_CTX_use_RSAPrivateKey"},
+{ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1),	"SSL_CTX_use_RSAPrivateKey_ASN1"},
+{ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE),	"SSL_CTX_use_RSAPrivateKey_file"},
+{ERR_FUNC(SSL_F_SSL_DO_HANDSHAKE),	"SSL_do_handshake"},
+{ERR_FUNC(SSL_F_SSL_GET_NEW_SESSION),	"SSL_GET_NEW_SESSION"},
+{ERR_FUNC(SSL_F_SSL_GET_PREV_SESSION),	"SSL_GET_PREV_SESSION"},
+{ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_CERT),	"SSL_GET_SERVER_SEND_CERT"},
+{ERR_FUNC(SSL_F_SSL_GET_SIGN_PKEY),	"SSL_GET_SIGN_PKEY"},
+{ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER),	"SSL_INIT_WBIO_BUFFER"},
+{ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE),	"SSL_load_client_CA_file"},
+{ERR_FUNC(SSL_F_SSL_NEW),	"SSL_new"},
+{ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT),	"SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT"},
+{ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT),	"SSL_PARSE_CLIENTHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT),	"SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT"},
+{ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT),	"SSL_PARSE_SERVERHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_SSL_PEEK),	"SSL_peek"},
+{ERR_FUNC(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT),	"SSL_PREPARE_CLIENTHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT),	"SSL_PREPARE_SERVERHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_SSL_READ),	"SSL_read"},
+{ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT),	"SSL_RSA_PRIVATE_DECRYPT"},
+{ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT),	"SSL_RSA_PUBLIC_ENCRYPT"},
+{ERR_FUNC(SSL_F_SSL_SESSION_NEW),	"SSL_SESSION_new"},
+{ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP),	"SSL_SESSION_print_fp"},
+{ERR_FUNC(SSL_F_SSL_SESS_CERT_NEW),	"SSL_SESS_CERT_NEW"},
+{ERR_FUNC(SSL_F_SSL_SET_CERT),	"SSL_SET_CERT"},
+{ERR_FUNC(SSL_F_SSL_SET_CIPHER_LIST),	"SSL_set_cipher_list"},
+{ERR_FUNC(SSL_F_SSL_SET_FD),	"SSL_set_fd"},
+{ERR_FUNC(SSL_F_SSL_SET_PKEY),	"SSL_SET_PKEY"},
+{ERR_FUNC(SSL_F_SSL_SET_PURPOSE),	"SSL_set_purpose"},
+{ERR_FUNC(SSL_F_SSL_SET_RFD),	"SSL_set_rfd"},
+{ERR_FUNC(SSL_F_SSL_SET_SESSION),	"SSL_set_session"},
+{ERR_FUNC(SSL_F_SSL_SET_SESSION_ID_CONTEXT),	"SSL_set_session_id_context"},
+{ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT),	"SSL_set_session_ticket_ext"},
+{ERR_FUNC(SSL_F_SSL_SET_TRUST),	"SSL_set_trust"},
+{ERR_FUNC(SSL_F_SSL_SET_WFD),	"SSL_set_wfd"},
+{ERR_FUNC(SSL_F_SSL_SHUTDOWN),	"SSL_shutdown"},
+{ERR_FUNC(SSL_F_SSL_UNDEFINED_CONST_FUNCTION),	"SSL_UNDEFINED_CONST_FUNCTION"},
+{ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION),	"SSL_UNDEFINED_FUNCTION"},
+{ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION),	"SSL_UNDEFINED_VOID_FUNCTION"},
+{ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE),	"SSL_use_certificate"},
+{ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_ASN1),	"SSL_use_certificate_ASN1"},
+{ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_FILE),	"SSL_use_certificate_file"},
+{ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY),	"SSL_use_PrivateKey"},
+{ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_ASN1),	"SSL_use_PrivateKey_ASN1"},
+{ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_FILE),	"SSL_use_PrivateKey_file"},
+{ERR_FUNC(SSL_F_SSL_USE_PSK_IDENTITY_HINT),	"SSL_use_psk_identity_hint"},
+{ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY),	"SSL_use_RSAPrivateKey"},
+{ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1),	"SSL_use_RSAPrivateKey_ASN1"},
+{ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE),	"SSL_use_RSAPrivateKey_file"},
+{ERR_FUNC(SSL_F_SSL_VERIFY_CERT_CHAIN),	"SSL_VERIFY_CERT_CHAIN"},
+{ERR_FUNC(SSL_F_SSL_WRITE),	"SSL_write"},
+{ERR_FUNC(SSL_F_TLS1_CERT_VERIFY_MAC),	"tls1_cert_verify_mac"},
+{ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE),	"TLS1_CHANGE_CIPHER_STATE"},
+{ERR_FUNC(SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT),	"TLS1_CHECK_SERVERHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_TLS1_ENC),	"TLS1_ENC"},
+{ERR_FUNC(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT),	"TLS1_PREPARE_CLIENTHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT),	"TLS1_PREPARE_SERVERHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_TLS1_PRF),	"tls1_prf"},
+{ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK),	"TLS1_SETUP_KEY_BLOCK"},
+{ERR_FUNC(SSL_F_WRITE_PENDING),	"WRITE_PENDING"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA SSL_str_reasons[]=
+	{
+{ERR_REASON(SSL_R_APP_DATA_IN_HANDSHAKE) ,"app data in handshake"},
+{ERR_REASON(SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT),"attempt to reuse session in different context"},
+{ERR_REASON(SSL_R_BAD_ALERT_RECORD)      ,"bad alert record"},
+{ERR_REASON(SSL_R_BAD_AUTHENTICATION_TYPE),"bad authentication type"},
+{ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC),"bad change cipher spec"},
+{ERR_REASON(SSL_R_BAD_CHECKSUM)          ,"bad checksum"},
+{ERR_REASON(SSL_R_BAD_DATA_RETURNED_BY_CALLBACK),"bad data returned by callback"},
+{ERR_REASON(SSL_R_BAD_DECOMPRESSION)     ,"bad decompression"},
+{ERR_REASON(SSL_R_BAD_DH_G_LENGTH)       ,"bad dh g length"},
+{ERR_REASON(SSL_R_BAD_DH_PUB_KEY_LENGTH) ,"bad dh pub key length"},
+{ERR_REASON(SSL_R_BAD_DH_P_LENGTH)       ,"bad dh p length"},
+{ERR_REASON(SSL_R_BAD_DIGEST_LENGTH)     ,"bad digest length"},
+{ERR_REASON(SSL_R_BAD_DSA_SIGNATURE)     ,"bad dsa signature"},
+{ERR_REASON(SSL_R_BAD_ECC_CERT)          ,"bad ecc cert"},
+{ERR_REASON(SSL_R_BAD_ECDSA_SIGNATURE)   ,"bad ecdsa signature"},
+{ERR_REASON(SSL_R_BAD_ECPOINT)           ,"bad ecpoint"},
+{ERR_REASON(SSL_R_BAD_HANDSHAKE_LENGTH)  ,"bad handshake length"},
+{ERR_REASON(SSL_R_BAD_HELLO_REQUEST)     ,"bad hello request"},
+{ERR_REASON(SSL_R_BAD_LENGTH)            ,"bad length"},
+{ERR_REASON(SSL_R_BAD_MAC_DECODE)        ,"bad mac decode"},
+{ERR_REASON(SSL_R_BAD_MAC_LENGTH)        ,"bad mac length"},
+{ERR_REASON(SSL_R_BAD_MESSAGE_TYPE)      ,"bad message type"},
+{ERR_REASON(SSL_R_BAD_PACKET_LENGTH)     ,"bad packet length"},
+{ERR_REASON(SSL_R_BAD_PROTOCOL_VERSION_NUMBER),"bad protocol version number"},
+{ERR_REASON(SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH),"bad psk identity hint length"},
+{ERR_REASON(SSL_R_BAD_RESPONSE_ARGUMENT) ,"bad response argument"},
+{ERR_REASON(SSL_R_BAD_RSA_DECRYPT)       ,"bad rsa decrypt"},
+{ERR_REASON(SSL_R_BAD_RSA_ENCRYPT)       ,"bad rsa encrypt"},
+{ERR_REASON(SSL_R_BAD_RSA_E_LENGTH)      ,"bad rsa e length"},
+{ERR_REASON(SSL_R_BAD_RSA_MODULUS_LENGTH),"bad rsa modulus length"},
+{ERR_REASON(SSL_R_BAD_RSA_SIGNATURE)     ,"bad rsa signature"},
+{ERR_REASON(SSL_R_BAD_SIGNATURE)         ,"bad signature"},
+{ERR_REASON(SSL_R_BAD_SSL_FILETYPE)      ,"bad ssl filetype"},
+{ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH),"bad ssl session id length"},
+{ERR_REASON(SSL_R_BAD_STATE)             ,"bad state"},
+{ERR_REASON(SSL_R_BAD_WRITE_RETRY)       ,"bad write retry"},
+{ERR_REASON(SSL_R_BIO_NOT_SET)           ,"bio not set"},
+{ERR_REASON(SSL_R_BLOCK_CIPHER_PAD_IS_WRONG),"block cipher pad is wrong"},
+{ERR_REASON(SSL_R_BN_LIB)                ,"bn lib"},
+{ERR_REASON(SSL_R_CA_DN_LENGTH_MISMATCH) ,"ca dn length mismatch"},
+{ERR_REASON(SSL_R_CA_DN_TOO_LONG)        ,"ca dn too long"},
+{ERR_REASON(SSL_R_CCS_RECEIVED_EARLY)    ,"ccs received early"},
+{ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED),"certificate verify failed"},
+{ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH)  ,"cert length mismatch"},
+{ERR_REASON(SSL_R_CHALLENGE_IS_DIFFERENT),"challenge is different"},
+{ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH),"cipher code wrong length"},
+{ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE),"cipher or hash unavailable"},
+{ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR),"cipher table src error"},
+{ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT)    ,"clienthello tlsext"},
+{ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG),"compressed length too long"},
+{ERR_REASON(SSL_R_COMPRESSION_DISABLED)  ,"compression disabled"},
+{ERR_REASON(SSL_R_COMPRESSION_FAILURE)   ,"compression failure"},
+{ERR_REASON(SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE),"compression id not within private range"},
+{ERR_REASON(SSL_R_COMPRESSION_LIBRARY_ERROR),"compression library error"},
+{ERR_REASON(SSL_R_CONNECTION_ID_IS_DIFFERENT),"connection id is different"},
+{ERR_REASON(SSL_R_CONNECTION_TYPE_NOT_SET),"connection type not set"},
+{ERR_REASON(SSL_R_COOKIE_MISMATCH)       ,"cookie mismatch"},
+{ERR_REASON(SSL_R_DATA_BETWEEN_CCS_AND_FINISHED),"data between ccs and finished"},
+{ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG)  ,"data length too long"},
+{ERR_REASON(SSL_R_DECRYPTION_FAILED)     ,"decryption failed"},
+{ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC),"decryption failed or bad record mac"},
+{ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG),"dh public value length is wrong"},
+{ERR_REASON(SSL_R_DIGEST_CHECK_FAILED)   ,"digest check failed"},
+{ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG)  ,"dtls message too big"},
+{ERR_REASON(SSL_R_DUPLICATE_COMPRESSION_ID),"duplicate compression id"},
+{ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT),"ecc cert not for key agreement"},
+{ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_SIGNING),"ecc cert not for signing"},
+{ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE),"ecc cert should have rsa signature"},
+{ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE),"ecc cert should have sha1 signature"},
+{ERR_REASON(SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER),"ecgroup too large for cipher"},
+{ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG),"encrypted length too long"},
+{ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY),"error generating tmp rsa key"},
+{ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST),"error in received cipher list"},
+{ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE),"excessive message size"},
+{ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE) ,"extra data in message"},
+{ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS),"got a fin before a ccs"},
+{ERR_REASON(SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS),"got next proto before a ccs"},
+{ERR_REASON(SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION),"got next proto without seeing extension"},
+{ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST)   ,"https proxy request"},
+{ERR_REASON(SSL_R_HTTP_REQUEST)          ,"http request"},
+{ERR_REASON(SSL_R_ILLEGAL_PADDING)       ,"illegal padding"},
+{ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION),"inconsistent compression"},
+{ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"},
+{ERR_REASON(SSL_R_INVALID_COMMAND)       ,"invalid command"},
+{ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"},
+{ERR_REASON(SSL_R_INVALID_PURPOSE)       ,"invalid purpose"},
+{ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE),"invalid status response"},
+{ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH),"invalid ticket keys length"},
+{ERR_REASON(SSL_R_INVALID_TRUST)         ,"invalid trust"},
+{ERR_REASON(SSL_R_KEY_ARG_TOO_LONG)      ,"key arg too long"},
+{ERR_REASON(SSL_R_KRB5)                  ,"krb5"},
+{ERR_REASON(SSL_R_KRB5_C_CC_PRINC)       ,"krb5 client cc principal (no tkt?)"},
+{ERR_REASON(SSL_R_KRB5_C_GET_CRED)       ,"krb5 client get cred"},
+{ERR_REASON(SSL_R_KRB5_C_INIT)           ,"krb5 client init"},
+{ERR_REASON(SSL_R_KRB5_C_MK_REQ)         ,"krb5 client mk_req (expired tkt?)"},
+{ERR_REASON(SSL_R_KRB5_S_BAD_TICKET)     ,"krb5 server bad ticket"},
+{ERR_REASON(SSL_R_KRB5_S_INIT)           ,"krb5 server init"},
+{ERR_REASON(SSL_R_KRB5_S_RD_REQ)         ,"krb5 server rd_req (keytab perms?)"},
+{ERR_REASON(SSL_R_KRB5_S_TKT_EXPIRED)    ,"krb5 server tkt expired"},
+{ERR_REASON(SSL_R_KRB5_S_TKT_NYV)        ,"krb5 server tkt not yet valid"},
+{ERR_REASON(SSL_R_KRB5_S_TKT_SKEW)       ,"krb5 server tkt skew"},
+{ERR_REASON(SSL_R_LENGTH_MISMATCH)       ,"length mismatch"},
+{ERR_REASON(SSL_R_LENGTH_TOO_SHORT)      ,"length too short"},
+{ERR_REASON(SSL_R_LIBRARY_BUG)           ,"library bug"},
+{ERR_REASON(SSL_R_LIBRARY_HAS_NO_CIPHERS),"library has no ciphers"},
+{ERR_REASON(SSL_R_MESSAGE_TOO_LONG)      ,"message too long"},
+{ERR_REASON(SSL_R_MISSING_DH_DSA_CERT)   ,"missing dh dsa cert"},
+{ERR_REASON(SSL_R_MISSING_DH_KEY)        ,"missing dh key"},
+{ERR_REASON(SSL_R_MISSING_DH_RSA_CERT)   ,"missing dh rsa cert"},
+{ERR_REASON(SSL_R_MISSING_DSA_SIGNING_CERT),"missing dsa signing cert"},
+{ERR_REASON(SSL_R_MISSING_EXPORT_TMP_DH_KEY),"missing export tmp dh key"},
+{ERR_REASON(SSL_R_MISSING_EXPORT_TMP_RSA_KEY),"missing export tmp rsa key"},
+{ERR_REASON(SSL_R_MISSING_RSA_CERTIFICATE),"missing rsa certificate"},
+{ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT),"missing rsa encrypting cert"},
+{ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT),"missing rsa signing cert"},
+{ERR_REASON(SSL_R_MISSING_TMP_DH_KEY)    ,"missing tmp dh key"},
+{ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY)  ,"missing tmp ecdh key"},
+{ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY)   ,"missing tmp rsa key"},
+{ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY)  ,"missing tmp rsa pkey"},
+{ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE),"missing verify message"},
+{ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS) ,"multiple sgc restarts"},
+{ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET),"non sslv2 initial packet"},
+{ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED),"no certificates returned"},
+{ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED),"no certificate assigned"},
+{ERR_REASON(SSL_R_NO_CERTIFICATE_RETURNED),"no certificate returned"},
+{ERR_REASON(SSL_R_NO_CERTIFICATE_SET)    ,"no certificate set"},
+{ERR_REASON(SSL_R_NO_CERTIFICATE_SPECIFIED),"no certificate specified"},
+{ERR_REASON(SSL_R_NO_CIPHERS_AVAILABLE)  ,"no ciphers available"},
+{ERR_REASON(SSL_R_NO_CIPHERS_PASSED)     ,"no ciphers passed"},
+{ERR_REASON(SSL_R_NO_CIPHERS_SPECIFIED)  ,"no ciphers specified"},
+{ERR_REASON(SSL_R_NO_CIPHER_LIST)        ,"no cipher list"},
+{ERR_REASON(SSL_R_NO_CIPHER_MATCH)       ,"no cipher match"},
+{ERR_REASON(SSL_R_NO_CLIENT_CERT_METHOD) ,"no client cert method"},
+{ERR_REASON(SSL_R_NO_CLIENT_CERT_RECEIVED),"no client cert received"},
+{ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED),"no compression specified"},
+{ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER),"Peer haven't sent GOST certificate, required for selected ciphersuite"},
+{ERR_REASON(SSL_R_NO_METHOD_SPECIFIED)   ,"no method specified"},
+{ERR_REASON(SSL_R_NO_PRIVATEKEY)         ,"no privatekey"},
+{ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED),"no private key assigned"},
+{ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE),"no protocols available"},
+{ERR_REASON(SSL_R_NO_PUBLICKEY)          ,"no publickey"},
+{ERR_REASON(SSL_R_NO_RENEGOTIATION)      ,"no renegotiation"},
+{ERR_REASON(SSL_R_NO_REQUIRED_DIGEST)    ,"digest requred for handshake isn't computed"},
+{ERR_REASON(SSL_R_NO_SHARED_CIPHER)      ,"no shared cipher"},
+{ERR_REASON(SSL_R_NO_VERIFY_CALLBACK)    ,"no verify callback"},
+{ERR_REASON(SSL_R_NULL_SSL_CTX)          ,"null ssl ctx"},
+{ERR_REASON(SSL_R_NULL_SSL_METHOD_PASSED),"null ssl method passed"},
+{ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED),"old session cipher not returned"},
+{ERR_REASON(SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED),"old session compression algorithm not returned"},
+{ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE),"only tls allowed in fips mode"},
+{ERR_REASON(SSL_R_OPAQUE_PRF_INPUT_TOO_LONG),"opaque PRF input too long"},
+{ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG),"packet length too long"},
+{ERR_REASON(SSL_R_PARSE_TLSEXT)          ,"parse tlsext"},
+{ERR_REASON(SSL_R_PATH_TOO_LONG)         ,"path too long"},
+{ERR_REASON(SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE),"peer did not return a certificate"},
+{ERR_REASON(SSL_R_PEER_ERROR)            ,"peer error"},
+{ERR_REASON(SSL_R_PEER_ERROR_CERTIFICATE),"peer error certificate"},
+{ERR_REASON(SSL_R_PEER_ERROR_NO_CERTIFICATE),"peer error no certificate"},
+{ERR_REASON(SSL_R_PEER_ERROR_NO_CIPHER)  ,"peer error no cipher"},
+{ERR_REASON(SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE),"peer error unsupported certificate type"},
+{ERR_REASON(SSL_R_PRE_MAC_LENGTH_TOO_LONG),"pre mac length too long"},
+{ERR_REASON(SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS),"problems mapping cipher functions"},
+{ERR_REASON(SSL_R_PROTOCOL_IS_SHUTDOWN)  ,"protocol is shutdown"},
+{ERR_REASON(SSL_R_PSK_IDENTITY_NOT_FOUND),"psk identity not found"},
+{ERR_REASON(SSL_R_PSK_NO_CLIENT_CB)      ,"psk no client cb"},
+{ERR_REASON(SSL_R_PSK_NO_SERVER_CB)      ,"psk no server cb"},
+{ERR_REASON(SSL_R_PUBLIC_KEY_ENCRYPT_ERROR),"public key encrypt error"},
+{ERR_REASON(SSL_R_PUBLIC_KEY_IS_NOT_RSA) ,"public key is not rsa"},
+{ERR_REASON(SSL_R_PUBLIC_KEY_NOT_RSA)    ,"public key not rsa"},
+{ERR_REASON(SSL_R_READ_BIO_NOT_SET)      ,"read bio not set"},
+{ERR_REASON(SSL_R_READ_TIMEOUT_EXPIRED)  ,"read timeout expired"},
+{ERR_REASON(SSL_R_READ_WRONG_PACKET_TYPE),"read wrong packet type"},
+{ERR_REASON(SSL_R_RECORD_LENGTH_MISMATCH),"record length mismatch"},
+{ERR_REASON(SSL_R_RECORD_TOO_LARGE)      ,"record too large"},
+{ERR_REASON(SSL_R_RECORD_TOO_SMALL)      ,"record too small"},
+{ERR_REASON(SSL_R_RENEGOTIATE_EXT_TOO_LONG),"renegotiate ext too long"},
+{ERR_REASON(SSL_R_RENEGOTIATION_ENCODING_ERR),"renegotiation encoding err"},
+{ERR_REASON(SSL_R_RENEGOTIATION_MISMATCH),"renegotiation mismatch"},
+{ERR_REASON(SSL_R_REQUIRED_CIPHER_MISSING),"required cipher missing"},
+{ERR_REASON(SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING),"required compresssion algorithm missing"},
+{ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO),"reuse cert length not zero"},
+{ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO),"reuse cert type not zero"},
+{ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO),"reuse cipher list not zero"},
+{ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING),"scsv received when renegotiating"},
+{ERR_REASON(SSL_R_SERVERHELLO_TLSEXT)    ,"serverhello tlsext"},
+{ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"},
+{ERR_REASON(SSL_R_SESSION_MAY_NOT_BE_CREATED),"session may not be created"},
+{ERR_REASON(SSL_R_SHORT_READ)            ,"short read"},
+{ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"},
+{ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"},
+{ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG),"ssl2 connection id too long"},
+{ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT),"ssl3 ext invalid ecpointformat"},
+{ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME),"ssl3 ext invalid servername"},
+{ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE),"ssl3 ext invalid servername type"},
+{ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_LONG),"ssl3 session id too long"},
+{ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_SHORT),"ssl3 session id too short"},
+{ERR_REASON(SSL_R_SSLV3_ALERT_BAD_CERTIFICATE),"sslv3 alert bad certificate"},
+{ERR_REASON(SSL_R_SSLV3_ALERT_BAD_RECORD_MAC),"sslv3 alert bad record mac"},
+{ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED),"sslv3 alert certificate expired"},
+{ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED),"sslv3 alert certificate revoked"},
+{ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN),"sslv3 alert certificate unknown"},
+{ERR_REASON(SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE),"sslv3 alert decompression failure"},
+{ERR_REASON(SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE),"sslv3 alert handshake failure"},
+{ERR_REASON(SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER),"sslv3 alert illegal parameter"},
+{ERR_REASON(SSL_R_SSLV3_ALERT_NO_CERTIFICATE),"sslv3 alert no certificate"},
+{ERR_REASON(SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE),"sslv3 alert unexpected message"},
+{ERR_REASON(SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE),"sslv3 alert unsupported certificate"},
+{ERR_REASON(SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION),"ssl ctx has no default ssl version"},
+{ERR_REASON(SSL_R_SSL_HANDSHAKE_FAILURE) ,"ssl handshake failure"},
+{ERR_REASON(SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS),"ssl library has no ciphers"},
+{ERR_REASON(SSL_R_SSL_SESSION_ID_CALLBACK_FAILED),"ssl session id callback failed"},
+{ERR_REASON(SSL_R_SSL_SESSION_ID_CONFLICT),"ssl session id conflict"},
+{ERR_REASON(SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG),"ssl session id context too long"},
+{ERR_REASON(SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH),"ssl session id has bad length"},
+{ERR_REASON(SSL_R_SSL_SESSION_ID_IS_DIFFERENT),"ssl session id is different"},
+{ERR_REASON(SSL_R_TLSV1_ALERT_ACCESS_DENIED),"tlsv1 alert access denied"},
+{ERR_REASON(SSL_R_TLSV1_ALERT_DECODE_ERROR),"tlsv1 alert decode error"},
+{ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED),"tlsv1 alert decryption failed"},
+{ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR),"tlsv1 alert decrypt error"},
+{ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION),"tlsv1 alert export restriction"},
+{ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY),"tlsv1 alert insufficient security"},
+{ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR),"tlsv1 alert internal error"},
+{ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION),"tlsv1 alert no renegotiation"},
+{ERR_REASON(SSL_R_TLSV1_ALERT_PROTOCOL_VERSION),"tlsv1 alert protocol version"},
+{ERR_REASON(SSL_R_TLSV1_ALERT_RECORD_OVERFLOW),"tlsv1 alert record overflow"},
+{ERR_REASON(SSL_R_TLSV1_ALERT_UNKNOWN_CA),"tlsv1 alert unknown ca"},
+{ERR_REASON(SSL_R_TLSV1_ALERT_USER_CANCELLED),"tlsv1 alert user cancelled"},
+{ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE),"tlsv1 bad certificate hash value"},
+{ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE),"tlsv1 bad certificate status response"},
+{ERR_REASON(SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE),"tlsv1 certificate unobtainable"},
+{ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME),"tlsv1 unrecognized name"},
+{ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION),"tlsv1 unsupported extension"},
+{ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER),"tls client cert req with anon cipher"},
+{ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),"tls invalid ecpointformat list"},
+{ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST),"tls peer did not respond with certificate list"},
+{ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG),"tls rsa encrypted value length is wrong"},
+{ERR_REASON(SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER),"tried to use unsupported cipher"},
+{ERR_REASON(SSL_R_UNABLE_TO_DECODE_DH_CERTS),"unable to decode dh certs"},
+{ERR_REASON(SSL_R_UNABLE_TO_DECODE_ECDH_CERTS),"unable to decode ecdh certs"},
+{ERR_REASON(SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY),"unable to extract public key"},
+{ERR_REASON(SSL_R_UNABLE_TO_FIND_DH_PARAMETERS),"unable to find dh parameters"},
+{ERR_REASON(SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS),"unable to find ecdh parameters"},
+{ERR_REASON(SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS),"unable to find public key parameters"},
+{ERR_REASON(SSL_R_UNABLE_TO_FIND_SSL_METHOD),"unable to find ssl method"},
+{ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES),"unable to load ssl2 md5 routines"},
+{ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES),"unable to load ssl3 md5 routines"},
+{ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES),"unable to load ssl3 sha1 routines"},
+{ERR_REASON(SSL_R_UNEXPECTED_MESSAGE)    ,"unexpected message"},
+{ERR_REASON(SSL_R_UNEXPECTED_RECORD)     ,"unexpected record"},
+{ERR_REASON(SSL_R_UNINITIALIZED)         ,"uninitialized"},
+{ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE)    ,"unknown alert type"},
+{ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE),"unknown certificate type"},
+{ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED),"unknown cipher returned"},
+{ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE)   ,"unknown cipher type"},
+{ERR_REASON(SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE),"unknown key exchange type"},
+{ERR_REASON(SSL_R_UNKNOWN_PKEY_TYPE)     ,"unknown pkey type"},
+{ERR_REASON(SSL_R_UNKNOWN_PROTOCOL)      ,"unknown protocol"},
+{ERR_REASON(SSL_R_UNKNOWN_REMOTE_ERROR_TYPE),"unknown remote error type"},
+{ERR_REASON(SSL_R_UNKNOWN_SSL_VERSION)   ,"unknown ssl version"},
+{ERR_REASON(SSL_R_UNKNOWN_STATE)         ,"unknown state"},
+{ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED),"unsafe legacy renegotiation disabled"},
+{ERR_REASON(SSL_R_UNSUPPORTED_CIPHER)    ,"unsupported cipher"},
+{ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"},
+{ERR_REASON(SSL_R_UNSUPPORTED_DIGEST_TYPE),"unsupported digest type"},
+{ERR_REASON(SSL_R_UNSUPPORTED_ELLIPTIC_CURVE),"unsupported elliptic curve"},
+{ERR_REASON(SSL_R_UNSUPPORTED_PROTOCOL)  ,"unsupported protocol"},
+{ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION),"unsupported ssl version"},
+{ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE),"unsupported status type"},
+{ERR_REASON(SSL_R_WRITE_BIO_NOT_SET)     ,"write bio not set"},
+{ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED) ,"wrong cipher returned"},
+{ERR_REASON(SSL_R_WRONG_MESSAGE_TYPE)    ,"wrong message type"},
+{ERR_REASON(SSL_R_WRONG_NUMBER_OF_KEY_BITS),"wrong number of key bits"},
+{ERR_REASON(SSL_R_WRONG_SIGNATURE_LENGTH),"wrong signature length"},
+{ERR_REASON(SSL_R_WRONG_SIGNATURE_SIZE)  ,"wrong signature size"},
+{ERR_REASON(SSL_R_WRONG_SSL_VERSION)     ,"wrong ssl version"},
+{ERR_REASON(SSL_R_WRONG_VERSION_NUMBER)  ,"wrong version number"},
+{ERR_REASON(SSL_R_X509_LIB)              ,"x509 lib"},
+{ERR_REASON(SSL_R_X509_VERIFICATION_SETUP_PROBLEMS),"x509 verification setup problems"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_SSL_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(SSL_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,SSL_str_functs);
+		ERR_load_strings(0,SSL_str_reasons);
+		}
+#endif
+	}
diff --git a/openssl/ssl/ssl_err2.c b/openssl/ssl/ssl_err2.c
new file mode 100644
index 0000000..ea95a5f
--- /dev/null
+++ b/openssl/ssl/ssl_err2.c
@@ -0,0 +1,70 @@
+/* ssl/ssl_err2.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+void SSL_load_error_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+	ERR_load_crypto_strings();
+	ERR_load_SSL_strings();
+#endif
+	}
+
diff --git a/openssl/ssl/ssl_lib.c b/openssl/ssl/ssl_lib.c
new file mode 100644
index 0000000..add3058
--- /dev/null
+++ b/openssl/ssl/ssl_lib.c
@@ -0,0 +1,3259 @@
+/*! \file ssl/ssl_lib.c
+ *  \brief Version independent SSL functions.
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#ifdef REF_CHECK
+#  include <assert.h>
+#endif
+#include <stdio.h>
+#include "ssl_locl.h"
+#include "kssl_lcl.h"
+#include <openssl/objects.h>
+#include <openssl/lhash.h>
+#include <openssl/x509v3.h>
+#include <openssl/rand.h>
+#include <openssl/ocsp.h>
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+const char *SSL_version_str=OPENSSL_VERSION_TEXT;
+
+SSL3_ENC_METHOD ssl3_undef_enc_method={
+	/* evil casts, but these functions are only called if there's a library bug */
+	(int (*)(SSL *,int))ssl_undefined_function,
+	(int (*)(SSL *, unsigned char *, int))ssl_undefined_function,
+	ssl_undefined_function,
+	(int (*)(SSL *, unsigned char *, unsigned char *, int))ssl_undefined_function,
+	(int (*)(SSL*, int))ssl_undefined_function,
+	(int (*)(SSL *,  const char*, int, unsigned char *))ssl_undefined_function,
+	0,	/* finish_mac_length */
+	(int (*)(SSL *, int, unsigned char *))ssl_undefined_function,
+	NULL,	/* client_finished_label */
+	0,	/* client_finished_label_len */
+	NULL,	/* server_finished_label */
+	0,	/* server_finished_label_len */
+	(int (*)(int))ssl_undefined_function
+	};
+
+int SSL_clear(SSL *s)
+	{
+
+	if (s->method == NULL)
+		{
+		SSLerr(SSL_F_SSL_CLEAR,SSL_R_NO_METHOD_SPECIFIED);
+		return(0);
+		}
+
+	if (ssl_clear_bad_session(s))
+		{
+		SSL_SESSION_free(s->session);
+		s->session=NULL;
+		}
+
+	s->error=0;
+	s->hit=0;
+	s->shutdown=0;
+
+#if 0 /* Disabled since version 1.10 of this file (early return not
+       * needed because SSL_clear is not called when doing renegotiation) */
+	/* This is set if we are doing dynamic renegotiation so keep
+	 * the old cipher.  It is sort of a SSL_clear_lite :-) */
+	if (s->new_session) return(1);
+#else
+	if (s->new_session)
+		{
+		SSLerr(SSL_F_SSL_CLEAR,ERR_R_INTERNAL_ERROR);
+		return 0;
+		}
+#endif
+
+	s->type=0;
+
+	s->state=SSL_ST_BEFORE|((s->server)?SSL_ST_ACCEPT:SSL_ST_CONNECT);
+
+	s->version=s->method->version;
+	s->client_version=s->version;
+	s->rwstate=SSL_NOTHING;
+	s->rstate=SSL_ST_READ_HEADER;
+#if 0
+	s->read_ahead=s->ctx->read_ahead;
+#endif
+
+	if (s->init_buf != NULL)
+		{
+		BUF_MEM_free(s->init_buf);
+		s->init_buf=NULL;
+		}
+
+	ssl_clear_cipher_ctx(s);
+	ssl_clear_hash_ctx(&s->read_hash);
+	ssl_clear_hash_ctx(&s->write_hash);
+
+	s->first_packet=0;
+
+#if 1
+	/* Check to see if we were changed into a different method, if
+	 * so, revert back if we are not doing session-id reuse. */
+	if (!s->in_handshake && (s->session == NULL) && (s->method != s->ctx->method))
+		{
+		s->method->ssl_free(s);
+		s->method=s->ctx->method;
+		if (!s->method->ssl_new(s))
+			return(0);
+		}
+	else
+#endif
+		s->method->ssl_clear(s);
+	return(1);
+	}
+
+/** Used to change an SSL_CTXs default SSL method type */
+int SSL_CTX_set_ssl_version(SSL_CTX *ctx,const SSL_METHOD *meth)
+	{
+	STACK_OF(SSL_CIPHER) *sk;
+
+	ctx->method=meth;
+
+	sk=ssl_create_cipher_list(ctx->method,&(ctx->cipher_list),
+		&(ctx->cipher_list_by_id),
+		meth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST);
+	if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0))
+		{
+		SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION,SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS);
+		return(0);
+		}
+	return(1);
+	}
+
+SSL *SSL_new(SSL_CTX *ctx)
+	{
+	SSL *s;
+
+	if (ctx == NULL)
+		{
+		SSLerr(SSL_F_SSL_NEW,SSL_R_NULL_SSL_CTX);
+		return(NULL);
+		}
+	if (ctx->method == NULL)
+		{
+		SSLerr(SSL_F_SSL_NEW,SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION);
+		return(NULL);
+		}
+
+	s=(SSL *)OPENSSL_malloc(sizeof(SSL));
+	if (s == NULL) goto err;
+	memset(s,0,sizeof(SSL));
+
+#ifndef	OPENSSL_NO_KRB5
+	s->kssl_ctx = kssl_ctx_new();
+#endif	/* OPENSSL_NO_KRB5 */
+
+	s->options=ctx->options;
+	s->mode=ctx->mode;
+	s->max_cert_list=ctx->max_cert_list;
+
+	if (ctx->cert != NULL)
+		{
+		/* Earlier library versions used to copy the pointer to
+		 * the CERT, not its contents; only when setting new
+		 * parameters for the per-SSL copy, ssl_cert_new would be
+		 * called (and the direct reference to the per-SSL_CTX
+		 * settings would be lost, but those still were indirectly
+		 * accessed for various purposes, and for that reason they
+		 * used to be known as s->ctx->default_cert).
+		 * Now we don't look at the SSL_CTX's CERT after having
+		 * duplicated it once. */
+
+		s->cert = ssl_cert_dup(ctx->cert);
+		if (s->cert == NULL)
+			goto err;
+		}
+	else
+		s->cert=NULL; /* Cannot really happen (see SSL_CTX_new) */
+
+	s->read_ahead=ctx->read_ahead;
+	s->msg_callback=ctx->msg_callback;
+	s->msg_callback_arg=ctx->msg_callback_arg;
+	s->verify_mode=ctx->verify_mode;
+#if 0
+	s->verify_depth=ctx->verify_depth;
+#endif
+	s->sid_ctx_length=ctx->sid_ctx_length;
+	OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx);
+	memcpy(&s->sid_ctx,&ctx->sid_ctx,sizeof(s->sid_ctx));
+	s->verify_callback=ctx->default_verify_callback;
+	s->session_creation_enabled=1;
+	s->generate_session_id=ctx->generate_session_id;
+
+	s->param = X509_VERIFY_PARAM_new();
+	if (!s->param)
+		goto err;
+	X509_VERIFY_PARAM_inherit(s->param, ctx->param);
+#if 0
+	s->purpose = ctx->purpose;
+	s->trust = ctx->trust;
+#endif
+	s->quiet_shutdown=ctx->quiet_shutdown;
+	s->max_send_fragment = ctx->max_send_fragment;
+
+	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
+	s->ctx=ctx;
+#ifndef OPENSSL_NO_TLSEXT
+	s->tlsext_debug_cb = 0;
+	s->tlsext_debug_arg = NULL;
+	s->tlsext_ticket_expected = 0;
+	s->tlsext_status_type = -1;
+	s->tlsext_status_expected = 0;
+	s->tlsext_ocsp_ids = NULL;
+	s->tlsext_ocsp_exts = NULL;
+	s->tlsext_ocsp_resp = NULL;
+	s->tlsext_ocsp_resplen = -1;
+	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
+	s->initial_ctx=ctx;
+# ifndef OPENSSL_NO_NEXTPROTONEG
+	s->next_proto_negotiated = NULL;
+# endif
+#endif
+
+	s->verify_result=X509_V_OK;
+
+	s->method=ctx->method;
+
+	if (!s->method->ssl_new(s))
+		goto err;
+
+	s->references=1;
+	s->server=(ctx->method->ssl_accept == ssl_undefined_function)?0:1;
+
+	SSL_clear(s);
+
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
+
+#ifndef OPENSSL_NO_PSK
+	s->psk_client_callback=ctx->psk_client_callback;
+	s->psk_server_callback=ctx->psk_server_callback;
+#endif
+
+	return(s);
+err:
+	if (s != NULL)
+		{
+		if (s->cert != NULL)
+			ssl_cert_free(s->cert);
+		if (s->ctx != NULL)
+			SSL_CTX_free(s->ctx); /* decrement reference count */
+		OPENSSL_free(s);
+		}
+	SSLerr(SSL_F_SSL_NEW,ERR_R_MALLOC_FAILURE);
+	return(NULL);
+	}
+
+int SSL_CTX_set_session_id_context(SSL_CTX *ctx,const unsigned char *sid_ctx,
+				   unsigned int sid_ctx_len)
+    {
+    if(sid_ctx_len > sizeof ctx->sid_ctx)
+	{
+	SSLerr(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT,SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
+	return 0;
+	}
+    ctx->sid_ctx_length=sid_ctx_len;
+    memcpy(ctx->sid_ctx,sid_ctx,sid_ctx_len);
+
+    return 1;
+    }
+
+int SSL_set_session_id_context(SSL *ssl,const unsigned char *sid_ctx,
+			       unsigned int sid_ctx_len)
+    {
+    if(sid_ctx_len > SSL_MAX_SID_CTX_LENGTH)
+	{
+	SSLerr(SSL_F_SSL_SET_SESSION_ID_CONTEXT,SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
+	return 0;
+	}
+    ssl->sid_ctx_length=sid_ctx_len;
+    memcpy(ssl->sid_ctx,sid_ctx,sid_ctx_len);
+
+    return 1;
+    }
+
+int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb)
+	{
+	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+	ctx->generate_session_id = cb;
+	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+	return 1;
+	}
+
+int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb)
+	{
+	CRYPTO_w_lock(CRYPTO_LOCK_SSL);
+	ssl->generate_session_id = cb;
+	CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
+	return 1;
+	}
+
+int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
+				unsigned int id_len)
+	{
+	/* A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how
+	 * we can "construct" a session to give us the desired check - ie. to
+	 * find if there's a session in the hash table that would conflict with
+	 * any new session built out of this id/id_len and the ssl_version in
+	 * use by this SSL. */
+	SSL_SESSION r, *p;
+
+	if(id_len > sizeof r.session_id)
+		return 0;
+
+	r.ssl_version = ssl->version;
+	r.session_id_length = id_len;
+	memcpy(r.session_id, id, id_len);
+	/* NB: SSLv2 always uses a fixed 16-byte session ID, so even if a
+	 * callback is calling us to check the uniqueness of a shorter ID, it
+	 * must be compared as a padded-out ID because that is what it will be
+	 * converted to when the callback has finished choosing it. */
+	if((r.ssl_version == SSL2_VERSION) &&
+			(id_len < SSL2_SSL_SESSION_ID_LENGTH))
+		{
+		memset(r.session_id + id_len, 0,
+			SSL2_SSL_SESSION_ID_LENGTH - id_len);
+		r.session_id_length = SSL2_SSL_SESSION_ID_LENGTH;
+		}
+
+	CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
+	p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r);
+	CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
+	return (p != NULL);
+	}
+
+int SSL_CTX_set_purpose(SSL_CTX *s, int purpose)
+	{
+	return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
+	}
+
+int SSL_set_purpose(SSL *s, int purpose)
+	{
+	return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
+	}
+
+int SSL_CTX_set_trust(SSL_CTX *s, int trust)
+	{
+	return X509_VERIFY_PARAM_set_trust(s->param, trust);
+	}
+
+int SSL_set_trust(SSL *s, int trust)
+	{
+	return X509_VERIFY_PARAM_set_trust(s->param, trust);
+	}
+
+int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm)
+	{
+	return X509_VERIFY_PARAM_set1(ctx->param, vpm);
+	}
+
+int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm)
+	{
+	return X509_VERIFY_PARAM_set1(ssl->param, vpm);
+	}
+
+void SSL_free(SSL *s)
+	{
+	int i;
+
+	if(s == NULL)
+	    return;
+
+	i=CRYPTO_add(&s->references,-1,CRYPTO_LOCK_SSL);
+#ifdef REF_PRINT
+	REF_PRINT("SSL",s);
+#endif
+	if (i > 0) return;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"SSL_free, bad reference count\n");
+		abort(); /* ok */
+		}
+#endif
+
+	if (s->param)
+		X509_VERIFY_PARAM_free(s->param);
+
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
+
+	if (s->bbio != NULL)
+		{
+		/* If the buffering BIO is in place, pop it off */
+		if (s->bbio == s->wbio)
+			{
+			s->wbio=BIO_pop(s->wbio);
+			}
+		BIO_free(s->bbio);
+		s->bbio=NULL;
+		}
+	if (s->rbio != NULL)
+		BIO_free_all(s->rbio);
+	if ((s->wbio != NULL) && (s->wbio != s->rbio))
+		BIO_free_all(s->wbio);
+
+	if (s->init_buf != NULL) BUF_MEM_free(s->init_buf);
+
+	/* add extra stuff */
+	if (s->cipher_list != NULL) sk_SSL_CIPHER_free(s->cipher_list);
+	if (s->cipher_list_by_id != NULL) sk_SSL_CIPHER_free(s->cipher_list_by_id);
+
+	/* Make the next call work :-) */
+	if (s->session != NULL)
+		{
+		ssl_clear_bad_session(s);
+		SSL_SESSION_free(s->session);
+		}
+
+	ssl_clear_cipher_ctx(s);
+	ssl_clear_hash_ctx(&s->read_hash);
+	ssl_clear_hash_ctx(&s->write_hash);
+
+	if (s->cert != NULL) ssl_cert_free(s->cert);
+	/* Free up if allocated */
+
+#ifndef OPENSSL_NO_TLSEXT
+	if (s->tlsext_hostname)
+		OPENSSL_free(s->tlsext_hostname);
+	if (s->initial_ctx) SSL_CTX_free(s->initial_ctx);
+#ifndef OPENSSL_NO_EC
+	if (s->tlsext_ecpointformatlist) OPENSSL_free(s->tlsext_ecpointformatlist);
+	if (s->tlsext_ellipticcurvelist) OPENSSL_free(s->tlsext_ellipticcurvelist);
+#endif /* OPENSSL_NO_EC */
+	if (s->tlsext_opaque_prf_input) OPENSSL_free(s->tlsext_opaque_prf_input);
+	if (s->tlsext_ocsp_exts)
+		sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
+						X509_EXTENSION_free);
+	if (s->tlsext_ocsp_ids)
+		sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free);
+	if (s->tlsext_ocsp_resp)
+		OPENSSL_free(s->tlsext_ocsp_resp);
+#endif
+
+	if (s->client_CA != NULL)
+		sk_X509_NAME_pop_free(s->client_CA,X509_NAME_free);
+
+	if (s->method != NULL) s->method->ssl_free(s);
+
+	if (s->ctx) SSL_CTX_free(s->ctx);
+
+#ifndef	OPENSSL_NO_KRB5
+	if (s->kssl_ctx != NULL)
+		kssl_ctx_free(s->kssl_ctx);
+#endif	/* OPENSSL_NO_KRB5 */
+
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+	if (s->next_proto_negotiated)
+		OPENSSL_free(s->next_proto_negotiated);
+#endif
+
+	OPENSSL_free(s);
+	}
+
+void SSL_set_bio(SSL *s,BIO *rbio,BIO *wbio)
+	{
+	/* If the output buffering BIO is still in place, remove it
+	 */
+	if (s->bbio != NULL)
+		{
+		if (s->wbio == s->bbio)
+			{
+			s->wbio=s->wbio->next_bio;
+			s->bbio->next_bio=NULL;
+			}
+		}
+	if ((s->rbio != NULL) && (s->rbio != rbio))
+		BIO_free_all(s->rbio);
+	if ((s->wbio != NULL) && (s->wbio != wbio) && (s->rbio != s->wbio))
+		BIO_free_all(s->wbio);
+	s->rbio=rbio;
+	s->wbio=wbio;
+	}
+
+BIO *SSL_get_rbio(const SSL *s)
+	{ return(s->rbio); }
+
+BIO *SSL_get_wbio(const SSL *s)
+	{ return(s->wbio); }
+
+int SSL_get_fd(const SSL *s)
+	{
+	return(SSL_get_rfd(s));
+	}
+
+int SSL_get_rfd(const SSL *s)
+	{
+	int ret= -1;
+	BIO *b,*r;
+
+	b=SSL_get_rbio(s);
+	r=BIO_find_type(b,BIO_TYPE_DESCRIPTOR);
+	if (r != NULL)
+		BIO_get_fd(r,&ret);
+	return(ret);
+	}
+
+int SSL_get_wfd(const SSL *s)
+	{
+	int ret= -1;
+	BIO *b,*r;
+
+	b=SSL_get_wbio(s);
+	r=BIO_find_type(b,BIO_TYPE_DESCRIPTOR);
+	if (r != NULL)
+		BIO_get_fd(r,&ret);
+	return(ret);
+	}
+
+#ifndef OPENSSL_NO_SOCK
+int SSL_set_fd(SSL *s,int fd)
+	{
+	int ret=0;
+	BIO *bio=NULL;
+
+	bio=BIO_new(BIO_s_socket());
+
+	if (bio == NULL)
+		{
+		SSLerr(SSL_F_SSL_SET_FD,ERR_R_BUF_LIB);
+		goto err;
+		}
+	BIO_set_fd(bio,fd,BIO_NOCLOSE);
+	SSL_set_bio(s,bio,bio);
+	ret=1;
+err:
+	return(ret);
+	}
+
+int SSL_set_wfd(SSL *s,int fd)
+	{
+	int ret=0;
+	BIO *bio=NULL;
+
+	if ((s->rbio == NULL) || (BIO_method_type(s->rbio) != BIO_TYPE_SOCKET)
+		|| ((int)BIO_get_fd(s->rbio,NULL) != fd))
+		{
+		bio=BIO_new(BIO_s_socket());
+
+		if (bio == NULL)
+			{ SSLerr(SSL_F_SSL_SET_WFD,ERR_R_BUF_LIB); goto err; }
+		BIO_set_fd(bio,fd,BIO_NOCLOSE);
+		SSL_set_bio(s,SSL_get_rbio(s),bio);
+		}
+	else
+		SSL_set_bio(s,SSL_get_rbio(s),SSL_get_rbio(s));
+	ret=1;
+err:
+	return(ret);
+	}
+
+int SSL_set_rfd(SSL *s,int fd)
+	{
+	int ret=0;
+	BIO *bio=NULL;
+
+	if ((s->wbio == NULL) || (BIO_method_type(s->wbio) != BIO_TYPE_SOCKET)
+		|| ((int)BIO_get_fd(s->wbio,NULL) != fd))
+		{
+		bio=BIO_new(BIO_s_socket());
+
+		if (bio == NULL)
+			{
+			SSLerr(SSL_F_SSL_SET_RFD,ERR_R_BUF_LIB);
+			goto err;
+			}
+		BIO_set_fd(bio,fd,BIO_NOCLOSE);
+		SSL_set_bio(s,bio,SSL_get_wbio(s));
+		}
+	else
+		SSL_set_bio(s,SSL_get_wbio(s),SSL_get_wbio(s));
+	ret=1;
+err:
+	return(ret);
+	}
+#endif
+
+
+/* return length of latest Finished message we sent, copy to 'buf' */
+size_t SSL_get_finished(const SSL *s, void *buf, size_t count)
+	{
+	size_t ret = 0;
+	
+	if (s->s3 != NULL)
+		{
+		ret = s->s3->tmp.finish_md_len;
+		if (count > ret)
+			count = ret;
+		memcpy(buf, s->s3->tmp.finish_md, count);
+		}
+	return ret;
+	}
+
+/* return length of latest Finished message we expected, copy to 'buf' */
+size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count)
+	{
+	size_t ret = 0;
+	
+	if (s->s3 != NULL)
+		{
+		ret = s->s3->tmp.peer_finish_md_len;
+		if (count > ret)
+			count = ret;
+		memcpy(buf, s->s3->tmp.peer_finish_md, count);
+		}
+	return ret;
+	}
+
+
+int SSL_get_verify_mode(const SSL *s)
+	{
+	return(s->verify_mode);
+	}
+
+int SSL_get_verify_depth(const SSL *s)
+	{
+	return X509_VERIFY_PARAM_get_depth(s->param);
+	}
+
+int (*SSL_get_verify_callback(const SSL *s))(int,X509_STORE_CTX *)
+	{
+	return(s->verify_callback);
+	}
+
+int SSL_CTX_get_verify_mode(const SSL_CTX *ctx)
+	{
+	return(ctx->verify_mode);
+	}
+
+int SSL_CTX_get_verify_depth(const SSL_CTX *ctx)
+	{
+	return X509_VERIFY_PARAM_get_depth(ctx->param);
+	}
+
+int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int,X509_STORE_CTX *)
+	{
+	return(ctx->default_verify_callback);
+	}
+
+void SSL_set_verify(SSL *s,int mode,
+		    int (*callback)(int ok,X509_STORE_CTX *ctx))
+	{
+	s->verify_mode=mode;
+	if (callback != NULL)
+		s->verify_callback=callback;
+	}
+
+void SSL_set_verify_depth(SSL *s,int depth)
+	{
+	X509_VERIFY_PARAM_set_depth(s->param, depth);
+	}
+
+void SSL_set_read_ahead(SSL *s,int yes)
+	{
+	s->read_ahead=yes;
+	}
+
+int SSL_get_read_ahead(const SSL *s)
+	{
+	return(s->read_ahead);
+	}
+
+int SSL_pending(const SSL *s)
+	{
+	/* SSL_pending cannot work properly if read-ahead is enabled
+	 * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)),
+	 * and it is impossible to fix since SSL_pending cannot report
+	 * errors that may be observed while scanning the new data.
+	 * (Note that SSL_pending() is often used as a boolean value,
+	 * so we'd better not return -1.)
+	 */
+	return(s->method->ssl_pending(s));
+	}
+
+X509 *SSL_get_peer_certificate(const SSL *s)
+	{
+	X509 *r;
+	
+	if ((s == NULL) || (s->session == NULL))
+		r=NULL;
+	else
+		r=s->session->peer;
+
+	if (r == NULL) return(r);
+
+	CRYPTO_add(&r->references,1,CRYPTO_LOCK_X509);
+
+	return(r);
+	}
+
+STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s)
+	{
+	STACK_OF(X509) *r;
+	
+	if ((s == NULL) || (s->session == NULL) || (s->session->sess_cert == NULL))
+		r=NULL;
+	else
+		r=s->session->sess_cert->cert_chain;
+
+	/* If we are a client, cert_chain includes the peer's own
+	 * certificate; if we are a server, it does not. */
+	
+	return(r);
+	}
+
+/* Now in theory, since the calling process own 't' it should be safe to
+ * modify.  We need to be able to read f without being hassled */
+void SSL_copy_session_id(SSL *t,const SSL *f)
+	{
+	CERT *tmp;
+
+	/* Do we need to to SSL locking? */
+	SSL_set_session(t,SSL_get_session(f));
+
+	/* what if we are setup as SSLv2 but want to talk SSLv3 or
+	 * vice-versa */
+	if (t->method != f->method)
+		{
+		t->method->ssl_free(t);	/* cleanup current */
+		t->method=f->method;	/* change method */
+		t->method->ssl_new(t);	/* setup new */
+		}
+
+	tmp=t->cert;
+	if (f->cert != NULL)
+		{
+		CRYPTO_add(&f->cert->references,1,CRYPTO_LOCK_SSL_CERT);
+		t->cert=f->cert;
+		}
+	else
+		t->cert=NULL;
+	if (tmp != NULL) ssl_cert_free(tmp);
+	SSL_set_session_id_context(t,f->sid_ctx,f->sid_ctx_length);
+	}
+
+/* Fix this so it checks all the valid key/cert options */
+int SSL_CTX_check_private_key(const SSL_CTX *ctx)
+	{
+	if (	(ctx == NULL) ||
+		(ctx->cert == NULL) ||
+		(ctx->cert->key->x509 == NULL))
+		{
+		SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY,SSL_R_NO_CERTIFICATE_ASSIGNED);
+		return(0);
+		}
+	if 	(ctx->cert->key->privatekey == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY,SSL_R_NO_PRIVATE_KEY_ASSIGNED);
+		return(0);
+		}
+	return(X509_check_private_key(ctx->cert->key->x509, ctx->cert->key->privatekey));
+	}
+
+/* Fix this function so that it takes an optional type parameter */
+int SSL_check_private_key(const SSL *ssl)
+	{
+	if (ssl == NULL)
+		{
+		SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	if (ssl->cert == NULL)
+		{
+		SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,SSL_R_NO_CERTIFICATE_ASSIGNED);
+		return 0;
+		}
+	if (ssl->cert->key->x509 == NULL)
+		{
+		SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,SSL_R_NO_CERTIFICATE_ASSIGNED);
+		return(0);
+		}
+	if (ssl->cert->key->privatekey == NULL)
+		{
+		SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,SSL_R_NO_PRIVATE_KEY_ASSIGNED);
+		return(0);
+		}
+	return(X509_check_private_key(ssl->cert->key->x509,
+		ssl->cert->key->privatekey));
+	}
+
+int SSL_accept(SSL *s)
+	{
+	if (s->handshake_func == 0)
+		/* Not properly initialized yet */
+		SSL_set_accept_state(s);
+
+	return(s->method->ssl_accept(s));
+	}
+
+int SSL_connect(SSL *s)
+	{
+	if (s->handshake_func == 0)
+		/* Not properly initialized yet */
+		SSL_set_connect_state(s);
+
+	return(s->method->ssl_connect(s));
+	}
+
+long SSL_get_default_timeout(const SSL *s)
+	{
+	return(s->method->get_timeout());
+	}
+
+int SSL_read(SSL *s,void *buf,int num)
+	{
+	if (s->handshake_func == 0)
+		{
+		SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED);
+		return -1;
+		}
+
+	if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
+		{
+		s->rwstate=SSL_NOTHING;
+		return(0);
+		}
+	return(s->method->ssl_read(s,buf,num));
+	}
+
+int SSL_peek(SSL *s,void *buf,int num)
+	{
+	if (s->handshake_func == 0)
+		{
+		SSLerr(SSL_F_SSL_PEEK, SSL_R_UNINITIALIZED);
+		return -1;
+		}
+
+	if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
+		{
+		return(0);
+		}
+	return(s->method->ssl_peek(s,buf,num));
+	}
+
+int SSL_write(SSL *s,const void *buf,int num)
+	{
+	if (s->handshake_func == 0)
+		{
+		SSLerr(SSL_F_SSL_WRITE, SSL_R_UNINITIALIZED);
+		return -1;
+		}
+
+	if (s->shutdown & SSL_SENT_SHUTDOWN)
+		{
+		s->rwstate=SSL_NOTHING;
+		SSLerr(SSL_F_SSL_WRITE,SSL_R_PROTOCOL_IS_SHUTDOWN);
+		return(-1);
+		}
+	return(s->method->ssl_write(s,buf,num));
+	}
+
+int SSL_shutdown(SSL *s)
+	{
+	/* Note that this function behaves differently from what one might
+	 * expect.  Return values are 0 for no success (yet),
+	 * 1 for success; but calling it once is usually not enough,
+	 * even if blocking I/O is used (see ssl3_shutdown).
+	 */
+
+	if (s->handshake_func == 0)
+		{
+		SSLerr(SSL_F_SSL_SHUTDOWN, SSL_R_UNINITIALIZED);
+		return -1;
+		}
+
+	if ((s != NULL) && !SSL_in_init(s))
+		return(s->method->ssl_shutdown(s));
+	else
+		return(1);
+	}
+
+int SSL_renegotiate(SSL *s)
+	{
+	if (s->new_session == 0)
+		{
+		s->new_session=1;
+		}
+	return(s->method->ssl_renegotiate(s));
+	}
+
+int SSL_renegotiate_pending(SSL *s)
+	{
+	/* becomes true when negotiation is requested;
+	 * false again once a handshake has finished */
+	return (s->new_session != 0);
+	}
+
+long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)
+	{
+	long l;
+
+	switch (cmd)
+		{
+	case SSL_CTRL_GET_READ_AHEAD:
+		return(s->read_ahead);
+	case SSL_CTRL_SET_READ_AHEAD:
+		l=s->read_ahead;
+		s->read_ahead=larg;
+		return(l);
+
+	case SSL_CTRL_SET_MSG_CALLBACK_ARG:
+		s->msg_callback_arg = parg;
+		return 1;
+
+	case SSL_CTRL_OPTIONS:
+		return(s->options|=larg);
+	case SSL_CTRL_CLEAR_OPTIONS:
+		return(s->options&=~larg);
+	case SSL_CTRL_MODE:
+		return(s->mode|=larg);
+	case SSL_CTRL_CLEAR_MODE:
+		return(s->mode &=~larg);
+	case SSL_CTRL_GET_MAX_CERT_LIST:
+		return(s->max_cert_list);
+	case SSL_CTRL_SET_MAX_CERT_LIST:
+		l=s->max_cert_list;
+		s->max_cert_list=larg;
+		return(l);
+	case SSL_CTRL_SET_MTU:
+#ifndef OPENSSL_NO_DTLS1
+		if (larg < (long)dtls1_min_mtu())
+			return 0;
+#endif
+
+		if (SSL_version(s) == DTLS1_VERSION ||
+		    SSL_version(s) == DTLS1_BAD_VER)
+			{
+			s->d1->mtu = larg;
+			return larg;
+			}
+		return 0;
+	case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
+		if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
+			return 0;
+		s->max_send_fragment = larg;
+		return 1;
+	case SSL_CTRL_GET_RI_SUPPORT:
+		if (s->s3)
+			return s->s3->send_connection_binding;
+		else return 0;
+	default:
+		return(s->method->ssl_ctrl(s,cmd,larg,parg));
+		}
+	}
+
+long SSL_callback_ctrl(SSL *s, int cmd, void (*fp)(void))
+	{
+	switch(cmd)
+		{
+	case SSL_CTRL_SET_MSG_CALLBACK:
+		s->msg_callback = (void (*)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg))(fp);
+		return 1;
+		
+	default:
+		return(s->method->ssl_callback_ctrl(s,cmd,fp));
+		}
+	}
+
+LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx)
+	{
+	return ctx->sessions;
+	}
+
+long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,void *parg)
+	{
+	long l;
+
+	switch (cmd)
+		{
+	case SSL_CTRL_GET_READ_AHEAD:
+		return(ctx->read_ahead);
+	case SSL_CTRL_SET_READ_AHEAD:
+		l=ctx->read_ahead;
+		ctx->read_ahead=larg;
+		return(l);
+		
+	case SSL_CTRL_SET_MSG_CALLBACK_ARG:
+		ctx->msg_callback_arg = parg;
+		return 1;
+
+	case SSL_CTRL_GET_MAX_CERT_LIST:
+		return(ctx->max_cert_list);
+	case SSL_CTRL_SET_MAX_CERT_LIST:
+		l=ctx->max_cert_list;
+		ctx->max_cert_list=larg;
+		return(l);
+
+	case SSL_CTRL_SET_SESS_CACHE_SIZE:
+		l=ctx->session_cache_size;
+		ctx->session_cache_size=larg;
+		return(l);
+	case SSL_CTRL_GET_SESS_CACHE_SIZE:
+		return(ctx->session_cache_size);
+	case SSL_CTRL_SET_SESS_CACHE_MODE:
+		l=ctx->session_cache_mode;
+		ctx->session_cache_mode=larg;
+		return(l);
+	case SSL_CTRL_GET_SESS_CACHE_MODE:
+		return(ctx->session_cache_mode);
+
+	case SSL_CTRL_SESS_NUMBER:
+		return(lh_SSL_SESSION_num_items(ctx->sessions));
+	case SSL_CTRL_SESS_CONNECT:
+		return(ctx->stats.sess_connect);
+	case SSL_CTRL_SESS_CONNECT_GOOD:
+		return(ctx->stats.sess_connect_good);
+	case SSL_CTRL_SESS_CONNECT_RENEGOTIATE:
+		return(ctx->stats.sess_connect_renegotiate);
+	case SSL_CTRL_SESS_ACCEPT:
+		return(ctx->stats.sess_accept);
+	case SSL_CTRL_SESS_ACCEPT_GOOD:
+		return(ctx->stats.sess_accept_good);
+	case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE:
+		return(ctx->stats.sess_accept_renegotiate);
+	case SSL_CTRL_SESS_HIT:
+		return(ctx->stats.sess_hit);
+	case SSL_CTRL_SESS_CB_HIT:
+		return(ctx->stats.sess_cb_hit);
+	case SSL_CTRL_SESS_MISSES:
+		return(ctx->stats.sess_miss);
+	case SSL_CTRL_SESS_TIMEOUTS:
+		return(ctx->stats.sess_timeout);
+	case SSL_CTRL_SESS_CACHE_FULL:
+		return(ctx->stats.sess_cache_full);
+	case SSL_CTRL_OPTIONS:
+		return(ctx->options|=larg);
+	case SSL_CTRL_CLEAR_OPTIONS:
+		return(ctx->options&=~larg);
+	case SSL_CTRL_MODE:
+		return(ctx->mode|=larg);
+	case SSL_CTRL_CLEAR_MODE:
+		return(ctx->mode&=~larg);
+	case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
+		if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
+			return 0;
+		ctx->max_send_fragment = larg;
+		return 1;
+	default:
+		return(ctx->method->ssl_ctx_ctrl(ctx,cmd,larg,parg));
+		}
+	}
+
+long SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
+	{
+	switch(cmd)
+		{
+	case SSL_CTRL_SET_MSG_CALLBACK:
+		ctx->msg_callback = (void (*)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg))(fp);
+		return 1;
+
+	default:
+		return(ctx->method->ssl_ctx_callback_ctrl(ctx,cmd,fp));
+		}
+	}
+
+int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b)
+	{
+	long l;
+
+	l=a->id-b->id;
+	if (l == 0L)
+		return(0);
+	else
+		return((l > 0)?1:-1);
+	}
+
+int ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap,
+			const SSL_CIPHER * const *bp)
+	{
+	long l;
+
+	l=(*ap)->id-(*bp)->id;
+	if (l == 0L)
+		return(0);
+	else
+		return((l > 0)?1:-1);
+	}
+
+/** return a STACK of the ciphers available for the SSL and in order of
+ * preference */
+STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s)
+	{
+	if (s != NULL)
+		{
+		if (s->cipher_list != NULL)
+			{
+			return(s->cipher_list);
+			}
+		else if ((s->ctx != NULL) &&
+			(s->ctx->cipher_list != NULL))
+			{
+			return(s->ctx->cipher_list);
+			}
+		}
+	return(NULL);
+	}
+
+/** return a STACK of the ciphers available for the SSL and in order of
+ * algorithm id */
+STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s)
+	{
+	if (s != NULL)
+		{
+		if (s->cipher_list_by_id != NULL)
+			{
+			return(s->cipher_list_by_id);
+			}
+		else if ((s->ctx != NULL) &&
+			(s->ctx->cipher_list_by_id != NULL))
+			{
+			return(s->ctx->cipher_list_by_id);
+			}
+		}
+	return(NULL);
+	}
+
+/** The old interface to get the same thing as SSL_get_ciphers() */
+const char *SSL_get_cipher_list(const SSL *s,int n)
+	{
+	SSL_CIPHER *c;
+	STACK_OF(SSL_CIPHER) *sk;
+
+	if (s == NULL) return(NULL);
+	sk=SSL_get_ciphers(s);
+	if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= n))
+		return(NULL);
+	c=sk_SSL_CIPHER_value(sk,n);
+	if (c == NULL) return(NULL);
+	return(c->name);
+	}
+
+/** specify the ciphers to be used by default by the SSL_CTX */
+int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str)
+	{
+	STACK_OF(SSL_CIPHER) *sk;
+	
+	sk=ssl_create_cipher_list(ctx->method,&ctx->cipher_list,
+		&ctx->cipher_list_by_id,str);
+	/* ssl_create_cipher_list may return an empty stack if it
+	 * was unable to find a cipher matching the given rule string
+	 * (for example if the rule string specifies a cipher which
+	 * has been disabled). This is not an error as far as
+	 * ssl_create_cipher_list is concerned, and hence
+	 * ctx->cipher_list and ctx->cipher_list_by_id has been
+	 * updated. */
+	if (sk == NULL)
+		return 0;
+	else if (sk_SSL_CIPHER_num(sk) == 0)
+		{
+		SSLerr(SSL_F_SSL_CTX_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH);
+		return 0;
+		}
+	return 1;
+	}
+
+/** specify the ciphers to be used by the SSL */
+int SSL_set_cipher_list(SSL *s,const char *str)
+	{
+	STACK_OF(SSL_CIPHER) *sk;
+	
+	sk=ssl_create_cipher_list(s->ctx->method,&s->cipher_list,
+		&s->cipher_list_by_id,str);
+	/* see comment in SSL_CTX_set_cipher_list */
+	if (sk == NULL)
+		return 0;
+	else if (sk_SSL_CIPHER_num(sk) == 0)
+		{
+		SSLerr(SSL_F_SSL_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH);
+		return 0;
+		}
+	return 1;
+	}
+
+/** specify the ciphers to be used by the SSL */
+int SSL_set_cipher_lists(SSL *s,STACK_OF(SSL_CIPHER) *sk)
+	{
+	STACK_OF(SSL_CIPHER) *tmp_cipher_list;
+
+	if (sk == NULL)
+		return 0;
+
+        /* Based on end of ssl_create_cipher_list */
+	tmp_cipher_list = sk_SSL_CIPHER_dup(sk);
+	if (tmp_cipher_list == NULL)
+		{
+		return 0;
+		}
+	if (s->cipher_list != NULL)
+		sk_SSL_CIPHER_free(s->cipher_list);
+	s->cipher_list = sk;
+	if (s->cipher_list_by_id != NULL)
+		sk_SSL_CIPHER_free(s->cipher_list_by_id);
+	s->cipher_list_by_id = tmp_cipher_list;
+	(void)sk_SSL_CIPHER_set_cmp_func(s->cipher_list_by_id,ssl_cipher_ptr_id_cmp);
+
+	sk_SSL_CIPHER_sort(s->cipher_list_by_id);
+	return 1;
+	}
+
+/* works well for SSLv2, not so good for SSLv3 */
+char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len)
+	{
+	char *p;
+	STACK_OF(SSL_CIPHER) *sk;
+	SSL_CIPHER *c;
+	int i;
+
+	if ((s->session == NULL) || (s->session->ciphers == NULL) ||
+		(len < 2))
+		return(NULL);
+
+	p=buf;
+	sk=s->session->ciphers;
+	for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
+		{
+		int n;
+
+		c=sk_SSL_CIPHER_value(sk,i);
+		n=strlen(c->name);
+		if (n+1 > len)
+			{
+			if (p != buf)
+				--p;
+			*p='\0';
+			return buf;
+			}
+		strcpy(p,c->name);
+		p+=n;
+		*(p++)=':';
+		len-=n+1;
+		}
+	p[-1]='\0';
+	return(buf);
+	}
+
+int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
+			     int (*put_cb)(const SSL_CIPHER *, unsigned char *))
+	{
+	int i,j=0;
+	SSL_CIPHER *c;
+	unsigned char *q;
+#ifndef OPENSSL_NO_KRB5
+	int nokrb5 = !kssl_tgt_is_available(s->kssl_ctx);
+#endif /* OPENSSL_NO_KRB5 */
+
+	if (sk == NULL) return(0);
+	q=p;
+
+	for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
+		{
+		c=sk_SSL_CIPHER_value(sk,i);
+#ifndef OPENSSL_NO_KRB5
+		if (((c->algorithm_mkey & SSL_kKRB5) || (c->algorithm_auth & SSL_aKRB5)) &&
+		    nokrb5)
+		    continue;
+#endif /* OPENSSL_NO_KRB5 */
+#ifndef OPENSSL_NO_PSK
+		/* with PSK there must be client callback set */
+		if (((c->algorithm_mkey & SSL_kPSK) || (c->algorithm_auth & SSL_aPSK)) &&
+		    s->psk_client_callback == NULL)
+			continue;
+#endif /* OPENSSL_NO_PSK */
+		j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p);
+		p+=j;
+		}
+	/* If p == q, no ciphers and caller indicates an error. Otherwise
+	 * add SCSV if not renegotiating.
+	 */
+	if (p != q && !s->new_session)
+		{
+		static SSL_CIPHER scsv =
+			{
+			0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
+			};
+		j = put_cb ? put_cb(&scsv,p) : ssl_put_cipher_by_char(s,&scsv,p);
+		p+=j;
+#ifdef OPENSSL_RI_DEBUG
+		fprintf(stderr, "SCSV sent by client\n");
+#endif
+		}
+
+	return(p-q);
+	}
+
+STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
+					       STACK_OF(SSL_CIPHER) **skp)
+	{
+	const SSL_CIPHER *c;
+	STACK_OF(SSL_CIPHER) *sk;
+	int i,n;
+	if (s->s3)
+		s->s3->send_connection_binding = 0;
+
+	n=ssl_put_cipher_by_char(s,NULL,NULL);
+	if ((num%n) != 0)
+		{
+		SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
+		return(NULL);
+		}
+	if ((skp == NULL) || (*skp == NULL))
+		sk=sk_SSL_CIPHER_new_null(); /* change perhaps later */
+	else
+		{
+		sk= *skp;
+		sk_SSL_CIPHER_zero(sk);
+		}
+
+	for (i=0; i<num; i+=n)
+		{
+		/* Check for SCSV */
+		if (s->s3 && (n != 3 || !p[0]) &&
+			(p[n-2] == ((SSL3_CK_SCSV >> 8) & 0xff)) &&
+			(p[n-1] == (SSL3_CK_SCSV & 0xff)))
+			{
+			/* SCSV fatal if renegotiating */
+			if (s->new_session)
+				{
+				SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); 
+				goto err;
+				}
+			s->s3->send_connection_binding = 1;
+			p += n;
+#ifdef OPENSSL_RI_DEBUG
+			fprintf(stderr, "SCSV received by server\n");
+#endif
+			continue;
+			}
+
+		c=ssl_get_cipher_by_char(s,p);
+		p+=n;
+		if (c != NULL)
+			{
+			if (!sk_SSL_CIPHER_push(sk,c))
+				{
+				SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			}
+		}
+
+	if (skp != NULL)
+		*skp=sk;
+	return(sk);
+err:
+	if ((skp == NULL) || (*skp == NULL))
+		sk_SSL_CIPHER_free(sk);
+	return(NULL);
+	}
+
+
+#ifndef OPENSSL_NO_TLSEXT
+/** return a servername extension value if provided in Client Hello, or NULL.
+ * So far, only host_name types are defined (RFC 3546).
+ */
+
+const char *SSL_get_servername(const SSL *s, const int type)
+	{
+	if (type != TLSEXT_NAMETYPE_host_name)
+		return NULL;
+
+	return s->session && !s->tlsext_hostname ?
+		s->session->tlsext_hostname :
+		s->tlsext_hostname;
+	}
+
+int SSL_get_servername_type(const SSL *s)
+	{
+	if (s->session && (!s->tlsext_hostname ? s->session->tlsext_hostname : s->tlsext_hostname))
+		return TLSEXT_NAMETYPE_host_name;
+	return -1;
+	}
+
+# ifndef OPENSSL_NO_NEXTPROTONEG
+/* SSL_select_next_proto implements the standard protocol selection. It is
+ * expected that this function is called from the callback set by
+ * SSL_CTX_set_next_proto_select_cb.
+ *
+ * The protocol data is assumed to be a vector of 8-bit, length prefixed byte
+ * strings. The length byte itself is not included in the length. A byte
+ * string of length 0 is invalid. No byte string may be truncated.
+ *
+ * The current, but experimental algorithm for selecting the protocol is:
+ *
+ * 1) If the server doesn't support NPN then this is indicated to the
+ * callback. In this case, the client application has to abort the connection
+ * or have a default application level protocol.
+ *
+ * 2) If the server supports NPN, but advertises an empty list then the
+ * client selects the first protcol in its list, but indicates via the
+ * API that this fallback case was enacted.
+ *
+ * 3) Otherwise, the client finds the first protocol in the server's list
+ * that it supports and selects this protocol. This is because it's
+ * assumed that the server has better information about which protocol
+ * a client should use.
+ *
+ * 4) If the client doesn't support any of the server's advertised
+ * protocols, then this is treated the same as case 2.
+ *
+ * It returns either
+ * OPENSSL_NPN_NEGOTIATED if a common protocol was found, or
+ * OPENSSL_NPN_NO_OVERLAP if the fallback case was reached.
+ */
+int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, const unsigned char *server, unsigned int server_len, const unsigned char *client, unsigned int client_len)
+	{
+	unsigned int i, j;
+	const unsigned char *result;
+	int status = OPENSSL_NPN_UNSUPPORTED;
+
+	/* For each protocol in server preference order, see if we support it. */
+	for (i = 0; i < server_len; )
+		{
+		for (j = 0; j < client_len; )
+			{
+			if (server[i] == client[j] &&
+			    memcmp(&server[i+1], &client[j+1], server[i]) == 0)
+				{
+				/* We found a match */
+				result = &server[i];
+				status = OPENSSL_NPN_NEGOTIATED;
+				goto found;
+				}
+			j += client[j];
+			j++;
+			}
+		i += server[i];
+		i++;
+		}
+
+	/* There's no overlap between our protocols and the server's list. */
+	result = client;
+	status = OPENSSL_NPN_NO_OVERLAP;
+
+	found:
+	*out = (unsigned char *) result + 1;
+	*outlen = result[0];
+	return status;
+	}
+
+/* SSL_get0_next_proto_negotiated sets *data and *len to point to the client's
+ * requested protocol for this connection and returns 0. If the client didn't
+ * request any protocol, then *data is set to NULL.
+ *
+ * Note that the client can request any protocol it chooses. The value returned
+ * from this function need not be a member of the list of supported protocols
+ * provided by the callback.
+ */
+void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, unsigned *len)
+	{
+	*data = s->next_proto_negotiated;
+	if (!*data) {
+		*len = 0;
+	} else {
+		*len = s->next_proto_negotiated_len;
+	}
+}
+
+/* SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when a
+ * TLS server needs a list of supported protocols for Next Protocol
+ * Negotiation. The returned list must be in wire format.  The list is returned
+ * by setting |out| to point to it and |outlen| to its length. This memory will
+ * not be modified, but one should assume that the SSL* keeps a reference to
+ * it.
+ *
+ * The callback should return SSL_TLSEXT_ERR_OK if it wishes to advertise. Otherwise, no
+ * such extension will be included in the ServerHello. */
+void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *ctx, int (*cb) (SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg), void *arg)
+	{
+	ctx->next_protos_advertised_cb = cb;
+	ctx->next_protos_advertised_cb_arg = arg;
+	}
+
+/* SSL_CTX_set_next_proto_select_cb sets a callback that is called when a
+ * client needs to select a protocol from the server's provided list. |out|
+ * must be set to point to the selected protocol (which may be within |in|).
+ * The length of the protocol name must be written into |outlen|. The server's
+ * advertised protocols are provided in |in| and |inlen|. The callback can
+ * assume that |in| is syntactically valid.
+ *
+ * The client must select a protocol. It is fatal to the connection if this
+ * callback returns a value other than SSL_TLSEXT_ERR_OK.
+ */
+void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg), void *arg)
+	{
+	ctx->next_proto_select_cb = cb;
+	ctx->next_proto_select_cb_arg = arg;
+	}
+
+# endif
+#endif
+
+static unsigned long ssl_session_hash(const SSL_SESSION *a)
+	{
+	unsigned long l;
+
+	l=(unsigned long)
+		((unsigned int) a->session_id[0]     )|
+		((unsigned int) a->session_id[1]<< 8L)|
+		((unsigned long)a->session_id[2]<<16L)|
+		((unsigned long)a->session_id[3]<<24L);
+	return(l);
+	}
+
+/* NB: If this function (or indeed the hash function which uses a sort of
+ * coarser function than this one) is changed, ensure
+ * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being
+ * able to construct an SSL_SESSION that will collide with any existing session
+ * with a matching session ID. */
+static int ssl_session_cmp(const SSL_SESSION *a,const SSL_SESSION *b)
+	{
+	if (a->ssl_version != b->ssl_version)
+		return(1);
+	if (a->session_id_length != b->session_id_length)
+		return(1);
+	return(memcmp(a->session_id,b->session_id,a->session_id_length));
+	}
+
+/* These wrapper functions should remain rather than redeclaring
+ * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each
+ * variable. The reason is that the functions aren't static, they're exposed via
+ * ssl.h. */
+static IMPLEMENT_LHASH_HASH_FN(ssl_session, SSL_SESSION)
+static IMPLEMENT_LHASH_COMP_FN(ssl_session, SSL_SESSION)
+
+SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
+	{
+	SSL_CTX *ret=NULL;
+
+	if (meth == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_NULL_SSL_METHOD_PASSED);
+		return(NULL);
+		}
+
+	if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0)
+		{
+		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
+		goto err;
+		}
+	ret=(SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
+	if (ret == NULL)
+		goto err;
+
+	memset(ret,0,sizeof(SSL_CTX));
+
+	ret->method=meth;
+
+	ret->cert_store=NULL;
+	ret->session_cache_mode=SSL_SESS_CACHE_SERVER;
+	ret->session_cache_size=SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
+	ret->session_cache_head=NULL;
+	ret->session_cache_tail=NULL;
+
+	/* We take the system default */
+	ret->session_timeout=meth->get_timeout();
+
+	ret->new_session_cb=0;
+	ret->remove_session_cb=0;
+	ret->get_session_cb=0;
+	ret->generate_session_id=0;
+
+	memset((char *)&ret->stats,0,sizeof(ret->stats));
+
+	ret->references=1;
+	ret->quiet_shutdown=0;
+
+/*	ret->cipher=NULL;*/
+/*	ret->s2->challenge=NULL;
+	ret->master_key=NULL;
+	ret->key_arg=NULL;
+	ret->s2->conn_id=NULL; */
+
+	ret->info_callback=NULL;
+
+	ret->app_verify_callback=0;
+	ret->app_verify_arg=NULL;
+
+	ret->max_cert_list=SSL_MAX_CERT_LIST_DEFAULT;
+	ret->read_ahead=0;
+	ret->msg_callback=0;
+	ret->msg_callback_arg=NULL;
+	ret->verify_mode=SSL_VERIFY_NONE;
+#if 0
+	ret->verify_depth=-1; /* Don't impose a limit (but x509_lu.c does) */
+#endif
+	ret->sid_ctx_length=0;
+	ret->default_verify_callback=NULL;
+	if ((ret->cert=ssl_cert_new()) == NULL)
+		goto err;
+
+	ret->default_passwd_callback=0;
+	ret->default_passwd_callback_userdata=NULL;
+	ret->client_cert_cb=0;
+	ret->app_gen_cookie_cb=0;
+	ret->app_verify_cookie_cb=0;
+
+	ret->sessions=lh_SSL_SESSION_new();
+	if (ret->sessions == NULL) goto err;
+	ret->cert_store=X509_STORE_new();
+	if (ret->cert_store == NULL) goto err;
+
+	ssl_create_cipher_list(ret->method,
+		&ret->cipher_list,&ret->cipher_list_by_id,
+		meth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST);
+	if (ret->cipher_list == NULL
+	    || sk_SSL_CIPHER_num(ret->cipher_list) <= 0)
+		{
+		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_LIBRARY_HAS_NO_CIPHERS);
+		goto err2;
+		}
+
+	ret->param = X509_VERIFY_PARAM_new();
+	if (!ret->param)
+		goto err;
+
+	if ((ret->rsa_md5=EVP_get_digestbyname("ssl2-md5")) == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES);
+		goto err2;
+		}
+	if ((ret->md5=EVP_get_digestbyname("ssl3-md5")) == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES);
+		goto err2;
+		}
+	if ((ret->sha1=EVP_get_digestbyname("ssl3-sha1")) == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES);
+		goto err2;
+		}
+
+	if ((ret->client_CA=sk_X509_NAME_new_null()) == NULL)
+		goto err;
+
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data);
+
+	ret->extra_certs=NULL;
+	ret->comp_methods=SSL_COMP_get_compression_methods();
+
+	ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
+
+#ifndef OPENSSL_NO_TLSEXT
+	ret->tlsext_servername_callback = 0;
+	ret->tlsext_servername_arg = NULL;
+	/* Setup RFC4507 ticket keys */
+	if ((RAND_pseudo_bytes(ret->tlsext_tick_key_name, 16) <= 0)
+		|| (RAND_bytes(ret->tlsext_tick_hmac_key, 16) <= 0)
+		|| (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0))
+		ret->options |= SSL_OP_NO_TICKET;
+
+	ret->tlsext_status_cb = 0;
+	ret->tlsext_status_arg = NULL;
+
+# ifndef OPENSSL_NO_NEXTPROTONEG
+	ret->next_protos_advertised_cb = 0;
+	ret->next_proto_select_cb = 0;
+# endif
+#endif
+#ifndef OPENSSL_NO_PSK
+	ret->psk_identity_hint=NULL;
+	ret->psk_client_callback=NULL;
+	ret->psk_server_callback=NULL;
+#endif
+#ifndef OPENSSL_NO_BUF_FREELISTS
+	ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT;
+	ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
+	if (!ret->rbuf_freelist)
+		goto err;
+	ret->rbuf_freelist->chunklen = 0;
+	ret->rbuf_freelist->len = 0;
+	ret->rbuf_freelist->head = NULL;
+	ret->wbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
+	if (!ret->wbuf_freelist)
+		{
+		OPENSSL_free(ret->rbuf_freelist);
+		goto err;
+		}
+	ret->wbuf_freelist->chunklen = 0;
+	ret->wbuf_freelist->len = 0;
+	ret->wbuf_freelist->head = NULL;
+#endif
+#ifndef OPENSSL_NO_ENGINE
+	ret->client_cert_engine = NULL;
+#ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO
+#define eng_strx(x)	#x
+#define eng_str(x)	eng_strx(x)
+	/* Use specific client engine automatically... ignore errors */
+	{
+	ENGINE *eng;
+	eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO));
+	if (!eng)
+		{
+		ERR_clear_error();
+		ENGINE_load_builtin_engines();
+		eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO));
+		}
+	if (!eng || !SSL_CTX_set_client_cert_engine(ret, eng))
+		ERR_clear_error();
+	}
+#endif
+#endif
+	/* Default is to connect to non-RI servers. When RI is more widely
+	 * deployed might change this.
+	 */
+	ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;
+
+	return(ret);
+err:
+	SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE);
+err2:
+	if (ret != NULL) SSL_CTX_free(ret);
+	return(NULL);
+	}
+
+#if 0
+static void SSL_COMP_free(SSL_COMP *comp)
+    { OPENSSL_free(comp); }
+#endif
+
+#ifndef OPENSSL_NO_BUF_FREELISTS
+static void
+ssl_buf_freelist_free(SSL3_BUF_FREELIST *list)
+	{
+	SSL3_BUF_FREELIST_ENTRY *ent, *next;
+	for (ent = list->head; ent; ent = next)
+		{
+		next = ent->next;
+		OPENSSL_free(ent);
+		}
+	OPENSSL_free(list);
+	}
+#endif
+
+void SSL_CTX_free(SSL_CTX *a)
+	{
+	int i;
+
+	if (a == NULL) return;
+
+	i=CRYPTO_add(&a->references,-1,CRYPTO_LOCK_SSL_CTX);
+#ifdef REF_PRINT
+	REF_PRINT("SSL_CTX",a);
+#endif
+	if (i > 0) return;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"SSL_CTX_free, bad reference count\n");
+		abort(); /* ok */
+		}
+#endif
+
+	if (a->param)
+		X509_VERIFY_PARAM_free(a->param);
+
+	/*
+	 * Free internal session cache. However: the remove_cb() may reference
+	 * the ex_data of SSL_CTX, thus the ex_data store can only be removed
+	 * after the sessions were flushed.
+	 * As the ex_data handling routines might also touch the session cache,
+	 * the most secure solution seems to be: empty (flush) the cache, then
+	 * free ex_data, then finally free the cache.
+	 * (See ticket [openssl.org #212].)
+	 */
+	if (a->sessions != NULL)
+		SSL_CTX_flush_sessions(a,0);
+
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data);
+
+	if (a->sessions != NULL)
+		lh_SSL_SESSION_free(a->sessions);
+
+	if (a->cert_store != NULL)
+		X509_STORE_free(a->cert_store);
+	if (a->cipher_list != NULL)
+		sk_SSL_CIPHER_free(a->cipher_list);
+	if (a->cipher_list_by_id != NULL)
+		sk_SSL_CIPHER_free(a->cipher_list_by_id);
+	if (a->cert != NULL)
+		ssl_cert_free(a->cert);
+	if (a->client_CA != NULL)
+		sk_X509_NAME_pop_free(a->client_CA,X509_NAME_free);
+	if (a->extra_certs != NULL)
+		sk_X509_pop_free(a->extra_certs,X509_free);
+#if 0 /* This should never be done, since it removes a global database */
+	if (a->comp_methods != NULL)
+		sk_SSL_COMP_pop_free(a->comp_methods,SSL_COMP_free);
+#else
+	a->comp_methods = NULL;
+#endif
+
+#ifndef OPENSSL_NO_PSK
+	if (a->psk_identity_hint)
+		OPENSSL_free(a->psk_identity_hint);
+#endif
+#ifndef OPENSSL_NO_ENGINE
+	if (a->client_cert_engine)
+		ENGINE_finish(a->client_cert_engine);
+#endif
+
+#ifndef OPENSSL_NO_BUF_FREELISTS
+	if (a->wbuf_freelist)
+		ssl_buf_freelist_free(a->wbuf_freelist);
+	if (a->rbuf_freelist)
+		ssl_buf_freelist_free(a->rbuf_freelist);
+#endif
+
+	OPENSSL_free(a);
+	}
+
+void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb)
+	{
+	ctx->default_passwd_callback=cb;
+	}
+
+void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx,void *u)
+	{
+	ctx->default_passwd_callback_userdata=u;
+	}
+
+void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *,void *), void *arg)
+	{
+	ctx->app_verify_callback=cb;
+	ctx->app_verify_arg=arg;
+	}
+
+void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,int (*cb)(int, X509_STORE_CTX *))
+	{
+	ctx->verify_mode=mode;
+	ctx->default_verify_callback=cb;
+	}
+
+void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth)
+	{
+	X509_VERIFY_PARAM_set_depth(ctx->param, depth);
+	}
+
+void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
+	{
+	CERT_PKEY *cpk;
+	int rsa_enc,rsa_tmp,rsa_sign,dh_tmp,dh_rsa,dh_dsa,dsa_sign;
+	int rsa_enc_export,dh_rsa_export,dh_dsa_export;
+	int rsa_tmp_export,dh_tmp_export,kl;
+	unsigned long mask_k,mask_a,emask_k,emask_a;
+	int have_ecc_cert, ecdh_ok, ecdsa_ok, ecc_pkey_size;
+#ifndef OPENSSL_NO_ECDH
+	int have_ecdh_tmp;
+#endif
+	X509 *x = NULL;
+	EVP_PKEY *ecc_pkey = NULL;
+	int signature_nid = 0, pk_nid = 0, md_nid = 0;
+
+	if (c == NULL) return;
+
+	kl=SSL_C_EXPORT_PKEYLENGTH(cipher);
+
+#ifndef OPENSSL_NO_RSA
+	rsa_tmp=(c->rsa_tmp != NULL || c->rsa_tmp_cb != NULL);
+	rsa_tmp_export=(c->rsa_tmp_cb != NULL ||
+		(rsa_tmp && RSA_size(c->rsa_tmp)*8 <= kl));
+#else
+	rsa_tmp=rsa_tmp_export=0;
+#endif
+#ifndef OPENSSL_NO_DH
+	dh_tmp=(c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
+	dh_tmp_export=(c->dh_tmp_cb != NULL ||
+		(dh_tmp && DH_size(c->dh_tmp)*8 <= kl));
+#else
+	dh_tmp=dh_tmp_export=0;
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+	have_ecdh_tmp=(c->ecdh_tmp != NULL || c->ecdh_tmp_cb != NULL);
+#endif
+	cpk= &(c->pkeys[SSL_PKEY_RSA_ENC]);
+	rsa_enc= (cpk->x509 != NULL && cpk->privatekey != NULL);
+	rsa_enc_export=(rsa_enc && EVP_PKEY_size(cpk->privatekey)*8 <= kl);
+	cpk= &(c->pkeys[SSL_PKEY_RSA_SIGN]);
+	rsa_sign=(cpk->x509 != NULL && cpk->privatekey != NULL);
+	cpk= &(c->pkeys[SSL_PKEY_DSA_SIGN]);
+	dsa_sign=(cpk->x509 != NULL && cpk->privatekey != NULL);
+	cpk= &(c->pkeys[SSL_PKEY_DH_RSA]);
+	dh_rsa=  (cpk->x509 != NULL && cpk->privatekey != NULL);
+	dh_rsa_export=(dh_rsa && EVP_PKEY_size(cpk->privatekey)*8 <= kl);
+	cpk= &(c->pkeys[SSL_PKEY_DH_DSA]);
+/* FIX THIS EAY EAY EAY */
+	dh_dsa=  (cpk->x509 != NULL && cpk->privatekey != NULL);
+	dh_dsa_export=(dh_dsa && EVP_PKEY_size(cpk->privatekey)*8 <= kl);
+	cpk= &(c->pkeys[SSL_PKEY_ECC]);
+	have_ecc_cert= (cpk->x509 != NULL && cpk->privatekey != NULL);
+	mask_k=0;
+	mask_a=0;
+	emask_k=0;
+	emask_a=0;
+
+	
+
+#ifdef CIPHER_DEBUG
+	printf("rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n",
+	        rsa_tmp,rsa_tmp_export,dh_tmp,have_ecdh_tmp,
+		rsa_enc,rsa_enc_export,rsa_sign,dsa_sign,dh_rsa,dh_dsa);
+#endif
+	
+	cpk = &(c->pkeys[SSL_PKEY_GOST01]);
+	if (cpk->x509 != NULL && cpk->privatekey !=NULL) {
+		mask_k |= SSL_kGOST;
+		mask_a |= SSL_aGOST01;
+	}
+	cpk = &(c->pkeys[SSL_PKEY_GOST94]);
+	if (cpk->x509 != NULL && cpk->privatekey !=NULL) {
+		mask_k |= SSL_kGOST;
+		mask_a |= SSL_aGOST94;
+	}
+
+	if (rsa_enc || (rsa_tmp && rsa_sign))
+		mask_k|=SSL_kRSA;
+	if (rsa_enc_export || (rsa_tmp_export && (rsa_sign || rsa_enc)))
+		emask_k|=SSL_kRSA;
+
+#if 0
+	/* The match needs to be both kEDH and aRSA or aDSA, so don't worry */
+	if (	(dh_tmp || dh_rsa || dh_dsa) &&
+		(rsa_enc || rsa_sign || dsa_sign))
+		mask_k|=SSL_kEDH;
+	if ((dh_tmp_export || dh_rsa_export || dh_dsa_export) &&
+		(rsa_enc || rsa_sign || dsa_sign))
+		emask_k|=SSL_kEDH;
+#endif
+
+	if (dh_tmp_export)
+		emask_k|=SSL_kEDH;
+
+	if (dh_tmp)
+		mask_k|=SSL_kEDH;
+
+	if (dh_rsa) mask_k|=SSL_kDHr;
+	if (dh_rsa_export) emask_k|=SSL_kDHr;
+
+	if (dh_dsa) mask_k|=SSL_kDHd;
+	if (dh_dsa_export) emask_k|=SSL_kDHd;
+
+	if (rsa_enc || rsa_sign)
+		{
+		mask_a|=SSL_aRSA;
+		emask_a|=SSL_aRSA;
+		}
+
+	if (dsa_sign)
+		{
+		mask_a|=SSL_aDSS;
+		emask_a|=SSL_aDSS;
+		}
+
+	mask_a|=SSL_aNULL;
+	emask_a|=SSL_aNULL;
+
+#ifndef OPENSSL_NO_KRB5
+	mask_k|=SSL_kKRB5;
+	mask_a|=SSL_aKRB5;
+	emask_k|=SSL_kKRB5;
+	emask_a|=SSL_aKRB5;
+#endif
+
+	/* An ECC certificate may be usable for ECDH and/or
+	 * ECDSA cipher suites depending on the key usage extension.
+	 */
+	if (have_ecc_cert)
+		{
+		/* This call populates extension flags (ex_flags) */
+		x = (c->pkeys[SSL_PKEY_ECC]).x509;
+		X509_check_purpose(x, -1, 0);
+		ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ?
+		    (x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1;
+		ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ?
+		    (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1;
+		ecc_pkey = X509_get_pubkey(x);
+		ecc_pkey_size = (ecc_pkey != NULL) ?
+		    EVP_PKEY_bits(ecc_pkey) : 0;
+		EVP_PKEY_free(ecc_pkey);
+		if ((x->sig_alg) && (x->sig_alg->algorithm))
+			{
+			signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
+			OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid);
+			}
+#ifndef OPENSSL_NO_ECDH
+		if (ecdh_ok)
+			{
+
+			if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa)
+				{
+				mask_k|=SSL_kECDHr;
+				mask_a|=SSL_aECDH;
+				if (ecc_pkey_size <= 163)
+					{
+					emask_k|=SSL_kECDHr;
+					emask_a|=SSL_aECDH;
+					}
+				}
+
+			if (pk_nid == NID_X9_62_id_ecPublicKey)
+				{
+				mask_k|=SSL_kECDHe;
+				mask_a|=SSL_aECDH;
+				if (ecc_pkey_size <= 163)
+					{
+					emask_k|=SSL_kECDHe;
+					emask_a|=SSL_aECDH;
+					}
+				}
+			}
+#endif
+#ifndef OPENSSL_NO_ECDSA
+		if (ecdsa_ok)
+			{
+			mask_a|=SSL_aECDSA;
+			emask_a|=SSL_aECDSA;
+			}
+#endif
+		}
+
+#ifndef OPENSSL_NO_ECDH
+	if (have_ecdh_tmp)
+		{
+		mask_k|=SSL_kEECDH;
+		emask_k|=SSL_kEECDH;
+		}
+#endif
+
+#ifndef OPENSSL_NO_PSK
+	mask_k |= SSL_kPSK;
+	mask_a |= SSL_aPSK;
+	emask_k |= SSL_kPSK;
+	emask_a |= SSL_aPSK;
+#endif
+
+	c->mask_k=mask_k;
+	c->mask_a=mask_a;
+	c->export_mask_k=emask_k;
+	c->export_mask_a=emask_a;
+	c->valid=1;
+	}
+
+/* This handy macro borrowed from crypto/x509v3/v3_purp.c */
+#define ku_reject(x, usage) \
+	(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
+
+#ifndef OPENSSL_NO_EC
+
+int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs)
+	{
+	unsigned long alg_k, alg_a;
+	EVP_PKEY *pkey = NULL;
+	int keysize = 0;
+	int signature_nid = 0, md_nid = 0, pk_nid = 0;
+
+	alg_k = cs->algorithm_mkey;
+	alg_a = cs->algorithm_auth;
+
+	if (SSL_C_IS_EXPORT(cs))
+		{
+		/* ECDH key length in export ciphers must be <= 163 bits */
+		pkey = X509_get_pubkey(x);
+		if (pkey == NULL) return 0;
+		keysize = EVP_PKEY_bits(pkey);
+		EVP_PKEY_free(pkey);
+		if (keysize > 163) return 0;
+		}
+
+	/* This call populates the ex_flags field correctly */
+	X509_check_purpose(x, -1, 0);
+	if ((x->sig_alg) && (x->sig_alg->algorithm))
+		{
+		signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
+		OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid);
+		}
+	if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr)
+		{
+		/* key usage, if present, must allow key agreement */
+		if (ku_reject(x, X509v3_KU_KEY_AGREEMENT))
+			{
+			SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT);
+			return 0;
+			}
+		if (alg_k & SSL_kECDHe)
+			{
+			/* signature alg must be ECDSA */
+			if (pk_nid != NID_X9_62_id_ecPublicKey)
+				{
+				SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE);
+				return 0;
+				}
+			}
+		if (alg_k & SSL_kECDHr)
+			{
+			/* signature alg must be RSA */
+
+			if (pk_nid != NID_rsaEncryption && pk_nid != NID_rsa)
+				{
+				SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE);
+				return 0;
+				}
+			}
+		}
+	if (alg_a & SSL_aECDSA)
+		{
+		/* key usage, if present, must allow signing */
+		if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE))
+			{
+			SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_NOT_FOR_SIGNING);
+			return 0;
+			}
+		}
+
+	return 1;  /* all checks are ok */
+	}
+
+#endif
+
+/* THIS NEEDS CLEANING UP */
+X509 *ssl_get_server_send_cert(SSL *s)
+	{
+	unsigned long alg_k,alg_a;
+	CERT *c;
+	int i;
+
+	c=s->cert;
+	ssl_set_cert_masks(c, s->s3->tmp.new_cipher);
+	
+	alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+	alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+
+	if (alg_k & (SSL_kECDHr|SSL_kECDHe))
+		{
+		/* we don't need to look at SSL_kEECDH
+		 * since no certificate is needed for
+		 * anon ECDH and for authenticated
+		 * EECDH, the check for the auth
+		 * algorithm will set i correctly
+		 * NOTE: For ECDH-RSA, we need an ECC
+		 * not an RSA cert but for EECDH-RSA
+		 * we need an RSA cert. Placing the
+		 * checks for SSL_kECDH before RSA
+		 * checks ensures the correct cert is chosen.
+		 */
+		i=SSL_PKEY_ECC;
+		}
+	else if (alg_a & SSL_aECDSA)
+		{
+		i=SSL_PKEY_ECC;
+		}
+	else if (alg_k & SSL_kDHr)
+		i=SSL_PKEY_DH_RSA;
+	else if (alg_k & SSL_kDHd)
+		i=SSL_PKEY_DH_DSA;
+	else if (alg_a & SSL_aDSS)
+		i=SSL_PKEY_DSA_SIGN;
+	else if (alg_a & SSL_aRSA)
+		{
+		if (c->pkeys[SSL_PKEY_RSA_ENC].x509 == NULL)
+			i=SSL_PKEY_RSA_SIGN;
+		else
+			i=SSL_PKEY_RSA_ENC;
+		}
+	else if (alg_a & SSL_aKRB5)
+		{
+		/* VRS something else here? */
+		return(NULL);
+		}
+	else if (alg_a & SSL_aGOST94) 
+		i=SSL_PKEY_GOST94;
+	else if (alg_a & SSL_aGOST01)
+		i=SSL_PKEY_GOST01;
+	else /* if (alg_a & SSL_aNULL) */
+		{
+		SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,ERR_R_INTERNAL_ERROR);
+		return(NULL);
+		}
+	if (c->pkeys[i].x509 == NULL) return(NULL);
+
+	return(c->pkeys[i].x509);
+	}
+
+EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher)
+	{
+	unsigned long alg_a;
+	CERT *c;
+
+	alg_a = cipher->algorithm_auth;
+	c=s->cert;
+
+	if ((alg_a & SSL_aDSS) &&
+		(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL))
+		return(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey);
+	else if (alg_a & SSL_aRSA)
+		{
+		if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL)
+			return(c->pkeys[SSL_PKEY_RSA_SIGN].privatekey);
+		else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL)
+			return(c->pkeys[SSL_PKEY_RSA_ENC].privatekey);
+		else
+			return(NULL);
+		}
+	else if ((alg_a & SSL_aECDSA) &&
+	         (c->pkeys[SSL_PKEY_ECC].privatekey != NULL))
+		return(c->pkeys[SSL_PKEY_ECC].privatekey);
+	else /* if (alg_a & SSL_aNULL) */
+		{
+		SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR);
+		return(NULL);
+		}
+	}
+
+void ssl_update_cache(SSL *s,int mode)
+	{
+	int i;
+
+	/* If the session_id_length is 0, we are not supposed to cache it,
+	 * and it would be rather hard to do anyway :-) */
+	if (s->session->session_id_length == 0) return;
+
+	i=s->session_ctx->session_cache_mode;
+	if ((i & mode) && (!s->hit)
+		&& ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE)
+		    || SSL_CTX_add_session(s->session_ctx,s->session))
+		&& (s->session_ctx->new_session_cb != NULL))
+		{
+		CRYPTO_add(&s->session->references,1,CRYPTO_LOCK_SSL_SESSION);
+		if (!s->session_ctx->new_session_cb(s,s->session))
+			SSL_SESSION_free(s->session);
+		}
+
+	/* auto flush every 255 connections */
+	if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) &&
+		((i & mode) == mode))
+		{
+		if (  (((mode & SSL_SESS_CACHE_CLIENT)
+			?s->session_ctx->stats.sess_connect_good
+			:s->session_ctx->stats.sess_accept_good) & 0xff) == 0xff)
+			{
+			SSL_CTX_flush_sessions(s->session_ctx,(unsigned long)time(NULL));
+			}
+		}
+	}
+
+const SSL_METHOD *SSL_get_ssl_method(SSL *s)
+	{
+	return(s->method);
+	}
+
+int SSL_set_ssl_method(SSL *s, const SSL_METHOD *meth)
+	{
+	int conn= -1;
+	int ret=1;
+
+	if (s->method != meth)
+		{
+		if (s->handshake_func != NULL)
+			conn=(s->handshake_func == s->method->ssl_connect);
+
+		if (s->method->version == meth->version)
+			s->method=meth;
+		else
+			{
+			s->method->ssl_free(s);
+			s->method=meth;
+			ret=s->method->ssl_new(s);
+			}
+
+		if (conn == 1)
+			s->handshake_func=meth->ssl_connect;
+		else if (conn == 0)
+			s->handshake_func=meth->ssl_accept;
+		}
+	return(ret);
+	}
+
+int SSL_get_error(const SSL *s,int i)
+	{
+	int reason;
+	unsigned long l;
+	BIO *bio;
+
+	if (i > 0) return(SSL_ERROR_NONE);
+
+	/* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake
+	 * etc, where we do encode the error */
+	if ((l=ERR_peek_error()) != 0)
+		{
+		if (ERR_GET_LIB(l) == ERR_LIB_SYS)
+			return(SSL_ERROR_SYSCALL);
+		else
+			return(SSL_ERROR_SSL);
+		}
+
+	if ((i < 0) && SSL_want_read(s))
+		{
+		bio=SSL_get_rbio(s);
+		if (BIO_should_read(bio))
+			return(SSL_ERROR_WANT_READ);
+		else if (BIO_should_write(bio))
+			/* This one doesn't make too much sense ... We never try
+			 * to write to the rbio, and an application program where
+			 * rbio and wbio are separate couldn't even know what it
+			 * should wait for.
+			 * However if we ever set s->rwstate incorrectly
+			 * (so that we have SSL_want_read(s) instead of
+			 * SSL_want_write(s)) and rbio and wbio *are* the same,
+			 * this test works around that bug; so it might be safer
+			 * to keep it. */
+			return(SSL_ERROR_WANT_WRITE);
+		else if (BIO_should_io_special(bio))
+			{
+			reason=BIO_get_retry_reason(bio);
+			if (reason == BIO_RR_CONNECT)
+				return(SSL_ERROR_WANT_CONNECT);
+			else if (reason == BIO_RR_ACCEPT)
+				return(SSL_ERROR_WANT_ACCEPT);
+			else
+				return(SSL_ERROR_SYSCALL); /* unknown */
+			}
+		}
+
+	if ((i < 0) && SSL_want_write(s))
+		{
+		bio=SSL_get_wbio(s);
+		if (BIO_should_write(bio))
+			return(SSL_ERROR_WANT_WRITE);
+		else if (BIO_should_read(bio))
+			/* See above (SSL_want_read(s) with BIO_should_write(bio)) */
+			return(SSL_ERROR_WANT_READ);
+		else if (BIO_should_io_special(bio))
+			{
+			reason=BIO_get_retry_reason(bio);
+			if (reason == BIO_RR_CONNECT)
+				return(SSL_ERROR_WANT_CONNECT);
+			else if (reason == BIO_RR_ACCEPT)
+				return(SSL_ERROR_WANT_ACCEPT);
+			else
+				return(SSL_ERROR_SYSCALL);
+			}
+		}
+	if ((i < 0) && SSL_want_x509_lookup(s))
+		{
+		return(SSL_ERROR_WANT_X509_LOOKUP);
+		}
+
+	if (i == 0)
+		{
+		if (s->version == SSL2_VERSION)
+			{
+			/* assume it is the socket being closed */
+			return(SSL_ERROR_ZERO_RETURN);
+			}
+		else
+			{
+			if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) &&
+				(s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY))
+				return(SSL_ERROR_ZERO_RETURN);
+			}
+		}
+	return(SSL_ERROR_SYSCALL);
+	}
+
+int SSL_do_handshake(SSL *s)
+	{
+	int ret=1;
+
+	if (s->handshake_func == NULL)
+		{
+		SSLerr(SSL_F_SSL_DO_HANDSHAKE,SSL_R_CONNECTION_TYPE_NOT_SET);
+		return(-1);
+		}
+
+	s->method->ssl_renegotiate_check(s);
+
+	if (SSL_in_init(s) || SSL_in_before(s))
+		{
+		ret=s->handshake_func(s);
+		}
+	return(ret);
+	}
+
+/* For the next 2 functions, SSL_clear() sets shutdown and so
+ * one of these calls will reset it */
+void SSL_set_accept_state(SSL *s)
+	{
+	s->server=1;
+	s->shutdown=0;
+	s->state=SSL_ST_ACCEPT|SSL_ST_BEFORE;
+	s->handshake_func=s->method->ssl_accept;
+	/* clear the current cipher */
+	ssl_clear_cipher_ctx(s);
+	ssl_clear_hash_ctx(&s->read_hash);
+	ssl_clear_hash_ctx(&s->write_hash);
+	}
+
+void SSL_set_connect_state(SSL *s)
+	{
+	s->server=0;
+	s->shutdown=0;
+	s->state=SSL_ST_CONNECT|SSL_ST_BEFORE;
+	s->handshake_func=s->method->ssl_connect;
+	/* clear the current cipher */
+	ssl_clear_cipher_ctx(s);
+	ssl_clear_hash_ctx(&s->read_hash);
+	ssl_clear_hash_ctx(&s->write_hash);
+	}
+
+int ssl_undefined_function(SSL *s)
+	{
+	SSLerr(SSL_F_SSL_UNDEFINED_FUNCTION,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+	return(0);
+	}
+
+int ssl_undefined_void_function(void)
+	{
+	SSLerr(SSL_F_SSL_UNDEFINED_VOID_FUNCTION,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+	return(0);
+	}
+
+int ssl_undefined_const_function(const SSL *s)
+	{
+	SSLerr(SSL_F_SSL_UNDEFINED_CONST_FUNCTION,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+	return(0);
+	}
+
+SSL_METHOD *ssl_bad_method(int ver)
+	{
+	SSLerr(SSL_F_SSL_BAD_METHOD,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+	return(NULL);
+	}
+
+static const char *ssl_get_version(int version)
+	{
+	if (version == TLS1_VERSION)
+		return("TLSv1");
+	else if (version == SSL3_VERSION)
+		return("SSLv3");
+	else if (version == SSL2_VERSION)
+		return("SSLv2");
+	else
+		return("unknown");
+	}
+
+const char *SSL_get_version(const SSL *s)
+	{
+		return ssl_get_version(s->version);
+	}
+
+const char *SSL_SESSION_get_version(const SSL_SESSION *s)
+	{
+		return ssl_get_version(s->ssl_version);
+	}
+
+const char* SSL_authentication_method(const SSL* ssl)
+	{
+	if (ssl->cert != NULL && ssl->cert->rsa_tmp != NULL)
+		return SSL_TXT_RSA "_" SSL_TXT_EXPORT;
+	switch (ssl->version)
+		{
+	case SSL2_VERSION:
+		return SSL_TXT_RSA;
+	case SSL3_VERSION:
+	case TLS1_VERSION:
+	case DTLS1_VERSION:
+		return SSL_CIPHER_authentication_method(ssl->s3->tmp.new_cipher);
+	default:
+		return "UNKNOWN";
+		}
+	}
+
+SSL *SSL_dup(SSL *s)
+	{
+	STACK_OF(X509_NAME) *sk;
+	X509_NAME *xn;
+	SSL *ret;
+	int i;
+	
+	if ((ret=SSL_new(SSL_get_SSL_CTX(s))) == NULL)
+	    return(NULL);
+
+	ret->version = s->version;
+	ret->type = s->type;
+	ret->method = s->method;
+
+	if (s->session != NULL)
+		{
+		/* This copies session-id, SSL_METHOD, sid_ctx, and 'cert' */
+		SSL_copy_session_id(ret,s);
+		}
+	else
+		{
+		/* No session has been established yet, so we have to expect
+		 * that s->cert or ret->cert will be changed later --
+		 * they should not both point to the same object,
+		 * and thus we can't use SSL_copy_session_id. */
+
+		ret->method->ssl_free(ret);
+		ret->method = s->method;
+		ret->method->ssl_new(ret);
+
+		if (s->cert != NULL)
+			{
+			if (ret->cert != NULL)
+				{
+				ssl_cert_free(ret->cert);
+				}
+			ret->cert = ssl_cert_dup(s->cert);
+			if (ret->cert == NULL)
+				goto err;
+			}
+				
+		SSL_set_session_id_context(ret,
+			s->sid_ctx, s->sid_ctx_length);
+		}
+
+	ret->options=s->options;
+	ret->mode=s->mode;
+	SSL_set_max_cert_list(ret,SSL_get_max_cert_list(s));
+	SSL_set_read_ahead(ret,SSL_get_read_ahead(s));
+	ret->msg_callback = s->msg_callback;
+	ret->msg_callback_arg = s->msg_callback_arg;
+	SSL_set_verify(ret,SSL_get_verify_mode(s),
+		SSL_get_verify_callback(s));
+	SSL_set_verify_depth(ret,SSL_get_verify_depth(s));
+	ret->generate_session_id = s->generate_session_id;
+
+	SSL_set_info_callback(ret,SSL_get_info_callback(s));
+	
+	ret->debug=s->debug;
+
+	/* copy app data, a little dangerous perhaps */
+	if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL, &ret->ex_data, &s->ex_data))
+		goto err;
+
+	/* setup rbio, and wbio */
+	if (s->rbio != NULL)
+		{
+		if (!BIO_dup_state(s->rbio,(char *)&ret->rbio))
+			goto err;
+		}
+	if (s->wbio != NULL)
+		{
+		if (s->wbio != s->rbio)
+			{
+			if (!BIO_dup_state(s->wbio,(char *)&ret->wbio))
+				goto err;
+			}
+		else
+			ret->wbio=ret->rbio;
+		}
+	ret->rwstate = s->rwstate;
+	ret->in_handshake = s->in_handshake;
+	ret->handshake_func = s->handshake_func;
+	ret->server = s->server;
+	ret->new_session = s->new_session;
+	ret->quiet_shutdown = s->quiet_shutdown;
+	ret->shutdown=s->shutdown;
+	ret->state=s->state; /* SSL_dup does not really work at any state, though */
+	ret->rstate=s->rstate;
+	ret->init_num = 0; /* would have to copy ret->init_buf, ret->init_msg, ret->init_num, ret->init_off */
+	ret->hit=s->hit;
+
+	X509_VERIFY_PARAM_inherit(ret->param, s->param);
+
+	/* dup the cipher_list and cipher_list_by_id stacks */
+	if (s->cipher_list != NULL)
+		{
+		if ((ret->cipher_list=sk_SSL_CIPHER_dup(s->cipher_list)) == NULL)
+			goto err;
+		}
+	if (s->cipher_list_by_id != NULL)
+		if ((ret->cipher_list_by_id=sk_SSL_CIPHER_dup(s->cipher_list_by_id))
+			== NULL)
+			goto err;
+
+	/* Dup the client_CA list */
+	if (s->client_CA != NULL)
+		{
+		if ((sk=sk_X509_NAME_dup(s->client_CA)) == NULL) goto err;
+		ret->client_CA=sk;
+		for (i=0; i<sk_X509_NAME_num(sk); i++)
+			{
+			xn=sk_X509_NAME_value(sk,i);
+			if (sk_X509_NAME_set(sk,i,X509_NAME_dup(xn)) == NULL)
+				{
+				X509_NAME_free(xn);
+				goto err;
+				}
+			}
+		}
+
+	if (0)
+		{
+err:
+		if (ret != NULL) SSL_free(ret);
+		ret=NULL;
+		}
+	return(ret);
+	}
+
+void ssl_clear_cipher_ctx(SSL *s)
+	{
+	if (s->enc_read_ctx != NULL)
+		{
+		EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
+		OPENSSL_free(s->enc_read_ctx);
+		s->enc_read_ctx=NULL;
+		}
+	if (s->enc_write_ctx != NULL)
+		{
+		EVP_CIPHER_CTX_cleanup(s->enc_write_ctx);
+		OPENSSL_free(s->enc_write_ctx);
+		s->enc_write_ctx=NULL;
+		}
+#ifndef OPENSSL_NO_COMP
+	if (s->expand != NULL)
+		{
+		COMP_CTX_free(s->expand);
+		s->expand=NULL;
+		}
+	if (s->compress != NULL)
+		{
+		COMP_CTX_free(s->compress);
+		s->compress=NULL;
+		}
+#endif
+	}
+
+/* Fix this function so that it takes an optional type parameter */
+X509 *SSL_get_certificate(const SSL *s)
+	{
+	if (s->cert != NULL)
+		return(s->cert->key->x509);
+	else
+		return(NULL);
+	}
+
+/* Fix this function so that it takes an optional type parameter */
+EVP_PKEY *SSL_get_privatekey(SSL *s)
+	{
+	if (s->cert != NULL)
+		return(s->cert->key->privatekey);
+	else
+		return(NULL);
+	}
+
+const SSL_CIPHER *SSL_get_current_cipher(const SSL *s)
+	{
+	if ((s->session != NULL) && (s->session->cipher != NULL))
+		return(s->session->cipher);
+	return(NULL);
+	}
+#ifdef OPENSSL_NO_COMP
+const void *SSL_get_current_compression(SSL *s)
+	{
+	return NULL;
+	}
+const void *SSL_get_current_expansion(SSL *s)
+	{
+	return NULL;
+	}
+#else
+
+const COMP_METHOD *SSL_get_current_compression(SSL *s)
+	{
+	if (s->compress != NULL)
+		return(s->compress->meth);
+	return(NULL);
+	}
+
+const COMP_METHOD *SSL_get_current_expansion(SSL *s)
+	{
+	if (s->expand != NULL)
+		return(s->expand->meth);
+	return(NULL);
+	}
+#endif
+
+int ssl_init_wbio_buffer(SSL *s,int push)
+	{
+	BIO *bbio;
+
+	if (s->bbio == NULL)
+		{
+		bbio=BIO_new(BIO_f_buffer());
+		if (bbio == NULL) return(0);
+		s->bbio=bbio;
+		}
+	else
+		{
+		bbio=s->bbio;
+		if (s->bbio == s->wbio)
+			s->wbio=BIO_pop(s->wbio);
+		}
+	(void)BIO_reset(bbio);
+/*	if (!BIO_set_write_buffer_size(bbio,16*1024)) */
+	if (!BIO_set_read_buffer_size(bbio,1))
+		{
+		SSLerr(SSL_F_SSL_INIT_WBIO_BUFFER,ERR_R_BUF_LIB);
+		return(0);
+		}
+	if (push)
+		{
+		if (s->wbio != bbio)
+			s->wbio=BIO_push(bbio,s->wbio);
+		}
+	else
+		{
+		if (s->wbio == bbio)
+			s->wbio=BIO_pop(bbio);
+		}
+	return(1);
+	}
+
+void ssl_free_wbio_buffer(SSL *s)
+	{
+	if (s->bbio == NULL) return;
+
+	if (s->bbio == s->wbio)
+		{
+		/* remove buffering */
+		s->wbio=BIO_pop(s->wbio);
+#ifdef REF_CHECK /* not the usual REF_CHECK, but this avoids adding one more preprocessor symbol */
+		assert(s->wbio != NULL);
+#endif
+	}
+	BIO_free(s->bbio);
+	s->bbio=NULL;
+	}
+	
+void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx,int mode)
+	{
+	ctx->quiet_shutdown=mode;
+	}
+
+int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx)
+	{
+	return(ctx->quiet_shutdown);
+	}
+
+void SSL_set_quiet_shutdown(SSL *s,int mode)
+	{
+	s->quiet_shutdown=mode;
+	}
+
+int SSL_get_quiet_shutdown(const SSL *s)
+	{
+	return(s->quiet_shutdown);
+	}
+
+void SSL_set_shutdown(SSL *s,int mode)
+	{
+	s->shutdown=mode;
+	}
+
+int SSL_get_shutdown(const SSL *s)
+	{
+	return(s->shutdown);
+	}
+
+int SSL_version(const SSL *s)
+	{
+	return(s->version);
+	}
+
+SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl)
+	{
+	return(ssl->ctx);
+	}
+
+SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx)
+	{
+	if (ssl->ctx == ctx)
+		return ssl->ctx;
+#ifndef OPENSSL_NO_TLSEXT
+	if (ctx == NULL)
+		ctx = ssl->initial_ctx;
+#endif
+	if (ssl->cert != NULL)
+		ssl_cert_free(ssl->cert);
+	ssl->cert = ssl_cert_dup(ctx->cert);
+	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
+	if (ssl->ctx != NULL)
+		SSL_CTX_free(ssl->ctx); /* decrement reference count */
+	ssl->ctx = ctx;
+	return(ssl->ctx);
+	}
+
+#ifndef OPENSSL_NO_STDIO
+int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
+	{
+	return(X509_STORE_set_default_paths(ctx->cert_store));
+	}
+
+int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
+		const char *CApath)
+	{
+	return(X509_STORE_load_locations(ctx->cert_store,CAfile,CApath));
+	}
+#endif
+
+void SSL_set_info_callback(SSL *ssl,
+	void (*cb)(const SSL *ssl,int type,int val))
+	{
+	ssl->info_callback=cb;
+	}
+
+/* One compiler (Diab DCC) doesn't like argument names in returned
+   function pointer.  */
+void (*SSL_get_info_callback(const SSL *ssl))(const SSL * /*ssl*/,int /*type*/,int /*val*/)
+	{
+	return ssl->info_callback;
+	}
+
+int SSL_state(const SSL *ssl)
+	{
+	return(ssl->state);
+	}
+
+void SSL_set_verify_result(SSL *ssl,long arg)
+	{
+	ssl->verify_result=arg;
+	}
+
+long SSL_get_verify_result(const SSL *ssl)
+	{
+	return(ssl->verify_result);
+	}
+
+int SSL_get_ex_new_index(long argl,void *argp,CRYPTO_EX_new *new_func,
+			 CRYPTO_EX_dup *dup_func,CRYPTO_EX_free *free_func)
+	{
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, argl, argp,
+				new_func, dup_func, free_func);
+	}
+
+int SSL_set_ex_data(SSL *s,int idx,void *arg)
+	{
+	return(CRYPTO_set_ex_data(&s->ex_data,idx,arg));
+	}
+
+void *SSL_get_ex_data(const SSL *s,int idx)
+	{
+	return(CRYPTO_get_ex_data(&s->ex_data,idx));
+	}
+
+int SSL_CTX_get_ex_new_index(long argl,void *argp,CRYPTO_EX_new *new_func,
+			     CRYPTO_EX_dup *dup_func,CRYPTO_EX_free *free_func)
+	{
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, argl, argp,
+				new_func, dup_func, free_func);
+	}
+
+int SSL_CTX_set_ex_data(SSL_CTX *s,int idx,void *arg)
+	{
+	return(CRYPTO_set_ex_data(&s->ex_data,idx,arg));
+	}
+
+void *SSL_CTX_get_ex_data(const SSL_CTX *s,int idx)
+	{
+	return(CRYPTO_get_ex_data(&s->ex_data,idx));
+	}
+
+int ssl_ok(SSL *s)
+	{
+	return(1);
+	}
+
+X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx)
+	{
+	return(ctx->cert_store);
+	}
+
+void SSL_CTX_set_cert_store(SSL_CTX *ctx,X509_STORE *store)
+	{
+	if (ctx->cert_store != NULL)
+		X509_STORE_free(ctx->cert_store);
+	ctx->cert_store=store;
+	}
+
+int SSL_want(const SSL *s)
+	{
+	return(s->rwstate);
+	}
+
+/*!
+ * \brief Set the callback for generating temporary RSA keys.
+ * \param ctx the SSL context.
+ * \param cb the callback
+ */
+
+#ifndef OPENSSL_NO_RSA
+void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,RSA *(*cb)(SSL *ssl,
+							  int is_export,
+							  int keylength))
+    {
+    SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TMP_RSA_CB,(void (*)(void))cb);
+    }
+
+void SSL_set_tmp_rsa_callback(SSL *ssl,RSA *(*cb)(SSL *ssl,
+						  int is_export,
+						  int keylength))
+    {
+    SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_RSA_CB,(void (*)(void))cb);
+    }
+#endif
+
+#ifdef DOXYGEN
+/*!
+ * \brief The RSA temporary key callback function.
+ * \param ssl the SSL session.
+ * \param is_export \c TRUE if the temp RSA key is for an export ciphersuite.
+ * \param keylength if \c is_export is \c TRUE, then \c keylength is the size
+ * of the required key in bits.
+ * \return the temporary RSA key.
+ * \sa SSL_CTX_set_tmp_rsa_callback, SSL_set_tmp_rsa_callback
+ */
+
+RSA *cb(SSL *ssl,int is_export,int keylength)
+    {}
+#endif
+
+/*!
+ * \brief Set the callback for generating temporary DH keys.
+ * \param ctx the SSL context.
+ * \param dh the callback
+ */
+
+#ifndef OPENSSL_NO_DH
+void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,DH *(*dh)(SSL *ssl,int is_export,
+                                                        int keylength))
+	{
+	SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TMP_DH_CB,(void (*)(void))dh);
+	}
+
+void SSL_set_tmp_dh_callback(SSL *ssl,DH *(*dh)(SSL *ssl,int is_export,
+                                                int keylength))
+	{
+	SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_DH_CB,(void (*)(void))dh);
+	}
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,EC_KEY *(*ecdh)(SSL *ssl,int is_export,
+                                                                int keylength))
+	{
+	SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH_CB,(void (*)(void))ecdh);
+	}
+
+void SSL_set_tmp_ecdh_callback(SSL *ssl,EC_KEY *(*ecdh)(SSL *ssl,int is_export,
+                                                        int keylength))
+	{
+	SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH_CB,(void (*)(void))ecdh);
+	}
+#endif
+
+#ifndef OPENSSL_NO_PSK
+int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint)
+	{
+	if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG);
+		return 0;
+		}
+	if (ctx->psk_identity_hint != NULL)
+		OPENSSL_free(ctx->psk_identity_hint);
+	if (identity_hint != NULL)
+		{
+		ctx->psk_identity_hint = BUF_strdup(identity_hint);
+		if (ctx->psk_identity_hint == NULL)
+			return 0;
+		}
+	else
+		ctx->psk_identity_hint = NULL;
+	return 1;
+	}
+
+int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint)
+	{
+	if (s == NULL)
+		return 0;
+
+	if (s->session == NULL)
+		return 1; /* session not created yet, ignored */
+
+	if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN)
+		{
+		SSLerr(SSL_F_SSL_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG);
+		return 0;
+		}
+	if (s->session->psk_identity_hint != NULL)
+		OPENSSL_free(s->session->psk_identity_hint);
+	if (identity_hint != NULL)
+		{
+		s->session->psk_identity_hint = BUF_strdup(identity_hint);
+		if (s->session->psk_identity_hint == NULL)
+			return 0;
+		}
+	else
+		s->session->psk_identity_hint = NULL;
+	return 1;
+	}
+
+const char *SSL_get_psk_identity_hint(const SSL *s)
+	{
+	if (s == NULL || s->session == NULL)
+		return NULL;
+	return(s->session->psk_identity_hint);
+	}
+
+const char *SSL_get_psk_identity(const SSL *s)
+	{
+	if (s == NULL || s->session == NULL)
+		return NULL;
+	return(s->session->psk_identity);
+	}
+
+void SSL_set_psk_client_callback(SSL *s,
+    unsigned int (*cb)(SSL *ssl, const char *hint,
+                       char *identity, unsigned int max_identity_len, unsigned char *psk,
+                       unsigned int max_psk_len))
+	{
+	s->psk_client_callback = cb;
+	}
+
+void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx,
+    unsigned int (*cb)(SSL *ssl, const char *hint,
+                       char *identity, unsigned int max_identity_len, unsigned char *psk,
+                       unsigned int max_psk_len))
+	{
+	ctx->psk_client_callback = cb;
+	}
+
+void SSL_set_psk_server_callback(SSL *s,
+    unsigned int (*cb)(SSL *ssl, const char *identity,
+                       unsigned char *psk, unsigned int max_psk_len))
+	{
+	s->psk_server_callback = cb;
+	}
+
+void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx,
+    unsigned int (*cb)(SSL *ssl, const char *identity,
+                       unsigned char *psk, unsigned int max_psk_len))
+	{
+	ctx->psk_server_callback = cb;
+	}
+#endif
+
+void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg))
+	{
+	SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
+	}
+void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg))
+	{
+	SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
+	}
+
+int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
+        const char *label, size_t llen, const unsigned char *p, size_t plen,
+        int use_context)
+	{
+	if (s->version < TLS1_VERSION)
+		return -1;
+
+	return s->method->ssl3_enc->export_keying_material(s, out, olen, label,
+							   llen, p, plen,
+							   use_context);
+	}
+
+int SSL_cutthrough_complete(const SSL *s)
+	{
+	return (!s->server &&                 /* cutthrough only applies to clients */
+		!s->hit &&                        /* full-handshake */
+		s->version >= SSL3_VERSION &&
+		s->s3->in_read_app_data == 0 &&   /* cutthrough only applies to write() */
+		(SSL_get_mode((SSL*)s) & SSL_MODE_HANDSHAKE_CUTTHROUGH) &&  /* cutthrough enabled */
+		SSL_get_cipher_bits(s, NULL) >= 128 &&                      /* strong cipher choosen */
+		s->s3->previous_server_finished_len == 0 &&                 /* not a renegotiation handshake */
+		(s->state == SSL3_ST_CR_SESSION_TICKET_A ||                 /* ready to write app-data*/
+			s->state == SSL3_ST_CR_FINISHED_A));
+	}
+
+/* Allocates new EVP_MD_CTX and sets pointer to it into given pointer
+ * vairable, freeing  EVP_MD_CTX previously stored in that variable, if
+ * any. If EVP_MD pointer is passed, initializes ctx with this md
+ * Returns newly allocated ctx;
+ */
+
+EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) 
+{
+	ssl_clear_hash_ctx(hash);
+	*hash = EVP_MD_CTX_create();
+	if (md) EVP_DigestInit_ex(*hash,md,NULL);
+	return *hash;
+}
+void ssl_clear_hash_ctx(EVP_MD_CTX **hash) 
+{
+
+	if (*hash) EVP_MD_CTX_destroy(*hash);
+	*hash=NULL;
+}
+
+#if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16)
+#include "../crypto/bio/bss_file.c"
+#endif
+
+IMPLEMENT_STACK_OF(SSL_CIPHER)
+IMPLEMENT_STACK_OF(SSL_COMP)
+IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER,
+				    ssl_cipher_id);
+
diff --git a/openssl/ssl/ssl_locl.h b/openssl/ssl/ssl_locl.h
new file mode 100644
index 0000000..af607e6
--- /dev/null
+++ b/openssl/ssl/ssl_locl.h
@@ -0,0 +1,1093 @@
+/* ssl/ssl_locl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#ifndef HEADER_SSL_LOCL_H
+#define HEADER_SSL_LOCL_H
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+
+#include "e_os.h"
+
+#include <openssl/buffer.h>
+#ifndef OPENSSL_NO_COMP
+#include <openssl/comp.h>
+#endif
+#include <openssl/bio.h>
+#include <openssl/stack.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+#include <openssl/symhacks.h>
+
+#ifdef OPENSSL_BUILD_SHLIBSSL
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+#define PKCS1_CHECK
+
+#define c2l(c,l)	(l = ((unsigned long)(*((c)++)))     , \
+			 l|=(((unsigned long)(*((c)++)))<< 8), \
+			 l|=(((unsigned long)(*((c)++)))<<16), \
+			 l|=(((unsigned long)(*((c)++)))<<24))
+
+/* NOTE - c is not incremented as per c2l */
+#define c2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))<<24; \
+			case 7: l2|=((unsigned long)(*(--(c))))<<16; \
+			case 6: l2|=((unsigned long)(*(--(c))))<< 8; \
+			case 5: l2|=((unsigned long)(*(--(c))));     \
+			case 4: l1 =((unsigned long)(*(--(c))))<<24; \
+			case 3: l1|=((unsigned long)(*(--(c))))<<16; \
+			case 2: l1|=((unsigned long)(*(--(c))))<< 8; \
+			case 1: l1|=((unsigned long)(*(--(c))));     \
+				} \
+			}
+
+#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)    )&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>24)&0xff))
+
+#define n2l(c,l)	(l =((unsigned long)(*((c)++)))<<24, \
+			 l|=((unsigned long)(*((c)++)))<<16, \
+			 l|=((unsigned long)(*((c)++)))<< 8, \
+			 l|=((unsigned long)(*((c)++))))
+
+#define l2n(l,c)	(*((c)++)=(unsigned char)(((l)>>24)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+			 *((c)++)=(unsigned char)(((l)    )&0xff))
+
+#define l2n6(l,c)	(*((c)++)=(unsigned char)(((l)>>40)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>32)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>24)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+			 *((c)++)=(unsigned char)(((l)    )&0xff))
+
+#define n2l6(c,l)	(l =((BN_ULLONG)(*((c)++)))<<40, \
+			 l|=((BN_ULLONG)(*((c)++)))<<32, \
+			 l|=((BN_ULLONG)(*((c)++)))<<24, \
+			 l|=((BN_ULLONG)(*((c)++)))<<16, \
+			 l|=((BN_ULLONG)(*((c)++)))<< 8, \
+			 l|=((BN_ULLONG)(*((c)++))))
+
+/* NOTE - c is not incremented as per l2c */
+#define l2cn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+				} \
+			}
+
+#define n2s(c,s)	((s=(((unsigned int)(c[0]))<< 8)| \
+			    (((unsigned int)(c[1]))    )),c+=2)
+#define s2n(s,c)	((c[0]=(unsigned char)(((s)>> 8)&0xff), \
+			  c[1]=(unsigned char)(((s)    )&0xff)),c+=2)
+
+#define n2l3(c,l)	((l =(((unsigned long)(c[0]))<<16)| \
+			     (((unsigned long)(c[1]))<< 8)| \
+			     (((unsigned long)(c[2]))    )),c+=3)
+
+#define l2n3(l,c)	((c[0]=(unsigned char)(((l)>>16)&0xff), \
+			  c[1]=(unsigned char)(((l)>> 8)&0xff), \
+			  c[2]=(unsigned char)(((l)    )&0xff)),c+=3)
+
+/* LOCAL STUFF */
+
+#define SSL_DECRYPT	0
+#define SSL_ENCRYPT	1
+
+#define TWO_BYTE_BIT	0x80
+#define SEC_ESC_BIT	0x40
+#define TWO_BYTE_MASK	0x7fff
+#define THREE_BYTE_MASK	0x3fff
+
+#define INC32(a)	((a)=((a)+1)&0xffffffffL)
+#define DEC32(a)	((a)=((a)-1)&0xffffffffL)
+#define MAX_MAC_SIZE	20 /* up from 16 for SSLv3 */
+
+/*
+ * Define the Bitmasks for SSL_CIPHER.algorithms.
+ * This bits are used packed as dense as possible. If new methods/ciphers
+ * etc will be added, the bits a likely to change, so this information
+ * is for internal library use only, even though SSL_CIPHER.algorithms
+ * can be publicly accessed.
+ * Use the according functions for cipher management instead.
+ *
+ * The bit mask handling in the selection and sorting scheme in
+ * ssl_create_cipher_list() has only limited capabilities, reflecting
+ * that the different entities within are mutually exclusive:
+ * ONLY ONE BIT PER MASK CAN BE SET AT A TIME.
+ */
+
+/* Bits for algorithm_mkey (key exchange algorithm) */
+#define SSL_kRSA		0x00000001L /* RSA key exchange */
+#define SSL_kDHr		0x00000002L /* DH cert, RSA CA cert */ /* no such ciphersuites supported! */
+#define SSL_kDHd		0x00000004L /* DH cert, DSA CA cert */ /* no such ciphersuite supported! */
+#define SSL_kEDH		0x00000008L /* tmp DH key no DH cert */
+#define SSL_kKRB5		0x00000010L /* Kerberos5 key exchange */
+#define SSL_kECDHr		0x00000020L /* ECDH cert, RSA CA cert */
+#define SSL_kECDHe		0x00000040L /* ECDH cert, ECDSA CA cert */
+#define SSL_kEECDH		0x00000080L /* ephemeral ECDH */
+#define SSL_kPSK		0x00000100L /* PSK */
+#define SSL_kGOST       0x00000200L /* GOST key exchange */
+
+/* Bits for algorithm_auth (server authentication) */
+#define SSL_aRSA		0x00000001L /* RSA auth */
+#define SSL_aDSS 		0x00000002L /* DSS auth */
+#define SSL_aNULL 		0x00000004L /* no auth (i.e. use ADH or AECDH) */
+#define SSL_aDH 		0x00000008L /* Fixed DH auth (kDHd or kDHr) */ /* no such ciphersuites supported! */
+#define SSL_aECDH 		0x00000010L /* Fixed ECDH auth (kECDHe or kECDHr) */
+#define SSL_aKRB5               0x00000020L /* KRB5 auth */
+#define SSL_aECDSA              0x00000040L /* ECDSA auth*/
+#define SSL_aPSK                0x00000080L /* PSK auth */
+#define SSL_aGOST94				0x00000100L /* GOST R 34.10-94 signature auth */
+#define SSL_aGOST01 			0x00000200L /* GOST R 34.10-2001 signature auth */
+
+
+/* Bits for algorithm_enc (symmetric encryption) */
+#define SSL_DES			0x00000001L
+#define SSL_3DES		0x00000002L
+#define SSL_RC4			0x00000004L
+#define SSL_RC2			0x00000008L
+#define SSL_IDEA		0x00000010L
+#define SSL_eNULL		0x00000020L
+#define SSL_AES128		0x00000040L
+#define SSL_AES256		0x00000080L
+#define SSL_CAMELLIA128		0x00000100L
+#define SSL_CAMELLIA256		0x00000200L
+#define SSL_eGOST2814789CNT	0x00000400L
+#define SSL_SEED		0x00000800L
+
+#define SSL_AES        		(SSL_AES128|SSL_AES256)
+#define SSL_CAMELLIA		(SSL_CAMELLIA128|SSL_CAMELLIA256)
+
+
+/* Bits for algorithm_mac (symmetric authentication) */
+#define SSL_MD5			0x00000001L
+#define SSL_SHA1		0x00000002L
+#define SSL_GOST94      0x00000004L
+#define SSL_GOST89MAC   0x00000008L
+
+/* Bits for algorithm_ssl (protocol version) */
+#define SSL_SSLV2		0x00000001L
+#define SSL_SSLV3		0x00000002L
+#define SSL_TLSV1		SSL_SSLV3	/* for now */
+
+
+/* Bits for algorithm2 (handshake digests and other extra flags) */
+
+#define SSL_HANDSHAKE_MAC_MD5 0x10
+#define SSL_HANDSHAKE_MAC_SHA 0x20
+#define SSL_HANDSHAKE_MAC_GOST94 0x40
+#define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA)
+
+/* When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX
+ * make sure to update this constant too */
+#define SSL_MAX_DIGEST 4
+
+#define TLS1_PRF_DGST_SHIFT 8
+#define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF_GOST94 (SSL_HANDSHAKE_MAC_GOST94 << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1)
+
+/* Stream MAC for GOST ciphersuites from cryptopro draft
+ * (currently this also goes into algorithm2) */
+#define TLS1_STREAM_MAC 0x04
+
+
+
+/*
+ * Export and cipher strength information. For each cipher we have to decide
+ * whether it is exportable or not. This information is likely to change
+ * over time, since the export control rules are no static technical issue.
+ *
+ * Independent of the export flag the cipher strength is sorted into classes.
+ * SSL_EXP40 was denoting the 40bit US export limit of past times, which now
+ * is at 56bit (SSL_EXP56). If the exportable cipher class is going to change
+ * again (eg. to 64bit) the use of "SSL_EXP*" becomes blurred even more,
+ * since SSL_EXP64 could be similar to SSL_LOW.
+ * For this reason SSL_MICRO and SSL_MINI macros are included to widen the
+ * namespace of SSL_LOW-SSL_HIGH to lower values. As development of speed
+ * and ciphers goes, another extension to SSL_SUPER and/or SSL_ULTRA would
+ * be possible.
+ */
+#define SSL_EXP_MASK		0x00000003L
+#define SSL_STRONG_MASK		0x000001fcL
+
+#define SSL_NOT_EXP		0x00000001L
+#define SSL_EXPORT		0x00000002L
+
+#define SSL_STRONG_NONE		0x00000004L
+#define SSL_EXP40		0x00000008L
+#define SSL_MICRO		(SSL_EXP40)
+#define SSL_EXP56		0x00000010L
+#define SSL_MINI		(SSL_EXP56)
+#define SSL_LOW			0x00000020L
+#define SSL_MEDIUM		0x00000040L
+#define SSL_HIGH		0x00000080L
+#define SSL_FIPS		0x00000100L
+
+/* we have used 000001ff - 23 bits left to go */
+
+/*
+ * Macros to check the export status and cipher strength for export ciphers.
+ * Even though the macros for EXPORT and EXPORT40/56 have similar names,
+ * their meaning is different:
+ * *_EXPORT macros check the 'exportable' status.
+ * *_EXPORT40/56 macros are used to check whether a certain cipher strength
+ *          is given.
+ * Since the SSL_IS_EXPORT* and SSL_EXPORT* macros depend on the correct
+ * algorithm structure element to be passed (algorithms, algo_strength) and no
+ * typechecking can be done as they are all of type unsigned long, their
+ * direct usage is discouraged.
+ * Use the SSL_C_* macros instead.
+ */
+#define SSL_IS_EXPORT(a)	((a)&SSL_EXPORT)
+#define SSL_IS_EXPORT56(a)	((a)&SSL_EXP56)
+#define SSL_IS_EXPORT40(a)	((a)&SSL_EXP40)
+#define SSL_C_IS_EXPORT(c)	SSL_IS_EXPORT((c)->algo_strength)
+#define SSL_C_IS_EXPORT56(c)	SSL_IS_EXPORT56((c)->algo_strength)
+#define SSL_C_IS_EXPORT40(c)	SSL_IS_EXPORT40((c)->algo_strength)
+
+#define SSL_EXPORT_KEYLENGTH(a,s)	(SSL_IS_EXPORT40(s) ? 5 : \
+				 (a) == SSL_DES ? 8 : 7)
+#define SSL_EXPORT_PKEYLENGTH(a) (SSL_IS_EXPORT40(a) ? 512 : 1024)
+#define SSL_C_EXPORT_KEYLENGTH(c)	SSL_EXPORT_KEYLENGTH((c)->algorithm_enc, \
+				(c)->algo_strength)
+#define SSL_C_EXPORT_PKEYLENGTH(c)	SSL_EXPORT_PKEYLENGTH((c)->algo_strength)
+
+
+
+
+/* Mostly for SSLv3 */
+#define SSL_PKEY_RSA_ENC	0
+#define SSL_PKEY_RSA_SIGN	1
+#define SSL_PKEY_DSA_SIGN	2
+#define SSL_PKEY_DH_RSA		3
+#define SSL_PKEY_DH_DSA		4
+#define SSL_PKEY_ECC            5
+#define SSL_PKEY_GOST94		6
+#define SSL_PKEY_GOST01		7
+#define SSL_PKEY_NUM		8
+
+/* SSL_kRSA <- RSA_ENC | (RSA_TMP & RSA_SIGN) |
+ * 	    <- (EXPORT & (RSA_ENC | RSA_TMP) & RSA_SIGN)
+ * SSL_kDH  <- DH_ENC & (RSA_ENC | RSA_SIGN | DSA_SIGN)
+ * SSL_kEDH <- RSA_ENC | RSA_SIGN | DSA_SIGN
+ * SSL_aRSA <- RSA_ENC | RSA_SIGN
+ * SSL_aDSS <- DSA_SIGN
+ */
+
+/*
+#define CERT_INVALID		0
+#define CERT_PUBLIC_KEY		1
+#define CERT_PRIVATE_KEY	2
+*/
+
+#ifndef OPENSSL_NO_EC
+/* From ECC-TLS draft, used in encoding the curve type in 
+ * ECParameters
+ */
+#define EXPLICIT_PRIME_CURVE_TYPE  1   
+#define EXPLICIT_CHAR2_CURVE_TYPE  2
+#define NAMED_CURVE_TYPE           3
+#endif  /* OPENSSL_NO_EC */
+
+typedef struct cert_pkey_st
+	{
+	X509 *x509;
+	STACK_OF(X509) *cert_chain;
+	EVP_PKEY *privatekey;
+	} CERT_PKEY;
+
+typedef struct cert_st
+	{
+	/* Current active set */
+	CERT_PKEY *key; /* ALWAYS points to an element of the pkeys array
+			 * Probably it would make more sense to store
+			 * an index, not a pointer. */
+ 
+	/* The following masks are for the key and auth
+	 * algorithms that are supported by the certs below */
+	int valid;
+	unsigned long mask_k;
+	unsigned long mask_a;
+	unsigned long export_mask_k;
+	unsigned long export_mask_a;
+#ifndef OPENSSL_NO_RSA
+	RSA *rsa_tmp;
+	RSA *(*rsa_tmp_cb)(SSL *ssl,int is_export,int keysize);
+#endif
+#ifndef OPENSSL_NO_DH
+	DH *dh_tmp;
+	DH *(*dh_tmp_cb)(SSL *ssl,int is_export,int keysize);
+#endif
+#ifndef OPENSSL_NO_ECDH
+	EC_KEY *ecdh_tmp;
+	/* Callback for generating ephemeral ECDH keys */
+	EC_KEY *(*ecdh_tmp_cb)(SSL *ssl,int is_export,int keysize);
+#endif
+
+	CERT_PKEY pkeys[SSL_PKEY_NUM];
+
+	int references; /* >1 only if SSL_copy_session_id is used */
+	} CERT;
+
+
+typedef struct sess_cert_st
+	{
+	STACK_OF(X509) *cert_chain; /* as received from peer (not for SSL2) */
+
+	/* The 'peer_...' members are used only by clients. */
+	int peer_cert_type;
+
+	CERT_PKEY *peer_key; /* points to an element of peer_pkeys (never NULL!) */
+	CERT_PKEY peer_pkeys[SSL_PKEY_NUM];
+	/* Obviously we don't have the private keys of these,
+	 * so maybe we shouldn't even use the CERT_PKEY type here. */
+
+#ifndef OPENSSL_NO_RSA
+	RSA *peer_rsa_tmp; /* not used for SSL 2 */
+#endif
+#ifndef OPENSSL_NO_DH
+	DH *peer_dh_tmp; /* not used for SSL 2 */
+#endif
+#ifndef OPENSSL_NO_ECDH
+	EC_KEY *peer_ecdh_tmp;
+#endif
+
+	int references; /* actually always 1 at the moment */
+	} SESS_CERT;
+
+
+/*#define MAC_DEBUG	*/
+
+/*#define ERR_DEBUG	*/
+/*#define ABORT_DEBUG	*/
+/*#define PKT_DEBUG 1   */
+/*#define DES_DEBUG	*/
+/*#define DES_OFB_DEBUG	*/
+/*#define SSL_DEBUG	*/
+/*#define RSA_DEBUG	*/ 
+/*#define IDEA_DEBUG	*/ 
+
+#define FP_ICC  (int (*)(const void *,const void *))
+#define ssl_put_cipher_by_char(ssl,ciph,ptr) \
+		((ssl)->method->put_cipher_by_char((ciph),(ptr)))
+#define ssl_get_cipher_by_char(ssl,ptr) \
+		((ssl)->method->get_cipher_by_char(ptr))
+
+/* This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff
+ * It is a bit of a mess of functions, but hell, think of it as
+ * an opaque structure :-) */
+typedef struct ssl3_enc_method
+	{
+	int (*enc)(SSL *, int);
+	int (*mac)(SSL *, unsigned char *, int);
+	int (*setup_key_block)(SSL *);
+	int (*generate_master_secret)(SSL *, unsigned char *, unsigned char *, int);
+	int (*change_cipher_state)(SSL *, int);
+	int (*final_finish_mac)(SSL *,  const char *, int, unsigned char *);
+	int finish_mac_length;
+	int (*cert_verify_mac)(SSL *, int, unsigned char *);
+	const char *client_finished_label;
+	int client_finished_label_len;
+	const char *server_finished_label;
+	int server_finished_label_len;
+	int (*alert_value)(int);
+	int (*export_keying_material)(SSL *, unsigned char *, size_t,
+				      const char *, size_t,
+				      const unsigned char *, size_t,
+				      int use_context);
+	} SSL3_ENC_METHOD;
+
+#ifndef OPENSSL_NO_COMP
+/* Used for holding the relevant compression methods loaded into SSL_CTX */
+typedef struct ssl3_comp_st
+	{
+	int comp_id;	/* The identifier byte for this compression type */
+	char *name;	/* Text name used for the compression type */
+	COMP_METHOD *method; /* The method :-) */
+	} SSL3_COMP;
+#endif
+
+#ifndef OPENSSL_NO_BUF_FREELISTS
+typedef struct ssl3_buf_freelist_st
+	{
+	size_t chunklen;
+	unsigned int len;
+	struct ssl3_buf_freelist_entry_st *head;
+	} SSL3_BUF_FREELIST;
+
+typedef struct ssl3_buf_freelist_entry_st
+	{
+	struct ssl3_buf_freelist_entry_st *next;
+	} SSL3_BUF_FREELIST_ENTRY;
+#endif
+
+extern SSL3_ENC_METHOD ssl3_undef_enc_method;
+OPENSSL_EXTERN const SSL_CIPHER ssl2_ciphers[];
+OPENSSL_EXTERN SSL_CIPHER ssl3_ciphers[];
+
+
+SSL_METHOD *ssl_bad_method(int ver);
+
+extern SSL3_ENC_METHOD TLSv1_enc_data;
+extern SSL3_ENC_METHOD SSLv3_enc_data;
+extern SSL3_ENC_METHOD DTLSv1_enc_data;
+
+#define IMPLEMENT_tls1_meth_func(func_name, s_accept, s_connect, s_get_meth) \
+const SSL_METHOD *func_name(void)  \
+	{ \
+	static const SSL_METHOD func_name##_data= { \
+		TLS1_VERSION, \
+		tls1_new, \
+		tls1_clear, \
+		tls1_free, \
+		s_accept, \
+		s_connect, \
+		ssl3_read, \
+		ssl3_peek, \
+		ssl3_write, \
+		ssl3_shutdown, \
+		ssl3_renegotiate, \
+		ssl3_renegotiate_check, \
+		ssl3_get_message, \
+		ssl3_read_bytes, \
+		ssl3_write_bytes, \
+		ssl3_dispatch_alert, \
+		ssl3_ctrl, \
+		ssl3_ctx_ctrl, \
+		ssl3_get_cipher_by_char, \
+		ssl3_put_cipher_by_char, \
+		ssl3_pending, \
+		ssl3_num_ciphers, \
+		ssl3_get_cipher, \
+		s_get_meth, \
+		tls1_default_timeout, \
+		&TLSv1_enc_data, \
+		ssl_undefined_void_function, \
+		ssl3_callback_ctrl, \
+		ssl3_ctx_callback_ctrl, \
+	}; \
+	return &func_name##_data; \
+	}
+
+#define IMPLEMENT_ssl3_meth_func(func_name, s_accept, s_connect, s_get_meth) \
+const SSL_METHOD *func_name(void)  \
+	{ \
+	static const SSL_METHOD func_name##_data= { \
+		SSL3_VERSION, \
+		ssl3_new, \
+		ssl3_clear, \
+		ssl3_free, \
+		s_accept, \
+		s_connect, \
+		ssl3_read, \
+		ssl3_peek, \
+		ssl3_write, \
+		ssl3_shutdown, \
+		ssl3_renegotiate, \
+		ssl3_renegotiate_check, \
+		ssl3_get_message, \
+		ssl3_read_bytes, \
+		ssl3_write_bytes, \
+		ssl3_dispatch_alert, \
+		ssl3_ctrl, \
+		ssl3_ctx_ctrl, \
+		ssl3_get_cipher_by_char, \
+		ssl3_put_cipher_by_char, \
+		ssl3_pending, \
+		ssl3_num_ciphers, \
+		ssl3_get_cipher, \
+		s_get_meth, \
+		ssl3_default_timeout, \
+		&SSLv3_enc_data, \
+		ssl_undefined_void_function, \
+		ssl3_callback_ctrl, \
+		ssl3_ctx_callback_ctrl, \
+	}; \
+	return &func_name##_data; \
+	}
+
+#define IMPLEMENT_ssl23_meth_func(func_name, s_accept, s_connect, s_get_meth) \
+const SSL_METHOD *func_name(void)  \
+	{ \
+	static const SSL_METHOD func_name##_data= { \
+	TLS1_VERSION, \
+	tls1_new, \
+	tls1_clear, \
+	tls1_free, \
+	s_accept, \
+	s_connect, \
+	ssl23_read, \
+	ssl23_peek, \
+	ssl23_write, \
+	ssl_undefined_function, \
+	ssl_undefined_function, \
+	ssl_ok, \
+	ssl3_get_message, \
+	ssl3_read_bytes, \
+	ssl3_write_bytes, \
+	ssl3_dispatch_alert, \
+	ssl3_ctrl, \
+	ssl3_ctx_ctrl, \
+	ssl23_get_cipher_by_char, \
+	ssl23_put_cipher_by_char, \
+	ssl_undefined_const_function, \
+	ssl23_num_ciphers, \
+	ssl23_get_cipher, \
+	s_get_meth, \
+	ssl23_default_timeout, \
+	&ssl3_undef_enc_method, \
+	ssl_undefined_void_function, \
+	ssl3_callback_ctrl, \
+	ssl3_ctx_callback_ctrl, \
+	}; \
+	return &func_name##_data; \
+	}
+
+#define IMPLEMENT_ssl2_meth_func(func_name, s_accept, s_connect, s_get_meth) \
+const SSL_METHOD *func_name(void)  \
+	{ \
+	static const SSL_METHOD func_name##_data= { \
+		SSL2_VERSION, \
+		ssl2_new,	/* local */ \
+		ssl2_clear,	/* local */ \
+		ssl2_free,	/* local */ \
+		s_accept, \
+		s_connect, \
+		ssl2_read, \
+		ssl2_peek, \
+		ssl2_write, \
+		ssl2_shutdown, \
+		ssl_ok,	/* NULL - renegotiate */ \
+		ssl_ok,	/* NULL - check renegotiate */ \
+		NULL, /* NULL - ssl_get_message */ \
+		NULL, /* NULL - ssl_get_record */ \
+		NULL, /* NULL - ssl_write_bytes */ \
+		NULL, /* NULL - dispatch_alert */ \
+		ssl2_ctrl,	/* local */ \
+		ssl2_ctx_ctrl,	/* local */ \
+		ssl2_get_cipher_by_char, \
+		ssl2_put_cipher_by_char, \
+		ssl2_pending, \
+		ssl2_num_ciphers, \
+		ssl2_get_cipher, \
+		s_get_meth, \
+		ssl2_default_timeout, \
+		&ssl3_undef_enc_method, \
+		ssl_undefined_void_function, \
+		ssl2_callback_ctrl,	/* local */ \
+		ssl2_ctx_callback_ctrl,	/* local */ \
+	}; \
+	return &func_name##_data; \
+	}
+
+#define IMPLEMENT_dtls1_meth_func(func_name, s_accept, s_connect, s_get_meth) \
+const SSL_METHOD *func_name(void)  \
+	{ \
+	static const SSL_METHOD func_name##_data= { \
+		DTLS1_VERSION, \
+		dtls1_new, \
+		dtls1_clear, \
+		dtls1_free, \
+		s_accept, \
+		s_connect, \
+		ssl3_read, \
+		ssl3_peek, \
+		ssl3_write, \
+		ssl3_shutdown, \
+		ssl3_renegotiate, \
+		ssl3_renegotiate_check, \
+		dtls1_get_message, \
+		dtls1_read_bytes, \
+		dtls1_write_app_data_bytes, \
+		dtls1_dispatch_alert, \
+		dtls1_ctrl, \
+		ssl3_ctx_ctrl, \
+		ssl3_get_cipher_by_char, \
+		ssl3_put_cipher_by_char, \
+		ssl3_pending, \
+		ssl3_num_ciphers, \
+		dtls1_get_cipher, \
+		s_get_meth, \
+		dtls1_default_timeout, \
+		&DTLSv1_enc_data, \
+		ssl_undefined_void_function, \
+		ssl3_callback_ctrl, \
+		ssl3_ctx_callback_ctrl, \
+	}; \
+	return &func_name##_data; \
+	}
+
+void ssl_clear_cipher_ctx(SSL *s);
+int ssl_clear_bad_session(SSL *s);
+CERT *ssl_cert_new(void);
+CERT *ssl_cert_dup(CERT *cert);
+int ssl_cert_inst(CERT **o);
+void ssl_cert_free(CERT *c);
+SESS_CERT *ssl_sess_cert_new(void);
+void ssl_sess_cert_free(SESS_CERT *sc);
+int ssl_set_peer_cert_type(SESS_CERT *c, int type);
+int ssl_get_new_session(SSL *s, int session);
+int ssl_get_prev_session(SSL *s, unsigned char *session,int len, const unsigned char *limit);
+int ssl_cipher_id_cmp(const SSL_CIPHER *a,const SSL_CIPHER *b);
+DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER,
+				  ssl_cipher_id);
+int ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap,
+			const SSL_CIPHER * const *bp);
+STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
+					       STACK_OF(SSL_CIPHER) **skp);
+int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
+                             int (*put_cb)(const SSL_CIPHER *, unsigned char *));
+STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth,
+					     STACK_OF(SSL_CIPHER) **pref,
+					     STACK_OF(SSL_CIPHER) **sorted,
+					     const char *rule_str);
+void ssl_update_cache(SSL *s, int mode);
+int ssl_cipher_get_evp(const SSL_SESSION *s,const EVP_CIPHER **enc,
+		       const EVP_MD **md,int *mac_pkey_type,int *mac_secret_size, SSL_COMP **comp);
+int ssl_get_handshake_digest(int i,long *mask,const EVP_MD **md);			   
+int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk);
+int ssl_undefined_function(SSL *s);
+int ssl_undefined_void_function(void);
+int ssl_undefined_const_function(const SSL *s);
+X509 *ssl_get_server_send_cert(SSL *);
+EVP_PKEY *ssl_get_sign_pkey(SSL *,const SSL_CIPHER *);
+int ssl_cert_type(X509 *x,EVP_PKEY *pkey);
+void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher);
+STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
+int ssl_verify_alarm_type(long type);
+void ssl_load_ciphers(void);
+
+int ssl2_enc_init(SSL *s, int client);
+int ssl2_generate_key_material(SSL *s);
+void ssl2_enc(SSL *s,int send_data);
+void ssl2_mac(SSL *s,unsigned char *mac,int send_data);
+const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p);
+int ssl2_put_cipher_by_char(const SSL_CIPHER *c,unsigned char *p);
+int ssl2_part_read(SSL *s, unsigned long f, int i);
+int ssl2_do_write(SSL *s);
+int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data);
+void ssl2_return_error(SSL *s,int reason);
+void ssl2_write_error(SSL *s);
+int ssl2_num_ciphers(void);
+const SSL_CIPHER *ssl2_get_cipher(unsigned int u);
+int	ssl2_new(SSL *s);
+void	ssl2_free(SSL *s);
+int	ssl2_accept(SSL *s);
+int	ssl2_connect(SSL *s);
+int	ssl2_read(SSL *s, void *buf, int len);
+int	ssl2_peek(SSL *s, void *buf, int len);
+int	ssl2_write(SSL *s, const void *buf, int len);
+int	ssl2_shutdown(SSL *s);
+void	ssl2_clear(SSL *s);
+long	ssl2_ctrl(SSL *s,int cmd, long larg, void *parg);
+long	ssl2_ctx_ctrl(SSL_CTX *s,int cmd, long larg, void *parg);
+long	ssl2_callback_ctrl(SSL *s,int cmd, void (*fp)(void));
+long	ssl2_ctx_callback_ctrl(SSL_CTX *s,int cmd, void (*fp)(void));
+int	ssl2_pending(const SSL *s);
+long	ssl2_default_timeout(void );
+
+const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p);
+int ssl3_put_cipher_by_char(const SSL_CIPHER *c,unsigned char *p);
+void ssl3_init_finished_mac(SSL *s);
+int ssl3_send_server_certificate(SSL *s);
+int ssl3_send_newsession_ticket(SSL *s);
+int ssl3_send_cert_status(SSL *s);
+int ssl3_get_finished(SSL *s,int state_a,int state_b);
+int ssl3_setup_key_block(SSL *s);
+int ssl3_send_change_cipher_spec(SSL *s,int state_a,int state_b);
+int ssl3_change_cipher_state(SSL *s,int which);
+void ssl3_cleanup_key_block(SSL *s);
+int ssl3_do_write(SSL *s,int type);
+int ssl3_send_alert(SSL *s,int level, int desc);
+int ssl3_generate_master_secret(SSL *s, unsigned char *out,
+	unsigned char *p, int len);
+int ssl3_get_req_cert_type(SSL *s,unsigned char *p);
+long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok);
+int ssl3_send_finished(SSL *s, int a, int b, const char *sender,int slen);
+int ssl3_num_ciphers(void);
+const SSL_CIPHER *ssl3_get_cipher(unsigned int u);
+int ssl3_renegotiate(SSL *ssl); 
+int ssl3_renegotiate_check(SSL *ssl); 
+int ssl3_dispatch_alert(SSL *s);
+int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek);
+int ssl3_write_bytes(SSL *s, int type, const void *buf, int len);
+int ssl3_final_finish_mac(SSL *s, const char *sender, int slen,unsigned char *p);
+int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
+void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len);
+int ssl3_enc(SSL *s, int send_data);
+int n_ssl3_mac(SSL *ssl, unsigned char *md, int send_data);
+void ssl3_free_digest_list(SSL *s);
+unsigned long ssl3_output_cert_chain(SSL *s, X509 *x);
+SSL_CIPHER *ssl3_choose_cipher(SSL *ssl,STACK_OF(SSL_CIPHER) *clnt,
+			       STACK_OF(SSL_CIPHER) *srvr);
+int	ssl3_setup_buffers(SSL *s);
+int	ssl3_setup_read_buffer(SSL *s);
+int	ssl3_setup_write_buffer(SSL *s);
+int	ssl3_release_read_buffer(SSL *s);
+int	ssl3_release_write_buffer(SSL *s);
+int	ssl3_digest_cached_records(SSL *s);
+int	ssl3_new(SSL *s);
+void	ssl3_free(SSL *s);
+int	ssl3_accept(SSL *s);
+int	ssl3_connect(SSL *s);
+int	ssl3_read(SSL *s, void *buf, int len);
+int	ssl3_peek(SSL *s, void *buf, int len);
+int	ssl3_write(SSL *s, const void *buf, int len);
+int	ssl3_shutdown(SSL *s);
+void	ssl3_clear(SSL *s);
+long	ssl3_ctrl(SSL *s,int cmd, long larg, void *parg);
+long	ssl3_ctx_ctrl(SSL_CTX *s,int cmd, long larg, void *parg);
+long	ssl3_callback_ctrl(SSL *s,int cmd, void (*fp)(void));
+long	ssl3_ctx_callback_ctrl(SSL_CTX *s,int cmd, void (*fp)(void));
+int	ssl3_pending(const SSL *s);
+
+void ssl3_record_sequence_update(unsigned char *seq);
+int ssl3_do_change_cipher_spec(SSL *ssl);
+long ssl3_default_timeout(void );
+
+int ssl23_num_ciphers(void );
+const SSL_CIPHER *ssl23_get_cipher(unsigned int u);
+int ssl23_read(SSL *s, void *buf, int len);
+int ssl23_peek(SSL *s, void *buf, int len);
+int ssl23_write(SSL *s, const void *buf, int len);
+int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p);
+const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p);
+long ssl23_default_timeout(void );
+
+long tls1_default_timeout(void);
+int dtls1_do_write(SSL *s,int type);
+int ssl3_read_n(SSL *s, int n, int max, int extend);
+int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek);
+int ssl3_do_compress(SSL *ssl);
+int ssl3_do_uncompress(SSL *ssl);
+int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
+	unsigned int len);
+unsigned char *dtls1_set_message_header(SSL *s, 
+	unsigned char *p, unsigned char mt,	unsigned long len, 
+	unsigned long frag_off, unsigned long frag_len);
+
+int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf, int len);
+int dtls1_write_bytes(SSL *s, int type, const void *buf, int len);
+
+int dtls1_send_change_cipher_spec(SSL *s, int a, int b);
+int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen);
+unsigned long dtls1_output_cert_chain(SSL *s, X509 *x);
+int dtls1_read_failed(SSL *s, int code);
+int dtls1_buffer_message(SSL *s, int ccs);
+int dtls1_retransmit_message(SSL *s, unsigned short seq, 
+	unsigned long frag_off, int *found);
+int dtls1_get_queue_priority(unsigned short seq, int is_ccs);
+int dtls1_retransmit_buffered_messages(SSL *s);
+void dtls1_clear_record_buffer(SSL *s);
+void dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr);
+void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr);
+void dtls1_reset_seq_numbers(SSL *s, int rw);
+long dtls1_default_timeout(void);
+struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft);
+int dtls1_handle_timeout(SSL *s);
+const SSL_CIPHER *dtls1_get_cipher(unsigned int u);
+void dtls1_start_timer(SSL *s);
+void dtls1_stop_timer(SSL *s);
+int dtls1_is_timer_expired(SSL *s);
+void dtls1_double_timeout(SSL *s);
+int dtls1_send_newsession_ticket(SSL *s);
+unsigned int dtls1_min_mtu(void);
+
+/* some client-only functions */
+int ssl3_client_hello(SSL *s);
+int ssl3_get_server_hello(SSL *s);
+int ssl3_get_certificate_request(SSL *s);
+int ssl3_get_new_session_ticket(SSL *s);
+int ssl3_get_cert_status(SSL *s);
+int ssl3_get_server_done(SSL *s);
+int ssl3_send_client_verify(SSL *s);
+int ssl3_send_client_certificate(SSL *s);
+int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey);
+int ssl3_send_client_key_exchange(SSL *s);
+int ssl3_get_key_exchange(SSL *s);
+int ssl3_get_server_certificate(SSL *s);
+int ssl3_check_cert_and_algorithm(SSL *s);
+#ifndef OPENSSL_NO_TLSEXT
+int ssl3_check_finished(SSL *s);
+# ifndef OPENSSL_NO_NEXTPROTONEG
+int ssl3_send_next_proto(SSL *s);
+# endif
+#endif
+
+int dtls1_client_hello(SSL *s);
+int dtls1_send_client_certificate(SSL *s);
+int dtls1_send_client_key_exchange(SSL *s);
+int dtls1_send_client_verify(SSL *s);
+
+/* some server-only functions */
+int ssl3_get_client_hello(SSL *s);
+int ssl3_send_server_hello(SSL *s);
+int ssl3_send_hello_request(SSL *s);
+int ssl3_send_server_key_exchange(SSL *s);
+int ssl3_send_certificate_request(SSL *s);
+int ssl3_send_server_done(SSL *s);
+int ssl3_check_client_hello(SSL *s);
+int ssl3_get_client_certificate(SSL *s);
+int ssl3_get_client_key_exchange(SSL *s);
+int ssl3_get_cert_verify(SSL *s);
+#ifndef OPENSSL_NO_NEXTPROTONEG
+int ssl3_get_next_proto(SSL *s);
+#endif
+
+int dtls1_send_hello_request(SSL *s);
+int dtls1_send_server_hello(SSL *s);
+int dtls1_send_server_certificate(SSL *s);
+int dtls1_send_server_key_exchange(SSL *s);
+int dtls1_send_certificate_request(SSL *s);
+int dtls1_send_server_done(SSL *s);
+
+
+
+int ssl23_accept(SSL *s);
+int ssl23_connect(SSL *s);
+int ssl23_read_bytes(SSL *s, int n);
+int ssl23_write_bytes(SSL *s);
+
+int tls1_new(SSL *s);
+void tls1_free(SSL *s);
+void tls1_clear(SSL *s);
+long tls1_ctrl(SSL *s,int cmd, long larg, void *parg);
+long tls1_callback_ctrl(SSL *s,int cmd, void (*fp)(void));
+
+int dtls1_new(SSL *s);
+int	dtls1_accept(SSL *s);
+int	dtls1_connect(SSL *s);
+void dtls1_free(SSL *s);
+void dtls1_clear(SSL *s);
+long dtls1_ctrl(SSL *s,int cmd, long larg, void *parg);
+
+long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok);
+int dtls1_get_record(SSL *s);
+int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
+	unsigned int len, int create_empty_fragement);
+int dtls1_dispatch_alert(SSL *s);
+int dtls1_enc(SSL *s, int snd);
+
+int ssl_init_wbio_buffer(SSL *s, int push);
+void ssl_free_wbio_buffer(SSL *s);
+
+int tls1_change_cipher_state(SSL *s, int which);
+int tls1_setup_key_block(SSL *s);
+int tls1_enc(SSL *s, int snd);
+int tls1_final_finish_mac(SSL *s,
+	const char *str, int slen, unsigned char *p);
+int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
+int tls1_mac(SSL *ssl, unsigned char *md, int snd);
+int tls1_generate_master_secret(SSL *s, unsigned char *out,
+	unsigned char *p, int len);
+int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
+	const char *label, size_t llen, const unsigned char *p,
+	size_t plen, int use_context);
+int tls1_alert_code(int code);
+int ssl3_alert_code(int code);
+int ssl_ok(SSL *s);
+
+#ifndef OPENSSL_NO_ECDH
+int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs);
+#endif
+
+SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n);
+
+#ifndef OPENSSL_NO_EC
+int tls1_ec_curve_id2nid(int curve_id);
+int tls1_ec_nid2curve_id(int nid);
+#endif /* OPENSSL_NO_EC */
+
+#ifndef OPENSSL_NO_TLSEXT
+unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); 
+unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); 
+int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
+int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
+int ssl_prepare_clienthello_tlsext(SSL *s);
+int ssl_prepare_serverhello_tlsext(SSL *s);
+int ssl_check_clienthello_tlsext(SSL *s);
+int ssl_check_serverhello_tlsext(SSL *s);
+
+#ifdef OPENSSL_NO_SHA256
+#define tlsext_tick_md	EVP_sha1
+#else
+#define tlsext_tick_md	EVP_sha256
+#endif
+int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
+				const unsigned char *limit, SSL_SESSION **ret);
+#endif
+EVP_MD_CTX* ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) ;
+void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
+int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
+					int maxlen);
+int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len,
+					  int *al);
+int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
+					int maxlen);
+int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
+					  int *al);
+#endif
diff --git a/openssl/ssl/ssl_rsa.c b/openssl/ssl/ssl_rsa.c
new file mode 100644
index 0000000..c43f3e2
--- /dev/null
+++ b/openssl/ssl/ssl_rsa.c
@@ -0,0 +1,815 @@
+/* ssl/ssl_rsa.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "ssl_locl.h"
+#include <openssl/bio.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+static int ssl_set_cert(CERT *c, X509 *x509);
+static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
+int SSL_use_certificate(SSL *ssl, X509 *x)
+	{
+	if (x == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_CERTIFICATE,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	if (!ssl_cert_inst(&ssl->cert))
+		{
+		SSLerr(SSL_F_SSL_USE_CERTIFICATE,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	return(ssl_set_cert(ssl->cert,x));
+	}
+
+#ifndef OPENSSL_NO_STDIO
+int SSL_use_certificate_file(SSL *ssl, const char *file, int type)
+	{
+	int j;
+	BIO *in;
+	int ret=0;
+	X509 *x=NULL;
+
+	in=BIO_new(BIO_s_file_internal());
+	if (in == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,ERR_R_BUF_LIB);
+		goto end;
+		}
+
+	if (BIO_read_filename(in,file) <= 0)
+		{
+		SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,ERR_R_SYS_LIB);
+		goto end;
+		}
+	if (type == SSL_FILETYPE_ASN1)
+		{
+		j=ERR_R_ASN1_LIB;
+		x=d2i_X509_bio(in,NULL);
+		}
+	else if (type == SSL_FILETYPE_PEM)
+		{
+		j=ERR_R_PEM_LIB;
+		x=PEM_read_bio_X509(in,NULL,ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata);
+		}
+	else
+		{
+		SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,SSL_R_BAD_SSL_FILETYPE);
+		goto end;
+		}
+
+	if (x == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,j);
+		goto end;
+		}
+
+	ret=SSL_use_certificate(ssl,x);
+end:
+	if (x != NULL) X509_free(x);
+	if (in != NULL) BIO_free(in);
+	return(ret);
+	}
+#endif
+
+int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
+	{
+	X509 *x;
+	int ret;
+
+	x=d2i_X509(NULL,&d,(long)len);
+	if (x == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1,ERR_R_ASN1_LIB);
+		return(0);
+		}
+
+	ret=SSL_use_certificate(ssl,x);
+	X509_free(x);
+	return(ret);
+	}
+
+#ifndef OPENSSL_NO_RSA
+int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
+	{
+	EVP_PKEY *pkey;
+	int ret;
+
+	if (rsa == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	if (!ssl_cert_inst(&ssl->cert))
+		{
+		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	if ((pkey=EVP_PKEY_new()) == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_EVP_LIB);
+		return(0);
+		}
+
+	RSA_up_ref(rsa);
+	EVP_PKEY_assign_RSA(pkey,rsa);
+
+	ret=ssl_set_pkey(ssl->cert,pkey);
+	EVP_PKEY_free(pkey);
+	return(ret);
+	}
+#endif
+
+static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
+	{
+	int i;
+
+	i=ssl_cert_type(NULL,pkey);
+	if (i < 0)
+		{
+		SSLerr(SSL_F_SSL_SET_PKEY,SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+		return(0);
+		}
+
+	if (c->pkeys[i].x509 != NULL)
+		{
+		EVP_PKEY *pktmp;
+		pktmp =	X509_get_pubkey(c->pkeys[i].x509);
+		EVP_PKEY_copy_parameters(pktmp,pkey);
+		EVP_PKEY_free(pktmp);
+		ERR_clear_error();
+
+#ifndef OPENSSL_NO_RSA
+		/* Don't check the public/private key, this is mostly
+		 * for smart cards. */
+		if ((pkey->type == EVP_PKEY_RSA) &&
+			(RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK))
+			;
+		else
+#endif
+		if (!X509_check_private_key(c->pkeys[i].x509,pkey))
+			{
+			X509_free(c->pkeys[i].x509);
+			c->pkeys[i].x509 = NULL;
+			return 0;
+			}
+		}
+
+	if (c->pkeys[i].privatekey != NULL)
+		EVP_PKEY_free(c->pkeys[i].privatekey);
+	CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
+	c->pkeys[i].privatekey=pkey;
+	c->key= &(c->pkeys[i]);
+
+	c->valid=0;
+	return(1);
+	}
+
+#ifndef OPENSSL_NO_RSA
+#ifndef OPENSSL_NO_STDIO
+int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type)
+	{
+	int j,ret=0;
+	BIO *in;
+	RSA *rsa=NULL;
+
+	in=BIO_new(BIO_s_file_internal());
+	if (in == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,ERR_R_BUF_LIB);
+		goto end;
+		}
+
+	if (BIO_read_filename(in,file) <= 0)
+		{
+		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,ERR_R_SYS_LIB);
+		goto end;
+		}
+	if	(type == SSL_FILETYPE_ASN1)
+		{
+		j=ERR_R_ASN1_LIB;
+		rsa=d2i_RSAPrivateKey_bio(in,NULL);
+		}
+	else if (type == SSL_FILETYPE_PEM)
+		{
+		j=ERR_R_PEM_LIB;
+		rsa=PEM_read_bio_RSAPrivateKey(in,NULL,
+			ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata);
+		}
+	else
+		{
+		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE);
+		goto end;
+		}
+	if (rsa == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,j);
+		goto end;
+		}
+	ret=SSL_use_RSAPrivateKey(ssl,rsa);
+	RSA_free(rsa);
+end:
+	if (in != NULL) BIO_free(in);
+	return(ret);
+	}
+#endif
+
+int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len)
+	{
+	int ret;
+	const unsigned char *p;
+	RSA *rsa;
+
+	p=d;
+	if ((rsa=d2i_RSAPrivateKey(NULL,&p,(long)len)) == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1,ERR_R_ASN1_LIB);
+		return(0);
+		}
+
+	ret=SSL_use_RSAPrivateKey(ssl,rsa);
+	RSA_free(rsa);
+	return(ret);
+	}
+#endif /* !OPENSSL_NO_RSA */
+
+int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
+	{
+	int ret;
+
+	if (pkey == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_PRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	if (!ssl_cert_inst(&ssl->cert))
+		{
+		SSLerr(SSL_F_SSL_USE_PRIVATEKEY,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	ret=ssl_set_pkey(ssl->cert,pkey);
+	return(ret);
+	}
+
+#ifndef OPENSSL_NO_STDIO
+int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
+	{
+	int j,ret=0;
+	BIO *in;
+	EVP_PKEY *pkey=NULL;
+
+	in=BIO_new(BIO_s_file_internal());
+	if (in == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,ERR_R_BUF_LIB);
+		goto end;
+		}
+
+	if (BIO_read_filename(in,file) <= 0)
+		{
+		SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,ERR_R_SYS_LIB);
+		goto end;
+		}
+	if (type == SSL_FILETYPE_PEM)
+		{
+		j=ERR_R_PEM_LIB;
+		pkey=PEM_read_bio_PrivateKey(in,NULL,
+			ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata);
+		}
+	else if (type == SSL_FILETYPE_ASN1)
+		{
+		j = ERR_R_ASN1_LIB;
+		pkey = d2i_PrivateKey_bio(in,NULL);
+		}
+	else
+		{
+		SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE);
+		goto end;
+		}
+	if (pkey == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,j);
+		goto end;
+		}
+	ret=SSL_use_PrivateKey(ssl,pkey);
+	EVP_PKEY_free(pkey);
+end:
+	if (in != NULL) BIO_free(in);
+	return(ret);
+	}
+#endif
+
+int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len)
+	{
+	int ret;
+	const unsigned char *p;
+	EVP_PKEY *pkey;
+
+	p=d;
+	if ((pkey=d2i_PrivateKey(type,NULL,&p,(long)len)) == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1,ERR_R_ASN1_LIB);
+		return(0);
+		}
+
+	ret=SSL_use_PrivateKey(ssl,pkey);
+	EVP_PKEY_free(pkey);
+	return(ret);
+	}
+
+int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
+	{
+	if (x == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	if (!ssl_cert_inst(&ctx->cert))
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	return(ssl_set_cert(ctx->cert, x));
+	}
+
+static int ssl_set_cert(CERT *c, X509 *x)
+	{
+	EVP_PKEY *pkey;
+	int i;
+
+	pkey=X509_get_pubkey(x);
+	if (pkey == NULL)
+		{
+		SSLerr(SSL_F_SSL_SET_CERT,SSL_R_X509_LIB);
+		return(0);
+		}
+
+	i=ssl_cert_type(x,pkey);
+	if (i < 0)
+		{
+		SSLerr(SSL_F_SSL_SET_CERT,SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+		EVP_PKEY_free(pkey);
+		return(0);
+		}
+
+	if (c->pkeys[i].privatekey != NULL)
+		{
+		EVP_PKEY_copy_parameters(pkey,c->pkeys[i].privatekey);
+		ERR_clear_error();
+
+#ifndef OPENSSL_NO_RSA
+		/* Don't check the public/private key, this is mostly
+		 * for smart cards. */
+		if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) &&
+			(RSA_flags(c->pkeys[i].privatekey->pkey.rsa) &
+			 RSA_METHOD_FLAG_NO_CHECK))
+			 ;
+		else
+#endif /* OPENSSL_NO_RSA */
+		if (!X509_check_private_key(x,c->pkeys[i].privatekey))
+			{
+			/* don't fail for a cert/key mismatch, just free
+			 * current private key (when switching to a different
+			 * cert & key, first this function should be used,
+			 * then ssl_set_pkey */
+			EVP_PKEY_free(c->pkeys[i].privatekey);
+			c->pkeys[i].privatekey=NULL;
+			/* clear error queue */
+			ERR_clear_error();
+			}
+		}
+
+	EVP_PKEY_free(pkey);
+
+	if (c->pkeys[i].x509 != NULL)
+		X509_free(c->pkeys[i].x509);
+	CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
+	c->pkeys[i].x509=x;
+	c->key= &(c->pkeys[i]);
+
+	c->valid=0;
+	return(1);
+	}
+
+#ifndef OPENSSL_NO_STDIO
+int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
+	{
+	int j;
+	BIO *in;
+	int ret=0;
+	X509 *x=NULL;
+
+	in=BIO_new(BIO_s_file_internal());
+	if (in == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_BUF_LIB);
+		goto end;
+		}
+
+	if (BIO_read_filename(in,file) <= 0)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_SYS_LIB);
+		goto end;
+		}
+	if (type == SSL_FILETYPE_ASN1)
+		{
+		j=ERR_R_ASN1_LIB;
+		x=d2i_X509_bio(in,NULL);
+		}
+	else if (type == SSL_FILETYPE_PEM)
+		{
+		j=ERR_R_PEM_LIB;
+		x=PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
+		}
+	else
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,SSL_R_BAD_SSL_FILETYPE);
+		goto end;
+		}
+
+	if (x == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,j);
+		goto end;
+		}
+
+	ret=SSL_CTX_use_certificate(ctx,x);
+end:
+	if (x != NULL) X509_free(x);
+	if (in != NULL) BIO_free(in);
+	return(ret);
+	}
+#endif
+
+int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d)
+	{
+	X509 *x;
+	int ret;
+
+	x=d2i_X509(NULL,&d,(long)len);
+	if (x == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1,ERR_R_ASN1_LIB);
+		return(0);
+		}
+
+	ret=SSL_CTX_use_certificate(ctx,x);
+	X509_free(x);
+	return(ret);
+	}
+
+#ifndef OPENSSL_NO_RSA
+int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
+	{
+	int ret;
+	EVP_PKEY *pkey;
+
+	if (rsa == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	if (!ssl_cert_inst(&ctx->cert))
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	if ((pkey=EVP_PKEY_new()) == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_EVP_LIB);
+		return(0);
+		}
+
+	RSA_up_ref(rsa);
+	EVP_PKEY_assign_RSA(pkey,rsa);
+
+	ret=ssl_set_pkey(ctx->cert, pkey);
+	EVP_PKEY_free(pkey);
+	return(ret);
+	}
+
+#ifndef OPENSSL_NO_STDIO
+int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
+	{
+	int j,ret=0;
+	BIO *in;
+	RSA *rsa=NULL;
+
+	in=BIO_new(BIO_s_file_internal());
+	if (in == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,ERR_R_BUF_LIB);
+		goto end;
+		}
+
+	if (BIO_read_filename(in,file) <= 0)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,ERR_R_SYS_LIB);
+		goto end;
+		}
+	if	(type == SSL_FILETYPE_ASN1)
+		{
+		j=ERR_R_ASN1_LIB;
+		rsa=d2i_RSAPrivateKey_bio(in,NULL);
+		}
+	else if (type == SSL_FILETYPE_PEM)
+		{
+		j=ERR_R_PEM_LIB;
+		rsa=PEM_read_bio_RSAPrivateKey(in,NULL,
+			ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
+		}
+	else
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE);
+		goto end;
+		}
+	if (rsa == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,j);
+		goto end;
+		}
+	ret=SSL_CTX_use_RSAPrivateKey(ctx,rsa);
+	RSA_free(rsa);
+end:
+	if (in != NULL) BIO_free(in);
+	return(ret);
+	}
+#endif
+
+int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len)
+	{
+	int ret;
+	const unsigned char *p;
+	RSA *rsa;
+
+	p=d;
+	if ((rsa=d2i_RSAPrivateKey(NULL,&p,(long)len)) == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1,ERR_R_ASN1_LIB);
+		return(0);
+		}
+
+	ret=SSL_CTX_use_RSAPrivateKey(ctx,rsa);
+	RSA_free(rsa);
+	return(ret);
+	}
+#endif /* !OPENSSL_NO_RSA */
+
+int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
+	{
+	if (pkey == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	if (!ssl_cert_inst(&ctx->cert))
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	return(ssl_set_pkey(ctx->cert,pkey));
+	}
+
+#ifndef OPENSSL_NO_STDIO
+int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
+	{
+	int j,ret=0;
+	BIO *in;
+	EVP_PKEY *pkey=NULL;
+
+	in=BIO_new(BIO_s_file_internal());
+	if (in == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,ERR_R_BUF_LIB);
+		goto end;
+		}
+
+	if (BIO_read_filename(in,file) <= 0)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,ERR_R_SYS_LIB);
+		goto end;
+		}
+	if (type == SSL_FILETYPE_PEM)
+		{
+		j=ERR_R_PEM_LIB;
+		pkey=PEM_read_bio_PrivateKey(in,NULL,
+			ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
+		}
+	else if (type == SSL_FILETYPE_ASN1)
+		{
+		j = ERR_R_ASN1_LIB;
+		pkey = d2i_PrivateKey_bio(in,NULL);
+		}
+	else
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE);
+		goto end;
+		}
+	if (pkey == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,j);
+		goto end;
+		}
+	ret=SSL_CTX_use_PrivateKey(ctx,pkey);
+	EVP_PKEY_free(pkey);
+end:
+	if (in != NULL) BIO_free(in);
+	return(ret);
+	}
+#endif
+
+int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d,
+	     long len)
+	{
+	int ret;
+	const unsigned char *p;
+	EVP_PKEY *pkey;
+
+	p=d;
+	if ((pkey=d2i_PrivateKey(type,NULL,&p,(long)len)) == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1,ERR_R_ASN1_LIB);
+		return(0);
+		}
+
+	ret=SSL_CTX_use_PrivateKey(ctx,pkey);
+	EVP_PKEY_free(pkey);
+	return(ret);
+	}
+
+
+int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain)
+	{
+	if (ssl == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,ERR_R_PASSED_NULL_PARAMETER);
+		return(0);
+		}
+	if (ssl->cert == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED);
+		return(0);
+		}
+	if (ssl->cert->key == NULL)
+		{
+		SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED);
+		return(0);
+		}
+	ssl->cert->key->cert_chain = cert_chain;
+	return(1);
+	}
+
+STACK_OF(X509) *SSL_get_certificate_chain(SSL *ssl, X509 *x)
+	{
+	int i;
+	if (x == NULL)
+		return NULL;
+	if (ssl == NULL)
+		return NULL;
+	if (ssl->cert == NULL)
+		return NULL;
+	for (i = 0; i < SSL_PKEY_NUM; i++)
+		if (ssl->cert->pkeys[i].x509 == x)
+			return ssl->cert->pkeys[i].cert_chain;
+	return NULL;
+	}
+
+#ifndef OPENSSL_NO_STDIO
+/* Read a file that contains our certificate in "PEM" format,
+ * possibly followed by a sequence of CA certificates that should be
+ * sent to the peer in the Certificate message.
+ */
+int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
+	{
+	BIO *in;
+	int ret=0;
+	X509 *x=NULL;
+
+	ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */
+
+	in=BIO_new(BIO_s_file_internal());
+	if (in == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_BUF_LIB);
+		goto end;
+		}
+
+	if (BIO_read_filename(in,file) <= 0)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_SYS_LIB);
+		goto end;
+		}
+
+	x=PEM_read_bio_X509_AUX(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
+	if (x == NULL)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_PEM_LIB);
+		goto end;
+		}
+
+	ret=SSL_CTX_use_certificate(ctx,x);
+	if (ERR_peek_error() != 0)
+		ret = 0;  /* Key/certificate mismatch doesn't imply ret==0 ... */
+	if (ret)
+		{
+		/* If we could set up our certificate, now proceed to
+		 * the CA certificates.
+		 */
+		X509 *ca;
+		int r;
+		unsigned long err;
+		
+		if (ctx->extra_certs != NULL) 
+			{
+			sk_X509_pop_free(ctx->extra_certs, X509_free);
+			ctx->extra_certs = NULL;
+			}
+
+		while ((ca = PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata))
+			!= NULL)
+			{
+			r = SSL_CTX_add_extra_chain_cert(ctx, ca);
+			if (!r) 
+				{
+				X509_free(ca);
+				ret = 0;
+				goto end;
+				}
+			/* Note that we must not free r if it was successfully
+			 * added to the chain (while we must free the main
+			 * certificate, since its reference count is increased
+			 * by SSL_CTX_use_certificate). */
+			}
+		/* When the while loop ends, it's usually just EOF. */
+		err = ERR_peek_last_error();
+		if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
+			ERR_clear_error();
+		else 
+			ret = 0; /* some real error */
+		}
+
+end:
+	if (x != NULL) X509_free(x);
+	if (in != NULL) BIO_free(in);
+	return(ret);
+	}
+#endif
diff --git a/openssl/ssl/ssl_sess.c b/openssl/ssl/ssl_sess.c
new file mode 100644
index 0000000..93954e4
--- /dev/null
+++ b/openssl/ssl/ssl_sess.c
@@ -0,0 +1,1102 @@
+/* ssl/ssl_sess.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include <openssl/lhash.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include "ssl_locl.h"
+
+static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
+static void SSL_SESSION_list_add(SSL_CTX *ctx,SSL_SESSION *s);
+static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
+
+SSL_SESSION *SSL_get_session(const SSL *ssl)
+/* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */
+	{
+	return(ssl->session);
+	}
+
+SSL_SESSION *SSL_get1_session(SSL *ssl)
+/* variant of SSL_get_session: caller really gets something */
+	{
+	SSL_SESSION *sess;
+	/* Need to lock this all up rather than just use CRYPTO_add so that
+	 * somebody doesn't free ssl->session between when we check it's
+	 * non-null and when we up the reference count. */
+	CRYPTO_w_lock(CRYPTO_LOCK_SSL_SESSION);
+	sess = ssl->session;
+	if(sess)
+		sess->references++;
+	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_SESSION);
+	return(sess);
+	}
+
+int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+	{
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, argl, argp,
+			new_func, dup_func, free_func);
+	}
+
+int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg)
+	{
+	return(CRYPTO_set_ex_data(&s->ex_data,idx,arg));
+	}
+
+void *SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx)
+	{
+	return(CRYPTO_get_ex_data(&s->ex_data,idx));
+	}
+
+SSL_SESSION *SSL_SESSION_new(void)
+	{
+	SSL_SESSION *ss;
+
+	ss=(SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION));
+	if (ss == NULL)
+		{
+		SSLerr(SSL_F_SSL_SESSION_NEW,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	memset(ss,0,sizeof(SSL_SESSION));
+
+	ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */
+	ss->references=1;
+	ss->timeout=60*5+4; /* 5 minute timeout by default */
+	ss->time=(unsigned long)time(NULL);
+	ss->prev=NULL;
+	ss->next=NULL;
+	ss->compress_meth=0;
+#ifndef OPENSSL_NO_TLSEXT
+	ss->tlsext_hostname = NULL; 
+#ifndef OPENSSL_NO_EC
+	ss->tlsext_ecpointformatlist_length = 0;
+	ss->tlsext_ecpointformatlist = NULL;
+	ss->tlsext_ellipticcurvelist_length = 0;
+	ss->tlsext_ellipticcurvelist = NULL;
+#endif
+#endif
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
+#ifndef OPENSSL_NO_PSK
+	ss->psk_identity_hint=NULL;
+	ss->psk_identity=NULL;
+#endif
+	return(ss);
+	}
+
+const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
+	{
+	if(len)
+		*len = s->session_id_length;
+	return s->session_id;
+	}
+
+/* Even with SSLv2, we have 16 bytes (128 bits) of session ID space. SSLv3/TLSv1
+ * has 32 bytes (256 bits). As such, filling the ID with random gunk repeatedly
+ * until we have no conflict is going to complete in one iteration pretty much
+ * "most" of the time (btw: understatement). So, if it takes us 10 iterations
+ * and we still can't avoid a conflict - well that's a reasonable point to call
+ * it quits. Either the RAND code is broken or someone is trying to open roughly
+ * very close to 2^128 (or 2^256) SSL sessions to our server. How you might
+ * store that many sessions is perhaps a more interesting question ... */
+
+#define MAX_SESS_ID_ATTEMPTS 10
+static int def_generate_session_id(const SSL *ssl, unsigned char *id,
+				unsigned int *id_len)
+{
+	unsigned int retry = 0;
+	do
+		if (RAND_pseudo_bytes(id, *id_len) <= 0)
+			return 0;
+	while(SSL_has_matching_session_id(ssl, id, *id_len) &&
+		(++retry < MAX_SESS_ID_ATTEMPTS));
+	if(retry < MAX_SESS_ID_ATTEMPTS)
+		return 1;
+	/* else - woops a session_id match */
+	/* XXX We should also check the external cache --
+	 * but the probability of a collision is negligible, and
+	 * we could not prevent the concurrent creation of sessions
+	 * with identical IDs since we currently don't have means
+	 * to atomically check whether a session ID already exists
+	 * and make a reservation for it if it does not
+	 * (this problem applies to the internal cache as well).
+	 */
+	return 0;
+}
+
+void SSL_set_session_creation_enabled (SSL *s, int creation_enabled)
+	{
+	s->session_creation_enabled = creation_enabled;
+	}
+
+int ssl_get_new_session(SSL *s, int session)
+	{
+	/* This gets used by clients and servers. */
+
+	unsigned int tmp;
+	SSL_SESSION *ss=NULL;
+	GEN_SESSION_CB cb = def_generate_session_id;
+
+	/* caller should check this if they can do better error handling */
+        if (!s->session_creation_enabled) return(0);
+	if ((ss=SSL_SESSION_new()) == NULL) return(0);
+
+	/* If the context has a default timeout, use it */
+	if (s->session_ctx->session_timeout == 0)
+		ss->timeout=SSL_get_default_timeout(s);
+	else
+		ss->timeout=s->session_ctx->session_timeout;
+
+	if (s->session != NULL)
+		{
+		SSL_SESSION_free(s->session);
+		s->session=NULL;
+		}
+
+	if (session)
+		{
+		if (s->version == SSL2_VERSION)
+			{
+			ss->ssl_version=SSL2_VERSION;
+			ss->session_id_length=SSL2_SSL_SESSION_ID_LENGTH;
+			}
+		else if (s->version == SSL3_VERSION)
+			{
+			ss->ssl_version=SSL3_VERSION;
+			ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
+			}
+		else if (s->version == TLS1_VERSION)
+			{
+			ss->ssl_version=TLS1_VERSION;
+			ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
+			}
+		else if (s->version == DTLS1_BAD_VER)
+			{
+			ss->ssl_version=DTLS1_BAD_VER;
+			ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
+			}
+		else if (s->version == DTLS1_VERSION)
+			{
+			ss->ssl_version=DTLS1_VERSION;
+			ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
+			}
+		else
+			{
+			SSLerr(SSL_F_SSL_GET_NEW_SESSION,SSL_R_UNSUPPORTED_SSL_VERSION);
+			SSL_SESSION_free(ss);
+			return(0);
+			}
+#ifndef OPENSSL_NO_TLSEXT
+		/* If RFC4507 ticket use empty session ID */
+		if (s->tlsext_ticket_expected)
+			{
+			ss->session_id_length = 0;
+			goto sess_id_done;
+			}
+#endif
+		/* Choose which callback will set the session ID */
+		CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
+		if(s->generate_session_id)
+			cb = s->generate_session_id;
+		else if(s->session_ctx->generate_session_id)
+			cb = s->session_ctx->generate_session_id;
+		CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
+		/* Choose a session ID */
+		tmp = ss->session_id_length;
+		if(!cb(s, ss->session_id, &tmp))
+			{
+			/* The callback failed */
+			SSLerr(SSL_F_SSL_GET_NEW_SESSION,
+				SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);
+			SSL_SESSION_free(ss);
+			return(0);
+			}
+		/* Don't allow the callback to set the session length to zero.
+		 * nor set it higher than it was. */
+		if(!tmp || (tmp > ss->session_id_length))
+			{
+			/* The callback set an illegal length */
+			SSLerr(SSL_F_SSL_GET_NEW_SESSION,
+				SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);
+			SSL_SESSION_free(ss);
+			return(0);
+			}
+		/* If the session length was shrunk and we're SSLv2, pad it */
+		if((tmp < ss->session_id_length) && (s->version == SSL2_VERSION))
+			memset(ss->session_id + tmp, 0, ss->session_id_length - tmp);
+		else
+			ss->session_id_length = tmp;
+		/* Finally, check for a conflict */
+		if(SSL_has_matching_session_id(s, ss->session_id,
+						ss->session_id_length))
+			{
+			SSLerr(SSL_F_SSL_GET_NEW_SESSION,
+				SSL_R_SSL_SESSION_ID_CONFLICT);
+			SSL_SESSION_free(ss);
+			return(0);
+			}
+#ifndef OPENSSL_NO_TLSEXT
+		sess_id_done:
+		if (s->tlsext_hostname) {
+			ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
+			if (ss->tlsext_hostname == NULL) {
+				SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR);
+				SSL_SESSION_free(ss);
+				return 0;
+				}
+			}
+#ifndef OPENSSL_NO_EC
+		if (s->tlsext_ecpointformatlist)
+			{
+			if (ss->tlsext_ecpointformatlist != NULL) OPENSSL_free(ss->tlsext_ecpointformatlist);
+			if ((ss->tlsext_ecpointformatlist = OPENSSL_malloc(s->tlsext_ecpointformatlist_length)) == NULL)
+				{
+				SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE);
+				SSL_SESSION_free(ss);
+				return 0;
+				}
+			ss->tlsext_ecpointformatlist_length = s->tlsext_ecpointformatlist_length;
+			memcpy(ss->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
+			}
+		if (s->tlsext_ellipticcurvelist)
+			{
+			if (ss->tlsext_ellipticcurvelist != NULL) OPENSSL_free(ss->tlsext_ellipticcurvelist);
+			if ((ss->tlsext_ellipticcurvelist = OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL)
+				{
+				SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE);
+				SSL_SESSION_free(ss);
+				return 0;
+				}
+			ss->tlsext_ellipticcurvelist_length = s->tlsext_ellipticcurvelist_length;
+			memcpy(ss->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
+			}
+#endif
+#endif
+		}
+	else
+		{
+		ss->session_id_length=0;
+		}
+
+	if (s->sid_ctx_length > sizeof ss->sid_ctx)
+		{
+		SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR);
+		SSL_SESSION_free(ss);
+		return 0;
+		}
+	memcpy(ss->sid_ctx,s->sid_ctx,s->sid_ctx_length);
+	ss->sid_ctx_length=s->sid_ctx_length;
+	s->session=ss;
+	ss->ssl_version=s->version;
+	ss->verify_result = X509_V_OK;
+
+	return(1);
+	}
+
+int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
+			const unsigned char *limit)
+	{
+	/* This is used only by servers. */
+
+	SSL_SESSION *ret=NULL;
+	int fatal = 0;
+#ifndef OPENSSL_NO_TLSEXT
+	int r;
+#endif
+
+	if (len > SSL_MAX_SSL_SESSION_ID_LENGTH)
+		goto err;
+#ifndef OPENSSL_NO_TLSEXT
+	r = tls1_process_ticket(s, session_id, len, limit, &ret);
+	if (r == -1)
+		{
+		fatal = 1;
+		goto err;
+		}
+	else if (r == 0 || (!ret && !len))
+		goto err;
+	else if (!ret && !(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
+#else
+	if (len == 0)
+		goto err;
+	if (!(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
+#endif
+		{
+		SSL_SESSION data;
+		data.ssl_version=s->version;
+		data.session_id_length=len;
+		if (len == 0)
+			return 0;
+		memcpy(data.session_id,session_id,len);
+		CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
+		ret=lh_SSL_SESSION_retrieve(s->session_ctx->sessions,&data);
+		if (ret != NULL)
+		    /* don't allow other threads to steal it: */
+		    CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
+		CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
+		}
+
+	if (ret == NULL)
+		{
+		int copy=1;
+	
+		s->session_ctx->stats.sess_miss++;
+		ret=NULL;
+		if (s->session_ctx->get_session_cb != NULL
+		    && (ret=s->session_ctx->get_session_cb(s,session_id,len,&copy))
+		       != NULL)
+			{
+			s->session_ctx->stats.sess_cb_hit++;
+
+			/* Increment reference count now if the session callback
+			 * asks us to do so (note that if the session structures
+			 * returned by the callback are shared between threads,
+			 * it must handle the reference count itself [i.e. copy == 0],
+			 * or things won't be thread-safe). */
+			if (copy)
+				CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
+
+			/* Add the externally cached session to the internal
+			 * cache as well if and only if we are supposed to. */
+			if(!(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE))
+				/* The following should not return 1, otherwise,
+				 * things are very strange */
+				SSL_CTX_add_session(s->session_ctx,ret);
+			}
+		if (ret == NULL)
+			goto err;
+		}
+
+	/* Now ret is non-NULL, and we own one of its reference counts. */
+
+	if (ret->sid_ctx_length != s->sid_ctx_length
+	    || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length))
+		{
+		/* We've found the session named by the client, but we don't
+		 * want to use it in this context. */
+
+#if 0 /* The client cannot always know when a session is not appropriate,
+       * so we shouldn't generate an error message. */
+
+		SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
+#endif
+		goto err; /* treat like cache miss */
+		}
+	
+	if((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0)
+		{
+		/* We can't be sure if this session is being used out of
+		 * context, which is especially important for SSL_VERIFY_PEER.
+		 * The application should have used SSL[_CTX]_set_session_id_context.
+		 *
+		 * For this error case, we generate an error instead of treating
+		 * the event like a cache miss (otherwise it would be easy for
+		 * applications to effectively disable the session cache by
+		 * accident without anyone noticing).
+		 */
+		
+		SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
+		fatal = 1;
+		goto err;
+		}
+
+	if (ret->cipher == NULL)
+		{
+		unsigned char buf[5],*p;
+		unsigned long l;
+
+		p=buf;
+		l=ret->cipher_id;
+		l2n(l,p);
+		if ((ret->ssl_version>>8) >= SSL3_VERSION_MAJOR)
+			ret->cipher=ssl_get_cipher_by_char(s,&(buf[2]));
+		else 
+			ret->cipher=ssl_get_cipher_by_char(s,&(buf[1]));
+		if (ret->cipher == NULL)
+			goto err;
+		}
+
+
+#if 0 /* This is way too late. */
+
+	/* If a thread got the session, then 'swaped', and another got
+	 * it and then due to a time-out decided to 'OPENSSL_free' it we could
+	 * be in trouble.  So I'll increment it now, then double decrement
+	 * later - am I speaking rubbish?. */
+	CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
+#endif
+
+	if (ret->timeout < (long)(time(NULL) - ret->time)) /* timeout */
+		{
+		s->session_ctx->stats.sess_timeout++;
+		/* remove it from the cache */
+		SSL_CTX_remove_session(s->session_ctx,ret);
+		goto err;
+		}
+
+	s->session_ctx->stats.sess_hit++;
+
+	/* ret->time=time(NULL); */ /* rezero timeout? */
+	/* again, just leave the session 
+	 * if it is the same session, we have just incremented and
+	 * then decremented the reference count :-) */
+	if (s->session != NULL)
+		SSL_SESSION_free(s->session);
+	s->session=ret;
+	s->verify_result = s->session->verify_result;
+	return(1);
+
+ err:
+	if (ret != NULL)
+		SSL_SESSION_free(ret);
+	if (fatal)
+		return -1;
+	else
+		return 0;
+	}
+
+int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
+	{
+	int ret=0;
+	SSL_SESSION *s;
+
+	/* add just 1 reference count for the SSL_CTX's session cache
+	 * even though it has two ways of access: each session is in a
+	 * doubly linked list and an lhash */
+	CRYPTO_add(&c->references,1,CRYPTO_LOCK_SSL_SESSION);
+	/* if session c is in already in cache, we take back the increment later */
+
+	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+	s=lh_SSL_SESSION_insert(ctx->sessions,c);
+	
+	/* s != NULL iff we already had a session with the given PID.
+	 * In this case, s == c should hold (then we did not really modify
+	 * ctx->sessions), or we're in trouble. */
+	if (s != NULL && s != c)
+		{
+		/* We *are* in trouble ... */
+		SSL_SESSION_list_remove(ctx,s);
+		SSL_SESSION_free(s);
+		/* ... so pretend the other session did not exist in cache
+		 * (we cannot handle two SSL_SESSION structures with identical
+		 * session ID in the same cache, which could happen e.g. when
+		 * two threads concurrently obtain the same session from an external
+		 * cache) */
+		s = NULL;
+		}
+
+ 	/* Put at the head of the queue unless it is already in the cache */
+	if (s == NULL)
+		SSL_SESSION_list_add(ctx,c);
+
+	if (s != NULL)
+		{
+		/* existing cache entry -- decrement previously incremented reference
+		 * count because it already takes into account the cache */
+
+		SSL_SESSION_free(s); /* s == c */
+		ret=0;
+		}
+	else
+		{
+		/* new cache entry -- remove old ones if cache has become too large */
+		
+		ret=1;
+
+		if (SSL_CTX_sess_get_cache_size(ctx) > 0)
+			{
+			while (SSL_CTX_sess_number(ctx) >
+				SSL_CTX_sess_get_cache_size(ctx))
+				{
+				if (!remove_session_lock(ctx,
+					ctx->session_cache_tail, 0))
+					break;
+				else
+					ctx->stats.sess_cache_full++;
+				}
+			}
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+	return(ret);
+	}
+
+int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c)
+{
+	return remove_session_lock(ctx, c, 1);
+}
+
+static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)
+	{
+	SSL_SESSION *r;
+	int ret=0;
+
+	if ((c != NULL) && (c->session_id_length != 0))
+		{
+		if(lck) CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+		if ((r = lh_SSL_SESSION_retrieve(ctx->sessions,c)) == c)
+			{
+			ret=1;
+			r=lh_SSL_SESSION_delete(ctx->sessions,c);
+			SSL_SESSION_list_remove(ctx,c);
+			}
+
+		if(lck) CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+
+		if (ret)
+			{
+			r->not_resumable=1;
+			if (ctx->remove_session_cb != NULL)
+				ctx->remove_session_cb(ctx,r);
+			SSL_SESSION_free(r);
+			}
+		}
+	else
+		ret=0;
+	return(ret);
+	}
+
+void SSL_SESSION_free(SSL_SESSION *ss)
+	{
+	int i;
+
+	if(ss == NULL)
+	    return;
+
+	i=CRYPTO_add(&ss->references,-1,CRYPTO_LOCK_SSL_SESSION);
+#ifdef REF_PRINT
+	REF_PRINT("SSL_SESSION",ss);
+#endif
+	if (i > 0) return;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"SSL_SESSION_free, bad reference count\n");
+		abort(); /* ok */
+		}
+#endif
+
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
+
+	OPENSSL_cleanse(ss->key_arg,sizeof ss->key_arg);
+	OPENSSL_cleanse(ss->master_key,sizeof ss->master_key);
+	OPENSSL_cleanse(ss->session_id,sizeof ss->session_id);
+	if (ss->sess_cert != NULL) ssl_sess_cert_free(ss->sess_cert);
+	if (ss->peer != NULL) X509_free(ss->peer);
+	if (ss->ciphers != NULL) sk_SSL_CIPHER_free(ss->ciphers);
+#ifndef OPENSSL_NO_TLSEXT
+	if (ss->tlsext_hostname != NULL) OPENSSL_free(ss->tlsext_hostname);
+	if (ss->tlsext_tick != NULL) OPENSSL_free(ss->tlsext_tick);
+#ifndef OPENSSL_NO_EC
+	ss->tlsext_ecpointformatlist_length = 0;
+	if (ss->tlsext_ecpointformatlist != NULL) OPENSSL_free(ss->tlsext_ecpointformatlist);
+	ss->tlsext_ellipticcurvelist_length = 0;
+	if (ss->tlsext_ellipticcurvelist != NULL) OPENSSL_free(ss->tlsext_ellipticcurvelist);
+#endif /* OPENSSL_NO_EC */
+#endif
+#ifndef OPENSSL_NO_PSK
+	if (ss->psk_identity_hint != NULL)
+		OPENSSL_free(ss->psk_identity_hint);
+	if (ss->psk_identity != NULL)
+		OPENSSL_free(ss->psk_identity);
+#endif
+	OPENSSL_cleanse(ss,sizeof(*ss));
+	OPENSSL_free(ss);
+	}
+
+int SSL_set_session(SSL *s, SSL_SESSION *session)
+	{
+	int ret=0;
+	const SSL_METHOD *meth;
+
+	if (session != NULL)
+		{
+		meth=s->ctx->method->get_ssl_method(session->ssl_version);
+		if (meth == NULL)
+			meth=s->method->get_ssl_method(session->ssl_version);
+		if (meth == NULL)
+			{
+			SSLerr(SSL_F_SSL_SET_SESSION,SSL_R_UNABLE_TO_FIND_SSL_METHOD);
+			return(0);
+			}
+
+		if (meth != s->method)
+			{
+			if (!SSL_set_ssl_method(s,meth))
+				return(0);
+			if (s->ctx->session_timeout == 0)
+				session->timeout=SSL_get_default_timeout(s);
+			else
+				session->timeout=s->ctx->session_timeout;
+			}
+
+#ifndef OPENSSL_NO_KRB5
+                if (s->kssl_ctx && !s->kssl_ctx->client_princ &&
+                    session->krb5_client_princ_len > 0)
+                {
+                    s->kssl_ctx->client_princ = (char *)OPENSSL_malloc(session->krb5_client_princ_len + 1);
+                    memcpy(s->kssl_ctx->client_princ,session->krb5_client_princ,
+                            session->krb5_client_princ_len);
+                    s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0';
+                }
+#endif /* OPENSSL_NO_KRB5 */
+
+		/* CRYPTO_w_lock(CRYPTO_LOCK_SSL);*/
+		CRYPTO_add(&session->references,1,CRYPTO_LOCK_SSL_SESSION);
+		if (s->session != NULL)
+			SSL_SESSION_free(s->session);
+		s->session=session;
+		s->verify_result = s->session->verify_result;
+		/* CRYPTO_w_unlock(CRYPTO_LOCK_SSL);*/
+		ret=1;
+		}
+	else
+		{
+		if (s->session != NULL)
+			{
+			SSL_SESSION_free(s->session);
+			s->session=NULL;
+			}
+
+		meth=s->ctx->method;
+		if (meth != s->method)
+			{
+			if (!SSL_set_ssl_method(s,meth))
+				return(0);
+			}
+		ret=1;
+		}
+	return(ret);
+	}
+
+long SSL_SESSION_set_timeout(SSL_SESSION *s, long t)
+	{
+	if (s == NULL) return(0);
+	s->timeout=t;
+	return(1);
+	}
+
+long SSL_SESSION_get_timeout(const SSL_SESSION *s)
+	{
+	if (s == NULL) return(0);
+	return(s->timeout);
+	}
+
+long SSL_SESSION_get_time(const SSL_SESSION *s)
+	{
+	if (s == NULL) return(0);
+	return(s->time);
+	}
+
+long SSL_SESSION_set_time(SSL_SESSION *s, long t)
+	{
+	if (s == NULL) return(0);
+	s->time=t;
+	return(t);
+	}
+
+long SSL_CTX_set_timeout(SSL_CTX *s, long t)
+	{
+	long l;
+	if (s == NULL) return(0);
+	l=s->session_timeout;
+	s->session_timeout=t;
+	return(l);
+	}
+
+long SSL_CTX_get_timeout(const SSL_CTX *s)
+	{
+	if (s == NULL) return(0);
+	return(s->session_timeout);
+	}
+
+#ifndef OPENSSL_NO_TLSEXT
+int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len,
+	STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg)
+	{
+	if (s == NULL) return(0);
+	s->tls_session_secret_cb = tls_session_secret_cb;
+	s->tls_session_secret_cb_arg = arg;
+	return(1);
+	}
+
+int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
+				  void *arg)
+	{
+	if (s == NULL) return(0);
+	s->tls_session_ticket_ext_cb = cb;
+	s->tls_session_ticket_ext_cb_arg = arg;
+	return(1);
+	}
+
+int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len)
+	{
+	if (s->version >= TLS1_VERSION)
+		{
+		if (s->tlsext_session_ticket)
+			{
+			OPENSSL_free(s->tlsext_session_ticket);
+			s->tlsext_session_ticket = NULL;
+			}
+
+		s->tlsext_session_ticket = OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len);
+		if (!s->tlsext_session_ticket)
+			{
+			SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+
+		if (ext_data)
+			{
+			s->tlsext_session_ticket->length = ext_len;
+			s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1;
+			memcpy(s->tlsext_session_ticket->data, ext_data, ext_len);
+			}
+		else
+			{
+			s->tlsext_session_ticket->length = 0;
+			s->tlsext_session_ticket->data = NULL;
+			}
+
+		return 1;
+		}
+
+	return 0;
+	}
+#endif /* OPENSSL_NO_TLSEXT */
+
+typedef struct timeout_param_st
+	{
+	SSL_CTX *ctx;
+	long time;
+	LHASH_OF(SSL_SESSION) *cache;
+	} TIMEOUT_PARAM;
+
+static void timeout_doall_arg(SSL_SESSION *s, TIMEOUT_PARAM *p)
+	{
+	if ((p->time == 0) || (p->time > (s->time+s->timeout))) /* timeout */
+		{
+		/* The reason we don't call SSL_CTX_remove_session() is to
+		 * save on locking overhead */
+		(void)lh_SSL_SESSION_delete(p->cache,s);
+		SSL_SESSION_list_remove(p->ctx,s);
+		s->not_resumable=1;
+		if (p->ctx->remove_session_cb != NULL)
+			p->ctx->remove_session_cb(p->ctx,s);
+		SSL_SESSION_free(s);
+		}
+	}
+
+static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION, TIMEOUT_PARAM)
+
+void SSL_CTX_flush_sessions(SSL_CTX *s, long t)
+	{
+	unsigned long i;
+	TIMEOUT_PARAM tp;
+
+	tp.ctx=s;
+	tp.cache=s->sessions;
+	if (tp.cache == NULL) return;
+	tp.time=t;
+	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+	i=CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load;
+	CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load=0;
+	lh_SSL_SESSION_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout),
+				 TIMEOUT_PARAM, &tp);
+	CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load=i;
+	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+	}
+
+int ssl_clear_bad_session(SSL *s)
+	{
+	if (	(s->session != NULL) &&
+		!(s->shutdown & SSL_SENT_SHUTDOWN) &&
+		!(SSL_in_init(s) || SSL_in_before(s)))
+		{
+		SSL_CTX_remove_session(s->ctx,s->session);
+		return(1);
+		}
+	else
+		return(0);
+	}
+
+/* locked by SSL_CTX in the calling function */
+static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s)
+	{
+	if ((s->next == NULL) || (s->prev == NULL)) return;
+
+	if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail))
+		{ /* last element in list */
+		if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head))
+			{ /* only one element in list */
+			ctx->session_cache_head=NULL;
+			ctx->session_cache_tail=NULL;
+			}
+		else
+			{
+			ctx->session_cache_tail=s->prev;
+			s->prev->next=(SSL_SESSION *)&(ctx->session_cache_tail);
+			}
+		}
+	else
+		{
+		if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head))
+			{ /* first element in list */
+			ctx->session_cache_head=s->next;
+			s->next->prev=(SSL_SESSION *)&(ctx->session_cache_head);
+			}
+		else
+			{ /* middle of list */
+			s->next->prev=s->prev;
+			s->prev->next=s->next;
+			}
+		}
+	s->prev=s->next=NULL;
+	}
+
+static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s)
+	{
+	if ((s->next != NULL) && (s->prev != NULL))
+		SSL_SESSION_list_remove(ctx,s);
+
+	if (ctx->session_cache_head == NULL)
+		{
+		ctx->session_cache_head=s;
+		ctx->session_cache_tail=s;
+		s->prev=(SSL_SESSION *)&(ctx->session_cache_head);
+		s->next=(SSL_SESSION *)&(ctx->session_cache_tail);
+		}
+	else
+		{
+		s->next=ctx->session_cache_head;
+		s->next->prev=s;
+		s->prev=(SSL_SESSION *)&(ctx->session_cache_head);
+		ctx->session_cache_head=s;
+		}
+	}
+
+void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
+	int (*cb)(struct ssl_st *ssl,SSL_SESSION *sess))
+	{
+	ctx->new_session_cb=cb;
+	}
+
+int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *sess)
+	{
+	return ctx->new_session_cb;
+	}
+
+void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
+	void (*cb)(SSL_CTX *ctx,SSL_SESSION *sess))
+	{
+	ctx->remove_session_cb=cb;
+	}
+
+void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX * ctx,SSL_SESSION *sess)
+	{
+	return ctx->remove_session_cb;
+	}
+
+void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
+	SSL_SESSION *(*cb)(struct ssl_st *ssl,
+	         unsigned char *data,int len,int *copy))
+	{
+	ctx->get_session_cb=cb;
+	}
+
+SSL_SESSION * (*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(SSL *ssl,
+	         unsigned char *data,int len,int *copy)
+	{
+	return ctx->get_session_cb;
+	}
+
+void SSL_CTX_set_info_callback(SSL_CTX *ctx, 
+	void (*cb)(const SSL *ssl,int type,int val))
+	{
+	ctx->info_callback=cb;
+	}
+
+void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val)
+	{
+	return ctx->info_callback;
+	}
+
+void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx,
+	int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey))
+	{
+	ctx->client_cert_cb=cb;
+	}
+
+int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL * ssl, X509 ** x509 , EVP_PKEY **pkey)
+	{
+	return ctx->client_cert_cb;
+	}
+
+#ifndef OPENSSL_NO_ENGINE
+int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e)
+	{
+	if (!ENGINE_init(e))
+		{
+		SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB);
+		return 0;
+		}
+	if(!ENGINE_get_ssl_client_cert_function(e))
+		{
+		SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, SSL_R_NO_CLIENT_CERT_METHOD);
+		ENGINE_finish(e);
+		return 0;
+		}
+	ctx->client_cert_engine = e;
+	return 1;
+	}
+#endif
+
+void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx,
+	int (*cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len))
+	{
+	ctx->app_gen_cookie_cb=cb;
+	}
+
+void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx,
+	int (*cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len))
+	{
+	ctx->app_verify_cookie_cb=cb;
+	}
+
+IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
diff --git a/openssl/ssl/ssl_stat.c b/openssl/ssl/ssl_stat.c
new file mode 100644
index 0000000..144b81e
--- /dev/null
+++ b/openssl/ssl/ssl_stat.c
@@ -0,0 +1,567 @@
+/* ssl/ssl_stat.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include "ssl_locl.h"
+
+const char *SSL_state_string_long(const SSL *s)
+	{
+	const char *str;
+
+	switch (s->state)
+		{
+case SSL_ST_BEFORE: str="before SSL initialization"; break;
+case SSL_ST_ACCEPT: str="before accept initialization"; break;
+case SSL_ST_CONNECT: str="before connect initialization"; break;
+case SSL_ST_OK: str="SSL negotiation finished successfully"; break;
+case SSL_ST_RENEGOTIATE:	str="SSL renegotiate ciphers"; break;
+case SSL_ST_BEFORE|SSL_ST_CONNECT: str="before/connect initialization"; break;
+case SSL_ST_OK|SSL_ST_CONNECT: str="ok/connect SSL initialization"; break;
+case SSL_ST_BEFORE|SSL_ST_ACCEPT: str="before/accept initialization"; break;
+case SSL_ST_OK|SSL_ST_ACCEPT: str="ok/accept SSL initialization"; break;
+#ifndef OPENSSL_NO_SSL2
+case SSL2_ST_CLIENT_START_ENCRYPTION: str="SSLv2 client start encryption"; break;
+case SSL2_ST_SERVER_START_ENCRYPTION: str="SSLv2 server start encryption"; break;
+case SSL2_ST_SEND_CLIENT_HELLO_A: str="SSLv2 write client hello A"; break;
+case SSL2_ST_SEND_CLIENT_HELLO_B: str="SSLv2 write client hello B"; break;
+case SSL2_ST_GET_SERVER_HELLO_A: str="SSLv2 read server hello A"; break;
+case SSL2_ST_GET_SERVER_HELLO_B: str="SSLv2 read server hello B"; break;
+case SSL2_ST_SEND_CLIENT_MASTER_KEY_A: str="SSLv2 write client master key A"; break;
+case SSL2_ST_SEND_CLIENT_MASTER_KEY_B: str="SSLv2 write client master key B"; break;
+case SSL2_ST_SEND_CLIENT_FINISHED_A: str="SSLv2 write client finished A"; break;
+case SSL2_ST_SEND_CLIENT_FINISHED_B: str="SSLv2 write client finished B"; break;
+case SSL2_ST_SEND_CLIENT_CERTIFICATE_A: str="SSLv2 write client certificate A"; break;
+case SSL2_ST_SEND_CLIENT_CERTIFICATE_B: str="SSLv2 write client certificate B"; break;
+case SSL2_ST_SEND_CLIENT_CERTIFICATE_C: str="SSLv2 write client certificate C"; break;
+case SSL2_ST_SEND_CLIENT_CERTIFICATE_D: str="SSLv2 write client certificate D"; break;
+case SSL2_ST_GET_SERVER_VERIFY_A: str="SSLv2 read server verify A"; break;
+case SSL2_ST_GET_SERVER_VERIFY_B: str="SSLv2 read server verify B"; break;
+case SSL2_ST_GET_SERVER_FINISHED_A: str="SSLv2 read server finished A"; break;
+case SSL2_ST_GET_SERVER_FINISHED_B: str="SSLv2 read server finished B"; break;
+case SSL2_ST_GET_CLIENT_HELLO_A: str="SSLv2 read client hello A"; break;
+case SSL2_ST_GET_CLIENT_HELLO_B: str="SSLv2 read client hello B"; break;
+case SSL2_ST_GET_CLIENT_HELLO_C: str="SSLv2 read client hello C"; break;
+case SSL2_ST_SEND_SERVER_HELLO_A: str="SSLv2 write server hello A"; break;
+case SSL2_ST_SEND_SERVER_HELLO_B: str="SSLv2 write server hello B"; break;
+case SSL2_ST_GET_CLIENT_MASTER_KEY_A: str="SSLv2 read client master key A"; break;
+case SSL2_ST_GET_CLIENT_MASTER_KEY_B: str="SSLv2 read client master key B"; break;
+case SSL2_ST_SEND_SERVER_VERIFY_A: str="SSLv2 write server verify A"; break;
+case SSL2_ST_SEND_SERVER_VERIFY_B: str="SSLv2 write server verify B"; break;
+case SSL2_ST_SEND_SERVER_VERIFY_C: str="SSLv2 write server verify C"; break;
+case SSL2_ST_GET_CLIENT_FINISHED_A: str="SSLv2 read client finished A"; break;
+case SSL2_ST_GET_CLIENT_FINISHED_B: str="SSLv2 read client finished B"; break;
+case SSL2_ST_SEND_SERVER_FINISHED_A: str="SSLv2 write server finished A"; break;
+case SSL2_ST_SEND_SERVER_FINISHED_B: str="SSLv2 write server finished B"; break;
+case SSL2_ST_SEND_REQUEST_CERTIFICATE_A: str="SSLv2 write request certificate A"; break;
+case SSL2_ST_SEND_REQUEST_CERTIFICATE_B: str="SSLv2 write request certificate B"; break;
+case SSL2_ST_SEND_REQUEST_CERTIFICATE_C: str="SSLv2 write request certificate C"; break;
+case SSL2_ST_SEND_REQUEST_CERTIFICATE_D: str="SSLv2 write request certificate D"; break;
+case SSL2_ST_X509_GET_SERVER_CERTIFICATE: str="SSLv2 X509 read server certificate"; break;
+case SSL2_ST_X509_GET_CLIENT_CERTIFICATE: str="SSLv2 X509 read client certificate"; break;
+#endif
+
+#ifndef OPENSSL_NO_SSL3
+/* SSLv3 additions */
+case SSL3_ST_CW_CLNT_HELLO_A:	str="SSLv3 write client hello A"; break;
+case SSL3_ST_CW_CLNT_HELLO_B:	str="SSLv3 write client hello B"; break;
+case SSL3_ST_CR_SRVR_HELLO_A:	str="SSLv3 read server hello A"; break;
+case SSL3_ST_CR_SRVR_HELLO_B:	str="SSLv3 read server hello B"; break;
+case SSL3_ST_CR_CERT_A:		str="SSLv3 read server certificate A"; break;
+case SSL3_ST_CR_CERT_B:		str="SSLv3 read server certificate B"; break;
+case SSL3_ST_CR_KEY_EXCH_A:	str="SSLv3 read server key exchange A"; break;
+case SSL3_ST_CR_KEY_EXCH_B:	str="SSLv3 read server key exchange B"; break;
+case SSL3_ST_CR_CERT_REQ_A:	str="SSLv3 read server certificate request A"; break;
+case SSL3_ST_CR_CERT_REQ_B:	str="SSLv3 read server certificate request B"; break;
+case SSL3_ST_CR_SESSION_TICKET_A: str="SSLv3 read server session ticket A";break;
+case SSL3_ST_CR_SESSION_TICKET_B: str="SSLv3 read server session ticket B";break;
+case SSL3_ST_CR_SRVR_DONE_A:	str="SSLv3 read server done A"; break;
+case SSL3_ST_CR_SRVR_DONE_B:	str="SSLv3 read server done B"; break;
+case SSL3_ST_CW_CERT_A:		str="SSLv3 write client certificate A"; break;
+case SSL3_ST_CW_CERT_B:		str="SSLv3 write client certificate B"; break;
+case SSL3_ST_CW_CERT_C:		str="SSLv3 write client certificate C"; break;
+case SSL3_ST_CW_CERT_D:		str="SSLv3 write client certificate D"; break;
+case SSL3_ST_CW_KEY_EXCH_A:	str="SSLv3 write client key exchange A"; break;
+case SSL3_ST_CW_KEY_EXCH_B:	str="SSLv3 write client key exchange B"; break;
+case SSL3_ST_CW_CERT_VRFY_A:	str="SSLv3 write certificate verify A"; break;
+case SSL3_ST_CW_CERT_VRFY_B:	str="SSLv3 write certificate verify B"; break;
+
+case SSL3_ST_CW_CHANGE_A:
+case SSL3_ST_SW_CHANGE_A:	str="SSLv3 write change cipher spec A"; break;
+case SSL3_ST_CW_CHANGE_B:	
+case SSL3_ST_SW_CHANGE_B:	str="SSLv3 write change cipher spec B"; break;
+case SSL3_ST_CW_FINISHED_A:	
+case SSL3_ST_SW_FINISHED_A:	str="SSLv3 write finished A"; break;
+case SSL3_ST_CW_FINISHED_B:	
+case SSL3_ST_SW_FINISHED_B:	str="SSLv3 write finished B"; break;
+case SSL3_ST_CR_CHANGE_A:	
+case SSL3_ST_SR_CHANGE_A:	str="SSLv3 read change cipher spec A"; break;
+case SSL3_ST_CR_CHANGE_B:	
+case SSL3_ST_SR_CHANGE_B:	str="SSLv3 read change cipher spec B"; break;
+case SSL3_ST_CR_FINISHED_A:	
+case SSL3_ST_SR_FINISHED_A:	str="SSLv3 read finished A"; break;
+case SSL3_ST_CR_FINISHED_B:	
+case SSL3_ST_SR_FINISHED_B:	str="SSLv3 read finished B"; break;
+
+case SSL3_ST_CW_FLUSH:
+case SSL3_ST_SW_FLUSH:		str="SSLv3 flush data"; break;
+
+case SSL3_ST_SR_CLNT_HELLO_A:	str="SSLv3 read client hello A"; break;
+case SSL3_ST_SR_CLNT_HELLO_B:	str="SSLv3 read client hello B"; break;
+case SSL3_ST_SR_CLNT_HELLO_C:	str="SSLv3 read client hello C"; break;
+case SSL3_ST_SW_HELLO_REQ_A:	str="SSLv3 write hello request A"; break;
+case SSL3_ST_SW_HELLO_REQ_B:	str="SSLv3 write hello request B"; break;
+case SSL3_ST_SW_HELLO_REQ_C:	str="SSLv3 write hello request C"; break;
+case SSL3_ST_SW_SRVR_HELLO_A:	str="SSLv3 write server hello A"; break;
+case SSL3_ST_SW_SRVR_HELLO_B:	str="SSLv3 write server hello B"; break;
+case SSL3_ST_SW_CERT_A:		str="SSLv3 write certificate A"; break;
+case SSL3_ST_SW_CERT_B:		str="SSLv3 write certificate B"; break;
+case SSL3_ST_SW_KEY_EXCH_A:	str="SSLv3 write key exchange A"; break;
+case SSL3_ST_SW_KEY_EXCH_B:	str="SSLv3 write key exchange B"; break;
+case SSL3_ST_SW_CERT_REQ_A:	str="SSLv3 write certificate request A"; break;
+case SSL3_ST_SW_CERT_REQ_B:	str="SSLv3 write certificate request B"; break;
+case SSL3_ST_SW_SESSION_TICKET_A: str="SSLv3 write session ticket A"; break;
+case SSL3_ST_SW_SESSION_TICKET_B: str="SSLv3 write session ticket B"; break;
+case SSL3_ST_SW_SRVR_DONE_A:	str="SSLv3 write server done A"; break;
+case SSL3_ST_SW_SRVR_DONE_B:	str="SSLv3 write server done B"; break;
+case SSL3_ST_SR_CERT_A:		str="SSLv3 read client certificate A"; break;
+case SSL3_ST_SR_CERT_B:		str="SSLv3 read client certificate B"; break;
+case SSL3_ST_SR_KEY_EXCH_A:	str="SSLv3 read client key exchange A"; break;
+case SSL3_ST_SR_KEY_EXCH_B:	str="SSLv3 read client key exchange B"; break;
+case SSL3_ST_SR_CERT_VRFY_A:	str="SSLv3 read certificate verify A"; break;
+case SSL3_ST_SR_CERT_VRFY_B:	str="SSLv3 read certificate verify B"; break;
+#endif
+
+#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
+/* SSLv2/v3 compatibility states */
+/* client */
+case SSL23_ST_CW_CLNT_HELLO_A:	str="SSLv2/v3 write client hello A"; break;
+case SSL23_ST_CW_CLNT_HELLO_B:	str="SSLv2/v3 write client hello B"; break;
+case SSL23_ST_CR_SRVR_HELLO_A:	str="SSLv2/v3 read server hello A"; break;
+case SSL23_ST_CR_SRVR_HELLO_B:	str="SSLv2/v3 read server hello B"; break;
+/* server */
+case SSL23_ST_SR_CLNT_HELLO_A:	str="SSLv2/v3 read client hello A"; break;
+case SSL23_ST_SR_CLNT_HELLO_B:	str="SSLv2/v3 read client hello B"; break;
+#endif
+
+/* DTLS */
+case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: str="DTLS1 read hello verify request A"; break;
+case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: str="DTLS1 read hello verify request B"; break;
+case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: str="DTLS1 write hello verify request A"; break;
+case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: str="DTLS1 write hello verify request B"; break;
+
+default:	str="unknown state"; break;
+		}
+	return(str);
+	}
+
+const char *SSL_rstate_string_long(const SSL *s)
+	{
+	const char *str;
+
+	switch (s->rstate)
+		{
+	case SSL_ST_READ_HEADER: str="read header"; break;
+	case SSL_ST_READ_BODY: str="read body"; break;
+	case SSL_ST_READ_DONE: str="read done"; break;
+	default: str="unknown"; break;
+		}
+	return(str);
+	}
+
+const char *SSL_state_string(const SSL *s)
+	{
+	const char *str;
+
+	switch (s->state)
+		{
+case SSL_ST_BEFORE:				str="PINIT "; break;
+case SSL_ST_ACCEPT:				str="AINIT "; break;
+case SSL_ST_CONNECT:				str="CINIT "; break;
+case SSL_ST_OK:			 		str="SSLOK "; break;
+#ifndef OPENSSL_NO_SSL2
+case SSL2_ST_CLIENT_START_ENCRYPTION:		str="2CSENC"; break;
+case SSL2_ST_SERVER_START_ENCRYPTION:		str="2SSENC"; break;
+case SSL2_ST_SEND_CLIENT_HELLO_A:		str="2SCH_A"; break;
+case SSL2_ST_SEND_CLIENT_HELLO_B:		str="2SCH_B"; break;
+case SSL2_ST_GET_SERVER_HELLO_A:		str="2GSH_A"; break;
+case SSL2_ST_GET_SERVER_HELLO_B:		str="2GSH_B"; break;
+case SSL2_ST_SEND_CLIENT_MASTER_KEY_A:		str="2SCMKA"; break;
+case SSL2_ST_SEND_CLIENT_MASTER_KEY_B:		str="2SCMKB"; break;
+case SSL2_ST_SEND_CLIENT_FINISHED_A:		str="2SCF_A"; break;
+case SSL2_ST_SEND_CLIENT_FINISHED_B:		str="2SCF_B"; break;
+case SSL2_ST_SEND_CLIENT_CERTIFICATE_A:		str="2SCC_A"; break;
+case SSL2_ST_SEND_CLIENT_CERTIFICATE_B:		str="2SCC_B"; break;
+case SSL2_ST_SEND_CLIENT_CERTIFICATE_C:		str="2SCC_C"; break;
+case SSL2_ST_SEND_CLIENT_CERTIFICATE_D:		str="2SCC_D"; break;
+case SSL2_ST_GET_SERVER_VERIFY_A:		str="2GSV_A"; break;
+case SSL2_ST_GET_SERVER_VERIFY_B:		str="2GSV_B"; break;
+case SSL2_ST_GET_SERVER_FINISHED_A:		str="2GSF_A"; break;
+case SSL2_ST_GET_SERVER_FINISHED_B:		str="2GSF_B"; break;
+case SSL2_ST_GET_CLIENT_HELLO_A:		str="2GCH_A"; break;
+case SSL2_ST_GET_CLIENT_HELLO_B:		str="2GCH_B"; break;
+case SSL2_ST_GET_CLIENT_HELLO_C:		str="2GCH_C"; break;
+case SSL2_ST_SEND_SERVER_HELLO_A:		str="2SSH_A"; break;
+case SSL2_ST_SEND_SERVER_HELLO_B:		str="2SSH_B"; break;
+case SSL2_ST_GET_CLIENT_MASTER_KEY_A:		str="2GCMKA"; break;
+case SSL2_ST_GET_CLIENT_MASTER_KEY_B:		str="2GCMKA"; break;
+case SSL2_ST_SEND_SERVER_VERIFY_A:		str="2SSV_A"; break;
+case SSL2_ST_SEND_SERVER_VERIFY_B:		str="2SSV_B"; break;
+case SSL2_ST_SEND_SERVER_VERIFY_C:		str="2SSV_C"; break;
+case SSL2_ST_GET_CLIENT_FINISHED_A:		str="2GCF_A"; break;
+case SSL2_ST_GET_CLIENT_FINISHED_B:		str="2GCF_B"; break;
+case SSL2_ST_SEND_SERVER_FINISHED_A:		str="2SSF_A"; break;
+case SSL2_ST_SEND_SERVER_FINISHED_B:		str="2SSF_B"; break;
+case SSL2_ST_SEND_REQUEST_CERTIFICATE_A:	str="2SRC_A"; break;
+case SSL2_ST_SEND_REQUEST_CERTIFICATE_B:	str="2SRC_B"; break;
+case SSL2_ST_SEND_REQUEST_CERTIFICATE_C:	str="2SRC_C"; break;
+case SSL2_ST_SEND_REQUEST_CERTIFICATE_D:	str="2SRC_D"; break;
+case SSL2_ST_X509_GET_SERVER_CERTIFICATE:	str="2X9GSC"; break;
+case SSL2_ST_X509_GET_CLIENT_CERTIFICATE:	str="2X9GCC"; break;
+#endif
+
+#ifndef OPENSSL_NO_SSL3
+/* SSLv3 additions */
+case SSL3_ST_SW_FLUSH:
+case SSL3_ST_CW_FLUSH:				str="3FLUSH"; break;
+case SSL3_ST_CW_CLNT_HELLO_A:			str="3WCH_A"; break;
+case SSL3_ST_CW_CLNT_HELLO_B:			str="3WCH_B"; break;
+case SSL3_ST_CR_SRVR_HELLO_A:			str="3RSH_A"; break;
+case SSL3_ST_CR_SRVR_HELLO_B:			str="3RSH_B"; break;
+case SSL3_ST_CR_CERT_A:				str="3RSC_A"; break;
+case SSL3_ST_CR_CERT_B:				str="3RSC_B"; break;
+case SSL3_ST_CR_KEY_EXCH_A:			str="3RSKEA"; break;
+case SSL3_ST_CR_KEY_EXCH_B:			str="3RSKEB"; break;
+case SSL3_ST_CR_CERT_REQ_A:			str="3RCR_A"; break;
+case SSL3_ST_CR_CERT_REQ_B:			str="3RCR_B"; break;
+case SSL3_ST_CR_SRVR_DONE_A:			str="3RSD_A"; break;
+case SSL3_ST_CR_SRVR_DONE_B:			str="3RSD_B"; break;
+case SSL3_ST_CW_CERT_A:				str="3WCC_A"; break;
+case SSL3_ST_CW_CERT_B:				str="3WCC_B"; break;
+case SSL3_ST_CW_CERT_C:				str="3WCC_C"; break;
+case SSL3_ST_CW_CERT_D:				str="3WCC_D"; break;
+case SSL3_ST_CW_KEY_EXCH_A:			str="3WCKEA"; break;
+case SSL3_ST_CW_KEY_EXCH_B:			str="3WCKEB"; break;
+case SSL3_ST_CW_CERT_VRFY_A:			str="3WCV_A"; break;
+case SSL3_ST_CW_CERT_VRFY_B:			str="3WCV_B"; break;
+
+case SSL3_ST_SW_CHANGE_A:
+case SSL3_ST_CW_CHANGE_A:			str="3WCCSA"; break;
+case SSL3_ST_SW_CHANGE_B:
+case SSL3_ST_CW_CHANGE_B:			str="3WCCSB"; break;
+case SSL3_ST_SW_FINISHED_A:
+case SSL3_ST_CW_FINISHED_A:			str="3WFINA"; break;
+case SSL3_ST_SW_FINISHED_B:
+case SSL3_ST_CW_FINISHED_B:			str="3WFINB"; break;
+case SSL3_ST_SR_CHANGE_A:
+case SSL3_ST_CR_CHANGE_A:			str="3RCCSA"; break;
+case SSL3_ST_SR_CHANGE_B:
+case SSL3_ST_CR_CHANGE_B:			str="3RCCSB"; break;
+case SSL3_ST_SR_FINISHED_A:
+case SSL3_ST_CR_FINISHED_A:			str="3RFINA"; break;
+case SSL3_ST_SR_FINISHED_B:
+case SSL3_ST_CR_FINISHED_B:			str="3RFINB"; break;
+
+case SSL3_ST_SW_HELLO_REQ_A:			str="3WHR_A"; break;
+case SSL3_ST_SW_HELLO_REQ_B:			str="3WHR_B"; break;
+case SSL3_ST_SW_HELLO_REQ_C:			str="3WHR_C"; break;
+case SSL3_ST_SR_CLNT_HELLO_A:			str="3RCH_A"; break;
+case SSL3_ST_SR_CLNT_HELLO_B:			str="3RCH_B"; break;
+case SSL3_ST_SR_CLNT_HELLO_C:			str="3RCH_C"; break;
+case SSL3_ST_SW_SRVR_HELLO_A:			str="3WSH_A"; break;
+case SSL3_ST_SW_SRVR_HELLO_B:			str="3WSH_B"; break;
+case SSL3_ST_SW_CERT_A:				str="3WSC_A"; break;
+case SSL3_ST_SW_CERT_B:				str="3WSC_B"; break;
+case SSL3_ST_SW_KEY_EXCH_A:			str="3WSKEA"; break;
+case SSL3_ST_SW_KEY_EXCH_B:			str="3WSKEB"; break;
+case SSL3_ST_SW_CERT_REQ_A:			str="3WCR_A"; break;
+case SSL3_ST_SW_CERT_REQ_B:			str="3WCR_B"; break;
+case SSL3_ST_SW_SRVR_DONE_A:			str="3WSD_A"; break;
+case SSL3_ST_SW_SRVR_DONE_B:			str="3WSD_B"; break;
+case SSL3_ST_SR_CERT_A:				str="3RCC_A"; break;
+case SSL3_ST_SR_CERT_B:				str="3RCC_B"; break;
+case SSL3_ST_SR_KEY_EXCH_A:			str="3RCKEA"; break;
+case SSL3_ST_SR_KEY_EXCH_B:			str="3RCKEB"; break;
+case SSL3_ST_SR_CERT_VRFY_A:			str="3RCV_A"; break;
+case SSL3_ST_SR_CERT_VRFY_B:			str="3RCV_B"; break;
+#endif
+
+#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
+/* SSLv2/v3 compatibility states */
+/* client */
+case SSL23_ST_CW_CLNT_HELLO_A:			str="23WCHA"; break;
+case SSL23_ST_CW_CLNT_HELLO_B:			str="23WCHB"; break;
+case SSL23_ST_CR_SRVR_HELLO_A:			str="23RSHA"; break;
+case SSL23_ST_CR_SRVR_HELLO_B:			str="23RSHA"; break;
+/* server */
+case SSL23_ST_SR_CLNT_HELLO_A:			str="23RCHA"; break;
+case SSL23_ST_SR_CLNT_HELLO_B:			str="23RCHB"; break;
+#endif
+/* DTLS */
+case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: str="DRCHVA"; break;
+case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: str="DRCHVB"; break;
+case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: str="DWCHVA"; break;
+case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: str="DWCHVB"; break;
+
+default:					str="UNKWN "; break;
+		}
+	return(str);
+	}
+
+const char *SSL_alert_type_string_long(int value)
+	{
+	value>>=8;
+	if (value == SSL3_AL_WARNING)
+		return("warning");
+	else if (value == SSL3_AL_FATAL)
+		return("fatal");
+	else
+		return("unknown");
+	}
+
+const char *SSL_alert_type_string(int value)
+	{
+	value>>=8;
+	if (value == SSL3_AL_WARNING)
+		return("W");
+	else if (value == SSL3_AL_FATAL)
+		return("F");
+	else
+		return("U");
+	}
+
+const char *SSL_alert_desc_string(int value)
+	{
+	const char *str;
+
+	switch (value & 0xff)
+		{
+	case SSL3_AD_CLOSE_NOTIFY:		str="CN"; break;
+	case SSL3_AD_UNEXPECTED_MESSAGE:	str="UM"; break;
+	case SSL3_AD_BAD_RECORD_MAC:		str="BM"; break;
+	case SSL3_AD_DECOMPRESSION_FAILURE:	str="DF"; break;
+	case SSL3_AD_HANDSHAKE_FAILURE:		str="HF"; break;
+	case SSL3_AD_NO_CERTIFICATE:		str="NC"; break;
+	case SSL3_AD_BAD_CERTIFICATE:		str="BC"; break;
+	case SSL3_AD_UNSUPPORTED_CERTIFICATE:	str="UC"; break;
+	case SSL3_AD_CERTIFICATE_REVOKED:	str="CR"; break;
+	case SSL3_AD_CERTIFICATE_EXPIRED:	str="CE"; break;
+	case SSL3_AD_CERTIFICATE_UNKNOWN:	str="CU"; break;
+	case SSL3_AD_ILLEGAL_PARAMETER:		str="IP"; break;
+	case TLS1_AD_DECRYPTION_FAILED:		str="DC"; break;
+	case TLS1_AD_RECORD_OVERFLOW:		str="RO"; break;
+	case TLS1_AD_UNKNOWN_CA:		str="CA"; break;
+	case TLS1_AD_ACCESS_DENIED:		str="AD"; break;
+	case TLS1_AD_DECODE_ERROR:		str="DE"; break;
+	case TLS1_AD_DECRYPT_ERROR:		str="CY"; break;
+	case TLS1_AD_EXPORT_RESTRICTION:	str="ER"; break;
+	case TLS1_AD_PROTOCOL_VERSION:		str="PV"; break;
+	case TLS1_AD_INSUFFICIENT_SECURITY:	str="IS"; break;
+	case TLS1_AD_INTERNAL_ERROR:		str="IE"; break;
+	case TLS1_AD_USER_CANCELLED:		str="US"; break;
+	case TLS1_AD_NO_RENEGOTIATION:		str="NR"; break;
+	case TLS1_AD_UNSUPPORTED_EXTENSION:	str="UE"; break;
+	case TLS1_AD_CERTIFICATE_UNOBTAINABLE:	str="CO"; break;
+	case TLS1_AD_UNRECOGNIZED_NAME:		str="UN"; break;
+	case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: str="BR"; break;
+	case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: str="BH"; break;
+	case TLS1_AD_UNKNOWN_PSK_IDENTITY:	str="UP"; break;
+	default:				str="UK"; break;
+		}
+	return(str);
+	}
+
+const char *SSL_alert_desc_string_long(int value)
+	{
+	const char *str;
+
+	switch (value & 0xff)
+		{
+	case SSL3_AD_CLOSE_NOTIFY:
+		str="close notify";
+		break;
+	case SSL3_AD_UNEXPECTED_MESSAGE:
+		str="unexpected_message";
+		break;
+	case SSL3_AD_BAD_RECORD_MAC:
+		str="bad record mac";
+		break;
+	case SSL3_AD_DECOMPRESSION_FAILURE:
+		str="decompression failure";
+		break;
+	case SSL3_AD_HANDSHAKE_FAILURE:
+		str="handshake failure";
+		break;
+	case SSL3_AD_NO_CERTIFICATE:
+		str="no certificate";
+		break;
+	case SSL3_AD_BAD_CERTIFICATE:
+		str="bad certificate";
+		break;
+	case SSL3_AD_UNSUPPORTED_CERTIFICATE:
+		str="unsupported certificate";
+		break;
+	case SSL3_AD_CERTIFICATE_REVOKED:
+		str="certificate revoked";
+		break;
+	case SSL3_AD_CERTIFICATE_EXPIRED:
+		str="certificate expired";
+		break;
+	case SSL3_AD_CERTIFICATE_UNKNOWN:
+		str="certificate unknown";
+		break;
+	case SSL3_AD_ILLEGAL_PARAMETER:
+		str="illegal parameter";
+		break;
+	case TLS1_AD_DECRYPTION_FAILED:
+		str="decryption failed";
+		break;
+	case TLS1_AD_RECORD_OVERFLOW:
+		str="record overflow";
+		break;
+	case TLS1_AD_UNKNOWN_CA:
+		str="unknown CA";
+		break;
+	case TLS1_AD_ACCESS_DENIED:
+		str="access denied";
+		break;
+	case TLS1_AD_DECODE_ERROR:
+		str="decode error";
+		break;
+	case TLS1_AD_DECRYPT_ERROR:
+		str="decrypt error";
+		break;
+	case TLS1_AD_EXPORT_RESTRICTION:
+		str="export restriction";
+		break;
+	case TLS1_AD_PROTOCOL_VERSION:
+		str="protocol version";
+		break;
+	case TLS1_AD_INSUFFICIENT_SECURITY:
+		str="insufficient security";
+		break;
+	case TLS1_AD_INTERNAL_ERROR:
+		str="internal error";
+		break;
+	case TLS1_AD_USER_CANCELLED:
+		str="user canceled";
+		break;
+	case TLS1_AD_NO_RENEGOTIATION:
+		str="no renegotiation";
+		break;
+	case TLS1_AD_UNSUPPORTED_EXTENSION:
+		str="unsupported extension";
+		break;
+	case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
+		str="certificate unobtainable";
+		break;
+	case TLS1_AD_UNRECOGNIZED_NAME:
+		str="unrecognized name";
+		break;
+	case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
+		str="bad certificate status response";
+		break;
+	case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
+		str="bad certificate hash value";
+		break;
+	case TLS1_AD_UNKNOWN_PSK_IDENTITY:
+		str="unknown PSK identity";
+		break;
+	default: str="unknown"; break;
+		}
+	return(str);
+	}
+
+const char *SSL_rstate_string(const SSL *s)
+	{
+	const char *str;
+
+	switch (s->rstate)
+		{
+	case SSL_ST_READ_HEADER:str="RH"; break;
+	case SSL_ST_READ_BODY:	str="RB"; break;
+	case SSL_ST_READ_DONE:	str="RD"; break;
+	default: str="unknown"; break;
+		}
+	return(str);
+	}
diff --git a/openssl/ssl/ssl_task.c b/openssl/ssl/ssl_task.c
new file mode 100644
index 0000000..b5ce44b
--- /dev/null
+++ b/openssl/ssl/ssl_task.c
@@ -0,0 +1,369 @@
+/* ssl/ssl_task.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* VMS */
+/*
+ * DECnet object for servicing SSL.  We accept the inbound and speak a
+ * simple protocol for multiplexing the 2 data streams (application and
+ * ssl data) over this logical link.
+ *
+ * Logical names:
+ *    SSL_CIPHER	Defines a list of cipher specifications the server
+ *			will support in order of preference.
+ *    SSL_SERVER_CERTIFICATE
+ *			Points to PEM (privacy enhanced mail) file that
+ *			contains the server certificate and private password.
+ *    SYS$NET		Logical created by netserver.exe as hook for completing
+ *			DECnet logical link.
+ *
+ * Each NSP message sent over the DECnet link has the following structure:
+ *    struct rpc_msg { 
+ *      char channel;
+ *      char function;
+ *      short length;
+ *      char data[MAX_DATA];
+ *    } msg;
+ *
+ * The channel field designates the virtual data stream this message applies
+ * to and is one of:
+ *   A - Application data (payload).
+ *   R - Remote client connection that initiated the SSL connection.  Encrypted
+ *       data is sent over this connection.
+ *   G - General data, reserved for future use.
+ *
+ * The data streams are half-duplex read/write and have following functions:
+ *   G - Get, requests that up to msg.length bytes of data be returned.  The
+ *       data is returned in the next 'C' function response that matches the
+ *       requesting channel.
+ *   P - Put, requests that the first msg.length bytes of msg.data be appended
+ *       to the designated stream.
+ *   C - Confirms a get or put.  Every get and put will get a confirm response,
+ *       you cannot initiate another function on a channel until the previous
+ *       operation has been confirmed.
+ *
+ *  The 2 channels may interleave their operations, for example:
+ *        Server msg           Client msg
+ *         A, Get, 4092          ---->
+ *                               <----  R, get, 4092
+ *         R, Confirm, {hello}   ---->
+ *                               <----  R, put, {srv hello}
+ *         R, Confirm, 0         ---->
+ *                               .		(SSL handshake completed)
+ *                               .              (read first app data).
+ *                               <----  A, confirm, {http data}
+ *         A, Put, {http data}   ---->
+ *                               <----  A, confirm, 0
+ *
+ *  The length field is not permitted to be larger that 4092 bytes.
+ *
+ * Author: Dave Jones
+ * Date:   22-JUL-1996
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <iodef.h>		/* VMS IO$_ definitions */
+#include <descrip.h>		/* VMS string descriptors */
+extern int SYS$QIOW(), SYS$ASSIGN();
+int LIB$INIT_TIMER(), LIB$SHOW_TIMER();
+
+#include <string.h>		/* from ssltest.c */
+#include <errno.h>
+
+#include "e_os.h"
+
+#include <openssl/buffer.h>
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+int MS_CALLBACK verify_callback(int ok, X509 *xs, X509 *xi, int depth,
+	int error);
+BIO *bio_err=NULL;
+BIO *bio_stdout=NULL;
+BIO_METHOD *BIO_s_rtcp();
+
+static char *cipher=NULL;
+int verbose=1;
+#ifdef FIONBIO
+static int s_nbio=0;
+#endif
+#define TEST_SERVER_CERT "SSL_SERVER_CERTIFICATE"
+/*************************************************************************/
+struct rpc_msg {		/* Should have member alignment inhibited */
+   char channel;		/* 'A'-app data. 'R'-remote client 'G'-global */
+   char function;		/* 'G'-get, 'P'-put, 'C'-confirm, 'X'-close */
+   unsigned short int length;	/* Amount of data returned or max to return */
+   char data[4092];		/* variable data */
+};
+#define RPC_HDR_SIZE (sizeof(struct rpc_msg) - 4092)
+
+static $DESCRIPTOR(sysnet, "SYS$NET");
+typedef unsigned short io_channel;
+
+struct io_status {
+    unsigned short status;
+    unsigned short count;
+    unsigned long stsval;
+};
+int doit(io_channel chan, SSL_CTX *s_ctx );
+/*****************************************************************************/
+/* Decnet I/O routines.
+ */
+static int get ( io_channel chan, char *buffer, int maxlen, int *length )
+{
+    int status;
+    struct io_status iosb;
+    status = SYS$QIOW ( 0, chan, IO$_READVBLK, &iosb, 0, 0,
+	buffer, maxlen, 0, 0, 0, 0 );
+    if ( (status&1) == 1 ) status = iosb.status;
+    if ( (status&1) == 1 ) *length = iosb.count;
+    return status;
+}
+
+static int put ( io_channel chan, char *buffer, int length )
+{
+    int status;
+    struct io_status iosb;
+    status = SYS$QIOW ( 0, chan, IO$_WRITEVBLK, &iosb, 0, 0,
+	buffer, length, 0, 0, 0, 0 );
+    if ( (status&1) == 1 ) status = iosb.status;
+    return status;
+}
+/***************************************************************************/
+/* Handle operations on the 'G' channel.
+ */
+static int general_request ( io_channel chan, struct rpc_msg *msg, int length )
+{
+    return 48;
+}
+/***************************************************************************/
+int main ( int argc, char **argv )
+{
+    int status, length;
+    io_channel chan;
+    struct rpc_msg msg;
+
+	char *CApath=NULL,*CAfile=NULL;
+	int badop=0;
+	int ret=1;
+	int client_auth=0;
+	int server_auth=0;
+	SSL_CTX *s_ctx=NULL;
+    /*
+     * Confirm logical link with initiating client.
+     */
+    LIB$INIT_TIMER();
+    status = SYS$ASSIGN ( &sysnet, &chan, 0, 0, 0 );
+    printf("status of assign to SYS$NET: %d\n", status );
+    /*
+     * Initialize standard out and error files.
+     */
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE);
+	if (bio_stdout == NULL)
+		if ((bio_stdout=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_stdout,stdout,BIO_NOCLOSE);
+    /*
+     * get the preferred cipher list and other initialization
+     */
+	if (cipher == NULL) cipher=getenv("SSL_CIPHER");
+	printf("cipher list: %s\n", cipher ? cipher : "{undefined}" );
+
+	SSL_load_error_strings();
+	OpenSSL_add_all_algorithms();
+
+/* DRM, this was the original, but there is no such thing as SSLv2()
+	s_ctx=SSL_CTX_new(SSLv2());
+*/
+	s_ctx=SSL_CTX_new(SSLv2_server_method());
+
+	if (s_ctx == NULL) goto end;
+
+	SSL_CTX_use_certificate_file(s_ctx,TEST_SERVER_CERT,SSL_FILETYPE_PEM);
+	SSL_CTX_use_RSAPrivateKey_file(s_ctx,TEST_SERVER_CERT,SSL_FILETYPE_PEM);
+	printf("Loaded server certificate: '%s'\n", TEST_SERVER_CERT );
+
+    /*
+     * Take commands from client until bad status.
+     */
+    LIB$SHOW_TIMER();
+    status = doit ( chan, s_ctx );
+    LIB$SHOW_TIMER();
+    /*
+     * do final cleanup and exit.
+     */
+end:
+	if (s_ctx != NULL) SSL_CTX_free(s_ctx);
+    LIB$SHOW_TIMER();
+    return 1;
+}
+
+int doit(io_channel chan, SSL_CTX *s_ctx )
+{
+    int status, length, link_state;
+     struct rpc_msg msg;
+
+	SSL *s_ssl=NULL;
+	BIO *c_to_s=NULL;
+	BIO *s_to_c=NULL;
+	BIO *c_bio=NULL;
+	BIO *s_bio=NULL;
+	int i;
+	int done=0;
+
+	s_ssl=SSL_new(s_ctx);
+	if (s_ssl == NULL) goto err;
+
+	c_to_s=BIO_new(BIO_s_rtcp());
+	s_to_c=BIO_new(BIO_s_rtcp());
+	if ((s_to_c == NULL) || (c_to_s == NULL)) goto err;
+/* original, DRM 24-SEP-1997
+	BIO_set_fd ( c_to_s, "", chan );
+	BIO_set_fd ( s_to_c, "", chan );
+*/
+	BIO_set_fd ( c_to_s, 0, chan );
+	BIO_set_fd ( s_to_c, 0, chan );
+
+	c_bio=BIO_new(BIO_f_ssl());
+	s_bio=BIO_new(BIO_f_ssl());
+	if ((c_bio == NULL) || (s_bio == NULL)) goto err;
+
+	SSL_set_accept_state(s_ssl);
+	SSL_set_bio(s_ssl,c_to_s,s_to_c);
+	BIO_set_ssl(s_bio,s_ssl,BIO_CLOSE);
+
+	/* We can always do writes */
+	printf("Begin doit main loop\n");
+	/*
+	 * Link states: 0-idle, 1-read pending, 2-write pending, 3-closed.
+	 */
+	for (link_state = 0; link_state < 3; ) {
+	    /*
+	     * Wait for remote end to request data action on A channel.
+	     */
+	    while ( link_state == 0 ) {
+		status = get ( chan, (char *) &msg, sizeof(msg), &length );
+		if ( (status&1) == 0 ) {
+		    printf("Error in main loop get: %d\n", status );
+		    link_state = 3;
+		    break;
+		}
+	   	if ( length < RPC_HDR_SIZE ) {
+		    printf("Error in main loop get size: %d\n", length );
+		    break;
+		    link_state = 3;
+		}
+	   	if ( msg.channel != 'A' ) {
+		    printf("Error in main loop, unexpected channel: %c\n", 
+			msg.channel );
+		    break;
+		    link_state = 3;
+		}
+		if ( msg.function == 'G' ) {
+		    link_state = 1;
+		} else if ( msg.function == 'P' ) {
+		    link_state = 2;	/* write pending */
+		} else if ( msg.function == 'X' ) {
+		    link_state = 3;
+		} else {
+		    link_state = 3;
+		}
+	    }
+	    if ( link_state == 1 ) {
+		i = BIO_read ( s_bio, msg.data, msg.length );
+		if ( i < 0 ) link_state = 3;
+		else {
+		    msg.channel = 'A';
+		    msg.function = 'C';		/* confirm */
+		    msg.length = i;
+		    status = put ( chan, (char *) &msg, i+RPC_HDR_SIZE );
+		    if ( (status&1) == 0 ) break;
+		    link_state = 0;
+		}
+	    } else if ( link_state == 2 ) {
+		i = BIO_write ( s_bio, msg.data, msg.length );
+		if ( i < 0 ) link_state = 3;
+		else {
+		    msg.channel = 'A';
+		    msg.function = 'C';		/* confirm */
+		    msg.length = 0;
+		    status = put ( chan, (char *) &msg, RPC_HDR_SIZE );
+		    if ( (status&1) == 0 ) break;
+		    link_state = 0;
+		}
+	    }
+	}
+	fprintf(stdout,"DONE\n");
+err:
+	/* We have to set the BIO's to NULL otherwise they will be
+	 * free()ed twice.  Once when th s_ssl is SSL_free()ed and
+	 * again when c_ssl is SSL_free()ed.
+	 * This is a hack required because s_ssl and c_ssl are sharing the same
+	 * BIO structure and SSL_set_bio() and SSL_free() automatically
+	 * BIO_free non NULL entries.
+	 * You should not normally do this or be required to do this */
+	s_ssl->rbio=NULL;
+	s_ssl->wbio=NULL;
+
+	if (c_to_s != NULL) BIO_free(c_to_s);
+	if (s_to_c != NULL) BIO_free(s_to_c);
+	if (c_bio != NULL) BIO_free(c_bio);
+	if (s_bio != NULL) BIO_free(s_bio);
+	return(0);
+}
diff --git a/openssl/ssl/ssl_txt.c b/openssl/ssl/ssl_txt.c
new file mode 100644
index 0000000..3122440
--- /dev/null
+++ b/openssl/ssl/ssl_txt.c
@@ -0,0 +1,240 @@
+/* ssl/ssl_txt.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include <openssl/buffer.h>
+#include "ssl_locl.h"
+
+#ifndef OPENSSL_NO_FP_API
+int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x)
+	{
+	BIO *b;
+	int ret;
+
+	if ((b=BIO_new(BIO_s_file_internal())) == NULL)
+		{
+		SSLerr(SSL_F_SSL_SESSION_PRINT_FP,ERR_R_BUF_LIB);
+		return(0);
+		}
+	BIO_set_fp(b,fp,BIO_NOCLOSE);
+	ret=SSL_SESSION_print(b,x);
+	BIO_free(b);
+	return(ret);
+	}
+#endif
+
+int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
+	{
+	unsigned int i;
+	const char *s;
+
+	if (x == NULL) goto err;
+	if (BIO_puts(bp,"SSL-Session:\n") <= 0) goto err;
+	if (x->ssl_version == SSL2_VERSION)
+		s="SSLv2";
+	else if (x->ssl_version == SSL3_VERSION)
+		s="SSLv3";
+	else if (x->ssl_version == TLS1_VERSION)
+		s="TLSv1";
+	else if (x->ssl_version == DTLS1_VERSION)
+		s="DTLSv1";
+	else if (x->ssl_version == DTLS1_BAD_VER)
+		s="DTLSv1-bad";
+	else
+		s="unknown";
+	if (BIO_printf(bp,"    Protocol  : %s\n",s) <= 0) goto err;
+
+	if (x->cipher == NULL)
+		{
+		if (((x->cipher_id) & 0xff000000) == 0x02000000)
+			{
+			if (BIO_printf(bp,"    Cipher    : %06lX\n",x->cipher_id&0xffffff) <= 0)
+				goto err;
+			}
+		else
+			{
+			if (BIO_printf(bp,"    Cipher    : %04lX\n",x->cipher_id&0xffff) <= 0)
+				goto err;
+			}
+		}
+	else
+		{
+		if (BIO_printf(bp,"    Cipher    : %s\n",((x->cipher == NULL)?"unknown":x->cipher->name)) <= 0)
+			goto err;
+		}
+	if (BIO_puts(bp,"    Session-ID: ") <= 0) goto err;
+	for (i=0; i<x->session_id_length; i++)
+		{
+		if (BIO_printf(bp,"%02X",x->session_id[i]) <= 0) goto err;
+		}
+	if (BIO_puts(bp,"\n    Session-ID-ctx: ") <= 0) goto err;
+	for (i=0; i<x->sid_ctx_length; i++)
+		{
+		if (BIO_printf(bp,"%02X",x->sid_ctx[i]) <= 0)
+			goto err;
+		}
+	if (BIO_puts(bp,"\n    Master-Key: ") <= 0) goto err;
+	for (i=0; i<(unsigned int)x->master_key_length; i++)
+		{
+		if (BIO_printf(bp,"%02X",x->master_key[i]) <= 0) goto err;
+		}
+	if (BIO_puts(bp,"\n    Key-Arg   : ") <= 0) goto err;
+	if (x->key_arg_length == 0)
+		{
+		if (BIO_puts(bp,"None") <= 0) goto err;
+		}
+	else
+		for (i=0; i<x->key_arg_length; i++)
+			{
+			if (BIO_printf(bp,"%02X",x->key_arg[i]) <= 0) goto err;
+			}
+#ifndef OPENSSL_NO_KRB5
+       if (BIO_puts(bp,"\n    Krb5 Principal: ") <= 0) goto err;
+            if (x->krb5_client_princ_len == 0)
+            {
+		if (BIO_puts(bp,"None") <= 0) goto err;
+		}
+	else
+		for (i=0; i<x->krb5_client_princ_len; i++)
+			{
+			if (BIO_printf(bp,"%02X",x->krb5_client_princ[i]) <= 0) goto err;
+			}
+#endif /* OPENSSL_NO_KRB5 */
+#ifndef OPENSSL_NO_PSK
+	if (BIO_puts(bp,"\n    PSK identity: ") <= 0) goto err;
+	if (BIO_printf(bp, "%s", x->psk_identity ? x->psk_identity : "None") <= 0) goto err;
+	if (BIO_puts(bp,"\n    PSK identity hint: ") <= 0) goto err;
+	if (BIO_printf(bp, "%s", x->psk_identity_hint ? x->psk_identity_hint : "None") <= 0) goto err;
+#endif
+#ifndef OPENSSL_NO_TLSEXT
+	if (x->tlsext_tick_lifetime_hint)
+		{
+		if (BIO_printf(bp,
+			"\n    TLS session ticket lifetime hint: %ld (seconds)",
+			x->tlsext_tick_lifetime_hint) <=0)
+			goto err;
+		}
+	if (x->tlsext_tick)
+		{
+		if (BIO_puts(bp, "\n    TLS session ticket:\n") <= 0) goto err;
+		if (BIO_dump_indent(bp, (char *)x->tlsext_tick, x->tlsext_ticklen, 4) <= 0)
+			goto err;
+		}
+#endif
+
+#ifndef OPENSSL_NO_COMP
+	if (x->compress_meth != 0)
+		{
+		SSL_COMP *comp = NULL;
+
+		ssl_cipher_get_evp(x,NULL,NULL,NULL,NULL,&comp);
+		if (comp == NULL)
+			{
+			if (BIO_printf(bp,"\n    Compression: %d",x->compress_meth) <= 0) goto err;
+			}
+		else
+			{
+			if (BIO_printf(bp,"\n    Compression: %d (%s)", comp->id,comp->method->name) <= 0) goto err;
+			}
+		}	
+#endif
+	if (x->time != 0L)
+		{
+		if (BIO_printf(bp, "\n    Start Time: %ld",x->time) <= 0) goto err;
+		}
+	if (x->timeout != 0L)
+		{
+		if (BIO_printf(bp, "\n    Timeout   : %ld (sec)",x->timeout) <= 0) goto err;
+		}
+	if (BIO_puts(bp,"\n") <= 0) goto err;
+
+	if (BIO_puts(bp, "    Verify return code: ") <= 0) goto err;
+	if (BIO_printf(bp, "%ld (%s)\n", x->verify_result,
+		X509_verify_cert_error_string(x->verify_result)) <= 0) goto err;
+		
+	return(1);
+err:
+	return(0);
+	}
+
diff --git a/openssl/ssl/ssltest.c b/openssl/ssl/ssltest.c
new file mode 100644
index 0000000..f6a2c79
--- /dev/null
+++ b/openssl/ssl/ssltest.c
@@ -0,0 +1,2503 @@
+/* ssl/ssltest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#define _BSD_SOURCE 1		/* Or gethostname won't be declared properly
+				   on Linux and GNU platforms. */
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#define USE_SOCKETS
+#include "e_os.h"
+
+#ifdef OPENSSL_SYS_VMS
+#define _XOPEN_SOURCE 500	/* Or isascii won't be declared properly on
+				   VMS (at least with DECompHP C).  */
+#endif
+
+#include <ctype.h>
+
+#include <openssl/bio.h>
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/ssl.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#include <openssl/bn.h>
+
+#define _XOPEN_SOURCE_EXTENDED	1 /* Or gethostname won't be declared properly
+				     on Compaq platforms (at least with DEC C).
+				     Do not try to put it earlier, or IPv6 includes
+				     get screwed...
+				  */
+
+#ifdef OPENSSL_SYS_WINDOWS
+#include <winsock.h>
+#else
+#include OPENSSL_UNISTD
+#endif
+
+#ifdef OPENSSL_SYS_VMS
+#  define TEST_SERVER_CERT "SYS$DISK:[-.APPS]SERVER.PEM"
+#  define TEST_CLIENT_CERT "SYS$DISK:[-.APPS]CLIENT.PEM"
+#elif defined(OPENSSL_SYS_WINCE)
+#  define TEST_SERVER_CERT "\\OpenSSL\\server.pem"
+#  define TEST_CLIENT_CERT "\\OpenSSL\\client.pem"
+#elif defined(OPENSSL_SYS_NETWARE)
+#  define TEST_SERVER_CERT "\\openssl\\apps\\server.pem"
+#  define TEST_CLIENT_CERT "\\openssl\\apps\\client.pem"
+#else
+#  define TEST_SERVER_CERT "../apps/server.pem"
+#  define TEST_CLIENT_CERT "../apps/client.pem"
+#endif
+
+/* There is really no standard for this, so let's assign some tentative
+   numbers.  In any case, these numbers are only for this test */
+#define COMP_RLE	255
+#define COMP_ZLIB	1
+
+static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
+#ifndef OPENSSL_NO_RSA
+static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export,int keylength);
+static void free_tmp_rsa(void);
+#endif
+static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg);
+#define APP_CALLBACK_STRING "Test Callback Argument"
+struct app_verify_arg
+	{
+	char *string;
+	int app_verify;
+	int allow_proxy_certs;
+	char *proxy_auth;
+	char *proxy_cond;
+	};
+
+#ifndef OPENSSL_NO_DH
+static DH *get_dh512(void);
+static DH *get_dh1024(void);
+static DH *get_dh1024dsa(void);
+#endif
+
+
+static char *psk_key=NULL; /* by default PSK is not used */
+#ifndef OPENSSL_NO_PSK
+static unsigned int psk_client_callback(SSL *ssl, const char *hint, char *identity,
+	unsigned int max_identity_len, unsigned char *psk,
+	unsigned int max_psk_len);
+static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned char *psk,
+	unsigned int max_psk_len);
+#endif
+
+static BIO *bio_err=NULL;
+static BIO *bio_stdout=NULL;
+
+static char *cipher=NULL;
+static int verbose=0;
+static int debug=0;
+#if 0
+/* Not used yet. */
+#ifdef FIONBIO
+static int s_nbio=0;
+#endif
+#endif
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+int doit_biopair(SSL *s_ssl,SSL *c_ssl,long bytes,clock_t *s_time,clock_t *c_time);
+int doit(SSL *s_ssl,SSL *c_ssl,long bytes);
+static int do_test_cipherlist(void);
+static void sv_usage(void)
+	{
+	fprintf(stderr,"usage: ssltest [args ...]\n");
+	fprintf(stderr,"\n");
+	fprintf(stderr," -server_auth  - check server certificate\n");
+	fprintf(stderr," -client_auth  - do client authentication\n");
+	fprintf(stderr," -proxy        - allow proxy certificates\n");
+	fprintf(stderr," -proxy_auth <val> - set proxy policy rights\n");
+	fprintf(stderr," -proxy_cond <val> - experssion to test proxy policy rights\n");
+	fprintf(stderr," -v            - more output\n");
+	fprintf(stderr," -d            - debug output\n");
+	fprintf(stderr," -reuse        - use session-id reuse\n");
+	fprintf(stderr," -num <val>    - number of connections to perform\n");
+	fprintf(stderr," -bytes <val>  - number of bytes to swap between client/server\n");
+#ifndef OPENSSL_NO_DH
+	fprintf(stderr," -dhe1024      - use 1024 bit key (safe prime) for DHE\n");
+	fprintf(stderr," -dhe1024dsa   - use 1024 bit key (with 160-bit subprime) for DHE\n");
+	fprintf(stderr," -no_dhe       - disable DHE\n");
+#endif
+#ifndef OPENSSL_NO_ECDH
+	fprintf(stderr," -no_ecdhe     - disable ECDHE\n");
+#endif
+#ifndef OPENSSL_NO_PSK
+	fprintf(stderr," -psk arg      - PSK in hex (without 0x)\n");
+#endif
+#ifndef OPENSSL_NO_SSL2
+	fprintf(stderr," -ssl2         - use SSLv2\n");
+#endif
+#ifndef OPENSSL_NO_SSL3
+	fprintf(stderr," -ssl3         - use SSLv3\n");
+#endif
+#ifndef OPENSSL_NO_TLS1
+	fprintf(stderr," -tls1         - use TLSv1\n");
+#endif
+	fprintf(stderr," -CApath arg   - PEM format directory of CA's\n");
+	fprintf(stderr," -CAfile arg   - PEM format file of CA's\n");
+	fprintf(stderr," -cert arg     - Server certificate file\n");
+	fprintf(stderr," -key arg      - Server key file (default: same as -cert)\n");
+	fprintf(stderr," -c_cert arg   - Client certificate file\n");
+	fprintf(stderr," -c_key arg    - Client key file (default: same as -c_cert)\n");
+	fprintf(stderr," -cipher arg   - The cipher list\n");
+	fprintf(stderr," -bio_pair     - Use BIO pairs\n");
+	fprintf(stderr," -f            - Test even cases that can't work\n");
+	fprintf(stderr," -time         - measure processor time used by client and server\n");
+	fprintf(stderr," -zlib         - use zlib compression\n");
+	fprintf(stderr," -rle          - use rle compression\n");
+#ifndef OPENSSL_NO_ECDH
+	fprintf(stderr," -named_curve arg  - Elliptic curve name to use for ephemeral ECDH keys.\n" \
+	               "                 Use \"openssl ecparam -list_curves\" for all names\n"  \
+	               "                 (default is sect163r2).\n");
+#endif
+	fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
+	fprintf(stderr," -c_small_records - enable client side use of small SSL record buffers\n");
+	fprintf(stderr," -s_small_records - enable server side use of small SSL record buffers\n");
+	fprintf(stderr," -cutthrough      - enable 1-RTT full-handshake for strong ciphers\n");
+	}
+
+static void print_details(SSL *c_ssl, const char *prefix)
+	{
+	const SSL_CIPHER *ciph;
+	X509 *cert;
+		
+	ciph=SSL_get_current_cipher(c_ssl);
+	BIO_printf(bio_stdout,"%s%s, cipher %s %s",
+		prefix,
+		SSL_get_version(c_ssl),
+		SSL_CIPHER_get_version(ciph),
+		SSL_CIPHER_get_name(ciph));
+	cert=SSL_get_peer_certificate(c_ssl);
+	if (cert != NULL)
+		{
+		EVP_PKEY *pkey = X509_get_pubkey(cert);
+		if (pkey != NULL)
+			{
+			if (0) 
+				;
+#ifndef OPENSSL_NO_RSA
+			else if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL
+				&& pkey->pkey.rsa->n != NULL)
+				{
+				BIO_printf(bio_stdout, ", %d bit RSA",
+					BN_num_bits(pkey->pkey.rsa->n));
+				}
+#endif
+#ifndef OPENSSL_NO_DSA
+			else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL
+				&& pkey->pkey.dsa->p != NULL)
+				{
+				BIO_printf(bio_stdout, ", %d bit DSA",
+					BN_num_bits(pkey->pkey.dsa->p));
+				}
+#endif
+			EVP_PKEY_free(pkey);
+			}
+		X509_free(cert);
+		}
+	/* The SSL API does not allow us to look at temporary RSA/DH keys,
+	 * otherwise we should print their lengths too */
+	BIO_printf(bio_stdout,"\n");
+	}
+
+static void lock_dbg_cb(int mode, int type, const char *file, int line)
+	{
+	static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */
+	const char *errstr = NULL;
+	int rw;
+	
+	rw = mode & (CRYPTO_READ|CRYPTO_WRITE);
+	if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE)))
+		{
+		errstr = "invalid mode";
+		goto err;
+		}
+
+	if (type < 0 || type >= CRYPTO_NUM_LOCKS)
+		{
+		errstr = "type out of bounds";
+		goto err;
+		}
+
+	if (mode & CRYPTO_LOCK)
+		{
+		if (modes[type])
+			{
+			errstr = "already locked";
+			/* must not happen in a single-threaded program
+			 * (would deadlock) */
+			goto err;
+			}
+
+		modes[type] = rw;
+		}
+	else if (mode & CRYPTO_UNLOCK)
+		{
+		if (!modes[type])
+			{
+			errstr = "not locked";
+			goto err;
+			}
+		
+		if (modes[type] != rw)
+			{
+			errstr = (rw == CRYPTO_READ) ?
+				"CRYPTO_r_unlock on write lock" :
+				"CRYPTO_w_unlock on read lock";
+			}
+
+		modes[type] = 0;
+		}
+	else
+		{
+		errstr = "invalid mode";
+		goto err;
+		}
+
+ err:
+	if (errstr)
+		{
+		/* we cannot use bio_err here */
+		fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n",
+			errstr, mode, type, file, line);
+		}
+	}
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+struct cb_info_st { void *input; size_t len; int ret; };
+struct cb_info_st co1 = { "C", 1, 1 }; /* try to negotiate oqaque PRF input */
+struct cb_info_st co2 = { "C", 1, 2 }; /* insist on oqaque PRF input */
+struct cb_info_st so1 = { "S", 1, 1 }; /* try to negotiate oqaque PRF input */
+struct cb_info_st so2 = { "S", 1, 2 }; /* insist on oqaque PRF input */
+
+int opaque_prf_input_cb(SSL *ssl, void *peerinput, size_t len, void *arg_)
+	{
+	struct cb_info_st *arg = arg_;
+
+	if (arg == NULL)
+		return 1;
+	
+	if (!SSL_set_tlsext_opaque_prf_input(ssl, arg->input, arg->len))
+		return 0;
+	return arg->ret;
+	}
+#endif
+	int ssl_mode = 0;
+	int c_small_records=0;
+	int s_small_records=0;
+	int cutthrough = 0;
+
+int main(int argc, char *argv[])
+	{
+	char *CApath=NULL,*CAfile=NULL;
+	int badop=0;
+	int bio_pair=0;
+	int force=0;
+	int tls1=0,ssl2=0,ssl3=0,ret=1;
+	int client_auth=0;
+	int server_auth=0,i;
+	struct app_verify_arg app_verify_arg =
+		{ APP_CALLBACK_STRING, 0, 0, NULL, NULL };
+	char *server_cert=TEST_SERVER_CERT;
+	char *server_key=NULL;
+	char *client_cert=TEST_CLIENT_CERT;
+	char *client_key=NULL;
+#ifndef OPENSSL_NO_ECDH
+	char *named_curve = NULL;
+#endif
+	SSL_CTX *s_ctx=NULL;
+	SSL_CTX *c_ctx=NULL;
+	const SSL_METHOD *meth=NULL;
+	SSL *c_ssl,*s_ssl;
+	int number=1,reuse=0;
+	long bytes=256L;
+#ifndef OPENSSL_NO_DH
+	DH *dh;
+	int dhe1024 = 0, dhe1024dsa = 0;
+#endif
+#ifndef OPENSSL_NO_ECDH
+	EC_KEY *ecdh = NULL;
+#endif
+	int no_dhe = 0;
+	int no_ecdhe = 0;
+	int no_psk = 0;
+	int print_time = 0;
+	clock_t s_time = 0, c_time = 0;
+	int comp = 0;
+#ifndef OPENSSL_NO_COMP
+	COMP_METHOD *cm = NULL;
+#endif
+	STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
+	int test_cipherlist = 0;
+
+	verbose = 0;
+	debug = 0;
+	cipher = 0;
+
+	bio_err=BIO_new_fp(stderr,BIO_NOCLOSE|BIO_FP_TEXT);	
+
+	CRYPTO_set_locking_callback(lock_dbg_cb);
+
+	/* enable memory leak checking unless explicitly disabled */
+	if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
+		{
+		CRYPTO_malloc_debug_init();
+		CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+		}
+	else
+		{
+		/* OPENSSL_DEBUG_MEMORY=off */
+		CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
+		}
+	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+	RAND_seed(rnd_seed, sizeof rnd_seed);
+
+	bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	argc--;
+	argv++;
+
+	while (argc >= 1)
+		{
+		if	(strcmp(*argv,"-server_auth") == 0)
+			server_auth=1;
+		else if	(strcmp(*argv,"-client_auth") == 0)
+			client_auth=1;
+		else if (strcmp(*argv,"-proxy_auth") == 0)
+			{
+			if (--argc < 1) goto bad;
+			app_verify_arg.proxy_auth= *(++argv);
+			}
+		else if (strcmp(*argv,"-proxy_cond") == 0)
+			{
+			if (--argc < 1) goto bad;
+			app_verify_arg.proxy_cond= *(++argv);
+			}
+		else if	(strcmp(*argv,"-v") == 0)
+			verbose=1;
+		else if	(strcmp(*argv,"-d") == 0)
+			debug=1;
+		else if	(strcmp(*argv,"-reuse") == 0)
+			reuse=1;
+		else if	(strcmp(*argv,"-dhe1024") == 0)
+			{
+#ifndef OPENSSL_NO_DH
+			dhe1024=1;
+#else
+			fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n");
+#endif
+			}
+		else if	(strcmp(*argv,"-dhe1024dsa") == 0)
+			{
+#ifndef OPENSSL_NO_DH
+			dhe1024dsa=1;
+#else
+			fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n");
+#endif
+			}
+		else if	(strcmp(*argv,"-no_dhe") == 0)
+			no_dhe=1;
+		else if	(strcmp(*argv,"-no_ecdhe") == 0)
+			no_ecdhe=1;
+		else if (strcmp(*argv,"-psk") == 0)
+			{
+			if (--argc < 1) goto bad;
+			psk_key=*(++argv);
+#ifndef OPENSSL_NO_PSK
+			if (strspn(psk_key, "abcdefABCDEF1234567890") != strlen(psk_key))
+				{
+				BIO_printf(bio_err,"Not a hex number '%s'\n",*argv);
+				goto bad;
+				}
+#else
+			no_psk=1;
+#endif
+			}
+		else if	(strcmp(*argv,"-ssl2") == 0)
+			ssl2=1;
+		else if	(strcmp(*argv,"-tls1") == 0)
+			tls1=1;
+		else if	(strcmp(*argv,"-ssl3") == 0)
+			ssl3=1;
+		else if	(strncmp(*argv,"-num",4) == 0)
+			{
+			if (--argc < 1) goto bad;
+			number= atoi(*(++argv));
+			if (number == 0) number=1;
+			}
+		else if	(strcmp(*argv,"-bytes") == 0)
+			{
+			if (--argc < 1) goto bad;
+			bytes= atol(*(++argv));
+			if (bytes == 0L) bytes=1L;
+			i=strlen(argv[0]);
+			if (argv[0][i-1] == 'k') bytes*=1024L;
+			if (argv[0][i-1] == 'm') bytes*=1024L*1024L;
+			}
+		else if	(strcmp(*argv,"-cert") == 0)
+			{
+			if (--argc < 1) goto bad;
+			server_cert= *(++argv);
+			}
+		else if	(strcmp(*argv,"-s_cert") == 0)
+			{
+			if (--argc < 1) goto bad;
+			server_cert= *(++argv);
+			}
+		else if	(strcmp(*argv,"-key") == 0)
+			{
+			if (--argc < 1) goto bad;
+			server_key= *(++argv);
+			}
+		else if	(strcmp(*argv,"-s_key") == 0)
+			{
+			if (--argc < 1) goto bad;
+			server_key= *(++argv);
+			}
+		else if	(strcmp(*argv,"-c_cert") == 0)
+			{
+			if (--argc < 1) goto bad;
+			client_cert= *(++argv);
+			}
+		else if	(strcmp(*argv,"-c_key") == 0)
+			{
+			if (--argc < 1) goto bad;
+			client_key= *(++argv);
+			}
+		else if	(strcmp(*argv,"-cipher") == 0)
+			{
+			if (--argc < 1) goto bad;
+			cipher= *(++argv);
+			}
+		else if	(strcmp(*argv,"-CApath") == 0)
+			{
+			if (--argc < 1) goto bad;
+			CApath= *(++argv);
+			}
+		else if	(strcmp(*argv,"-CAfile") == 0)
+			{
+			if (--argc < 1) goto bad;
+			CAfile= *(++argv);
+			}
+		else if	(strcmp(*argv,"-bio_pair") == 0)
+			{
+			bio_pair = 1;
+			}
+		else if	(strcmp(*argv,"-f") == 0)
+			{
+			force = 1;
+			}
+		else if	(strcmp(*argv,"-time") == 0)
+			{
+			print_time = 1;
+			}
+		else if	(strcmp(*argv,"-zlib") == 0)
+			{
+			comp = COMP_ZLIB;
+			}
+		else if	(strcmp(*argv,"-rle") == 0)
+			{
+			comp = COMP_RLE;
+			}
+		else if	(strcmp(*argv,"-named_curve") == 0)
+			{
+			if (--argc < 1) goto bad;
+#ifndef OPENSSL_NO_ECDH		
+			named_curve = *(++argv);
+#else
+			fprintf(stderr,"ignoring -named_curve, since I'm compiled without ECDH\n");
+			++argv;
+#endif
+			}
+		else if	(strcmp(*argv,"-app_verify") == 0)
+			{
+			app_verify_arg.app_verify = 1;
+			}
+		else if	(strcmp(*argv,"-proxy") == 0)
+			{
+			app_verify_arg.allow_proxy_certs = 1;
+			}
+		else if (strcmp(*argv,"-test_cipherlist") == 0)
+			{
+			test_cipherlist = 1;
+			}
+		else if (strcmp(*argv, "-c_small_records") == 0)
+			{
+			c_small_records = 1;
+			}
+		else if (strcmp(*argv, "-s_small_records") == 0)
+			{
+			s_small_records = 1;
+			}
+		else if (strcmp(*argv, "-cutthrough") == 0)
+			{
+			cutthrough = 1;
+			}
+		else
+			{
+			fprintf(stderr,"unknown option %s\n",*argv);
+			badop=1;
+			break;
+			}
+		argc--;
+		argv++;
+		}
+	if (badop)
+		{
+bad:
+		sv_usage();
+		goto end;
+		}
+
+	if (test_cipherlist == 1)
+		{
+		/* ensure that the cipher list are correctly sorted and exit */
+		if (do_test_cipherlist() == 0)
+			EXIT(1);
+		ret = 0;
+		goto end;
+		}
+
+	if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force)
+		{
+		fprintf(stderr, "This case cannot work.  Use -f to perform "
+			"the test anyway (and\n-d to see what happens), "
+			"or add one of -ssl2, -ssl3, -tls1, -reuse\n"
+			"to avoid protocol mismatch.\n");
+		EXIT(1);
+		}
+
+	if (print_time)
+		{
+		if (!bio_pair)
+			{
+			fprintf(stderr, "Using BIO pair (-bio_pair)\n");
+			bio_pair = 1;
+			}
+		if (number < 50 && !force)
+			fprintf(stderr, "Warning: For accurate timings, use more connections (e.g. -num 1000)\n");
+		}
+
+/*	if (cipher == NULL) cipher=getenv("SSL_CIPHER"); */
+
+	SSL_library_init();
+	SSL_load_error_strings();
+
+#ifndef OPENSSL_NO_COMP
+	if (comp == COMP_ZLIB) cm = COMP_zlib();
+	if (comp == COMP_RLE) cm = COMP_rle();
+	if (cm != NULL)
+		{
+		if (cm->type != NID_undef)
+			{
+			if (SSL_COMP_add_compression_method(comp, cm) != 0)
+				{
+				fprintf(stderr,
+					"Failed to add compression method\n");
+				ERR_print_errors_fp(stderr);
+				}
+			}
+		else
+			{
+			fprintf(stderr,
+				"Warning: %s compression not supported\n",
+				(comp == COMP_RLE ? "rle" :
+					(comp == COMP_ZLIB ? "zlib" :
+						"unknown")));
+			ERR_print_errors_fp(stderr);
+			}
+		}
+	ssl_comp_methods = SSL_COMP_get_compression_methods();
+	fprintf(stderr, "Available compression methods:\n");
+	{
+	int j, n = sk_SSL_COMP_num(ssl_comp_methods);
+	if (n == 0)
+		fprintf(stderr, "  NONE\n");
+	else
+		for (j = 0; j < n; j++)
+			{
+			SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
+			fprintf(stderr, "  %d: %s\n", c->id, c->name);
+			}
+	}
+#endif
+
+#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
+	if (ssl2)
+		meth=SSLv2_method();
+	else 
+	if (tls1)
+		meth=TLSv1_method();
+	else
+	if (ssl3)
+		meth=SSLv3_method();
+	else
+		meth=SSLv23_method();
+#else
+#ifdef OPENSSL_NO_SSL2
+	meth=SSLv3_method();
+#else
+	meth=SSLv2_method();
+#endif
+#endif
+
+	c_ctx=SSL_CTX_new(meth);
+	s_ctx=SSL_CTX_new(meth);
+	if ((c_ctx == NULL) || (s_ctx == NULL))
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (cipher != NULL)
+		{
+		SSL_CTX_set_cipher_list(c_ctx,cipher);
+		SSL_CTX_set_cipher_list(s_ctx,cipher);
+		}
+
+	ssl_mode = 0;
+	if (c_small_records)
+		{
+		ssl_mode = SSL_CTX_get_mode(c_ctx);
+		ssl_mode |= SSL_MODE_SMALL_BUFFERS;
+		SSL_CTX_set_mode(c_ctx, ssl_mode);
+		}
+	ssl_mode = 0;
+	if (s_small_records)
+		{
+		ssl_mode = SSL_CTX_get_mode(s_ctx);
+		ssl_mode |= SSL_MODE_SMALL_BUFFERS;
+		SSL_CTX_set_mode(s_ctx, ssl_mode);
+		}
+	ssl_mode = 0;
+	if (cutthrough)
+		{
+		ssl_mode = SSL_CTX_get_mode(c_ctx);
+		ssl_mode = SSL_MODE_HANDSHAKE_CUTTHROUGH;
+		SSL_CTX_set_mode(c_ctx, ssl_mode);
+		}
+
+#ifndef OPENSSL_NO_DH
+	if (!no_dhe)
+		{
+		if (dhe1024dsa)
+			{
+			/* use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks */
+			SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
+			dh=get_dh1024dsa();
+			}
+		else if (dhe1024)
+			dh=get_dh1024();
+		else
+			dh=get_dh512();
+		SSL_CTX_set_tmp_dh(s_ctx,dh);
+		DH_free(dh);
+		}
+#else
+	(void)no_dhe;
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+	if (!no_ecdhe)
+		{
+		int nid;
+
+		if (named_curve != NULL)
+			{
+			nid = OBJ_sn2nid(named_curve);
+			if (nid == 0)
+			{
+				BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve);
+				goto end;
+				}
+			}
+		else
+			nid = NID_sect163r2;
+
+		ecdh = EC_KEY_new_by_curve_name(nid);
+		if (ecdh == NULL)
+			{
+			BIO_printf(bio_err, "unable to create curve\n");
+			goto end;
+			}
+
+		SSL_CTX_set_tmp_ecdh(s_ctx, ecdh);
+		SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE);
+		EC_KEY_free(ecdh);
+		}
+#else
+	(void)no_ecdhe;
+#endif
+
+#ifndef OPENSSL_NO_RSA
+	SSL_CTX_set_tmp_rsa_callback(s_ctx,tmp_rsa_cb);
+#endif
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	SSL_CTX_set_tlsext_opaque_prf_input_callback(c_ctx, opaque_prf_input_cb);
+	SSL_CTX_set_tlsext_opaque_prf_input_callback(s_ctx, opaque_prf_input_cb);
+	SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(c_ctx, &co1); /* or &co2 or NULL */
+	SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(s_ctx, &so1); /* or &so2 or NULL */
+#endif
+
+	if (!SSL_CTX_use_certificate_file(s_ctx,server_cert,SSL_FILETYPE_PEM))
+		{
+		ERR_print_errors(bio_err);
+		}
+	else if (!SSL_CTX_use_PrivateKey_file(s_ctx,
+		(server_key?server_key:server_cert), SSL_FILETYPE_PEM))
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (client_auth)
+		{
+		SSL_CTX_use_certificate_file(c_ctx,client_cert,
+			SSL_FILETYPE_PEM);
+		SSL_CTX_use_PrivateKey_file(c_ctx,
+			(client_key?client_key:client_cert),
+			SSL_FILETYPE_PEM);
+		}
+
+	if (	(!SSL_CTX_load_verify_locations(s_ctx,CAfile,CApath)) ||
+		(!SSL_CTX_set_default_verify_paths(s_ctx)) ||
+		(!SSL_CTX_load_verify_locations(c_ctx,CAfile,CApath)) ||
+		(!SSL_CTX_set_default_verify_paths(c_ctx)))
+		{
+		/* fprintf(stderr,"SSL_load_verify_locations\n"); */
+		ERR_print_errors(bio_err);
+		/* goto end; */
+		}
+
+	if (client_auth)
+		{
+		BIO_printf(bio_err,"client authentication\n");
+		SSL_CTX_set_verify(s_ctx,
+			SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
+			verify_callback);
+		SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, &app_verify_arg);
+		}
+	if (server_auth)
+		{
+		BIO_printf(bio_err,"server authentication\n");
+		SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER,
+			verify_callback);
+		SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback, &app_verify_arg);
+		}
+	
+	{
+		int session_id_context = 0;
+		SSL_CTX_set_session_id_context(s_ctx, (void *)&session_id_context, sizeof session_id_context);
+	}
+
+	/* Use PSK only if PSK key is given */
+	if (psk_key != NULL)
+		{
+		/* no_psk is used to avoid putting psk command to openssl tool */
+		if (no_psk)
+			{
+			/* if PSK is not compiled in and psk key is
+			 * given, do nothing and exit successfully */
+			ret=0;
+			goto end;
+			}
+#ifndef OPENSSL_NO_PSK
+		SSL_CTX_set_psk_client_callback(c_ctx, psk_client_callback);
+		SSL_CTX_set_psk_server_callback(s_ctx, psk_server_callback);
+		if (debug)
+			BIO_printf(bio_err,"setting PSK identity hint to s_ctx\n");
+		if (!SSL_CTX_use_psk_identity_hint(s_ctx, "ctx server identity_hint"))
+			{
+			BIO_printf(bio_err,"error setting PSK identity hint to s_ctx\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+#endif
+		}
+
+	c_ssl=SSL_new(c_ctx);
+	s_ssl=SSL_new(s_ctx);
+
+#ifndef OPENSSL_NO_KRB5
+	if (c_ssl  &&  c_ssl->kssl_ctx)
+                {
+                char	localhost[MAXHOSTNAMELEN+2];
+
+		if (gethostname(localhost, sizeof localhost-1) == 0)
+                        {
+			localhost[sizeof localhost-1]='\0';
+			if(strlen(localhost) == sizeof localhost-1)
+				{
+				BIO_printf(bio_err,"localhost name too long\n");
+				goto end;
+				}
+			kssl_ctx_setstring(c_ssl->kssl_ctx, KSSL_SERVER,
+                                localhost);
+			}
+		}
+#endif    /* OPENSSL_NO_KRB5  */
+
+	for (i=0; i<number; i++)
+		{
+		if (!reuse) SSL_set_session(c_ssl,NULL);
+		if (bio_pair)
+			ret=doit_biopair(s_ssl,c_ssl,bytes,&s_time,&c_time);
+		else
+			ret=doit(s_ssl,c_ssl,bytes);
+		}
+
+	if (!verbose)
+		{
+		print_details(c_ssl, "");
+		}
+	if ((number > 1) || (bytes > 1L))
+		BIO_printf(bio_stdout, "%d handshakes of %ld bytes done\n",number,bytes);
+	if (print_time)
+		{
+#ifdef CLOCKS_PER_SEC
+		/* "To determine the time in seconds, the value returned
+		 * by the clock function should be divided by the value
+		 * of the macro CLOCKS_PER_SEC."
+		 *                                       -- ISO/IEC 9899 */
+		BIO_printf(bio_stdout, "Approximate total server time: %6.2f s\n"
+			"Approximate total client time: %6.2f s\n",
+			(double)s_time/CLOCKS_PER_SEC,
+			(double)c_time/CLOCKS_PER_SEC);
+#else
+		/* "`CLOCKS_PER_SEC' undeclared (first use this function)"
+		 *                            -- cc on NeXTstep/OpenStep */
+		BIO_printf(bio_stdout,
+			"Approximate total server time: %6.2f units\n"
+			"Approximate total client time: %6.2f units\n",
+			(double)s_time,
+			(double)c_time);
+#endif
+		}
+
+	SSL_free(s_ssl);
+	SSL_free(c_ssl);
+
+end:
+	if (s_ctx != NULL) SSL_CTX_free(s_ctx);
+	if (c_ctx != NULL) SSL_CTX_free(c_ctx);
+
+	if (bio_stdout != NULL) BIO_free(bio_stdout);
+
+#ifndef OPENSSL_NO_RSA
+	free_tmp_rsa();
+#endif
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE_cleanup();
+#endif
+	CRYPTO_cleanup_all_ex_data();
+	ERR_free_strings();
+	ERR_remove_thread_state(NULL);
+	EVP_cleanup();
+	CRYPTO_mem_leaks(bio_err);
+	if (bio_err != NULL) BIO_free(bio_err);
+	EXIT(ret);
+	return ret;
+	}
+
+int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
+	clock_t *s_time, clock_t *c_time)
+	{
+	long cw_num = count, cr_num = count, sw_num = count, sr_num = count;
+	BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL;
+	BIO *server = NULL, *server_io = NULL, *client = NULL, *client_io = NULL;
+	int ret = 1;
+	
+	size_t bufsiz = 256; /* small buffer for testing */
+
+	if (!BIO_new_bio_pair(&server, bufsiz, &server_io, bufsiz))
+		goto err;
+	if (!BIO_new_bio_pair(&client, bufsiz, &client_io, bufsiz))
+		goto err;
+	
+	s_ssl_bio = BIO_new(BIO_f_ssl());
+	if (!s_ssl_bio)
+		goto err;
+
+	c_ssl_bio = BIO_new(BIO_f_ssl());
+	if (!c_ssl_bio)
+		goto err;
+
+	SSL_set_connect_state(c_ssl);
+	SSL_set_bio(c_ssl, client, client);
+	(void)BIO_set_ssl(c_ssl_bio, c_ssl, BIO_NOCLOSE);
+
+	SSL_set_accept_state(s_ssl);
+	SSL_set_bio(s_ssl, server, server);
+	(void)BIO_set_ssl(s_ssl_bio, s_ssl, BIO_NOCLOSE);
+
+	do
+		{
+		/* c_ssl_bio:          SSL filter BIO
+		 *
+		 * client:             pseudo-I/O for SSL library
+		 *
+		 * client_io:          client's SSL communication; usually to be
+		 *                     relayed over some I/O facility, but in this
+		 *                     test program, we're the server, too:
+		 *
+		 * server_io:          server's SSL communication
+		 *
+		 * server:             pseudo-I/O for SSL library
+		 *
+		 * s_ssl_bio:          SSL filter BIO
+		 *
+		 * The client and the server each employ a "BIO pair":
+		 * client + client_io, server + server_io.
+		 * BIO pairs are symmetric.  A BIO pair behaves similar
+		 * to a non-blocking socketpair (but both endpoints must
+		 * be handled by the same thread).
+		 * [Here we could connect client and server to the ends
+		 * of a single BIO pair, but then this code would be less
+		 * suitable as an example for BIO pairs in general.]
+		 *
+		 * Useful functions for querying the state of BIO pair endpoints:
+		 *
+		 * BIO_ctrl_pending(bio)              number of bytes we can read now
+		 * BIO_ctrl_get_read_request(bio)     number of bytes needed to fulfil
+		 *                                      other side's read attempt
+		 * BIO_ctrl_get_write_guarantee(bio)   number of bytes we can write now
+		 *
+		 * ..._read_request is never more than ..._write_guarantee;
+		 * it depends on the application which one you should use.
+		 */
+
+		/* We have non-blocking behaviour throughout this test program, but
+		 * can be sure that there is *some* progress in each iteration; so
+		 * we don't have to worry about ..._SHOULD_READ or ..._SHOULD_WRITE
+		 * -- we just try everything in each iteration
+		 */
+
+			{
+			/* CLIENT */
+		
+			MS_STATIC char cbuf[1024*8];
+			int i, r;
+			clock_t c_clock = clock();
+
+			memset(cbuf, 0, sizeof(cbuf));
+
+			if (debug)
+				if (SSL_in_init(c_ssl))
+					printf("client waiting in SSL_connect - %s\n",
+						SSL_state_string_long(c_ssl));
+
+			if (cw_num > 0)
+				{
+				/* Write to server. */
+				
+				if (cw_num > (long)sizeof cbuf)
+					i = sizeof cbuf;
+				else
+					i = (int)cw_num;
+				r = BIO_write(c_ssl_bio, cbuf, i);
+				if (r < 0)
+					{
+					if (!BIO_should_retry(c_ssl_bio))
+						{
+						fprintf(stderr,"ERROR in CLIENT\n");
+						goto err;
+						}
+					/* BIO_should_retry(...) can just be ignored here.
+					 * The library expects us to call BIO_write with
+					 * the same arguments again, and that's what we will
+					 * do in the next iteration. */
+					}
+				else if (r == 0)
+					{
+					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
+					goto err;
+					}
+				else
+					{
+					if (debug)
+						printf("client wrote %d\n", r);
+					cw_num -= r;				
+					}
+				}
+
+			if (cr_num > 0)
+				{
+				/* Read from server. */
+
+				r = BIO_read(c_ssl_bio, cbuf, sizeof(cbuf));
+				if (r < 0)
+					{
+					if (!BIO_should_retry(c_ssl_bio))
+						{
+						fprintf(stderr,"ERROR in CLIENT\n");
+						goto err;
+						}
+					/* Again, "BIO_should_retry" can be ignored. */
+					}
+				else if (r == 0)
+					{
+					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
+					goto err;
+					}
+				else
+					{
+					if (debug)
+						printf("client read %d\n", r);
+					cr_num -= r;
+					}
+				}
+
+			/* c_time and s_time increments will typically be very small
+			 * (depending on machine speed and clock tick intervals),
+			 * but sampling over a large number of connections should
+			 * result in fairly accurate figures.  We cannot guarantee
+			 * a lot, however -- if each connection lasts for exactly
+			 * one clock tick, it will be counted only for the client
+			 * or only for the server or even not at all.
+			 */
+			*c_time += (clock() - c_clock);
+			}
+
+			{
+			/* SERVER */
+		
+			MS_STATIC char sbuf[1024*8];
+			int i, r;
+			clock_t s_clock = clock();
+
+			memset(sbuf, 0, sizeof(sbuf));
+
+			if (debug)
+				if (SSL_in_init(s_ssl))
+					printf("server waiting in SSL_accept - %s\n",
+						SSL_state_string_long(s_ssl));
+
+			if (sw_num > 0)
+				{
+				/* Write to client. */
+				
+				if (sw_num > (long)sizeof sbuf)
+					i = sizeof sbuf;
+				else
+					i = (int)sw_num;
+				r = BIO_write(s_ssl_bio, sbuf, i);
+				if (r < 0)
+					{
+					if (!BIO_should_retry(s_ssl_bio))
+						{
+						fprintf(stderr,"ERROR in SERVER\n");
+						goto err;
+						}
+					/* Ignore "BIO_should_retry". */
+					}
+				else if (r == 0)
+					{
+					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
+					goto err;
+					}
+				else
+					{
+					if (debug)
+						printf("server wrote %d\n", r);
+					sw_num -= r;				
+					}
+				}
+
+			if (sr_num > 0)
+				{
+				/* Read from client. */
+
+				r = BIO_read(s_ssl_bio, sbuf, sizeof(sbuf));
+				if (r < 0)
+					{
+					if (!BIO_should_retry(s_ssl_bio))
+						{
+						fprintf(stderr,"ERROR in SERVER\n");
+						goto err;
+						}
+					/* blah, blah */
+					}
+				else if (r == 0)
+					{
+					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
+					goto err;
+					}
+				else
+					{
+					if (debug)
+						printf("server read %d\n", r);
+					sr_num -= r;
+					}
+				}
+
+			*s_time += (clock() - s_clock);
+			}
+			
+			{
+			/* "I/O" BETWEEN CLIENT AND SERVER. */
+
+			size_t r1, r2;
+			BIO *io1 = server_io, *io2 = client_io;
+			/* we use the non-copying interface for io1
+			 * and the standard BIO_write/BIO_read interface for io2
+			 */
+			
+			static int prev_progress = 1;
+			int progress = 0;
+			
+			/* io1 to io2 */
+			do
+				{
+				size_t num;
+				int r;
+
+				r1 = BIO_ctrl_pending(io1);
+				r2 = BIO_ctrl_get_write_guarantee(io2);
+
+				num = r1;
+				if (r2 < num)
+					num = r2;
+				if (num)
+					{
+					char *dataptr;
+
+					if (INT_MAX < num) /* yeah, right */
+						num = INT_MAX;
+					
+					r = BIO_nread(io1, &dataptr, (int)num);
+					assert(r > 0);
+					assert(r <= (int)num);
+					/* possibly r < num (non-contiguous data) */
+					num = r;
+					r = BIO_write(io2, dataptr, (int)num);
+					if (r != (int)num) /* can't happen */
+						{
+						fprintf(stderr, "ERROR: BIO_write could not write "
+							"BIO_ctrl_get_write_guarantee() bytes");
+						goto err;
+						}
+					progress = 1;
+
+					if (debug)
+						printf((io1 == client_io) ?
+							"C->S relaying: %d bytes\n" :
+							"S->C relaying: %d bytes\n",
+							(int)num);
+					}
+				}
+			while (r1 && r2);
+
+			/* io2 to io1 */
+			{
+				size_t num;
+				int r;
+
+				r1 = BIO_ctrl_pending(io2);
+				r2 = BIO_ctrl_get_read_request(io1);
+				/* here we could use ..._get_write_guarantee instead of
+				 * ..._get_read_request, but by using the latter
+				 * we test restartability of the SSL implementation
+				 * more thoroughly */
+				num = r1;
+				if (r2 < num)
+					num = r2;
+				if (num)
+					{
+					char *dataptr;
+					
+					if (INT_MAX < num)
+						num = INT_MAX;
+
+					if (num > 1)
+						--num; /* test restartability even more thoroughly */
+					
+					r = BIO_nwrite0(io1, &dataptr);
+					assert(r > 0);
+					if (r < (int)num)
+						num = r;
+					r = BIO_read(io2, dataptr, (int)num);
+					if (r != (int)num) /* can't happen */
+						{
+						fprintf(stderr, "ERROR: BIO_read could not read "
+							"BIO_ctrl_pending() bytes");
+						goto err;
+						}
+					progress = 1;
+					r = BIO_nwrite(io1, &dataptr, (int)num);
+					if (r != (int)num) /* can't happen */
+						{
+						fprintf(stderr, "ERROR: BIO_nwrite() did not accept "
+							"BIO_nwrite0() bytes");
+						goto err;
+						}
+					
+					if (debug)
+						printf((io2 == client_io) ?
+							"C->S relaying: %d bytes\n" :
+							"S->C relaying: %d bytes\n",
+							(int)num);
+					}
+			} /* no loop, BIO_ctrl_get_read_request now returns 0 anyway */
+
+			if (!progress && !prev_progress)
+				if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0)
+					{
+					fprintf(stderr, "ERROR: got stuck\n");
+					if (strcmp("SSLv2", SSL_get_version(c_ssl)) == 0)
+						{
+						fprintf(stderr, "This can happen for SSL2 because "
+							"CLIENT-FINISHED and SERVER-VERIFY are written \n"
+							"concurrently ...");
+						if (strncmp("2SCF", SSL_state_string(c_ssl), 4) == 0
+							&& strncmp("2SSV", SSL_state_string(s_ssl), 4) == 0)
+							{
+							fprintf(stderr, " ok.\n");
+							goto end;
+							}
+						}
+					fprintf(stderr, " ERROR.\n");
+					goto err;
+					}
+			prev_progress = progress;
+			}
+		}
+	while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0);
+
+	if (verbose)
+		print_details(c_ssl, "DONE via BIO pair: ");
+end:
+	ret = 0;
+
+ err:
+	ERR_print_errors(bio_err);
+	
+	if (server)
+		BIO_free(server);
+	if (server_io)
+		BIO_free(server_io);
+	if (client)
+		BIO_free(client);
+	if (client_io)
+		BIO_free(client_io);
+	if (s_ssl_bio)
+		BIO_free(s_ssl_bio);
+	if (c_ssl_bio)
+		BIO_free(c_ssl_bio);
+
+	return ret;
+	}
+
+
+#define W_READ	1
+#define W_WRITE	2
+#define C_DONE	1
+#define S_DONE	2
+
+int doit(SSL *s_ssl, SSL *c_ssl, long count)
+	{
+	MS_STATIC char cbuf[1024*8],sbuf[1024*8];
+	long cw_num=count,cr_num=count;
+	long sw_num=count,sr_num=count;
+	int ret=1;
+	BIO *c_to_s=NULL;
+	BIO *s_to_c=NULL;
+	BIO *c_bio=NULL;
+	BIO *s_bio=NULL;
+	int c_r,c_w,s_r,s_w;
+	int i,j;
+	int done=0;
+	int c_write,s_write;
+	int do_server=0,do_client=0;
+
+	memset(cbuf,0,sizeof(cbuf));
+	memset(sbuf,0,sizeof(sbuf));
+
+	c_to_s=BIO_new(BIO_s_mem());
+	s_to_c=BIO_new(BIO_s_mem());
+	if ((s_to_c == NULL) || (c_to_s == NULL))
+		{
+		ERR_print_errors(bio_err);
+		goto err;
+		}
+
+	c_bio=BIO_new(BIO_f_ssl());
+	s_bio=BIO_new(BIO_f_ssl());
+	if ((c_bio == NULL) || (s_bio == NULL))
+		{
+		ERR_print_errors(bio_err);
+		goto err;
+		}
+
+	SSL_set_connect_state(c_ssl);
+	SSL_set_bio(c_ssl,s_to_c,c_to_s);
+	BIO_set_ssl(c_bio,c_ssl,BIO_NOCLOSE);
+
+	SSL_set_accept_state(s_ssl);
+	SSL_set_bio(s_ssl,c_to_s,s_to_c);
+	BIO_set_ssl(s_bio,s_ssl,BIO_NOCLOSE);
+
+	c_r=0; s_r=1;
+	c_w=1; s_w=0;
+	c_write=1,s_write=0;
+
+	/* We can always do writes */
+	for (;;)
+		{
+		do_server=0;
+		do_client=0;
+
+		i=(int)BIO_pending(s_bio);
+		if ((i && s_r) || s_w) do_server=1;
+
+		i=(int)BIO_pending(c_bio);
+		if ((i && c_r) || c_w) do_client=1;
+
+		if (do_server && debug)
+			{
+			if (SSL_in_init(s_ssl))
+				printf("server waiting in SSL_accept - %s\n",
+					SSL_state_string_long(s_ssl));
+/*			else if (s_write)
+				printf("server:SSL_write()\n");
+			else
+				printf("server:SSL_read()\n"); */
+			}
+
+		if (do_client && debug)
+			{
+			if (SSL_in_init(c_ssl))
+				printf("client waiting in SSL_connect - %s\n",
+					SSL_state_string_long(c_ssl));
+/*			else if (c_write)
+				printf("client:SSL_write()\n");
+			else
+				printf("client:SSL_read()\n"); */
+			}
+
+		if (!do_client && !do_server)
+			{
+			fprintf(stdout,"ERROR IN STARTUP\n");
+			ERR_print_errors(bio_err);
+			break;
+			}
+		if (do_client && !(done & C_DONE))
+			{
+			if (c_write)
+				{
+				j = (cw_num > (long)sizeof(cbuf)) ?
+					(int)sizeof(cbuf) : (int)cw_num;
+				i=BIO_write(c_bio,cbuf,j);
+				if (i < 0)
+					{
+					c_r=0;
+					c_w=0;
+					if (BIO_should_retry(c_bio))
+						{
+						if (BIO_should_read(c_bio))
+							c_r=1;
+						if (BIO_should_write(c_bio))
+							c_w=1;
+						}
+					else
+						{
+						fprintf(stderr,"ERROR in CLIENT\n");
+						ERR_print_errors(bio_err);
+						goto err;
+						}
+					}
+				else if (i == 0)
+					{
+					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
+					goto err;
+					}
+				else
+					{
+					if (debug)
+						printf("client wrote %d\n",i);
+					/* ok */
+					s_r=1;
+					c_write=0;
+					cw_num-=i;
+					}
+				}
+			else
+				{
+				i=BIO_read(c_bio,cbuf,sizeof(cbuf));
+				if (i < 0)
+					{
+					c_r=0;
+					c_w=0;
+					if (BIO_should_retry(c_bio))
+						{
+						if (BIO_should_read(c_bio))
+							c_r=1;
+						if (BIO_should_write(c_bio))
+							c_w=1;
+						}
+					else
+						{
+						fprintf(stderr,"ERROR in CLIENT\n");
+						ERR_print_errors(bio_err);
+						goto err;
+						}
+					}
+				else if (i == 0)
+					{
+					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
+					goto err;
+					}
+				else
+					{
+					if (debug)
+						printf("client read %d\n",i);
+					cr_num-=i;
+					if (sw_num > 0)
+						{
+						s_write=1;
+						s_w=1;
+						}
+					if (cr_num <= 0)
+						{
+						s_write=1;
+						s_w=1;
+						done=S_DONE|C_DONE;
+						}
+					}
+				}
+			}
+
+		if (do_server && !(done & S_DONE))
+			{
+			if (!s_write)
+				{
+				i=BIO_read(s_bio,sbuf,sizeof(cbuf));
+				if (i < 0)
+					{
+					s_r=0;
+					s_w=0;
+					if (BIO_should_retry(s_bio))
+						{
+						if (BIO_should_read(s_bio))
+							s_r=1;
+						if (BIO_should_write(s_bio))
+							s_w=1;
+						}
+					else
+						{
+						fprintf(stderr,"ERROR in SERVER\n");
+						ERR_print_errors(bio_err);
+						goto err;
+						}
+					}
+				else if (i == 0)
+					{
+					ERR_print_errors(bio_err);
+					fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_read\n");
+					goto err;
+					}
+				else
+					{
+					if (debug)
+						printf("server read %d\n",i);
+					sr_num-=i;
+					if (cw_num > 0)
+						{
+						c_write=1;
+						c_w=1;
+						}
+					if (sr_num <= 0)
+						{
+						s_write=1;
+						s_w=1;
+						c_write=0;
+						}
+					}
+				}
+			else
+				{
+				j = (sw_num > (long)sizeof(sbuf)) ?
+					(int)sizeof(sbuf) : (int)sw_num;
+				i=BIO_write(s_bio,sbuf,j);
+				if (i < 0)
+					{
+					s_r=0;
+					s_w=0;
+					if (BIO_should_retry(s_bio))
+						{
+						if (BIO_should_read(s_bio))
+							s_r=1;
+						if (BIO_should_write(s_bio))
+							s_w=1;
+						}
+					else
+						{
+						fprintf(stderr,"ERROR in SERVER\n");
+						ERR_print_errors(bio_err);
+						goto err;
+						}
+					}
+				else if (i == 0)
+					{
+					ERR_print_errors(bio_err);
+					fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_write\n");
+					goto err;
+					}
+				else
+					{
+					if (debug)
+						printf("server wrote %d\n",i);
+					sw_num-=i;
+					s_write=0;
+					c_r=1;
+					if (sw_num <= 0)
+						done|=S_DONE;
+					}
+				}
+			}
+
+		if ((done & S_DONE) && (done & C_DONE)) break;
+		}
+
+	if (verbose)
+		print_details(c_ssl, "DONE: ");
+	ret=0;
+err:
+	/* We have to set the BIO's to NULL otherwise they will be
+	 * OPENSSL_free()ed twice.  Once when th s_ssl is SSL_free()ed and
+	 * again when c_ssl is SSL_free()ed.
+	 * This is a hack required because s_ssl and c_ssl are sharing the same
+	 * BIO structure and SSL_set_bio() and SSL_free() automatically
+	 * BIO_free non NULL entries.
+	 * You should not normally do this or be required to do this */
+	if (s_ssl != NULL)
+		{
+		s_ssl->rbio=NULL;
+		s_ssl->wbio=NULL;
+		}
+	if (c_ssl != NULL)
+		{
+		c_ssl->rbio=NULL;
+		c_ssl->wbio=NULL;
+		}
+
+	if (c_to_s != NULL) BIO_free(c_to_s);
+	if (s_to_c != NULL) BIO_free(s_to_c);
+	if (c_bio != NULL) BIO_free_all(c_bio);
+	if (s_bio != NULL) BIO_free_all(s_bio);
+	return(ret);
+	}
+
+static int get_proxy_auth_ex_data_idx(void)
+	{
+	static volatile int idx = -1;
+	if (idx < 0)
+		{
+		CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+		if (idx < 0)
+			{
+			idx = X509_STORE_CTX_get_ex_new_index(0,
+				"SSLtest for verify callback", NULL,NULL,NULL);
+			}
+		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+		}
+	return idx;
+	}
+
+static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
+	{
+	char *s,buf[256];
+
+	s=X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),buf,
+			    sizeof buf);
+	if (s != NULL)
+		{
+		if (ok)
+			fprintf(stderr,"depth=%d %s\n",
+				ctx->error_depth,buf);
+		else
+			{
+			fprintf(stderr,"depth=%d error=%d %s\n",
+				ctx->error_depth,ctx->error,buf);
+			}
+		}
+
+	if (ok == 0)
+		{
+		fprintf(stderr,"Error string: %s\n",
+			X509_verify_cert_error_string(ctx->error));
+		switch (ctx->error)
+			{
+		case X509_V_ERR_CERT_NOT_YET_VALID:
+		case X509_V_ERR_CERT_HAS_EXPIRED:
+		case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+			fprintf(stderr,"  ... ignored.\n");
+			ok=1;
+			}
+		}
+
+	if (ok == 1)
+		{
+		X509 *xs = ctx->current_cert;
+#if 0
+		X509 *xi = ctx->current_issuer;
+#endif
+
+		if (xs->ex_flags & EXFLAG_PROXY)
+			{
+			unsigned int *letters =
+				X509_STORE_CTX_get_ex_data(ctx,
+					get_proxy_auth_ex_data_idx());
+
+			if (letters)
+				{
+				int found_any = 0;
+				int i;
+				PROXY_CERT_INFO_EXTENSION *pci =
+					X509_get_ext_d2i(xs, NID_proxyCertInfo,
+						NULL, NULL);
+
+				switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage))
+					{
+				case NID_Independent:
+					/* Completely meaningless in this
+					   program, as there's no way to
+					   grant explicit rights to a
+					   specific PrC.  Basically, using
+					   id-ppl-Independent is the perfect
+					   way to grant no rights at all. */
+					fprintf(stderr, "  Independent proxy certificate");
+					for (i = 0; i < 26; i++)
+						letters[i] = 0;
+					break;
+				case NID_id_ppl_inheritAll:
+					/* This is basically a NOP, we
+					   simply let the current rights
+					   stand as they are. */
+					fprintf(stderr, "  Proxy certificate inherits all");
+					break;
+				default:
+					s = (char *)
+						pci->proxyPolicy->policy->data;
+					i = pci->proxyPolicy->policy->length;
+
+					/* The algorithm works as follows:
+					   it is assumed that previous
+					   iterations or the initial granted
+					   rights has already set some elements
+					   of `letters'.  What we need to do is
+					   to clear those that weren't granted
+					   by the current PrC as well.  The
+					   easiest way to do this is to add 1
+					   to all the elements whose letters
+					   are given with the current policy.
+					   That way, all elements that are set
+					   by the current policy and were
+					   already set by earlier policies and
+					   through the original grant of rights
+					   will get the value 2 or higher.
+					   The last thing to do is to sweep
+					   through `letters' and keep the
+					   elements having the value 2 as set,
+					   and clear all the others. */
+
+					fprintf(stderr, "  Certificate proxy rights = %*.*s", i, i, s);
+					while(i-- > 0)
+						{
+						int c = *s++;
+						if (isascii(c) && isalpha(c))
+							{
+							if (islower(c))
+								c = toupper(c);
+							letters[c - 'A']++;
+							}
+						}
+					for (i = 0; i < 26; i++)
+						if (letters[i] < 2)
+							letters[i] = 0;
+						else
+							letters[i] = 1;
+					}
+
+				found_any = 0;
+				fprintf(stderr,
+					", resulting proxy rights = ");
+				for(i = 0; i < 26; i++)
+					if (letters[i])
+						{
+						fprintf(stderr, "%c", i + 'A');
+						found_any = 1;
+						}
+				if (!found_any)
+					fprintf(stderr, "none");
+				fprintf(stderr, "\n");
+
+				PROXY_CERT_INFO_EXTENSION_free(pci);
+				}
+			}
+		}
+
+	return(ok);
+	}
+
+static void process_proxy_debug(int indent, const char *format, ...)
+	{
+	static const char indentation[] =
+		">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
+		">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; /* That's 80 > */
+	char my_format[256];
+	va_list args;
+
+	BIO_snprintf(my_format, sizeof(my_format), "%*.*s %s",
+		indent, indent, indentation, format);
+
+	va_start(args, format);
+	vfprintf(stderr, my_format, args);
+	va_end(args);
+	}
+/* Priority levels:
+   0	[!]var, ()
+   1	& ^
+   2	|
+*/
+static int process_proxy_cond_adders(unsigned int letters[26],
+	const char *cond, const char **cond_end, int *pos, int indent);
+static int process_proxy_cond_val(unsigned int letters[26],
+	const char *cond, const char **cond_end, int *pos, int indent)
+	{
+	int c;
+	int ok = 1;
+	int negate = 0;
+
+	while(isspace((int)*cond))
+		{
+		cond++; (*pos)++;
+		}
+	c = *cond;
+
+	if (debug)
+		process_proxy_debug(indent,
+			"Start process_proxy_cond_val at position %d: %s\n",
+			*pos, cond);
+
+	while(c == '!')
+		{
+		negate = !negate;
+		cond++; (*pos)++;
+		while(isspace((int)*cond))
+			{
+			cond++; (*pos)++;
+			}
+		c = *cond;
+		}
+
+	if (c == '(')
+		{
+		cond++; (*pos)++;
+		ok = process_proxy_cond_adders(letters, cond, cond_end, pos,
+			indent + 1);
+		cond = *cond_end;
+		if (ok < 0)
+			goto end;
+		while(isspace((int)*cond))
+			{
+			cond++; (*pos)++;
+			}
+		c = *cond;
+		if (c != ')')
+			{
+			fprintf(stderr,
+				"Weird condition character in position %d: "
+				"%c\n", *pos, c);
+			ok = -1;
+			goto end;
+			}
+		cond++; (*pos)++;
+		}
+	else if (isascii(c) && isalpha(c))
+		{
+		if (islower(c))
+			c = toupper(c);
+		ok = letters[c - 'A'];
+		cond++; (*pos)++;
+		}
+	else
+		{
+		fprintf(stderr,
+			"Weird condition character in position %d: "
+			"%c\n", *pos, c);
+		ok = -1;
+		goto end;
+		}
+ end:
+	*cond_end = cond;
+	if (ok >= 0 && negate)
+		ok = !ok;
+
+	if (debug)
+		process_proxy_debug(indent,
+			"End process_proxy_cond_val at position %d: %s, returning %d\n",
+			*pos, cond, ok);
+
+	return ok;
+	}
+static int process_proxy_cond_multipliers(unsigned int letters[26],
+	const char *cond, const char **cond_end, int *pos, int indent)
+	{
+	int ok;
+	char c;
+
+	if (debug)
+		process_proxy_debug(indent,
+			"Start process_proxy_cond_multipliers at position %d: %s\n",
+			*pos, cond);
+
+	ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1);
+	cond = *cond_end;
+	if (ok < 0)
+		goto end;
+
+	while(ok >= 0)
+		{
+		while(isspace((int)*cond))
+			{
+			cond++; (*pos)++;
+			}
+		c = *cond;
+
+		switch(c)
+			{
+		case '&':
+		case '^':
+			{
+			int save_ok = ok;
+
+			cond++; (*pos)++;
+			ok = process_proxy_cond_val(letters,
+				cond, cond_end, pos, indent + 1);
+			cond = *cond_end;
+			if (ok < 0)
+				break;
+
+			switch(c)
+				{
+			case '&':
+				ok &= save_ok;
+				break;
+			case '^':
+				ok ^= save_ok;
+				break;
+			default:
+				fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
+					" STOPPING\n");
+				EXIT(1);
+				}
+			}
+			break;
+		default:
+			goto end;
+			}
+		}
+ end:
+	if (debug)
+		process_proxy_debug(indent,
+			"End process_proxy_cond_multipliers at position %d: %s, returning %d\n",
+			*pos, cond, ok);
+
+	*cond_end = cond;
+	return ok;
+	}
+static int process_proxy_cond_adders(unsigned int letters[26],
+	const char *cond, const char **cond_end, int *pos, int indent)
+	{
+	int ok;
+	char c;
+
+	if (debug)
+		process_proxy_debug(indent,
+			"Start process_proxy_cond_adders at position %d: %s\n",
+			*pos, cond);
+
+	ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos,
+		indent + 1);
+	cond = *cond_end;
+	if (ok < 0)
+		goto end;
+
+	while(ok >= 0)
+		{
+		while(isspace((int)*cond))
+			{
+			cond++; (*pos)++;
+			}
+		c = *cond;
+
+		switch(c)
+			{
+		case '|':
+			{
+			int save_ok = ok;
+
+			cond++; (*pos)++;
+			ok = process_proxy_cond_multipliers(letters,
+				cond, cond_end, pos, indent + 1);
+			cond = *cond_end;
+			if (ok < 0)
+				break;
+
+			switch(c)
+				{
+			case '|':
+				ok |= save_ok;
+				break;
+			default:
+				fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
+					" STOPPING\n");
+				EXIT(1);
+				}
+			}
+			break;
+		default:
+			goto end;
+			}
+		}
+ end:
+	if (debug)
+		process_proxy_debug(indent,
+			"End process_proxy_cond_adders at position %d: %s, returning %d\n",
+			*pos, cond, ok);
+
+	*cond_end = cond;
+	return ok;
+	}
+
+static int process_proxy_cond(unsigned int letters[26],
+	const char *cond, const char **cond_end)
+	{
+	int pos = 1;
+	return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1);
+	}
+
+static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg)
+	{
+	int ok=1;
+	struct app_verify_arg *cb_arg = arg;
+	unsigned int letters[26]; /* only used with proxy_auth */
+
+	if (cb_arg->app_verify)
+		{
+		char *s = NULL,buf[256];
+
+		fprintf(stderr, "In app_verify_callback, allowing cert. ");
+		fprintf(stderr, "Arg is: %s\n", cb_arg->string);
+		fprintf(stderr, "Finished printing do we have a context? 0x%p a cert? 0x%p\n",
+			(void *)ctx, (void *)ctx->cert);
+		if (ctx->cert)
+			s=X509_NAME_oneline(X509_get_subject_name(ctx->cert),buf,256);
+		if (s != NULL)
+			{
+			fprintf(stderr,"cert depth=%d %s\n",ctx->error_depth,buf);
+			}
+		return(1);
+		}
+	if (cb_arg->proxy_auth)
+		{
+		int found_any = 0, i;
+		char *sp;
+
+		for(i = 0; i < 26; i++)
+			letters[i] = 0;
+		for(sp = cb_arg->proxy_auth; *sp; sp++)
+			{
+			int c = *sp;
+			if (isascii(c) && isalpha(c))
+				{
+				if (islower(c))
+					c = toupper(c);
+				letters[c - 'A'] = 1;
+				}
+			}
+
+		fprintf(stderr,
+			"  Initial proxy rights = ");
+		for(i = 0; i < 26; i++)
+			if (letters[i])
+				{
+				fprintf(stderr, "%c", i + 'A');
+				found_any = 1;
+				}
+		if (!found_any)
+			fprintf(stderr, "none");
+		fprintf(stderr, "\n");
+
+		X509_STORE_CTX_set_ex_data(ctx,
+			get_proxy_auth_ex_data_idx(),letters);
+		}
+	if (cb_arg->allow_proxy_certs)
+		{
+		X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
+		}
+
+#ifndef OPENSSL_NO_X509_VERIFY
+# ifdef OPENSSL_FIPS
+	if(s->version == TLS1_VERSION)
+		FIPS_allow_md5(1);
+# endif
+	ok = X509_verify_cert(ctx);
+# ifdef OPENSSL_FIPS
+	if(s->version == TLS1_VERSION)
+		FIPS_allow_md5(0);
+# endif
+#endif
+
+	if (cb_arg->proxy_auth)
+		{
+		if (ok > 0)
+			{
+			const char *cond_end = NULL;
+
+			ok = process_proxy_cond(letters,
+				cb_arg->proxy_cond, &cond_end);
+
+			if (ok < 0)
+				EXIT(3);
+			if (*cond_end)
+				{
+				fprintf(stderr, "Stopped processing condition before it's end.\n");
+				ok = 0;
+				}
+			if (!ok)
+				fprintf(stderr, "Proxy rights check with condition '%s' proved invalid\n",
+					cb_arg->proxy_cond);
+			else
+				fprintf(stderr, "Proxy rights check with condition '%s' proved valid\n",
+					cb_arg->proxy_cond);
+			}
+		}
+	return(ok);
+	}
+
+#ifndef OPENSSL_NO_RSA
+static RSA *rsa_tmp=NULL;
+
+static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
+	{
+	BIGNUM *bn = NULL;
+	if (rsa_tmp == NULL)
+		{
+		bn = BN_new();
+		rsa_tmp = RSA_new();
+		if(!bn || !rsa_tmp || !BN_set_word(bn, RSA_F4))
+			{
+			BIO_printf(bio_err, "Memory error...");
+			goto end;
+			}
+		BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
+		(void)BIO_flush(bio_err);
+		if(!RSA_generate_key_ex(rsa_tmp,keylength,bn,NULL))
+			{
+			BIO_printf(bio_err, "Error generating key.");
+			RSA_free(rsa_tmp);
+			rsa_tmp = NULL;
+			}
+end:
+		BIO_printf(bio_err,"\n");
+		(void)BIO_flush(bio_err);
+		}
+	if(bn) BN_free(bn);
+	return(rsa_tmp);
+	}
+
+static void free_tmp_rsa(void)
+	{
+	if (rsa_tmp != NULL)
+		{
+		RSA_free(rsa_tmp);
+		rsa_tmp = NULL;
+		}
+	}
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* These DH parameters have been generated as follows:
+ *    $ openssl dhparam -C -noout 512
+ *    $ openssl dhparam -C -noout 1024
+ *    $ openssl dhparam -C -noout -dsaparam 1024
+ * (The third function has been renamed to avoid name conflicts.)
+ */
+static DH *get_dh512()
+	{
+	static unsigned char dh512_p[]={
+		0xCB,0xC8,0xE1,0x86,0xD0,0x1F,0x94,0x17,0xA6,0x99,0xF0,0xC6,
+		0x1F,0x0D,0xAC,0xB6,0x25,0x3E,0x06,0x39,0xCA,0x72,0x04,0xB0,
+		0x6E,0xDA,0xC0,0x61,0xE6,0x7A,0x77,0x25,0xE8,0x3B,0xB9,0x5F,
+		0x9A,0xB6,0xB5,0xFE,0x99,0x0B,0xA1,0x93,0x4E,0x35,0x33,0xB8,
+		0xE1,0xF1,0x13,0x4F,0x59,0x1A,0xD2,0x57,0xC0,0x26,0x21,0x33,
+		0x02,0xC5,0xAE,0x23,
+		};
+	static unsigned char dh512_g[]={
+		0x02,
+		};
+	DH *dh;
+
+	if ((dh=DH_new()) == NULL) return(NULL);
+	dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
+	dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
+	if ((dh->p == NULL) || (dh->g == NULL))
+		{ DH_free(dh); return(NULL); }
+	return(dh);
+	}
+
+static DH *get_dh1024()
+	{
+	static unsigned char dh1024_p[]={
+		0xF8,0x81,0x89,0x7D,0x14,0x24,0xC5,0xD1,0xE6,0xF7,0xBF,0x3A,
+		0xE4,0x90,0xF4,0xFC,0x73,0xFB,0x34,0xB5,0xFA,0x4C,0x56,0xA2,
+		0xEA,0xA7,0xE9,0xC0,0xC0,0xCE,0x89,0xE1,0xFA,0x63,0x3F,0xB0,
+		0x6B,0x32,0x66,0xF1,0xD1,0x7B,0xB0,0x00,0x8F,0xCA,0x87,0xC2,
+		0xAE,0x98,0x89,0x26,0x17,0xC2,0x05,0xD2,0xEC,0x08,0xD0,0x8C,
+		0xFF,0x17,0x52,0x8C,0xC5,0x07,0x93,0x03,0xB1,0xF6,0x2F,0xB8,
+		0x1C,0x52,0x47,0x27,0x1B,0xDB,0xD1,0x8D,0x9D,0x69,0x1D,0x52,
+		0x4B,0x32,0x81,0xAA,0x7F,0x00,0xC8,0xDC,0xE6,0xD9,0xCC,0xC1,
+		0x11,0x2D,0x37,0x34,0x6C,0xEA,0x02,0x97,0x4B,0x0E,0xBB,0xB1,
+		0x71,0x33,0x09,0x15,0xFD,0xDD,0x23,0x87,0x07,0x5E,0x89,0xAB,
+		0x6B,0x7C,0x5F,0xEC,0xA6,0x24,0xDC,0x53,
+		};
+	static unsigned char dh1024_g[]={
+		0x02,
+		};
+	DH *dh;
+
+	if ((dh=DH_new()) == NULL) return(NULL);
+	dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
+	dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
+	if ((dh->p == NULL) || (dh->g == NULL))
+		{ DH_free(dh); return(NULL); }
+	return(dh);
+	}
+
+static DH *get_dh1024dsa()
+	{
+	static unsigned char dh1024_p[]={
+		0xC8,0x00,0xF7,0x08,0x07,0x89,0x4D,0x90,0x53,0xF3,0xD5,0x00,
+		0x21,0x1B,0xF7,0x31,0xA6,0xA2,0xDA,0x23,0x9A,0xC7,0x87,0x19,
+		0x3B,0x47,0xB6,0x8C,0x04,0x6F,0xFF,0xC6,0x9B,0xB8,0x65,0xD2,
+		0xC2,0x5F,0x31,0x83,0x4A,0xA7,0x5F,0x2F,0x88,0x38,0xB6,0x55,
+		0xCF,0xD9,0x87,0x6D,0x6F,0x9F,0xDA,0xAC,0xA6,0x48,0xAF,0xFC,
+		0x33,0x84,0x37,0x5B,0x82,0x4A,0x31,0x5D,0xE7,0xBD,0x52,0x97,
+		0xA1,0x77,0xBF,0x10,0x9E,0x37,0xEA,0x64,0xFA,0xCA,0x28,0x8D,
+		0x9D,0x3B,0xD2,0x6E,0x09,0x5C,0x68,0xC7,0x45,0x90,0xFD,0xBB,
+		0x70,0xC9,0x3A,0xBB,0xDF,0xD4,0x21,0x0F,0xC4,0x6A,0x3C,0xF6,
+		0x61,0xCF,0x3F,0xD6,0x13,0xF1,0x5F,0xBC,0xCF,0xBC,0x26,0x9E,
+		0xBC,0x0B,0xBD,0xAB,0x5D,0xC9,0x54,0x39,
+		};
+	static unsigned char dh1024_g[]={
+		0x3B,0x40,0x86,0xE7,0xF3,0x6C,0xDE,0x67,0x1C,0xCC,0x80,0x05,
+		0x5A,0xDF,0xFE,0xBD,0x20,0x27,0x74,0x6C,0x24,0xC9,0x03,0xF3,
+		0xE1,0x8D,0xC3,0x7D,0x98,0x27,0x40,0x08,0xB8,0x8C,0x6A,0xE9,
+		0xBB,0x1A,0x3A,0xD6,0x86,0x83,0x5E,0x72,0x41,0xCE,0x85,0x3C,
+		0xD2,0xB3,0xFC,0x13,0xCE,0x37,0x81,0x9E,0x4C,0x1C,0x7B,0x65,
+		0xD3,0xE6,0xA6,0x00,0xF5,0x5A,0x95,0x43,0x5E,0x81,0xCF,0x60,
+		0xA2,0x23,0xFC,0x36,0xA7,0x5D,0x7A,0x4C,0x06,0x91,0x6E,0xF6,
+		0x57,0xEE,0x36,0xCB,0x06,0xEA,0xF5,0x3D,0x95,0x49,0xCB,0xA7,
+		0xDD,0x81,0xDF,0x80,0x09,0x4A,0x97,0x4D,0xA8,0x22,0x72,0xA1,
+		0x7F,0xC4,0x70,0x56,0x70,0xE8,0x20,0x10,0x18,0x8F,0x2E,0x60,
+		0x07,0xE7,0x68,0x1A,0x82,0x5D,0x32,0xA2,
+		};
+	DH *dh;
+
+	if ((dh=DH_new()) == NULL) return(NULL);
+	dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
+	dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
+	if ((dh->p == NULL) || (dh->g == NULL))
+		{ DH_free(dh); return(NULL); }
+	dh->length = 160;
+	return(dh);
+	}
+#endif
+
+#ifndef OPENSSL_NO_PSK
+/* convert the PSK key (psk_key) in ascii to binary (psk) */
+static int psk_key2bn(const char *pskkey, unsigned char *psk,
+	unsigned int max_psk_len)
+	{
+	int ret;
+	BIGNUM *bn = NULL;
+
+	ret = BN_hex2bn(&bn, pskkey);
+	if (!ret)
+		{
+		BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", pskkey); 
+		if (bn)
+			BN_free(bn);
+		return 0;
+		}
+	if (BN_num_bytes(bn) > (int)max_psk_len)
+		{
+		BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n",
+			max_psk_len, BN_num_bytes(bn));
+		BN_free(bn);
+		return 0;
+		}
+	ret = BN_bn2bin(bn, psk);
+	BN_free(bn);
+	return ret;
+	}
+
+static unsigned int psk_client_callback(SSL *ssl, const char *hint, char *identity,
+	unsigned int max_identity_len, unsigned char *psk,
+	unsigned int max_psk_len)
+	{
+	int ret;
+	unsigned int psk_len = 0;
+
+	ret = BIO_snprintf(identity, max_identity_len, "Client_identity");
+	if (ret < 0)
+		goto out_err;
+	if (debug)
+		fprintf(stderr, "client: created identity '%s' len=%d\n", identity, ret);
+	ret = psk_key2bn(psk_key, psk, max_psk_len);
+	if (ret < 0)
+		goto out_err;
+	psk_len = ret;
+out_err:
+	return psk_len;
+	}
+
+static unsigned int psk_server_callback(SSL *ssl, const char *identity,
+	unsigned char *psk, unsigned int max_psk_len)
+	{
+	unsigned int psk_len=0;
+
+	if (strcmp(identity, "Client_identity") != 0)
+		{
+		BIO_printf(bio_err, "server: PSK error: client identity not found\n");
+		return 0;
+		}
+	psk_len=psk_key2bn(psk_key, psk, max_psk_len);
+	return psk_len;
+	}
+#endif
+
+static int do_test_cipherlist(void)
+	{
+	int i = 0;
+	const SSL_METHOD *meth;
+	const SSL_CIPHER *ci, *tci = NULL;
+
+#ifndef OPENSSL_NO_SSL2
+	fprintf(stderr, "testing SSLv2 cipher list order: ");
+	meth = SSLv2_method();
+	while ((ci = meth->get_cipher(i++)) != NULL)
+		{
+		if (tci != NULL)
+			if (ci->id >= tci->id)
+				{
+				fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
+				return 0;
+				}
+		tci = ci;
+		}
+	fprintf(stderr, "ok\n");
+#endif
+#ifndef OPENSSL_NO_SSL3
+	fprintf(stderr, "testing SSLv3 cipher list order: ");
+	meth = SSLv3_method();
+	tci = NULL;
+	while ((ci = meth->get_cipher(i++)) != NULL)
+		{
+		if (tci != NULL)
+			if (ci->id >= tci->id)
+				{
+				fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
+				return 0;
+				}
+		tci = ci;
+		}
+	fprintf(stderr, "ok\n");
+#endif
+#ifndef OPENSSL_NO_TLS1
+	fprintf(stderr, "testing TLSv1 cipher list order: ");
+	meth = TLSv1_method();
+	tci = NULL;
+	while ((ci = meth->get_cipher(i++)) != NULL)
+		{
+		if (tci != NULL)
+			if (ci->id >= tci->id)
+				{
+				fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
+				return 0;
+				}
+		tci = ci;
+		}
+	fprintf(stderr, "ok\n");
+#endif
+
+	return 1;
+	}
diff --git a/openssl/ssl/t1_clnt.c b/openssl/ssl/t1_clnt.c
new file mode 100644
index 0000000..c87af17
--- /dev/null
+++ b/openssl/ssl/t1_clnt.c
@@ -0,0 +1,79 @@
+/* ssl/t1_clnt.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "ssl_locl.h"
+#include <openssl/buffer.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+
+static const SSL_METHOD *tls1_get_client_method(int ver);
+static const SSL_METHOD *tls1_get_client_method(int ver)
+	{
+	if (ver == TLS1_VERSION)
+		return(TLSv1_client_method());
+	else
+		return(NULL);
+	}
+
+IMPLEMENT_tls1_meth_func(TLSv1_client_method,
+			ssl_undefined_function,
+			ssl3_connect,
+			tls1_get_client_method)
+
diff --git a/openssl/ssl/t1_enc.c b/openssl/ssl/t1_enc.c
new file mode 100644
index 0000000..b1d5b28
--- /dev/null
+++ b/openssl/ssl/t1_enc.c
@@ -0,0 +1,1134 @@
+/* ssl/t1_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include "ssl_locl.h"
+#ifndef OPENSSL_NO_COMP
+#include <openssl/comp.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/md5.h>
+#ifdef KSSL_DEBUG
+#include <openssl/des.h>
+#endif
+
+/* seed1 through seed5 are virtually concatenated */
+static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
+			int sec_len,
+			const void *seed1, int seed1_len,
+			const void *seed2, int seed2_len,
+			const void *seed3, int seed3_len,
+			const void *seed4, int seed4_len,
+			const void *seed5, int seed5_len,
+			unsigned char *out, int olen)
+	{
+	int chunk;
+	unsigned int j;
+	HMAC_CTX ctx;
+	HMAC_CTX ctx_tmp;
+	unsigned char A1[EVP_MAX_MD_SIZE];
+	unsigned int A1_len;
+	int ret = 0;
+	
+	chunk=EVP_MD_size(md);
+	OPENSSL_assert(chunk >= 0);
+
+	HMAC_CTX_init(&ctx);
+	HMAC_CTX_init(&ctx_tmp);
+	if (!HMAC_Init_ex(&ctx,sec,sec_len,md, NULL))
+		goto err;
+	if (!HMAC_Init_ex(&ctx_tmp,sec,sec_len,md, NULL))
+		goto err;
+	if (seed1 != NULL && !HMAC_Update(&ctx,seed1,seed1_len))
+		goto err;
+	if (seed2 != NULL && !HMAC_Update(&ctx,seed2,seed2_len))
+		goto err;
+	if (seed3 != NULL && !HMAC_Update(&ctx,seed3,seed3_len))
+		goto err;
+	if (seed4 != NULL && !HMAC_Update(&ctx,seed4,seed4_len))
+		goto err;
+	if (seed5 != NULL && !HMAC_Update(&ctx,seed5,seed5_len))
+		goto err;
+	if (!HMAC_Final(&ctx,A1,&A1_len))
+		goto err;
+
+	for (;;)
+		{
+		if (!HMAC_Init_ex(&ctx,NULL,0,NULL,NULL)) /* re-init */
+			goto err;
+		if (!HMAC_Init_ex(&ctx_tmp,NULL,0,NULL,NULL)) /* re-init */
+			goto err;
+		if (!HMAC_Update(&ctx,A1,A1_len))
+			goto err;
+		if (!HMAC_Update(&ctx_tmp,A1,A1_len))
+			goto err;
+		if (seed1 != NULL && !HMAC_Update(&ctx,seed1,seed1_len))
+			goto err;
+		if (seed2 != NULL && !HMAC_Update(&ctx,seed2,seed2_len))
+			goto err;
+		if (seed3 != NULL && !HMAC_Update(&ctx,seed3,seed3_len))
+			goto err;
+		if (seed4 != NULL && !HMAC_Update(&ctx,seed4,seed4_len))
+			goto err;
+		if (seed5 != NULL && !HMAC_Update(&ctx,seed5,seed5_len))
+			goto err;
+
+		if (olen > chunk)
+			{
+			if (!HMAC_Final(&ctx,out,&j))
+				goto err;
+			out+=j;
+			olen-=j;
+			if (!HMAC_Final(&ctx_tmp,A1,&A1_len)) /* calc the next A1 value */
+				goto err;
+			}
+		else	/* last one */
+			{
+			if (!HMAC_Final(&ctx,A1,&A1_len))
+				goto err;
+			memcpy(out,A1,olen);
+			break;
+			}
+		}
+	ret = 1;
+err:
+	HMAC_CTX_cleanup(&ctx);
+	HMAC_CTX_cleanup(&ctx_tmp);
+	OPENSSL_cleanse(A1,sizeof(A1));
+	return ret;
+	}
+
+/* seed1 through seed5 are virtually concatenated */
+static int tls1_PRF(long digest_mask,
+		     const void *seed1, int seed1_len,
+		     const void *seed2, int seed2_len,
+		     const void *seed3, int seed3_len,
+		     const void *seed4, int seed4_len,
+		     const void *seed5, int seed5_len,
+		     const unsigned char *sec, int slen,
+		     unsigned char *out1,
+		     unsigned char *out2, int olen)
+	{
+	int len,i,idx,count;
+	const unsigned char *S1;
+	long m;
+	const EVP_MD *md;
+	int ret = 0;
+
+	/* Count number of digests and partition sec evenly */
+	count=0;
+	for (idx=0;ssl_get_handshake_digest(idx,&m,&md);idx++) {
+		if ((m<<TLS1_PRF_DGST_SHIFT) & digest_mask) count++;
+	}	
+	len=slen/count;
+	S1=sec;
+	memset(out1,0,olen);
+	for (idx=0;ssl_get_handshake_digest(idx,&m,&md);idx++) {
+		if ((m<<TLS1_PRF_DGST_SHIFT) & digest_mask) {
+			if (!md) {
+				SSLerr(SSL_F_TLS1_PRF,
+				SSL_R_UNSUPPORTED_DIGEST_TYPE);
+				goto err;				
+			}
+			if (!tls1_P_hash(md ,S1,len+(slen&1),
+					seed1,seed1_len,seed2,seed2_len,seed3,seed3_len,seed4,seed4_len,seed5,seed5_len,
+					out2,olen))
+				goto err;
+			S1+=len;
+			for (i=0; i<olen; i++)
+			{
+				out1[i]^=out2[i];
+			}
+		}
+	}
+	ret = 1;
+err:
+	return ret;
+}
+static int tls1_generate_key_block(SSL *s, unsigned char *km,
+	     unsigned char *tmp, int num)
+	{
+	int ret;
+	ret = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+		 TLS_MD_KEY_EXPANSION_CONST,TLS_MD_KEY_EXPANSION_CONST_SIZE,
+		 s->s3->server_random,SSL3_RANDOM_SIZE,
+		 s->s3->client_random,SSL3_RANDOM_SIZE,
+		 NULL,0,NULL,0,
+		 s->session->master_key,s->session->master_key_length,
+		 km,tmp,num);
+#ifdef KSSL_DEBUG
+	printf("tls1_generate_key_block() ==> %d byte master_key =\n\t",
+                s->session->master_key_length);
+	{
+        int i;
+        for (i=0; i < s->session->master_key_length; i++)
+                {
+                printf("%02X", s->session->master_key[i]);
+                }
+        printf("\n");  }
+#endif    /* KSSL_DEBUG */
+	return ret;
+	}
+
+int tls1_change_cipher_state(SSL *s, int which)
+	{
+	static const unsigned char empty[]="";
+	unsigned char *p,*mac_secret;
+	unsigned char *exp_label;
+	unsigned char tmp1[EVP_MAX_KEY_LENGTH];
+	unsigned char tmp2[EVP_MAX_KEY_LENGTH];
+	unsigned char iv1[EVP_MAX_IV_LENGTH*2];
+	unsigned char iv2[EVP_MAX_IV_LENGTH*2];
+	unsigned char *ms,*key,*iv;
+	int client_write;
+	EVP_CIPHER_CTX *dd;
+	const EVP_CIPHER *c;
+#ifndef OPENSSL_NO_COMP
+	const SSL_COMP *comp;
+#endif
+	const EVP_MD *m;
+	int mac_type;
+	int *mac_secret_size;
+	EVP_MD_CTX *mac_ctx;
+	EVP_PKEY *mac_key;
+	int is_export,n,i,j,k,exp_label_len,cl;
+	int reuse_dd = 0;
+
+	is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
+	c=s->s3->tmp.new_sym_enc;
+	m=s->s3->tmp.new_hash;
+	mac_type = s->s3->tmp.new_mac_pkey_type;
+#ifndef OPENSSL_NO_COMP
+	comp=s->s3->tmp.new_compression;
+#endif
+
+#ifdef KSSL_DEBUG
+	printf("tls1_change_cipher_state(which= %d) w/\n", which);
+	printf("\talg= %ld/%ld, comp= %p\n",
+	       s->s3->tmp.new_cipher->algorithm_mkey,
+	       s->s3->tmp.new_cipher->algorithm_auth,
+	       comp);
+	printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c);
+	printf("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n",
+                c->nid,c->block_size,c->key_len,c->iv_len);
+	printf("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length);
+	{
+        int i;
+        for (i=0; i<s->s3->tmp.key_block_length; i++)
+		printf("%02x", key_block[i]);  printf("\n");
+        }
+#endif	/* KSSL_DEBUG */
+
+	if (which & SSL3_CC_READ)
+		{
+		if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
+			s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
+			else
+			s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;
+
+		if (s->enc_read_ctx != NULL)
+			reuse_dd = 1;
+		else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
+			goto err;
+		else
+			/* make sure it's intialized in case we exit later with an error */
+			EVP_CIPHER_CTX_init(s->enc_read_ctx);
+		dd= s->enc_read_ctx;
+		mac_ctx=ssl_replace_hash(&s->read_hash,NULL);
+#ifndef OPENSSL_NO_COMP
+		if (s->expand != NULL)
+			{
+			COMP_CTX_free(s->expand);
+			s->expand=NULL;
+			}
+		if (comp != NULL)
+			{
+			s->expand=COMP_CTX_new(comp->method);
+			if (s->expand == NULL)
+				{
+				SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
+				goto err2;
+				}
+			if (s->s3->rrec.comp == NULL)
+				s->s3->rrec.comp=(unsigned char *)
+					OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH);
+			if (s->s3->rrec.comp == NULL)
+				goto err;
+			}
+#endif
+		/* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */
+ 		if (s->version != DTLS1_VERSION)
+			memset(&(s->s3->read_sequence[0]),0,8);
+		mac_secret= &(s->s3->read_mac_secret[0]);
+		mac_secret_size=&(s->s3->read_mac_secret_size);
+		}
+	else
+		{
+		if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
+			s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
+			else
+			s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
+		if (s->enc_write_ctx != NULL)
+			reuse_dd = 1;
+		else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
+			goto err;
+		else
+			/* make sure it's intialized in case we exit later with an error */
+			EVP_CIPHER_CTX_init(s->enc_write_ctx);
+		dd= s->enc_write_ctx;
+		mac_ctx = ssl_replace_hash(&s->write_hash,NULL);
+#ifndef OPENSSL_NO_COMP
+		if (s->compress != NULL)
+			{
+			COMP_CTX_free(s->compress);
+			s->compress=NULL;
+			}
+		if (comp != NULL)
+			{
+			s->compress=COMP_CTX_new(comp->method);
+			if (s->compress == NULL)
+				{
+				SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
+				goto err2;
+				}
+			}
+#endif
+		/* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */
+ 		if (s->version != DTLS1_VERSION)
+			memset(&(s->s3->write_sequence[0]),0,8);
+		mac_secret= &(s->s3->write_mac_secret[0]);
+		mac_secret_size = &(s->s3->write_mac_secret_size);
+		}
+
+	if (reuse_dd)
+		EVP_CIPHER_CTX_cleanup(dd);
+
+	p=s->s3->tmp.key_block;
+	i=*mac_secret_size=s->s3->tmp.new_mac_secret_size;
+
+	cl=EVP_CIPHER_key_length(c);
+	j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
+	               cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
+	/* Was j=(exp)?5:EVP_CIPHER_key_length(c); */
+	k=EVP_CIPHER_iv_length(c);
+	if (	(which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
+		(which == SSL3_CHANGE_CIPHER_SERVER_READ))
+		{
+		ms=  &(p[ 0]); n=i+i;
+		key= &(p[ n]); n+=j+j;
+		iv=  &(p[ n]); n+=k+k;
+		exp_label=(unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST;
+		exp_label_len=TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE;
+		client_write=1;
+		}
+	else
+		{
+		n=i;
+		ms=  &(p[ n]); n+=i+j;
+		key= &(p[ n]); n+=j+k;
+		iv=  &(p[ n]); n+=k;
+		exp_label=(unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST;
+		exp_label_len=TLS_MD_SERVER_WRITE_KEY_CONST_SIZE;
+		client_write=0;
+		}
+
+	if (n > s->s3->tmp.key_block_length)
+		{
+		SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR);
+		goto err2;
+		}
+
+	memcpy(mac_secret,ms,i);
+	mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,
+			mac_secret,*mac_secret_size);
+	EVP_DigestSignInit(mac_ctx,NULL,m,NULL,mac_key);
+	EVP_PKEY_free(mac_key);
+#ifdef TLS_DEBUG
+printf("which = %04X\nmac key=",which);
+{ int z; for (z=0; z<i; z++) printf("%02X%c",ms[z],((z+1)%16)?' ':'\n'); }
+#endif
+	if (is_export)
+		{
+		/* In here I set both the read and write key/iv to the
+		 * same value since only the correct one will be used :-).
+		 */
+		if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+				exp_label,exp_label_len,
+				s->s3->client_random,SSL3_RANDOM_SIZE,
+				s->s3->server_random,SSL3_RANDOM_SIZE,
+				NULL,0,NULL,0,
+				key,j,tmp1,tmp2,EVP_CIPHER_key_length(c)))
+			goto err2;
+		key=tmp1;
+
+		if (k > 0)
+			{
+			if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+					TLS_MD_IV_BLOCK_CONST,TLS_MD_IV_BLOCK_CONST_SIZE,
+					s->s3->client_random,SSL3_RANDOM_SIZE,
+					s->s3->server_random,SSL3_RANDOM_SIZE,
+					NULL,0,NULL,0,
+					empty,0,iv1,iv2,k*2))
+				goto err2;
+			if (client_write)
+				iv=iv1;
+			else
+				iv= &(iv1[k]);
+			}
+		}
+
+	s->session->key_arg_length=0;
+#ifdef KSSL_DEBUG
+	{
+        int i;
+	printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n");
+	printf("\tkey= "); for (i=0; i<c->key_len; i++) printf("%02x", key[i]);
+	printf("\n");
+	printf("\t iv= "); for (i=0; i<c->iv_len; i++) printf("%02x", iv[i]);
+	printf("\n");
+	}
+#endif	/* KSSL_DEBUG */
+
+	EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
+#ifdef TLS_DEBUG
+printf("which = %04X\nkey=",which);
+{ int z; for (z=0; z<EVP_CIPHER_key_length(c); z++) printf("%02X%c",key[z],((z+1)%16)?' ':'\n'); }
+printf("\niv=");
+{ int z; for (z=0; z<k; z++) printf("%02X%c",iv[z],((z+1)%16)?' ':'\n'); }
+printf("\n");
+#endif
+
+	OPENSSL_cleanse(tmp1,sizeof(tmp1));
+	OPENSSL_cleanse(tmp2,sizeof(tmp1));
+	OPENSSL_cleanse(iv1,sizeof(iv1));
+	OPENSSL_cleanse(iv2,sizeof(iv2));
+	return(1);
+err:
+	SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE);
+err2:
+	return(0);
+	}
+
+int tls1_setup_key_block(SSL *s)
+	{
+	unsigned char *p1,*p2=NULL;
+	const EVP_CIPHER *c;
+	const EVP_MD *hash;
+	int num;
+	SSL_COMP *comp;
+	int mac_type= NID_undef,mac_secret_size=0;
+	int ret=0;
+
+#ifdef KSSL_DEBUG
+	printf ("tls1_setup_key_block()\n");
+#endif	/* KSSL_DEBUG */
+
+	if (s->s3->tmp.key_block_length != 0)
+		return(1);
+
+	if (!ssl_cipher_get_evp(s->session,&c,&hash,&mac_type,&mac_secret_size,&comp))
+		{
+		SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
+		return(0);
+		}
+
+	s->s3->tmp.new_sym_enc=c;
+	s->s3->tmp.new_hash=hash;
+	s->s3->tmp.new_mac_pkey_type = mac_type;
+	s->s3->tmp.new_mac_secret_size = mac_secret_size;
+	num=EVP_CIPHER_key_length(c)+mac_secret_size+EVP_CIPHER_iv_length(c);
+	num*=2;
+
+	ssl3_cleanup_key_block(s);
+
+	if ((p1=(unsigned char *)OPENSSL_malloc(num)) == NULL)
+		{
+		SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	s->s3->tmp.key_block_length=num;
+	s->s3->tmp.key_block=p1;
+
+	if ((p2=(unsigned char *)OPENSSL_malloc(num)) == NULL)
+		{
+		SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+#ifdef TLS_DEBUG
+printf("client random\n");
+{ int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->client_random[z],((z+1)%16)?' ':'\n'); }
+printf("server random\n");
+{ int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->server_random[z],((z+1)%16)?' ':'\n'); }
+printf("pre-master\n");
+{ int z; for (z=0; z<s->session->master_key_length; z++) printf("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); }
+#endif
+	if (!tls1_generate_key_block(s,p1,p2,num))
+		goto err;
+#ifdef TLS_DEBUG
+printf("\nkey block\n");
+{ int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); }
+#endif
+
+	if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
+		{
+		/* enable vulnerability countermeasure for CBC ciphers with
+		 * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
+		 */
+		s->s3->need_empty_fragments = 1;
+
+		if (s->session->cipher != NULL)
+			{
+			if (s->session->cipher->algorithm_enc == SSL_eNULL)
+				s->s3->need_empty_fragments = 0;
+			
+#ifndef OPENSSL_NO_RC4
+			if (s->session->cipher->algorithm_enc == SSL_RC4)
+				s->s3->need_empty_fragments = 0;
+#endif
+			}
+		}
+		
+	ret = 1;
+err:
+	if (p2)
+		{
+		OPENSSL_cleanse(p2,num);
+		OPENSSL_free(p2);
+		}
+	return(ret);
+	}
+
+int tls1_enc(SSL *s, int send)
+	{
+	SSL3_RECORD *rec;
+	EVP_CIPHER_CTX *ds;
+	unsigned long l;
+	int bs,i,ii,j,k,n=0;
+	const EVP_CIPHER *enc;
+
+	if (send)
+		{
+		if (EVP_MD_CTX_md(s->write_hash))
+			{
+			n=EVP_MD_CTX_size(s->write_hash);
+			OPENSSL_assert(n >= 0);
+			}
+		ds=s->enc_write_ctx;
+		rec= &(s->s3->wrec);
+		if (s->enc_write_ctx == NULL)
+			enc=NULL;
+		else
+			enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
+		}
+	else
+		{
+		if (EVP_MD_CTX_md(s->read_hash))
+			{
+			n=EVP_MD_CTX_size(s->read_hash);
+			OPENSSL_assert(n >= 0);
+			}
+		ds=s->enc_read_ctx;
+		rec= &(s->s3->rrec);
+		if (s->enc_read_ctx == NULL)
+			enc=NULL;
+		else
+			enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
+		}
+
+#ifdef KSSL_DEBUG
+	printf("tls1_enc(%d)\n", send);
+#endif    /* KSSL_DEBUG */
+
+	if ((s->session == NULL) || (ds == NULL) ||
+		(enc == NULL))
+		{
+		memmove(rec->data,rec->input,rec->length);
+		rec->input=rec->data;
+		}
+	else
+		{
+		l=rec->length;
+		bs=EVP_CIPHER_block_size(ds->cipher);
+
+		if ((bs != 1) && send)
+			{
+			i=bs-((int)l%bs);
+
+			/* Add weird padding of upto 256 bytes */
+
+			/* we need to add 'i' padding bytes of value j */
+			j=i-1;
+			if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG)
+				{
+				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
+					j++;
+				}
+			for (k=(int)l; k<(int)(l+i); k++)
+				rec->input[k]=j;
+			l+=i;
+			rec->length+=i;
+			}
+
+#ifdef KSSL_DEBUG
+		{
+                unsigned long ui;
+		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
+                        ds,rec->data,rec->input,l);
+		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
+                        ds->buf_len, ds->cipher->key_len,
+                        DES_KEY_SZ, DES_SCHEDULE_SZ,
+                        ds->cipher->iv_len);
+		printf("\t\tIV: ");
+		for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
+		printf("\n");
+		printf("\trec->input=");
+		for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
+		printf("\n");
+		}
+#endif	/* KSSL_DEBUG */
+
+		if (!send)
+			{
+			if (l == 0 || l%bs != 0)
+				{
+				SSLerr(SSL_F_TLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED);
+				return 0;
+				}
+			}
+		
+		EVP_Cipher(ds,rec->data,rec->input,l);
+
+#ifdef KSSL_DEBUG
+		{
+                unsigned long i;
+                printf("\trec->data=");
+		for (i=0; i<l; i++)
+                        printf(" %02x", rec->data[i]);  printf("\n");
+                }
+#endif	/* KSSL_DEBUG */
+
+		if ((bs != 1) && !send)
+			{
+			ii=i=rec->data[l-1]; /* padding_length */
+			i++;
+			/* NB: if compression is in operation the first packet
+			 * may not be of even length so the padding bug check
+			 * cannot be performed. This bug workaround has been
+			 * around since SSLeay so hopefully it is either fixed
+			 * now or no buggy implementation supports compression 
+			 * [steve]
+			 */
+			if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG)
+				&& !s->expand)
+				{
+				/* First packet is even in size, so check */
+				if ((memcmp(s->s3->read_sequence,
+					"\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1))
+					s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
+				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
+					i--;
+				}
+			/* TLS 1.0 does not bound the number of padding bytes by the block size.
+			 * All of them must have value 'padding_length'. */
+			if (i > (int)rec->length)
+				{
+				/* Incorrect padding. SSLerr() and ssl3_alert are done
+				 * by caller: we don't want to reveal whether this is
+				 * a decryption error or a MAC verification failure
+				 * (see http://www.openssl.org/~bodo/tls-cbc.txt) */
+				return -1;
+				}
+			for (j=(int)(l-i); j<(int)l; j++)
+				{
+				if (rec->data[j] != ii)
+					{
+					/* Incorrect padding */
+					return -1;
+					}
+				}
+			rec->length-=i;
+			}
+		}
+	return(1);
+	}
+int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
+	{
+	unsigned int ret;
+	EVP_MD_CTX ctx, *d=NULL;
+	int i;
+
+	if (s->s3->handshake_buffer) 
+		if (!ssl3_digest_cached_records(s))
+			return 0;
+
+	for (i=0;i<SSL_MAX_DIGEST;i++) 
+		{
+		  if (s->s3->handshake_dgst[i]&&EVP_MD_CTX_type(s->s3->handshake_dgst[i])==md_nid) 
+		  	{
+		  	d=s->s3->handshake_dgst[i];
+			break;
+			}
+		}
+	if (!d) {
+		SSLerr(SSL_F_TLS1_CERT_VERIFY_MAC,SSL_R_NO_REQUIRED_DIGEST);
+		return 0;
+	}	
+
+	EVP_MD_CTX_init(&ctx);
+	EVP_MD_CTX_copy_ex(&ctx,d);
+	EVP_DigestFinal_ex(&ctx,out,&ret);
+	EVP_MD_CTX_cleanup(&ctx);
+	return((int)ret);
+	}
+
+int tls1_final_finish_mac(SSL *s,
+	     const char *str, int slen, unsigned char *out)
+	{
+	unsigned int i;
+	EVP_MD_CTX ctx;
+	unsigned char buf[2*EVP_MAX_MD_SIZE];
+	unsigned char *q,buf2[12];
+	int idx;
+	long mask;
+	int err=0;
+	const EVP_MD *md; 
+
+	q=buf;
+
+	if (s->s3->handshake_buffer) 
+		if (!ssl3_digest_cached_records(s))
+			return 0;
+
+	EVP_MD_CTX_init(&ctx);
+
+	for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++)
+		{
+		if (mask & s->s3->tmp.new_cipher->algorithm2)
+			{
+			int hashsize = EVP_MD_size(md);
+			if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
+				{
+				/* internal error: 'buf' is too small for this cipersuite! */
+				err = 1;
+				}
+			else
+				{
+				EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
+				EVP_DigestFinal_ex(&ctx,q,&i);
+				if (i != (unsigned int)hashsize) /* can't really happen */
+					err = 1;
+				q+=i;
+				}
+			}
+		}
+		
+	if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+			str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0,
+			s->session->master_key,s->session->master_key_length,
+			out,buf2,sizeof buf2))
+		err = 1;
+	EVP_MD_CTX_cleanup(&ctx);
+
+	if (err)
+		return 0;
+	else
+		return sizeof buf2;
+	}
+
+int tls1_mac(SSL *ssl, unsigned char *md, int send)
+	{
+	SSL3_RECORD *rec;
+	unsigned char *seq;
+	EVP_MD_CTX *hash;
+	size_t md_size;
+	int i;
+	EVP_MD_CTX hmac, *mac_ctx;
+	unsigned char buf[5]; 
+	int stream_mac = (send?(ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM):(ssl->mac_flags&SSL_MAC_FLAG_READ_MAC_STREAM));
+	int t;
+
+	if (send)
+		{
+		rec= &(ssl->s3->wrec);
+		seq= &(ssl->s3->write_sequence[0]);
+		hash=ssl->write_hash;
+		}
+	else
+		{
+		rec= &(ssl->s3->rrec);
+		seq= &(ssl->s3->read_sequence[0]);
+		hash=ssl->read_hash;
+		}
+
+	t=EVP_MD_CTX_size(hash);
+	OPENSSL_assert(t >= 0);
+	md_size=t;
+
+	buf[0]=rec->type;
+	buf[1]=(unsigned char)(ssl->version>>8);
+	buf[2]=(unsigned char)(ssl->version);
+	buf[3]=rec->length>>8;
+	buf[4]=rec->length&0xff;
+
+	/* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */
+	if (stream_mac) 
+		{
+			mac_ctx = hash;
+		}
+		else
+		{
+			EVP_MD_CTX_copy(&hmac,hash);
+			mac_ctx = &hmac;
+		}
+
+	if (ssl->version == DTLS1_VERSION || ssl->version == DTLS1_BAD_VER)
+		{
+		unsigned char dtlsseq[8],*p=dtlsseq;
+
+		s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p);
+		memcpy (p,&seq[2],6);
+
+		EVP_DigestSignUpdate(mac_ctx,dtlsseq,8);
+		}
+	else
+		EVP_DigestSignUpdate(mac_ctx,seq,8);
+
+	EVP_DigestSignUpdate(mac_ctx,buf,5);
+	EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length);
+	t=EVP_DigestSignFinal(mac_ctx,md,&md_size);
+	OPENSSL_assert(t > 0);
+		
+	if (!stream_mac) EVP_MD_CTX_cleanup(&hmac);
+#ifdef TLS_DEBUG
+printf("sec=");
+{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); }
+printf("seq=");
+{int z; for (z=0; z<8; z++) printf("%02X ",seq[z]); printf("\n"); }
+printf("buf=");
+{int z; for (z=0; z<5; z++) printf("%02X ",buf[z]); printf("\n"); }
+printf("rec=");
+{unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); }
+#endif
+
+	if (ssl->version != DTLS1_VERSION && ssl->version != DTLS1_BAD_VER)
+		{
+		for (i=7; i>=0; i--)
+			{
+			++seq[i];
+			if (seq[i] != 0) break; 
+			}
+		}
+
+#ifdef TLS_DEBUG
+{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",md[z]); printf("\n"); }
+#endif
+	return(md_size);
+	}
+
+int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
+	     int len)
+	{
+	unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH];
+	const void *co = NULL, *so = NULL;
+	int col = 0, sol = 0;
+
+#ifdef KSSL_DEBUG
+	printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
+#endif	/* KSSL_DEBUG */
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	if (s->s3->client_opaque_prf_input != NULL && s->s3->server_opaque_prf_input != NULL &&
+	    s->s3->client_opaque_prf_input_len > 0 &&
+	    s->s3->client_opaque_prf_input_len == s->s3->server_opaque_prf_input_len)
+		{
+		co = s->s3->client_opaque_prf_input;
+		col = s->s3->server_opaque_prf_input_len;
+		so = s->s3->server_opaque_prf_input;
+		sol = s->s3->client_opaque_prf_input_len; /* must be same as col (see draft-rescorla-tls-opaque-prf-input-00.txt, section 3.1) */
+		}
+#endif
+
+	tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+		TLS_MD_MASTER_SECRET_CONST,TLS_MD_MASTER_SECRET_CONST_SIZE,
+		s->s3->client_random,SSL3_RANDOM_SIZE,
+		co, col,
+		s->s3->server_random,SSL3_RANDOM_SIZE,
+		so, sol,
+		p,len,
+		s->session->master_key,buff,sizeof buff);
+
+#ifdef KSSL_DEBUG
+	printf ("tls1_generate_master_secret() complete\n");
+#endif	/* KSSL_DEBUG */
+	return(SSL3_MASTER_SECRET_SIZE);
+	}
+
+int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
+	 const char *label, size_t llen, const unsigned char *context,
+	 size_t contextlen, int use_context)
+	{
+	unsigned char *buff;
+	unsigned char *val = NULL;
+	size_t vallen, currentvalpos;
+	int rv;
+
+#ifdef KSSL_DEBUG
+	printf ("tls1_export_keying_material(%p,%p,%d,%s,%d,%p,%d)\n", s, out, olen, label, llen, p, plen);
+#endif	/* KSSL_DEBUG */
+
+	buff = OPENSSL_malloc(olen);
+	if (buff == NULL) goto err2;
+
+	/* construct PRF arguments
+	 * we construct the PRF argument ourself rather than passing separate
+	 * values into the TLS PRF to ensure that the concatenation of values
+	 * does not create a prohibited label.
+	 */
+	vallen = llen + SSL3_RANDOM_SIZE * 2;
+	if (use_context)
+		{
+		vallen += 2 + contextlen;
+		}
+
+	val = OPENSSL_malloc(vallen);
+	if (val == NULL) goto err2;
+	currentvalpos = 0;
+	memcpy(val + currentvalpos, (unsigned char *) label, llen);
+	currentvalpos += llen;
+	memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE);
+	currentvalpos += SSL3_RANDOM_SIZE;
+	memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE);
+	currentvalpos += SSL3_RANDOM_SIZE;
+
+	if (use_context)
+		{
+		val[currentvalpos] = (contextlen >> 8) & 0xff;
+		currentvalpos++;
+		val[currentvalpos] = contextlen & 0xff;
+		currentvalpos++;
+		if ((contextlen > 0) || (context != NULL))
+			{
+			memcpy(val + currentvalpos, context, contextlen);
+			}
+		}
+
+	/* disallow prohibited labels
+	 * note that SSL3_RANDOM_SIZE > max(prohibited label len) =
+	 * 15, so size of val > max(prohibited label len) = 15 and the
+	 * comparisons won't have buffer overflow
+	 */
+	if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST,
+		 TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0) goto err1;
+	if (memcmp(val, TLS_MD_SERVER_FINISH_CONST,
+		 TLS_MD_SERVER_FINISH_CONST_SIZE) == 0) goto err1;
+	if (memcmp(val, TLS_MD_MASTER_SECRET_CONST,
+		 TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) goto err1;
+	if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
+		 TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) goto err1;
+
+	rv = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+		      val, vallen,
+		      NULL, 0,
+		      NULL, 0,
+		      NULL, 0,
+		      NULL, 0,
+		      s->session->master_key,s->session->master_key_length,
+		      out,buff,olen);
+
+#ifdef KSSL_DEBUG
+	printf ("tls1_export_keying_material() complete\n");
+#endif	/* KSSL_DEBUG */
+	goto ret;
+err1:
+	SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
+	rv = 0;
+	goto ret;
+err2:
+	SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, ERR_R_MALLOC_FAILURE);
+	rv = 0;
+ret:
+	if (buff != NULL) OPENSSL_free(buff);
+	if (val != NULL) OPENSSL_free(val);
+	return(rv);
+	}
+
+int tls1_alert_code(int code)
+	{
+	switch (code)
+		{
+	case SSL_AD_CLOSE_NOTIFY:	return(SSL3_AD_CLOSE_NOTIFY);
+	case SSL_AD_UNEXPECTED_MESSAGE:	return(SSL3_AD_UNEXPECTED_MESSAGE);
+	case SSL_AD_BAD_RECORD_MAC:	return(SSL3_AD_BAD_RECORD_MAC);
+	case SSL_AD_DECRYPTION_FAILED:	return(TLS1_AD_DECRYPTION_FAILED);
+	case SSL_AD_RECORD_OVERFLOW:	return(TLS1_AD_RECORD_OVERFLOW);
+	case SSL_AD_DECOMPRESSION_FAILURE:return(SSL3_AD_DECOMPRESSION_FAILURE);
+	case SSL_AD_HANDSHAKE_FAILURE:	return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_NO_CERTIFICATE:	return(-1);
+	case SSL_AD_BAD_CERTIFICATE:	return(SSL3_AD_BAD_CERTIFICATE);
+	case SSL_AD_UNSUPPORTED_CERTIFICATE:return(SSL3_AD_UNSUPPORTED_CERTIFICATE);
+	case SSL_AD_CERTIFICATE_REVOKED:return(SSL3_AD_CERTIFICATE_REVOKED);
+	case SSL_AD_CERTIFICATE_EXPIRED:return(SSL3_AD_CERTIFICATE_EXPIRED);
+	case SSL_AD_CERTIFICATE_UNKNOWN:return(SSL3_AD_CERTIFICATE_UNKNOWN);
+	case SSL_AD_ILLEGAL_PARAMETER:	return(SSL3_AD_ILLEGAL_PARAMETER);
+	case SSL_AD_UNKNOWN_CA:		return(TLS1_AD_UNKNOWN_CA);
+	case SSL_AD_ACCESS_DENIED:	return(TLS1_AD_ACCESS_DENIED);
+	case SSL_AD_DECODE_ERROR:	return(TLS1_AD_DECODE_ERROR);
+	case SSL_AD_DECRYPT_ERROR:	return(TLS1_AD_DECRYPT_ERROR);
+	case SSL_AD_EXPORT_RESTRICTION:	return(TLS1_AD_EXPORT_RESTRICTION);
+	case SSL_AD_PROTOCOL_VERSION:	return(TLS1_AD_PROTOCOL_VERSION);
+	case SSL_AD_INSUFFICIENT_SECURITY:return(TLS1_AD_INSUFFICIENT_SECURITY);
+	case SSL_AD_INTERNAL_ERROR:	return(TLS1_AD_INTERNAL_ERROR);
+	case SSL_AD_USER_CANCELLED:	return(TLS1_AD_USER_CANCELLED);
+	case SSL_AD_NO_RENEGOTIATION:	return(TLS1_AD_NO_RENEGOTIATION);
+	case SSL_AD_UNSUPPORTED_EXTENSION: return(TLS1_AD_UNSUPPORTED_EXTENSION);
+	case SSL_AD_CERTIFICATE_UNOBTAINABLE: return(TLS1_AD_CERTIFICATE_UNOBTAINABLE);
+	case SSL_AD_UNRECOGNIZED_NAME:	return(TLS1_AD_UNRECOGNIZED_NAME);
+	case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
+	case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
+	case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
+#if 0 /* not appropriate for TLS, not used for DTLS */
+	case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return 
+					  (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
+#endif
+	default:			return(-1);
+		}
+	}
+
diff --git a/openssl/ssl/t1_lib.c b/openssl/ssl/t1_lib.c
new file mode 100644
index 0000000..03becbc
--- /dev/null
+++ b/openssl/ssl/t1_lib.c
@@ -0,0 +1,1866 @@
+/* ssl/t1_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/ocsp.h>
+#include "ssl_locl.h"
+
+const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT;
+
+#ifndef OPENSSL_NO_TLSEXT
+static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen,
+				const unsigned char *sess_id, int sesslen,
+				SSL_SESSION **psess);
+#endif
+
+SSL3_ENC_METHOD TLSv1_enc_data={
+	tls1_enc,
+	tls1_mac,
+	tls1_setup_key_block,
+	tls1_generate_master_secret,
+	tls1_change_cipher_state,
+	tls1_final_finish_mac,
+	TLS1_FINISH_MAC_LENGTH,
+	tls1_cert_verify_mac,
+	TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
+	TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
+	tls1_alert_code,
+	tls1_export_keying_material,
+	};
+
+long tls1_default_timeout(void)
+	{
+	/* 2 hours, the 24 hours mentioned in the TLSv1 spec
+	 * is way too long for http, the cache would over fill */
+	return(60*60*2);
+	}
+
+int tls1_new(SSL *s)
+	{
+	if (!ssl3_new(s)) return(0);
+	s->method->ssl_clear(s);
+	return(1);
+	}
+
+void tls1_free(SSL *s)
+	{
+#ifndef OPENSSL_NO_TLSEXT
+	if (s->tlsext_session_ticket)
+		{
+		OPENSSL_free(s->tlsext_session_ticket);
+		}
+#endif /* OPENSSL_NO_TLSEXT */
+	ssl3_free(s);
+	}
+
+void tls1_clear(SSL *s)
+	{
+	ssl3_clear(s);
+	s->version=TLS1_VERSION;
+	}
+
+#ifndef OPENSSL_NO_EC
+static int nid_list[] =
+	{
+		NID_sect163k1, /* sect163k1 (1) */
+		NID_sect163r1, /* sect163r1 (2) */
+		NID_sect163r2, /* sect163r2 (3) */
+		NID_sect193r1, /* sect193r1 (4) */ 
+		NID_sect193r2, /* sect193r2 (5) */ 
+		NID_sect233k1, /* sect233k1 (6) */
+		NID_sect233r1, /* sect233r1 (7) */ 
+		NID_sect239k1, /* sect239k1 (8) */ 
+		NID_sect283k1, /* sect283k1 (9) */
+		NID_sect283r1, /* sect283r1 (10) */ 
+		NID_sect409k1, /* sect409k1 (11) */ 
+		NID_sect409r1, /* sect409r1 (12) */
+		NID_sect571k1, /* sect571k1 (13) */ 
+		NID_sect571r1, /* sect571r1 (14) */ 
+		NID_secp160k1, /* secp160k1 (15) */
+		NID_secp160r1, /* secp160r1 (16) */ 
+		NID_secp160r2, /* secp160r2 (17) */ 
+		NID_secp192k1, /* secp192k1 (18) */
+		NID_X9_62_prime192v1, /* secp192r1 (19) */ 
+		NID_secp224k1, /* secp224k1 (20) */ 
+		NID_secp224r1, /* secp224r1 (21) */
+		NID_secp256k1, /* secp256k1 (22) */ 
+		NID_X9_62_prime256v1, /* secp256r1 (23) */ 
+		NID_secp384r1, /* secp384r1 (24) */
+		NID_secp521r1  /* secp521r1 (25) */	
+	};
+	
+int tls1_ec_curve_id2nid(int curve_id)
+	{
+	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+	if ((curve_id < 1) || ((unsigned int)curve_id >
+				sizeof(nid_list)/sizeof(nid_list[0])))
+		return 0;
+	return nid_list[curve_id-1];
+	}
+
+int tls1_ec_nid2curve_id(int nid)
+	{
+	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+	switch (nid)
+		{
+	case NID_sect163k1: /* sect163k1 (1) */
+		return 1;
+	case NID_sect163r1: /* sect163r1 (2) */
+		return 2;
+	case NID_sect163r2: /* sect163r2 (3) */
+		return 3;
+	case NID_sect193r1: /* sect193r1 (4) */ 
+		return 4;
+	case NID_sect193r2: /* sect193r2 (5) */ 
+		return 5;
+	case NID_sect233k1: /* sect233k1 (6) */
+		return 6;
+	case NID_sect233r1: /* sect233r1 (7) */ 
+		return 7;
+	case NID_sect239k1: /* sect239k1 (8) */ 
+		return 8;
+	case NID_sect283k1: /* sect283k1 (9) */
+		return 9;
+	case NID_sect283r1: /* sect283r1 (10) */ 
+		return 10;
+	case NID_sect409k1: /* sect409k1 (11) */ 
+		return 11;
+	case NID_sect409r1: /* sect409r1 (12) */
+		return 12;
+	case NID_sect571k1: /* sect571k1 (13) */ 
+		return 13;
+	case NID_sect571r1: /* sect571r1 (14) */ 
+		return 14;
+	case NID_secp160k1: /* secp160k1 (15) */
+		return 15;
+	case NID_secp160r1: /* secp160r1 (16) */ 
+		return 16;
+	case NID_secp160r2: /* secp160r2 (17) */ 
+		return 17;
+	case NID_secp192k1: /* secp192k1 (18) */
+		return 18;
+	case NID_X9_62_prime192v1: /* secp192r1 (19) */ 
+		return 19;
+	case NID_secp224k1: /* secp224k1 (20) */ 
+		return 20;
+	case NID_secp224r1: /* secp224r1 (21) */
+		return 21;
+	case NID_secp256k1: /* secp256k1 (22) */ 
+		return 22;
+	case NID_X9_62_prime256v1: /* secp256r1 (23) */ 
+		return 23;
+	case NID_secp384r1: /* secp384r1 (24) */
+		return 24;
+	case NID_secp521r1:  /* secp521r1 (25) */	
+		return 25;
+	default:
+		return 0;
+		}
+	}
+#endif /* OPENSSL_NO_EC */
+
+#ifndef OPENSSL_NO_TLSEXT
+unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
+	{
+	int extdatalen=0;
+	unsigned char *ret = p;
+
+	/* don't add extensions for SSLv3 unless doing secure renegotiation */
+	if (s->client_version == SSL3_VERSION
+					&& !s->s3->send_connection_binding)
+		return p;
+
+	ret+=2;
+
+	if (ret>=limit) return NULL; /* this really never occurs, but ... */
+
+ 	if (s->tlsext_hostname != NULL)
+		{ 
+		/* Add TLS extension servername to the Client Hello message */
+		unsigned long size_str;
+		long lenmax; 
+
+		/* check for enough space.
+		   4 for the servername type and entension length
+		   2 for servernamelist length
+		   1 for the hostname type
+		   2 for hostname length
+		   + hostname length 
+		*/
+		   
+		if ((lenmax = limit - ret - 9) < 0 
+		    || (size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax) 
+			return NULL;
+			
+		/* extension type and length */
+		s2n(TLSEXT_TYPE_server_name,ret); 
+		s2n(size_str+5,ret);
+		
+		/* length of servername list */
+		s2n(size_str+3,ret);
+	
+		/* hostname type, length and hostname */
+		*(ret++) = (unsigned char) TLSEXT_NAMETYPE_host_name;
+		s2n(size_str,ret);
+		memcpy(ret, s->tlsext_hostname, size_str);
+		ret+=size_str;
+		}
+
+        /* Add RI if renegotiating */
+        if (s->new_session)
+          {
+          int el;
+          
+          if(!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0))
+              {
+              SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+              return NULL;
+              }
+
+          if((limit - p - 4 - el) < 0) return NULL;
+          
+          s2n(TLSEXT_TYPE_renegotiate,ret);
+          s2n(el,ret);
+
+          if(!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el))
+              {
+              SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+              return NULL;
+              }
+
+          ret += el;
+        }
+
+#ifndef OPENSSL_NO_EC
+	if (s->tlsext_ecpointformatlist != NULL &&
+	    s->version != DTLS1_VERSION)
+		{
+		/* Add TLS extension ECPointFormats to the ClientHello message */
+		long lenmax; 
+
+		if ((lenmax = limit - ret - 5) < 0) return NULL; 
+		if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL;
+		if (s->tlsext_ecpointformatlist_length > 255)
+			{
+			SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+			return NULL;
+			}
+		
+		s2n(TLSEXT_TYPE_ec_point_formats,ret);
+		s2n(s->tlsext_ecpointformatlist_length + 1,ret);
+		*(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
+		memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
+		ret+=s->tlsext_ecpointformatlist_length;
+		}
+	if (s->tlsext_ellipticcurvelist != NULL &&
+	    s->version != DTLS1_VERSION)
+		{
+		/* Add TLS extension EllipticCurves to the ClientHello message */
+		long lenmax; 
+
+		if ((lenmax = limit - ret - 6) < 0) return NULL; 
+		if (s->tlsext_ellipticcurvelist_length > (unsigned long)lenmax) return NULL;
+		if (s->tlsext_ellipticcurvelist_length > 65532)
+			{
+			SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+			return NULL;
+			}
+		
+		s2n(TLSEXT_TYPE_elliptic_curves,ret);
+		s2n(s->tlsext_ellipticcurvelist_length + 2, ret);
+
+		/* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
+		 * elliptic_curve_list, but the examples use two bytes.
+		 * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
+		 * resolves this to two bytes.
+		 */
+		s2n(s->tlsext_ellipticcurvelist_length, ret);
+		memcpy(ret, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
+		ret+=s->tlsext_ellipticcurvelist_length;
+		}
+#endif /* OPENSSL_NO_EC */
+
+	if (!(SSL_get_options(s) & SSL_OP_NO_TICKET))
+		{
+		int ticklen;
+		if (!s->new_session && s->session && s->session->tlsext_tick)
+			ticklen = s->session->tlsext_ticklen;
+		else if (s->session && s->tlsext_session_ticket &&
+			 s->tlsext_session_ticket->data)
+			{
+			ticklen = s->tlsext_session_ticket->length;
+			s->session->tlsext_tick = OPENSSL_malloc(ticklen);
+			if (!s->session->tlsext_tick)
+				return NULL;
+			memcpy(s->session->tlsext_tick,
+			       s->tlsext_session_ticket->data,
+			       ticklen);
+			s->session->tlsext_ticklen = ticklen;
+			}
+		else
+			ticklen = 0;
+		if (ticklen == 0 && s->tlsext_session_ticket &&
+		    s->tlsext_session_ticket->data == NULL)
+			goto skip_ext;
+		/* Check for enough room 2 for extension type, 2 for len
+ 		 * rest for ticket
+  		 */
+		if ((long)(limit - ret - 4 - ticklen) < 0) return NULL;
+		s2n(TLSEXT_TYPE_session_ticket,ret); 
+		s2n(ticklen,ret);
+		if (ticklen)
+			{
+			memcpy(ret, s->session->tlsext_tick, ticklen);
+			ret += ticklen;
+			}
+		}
+		skip_ext:
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	if (s->s3->client_opaque_prf_input != NULL &&
+	    s->version != DTLS1_VERSION)
+		{
+		size_t col = s->s3->client_opaque_prf_input_len;
+		
+		if ((long)(limit - ret - 6 - col < 0))
+			return NULL;
+		if (col > 0xFFFD) /* can't happen */
+			return NULL;
+
+		s2n(TLSEXT_TYPE_opaque_prf_input, ret); 
+		s2n(col + 2, ret);
+		s2n(col, ret);
+		memcpy(ret, s->s3->client_opaque_prf_input, col);
+		ret += col;
+		}
+#endif
+
+	if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp &&
+	    s->version != DTLS1_VERSION)
+		{
+		int i;
+		long extlen, idlen, itmp;
+		OCSP_RESPID *id;
+
+		idlen = 0;
+		for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++)
+			{
+			id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
+			itmp = i2d_OCSP_RESPID(id, NULL);
+			if (itmp <= 0)
+				return NULL;
+			idlen += itmp + 2;
+			}
+
+		if (s->tlsext_ocsp_exts)
+			{
+			extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
+			if (extlen < 0)
+				return NULL;
+			}
+		else
+			extlen = 0;
+			
+		if ((long)(limit - ret - 7 - extlen - idlen) < 0) return NULL;
+		s2n(TLSEXT_TYPE_status_request, ret);
+		if (extlen + idlen > 0xFFF0)
+			return NULL;
+		s2n(extlen + idlen + 5, ret);
+		*(ret++) = TLSEXT_STATUSTYPE_ocsp;
+		s2n(idlen, ret);
+		for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++)
+			{
+			/* save position of id len */
+			unsigned char *q = ret;
+			id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
+			/* skip over id len */
+			ret += 2;
+			itmp = i2d_OCSP_RESPID(id, &ret);
+			/* write id len */
+			s2n(itmp, q);
+			}
+		s2n(extlen, ret);
+		if (extlen > 0)
+			i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
+		}
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+	if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len)
+		{
+		/* The client advertises an emtpy extension to indicate its
+		 * support for Next Protocol Negotiation */
+		if (limit - ret - 4 < 0)
+			return NULL;
+		s2n(TLSEXT_TYPE_next_proto_neg,ret);
+		s2n(0,ret);
+		}
+#endif
+
+	if ((extdatalen = ret-p-2)== 0) 
+		return p;
+
+	s2n(extdatalen,p);
+	return ret;
+	}
+
+unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
+	{
+	int extdatalen=0;
+	unsigned char *ret = p;
+#ifndef OPENSSL_NO_NEXTPROTONEG
+	int next_proto_neg_seen;
+#endif
+
+	/* don't add extensions for SSLv3, unless doing secure renegotiation */
+	if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
+		return p;
+	
+	ret+=2;
+	if (ret>=limit) return NULL; /* this really never occurs, but ... */
+
+	if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL)
+		{ 
+		if ((long)(limit - ret - 4) < 0) return NULL; 
+
+		s2n(TLSEXT_TYPE_server_name,ret);
+		s2n(0,ret);
+		}
+
+	if(s->s3->send_connection_binding)
+        {
+          int el;
+          
+          if(!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0))
+              {
+              SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+              return NULL;
+              }
+
+          if((limit - p - 4 - el) < 0) return NULL;
+          
+          s2n(TLSEXT_TYPE_renegotiate,ret);
+          s2n(el,ret);
+
+          if(!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el))
+              {
+              SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+              return NULL;
+              }
+
+          ret += el;
+        }
+
+#ifndef OPENSSL_NO_EC
+	if (s->tlsext_ecpointformatlist != NULL &&
+	    s->version != DTLS1_VERSION)
+		{
+		/* Add TLS extension ECPointFormats to the ServerHello message */
+		long lenmax; 
+
+		if ((lenmax = limit - ret - 5) < 0) return NULL; 
+		if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL;
+		if (s->tlsext_ecpointformatlist_length > 255)
+			{
+			SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+			return NULL;
+			}
+		
+		s2n(TLSEXT_TYPE_ec_point_formats,ret);
+		s2n(s->tlsext_ecpointformatlist_length + 1,ret);
+		*(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
+		memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
+		ret+=s->tlsext_ecpointformatlist_length;
+
+		}
+	/* Currently the server should not respond with a SupportedCurves extension */
+#endif /* OPENSSL_NO_EC */
+
+	if (s->tlsext_ticket_expected
+		&& !(SSL_get_options(s) & SSL_OP_NO_TICKET)) 
+		{ 
+		if ((long)(limit - ret - 4) < 0) return NULL; 
+		s2n(TLSEXT_TYPE_session_ticket,ret);
+		s2n(0,ret);
+		}
+
+	if (s->tlsext_status_expected)
+		{ 
+		if ((long)(limit - ret - 4) < 0) return NULL; 
+		s2n(TLSEXT_TYPE_status_request,ret);
+		s2n(0,ret);
+		}
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	if (s->s3->server_opaque_prf_input != NULL &&
+	    s->version != DTLS1_VERSION)
+		{
+		size_t sol = s->s3->server_opaque_prf_input_len;
+		
+		if ((long)(limit - ret - 6 - sol) < 0)
+			return NULL;
+		if (sol > 0xFFFD) /* can't happen */
+			return NULL;
+
+		s2n(TLSEXT_TYPE_opaque_prf_input, ret); 
+		s2n(sol + 2, ret);
+		s2n(sol, ret);
+		memcpy(ret, s->s3->server_opaque_prf_input, sol);
+		ret += sol;
+		}
+#endif
+	if (((s->s3->tmp.new_cipher->id & 0xFFFF)==0x80 || (s->s3->tmp.new_cipher->id & 0xFFFF)==0x81) 
+		&& (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG))
+		{ const unsigned char cryptopro_ext[36] = {
+			0xfd, 0xe8, /*65000*/
+			0x00, 0x20, /*32 bytes length*/
+			0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85, 
+			0x03,   0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06, 
+			0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08, 
+			0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17};
+			if (limit-ret<36) return NULL;
+			memcpy(ret,cryptopro_ext,36);
+			ret+=36;
+
+		}
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+	next_proto_neg_seen = s->s3->next_proto_neg_seen;
+	s->s3->next_proto_neg_seen = 0;
+	if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb)
+		{
+		const unsigned char *npa;
+		unsigned int npalen;
+		int r;
+
+		r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen, s->ctx->next_protos_advertised_cb_arg);
+		if (r == SSL_TLSEXT_ERR_OK)
+			{
+			if ((long)(limit - ret - 4 - npalen) < 0) return NULL;
+			s2n(TLSEXT_TYPE_next_proto_neg,ret);
+			s2n(npalen,ret);
+			memcpy(ret, npa, npalen);
+			ret += npalen;
+			s->s3->next_proto_neg_seen = 1;
+			}
+		}
+#endif
+
+	if ((extdatalen = ret-p-2)== 0) 
+		return p;
+
+	s2n(extdatalen,p);
+	return ret;
+	}
+
+int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
+	{
+	unsigned short type;
+	unsigned short size;
+	unsigned short len;
+	unsigned char *data = *p;
+	int renegotiate_seen = 0;
+
+	s->servername_done = 0;
+	s->tlsext_status_type = -1;
+
+	if (data >= (d+n-2))
+		goto ri_check;
+	n2s(data,len);
+
+	if (data > (d+n-len)) 
+		goto ri_check;
+
+	while (data <= (d+n-4))
+		{
+		n2s(data,type);
+		n2s(data,size);
+
+		if (data+size > (d+n))
+	   		goto ri_check;
+#if 0
+		fprintf(stderr,"Received extension type %d size %d\n",type,size);
+#endif
+		if (s->tlsext_debug_cb)
+			s->tlsext_debug_cb(s, 0, type, data, size,
+						s->tlsext_debug_arg);
+/* The servername extension is treated as follows:
+
+   - Only the hostname type is supported with a maximum length of 255.
+   - The servername is rejected if too long or if it contains zeros,
+     in which case an fatal alert is generated.
+   - The servername field is maintained together with the session cache.
+   - When a session is resumed, the servername call back invoked in order
+     to allow the application to position itself to the right context. 
+   - The servername is acknowledged if it is new for a session or when 
+     it is identical to a previously used for the same session. 
+     Applications can control the behaviour.  They can at any time
+     set a 'desirable' servername for a new SSL object. This can be the
+     case for example with HTTPS when a Host: header field is received and
+     a renegotiation is requested. In this case, a possible servername
+     presented in the new client hello is only acknowledged if it matches
+     the value of the Host: field. 
+   - Applications must  use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
+     if they provide for changing an explicit servername context for the session,
+     i.e. when the session has been established with a servername extension. 
+   - On session reconnect, the servername extension may be absent. 
+
+*/      
+
+		if (type == TLSEXT_TYPE_server_name)
+			{
+			unsigned char *sdata;
+			int servname_type;
+			int dsize; 
+		
+			if (size < 2) 
+				{
+				*al = SSL_AD_DECODE_ERROR;
+				return 0;
+				}
+			n2s(data,dsize);  
+			size -= 2;
+			if (dsize > size  ) 
+				{
+				*al = SSL_AD_DECODE_ERROR;
+				return 0;
+				} 
+
+			sdata = data;
+			while (dsize > 3) 
+				{
+	 			servname_type = *(sdata++); 
+				n2s(sdata,len);
+				dsize -= 3;
+
+				if (len > dsize) 
+					{
+					*al = SSL_AD_DECODE_ERROR;
+					return 0;
+					}
+				if (s->servername_done == 0)
+				switch (servname_type)
+					{
+				case TLSEXT_NAMETYPE_host_name:
+					if (!s->hit)
+						{
+						if(s->session->tlsext_hostname)
+							{
+							*al = SSL_AD_DECODE_ERROR;
+							return 0;
+							}
+						if (len > TLSEXT_MAXLEN_host_name)
+							{
+							*al = TLS1_AD_UNRECOGNIZED_NAME;
+							return 0;
+							}
+						if ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL)
+							{
+							*al = TLS1_AD_INTERNAL_ERROR;
+							return 0;
+							}
+						memcpy(s->session->tlsext_hostname, sdata, len);
+						s->session->tlsext_hostname[len]='\0';
+						if (strlen(s->session->tlsext_hostname) != len) {
+							OPENSSL_free(s->session->tlsext_hostname);
+							s->session->tlsext_hostname = NULL;
+							*al = TLS1_AD_UNRECOGNIZED_NAME;
+							return 0;
+						}
+						s->servername_done = 1; 
+
+						}
+					else 
+						s->servername_done = s->session->tlsext_hostname
+							&& strlen(s->session->tlsext_hostname) == len 
+							&& strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0;
+					
+					break;
+
+				default:
+					break;
+					}
+				 
+				dsize -= len;
+				}
+			if (dsize != 0) 
+				{
+				*al = SSL_AD_DECODE_ERROR;
+				return 0;
+				}
+
+			}
+
+#ifndef OPENSSL_NO_EC
+		else if (type == TLSEXT_TYPE_ec_point_formats &&
+	             s->version != DTLS1_VERSION)
+			{
+			unsigned char *sdata = data;
+			int ecpointformatlist_length = *(sdata++);
+
+			if (ecpointformatlist_length != size - 1)
+				{
+				*al = TLS1_AD_DECODE_ERROR;
+				return 0;
+				}
+			if (!s->hit)
+				{
+				if(s->session->tlsext_ecpointformatlist)
+					{
+					OPENSSL_free(s->session->tlsext_ecpointformatlist);
+					s->session->tlsext_ecpointformatlist = NULL;
+					}
+				s->session->tlsext_ecpointformatlist_length = 0;
+				if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
+					{
+					*al = TLS1_AD_INTERNAL_ERROR;
+					return 0;
+					}
+				s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
+				memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
+				}
+#if 0
+			fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", s->session->tlsext_ecpointformatlist_length);
+			sdata = s->session->tlsext_ecpointformatlist;
+			for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
+				fprintf(stderr,"%i ",*(sdata++));
+			fprintf(stderr,"\n");
+#endif
+			}
+		else if (type == TLSEXT_TYPE_elliptic_curves &&
+	             s->version != DTLS1_VERSION)
+			{
+			unsigned char *sdata = data;
+			int ellipticcurvelist_length = (*(sdata++) << 8);
+			ellipticcurvelist_length += (*(sdata++));
+
+			if (ellipticcurvelist_length != size - 2)
+				{
+				*al = TLS1_AD_DECODE_ERROR;
+				return 0;
+				}
+			if (!s->hit)
+				{
+				if(s->session->tlsext_ellipticcurvelist)
+					{
+					*al = TLS1_AD_DECODE_ERROR;
+					return 0;
+					}
+				s->session->tlsext_ellipticcurvelist_length = 0;
+				if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL)
+					{
+					*al = TLS1_AD_INTERNAL_ERROR;
+					return 0;
+					}
+				s->session->tlsext_ellipticcurvelist_length = ellipticcurvelist_length;
+				memcpy(s->session->tlsext_ellipticcurvelist, sdata, ellipticcurvelist_length);
+				}
+#if 0
+			fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", s->session->tlsext_ellipticcurvelist_length);
+			sdata = s->session->tlsext_ellipticcurvelist;
+			for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++)
+				fprintf(stderr,"%i ",*(sdata++));
+			fprintf(stderr,"\n");
+#endif
+			}
+#endif /* OPENSSL_NO_EC */
+#ifdef TLSEXT_TYPE_opaque_prf_input
+		else if (type == TLSEXT_TYPE_opaque_prf_input &&
+	             s->version != DTLS1_VERSION)
+			{
+			unsigned char *sdata = data;
+
+			if (size < 2)
+				{
+				*al = SSL_AD_DECODE_ERROR;
+				return 0;
+				}
+			n2s(sdata, s->s3->client_opaque_prf_input_len);
+			if (s->s3->client_opaque_prf_input_len != size - 2)
+				{
+				*al = SSL_AD_DECODE_ERROR;
+				return 0;
+				}
+
+			if (s->s3->client_opaque_prf_input != NULL) /* shouldn't really happen */
+				OPENSSL_free(s->s3->client_opaque_prf_input);
+			if (s->s3->client_opaque_prf_input_len == 0)
+				s->s3->client_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
+			else
+				s->s3->client_opaque_prf_input = BUF_memdup(sdata, s->s3->client_opaque_prf_input_len);
+			if (s->s3->client_opaque_prf_input == NULL)
+				{
+				*al = TLS1_AD_INTERNAL_ERROR;
+				return 0;
+				}
+			}
+#endif
+		else if (type == TLSEXT_TYPE_session_ticket)
+			{
+			if (s->tls_session_ticket_ext_cb &&
+			    !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg))
+				{
+				*al = TLS1_AD_INTERNAL_ERROR;
+				return 0;
+				}
+			}
+		else if (type == TLSEXT_TYPE_renegotiate)
+			{
+			if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
+				return 0;
+			renegotiate_seen = 1;
+			}
+		else if (type == TLSEXT_TYPE_status_request &&
+		         s->version != DTLS1_VERSION && s->ctx->tlsext_status_cb)
+			{
+		
+			if (size < 5) 
+				{
+				*al = SSL_AD_DECODE_ERROR;
+				return 0;
+				}
+
+			s->tlsext_status_type = *data++;
+			size--;
+			if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp)
+				{
+				const unsigned char *sdata;
+				int dsize;
+				/* Read in responder_id_list */
+				n2s(data,dsize);
+				size -= 2;
+				if (dsize > size  ) 
+					{
+					*al = SSL_AD_DECODE_ERROR;
+					return 0;
+					}
+				while (dsize > 0)
+					{
+					OCSP_RESPID *id;
+					int idsize;
+					if (dsize < 4)
+						{
+						*al = SSL_AD_DECODE_ERROR;
+						return 0;
+						}
+					n2s(data, idsize);
+					dsize -= 2 + idsize;
+					size -= 2 + idsize;
+					if (dsize < 0)
+						{
+						*al = SSL_AD_DECODE_ERROR;
+						return 0;
+						}
+					sdata = data;
+					data += idsize;
+					id = d2i_OCSP_RESPID(NULL,
+								&sdata, idsize);
+					if (!id)
+						{
+						*al = SSL_AD_DECODE_ERROR;
+						return 0;
+						}
+					if (data != sdata)
+						{
+						OCSP_RESPID_free(id);
+						*al = SSL_AD_DECODE_ERROR;
+						return 0;
+						}
+					if (!s->tlsext_ocsp_ids
+						&& !(s->tlsext_ocsp_ids =
+						sk_OCSP_RESPID_new_null()))
+						{
+						OCSP_RESPID_free(id);
+						*al = SSL_AD_INTERNAL_ERROR;
+						return 0;
+						}
+					if (!sk_OCSP_RESPID_push(
+							s->tlsext_ocsp_ids, id))
+						{
+						OCSP_RESPID_free(id);
+						*al = SSL_AD_INTERNAL_ERROR;
+						return 0;
+						}
+					}
+
+				/* Read in request_extensions */
+				if (size < 2)
+					{
+					*al = SSL_AD_DECODE_ERROR;
+					return 0;
+					}
+				n2s(data,dsize);
+				size -= 2;
+				if (dsize != size)
+					{
+					*al = SSL_AD_DECODE_ERROR;
+					return 0;
+					}
+				sdata = data;
+				if (dsize > 0)
+					{
+					if (s->tlsext_ocsp_exts)
+						{
+						sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
+									   X509_EXTENSION_free);
+						}
+
+					s->tlsext_ocsp_exts =
+						d2i_X509_EXTENSIONS(NULL,
+							&sdata, dsize);
+					if (!s->tlsext_ocsp_exts
+						|| (data + dsize != sdata))
+						{
+						*al = SSL_AD_DECODE_ERROR;
+						return 0;
+						}
+					}
+				}
+				/* We don't know what to do with any other type
+ 			 	* so ignore it.
+ 			 	*/
+				else
+					s->tlsext_status_type = -1;
+			}
+#ifndef OPENSSL_NO_NEXTPROTONEG
+		else if (type == TLSEXT_TYPE_next_proto_neg &&
+                         s->s3->tmp.finish_md_len == 0)
+			{
+			/* We shouldn't accept this extension on a
+			 * renegotiation.
+			 *
+			 * s->new_session will be set on renegotiation, but we
+			 * probably shouldn't rely that it couldn't be set on
+			 * the initial renegotation too in certain cases (when
+			 * there's some other reason to disallow resuming an
+			 * earlier session -- the current code won't be doing
+			 * anything like that, but this might change).
+
+			 * A valid sign that there's been a previous handshake
+			 * in this connection is if s->s3->tmp.finish_md_len >
+			 * 0.  (We are talking about a check that will happen
+			 * in the Hello protocol round, well before a new
+			 * Finished message could have been computed.) */
+			s->s3->next_proto_neg_seen = 1;
+			}
+#endif
+
+		/* session ticket processed earlier */
+		data+=size;
+		}
+				
+	*p = data;
+
+	ri_check:
+
+	/* Need RI if renegotiating */
+
+	if (!renegotiate_seen && s->new_session &&
+		!(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+		{
+		*al = SSL_AD_HANDSHAKE_FAILURE;
+	 	SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT,
+				SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+		return 0;
+		}
+
+	return 1;
+	}
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+/* ssl_next_proto_validate validates a Next Protocol Negotiation block. No
+ * elements of zero length are allowed and the set of elements must exactly fill
+ * the length of the block. */
+static int ssl_next_proto_validate(unsigned char *d, unsigned len)
+	{
+	unsigned int off = 0;
+
+	while (off < len)
+		{
+		if (d[off] == 0)
+			return 0;
+		off += d[off];
+		off++;
+		}
+
+	return off == len;
+	}
+#endif
+
+int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
+	{
+	unsigned short length;
+	unsigned short type;
+	unsigned short size;
+	unsigned char *data = *p;
+	int tlsext_servername = 0;
+	int renegotiate_seen = 0;
+
+	if (data >= (d+n-2))
+		goto ri_check;
+
+	n2s(data,length);
+	if (data+length != d+n)
+		{
+		*al = SSL_AD_DECODE_ERROR;
+		return 0;
+		}
+
+	while(data <= (d+n-4))
+		{
+		n2s(data,type);
+		n2s(data,size);
+
+		if (data+size > (d+n))
+	   		goto ri_check;
+
+		if (s->tlsext_debug_cb)
+			s->tlsext_debug_cb(s, 1, type, data, size,
+						s->tlsext_debug_arg);
+
+		if (type == TLSEXT_TYPE_server_name)
+			{
+			if (s->tlsext_hostname == NULL || size > 0)
+				{
+				*al = TLS1_AD_UNRECOGNIZED_NAME;
+				return 0;
+				}
+			tlsext_servername = 1;   
+			}
+
+#ifndef OPENSSL_NO_EC
+		else if (type == TLSEXT_TYPE_ec_point_formats &&
+	             s->version != DTLS1_VERSION)
+			{
+			unsigned char *sdata = data;
+			int ecpointformatlist_length = *(sdata++);
+
+			if (ecpointformatlist_length != size - 1)
+				{
+				*al = TLS1_AD_DECODE_ERROR;
+				return 0;
+				}
+			s->session->tlsext_ecpointformatlist_length = 0;
+			if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist);
+			if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
+				{
+				*al = TLS1_AD_INTERNAL_ERROR;
+				return 0;
+				}
+			s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
+			memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
+#if 0
+			fprintf(stderr,"ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist ");
+			sdata = s->session->tlsext_ecpointformatlist;
+			for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
+				fprintf(stderr,"%i ",*(sdata++));
+			fprintf(stderr,"\n");
+#endif
+			}
+#endif /* OPENSSL_NO_EC */
+
+		else if (type == TLSEXT_TYPE_session_ticket)
+			{
+			if (s->tls_session_ticket_ext_cb &&
+			    !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg))
+				{
+				*al = TLS1_AD_INTERNAL_ERROR;
+				return 0;
+				}
+			if ((SSL_get_options(s) & SSL_OP_NO_TICKET)
+				|| (size > 0))
+				{
+				*al = TLS1_AD_UNSUPPORTED_EXTENSION;
+				return 0;
+				}
+			s->tlsext_ticket_expected = 1;
+			}
+#ifdef TLSEXT_TYPE_opaque_prf_input
+		else if (type == TLSEXT_TYPE_opaque_prf_input &&
+	             s->version != DTLS1_VERSION)
+			{
+			unsigned char *sdata = data;
+
+			if (size < 2)
+				{
+				*al = SSL_AD_DECODE_ERROR;
+				return 0;
+				}
+			n2s(sdata, s->s3->server_opaque_prf_input_len);
+			if (s->s3->server_opaque_prf_input_len != size - 2)
+				{
+				*al = SSL_AD_DECODE_ERROR;
+				return 0;
+				}
+			
+			if (s->s3->server_opaque_prf_input != NULL) /* shouldn't really happen */
+				OPENSSL_free(s->s3->server_opaque_prf_input);
+			if (s->s3->server_opaque_prf_input_len == 0)
+				s->s3->server_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
+			else
+				s->s3->server_opaque_prf_input = BUF_memdup(sdata, s->s3->server_opaque_prf_input_len);
+
+			if (s->s3->server_opaque_prf_input == NULL)
+				{
+				*al = TLS1_AD_INTERNAL_ERROR;
+				return 0;
+				}
+			}
+#endif
+		else if (type == TLSEXT_TYPE_status_request &&
+		         s->version != DTLS1_VERSION)
+			{
+			/* MUST be empty and only sent if we've requested
+			 * a status request message.
+			 */ 
+			if ((s->tlsext_status_type == -1) || (size > 0))
+				{
+				*al = TLS1_AD_UNSUPPORTED_EXTENSION;
+				return 0;
+				}
+			/* Set flag to expect CertificateStatus message */
+			s->tlsext_status_expected = 1;
+			}
+#ifndef OPENSSL_NO_NEXTPROTONEG
+		else if (type == TLSEXT_TYPE_next_proto_neg)
+			{
+			unsigned char *selected;
+			unsigned char selected_len;
+
+			/* We must have requested it. */
+			if ((s->ctx->next_proto_select_cb == NULL))
+				{
+				*al = TLS1_AD_UNSUPPORTED_EXTENSION;
+				return 0;
+				}
+			/* The data must be valid */
+			if (!ssl_next_proto_validate(data, size))
+				{
+				*al = TLS1_AD_DECODE_ERROR;
+				return 0;
+				}
+			if (s->ctx->next_proto_select_cb(s, &selected, &selected_len, data, size, s->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK)
+				{
+				*al = TLS1_AD_INTERNAL_ERROR;
+				return 0;
+				}
+			s->next_proto_negotiated = OPENSSL_malloc(selected_len);
+			if (!s->next_proto_negotiated)
+				{
+				*al = TLS1_AD_INTERNAL_ERROR;
+				return 0;
+				}
+			memcpy(s->next_proto_negotiated, selected, selected_len);
+			s->next_proto_negotiated_len = selected_len;
+			}
+#endif
+		else if (type == TLSEXT_TYPE_renegotiate)
+			{
+			if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
+				return 0;
+			renegotiate_seen = 1;
+			}
+		data+=size;		
+		}
+
+	if (data != d+n)
+		{
+		*al = SSL_AD_DECODE_ERROR;
+		return 0;
+		}
+
+	if (!s->hit && tlsext_servername == 1)
+		{
+ 		if (s->tlsext_hostname)
+			{
+			if (s->session->tlsext_hostname == NULL)
+				{
+				s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname);	
+				if (!s->session->tlsext_hostname)
+					{
+					*al = SSL_AD_UNRECOGNIZED_NAME;
+					return 0;
+					}
+				}
+			else 
+				{
+				*al = SSL_AD_DECODE_ERROR;
+				return 0;
+				}
+			}
+		}
+
+	*p = data;
+
+	ri_check:
+
+	/* Determine if we need to see RI. Strictly speaking if we want to
+	 * avoid an attack we should *always* see RI even on initial server
+	 * hello because the client doesn't see any renegotiation during an
+	 * attack. However this would mean we could not connect to any server
+	 * which doesn't support RI so for the immediate future tolerate RI
+	 * absence on initial connect only.
+	 */
+	if (!renegotiate_seen
+		&& !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)
+		&& !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+		{
+		*al = SSL_AD_HANDSHAKE_FAILURE;
+		SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT,
+				SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+		return 0;
+		}
+
+	return 1;
+	}
+
+
+int ssl_prepare_clienthello_tlsext(SSL *s)
+	{
+#ifndef OPENSSL_NO_EC
+	/* If we are client and using an elliptic curve cryptography cipher suite, send the point formats 
+	 * and elliptic curves we support.
+	 */
+	int using_ecc = 0;
+	int i;
+	unsigned char *j;
+	unsigned long alg_k, alg_a;
+	STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
+
+	for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++)
+		{
+		SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
+
+		alg_k = c->algorithm_mkey;
+		alg_a = c->algorithm_auth;
+		if ((alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe) || (alg_a & SSL_aECDSA)))
+			{
+			using_ecc = 1;
+			break;
+			}
+		}
+	using_ecc = using_ecc && (s->version == TLS1_VERSION);
+	if (using_ecc)
+		{
+		if (s->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->tlsext_ecpointformatlist);
+		if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL)
+			{
+			SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
+			return -1;
+			}
+		s->tlsext_ecpointformatlist_length = 3;
+		s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
+		s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
+		s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
+
+		/* we support all named elliptic curves in draft-ietf-tls-ecc-12 */
+		if (s->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->tlsext_ellipticcurvelist);
+		s->tlsext_ellipticcurvelist_length = sizeof(nid_list)/sizeof(nid_list[0]) * 2;
+		if ((s->tlsext_ellipticcurvelist = OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL)
+			{
+			s->tlsext_ellipticcurvelist_length = 0;
+			SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
+			return -1;
+			}
+		for (i = 1, j = s->tlsext_ellipticcurvelist; (unsigned int)i <=
+				sizeof(nid_list)/sizeof(nid_list[0]); i++)
+			s2n(i,j);
+		}
+#endif /* OPENSSL_NO_EC */
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+ 	{
+		int r = 1;
+	
+		if (s->ctx->tlsext_opaque_prf_input_callback != 0)
+			{
+			r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, s->ctx->tlsext_opaque_prf_input_callback_arg);
+			if (!r)
+				return -1;
+			}
+
+		if (s->tlsext_opaque_prf_input != NULL)
+			{
+			if (s->s3->client_opaque_prf_input != NULL) /* shouldn't really happen */
+				OPENSSL_free(s->s3->client_opaque_prf_input);
+
+			if (s->tlsext_opaque_prf_input_len == 0)
+				s->s3->client_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
+			else
+				s->s3->client_opaque_prf_input = BUF_memdup(s->tlsext_opaque_prf_input, s->tlsext_opaque_prf_input_len);
+			if (s->s3->client_opaque_prf_input == NULL)
+				{
+				SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
+				return -1;
+				}
+			s->s3->client_opaque_prf_input_len = s->tlsext_opaque_prf_input_len;
+			}
+
+		if (r == 2)
+			/* at callback's request, insist on receiving an appropriate server opaque PRF input */
+			s->s3->server_opaque_prf_input_len = s->tlsext_opaque_prf_input_len;
+	}
+#endif
+
+	return 1;
+	}
+
+int ssl_prepare_serverhello_tlsext(SSL *s)
+	{
+#ifndef OPENSSL_NO_EC
+	/* If we are server and using an ECC cipher suite, send the point formats we support 
+	 * if the client sent us an ECPointsFormat extension.  Note that the server is not
+	 * supposed to send an EllipticCurves extension.
+	 */
+
+	unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+	unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+	int using_ecc = (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA);
+	using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
+	
+	if (using_ecc)
+		{
+		if (s->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->tlsext_ecpointformatlist);
+		if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL)
+			{
+			SSLerr(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
+			return -1;
+			}
+		s->tlsext_ecpointformatlist_length = 3;
+		s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
+		s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
+		s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
+		}
+#endif /* OPENSSL_NO_EC */
+
+	return 1;
+	}
+
+int ssl_check_clienthello_tlsext(SSL *s)
+	{
+	int ret=SSL_TLSEXT_ERR_NOACK;
+	int al = SSL_AD_UNRECOGNIZED_NAME;
+
+#ifndef OPENSSL_NO_EC
+	/* The handling of the ECPointFormats extension is done elsewhere, namely in 
+	 * ssl3_choose_cipher in s3_lib.c.
+	 */
+	/* The handling of the EllipticCurves extension is done elsewhere, namely in 
+	 * ssl3_choose_cipher in s3_lib.c.
+	 */
+#endif
+
+	if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) 
+		ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg);
+	else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) 		
+		ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg);
+
+	/* If status request then ask callback what to do.
+ 	 * Note: this must be called after servername callbacks in case 
+ 	 * the certificate has changed.
+ 	 */
+	if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb)
+		{
+		int r;
+		r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
+		switch (r)
+			{
+			/* We don't want to send a status request response */
+			case SSL_TLSEXT_ERR_NOACK:
+				s->tlsext_status_expected = 0;
+				break;
+			/* status request response should be sent */
+			case SSL_TLSEXT_ERR_OK:
+				if (s->tlsext_ocsp_resp)
+					s->tlsext_status_expected = 1;
+				else
+					s->tlsext_status_expected = 0;
+				break;
+			/* something bad happened */
+			case SSL_TLSEXT_ERR_ALERT_FATAL:
+				ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+				al = SSL_AD_INTERNAL_ERROR;
+				goto err;
+			}
+		}
+	else
+		s->tlsext_status_expected = 0;
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+ 	{
+		/* This sort of belongs into ssl_prepare_serverhello_tlsext(),
+		 * but we might be sending an alert in response to the client hello,
+		 * so this has to happen here in ssl_check_clienthello_tlsext(). */
+
+		int r = 1;
+	
+		if (s->ctx->tlsext_opaque_prf_input_callback != 0)
+			{
+			r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, s->ctx->tlsext_opaque_prf_input_callback_arg);
+			if (!r)
+				{
+				ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+				al = SSL_AD_INTERNAL_ERROR;
+				goto err;
+				}
+			}
+
+		if (s->s3->server_opaque_prf_input != NULL) /* shouldn't really happen */
+			OPENSSL_free(s->s3->server_opaque_prf_input);
+		s->s3->server_opaque_prf_input = NULL;
+
+		if (s->tlsext_opaque_prf_input != NULL)
+			{
+			if (s->s3->client_opaque_prf_input != NULL &&
+				s->s3->client_opaque_prf_input_len == s->tlsext_opaque_prf_input_len)
+				{
+				/* can only use this extension if we have a server opaque PRF input
+				 * of the same length as the client opaque PRF input! */
+
+				if (s->tlsext_opaque_prf_input_len == 0)
+					s->s3->server_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
+				else
+					s->s3->server_opaque_prf_input = BUF_memdup(s->tlsext_opaque_prf_input, s->tlsext_opaque_prf_input_len);
+				if (s->s3->server_opaque_prf_input == NULL)
+					{
+					ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+					al = SSL_AD_INTERNAL_ERROR;
+					goto err;
+					}
+				s->s3->server_opaque_prf_input_len = s->tlsext_opaque_prf_input_len;
+				}
+			}
+
+		if (r == 2 && s->s3->server_opaque_prf_input == NULL)
+			{
+			/* The callback wants to enforce use of the extension,
+			 * but we can't do that with the client opaque PRF input;
+			 * abort the handshake.
+			 */
+			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+			al = SSL_AD_HANDSHAKE_FAILURE;
+			}
+	}
+
+#endif
+ err:
+	switch (ret)
+		{
+		case SSL_TLSEXT_ERR_ALERT_FATAL:
+			ssl3_send_alert(s,SSL3_AL_FATAL,al); 
+			return -1;
+
+		case SSL_TLSEXT_ERR_ALERT_WARNING:
+			ssl3_send_alert(s,SSL3_AL_WARNING,al);
+			return 1; 
+					
+		case SSL_TLSEXT_ERR_NOACK:
+			s->servername_done=0;
+			default:
+		return 1;
+		}
+	}
+
+int ssl_check_serverhello_tlsext(SSL *s)
+	{
+	int ret=SSL_TLSEXT_ERR_NOACK;
+	int al = SSL_AD_UNRECOGNIZED_NAME;
+
+#ifndef OPENSSL_NO_EC
+	/* If we are client and using an elliptic curve cryptography cipher
+	 * suite, then if server returns an EC point formats lists extension
+	 * it must contain uncompressed.
+	 */
+	unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+	unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+	if ((s->tlsext_ecpointformatlist != NULL) && (s->tlsext_ecpointformatlist_length > 0) && 
+	    (s->session->tlsext_ecpointformatlist != NULL) && (s->session->tlsext_ecpointformatlist_length > 0) && 
+	    ((alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA)))
+		{
+		/* we are using an ECC cipher */
+		size_t i;
+		unsigned char *list;
+		int found_uncompressed = 0;
+		list = s->session->tlsext_ecpointformatlist;
+		for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
+			{
+			if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed)
+				{
+				found_uncompressed = 1;
+				break;
+				}
+			}
+		if (!found_uncompressed)
+			{
+			SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
+			return -1;
+			}
+		}
+	ret = SSL_TLSEXT_ERR_OK;
+#endif /* OPENSSL_NO_EC */
+
+	if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) 
+		ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg);
+	else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) 		
+		ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg);
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	if (s->s3->server_opaque_prf_input_len > 0)
+		{
+		/* This case may indicate that we, as a client, want to insist on using opaque PRF inputs.
+		 * So first verify that we really have a value from the server too. */
+
+		if (s->s3->server_opaque_prf_input == NULL)
+			{
+			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+			al = SSL_AD_HANDSHAKE_FAILURE;
+			}
+		
+		/* Anytime the server *has* sent an opaque PRF input, we need to check
+		 * that we have a client opaque PRF input of the same size. */
+		if (s->s3->client_opaque_prf_input == NULL ||
+		    s->s3->client_opaque_prf_input_len != s->s3->server_opaque_prf_input_len)
+			{
+			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+			al = SSL_AD_ILLEGAL_PARAMETER;
+			}
+		}
+#endif
+
+	/* If we've requested certificate status and we wont get one
+ 	 * tell the callback
+ 	 */
+	if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected)
+			&& s->ctx && s->ctx->tlsext_status_cb)
+		{
+		int r;
+		/* Set resp to NULL, resplen to -1 so callback knows
+ 		 * there is no response.
+ 		 */
+		if (s->tlsext_ocsp_resp)
+			{
+			OPENSSL_free(s->tlsext_ocsp_resp);
+			s->tlsext_ocsp_resp = NULL;
+			}
+		s->tlsext_ocsp_resplen = -1;
+		r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
+		if (r == 0)
+			{
+			al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
+			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+			}
+		if (r < 0)
+			{
+			al = SSL_AD_INTERNAL_ERROR;
+			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+			}
+		}
+
+	switch (ret)
+		{
+		case SSL_TLSEXT_ERR_ALERT_FATAL:
+			ssl3_send_alert(s,SSL3_AL_FATAL,al); 
+			return -1;
+
+		case SSL_TLSEXT_ERR_ALERT_WARNING:
+			ssl3_send_alert(s,SSL3_AL_WARNING,al);
+			return 1; 
+					
+		case SSL_TLSEXT_ERR_NOACK:
+			s->servername_done=0;
+			default:
+		return 1;
+		}
+	}
+
+/* Since the server cache lookup is done early on in the processing of client
+ * hello and other operations depend on the result we need to handle any TLS
+ * session ticket extension at the same time.
+ */
+
+int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
+				const unsigned char *limit, SSL_SESSION **ret)
+	{
+	/* Point after session ID in client hello */
+	const unsigned char *p = session_id + len;
+	unsigned short i;
+
+	/* If tickets disabled behave as if no ticket present
+ 	 * to permit stateful resumption.
+ 	 */
+	if (SSL_get_options(s) & SSL_OP_NO_TICKET)
+		return 1;
+
+	if ((s->version <= SSL3_VERSION) || !limit)
+		return 1;
+	if (p >= limit)
+		return -1;
+	/* Skip past DTLS cookie */
+	if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
+		{
+		i = *(p++);
+		p+= i;
+		if (p >= limit)
+			return -1;
+		}
+	/* Skip past cipher list */
+	n2s(p, i);
+	p+= i;
+	if (p >= limit)
+		return -1;
+	/* Skip past compression algorithm list */
+	i = *(p++);
+	p += i;
+	if (p > limit)
+		return -1;
+	/* Now at start of extensions */
+	if ((p + 2) >= limit)
+		return 1;
+	n2s(p, i);
+	while ((p + 4) <= limit)
+		{
+		unsigned short type, size;
+		n2s(p, type);
+		n2s(p, size);
+		if (p + size > limit)
+			return 1;
+		if (type == TLSEXT_TYPE_session_ticket)
+			{
+			/* If tickets disabled indicate cache miss which will
+ 			 * trigger a full handshake
+ 			 */
+			if (SSL_get_options(s) & SSL_OP_NO_TICKET)
+				return 1;
+			/* If zero length note client will accept a ticket
+ 			 * and indicate cache miss to trigger full handshake
+ 			 */
+			if (size == 0)
+				{
+				s->tlsext_ticket_expected = 1;
+				return 0;	/* Cache miss */
+				}
+			if (s->tls_session_secret_cb)
+				{
+				/* Indicate cache miss here and instead of
+				 * generating the session from ticket now,
+				 * trigger abbreviated handshake based on
+				 * external mechanism to calculate the master
+				 * secret later. */
+				return 0;
+				}
+			return tls_decrypt_ticket(s, p, size, session_id, len,
+									ret);
+			}
+		p += size;
+		}
+	return 1;
+	}
+
+static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
+				const unsigned char *sess_id, int sesslen,
+				SSL_SESSION **psess)
+	{
+	SSL_SESSION *sess;
+	unsigned char *sdec;
+	const unsigned char *p;
+	int slen, mlen, renew_ticket = 0;
+	unsigned char tick_hmac[EVP_MAX_MD_SIZE];
+	HMAC_CTX hctx;
+	EVP_CIPHER_CTX ctx;
+	SSL_CTX *tctx = s->initial_ctx;
+	/* Need at least keyname + iv + some encrypted data */
+	if (eticklen < 48)
+		goto tickerr;
+	/* Initialize session ticket encryption and HMAC contexts */
+	HMAC_CTX_init(&hctx);
+	EVP_CIPHER_CTX_init(&ctx);
+	if (tctx->tlsext_ticket_key_cb)
+		{
+		unsigned char *nctick = (unsigned char *)etick;
+		int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
+							&ctx, &hctx, 0);
+		if (rv < 0)
+			return -1;
+		if (rv == 0)
+			goto tickerr;
+		if (rv == 2)
+			renew_ticket = 1;
+		}
+	else
+		{
+		/* Check key name matches */
+		if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
+			goto tickerr;
+		HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
+					tlsext_tick_md(), NULL);
+		EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
+				tctx->tlsext_tick_aes_key, etick + 16);
+		}
+	/* Attempt to process session ticket, first conduct sanity and
+ 	 * integrity checks on ticket.
+ 	 */
+	mlen = HMAC_size(&hctx);
+	if (mlen < 0)
+		{
+		EVP_CIPHER_CTX_cleanup(&ctx);
+		return -1;
+		}
+	eticklen -= mlen;
+	/* Check HMAC of encrypted ticket */
+	HMAC_Update(&hctx, etick, eticklen);
+	HMAC_Final(&hctx, tick_hmac, NULL);
+	HMAC_CTX_cleanup(&hctx);
+	if (memcmp(tick_hmac, etick + eticklen, mlen))
+		goto tickerr;
+	/* Attempt to decrypt session data */
+	/* Move p after IV to start of encrypted ticket, update length */
+	p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
+	eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
+	sdec = OPENSSL_malloc(eticklen);
+	if (!sdec)
+		{
+		EVP_CIPHER_CTX_cleanup(&ctx);
+		return -1;
+		}
+	EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
+	if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0)
+		goto tickerr;
+	slen += mlen;
+	EVP_CIPHER_CTX_cleanup(&ctx);
+	p = sdec;
+		
+	sess = d2i_SSL_SESSION(NULL, &p, slen);
+	OPENSSL_free(sdec);
+	if (sess)
+		{
+		/* The session ID if non-empty is used by some clients to
+ 		 * detect that the ticket has been accepted. So we copy it to
+ 		 * the session structure. If it is empty set length to zero
+ 		 * as required by standard.
+ 		 */
+		if (sesslen)
+			memcpy(sess->session_id, sess_id, sesslen);
+		sess->session_id_length = sesslen;
+		*psess = sess;
+		s->tlsext_ticket_expected = renew_ticket;
+		return 1;
+		}
+	/* If session decrypt failure indicate a cache miss and set state to
+ 	 * send a new ticket
+ 	 */
+	tickerr:	
+	s->tlsext_ticket_expected = 1;
+	return 0;
+	}
+
+#endif
diff --git a/openssl/ssl/t1_meth.c b/openssl/ssl/t1_meth.c
new file mode 100644
index 0000000..6ce7c0b
--- /dev/null
+++ b/openssl/ssl/t1_meth.c
@@ -0,0 +1,76 @@
+/* ssl/t1_meth.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+
+static const SSL_METHOD *tls1_get_method(int ver);
+static const SSL_METHOD *tls1_get_method(int ver)
+	{
+	if (ver == TLS1_VERSION)
+		return(TLSv1_method());
+	else
+		return(NULL);
+	}
+
+IMPLEMENT_tls1_meth_func(TLSv1_method,
+			ssl3_accept,
+			ssl3_connect,
+			tls1_get_method)
+
diff --git a/openssl/ssl/t1_reneg.c b/openssl/ssl/t1_reneg.c
new file mode 100644
index 0000000..9c2cc3c
--- /dev/null
+++ b/openssl/ssl/t1_reneg.c
@@ -0,0 +1,292 @@
+/* ssl/t1_reneg.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2009 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <stdio.h>
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+
+/* Add the client's renegotiation binding */
+int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
+					int maxlen)
+    {
+    if(p)
+        {
+	if((s->s3->previous_client_finished_len+1) > maxlen)
+            {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATE_EXT_TOO_LONG);
+            return 0;
+            }
+            
+        /* Length byte */
+	*p = s->s3->previous_client_finished_len;
+        p++;
+
+        memcpy(p, s->s3->previous_client_finished,
+	       s->s3->previous_client_finished_len);
+#ifdef OPENSSL_RI_DEBUG
+    fprintf(stderr, "%s RI extension sent by client\n",
+		s->s3->previous_client_finished_len ? "Non-empty" : "Empty");
+#endif
+        }
+    
+    *len=s->s3->previous_client_finished_len + 1;
+
+ 
+    return 1;
+    }
+
+/* Parse the client's renegotiation binding and abort if it's not
+   right */
+int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
+					  int *al)
+    {
+    int ilen;
+
+    /* Parse the length byte */
+    if(len < 1)
+        {
+        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
+        *al=SSL_AD_ILLEGAL_PARAMETER;
+        return 0;
+        }
+    ilen = *d;
+    d++;
+
+    /* Consistency check */
+    if((ilen+1) != len)
+        {
+        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
+        *al=SSL_AD_ILLEGAL_PARAMETER;
+        return 0;
+        }
+
+    /* Check that the extension matches */
+    if(ilen != s->s3->previous_client_finished_len)
+        {
+        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
+        *al=SSL_AD_HANDSHAKE_FAILURE;
+        return 0;
+        }
+    
+    if(memcmp(d, s->s3->previous_client_finished,
+	      s->s3->previous_client_finished_len))
+        {
+        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
+        *al=SSL_AD_HANDSHAKE_FAILURE;
+        return 0;
+        }
+#ifdef OPENSSL_RI_DEBUG
+    fprintf(stderr, "%s RI extension received by server\n",
+				ilen ? "Non-empty" : "Empty");
+#endif
+
+    s->s3->send_connection_binding=1;
+
+    return 1;
+    }
+
+/* Add the server's renegotiation binding */
+int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
+					int maxlen)
+    {
+    if(p)
+        {
+        if((s->s3->previous_client_finished_len +
+            s->s3->previous_server_finished_len + 1) > maxlen)
+            {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATE_EXT_TOO_LONG);
+            return 0;
+            }
+        
+        /* Length byte */
+        *p = s->s3->previous_client_finished_len + s->s3->previous_server_finished_len;
+        p++;
+
+        memcpy(p, s->s3->previous_client_finished,
+	       s->s3->previous_client_finished_len);
+        p += s->s3->previous_client_finished_len;
+
+        memcpy(p, s->s3->previous_server_finished,
+	       s->s3->previous_server_finished_len);
+#ifdef OPENSSL_RI_DEBUG
+    fprintf(stderr, "%s RI extension sent by server\n",
+    		s->s3->previous_client_finished_len ? "Non-empty" : "Empty");
+#endif
+        }
+    
+    *len=s->s3->previous_client_finished_len
+	+ s->s3->previous_server_finished_len + 1;
+    
+    return 1;
+    }
+
+/* Parse the server's renegotiation binding and abort if it's not
+   right */
+int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len,
+					  int *al)
+    {
+    int expected_len=s->s3->previous_client_finished_len
+	+ s->s3->previous_server_finished_len;
+    int ilen;
+
+    /* Check for logic errors */
+    OPENSSL_assert(!expected_len || s->s3->previous_client_finished_len);
+    OPENSSL_assert(!expected_len || s->s3->previous_server_finished_len);
+    
+    /* Parse the length byte */
+    if(len < 1)
+        {
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
+        *al=SSL_AD_ILLEGAL_PARAMETER;
+        return 0;
+        }
+    ilen = *d;
+    d++;
+
+    /* Consistency check */
+    if(ilen+1 != len)
+        {
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
+        *al=SSL_AD_ILLEGAL_PARAMETER;
+        return 0;
+        }
+    
+    /* Check that the extension matches */
+    if(ilen != expected_len)
+        {
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
+        *al=SSL_AD_HANDSHAKE_FAILURE;
+        return 0;
+        }
+
+    if(memcmp(d, s->s3->previous_client_finished,
+	      s->s3->previous_client_finished_len))
+        {
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
+        *al=SSL_AD_HANDSHAKE_FAILURE;
+        return 0;
+        }
+    d += s->s3->previous_client_finished_len;
+
+    if(memcmp(d, s->s3->previous_server_finished,
+	      s->s3->previous_server_finished_len))
+        {
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
+        *al=SSL_AD_ILLEGAL_PARAMETER;
+        return 0;
+        }
+#ifdef OPENSSL_RI_DEBUG
+    fprintf(stderr, "%s RI extension received by client\n",
+				ilen ? "Non-empty" : "Empty");
+#endif
+    s->s3->send_connection_binding=1;
+
+    return 1;
+    }
diff --git a/openssl/ssl/t1_srvr.c b/openssl/ssl/t1_srvr.c
new file mode 100644
index 0000000..42525e9
--- /dev/null
+++ b/openssl/ssl/t1_srvr.c
@@ -0,0 +1,80 @@
+/* ssl/t1_srvr.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "ssl_locl.h"
+#include <openssl/buffer.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+static const SSL_METHOD *tls1_get_server_method(int ver);
+static const SSL_METHOD *tls1_get_server_method(int ver)
+	{
+	if (ver == TLS1_VERSION)
+		return(TLSv1_server_method());
+	else
+		return(NULL);
+	}
+
+IMPLEMENT_tls1_meth_func(TLSv1_server_method,
+			ssl3_accept,
+			ssl_undefined_function,
+			tls1_get_server_method)
+
diff --git a/openssl/ssl/tls1.h b/openssl/ssl/tls1.h
new file mode 100644
index 0000000..71f9722
--- /dev/null
+++ b/openssl/ssl/tls1.h
@@ -0,0 +1,540 @@
+/* ssl/tls1.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * ECC cipher suite support in OpenSSL originally written by
+ * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#ifndef HEADER_TLS1_H 
+#define HEADER_TLS1_H 
+
+#include <openssl/buffer.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES	0
+
+#define TLS1_VERSION			0x0301
+#define TLS1_VERSION_MAJOR		0x03
+#define TLS1_VERSION_MINOR		0x01
+
+#define TLS1_AD_DECRYPTION_FAILED	21
+#define TLS1_AD_RECORD_OVERFLOW		22
+#define TLS1_AD_UNKNOWN_CA		48	/* fatal */
+#define TLS1_AD_ACCESS_DENIED		49	/* fatal */
+#define TLS1_AD_DECODE_ERROR		50	/* fatal */
+#define TLS1_AD_DECRYPT_ERROR		51
+#define TLS1_AD_EXPORT_RESTRICTION	60	/* fatal */
+#define TLS1_AD_PROTOCOL_VERSION	70	/* fatal */
+#define TLS1_AD_INSUFFICIENT_SECURITY	71	/* fatal */
+#define TLS1_AD_INTERNAL_ERROR		80	/* fatal */
+#define TLS1_AD_USER_CANCELLED		90
+#define TLS1_AD_NO_RENEGOTIATION	100
+/* codes 110-114 are from RFC3546 */
+#define TLS1_AD_UNSUPPORTED_EXTENSION	110
+#define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111
+#define TLS1_AD_UNRECOGNIZED_NAME 	112
+#define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113
+#define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
+#define TLS1_AD_UNKNOWN_PSK_IDENTITY	115	/* fatal */
+
+/* ExtensionType values from RFC3546 / RFC4366 */
+#define TLSEXT_TYPE_server_name			0
+#define TLSEXT_TYPE_max_fragment_length		1
+#define TLSEXT_TYPE_client_certificate_url	2
+#define TLSEXT_TYPE_trusted_ca_keys		3
+#define TLSEXT_TYPE_truncated_hmac		4
+#define TLSEXT_TYPE_status_request		5
+/* ExtensionType values from RFC4492 */
+#define TLSEXT_TYPE_elliptic_curves		10
+#define TLSEXT_TYPE_ec_point_formats		11
+#define TLSEXT_TYPE_session_ticket		35
+/* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */
+#if 0 /* will have to be provided externally for now ,
+       * i.e. build with -DTLSEXT_TYPE_opaque_prf_input=38183
+       * using whatever extension number you'd like to try */
+# define TLSEXT_TYPE_opaque_prf_input		?? */
+#endif
+
+/* Temporary extension type */
+#define TLSEXT_TYPE_renegotiate                 0xff01
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+/* This is not an IANA defined extension number */
+#define TLSEXT_TYPE_next_proto_neg		13172
+#endif
+
+/* NameType value from RFC 3546 */
+#define TLSEXT_NAMETYPE_host_name 0
+/* status request value from RFC 3546 */
+#define TLSEXT_STATUSTYPE_ocsp 1
+
+/* ECPointFormat values from draft-ietf-tls-ecc-12 */
+#define TLSEXT_ECPOINTFORMAT_first			0
+#define TLSEXT_ECPOINTFORMAT_uncompressed		0
+#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime	1
+#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2	2
+#define TLSEXT_ECPOINTFORMAT_last			2
+
+#ifndef OPENSSL_NO_TLSEXT
+
+#define TLSEXT_MAXLEN_host_name 255
+
+const char *SSL_get_servername(const SSL *s, const int type) ;
+int SSL_get_servername_type(const SSL *s) ;
+int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
+	const char *label, size_t llen, const unsigned char *p, size_t plen,
+	int use_context);
+
+#define SSL_set_tlsext_host_name(s,name) \
+SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name)
+
+#define SSL_set_tlsext_debug_callback(ssl, cb) \
+SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,(void (*)(void))cb)
+
+#define SSL_set_tlsext_debug_arg(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0, (void *)arg)
+
+#define SSL_set_tlsext_status_type(ssl, type) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type, NULL)
+
+#define SSL_get_tlsext_status_exts(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg)
+
+#define SSL_set_tlsext_status_exts(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg)
+
+#define SSL_get_tlsext_status_ids(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg)
+
+#define SSL_set_tlsext_status_ids(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg)
+
+#define SSL_get_tlsext_status_ocsp_resp(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,0, (void *)arg)
+
+#define SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,arglen, (void *)arg)
+
+#define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \
+SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb)
+
+#define SSL_TLSEXT_ERR_OK 0
+#define SSL_TLSEXT_ERR_ALERT_WARNING 1
+#define SSL_TLSEXT_ERR_ALERT_FATAL 2
+#define SSL_TLSEXT_ERR_NOACK 3
+
+#define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \
+SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg)
+
+#define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \
+	SSL_CTX_ctrl((ctx),SSL_CTRL_GET_TLSEXT_TICKET_KEYS,(keylen),(keys))
+#define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \
+	SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLSEXT_TICKET_KEYS,(keylen),(keys))
+
+#define SSL_CTX_set_tlsext_status_cb(ssl, cb) \
+SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb)
+
+#define SSL_CTX_set_tlsext_status_arg(ssl, arg) \
+SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg)
+
+#define SSL_set_tlsext_opaque_prf_input(s, src, len) \
+SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT, len, src)
+#define SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) \
+SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB, (void (*)(void))cb)
+#define SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) \
+SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg)
+
+#define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \
+SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
+
+#endif
+
+/* PSK ciphersuites from 4279 */
+#define TLS1_CK_PSK_WITH_RC4_128_SHA                    0x0300008A
+#define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA               0x0300008B
+#define TLS1_CK_PSK_WITH_AES_128_CBC_SHA                0x0300008C
+#define TLS1_CK_PSK_WITH_AES_256_CBC_SHA                0x0300008D
+
+/* Additional TLS ciphersuites from expired Internet Draft
+ * draft-ietf-tls-56-bit-ciphersuites-01.txt
+ * (available if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see
+ * s3_lib.c).  We actually treat them like SSL 3.0 ciphers, which we probably
+ * shouldn't.  Note that the first two are actually not in the IDs. */
+#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5		0x03000060 /* not in ID */
+#define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5	0x03000061 /* not in ID */
+#define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA		0x03000062
+#define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA	0x03000063
+#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA		0x03000064
+#define TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA	0x03000065
+#define TLS1_CK_DHE_DSS_WITH_RC4_128_SHA		0x03000066
+
+/* AES ciphersuites from RFC3268 */
+
+#define TLS1_CK_RSA_WITH_AES_128_SHA			0x0300002F
+#define TLS1_CK_DH_DSS_WITH_AES_128_SHA			0x03000030
+#define TLS1_CK_DH_RSA_WITH_AES_128_SHA			0x03000031
+#define TLS1_CK_DHE_DSS_WITH_AES_128_SHA		0x03000032
+#define TLS1_CK_DHE_RSA_WITH_AES_128_SHA		0x03000033
+#define TLS1_CK_ADH_WITH_AES_128_SHA			0x03000034
+
+#define TLS1_CK_RSA_WITH_AES_256_SHA			0x03000035
+#define TLS1_CK_DH_DSS_WITH_AES_256_SHA			0x03000036
+#define TLS1_CK_DH_RSA_WITH_AES_256_SHA			0x03000037
+#define TLS1_CK_DHE_DSS_WITH_AES_256_SHA		0x03000038
+#define TLS1_CK_DHE_RSA_WITH_AES_256_SHA		0x03000039
+#define TLS1_CK_ADH_WITH_AES_256_SHA			0x0300003A
+
+/* Camellia ciphersuites from RFC4132 */
+#define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA		0x03000041
+#define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA	0x03000042
+#define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA	0x03000043
+#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA	0x03000044
+#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA	0x03000045
+#define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA		0x03000046
+
+#define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA		0x03000084
+#define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA	0x03000085
+#define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA	0x03000086
+#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA	0x03000087
+#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA	0x03000088
+#define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA		0x03000089
+
+/* SEED ciphersuites from RFC4162 */
+#define TLS1_CK_RSA_WITH_SEED_SHA                       0x03000096
+#define TLS1_CK_DH_DSS_WITH_SEED_SHA                    0x03000097
+#define TLS1_CK_DH_RSA_WITH_SEED_SHA                    0x03000098
+#define TLS1_CK_DHE_DSS_WITH_SEED_SHA                   0x03000099
+#define TLS1_CK_DHE_RSA_WITH_SEED_SHA                   0x0300009A
+#define TLS1_CK_ADH_WITH_SEED_SHA                	0x0300009B
+
+/* ECC ciphersuites from draft-ietf-tls-ecc-12.txt with changes soon to be in draft 13 */
+#define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA                0x0300C001
+#define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA             0x0300C002
+#define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA        0x0300C003
+#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA         0x0300C004
+#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA         0x0300C005
+
+#define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA               0x0300C006
+#define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA            0x0300C007
+#define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA       0x0300C008
+#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA        0x0300C009
+#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA        0x0300C00A
+
+#define TLS1_CK_ECDH_RSA_WITH_NULL_SHA                  0x0300C00B
+#define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA               0x0300C00C
+#define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA          0x0300C00D
+#define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA           0x0300C00E
+#define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA           0x0300C00F
+
+#define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA                 0x0300C010
+#define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA              0x0300C011
+#define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA         0x0300C012
+#define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA          0x0300C013
+#define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA          0x0300C014
+
+#define TLS1_CK_ECDH_anon_WITH_NULL_SHA                 0x0300C015
+#define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA              0x0300C016
+#define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA         0x0300C017
+#define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA          0x0300C018
+#define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA          0x0300C019
+
+/* XXX
+ * Inconsistency alert:
+ * The OpenSSL names of ciphers with ephemeral DH here include the string
+ * "DHE", while elsewhere it has always been "EDH".
+ * (The alias for the list of all such ciphers also is "EDH".)
+ * The specifications speak of "EDH"; maybe we should allow both forms
+ * for everything. */
+#define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5		"EXP1024-RC4-MD5"
+#define TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5	"EXP1024-RC2-CBC-MD5"
+#define TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA	"EXP1024-DES-CBC-SHA"
+#define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA	"EXP1024-DHE-DSS-DES-CBC-SHA"
+#define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA		"EXP1024-RC4-SHA"
+#define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA	"EXP1024-DHE-DSS-RC4-SHA"
+#define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA		"DHE-DSS-RC4-SHA"
+
+/* AES ciphersuites from RFC3268 */
+#define TLS1_TXT_RSA_WITH_AES_128_SHA			"AES128-SHA"
+#define TLS1_TXT_DH_DSS_WITH_AES_128_SHA		"DH-DSS-AES128-SHA"
+#define TLS1_TXT_DH_RSA_WITH_AES_128_SHA		"DH-RSA-AES128-SHA"
+#define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA		"DHE-DSS-AES128-SHA"
+#define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA		"DHE-RSA-AES128-SHA"
+#define TLS1_TXT_ADH_WITH_AES_128_SHA			"ADH-AES128-SHA"
+
+#define TLS1_TXT_RSA_WITH_AES_256_SHA			"AES256-SHA"
+#define TLS1_TXT_DH_DSS_WITH_AES_256_SHA		"DH-DSS-AES256-SHA"
+#define TLS1_TXT_DH_RSA_WITH_AES_256_SHA		"DH-RSA-AES256-SHA"
+#define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA		"DHE-DSS-AES256-SHA"
+#define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA		"DHE-RSA-AES256-SHA"
+#define TLS1_TXT_ADH_WITH_AES_256_SHA			"ADH-AES256-SHA"
+
+/* ECC ciphersuites from draft-ietf-tls-ecc-01.txt (Mar 15, 2001) */
+#define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA               "ECDH-ECDSA-NULL-SHA"
+#define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA            "ECDH-ECDSA-RC4-SHA"
+#define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA       "ECDH-ECDSA-DES-CBC3-SHA"
+#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA        "ECDH-ECDSA-AES128-SHA"
+#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA        "ECDH-ECDSA-AES256-SHA"
+
+#define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA              "ECDHE-ECDSA-NULL-SHA"
+#define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA           "ECDHE-ECDSA-RC4-SHA"
+#define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA      "ECDHE-ECDSA-DES-CBC3-SHA"
+#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA       "ECDHE-ECDSA-AES128-SHA"
+#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA       "ECDHE-ECDSA-AES256-SHA"
+
+#define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA                 "ECDH-RSA-NULL-SHA"
+#define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA              "ECDH-RSA-RC4-SHA"
+#define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA         "ECDH-RSA-DES-CBC3-SHA"
+#define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA          "ECDH-RSA-AES128-SHA"
+#define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA          "ECDH-RSA-AES256-SHA"
+
+#define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA                "ECDHE-RSA-NULL-SHA"
+#define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA             "ECDHE-RSA-RC4-SHA"
+#define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA        "ECDHE-RSA-DES-CBC3-SHA"
+#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA         "ECDHE-RSA-AES128-SHA"
+#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA         "ECDHE-RSA-AES256-SHA"
+
+#define TLS1_TXT_ECDH_anon_WITH_NULL_SHA                "AECDH-NULL-SHA"
+#define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA             "AECDH-RC4-SHA"
+#define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA        "AECDH-DES-CBC3-SHA"
+#define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA         "AECDH-AES128-SHA"
+#define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA         "AECDH-AES256-SHA"
+
+/* PSK ciphersuites from RFC 4279 */
+#define TLS1_TXT_PSK_WITH_RC4_128_SHA			"PSK-RC4-SHA"
+#define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA		"PSK-3DES-EDE-CBC-SHA"
+#define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA		"PSK-AES128-CBC-SHA"
+#define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA		"PSK-AES256-CBC-SHA"
+
+/* Camellia ciphersuites from RFC4132 */
+#define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA		"CAMELLIA128-SHA"
+#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA	"DH-DSS-CAMELLIA128-SHA"
+#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA	"DH-RSA-CAMELLIA128-SHA"
+#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA	"DHE-DSS-CAMELLIA128-SHA"
+#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA	"DHE-RSA-CAMELLIA128-SHA"
+#define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA		"ADH-CAMELLIA128-SHA"
+
+#define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA		"CAMELLIA256-SHA"
+#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA	"DH-DSS-CAMELLIA256-SHA"
+#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA	"DH-RSA-CAMELLIA256-SHA"
+#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA	"DHE-DSS-CAMELLIA256-SHA"
+#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA	"DHE-RSA-CAMELLIA256-SHA"
+#define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA		"ADH-CAMELLIA256-SHA"
+
+/* SEED ciphersuites from RFC4162 */
+#define TLS1_TXT_RSA_WITH_SEED_SHA                      "SEED-SHA"
+#define TLS1_TXT_DH_DSS_WITH_SEED_SHA                   "DH-DSS-SEED-SHA"
+#define TLS1_TXT_DH_RSA_WITH_SEED_SHA                   "DH-RSA-SEED-SHA"
+#define TLS1_TXT_DHE_DSS_WITH_SEED_SHA                  "DHE-DSS-SEED-SHA"
+#define TLS1_TXT_DHE_RSA_WITH_SEED_SHA                  "DHE-RSA-SEED-SHA"
+#define TLS1_TXT_ADH_WITH_SEED_SHA                      "ADH-SEED-SHA"
+
+
+#define TLS_CT_RSA_SIGN			1
+#define TLS_CT_DSS_SIGN			2
+#define TLS_CT_RSA_FIXED_DH		3
+#define TLS_CT_DSS_FIXED_DH		4
+#define TLS_CT_ECDSA_SIGN		64
+#define TLS_CT_RSA_FIXED_ECDH		65
+#define TLS_CT_ECDSA_FIXED_ECDH 	66
+#define TLS_CT_GOST94_SIGN		21
+#define TLS_CT_GOST01_SIGN		22
+/* when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see
+ * comment there) */
+#define TLS_CT_NUMBER			9
+
+#define TLS1_FINISH_MAC_LENGTH		12
+
+#define TLS_MD_MAX_CONST_SIZE			20
+#define TLS_MD_CLIENT_FINISH_CONST		"client finished"
+#define TLS_MD_CLIENT_FINISH_CONST_SIZE		15
+#define TLS_MD_SERVER_FINISH_CONST		"server finished"
+#define TLS_MD_SERVER_FINISH_CONST_SIZE		15
+#define TLS_MD_SERVER_WRITE_KEY_CONST		"server write key"
+#define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE	16
+#define TLS_MD_KEY_EXPANSION_CONST		"key expansion"
+#define TLS_MD_KEY_EXPANSION_CONST_SIZE		13
+#define TLS_MD_CLIENT_WRITE_KEY_CONST		"client write key"
+#define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE	16
+#define TLS_MD_SERVER_WRITE_KEY_CONST		"server write key"
+#define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE	16
+#define TLS_MD_IV_BLOCK_CONST			"IV block"
+#define TLS_MD_IV_BLOCK_CONST_SIZE		8
+#define TLS_MD_MASTER_SECRET_CONST		"master secret"
+#define TLS_MD_MASTER_SECRET_CONST_SIZE		13
+
+#ifdef CHARSET_EBCDIC
+#undef TLS_MD_CLIENT_FINISH_CONST
+#define TLS_MD_CLIENT_FINISH_CONST    "\x63\x6c\x69\x65\x6e\x74\x20\x66\x69\x6e\x69\x73\x68\x65\x64"  /*client finished*/
+#undef TLS_MD_SERVER_FINISH_CONST
+#define TLS_MD_SERVER_FINISH_CONST    "\x73\x65\x72\x76\x65\x72\x20\x66\x69\x6e\x69\x73\x68\x65\x64"  /*server finished*/
+#undef TLS_MD_SERVER_WRITE_KEY_CONST
+#define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"  /*server write key*/
+#undef TLS_MD_KEY_EXPANSION_CONST
+#define TLS_MD_KEY_EXPANSION_CONST    "\x6b\x65\x79\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e"  /*key expansion*/
+#undef TLS_MD_CLIENT_WRITE_KEY_CONST
+#define TLS_MD_CLIENT_WRITE_KEY_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"  /*client write key*/
+#undef TLS_MD_SERVER_WRITE_KEY_CONST
+#define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"  /*server write key*/
+#undef TLS_MD_IV_BLOCK_CONST
+#define TLS_MD_IV_BLOCK_CONST         "\x49\x56\x20\x62\x6c\x6f\x63\x6b"  /*IV block*/
+#undef TLS_MD_MASTER_SECRET_CONST
+#define TLS_MD_MASTER_SECRET_CONST    "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"  /*master secret*/
+#endif
+
+/* TLS Session Ticket extension struct */
+struct tls_session_ticket_ext_st
+	{
+	unsigned short length;
+	void *data;
+	};
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/test/CAss.cnf b/openssl/test/CAss.cnf
new file mode 100644
index 0000000..20f8f05
--- /dev/null
+++ b/openssl/test/CAss.cnf
@@ -0,0 +1,76 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+RANDFILE		= ./.rnd
+
+####################################################################
+[ req ]
+default_bits		= 512
+default_keyfile 	= keySS.pem
+distinguished_name	= req_distinguished_name
+encrypt_rsa_key		= no
+default_md		= sha1
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= AU
+countryName_value		= AU
+
+organizationName		= Organization Name (eg, company)
+organizationName_value		= Dodgy Brothers
+
+commonName			= Common Name (eg, YOUR name)
+commonName_value		= Dodgy CA
+
+####################################################################
+[ ca ]
+default_ca	= CA_default		# The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir		= ./demoCA		# Where everything is kept
+certs		= $dir/certs		# Where the issued certs are kept
+crl_dir		= $dir/crl		# Where the issued crl are kept
+database	= $dir/index.txt	# database index file.
+#unique_subject	= no			# Set to 'no' to allow creation of
+					# several ctificates with same subject.
+new_certs_dir	= $dir/newcerts		# default place for new certs.
+
+certificate	= $dir/cacert.pem 	# The CA certificate
+serial		= $dir/serial 		# The current serial number
+crl		= $dir/crl.pem 		# The current CRL
+private_key	= $dir/private/cakey.pem# The private key
+RANDFILE	= $dir/private/.rand	# private random number file
+
+x509_extensions	= v3_ca			# The extentions to add to the cert
+
+name_opt 	= ca_default		# Subject Name options
+cert_opt 	= ca_default		# Certificate field options
+
+default_days	= 365			# how long to certify for
+default_crl_days= 30			# how long before next CRL
+default_md	= md5			# which md to use.
+preserve	= no			# keep passed DN ordering
+
+policy		= policy_anything
+
+[ policy_anything ]
+countryName		= optional
+stateOrProvinceName	= optional
+localityName		= optional
+organizationName	= optional
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+
+
+[ v3_ca ]
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid:always,issuer:always
+basicConstraints = CA:true,pathlen:1
+keyUsage = cRLSign, keyCertSign
+issuerAltName=issuer:copy
diff --git a/openssl/test/CAssdh.cnf b/openssl/test/CAssdh.cnf
new file mode 100644
index 0000000..4e0a908
--- /dev/null
+++ b/openssl/test/CAssdh.cnf
@@ -0,0 +1,24 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+# hacked by iang to do DH certs - CA
+
+RANDFILE              = ./.rnd
+
+####################################################################
+[ req ]
+distinguished_name    = req_distinguished_name
+encrypt_rsa_key               = no
+
+[ req_distinguished_name ]
+countryName                   = Country Name (2 letter code)
+countryName_default           = CU
+countryName_value             = CU
+
+organizationName              = Organization Name (eg, company)
+organizationName_value                = La Junta de la Revolucion
+
+commonName                    = Common Name (eg, YOUR name)
+commonName_value              = Junta
+
diff --git a/openssl/test/CAssdsa.cnf b/openssl/test/CAssdsa.cnf
new file mode 100644
index 0000000..a6b4d18
--- /dev/null
+++ b/openssl/test/CAssdsa.cnf
@@ -0,0 +1,23 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+# hacked by iang to do DSA certs - CA
+
+RANDFILE              = ./.rnd
+
+####################################################################
+[ req ]
+distinguished_name    = req_distinguished_name
+encrypt_rsa_key               = no
+
+[ req_distinguished_name ]
+countryName                   = Country Name (2 letter code)
+countryName_default           = ES
+countryName_value             = ES
+
+organizationName              = Organization Name (eg, company)
+organizationName_value                = Hermanos Locos
+
+commonName                    = Common Name (eg, YOUR name)
+commonName_value              = Hermanos Locos CA
diff --git a/openssl/test/CAssrsa.cnf b/openssl/test/CAssrsa.cnf
new file mode 100644
index 0000000..eb24a6d
--- /dev/null
+++ b/openssl/test/CAssrsa.cnf
@@ -0,0 +1,24 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+# create RSA certs - CA
+
+RANDFILE              = ./.rnd
+
+####################################################################
+[ req ]
+distinguished_name    = req_distinguished_name
+encrypt_key           = no
+
+[ req_distinguished_name ]
+countryName                   = Country Name (2 letter code)
+countryName_default           = ES
+countryName_value             = ES
+
+organizationName              = Organization Name (eg, company)
+organizationName_value                = Hermanos Locos
+
+commonName                    = Common Name (eg, YOUR name)
+commonName_value              = Hermanos Locos CA
+
diff --git a/openssl/test/CAtsa.cnf b/openssl/test/CAtsa.cnf
new file mode 100644
index 0000000..f5a275b
--- /dev/null
+++ b/openssl/test/CAtsa.cnf
@@ -0,0 +1,163 @@
+
+#
+# This config is used by the Time Stamp Authority tests.
+#
+
+RANDFILE		= ./.rnd
+
+# Extra OBJECT IDENTIFIER info:
+oid_section		= new_oids
+
+TSDNSECT		= ts_cert_dn
+INDEX			= 1
+
+[ new_oids ]
+
+# Policies used by the TSA tests.
+tsa_policy1 = 1.2.3.4.1
+tsa_policy2 = 1.2.3.4.5.6
+tsa_policy3 = 1.2.3.4.5.7
+
+#----------------------------------------------------------------------
+[ ca ]
+default_ca	= CA_default		# The default ca section
+
+[ CA_default ]
+
+dir		= ./demoCA
+certs		= $dir/certs		# Where the issued certs are kept
+database	= $dir/index.txt	# database index file.
+new_certs_dir	= $dir/newcerts		# default place for new certs.
+
+certificate	= $dir/cacert.pem 	# The CA certificate
+serial		= $dir/serial 		# The current serial number
+private_key	= $dir/private/cakey.pem# The private key
+RANDFILE	= $dir/private/.rand	# private random number file
+
+default_days	= 365			# how long to certify for
+default_md	= sha1			# which md to use.
+preserve	= no			# keep passed DN ordering
+
+policy		= policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName		= supplied
+stateOrProvinceName	= supplied
+organizationName	= supplied
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+#----------------------------------------------------------------------
+[ req ]
+default_bits		= 1024
+default_md		= sha1
+distinguished_name	= $ENV::TSDNSECT
+encrypt_rsa_key		= no
+prompt 			= no
+# attributes		= req_attributes
+x509_extensions	= v3_ca	# The extentions to add to the self signed cert
+
+string_mask = nombstr
+
+[ ts_ca_dn ]
+countryName			= HU
+stateOrProvinceName		= Budapest
+localityName			= Budapest
+organizationName		= Gov-CA Ltd.
+commonName			= ca1
+
+[ ts_cert_dn ]
+countryName			= HU
+stateOrProvinceName		= Budapest
+localityName			= Buda
+organizationName		= Hun-TSA Ltd.
+commonName			= tsa$ENV::INDEX
+
+[ tsa_cert ]
+
+# TSA server cert is not a CA cert.
+basicConstraints=CA:FALSE
+
+# The following key usage flags are needed for TSA server certificates.
+keyUsage = nonRepudiation, digitalSignature
+extendedKeyUsage = critical,timeStamping
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+
+[ non_tsa_cert ]
+
+# This is not a CA cert and not a TSA cert, either (timeStamping usage missing)
+basicConstraints=CA:FALSE
+
+# The following key usage flags are needed for TSA server certificates.
+keyUsage = nonRepudiation, digitalSignature
+# timeStamping is not supported by this certificate
+# extendedKeyUsage = critical,timeStamping
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature
+
+[ v3_ca ]
+
+# Extensions for a typical CA
+
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid:always,issuer:always
+basicConstraints = critical,CA:true
+keyUsage = cRLSign, keyCertSign
+
+#----------------------------------------------------------------------
+[ tsa ]
+
+default_tsa = tsa_config1	# the default TSA section
+
+[ tsa_config1 ]
+
+# These are used by the TSA reply generation only.
+dir		= .			# TSA root directory
+serial		= $dir/tsa_serial	# The current serial number (mandatory)
+signer_cert	= $dir/tsa_cert1.pem 	# The TSA signing certificate
+					# (optional)
+certs		= $dir/tsaca.pem	# Certificate chain to include in reply
+					# (optional)
+signer_key	= $dir/tsa_key1.pem	# The TSA private key (optional)
+
+default_policy	= tsa_policy1		# Policy if request did not specify it
+					# (optional)
+other_policies	= tsa_policy2, tsa_policy3	# acceptable policies (optional)
+digests		= md5, sha1		# Acceptable message digests (mandatory)
+accuracy	= secs:1, millisecs:500, microsecs:100	# (optional)
+ordering		= yes	# Is ordering defined for timestamps?
+				# (optional, default: no)
+tsa_name		= yes	# Must the TSA name be included in the reply?
+				# (optional, default: no)
+ess_cert_id_chain	= yes	# Must the ESS cert id chain be included?
+				# (optional, default: no)
+
+[ tsa_config2 ]
+
+# This configuration uses a certificate which doesn't have timeStamping usage.
+# These are used by the TSA reply generation only.
+dir		= .			# TSA root directory
+serial		= $dir/tsa_serial	# The current serial number (mandatory)
+signer_cert	= $dir/tsa_cert2.pem 	# The TSA signing certificate
+					# (optional)
+certs		= $dir/demoCA/cacert.pem# Certificate chain to include in reply
+					# (optional)
+signer_key	= $dir/tsa_key2.pem	# The TSA private key (optional)
+
+default_policy	= tsa_policy1		# Policy if request did not specify it
+					# (optional)
+other_policies	= tsa_policy2, tsa_policy3	# acceptable policies (optional)
+digests		= md5, sha1		# Acceptable message digests (mandatory)
diff --git a/openssl/test/Makefile b/openssl/test/Makefile
new file mode 100644
index 0000000..3912f82
--- /dev/null
+++ b/openssl/test/Makefile
@@ -0,0 +1,698 @@
+#
+# test/Makefile
+#
+
+DIR=		test
+TOP=		..
+CC=		cc
+INCLUDES=	-I$(TOP) -I../include $(KRB5_INCLUDES)
+CFLAG=		-g
+MAKEDEPEND=	$(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
+PERL=		perl
+# KRB5 stuff
+KRB5_INCLUDES=
+LIBKRB5=
+
+PEX_LIBS=
+EX_LIBS= #-lnsl -lsocket
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile maketests.com \
+	tests.com testenc.com tx509.com trsa.com tcrl.com tsid.com treq.com \
+	tpkcs7.com tpkcs7d.com tverify.com testgen.com testss.com testssl.com \
+	testca.com VMSca-response.1 VMSca-response.2
+
+DLIBCRYPTO= ../libcrypto.a
+DLIBSSL= ../libssl.a
+LIBCRYPTO= -L.. -lcrypto
+LIBSSL= -L.. -lssl
+
+BNTEST=		bntest
+ECTEST=		ectest
+ECDSATEST=	ecdsatest
+ECDHTEST=	ecdhtest
+EXPTEST=	exptest
+IDEATEST=	ideatest
+SHATEST=	shatest
+SHA1TEST=	sha1test
+SHA256TEST=	sha256t
+SHA512TEST=	sha512t
+MDC2TEST=	mdc2test
+RMDTEST=	rmdtest
+MD2TEST=	md2test
+MD4TEST=	md4test
+MD5TEST=	md5test
+HMACTEST=	hmactest
+WPTEST=		wp_test
+RC2TEST=	rc2test
+RC4TEST=	rc4test
+RC5TEST=	rc5test
+BFTEST=		bftest
+CASTTEST=	casttest
+DESTEST=	destest
+RANDTEST=	randtest
+DHTEST=		dhtest
+DSATEST=	dsatest
+METHTEST=	methtest
+SSLTEST=	ssltest
+RSATEST=	rsa_test
+ENGINETEST=	enginetest
+EVPTEST=	evp_test
+IGETEST=	igetest
+JPAKETEST=	jpaketest
+ASN1TEST=	asn1test
+
+TESTS=		alltests
+
+EXE=	$(BNTEST)$(EXE_EXT) $(ECTEST)$(EXE_EXT)  $(ECDSATEST)$(EXE_EXT) $(ECDHTEST)$(EXE_EXT) $(IDEATEST)$(EXE_EXT) \
+	$(MD2TEST)$(EXE_EXT)  $(MD4TEST)$(EXE_EXT) $(MD5TEST)$(EXE_EXT) $(HMACTEST)$(EXE_EXT) $(WPTEST)$(EXE_EXT) \
+	$(RC2TEST)$(EXE_EXT) $(RC4TEST)$(EXE_EXT) $(RC5TEST)$(EXE_EXT) \
+	$(DESTEST)$(EXE_EXT) $(SHATEST)$(EXE_EXT) $(SHA1TEST)$(EXE_EXT) $(SHA256TEST)$(EXE_EXT) $(SHA512TEST)$(EXE_EXT) \
+	$(MDC2TEST)$(EXE_EXT) $(RMDTEST)$(EXE_EXT) \
+	$(RANDTEST)$(EXE_EXT) $(DHTEST)$(EXE_EXT) $(ENGINETEST)$(EXE_EXT) \
+	$(BFTEST)$(EXE_EXT) $(CASTTEST)$(EXE_EXT) $(SSLTEST)$(EXE_EXT) $(EXPTEST)$(EXE_EXT) $(DSATEST)$(EXE_EXT) $(RSATEST)$(EXE_EXT) \
+	$(EVPTEST)$(EXE_EXT) $(IGETEST)$(EXE_EXT) $(JPAKETEST)$(EXE_EXT) \
+	$(ASN1TEST)$(EXE_EXT)
+
+# $(METHTEST)$(EXE_EXT)
+
+OBJ=	$(BNTEST).o $(ECTEST).o  $(ECDSATEST).o $(ECDHTEST).o $(IDEATEST).o \
+	$(MD2TEST).o $(MD4TEST).o $(MD5TEST).o \
+	$(HMACTEST).o $(WPTEST).o \
+	$(RC2TEST).o $(RC4TEST).o $(RC5TEST).o \
+	$(DESTEST).o $(SHATEST).o $(SHA1TEST).o $(SHA256TEST).o $(SHA512TEST).o \
+	$(MDC2TEST).o $(RMDTEST).o \
+	$(RANDTEST).o $(DHTEST).o $(ENGINETEST).o $(CASTTEST).o \
+	$(BFTEST).o  $(SSLTEST).o  $(DSATEST).o  $(EXPTEST).o $(RSATEST).o \
+	$(EVPTEST).o $(IGETEST).o $(JPAKETEST).o $(ASN1TEST).o
+SRC=	$(BNTEST).c $(ECTEST).c  $(ECDSATEST).c $(ECDHTEST).c $(IDEATEST).c \
+	$(MD2TEST).c  $(MD4TEST).c $(MD5TEST).c \
+	$(HMACTEST).c $(WPTEST).c \
+	$(RC2TEST).c $(RC4TEST).c $(RC5TEST).c \
+	$(DESTEST).c $(SHATEST).c $(SHA1TEST).c $(MDC2TEST).c $(RMDTEST).c \
+	$(RANDTEST).c $(DHTEST).c $(ENGINETEST).c $(CASTTEST).c \
+	$(BFTEST).c  $(SSLTEST).c $(DSATEST).c   $(EXPTEST).c $(RSATEST).c \
+	$(EVPTEST).c $(IGETEST).c $(JPAKETEST).c $(ASN1TEST).c
+
+EXHEADER= 
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ..; $(MAKE) DIRS=$(DIR) TESTS=$(TESTS) all)
+
+all:	exe
+
+exe:	$(EXE) dummytest$(EXE_EXT)
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+
+generate: $(SRC)
+$(SRC):
+	@sh $(TOP)/util/point.sh dummytest.c $@
+
+errors:
+
+install:
+
+tags:
+	ctags $(SRC)
+
+tests:	exe apps $(TESTS)
+
+apps:
+	@(cd ..; $(MAKE) DIRS=apps all)
+
+alltests: \
+	test_des test_idea test_sha test_md4 test_md5 test_hmac \
+	test_md2 test_mdc2 test_wp \
+	test_rmd test_rc2 test_rc4 test_rc5 test_bf test_cast test_aes \
+	test_rand test_bn test_ec test_ecdsa test_ecdh \
+	test_enc test_x509 test_rsa test_crl test_sid \
+	test_gen test_req test_pkcs7 test_verify test_dh test_dsa \
+	test_ss test_ca test_engine test_evp test_ssl test_tsa test_ige \
+	test_jpake test_cms
+
+test_evp:
+	../util/shlib_wrap.sh ./$(EVPTEST) evptests.txt
+
+test_des:
+	../util/shlib_wrap.sh ./$(DESTEST)
+
+test_idea:
+	../util/shlib_wrap.sh ./$(IDEATEST)
+
+test_sha:
+	../util/shlib_wrap.sh ./$(SHATEST)
+	../util/shlib_wrap.sh ./$(SHA1TEST)
+	../util/shlib_wrap.sh ./$(SHA256TEST)
+	../util/shlib_wrap.sh ./$(SHA512TEST)
+
+test_mdc2:
+	../util/shlib_wrap.sh ./$(MDC2TEST)
+
+test_md5:
+	../util/shlib_wrap.sh ./$(MD5TEST)
+
+test_md4:
+	../util/shlib_wrap.sh ./$(MD4TEST)
+
+test_hmac:
+	../util/shlib_wrap.sh ./$(HMACTEST)
+
+test_wp:
+	../util/shlib_wrap.sh ./$(WPTEST)
+
+test_md2:
+	../util/shlib_wrap.sh ./$(MD2TEST)
+
+test_rmd:
+	../util/shlib_wrap.sh ./$(RMDTEST)
+
+test_bf:
+	../util/shlib_wrap.sh ./$(BFTEST)
+
+test_cast:
+	../util/shlib_wrap.sh ./$(CASTTEST)
+
+test_rc2:
+	../util/shlib_wrap.sh ./$(RC2TEST)
+
+test_rc4:
+	../util/shlib_wrap.sh ./$(RC4TEST)
+
+test_rc5:
+	../util/shlib_wrap.sh ./$(RC5TEST)
+
+test_rand:
+	../util/shlib_wrap.sh ./$(RANDTEST)
+
+test_enc:
+	@sh ./testenc
+
+test_x509:
+	echo test normal x509v1 certificate
+	sh ./tx509 2>/dev/null
+	echo test first x509v3 certificate
+	sh ./tx509 v3-cert1.pem 2>/dev/null
+	echo test second x509v3 certificate
+	sh ./tx509 v3-cert2.pem 2>/dev/null
+
+test_rsa: $(RSATEST)$(EXE_EXT)
+	@sh ./trsa 2>/dev/null
+	../util/shlib_wrap.sh ./$(RSATEST)
+
+test_crl:
+	@sh ./tcrl 2>/dev/null
+
+test_sid:
+	@sh ./tsid 2>/dev/null
+
+test_req:
+	@sh ./treq 2>/dev/null
+	@sh ./treq testreq2.pem 2>/dev/null
+
+test_pkcs7:
+	@sh ./tpkcs7 2>/dev/null
+	@sh ./tpkcs7d 2>/dev/null
+
+test_bn:
+	@echo starting big number library test, could take a while...
+	@../util/shlib_wrap.sh ./$(BNTEST) >tmp.bntest
+	@echo quit >>tmp.bntest
+	@echo "running bc"
+	@<tmp.bntest sh -c "`sh ./bctest ignore`" | $(PERL) -e '$$i=0; while (<STDIN>) {if (/^test (.*)/) {print STDERR "\nverify $$1";} elsif (!/^0$$/) {die "\nFailed! bc: $$_";} else {print STDERR "."; $$i++;}} print STDERR "\n$$i tests passed\n"'
+	@echo 'test a^b%c implementations'
+	../util/shlib_wrap.sh ./$(EXPTEST)
+
+test_ec:
+	@echo 'test elliptic curves'
+	../util/shlib_wrap.sh ./$(ECTEST)
+
+test_ecdsa:
+	@echo 'test ecdsa'
+	../util/shlib_wrap.sh ./$(ECDSATEST)
+
+test_ecdh:
+	@echo 'test ecdh'
+	../util/shlib_wrap.sh ./$(ECDHTEST)
+
+test_verify:
+	@echo "The following command should have some OK's and some failures"
+	@echo "There are definitly a few expired certificates"
+	../util/shlib_wrap.sh ../apps/openssl verify -CApath ../certs ../certs/*.pem
+
+test_dh:
+	@echo "Generate a set of DH parameters"
+	../util/shlib_wrap.sh ./$(DHTEST)
+
+test_dsa:
+	@echo "Generate a set of DSA parameters"
+	../util/shlib_wrap.sh ./$(DSATEST)
+	../util/shlib_wrap.sh ./$(DSATEST) -app2_1
+
+test_gen:
+	@echo "Generate and verify a certificate request"
+	@sh ./testgen
+
+test_ss keyU.ss certU.ss certCA.ss certP1.ss keyP1.ss certP2.ss keyP2.ss \
+		intP1.ss intP2.ss: testss
+	@echo "Generate and certify a test certificate"
+	@sh ./testss
+	@cat certCA.ss certU.ss > intP1.ss
+	@cat certCA.ss certU.ss certP1.ss > intP2.ss
+
+test_engine: 
+	@echo "Manipulate the ENGINE structures"
+	../util/shlib_wrap.sh ./$(ENGINETEST)
+
+test_ssl: keyU.ss certU.ss certCA.ss certP1.ss keyP1.ss certP2.ss keyP2.ss \
+		intP1.ss intP2.ss
+	@echo "test SSL protocol"
+	../util/shlib_wrap.sh ./$(SSLTEST) -test_cipherlist
+	@sh ./testssl keyU.ss certU.ss certCA.ss
+	@sh ./testsslproxy keyP1.ss certP1.ss intP1.ss
+	@sh ./testsslproxy keyP2.ss certP2.ss intP2.ss
+
+test_ca:
+	@if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then \
+	  echo "skipping CA.sh test -- requires RSA"; \
+	else \
+	  echo "Generate and certify a test certificate via the 'ca' program"; \
+	  sh ./testca; \
+	fi
+
+test_aes: #$(AESTEST)
+#	@echo "test Rijndael"
+#	../util/shlib_wrap.sh ./$(AESTEST)
+
+test_tsa:
+	@if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then \
+	  echo "skipping testtsa test -- requires RSA"; \
+	else \
+	  sh ./testtsa; \
+	fi
+
+test_ige: $(IGETEST)$(EXE_EXT)
+	@echo "Test IGE mode"
+	../util/shlib_wrap.sh ./$(IGETEST)
+
+test_jpake: $(JPAKETEST)$(EXE_EXT)
+	@echo "Test JPAKE"
+	../util/shlib_wrap.sh ./$(JPAKETEST)
+
+test_cms:
+	@echo "CMS consistency test"
+	$(PERL) cms-test.pl
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@if [ -z "$(THIS)" ]; then \
+	    $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
+	else \
+	    $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(SRC); \
+	fi
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+	rm -f $(SRC) $(SHA256TEST).c $(SHA512TEST).c evptests.txt newkey.pem testkey.pem \
+			testreq.pem
+
+clean:
+	rm -f .rnd tmp.bntest tmp.bctest *.o *.obj *.dll lib tags core .pure .nfs* *.old *.bak fluff $(EXE) *.ss *.srl log dummytest
+
+$(DLIBSSL):
+	(cd ..; $(MAKE) DIRS=ssl all)
+
+$(DLIBCRYPTO):
+	(cd ..; $(MAKE) DIRS=crypto all)
+
+BUILD_CMD=shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \
+		shlib_target="$(SHLIB_TARGET)"; \
+	fi; \
+	LIBRARIES="$(LIBSSL) $(LIBCRYPTO) $(LIBKRB5)"; \
+	$(MAKE) -f $(TOP)/Makefile.shared -e \
+		APPNAME=$$target$(EXE_EXT) OBJECTS="$$target.o" \
+		LIBDEPS="$(PEX_LIBS) $$LIBRARIES $(EX_LIBS)" \
+		link_app.$${shlib_target}
+
+$(RSATEST)$(EXE_EXT): $(RSATEST).o $(DLIBCRYPTO)
+	@target=$(RSATEST); $(BUILD_CMD)
+
+$(BNTEST)$(EXE_EXT): $(BNTEST).o $(DLIBCRYPTO)
+	@target=$(BNTEST); $(BUILD_CMD)
+
+$(ECTEST)$(EXE_EXT): $(ECTEST).o $(DLIBCRYPTO)
+	@target=$(ECTEST); $(BUILD_CMD)
+
+$(EXPTEST)$(EXE_EXT): $(EXPTEST).o $(DLIBCRYPTO)
+	@target=$(EXPTEST); $(BUILD_CMD)
+
+$(IDEATEST)$(EXE_EXT): $(IDEATEST).o $(DLIBCRYPTO)
+	@target=$(IDEATEST); $(BUILD_CMD)
+
+$(MD2TEST)$(EXE_EXT): $(MD2TEST).o $(DLIBCRYPTO)
+	@target=$(MD2TEST); $(BUILD_CMD)
+
+$(SHATEST)$(EXE_EXT): $(SHATEST).o $(DLIBCRYPTO)
+	@target=$(SHATEST); $(BUILD_CMD)
+
+$(SHA1TEST)$(EXE_EXT): $(SHA1TEST).o $(DLIBCRYPTO)
+	@target=$(SHA1TEST); $(BUILD_CMD)
+
+$(SHA256TEST)$(EXE_EXT): $(SHA256TEST).o $(DLIBCRYPTO)
+	@target=$(SHA256TEST); $(BUILD_CMD)
+
+$(SHA512TEST)$(EXE_EXT): $(SHA512TEST).o $(DLIBCRYPTO)
+	@target=$(SHA512TEST); $(BUILD_CMD)
+
+$(RMDTEST)$(EXE_EXT): $(RMDTEST).o $(DLIBCRYPTO)
+	@target=$(RMDTEST); $(BUILD_CMD)
+
+$(MDC2TEST)$(EXE_EXT): $(MDC2TEST).o $(DLIBCRYPTO)
+	@target=$(MDC2TEST); $(BUILD_CMD)
+
+$(MD4TEST)$(EXE_EXT): $(MD4TEST).o $(DLIBCRYPTO)
+	@target=$(MD4TEST); $(BUILD_CMD)
+
+$(MD5TEST)$(EXE_EXT): $(MD5TEST).o $(DLIBCRYPTO)
+	@target=$(MD5TEST); $(BUILD_CMD)
+
+$(HMACTEST)$(EXE_EXT): $(HMACTEST).o $(DLIBCRYPTO)
+	@target=$(HMACTEST); $(BUILD_CMD)
+
+$(WPTEST)$(EXE_EXT): $(WPTEST).o $(DLIBCRYPTO)
+	@target=$(WPTEST); $(BUILD_CMD)
+
+$(RC2TEST)$(EXE_EXT): $(RC2TEST).o $(DLIBCRYPTO)
+	@target=$(RC2TEST); $(BUILD_CMD)
+
+$(BFTEST)$(EXE_EXT): $(BFTEST).o $(DLIBCRYPTO)
+	@target=$(BFTEST); $(BUILD_CMD)
+
+$(CASTTEST)$(EXE_EXT): $(CASTTEST).o $(DLIBCRYPTO)
+	@target=$(CASTTEST); $(BUILD_CMD)
+
+$(RC4TEST)$(EXE_EXT): $(RC4TEST).o $(DLIBCRYPTO)
+	@target=$(RC4TEST); $(BUILD_CMD)
+
+$(RC5TEST)$(EXE_EXT): $(RC5TEST).o $(DLIBCRYPTO)
+	@target=$(RC5TEST); $(BUILD_CMD)
+
+$(DESTEST)$(EXE_EXT): $(DESTEST).o $(DLIBCRYPTO)
+	@target=$(DESTEST); $(BUILD_CMD)
+
+$(RANDTEST)$(EXE_EXT): $(RANDTEST).o $(DLIBCRYPTO)
+	@target=$(RANDTEST); $(BUILD_CMD)
+
+$(DHTEST)$(EXE_EXT): $(DHTEST).o $(DLIBCRYPTO)
+	@target=$(DHTEST); $(BUILD_CMD)
+
+$(DSATEST)$(EXE_EXT): $(DSATEST).o $(DLIBCRYPTO)
+	@target=$(DSATEST); $(BUILD_CMD)
+
+$(METHTEST)$(EXE_EXT): $(METHTEST).o $(DLIBCRYPTO)
+	@target=$(METHTEST); $(BUILD_CMD)
+
+$(SSLTEST)$(EXE_EXT): $(SSLTEST).o $(DLIBSSL) $(DLIBCRYPTO)
+	@target=$(SSLTEST); $(BUILD_CMD)
+
+$(ENGINETEST)$(EXE_EXT): $(ENGINETEST).o $(DLIBCRYPTO)
+	@target=$(ENGINETEST); $(BUILD_CMD)
+
+$(EVPTEST)$(EXE_EXT): $(EVPTEST).o $(DLIBCRYPTO)
+	@target=$(EVPTEST); $(BUILD_CMD)
+
+$(ECDSATEST)$(EXE_EXT): $(ECDSATEST).o $(DLIBCRYPTO)
+	@target=$(ECDSATEST); $(BUILD_CMD)
+
+$(ECDHTEST)$(EXE_EXT): $(ECDHTEST).o $(DLIBCRYPTO)
+	@target=$(ECDHTEST); $(BUILD_CMD)
+
+$(IGETEST)$(EXE_EXT): $(IGETEST).o $(DLIBCRYPTO)
+	@target=$(IGETEST); $(BUILD_CMD)
+
+$(JPAKETEST)$(EXE_EXT): $(JPAKETEST).o $(DLIBCRYPTO)
+	@target=$(JPAKETEST); $(BUILD_CMD)
+
+$(ASN1TEST)$(EXE_EXT): $(ASN1TEST).o $(DLIBCRYPTO)
+	@target=$(ASN1TEST); $(BUILD_CMD)
+
+#$(AESTEST).o: $(AESTEST).c
+#	$(CC) -c $(CFLAGS) -DINTERMEDIATE_VALUE_KAT -DTRACE_KAT_MCT $(AESTEST).c
+
+#$(AESTEST)$(EXE_EXT): $(AESTEST).o $(DLIBCRYPTO)
+#	if [ "$(SHLIB_TARGET)" = "hpux-shared" -o "$(SHLIB_TARGET)" = "darwin-shared" ] ; then \
+#	  $(CC) -o $(AESTEST)$(EXE_EXT) $(CFLAGS) $(AESTEST).o $(PEX_LIBS) $(DLIBCRYPTO) $(EX_LIBS) ; \
+#	else \
+#	  $(CC) -o $(AESTEST)$(EXE_EXT) $(CFLAGS) $(AESTEST).o $(PEX_LIBS) $(LIBCRYPTO) $(EX_LIBS) ; \
+#	fi
+
+dummytest$(EXE_EXT): dummytest.o $(DLIBCRYPTO)
+	@target=dummytest; $(BUILD_CMD)
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+asn1test.o: ../include/openssl/asn1.h ../include/openssl/asn1_mac.h
+asn1test.o: ../include/openssl/bio.h ../include/openssl/buffer.h
+asn1test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+asn1test.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+asn1test.o: ../include/openssl/ecdsa.h ../include/openssl/evp.h
+asn1test.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+asn1test.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+asn1test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+asn1test.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+asn1test.o: ../include/openssl/sha.h ../include/openssl/stack.h
+asn1test.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
+asn1test.o: ../include/openssl/x509_vfy.h asn1test.c
+bftest.o: ../e_os.h ../include/openssl/blowfish.h ../include/openssl/e_os2.h
+bftest.o: ../include/openssl/opensslconf.h bftest.c
+bntest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+bntest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+bntest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+bntest.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
+bntest.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+bntest.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+bntest.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+bntest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+bntest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+bntest.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+bntest.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+bntest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+bntest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+bntest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h bntest.c
+casttest.o: ../e_os.h ../include/openssl/cast.h ../include/openssl/e_os2.h
+casttest.o: ../include/openssl/opensslconf.h casttest.c
+destest.o: ../include/openssl/des.h ../include/openssl/des_old.h
+destest.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
+destest.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+destest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+destest.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h destest.c
+dhtest.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/bn.h
+dhtest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+dhtest.o: ../include/openssl/e_os2.h ../include/openssl/err.h
+dhtest.o: ../include/openssl/lhash.h ../include/openssl/opensslconf.h
+dhtest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+dhtest.o: ../include/openssl/rand.h ../include/openssl/safestack.h
+dhtest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h dhtest.c
+dsatest.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/bn.h
+dsatest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+dsatest.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
+dsatest.o: ../include/openssl/err.h ../include/openssl/lhash.h
+dsatest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+dsatest.o: ../include/openssl/ossl_typ.h ../include/openssl/rand.h
+dsatest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+dsatest.o: ../include/openssl/symhacks.h dsatest.c
+ecdhtest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ecdhtest.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+ecdhtest.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ecdhtest.o: ../include/openssl/ecdh.h ../include/openssl/err.h
+ecdhtest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ecdhtest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+ecdhtest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ecdhtest.o: ../include/openssl/rand.h ../include/openssl/safestack.h
+ecdhtest.o: ../include/openssl/sha.h ../include/openssl/stack.h
+ecdhtest.o: ../include/openssl/symhacks.h ecdhtest.c
+ecdsatest.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+ecdsatest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+ecdsatest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+ecdsatest.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ecdsatest.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+ecdsatest.o: ../include/openssl/err.h ../include/openssl/evp.h
+ecdsatest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ecdsatest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+ecdsatest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ecdsatest.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+ecdsatest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ecdsatest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ecdsatest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+ecdsatest.o: ecdsatest.c
+ectest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ectest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+ectest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+ectest.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ectest.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+ectest.o: ../include/openssl/err.h ../include/openssl/evp.h
+ectest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ectest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+ectest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ectest.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+ectest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ectest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ectest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ectest.c
+enginetest.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+enginetest.o: ../include/openssl/buffer.h ../include/openssl/crypto.h
+enginetest.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+enginetest.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+enginetest.o: ../include/openssl/engine.h ../include/openssl/err.h
+enginetest.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+enginetest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+enginetest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+enginetest.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+enginetest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+enginetest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+enginetest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+enginetest.o: enginetest.c
+evp_test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+evp_test.o: ../include/openssl/buffer.h ../include/openssl/conf.h
+evp_test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+evp_test.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+evp_test.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+evp_test.o: ../include/openssl/err.h ../include/openssl/evp.h
+evp_test.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+evp_test.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+evp_test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+evp_test.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+evp_test.o: ../include/openssl/sha.h ../include/openssl/stack.h
+evp_test.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
+evp_test.o: ../include/openssl/x509_vfy.h evp_test.c
+exptest.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/bn.h
+exptest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+exptest.o: ../include/openssl/err.h ../include/openssl/lhash.h
+exptest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+exptest.o: ../include/openssl/ossl_typ.h ../include/openssl/rand.h
+exptest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+exptest.o: ../include/openssl/symhacks.h exptest.c
+hmactest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+hmactest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+hmactest.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+hmactest.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+hmactest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+hmactest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+hmactest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+hmactest.o: ../include/openssl/symhacks.h hmactest.c
+ideatest.o: ../e_os.h ../include/openssl/e_os2.h ../include/openssl/idea.h
+ideatest.o: ../include/openssl/opensslconf.h ideatest.c
+igetest.o: ../include/openssl/aes.h ../include/openssl/e_os2.h
+igetest.o: ../include/openssl/opensslconf.h ../include/openssl/ossl_typ.h
+igetest.o: ../include/openssl/rand.h igetest.c
+jpaketest.o: ../include/openssl/buffer.h ../include/openssl/crypto.h
+jpaketest.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
+jpaketest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+jpaketest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+jpaketest.o: ../include/openssl/symhacks.h jpaketest.c
+md2test.o: ../include/openssl/buffer.h ../include/openssl/crypto.h
+md2test.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
+md2test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+md2test.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+md2test.o: ../include/openssl/symhacks.h md2test.c
+md4test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+md4test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+md4test.o: ../include/openssl/evp.h ../include/openssl/md4.h
+md4test.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+md4test.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+md4test.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+md4test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h md4test.c
+md5test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+md5test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+md5test.o: ../include/openssl/evp.h ../include/openssl/md5.h
+md5test.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+md5test.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+md5test.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+md5test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h md5test.c
+mdc2test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+mdc2test.o: ../include/openssl/crypto.h ../include/openssl/des.h
+mdc2test.o: ../include/openssl/des_old.h ../include/openssl/e_os2.h
+mdc2test.o: ../include/openssl/evp.h ../include/openssl/mdc2.h
+mdc2test.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+mdc2test.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+mdc2test.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+mdc2test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+mdc2test.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h mdc2test.c
+randtest.o: ../e_os.h ../include/openssl/e_os2.h
+randtest.o: ../include/openssl/opensslconf.h ../include/openssl/ossl_typ.h
+randtest.o: ../include/openssl/rand.h randtest.c
+rc2test.o: ../e_os.h ../include/openssl/e_os2.h
+rc2test.o: ../include/openssl/opensslconf.h ../include/openssl/rc2.h rc2test.c
+rc4test.o: ../e_os.h ../include/openssl/e_os2.h
+rc4test.o: ../include/openssl/opensslconf.h ../include/openssl/rc4.h
+rc4test.o: ../include/openssl/sha.h rc4test.c
+rc5test.o: ../include/openssl/buffer.h ../include/openssl/crypto.h
+rc5test.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
+rc5test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+rc5test.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+rc5test.o: ../include/openssl/symhacks.h rc5test.c
+rmdtest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+rmdtest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+rmdtest.o: ../include/openssl/evp.h ../include/openssl/obj_mac.h
+rmdtest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+rmdtest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+rmdtest.o: ../include/openssl/ripemd.h ../include/openssl/safestack.h
+rmdtest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h rmdtest.c
+rsa_test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+rsa_test.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+rsa_test.o: ../include/openssl/e_os2.h ../include/openssl/err.h
+rsa_test.o: ../include/openssl/lhash.h ../include/openssl/opensslconf.h
+rsa_test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+rsa_test.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+rsa_test.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+rsa_test.o: ../include/openssl/symhacks.h rsa_test.c
+sha1test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+sha1test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+sha1test.o: ../include/openssl/evp.h ../include/openssl/obj_mac.h
+sha1test.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+sha1test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+sha1test.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+sha1test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h sha1test.c
+shatest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+shatest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+shatest.o: ../include/openssl/evp.h ../include/openssl/obj_mac.h
+shatest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+shatest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+shatest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+shatest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h shatest.c
+ssltest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ssltest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+ssltest.o: ../include/openssl/comp.h ../include/openssl/conf.h
+ssltest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+ssltest.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
+ssltest.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ssltest.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+ssltest.o: ../include/openssl/engine.h ../include/openssl/err.h
+ssltest.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+ssltest.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+ssltest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ssltest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ssltest.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ssltest.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ssltest.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+ssltest.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+ssltest.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+ssltest.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ssltest.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ssltest.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ssltest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+ssltest.o: ../include/openssl/x509v3.h ssltest.c
+wp_test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+wp_test.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+wp_test.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+wp_test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+wp_test.o: ../include/openssl/whrlpool.h wp_test.c
diff --git a/openssl/test/P1ss.cnf b/openssl/test/P1ss.cnf
new file mode 100644
index 0000000..876a0d3
--- /dev/null
+++ b/openssl/test/P1ss.cnf
@@ -0,0 +1,37 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+RANDFILE		= ./.rnd
+
+####################################################################
+[ req ]
+default_bits		= 512
+default_keyfile 	= keySS.pem
+distinguished_name	= req_distinguished_name
+encrypt_rsa_key		= no
+default_md		= md2
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= AU
+countryName_value		= AU
+
+organizationName                = Organization Name (eg, company)
+organizationName_value          = Dodgy Brothers
+
+0.commonName			= Common Name (eg, YOUR name)
+0.commonName_value		= Brother 1
+
+1.commonName			= Common Name (eg, YOUR name)
+1.commonName_value		= Brother 2
+
+2.commonName			= Common Name (eg, YOUR name)
+2.commonName_value		= Proxy 1
+
+[ v3_proxy ]
+basicConstraints=CA:FALSE
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:1,policy:text:AB
diff --git a/openssl/test/P2ss.cnf b/openssl/test/P2ss.cnf
new file mode 100644
index 0000000..373a87e
--- /dev/null
+++ b/openssl/test/P2ss.cnf
@@ -0,0 +1,45 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+RANDFILE		= ./.rnd
+
+####################################################################
+[ req ]
+default_bits		= 512
+default_keyfile 	= keySS.pem
+distinguished_name	= req_distinguished_name
+encrypt_rsa_key		= no
+default_md		= md2
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= AU
+countryName_value		= AU
+
+organizationName                = Organization Name (eg, company)
+organizationName_value          = Dodgy Brothers
+
+0.commonName			= Common Name (eg, YOUR name)
+0.commonName_value		= Brother 1
+
+1.commonName			= Common Name (eg, YOUR name)
+1.commonName_value		= Brother 2
+
+2.commonName			= Common Name (eg, YOUR name)
+2.commonName_value		= Proxy 1
+
+3.commonName			= Common Name (eg, YOUR name)
+3.commonName_value		= Proxy 2
+
+[ v3_proxy ]
+basicConstraints=CA:FALSE
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+proxyCertInfo=critical,@proxy_ext
+
+[ proxy_ext ]
+language=id-ppl-anyLanguage
+pathlen=0
+policy=text:BC
diff --git a/openssl/test/Sssdsa.cnf b/openssl/test/Sssdsa.cnf
new file mode 100644
index 0000000..8e170a2
--- /dev/null
+++ b/openssl/test/Sssdsa.cnf
@@ -0,0 +1,27 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+# hacked by iang to do DSA certs - Server
+
+RANDFILE              = ./.rnd
+
+####################################################################
+[ req ]
+distinguished_name    = req_distinguished_name
+encrypt_rsa_key               = no
+
+[ req_distinguished_name ]
+countryName                   = Country Name (2 letter code)
+countryName_default           = ES
+countryName_value             = ES
+
+organizationName                = Organization Name (eg, company)
+organizationName_value          = Tortilleras S.A.
+
+0.commonName                  = Common Name (eg, YOUR name)
+0.commonName_value            = Torti
+
+1.commonName                  = Common Name (eg, YOUR name)
+1.commonName_value            = Gordita
+
diff --git a/openssl/test/Sssrsa.cnf b/openssl/test/Sssrsa.cnf
new file mode 100644
index 0000000..8c79a03
--- /dev/null
+++ b/openssl/test/Sssrsa.cnf
@@ -0,0 +1,26 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+# create RSA certs - Server
+
+RANDFILE              = ./.rnd
+
+####################################################################
+[ req ]
+distinguished_name    = req_distinguished_name
+encrypt_key           = no
+
+[ req_distinguished_name ]
+countryName                   = Country Name (2 letter code)
+countryName_default           = ES
+countryName_value             = ES
+
+organizationName                = Organization Name (eg, company)
+organizationName_value          = Tortilleras S.A.
+
+0.commonName                  = Common Name (eg, YOUR name)
+0.commonName_value            = Torti
+
+1.commonName                  = Common Name (eg, YOUR name)
+1.commonName_value            = Gordita
diff --git a/openssl/test/Uss.cnf b/openssl/test/Uss.cnf
new file mode 100644
index 0000000..0c0ebb5
--- /dev/null
+++ b/openssl/test/Uss.cnf
@@ -0,0 +1,36 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+RANDFILE		= ./.rnd
+
+####################################################################
+[ req ]
+default_bits		= 512
+default_keyfile 	= keySS.pem
+distinguished_name	= req_distinguished_name
+encrypt_rsa_key		= no
+default_md		= md2
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= AU
+countryName_value		= AU
+
+organizationName                = Organization Name (eg, company)
+organizationName_value          = Dodgy Brothers
+
+0.commonName			= Common Name (eg, YOUR name)
+0.commonName_value		= Brother 1
+
+1.commonName			= Common Name (eg, YOUR name)
+1.commonName_value		= Brother 2
+
+[ v3_ee ]
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+basicConstraints = CA:false
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+issuerAltName=issuer:copy
+
diff --git a/openssl/test/VMSca-response.1 b/openssl/test/VMSca-response.1
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/openssl/test/VMSca-response.1
@@ -0,0 +1 @@
+
diff --git a/openssl/test/VMSca-response.2 b/openssl/test/VMSca-response.2
new file mode 100644
index 0000000..9b48ee4
--- /dev/null
+++ b/openssl/test/VMSca-response.2
@@ -0,0 +1,2 @@
+y
+y
diff --git a/openssl/test/asn1test.c b/openssl/test/asn1test.c
new file mode 100644
index 0000000..9f53d80
--- /dev/null
+++ b/openssl/test/asn1test.c
@@ -0,0 +1,22 @@
+#include <openssl/x509.h>
+#include <openssl/asn1_mac.h>
+
+typedef struct X
+    {
+    STACK_OF(X509_EXTENSION) *ext;
+    } X;
+
+/* This isn't meant to run particularly, it's just to test type checking */
+int main(int argc, char **argv)
+    {
+    X *x = NULL;
+    unsigned char **pp = NULL;
+
+    M_ASN1_I2D_vars(x);
+    M_ASN1_I2D_len_SEQUENCE_opt_type(X509_EXTENSION, x->ext,
+				     i2d_X509_EXTENSION);
+    M_ASN1_I2D_seq_total();
+    M_ASN1_I2D_put_SEQUENCE_opt_type(X509_EXTENSION, x->ext,
+				     i2d_X509_EXTENSION);
+    M_ASN1_I2D_finish();
+    }
diff --git a/openssl/test/bctest b/openssl/test/bctest
new file mode 100755
index 0000000..bdb3218
--- /dev/null
+++ b/openssl/test/bctest
@@ -0,0 +1,111 @@
+#!/bin/sh
+
+# This script is used by test/Makefile.ssl to check whether a sane 'bc'
+# is installed.
+# ('make test_bn' should not try to run 'bc' if it does not exist or if
+# it is a broken 'bc' version that is known to cause trouble.)
+#
+# If 'bc' works, we also test if it knows the 'print' command.
+#
+# In any case, output an appropriate command line for running (or not
+# running) bc.
+
+
+IFS=:
+try_without_dir=true
+# First we try "bc", then "$dir/bc" for each item in $PATH.
+for dir in dummy:$PATH; do
+    if [ "$try_without_dir" = true ]; then
+      # first iteration
+      bc=bc
+      try_without_dir=false
+    else
+      # second and later iterations
+      bc="$dir/bc"
+      if [ ! -f "$bc" ]; then  # '-x' is not available on Ultrix
+        bc=''
+      fi
+    fi
+
+    if [ ! "$bc" = '' ]; then
+        failure=none
+
+
+        # Test for SunOS 5.[78] bc bug
+        "$bc" >tmp.bctest <<\EOF
+obase=16
+ibase=16
+a=AD88C418F31B3FC712D0425001D522B3AE9134FF3A98C13C1FCC1682211195406C1A6C66C6A\
+CEEC1A0EC16950233F77F1C2F2363D56DD71A36C57E0B2511FC4BA8F22D261FE2E9356D99AF57\
+10F3817C0E05BF79C423C3F66FDF321BE8D3F18F625D91B670931C1EF25F28E489BDA1C5422D1\
+C3F6F7A1AD21585746ECC4F10A14A778AF56F08898E965E9909E965E0CB6F85B514150C644759\
+3BE731877B16EA07B552088FF2EA728AC5E0FF3A23EB939304519AB8B60F2C33D6BA0945B66F0\
+4FC3CADF855448B24A9D7640BCF473E
+b=DCE91E7D120B983EA9A104B5A96D634DD644C37657B1C7860B45E6838999B3DCE5A555583C6\
+9209E41F413422954175A06E67FFEF6746DD652F0F48AEFECC3D8CAC13523BDAAD3F5AF4212BD\
+8B3CD64126E1A82E190228020C05B91C8B141F1110086FC2A4C6ED631EBA129D04BB9A19FC53D\
+3ED0E2017D60A68775B75481449
+(a/b)*b + (a%b) - a
+EOF
+        if [ 0 != "`cat tmp.bctest`" ]; then
+            failure=SunOStest
+        fi
+
+
+        if [ "$failure" = none ]; then
+            # Test for SCO bc bug.
+            "$bc" >tmp.bctest <<\EOF
+obase=16
+ibase=16
+-FFDD63BA1A4648F0D804F8A1C66C53F0D2110590E8A3907EC73B4AEC6F15AC177F176F2274D2\
+9DC8022EA0D7DD3ABE9746D2D46DD3EA5B5F6F69DF12877E0AC5E7F5ADFACEE54573F5D256A06\
+11B5D2BC24947724E22AE4EC3FB0C39D9B4694A01AFE5E43B4D99FB9812A0E4A5773D8B254117\
+1239157EC6E3D8D50199 * -FFDD63BA1A4648F0D804F8A1C66C53F0D2110590E8A3907EC73B4\
+AEC6F15AC177F176F2274D29DC8022EA0D7DD3ABE9746D2D46DD3EA5B5F6F69DF12877E0AC5E7\
+F5ADFACEE54573F5D256A0611B5D2BC24947724E22AE4EC3FB0C39D9B4694A01AFE5E43B4D99F\
+B9812A0E4A5773D8B2541171239157EC6E3D8D50199 - FFBACC221682DA464B6D7F123482522\
+02EDAEDCA38C3B69E9B7BBCD6165A9CD8716C4903417F23C09A85B851961F92C217258CEEB866\
+85EFCC5DD131853A02C07A873B8E2AF2E40C6D5ED598CD0E8F35AD49F3C3A17FDB7653E4E2DC4\
+A8D23CC34686EE4AD01F7407A7CD74429AC6D36DBF0CB6A3E302D0E5BDFCD048A3B90C1BE5AA8\
+E16C3D5884F9136B43FF7BB443764153D4AEC176C681B078F4CC53D6EB6AB76285537DDEE7C18\
+8C72441B52EDBDDBC77E02D34E513F2AABF92F44109CAFE8242BD0ECBAC5604A94B02EA44D43C\
+04E9476E6FBC48043916BFA1485C6093603600273C9C33F13114D78064AE42F3DC466C7DA543D\
+89C8D71
+AD534AFBED2FA39EE9F40E20FCF9E2C861024DB98DDCBA1CD118C49CA55EEBC20D6BA51B2271C\
+928B693D6A73F67FEB1B4571448588B46194617D25D910C6A9A130CC963155CF34079CB218A44\
+8A1F57E276D92A33386DDCA3D241DB78C8974ABD71DD05B0FA555709C9910D745185E6FE108E3\
+37F1907D0C56F8BFBF52B9704 % -E557905B56B13441574CAFCE2BD257A750B1A8B2C88D0E36\
+E18EF7C38DAC80D3948E17ED63AFF3B3467866E3B89D09A81B3D16B52F6A3C7134D3C6F5123E9\
+F617E3145BBFBE9AFD0D6E437EA4FF6F04BC67C4F1458B4F0F47B64 - 1C2BBBB19B74E86FD32\
+9E8DB6A8C3B1B9986D57ED5419C2E855F7D5469E35E76334BB42F4C43E3F3A31B9697C171DAC4\
+D97935A7E1A14AD209D6CF811F55C6DB83AA9E6DFECFCD6669DED7171EE22A40C6181615CAF3F\
+5296964
+EOF
+            if [ "0
+0" != "`cat tmp.bctest`" ]; then
+                failure=SCOtest
+            fi
+        fi
+
+
+        if [ "$failure" = none ]; then
+            # bc works; now check if it knows the 'print' command.
+            if [ "OK" = "`echo 'print \"OK\"' | $bc 2>/dev/null`" ]
+            then
+                echo "$bc"
+            else
+                echo "sed 's/print.*//' | $bc"
+            fi
+            exit 0
+        fi
+
+        echo "$bc does not work properly ('$failure' failed).  Looking for another bc ..." >&2
+    fi
+done
+
+echo "No working bc found.  Consider installing GNU bc." >&2
+if [ "$1" = ignore ]; then
+  echo "cat >/dev/null"
+  exit 0
+fi
+exit 1
diff --git a/openssl/test/bctest.com b/openssl/test/bctest.com
new file mode 100644
index 0000000..d7e5ec1
--- /dev/null
+++ b/openssl/test/bctest.com
@@ -0,0 +1,152 @@
+$!
+$! Check operation of "bc".
+$!
+$! 2010-04-05 SMS.  New.  Based (loosely) on "bctest".
+$!
+$!
+$ tmp_file_name = "tmp.bctest"
+$ failure = ""
+$!
+$! Basic command test.
+$!
+$ on warning then goto bc_fail
+$ bc
+$ on error then exit
+$!
+$! Test for SunOS 5.[78] bc bug.
+$!
+$ if (failure .eqs. "")
+$ then
+$!
+$     define /user_mode sys$output 'tmp_file_name'
+$     bc
+obase=16
+ibase=16
+a=AD88C418F31B3FC712D0425001D522B3AE9134FF3A98C13C1FCC1682211195406C1A6C66C6A\
+CEEC1A0EC16950233F77F1C2F2363D56DD71A36C57E0B2511FC4BA8F22D261FE2E9356D99AF57\
+10F3817C0E05BF79C423C3F66FDF321BE8D3F18F625D91B670931C1EF25F28E489BDA1C5422D1\
+C3F6F7A1AD21585746ECC4F10A14A778AF56F08898E965E9909E965E0CB6F85B514150C644759\
+3BE731877B16EA07B552088FF2EA728AC5E0FF3A23EB939304519AB8B60F2C33D6BA0945B66F0\
+4FC3CADF855448B24A9D7640BCF473E
+b=DCE91E7D120B983EA9A104B5A96D634DD644C37657B1C7860B45E6838999B3DCE5A555583C6\
+9209E41F413422954175A06E67FFEF6746DD652F0F48AEFECC3D8CAC13523BDAAD3F5AF4212BD\
+8B3CD64126E1A82E190228020C05B91C8B141F1110086FC2A4C6ED631EBA129D04BB9A19FC53D\
+3ED0E2017D60A68775B75481449
+(a/b)*b + (a%b) - a
+$     status = $status
+$     output_expected = "0"
+$     gosub check_output
+$     if (output .ne. 1)
+$     then
+$         failure = "SunOStest"
+$     else
+$         delete 'f$parse( tmp_file_name)'
+$     endif
+$ endif
+$!
+$! Test for SCO bc bug.
+$!
+$ if (failure .eqs. "")
+$ then
+$!
+$     define /user_mode sys$output 'tmp_file_name'
+$     bc
+obase=16
+ibase=16
+-FFDD63BA1A4648F0D804F8A1C66C53F0D2110590E8A3907EC73B4AEC6F15AC177F176F2274D2\
+9DC8022EA0D7DD3ABE9746D2D46DD3EA5B5F6F69DF12877E0AC5E7F5ADFACEE54573F5D256A06\
+11B5D2BC24947724E22AE4EC3FB0C39D9B4694A01AFE5E43B4D99FB9812A0E4A5773D8B254117\
+1239157EC6E3D8D50199 * -FFDD63BA1A4648F0D804F8A1C66C53F0D2110590E8A3907EC73B4\
+AEC6F15AC177F176F2274D29DC8022EA0D7DD3ABE9746D2D46DD3EA5B5F6F69DF12877E0AC5E7\
+F5ADFACEE54573F5D256A0611B5D2BC24947724E22AE4EC3FB0C39D9B4694A01AFE5E43B4D99F\
+B9812A0E4A5773D8B2541171239157EC6E3D8D50199 - FFBACC221682DA464B6D7F123482522\
+02EDAEDCA38C3B69E9B7BBCD6165A9CD8716C4903417F23C09A85B851961F92C217258CEEB866\
+85EFCC5DD131853A02C07A873B8E2AF2E40C6D5ED598CD0E8F35AD49F3C3A17FDB7653E4E2DC4\
+A8D23CC34686EE4AD01F7407A7CD74429AC6D36DBF0CB6A3E302D0E5BDFCD048A3B90C1BE5AA8\
+E16C3D5884F9136B43FF7BB443764153D4AEC176C681B078F4CC53D6EB6AB76285537DDEE7C18\
+8C72441B52EDBDDBC77E02D34E513F2AABF92F44109CAFE8242BD0ECBAC5604A94B02EA44D43C\
+04E9476E6FBC48043916BFA1485C6093603600273C9C33F13114D78064AE42F3DC466C7DA543D\
+89C8D71
+AD534AFBED2FA39EE9F40E20FCF9E2C861024DB98DDCBA1CD118C49CA55EEBC20D6BA51B2271C\
+928B693D6A73F67FEB1B4571448588B46194617D25D910C6A9A130CC963155CF34079CB218A44\
+8A1F57E276D92A33386DDCA3D241DB78C8974ABD71DD05B0FA555709C9910D745185E6FE108E3\
+37F1907D0C56F8BFBF52B9704 % -E557905B56B13441574CAFCE2BD257A750B1A8B2C88D0E36\
+E18EF7C38DAC80D3948E17ED63AFF3B3467866E3B89D09A81B3D16B52F6A3C7134D3C6F5123E9\
+F617E3145BBFBE9AFD0D6E437EA4FF6F04BC67C4F1458B4F0F47B64 - 1C2BBBB19B74E86FD32\
+9E8DB6A8C3B1B9986D57ED5419C2E855F7D5469E35E76334BB42F4C43E3F3A31B9697C171DAC4\
+D97935A7E1A14AD209D6CF811F55C6DB83AA9E6DFECFCD6669DED7171EE22A40C6181615CAF3F\
+5296964
+$     status = $status
+$     output_expected = "0\0"
+$     gosub check_output
+$     if (output .ne. 1)
+$     then
+$         failure = "SCOtest"
+$     else
+$         delete 'f$parse( tmp_file_name)'
+$     endif
+$ endif
+$!
+$! Test for working 'print' command.
+$!
+$ if (failure .eqs. "")
+$ then
+$!
+$     define /user_mode sys$output 'tmp_file_name'
+$     bc
+print "OK"
+$     status = $status
+$     output_expected = "OK"
+$     gosub check_output
+$     if (output .ne. 1)
+$     then
+$         failure = "printtest"
+$     else
+$         delete 'f$parse( tmp_file_name)'
+$     endif
+$ endif
+$!
+$ if (failure .nes. "")
+$ then
+$     write sys$output -
+       "No working bc found.  Consider installing GNU bc."
+$     exit %X00030000 ! %DCL-W-NORMAL
+$ endif
+$!
+$ exit
+$!
+$!
+$! Complete "bc" command failure.
+$!
+$ bc_fail:
+$ write sys$output -
+   "No ""bc"" program/symbol found.  Consider installing GNU bc."
+$ exit %X00030000 ! %DCL-W-NORMAL
+$!
+$!
+$! Output check subroutine.
+$!
+$ check_output:
+$     eof = 0
+$     line_nr = 0
+$     open /read tmp_file 'tmp_file_name'
+$     c_o_loop:
+$         read /error = error_read tmp_file line
+$         goto ok_read
+$         error_read:
+$         eof = 1
+$         ok_read:
+$         line_expected = f$element( line_nr, "\", output_expected)
+$         line_nr = line_nr+ 1
+$     if ((line_expected .nes. "\") .and. (.not. eof) .and. -
+       (line_expected .eqs. line)) then goto c_o_loop
+$!
+$     if ((line_expected .eqs. "\") .and. eof)
+$     then
+$         output = 1
+$     else
+$         output = 0
+$     endif
+$     close tmp_file
+$ return
+$!
diff --git a/openssl/test/bftest.c b/openssl/test/bftest.c
new file mode 120000
index 0000000..78b1749
--- /dev/null
+++ b/openssl/test/bftest.c
@@ -0,0 +1 @@
+../crypto/bf/bftest.c
\ No newline at end of file
diff --git a/openssl/test/bntest.c b/openssl/test/bntest.c
new file mode 120000
index 0000000..03f54a2
--- /dev/null
+++ b/openssl/test/bntest.c
@@ -0,0 +1 @@
+../crypto/bn/bntest.c
\ No newline at end of file
diff --git a/openssl/test/bntest.com b/openssl/test/bntest.com
new file mode 100644
index 0000000..6545d2e
--- /dev/null
+++ b/openssl/test/bntest.com
@@ -0,0 +1,76 @@
+$!
+$! Analyze bntest output file.
+$!
+$! Exit status = 1 (success) if all tests passed,
+$!               0 (warning) if any test failed.
+$!
+$! 2011-02-20 SMS.  Added code to skip "#" comments in the input file.
+$!
+$! 2010-04-05 SMS.  New.  Based (loosely) on perl code in bntest-vms.sh.
+$!
+$!                  Expect data like:
+$!                        test test_name1
+$!                        0
+$!                        [...]
+$!                        test test_name2
+$!                        0
+$!                        [...]
+$!                        [...]
+$!
+$!                  Some tests have no following "0" lines.
+$!
+$ result_file_name = f$edit( p1, "TRIM")
+$ if (result_file_name .eqs. "")
+$ then
+$     result_file_name = "bntest-vms.out"
+$ endif
+$!
+$ fail = 0
+$ passed = 0
+$ tests = 0
+$!
+$ on control_c then goto tidy
+$ on error then goto tidy
+$!
+$ open /read result_file 'result_file_name'
+$!
+$ read_loop:
+$     read /end = read_loop_end /error = tidy result_file line
+$     t1 = f$element( 0, " ", line)
+$!
+$!    Skip "#" comment lines.
+$     if (f$extract( 0, 1, f$edit( line, "TRIM")) .eqs. "#") then -
+       goto read_loop
+$!
+$     if (t1 .eqs. "test")
+$     then
+$         passed = passed+ 1
+$         tests = tests+ 1
+$         fail = 1
+$         t2 = f$extract( 5, 1000, line)
+$         write sys$output "verify ''t2'"
+$     else
+$         if (t1 .nes. "0")
+$         then
+$             write sys$output "Failed! bc: ''line'"
+$             passed = passed- fail
+$             fail = 0
+$         endif
+$     endif
+$ goto read_loop
+$ read_loop_end:
+$ write sys$output "''passed'/''tests' tests passed"
+$!
+$ tidy:
+$ if f$trnlnm( "result_file", "LNM$PROCESS_TABLE", , "SUPERVISOR", , "CONFINE")
+$ then
+$     close result_file
+$ endif
+$!
+$ if ((tests .gt. 0) .and. (tests .eq. passed))
+$ then
+$    exit 1
+$ else
+$    exit 0
+$ endif
+$!
diff --git a/openssl/test/casttest.c b/openssl/test/casttest.c
new file mode 120000
index 0000000..ac7ede8
--- /dev/null
+++ b/openssl/test/casttest.c
@@ -0,0 +1 @@
+../crypto/cast/casttest.c
\ No newline at end of file
diff --git a/openssl/test/clean_test.com b/openssl/test/clean_test.com
new file mode 100644
index 0000000..7df633f
--- /dev/null
+++ b/openssl/test/clean_test.com
@@ -0,0 +1,35 @@
+$!
+$! Delete various test results files.
+$!
+$ def_orig = f$environment( "default")
+$ proc = f$environment( "procedure")
+$ proc_dev_dir = f$parse( "A.;", proc) - "A.;"
+$!
+$ on control_c then goto tidy
+$ on error then goto tidy
+$!
+$ set default 'proc_dev_dir'
+$!
+$ files := *.cms;*, *.srl;*, *.ss;*, -
+   cms.err;*, cms.out;*, newreq.pem;*, -
+   p.txt-zlib-cipher;*, -
+   smtst.txt;*, testkey.pem;*, testreq.pem;*, -
+   test_*.err;*, test_*.out;*, -
+   .rnd;*
+$!
+$ delim = ","
+$ i = 0
+$ loop:
+$    file = f$edit( f$element( i, delim, files), "trim")
+$    if (file .eqs. delim) then goto loop_end
+$    if (f$search( file) .nes. "") then -
+      delete 'p1' 'file'
+$    i = i+ 1
+$ goto loop
+$ loop_end:
+$!
+$ tidy:
+$ 
+$ if (f$type( def_orig) .nes. "") then -
+   set default 'def_orig'
+$!
diff --git a/openssl/test/cms-examples.pl b/openssl/test/cms-examples.pl
new file mode 100644
index 0000000..2e95b48
--- /dev/null
+++ b/openssl/test/cms-examples.pl
@@ -0,0 +1,409 @@
+# test/cms-examples.pl
+# Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+# project.
+#
+# ====================================================================
+# Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in
+#    the documentation and/or other materials provided with the
+#    distribution.
+#
+# 3. All advertising materials mentioning features or use of this
+#    software must display the following acknowledgment:
+#    "This product includes software developed by the OpenSSL Project
+#    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+#
+# 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+#    endorse or promote products derived from this software without
+#    prior written permission. For written permission, please contact
+#    licensing@OpenSSL.org.
+#
+# 5. Products derived from this software may not be called "OpenSSL"
+#    nor may "OpenSSL" appear in their names without prior written
+#    permission of the OpenSSL Project.
+#
+# 6. Redistributions of any form whatsoever must retain the following
+#    acknowledgment:
+#    "This product includes software developed by the OpenSSL Project
+#    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+#
+# THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+# OF THE POSSIBILITY OF SUCH DAMAGE.
+# ====================================================================
+
+# Perl script to run tests against S/MIME examples in RFC4134
+# Assumes RFC is in current directory and called "rfc4134.txt"
+
+use MIME::Base64;
+
+my $badttest = 0;
+my $verbose  = 1;
+
+my $cmscmd;
+my $exdir  = "./";
+my $exfile = "./rfc4134.txt";
+
+if (-f "../apps/openssl")
+	{
+	$cmscmd = "../util/shlib_wrap.sh ../apps/openssl cms";
+	}
+elsif (-f "..\\out32dll\\openssl.exe")
+	{
+	$cmscmd = "..\\out32dll\\openssl.exe cms";
+	}
+elsif (-f "..\\out32\\openssl.exe")
+	{
+	$cmscmd = "..\\out32\\openssl.exe cms";
+	}
+
+my @test_list = (
+    [ "3.1.bin"  => "dataout" ],
+    [ "3.2.bin"  => "encode, dataout" ],
+    [ "4.1.bin"  => "encode, verifyder, cont, dss" ],
+    [ "4.2.bin"  => "encode, verifyder, cont, rsa" ],
+    [ "4.3.bin"  => "encode, verifyder, cont_extern, dss" ],
+    [ "4.4.bin"  => "encode, verifyder, cont, dss" ],
+    [ "4.5.bin"  => "verifyder, cont, rsa" ],
+    [ "4.6.bin"  => "encode, verifyder, cont, dss" ],
+    [ "4.7.bin"  => "encode, verifyder, cont, dss" ],
+    [ "4.8.eml"  => "verifymime, dss" ],
+    [ "4.9.eml"  => "verifymime, dss" ],
+    [ "4.10.bin" => "encode, verifyder, cont, dss" ],
+    [ "4.11.bin" => "encode, certsout" ],
+    [ "5.1.bin"  => "encode, envelopeder, cont" ],
+    [ "5.2.bin"  => "encode, envelopeder, cont" ],
+    [ "5.3.eml"  => "envelopemime, cont" ],
+    [ "6.0.bin"  => "encode, digest, cont" ],
+    [ "7.1.bin"  => "encode, encrypted, cont" ],
+    [ "7.2.bin"  => "encode, encrypted, cont" ]
+);
+
+# Extract examples from RFC4134 text.
+# Base64 decode all examples, certificates and
+# private keys are converted to PEM format.
+
+my ( $filename, $data );
+
+my @cleanup = ( "cms.out", "cms.err", "tmp.der", "tmp.txt" );
+
+$data = "";
+
+open( IN, $exfile ) || die "Can't Open RFC examples file $exfile";
+
+while (<IN>) {
+    next unless (/^\|/);
+    s/^\|//;
+    next if (/^\*/);
+    if (/^>(.*)$/) {
+        $filename = $1;
+        next;
+    }
+    if (/^</) {
+        $filename = "$exdir/$filename";
+        if ( $filename =~ /\.bin$/ || $filename =~ /\.eml$/ ) {
+            $data = decode_base64($data);
+            open OUT, ">$filename";
+            binmode OUT;
+            print OUT $data;
+            close OUT;
+            push @cleanup, $filename;
+        }
+        elsif ( $filename =~ /\.cer$/ ) {
+            write_pem( $filename, "CERTIFICATE", $data );
+        }
+        elsif ( $filename =~ /\.pri$/ ) {
+            write_pem( $filename, "PRIVATE KEY", $data );
+        }
+        $data     = "";
+        $filename = "";
+    }
+    else {
+        $data .= $_;
+    }
+
+}
+
+my $secretkey =
+  "73:7c:79:1f:25:ea:d0:e0:46:29:25:43:52:f7:dc:62:91:e5:cb:26:91:7a:da:32";
+
+foreach (@test_list) {
+    my ( $file, $tlist ) = @$_;
+    print "Example file $file:\n";
+    if ( $tlist =~ /encode/ ) {
+        run_reencode_test( $exdir, $file );
+    }
+    if ( $tlist =~ /certsout/ ) {
+        run_certsout_test( $exdir, $file );
+    }
+    if ( $tlist =~ /dataout/ ) {
+        run_dataout_test( $exdir, $file );
+    }
+    if ( $tlist =~ /verify/ ) {
+        run_verify_test( $exdir, $tlist, $file );
+    }
+    if ( $tlist =~ /digest/ ) {
+        run_digest_test( $exdir, $tlist, $file );
+    }
+    if ( $tlist =~ /encrypted/ ) {
+        run_encrypted_test( $exdir, $tlist, $file, $secretkey );
+    }
+    if ( $tlist =~ /envelope/ ) {
+        run_envelope_test( $exdir, $tlist, $file );
+    }
+
+}
+
+foreach (@cleanup) {
+    unlink $_;
+}
+
+if ($badtest) {
+    print "\n$badtest TESTS FAILED!!\n";
+}
+else {
+    print "\n***All tests successful***\n";
+}
+
+sub write_pem {
+    my ( $filename, $str, $data ) = @_;
+
+    $filename =~ s/\.[^.]*$/.pem/;
+
+    push @cleanup, $filename;
+
+    open OUT, ">$filename";
+
+    print OUT "-----BEGIN $str-----\n";
+    print OUT $data;
+    print OUT "-----END $str-----\n";
+
+    close OUT;
+}
+
+sub run_reencode_test {
+    my ( $cmsdir, $tfile ) = @_;
+    unlink "tmp.der";
+
+    system( "$cmscmd -cmsout -inform DER -outform DER"
+          . " -in $cmsdir/$tfile -out tmp.der" );
+
+    if ($?) {
+        print "\tReencode command FAILED!!\n";
+        $badtest++;
+    }
+    elsif ( !cmp_files( "$cmsdir/$tfile", "tmp.der" ) ) {
+        print "\tReencode FAILED!!\n";
+        $badtest++;
+    }
+    else {
+        print "\tReencode passed\n" if $verbose;
+    }
+}
+
+sub run_certsout_test {
+    my ( $cmsdir, $tfile ) = @_;
+    unlink "tmp.der";
+    unlink "tmp.pem";
+
+    system( "$cmscmd -cmsout -inform DER -certsout tmp.pem"
+          . " -in $cmsdir/$tfile -out tmp.der" );
+
+    if ($?) {
+        print "\tCertificate output command FAILED!!\n";
+        $badtest++;
+    }
+    else {
+        print "\tCertificate output passed\n" if $verbose;
+    }
+}
+
+sub run_dataout_test {
+    my ( $cmsdir, $tfile ) = @_;
+    unlink "tmp.txt";
+
+    system(
+        "$cmscmd -data_out -inform DER" . " -in $cmsdir/$tfile -out tmp.txt" );
+
+    if ($?) {
+        print "\tDataout command FAILED!!\n";
+        $badtest++;
+    }
+    elsif ( !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) {
+        print "\tDataout compare FAILED!!\n";
+        $badtest++;
+    }
+    else {
+        print "\tDataout passed\n" if $verbose;
+    }
+}
+
+sub run_verify_test {
+    my ( $cmsdir, $tlist, $tfile ) = @_;
+    unlink "tmp.txt";
+
+    $form   = "DER"                     if $tlist =~ /verifyder/;
+    $form   = "SMIME"                   if $tlist =~ /verifymime/;
+    $cafile = "$cmsdir/CarlDSSSelf.pem" if $tlist =~ /dss/;
+    $cafile = "$cmsdir/CarlRSASelf.pem" if $tlist =~ /rsa/;
+
+    $cmd =
+        "$cmscmd -verify -inform $form"
+      . " -CAfile $cafile"
+      . " -in $cmsdir/$tfile -out tmp.txt";
+
+    $cmd .= " -content $cmsdir/ExContent.bin" if $tlist =~ /cont_extern/;
+
+    system("$cmd 2>cms.err 1>cms.out");
+
+    if ($?) {
+        print "\tVerify command FAILED!!\n";
+        $badtest++;
+    }
+    elsif ( $tlist =~ /cont/
+        && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
+    {
+        print "\tVerify content compare FAILED!!\n";
+        $badtest++;
+    }
+    else {
+        print "\tVerify passed\n" if $verbose;
+    }
+}
+
+sub run_envelope_test {
+    my ( $cmsdir, $tlist, $tfile ) = @_;
+    unlink "tmp.txt";
+
+    $form = "DER"   if $tlist =~ /envelopeder/;
+    $form = "SMIME" if $tlist =~ /envelopemime/;
+
+    $cmd =
+        "$cmscmd -decrypt -inform $form"
+      . " -recip $cmsdir/BobRSASignByCarl.pem"
+      . " -inkey $cmsdir/BobPrivRSAEncrypt.pem"
+      . " -in $cmsdir/$tfile -out tmp.txt";
+
+    system("$cmd 2>cms.err 1>cms.out");
+
+    if ($?) {
+        print "\tDecrypt command FAILED!!\n";
+        $badtest++;
+    }
+    elsif ( $tlist =~ /cont/
+        && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
+    {
+        print "\tDecrypt content compare FAILED!!\n";
+        $badtest++;
+    }
+    else {
+        print "\tDecrypt passed\n" if $verbose;
+    }
+}
+
+sub run_digest_test {
+    my ( $cmsdir, $tlist, $tfile ) = @_;
+    unlink "tmp.txt";
+
+    my $cmd =
+      "$cmscmd -digest_verify -inform DER" . " -in $cmsdir/$tfile -out tmp.txt";
+
+    system("$cmd 2>cms.err 1>cms.out");
+
+    if ($?) {
+        print "\tDigest verify command FAILED!!\n";
+        $badtest++;
+    }
+    elsif ( $tlist =~ /cont/
+        && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
+    {
+        print "\tDigest verify content compare FAILED!!\n";
+        $badtest++;
+    }
+    else {
+        print "\tDigest verify passed\n" if $verbose;
+    }
+}
+
+sub run_encrypted_test {
+    my ( $cmsdir, $tlist, $tfile, $key ) = @_;
+    unlink "tmp.txt";
+
+    system( "$cmscmd -EncryptedData_decrypt -inform DER"
+          . " -secretkey $key"
+          . " -in $cmsdir/$tfile -out tmp.txt" );
+
+    if ($?) {
+        print "\tEncrypted Data command FAILED!!\n";
+        $badtest++;
+    }
+    elsif ( $tlist =~ /cont/
+        && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
+    {
+        print "\tEncrypted Data content compare FAILED!!\n";
+        $badtest++;
+    }
+    else {
+        print "\tEncryptedData verify passed\n" if $verbose;
+    }
+}
+
+sub cmp_files {
+    my ( $f1, $f2 ) = @_;
+    my ( $fp1, $fp2 );
+
+    my ( $rd1, $rd2 );
+
+    if ( !open( $fp1, "<$f1" ) ) {
+        print STDERR "Can't Open file $f1\n";
+        return 0;
+    }
+
+    if ( !open( $fp2, "<$f2" ) ) {
+        print STDERR "Can't Open file $f2\n";
+        return 0;
+    }
+
+    binmode $fp1;
+    binmode $fp2;
+
+    my $ret = 0;
+
+    for ( ; ; ) {
+        $n1 = sysread $fp1, $rd1, 4096;
+        $n2 = sysread $fp2, $rd2, 4096;
+        last if ( $n1 != $n2 );
+        last if ( $rd1 ne $rd2 );
+
+        if ( $n1 == 0 ) {
+            $ret = 1;
+            last;
+        }
+
+    }
+
+    close $fp1;
+    close $fp2;
+
+    return $ret;
+
+}
+
diff --git a/openssl/test/cms-test.pl b/openssl/test/cms-test.pl
new file mode 100644
index 0000000..c938bcf
--- /dev/null
+++ b/openssl/test/cms-test.pl
@@ -0,0 +1,457 @@
+# test/cms-test.pl
+# Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+# project.
+#
+# ====================================================================
+# Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in
+#    the documentation and/or other materials provided with the
+#    distribution.
+#
+# 3. All advertising materials mentioning features or use of this
+#    software must display the following acknowledgment:
+#    "This product includes software developed by the OpenSSL Project
+#    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+#
+# 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+#    endorse or promote products derived from this software without
+#    prior written permission. For written permission, please contact
+#    licensing@OpenSSL.org.
+#
+# 5. Products derived from this software may not be called "OpenSSL"
+#    nor may "OpenSSL" appear in their names without prior written
+#    permission of the OpenSSL Project.
+#
+# 6. Redistributions of any form whatsoever must retain the following
+#    acknowledgment:
+#    "This product includes software developed by the OpenSSL Project
+#    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+#
+# THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+# OF THE POSSIBILITY OF SUCH DAMAGE.
+# ====================================================================
+
+# CMS, PKCS7 consistency test script. Run extensive tests on
+# OpenSSL PKCS#7 and CMS implementations.
+
+my $ossl_path;
+my $redir = " 2> cms.err > cms.out";
+# Make VMS work
+if ( $^O eq "VMS" && -f "OSSLX:openssl.exe" ) {
+    $ossl_path = "pipe mcr OSSLX:openssl";
+}
+# Make MSYS work
+elsif ( $^O eq "MSWin32" && -f "../apps/openssl.exe" ) {
+    $ossl_path = "cmd /c ..\\apps\\openssl";
+}
+elsif ( -f "../apps/openssl$ENV{EXE_EXT}" ) {
+    $ossl_path = "../util/shlib_wrap.sh ../apps/openssl";
+}
+elsif ( -f "..\\out32dll\\openssl.exe" ) {
+    $ossl_path = "..\\out32dll\\openssl.exe";
+}
+elsif ( -f "..\\out32\\openssl.exe" ) {
+    $ossl_path = "..\\out32\\openssl.exe";
+}
+else {
+    die "Can't find OpenSSL executable";
+}
+
+my $pk7cmd   = "$ossl_path smime ";
+my $cmscmd   = "$ossl_path cms ";
+my $smdir    = "smime-certs";
+my $halt_err = 1;
+
+my $badcmd = 0;
+my $ossl8 = `$ossl_path version -v` =~ /0\.9\.8/;
+
+my @smime_pkcs7_tests = (
+
+    [
+        "signed content DER format, RSA key",
+        "-sign -in smcont.txt -outform \"DER\" -nodetach"
+          . " -certfile $smdir/smroot.pem"
+          . " -signer $smdir/smrsa1.pem -out test.cms",
+        "-verify -in test.cms -inform \"DER\" "
+          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+    ],
+
+    [
+        "signed detached content DER format, RSA key",
+        "-sign -in smcont.txt -outform \"DER\""
+          . " -signer $smdir/smrsa1.pem -out test.cms",
+        "-verify -in test.cms -inform \"DER\" "
+          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt -content smcont.txt"
+    ],
+
+    [
+        "signed content test streaming BER format, RSA",
+        "-sign -in smcont.txt -outform \"DER\" -nodetach"
+          . " -stream -signer $smdir/smrsa1.pem -out test.cms",
+        "-verify -in test.cms -inform \"DER\" "
+          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+    ],
+
+    [
+        "signed content DER format, DSA key",
+        "-sign -in smcont.txt -outform \"DER\" -nodetach"
+          . " -signer $smdir/smdsa1.pem -out test.cms",
+        "-verify -in test.cms -inform \"DER\" "
+          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+    ],
+
+    [
+        "signed detached content DER format, DSA key",
+        "-sign -in smcont.txt -outform \"DER\""
+          . " -signer $smdir/smdsa1.pem -out test.cms",
+        "-verify -in test.cms -inform \"DER\" "
+          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt -content smcont.txt"
+    ],
+
+    [
+        "signed detached content DER format, add RSA signer",
+        "-resign -inform \"DER\" -in test.cms -outform \"DER\""
+          . " -signer $smdir/smrsa1.pem -out test2.cms",
+        "-verify -in test2.cms -inform \"DER\" "
+          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt -content smcont.txt"
+    ],
+
+    [
+        "signed content test streaming BER format, DSA key",
+        "-sign -in smcont.txt -outform \"DER\" -nodetach"
+          . " -stream -signer $smdir/smdsa1.pem -out test.cms",
+        "-verify -in test.cms -inform \"DER\" "
+          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+    ],
+
+    [
+        "signed content test streaming BER format, 2 DSA and 2 RSA keys",
+        "-sign -in smcont.txt -outform \"DER\" -nodetach"
+          . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
+          . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
+          . " -stream -out test.cms",
+        "-verify -in test.cms -inform \"DER\" "
+          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+    ],
+
+    [
+"signed content test streaming BER format, 2 DSA and 2 RSA keys, no attributes",
+        "-sign -in smcont.txt -outform \"DER\" -noattr -nodetach"
+          . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
+          . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
+          . " -stream -out test.cms",
+        "-verify -in test.cms -inform \"DER\" "
+          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+    ],
+
+    [
+        "signed content test streaming S/MIME format, 2 DSA and 2 RSA keys",
+        "-sign -in smcont.txt -nodetach"
+          . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
+          . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
+          . " -stream -out test.cms",
+        "-verify -in test.cms " . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+    ],
+
+    [
+"signed content test streaming multipart S/MIME format, 2 DSA and 2 RSA keys",
+        "-sign -in smcont.txt"
+          . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
+          . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
+          . " -stream -out test.cms",
+        "-verify -in test.cms " . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+    ],
+
+    [
+        "enveloped content test streaming S/MIME format, 3 recipients",
+        "-encrypt -in smcont.txt"
+          . " -stream -out test.cms"
+          . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
+        "-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt"
+    ],
+
+    [
+"enveloped content test streaming S/MIME format, 3 recipients, 3rd used",
+        "-encrypt -in smcont.txt"
+          . " -stream -out test.cms"
+          . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
+        "-decrypt -recip $smdir/smrsa3.pem -in test.cms -out smtst.txt"
+    ],
+
+    [
+"enveloped content test streaming S/MIME format, 3 recipients, key only used",
+        "-encrypt -in smcont.txt"
+          . " -stream -out test.cms"
+          . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
+        "-decrypt -inkey $smdir/smrsa3.pem -in test.cms -out smtst.txt"
+    ],
+
+    [
+"enveloped content test streaming S/MIME format, AES-256 cipher, 3 recipients",
+        "-encrypt -in smcont.txt"
+          . " -aes256 -stream -out test.cms"
+          . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
+        "-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt"
+    ],
+
+);
+
+my @smime_cms_tests = (
+
+    [
+        "signed content test streaming BER format, 2 DSA and 2 RSA keys, keyid",
+        "-sign -in smcont.txt -outform \"DER\" -nodetach -keyid"
+          . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
+          . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
+          . " -stream -out test.cms",
+        "-verify -in test.cms -inform \"DER\" "
+          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+    ],
+
+    [
+        "signed content test streaming PEM format, 2 DSA and 2 RSA keys",
+        "-sign -in smcont.txt -outform PEM -nodetach"
+          . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
+          . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
+          . " -stream -out test.cms",
+        "-verify -in test.cms -inform PEM "
+          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+    ],
+
+    [
+        "signed content MIME format, RSA key, signed receipt request",
+        "-sign -in smcont.txt -signer $smdir/smrsa1.pem -nodetach"
+          . " -receipt_request_to test\@openssl.org -receipt_request_all"
+          . " -out test.cms",
+        "-verify -in test.cms "
+          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
+    ],
+
+    [
+        "signed receipt MIME format, RSA key",
+        "-sign_receipt -in test.cms"
+          . " -signer $smdir/smrsa2.pem"
+          . " -out test2.cms",
+        "-verify_receipt test2.cms -in test.cms"
+          . " \"-CAfile\" $smdir/smroot.pem"
+    ],
+
+    [
+        "enveloped content test streaming S/MIME format, 3 recipients, keyid",
+        "-encrypt -in smcont.txt"
+          . " -stream -out test.cms -keyid"
+          . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
+        "-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt"
+    ],
+
+    [
+        "enveloped content test streaming PEM format, KEK",
+        "-encrypt -in smcont.txt -outform PEM -aes128"
+          . " -stream -out test.cms "
+          . " -secretkey 000102030405060708090A0B0C0D0E0F "
+          . " -secretkeyid C0FEE0",
+        "-decrypt -in test.cms -out smtst.txt -inform PEM"
+          . " -secretkey 000102030405060708090A0B0C0D0E0F "
+          . " -secretkeyid C0FEE0"
+    ],
+
+    [
+        "enveloped content test streaming PEM format, KEK, key only",
+        "-encrypt -in smcont.txt -outform PEM -aes128"
+          . " -stream -out test.cms "
+          . " -secretkey 000102030405060708090A0B0C0D0E0F "
+          . " -secretkeyid C0FEE0",
+        "-decrypt -in test.cms -out smtst.txt -inform PEM"
+          . " -secretkey 000102030405060708090A0B0C0D0E0F "
+    ],
+
+    [
+        "data content test streaming PEM format",
+        "-data_create -in smcont.txt -outform PEM -nodetach"
+          . " -stream -out test.cms",
+        "-data_out -in test.cms -inform PEM -out smtst.txt"
+    ],
+
+    [
+        "encrypted content test streaming PEM format, 128 bit RC2 key",
+        "\"-EncryptedData_encrypt\" -in smcont.txt -outform PEM"
+          . " -rc2 -secretkey 000102030405060708090A0B0C0D0E0F"
+          . " -stream -out test.cms",
+        "\"-EncryptedData_decrypt\" -in test.cms -inform PEM "
+          . " -secretkey 000102030405060708090A0B0C0D0E0F -out smtst.txt"
+    ],
+
+    [
+        "encrypted content test streaming PEM format, 40 bit RC2 key",
+        "\"-EncryptedData_encrypt\" -in smcont.txt -outform PEM"
+          . " -rc2 -secretkey 0001020304"
+          . " -stream -out test.cms",
+        "\"-EncryptedData_decrypt\" -in test.cms -inform PEM "
+          . " -secretkey 0001020304 -out smtst.txt"
+    ],
+
+    [
+        "encrypted content test streaming PEM format, triple DES key",
+        "\"-EncryptedData_encrypt\" -in smcont.txt -outform PEM"
+          . " -des3 -secretkey 000102030405060708090A0B0C0D0E0F1011121314151617"
+          . " -stream -out test.cms",
+        "\"-EncryptedData_decrypt\" -in test.cms -inform PEM "
+          . " -secretkey 000102030405060708090A0B0C0D0E0F1011121314151617"
+          . " -out smtst.txt"
+    ],
+
+    [
+        "encrypted content test streaming PEM format, 128 bit AES key",
+        "\"-EncryptedData_encrypt\" -in smcont.txt -outform PEM"
+          . " -aes128 -secretkey 000102030405060708090A0B0C0D0E0F"
+          . " -stream -out test.cms",
+        "\"-EncryptedData_decrypt\" -in test.cms -inform PEM "
+          . " -secretkey 000102030405060708090A0B0C0D0E0F -out smtst.txt"
+    ],
+
+);
+
+my @smime_cms_comp_tests = (
+
+    [
+        "compressed content test streaming PEM format",
+        "-compress -in smcont.txt -outform PEM -nodetach"
+          . " -stream -out test.cms",
+        "-uncompress -in test.cms -inform PEM -out smtst.txt"
+    ]
+
+);
+
+print "CMS => PKCS#7 compatibility tests\n";
+
+run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $pk7cmd );
+
+print "CMS <= PKCS#7 compatibility tests\n";
+
+run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $pk7cmd, $cmscmd );
+
+print "CMS <=> CMS consistency tests\n";
+
+run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $cmscmd );
+run_smime_tests( \$badcmd, \@smime_cms_tests,   $cmscmd, $cmscmd );
+
+if ( `$ossl_path version -f` =~ /ZLIB/ ) {
+    run_smime_tests( \$badcmd, \@smime_cms_comp_tests, $cmscmd, $cmscmd );
+}
+else {
+    print "Zlib not supported: compression tests skipped\n";
+}
+
+print "Running modified tests for OpenSSL 0.9.8 cms backport\n" if($ossl8);
+
+if ($badcmd) {
+    print "$badcmd TESTS FAILED!!\n";
+}
+else {
+    print "ALL TESTS SUCCESSFUL.\n";
+}
+
+unlink "test.cms";
+unlink "test2.cms";
+unlink "smtst.txt";
+unlink "cms.out";
+unlink "cms.err";
+
+sub run_smime_tests {
+    my ( $rv, $aref, $scmd, $vcmd ) = @_;
+
+    foreach $smtst (@$aref) {
+        my ( $tnam, $rscmd, $rvcmd ) = @$smtst;
+	if ($ossl8)
+		{
+		# Skip smime resign: 0.9.8 smime doesn't support -resign	
+		next if ($scmd =~ /smime/ && $rscmd =~ /-resign/);
+		# Disable streaming: option not supported in 0.9.8
+		$tnam =~ s/streaming//;	
+		$rscmd =~ s/-stream//;	
+		$rvcmd =~ s/-stream//;
+		}
+        system("$scmd$rscmd$redir");
+        if ($?) {
+            print "$tnam: generation error\n";
+            $$rv++;
+            exit 1 if $halt_err;
+            next;
+        }
+        system("$vcmd$rvcmd$redir");
+        if ($?) {
+            print "$tnam: verify error\n";
+            $$rv++;
+            exit 1 if $halt_err;
+            next;
+        }
+	if (!cmp_files("smtst.txt", "smcont.txt")) {
+            print "$tnam: content verify error\n";
+            $$rv++;
+            exit 1 if $halt_err;
+            next;
+	}
+        print "$tnam: OK\n";
+    }
+}
+
+sub cmp_files {
+    my ( $f1, $f2 ) = @_;
+    my ( $fp1, $fp2 );
+
+    my ( $rd1, $rd2 );
+
+    if ( !open( $fp1, "<$f1" ) ) {
+        print STDERR "Can't Open file $f1\n";
+        return 0;
+    }
+
+    if ( !open( $fp2, "<$f2" ) ) {
+        print STDERR "Can't Open file $f2\n";
+        return 0;
+    }
+
+    binmode $fp1;
+    binmode $fp2;
+
+    my $ret = 0;
+
+    for ( ; ; ) {
+        $n1 = sysread $fp1, $rd1, 4096;
+        $n2 = sysread $fp2, $rd2, 4096;
+        last if ( $n1 != $n2 );
+        last if ( $rd1 ne $rd2 );
+
+        if ( $n1 == 0 ) {
+            $ret = 1;
+            last;
+        }
+
+    }
+
+    close $fp1;
+    close $fp2;
+
+    return $ret;
+
+}
+
diff --git a/openssl/test/destest.c b/openssl/test/destest.c
new file mode 120000
index 0000000..5988c73
--- /dev/null
+++ b/openssl/test/destest.c
@@ -0,0 +1 @@
+../crypto/des/destest.c
\ No newline at end of file
diff --git a/openssl/test/dhtest.c b/openssl/test/dhtest.c
new file mode 120000
index 0000000..9a67f91
--- /dev/null
+++ b/openssl/test/dhtest.c
@@ -0,0 +1 @@
+../crypto/dh/dhtest.c
\ No newline at end of file
diff --git a/openssl/test/dsatest.c b/openssl/test/dsatest.c
new file mode 120000
index 0000000..16a1b5a
--- /dev/null
+++ b/openssl/test/dsatest.c
@@ -0,0 +1 @@
+../crypto/dsa/dsatest.c
\ No newline at end of file
diff --git a/openssl/test/dummytest.c b/openssl/test/dummytest.c
new file mode 100644
index 0000000..5b4467e
--- /dev/null
+++ b/openssl/test/dummytest.c
@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <openssl/e_os2.h>
+#include <openssl/buffer.h>
+#include <openssl/crypto.h>
+
+int main(int argc, char *argv[])
+	{
+	char *p, *q = 0, *program;
+
+	p = strrchr(argv[0], '/');
+	if (!p) p = strrchr(argv[0], '\\');
+#ifdef OPENSSL_SYS_VMS
+	if (!p) p = strrchr(argv[0], ']');
+	if (p) q = strrchr(p, '>');
+	if (q) p = q;
+	if (!p) p = strrchr(argv[0], ':');
+	q = 0;
+#endif
+	if (p) p++;
+	if (!p) p = argv[0];
+	if (p) q = strchr(p, '.');
+	if (p && !q) q = p + strlen(p);
+
+	if (!p)
+		program = BUF_strdup("(unknown)");
+	else
+		{
+		program = OPENSSL_malloc((q - p) + 1);
+		strncpy(program, p, q - p);
+		program[q - p] = '\0';
+		}
+
+	for(p = program; *p; p++)
+		if (islower((unsigned char)(*p)))
+			*p = toupper((unsigned char)(*p));
+
+	q = strstr(program, "TEST");
+	if (q > p && q[-1] == '_') q--;
+	*q = '\0';
+
+	printf("No %s support\n", program);
+
+	OPENSSL_free(program);
+	return(0);
+	}
diff --git a/openssl/test/ecdhtest.c b/openssl/test/ecdhtest.c
new file mode 120000
index 0000000..206d986
--- /dev/null
+++ b/openssl/test/ecdhtest.c
@@ -0,0 +1 @@
+../crypto/ecdh/ecdhtest.c
\ No newline at end of file
diff --git a/openssl/test/ecdsatest.c b/openssl/test/ecdsatest.c
new file mode 120000
index 0000000..441082b
--- /dev/null
+++ b/openssl/test/ecdsatest.c
@@ -0,0 +1 @@
+../crypto/ecdsa/ecdsatest.c
\ No newline at end of file
diff --git a/openssl/test/ectest.c b/openssl/test/ectest.c
new file mode 120000
index 0000000..df1831f
--- /dev/null
+++ b/openssl/test/ectest.c
@@ -0,0 +1 @@
+../crypto/ec/ectest.c
\ No newline at end of file
diff --git a/openssl/test/enginetest.c b/openssl/test/enginetest.c
new file mode 120000
index 0000000..5c74a6f
--- /dev/null
+++ b/openssl/test/enginetest.c
@@ -0,0 +1 @@
+../crypto/engine/enginetest.c
\ No newline at end of file
diff --git a/openssl/test/evp_test.c b/openssl/test/evp_test.c
new file mode 120000
index 0000000..0741628
--- /dev/null
+++ b/openssl/test/evp_test.c
@@ -0,0 +1 @@
+../crypto/evp/evp_test.c
\ No newline at end of file
diff --git a/openssl/test/evptests.txt b/openssl/test/evptests.txt
new file mode 100644
index 0000000..beb1214
--- /dev/null
+++ b/openssl/test/evptests.txt
@@ -0,0 +1,321 @@
+#cipher:key:iv:plaintext:ciphertext:0/1(decrypt/encrypt)
+#digest:::input:output
+
+# SHA(1) tests (from shatest.c)
+SHA1:::616263:a9993e364706816aba3e25717850c26c9cd0d89d
+
+# MD5 tests (from md5test.c)
+MD5::::d41d8cd98f00b204e9800998ecf8427e
+MD5:::61:0cc175b9c0f1b6a831c399e269772661
+MD5:::616263:900150983cd24fb0d6963f7d28e17f72
+MD5:::6d65737361676520646967657374:f96b697d7cb7938d525a2f31aaf161d0
+MD5:::6162636465666768696a6b6c6d6e6f707172737475767778797a:c3fcd3d76192e4007dfb496cca67e13b
+MD5:::4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a30313233343536373839:d174ab98d277d9f5a5611c2c9f419d9f
+MD5:::3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930:57edf4a22be3c955ac49da2e2107b67a
+
+# AES 128 ECB tests (from FIPS-197 test vectors, encrypt)
+
+AES-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:69C4E0D86A7B0430D8CDB78070B4C55A:1
+
+# AES 192 ECB tests (from FIPS-197 test vectors, encrypt)
+
+AES-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:DDA97CA4864CDFE06EAF70A0EC0D7191:1
+
+# AES 256 ECB tests (from FIPS-197 test vectors, encrypt)
+
+AES-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:8EA2B7CA516745BFEAFC49904B496089:1
+
+# AES 128 ECB tests (from NIST test vectors, encrypt)
+
+#AES-128-ECB:00000000000000000000000000000000::00000000000000000000000000000000:C34C052CC0DA8D73451AFE5F03BE297F:1
+
+# AES 128 ECB tests (from NIST test vectors, decrypt)
+
+#AES-128-ECB:00000000000000000000000000000000::44416AC2D1F53C583303917E6BE9EBE0:00000000000000000000000000000000:0
+
+# AES 192 ECB tests (from NIST test vectors, decrypt)
+
+#AES-192-ECB:000000000000000000000000000000000000000000000000::48E31E9E256718F29229319C19F15BA4:00000000000000000000000000000000:0
+
+# AES 256 ECB tests (from NIST test vectors, decrypt)
+
+#AES-256-ECB:0000000000000000000000000000000000000000000000000000000000000000::058CCFFDBBCB382D1F6F56585D8A4ADE:00000000000000000000000000000000:0
+
+# AES 128 CBC tests (from NIST test vectors, encrypt)
+
+#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:8A05FC5E095AF4848A08D328D3688E3D:1
+
+# AES 192 CBC tests (from NIST test vectors, encrypt)
+
+#AES-192-CBC:000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:7BD966D53AD8C1BB85D2ADFAE87BB104:1
+
+# AES 256 CBC tests (from NIST test vectors, encrypt)
+
+#AES-256-CBC:0000000000000000000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:FE3C53653E2F45B56FCD88B2CC898FF0:1
+
+# AES 128 CBC tests (from NIST test vectors, decrypt)
+
+#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:FACA37E0B0C85373DF706E73F7C9AF86:00000000000000000000000000000000:0
+
+# AES tests from NIST document SP800-38A
+# For all ECB encrypts and decrypts, the transformed sequence is
+#   AES-bits-ECB:key::plaintext:ciphertext:encdec
+# ECB-AES128.Encrypt and ECB-AES128.Decrypt
+AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:3AD77BB40D7A3660A89ECAF32466EF97
+AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:F5D3D58503B9699DE785895A96FDBAAF
+AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:43B1CD7F598ECE23881B00E3ED030688
+AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:7B0C785E27E8AD3F8223207104725DD4
+# ECB-AES192.Encrypt and ECB-AES192.Decrypt 
+AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:BD334F1D6E45F25FF712A214571FA5CC
+AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:974104846D0AD3AD7734ECB3ECEE4EEF
+AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:EF7AFD2270E2E60ADCE0BA2FACE6444E
+AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:9A4B41BA738D6C72FB16691603C18E0E
+# ECB-AES256.Encrypt and ECB-AES256.Decrypt 
+AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:F3EED1BDB5D2A03C064B5A7E3DB181F8
+AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:591CCB10D410ED26DC5BA74A31362870
+AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:B6ED21B99CA6F4F9F153E7B1BEAFED1D
+AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:23304B7A39F9F3FF067D8D8F9E24ECC7
+# For all CBC encrypts and decrypts, the transformed sequence is
+#   AES-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec
+# CBC-AES128.Encrypt and CBC-AES128.Decrypt 
+AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:7649ABAC8119B246CEE98E9B12E9197D
+AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:7649ABAC8119B246CEE98E9B12E9197D:AE2D8A571E03AC9C9EB76FAC45AF8E51:5086CB9B507219EE95DB113A917678B2
+AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:5086CB9B507219EE95DB113A917678B2:30C81C46A35CE411E5FBC1191A0A52EF:73BED6B8E3C1743B7116E69E22229516
+AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:73BED6B8E3C1743B7116E69E22229516:F69F2445DF4F9B17AD2B417BE66C3710:3FF1CAA1681FAC09120ECA307586E1A7
+# CBC-AES192.Encrypt and CBC-AES192.Decrypt 
+AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:4F021DB243BC633D7178183A9FA071E8
+AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:4F021DB243BC633D7178183A9FA071E8:AE2D8A571E03AC9C9EB76FAC45AF8E51:B4D9ADA9AD7DEDF4E5E738763F69145A
+AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:B4D9ADA9AD7DEDF4E5E738763F69145A:30C81C46A35CE411E5FBC1191A0A52EF:571B242012FB7AE07FA9BAAC3DF102E0
+AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:571B242012FB7AE07FA9BAAC3DF102E0:F69F2445DF4F9B17AD2B417BE66C3710:08B0E27988598881D920A9E64F5615CD
+# CBC-AES256.Encrypt and CBC-AES256.Decrypt 
+AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:F58C4C04D6E5F1BA779EABFB5F7BFBD6
+AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:F58C4C04D6E5F1BA779EABFB5F7BFBD6:AE2D8A571E03AC9C9EB76FAC45AF8E51:9CFC4E967EDB808D679F777BC6702C7D
+AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:9CFC4E967EDB808D679F777BC6702C7D:30C81C46A35CE411E5FBC1191A0A52EF:39F23369A9D9BACFA530E26304231461
+AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39F23369A9D9BACFA530E26304231461:F69F2445DF4F9B17AD2B417BE66C3710:B2EB05E2C39BE9FCDA6C19078C6A9D1B
+# We don't support CFB{1,8}-AESxxx.{En,De}crypt
+# For all CFB128 encrypts and decrypts, the transformed sequence is
+#   AES-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec
+# CFB128-AES128.Encrypt 
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:1
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:1
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:1
+# CFB128-AES128.Decrypt 
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:0
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:0
+AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:0
+# CFB128-AES192.Encrypt
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:1
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:1
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:1
+# CFB128-AES192.Decrypt
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:0
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:0
+AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:0
+# CFB128-AES256.Encrypt 
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:1
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:1
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:1
+# CFB128-AES256.Decrypt 
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:0
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:0
+AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:0
+# For all OFB encrypts and decrypts, the transformed sequence is
+#   AES-bits-CFB:key:IV/output':plaintext:ciphertext:encdec
+# OFB-AES128.Encrypt 
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1 
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:1 
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:1 
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:1 
+# OFB-AES128.Decrypt 
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:0
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:0
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:0
+# OFB-AES192.Encrypt 
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1 
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:1 
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:1 
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:1 
+# OFB-AES192.Decrypt 
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0 
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:0 
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:0 
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:0 
+# OFB-AES256.Encrypt 
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:1
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:1
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:1
+# OFB-AES256.Decrypt 
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:0
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:0
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:0
+
+# DES ECB tests (from destest)
+
+DES-ECB:0000000000000000::0000000000000000:8CA64DE9C1B123A7
+DES-ECB:FFFFFFFFFFFFFFFF::FFFFFFFFFFFFFFFF:7359B2163E4EDC58
+DES-ECB:3000000000000000::1000000000000001:958E6E627A05557B
+DES-ECB:1111111111111111::1111111111111111:F40379AB9E0EC533
+DES-ECB:0123456789ABCDEF::1111111111111111:17668DFC7292532D
+DES-ECB:1111111111111111::0123456789ABCDEF:8A5AE1F81AB8F2DD
+DES-ECB:FEDCBA9876543210::0123456789ABCDEF:ED39D950FA74BCC4
+
+# DESX-CBC tests (from destest)
+DESX-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:846B2914851E9A2954732F8AA0A611C115CDC2D7951B1053A63C5E03B21AA3C4
+
+# DES EDE3 CBC tests (from destest)
+DES-EDE3-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675
+
+# RC4 tests (from rc4test)
+RC4:0123456789abcdef0123456789abcdef::0123456789abcdef:75b7878099e0c596
+RC4:0123456789abcdef0123456789abcdef::0000000000000000:7494c2e7104b0879
+RC4:00000000000000000000000000000000::0000000000000000:de188941a3375d3a
+RC4:ef012345ef012345ef012345ef012345::0000000000000000000000000000000000000000:d6a141a7ec3c38dfbd615a1162e1c7ba36b67858
+RC4:0123456789abcdef0123456789abcdef::123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345678:66a0949f8af7d6891f7f832ba833c00c892ebe30143ce28740011ecf
+RC4:ef012345ef012345ef012345ef012345::00000000000000000000:d6a141a7ec3c38dfbd61
+
+
+# Camellia tests from RFC3713
+# For all ECB encrypts and decrypts, the transformed sequence is
+#   CAMELLIA-bits-ECB:key::plaintext:ciphertext:encdec
+CAMELLIA-128-ECB:0123456789abcdeffedcba9876543210::0123456789abcdeffedcba9876543210:67673138549669730857065648eabe43
+CAMELLIA-192-ECB:0123456789abcdeffedcba98765432100011223344556677::0123456789abcdeffedcba9876543210:b4993401b3e996f84ee5cee7d79b09b9
+CAMELLIA-256-ECB:0123456789abcdeffedcba987654321000112233445566778899aabbccddeeff::0123456789abcdeffedcba9876543210:9acc237dff16d76c20ef7c919e3a7509
+
+# ECB-CAMELLIA128.Encrypt
+CAMELLIA-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:77CF412067AF8270613529149919546F:1
+CAMELLIA-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:B22F3C36B72D31329EEE8ADDC2906C68:1
+CAMELLIA-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:2EDF1F3418D53B88841FC8985FB1ECF2:1
+
+# ECB-CAMELLIA128.Encrypt and ECB-CAMELLIA128.Decrypt 
+CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:432FC5DCD628115B7C388D770B270C96
+CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:0BE1F14023782A22E8384C5ABB7FAB2B
+CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:A0A1ABCD1893AB6FE0FE5B65DF5F8636
+CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:E61925E0D5DFAA9BB29F815B3076E51A
+
+# ECB-CAMELLIA192.Encrypt and ECB-CAMELLIA192.Decrypt 
+CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:CCCC6C4E138B45848514D48D0D3439D3
+CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:5713C62C14B2EC0F8393B6AFD6F5785A
+CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:B40ED2B60EB54D09D030CF511FEEF366
+CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:909DBD95799096748CB27357E73E1D26
+
+# ECB-CAMELLIA256.Encrypt and ECB-CAMELLIA256.Decrypt 
+CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:BEFD219B112FA00098919CD101C9CCFA
+CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:C91D3A8F1AEA08A9386CF4B66C0169EA
+CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:A623D711DC5F25A51BB8A80D56397D28
+CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:7960109FB6DC42947FCFE59EA3C5EB6B
+
+# For all CBC encrypts and decrypts, the transformed sequence is
+#   CAMELLIA-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec
+# CBC-CAMELLIA128.Encrypt and CBC-CAMELLIA128.Decrypt 
+CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:1607CF494B36BBF00DAEB0B503C831AB
+CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:1607CF494B36BBF00DAEB0B503C831AB:AE2D8A571E03AC9C9EB76FAC45AF8E51:A2F2CF671629EF7840C5A5DFB5074887
+CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:A2F2CF671629EF7840C5A5DFB5074887:30C81C46A35CE411E5FBC1191A0A52EF:0F06165008CF8B8B5A63586362543E54
+CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:36A84CDAFD5F9A85ADA0F0A993D6D577:F69F2445DF4F9B17AD2B417BE66C3710:74C64268CDB8B8FAF5B34E8AF3732980
+
+# CBC-CAMELLIA192.Encrypt and CBC-CAMELLIA192.Decrypt 
+CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:2A4830AB5AC4A1A2405955FD2195CF93
+CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2A4830AB5AC4A1A2405955FD2195CF93:AE2D8A571E03AC9C9EB76FAC45AF8E51:5D5A869BD14CE54264F892A6DD2EC3D5
+CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:5D5A869BD14CE54264F892A6DD2EC3D5:30C81C46A35CE411E5FBC1191A0A52EF:37D359C3349836D884E310ADDF68C449
+CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:37D359C3349836D884E310ADDF68C449:F69F2445DF4F9B17AD2B417BE66C3710:01FAAA930B4AB9916E9668E1428C6B08
+
+# CBC-CAMELLIA256.Encrypt and CBC-CAMELLIA256.Decrypt 
+CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:E6CFA35FC02B134A4D2C0B6737AC3EDA
+CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E6CFA35FC02B134A4D2C0B6737AC3EDA:AE2D8A571E03AC9C9EB76FAC45AF8E51:36CBEB73BD504B4070B1B7DE2B21EB50
+CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:36CBEB73BD504B4070B1B7DE2B21EB50:30C81C46A35CE411E5FBC1191A0A52EF:E31A6055297D96CA3330CDF1B1860A83
+CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E31A6055297D96CA3330CDF1B1860A83:F69F2445DF4F9B17AD2B417BE66C3710:5D563F6D1CCCF236051C0C5C1C58F28F
+
+# We don't support CFB{1,8}-CAMELLIAxxx.{En,De}crypt
+# For all CFB128 encrypts and decrypts, the transformed sequence is
+#   CAMELLIA-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec
+# CFB128-CAMELLIA128.Encrypt 
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:1
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:1
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:1
+
+# CFB128-CAMELLIA128.Decrypt 
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:0
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:0
+CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:0
+
+# CFB128-CAMELLIA192.Encrypt
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:1
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:1
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:1
+
+# CFB128-CAMELLIA192.Decrypt
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:0
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:0
+CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:0
+
+# CFB128-CAMELLIA256.Encrypt 
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:1
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:1
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:1
+
+# CFB128-CAMELLIA256.Decrypt 
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:0
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:0
+CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:0
+
+# For all OFB encrypts and decrypts, the transformed sequence is
+#   CAMELLIA-bits-OFB:key:IV/output':plaintext:ciphertext:encdec
+# OFB-CAMELLIA128.Encrypt 
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:1
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:1
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:1
+
+# OFB-CAMELLIA128.Decrypt 
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:0
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:0
+CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:0
+
+# OFB-CAMELLIA192.Encrypt 
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:1
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:1
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:1
+
+# OFB-CAMELLIA192.Decrypt 
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:0
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:0
+CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:0
+
+# OFB-CAMELLIA256.Encrypt 
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:1
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:1
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:1
+
+# OFB-CAMELLIA256.Decrypt 
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:0
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:0
+CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:0
+
+# SEED test vectors from RFC4269
+SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:0
+SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:0
+SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:0
+SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:0
+SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:1
+SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:1
+SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:1
+SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:1
diff --git a/openssl/test/exptest.c b/openssl/test/exptest.c
new file mode 120000
index 0000000..50ccf71
--- /dev/null
+++ b/openssl/test/exptest.c
@@ -0,0 +1 @@
+../crypto/bn/exptest.c
\ No newline at end of file
diff --git a/openssl/test/fips_aesavs.c b/openssl/test/fips_aesavs.c
new file mode 120000
index 0000000..7d9da0e
--- /dev/null
+++ b/openssl/test/fips_aesavs.c
@@ -0,0 +1 @@
+../fips/aes/fips_aesavs.c
\ No newline at end of file
diff --git a/openssl/test/fips_desmovs.c b/openssl/test/fips_desmovs.c
new file mode 120000
index 0000000..dd74966
--- /dev/null
+++ b/openssl/test/fips_desmovs.c
@@ -0,0 +1 @@
+../fips/des/fips_desmovs.c
\ No newline at end of file
diff --git a/openssl/test/fips_dsatest.c b/openssl/test/fips_dsatest.c
new file mode 120000
index 0000000..e43b79b
--- /dev/null
+++ b/openssl/test/fips_dsatest.c
@@ -0,0 +1 @@
+../fips/dsa/fips_dsatest.c
\ No newline at end of file
diff --git a/openssl/test/fips_dssvs.c b/openssl/test/fips_dssvs.c
new file mode 120000
index 0000000..93e05e6
--- /dev/null
+++ b/openssl/test/fips_dssvs.c
@@ -0,0 +1 @@
+../fips/dsa/fips_dssvs.c
\ No newline at end of file
diff --git a/openssl/test/fips_hmactest.c b/openssl/test/fips_hmactest.c
new file mode 120000
index 0000000..b674d16
--- /dev/null
+++ b/openssl/test/fips_hmactest.c
@@ -0,0 +1 @@
+../fips/hmac/fips_hmactest.c
\ No newline at end of file
diff --git a/openssl/test/fips_randtest.c b/openssl/test/fips_randtest.c
new file mode 120000
index 0000000..8b8f486
--- /dev/null
+++ b/openssl/test/fips_randtest.c
@@ -0,0 +1 @@
+../fips/rand/fips_randtest.c
\ No newline at end of file
diff --git a/openssl/test/fips_rngvs.c b/openssl/test/fips_rngvs.c
new file mode 120000
index 0000000..0d6c9be
--- /dev/null
+++ b/openssl/test/fips_rngvs.c
@@ -0,0 +1 @@
+../fips/rand/fips_rngvs.c
\ No newline at end of file
diff --git a/openssl/test/fips_rsagtest.c b/openssl/test/fips_rsagtest.c
new file mode 120000
index 0000000..3ed6b51
--- /dev/null
+++ b/openssl/test/fips_rsagtest.c
@@ -0,0 +1 @@
+../fips/rsa/fips_rsagtest.c
\ No newline at end of file
diff --git a/openssl/test/fips_rsastest.c b/openssl/test/fips_rsastest.c
new file mode 120000
index 0000000..2a5f8b0
--- /dev/null
+++ b/openssl/test/fips_rsastest.c
@@ -0,0 +1 @@
+../fips/rsa/fips_rsastest.c
\ No newline at end of file
diff --git a/openssl/test/fips_rsavtest.c b/openssl/test/fips_rsavtest.c
new file mode 120000
index 0000000..f45aa58
--- /dev/null
+++ b/openssl/test/fips_rsavtest.c
@@ -0,0 +1 @@
+../fips/rsa/fips_rsavtest.c
\ No newline at end of file
diff --git a/openssl/test/fips_shatest.c b/openssl/test/fips_shatest.c
new file mode 120000
index 0000000..67c47ca
--- /dev/null
+++ b/openssl/test/fips_shatest.c
@@ -0,0 +1 @@
+../fips/sha/fips_shatest.c
\ No newline at end of file
diff --git a/openssl/test/fips_test_suite.c b/openssl/test/fips_test_suite.c
new file mode 120000
index 0000000..b538efa
--- /dev/null
+++ b/openssl/test/fips_test_suite.c
@@ -0,0 +1 @@
+../fips/fips_test_suite.c
\ No newline at end of file
diff --git a/openssl/test/hmactest.c b/openssl/test/hmactest.c
new file mode 120000
index 0000000..353ee2c
--- /dev/null
+++ b/openssl/test/hmactest.c
@@ -0,0 +1 @@
+../crypto/hmac/hmactest.c
\ No newline at end of file
diff --git a/openssl/test/ideatest.c b/openssl/test/ideatest.c
new file mode 120000
index 0000000..a9bfb3d
--- /dev/null
+++ b/openssl/test/ideatest.c
@@ -0,0 +1 @@
+../crypto/idea/ideatest.c
\ No newline at end of file
diff --git a/openssl/test/igetest.c b/openssl/test/igetest.c
new file mode 100644
index 0000000..1ba9002
--- /dev/null
+++ b/openssl/test/igetest.c
@@ -0,0 +1,503 @@
+/* test/igetest.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/aes.h>
+#include <openssl/rand.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#define TEST_SIZE	128
+#define BIG_TEST_SIZE 10240
+
+static void hexdump(FILE *f,const char *title,const unsigned char *s,int l)
+    {
+    int n=0;
+
+    fprintf(f,"%s",title);
+    for( ; n < l ; ++n)
+		{
+		if((n%16) == 0)
+			fprintf(f,"\n%04x",n);
+		fprintf(f," %02x",s[n]);
+		}
+    fprintf(f,"\n");
+    }
+
+#define MAX_VECTOR_SIZE	64
+
+struct ige_test
+	{
+	const unsigned char key[16];
+	const unsigned char iv[32];
+	const unsigned char in[MAX_VECTOR_SIZE];
+	const unsigned char out[MAX_VECTOR_SIZE];
+	const size_t length;
+	const int encrypt;
+	};
+
+static struct ige_test const ige_test_vectors[] = {
+{ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* key */
+  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, /* iv */
+  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* in */
+  { 0x1a, 0x85, 0x19, 0xa6, 0x55, 0x7b, 0xe6, 0x52,
+    0xe9, 0xda, 0x8e, 0x43, 0xda, 0x4e, 0xf4, 0x45,
+    0x3c, 0xf4, 0x56, 0xb4, 0xca, 0x48, 0x8a, 0xa3,
+    0x83, 0xc7, 0x9c, 0x98, 0xb3, 0x47, 0x97, 0xcb }, /* out */
+  32, AES_ENCRYPT }, /* test vector 0 */
+
+{ { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
+    0x61, 0x6e, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65 }, /* key */
+  { 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x6f, 0x66, 0x20, 0x49, 0x47, 0x45,
+    0x20, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f,
+    0x72, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53 }, /* iv */
+  { 0x4c, 0x2e, 0x20, 0x4c, 0x65, 0x74, 0x27, 0x73,
+    0x20, 0x68, 0x6f, 0x70, 0x65, 0x20, 0x42, 0x65,
+    0x6e, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x69, 0x74,
+    0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x21, 0x0a }, /* in */
+  { 0x99, 0x70, 0x64, 0x87, 0xa1, 0xcd, 0xe6, 0x13,
+    0xbc, 0x6d, 0xe0, 0xb6, 0xf2, 0x4b, 0x1c, 0x7a,
+    0xa4, 0x48, 0xc8, 0xb9, 0xc3, 0x40, 0x3e, 0x34,
+    0x67, 0xa8, 0xca, 0xd8, 0x93, 0x40, 0xf5, 0x3b }, /* out */
+  32, AES_DECRYPT }, /* test vector 1 */
+};
+
+struct bi_ige_test
+	{
+	const unsigned char key1[32];
+	const unsigned char key2[32];
+	const unsigned char iv[64];
+	const unsigned char in[MAX_VECTOR_SIZE];
+	const unsigned char out[MAX_VECTOR_SIZE];
+	const size_t keysize;
+	const size_t length;
+	const int encrypt;
+	};
+
+static struct bi_ige_test const bi_ige_test_vectors[] = {
+{ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* key1 */
+  { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, /* key2 */
+  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f }, /* iv */
+  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* in */
+  { 0x14, 0x40, 0x6f, 0xae, 0xa2, 0x79, 0xf2, 0x56,
+	0x1f, 0x86, 0xeb, 0x3b, 0x7d, 0xff, 0x53, 0xdc,
+	0x4e, 0x27, 0x0c, 0x03, 0xde, 0x7c, 0xe5, 0x16,
+	0x6a, 0x9c, 0x20, 0x33, 0x9d, 0x33, 0xfe, 0x12 }, /* out */
+  16, 32, AES_ENCRYPT }, /* test vector 0 */
+{ { 0x58, 0x0a, 0x06, 0xe9, 0x97, 0x07, 0x59, 0x5c,
+	0x9e, 0x19, 0xd2, 0xa7, 0xbb, 0x40, 0x2b, 0x7a,
+	0xc7, 0xd8, 0x11, 0x9e, 0x4c, 0x51, 0x35, 0x75,
+	0x64, 0x28, 0x0f, 0x23, 0xad, 0x74, 0xac, 0x37 }, /* key1 */
+  { 0xd1, 0x80, 0xa0, 0x31, 0x47, 0xa3, 0x11, 0x13,
+	0x86, 0x26, 0x9e, 0x6d, 0xff, 0xaf, 0x72, 0x74,
+	0x5b, 0xa2, 0x35, 0x81, 0xd2, 0xa6, 0x3d, 0x21,
+	0x67, 0x7b, 0x58, 0xa8, 0x18, 0xf9, 0x72, 0xe4 }, /* key2 */
+  { 0x80, 0x3d, 0xbd, 0x4c, 0xe6, 0x7b, 0x06, 0xa9,
+	0x53, 0x35, 0xd5, 0x7e, 0x71, 0xc1, 0x70, 0x70,
+	0x74, 0x9a, 0x00, 0x28, 0x0c, 0xbf, 0x6c, 0x42,
+	0x9b, 0xa4, 0xdd, 0x65, 0x11, 0x77, 0x7c, 0x67,
+	0xfe, 0x76, 0x0a, 0xf0, 0xd5, 0xc6, 0x6e, 0x6a,
+	0xe7, 0x5e, 0x4c, 0xf2, 0x7e, 0x9e, 0xf9, 0x20,
+	0x0e, 0x54, 0x6f, 0x2d, 0x8a, 0x8d, 0x7e, 0xbd,
+	0x48, 0x79, 0x37, 0x99, 0xff, 0x27, 0x93, 0xa3 }, /* iv */
+  { 0xf1, 0x54, 0x3d, 0xca, 0xfe, 0xb5, 0xef, 0x1c,
+	0x4f, 0xa6, 0x43, 0xf6, 0xe6, 0x48, 0x57, 0xf0,
+	0xee, 0x15, 0x7f, 0xe3, 0xe7, 0x2f, 0xd0, 0x2f,
+	0x11, 0x95, 0x7a, 0x17, 0x00, 0xab, 0xa7, 0x0b,
+	0xbe, 0x44, 0x09, 0x9c, 0xcd, 0xac, 0xa8, 0x52,
+	0xa1, 0x8e, 0x7b, 0x75, 0xbc, 0xa4, 0x92, 0x5a,
+	0xab, 0x46, 0xd3, 0x3a, 0xa0, 0xd5, 0x35, 0x1c,
+	0x55, 0xa4, 0xb3, 0xa8, 0x40, 0x81, 0xa5, 0x0b}, /* in */
+  { 0x42, 0xe5, 0x28, 0x30, 0x31, 0xc2, 0xa0, 0x23,
+	0x68, 0x49, 0x4e, 0xb3, 0x24, 0x59, 0x92, 0x79,
+	0xc1, 0xa5, 0xcc, 0xe6, 0x76, 0x53, 0xb1, 0xcf,
+	0x20, 0x86, 0x23, 0xe8, 0x72, 0x55, 0x99, 0x92,
+	0x0d, 0x16, 0x1c, 0x5a, 0x2f, 0xce, 0xcb, 0x51,
+	0xe2, 0x67, 0xfa, 0x10, 0xec, 0xcd, 0x3d, 0x67,
+	0xa5, 0xe6, 0xf7, 0x31, 0x26, 0xb0, 0x0d, 0x76,
+	0x5e, 0x28, 0xdc, 0x7f, 0x01, 0xc5, 0xa5, 0x4c}, /* out */
+  32, 64, AES_ENCRYPT }, /* test vector 1 */
+
+};
+
+static int run_test_vectors(void)
+	{
+	unsigned int n;
+	int errs = 0;
+
+	for(n=0 ; n < sizeof(ige_test_vectors)/sizeof(ige_test_vectors[0]) ; ++n)
+		{
+		const struct ige_test * const v = &ige_test_vectors[n];
+		AES_KEY key;
+		unsigned char buf[MAX_VECTOR_SIZE];
+		unsigned char iv[AES_BLOCK_SIZE*2];
+
+		assert(v->length <= MAX_VECTOR_SIZE);
+
+		if(v->encrypt == AES_ENCRYPT)
+			AES_set_encrypt_key(v->key, 8*sizeof v->key, &key);
+		else
+			AES_set_decrypt_key(v->key, 8*sizeof v->key, &key);
+		memcpy(iv, v->iv, sizeof iv);
+		AES_ige_encrypt(v->in, buf, v->length, &key, iv, v->encrypt);
+
+		if(memcmp(v->out, buf, v->length))
+			{
+			printf("IGE test vector %d failed\n", n);
+			hexdump(stdout, "key", v->key, sizeof v->key);
+			hexdump(stdout, "iv", v->iv, sizeof v->iv);
+			hexdump(stdout, "in", v->in, v->length);
+			hexdump(stdout, "expected", v->out, v->length);
+			hexdump(stdout, "got", buf, v->length);
+
+			++errs;
+			}
+
+                /* try with in == out */
+		memcpy(iv, v->iv, sizeof iv);
+                memcpy(buf, v->in, v->length);
+		AES_ige_encrypt(buf, buf, v->length, &key, iv, v->encrypt);
+
+		if(memcmp(v->out, buf, v->length))
+			{
+			printf("IGE test vector %d failed (with in == out)\n", n);
+			hexdump(stdout, "key", v->key, sizeof v->key);
+			hexdump(stdout, "iv", v->iv, sizeof v->iv);
+			hexdump(stdout, "in", v->in, v->length);
+			hexdump(stdout, "expected", v->out, v->length);
+			hexdump(stdout, "got", buf, v->length);
+
+			++errs;
+			}
+		}
+
+	for(n=0 ; n < sizeof(bi_ige_test_vectors)/sizeof(bi_ige_test_vectors[0])
+			; ++n)
+		{
+		const struct bi_ige_test * const v = &bi_ige_test_vectors[n];
+		AES_KEY key1;
+		AES_KEY key2;
+		unsigned char buf[MAX_VECTOR_SIZE];
+
+		assert(v->length <= MAX_VECTOR_SIZE);
+
+		if(v->encrypt == AES_ENCRYPT)
+			{
+			AES_set_encrypt_key(v->key1, 8*v->keysize, &key1);
+			AES_set_encrypt_key(v->key2, 8*v->keysize, &key2);
+			}
+		else
+			{
+			AES_set_decrypt_key(v->key1, 8*v->keysize, &key1);
+			AES_set_decrypt_key(v->key2, 8*v->keysize, &key2);
+			}
+
+		AES_bi_ige_encrypt(v->in, buf, v->length, &key1, &key2, v->iv,
+						   v->encrypt);
+
+		if(memcmp(v->out, buf, v->length))
+			{
+			printf("Bidirectional IGE test vector %d failed\n", n);
+			hexdump(stdout, "key 1", v->key1, sizeof v->key1);
+			hexdump(stdout, "key 2", v->key2, sizeof v->key2);
+			hexdump(stdout, "iv", v->iv, sizeof v->iv);
+			hexdump(stdout, "in", v->in, v->length);
+			hexdump(stdout, "expected", v->out, v->length);
+			hexdump(stdout, "got", buf, v->length);
+
+			++errs;
+			}
+		}
+
+	return errs;
+	}
+
+int main(int argc, char **argv)
+	{
+	unsigned char rkey[16];
+	unsigned char rkey2[16];
+	AES_KEY key;
+	AES_KEY key2;
+	unsigned char plaintext[BIG_TEST_SIZE];
+	unsigned char ciphertext[BIG_TEST_SIZE];
+	unsigned char checktext[BIG_TEST_SIZE];
+	unsigned char iv[AES_BLOCK_SIZE*4];
+	unsigned char saved_iv[AES_BLOCK_SIZE*4];
+	int err = 0;
+	unsigned int n;
+	unsigned matches;
+
+	assert(BIG_TEST_SIZE >= TEST_SIZE);
+
+	RAND_pseudo_bytes(rkey, sizeof rkey);
+	RAND_pseudo_bytes(plaintext, sizeof plaintext);
+	RAND_pseudo_bytes(iv, sizeof iv);
+	memcpy(saved_iv, iv, sizeof saved_iv);
+
+	/* Forward IGE only... */
+
+	/* Straight encrypt/decrypt */
+	AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
+	AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, iv,
+					AES_ENCRYPT);
+
+	AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
+	memcpy(iv, saved_iv, sizeof iv);
+	AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv,
+					AES_DECRYPT);
+
+	if(memcmp(checktext, plaintext, TEST_SIZE))
+		{
+		printf("Encrypt+decrypt doesn't match\n");
+		hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
+		hexdump(stdout, "Checktext", checktext, TEST_SIZE);
+		++err;
+		}
+
+	/* Now check encrypt chaining works */
+	AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
+	memcpy(iv, saved_iv, sizeof iv);
+	AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE/2, &key, iv,
+					AES_ENCRYPT);
+	AES_ige_encrypt(plaintext+TEST_SIZE/2,
+					ciphertext+TEST_SIZE/2, TEST_SIZE/2,
+					&key, iv, AES_ENCRYPT);
+
+	AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
+	memcpy(iv, saved_iv, sizeof iv);
+	AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv,
+					AES_DECRYPT);
+
+	if(memcmp(checktext, plaintext, TEST_SIZE))
+		{
+		printf("Chained encrypt+decrypt doesn't match\n");
+		hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
+		hexdump(stdout, "Checktext", checktext, TEST_SIZE);
+		++err;
+		}
+
+	/* And check decrypt chaining */
+	AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
+	memcpy(iv, saved_iv, sizeof iv);
+	AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE/2, &key, iv,
+					AES_ENCRYPT);
+	AES_ige_encrypt(plaintext+TEST_SIZE/2,
+					ciphertext+TEST_SIZE/2, TEST_SIZE/2,
+					&key, iv, AES_ENCRYPT);
+
+	AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
+	memcpy(iv, saved_iv, sizeof iv);
+	AES_ige_encrypt(ciphertext, checktext, TEST_SIZE/2, &key, iv,
+					AES_DECRYPT);
+	AES_ige_encrypt(ciphertext+TEST_SIZE/2,
+					checktext+TEST_SIZE/2, TEST_SIZE/2, &key, iv,
+					AES_DECRYPT);
+
+	if(memcmp(checktext, plaintext, TEST_SIZE))
+		{
+		printf("Chained encrypt+chained decrypt doesn't match\n");
+		hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
+		hexdump(stdout, "Checktext", checktext, TEST_SIZE);
+		++err;
+		}
+
+	/* make sure garble extends forwards only */
+	AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
+	memcpy(iv, saved_iv, sizeof iv);
+	AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
+					AES_ENCRYPT);
+
+	/* corrupt halfway through */
+	++ciphertext[sizeof ciphertext/2];
+	AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
+	memcpy(iv, saved_iv, sizeof iv);
+	AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
+					AES_DECRYPT);
+
+	matches=0;
+	for(n=0 ; n < sizeof checktext ; ++n)
+		if(checktext[n] == plaintext[n])
+			++matches;
+
+	if(matches > sizeof checktext/2+sizeof checktext/100)
+		{
+		printf("More than 51%% matches after garbling\n");
+		++err;
+		}
+
+	if(matches < sizeof checktext/2)
+		{
+		printf("Garble extends backwards!\n");
+		++err;
+		}
+
+	/* Bi-directional IGE */
+
+	/* Note that we don't have to recover the IV, because chaining isn't */
+	/* possible with biIGE, so the IV is not updated. */
+
+	RAND_pseudo_bytes(rkey2, sizeof rkey2);
+
+	/* Straight encrypt/decrypt */
+	AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
+	AES_set_encrypt_key(rkey2, 8*sizeof rkey2, &key2);
+	AES_bi_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, &key2, iv,
+					   AES_ENCRYPT);
+
+	AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
+	AES_set_decrypt_key(rkey2, 8*sizeof rkey2, &key2);
+	AES_bi_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, &key2, iv,
+					   AES_DECRYPT);
+
+	if(memcmp(checktext, plaintext, TEST_SIZE))
+		{
+		printf("Encrypt+decrypt doesn't match\n");
+		hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
+		hexdump(stdout, "Checktext", checktext, TEST_SIZE);
+		++err;
+		}
+
+	/* make sure garble extends both ways */
+	AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
+	AES_set_encrypt_key(rkey2, 8*sizeof rkey2, &key2);
+	AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
+					AES_ENCRYPT);
+
+	/* corrupt halfway through */
+	++ciphertext[sizeof ciphertext/2];
+	AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
+	AES_set_decrypt_key(rkey2, 8*sizeof rkey2, &key2);
+	AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
+					AES_DECRYPT);
+
+	matches=0;
+	for(n=0 ; n < sizeof checktext ; ++n)
+		if(checktext[n] == plaintext[n])
+			++matches;
+
+	if(matches > sizeof checktext/100)
+		{
+		printf("More than 1%% matches after bidirectional garbling\n");
+		++err;
+		}
+
+	/* make sure garble extends both ways (2) */
+	AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
+	AES_set_encrypt_key(rkey2, 8*sizeof rkey2, &key2);
+	AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
+					AES_ENCRYPT);
+
+	/* corrupt right at the end */
+	++ciphertext[sizeof ciphertext-1];
+	AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
+	AES_set_decrypt_key(rkey2, 8*sizeof rkey2, &key2);
+	AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
+					AES_DECRYPT);
+
+	matches=0;
+	for(n=0 ; n < sizeof checktext ; ++n)
+		if(checktext[n] == plaintext[n])
+			++matches;
+
+	if(matches > sizeof checktext/100)
+		{
+		printf("More than 1%% matches after bidirectional garbling (2)\n");
+		++err;
+		}
+
+	/* make sure garble extends both ways (3) */
+	AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
+	AES_set_encrypt_key(rkey2, 8*sizeof rkey2, &key2);
+	AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
+					AES_ENCRYPT);
+
+	/* corrupt right at the start */
+	++ciphertext[0];
+	AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
+	AES_set_decrypt_key(rkey2, 8*sizeof rkey2, &key2);
+	AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
+					AES_DECRYPT);
+
+	matches=0;
+	for(n=0 ; n < sizeof checktext ; ++n)
+		if(checktext[n] == plaintext[n])
+			++matches;
+
+	if(matches > sizeof checktext/100)
+		{
+		printf("More than 1%% matches after bidirectional garbling (3)\n");
+		++err;
+		}
+
+	err += run_test_vectors();
+
+	return err;
+	}
diff --git a/openssl/test/jpaketest.c b/openssl/test/jpaketest.c
new file mode 120000
index 0000000..49f44f8
--- /dev/null
+++ b/openssl/test/jpaketest.c
@@ -0,0 +1 @@
+dummytest.c
\ No newline at end of file
diff --git a/openssl/test/maketests.com b/openssl/test/maketests.com
new file mode 100644
index 0000000..386e5cf
--- /dev/null
+++ b/openssl/test/maketests.com
@@ -0,0 +1,1085 @@
+$!
+$!  MAKETESTS.COM
+$!  Written By:  Robert Byer
+$!               Vice-President
+$!               A-Com Computing, Inc.
+$!               byer@mail.all-net.net
+$!
+$!  Changes by Richard Levitte <richard@levitte.org>
+$!
+$!  This command files compiles and creates all the various different
+$!  "test" programs for the different types of encryption for OpenSSL.
+$!  It was written so it would try to determine what "C" compiler to
+$!  use or you can specify which "C" compiler to use.
+$!
+$!  The test "executables" will be placed in a directory called
+$!  [.xxx.EXE.TEST] where "xxx" denotes ALPHA, IA64, or VAX, depending
+$!  on your machine architecture.
+$!
+$!  Specify DEBUG or NODEBUG P1 to compile with or without debugger
+$!  information.
+$!
+$!  Specify which compiler at P2 to try to compile under.
+$!
+$!	   VAXC	 For VAX C.
+$!	   DECC	 For DEC C.
+$!	   GNUC	 For GNU C.
+$!
+$!  If you don't specify a compiler, it will try to determine which
+$!  "C" compiler to use.
+$!
+$!  P3, if defined, sets a TCP/IP library to use, through one of the following
+$!  keywords:
+$!
+$!	UCX		for UCX
+$!	SOCKETSHR	for SOCKETSHR+NETLIB
+$!
+$!  P4, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
+$!
+$!
+$!  P5, if defined, specifies the C pointer size.  Ignored on VAX.
+$!      ("64=ARGV" gives more efficient code with HP C V7.3 or newer.)
+$!      Supported values are:
+$!
+$!      ""       Compile with default (/NOPOINTER_SIZE)
+$!      32       Compile with /POINTER_SIZE=32 (SHORT)
+$!      64       Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV])
+$!               (Automatically select ARGV if compiler supports it.)
+$!      64=      Compile with /POINTER_SIZE=64 (LONG).
+$!      64=ARGV  Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV).
+$!
+$!  P6, if defined, specifies a directory where ZLIB files (zlib.h,
+$!  libz.olb) may be found.  Optionally, a non-default object library
+$!  name may be included ("dev:[dir]libz_64.olb", for example).
+$!
+$!
+$! Announce/identify.
+$!
+$ proc = f$environment( "procedure")
+$ write sys$output "@@@ "+ -
+   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
+$!
+$! Define A TCP/IP Library That We Will Need To Link To.
+$! (That is, If We Need To Link To One.)
+$!
+$ TCPIP_LIB = ""
+$ ZLIB_LIB = ""
+$!
+$! Check Which Architecture We Are Using.
+$!
+$ if (f$getsyi( "cpu") .lt. 128)
+$ then
+$    ARCH = "VAX"
+$ else
+$    ARCH = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$    if (ARCH .eqs. "") then ARCH = "UNK"
+$ endif
+$!
+$ ARCHD = ARCH
+$ LIB32 = "32"
+$ OPT_FILE = ""
+$ POINTER_SIZE = ""
+$!
+$! Check To Make Sure We Have Valid Command Line Parameters.
+$!
+$ GOSUB CHECK_OPTIONS
+$!
+$! Define The OBJ and EXE Directories.
+$!
+$ OBJ_DIR := SYS$DISK:[-.'ARCHD'.OBJ.TEST]
+$ EXE_DIR := SYS$DISK:[-.'ARCHD'.EXE.TEST]
+$!
+$! Specify the destination directory in any /MAP option.
+$!
+$ if (LINKMAP .eqs. "MAP")
+$ then
+$   LINKMAP = LINKMAP+ "=''EXE_DIR'"
+$ endif
+$!
+$! Add the location prefix to the linker options file name.
+$!
+$ if (OPT_FILE .nes. "")
+$ then
+$   OPT_FILE = EXE_DIR+ OPT_FILE
+$ endif
+$!
+$! Initialise logical names and such
+$!
+$ GOSUB INITIALISE
+$!
+$! Tell The User What Kind of Machine We Run On.
+$!
+$ WRITE SYS$OUTPUT "Host system architecture: ''ARCHD'"
+$!
+$! Define The CRYPTO-LIB We Are To Use.
+$!
+$ CRYPTO_LIB := SYS$DISK:[-.'ARCHD'.EXE.CRYPTO]SSL_LIBCRYPTO'LIB32'.OLB
+$!
+$! Define The SSL We Are To Use.
+$!
+$ SSL_LIB := SYS$DISK:[-.'ARCHD'.EXE.SSL]SSL_LIBSSL'LIB32'.OLB
+$!
+$! Create the OBJ and EXE Directories, if needed.
+$!
+$ IF (F$PARSE(OBJ_DIR).EQS."") THEN -
+   CREATE /DIRECTORY 'OBJ_DIR'
+$ IF (F$PARSE(EXE_DIR).EQS."") THEN -
+   CREATE /DIRECTORY 'EXE_DIR'
+$!
+$! Check To See If We Have The Proper Libraries.
+$!
+$ GOSUB LIB_CHECK
+$!
+$! Check To See If We Have A Linker Option File.
+$!
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Define The TEST Files.
+$! NOTE: Some might think this list ugly.  However, it's made this way to
+$! reflect the EXE variable in Makefile as closely as possible,
+$! thereby making it fairly easy to verify that the lists are the same.
+$!
+$ TEST_FILES = "BNTEST,ECTEST,ECDSATEST,ECDHTEST,IDEATEST,"+ -
+	       "MD2TEST,MD4TEST,MD5TEST,HMACTEST,WP_TEST,"+ -
+	       "RC2TEST,RC4TEST,RC5TEST,"+ -
+	       "DESTEST,SHATEST,SHA1TEST,SHA256T,SHA512T,"+ -
+	       "MDC2TEST,RMDTEST,"+ -
+	       "RANDTEST,DHTEST,ENGINETEST,"+ -
+	       "BFTEST,CASTTEST,SSLTEST,EXPTEST,DSATEST,RSA_TEST,"+ -
+	       "EVP_TEST,IGETEST,JPAKETEST,ASN1TEST"
+$! Should we add MTTEST,PQ_TEST,LH_TEST,DIVTEST,TABTEST as well?
+$!
+$! Additional directory information.
+$ T_D_BNTEST     := [-.crypto.bn]
+$ T_D_ECTEST     := [-.crypto.ec]
+$ T_D_ECDSATEST  := [-.crypto.ecdsa]
+$ T_D_ECDHTEST   := [-.crypto.ecdh]
+$ T_D_IDEATEST   := [-.crypto.idea]
+$ T_D_MD2TEST    := [-.crypto.md2]
+$ T_D_MD4TEST    := [-.crypto.md4]
+$ T_D_MD5TEST    := [-.crypto.md5]
+$ T_D_HMACTEST   := [-.crypto.hmac]
+$ T_D_WP_TEST    := [-.crypto.whrlpool]
+$ T_D_RC2TEST    := [-.crypto.rc2]
+$ T_D_RC4TEST    := [-.crypto.rc4]
+$ T_D_RC5TEST    := [-.crypto.rc5]
+$ T_D_DESTEST    := [-.crypto.des]
+$ T_D_SHATEST    := [-.crypto.sha]
+$ T_D_SHA1TEST   := [-.crypto.sha]
+$ T_D_SHA256T    := [-.crypto.sha]
+$ T_D_SHA512T    := [-.crypto.sha]
+$ T_D_MDC2TEST   := [-.crypto.mdc2]
+$ T_D_RMDTEST    := [-.crypto.ripemd]
+$ T_D_RANDTEST   := [-.crypto.rand]
+$ T_D_DHTEST     := [-.crypto.dh]
+$ T_D_ENGINETEST := [-.crypto.engine]
+$ T_D_BFTEST     := [-.crypto.bf]
+$ T_D_CASTTEST   := [-.crypto.cast]
+$ T_D_SSLTEST    := [-.ssl]
+$ T_D_EXPTEST    := [-.crypto.bn]
+$ T_D_DSATEST    := [-.crypto.dsa]
+$ T_D_RSA_TEST   := [-.crypto.rsa]
+$ T_D_EVP_TEST   := [-.crypto.evp]
+$ T_D_IGETEST    := [-.test]
+$ T_D_JPAKETEST  := [-.crypto.jpake]
+$ T_D_ASN1TEST   := [-.test]
+$!
+$ TCPIP_PROGRAMS = ",,"
+$ IF COMPILER .EQS. "VAXC" THEN -
+     TCPIP_PROGRAMS = ",SSLTEST,"
+$!
+$! Define A File Counter And Set It To "0".
+$!
+$ FILE_COUNTER = 0
+$!
+$! Top Of The File Loop.
+$!
+$ NEXT_FILE:
+$!
+$! O.K, Extract The File Name From The File List.
+$!
+$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",TEST_FILES)
+$!
+$! Check To See If We Are At The End Of The File List.
+$!
+$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
+$!
+$! Increment The Counter.
+$!
+$ FILE_COUNTER = FILE_COUNTER + 1
+$!
+$! Create The Source File Name.
+$!
+$ SOURCE_FILE = "SYS$DISK:" + T_D_'FILE_NAME' + FILE_NAME + ".C"
+$!
+$! Create The Object File Name.
+$!
+$ OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ"
+$!
+$! Create The Executable File Name.
+$!
+$ EXE_FILE = EXE_DIR + FILE_NAME + ".EXE"
+$ ON WARNING THEN GOTO NEXT_FILE
+$!
+$! Check To See If The File We Want To Compile Actually Exists.
+$!
+$ IF (F$SEARCH(SOURCE_FILE).EQS."")
+$ THEN
+$!
+$!  Tell The User That The File Dosen't Exist.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Exit The Build.
+$!
+$   GOTO EXIT
+$ ENDIF
+$!
+$! Tell The User What We Are Building.
+$!
+$ WRITE SYS$OUTPUT "Building The ",FILE_NAME," Test Program."
+$!
+$! Compile The File.
+$!
+$ ON ERROR THEN GOTO NEXT_FILE
+$ CC /OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ON WARNING THEN GOTO NEXT_FILE
+$!
+$! Check If What We Are About To Compile Works Without A TCP/IP Library.
+$!
+$ IF ((TCPIP_LIB.EQS."").AND.((TCPIP_PROGRAMS-FILE_NAME).NES.TCPIP_PROGRAMS))
+$ THEN
+$!
+$!  Inform The User That A TCP/IP Library Is Needed To Compile This Program.
+$!
+$   WRITE SYS$OUTPUT -
+	  FILE_NAME," Needs A TCP/IP Library.  Can't Link.  Skipping..."
+$   GOTO NEXT_FILE
+$!
+$! End The TCP/IP Library Check.
+$!
+$ ENDIF
+$!
+$! Link The Program, Check To See If We Need To Link With RSAREF Or Not.
+$! Check To See If We Are To Link With A Specific TCP/IP Library.
+$!
+$!  Don't Link With The RSAREF Routines And TCP/IP Library.
+$!
+$ LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' /EXECTABLE = 'EXE_FILE' -
+   'OBJECT_FILE', -
+   'SSL_LIB' /LIBRARY, -
+   'CRYPTO_LIB' /LIBRARY -
+   'TCPIP_LIB' -
+   'ZLIB_LIB' -
+   ,'OPT_FILE' /OPTIONS
+$!
+$! Go Back And Do It Again.
+$!
+$ GOTO NEXT_FILE
+$!
+$! All Done With This Library Part.
+$!
+$ FILE_DONE:
+$!
+$! All Done, Time To Exit.
+$!
+$ EXIT:
+$ GOSUB CLEANUP
+$ EXIT
+$!
+$! Check For The Link Option FIle.
+$!
+$ CHECK_OPT_FILE:
+$!
+$! Check To See If We Need To Make A VAX C Option File.
+$!
+$ IF (COMPILER.EQS."VAXC")
+$ THEN
+$!
+$!  Check To See If We Already Have A VAX C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    We Need A VAX C Linker Option File.
+$!
+$     CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against 
+! The Sharable VAX C Runtime Library.
+!
+SYS$SHARE:VAXCRTL.EXE /SHAREABLE
+$EOD
+$!
+$!  End The Option File Check.
+$!
+$   ENDIF
+$!
+$! End The VAXC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A GNU C Option File.
+$!
+$ IF (COMPILER.EQS."GNUC")
+$ THEN
+$!
+$!  Check To See If We Already Have A GNU C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    We Need A GNU C Linker Option File.
+$!
+$     CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against 
+! The Sharable C Runtime Library.
+!
+GNU_CC:[000000]GCCLIB.OLB /LIBRARY
+SYS$SHARE:VAXCRTL.EXE /SHAREABLE
+$EOD
+$!
+$!  End The Option File Check.
+$!
+$   ENDIF
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A DEC C Option File.
+$!
+$ IF (COMPILER.EQS."DECC")
+$ THEN
+$!
+$!  Check To See If We Already Have A DEC C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    Figure Out If We Need A non-VAX Or A VAX Linker Option File.
+$!
+$     IF (ARCH.EQS."VAX")
+$     THEN
+$!
+$!      We Need A DEC C Linker Option File For VAX.
+$!
+$       CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against 
+! The Sharable DEC C Runtime Library.
+!
+SYS$SHARE:DECC$SHR.EXE /SHAREABLE
+$EOD
+$!
+$!    Else...
+$!
+$     ELSE
+$!
+$!      Create The non-VAX Linker Option File.
+$!
+$       CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File For non-VAX To Link Against 
+! The Sharable C Runtime Library.
+!
+SYS$SHARE:CMA$OPEN_LIB_SHR.EXE /SHAREABLE
+SYS$SHARE:CMA$OPEN_RTL.EXE /SHAREABLE
+$EOD
+$!
+$!    End The DEC C Option File Check.
+$!
+$     ENDIF
+$!
+$!  End The Option File Search.
+$!
+$   ENDIF
+$!
+$! End The DEC C Check.
+$!
+$ ENDIF
+$!
+$!  Tell The User What Linker Option File We Are Using.
+$!
+$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."	
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$!
+$! Check To See If We Have The Appropiate Libraries.
+$!
+$ LIB_CHECK:
+$!
+$! Look For The Library LIBCRYPTO.OLB.
+$!
+$ IF (F$SEARCH(CRYPTO_LIB).EQS."")
+$ THEN
+$!
+$!  Tell The User We Can't Find The LIBCRYPTO.OLB Library.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"."
+$   WRITE SYS$OUTPUT "We Can't Link Without It."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Since We Can't Link Without It, Exit.
+$!
+$   EXIT
+$!
+$! End The Crypto Library Check.
+$!
+$ ENDIF
+$!
+$! Look For The Library LIBSSL.OLB.
+$!
+$ IF (F$SEARCH(SSL_LIB).EQS."")
+$ THEN
+$!
+$!  Tell The User We Can't Find The LIBSSL.OLB Library.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"."
+$   WRITE SYS$OUTPUT "Some Of The Test Programs Need To Link To It."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Since We Can't Link Without It, Exit.
+$!
+$   EXIT
+$!
+$! End The SSL Library Check.
+$!
+$ ENDIF
+$!
+$! Time To Return.
+$!
+$ RETURN
+$!
+$! Check The User's Options.
+$!
+$ CHECK_OPTIONS:
+$!
+$! Set basic C compiler /INCLUDE directories.
+$!
+$ CC_INCLUDES = "SYS$DISK:[-],SYS$DISK:[-.CRYPTO]"
+$!
+$! Check To See If P1 Is Blank.
+$!
+$ IF (P1.EQS."NODEBUG")
+$ THEN
+$!
+$!  P1 Is NODEBUG, So Compile Without Debugger Information.
+$!
+$   DEBUGGER  = "NODEBUG"
+$   LINKMAP = "NOMAP"
+$   TRACEBACK = "NOTRACEBACK" 
+$   GCC_OPTIMIZE = "OPTIMIZE"
+$   CC_OPTIMIZE = "OPTIMIZE"
+$   WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
+$   WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  Check To See If We Are To Compile With Debugger Information.
+$!
+$   IF (P1.EQS."DEBUG")
+$   THEN
+$!
+$!    Compile With Debugger Information.
+$!
+$     DEBUGGER  = "DEBUG"
+$     LINKMAP = "MAP"
+$     TRACEBACK = "TRACEBACK"
+$     GCC_OPTIMIZE = "NOOPTIMIZE"
+$     CC_OPTIMIZE = "NOOPTIMIZE"
+$     WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
+$     WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
+$!
+$!  Else...
+$!
+$   ELSE
+$!
+$!    Tell The User Entered An Invalid Option.
+$!
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ",P1," Is Invalid.  The Valid Options Are:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "    DEBUG    :  Compile With The Debugger Information."
+$     WRITE SYS$OUTPUT "    NODEBUG  :  Compile Without The Debugger Information."
+$     WRITE SYS$OUTPUT ""
+$!
+$!    Time To EXIT.
+$!
+$     EXIT
+$!
+$!  End The Valid Argument Check.
+$!
+$   ENDIF
+$!
+$! End The P1 Check.
+$!
+$ ENDIF
+$!
+$! Check P5 (POINTER_SIZE).
+$!
+$ IF (P5 .NES. "") .AND. (ARCH .NES. "VAX")
+$ THEN
+$!
+$   IF (P5 .EQS. "32")
+$   THEN
+$     POINTER_SIZE = " /POINTER_SIZE=32"
+$   ELSE
+$     POINTER_SIZE = F$EDIT( P5, "COLLAPSE, UPCASE")
+$     IF ((POINTER_SIZE .EQS. "64") .OR. -
+       (POINTER_SIZE .EQS. "64=") .OR. -
+       (POINTER_SIZE .EQS. "64=ARGV"))
+$     THEN
+$       ARCHD = ARCH+ "_64"
+$       LIB32 = ""
+$       IF (F$EXTRACT( 2, 1, POINTER_SIZE) .EQS. "=")
+$       THEN
+$!        Explicit user choice: "64" or "64=ARGV".
+$         IF (POINTER_SIZE .EQS. "64=") THEN POINTER_SIZE = "64"
+$       ELSE
+$         SET NOON
+$         DEFINE /USER_MODE SYS$OUTPUT NL:
+$         DEFINE /USER_MODE SYS$ERROR NL:
+$         CC /NOLIST /NOOBJECT /POINTER_SIZE=64=ARGV NL:
+$         IF ($STATUS .AND. %X0FFF0000) .EQ. %X00030000
+$         THEN
+$           ! If we got here, it means DCL complained like this:
+$           ! %DCL-W-NOVALU, value not allowed - remove value specification
+$           !  \64=\
+$           !
+$           ! If the compiler was run, logicals defined in /USER would
+$           ! have been deassigned automatically.  However, when DCL
+$           ! complains, they aren't, so we do it here (it might be
+$           ! unnecessary, but just in case there will be another error
+$           ! message further on that we don't want to miss)
+$           DEASSIGN /USER_MODE SYS$ERROR
+$           DEASSIGN /USER_MODE SYS$OUTPUT
+$         ELSE
+$           POINTER_SIZE = POINTER_SIZE + "=ARGV"
+$         ENDIF
+$         SET ON
+$       ENDIF
+$       POINTER_SIZE = " /POINTER_SIZE=''POINTER_SIZE'"
+$     ELSE
+$!
+$!      Tell The User Entered An Invalid Option.
+$!
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT "The Option ", P5, -
+         " Is Invalid.  The Valid Options Are:"
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT -
+         "    """"  :  Compile with default (short) pointers."
+$       WRITE SYS$OUTPUT -
+         "    32  :  Compile with 32-bit (short) pointers."
+$       WRITE SYS$OUTPUT -
+         "    64       :  Compile with 64-bit (long) pointers (auto ARGV)."
+$       WRITE SYS$OUTPUT -
+         "    64=      :  Compile with 64-bit (long) pointers (no ARGV)."
+$       WRITE SYS$OUTPUT -
+         "    64=ARGV  :  Compile with 64-bit (long) pointers (ARGV)."
+$       WRITE SYS$OUTPUT ""
+$! 
+$!      Time To EXIT.
+$!
+$       EXIT
+$!
+$     ENDIF
+$!
+$   ENDIF
+$!
+$! End The P5 (POINTER_SIZE) Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P2 Is Blank.
+$!
+$ IF (P2.EQS."")
+$ THEN
+$!
+$!  O.K., The User Didn't Specify A Compiler, Let's Try To
+$!  Find Out Which One To Use.
+$!
+$!  Check To See If We Have GNU C.
+$!
+$   IF (F$TRNLNM("GNU_CC").NES."")
+$   THEN
+$!
+$!    Looks Like GNUC, Set To Use GNUC.
+$!
+$     P2 = "GNUC"
+$!
+$!  End The GNU C Compiler Check.
+$!
+$   ELSE
+$!
+$!  Check To See If We Have VAXC Or DECC.
+$!
+$     IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
+$     THEN 
+$!
+$!      Looks Like DECC, Set To Use DECC.
+$!
+$       P2 = "DECC"
+$!
+$!      Else...
+$!
+$     ELSE
+$!
+$!      Looks Like VAXC, Set To Use VAXC.
+$!
+$       P2 = "VAXC"
+$!
+$!    End The VAXC Compiler Check.
+$!
+$     ENDIF
+$!
+$!  End The DECC & VAXC Compiler Check.
+$!
+$   ENDIF
+$!
+$!  End The Compiler Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have A Option For P3.
+$!
+$ IF (P3.EQS."")
+$ THEN
+$!
+$!  Find out what socket library we have available
+$!
+$   IF F$PARSE("SOCKETSHR:") .NES. ""
+$   THEN
+$!
+$!    We have SOCKETSHR, and it is my opinion that it's the best to use.
+$!
+$     P3 = "SOCKETSHR"
+$!
+$!    Tell the user
+$!
+$     WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
+$!
+$!    Else, let's look for something else
+$!
+$   ELSE
+$!
+$!    Like UCX (the reason to do this before Multinet is that the UCX
+$!    emulation is easier to use...)
+$!
+$     IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
+	 .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
+	 .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
+$     THEN
+$!
+$!	Last resort: a UCX or UCX-compatible library
+$!
+$	P3 = "UCX"
+$!
+$!      Tell the user
+$!
+$       WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
+$!
+$!	That was all...
+$!
+$     ENDIF
+$   ENDIF
+$ ENDIF
+$!
+$! Set Up Initial CC Definitions, Possibly With User Ones
+$!
+$ CCDEFS = "TCPIP_TYPE_''P3'"
+$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
+$ CCEXTRAFLAGS = ""
+$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
+$ CCDISABLEWARNINGS = "" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
+$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
+	CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
+$!
+$! Check To See If We Have A ZLIB Option.
+$!
+$ ZLIB = P6
+$ IF (ZLIB .NES. "")
+$ THEN
+$!
+$!  Check for expected ZLIB files.
+$!
+$   err = 0
+$   file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY")
+$   if (f$search( file1) .eqs. "")
+$   then
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
+$     WRITE SYS$OUTPUT "    Can't find header: ''file1'"
+$     err = 1
+$   endif
+$   file1 = f$parse( "A.;", ZLIB)- "A.;"
+$!
+$   file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY")
+$   if (f$search( file2) .eqs. "")
+$   then
+$     if (err .eq. 0)
+$     then
+$       WRITE SYS$OUTPUT ""
+$       WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
+$     endif
+$     WRITE SYS$OUTPUT "    Can't find library: ''file2'"
+$     WRITE SYS$OUTPUT ""
+$     err = err+ 2
+$   endif
+$   if (err .eq. 1)
+$   then
+$     WRITE SYS$OUTPUT ""
+$   endif
+$!
+$   if (err .ne. 0)
+$   then
+$     GOTO EXIT
+$   endif
+$!
+$   CCDEFS = """ZLIB=1"", "+ CCDEFS
+$   CC_INCLUDES = CC_INCLUDES+ ", "+ file1
+$   ZLIB_LIB = ", ''file2' /library"
+$!
+$!  Print info
+$!
+$   WRITE SYS$OUTPUT "ZLIB library spec: ", file2
+$!
+$! End The P8 Check.
+$!
+$ ENDIF
+$!
+$!  Check To See If The User Entered A Valid Parameter.
+$!
+$ IF (P2.EQS."VAXC").OR.(P2.EQS."DECC").OR.(P2.EQS."GNUC")
+$ THEN
+$!
+$!  Check To See If The User Wanted DECC.
+$!
+$   IF (P2.EQS."DECC")
+$   THEN
+$!
+$!    Looks Like DECC, Set To Use DECC.
+$!
+$     COMPILER = "DECC"
+$!
+$!    Tell The User We Are Using DECC.
+$!
+$     WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$!    Use DECC...
+$!
+$     CC = "CC"
+$     IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
+	 THEN CC = "CC /DECC"
+$     CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ -
+       "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + -
+       " /INCLUDE=(''CC_INCLUDES') " + CCEXTRAFLAGS
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "VAX_DECC_OPTIONS.OPT"
+$!
+$!  End DECC Check.
+$!
+$   ENDIF
+$!
+$!  Check To See If We Are To Use VAXC.
+$!
+$   IF (P2.EQS."VAXC")
+$   THEN
+$!
+$!    Looks Like VAXC, Set To Use VAXC.
+$!
+$     COMPILER = "VAXC"
+$!
+$!    Tell The User We Are Using VAX C.
+$!
+$     WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$!    Compile Using VAXC.
+$!
+$     CC = "CC"
+$     IF ARCH.NES."VAX"
+$     THEN
+$	WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
+$	EXIT
+$     ENDIF
+$     IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC /VAXC"
+$     CC = CC + "/''CC_OPTIMIZE' /''DEBUGGER' /NOLIST" + -
+	   "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
+$     CCDEFS = CCDEFS + ",""VAXC"""
+$!
+$!    Define <sys> As SYS$COMMON:[SYSLIB]
+$!
+$     DEFINE /NOLOG SYS SYS$COMMON:[SYSLIB]
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "VAX_VAXC_OPTIONS.OPT"
+$!
+$!  End VAXC Check
+$!
+$   ENDIF
+$!
+$!  Check To See If We Are To Use GNU C.
+$!
+$   IF (P2.EQS."GNUC")
+$   THEN
+$!
+$!    Looks Like GNUC, Set To Use GNUC.
+$!
+$     COMPILER = "GNUC"
+$!
+$!    Tell The User We Are Using GNUC.
+$!
+$     WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$!    Use GNU C...
+$!
+$     CC = "GCC /NOCASE_HACK /''GCC_OPTIMIZE' /''DEBUGGER' /NOLIST" + -
+	   "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "VAX_GNUC_OPTIONS.OPT"
+$!
+$!  End The GNU C Check.
+$!
+$   ENDIF
+$!
+$!  Set up default defines
+$!
+$   CCDEFS = """FLAT_INC=1""," + CCDEFS
+$!
+$!  Finish up the definition of CC.
+$!
+$   IF COMPILER .EQS. "DECC"
+$   THEN
+$     IF CCDISABLEWARNINGS .EQS. ""
+$     THEN
+$       CC4DISABLEWARNINGS = "DOLLARID"
+$     ELSE
+$       CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
+$       CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
+$     ENDIF
+$     CC4DISABLEWARNINGS = " /WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
+$   ELSE
+$     CCDISABLEWARNINGS = ""
+$     CC4DISABLEWARNINGS = ""
+$   ENDIF
+$   CC = CC + " /DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
+$!
+$!  Show user the result
+$!
+$   WRITE /SYMBOL SYS$OUTPUT "Main Compiling Command: ", CC
+$!
+$!  Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$!  Tell The User We Don't Know What They Want.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The Option ",P2," Is Invalid.  The Valid Options Are:"
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "    VAXC  :  To Compile With VAX C."
+$   WRITE SYS$OUTPUT "    DECC  :  To Compile With DEC C."
+$   WRITE SYS$OUTPUT "    GNUC  :  To Compile With GNU C."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Time To EXIT.
+$!
+$   EXIT
+$ ENDIF
+$!
+$! Time to check the contents, and to make sure we get the correct library.
+$!
+$ IF P3.EQS."SOCKETSHR" .OR. P3.EQS."MULTINET" .OR. P3.EQS."UCX" -
+     .OR. P3.EQS."TCPIP" .OR. P3.EQS."NONE"
+$ THEN
+$!
+$!  Check to see if SOCKETSHR was chosen
+$!
+$   IF P3.EQS."SOCKETSHR"
+$   THEN
+$!
+$!    Set the library to use SOCKETSHR
+$!
+$     TCPIP_LIB = ",SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
+$!
+$!    Done with SOCKETSHR
+$!
+$   ENDIF
+$!
+$!  Check to see if MULTINET was chosen
+$!
+$   IF P3.EQS."MULTINET"
+$   THEN
+$!
+$!    Set the library to use UCX emulation.
+$!
+$     P3 = "UCX"
+$!
+$!    Done with MULTINET
+$!
+$   ENDIF
+$!
+$!  Check to see if UCX was chosen
+$!
+$   IF P3.EQS."UCX"
+$   THEN
+$!
+$!    Set the library to use UCX.
+$!
+$     TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
+$     IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
+$     THEN
+$       TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS"
+$     ELSE
+$       IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
+	  TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS"
+$     ENDIF
+$!
+$!    Done with UCX
+$!
+$   ENDIF
+$!
+$!  Check to see if TCPIP was chosen
+$!
+$   IF P3.EQS."TCPIP"
+$   THEN
+$!
+$!    Set the library to use TCPIP (post UCX).
+$!
+$     TCPIP_LIB = ",SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
+$!
+$!    Done with TCPIP
+$!
+$   ENDIF
+$!
+$!  Check to see if NONE was chosen
+$!
+$   IF P3.EQS."NONE"
+$   THEN
+$!
+$!    Do not use a TCPIP library.
+$!
+$     TCPIP_LIB = ""
+$!
+$!    Done with NONE
+$!
+$   ENDIF
+$!
+$!  Print info
+$!
+$   WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB- ","
+$!
+$!  Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$!  Tell The User We Don't Know What They Want.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The Option ",P3," Is Invalid.  The Valid Options Are:"
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "    SOCKETSHR  :  To link with SOCKETSHR TCP/IP library."
+$   WRITE SYS$OUTPUT "    UCX        :  To link with UCX TCP/IP library."
+$   WRITE SYS$OUTPUT "    TCPIP      :  To link with TCPIP (post UCX) TCP/IP library."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Time To EXIT.
+$!
+$   EXIT
+$!
+$!  Done with TCP/IP libraries
+$!
+$ ENDIF
+$!
+$! Special Threads For OpenVMS v7.1 Or Later
+$!
+$! Written By:  Richard Levitte
+$!              richard@levitte.org
+$!
+$!
+$! Check To See If We Have A Option For P4.
+$!
+$ IF (P4.EQS."")
+$ THEN
+$!
+$!  Get The Version Of VMS We Are Using.
+$!
+$   ISSEVEN :=
+$   TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
+$   TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
+$!
+$!  Check To See If The VMS Version Is v7.1 Or Later.
+$!
+$   IF (TMP.GE.71)
+$   THEN
+$!
+$!    We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
+$!
+$     ISSEVEN := ,PTHREAD_USE_D4
+$!
+$!  End The VMS Version Check.
+$!
+$   ENDIF
+$!
+$! End The P4 Check.
+$!
+$ ENDIF
+$!
+$!  Time To RETURN...
+$!
+$ RETURN
+$!
+$ INITIALISE:
+$!
+$! Save old value of the logical name OPENSSL
+$!
+$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
+$!
+$! Save directory information
+$!
+$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
+$ __HERE = F$EDIT(__HERE,"UPCASE")
+$ __TOP = __HERE - "TEST]"
+$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
+$!
+$! Set up the logical name OPENSSL to point at the include directory
+$!
+$ DEFINE OPENSSL /NOLOG '__INCLUDE'
+$!
+$! Done
+$!
+$ RETURN
+$!
+$ CLEANUP:
+$!
+$! Restore the logical name OPENSSL if it had a value
+$!
+$ IF __SAVE_OPENSSL .EQS. ""
+$ THEN
+$   DEASSIGN OPENSSL
+$ ELSE
+$   DEFINE /NOLOG OPENSSL '__SAVE_OPENSSL'
+$ ENDIF
+$!
+$! Done
+$!
+$ RETURN
diff --git a/openssl/test/md2test.c b/openssl/test/md2test.c
new file mode 120000
index 0000000..b0c6e6f
--- /dev/null
+++ b/openssl/test/md2test.c
@@ -0,0 +1 @@
+../crypto/md2/md2test.c
\ No newline at end of file
diff --git a/openssl/test/md4test.c b/openssl/test/md4test.c
new file mode 120000
index 0000000..1509be9
--- /dev/null
+++ b/openssl/test/md4test.c
@@ -0,0 +1 @@
+../crypto/md4/md4test.c
\ No newline at end of file
diff --git a/openssl/test/md5test.c b/openssl/test/md5test.c
new file mode 120000
index 0000000..20f4aaf
--- /dev/null
+++ b/openssl/test/md5test.c
@@ -0,0 +1 @@
+../crypto/md5/md5test.c
\ No newline at end of file
diff --git a/openssl/test/mdc2test.c b/openssl/test/mdc2test.c
new file mode 120000
index 0000000..49f44f8
--- /dev/null
+++ b/openssl/test/mdc2test.c
@@ -0,0 +1 @@
+dummytest.c
\ No newline at end of file
diff --git a/openssl/test/methtest.c b/openssl/test/methtest.c
new file mode 100644
index 0000000..005c2f4
--- /dev/null
+++ b/openssl/test/methtest.c
@@ -0,0 +1,105 @@
+/* test/methtest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/rsa.h>
+#include <openssl/x509.h>
+#include "meth.h"
+#include <openssl/err.h>
+
+int main(argc,argv)
+int argc;
+char *argv[];
+	{
+	METHOD_CTX *top,*tmp1,*tmp2;
+
+	top=METH_new(x509_lookup()); /* get a top level context */
+	if (top == NULL) goto err;
+
+	tmp1=METH_new(x509_by_file());
+	if (top == NULL) goto err;
+	METH_arg(tmp1,METH_TYPE_FILE,"cafile1");
+	METH_arg(tmp1,METH_TYPE_FILE,"cafile2");
+	METH_push(top,METH_X509_CA_BY_SUBJECT,tmp1);
+
+	tmp2=METH_new(x509_by_dir());
+	METH_arg(tmp2,METH_TYPE_DIR,"/home/eay/.CAcerts");
+	METH_arg(tmp2,METH_TYPE_DIR,"/home/eay/SSLeay/certs");
+	METH_arg(tmp2,METH_TYPE_DIR,"/usr/local/ssl/certs");
+	METH_push(top,METH_X509_CA_BY_SUBJECT,tmp2);
+
+/*	tmp=METH_new(x509_by_issuer_dir);
+	METH_arg(tmp,METH_TYPE_DIR,"/home/eay/.mycerts");
+	METH_push(top,METH_X509_BY_ISSUER,tmp);
+
+	tmp=METH_new(x509_by_issuer_primary);
+	METH_arg(tmp,METH_TYPE_FILE,"/home/eay/.mycerts/primary.pem");
+	METH_push(top,METH_X509_BY_ISSUER,tmp);
+*/
+
+	METH_init(top);
+	METH_control(tmp1,METH_CONTROL_DUMP,stdout);
+	METH_control(tmp2,METH_CONTROL_DUMP,stdout);
+	EXIT(0);
+err:
+	ERR_load_crypto_strings();
+	ERR_print_errors_fp(stderr);
+	EXIT(1);
+	return(0);
+	}
diff --git a/openssl/test/pkcs7-1.pem b/openssl/test/pkcs7-1.pem
new file mode 100644
index 0000000..c47b27a
--- /dev/null
+++ b/openssl/test/pkcs7-1.pem
@@ -0,0 +1,15 @@
+-----BEGIN PKCS7-----
+MIICUAYJKoZIhvcNAQcCoIICQTCCAj0CAQExDjAMBggqhkiG9w0CAgUAMCgGCSqG
+SIb3DQEHAaAbBBlFdmVyeW9uZSBnZXRzIEZyaWRheSBvZmYuoIIBXjCCAVowggEE
+AgQUAAApMA0GCSqGSIb3DQEBAgUAMCwxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRF
+eGFtcGxlIE9yZ2FuaXphdGlvbjAeFw05MjA5MDkyMjE4MDZaFw05NDA5MDkyMjE4
+MDVaMEIxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRFeGFtcGxlIE9yZ2FuaXphdGlv
+bjEUMBIGA1UEAxMLVGVzdCBVc2VyIDEwWzANBgkqhkiG9w0BAQEFAANKADBHAkAK
+ZnkdxpiBaN56t3QZu3+wwAHGJxAnAHUUKULhmo2MUdBTs+N4Kh3l3Fr06+mUaBcB
+FKHf5nzcmpr1XWVWILurAgMBAAEwDQYJKoZIhvcNAQECBQADQQBFGqHhqncgSl/N
+9XYGnQL3MsJvNnsNV4puZPOakR9Hld8JlDQFEaDR30ogsmp3TMrvdfxpLlTCoZN8
+BxEmnZsWMYGbMIGYAgEBMDQwLDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFEV4YW1w
+bGUgT3JnYW5pemF0aW9uAgQUAAApMAwGCCqGSIb3DQICBQAwDQYJKoZIhvcNAQEB
+BQAEQAX6aoEvx9+L9PJUJQngPoRuEbnGIL4gCe+0QO+8xmkhaZSsBPNBtX0FIC1C
+j7Kie1x339mxW/w9VZNTUDQQweHh
+-----END PKCS7-----
diff --git a/openssl/test/pkcs7.pem b/openssl/test/pkcs7.pem
new file mode 100644
index 0000000..d55c60b
--- /dev/null
+++ b/openssl/test/pkcs7.pem
@@ -0,0 +1,54 @@
+     MIAGCSqGSIb3DQEHAqCAMIACAQExADCABgkqhkiG9w0BBwEAAKCAMIIE+DCCBGGg
+     AwIBAgIQaGSF/JpbS1C223+yrc+N1DANBgkqhkiG9w0BAQQFADBiMREwDwYDVQQH
+     EwhJbnRlcm5ldDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNDAyBgNVBAsTK1Zl
+     cmlTaWduIENsYXNzIDEgQ0EgLSBJbmRpdmlkdWFsIFN1YnNjcmliZXIwHhcNOTYw
+     ODEyMDAwMDAwWhcNOTYwODE3MjM1OTU5WjCCASAxETAPBgNVBAcTCEludGVybmV0
+     MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE0MDIGA1UECxMrVmVyaVNpZ24gQ2xh
+     c3MgMSBDQSAtIEluZGl2aWR1YWwgU3Vic2NyaWJlcjE3MDUGA1UECxMuRGlnaXRh
+     bCBJRCBDbGFzcyAxIC0gU01JTUUgVmVyaVNpZ24sIEluYy4gVEVTVDFGMEQGA1UE
+     CxM9d3d3LnZlcmlzaWduLmNvbS9yZXBvc2l0b3J5L0NQUyBJbmNvcnAuIGJ5IFJl
+     Zi4sTElBQi5MVEQoYyk5NjEZMBcGA1UEAxMQQWxleGFuZHJlIERlYWNvbjEgMB4G
+     CSqGSIb3DQEJARYRYWxleEB2ZXJpc2lnbi5jb20wWzANBgkqhkiG9w0BAQEFAANK
+     ADBHAkAOy7xxCAIkOfuIA2LyRpxgKlDORl8htdXYhF5iBGUx1GYaK6KF+bK/CCI0
+     l4j2OfWGFBUrwGoWqxTNcWgTfMzRAgMBAAGjggIyMIICLjAJBgNVHRMEAjAAMIIC
+     HwYDVR0DBIICFjCCAhIwggIOMIICCgYLYIZIAYb4RQEHAQEwggH5FoIBp1RoaXMg
+     Y2VydGlmaWNhdGUgaW5jb3Jwb3JhdGVzIGJ5IHJlZmVyZW5jZSwgYW5kIGl0cyB1
+     c2UgaXMgc3RyaWN0bHkgc3ViamVjdCB0bywgdGhlIFZlcmlTaWduIENlcnRpZmlj
+     YXRpb24gUHJhY3RpY2UgU3RhdGVtZW50IChDUFMpLCBhdmFpbGFibGUgYXQ6IGh0
+     dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9DUFM7IGJ5IEUtbWFpbCBhdCBDUFMtcmVx
+     dWVzdHNAdmVyaXNpZ24uY29tOyBvciBieSBtYWlsIGF0IFZlcmlTaWduLCBJbmMu
+     LCAyNTkzIENvYXN0IEF2ZS4sIE1vdW50YWluIFZpZXcsIENBIDk0MDQzIFVTQSBU
+     ZWwuICsxICg0MTUpIDk2MS04ODMwIENvcHlyaWdodCAoYykgMTk5NiBWZXJpU2ln
+     biwgSW5jLiAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4gQ0VSVEFJTiBXQVJSQU5USUVT
+     IERJU0NMQUlNRUQgYW5kIExJQUJJTElUWSBMSU1JVEVELqAOBgxghkgBhvhFAQcB
+     AQGhDgYMYIZIAYb4RQEHAQECMCwwKhYoaHR0cHM6Ly93d3cudmVyaXNpZ24uY29t
+     L3JlcG9zaXRvcnkvQ1BTIDANBgkqhkiG9w0BAQQFAAOBgQAimWMGQwwwxk+b3KAL
+     HlSWXtU7LWHe29CEG8XeVNTvrqs6SBqT7OoENOkGxpfdpVgZ3Qw2SKjxDvbvpfSF
+     slsqcxWSgB/hWuaVuZCkvTw/dYGGOxkTJGxvDCfl1PZjX4dKbatslsi9Z9HpGWT7
+     ttItRwKqcBKgmCJvKi1pGWED0zCCAnkwggHioAMCAQICEDURpVKQb+fQKaRAGdQR
+     /D4wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlT
+     aWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmltYXJ5IENlcnRp
+     ZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDYyNzAwMDAwMFoXDTk3MDYyNzIzNTk1
+     OVowYjERMA8GA1UEBxMISW50ZXJuZXQxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMu
+     MTQwMgYDVQQLEytWZXJpU2lnbiBDbGFzcyAxIENBIC0gSW5kaXZpZHVhbCBTdWJz
+     Y3JpYmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2FKbPTdAFDdjKI9Bv
+     qrQpkmOOLPhvltcunXZLEbE2jVfJw/0cxrr+Hgi6M8qV6r7jW80GqLd5HUQq7XPy
+     sVKDaBBwZJHXPmv5912dFEObbpdFmIFH0S3L3bty10w/cariQPJUObwW7s987Lrb
+     P2wqsxaxhhKdrpM01bjV0Pc+qQIDAQABozMwMTAPBgNVHRMECDAGAQH/AgEBMAsG
+     A1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAgQwDQYJKoZIhvcNAQECBQADgYEA
+     KeXHoBmnbxRCgk0jM9e9mDppdxpsipIna/J8DOHEUuD4nONAr4+xOg73SBl026n7
+     Bk55A2wvAMGo7+kKTZ+rHaFDDcmq4O+rzFri2RIOeGAncj1IcGptAQhvXoIhFMG4
+     Jlzg1KlHZHqy7D3jex78zcSU7kKOu8f5tAX1jC3+sToAAKGAMIIBJzCBkTANBgkq
+     hkiG9w0BAQIFADBiMREwDwYDVQQHEwhJbnRlcm5ldDEXMBUGA1UEChMOVmVyaVNp
+     Z24sIEluYy4xNDAyBgNVBAsTK1ZlcmlTaWduIENsYXNzIDEgQ0EgLSBJbmRpdmlk
+     dWFsIFN1YnNjcmliZXIXDTk2MDcwMTE3MzA0MFoXDTk3MDcwMTAwMDAwMFowDQYJ
+     KoZIhvcNAQECBQADgYEAGLuQ6PX8A7AiqBEtWzYtl6lZNSDI0bR5YUo+D2Jzkw30
+     dxQnJSbKXEc6XYuzAW5HvrzATXu5c19WWPT4cRDwmjH71i9QcDysWwf/wE0qGTiW
+     I3tQT0I5VGh7jIJD07nlBw3R4Xl8dH9kr85JsWinqDH5YKpIo9o8knY5n7+qjOow
+     ggEkMIGOMA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5W
+     ZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMSBQdWJsaWMgUHJpbWFyeSBD
+     ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eRcNOTYwNzE2MjMxMTI5WhcNOTYwODE1MDAw
+     MDAwWjANBgkqhkiG9w0BAQIFAAOBgQAXsLE4vnsY6sY67QrmWec7iaU2ehzxanEK
+     /9wKHZNuhlNzk+qGZZw2evxfUe2OaRbYpl8zuZvhK9BHD3ad14OSe9/zx5hOPgP/
+     DQXt6R4R8Q/1JheBrolrgbavjvI2wKS8/Psp2prBrkF4T48+AKRmS8Zzh1guxgvP
+     b+xSu/jH0gAAMYAAAAAAAAAAAA==
diff --git a/openssl/test/pkits-test.pl b/openssl/test/pkits-test.pl
new file mode 100644
index 0000000..69dffa1
--- /dev/null
+++ b/openssl/test/pkits-test.pl
@@ -0,0 +1,940 @@
+# test/pkits-test.pl
+# Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+# project.
+#
+# ====================================================================
+# Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in
+#    the documentation and/or other materials provided with the
+#    distribution.
+#
+# 3. All advertising materials mentioning features or use of this
+#    software must display the following acknowledgment:
+#    "This product includes software developed by the OpenSSL Project
+#    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+#
+# 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+#    endorse or promote products derived from this software without
+#    prior written permission. For written permission, please contact
+#    licensing@OpenSSL.org.
+#
+# 5. Products derived from this software may not be called "OpenSSL"
+#    nor may "OpenSSL" appear in their names without prior written
+#    permission of the OpenSSL Project.
+#
+# 6. Redistributions of any form whatsoever must retain the following
+#    acknowledgment:
+#    "This product includes software developed by the OpenSSL Project
+#    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+#
+# THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+# OF THE POSSIBILITY OF SUCH DAMAGE.
+# ====================================================================
+
+# Perl utility to run PKITS tests for RFC3280 compliance. 
+
+my $ossl_path;
+
+if ( -f "../apps/openssl" ) {
+    $ossl_path = "../util/shlib_wrap.sh ../apps/openssl";
+}
+elsif ( -f "..\\out32dll\\openssl.exe" ) {
+    $ossl_path = "..\\out32dll\\openssl.exe";
+}
+elsif ( -f "..\\out32\\openssl.exe" ) {
+    $ossl_path = "..\\out32\\openssl.exe";
+}
+else {
+    die "Can't find OpenSSL executable";
+}
+
+my $pkitsdir = "pkits/smime";
+my $pkitsta = "pkits/certs/TrustAnchorRootCertificate.crt";
+
+die "Can't find PKITS test data" if !-d $pkitsdir;
+
+my $nist1 = "2.16.840.1.101.3.2.1.48.1";
+my $nist2 = "2.16.840.1.101.3.2.1.48.2";
+my $nist3 = "2.16.840.1.101.3.2.1.48.3";
+my $nist4 = "2.16.840.1.101.3.2.1.48.4";
+my $nist5 = "2.16.840.1.101.3.2.1.48.5";
+my $nist6 = "2.16.840.1.101.3.2.1.48.6";
+
+my $apolicy = "X509v3 Any Policy";
+
+# This table contains the chapter headings of the accompanying PKITS
+# document. They provide useful informational output and their names
+# can be converted into the filename to test.
+
+my @testlists = (
+    [ "4.1", "Signature Verification" ],
+    [ "4.1.1", "Valid Signatures Test1",                        0 ],
+    [ "4.1.2", "Invalid CA Signature Test2",                    7 ],
+    [ "4.1.3", "Invalid EE Signature Test3",                    7 ],
+    [ "4.1.4", "Valid DSA Signatures Test4",                    0 ],
+    [ "4.1.5", "Valid DSA Parameter Inheritance Test5",         0 ],
+    [ "4.1.6", "Invalid DSA Signature Test6",                   7 ],
+    [ "4.2",   "Validity Periods" ],
+    [ "4.2.1", "Invalid CA notBefore Date Test1",               9 ],
+    [ "4.2.2", "Invalid EE notBefore Date Test2",               9 ],
+    [ "4.2.3", "Valid pre2000 UTC notBefore Date Test3",        0 ],
+    [ "4.2.4", "Valid GeneralizedTime notBefore Date Test4",    0 ],
+    [ "4.2.5", "Invalid CA notAfter Date Test5",                10 ],
+    [ "4.2.6", "Invalid EE notAfter Date Test6",                10 ],
+    [ "4.2.7", "Invalid pre2000 UTC EE notAfter Date Test7",    10 ],
+    [ "4.2.8", "Valid GeneralizedTime notAfter Date Test8",     0 ],
+    [ "4.3",   "Verifying Name Chaining" ],
+    [ "4.3.1", "Invalid Name Chaining EE Test1",                20 ],
+    [ "4.3.2", "Invalid Name Chaining Order Test2",             20 ],
+    [ "4.3.3", "Valid Name Chaining Whitespace Test3",          0 ],
+    [ "4.3.4", "Valid Name Chaining Whitespace Test4",          0 ],
+    [ "4.3.5", "Valid Name Chaining Capitalization Test5",      0 ],
+    [ "4.3.6", "Valid Name Chaining UIDs Test6",                0 ],
+    [ "4.3.7", "Valid RFC3280 Mandatory Attribute Types Test7", 0 ],
+    [ "4.3.8", "Valid RFC3280 Optional Attribute Types Test8",  0 ],
+    [ "4.3.9", "Valid UTF8String Encoded Names Test9",          0 ],
+    [ "4.3.10", "Valid Rollover from PrintableString to UTF8String Test10", 0 ],
+    [ "4.3.11", "Valid UTF8String Case Insensitive Match Test11",           0 ],
+    [ "4.4",    "Basic Certificate Revocation Tests" ],
+    [ "4.4.1",  "Missing CRL Test1",                                        3 ],
+    [ "4.4.2", "Invalid Revoked CA Test2",          23 ],
+    [ "4.4.3", "Invalid Revoked EE Test3",          23 ],
+    [ "4.4.4", "Invalid Bad CRL Signature Test4",   8 ],
+    [ "4.4.5", "Invalid Bad CRL Issuer Name Test5", 3 ],
+    [ "4.4.6", "Invalid Wrong CRL Test6",           3 ],
+    [ "4.4.7", "Valid Two CRLs Test7",              0 ],
+
+    # The test document suggests these should return certificate revoked...
+    # Subsquent discussion has concluded they should not due to unhandle
+    # critical CRL extensions.
+    [ "4.4.8", "Invalid Unknown CRL Entry Extension Test8", 36 ],
+    [ "4.4.9", "Invalid Unknown CRL Extension Test9",       36 ],
+
+    [ "4.4.10", "Invalid Unknown CRL Extension Test10",             36 ],
+    [ "4.4.11", "Invalid Old CRL nextUpdate Test11",                12 ],
+    [ "4.4.12", "Invalid pre2000 CRL nextUpdate Test12",            12 ],
+    [ "4.4.13", "Valid GeneralizedTime CRL nextUpdate Test13",      0 ],
+    [ "4.4.14", "Valid Negative Serial Number Test14",              0 ],
+    [ "4.4.15", "Invalid Negative Serial Number Test15",            23 ],
+    [ "4.4.16", "Valid Long Serial Number Test16",                  0 ],
+    [ "4.4.17", "Valid Long Serial Number Test17",                  0 ],
+    [ "4.4.18", "Invalid Long Serial Number Test18",                23 ],
+    [ "4.4.19", "Valid Separate Certificate and CRL Keys Test19",   0 ],
+    [ "4.4.20", "Invalid Separate Certificate and CRL Keys Test20", 23 ],
+
+    # CRL path is revoked so get a CRL path validation error
+    [ "4.4.21", "Invalid Separate Certificate and CRL Keys Test21",      54 ],
+    [ "4.5",    "Verifying Paths with Self-Issued Certificates" ],
+    [ "4.5.1",  "Valid Basic Self-Issued Old With New Test1",            0 ],
+    [ "4.5.2",  "Invalid Basic Self-Issued Old With New Test2",          23 ],
+    [ "4.5.3",  "Valid Basic Self-Issued New With Old Test3",            0 ],
+    [ "4.5.4",  "Valid Basic Self-Issued New With Old Test4",            0 ],
+    [ "4.5.5",  "Invalid Basic Self-Issued New With Old Test5",          23 ],
+    [ "4.5.6",  "Valid Basic Self-Issued CRL Signing Key Test6",         0 ],
+    [ "4.5.7",  "Invalid Basic Self-Issued CRL Signing Key Test7",       23 ],
+    [ "4.5.8",  "Invalid Basic Self-Issued CRL Signing Key Test8",       20 ],
+    [ "4.6",    "Verifying Basic Constraints" ],
+    [ "4.6.1",  "Invalid Missing basicConstraints Test1",                24 ],
+    [ "4.6.2",  "Invalid cA False Test2",                                24 ],
+    [ "4.6.3",  "Invalid cA False Test3",                                24 ],
+    [ "4.6.4",  "Valid basicConstraints Not Critical Test4",             0 ],
+    [ "4.6.5",  "Invalid pathLenConstraint Test5",                       25 ],
+    [ "4.6.6",  "Invalid pathLenConstraint Test6",                       25 ],
+    [ "4.6.7",  "Valid pathLenConstraint Test7",                         0 ],
+    [ "4.6.8",  "Valid pathLenConstraint Test8",                         0 ],
+    [ "4.6.9",  "Invalid pathLenConstraint Test9",                       25 ],
+    [ "4.6.10", "Invalid pathLenConstraint Test10",                      25 ],
+    [ "4.6.11", "Invalid pathLenConstraint Test11",                      25 ],
+    [ "4.6.12", "Invalid pathLenConstraint Test12",                      25 ],
+    [ "4.6.13", "Valid pathLenConstraint Test13",                        0 ],
+    [ "4.6.14", "Valid pathLenConstraint Test14",                        0 ],
+    [ "4.6.15", "Valid Self-Issued pathLenConstraint Test15",            0 ],
+    [ "4.6.16", "Invalid Self-Issued pathLenConstraint Test16",          25 ],
+    [ "4.6.17", "Valid Self-Issued pathLenConstraint Test17",            0 ],
+    [ "4.7",    "Key Usage" ],
+    [ "4.7.1",  "Invalid keyUsage Critical keyCertSign False Test1",     20 ],
+    [ "4.7.2",  "Invalid keyUsage Not Critical keyCertSign False Test2", 20 ],
+    [ "4.7.3",  "Valid keyUsage Not Critical Test3",                     0 ],
+    [ "4.7.4",  "Invalid keyUsage Critical cRLSign False Test4",         35 ],
+    [ "4.7.5",  "Invalid keyUsage Not Critical cRLSign False Test5",     35 ],
+
+    # Certificate policy tests need special handling. They can have several
+    # sub tests and we need to check the outputs are correct.
+
+    [ "4.8", "Certificate Policies" ],
+    [
+        "4.8.1.1",
+        "All Certificates Same Policy Test1",
+        "-policy anyPolicy -explicit_policy",
+        "True", $nist1, $nist1, 0
+    ],
+    [
+        "4.8.1.2",
+        "All Certificates Same Policy Test1",
+        "-policy $nist1 -explicit_policy",
+        "True", $nist1, $nist1, 0
+    ],
+    [
+        "4.8.1.3",
+        "All Certificates Same Policy Test1",
+        "-policy $nist2 -explicit_policy",
+        "True", $nist1, "<empty>", 43
+    ],
+    [
+        "4.8.1.4",
+        "All Certificates Same Policy Test1",
+        "-policy $nist1 -policy $nist2 -explicit_policy",
+        "True", $nist1, $nist1, 0
+    ],
+    [
+        "4.8.2.1",
+        "All Certificates No Policies Test2",
+        "-policy anyPolicy",
+        "False", "<empty>", "<empty>", 0
+    ],
+    [
+        "4.8.2.2",
+        "All Certificates No Policies Test2",
+        "-policy anyPolicy -explicit_policy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.8.3.1",
+        "Different Policies Test3",
+        "-policy anyPolicy",
+        "False", "<empty>", "<empty>", 0
+    ],
+    [
+        "4.8.3.2",
+        "Different Policies Test3",
+        "-policy anyPolicy -explicit_policy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.8.3.3",
+        "Different Policies Test3",
+        "-policy $nist1 -policy $nist2 -explicit_policy",
+        "True", "<empty>", "<empty>", 43
+    ],
+
+    [
+        "4.8.4",
+        "Different Policies Test4",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.8.5",
+        "Different Policies Test5",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.8.6.1",
+        "Overlapping Policies Test6",
+        "-policy anyPolicy",
+        "True", $nist1, $nist1, 0
+    ],
+    [
+        "4.8.6.2",
+        "Overlapping Policies Test6",
+        "-policy $nist1",
+        "True", $nist1, $nist1, 0
+    ],
+    [
+        "4.8.6.3",
+        "Overlapping Policies Test6",
+        "-policy $nist2",
+        "True", $nist1, "<empty>", 43
+    ],
+    [
+        "4.8.7",
+        "Different Policies Test7",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.8.8",
+        "Different Policies Test8",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.8.9",
+        "Different Policies Test9",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.8.10.1",
+        "All Certificates Same Policies Test10",
+        "-policy $nist1",
+        "True", "$nist1:$nist2", "$nist1", 0
+    ],
+    [
+        "4.8.10.2",
+        "All Certificates Same Policies Test10",
+        "-policy $nist2",
+        "True", "$nist1:$nist2", "$nist2", 0
+    ],
+    [
+        "4.8.10.3",
+        "All Certificates Same Policies Test10",
+        "-policy anyPolicy",
+        "True", "$nist1:$nist2", "$nist1:$nist2", 0
+    ],
+    [
+        "4.8.11.1",
+        "All Certificates AnyPolicy Test11",
+        "-policy anyPolicy",
+        "True", "$apolicy", "$apolicy", 0
+    ],
+    [
+        "4.8.11.2",
+        "All Certificates AnyPolicy Test11",
+        "-policy $nist1",
+        "True", "$apolicy", "$nist1", 0
+    ],
+    [
+        "4.8.12",
+        "Different Policies Test12",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.8.13.1",
+        "All Certificates Same Policies Test13",
+        "-policy $nist1",
+        "True", "$nist1:$nist2:$nist3", "$nist1", 0
+    ],
+    [
+        "4.8.13.2",
+        "All Certificates Same Policies Test13",
+        "-policy $nist2",
+        "True", "$nist1:$nist2:$nist3", "$nist2", 0
+    ],
+    [
+        "4.8.13.3",
+        "All Certificates Same Policies Test13",
+        "-policy $nist3",
+        "True", "$nist1:$nist2:$nist3", "$nist3", 0
+    ],
+    [
+        "4.8.14.1",       "AnyPolicy Test14",
+        "-policy $nist1", "True",
+        "$nist1",         "$nist1",
+        0
+    ],
+    [
+        "4.8.14.2",       "AnyPolicy Test14",
+        "-policy $nist2", "True",
+        "$nist1",         "<empty>",
+        43
+    ],
+    [
+        "4.8.15",
+        "User Notice Qualifier Test15",
+        "-policy anyPolicy",
+        "False", "$nist1", "$nist1", 0
+    ],
+    [
+        "4.8.16",
+        "User Notice Qualifier Test16",
+        "-policy anyPolicy",
+        "False", "$nist1", "$nist1", 0
+    ],
+    [
+        "4.8.17",
+        "User Notice Qualifier Test17",
+        "-policy anyPolicy",
+        "False", "$nist1", "$nist1", 0
+    ],
+    [
+        "4.8.18.1",
+        "User Notice Qualifier Test18",
+        "-policy $nist1",
+        "True", "$nist1:$nist2", "$nist1", 0
+    ],
+    [
+        "4.8.18.2",
+        "User Notice Qualifier Test18",
+        "-policy $nist2",
+        "True", "$nist1:$nist2", "$nist2", 0
+    ],
+    [
+        "4.8.19",
+        "User Notice Qualifier Test19",
+        "-policy anyPolicy",
+        "False", "$nist1", "$nist1", 0
+    ],
+    [
+        "4.8.20",
+        "CPS Pointer Qualifier Test20",
+        "-policy anyPolicy -explicit_policy",
+        "True", "$nist1", "$nist1", 0
+    ],
+    [ "4.9", "Require Explicit Policy" ],
+    [
+        "4.9.1",
+        "Valid RequireExplicitPolicy Test1",
+        "-policy anyPolicy",
+        "False", "<empty>", "<empty>", 0
+    ],
+    [
+        "4.9.2",
+        "Valid RequireExplicitPolicy Test2",
+        "-policy anyPolicy",
+        "False", "<empty>", "<empty>", 0
+    ],
+    [
+        "4.9.3",
+        "Invalid RequireExplicitPolicy Test3",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.9.4",
+        "Valid RequireExplicitPolicy Test4",
+        "-policy anyPolicy",
+        "True", "$nist1", "$nist1", 0
+    ],
+    [
+        "4.9.5",
+        "Invalid RequireExplicitPolicy Test5",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.9.6",
+        "Valid Self-Issued requireExplicitPolicy Test6",
+        "-policy anyPolicy",
+        "False", "<empty>", "<empty>", 0
+    ],
+    [
+        "4.9.7",
+        "Invalid Self-Issued requireExplicitPolicy Test7",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.9.8",
+        "Invalid Self-Issued requireExplicitPolicy Test8",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [ "4.10", "Policy Mappings" ],
+    [
+        "4.10.1.1",
+        "Valid Policy Mapping Test1",
+        "-policy $nist1",
+        "True", "$nist1", "$nist1", 0
+    ],
+    [
+        "4.10.1.2",
+        "Valid Policy Mapping Test1",
+        "-policy $nist2",
+        "True", "$nist1", "<empty>", 43
+    ],
+    [
+        "4.10.1.3",
+        "Valid Policy Mapping Test1",
+        "-policy anyPolicy -inhibit_map",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.10.2.1",
+        "Invalid Policy Mapping Test2",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.10.2.2",
+        "Invalid Policy Mapping Test2",
+        "-policy anyPolicy -inhibit_map",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.10.3.1",
+        "Valid Policy Mapping Test3",
+        "-policy $nist1",
+        "True", "$nist2", "<empty>", 43
+    ],
+    [
+        "4.10.3.2",
+        "Valid Policy Mapping Test3",
+        "-policy $nist2",
+        "True", "$nist2", "$nist2", 0
+    ],
+    [
+        "4.10.4",
+        "Invalid Policy Mapping Test4",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.10.5.1",
+        "Valid Policy Mapping Test5",
+        "-policy $nist1",
+        "True", "$nist1", "$nist1", 0
+    ],
+    [
+        "4.10.5.2",
+        "Valid Policy Mapping Test5",
+        "-policy $nist6",
+        "True", "$nist1", "<empty>", 43
+    ],
+    [
+        "4.10.6.1",
+        "Valid Policy Mapping Test6",
+        "-policy $nist1",
+        "True", "$nist1", "$nist1", 0
+    ],
+    [
+        "4.10.6.2",
+        "Valid Policy Mapping Test6",
+        "-policy $nist6",
+        "True", "$nist1", "<empty>", 43
+    ],
+    [ "4.10.7", "Invalid Mapping From anyPolicy Test7", 42 ],
+    [ "4.10.8", "Invalid Mapping To anyPolicy Test8",   42 ],
+    [
+        "4.10.9",
+        "Valid Policy Mapping Test9",
+        "-policy anyPolicy",
+        "True", "$nist1", "$nist1", 0
+    ],
+    [
+        "4.10.10",
+        "Invalid Policy Mapping Test10",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.10.11",
+        "Valid Policy Mapping Test11",
+        "-policy anyPolicy",
+        "True", "$nist1", "$nist1", 0
+    ],
+
+    # TODO: check notice display
+    [
+        "4.10.12.1",
+        "Valid Policy Mapping Test12",
+        "-policy $nist1",
+        "True", "$nist1:$nist2", "$nist1", 0
+    ],
+
+    # TODO: check notice display
+    [
+        "4.10.12.2",
+        "Valid Policy Mapping Test12",
+        "-policy $nist2",
+        "True", "$nist1:$nist2", "$nist2", 0
+    ],
+    [
+        "4.10.13",
+        "Valid Policy Mapping Test13",
+        "-policy anyPolicy",
+        "True", "$nist1", "$nist1", 0
+    ],
+
+    # TODO: check notice display
+    [
+        "4.10.14",
+        "Valid Policy Mapping Test14",
+        "-policy anyPolicy",
+        "True", "$nist1", "$nist1", 0
+    ],
+    [ "4.11", "Inhibit Policy Mapping" ],
+    [
+        "4.11.1",
+        "Invalid inhibitPolicyMapping Test1",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.11.2",
+        "Valid inhibitPolicyMapping Test2",
+        "-policy anyPolicy",
+        "True", "$nist1", "$nist1", 0
+    ],
+    [
+        "4.11.3",
+        "Invalid inhibitPolicyMapping Test3",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.11.4",
+        "Valid inhibitPolicyMapping Test4",
+        "-policy anyPolicy",
+        "True", "$nist2", "$nist2", 0
+    ],
+    [
+        "4.11.5",
+        "Invalid inhibitPolicyMapping Test5",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.11.6",
+        "Invalid inhibitPolicyMapping Test6",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.11.7",
+        "Valid Self-Issued inhibitPolicyMapping Test7",
+        "-policy anyPolicy",
+        "True", "$nist1", "$nist1", 0
+    ],
+    [
+        "4.11.8",
+        "Invalid Self-Issued inhibitPolicyMapping Test8",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.11.9",
+        "Invalid Self-Issued inhibitPolicyMapping Test9",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.11.10",
+        "Invalid Self-Issued inhibitPolicyMapping Test10",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.11.11",
+        "Invalid Self-Issued inhibitPolicyMapping Test11",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [ "4.12", "Inhibit Any Policy" ],
+    [
+        "4.12.1",
+        "Invalid inhibitAnyPolicy Test1",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.12.2",
+        "Valid inhibitAnyPolicy Test2",
+        "-policy anyPolicy",
+        "True", "$nist1", "$nist1", 0
+    ],
+    [
+        "4.12.3.1",
+        "inhibitAnyPolicy Test3",
+        "-policy anyPolicy",
+        "True", "$nist1", "$nist1", 0
+    ],
+    [
+        "4.12.3.2",
+        "inhibitAnyPolicy Test3",
+        "-policy anyPolicy -inhibit_any",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.12.4",
+        "Invalid inhibitAnyPolicy Test4",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.12.5",
+        "Invalid inhibitAnyPolicy Test5",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [
+        "4.12.6",
+        "Invalid inhibitAnyPolicy Test6",
+        "-policy anyPolicy",
+        "True", "<empty>", "<empty>", 43
+    ],
+    [ "4.12.7",  "Valid Self-Issued inhibitAnyPolicy Test7",      0 ],
+    [ "4.12.8",  "Invalid Self-Issued inhibitAnyPolicy Test8",    43 ],
+    [ "4.12.9",  "Valid Self-Issued inhibitAnyPolicy Test9",      0 ],
+    [ "4.12.10", "Invalid Self-Issued inhibitAnyPolicy Test10",   43 ],
+    [ "4.13",    "Name Constraints" ],
+    [ "4.13.1",  "Valid DN nameConstraints Test1",                0 ],
+    [ "4.13.2",  "Invalid DN nameConstraints Test2",              47 ],
+    [ "4.13.3",  "Invalid DN nameConstraints Test3",              47 ],
+    [ "4.13.4",  "Valid DN nameConstraints Test4",                0 ],
+    [ "4.13.5",  "Valid DN nameConstraints Test5",                0 ],
+    [ "4.13.6",  "Valid DN nameConstraints Test6",                0 ],
+    [ "4.13.7",  "Invalid DN nameConstraints Test7",              48 ],
+    [ "4.13.8",  "Invalid DN nameConstraints Test8",              48 ],
+    [ "4.13.9",  "Invalid DN nameConstraints Test9",              48 ],
+    [ "4.13.10", "Invalid DN nameConstraints Test10",             48 ],
+    [ "4.13.11", "Valid DN nameConstraints Test11",               0 ],
+    [ "4.13.12", "Invalid DN nameConstraints Test12",             47 ],
+    [ "4.13.13", "Invalid DN nameConstraints Test13",             47 ],
+    [ "4.13.14", "Valid DN nameConstraints Test14",               0 ],
+    [ "4.13.15", "Invalid DN nameConstraints Test15",             48 ],
+    [ "4.13.16", "Invalid DN nameConstraints Test16",             48 ],
+    [ "4.13.17", "Invalid DN nameConstraints Test17",             48 ],
+    [ "4.13.18", "Valid DN nameConstraints Test18",               0 ],
+    [ "4.13.19", "Valid Self-Issued DN nameConstraints Test19",   0 ],
+    [ "4.13.20", "Invalid Self-Issued DN nameConstraints Test20", 47 ],
+    [ "4.13.21", "Valid RFC822 nameConstraints Test21",           0 ],
+    [ "4.13.22", "Invalid RFC822 nameConstraints Test22",         47 ],
+    [ "4.13.23", "Valid RFC822 nameConstraints Test23",           0 ],
+    [ "4.13.24", "Invalid RFC822 nameConstraints Test24",         47 ],
+    [ "4.13.25", "Valid RFC822 nameConstraints Test25",           0 ],
+    [ "4.13.26", "Invalid RFC822 nameConstraints Test26",         48 ],
+    [ "4.13.27", "Valid DN and RFC822 nameConstraints Test27",    0 ],
+    [ "4.13.28", "Invalid DN and RFC822 nameConstraints Test28",  47 ],
+    [ "4.13.29", "Invalid DN and RFC822 nameConstraints Test29",  47 ],
+    [ "4.13.30", "Valid DNS nameConstraints Test30",              0 ],
+    [ "4.13.31", "Invalid DNS nameConstraints Test31",            47 ],
+    [ "4.13.32", "Valid DNS nameConstraints Test32",              0 ],
+    [ "4.13.33", "Invalid DNS nameConstraints Test33",            48 ],
+    [ "4.13.34", "Valid URI nameConstraints Test34",              0 ],
+    [ "4.13.35", "Invalid URI nameConstraints Test35",            47 ],
+    [ "4.13.36", "Valid URI nameConstraints Test36",              0 ],
+    [ "4.13.37", "Invalid URI nameConstraints Test37",            48 ],
+    [ "4.13.38", "Invalid DNS nameConstraints Test38",            47 ],
+    [ "4.14",    "Distribution Points" ],
+    [ "4.14.1",  "Valid distributionPoint Test1",                 0 ],
+    [ "4.14.2",  "Invalid distributionPoint Test2",               23 ],
+    [ "4.14.3",  "Invalid distributionPoint Test3",               44 ],
+    [ "4.14.4",  "Valid distributionPoint Test4",                 0 ],
+    [ "4.14.5",  "Valid distributionPoint Test5",                 0 ],
+    [ "4.14.6",  "Invalid distributionPoint Test6",               23 ],
+    [ "4.14.7",  "Valid distributionPoint Test7",                 0 ],
+    [ "4.14.8",  "Invalid distributionPoint Test8",               44 ],
+    [ "4.14.9",  "Invalid distributionPoint Test9",               44 ],
+    [ "4.14.10", "Valid No issuingDistributionPoint Test10",      0 ],
+    [ "4.14.11", "Invalid onlyContainsUserCerts CRL Test11",      44 ],
+    [ "4.14.12", "Invalid onlyContainsCACerts CRL Test12",        44 ],
+    [ "4.14.13", "Valid onlyContainsCACerts CRL Test13",          0 ],
+    [ "4.14.14", "Invalid onlyContainsAttributeCerts Test14",     44 ],
+    [ "4.14.15", "Invalid onlySomeReasons Test15",                23 ],
+    [ "4.14.16", "Invalid onlySomeReasons Test16",                23 ],
+    [ "4.14.17", "Invalid onlySomeReasons Test17",                3 ],
+    [ "4.14.18", "Valid onlySomeReasons Test18",                  0 ],
+    [ "4.14.19", "Valid onlySomeReasons Test19",                  0 ],
+    [ "4.14.20", "Invalid onlySomeReasons Test20",                23 ],
+    [ "4.14.21", "Invalid onlySomeReasons Test21",                23 ],
+    [ "4.14.22", "Valid IDP with indirectCRL Test22",             0 ],
+    [ "4.14.23", "Invalid IDP with indirectCRL Test23",           23 ],
+    [ "4.14.24", "Valid IDP with indirectCRL Test24",             0 ],
+    [ "4.14.25", "Valid IDP with indirectCRL Test25",             0 ],
+    [ "4.14.26", "Invalid IDP with indirectCRL Test26",           44 ],
+    [ "4.14.27", "Invalid cRLIssuer Test27",                      3 ],
+    [ "4.14.28", "Valid cRLIssuer Test28",                        0 ],
+    [ "4.14.29", "Valid cRLIssuer Test29",                        0 ],
+
+    # Although this test is valid it has a circular dependency. As a result
+    # an attempt is made to reursively checks a CRL path and rejected due to
+    # a CRL path validation error. PKITS notes suggest this test does not
+    # need to be run due to this issue.
+    [ "4.14.30", "Valid cRLIssuer Test30",                                 54 ],
+    [ "4.14.31", "Invalid cRLIssuer Test31",                               23 ],
+    [ "4.14.32", "Invalid cRLIssuer Test32",                               23 ],
+    [ "4.14.33", "Valid cRLIssuer Test33",                                 0 ],
+    [ "4.14.34", "Invalid cRLIssuer Test34",                               23 ],
+    [ "4.14.35", "Invalid cRLIssuer Test35",                               44 ],
+    [ "4.15",    "Delta-CRLs" ],
+    [ "4.15.1",  "Invalid deltaCRLIndicator No Base Test1",                3 ],
+    [ "4.15.2",  "Valid delta-CRL Test2",                                  0 ],
+    [ "4.15.3",  "Invalid delta-CRL Test3",                                23 ],
+    [ "4.15.4",  "Invalid delta-CRL Test4",                                23 ],
+    [ "4.15.5",  "Valid delta-CRL Test5",                                  0 ],
+    [ "4.15.6",  "Invalid delta-CRL Test6",                                23 ],
+    [ "4.15.7",  "Valid delta-CRL Test7",                                  0 ],
+    [ "4.15.8",  "Valid delta-CRL Test8",                                  0 ],
+    [ "4.15.9",  "Invalid delta-CRL Test9",                                23 ],
+    [ "4.15.10", "Invalid delta-CRL Test10",                               12 ],
+    [ "4.16",    "Private Certificate Extensions" ],
+    [ "4.16.1",  "Valid Unknown Not Critical Certificate Extension Test1", 0 ],
+    [ "4.16.2",  "Invalid Unknown Critical Certificate Extension Test2",   34 ],
+);
+
+
+my $verbose = 1;
+
+my $numtest = 0;
+my $numfail = 0;
+
+my $ossl = "ossl/apps/openssl";
+
+my $ossl_cmd = "$ossl_path cms -verify -verify_retcode ";
+$ossl_cmd .= "-CAfile pkitsta.pem -crl_check_all -x509_strict ";
+$ossl_cmd .= "-policy_check -extended_crl -use_deltas -out /dev/null 2>&1 ";
+
+system "$ossl_path x509 -inform DER -in $pkitsta -out pkitsta.pem";
+
+die "Can't create trust anchor file" if $?;
+
+print "Running PKITS tests:\n" if $verbose;
+
+foreach (@testlists) {
+    my $argnum = @$_;
+    if ( $argnum == 2 ) {
+        my ( $tnum, $title ) = @$_;
+        print "$tnum $title\n" if $verbose;
+    }
+    elsif ( $argnum == 3 ) {
+        my ( $tnum, $title, $exp_ret ) = @$_;
+        my $filename = $title;
+        $exp_ret += 32 if $exp_ret;
+        $filename =~ tr/ -//d;
+        $filename = "Signed${filename}.eml";
+        if ( !-f "$pkitsdir/$filename" ) {
+            print "\"$filename\" not found\n";
+        }
+        else {
+            my $ret;
+            my $test_fail = 0;
+            my $errmsg    = "";
+            my $cmd       = $ossl_cmd;
+            $cmd .= "-in $pkitsdir/$filename -policy anyPolicy";
+            my $cmdout = `$cmd`;
+            $ret = $? >> 8;
+            if ( $? & 0xff ) {
+                $errmsg .= "Abnormal OpenSSL termination\n";
+                $test_fail = 1;
+            }
+            if ( $exp_ret != $ret ) {
+                $errmsg .= "Return code:$ret, ";
+                $errmsg .= "expected $exp_ret\n";
+                $test_fail = 1;
+            }
+            if ($test_fail) {
+                print "$tnum $title : Failed!\n";
+                print "Filename: $pkitsdir/$filename\n";
+                print $errmsg;
+                print "Command output:\n$cmdout\n";
+                $numfail++;
+            }
+            $numtest++;
+        }
+    }
+    elsif ( $argnum == 7 ) {
+        my ( $tnum, $title, $exargs, $exp_epol, $exp_aset, $exp_uset, $exp_ret )
+          = @$_;
+        my $filename = $title;
+        $exp_ret += 32 if $exp_ret;
+        $filename =~ tr/ -//d;
+        $filename = "Signed${filename}.eml";
+        if ( !-f "$pkitsdir/$filename" ) {
+            print "\"$filename\" not found\n";
+        }
+        else {
+            my $ret;
+            my $cmdout    = "";
+            my $errmsg    = "";
+            my $epol      = "";
+            my $aset      = "";
+            my $uset      = "";
+            my $pol       = -1;
+            my $test_fail = 0;
+            my $cmd       = $ossl_cmd;
+            $cmd .= "-in $pkitsdir/$filename $exargs -policy_print";
+            @oparr = `$cmd`;
+            $ret   = $? >> 8;
+
+            if ( $? & 0xff ) {
+                $errmsg .= "Abnormal OpenSSL termination\n";
+                $test_fail = 1;
+            }
+            foreach (@oparr) {
+                my $test_failed = 0;
+                $cmdout .= $_;
+                if (/^Require explicit Policy: (.*)$/) {
+                    $epol = $1;
+                }
+                if (/^Authority Policies/) {
+                    if (/empty/) {
+                        $aset = "<empty>";
+                    }
+                    else {
+                        $pol = 1;
+                    }
+                }
+                $test_fail = 1 if (/leak/i);
+                if (/^User Policies/) {
+                    if (/empty/) {
+                        $uset = "<empty>";
+                    }
+                    else {
+                        $pol = 2;
+                    }
+                }
+                if (/\s+Policy: (.*)$/) {
+                    if ( $pol == 1 ) {
+                        $aset .= ":" if $aset ne "";
+                        $aset .= $1;
+                    }
+                    elsif ( $pol == 2 ) {
+                        $uset .= ":" if $uset ne "";
+                        $uset .= $1;
+                    }
+                }
+            }
+
+            if ( $epol ne $exp_epol ) {
+                $errmsg .= "Explicit policy:$epol, ";
+                $errmsg .= "expected $exp_epol\n";
+                $test_fail = 1;
+            }
+            if ( $aset ne $exp_aset ) {
+                $errmsg .= "Authority policy set :$aset, ";
+                $errmsg .= "expected $exp_aset\n";
+                $test_fail = 1;
+            }
+            if ( $uset ne $exp_uset ) {
+                $errmsg .= "User policy set :$uset, ";
+                $errmsg .= "expected $exp_uset\n";
+                $test_fail = 1;
+            }
+
+            if ( $exp_ret != $ret ) {
+                print "Return code:$ret, expected $exp_ret\n";
+                $test_fail = 1;
+            }
+
+            if ($test_fail) {
+                print "$tnum $title : Failed!\n";
+                print "Filename: $pkitsdir/$filename\n";
+                print "Command output:\n$cmdout\n";
+                $numfail++;
+            }
+            $numtest++;
+        }
+    }
+}
+
+if ($numfail) {
+    print "$numfail tests failed out of $numtest\n";
+}
+else {
+    print "All Tests Successful.\n";
+}
+
+unlink "pkitsta.pem";
+
diff --git a/openssl/test/r160test.c b/openssl/test/r160test.c
new file mode 100644
index 0000000..a172e39
--- /dev/null
+++ b/openssl/test/r160test.c
@@ -0,0 +1,57 @@
+/* test/r160test.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
diff --git a/openssl/test/randtest.c b/openssl/test/randtest.c
new file mode 120000
index 0000000..a2b107a
--- /dev/null
+++ b/openssl/test/randtest.c
@@ -0,0 +1 @@
+../crypto/rand/randtest.c
\ No newline at end of file
diff --git a/openssl/test/rc2test.c b/openssl/test/rc2test.c
new file mode 120000
index 0000000..5c53ad9
--- /dev/null
+++ b/openssl/test/rc2test.c
@@ -0,0 +1 @@
+../crypto/rc2/rc2test.c
\ No newline at end of file
diff --git a/openssl/test/rc4test.c b/openssl/test/rc4test.c
new file mode 120000
index 0000000..061ac37
--- /dev/null
+++ b/openssl/test/rc4test.c
@@ -0,0 +1 @@
+../crypto/rc4/rc4test.c
\ No newline at end of file
diff --git a/openssl/test/rc5test.c b/openssl/test/rc5test.c
new file mode 120000
index 0000000..49f44f8
--- /dev/null
+++ b/openssl/test/rc5test.c
@@ -0,0 +1 @@
+dummytest.c
\ No newline at end of file
diff --git a/openssl/test/rmdtest.c b/openssl/test/rmdtest.c
new file mode 120000
index 0000000..ce66460
--- /dev/null
+++ b/openssl/test/rmdtest.c
@@ -0,0 +1 @@
+../crypto/ripemd/rmdtest.c
\ No newline at end of file
diff --git a/openssl/test/rsa_test.c b/openssl/test/rsa_test.c
new file mode 120000
index 0000000..aaea20d
--- /dev/null
+++ b/openssl/test/rsa_test.c
@@ -0,0 +1 @@
+../crypto/rsa/rsa_test.c
\ No newline at end of file
diff --git a/openssl/test/sha1test.c b/openssl/test/sha1test.c
new file mode 120000
index 0000000..8d66e9e
--- /dev/null
+++ b/openssl/test/sha1test.c
@@ -0,0 +1 @@
+../crypto/sha/sha1test.c
\ No newline at end of file
diff --git a/openssl/test/sha256t.c b/openssl/test/sha256t.c
new file mode 120000
index 0000000..952a508
--- /dev/null
+++ b/openssl/test/sha256t.c
@@ -0,0 +1 @@
+../crypto/sha/sha256t.c
\ No newline at end of file
diff --git a/openssl/test/sha512t.c b/openssl/test/sha512t.c
new file mode 120000
index 0000000..c80d152
--- /dev/null
+++ b/openssl/test/sha512t.c
@@ -0,0 +1 @@
+../crypto/sha/sha512t.c
\ No newline at end of file
diff --git a/openssl/test/shatest.c b/openssl/test/shatest.c
new file mode 120000
index 0000000..43cfda7
--- /dev/null
+++ b/openssl/test/shatest.c
@@ -0,0 +1 @@
+../crypto/sha/shatest.c
\ No newline at end of file
diff --git a/openssl/test/smcont.txt b/openssl/test/smcont.txt
new file mode 100644
index 0000000..e837c0b
--- /dev/null
+++ b/openssl/test/smcont.txt
@@ -0,0 +1 @@
+Some test content for OpenSSL CMS
\ No newline at end of file
diff --git a/openssl/test/smime-certs/smdsa1.pem b/openssl/test/smime-certs/smdsa1.pem
new file mode 100644
index 0000000..d5677db
--- /dev/null
+++ b/openssl/test/smime-certs/smdsa1.pem
@@ -0,0 +1,34 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
+OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
+GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
+jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
+wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
++FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
+SJCBQw5zAoGATQlPPF+OeU8nu3rsdXGDiZdJzOkuCce3KQfTABA9C+Dk4CVcvBdd
+YRLGpnykumkNTO1sTO+4/Gphsuje1ujK9td4UEhdYqylCe5QjEMrszDlJtelDQF9
+C0yhdjKGTP0kxofLhsGckcuQvcKEKffT2pDDKJIy4vWQO0UyJl1vjLcCFG2uiGGx
+9fMUZq1v0ePD4Wo0Xkxo
+-----END DSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDpDCCAw2gAwIBAgIJAMtotfHYdEsWMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
+TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
+CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+ZXN0IFMvTUlNRSBFRSBEU0EgIzEwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
+CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
+mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
+jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
+CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
+kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
+xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhAACgYBN
+CU88X455Tye7eux1cYOJl0nM6S4Jx7cpB9MAED0L4OTgJVy8F11hEsamfKS6aQ1M
+7WxM77j8amGy6N7W6Mr213hQSF1irKUJ7lCMQyuzMOUm16UNAX0LTKF2MoZM/STG
+h8uGwZyRy5C9woQp99PakMMokjLi9ZA7RTImXW+Mt6OBgzCBgDAdBgNVHQ4EFgQU
+4Qfbhpi5yqXaXuCLXj427mR25MkwHwYDVR0jBBgwFoAUE89Lp7uJLrM4Vxd2xput
+aFvl7RcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBsAwIAYDVR0RBBkwF4EV
+c21pbWVkc2ExQG9wZW5zc2wub3JnMA0GCSqGSIb3DQEBBQUAA4GBAFrdUzKK1pWO
+kd02S423KUBc4GWWyiGlVoEO7WxVhHLJ8sm67X7OtJOwe0UGt+Nc5qLtyJYSirw8
+phjiTdNpQCTJ8+Kc56tWkJ6H7NAI4vTJtPL5BM/EmeYrVSU9JI9xhqpyKw9IBD+n
+hRJ79W9FaiJRvaAOX+TkyTukJrxAWRyv
+-----END CERTIFICATE-----
diff --git a/openssl/test/smime-certs/smdsa2.pem b/openssl/test/smime-certs/smdsa2.pem
new file mode 100644
index 0000000..ef86c11
--- /dev/null
+++ b/openssl/test/smime-certs/smdsa2.pem
@@ -0,0 +1,34 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
+OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
+GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
+jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
+wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
++FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
+SJCBQw5zAoGBAIPmO8BtJ+Yac58trrPwq9b/6VW3jQTWzTLWSH84/QQdqQa+Pz3v
+It/+hHM0daNF5uls8ICsPL1aLXmRx0pHvIyb0aAzYae4T4Jv/COPDMTdKbA1uitJ
+VbkGZrm+LIrs7I9lOkb4T0vI6kL/XdOCXY1469zsqCgJ/O2ibn6mq0nWAhR716o2
+Nf8SimTZYB0/CKje6M5ufA==
+-----END DSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDpTCCAw6gAwIBAgIJAMtotfHYdEsXMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
+TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
+CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+ZXN0IFMvTUlNRSBFRSBEU0EgIzIwggG4MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
+CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
+mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
+jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
+CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
+kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
+xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhQACgYEA
+g+Y7wG0n5hpzny2us/Cr1v/pVbeNBNbNMtZIfzj9BB2pBr4/Pe8i3/6EczR1o0Xm
+6WzwgKw8vVoteZHHSke8jJvRoDNhp7hPgm/8I48MxN0psDW6K0lVuQZmub4siuzs
+j2U6RvhPS8jqQv9d04JdjXjr3OyoKAn87aJufqarSdajgYMwgYAwHQYDVR0OBBYE
+FHsAGNfVltSYUq4hC+YVYwsYtA+dMB8GA1UdIwQYMBaAFBPPS6e7iS6zOFcXdsab
+rWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgbAMCAGA1UdEQQZMBeB
+FXNtaW1lZHNhMkBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQCx9BtCbaYF
+FXjLClkuKXbESaDZA1biPgY25i00FsUzARuhCpqD2v+0tu5c33ZzIhL6xlvBRU5l
+6Atw/xpZhae+hdBEtxPJoGekLLrHOau7Md3XwDjV4lFgcEJkWZoaSOOIK+4D5jF0
+jZWtHjnwEzuLYlo7ScHSsbcQfjH0M1TP5A==
+-----END CERTIFICATE-----
diff --git a/openssl/test/smime-certs/smdsa3.pem b/openssl/test/smime-certs/smdsa3.pem
new file mode 100644
index 0000000..eeb848d
--- /dev/null
+++ b/openssl/test/smime-certs/smdsa3.pem
@@ -0,0 +1,34 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
+OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
+GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
+jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
+wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
++FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
+SJCBQw5zAoGAYzOpPmh8Je1IDauEXhgaLz14wqYUHHcrj2VWVJ6fRm8GhdQFJSI7
+GUk08pgKZSKic2lNqxuzW7/vFxKQ/nvzfytY16b+2i+BR4Q6yvMzCebE1hHVg0Ju
+TwfUMwoFEOhYP6ZwHSUiQl9IBMH9TNJCMwYMxfY+VOrURFsjGTRUgpwCFQCIGt5g
+Y+XZd0Sv69CatDIRYWvaIA==
+-----END DSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDpDCCAw2gAwIBAgIJAMtotfHYdEsYMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
+TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
+CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+ZXN0IFMvTUlNRSBFRSBEU0EgIzMwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
+CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
+mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
+jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
+CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
+kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
+xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhAACgYBj
+M6k+aHwl7UgNq4ReGBovPXjCphQcdyuPZVZUnp9GbwaF1AUlIjsZSTTymAplIqJz
+aU2rG7Nbv+8XEpD+e/N/K1jXpv7aL4FHhDrK8zMJ5sTWEdWDQm5PB9QzCgUQ6Fg/
+pnAdJSJCX0gEwf1M0kIzBgzF9j5U6tREWyMZNFSCnKOBgzCBgDAdBgNVHQ4EFgQU
+VhpVXqQ/EzUMdxLvP7o9EhJ8h70wHwYDVR0jBBgwFoAUE89Lp7uJLrM4Vxd2xput
+aFvl7RcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBsAwIAYDVR0RBBkwF4EV
+c21pbWVkc2EzQG9wZW5zc2wub3JnMA0GCSqGSIb3DQEBBQUAA4GBACM9e75EQa8m
+k/AZkH/tROqf3yeqijULl9x8FjFatqoY+29OM6oMGM425IqSkKd2ipz7OxO0SShu
+rE0O3edS7DvYBwvhWPviRaYBMyZ4iFJVup+fOzoYK/j/bASxS3BHQBwb2r4rhe25
+OlTyyFEk7DJyW18YFOG97S1P52oQ5f5x
+-----END CERTIFICATE-----
diff --git a/openssl/test/smime-certs/smdsap.pem b/openssl/test/smime-certs/smdsap.pem
new file mode 100644
index 0000000..249706c
--- /dev/null
+++ b/openssl/test/smime-certs/smdsap.pem
@@ -0,0 +1,9 @@
+-----BEGIN DSA PARAMETERS-----
+MIIBHwKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3OjSG
+Lh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqtGcoA
+gsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2Jjt+d
+qk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qtwjqv
+Wp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK+FMO
+GnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4ZSJCB
+Qw5z
+-----END DSA PARAMETERS-----
diff --git a/openssl/test/smime-certs/smroot.pem b/openssl/test/smime-certs/smroot.pem
new file mode 100644
index 0000000..a59eb26
--- /dev/null
+++ b/openssl/test/smime-certs/smroot.pem
@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQDBV1Z/Q5gPF7lojc8pKUdyz5+Jf2B3vs4he6egekugWnoJduki
+9Lnae/JchB/soIX0co3nLc11NuFFlnAWJNMDJr08l5AHAJLYNHevF5l/f9oDQwvZ
+speKh1xpIAJNqCTzVeQ/ZLx6/GccIXV/xDuKIiovqJTPgR5WPkYKaw++lQIDAQAB
+AoGALXnUj5SflJU4+B2652ydMKUjWl0KnL/VjkyejgGV/j6py8Ybaixz9q8Gv7oY
+JDlRqMC1HfZJCFQDQrHy5VJ+CywA/H9WrqKo/Ch9U4tJAZtkig1Cmay/BAYixVu0
+xBeim10aKF6hxHH4Chg9We+OCuzWBWJhqveNjuDedL/i7JUCQQDlejovcwBUCbhJ
+U12qKOwlaboolWbl7yF3XdckTJZg7+1UqQHZH5jYZlLZyZxiaC92SNV0SyTLJZnS
+Jh5CO+VDAkEA16/pPcuVtMMz/R6SSPpRSIAa1stLs0mFSs3NpR4pdm0n42mu05pO
+1tJEt3a1g7zkreQBf53+Dwb+lA841EkjRwJBAIFmt0DifKDnCkBu/jZh9SfzwsH3
+3Zpzik+hXxxdA7+ODCrdUul449vDd5zQD5t+XKU61QNLDGhxv5e9XvrCg7kCQH/a
+3ldsVF0oDaxxL+QkxoREtCQ5tLEd1u7F2q6Tl56FDE0pe6Ih6bQ8RtG+g9EI60IN
+U7oTrOO5kLWx5E0q4ccCQAZVgoenn9MhRU1agKOCuM6LT2DxReTu4XztJzynej+8
+0J93n3ebanB1MlRpn1XJwhQ7gAC8ImaQKLJK5jdJzFc=
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIICaTCCAdKgAwIBAgIJAP6VN47boiXRMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
+TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDdaFw0xNjA1MTExMzUzMDdaMEQx
+CzAJBgNVBAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRU
+ZXN0IFMvTUlNRSBSU0EgUm9vdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
+wVdWf0OYDxe5aI3PKSlHcs+fiX9gd77OIXunoHpLoFp6CXbpIvS52nvyXIQf7KCF
+9HKN5y3NdTbhRZZwFiTTAya9PJeQBwCS2DR3rxeZf3/aA0ML2bKXiodcaSACTagk
+81XkP2S8evxnHCF1f8Q7iiIqL6iUz4EeVj5GCmsPvpUCAwEAAaNjMGEwHQYDVR0O
+BBYEFBPPS6e7iS6zOFcXdsabrWhb5e0XMB8GA1UdIwQYMBaAFBPPS6e7iS6zOFcX
+dsabrWhb5e0XMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqG
+SIb3DQEBBQUAA4GBAIECprq5viDvnDbkyOaiSr9ubMUmWqvycfAJMdPZRKcOZczS
+l+L9R9lF3JSqbt3knOe9u6bGDBOTY2285PdCCuHRVMk2Af1f6El1fqAlRUwNqipp
+r68sWFuRqrcRNtk6QQvXfkOhrqQBuDa7te/OVQLa2lGN9Dr2mQsD8ijctatG
+-----END CERTIFICATE-----
diff --git a/openssl/test/smime-certs/smrsa1.pem b/openssl/test/smime-certs/smrsa1.pem
new file mode 100644
index 0000000..2cf3148
--- /dev/null
+++ b/openssl/test/smime-certs/smrsa1.pem
@@ -0,0 +1,31 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQC6A978j4pmPgUtUQqF+bjh6vdhwGOGZSD7xXgFTMjm88twfv+E
+ixkq2KXSDjD0ZXoQbdOaSbvGRQrIJpG2NGiKAFdYNrP025kCCdh5wF/aEI7KLEm7
+JlHwXpQsuj4wkMgmkFjL3Ty4Z55aNH+2pPQIa0k+ENJXm2gDuhqgBmduAwIDAQAB
+AoGBAJMuYu51aO2THyeHGwt81uOytcCbqGP7eoib62ZOJhxPRGYjpmuqX+R9/V5i
+KiwGavm63JYUx0WO9YP+uIZxm1BUATzkgkS74u5LP6ajhkZh6/Bck1oIYYkbVOXl
+JVrdENuH6U7nupznsyYgONByo+ykFPVUGmutgiaC7NMVo/MxAkEA6KLejWXdCIEn
+xr7hGph9NlvY9xuRIMexRV/WrddcFfCdjI1PciIupgrIkR65M9yr7atm1iU6/aRf
+KOr8rLZsSQJBAMyyXN71NsDNx4BP6rtJ/LJMP0BylznWkA7zWfGCbAYn9VhZVlSY
+Eu9Gyr7quD1ix7G3kInKVYOEEOpockBLz+sCQQCedyMmKjcQLfpMVYW8uhbAynvW
+h36qV5yXZxszO7nMcCTBsxhk5IfmLv5EbCs3+p9avCDGyoGOeUMg+kC33WORAkAg
+oUIarH4o5+SoeJTTfCzTA0KF9H5U0vYt2+73h7HOnWoHxl3zqDZEfEVvf50U8/0f
+QELDJETTbScBJtsnkq43AkEA38etvoZ2i4FJvvo7R/9gWBHVEcrGzcsCBYrNnIR1
+SZLRwHEGaiOK1wxMsWzqp7PJwL9z/M8A8DyOFBx3GPOniA==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIICizCCAfSgAwIBAgIJAMtotfHYdEsTMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
+TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDhaFw0xNjA1MTAxMzUzMDhaMEUx
+CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+ZXN0IFMvTUlNRSBFRSBSU0EgIzEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
+ALoD3vyPimY+BS1RCoX5uOHq92HAY4ZlIPvFeAVMyObzy3B+/4SLGSrYpdIOMPRl
+ehBt05pJu8ZFCsgmkbY0aIoAV1g2s/TbmQIJ2HnAX9oQjsosSbsmUfBelCy6PjCQ
+yCaQWMvdPLhnnlo0f7ak9AhrST4Q0lebaAO6GqAGZ24DAgMBAAGjgYMwgYAwHQYD
+VR0OBBYEFE2vMvKz5jrC7Lbdg68XwZ95iL/QMB8GA1UdIwQYMBaAFBPPS6e7iS6z
+OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
+EQQZMBeBFXNtaW1lcnNhMUBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQAi
+O3GOkUl646oLnOimc36i9wxZ1tejsqs8vMjJ0Pym6Uq9FE2JoGzJ6OhB1GOsEVmj
+9cQ5UNQcRYL3cqOFtl6f4Dpu/lhzfbaqgmLjv29G1mS0uuTZrixhlyCXjwcbOkNC
+I/+wvHHENYIK5+T/79M9LaZ2Qk4F9MNE1VMljdz9Qw==
+-----END CERTIFICATE-----
diff --git a/openssl/test/smime-certs/smrsa2.pem b/openssl/test/smime-certs/smrsa2.pem
new file mode 100644
index 0000000..d41f69c
--- /dev/null
+++ b/openssl/test/smime-certs/smrsa2.pem
@@ -0,0 +1,31 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICWwIBAAKBgQCwBfryW4Vu5U9wNIDKspJO/N9YF4CcTlrCUyzVlKgb+8urHlSe
+59i5verR9IOCCXkemjOzZ/3nALTGqYZlnEvHp0Rjk+KdKXnKBIB+SRPpeu3LcXMT
+WPgsThPa0UQxedNKG0g6aG+kLhsDlFBCoxd09jJtSpb9jmroJOq0ZYEHLwIDAQAB
+AoGAKa/w4677Je1W5+r3SYoLDnvi5TkDs4D3C6ipKJgBTEdQz+DqB4w/DpZE4551
++rkFn1LDxcxuHGRVa+tAMhZW97fwq9YUbjVZEyOz79qrX+BMyl/NbHkf1lIKDo3q
+dWalzQvop7nbzeLC+VmmviwZfLQUbA61AQl3jm4dswT4XykCQQDloDadEv/28NTx
+bvvywvyGuvJkCkEIycm4JrIInvwsd76h/chZ3oymrqzc7hkEtK6kThqlS5y+WXl6
+QzPruTKTAkEAxD2ro/VUoN+scIVaLmn0RBmZ67+9Pdn6pNSfjlK3s0T0EM6/iUWS
+M06l6L9wFS3/ceu1tIifsh9BeqOGTa+udQJARIFnybTBaIqw/NZ/lA1YCVn8tpvY
+iyaoZ6gjtS65TQrsdKeh/i3HCHNUXxUpoZ3F/H7QtD+6o49ODou+EbVOwQJAVmex
+A2gp8wuJKaINqxIL81AybZLnCCzKJ3lXJ5tUNyLNM/lUbGStktm2Q1zHRQwTxV07
+jFn7trn8YrtNjzcjYQJAUKIJRt38A8Jw3HoPT+D0WS2IgxjVL0eYGsZX1lyeammG
+6rfnQ3u5uP7mEK2EH2o8mDUpAE0gclWBU9UkKxJsGA==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIICizCCAfSgAwIBAgIJAMtotfHYdEsUMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
+TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDhaFw0xNjA1MTAxMzUzMDhaMEUx
+CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+ZXN0IFMvTUlNRSBFRSBSU0EgIzIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
+ALAF+vJbhW7lT3A0gMqykk7831gXgJxOWsJTLNWUqBv7y6seVJ7n2Lm96tH0g4IJ
+eR6aM7Nn/ecAtMaphmWcS8enRGOT4p0pecoEgH5JE+l67ctxcxNY+CxOE9rRRDF5
+00obSDpob6QuGwOUUEKjF3T2Mm1Klv2Oaugk6rRlgQcvAgMBAAGjgYMwgYAwHQYD
+VR0OBBYEFIL/u+mEvaw7RuKLRuElfVkxSQjYMB8GA1UdIwQYMBaAFBPPS6e7iS6z
+OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
+EQQZMBeBFXNtaW1lcnNhMkBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQC2
+rXR5bm/9RtOMQPleNpd3y6uUX3oy+0CafK5Yl3PMnItjjnKJ0l1/DbLbDj2twehe
+ewaB8CROcBCA3AMLSmGvPKgUCFMGtWam3328M4fBHzon5ka7qDXzM+imkAly/Yx2
+YNdR/aNOug+5sXygHmTSKqiCpQjOIClzXoPVVeEVHw==
+-----END CERTIFICATE-----
diff --git a/openssl/test/smime-certs/smrsa3.pem b/openssl/test/smime-certs/smrsa3.pem
new file mode 100644
index 0000000..c8cbe55
--- /dev/null
+++ b/openssl/test/smime-certs/smrsa3.pem
@@ -0,0 +1,31 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQC6syTZtZNe1hRScFc4PUVyVLsr7+C1HDIZnOHmwFoLayX6RHwy
+ep/TkdwiPHnemVLuwvpSjLMLZkXy/J764kSHJrNeVl3UvmCVCOm40hAtK1+F39pM
+h8phkbPPD7i+hwq4/Vs79o46nzwbVKmzgoZBJhZ+codujUSYM3LjJ4aq+wIDAQAB
+AoGAE1Zixrnr3bLGwBMqtYSDIOhtyos59whImCaLr17U9MHQWS+mvYO98if1aQZi
+iQ/QazJ+wvYXxWJ+dEB+JvYwqrGeuAU6He/rAb4OShG4FPVU2D19gzRnaButWMeT
+/1lgXV08hegGBL7RQNaN7b0viFYMcKnSghleMP0/q+Y/oaECQQDkXEwDYJW13X9p
+ijS20ykWdY5lLknjkHRhhOYux0rlhOqsyMZjoUmwI2m0qj9yrIysKhrk4MZaM/uC
+hy0xp3hdAkEA0Uv/UY0Kwsgc+W6YxeypECtg1qCE6FBib8n4iFy/6VcWqhvE5xrs
+OdhKv9/p6aLjLneGd1sU+F8eS9LGyKIbNwJBAJPgbNzXA7uUZriqZb5qeTXxBDfj
+RLfXSHYKAKEULxz3+JvRHB9SR4yHMiFrCdExiZrHXUkPgYLSHLGG5a4824UCQD6T
+9XvhquUARkGCAuWy0/3Eqoihp/t6BWSdQ9Upviu7YUhtUxsyXo0REZB7F4pGrJx5
+GlhXgFaewgUzuUHFzlMCQCzJMMWslWpoLntnR6sMhBMhBFHSw+Y5CbxBmFrdtSkd
+VdtNO1VuDCTxjjW7W3Khj7LX4KZ1ye/5jfAgnnnXisc=
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIICizCCAfSgAwIBAgIJAMtotfHYdEsVMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
+TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
+CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+ZXN0IFMvTUlNRSBFRSBSU0EgIzMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
+ALqzJNm1k17WFFJwVzg9RXJUuyvv4LUcMhmc4ebAWgtrJfpEfDJ6n9OR3CI8ed6Z
+Uu7C+lKMswtmRfL8nvriRIcms15WXdS+YJUI6bjSEC0rX4Xf2kyHymGRs88PuL6H
+Crj9Wzv2jjqfPBtUqbOChkEmFn5yh26NRJgzcuMnhqr7AgMBAAGjgYMwgYAwHQYD
+VR0OBBYEFDsSFjNtYZzd0tTHafNS7tneQQj6MB8GA1UdIwQYMBaAFBPPS6e7iS6z
+OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
+EQQZMBeBFXNtaW1lcnNhM0BvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQBE
+tUDB+1Dqigu4p1xtdq7JRK6S+gfA7RWmhz0j2scb2zhpS12h37JLHsidGeKAzZYq
+jUjOrH/j3xcV5AnuJoqImJaN23nzzxtR4qGGX2mrq6EtObzdEGgCUaizsGM+0slJ
+PYxcy8KeY/63B1BpYhj2RjGkL6HrvuAaxVORa3acoA==
+-----END CERTIFICATE-----
diff --git a/openssl/test/ssltest.c b/openssl/test/ssltest.c
new file mode 120000
index 0000000..40191f0
--- /dev/null
+++ b/openssl/test/ssltest.c
@@ -0,0 +1 @@
+../ssl/ssltest.c
\ No newline at end of file
diff --git a/openssl/test/tcrl b/openssl/test/tcrl
new file mode 100644
index 0000000..055269e
--- /dev/null
+++ b/openssl/test/tcrl
@@ -0,0 +1,78 @@
+#!/bin/sh
+
+cmd='../util/shlib_wrap.sh ../apps/openssl crl'
+
+if [ "$1"x != "x" ]; then
+	t=$1
+else
+	t=testcrl.pem
+fi
+
+echo testing crl conversions
+cp $t fff.p
+
+echo "p -> d"
+$cmd -in fff.p -inform p -outform d >f.d
+if [ $? != 0 ]; then exit 1; fi
+#echo "p -> t"
+#$cmd -in fff.p -inform p -outform t >f.t
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in fff.p -inform p -outform p >f.p
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> d"
+$cmd -in f.d -inform d -outform d >ff.d1
+if [ $? != 0 ]; then exit 1; fi
+#echo "t -> d"
+#$cmd -in f.t -inform t -outform d >ff.d2
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> d"
+$cmd -in f.p -inform p -outform d >ff.d3
+if [ $? != 0 ]; then exit 1; fi
+
+#echo "d -> t"
+#$cmd -in f.d -inform d -outform t >ff.t1
+#if [ $? != 0 ]; then exit 1; fi
+#echo "t -> t"
+#$cmd -in f.t -inform t -outform t >ff.t2
+#if [ $? != 0 ]; then exit 1; fi
+#echo "p -> t"
+#$cmd -in f.p -inform p -outform t >ff.t3
+#if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> p"
+$cmd -in f.d -inform d -outform p >ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#echo "t -> p"
+#$cmd -in f.t -inform t -outform p >ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in f.p -inform p -outform p >ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp fff.p f.p
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#cmp fff.p ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+#cmp f.t ff.t1
+#if [ $? != 0 ]; then exit 1; fi
+#cmp f.t ff.t2
+#if [ $? != 0 ]; then exit 1; fi
+#cmp f.t ff.t3
+#if [ $? != 0 ]; then exit 1; fi
+
+cmp f.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#cmp f.p ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+cmp f.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+/bin/rm -f f.* ff.* fff.*
+exit 0
diff --git a/openssl/test/tcrl.com b/openssl/test/tcrl.com
new file mode 100644
index 0000000..dd96a2b
--- /dev/null
+++ b/openssl/test/tcrl.com
@@ -0,0 +1,88 @@
+$! TCRL.COM  --  Tests crl keys
+$
+$	__arch = "VAX"
+$	if f$getsyi("cpu") .ge. 128 then -
+	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$	if __arch .eqs. "" then __arch = "UNK"
+$!
+$	if (p2 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$	cmd = "mcr ''exe_dir'openssl crl"
+$
+$	t = "testcrl.pem"
+$	if p1 .nes. "" then t = p1
+$
+$	write sys$output "testing CRL conversions"
+$	if f$search("fff.*") .nes "" then delete fff.*;*
+$	if f$search("ff.*") .nes "" then delete ff.*;*
+$	if f$search("f.*") .nes "" then delete f.*;*
+$	convert/fdl=sys$input: 't' fff.p
+RECORD
+	FORMAT STREAM_LF
+$
+$	write sys$output "p -> d"
+$	'cmd' -in fff.p -inform p -outform d -out f.d
+$	if $severity .ne. 1 then exit 3
+$!	write sys$output "p -> t"
+$!	'cmd' -in fff.p -inform p -outform t -out f.t
+$!	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> p"
+$	'cmd' -in fff.p -inform p -outform p -out f.p
+$	if $severity .ne. 1 then exit 3
+$
+$	write sys$output "d -> d"
+$	'cmd' -in f.d -inform d -outform d -out ff.d1
+$	if $severity .ne. 1 then exit 3
+$!	write sys$output "t -> d"
+$!	'cmd' -in f.t -inform t -outform d -out ff.d2
+$!	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> d"
+$	'cmd' -in f.p -inform p -outform d -out ff.d3
+$	if $severity .ne. 1 then exit 3
+$
+$!	write sys$output "d -> t"
+$!	'cmd' -in f.d -inform d -outform t -out ff.t1
+$!	if $severity .ne. 1 then exit 3
+$!	write sys$output "t -> t"
+$!	'cmd' -in f.t -inform t -outform t -out ff.t2
+$!	if $severity .ne. 1 then exit 3
+$!	write sys$output "p -> t"
+$!	'cmd' -in f.p -inform p -outform t -out ff.t3
+$!	if $severity .ne. 1 then exit 3
+$
+$	write sys$output "d -> p"
+$	'cmd' -in f.d -inform d -outform p -out ff.p1
+$	if $severity .ne. 1 then exit 3
+$!	write sys$output "t -> p"
+$!	'cmd' -in f.t -inform t -outform p -out ff.p2
+$!	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> p"
+$	'cmd' -in f.p -inform p -outform p -out ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$	backup/compare fff.p f.p
+$	if $severity .ne. 1 then exit 3
+$	backup/compare fff.p ff.p1
+$	if $severity .ne. 1 then exit 3
+$!	backup/compare fff.p ff.p2
+$!	if $severity .ne. 1 then exit 3
+$	backup/compare fff.p ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$!	backup/compare f.t ff.t1
+$!	if $severity .ne. 1 then exit 3
+$!	backup/compare f.t ff.t2
+$!	if $severity .ne. 1 then exit 3
+$!	backup/compare f.t ff.t3
+$!	if $severity .ne. 1 then exit 3
+$
+$	backup/compare f.p ff.p1
+$	if $severity .ne. 1 then exit 3
+$!	backup/compare f.p ff.p2
+$!	if $severity .ne. 1 then exit 3
+$	backup/compare f.p ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$	delete f.*;*,ff.*;*,fff.*;*
diff --git a/openssl/test/test.cnf b/openssl/test/test.cnf
new file mode 100644
index 0000000..faad391
--- /dev/null
+++ b/openssl/test/test.cnf
@@ -0,0 +1,88 @@
+#
+# SSLeay example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+RANDFILE		= ./.rnd
+
+####################################################################
+[ ca ]
+default_ca	= CA_default		# The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir		= ./demoCA		# Where everything is kept
+certs		= $dir/certs		# Where the issued certs are kept
+crl_dir		= $dir/crl		# Where the issued crl are kept
+database	= $dir/index.txt	# database index file.
+new_certs_dir	= $dir/new_certs	# default place for new certs.
+
+certificate	= $dir/CAcert.pem 	# The CA certificate
+serial		= $dir/serial 		# The current serial number
+crl		= $dir/crl.pem 		# The current CRL
+private_key	= $dir/private/CAkey.pem# The private key
+RANDFILE	= $dir/private/.rand	# private random number file
+
+default_days	= 365			# how long to certify for
+default_crl_days= 30			# how long before next CRL
+default_md	= md5			# which md to use.
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy		= policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName		= match
+stateOrProvinceName	= match
+organizationName	= match
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName		= optional
+stateOrProvinceName	= optional
+localityName		= optional
+organizationName	= optional
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+####################################################################
+[ req ]
+default_bits		= 512
+default_keyfile 	= testkey.pem
+distinguished_name	= req_distinguished_name
+encrypt_rsa_key		= no
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= AU
+countryName_value		= AU
+
+stateOrProvinceName		= State or Province Name (full name)
+stateOrProvinceName_default	= Queensland
+stateOrProvinceName_value	=
+
+localityName			= Locality Name (eg, city)
+localityName_value		= Brisbane
+
+organizationName		= Organization Name (eg, company)
+organizationName_default	= 
+organizationName_value		= CryptSoft Pty Ltd
+
+organizationalUnitName		= Organizational Unit Name (eg, section)
+organizationalUnitName_default	=
+organizationalUnitName_value	= .
+
+commonName			= Common Name (eg, YOUR name)
+commonName_value		= Eric Young
+
+emailAddress			= Email Address
+emailAddress_value		= eay@mincom.oz.au
diff --git a/openssl/test/test_padlock b/openssl/test/test_padlock
new file mode 100644
index 0000000..5c0f210
--- /dev/null
+++ b/openssl/test/test_padlock
@@ -0,0 +1,64 @@
+#!/bin/sh
+
+PROG=$1
+
+if [ -x $PROG ]; then
+    if expr "x`$PROG version`" : "xOpenSSL" > /dev/null; then
+	:
+    else
+	echo "$PROG is not OpenSSL executable"
+	exit 1
+    fi
+else
+    echo "$PROG is not executable"
+    exit 1;
+fi
+
+if $PROG engine padlock | grep -v no-ACE; then
+
+    HASH=`cat $PROG | $PROG dgst -hex`
+
+    ACE_ALGS="	aes-128-ecb aes-192-ecb aes-256-ecb \
+		aes-128-cbc aes-192-cbc aes-256-cbc \
+		aes-128-cfb aes-192-cfb aes-256-cfb \
+		aes-128-ofb aes-192-ofb aes-256-ofb"
+
+    nerr=0
+
+    for alg in $ACE_ALGS; do
+	echo $alg
+	TEST=`(	cat $PROG | \
+		$PROG enc -e -k "$HASH" -$alg -bufsize 999 -engine padlock | \
+		$PROG enc -d -k "$HASH" -$alg | \
+		$PROG dgst -hex ) 2>/dev/null`
+	if [ "$TEST" != "$HASH" ]; then
+		echo "-$alg encrypt test failed"
+		nerr=`expr $nerr + 1`
+	fi
+	TEST=`(	cat $PROG | \
+		$PROG enc -e -k "$HASH" -$alg | \
+		$PROG enc -d -k "$HASH" -$alg -bufsize 999 -engine padlock | \
+		$PROG dgst -hex ) 2>/dev/null`
+	if [ "$TEST" != "$HASH" ]; then
+		echo "-$alg decrypt test failed"
+		nerr=`expr $nerr + 1`
+	fi
+	TEST=`(	cat $PROG | \
+		$PROG enc -e -k "$HASH" -$alg -engine padlock | \
+		$PROG enc -d -k "$HASH" -$alg -engine padlock | \
+		$PROG dgst -hex ) 2>/dev/null`
+	if [ "$TEST" != "$HASH" ]; then
+		echo "-$alg en/decrypt test failed"
+		nerr=`expr $nerr + 1`
+	fi
+    done
+
+    if [ $nerr -gt 0 ]; then
+	echo "PadLock ACE test failed."
+	exit 1;
+    fi
+else
+    echo "PadLock ACE is not available"
+fi
+
+exit 0
diff --git a/openssl/test/testca b/openssl/test/testca
new file mode 100644
index 0000000..b109cfe
--- /dev/null
+++ b/openssl/test/testca
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+SH="/bin/sh"
+if test "$OSTYPE" = msdosdjgpp; then
+    PATH="../apps\;$PATH"
+else
+    PATH="../apps:$PATH"
+fi
+export SH PATH
+
+SSLEAY_CONFIG="-config CAss.cnf"
+export SSLEAY_CONFIG
+
+OPENSSL="`pwd`/../util/opensslwrap.sh"
+export OPENSSL
+
+/bin/rm -fr demoCA
+$SH ../apps/CA.sh -newca <<EOF
+EOF
+
+if [ $? != 0 ]; then
+	exit 1;
+fi
+
+SSLEAY_CONFIG="-config Uss.cnf"
+export SSLEAY_CONFIG
+$SH ../apps/CA.sh -newreq
+if [ $? != 0 ]; then
+	exit 1;
+fi
+
+
+SSLEAY_CONFIG="-config ../apps/openssl.cnf"
+export SSLEAY_CONFIG
+$SH ../apps/CA.sh -sign  <<EOF
+y
+y
+EOF
+if [ $? != 0 ]; then
+	exit 1;
+fi
+
+
+$SH ../apps/CA.sh -verify newcert.pem
+if [ $? != 0 ]; then
+	exit 1;
+fi
+
+/bin/rm -fr demoCA newcert.pem newreq.pem
+#usage: CA -newcert|-newreq|-newca|-sign|-verify
+
diff --git a/openssl/test/testca.com b/openssl/test/testca.com
new file mode 100644
index 0000000..78cda9e
--- /dev/null
+++ b/openssl/test/testca.com
@@ -0,0 +1,52 @@
+$! TESTCA.COM
+$
+$	__arch = "VAX"
+$	if f$getsyi("cpu") .ge. 128 then -
+	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$	if __arch .eqs. "" then __arch = "UNK"
+$!
+$       if (p1 .eqs. "64") then __arch = __arch+ "_64"
+$
+$	openssl = "mcr ''exe_dir'openssl"
+$
+$	SSLEAY_CONFIG="-config ""CAss.cnf"""
+$
+$	set noon
+$	if f$search("demoCA.dir") .nes. ""
+$	then
+$	    @[-.util]deltree [.demoCA]*.*
+$	    set file/prot=(S:RWED,O:RWED,G:RWED,W:RWED) demoCA.dir;*
+$	    delete demoCA.dir;*
+$	endif
+$	set on
+$	open/read sys$ca_input VMSca-response.1
+$	@[-.apps]CA.com -input sys$ca_input -newca
+$	close sys$ca_input
+$	if $severity .ne. 1 then exit 3
+$
+$
+$	SSLEAY_CONFIG="-config ""Uss.cnf"""
+$	@[-.apps]CA.com -newreq
+$	if $severity .ne. 1 then exit 3
+$
+$
+$	SSLEAY_CONFIG="-config [-.apps]openssl-vms.cnf"
+$	open/read sys$ca_input VMSca-response.2
+$	@[-.apps]CA.com -input sys$ca_input -sign
+$	close sys$ca_input
+$	if $severity .ne. 1 then exit 3
+$
+$
+$	@[-.apps]CA.com -verify newcert.pem
+$	if $severity .ne. 1 then exit 3
+$
+$	set noon
+$	@[-.util]deltree [.demoCA]*.*
+$	set file/prot=(S:RWED,O:RWED,G:RWED,W:RWED) demoCA.dir;*
+$	delete demoCA.dir;*
+$	if f$search("newcert.pem") .nes. "" then delete newcert.pem;*
+$	if f$search("newcert.pem") .nes. "" then delete newreq.pem;*
+$	set on
+$!	#usage: CA -newcert|-newreq|-newca|-sign|-verify
+$
+$	exit
diff --git a/openssl/test/testcrl.pem b/openssl/test/testcrl.pem
new file mode 100644
index 0000000..0989788
--- /dev/null
+++ b/openssl/test/testcrl.pem
@@ -0,0 +1,16 @@
+-----BEGIN X509 CRL-----
+MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT
+F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy
+IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw
+MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw
+MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw
+MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw
+MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw
+MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw
+MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw
+NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw
+NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF
+AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ
+wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt
+JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v
+-----END X509 CRL-----
diff --git a/openssl/test/testenc b/openssl/test/testenc
new file mode 100644
index 0000000..f5ce7c0
--- /dev/null
+++ b/openssl/test/testenc
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+testsrc=Makefile
+test=./p
+cmd="../util/shlib_wrap.sh ../apps/openssl"
+
+cat $testsrc >$test;
+
+echo cat
+$cmd enc < $test > $test.cipher
+$cmd enc < $test.cipher >$test.clear
+cmp $test $test.clear
+if [ $? != 0 ]
+then
+	exit 1
+else
+	/bin/rm $test.cipher $test.clear
+fi
+echo base64
+$cmd enc -a -e < $test > $test.cipher
+$cmd enc -a -d < $test.cipher >$test.clear
+cmp $test $test.clear
+if [ $? != 0 ]
+then
+	exit 1
+else
+	/bin/rm $test.cipher $test.clear
+fi
+
+for i in `$cmd list-cipher-commands`
+do
+	echo $i
+	$cmd $i -bufsize 113 -e -k test < $test > $test.$i.cipher
+	$cmd $i -bufsize 157 -d -k test < $test.$i.cipher >$test.$i.clear
+	cmp $test $test.$i.clear
+	if [ $? != 0 ]
+	then
+		exit 1
+	else
+		/bin/rm $test.$i.cipher $test.$i.clear
+	fi
+
+	echo $i base64
+	$cmd $i -bufsize 113 -a -e -k test < $test > $test.$i.cipher
+	$cmd $i -bufsize 157 -a -d -k test < $test.$i.cipher >$test.$i.clear
+	cmp $test $test.$i.clear
+	if [ $? != 0 ]
+	then
+		exit 1
+	else
+		/bin/rm $test.$i.cipher $test.$i.clear
+	fi
+done
+rm -f $test
diff --git a/openssl/test/testenc.com b/openssl/test/testenc.com
new file mode 100644
index 0000000..75acd6f
--- /dev/null
+++ b/openssl/test/testenc.com
@@ -0,0 +1,66 @@
+$! TESTENC.COM  --  Test encoding and decoding
+$
+$	__arch = "VAX"
+$	if f$getsyi("cpu") .ge. 128 then -
+	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$	if __arch .eqs. "" then __arch = "UNK"
+$!
+$	if (p1 .eqs. 64) then __arch = __arch+ "_64"
+$
+$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$	testsrc = "makefile."
+$	test = "p.txt"
+$	cmd = "mcr ''exe_dir'openssl"
+$
+$	if f$search(test) .nes. "" then delete 'test';*
+$	convert/fdl=sys$input: 'testsrc' 'test'
+RECORD
+	FORMAT STREAM_LF
+$
+$	if f$search(test+"-cipher") .nes. "" then delete 'test'-cipher;*
+$	if f$search(test+"-clear") .nes. "" then delete 'test'-clear;*
+$
+$	write sys$output "cat"
+$	'cmd' enc -in 'test' -out 'test'-cipher
+$	'cmd' enc -in 'test'-cipher -out 'test'-clear
+$	backup/compare 'test' 'test'-clear
+$	if $severity .ne. 1 then exit 3
+$	delete 'test'-cipher;*,'test'-clear;*
+$
+$	write sys$output "base64"
+$	'cmd' enc -a -e -in 'test' -out 'test'-cipher
+$	'cmd' enc -a -d -in 'test'-cipher -out 'test'-clear
+$	backup/compare 'test' 'test'-clear
+$	if $severity .ne. 1 then exit 3
+$	delete 'test'-cipher;*,'test'-clear;*
+$
+$	define/user sys$output 'test'-cipher-commands
+$	'cmd' list-cipher-commands
+$	open/read f 'test'-cipher-commands
+$ loop_cipher_commands:
+$	read/end=loop_cipher_commands_end f i
+$	write sys$output i
+$
+$	if f$search(test+"-"+i+"-cipher") .nes. "" then -
+		delete 'test'-'i'-cipher;*
+$	if f$search(test+"-"+i+"-clear") .nes. "" then -
+		delete 'test'-'i'-clear;*
+$
+$	'cmd' 'i' -bufsize 113 -e -k test -in 'test' -out 'test'-'i'-cipher
+$	'cmd' 'i' -bufsize 157 -d -k test -in 'test'-'i'-cipher -out 'test'-'i'-clear
+$	backup/compare 'test' 'test'-'i'-clear
+$	if $severity .ne. 1 then exit 3
+$	delete 'test'-'i'-cipher;*,'test'-'i'-clear;*
+$
+$	write sys$output i," base64"
+$	'cmd' 'i' -bufsize 113 -a -e -k test -in 'test' -out 'test'-'i'-cipher
+$	'cmd' 'i' -bufsize 157 -a -d -k test -in 'test'-'i'-cipher -out 'test'-'i'-clear
+$	backup/compare 'test' 'test'-'i'-clear
+$	if $severity .ne. 1 then exit 3
+$	delete 'test'-'i'-cipher;*,'test'-'i'-clear;*
+$
+$	goto loop_cipher_commands
+$ loop_cipher_commands_end:
+$	close f
+$	delete 'test'-cipher-commands;*
+$	delete 'test';*
diff --git a/openssl/test/testgen b/openssl/test/testgen
new file mode 100644
index 0000000..524c0d1
--- /dev/null
+++ b/openssl/test/testgen
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+T=testcert
+KEY=512
+CA=../certs/testca.pem
+
+/bin/rm -f $T.1 $T.2 $T.key
+
+if test "$OSTYPE" = msdosdjgpp; then
+    PATH=../apps\;$PATH;
+else
+    PATH=../apps:$PATH;
+fi
+export PATH
+
+echo "generating certificate request"
+
+echo "string to make the random number generator think it has entropy" >> ./.rnd
+
+if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then
+  req_new='-newkey dsa:../apps/dsa512.pem'
+else
+  req_new='-new'
+  echo "There should be a 2 sequences of .'s and some +'s."
+  echo "There should not be more that at most 80 per line"
+fi
+
+echo "This could take some time."
+
+rm -f testkey.pem testreq.pem
+
+../util/shlib_wrap.sh ../apps/openssl req -config test.cnf $req_new -out testreq.pem
+if [ $? != 0 ]; then
+echo problems creating request
+exit 1
+fi
+
+../util/shlib_wrap.sh ../apps/openssl req -config test.cnf -verify -in testreq.pem -noout
+if [ $? != 0 ]; then
+echo signature on req is wrong
+exit 1
+fi
+
+exit 0
diff --git a/openssl/test/testgen.com b/openssl/test/testgen.com
new file mode 100644
index 0000000..e076da2
--- /dev/null
+++ b/openssl/test/testgen.com
@@ -0,0 +1,58 @@
+$! TESTGEN.COM
+$
+$	__arch = "VAX"
+$	if f$getsyi("cpu") .ge. 128 then -
+	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$	if __arch .eqs. "" then __arch = "UNK"
+$	if (p1 .eqs. 64) then __arch = __arch+ "_64"
+$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$	T = "testcert"
+$	KEY = 512
+$	CA = "[-.certs]testca.pem"
+$
+$	set noon
+$	if f$search(T+".1;*") .nes. "" then delete 'T'.1;*
+$	if f$search(T+".2;*") .nes. "" then delete 'T'.2;*
+$	if f$search(T+".key;*") .nes. "" then delete 'T'.key;*
+$	set on
+$
+$	write sys$output "generating certificate request"
+$
+$	append/new nl: .rnd
+$	open/append random_file .rnd
+$	write random_file -
+	 "string to make the random number generator think it has entropy"
+$	close random_file
+$
+$	set noon
+$	define/user sys$output nla0:
+$	mcr 'exe_dir'openssl no-rsa
+$	save_severity=$SEVERITY
+$	set on
+$	if save_severity
+$	then
+$	    req_new="-newkey dsa:[-.apps]dsa512.pem"
+$	else
+$	    req_new="-new"
+$	    write sys$output -
+	     "There should be a 2 sequences of .'s and some +'s."
+$	    write sys$output -
+	     "There should not be more that at most 80 per line"
+$	endif
+$
+$	write sys$output "This could take some time."
+$
+$	mcr 'exe_dir'openssl req -config test.cnf 'req_new' -out testreq.pem
+$	if $severity .ne. 1
+$	then
+$	    write sys$output "problems creating request"
+$	    exit 3
+$	endif
+$
+$	mcr 'exe_dir'openssl req -config test.cnf -verify -in testreq.pem -noout
+$	if $severity .ne. 1
+$	then
+$	    write sys$output "signature on req is wrong"
+$	    exit 3
+$	endif
diff --git a/openssl/test/testp7.pem b/openssl/test/testp7.pem
new file mode 100644
index 0000000..e5b7866
--- /dev/null
+++ b/openssl/test/testp7.pem
@@ -0,0 +1,46 @@
+-----BEGIN PKCS7-----
+MIIIGAYJKoZIhvcNAQcCoIIICTCCCAUCAQExADALBgkqhkiG9w0BBwGgggY8MIIE
+cjCCBBygAwIBAgIQeS+OJfWJUZAx6cX0eAiMjzANBgkqhkiG9w0BAQQFADBiMREw
+DwYDVQQHEwhJbnRlcm5ldDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNDAyBgNV
+BAsTK1ZlcmlTaWduIENsYXNzIDEgQ0EgLSBJbmRpdmlkdWFsIFN1YnNjcmliZXIw
+HhcNOTYwNzE5MDAwMDAwWhcNOTcwMzMwMjM1OTU5WjCB1TERMA8GA1UEBxMISW50
+ZXJuZXQxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTQwMgYDVQQLEytWZXJpU2ln
+biBDbGFzcyAxIENBIC0gSW5kaXZpZHVhbCBTdWJzY3JpYmVyMSgwJgYDVQQLEx9E
+aWdpdGFsIElEIENsYXNzIDEgLSBTTUlNRSBUZXN0MUcwRQYDVQQLEz53d3cudmVy
+aXNpZ24uY29tL3JlcG9zaXRvcnkvQ1BTLTEuMCBJbmMuIGJ5IFJlZi4sTElBQi5M
+VEQoYyk5NjBbMA0GCSqGSIb3DQEBAQUAA0oAMEcCQA7LvHEIAiQ5+4gDYvJGnGAq
+UM5GXyG11diEXmIEZTHUZhorooX5sr8IIjSXiPY59YYUFSvAaharFM1xaBN8zNEC
+AwEAAaOCAjkwggI1MAkGA1UdEwQCMAAwggImBgNVHQMEggIdMIICGTCCAhUwggIR
+BgtghkgBhvhFAQcBATCCAgAWggGrVGhpcyBjZXJ0aWZpY2F0ZSBpbmNvcnBvcmF0
+ZXMgYnkgcmVmZXJlbmNlLCBhbmQgaXRzIHVzZSBpcyBzdHJpY3RseSBzdWJqZWN0
+IHRvLCB0aGUgVmVyaVNpZ24gQ2VydGlmaWNhdGlvbiBQcmFjdGljZSBTdGF0ZW1l
+bnQgKENQUyksIGF2YWlsYWJsZSBhdDogaHR0cHM6Ly93d3cudmVyaXNpZ24uY29t
+L0NQUy0xLjA7IGJ5IEUtbWFpbCBhdCBDUFMtcmVxdWVzdHNAdmVyaXNpZ24uY29t
+OyBvciBieSBtYWlsIGF0IFZlcmlTaWduLCBJbmMuLCAyNTkzIENvYXN0IEF2ZS4s
+IE1vdW50YWluIFZpZXcsIENBIDk0MDQzIFVTQSBUZWwuICsxICg0MTUpIDk2MS04
+ODMwIENvcHlyaWdodCAoYykgMTk5NiBWZXJpU2lnbiwgSW5jLiAgQWxsIFJpZ2h0
+cyBSZXNlcnZlZC4gQ0VSVEFJTiBXQVJSQU5USUVTIERJU0NMQUlNRUQgYW5kIExJ
+QUJJTElUWSBMSU1JVEVELqAOBgxghkgBhvhFAQcBAQGhDgYMYIZIAYb4RQEHAQEC
+MC8wLRYraHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvQ1BTLTEu
+AzANBgkqhkiG9w0BAQQFAANBAMCYDuSb/eIlYSxY31nZZTaCZkCSfHjlacMofExr
+cF+A2yHoEuT+eCQkqM0pMNHXddUeoQ9RjV+VuMBNmm63DUYwggHCMIIBbKADAgEC
+AhB8CYTq1bkRFJBYOd67cp9JMA0GCSqGSIb3DQEBAgUAMD4xCzAJBgNVBAYTAlVT
+MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEWMBQGA1UECxMNVEVTVCBSb290IFBD
+QTAeFw05NjA3MTcwMDAwMDBaFw05NzA3MTcyMzU5NTlaMGIxETAPBgNVBAcTCElu
+dGVybmV0MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE0MDIGA1UECxMrVmVyaVNp
+Z24gQ2xhc3MgMSBDQSAtIEluZGl2aWR1YWwgU3Vic2NyaWJlcjBcMA0GCSqGSIb3
+DQEBAQUAA0sAMEgCQQDsVzrNgnDhbAJZrWeLd9g1vMZJA2W67D33TTbga6yMt+ES
+TWEywhS6RNP+fzLGg7utinjH4tL60cXa0G27GDsLAgMBAAGjIjAgMAsGA1UdDwQE
+AwIBBjARBglghkgBhvhCAQEEBAMCAgQwDQYJKoZIhvcNAQECBQADQQAUp6bRwkaD
+2d1MBs/mjUcgTI2fXVmW8tTm/Ud6OzUwpC3vYgybiOOA4f6mOC5dbyUHrLOsrihU
+47ZQ0Jo1DUfboYIBrTCBwTBtMA0GCSqGSIb3DQEBAgUAMD4xCzAJBgNVBAYTAlVT
+MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEWMBQGA1UECxMNVEVTVCBSb290IFBD
+QRcNOTYwNzE3MTc0NDA5WhcNOTgwNzE3MDAwMDAwWjANBgkqhkiG9w0BAQIFAANB
+AHitA0/xAukCjHzeh1AMT/l2oC68N+yFb+aJPHBBMxc6gG2MaKjBNwb5hcXUllMl
+ExONA3ju10f7owIq3s3wx10wgeYwgZEwDQYJKoZIhvcNAQECBQAwYjERMA8GA1UE
+BxMISW50ZXJuZXQxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTQwMgYDVQQLEytW
+ZXJpU2lnbiBDbGFzcyAxIENBIC0gSW5kaXZpZHVhbCBTdWJzY3JpYmVyFw05NjA3
+MTcxNzU5MjlaFw05NzA3MTgwMDAwMDBaMA0GCSqGSIb3DQEBAgUAA0EAubVWYTsW
+sQmste9f+UgMw8BkjDlM25fwQLrCfmmnLxjewey10kSROypUaJLb+r4oRALc0fG9
+XfZsaiiIgotQHjEA
+-----END PKCS7-----
diff --git a/openssl/test/testreq2.pem b/openssl/test/testreq2.pem
new file mode 100644
index 0000000..c3cdcff
--- /dev/null
+++ b/openssl/test/testreq2.pem
@@ -0,0 +1,7 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIHaMIGFAgEAMA4xDDAKBgNVBAMTA2NuNDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgC
+QQCQsnkyUGDY2R3mYoeTprFJKgWuJ3f1jUjlIuW5+wfAUoeMt35c4vcFZ2mIBpEG
+DtzkNQN1kr2O9ldm9zYnYhyhAgMBAAGgEjAQBgorBgEEAYI3AgEOMQIwADANBgkq
+hkiG9w0BAQQFAANBAAb2szZgVIxg3vK6kYLjGSBISyuzcXJ6IvuPW6M+yzi1Qgoi
+gQhazHTJp91T8ItZEzUJGZSZl2e5iXlnffWB+/U=
+-----END CERTIFICATE REQUEST-----
diff --git a/openssl/test/testrsa.pem b/openssl/test/testrsa.pem
new file mode 100644
index 0000000..aad2106
--- /dev/null
+++ b/openssl/test/testrsa.pem
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBPAIBAAJBAKrbeqkuRk8VcRmWFmtP+LviMB3+6dizWW3DwaffznyHGAFwUJ/I
+Tv0XtbsCyl3QoyKGhrOAy3RvPK5M38iuXT0CAwEAAQJAZ3cnzaHXM/bxGaR5CR1R
+rD1qFBAVfoQFiOH9uPJgMaoAuoQEisPHVcZDKcOv4wEg6/TInAIXBnEigtqvRzuy
+oQIhAPcgZzUq3yVooAaoov8UbXPxqHlwo6GBMqnv20xzkf6ZAiEAsP4BnIaQTM8S
+mvcpHZwQJdmdHHkGKAs37Dfxi67HbkUCIQCeZGliHXFa071Fp06ZeWlR2ADonTZz
+rJBhdTe0v5pCeQIhAIZfkiGgGBX4cIuuckzEm43g9WMUjxP/0GlK39vIyihxAiEA
+mymehFRT0MvqW5xAKAx7Pgkt8HVKwVhc2LwGKHE0DZM=
+-----END RSA PRIVATE KEY-----
diff --git a/openssl/test/tests.com b/openssl/test/tests.com
new file mode 100644
index 0000000..373dd16
--- /dev/null
+++ b/openssl/test/tests.com
@@ -0,0 +1,366 @@
+$! TESTS.COM  --  Performs the necessary tests
+$!
+$! P1	tests to be performed.  Empty means all.
+$! P2	Pointer size: "", "32", or "64".
+$!
+$! Announce/identify.
+$!
+$	proc = f$environment( "procedure")
+$	write sys$output "@@@ "+ -
+	 f$parse( proc, , , "name")+ f$parse( proc, , , "type")
+$!
+$	__proc = f$element(0,";",f$environment("procedure"))
+$	__here = f$parse(f$parse("A.;",__proc) - "A.;","[]A.;") - "A.;"
+$	__save_default = f$environment("default")
+$	__arch = "VAX"
+$	if f$getsyi("cpu") .ge. 128 then -
+	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$	if __arch .eqs. "" then __arch = "UNK"
+$!
+$	__archd = __arch
+$       pointer_size = ""
+$	if (p2 .eq. "64")
+$	then
+$	  pointer_size = "64"
+$	  __archd = __arch+ "_64"
+$	endif
+$!
+$	texe_dir := sys$disk:[-.'__archd'.exe.test]
+$	exe_dir := sys$disk:[-.'__archd'.exe.apps]
+$
+$	set default '__here'
+$
+$       ROOT = F$PARSE("sys$disk:[-]A.;0",,,,"SYNTAX_ONLY,NO_CONCEAL") - "A.;0"
+$       ROOT_DEV = F$PARSE(ROOT,,,"DEVICE","SYNTAX_ONLY")
+$       ROOT_DIR = F$PARSE(ROOT,,,"DIRECTORY","SYNTAX_ONLY") -
+                   - ".][000000" - "[000000." - "][" - "[" - "]"
+$       ROOT = ROOT_DEV + "[" + ROOT_DIR
+$       DEFINE/NOLOG SSLROOT 'ROOT'.APPS.] /TRANS=CONC
+$	openssl_conf := sslroot:[000000]openssl-vms.cnf
+$
+$	on control_y then goto exit
+$	on error then goto exit
+$
+$	if p1 .nes. ""
+$	then
+$	    tests = p1
+$	else
+$! NOTE: This list reflects the list of dependencies following the
+$! "alltests" target in Makefile.  This should make it easy to see
+$! if there's a difference that needs to be taken care of.
+$	    tests := -
+	test_des,test_idea,test_sha,test_md4,test_md5,test_hmac,-
+	test_md2,test_mdc2,test_wp,-
+	test_rmd,test_rc2,test_rc4,test_rc5,test_bf,test_cast,test_aes,-
+	test_rand,test_bn,test_ec,test_ecdsa,test_ecdh,-
+	test_enc,test_x509,test_rsa,test_crl,test_sid,-
+	test_gen,test_req,test_pkcs7,test_verify,test_dh,test_dsa,-
+	test_ss,test_ca,test_engine,test_evp,test_ssl,test_tsa,test_ige,-
+	test_jpake,test_cms
+$	endif
+$	tests = f$edit(tests,"COLLAPSE")
+$
+$	BNTEST :=	bntest
+$	ECTEST :=	ectest
+$	ECDSATEST :=	ecdsatest
+$	ECDHTEST :=	ecdhtest
+$	EXPTEST :=	exptest
+$	IDEATEST :=	ideatest
+$	SHATEST :=	shatest
+$	SHA1TEST :=	sha1test
+$	MDC2TEST :=	mdc2test
+$	RMDTEST :=	rmdtest
+$	MD2TEST :=	md2test
+$	MD4TEST :=	md4test
+$	MD5TEST :=	md5test
+$	HMACTEST :=	hmactest
+$	WPTEST :=	wp_test
+$	RC2TEST :=	rc2test
+$	RC4TEST :=	rc4test
+$	RC5TEST :=	rc5test
+$	BFTEST :=	bftest
+$	CASTTEST :=	casttest
+$	DESTEST :=	destest
+$	RANDTEST :=	randtest
+$	DHTEST :=	dhtest
+$	DSATEST :=	dsatest
+$	METHTEST :=	methtest
+$	SSLTEST :=	ssltest
+$	RSATEST :=	rsa_test
+$	ENGINETEST :=	enginetest
+$	EVPTEST :=	evp_test
+$	IGETEST :=	igetest
+$	JPAKETEST :=	jpaketest
+$	ASN1TEST :=	asn1test
+$!
+$	tests_i = 0
+$ loop_tests:
+$	tests_e = f$element(tests_i,",",tests)
+$	tests_i = tests_i + 1
+$	if tests_e .eqs. "," then goto exit
+$	write sys$output "---> ''tests_e'"
+$	gosub 'tests_e'
+$	goto loop_tests
+$
+$ test_evp:
+$	mcr 'texe_dir''evptest' 'ROOT'.CRYPTO.EVP]evptests.txt
+$	return
+$ test_des:
+$	mcr 'texe_dir''destest'
+$	return
+$ test_idea:
+$	mcr 'texe_dir''ideatest'
+$	return
+$ test_sha:
+$	mcr 'texe_dir''shatest'
+$	mcr 'texe_dir''sha1test'
+$	return
+$ test_mdc2:
+$	mcr 'texe_dir''mdc2test'
+$	return
+$ test_md5:
+$	mcr 'texe_dir''md5test'
+$	return
+$ test_md4:
+$	mcr 'texe_dir''md4test'
+$	return
+$ test_hmac:
+$	mcr 'texe_dir''hmactest'
+$	return
+$ test_wp:
+$	mcr 'texe_dir''wptest'
+$	return
+$ test_md2:
+$	mcr 'texe_dir''md2test'
+$	return
+$ test_rmd:
+$	mcr 'texe_dir''rmdtest'
+$	return
+$ test_bf:
+$	mcr 'texe_dir''bftest'
+$	return
+$ test_cast:
+$	mcr 'texe_dir''casttest'
+$	return
+$ test_rc2:
+$	mcr 'texe_dir''rc2test'
+$	return
+$ test_rc4:
+$	mcr 'texe_dir''rc4test'
+$	return
+$ test_rc5:
+$	mcr 'texe_dir''rc5test'
+$	return
+$ test_rand:
+$	mcr 'texe_dir''randtest'
+$	return
+$ test_enc:
+$	@testenc.com 'pointer_size'
+$	return
+$ test_x509:
+$	set noon
+$	define sys$error test_x509.err
+$	write sys$output "test normal x509v1 certificate"
+$	@tx509.com "" 'pointer_size'
+$	write sys$output "test first x509v3 certificate"
+$	@tx509.com v3-cert1.pem 'pointer_size'
+$	write sys$output "test second x509v3 certificate"
+$	@tx509.com v3-cert2.pem 'pointer_size'
+$	deassign sys$error
+$	set on
+$	return
+$ test_rsa:
+$	set noon
+$	define sys$error test_rsa.err
+$	@trsa.com "" 'pointer_size'
+$	deassign sys$error
+$	mcr 'texe_dir''rsatest'
+$	set on
+$	return
+$ test_crl:
+$	set noon
+$	define sys$error test_crl.err
+$	@tcrl.com "" 'pointer_size'
+$	deassign sys$error
+$	set on
+$	return
+$ test_sid:
+$	set noon
+$	define sys$error test_sid.err
+$	@tsid.com "" 'pointer_size'
+$	deassign sys$error
+$	set on
+$	return
+$ test_req:
+$	set noon
+$	define sys$error test_req.err
+$	@treq.com "" 'pointer_size'
+$	@treq.com testreq2.pem 'pointer_size'
+$	deassign sys$error
+$	set on
+$	return
+$ test_pkcs7:
+$	set noon
+$	define sys$error test_pkcs7.err
+$	@tpkcs7.com "" 'pointer_size'
+$	@tpkcs7d.com "" 'pointer_size'
+$	deassign sys$error
+$	set on
+$	return
+$ test_bn:
+$	write sys$output -
+	      "starting big number library test, could take a while..."
+$	set noon
+$	define sys$error test_bn.err
+$	define sys$output test_bn.out
+$	@ bctest.com
+$	status = $status
+$	deassign sys$error
+$	deassign sys$output
+$	set on
+$	if (status)
+$	then
+$	    create /fdl = sys$input bntest-vms.tmp
+FILE
+	ORGANIZATION	sequential
+RECORD
+	FORMAT		stream_lf
+$	    define /user_mode sys$output bntest-vms.tmp
+$	    mcr 'texe_dir''bntest'
+$	    define /user_mode sys$input bntest-vms.tmp
+$	    define /user_mode sys$output bntest-vms.out
+$	    bc
+$	    @ bntest.com bntest-vms.out
+$	    status = $status
+$	    if (status)
+$	    then
+$		delete bntest-vms.out;*
+$		delete bntest-vms.tmp;*
+$	    endif
+$	else
+$	    create /fdl = sys$input bntest-vms.sh
+FILE
+	ORGANIZATION	sequential
+RECORD
+	FORMAT		stream_lf
+$	    open /append bntest_file bntest-vms.sh
+$	    type /output = bntest_file sys$input:
+<< __FOO__ sh -c "`sh ./bctest`" | perl -e '$i=0; while (<STDIN>) {if (/^test (.*)/) {print STDERR "\nverify $1";} elsif (!/^0$/) {die "\nFailed! bc: $_";} else {print STDERR "."; $i++;}} print STDERR "\n$i tests passed\n"'
+$	    define /user_mode sys$output bntest-vms.tmp
+$	    mcr 'texe_dir''bntest'
+$	    copy bntest-vms.tmp bntest_file
+$	    delete bntest-vms.tmp;*
+$	    type /output = bntest_file sys$input:
+__FOO__
+$	    close bntest_file
+$	    write sys$output "-- copy the [.test]bntest-vms.sh and [.test]bctest files to a Unix system and"
+$	    write sys$output "-- run bntest-vms.sh through sh or bash to verify that the bignum operations"
+$	    write sys$output "-- went well."
+$	    write sys$output ""
+$	endif
+$	write sys$output "test a^b%c implementations"
+$	mcr 'texe_dir''exptest'
+$	return
+$ test_ec:
+$	write sys$output "test elliptic curves"
+$	mcr 'texe_dir''ectest'
+$	return
+$ test_ecdsa:
+$	write sys$output "test ecdsa"
+$	mcr 'texe_dir''ecdsatest'
+$	return
+$ test_ecdh:
+$	write sys$output "test ecdh"
+$	mcr 'texe_dir''ecdhtest'
+$	return
+$ test_verify:
+$	write sys$output "The following command should have some OK's and some failures"
+$	write sys$output "There are definitly a few expired certificates"
+$	@tverify.com 'pointer_size'
+$	return
+$ test_dh:
+$	write sys$output "Generate a set of DH parameters"
+$	mcr 'texe_dir''dhtest'
+$	return
+$ test_dsa:
+$	write sys$output "Generate a set of DSA parameters"
+$	mcr 'texe_dir''dsatest'
+$	return
+$ test_gen:
+$	write sys$output "Generate and verify a certificate request"
+$	@testgen.com 'pointer_size'
+$	return
+$ maybe_test_ss:
+$	testss_RDT = f$cvtime(f$file_attributes("testss.com","RDT"))
+$	if f$cvtime(f$file_attributes("keyU.ss","RDT")) .les. testss_RDT then -
+		goto test_ss
+$	if f$cvtime(f$file_attributes("certU.ss","RDT")) .les. testss_RDT then -
+		goto test_ss
+$	if f$cvtime(f$file_attributes("certCA.ss","RDT")) .les. testss_RDT then -
+		goto test_ss
+$	return
+$ test_ss:
+$	write sys$output "Generate and certify a test certificate"
+$	@testss.com 'pointer_size'
+$	return
+$ test_engine: 
+$	write sys$output "Manipulate the ENGINE structures"
+$	mcr 'texe_dir''enginetest'
+$	return
+$ test_ssl:
+$	write sys$output "test SSL protocol"
+$	gosub maybe_test_ss
+$	@testssl.com keyU.ss certU.ss certCA.ss 'pointer_size'
+$	return
+$ test_ca:
+$	set noon
+$	define /user_mode sys$output test_ca.out
+$	mcr 'exe_dir'openssl no-rsa
+$	save_severity=$SEVERITY
+$	set on
+$	if save_severity
+$	then
+$	    write sys$output "skipping CA.com test -- requires RSA"
+$	else
+$	    write sys$output "Generate and certify a test certificate via the 'ca' program"
+$	    @testca.com 'pointer_size'
+$	endif
+$	return
+$ test_aes: 
+$!	write sys$output "test AES"
+$!	!mcr 'texe_dir''aestest'
+$	return
+$ test_tsa:
+$	set noon
+$	define /user_mode sys$output nla0:
+$	mcr 'exe_dir'openssl no-rsa
+$	save_severity=$SEVERITY
+$	set on
+$	if save_severity
+$	then
+$	    write sys$output "skipping testtsa.com test -- requires RSA"
+$	else
+$	    @testtsa.com "" "" "" 'pointer_size'
+$	endif
+$	return
+$ test_ige: 
+$	write sys$output "Test IGE mode"
+$	mcr 'texe_dir''igetest'
+$	return
+$ test_jpake: 
+$	write sys$output "Test JPAKE"
+$	mcr 'texe_dir''jpaketest'
+$	return
+$ test_cms:
+$	write sys$output "CMS consistency test"
+$	! Define the logical name used to find openssl.exe in the perl script.
+$	define /user_mode osslx 'exe_dir'
+$	perl CMS-TEST.PL
+$	return
+$
+$
+$ exit:
+$	mcr 'exe_dir'openssl version -a
+$	set default '__save_default'
+$	deassign sslroot
+$	exit
diff --git a/openssl/test/testsid.pem b/openssl/test/testsid.pem
new file mode 100644
index 0000000..7ffd008
--- /dev/null
+++ b/openssl/test/testsid.pem
@@ -0,0 +1,12 @@
+-----BEGIN SSL SESSION PARAMETERS-----
+MIIB1gIBAQIBAgQDAQCABBCi11xa5qkOP8xrr02K/NQCBBBkIYQZM0Bt95W0EHNV
+bA58oQYCBDIBr7WiBAICASyjggGGMIIBgjCCASwCAQMwDQYJKoZIhvcNAQEEBQAw
+ODELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3Jz
+YSB0ZXN0IENBMB4XDTk1MTAwOTIzMzEzNFoXDTk4MDcwNTIzMzEzNFowYDELMAkG
+A1UEBhMCQVUxDDAKBgNVBAgTA1FMRDEZMBcGA1UEChMQTWluY29tIFB0eS4gTHRk
+LjELMAkGA1UECxMCQ1MxGzAZBgNVBAMTElNTTGVheSBkZW1vIGNsaWVudDBcMA0G
+CSqGSIb3DQEBAQUAA0sAMEgCQQC4pcXEL1lgVA+B5Q3TcuW/O3LZHoA73IYm8oFD
+TezgCDhL2RTMn+seKWF36UtJKRIOBU9jZHCVVd0Me5ls6BEjAgMBAAEwDQYJKoZI
+hvcNAQEEBQADQQBoIpOcwUY1qlVF7j3ROSGvUsbvByOBFmYWkIBgsCqR+9qo1A7L
+CrWF5i8LWt/vLwAHaxWNx2YuBJMFyuK81fTvpA0EC3Rlc3Rjb250ZXh0
+-----END SSL SESSION PARAMETERS-----
diff --git a/openssl/test/testss b/openssl/test/testss
new file mode 100644
index 0000000..1a42685
--- /dev/null
+++ b/openssl/test/testss
@@ -0,0 +1,163 @@
+#!/bin/sh
+
+digest='-sha1'
+reqcmd="../util/shlib_wrap.sh ../apps/openssl req"
+x509cmd="../util/shlib_wrap.sh ../apps/openssl x509 $digest"
+verifycmd="../util/shlib_wrap.sh ../apps/openssl verify"
+dummycnf="../apps/openssl.cnf"
+
+CAkey="keyCA.ss"
+CAcert="certCA.ss"
+CAreq="reqCA.ss"
+CAconf="CAss.cnf"
+CAreq2="req2CA.ss"	# temp
+
+Uconf="Uss.cnf"
+Ukey="keyU.ss"
+Ureq="reqU.ss"
+Ucert="certU.ss"
+
+P1conf="P1ss.cnf"
+P1key="keyP1.ss"
+P1req="reqP1.ss"
+P1cert="certP1.ss"
+P1intermediate="tmp_intP1.ss"
+
+P2conf="P2ss.cnf"
+P2key="keyP2.ss"
+P2req="reqP2.ss"
+P2cert="certP2.ss"
+P2intermediate="tmp_intP2.ss"
+
+echo
+echo "make a certificate request using 'req'"
+
+echo "string to make the random number generator think it has entropy" >> ./.rnd
+
+if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then
+  req_new='-newkey dsa:../apps/dsa512.pem'
+else
+  req_new='-new'
+fi
+
+$reqcmd -config $CAconf -out $CAreq -keyout $CAkey $req_new #>err.ss
+if [ $? != 0 ]; then
+	echo "error using 'req' to generate a certificate request"
+	exit 1
+fi
+echo
+echo "convert the certificate request into a self signed certificate using 'x509'"
+$x509cmd -CAcreateserial -in $CAreq -days 30 -req -out $CAcert -signkey $CAkey -extfile $CAconf -extensions v3_ca >err.ss
+if [ $? != 0 ]; then
+	echo "error using 'x509' to self sign a certificate request"
+	exit 1
+fi
+
+echo
+echo "convert a certificate into a certificate request using 'x509'"
+$x509cmd -in $CAcert -x509toreq -signkey $CAkey -out $CAreq2 >err.ss
+if [ $? != 0 ]; then
+	echo "error using 'x509' convert a certificate to a certificate request"
+	exit 1
+fi
+
+$reqcmd -config $dummycnf -verify -in $CAreq -noout
+if [ $? != 0 ]; then
+	echo first generated request is invalid
+	exit 1
+fi
+
+$reqcmd -config $dummycnf -verify -in $CAreq2 -noout
+if [ $? != 0 ]; then
+	echo second generated request is invalid
+	exit 1
+fi
+
+$verifycmd -CAfile $CAcert $CAcert
+if [ $? != 0 ]; then
+	echo first generated cert is invalid
+	exit 1
+fi
+
+echo
+echo "make a user certificate request using 'req'"
+$reqcmd -config $Uconf -out $Ureq -keyout $Ukey $req_new >err.ss
+if [ $? != 0 ]; then
+	echo "error using 'req' to generate a user certificate request"
+	exit 1
+fi
+
+echo
+echo "sign user certificate request with the just created CA via 'x509'"
+$x509cmd -CAcreateserial -in $Ureq -days 30 -req -out $Ucert -CA $CAcert -CAkey $CAkey -extfile $Uconf -extensions v3_ee >err.ss
+if [ $? != 0 ]; then
+	echo "error using 'x509' to sign a user certificate request"
+	exit 1
+fi
+
+$verifycmd -CAfile $CAcert $Ucert
+echo
+echo "Certificate details"
+$x509cmd -subject -issuer -startdate -enddate -noout -in $Ucert
+
+echo
+echo "make a proxy certificate request using 'req'"
+$reqcmd -config $P1conf -out $P1req -keyout $P1key $req_new >err.ss
+if [ $? != 0 ]; then
+	echo "error using 'req' to generate a proxy certificate request"
+	exit 1
+fi
+
+echo
+echo "sign proxy certificate request with the just created user certificate via 'x509'"
+$x509cmd -CAcreateserial -in $P1req -days 30 -req -out $P1cert -CA $Ucert -CAkey $Ukey -extfile $P1conf -extensions v3_proxy >err.ss
+if [ $? != 0 ]; then
+	echo "error using 'x509' to sign a proxy certificate request"
+	exit 1
+fi
+
+cat $Ucert > $P1intermediate
+$verifycmd -CAfile $CAcert -untrusted $P1intermediate $P1cert
+echo
+echo "Certificate details"
+$x509cmd -subject -issuer -startdate -enddate -noout -in $P1cert
+
+echo
+echo "make another proxy certificate request using 'req'"
+$reqcmd -config $P2conf -out $P2req -keyout $P2key $req_new >err.ss
+if [ $? != 0 ]; then
+	echo "error using 'req' to generate another proxy certificate request"
+	exit 1
+fi
+
+echo
+echo "sign second proxy certificate request with the first proxy certificate via 'x509'"
+$x509cmd -CAcreateserial -in $P2req -days 30 -req -out $P2cert -CA $P1cert -CAkey $P1key -extfile $P2conf -extensions v3_proxy >err.ss
+if [ $? != 0 ]; then
+	echo "error using 'x509' to sign a second proxy certificate request"
+	exit 1
+fi
+
+cat $Ucert $P1cert > $P2intermediate
+$verifycmd -CAfile $CAcert -untrusted $P2intermediate $P2cert
+echo
+echo "Certificate details"
+$x509cmd -subject -issuer -startdate -enddate -noout -in $P2cert
+
+echo
+echo The generated CA certificate is $CAcert
+echo The generated CA private key is $CAkey
+
+echo The generated user certificate is $Ucert
+echo The generated user private key is $Ukey
+
+echo The first generated proxy certificate is $P1cert
+echo The first generated proxy private key is $P1key
+
+echo The second generated proxy certificate is $P2cert
+echo The second generated proxy private key is $P2key
+
+/bin/rm err.ss
+#/bin/rm $P1intermediate
+#/bin/rm $P2intermediate
+exit 0
diff --git a/openssl/test/testss.com b/openssl/test/testss.com
new file mode 100644
index 0000000..32a74d0
--- /dev/null
+++ b/openssl/test/testss.com
@@ -0,0 +1,123 @@
+$! TESTSS.COM
+$
+$	__arch = "VAX"
+$	if f$getsyi("cpu") .ge. 128 then -
+	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$	if __arch .eqs. "" then __arch = "UNK"
+$!
+$	if (p1 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$	digest="-md5"
+$	reqcmd = "mcr ''exe_dir'openssl req"
+$	x509cmd = "mcr ''exe_dir'openssl x509 ''digest'"
+$	verifycmd = "mcr ''exe_dir'openssl verify"
+$	dummycnf = "sys$disk:[-.apps]openssl-vms.cnf"
+$
+$	CAkey="""keyCA.ss"""
+$	CAcert="""certCA.ss"""
+$	CAreq="""reqCA.ss"""
+$	CAconf="""CAss.cnf"""
+$	CAreq2="""req2CA.ss"""	! temp
+$
+$	Uconf="""Uss.cnf"""
+$	Ukey="""keyU.ss"""
+$	Ureq="""reqU.ss"""
+$	Ucert="""certU.ss"""
+$
+$	write sys$output ""
+$	write sys$output "make a certificate request using 'req'"
+$
+$	set noon
+$	define/user sys$output nla0:
+$	mcr 'exe_dir'openssl no-rsa
+$	save_severity=$SEVERITY
+$	set on
+$	if save_severity
+$	then
+$	    req_new="-newkey dsa:[-.apps]dsa512.pem"
+$	else
+$	    req_new="-new"
+$	endif
+$
+$	'reqcmd' -config 'CAconf' -out 'CAreq' -keyout 'CAkey' 'req_new' ! -out err.ss
+$	if $severity .ne. 1
+$	then
+$		write sys$output "error using 'req' to generate a certificate request"
+$		exit 3
+$	endif
+$	write sys$output ""
+$	write sys$output "convert the certificate request into a self signed certificate using 'x509'"
+$	define /user sys$output err.ss
+$	'x509cmd' "-CAcreateserial" -in 'CAreq' -days 30 -req -out 'CAcert' -signkey 'CAkey'
+$	if $severity .ne. 1
+$	then
+$		write sys$output "error using 'x509' to self sign a certificate request"
+$		exit 3
+$	endif
+$
+$	write sys$output ""
+$	write sys$output "convert a certificate into a certificate request using 'x509'"
+$	define /user sys$output err.ss
+$	'x509cmd' -in 'CAcert' -x509toreq -signkey 'CAkey' -out 'CAreq2'
+$	if $severity .ne. 1
+$	then
+$		write sys$output "error using 'x509' convert a certificate to a certificate request"
+$		exit 3
+$	endif
+$
+$	'reqcmd' -config 'dummycnf' -verify -in 'CAreq' -noout
+$	if $severity .ne. 1
+$	then
+$		write sys$output "first generated request is invalid"
+$		exit 3
+$	endif
+$
+$	'reqcmd' -config 'dummycnf' -verify -in 'CAreq2' -noout
+$	if $severity .ne. 1
+$	then
+$		write sys$output "second generated request is invalid"
+$		exit 3
+$	endif
+$
+$	'verifycmd' "-CAfile" 'CAcert' 'CAcert'
+$	if $severity .ne. 1
+$	then
+$		write sys$output "first generated cert is invalid"
+$		exit 3
+$	endif
+$
+$	write sys$output ""
+$	write sys$output "make another certificate request using 'req'"
+$	define /user sys$output err.ss
+$	'reqcmd' -config 'Uconf' -out 'Ureq' -keyout 'Ukey' 'req_new'
+$	if $severity .ne. 1
+$	then
+$		write sys$output "error using 'req' to generate a certificate request"
+$		exit 3
+$	endif
+$
+$	write sys$output ""
+$	write sys$output "sign certificate request with the just created CA via 'x509'"
+$	define /user sys$output err.ss
+$	'x509cmd' "-CAcreateserial" -in 'Ureq' -days 30 -req -out 'Ucert' "-CA" 'CAcert' "-CAkey" 'CAkey'
+$	if $severity .ne. 1
+$	then
+$		write sys$output "error using 'x509' to sign a certificate request"
+$		exit 3
+$	endif
+$
+$	'verifycmd' "-CAfile" 'CAcert' 'Ucert'
+$	write sys$output ""
+$	write sys$output "Certificate details"
+$	'x509cmd' -subject -issuer -startdate -enddate -noout -in 'Ucert'
+$
+$	write sys$output ""
+$	write sys$output "The generated CA certificate is ",CAcert
+$	write sys$output "The generated CA private key is ",CAkey
+$
+$	write sys$output "The generated user certificate is ",Ucert
+$	write sys$output "The generated user private key is ",Ukey
+$
+$	if f$search("err.ss;*") .nes. "" then delete err.ss;*
diff --git a/openssl/test/testssl b/openssl/test/testssl
new file mode 100644
index 0000000..aa5be9e
--- /dev/null
+++ b/openssl/test/testssl
@@ -0,0 +1,163 @@
+#!/bin/sh
+
+if [ "$1" = "" ]; then
+  key=../apps/server.pem
+else
+  key="$1"
+fi
+if [ "$2" = "" ]; then
+  cert=../apps/server.pem
+else
+  cert="$2"
+fi
+ssltest="../util/shlib_wrap.sh ./ssltest -key $key -cert $cert -c_key $key -c_cert $cert"
+
+if ../util/shlib_wrap.sh ../apps/openssl x509 -in $cert -text -noout | fgrep 'DSA Public Key' >/dev/null; then
+  dsa_cert=YES
+else
+  dsa_cert=NO
+fi
+
+if [ "$3" = "" ]; then
+  CA="-CApath ../certs"
+else
+  CA="-CAfile $3"
+fi
+
+if [ "$4" = "" ]; then
+  extra=""
+else
+  extra="$4"
+fi
+
+#############################################################################
+
+echo test sslv2
+$ssltest -ssl2 $extra || exit 1
+
+echo test sslv2 with server authentication
+$ssltest -ssl2 -server_auth $CA $extra || exit 1
+
+if [ $dsa_cert = NO ]; then
+  echo test sslv2 with client authentication
+  $ssltest -ssl2 -client_auth $CA $extra || exit 1
+
+  echo test sslv2 with both client and server authentication
+  $ssltest -ssl2 -server_auth -client_auth $CA $extra || exit 1
+fi
+
+echo test sslv3
+$ssltest -ssl3 $extra || exit 1
+
+echo test sslv3 with server authentication
+$ssltest -ssl3 -server_auth $CA $extra || exit 1
+
+echo test sslv3 with client authentication
+$ssltest -ssl3 -client_auth $CA $extra || exit 1
+
+echo test sslv3 with both client and server authentication
+$ssltest -ssl3 -server_auth -client_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3
+$ssltest $extra || exit 1
+
+echo test sslv2/sslv3 with server authentication
+$ssltest -server_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3 with client authentication
+$ssltest -client_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3 with both client and server authentication
+$ssltest -server_auth -client_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3 with both client and server authentication and small client buffers
+$ssltest -server_auth -client_auth -c_small_records $CA $extra || exit 1
+
+echo test sslv2/sslv3 with both client and server authentication and small server buffers
+$ssltest -server_auth -client_auth -s_small_records $CA $extra || exit 1
+
+echo test sslv2/sslv3 with both client and server authentication and small client and server buffers
+$ssltest -server_auth -client_auth -c_small_records -s_small_records $CA $extra || exit 1
+
+echo test sslv2/sslv3 with both client and server authentication and handshake cutthrough
+$ssltest -server_auth -client_auth -cutthrough $CA $extra || exit 1
+
+echo test sslv2 via BIO pair
+$ssltest -bio_pair -ssl2 $extra || exit 1
+
+echo test sslv2 with server authentication via BIO pair
+$ssltest -bio_pair -ssl2 -server_auth $CA $extra || exit 1
+
+if [ $dsa_cert = NO ]; then
+  echo test sslv2 with client authentication via BIO pair
+  $ssltest -bio_pair -ssl2 -client_auth $CA $extra || exit 1
+
+  echo test sslv2 with both client and server authentication via BIO pair
+  $ssltest -bio_pair -ssl2 -server_auth -client_auth $CA $extra || exit 1
+fi
+
+echo test sslv3 via BIO pair
+$ssltest -bio_pair -ssl3 $extra || exit 1
+
+echo test sslv3 with server authentication via BIO pair
+$ssltest -bio_pair -ssl3 -server_auth $CA $extra || exit 1
+
+echo test sslv3 with client authentication via BIO pair
+$ssltest -bio_pair -ssl3 -client_auth $CA $extra || exit 1
+
+echo test sslv3 with both client and server authentication via BIO pair
+$ssltest -bio_pair -ssl3 -server_auth -client_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3 via BIO pair
+$ssltest $extra || exit 1
+
+if [ $dsa_cert = NO ]; then
+  echo 'test sslv2/sslv3 w/o (EC)DHE via BIO pair'
+  $ssltest -bio_pair -no_dhe -no_ecdhe $extra || exit 1
+fi
+
+echo test sslv2/sslv3 with 1024bit DHE via BIO pair
+$ssltest -bio_pair -dhe1024dsa -v $extra || exit 1
+
+echo test sslv2/sslv3 with server authentication
+$ssltest -bio_pair -server_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3 with client authentication via BIO pair
+$ssltest -bio_pair -client_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3 with both client and server authentication via BIO pair
+$ssltest -bio_pair -server_auth -client_auth $CA $extra || exit 1
+
+echo test sslv2/sslv3 with both client and server authentication via BIO pair and app verify
+$ssltest -bio_pair -server_auth -client_auth -app_verify $CA $extra || exit 1
+
+#############################################################################
+
+if ../util/shlib_wrap.sh ../apps/openssl no-dh; then
+  echo skipping anonymous DH tests
+else
+  echo test tls1 with 1024bit anonymous DH, multiple handshakes
+  $ssltest -v -bio_pair -tls1 -cipher ADH -dhe1024dsa -num 10 -f -time $extra || exit 1
+fi
+
+if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then
+  echo skipping RSA tests
+else
+  echo 'test tls1 with 1024bit RSA, no (EC)DHE, multiple handshakes'
+  ../util/shlib_wrap.sh ./ssltest -v -bio_pair -tls1 -cert ../apps/server2.pem -no_dhe -no_ecdhe -num 10 -f -time $extra || exit 1
+
+  if ../util/shlib_wrap.sh ../apps/openssl no-dh; then
+    echo skipping RSA+DHE tests
+  else
+    echo test tls1 with 1024bit RSA, 1024bit DHE, multiple handshakes
+    ../util/shlib_wrap.sh ./ssltest -v -bio_pair -tls1 -cert ../apps/server2.pem -dhe1024dsa -num 10 -f -time $extra || exit 1
+  fi
+fi
+
+echo test tls1 with PSK
+$ssltest -tls1 -cipher PSK -psk abc123 $extra || exit 1
+
+echo test tls1 with PSK via BIO pair
+$ssltest -bio_pair -tls1 -cipher PSK -psk abc123 $extra || exit 1
+
+exit 0
diff --git a/openssl/test/testssl.com b/openssl/test/testssl.com
new file mode 100644
index 0000000..f19edc4
--- /dev/null
+++ b/openssl/test/testssl.com
@@ -0,0 +1,208 @@
+$! TESTSSL.COM
+$
+$	__arch = "VAX"
+$	if f$getsyi("cpu") .ge. 128 then -
+	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$	if __arch .eqs. "" then __arch = "UNK"
+$!
+$	if (p4 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$	texe_dir = "sys$disk:[-.''__arch'.exe.test]"
+$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$	if p1 .eqs. ""
+$	then
+$	    key="[-.apps]server.pem"
+$	else
+$	    key=p1
+$	endif
+$	if p2 .eqs. ""
+$	then
+$	    cert="[-.apps]server.pem"
+$	else
+$	    cert=p2
+$	endif
+$	ssltest = "mcr ''texe_dir'ssltest -key ''key'"+ -
+	 " -cert ''cert' -c_key ''key' -c_cert ''cert'"
+$!
+$	set noon
+$	define/user sys$output testssl-x509-output.
+$	define/user sys$error nla0:
+$	mcr 'exe_dir'openssl x509 -in 'cert' -text -noout
+$	define/user sys$error nla0:
+$	search/output=nla0: testssl-x509-output. "DSA Public Key"/exact
+$	if $severity .eq. 1
+$	then
+$	    dsa_cert = "YES"
+$	else
+$	    dsa_cert = "NO"
+$	endif
+$	delete testssl-x509-output.;*
+$
+$	if p3 .eqs. ""
+$	then
+$	    copy/concatenate [-.certs]*.pem certs.tmp
+$	    CA = """-CAfile"" certs.tmp"
+$	else
+$	    CA = """-CAfile"" "+p3
+$	endif
+$
+$!###########################################################################
+$
+$	write sys$output "test sslv2"
+$	'ssltest' -ssl2
+$	if $severity .ne. 1 then goto exit3
+$
+$	write sys$output "test sslv2 with server authentication"
+$	'ssltest' -ssl2 -server_auth 'CA'
+$	if $severity .ne. 1 then goto exit3
+$
+$	if .not. dsa_cert
+$	then
+$	    write sys$output "test sslv2 with client authentication"
+$	    'ssltest' -ssl2 -client_auth 'CA'
+$	    if $severity .ne. 1 then goto exit3
+$
+$	    write sys$output "test sslv2 with both client and server authentication"
+$	    'ssltest' -ssl2 -server_auth -client_auth 'CA'
+$	    if $severity .ne. 1 then goto exit3
+$	endif
+$
+$	write sys$output "test sslv3"
+$	'ssltest' -ssl3
+$	if $severity .ne. 1 then goto exit3
+$
+$	write sys$output "test sslv3 with server authentication"
+$	'ssltest' -ssl3 -server_auth 'CA'
+$	if $severity .ne. 1 then goto exit3
+$
+$	write sys$output "test sslv3 with client authentication"
+$	'ssltest' -ssl3 -client_auth 'CA'
+$	if $severity .ne. 1 then goto exit3
+$
+$	write sys$output "test sslv3 with both client and server authentication"
+$	'ssltest' -ssl3 -server_auth -client_auth 'CA'
+$	if $severity .ne. 1 then goto exit3
+$
+$	write sys$output "test sslv2/sslv3"
+$	'ssltest'
+$	if $severity .ne. 1 then goto exit3
+$
+$	write sys$output "test sslv2/sslv3 with server authentication"
+$	'ssltest' -server_auth 'CA'
+$	if $severity .ne. 1 then goto exit3
+$
+$	write sys$output "test sslv2/sslv3 with client authentication"
+$	'ssltest' -client_auth 'CA'
+$	if $severity .ne. 1 then goto exit3
+$
+$	write sys$output "test sslv2/sslv3 with both client and server authentication"
+$	'ssltest' -server_auth -client_auth 'CA'
+$	if $severity .ne. 1 then goto exit3
+$
+$	write sys$output "test sslv2 via BIO pair"
+$	'ssltest' -bio_pair -ssl2 
+$	if $severity .ne. 1 then goto exit3
+$
+$	write sys$output "test sslv2 with server authentication via BIO pair"
+$	'ssltest' -bio_pair -ssl2 -server_auth 'CA' 
+$	if $severity .ne. 1 then goto exit3
+$
+$	if .not. dsa_cert
+$	then
+$	    write sys$output "test sslv2 with client authentication via BIO pair"
+$	    'ssltest' -bio_pair -ssl2 -client_auth 'CA' 
+$	    if $severity .ne. 1 then goto exit3
+$
+$	    write sys$output "test sslv2 with both client and server authentication via BIO pair"
+$	    'ssltest' -bio_pair -ssl2 -server_auth -client_auth 'CA' 
+$	    if $severity .ne. 1 then goto exit3
+$	endif
+$
+$	write sys$output "test sslv3 via BIO pair"
+$	'ssltest' -bio_pair -ssl3 
+$	if $severity .ne. 1 then goto exit3
+$
+$	write sys$output "test sslv3 with server authentication via BIO pair"
+$	'ssltest' -bio_pair -ssl3 -server_auth 'CA' 
+$	if $severity .ne. 1 then goto exit3
+$
+$	write sys$output "test sslv3 with client authentication via BIO pair"
+$	'ssltest' -bio_pair -ssl3 -client_auth 'CA' 
+$	if $severity .ne. 1 then goto exit3
+ 
+$	write sys$output "test sslv3 with both client and server authentication via BIO pair"
+$	'ssltest' -bio_pair -ssl3 -server_auth -client_auth 'CA' 
+$	if $severity .ne. 1 then goto exit3
+$
+$	write sys$output "test sslv2/sslv3 via BIO pair"
+$	'ssltest' 
+$	if $severity .ne. 1 then goto exit3
+$
+$	if .not. dsa_cert
+$	then
+$	    write sys$output "test sslv2/sslv3 w/o DHE via BIO pair"
+$	    'ssltest' -bio_pair -no_dhe
+$	    if $severity .ne. 1 then goto exit3
+$	endif
+$
+$	write sys$output "test sslv2/sslv3 with 1024 bit DHE via BIO pair"
+$	'ssltest' -bio_pair -dhe1024dsa -v
+$	if $severity .ne. 1 then goto exit3
+$
+$	write sys$output "test sslv2/sslv3 with server authentication"
+$	'ssltest' -bio_pair -server_auth 'CA' 
+$	if $severity .ne. 1 then goto exit3
+$
+$	write sys$output "test sslv2/sslv3 with client authentication via BIO pair"
+$	'ssltest' -bio_pair -client_auth 'CA' 
+$	if $severity .ne. 1 then goto exit3
+$
+$	write sys$output "test sslv2/sslv3 with both client and server authentication via BIO pair"
+$	'ssltest' -bio_pair -server_auth -client_auth 'CA' 
+$	if $severity .ne. 1 then goto exit3
+$
+$!###########################################################################
+$
+$	define/user sys$output nla0:
+$	mcr 'exe_dir'openssl no-rsa
+$	no_rsa=$SEVERITY
+$	define/user sys$output nla0:
+$	mcr 'exe_dir'openssl no-dh
+$	no_dh=$SEVERITY
+$
+$	if no_dh
+$	then
+$	    write sys$output "skipping anonymous DH tests"
+$	else
+$	    write sys$output "test tls1 with 1024bit anonymous DH, multiple handshakes"
+$	    'ssltest' -v -bio_pair -tls1 -cipher "ADH" -dhe1024dsa -num 10 -f -time
+$	    if $severity .ne. 1 then goto exit3
+$	endif
+$
+$	if no_rsa
+$	then
+$	    write sys$output "skipping RSA tests"
+$	else
+$	    write sys$output "test tls1 with 1024bit RSA, no DHE, multiple handshakes"
+$	    mcr 'texe_dir'ssltest -v -bio_pair -tls1 -cert [-.apps]server2.pem -no_dhe -num 10 -f -time
+$	    if $severity .ne. 1 then goto exit3
+$
+$	    if no_dh
+$	    then
+$		write sys$output "skipping RSA+DHE tests"
+$	    else
+$		write sys$output "test tls1 with 1024bit RSA, 1024bit DHE, multiple handshakes"
+$		mcr 'texe_dir'ssltest -v -bio_pair -tls1 -cert [-.apps]server2.pem -dhe1024dsa -num 10 -f -time
+$		if $severity .ne. 1 then goto exit3
+$	    endif
+$	endif
+$
+$	RET = 1
+$	goto exit
+$ exit3:
+$	RET = 3
+$ exit:
+$	if p3 .eqs. "" then delete certs.tmp;*
+$	set on
+$	exit 'RET'
diff --git a/openssl/test/testsslproxy b/openssl/test/testsslproxy
new file mode 100644
index 0000000..58bbda8
--- /dev/null
+++ b/openssl/test/testsslproxy
@@ -0,0 +1,10 @@
+#! /bin/sh
+
+echo 'Testing a lot of proxy conditions.'
+echo 'Some of them may turn out being invalid, which is fine.'
+for auth in A B C BC; do
+    for cond in A B C 'A|B&!C'; do
+	sh ./testssl $1 $2 $3 "-proxy -proxy_auth $auth -proxy_cond $cond"
+	if [ $? = 3 ]; then exit 1; fi
+    done
+done
diff --git a/openssl/test/testtsa b/openssl/test/testtsa
new file mode 100644
index 0000000..bb653b5
--- /dev/null
+++ b/openssl/test/testtsa
@@ -0,0 +1,238 @@
+#!/bin/sh
+
+#
+# A few very basic tests for the 'ts' time stamping authority command.
+#
+
+SH="/bin/sh"
+if test "$OSTYPE" = msdosdjgpp; then
+    PATH="../apps\;$PATH"
+else
+    PATH="../apps:$PATH"
+fi
+export SH PATH
+
+OPENSSL_CONF="../CAtsa.cnf"
+export OPENSSL_CONF
+# Because that's what ../apps/CA.sh really looks at
+SSLEAY_CONFIG="-config $OPENSSL_CONF"
+export SSLEAY_CONFIG
+
+OPENSSL="`pwd`/../util/opensslwrap.sh"
+export OPENSSL
+
+error () {
+
+    echo "TSA test failed!" >&2
+    exit 1
+}
+
+setup_dir () {
+
+    rm -rf tsa 2>/dev/null
+    mkdir tsa
+    cd ./tsa
+}
+
+clean_up_dir () {
+
+    cd ..
+    rm -rf tsa
+}
+
+create_ca () {
+
+    echo "Creating a new CA for the TSA tests..."
+    TSDNSECT=ts_ca_dn
+    export TSDNSECT   
+    ../../util/shlib_wrap.sh ../../apps/openssl req -new -x509 -nodes \
+	-out tsaca.pem -keyout tsacakey.pem
+    test $? != 0 && error
+}
+
+create_tsa_cert () {
+
+    INDEX=$1
+    export INDEX
+    EXT=$2
+    TSDNSECT=ts_cert_dn
+    export TSDNSECT   
+
+    ../../util/shlib_wrap.sh ../../apps/openssl req -new \
+	-out tsa_req${INDEX}.pem -keyout tsa_key${INDEX}.pem
+    test $? != 0 && error
+echo Using extension $EXT
+    ../../util/shlib_wrap.sh ../../apps/openssl x509 -req \
+	-in tsa_req${INDEX}.pem -out tsa_cert${INDEX}.pem \
+	-CA tsaca.pem -CAkey tsacakey.pem -CAcreateserial \
+	-extfile $OPENSSL_CONF -extensions $EXT
+    test $? != 0 && error
+}
+
+print_request () {
+
+    ../../util/shlib_wrap.sh ../../apps/openssl ts -query -in $1 -text
+}
+
+create_time_stamp_request1 () {
+
+    ../../util/shlib_wrap.sh ../../apps/openssl ts -query -data ../testtsa -policy tsa_policy1 -cert -out req1.tsq
+    test $? != 0 && error
+}
+
+create_time_stamp_request2 () {
+
+    ../../util/shlib_wrap.sh ../../apps/openssl ts -query -data ../testtsa -policy tsa_policy2 -no_nonce \
+	-out req2.tsq
+    test $? != 0 && error
+}
+
+create_time_stamp_request3 () {
+
+    ../../util/shlib_wrap.sh ../../apps/openssl ts -query -data ../CAtsa.cnf -no_nonce -out req3.tsq
+    test $? != 0 && error
+}
+
+print_response () {
+
+    ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $1 -text
+    test $? != 0 && error
+}
+
+create_time_stamp_response () {
+
+    ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -section $3 -queryfile $1 -out $2
+    test $? != 0 && error
+}
+
+time_stamp_response_token_test () {
+
+    RESPONSE2=$2.copy.tsr
+    TOKEN_DER=$2.token.der
+    ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $2 -out $TOKEN_DER -token_out
+    test $? != 0 && error
+    ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $TOKEN_DER -token_in -out $RESPONSE2
+    test $? != 0 && error
+    cmp $RESPONSE2 $2
+    test $? != 0 && error
+    ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $2 -text -token_out
+    test $? != 0 && error
+    ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $TOKEN_DER -token_in -text -token_out
+    test $? != 0 && error
+    ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -queryfile $1 -text -token_out
+    test $? != 0 && error
+}
+
+verify_time_stamp_response () {
+
+    ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -queryfile $1 -in $2 -CAfile tsaca.pem \
+	-untrusted tsa_cert1.pem
+    test $? != 0 && error
+    ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -data $3 -in $2 -CAfile tsaca.pem \
+	-untrusted tsa_cert1.pem
+    test $? != 0 && error
+}
+
+verify_time_stamp_token () {
+
+    # create the token from the response first
+    ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $2 -out $2.token -token_out
+    test $? != 0 && error
+    ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -queryfile $1 -in $2.token -token_in \
+	-CAfile tsaca.pem -untrusted tsa_cert1.pem
+    test $? != 0 && error
+    ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -data $3 -in $2.token -token_in \
+	-CAfile tsaca.pem -untrusted tsa_cert1.pem
+    test $? != 0 && error
+}
+
+verify_time_stamp_response_fail () {
+
+    ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -queryfile $1 -in $2 -CAfile tsaca.pem \
+	-untrusted tsa_cert1.pem
+    # Checks if the verification failed, as it should have.
+    test $? = 0 && error
+    echo Ok
+}
+
+# main functions
+
+echo "Setting up TSA test directory..."
+setup_dir
+
+echo "Creating CA for TSA tests..."
+create_ca
+
+echo "Creating tsa_cert1.pem TSA server cert..."
+create_tsa_cert 1 tsa_cert
+
+echo "Creating tsa_cert2.pem non-TSA server cert..."
+create_tsa_cert 2 non_tsa_cert
+
+echo "Creating req1.req time stamp request for file testtsa..."
+create_time_stamp_request1
+
+echo "Printing req1.req..."
+print_request req1.tsq
+
+echo "Generating valid response for req1.req..."
+create_time_stamp_response req1.tsq resp1.tsr tsa_config1
+
+echo "Printing response..."
+print_response resp1.tsr
+
+echo "Verifying valid response..."
+verify_time_stamp_response req1.tsq resp1.tsr ../testtsa
+
+echo "Verifying valid token..."
+verify_time_stamp_token req1.tsq resp1.tsr ../testtsa
+
+# The tests below are commented out, because invalid signer certificates
+# can no longer be specified in the config file.
+
+# echo "Generating _invalid_ response for req1.req..."
+# create_time_stamp_response req1.tsq resp1_bad.tsr tsa_config2
+
+# echo "Printing response..."
+# print_response resp1_bad.tsr
+
+# echo "Verifying invalid response, it should fail..."
+# verify_time_stamp_response_fail req1.tsq resp1_bad.tsr
+
+echo "Creating req2.req time stamp request for file testtsa..."
+create_time_stamp_request2
+
+echo "Printing req2.req..."
+print_request req2.tsq
+
+echo "Generating valid response for req2.req..."
+create_time_stamp_response req2.tsq resp2.tsr tsa_config1
+
+echo "Checking '-token_in' and '-token_out' options with '-reply'..."
+time_stamp_response_token_test req2.tsq resp2.tsr
+
+echo "Printing response..."
+print_response resp2.tsr
+
+echo "Verifying valid response..."
+verify_time_stamp_response req2.tsq resp2.tsr ../testtsa
+
+echo "Verifying response against wrong request, it should fail..."
+verify_time_stamp_response_fail req1.tsq resp2.tsr
+
+echo "Verifying response against wrong request, it should fail..."
+verify_time_stamp_response_fail req2.tsq resp1.tsr
+
+echo "Creating req3.req time stamp request for file CAtsa.cnf..."
+create_time_stamp_request3
+
+echo "Printing req3.req..."
+print_request req3.tsq
+
+echo "Verifying response against wrong request, it should fail..."
+verify_time_stamp_response_fail req3.tsq resp1.tsr
+
+echo "Cleaning up..."
+clean_up_dir
+
+exit 0
diff --git a/openssl/test/testtsa.com b/openssl/test/testtsa.com
new file mode 100644
index 0000000..29fb1d0
--- /dev/null
+++ b/openssl/test/testtsa.com
@@ -0,0 +1,255 @@
+$!
+$! A few very basic tests for the 'ts' time stamping authority command.
+$!
+$
+$	__arch = "VAX"
+$	if f$getsyi("cpu") .ge. 128 then -
+	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$	if __arch .eqs. "" then __arch = "UNK"
+$!
+$	if (p4 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$	openssl = "mcr ''f$parse(exe_dir+"openssl.exe")'"
+$	OPENSSL_CONF = "[-]CAtsa.cnf"
+$	! Because that's what ../apps/CA.sh really looks at
+$	SSLEAY_CONFIG = "-config " + OPENSSL_CONF
+$
+$ error:
+$	subroutine
+$		write sys$error "TSA test failed!"
+$		exit 3
+$	endsubroutine
+$
+$ setup_dir:
+$	subroutine
+$
+$		if f$search("tsa.dir") .nes ""
+$		then
+$			@[-.util]deltree [.tsa]*.*
+$ 			set file/prot=(S:RWED,O:RWED,G:RWED,W:RWED) tsa.dir;*
+$ 			delete tsa.dir;*
+$		endif
+$
+$		create/dir [.tsa]
+$		set default [.tsa]
+$	endsubroutine
+$
+$ clean_up_dir:
+$	subroutine
+$
+$		set default [-]
+$		@[-.util]deltree [.tsa]*.*
+$ 		set file/prot=(S:RWED,O:RWED,G:RWED,W:RWED) tsa.dir;*
+$ 		delete tsa.dir;*
+$	endsubroutine
+$
+$ create_ca:
+$	subroutine
+$
+$		write sys$output "Creating a new CA for the TSA tests..."
+$		TSDNSECT = "ts_ca_dn"
+$		openssl req -new -x509 -nodes -
+			-out tsaca.pem -keyout tsacakey.pem
+$		if $severity .ne. 1 then call error
+$	endsubroutine
+$
+$ create_tsa_cert:
+$	subroutine
+$
+$		INDEX=p1
+$		EXT=p2
+$		TSDNSECT = "ts_cert_dn"
+$
+$		openssl req -new -
+			-out tsa_req'INDEX'.pem -keyout tsa_key'INDEX'.pem
+$		if $severity .ne. 1 then call error
+$
+$		write sys$output "Using extension ''EXT'"
+$		openssl x509 -req -
+			-in tsa_req'INDEX'.pem -out tsa_cert'INDEX'.pem -
+			"-CA" tsaca.pem "-CAkey" tsacakey.pem "-CAcreateserial" -
+			-extfile 'OPENSSL_CONF' -extensions "''EXT'"
+$		if $severity .ne. 1 then call error
+$	endsubroutine
+$
+$ print_request:
+$	subroutine
+$
+$		openssl ts -query -in 'p1' -text
+$	endsubroutine
+$
+$ create_time_stamp_request1: subroutine
+$
+$		openssl ts -query -data [-]testtsa.com -policy tsa_policy1 -
+			-cert -out req1.tsq
+$		if $severity .ne. 1 then call error
+$	endsubroutine
+$
+$ create_time_stamp_request2: subroutine
+$
+$		openssl ts -query -data [-]testtsa.com -policy tsa_policy2 -
+			-no_nonce -out req2.tsq
+$		if $severity .ne. 1 then call error
+$	endsubroutine
+$
+$ create_time_stamp_request3: subroutine
+$
+$		openssl ts -query -data [-]CAtsa.cnf -no_nonce -out req3.tsq
+$		if $severity .ne. 1 then call error
+$	endsubroutine
+$
+$ print_response:
+$	subroutine
+$
+$		openssl ts -reply -in 'p1' -text
+$		if $severity .ne. 1 then call error
+$	endsubroutine
+$
+$ create_time_stamp_response:
+$	subroutine
+$
+$		openssl ts -reply -section 'p3' -queryfile 'p1' -out 'p2'
+$		if $severity .ne. 1 then call error
+$	endsubroutine
+$
+$ time_stamp_response_token_test:
+$	subroutine
+$
+$		RESPONSE2 = p2+ "-copy_tsr"
+$		TOKEN_DER = p2+ "-token_der"
+$		openssl ts -reply -in 'p2' -out 'TOKEN_DER' -token_out
+$		if $severity .ne. 1 then call error
+$		openssl ts -reply -in 'TOKEN_DER' -token_in -out 'RESPONSE2'
+$		if $severity .ne. 1 then call error
+$		backup/compare 'RESPONSE2' 'p2'
+$		if $severity .ne. 1 then call error
+$		openssl ts -reply -in 'p2' -text -token_out
+$		if $severity .ne. 1 then call error
+$		openssl ts -reply -in 'TOKEN_DER' -token_in -text -token_out
+$		if $severity .ne. 1 then call error
+$		openssl ts -reply -queryfile 'p1' -text -token_out
+$		if $severity .ne. 1 then call error
+$	endsubroutine
+$
+$ verify_time_stamp_response:
+$	subroutine
+$
+$		openssl ts -verify -queryfile 'p1' -in 'p2' -
+			"-CAfile" tsaca.pem -untrusted tsa_cert1.pem
+$		if $severity .ne. 1 then call error
+$		openssl ts -verify -data 'p3' -in 'p2' -
+			"-CAfile" tsaca.pem -untrusted tsa_cert1.pem
+$		if $severity .ne. 1 then call error
+$	endsubroutine
+$
+$ verify_time_stamp_token:
+$	subroutine
+$
+$		! create the token from the response first
+$		openssl ts -reply -in "''p2'" -out "''p2'-token" -token_out
+$		if $severity .ne. 1 then call error
+$		openssl ts -verify -queryfile "''p1'" -in "''p2'-token" -
+		 -token_in "-CAfile" tsaca.pem -untrusted tsa_cert1.pem
+$		if $severity .ne. 1 then call error
+$		openssl ts -verify -data "''p3'" -in "''p2'-token" -
+		 -token_in "-CAfile" tsaca.pem -untrusted tsa_cert1.pem
+$		if $severity .ne. 1 then call error
+$	endsubroutine
+$
+$ verify_time_stamp_response_fail:
+$	subroutine
+$
+$		openssl ts -verify -queryfile 'p1' -in 'p2' -
+			"-CAfile" tsaca.pem -untrusted tsa_cert1.pem
+$		! Checks if the verification failed, as it should have.
+$		if $severity .eq. 1 then call error
+$		write sys$output "Ok"
+$	endsubroutine
+$
+$	! Main body ----------------------------------------------------------
+$
+$	set noon
+$
+$	write sys$output "Setting up TSA test directory..."
+$	call setup_dir
+$
+$	write sys$output "Creating CA for TSA tests..."
+$	call create_ca
+$
+$	write sys$output "Creating tsa_cert1.pem TSA server cert..."
+$	call create_tsa_cert 1 "tsa_cert"
+$
+$	write sys$output "Creating tsa_cert2.pem non-TSA server cert..."
+$	call create_tsa_cert 2 "non_tsa_cert"
+$
+$	write sys$output "Creating req1.req time stamp request for file testtsa..."
+$	call create_time_stamp_request1
+$
+$	write sys$output "Printing req1.req..."
+$	call print_request "req1.tsq"
+$
+$	write sys$output "Generating valid response for req1.req..."
+$	call create_time_stamp_response "req1.tsq" "resp1.tsr" "tsa_config1"
+$
+$	write sys$output "Printing response..."
+$	call print_response "resp1.tsr"
+$
+$	write sys$output "Verifying valid response..."
+$	call verify_time_stamp_response "req1.tsq" "resp1.tsr" "[-]testtsa.com"
+$
+$	write sys$output "Verifying valid token..."
+$	call verify_time_stamp_token "req1.tsq" "resp1.tsr" "[-]testtsa.com"
+$
+$	! The tests below are commented out, because invalid signer certificates
+$	! can no longer be specified in the config file.
+$
+$	! write sys$output "Generating _invalid_ response for req1.req..."
+$	! call create_time_stamp_response "req1.tsq" "resp1_bad.tsr" "tsa_config2"
+$
+$	! write sys$output "Printing response..."
+$	! call print_response "resp1_bad.tsr"
+$
+$	! write sys$output "Verifying invalid response, it should fail..."
+$	! call verify_time_stamp_response_fail "req1.tsq" "resp1_bad.tsr"
+$
+$	write sys$output "Creating req2.req time stamp request for file testtsa..."
+$	call create_time_stamp_request2
+$
+$	write sys$output "Printing req2.req..."
+$	call print_request "req2.tsq"
+$
+$	write sys$output "Generating valid response for req2.req..."
+$	call create_time_stamp_response "req2.tsq" "resp2.tsr" "tsa_config1"
+$
+$	write sys$output "Checking '-token_in' and '-token_out' options with '-reply'..."
+$	call time_stamp_response_token_test "req2.tsq" "resp2.tsr"
+$
+$	write sys$output "Printing response..."
+$	call print_response "resp2.tsr"
+$
+$	write sys$output "Verifying valid response..."
+$	call verify_time_stamp_response "req2.tsq" "resp2.tsr" "[-]testtsa.com"
+$
+$	write sys$output "Verifying response against wrong request, it should fail..."
+$	call verify_time_stamp_response_fail "req1.tsq" "resp2.tsr"
+$
+$	write sys$output "Verifying response against wrong request, it should fail..."
+$	call verify_time_stamp_response_fail "req2.tsq" "resp1.tsr"
+$
+$	write sys$output "Creating req3.req time stamp request for file CAtsa.cnf..."
+$	call create_time_stamp_request3
+$
+$	write sys$output "Printing req3.req..."
+$	call print_request "req3.tsq"
+$
+$	write sys$output "Verifying response against wrong request, it should fail..."
+$	call verify_time_stamp_response_fail "req3.tsq" "resp1.tsr"
+$
+$	write sys$output "Cleaning up..."
+$	call clean_up_dir
+$
+$	set on
+$
+$	exit
diff --git a/openssl/test/testx509.pem b/openssl/test/testx509.pem
new file mode 100644
index 0000000..8a85d14
--- /dev/null
+++ b/openssl/test/testx509.pem
@@ -0,0 +1,10 @@
+-----BEGIN CERTIFICATE-----
+MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV
+BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz
+MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM
+RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF
+AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO
+/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE
+Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ
+zl9HYIMxATFyqSiD9jsx
+-----END CERTIFICATE-----
diff --git a/openssl/test/times b/openssl/test/times
new file mode 100644
index 0000000..6b66eb3
--- /dev/null
+++ b/openssl/test/times
@@ -0,0 +1,113 @@
+
+More number for the questions about SSL overheads....
+
+The following numbers were generated on a Pentium pro 200, running Linux.
+They give an indication of the SSL protocol and encryption overheads.
+
+The program that generated them is an unreleased version of ssl/ssltest.c
+which is the SSLeay ssl protocol testing program.  It is a single process that
+talks both sides of the SSL protocol via a non-blocking memory buffer
+interface.
+
+How do I read this?  The protocol and cipher are reasonable obvious.
+The next number is the number of connections being made.  The next is the
+number of bytes exchanged between the client and server side of the protocol.
+This is the number of bytes that the client sends to the server, and then
+the server sends back.  Because this is all happening in one process,
+the data is being encrypted, decrypted, encrypted and then decrypted again.
+It is a round trip of that many bytes.  Because the one process performs
+both the client and server sides of the protocol and it sends this many bytes
+each direction, multiply this number by 4 to generate the number
+of bytes encrypted/decrypted/MACed.  The first time value is how many seconds
+elapsed doing a full SSL handshake, the second is the cost of one
+full handshake and the rest being session-id reuse.
+
+SSLv2 RC4-MD5      1000 x      1   12.83s   0.70s
+SSLv3 NULL-MD5     1000 x      1   14.35s   1.47s
+SSLv3 RC4-MD5      1000 x      1   14.46s   1.56s
+SSLv3 RC4-MD5      1000 x      1   51.93s   1.62s 1024bit RSA
+SSLv3 RC4-SHA      1000 x      1   14.61s   1.83s
+SSLv3 DES-CBC-SHA  1000 x      1   14.70s   1.89s
+SSLv3 DES-CBC3-SHA 1000 x      1   15.16s   2.16s
+
+SSLv2 RC4-MD5      1000 x   1024   13.72s   1.27s
+SSLv3 NULL-MD5     1000 x   1024   14.79s   1.92s
+SSLv3 RC4-MD5      1000 x   1024   52.58s   2.29s 1024bit RSA
+SSLv3 RC4-SHA      1000 x   1024   15.39s   2.67s
+SSLv3 DES-CBC-SHA  1000 x   1024   16.45s   3.55s
+SSLv3 DES-CBC3-SHA 1000 x   1024   18.21s   5.38s
+
+SSLv2 RC4-MD5      1000 x  10240   18.97s   6.52s
+SSLv3 NULL-MD5     1000 x  10240   17.79s   5.11s
+SSLv3 RC4-MD5      1000 x  10240   20.25s   7.90s
+SSLv3 RC4-MD5      1000 x  10240   58.26s   8.08s 1024bit RSA
+SSLv3 RC4-SHA      1000 x  10240   22.96s  11.44s
+SSLv3 DES-CBC-SHA  1000 x  10240   30.65s  18.41s
+SSLv3 DES-CBC3-SHA 1000 x  10240   47.04s  34.53s
+
+SSLv2 RC4-MD5      1000 x 102400   70.22s  57.74s
+SSLv3 NULL-MD5     1000 x 102400   43.73s  31.03s
+SSLv3 RC4-MD5      1000 x 102400   71.32s  58.83s
+SSLv3 RC4-MD5      1000 x 102400  109.66s  59.20s 1024bit RSA
+SSLv3 RC4-SHA      1000 x 102400   95.88s  82.21s
+SSLv3 DES-CBC-SHA  1000 x 102400  173.22s 160.55s
+SSLv3 DES-CBC3-SHA 1000 x 102400  336.61s 323.82s
+
+What does this all mean?  Well for a server, with no session-id reuse, with
+a transfer size of 10240 bytes, using RC4-MD5 and a 512bit server key,
+a Pentium pro 200 running Linux can handle the SSLv3 protocol overheads of
+about 49 connections a second.  Reality will be quite different :-).
+
+Remember the first number is 1000 full ssl handshakes, the second is
+1 full and 999 with session-id reuse.  The RSA overheads for each exchange
+would be one public and one private operation, but the protocol/MAC/cipher
+cost would be quite similar in both the client and server.
+
+eric (adding numbers to speculation)
+
+--- Appendix ---
+- The time measured is user time but these number a very rough.
+- Remember this is the cost of both client and server sides of the protocol.
+- The TCP/kernel overhead of connection establishment is normally the
+  killer in SSL.  Often delays in the TCP protocol will make session-id
+  reuse look slower that new sessions, but this would not be the case on
+  a loaded server.
+- The TCP round trip latencies, while slowing individual connections,
+  would have minimal impact on throughput.
+- Instead of sending one 102400 byte buffer, one 8k buffer is sent until
+- the required number of bytes are processed.
+- The SSLv3 connections were actually SSLv2 compatible SSLv3 headers.
+- A 512bit server key was being used except where noted.
+- No server key verification was being performed on the client side of the
+  protocol.  This would slow things down very little.
+- The library being used is SSLeay 0.8.x.
+- The normal measuring system was commands of the form
+  time ./ssltest -num 1000 -bytes 102400 -cipher DES-CBC-SHA -reuse
+  This modified version of ssltest should be in the next public release of
+  SSLeay.
+
+The general cipher performance number for this platform are
+
+SSLeay 0.8.2a 04-Sep-1997
+built on Fri Sep  5 17:37:05 EST 1997
+options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2)
+C flags:gcc -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized 
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2               131.02k      368.41k      500.57k      549.21k      566.09k
+mdc2              535.60k      589.10k      595.88k      595.97k      594.54k
+md5              1801.53k     9674.77k    17484.03k    21849.43k    23592.96k
+sha              1261.63k     5533.25k     9285.63k    11187.88k    11913.90k
+sha1             1103.13k     4782.53k     7933.78k     9472.34k    10070.70k
+rc4             10722.53k    14443.93k    15215.79k    15299.24k    15219.59k
+des cbc          3286.57k     3827.73k     3913.39k     3931.82k     3926.70k
+des ede3         1443.50k     1549.08k     1561.17k     1566.38k     1564.67k
+idea cbc         2203.64k     2508.16k     2538.33k     2543.62k     2547.71k
+rc2 cbc          1430.94k     1511.59k     1524.82k     1527.13k     1523.33k
+blowfish cbc     4716.07k     5965.82k     6190.17k     6243.67k     6234.11k
+                  sign    verify
+rsa  512 bits   0.0100s   0.0011s
+rsa 1024 bits   0.0451s   0.0012s
+rsa 2048 bits   0.2605s   0.0086s
+rsa 4096 bits   1.6883s   0.0302s
+
diff --git a/openssl/test/tpkcs7 b/openssl/test/tpkcs7
new file mode 100644
index 0000000..3e435ff
--- /dev/null
+++ b/openssl/test/tpkcs7
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+cmd='../util/shlib_wrap.sh ../apps/openssl pkcs7'
+
+if [ "$1"x != "x" ]; then
+	t=$1
+else
+	t=testp7.pem
+fi
+
+echo testing pkcs7 conversions
+cp $t fff.p
+
+echo "p -> d"
+$cmd -in fff.p -inform p -outform d >f.d
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in fff.p -inform p -outform p >f.p
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> d"
+$cmd -in f.d -inform d -outform d >ff.d1
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> d"
+$cmd -in f.p -inform p -outform d >ff.d3
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> p"
+$cmd -in f.d -inform d -outform p >ff.p1
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in f.p -inform p -outform p >ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp fff.p f.p
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp f.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+cmp f.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+/bin/rm -f f.* ff.* fff.*
+exit 0
diff --git a/openssl/test/tpkcs7.com b/openssl/test/tpkcs7.com
new file mode 100644
index 0000000..3fc4982
--- /dev/null
+++ b/openssl/test/tpkcs7.com
@@ -0,0 +1,59 @@
+$! TPKCS7.COM  --  Tests pkcs7 keys
+$
+$	__arch = "VAX"
+$	if f$getsyi("cpu") .ge. 128 then -
+	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$	if __arch .eqs. "" then __arch = "UNK"
+$!
+$	if (p2 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$	cmd = "mcr ''exe_dir'openssl pkcs7"
+$
+$	t = "testp7.pem"
+$	if p1 .nes. "" then t = p1
+$
+$	write sys$output "testing PKCS7 conversions"
+$	if f$search("fff.*") .nes "" then delete fff.*;*
+$	if f$search("ff.*") .nes "" then delete ff.*;*
+$	if f$search("f.*") .nes "" then delete f.*;*
+$	convert/fdl=sys$input: 't' fff.p
+RECORD
+	FORMAT STREAM_LF
+$
+$	write sys$output "p -> d"
+$	'cmd' -in fff.p -inform p -outform d -out f.d
+$	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> p"
+$	'cmd' -in fff.p -inform p -outform p -out f.p
+$	if $severity .ne. 1 then exit 3
+$
+$	write sys$output "d -> d"
+$	'cmd' -in f.d -inform d -outform d -out ff.d1
+$	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> d"
+$	'cmd' -in f.p -inform p -outform d -out ff.d3
+$	if $severity .ne. 1 then exit 3
+$
+$
+$	write sys$output "d -> p"
+$	'cmd' -in f.d -inform d -outform p -out ff.p1
+$	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> p"
+$	'cmd' -in f.p -inform p -outform p -out ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$	backup/compare fff.p f.p
+$	if $severity .ne. 1 then exit 3
+$	backup/compare fff.p ff.p1
+$	if $severity .ne. 1 then exit 3
+$	backup/compare fff.p ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$	backup/compare f.p ff.p1
+$	if $severity .ne. 1 then exit 3
+$	backup/compare f.p ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$	delete f.*;*,ff.*;*,fff.*;*
diff --git a/openssl/test/tpkcs7d b/openssl/test/tpkcs7d
new file mode 100644
index 0000000..64fc28e
--- /dev/null
+++ b/openssl/test/tpkcs7d
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+cmd='../util/shlib_wrap.sh ../apps/openssl pkcs7'
+
+if [ "$1"x != "x" ]; then
+	t=$1
+else
+	t=pkcs7-1.pem
+fi
+
+echo "testing pkcs7 conversions (2)"
+cp $t fff.p
+
+echo "p -> d"
+$cmd -in fff.p -inform p -outform d >f.d
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in fff.p -inform p -outform p >f.p
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> d"
+$cmd -in f.d -inform d -outform d >ff.d1
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> d"
+$cmd -in f.p -inform p -outform d >ff.d3
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> p"
+$cmd -in f.d -inform d -outform p >ff.p1
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in f.p -inform p -outform p >ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp f.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+cmp f.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+/bin/rm -f f.* ff.* fff.*
+exit 0
diff --git a/openssl/test/tpkcs7d.com b/openssl/test/tpkcs7d.com
new file mode 100644
index 0000000..eea8c88
--- /dev/null
+++ b/openssl/test/tpkcs7d.com
@@ -0,0 +1,52 @@
+$! TPKCS7.COM  --  Tests pkcs7 keys
+$
+$	__arch = "VAX"
+$	if f$getsyi("cpu") .ge. 128 then -
+	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$	if __arch .eqs. "" then __arch = "UNK"
+$!
+$	if (p2 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$	cmd = "mcr ''exe_dir'openssl pkcs7"
+$
+$	t = "pkcs7-1.pem"
+$	if p1 .nes. "" then t = p1
+$
+$	write sys$output "testing PKCS7 conversions (2)"
+$	if f$search("fff.*") .nes "" then delete fff.*;*
+$	if f$search("ff.*") .nes "" then delete ff.*;*
+$	if f$search("f.*") .nes "" then delete f.*;*
+$	convert/fdl=sys$input: 't' fff.p
+RECORD
+	FORMAT STREAM_LF
+$
+$	write sys$output "p -> d"
+$	'cmd' -in fff.p -inform p -outform d -out f.d
+$	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> p"
+$	'cmd' -in fff.p -inform p -outform p -out f.p
+$	if $severity .ne. 1 then exit 3
+$
+$	write sys$output "d -> d"
+$	'cmd' -in f.d -inform d -outform d -out ff.d1
+$	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> d"
+$	'cmd' -in f.p -inform p -outform d -out ff.d3
+$	if $severity .ne. 1 then exit 3
+$
+$
+$	write sys$output "d -> p"
+$	'cmd' -in f.d -inform d -outform p -out ff.p1
+$	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> p"
+$	'cmd' -in f.p -inform p -outform p -out ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$	backup/compare f.p ff.p1
+$	if $severity .ne. 1 then exit 3
+$	backup/compare f.p ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$	delete f.*;*,ff.*;*,fff.*;*
diff --git a/openssl/test/treq b/openssl/test/treq
new file mode 100644
index 0000000..77f37dc
--- /dev/null
+++ b/openssl/test/treq
@@ -0,0 +1,83 @@
+#!/bin/sh
+
+cmd='../util/shlib_wrap.sh ../apps/openssl req -config ../apps/openssl.cnf'
+
+if [ "$1"x != "x" ]; then
+	t=$1
+else
+	t=testreq.pem
+fi
+
+if $cmd -in $t -inform p -noout -text 2>&1 | fgrep -i 'Unknown Public Key'; then
+  echo "skipping req conversion test for $t"
+  exit 0
+fi
+
+echo testing req conversions
+cp $t fff.p
+
+echo "p -> d"
+$cmd -in fff.p -inform p -outform d >f.d
+if [ $? != 0 ]; then exit 1; fi
+#echo "p -> t"
+#$cmd -in fff.p -inform p -outform t >f.t
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in fff.p -inform p -outform p >f.p
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> d"
+$cmd -verify -in f.d -inform d -outform d >ff.d1
+if [ $? != 0 ]; then exit 1; fi
+#echo "t -> d"
+#$cmd -in f.t -inform t -outform d >ff.d2
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> d"
+$cmd -verify -in f.p -inform p -outform d >ff.d3
+if [ $? != 0 ]; then exit 1; fi
+
+#echo "d -> t"
+#$cmd -in f.d -inform d -outform t >ff.t1
+#if [ $? != 0 ]; then exit 1; fi
+#echo "t -> t"
+#$cmd -in f.t -inform t -outform t >ff.t2
+#if [ $? != 0 ]; then exit 1; fi
+#echo "p -> t"
+#$cmd -in f.p -inform p -outform t >ff.t3
+#if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> p"
+$cmd -in f.d -inform d -outform p >ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#echo "t -> p"
+#$cmd -in f.t -inform t -outform p >ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in f.p -inform p -outform p >ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp fff.p f.p
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#cmp fff.p ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+#cmp f.t ff.t1
+#if [ $? != 0 ]; then exit 1; fi
+#cmp f.t ff.t2
+#if [ $? != 0 ]; then exit 1; fi
+#cmp f.t ff.t3
+#if [ $? != 0 ]; then exit 1; fi
+
+cmp f.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#cmp f.p ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+cmp f.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+/bin/rm -f f.* ff.* fff.*
+exit 0
diff --git a/openssl/test/treq.com b/openssl/test/treq.com
new file mode 100644
index 0000000..acf08b7
--- /dev/null
+++ b/openssl/test/treq.com
@@ -0,0 +1,88 @@
+$! TREQ.COM  --  Tests req keys
+$
+$	__arch = "VAX"
+$	if f$getsyi("cpu") .ge. 128 then -
+	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$	if __arch .eqs. "" then __arch = "UNK"
+$!
+$	if (p2 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$	cmd = "mcr ''exe_dir'openssl req -config [-.apps]openssl-vms.cnf"
+$
+$	t = "testreq.pem"
+$	if p1 .nes. "" then t = p1
+$
+$	write sys$output "testing req conversions"
+$	if f$search("fff.*") .nes "" then delete fff.*;*
+$	if f$search("ff.*") .nes "" then delete ff.*;*
+$	if f$search("f.*") .nes "" then delete f.*;*
+$	convert/fdl=sys$input: 't' fff.p
+RECORD
+	FORMAT STREAM_LF
+$
+$	write sys$output "p -> d"
+$	'cmd' -in fff.p -inform p -outform d -out f.d
+$	if $severity .ne. 1 then exit 3
+$!	write sys$output "p -> t"
+$!	'cmd' -in fff.p -inform p -outform t -out f.t
+$!	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> p"
+$	'cmd' -in fff.p -inform p -outform p -out f.p
+$	if $severity .ne. 1 then exit 3
+$
+$	write sys$output "d -> d"
+$	'cmd' -verify -in f.d -inform d -outform d -out ff.d1
+$	if $severity .ne. 1 then exit 3
+$!	write sys$output "t -> d"
+$!	'cmd' -verify -in f.t -inform t -outform d -out ff.d2
+$!	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> d"
+$	'cmd' -verify -in f.p -inform p -outform d -out ff.d3
+$	if $severity .ne. 1 then exit 3
+$
+$!	write sys$output "d -> t"
+$!	'cmd' -in f.d -inform d -outform t -out ff.t1
+$!	if $severity .ne. 1 then exit 3
+$!	write sys$output "t -> t"
+$!	'cmd' -in f.t -inform t -outform t -out ff.t2
+$!	if $severity .ne. 1 then exit 3
+$!	write sys$output "p -> t"
+$!	'cmd' -in f.p -inform p -outform t -out ff.t3
+$!	if $severity .ne. 1 then exit 3
+$
+$	write sys$output "d -> p"
+$	'cmd' -in f.d -inform d -outform p -out ff.p1
+$	if $severity .ne. 1 then exit 3
+$!	write sys$output "t -> p"
+$!	'cmd' -in f.t -inform t -outform p -out ff.p2
+$!	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> p"
+$	'cmd' -in f.p -inform p -outform p -out ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$	backup/compare fff.p f.p
+$	if $severity .ne. 1 then exit 3
+$	backup/compare fff.p ff.p1
+$	if $severity .ne. 1 then exit 3
+$!	backup/compare fff.p ff.p2
+$!	if $severity .ne. 1 then exit 3
+$	backup/compare fff.p ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$!	backup/compare f.t ff.t1
+$!	if $severity .ne. 1 then exit 3
+$!	backup/compare f.t ff.t2
+$!	if $severity .ne. 1 then exit 3
+$!	backup/compare f.t ff.t3
+$!	if $severity .ne. 1 then exit 3
+$
+$	backup/compare f.p ff.p1
+$	if $severity .ne. 1 then exit 3
+$!	backup/compare f.p ff.p2
+$!	if $severity .ne. 1 then exit 3
+$	backup/compare f.p ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$	delete f.*;*,ff.*;*,fff.*;*
diff --git a/openssl/test/trsa b/openssl/test/trsa
new file mode 100644
index 0000000..249ac1d
--- /dev/null
+++ b/openssl/test/trsa
@@ -0,0 +1,83 @@
+#!/bin/sh
+
+if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then
+  echo skipping rsa conversion test
+  exit 0
+fi
+
+cmd='../util/shlib_wrap.sh ../apps/openssl rsa'
+
+if [ "$1"x != "x" ]; then
+	t=$1
+else
+	t=testrsa.pem
+fi
+
+echo testing rsa conversions
+cp $t fff.p
+
+echo "p -> d"
+$cmd -in fff.p -inform p -outform d >f.d
+if [ $? != 0 ]; then exit 1; fi
+#echo "p -> t"
+#$cmd -in fff.p -inform p -outform t >f.t
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in fff.p -inform p -outform p >f.p
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> d"
+$cmd -in f.d -inform d -outform d >ff.d1
+if [ $? != 0 ]; then exit 1; fi
+#echo "t -> d"
+#$cmd -in f.t -inform t -outform d >ff.d2
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> d"
+$cmd -in f.p -inform p -outform d >ff.d3
+if [ $? != 0 ]; then exit 1; fi
+
+#echo "d -> t"
+#$cmd -in f.d -inform d -outform t >ff.t1
+#if [ $? != 0 ]; then exit 1; fi
+#echo "t -> t"
+#$cmd -in f.t -inform t -outform t >ff.t2
+#if [ $? != 0 ]; then exit 1; fi
+#echo "p -> t"
+#$cmd -in f.p -inform p -outform t >ff.t3
+#if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> p"
+$cmd -in f.d -inform d -outform p >ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#echo "t -> p"
+#$cmd -in f.t -inform t -outform p >ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in f.p -inform p -outform p >ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp fff.p f.p
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#cmp fff.p ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+#cmp f.t ff.t1
+#if [ $? != 0 ]; then exit 1; fi
+#cmp f.t ff.t2
+#if [ $? != 0 ]; then exit 1; fi
+#cmp f.t ff.t3
+#if [ $? != 0 ]; then exit 1; fi
+
+cmp f.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#cmp f.p ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+cmp f.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+/bin/rm -f f.* ff.* fff.*
+exit 0
diff --git a/openssl/test/trsa.com b/openssl/test/trsa.com
new file mode 100644
index 0000000..5418084
--- /dev/null
+++ b/openssl/test/trsa.com
@@ -0,0 +1,99 @@
+$! TRSA.COM  --  Tests rsa keys
+$
+$	__arch = "VAX"
+$	if f$getsyi("cpu") .ge. 128 then -
+	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$	if __arch .eqs. "" then __arch = "UNK"
+$!
+$	if (p2 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$	set noon
+$	define/user sys$output nla0:
+$	mcr 'exe_dir'openssl no-rsa
+$	save_severity=$SEVERITY
+$	set on
+$	if save_severity
+$	then
+$	    write sys$output "skipping RSA conversion test"
+$	    exit
+$	endif
+$
+$	cmd = "mcr ''exe_dir'openssl rsa"
+$
+$	t = "testrsa.pem"
+$	if p1 .nes. "" then t = p1
+$
+$	write sys$output "testing RSA conversions"
+$	if f$search("fff.*") .nes "" then delete fff.*;*
+$	if f$search("ff.*") .nes "" then delete ff.*;*
+$	if f$search("f.*") .nes "" then delete f.*;*
+$	convert/fdl=sys$input: 't' fff.p
+RECORD
+	FORMAT STREAM_LF
+$
+$	write sys$output "p -> d"
+$	'cmd' -in fff.p -inform p -outform d -out f.d
+$	if $severity .ne. 1 then exit 3
+$!	write sys$output "p -> t"
+$!	'cmd' -in fff.p -inform p -outform t -out f.t
+$!	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> p"
+$	'cmd' -in fff.p -inform p -outform p -out f.p
+$	if $severity .ne. 1 then exit 3
+$
+$	write sys$output "d -> d"
+$	'cmd' -in f.d -inform d -outform d -out ff.d1
+$	if $severity .ne. 1 then exit 3
+$!	write sys$output "t -> d"
+$!	'cmd' -in f.t -inform t -outform d -out ff.d2
+$!	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> d"
+$	'cmd' -in f.p -inform p -outform d -out ff.d3
+$	if $severity .ne. 1 then exit 3
+$
+$!	write sys$output "d -> t"
+$!	'cmd' -in f.d -inform d -outform t -out ff.t1
+$!	if $severity .ne. 1 then exit 3
+$!	write sys$output "t -> t"
+$!	'cmd' -in f.t -inform t -outform t -out ff.t2
+$!	if $severity .ne. 1 then exit 3
+$!	write sys$output "p -> t"
+$!	'cmd' -in f.p -inform p -outform t -out ff.t3
+$!	if $severity .ne. 1 then exit 3
+$
+$	write sys$output "d -> p"
+$	'cmd' -in f.d -inform d -outform p -out ff.p1
+$	if $severity .ne. 1 then exit 3
+$!	write sys$output "t -> p"
+$!	'cmd' -in f.t -inform t -outform p -out ff.p2
+$!	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> p"
+$	'cmd' -in f.p -inform p -outform p -out ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$	backup/compare fff.p f.p
+$	if $severity .ne. 1 then exit 3
+$	backup/compare fff.p ff.p1
+$	if $severity .ne. 1 then exit 3
+$!	backup/compare fff.p ff.p2
+$!	if $severity .ne. 1 then exit 3
+$	backup/compare fff.p ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$!	backup/compare f.t ff.t1
+$!	if $severity .ne. 1 then exit 3
+$!	backup/compare f.t ff.t2
+$!	if $severity .ne. 1 then exit 3
+$!	backup/compare f.t ff.t3
+$!	if $severity .ne. 1 then exit 3
+$
+$	backup/compare f.p ff.p1
+$	if $severity .ne. 1 then exit 3
+$!	backup/compare f.p ff.p2
+$!	if $severity .ne. 1 then exit 3
+$	backup/compare f.p ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$	delete f.*;*,ff.*;*,fff.*;*
diff --git a/openssl/test/tsid b/openssl/test/tsid
new file mode 100644
index 0000000..6adbd53
--- /dev/null
+++ b/openssl/test/tsid
@@ -0,0 +1,78 @@
+#!/bin/sh
+
+cmd='../util/shlib_wrap.sh ../apps/openssl sess_id'
+
+if [ "$1"x != "x" ]; then
+	t=$1
+else
+	t=testsid.pem
+fi
+
+echo testing session-id conversions
+cp $t fff.p
+
+echo "p -> d"
+$cmd -in fff.p -inform p -outform d >f.d
+if [ $? != 0 ]; then exit 1; fi
+#echo "p -> t"
+#$cmd -in fff.p -inform p -outform t >f.t
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in fff.p -inform p -outform p >f.p
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> d"
+$cmd -in f.d -inform d -outform d >ff.d1
+if [ $? != 0 ]; then exit 1; fi
+#echo "t -> d"
+#$cmd -in f.t -inform t -outform d >ff.d2
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> d"
+$cmd -in f.p -inform p -outform d >ff.d3
+if [ $? != 0 ]; then exit 1; fi
+
+#echo "d -> t"
+#$cmd -in f.d -inform d -outform t >ff.t1
+#if [ $? != 0 ]; then exit 1; fi
+#echo "t -> t"
+#$cmd -in f.t -inform t -outform t >ff.t2
+#if [ $? != 0 ]; then exit 1; fi
+#echo "p -> t"
+#$cmd -in f.p -inform p -outform t >ff.t3
+#if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> p"
+$cmd -in f.d -inform d -outform p >ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#echo "t -> p"
+#$cmd -in f.t -inform t -outform p >ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in f.p -inform p -outform p >ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp fff.p f.p
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#cmp fff.p ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+#cmp f.t ff.t1
+#if [ $? != 0 ]; then exit 1; fi
+#cmp f.t ff.t2
+#if [ $? != 0 ]; then exit 1; fi
+#cmp f.t ff.t3
+#if [ $? != 0 ]; then exit 1; fi
+
+cmp f.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+#cmp f.p ff.p2
+#if [ $? != 0 ]; then exit 1; fi
+cmp f.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+/bin/rm -f f.* ff.* fff.*
+exit 0
diff --git a/openssl/test/tsid.com b/openssl/test/tsid.com
new file mode 100644
index 0000000..b6c4e49
--- /dev/null
+++ b/openssl/test/tsid.com
@@ -0,0 +1,88 @@
+$! TSID.COM  --  Tests sid keys
+$
+$	__arch = "VAX"
+$	if f$getsyi("cpu") .ge. 128 then -
+	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$	if __arch .eqs. "" then __arch = "UNK"
+$!
+$	if (p2 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$	cmd = "mcr ''exe_dir'openssl sess_id"
+$
+$	t = "testsid.pem"
+$	if p1 .nes. "" then t = p1
+$
+$	write sys$output "testing session-id conversions"
+$	if f$search("fff.*") .nes "" then delete fff.*;*
+$	if f$search("ff.*") .nes "" then delete ff.*;*
+$	if f$search("f.*") .nes "" then delete f.*;*
+$	convert/fdl=sys$input: 't' fff.p
+RECORD
+	FORMAT STREAM_LF
+$
+$	write sys$output "p -> d"
+$	'cmd' -in fff.p -inform p -outform d -out f.d
+$	if $severity .ne. 1 then exit 3
+$!	write sys$output "p -> t"
+$!	'cmd' -in fff.p -inform p -outform t -out f.t
+$!	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> p"
+$	'cmd' -in fff.p -inform p -outform p -out f.p
+$	if $severity .ne. 1 then exit 3
+$
+$	write sys$output "d -> d"
+$	'cmd' -in f.d -inform d -outform d -out ff.d1
+$	if $severity .ne. 1 then exit 3
+$!	write sys$output "t -> d"
+$!	'cmd' -in f.t -inform t -outform d -out ff.d2
+$!	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> d"
+$	'cmd' -in f.p -inform p -outform d -out ff.d3
+$	if $severity .ne. 1 then exit 3
+$
+$!	write sys$output "d -> t"
+$!	'cmd' -in f.d -inform d -outform t -out ff.t1
+$!	if $severity .ne. 1 then exit 3
+$!	write sys$output "t -> t"
+$!	'cmd' -in f.t -inform t -outform t -out ff.t2
+$!	if $severity .ne. 1 then exit 3
+$!	write sys$output "p -> t"
+$!	'cmd' -in f.p -inform p -outform t -out ff.t3
+$!	if $severity .ne. 1 then exit 3
+$
+$	write sys$output "d -> p"
+$	'cmd' -in f.d -inform d -outform p -out ff.p1
+$	if $severity .ne. 1 then exit 3
+$!	write sys$output "t -> p"
+$!	'cmd' -in f.t -inform t -outform p -out ff.p2
+$!	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> p"
+$	'cmd' -in f.p -inform p -outform p -out ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$	backup/compare fff.p f.p
+$	if $severity .ne. 1 then exit 3
+$	backup/compare fff.p ff.p1
+$	if $severity .ne. 1 then exit 3
+$!	backup/compare fff.p ff.p2
+$!	if $severity .ne. 1 then exit 3
+$	backup/compare fff.p ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$!	backup/compare f.t ff.t1
+$!	if $severity .ne. 1 then exit 3
+$!	backup/compare f.t ff.t2
+$!	if $severity .ne. 1 then exit 3
+$!	backup/compare f.t ff.t3
+$!	if $severity .ne. 1 then exit 3
+$
+$	backup/compare f.p ff.p1
+$	if $severity .ne. 1 then exit 3
+$!	backup/compare f.p ff.p2
+$!	if $severity .ne. 1 then exit 3
+$	backup/compare f.p ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$	delete f.*;*,ff.*;*,fff.*;*
diff --git a/openssl/test/tverify.com b/openssl/test/tverify.com
new file mode 100644
index 0000000..d888344
--- /dev/null
+++ b/openssl/test/tverify.com
@@ -0,0 +1,65 @@
+$! TVERIFY.COM
+$
+$	__arch = "VAX"
+$	if f$getsyi("cpu") .ge. 128 then -
+	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$	if __arch .eqs. "" then __arch = "UNK"
+$!
+$	if (p1 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$	line_max = 255 ! Could be longer on modern non-VAX.
+$	temp_file_name = "certs_"+ f$getjpi( "", "PID")+ ".tmp"
+$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$	cmd = "mcr ''exe_dir'openssl verify ""-CAfile"" ''temp_file_name'"
+$	cmd_len = f$length( cmd)
+$	pems = "[-.certs...]*.pem"
+$!
+$!	Concatenate all the certificate files.
+$!
+$	copy /concatenate 'pems' 'temp_file_name'
+$!
+$!	Loop through all the certificate files.
+$!
+$	args = ""
+$	old_f = ""
+$ loop_file: 
+$	    f = f$search( pems)
+$	    if ((f .nes. "") .and. (f .nes. old_f))
+$	    then
+$	      old_f = f
+$!
+$!	      If this file name would over-extend the command line, then
+$!	      run the command now.
+$!
+$	      if (cmd_len+ f$length( args)+ 1+ f$length( f) .gt. line_max)
+$	      then
+$	         if (args .eqs. "") then goto disaster
+$	         'cmd''args'
+$	         args = ""
+$	      endif
+$!	      Add the next file to the argument list.
+$	      args = args+ " "+ f
+$	   else
+$!            No more files in the list
+$	      goto loop_file_end
+$	   endif
+$	goto loop_file
+$	loop_file_end:
+$!
+$!	Run the command for any left-over arguments.
+$!
+$	if (args .nes. "")
+$	then
+$	   'cmd''args'
+$	endif
+$!
+$!	Delete the temporary file.
+$!
+$	if (f$search( "''temp_file_name';*") .nes. "") then -
+	 delete 'temp_file_name';*
+$!
+$	exit
+$!
+$	disaster:
+$	write sys$output "   Command line too long.  Doomed."
+$!
diff --git a/openssl/test/tx509 b/openssl/test/tx509
new file mode 100644
index 0000000..4a15b98
--- /dev/null
+++ b/openssl/test/tx509
@@ -0,0 +1,78 @@
+#!/bin/sh
+
+cmd='../util/shlib_wrap.sh ../apps/openssl x509'
+
+if [ "$1"x != "x" ]; then
+	t=$1
+else
+	t=testx509.pem
+fi
+
+echo testing X509 conversions
+cp $t fff.p
+
+echo "p -> d"
+$cmd -in fff.p -inform p -outform d >f.d
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> n"
+$cmd -in fff.p -inform p -outform n >f.n
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in fff.p -inform p -outform p >f.p
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> d"
+$cmd -in f.d -inform d -outform d >ff.d1
+if [ $? != 0 ]; then exit 1; fi
+echo "n -> d"
+$cmd -in f.n -inform n -outform d >ff.d2
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> d"
+$cmd -in f.p -inform p -outform d >ff.d3
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> n"
+$cmd -in f.d -inform d -outform n >ff.n1
+if [ $? != 0 ]; then exit 1; fi
+echo "n -> n"
+$cmd -in f.n -inform n -outform n >ff.n2
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> n"
+$cmd -in f.p -inform p -outform n >ff.n3
+if [ $? != 0 ]; then exit 1; fi
+
+echo "d -> p"
+$cmd -in f.d -inform d -outform p >ff.p1
+if [ $? != 0 ]; then exit 1; fi
+echo "n -> p"
+$cmd -in f.n -inform n -outform p >ff.p2
+if [ $? != 0 ]; then exit 1; fi
+echo "p -> p"
+$cmd -in f.p -inform p -outform p >ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp fff.p f.p
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p2
+if [ $? != 0 ]; then exit 1; fi
+cmp fff.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp f.n ff.n1
+if [ $? != 0 ]; then exit 1; fi
+cmp f.n ff.n2
+if [ $? != 0 ]; then exit 1; fi
+cmp f.n ff.n3
+if [ $? != 0 ]; then exit 1; fi
+
+cmp f.p ff.p1
+if [ $? != 0 ]; then exit 1; fi
+cmp f.p ff.p2
+if [ $? != 0 ]; then exit 1; fi
+cmp f.p ff.p3
+if [ $? != 0 ]; then exit 1; fi
+
+/bin/rm -f f.* ff.* fff.*
+exit 0
diff --git a/openssl/test/tx509.com b/openssl/test/tx509.com
new file mode 100644
index 0000000..93ce988
--- /dev/null
+++ b/openssl/test/tx509.com
@@ -0,0 +1,88 @@
+$! TX509.COM  --  Tests x509 certificates
+$
+$	__arch = "VAX"
+$	if f$getsyi("cpu") .ge. 128 then -
+	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$	if __arch .eqs. "" then __arch = "UNK"
+$!
+$	if (p2 .eqs. "64") then __arch = __arch+ "_64"
+$!
+$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
+$
+$	cmd = "mcr ''exe_dir'openssl x509"
+$
+$	t = "testx509.pem"
+$	if p1 .nes. "" then t = p1
+$
+$	write sys$output "testing X509 conversions"
+$	if f$search("fff.*") .nes "" then delete fff.*;*
+$	if f$search("ff.*") .nes "" then delete ff.*;*
+$	if f$search("f.*") .nes "" then delete f.*;*
+$	convert/fdl=sys$input: 't' fff.p
+RECORD
+	FORMAT STREAM_LF
+$
+$	write sys$output "p -> d"
+$	'cmd' -in fff.p -inform p -outform d -out f.d
+$	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> n"
+$	'cmd' -in fff.p -inform p -outform n -out f.n
+$	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> p"
+$	'cmd' -in fff.p -inform p -outform p -out f.p
+$	if $severity .ne. 1 then exit 3
+$
+$	write sys$output "d -> d"
+$	'cmd' -in f.d -inform d -outform d -out ff.d1
+$	if $severity .ne. 1 then exit 3
+$	write sys$output "n -> d"
+$	'cmd' -in f.n -inform n -outform d -out ff.d2
+$	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> d"
+$	'cmd' -in f.p -inform p -outform d -out ff.d3
+$	if $severity .ne. 1 then exit 3
+$
+$	write sys$output "d -> n"
+$	'cmd' -in f.d -inform d -outform n -out ff.n1
+$	if $severity .ne. 1 then exit 3
+$	write sys$output "n -> n"
+$	'cmd' -in f.n -inform n -outform n -out ff.n2
+$	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> n"
+$	'cmd' -in f.p -inform p -outform n -out ff.n3
+$	if $severity .ne. 1 then exit 3
+$
+$	write sys$output "d -> p"
+$	'cmd' -in f.d -inform d -outform p -out ff.p1
+$	if $severity .ne. 1 then exit 3
+$	write sys$output "n -> p"
+$	'cmd' -in f.n -inform n -outform p -out ff.p2
+$	if $severity .ne. 1 then exit 3
+$	write sys$output "p -> p"
+$	'cmd' -in f.p -inform p -outform p -out ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$	backup/compare fff.p f.p
+$	if $severity .ne. 1 then exit 3
+$	backup/compare fff.p ff.p1
+$	if $severity .ne. 1 then exit 3
+$	backup/compare fff.p ff.p2
+$	if $severity .ne. 1 then exit 3
+$	backup/compare fff.p ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$	backup/compare f.n ff.n1
+$	if $severity .ne. 1 then exit 3
+$	backup/compare f.n ff.n2
+$	if $severity .ne. 1 then exit 3
+$	backup/compare f.n ff.n3
+$	if $severity .ne. 1 then exit 3
+$
+$	backup/compare f.p ff.p1
+$	if $severity .ne. 1 then exit 3
+$	backup/compare f.p ff.p2
+$	if $severity .ne. 1 then exit 3
+$	backup/compare f.p ff.p3
+$	if $severity .ne. 1 then exit 3
+$
+$	delete f.*;*,ff.*;*,fff.*;*
diff --git a/openssl/test/v3-cert1.pem b/openssl/test/v3-cert1.pem
new file mode 100644
index 0000000..0da253d
--- /dev/null
+++ b/openssl/test/v3-cert1.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx
+NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz
+dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw
+ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu
+ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2
+ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp
+miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C
+AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK
+Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x
+DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR
+MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB
+AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21
+X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3
+WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO
+-----END CERTIFICATE-----
diff --git a/openssl/test/v3-cert2.pem b/openssl/test/v3-cert2.pem
new file mode 100644
index 0000000..de0723f
--- /dev/null
+++ b/openssl/test/v3-cert2.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD
+YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0
+ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu
+dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1
+WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV
+BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx
+FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA
+6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT
+G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ
+YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm
+b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc
+F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz
+lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap
+jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU=
+-----END CERTIFICATE-----
diff --git a/openssl/test/wp_test.c b/openssl/test/wp_test.c
new file mode 100644
index 0000000..7a4bb75
--- /dev/null
+++ b/openssl/test/wp_test.c
@@ -0,0 +1 @@
+link ../crypto/whrlpool/wp_test.c
\ No newline at end of file
diff --git a/openssl/times/090/586-100.nt b/openssl/times/090/586-100.nt
new file mode 100644
index 0000000..297ec3e
--- /dev/null
+++ b/openssl/times/090/586-100.nt
@@ -0,0 +1,32 @@
+SSLeay 0.9.0 08-Apr-1998
+built on Wed Apr  8 12:47:17 EST 1998
+options:bn(64,32) md2(int) rc4(idx,int) des(idx,cisc,4,long) idea(int) blowfish(
+ptr2)
+C flags:cl /MD /W3 /WX /G5 /Ox /O2 /Ob2 /Gs0 /GF /Gy /nologo -DWIN32 -DL_ENDIAN
+-DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                 92.25k      256.80k      347.01k      380.40k      390.31k
+mdc2               240.72k      251.10k      252.00k      250.80k      251.40k
+md5               1013.61k     5651.94k    11831.61k    16294.89k    17901.43k
+hmac(md5)          419.50k     2828.07k     7770.11k    13824.34k    17091.70k
+sha1               524.31k     2721.45k     5216.15k     6766.10k     7308.42k
+rmd160             462.09k     2288.59k     4260.77k     5446.44k     5841.65k
+rc4               7895.90k    10326.73k    10555.43k    10728.22k    10429.44k
+des cbc           2036.86k     2208.92k     2237.68k     2237.20k     2181.35k
+des ede3           649.92k      739.42k      749.07k      748.86k      738.27k
+idea cbc           823.19k      885.10k      894.92k      896.45k      891.87k
+rc2 cbc            792.63k      859.00k      867.45k      868.96k      865.30k
+rc5-32/12 cbc     3502.26k     4026.79k     4107.23k     4121.76k     4073.72k
+blowfish cbc      3752.96k     4026.79k     4075.31k     3965.87k     3892.26k
+cast cbc          2566.27k     2807.43k     2821.79k     2792.48k     2719.34k
+                  sign    verify    sign/s verify/s
+rsa  512 bits   0.0179s   0.0020s     56.0    501.7
+rsa 1024 bits   0.0950s   0.0060s     10.5    166.6
+rsa 2048 bits   0.6299s   0.0209s      1.6     47.8
+rsa 4096 bits   4.5870s   0.0787s      0.2     12.7
+                  sign    verify    sign/s verify/s
+dsa  512 bits   0.0180s   0.0339s     55.6     29.5
+dsa 1024 bits   0.0555s   0.1076s     18.0      9.3
+dsa 2048 bits   0.1971s   0.3918s      5.1      2.6
+
diff --git a/openssl/times/091/486-50.nt b/openssl/times/091/486-50.nt
new file mode 100644
index 0000000..84820d9
--- /dev/null
+++ b/openssl/times/091/486-50.nt
@@ -0,0 +1,30 @@
+486-50 NT 4.0
+
+SSLeay 0.9.1a 06-Jul-1998
+built on Sat Jul 18 18:03:20 EST 1998
+options:bn(64,32) md2(int) rc4(idx,int) des(idx,cisc,4,long) idea(int) blowfish(ptr2)
+C flags:cl /MD /W3 /WX /G5 /Ox /O2 /Ob2 /Gs0 /GF /Gy /nologo -DWIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM /Fdout32
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                 28.77k       80.30k      108.50k      118.98k      122.47k
+mdc2                51.52k       54.06k       54.54k       54.65k       54.62k
+md5                304.39k     1565.04k     3061.54k     3996.10k     4240.10k
+hmac(md5)          119.53k      793.23k     2061.29k     3454.95k     4121.76k
+sha1               127.51k      596.93k     1055.54k     1313.84k     1413.18k
+rmd160             128.50k      572.49k     1001.03k     1248.01k     1323.63k
+rc4               1224.40k     1545.11k     1590.29k     1600.20k     1576.90k
+des cbc            448.19k      503.45k      512.30k      513.30k      508.23k
+des ede3           148.66k      162.48k      163.68k      163.94k      164.24k
+idea cbc           194.18k      211.10k      212.99k      213.18k      212.64k
+rc2 cbc            245.78k      271.01k      274.12k      274.38k      273.52k
+rc5-32/12 cbc     1252.48k     1625.20k     1700.03k     1711.12k     1677.18k
+blowfish cbc       725.16k      828.26k      850.01k      846.99k      833.79k
+cast cbc           643.30k      717.22k      739.48k      741.57k      735.33k
+                  sign    verify    sign/s verify/s
+rsa  512 bits   0.0904s   0.0104s     11.1     96.2
+rsa 1024 bits   0.5968s   0.0352s      1.7     28.4
+rsa 2048 bits   3.8860s   0.1017s      0.3      9.8
+                  sign    verify    sign/s verify/s
+dsa  512 bits   0.1006s   0.1249s      9.9      8.0
+dsa 1024 bits   0.3306s   0.4093s      3.0      2.4
+dsa 2048 bits   0.9454s   1.1707s      1.1      0.9
diff --git a/openssl/times/091/586-100.lnx b/openssl/times/091/586-100.lnx
new file mode 100644
index 0000000..92892a6
--- /dev/null
+++ b/openssl/times/091/586-100.lnx
@@ -0,0 +1,32 @@
+Pentium 100mhz, linux
+
+SSLeay 0.9.0a 14-Apr-1998
+built on Fri Apr 17 08:47:07 EST 1998
+options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2)
+C flags:gcc -DL_ENDIAN -DTERMIO -DBN_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized -DSHA1_ASM -DMD5_ASM -DRMD160_ASM
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                 56.65k      153.88k      208.47k      229.03k      237.57k
+mdc2               189.59k      204.95k      206.93k      208.90k      209.56k
+md5               1019.48k     5882.41k    12085.42k    16376.49k    18295.47k
+hmac(md5)          415.86k     2887.85k     7891.29k    13894.66k    17446.23k
+sha1               540.68k     2791.96k     5289.30k     6813.01k     7432.87k
+rmd160             298.37k     1846.87k     3869.10k     5273.94k     5892.78k
+rc4               7870.87k    10438.10k    10857.13k    10729.47k    10788.86k
+des cbc           1960.60k     2226.37k     2241.88k     2054.83k     2181.80k
+des ede3           734.44k      739.69k      779.43k      750.25k      772.78k
+idea cbc           654.07k      711.00k      716.89k      718.51k      720.90k
+rc2 cbc            648.83k      701.91k      708.61k      708.95k      709.97k
+rc5-32/12 cbc     3504.71k     4054.76k     4131.41k     4105.56k     4134.23k
+blowfish cbc      3762.25k     4313.79k     4460.54k     4356.78k     4317.18k
+cast cbc          2755.01k     3038.91k     3076.44k     3027.63k     2998.27k
+                  sign    verify    sign/s verify/s
+rsa  512 bits   0.0195s   0.0019s     51.4    519.9
+rsa 1024 bits   0.1000s   0.0059s     10.0    168.2
+rsa 2048 bits   0.6406s   0.0209s      1.6     47.8
+rsa 4096 bits   4.6100s   0.0787s      0.2     12.7
+                  sign    verify    sign/s verify/s
+dsa  512 bits   0.0188s   0.0360s     53.1     27.8
+dsa 1024 bits   0.0570s   0.1126s     17.5      8.9
+dsa 2048 bits   0.1990s   0.3954s      5.0      2.5
+
diff --git a/openssl/times/091/68000.bsd b/openssl/times/091/68000.bsd
new file mode 100644
index 0000000..a3a14e8
--- /dev/null
+++ b/openssl/times/091/68000.bsd
@@ -0,0 +1,32 @@
+Motorolla 68020 20mhz, NetBSD
+
+SSLeay 0.9.0t 29-May-1998
+built on Fri Jun  5 12:42:23 EST 1998
+options:bn(64,32) md2(char) rc4(idx,int) des(idx,cisc,16,long) idea(int) blowfish(idx) 
+C flags:gcc -DTERMIOS -O3 -fomit-frame-pointer -Wall -DB_ENDIAN
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2               2176.00      5994.67      8079.73      8845.18      9077.01 
+mdc2              5730.67      6122.67      6167.66      6176.51      6174.87 
+md5                 29.10k      127.31k      209.66k      250.50k      263.99k
+hmac(md5)           12.33k       73.02k      160.17k      228.04k      261.15k
+sha1                11.27k       49.37k       84.31k      102.40k      109.23k
+rmd160              11.69k       48.62k       78.76k       93.15k       98.41k
+rc4                117.96k      148.94k      152.57k      153.09k      152.92k
+des cbc             27.13k       30.06k       30.38k       30.38k       30.53k
+des ede3            10.51k       10.94k       11.01k       11.01k       11.01k
+idea cbc            26.74k       29.23k       29.45k       29.60k       29.74k
+rc2 cbc             34.27k       39.39k       40.03k       40.07k       40.16k
+rc5-32/12 cbc       64.31k       83.18k       85.70k       86.70k       87.09k
+blowfish cbc        48.86k       59.18k       60.07k       60.42k       60.78k
+cast cbc            42.67k       50.01k       50.86k       51.20k       51.37k
+                  sign    verify    sign/s verify/s
+rsa  512 bits   0.7738s   0.0774s      1.3     12.9
+rsa 1024 bits   4.3967s   0.2615s      0.2      3.8
+rsa 2048 bits  29.5200s   0.9664s      0.0      1.0
+                  sign    verify    sign/s verify/s
+dsa  512 bits   0.7862s   0.9709s      1.3      1.0
+dsa 1024 bits   2.5375s   3.1625s      0.4      0.3
+dsa 2048 bits   9.2150s  11.8200s      0.1      0.1
+
+
diff --git a/openssl/times/091/686-200.lnx b/openssl/times/091/686-200.lnx
new file mode 100644
index 0000000..bb857d4
--- /dev/null
+++ b/openssl/times/091/686-200.lnx
@@ -0,0 +1,32 @@
+Pentium Pro 200mhz, linux
+
+SSLeay 0.9.0d 26-Apr-1998
+built on Sun Apr 26 10:25:33 EST 1998
+options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) 
+C flags:gcc -DL_ENDIAN -DTERMIO -DBN_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized -DSHA1_ASM -DMD5_ASM -DRMD160_ASM
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                130.58k      364.54k      499.24k      545.79k      561.66k
+mdc2               526.68k      579.72k      588.37k      588.80k      589.82k
+md5               1917.71k    11434.69k    22512.21k    29495.30k    32677.89k
+hmac(md5)          749.18k     5264.83k    14227.20k    25018.71k    31760.38k
+sha1              1343.83k     6436.29k    11702.78k    14664.70k    15829.67k
+rmd160            1038.05k     5138.77k     8985.51k    10985.13k    11799.21k
+rc4              14891.04k    21334.06k    22376.79k    22579.54k    22574.42k
+des cbc           4131.97k     4568.31k     4645.29k     4631.21k     4572.73k
+des ede3          1567.17k     1631.13k     1657.32k     1653.08k     1643.86k
+idea cbc          2427.23k     2671.21k     2716.67k     2723.84k     2733.40k
+rc2 cbc           1629.90k     1767.38k     1788.50k     1797.12k     1799.51k
+rc5-32/12 cbc    10290.55k    13161.60k    13744.55k    14011.73k    14123.01k
+blowfish cbc      5896.42k     6920.77k     7122.01k     7151.62k     7146.15k
+cast cbc          6037.71k     6935.19k     7101.35k     7145.81k     7116.12k
+                  sign    verify    sign/s verify/s
+rsa  512 bits   0.0070s   0.0007s    142.6   1502.9
+rsa 1024 bits   0.0340s   0.0019s     29.4    513.3
+rsa 2048 bits   0.2087s   0.0066s      4.8    151.3
+rsa 4096 bits   1.4700s   0.0242s      0.7     41.2
+                  sign    verify    sign/s verify/s
+dsa  512 bits   0.0064s   0.0121s    156.1     82.9
+dsa 1024 bits   0.0184s   0.0363s     54.4     27.5
+dsa 2048 bits   0.0629s   0.1250s     15.9      8.0
+
diff --git a/openssl/times/091/alpha064.osf b/openssl/times/091/alpha064.osf
new file mode 100644
index 0000000..a8e7fdf
--- /dev/null
+++ b/openssl/times/091/alpha064.osf
@@ -0,0 +1,32 @@
+Alpha EV4.5 (21064) 275mhz, OSF1 V4.0
+SSLeay 0.9.0g 01-May-1998
+built on Mon May  4 17:26:09 CST 1998
+options:bn(64,64) md2(int) rc4(ptr,int) des(idx,cisc,4,long) idea(int) blowfish(idx) 
+C flags:cc -tune host -O4 -readonly_strings
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                119.58k      327.48k      443.28k      480.09k      495.16k
+mdc2               436.67k      456.35k      465.42k      466.57k      469.01k
+md5               1459.34k     6566.46k    11111.91k    13375.30k    14072.60k
+hmac(md5)          597.90k     3595.45k     8180.88k    12099.49k    13884.46k
+sha1               707.01k     3253.09k     6131.73k     7798.23k     8439.67k
+rmd160             618.57k     2729.07k     4711.33k     5825.16k     6119.23k
+rc4               8796.43k     9393.62k     9548.88k     9378.77k     9472.57k
+des cbc           2165.97k     2514.90k     2586.27k     2572.93k     2639.08k
+des ede3           945.44k     1004.03k     1005.96k     1017.33k     1020.85k
+idea cbc          1498.81k     1629.11k     1637.28k     1625.50k     1641.11k
+rc2 cbc           1866.00k     2044.92k     2067.12k     2064.00k     2068.96k
+rc5-32/12 cbc     4366.97k     5521.32k     5687.50k     5729.16k     5736.96k
+blowfish cbc      3997.31k     4790.60k     4937.84k     4954.56k     5024.85k
+cast cbc          2900.19k     3673.30k     3803.73k     3823.93k     3890.25k
+                  sign    verify    sign/s verify/s
+rsa  512 bits   0.0069s   0.0006s    144.2   1545.8
+rsa 1024 bits   0.0304s   0.0018s     32.9    552.6
+rsa 2048 bits   0.1887s   0.0062s      5.3    161.4
+rsa 4096 bits   1.3667s   0.0233s      0.7     42.9
+                  sign    verify    sign/s verify/s
+dsa  512 bits   0.0067s   0.0123s    149.6     81.1
+dsa 1024 bits   0.0177s   0.0332s     56.6     30.1
+dsa 2048 bits   0.0590s   0.1162s     16.9      8.6
+
+
diff --git a/openssl/times/091/alpha164.lnx b/openssl/times/091/alpha164.lnx
new file mode 100644
index 0000000..c994662
--- /dev/null
+++ b/openssl/times/091/alpha164.lnx
@@ -0,0 +1,32 @@
+Alpha EV5.6 (21164A) 533mhz, Linux 2.0.32
+
+SSLeay 0.9.0p 22-May-1998
+built on Sun May 27 14:23:38 GMT 2018
+options:bn(64,64) md2(int) rc4(ptr,int) des(idx,risc1,16,long) idea(int) blowfish(idx) 
+C flags:gcc -O3
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                295.78k      825.34k     1116.42k     1225.10k     1262.65k
+mdc2               918.16k     1017.55k     1032.18k     1034.24k     1035.60k
+md5               3574.93k    15517.05k    25482.67k    30434.31k    32210.51k
+hmac(md5)         1261.54k     7757.15k    18025.46k    27081.21k    31653.27k
+sha1              2251.89k    10056.84k    16990.19k    20651.04k    21973.29k
+rmd160            1615.49k     7017.13k    11601.11k    13875.62k    14690.31k
+rc4              22435.16k    24476.40k    24349.95k    23042.36k    24581.53k
+des cbc           5198.38k     6559.04k     6775.43k     6827.87k     6875.82k
+des ede3          2257.73k     2602.18k     2645.60k     2657.12k     2670.59k
+idea cbc          3694.42k     4125.61k     4180.74k     4193.28k     4192.94k
+rc2 cbc           4642.47k     5323.85k     5415.42k     5435.86k     5434.03k
+rc5-32/12 cbc     9705.26k    13277.79k    13843.46k    13989.66k    13987.57k
+blowfish cbc      7861.28k    10852.34k    11447.98k    11616.97k    11667.54k
+cast cbc          6718.13k     8599.98k     8967.17k     9070.81k     9099.28k
+                  sign    verify    sign/s verify/s
+rsa  512 bits   0.0018s   0.0002s    555.9   6299.5
+rsa 1024 bits   0.0081s   0.0005s    123.3   2208.7
+rsa 2048 bits   0.0489s   0.0015s     20.4    648.5
+rsa 4096 bits   0.3402s   0.0057s      2.9    174.7
+                  sign    verify    sign/s verify/s
+dsa  512 bits   0.0019s   0.0032s    529.0    310.2
+dsa 1024 bits   0.0047s   0.0086s    214.1    115.7
+dsa 2048 bits   0.0150s   0.0289s     66.7     34.6
+
diff --git a/openssl/times/091/alpha164.osf b/openssl/times/091/alpha164.osf
new file mode 100644
index 0000000..df712c6
--- /dev/null
+++ b/openssl/times/091/alpha164.osf
@@ -0,0 +1,31 @@
+Alpha EV5.6 (21164A) 400mhz, OSF1 V4.0
+
+SSLeay 0.9.0 10-Apr-1998
+built on Sun Apr 19 07:54:37 EST 1998
+options:bn(64,64) md2(int) rc4(ptr,int) des(ptr,risc2,4,int) idea(int) blowfish(idx) 
+C flags:cc -O4 -tune host -fast
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                276.30k      762.07k     1034.35k     1134.07k     1160.53k
+mdc2               814.99k      845.83k      849.09k      850.33k      849.24k
+md5               2468.43k    10945.27k    17963.48k    21430.89k    22544.38k
+hmac(md5)         1002.48k     6023.98k    13430.99k    19344.17k    22351.80k
+sha1              1984.93k     8882.47k    14856.47k    17878.70k    18955.10k
+rmd160            1286.96k     5595.52k     9167.00k    10957.74k    11582.30k
+rc4              15948.15k    16710.29k    16793.20k    17929.50k    18474.56k
+des cbc           3416.04k     4149.37k     4296.25k     4328.89k     4327.57k
+des ede3          1540.14k     1683.36k     1691.14k     1705.90k     1705.22k
+idea cbc          2795.87k     3192.93k     3238.13k     3238.17k     3256.66k
+rc2 cbc           3529.00k     4069.93k     4135.79k     4135.25k     4160.07k
+rc5-32/12 cbc     7212.35k     9849.71k    10260.91k    10423.38k    10439.99k
+blowfish cbc      6061.75k     8363.50k     8706.80k     8779.40k     8784.55k
+cast cbc          5401.75k     6433.31k     6638.18k     6662.40k     6702.80k
+                  sign    verify    sign/s verify/s
+rsa  512 bits   0.0022s   0.0002s    449.6   4916.2
+rsa 1024 bits   0.0105s   0.0006s     95.3   1661.2
+rsa 2048 bits   0.0637s   0.0020s     15.7    495.6
+rsa 4096 bits   0.4457s   0.0075s      2.2    132.7
+                  sign    verify    sign/s verify/s
+dsa  512 bits   0.0028s   0.0048s    362.2    210.4
+dsa 1024 bits   0.0064s   0.0123s    155.2     81.6
+dsa 2048 bits   0.0201s   0.0394s     49.7     25.4
diff --git a/openssl/times/091/mips-rel.pl b/openssl/times/091/mips-rel.pl
new file mode 100644
index 0000000..4b25093
--- /dev/null
+++ b/openssl/times/091/mips-rel.pl
@@ -0,0 +1,21 @@
+#!/usr/local/bin/perl
+
+&doit(100,"Pentium   100 32",0.0195,0.1000,0.6406,4.6100);	# pentium-100
+&doit(200,"PPro      200 32",0.0070,0.0340,0.2087,1.4700);	# pentium-100
+&doit( 25,"R3000      25 32",0.0860,0.4825,3.2417,23.8833);	# R3000-25
+&doit(200,"R4400     200 32",0.0137,0.0717,0.4730,3.4367);	# R4400 32bit
+&doit(180,"R10000    180 32",0.0061,0.0311,0.1955,1.3871);	# R10000 32bit
+&doit(180,"R10000    180 64",0.0034,0.0149,0.0880,0.5933);	# R10000 64bit
+&doit(400,"DEC 21164 400 64",0.0022,0.0105,0.0637,0.4457);	# R10000 64bit
+
+sub doit
+	{
+	local($mhz,$label,@data)=@_;
+
+	for ($i=0; $i <= $#data; $i++)
+		{
+		$data[$i]=1/$data[$i]*200/$mhz;
+		}
+	printf("%s %6.1f %6.1f %6.1f %6.1f\n",$label,@data);
+	}
+
diff --git a/openssl/times/091/r10000.irx b/openssl/times/091/r10000.irx
new file mode 100644
index 0000000..237ee5d
--- /dev/null
+++ b/openssl/times/091/r10000.irx
@@ -0,0 +1,37 @@
+MIPS R10000 32kI+32kD 180mhz, IRIX 6.4
+
+Using crypto/bn/mips3.s
+
+This is built for n32, which is faster for all benchmarks than the n64
+compilation model
+
+SSLeay 0.9.0b 19-Apr-1998
+built on Sat Apr 25 12:43:14 EST 1998
+options:bn(64,64) md2(int) rc4(ptr,int) des(ptr,risc2,16,long) idea(int) blowfish(ptr) 
+C flags:cc -use_readonly_const -O2 -DTERMIOS -DB_ENDIAN
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                126.38k      349.38k      472.67k      517.01k      529.81k
+mdc2               501.64k      545.87k      551.80k      553.64k      554.41k
+md5               1825.77k     7623.64k    12630.47k    15111.74k    16012.09k
+hmac(md5)          780.81k     4472.86k     9667.22k    13802.67k    15777.89k
+sha1              1375.52k     6213.91k    11037.30k    13682.01k    14714.09k
+rmd160             856.72k     3454.40k     5598.33k     6689.94k     7073.48k
+rc4              11260.93k    13311.50k    13360.05k    13322.17k    13364.39k
+des cbc           2770.78k     3055.42k     3095.18k     3092.48k     3103.03k
+des ede3          1023.22k     1060.58k     1063.81k     1070.37k     1064.54k
+idea cbc          3029.09k     3334.30k     3375.29k     3375.65k     3380.64k
+rc2 cbc           2307.45k     2470.72k     2501.25k     2500.68k     2500.55k
+rc5-32/12 cbc     6770.91k     8629.89k     8909.58k     9009.64k     9044.95k
+blowfish cbc      4796.53k     5598.20k     5717.14k     5755.11k     5749.86k
+cast cbc          3986.20k     4426.17k     4465.04k     4476.84k     4475.08k
+                  sign    verify    sign/s verify/s
+rsa  512 bits   0.0034s   0.0003s    296.1   3225.4
+rsa 1024 bits   0.0139s   0.0008s     71.8   1221.8
+rsa 2048 bits   0.0815s   0.0026s     12.3    380.3
+rsa 4096 bits   0.5656s   0.0096s      1.8    103.7
+                  sign    verify    sign/s verify/s
+dsa  512 bits   0.0034s   0.0061s    290.8    164.9
+dsa 1024 bits   0.0084s   0.0161s    119.1     62.3
+dsa 2048 bits   0.0260s   0.0515s     38.5     19.4
+
diff --git a/openssl/times/091/r3000.ult b/openssl/times/091/r3000.ult
new file mode 100644
index 0000000..ecd3390
--- /dev/null
+++ b/openssl/times/091/r3000.ult
@@ -0,0 +1,32 @@
+MIPS R3000 64kI+64kD 25mhz, ultrix 4.3
+
+SSLeay 0.9.0b 19-Apr-1998
+built on Thu Apr 23 07:22:31 EST 1998
+options:bn(32,32) md2(int) rc4(ptr,int) des(ptr,risc2,16,long) idea(int) blowfish(idx) 
+C flags:cc -O2 -DL_ENDIAN -DNOPROTO -DNOCONST
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                 14.63k       40.65k       54.70k       60.07k       61.78k
+mdc2                29.43k       37.27k       38.23k       38.57k       38.60k
+md5                140.04k      676.59k     1283.84k     1654.10k     1802.24k
+hmac(md5)           60.51k      378.90k      937.82k     1470.46k     1766.74k
+sha1                60.77k      296.79k      525.40k      649.90k      699.05k
+rmd160              48.82k      227.16k      417.19k      530.31k      572.05k
+rc4                904.76k      996.20k     1007.53k     1015.65k     1010.35k
+des cbc            178.87k      209.39k      213.42k      215.55k      214.53k
+des ede3            74.25k       79.30k       80.40k       80.21k       80.14k
+idea cbc           181.02k      209.37k      214.44k      214.36k      213.83k
+rc2 cbc            161.52k      184.98k      187.99k      188.76k      189.05k
+rc5-32/12 cbc      398.99k      582.91k      614.66k      626.07k      621.87k
+blowfish cbc       296.38k      387.69k      405.50k      412.57k      410.05k
+cast cbc           214.76k      260.63k      266.92k      268.63k      258.26k
+                  sign    verify    sign/s verify/s
+rsa  512 bits   0.0870s   0.0089s     11.5    112.4
+rsa 1024 bits   0.4881s   0.0295s      2.0     33.9
+rsa 2048 bits   3.2750s   0.1072s      0.3      9.3
+rsa 4096 bits  23.9833s   0.4093s      0.0      2.4
+                  sign    verify    sign/s verify/s
+dsa  512 bits   0.0898s   0.1706s     11.1      5.9
+dsa 1024 bits   0.2847s   0.5565s      3.5      1.8
+dsa 2048 bits   1.0267s   2.0433s      1.0      0.5
+
diff --git a/openssl/times/091/r4400.irx b/openssl/times/091/r4400.irx
new file mode 100644
index 0000000..9b96ca1
--- /dev/null
+++ b/openssl/times/091/r4400.irx
@@ -0,0 +1,32 @@
+R4400 16kI+16kD 200mhz, Irix 5.3
+
+SSLeay 0.9.0e 27-Apr-1998
+built on Sun Apr 26 07:26:05 PDT 1998
+options:bn(64,32) md2(int) rc4(ptr,int) des(ptr,risc2,16,long) idea(int) blowfish(ptr) 
+C flags:cc -O2 -use_readonly_const -DTERMIOS -DB_ENDIAN
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                 79.80k      220.59k      298.01k      327.06k      338.60k
+mdc2               262.74k      285.30k      289.16k      288.36k      288.49k
+md5                930.35k     4167.13k     7167.91k     8678.23k     9235.86k
+hmac(md5)          399.44k     2367.57k     5370.74k     7884.28k     9076.98k
+sha1               550.96k     2488.17k     4342.76k     5362.50k     5745.40k
+rmd160             424.58k     1752.83k     2909.67k     3486.08k     3702.89k
+rc4               6687.79k     7834.63k     7962.61k     8035.65k     7915.28k
+des cbc           1544.20k     1725.94k     1748.35k     1758.17k     1745.61k
+des ede3           587.29k      637.75k      645.93k      643.17k      646.01k
+idea cbc          1575.52k     1719.75k     1732.41k     1736.69k     1740.11k
+rc2 cbc           1496.21k     1629.90k     1643.19k     1652.14k     1646.62k
+rc5-32/12 cbc     3452.48k     4276.47k     4390.74k     4405.25k     4400.12k
+blowfish cbc      2354.58k     3242.36k     3401.11k     3433.65k     3383.65k
+cast cbc          1942.22k     2152.28k     2187.51k     2185.67k     2177.20k
+                  sign    verify    sign/s verify/s
+rsa  512 bits   0.0130s   0.0014s     76.9    729.8
+rsa 1024 bits   0.0697s   0.0043s     14.4    233.9
+rsa 2048 bits   0.4664s   0.0156s      2.1     64.0
+rsa 4096 bits   3.4067s   0.0586s      0.3     17.1
+                  sign    verify    sign/s verify/s
+dsa  512 bits   0.0140s   0.0261s     71.4     38.4
+dsa 1024 bits   0.0417s   0.0794s     24.0     12.6
+dsa 2048 bits   0.1478s   0.2929s      6.8      3.4
+
diff --git a/openssl/times/100.lnx b/openssl/times/100.lnx
new file mode 100644
index 0000000..d0f4537
--- /dev/null
+++ b/openssl/times/100.lnx
@@ -0,0 +1,32 @@
+SSLeay 0.8.4c 03-Aug-1999
+built on Tue Nov  4 02:52:29 EST 1997
+options:bn(64,32) md2(int) rc4(ptr,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) 
+C flags:gcc -DL_ENDIAN -DTERMIO -DBN_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized -DMD5_ASM -DSHA1_ASM
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                53.27k      155.95k      201.30k      216.41k      236.78k
+mdc2              192.98k      207.98k      206.76k      206.17k      208.87k
+md5               993.15k     5748.27k    11944.70k    16477.53k    18287.27k
+hmac(md5)         404.97k     2787.58k     7690.07k    13744.43k    17601.88k
+sha1              563.24k     2851.67k     5363.71k     6879.23k     7441.07k
+rc4              7876.70k    10400.85k    10825.90k    10943.49k    10745.17k
+des cbc          2047.39k     2188.25k     2188.29k     2239.49k     2233.69k
+des ede3          660.55k      764.01k      773.55k      779.21k      780.97k
+idea cbc          653.93k      708.48k      715.43k      719.87k      720.90k
+rc2 cbc           648.08k      702.23k      708.78k      711.00k      709.97k
+blowfish cbc     3764.39k     4288.66k     4375.04k     4497.07k     4423.68k
+cast cbc         2757.14k     2993.75k     3035.31k     3078.90k     3055.62k
+
+blowfish cbc     3258.81k     3673.47k     3767.30k     3774.12k     3719.17k
+cast cbc         2677.05k     3164.78k     3273.05k     3287.38k     3244.03k
+
+
+                  sign    verify
+rsa  512 bits   0.0213s   0.0020s
+rsa 1024 bits   0.1073s   0.0063s
+rsa 2048 bits   0.6873s   0.0224s
+rsa 4096 bits   4.9333s   0.0845s
+                  sign    verify
+dsa  512 bits   0.0201s   0.0385s
+dsa 1024 bits   0.0604s   0.1190s
+dsa 2048 bits   0.2121s   0.4229s
diff --git a/openssl/times/100.nt b/openssl/times/100.nt
new file mode 100644
index 0000000..0dd7cfc
--- /dev/null
+++ b/openssl/times/100.nt
@@ -0,0 +1,29 @@
+SSLeay 0.8.4c 03-Aug-1999
+built on Tue Aug  3 09:49:58 EST 1999
+options:bn(64,32) md2(int) rc4(ptr,int) des(idx,cisc,4,long) idea(int) blowfish(
+ptr2)
+C flags:cl /W3 /WX /G5 /Ox /O2 /Ob2 /Gs0 /GF /Gy /nologo -DWIN32 -DL_ENDIAN -DBN
+_ASM -DMD5_ASM -DSHA1_ASM
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                93.07k      258.38k      349.03k      382.83k      392.87k
+mdc2              245.80k      259.02k      259.34k      259.16k      260.14k
+md5              1103.42k     6017.65k    12210.49k    16552.11k    18291.77k
+hmac(md5)         520.15k     3394.00k     8761.86k    14593.96k    17742.40k
+sha1              538.06k     2726.76k     5242.22k     6821.12k     7426.18k
+rc4              8283.90k    10513.09k    10886.38k    10929.50k    10816.75k
+des cbc          2073.10k     2232.91k     2251.61k     2256.46k     2232.44k
+des ede3          758.85k      782.46k      786.14k      786.08k      781.24k
+idea cbc          831.02k      892.63k      901.07k      903.48k      901.85k
+rc2 cbc           799.89k      866.09k      873.96k      876.22k      874.03k
+blowfish cbc     3835.32k     4418.78k     4511.94k     4494.54k     4416.92k
+cast cbc         2974.68k     3272.71k     3313.04k     3335.17k     3261.51k
+                  sign    verify
+rsa  512 bits   0.0202s   0.0019s
+rsa 1024 bits   0.1029s   0.0062s
+rsa 2048 bits   0.6770s   0.0220s
+rsa 4096 bits   4.8770s   0.0838s
+                  sign    verify
+dsa  512 bits   0.0191s   0.0364s
+dsa 1024 bits   0.0590s   0.1141s
+dsa 2048 bits   0.2088s   0.4171s
diff --git a/openssl/times/200.lnx b/openssl/times/200.lnx
new file mode 100644
index 0000000..fd7e7f4
--- /dev/null
+++ b/openssl/times/200.lnx
@@ -0,0 +1,30 @@
+This machine was slightly loaded :-(
+
+SSLeay 0.8.4c 03-Aug-1999
+built on Tue Nov  4 02:52:29 EST 1997
+options:bn(64,32) md2(int) rc4(ptr,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) 
+C flags:gcc -DL_ENDIAN -DTERMIO -DBN_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized -DMD5_ASM -DSHA1_ASM
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2               130.86k      365.31k      499.60k      547.75k      561.41k
+mdc2              526.03k      581.38k      587.12k      586.31k      589.60k
+md5              1919.49k    11173.23k    22387.60k    29553.47k    32587.21k
+hmac(md5)         747.09k     5248.35k    14275.44k    24713.26k    31737.13k
+sha1             1336.63k     6400.50k    11668.67k    14648.83k    15700.85k
+rc4             15002.32k    21327.21k    22301.63k    22503.78k    22549.26k
+des cbc          4115.16k     4521.08k     4632.37k     4607.28k     4570.57k
+des ede3         1540.29k     1609.76k     1623.64k     1620.76k     1624.18k
+idea cbc         2405.08k     2664.78k     2704.22k     2713.95k     2716.29k
+rc2 cbc          1634.07k     1764.30k     1780.23k     1790.27k     1788.12k
+blowfish cbc     5993.98k     6927.27k     7083.61k     7088.40k     7123.72k
+cast cbc         5981.52k     6900.44k     7079.70k     7110.40k     7057.72k
+                  sign    verify
+rsa  512 bits   0.0085s   0.0007s
+rsa 1024 bits   0.0377s   0.0020s
+rsa 2048 bits   0.2176s   0.0067s
+rsa 4096 bits   1.4800s   0.0242s
+sign    verify
+dsa  512 bits   0.0071s   0.0132s
+dsa 1024 bits   0.0192s   0.0376s
+dsa 2048 bits   0.0638s   0.1280s
+
diff --git a/openssl/times/486-66.dos b/openssl/times/486-66.dos
new file mode 100644
index 0000000..1644bf8
--- /dev/null
+++ b/openssl/times/486-66.dos
@@ -0,0 +1,22 @@
+MS-dos static libs, 16bit C build, 16bit assember
+
+SSLeay 0.6.1
+options:bn(32,16) md2(char) rc4(idx,int) des(ptr,long) idea(short)
+C flags:cl /ALw /Gx- /Gf /f- /Ocgnotb2 /G2 /W3 /WX -DL_ENDIAN /nologo -DMSDOS -D
+NO_SOCK
+The 'numbers' are in 1000s of bytes per second processed.
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2             18.62k       55.54k       76.88k       85.39k       86.52k
+md5             94.03k      442.06k      794.38k      974.51k     1061.31k
+sha             38.37k      166.23k      272.78k      331.41k      353.77k
+sha1            34.38k      147.77k      244.77k      292.57k      312.08k
+rc4            641.25k      795.34k      817.16k      829.57k      817.16k
+des cfb        111.46k      118.08k      120.69k      119.16k      119.37k
+des cbc        122.96k      135.69k      137.10k      135.69k      135.40k
+des ede3        48.01k       50.92k       50.32k       50.96k       50.96k
+idea cfb        97.09k      100.21k      100.36k      101.14k      100.98k
+idea cbc       102.08k      109.41k      111.46k      111.65k      110.52k
+rc2 cfb        120.47k      125.55k      125.79k      125.55k      125.55k
+rc2 cbc        129.77k      140.33k      143.72k      142.16k      141.85k
+rsa  512 bits   0.264s
+rsa 1024 bits   1.494s
diff --git a/openssl/times/486-66.nt b/openssl/times/486-66.nt
new file mode 100644
index 0000000..b26a900
--- /dev/null
+++ b/openssl/times/486-66.nt
@@ -0,0 +1,22 @@
+SSLeay 0.6.1 02-Jul-1996
+built on Fri Jul 10 09:53:15 EST 1996
+options:bn(64,32) md2(int) rc4(idx,int) des(idx,long) idea(int)
+C flags:cl /W3 /WX /G5 /Ox /O2 /Ob2 /Gs0 /nologo -DWIN32 -DL_ENDIAN /MD
+The 'numbers' are in 1000s of bytes per second processed.
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2             38.27k      107.28k      145.43k      159.60k      164.15k
+md5            399.00k     1946.13k     3610.80k     4511.94k     4477.27k
+sha            182.04k      851.26k     1470.65k     1799.20k     1876.48k
+sha1           151.83k      756.55k     1289.76k     1567.38k     1625.70k
+rc4           1853.92k     2196.25k     2232.91k     2241.31k     2152.96k
+des cfb        360.58k      382.69k      384.94k      386.07k      377.19k
+des cbc        376.10k      431.87k      436.32k      437.78k      430.45k
+des ede3       152.55k      160.38k      161.51k      161.33k      159.98k
+idea cfb       245.59k      255.60k      256.65k      257.16k      254.61k
+idea cbc       257.16k      276.12k      279.05k      279.11k      276.70k
+rc2 cfb        280.25k      293.49k      294.74k      294.15k      291.47k
+rc2 cbc        295.47k      321.57k      324.76k      324.76k      320.00k
+rsa  512 bits   0.084s
+rsa 1024 bits   0.495s
+rsa 2048 bits   3.435s
+
diff --git a/openssl/times/486-66.w31 b/openssl/times/486-66.w31
new file mode 100644
index 0000000..381f149
--- /dev/null
+++ b/openssl/times/486-66.w31
@@ -0,0 +1,23 @@
+Windows 3.1 DLL's, 16 bit C with 32bit assember
+
+SSLeay 0.6.1 02-Jul-1996
+built on Wed Jul 10 09:53:15 EST 1996
+options:bn(32,32) md2(char) rc4(idx,int) des(ptr,long) idea(short)
+C flags:cl /ALw /Gx- /Gf /G2 /f- /Ocgnotb2 /W3 /WX -DL_ENDIAN /nologo -DWIN16
+The 'numbers' are in 1000s of bytes per second processed.
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2             18.94k       54.27k       73.43k       80.91k       83.75k
+md5             78.96k      391.26k      734.30k      919.80k      992.97k
+sha             39.01k      168.04k      280.67k      336.08k      359.10k
+sha1            35.20k      150.14k      247.31k      294.54k      313.94k
+rc4            509.61k      655.36k      678.43k      677.02k      670.10k
+des cfb         97.09k      104.69k      106.56k      105.70k      106.56k
+des cbc        116.82k      129.77k      131.07k      131.07k      131.07k
+des ede3        44.22k       47.90k       48.53k       48.47k       47.86k
+idea cfb        83.49k       87.03k       87.03k       87.15k       87.73k
+idea cbc        89.04k       96.23k       96.95k       97.81k       97.09k
+rc2 cfb        108.32k      113.58k      113.78k      114.57k      114.77k
+rc2 cbc        118.08k      131.07k      134.02k      134.02k      132.66k
+rsa  512 bits   0.181s
+rsa 1024 bits   0.846s
+
diff --git a/openssl/times/5.lnx b/openssl/times/5.lnx
new file mode 100644
index 0000000..1c1e392
--- /dev/null
+++ b/openssl/times/5.lnx
@@ -0,0 +1,29 @@
+SSLeay 0.8.5g 24-Jan-1998
+built on Tue Jan 27 08:11:42 EST 1998
+options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) 
+C flags:gcc -DL_ENDIAN -DTERMIO -DBN_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized -DSHA1_ASM -DMD5_ASM -DRMD160_ASM
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                 56.55k      156.69k      211.63k      231.77k      238.71k
+mdc2               192.26k      208.09k      210.09k      209.58k      210.26k
+md5                991.04k     5745.51k    11932.67k    16465.24k    18306.39k
+hmac(md5)          333.99k     2383.89k     6890.67k    13133.82k    17397.08k
+sha1               571.68k     2883.88k     5379.07k     6880.26k     7443.80k
+rmd160             409.41k     2212.91k     4225.45k     5456.55k     5928.28k
+rc4               6847.57k     8596.22k     8901.80k     8912.90k     8850.09k
+des cbc           2046.29k     2229.78k     2254.76k     2259.97k     2233.69k
+des ede3           751.11k      779.95k      783.96k      784.38k      780.97k
+idea cbc           653.40k      708.29k      718.42k      720.21k      720.90k
+rc2 cbc            647.19k      702.46k      709.21k      710.66k      709.97k
+rc5-32/12 cbc     3498.18k     4054.12k     4133.46k     4151.64k     4139.69k
+blowfish cbc      3763.95k     4437.74k     4532.74k     4515.50k     4448.26k
+cast cbc          2754.22k     3020.67k     3079.08k     3069.95k     3036.50k
+                  sign    verify    sign/s verify/s
+rsa  512 bits   0.0207s   0.0020s     48.3    511.3
+rsa 1024 bits   0.1018s   0.0059s      9.8    169.6
+rsa 2048 bits   0.6438s   0.0208s      1.6     48.0
+rsa 4096 bits   4.6033s   0.0793s      0.2     12.6
+                  sign    verify    sign/s verify/s
+dsa  512 bits   0.0190s   0.0359s     52.6     27.8
+dsa 1024 bits   0.0566s   0.1109s     17.7      9.0
+dsa 2048 bits   0.1988s   0.3915s      5.0      2.6
diff --git a/openssl/times/586-085i.nt b/openssl/times/586-085i.nt
new file mode 100644
index 0000000..8a57975
--- /dev/null
+++ b/openssl/times/586-085i.nt
@@ -0,0 +1,29 @@
+SSLeay 0.8.5i 28-Jan-1998
+built on Wed Jan 28 18:00:07 EST 1998
+options:bn(64,32) md2(int) rc4(idx,int) des(idx,cisc,4,long) idea(int) blowfish(ptr2)
+C flags:cl /MT /W3 /WX /G5 /Ox /O2 /Ob2 /Gs0 /GF /Gy /nologo -DWIN32 -DL_ENDIAN -DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                 92.74k      257.59k      348.16k      381.79k      392.14k
+mdc2               227.65k      247.82k      249.90k      250.65k      250.20k
+md5               1089.54k     5966.29k    12104.77k    16493.53k    18204.44k
+hmac(md5)          513.53k     3361.36k     8725.41k    14543.36k    17593.56k
+sha1               580.74k     2880.51k     5376.62k     6865.78k     7413.05k
+rmd160             508.06k     2427.96k     4385.51k     5510.84k     5915.80k
+rc4               8004.40k    10408.74k    10794.48k    10884.12k    10728.22k
+des cbc           2057.24k     2222.97k     2246.79k     2209.39k     2223.44k
+des ede3           739.42k      761.99k      765.48k      760.26k      760.97k
+idea cbc           827.08k      889.60k      898.83k      901.15k      897.98k
+rc2 cbc            795.64k      861.04k      871.13k      872.58k      871.13k
+rc5-32/12 cbc     3597.17k     4139.66k     4204.39k     4223.02k     4204.39k
+blowfish cbc      3807.47k     3996.10k     4156.07k     4204.39k     4105.62k
+cast cbc          2777.68k     2814.21k     2892.62k     2916.76k     2868.88k
+                  sign    verify    sign/s verify/s
+rsa  512 bits   0.0178s   0.0018s     56.3    541.6
+rsa 1024 bits   0.0945s   0.0059s     10.6    168.3
+rsa 2048 bits   0.6269s   0.0208s      1.6     48.0
+rsa 4096 bits   4.5560s   0.0784s      0.2     12.8
+                  sign    verify    sign/s verify/s
+dsa  512 bits   0.0178s   0.0340s     56.2     29.4
+dsa 1024 bits   0.0552s   0.1077s     18.1      9.3
+dsa 2048 bits   0.1963s   0.3811s      5.1      2.6
diff --git a/openssl/times/586-100.LN3 b/openssl/times/586-100.LN3
new file mode 100644
index 0000000..a6fa818
--- /dev/null
+++ b/openssl/times/586-100.LN3
@@ -0,0 +1,26 @@
+SSLeay 0.8.3v 15-Oct-1997
+built on Wed Oct 15 10:05:00 EST 1997
+options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) 
+C flags:gcc -DL_ENDIAN -DTERMIO -DX86_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                56.27k      156.76k      211.46k      231.77k      238.71k
+mdc2              188.74k      206.12k      207.70k      207.87k      208.18k
+md5               991.56k     5718.31k    11748.61k    16090.79k    17850.37k
+hmac(md5)         387.56k     2636.01k     7327.83k    13340.33k    17091.24k
+sha1              463.55k     2274.18k     4071.17k     5072.90k     5447.68k
+rc4              3673.94k     4314.52k     4402.26k     4427.09k     4407.30k
+des cbc          2023.79k     2209.77k     2233.34k     2220.71k     2222.76k
+des ede3          747.17k      778.54k      781.57k      778.24k      778.24k
+idea cbc          614.64k      678.04k      683.52k      685.06k      685.40k
+rc2 cbc           536.83k      574.10k      578.05k      579.24k      578.90k
+blowfish cbc     3673.39k     4354.58k     4450.22k     4429.48k     4377.26k
+                  sign    verify
+rsa  512 bits   0.0217s   0.0021s
+rsa 1024 bits   0.1083s   0.0064s
+rsa 2048 bits   0.6867s   0.0223s
+rsa 4096 bits   4.9400s   0.0846s
+                  sign    verify
+dsa  512 bits   0.0203s   0.0387s
+dsa 1024 bits   0.0599s   0.1170s
+dsa 2048 bits   0.2115s   0.4242s
diff --git a/openssl/times/586-100.NT2 b/openssl/times/586-100.NT2
new file mode 100644
index 0000000..7f8c167
--- /dev/null
+++ b/openssl/times/586-100.NT2
@@ -0,0 +1,26 @@
+SSLeay 0.8.3e 30-Sep-1997
+built on Tue Sep 30 14:52:58 EST 1997
+options:bn(64,32) md2(int) rc4(idx,int) des(idx,cisc,4,long) idea(int) blowfish(ptr2)
+C flags:cl /W3 /WX /G5 /Ox /O2 /Ob2 /Gs0 /GF /Gy /nologo -DWIN32 -DL_ENDIAN -DX86_ASM
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                92.99k      257.59k      348.16k      381.47k      392.14k
+mdc2              223.77k      235.30k      237.15k      236.77k      237.29k
+md5               862.53k     4222.17k     7842.75k     9925.00k    10392.23k
+sha               491.34k     2338.61k     4062.28k     4986.10k     5307.90k
+sha1              494.38k     2234.94k     3838.83k     4679.58k     4980.18k
+rc4              6338.10k     7489.83k     7676.25k     7698.80k     7631.56k
+des cbc          1654.17k     1917.66k     1961.05k     1968.05k     1960.69k
+des ede3          691.17k      739.42k      744.13k      745.82k      741.40k
+idea cbc          788.46k      870.33k      879.16k      881.38k      879.90k
+rc2 cbc           794.44k      859.63k      868.24k      869.68k      867.45k
+blowfish cbc     2379.88k     3017.48k     3116.12k     3134.76k     3070.50k
+                  sign    verify
+rsa  512 bits   0.0204s   0.0027s
+rsa 1024 bits   0.1074s   0.0032s
+rsa 2048 bits   0.6890s   0.0246s
+rsa 4096 bits   5.0180s   0.0911s
+                  sign    verify
+dsa  512 bits   0.0201s   0.0376s
+dsa 1024 bits   0.0608s   0.1193s
+dsa 2048 bits   0.2133s   0.4294s
diff --git a/openssl/times/586-100.dos b/openssl/times/586-100.dos
new file mode 100644
index 0000000..3085c25
--- /dev/null
+++ b/openssl/times/586-100.dos
@@ -0,0 +1,24 @@
+ms-dos static libs, 16 bit C and 16 bit assmber 
+
+SSLeay 0.6.1 02-Jul-1996
+built on Tue Jul  9 22:52:54 EST 1996
+options:bn(32,16) md2(char) rc4(idx,int) des(ptr,long) idea(short)
+C flags:cl /ALw /Gx- /Gf /G2 /f- /Ocgnotb2 /W3 /WX -DL_ENDIAN /nologo -DMSDOS -DNO_SOCK
+The 'numbers' are in 1000s of bytes per second processed.
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2             45.99k      130.75k      176.53k      199.35k      203.21k
+md5            236.17k     1072.16k     1839.61k     2221.56k     2383.13k
+sha            107.97k      459.10k      757.64k      908.64k      954.99k
+sha1            96.95k      409.92k      672.16k      788.40k      844.26k
+rc4           1659.14k     1956.30k     2022.72k     2022.72k     2022.72k
+des cfb        313.57k      326.86k      326.86k      331.83k      326.86k
+des cbc        345.84k      378.82k      378.82k      384.38k      378.82k
+des ede3       139.59k      144.66k      144.61k      144.45k      143.29k
+idea cfb       262.67k      274.21k      274.21k      274.21k      274.21k
+idea cbc       284.32k      318.14k      318.14k      318.14k      318.14k
+rc2 cfb        265.33k      274.21k      277.69k      277.11k      277.69k
+rc2 cbc        283.71k      310.60k      309.86k      313.57k      314.32k
+rsa  512 bits   0.104s
+rsa 1024 bits   0.566s
+rsa 2048 bits   3.680s
+rsa 4096 bits  26.740s
diff --git a/openssl/times/586-100.ln4 b/openssl/times/586-100.ln4
new file mode 100644
index 0000000..14a9db9
--- /dev/null
+++ b/openssl/times/586-100.ln4
@@ -0,0 +1,26 @@
+SSLeay 0.8.3aa 24-Oct-1997
+built on Mon Oct 27 10:16:25 EST 1997
+options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) 
+C flags:gcc -DL_ENDIAN -DTERMIO -DBN_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized -DMD5_ASM -DSHA1_ASM
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                56.78k      156.71k      211.46k      231.77k      238.71k
+mdc2              187.45k      200.49k      201.64k      202.75k      202.77k
+md5              1002.51k     5798.66k    11967.15k    16449.19k    18251.78k
+hmac(md5)         468.71k     3173.46k     8386.99k    14305.56k    17607.34k
+sha1              586.98k     2934.87k     5393.58k     6863.19k     7408.30k
+rc4              3675.10k     4314.15k     4402.77k     4427.78k     4404.57k
+des cbc          1902.96k     2202.01k     2242.30k     2252.46k     2236.42k
+des ede3          700.15k      774.23k      783.70k      781.62k      783.70k
+idea cbc          618.46k      677.93k      683.61k      685.40k      685.40k
+rc2 cbc           536.97k      573.87k      577.96k      579.24k      578.90k
+blowfish cbc     3672.66k     4271.89k     4428.80k     4469.76k     4374.53k
+                  sign    verify
+rsa  512 bits   0.0213s   0.0021s
+rsa 1024 bits   0.1075s   0.0063s
+rsa 2048 bits   0.6853s   0.0224s
+rsa 4096 bits   4.9400s   0.0845s
+                  sign    verify
+dsa  512 bits   0.0203s   0.0380s
+dsa 1024 bits   0.0600s   0.1189s
+dsa 2048 bits   0.2110s   0.4250s
diff --git a/openssl/times/586-100.lnx b/openssl/times/586-100.lnx
new file mode 100644
index 0000000..0c05173
--- /dev/null
+++ b/openssl/times/586-100.lnx
@@ -0,0 +1,23 @@
+SSLeay 0.7.3 30-Apr-1997
+built on Mon May 12 04:13:55 EST 1997
+options:bn(64,32) md2(char) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2)
+C flags:gcc -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                72.95k      202.77k      274.01k      300.37k      309.23k
+md5               770.57k     4094.02k     7409.41k     9302.36k     9986.05k
+sha               363.05k     1571.07k     2613.85k     3134.81k     3320.49k
+sha1              340.94k     1462.85k     2419.20k     2892.12k     3042.35k
+rc4              3676.91k     4314.94k     4407.47k     4430.51k     4412.76k
+des cbc          1489.95k     1799.08k     1841.66k     1851.73k     1848.66k
+des ede3          621.93k      711.19k      726.10k      729.77k      729.09k
+idea cbc          618.16k      676.99k      683.09k      684.37k      683.59k
+rc2 cbc           537.59k      573.93k      578.56k      579.58k      579.70k
+blowfish cbc     2077.57k     2682.20k     2827.18k     2840.92k     2842.62k
+rsa  512 bits   0.024s   0.003
+rsa 1024 bits   0.120s   0.003
+rsa 2048 bits   0.751s   0.026
+rsa 4096 bits   5.320s   0.096
+dsa  512 bits   0.022s   0.042
+dsa 1024 bits   0.065s   0.126
+dsa 2048 bits   0.227s   0.449
diff --git a/openssl/times/586-100.nt b/openssl/times/586-100.nt
new file mode 100644
index 0000000..9adcac3
--- /dev/null
+++ b/openssl/times/586-100.nt
@@ -0,0 +1,23 @@
+SSLeay 0.7.3 30-Apr-1997
+built on Mon May 19 10:47:38 EST 1997
+options:bn(64,32) md2(char) rc4(idx,int) des(idx,cisc,4,long) idea(int) blowfish(ptr2)
+C flags not available
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                89.57k      245.94k      331.59k      362.95k      373.29k
+md5               858.93k     4175.51k     7700.21k     9715.78k    10369.11k
+sha               466.18k     2103.67k     3607.69k     4399.31k     4669.16k
+sha1              449.59k     2041.02k     3496.13k     4256.45k     4512.92k
+rc4              5862.55k     7447.27k     7698.80k     7768.38k     7653.84k
+des cbc          1562.71k     1879.84k     1928.24k     1938.93k     1911.02k
+des ede3          680.27k      707.97k      728.62k      733.15k      725.98k
+idea cbc          797.46k      885.85k      895.68k      898.06k      896.45k
+rc2 cbc           609.46k      648.75k      654.01k      654.42k      653.60k
+blowfish cbc     2357.94k     3000.22k     3106.89k     3134.76k     3080.42k
+rsa  512 bits   0.022s   0.003
+rsa 1024 bits   0.112s   0.003
+rsa 2048 bits   0.726s   0.026
+rsa 4096 bits   5.268s   0.095
+dsa  512 bits   0.021s   0.039
+dsa 1024 bits   0.063s   0.127
+dsa 2048 bits   0.224s   0.451
diff --git a/openssl/times/586-100.ntx b/openssl/times/586-100.ntx
new file mode 100644
index 0000000..35166a5
--- /dev/null
+++ b/openssl/times/586-100.ntx
@@ -0,0 +1,30 @@
+SSLeay 0.8.5f 22-Jan-1998
+built on Wed Jan 21 17:11:53 EST 1998
+options:bn(64,32) md2(int) rc4(idx,int) des(idx,cisc,4,long) idea(int) blowfish(
+ptr2)
+C flags:cl /MT /W3 /WX /G5 /Ox /O2 /Ob2 /Gs0 /GF /Gy /nologo -DWIN32 -DL_ENDIAN
+-DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                92.99k      257.43k      347.84k      381.82k      392.14k
+mdc2              232.19k      253.68k      257.57k      258.70k      258.70k
+md5              1094.09k     5974.79k    12139.81k    16487.04k    18291.77k
+hmac(md5)         375.70k     2590.04k     7309.70k    13469.18k    17447.19k
+sha1              613.78k     2982.93k     5446.44k     6889.46k     7424.86k
+rmd160            501.23k     2405.68k     4367.25k     5503.61k     5915.80k
+rc4              8167.75k    10429.44k    10839.12k    10929.50k    10772.30k
+des cbc          2057.24k     2218.27k     2237.20k     2227.69k     2213.59k
+des ede3          719.63k      727.11k      728.77k      719.56k      722.97k
+idea cbc          827.67k      888.85k      898.06k      900.30k      898.75k
+rc2 cbc           797.46k      862.53k      870.33k      872.58k      870.40k
+blowfish cbc     3835.32k     4435.60k     4513.89k     4513.89k     4416.92k
+cast cbc         2785.06k     3052.62k     3088.59k     3034.95k     3034.95k
+                  sign    verify    sign/s verify/s
+rsa  512 bits   0.0202s   0.0020s     49.4    500.2
+rsa 1024 bits   0.1030s   0.0063s      9.7    159.4
+rsa 2048 bits   0.6740s   0.0223s      1.5     44.9
+rsa 4096 bits   4.8970s   0.0844s      0.2     11.8
+                  sign    verify    sign/s verify/s
+dsa  512 bits   0.0191s   0.0361s     52.4     27.7
+dsa 1024 bits   0.0587s   0.1167s     17.0      8.6
+dsa 2048 bits   0.2091s   0.4123s      4.8      2.4
diff --git a/openssl/times/586-100.w31 b/openssl/times/586-100.w31
new file mode 100644
index 0000000..d5b1c10
--- /dev/null
+++ b/openssl/times/586-100.w31
@@ -0,0 +1,27 @@
+Pentium 100, Windows 3.1 DLL's, 16 bit C, 32bit assember.
+
+Running under Windows NT 4.0 Beta 2
+
+SSLeay 0.6.4 20-Aug-1996
+built on Thu Aug 22 08:44:21 EST 1996
+options:bn(32,32) md2(char) rc4(idx,int) des(ptr,long) idea(short)
+C flags:cl /ALw /Gx- /Gf /G2 /f- /Ocgnotb2 /W3 /WX -DL_ENDIAN /nologo -DWIN16
+The 'numbers' are in 1000s of bytes per second processed.
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2             45.83k      128.82k      180.17k      194.90k      198.59k
+md5            224.82k     1038.19k     1801.68k     2175.47k     2330.17k
+sha            105.11k      448.11k      739.48k      884.13k      944.66k
+sha1            94.71k      402.99k      667.88k      795.58k      844.26k
+rc4           1614.19k     1956.30k     2022.72k     2022.72k     2022.72k
+des cfb        291.27k      318.14k      318.14k      318.14k      322.84k
+des cbc        326.86k      356.17k      362.08k      362.08k      367.15k
+des ede3       132.40k      139.57k      139.53k      139.37k      140.97k
+idea cfb       265.33k      280.67k      280.67k      277.69k      281.27k
+idea cbc       274.21k      302.01k      306.24k      306.24k      305.53k
+rc2 cfb        264.79k      274.21k      274.78k      274.21k      274.21k
+rc2 cbc        281.27k      306.24k      309.86k      305.53k      309.86k
+rsa  512 bits   0.058s
+rsa 1024 bits   0.280s
+rsa 2048 bits   1.430s
+rsa 4096 bits  10.600s
+
diff --git a/openssl/times/586-1002.lnx b/openssl/times/586-1002.lnx
new file mode 100644
index 0000000..d830bce
--- /dev/null
+++ b/openssl/times/586-1002.lnx
@@ -0,0 +1,26 @@
+SSLeay 0.8.3e 30-Sep-1997
+built on Wed Oct  1 03:01:44 EST 1997
+options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) 
+C flags:gcc -DL_ENDIAN -DTERMIO -DX86_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                56.21k      156.57k      211.29k      231.77k      237.92k
+mdc2              170.99k      191.70k      193.90k      195.58k      195.95k
+md5               770.50k     3961.96k     7291.22k     9250.82k     9942.36k
+sha               344.93k     1520.77k     2569.81k     3108.52k     3295.91k
+sha1              326.20k     1423.74k     2385.15k     2870.95k     3041.96k
+rc4              3672.88k     4309.65k     4374.41k     4408.66k     4355.41k
+des cbc          1349.73k     1689.05k     1735.34k     1748.99k     1739.43k
+des ede3          638.70k      704.00k      711.85k      714.41k      712.70k
+idea cbc          619.55k      677.33k      683.26k      685.06k      685.40k
+rc2 cbc           521.18k      571.20k      573.46k      578.90k      578.90k
+blowfish cbc     2079.67k     2592.49k     2702.34k     2730.33k     2695.17k
+                  sign    verify
+rsa  512 bits   0.0213s   0.0026s
+rsa 1024 bits   0.1099s   0.0031s
+rsa 2048 bits   0.7007s   0.0248s
+rsa 4096 bits   5.0500s   0.0921s
+                  sign    verify
+dsa  512 bits   0.0203s   0.0389s
+dsa 1024 bits   0.0614s   0.1222s
+dsa 2048 bits   0.2149s   0.4283s
diff --git a/openssl/times/586p-100.lnx b/openssl/times/586p-100.lnx
new file mode 100644
index 0000000..561eb31
--- /dev/null
+++ b/openssl/times/586p-100.lnx
@@ -0,0 +1,26 @@
+Pentium 100 - Linux 1.2.13 - gcc 2.7.2p
+This is the pentium specific version of gcc
+
+SSLeay 0.6.4 20-Aug-1996
+built on Thu Aug 22 08:27:58 EST 1996
+options:bn(64,32) md2(char) rc4(idx,int) des(idx,long) idea(int)
+C flags:gcc -DL_ENDIAN -DTERMIO -O6 -fomit-frame-pointer -mpentium -Wall
+The 'numbers' are in 1000s of bytes per second processed.
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2             74.90k      208.43k      282.11k      309.59k      318.43k
+md5            807.08k     4205.67k     7801.51k     9958.06k    10810.71k
+sha            405.98k     1821.55k     3119.10k     3799.04k     4052.31k
+sha1           389.13k     1699.50k     2852.78k     3437.57k     3656.36k
+rc4           3621.15k     4130.07k     4212.74k     4228.44k     4213.42k
+des cfb        794.39k      828.37k      831.74k      832.51k      832.85k
+des cbc        817.68k      886.17k      894.72k      896.00k      892.93k
+des ede3       308.83k      323.29k      324.61k      324.95k      324.95k
+idea cfb       690.41k      715.39k      718.51k      719.19k      718.17k
+idea cbc       696.80k      760.60k      767.32k      768.68k      770.05k
+rc2 cfb        619.91k      639.74k      642.30k      642.73k      641.71k
+rc2 cbc        631.99k      671.42k      676.35k      676.18k      677.21k
+rsa  512 bits   0.025s
+rsa 1024 bits   0.123s
+rsa 2048 bits   0.756s
+rsa 4096 bits   5.365s
+
diff --git a/openssl/times/686-200.bsd b/openssl/times/686-200.bsd
new file mode 100644
index 0000000..f23c580
--- /dev/null
+++ b/openssl/times/686-200.bsd
@@ -0,0 +1,25 @@
+Pentium Pro 200mhz
+FreeBSD 2.1.5
+gcc 2.7.2.2
+
+SSLeay 0.7.0 30-Jan-1997
+built on Tue Apr 22 12:14:36 EST 1997
+options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2)
+C flags:gcc -DTERMIOS -D_ANSI_SOURCE -fomit-frame-pointer -O3 -m486 -Wall
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2               130.99k      367.68k      499.09k      547.04k      566.50k
+md5              1924.98k     8293.50k    13464.41k    16010.39k    16820.68k
+sha              1250.75k     5330.43k     8636.88k    10227.36k    10779.14k
+sha1             1071.55k     4572.50k     7459.98k     8791.96k     9341.61k
+rc4             10724.22k    14546.25k    15240.18k    15259.50k    15265.63k
+des cbc          3309.11k     3883.01k     3968.25k     3971.86k     3979.14k
+des ede3         1442.98k     1548.33k     1562.48k     1562.00k     1563.33k
+idea cbc         2195.69k     2506.39k     2529.59k     2545.66k     2546.54k
+rc2 cbc           806.00k      833.52k      837.58k      838.52k      836.69k
+blowfish cbc     4687.34k     5949.97k     6182.43k     6248.11k     6226.09k
+rsa  512 bits   0.010s
+rsa 1024 bits   0.045s
+rsa 2048 bits   0.260s
+rsa 4096 bits   1.690s
+
diff --git a/openssl/times/686-200.lnx b/openssl/times/686-200.lnx
new file mode 100644
index 0000000..a10cc2f
--- /dev/null
+++ b/openssl/times/686-200.lnx
@@ -0,0 +1,26 @@
+SSLeay 0.8.2a 04-Sep-1997
+built on Fri Sep  5 17:37:05 EST 1997
+options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) C flags:gcc -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2               131.02k      368.41k      500.57k      549.21k      566.09k
+mdc2              535.60k      589.10k      595.88k      595.97k      594.54k
+md5              1801.53k     9674.77k    17484.03k    21849.43k    23592.96k
+sha              1261.63k     5533.25k     9285.63k    11187.88k    11913.90k
+sha1             1103.13k     4782.53k     7933.78k     9472.34k    10070.70k
+rc4             10722.53k    14443.93k    15215.79k    15299.24k    15219.59k
+des cbc          3286.57k     3827.73k     3913.39k     3931.82k     3926.70k
+des ede3         1443.50k     1549.08k     1561.17k     1566.38k     1564.67k
+idea cbc         2203.64k     2508.16k     2538.33k     2543.62k     2547.71k
+rc2 cbc          1430.94k     1511.59k     1524.82k     1527.13k     1523.33k
+blowfish cbc     4716.07k     5965.82k     6190.17k     6243.67k     6234.11k
+                  sign    verify
+rsa  512 bits   0.0100s   0.0011s
+rsa 1024 bits   0.0451s   0.0012s
+rsa 2048 bits   0.2605s   0.0086s
+rsa 4096 bits   1.6883s   0.0302s
+                  sign    verify
+dsa  512 bits   0.0083s   0.0156s
+dsa 1024 bits   0.0228s   0.0454s
+dsa 2048 bits   0.0719s   0.1446s
+
diff --git a/openssl/times/686-200.nt b/openssl/times/686-200.nt
new file mode 100644
index 0000000..c8cbaa0
--- /dev/null
+++ b/openssl/times/686-200.nt
@@ -0,0 +1,24 @@
+built on Tue May 13 08:24:51 EST 1997
+options:bn(64,32) md2(char) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfi
+sh(ptr2)
+C flags not available
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2               156.39k      427.99k      576.14k      628.36k      647.27k
+md5              2120.48k    10255.02k    18396.07k    22795.13k    24244.53k
+sha              1468.59k     6388.89k    10686.12k    12826.62k    13640.01k
+sha1             1393.46k     6013.34k     9974.56k    11932.59k    12633.45k
+rc4             13833.46k    19275.29k    20321.24k    20281.93k    20520.08k
+des cbc          3382.50k     4104.02k     4152.78k     4194.30k     4194.30k
+des ede3         1465.51k     1533.00k     1549.96k     1553.29k     1570.29k
+idea cbc         2579.52k     3079.52k     3130.08k     3153.61k     3106.89k
+rc2 cbc          1204.57k     1276.42k     1285.81k     1289.76k     1285.81k
+blowfish cbc     5229.81k     6374.32k     6574.14k     6574.14k     6594.82k
+rsa  512 bits   0.008s   0.001
+rsa 1024 bits   0.038s   0.001
+rsa 2048 bits   0.231s   0.008
+rsa 4096 bits   1.540s   0.027
+dsa  512 bits   0.007s   0.013
+dsa 1024 bits   0.021s   0.040
+dsa 2048 bits   0.066s   0.130
+
diff --git a/openssl/times/L1 b/openssl/times/L1
new file mode 100644
index 0000000..09253d7
--- /dev/null
+++ b/openssl/times/L1
@@ -0,0 +1,27 @@
+SSLeay 0.8.3ad 27-Oct-1997
+built on Wed Oct 29 00:36:17 EST 1997
+options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) 
+C flags:gcc -DL_ENDIAN -DTERMIO -DBN_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized -DMD5_ASM -DSHA1_ASM
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                56.16k      156.50k      211.46k      231.77k      238.71k
+mdc2              183.37k      205.21k      205.57k      209.92k      207.53k
+md5              1003.65k     5605.56k    11628.54k    15887.70k    17522.69k
+hmac(md5)         411.24k     2803.46k     7616.94k    13475.84k    16864.60k
+sha1              542.66k     2843.50k     5320.53k     6833.49k     7389.18k
+rc4              3677.15k     4313.73k     4407.89k     4429.82k     4404.57k
+des cbc          1787.94k     2174.51k     2236.76k     2249.73k     2230.95k
+des ede3          719.46k      777.26k      784.81k      780.29k      783.70k
+idea cbc          619.56k      677.89k      684.12k      685.40k      685.40k
+rc2 cbc           537.51k      573.93k      578.47k      579.24k      578.90k
+blowfish cbc     3226.76k     4221.65k     4424.19k     4468.39k     4377.26k
+cast cbc         2866.13k     3165.35k     3263.15k     3287.04k     3233.11k
+                  sign    verify
+rsa  512 bits   0.0212s   0.0021s
+rsa 1024 bits   0.1072s   0.0064s
+rsa 2048 bits   0.6853s   0.0222s
+rsa 4096 bits   4.9300s   0.0848s
+                  sign    verify
+dsa  512 bits   0.0200s   0.0380s
+dsa 1024 bits   0.0600s   0.1180s
+dsa 2048 bits   0.2110s   0.4221s
diff --git a/openssl/times/R10000.t b/openssl/times/R10000.t
new file mode 100644
index 0000000..6b3874c
--- /dev/null
+++ b/openssl/times/R10000.t
@@ -0,0 +1,24 @@
+IRIX 6.2 - R10000 195mhz
+SLeay 0.6.5a 06-Dec-1996
+built on Tue Dec 24 03:51:45 EST 1996
+options:bn(32,32) md2(int) rc4(ptr,int) des(ptr,risc2,16,long) idea(int)
+C flags:cc -O2 -DTERMIOS -DB_ENDIAN
+The 'numbers' are in 1000s of bytes per second processed.
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2            156.34k      424.03k      571.88k      628.88k      646.01k
+md5           1885.02k     8181.72k    13440.53k    16020.60k    16947.54k
+sha           1587.12k     7022.05k    11951.24k    14440.12k    15462.74k
+sha1          1413.13k     6215.86k    10571.16k    12736.22k    13628.51k
+rc4          10556.28k    11974.08k    12077.10k    12111.38k    12103.20k
+des cfb       2977.71k     3252.27k     3284.36k     3302.66k     3290.54k
+des cbc       3298.31k     3704.96k     3771.30k     3730.73k     3778.80k
+des ede3      1278.28k     1328.82k     1342.66k     1339.82k     1343.27k
+idea cfb      2843.34k     3138.04k     3180.95k     3176.46k     3188.54k
+idea cbc      3115.21k     3558.03k     3590.61k     3591.24k     3601.18k
+rc2 cfb       2006.66k     2133.33k     2149.03k     2159.36k     2149.71k
+rc2 cbc       2167.07k     2315.30k     2338.05k     2329.34k     2333.90k
+rsa  512 bits   0.008s
+rsa 1024 bits   0.043s
+rsa 2048 bits   0.280s
+rsa 4096 bits   2.064s
+
diff --git a/openssl/times/R4400.t b/openssl/times/R4400.t
new file mode 100644
index 0000000..af8848f
--- /dev/null
+++ b/openssl/times/R4400.t
@@ -0,0 +1,26 @@
+IRIX 5.3
+R4400 200mhz
+cc -O2
+SSLeay 0.6.5a 06-Dec-1996
+built on Mon Dec 23 11:51:11 EST 1996
+options:bn(32,32) md2(int) rc4(ptr,int) des(ptr,risc2,16,long) idea(int)
+C flags:cc -O2 -DTERMIOS -DB_ENDIAN
+The 'numbers' are in 1000s of bytes per second processed.
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2            100.62k      280.25k      380.15k      416.02k      428.82k
+md5            828.62k     3525.05k     6311.98k     7742.51k     8328.04k
+sha            580.04k     2513.74k     4251.73k     5101.04k     5394.80k
+sha1           520.23k     2382.94k     4107.82k     5024.62k     5362.56k
+rc4           5871.53k     6323.08k     6357.49k     6392.04k     6305.45k
+des cfb       1016.76k     1156.72k     1176.59k     1180.55k     1181.65k
+des cbc       1016.38k     1303.81k     1349.10k     1359.41k     1356.62k
+des ede3       607.39k      650.74k      655.11k      657.52k      654.18k
+idea cfb      1296.10k     1348.66k     1353.80k     1358.75k     1355.40k
+idea cbc      1453.90k     1554.68k     1567.84k     1569.89k     1573.57k
+rc2 cfb       1199.86k     1251.69k     1253.57k     1259.56k     1251.31k
+rc2 cbc       1334.60k     1428.55k     1441.89k     1445.42k     1441.45k
+rsa  512 bits   0.024s
+rsa 1024 bits   0.125s
+rsa 2048 bits   0.806s
+rsa 4096 bits   5.800s
+
diff --git a/openssl/times/aix.t b/openssl/times/aix.t
new file mode 100644
index 0000000..4f24e39
--- /dev/null
+++ b/openssl/times/aix.t
@@ -0,0 +1,34 @@
+from Paco Garcia <pgarcia@ctv.es>
+This machine is a Bull Estrella  Minitower Model MT604-100
+Processor        : PPC604 
+P.Speed          : 100Mhz 
+Data/Instr Cache :    16 K
+L2 Cache         :   256 K
+PCI BUS Speed    :    33 Mhz
+TransfRate PCI   :   132 MB/s
+Memory           :    96 MB
+
+AIX 4.1.4
+
+SSLeay 0.6.6 14-Jan-1997
+built on Mon Jan 13 21:36:03 CUT 1997
+options:bn(64,32) md2(int) rc4(ptr,char) des(idx,cisc,4,long) idea(int) blowfish
+(idx)
+C flags:cc -O -DAIX -DB_ENDIAN
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                53.83k      147.46k      197.63k      215.72k     221.70k
+md5              1278.13k     5354.77k     8679.60k    10195.09k   10780.56k
+sha              1055.34k     4600.37k     7721.30k     9298.94k    9868.63k
+sha1              276.90k     1270.25k     2187.95k     2666.84k    2850.82k
+rc4              4660.57k     5268.93k     5332.48k     5362.47k    5346.65k
+des cbc          1774.16k     1981.10k     1979.56k     2032.71k    1972.25k
+des ede3          748.81k      781.42k      785.66k      785.75k     780.84k
+idea cbc         2066.19k     2329.58k     2378.91k     2379.86k    2380.89k
+rc2 cbc          1278.53k     1379.69k     1389.99k     1393.66k    1389.91k
+blowfish cbc     2812.91k     3307.90k     3364.91k     3386.37k    3374.32k
+rsa  512 bits   0.019s
+rsa 1024 bits   0.096s
+rsa 2048 bits   0.614s
+rsa 4096 bits   4.433s
+
diff --git a/openssl/times/aixold.t b/openssl/times/aixold.t
new file mode 100644
index 0000000..0b51412
--- /dev/null
+++ b/openssl/times/aixold.t
@@ -0,0 +1,23 @@
+SSLeay 0.7.3r 20-May-1997
+built on Mon Jun  2 04:06:32 EST 1997
+options:bn(64,32) md2(int) rc4(ptr,char) des(idx,cisc,4,long) idea(int) blowfish(idx)
+C flags:cc -O -DAIX -DB_ENDIAN
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                19.09k       52.47k       71.23k       77.49k       78.93k
+md5               214.56k      941.21k     1585.43k     1883.12k     1988.70k
+sha               118.35k      521.65k      860.28k     1042.27k     1100.46k
+sha1              109.52k      478.98k      825.90k      995.48k     1049.69k
+rc4              1263.63k     1494.24k     1545.70k     1521.66k     1518.99k
+des cbc           259.62k      286.55k      287.15k      288.15k      289.45k
+des ede3          104.92k      107.88k      109.27k      109.25k      109.96k
+idea cbc          291.63k      320.07k      319.40k      320.51k      318.27k
+rc2 cbc           220.04k      237.76k      241.44k      245.90k      244.08k
+blowfish cbc      407.95k      474.83k      480.99k      485.71k      481.07k
+rsa  512 bits   0.157s   0.019
+rsa 1024 bits   0.908s   0.023
+rsa 2048 bits   6.225s   0.218
+rsa 4096 bits  46.500s   0.830
+dsa  512 bits   0.159s   0.312
+dsa 1024 bits   0.536s   1.057
+dsa 2048 bits   1.970s   3.977
diff --git a/openssl/times/alpha.t b/openssl/times/alpha.t
new file mode 100644
index 0000000..3a7c6c4
--- /dev/null
+++ b/openssl/times/alpha.t
@@ -0,0 +1,81 @@
+SSLeay-051 Alpha gcc -O3 64Bit (assember bn_mul)
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2             44.40k      121.56k      162.73k      179.20k      185.01k
+md5            780.85k     3278.53k     5281.52k     6327.98k     6684.67k
+sha            501.40k     2249.19k     3855.27k     4801.19k     5160.96k
+sha-1          384.99k     1759.72k     3113.64k     3946.92k     4229.80k
+rc4           3505.05k     3724.54k     3723.78k     3555.33k     3694.68k
+des cfb        946.96k     1015.27k     1021.87k     1033.56k     1037.65k
+des cbc       1001.24k     1220.20k     1243.31k     1272.73k     1265.87k
+des ede3       445.34k      491.65k      500.53k      502.10k      502.44k
+idea cfb       643.53k      667.49k      663.81k      666.28k      664.51k
+idea cbc       650.42k      735.41k      733.27k      742.74k      745.47k
+rsa  512 bits   0.031s
+rsa 1024 bits   0.141s
+rsa 2048 bits   0.844s
+rsa 4096 bits   6.033s
+
+SSLeay-051 Alpha cc -O2 64bit (assember bn_mul)
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2             45.37k      122.86k      165.97k      182.95k      188.42k
+md5            842.42k     3629.93k     5916.76k     7039.17k     7364.61k
+sha            498.93k     2197.23k     3895.60k     4756.48k     5132.13k
+sha-1          382.02k     1757.21k     3112.53k     3865.23k     4128.77k
+rc4           2975.25k     3049.33k     3180.97k     3214.68k     3424.26k
+des cfb        901.55k      990.83k     1006.08k     1011.19k     1004.89k
+des cbc        947.84k     1127.84k     1163.67k     1162.24k     1157.80k
+des ede3       435.62k      485.57k      493.67k      491.52k      491.52k
+idea cfb       629.31k      648.66k      647.77k      648.53k      649.90k
+idea cbc       565.15k      608.00k      613.46k      613.38k      617.13k
+rsa  512 bits   0.030s
+rsa 1024 bits   0.141s
+rsa 2048 bits   0.854s
+rsa 4096 bits   6.067s
+
+des cfb        718.28k      822.64k      833.11k      836.27k      841.05k
+des cbc        806.10k      951.42k      975.83k      983.73k      991.23k
+des ede3       329.50k      379.11k      387.95k      387.41k      388.33k
+
+des cfb        871.62k      948.65k      951.81k      953.00k      955.58k
+des cbc        953.60k     1174.27k     1206.70k     1216.10k     1216.44k
+des ede3       349.34k      418.05k      427.26k      429.74k      431.45k
+
+
+
+
+SSLeay-045c Alpha gcc -O3 64Bit
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2             44.95k      122.22k      164.27k      180.62k      184.66k
+md5            808.71k     3371.95k     5415.68k     6385.66k     6684.67k
+sha            493.68k     2162.05k     3725.82k     4552.02k     4838.74k
+rc4           3317.32k     3649.09k     3728.30k     3744.09k     3691.86k
+cfb des        996.45k     1050.77k     1058.30k     1059.16k     1064.96k
+cbc des       1096.52k     1255.49k     1282.13k     1289.90k     1299.80k
+ede3 des       482.14k      513.51k      518.66k      520.19k      521.39k
+cfb idea       519.90k      533.40k      535.21k      535.55k      535.21k
+cbc idea       619.34k      682.21k      688.04k      689.15k      690.86k
+rsa  512 bits   0.050s
+rsa 1024 bits   0.279s
+rsa 2048 bits   1.908s
+rsa 4096 bits  14.750s
+
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2             37.31k      102.77k      137.64k      151.55k      155.78k
+md5            516.65k     2535.21k     4655.72k     5859.66k     6343.34k
+rc4           3519.61k     3707.01k     3746.86k     3755.39k     3675.48k
+cfb des        780.27k      894.68k      913.10k      921.26k      922.97k
+cbc des        867.54k     1040.13k     1074.17k     1075.54k     1084.07k
+ede3 des       357.19k      397.36k      398.08k      402.28k      401.41k
+cbc idea       646.53k      686.44k      694.03k      691.20k      693.59k
+rsa  512 bits   0.046s
+rsa 1024 bits   0.270s
+rsa 2048 bits   1.858s
+rsa 4096 bits  14.350s
+
+md2      C      37.83k      103.17k      137.90k      150.87k      155.37k
+md2      L      37.30k      102.04k      139.01k      152.74k      155.78k
+rc4       I   3532.24k     3718.08k     3750.83k     3768.78k     3694.59k
+rc4      CI   2662.97k     2873.26k     2907.22k     2920.63k     2886.31k
+rc4      LI   3514.63k     3738.72k     3747.41k     3752.96k     3708.49k
+cbc idea S     619.01k      658.68k      661.50k      662.53k      663.55k
+cbc idea  L    645.69k      684.22k      694.55k      692.57k      690.86k
diff --git a/openssl/times/alpha400.t b/openssl/times/alpha400.t
new file mode 100644
index 0000000..079e0d1
--- /dev/null
+++ b/openssl/times/alpha400.t
@@ -0,0 +1,25 @@
+Alpha EV5.6 (21164A) 400mhz
+
+SSLeay 0.7.3r 20-May-1997
+built on Mon Jun  2 03:39:58 EST 1997
+options:bn(64,64) md2(int) rc4(ptr,int) des(idx,cisc,4,long) idea(int) blowfish(idx)
+C flags:cc -arch host -tune host -fast -std -O4 -inline speed
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2               274.98k      760.96k     1034.27k     1124.69k     1148.69k
+md5              2524.46k    11602.60k    19838.81k    24075.26k    25745.10k
+sha              1848.46k     8335.66k    14232.49k    17247.91k    18530.30k
+sha1             1639.67k     7336.53k    12371.80k    14807.72k    15870.63k
+rc4             17950.93k    19390.66k    19652.44k    19700.39k    19412.31k
+des cbc          4018.59k     4872.06k     4988.76k     5003.26k     4995.73k
+des ede3         1809.11k     1965.67k     1984.26k     1986.90k     1982.46k
+idea cbc         2848.82k     3204.33k     3250.26k     3257.34k     3260.42k
+rc2 cbc          3766.08k     4349.50k     4432.21k     4448.94k     4448.26k
+blowfish cbc     6694.88k     9042.35k     9486.93k     9598.98k     9624.91k
+rsa  512 bits   0.003s   0.000
+rsa 1024 bits   0.013s   0.000
+rsa 2048 bits   0.081s   0.003
+rsa 4096 bits   0.577s   0.011
+dsa  512 bits   0.003s   0.005
+dsa 1024 bits   0.007s   0.014
+dsa 2048 bits   0.025s   0.050
diff --git a/openssl/times/cyrix100.lnx b/openssl/times/cyrix100.lnx
new file mode 100644
index 0000000..010a221
--- /dev/null
+++ b/openssl/times/cyrix100.lnx
@@ -0,0 +1,22 @@
+SSLeay 0.6.6 06-Dec-1996
+built on Fri Dec  6 10:05:20 GMT 1996
+options:bn(64,32) md2(char) rc4(idx,int) des(idx,risc,16,long) idea(int)
+C flags:gcc -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized
+The 'numbers' are in 1000s of bytes per second processed.
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2             36.77k      102.48k      138.00k      151.57k      155.78k
+md5            513.59k     2577.22k     4623.51k     5768.99k     6214.53k
+sha            259.89k     1105.45k     1814.97k     2156.16k     2292.13k
+sha1           242.43k     1040.95k     1719.44k     2049.74k     2164.64k
+rc4           1984.48k     2303.41k     2109.37k     2071.47k     1985.61k
+des cfb        712.08k      758.29k      753.17k      752.06k      748.67k
+des cbc        787.37k      937.64k      956.77k      961.61k      957.54k
+des ede3       353.97k      377.28k      379.99k      379.34k      379.11k
+idea cfb       403.80k      418.50k      416.60k      415.78k      415.03k
+idea cbc       426.54k      466.40k      471.31k      472.67k      473.14k
+rc2 cfb        405.15k      420.05k      418.16k      416.72k      416.36k
+rc2 cbc        428.21k      468.43k      473.09k      472.59k      474.70k
+rsa  512 bits   0.040s
+rsa 1024 bits   0.195s
+rsa 2048 bits   1.201s
+rsa 4096 bits   8.700s
diff --git a/openssl/times/dgux-x86.t b/openssl/times/dgux-x86.t
new file mode 100644
index 0000000..70635c5
--- /dev/null
+++ b/openssl/times/dgux-x86.t
@@ -0,0 +1,23 @@
+version:SSLeay 0.5.2c 15-May-1996
+built Fri Jun 14 19:47:04 EST 1996
+options:bn(LLONG,thirty_two) md2(CHAR) rc4(IDX,int) des(ary,long) idea(int)
+C flags:gcc -O3 -fomit-frame-pointer -DL_ENDIAN
+
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2            113.86k      316.48k      428.36k      467.63k      481.56k
+md5           1001.99k     5037.99k     9545.94k    12036.95k    11800.38k
+sha            628.77k     2743.48k     5113.42k     6206.99k     6165.42k
+sha1           583.83k     2638.66k     4538.85k     5532.09k     5917.04k
+rc4           5493.27k     6369.39k     6511.30k     6577.83k     6486.73k
+des cfb       1219.01k     1286.06k     1299.33k     1288.87k     1381.72k
+des cbc       1360.58k     1469.04k     1456.96k     1454.08k     1513.57k
+des ede3       544.45k      567.84k      568.99k      570.37k      566.09k
+idea cfb      1012.39k     1056.30k     1063.52k      989.17k      863.24k
+idea cbc       985.36k     1090.44k     1105.92k     1108.65k     1090.17k
+rc2 cfb        963.86k      979.06k      995.30k      937.35k      827.39k
+rc2 cbc        951.72k     1042.11k     1049.60k     1047.21k     1059.11k
+rsa  512 bits   0.032s
+rsa 1024 bits   0.159s
+rsa 2048 bits   1.025s
+rsa 4096 bits   7.270s
+
diff --git a/openssl/times/dgux.t b/openssl/times/dgux.t
new file mode 100644
index 0000000..c7f7564
--- /dev/null
+++ b/openssl/times/dgux.t
@@ -0,0 +1,17 @@
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2             38.54k      106.28k      144.00k      157.46k      161.72k
+md5            323.23k     1471.62k     2546.11k     3100.20k     3309.57k
+rc4        I  1902.74k     2055.20k     2080.42k     2077.88k     2065.46k
+cfb des        456.23k      475.22k      481.79k      488.42k      487.17k
+cbc des        484.30k      537.50k      553.09k      558.08k      558.67k
+ede3 des       199.97k      209.05k      211.03k      211.85k      212.78k
+cbc idea       478.50k      519.33k      523.42k      525.09k      526.44k
+rsa  512 bits   0.159s !RSA_LLONG
+rsa 1024 bits   1.053s
+rsa 2048 bits   7.600s
+rsa 4096 bits  59.760s
+
+md2       C     30.53k       83.58k      112.84k      123.22k      126.24k
+rc4           1844.56k     1975.50k     1997.73k     1994.95k     1984.88k
+rc4       C   1800.09k     1968.85k     1995.20k     1992.36k     1996.80k
+rc4       CI  1830.81k     2035.75k     2067.28k     2070.23k     2062.77k
diff --git a/openssl/times/hpux-acc.t b/openssl/times/hpux-acc.t
new file mode 100644
index 0000000..0c0e936
--- /dev/null
+++ b/openssl/times/hpux-acc.t
@@ -0,0 +1,25 @@
+HPUX 887
+
+SSLeay 0.7.3r 20-May-1997
+built on Mon Jun  2 02:59:45 EST 1997
+options:bn(32,32) md2(int) rc4(ptr,int) des(ptr,risc1,16,long) idea(int) blowfish(idx)
+C flags:cc -DB_ENDIAN -D_HPUX_SOURCE -Aa -Ae +ESlit +O4 -Wl,-a,archive
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                58.99k      166.85k      225.07k      247.21k      253.76k
+md5               639.22k     2726.98k     4477.25k     5312.69k     5605.20k
+sha               381.08k     1661.49k     2793.84k     3368.86k     3581.23k
+sha1              349.54k     1514.56k     2536.63k     3042.59k     3224.39k
+rc4              2891.10k     4238.01k     4464.11k     4532.49k     4545.87k
+des cbc           717.05k      808.76k      820.14k      821.97k      821.96k
+des ede3          288.21k      303.50k      303.69k      305.82k      305.14k
+idea cbc          325.83k      334.36k      335.89k      336.61k      333.43k
+rc2 cbc           793.00k      915.81k      926.69k      933.28k      929.53k
+blowfish cbc     1561.91k     2051.97k     2122.65k     2139.40k     2145.92k
+rsa  512 bits   0.031s   0.004
+rsa 1024 bits   0.164s   0.004
+rsa 2048 bits   1.055s   0.037
+rsa 4096 bits   7.600s   0.137
+dsa  512 bits   0.029s   0.057
+dsa 1024 bits   0.092s   0.177
+dsa 2048 bits   0.325s   0.646
diff --git a/openssl/times/hpux-kr.t b/openssl/times/hpux-kr.t
new file mode 100644
index 0000000..ad4a0ad
--- /dev/null
+++ b/openssl/times/hpux-kr.t
@@ -0,0 +1,23 @@
+SSLeay 0.7.3r 20-May-1997
+built on Mon Jun  2 02:17:35 EST 1997
+options:bn(32,32) md2(int) rc4(ptr,int) des(ptr,cisc,16,long) idea(int) blowfish(idx)
+C flags:cc -DB_ENDIAN -DNOCONST -DNOPROTO -D_HPUX_SOURCE
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                35.30k       98.36k      133.41k      146.34k      150.69k
+md5               391.20k     1737.31k     2796.65k     3313.75k     3503.74k
+sha               189.55k      848.14k     1436.72k     1735.87k     1848.03k
+sha1              175.30k      781.14k     1310.32k     1575.61k     1675.81k
+rc4              2070.55k     2501.47k     2556.65k     2578.34k     2584.91k
+des cbc           465.13k      536.85k      545.87k      547.86k      548.89k
+des ede3          190.05k      200.99k      202.31k      202.22k      202.75k
+idea cbc          263.44k      277.77k      282.13k      281.51k      283.15k
+rc2 cbc           448.37k      511.39k      519.54k      522.00k      521.31k
+blowfish cbc      839.98k     1097.70k     1131.16k     1145.64k     1144.67k
+rsa  512 bits   0.048s   0.005
+rsa 1024 bits   0.222s   0.006
+rsa 2048 bits   1.272s   0.042
+rsa 4096 bits   8.445s   0.149
+dsa  512 bits   0.041s   0.077
+dsa 1024 bits   0.111s   0.220
+dsa 2048 bits   0.363s   0.726
diff --git a/openssl/times/hpux.t b/openssl/times/hpux.t
new file mode 100644
index 0000000..dcf7615
--- /dev/null
+++ b/openssl/times/hpux.t
@@ -0,0 +1,86 @@
+HP-UX A.09.05 9000/712
+
+SSLeay 0.6.6 14-Jan-1997
+built on Tue Jan 14 16:36:31 WET 1997
+options:bn(32,32) md2(int) rc4(ptr,int) des(ptr,risc1,16,long) idea(int) 
+blowfish(idx)
+C flags:cc -DB_ENDIAN -D_HPUX_SOURCE -Aa +ESlit +O2 -Wl,-a,archive
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                66.56k      184.92k      251.82k      259.86k      282.62k
+md5               615.54k     2805.92k     4764.30k     5724.21k     6084.39k
+sha               358.23k     1616.46k     2781.50k     3325.72k     3640.89k
+sha1              327.50k     1497.98k     2619.44k     3220.26k     3460.85k
+rc4              3500.47k     3890.99k     3943.81k     3883.74k     3900.02k
+des cbc           742.65k      871.66k      887.15k      891.21k      895.40k
+des ede3          302.42k      322.50k      324.46k      326.66k      326.05k
+idea cbc          664.41k      755.87k      765.61k      772.70k      773.69k
+rc2 cbc           798.78k      931.04k      947.69k      950.31k      952.04k
+blowfish cbc     1353.32k     1932.29k     2021.93k     2047.02k     2053.66k
+rsa  512 bits   0.059s
+rsa 1024 bits   0.372s
+rsa 2048 bits   2.697s
+rsa 4096 bits  20.790s
+
+SSLeay 0.6.6 14-Jan-1997
+built on Tue Jan 14 15:37:30 WET 1997
+options:bn(64,32) md2(int) rc4(ptr,int) des(ptr,risc1,16,long) idea(int) 
+blowfish(idx)
+C flags:gcc -DB_ENDIAN -O3
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                44.91k      122.57k      167.71k      183.89k      190.24k
+md5               532.50k     2316.27k     3965.72k     4740.11k     5055.06k
+sha               363.76k     1684.09k     2978.53k     3730.86k     3972.72k
+sha1              385.76k     1743.53k     2997.69k     3650.74k     3899.08k
+rc4              3178.84k     3621.31k     3672.71k     3684.01k     3571.54k
+des cbc           733.00k      844.70k      863.28k      863.72k      868.73k
+des ede3          289.99k      308.94k      310.11k      309.64k      312.08k
+idea cbc          624.07k      713.91k      724.76k      723.35k      725.13k
+rc2 cbc           704.34k      793.39k      804.25k      805.99k      782.63k
+blowfish cbc     1371.24k     1823.66k     1890.05k     1915.51k     1920.12k
+rsa  512 bits   0.030s
+rsa 1024 bits   0.156s
+rsa 2048 bits   1.113s
+rsa 4096 bits   7.480s
+
+
+HPUX B.10.01 V 9000/887 - HP92453-01 A.10.11 HP C Compiler
+SSLeay 0.5.2 - -Aa +ESlit +Oall +O4 -Wl,-a,archive
+
+HPUX A.09.04 B 9000/887
+
+ssleay 0.5.1 gcc v 2.7.0 -O3 -mpa-risc-1-1
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2             53.00k      166.81k      205.66k      241.95k      242.20k
+md5            743.22k     3128.44k     6031.85k     6142.07k     7025.26k
+sha            481.30k     2008.24k     3361.31k     3985.07k     4180.74k
+sha-1          463.60k     1916.15k     3139.24k     3786.27k     3997.70k
+rc4           3708.61k     4125.16k     4547.53k     4206.21k     4390.07k
+des cfb        665.91k      705.97k      698.48k      694.25k      666.08k
+des cbc        679.80k      741.90k      769.85k      747.62k      719.47k
+des ede3       264.31k      270.22k      265.63k      273.07k      273.07k
+idea cfb       635.91k      673.40k      605.60k      699.53k      672.36k
+idea cbc       705.85k      774.63k      750.60k      715.83k      721.50k
+rsa  512 bits   0.066s
+rsa 1024 bits   0.372s
+rsa 2048 bits   2.177s
+rsa 4096 bits  16.230s
+
+HP92453-01 A.09.61 HP C Compiler
+ssleay 0.5.1 cc -Ae +ESlit +Oall -Wl,-a,archive
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2             58.69k      163.30k      213.57k      230.40k      254.23k
+md5            608.60k     2596.82k     3871.43k     4684.10k     4763.88k
+sha            343.26k     1482.43k     2316.80k     2766.27k     2860.26k
+sha-1          319.15k     1324.13k     2106.03k     2527.82k     2747.95k
+rc4           2467.47k     3374.41k     3265.49k     3354.39k     3368.55k
+des cfb        812.05k      814.90k      851.20k      819.20k      854.56k
+des cbc        836.35k      994.06k      916.02k     1020.01k      988.14k
+des ede3       369.78k      389.15k      401.01k      382.94k      408.03k
+idea cfb       290.40k      298.06k      286.11k      296.92k      299.46k
+idea cbc       301.30k      297.72k      304.34k      300.10k      309.70k
+rsa  512 bits   0.350s
+rsa 1024 bits   2.635s
+rsa 2048 bits  19.930s
+
diff --git a/openssl/times/p2.w95 b/openssl/times/p2.w95
new file mode 100644
index 0000000..82d1e55
--- /dev/null
+++ b/openssl/times/p2.w95
@@ -0,0 +1,22 @@
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2               235.90k      652.30k      893.36k      985.74k      985.74k
+mdc2              779.61k      816.81k      825.65k      816.01k      825.65k
+md5              2788.77k    13508.23k    24672.38k    30504.03k    33156.55k
+sha              1938.22k     8397.01k    14122.24k    16980.99k    18196.55k
+sha1             1817.29k     7832.50k    13168.93k    15738.48k    16810.84k
+rc4             15887.52k    21709.65k    22745.68k    22995.09k    22995.09k
+des cbc          4599.02k     5377.31k     5377.31k     5533.38k     5533.38k
+des ede3         1899.59k     2086.71k     2086.67k     2086.51k     2085.90k
+idea cbc         3350.08k     3934.62k     3979.42k     4017.53k     4017.53k
+rc2 cbc          1534.13k     1630.76k     1625.70k     1644.83k     1653.91k
+blowfish cbc     6678.83k     8490.49k     8701.88k     8848.74k     8886.24k
+                  sign    verify
+rsa  512 bits   0.0062s   0.0008s
+rsa 1024 bits   0.0287s   0.0009s
+rsa 2048 bits   0.1785s   0.0059s
+rsa 4096 bits   1.1300s   0.0205s
+                  sign    verify
+dsa  512 bits   0.0055s   0.0100s
+dsa 1024 bits   0.0154s   0.0299s
+dsa 2048 bits   0.0502s   0.0996s
diff --git a/openssl/times/pent2.t b/openssl/times/pent2.t
new file mode 100644
index 0000000..b6dc269
--- /dev/null
+++ b/openssl/times/pent2.t
@@ -0,0 +1,24 @@
+pentium 2, 266mhz, Visual C++ 5.0, Windows 95
+
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2               235.90k      652.30k      893.36k      985.74k      985.74k
+mdc2              779.61k      816.81k      825.65k      816.01k      825.65k
+md5              2788.77k    13508.23k    24672.38k    30504.03k    33156.55k
+sha              1938.22k     8397.01k    14122.24k    16980.99k    18196.55k
+sha1             1817.29k     7832.50k    13168.93k    15738.48k    16810.84k
+rc4             15887.52k    21709.65k    22745.68k    22995.09k    22995.09k
+des cbc          4599.02k     5377.31k     5377.31k     5533.38k     5533.38k
+des ede3         1899.59k     2086.71k     2086.67k     2086.51k     2085.90k
+idea cbc         3350.08k     3934.62k     3979.42k     4017.53k     4017.53k
+rc2 cbc          1534.13k     1630.76k     1625.70k     1644.83k     1653.91k
+blowfish cbc     6678.83k     8490.49k     8701.88k     8848.74k     8886.24k
+                  sign    verify
+rsa  512 bits   0.0062s   0.0008s
+rsa 1024 bits   0.0287s   0.0009s
+rsa 2048 bits   0.1785s   0.0059s
+rsa 4096 bits   1.1300s   0.0205s
+                  sign    verify
+dsa  512 bits   0.0055s   0.0100s
+dsa 1024 bits   0.0154s   0.0299s
+dsa 2048 bits   0.0502s   0.0996s
diff --git a/openssl/times/readme b/openssl/times/readme
new file mode 100644
index 0000000..7074f58
--- /dev/null
+++ b/openssl/times/readme
@@ -0,0 +1,11 @@
+The 'times' in this directory are not all for the most recent version of
+the library and it should be noted that on some CPUs (specifically sparc
+and Alpha), the locations of files in the application after linking can
+make upto a %10 speed difference when running benchmarks on things like
+cbc mode DES.  To put it mildly this can be very anoying.
+
+About the only way to get around this would be to compile the library as one
+object file, or to 'include' the source files in a specific order.
+
+The best way to get an idea of the 'raw' DES speed is to build the 
+'speed' program in crypto/des.
diff --git a/openssl/times/s586-100.lnx b/openssl/times/s586-100.lnx
new file mode 100644
index 0000000..cbc3e3c
--- /dev/null
+++ b/openssl/times/s586-100.lnx
@@ -0,0 +1,25 @@
+Shared library build
+
+SSLeay 0.7.3 30-Apr-1997
+built on Tue May 13 03:43:56 EST 1997
+options:bn(64,32) md2(char) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2)
+C flags:-DTERMIO -O3 -DL_ENDIAN -fomit-frame-pointer -m486 -Wall
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                68.95k      191.40k      258.22k      283.31k      291.21k
+md5               627.37k     3064.75k     5370.15k     6765.91k     7255.38k
+sha               323.35k     1431.32k     2417.07k     2916.69k     3102.04k
+sha1              298.08k     1318.34k     2228.82k     2694.83k     2864.47k
+rc4              3404.13k     4026.33k     4107.43k     4136.28k     4117.85k
+des cbc          1414.60k     1782.53k     1824.24k     1847.64k     1840.47k
+des ede3          588.36k      688.19k      700.33k      702.46k      704.51k
+idea cbc          582.96k      636.71k      641.54k      642.39k      642.30k
+rc2 cbc           569.34k      612.37k      617.64k      617.47k      619.86k
+blowfish cbc     2015.77k     2534.49k     2609.65k     2607.10k     2615.98k
+rsa  512 bits   0.027s   0.003
+rsa 1024 bits   0.128s   0.003
+rsa 2048 bits   0.779s   0.027
+rsa 4096 bits   5.450s   0.098
+dsa  512 bits   0.024s   0.045
+dsa 1024 bits   0.068s   0.132
+dsa 2048 bits   0.231s   0.469
diff --git a/openssl/times/s586-100.nt b/openssl/times/s586-100.nt
new file mode 100644
index 0000000..8e3baf6
--- /dev/null
+++ b/openssl/times/s586-100.nt
@@ -0,0 +1,23 @@
+SSLeay 0.7.3 30-Apr-1997
+built on Mon May 19 10:47:38 EST 1997
+options:bn(64,32) md2(char) rc4(idx,int) des(idx,cisc,4,long) idea(int) blowfish(ptr2)
+C flags not available
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                90.26k      248.57k      335.06k      366.09k      376.64k
+md5               863.95k     4205.24k     7628.78k     9582.60k    10290.25k
+sha               463.93k     2102.51k     3623.28k     4417.85k     4695.29k
+sha1              458.23k     2005.88k     3385.78k     4094.00k     4340.13k
+rc4              5843.60k     7543.71k     7790.31k     7836.89k     7791.47k
+des cbc          1583.95k     1910.67k     1960.69k     1972.12k     1946.13k
+des ede3          654.79k      722.60k      740.97k      745.82k      738.27k
+idea cbc          792.04k      876.96k      887.35k      892.63k      890.36k
+rc2 cbc           603.50k      652.38k      661.85k      662.69k      661.44k
+blowfish cbc     2379.88k     3043.76k     3153.61k     3153.61k     3134.76k
+rsa  512 bits   0.022s   0.003
+rsa 1024 bits   0.111s   0.003
+rsa 2048 bits   0.716s   0.025
+rsa 4096 bits   5.188s   0.094
+dsa  512 bits   0.020s   0.039
+dsa 1024 bits   0.062s   0.124
+dsa 2048 bits   0.221s   0.441
diff --git a/openssl/times/sgi.t b/openssl/times/sgi.t
new file mode 100644
index 0000000..7963610
--- /dev/null
+++ b/openssl/times/sgi.t
@@ -0,0 +1,29 @@
+SGI Challenge R4400 200mhz IRIX 5.3 - gcc (2.6.3)
+SSLeay 0.6.1 02-Jul-1996
+built on Tue Jul  2 16:25:30 EST 1996
+options:bn(64,32) md2(char) rc4(idx,char) des(idx,long) idea(int)
+C flags:gcc -O2 -mips2 -DTERMIOS -DB_ENDIAN
+The 'numbers' are in 1000s of bytes per second processed.
+type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2             96.53k      266.70k      360.09k      393.70k      405.07k
+md5            971.15k     4382.56k     7406.90k     8979.99k     9559.18k
+sha            596.86k     2832.26k     4997.30k     6277.75k     6712.89k
+sha1           578.34k     2630.16k     4632.05k     5684.34k     6083.37k
+rc4           5641.12k     6821.76k     6996.13k     7052.61k     6913.32k
+des cfb       1354.86k     1422.11k     1434.58k     1433.24k     1432.89k
+des cbc       1467.13k     1618.92k     1630.08k     1637.00k     1629.62k
+des ede3       566.13k      591.91k      596.86k      596.18k      592.54k
+idea cfb      1190.60k     1264.49k     1270.38k     1267.84k     1272.37k
+idea cbc      1271.45k     1410.37k     1422.49k     1426.46k     1421.73k
+rc2 cfb       1285.73k     1371.40k     1380.92k     1383.13k     1379.23k
+rc2 cbc       1386.61k     1542.10k     1562.49k     1572.45k     1567.93k
+rsa  512 bits   0.018s
+rsa 1024 bits   0.106s
+rsa 2048 bits   0.738s
+rsa 4096 bits   5.535s
+
+version:SSLeay 0.5.2c 15-May-1996
+rsa  512 bits   0.035s
+rsa 1024 bits   0.204s
+rsa 2048 bits   1.423s
+rsa 4096 bits  10.800s
diff --git a/openssl/times/sparc.t b/openssl/times/sparc.t
new file mode 100644
index 0000000..1611f76
--- /dev/null
+++ b/openssl/times/sparc.t
@@ -0,0 +1,26 @@
+gcc 2.7.2
+Sparc 10 - Solaris 2.3 - 50mhz
+SSLeay 0.7.3r 20-May-1997
+built on Mon Jun  2 00:55:51 EST 1997
+options:bn(64,32) md2(int) rc4(ptr,char) des(idx,cisc,16,long) idea(int) blowfish(ptr)
+C flags:gcc -O3 -fomit-frame-pointer -mv8 -Wall
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                54.88k      154.52k      210.35k      231.08k      237.21k
+md5               550.75k     2460.49k     4116.01k     4988.74k     5159.86k
+sha               340.28k     1461.76k     2430.10k     2879.87k     2999.15k
+sha1              307.27k     1298.41k     2136.26k     2540.07k     2658.28k
+rc4              2652.21k     2805.24k     3301.63k     4003.98k     4071.18k
+des cbc           811.78k      903.93k      914.19k      921.60k      932.29k
+des ede3          328.21k      344.93k      349.64k      351.48k      345.07k
+idea cbc          685.06k      727.42k      734.41k      730.11k      739.21k
+rc2 cbc           718.59k      777.02k      781.96k      784.38k      782.60k
+blowfish cbc     1268.85k     1520.64k     1568.88k     1587.54k     1591.98k
+rsa  512 bits   0.037s   0.005
+rsa 1024 bits   0.213s   0.006
+rsa 2048 bits   1.471s   0.053
+rsa 4096 bits  11.100s   0.202
+dsa  512 bits   0.038s   0.074
+dsa 1024 bits   0.128s   0.248
+dsa 2048 bits   0.473s   0.959
+
diff --git a/openssl/times/sparc2 b/openssl/times/sparc2
new file mode 100644
index 0000000..4b0dd80
--- /dev/null
+++ b/openssl/times/sparc2
@@ -0,0 +1,21 @@
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                14.56k       40.25k       54.95k       60.13k       62.18k
+mdc2               53.59k       57.45k       58.11k       58.21k       58.51k
+md5               176.95k      764.75k     1270.36k     1520.14k     1608.36k
+hmac(md5)          55.88k      369.70k      881.15k     1337.05k     1567.40k
+sha1               92.69k      419.75k      723.63k      878.82k      939.35k
+rc4              1247.28k     1414.09k     1434.30k     1434.34k     1441.13k
+des cbc           284.41k      318.58k      323.07k      324.09k      323.87k
+des ede3          109.99k      119.99k      121.60k      121.87k      121.66k
+idea cbc           43.06k       43.68k       43.84k       43.64k       44.07k
+rc2 cbc           278.85k      311.44k      316.50k      316.57k      317.37k
+blowfish cbc      468.89k      569.35k      581.61k      568.34k      559.54k
+cast cbc          285.84k      338.79k      345.71k      346.19k      341.09k
+                  sign    verify
+rsa  512 bits   0.4175s   0.0519s
+rsa 1024 bits   2.9325s   0.1948s
+rsa 2048 bits  22.3600s   0.7669s
+		  sign    verify
+dsa  512 bits   0.5178s   1.0300s
+dsa 1024 bits   1.8780s   3.7167s
+dsa 2048 bits   7.3500s  14.4800s
diff --git a/openssl/times/sparcLX.t b/openssl/times/sparcLX.t
new file mode 100644
index 0000000..2fdaed7
--- /dev/null
+++ b/openssl/times/sparcLX.t
@@ -0,0 +1,22 @@
+Sparc Station LX
+SSLeay 0.7.3 30-Apr-1997
+built on Thu May  1 10:44:02 EST 1997
+options:bn(64,32) md2(int) rc4(ptr,char) des(idx,cisc,16,long) idea(int) blowfish(ptr)
+C flags:gcc -O3 -fomit-frame-pointer -mv8 -Wall
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2                17.60k       48.72k       66.47k       72.70k       74.72k
+md5               226.24k     1082.21k     1982.72k     2594.02k     2717.01k
+sha                71.38k      320.71k      551.08k      677.76k      720.90k
+sha1               63.08k      280.79k      473.86k      576.94k      608.94k
+rc4              1138.30k     1257.67k     1304.49k     1377.78k     1364.42k
+des cbc           265.34k      308.85k      314.28k      315.39k      317.20k
+des ede3           83.23k       93.13k       94.04k       94.50k       94.63k
+idea cbc          254.48k      274.26k      275.88k      274.68k      275.80k
+rc2 cbc           328.27k      375.39k      381.43k      381.61k      380.83k
+blowfish cbc      487.00k      498.02k      510.12k      515.41k      516.10k
+rsa  512 bits   0.093s
+rsa 1024 bits   0.537s
+rsa 2048 bits   3.823s
+rsa 4096 bits  28.650s
+
diff --git a/openssl/times/usparc.t b/openssl/times/usparc.t
new file mode 100644
index 0000000..2215624
--- /dev/null
+++ b/openssl/times/usparc.t
@@ -0,0 +1,25 @@
+Sparc 2000? - Solaris 2.5.1 - 167mhz Ultra sparc
+
+SSLeay 0.7.3r 20-May-1997
+built on Mon Jun  2 02:25:48 EST 1997
+options:bn(64,32) md2(int) rc4(ptr,char) des(ptr,risc1,16,long) idea(int) blowfish(ptr)
+C flags:cc cc -xtarget=ultra -xarch=v8plus -Xa -xO5 -Xa -DB_ENDIAN
+The 'numbers' are in 1000s of bytes per second processed.
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+md2               135.23k      389.87k      536.66k      591.87k      603.48k
+md5              1534.38k     6160.41k     9842.69k    11446.95k    11993.09k
+sha              1178.30k     5020.74k     8532.22k    10275.50k    11010.05k
+sha1             1114.22k     4703.94k     7703.81k     9236.14k     9756.67k
+rc4             10818.03k    13327.57k    13711.10k    13810.69k    13836.29k
+des cbc          3052.44k     3320.02k     3356.25k     3369.98k     3295.91k
+des ede3         1310.32k     1359.98k     1367.47k     1362.94k     1362.60k
+idea cbc         1749.52k     1833.13k     1844.74k     1848.32k     1848.66k
+rc2 cbc          1950.25k     2053.23k     2064.21k     2072.58k     2072.58k
+blowfish cbc     4927.16k     5659.75k     5762.73k     5797.55k     5805.40k
+rsa  512 bits   0.021s   0.003
+rsa 1024 bits   0.126s   0.003
+rsa 2048 bits   0.888s   0.032
+rsa 4096 bits   6.770s   0.122
+dsa  512 bits   0.022s   0.043
+dsa 1024 bits   0.076s   0.151
+dsa 2048 bits   0.286s   0.574
diff --git a/openssl/times/x86/bfs.cpp b/openssl/times/x86/bfs.cpp
new file mode 100644
index 0000000..d74c457
--- /dev/null
+++ b/openssl/times/x86/bfs.cpp
@@ -0,0 +1,67 @@
+//
+// gettsc.inl
+//
+// gives access to the Pentium's (secret) cycle counter
+//
+// This software was written by Leonard Janke (janke@unixg.ubc.ca)
+// in 1996-7 and is entered, by him, into the public domain.
+
+#if defined(__WATCOMC__)
+void GetTSC(unsigned long&);
+#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
+#elif defined(__GNUC__)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  asm volatile(".byte 15, 49\n\t"
+	       : "=eax" (tsc)
+	       :
+	       : "%edx", "%eax");
+}
+#elif defined(_MSC_VER)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  unsigned long a;
+  __asm _emit 0fh
+  __asm _emit 31h
+  __asm mov a, eax;
+  tsc=a;
+}
+#endif      
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/blowfish.h>
+
+void main(int argc,char *argv[])
+	{
+	BF_KEY key;
+	unsigned long s1,s2,e1,e2;
+	unsigned long data[2];
+	int i,j;
+
+	for (j=0; j<6; j++)
+		{
+		for (i=0; i<1000; i++) /**/
+			{
+			BF_encrypt(&data[0],&key);
+			GetTSC(s1);
+			BF_encrypt(&data[0],&key);
+			BF_encrypt(&data[0],&key);
+			BF_encrypt(&data[0],&key);
+			GetTSC(e1);
+			GetTSC(s2);
+			BF_encrypt(&data[0],&key);
+			BF_encrypt(&data[0],&key);
+			BF_encrypt(&data[0],&key);
+			BF_encrypt(&data[0],&key);
+			GetTSC(e2);
+			BF_encrypt(&data[0],&key);
+			}
+
+		printf("blowfish %d %d (%d)\n",
+			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
+		}
+	}
+
diff --git a/openssl/times/x86/casts.cpp b/openssl/times/x86/casts.cpp
new file mode 100644
index 0000000..7661191
--- /dev/null
+++ b/openssl/times/x86/casts.cpp
@@ -0,0 +1,67 @@
+//
+// gettsc.inl
+//
+// gives access to the Pentium's (secret) cycle counter
+//
+// This software was written by Leonard Janke (janke@unixg.ubc.ca)
+// in 1996-7 and is entered, by him, into the public domain.
+
+#if defined(__WATCOMC__)
+void GetTSC(unsigned long&);
+#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
+#elif defined(__GNUC__)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  asm volatile(".byte 15, 49\n\t"
+	       : "=eax" (tsc)
+	       :
+	       : "%edx", "%eax");
+}
+#elif defined(_MSC_VER)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  unsigned long a;
+  __asm _emit 0fh
+  __asm _emit 31h
+  __asm mov a, eax;
+  tsc=a;
+}
+#endif      
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/cast.h>
+
+void main(int argc,char *argv[])
+	{
+	CAST_KEY key;
+	unsigned long s1,s2,e1,e2;
+	unsigned long data[2];
+	int i,j;
+
+	for (j=0; j<6; j++)
+		{
+		for (i=0; i<1000; i++) /**/
+			{
+			CAST_encrypt(&data[0],&key);
+			GetTSC(s1);
+			CAST_encrypt(&data[0],&key);
+			CAST_encrypt(&data[0],&key);
+			CAST_encrypt(&data[0],&key);
+			GetTSC(e1);
+			GetTSC(s2);
+			CAST_encrypt(&data[0],&key);
+			CAST_encrypt(&data[0],&key);
+			CAST_encrypt(&data[0],&key);
+			CAST_encrypt(&data[0],&key);
+			GetTSC(e2);
+			CAST_encrypt(&data[0],&key);
+			}
+
+		printf("cast %d %d (%d)\n",
+			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
+		}
+	}
+
diff --git a/openssl/times/x86/des3s.cpp b/openssl/times/x86/des3s.cpp
new file mode 100644
index 0000000..cd2b112
--- /dev/null
+++ b/openssl/times/x86/des3s.cpp
@@ -0,0 +1,67 @@
+//
+// gettsc.inl
+//
+// gives access to the Pentium's (secret) cycle counter
+//
+// This software was written by Leonard Janke (janke@unixg.ubc.ca)
+// in 1996-7 and is entered, by him, into the public domain.
+
+#if defined(__WATCOMC__)
+void GetTSC(unsigned long&);
+#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
+#elif defined(__GNUC__)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  asm volatile(".byte 15, 49\n\t"
+	       : "=eax" (tsc)
+	       :
+	       : "%edx", "%eax");
+}
+#elif defined(_MSC_VER)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  unsigned long a;
+  __asm _emit 0fh
+  __asm _emit 31h
+  __asm mov a, eax;
+  tsc=a;
+}
+#endif      
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/des.h>
+
+void main(int argc,char *argv[])
+	{
+	des_key_schedule key1,key2,key3;
+	unsigned long s1,s2,e1,e2;
+	unsigned long data[2];
+	int i,j;
+
+	for (j=0; j<6; j++)
+		{
+		for (i=0; i<1000; i++) /**/
+			{
+			des_encrypt3(&data[0],key1,key2,key3);
+			GetTSC(s1);
+			des_encrypt3(&data[0],key1,key2,key3);
+			des_encrypt3(&data[0],key1,key2,key3);
+			des_encrypt3(&data[0],key1,key2,key3);
+			GetTSC(e1);
+			GetTSC(s2);
+			des_encrypt3(&data[0],key1,key2,key3);
+			des_encrypt3(&data[0],key1,key2,key3);
+			des_encrypt3(&data[0],key1,key2,key3);
+			des_encrypt3(&data[0],key1,key2,key3);
+			GetTSC(e2);
+			des_encrypt3(&data[0],key1,key2,key3);
+			}
+
+		printf("des3 %d %d (%d)\n",
+			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
+		}
+	}
+
diff --git a/openssl/times/x86/dess.cpp b/openssl/times/x86/dess.cpp
new file mode 100644
index 0000000..753e67a
--- /dev/null
+++ b/openssl/times/x86/dess.cpp
@@ -0,0 +1,67 @@
+//
+// gettsc.inl
+//
+// gives access to the Pentium's (secret) cycle counter
+//
+// This software was written by Leonard Janke (janke@unixg.ubc.ca)
+// in 1996-7 and is entered, by him, into the public domain.
+
+#if defined(__WATCOMC__)
+void GetTSC(unsigned long&);
+#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
+#elif defined(__GNUC__)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  asm volatile(".byte 15, 49\n\t"
+	       : "=eax" (tsc)
+	       :
+	       : "%edx", "%eax");
+}
+#elif defined(_MSC_VER)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  unsigned long a;
+  __asm _emit 0fh
+  __asm _emit 31h
+  __asm mov a, eax;
+  tsc=a;
+}
+#endif      
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/des.h>
+
+void main(int argc,char *argv[])
+	{
+	des_key_schedule key;
+	unsigned long s1,s2,e1,e2;
+	unsigned long data[2];
+	int i,j;
+
+	for (j=0; j<6; j++)
+		{
+		for (i=0; i<1000; i++) /**/
+			{
+			des_encrypt(&data[0],key,1);
+			GetTSC(s1);
+			des_encrypt(&data[0],key,1);
+			des_encrypt(&data[0],key,1);
+			des_encrypt(&data[0],key,1);
+			GetTSC(e1);
+			GetTSC(s2);
+			des_encrypt(&data[0],key,1);
+			des_encrypt(&data[0],key,1);
+			des_encrypt(&data[0],key,1);
+			des_encrypt(&data[0],key,1);
+			GetTSC(e2);
+			des_encrypt(&data[0],key,1);
+			}
+
+		printf("des %d %d (%d)\n",
+			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
+		}
+	}
+
diff --git a/openssl/times/x86/md4s.cpp b/openssl/times/x86/md4s.cpp
new file mode 100644
index 0000000..c0ec97f
--- /dev/null
+++ b/openssl/times/x86/md4s.cpp
@@ -0,0 +1,78 @@
+//
+// gettsc.inl
+//
+// gives access to the Pentium's (secret) cycle counter
+//
+// This software was written by Leonard Janke (janke@unixg.ubc.ca)
+// in 1996-7 and is entered, by him, into the public domain.
+
+#if defined(__WATCOMC__)
+void GetTSC(unsigned long&);
+#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
+#elif defined(__GNUC__)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  asm volatile(".byte 15, 49\n\t"
+	       : "=eax" (tsc)
+	       :
+	       : "%edx", "%eax");
+}
+#elif defined(_MSC_VER)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  unsigned long a;
+  __asm _emit 0fh
+  __asm _emit 31h
+  __asm mov a, eax;
+  tsc=a;
+}
+#endif      
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/md4.h>
+
+extern "C" {
+void md4_block_x86(MD4_CTX *ctx, unsigned char *buffer,int num);
+}
+
+void main(int argc,char *argv[])
+	{
+	unsigned char buffer[64*256];
+	MD4_CTX ctx;
+	unsigned long s1,s2,e1,e2;
+	unsigned char k[16];
+	unsigned long data[2];
+	unsigned char iv[8];
+	int i,num=0,numm;
+	int j=0;
+
+	if (argc >= 2)
+		num=atoi(argv[1]);
+
+	if (num == 0) num=16;
+	if (num > 250) num=16;
+	numm=num+2;
+	num*=64;
+	numm*=64;
+
+	for (j=0; j<6; j++)
+		{
+		for (i=0; i<10; i++) /**/
+			{
+			md4_block_x86(&ctx,buffer,numm);
+			GetTSC(s1);
+			md4_block_x86(&ctx,buffer,numm);
+			GetTSC(e1);
+			GetTSC(s2);
+			md4_block_x86(&ctx,buffer,num);
+			GetTSC(e2);
+			md4_block_x86(&ctx,buffer,num);
+			}
+		printf("md4 (%d bytes) %d %d (%.2f)\n",num,
+			e1-s1,e2-s2,(double)((e1-s1)-(e2-s2))/2);
+		}
+	}
+
diff --git a/openssl/times/x86/md5s.cpp b/openssl/times/x86/md5s.cpp
new file mode 100644
index 0000000..dd343fd
--- /dev/null
+++ b/openssl/times/x86/md5s.cpp
@@ -0,0 +1,78 @@
+//
+// gettsc.inl
+//
+// gives access to the Pentium's (secret) cycle counter
+//
+// This software was written by Leonard Janke (janke@unixg.ubc.ca)
+// in 1996-7 and is entered, by him, into the public domain.
+
+#if defined(__WATCOMC__)
+void GetTSC(unsigned long&);
+#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
+#elif defined(__GNUC__)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  asm volatile(".byte 15, 49\n\t"
+	       : "=eax" (tsc)
+	       :
+	       : "%edx", "%eax");
+}
+#elif defined(_MSC_VER)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  unsigned long a;
+  __asm _emit 0fh
+  __asm _emit 31h
+  __asm mov a, eax;
+  tsc=a;
+}
+#endif      
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/md5.h>
+
+extern "C" {
+void md5_block_x86(MD5_CTX *ctx, unsigned char *buffer,int num);
+}
+
+void main(int argc,char *argv[])
+	{
+	unsigned char buffer[64*256];
+	MD5_CTX ctx;
+	unsigned long s1,s2,e1,e2;
+	unsigned char k[16];
+	unsigned long data[2];
+	unsigned char iv[8];
+	int i,num=0,numm;
+	int j=0;
+
+	if (argc >= 2)
+		num=atoi(argv[1]);
+
+	if (num == 0) num=16;
+	if (num > 250) num=16;
+	numm=num+2;
+	num*=64;
+	numm*=64;
+
+	for (j=0; j<6; j++)
+		{
+		for (i=0; i<10; i++) /**/
+			{
+			md5_block_x86(&ctx,buffer,numm);
+			GetTSC(s1);
+			md5_block_x86(&ctx,buffer,numm);
+			GetTSC(e1);
+			GetTSC(s2);
+			md5_block_x86(&ctx,buffer,num);
+			GetTSC(e2);
+			md5_block_x86(&ctx,buffer,num);
+			}
+		printf("md5 (%d bytes) %d %d (%.2f)\n",num,
+			e1-s1,e2-s2,(double)((e1-s1)-(e2-s2))/2);
+		}
+	}
+
diff --git a/openssl/times/x86/rc4s.cpp b/openssl/times/x86/rc4s.cpp
new file mode 100644
index 0000000..3814fde
--- /dev/null
+++ b/openssl/times/x86/rc4s.cpp
@@ -0,0 +1,73 @@
+//
+// gettsc.inl
+//
+// gives access to the Pentium's (secret) cycle counter
+//
+// This software was written by Leonard Janke (janke@unixg.ubc.ca)
+// in 1996-7 and is entered, by him, into the public domain.
+
+#if defined(__WATCOMC__)
+void GetTSC(unsigned long&);
+#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
+#elif defined(__GNUC__)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  asm volatile(".byte 15, 49\n\t"
+	       : "=eax" (tsc)
+	       :
+	       : "%edx", "%eax");
+}
+#elif defined(_MSC_VER)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  unsigned long a;
+  __asm _emit 0fh
+  __asm _emit 31h
+  __asm mov a, eax;
+  tsc=a;
+}
+#endif      
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/rc4.h>
+
+void main(int argc,char *argv[])
+	{
+	unsigned char buffer[1024];
+	RC4_KEY ctx;
+	unsigned long s1,s2,e1,e2;
+	unsigned char k[16];
+	unsigned long data[2];
+	unsigned char iv[8];
+	int i,num=64,numm;
+	int j=0;
+
+	if (argc >= 2)
+		num=atoi(argv[1]);
+
+	if (num == 0) num=256;
+	if (num > 1024-16) num=1024-16;
+	numm=num+8;
+
+	for (j=0; j<6; j++)
+		{
+		for (i=0; i<10; i++) /**/
+			{
+			RC4(&ctx,numm,buffer,buffer);
+			GetTSC(s1);
+			RC4(&ctx,numm,buffer,buffer);
+			GetTSC(e1);
+			GetTSC(s2);
+			RC4(&ctx,num,buffer,buffer);
+			GetTSC(e2);
+			RC4(&ctx,num,buffer,buffer);
+			}
+
+		printf("RC4 (%d bytes) %d %d (%d) - 8 bytes\n",num,
+			e1-s1,e2-s2,(e1-s1)-(e2-s2));
+		}
+	}
+
diff --git a/openssl/times/x86/sha1s.cpp b/openssl/times/x86/sha1s.cpp
new file mode 100644
index 0000000..3103e18
--- /dev/null
+++ b/openssl/times/x86/sha1s.cpp
@@ -0,0 +1,79 @@
+//
+// gettsc.inl
+//
+// gives access to the Pentium's (secret) cycle counter
+//
+// This software was written by Leonard Janke (janke@unixg.ubc.ca)
+// in 1996-7 and is entered, by him, into the public domain.
+
+#if defined(__WATCOMC__)
+void GetTSC(unsigned long&);
+#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
+#elif defined(__GNUC__)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  asm volatile(".byte 15, 49\n\t"
+	       : "=eax" (tsc)
+	       :
+	       : "%edx", "%eax");
+}
+#elif defined(_MSC_VER)
+inline
+void GetTSC(unsigned long& tsc)
+{
+  unsigned long a;
+  __asm _emit 0fh
+  __asm _emit 31h
+  __asm mov a, eax;
+  tsc=a;
+}
+#endif      
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/sha.h>
+
+extern "C" {
+void sha1_block_x86(SHA_CTX *ctx, unsigned char *buffer,int num);
+}
+
+void main(int argc,char *argv[])
+	{
+	unsigned char buffer[64*256];
+	SHA_CTX ctx;
+	unsigned long s1,s2,e1,e2;
+	unsigned char k[16];
+	unsigned long data[2];
+	unsigned char iv[8];
+	int i,num=0,numm;
+	int j=0;
+
+	if (argc >= 2)
+		num=atoi(argv[1]);
+
+	if (num == 0) num=16;
+	if (num > 250) num=16;
+	numm=num+2;
+	num*=64;
+	numm*=64;
+
+	for (j=0; j<6; j++)
+		{
+		for (i=0; i<10; i++) /**/
+			{
+			sha1_block_x86(&ctx,buffer,numm);
+			GetTSC(s1);
+			sha1_block_x86(&ctx,buffer,numm);
+			GetTSC(e1);
+			GetTSC(s2);
+			sha1_block_x86(&ctx,buffer,num);
+			GetTSC(e2);
+			sha1_block_x86(&ctx,buffer,num);
+			}
+
+		printf("sha1 (%d bytes) %d %d (%.2f)\n",num,
+			e1-s1,e2-s2,(double)((e1-s1)-(e2-s2))/2);
+		}
+	}
+
diff --git a/openssl/tools/Makefile b/openssl/tools/Makefile
new file mode 100644
index 0000000..bb6fb71
--- /dev/null
+++ b/openssl/tools/Makefile
@@ -0,0 +1,59 @@
+#
+# OpenSSL/tools/Makefile
+#
+
+DIR=	tools
+TOP=	..
+CC=	cc
+INCLUDES= -I$(TOP) -I../../include
+CFLAG=-g
+MAKEFILE=	Makefile
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS= c_rehash
+MISC_APPS= c_hash c_info c_issuer c_name
+
+all:
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@for i in $(APPS) ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
+	chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
+	mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i ); \
+	done;
+	@for i in $(MISC_APPS) ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
+	chmod 755 $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
+	mv -f $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i ); \
+	done;
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+
+lint:
+
+tags:
+
+errors:
+
+depend:
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+	rm -f c_rehash
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+errors:
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
diff --git a/openssl/tools/c89.sh b/openssl/tools/c89.sh
new file mode 100755
index 0000000..b25c9fd
--- /dev/null
+++ b/openssl/tools/c89.sh
@@ -0,0 +1,15 @@
+#!/bin/sh -k
+#
+# Re-order arguments so that -L comes first
+#
+opts=""
+lopts=""
+        
+for arg in $* ; do
+  case $arg in
+    -L*) lopts="$lopts $arg" ;;
+    *) opts="$opts $arg" ;;
+  esac
+done
+
+c89 $lopts $opts
diff --git a/openssl/tools/c_hash b/openssl/tools/c_hash
new file mode 100644
index 0000000..5e0a908
--- /dev/null
+++ b/openssl/tools/c_hash
@@ -0,0 +1,9 @@
+#!/bin/sh
+# print out the hash values 
+#
+
+for i in $*
+do
+	h=`openssl x509 -hash -noout -in $i`
+	echo "$h.0 => $i"
+done
diff --git a/openssl/tools/c_info b/openssl/tools/c_info
new file mode 100644
index 0000000..0e1e633
--- /dev/null
+++ b/openssl/tools/c_info
@@ -0,0 +1,12 @@
+#!/bin/sh
+#
+# print the subject
+#
+
+for i in $*
+do
+	n=`openssl x509 -subject -issuer -enddate -noout -in $i`
+	echo "$i"
+	echo "$n"
+	echo "--------"
+done
diff --git a/openssl/tools/c_issuer b/openssl/tools/c_issuer
new file mode 100644
index 0000000..55821ab
--- /dev/null
+++ b/openssl/tools/c_issuer
@@ -0,0 +1,10 @@
+#!/bin/sh
+#
+# print out the issuer
+#
+
+for i in $*
+do
+	n=`openssl x509 -issuer -noout -in $i`
+	echo "$i	$n"
+done
diff --git a/openssl/tools/c_name b/openssl/tools/c_name
new file mode 100644
index 0000000..28800c0
--- /dev/null
+++ b/openssl/tools/c_name
@@ -0,0 +1,10 @@
+#!/bin/sh
+#
+# print the subject
+#
+
+for i in $*
+do
+	n=`openssl x509 -subject -noout -in $i`
+	echo "$i	$n"
+done
diff --git a/openssl/tools/c_rehash b/openssl/tools/c_rehash
new file mode 100644
index 0000000..6a20011
--- /dev/null
+++ b/openssl/tools/c_rehash
@@ -0,0 +1,180 @@
+#!/usr/bin/perl
+
+
+# Perl c_rehash script, scan all files in a directory
+# and add symbolic links to their hash values.
+
+my $openssl;
+
+my $dir = "/usr/local/ssl";
+my $prefix = "/usr/local/ssl";
+
+if(defined $ENV{OPENSSL}) {
+	$openssl = $ENV{OPENSSL};
+} else {
+	$openssl = "openssl";
+	$ENV{OPENSSL} = $openssl;
+}
+
+my $pwd;
+eval "require Cwd";
+if (defined(&Cwd::getcwd)) {
+	$pwd=Cwd::getcwd();
+} else {
+	$pwd=`pwd`; chomp($pwd);
+}
+my $path_delim = ($pwd =~ /^[a-z]\:/i) ? ';' : ':'; # DOS/Win32 or Unix delimiter?
+
+$ENV{PATH} = "$prefix/bin" . ($ENV{PATH} ? $path_delim . $ENV{PATH} : ""); # prefix our path
+
+if(! -x $openssl) {
+	my $found = 0;
+	foreach (split /$path_delim/, $ENV{PATH}) {
+		if(-x "$_/$openssl") {
+			$found = 1;
+			$openssl = "$_/$openssl";
+			last;
+		}	
+	}
+	if($found == 0) {
+		print STDERR "c_rehash: rehashing skipped ('openssl' program not available)\n";
+		exit 0;
+	}
+}
+
+if(@ARGV) {
+	@dirlist = @ARGV;
+} elsif($ENV{SSL_CERT_DIR}) {
+	@dirlist = split /$path_delim/, $ENV{SSL_CERT_DIR};
+} else {
+	$dirlist[0] = "$dir/certs";
+}
+
+if (-d $dirlist[0]) {
+	chdir $dirlist[0];
+	$openssl="$pwd/$openssl" if (!-x $openssl);
+	chdir $pwd;
+}
+
+foreach (@dirlist) {
+	if(-d $_ and -w $_) {
+		hash_dir($_);
+	}
+}
+
+sub hash_dir {
+	my %hashlist;
+	print "Doing $_[0]\n";
+	chdir $_[0];
+	opendir(DIR, ".");
+	my @flist = readdir(DIR);
+	# Delete any existing symbolic links
+	foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) {
+		if(-l $_) {
+			unlink $_;
+		}
+	}
+	closedir DIR;
+	FILE: foreach $fname (grep {/\.pem$/} @flist) {
+		# Check to see if certificates and/or CRLs present.
+		my ($cert, $crl) = check_file($fname);
+		if(!$cert && !$crl) {
+			print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n";
+			next;
+		}
+		link_hash_cert($fname) if($cert);
+		link_hash_crl($fname) if($crl);
+	}
+}
+
+sub check_file {
+	my ($is_cert, $is_crl) = (0,0);
+	my $fname = $_[0];
+	open IN, $fname;
+	while(<IN>) {
+		if(/^-----BEGIN (.*)-----/) {
+			my $hdr = $1;
+			if($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
+				$is_cert = 1;
+				last if($is_crl);
+			} elsif($hdr eq "X509 CRL") {
+				$is_crl = 1;
+				last if($is_cert);
+			}
+		}
+	}
+	close IN;
+	return ($is_cert, $is_crl);
+}
+
+
+# Link a certificate to its subject name hash value, each hash is of
+# the form <hash>.<n> where n is an integer. If the hash value already exists
+# then we need to up the value of n, unless its a duplicate in which
+# case we skip the link. We check for duplicates by comparing the
+# certificate fingerprints
+
+sub link_hash_cert {
+		my $fname = $_[0];
+		$fname =~ s/'/'\\''/g;
+		my ($hash, $fprint) = `"$openssl" x509 -hash -fingerprint -noout -in "$fname"`;
+		chomp $hash;
+		chomp $fprint;
+		$fprint =~ s/^.*=//;
+		$fprint =~ tr/://d;
+		my $suffix = 0;
+		# Search for an unused hash filename
+		while(exists $hashlist{"$hash.$suffix"}) {
+			# Hash matches: if fingerprint matches its a duplicate cert
+			if($hashlist{"$hash.$suffix"} eq $fprint) {
+				print STDERR "WARNING: Skipping duplicate certificate $fname\n";
+				return;
+			}
+			$suffix++;
+		}
+		$hash .= ".$suffix";
+		print "$fname => $hash\n";
+		$symlink_exists=eval {symlink("",""); 1};
+		if ($symlink_exists) {
+			symlink $fname, $hash;
+		} else {
+			open IN,"<$fname" or die "can't open $fname for read";
+			open OUT,">$hash" or die "can't open $hash for write";
+			print OUT <IN>;	# does the job for small text files
+			close OUT;
+			close IN;
+		}
+		$hashlist{$hash} = $fprint;
+}
+
+# Same as above except for a CRL. CRL links are of the form <hash>.r<n>
+
+sub link_hash_crl {
+		my $fname = $_[0];
+		$fname =~ s/'/'\\''/g;
+		my ($hash, $fprint) = `"$openssl" crl -hash -fingerprint -noout -in '$fname'`;
+		chomp $hash;
+		chomp $fprint;
+		$fprint =~ s/^.*=//;
+		$fprint =~ tr/://d;
+		my $suffix = 0;
+		# Search for an unused hash filename
+		while(exists $hashlist{"$hash.r$suffix"}) {
+			# Hash matches: if fingerprint matches its a duplicate cert
+			if($hashlist{"$hash.r$suffix"} eq $fprint) {
+				print STDERR "WARNING: Skipping duplicate CRL $fname\n";
+				return;
+			}
+			$suffix++;
+		}
+		$hash .= ".r$suffix";
+		print "$fname => $hash\n";
+		$symlink_exists=eval {symlink("",""); 1};
+		if ($symlink_exists) {
+			symlink $fname, $hash;
+		} else {
+			system ("cp", $fname, $hash);
+		}
+		$hashlist{$hash} = $fprint;
+}
+
diff --git a/openssl/tools/c_rehash.in b/openssl/tools/c_rehash.in
new file mode 100644
index 0000000..bfc4a69
--- /dev/null
+++ b/openssl/tools/c_rehash.in
@@ -0,0 +1,180 @@
+#!/usr/local/bin/perl
+
+
+# Perl c_rehash script, scan all files in a directory
+# and add symbolic links to their hash values.
+
+my $openssl;
+
+my $dir;
+my $prefix;
+
+if(defined $ENV{OPENSSL}) {
+	$openssl = $ENV{OPENSSL};
+} else {
+	$openssl = "openssl";
+	$ENV{OPENSSL} = $openssl;
+}
+
+my $pwd;
+eval "require Cwd";
+if (defined(&Cwd::getcwd)) {
+	$pwd=Cwd::getcwd();
+} else {
+	$pwd=`pwd`; chomp($pwd);
+}
+my $path_delim = ($pwd =~ /^[a-z]\:/i) ? ';' : ':'; # DOS/Win32 or Unix delimiter?
+
+$ENV{PATH} = "$prefix/bin" . ($ENV{PATH} ? $path_delim . $ENV{PATH} : ""); # prefix our path
+
+if(! -x $openssl) {
+	my $found = 0;
+	foreach (split /$path_delim/, $ENV{PATH}) {
+		if(-x "$_/$openssl") {
+			$found = 1;
+			$openssl = "$_/$openssl";
+			last;
+		}	
+	}
+	if($found == 0) {
+		print STDERR "c_rehash: rehashing skipped ('openssl' program not available)\n";
+		exit 0;
+	}
+}
+
+if(@ARGV) {
+	@dirlist = @ARGV;
+} elsif($ENV{SSL_CERT_DIR}) {
+	@dirlist = split /$path_delim/, $ENV{SSL_CERT_DIR};
+} else {
+	$dirlist[0] = "$dir/certs";
+}
+
+if (-d $dirlist[0]) {
+	chdir $dirlist[0];
+	$openssl="$pwd/$openssl" if (!-x $openssl);
+	chdir $pwd;
+}
+
+foreach (@dirlist) {
+	if(-d $_ and -w $_) {
+		hash_dir($_);
+	}
+}
+
+sub hash_dir {
+	my %hashlist;
+	print "Doing $_[0]\n";
+	chdir $_[0];
+	opendir(DIR, ".");
+	my @flist = readdir(DIR);
+	# Delete any existing symbolic links
+	foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) {
+		if(-l $_) {
+			unlink $_;
+		}
+	}
+	closedir DIR;
+	FILE: foreach $fname (grep {/\.pem$/} @flist) {
+		# Check to see if certificates and/or CRLs present.
+		my ($cert, $crl) = check_file($fname);
+		if(!$cert && !$crl) {
+			print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n";
+			next;
+		}
+		link_hash_cert($fname) if($cert);
+		link_hash_crl($fname) if($crl);
+	}
+}
+
+sub check_file {
+	my ($is_cert, $is_crl) = (0,0);
+	my $fname = $_[0];
+	open IN, $fname;
+	while(<IN>) {
+		if(/^-----BEGIN (.*)-----/) {
+			my $hdr = $1;
+			if($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
+				$is_cert = 1;
+				last if($is_crl);
+			} elsif($hdr eq "X509 CRL") {
+				$is_crl = 1;
+				last if($is_cert);
+			}
+		}
+	}
+	close IN;
+	return ($is_cert, $is_crl);
+}
+
+
+# Link a certificate to its subject name hash value, each hash is of
+# the form <hash>.<n> where n is an integer. If the hash value already exists
+# then we need to up the value of n, unless its a duplicate in which
+# case we skip the link. We check for duplicates by comparing the
+# certificate fingerprints
+
+sub link_hash_cert {
+		my $fname = $_[0];
+		$fname =~ s/'/'\\''/g;
+		my ($hash, $fprint) = `"$openssl" x509 -hash -fingerprint -noout -in "$fname"`;
+		chomp $hash;
+		chomp $fprint;
+		$fprint =~ s/^.*=//;
+		$fprint =~ tr/://d;
+		my $suffix = 0;
+		# Search for an unused hash filename
+		while(exists $hashlist{"$hash.$suffix"}) {
+			# Hash matches: if fingerprint matches its a duplicate cert
+			if($hashlist{"$hash.$suffix"} eq $fprint) {
+				print STDERR "WARNING: Skipping duplicate certificate $fname\n";
+				return;
+			}
+			$suffix++;
+		}
+		$hash .= ".$suffix";
+		print "$fname => $hash\n";
+		$symlink_exists=eval {symlink("",""); 1};
+		if ($symlink_exists) {
+			symlink $fname, $hash;
+		} else {
+			open IN,"<$fname" or die "can't open $fname for read";
+			open OUT,">$hash" or die "can't open $hash for write";
+			print OUT <IN>;	# does the job for small text files
+			close OUT;
+			close IN;
+		}
+		$hashlist{$hash} = $fprint;
+}
+
+# Same as above except for a CRL. CRL links are of the form <hash>.r<n>
+
+sub link_hash_crl {
+		my $fname = $_[0];
+		$fname =~ s/'/'\\''/g;
+		my ($hash, $fprint) = `"$openssl" crl -hash -fingerprint -noout -in '$fname'`;
+		chomp $hash;
+		chomp $fprint;
+		$fprint =~ s/^.*=//;
+		$fprint =~ tr/://d;
+		my $suffix = 0;
+		# Search for an unused hash filename
+		while(exists $hashlist{"$hash.r$suffix"}) {
+			# Hash matches: if fingerprint matches its a duplicate cert
+			if($hashlist{"$hash.r$suffix"} eq $fprint) {
+				print STDERR "WARNING: Skipping duplicate CRL $fname\n";
+				return;
+			}
+			$suffix++;
+		}
+		$hash .= ".r$suffix";
+		print "$fname => $hash\n";
+		$symlink_exists=eval {symlink("",""); 1};
+		if ($symlink_exists) {
+			symlink $fname, $hash;
+		} else {
+			system ("cp", $fname, $hash);
+		}
+		$hashlist{$hash} = $fprint;
+}
+
diff --git a/openssl/util/FreeBSD.sh b/openssl/util/FreeBSD.sh
new file mode 100755
index 0000000..db8edfc
--- /dev/null
+++ b/openssl/util/FreeBSD.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+perl util/perlpath.pl /usr/bin
+perl util/ssldir.pl /usr/local  
+perl util/mk1mf.pl FreeBSD >Makefile.FreeBSD
+perl Configure FreeBSD
diff --git a/openssl/util/add_cr.pl b/openssl/util/add_cr.pl
new file mode 100755
index 0000000..c7b62c1
--- /dev/null
+++ b/openssl/util/add_cr.pl
@@ -0,0 +1,123 @@
+#!/usr/local/bin/perl
+#
+# This adds a copyright message to a souce code file.
+# It also gets the file name correct.
+#
+# perl util/add_cr.pl *.[ch] */*.[ch] */*/*.[ch]
+#
+
+foreach (@ARGV)
+	{
+	&dofile($_);
+	}
+
+sub dofile
+	{
+	local($file)=@_;
+
+	open(IN,"<$file") || die "unable to open $file:$!\n";
+
+	print STDERR "doing $file\n";
+	@in=<IN>;
+
+	return(1) if ($in[0] =~ / NOCW /);
+
+	@out=();
+	open(OUT,">$file.out") || die "unable to open $file.$$:$!\n";
+	push(@out,"/* $file */\n");
+	if (($in[1] !~ /^\/\* Copyright \(C\) [0-9-]+ Eric Young \(eay\@cryptsoft.com\)/))
+		{
+		push(@out,&Copyright);
+		$i=2;
+		@a=grep(/ Copyright \(C\) /,@in);
+		if ($#a >= 0)
+			{
+			while (($i <= $#in) && ($in[$i] ne " */\n"))
+				{ $i++; }
+			$i++ if ($in[$i] eq " */\n");
+
+			while (($i <= $#in) && ($in[$i] =~ /^\s*$/))
+				{ $i++; }
+
+			push(@out,"\n");
+			for ( ; $i <= $#in; $i++)
+				{ push(@out,$in[$i]); }
+			}
+		else
+			{ push(@out,@in); }
+		}
+	else
+		{
+		shift(@in);
+		push(@out,@in);
+		}
+	print OUT @out;
+	close(IN);
+	close(OUT);
+	rename("$file","$file.orig") || die "unable to rename $file:$!\n";
+	rename("$file.out",$file) || die "unable to rename $file.out:$!\n";
+	}
+
+
+
+sub Copyright
+	{
+	return <<'EOF';
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+EOF
+	}
diff --git a/openssl/util/bat.sh b/openssl/util/bat.sh
new file mode 100755
index 0000000..4d9a828
--- /dev/null
+++ b/openssl/util/bat.sh
@@ -0,0 +1,134 @@
+#!/usr/local/bin/perl
+
+$infile="/home/eay/ssl/SSLeay/MINFO";
+
+open(IN,"<$infile") || die "unable to open $infile:$!\n";
+$_=<IN>;
+for (;;)
+	{
+	chop;
+
+	($key,$val)=/^([^=]+)=(.*)/;
+	if ($key eq "RELATIVE_DIRECTORY")
+		{
+		if ($lib ne "")
+			{
+			$uc=$lib;
+			$uc =~ s/^lib(.*)\.a/$1/;
+			$uc =~ tr/a-z/A-Z/;
+			$lib_nam{$uc}=$uc;
+			$lib_obj{$uc}.=$libobj." ";
+			}
+		last if ($val eq "FINISHED");
+		$lib="";
+		$libobj="";
+		$dir=$val;
+		}
+
+	if ($key eq "TEST")
+		{ $test.=&var_add($dir,$val); }
+
+	if (($key eq "PROGS") || ($key eq "E_OBJ"))
+		{ $e_exe.=&var_add($dir,$val); }
+
+	if ($key eq "LIB")
+		{
+		$lib=$val;
+		$lib =~ s/^.*\/([^\/]+)$/$1/;
+		}
+
+	if ($key eq "EXHEADER")
+		{ $exheader.=&var_add($dir,$val); }
+
+	if ($key eq "HEADER")
+		{ $header.=&var_add($dir,$val); }
+
+	if ($key eq "LIBSRC")
+		{ $libsrc.=&var_add($dir,$val); }
+
+	if (!($_=<IN>))
+		{ $_="RELATIVE_DIRECTORY=FINISHED\n"; }
+	}
+close(IN);
+
+@a=split(/\s+/,$libsrc);
+foreach (@a)
+	{
+	print "${_}.c\n";
+	}
+
+sub var_add
+	{
+	local($dir,$val)=@_;
+	local(@a,$_,$ret);
+
+	return("") if $no_engine && $dir =~ /\/engine/;
+	return("") if $no_idea && $dir =~ /\/idea/;
+	return("") if $no_rc2  && $dir =~ /\/rc2/;
+	return("") if $no_rc4  && $dir =~ /\/rc4/;
+	return("") if $no_rsa  && $dir =~ /\/rsa/;
+	return("") if $no_rsa  && $dir =~ /^rsaref/;
+	return("") if $no_dsa  && $dir =~ /\/dsa/;
+	return("") if $no_dh   && $dir =~ /\/dh/;
+	if ($no_des && $dir =~ /\/des/)
+		{
+		if ($val =~ /read_pwd/)
+			{ return("$dir/read_pwd "); }
+		else
+			{ return(""); }
+		}
+	return("") if $no_mdc2 && $dir =~ /\/mdc2/;
+	return("") if $no_sock && $dir =~ /\/proxy/;
+	return("") if $no_bf   && $dir =~ /\/bf/;
+	return("") if $no_cast && $dir =~ /\/cast/;
+
+	$val =~ s/^\s*(.*)\s*$/$1/;
+	@a=split(/\s+/,$val);
+	grep(s/\.[och]$//,@a);
+
+	@a=grep(!/^e_.*_3d$/,@a) if $no_des;
+	@a=grep(!/^e_.*_d$/,@a) if $no_des;
+	@a=grep(!/^e_.*_i$/,@a) if $no_idea;
+	@a=grep(!/^e_.*_r2$/,@a) if $no_rc2;
+	@a=grep(!/^e_.*_bf$/,@a) if $no_bf;
+	@a=grep(!/^e_.*_c$/,@a) if $no_cast;
+	@a=grep(!/^e_rc4$/,@a) if $no_rc4;
+
+	@a=grep(!/(^s2_)|(^s23_)/,@a) if $no_ssl2;
+	@a=grep(!/(^s3_)|(^s23_)/,@a) if $no_ssl3;
+
+	@a=grep(!/(_sock$)|(_acpt$)|(_conn$)|(^pxy_)/,@a) if $no_sock;
+
+	@a=grep(!/(^md2)|(_md2$)/,@a) if $no_md2;
+	@a=grep(!/(^md5)|(_md5$)/,@a) if $no_md5;
+
+	@a=grep(!/(^d2i_r_)|(^i2d_r_)/,@a) if $no_rsa;
+	@a=grep(!/(^p_open$)|(^p_seal$)/,@a) if $no_rsa;
+	@a=grep(!/(^pem_seal$)/,@a) if $no_rsa;
+
+	@a=grep(!/(m_dss$)|(m_dss1$)/,@a) if $no_dsa;
+	@a=grep(!/(^d2i_s_)|(^i2d_s_)|(_dsap$)/,@a) if $no_dsa;
+
+	@a=grep(!/^n_pkey$/,@a) if $no_rsa || $no_rc4;
+
+	@a=grep(!/_dhp$/,@a) if $no_dh;
+
+	@a=grep(!/(^sha[^1])|(_sha$)|(m_dss$)/,@a) if $no_sha;
+	@a=grep(!/(^sha1)|(_sha1$)|(m_dss1$)/,@a) if $no_sha1;
+	@a=grep(!/_mdc2$/,@a) if $no_mdc2;
+
+	@a=grep(!/^engine$/,@a) if $no_engine;
+	@a=grep(!/(^rsa$)|(^genrsa$)|(^req$)|(^ca$)/,@a) if $no_rsa;
+	@a=grep(!/(^dsa$)|(^gendsa$)|(^dsaparam$)/,@a) if $no_dsa;
+	@a=grep(!/^gendsa$/,@a) if $no_sha1;
+	@a=grep(!/(^dh$)|(^gendh$)/,@a) if $no_dh;
+
+	@a=grep(!/(^dh)|(_sha1$)|(m_dss1$)/,@a) if $no_sha1;
+
+	grep($_="$dir/$_",@a);
+	@a=grep(!/(^|\/)s_/,@a) if $no_sock;
+	@a=grep(!/(^|\/)bio_sock/,@a) if $no_sock;
+	$ret=join(' ',@a)." ";
+	return($ret);
+	}
+
diff --git a/openssl/util/ck_errf.pl b/openssl/util/ck_errf.pl
new file mode 100755
index 0000000..f13af5c
--- /dev/null
+++ b/openssl/util/ck_errf.pl
@@ -0,0 +1,64 @@
+#!/usr/local/bin/perl
+#
+# This is just a quick script to scan for cases where the 'error'
+# function name in a XXXerr() macro is wrong.
+# 
+# Run in the top level by going
+# perl util/ck_errf.pl */*.c */*/*.c
+#
+
+my $err_strict = 0;
+my $bad = 0;
+
+foreach $file (@ARGV)
+	{
+	if ($file eq "-strict")
+		{
+		$err_strict = 1;
+		next;
+		}
+	open(IN,"<$file") || die "unable to open $file\n";
+	$func="";
+	while (<IN>)
+		{
+		if (!/;$/ && /^([a-zA-Z].*[\s*])?([A-Za-z_0-9]+)\(.*[),]/)
+			{
+			/^([^()]*(\([^()]*\)[^()]*)*)\(/;
+			$1 =~ /([A-Za-z_0-9]*)$/;
+			$func = $1;
+			$func =~ tr/A-Z/a-z/;
+			}
+		if (/([A-Z0-9]+)err\(([^,]+)/ && ! /ckerr_ignore/)
+			{
+			$errlib=$1;
+			$n=$2;
+
+			if ($func eq "")
+				{ print "$file:$.:???:$n\n"; $bad = 1; next; }
+
+			if ($n !~ /([^_]+)_F_(.+)$/)
+				{
+		#		print "check -$file:$.:$func:$n\n";
+				next;
+				}
+			$lib=$1;
+			$n=$2;
+
+			if ($lib ne $errlib)
+				{ print "$file:$.:$func:$n [${errlib}err]\n"; $bad = 1; next; }
+
+			$n =~ tr/A-Z/a-z/;
+			if (($n ne $func) && ($errlib ne "SYS"))
+				{ print "$file:$.:$func:$n\n"; $bad = 1; next; }
+	#		print "$func:$1\n";
+			}
+		}
+	close(IN);
+        }
+
+if ($bad && $err_strict)
+	{
+	print STDERR "FATAL: error discrepancy\n";
+	exit 1;
+	}
+
diff --git a/openssl/util/clean-depend.pl b/openssl/util/clean-depend.pl
new file mode 100755
index 0000000..d3525b0
--- /dev/null
+++ b/openssl/util/clean-depend.pl
@@ -0,0 +1,58 @@
+#!/usr/local/bin/perl -w
+# Clean the dependency list in a makefile of standard includes...
+# Written by Ben Laurie <ben@algroup.co.uk> 19 Jan 1999
+
+use strict;
+
+while(<STDIN>) {
+    print;
+    last if /^# DO NOT DELETE THIS LINE/;
+}
+
+my %files;
+
+my $thisfile="";
+while(<STDIN>) {
+    my ($dummy, $file,$deps)=/^((.*):)? (.*)$/;
+    my $origfile="";
+    $thisfile=$file if defined $file;
+    next if !defined $deps;
+    $origfile=$thisfile;
+    $origfile=~s/\.o$/.c/;
+    my @deps=split ' ',$deps;
+    @deps=grep(!/^\//,@deps);
+    @deps=grep(!/^\\$/,@deps);
+    @deps=grep(!/^$origfile$/,@deps);
+# pull out the kludged kerberos header (if present).
+    @deps=grep(!/^[.\/]+\/krb5.h/,@deps);
+    push @{$files{$thisfile}},@deps;
+}
+
+my $file;
+foreach $file (sort keys %files) {
+    my $len=0;
+    my $dep;
+    my $origfile=$file;
+    $origfile=~s/\.o$/.c/;
+    $file=~s/^\.\///;
+    push @{$files{$file}},$origfile;
+    my $prevdep="";
+
+    # Remove leading ./ before sorting
+    my @deps = map { $_ =~ s/^\.\///; $_ } @{$files{$file}};
+
+    foreach $dep (sort @deps) {
+	$dep=~s/^\.\///;
+	next if $prevdep eq $dep; # to exterminate duplicates...
+	$prevdep = $dep;
+	$len=0 if $len+length($dep)+1 >= 80;
+	if($len == 0) {
+	    print "\n$file:";
+	    $len=length($file)+1;
+	}
+	print " $dep";
+	$len+=length($dep)+1;
+    }
+}
+
+print "\n";
diff --git a/openssl/util/copy.pl b/openssl/util/copy.pl
new file mode 100644
index 0000000..e20b455
--- /dev/null
+++ b/openssl/util/copy.pl
@@ -0,0 +1,59 @@
+#!/usr/local/bin/perl
+
+use Fcntl;
+
+
+# copy.pl
+
+# Perl script 'copy' comment. On Windows the built in "copy" command also
+# copies timestamps: this messes up Makefile dependencies.
+
+my $arg;
+
+foreach $arg (@ARGV) {
+	$arg =~ s|\\|/|g;	# compensate for bug/feature in cygwin glob...
+	foreach (glob $arg)
+		{
+		push @filelist, $_;
+		}
+}
+
+$fnum = @filelist;
+
+if ($fnum <= 1)
+	{
+	die "Need at least two filenames";
+	}
+
+$dest = pop @filelist;
+	
+if ($fnum > 2 && ! -d $dest)
+	{
+	die "Destination must be a directory";
+	}
+
+foreach (@filelist)
+	{
+	if (-d $dest)
+		{
+		$dfile = $_;
+		$dfile =~ s|^.*[/\\]([^/\\]*)$|$1|;
+		$dfile = "$dest/$dfile";
+		}
+	else
+		{
+		$dfile = $dest;
+		}
+	sysopen(IN, $_, O_RDONLY|O_BINARY) || die "Can't Open $_";
+	sysopen(OUT, $dfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY)
+					|| die "Can't Open $dfile";
+	while (sysread IN, $buf, 10240)
+		{
+		syswrite(OUT, $buf, length($buf));
+		}
+	close(IN);
+	close(OUT);
+	print "Copying: $_ to $dfile\n";
+	}
+		
+
diff --git a/openssl/util/cygwin.sh b/openssl/util/cygwin.sh
new file mode 100755
index 0000000..d622852
--- /dev/null
+++ b/openssl/util/cygwin.sh
@@ -0,0 +1,146 @@
+#!/bin/bash
+#
+# This script configures, builds and packs the binary package for
+# the Cygwin net distribution version of OpenSSL
+#
+
+# Uncomment when debugging
+#set -x
+
+CONFIG_OPTIONS="--prefix=/usr shared zlib no-idea no-rc5"
+INSTALL_PREFIX=/tmp/install/INSTALL
+
+VERSION=
+SUBVERSION=$1
+
+function cleanup()
+{
+  rm -rf ${INSTALL_PREFIX}/etc
+  rm -rf ${INSTALL_PREFIX}/usr
+}
+
+function get_openssl_version()
+{
+  eval `grep '^VERSION=' Makefile`
+  if [ -z "${VERSION}" ]
+  then
+    echo "Error: Couldn't retrieve OpenSSL version from Makefile."
+    echo "       Check value of variable VERSION in Makefile."
+    exit 1
+  fi
+}
+
+function base_install()
+{
+  mkdir -p ${INSTALL_PREFIX}
+  cleanup
+  make install INSTALL_PREFIX="${INSTALL_PREFIX}"
+}
+
+function doc_install()
+{
+  DOC_DIR=${INSTALL_PREFIX}/usr/share/doc/openssl
+
+  mkdir -p ${DOC_DIR}
+  cp CHANGES CHANGES.SSLeay INSTALL LICENSE NEWS README ${DOC_DIR}
+
+  create_cygwin_readme
+}
+
+function certs_install()
+{
+  CERTS_DIR=${INSTALL_PREFIX}/usr/ssl/certs
+
+  mkdir -p ${CERTS_DIR}
+  cp -rp certs/* ${CERTS_DIR}
+}
+
+function create_cygwin_readme()
+{
+  README_DIR=${INSTALL_PREFIX}/usr/share/doc/Cygwin
+  README_FILE=${README_DIR}/openssl-${VERSION}.README
+
+  mkdir -p ${README_DIR}
+  cat > ${README_FILE} <<- EOF
+	The Cygwin version has been built using the following configure:
+
+	  ./config ${CONFIG_OPTIONS}
+
+	The IDEA and RC5 algorithms are disabled due to patent and/or
+	licensing issues.
+	EOF
+}
+
+function create_profile_files()
+{
+  PROFILE_DIR=${INSTALL_PREFIX}/etc/profile.d
+
+  mkdir -p $PROFILE_DIR
+  cat > ${PROFILE_DIR}/openssl.sh <<- "EOF"
+	export MANPATH="${MANPATH}:/usr/ssl/man"
+	EOF
+  cat > ${PROFILE_DIR}/openssl.csh <<- "EOF"
+	if ( $?MANPATH ) then
+	  setenv MANPATH "${MANPATH}:/usr/ssl/man"
+	else
+	  setenv MANPATH ":/usr/ssl/man"
+	endif
+	EOF
+}
+
+if [ -z "${SUBVERSION}" ]
+then
+  echo "Usage: $0 subversion"
+  exit 1
+fi
+
+if [ ! -f config ]
+then
+  echo "You must start this script in the OpenSSL toplevel source dir."
+  exit 1
+fi
+
+./config ${CONFIG_OPTIONS}
+
+get_openssl_version
+
+make depend || exit 1
+
+make || exit 1
+
+base_install
+
+doc_install
+
+certs_install
+
+create_cygwin_readme
+
+create_profile_files
+
+cd ${INSTALL_PREFIX}
+chmod u+w usr/lib/engines/*.so
+strip usr/bin/*.exe usr/bin/*.dll usr/lib/engines/*.so
+chmod u-w usr/lib/engines/*.so
+
+# Runtime package
+tar cjf libopenssl${VERSION//[!0-9]/}-${VERSION}-${SUBVERSION}.tar.bz2 \
+     usr/bin/cyg*dll
+# Base package
+find etc usr/bin/openssl.exe usr/bin/c_rehash usr/lib/engines usr/share/doc \
+     usr/ssl/certs usr/ssl/man/man[157] usr/ssl/misc usr/ssl/openssl.cnf \
+     usr/ssl/private \
+     -empty -o \! -type d |
+tar cjfT openssl-${VERSION}-${SUBVERSION}.tar.bz2 -
+# Development package
+find usr/include usr/lib/*.a usr/lib/pkgconfig usr/ssl/man/man3 \
+     -empty -o \! -type d |
+tar cjfT openssl-devel-${VERSION}-${SUBVERSION}.tar.bz2 -
+
+ls -l openssl-${VERSION}-${SUBVERSION}.tar.bz2
+ls -l openssl-devel-${VERSION}-${SUBVERSION}.tar.bz2
+ls -l libopenssl${VERSION//[!0-9]/}-${VERSION}-${SUBVERSION}.tar.bz2
+
+cleanup
+
+exit 0
diff --git a/openssl/util/deleof.pl b/openssl/util/deleof.pl
new file mode 100755
index 0000000..155acd8
--- /dev/null
+++ b/openssl/util/deleof.pl
@@ -0,0 +1,7 @@
+#!/usr/local/bin/perl
+
+while (<>)
+	{
+	print
+	last if (/^# DO NOT DELETE THIS LINE/);
+	}
diff --git a/openssl/util/deltree.com b/openssl/util/deltree.com
new file mode 100644
index 0000000..9f36b1a
--- /dev/null
+++ b/openssl/util/deltree.com
@@ -0,0 +1,34 @@
+$! DELTREE.COM
+$
+$ call deltree 'p1'
+$ exit $status
+$
+$ deltree: subroutine ! P1 is a name of a directory
+$	on control_y then goto dt_STOP
+$	on warning then goto dt_exit
+$	_dt_def = f$trnlnm("SYS$DISK")+f$directory()
+$	if f$parse(p1) .eqs. "" then exit
+$	set default 'f$parse(p1,,,"DEVICE")''f$parse(p1,,,"DIRECTORY")'
+$	p1 = f$parse(p1,,,"NAME") + f$parse(p1,,,"TYPE")
+$	_fp = f$parse(".DIR",p1)
+$ dt_loop:
+$	_f = f$search(_fp)
+$	if _f .eqs. "" then goto dt_loopend
+$	call deltree [.'f$parse(_f,,,"NAME")']*.*
+$	goto dt_loop
+$ dt_loopend:
+$	_fp = f$parse(p1,".;*")
+$	if f$search(_fp) .eqs. "" then goto dt_exit
+$	set noon
+$	set file/prot=(S:RWED,O:RWED,G:RWED,W:RWED) '_fp'
+$	set on
+$	delete/nolog '_fp'
+$ dt_exit:
+$	set default '_dt_def'
+$	goto dt_end
+$ dt_STOP:
+$	set default '_dt_def'
+$	stop/id=""
+$	exit
+$ dt_end:
+$	endsubroutine
diff --git a/openssl/util/dirname.pl b/openssl/util/dirname.pl
new file mode 100644
index 0000000..d7a66d9
--- /dev/null
+++ b/openssl/util/dirname.pl
@@ -0,0 +1,18 @@
+#!/usr/local/bin/perl
+
+if ($#ARGV < 0) {
+    die "dirname.pl: too few arguments\n";
+} elsif ($#ARGV > 0) {
+    die "dirname.pl: too many arguments\n";
+}
+
+my $d = $ARGV[0];
+
+if ($d =~ m|.*/.*|) {
+    $d =~ s|/[^/]*$||;
+} else {
+    $d = ".";
+}
+
+print $d,"\n";
+exit(0);
diff --git a/openssl/util/do_ms.sh b/openssl/util/do_ms.sh
new file mode 100755
index 0000000..515b074
--- /dev/null
+++ b/openssl/util/do_ms.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+# generate the Microsoft makefiles and .def files
+#
+
+PATH=util:../util:$PATH
+
+# perl util/mk1mf.pl no-sock VC-MSDOS >ms/msdos.mak
+# perl util/mk1mf.pl VC-W31-32 >ms/w31.mak
+perl util/mk1mf.pl dll VC-WIN16 >ms/w31dll.mak
+# perl util/mk1mf.pl VC-WIN32 >ms/nt.mak
+perl util/mk1mf.pl dll VC-WIN32 >ms/ntdll.mak
+perl util/mk1mf.pl Mingw32 >ms/mingw32.mak
+perl util/mk1mf.pl Mingw32-files >ms/mingw32f.mak
+
+perl util/mkdef.pl 16 libeay > ms/libeay16.def
+perl util/mkdef.pl 32 libeay > ms/libeay32.def
+perl util/mkdef.pl 16 ssleay > ms/ssleay16.def
+perl util/mkdef.pl 32 ssleay > ms/ssleay32.def
diff --git a/openssl/util/domd b/openssl/util/domd
new file mode 100755
index 0000000..bab48cb
--- /dev/null
+++ b/openssl/util/domd
@@ -0,0 +1,38 @@
+#!/bin/sh
+# Do a makedepend, only leave out the standard headers
+# Written by Ben Laurie <ben@algroup.co.uk> 19 Jan 1999
+
+TOP=$1
+shift
+if [ "$1" = "-MD" ]; then
+    shift
+    MAKEDEPEND=$1
+    shift
+fi
+if [ "$MAKEDEPEND" = "" ]; then MAKEDEPEND=makedepend; fi
+
+cp Makefile Makefile.save
+# fake the presence of Kerberos
+touch $TOP/krb5.h
+if expr "$MAKEDEPEND" : '.*gcc$' > /dev/null; then
+    args=""
+    while [ $# -gt 0 ]; do
+	if [ "$1" != "--" ]; then args="$args $1"; fi
+	shift
+    done
+    sed -e '/^# DO NOT DELETE.*/,$d' < Makefile > Makefile.tmp
+    echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' >> Makefile.tmp
+    ${MAKEDEPEND} -Werror -D OPENSSL_DOING_MAKEDEPEND -M $args >> Makefile.tmp || exit 1
+    ${PERL} $TOP/util/clean-depend.pl < Makefile.tmp > Makefile.new
+    RC=$?
+    rm -f Makefile.tmp
+else
+    ${MAKEDEPEND} -D OPENSSL_DOING_MAKEDEPEND $@ && \
+    ${PERL} $TOP/util/clean-depend.pl < Makefile > Makefile.new
+    RC=$?
+fi
+mv Makefile.new Makefile
+# unfake the presence of Kerberos
+rm $TOP/krb5.h
+
+exit $RC
diff --git a/openssl/util/err-ins.pl b/openssl/util/err-ins.pl
new file mode 100755
index 0000000..31b70df
--- /dev/null
+++ b/openssl/util/err-ins.pl
@@ -0,0 +1,33 @@
+#!/usr/local/bin/perl
+#
+# tack error codes onto the end of a file
+#
+
+open(ERR,$ARGV[0]) || die "unable to open error file '$ARGV[0]':$!\n";
+@err=<ERR>;
+close(ERR);
+
+open(IN,$ARGV[1]) || die "unable to open header file '$ARGV[1]':$!\n";
+
+@out="";
+while (<IN>)
+	{
+	push(@out,$_);
+	last if /BEGIN ERROR CODES/;
+	}
+close(IN);
+
+open(OUT,">$ARGV[1]") || die "unable to open header file '$ARGV[1]':$1\n";
+print OUT @out;
+print OUT @err;
+print OUT <<"EOF";
+ 
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
+EOF
+close(OUT);
+
+
diff --git a/openssl/util/extract-names.pl b/openssl/util/extract-names.pl
new file mode 100644
index 0000000..35bd6ed
--- /dev/null
+++ b/openssl/util/extract-names.pl
@@ -0,0 +1,26 @@
+#!/usr/bin/perl
+
+$/ = "";			# Eat a paragraph at once.
+while(<STDIN>) {
+    chop;
+    s/\n/ /gm;
+    if (/^=head1 /) {
+	$name = 0;
+    } elsif ($name) {
+	if (/ - /) {
+	    s/ - .*//;
+	    s/,\s+/,/g;
+	    s/\s+,/,/g;
+	    s/^\s+//g;
+	    s/\s+$//g;
+	    s/\s/_/g;
+	    push @words, split ',';
+	}
+    }
+    if (/^=head1 *NAME *$/) {
+	$name = 1;
+    }
+}
+
+print join("\n", @words),"\n";
+
diff --git a/openssl/util/extract-section.pl b/openssl/util/extract-section.pl
new file mode 100644
index 0000000..7a0ba4f
--- /dev/null
+++ b/openssl/util/extract-section.pl
@@ -0,0 +1,12 @@
+#!/usr/bin/perl
+
+while(<STDIN>) {
+	if (/=for\s+comment\s+openssl_manual_section:(\S+)/)
+		{
+		print "$1\n";
+		exit 0;
+		}
+}
+
+print "$ARGV[0]\n";
+
diff --git a/openssl/util/files.pl b/openssl/util/files.pl
new file mode 100755
index 0000000..41f033e
--- /dev/null
+++ b/openssl/util/files.pl
@@ -0,0 +1,61 @@
+#!/usr/local/bin/perl
+#
+# used to generate the file MINFO for use by util/mk1mf.pl
+# It is basically a list of all variables from the passed makefile
+#
+
+$s="";
+while (<>)
+	{
+	chop;
+	s/#.*//;
+	if (/^(\S+)\s*=\s*(.*)$/)
+		{
+		$o="";
+		($s,$b)=($1,$2);
+		for (;;)
+			{
+			if ($b =~ /\\$/)
+				{
+				chop($b);
+				$o.=$b." ";
+				$b=<>;
+				chop($b);
+				}
+			else
+				{
+				$o.=$b." ";
+				last;
+				}
+			}
+		$o =~ s/^\s+//;
+		$o =~ s/\s+$//;
+		$o =~ s/\s+/ /g;
+
+		$o =~ s/\$[({]([^)}]+)[)}]/$sym{$1}/g;
+		$sym{$s}=$o;
+		}
+	}
+
+$pwd=`pwd`; chop($pwd);
+
+if ($sym{'TOP'} eq ".")
+	{
+	$n=0;
+	$dir=".";
+	}
+else	{
+	$n=split(/\//,$sym{'TOP'});
+	@_=split(/\//,$pwd);
+	$z=$#_-$n+1;
+	foreach $i ($z .. $#_) { $dir.=$_[$i]."/"; }
+	chop($dir);
+	}
+
+print "RELATIVE_DIRECTORY=$dir\n";
+
+foreach (sort keys %sym)
+	{
+	print "$_=$sym{$_}\n";
+	}
+print "RELATIVE_DIRECTORY=\n";
diff --git a/openssl/util/fixNT.sh b/openssl/util/fixNT.sh
new file mode 100755
index 0000000..ab9e766
--- /dev/null
+++ b/openssl/util/fixNT.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# clean up the mess that NT makes of my source tree
+#
+
+if [ -f makefile -a ! -f Makefile ]; then
+	/bin/mv makefile Makefile
+fi
+chmod +x Configure util/*
+echo cleaning
+/bin/rm -f `find . -name '*.$$$' -print` 2>/dev/null >/dev/null
+echo 'removing those damn ^M'
+perl -pi -e 's/\015//' `find . -type 'f' -print |grep -v '.obj$' |grep -v '.der$' |grep -v '.gz'`
+make -f Makefile links
diff --git a/openssl/util/install.sh b/openssl/util/install.sh
new file mode 100755
index 0000000..e1d0c98
--- /dev/null
+++ b/openssl/util/install.sh
@@ -0,0 +1,108 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5; it is not part of GNU.
+#
+# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+doit="${DOITPROG:-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG:-mv}"
+cpprog="${CPPROG:-cp}"
+chmodprog="${CHMODPROG:-chmod}"
+chownprog="${CHOWNPROG:-chown}"
+chgrpprog="${CHGRPPROG:-chgrp}"
+stripprog="${STRIPPROG:-strip}"
+rmprog="${RMPROG:-rm}"
+
+instcmd="$mvprog"
+chmodcmd=""
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+src=""
+dst=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:  no input file specified"
+	exit 1
+fi
+
+if [ x"$dst" = x ]
+then
+	echo "install:  no destination specified"
+	exit 1
+fi
+
+
+# if destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+if [ -d $dst ]
+then
+	dst="$dst"/`basename $src`
+fi
+
+
+# get rid of the old one and mode the new one in
+
+$doit $rmcmd $dst
+$doit $instcmd $src $dst
+
+
+# and set any options; do chmod last to preserve setuid bits
+
+if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; fi
+if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; fi
+if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; fi
+if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; fi
+
+exit 0
diff --git a/openssl/util/libeay.num b/openssl/util/libeay.num
new file mode 100755
index 0000000..b23619f
--- /dev/null
+++ b/openssl/util/libeay.num
@@ -0,0 +1,4196 @@
+SSLeay                                  1	EXIST::FUNCTION:
+SSLeay_version                          2	EXIST::FUNCTION:
+ASN1_BIT_STRING_asn1_meth               3	NOEXIST::FUNCTION:
+ASN1_HEADER_free                        4	NOEXIST::FUNCTION:
+ASN1_HEADER_new                         5	NOEXIST::FUNCTION:
+ASN1_IA5STRING_asn1_meth                6	NOEXIST::FUNCTION:
+ASN1_INTEGER_get                        7	EXIST::FUNCTION:
+ASN1_INTEGER_set                        8	EXIST::FUNCTION:
+ASN1_INTEGER_to_BN                      9	EXIST::FUNCTION:
+ASN1_OBJECT_create                      10	EXIST::FUNCTION:
+ASN1_OBJECT_free                        11	EXIST::FUNCTION:
+ASN1_OBJECT_new                         12	EXIST::FUNCTION:
+ASN1_PRINTABLE_type                     13	EXIST::FUNCTION:
+ASN1_STRING_cmp                         14	EXIST::FUNCTION:
+ASN1_STRING_dup                         15	EXIST::FUNCTION:
+ASN1_STRING_free                        16	EXIST::FUNCTION:
+ASN1_STRING_new                         17	EXIST::FUNCTION:
+ASN1_STRING_print                       18	EXIST::FUNCTION:BIO
+ASN1_STRING_set                         19	EXIST::FUNCTION:
+ASN1_STRING_type_new                    20	EXIST::FUNCTION:
+ASN1_TYPE_free                          21	EXIST::FUNCTION:
+ASN1_TYPE_new                           22	EXIST::FUNCTION:
+ASN1_UNIVERSALSTRING_to_string          23	EXIST::FUNCTION:
+ASN1_UTCTIME_check                      24	EXIST::FUNCTION:
+ASN1_UTCTIME_print                      25	EXIST::FUNCTION:BIO
+ASN1_UTCTIME_set                        26	EXIST::FUNCTION:
+ASN1_check_infinite_end                 27	EXIST::FUNCTION:
+ASN1_d2i_bio                            28	EXIST::FUNCTION:BIO
+ASN1_d2i_fp                             29	EXIST::FUNCTION:FP_API
+ASN1_digest                             30	EXIST::FUNCTION:EVP
+ASN1_dup                                31	EXIST::FUNCTION:
+ASN1_get_object                         32	EXIST::FUNCTION:
+ASN1_i2d_bio                            33	EXIST::FUNCTION:BIO
+ASN1_i2d_fp                             34	EXIST::FUNCTION:FP_API
+ASN1_object_size                        35	EXIST::FUNCTION:
+ASN1_parse                              36	EXIST::FUNCTION:BIO
+ASN1_put_object                         37	EXIST::FUNCTION:
+ASN1_sign                               38	EXIST::FUNCTION:EVP
+ASN1_verify                             39	EXIST::FUNCTION:EVP
+BF_cbc_encrypt                          40	EXIST::FUNCTION:BF
+BF_cfb64_encrypt                        41	EXIST::FUNCTION:BF
+BF_ecb_encrypt                          42	EXIST::FUNCTION:BF
+BF_encrypt                              43	EXIST::FUNCTION:BF
+BF_ofb64_encrypt                        44	EXIST::FUNCTION:BF
+BF_options                              45	EXIST::FUNCTION:BF
+BF_set_key                              46	EXIST::FUNCTION:BF
+BIO_CONNECT_free                        47	NOEXIST::FUNCTION:
+BIO_CONNECT_new                         48	NOEXIST::FUNCTION:
+BIO_accept                              51	EXIST::FUNCTION:
+BIO_ctrl                                52	EXIST::FUNCTION:
+BIO_int_ctrl                            53	EXIST::FUNCTION:
+BIO_debug_callback                      54	EXIST::FUNCTION:
+BIO_dump                                55	EXIST::FUNCTION:
+BIO_dup_chain                           56	EXIST::FUNCTION:
+BIO_f_base64                            57	EXIST::FUNCTION:BIO
+BIO_f_buffer                            58	EXIST::FUNCTION:
+BIO_f_cipher                            59	EXIST::FUNCTION:BIO
+BIO_f_md                                60	EXIST::FUNCTION:BIO
+BIO_f_null                              61	EXIST::FUNCTION:
+BIO_f_proxy_server                      62	NOEXIST::FUNCTION:
+BIO_fd_non_fatal_error                  63	EXIST::FUNCTION:
+BIO_fd_should_retry                     64	EXIST::FUNCTION:
+BIO_find_type                           65	EXIST::FUNCTION:
+BIO_free                                66	EXIST::FUNCTION:
+BIO_free_all                            67	EXIST::FUNCTION:
+BIO_get_accept_socket                   69	EXIST::FUNCTION:
+BIO_get_filter_bio                      70	NOEXIST::FUNCTION:
+BIO_get_host_ip                         71	EXIST::FUNCTION:
+BIO_get_port                            72	EXIST::FUNCTION:
+BIO_get_retry_BIO                       73	EXIST::FUNCTION:
+BIO_get_retry_reason                    74	EXIST::FUNCTION:
+BIO_gethostbyname                       75	EXIST::FUNCTION:
+BIO_gets                                76	EXIST::FUNCTION:
+BIO_new                                 78	EXIST::FUNCTION:
+BIO_new_accept                          79	EXIST::FUNCTION:
+BIO_new_connect                         80	EXIST::FUNCTION:
+BIO_new_fd                              81	EXIST::FUNCTION:
+BIO_new_file                            82	EXIST::FUNCTION:FP_API
+BIO_new_fp                              83	EXIST::FUNCTION:FP_API
+BIO_new_socket                          84	EXIST::FUNCTION:
+BIO_pop                                 85	EXIST::FUNCTION:
+BIO_printf                              86	EXIST::FUNCTION:
+BIO_push                                87	EXIST::FUNCTION:
+BIO_puts                                88	EXIST::FUNCTION:
+BIO_read                                89	EXIST::FUNCTION:
+BIO_s_accept                            90	EXIST::FUNCTION:
+BIO_s_connect                           91	EXIST::FUNCTION:
+BIO_s_fd                                92	EXIST::FUNCTION:
+BIO_s_file                              93	EXIST::FUNCTION:FP_API
+BIO_s_mem                               95	EXIST::FUNCTION:
+BIO_s_null                              96	EXIST::FUNCTION:
+BIO_s_proxy_client                      97	NOEXIST::FUNCTION:
+BIO_s_socket                            98	EXIST::FUNCTION:
+BIO_set                                 100	EXIST::FUNCTION:
+BIO_set_cipher                          101	EXIST::FUNCTION:BIO
+BIO_set_tcp_ndelay                      102	EXIST::FUNCTION:
+BIO_sock_cleanup                        103	EXIST::FUNCTION:
+BIO_sock_error                          104	EXIST::FUNCTION:
+BIO_sock_init                           105	EXIST::FUNCTION:
+BIO_sock_non_fatal_error                106	EXIST::FUNCTION:
+BIO_sock_should_retry                   107	EXIST::FUNCTION:
+BIO_socket_ioctl                        108	EXIST::FUNCTION:
+BIO_write                               109	EXIST::FUNCTION:
+BN_CTX_free                             110	EXIST::FUNCTION:
+BN_CTX_new                              111	EXIST::FUNCTION:
+BN_MONT_CTX_free                        112	EXIST::FUNCTION:
+BN_MONT_CTX_new                         113	EXIST::FUNCTION:
+BN_MONT_CTX_set                         114	EXIST::FUNCTION:
+BN_add                                  115	EXIST::FUNCTION:
+BN_add_word                             116	EXIST::FUNCTION:
+BN_hex2bn                               117	EXIST::FUNCTION:
+BN_bin2bn                               118	EXIST::FUNCTION:
+BN_bn2hex                               119	EXIST::FUNCTION:
+BN_bn2bin                               120	EXIST::FUNCTION:
+BN_clear                                121	EXIST::FUNCTION:
+BN_clear_bit                            122	EXIST::FUNCTION:
+BN_clear_free                           123	EXIST::FUNCTION:
+BN_cmp                                  124	EXIST::FUNCTION:
+BN_copy                                 125	EXIST::FUNCTION:
+BN_div                                  126	EXIST::FUNCTION:
+BN_div_word                             127	EXIST::FUNCTION:
+BN_dup                                  128	EXIST::FUNCTION:
+BN_free                                 129	EXIST::FUNCTION:
+BN_from_montgomery                      130	EXIST::FUNCTION:
+BN_gcd                                  131	EXIST::FUNCTION:
+BN_generate_prime                       132	EXIST::FUNCTION:DEPRECATED
+BN_get_word                             133	EXIST::FUNCTION:
+BN_is_bit_set                           134	EXIST::FUNCTION:
+BN_is_prime                             135	EXIST::FUNCTION:DEPRECATED
+BN_lshift                               136	EXIST::FUNCTION:
+BN_lshift1                              137	EXIST::FUNCTION:
+BN_mask_bits                            138	EXIST::FUNCTION:
+BN_mod                                  139	NOEXIST::FUNCTION:
+BN_mod_exp                              140	EXIST::FUNCTION:
+BN_mod_exp_mont                         141	EXIST::FUNCTION:
+BN_mod_exp_simple                       143	EXIST::FUNCTION:
+BN_mod_inverse                          144	EXIST::FUNCTION:
+BN_mod_mul                              145	EXIST::FUNCTION:
+BN_mod_mul_montgomery                   146	EXIST::FUNCTION:
+BN_mod_word                             148	EXIST::FUNCTION:
+BN_mul                                  149	EXIST::FUNCTION:
+BN_new                                  150	EXIST::FUNCTION:
+BN_num_bits                             151	EXIST::FUNCTION:
+BN_num_bits_word                        152	EXIST::FUNCTION:
+BN_options                              153	EXIST::FUNCTION:
+BN_print                                154	EXIST::FUNCTION:
+BN_print_fp                             155	EXIST::FUNCTION:FP_API
+BN_rand                                 156	EXIST::FUNCTION:
+BN_reciprocal                           157	EXIST::FUNCTION:
+BN_rshift                               158	EXIST::FUNCTION:
+BN_rshift1                              159	EXIST::FUNCTION:
+BN_set_bit                              160	EXIST::FUNCTION:
+BN_set_word                             161	EXIST::FUNCTION:
+BN_sqr                                  162	EXIST::FUNCTION:
+BN_sub                                  163	EXIST::FUNCTION:
+BN_to_ASN1_INTEGER                      164	EXIST::FUNCTION:
+BN_ucmp                                 165	EXIST::FUNCTION:
+BN_value_one                            166	EXIST::FUNCTION:
+BUF_MEM_free                            167	EXIST::FUNCTION:
+BUF_MEM_grow                            168	EXIST::FUNCTION:
+BUF_MEM_new                             169	EXIST::FUNCTION:
+BUF_strdup                              170	EXIST::FUNCTION:
+CONF_free                               171	EXIST::FUNCTION:
+CONF_get_number                         172	EXIST::FUNCTION:
+CONF_get_section                        173	EXIST::FUNCTION:
+CONF_get_string                         174	EXIST::FUNCTION:
+CONF_load                               175	EXIST::FUNCTION:
+CRYPTO_add_lock                         176	EXIST::FUNCTION:
+CRYPTO_dbg_free                         177	EXIST::FUNCTION:
+CRYPTO_dbg_malloc                       178	EXIST::FUNCTION:
+CRYPTO_dbg_realloc                      179	EXIST::FUNCTION:
+CRYPTO_dbg_remalloc                     180	NOEXIST::FUNCTION:
+CRYPTO_free                             181	EXIST::FUNCTION:
+CRYPTO_get_add_lock_callback            182	EXIST::FUNCTION:
+CRYPTO_get_id_callback                  183	EXIST::FUNCTION:DEPRECATED
+CRYPTO_get_lock_name                    184	EXIST::FUNCTION:
+CRYPTO_get_locking_callback             185	EXIST::FUNCTION:
+CRYPTO_get_mem_functions                186	EXIST::FUNCTION:
+CRYPTO_lock                             187	EXIST::FUNCTION:
+CRYPTO_malloc                           188	EXIST::FUNCTION:
+CRYPTO_mem_ctrl                         189	EXIST::FUNCTION:
+CRYPTO_mem_leaks                        190	EXIST::FUNCTION:
+CRYPTO_mem_leaks_cb                     191	EXIST::FUNCTION:
+CRYPTO_mem_leaks_fp                     192	EXIST::FUNCTION:FP_API
+CRYPTO_realloc                          193	EXIST::FUNCTION:
+CRYPTO_remalloc                         194	EXIST::FUNCTION:
+CRYPTO_set_add_lock_callback            195	EXIST::FUNCTION:
+CRYPTO_set_id_callback                  196	EXIST::FUNCTION:DEPRECATED
+CRYPTO_set_locking_callback             197	EXIST::FUNCTION:
+CRYPTO_set_mem_functions                198	EXIST::FUNCTION:
+CRYPTO_thread_id                        199	EXIST::FUNCTION:DEPRECATED
+DH_check                                200	EXIST::FUNCTION:DH
+DH_compute_key                          201	EXIST::FUNCTION:DH
+DH_free                                 202	EXIST::FUNCTION:DH
+DH_generate_key                         203	EXIST::FUNCTION:DH
+DH_generate_parameters                  204	EXIST::FUNCTION:DEPRECATED,DH
+DH_new                                  205	EXIST::FUNCTION:DH
+DH_size                                 206	EXIST::FUNCTION:DH
+DHparams_print                          207	EXIST::FUNCTION:BIO,DH
+DHparams_print_fp                       208	EXIST::FUNCTION:DH,FP_API
+DSA_free                                209	EXIST::FUNCTION:DSA
+DSA_generate_key                        210	EXIST::FUNCTION:DSA
+DSA_generate_parameters                 211	EXIST::FUNCTION:DEPRECATED,DSA
+DSA_is_prime                            212	NOEXIST::FUNCTION:
+DSA_new                                 213	EXIST::FUNCTION:DSA
+DSA_print                               214	EXIST::FUNCTION:BIO,DSA
+DSA_print_fp                            215	EXIST::FUNCTION:DSA,FP_API
+DSA_sign                                216	EXIST::FUNCTION:DSA
+DSA_sign_setup                          217	EXIST::FUNCTION:DSA
+DSA_size                                218	EXIST::FUNCTION:DSA
+DSA_verify                              219	EXIST::FUNCTION:DSA
+DSAparams_print                         220	EXIST::FUNCTION:BIO,DSA
+DSAparams_print_fp                      221	EXIST::FUNCTION:DSA,FP_API
+ERR_clear_error                         222	EXIST::FUNCTION:
+ERR_error_string                        223	EXIST::FUNCTION:
+ERR_free_strings                        224	EXIST::FUNCTION:
+ERR_func_error_string                   225	EXIST::FUNCTION:
+ERR_get_err_state_table                 226	EXIST::FUNCTION:LHASH
+ERR_get_error                           227	EXIST::FUNCTION:
+ERR_get_error_line                      228	EXIST::FUNCTION:
+ERR_get_state                           229	EXIST::FUNCTION:
+ERR_get_string_table                    230	EXIST::FUNCTION:LHASH
+ERR_lib_error_string                    231	EXIST::FUNCTION:
+ERR_load_ASN1_strings                   232	EXIST::FUNCTION:
+ERR_load_BIO_strings                    233	EXIST::FUNCTION:
+ERR_load_BN_strings                     234	EXIST::FUNCTION:
+ERR_load_BUF_strings                    235	EXIST::FUNCTION:
+ERR_load_CONF_strings                   236	EXIST::FUNCTION:
+ERR_load_DH_strings                     237	EXIST::FUNCTION:DH
+ERR_load_DSA_strings                    238	EXIST::FUNCTION:DSA
+ERR_load_ERR_strings                    239	EXIST::FUNCTION:
+ERR_load_EVP_strings                    240	EXIST::FUNCTION:
+ERR_load_OBJ_strings                    241	EXIST::FUNCTION:
+ERR_load_PEM_strings                    242	EXIST::FUNCTION:
+ERR_load_PROXY_strings                  243	NOEXIST::FUNCTION:
+ERR_load_RSA_strings                    244	EXIST::FUNCTION:RSA
+ERR_load_X509_strings                   245	EXIST::FUNCTION:
+ERR_load_crypto_strings                 246	EXIST::FUNCTION:
+ERR_load_strings                        247	EXIST::FUNCTION:
+ERR_peek_error                          248	EXIST::FUNCTION:
+ERR_peek_error_line                     249	EXIST::FUNCTION:
+ERR_print_errors                        250	EXIST::FUNCTION:BIO
+ERR_print_errors_fp                     251	EXIST::FUNCTION:FP_API
+ERR_put_error                           252	EXIST::FUNCTION:
+ERR_reason_error_string                 253	EXIST::FUNCTION:
+ERR_remove_state                        254	EXIST::FUNCTION:DEPRECATED
+EVP_BytesToKey                          255	EXIST::FUNCTION:
+EVP_CIPHER_CTX_cleanup                  256	EXIST::FUNCTION:
+EVP_CipherFinal                         257	EXIST::FUNCTION:
+EVP_CipherInit                          258	EXIST::FUNCTION:
+EVP_CipherUpdate                        259	EXIST::FUNCTION:
+EVP_DecodeBlock                         260	EXIST::FUNCTION:
+EVP_DecodeFinal                         261	EXIST::FUNCTION:
+EVP_DecodeInit                          262	EXIST::FUNCTION:
+EVP_DecodeUpdate                        263	EXIST::FUNCTION:
+EVP_DecryptFinal                        264	EXIST::FUNCTION:
+EVP_DecryptInit                         265	EXIST::FUNCTION:
+EVP_DecryptUpdate                       266	EXIST::FUNCTION:
+EVP_DigestFinal                         267	EXIST::FUNCTION:
+EVP_DigestInit                          268	EXIST::FUNCTION:
+EVP_DigestUpdate                        269	EXIST::FUNCTION:
+EVP_EncodeBlock                         270	EXIST::FUNCTION:
+EVP_EncodeFinal                         271	EXIST::FUNCTION:
+EVP_EncodeInit                          272	EXIST::FUNCTION:
+EVP_EncodeUpdate                        273	EXIST::FUNCTION:
+EVP_EncryptFinal                        274	EXIST::FUNCTION:
+EVP_EncryptInit                         275	EXIST::FUNCTION:
+EVP_EncryptUpdate                       276	EXIST::FUNCTION:
+EVP_OpenFinal                           277	EXIST::FUNCTION:RSA
+EVP_OpenInit                            278	EXIST::FUNCTION:RSA
+EVP_PKEY_assign                         279	EXIST::FUNCTION:
+EVP_PKEY_copy_parameters                280	EXIST::FUNCTION:
+EVP_PKEY_free                           281	EXIST::FUNCTION:
+EVP_PKEY_missing_parameters             282	EXIST::FUNCTION:
+EVP_PKEY_new                            283	EXIST::FUNCTION:
+EVP_PKEY_save_parameters                284	EXIST::FUNCTION:
+EVP_PKEY_size                           285	EXIST::FUNCTION:
+EVP_PKEY_type                           286	EXIST::FUNCTION:
+EVP_SealFinal                           287	EXIST::FUNCTION:RSA
+EVP_SealInit                            288	EXIST::FUNCTION:RSA
+EVP_SignFinal                           289	EXIST::FUNCTION:
+EVP_VerifyFinal                         290	EXIST::FUNCTION:
+EVP_add_alias                           291	NOEXIST::FUNCTION:
+EVP_add_cipher                          292	EXIST::FUNCTION:
+EVP_add_digest                          293	EXIST::FUNCTION:
+EVP_bf_cbc                              294	EXIST::FUNCTION:BF
+EVP_bf_cfb64                            295	EXIST::FUNCTION:BF
+EVP_bf_ecb                              296	EXIST::FUNCTION:BF
+EVP_bf_ofb                              297	EXIST::FUNCTION:BF
+EVP_cleanup                             298	EXIST::FUNCTION:
+EVP_des_cbc                             299	EXIST::FUNCTION:DES
+EVP_des_cfb64                           300	EXIST::FUNCTION:DES
+EVP_des_ecb                             301	EXIST::FUNCTION:DES
+EVP_des_ede                             302	EXIST::FUNCTION:DES
+EVP_des_ede3                            303	EXIST::FUNCTION:DES
+EVP_des_ede3_cbc                        304	EXIST::FUNCTION:DES
+EVP_des_ede3_cfb64                      305	EXIST::FUNCTION:DES
+EVP_des_ede3_ofb                        306	EXIST::FUNCTION:DES
+EVP_des_ede_cbc                         307	EXIST::FUNCTION:DES
+EVP_des_ede_cfb64                       308	EXIST::FUNCTION:DES
+EVP_des_ede_ofb                         309	EXIST::FUNCTION:DES
+EVP_des_ofb                             310	EXIST::FUNCTION:DES
+EVP_desx_cbc                            311	EXIST::FUNCTION:DES
+EVP_dss                                 312	EXIST::FUNCTION:DSA,SHA
+EVP_dss1                                313	EXIST::FUNCTION:DSA,SHA
+EVP_enc_null                            314	EXIST::FUNCTION:
+EVP_get_cipherbyname                    315	EXIST::FUNCTION:
+EVP_get_digestbyname                    316	EXIST::FUNCTION:
+EVP_get_pw_prompt                       317	EXIST::FUNCTION:
+EVP_idea_cbc                            318	EXIST::FUNCTION:IDEA
+EVP_idea_cfb64                          319	EXIST::FUNCTION:IDEA
+EVP_idea_ecb                            320	EXIST::FUNCTION:IDEA
+EVP_idea_ofb                            321	EXIST::FUNCTION:IDEA
+EVP_md2                                 322	EXIST::FUNCTION:MD2
+EVP_md5                                 323	EXIST::FUNCTION:MD5
+EVP_md_null                             324	EXIST::FUNCTION:
+EVP_rc2_cbc                             325	EXIST::FUNCTION:RC2
+EVP_rc2_cfb64                           326	EXIST::FUNCTION:RC2
+EVP_rc2_ecb                             327	EXIST::FUNCTION:RC2
+EVP_rc2_ofb                             328	EXIST::FUNCTION:RC2
+EVP_rc4                                 329	EXIST::FUNCTION:RC4
+EVP_read_pw_string                      330	EXIST::FUNCTION:
+EVP_set_pw_prompt                       331	EXIST::FUNCTION:
+EVP_sha                                 332	EXIST::FUNCTION:SHA
+EVP_sha1                                333	EXIST::FUNCTION:SHA
+MD2                                     334	EXIST::FUNCTION:MD2
+MD2_Final                               335	EXIST::FUNCTION:MD2
+MD2_Init                                336	EXIST::FUNCTION:MD2
+MD2_Update                              337	EXIST::FUNCTION:MD2
+MD2_options                             338	EXIST::FUNCTION:MD2
+MD5                                     339	EXIST::FUNCTION:MD5
+MD5_Final                               340	EXIST::FUNCTION:MD5
+MD5_Init                                341	EXIST::FUNCTION:MD5
+MD5_Update                              342	EXIST::FUNCTION:MD5
+MDC2                                    343	EXIST::FUNCTION:MDC2
+MDC2_Final                              344	EXIST::FUNCTION:MDC2
+MDC2_Init                               345	EXIST::FUNCTION:MDC2
+MDC2_Update                             346	EXIST::FUNCTION:MDC2
+NETSCAPE_SPKAC_free                     347	EXIST::FUNCTION:
+NETSCAPE_SPKAC_new                      348	EXIST::FUNCTION:
+NETSCAPE_SPKI_free                      349	EXIST::FUNCTION:
+NETSCAPE_SPKI_new                       350	EXIST::FUNCTION:
+NETSCAPE_SPKI_sign                      351	EXIST::FUNCTION:EVP
+NETSCAPE_SPKI_verify                    352	EXIST::FUNCTION:EVP
+OBJ_add_object                          353	EXIST::FUNCTION:
+OBJ_bsearch                             354	NOEXIST::FUNCTION:
+OBJ_cleanup                             355	EXIST::FUNCTION:
+OBJ_cmp                                 356	EXIST::FUNCTION:
+OBJ_create                              357	EXIST::FUNCTION:
+OBJ_dup                                 358	EXIST::FUNCTION:
+OBJ_ln2nid                              359	EXIST::FUNCTION:
+OBJ_new_nid                             360	EXIST::FUNCTION:
+OBJ_nid2ln                              361	EXIST::FUNCTION:
+OBJ_nid2obj                             362	EXIST::FUNCTION:
+OBJ_nid2sn                              363	EXIST::FUNCTION:
+OBJ_obj2nid                             364	EXIST::FUNCTION:
+OBJ_sn2nid                              365	EXIST::FUNCTION:
+OBJ_txt2nid                             366	EXIST::FUNCTION:
+PEM_ASN1_read                           367	EXIST::FUNCTION:
+PEM_ASN1_read_bio                       368	EXIST::FUNCTION:BIO
+PEM_ASN1_write                          369	EXIST::FUNCTION:
+PEM_ASN1_write_bio                      370	EXIST::FUNCTION:BIO
+PEM_SealFinal                           371	EXIST::FUNCTION:RSA
+PEM_SealInit                            372	EXIST::FUNCTION:RSA
+PEM_SealUpdate                          373	EXIST::FUNCTION:RSA
+PEM_SignFinal                           374	EXIST::FUNCTION:
+PEM_SignInit                            375	EXIST::FUNCTION:
+PEM_SignUpdate                          376	EXIST::FUNCTION:
+PEM_X509_INFO_read                      377	EXIST::FUNCTION:
+PEM_X509_INFO_read_bio                  378	EXIST::FUNCTION:BIO
+PEM_X509_INFO_write_bio                 379	EXIST::FUNCTION:BIO
+PEM_dek_info                            380	EXIST::FUNCTION:
+PEM_do_header                           381	EXIST::FUNCTION:
+PEM_get_EVP_CIPHER_INFO                 382	EXIST::FUNCTION:
+PEM_proc_type                           383	EXIST::FUNCTION:
+PEM_read                                384	EXIST::FUNCTION:
+PEM_read_DHparams                       385	EXIST:!WIN16:FUNCTION:DH
+PEM_read_DSAPrivateKey                  386	EXIST:!WIN16:FUNCTION:DSA
+PEM_read_DSAparams                      387	EXIST:!WIN16:FUNCTION:DSA
+PEM_read_PKCS7                          388	EXIST:!WIN16:FUNCTION:
+PEM_read_PrivateKey                     389	EXIST:!WIN16:FUNCTION:
+PEM_read_RSAPrivateKey                  390	EXIST:!WIN16:FUNCTION:RSA
+PEM_read_X509                           391	EXIST:!WIN16:FUNCTION:
+PEM_read_X509_CRL                       392	EXIST:!WIN16:FUNCTION:
+PEM_read_X509_REQ                       393	EXIST:!WIN16:FUNCTION:
+PEM_read_bio                            394	EXIST::FUNCTION:BIO
+PEM_read_bio_DHparams                   395	EXIST::FUNCTION:DH
+PEM_read_bio_DSAPrivateKey              396	EXIST::FUNCTION:DSA
+PEM_read_bio_DSAparams                  397	EXIST::FUNCTION:DSA
+PEM_read_bio_PKCS7                      398	EXIST::FUNCTION:
+PEM_read_bio_PrivateKey                 399	EXIST::FUNCTION:
+PEM_read_bio_RSAPrivateKey              400	EXIST::FUNCTION:RSA
+PEM_read_bio_X509                       401	EXIST::FUNCTION:
+PEM_read_bio_X509_CRL                   402	EXIST::FUNCTION:
+PEM_read_bio_X509_REQ                   403	EXIST::FUNCTION:
+PEM_write                               404	EXIST::FUNCTION:
+PEM_write_DHparams                      405	EXIST:!WIN16:FUNCTION:DH
+PEM_write_DSAPrivateKey                 406	EXIST:!WIN16:FUNCTION:DSA
+PEM_write_DSAparams                     407	EXIST:!WIN16:FUNCTION:DSA
+PEM_write_PKCS7                         408	EXIST:!WIN16:FUNCTION:
+PEM_write_PrivateKey                    409	EXIST:!WIN16:FUNCTION:
+PEM_write_RSAPrivateKey                 410	EXIST:!WIN16:FUNCTION:RSA
+PEM_write_X509                          411	EXIST:!WIN16:FUNCTION:
+PEM_write_X509_CRL                      412	EXIST:!WIN16:FUNCTION:
+PEM_write_X509_REQ                      413	EXIST:!WIN16:FUNCTION:
+PEM_write_bio                           414	EXIST::FUNCTION:BIO
+PEM_write_bio_DHparams                  415	EXIST::FUNCTION:DH
+PEM_write_bio_DSAPrivateKey             416	EXIST::FUNCTION:DSA
+PEM_write_bio_DSAparams                 417	EXIST::FUNCTION:DSA
+PEM_write_bio_PKCS7                     418	EXIST::FUNCTION:
+PEM_write_bio_PrivateKey                419	EXIST::FUNCTION:
+PEM_write_bio_RSAPrivateKey             420	EXIST::FUNCTION:RSA
+PEM_write_bio_X509                      421	EXIST::FUNCTION:
+PEM_write_bio_X509_CRL                  422	EXIST::FUNCTION:
+PEM_write_bio_X509_REQ                  423	EXIST::FUNCTION:
+PKCS7_DIGEST_free                       424	EXIST::FUNCTION:
+PKCS7_DIGEST_new                        425	EXIST::FUNCTION:
+PKCS7_ENCRYPT_free                      426	EXIST::FUNCTION:
+PKCS7_ENCRYPT_new                       427	EXIST::FUNCTION:
+PKCS7_ENC_CONTENT_free                  428	EXIST::FUNCTION:
+PKCS7_ENC_CONTENT_new                   429	EXIST::FUNCTION:
+PKCS7_ENVELOPE_free                     430	EXIST::FUNCTION:
+PKCS7_ENVELOPE_new                      431	EXIST::FUNCTION:
+PKCS7_ISSUER_AND_SERIAL_digest          432	EXIST::FUNCTION:
+PKCS7_ISSUER_AND_SERIAL_free            433	EXIST::FUNCTION:
+PKCS7_ISSUER_AND_SERIAL_new             434	EXIST::FUNCTION:
+PKCS7_RECIP_INFO_free                   435	EXIST::FUNCTION:
+PKCS7_RECIP_INFO_new                    436	EXIST::FUNCTION:
+PKCS7_SIGNED_free                       437	EXIST::FUNCTION:
+PKCS7_SIGNED_new                        438	EXIST::FUNCTION:
+PKCS7_SIGNER_INFO_free                  439	EXIST::FUNCTION:
+PKCS7_SIGNER_INFO_new                   440	EXIST::FUNCTION:
+PKCS7_SIGN_ENVELOPE_free                441	EXIST::FUNCTION:
+PKCS7_SIGN_ENVELOPE_new                 442	EXIST::FUNCTION:
+PKCS7_dup                               443	EXIST::FUNCTION:
+PKCS7_free                              444	EXIST::FUNCTION:
+PKCS7_new                               445	EXIST::FUNCTION:
+PROXY_ENTRY_add_noproxy                 446	NOEXIST::FUNCTION:
+PROXY_ENTRY_clear_noproxy               447	NOEXIST::FUNCTION:
+PROXY_ENTRY_free                        448	NOEXIST::FUNCTION:
+PROXY_ENTRY_get_noproxy                 449	NOEXIST::FUNCTION:
+PROXY_ENTRY_new                         450	NOEXIST::FUNCTION:
+PROXY_ENTRY_set_server                  451	NOEXIST::FUNCTION:
+PROXY_add_noproxy                       452	NOEXIST::FUNCTION:
+PROXY_add_server                        453	NOEXIST::FUNCTION:
+PROXY_check_by_host                     454	NOEXIST::FUNCTION:
+PROXY_check_url                         455	NOEXIST::FUNCTION:
+PROXY_clear_noproxy                     456	NOEXIST::FUNCTION:
+PROXY_free                              457	NOEXIST::FUNCTION:
+PROXY_get_noproxy                       458	NOEXIST::FUNCTION:
+PROXY_get_proxies                       459	NOEXIST::FUNCTION:
+PROXY_get_proxy_entry                   460	NOEXIST::FUNCTION:
+PROXY_load_conf                         461	NOEXIST::FUNCTION:
+PROXY_new                               462	NOEXIST::FUNCTION:
+PROXY_print                             463	NOEXIST::FUNCTION:
+RAND_bytes                              464	EXIST::FUNCTION:
+RAND_cleanup                            465	EXIST::FUNCTION:
+RAND_file_name                          466	EXIST::FUNCTION:
+RAND_load_file                          467	EXIST::FUNCTION:
+RAND_screen                             468	EXIST:WIN32:FUNCTION:
+RAND_seed                               469	EXIST::FUNCTION:
+RAND_write_file                         470	EXIST::FUNCTION:
+RC2_cbc_encrypt                         471	EXIST::FUNCTION:RC2
+RC2_cfb64_encrypt                       472	EXIST::FUNCTION:RC2
+RC2_ecb_encrypt                         473	EXIST::FUNCTION:RC2
+RC2_encrypt                             474	EXIST::FUNCTION:RC2
+RC2_ofb64_encrypt                       475	EXIST::FUNCTION:RC2
+RC2_set_key                             476	EXIST::FUNCTION:RC2
+RC4                                     477	EXIST::FUNCTION:RC4
+RC4_options                             478	EXIST::FUNCTION:RC4
+RC4_set_key                             479	EXIST::FUNCTION:RC4
+RSAPrivateKey_asn1_meth                 480	NOEXIST::FUNCTION:
+RSAPrivateKey_dup                       481	EXIST::FUNCTION:RSA
+RSAPublicKey_dup                        482	EXIST::FUNCTION:RSA
+RSA_PKCS1_SSLeay                        483	EXIST::FUNCTION:RSA
+RSA_free                                484	EXIST::FUNCTION:RSA
+RSA_generate_key                        485	EXIST::FUNCTION:DEPRECATED,RSA
+RSA_new                                 486	EXIST::FUNCTION:RSA
+RSA_new_method                          487	EXIST::FUNCTION:RSA
+RSA_print                               488	EXIST::FUNCTION:BIO,RSA
+RSA_print_fp                            489	EXIST::FUNCTION:FP_API,RSA
+RSA_private_decrypt                     490	EXIST::FUNCTION:RSA
+RSA_private_encrypt                     491	EXIST::FUNCTION:RSA
+RSA_public_decrypt                      492	EXIST::FUNCTION:RSA
+RSA_public_encrypt                      493	EXIST::FUNCTION:RSA
+RSA_set_default_method                  494	EXIST::FUNCTION:RSA
+RSA_sign                                495	EXIST::FUNCTION:RSA
+RSA_sign_ASN1_OCTET_STRING              496	EXIST::FUNCTION:RSA
+RSA_size                                497	EXIST::FUNCTION:RSA
+RSA_verify                              498	EXIST::FUNCTION:RSA
+RSA_verify_ASN1_OCTET_STRING            499	EXIST::FUNCTION:RSA
+SHA                                     500	EXIST::FUNCTION:SHA,SHA0
+SHA1                                    501	EXIST::FUNCTION:SHA,SHA1
+SHA1_Final                              502	EXIST::FUNCTION:SHA,SHA1
+SHA1_Init                               503	EXIST::FUNCTION:SHA,SHA1
+SHA1_Update                             504	EXIST::FUNCTION:SHA,SHA1
+SHA_Final                               505	EXIST::FUNCTION:SHA,SHA0
+SHA_Init                                506	EXIST::FUNCTION:SHA,SHA0
+SHA_Update                              507	EXIST::FUNCTION:SHA,SHA0
+OpenSSL_add_all_algorithms              508	NOEXIST::FUNCTION:
+OpenSSL_add_all_ciphers                 509	EXIST::FUNCTION:
+OpenSSL_add_all_digests                 510	EXIST::FUNCTION:
+TXT_DB_create_index                     511	EXIST::FUNCTION:
+TXT_DB_free                             512	EXIST::FUNCTION:
+TXT_DB_get_by_index                     513	EXIST::FUNCTION:
+TXT_DB_insert                           514	EXIST::FUNCTION:
+TXT_DB_read                             515	EXIST::FUNCTION:BIO
+TXT_DB_write                            516	EXIST::FUNCTION:BIO
+X509_ALGOR_free                         517	EXIST::FUNCTION:
+X509_ALGOR_new                          518	EXIST::FUNCTION:
+X509_ATTRIBUTE_free                     519	EXIST::FUNCTION:
+X509_ATTRIBUTE_new                      520	EXIST::FUNCTION:
+X509_CINF_free                          521	EXIST::FUNCTION:
+X509_CINF_new                           522	EXIST::FUNCTION:
+X509_CRL_INFO_free                      523	EXIST::FUNCTION:
+X509_CRL_INFO_new                       524	EXIST::FUNCTION:
+X509_CRL_add_ext                        525	EXIST::FUNCTION:
+X509_CRL_cmp                            526	EXIST::FUNCTION:
+X509_CRL_delete_ext                     527	EXIST::FUNCTION:
+X509_CRL_dup                            528	EXIST::FUNCTION:
+X509_CRL_free                           529	EXIST::FUNCTION:
+X509_CRL_get_ext                        530	EXIST::FUNCTION:
+X509_CRL_get_ext_by_NID                 531	EXIST::FUNCTION:
+X509_CRL_get_ext_by_OBJ                 532	EXIST::FUNCTION:
+X509_CRL_get_ext_by_critical            533	EXIST::FUNCTION:
+X509_CRL_get_ext_count                  534	EXIST::FUNCTION:
+X509_CRL_new                            535	EXIST::FUNCTION:
+X509_CRL_sign                           536	EXIST::FUNCTION:EVP
+X509_CRL_verify                         537	EXIST::FUNCTION:EVP
+X509_EXTENSION_create_by_NID            538	EXIST::FUNCTION:
+X509_EXTENSION_create_by_OBJ            539	EXIST::FUNCTION:
+X509_EXTENSION_dup                      540	EXIST::FUNCTION:
+X509_EXTENSION_free                     541	EXIST::FUNCTION:
+X509_EXTENSION_get_critical             542	EXIST::FUNCTION:
+X509_EXTENSION_get_data                 543	EXIST::FUNCTION:
+X509_EXTENSION_get_object               544	EXIST::FUNCTION:
+X509_EXTENSION_new                      545	EXIST::FUNCTION:
+X509_EXTENSION_set_critical             546	EXIST::FUNCTION:
+X509_EXTENSION_set_data                 547	EXIST::FUNCTION:
+X509_EXTENSION_set_object               548	EXIST::FUNCTION:
+X509_INFO_free                          549	EXIST::FUNCTION:EVP
+X509_INFO_new                           550	EXIST::FUNCTION:EVP
+X509_LOOKUP_by_alias                    551	EXIST::FUNCTION:
+X509_LOOKUP_by_fingerprint              552	EXIST::FUNCTION:
+X509_LOOKUP_by_issuer_serial            553	EXIST::FUNCTION:
+X509_LOOKUP_by_subject                  554	EXIST::FUNCTION:
+X509_LOOKUP_ctrl                        555	EXIST::FUNCTION:
+X509_LOOKUP_file                        556	EXIST::FUNCTION:
+X509_LOOKUP_free                        557	EXIST::FUNCTION:
+X509_LOOKUP_hash_dir                    558	EXIST::FUNCTION:
+X509_LOOKUP_init                        559	EXIST::FUNCTION:
+X509_LOOKUP_new                         560	EXIST::FUNCTION:
+X509_LOOKUP_shutdown                    561	EXIST::FUNCTION:
+X509_NAME_ENTRY_create_by_NID           562	EXIST::FUNCTION:
+X509_NAME_ENTRY_create_by_OBJ           563	EXIST::FUNCTION:
+X509_NAME_ENTRY_dup                     564	EXIST::FUNCTION:
+X509_NAME_ENTRY_free                    565	EXIST::FUNCTION:
+X509_NAME_ENTRY_get_data                566	EXIST::FUNCTION:
+X509_NAME_ENTRY_get_object              567	EXIST::FUNCTION:
+X509_NAME_ENTRY_new                     568	EXIST::FUNCTION:
+X509_NAME_ENTRY_set_data                569	EXIST::FUNCTION:
+X509_NAME_ENTRY_set_object              570	EXIST::FUNCTION:
+X509_NAME_add_entry                     571	EXIST::FUNCTION:
+X509_NAME_cmp                           572	EXIST::FUNCTION:
+X509_NAME_delete_entry                  573	EXIST::FUNCTION:
+X509_NAME_digest                        574	EXIST::FUNCTION:EVP
+X509_NAME_dup                           575	EXIST::FUNCTION:
+X509_NAME_entry_count                   576	EXIST::FUNCTION:
+X509_NAME_free                          577	EXIST::FUNCTION:
+X509_NAME_get_entry                     578	EXIST::FUNCTION:
+X509_NAME_get_index_by_NID              579	EXIST::FUNCTION:
+X509_NAME_get_index_by_OBJ              580	EXIST::FUNCTION:
+X509_NAME_get_text_by_NID               581	EXIST::FUNCTION:
+X509_NAME_get_text_by_OBJ               582	EXIST::FUNCTION:
+X509_NAME_hash                          583	EXIST::FUNCTION:
+X509_NAME_new                           584	EXIST::FUNCTION:
+X509_NAME_oneline                       585	EXIST::FUNCTION:EVP
+X509_NAME_print                         586	EXIST::FUNCTION:BIO
+X509_NAME_set                           587	EXIST::FUNCTION:
+X509_OBJECT_free_contents               588	EXIST::FUNCTION:
+X509_OBJECT_retrieve_by_subject         589	EXIST::FUNCTION:
+X509_OBJECT_up_ref_count                590	EXIST::FUNCTION:
+X509_PKEY_free                          591	EXIST::FUNCTION:
+X509_PKEY_new                           592	EXIST::FUNCTION:
+X509_PUBKEY_free                        593	EXIST::FUNCTION:
+X509_PUBKEY_get                         594	EXIST::FUNCTION:
+X509_PUBKEY_new                         595	EXIST::FUNCTION:
+X509_PUBKEY_set                         596	EXIST::FUNCTION:
+X509_REQ_INFO_free                      597	EXIST::FUNCTION:
+X509_REQ_INFO_new                       598	EXIST::FUNCTION:
+X509_REQ_dup                            599	EXIST::FUNCTION:
+X509_REQ_free                           600	EXIST::FUNCTION:
+X509_REQ_get_pubkey                     601	EXIST::FUNCTION:
+X509_REQ_new                            602	EXIST::FUNCTION:
+X509_REQ_print                          603	EXIST::FUNCTION:BIO
+X509_REQ_print_fp                       604	EXIST::FUNCTION:FP_API
+X509_REQ_set_pubkey                     605	EXIST::FUNCTION:
+X509_REQ_set_subject_name               606	EXIST::FUNCTION:
+X509_REQ_set_version                    607	EXIST::FUNCTION:
+X509_REQ_sign                           608	EXIST::FUNCTION:EVP
+X509_REQ_to_X509                        609	EXIST::FUNCTION:
+X509_REQ_verify                         610	EXIST::FUNCTION:EVP
+X509_REVOKED_add_ext                    611	EXIST::FUNCTION:
+X509_REVOKED_delete_ext                 612	EXIST::FUNCTION:
+X509_REVOKED_free                       613	EXIST::FUNCTION:
+X509_REVOKED_get_ext                    614	EXIST::FUNCTION:
+X509_REVOKED_get_ext_by_NID             615	EXIST::FUNCTION:
+X509_REVOKED_get_ext_by_OBJ             616	EXIST::FUNCTION:
+X509_REVOKED_get_ext_by_critical        617	EXIST:!VMS:FUNCTION:
+X509_REVOKED_get_ext_by_critic          617	EXIST:VMS:FUNCTION:
+X509_REVOKED_get_ext_count              618	EXIST::FUNCTION:
+X509_REVOKED_new                        619	EXIST::FUNCTION:
+X509_SIG_free                           620	EXIST::FUNCTION:
+X509_SIG_new                            621	EXIST::FUNCTION:
+X509_STORE_CTX_cleanup                  622	EXIST::FUNCTION:
+X509_STORE_CTX_init                     623	EXIST::FUNCTION:
+X509_STORE_add_cert                     624	EXIST::FUNCTION:
+X509_STORE_add_lookup                   625	EXIST::FUNCTION:
+X509_STORE_free                         626	EXIST::FUNCTION:
+X509_STORE_get_by_subject               627	EXIST::FUNCTION:
+X509_STORE_load_locations               628	EXIST::FUNCTION:STDIO
+X509_STORE_new                          629	EXIST::FUNCTION:
+X509_STORE_set_default_paths            630	EXIST::FUNCTION:STDIO
+X509_VAL_free                           631	EXIST::FUNCTION:
+X509_VAL_new                            632	EXIST::FUNCTION:
+X509_add_ext                            633	EXIST::FUNCTION:
+X509_asn1_meth                          634	NOEXIST::FUNCTION:
+X509_certificate_type                   635	EXIST::FUNCTION:
+X509_check_private_key                  636	EXIST::FUNCTION:
+X509_cmp_current_time                   637	EXIST::FUNCTION:
+X509_delete_ext                         638	EXIST::FUNCTION:
+X509_digest                             639	EXIST::FUNCTION:EVP
+X509_dup                                640	EXIST::FUNCTION:
+X509_free                               641	EXIST::FUNCTION:
+X509_get_default_cert_area              642	EXIST::FUNCTION:
+X509_get_default_cert_dir               643	EXIST::FUNCTION:
+X509_get_default_cert_dir_env           644	EXIST::FUNCTION:
+X509_get_default_cert_file              645	EXIST::FUNCTION:
+X509_get_default_cert_file_env          646	EXIST::FUNCTION:
+X509_get_default_private_dir            647	EXIST::FUNCTION:
+X509_get_ext                            648	EXIST::FUNCTION:
+X509_get_ext_by_NID                     649	EXIST::FUNCTION:
+X509_get_ext_by_OBJ                     650	EXIST::FUNCTION:
+X509_get_ext_by_critical                651	EXIST::FUNCTION:
+X509_get_ext_count                      652	EXIST::FUNCTION:
+X509_get_issuer_name                    653	EXIST::FUNCTION:
+X509_get_pubkey                         654	EXIST::FUNCTION:
+X509_get_pubkey_parameters              655	EXIST::FUNCTION:
+X509_get_serialNumber                   656	EXIST::FUNCTION:
+X509_get_subject_name                   657	EXIST::FUNCTION:
+X509_gmtime_adj                         658	EXIST::FUNCTION:
+X509_issuer_and_serial_cmp              659	EXIST::FUNCTION:
+X509_issuer_and_serial_hash             660	EXIST::FUNCTION:
+X509_issuer_name_cmp                    661	EXIST::FUNCTION:
+X509_issuer_name_hash                   662	EXIST::FUNCTION:
+X509_load_cert_file                     663	EXIST::FUNCTION:STDIO
+X509_new                                664	EXIST::FUNCTION:
+X509_print                              665	EXIST::FUNCTION:BIO
+X509_print_fp                           666	EXIST::FUNCTION:FP_API
+X509_set_issuer_name                    667	EXIST::FUNCTION:
+X509_set_notAfter                       668	EXIST::FUNCTION:
+X509_set_notBefore                      669	EXIST::FUNCTION:
+X509_set_pubkey                         670	EXIST::FUNCTION:
+X509_set_serialNumber                   671	EXIST::FUNCTION:
+X509_set_subject_name                   672	EXIST::FUNCTION:
+X509_set_version                        673	EXIST::FUNCTION:
+X509_sign                               674	EXIST::FUNCTION:EVP
+X509_subject_name_cmp                   675	EXIST::FUNCTION:
+X509_subject_name_hash                  676	EXIST::FUNCTION:
+X509_to_X509_REQ                        677	EXIST::FUNCTION:
+X509_verify                             678	EXIST::FUNCTION:EVP
+X509_verify_cert                        679	EXIST::FUNCTION:
+X509_verify_cert_error_string           680	EXIST::FUNCTION:
+X509v3_add_ext                          681	EXIST::FUNCTION:
+X509v3_add_extension                    682	NOEXIST::FUNCTION:
+X509v3_add_netscape_extensions          683	NOEXIST::FUNCTION:
+X509v3_add_standard_extensions          684	NOEXIST::FUNCTION:
+X509v3_cleanup_extensions               685	NOEXIST::FUNCTION:
+X509v3_data_type_by_NID                 686	NOEXIST::FUNCTION:
+X509v3_data_type_by_OBJ                 687	NOEXIST::FUNCTION:
+X509v3_delete_ext                       688	EXIST::FUNCTION:
+X509v3_get_ext                          689	EXIST::FUNCTION:
+X509v3_get_ext_by_NID                   690	EXIST::FUNCTION:
+X509v3_get_ext_by_OBJ                   691	EXIST::FUNCTION:
+X509v3_get_ext_by_critical              692	EXIST::FUNCTION:
+X509v3_get_ext_count                    693	EXIST::FUNCTION:
+X509v3_pack_string                      694	NOEXIST::FUNCTION:
+X509v3_pack_type_by_NID                 695	NOEXIST::FUNCTION:
+X509v3_pack_type_by_OBJ                 696	NOEXIST::FUNCTION:
+X509v3_unpack_string                    697	NOEXIST::FUNCTION:
+_des_crypt                              698	NOEXIST::FUNCTION:
+a2d_ASN1_OBJECT                         699	EXIST::FUNCTION:
+a2i_ASN1_INTEGER                        700	EXIST::FUNCTION:BIO
+a2i_ASN1_STRING                         701	EXIST::FUNCTION:BIO
+asn1_Finish                             702	EXIST::FUNCTION:
+asn1_GetSequence                        703	EXIST::FUNCTION:
+bn_div_words                            704	EXIST::FUNCTION:
+bn_expand2                              705	EXIST::FUNCTION:
+bn_mul_add_words                        706	EXIST::FUNCTION:
+bn_mul_words                            707	EXIST::FUNCTION:
+BN_uadd                                 708	EXIST::FUNCTION:
+BN_usub                                 709	EXIST::FUNCTION:
+bn_sqr_words                            710	EXIST::FUNCTION:
+_ossl_old_crypt                         711	EXIST:!NeXT,!PERL5:FUNCTION:DES
+d2i_ASN1_BIT_STRING                     712	EXIST::FUNCTION:
+d2i_ASN1_BOOLEAN                        713	EXIST::FUNCTION:
+d2i_ASN1_HEADER                         714	NOEXIST::FUNCTION:
+d2i_ASN1_IA5STRING                      715	EXIST::FUNCTION:
+d2i_ASN1_INTEGER                        716	EXIST::FUNCTION:
+d2i_ASN1_OBJECT                         717	EXIST::FUNCTION:
+d2i_ASN1_OCTET_STRING                   718	EXIST::FUNCTION:
+d2i_ASN1_PRINTABLE                      719	EXIST::FUNCTION:
+d2i_ASN1_PRINTABLESTRING                720	EXIST::FUNCTION:
+d2i_ASN1_SET                            721	EXIST::FUNCTION:
+d2i_ASN1_T61STRING                      722	EXIST::FUNCTION:
+d2i_ASN1_TYPE                           723	EXIST::FUNCTION:
+d2i_ASN1_UTCTIME                        724	EXIST::FUNCTION:
+d2i_ASN1_bytes                          725	EXIST::FUNCTION:
+d2i_ASN1_type_bytes                     726	EXIST::FUNCTION:
+d2i_DHparams                            727	EXIST::FUNCTION:DH
+d2i_DSAPrivateKey                       728	EXIST::FUNCTION:DSA
+d2i_DSAPrivateKey_bio                   729	EXIST::FUNCTION:BIO,DSA
+d2i_DSAPrivateKey_fp                    730	EXIST::FUNCTION:DSA,FP_API
+d2i_DSAPublicKey                        731	EXIST::FUNCTION:DSA
+d2i_DSAparams                           732	EXIST::FUNCTION:DSA
+d2i_NETSCAPE_SPKAC                      733	EXIST::FUNCTION:
+d2i_NETSCAPE_SPKI                       734	EXIST::FUNCTION:
+d2i_Netscape_RSA                        735	EXIST::FUNCTION:RC4,RSA
+d2i_PKCS7                               736	EXIST::FUNCTION:
+d2i_PKCS7_DIGEST                        737	EXIST::FUNCTION:
+d2i_PKCS7_ENCRYPT                       738	EXIST::FUNCTION:
+d2i_PKCS7_ENC_CONTENT                   739	EXIST::FUNCTION:
+d2i_PKCS7_ENVELOPE                      740	EXIST::FUNCTION:
+d2i_PKCS7_ISSUER_AND_SERIAL             741	EXIST::FUNCTION:
+d2i_PKCS7_RECIP_INFO                    742	EXIST::FUNCTION:
+d2i_PKCS7_SIGNED                        743	EXIST::FUNCTION:
+d2i_PKCS7_SIGNER_INFO                   744	EXIST::FUNCTION:
+d2i_PKCS7_SIGN_ENVELOPE                 745	EXIST::FUNCTION:
+d2i_PKCS7_bio                           746	EXIST::FUNCTION:
+d2i_PKCS7_fp                            747	EXIST::FUNCTION:FP_API
+d2i_PrivateKey                          748	EXIST::FUNCTION:
+d2i_PublicKey                           749	EXIST::FUNCTION:
+d2i_RSAPrivateKey                       750	EXIST::FUNCTION:RSA
+d2i_RSAPrivateKey_bio                   751	EXIST::FUNCTION:BIO,RSA
+d2i_RSAPrivateKey_fp                    752	EXIST::FUNCTION:FP_API,RSA
+d2i_RSAPublicKey                        753	EXIST::FUNCTION:RSA
+d2i_X509                                754	EXIST::FUNCTION:
+d2i_X509_ALGOR                          755	EXIST::FUNCTION:
+d2i_X509_ATTRIBUTE                      756	EXIST::FUNCTION:
+d2i_X509_CINF                           757	EXIST::FUNCTION:
+d2i_X509_CRL                            758	EXIST::FUNCTION:
+d2i_X509_CRL_INFO                       759	EXIST::FUNCTION:
+d2i_X509_CRL_bio                        760	EXIST::FUNCTION:BIO
+d2i_X509_CRL_fp                         761	EXIST::FUNCTION:FP_API
+d2i_X509_EXTENSION                      762	EXIST::FUNCTION:
+d2i_X509_NAME                           763	EXIST::FUNCTION:
+d2i_X509_NAME_ENTRY                     764	EXIST::FUNCTION:
+d2i_X509_PKEY                           765	EXIST::FUNCTION:
+d2i_X509_PUBKEY                         766	EXIST::FUNCTION:
+d2i_X509_REQ                            767	EXIST::FUNCTION:
+d2i_X509_REQ_INFO                       768	EXIST::FUNCTION:
+d2i_X509_REQ_bio                        769	EXIST::FUNCTION:BIO
+d2i_X509_REQ_fp                         770	EXIST::FUNCTION:FP_API
+d2i_X509_REVOKED                        771	EXIST::FUNCTION:
+d2i_X509_SIG                            772	EXIST::FUNCTION:
+d2i_X509_VAL                            773	EXIST::FUNCTION:
+d2i_X509_bio                            774	EXIST::FUNCTION:BIO
+d2i_X509_fp                             775	EXIST::FUNCTION:FP_API
+DES_cbc_cksum                           777	EXIST::FUNCTION:DES
+DES_cbc_encrypt                         778	EXIST::FUNCTION:DES
+DES_cblock_print_file                   779	NOEXIST::FUNCTION:
+DES_cfb64_encrypt                       780	EXIST::FUNCTION:DES
+DES_cfb_encrypt                         781	EXIST::FUNCTION:DES
+DES_decrypt3                            782	EXIST::FUNCTION:DES
+DES_ecb3_encrypt                        783	EXIST::FUNCTION:DES
+DES_ecb_encrypt                         784	EXIST::FUNCTION:DES
+DES_ede3_cbc_encrypt                    785	EXIST::FUNCTION:DES
+DES_ede3_cfb64_encrypt                  786	EXIST::FUNCTION:DES
+DES_ede3_ofb64_encrypt                  787	EXIST::FUNCTION:DES
+DES_enc_read                            788	EXIST::FUNCTION:DES
+DES_enc_write                           789	EXIST::FUNCTION:DES
+DES_encrypt1                            790	EXIST::FUNCTION:DES
+DES_encrypt2                            791	EXIST::FUNCTION:DES
+DES_encrypt3                            792	EXIST::FUNCTION:DES
+DES_fcrypt                              793	EXIST::FUNCTION:DES
+DES_is_weak_key                         794	EXIST::FUNCTION:DES
+DES_key_sched                           795	EXIST::FUNCTION:DES
+DES_ncbc_encrypt                        796	EXIST::FUNCTION:DES
+DES_ofb64_encrypt                       797	EXIST::FUNCTION:DES
+DES_ofb_encrypt                         798	EXIST::FUNCTION:DES
+DES_options                             799	EXIST::FUNCTION:DES
+DES_pcbc_encrypt                        800	EXIST::FUNCTION:DES
+DES_quad_cksum                          801	EXIST::FUNCTION:DES
+DES_random_key                          802	EXIST::FUNCTION:DES
+_ossl_old_des_random_seed               803	EXIST::FUNCTION:DES
+_ossl_old_des_read_2passwords           804	EXIST::FUNCTION:DES
+_ossl_old_des_read_password             805	EXIST::FUNCTION:DES
+_ossl_old_des_read_pw                   806	EXIST::FUNCTION:
+_ossl_old_des_read_pw_string            807	EXIST::FUNCTION:
+DES_set_key                             808	EXIST::FUNCTION:DES
+DES_set_odd_parity                      809	EXIST::FUNCTION:DES
+DES_string_to_2keys                     810	EXIST::FUNCTION:DES
+DES_string_to_key                       811	EXIST::FUNCTION:DES
+DES_xcbc_encrypt                        812	EXIST::FUNCTION:DES
+DES_xwhite_in2out                       813	NOEXIST::FUNCTION:
+fcrypt_body                             814	NOEXIST::FUNCTION:
+i2a_ASN1_INTEGER                        815	EXIST::FUNCTION:BIO
+i2a_ASN1_OBJECT                         816	EXIST::FUNCTION:BIO
+i2a_ASN1_STRING                         817	EXIST::FUNCTION:BIO
+i2d_ASN1_BIT_STRING                     818	EXIST::FUNCTION:
+i2d_ASN1_BOOLEAN                        819	EXIST::FUNCTION:
+i2d_ASN1_HEADER                         820	NOEXIST::FUNCTION:
+i2d_ASN1_IA5STRING                      821	EXIST::FUNCTION:
+i2d_ASN1_INTEGER                        822	EXIST::FUNCTION:
+i2d_ASN1_OBJECT                         823	EXIST::FUNCTION:
+i2d_ASN1_OCTET_STRING                   824	EXIST::FUNCTION:
+i2d_ASN1_PRINTABLE                      825	EXIST::FUNCTION:
+i2d_ASN1_SET                            826	EXIST::FUNCTION:
+i2d_ASN1_TYPE                           827	EXIST::FUNCTION:
+i2d_ASN1_UTCTIME                        828	EXIST::FUNCTION:
+i2d_ASN1_bytes                          829	EXIST::FUNCTION:
+i2d_DHparams                            830	EXIST::FUNCTION:DH
+i2d_DSAPrivateKey                       831	EXIST::FUNCTION:DSA
+i2d_DSAPrivateKey_bio                   832	EXIST::FUNCTION:BIO,DSA
+i2d_DSAPrivateKey_fp                    833	EXIST::FUNCTION:DSA,FP_API
+i2d_DSAPublicKey                        834	EXIST::FUNCTION:DSA
+i2d_DSAparams                           835	EXIST::FUNCTION:DSA
+i2d_NETSCAPE_SPKAC                      836	EXIST::FUNCTION:
+i2d_NETSCAPE_SPKI                       837	EXIST::FUNCTION:
+i2d_Netscape_RSA                        838	EXIST::FUNCTION:RC4,RSA
+i2d_PKCS7                               839	EXIST::FUNCTION:
+i2d_PKCS7_DIGEST                        840	EXIST::FUNCTION:
+i2d_PKCS7_ENCRYPT                       841	EXIST::FUNCTION:
+i2d_PKCS7_ENC_CONTENT                   842	EXIST::FUNCTION:
+i2d_PKCS7_ENVELOPE                      843	EXIST::FUNCTION:
+i2d_PKCS7_ISSUER_AND_SERIAL             844	EXIST::FUNCTION:
+i2d_PKCS7_RECIP_INFO                    845	EXIST::FUNCTION:
+i2d_PKCS7_SIGNED                        846	EXIST::FUNCTION:
+i2d_PKCS7_SIGNER_INFO                   847	EXIST::FUNCTION:
+i2d_PKCS7_SIGN_ENVELOPE                 848	EXIST::FUNCTION:
+i2d_PKCS7_bio                           849	EXIST::FUNCTION:
+i2d_PKCS7_fp                            850	EXIST::FUNCTION:FP_API
+i2d_PrivateKey                          851	EXIST::FUNCTION:
+i2d_PublicKey                           852	EXIST::FUNCTION:
+i2d_RSAPrivateKey                       853	EXIST::FUNCTION:RSA
+i2d_RSAPrivateKey_bio                   854	EXIST::FUNCTION:BIO,RSA
+i2d_RSAPrivateKey_fp                    855	EXIST::FUNCTION:FP_API,RSA
+i2d_RSAPublicKey                        856	EXIST::FUNCTION:RSA
+i2d_X509                                857	EXIST::FUNCTION:
+i2d_X509_ALGOR                          858	EXIST::FUNCTION:
+i2d_X509_ATTRIBUTE                      859	EXIST::FUNCTION:
+i2d_X509_CINF                           860	EXIST::FUNCTION:
+i2d_X509_CRL                            861	EXIST::FUNCTION:
+i2d_X509_CRL_INFO                       862	EXIST::FUNCTION:
+i2d_X509_CRL_bio                        863	EXIST::FUNCTION:BIO
+i2d_X509_CRL_fp                         864	EXIST::FUNCTION:FP_API
+i2d_X509_EXTENSION                      865	EXIST::FUNCTION:
+i2d_X509_NAME                           866	EXIST::FUNCTION:
+i2d_X509_NAME_ENTRY                     867	EXIST::FUNCTION:
+i2d_X509_PKEY                           868	EXIST::FUNCTION:
+i2d_X509_PUBKEY                         869	EXIST::FUNCTION:
+i2d_X509_REQ                            870	EXIST::FUNCTION:
+i2d_X509_REQ_INFO                       871	EXIST::FUNCTION:
+i2d_X509_REQ_bio                        872	EXIST::FUNCTION:BIO
+i2d_X509_REQ_fp                         873	EXIST::FUNCTION:FP_API
+i2d_X509_REVOKED                        874	EXIST::FUNCTION:
+i2d_X509_SIG                            875	EXIST::FUNCTION:
+i2d_X509_VAL                            876	EXIST::FUNCTION:
+i2d_X509_bio                            877	EXIST::FUNCTION:BIO
+i2d_X509_fp                             878	EXIST::FUNCTION:FP_API
+idea_cbc_encrypt                        879	EXIST::FUNCTION:IDEA
+idea_cfb64_encrypt                      880	EXIST::FUNCTION:IDEA
+idea_ecb_encrypt                        881	EXIST::FUNCTION:IDEA
+idea_encrypt                            882	EXIST::FUNCTION:IDEA
+idea_ofb64_encrypt                      883	EXIST::FUNCTION:IDEA
+idea_options                            884	EXIST::FUNCTION:IDEA
+idea_set_decrypt_key                    885	EXIST::FUNCTION:IDEA
+idea_set_encrypt_key                    886	EXIST::FUNCTION:IDEA
+lh_delete                               887	EXIST::FUNCTION:
+lh_doall                                888	EXIST::FUNCTION:
+lh_doall_arg                            889	EXIST::FUNCTION:
+lh_free                                 890	EXIST::FUNCTION:
+lh_insert                               891	EXIST::FUNCTION:
+lh_new                                  892	EXIST::FUNCTION:
+lh_node_stats                           893	EXIST::FUNCTION:FP_API
+lh_node_stats_bio                       894	EXIST::FUNCTION:BIO
+lh_node_usage_stats                     895	EXIST::FUNCTION:FP_API
+lh_node_usage_stats_bio                 896	EXIST::FUNCTION:BIO
+lh_retrieve                             897	EXIST::FUNCTION:
+lh_stats                                898	EXIST::FUNCTION:FP_API
+lh_stats_bio                            899	EXIST::FUNCTION:BIO
+lh_strhash                              900	EXIST::FUNCTION:
+sk_delete                               901	EXIST::FUNCTION:
+sk_delete_ptr                           902	EXIST::FUNCTION:
+sk_dup                                  903	EXIST::FUNCTION:
+sk_find                                 904	EXIST::FUNCTION:
+sk_free                                 905	EXIST::FUNCTION:
+sk_insert                               906	EXIST::FUNCTION:
+sk_new                                  907	EXIST::FUNCTION:
+sk_pop                                  908	EXIST::FUNCTION:
+sk_pop_free                             909	EXIST::FUNCTION:
+sk_push                                 910	EXIST::FUNCTION:
+sk_set_cmp_func                         911	EXIST::FUNCTION:
+sk_shift                                912	EXIST::FUNCTION:
+sk_unshift                              913	EXIST::FUNCTION:
+sk_zero                                 914	EXIST::FUNCTION:
+BIO_f_nbio_test                         915	EXIST::FUNCTION:
+ASN1_TYPE_get                           916	EXIST::FUNCTION:
+ASN1_TYPE_set                           917	EXIST::FUNCTION:
+PKCS7_content_free                      918	NOEXIST::FUNCTION:
+ERR_load_PKCS7_strings                  919	EXIST::FUNCTION:
+X509_find_by_issuer_and_serial          920	EXIST::FUNCTION:
+X509_find_by_subject                    921	EXIST::FUNCTION:
+PKCS7_ctrl                              927	EXIST::FUNCTION:
+PKCS7_set_type                          928	EXIST::FUNCTION:
+PKCS7_set_content                       929	EXIST::FUNCTION:
+PKCS7_SIGNER_INFO_set                   930	EXIST::FUNCTION:
+PKCS7_add_signer                        931	EXIST::FUNCTION:
+PKCS7_add_certificate                   932	EXIST::FUNCTION:
+PKCS7_add_crl                           933	EXIST::FUNCTION:
+PKCS7_content_new                       934	EXIST::FUNCTION:
+PKCS7_dataSign                          935	NOEXIST::FUNCTION:
+PKCS7_dataVerify                        936	EXIST::FUNCTION:
+PKCS7_dataInit                          937	EXIST::FUNCTION:
+PKCS7_add_signature                     938	EXIST::FUNCTION:
+PKCS7_cert_from_signer_info             939	EXIST::FUNCTION:
+PKCS7_get_signer_info                   940	EXIST::FUNCTION:
+EVP_delete_alias                        941	NOEXIST::FUNCTION:
+EVP_mdc2                                942	EXIST::FUNCTION:MDC2
+PEM_read_bio_RSAPublicKey               943	EXIST::FUNCTION:RSA
+PEM_write_bio_RSAPublicKey              944	EXIST::FUNCTION:RSA
+d2i_RSAPublicKey_bio                    945	EXIST::FUNCTION:BIO,RSA
+i2d_RSAPublicKey_bio                    946	EXIST::FUNCTION:BIO,RSA
+PEM_read_RSAPublicKey                   947	EXIST:!WIN16:FUNCTION:RSA
+PEM_write_RSAPublicKey                  949	EXIST:!WIN16:FUNCTION:RSA
+d2i_RSAPublicKey_fp                     952	EXIST::FUNCTION:FP_API,RSA
+i2d_RSAPublicKey_fp                     954	EXIST::FUNCTION:FP_API,RSA
+BIO_copy_next_retry                     955	EXIST::FUNCTION:
+RSA_flags                               956	EXIST::FUNCTION:RSA
+X509_STORE_add_crl                      957	EXIST::FUNCTION:
+X509_load_crl_file                      958	EXIST::FUNCTION:STDIO
+EVP_rc2_40_cbc                          959	EXIST::FUNCTION:RC2
+EVP_rc4_40                              960	EXIST::FUNCTION:RC4
+EVP_CIPHER_CTX_init                     961	EXIST::FUNCTION:
+HMAC                                    962	EXIST::FUNCTION:HMAC
+HMAC_Init                               963	EXIST::FUNCTION:HMAC
+HMAC_Update                             964	EXIST::FUNCTION:HMAC
+HMAC_Final                              965	EXIST::FUNCTION:HMAC
+ERR_get_next_error_library              966	EXIST::FUNCTION:
+EVP_PKEY_cmp_parameters                 967	EXIST::FUNCTION:
+HMAC_cleanup                            968	NOEXIST::FUNCTION:
+BIO_ptr_ctrl                            969	EXIST::FUNCTION:
+BIO_new_file_internal                   970	NOEXIST::FUNCTION:
+BIO_new_fp_internal                     971	NOEXIST::FUNCTION:
+BIO_s_file_internal                     972	NOEXIST::FUNCTION:
+BN_BLINDING_convert                     973	EXIST::FUNCTION:
+BN_BLINDING_invert                      974	EXIST::FUNCTION:
+BN_BLINDING_update                      975	EXIST::FUNCTION:
+RSA_blinding_on                         977	EXIST::FUNCTION:RSA
+RSA_blinding_off                        978	EXIST::FUNCTION:RSA
+i2t_ASN1_OBJECT                         979	EXIST::FUNCTION:
+BN_BLINDING_new                         980	EXIST::FUNCTION:
+BN_BLINDING_free                        981	EXIST::FUNCTION:
+EVP_cast5_cbc                           983	EXIST::FUNCTION:CAST
+EVP_cast5_cfb64                         984	EXIST::FUNCTION:CAST
+EVP_cast5_ecb                           985	EXIST::FUNCTION:CAST
+EVP_cast5_ofb                           986	EXIST::FUNCTION:CAST
+BF_decrypt                              987	EXIST::FUNCTION:BF
+CAST_set_key                            988	EXIST::FUNCTION:CAST
+CAST_encrypt                            989	EXIST::FUNCTION:CAST
+CAST_decrypt                            990	EXIST::FUNCTION:CAST
+CAST_ecb_encrypt                        991	EXIST::FUNCTION:CAST
+CAST_cbc_encrypt                        992	EXIST::FUNCTION:CAST
+CAST_cfb64_encrypt                      993	EXIST::FUNCTION:CAST
+CAST_ofb64_encrypt                      994	EXIST::FUNCTION:CAST
+RC2_decrypt                             995	EXIST::FUNCTION:RC2
+OBJ_create_objects                      997	EXIST::FUNCTION:
+BN_exp                                  998	EXIST::FUNCTION:
+BN_mul_word                             999	EXIST::FUNCTION:
+BN_sub_word                             1000	EXIST::FUNCTION:
+BN_dec2bn                               1001	EXIST::FUNCTION:
+BN_bn2dec                               1002	EXIST::FUNCTION:
+BIO_ghbn_ctrl                           1003	NOEXIST::FUNCTION:
+CRYPTO_free_ex_data                     1004	EXIST::FUNCTION:
+CRYPTO_get_ex_data                      1005	EXIST::FUNCTION:
+CRYPTO_set_ex_data                      1007	EXIST::FUNCTION:
+ERR_load_CRYPTO_strings                 1009	EXIST:!OS2,!VMS:FUNCTION:
+ERR_load_CRYPTOlib_strings              1009	EXIST:OS2,VMS:FUNCTION:
+EVP_PKEY_bits                           1010	EXIST::FUNCTION:
+MD5_Transform                           1011	EXIST::FUNCTION:MD5
+SHA1_Transform                          1012	EXIST::FUNCTION:SHA,SHA1
+SHA_Transform                           1013	EXIST::FUNCTION:SHA,SHA0
+X509_STORE_CTX_get_chain                1014	EXIST::FUNCTION:
+X509_STORE_CTX_get_current_cert         1015	EXIST::FUNCTION:
+X509_STORE_CTX_get_error                1016	EXIST::FUNCTION:
+X509_STORE_CTX_get_error_depth          1017	EXIST::FUNCTION:
+X509_STORE_CTX_get_ex_data              1018	EXIST::FUNCTION:
+X509_STORE_CTX_set_cert                 1020	EXIST::FUNCTION:
+X509_STORE_CTX_set_chain                1021	EXIST::FUNCTION:
+X509_STORE_CTX_set_error                1022	EXIST::FUNCTION:
+X509_STORE_CTX_set_ex_data              1023	EXIST::FUNCTION:
+CRYPTO_dup_ex_data                      1025	EXIST::FUNCTION:
+CRYPTO_get_new_lockid                   1026	EXIST::FUNCTION:
+CRYPTO_new_ex_data                      1027	EXIST::FUNCTION:
+RSA_set_ex_data                         1028	EXIST::FUNCTION:RSA
+RSA_get_ex_data                         1029	EXIST::FUNCTION:RSA
+RSA_get_ex_new_index                    1030	EXIST::FUNCTION:RSA
+RSA_padding_add_PKCS1_type_1            1031	EXIST::FUNCTION:RSA
+RSA_padding_add_PKCS1_type_2            1032	EXIST::FUNCTION:RSA
+RSA_padding_add_SSLv23                  1033	EXIST::FUNCTION:RSA
+RSA_padding_add_none                    1034	EXIST::FUNCTION:RSA
+RSA_padding_check_PKCS1_type_1          1035	EXIST::FUNCTION:RSA
+RSA_padding_check_PKCS1_type_2          1036	EXIST::FUNCTION:RSA
+RSA_padding_check_SSLv23                1037	EXIST::FUNCTION:RSA
+RSA_padding_check_none                  1038	EXIST::FUNCTION:RSA
+bn_add_words                            1039	EXIST::FUNCTION:
+d2i_Netscape_RSA_2                      1040	NOEXIST::FUNCTION:
+CRYPTO_get_ex_new_index                 1041	EXIST::FUNCTION:
+RIPEMD160_Init                          1042	EXIST::FUNCTION:RIPEMD
+RIPEMD160_Update                        1043	EXIST::FUNCTION:RIPEMD
+RIPEMD160_Final                         1044	EXIST::FUNCTION:RIPEMD
+RIPEMD160                               1045	EXIST::FUNCTION:RIPEMD
+RIPEMD160_Transform                     1046	EXIST::FUNCTION:RIPEMD
+RC5_32_set_key                          1047	EXIST::FUNCTION:RC5
+RC5_32_ecb_encrypt                      1048	EXIST::FUNCTION:RC5
+RC5_32_encrypt                          1049	EXIST::FUNCTION:RC5
+RC5_32_decrypt                          1050	EXIST::FUNCTION:RC5
+RC5_32_cbc_encrypt                      1051	EXIST::FUNCTION:RC5
+RC5_32_cfb64_encrypt                    1052	EXIST::FUNCTION:RC5
+RC5_32_ofb64_encrypt                    1053	EXIST::FUNCTION:RC5
+BN_bn2mpi                               1058	EXIST::FUNCTION:
+BN_mpi2bn                               1059	EXIST::FUNCTION:
+ASN1_BIT_STRING_get_bit                 1060	EXIST::FUNCTION:
+ASN1_BIT_STRING_set_bit                 1061	EXIST::FUNCTION:
+BIO_get_ex_data                         1062	EXIST::FUNCTION:
+BIO_get_ex_new_index                    1063	EXIST::FUNCTION:
+BIO_set_ex_data                         1064	EXIST::FUNCTION:
+X509v3_get_key_usage                    1066	NOEXIST::FUNCTION:
+X509v3_set_key_usage                    1067	NOEXIST::FUNCTION:
+a2i_X509v3_key_usage                    1068	NOEXIST::FUNCTION:
+i2a_X509v3_key_usage                    1069	NOEXIST::FUNCTION:
+EVP_PKEY_decrypt                        1070	EXIST::FUNCTION:
+EVP_PKEY_encrypt                        1071	EXIST::FUNCTION:
+PKCS7_RECIP_INFO_set                    1072	EXIST::FUNCTION:
+PKCS7_add_recipient                     1073	EXIST::FUNCTION:
+PKCS7_add_recipient_info                1074	EXIST::FUNCTION:
+PKCS7_set_cipher                        1075	EXIST::FUNCTION:
+ASN1_TYPE_get_int_octetstring           1076	EXIST::FUNCTION:
+ASN1_TYPE_get_octetstring               1077	EXIST::FUNCTION:
+ASN1_TYPE_set_int_octetstring           1078	EXIST::FUNCTION:
+ASN1_TYPE_set_octetstring               1079	EXIST::FUNCTION:
+ASN1_UTCTIME_set_string                 1080	EXIST::FUNCTION:
+ERR_add_error_data                      1081	EXIST::FUNCTION:BIO
+ERR_set_error_data                      1082	EXIST::FUNCTION:
+EVP_CIPHER_asn1_to_param                1083	EXIST::FUNCTION:
+EVP_CIPHER_param_to_asn1                1084	EXIST::FUNCTION:
+EVP_CIPHER_get_asn1_iv                  1085	EXIST::FUNCTION:
+EVP_CIPHER_set_asn1_iv                  1086	EXIST::FUNCTION:
+EVP_rc5_32_12_16_cbc                    1087	EXIST::FUNCTION:RC5
+EVP_rc5_32_12_16_cfb64                  1088	EXIST::FUNCTION:RC5
+EVP_rc5_32_12_16_ecb                    1089	EXIST::FUNCTION:RC5
+EVP_rc5_32_12_16_ofb                    1090	EXIST::FUNCTION:RC5
+asn1_add_error                          1091	EXIST::FUNCTION:
+d2i_ASN1_BMPSTRING                      1092	EXIST::FUNCTION:
+i2d_ASN1_BMPSTRING                      1093	EXIST::FUNCTION:
+BIO_f_ber                               1094	NOEXIST::FUNCTION:
+BN_init                                 1095	EXIST::FUNCTION:
+COMP_CTX_new                            1096	EXIST::FUNCTION:
+COMP_CTX_free                           1097	EXIST::FUNCTION:
+COMP_CTX_compress_block                 1098	NOEXIST::FUNCTION:
+COMP_CTX_expand_block                   1099	NOEXIST::FUNCTION:
+X509_STORE_CTX_get_ex_new_index         1100	EXIST::FUNCTION:
+OBJ_NAME_add                            1101	EXIST::FUNCTION:
+BIO_socket_nbio                         1102	EXIST::FUNCTION:
+EVP_rc2_64_cbc                          1103	EXIST::FUNCTION:RC2
+OBJ_NAME_cleanup                        1104	EXIST::FUNCTION:
+OBJ_NAME_get                            1105	EXIST::FUNCTION:
+OBJ_NAME_init                           1106	EXIST::FUNCTION:
+OBJ_NAME_new_index                      1107	EXIST::FUNCTION:
+OBJ_NAME_remove                         1108	EXIST::FUNCTION:
+BN_MONT_CTX_copy                        1109	EXIST::FUNCTION:
+BIO_new_socks4a_connect                 1110	NOEXIST::FUNCTION:
+BIO_s_socks4a_connect                   1111	NOEXIST::FUNCTION:
+PROXY_set_connect_mode                  1112	NOEXIST::FUNCTION:
+RAND_SSLeay                             1113	EXIST::FUNCTION:
+RAND_set_rand_method                    1114	EXIST::FUNCTION:
+RSA_memory_lock                         1115	EXIST::FUNCTION:RSA
+bn_sub_words                            1116	EXIST::FUNCTION:
+bn_mul_normal                           1117	NOEXIST::FUNCTION:
+bn_mul_comba8                           1118	NOEXIST::FUNCTION:
+bn_mul_comba4                           1119	NOEXIST::FUNCTION:
+bn_sqr_normal                           1120	NOEXIST::FUNCTION:
+bn_sqr_comba8                           1121	NOEXIST::FUNCTION:
+bn_sqr_comba4                           1122	NOEXIST::FUNCTION:
+bn_cmp_words                            1123	NOEXIST::FUNCTION:
+bn_mul_recursive                        1124	NOEXIST::FUNCTION:
+bn_mul_part_recursive                   1125	NOEXIST::FUNCTION:
+bn_sqr_recursive                        1126	NOEXIST::FUNCTION:
+bn_mul_low_normal                       1127	NOEXIST::FUNCTION:
+BN_RECP_CTX_init                        1128	EXIST::FUNCTION:
+BN_RECP_CTX_new                         1129	EXIST::FUNCTION:
+BN_RECP_CTX_free                        1130	EXIST::FUNCTION:
+BN_RECP_CTX_set                         1131	EXIST::FUNCTION:
+BN_mod_mul_reciprocal                   1132	EXIST::FUNCTION:
+BN_mod_exp_recp                         1133	EXIST::FUNCTION:
+BN_div_recp                             1134	EXIST::FUNCTION:
+BN_CTX_init                             1135	EXIST::FUNCTION:DEPRECATED
+BN_MONT_CTX_init                        1136	EXIST::FUNCTION:
+RAND_get_rand_method                    1137	EXIST::FUNCTION:
+PKCS7_add_attribute                     1138	EXIST::FUNCTION:
+PKCS7_add_signed_attribute              1139	EXIST::FUNCTION:
+PKCS7_digest_from_attributes            1140	EXIST::FUNCTION:
+PKCS7_get_attribute                     1141	EXIST::FUNCTION:
+PKCS7_get_issuer_and_serial             1142	EXIST::FUNCTION:
+PKCS7_get_signed_attribute              1143	EXIST::FUNCTION:
+COMP_compress_block                     1144	EXIST::FUNCTION:
+COMP_expand_block                       1145	EXIST::FUNCTION:
+COMP_rle                                1146	EXIST::FUNCTION:
+COMP_zlib                               1147	EXIST::FUNCTION:
+ms_time_diff                            1148	NOEXIST::FUNCTION:
+ms_time_new                             1149	NOEXIST::FUNCTION:
+ms_time_free                            1150	NOEXIST::FUNCTION:
+ms_time_cmp                             1151	NOEXIST::FUNCTION:
+ms_time_get                             1152	NOEXIST::FUNCTION:
+PKCS7_set_attributes                    1153	EXIST::FUNCTION:
+PKCS7_set_signed_attributes             1154	EXIST::FUNCTION:
+X509_ATTRIBUTE_create                   1155	EXIST::FUNCTION:
+X509_ATTRIBUTE_dup                      1156	EXIST::FUNCTION:
+ASN1_GENERALIZEDTIME_check              1157	EXIST::FUNCTION:
+ASN1_GENERALIZEDTIME_print              1158	EXIST::FUNCTION:BIO
+ASN1_GENERALIZEDTIME_set                1159	EXIST::FUNCTION:
+ASN1_GENERALIZEDTIME_set_string         1160	EXIST::FUNCTION:
+ASN1_TIME_print                         1161	EXIST::FUNCTION:BIO
+BASIC_CONSTRAINTS_free                  1162	EXIST::FUNCTION:
+BASIC_CONSTRAINTS_new                   1163	EXIST::FUNCTION:
+ERR_load_X509V3_strings                 1164	EXIST::FUNCTION:
+NETSCAPE_CERT_SEQUENCE_free             1165	EXIST::FUNCTION:
+NETSCAPE_CERT_SEQUENCE_new              1166	EXIST::FUNCTION:
+OBJ_txt2obj                             1167	EXIST::FUNCTION:
+PEM_read_NETSCAPE_CERT_SEQUENCE         1168	EXIST:!VMS,!WIN16:FUNCTION:
+PEM_read_NS_CERT_SEQ                    1168	EXIST:VMS:FUNCTION:
+PEM_read_bio_NETSCAPE_CERT_SEQUENCE     1169	EXIST:!VMS:FUNCTION:
+PEM_read_bio_NS_CERT_SEQ                1169	EXIST:VMS:FUNCTION:
+PEM_write_NETSCAPE_CERT_SEQUENCE        1170	EXIST:!VMS,!WIN16:FUNCTION:
+PEM_write_NS_CERT_SEQ                   1170	EXIST:VMS:FUNCTION:
+PEM_write_bio_NETSCAPE_CERT_SEQUENCE    1171	EXIST:!VMS:FUNCTION:
+PEM_write_bio_NS_CERT_SEQ               1171	EXIST:VMS:FUNCTION:
+X509V3_EXT_add                          1172	EXIST::FUNCTION:
+X509V3_EXT_add_alias                    1173	EXIST::FUNCTION:
+X509V3_EXT_add_conf                     1174	EXIST::FUNCTION:
+X509V3_EXT_cleanup                      1175	EXIST::FUNCTION:
+X509V3_EXT_conf                         1176	EXIST::FUNCTION:
+X509V3_EXT_conf_nid                     1177	EXIST::FUNCTION:
+X509V3_EXT_get                          1178	EXIST::FUNCTION:
+X509V3_EXT_get_nid                      1179	EXIST::FUNCTION:
+X509V3_EXT_print                        1180	EXIST::FUNCTION:
+X509V3_EXT_print_fp                     1181	EXIST::FUNCTION:
+X509V3_add_standard_extensions          1182	EXIST::FUNCTION:
+X509V3_add_value                        1183	EXIST::FUNCTION:
+X509V3_add_value_bool                   1184	EXIST::FUNCTION:
+X509V3_add_value_int                    1185	EXIST::FUNCTION:
+X509V3_conf_free                        1186	EXIST::FUNCTION:
+X509V3_get_value_bool                   1187	EXIST::FUNCTION:
+X509V3_get_value_int                    1188	EXIST::FUNCTION:
+X509V3_parse_list                       1189	EXIST::FUNCTION:
+d2i_ASN1_GENERALIZEDTIME                1190	EXIST::FUNCTION:
+d2i_ASN1_TIME                           1191	EXIST::FUNCTION:
+d2i_BASIC_CONSTRAINTS                   1192	EXIST::FUNCTION:
+d2i_NETSCAPE_CERT_SEQUENCE              1193	EXIST::FUNCTION:
+d2i_ext_ku                              1194	NOEXIST::FUNCTION:
+ext_ku_free                             1195	NOEXIST::FUNCTION:
+ext_ku_new                              1196	NOEXIST::FUNCTION:
+i2d_ASN1_GENERALIZEDTIME                1197	EXIST::FUNCTION:
+i2d_ASN1_TIME                           1198	EXIST::FUNCTION:
+i2d_BASIC_CONSTRAINTS                   1199	EXIST::FUNCTION:
+i2d_NETSCAPE_CERT_SEQUENCE              1200	EXIST::FUNCTION:
+i2d_ext_ku                              1201	NOEXIST::FUNCTION:
+EVP_MD_CTX_copy                         1202	EXIST::FUNCTION:
+i2d_ASN1_ENUMERATED                     1203	EXIST::FUNCTION:
+d2i_ASN1_ENUMERATED                     1204	EXIST::FUNCTION:
+ASN1_ENUMERATED_set                     1205	EXIST::FUNCTION:
+ASN1_ENUMERATED_get                     1206	EXIST::FUNCTION:
+BN_to_ASN1_ENUMERATED                   1207	EXIST::FUNCTION:
+ASN1_ENUMERATED_to_BN                   1208	EXIST::FUNCTION:
+i2a_ASN1_ENUMERATED                     1209	EXIST::FUNCTION:BIO
+a2i_ASN1_ENUMERATED                     1210	EXIST::FUNCTION:BIO
+i2d_GENERAL_NAME                        1211	EXIST::FUNCTION:
+d2i_GENERAL_NAME                        1212	EXIST::FUNCTION:
+GENERAL_NAME_new                        1213	EXIST::FUNCTION:
+GENERAL_NAME_free                       1214	EXIST::FUNCTION:
+GENERAL_NAMES_new                       1215	EXIST::FUNCTION:
+GENERAL_NAMES_free                      1216	EXIST::FUNCTION:
+d2i_GENERAL_NAMES                       1217	EXIST::FUNCTION:
+i2d_GENERAL_NAMES                       1218	EXIST::FUNCTION:
+i2v_GENERAL_NAMES                       1219	EXIST::FUNCTION:
+i2s_ASN1_OCTET_STRING                   1220	EXIST::FUNCTION:
+s2i_ASN1_OCTET_STRING                   1221	EXIST::FUNCTION:
+X509V3_EXT_check_conf                   1222	NOEXIST::FUNCTION:
+hex_to_string                           1223	EXIST::FUNCTION:
+string_to_hex                           1224	EXIST::FUNCTION:
+DES_ede3_cbcm_encrypt                   1225	EXIST::FUNCTION:DES
+RSA_padding_add_PKCS1_OAEP              1226	EXIST::FUNCTION:RSA
+RSA_padding_check_PKCS1_OAEP            1227	EXIST::FUNCTION:RSA
+X509_CRL_print_fp                       1228	EXIST::FUNCTION:FP_API
+X509_CRL_print                          1229	EXIST::FUNCTION:BIO
+i2v_GENERAL_NAME                        1230	EXIST::FUNCTION:
+v2i_GENERAL_NAME                        1231	EXIST::FUNCTION:
+i2d_PKEY_USAGE_PERIOD                   1232	EXIST::FUNCTION:
+d2i_PKEY_USAGE_PERIOD                   1233	EXIST::FUNCTION:
+PKEY_USAGE_PERIOD_new                   1234	EXIST::FUNCTION:
+PKEY_USAGE_PERIOD_free                  1235	EXIST::FUNCTION:
+v2i_GENERAL_NAMES                       1236	EXIST::FUNCTION:
+i2s_ASN1_INTEGER                        1237	EXIST::FUNCTION:
+X509V3_EXT_d2i                          1238	EXIST::FUNCTION:
+name_cmp                                1239	EXIST::FUNCTION:
+str_dup                                 1240	NOEXIST::FUNCTION:
+i2s_ASN1_ENUMERATED                     1241	EXIST::FUNCTION:
+i2s_ASN1_ENUMERATED_TABLE               1242	EXIST::FUNCTION:
+BIO_s_log                               1243	EXIST:!OS2,!WIN16,!WIN32,!macintosh:FUNCTION:
+BIO_f_reliable                          1244	EXIST::FUNCTION:BIO
+PKCS7_dataFinal                         1245	EXIST::FUNCTION:
+PKCS7_dataDecode                        1246	EXIST::FUNCTION:
+X509V3_EXT_CRL_add_conf                 1247	EXIST::FUNCTION:
+BN_set_params                           1248	EXIST::FUNCTION:DEPRECATED
+BN_get_params                           1249	EXIST::FUNCTION:DEPRECATED
+BIO_get_ex_num                          1250	NOEXIST::FUNCTION:
+BIO_set_ex_free_func                    1251	NOEXIST::FUNCTION:
+EVP_ripemd160                           1252	EXIST::FUNCTION:RIPEMD
+ASN1_TIME_set                           1253	EXIST::FUNCTION:
+i2d_AUTHORITY_KEYID                     1254	EXIST::FUNCTION:
+d2i_AUTHORITY_KEYID                     1255	EXIST::FUNCTION:
+AUTHORITY_KEYID_new                     1256	EXIST::FUNCTION:
+AUTHORITY_KEYID_free                    1257	EXIST::FUNCTION:
+ASN1_seq_unpack                         1258	EXIST::FUNCTION:
+ASN1_seq_pack                           1259	EXIST::FUNCTION:
+ASN1_unpack_string                      1260	EXIST::FUNCTION:
+ASN1_pack_string                        1261	EXIST::FUNCTION:
+PKCS12_pack_safebag                     1262	NOEXIST::FUNCTION:
+PKCS12_MAKE_KEYBAG                      1263	EXIST::FUNCTION:
+PKCS8_encrypt                           1264	EXIST::FUNCTION:
+PKCS12_MAKE_SHKEYBAG                    1265	EXIST::FUNCTION:
+PKCS12_pack_p7data                      1266	EXIST::FUNCTION:
+PKCS12_pack_p7encdata                   1267	EXIST::FUNCTION:
+PKCS12_add_localkeyid                   1268	EXIST::FUNCTION:
+PKCS12_add_friendlyname_asc             1269	EXIST::FUNCTION:
+PKCS12_add_friendlyname_uni             1270	EXIST::FUNCTION:
+PKCS12_get_friendlyname                 1271	EXIST::FUNCTION:
+PKCS12_pbe_crypt                        1272	EXIST::FUNCTION:
+PKCS12_decrypt_d2i                      1273	NOEXIST::FUNCTION:
+PKCS12_i2d_encrypt                      1274	NOEXIST::FUNCTION:
+PKCS12_init                             1275	EXIST::FUNCTION:
+PKCS12_key_gen_asc                      1276	EXIST::FUNCTION:
+PKCS12_key_gen_uni                      1277	EXIST::FUNCTION:
+PKCS12_gen_mac                          1278	EXIST::FUNCTION:
+PKCS12_verify_mac                       1279	EXIST::FUNCTION:
+PKCS12_set_mac                          1280	EXIST::FUNCTION:
+PKCS12_setup_mac                        1281	EXIST::FUNCTION:
+OPENSSL_asc2uni                         1282	EXIST::FUNCTION:
+OPENSSL_uni2asc                         1283	EXIST::FUNCTION:
+i2d_PKCS12_BAGS                         1284	EXIST::FUNCTION:
+PKCS12_BAGS_new                         1285	EXIST::FUNCTION:
+d2i_PKCS12_BAGS                         1286	EXIST::FUNCTION:
+PKCS12_BAGS_free                        1287	EXIST::FUNCTION:
+i2d_PKCS12                              1288	EXIST::FUNCTION:
+d2i_PKCS12                              1289	EXIST::FUNCTION:
+PKCS12_new                              1290	EXIST::FUNCTION:
+PKCS12_free                             1291	EXIST::FUNCTION:
+i2d_PKCS12_MAC_DATA                     1292	EXIST::FUNCTION:
+PKCS12_MAC_DATA_new                     1293	EXIST::FUNCTION:
+d2i_PKCS12_MAC_DATA                     1294	EXIST::FUNCTION:
+PKCS12_MAC_DATA_free                    1295	EXIST::FUNCTION:
+i2d_PKCS12_SAFEBAG                      1296	EXIST::FUNCTION:
+PKCS12_SAFEBAG_new                      1297	EXIST::FUNCTION:
+d2i_PKCS12_SAFEBAG                      1298	EXIST::FUNCTION:
+PKCS12_SAFEBAG_free                     1299	EXIST::FUNCTION:
+ERR_load_PKCS12_strings                 1300	EXIST::FUNCTION:
+PKCS12_PBE_add                          1301	EXIST::FUNCTION:
+PKCS8_add_keyusage                      1302	EXIST::FUNCTION:
+PKCS12_get_attr_gen                     1303	EXIST::FUNCTION:
+PKCS12_parse                            1304	EXIST::FUNCTION:
+PKCS12_create                           1305	EXIST::FUNCTION:
+i2d_PKCS12_bio                          1306	EXIST::FUNCTION:
+i2d_PKCS12_fp                           1307	EXIST::FUNCTION:
+d2i_PKCS12_bio                          1308	EXIST::FUNCTION:
+d2i_PKCS12_fp                           1309	EXIST::FUNCTION:
+i2d_PBEPARAM                            1310	EXIST::FUNCTION:
+PBEPARAM_new                            1311	EXIST::FUNCTION:
+d2i_PBEPARAM                            1312	EXIST::FUNCTION:
+PBEPARAM_free                           1313	EXIST::FUNCTION:
+i2d_PKCS8_PRIV_KEY_INFO                 1314	EXIST::FUNCTION:
+PKCS8_PRIV_KEY_INFO_new                 1315	EXIST::FUNCTION:
+d2i_PKCS8_PRIV_KEY_INFO                 1316	EXIST::FUNCTION:
+PKCS8_PRIV_KEY_INFO_free                1317	EXIST::FUNCTION:
+EVP_PKCS82PKEY                          1318	EXIST::FUNCTION:
+EVP_PKEY2PKCS8                          1319	EXIST::FUNCTION:
+PKCS8_set_broken                        1320	EXIST::FUNCTION:
+EVP_PBE_ALGOR_CipherInit                1321	NOEXIST::FUNCTION:
+EVP_PBE_alg_add                         1322	EXIST::FUNCTION:
+PKCS5_pbe_set                           1323	EXIST::FUNCTION:
+EVP_PBE_cleanup                         1324	EXIST::FUNCTION:
+i2d_SXNET                               1325	EXIST::FUNCTION:
+d2i_SXNET                               1326	EXIST::FUNCTION:
+SXNET_new                               1327	EXIST::FUNCTION:
+SXNET_free                              1328	EXIST::FUNCTION:
+i2d_SXNETID                             1329	EXIST::FUNCTION:
+d2i_SXNETID                             1330	EXIST::FUNCTION:
+SXNETID_new                             1331	EXIST::FUNCTION:
+SXNETID_free                            1332	EXIST::FUNCTION:
+DSA_SIG_new                             1333	EXIST::FUNCTION:DSA
+DSA_SIG_free                            1334	EXIST::FUNCTION:DSA
+DSA_do_sign                             1335	EXIST::FUNCTION:DSA
+DSA_do_verify                           1336	EXIST::FUNCTION:DSA
+d2i_DSA_SIG                             1337	EXIST::FUNCTION:DSA
+i2d_DSA_SIG                             1338	EXIST::FUNCTION:DSA
+i2d_ASN1_VISIBLESTRING                  1339	EXIST::FUNCTION:
+d2i_ASN1_VISIBLESTRING                  1340	EXIST::FUNCTION:
+i2d_ASN1_UTF8STRING                     1341	EXIST::FUNCTION:
+d2i_ASN1_UTF8STRING                     1342	EXIST::FUNCTION:
+i2d_DIRECTORYSTRING                     1343	EXIST::FUNCTION:
+d2i_DIRECTORYSTRING                     1344	EXIST::FUNCTION:
+i2d_DISPLAYTEXT                         1345	EXIST::FUNCTION:
+d2i_DISPLAYTEXT                         1346	EXIST::FUNCTION:
+d2i_ASN1_SET_OF_X509                    1379	NOEXIST::FUNCTION:
+i2d_ASN1_SET_OF_X509                    1380	NOEXIST::FUNCTION:
+i2d_PBKDF2PARAM                         1397	EXIST::FUNCTION:
+PBKDF2PARAM_new                         1398	EXIST::FUNCTION:
+d2i_PBKDF2PARAM                         1399	EXIST::FUNCTION:
+PBKDF2PARAM_free                        1400	EXIST::FUNCTION:
+i2d_PBE2PARAM                           1401	EXIST::FUNCTION:
+PBE2PARAM_new                           1402	EXIST::FUNCTION:
+d2i_PBE2PARAM                           1403	EXIST::FUNCTION:
+PBE2PARAM_free                          1404	EXIST::FUNCTION:
+d2i_ASN1_SET_OF_GENERAL_NAME            1421	NOEXIST::FUNCTION:
+i2d_ASN1_SET_OF_GENERAL_NAME            1422	NOEXIST::FUNCTION:
+d2i_ASN1_SET_OF_SXNETID                 1439	NOEXIST::FUNCTION:
+i2d_ASN1_SET_OF_SXNETID                 1440	NOEXIST::FUNCTION:
+d2i_ASN1_SET_OF_POLICYQUALINFO          1457	NOEXIST::FUNCTION:
+i2d_ASN1_SET_OF_POLICYQUALINFO          1458	NOEXIST::FUNCTION:
+d2i_ASN1_SET_OF_POLICYINFO              1475	NOEXIST::FUNCTION:
+i2d_ASN1_SET_OF_POLICYINFO              1476	NOEXIST::FUNCTION:
+SXNET_add_id_asc                        1477	EXIST::FUNCTION:
+SXNET_add_id_ulong                      1478	EXIST::FUNCTION:
+SXNET_add_id_INTEGER                    1479	EXIST::FUNCTION:
+SXNET_get_id_asc                        1480	EXIST::FUNCTION:
+SXNET_get_id_ulong                      1481	EXIST::FUNCTION:
+SXNET_get_id_INTEGER                    1482	EXIST::FUNCTION:
+X509V3_set_conf_lhash                   1483	EXIST::FUNCTION:
+i2d_CERTIFICATEPOLICIES                 1484	EXIST::FUNCTION:
+CERTIFICATEPOLICIES_new                 1485	EXIST::FUNCTION:
+CERTIFICATEPOLICIES_free                1486	EXIST::FUNCTION:
+d2i_CERTIFICATEPOLICIES                 1487	EXIST::FUNCTION:
+i2d_POLICYINFO                          1488	EXIST::FUNCTION:
+POLICYINFO_new                          1489	EXIST::FUNCTION:
+d2i_POLICYINFO                          1490	EXIST::FUNCTION:
+POLICYINFO_free                         1491	EXIST::FUNCTION:
+i2d_POLICYQUALINFO                      1492	EXIST::FUNCTION:
+POLICYQUALINFO_new                      1493	EXIST::FUNCTION:
+d2i_POLICYQUALINFO                      1494	EXIST::FUNCTION:
+POLICYQUALINFO_free                     1495	EXIST::FUNCTION:
+i2d_USERNOTICE                          1496	EXIST::FUNCTION:
+USERNOTICE_new                          1497	EXIST::FUNCTION:
+d2i_USERNOTICE                          1498	EXIST::FUNCTION:
+USERNOTICE_free                         1499	EXIST::FUNCTION:
+i2d_NOTICEREF                           1500	EXIST::FUNCTION:
+NOTICEREF_new                           1501	EXIST::FUNCTION:
+d2i_NOTICEREF                           1502	EXIST::FUNCTION:
+NOTICEREF_free                          1503	EXIST::FUNCTION:
+X509V3_get_string                       1504	EXIST::FUNCTION:
+X509V3_get_section                      1505	EXIST::FUNCTION:
+X509V3_string_free                      1506	EXIST::FUNCTION:
+X509V3_section_free                     1507	EXIST::FUNCTION:
+X509V3_set_ctx                          1508	EXIST::FUNCTION:
+s2i_ASN1_INTEGER                        1509	EXIST::FUNCTION:
+CRYPTO_set_locked_mem_functions         1510	EXIST::FUNCTION:
+CRYPTO_get_locked_mem_functions         1511	EXIST::FUNCTION:
+CRYPTO_malloc_locked                    1512	EXIST::FUNCTION:
+CRYPTO_free_locked                      1513	EXIST::FUNCTION:
+BN_mod_exp2_mont                        1514	EXIST::FUNCTION:
+ERR_get_error_line_data                 1515	EXIST::FUNCTION:
+ERR_peek_error_line_data                1516	EXIST::FUNCTION:
+PKCS12_PBE_keyivgen                     1517	EXIST::FUNCTION:
+X509_ALGOR_dup                          1518	EXIST::FUNCTION:
+d2i_ASN1_SET_OF_DIST_POINT              1535	NOEXIST::FUNCTION:
+i2d_ASN1_SET_OF_DIST_POINT              1536	NOEXIST::FUNCTION:
+i2d_CRL_DIST_POINTS                     1537	EXIST::FUNCTION:
+CRL_DIST_POINTS_new                     1538	EXIST::FUNCTION:
+CRL_DIST_POINTS_free                    1539	EXIST::FUNCTION:
+d2i_CRL_DIST_POINTS                     1540	EXIST::FUNCTION:
+i2d_DIST_POINT                          1541	EXIST::FUNCTION:
+DIST_POINT_new                          1542	EXIST::FUNCTION:
+d2i_DIST_POINT                          1543	EXIST::FUNCTION:
+DIST_POINT_free                         1544	EXIST::FUNCTION:
+i2d_DIST_POINT_NAME                     1545	EXIST::FUNCTION:
+DIST_POINT_NAME_new                     1546	EXIST::FUNCTION:
+DIST_POINT_NAME_free                    1547	EXIST::FUNCTION:
+d2i_DIST_POINT_NAME                     1548	EXIST::FUNCTION:
+X509V3_add_value_uchar                  1549	EXIST::FUNCTION:
+d2i_ASN1_SET_OF_X509_ATTRIBUTE          1555	NOEXIST::FUNCTION:
+i2d_ASN1_SET_OF_ASN1_TYPE               1560	NOEXIST::FUNCTION:
+d2i_ASN1_SET_OF_X509_EXTENSION          1567	NOEXIST::FUNCTION:
+d2i_ASN1_SET_OF_X509_NAME_ENTRY         1574	NOEXIST::FUNCTION:
+d2i_ASN1_SET_OF_ASN1_TYPE               1589	NOEXIST::FUNCTION:
+i2d_ASN1_SET_OF_X509_ATTRIBUTE          1615	NOEXIST::FUNCTION:
+i2d_ASN1_SET_OF_X509_EXTENSION          1624	NOEXIST::FUNCTION:
+i2d_ASN1_SET_OF_X509_NAME_ENTRY         1633	NOEXIST::FUNCTION:
+X509V3_EXT_i2d                          1646	EXIST::FUNCTION:
+X509V3_EXT_val_prn                      1647	EXIST::FUNCTION:
+X509V3_EXT_add_list                     1648	EXIST::FUNCTION:
+EVP_CIPHER_type                         1649	EXIST::FUNCTION:
+EVP_PBE_CipherInit                      1650	EXIST::FUNCTION:
+X509V3_add_value_bool_nf                1651	EXIST::FUNCTION:
+d2i_ASN1_UINTEGER                       1652	EXIST::FUNCTION:
+sk_value                                1653	EXIST::FUNCTION:
+sk_num                                  1654	EXIST::FUNCTION:
+sk_set                                  1655	EXIST::FUNCTION:
+i2d_ASN1_SET_OF_X509_REVOKED            1661	NOEXIST::FUNCTION:
+sk_sort                                 1671	EXIST::FUNCTION:
+d2i_ASN1_SET_OF_X509_REVOKED            1674	NOEXIST::FUNCTION:
+i2d_ASN1_SET_OF_X509_ALGOR              1682	NOEXIST::FUNCTION:
+i2d_ASN1_SET_OF_X509_CRL                1685	NOEXIST::FUNCTION:
+d2i_ASN1_SET_OF_X509_ALGOR              1696	NOEXIST::FUNCTION:
+d2i_ASN1_SET_OF_X509_CRL                1702	NOEXIST::FUNCTION:
+i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO       1723	NOEXIST::FUNCTION:
+i2d_ASN1_SET_OF_PKCS7_RECIP_INFO        1738	NOEXIST::FUNCTION:
+d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO       1748	NOEXIST::FUNCTION:
+d2i_ASN1_SET_OF_PKCS7_RECIP_INFO        1753	NOEXIST::FUNCTION:
+PKCS5_PBE_add                           1775	EXIST::FUNCTION:
+PEM_write_bio_PKCS8                     1776	EXIST::FUNCTION:
+i2d_PKCS8_fp                            1777	EXIST::FUNCTION:FP_API
+PEM_read_bio_PKCS8_PRIV_KEY_INFO        1778	EXIST:!VMS:FUNCTION:
+PEM_read_bio_P8_PRIV_KEY_INFO           1778	EXIST:VMS:FUNCTION:
+d2i_PKCS8_bio                           1779	EXIST::FUNCTION:BIO
+d2i_PKCS8_PRIV_KEY_INFO_fp              1780	EXIST::FUNCTION:FP_API
+PEM_write_bio_PKCS8_PRIV_KEY_INFO       1781	EXIST:!VMS:FUNCTION:
+PEM_write_bio_P8_PRIV_KEY_INFO          1781	EXIST:VMS:FUNCTION:
+PEM_read_PKCS8                          1782	EXIST:!WIN16:FUNCTION:
+d2i_PKCS8_PRIV_KEY_INFO_bio             1783	EXIST::FUNCTION:BIO
+d2i_PKCS8_fp                            1784	EXIST::FUNCTION:FP_API
+PEM_write_PKCS8                         1785	EXIST:!WIN16:FUNCTION:
+PEM_read_PKCS8_PRIV_KEY_INFO            1786	EXIST:!VMS,!WIN16:FUNCTION:
+PEM_read_P8_PRIV_KEY_INFO               1786	EXIST:VMS:FUNCTION:
+PEM_read_bio_PKCS8                      1787	EXIST::FUNCTION:
+PEM_write_PKCS8_PRIV_KEY_INFO           1788	EXIST:!VMS,!WIN16:FUNCTION:
+PEM_write_P8_PRIV_KEY_INFO              1788	EXIST:VMS:FUNCTION:
+PKCS5_PBE_keyivgen                      1789	EXIST::FUNCTION:
+i2d_PKCS8_bio                           1790	EXIST::FUNCTION:BIO
+i2d_PKCS8_PRIV_KEY_INFO_fp              1791	EXIST::FUNCTION:FP_API
+i2d_PKCS8_PRIV_KEY_INFO_bio             1792	EXIST::FUNCTION:BIO
+BIO_s_bio                               1793	EXIST::FUNCTION:
+PKCS5_pbe2_set                          1794	EXIST::FUNCTION:
+PKCS5_PBKDF2_HMAC_SHA1                  1795	EXIST::FUNCTION:
+PKCS5_v2_PBE_keyivgen                   1796	EXIST::FUNCTION:
+PEM_write_bio_PKCS8PrivateKey           1797	EXIST::FUNCTION:
+PEM_write_PKCS8PrivateKey               1798	EXIST::FUNCTION:
+BIO_ctrl_get_read_request               1799	EXIST::FUNCTION:
+BIO_ctrl_pending                        1800	EXIST::FUNCTION:
+BIO_ctrl_wpending                       1801	EXIST::FUNCTION:
+BIO_new_bio_pair                        1802	EXIST::FUNCTION:
+BIO_ctrl_get_write_guarantee            1803	EXIST::FUNCTION:
+CRYPTO_num_locks                        1804	EXIST::FUNCTION:
+CONF_load_bio                           1805	EXIST::FUNCTION:
+CONF_load_fp                            1806	EXIST::FUNCTION:FP_API
+i2d_ASN1_SET_OF_ASN1_OBJECT             1837	NOEXIST::FUNCTION:
+d2i_ASN1_SET_OF_ASN1_OBJECT             1844	NOEXIST::FUNCTION:
+PKCS7_signatureVerify                   1845	EXIST::FUNCTION:
+RSA_set_method                          1846	EXIST::FUNCTION:RSA
+RSA_get_method                          1847	EXIST::FUNCTION:RSA
+RSA_get_default_method                  1848	EXIST::FUNCTION:RSA
+RSA_check_key                           1869	EXIST::FUNCTION:RSA
+OBJ_obj2txt                             1870	EXIST::FUNCTION:
+DSA_dup_DH                              1871	EXIST::FUNCTION:DH,DSA
+X509_REQ_get_extensions                 1872	EXIST::FUNCTION:
+X509_REQ_set_extension_nids             1873	EXIST::FUNCTION:
+BIO_nwrite                              1874	EXIST::FUNCTION:
+X509_REQ_extension_nid                  1875	EXIST::FUNCTION:
+BIO_nread                               1876	EXIST::FUNCTION:
+X509_REQ_get_extension_nids             1877	EXIST::FUNCTION:
+BIO_nwrite0                             1878	EXIST::FUNCTION:
+X509_REQ_add_extensions_nid             1879	EXIST::FUNCTION:
+BIO_nread0                              1880	EXIST::FUNCTION:
+X509_REQ_add_extensions                 1881	EXIST::FUNCTION:
+BIO_new_mem_buf                         1882	EXIST::FUNCTION:
+DH_set_ex_data                          1883	EXIST::FUNCTION:DH
+DH_set_method                           1884	EXIST::FUNCTION:DH
+DSA_OpenSSL                             1885	EXIST::FUNCTION:DSA
+DH_get_ex_data                          1886	EXIST::FUNCTION:DH
+DH_get_ex_new_index                     1887	EXIST::FUNCTION:DH
+DSA_new_method                          1888	EXIST::FUNCTION:DSA
+DH_new_method                           1889	EXIST::FUNCTION:DH
+DH_OpenSSL                              1890	EXIST::FUNCTION:DH
+DSA_get_ex_new_index                    1891	EXIST::FUNCTION:DSA
+DH_get_default_method                   1892	EXIST::FUNCTION:DH
+DSA_set_ex_data                         1893	EXIST::FUNCTION:DSA
+DH_set_default_method                   1894	EXIST::FUNCTION:DH
+DSA_get_ex_data                         1895	EXIST::FUNCTION:DSA
+X509V3_EXT_REQ_add_conf                 1896	EXIST::FUNCTION:
+NETSCAPE_SPKI_print                     1897	EXIST::FUNCTION:EVP
+NETSCAPE_SPKI_set_pubkey                1898	EXIST::FUNCTION:EVP
+NETSCAPE_SPKI_b64_encode                1899	EXIST::FUNCTION:EVP
+NETSCAPE_SPKI_get_pubkey                1900	EXIST::FUNCTION:EVP
+NETSCAPE_SPKI_b64_decode                1901	EXIST::FUNCTION:EVP
+UTF8_putc                               1902	EXIST::FUNCTION:
+UTF8_getc                               1903	EXIST::FUNCTION:
+RSA_null_method                         1904	EXIST::FUNCTION:RSA
+ASN1_tag2str                            1905	EXIST::FUNCTION:
+BIO_ctrl_reset_read_request             1906	EXIST::FUNCTION:
+DISPLAYTEXT_new                         1907	EXIST::FUNCTION:
+ASN1_GENERALIZEDTIME_free               1908	EXIST::FUNCTION:
+X509_REVOKED_get_ext_d2i                1909	EXIST::FUNCTION:
+X509_set_ex_data                        1910	EXIST::FUNCTION:
+X509_reject_set_bit_asc                 1911	NOEXIST::FUNCTION:
+X509_NAME_add_entry_by_txt              1912	EXIST::FUNCTION:
+X509_NAME_add_entry_by_NID              1914	EXIST::FUNCTION:
+X509_PURPOSE_get0                       1915	EXIST::FUNCTION:
+PEM_read_X509_AUX                       1917	EXIST:!WIN16:FUNCTION:
+d2i_AUTHORITY_INFO_ACCESS               1918	EXIST::FUNCTION:
+PEM_write_PUBKEY                        1921	EXIST:!WIN16:FUNCTION:
+ACCESS_DESCRIPTION_new                  1925	EXIST::FUNCTION:
+X509_CERT_AUX_free                      1926	EXIST::FUNCTION:
+d2i_ACCESS_DESCRIPTION                  1927	EXIST::FUNCTION:
+X509_trust_clear                        1928	EXIST::FUNCTION:
+X509_TRUST_add                          1931	EXIST::FUNCTION:
+ASN1_VISIBLESTRING_new                  1932	EXIST::FUNCTION:
+X509_alias_set1                         1933	EXIST::FUNCTION:
+ASN1_PRINTABLESTRING_free               1934	EXIST::FUNCTION:
+EVP_PKEY_get1_DSA                       1935	EXIST::FUNCTION:DSA
+ASN1_BMPSTRING_new                      1936	EXIST::FUNCTION:
+ASN1_mbstring_copy                      1937	EXIST::FUNCTION:
+ASN1_UTF8STRING_new                     1938	EXIST::FUNCTION:
+DSA_get_default_method                  1941	EXIST::FUNCTION:DSA
+i2d_ASN1_SET_OF_ACCESS_DESCRIPTION      1945	NOEXIST::FUNCTION:
+ASN1_T61STRING_free                     1946	EXIST::FUNCTION:
+DSA_set_method                          1949	EXIST::FUNCTION:DSA
+X509_get_ex_data                        1950	EXIST::FUNCTION:
+ASN1_STRING_type                        1951	EXIST::FUNCTION:
+X509_PURPOSE_get_by_sname               1952	EXIST::FUNCTION:
+ASN1_TIME_free                          1954	EXIST::FUNCTION:
+ASN1_OCTET_STRING_cmp                   1955	EXIST::FUNCTION:
+ASN1_BIT_STRING_new                     1957	EXIST::FUNCTION:
+X509_get_ext_d2i                        1958	EXIST::FUNCTION:
+PEM_read_bio_X509_AUX                   1959	EXIST::FUNCTION:
+ASN1_STRING_set_default_mask_asc        1960	EXIST:!VMS:FUNCTION:
+ASN1_STRING_set_def_mask_asc            1960	EXIST:VMS:FUNCTION:
+PEM_write_bio_RSA_PUBKEY                1961	EXIST::FUNCTION:RSA
+ASN1_INTEGER_cmp                        1963	EXIST::FUNCTION:
+d2i_RSA_PUBKEY_fp                       1964	EXIST::FUNCTION:FP_API,RSA
+X509_trust_set_bit_asc                  1967	NOEXIST::FUNCTION:
+PEM_write_bio_DSA_PUBKEY                1968	EXIST::FUNCTION:DSA
+X509_STORE_CTX_free                     1969	EXIST::FUNCTION:
+EVP_PKEY_set1_DSA                       1970	EXIST::FUNCTION:DSA
+i2d_DSA_PUBKEY_fp                       1971	EXIST::FUNCTION:DSA,FP_API
+X509_load_cert_crl_file                 1972	EXIST::FUNCTION:STDIO
+ASN1_TIME_new                           1973	EXIST::FUNCTION:
+i2d_RSA_PUBKEY                          1974	EXIST::FUNCTION:RSA
+X509_STORE_CTX_purpose_inherit          1976	EXIST::FUNCTION:
+PEM_read_RSA_PUBKEY                     1977	EXIST:!WIN16:FUNCTION:RSA
+d2i_X509_AUX                            1980	EXIST::FUNCTION:
+i2d_DSA_PUBKEY                          1981	EXIST::FUNCTION:DSA
+X509_CERT_AUX_print                     1982	EXIST::FUNCTION:BIO
+PEM_read_DSA_PUBKEY                     1984	EXIST:!WIN16:FUNCTION:DSA
+i2d_RSA_PUBKEY_bio                      1985	EXIST::FUNCTION:BIO,RSA
+ASN1_BIT_STRING_num_asc                 1986	EXIST::FUNCTION:
+i2d_PUBKEY                              1987	EXIST::FUNCTION:
+ASN1_UTCTIME_free                       1988	EXIST::FUNCTION:
+DSA_set_default_method                  1989	EXIST::FUNCTION:DSA
+X509_PURPOSE_get_by_id                  1990	EXIST::FUNCTION:
+ACCESS_DESCRIPTION_free                 1994	EXIST::FUNCTION:
+PEM_read_bio_PUBKEY                     1995	EXIST::FUNCTION:
+ASN1_STRING_set_by_NID                  1996	EXIST::FUNCTION:
+X509_PURPOSE_get_id                     1997	EXIST::FUNCTION:
+DISPLAYTEXT_free                        1998	EXIST::FUNCTION:
+OTHERNAME_new                           1999	EXIST::FUNCTION:
+X509_CERT_AUX_new                       2001	EXIST::FUNCTION:
+X509_TRUST_cleanup                      2007	EXIST::FUNCTION:
+X509_NAME_add_entry_by_OBJ              2008	EXIST::FUNCTION:
+X509_CRL_get_ext_d2i                    2009	EXIST::FUNCTION:
+X509_PURPOSE_get0_name                  2011	EXIST::FUNCTION:
+PEM_read_PUBKEY                         2012	EXIST:!WIN16:FUNCTION:
+i2d_DSA_PUBKEY_bio                      2014	EXIST::FUNCTION:BIO,DSA
+i2d_OTHERNAME                           2015	EXIST::FUNCTION:
+ASN1_OCTET_STRING_free                  2016	EXIST::FUNCTION:
+ASN1_BIT_STRING_set_asc                 2017	EXIST::FUNCTION:
+X509_get_ex_new_index                   2019	EXIST::FUNCTION:
+ASN1_STRING_TABLE_cleanup               2020	EXIST::FUNCTION:
+X509_TRUST_get_by_id                    2021	EXIST::FUNCTION:
+X509_PURPOSE_get_trust                  2022	EXIST::FUNCTION:
+ASN1_STRING_length                      2023	EXIST::FUNCTION:
+d2i_ASN1_SET_OF_ACCESS_DESCRIPTION      2024	NOEXIST::FUNCTION:
+ASN1_PRINTABLESTRING_new                2025	EXIST::FUNCTION:
+X509V3_get_d2i                          2026	EXIST::FUNCTION:
+ASN1_ENUMERATED_free                    2027	EXIST::FUNCTION:
+i2d_X509_CERT_AUX                       2028	EXIST::FUNCTION:
+X509_STORE_CTX_set_trust                2030	EXIST::FUNCTION:
+ASN1_STRING_set_default_mask            2032	EXIST::FUNCTION:
+X509_STORE_CTX_new                      2033	EXIST::FUNCTION:
+EVP_PKEY_get1_RSA                       2034	EXIST::FUNCTION:RSA
+DIRECTORYSTRING_free                    2038	EXIST::FUNCTION:
+PEM_write_X509_AUX                      2039	EXIST:!WIN16:FUNCTION:
+ASN1_OCTET_STRING_set                   2040	EXIST::FUNCTION:
+d2i_DSA_PUBKEY_fp                       2041	EXIST::FUNCTION:DSA,FP_API
+d2i_RSA_PUBKEY                          2044	EXIST::FUNCTION:RSA
+X509_TRUST_get0_name                    2046	EXIST::FUNCTION:
+X509_TRUST_get0                         2047	EXIST::FUNCTION:
+AUTHORITY_INFO_ACCESS_free              2048	EXIST::FUNCTION:
+ASN1_IA5STRING_new                      2049	EXIST::FUNCTION:
+d2i_DSA_PUBKEY                          2050	EXIST::FUNCTION:DSA
+X509_check_purpose                      2051	EXIST::FUNCTION:
+ASN1_ENUMERATED_new                     2052	EXIST::FUNCTION:
+d2i_RSA_PUBKEY_bio                      2053	EXIST::FUNCTION:BIO,RSA
+d2i_PUBKEY                              2054	EXIST::FUNCTION:
+X509_TRUST_get_trust                    2055	EXIST::FUNCTION:
+X509_TRUST_get_flags                    2056	EXIST::FUNCTION:
+ASN1_BMPSTRING_free                     2057	EXIST::FUNCTION:
+ASN1_T61STRING_new                      2058	EXIST::FUNCTION:
+ASN1_UTCTIME_new                        2060	EXIST::FUNCTION:
+i2d_AUTHORITY_INFO_ACCESS               2062	EXIST::FUNCTION:
+EVP_PKEY_set1_RSA                       2063	EXIST::FUNCTION:RSA
+X509_STORE_CTX_set_purpose              2064	EXIST::FUNCTION:
+ASN1_IA5STRING_free                     2065	EXIST::FUNCTION:
+PEM_write_bio_X509_AUX                  2066	EXIST::FUNCTION:
+X509_PURPOSE_get_count                  2067	EXIST::FUNCTION:
+CRYPTO_add_info                         2068	NOEXIST::FUNCTION:
+X509_NAME_ENTRY_create_by_txt           2071	EXIST::FUNCTION:
+ASN1_STRING_get_default_mask            2072	EXIST::FUNCTION:
+X509_alias_get0                         2074	EXIST::FUNCTION:
+ASN1_STRING_data                        2075	EXIST::FUNCTION:
+i2d_ACCESS_DESCRIPTION                  2077	EXIST::FUNCTION:
+X509_trust_set_bit                      2078	NOEXIST::FUNCTION:
+ASN1_BIT_STRING_free                    2080	EXIST::FUNCTION:
+PEM_read_bio_RSA_PUBKEY                 2081	EXIST::FUNCTION:RSA
+X509_add1_reject_object                 2082	EXIST::FUNCTION:
+X509_check_trust                        2083	EXIST::FUNCTION:
+PEM_read_bio_DSA_PUBKEY                 2088	EXIST::FUNCTION:DSA
+X509_PURPOSE_add                        2090	EXIST::FUNCTION:
+ASN1_STRING_TABLE_get                   2091	EXIST::FUNCTION:
+ASN1_UTF8STRING_free                    2092	EXIST::FUNCTION:
+d2i_DSA_PUBKEY_bio                      2093	EXIST::FUNCTION:BIO,DSA
+PEM_write_RSA_PUBKEY                    2095	EXIST:!WIN16:FUNCTION:RSA
+d2i_OTHERNAME                           2096	EXIST::FUNCTION:
+X509_reject_set_bit                     2098	NOEXIST::FUNCTION:
+PEM_write_DSA_PUBKEY                    2101	EXIST:!WIN16:FUNCTION:DSA
+X509_PURPOSE_get0_sname                 2105	EXIST::FUNCTION:
+EVP_PKEY_set1_DH                        2107	EXIST::FUNCTION:DH
+ASN1_OCTET_STRING_dup                   2108	EXIST::FUNCTION:
+ASN1_BIT_STRING_set                     2109	EXIST::FUNCTION:
+X509_TRUST_get_count                    2110	EXIST::FUNCTION:
+ASN1_INTEGER_free                       2111	EXIST::FUNCTION:
+OTHERNAME_free                          2112	EXIST::FUNCTION:
+i2d_RSA_PUBKEY_fp                       2113	EXIST::FUNCTION:FP_API,RSA
+ASN1_INTEGER_dup                        2114	EXIST::FUNCTION:
+d2i_X509_CERT_AUX                       2115	EXIST::FUNCTION:
+PEM_write_bio_PUBKEY                    2117	EXIST::FUNCTION:
+ASN1_VISIBLESTRING_free                 2118	EXIST::FUNCTION:
+X509_PURPOSE_cleanup                    2119	EXIST::FUNCTION:
+ASN1_mbstring_ncopy                     2123	EXIST::FUNCTION:
+ASN1_GENERALIZEDTIME_new                2126	EXIST::FUNCTION:
+EVP_PKEY_get1_DH                        2128	EXIST::FUNCTION:DH
+ASN1_OCTET_STRING_new                   2130	EXIST::FUNCTION:
+ASN1_INTEGER_new                        2131	EXIST::FUNCTION:
+i2d_X509_AUX                            2132	EXIST::FUNCTION:
+ASN1_BIT_STRING_name_print              2134	EXIST::FUNCTION:BIO
+X509_cmp                                2135	EXIST::FUNCTION:
+ASN1_STRING_length_set                  2136	EXIST::FUNCTION:
+DIRECTORYSTRING_new                     2137	EXIST::FUNCTION:
+X509_add1_trust_object                  2140	EXIST::FUNCTION:
+PKCS12_newpass                          2141	EXIST::FUNCTION:
+SMIME_write_PKCS7                       2142	EXIST::FUNCTION:
+SMIME_read_PKCS7                        2143	EXIST::FUNCTION:
+DES_set_key_checked                     2144	EXIST::FUNCTION:DES
+PKCS7_verify                            2145	EXIST::FUNCTION:
+PKCS7_encrypt                           2146	EXIST::FUNCTION:
+DES_set_key_unchecked                   2147	EXIST::FUNCTION:DES
+SMIME_crlf_copy                         2148	EXIST::FUNCTION:
+i2d_ASN1_PRINTABLESTRING                2149	EXIST::FUNCTION:
+PKCS7_get0_signers                      2150	EXIST::FUNCTION:
+PKCS7_decrypt                           2151	EXIST::FUNCTION:
+SMIME_text                              2152	EXIST::FUNCTION:
+PKCS7_simple_smimecap                   2153	EXIST::FUNCTION:
+PKCS7_get_smimecap                      2154	EXIST::FUNCTION:
+PKCS7_sign                              2155	EXIST::FUNCTION:
+PKCS7_add_attrib_smimecap               2156	EXIST::FUNCTION:
+CRYPTO_dbg_set_options                  2157	EXIST::FUNCTION:
+CRYPTO_remove_all_info                  2158	EXIST::FUNCTION:
+CRYPTO_get_mem_debug_functions          2159	EXIST::FUNCTION:
+CRYPTO_is_mem_check_on                  2160	EXIST::FUNCTION:
+CRYPTO_set_mem_debug_functions          2161	EXIST::FUNCTION:
+CRYPTO_pop_info                         2162	EXIST::FUNCTION:
+CRYPTO_push_info_                       2163	EXIST::FUNCTION:
+CRYPTO_set_mem_debug_options            2164	EXIST::FUNCTION:
+PEM_write_PKCS8PrivateKey_nid           2165	EXIST::FUNCTION:
+PEM_write_bio_PKCS8PrivateKey_nid       2166	EXIST:!VMS:FUNCTION:
+PEM_write_bio_PKCS8PrivKey_nid          2166	EXIST:VMS:FUNCTION:
+d2i_PKCS8PrivateKey_bio                 2167	EXIST::FUNCTION:
+ASN1_NULL_free                          2168	EXIST::FUNCTION:
+d2i_ASN1_NULL                           2169	EXIST::FUNCTION:
+ASN1_NULL_new                           2170	EXIST::FUNCTION:
+i2d_PKCS8PrivateKey_bio                 2171	EXIST::FUNCTION:
+i2d_PKCS8PrivateKey_fp                  2172	EXIST::FUNCTION:
+i2d_ASN1_NULL                           2173	EXIST::FUNCTION:
+i2d_PKCS8PrivateKey_nid_fp              2174	EXIST::FUNCTION:
+d2i_PKCS8PrivateKey_fp                  2175	EXIST::FUNCTION:
+i2d_PKCS8PrivateKey_nid_bio             2176	EXIST::FUNCTION:
+i2d_PKCS8PrivateKeyInfo_fp              2177	EXIST::FUNCTION:FP_API
+i2d_PKCS8PrivateKeyInfo_bio             2178	EXIST::FUNCTION:BIO
+PEM_cb                                  2179	NOEXIST::FUNCTION:
+i2d_PrivateKey_fp                       2180	EXIST::FUNCTION:FP_API
+d2i_PrivateKey_bio                      2181	EXIST::FUNCTION:BIO
+d2i_PrivateKey_fp                       2182	EXIST::FUNCTION:FP_API
+i2d_PrivateKey_bio                      2183	EXIST::FUNCTION:BIO
+X509_reject_clear                       2184	EXIST::FUNCTION:
+X509_TRUST_set_default                  2185	EXIST::FUNCTION:
+d2i_AutoPrivateKey                      2186	EXIST::FUNCTION:
+X509_ATTRIBUTE_get0_type                2187	EXIST::FUNCTION:
+X509_ATTRIBUTE_set1_data                2188	EXIST::FUNCTION:
+X509at_get_attr                         2189	EXIST::FUNCTION:
+X509at_get_attr_count                   2190	EXIST::FUNCTION:
+X509_ATTRIBUTE_create_by_NID            2191	EXIST::FUNCTION:
+X509_ATTRIBUTE_set1_object              2192	EXIST::FUNCTION:
+X509_ATTRIBUTE_count                    2193	EXIST::FUNCTION:
+X509_ATTRIBUTE_create_by_OBJ            2194	EXIST::FUNCTION:
+X509_ATTRIBUTE_get0_object              2195	EXIST::FUNCTION:
+X509at_get_attr_by_NID                  2196	EXIST::FUNCTION:
+X509at_add1_attr                        2197	EXIST::FUNCTION:
+X509_ATTRIBUTE_get0_data                2198	EXIST::FUNCTION:
+X509at_delete_attr                      2199	EXIST::FUNCTION:
+X509at_get_attr_by_OBJ                  2200	EXIST::FUNCTION:
+RAND_add                                2201	EXIST::FUNCTION:
+BIO_number_written                      2202	EXIST::FUNCTION:
+BIO_number_read                         2203	EXIST::FUNCTION:
+X509_STORE_CTX_get1_chain               2204	EXIST::FUNCTION:
+ERR_load_RAND_strings                   2205	EXIST::FUNCTION:
+RAND_pseudo_bytes                       2206	EXIST::FUNCTION:
+X509_REQ_get_attr_by_NID                2207	EXIST::FUNCTION:
+X509_REQ_get_attr                       2208	EXIST::FUNCTION:
+X509_REQ_add1_attr_by_NID               2209	EXIST::FUNCTION:
+X509_REQ_get_attr_by_OBJ                2210	EXIST::FUNCTION:
+X509at_add1_attr_by_NID                 2211	EXIST::FUNCTION:
+X509_REQ_add1_attr_by_OBJ               2212	EXIST::FUNCTION:
+X509_REQ_get_attr_count                 2213	EXIST::FUNCTION:
+X509_REQ_add1_attr                      2214	EXIST::FUNCTION:
+X509_REQ_delete_attr                    2215	EXIST::FUNCTION:
+X509at_add1_attr_by_OBJ                 2216	EXIST::FUNCTION:
+X509_REQ_add1_attr_by_txt               2217	EXIST::FUNCTION:
+X509_ATTRIBUTE_create_by_txt            2218	EXIST::FUNCTION:
+X509at_add1_attr_by_txt                 2219	EXIST::FUNCTION:
+BN_pseudo_rand                          2239	EXIST::FUNCTION:
+BN_is_prime_fasttest                    2240	EXIST::FUNCTION:DEPRECATED
+BN_CTX_end                              2241	EXIST::FUNCTION:
+BN_CTX_start                            2242	EXIST::FUNCTION:
+BN_CTX_get                              2243	EXIST::FUNCTION:
+EVP_PKEY2PKCS8_broken                   2244	EXIST::FUNCTION:
+ASN1_STRING_TABLE_add                   2245	EXIST::FUNCTION:
+CRYPTO_dbg_get_options                  2246	EXIST::FUNCTION:
+AUTHORITY_INFO_ACCESS_new               2247	EXIST::FUNCTION:
+CRYPTO_get_mem_debug_options            2248	EXIST::FUNCTION:
+DES_crypt                               2249	EXIST::FUNCTION:DES
+PEM_write_bio_X509_REQ_NEW              2250	EXIST::FUNCTION:
+PEM_write_X509_REQ_NEW                  2251	EXIST:!WIN16:FUNCTION:
+BIO_callback_ctrl                       2252	EXIST::FUNCTION:
+RAND_egd                                2253	EXIST::FUNCTION:
+RAND_status                             2254	EXIST::FUNCTION:
+bn_dump1                                2255	NOEXIST::FUNCTION:
+DES_check_key_parity                    2256	EXIST::FUNCTION:DES
+lh_num_items                            2257	EXIST::FUNCTION:
+RAND_event                              2258	EXIST:WIN32:FUNCTION:
+DSO_new                                 2259	EXIST::FUNCTION:
+DSO_new_method                          2260	EXIST::FUNCTION:
+DSO_free                                2261	EXIST::FUNCTION:
+DSO_flags                               2262	EXIST::FUNCTION:
+DSO_up                                  2263	NOEXIST::FUNCTION:
+DSO_set_default_method                  2264	EXIST::FUNCTION:
+DSO_get_default_method                  2265	EXIST::FUNCTION:
+DSO_get_method                          2266	EXIST::FUNCTION:
+DSO_set_method                          2267	EXIST::FUNCTION:
+DSO_load                                2268	EXIST::FUNCTION:
+DSO_bind_var                            2269	EXIST::FUNCTION:
+DSO_METHOD_null                         2270	EXIST::FUNCTION:
+DSO_METHOD_openssl                      2271	EXIST::FUNCTION:
+DSO_METHOD_dlfcn                        2272	EXIST::FUNCTION:
+DSO_METHOD_win32                        2273	EXIST::FUNCTION:
+ERR_load_DSO_strings                    2274	EXIST::FUNCTION:
+DSO_METHOD_dl                           2275	EXIST::FUNCTION:
+NCONF_load                              2276	EXIST::FUNCTION:
+NCONF_load_fp                           2278	EXIST::FUNCTION:FP_API
+NCONF_new                               2279	EXIST::FUNCTION:
+NCONF_get_string                        2280	EXIST::FUNCTION:
+NCONF_free                              2281	EXIST::FUNCTION:
+NCONF_get_number                        2282	NOEXIST::FUNCTION:
+CONF_dump_fp                            2283	EXIST::FUNCTION:
+NCONF_load_bio                          2284	EXIST::FUNCTION:
+NCONF_dump_fp                           2285	EXIST::FUNCTION:
+NCONF_get_section                       2286	EXIST::FUNCTION:
+NCONF_dump_bio                          2287	EXIST::FUNCTION:
+CONF_dump_bio                           2288	EXIST::FUNCTION:
+NCONF_free_data                         2289	EXIST::FUNCTION:
+CONF_set_default_method                 2290	EXIST::FUNCTION:
+ERR_error_string_n                      2291	EXIST::FUNCTION:
+BIO_snprintf                            2292	EXIST::FUNCTION:
+DSO_ctrl                                2293	EXIST::FUNCTION:
+i2d_ASN1_SET_OF_ASN1_INTEGER            2317	NOEXIST::FUNCTION:
+i2d_ASN1_SET_OF_PKCS12_SAFEBAG          2320	NOEXIST::FUNCTION:
+i2d_ASN1_SET_OF_PKCS7                   2328	NOEXIST::FUNCTION:
+BIO_vfree                               2334	EXIST::FUNCTION:
+d2i_ASN1_SET_OF_ASN1_INTEGER            2339	NOEXIST::FUNCTION:
+d2i_ASN1_SET_OF_PKCS12_SAFEBAG          2341	NOEXIST::FUNCTION:
+ASN1_UTCTIME_get                        2350	NOEXIST::FUNCTION:
+X509_REQ_digest                         2362	EXIST::FUNCTION:EVP
+X509_CRL_digest                         2391	EXIST::FUNCTION:EVP
+d2i_ASN1_SET_OF_PKCS7                   2397	NOEXIST::FUNCTION:
+EVP_CIPHER_CTX_set_key_length           2399	EXIST::FUNCTION:
+EVP_CIPHER_CTX_ctrl                     2400	EXIST::FUNCTION:
+BN_mod_exp_mont_word                    2401	EXIST::FUNCTION:
+RAND_egd_bytes                          2402	EXIST::FUNCTION:
+X509_REQ_get1_email                     2403	EXIST::FUNCTION:
+X509_get1_email                         2404	EXIST::FUNCTION:
+X509_email_free                         2405	EXIST::FUNCTION:
+i2d_RSA_NET                             2406	EXIST::FUNCTION:RC4,RSA
+d2i_RSA_NET_2                           2407	NOEXIST::FUNCTION:
+d2i_RSA_NET                             2408	EXIST::FUNCTION:RC4,RSA
+DSO_bind_func                           2409	EXIST::FUNCTION:
+CRYPTO_get_new_dynlockid                2410	EXIST::FUNCTION:
+sk_new_null                             2411	EXIST::FUNCTION:
+CRYPTO_set_dynlock_destroy_callback     2412	EXIST:!VMS:FUNCTION:
+CRYPTO_set_dynlock_destroy_cb           2412	EXIST:VMS:FUNCTION:
+CRYPTO_destroy_dynlockid                2413	EXIST::FUNCTION:
+CRYPTO_set_dynlock_size                 2414	NOEXIST::FUNCTION:
+CRYPTO_set_dynlock_create_callback      2415	EXIST:!VMS:FUNCTION:
+CRYPTO_set_dynlock_create_cb            2415	EXIST:VMS:FUNCTION:
+CRYPTO_set_dynlock_lock_callback        2416	EXIST:!VMS:FUNCTION:
+CRYPTO_set_dynlock_lock_cb              2416	EXIST:VMS:FUNCTION:
+CRYPTO_get_dynlock_lock_callback        2417	EXIST:!VMS:FUNCTION:
+CRYPTO_get_dynlock_lock_cb              2417	EXIST:VMS:FUNCTION:
+CRYPTO_get_dynlock_destroy_callback     2418	EXIST:!VMS:FUNCTION:
+CRYPTO_get_dynlock_destroy_cb           2418	EXIST:VMS:FUNCTION:
+CRYPTO_get_dynlock_value                2419	EXIST::FUNCTION:
+CRYPTO_get_dynlock_create_callback      2420	EXIST:!VMS:FUNCTION:
+CRYPTO_get_dynlock_create_cb            2420	EXIST:VMS:FUNCTION:
+c2i_ASN1_BIT_STRING                     2421	EXIST::FUNCTION:
+i2c_ASN1_BIT_STRING                     2422	EXIST::FUNCTION:
+RAND_poll                               2423	EXIST::FUNCTION:
+c2i_ASN1_INTEGER                        2424	EXIST::FUNCTION:
+i2c_ASN1_INTEGER                        2425	EXIST::FUNCTION:
+BIO_dump_indent                         2426	EXIST::FUNCTION:
+ASN1_parse_dump                         2427	EXIST::FUNCTION:BIO
+c2i_ASN1_OBJECT                         2428	EXIST::FUNCTION:
+X509_NAME_print_ex_fp                   2429	EXIST::FUNCTION:FP_API
+ASN1_STRING_print_ex_fp                 2430	EXIST::FUNCTION:FP_API
+X509_NAME_print_ex                      2431	EXIST::FUNCTION:BIO
+ASN1_STRING_print_ex                    2432	EXIST::FUNCTION:BIO
+MD4                                     2433	EXIST::FUNCTION:MD4
+MD4_Transform                           2434	EXIST::FUNCTION:MD4
+MD4_Final                               2435	EXIST::FUNCTION:MD4
+MD4_Update                              2436	EXIST::FUNCTION:MD4
+MD4_Init                                2437	EXIST::FUNCTION:MD4
+EVP_md4                                 2438	EXIST::FUNCTION:MD4
+i2d_PUBKEY_bio                          2439	EXIST::FUNCTION:BIO
+i2d_PUBKEY_fp                           2440	EXIST::FUNCTION:FP_API
+d2i_PUBKEY_bio                          2441	EXIST::FUNCTION:BIO
+ASN1_STRING_to_UTF8                     2442	EXIST::FUNCTION:
+BIO_vprintf                             2443	EXIST::FUNCTION:
+BIO_vsnprintf                           2444	EXIST::FUNCTION:
+d2i_PUBKEY_fp                           2445	EXIST::FUNCTION:FP_API
+X509_cmp_time                           2446	EXIST::FUNCTION:
+X509_STORE_CTX_set_time                 2447	EXIST::FUNCTION:
+X509_STORE_CTX_get1_issuer              2448	EXIST::FUNCTION:
+X509_OBJECT_retrieve_match              2449	EXIST::FUNCTION:
+X509_OBJECT_idx_by_subject              2450	EXIST::FUNCTION:
+X509_STORE_CTX_set_flags                2451	EXIST::FUNCTION:
+X509_STORE_CTX_trusted_stack            2452	EXIST::FUNCTION:
+X509_time_adj                           2453	EXIST::FUNCTION:
+X509_check_issued                       2454	EXIST::FUNCTION:
+ASN1_UTCTIME_cmp_time_t                 2455	EXIST::FUNCTION:
+DES_set_weak_key_flag                   2456	NOEXIST::FUNCTION:
+DES_check_key                           2457	NOEXIST::FUNCTION:
+DES_rw_mode                             2458	NOEXIST::FUNCTION:
+RSA_PKCS1_RSAref                        2459	NOEXIST::FUNCTION:
+X509_keyid_set1                         2460	EXIST::FUNCTION:
+BIO_next                                2461	EXIST::FUNCTION:
+DSO_METHOD_vms                          2462	EXIST::FUNCTION:
+BIO_f_linebuffer                        2463	EXIST:VMS:FUNCTION:
+BN_bntest_rand                          2464	EXIST::FUNCTION:
+OPENSSL_issetugid                       2465	EXIST::FUNCTION:
+BN_rand_range                           2466	EXIST::FUNCTION:
+ERR_load_ENGINE_strings                 2467	EXIST::FUNCTION:ENGINE
+ENGINE_set_DSA                          2468	EXIST::FUNCTION:ENGINE
+ENGINE_get_finish_function              2469	EXIST::FUNCTION:ENGINE
+ENGINE_get_default_RSA                  2470	EXIST::FUNCTION:ENGINE
+ENGINE_get_BN_mod_exp                   2471	NOEXIST::FUNCTION:
+DSA_get_default_openssl_method          2472	NOEXIST::FUNCTION:
+ENGINE_set_DH                           2473	EXIST::FUNCTION:ENGINE
+ENGINE_set_def_BN_mod_exp_crt           2474	NOEXIST::FUNCTION:
+ENGINE_set_default_BN_mod_exp_crt       2474	NOEXIST::FUNCTION:
+ENGINE_init                             2475	EXIST::FUNCTION:ENGINE
+DH_get_default_openssl_method           2476	NOEXIST::FUNCTION:
+RSA_set_default_openssl_method          2477	NOEXIST::FUNCTION:
+ENGINE_finish                           2478	EXIST::FUNCTION:ENGINE
+ENGINE_load_public_key                  2479	EXIST::FUNCTION:ENGINE
+ENGINE_get_DH                           2480	EXIST::FUNCTION:ENGINE
+ENGINE_ctrl                             2481	EXIST::FUNCTION:ENGINE
+ENGINE_get_init_function                2482	EXIST::FUNCTION:ENGINE
+ENGINE_set_init_function                2483	EXIST::FUNCTION:ENGINE
+ENGINE_set_default_DSA                  2484	EXIST::FUNCTION:ENGINE
+ENGINE_get_name                         2485	EXIST::FUNCTION:ENGINE
+ENGINE_get_last                         2486	EXIST::FUNCTION:ENGINE
+ENGINE_get_prev                         2487	EXIST::FUNCTION:ENGINE
+ENGINE_get_default_DH                   2488	EXIST::FUNCTION:ENGINE
+ENGINE_get_RSA                          2489	EXIST::FUNCTION:ENGINE
+ENGINE_set_default                      2490	EXIST::FUNCTION:ENGINE
+ENGINE_get_RAND                         2491	EXIST::FUNCTION:ENGINE
+ENGINE_get_first                        2492	EXIST::FUNCTION:ENGINE
+ENGINE_by_id                            2493	EXIST::FUNCTION:ENGINE
+ENGINE_set_finish_function              2494	EXIST::FUNCTION:ENGINE
+ENGINE_get_def_BN_mod_exp_crt           2495	NOEXIST::FUNCTION:
+ENGINE_get_default_BN_mod_exp_crt       2495	NOEXIST::FUNCTION:
+RSA_get_default_openssl_method          2496	NOEXIST::FUNCTION:
+ENGINE_set_RSA                          2497	EXIST::FUNCTION:ENGINE
+ENGINE_load_private_key                 2498	EXIST::FUNCTION:ENGINE
+ENGINE_set_default_RAND                 2499	EXIST::FUNCTION:ENGINE
+ENGINE_set_BN_mod_exp                   2500	NOEXIST::FUNCTION:
+ENGINE_remove                           2501	EXIST::FUNCTION:ENGINE
+ENGINE_free                             2502	EXIST::FUNCTION:ENGINE
+ENGINE_get_BN_mod_exp_crt               2503	NOEXIST::FUNCTION:
+ENGINE_get_next                         2504	EXIST::FUNCTION:ENGINE
+ENGINE_set_name                         2505	EXIST::FUNCTION:ENGINE
+ENGINE_get_default_DSA                  2506	EXIST::FUNCTION:ENGINE
+ENGINE_set_default_BN_mod_exp           2507	NOEXIST::FUNCTION:
+ENGINE_set_default_RSA                  2508	EXIST::FUNCTION:ENGINE
+ENGINE_get_default_RAND                 2509	EXIST::FUNCTION:ENGINE
+ENGINE_get_default_BN_mod_exp           2510	NOEXIST::FUNCTION:
+ENGINE_set_RAND                         2511	EXIST::FUNCTION:ENGINE
+ENGINE_set_id                           2512	EXIST::FUNCTION:ENGINE
+ENGINE_set_BN_mod_exp_crt               2513	NOEXIST::FUNCTION:
+ENGINE_set_default_DH                   2514	EXIST::FUNCTION:ENGINE
+ENGINE_new                              2515	EXIST::FUNCTION:ENGINE
+ENGINE_get_id                           2516	EXIST::FUNCTION:ENGINE
+DSA_set_default_openssl_method          2517	NOEXIST::FUNCTION:
+ENGINE_add                              2518	EXIST::FUNCTION:ENGINE
+DH_set_default_openssl_method           2519	NOEXIST::FUNCTION:
+ENGINE_get_DSA                          2520	EXIST::FUNCTION:ENGINE
+ENGINE_get_ctrl_function                2521	EXIST::FUNCTION:ENGINE
+ENGINE_set_ctrl_function                2522	EXIST::FUNCTION:ENGINE
+BN_pseudo_rand_range                    2523	EXIST::FUNCTION:
+X509_STORE_CTX_set_verify_cb            2524	EXIST::FUNCTION:
+ERR_load_COMP_strings                   2525	EXIST::FUNCTION:
+PKCS12_item_decrypt_d2i                 2526	EXIST::FUNCTION:
+ASN1_UTF8STRING_it                      2527	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_UTF8STRING_it                      2527	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ENGINE_unregister_ciphers               2528	EXIST::FUNCTION:ENGINE
+ENGINE_get_ciphers                      2529	EXIST::FUNCTION:ENGINE
+d2i_OCSP_BASICRESP                      2530	EXIST::FUNCTION:
+KRB5_CHECKSUM_it                        2531	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+KRB5_CHECKSUM_it                        2531	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+EC_POINT_add                            2532	EXIST::FUNCTION:EC
+ASN1_item_ex_i2d                        2533	EXIST::FUNCTION:
+OCSP_CERTID_it                          2534	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+OCSP_CERTID_it                          2534	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+d2i_OCSP_RESPBYTES                      2535	EXIST::FUNCTION:
+X509V3_add1_i2d                         2536	EXIST::FUNCTION:
+PKCS7_ENVELOPE_it                       2537	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS7_ENVELOPE_it                       2537	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+UI_add_input_boolean                    2538	EXIST::FUNCTION:
+ENGINE_unregister_RSA                   2539	EXIST::FUNCTION:ENGINE
+X509V3_EXT_nconf                        2540	EXIST::FUNCTION:
+ASN1_GENERALSTRING_free                 2541	EXIST::FUNCTION:
+d2i_OCSP_CERTSTATUS                     2542	EXIST::FUNCTION:
+X509_REVOKED_set_serialNumber           2543	EXIST::FUNCTION:
+X509_print_ex                           2544	EXIST::FUNCTION:BIO
+OCSP_ONEREQ_get1_ext_d2i                2545	EXIST::FUNCTION:
+ENGINE_register_all_RAND                2546	EXIST::FUNCTION:ENGINE
+ENGINE_load_dynamic                     2547	EXIST::FUNCTION:ENGINE
+PBKDF2PARAM_it                          2548	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PBKDF2PARAM_it                          2548	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+EXTENDED_KEY_USAGE_new                  2549	EXIST::FUNCTION:
+EC_GROUP_clear_free                     2550	EXIST::FUNCTION:EC
+OCSP_sendreq_bio                        2551	EXIST::FUNCTION:
+ASN1_item_digest                        2552	EXIST::FUNCTION:EVP
+OCSP_BASICRESP_delete_ext               2553	EXIST::FUNCTION:
+OCSP_SIGNATURE_it                       2554	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+OCSP_SIGNATURE_it                       2554	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+X509_CRL_it                             2555	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_CRL_it                             2555	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+OCSP_BASICRESP_add_ext                  2556	EXIST::FUNCTION:
+KRB5_ENCKEY_it                          2557	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+KRB5_ENCKEY_it                          2557	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+UI_method_set_closer                    2558	EXIST::FUNCTION:
+X509_STORE_set_purpose                  2559	EXIST::FUNCTION:
+i2d_ASN1_GENERALSTRING                  2560	EXIST::FUNCTION:
+OCSP_response_status                    2561	EXIST::FUNCTION:
+i2d_OCSP_SERVICELOC                     2562	EXIST::FUNCTION:
+ENGINE_get_digest_engine                2563	EXIST::FUNCTION:ENGINE
+EC_GROUP_set_curve_GFp                  2564	EXIST::FUNCTION:EC
+OCSP_REQUEST_get_ext_by_OBJ             2565	EXIST::FUNCTION:
+_ossl_old_des_random_key                2566	EXIST::FUNCTION:DES
+ASN1_T61STRING_it                       2567	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_T61STRING_it                       2567	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+EC_GROUP_method_of                      2568	EXIST::FUNCTION:EC
+i2d_KRB5_APREQ                          2569	EXIST::FUNCTION:
+_ossl_old_des_encrypt                   2570	EXIST::FUNCTION:DES
+ASN1_PRINTABLE_new                      2571	EXIST::FUNCTION:
+HMAC_Init_ex                            2572	EXIST::FUNCTION:HMAC
+d2i_KRB5_AUTHENT                        2573	EXIST::FUNCTION:
+OCSP_archive_cutoff_new                 2574	EXIST::FUNCTION:
+EC_POINT_set_Jprojective_coordinates_GFp 2575	EXIST:!VMS:FUNCTION:EC
+EC_POINT_set_Jproj_coords_GFp           2575	EXIST:VMS:FUNCTION:EC
+_ossl_old_des_is_weak_key               2576	EXIST::FUNCTION:DES
+OCSP_BASICRESP_get_ext_by_OBJ           2577	EXIST::FUNCTION:
+EC_POINT_oct2point                      2578	EXIST::FUNCTION:EC
+OCSP_SINGLERESP_get_ext_count           2579	EXIST::FUNCTION:
+UI_ctrl                                 2580	EXIST::FUNCTION:
+_shadow_DES_rw_mode                     2581	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:DES
+_shadow_DES_rw_mode                     2581	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:DES
+asn1_do_adb                             2582	EXIST::FUNCTION:
+ASN1_template_i2d                       2583	EXIST::FUNCTION:
+ENGINE_register_DH                      2584	EXIST::FUNCTION:ENGINE
+UI_construct_prompt                     2585	EXIST::FUNCTION:
+X509_STORE_set_trust                    2586	EXIST::FUNCTION:
+UI_dup_input_string                     2587	EXIST::FUNCTION:
+d2i_KRB5_APREQ                          2588	EXIST::FUNCTION:
+EVP_MD_CTX_copy_ex                      2589	EXIST::FUNCTION:
+OCSP_request_is_signed                  2590	EXIST::FUNCTION:
+i2d_OCSP_REQINFO                        2591	EXIST::FUNCTION:
+KRB5_ENCKEY_free                        2592	EXIST::FUNCTION:
+OCSP_resp_get0                          2593	EXIST::FUNCTION:
+GENERAL_NAME_it                         2594	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+GENERAL_NAME_it                         2594	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ASN1_GENERALIZEDTIME_it                 2595	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_GENERALIZEDTIME_it                 2595	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+X509_STORE_set_flags                    2596	EXIST::FUNCTION:
+EC_POINT_set_compressed_coordinates_GFp 2597	EXIST:!VMS:FUNCTION:EC
+EC_POINT_set_compr_coords_GFp           2597	EXIST:VMS:FUNCTION:EC
+OCSP_response_status_str                2598	EXIST::FUNCTION:
+d2i_OCSP_REVOKEDINFO                    2599	EXIST::FUNCTION:
+OCSP_basic_add1_cert                    2600	EXIST::FUNCTION:
+ERR_get_implementation                  2601	EXIST::FUNCTION:
+EVP_CipherFinal_ex                      2602	EXIST::FUNCTION:
+OCSP_CERTSTATUS_new                     2603	EXIST::FUNCTION:
+CRYPTO_cleanup_all_ex_data              2604	EXIST::FUNCTION:
+OCSP_resp_find                          2605	EXIST::FUNCTION:
+BN_nnmod                                2606	EXIST::FUNCTION:
+X509_CRL_sort                           2607	EXIST::FUNCTION:
+X509_REVOKED_set_revocationDate         2608	EXIST::FUNCTION:
+ENGINE_register_RAND                    2609	EXIST::FUNCTION:ENGINE
+OCSP_SERVICELOC_new                     2610	EXIST::FUNCTION:
+EC_POINT_set_affine_coordinates_GFp     2611	EXIST:!VMS:FUNCTION:EC
+EC_POINT_set_affine_coords_GFp          2611	EXIST:VMS:FUNCTION:EC
+_ossl_old_des_options                   2612	EXIST::FUNCTION:DES
+SXNET_it                                2613	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+SXNET_it                                2613	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+UI_dup_input_boolean                    2614	EXIST::FUNCTION:
+PKCS12_add_CSPName_asc                  2615	EXIST::FUNCTION:
+EC_POINT_is_at_infinity                 2616	EXIST::FUNCTION:EC
+ENGINE_load_cryptodev                   2617	EXIST::FUNCTION:ENGINE
+DSO_convert_filename                    2618	EXIST::FUNCTION:
+POLICYQUALINFO_it                       2619	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+POLICYQUALINFO_it                       2619	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ENGINE_register_ciphers                 2620	EXIST::FUNCTION:ENGINE
+BN_mod_lshift_quick                     2621	EXIST::FUNCTION:
+DSO_set_filename                        2622	EXIST::FUNCTION:
+ASN1_item_free                          2623	EXIST::FUNCTION:
+KRB5_TKTBODY_free                       2624	EXIST::FUNCTION:
+AUTHORITY_KEYID_it                      2625	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+AUTHORITY_KEYID_it                      2625	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+KRB5_APREQBODY_new                      2626	EXIST::FUNCTION:
+X509V3_EXT_REQ_add_nconf                2627	EXIST::FUNCTION:
+ENGINE_ctrl_cmd_string                  2628	EXIST::FUNCTION:ENGINE
+i2d_OCSP_RESPDATA                       2629	EXIST::FUNCTION:
+EVP_MD_CTX_init                         2630	EXIST::FUNCTION:
+EXTENDED_KEY_USAGE_free                 2631	EXIST::FUNCTION:
+PKCS7_ATTR_SIGN_it                      2632	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS7_ATTR_SIGN_it                      2632	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+UI_add_error_string                     2633	EXIST::FUNCTION:
+KRB5_CHECKSUM_free                      2634	EXIST::FUNCTION:
+OCSP_REQUEST_get_ext                    2635	EXIST::FUNCTION:
+ENGINE_load_ubsec                       2636	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
+ENGINE_register_all_digests             2637	EXIST::FUNCTION:ENGINE
+PKEY_USAGE_PERIOD_it                    2638	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKEY_USAGE_PERIOD_it                    2638	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+PKCS12_unpack_authsafes                 2639	EXIST::FUNCTION:
+ASN1_item_unpack                        2640	EXIST::FUNCTION:
+NETSCAPE_SPKAC_it                       2641	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+NETSCAPE_SPKAC_it                       2641	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+X509_REVOKED_it                         2642	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_REVOKED_it                         2642	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ASN1_STRING_encode                      2643	NOEXIST::FUNCTION:
+EVP_aes_128_ecb                         2644	EXIST::FUNCTION:AES
+KRB5_AUTHENT_free                       2645	EXIST::FUNCTION:
+OCSP_BASICRESP_get_ext_by_critical      2646	EXIST:!VMS:FUNCTION:
+OCSP_BASICRESP_get_ext_by_crit          2646	EXIST:VMS:FUNCTION:
+OCSP_cert_status_str                    2647	EXIST::FUNCTION:
+d2i_OCSP_REQUEST                        2648	EXIST::FUNCTION:
+UI_dup_info_string                      2649	EXIST::FUNCTION:
+_ossl_old_des_xwhite_in2out             2650	NOEXIST::FUNCTION:
+PKCS12_it                               2651	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS12_it                               2651	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+OCSP_SINGLERESP_get_ext_by_critical     2652	EXIST:!VMS:FUNCTION:
+OCSP_SINGLERESP_get_ext_by_crit         2652	EXIST:VMS:FUNCTION:
+OCSP_CERTSTATUS_free                    2653	EXIST::FUNCTION:
+_ossl_old_des_crypt                     2654	EXIST::FUNCTION:DES
+ASN1_item_i2d                           2655	EXIST::FUNCTION:
+EVP_DecryptFinal_ex                     2656	EXIST::FUNCTION:
+ENGINE_load_openssl                     2657	EXIST::FUNCTION:ENGINE
+ENGINE_get_cmd_defns                    2658	EXIST::FUNCTION:ENGINE
+ENGINE_set_load_privkey_function        2659	EXIST:!VMS:FUNCTION:ENGINE
+ENGINE_set_load_privkey_fn              2659	EXIST:VMS:FUNCTION:ENGINE
+EVP_EncryptFinal_ex                     2660	EXIST::FUNCTION:
+ENGINE_set_default_digests              2661	EXIST::FUNCTION:ENGINE
+X509_get0_pubkey_bitstr                 2662	EXIST::FUNCTION:
+asn1_ex_i2c                             2663	EXIST::FUNCTION:
+ENGINE_register_RSA                     2664	EXIST::FUNCTION:ENGINE
+ENGINE_unregister_DSA                   2665	EXIST::FUNCTION:ENGINE
+_ossl_old_des_key_sched                 2666	EXIST::FUNCTION:DES
+X509_EXTENSION_it                       2667	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_EXTENSION_it                       2667	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+i2d_KRB5_AUTHENT                        2668	EXIST::FUNCTION:
+SXNETID_it                              2669	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+SXNETID_it                              2669	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+d2i_OCSP_SINGLERESP                     2670	EXIST::FUNCTION:
+EDIPARTYNAME_new                        2671	EXIST::FUNCTION:
+PKCS12_certbag2x509                     2672	EXIST::FUNCTION:
+_ossl_old_des_ofb64_encrypt             2673	EXIST::FUNCTION:DES
+d2i_EXTENDED_KEY_USAGE                  2674	EXIST::FUNCTION:
+ERR_print_errors_cb                     2675	EXIST::FUNCTION:
+ENGINE_set_ciphers                      2676	EXIST::FUNCTION:ENGINE
+d2i_KRB5_APREQBODY                      2677	EXIST::FUNCTION:
+UI_method_get_flusher                   2678	EXIST::FUNCTION:
+X509_PUBKEY_it                          2679	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_PUBKEY_it                          2679	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+_ossl_old_des_enc_read                  2680	EXIST::FUNCTION:DES
+PKCS7_ENCRYPT_it                        2681	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS7_ENCRYPT_it                        2681	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+i2d_OCSP_RESPONSE                       2682	EXIST::FUNCTION:
+EC_GROUP_get_cofactor                   2683	EXIST::FUNCTION:EC
+PKCS12_unpack_p7data                    2684	EXIST::FUNCTION:
+d2i_KRB5_AUTHDATA                       2685	EXIST::FUNCTION:
+OCSP_copy_nonce                         2686	EXIST::FUNCTION:
+KRB5_AUTHDATA_new                       2687	EXIST::FUNCTION:
+OCSP_RESPDATA_new                       2688	EXIST::FUNCTION:
+EC_GFp_mont_method                      2689	EXIST::FUNCTION:EC
+OCSP_REVOKEDINFO_free                   2690	EXIST::FUNCTION:
+UI_get_ex_data                          2691	EXIST::FUNCTION:
+KRB5_APREQBODY_free                     2692	EXIST::FUNCTION:
+EC_GROUP_get0_generator                 2693	EXIST::FUNCTION:EC
+UI_get_default_method                   2694	EXIST::FUNCTION:
+X509V3_set_nconf                        2695	EXIST::FUNCTION:
+PKCS12_item_i2d_encrypt                 2696	EXIST::FUNCTION:
+X509_add1_ext_i2d                       2697	EXIST::FUNCTION:
+PKCS7_SIGNER_INFO_it                    2698	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS7_SIGNER_INFO_it                    2698	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+KRB5_PRINCNAME_new                      2699	EXIST::FUNCTION:
+PKCS12_SAFEBAG_it                       2700	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS12_SAFEBAG_it                       2700	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+EC_GROUP_get_order                      2701	EXIST::FUNCTION:EC
+d2i_OCSP_RESPID                         2702	EXIST::FUNCTION:
+OCSP_request_verify                     2703	EXIST::FUNCTION:
+NCONF_get_number_e                      2704	EXIST::FUNCTION:
+_ossl_old_des_decrypt3                  2705	EXIST::FUNCTION:DES
+X509_signature_print                    2706	EXIST::FUNCTION:EVP
+OCSP_SINGLERESP_free                    2707	EXIST::FUNCTION:
+ENGINE_load_builtin_engines             2708	EXIST::FUNCTION:ENGINE
+i2d_OCSP_ONEREQ                         2709	EXIST::FUNCTION:
+OCSP_REQUEST_add_ext                    2710	EXIST::FUNCTION:
+OCSP_RESPBYTES_new                      2711	EXIST::FUNCTION:
+EVP_MD_CTX_create                       2712	EXIST::FUNCTION:
+OCSP_resp_find_status                   2713	EXIST::FUNCTION:
+X509_ALGOR_it                           2714	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_ALGOR_it                           2714	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ASN1_TIME_it                            2715	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_TIME_it                            2715	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+OCSP_request_set1_name                  2716	EXIST::FUNCTION:
+OCSP_ONEREQ_get_ext_count               2717	EXIST::FUNCTION:
+UI_get0_result                          2718	EXIST::FUNCTION:
+PKCS12_AUTHSAFES_it                     2719	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS12_AUTHSAFES_it                     2719	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+EVP_aes_256_ecb                         2720	EXIST::FUNCTION:AES
+PKCS12_pack_authsafes                   2721	EXIST::FUNCTION:
+ASN1_IA5STRING_it                       2722	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_IA5STRING_it                       2722	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+UI_get_input_flags                      2723	EXIST::FUNCTION:
+EC_GROUP_set_generator                  2724	EXIST::FUNCTION:EC
+_ossl_old_des_string_to_2keys           2725	EXIST::FUNCTION:DES
+OCSP_CERTID_free                        2726	EXIST::FUNCTION:
+X509_CERT_AUX_it                        2727	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_CERT_AUX_it                        2727	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+CERTIFICATEPOLICIES_it                  2728	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+CERTIFICATEPOLICIES_it                  2728	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+_ossl_old_des_ede3_cbc_encrypt          2729	EXIST::FUNCTION:DES
+RAND_set_rand_engine                    2730	EXIST::FUNCTION:ENGINE
+DSO_get_loaded_filename                 2731	EXIST::FUNCTION:
+X509_ATTRIBUTE_it                       2732	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_ATTRIBUTE_it                       2732	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+OCSP_ONEREQ_get_ext_by_NID              2733	EXIST::FUNCTION:
+PKCS12_decrypt_skey                     2734	EXIST::FUNCTION:
+KRB5_AUTHENT_it                         2735	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+KRB5_AUTHENT_it                         2735	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+UI_dup_error_string                     2736	EXIST::FUNCTION:
+RSAPublicKey_it                         2737	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RSA
+RSAPublicKey_it                         2737	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RSA
+i2d_OCSP_REQUEST                        2738	EXIST::FUNCTION:
+PKCS12_x509crl2certbag                  2739	EXIST::FUNCTION:
+OCSP_SERVICELOC_it                      2740	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+OCSP_SERVICELOC_it                      2740	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ASN1_item_sign                          2741	EXIST::FUNCTION:EVP
+X509_CRL_set_issuer_name                2742	EXIST::FUNCTION:
+OBJ_NAME_do_all_sorted                  2743	EXIST::FUNCTION:
+i2d_OCSP_BASICRESP                      2744	EXIST::FUNCTION:
+i2d_OCSP_RESPBYTES                      2745	EXIST::FUNCTION:
+PKCS12_unpack_p7encdata                 2746	EXIST::FUNCTION:
+HMAC_CTX_init                           2747	EXIST::FUNCTION:HMAC
+ENGINE_get_digest                       2748	EXIST::FUNCTION:ENGINE
+OCSP_RESPONSE_print                     2749	EXIST::FUNCTION:
+KRB5_TKTBODY_it                         2750	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+KRB5_TKTBODY_it                         2750	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ACCESS_DESCRIPTION_it                   2751	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ACCESS_DESCRIPTION_it                   2751	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+PKCS7_ISSUER_AND_SERIAL_it              2752	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS7_ISSUER_AND_SERIAL_it              2752	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+PBE2PARAM_it                            2753	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PBE2PARAM_it                            2753	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+PKCS12_certbag2x509crl                  2754	EXIST::FUNCTION:
+PKCS7_SIGNED_it                         2755	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS7_SIGNED_it                         2755	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ENGINE_get_cipher                       2756	EXIST::FUNCTION:ENGINE
+i2d_OCSP_CRLID                          2757	EXIST::FUNCTION:
+OCSP_SINGLERESP_new                     2758	EXIST::FUNCTION:
+ENGINE_cmd_is_executable                2759	EXIST::FUNCTION:ENGINE
+RSA_up_ref                              2760	EXIST::FUNCTION:RSA
+ASN1_GENERALSTRING_it                   2761	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_GENERALSTRING_it                   2761	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ENGINE_register_DSA                     2762	EXIST::FUNCTION:ENGINE
+X509V3_EXT_add_nconf_sk                 2763	EXIST::FUNCTION:
+ENGINE_set_load_pubkey_function         2764	EXIST::FUNCTION:ENGINE
+PKCS8_decrypt                           2765	EXIST::FUNCTION:
+PEM_bytes_read_bio                      2766	EXIST::FUNCTION:BIO
+DIRECTORYSTRING_it                      2767	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+DIRECTORYSTRING_it                      2767	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+d2i_OCSP_CRLID                          2768	EXIST::FUNCTION:
+EC_POINT_is_on_curve                    2769	EXIST::FUNCTION:EC
+CRYPTO_set_locked_mem_ex_functions      2770	EXIST:!VMS:FUNCTION:
+CRYPTO_set_locked_mem_ex_funcs          2770	EXIST:VMS:FUNCTION:
+d2i_KRB5_CHECKSUM                       2771	EXIST::FUNCTION:
+ASN1_item_dup                           2772	EXIST::FUNCTION:
+X509_it                                 2773	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_it                                 2773	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+BN_mod_add                              2774	EXIST::FUNCTION:
+KRB5_AUTHDATA_free                      2775	EXIST::FUNCTION:
+_ossl_old_des_cbc_cksum                 2776	EXIST::FUNCTION:DES
+ASN1_item_verify                        2777	EXIST::FUNCTION:EVP
+CRYPTO_set_mem_ex_functions             2778	EXIST::FUNCTION:
+EC_POINT_get_Jprojective_coordinates_GFp 2779	EXIST:!VMS:FUNCTION:EC
+EC_POINT_get_Jproj_coords_GFp           2779	EXIST:VMS:FUNCTION:EC
+ZLONG_it                                2780	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ZLONG_it                                2780	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+CRYPTO_get_locked_mem_ex_functions      2781	EXIST:!VMS:FUNCTION:
+CRYPTO_get_locked_mem_ex_funcs          2781	EXIST:VMS:FUNCTION:
+ASN1_TIME_check                         2782	EXIST::FUNCTION:
+UI_get0_user_data                       2783	EXIST::FUNCTION:
+HMAC_CTX_cleanup                        2784	EXIST::FUNCTION:HMAC
+DSA_up_ref                              2785	EXIST::FUNCTION:DSA
+_ossl_old_des_ede3_cfb64_encrypt        2786	EXIST:!VMS:FUNCTION:DES
+_ossl_odes_ede3_cfb64_encrypt           2786	EXIST:VMS:FUNCTION:DES
+ASN1_BMPSTRING_it                       2787	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_BMPSTRING_it                       2787	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ASN1_tag2bit                            2788	EXIST::FUNCTION:
+UI_method_set_flusher                   2789	EXIST::FUNCTION:
+X509_ocspid_print                       2790	EXIST::FUNCTION:BIO
+KRB5_ENCDATA_it                         2791	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+KRB5_ENCDATA_it                         2791	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ENGINE_get_load_pubkey_function         2792	EXIST::FUNCTION:ENGINE
+UI_add_user_data                        2793	EXIST::FUNCTION:
+OCSP_REQUEST_delete_ext                 2794	EXIST::FUNCTION:
+UI_get_method                           2795	EXIST::FUNCTION:
+OCSP_ONEREQ_free                        2796	EXIST::FUNCTION:
+ASN1_PRINTABLESTRING_it                 2797	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_PRINTABLESTRING_it                 2797	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+X509_CRL_set_nextUpdate                 2798	EXIST::FUNCTION:
+OCSP_REQUEST_it                         2799	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+OCSP_REQUEST_it                         2799	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+OCSP_BASICRESP_it                       2800	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+OCSP_BASICRESP_it                       2800	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+AES_ecb_encrypt                         2801	EXIST::FUNCTION:AES
+BN_mod_sqr                              2802	EXIST::FUNCTION:
+NETSCAPE_CERT_SEQUENCE_it               2803	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+NETSCAPE_CERT_SEQUENCE_it               2803	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+GENERAL_NAMES_it                        2804	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+GENERAL_NAMES_it                        2804	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+AUTHORITY_INFO_ACCESS_it                2805	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+AUTHORITY_INFO_ACCESS_it                2805	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ASN1_FBOOLEAN_it                        2806	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_FBOOLEAN_it                        2806	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+UI_set_ex_data                          2807	EXIST::FUNCTION:
+_ossl_old_des_string_to_key             2808	EXIST::FUNCTION:DES
+ENGINE_register_all_RSA                 2809	EXIST::FUNCTION:ENGINE
+d2i_KRB5_PRINCNAME                      2810	EXIST::FUNCTION:
+OCSP_RESPBYTES_it                       2811	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+OCSP_RESPBYTES_it                       2811	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+X509_CINF_it                            2812	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_CINF_it                            2812	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ENGINE_unregister_digests               2813	EXIST::FUNCTION:ENGINE
+d2i_EDIPARTYNAME                        2814	EXIST::FUNCTION:
+d2i_OCSP_SERVICELOC                     2815	EXIST::FUNCTION:
+ENGINE_get_digests                      2816	EXIST::FUNCTION:ENGINE
+_ossl_old_des_set_odd_parity            2817	EXIST::FUNCTION:DES
+OCSP_RESPDATA_free                      2818	EXIST::FUNCTION:
+d2i_KRB5_TICKET                         2819	EXIST::FUNCTION:
+OTHERNAME_it                            2820	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+OTHERNAME_it                            2820	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+EVP_MD_CTX_cleanup                      2821	EXIST::FUNCTION:
+d2i_ASN1_GENERALSTRING                  2822	EXIST::FUNCTION:
+X509_CRL_set_version                    2823	EXIST::FUNCTION:
+BN_mod_sub                              2824	EXIST::FUNCTION:
+OCSP_SINGLERESP_get_ext_by_NID          2825	EXIST::FUNCTION:
+ENGINE_get_ex_new_index                 2826	EXIST::FUNCTION:ENGINE
+OCSP_REQUEST_free                       2827	EXIST::FUNCTION:
+OCSP_REQUEST_add1_ext_i2d               2828	EXIST::FUNCTION:
+X509_VAL_it                             2829	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_VAL_it                             2829	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+EC_POINTs_make_affine                   2830	EXIST::FUNCTION:EC
+EC_POINT_mul                            2831	EXIST::FUNCTION:EC
+X509V3_EXT_add_nconf                    2832	EXIST::FUNCTION:
+X509_TRUST_set                          2833	EXIST::FUNCTION:
+X509_CRL_add1_ext_i2d                   2834	EXIST::FUNCTION:
+_ossl_old_des_fcrypt                    2835	EXIST::FUNCTION:DES
+DISPLAYTEXT_it                          2836	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+DISPLAYTEXT_it                          2836	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+X509_CRL_set_lastUpdate                 2837	EXIST::FUNCTION:
+OCSP_BASICRESP_free                     2838	EXIST::FUNCTION:
+OCSP_BASICRESP_add1_ext_i2d             2839	EXIST::FUNCTION:
+d2i_KRB5_AUTHENTBODY                    2840	EXIST::FUNCTION:
+CRYPTO_set_ex_data_implementation       2841	EXIST:!VMS:FUNCTION:
+CRYPTO_set_ex_data_impl                 2841	EXIST:VMS:FUNCTION:
+KRB5_ENCDATA_new                        2842	EXIST::FUNCTION:
+DSO_up_ref                              2843	EXIST::FUNCTION:
+OCSP_crl_reason_str                     2844	EXIST::FUNCTION:
+UI_get0_result_string                   2845	EXIST::FUNCTION:
+ASN1_GENERALSTRING_new                  2846	EXIST::FUNCTION:
+X509_SIG_it                             2847	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_SIG_it                             2847	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ERR_set_implementation                  2848	EXIST::FUNCTION:
+ERR_load_EC_strings                     2849	EXIST::FUNCTION:EC
+UI_get0_action_string                   2850	EXIST::FUNCTION:
+OCSP_ONEREQ_get_ext                     2851	EXIST::FUNCTION:
+EC_POINT_method_of                      2852	EXIST::FUNCTION:EC
+i2d_KRB5_APREQBODY                      2853	EXIST::FUNCTION:
+_ossl_old_des_ecb3_encrypt              2854	EXIST::FUNCTION:DES
+CRYPTO_get_mem_ex_functions             2855	EXIST::FUNCTION:
+ENGINE_get_ex_data                      2856	EXIST::FUNCTION:ENGINE
+UI_destroy_method                       2857	EXIST::FUNCTION:
+ASN1_item_i2d_bio                       2858	EXIST::FUNCTION:BIO
+OCSP_ONEREQ_get_ext_by_OBJ              2859	EXIST::FUNCTION:
+ASN1_primitive_new                      2860	EXIST::FUNCTION:
+ASN1_PRINTABLE_it                       2861	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_PRINTABLE_it                       2861	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+EVP_aes_192_ecb                         2862	EXIST::FUNCTION:AES
+OCSP_SIGNATURE_new                      2863	EXIST::FUNCTION:
+LONG_it                                 2864	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+LONG_it                                 2864	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ASN1_VISIBLESTRING_it                   2865	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_VISIBLESTRING_it                   2865	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+OCSP_SINGLERESP_add1_ext_i2d            2866	EXIST::FUNCTION:
+d2i_OCSP_CERTID                         2867	EXIST::FUNCTION:
+ASN1_item_d2i_fp                        2868	EXIST::FUNCTION:FP_API
+CRL_DIST_POINTS_it                      2869	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+CRL_DIST_POINTS_it                      2869	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+GENERAL_NAME_print                      2870	EXIST::FUNCTION:
+OCSP_SINGLERESP_delete_ext              2871	EXIST::FUNCTION:
+PKCS12_SAFEBAGS_it                      2872	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS12_SAFEBAGS_it                      2872	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+d2i_OCSP_SIGNATURE                      2873	EXIST::FUNCTION:
+OCSP_request_add1_nonce                 2874	EXIST::FUNCTION:
+ENGINE_set_cmd_defns                    2875	EXIST::FUNCTION:ENGINE
+OCSP_SERVICELOC_free                    2876	EXIST::FUNCTION:
+EC_GROUP_free                           2877	EXIST::FUNCTION:EC
+ASN1_BIT_STRING_it                      2878	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_BIT_STRING_it                      2878	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+X509_REQ_it                             2879	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_REQ_it                             2879	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+_ossl_old_des_cbc_encrypt               2880	EXIST::FUNCTION:DES
+ERR_unload_strings                      2881	EXIST::FUNCTION:
+PKCS7_SIGN_ENVELOPE_it                  2882	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS7_SIGN_ENVELOPE_it                  2882	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+EDIPARTYNAME_free                       2883	EXIST::FUNCTION:
+OCSP_REQINFO_free                       2884	EXIST::FUNCTION:
+EC_GROUP_new_curve_GFp                  2885	EXIST::FUNCTION:EC
+OCSP_REQUEST_get1_ext_d2i               2886	EXIST::FUNCTION:
+PKCS12_item_pack_safebag                2887	EXIST::FUNCTION:
+asn1_ex_c2i                             2888	EXIST::FUNCTION:
+ENGINE_register_digests                 2889	EXIST::FUNCTION:ENGINE
+i2d_OCSP_REVOKEDINFO                    2890	EXIST::FUNCTION:
+asn1_enc_restore                        2891	EXIST::FUNCTION:
+UI_free                                 2892	EXIST::FUNCTION:
+UI_new_method                           2893	EXIST::FUNCTION:
+EVP_EncryptInit_ex                      2894	EXIST::FUNCTION:
+X509_pubkey_digest                      2895	EXIST::FUNCTION:EVP
+EC_POINT_invert                         2896	EXIST::FUNCTION:EC
+OCSP_basic_sign                         2897	EXIST::FUNCTION:
+i2d_OCSP_RESPID                         2898	EXIST::FUNCTION:
+OCSP_check_nonce                        2899	EXIST::FUNCTION:
+ENGINE_ctrl_cmd                         2900	EXIST::FUNCTION:ENGINE
+d2i_KRB5_ENCKEY                         2901	EXIST::FUNCTION:
+OCSP_parse_url                          2902	EXIST::FUNCTION:
+OCSP_SINGLERESP_get_ext                 2903	EXIST::FUNCTION:
+OCSP_CRLID_free                         2904	EXIST::FUNCTION:
+OCSP_BASICRESP_get1_ext_d2i             2905	EXIST::FUNCTION:
+RSAPrivateKey_it                        2906	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RSA
+RSAPrivateKey_it                        2906	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RSA
+ENGINE_register_all_DH                  2907	EXIST::FUNCTION:ENGINE
+i2d_EDIPARTYNAME                        2908	EXIST::FUNCTION:
+EC_POINT_get_affine_coordinates_GFp     2909	EXIST:!VMS:FUNCTION:EC
+EC_POINT_get_affine_coords_GFp          2909	EXIST:VMS:FUNCTION:EC
+OCSP_CRLID_new                          2910	EXIST::FUNCTION:
+ENGINE_get_flags                        2911	EXIST::FUNCTION:ENGINE
+OCSP_ONEREQ_it                          2912	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+OCSP_ONEREQ_it                          2912	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+UI_process                              2913	EXIST::FUNCTION:
+ASN1_INTEGER_it                         2914	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_INTEGER_it                         2914	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+EVP_CipherInit_ex                       2915	EXIST::FUNCTION:
+UI_get_string_type                      2916	EXIST::FUNCTION:
+ENGINE_unregister_DH                    2917	EXIST::FUNCTION:ENGINE
+ENGINE_register_all_DSA                 2918	EXIST::FUNCTION:ENGINE
+OCSP_ONEREQ_get_ext_by_critical         2919	EXIST::FUNCTION:
+bn_dup_expand                           2920	EXIST::FUNCTION:DEPRECATED
+OCSP_cert_id_new                        2921	EXIST::FUNCTION:
+BASIC_CONSTRAINTS_it                    2922	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+BASIC_CONSTRAINTS_it                    2922	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+BN_mod_add_quick                        2923	EXIST::FUNCTION:
+EC_POINT_new                            2924	EXIST::FUNCTION:EC
+EVP_MD_CTX_destroy                      2925	EXIST::FUNCTION:
+OCSP_RESPBYTES_free                     2926	EXIST::FUNCTION:
+EVP_aes_128_cbc                         2927	EXIST::FUNCTION:AES
+OCSP_SINGLERESP_get1_ext_d2i            2928	EXIST::FUNCTION:
+EC_POINT_free                           2929	EXIST::FUNCTION:EC
+DH_up_ref                               2930	EXIST::FUNCTION:DH
+X509_NAME_ENTRY_it                      2931	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_NAME_ENTRY_it                      2931	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+UI_get_ex_new_index                     2932	EXIST::FUNCTION:
+BN_mod_sub_quick                        2933	EXIST::FUNCTION:
+OCSP_ONEREQ_add_ext                     2934	EXIST::FUNCTION:
+OCSP_request_sign                       2935	EXIST::FUNCTION:
+EVP_DigestFinal_ex                      2936	EXIST::FUNCTION:
+ENGINE_set_digests                      2937	EXIST::FUNCTION:ENGINE
+OCSP_id_issuer_cmp                      2938	EXIST::FUNCTION:
+OBJ_NAME_do_all                         2939	EXIST::FUNCTION:
+EC_POINTs_mul                           2940	EXIST::FUNCTION:EC
+ENGINE_register_complete                2941	EXIST::FUNCTION:ENGINE
+X509V3_EXT_nconf_nid                    2942	EXIST::FUNCTION:
+ASN1_SEQUENCE_it                        2943	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_SEQUENCE_it                        2943	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+UI_set_default_method                   2944	EXIST::FUNCTION:
+RAND_query_egd_bytes                    2945	EXIST::FUNCTION:
+UI_method_get_writer                    2946	EXIST::FUNCTION:
+UI_OpenSSL                              2947	EXIST::FUNCTION:
+PEM_def_callback                        2948	EXIST::FUNCTION:
+ENGINE_cleanup                          2949	EXIST::FUNCTION:ENGINE
+DIST_POINT_it                           2950	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+DIST_POINT_it                           2950	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+OCSP_SINGLERESP_it                      2951	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+OCSP_SINGLERESP_it                      2951	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+d2i_KRB5_TKTBODY                        2952	EXIST::FUNCTION:
+EC_POINT_cmp                            2953	EXIST::FUNCTION:EC
+OCSP_REVOKEDINFO_new                    2954	EXIST::FUNCTION:
+i2d_OCSP_CERTSTATUS                     2955	EXIST::FUNCTION:
+OCSP_basic_add1_nonce                   2956	EXIST::FUNCTION:
+ASN1_item_ex_d2i                        2957	EXIST::FUNCTION:
+BN_mod_lshift1_quick                    2958	EXIST::FUNCTION:
+UI_set_method                           2959	EXIST::FUNCTION:
+OCSP_id_get0_info                       2960	EXIST::FUNCTION:
+BN_mod_sqrt                             2961	EXIST::FUNCTION:
+EC_GROUP_copy                           2962	EXIST::FUNCTION:EC
+KRB5_ENCDATA_free                       2963	EXIST::FUNCTION:
+_ossl_old_des_cfb_encrypt               2964	EXIST::FUNCTION:DES
+OCSP_SINGLERESP_get_ext_by_OBJ          2965	EXIST::FUNCTION:
+OCSP_cert_to_id                         2966	EXIST::FUNCTION:
+OCSP_RESPID_new                         2967	EXIST::FUNCTION:
+OCSP_RESPDATA_it                        2968	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+OCSP_RESPDATA_it                        2968	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+d2i_OCSP_RESPDATA                       2969	EXIST::FUNCTION:
+ENGINE_register_all_complete            2970	EXIST::FUNCTION:ENGINE
+OCSP_check_validity                     2971	EXIST::FUNCTION:
+PKCS12_BAGS_it                          2972	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS12_BAGS_it                          2972	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+OCSP_url_svcloc_new                     2973	EXIST::FUNCTION:
+ASN1_template_free                      2974	EXIST::FUNCTION:
+OCSP_SINGLERESP_add_ext                 2975	EXIST::FUNCTION:
+KRB5_AUTHENTBODY_it                     2976	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+KRB5_AUTHENTBODY_it                     2976	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+X509_supported_extension                2977	EXIST::FUNCTION:
+i2d_KRB5_AUTHDATA                       2978	EXIST::FUNCTION:
+UI_method_get_opener                    2979	EXIST::FUNCTION:
+ENGINE_set_ex_data                      2980	EXIST::FUNCTION:ENGINE
+OCSP_REQUEST_print                      2981	EXIST::FUNCTION:
+CBIGNUM_it                              2982	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+CBIGNUM_it                              2982	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+KRB5_TICKET_new                         2983	EXIST::FUNCTION:
+KRB5_APREQ_new                          2984	EXIST::FUNCTION:
+EC_GROUP_get_curve_GFp                  2985	EXIST::FUNCTION:EC
+KRB5_ENCKEY_new                         2986	EXIST::FUNCTION:
+ASN1_template_d2i                       2987	EXIST::FUNCTION:
+_ossl_old_des_quad_cksum                2988	EXIST::FUNCTION:DES
+OCSP_single_get0_status                 2989	EXIST::FUNCTION:
+BN_swap                                 2990	EXIST::FUNCTION:
+POLICYINFO_it                           2991	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+POLICYINFO_it                           2991	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ENGINE_set_destroy_function             2992	EXIST::FUNCTION:ENGINE
+asn1_enc_free                           2993	EXIST::FUNCTION:
+OCSP_RESPID_it                          2994	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+OCSP_RESPID_it                          2994	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+EC_GROUP_new                            2995	EXIST::FUNCTION:EC
+EVP_aes_256_cbc                         2996	EXIST::FUNCTION:AES
+i2d_KRB5_PRINCNAME                      2997	EXIST::FUNCTION:
+_ossl_old_des_encrypt2                  2998	EXIST::FUNCTION:DES
+_ossl_old_des_encrypt3                  2999	EXIST::FUNCTION:DES
+PKCS8_PRIV_KEY_INFO_it                  3000	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS8_PRIV_KEY_INFO_it                  3000	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+OCSP_REQINFO_it                         3001	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+OCSP_REQINFO_it                         3001	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+PBEPARAM_it                             3002	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PBEPARAM_it                             3002	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+KRB5_AUTHENTBODY_new                    3003	EXIST::FUNCTION:
+X509_CRL_add0_revoked                   3004	EXIST::FUNCTION:
+EDIPARTYNAME_it                         3005	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+EDIPARTYNAME_it                         3005	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+NETSCAPE_SPKI_it                        3006	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+NETSCAPE_SPKI_it                        3006	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+UI_get0_test_string                     3007	EXIST::FUNCTION:
+ENGINE_get_cipher_engine                3008	EXIST::FUNCTION:ENGINE
+ENGINE_register_all_ciphers             3009	EXIST::FUNCTION:ENGINE
+EC_POINT_copy                           3010	EXIST::FUNCTION:EC
+BN_kronecker                            3011	EXIST::FUNCTION:
+_ossl_old_des_ede3_ofb64_encrypt        3012	EXIST:!VMS:FUNCTION:DES
+_ossl_odes_ede3_ofb64_encrypt           3012	EXIST:VMS:FUNCTION:DES
+UI_method_get_reader                    3013	EXIST::FUNCTION:
+OCSP_BASICRESP_get_ext_count            3014	EXIST::FUNCTION:
+ASN1_ENUMERATED_it                      3015	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_ENUMERATED_it                      3015	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+UI_set_result                           3016	EXIST::FUNCTION:
+i2d_KRB5_TICKET                         3017	EXIST::FUNCTION:
+X509_print_ex_fp                        3018	EXIST::FUNCTION:FP_API
+EVP_CIPHER_CTX_set_padding              3019	EXIST::FUNCTION:
+d2i_OCSP_RESPONSE                       3020	EXIST::FUNCTION:
+ASN1_UTCTIME_it                         3021	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_UTCTIME_it                         3021	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+_ossl_old_des_enc_write                 3022	EXIST::FUNCTION:DES
+OCSP_RESPONSE_new                       3023	EXIST::FUNCTION:
+AES_set_encrypt_key                     3024	EXIST::FUNCTION:AES
+OCSP_resp_count                         3025	EXIST::FUNCTION:
+KRB5_CHECKSUM_new                       3026	EXIST::FUNCTION:
+ENGINE_load_cswift                      3027	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
+OCSP_onereq_get0_id                     3028	EXIST::FUNCTION:
+ENGINE_set_default_ciphers              3029	EXIST::FUNCTION:ENGINE
+NOTICEREF_it                            3030	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+NOTICEREF_it                            3030	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+X509V3_EXT_CRL_add_nconf                3031	EXIST::FUNCTION:
+OCSP_REVOKEDINFO_it                     3032	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+OCSP_REVOKEDINFO_it                     3032	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+AES_encrypt                             3033	EXIST::FUNCTION:AES
+OCSP_REQUEST_new                        3034	EXIST::FUNCTION:
+ASN1_ANY_it                             3035	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_ANY_it                             3035	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+CRYPTO_ex_data_new_class                3036	EXIST::FUNCTION:
+_ossl_old_des_ncbc_encrypt              3037	EXIST::FUNCTION:DES
+i2d_KRB5_TKTBODY                        3038	EXIST::FUNCTION:
+EC_POINT_clear_free                     3039	EXIST::FUNCTION:EC
+AES_decrypt                             3040	EXIST::FUNCTION:AES
+asn1_enc_init                           3041	EXIST::FUNCTION:
+UI_get_result_maxsize                   3042	EXIST::FUNCTION:
+OCSP_CERTID_new                         3043	EXIST::FUNCTION:
+ENGINE_unregister_RAND                  3044	EXIST::FUNCTION:ENGINE
+UI_method_get_closer                    3045	EXIST::FUNCTION:
+d2i_KRB5_ENCDATA                        3046	EXIST::FUNCTION:
+OCSP_request_onereq_count               3047	EXIST::FUNCTION:
+OCSP_basic_verify                       3048	EXIST::FUNCTION:
+KRB5_AUTHENTBODY_free                   3049	EXIST::FUNCTION:
+ASN1_item_d2i                           3050	EXIST::FUNCTION:
+ASN1_primitive_free                     3051	EXIST::FUNCTION:
+i2d_EXTENDED_KEY_USAGE                  3052	EXIST::FUNCTION:
+i2d_OCSP_SIGNATURE                      3053	EXIST::FUNCTION:
+asn1_enc_save                           3054	EXIST::FUNCTION:
+ENGINE_load_nuron                       3055	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
+_ossl_old_des_pcbc_encrypt              3056	EXIST::FUNCTION:DES
+PKCS12_MAC_DATA_it                      3057	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS12_MAC_DATA_it                      3057	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+OCSP_accept_responses_new               3058	EXIST::FUNCTION:
+asn1_do_lock                            3059	EXIST::FUNCTION:
+PKCS7_ATTR_VERIFY_it                    3060	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS7_ATTR_VERIFY_it                    3060	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+KRB5_APREQBODY_it                       3061	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+KRB5_APREQBODY_it                       3061	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+i2d_OCSP_SINGLERESP                     3062	EXIST::FUNCTION:
+ASN1_item_ex_new                        3063	EXIST::FUNCTION:
+UI_add_verify_string                    3064	EXIST::FUNCTION:
+_ossl_old_des_set_key                   3065	EXIST::FUNCTION:DES
+KRB5_PRINCNAME_it                       3066	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+KRB5_PRINCNAME_it                       3066	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+EVP_DecryptInit_ex                      3067	EXIST::FUNCTION:
+i2d_OCSP_CERTID                         3068	EXIST::FUNCTION:
+ASN1_item_d2i_bio                       3069	EXIST::FUNCTION:BIO
+EC_POINT_dbl                            3070	EXIST::FUNCTION:EC
+asn1_get_choice_selector                3071	EXIST::FUNCTION:
+i2d_KRB5_CHECKSUM                       3072	EXIST::FUNCTION:
+ENGINE_set_table_flags                  3073	EXIST::FUNCTION:ENGINE
+AES_options                             3074	EXIST::FUNCTION:AES
+ENGINE_load_chil                        3075	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
+OCSP_id_cmp                             3076	EXIST::FUNCTION:
+OCSP_BASICRESP_new                      3077	EXIST::FUNCTION:
+OCSP_REQUEST_get_ext_by_NID             3078	EXIST::FUNCTION:
+KRB5_APREQ_it                           3079	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+KRB5_APREQ_it                           3079	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ENGINE_get_destroy_function             3080	EXIST::FUNCTION:ENGINE
+CONF_set_nconf                          3081	EXIST::FUNCTION:
+ASN1_PRINTABLE_free                     3082	EXIST::FUNCTION:
+OCSP_BASICRESP_get_ext_by_NID           3083	EXIST::FUNCTION:
+DIST_POINT_NAME_it                      3084	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+DIST_POINT_NAME_it                      3084	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+X509V3_extensions_print                 3085	EXIST::FUNCTION:
+_ossl_old_des_cfb64_encrypt             3086	EXIST::FUNCTION:DES
+X509_REVOKED_add1_ext_i2d               3087	EXIST::FUNCTION:
+_ossl_old_des_ofb_encrypt               3088	EXIST::FUNCTION:DES
+KRB5_TKTBODY_new                        3089	EXIST::FUNCTION:
+ASN1_OCTET_STRING_it                    3090	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_OCTET_STRING_it                    3090	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ERR_load_UI_strings                     3091	EXIST::FUNCTION:
+i2d_KRB5_ENCKEY                         3092	EXIST::FUNCTION:
+ASN1_template_new                       3093	EXIST::FUNCTION:
+OCSP_SIGNATURE_free                     3094	EXIST::FUNCTION:
+ASN1_item_i2d_fp                        3095	EXIST::FUNCTION:FP_API
+KRB5_PRINCNAME_free                     3096	EXIST::FUNCTION:
+PKCS7_RECIP_INFO_it                     3097	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS7_RECIP_INFO_it                     3097	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+EXTENDED_KEY_USAGE_it                   3098	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+EXTENDED_KEY_USAGE_it                   3098	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+EC_GFp_simple_method                    3099	EXIST::FUNCTION:EC
+EC_GROUP_precompute_mult                3100	EXIST::FUNCTION:EC
+OCSP_request_onereq_get0                3101	EXIST::FUNCTION:
+UI_method_set_writer                    3102	EXIST::FUNCTION:
+KRB5_AUTHENT_new                        3103	EXIST::FUNCTION:
+X509_CRL_INFO_it                        3104	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_CRL_INFO_it                        3104	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+DSO_set_name_converter                  3105	EXIST::FUNCTION:
+AES_set_decrypt_key                     3106	EXIST::FUNCTION:AES
+PKCS7_DIGEST_it                         3107	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS7_DIGEST_it                         3107	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+PKCS12_x5092certbag                     3108	EXIST::FUNCTION:
+EVP_DigestInit_ex                       3109	EXIST::FUNCTION:
+i2a_ACCESS_DESCRIPTION                  3110	EXIST::FUNCTION:
+OCSP_RESPONSE_it                        3111	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+OCSP_RESPONSE_it                        3111	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+PKCS7_ENC_CONTENT_it                    3112	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS7_ENC_CONTENT_it                    3112	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+OCSP_request_add0_id                    3113	EXIST::FUNCTION:
+EC_POINT_make_affine                    3114	EXIST::FUNCTION:EC
+DSO_get_filename                        3115	EXIST::FUNCTION:
+OCSP_CERTSTATUS_it                      3116	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+OCSP_CERTSTATUS_it                      3116	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+OCSP_request_add1_cert                  3117	EXIST::FUNCTION:
+UI_get0_output_string                   3118	EXIST::FUNCTION:
+UI_dup_verify_string                    3119	EXIST::FUNCTION:
+BN_mod_lshift                           3120	EXIST::FUNCTION:
+KRB5_AUTHDATA_it                        3121	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+KRB5_AUTHDATA_it                        3121	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+asn1_set_choice_selector                3122	EXIST::FUNCTION:
+OCSP_basic_add1_status                  3123	EXIST::FUNCTION:
+OCSP_RESPID_free                        3124	EXIST::FUNCTION:
+asn1_get_field_ptr                      3125	EXIST::FUNCTION:
+UI_add_input_string                     3126	EXIST::FUNCTION:
+OCSP_CRLID_it                           3127	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+OCSP_CRLID_it                           3127	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+i2d_KRB5_AUTHENTBODY                    3128	EXIST::FUNCTION:
+OCSP_REQUEST_get_ext_count              3129	EXIST::FUNCTION:
+ENGINE_load_atalla                      3130	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
+X509_NAME_it                            3131	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_NAME_it                            3131	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+USERNOTICE_it                           3132	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+USERNOTICE_it                           3132	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+OCSP_REQINFO_new                        3133	EXIST::FUNCTION:
+OCSP_BASICRESP_get_ext                  3134	EXIST::FUNCTION:
+CRYPTO_get_ex_data_implementation       3135	EXIST:!VMS:FUNCTION:
+CRYPTO_get_ex_data_impl                 3135	EXIST:VMS:FUNCTION:
+ASN1_item_pack                          3136	EXIST::FUNCTION:
+i2d_KRB5_ENCDATA                        3137	EXIST::FUNCTION:
+X509_PURPOSE_set                        3138	EXIST::FUNCTION:
+X509_REQ_INFO_it                        3139	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_REQ_INFO_it                        3139	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+UI_method_set_opener                    3140	EXIST::FUNCTION:
+ASN1_item_ex_free                       3141	EXIST::FUNCTION:
+ASN1_BOOLEAN_it                         3142	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_BOOLEAN_it                         3142	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ENGINE_get_table_flags                  3143	EXIST::FUNCTION:ENGINE
+UI_create_method                        3144	EXIST::FUNCTION:
+OCSP_ONEREQ_add1_ext_i2d                3145	EXIST::FUNCTION:
+_shadow_DES_check_key                   3146	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:DES
+_shadow_DES_check_key                   3146	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:DES
+d2i_OCSP_REQINFO                        3147	EXIST::FUNCTION:
+UI_add_info_string                      3148	EXIST::FUNCTION:
+UI_get_result_minsize                   3149	EXIST::FUNCTION:
+ASN1_NULL_it                            3150	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_NULL_it                            3150	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+BN_mod_lshift1                          3151	EXIST::FUNCTION:
+d2i_OCSP_ONEREQ                         3152	EXIST::FUNCTION:
+OCSP_ONEREQ_new                         3153	EXIST::FUNCTION:
+KRB5_TICKET_it                          3154	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+KRB5_TICKET_it                          3154	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+EVP_aes_192_cbc                         3155	EXIST::FUNCTION:AES
+KRB5_TICKET_free                        3156	EXIST::FUNCTION:
+UI_new                                  3157	EXIST::FUNCTION:
+OCSP_response_create                    3158	EXIST::FUNCTION:
+_ossl_old_des_xcbc_encrypt              3159	EXIST::FUNCTION:DES
+PKCS7_it                                3160	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PKCS7_it                                3160	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+OCSP_REQUEST_get_ext_by_critical        3161	EXIST:!VMS:FUNCTION:
+OCSP_REQUEST_get_ext_by_crit            3161	EXIST:VMS:FUNCTION:
+ENGINE_set_flags                        3162	EXIST::FUNCTION:ENGINE
+_ossl_old_des_ecb_encrypt               3163	EXIST::FUNCTION:DES
+OCSP_response_get1_basic                3164	EXIST::FUNCTION:
+EVP_Digest                              3165	EXIST::FUNCTION:
+OCSP_ONEREQ_delete_ext                  3166	EXIST::FUNCTION:
+ASN1_TBOOLEAN_it                        3167	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_TBOOLEAN_it                        3167	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ASN1_item_new                           3168	EXIST::FUNCTION:
+ASN1_TIME_to_generalizedtime            3169	EXIST::FUNCTION:
+BIGNUM_it                               3170	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+BIGNUM_it                               3170	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+AES_cbc_encrypt                         3171	EXIST::FUNCTION:AES
+ENGINE_get_load_privkey_function        3172	EXIST:!VMS:FUNCTION:ENGINE
+ENGINE_get_load_privkey_fn              3172	EXIST:VMS:FUNCTION:ENGINE
+OCSP_RESPONSE_free                      3173	EXIST::FUNCTION:
+UI_method_set_reader                    3174	EXIST::FUNCTION:
+i2d_ASN1_T61STRING                      3175	EXIST::FUNCTION:
+EC_POINT_set_to_infinity                3176	EXIST::FUNCTION:EC
+ERR_load_OCSP_strings                   3177	EXIST::FUNCTION:
+EC_POINT_point2oct                      3178	EXIST::FUNCTION:EC
+KRB5_APREQ_free                         3179	EXIST::FUNCTION:
+ASN1_OBJECT_it                          3180	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_OBJECT_it                          3180	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+OCSP_crlID_new                          3181	EXIST:!OS2,!VMS:FUNCTION:
+OCSP_crlID2_new                         3181	EXIST:OS2,VMS:FUNCTION:
+CONF_modules_load_file                  3182	EXIST::FUNCTION:
+CONF_imodule_set_usr_data               3183	EXIST::FUNCTION:
+ENGINE_set_default_string               3184	EXIST::FUNCTION:ENGINE
+CONF_module_get_usr_data                3185	EXIST::FUNCTION:
+ASN1_add_oid_module                     3186	EXIST::FUNCTION:
+CONF_modules_finish                     3187	EXIST::FUNCTION:
+OPENSSL_config                          3188	EXIST::FUNCTION:
+CONF_modules_unload                     3189	EXIST::FUNCTION:
+CONF_imodule_get_value                  3190	EXIST::FUNCTION:
+CONF_module_set_usr_data                3191	EXIST::FUNCTION:
+CONF_parse_list                         3192	EXIST::FUNCTION:
+CONF_module_add                         3193	EXIST::FUNCTION:
+CONF_get1_default_config_file           3194	EXIST::FUNCTION:
+CONF_imodule_get_flags                  3195	EXIST::FUNCTION:
+CONF_imodule_get_module                 3196	EXIST::FUNCTION:
+CONF_modules_load                       3197	EXIST::FUNCTION:
+CONF_imodule_get_name                   3198	EXIST::FUNCTION:
+ERR_peek_top_error                      3199	NOEXIST::FUNCTION:
+CONF_imodule_get_usr_data               3200	EXIST::FUNCTION:
+CONF_imodule_set_flags                  3201	EXIST::FUNCTION:
+ENGINE_add_conf_module                  3202	EXIST::FUNCTION:ENGINE
+ERR_peek_last_error_line                3203	EXIST::FUNCTION:
+ERR_peek_last_error_line_data           3204	EXIST::FUNCTION:
+ERR_peek_last_error                     3205	EXIST::FUNCTION:
+DES_read_2passwords                     3206	EXIST::FUNCTION:DES
+DES_read_password                       3207	EXIST::FUNCTION:DES
+UI_UTIL_read_pw                         3208	EXIST::FUNCTION:
+UI_UTIL_read_pw_string                  3209	EXIST::FUNCTION:
+ENGINE_load_aep                         3210	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
+ENGINE_load_sureware                    3211	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
+OPENSSL_add_all_algorithms_noconf       3212	EXIST:!VMS:FUNCTION:
+OPENSSL_add_all_algo_noconf             3212	EXIST:VMS:FUNCTION:
+OPENSSL_add_all_algorithms_conf         3213	EXIST:!VMS:FUNCTION:
+OPENSSL_add_all_algo_conf               3213	EXIST:VMS:FUNCTION:
+OPENSSL_load_builtin_modules            3214	EXIST::FUNCTION:
+AES_ofb128_encrypt                      3215	EXIST::FUNCTION:AES
+AES_ctr128_encrypt                      3216	EXIST::FUNCTION:AES
+AES_cfb128_encrypt                      3217	EXIST::FUNCTION:AES
+ENGINE_load_4758cca                     3218	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
+_ossl_096_des_random_seed               3219	EXIST::FUNCTION:DES
+EVP_aes_256_ofb                         3220	EXIST::FUNCTION:AES
+EVP_aes_192_ofb                         3221	EXIST::FUNCTION:AES
+EVP_aes_128_cfb128                      3222	EXIST::FUNCTION:AES
+EVP_aes_256_cfb128                      3223	EXIST::FUNCTION:AES
+EVP_aes_128_ofb                         3224	EXIST::FUNCTION:AES
+EVP_aes_192_cfb128                      3225	EXIST::FUNCTION:AES
+CONF_modules_free                       3226	EXIST::FUNCTION:
+NCONF_default                           3227	EXIST::FUNCTION:
+OPENSSL_no_config                       3228	EXIST::FUNCTION:
+NCONF_WIN32                             3229	EXIST::FUNCTION:
+ASN1_UNIVERSALSTRING_new                3230	EXIST::FUNCTION:
+EVP_des_ede_ecb                         3231	EXIST::FUNCTION:DES
+i2d_ASN1_UNIVERSALSTRING                3232	EXIST::FUNCTION:
+ASN1_UNIVERSALSTRING_free               3233	EXIST::FUNCTION:
+ASN1_UNIVERSALSTRING_it                 3234	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_UNIVERSALSTRING_it                 3234	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+d2i_ASN1_UNIVERSALSTRING                3235	EXIST::FUNCTION:
+EVP_des_ede3_ecb                        3236	EXIST::FUNCTION:DES
+X509_REQ_print_ex                       3237	EXIST::FUNCTION:BIO
+ENGINE_up_ref                           3238	EXIST::FUNCTION:ENGINE
+BUF_MEM_grow_clean                      3239	EXIST::FUNCTION:
+CRYPTO_realloc_clean                    3240	EXIST::FUNCTION:
+BUF_strlcat                             3241	EXIST::FUNCTION:
+BIO_indent                              3242	EXIST::FUNCTION:
+BUF_strlcpy                             3243	EXIST::FUNCTION:
+OpenSSLDie                              3244	EXIST::FUNCTION:
+OPENSSL_cleanse                         3245	EXIST::FUNCTION:
+ENGINE_setup_bsd_cryptodev              3246	EXIST:__FreeBSD__:FUNCTION:ENGINE
+ERR_release_err_state_table             3247	EXIST::FUNCTION:LHASH
+EVP_aes_128_cfb8                        3248	EXIST::FUNCTION:AES
+FIPS_corrupt_rsa                        3249	NOEXIST::FUNCTION:
+FIPS_selftest_des                       3250	NOEXIST::FUNCTION:
+EVP_aes_128_cfb1                        3251	EXIST::FUNCTION:AES
+EVP_aes_192_cfb8                        3252	EXIST::FUNCTION:AES
+FIPS_mode_set                           3253	NOEXIST::FUNCTION:
+FIPS_selftest_dsa                       3254	NOEXIST::FUNCTION:
+EVP_aes_256_cfb8                        3255	EXIST::FUNCTION:AES
+FIPS_allow_md5                          3256	NOEXIST::FUNCTION:
+DES_ede3_cfb_encrypt                    3257	EXIST::FUNCTION:DES
+EVP_des_ede3_cfb8                       3258	EXIST::FUNCTION:DES
+FIPS_rand_seeded                        3259	NOEXIST::FUNCTION:
+AES_cfbr_encrypt_block                  3260	NOEXIST::FUNCTION:
+AES_cfb8_encrypt                        3261	EXIST::FUNCTION:AES
+FIPS_rand_seed                          3262	NOEXIST::FUNCTION:
+FIPS_corrupt_des                        3263	NOEXIST::FUNCTION:
+EVP_aes_192_cfb1                        3264	EXIST::FUNCTION:AES
+FIPS_selftest_aes                       3265	NOEXIST::FUNCTION:
+FIPS_set_prng_key                       3266	NOEXIST::FUNCTION:
+EVP_des_cfb8                            3267	EXIST::FUNCTION:DES
+FIPS_corrupt_dsa                        3268	NOEXIST::FUNCTION:
+FIPS_test_mode                          3269	NOEXIST::FUNCTION:
+FIPS_rand_method                        3270	NOEXIST::FUNCTION:
+EVP_aes_256_cfb1                        3271	EXIST::FUNCTION:AES
+ERR_load_FIPS_strings                   3272	NOEXIST::FUNCTION:
+FIPS_corrupt_aes                        3273	NOEXIST::FUNCTION:
+FIPS_selftest_sha1                      3274	NOEXIST::FUNCTION:
+FIPS_selftest_rsa                       3275	NOEXIST::FUNCTION:
+FIPS_corrupt_sha1                       3276	NOEXIST::FUNCTION:
+EVP_des_cfb1                            3277	EXIST::FUNCTION:DES
+FIPS_dsa_check                          3278	NOEXIST::FUNCTION:
+AES_cfb1_encrypt                        3279	EXIST::FUNCTION:AES
+EVP_des_ede3_cfb1                       3280	EXIST::FUNCTION:DES
+FIPS_rand_check                         3281	NOEXIST::FUNCTION:
+FIPS_md5_allowed                        3282	NOEXIST::FUNCTION:
+FIPS_mode                               3283	NOEXIST::FUNCTION:
+FIPS_selftest_failed                    3284	NOEXIST::FUNCTION:
+sk_is_sorted                            3285	EXIST::FUNCTION:
+X509_check_ca                           3286	EXIST::FUNCTION:
+private_idea_set_encrypt_key            3287	NOEXIST::FUNCTION:
+HMAC_CTX_set_flags                      3288	EXIST::FUNCTION:HMAC
+private_SHA_Init                        3289	NOEXIST::FUNCTION:
+private_CAST_set_key                    3290	NOEXIST::FUNCTION:
+private_RIPEMD160_Init                  3291	NOEXIST::FUNCTION:
+private_RC5_32_set_key                  3292	NOEXIST::FUNCTION:
+private_MD5_Init                        3293	NOEXIST::FUNCTION:
+private_RC4_set_key                     3294	NOEXIST::FUNCTION:
+private_MDC2_Init                       3295	NOEXIST::FUNCTION:
+private_RC2_set_key                     3296	NOEXIST::FUNCTION:
+private_MD4_Init                        3297	NOEXIST::FUNCTION:
+private_BF_set_key                      3298	NOEXIST::FUNCTION:
+private_MD2_Init                        3299	NOEXIST::FUNCTION:
+d2i_PROXY_CERT_INFO_EXTENSION           3300	EXIST::FUNCTION:
+PROXY_POLICY_it                         3301	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PROXY_POLICY_it                         3301	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+i2d_PROXY_POLICY                        3302	EXIST::FUNCTION:
+i2d_PROXY_CERT_INFO_EXTENSION           3303	EXIST::FUNCTION:
+d2i_PROXY_POLICY                        3304	EXIST::FUNCTION:
+PROXY_CERT_INFO_EXTENSION_new           3305	EXIST::FUNCTION:
+PROXY_CERT_INFO_EXTENSION_free          3306	EXIST::FUNCTION:
+PROXY_CERT_INFO_EXTENSION_it            3307	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PROXY_CERT_INFO_EXTENSION_it            3307	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+PROXY_POLICY_free                       3308	EXIST::FUNCTION:
+PROXY_POLICY_new                        3309	EXIST::FUNCTION:
+BN_MONT_CTX_set_locked                  3310	EXIST::FUNCTION:
+FIPS_selftest_rng                       3311	NOEXIST::FUNCTION:
+EVP_sha384                              3312	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
+EVP_sha512                              3313	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
+EVP_sha224                              3314	EXIST::FUNCTION:SHA,SHA256
+EVP_sha256                              3315	EXIST::FUNCTION:SHA,SHA256
+FIPS_selftest_hmac                      3316	NOEXIST::FUNCTION:
+FIPS_corrupt_rng                        3317	NOEXIST::FUNCTION:
+BN_mod_exp_mont_consttime               3318	EXIST::FUNCTION:
+RSA_X931_hash_id                        3319	EXIST::FUNCTION:RSA
+RSA_padding_check_X931                  3320	EXIST::FUNCTION:RSA
+RSA_verify_PKCS1_PSS                    3321	EXIST::FUNCTION:RSA
+RSA_padding_add_X931                    3322	EXIST::FUNCTION:RSA
+RSA_padding_add_PKCS1_PSS               3323	EXIST::FUNCTION:RSA
+PKCS1_MGF1                              3324	EXIST::FUNCTION:RSA
+BN_X931_generate_Xpq                    3325	NOEXIST::FUNCTION:
+RSA_X931_generate_key                   3326	NOEXIST::FUNCTION:
+BN_X931_derive_prime                    3327	NOEXIST::FUNCTION:
+BN_X931_generate_prime                  3328	NOEXIST::FUNCTION:
+RSA_X931_derive                         3329	NOEXIST::FUNCTION:
+BIO_new_dgram                           3330	EXIST::FUNCTION:
+BN_get0_nist_prime_384                  3331	EXIST::FUNCTION:
+ERR_set_mark                            3332	EXIST::FUNCTION:
+X509_STORE_CTX_set0_crls                3333	EXIST::FUNCTION:
+ENGINE_set_STORE                        3334	EXIST::FUNCTION:ENGINE
+ENGINE_register_ECDSA                   3335	EXIST::FUNCTION:ENGINE
+STORE_meth_set_list_start_fn            3336	NOEXIST::FUNCTION:
+STORE_method_set_list_start_function    3336	NOEXIST::FUNCTION:
+BN_BLINDING_invert_ex                   3337	EXIST::FUNCTION:
+NAME_CONSTRAINTS_free                   3338	EXIST::FUNCTION:
+STORE_ATTR_INFO_set_number              3339	NOEXIST::FUNCTION:
+BN_BLINDING_get_thread_id               3340	EXIST::FUNCTION:DEPRECATED
+X509_STORE_CTX_set0_param               3341	EXIST::FUNCTION:
+POLICY_MAPPING_it                       3342	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+POLICY_MAPPING_it                       3342	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+STORE_parse_attrs_start                 3343	NOEXIST::FUNCTION:
+POLICY_CONSTRAINTS_free                 3344	EXIST::FUNCTION:
+EVP_PKEY_add1_attr_by_NID               3345	EXIST::FUNCTION:
+BN_nist_mod_192                         3346	EXIST::FUNCTION:
+EC_GROUP_get_trinomial_basis            3347	EXIST::FUNCTION:EC
+STORE_set_method                        3348	NOEXIST::FUNCTION:
+GENERAL_SUBTREE_free                    3349	EXIST::FUNCTION:
+NAME_CONSTRAINTS_it                     3350	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+NAME_CONSTRAINTS_it                     3350	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+ECDH_get_default_method                 3351	EXIST::FUNCTION:ECDH
+PKCS12_add_safe                         3352	EXIST::FUNCTION:
+EC_KEY_new_by_curve_name                3353	EXIST::FUNCTION:EC
+STORE_meth_get_update_store_fn          3354	NOEXIST::FUNCTION:
+STORE_method_get_update_store_function  3354	NOEXIST::FUNCTION:
+ENGINE_register_ECDH                    3355	EXIST::FUNCTION:ENGINE
+SHA512_Update                           3356	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
+i2d_ECPrivateKey                        3357	EXIST::FUNCTION:EC
+BN_get0_nist_prime_192                  3358	EXIST::FUNCTION:
+STORE_modify_certificate                3359	NOEXIST::FUNCTION:
+EC_POINT_set_affine_coordinates_GF2m    3360	EXIST:!VMS:FUNCTION:EC
+EC_POINT_set_affine_coords_GF2m         3360	EXIST:VMS:FUNCTION:EC
+BN_GF2m_mod_exp_arr                     3361	EXIST::FUNCTION:
+STORE_ATTR_INFO_modify_number           3362	NOEXIST::FUNCTION:
+X509_keyid_get0                         3363	EXIST::FUNCTION:
+ENGINE_load_gmp                         3364	EXIST::FUNCTION:ENGINE,GMP,STATIC_ENGINE
+pitem_new                               3365	EXIST::FUNCTION:
+BN_GF2m_mod_mul_arr                     3366	EXIST::FUNCTION:
+STORE_list_public_key_endp              3367	NOEXIST::FUNCTION:
+o2i_ECPublicKey                         3368	EXIST::FUNCTION:EC
+EC_KEY_copy                             3369	EXIST::FUNCTION:EC
+BIO_dump_fp                             3370	EXIST::FUNCTION:FP_API
+X509_policy_node_get0_parent            3371	EXIST::FUNCTION:
+EC_GROUP_check_discriminant             3372	EXIST::FUNCTION:EC
+i2o_ECPublicKey                         3373	EXIST::FUNCTION:EC
+EC_KEY_precompute_mult                  3374	EXIST::FUNCTION:EC
+a2i_IPADDRESS                           3375	EXIST::FUNCTION:
+STORE_meth_set_initialise_fn            3376	NOEXIST::FUNCTION:
+STORE_method_set_initialise_function    3376	NOEXIST::FUNCTION:
+X509_STORE_CTX_set_depth                3377	EXIST::FUNCTION:
+X509_VERIFY_PARAM_inherit               3378	EXIST::FUNCTION:
+EC_POINT_point2bn                       3379	EXIST::FUNCTION:EC
+STORE_ATTR_INFO_set_dn                  3380	NOEXIST::FUNCTION:
+X509_policy_tree_get0_policies          3381	EXIST::FUNCTION:
+EC_GROUP_new_curve_GF2m                 3382	EXIST::FUNCTION:EC
+STORE_destroy_method                    3383	NOEXIST::FUNCTION:
+ENGINE_unregister_STORE                 3384	EXIST::FUNCTION:ENGINE
+EVP_PKEY_get1_EC_KEY                    3385	EXIST::FUNCTION:EC
+STORE_ATTR_INFO_get0_number             3386	NOEXIST::FUNCTION:
+ENGINE_get_default_ECDH                 3387	EXIST::FUNCTION:ENGINE
+EC_KEY_get_conv_form                    3388	EXIST::FUNCTION:EC
+ASN1_OCTET_STRING_NDEF_it               3389	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_OCTET_STRING_NDEF_it               3389	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+STORE_delete_public_key                 3390	NOEXIST::FUNCTION:
+STORE_get_public_key                    3391	NOEXIST::FUNCTION:
+STORE_modify_arbitrary                  3392	NOEXIST::FUNCTION:
+ENGINE_get_static_state                 3393	EXIST::FUNCTION:ENGINE
+pqueue_iterator                         3394	EXIST::FUNCTION:
+ECDSA_SIG_new                           3395	EXIST::FUNCTION:ECDSA
+OPENSSL_DIR_end                         3396	EXIST::FUNCTION:
+BN_GF2m_mod_sqr                         3397	EXIST::FUNCTION:
+EC_POINT_bn2point                       3398	EXIST::FUNCTION:EC
+X509_VERIFY_PARAM_set_depth             3399	EXIST::FUNCTION:
+EC_KEY_set_asn1_flag                    3400	EXIST::FUNCTION:EC
+STORE_get_method                        3401	NOEXIST::FUNCTION:
+EC_KEY_get_key_method_data              3402	EXIST::FUNCTION:EC
+ECDSA_sign_ex                           3403	EXIST::FUNCTION:ECDSA
+STORE_parse_attrs_end                   3404	NOEXIST::FUNCTION:
+EC_GROUP_get_point_conversion_form      3405	EXIST:!VMS:FUNCTION:EC
+EC_GROUP_get_point_conv_form            3405	EXIST:VMS:FUNCTION:EC
+STORE_method_set_store_function         3406	NOEXIST::FUNCTION:
+STORE_ATTR_INFO_in                      3407	NOEXIST::FUNCTION:
+PEM_read_bio_ECPKParameters             3408	EXIST::FUNCTION:EC
+EC_GROUP_get_pentanomial_basis          3409	EXIST::FUNCTION:EC
+EVP_PKEY_add1_attr_by_txt               3410	EXIST::FUNCTION:
+BN_BLINDING_set_flags                   3411	EXIST::FUNCTION:
+X509_VERIFY_PARAM_set1_policies         3412	EXIST::FUNCTION:
+X509_VERIFY_PARAM_set1_name             3413	EXIST::FUNCTION:
+X509_VERIFY_PARAM_set_purpose           3414	EXIST::FUNCTION:
+STORE_get_number                        3415	NOEXIST::FUNCTION:
+ECDSA_sign_setup                        3416	EXIST::FUNCTION:ECDSA
+BN_GF2m_mod_solve_quad_arr              3417	EXIST::FUNCTION:
+EC_KEY_up_ref                           3418	EXIST::FUNCTION:EC
+POLICY_MAPPING_free                     3419	EXIST::FUNCTION:
+BN_GF2m_mod_div                         3420	EXIST::FUNCTION:
+X509_VERIFY_PARAM_set_flags             3421	EXIST::FUNCTION:
+EC_KEY_free                             3422	EXIST::FUNCTION:EC
+STORE_meth_set_list_next_fn             3423	NOEXIST::FUNCTION:
+STORE_method_set_list_next_function     3423	NOEXIST::FUNCTION:
+PEM_write_bio_ECPrivateKey              3424	EXIST::FUNCTION:EC
+d2i_EC_PUBKEY                           3425	EXIST::FUNCTION:EC
+STORE_meth_get_generate_fn              3426	NOEXIST::FUNCTION:
+STORE_method_get_generate_function      3426	NOEXIST::FUNCTION:
+STORE_meth_set_list_end_fn              3427	NOEXIST::FUNCTION:
+STORE_method_set_list_end_function      3427	NOEXIST::FUNCTION:
+pqueue_print                            3428	EXIST::FUNCTION:
+EC_GROUP_have_precompute_mult           3429	EXIST::FUNCTION:EC
+EC_KEY_print_fp                         3430	EXIST::FUNCTION:EC,FP_API
+BN_GF2m_mod_arr                         3431	EXIST::FUNCTION:
+PEM_write_bio_X509_CERT_PAIR            3432	EXIST::FUNCTION:
+EVP_PKEY_cmp                            3433	EXIST::FUNCTION:
+X509_policy_level_node_count            3434	EXIST::FUNCTION:
+STORE_new_engine                        3435	NOEXIST::FUNCTION:
+STORE_list_public_key_start             3436	NOEXIST::FUNCTION:
+X509_VERIFY_PARAM_new                   3437	EXIST::FUNCTION:
+ECDH_get_ex_data                        3438	EXIST::FUNCTION:ECDH
+EVP_PKEY_get_attr                       3439	EXIST::FUNCTION:
+ECDSA_do_sign                           3440	EXIST::FUNCTION:ECDSA
+ENGINE_unregister_ECDH                  3441	EXIST::FUNCTION:ENGINE
+ECDH_OpenSSL                            3442	EXIST::FUNCTION:ECDH
+EC_KEY_set_conv_form                    3443	EXIST::FUNCTION:EC
+EC_POINT_dup                            3444	EXIST::FUNCTION:EC
+GENERAL_SUBTREE_new                     3445	EXIST::FUNCTION:
+STORE_list_crl_endp                     3446	NOEXIST::FUNCTION:
+EC_get_builtin_curves                   3447	EXIST::FUNCTION:EC
+X509_policy_node_get0_qualifiers        3448	EXIST:!VMS:FUNCTION:
+X509_pcy_node_get0_qualifiers           3448	EXIST:VMS:FUNCTION:
+STORE_list_crl_end                      3449	NOEXIST::FUNCTION:
+EVP_PKEY_set1_EC_KEY                    3450	EXIST::FUNCTION:EC
+BN_GF2m_mod_sqrt_arr                    3451	EXIST::FUNCTION:
+i2d_ECPrivateKey_bio                    3452	EXIST::FUNCTION:BIO,EC
+ECPKParameters_print_fp                 3453	EXIST::FUNCTION:EC,FP_API
+pqueue_find                             3454	EXIST::FUNCTION:
+ECDSA_SIG_free                          3455	EXIST::FUNCTION:ECDSA
+PEM_write_bio_ECPKParameters            3456	EXIST::FUNCTION:EC
+STORE_method_set_ctrl_function          3457	NOEXIST::FUNCTION:
+STORE_list_public_key_end               3458	NOEXIST::FUNCTION:
+EC_KEY_set_private_key                  3459	EXIST::FUNCTION:EC
+pqueue_peek                             3460	EXIST::FUNCTION:
+STORE_get_arbitrary                     3461	NOEXIST::FUNCTION:
+STORE_store_crl                         3462	NOEXIST::FUNCTION:
+X509_policy_node_get0_policy            3463	EXIST::FUNCTION:
+PKCS12_add_safes                        3464	EXIST::FUNCTION:
+BN_BLINDING_convert_ex                  3465	EXIST::FUNCTION:
+X509_policy_tree_free                   3466	EXIST::FUNCTION:
+OPENSSL_ia32cap_loc                     3467	EXIST::FUNCTION:
+BN_GF2m_poly2arr                        3468	EXIST::FUNCTION:
+STORE_ctrl                              3469	NOEXIST::FUNCTION:
+STORE_ATTR_INFO_compare                 3470	NOEXIST::FUNCTION:
+BN_get0_nist_prime_224                  3471	EXIST::FUNCTION:
+i2d_ECParameters                        3472	EXIST::FUNCTION:EC
+i2d_ECPKParameters                      3473	EXIST::FUNCTION:EC
+BN_GENCB_call                           3474	EXIST::FUNCTION:
+d2i_ECPKParameters                      3475	EXIST::FUNCTION:EC
+STORE_meth_set_generate_fn              3476	NOEXIST::FUNCTION:
+STORE_method_set_generate_function      3476	NOEXIST::FUNCTION:
+ENGINE_set_ECDH                         3477	EXIST::FUNCTION:ENGINE
+NAME_CONSTRAINTS_new                    3478	EXIST::FUNCTION:
+SHA256_Init                             3479	EXIST::FUNCTION:SHA,SHA256
+EC_KEY_get0_public_key                  3480	EXIST::FUNCTION:EC
+PEM_write_bio_EC_PUBKEY                 3481	EXIST::FUNCTION:EC
+STORE_ATTR_INFO_set_cstr                3482	NOEXIST::FUNCTION:
+STORE_list_crl_next                     3483	NOEXIST::FUNCTION:
+STORE_ATTR_INFO_in_range                3484	NOEXIST::FUNCTION:
+ECParameters_print                      3485	EXIST::FUNCTION:BIO,EC
+STORE_meth_set_delete_fn                3486	NOEXIST::FUNCTION:
+STORE_method_set_delete_function        3486	NOEXIST::FUNCTION:
+STORE_list_certificate_next             3487	NOEXIST::FUNCTION:
+ASN1_generate_nconf                     3488	EXIST::FUNCTION:
+BUF_memdup                              3489	EXIST::FUNCTION:
+BN_GF2m_mod_mul                         3490	EXIST::FUNCTION:
+STORE_meth_get_list_next_fn             3491	NOEXIST::FUNCTION:
+STORE_method_get_list_next_function     3491	NOEXIST::FUNCTION:
+STORE_ATTR_INFO_get0_dn                 3492	NOEXIST::FUNCTION:
+STORE_list_private_key_next             3493	NOEXIST::FUNCTION:
+EC_GROUP_set_seed                       3494	EXIST::FUNCTION:EC
+X509_VERIFY_PARAM_set_trust             3495	EXIST::FUNCTION:
+STORE_ATTR_INFO_free                    3496	NOEXIST::FUNCTION:
+STORE_get_private_key                   3497	NOEXIST::FUNCTION:
+EVP_PKEY_get_attr_count                 3498	EXIST::FUNCTION:
+STORE_ATTR_INFO_new                     3499	NOEXIST::FUNCTION:
+EC_GROUP_get_curve_GF2m                 3500	EXIST::FUNCTION:EC
+STORE_meth_set_revoke_fn                3501	NOEXIST::FUNCTION:
+STORE_method_set_revoke_function        3501	NOEXIST::FUNCTION:
+STORE_store_number                      3502	NOEXIST::FUNCTION:
+BN_is_prime_ex                          3503	EXIST::FUNCTION:
+STORE_revoke_public_key                 3504	NOEXIST::FUNCTION:
+X509_STORE_CTX_get0_param               3505	EXIST::FUNCTION:
+STORE_delete_arbitrary                  3506	NOEXIST::FUNCTION:
+PEM_read_X509_CERT_PAIR                 3507	EXIST:!WIN16:FUNCTION:
+X509_STORE_set_depth                    3508	EXIST::FUNCTION:
+ECDSA_get_ex_data                       3509	EXIST::FUNCTION:ECDSA
+SHA224                                  3510	EXIST::FUNCTION:SHA,SHA256
+BIO_dump_indent_fp                      3511	EXIST::FUNCTION:FP_API
+EC_KEY_set_group                        3512	EXIST::FUNCTION:EC
+BUF_strndup                             3513	EXIST::FUNCTION:
+STORE_list_certificate_start            3514	NOEXIST::FUNCTION:
+BN_GF2m_mod                             3515	EXIST::FUNCTION:
+X509_REQ_check_private_key              3516	EXIST::FUNCTION:
+EC_GROUP_get_seed_len                   3517	EXIST::FUNCTION:EC
+ERR_load_STORE_strings                  3518	NOEXIST::FUNCTION:
+PEM_read_bio_EC_PUBKEY                  3519	EXIST::FUNCTION:EC
+STORE_list_private_key_end              3520	NOEXIST::FUNCTION:
+i2d_EC_PUBKEY                           3521	EXIST::FUNCTION:EC
+ECDSA_get_default_method                3522	EXIST::FUNCTION:ECDSA
+ASN1_put_eoc                            3523	EXIST::FUNCTION:
+X509_STORE_CTX_get_explicit_policy      3524	EXIST:!VMS:FUNCTION:
+X509_STORE_CTX_get_expl_policy          3524	EXIST:VMS:FUNCTION:
+X509_VERIFY_PARAM_table_cleanup         3525	EXIST::FUNCTION:
+STORE_modify_private_key                3526	NOEXIST::FUNCTION:
+X509_VERIFY_PARAM_free                  3527	EXIST::FUNCTION:
+EC_METHOD_get_field_type                3528	EXIST::FUNCTION:EC
+EC_GFp_nist_method                      3529	EXIST::FUNCTION:EC
+STORE_meth_set_modify_fn                3530	NOEXIST::FUNCTION:
+STORE_method_set_modify_function        3530	NOEXIST::FUNCTION:
+STORE_parse_attrs_next                  3531	NOEXIST::FUNCTION:
+ENGINE_load_padlock                     3532	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
+EC_GROUP_set_curve_name                 3533	EXIST::FUNCTION:EC
+X509_CERT_PAIR_it                       3534	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_CERT_PAIR_it                       3534	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+STORE_meth_get_revoke_fn                3535	NOEXIST::FUNCTION:
+STORE_method_get_revoke_function        3535	NOEXIST::FUNCTION:
+STORE_method_set_get_function           3536	NOEXIST::FUNCTION:
+STORE_modify_number                     3537	NOEXIST::FUNCTION:
+STORE_method_get_store_function         3538	NOEXIST::FUNCTION:
+STORE_store_private_key                 3539	NOEXIST::FUNCTION:
+BN_GF2m_mod_sqr_arr                     3540	EXIST::FUNCTION:
+RSA_setup_blinding                      3541	EXIST::FUNCTION:RSA
+BIO_s_datagram                          3542	EXIST::FUNCTION:DGRAM
+STORE_Memory                            3543	NOEXIST::FUNCTION:
+sk_find_ex                              3544	EXIST::FUNCTION:
+EC_GROUP_set_curve_GF2m                 3545	EXIST::FUNCTION:EC
+ENGINE_set_default_ECDSA                3546	EXIST::FUNCTION:ENGINE
+POLICY_CONSTRAINTS_new                  3547	EXIST::FUNCTION:
+BN_GF2m_mod_sqrt                        3548	EXIST::FUNCTION:
+ECDH_set_default_method                 3549	EXIST::FUNCTION:ECDH
+EC_KEY_generate_key                     3550	EXIST::FUNCTION:EC
+SHA384_Update                           3551	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
+BN_GF2m_arr2poly                        3552	EXIST::FUNCTION:
+STORE_method_get_get_function           3553	NOEXIST::FUNCTION:
+STORE_meth_set_cleanup_fn               3554	NOEXIST::FUNCTION:
+STORE_method_set_cleanup_function       3554	NOEXIST::FUNCTION:
+EC_GROUP_check                          3555	EXIST::FUNCTION:EC
+d2i_ECPrivateKey_bio                    3556	EXIST::FUNCTION:BIO,EC
+EC_KEY_insert_key_method_data           3557	EXIST::FUNCTION:EC
+STORE_meth_get_lock_store_fn            3558	NOEXIST::FUNCTION:
+STORE_method_get_lock_store_function    3558	NOEXIST::FUNCTION:
+X509_VERIFY_PARAM_get_depth             3559	EXIST::FUNCTION:
+SHA224_Final                            3560	EXIST::FUNCTION:SHA,SHA256
+STORE_meth_set_update_store_fn          3561	NOEXIST::FUNCTION:
+STORE_method_set_update_store_function  3561	NOEXIST::FUNCTION:
+SHA224_Update                           3562	EXIST::FUNCTION:SHA,SHA256
+d2i_ECPrivateKey                        3563	EXIST::FUNCTION:EC
+ASN1_item_ndef_i2d                      3564	EXIST::FUNCTION:
+STORE_delete_private_key                3565	NOEXIST::FUNCTION:
+ERR_pop_to_mark                         3566	EXIST::FUNCTION:
+ENGINE_register_all_STORE               3567	EXIST::FUNCTION:ENGINE
+X509_policy_level_get0_node             3568	EXIST::FUNCTION:
+i2d_PKCS7_NDEF                          3569	EXIST::FUNCTION:
+EC_GROUP_get_degree                     3570	EXIST::FUNCTION:EC
+ASN1_generate_v3                        3571	EXIST::FUNCTION:
+STORE_ATTR_INFO_modify_cstr             3572	NOEXIST::FUNCTION:
+X509_policy_tree_level_count            3573	EXIST::FUNCTION:
+BN_GF2m_add                             3574	EXIST::FUNCTION:
+EC_KEY_get0_group                       3575	EXIST::FUNCTION:EC
+STORE_generate_crl                      3576	NOEXIST::FUNCTION:
+STORE_store_public_key                  3577	NOEXIST::FUNCTION:
+X509_CERT_PAIR_free                     3578	EXIST::FUNCTION:
+STORE_revoke_private_key                3579	NOEXIST::FUNCTION:
+BN_nist_mod_224                         3580	EXIST::FUNCTION:
+SHA512_Final                            3581	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
+STORE_ATTR_INFO_modify_dn               3582	NOEXIST::FUNCTION:
+STORE_meth_get_initialise_fn            3583	NOEXIST::FUNCTION:
+STORE_method_get_initialise_function    3583	NOEXIST::FUNCTION:
+STORE_delete_number                     3584	NOEXIST::FUNCTION:
+i2d_EC_PUBKEY_bio                       3585	EXIST::FUNCTION:BIO,EC
+BIO_dgram_non_fatal_error               3586	EXIST::FUNCTION:
+EC_GROUP_get_asn1_flag                  3587	EXIST::FUNCTION:EC
+STORE_ATTR_INFO_in_ex                   3588	NOEXIST::FUNCTION:
+STORE_list_crl_start                    3589	NOEXIST::FUNCTION:
+ECDH_get_ex_new_index                   3590	EXIST::FUNCTION:ECDH
+STORE_meth_get_modify_fn                3591	NOEXIST::FUNCTION:
+STORE_method_get_modify_function        3591	NOEXIST::FUNCTION:
+v2i_ASN1_BIT_STRING                     3592	EXIST::FUNCTION:
+STORE_store_certificate                 3593	NOEXIST::FUNCTION:
+OBJ_bsearch_ex                          3594	NOEXIST::FUNCTION:
+X509_STORE_CTX_set_default              3595	EXIST::FUNCTION:
+STORE_ATTR_INFO_set_sha1str             3596	NOEXIST::FUNCTION:
+BN_GF2m_mod_inv                         3597	EXIST::FUNCTION:
+BN_GF2m_mod_exp                         3598	EXIST::FUNCTION:
+STORE_modify_public_key                 3599	NOEXIST::FUNCTION:
+STORE_meth_get_list_start_fn            3600	NOEXIST::FUNCTION:
+STORE_method_get_list_start_function    3600	NOEXIST::FUNCTION:
+EC_GROUP_get0_seed                      3601	EXIST::FUNCTION:EC
+STORE_store_arbitrary                   3602	NOEXIST::FUNCTION:
+STORE_meth_set_unlock_store_fn          3603	NOEXIST::FUNCTION:
+STORE_method_set_unlock_store_function  3603	NOEXIST::FUNCTION:
+BN_GF2m_mod_div_arr                     3604	EXIST::FUNCTION:
+ENGINE_set_ECDSA                        3605	EXIST::FUNCTION:ENGINE
+STORE_create_method                     3606	NOEXIST::FUNCTION:
+ECPKParameters_print                    3607	EXIST::FUNCTION:BIO,EC
+EC_KEY_get0_private_key                 3608	EXIST::FUNCTION:EC
+PEM_write_EC_PUBKEY                     3609	EXIST:!WIN16:FUNCTION:EC
+X509_VERIFY_PARAM_set1                  3610	EXIST::FUNCTION:
+ECDH_set_method                         3611	EXIST::FUNCTION:ECDH
+v2i_GENERAL_NAME_ex                     3612	EXIST::FUNCTION:
+ECDH_set_ex_data                        3613	EXIST::FUNCTION:ECDH
+STORE_generate_key                      3614	NOEXIST::FUNCTION:
+BN_nist_mod_521                         3615	EXIST::FUNCTION:
+X509_policy_tree_get0_level             3616	EXIST::FUNCTION:
+EC_GROUP_set_point_conversion_form      3617	EXIST:!VMS:FUNCTION:EC
+EC_GROUP_set_point_conv_form            3617	EXIST:VMS:FUNCTION:EC
+PEM_read_EC_PUBKEY                      3618	EXIST:!WIN16:FUNCTION:EC
+i2d_ECDSA_SIG                           3619	EXIST::FUNCTION:ECDSA
+ECDSA_OpenSSL                           3620	EXIST::FUNCTION:ECDSA
+STORE_delete_crl                        3621	NOEXIST::FUNCTION:
+EC_KEY_get_enc_flags                    3622	EXIST::FUNCTION:EC
+ASN1_const_check_infinite_end           3623	EXIST::FUNCTION:
+EVP_PKEY_delete_attr                    3624	EXIST::FUNCTION:
+ECDSA_set_default_method                3625	EXIST::FUNCTION:ECDSA
+EC_POINT_set_compressed_coordinates_GF2m 3626	EXIST:!VMS:FUNCTION:EC
+EC_POINT_set_compr_coords_GF2m          3626	EXIST:VMS:FUNCTION:EC
+EC_GROUP_cmp                            3627	EXIST::FUNCTION:EC
+STORE_revoke_certificate                3628	NOEXIST::FUNCTION:
+BN_get0_nist_prime_256                  3629	EXIST::FUNCTION:
+STORE_meth_get_delete_fn                3630	NOEXIST::FUNCTION:
+STORE_method_get_delete_function        3630	NOEXIST::FUNCTION:
+SHA224_Init                             3631	EXIST::FUNCTION:SHA,SHA256
+PEM_read_ECPrivateKey                   3632	EXIST:!WIN16:FUNCTION:EC
+SHA512_Init                             3633	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
+STORE_parse_attrs_endp                  3634	NOEXIST::FUNCTION:
+BN_set_negative                         3635	EXIST::FUNCTION:
+ERR_load_ECDSA_strings                  3636	EXIST::FUNCTION:ECDSA
+EC_GROUP_get_basis_type                 3637	EXIST::FUNCTION:EC
+STORE_list_public_key_next              3638	NOEXIST::FUNCTION:
+i2v_ASN1_BIT_STRING                     3639	EXIST::FUNCTION:
+STORE_OBJECT_free                       3640	NOEXIST::FUNCTION:
+BN_nist_mod_384                         3641	EXIST::FUNCTION:
+i2d_X509_CERT_PAIR                      3642	EXIST::FUNCTION:
+PEM_write_ECPKParameters                3643	EXIST:!WIN16:FUNCTION:EC
+ECDH_compute_key                        3644	EXIST::FUNCTION:ECDH
+STORE_ATTR_INFO_get0_sha1str            3645	NOEXIST::FUNCTION:
+ENGINE_register_all_ECDH                3646	EXIST::FUNCTION:ENGINE
+pqueue_pop                              3647	EXIST::FUNCTION:
+STORE_ATTR_INFO_get0_cstr               3648	NOEXIST::FUNCTION:
+POLICY_CONSTRAINTS_it                   3649	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+POLICY_CONSTRAINTS_it                   3649	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+STORE_get_ex_new_index                  3650	NOEXIST::FUNCTION:
+EVP_PKEY_get_attr_by_OBJ                3651	EXIST::FUNCTION:
+X509_VERIFY_PARAM_add0_policy           3652	EXIST::FUNCTION:
+BN_GF2m_mod_solve_quad                  3653	EXIST::FUNCTION:
+SHA256                                  3654	EXIST::FUNCTION:SHA,SHA256
+i2d_ECPrivateKey_fp                     3655	EXIST::FUNCTION:EC,FP_API
+X509_policy_tree_get0_user_policies     3656	EXIST:!VMS:FUNCTION:
+X509_pcy_tree_get0_usr_policies         3656	EXIST:VMS:FUNCTION:
+OPENSSL_DIR_read                        3657	EXIST::FUNCTION:
+ENGINE_register_all_ECDSA               3658	EXIST::FUNCTION:ENGINE
+X509_VERIFY_PARAM_lookup                3659	EXIST::FUNCTION:
+EC_POINT_get_affine_coordinates_GF2m    3660	EXIST:!VMS:FUNCTION:EC
+EC_POINT_get_affine_coords_GF2m         3660	EXIST:VMS:FUNCTION:EC
+EC_GROUP_dup                            3661	EXIST::FUNCTION:EC
+ENGINE_get_default_ECDSA                3662	EXIST::FUNCTION:ENGINE
+EC_KEY_new                              3663	EXIST::FUNCTION:EC
+SHA256_Transform                        3664	EXIST::FUNCTION:SHA,SHA256
+EC_KEY_set_enc_flags                    3665	EXIST::FUNCTION:EC
+ECDSA_verify                            3666	EXIST::FUNCTION:ECDSA
+EC_POINT_point2hex                      3667	EXIST::FUNCTION:EC
+ENGINE_get_STORE                        3668	EXIST::FUNCTION:ENGINE
+SHA512                                  3669	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
+STORE_get_certificate                   3670	NOEXIST::FUNCTION:
+ECDSA_do_sign_ex                        3671	EXIST::FUNCTION:ECDSA
+ECDSA_do_verify                         3672	EXIST::FUNCTION:ECDSA
+d2i_ECPrivateKey_fp                     3673	EXIST::FUNCTION:EC,FP_API
+STORE_delete_certificate                3674	NOEXIST::FUNCTION:
+SHA512_Transform                        3675	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
+X509_STORE_set1_param                   3676	EXIST::FUNCTION:
+STORE_method_get_ctrl_function          3677	NOEXIST::FUNCTION:
+STORE_free                              3678	NOEXIST::FUNCTION:
+PEM_write_ECPrivateKey                  3679	EXIST:!WIN16:FUNCTION:EC
+STORE_meth_get_unlock_store_fn          3680	NOEXIST::FUNCTION:
+STORE_method_get_unlock_store_function  3680	NOEXIST::FUNCTION:
+STORE_get_ex_data                       3681	NOEXIST::FUNCTION:
+EC_KEY_set_public_key                   3682	EXIST::FUNCTION:EC
+PEM_read_ECPKParameters                 3683	EXIST:!WIN16:FUNCTION:EC
+X509_CERT_PAIR_new                      3684	EXIST::FUNCTION:
+ENGINE_register_STORE                   3685	EXIST::FUNCTION:ENGINE
+RSA_generate_key_ex                     3686	EXIST::FUNCTION:RSA
+DSA_generate_parameters_ex              3687	EXIST::FUNCTION:DSA
+ECParameters_print_fp                   3688	EXIST::FUNCTION:EC,FP_API
+X509V3_NAME_from_section                3689	EXIST::FUNCTION:
+EVP_PKEY_add1_attr                      3690	EXIST::FUNCTION:
+STORE_modify_crl                        3691	NOEXIST::FUNCTION:
+STORE_list_private_key_start            3692	NOEXIST::FUNCTION:
+POLICY_MAPPINGS_it                      3693	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+POLICY_MAPPINGS_it                      3693	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+GENERAL_SUBTREE_it                      3694	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+GENERAL_SUBTREE_it                      3694	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+EC_GROUP_get_curve_name                 3695	EXIST::FUNCTION:EC
+PEM_write_X509_CERT_PAIR                3696	EXIST:!WIN16:FUNCTION:
+BIO_dump_indent_cb                      3697	EXIST::FUNCTION:
+d2i_X509_CERT_PAIR                      3698	EXIST::FUNCTION:
+STORE_list_private_key_endp             3699	NOEXIST::FUNCTION:
+asn1_const_Finish                       3700	EXIST::FUNCTION:
+i2d_EC_PUBKEY_fp                        3701	EXIST::FUNCTION:EC,FP_API
+BN_nist_mod_256                         3702	EXIST::FUNCTION:
+X509_VERIFY_PARAM_add0_table            3703	EXIST::FUNCTION:
+pqueue_free                             3704	EXIST::FUNCTION:
+BN_BLINDING_create_param                3705	EXIST::FUNCTION:
+ECDSA_size                              3706	EXIST::FUNCTION:ECDSA
+d2i_EC_PUBKEY_bio                       3707	EXIST::FUNCTION:BIO,EC
+BN_get0_nist_prime_521                  3708	EXIST::FUNCTION:
+STORE_ATTR_INFO_modify_sha1str          3709	NOEXIST::FUNCTION:
+BN_generate_prime_ex                    3710	EXIST::FUNCTION:
+EC_GROUP_new_by_curve_name              3711	EXIST::FUNCTION:EC
+SHA256_Final                            3712	EXIST::FUNCTION:SHA,SHA256
+DH_generate_parameters_ex               3713	EXIST::FUNCTION:DH
+PEM_read_bio_ECPrivateKey               3714	EXIST::FUNCTION:EC
+STORE_meth_get_cleanup_fn               3715	NOEXIST::FUNCTION:
+STORE_method_get_cleanup_function       3715	NOEXIST::FUNCTION:
+ENGINE_get_ECDH                         3716	EXIST::FUNCTION:ENGINE
+d2i_ECDSA_SIG                           3717	EXIST::FUNCTION:ECDSA
+BN_is_prime_fasttest_ex                 3718	EXIST::FUNCTION:
+ECDSA_sign                              3719	EXIST::FUNCTION:ECDSA
+X509_policy_check                       3720	EXIST::FUNCTION:
+EVP_PKEY_get_attr_by_NID                3721	EXIST::FUNCTION:
+STORE_set_ex_data                       3722	NOEXIST::FUNCTION:
+ENGINE_get_ECDSA                        3723	EXIST::FUNCTION:ENGINE
+EVP_ecdsa                               3724	EXIST::FUNCTION:SHA
+BN_BLINDING_get_flags                   3725	EXIST::FUNCTION:
+PKCS12_add_cert                         3726	EXIST::FUNCTION:
+STORE_OBJECT_new                        3727	NOEXIST::FUNCTION:
+ERR_load_ECDH_strings                   3728	EXIST::FUNCTION:ECDH
+EC_KEY_dup                              3729	EXIST::FUNCTION:EC
+EVP_CIPHER_CTX_rand_key                 3730	EXIST::FUNCTION:
+ECDSA_set_method                        3731	EXIST::FUNCTION:ECDSA
+a2i_IPADDRESS_NC                        3732	EXIST::FUNCTION:
+d2i_ECParameters                        3733	EXIST::FUNCTION:EC
+STORE_list_certificate_end              3734	NOEXIST::FUNCTION:
+STORE_get_crl                           3735	NOEXIST::FUNCTION:
+X509_POLICY_NODE_print                  3736	EXIST::FUNCTION:
+SHA384_Init                             3737	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
+EC_GF2m_simple_method                   3738	EXIST::FUNCTION:EC
+ECDSA_set_ex_data                       3739	EXIST::FUNCTION:ECDSA
+SHA384_Final                            3740	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
+PKCS7_set_digest                        3741	EXIST::FUNCTION:
+EC_KEY_print                            3742	EXIST::FUNCTION:BIO,EC
+STORE_meth_set_lock_store_fn            3743	NOEXIST::FUNCTION:
+STORE_method_set_lock_store_function    3743	NOEXIST::FUNCTION:
+ECDSA_get_ex_new_index                  3744	EXIST::FUNCTION:ECDSA
+SHA384                                  3745	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
+POLICY_MAPPING_new                      3746	EXIST::FUNCTION:
+STORE_list_certificate_endp             3747	NOEXIST::FUNCTION:
+X509_STORE_CTX_get0_policy_tree         3748	EXIST::FUNCTION:
+EC_GROUP_set_asn1_flag                  3749	EXIST::FUNCTION:EC
+EC_KEY_check_key                        3750	EXIST::FUNCTION:EC
+d2i_EC_PUBKEY_fp                        3751	EXIST::FUNCTION:EC,FP_API
+PKCS7_set0_type_other                   3752	EXIST::FUNCTION:
+PEM_read_bio_X509_CERT_PAIR             3753	EXIST::FUNCTION:
+pqueue_next                             3754	EXIST::FUNCTION:
+STORE_meth_get_list_end_fn              3755	NOEXIST::FUNCTION:
+STORE_method_get_list_end_function      3755	NOEXIST::FUNCTION:
+EVP_PKEY_add1_attr_by_OBJ               3756	EXIST::FUNCTION:
+X509_VERIFY_PARAM_set_time              3757	EXIST::FUNCTION:
+pqueue_new                              3758	EXIST::FUNCTION:
+ENGINE_set_default_ECDH                 3759	EXIST::FUNCTION:ENGINE
+STORE_new_method                        3760	NOEXIST::FUNCTION:
+PKCS12_add_key                          3761	EXIST::FUNCTION:
+DSO_merge                               3762	EXIST::FUNCTION:
+EC_POINT_hex2point                      3763	EXIST::FUNCTION:EC
+BIO_dump_cb                             3764	EXIST::FUNCTION:
+SHA256_Update                           3765	EXIST::FUNCTION:SHA,SHA256
+pqueue_insert                           3766	EXIST::FUNCTION:
+pitem_free                              3767	EXIST::FUNCTION:
+BN_GF2m_mod_inv_arr                     3768	EXIST::FUNCTION:
+ENGINE_unregister_ECDSA                 3769	EXIST::FUNCTION:ENGINE
+BN_BLINDING_set_thread_id               3770	EXIST::FUNCTION:DEPRECATED
+get_rfc3526_prime_8192                  3771	EXIST::FUNCTION:
+X509_VERIFY_PARAM_clear_flags           3772	EXIST::FUNCTION:
+get_rfc2409_prime_1024                  3773	EXIST::FUNCTION:
+DH_check_pub_key                        3774	EXIST::FUNCTION:DH
+get_rfc3526_prime_2048                  3775	EXIST::FUNCTION:
+get_rfc3526_prime_6144                  3776	EXIST::FUNCTION:
+get_rfc3526_prime_1536                  3777	EXIST::FUNCTION:
+get_rfc3526_prime_3072                  3778	EXIST::FUNCTION:
+get_rfc3526_prime_4096                  3779	EXIST::FUNCTION:
+get_rfc2409_prime_768                   3780	EXIST::FUNCTION:
+X509_VERIFY_PARAM_get_flags             3781	EXIST::FUNCTION:
+EVP_CIPHER_CTX_new                      3782	EXIST::FUNCTION:
+EVP_CIPHER_CTX_free                     3783	EXIST::FUNCTION:
+Camellia_cbc_encrypt                    3784	EXIST::FUNCTION:CAMELLIA
+Camellia_cfb128_encrypt                 3785	EXIST::FUNCTION:CAMELLIA
+Camellia_cfb1_encrypt                   3786	EXIST::FUNCTION:CAMELLIA
+Camellia_cfb8_encrypt                   3787	EXIST::FUNCTION:CAMELLIA
+Camellia_ctr128_encrypt                 3788	EXIST::FUNCTION:CAMELLIA
+Camellia_cfbr_encrypt_block             3789	NOEXIST::FUNCTION:
+Camellia_decrypt                        3790	EXIST::FUNCTION:CAMELLIA
+Camellia_ecb_encrypt                    3791	EXIST::FUNCTION:CAMELLIA
+Camellia_encrypt                        3792	EXIST::FUNCTION:CAMELLIA
+Camellia_ofb128_encrypt                 3793	EXIST::FUNCTION:CAMELLIA
+Camellia_set_key                        3794	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_128_cbc                    3795	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_128_cfb128                 3796	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_128_cfb1                   3797	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_128_cfb8                   3798	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_128_ecb                    3799	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_128_ofb                    3800	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_192_cbc                    3801	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_192_cfb128                 3802	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_192_cfb1                   3803	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_192_cfb8                   3804	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_192_ecb                    3805	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_192_ofb                    3806	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_256_cbc                    3807	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_256_cfb128                 3808	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_256_cfb1                   3809	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_256_cfb8                   3810	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_256_ecb                    3811	EXIST::FUNCTION:CAMELLIA
+EVP_camellia_256_ofb                    3812	EXIST::FUNCTION:CAMELLIA
+a2i_ipadd                               3813	EXIST::FUNCTION:
+ASIdentifiers_free                      3814	EXIST::FUNCTION:RFC3779
+i2d_ASIdOrRange                         3815	EXIST::FUNCTION:RFC3779
+EVP_CIPHER_block_size                   3816	EXIST::FUNCTION:
+v3_asid_is_canonical                    3817	EXIST::FUNCTION:RFC3779
+IPAddressChoice_free                    3818	EXIST::FUNCTION:RFC3779
+EVP_CIPHER_CTX_set_app_data             3819	EXIST::FUNCTION:
+BIO_set_callback_arg                    3820	EXIST::FUNCTION:
+v3_addr_add_prefix                      3821	EXIST::FUNCTION:RFC3779
+IPAddressOrRange_it                     3822	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RFC3779
+IPAddressOrRange_it                     3822	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RFC3779
+BIO_set_flags                           3823	EXIST::FUNCTION:
+ASIdentifiers_it                        3824	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RFC3779
+ASIdentifiers_it                        3824	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RFC3779
+v3_addr_get_range                       3825	EXIST::FUNCTION:RFC3779
+BIO_method_type                         3826	EXIST::FUNCTION:
+v3_addr_inherits                        3827	EXIST::FUNCTION:RFC3779
+IPAddressChoice_it                      3828	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RFC3779
+IPAddressChoice_it                      3828	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RFC3779
+AES_ige_encrypt                         3829	EXIST::FUNCTION:AES
+v3_addr_add_range                       3830	EXIST::FUNCTION:RFC3779
+EVP_CIPHER_CTX_nid                      3831	EXIST::FUNCTION:
+d2i_ASRange                             3832	EXIST::FUNCTION:RFC3779
+v3_addr_add_inherit                     3833	EXIST::FUNCTION:RFC3779
+v3_asid_add_id_or_range                 3834	EXIST::FUNCTION:RFC3779
+v3_addr_validate_resource_set           3835	EXIST::FUNCTION:RFC3779
+EVP_CIPHER_iv_length                    3836	EXIST::FUNCTION:
+EVP_MD_type                             3837	EXIST::FUNCTION:
+v3_asid_canonize                        3838	EXIST::FUNCTION:RFC3779
+IPAddressRange_free                     3839	EXIST::FUNCTION:RFC3779
+v3_asid_add_inherit                     3840	EXIST::FUNCTION:RFC3779
+EVP_CIPHER_CTX_key_length               3841	EXIST::FUNCTION:
+IPAddressRange_new                      3842	EXIST::FUNCTION:RFC3779
+ASIdOrRange_new                         3843	EXIST::FUNCTION:RFC3779
+EVP_MD_size                             3844	EXIST::FUNCTION:
+EVP_MD_CTX_test_flags                   3845	EXIST::FUNCTION:
+BIO_clear_flags                         3846	EXIST::FUNCTION:
+i2d_ASRange                             3847	EXIST::FUNCTION:RFC3779
+IPAddressRange_it                       3848	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RFC3779
+IPAddressRange_it                       3848	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RFC3779
+IPAddressChoice_new                     3849	EXIST::FUNCTION:RFC3779
+ASIdentifierChoice_new                  3850	EXIST::FUNCTION:RFC3779
+ASRange_free                            3851	EXIST::FUNCTION:RFC3779
+EVP_MD_pkey_type                        3852	EXIST::FUNCTION:
+EVP_MD_CTX_clear_flags                  3853	EXIST::FUNCTION:
+IPAddressFamily_free                    3854	EXIST::FUNCTION:RFC3779
+i2d_IPAddressFamily                     3855	EXIST::FUNCTION:RFC3779
+IPAddressOrRange_new                    3856	EXIST::FUNCTION:RFC3779
+EVP_CIPHER_flags                        3857	EXIST::FUNCTION:
+v3_asid_validate_resource_set           3858	EXIST::FUNCTION:RFC3779
+d2i_IPAddressRange                      3859	EXIST::FUNCTION:RFC3779
+AES_bi_ige_encrypt                      3860	EXIST::FUNCTION:AES
+BIO_get_callback                        3861	EXIST::FUNCTION:
+IPAddressOrRange_free                   3862	EXIST::FUNCTION:RFC3779
+v3_addr_subset                          3863	EXIST::FUNCTION:RFC3779
+d2i_IPAddressFamily                     3864	EXIST::FUNCTION:RFC3779
+v3_asid_subset                          3865	EXIST::FUNCTION:RFC3779
+BIO_test_flags                          3866	EXIST::FUNCTION:
+i2d_ASIdentifierChoice                  3867	EXIST::FUNCTION:RFC3779
+ASRange_it                              3868	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RFC3779
+ASRange_it                              3868	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RFC3779
+d2i_ASIdentifiers                       3869	EXIST::FUNCTION:RFC3779
+ASRange_new                             3870	EXIST::FUNCTION:RFC3779
+d2i_IPAddressChoice                     3871	EXIST::FUNCTION:RFC3779
+v3_addr_get_afi                         3872	EXIST::FUNCTION:RFC3779
+EVP_CIPHER_key_length                   3873	EXIST::FUNCTION:
+EVP_Cipher                              3874	EXIST::FUNCTION:
+i2d_IPAddressOrRange                    3875	EXIST::FUNCTION:RFC3779
+ASIdOrRange_it                          3876	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RFC3779
+ASIdOrRange_it                          3876	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RFC3779
+EVP_CIPHER_nid                          3877	EXIST::FUNCTION:
+i2d_IPAddressChoice                     3878	EXIST::FUNCTION:RFC3779
+EVP_CIPHER_CTX_block_size               3879	EXIST::FUNCTION:
+ASIdentifiers_new                       3880	EXIST::FUNCTION:RFC3779
+v3_addr_validate_path                   3881	EXIST::FUNCTION:RFC3779
+IPAddressFamily_new                     3882	EXIST::FUNCTION:RFC3779
+EVP_MD_CTX_set_flags                    3883	EXIST::FUNCTION:
+v3_addr_is_canonical                    3884	EXIST::FUNCTION:RFC3779
+i2d_IPAddressRange                      3885	EXIST::FUNCTION:RFC3779
+IPAddressFamily_it                      3886	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RFC3779
+IPAddressFamily_it                      3886	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RFC3779
+v3_asid_inherits                        3887	EXIST::FUNCTION:RFC3779
+EVP_CIPHER_CTX_cipher                   3888	EXIST::FUNCTION:
+EVP_CIPHER_CTX_get_app_data             3889	EXIST::FUNCTION:
+EVP_MD_block_size                       3890	EXIST::FUNCTION:
+EVP_CIPHER_CTX_flags                    3891	EXIST::FUNCTION:
+v3_asid_validate_path                   3892	EXIST::FUNCTION:RFC3779
+d2i_IPAddressOrRange                    3893	EXIST::FUNCTION:RFC3779
+v3_addr_canonize                        3894	EXIST::FUNCTION:RFC3779
+ASIdentifierChoice_it                   3895	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RFC3779
+ASIdentifierChoice_it                   3895	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RFC3779
+EVP_MD_CTX_md                           3896	EXIST::FUNCTION:
+d2i_ASIdentifierChoice                  3897	EXIST::FUNCTION:RFC3779
+BIO_method_name                         3898	EXIST::FUNCTION:
+EVP_CIPHER_CTX_iv_length                3899	EXIST::FUNCTION:
+ASIdOrRange_free                        3900	EXIST::FUNCTION:RFC3779
+ASIdentifierChoice_free                 3901	EXIST::FUNCTION:RFC3779
+BIO_get_callback_arg                    3902	EXIST::FUNCTION:
+BIO_set_callback                        3903	EXIST::FUNCTION:
+d2i_ASIdOrRange                         3904	EXIST::FUNCTION:RFC3779
+i2d_ASIdentifiers                       3905	EXIST::FUNCTION:RFC3779
+SEED_decrypt                            3908	EXIST::FUNCTION:SEED
+SEED_encrypt                            3909	EXIST::FUNCTION:SEED
+SEED_cbc_encrypt                        3910	EXIST::FUNCTION:SEED
+EVP_seed_ofb                            3911	EXIST::FUNCTION:SEED
+SEED_cfb128_encrypt                     3912	EXIST::FUNCTION:SEED
+SEED_ofb128_encrypt                     3913	EXIST::FUNCTION:SEED
+EVP_seed_cbc                            3914	EXIST::FUNCTION:SEED
+SEED_ecb_encrypt                        3915	EXIST::FUNCTION:SEED
+EVP_seed_ecb                            3916	EXIST::FUNCTION:SEED
+SEED_set_key                            3917	EXIST::FUNCTION:SEED
+EVP_seed_cfb128                         3918	EXIST::FUNCTION:SEED
+X509_EXTENSIONS_it                      3919	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_EXTENSIONS_it                      3919	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+X509_get1_ocsp                          3920	EXIST::FUNCTION:
+OCSP_REQ_CTX_free                       3921	EXIST::FUNCTION:
+i2d_X509_EXTENSIONS                     3922	EXIST::FUNCTION:
+OCSP_sendreq_nbio                       3923	EXIST::FUNCTION:
+OCSP_sendreq_new                        3924	EXIST::FUNCTION:
+d2i_X509_EXTENSIONS                     3925	EXIST::FUNCTION:
+X509_ALGORS_it                          3926	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+X509_ALGORS_it                          3926	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+X509_ALGOR_get0                         3927	EXIST::FUNCTION:
+X509_ALGOR_set0                         3928	EXIST::FUNCTION:
+AES_unwrap_key                          3929	EXIST::FUNCTION:AES
+AES_wrap_key                            3930	EXIST::FUNCTION:AES
+X509at_get0_data_by_OBJ                 3931	EXIST::FUNCTION:
+ASN1_TYPE_set1                          3932	EXIST::FUNCTION:
+ASN1_STRING_set0                        3933	EXIST::FUNCTION:
+i2d_X509_ALGORS                         3934	EXIST::FUNCTION:
+BIO_f_zlib                              3935	EXIST:ZLIB:FUNCTION:
+COMP_zlib_cleanup                       3936	EXIST::FUNCTION:
+d2i_X509_ALGORS                         3937	EXIST::FUNCTION:
+CMS_ReceiptRequest_free                 3938	EXIST::FUNCTION:CMS
+PEM_write_CMS                           3939	EXIST:!WIN16:FUNCTION:CMS
+CMS_add0_CertificateChoices             3940	EXIST::FUNCTION:CMS
+CMS_unsigned_add1_attr_by_OBJ           3941	EXIST::FUNCTION:CMS
+ERR_load_CMS_strings                    3942	EXIST::FUNCTION:CMS
+CMS_sign_receipt                        3943	EXIST::FUNCTION:CMS
+i2d_CMS_ContentInfo                     3944	EXIST::FUNCTION:CMS
+CMS_signed_delete_attr                  3945	EXIST::FUNCTION:CMS
+d2i_CMS_bio                             3946	EXIST::FUNCTION:CMS
+CMS_unsigned_get_attr_by_NID            3947	EXIST::FUNCTION:CMS
+CMS_verify                              3948	EXIST::FUNCTION:CMS
+SMIME_read_CMS                          3949	EXIST::FUNCTION:CMS
+CMS_decrypt_set1_key                    3950	EXIST::FUNCTION:CMS
+CMS_SignerInfo_get0_algs                3951	EXIST::FUNCTION:CMS
+CMS_add1_cert                           3952	EXIST::FUNCTION:CMS
+CMS_set_detached                        3953	EXIST::FUNCTION:CMS
+CMS_encrypt                             3954	EXIST::FUNCTION:CMS
+CMS_EnvelopedData_create                3955	EXIST::FUNCTION:CMS
+CMS_uncompress                          3956	EXIST::FUNCTION:CMS
+CMS_add0_crl                            3957	EXIST::FUNCTION:CMS
+CMS_SignerInfo_verify_content           3958	EXIST::FUNCTION:CMS
+CMS_unsigned_get0_data_by_OBJ           3959	EXIST::FUNCTION:CMS
+PEM_write_bio_CMS                       3960	EXIST::FUNCTION:CMS
+CMS_unsigned_get_attr                   3961	EXIST::FUNCTION:CMS
+CMS_RecipientInfo_ktri_cert_cmp         3962	EXIST::FUNCTION:CMS
+CMS_RecipientInfo_ktri_get0_algs        3963	EXIST:!VMS:FUNCTION:CMS
+CMS_RecipInfo_ktri_get0_algs            3963	EXIST:VMS:FUNCTION:CMS
+CMS_ContentInfo_free                    3964	EXIST::FUNCTION:CMS
+CMS_final                               3965	EXIST::FUNCTION:CMS
+CMS_add_simple_smimecap                 3966	EXIST::FUNCTION:CMS
+CMS_SignerInfo_verify                   3967	EXIST::FUNCTION:CMS
+CMS_data                                3968	EXIST::FUNCTION:CMS
+CMS_ContentInfo_it                      3969	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:CMS
+CMS_ContentInfo_it                      3969	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:CMS
+d2i_CMS_ReceiptRequest                  3970	EXIST::FUNCTION:CMS
+CMS_compress                            3971	EXIST::FUNCTION:CMS
+CMS_digest_create                       3972	EXIST::FUNCTION:CMS
+CMS_SignerInfo_cert_cmp                 3973	EXIST::FUNCTION:CMS
+CMS_SignerInfo_sign                     3974	EXIST::FUNCTION:CMS
+CMS_data_create                         3975	EXIST::FUNCTION:CMS
+i2d_CMS_bio                             3976	EXIST::FUNCTION:CMS
+CMS_EncryptedData_set1_key              3977	EXIST::FUNCTION:CMS
+CMS_decrypt                             3978	EXIST::FUNCTION:CMS
+int_smime_write_ASN1                    3979	NOEXIST::FUNCTION:
+CMS_unsigned_delete_attr                3980	EXIST::FUNCTION:CMS
+CMS_unsigned_get_attr_count             3981	EXIST::FUNCTION:CMS
+CMS_add_smimecap                        3982	EXIST::FUNCTION:CMS
+PEM_read_CMS                            3983	EXIST:!WIN16:FUNCTION:CMS
+CMS_signed_get_attr_by_OBJ              3984	EXIST::FUNCTION:CMS
+d2i_CMS_ContentInfo                     3985	EXIST::FUNCTION:CMS
+CMS_add_standard_smimecap               3986	EXIST::FUNCTION:CMS
+CMS_ContentInfo_new                     3987	EXIST::FUNCTION:CMS
+CMS_RecipientInfo_type                  3988	EXIST::FUNCTION:CMS
+CMS_get0_type                           3989	EXIST::FUNCTION:CMS
+CMS_is_detached                         3990	EXIST::FUNCTION:CMS
+CMS_sign                                3991	EXIST::FUNCTION:CMS
+CMS_signed_add1_attr                    3992	EXIST::FUNCTION:CMS
+CMS_unsigned_get_attr_by_OBJ            3993	EXIST::FUNCTION:CMS
+SMIME_write_CMS                         3994	EXIST::FUNCTION:CMS
+CMS_EncryptedData_decrypt               3995	EXIST::FUNCTION:CMS
+CMS_get0_RecipientInfos                 3996	EXIST::FUNCTION:CMS
+CMS_add0_RevocationInfoChoice           3997	EXIST::FUNCTION:CMS
+CMS_decrypt_set1_pkey                   3998	EXIST::FUNCTION:CMS
+CMS_SignerInfo_set1_signer_cert         3999	EXIST::FUNCTION:CMS
+CMS_get0_signers                        4000	EXIST::FUNCTION:CMS
+CMS_ReceiptRequest_get0_values          4001	EXIST::FUNCTION:CMS
+CMS_signed_get0_data_by_OBJ             4002	EXIST::FUNCTION:CMS
+CMS_get0_SignerInfos                    4003	EXIST::FUNCTION:CMS
+CMS_add0_cert                           4004	EXIST::FUNCTION:CMS
+CMS_EncryptedData_encrypt               4005	EXIST::FUNCTION:CMS
+CMS_digest_verify                       4006	EXIST::FUNCTION:CMS
+CMS_set1_signers_certs                  4007	EXIST::FUNCTION:CMS
+CMS_signed_get_attr                     4008	EXIST::FUNCTION:CMS
+CMS_RecipientInfo_set0_key              4009	EXIST::FUNCTION:CMS
+CMS_SignedData_init                     4010	EXIST::FUNCTION:CMS
+CMS_RecipientInfo_kekri_get0_id         4011	EXIST::FUNCTION:CMS
+CMS_verify_receipt                      4012	EXIST::FUNCTION:CMS
+CMS_ReceiptRequest_it                   4013	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:CMS
+CMS_ReceiptRequest_it                   4013	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:CMS
+PEM_read_bio_CMS                        4014	EXIST::FUNCTION:CMS
+CMS_get1_crls                           4015	EXIST::FUNCTION:CMS
+CMS_add0_recipient_key                  4016	EXIST::FUNCTION:CMS
+SMIME_read_ASN1                         4017	EXIST::FUNCTION:
+CMS_ReceiptRequest_new                  4018	EXIST::FUNCTION:CMS
+CMS_get0_content                        4019	EXIST::FUNCTION:CMS
+CMS_get1_ReceiptRequest                 4020	EXIST::FUNCTION:CMS
+CMS_signed_add1_attr_by_OBJ             4021	EXIST::FUNCTION:CMS
+CMS_RecipientInfo_kekri_id_cmp          4022	EXIST::FUNCTION:CMS
+CMS_add1_ReceiptRequest                 4023	EXIST::FUNCTION:CMS
+CMS_SignerInfo_get0_signer_id           4024	EXIST::FUNCTION:CMS
+CMS_unsigned_add1_attr_by_NID           4025	EXIST::FUNCTION:CMS
+CMS_unsigned_add1_attr                  4026	EXIST::FUNCTION:CMS
+CMS_signed_get_attr_by_NID              4027	EXIST::FUNCTION:CMS
+CMS_get1_certs                          4028	EXIST::FUNCTION:CMS
+CMS_signed_add1_attr_by_NID             4029	EXIST::FUNCTION:CMS
+CMS_unsigned_add1_attr_by_txt           4030	EXIST::FUNCTION:CMS
+CMS_dataFinal                           4031	EXIST::FUNCTION:CMS
+CMS_RecipientInfo_ktri_get0_signer_id   4032	EXIST:!VMS:FUNCTION:CMS
+CMS_RecipInfo_ktri_get0_sigr_id         4032	EXIST:VMS:FUNCTION:CMS
+i2d_CMS_ReceiptRequest                  4033	EXIST::FUNCTION:CMS
+CMS_add1_recipient_cert                 4034	EXIST::FUNCTION:CMS
+CMS_dataInit                            4035	EXIST::FUNCTION:CMS
+CMS_signed_add1_attr_by_txt             4036	EXIST::FUNCTION:CMS
+CMS_RecipientInfo_decrypt               4037	EXIST::FUNCTION:CMS
+CMS_signed_get_attr_count               4038	EXIST::FUNCTION:CMS
+CMS_get0_eContentType                   4039	EXIST::FUNCTION:CMS
+CMS_set1_eContentType                   4040	EXIST::FUNCTION:CMS
+CMS_ReceiptRequest_create0              4041	EXIST::FUNCTION:CMS
+CMS_add1_signer                         4042	EXIST::FUNCTION:CMS
+CMS_RecipientInfo_set0_pkey             4043	EXIST::FUNCTION:CMS
+ENGINE_set_load_ssl_client_cert_function 4044	EXIST:!VMS:FUNCTION:ENGINE
+ENGINE_set_ld_ssl_clnt_cert_fn          4044	EXIST:VMS:FUNCTION:ENGINE
+ENGINE_get_ssl_client_cert_function     4045	EXIST:!VMS:FUNCTION:ENGINE
+ENGINE_get_ssl_client_cert_fn           4045	EXIST:VMS:FUNCTION:ENGINE
+ENGINE_load_ssl_client_cert             4046	EXIST::FUNCTION:ENGINE
+ENGINE_load_capi                        4047	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
+OPENSSL_isservice                       4048	EXIST::FUNCTION:
+FIPS_dsa_sig_decode                     4049	NOEXIST::FUNCTION:
+EVP_CIPHER_CTX_clear_flags              4050	EXIST::FUNCTION:
+FIPS_rand_status                        4051	NOEXIST::FUNCTION:
+FIPS_rand_set_key                       4052	NOEXIST::FUNCTION:
+CRYPTO_set_mem_info_functions           4053	NOEXIST::FUNCTION:
+RSA_X931_generate_key_ex                4054	NOEXIST::FUNCTION:
+int_ERR_set_state_func                  4055	NOEXIST::FUNCTION:
+int_EVP_MD_set_engine_callbacks         4056	NOEXIST::FUNCTION:
+int_CRYPTO_set_do_dynlock_callback      4057	NOEXIST::FUNCTION:
+FIPS_rng_stick                          4058	NOEXIST::FUNCTION:
+EVP_CIPHER_CTX_set_flags                4059	EXIST::FUNCTION:
+BN_X931_generate_prime_ex               4060	NOEXIST::FUNCTION:
+FIPS_selftest_check                     4061	NOEXIST::FUNCTION:
+FIPS_rand_set_dt                        4062	NOEXIST::FUNCTION:
+CRYPTO_dbg_pop_info                     4063	NOEXIST::FUNCTION:
+FIPS_dsa_free                           4064	NOEXIST::FUNCTION:
+RSA_X931_derive_ex                      4065	NOEXIST::FUNCTION:
+FIPS_rsa_new                            4066	NOEXIST::FUNCTION:
+FIPS_rand_bytes                         4067	NOEXIST::FUNCTION:
+fips_cipher_test                        4068	NOEXIST::FUNCTION:
+EVP_CIPHER_CTX_test_flags               4069	EXIST::FUNCTION:
+CRYPTO_malloc_debug_init                4070	NOEXIST::FUNCTION:
+CRYPTO_dbg_push_info                    4071	NOEXIST::FUNCTION:
+FIPS_corrupt_rsa_keygen                 4072	NOEXIST::FUNCTION:
+FIPS_dh_new                             4073	NOEXIST::FUNCTION:
+FIPS_corrupt_dsa_keygen                 4074	NOEXIST::FUNCTION:
+FIPS_dh_free                            4075	NOEXIST::FUNCTION:
+fips_pkey_signature_test                4076	NOEXIST::FUNCTION:
+EVP_add_alg_module                      4077	NOEXIST::FUNCTION:
+int_RAND_init_engine_callbacks          4078	NOEXIST::FUNCTION:
+int_EVP_CIPHER_set_engine_callbacks     4079	NOEXIST::FUNCTION:
+int_EVP_MD_init_engine_callbacks        4080	NOEXIST::FUNCTION:
+FIPS_rand_test_mode                     4081	NOEXIST::FUNCTION:
+FIPS_rand_reset                         4082	NOEXIST::FUNCTION:
+FIPS_dsa_new                            4083	NOEXIST::FUNCTION:
+int_RAND_set_callbacks                  4084	NOEXIST::FUNCTION:
+BN_X931_derive_prime_ex                 4085	NOEXIST::FUNCTION:
+int_ERR_lib_init                        4086	NOEXIST::FUNCTION:
+int_EVP_CIPHER_init_engine_callbacks    4087	NOEXIST::FUNCTION:
+FIPS_rsa_free                           4088	NOEXIST::FUNCTION:
+FIPS_dsa_sig_encode                     4089	NOEXIST::FUNCTION:
+CRYPTO_dbg_remove_all_info              4090	NOEXIST::FUNCTION:
+OPENSSL_init                            4091	NOEXIST::FUNCTION:
+private_Camellia_set_key                4092	NOEXIST::FUNCTION:
+CRYPTO_strdup                           4093	EXIST::FUNCTION:
+JPAKE_STEP3A_process                    4094	EXIST::FUNCTION:JPAKE
+JPAKE_STEP1_release                     4095	EXIST::FUNCTION:JPAKE
+JPAKE_get_shared_key                    4096	EXIST::FUNCTION:JPAKE
+JPAKE_STEP3B_init                       4097	EXIST::FUNCTION:JPAKE
+JPAKE_STEP1_generate                    4098	EXIST::FUNCTION:JPAKE
+JPAKE_STEP1_init                        4099	EXIST::FUNCTION:JPAKE
+JPAKE_STEP3B_process                    4100	EXIST::FUNCTION:JPAKE
+JPAKE_STEP2_generate                    4101	EXIST::FUNCTION:JPAKE
+JPAKE_CTX_new                           4102	EXIST::FUNCTION:JPAKE
+JPAKE_CTX_free                          4103	EXIST::FUNCTION:JPAKE
+JPAKE_STEP3B_release                    4104	EXIST::FUNCTION:JPAKE
+JPAKE_STEP3A_release                    4105	EXIST::FUNCTION:JPAKE
+JPAKE_STEP2_process                     4106	EXIST::FUNCTION:JPAKE
+JPAKE_STEP3B_generate                   4107	EXIST::FUNCTION:JPAKE
+JPAKE_STEP1_process                     4108	EXIST::FUNCTION:JPAKE
+JPAKE_STEP3A_generate                   4109	EXIST::FUNCTION:JPAKE
+JPAKE_STEP2_release                     4110	EXIST::FUNCTION:JPAKE
+JPAKE_STEP3A_init                       4111	EXIST::FUNCTION:JPAKE
+ERR_load_JPAKE_strings                  4112	EXIST::FUNCTION:JPAKE
+JPAKE_STEP2_init                        4113	EXIST::FUNCTION:JPAKE
+pqueue_size                             4114	EXIST::FUNCTION:
+i2d_TS_ACCURACY                         4115	EXIST::FUNCTION:
+i2d_TS_MSG_IMPRINT_fp                   4116	EXIST::FUNCTION:
+i2d_TS_MSG_IMPRINT                      4117	EXIST::FUNCTION:
+EVP_PKEY_print_public                   4118	EXIST::FUNCTION:
+EVP_PKEY_CTX_new                        4119	EXIST::FUNCTION:
+i2d_TS_TST_INFO                         4120	EXIST::FUNCTION:
+EVP_PKEY_asn1_find                      4121	EXIST::FUNCTION:
+DSO_METHOD_beos                         4122	EXIST::FUNCTION:
+TS_CONF_load_cert                       4123	EXIST::FUNCTION:
+TS_REQ_get_ext                          4124	EXIST::FUNCTION:
+EVP_PKEY_sign_init                      4125	EXIST::FUNCTION:
+ASN1_item_print                         4126	EXIST::FUNCTION:
+TS_TST_INFO_set_nonce                   4127	EXIST::FUNCTION:
+TS_RESP_dup                             4128	EXIST::FUNCTION:
+ENGINE_register_pkey_meths              4129	EXIST::FUNCTION:ENGINE
+EVP_PKEY_asn1_add0                      4130	EXIST::FUNCTION:
+PKCS7_add0_attrib_signing_time          4131	EXIST::FUNCTION:
+i2d_TS_TST_INFO_fp                      4132	EXIST::FUNCTION:
+BIO_asn1_get_prefix                     4133	EXIST::FUNCTION:
+TS_TST_INFO_set_time                    4134	EXIST::FUNCTION:
+EVP_PKEY_meth_set_decrypt               4135	EXIST::FUNCTION:
+EVP_PKEY_set_type_str                   4136	EXIST::FUNCTION:
+EVP_PKEY_CTX_get_keygen_info            4137	EXIST::FUNCTION:
+TS_REQ_set_policy_id                    4138	EXIST::FUNCTION:
+d2i_TS_RESP_fp                          4139	EXIST::FUNCTION:
+ENGINE_get_pkey_asn1_meth_engine        4140	EXIST:!VMS:FUNCTION:ENGINE
+ENGINE_get_pkey_asn1_meth_eng           4140	EXIST:VMS:FUNCTION:ENGINE
+WHIRLPOOL_Init                          4141	EXIST:!VMSVAX:FUNCTION:WHIRLPOOL
+TS_RESP_set_status_info                 4142	EXIST::FUNCTION:
+EVP_PKEY_keygen                         4143	EXIST::FUNCTION:
+EVP_DigestSignInit                      4144	EXIST::FUNCTION:
+TS_ACCURACY_set_millis                  4145	EXIST::FUNCTION:
+TS_REQ_dup                              4146	EXIST::FUNCTION:
+GENERAL_NAME_dup                        4147	EXIST::FUNCTION:
+ASN1_SEQUENCE_ANY_it                    4148	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_SEQUENCE_ANY_it                    4148	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+WHIRLPOOL                               4149	EXIST:!VMSVAX:FUNCTION:WHIRLPOOL
+X509_STORE_get1_crls                    4150	EXIST::FUNCTION:
+ENGINE_get_pkey_asn1_meth               4151	EXIST::FUNCTION:ENGINE
+EVP_PKEY_asn1_new                       4152	EXIST::FUNCTION:
+BIO_new_NDEF                            4153	EXIST::FUNCTION:
+ENGINE_get_pkey_meth                    4154	EXIST::FUNCTION:ENGINE
+TS_MSG_IMPRINT_set_algo                 4155	EXIST::FUNCTION:
+i2d_TS_TST_INFO_bio                     4156	EXIST::FUNCTION:
+TS_TST_INFO_set_ordering                4157	EXIST::FUNCTION:
+TS_TST_INFO_get_ext_by_OBJ              4158	EXIST::FUNCTION:
+CRYPTO_THREADID_set_pointer             4159	EXIST::FUNCTION:
+TS_CONF_get_tsa_section                 4160	EXIST::FUNCTION:
+SMIME_write_ASN1                        4161	EXIST::FUNCTION:
+TS_RESP_CTX_set_signer_key              4162	EXIST::FUNCTION:
+EVP_PKEY_encrypt_old                    4163	EXIST::FUNCTION:
+EVP_PKEY_encrypt_init                   4164	EXIST::FUNCTION:
+CRYPTO_THREADID_cpy                     4165	EXIST::FUNCTION:
+ASN1_PCTX_get_cert_flags                4166	EXIST::FUNCTION:
+i2d_ESS_SIGNING_CERT                    4167	EXIST::FUNCTION:
+TS_CONF_load_key                        4168	EXIST::FUNCTION:
+i2d_ASN1_SEQUENCE_ANY                   4169	EXIST::FUNCTION:
+d2i_TS_MSG_IMPRINT_bio                  4170	EXIST::FUNCTION:
+EVP_PKEY_asn1_set_public                4171	EXIST::FUNCTION:
+b2i_PublicKey_bio                       4172	EXIST::FUNCTION:
+BIO_asn1_set_prefix                     4173	EXIST::FUNCTION:
+EVP_PKEY_new_mac_key                    4174	EXIST::FUNCTION:
+BIO_new_CMS                             4175	EXIST::FUNCTION:CMS
+CRYPTO_THREADID_cmp                     4176	EXIST::FUNCTION:
+TS_REQ_ext_free                         4177	EXIST::FUNCTION:
+EVP_PKEY_asn1_set_free                  4178	EXIST::FUNCTION:
+EVP_PKEY_get0_asn1                      4179	EXIST::FUNCTION:
+d2i_NETSCAPE_X509                       4180	EXIST::FUNCTION:
+EVP_PKEY_verify_recover_init            4181	EXIST::FUNCTION:
+EVP_PKEY_CTX_set_data                   4182	EXIST::FUNCTION:
+EVP_PKEY_keygen_init                    4183	EXIST::FUNCTION:
+TS_RESP_CTX_set_status_info             4184	EXIST::FUNCTION:
+TS_MSG_IMPRINT_get_algo                 4185	EXIST::FUNCTION:
+TS_REQ_print_bio                        4186	EXIST::FUNCTION:
+EVP_PKEY_CTX_ctrl_str                   4187	EXIST::FUNCTION:
+EVP_PKEY_get_default_digest_nid         4188	EXIST::FUNCTION:
+PEM_write_bio_PKCS7_stream              4189	EXIST::FUNCTION:
+TS_MSG_IMPRINT_print_bio                4190	EXIST::FUNCTION:
+BN_asc2bn                               4191	EXIST::FUNCTION:
+TS_REQ_get_policy_id                    4192	EXIST::FUNCTION:
+ENGINE_set_default_pkey_asn1_meths      4193	EXIST:!VMS:FUNCTION:ENGINE
+ENGINE_set_def_pkey_asn1_meths          4193	EXIST:VMS:FUNCTION:ENGINE
+d2i_TS_ACCURACY                         4194	EXIST::FUNCTION:
+DSO_global_lookup                       4195	EXIST::FUNCTION:
+TS_CONF_set_tsa_name                    4196	EXIST::FUNCTION:
+i2d_ASN1_SET_ANY                        4197	EXIST::FUNCTION:
+ENGINE_load_gost                        4198	EXIST::FUNCTION:ENGINE,GOST,STATIC_ENGINE
+WHIRLPOOL_BitUpdate                     4199	EXIST:!VMSVAX:FUNCTION:WHIRLPOOL
+ASN1_PCTX_get_flags                     4200	EXIST::FUNCTION:
+TS_TST_INFO_get_ext_by_NID              4201	EXIST::FUNCTION:
+TS_RESP_new                             4202	EXIST::FUNCTION:
+ESS_CERT_ID_dup                         4203	EXIST::FUNCTION:
+TS_STATUS_INFO_dup                      4204	EXIST::FUNCTION:
+TS_REQ_delete_ext                       4205	EXIST::FUNCTION:
+EVP_DigestVerifyFinal                   4206	EXIST::FUNCTION:
+EVP_PKEY_print_params                   4207	EXIST::FUNCTION:
+i2d_CMS_bio_stream                      4208	EXIST::FUNCTION:CMS
+TS_REQ_get_msg_imprint                  4209	EXIST::FUNCTION:
+OBJ_find_sigid_by_algs                  4210	EXIST::FUNCTION:
+TS_TST_INFO_get_serial                  4211	EXIST::FUNCTION:
+TS_REQ_get_nonce                        4212	EXIST::FUNCTION:
+X509_PUBKEY_set0_param                  4213	EXIST::FUNCTION:
+EVP_PKEY_CTX_set0_keygen_info           4214	EXIST::FUNCTION:
+DIST_POINT_set_dpname                   4215	EXIST::FUNCTION:
+i2d_ISSUING_DIST_POINT                  4216	EXIST::FUNCTION:
+ASN1_SET_ANY_it                         4217	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ASN1_SET_ANY_it                         4217	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+EVP_PKEY_CTX_get_data                   4218	EXIST::FUNCTION:
+TS_STATUS_INFO_print_bio                4219	EXIST::FUNCTION:
+EVP_PKEY_derive_init                    4220	EXIST::FUNCTION:
+d2i_TS_TST_INFO                         4221	EXIST::FUNCTION:
+EVP_PKEY_asn1_add_alias                 4222	EXIST::FUNCTION:
+d2i_TS_RESP_bio                         4223	EXIST::FUNCTION:
+OTHERNAME_cmp                           4224	EXIST::FUNCTION:
+GENERAL_NAME_set0_value                 4225	EXIST::FUNCTION:
+PKCS7_RECIP_INFO_get0_alg               4226	EXIST::FUNCTION:
+TS_RESP_CTX_new                         4227	EXIST::FUNCTION:
+TS_RESP_set_tst_info                    4228	EXIST::FUNCTION:
+PKCS7_final                             4229	EXIST::FUNCTION:
+EVP_PKEY_base_id                        4230	EXIST::FUNCTION:
+TS_RESP_CTX_set_signer_cert             4231	EXIST::FUNCTION:
+TS_REQ_set_msg_imprint                  4232	EXIST::FUNCTION:
+EVP_PKEY_CTX_ctrl                       4233	EXIST::FUNCTION:
+TS_CONF_set_digests                     4234	EXIST::FUNCTION:
+d2i_TS_MSG_IMPRINT                      4235	EXIST::FUNCTION:
+EVP_PKEY_meth_set_ctrl                  4236	EXIST::FUNCTION:
+TS_REQ_get_ext_by_NID                   4237	EXIST::FUNCTION:
+PKCS5_pbe_set0_algor                    4238	EXIST::FUNCTION:
+BN_BLINDING_thread_id                   4239	EXIST::FUNCTION:
+TS_ACCURACY_new                         4240	EXIST::FUNCTION:
+X509_CRL_METHOD_free                    4241	EXIST::FUNCTION:
+ASN1_PCTX_get_nm_flags                  4242	EXIST::FUNCTION:
+EVP_PKEY_meth_set_sign                  4243	EXIST::FUNCTION:
+CRYPTO_THREADID_current                 4244	EXIST::FUNCTION:
+EVP_PKEY_decrypt_init                   4245	EXIST::FUNCTION:
+NETSCAPE_X509_free                      4246	EXIST::FUNCTION:
+i2b_PVK_bio                             4247	EXIST::FUNCTION:RC4
+EVP_PKEY_print_private                  4248	EXIST::FUNCTION:
+GENERAL_NAME_get0_value                 4249	EXIST::FUNCTION:
+b2i_PVK_bio                             4250	EXIST::FUNCTION:RC4
+ASN1_UTCTIME_adj                        4251	EXIST::FUNCTION:
+TS_TST_INFO_new                         4252	EXIST::FUNCTION:
+EVP_MD_do_all_sorted                    4253	EXIST::FUNCTION:
+TS_CONF_set_default_engine              4254	EXIST::FUNCTION:
+TS_ACCURACY_set_seconds                 4255	EXIST::FUNCTION:
+TS_TST_INFO_get_time                    4256	EXIST::FUNCTION:
+PKCS8_pkey_get0                         4257	EXIST::FUNCTION:
+EVP_PKEY_asn1_get0                      4258	EXIST::FUNCTION:
+OBJ_add_sigid                           4259	EXIST::FUNCTION:
+PKCS7_SIGNER_INFO_sign                  4260	EXIST::FUNCTION:
+EVP_PKEY_paramgen_init                  4261	EXIST::FUNCTION:
+EVP_PKEY_sign                           4262	EXIST::FUNCTION:
+OBJ_sigid_free                          4263	EXIST::FUNCTION:
+EVP_PKEY_meth_set_init                  4264	EXIST::FUNCTION:
+d2i_ESS_ISSUER_SERIAL                   4265	EXIST::FUNCTION:
+ISSUING_DIST_POINT_new                  4266	EXIST::FUNCTION:
+ASN1_TIME_adj                           4267	EXIST::FUNCTION:
+TS_OBJ_print_bio                        4268	EXIST::FUNCTION:
+EVP_PKEY_meth_set_verify_recover        4269	EXIST:!VMS:FUNCTION:
+EVP_PKEY_meth_set_vrfy_recover          4269	EXIST:VMS:FUNCTION:
+TS_RESP_get_status_info                 4270	EXIST::FUNCTION:
+CMS_stream                              4271	EXIST::FUNCTION:CMS
+EVP_PKEY_CTX_set_cb                     4272	EXIST::FUNCTION:
+PKCS7_to_TS_TST_INFO                    4273	EXIST::FUNCTION:
+ASN1_PCTX_get_oid_flags                 4274	EXIST::FUNCTION:
+TS_TST_INFO_add_ext                     4275	EXIST::FUNCTION:
+EVP_PKEY_meth_set_derive                4276	EXIST::FUNCTION:
+i2d_TS_RESP_fp                          4277	EXIST::FUNCTION:
+i2d_TS_MSG_IMPRINT_bio                  4278	EXIST::FUNCTION:
+TS_RESP_CTX_set_accuracy                4279	EXIST::FUNCTION:
+TS_REQ_set_nonce                        4280	EXIST::FUNCTION:
+ESS_CERT_ID_new                         4281	EXIST::FUNCTION:
+ENGINE_pkey_asn1_find_str               4282	EXIST::FUNCTION:ENGINE
+TS_REQ_get_ext_count                    4283	EXIST::FUNCTION:
+BUF_reverse                             4284	EXIST::FUNCTION:
+TS_TST_INFO_print_bio                   4285	EXIST::FUNCTION:
+d2i_ISSUING_DIST_POINT                  4286	EXIST::FUNCTION:
+ENGINE_get_pkey_meths                   4287	EXIST::FUNCTION:ENGINE
+i2b_PrivateKey_bio                      4288	EXIST::FUNCTION:
+i2d_TS_RESP                             4289	EXIST::FUNCTION:
+b2i_PublicKey                           4290	EXIST::FUNCTION:
+TS_VERIFY_CTX_cleanup                   4291	EXIST::FUNCTION:
+TS_STATUS_INFO_free                     4292	EXIST::FUNCTION:
+TS_RESP_verify_token                    4293	EXIST::FUNCTION:
+OBJ_bsearch_ex_                         4294	EXIST::FUNCTION:
+ASN1_bn_print                           4295	EXIST::FUNCTION:BIO
+EVP_PKEY_asn1_get_count                 4296	EXIST::FUNCTION:
+ENGINE_register_pkey_asn1_meths         4297	EXIST::FUNCTION:ENGINE
+ASN1_PCTX_set_nm_flags                  4298	EXIST::FUNCTION:
+EVP_DigestVerifyInit                    4299	EXIST::FUNCTION:
+ENGINE_set_default_pkey_meths           4300	EXIST::FUNCTION:ENGINE
+TS_TST_INFO_get_policy_id               4301	EXIST::FUNCTION:
+TS_REQ_get_cert_req                     4302	EXIST::FUNCTION:
+X509_CRL_set_meth_data                  4303	EXIST::FUNCTION:
+PKCS8_pkey_set0                         4304	EXIST::FUNCTION:
+ASN1_STRING_copy                        4305	EXIST::FUNCTION:
+d2i_TS_TST_INFO_fp                      4306	EXIST::FUNCTION:
+X509_CRL_match                          4307	EXIST::FUNCTION:
+EVP_PKEY_asn1_set_private               4308	EXIST::FUNCTION:
+TS_TST_INFO_get_ext_d2i                 4309	EXIST::FUNCTION:
+TS_RESP_CTX_add_policy                  4310	EXIST::FUNCTION:
+d2i_TS_RESP                             4311	EXIST::FUNCTION:
+TS_CONF_load_certs                      4312	EXIST::FUNCTION:
+TS_TST_INFO_get_msg_imprint             4313	EXIST::FUNCTION:
+ERR_load_TS_strings                     4314	EXIST::FUNCTION:
+TS_TST_INFO_get_version                 4315	EXIST::FUNCTION:
+EVP_PKEY_CTX_dup                        4316	EXIST::FUNCTION:
+EVP_PKEY_meth_set_verify                4317	EXIST::FUNCTION:
+i2b_PublicKey_bio                       4318	EXIST::FUNCTION:
+TS_CONF_set_certs                       4319	EXIST::FUNCTION:
+EVP_PKEY_asn1_get0_info                 4320	EXIST::FUNCTION:
+TS_VERIFY_CTX_free                      4321	EXIST::FUNCTION:
+TS_REQ_get_ext_by_critical              4322	EXIST::FUNCTION:
+TS_RESP_CTX_set_serial_cb               4323	EXIST::FUNCTION:
+X509_CRL_get_meth_data                  4324	EXIST::FUNCTION:
+TS_RESP_CTX_set_time_cb                 4325	EXIST::FUNCTION:
+TS_MSG_IMPRINT_get_msg                  4326	EXIST::FUNCTION:
+TS_TST_INFO_ext_free                    4327	EXIST::FUNCTION:
+TS_REQ_get_version                      4328	EXIST::FUNCTION:
+TS_REQ_add_ext                          4329	EXIST::FUNCTION:
+EVP_PKEY_CTX_set_app_data               4330	EXIST::FUNCTION:
+OBJ_bsearch_                            4331	EXIST::FUNCTION:
+EVP_PKEY_meth_set_verifyctx             4332	EXIST::FUNCTION:
+i2d_PKCS7_bio_stream                    4333	EXIST::FUNCTION:
+CRYPTO_THREADID_set_numeric             4334	EXIST::FUNCTION:
+PKCS7_sign_add_signer                   4335	EXIST::FUNCTION:
+d2i_TS_TST_INFO_bio                     4336	EXIST::FUNCTION:
+TS_TST_INFO_get_ordering                4337	EXIST::FUNCTION:
+TS_RESP_print_bio                       4338	EXIST::FUNCTION:
+TS_TST_INFO_get_exts                    4339	EXIST::FUNCTION:
+HMAC_CTX_copy                           4340	EXIST::FUNCTION:HMAC
+PKCS5_pbe2_set_iv                       4341	EXIST::FUNCTION:
+ENGINE_get_pkey_asn1_meths              4342	EXIST::FUNCTION:ENGINE
+b2i_PrivateKey                          4343	EXIST::FUNCTION:
+EVP_PKEY_CTX_get_app_data               4344	EXIST::FUNCTION:
+TS_REQ_set_cert_req                     4345	EXIST::FUNCTION:
+CRYPTO_THREADID_set_callback            4346	EXIST::FUNCTION:
+TS_CONF_set_serial                      4347	EXIST::FUNCTION:
+TS_TST_INFO_free                        4348	EXIST::FUNCTION:
+d2i_TS_REQ_fp                           4349	EXIST::FUNCTION:
+TS_RESP_verify_response                 4350	EXIST::FUNCTION:
+i2d_ESS_ISSUER_SERIAL                   4351	EXIST::FUNCTION:
+TS_ACCURACY_get_seconds                 4352	EXIST::FUNCTION:
+EVP_CIPHER_do_all                       4353	EXIST::FUNCTION:
+b2i_PrivateKey_bio                      4354	EXIST::FUNCTION:
+OCSP_CERTID_dup                         4355	EXIST::FUNCTION:
+X509_PUBKEY_get0_param                  4356	EXIST::FUNCTION:
+TS_MSG_IMPRINT_dup                      4357	EXIST::FUNCTION:
+PKCS7_print_ctx                         4358	EXIST::FUNCTION:
+i2d_TS_REQ_bio                          4359	EXIST::FUNCTION:
+EVP_whirlpool                           4360	EXIST:!VMSVAX:FUNCTION:WHIRLPOOL
+EVP_PKEY_asn1_set_param                 4361	EXIST::FUNCTION:
+EVP_PKEY_meth_set_encrypt               4362	EXIST::FUNCTION:
+ASN1_PCTX_set_flags                     4363	EXIST::FUNCTION:
+i2d_ESS_CERT_ID                         4364	EXIST::FUNCTION:
+TS_VERIFY_CTX_new                       4365	EXIST::FUNCTION:
+TS_RESP_CTX_set_extension_cb            4366	EXIST::FUNCTION:
+ENGINE_register_all_pkey_meths          4367	EXIST::FUNCTION:ENGINE
+TS_RESP_CTX_set_status_info_cond        4368	EXIST:!VMS:FUNCTION:
+TS_RESP_CTX_set_stat_info_cond          4368	EXIST:VMS:FUNCTION:
+EVP_PKEY_verify                         4369	EXIST::FUNCTION:
+WHIRLPOOL_Final                         4370	EXIST:!VMSVAX:FUNCTION:WHIRLPOOL
+X509_CRL_METHOD_new                     4371	EXIST::FUNCTION:
+EVP_DigestSignFinal                     4372	EXIST::FUNCTION:
+TS_RESP_CTX_set_def_policy              4373	EXIST::FUNCTION:
+NETSCAPE_X509_it                        4374	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+NETSCAPE_X509_it                        4374	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+TS_RESP_create_response                 4375	EXIST::FUNCTION:
+PKCS7_SIGNER_INFO_get0_algs             4376	EXIST::FUNCTION:
+TS_TST_INFO_get_nonce                   4377	EXIST::FUNCTION:
+EVP_PKEY_decrypt_old                    4378	EXIST::FUNCTION:
+TS_TST_INFO_set_policy_id               4379	EXIST::FUNCTION:
+TS_CONF_set_ess_cert_id_chain           4380	EXIST::FUNCTION:
+EVP_PKEY_CTX_get0_pkey                  4381	EXIST::FUNCTION:
+d2i_TS_REQ                              4382	EXIST::FUNCTION:
+EVP_PKEY_asn1_find_str                  4383	EXIST::FUNCTION:
+BIO_f_asn1                              4384	EXIST::FUNCTION:
+ESS_SIGNING_CERT_new                    4385	EXIST::FUNCTION:
+EVP_PBE_find                            4386	EXIST::FUNCTION:
+X509_CRL_get0_by_cert                   4387	EXIST::FUNCTION:
+EVP_PKEY_derive                         4388	EXIST::FUNCTION:
+i2d_TS_REQ                              4389	EXIST::FUNCTION:
+TS_TST_INFO_delete_ext                  4390	EXIST::FUNCTION:
+ESS_ISSUER_SERIAL_free                  4391	EXIST::FUNCTION:
+ASN1_PCTX_set_str_flags                 4392	EXIST::FUNCTION:
+ENGINE_get_pkey_asn1_meth_str           4393	EXIST::FUNCTION:ENGINE
+TS_CONF_set_signer_key                  4394	EXIST::FUNCTION:
+TS_ACCURACY_get_millis                  4395	EXIST::FUNCTION:
+TS_RESP_get_token                       4396	EXIST::FUNCTION:
+TS_ACCURACY_dup                         4397	EXIST::FUNCTION:
+ENGINE_register_all_pkey_asn1_meths     4398	EXIST:!VMS:FUNCTION:ENGINE
+ENGINE_reg_all_pkey_asn1_meths          4398	EXIST:VMS:FUNCTION:ENGINE
+X509_CRL_set_default_method             4399	EXIST::FUNCTION:
+CRYPTO_THREADID_hash                    4400	EXIST::FUNCTION:
+CMS_ContentInfo_print_ctx               4401	EXIST::FUNCTION:CMS
+TS_RESP_free                            4402	EXIST::FUNCTION:
+ISSUING_DIST_POINT_free                 4403	EXIST::FUNCTION:
+ESS_ISSUER_SERIAL_new                   4404	EXIST::FUNCTION:
+CMS_add1_crl                            4405	EXIST::FUNCTION:CMS
+PKCS7_add1_attrib_digest                4406	EXIST::FUNCTION:
+TS_RESP_CTX_add_md                      4407	EXIST::FUNCTION:
+TS_TST_INFO_dup                         4408	EXIST::FUNCTION:
+ENGINE_set_pkey_asn1_meths              4409	EXIST::FUNCTION:ENGINE
+PEM_write_bio_Parameters                4410	EXIST::FUNCTION:
+TS_TST_INFO_get_accuracy                4411	EXIST::FUNCTION:
+X509_CRL_get0_by_serial                 4412	EXIST::FUNCTION:
+TS_TST_INFO_set_version                 4413	EXIST::FUNCTION:
+TS_RESP_CTX_get_tst_info                4414	EXIST::FUNCTION:
+TS_RESP_verify_signature                4415	EXIST::FUNCTION:
+CRYPTO_THREADID_get_callback            4416	EXIST::FUNCTION:
+TS_TST_INFO_get_tsa                     4417	EXIST::FUNCTION:
+TS_STATUS_INFO_new                      4418	EXIST::FUNCTION:
+EVP_PKEY_CTX_get_cb                     4419	EXIST::FUNCTION:
+TS_REQ_get_ext_d2i                      4420	EXIST::FUNCTION:
+GENERAL_NAME_set0_othername             4421	EXIST::FUNCTION:
+TS_TST_INFO_get_ext_count               4422	EXIST::FUNCTION:
+TS_RESP_CTX_get_request                 4423	EXIST::FUNCTION:
+i2d_NETSCAPE_X509                       4424	EXIST::FUNCTION:
+ENGINE_get_pkey_meth_engine             4425	EXIST::FUNCTION:ENGINE
+EVP_PKEY_meth_set_signctx               4426	EXIST::FUNCTION:
+EVP_PKEY_asn1_copy                      4427	EXIST::FUNCTION:
+ASN1_TYPE_cmp                           4428	EXIST::FUNCTION:
+EVP_CIPHER_do_all_sorted                4429	EXIST::FUNCTION:
+EVP_PKEY_CTX_free                       4430	EXIST::FUNCTION:
+ISSUING_DIST_POINT_it                   4431	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+ISSUING_DIST_POINT_it                   4431	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+d2i_TS_MSG_IMPRINT_fp                   4432	EXIST::FUNCTION:
+X509_STORE_get1_certs                   4433	EXIST::FUNCTION:
+EVP_PKEY_CTX_get_operation              4434	EXIST::FUNCTION:
+d2i_ESS_SIGNING_CERT                    4435	EXIST::FUNCTION:
+TS_CONF_set_ordering                    4436	EXIST::FUNCTION:
+EVP_PBE_alg_add_type                    4437	EXIST::FUNCTION:
+TS_REQ_set_version                      4438	EXIST::FUNCTION:
+EVP_PKEY_get0                           4439	EXIST::FUNCTION:
+BIO_asn1_set_suffix                     4440	EXIST::FUNCTION:
+i2d_TS_STATUS_INFO                      4441	EXIST::FUNCTION:
+EVP_MD_do_all                           4442	EXIST::FUNCTION:
+TS_TST_INFO_set_accuracy                4443	EXIST::FUNCTION:
+PKCS7_add_attrib_content_type           4444	EXIST::FUNCTION:
+ERR_remove_thread_state                 4445	EXIST::FUNCTION:
+EVP_PKEY_meth_add0                      4446	EXIST::FUNCTION:
+TS_TST_INFO_set_tsa                     4447	EXIST::FUNCTION:
+EVP_PKEY_meth_new                       4448	EXIST::FUNCTION:
+WHIRLPOOL_Update                        4449	EXIST:!VMSVAX:FUNCTION:WHIRLPOOL
+TS_CONF_set_accuracy                    4450	EXIST::FUNCTION:
+ASN1_PCTX_set_oid_flags                 4451	EXIST::FUNCTION:
+ESS_SIGNING_CERT_dup                    4452	EXIST::FUNCTION:
+d2i_TS_REQ_bio                          4453	EXIST::FUNCTION:
+X509_time_adj_ex                        4454	EXIST::FUNCTION:
+TS_RESP_CTX_add_flags                   4455	EXIST::FUNCTION:
+d2i_TS_STATUS_INFO                      4456	EXIST::FUNCTION:
+TS_MSG_IMPRINT_set_msg                  4457	EXIST::FUNCTION:
+BIO_asn1_get_suffix                     4458	EXIST::FUNCTION:
+TS_REQ_free                             4459	EXIST::FUNCTION:
+EVP_PKEY_meth_free                      4460	EXIST::FUNCTION:
+TS_REQ_get_exts                         4461	EXIST::FUNCTION:
+TS_RESP_CTX_set_clock_precision_digits  4462	EXIST:!VMS:FUNCTION:
+TS_RESP_CTX_set_clk_prec_digits         4462	EXIST:VMS:FUNCTION:
+TS_RESP_CTX_add_failure_info            4463	EXIST::FUNCTION:
+i2d_TS_RESP_bio                         4464	EXIST::FUNCTION:
+EVP_PKEY_CTX_get0_peerkey               4465	EXIST::FUNCTION:
+PEM_write_bio_CMS_stream                4466	EXIST::FUNCTION:CMS
+TS_REQ_new                              4467	EXIST::FUNCTION:
+TS_MSG_IMPRINT_new                      4468	EXIST::FUNCTION:
+EVP_PKEY_meth_find                      4469	EXIST::FUNCTION:
+EVP_PKEY_id                             4470	EXIST::FUNCTION:
+TS_TST_INFO_set_serial                  4471	EXIST::FUNCTION:
+a2i_GENERAL_NAME                        4472	EXIST::FUNCTION:
+TS_CONF_set_crypto_device               4473	EXIST::FUNCTION:
+EVP_PKEY_verify_init                    4474	EXIST::FUNCTION:
+TS_CONF_set_policies                    4475	EXIST::FUNCTION:
+ASN1_PCTX_new                           4476	EXIST::FUNCTION:
+ESS_CERT_ID_free                        4477	EXIST::FUNCTION:
+ENGINE_unregister_pkey_meths            4478	EXIST::FUNCTION:ENGINE
+TS_MSG_IMPRINT_free                     4479	EXIST::FUNCTION:
+TS_VERIFY_CTX_init                      4480	EXIST::FUNCTION:
+PKCS7_stream                            4481	EXIST::FUNCTION:
+TS_RESP_CTX_set_certs                   4482	EXIST::FUNCTION:
+TS_CONF_set_def_policy                  4483	EXIST::FUNCTION:
+ASN1_GENERALIZEDTIME_adj                4484	EXIST::FUNCTION:
+NETSCAPE_X509_new                       4485	EXIST::FUNCTION:
+TS_ACCURACY_free                        4486	EXIST::FUNCTION:
+TS_RESP_get_tst_info                    4487	EXIST::FUNCTION:
+EVP_PKEY_derive_set_peer                4488	EXIST::FUNCTION:
+PEM_read_bio_Parameters                 4489	EXIST::FUNCTION:
+TS_CONF_set_clock_precision_digits      4490	EXIST:!VMS:FUNCTION:
+TS_CONF_set_clk_prec_digits             4490	EXIST:VMS:FUNCTION:
+ESS_ISSUER_SERIAL_dup                   4491	EXIST::FUNCTION:
+TS_ACCURACY_get_micros                  4492	EXIST::FUNCTION:
+ASN1_PCTX_get_str_flags                 4493	EXIST::FUNCTION:
+NAME_CONSTRAINTS_check                  4494	EXIST::FUNCTION:
+ASN1_BIT_STRING_check                   4495	EXIST::FUNCTION:
+X509_check_akid                         4496	EXIST::FUNCTION:
+ENGINE_unregister_pkey_asn1_meths       4497	EXIST:!VMS:FUNCTION:ENGINE
+ENGINE_unreg_pkey_asn1_meths            4497	EXIST:VMS:FUNCTION:ENGINE
+ASN1_PCTX_free                          4498	EXIST::FUNCTION:
+PEM_write_bio_ASN1_stream               4499	EXIST::FUNCTION:
+i2d_ASN1_bio_stream                     4500	EXIST::FUNCTION:
+TS_X509_ALGOR_print_bio                 4501	EXIST::FUNCTION:
+EVP_PKEY_meth_set_cleanup               4502	EXIST::FUNCTION:
+EVP_PKEY_asn1_free                      4503	EXIST::FUNCTION:
+ESS_SIGNING_CERT_free                   4504	EXIST::FUNCTION:
+TS_TST_INFO_set_msg_imprint             4505	EXIST::FUNCTION:
+GENERAL_NAME_cmp                        4506	EXIST::FUNCTION:
+d2i_ASN1_SET_ANY                        4507	EXIST::FUNCTION:
+ENGINE_set_pkey_meths                   4508	EXIST::FUNCTION:ENGINE
+i2d_TS_REQ_fp                           4509	EXIST::FUNCTION:
+d2i_ASN1_SEQUENCE_ANY                   4510	EXIST::FUNCTION:
+GENERAL_NAME_get0_otherName             4511	EXIST::FUNCTION:
+d2i_ESS_CERT_ID                         4512	EXIST::FUNCTION:
+OBJ_find_sigid_algs                     4513	EXIST::FUNCTION:
+EVP_PKEY_meth_set_keygen                4514	EXIST::FUNCTION:
+PKCS5_PBKDF2_HMAC                       4515	EXIST::FUNCTION:
+EVP_PKEY_paramgen                       4516	EXIST::FUNCTION:
+EVP_PKEY_meth_set_paramgen              4517	EXIST::FUNCTION:
+BIO_new_PKCS7                           4518	EXIST::FUNCTION:
+EVP_PKEY_verify_recover                 4519	EXIST::FUNCTION:
+TS_ext_print_bio                        4520	EXIST::FUNCTION:
+TS_ASN1_INTEGER_print_bio               4521	EXIST::FUNCTION:
+check_defer                             4522	EXIST::FUNCTION:
+DSO_pathbyaddr                          4523	EXIST::FUNCTION:
+EVP_PKEY_set_type                       4524	EXIST::FUNCTION:
+TS_ACCURACY_set_micros                  4525	EXIST::FUNCTION:
+TS_REQ_to_TS_VERIFY_CTX                 4526	EXIST::FUNCTION:
+EVP_PKEY_meth_set_copy                  4527	EXIST::FUNCTION:
+ASN1_PCTX_set_cert_flags                4528	EXIST::FUNCTION:
+TS_TST_INFO_get_ext                     4529	EXIST::FUNCTION:
+EVP_PKEY_asn1_set_ctrl                  4530	EXIST::FUNCTION:
+TS_TST_INFO_get_ext_by_critical         4531	EXIST::FUNCTION:
+EVP_PKEY_CTX_new_id                     4532	EXIST::FUNCTION:
+TS_REQ_get_ext_by_OBJ                   4533	EXIST::FUNCTION:
+TS_CONF_set_signer_cert                 4534	EXIST::FUNCTION:
+X509_NAME_hash_old                      4535	EXIST::FUNCTION:
+ASN1_TIME_set_string                    4536	EXIST::FUNCTION:
+EVP_MD_flags                            4537	EXIST::FUNCTION:
+TS_RESP_CTX_free                        4538	EXIST::FUNCTION:
+DSAparams_dup                           4539	EXIST::FUNCTION:DSA
+DHparams_dup                            4540	EXIST::FUNCTION:DH
+OCSP_REQ_CTX_add1_header                4541	EXIST::FUNCTION:
+OCSP_REQ_CTX_set1_req                   4542	EXIST::FUNCTION:
+X509_STORE_set_verify_cb                4543	EXIST::FUNCTION:
+X509_STORE_CTX_get0_current_crl         4544	EXIST::FUNCTION:
+X509_STORE_CTX_get0_parent_ctx          4545	EXIST::FUNCTION:
+X509_STORE_CTX_get0_current_issuer      4546	EXIST:!VMS:FUNCTION:
+X509_STORE_CTX_get0_cur_issuer          4546	EXIST:VMS:FUNCTION:
+X509_issuer_name_hash_old               4547	EXIST::FUNCTION:MD5
+X509_subject_name_hash_old              4548	EXIST::FUNCTION:MD5
+EVP_CIPHER_CTX_copy                     4549	EXIST::FUNCTION:
+UI_method_get_prompt_constructor        4550	EXIST:!VMS:FUNCTION:
+UI_method_get_prompt_constructr         4550	EXIST:VMS:FUNCTION:
+UI_method_set_prompt_constructor        4551	EXIST:!VMS:FUNCTION:
+UI_method_set_prompt_constructr         4551	EXIST:VMS:FUNCTION:
+EVP_read_pw_string_min                  4552	EXIST::FUNCTION:
+CRYPTO_cts128_encrypt                   4553	EXIST::FUNCTION:
+CRYPTO_cts128_decrypt_block             4554	EXIST::FUNCTION:
+CRYPTO_cfb128_1_encrypt                 4555	EXIST::FUNCTION:
+CRYPTO_cbc128_encrypt                   4556	EXIST::FUNCTION:
+CRYPTO_ctr128_encrypt                   4557	EXIST::FUNCTION:
+CRYPTO_ofb128_encrypt                   4558	EXIST::FUNCTION:
+CRYPTO_cts128_decrypt                   4559	EXIST::FUNCTION:
+CRYPTO_cts128_encrypt_block             4560	EXIST::FUNCTION:
+CRYPTO_cbc128_decrypt                   4561	EXIST::FUNCTION:
+CRYPTO_cfb128_encrypt                   4562	EXIST::FUNCTION:
+CRYPTO_cfb128_8_encrypt                 4563	EXIST::FUNCTION:
+OPENSSL_strcasecmp                      4564	EXIST::FUNCTION:
+OPENSSL_memcmp                          4565	EXIST::FUNCTION:
+OPENSSL_strncasecmp                     4566	EXIST::FUNCTION:
+OPENSSL_gmtime                          4567	EXIST::FUNCTION:
+OPENSSL_gmtime_adj                      4568	EXIST::FUNCTION:
diff --git a/openssl/util/mk1mf.pl b/openssl/util/mk1mf.pl
new file mode 100755
index 0000000..afe8c73
--- /dev/null
+++ b/openssl/util/mk1mf.pl
@@ -0,0 +1,1164 @@
+#!/usr/local/bin/perl
+# A bit of an evil hack but it post processes the file ../MINFO which
+# is generated by `make files` in the top directory.
+# This script outputs one mega makefile that has no shell stuff or any
+# funny stuff
+#
+
+$INSTALLTOP="/usr/local/ssl";
+$OPENSSLDIR="/usr/local/ssl";
+$OPTIONS="";
+$ssl_version="";
+$banner="\t\@echo Building OpenSSL";
+
+my $no_static_engine = 1;
+my $engines = "";
+my $otherlibs = "";
+local $zlib_opt = 0;	# 0 = no zlib, 1 = static, 2 = dynamic
+local $zlib_lib = "";
+local $perl_asm = 0;	# 1 to autobuild asm files from perl scripts
+
+# Options to import from top level Makefile
+
+my %mf_import = (
+	VERSION	       => \$ssl_version,
+	OPTIONS        => \$OPTIONS,
+	INSTALLTOP     => \$INSTALLTOP,
+	OPENSSLDIR     => \$OPENSSLDIR,
+	PLATFORM       => \$mf_platform,
+	CFLAG	       => \$mf_cflag,
+	DEPFLAG	       => \$mf_depflag,
+	CPUID_OBJ      => \$mf_cpuid_asm,
+	BN_ASM	       => \$mf_bn_asm,
+	DES_ENC	       => \$mf_des_asm,
+	AES_ENC        => \$mf_aes_asm,
+	BF_ENC	       => \$mf_bf_asm,
+	CAST_ENC       => \$mf_cast_asm,
+	RC4_ENC	       => \$mf_rc4_asm,
+	RC5_ENC        => \$mf_rc5_asm,
+	MD5_ASM_OBJ    => \$mf_md5_asm,
+	SHA1_ASM_OBJ   => \$mf_sha_asm,
+	RMD160_ASM_OBJ => \$mf_rmd_asm,
+	WP_ASM_OBJ     => \$mf_wp_asm,
+	CMLL_ENC       => \$mf_cm_asm
+);
+
+
+open(IN,"<Makefile") || die "unable to open Makefile!\n";
+while(<IN>) {
+    my ($mf_opt, $mf_ref);
+    while (($mf_opt, $mf_ref) = each %mf_import) {
+    	if (/^$mf_opt\s*=\s*(.*)$/) {
+	   $$mf_ref = $1;
+	}
+    }
+}
+close(IN);
+
+$debug = 1 if $mf_platform =~ /^debug-/;
+
+die "Makefile is not the toplevel Makefile!\n" if $ssl_version eq "";
+
+$infile="MINFO";
+
+%ops=(
+	"VC-WIN32",   "Microsoft Visual C++ [4-6] - Windows NT or 9X",
+	"VC-WIN64I",  "Microsoft C/C++ - Win64/IA-64",
+	"VC-WIN64A",  "Microsoft C/C++ - Win64/x64",
+	"VC-CE",   "Microsoft eMbedded Visual C++ 3.0 - Windows CE ONLY",
+	"VC-NT",   "Microsoft Visual C++ [4-6] - Windows NT ONLY",
+	"Mingw32", "GNU C++ - Windows NT or 9x",
+	"Mingw32-files", "Create files with DOS copy ...",
+	"BC-NT",   "Borland C++ 4.5 - Windows NT",
+	"linux-elf","Linux elf",
+	"ultrix-mips","DEC mips ultrix",
+	"FreeBSD","FreeBSD distribution",
+	"OS2-EMX", "EMX GCC OS/2",
+	"netware-clib", "CodeWarrior for NetWare - CLib - with WinSock Sockets",
+	"netware-clib-bsdsock", "CodeWarrior for NetWare - CLib - with BSD Sockets",
+	"netware-libc", "CodeWarrior for NetWare - LibC - with WinSock Sockets",
+	"netware-libc-bsdsock", "CodeWarrior for NetWare - LibC - with BSD Sockets",
+	"default","cc under unix",
+	"auto", "auto detect from top level Makefile"
+	);
+
+$platform="";
+my $xcflags="";
+foreach (@ARGV)
+	{
+	if (!&read_options && !defined($ops{$_}))
+		{
+		print STDERR "unknown option - $_\n";
+		print STDERR "usage: perl mk1mf.pl [options] [system]\n";
+		print STDERR "\nwhere [system] can be one of the following\n";
+		foreach $i (sort keys %ops)
+		{ printf STDERR "\t%-10s\t%s\n",$i,$ops{$i}; }
+		print STDERR <<"EOF";
+and [options] can be one of
+	no-md2 no-md4 no-md5 no-sha no-mdc2	- Skip this digest
+	no-ripemd
+	no-rc2 no-rc4 no-rc5 no-idea no-des     - Skip this symetric cipher
+	no-bf no-cast no-aes no-camellia no-seed
+	no-rsa no-dsa no-dh			- Skip this public key cipher
+	no-ssl2 no-ssl3				- Skip this version of SSL
+	just-ssl				- remove all non-ssl keys/digest
+	no-asm 					- No x86 asm
+	no-krb5					- No KRB5
+	no-ec					- No EC
+	no-ecdsa				- No ECDSA
+	no-ecdh					- No ECDH
+	no-engine				- No engine
+	no-hw					- No hw
+	nasm 					- Use NASM for x86 asm
+	nw-nasm					- Use NASM x86 asm for NetWare
+	nw-mwasm				- Use Metrowerks x86 asm for NetWare
+	gaswin					- Use GNU as with Mingw32
+	no-socks				- No socket code
+	no-err					- No error strings
+	dll/shlib				- Build shared libraries (MS)
+	debug					- Debug build
+        profile                                 - Profiling build
+	gcc					- Use Gcc (unix)
+
+Values that can be set
+TMP=tmpdir OUT=outdir SRC=srcdir BIN=binpath INC=header-outdir CC=C-compiler
+
+-L<ex_lib_path> -l<ex_lib>			- extra library flags (unix)
+-<ex_cc_flags>					- extra 'cc' flags,
+						  added (MS), or replace (unix)
+EOF
+		exit(1);
+		}
+	$platform=$_;
+	}
+foreach (grep(!/^$/, split(/ /, $OPTIONS)))
+	{
+	print STDERR "unknown option - $_\n" if !&read_options;
+	}
+
+$no_static_engine = 0 if (!$shlib);
+
+$no_mdc2=1 if ($no_des);
+
+$no_ssl3=1 if ($no_md5 || $no_sha);
+$no_ssl3=1 if ($no_rsa && $no_dh);
+
+$no_ssl2=1 if ($no_md5);
+$no_ssl2=1 if ($no_rsa);
+
+$out_def="out";
+$inc_def="outinc";
+$tmp_def="tmp";
+
+$perl="perl" unless defined $perl;
+$mkdir="-mkdir" unless defined $mkdir;
+
+($ssl,$crypto)=("ssl","crypto");
+$ranlib="echo ranlib";
+
+$cc=(defined($VARS{'CC'}))?$VARS{'CC'}:'cc';
+$src_dir=(defined($VARS{'SRC'}))?$VARS{'SRC'}:'.';
+$bin_dir=(defined($VARS{'BIN'}))?$VARS{'BIN'}:'';
+
+# $bin_dir.=$o causes a core dump on my sparc :-(
+
+
+$NT=0;
+
+push(@INC,"util/pl","pl");
+
+if ($platform eq "auto") {
+	$platform = $mf_platform;
+	print STDERR "Imported platform $mf_platform\n";
+}
+
+if (($platform =~ /VC-(.+)/))
+	{
+	$FLAVOR=$1;
+	$NT = 1 if $1 eq "NT";
+	require 'VC-32.pl';
+	}
+elsif ($platform eq "Mingw32")
+	{
+	require 'Mingw32.pl';
+	}
+elsif ($platform eq "Mingw32-files")
+	{
+	require 'Mingw32f.pl';
+	}
+elsif ($platform eq "BC-NT")
+	{
+	$bc=1;
+	require 'BC-32.pl';
+	}
+elsif ($platform eq "FreeBSD")
+	{
+	require 'unix.pl';
+	$cflags='-DTERMIO -D_ANSI_SOURCE -O2 -fomit-frame-pointer';
+	}
+elsif ($platform eq "linux-elf")
+	{
+	require "unix.pl";
+	require "linux.pl";
+	$unix=1;
+	}
+elsif ($platform eq "ultrix-mips")
+	{
+	require "unix.pl";
+	require "ultrix.pl";
+	$unix=1;
+	}
+elsif ($platform eq "OS2-EMX")
+	{
+	$wc=1;
+	require 'OS2-EMX.pl';
+	}
+elsif (($platform eq "netware-clib") || ($platform eq "netware-libc") ||
+       ($platform eq "netware-clib-bsdsock") || ($platform eq "netware-libc-bsdsock"))
+	{
+	$LIBC=1 if $platform eq "netware-libc" || $platform eq "netware-libc-bsdsock";
+	$BSDSOCK=1 if ($platform eq "netware-libc-bsdsock") || ($platform eq "netware-clib-bsdsock");
+	require 'netware.pl';
+	}
+else
+	{
+	require "unix.pl";
+
+	$unix=1;
+	$cflags.=' -DTERMIO';
+	}
+
+$out_dir=(defined($VARS{'OUT'}))?$VARS{'OUT'}:$out_def.($debug?".dbg":"");
+$tmp_dir=(defined($VARS{'TMP'}))?$VARS{'TMP'}:$tmp_def.($debug?".dbg":"");
+$inc_dir=(defined($VARS{'INC'}))?$VARS{'INC'}:$inc_def;
+
+$bin_dir=$bin_dir.$o unless ((substr($bin_dir,-1,1) eq $o) || ($bin_dir eq ''));
+
+$cflags= "$xcflags$cflags" if $xcflags ne "";
+
+$cflags.=" -DOPENSSL_NO_IDEA" if $no_idea;
+$cflags.=" -DOPENSSL_NO_AES"  if $no_aes;
+$cflags.=" -DOPENSSL_NO_CAMELLIA"  if $no_camellia;
+$cflags.=" -DOPENSSL_NO_SEED" if $no_seed;
+$cflags.=" -DOPENSSL_NO_RC2"  if $no_rc2;
+$cflags.=" -DOPENSSL_NO_RC4"  if $no_rc4;
+$cflags.=" -DOPENSSL_NO_RC5"  if $no_rc5;
+$cflags.=" -DOPENSSL_NO_MD2"  if $no_md2;
+$cflags.=" -DOPENSSL_NO_MD4"  if $no_md4;
+$cflags.=" -DOPENSSL_NO_MD5"  if $no_md5;
+$cflags.=" -DOPENSSL_NO_SHA"  if $no_sha;
+$cflags.=" -DOPENSSL_NO_SHA1" if $no_sha1;
+$cflags.=" -DOPENSSL_NO_RIPEMD" if $no_ripemd;
+$cflags.=" -DOPENSSL_NO_MDC2" if $no_mdc2;
+$cflags.=" -DOPENSSL_NO_BF"  if $no_bf;
+$cflags.=" -DOPENSSL_NO_CAST" if $no_cast;
+$cflags.=" -DOPENSSL_NO_DES"  if $no_des;
+$cflags.=" -DOPENSSL_NO_RSA"  if $no_rsa;
+$cflags.=" -DOPENSSL_NO_DSA"  if $no_dsa;
+$cflags.=" -DOPENSSL_NO_DH"   if $no_dh;
+$cflags.=" -DOPENSSL_NO_WHIRLPOOL"   if $no_whirlpool;
+$cflags.=" -DOPENSSL_NO_SOCK" if $no_sock;
+$cflags.=" -DOPENSSL_NO_SSL2" if $no_ssl2;
+$cflags.=" -DOPENSSL_NO_SSL3" if $no_ssl3;
+$cflags.=" -DOPENSSL_NO_TLSEXT" if $no_tlsext;
+$cflags.=" -DOPENSSL_NO_CMS" if $no_cms;
+$cflags.=" -DOPENSSL_NO_ERR"  if $no_err;
+$cflags.=" -DOPENSSL_NO_KRB5" if $no_krb5;
+$cflags.=" -DOPENSSL_NO_EC"   if $no_ec;
+$cflags.=" -DOPENSSL_NO_ECDSA" if $no_ecdsa;
+$cflags.=" -DOPENSSL_NO_ECDH" if $no_ecdh;
+$cflags.=" -DOPENSSL_NO_GOST" if $no_gost;
+$cflags.=" -DOPENSSL_NO_ENGINE"   if $no_engine;
+$cflags.=" -DOPENSSL_NO_HW"   if $no_hw;
+$cflags.=" -DOPENSSL_NO_JPAKE"    if $no_jpake;
+$cflags.= " -DZLIB" if $zlib_opt;
+$cflags.= " -DZLIB_SHARED" if $zlib_opt == 2;
+
+if ($no_static_engine)
+	{
+	$cflags .= " -DOPENSSL_NO_STATIC_ENGINE";
+	}
+else
+	{
+	$cflags .= " -DOPENSSL_NO_DYNAMIC_ENGINE";
+	}
+
+#$cflags.=" -DRSAref"  if $rsaref ne "";
+
+## if ($unix)
+##	{ $cflags="$c_flags" if ($c_flags ne ""); }
+##else
+	{ $cflags="$c_flags$cflags" if ($c_flags ne ""); }
+
+$ex_libs="$l_flags$ex_libs" if ($l_flags ne "");
+
+
+%shlib_ex_cflags=("SSL" => " -DOPENSSL_BUILD_SHLIBSSL",
+		  "CRYPTO" => " -DOPENSSL_BUILD_SHLIBCRYPTO");
+
+if ($msdos)
+	{
+	$banner ="\t\@echo Make sure you have run 'perl Configure $platform' in the\n";
+	$banner.="\t\@echo top level directory, if you don't have perl, you will\n";
+	$banner.="\t\@echo need to probably edit crypto/bn/bn.h, check the\n";
+	$banner.="\t\@echo documentation for details.\n";
+	}
+
+# have to do this to allow $(CC) under unix
+$link="$bin_dir$link" if ($link !~ /^\$/);
+
+$INSTALLTOP =~ s|/|$o|g;
+$OPENSSLDIR =~ s|/|$o|g;
+
+#############################################
+# We parse in input file and 'store' info for later printing.
+open(IN,"<$infile") || die "unable to open $infile:$!\n";
+$_=<IN>;
+for (;;)
+	{
+	chop;
+
+	($key,$val)=/^([^=]+)=(.*)/;
+	if ($key eq "RELATIVE_DIRECTORY")
+		{
+		if ($lib ne "")
+			{
+			$uc=$lib;
+			$uc =~ s/^lib(.*)\.a/$1/;
+			$uc =~ tr/a-z/A-Z/;
+			$lib_nam{$uc}=$uc;
+			$lib_obj{$uc}.=$libobj." ";
+			}
+		last if ($val eq "FINISHED");
+		$lib="";
+		$libobj="";
+		$dir=$val;
+		}
+
+	if ($key eq "KRB5_INCLUDES")
+		{ $cflags .= " $val";}
+
+	if ($key eq "ZLIB_INCLUDE")
+		{ $cflags .= " $val" if $val ne "";}
+
+	if ($key eq "LIBZLIB")
+		{ $zlib_lib = "$val" if $val ne "";}
+
+	if ($key eq "LIBKRB5")
+		{ $ex_libs .= " $val" if $val ne "";}
+
+	if ($key eq "TEST")
+		{ $test.=&var_add($dir,$val, 0); }
+
+	if (($key eq "PROGS") || ($key eq "E_OBJ"))
+		{ $e_exe.=&var_add($dir,$val, 0); }
+
+	if ($key eq "LIB")
+		{
+		$lib=$val;
+		$lib =~ s/^.*\/([^\/]+)$/$1/;
+		}
+	if ($key eq "LIBNAME" && $no_static_engine)
+		{
+		$lib=$val;
+		$lib =~ s/^.*\/([^\/]+)$/$1/;
+		$otherlibs .= " $lib";
+		}
+
+	if ($key eq "EXHEADER")
+		{ $exheader.=&var_add($dir,$val, 1); }
+
+	if ($key eq "HEADER")
+		{ $header.=&var_add($dir,$val, 1); }
+
+	if ($key eq "LIBOBJ" && ($dir ne "engines" || !$no_static_engine))
+		{ $libobj=&var_add($dir,$val, 0); }
+	if ($key eq "LIBNAMES" && $dir eq "engines" && $no_static_engine)
+ 		{ $engines.=$val }
+
+	if (!($_=<IN>))
+		{ $_="RELATIVE_DIRECTORY=FINISHED\n"; }
+	}
+close(IN);
+
+if ($shlib)
+	{
+	$extra_install= <<"EOF";
+	\$(CP) \"\$(O_SSL)\" \"\$(INSTALLTOP)${o}bin\"
+	\$(CP) \"\$(O_CRYPTO)\" \"\$(INSTALLTOP)${o}bin\"
+	\$(CP) \"\$(L_SSL)\" \"\$(INSTALLTOP)${o}lib\"
+	\$(CP) \"\$(L_CRYPTO)\" \"\$(INSTALLTOP)${o}lib\"
+EOF
+	if ($no_static_engine)
+		{
+		$extra_install .= <<"EOF"
+	\$(MKDIR) \"\$(INSTALLTOP)${o}lib${o}engines\"
+	\$(CP) \"\$(E_SHLIB)\" \"\$(INSTALLTOP)${o}lib${o}engines\"
+EOF
+		}
+	}
+else
+	{
+	$extra_install= <<"EOF";
+	\$(CP) \"\$(O_SSL)\" \"\$(INSTALLTOP)${o}lib\"
+	\$(CP) \"\$(O_CRYPTO)\" \"\$(INSTALLTOP)${o}lib\"
+EOF
+	$ex_libs .= " $zlib_lib" if $zlib_opt == 1;
+	}
+
+$defs= <<"EOF";
+# This makefile has been automatically generated from the OpenSSL distribution.
+# This single makefile will build the complete OpenSSL distribution and
+# by default leave the 'intertesting' output files in .${o}out and the stuff
+# that needs deleting in .${o}tmp.
+# The file was generated by running 'make makefile.one', which
+# does a 'make files', which writes all the environment variables from all
+# the makefiles to the file call MINFO.  This file is used by
+# util${o}mk1mf.pl to generate makefile.one.
+# The 'makefile per directory' system suites me when developing this
+# library and also so I can 'distribute' indervidual library sections.
+# The one monster makefile better suits building in non-unix
+# environments.
+
+EOF
+
+$defs .= $preamble if defined $preamble;
+
+$defs.= <<"EOF";
+INSTALLTOP=$INSTALLTOP
+OPENSSLDIR=$OPENSSLDIR
+
+# Set your compiler options
+PLATFORM=$platform
+CC=$bin_dir${cc}
+CFLAG=$cflags
+APP_CFLAG=$app_cflag
+LIB_CFLAG=$lib_cflag
+SHLIB_CFLAG=$shl_cflag
+APP_EX_OBJ=$app_ex_obj
+SHLIB_EX_OBJ=$shlib_ex_obj
+# add extra libraries to this define, for solaris -lsocket -lnsl would
+# be added
+EX_LIBS=$ex_libs
+
+# The OpenSSL directory
+SRC_D=$src_dir
+
+LINK=$link
+LFLAGS=$lflags
+RSC=$rsc
+
+# The output directory for everything intersting
+OUT_D=$out_dir
+# The output directory for all the temporary muck
+TMP_D=$tmp_dir
+# The output directory for the header files
+INC_D=$inc_dir
+INCO_D=$inc_dir${o}openssl
+
+PERL=$perl
+CP=$cp
+RM=$rm
+RANLIB=$ranlib
+MKDIR=$mkdir
+MKLIB=$bin_dir$mklib
+MLFLAGS=$mlflags
+ASM=$bin_dir$asm
+
+######################################################
+# You should not need to touch anything below this point
+######################################################
+
+E_EXE=openssl
+SSL=$ssl
+CRYPTO=$crypto
+
+# BIN_D  - Binary output directory
+# TEST_D - Binary test file output directory
+# LIB_D  - library output directory
+# ENG_D  - dynamic engine output directory
+# Note: if you change these point to different directories then uncomment out
+# the lines around the 'NB' comment below.
+# 
+BIN_D=\$(OUT_D)
+TEST_D=\$(OUT_D)
+LIB_D=\$(OUT_D)
+ENG_D=\$(OUT_D)
+
+# INCL_D - local library directory
+# OBJ_D  - temp object file directory
+OBJ_D=\$(TMP_D)
+INCL_D=\$(TMP_D)
+
+O_SSL=     \$(LIB_D)$o$plib\$(SSL)$shlibp
+O_CRYPTO=  \$(LIB_D)$o$plib\$(CRYPTO)$shlibp
+SO_SSL=    $plib\$(SSL)$so_shlibp
+SO_CRYPTO= $plib\$(CRYPTO)$so_shlibp
+L_SSL=     \$(LIB_D)$o$plib\$(SSL)$libp
+L_CRYPTO=  \$(LIB_D)$o$plib\$(CRYPTO)$libp
+
+L_LIBS= \$(L_SSL) \$(L_CRYPTO)
+
+######################################################
+# Don't touch anything below this point
+######################################################
+
+INC=-I\$(INC_D) -I\$(INCL_D)
+APP_CFLAGS=\$(INC) \$(CFLAG) \$(APP_CFLAG)
+LIB_CFLAGS=\$(INC) \$(CFLAG) \$(LIB_CFLAG)
+SHLIB_CFLAGS=\$(INC) \$(CFLAG) \$(LIB_CFLAG) \$(SHLIB_CFLAG)
+LIBS_DEP=\$(O_CRYPTO) \$(O_SSL)
+
+#############################################
+EOF
+
+$rules=<<"EOF";
+all: banner \$(TMP_D) \$(BIN_D) \$(TEST_D) \$(LIB_D) \$(INCO_D) headers lib exe
+
+banner:
+$banner
+
+\$(TMP_D):
+	\$(MKDIR) \"\$(TMP_D)\"
+# NB: uncomment out these lines if BIN_D, TEST_D and LIB_D are different
+#\$(BIN_D):
+#	\$(MKDIR) \$(BIN_D)
+#
+#\$(TEST_D):
+#	\$(MKDIR) \$(TEST_D)
+
+\$(LIB_D):
+	\$(MKDIR) \"\$(LIB_D)\"
+
+\$(INCO_D): \$(INC_D)
+	\$(MKDIR) \"\$(INCO_D)\"
+
+\$(INC_D):
+	\$(MKDIR) \"\$(INC_D)\"
+
+headers: \$(HEADER) \$(EXHEADER)
+	@
+
+lib: \$(LIBS_DEP) \$(E_SHLIB)
+
+exe: \$(T_EXE) \$(BIN_D)$o\$(E_EXE)$exep
+
+install: all
+	\$(MKDIR) \"\$(INSTALLTOP)\"
+	\$(MKDIR) \"\$(INSTALLTOP)${o}bin\"
+	\$(MKDIR) \"\$(INSTALLTOP)${o}include\"
+	\$(MKDIR) \"\$(INSTALLTOP)${o}include${o}openssl\"
+	\$(MKDIR) \"\$(INSTALLTOP)${o}lib\"
+	\$(CP) \"\$(INCO_D)${o}*.\[ch\]\" \"\$(INSTALLTOP)${o}include${o}openssl\"
+	\$(CP) \"\$(BIN_D)$o\$(E_EXE)$exep \$(INSTALLTOP)${o}bin\"
+	\$(MKDIR) \"\$(OPENSSLDIR)\"
+	\$(CP) apps${o}openssl.cnf \"\$(OPENSSLDIR)\"
+$extra_install
+
+
+test: \$(T_EXE)
+	cd \$(BIN_D)
+	..${o}ms${o}test
+
+clean:
+	\$(RM) \$(TMP_D)$o*.*
+
+vclean:
+	\$(RM) \$(TMP_D)$o*.*
+	\$(RM) \$(OUT_D)$o*.*
+
+EOF
+    
+my $platform_cpp_symbol = "MK1MF_PLATFORM_$platform";
+$platform_cpp_symbol =~ s/-/_/g;
+if (open(IN,"crypto/buildinf.h"))
+	{
+	# Remove entry for this platform in existing file buildinf.h.
+
+	my $old_buildinf_h = "";
+	while (<IN>)
+		{
+		if (/^\#ifdef $platform_cpp_symbol$/)
+			{
+			while (<IN>) { last if (/^\#endif/); }
+			}
+		else
+			{
+			$old_buildinf_h .= $_;
+			}
+		}
+	close(IN);
+
+	open(OUT,">crypto/buildinf.h") || die "Can't open buildinf.h";
+	print OUT $old_buildinf_h;
+	close(OUT);
+	}
+
+open (OUT,">>crypto/buildinf.h") || die "Can't open buildinf.h";
+printf OUT <<EOF;
+#ifdef $platform_cpp_symbol
+  /* auto-generated/updated by util/mk1mf.pl for crypto/cversion.c */
+  #define CFLAGS "$cc $cflags"
+  #define PLATFORM "$platform"
+EOF
+printf OUT "  #define DATE \"%s\"\n", scalar gmtime();
+printf OUT "#endif\n";
+close(OUT);
+
+# Strip of trailing ' '
+foreach (keys %lib_obj) { $lib_obj{$_}=&clean_up_ws($lib_obj{$_}); }
+$test=&clean_up_ws($test);
+$e_exe=&clean_up_ws($e_exe);
+$exheader=&clean_up_ws($exheader);
+$header=&clean_up_ws($header);
+
+# First we strip the exheaders from the headers list
+foreach (split(/\s+/,$exheader)){ $h{$_}=1; }
+foreach (split(/\s+/,$header))	{ $h.=$_." " unless $h{$_}; }
+chop($h); $header=$h;
+
+$defs.=&do_defs("HEADER",$header,"\$(INCL_D)","");
+$rules.=&do_copy_rule("\$(INCL_D)",$header,"");
+
+$defs.=&do_defs("EXHEADER",$exheader,"\$(INCO_D)","");
+$rules.=&do_copy_rule("\$(INCO_D)",$exheader,"");
+
+$defs.=&do_defs("T_OBJ",$test,"\$(OBJ_D)",$obj);
+$rules.=&do_compile_rule("\$(OBJ_D)",$test,"\$(APP_CFLAGS)");
+
+$defs.=&do_defs("E_OBJ",$e_exe,"\$(OBJ_D)",$obj);
+$rules.=&do_compile_rule("\$(OBJ_D)",$e_exe,'-DMONOLITH $(APP_CFLAGS)');
+
+foreach (values %lib_nam)
+	{
+	$lib_obj=$lib_obj{$_};
+	local($slib)=$shlib;
+
+	if (($_ eq "SSL") && $no_ssl2 && $no_ssl3)
+		{
+		$rules.="\$(O_SSL):\n\n"; 
+		next;
+		}
+
+	$defs.=&do_defs(${_}."OBJ",$lib_obj,"\$(OBJ_D)",$obj);
+	$lib=($slib)?" \$(SHLIB_CFLAGS)".$shlib_ex_cflags{$_}:" \$(LIB_CFLAGS)";
+	$rules.=&do_compile_rule("\$(OBJ_D)",$lib_obj{$_},$lib);
+	}
+
+# hack to add version info on MSVC
+if (($platform eq "VC-WIN32") || ($platform eq "VC-WIN64A")
+	|| ($platform eq "VC-WIN64I") || ($platform eq "VC-NT")) {
+    $rules.= <<"EOF";
+\$(OBJ_D)\\\$(CRYPTO).res: ms\\version32.rc
+	\$(RSC) /fo"\$(OBJ_D)\\\$(CRYPTO).res" /d CRYPTO ms\\version32.rc
+
+\$(OBJ_D)\\\$(SSL).res: ms\\version32.rc
+	\$(RSC) /fo"\$(OBJ_D)\\\$(SSL).res" /d SSL ms\\version32.rc
+
+EOF
+}
+
+$defs.=&do_defs("T_EXE",$test,"\$(TEST_D)",$exep);
+foreach (split(/\s+/,$test))
+	{
+	$t=&bname($_);
+	$tt="\$(OBJ_D)${o}$t${obj}";
+	$rules.=&do_link_rule("\$(TEST_D)$o$t$exep",$tt,"\$(LIBS_DEP)","\$(L_LIBS) \$(EX_LIBS)");
+	}
+
+$defs.=&do_defs("E_SHLIB",$engines . $otherlibs,"\$(ENG_D)",$shlibp);
+
+foreach (split(/\s+/,$engines))
+	{
+	$rules.=&do_compile_rule("\$(OBJ_D)","engines${o}e_$_",$lib);
+	$rules.= &do_lib_rule("\$(OBJ_D)${o}e_${_}.obj","\$(ENG_D)$o$_$shlibp","",$shlib,"");
+	}
+
+
+
+$rules.= &do_lib_rule("\$(SSLOBJ)","\$(O_SSL)",$ssl,$shlib,"\$(SO_SSL)");
+$rules.= &do_lib_rule("\$(CRYPTOOBJ)","\$(O_CRYPTO)",$crypto,$shlib,"\$(SO_CRYPTO)");
+
+foreach (split(" ",$otherlibs))
+	{
+	my $uc = $_;
+	$uc =~ tr /a-z/A-Z/;	
+	$rules.= &do_lib_rule("\$(${uc}OBJ)","\$(ENG_D)$o$_$shlibp", "", $shlib, "");
+
+	}
+
+$rules.=&do_link_rule("\$(BIN_D)$o\$(E_EXE)$exep","\$(E_OBJ)","\$(LIBS_DEP)","\$(L_LIBS) \$(EX_LIBS)");
+
+print $defs;
+
+if ($platform eq "linux-elf") {
+    print <<"EOF";
+# Generate perlasm output files
+%.cpp:
+	(cd \$(\@D)/..; PERL=perl make -f Makefile asm/\$(\@F))
+EOF
+}
+print "###################################################################\n";
+print $rules;
+
+###############################################
+# strip off any trailing .[och] and append the relative directory
+# also remembering to do nothing if we are in one of the dropped
+# directories
+sub var_add
+	{
+	local($dir,$val,$keepext)=@_;
+	local(@a,$_,$ret);
+
+	return("") if $no_engine && $dir =~ /\/engine/;
+	return("") if $no_hw   && $dir =~ /\/hw/;
+	return("") if $no_idea && $dir =~ /\/idea/;
+	return("") if $no_aes  && $dir =~ /\/aes/;
+	return("") if $no_camellia  && $dir =~ /\/camellia/;
+	return("") if $no_seed && $dir =~ /\/seed/;
+	return("") if $no_rc2  && $dir =~ /\/rc2/;
+	return("") if $no_rc4  && $dir =~ /\/rc4/;
+	return("") if $no_rc5  && $dir =~ /\/rc5/;
+	return("") if $no_rsa  && $dir =~ /\/rsa/;
+	return("") if $no_rsa  && $dir =~ /^rsaref/;
+	return("") if $no_dsa  && $dir =~ /\/dsa/;
+	return("") if $no_dh   && $dir =~ /\/dh/;
+	return("") if $no_ec   && $dir =~ /\/ec/;
+	return("") if $no_gost   && $dir =~ /\/ccgost/;
+	return("") if $no_cms  && $dir =~ /\/cms/;
+	return("") if $no_jpake  && $dir =~ /\/jpake/;
+	if ($no_des && $dir =~ /\/des/)
+		{
+		if ($val =~ /read_pwd/)
+			{ return("$dir/read_pwd "); }
+		else
+			{ return(""); }
+		}
+	return("") if $no_mdc2 && $dir =~ /\/mdc2/;
+	return("") if $no_sock && $dir =~ /\/proxy/;
+	return("") if $no_bf   && $dir =~ /\/bf/;
+	return("") if $no_cast && $dir =~ /\/cast/;
+	return("") if $no_whirlpool && $dir =~ /\/whrlpool/;
+
+	$val =~ s/^\s*(.*)\s*$/$1/;
+	@a=split(/\s+/,$val);
+	grep(s/\.[och]$//,@a) unless $keepext;
+
+	@a=grep(!/^e_.*_3d$/,@a) if $no_des;
+	@a=grep(!/^e_.*_d$/,@a) if $no_des;
+	@a=grep(!/^e_.*_ae$/,@a) if $no_idea;
+	@a=grep(!/^e_.*_i$/,@a) if $no_aes;
+	@a=grep(!/^e_.*_r2$/,@a) if $no_rc2;
+	@a=grep(!/^e_.*_r5$/,@a) if $no_rc5;
+	@a=grep(!/^e_.*_bf$/,@a) if $no_bf;
+	@a=grep(!/^e_.*_c$/,@a) if $no_cast;
+	@a=grep(!/^e_rc4$/,@a) if $no_rc4;
+	@a=grep(!/^e_camellia$/,@a) if $no_camellia;
+	@a=grep(!/^e_seed$/,@a) if $no_seed;
+
+	#@a=grep(!/(^s2_)|(^s23_)/,@a) if $no_ssl2;
+	#@a=grep(!/(^s3_)|(^s23_)/,@a) if $no_ssl3;
+
+	@a=grep(!/(_sock$)|(_acpt$)|(_conn$)|(^pxy_)/,@a) if $no_sock;
+
+	@a=grep(!/(^md2)|(_md2$)/,@a) if $no_md2;
+	@a=grep(!/(^md4)|(_md4$)/,@a) if $no_md4;
+	@a=grep(!/(^md5)|(_md5$)/,@a) if $no_md5;
+	@a=grep(!/(rmd)|(ripemd)/,@a) if $no_ripemd;
+
+	@a=grep(!/(^d2i_r_)|(^i2d_r_)/,@a) if $no_rsa;
+	@a=grep(!/(^p_open$)|(^p_seal$)/,@a) if $no_rsa;
+	@a=grep(!/(^pem_seal$)/,@a) if $no_rsa;
+
+	@a=grep(!/(m_dss$)|(m_dss1$)/,@a) if $no_dsa;
+	@a=grep(!/(^d2i_s_)|(^i2d_s_)|(_dsap$)/,@a) if $no_dsa;
+
+	@a=grep(!/^n_pkey$/,@a) if $no_rsa || $no_rc4;
+
+	@a=grep(!/_dhp$/,@a) if $no_dh;
+
+	@a=grep(!/(^sha[^1])|(_sha$)|(m_dss$)/,@a) if $no_sha;
+	@a=grep(!/(^sha1)|(_sha1$)|(m_dss1$)/,@a) if $no_sha1;
+	@a=grep(!/_mdc2$/,@a) if $no_mdc2;
+
+	@a=grep(!/^engine$/,@a) if $no_engine;
+	@a=grep(!/^hw$/,@a) if $no_hw;
+	@a=grep(!/(^rsa$)|(^genrsa$)/,@a) if $no_rsa;
+	@a=grep(!/(^dsa$)|(^gendsa$)|(^dsaparam$)/,@a) if $no_dsa;
+	@a=grep(!/^gendsa$/,@a) if $no_sha1;
+	@a=grep(!/(^dh$)|(^gendh$)/,@a) if $no_dh;
+
+	@a=grep(!/(^dh)|(_sha1$)|(m_dss1$)/,@a) if $no_sha1;
+
+	grep($_="$dir/$_",@a);
+	@a=grep(!/(^|\/)s_/,@a) if $no_sock;
+	@a=grep(!/(^|\/)bio_sock/,@a) if $no_sock;
+	$ret=join(' ',@a)." ";
+	return($ret);
+	}
+
+# change things so that each 'token' is only separated by one space
+sub clean_up_ws
+	{
+	local($w)=@_;
+
+	$w =~ s/^\s*(.*)\s*$/$1/;
+	$w =~ s/\s+/ /g;
+	return($w);
+	}
+
+sub do_defs
+	{
+	local($var,$files,$location,$postfix)=@_;
+	local($_,$ret,$pf);
+	local(*OUT,$tmp,$t);
+
+	$files =~ s/\//$o/g if $o ne '/';
+	$ret="$var="; 
+	$n=1;
+	$Vars{$var}.="";
+	foreach (split(/ /,$files))
+		{
+		$orig=$_;
+		$_=&bname($_) unless /^\$/;
+		if ($n++ == 2)
+			{
+			$n=0;
+			$ret.="\\\n\t";
+			}
+		if (($_ =~ /bss_file/) && ($postfix eq ".h"))
+			{ $pf=".c"; }
+		else	{ $pf=$postfix; }
+		if ($_ =~ /BN_ASM/)	{ $t="$_ "; }
+		elsif ($_ =~ /BNCO_ASM/){ $t="$_ "; }
+		elsif ($_ =~ /AES_ASM/){ $t="$_ "; }
+		elsif ($_ =~ /DES_ENC/)	{ $t="$_ "; }
+		elsif ($_ =~ /BF_ENC/)	{ $t="$_ "; }
+		elsif ($_ =~ /CAST_ENC/){ $t="$_ "; }
+		elsif ($_ =~ /RC4_ENC/)	{ $t="$_ "; }
+		elsif ($_ =~ /RC5_ENC/)	{ $t="$_ "; }
+		elsif ($_ =~ /MD5_ASM/)	{ $t="$_ "; }
+		elsif ($_ =~ /SHA1_ASM/){ $t="$_ "; }
+		elsif ($_ =~ /RMD160_ASM/){ $t="$_ "; }
+		elsif ($_ =~ /WHIRLPOOL_ASM/){ $t="$_ "; }
+		elsif ($_ =~ /CPUID_ASM/){ $t="$_ "; }
+		else	{ $t="$location${o}$_$pf "; }
+
+		$Vars{$var}.="$t ";
+		$ret.=$t;
+		}
+	# hack to add version info on MSVC
+	if ($shlib && (($platform eq "VC-WIN32") || ($platfrom eq "VC-WIN64I") || ($platform eq "VC-WIN64A") || ($platform eq "VC-NT")))
+		{
+		if ($var eq "CRYPTOOBJ")
+			{ $ret.="\$(OBJ_D)\\\$(CRYPTO).res "; }
+		elsif ($var eq "SSLOBJ")
+			{ $ret.="\$(OBJ_D)\\\$(SSL).res "; }
+		}
+	chomp($ret);
+	$ret.="\n\n";
+	return($ret);
+	}
+
+# return the name with the leading path removed
+sub bname
+	{
+	local($ret)=@_;
+	$ret =~ s/^.*[\\\/]([^\\\/]+)$/$1/;
+	return($ret);
+	}
+
+# return the leading path
+sub dname
+	{
+	my $ret=shift;
+	$ret =~ s/(^.*)[\\\/][^\\\/]+$/$1/;
+	return($ret);
+	}
+
+##############################################################
+# do a rule for each file that says 'compile' to new direcory
+# compile the files in '$files' into $to
+sub do_compile_rule
+	{
+	local($to,$files,$ex)=@_;
+	local($ret,$_,$n,$d,$s);
+
+	$files =~ s/\//$o/g if $o ne '/';
+	foreach (split(/\s+/,$files))
+		{
+		$n=&bname($_);
+		$d=&dname($_);
+		if (-f "${_}.c")
+			{
+			$ret.=&cc_compile_target("$to${o}$n$obj","${_}.c",$ex)
+			}
+		elsif (-f ($s="${d}${o}asm${o}${n}.pl") or
+		       ($s=~s/sha256/sha512/ and -f $s) or
+		       -f ($s="${d}${o}${n}.pl"))
+			{
+			$ret.=&perlasm_compile_target("$to${o}$n$obj",$s,$n);
+			}
+		elsif (-f ($s="${d}${o}asm${o}${n}.S") or
+		       -f ($s="${d}${o}${n}.S"))
+			{
+			$ret.=&Sasm_compile_target("$to${o}$n$obj",$s,$n);
+			}
+		else	{ die "no rule for $_"; }
+		}
+	return($ret);
+	}
+
+##############################################################
+# do a rule for each file that says 'compile' to new direcory
+sub perlasm_compile_target
+	{
+	my($target,$source,$bname)=@_;
+	my($ret);
+
+	$bname =~ s/(.*)\.[^\.]$/$1/;
+	$ret ="\$(TMP_D)$o$bname.asm: $source\n";
+	$ret.="\t\$(PERL) $source $asmtype \$(CFLAG) >\$\@\n\n";
+	$ret.="$target: \$(TMP_D)$o$bname.asm\n";
+	$ret.="\t\$(ASM) $afile\$\@ \$(TMP_D)$o$bname.asm\n\n";
+	return($ret);
+	}
+
+sub Sasm_compile_target
+	{
+	my($target,$source,$bname)=@_;
+	my($ret);
+
+	$bname =~ s/(.*)\.[^\.]$/$1/;
+	$ret ="\$(TMP_D)$o$bname.asm: $source\n";
+	$ret.="\t\$(CC) -E \$(CFLAG) $source >\$\@\n\n";
+	$ret.="$target: \$(TMP_D)$o$bname.asm\n";
+	$ret.="\t\$(ASM) $afile\$\@ \$(TMP_D)$o$bname.asm\n\n";
+	return($ret);
+	}
+
+sub cc_compile_target
+	{
+	local($target,$source,$ex_flags)=@_;
+	local($ret);
+	
+	$ex_flags.=" -DMK1MF_BUILD -D$platform_cpp_symbol" if ($source =~ /cversion/);
+	$target =~ s/\//$o/g if $o ne "/";
+	$source =~ s/\//$o/g if $o ne "/";
+	$ret ="$target: \$(SRC_D)$o$source\n\t";
+	$ret.="\$(CC) ${ofile}$target $ex_flags -c \$(SRC_D)$o$source\n\n";
+	return($ret);
+	}
+
+##############################################################
+sub do_asm_rule
+	{
+	local($target,$src)=@_;
+	local($ret,@s,@t,$i);
+
+	$target =~ s/\//$o/g if $o ne "/";
+	$src =~ s/\//$o/g if $o ne "/";
+
+	@t=split(/\s+/,$target);
+	@s=split(/\s+/,$src);
+
+
+	for ($i=0; $i<=$#s; $i++)
+		{
+		my $objfile = $t[$i];
+		my $srcfile = $s[$i];
+
+		if ($perl_asm == 1)
+			{
+			my $plasm = $objfile;
+			$plasm =~ s/${obj}/.pl/;
+			$ret.="$srcfile: $plasm\n";
+			$ret.="\t\$(PERL) $plasm $asmtype \$(CFLAG) >$srcfile\n\n";
+			}
+
+		$ret.="$objfile: $srcfile\n";
+		$ret.="\t\$(ASM) $afile$objfile \$(SRC_D)$o$srcfile\n\n";
+		}
+	return($ret);
+	}
+
+sub do_shlib_rule
+	{
+	local($n,$def)=@_;
+	local($ret,$nn);
+	local($t);
+
+	($nn=$n) =~ tr/a-z/A-Z/;
+	$ret.="$n.dll: \$(${nn}OBJ)\n";
+	if ($vc && $w32)
+		{
+		$ret.="\t\$(MKSHLIB) $efile$n.dll $def @<<\n  \$(${nn}OBJ_F)\n<<\n";
+		}
+	$ret.="\n";
+	return($ret);
+	}
+
+# do a rule for each file that says 'copy' to new direcory on change
+sub do_copy_rule
+	{
+	local($to,$files,$p)=@_;
+	local($ret,$_,$n,$pp);
+	
+	$files =~ s/\//$o/g if $o ne '/';
+	foreach (split(/\s+/,$files))
+		{
+		$n=&bname($_);
+		if ($n =~ /bss_file/)
+			{ $pp=".c"; }
+		else	{ $pp=$p; }
+		$ret.="$to${o}$n$pp: \$(SRC_D)$o$_$pp\n\t\$(CP) \"\$(SRC_D)$o$_$pp\" \"$to${o}$n$pp\"\n\n";
+		}
+	return($ret);
+	}
+
+sub read_options
+	{
+	# Many options are handled in a similar way. In particular
+	# no-xxx sets zero or more scalars to 1.
+	# Process these using a hash containing the option name and
+	# reference to the scalars to set.
+
+	my %valid_options = (
+		"no-rc2" => \$no_rc2,
+		"no-rc4" => \$no_rc4,
+		"no-rc5" => \$no_rc5,
+		"no-idea" => \$no_idea,
+		"no-aes" => \$no_aes,
+		"no-camellia" => \$no_camellia,
+		"no-seed" => \$no_seed,
+		"no-des" => \$no_des,
+		"no-bf" => \$no_bf,
+		"no-cast" => \$no_cast,
+		"no-md2" => \$no_md2,
+		"no-md4" => \$no_md4,
+		"no-md5" => \$no_md5,
+		"no-sha" => \$no_sha,
+		"no-sha1" => \$no_sha1,
+		"no-ripemd" => \$no_ripemd,
+		"no-mdc2" => \$no_mdc2,
+		"no-whirlpool" => \$no_whirlpool,
+		"no-patents" => 
+			[\$no_rc2, \$no_rc4, \$no_rc5, \$no_idea, \$no_rsa],
+		"no-rsa" => \$no_rsa,
+		"no-dsa" => \$no_dsa,
+		"no-dh" => \$no_dh,
+		"no-hmac" => \$no_hmac,
+		"no-asm" => \$no_asm,
+		"nasm" => \$nasm,
+		"nw-nasm" => \$nw_nasm,
+		"nw-mwasm" => \$nw_mwasm,
+		"gaswin" => \$gaswin,
+		"no-ssl2" => \$no_ssl2,
+		"no-ssl3" => \$no_ssl3,
+		"no-tlsext" => \$no_tlsext,
+		"no-cms" => \$no_cms,
+		"no-jpake" => \$no_jpake,
+		"no-err" => \$no_err,
+		"no-sock" => \$no_sock,
+		"no-krb5" => \$no_krb5,
+		"no-ec" => \$no_ec,
+		"no-ecdsa" => \$no_ecdsa,
+		"no-ecdh" => \$no_ecdh,
+		"no-gost" => \$no_gost,
+		"no-engine" => \$no_engine,
+		"no-hw" => \$no_hw,
+		"just-ssl" =>
+			[\$no_rc2, \$no_idea, \$no_des, \$no_bf, \$no_cast,
+			  \$no_md2, \$no_sha, \$no_mdc2, \$no_dsa, \$no_dh,
+			  \$no_ssl2, \$no_err, \$no_ripemd, \$no_rc5,
+			  \$no_aes, \$no_camellia, \$no_seed],
+		"rsaref" => 0,
+		"gcc" => \$gcc,
+		"debug" => \$debug,
+		"profile" => \$profile,
+		"shlib" => \$shlib,
+		"dll" => \$shlib,
+		"shared" => 0,
+		"no-gmp" => 0,
+		"no-rfc3779" => 0,
+		"no-montasm" => 0,
+		"no-shared" => 0,
+		"no-store" => 0,
+		"no-zlib" => 0,
+		"no-zlib-dynamic" => 0,
+		);
+
+	if (exists $valid_options{$_})
+		{
+		my $r = $valid_options{$_};
+		if ( ref $r eq "SCALAR")
+			{ $$r = 1;}
+		elsif ( ref $r eq "ARRAY")
+			{
+			my $r2;
+			foreach $r2 (@$r)
+				{
+				$$r2 = 1;
+				}
+			}
+		}
+	elsif (/^no-comp$/) { $xcflags = "-DOPENSSL_NO_COMP $xcflags"; }
+	elsif (/^enable-zlib$/) { $zlib_opt = 1 if $zlib_opt == 0 }
+	elsif (/^enable-zlib-dynamic$/)
+		{
+		$zlib_opt = 2;
+		}
+	elsif (/^no-static-engine/)
+		{
+		$no_static_engine = 1;
+		}
+	elsif (/^enable-static-engine/)
+		{
+		$no_static_engine = 0;
+		}
+	# There are also enable-xxx options which correspond to
+	# the no-xxx. Since the scalars are enabled by default
+	# these can be ignored.
+	elsif (/^enable-/)
+		{
+		my $t = $_;
+		$t =~ s/^enable/no/;
+		if (exists $valid_options{$t})
+			{return 1;}
+		return 0;
+		}
+	# experimental-xxx is mostly like enable-xxx, but opensslconf.v
+	# will still set OPENSSL_NO_xxx unless we set OPENSSL_EXPERIMENTAL_xxx.
+	# (No need to fail if we don't know the algorithm -- this is for adventurous users only.)
+	elsif (/^experimental-/)
+		{
+		my $algo, $ALGO;
+		($algo = $_) =~ s/^experimental-//;
+		($ALGO = $algo) =~ tr/[a-z]/[A-Z]/;
+
+		$xcflags="-DOPENSSL_EXPERIMENTAL_$ALGO $xcflags";
+		
+		}
+	elsif (/^--with-krb5-flavor=(.*)$/)
+		{
+		my $krb5_flavor = $1;
+		if ($krb5_flavor =~ /^force-[Hh]eimdal$/)
+			{
+			$xcflags="-DKRB5_HEIMDAL $xcflags";
+			}
+		elsif ($krb5_flavor =~ /^MIT/i)
+			{
+			$xcflags="-DKRB5_MIT $xcflags";
+		 	if ($krb5_flavor =~ /^MIT[._-]*1[._-]*[01]/i)
+				{
+				$xcflags="-DKRB5_MIT_OLD11 $xcflags"
+				}
+			}
+		}
+	elsif (/^([^=]*)=(.*)$/){ $VARS{$1}=$2; }
+	elsif (/^-[lL].*$/)	{ $l_flags.="$_ "; }
+	elsif ((!/^-help/) && (!/^-h/) && (!/^-\?/) && /^-.*$/)
+		{ $c_flags.="$_ "; }
+	else { return(0); }
+	return(1);
+	}
diff --git a/openssl/util/mkcerts.sh b/openssl/util/mkcerts.sh
new file mode 100755
index 0000000..0184fcb
--- /dev/null
+++ b/openssl/util/mkcerts.sh
@@ -0,0 +1,220 @@
+#!/bin/sh
+
+# This script will re-make all the required certs.
+# cd apps
+# sh ../util/mkcerts.sh
+# mv ca-cert.pem pca-cert.pem ../certs
+# cd ..
+# cat certs/*.pem >>apps/server.pem
+# cat certs/*.pem >>apps/server2.pem
+# SSLEAY=`pwd`/apps/ssleay; export SSLEAY
+# sh tools/c_rehash certs
+#
+ 
+CAbits=1024
+SSLEAY="../apps/openssl"
+CONF="-config ../apps/openssl.cnf"
+
+# create pca request.
+echo creating $CAbits bit PCA cert request
+$SSLEAY req $CONF \
+	-new -md5 -newkey $CAbits \
+	-keyout pca-key.pem \
+	-out pca-req.pem -nodes >/dev/null <<EOF
+AU
+Queensland
+.
+CryptSoft Pty Ltd
+.
+Test PCA (1024 bit)
+
+
+
+EOF
+
+if [ $? != 0 ]; then
+	echo problems generating PCA request
+	exit 1
+fi
+
+#sign it.
+echo
+echo self signing PCA
+$SSLEAY x509 -md5 -days 1461 \
+	-req -signkey pca-key.pem \
+	-CAcreateserial -CAserial pca-cert.srl \
+	-in pca-req.pem -out pca-cert.pem
+
+if [ $? != 0 ]; then
+	echo problems self signing PCA cert
+	exit 1
+fi
+echo
+
+# create ca request.
+echo creating $CAbits bit CA cert request
+$SSLEAY req $CONF \
+	-new -md5 -newkey $CAbits \
+	-keyout ca-key.pem \
+	-out ca-req.pem -nodes >/dev/null <<EOF
+AU
+Queensland
+.
+CryptSoft Pty Ltd
+.
+Test CA (1024 bit)
+
+
+
+EOF
+
+if [ $? != 0 ]; then
+	echo problems generating CA request
+	exit 1
+fi
+
+#sign it.
+echo
+echo signing CA
+$SSLEAY x509 -md5 -days 1461 \
+	-req \
+	-CAcreateserial -CAserial pca-cert.srl \
+	-CA pca-cert.pem -CAkey pca-key.pem \
+	-in ca-req.pem -out ca-cert.pem
+
+if [ $? != 0 ]; then
+	echo problems signing CA cert
+	exit 1
+fi
+echo
+
+# create server request.
+echo creating 512 bit server cert request
+$SSLEAY req $CONF \
+	-new -md5 -newkey 512 \
+	-keyout s512-key.pem \
+	-out s512-req.pem -nodes >/dev/null <<EOF
+AU
+Queensland
+.
+CryptSoft Pty Ltd
+.
+Server test cert (512 bit)
+
+
+
+EOF
+
+if [ $? != 0 ]; then
+	echo problems generating 512 bit server cert request
+	exit 1
+fi
+
+#sign it.
+echo
+echo signing 512 bit server cert
+$SSLEAY x509 -md5 -days 365 \
+	-req \
+	-CAcreateserial -CAserial ca-cert.srl \
+	-CA ca-cert.pem -CAkey ca-key.pem \
+	-in s512-req.pem -out server.pem
+
+if [ $? != 0 ]; then
+	echo problems signing 512 bit server cert
+	exit 1
+fi
+echo
+
+# create 1024 bit server request.
+echo creating 1024 bit server cert request
+$SSLEAY req $CONF \
+	-new -md5 -newkey 1024 \
+	-keyout s1024key.pem \
+	-out s1024req.pem -nodes >/dev/null <<EOF
+AU
+Queensland
+.
+CryptSoft Pty Ltd
+.
+Server test cert (1024 bit)
+
+
+
+EOF
+
+if [ $? != 0 ]; then
+	echo problems generating 1024 bit server cert request
+	exit 1
+fi
+
+#sign it.
+echo
+echo signing 1024 bit server cert
+$SSLEAY x509 -md5 -days 365 \
+	-req \
+	-CAcreateserial -CAserial ca-cert.srl \
+	-CA ca-cert.pem -CAkey ca-key.pem \
+	-in s1024req.pem -out server2.pem
+
+if [ $? != 0 ]; then
+	echo problems signing 1024 bit server cert
+	exit 1
+fi
+echo
+
+# create 512 bit client request.
+echo creating 512 bit client cert request
+$SSLEAY req $CONF \
+	-new -md5 -newkey 512 \
+	-keyout c512-key.pem \
+	-out c512-req.pem -nodes >/dev/null <<EOF
+AU
+Queensland
+.
+CryptSoft Pty Ltd
+.
+Client test cert (512 bit)
+
+
+
+EOF
+
+if [ $? != 0 ]; then
+	echo problems generating 512 bit client cert request
+	exit 1
+fi
+
+#sign it.
+echo
+echo signing 512 bit client cert
+$SSLEAY x509 -md5 -days 365 \
+	-req \
+	-CAcreateserial -CAserial ca-cert.srl \
+	-CA ca-cert.pem -CAkey ca-key.pem \
+	-in c512-req.pem -out client.pem
+
+if [ $? != 0 ]; then
+	echo problems signing 512 bit client cert
+	exit 1
+fi
+
+echo cleanup
+
+cat pca-key.pem  >> pca-cert.pem
+cat ca-key.pem   >> ca-cert.pem
+cat s512-key.pem >> server.pem
+cat s1024key.pem >> server2.pem
+cat c512-key.pem >> client.pem
+
+for i in pca-cert.pem ca-cert.pem server.pem server2.pem client.pem
+do
+$SSLEAY x509 -issuer -subject -in $i -noout >$$
+cat $$
+/bin/cat $i >>$$
+/bin/mv $$ $i
+done
+
+#/bin/rm -f *key.pem *req.pem *.srl
+
+echo Finished
+
diff --git a/openssl/util/mkdef.pl b/openssl/util/mkdef.pl
new file mode 100755
index 0000000..ab47329
--- /dev/null
+++ b/openssl/util/mkdef.pl
@@ -0,0 +1,1509 @@
+#!/usr/local/bin/perl -w
+#
+# generate a .def file
+#
+# It does this by parsing the header files and looking for the
+# prototyped functions: it then prunes the output.
+#
+# Intermediary files are created, call libeay.num and ssleay.num,...
+# Previously, they had the following format:
+#
+#	routine-name	nnnn
+#
+# But that isn't enough for a number of reasons, the first on being that
+# this format is (needlessly) very Win32-centric, and even then...
+# One of the biggest problems is that there's no information about what
+# routines should actually be used, which varies with what crypto algorithms
+# are disabled.  Also, some operating systems (for example VMS with VAX C)
+# need to keep track of the global variables as well as the functions.
+#
+# So, a remake of this script is done so as to include information on the
+# kind of symbol it is (function or variable) and what algorithms they're
+# part of.  This will allow easy translating to .def files or the corresponding
+# file in other operating systems (a .opt file for VMS, possibly with a .mar
+# file).
+#
+# The format now becomes:
+#
+#	routine-name	nnnn	info
+#
+# and the "info" part is actually a colon-separated string of fields with
+# the following meaning:
+#
+#	existence:platform:kind:algorithms
+#
+# - "existence" can be "EXIST" or "NOEXIST" depending on if the symbol is
+#   found somewhere in the source, 
+# - "platforms" is empty if it exists on all platforms, otherwise it contains
+#   comma-separated list of the platform, just as they are if the symbol exists
+#   for those platforms, or prepended with a "!" if not.  This helps resolve
+#   symbol name variants for platforms where the names are too long for the
+#   compiler or linker, or if the systems is case insensitive and there is a
+#   clash, or the symbol is implemented differently (see
+#   EXPORT_VAR_AS_FUNCTION).  This script assumes renaming of symbols is found
+#   in the file crypto/symhacks.h.
+#   The semantics for the platforms is that every item is checked against the
+#   environment.  For the negative items ("!FOO"), if any of them is false
+#   (i.e. "FOO" is true) in the environment, the corresponding symbol can't be
+#   used.  For the positive itms, if all of them are false in the environment,
+#   the corresponding symbol can't be used.  Any combination of positive and
+#   negative items are possible, and of course leave room for some redundancy.
+# - "kind" is "FUNCTION" or "VARIABLE".  The meaning of that is obvious.
+# - "algorithms" is a comma-separated list of algorithm names.  This helps
+#   exclude symbols that are part of an algorithm that some user wants to
+#   exclude.
+#
+
+my $debug=0;
+
+my $crypto_num= "util/libeay.num";
+my $ssl_num=    "util/ssleay.num";
+my $libname;
+
+my $do_update = 0;
+my $do_rewrite = 1;
+my $do_crypto = 0;
+my $do_ssl = 0;
+my $do_ctest = 0;
+my $do_ctestall = 0;
+my $do_checkexist = 0;
+
+my $VMSVAX=0;
+my $VMSNonVAX=0;
+my $VMS=0;
+my $W32=0;
+my $W16=0;
+my $NT=0;
+my $OS2=0;
+# Set this to make typesafe STACK definitions appear in DEF
+my $safe_stack_def = 0;
+
+my @known_platforms = ( "__FreeBSD__", "PERL5", "NeXT",
+			"EXPORT_VAR_AS_FUNCTION", "ZLIB" );
+my @known_ossl_platforms = ( "VMS", "WIN16", "WIN32", "WINNT", "OS2" );
+my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
+			 "CAST", "MD2", "MD4", "MD5", "SHA", "SHA0", "SHA1",
+			 "SHA256", "SHA512", "RIPEMD",
+			 "MDC2", "WHIRLPOOL", "RSA", "DSA", "DH", "EC", "ECDH", "ECDSA",
+			 "HMAC", "AES", "CAMELLIA", "SEED", "GOST",
+			 # Envelope "algorithms"
+			 "EVP", "X509", "ASN1_TYPEDEFS",
+			 # Helper "algorithms"
+			 "BIO", "COMP", "BUFFER", "LHASH", "STACK", "ERR",
+			 "LOCKING",
+			 # External "algorithms"
+			 "FP_API", "STDIO", "SOCK", "KRB5", "DGRAM",
+			 # Engines
+			 "STATIC_ENGINE", "ENGINE", "HW", "GMP",
+			 # RFC3779
+			 "RFC3779",
+			 # TLS
+			 "TLSEXT", "PSK",
+			 # CMS
+			 "CMS",
+			 # CryptoAPI Engine
+			 "CAPIENG",
+			 # SSL v2
+			 "SSL2",
+			 # JPAKE
+			 "JPAKE",
+			 # Deprecated functions
+			 "DEPRECATED" );
+
+my $options="";
+open(IN,"<Makefile") || die "unable to open Makefile!\n";
+while(<IN>) {
+    $options=$1 if (/^OPTIONS=(.*)$/);
+}
+close(IN);
+
+# The following ciphers may be excluded (by Configure). This means functions
+# defined with ifndef(NO_XXX) are not included in the .def file, and everything
+# in directory xxx is ignored.
+my $no_rc2; my $no_rc4; my $no_rc5; my $no_idea; my $no_des; my $no_bf;
+my $no_cast; my $no_whirlpool; my $no_camellia; my $no_seed;
+my $no_md2; my $no_md4; my $no_md5; my $no_sha; my $no_ripemd; my $no_mdc2;
+my $no_rsa; my $no_dsa; my $no_dh; my $no_hmac=0; my $no_aes; my $no_krb5;
+my $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw;
+my $no_fp_api; my $no_static_engine=1; my $no_gmp; my $no_deprecated;
+my $no_rfc3779; my $no_psk; my $no_tlsext; my $no_cms; my $no_capieng;
+my $no_jpake; my $no_ssl2;
+
+my $zlib;
+
+
+foreach (@ARGV, split(/ /, $options))
+	{
+	$debug=1 if $_ eq "debug";
+	$W32=1 if $_ eq "32";
+	$W16=1 if $_ eq "16";
+	if($_ eq "NT") {
+		$W32 = 1;
+		$NT = 1;
+	}
+	if ($_ eq "VMS-VAX") {
+		$VMS=1;
+		$VMSVAX=1;
+	}
+	if ($_ eq "VMS-NonVAX") {
+		$VMS=1;
+		$VMSNonVAX=1;
+	}
+	$VMS=1 if $_ eq "VMS";
+	$OS2=1 if $_ eq "OS2";
+	if ($_ eq "zlib" || $_ eq "enable-zlib" || $_ eq "zlib-dynamic"
+			 || $_ eq "enable-zlib-dynamic") {
+		$zlib = 1;
+	}
+
+	$do_ssl=1 if $_ eq "ssleay";
+	if ($_ eq "ssl") {
+		$do_ssl=1; 
+		$libname=$_
+	}
+	$do_crypto=1 if $_ eq "libeay";
+	if ($_ eq "crypto") {
+		$do_crypto=1;
+		$libname=$_;
+	}
+	$no_static_engine=1 if $_ eq "no-static-engine";
+	$no_static_engine=0 if $_ eq "enable-static-engine";
+	$do_update=1 if $_ eq "update";
+	$do_rewrite=1 if $_ eq "rewrite";
+	$do_ctest=1 if $_ eq "ctest";
+	$do_ctestall=1 if $_ eq "ctestall";
+	$do_checkexist=1 if $_ eq "exist";
+	#$safe_stack_def=1 if $_ eq "-DDEBUG_SAFESTACK";
+
+	if    (/^no-rc2$/)      { $no_rc2=1; }
+	elsif (/^no-rc4$/)      { $no_rc4=1; }
+	elsif (/^no-rc5$/)      { $no_rc5=1; }
+	elsif (/^no-idea$/)     { $no_idea=1; }
+	elsif (/^no-des$/)      { $no_des=1; $no_mdc2=1; }
+	elsif (/^no-bf$/)       { $no_bf=1; }
+	elsif (/^no-cast$/)     { $no_cast=1; }
+	elsif (/^no-whirlpool$/)     { $no_whirlpool=1; }
+	elsif (/^no-md2$/)      { $no_md2=1; }
+	elsif (/^no-md4$/)      { $no_md4=1; }
+	elsif (/^no-md5$/)      { $no_md5=1; }
+	elsif (/^no-sha$/)      { $no_sha=1; }
+	elsif (/^no-ripemd$/)   { $no_ripemd=1; }
+	elsif (/^no-mdc2$/)     { $no_mdc2=1; }
+	elsif (/^no-rsa$/)      { $no_rsa=1; }
+	elsif (/^no-dsa$/)      { $no_dsa=1; }
+	elsif (/^no-dh$/)       { $no_dh=1; }
+	elsif (/^no-ec$/)       { $no_ec=1; }
+	elsif (/^no-ecdsa$/)	{ $no_ecdsa=1; }
+	elsif (/^no-ecdh$/) 	{ $no_ecdh=1; }
+	elsif (/^no-hmac$/)	{ $no_hmac=1; }
+	elsif (/^no-aes$/)	{ $no_aes=1; }
+	elsif (/^no-camellia$/)	{ $no_camellia=1; }
+	elsif (/^no-seed$/)     { $no_seed=1; }
+	elsif (/^no-evp$/)	{ $no_evp=1; }
+	elsif (/^no-lhash$/)	{ $no_lhash=1; }
+	elsif (/^no-stack$/)	{ $no_stack=1; }
+	elsif (/^no-err$/)	{ $no_err=1; }
+	elsif (/^no-buffer$/)	{ $no_buffer=1; }
+	elsif (/^no-bio$/)	{ $no_bio=1; }
+	#elsif (/^no-locking$/)	{ $no_locking=1; }
+	elsif (/^no-comp$/)	{ $no_comp=1; }
+	elsif (/^no-dso$/)	{ $no_dso=1; }
+	elsif (/^no-krb5$/)	{ $no_krb5=1; }
+	elsif (/^no-engine$/)	{ $no_engine=1; }
+	elsif (/^no-hw$/)	{ $no_hw=1; }
+	elsif (/^no-gmp$/)	{ $no_gmp=1; }
+	elsif (/^no-rfc3779$/)	{ $no_rfc3779=1; }
+	elsif (/^no-tlsext$/)	{ $no_tlsext=1; }
+	elsif (/^no-cms$/)	{ $no_cms=1; }
+	elsif (/^no-ssl2$/)	{ $no_ssl2=1; }
+	elsif (/^no-capieng$/)	{ $no_capieng=1; }
+	elsif (/^no-jpake$/)	{ $no_jpake=1; }
+	}
+
+
+if (!$libname) { 
+	if ($do_ssl) {
+		$libname="SSLEAY";
+	}
+	if ($do_crypto) {
+		$libname="LIBEAY";
+	}
+}
+
+# If no platform is given, assume WIN32
+if ($W32 + $W16 + $VMS + $OS2 == 0) {
+	$W32 = 1;
+}
+
+# Add extra knowledge
+if ($W16) {
+	$no_fp_api=1;
+}
+
+if (!$do_ssl && !$do_crypto)
+	{
+	print STDERR "usage: $0 ( ssl | crypto ) [ 16 | 32 | NT | OS2 ]\n";
+	exit(1);
+	}
+
+%ssl_list=&load_numbers($ssl_num);
+$max_ssl = $max_num;
+%crypto_list=&load_numbers($crypto_num);
+$max_crypto = $max_num;
+
+my $ssl="ssl/ssl.h";
+$ssl.=" ssl/kssl.h";
+$ssl.=" ssl/tls1.h";
+
+my $crypto ="crypto/crypto.h";
+$crypto.=" crypto/o_dir.h";
+$crypto.=" crypto/o_str.h";
+$crypto.=" crypto/o_time.h";
+$crypto.=" crypto/des/des.h crypto/des/des_old.h" ; # unless $no_des;
+$crypto.=" crypto/idea/idea.h" ; # unless $no_idea;
+$crypto.=" crypto/rc4/rc4.h" ; # unless $no_rc4;
+$crypto.=" crypto/rc5/rc5.h" ; # unless $no_rc5;
+$crypto.=" crypto/rc2/rc2.h" ; # unless $no_rc2;
+$crypto.=" crypto/bf/blowfish.h" ; # unless $no_bf;
+$crypto.=" crypto/cast/cast.h" ; # unless $no_cast;
+$crypto.=" crypto/whrlpool/whrlpool.h" ;
+$crypto.=" crypto/md2/md2.h" ; # unless $no_md2;
+$crypto.=" crypto/md4/md4.h" ; # unless $no_md4;
+$crypto.=" crypto/md5/md5.h" ; # unless $no_md5;
+$crypto.=" crypto/mdc2/mdc2.h" ; # unless $no_mdc2;
+$crypto.=" crypto/sha/sha.h" ; # unless $no_sha;
+$crypto.=" crypto/ripemd/ripemd.h" ; # unless $no_ripemd;
+$crypto.=" crypto/aes/aes.h" ; # unless $no_aes;
+$crypto.=" crypto/camellia/camellia.h" ; # unless $no_camellia;
+$crypto.=" crypto/seed/seed.h"; # unless $no_seed;
+
+$crypto.=" crypto/bn/bn.h";
+$crypto.=" crypto/rsa/rsa.h" ; # unless $no_rsa;
+$crypto.=" crypto/dsa/dsa.h" ; # unless $no_dsa;
+$crypto.=" crypto/dh/dh.h" ; # unless $no_dh;
+$crypto.=" crypto/ec/ec.h" ; # unless $no_ec;
+$crypto.=" crypto/ecdsa/ecdsa.h" ; # unless $no_ecdsa;
+$crypto.=" crypto/ecdh/ecdh.h" ; # unless $no_ecdh;
+$crypto.=" crypto/hmac/hmac.h" ; # unless $no_hmac;
+
+$crypto.=" crypto/engine/engine.h"; # unless $no_engine;
+$crypto.=" crypto/stack/stack.h" ; # unless $no_stack;
+$crypto.=" crypto/buffer/buffer.h" ; # unless $no_buffer;
+$crypto.=" crypto/bio/bio.h" ; # unless $no_bio;
+$crypto.=" crypto/dso/dso.h" ; # unless $no_dso;
+$crypto.=" crypto/lhash/lhash.h" ; # unless $no_lhash;
+$crypto.=" crypto/conf/conf.h";
+$crypto.=" crypto/txt_db/txt_db.h";
+
+$crypto.=" crypto/evp/evp.h" ; # unless $no_evp;
+$crypto.=" crypto/objects/objects.h";
+$crypto.=" crypto/pem/pem.h";
+#$crypto.=" crypto/meth/meth.h";
+$crypto.=" crypto/asn1/asn1.h";
+$crypto.=" crypto/asn1/asn1t.h";
+$crypto.=" crypto/asn1/asn1_mac.h";
+$crypto.=" crypto/err/err.h" ; # unless $no_err;
+$crypto.=" crypto/pkcs7/pkcs7.h";
+$crypto.=" crypto/pkcs12/pkcs12.h";
+$crypto.=" crypto/x509/x509.h";
+$crypto.=" crypto/x509/x509_vfy.h";
+$crypto.=" crypto/x509v3/x509v3.h";
+$crypto.=" crypto/ts/ts.h";
+$crypto.=" crypto/rand/rand.h";
+$crypto.=" crypto/comp/comp.h" ; # unless $no_comp;
+$crypto.=" crypto/ocsp/ocsp.h";
+$crypto.=" crypto/ui/ui.h crypto/ui/ui_compat.h";
+$crypto.=" crypto/krb5/krb5_asn.h";
+#$crypto.=" crypto/store/store.h";
+$crypto.=" crypto/pqueue/pqueue.h";
+$crypto.=" crypto/cms/cms.h";
+$crypto.=" crypto/jpake/jpake.h";
+$crypto.=" crypto/modes/modes.h";
+
+my $symhacks="crypto/symhacks.h";
+
+my @ssl_symbols = &do_defs("SSLEAY", $ssl, $symhacks);
+my @crypto_symbols = &do_defs("LIBEAY", $crypto, $symhacks);
+
+if ($do_update) {
+
+if ($do_ssl == 1) {
+
+	&maybe_add_info("SSLEAY",*ssl_list,@ssl_symbols);
+	if ($do_rewrite == 1) {
+		open(OUT, ">$ssl_num");
+		&rewrite_numbers(*OUT,"SSLEAY",*ssl_list,@ssl_symbols);
+	} else {
+		open(OUT, ">>$ssl_num");
+	}
+	&update_numbers(*OUT,"SSLEAY",*ssl_list,$max_ssl,@ssl_symbols);
+	close OUT;
+}
+
+if($do_crypto == 1) {
+
+	&maybe_add_info("LIBEAY",*crypto_list,@crypto_symbols);
+	if ($do_rewrite == 1) {
+		open(OUT, ">$crypto_num");
+		&rewrite_numbers(*OUT,"LIBEAY",*crypto_list,@crypto_symbols);
+	} else {
+		open(OUT, ">>$crypto_num");
+	}
+	&update_numbers(*OUT,"LIBEAY",*crypto_list,$max_crypto,@crypto_symbols);
+	close OUT;
+} 
+
+} elsif ($do_checkexist) {
+	&check_existing(*ssl_list, @ssl_symbols)
+		if $do_ssl == 1;
+	&check_existing(*crypto_list, @crypto_symbols)
+		if $do_crypto == 1;
+} elsif ($do_ctest || $do_ctestall) {
+
+	print <<"EOF";
+
+/* Test file to check all DEF file symbols are present by trying
+ * to link to all of them. This is *not* intended to be run!
+ */
+
+int main()
+{
+EOF
+	&print_test_file(*STDOUT,"SSLEAY",*ssl_list,$do_ctestall,@ssl_symbols)
+		if $do_ssl == 1;
+
+	&print_test_file(*STDOUT,"LIBEAY",*crypto_list,$do_ctestall,@crypto_symbols)
+		if $do_crypto == 1;
+
+	print "}\n";
+
+} else {
+
+	&print_def_file(*STDOUT,$libname,*ssl_list,@ssl_symbols)
+		if $do_ssl == 1;
+
+	&print_def_file(*STDOUT,$libname,*crypto_list,@crypto_symbols)
+		if $do_crypto == 1;
+
+}
+
+
+sub do_defs
+{
+	my($name,$files,$symhacksfile)=@_;
+	my $file;
+	my @ret;
+	my %syms;
+	my %platform;		# For anything undefined, we assume ""
+	my %kind;		# For anything undefined, we assume "FUNCTION"
+	my %algorithm;		# For anything undefined, we assume ""
+	my %variant;
+	my %variant_cnt;	# To be able to allocate "name{n}" if "name"
+				# is the same name as the original.
+	my $cpp;
+	my %unknown_algorithms = ();
+
+	foreach $file (split(/\s+/,$symhacksfile." ".$files))
+		{
+		print STDERR "DEBUG: starting on $file:\n" if $debug;
+		open(IN,"<$file") || die "unable to open $file:$!\n";
+		my $line = "", my $def= "";
+		my %tag = (
+			(map { $_ => 0 } @known_platforms),
+			(map { "OPENSSL_SYS_".$_ => 0 } @known_ossl_platforms),
+			(map { "OPENSSL_NO_".$_ => 0 } @known_algorithms),
+			NOPROTO		=> 0,
+			PERL5		=> 0,
+			_WINDLL		=> 0,
+			CONST_STRICT	=> 0,
+			TRUE		=> 1,
+		);
+		my $symhacking = $file eq $symhacksfile;
+		my @current_platforms = ();
+		my @current_algorithms = ();
+
+		# params: symbol, alias, platforms, kind
+		# The reason to put this subroutine in a variable is that
+		# it will otherwise create it's own, unshared, version of
+		# %tag and %variant...
+		my $make_variant = sub
+		{
+			my ($s, $a, $p, $k) = @_;
+			my ($a1, $a2);
+
+			print STDERR "DEBUG: make_variant: Entered with ",$s,", ",$a,", ",(defined($p)?$p:""),", ",(defined($k)?$k:""),"\n" if $debug;
+			if (defined($p))
+			{
+				$a1 = join(",",$p,
+					   grep(!/^$/,
+						map { $tag{$_} == 1 ? $_ : "" }
+						@known_platforms));
+			}
+			else
+			{
+				$a1 = join(",",
+					   grep(!/^$/,
+						map { $tag{$_} == 1 ? $_ : "" }
+						@known_platforms));
+			}
+			$a2 = join(",",
+				   grep(!/^$/,
+					map { $tag{"OPENSSL_SYS_".$_} == 1 ? $_ : "" }
+					@known_ossl_platforms));
+			print STDERR "DEBUG: make_variant: a1 = $a1; a2 = $a2\n" if $debug;
+			if ($a1 eq "") { $a1 = $a2; }
+			elsif ($a1 ne "" && $a2 ne "") { $a1 .= ",".$a2; }
+			if ($a eq $s)
+			{
+				if (!defined($variant_cnt{$s}))
+				{
+					$variant_cnt{$s} = 0;
+				}
+				$variant_cnt{$s}++;
+				$a .= "{$variant_cnt{$s}}";
+			}
+			my $toadd = $a.":".$a1.(defined($k)?":".$k:"");
+			my $togrep = $s.'(\{[0-9]+\})?:'.$a1.(defined($k)?":".$k:"");
+			if (!grep(/^$togrep$/,
+				  split(/;/, defined($variant{$s})?$variant{$s}:""))) {
+				if (defined($variant{$s})) { $variant{$s} .= ";"; }
+				$variant{$s} .= $toadd;
+			}
+			print STDERR "DEBUG: make_variant: Exit with variant of ",$s," = ",$variant{$s},"\n" if $debug;
+		};
+
+		print STDERR "DEBUG: parsing ----------\n" if $debug;
+		while(<IN>) {
+			if (/\/\* Error codes for the \w+ functions\. \*\//)
+				{
+				undef @tag;
+				last;
+				}
+			if ($line ne '') {
+				$_ = $line . $_;
+				$line = '';
+			}
+
+			if (/\\$/) {
+				chomp; # remove eol
+				chop; # remove ending backslash
+				$line = $_;
+				next;
+			}
+
+			if(/\/\*/) {
+				if (not /\*\//) {	# multiline comment...
+					$line = $_;	# ... just accumulate
+					next;
+				} else {
+					s/\/\*.*?\*\///gs;# wipe it
+				}
+			}
+
+			if ($cpp) {
+				$cpp++ if /^#\s*if/;
+				$cpp-- if /^#\s*endif/;
+				next;
+	    		}
+			$cpp = 1 if /^#.*ifdef.*cplusplus/;
+
+			s/{[^{}]*}//gs;                      # ignore {} blocks
+			print STDERR "DEBUG: \$def=\"$def\"\n" if $debug && $def ne "";
+			print STDERR "DEBUG: \$_=\"$_\"\n" if $debug;
+			if (/^\#\s*ifndef\s+(.*)/) {
+				push(@tag,"-");
+				push(@tag,$1);
+				$tag{$1}=-1;
+				print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
+			} elsif (/^\#\s*if\s+!defined\(([^\)]+)\)/) {
+				push(@tag,"-");
+				if (/^\#\s*if\s+(!defined\(([^\)]+)\)(\s+\&\&\s+!defined\(([^\)]+)\))*)$/) {
+					my $tmp_1 = $1;
+					my $tmp_;
+					foreach $tmp_ (split '\&\&',$tmp_1) {
+						$tmp_ =~ /!defined\(([^\)]+)\)/;
+						print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
+						push(@tag,$1);
+						$tag{$1}=-1;
+					}
+				} else {
+					print STDERR "Warning: $file: complicated expression: $_" if $debug; # because it is O...
+					print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
+					push(@tag,$1);
+					$tag{$1}=-1;
+				}
+			} elsif (/^\#\s*ifdef\s+(\S*)/) {
+				push(@tag,"-");
+				push(@tag,$1);
+				$tag{$1}=1;
+				print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
+			} elsif (/^\#\s*if\s+defined\(([^\)]+)\)/) {
+				push(@tag,"-");
+				if (/^\#\s*if\s+(defined\(([^\)]+)\)(\s+\|\|\s+defined\(([^\)]+)\))*)$/) {
+					my $tmp_1 = $1;
+					my $tmp_;
+					foreach $tmp_ (split '\|\|',$tmp_1) {
+						$tmp_ =~ /defined\(([^\)]+)\)/;
+						print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
+						push(@tag,$1);
+						$tag{$1}=1;
+					}
+				} else {
+					print STDERR "Warning: $file: complicated expression: $_\n" if $debug; # because it is O...
+					print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
+					push(@tag,$1);
+					$tag{$1}=1;
+				}
+			} elsif (/^\#\s*error\s+(\w+) is disabled\./) {
+				my $tag_i = $#tag;
+				while($tag[$tag_i] ne "-") {
+					if ($tag[$tag_i] eq "OPENSSL_NO_".$1) {
+						$tag{$tag[$tag_i]}=2;
+						print STDERR "DEBUG: $file: chaged tag $1 = 2\n" if $debug;
+					}
+					$tag_i--;
+				}
+			} elsif (/^\#\s*endif/) {
+				my $tag_i = $#tag;
+				while($tag_i > 0 && $tag[$tag_i] ne "-") {
+					my $t=$tag[$tag_i];
+					print STDERR "DEBUG: \$t=\"$t\"\n" if $debug;
+					if ($tag{$t}==2) {
+						$tag{$t}=-1;
+					} else {
+						$tag{$t}=0;
+					}
+					print STDERR "DEBUG: $file: changed tag ",$t," = ",$tag{$t},"\n" if $debug;
+					pop(@tag);
+					if ($t =~ /^OPENSSL_NO_([A-Z0-9_]+)$/) {
+						$t=$1;
+					} else {
+						$t="";
+					}
+					if ($t ne ""
+					    && !grep(/^$t$/, @known_algorithms)) {
+						$unknown_algorithms{$t} = 1;
+						#print STDERR "DEBUG: Added as unknown algorithm: $t\n" if $debug;
+					}
+					$tag_i--;
+				}
+				pop(@tag);
+			} elsif (/^\#\s*else/) {
+				my $tag_i = $#tag;
+				while($tag[$tag_i] ne "-") {
+					my $t=$tag[$tag_i];
+					$tag{$t}= -$tag{$t};
+					print STDERR "DEBUG: $file: changed tag ",$t," = ",$tag{$t},"\n" if $debug;
+					$tag_i--;
+				}
+			} elsif (/^\#\s*if\s+1/) {
+				push(@tag,"-");
+				# Dummy tag
+				push(@tag,"TRUE");
+				$tag{"TRUE"}=1;
+				print STDERR "DEBUG: $file: found 1\n" if $debug;
+			} elsif (/^\#\s*if\s+0/) {
+				push(@tag,"-");
+				# Dummy tag
+				push(@tag,"TRUE");
+				$tag{"TRUE"}=-1;
+				print STDERR "DEBUG: $file: found 0\n" if $debug;
+			} elsif (/^\#\s*define\s+(\w+)\s+(\w+)/
+				 && $symhacking && $tag{'TRUE'} != -1) {
+				# This is for aliasing.  When we find an alias,
+				# we have to invert
+				&$make_variant($1,$2);
+				print STDERR "DEBUG: $file: defined $1 = $2\n" if $debug;
+			}
+			if (/^\#/) {
+				@current_platforms =
+				    grep(!/^$/,
+					 map { $tag{$_} == 1 ? $_ :
+						   $tag{$_} == -1 ? "!".$_  : "" }
+					 @known_platforms);
+				push @current_platforms
+				    , grep(!/^$/,
+					   map { $tag{"OPENSSL_SYS_".$_} == 1 ? $_ :
+						     $tag{"OPENSSL_SYS_".$_} == -1 ? "!".$_  : "" }
+					   @known_ossl_platforms);
+				@current_algorithms =
+				    grep(!/^$/,
+					 map { $tag{"OPENSSL_NO_".$_} == -1 ? $_ : "" }
+					 @known_algorithms);
+				$def .=
+				    "#INFO:"
+					.join(',',@current_platforms).":"
+					    .join(',',@current_algorithms).";";
+				next;
+			}
+			if ($tag{'TRUE'} != -1) {
+				if (/^\s*DECLARE_STACK_OF\s*\(\s*(\w*)\s*\)/) {
+					next;
+				} elsif (/^\s*DECLARE_ASN1_ENCODE_FUNCTIONS\s*\(\s*(\w*)\s*,\s*(\w*)\s*,\s*(\w*)\s*\)/) {
+					$def .= "int d2i_$3(void);";
+					$def .= "int i2d_$3(void);";
+					# Variant for platforms that do not
+					# have to access globale variables
+					# in shared libraries through functions
+					$def .=
+					    "#INFO:"
+						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					$def .= "OPENSSL_EXTERN int $2_it;";
+					$def .=
+					    "#INFO:"
+						.join(',',@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					# Variant for platforms that have to
+					# access globale variables in shared
+					# libraries through functions
+					&$make_variant("$2_it","$2_it",
+						      "EXPORT_VAR_AS_FUNCTION",
+						      "FUNCTION");
+					next;
+				} elsif (/^\s*DECLARE_ASN1_FUNCTIONS_fname\s*\(\s*(\w*)\s*,\s*(\w*)\s*,\s*(\w*)\s*\)/) {
+					$def .= "int d2i_$3(void);";
+					$def .= "int i2d_$3(void);";
+					$def .= "int $3_free(void);";
+					$def .= "int $3_new(void);";
+					# Variant for platforms that do not
+					# have to access globale variables
+					# in shared libraries through functions
+					$def .=
+					    "#INFO:"
+						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					$def .= "OPENSSL_EXTERN int $2_it;";
+					$def .=
+					    "#INFO:"
+						.join(',',@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					# Variant for platforms that have to
+					# access globale variables in shared
+					# libraries through functions
+					&$make_variant("$2_it","$2_it",
+						      "EXPORT_VAR_AS_FUNCTION",
+						      "FUNCTION");
+					next;
+				} elsif (/^\s*DECLARE_ASN1_FUNCTIONS\s*\(\s*(\w*)\s*\)/ ||
+					 /^\s*DECLARE_ASN1_FUNCTIONS_const\s*\(\s*(\w*)\s*\)/) {
+					$def .= "int d2i_$1(void);";
+					$def .= "int i2d_$1(void);";
+					$def .= "int $1_free(void);";
+					$def .= "int $1_new(void);";
+					# Variant for platforms that do not
+					# have to access globale variables
+					# in shared libraries through functions
+					$def .=
+					    "#INFO:"
+						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					$def .= "OPENSSL_EXTERN int $1_it;";
+					$def .=
+					    "#INFO:"
+						.join(',',@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					# Variant for platforms that have to
+					# access globale variables in shared
+					# libraries through functions
+					&$make_variant("$1_it","$1_it",
+						      "EXPORT_VAR_AS_FUNCTION",
+						      "FUNCTION");
+					next;
+				} elsif (/^\s*DECLARE_ASN1_ENCODE_FUNCTIONS_const\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
+					$def .= "int d2i_$2(void);";
+					$def .= "int i2d_$2(void);";
+					# Variant for platforms that do not
+					# have to access globale variables
+					# in shared libraries through functions
+					$def .=
+					    "#INFO:"
+						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					$def .= "OPENSSL_EXTERN int $2_it;";
+					$def .=
+					    "#INFO:"
+						.join(',',@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					# Variant for platforms that have to
+					# access globale variables in shared
+					# libraries through functions
+					&$make_variant("$2_it","$2_it",
+						      "EXPORT_VAR_AS_FUNCTION",
+						      "FUNCTION");
+					next;
+				} elsif (/^\s*DECLARE_ASN1_ALLOC_FUNCTIONS\s*\(\s*(\w*)\s*\)/) {
+					$def .= "int $1_free(void);";
+					$def .= "int $1_new(void);";
+					next;
+				} elsif (/^\s*DECLARE_ASN1_FUNCTIONS_name\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
+					$def .= "int d2i_$2(void);";
+					$def .= "int i2d_$2(void);";
+					$def .= "int $2_free(void);";
+					$def .= "int $2_new(void);";
+					# Variant for platforms that do not
+					# have to access globale variables
+					# in shared libraries through functions
+					$def .=
+					    "#INFO:"
+						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					$def .= "OPENSSL_EXTERN int $2_it;";
+					$def .=
+					    "#INFO:"
+						.join(',',@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					# Variant for platforms that have to
+					# access globale variables in shared
+					# libraries through functions
+					&$make_variant("$2_it","$2_it",
+						      "EXPORT_VAR_AS_FUNCTION",
+						      "FUNCTION");
+					next;
+				} elsif (/^\s*DECLARE_ASN1_ITEM\s*\(\s*(\w*)\s*\)/) {
+					# Variant for platforms that do not
+					# have to access globale variables
+					# in shared libraries through functions
+					$def .=
+					    "#INFO:"
+						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					$def .= "OPENSSL_EXTERN int $1_it;";
+					$def .=
+					    "#INFO:"
+						.join(',',@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					# Variant for platforms that have to
+					# access globale variables in shared
+					# libraries through functions
+					&$make_variant("$1_it","$1_it",
+						      "EXPORT_VAR_AS_FUNCTION",
+						      "FUNCTION");
+					next;
+				} elsif (/^\s*DECLARE_ASN1_NDEF_FUNCTION\s*\(\s*(\w*)\s*\)/) {
+					$def .= "int i2d_$1_NDEF(void);";
+				} elsif (/^\s*DECLARE_ASN1_SET_OF\s*\(\s*(\w*)\s*\)/) {
+					next;
+				} elsif (/^\s*DECLARE_ASN1_PRINT_FUNCTION\s*\(\s*(\w*)\s*\)/) {
+					$def .= "int $1_print_ctx(void);";
+					next;
+				} elsif (/^\s*DECLARE_ASN1_PRINT_FUNCTION_name\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
+					$def .= "int $2_print_ctx(void);";
+					next;
+				} elsif (/^\s*DECLARE_PKCS12_STACK_OF\s*\(\s*(\w*)\s*\)/) {
+					next;
+				} elsif (/^DECLARE_PEM_rw\s*\(\s*(\w*)\s*,/ ||
+					 /^DECLARE_PEM_rw_cb\s*\(\s*(\w*)\s*,/ ||
+					 /^DECLARE_PEM_rw_const\s*\(\s*(\w*)\s*,/ ) {
+					# Things not in Win16
+					$def .=
+					    "#INFO:"
+						.join(',',"!WIN16",@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					$def .= "int PEM_read_$1(void);";
+					$def .= "int PEM_write_$1(void);";
+					$def .=
+					    "#INFO:"
+						.join(',',@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					# Things that are everywhere
+					$def .= "int PEM_read_bio_$1(void);";
+					$def .= "int PEM_write_bio_$1(void);";
+					next;
+				} elsif (/^DECLARE_PEM_write\s*\(\s*(\w*)\s*,/ ||
+					 /^DECLARE_PEM_write_cb\s*\(\s*(\w*)\s*,/ ) {
+					# Things not in Win16
+					$def .=
+					    "#INFO:"
+						.join(',',"!WIN16",@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					$def .= "int PEM_write_$1(void);";
+					$def .=
+					    "#INFO:"
+						.join(',',@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					# Things that are everywhere
+					$def .= "int PEM_write_bio_$1(void);";
+					next;
+				} elsif (/^DECLARE_PEM_read\s*\(\s*(\w*)\s*,/ ||
+					 /^DECLARE_PEM_read_cb\s*\(\s*(\w*)\s*,/ ) {
+					# Things not in Win16
+					$def .=
+					    "#INFO:"
+						.join(',',"!WIN16",@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					$def .= "int PEM_read_$1(void);";
+					$def .=
+					    "#INFO:"
+						.join(',',@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					# Things that are everywhere
+					$def .= "int PEM_read_bio_$1(void);";
+					next;
+				} elsif (/^OPENSSL_DECLARE_GLOBAL\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
+					# Variant for platforms that do not
+					# have to access globale variables
+					# in shared libraries through functions
+					$def .=
+					    "#INFO:"
+						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					$def .= "OPENSSL_EXTERN int _shadow_$2;";
+					$def .=
+					    "#INFO:"
+						.join(',',@current_platforms).":"
+						    .join(',',@current_algorithms).";";
+					# Variant for platforms that have to
+					# access globale variables in shared
+					# libraries through functions
+					&$make_variant("_shadow_$2","_shadow_$2",
+						      "EXPORT_VAR_AS_FUNCTION",
+						      "FUNCTION");
+				} elsif ($tag{'CONST_STRICT'} != 1) {
+					if (/\{|\/\*|\([^\)]*$/) {
+						$line = $_;
+					} else {
+						$def .= $_;
+					}
+				}
+			}
+		}
+		close(IN);
+
+		my $algs;
+		my $plays;
+
+		print STDERR "DEBUG: postprocessing ----------\n" if $debug;
+		foreach (split /;/, $def) {
+			my $s; my $k = "FUNCTION"; my $p; my $a;
+			s/^[\n\s]*//g;
+			s/[\n\s]*$//g;
+			next if(/\#undef/);
+			next if(/typedef\W/);
+			next if(/\#define/);
+
+			# Reduce argument lists to empty ()
+			# fold round brackets recursively: (t(*v)(t),t) -> (t{}{},t) -> {}
+			while(/\(.*\)/s) {
+				s/\([^\(\)]+\)/\{\}/gs;
+				s/\(\s*\*\s*(\w+)\s*\{\}\s*\)/$1/gs;	#(*f{}) -> f
+			}
+			# pretend as we didn't use curly braces: {} -> ()
+			s/\{\}/\(\)/gs;
+
+			s/STACK_OF\(\)/void/gs;
+			s/LHASH_OF\(\)/void/gs;
+
+			print STDERR "DEBUG: \$_ = \"$_\"\n" if $debug;
+			if (/^\#INFO:([^:]*):(.*)$/) {
+				$plats = $1;
+				$algs = $2;
+				print STDERR "DEBUG: found info on platforms ($plats) and algorithms ($algs)\n" if $debug;
+				next;
+			} elsif (/^\s*OPENSSL_EXTERN\s.*?(\w+(\{[0-9]+\})?)(\[[0-9]*\])*\s*$/) {
+				$s = $1;
+				$k = "VARIABLE";
+				print STDERR "DEBUG: found external variable $s\n" if $debug;
+			} elsif (/TYPEDEF_\w+_OF/s) {
+				next;
+			} elsif (/(\w+)\s*\(\).*/s) {	# first token prior [first] () is
+				$s = $1;		# a function name!
+				print STDERR "DEBUG: found function $s\n" if $debug;
+			} elsif (/\(/ and not (/=/)) {
+				print STDERR "File $file: cannot parse: $_;\n";
+				next;
+			} else {
+				next;
+			}
+
+			$syms{$s} = 1;
+			$kind{$s} = $k;
+
+			$p = $plats;
+			$a = $algs;
+			$a .= ",BF" if($s =~ /EVP_bf/);
+			$a .= ",CAST" if($s =~ /EVP_cast/);
+			$a .= ",DES" if($s =~ /EVP_des/);
+			$a .= ",DSA" if($s =~ /EVP_dss/);
+			$a .= ",IDEA" if($s =~ /EVP_idea/);
+			$a .= ",MD2" if($s =~ /EVP_md2/);
+			$a .= ",MD4" if($s =~ /EVP_md4/);
+			$a .= ",MD5" if($s =~ /EVP_md5/);
+			$a .= ",RC2" if($s =~ /EVP_rc2/);
+			$a .= ",RC4" if($s =~ /EVP_rc4/);
+			$a .= ",RC5" if($s =~ /EVP_rc5/);
+			$a .= ",RIPEMD" if($s =~ /EVP_ripemd/);
+			$a .= ",SHA" if($s =~ /EVP_sha/);
+			$a .= ",RSA" if($s =~ /EVP_(Open|Seal)(Final|Init)/);
+			$a .= ",RSA" if($s =~ /PEM_Seal(Final|Init|Update)/);
+			$a .= ",RSA" if($s =~ /RSAPrivateKey/);
+			$a .= ",RSA" if($s =~ /SSLv23?_((client|server)_)?method/);
+
+			$platform{$s} =
+			    &reduce_platforms((defined($platform{$s})?$platform{$s}.',':"").$p);
+			$algorithm{$s} .= ','.$a;
+
+			if (defined($variant{$s})) {
+				foreach $v (split /;/,$variant{$s}) {
+					(my $r, my $p, my $k) = split(/:/,$v);
+					my $ip = join ',',map({ /^!(.*)$/ ? $1 : "!".$_ } split /,/, $p);
+					$syms{$r} = 1;
+					if (!defined($k)) { $k = $kind{$s}; }
+					$kind{$r} = $k."(".$s.")";
+					$algorithm{$r} = $algorithm{$s};
+					$platform{$r} = &reduce_platforms($platform{$s}.",".$p.",".$p);
+					$platform{$s} = &reduce_platforms($platform{$s}.','.$ip.','.$ip);
+					print STDERR "DEBUG: \$variant{\"$s\"} = ",$v,"; \$r = $r; \$p = ",$platform{$r},"; \$a = ",$algorithm{$r},"; \$kind = ",$kind{$r},"\n" if $debug;
+				}
+			}
+			print STDERR "DEBUG: \$s = $s; \$p = ",$platform{$s},"; \$a = ",$algorithm{$s},"; \$kind = ",$kind{$s},"\n" if $debug;
+		}
+	}
+
+	# Prune the returned symbols
+
+        delete $syms{"bn_dump1"};
+	$platform{"BIO_s_log"} .= ",!WIN32,!WIN16,!macintosh";
+
+	$platform{"PEM_read_NS_CERT_SEQ"} = "VMS";
+	$platform{"PEM_write_NS_CERT_SEQ"} = "VMS";
+	$platform{"PEM_read_P8_PRIV_KEY_INFO"} = "VMS";
+	$platform{"PEM_write_P8_PRIV_KEY_INFO"} = "VMS";
+	$platform{"EVP_sha384"} = "!VMSVAX";
+	$platform{"EVP_sha512"} = "!VMSVAX";
+	$platform{"SHA384_Init"} = "!VMSVAX";
+	$platform{"SHA384_Transform"} = "!VMSVAX";
+	$platform{"SHA384_Update"} = "!VMSVAX";
+	$platform{"SHA384_Final"} = "!VMSVAX";
+	$platform{"SHA384"} = "!VMSVAX";
+	$platform{"SHA512_Init"} = "!VMSVAX";
+	$platform{"SHA512_Transform"} = "!VMSVAX";
+	$platform{"SHA512_Update"} = "!VMSVAX";
+	$platform{"SHA512_Final"} = "!VMSVAX";
+	$platform{"SHA512"} = "!VMSVAX";
+	$platform{"WHIRLPOOL_Init"} = "!VMSVAX";
+	$platform{"WHIRLPOOL"} = "!VMSVAX";
+	$platform{"WHIRLPOOL_BitUpdate"} = "!VMSVAX";
+	$platform{"EVP_whirlpool"} = "!VMSVAX";
+	$platform{"WHIRLPOOL_Final"} = "!VMSVAX";
+	$platform{"WHIRLPOOL_Update"} = "!VMSVAX";
+
+
+	# Info we know about
+
+	push @ret, map { $_."\\".&info_string($_,"EXIST",
+					      $platform{$_},
+					      $kind{$_},
+					      $algorithm{$_}) } keys %syms;
+
+	if (keys %unknown_algorithms) {
+		print STDERR "WARNING: mkdef.pl doesn't know the following algorithms:\n";
+		print STDERR "\t",join("\n\t",keys %unknown_algorithms),"\n";
+	}
+	return(@ret);
+}
+
+# Param: string of comma-separated platform-specs.
+sub reduce_platforms
+{
+	my ($platforms) = @_;
+	my $pl = defined($platforms) ? $platforms : "";
+	my %p = map { $_ => 0 } split /,/, $pl;
+	my $ret;
+
+	print STDERR "DEBUG: Entered reduce_platforms with \"$platforms\"\n"
+	    if $debug;
+	# We do this, because if there's code like the following, it really
+	# means the function exists in all cases and should therefore be
+	# everywhere.  By increasing and decreasing, we may attain 0:
+	#
+	# ifndef WIN16
+	#    int foo();
+	# else
+	#    int _fat foo();
+	# endif
+	foreach $platform (split /,/, $pl) {
+		if ($platform =~ /^!(.*)$/) {
+			$p{$1}--;
+		} else {
+			$p{$platform}++;
+		}
+	}
+	foreach $platform (keys %p) {
+		if ($p{$platform} == 0) { delete $p{$platform}; }
+	}
+
+	delete $p{""};
+
+	$ret = join(',',sort(map { $p{$_} < 0 ? "!".$_ : $_ } keys %p));
+	print STDERR "DEBUG: Exiting reduce_platforms with \"$ret\"\n"
+	    if $debug;
+	return $ret;
+}
+
+sub info_string {
+	(my $symbol, my $exist, my $platforms, my $kind, my $algorithms) = @_;
+
+	my %a = defined($algorithms) ?
+	    map { $_ => 1 } split /,/, $algorithms : ();
+	my $k = defined($kind) ? $kind : "FUNCTION";
+	my $ret;
+	my $p = &reduce_platforms($platforms);
+
+	delete $a{""};
+
+	$ret = $exist;
+	$ret .= ":".$p;
+	$ret .= ":".$k;
+	$ret .= ":".join(',',sort keys %a);
+	return $ret;
+}
+
+sub maybe_add_info {
+	(my $name, *nums, my @symbols) = @_;
+	my $sym;
+	my $new_info = 0;
+	my %syms=();
+
+	print STDERR "Updating $name info\n";
+	foreach $sym (@symbols) {
+		(my $s, my $i) = split /\\/, $sym;
+		if (defined($nums{$s})) {
+			$i =~ s/^(.*?:.*?:\w+)(\(\w+\))?/$1/;
+			(my $n, my $dummy) = split /\\/, $nums{$s};
+			if (!defined($dummy) || $i ne $dummy) {
+				$nums{$s} = $n."\\".$i;
+				$new_info++;
+				print STDERR "DEBUG: maybe_add_info for $s: \"$dummy\" => \"$i\"\n" if $debug;
+			}
+		}
+		$syms{$s} = 1;
+	}
+
+	my @s=sort { &parse_number($nums{$a},"n") <=> &parse_number($nums{$b},"n") } keys %nums;
+	foreach $sym (@s) {
+		(my $n, my $i) = split /\\/, $nums{$sym};
+		if (!defined($syms{$sym}) && $i !~ /^NOEXIST:/) {
+			$new_info++;
+			print STDERR "DEBUG: maybe_add_info for $sym: -> undefined\n" if $debug;
+		}
+	}
+	if ($new_info) {
+		print STDERR "$new_info old symbols got an info update\n";
+		if (!$do_rewrite) {
+			print STDERR "You should do a rewrite to fix this.\n";
+		}
+	} else {
+		print STDERR "No old symbols needed info update\n";
+	}
+}
+
+# Param: string of comma-separated keywords, each possibly prefixed with a "!"
+sub is_valid
+{
+	my ($keywords_txt,$platforms) = @_;
+	my (@keywords) = split /,/,$keywords_txt;
+	my ($falsesum, $truesum) = (0, 1);
+
+	# Param: one keyword
+	sub recognise
+	{
+		my ($keyword,$platforms) = @_;
+
+		if ($platforms) {
+			# platforms
+			if ($keyword eq "VMSVAX" && $VMSVAX) { return 1; }
+			if ($keyword eq "VMSNonVAX" && $VMSNonVAX) { return 1; }
+			if ($keyword eq "VMS" && $VMS) { return 1; }
+			if ($keyword eq "WIN32" && $W32) { return 1; }
+			if ($keyword eq "WIN16" && $W16) { return 1; }
+			if ($keyword eq "WINNT" && $NT) { return 1; }
+			if ($keyword eq "OS2" && $OS2) { return 1; }
+			# Special platforms:
+			# EXPORT_VAR_AS_FUNCTION means that global variables
+			# will be represented as functions.  This currently
+			# only happens on VMS-VAX.
+			if ($keyword eq "EXPORT_VAR_AS_FUNCTION" && ($VMSVAX || $W32 || $W16)) {
+				return 1;
+			}
+			if ($keyword eq "ZLIB" && $zlib) { return 1; }
+			return 0;
+		} else {
+			# algorithms
+			if ($keyword eq "RC2" && $no_rc2) { return 0; }
+			if ($keyword eq "RC4" && $no_rc4) { return 0; }
+			if ($keyword eq "RC5" && $no_rc5) { return 0; }
+			if ($keyword eq "IDEA" && $no_idea) { return 0; }
+			if ($keyword eq "DES" && $no_des) { return 0; }
+			if ($keyword eq "BF" && $no_bf) { return 0; }
+			if ($keyword eq "CAST" && $no_cast) { return 0; }
+			if ($keyword eq "MD2" && $no_md2) { return 0; }
+			if ($keyword eq "MD4" && $no_md4) { return 0; }
+			if ($keyword eq "MD5" && $no_md5) { return 0; }
+			if ($keyword eq "SHA" && $no_sha) { return 0; }
+			if ($keyword eq "RIPEMD" && $no_ripemd) { return 0; }
+			if ($keyword eq "MDC2" && $no_mdc2) { return 0; }
+			if ($keyword eq "WHIRLPOOL" && $no_whirlpool) { return 0; }
+			if ($keyword eq "RSA" && $no_rsa) { return 0; }
+			if ($keyword eq "DSA" && $no_dsa) { return 0; }
+			if ($keyword eq "DH" && $no_dh) { return 0; }
+			if ($keyword eq "EC" && $no_ec) { return 0; }
+			if ($keyword eq "ECDSA" && $no_ecdsa) { return 0; }
+			if ($keyword eq "ECDH" && $no_ecdh) { return 0; }
+			if ($keyword eq "HMAC" && $no_hmac) { return 0; }
+			if ($keyword eq "AES" && $no_aes) { return 0; }
+			if ($keyword eq "CAMELLIA" && $no_camellia) { return 0; }
+			if ($keyword eq "SEED" && $no_seed) { return 0; }
+			if ($keyword eq "EVP" && $no_evp) { return 0; }
+			if ($keyword eq "LHASH" && $no_lhash) { return 0; }
+			if ($keyword eq "STACK" && $no_stack) { return 0; }
+			if ($keyword eq "ERR" && $no_err) { return 0; }
+			if ($keyword eq "BUFFER" && $no_buffer) { return 0; }
+			if ($keyword eq "BIO" && $no_bio) { return 0; }
+			if ($keyword eq "COMP" && $no_comp) { return 0; }
+			if ($keyword eq "DSO" && $no_dso) { return 0; }
+			if ($keyword eq "KRB5" && $no_krb5) { return 0; }
+			if ($keyword eq "ENGINE" && $no_engine) { return 0; }
+			if ($keyword eq "HW" && $no_hw) { return 0; }
+			if ($keyword eq "FP_API" && $no_fp_api) { return 0; }
+			if ($keyword eq "STATIC_ENGINE" && $no_static_engine) { return 0; }
+			if ($keyword eq "GMP" && $no_gmp) { return 0; }
+			if ($keyword eq "RFC3779" && $no_rfc3779) { return 0; }
+			if ($keyword eq "TLSEXT" && $no_tlsext) { return 0; }
+			if ($keyword eq "PSK" && $no_psk) { return 0; }
+			if ($keyword eq "CMS" && $no_cms) { return 0; }
+			if ($keyword eq "SSL2" && $no_ssl2) { return 0; }
+			if ($keyword eq "CAPIENG" && $no_capieng) { return 0; }
+			if ($keyword eq "JPAKE" && $no_jpake) { return 0; }
+			if ($keyword eq "DEPRECATED" && $no_deprecated) { return 0; }
+
+			# Nothing recognise as true
+			return 1;
+		}
+	}
+
+	foreach $k (@keywords) {
+		if ($k =~ /^!(.*)$/) {
+			$falsesum += &recognise($1,$platforms);
+		} else {
+			$truesum *= &recognise($k,$platforms);
+		}
+	}
+	print STDERR "DEBUG: [",$#keywords,",",$#keywords < 0,"] is_valid($keywords_txt) => (\!$falsesum) && $truesum = ",(!$falsesum) && $truesum,"\n" if $debug;
+	return (!$falsesum) && $truesum;
+}
+
+sub print_test_file
+{
+	(*OUT,my $name,*nums,my $testall,my @symbols)=@_;
+	my $n = 1; my @e; my @r;
+	my $sym; my $prev = ""; my $prefSSLeay;
+
+	(@e)=grep(/^SSLeay(\{[0-9]+\})?\\.*?:.*?:.*/,@symbols);
+	(@r)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:.*/ && !/^SSLeay(\{[0-9]+\})?\\.*?:.*?:.*/,@symbols);
+	@symbols=((sort @e),(sort @r));
+
+	foreach $sym (@symbols) {
+		(my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
+		my $v = 0;
+		$v = 1 if $i=~ /^.*?:.*?:VARIABLE/;
+		my $p = ($i =~ /^[^:]*:([^:]*):/,$1);
+		my $a = ($i =~ /^[^:]*:[^:]*:[^:]*:([^:]*)/,$1);
+		if (!defined($nums{$s})) {
+			print STDERR "Warning: $s does not have a number assigned\n"
+			    if(!$do_update);
+		} elsif (is_valid($p,1) && is_valid($a,0)) {
+			my $s2 = ($s =~ /^(.*?)(\{[0-9]+\})?$/, $1);
+			if ($prev eq $s2) {
+				print OUT "\t/* The following has already appeared previously */\n";
+				print STDERR "Warning: Symbol '",$s2,"' redefined. old=",($nums{$prev} =~ /^(.*?)\\/,$1),", new=",($nums{$s2} =~ /^(.*?)\\/,$1),"\n";
+			}
+			$prev = $s2;	# To warn about duplicates...
+
+			($nn,$ni)=($nums{$s2} =~ /^(.*?)\\(.*)$/);
+			if ($v) {
+				print OUT "\textern int $s2; /* type unknown */ /* $nn $ni */\n";
+			} else {
+				print OUT "\textern int $s2(); /* type unknown */ /* $nn $ni */\n";
+			}
+		}
+	}
+}
+
+sub get_version {
+   local *MF;
+   my $v = '?';
+   open MF, 'Makefile' or return $v;
+   while (<MF>) {
+     $v = $1, last if /^VERSION=(.*?)\s*$/;
+   }
+   close MF;
+   return $v;
+}
+
+sub print_def_file
+{
+	(*OUT,my $name,*nums,my @symbols)=@_;
+	my $n = 1; my @e; my @r; my @v; my $prev="";
+	my $liboptions="";
+	my $libname = $name;
+	my $http_vendor = 'www.openssl.org/';
+	my $version = get_version();
+	my $what = "OpenSSL: implementation of Secure Socket Layer";
+	my $description = "$what $version, $name - http://$http_vendor";
+
+	if ($W32)
+		{ $libname.="32"; }
+	elsif ($W16)
+		{ $libname.="16"; }
+	elsif ($OS2)
+		{ # DLL names should not clash on the whole system.
+		  # However, they should not have any particular relationship
+		  # to the name of the static library.  Chose descriptive names
+		  # (must be at most 8 chars).
+		  my %translate = (ssl => 'open_ssl', crypto => 'cryptssl');
+		  $libname = $translate{$name} || $name;
+		  $liboptions = <<EOO;
+INITINSTANCE
+DATA MULTIPLE NONSHARED
+EOO
+		  # Vendor field can't contain colon, drat; so we omit http://
+		  $description = "\@#$http_vendor:$version#\@$what; DLL for library $name.  Build for EMX -Zmtd";
+		}
+
+	print OUT <<"EOF";
+;
+; Definition file for the DLL version of the $name library from OpenSSL
+;
+
+LIBRARY         $libname	$liboptions
+
+EOF
+
+	if ($W16) {
+		print <<"EOF";
+CODE            PRELOAD MOVEABLE
+DATA            PRELOAD MOVEABLE SINGLE
+
+EXETYPE		WINDOWS
+
+HEAPSIZE	4096
+STACKSIZE	8192
+
+EOF
+	}
+
+	print "EXPORTS\n";
+
+	(@e)=grep(/^SSLeay(\{[0-9]+\})?\\.*?:.*?:FUNCTION/,@symbols);
+	(@r)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:FUNCTION/ && !/^SSLeay(\{[0-9]+\})?\\.*?:.*?:FUNCTION/,@symbols);
+	(@v)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:VARIABLE/,@symbols);
+	@symbols=((sort @e),(sort @r), (sort @v));
+
+
+	foreach $sym (@symbols) {
+		(my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
+		my $v = 0;
+		$v = 1 if $i =~ /^.*?:.*?:VARIABLE/;
+		if (!defined($nums{$s})) {
+			printf STDERR "Warning: $s does not have a number assigned\n"
+			    if(!$do_update);
+		} else {
+			(my $n, my $dummy) = split /\\/, $nums{$s};
+			my %pf = ();
+			my $p = ($i =~ /^[^:]*:([^:]*):/,$1);
+			my $a = ($i =~ /^[^:]*:[^:]*:[^:]*:([^:]*)/,$1);
+			if (is_valid($p,1) && is_valid($a,0)) {
+				my $s2 = ($s =~ /^(.*?)(\{[0-9]+\})?$/, $1);
+				if ($prev eq $s2) {
+					print STDERR "Warning: Symbol '",$s2,"' redefined. old=",($nums{$prev} =~ /^(.*?)\\/,$1),", new=",($nums{$s2} =~ /^(.*?)\\/,$1),"\n";
+				}
+				$prev = $s2;	# To warn about duplicates...
+				if($v && !$OS2) {
+					printf OUT "    %s%-39s @%-8d DATA\n",($W32)?"":"_",$s2,$n;
+				} else {
+					printf OUT "    %s%-39s @%d\n",($W32||$OS2)?"":"_",$s2,$n;
+				}
+			}
+		}
+	}
+	printf OUT "\n";
+}
+
+sub load_numbers
+{
+	my($name)=@_;
+	my(@a,%ret);
+
+	$max_num = 0;
+	$num_noinfo = 0;
+	$prev = "";
+	$prev_cnt = 0;
+
+	open(IN,"<$name") || die "unable to open $name:$!\n";
+	while (<IN>) {
+		chop;
+		s/#.*$//;
+		next if /^\s*$/;
+		@a=split;
+		if (defined $ret{$a[0]}) {
+			# This is actually perfectly OK
+			#print STDERR "Warning: Symbol '",$a[0],"' redefined. old=",$ret{$a[0]},", new=",$a[1],"\n";
+		}
+		if ($max_num > $a[1]) {
+			print STDERR "Warning: Number decreased from ",$max_num," to ",$a[1],"\n";
+		}
+		elsif ($max_num == $a[1]) {
+			# This is actually perfectly OK
+			#print STDERR "Warning: Symbol ",$a[0]," has same number as previous ",$prev,": ",$a[1],"\n";
+			if ($a[0] eq $prev) {
+				$prev_cnt++;
+				$a[0] .= "{$prev_cnt}";
+			}
+		}
+		else {
+			$prev_cnt = 0;
+		}
+		if ($#a < 2) {
+			# Existence will be proven later, in do_defs
+			$ret{$a[0]}=$a[1];
+			$num_noinfo++;
+		} else {
+			$ret{$a[0]}=$a[1]."\\".$a[2]; # \\ is a special marker
+		}
+		$max_num = $a[1] if $a[1] > $max_num;
+		$prev=$a[0];
+	}
+	if ($num_noinfo) {
+		print STDERR "Warning: $num_noinfo symbols were without info.";
+		if ($do_rewrite) {
+			printf STDERR "  The rewrite will fix this.\n";
+		} else {
+			printf STDERR "  You should do a rewrite to fix this.\n";
+		}
+	}
+	close(IN);
+	return(%ret);
+}
+
+sub parse_number
+{
+	(my $str, my $what) = @_;
+	(my $n, my $i) = split(/\\/,$str);
+	if ($what eq "n") {
+		return $n;
+	} else {
+		return $i;
+	}
+}
+
+sub rewrite_numbers
+{
+	(*OUT,$name,*nums,@symbols)=@_;
+	my $thing;
+
+	print STDERR "Rewriting $name\n";
+
+	my @r = grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:\w+\(\w+\)/,@symbols);
+	my $r; my %r; my %rsyms;
+	foreach $r (@r) {
+		(my $s, my $i) = split /\\/, $r;
+		my $a = $1 if $i =~ /^.*?:.*?:\w+\((\w+)\)/;
+		$i =~ s/^(.*?:.*?:\w+)\(\w+\)/$1/;
+		$r{$a} = $s."\\".$i;
+		$rsyms{$s} = 1;
+	}
+
+	my %syms = ();
+	foreach $_ (@symbols) {
+		(my $n, my $i) = split /\\/;
+		$syms{$n} = 1;
+	}
+
+	my @s=sort {
+	    &parse_number($nums{$a},"n") <=> &parse_number($nums{$b},"n")
+	    || $a cmp $b
+	} keys %nums;
+	foreach $sym (@s) {
+		(my $n, my $i) = split /\\/, $nums{$sym};
+		next if defined($i) && $i =~ /^.*?:.*?:\w+\(\w+\)/;
+		next if defined($rsyms{$sym});
+		print STDERR "DEBUG: rewrite_numbers for sym = ",$sym,": i = ",$i,", n = ",$n,", rsym{sym} = ",$rsyms{$sym},"syms{sym} = ",$syms{$sym},"\n" if $debug;
+		$i="NOEXIST::FUNCTION:"
+			if !defined($i) || $i eq "" || !defined($syms{$sym});
+		my $s2 = $sym;
+		$s2 =~ s/\{[0-9]+\}$//;
+		printf OUT "%s%-39s %d\t%s\n","",$s2,$n,$i;
+		if (exists $r{$sym}) {
+			(my $s, $i) = split /\\/,$r{$sym};
+			my $s2 = $s;
+			$s2 =~ s/\{[0-9]+\}$//;
+			printf OUT "%s%-39s %d\t%s\n","",$s2,$n,$i;
+		}
+	}
+}
+
+sub update_numbers
+{
+	(*OUT,$name,*nums,my $start_num, my @symbols)=@_;
+	my $new_syms = 0;
+
+	print STDERR "Updating $name numbers\n";
+
+	my @r = grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:\w+\(\w+\)/,@symbols);
+	my $r; my %r; my %rsyms;
+	foreach $r (@r) {
+		(my $s, my $i) = split /\\/, $r;
+		my $a = $1 if $i =~ /^.*?:.*?:\w+\((\w+)\)/;
+		$i =~ s/^(.*?:.*?:\w+)\(\w+\)/$1/;
+		$r{$a} = $s."\\".$i;
+		$rsyms{$s} = 1;
+	}
+
+	foreach $sym (@symbols) {
+		(my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
+		next if $i =~ /^.*?:.*?:\w+\(\w+\)/;
+		next if defined($rsyms{$sym});
+		die "ERROR: Symbol $sym had no info attached to it."
+		    if $i eq "";
+		if (!exists $nums{$s}) {
+			$new_syms++;
+			my $s2 = $s;
+			$s2 =~ s/\{[0-9]+\}$//;
+			printf OUT "%s%-39s %d\t%s\n","",$s2, ++$start_num,$i;
+			if (exists $r{$s}) {
+				($s, $i) = split /\\/,$r{$s};
+				$s =~ s/\{[0-9]+\}$//;
+				printf OUT "%s%-39s %d\t%s\n","",$s, $start_num,$i;
+			}
+		}
+	}
+	if($new_syms) {
+		print STDERR "$new_syms New symbols added\n";
+	} else {
+		print STDERR "No New symbols Added\n";
+	}
+}
+
+sub check_existing
+{
+	(*nums, my @symbols)=@_;
+	my %existing; my @remaining;
+	@remaining=();
+	foreach $sym (@symbols) {
+		(my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
+		$existing{$s}=1;
+	}
+	foreach $sym (keys %nums) {
+		if (!exists $existing{$sym}) {
+			push @remaining, $sym;
+		}
+	}
+	if(@remaining) {
+		print STDERR "The following symbols do not seem to exist:\n";
+		foreach $sym (@remaining) {
+			print STDERR "\t",$sym,"\n";
+		}
+	}
+}
+
diff --git a/openssl/util/mkdir-p.pl b/openssl/util/mkdir-p.pl
new file mode 100755
index 0000000..e73d02b
--- /dev/null
+++ b/openssl/util/mkdir-p.pl
@@ -0,0 +1,34 @@
+#!/usr/local/bin/perl
+
+# mkdir-p.pl
+
+# On some systems, the -p option to mkdir (= also create any missing parent
+# directories) is not available.
+
+my $arg;
+
+foreach $arg (@ARGV) {
+  $arg =~ tr|\\|/|;
+  &do_mkdir_p($arg);
+}
+
+
+sub do_mkdir_p {
+  local($dir) = @_;
+
+  $dir =~ s|/*\Z(?!\n)||s;
+
+  if (-d $dir) {
+    return;
+  }
+
+  if ($dir =~ m|[^/]/|s) {
+    local($parent) = $dir;
+    $parent =~ s|[^/]*\Z(?!\n)||s;
+
+    do_mkdir_p($parent);
+  }
+
+  mkdir($dir, 0777) || die "Cannot create directory $dir: $!\n";
+  print "created directory `$dir'\n";
+}
diff --git a/openssl/util/mkerr.pl b/openssl/util/mkerr.pl
new file mode 100644
index 0000000..aec401c
--- /dev/null
+++ b/openssl/util/mkerr.pl
@@ -0,0 +1,810 @@
+#!/usr/local/bin/perl -w
+
+my $config = "crypto/err/openssl.ec";
+my $hprefix = "openssl/";
+my $debug = 0;
+my $rebuild = 0;
+my $static = 1;
+my $recurse = 0;
+my $reindex = 0;
+my $dowrite = 0;
+my $staticloader = "";
+
+my $pack_errcode;
+my $load_errcode;
+
+my $errcount;
+
+while (@ARGV) {
+	my $arg = $ARGV[0];
+	if($arg eq "-conf") {
+		shift @ARGV;
+		$config = shift @ARGV;
+	} elsif($arg eq "-hprefix") {
+		shift @ARGV;
+		$hprefix = shift @ARGV;
+	} elsif($arg eq "-debug") {
+		$debug = 1;
+		shift @ARGV;
+	} elsif($arg eq "-rebuild") {
+		$rebuild = 1;
+		shift @ARGV;
+	} elsif($arg eq "-recurse") {
+		$recurse = 1;
+		shift @ARGV;
+	} elsif($arg eq "-reindex") {
+		$reindex = 1;
+		shift @ARGV;
+	} elsif($arg eq "-nostatic") {
+		$static = 0;
+		shift @ARGV;
+	} elsif($arg eq "-staticloader") {
+		$staticloader = "static ";
+		shift @ARGV;
+	} elsif($arg eq "-write") {
+		$dowrite = 1;
+		shift @ARGV;
+	} elsif($arg eq "-help" || $arg eq "-h" || $arg eq "-?" || $arg eq "--help") {
+		print STDERR <<"EOF";
+mkerr.pl [options] ...
+
+Options:
+
+  -conf F       Use the config file F instead of the default one:
+                  crypto/err/openssl.ec
+
+  -hprefix P    Prepend the filenames in generated #include <header>
+                statements with prefix P. Default: 'openssl/' (without
+                the quotes, naturally)
+
+  -debug        Turn on debugging verbose output on stderr.
+
+  -rebuild      Rebuild all header and C source files, irrespective of the
+                fact if any error or function codes have been added/removed.
+                Default: only update files for libraries which saw change
+                         (of course, this requires '-write' as well, or no
+                          files will be touched!)
+
+  -recurse      scan a preconfigured set of directories / files for error and
+                function codes:
+                  (<crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>, <apps/*.c>)
+                When this option is NOT specified, the filelist is taken from
+                the commandline instead. Here, wildcards may be embedded. (Be
+                sure to escape those to prevent the shell from expanding them
+                for you when you wish mkerr.pl to do so instead.)
+                Default: take file list to scan from the command line.
+
+  -reindex      Discard the numeric values previously assigned to the error
+                and function codes as extracted from the scanned header files;
+                instead renumber all of them starting from 100. (Note that
+                the numbers assigned through 'R' records in the config file
+                remain intact.)
+                Default: keep previously assigned numbers. (You are warned
+                         when collisions are detected.)
+
+  -nostatic     Generates a different source code, where these additional 
+                functions are generated for each library specified in the
+                config file:
+                  void ERR_load_<LIB>_strings(void);
+                  void ERR_unload_<LIB>_strings(void);
+                  void ERR_<LIB>_error(int f, int r, char *fn, int ln);
+                  #define <LIB>err(f,r) ERR_<LIB>_error(f,r,__FILE__,__LINE__)
+                while the code facilitates the use of these in an environment
+                where the error support routines are dynamically loaded at 
+                runtime.
+                Default: 'static' code generation.
+
+  -staticloader Prefix generated functions with the 'static' scope modifier.
+                Default: don't write any scope modifier prefix.
+
+  -write        Actually (over)write the generated code to the header and C 
+                source files as assigned to each library through the config 
+                file.
+                Default: don't write.
+
+  -help / -h / -? / --help            Show this help text.
+
+  ...           Additional arguments are added to the file list to scan,
+                assuming '-recurse' was NOT specified on the command line.
+
+EOF
+		exit 1;
+	} else {
+		last;
+	}
+}
+
+if($recurse) {
+	@source = (<crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>);
+} else {
+	@source = @ARGV;
+}
+
+# Read in the config file
+
+open(IN, "<$config") || die "Can't open config file $config";
+
+# Parse config file
+
+while(<IN>)
+{
+	if(/^L\s+(\S+)\s+(\S+)\s+(\S+)/) {
+		$hinc{$1} = $2;
+		$libinc{$2} = $1;
+		$cskip{$3} = $1;
+		if($3 ne "NONE") {
+			$csrc{$1} = $3;
+			$fmax{$1} = 100;
+			$rmax{$1} = 100;
+			$fassigned{$1} = ":";
+			$rassigned{$1} = ":";
+			$fnew{$1} = 0;
+			$rnew{$1} = 0;
+		}
+	} elsif (/^F\s+(\S+)/) {
+	# Add extra function with $1
+	} elsif (/^R\s+(\S+)\s+(\S+)/) {
+		$rextra{$1} = $2;
+		$rcodes{$1} = $2;
+	}
+}
+
+close IN;
+
+# Scan each header file in turn and make a list of error codes
+# and function names
+
+while (($hdr, $lib) = each %libinc)
+{
+	next if($hdr eq "NONE");
+	print STDERR "Scanning header file $hdr\n" if $debug; 
+	my $line = "", $def= "", $linenr = 0, $gotfile = 0;
+	if (open(IN, "<$hdr")) {
+	    $gotfile = 1;
+	    while(<IN>) {
+		$linenr++;
+		print STDERR "line: $linenr\r" if $debug;
+
+		last if(/BEGIN\s+ERROR\s+CODES/);
+		if ($line ne '') {
+		    $_ = $line . $_;
+		    $line = '';
+		}
+
+		if (/\\$/) {
+		    $line = $_;
+		    next;
+		}
+
+		if(/\/\*/) {
+		    if (not /\*\//) {		# multiline comment...
+			$line = $_;		# ... just accumulate
+			next; 
+		    } else {
+			s/\/\*.*?\*\///gs;	# wipe it
+		    }
+		}
+
+		if ($cpp) {
+		    $cpp++ if /^#\s*if/;
+		    $cpp-- if /^#\s*endif/;
+		    next;
+		}
+		$cpp = 1 if /^#.*ifdef.*cplusplus/;  # skip "C" declaration
+
+		next if (/^\#/);                      # skip preprocessor directives
+
+		s/{[^{}]*}//gs;                      # ignore {} blocks
+
+		if (/\{|\/\*/) { # Add a } so editor works...
+		    $line = $_;
+		} else {
+		    $def .= $_;
+		}
+	    }
+	}
+
+	print STDERR "                                  \r" if $debug;
+        $defnr = 0;
+	# Delete any DECLARE_ macros
+	$def =~ s/DECLARE_\w+\([\w,\s]+\)//gs;
+	foreach (split /;/, $def) {
+	    $defnr++;
+	    print STDERR "def: $defnr\r" if $debug;
+
+	    # The goal is to collect function names from function declarations.
+
+	    s/^[\n\s]*//g;
+	    s/[\n\s]*$//g;
+
+	    # Skip over recognized non-function declarations
+	    next if(/typedef\W/ or /DECLARE_STACK_OF/ or /TYPEDEF_.*_OF/);
+
+	    # Remove STACK_OF(foo)
+	    s/STACK_OF\(\w+\)/void/;
+
+	    # Reduce argument lists to empty ()
+	    # fold round brackets recursively: (t(*v)(t),t) -> (t{}{},t) -> {}
+	    while(/\(.*\)/s) {
+		s/\([^\(\)]+\)/\{\}/gs;
+		s/\(\s*\*\s*(\w+)\s*\{\}\s*\)/$1/gs;	#(*f{}) -> f
+	    }
+	    # pretend as we didn't use curly braces: {} -> ()
+	    s/\{\}/\(\)/gs;
+
+	    if (/(\w+)\s*\(\).*/s) {	# first token prior [first] () is
+		my $name = $1;		# a function name!
+		$name =~ tr/[a-z]/[A-Z]/;
+		$ftrans{$name} = $1;
+	    } elsif (/[\(\)]/ and not (/=/)) {
+		print STDERR "Header $hdr: cannot parse: $_;\n";
+	    }
+	}
+
+	print STDERR "                                  \r" if $debug;
+
+	next if $reindex;
+
+	# Scan function and reason codes and store them: keep a note of the
+	# maximum code used.
+
+	if ($gotfile) {
+	  while(<IN>) {
+		if(/^\#define\s+(\S+)\s+(\S+)/) {
+			$name = $1;
+			$code = $2;
+			next if $name =~ /^${lib}err/;
+			unless($name =~ /^${lib}_([RF])_(\w+)$/) {
+				print STDERR "Invalid error code $name\n";
+				next;
+			}
+			if($1 eq "R") {
+				$rcodes{$name} = $code;
+				if ($rassigned{$lib} =~ /:$code:/) {
+					print STDERR "!! ERROR: $lib reason code $code assigned twice (collision at $name)\n";
+					++$errcount;
+				}
+				$rassigned{$lib} .= "$code:";
+				if(!(exists $rextra{$name}) &&
+					 ($code > $rmax{$lib}) ) {
+					$rmax{$lib} = $code;
+				}
+			} else {
+				if ($fassigned{$lib} =~ /:$code:/) {
+					print STDERR "!! ERROR: $lib function code $code assigned twice (collision at $name)\n";
+					++$errcount;
+				}
+				$fassigned{$lib} .= "$code:";
+				if($code > $fmax{$lib}) {
+					$fmax{$lib} = $code;
+				}
+				$fcodes{$name} = $code;
+			}
+		}
+	  }
+	}
+
+	if ($debug) {
+		if (defined($fmax{$lib})) {
+			print STDERR "Max function code fmax" . "{" . "$lib" . "} = $fmax{$lib}\n";
+			$fassigned{$lib} =~ m/^:(.*):$/;
+			@fassigned = sort {$a <=> $b} split(":", $1);
+			print STDERR "  @fassigned\n";
+		}
+		if (defined($rmax{$lib})) {
+			print STDERR "Max reason code rmax" . "{" . "$lib" . "} = $rmax{$lib}\n";
+			$rassigned{$lib} =~ m/^:(.*):$/;
+			@rassigned = sort {$a <=> $b} split(":", $1);
+			print STDERR "  @rassigned\n";
+		}
+	}
+
+	if ($lib eq "SSL") {
+		if ($rmax{$lib} >= 1000) {
+			print STDERR "!! ERROR: SSL error codes 1000+ are reserved for alerts.\n";
+			print STDERR "!!        Any new alerts must be added to $config.\n";
+			++$errcount;
+			print STDERR "\n";
+		}
+	}
+	close IN;
+}
+
+# Scan each C source file and look for function and reason codes
+# This is done by looking for strings that "look like" function or
+# reason codes: basically anything consisting of all upper case and
+# numerics which has _F_ or _R_ in it and which has the name of an
+# error library at the start. This seems to work fine except for the
+# oddly named structure BIO_F_CTX which needs to be ignored.
+# If a code doesn't exist in list compiled from headers then mark it
+# with the value "X" as a place holder to give it a value later.
+# Store all function and reason codes found in %ufcodes and %urcodes
+# so all those unreferenced can be printed out.
+
+
+foreach $file (@source) {
+	# Don't parse the error source file.
+	next if exists $cskip{$file};
+	print STDERR "File loaded: ".$file."\r" if $debug;
+	open(IN, "<$file") || die "Can't open source file $file\n";
+	while(<IN>) {
+		# skip obsoleted source files entirely!
+		last if(/^#error\s+obsolete/);
+
+		if(/(([A-Z0-9]+)_F_([A-Z0-9_]+))/) {
+			next unless exists $csrc{$2};
+			next if($1 eq "BIO_F_BUFFER_CTX");
+			$ufcodes{$1} = 1;
+			if(!exists $fcodes{$1}) {
+				$fcodes{$1} = "X";
+				$fnew{$2}++;
+			}
+			$notrans{$1} = 1 unless exists $ftrans{$3};
+			print STDERR "Function: $1\t= $fcodes{$1} (lib: $2, name: $3)\n" if $debug; 
+		}
+		if(/(([A-Z0-9]+)_R_[A-Z0-9_]+)/) {
+			next unless exists $csrc{$2};
+			$urcodes{$1} = 1;
+			if(!exists $rcodes{$1}) {
+				$rcodes{$1} = "X";
+				$rnew{$2}++;
+			}
+			print STDERR "Reason: $1\t= $rcodes{$1} (lib: $2)\n" if $debug; 
+		} 
+	}
+	close IN;
+}
+print STDERR "                                  \n" if $debug;
+
+# Now process each library in turn.
+
+foreach $lib (keys %csrc)
+{
+	my $hfile = $hinc{$lib};
+	my $cfile = $csrc{$lib};
+	if(!$fnew{$lib} && !$rnew{$lib}) {
+		print STDERR "$lib:\t\tNo new error codes\n";
+		next unless $rebuild;
+	} else {
+		print STDERR "$lib:\t\t$fnew{$lib} New Functions,";
+		print STDERR " $rnew{$lib} New Reasons.\n";
+		next unless $dowrite;
+	}
+
+	# If we get here then we have some new error codes so we
+	# need to rebuild the header file and C file.
+
+	# Make a sorted list of error and reason codes for later use.
+
+	my @function = sort grep(/^${lib}_/,keys %fcodes);
+	my @reasons = sort grep(/^${lib}_/,keys %rcodes);
+
+	# Rewrite the header file
+
+	if (open(IN, "<$hfile")) {
+	    # Copy across the old file
+	    while(<IN>) {
+		push @out, $_;
+		last if (/BEGIN ERROR CODES/);
+	    }
+	    close IN;
+	} else {
+	    push @out,
+"/* ====================================================================\n",
+" * Copyright (c) 2001-2011 The OpenSSL Project.  All rights reserved.\n",
+" *\n",
+" * Redistribution and use in source and binary forms, with or without\n",
+" * modification, are permitted provided that the following conditions\n",
+" * are met:\n",
+" *\n",
+" * 1. Redistributions of source code must retain the above copyright\n",
+" *    notice, this list of conditions and the following disclaimer. \n",
+" *\n",
+" * 2. Redistributions in binary form must reproduce the above copyright\n",
+" *    notice, this list of conditions and the following disclaimer in\n",
+" *    the documentation and/or other materials provided with the\n",
+" *    distribution.\n",
+" *\n",
+" * 3. All advertising materials mentioning features or use of this\n",
+" *    software must display the following acknowledgment:\n",
+" *    \"This product includes software developed by the OpenSSL Project\n",
+" *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)\"\n",
+" *\n",
+" * 4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to\n",
+" *    endorse or promote products derived from this software without\n",
+" *    prior written permission. For written permission, please contact\n",
+" *    openssl-core\@openssl.org.\n",
+" *\n",
+" * 5. Products derived from this software may not be called \"OpenSSL\"\n",
+" *    nor may \"OpenSSL\" appear in their names without prior written\n",
+" *    permission of the OpenSSL Project.\n",
+" *\n",
+" * 6. Redistributions of any form whatsoever must retain the following\n",
+" *    acknowledgment:\n",
+" *    \"This product includes software developed by the OpenSSL Project\n",
+" *    for use in the OpenSSL Toolkit (http://www.openssl.org/)\"\n",
+" *\n",
+" * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY\n",
+" * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n",
+" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n",
+" * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR\n",
+" * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n",
+" * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n",
+" * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n",
+" * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n",
+" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n",
+" * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n",
+" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n",
+" * OF THE POSSIBILITY OF SUCH DAMAGE.\n",
+" * ====================================================================\n",
+" *\n",
+" * This product includes cryptographic software written by Eric Young\n",
+" * (eay\@cryptsoft.com).  This product includes software written by Tim\n",
+" * Hudson (tjh\@cryptsoft.com).\n",
+" *\n",
+" */\n",
+"\n",
+"#ifndef HEADER_${lib}_ERR_H\n",
+"#define HEADER_${lib}_ERR_H\n",
+"\n",
+"#ifdef  __cplusplus\n",
+"extern \"C\" {\n",
+"#endif\n",
+"\n",
+"/* BEGIN ERROR CODES */\n";
+	}
+	open (OUT, ">$hfile") || die "Can't Open File $hfile for writing\n";
+
+	print OUT @out;
+	undef @out;
+	print OUT <<"EOF";
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+EOF
+	if($static) {
+		print OUT <<"EOF";
+${staticloader}void ERR_load_${lib}_strings(void);
+
+EOF
+	} else {
+		print OUT <<"EOF";
+${staticloader}void ERR_load_${lib}_strings(void);
+${staticloader}void ERR_unload_${lib}_strings(void);
+${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line);
+#define ${lib}err(f,r) ERR_${lib}_error((f),(r),__FILE__,__LINE__)
+
+EOF
+	}
+	print OUT <<"EOF";
+/* Error codes for the $lib functions. */
+
+/* Function codes. */
+EOF
+
+	foreach $i (@function) {
+		$z=6-int(length($i)/8);
+		if($fcodes{$i} eq "X") {
+			$fassigned{$lib} =~ m/^:([^:]*):/;
+			$findcode = $1;
+			if (!defined($findcode)) {
+				$findcode = $fmax{$lib};
+			}
+			while ($fassigned{$lib} =~ m/:$findcode:/) {
+				$findcode++;
+			}
+			$fcodes{$i} = $findcode;
+			$fassigned{$lib} .= "$findcode:";
+			print STDERR "New Function code $i\n" if $debug;
+		}
+		printf OUT "#define $i%s $fcodes{$i}\n","\t" x $z;
+	}
+
+	print OUT "\n/* Reason codes. */\n";
+
+	foreach $i (@reasons) {
+		$z=6-int(length($i)/8);
+		if($rcodes{$i} eq "X") {
+			$rassigned{$lib} =~ m/^:([^:]*):/;
+			$findcode = $1;
+			if (!defined($findcode)) {
+				$findcode = $rmax{$lib};
+			}
+			while ($rassigned{$lib} =~ m/:$findcode:/) {
+				$findcode++;
+			}
+			$rcodes{$i} = $findcode;
+			$rassigned{$lib} .= "$findcode:";
+			print STDERR "New Reason code   $i\n" if $debug;
+		}
+		printf OUT "#define $i%s $rcodes{$i}\n","\t" x $z;
+	}
+	print OUT <<"EOF";
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+EOF
+	close OUT;
+
+	# Rewrite the C source file containing the error details.
+
+	# First, read any existing reason string definitions:
+	my %err_reason_strings;
+	if (open(IN,"<$cfile")) {
+		while (<IN>) {
+			if (/\b(${lib}_R_\w*)\b.*\"(.*)\"/) {
+				$err_reason_strings{$1} = $2;
+			}
+			if (/\b${lib}_F_(\w*)\b.*\"(.*)\"/) {
+				if (!exists $ftrans{$1} && ($1 ne $2)) {
+					print STDERR "WARNING: Mismatched function string $2\n";
+					$ftrans{$1} = $2;
+				}
+			}
+		}
+		close(IN);
+	}
+
+
+	my $hincf;
+	if($static) {
+		$hfile =~ /([^\/]+)$/;
+		$hincf = "<${hprefix}$1>";
+	} else {
+		$hincf = "\"$hfile\"";
+	}
+
+	# If static we know the error code at compile time so use it
+	# in error definitions.
+
+	if ($static)
+		{
+		$pack_errcode = "ERR_LIB_${lib}";
+		$load_errcode = "0";
+		}
+	else
+		{
+		$pack_errcode = "0";
+		$load_errcode = "ERR_LIB_${lib}";
+		}
+
+
+	open (OUT,">$cfile") || die "Can't open $cfile for writing";
+
+	print OUT <<"EOF";
+/* $cfile */
+/* ====================================================================
+ * Copyright (c) 1999-2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core\@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay\@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh\@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include $hincf
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK($pack_errcode,func,0)
+#define ERR_REASON(reason) ERR_PACK($pack_errcode,0,reason)
+
+static ERR_STRING_DATA ${lib}_str_functs[]=
+	{
+EOF
+	# Add each function code: if a function name is found then use it.
+	foreach $i (@function) {
+		my $fn;
+		$i =~ /^${lib}_F_(\S+)$/;
+		$fn = $1;
+		if(exists $ftrans{$fn}) {
+			$fn = $ftrans{$fn};
+		}
+#		print OUT "{ERR_PACK($pack_errcode,$i,0),\t\"$fn\"},\n";
+		print OUT "{ERR_FUNC($i),\t\"$fn\"},\n";
+	}
+	print OUT <<"EOF";
+{0,NULL}
+	};
+
+static ERR_STRING_DATA ${lib}_str_reasons[]=
+	{
+EOF
+	# Add each reason code.
+	foreach $i (@reasons) {
+		my $rn;
+		my $rstr = "ERR_REASON($i)";
+		my $nspc = 0;
+		if (exists $err_reason_strings{$i}) {
+			$rn = $err_reason_strings{$i};
+		} else {
+			$i =~ /^${lib}_R_(\S+)$/;
+			$rn = $1;
+			$rn =~ tr/_[A-Z]/ [a-z]/;
+		}
+		$nspc = 40 - length($rstr) unless length($rstr) > 40;
+		$nspc = " " x $nspc;
+		print OUT "{${rstr}${nspc},\"$rn\"},\n";
+	}
+if($static) {
+	print OUT <<"EOF";
+{0,NULL}
+	};
+
+#endif
+
+${staticloader}void ERR_load_${lib}_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(${lib}_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings($load_errcode,${lib}_str_functs);
+		ERR_load_strings($load_errcode,${lib}_str_reasons);
+		}
+#endif
+	}
+EOF
+} else {
+	print OUT <<"EOF";
+{0,NULL}
+	};
+
+#endif
+
+#ifdef ${lib}_LIB_NAME
+static ERR_STRING_DATA ${lib}_lib_name[]=
+        {
+{0	,${lib}_LIB_NAME},
+{0,NULL}
+	};
+#endif
+
+
+static int ${lib}_lib_error_code=0;
+static int ${lib}_error_init=1;
+
+${staticloader}void ERR_load_${lib}_strings(void)
+	{
+	if (${lib}_lib_error_code == 0)
+		${lib}_lib_error_code=ERR_get_next_error_library();
+
+	if (${lib}_error_init)
+		{
+		${lib}_error_init=0;
+#ifndef OPENSSL_NO_ERR
+		ERR_load_strings(${lib}_lib_error_code,${lib}_str_functs);
+		ERR_load_strings(${lib}_lib_error_code,${lib}_str_reasons);
+#endif
+
+#ifdef ${lib}_LIB_NAME
+		${lib}_lib_name->error = ERR_PACK(${lib}_lib_error_code,0,0);
+		ERR_load_strings(0,${lib}_lib_name);
+#endif
+		}
+	}
+
+${staticloader}void ERR_unload_${lib}_strings(void)
+	{
+	if (${lib}_error_init == 0)
+		{
+#ifndef OPENSSL_NO_ERR
+		ERR_unload_strings(${lib}_lib_error_code,${lib}_str_functs);
+		ERR_unload_strings(${lib}_lib_error_code,${lib}_str_reasons);
+#endif
+
+#ifdef ${lib}_LIB_NAME
+		ERR_unload_strings(0,${lib}_lib_name);
+#endif
+		${lib}_error_init=1;
+		}
+	}
+
+${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line)
+	{
+	if (${lib}_lib_error_code == 0)
+		${lib}_lib_error_code=ERR_get_next_error_library();
+	ERR_PUT_error(${lib}_lib_error_code,function,reason,file,line);
+	}
+EOF
+
+}
+
+	close OUT;
+	undef %err_reason_strings;
+}
+
+if($debug && %notrans) {
+	print STDERR "The following function codes were not translated:\n";
+	foreach(sort keys %notrans)
+	{
+		print STDERR "$_\n";
+	}
+}
+
+# Make a list of unreferenced function and reason codes
+
+foreach (keys %fcodes) {
+	push (@funref, $_) unless exists $ufcodes{$_};
+}
+
+foreach (keys %rcodes) {
+	push (@runref, $_) unless exists $urcodes{$_};
+}
+
+if($debug && defined(@funref) ) {
+	print STDERR "The following function codes were not referenced:\n";
+	foreach(sort @funref)
+	{
+		print STDERR "$_\n";
+	}
+}
+
+if($debug && defined(@runref) ) {
+	print STDERR "The following reason codes were not referenced:\n";
+	foreach(sort @runref)
+	{
+		print STDERR "$_\n";
+	}
+}
+
+if($errcount) {
+	print STDERR "There were errors, failing...\n\n";
+	exit $errcount;
+}
+
diff --git a/openssl/util/mkfiles.pl b/openssl/util/mkfiles.pl
new file mode 100755
index 0000000..6d15831
--- /dev/null
+++ b/openssl/util/mkfiles.pl
@@ -0,0 +1,141 @@
+#!/usr/local/bin/perl
+#
+# This is a hacked version of files.pl for systems that can't do a 'make files'.
+# Do a perl util/mkminfo.pl >MINFO to build MINFO
+# Written by Steve Henson 1999.
+
+# List of directories to process
+
+my @dirs = (
+".",
+"crypto",
+"crypto/md2",
+"crypto/md4",
+"crypto/md5",
+"crypto/sha",
+"crypto/mdc2",
+"crypto/hmac",
+"crypto/ripemd",
+"crypto/des",
+"crypto/rc2",
+"crypto/rc4",
+"crypto/rc5",
+"crypto/idea",
+"crypto/bf",
+"crypto/cast",
+"crypto/aes",
+"crypto/camellia",
+"crypto/seed",
+"crypto/modes",
+"crypto/bn",
+"crypto/rsa",
+"crypto/dsa",
+"crypto/dso",
+"crypto/dh",
+"crypto/ec",
+"crypto/ecdh",
+"crypto/ecdsa",
+"crypto/buffer",
+"crypto/bio",
+"crypto/stack",
+"crypto/lhash",
+"crypto/rand",
+"crypto/err",
+"crypto/objects",
+"crypto/evp",
+"crypto/asn1",
+"crypto/pem",
+"crypto/x509",
+"crypto/x509v3",
+"crypto/cms",
+"crypto/conf",
+"crypto/jpake",
+"crypto/txt_db",
+"crypto/pkcs7",
+"crypto/pkcs12",
+"crypto/comp",
+"crypto/engine",
+"crypto/ocsp",
+"crypto/ui",
+"crypto/krb5",
+#"crypto/store",
+"crypto/pqueue",
+"crypto/whrlpool",
+"crypto/ts",
+"ssl",
+"apps",
+"engines",
+"engines/ccgost",
+"test",
+"tools"
+);
+
+%top;
+
+foreach (@dirs) {
+	&files_dir ($_, "Makefile");
+}
+
+exit(0);
+
+sub files_dir
+{
+my ($dir, $makefile) = @_;
+
+my %sym;
+
+open (IN, "$dir/$makefile") || die "Can't open $dir/$makefile";
+
+my $s="";
+
+while (<IN>)
+	{
+	chop;
+	s/#.*//;
+	if (/^(\S+)\s*=\s*(.*)$/)
+		{
+		$o="";
+		($s,$b)=($1,$2);
+		for (;;)
+			{
+			if ($b =~ /\\$/)
+				{
+				chop($b);
+				$o.=$b." ";
+				$b=<IN>;
+				chop($b);
+				}
+			else
+				{
+				$o.=$b." ";
+				last;
+				}
+			}
+		$o =~ s/^\s+//;
+		$o =~ s/\s+$//;
+		$o =~ s/\s+/ /g;
+
+		$o =~ s/\$[({]([^)}]+)[)}]/$top{$1} or $sym{$1}/ge;
+		$sym{$s}=($top{$s} or $o);
+		}
+	}
+
+print "RELATIVE_DIRECTORY=$dir\n";
+
+foreach (sort keys %sym)
+	{
+	print "$_=$sym{$_}\n";
+	}
+if ($dir eq "." && defined($sym{"BUILDENV"}))
+	{
+	foreach (split(' ',$sym{"BUILDENV"}))
+		{
+		/^(.+)=/;
+		$top{$1}=$sym{$1};
+		}
+	}
+
+print "RELATIVE_DIRECTORY=\n";
+
+close (IN);
+}
diff --git a/openssl/util/mklink.pl b/openssl/util/mklink.pl
new file mode 100755
index 0000000..61db12c
--- /dev/null
+++ b/openssl/util/mklink.pl
@@ -0,0 +1,73 @@
+#!/usr/local/bin/perl
+
+# mklink.pl
+
+# The first command line argument is a non-empty relative path
+# specifying the "from" directory.
+# Each other argument is a file name not containing / and
+# names a file in the current directory.
+#
+# For each of these files, we create in the "from" directory a link
+# of the same name pointing to the local file.
+#
+# We assume that the directory structure is a tree, i.e. that it does
+# not contain symbolic links and that the parent of / is never referenced.
+# Apart from this, this script should be able to handle even the most
+# pathological cases.
+
+use Cwd;
+
+my $from = shift;
+my @files = @ARGV;
+
+my @from_path = split(/[\\\/]/, $from);
+my $pwd = getcwd();
+chomp($pwd);
+my @pwd_path = split(/[\\\/]/, $pwd);
+
+my @to_path = ();
+
+my $dirname;
+foreach $dirname (@from_path) {
+
+    # In this loop, @to_path always is a relative path from
+    # @pwd_path (interpreted is an absolute path) to the original pwd.
+
+    # At the end, @from_path (as a relative path from the original pwd)
+    # designates the same directory as the absolute path @pwd_path,
+    # which means that @to_path then is a path from there to the original pwd.
+
+    next if ($dirname eq "" || $dirname eq ".");
+
+    if ($dirname eq "..") {
+	@to_path = (pop(@pwd_path), @to_path);
+    } else {
+	@to_path = ("..", @to_path);
+	push(@pwd_path, $dirname);
+    }
+}
+
+my $to = join('/', @to_path);
+
+my $file;
+$symlink_exists=eval {symlink("",""); 1};
+if ($^O eq "msys") { $symlink_exists=0 };
+foreach $file (@files) {
+    my $err = "";
+    if ($symlink_exists) {
+	unlink "$from/$file";
+	symlink("$to/$file", "$from/$file") or $err = " [$!]";
+    } else {
+	unlink "$from/$file"; 
+	open (OLD, "<$file") or die "Can't open $file: $!";
+	open (NEW, ">$from/$file") or die "Can't open $from/$file: $!";
+	binmode(OLD);
+	binmode(NEW);
+	while (<OLD>) {
+	    print NEW $_;
+	}
+	close (OLD) or die "Can't close $file: $!";
+	close (NEW) or die "Can't close $from/$file: $!";
+    }
+    print $file . " => $from/$file$err\n";
+}
diff --git a/openssl/util/mkrc.pl b/openssl/util/mkrc.pl
new file mode 100644
index 0000000..0ceadcf
--- /dev/null
+++ b/openssl/util/mkrc.pl
@@ -0,0 +1,71 @@
+#!/bin/env perl
+#
+open FD,"crypto/opensslv.h";
+while(<FD>) {
+    if (/OPENSSL_VERSION_NUMBER\s+(0x[0-9a-f]+)/i) {
+	$ver = hex($1);
+	$v1 = ($ver>>28);
+	$v2 = ($ver>>20)&0xff;
+	$v3 = ($ver>>12)&0xff;
+	$v4 = ($ver>> 4)&0xff;
+	$beta = $ver&0xf;
+	$version = "$v1.$v2.$v3";
+	if ($beta==0xf)	{ $version .= chr(ord('a')+$v4-1) if ($v4);	}
+	elsif ($beta==0){ $version .= "-dev";				}
+	else		{ $version .= "-beta$beta";			}
+	last;
+    }
+}
+close(FD);
+
+$filename = $ARGV[0]; $filename =~ /(.*)\.([^.]+)$/;
+$basename = $1;
+$extname  = $2;
+
+if ($extname =~ /dll/i)	{ $description = "OpenSSL shared library"; }
+else			{ $description = "OpenSSL application";    }
+
+print <<___;
+#include <winver.h>
+
+LANGUAGE 0x09,0x01
+
+1 VERSIONINFO
+  FILEVERSION $v1,$v2,$v3,$v4
+  PRODUCTVERSION $v1,$v2,$v3,$v4
+  FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+  FILEFLAGS 0x01L
+#else
+  FILEFLAGS 0x00L
+#endif
+  FILEOS VOS__WINDOWS32
+  FILETYPE VFT_DLL
+  FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            // Required:
+            VALUE "CompanyName", "The OpenSSL Project, http://www.openssl.org/\\0"
+            VALUE "FileDescription", "$description\\0"
+            VALUE "FileVersion", "$version\\0"
+            VALUE "InternalName", "$basename\\0"
+            VALUE "OriginalFilename", "$filename\\0"
+            VALUE "ProductName", "The OpenSSL Toolkit\\0"
+            VALUE "ProductVersion", "$version\\0"
+            // Optional:
+            //VALUE "Comments", "\\0"
+            VALUE "LegalCopyright", "Copyright © 1998-2006 The OpenSSL Project. Copyright © 1995-1998 Eric A. Young, Tim J. Hudson. All rights reserved.\\0"
+            //VALUE "LegalTrademarks", "\\0"
+            //VALUE "PrivateBuild", "\\0"
+            //VALUE "SpecialBuild", "\\0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 0x4b0
+    END
+END
+___
diff --git a/openssl/util/mkstack.pl b/openssl/util/mkstack.pl
new file mode 100755
index 0000000..f708610
--- /dev/null
+++ b/openssl/util/mkstack.pl
@@ -0,0 +1,192 @@
+#!/usr/local/bin/perl -w
+
+# This is a utility that searches out "DECLARE_STACK_OF()"
+# declarations in .h and .c files, and updates/creates/replaces
+# the corresponding macro declarations in crypto/stack/safestack.h.
+# As it's not generally possible to have macros that generate macros,
+# we need to control this from the "outside", here in this script.
+#
+# Geoff Thorpe, June, 2000 (with massive Perl-hacking
+#                           help from Steve Robb)
+
+my $safestack = "crypto/stack/safestack";
+
+my $do_write;
+while (@ARGV) {
+	my $arg = $ARGV[0];
+	if($arg eq "-write") {
+		$do_write = 1;
+	}
+	shift @ARGV;
+}
+
+
+@source = (<crypto/*.[ch]>, <crypto/*/*.[ch]>, <ssl/*.[ch]>, <apps/*.[ch]>);
+foreach $file (@source) {
+	next if -l $file;
+
+	# Open the .c/.h file for reading
+	open(IN, "< $file") || die "Can't open $file for reading: $!";
+
+	while(<IN>) {
+		if (/^DECLARE_STACK_OF\(([^)]+)\)/) {
+			push @stacklst, $1;
+		}
+	        if (/^DECLARE_SPECIAL_STACK_OF\(([^,\s]+)\s*,\s*([^>\s]+)\)/) {
+		    	push @sstacklst, [$1, $2];
+		}
+		if (/^DECLARE_ASN1_SET_OF\(([^)]+)\)/) {
+			push @asn1setlst, $1;
+		}
+		if (/^DECLARE_PKCS12_STACK_OF\(([^)]+)\)/) {
+			push @p12stklst, $1;
+		}
+		if (/^DECLARE_LHASH_OF\(([^)]+)\)/) {
+			push @lhashlst, $1;
+		}
+	}
+	close(IN);
+}
+
+
+
+my $old_stackfile = "";
+my $new_stackfile = "";
+my $inside_block = 0;
+my $type_thing;
+
+open(IN, "< $safestack.h") || die "Can't open input file: $!";
+while(<IN>) {
+	$old_stackfile .= $_;
+
+	if (m|^/\* This block of defines is updated by util/mkstack.pl, please do not touch! \*/|) {
+		$inside_block = 1;
+	}
+	if (m|^/\* End of util/mkstack.pl block, you may now edit :-\) \*/|) {
+		$inside_block = 0;
+	} elsif ($inside_block == 0) {
+		$new_stackfile .= $_;
+	}
+	next if($inside_block != 1);
+	$new_stackfile .= "/* This block of defines is updated by util/mkstack.pl, please do not touch! */";
+		
+	foreach $type_thing (sort @stacklst) {
+		$new_stackfile .= <<EOF;
+
+#define sk_${type_thing}_new(cmp) SKM_sk_new($type_thing, (cmp))
+#define sk_${type_thing}_new_null() SKM_sk_new_null($type_thing)
+#define sk_${type_thing}_free(st) SKM_sk_free($type_thing, (st))
+#define sk_${type_thing}_num(st) SKM_sk_num($type_thing, (st))
+#define sk_${type_thing}_value(st, i) SKM_sk_value($type_thing, (st), (i))
+#define sk_${type_thing}_set(st, i, val) SKM_sk_set($type_thing, (st), (i), (val))
+#define sk_${type_thing}_zero(st) SKM_sk_zero($type_thing, (st))
+#define sk_${type_thing}_push(st, val) SKM_sk_push($type_thing, (st), (val))
+#define sk_${type_thing}_unshift(st, val) SKM_sk_unshift($type_thing, (st), (val))
+#define sk_${type_thing}_find(st, val) SKM_sk_find($type_thing, (st), (val))
+#define sk_${type_thing}_find_ex(st, val) SKM_sk_find_ex($type_thing, (st), (val))
+#define sk_${type_thing}_delete(st, i) SKM_sk_delete($type_thing, (st), (i))
+#define sk_${type_thing}_delete_ptr(st, ptr) SKM_sk_delete_ptr($type_thing, (st), (ptr))
+#define sk_${type_thing}_insert(st, val, i) SKM_sk_insert($type_thing, (st), (val), (i))
+#define sk_${type_thing}_set_cmp_func(st, cmp) SKM_sk_set_cmp_func($type_thing, (st), (cmp))
+#define sk_${type_thing}_dup(st) SKM_sk_dup($type_thing, st)
+#define sk_${type_thing}_pop_free(st, free_func) SKM_sk_pop_free($type_thing, (st), (free_func))
+#define sk_${type_thing}_shift(st) SKM_sk_shift($type_thing, (st))
+#define sk_${type_thing}_pop(st) SKM_sk_pop($type_thing, (st))
+#define sk_${type_thing}_sort(st) SKM_sk_sort($type_thing, (st))
+#define sk_${type_thing}_is_sorted(st) SKM_sk_is_sorted($type_thing, (st))
+EOF
+	}
+
+	foreach $type_thing (sort @sstacklst) {
+	    my $t1 = $type_thing->[0];
+	    my $t2 = $type_thing->[1];
+	    $new_stackfile .= <<EOF;
+
+#define sk_${t1}_new(cmp) ((STACK_OF($t1) *)sk_new(CHECKED_SK_CMP_FUNC($t2, cmp)))
+#define sk_${t1}_new_null() ((STACK_OF($t1) *)sk_new_null())
+#define sk_${t1}_push(st, val) sk_push(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, val))
+#define sk_${t1}_find(st, val) sk_find(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, val))
+#define sk_${t1}_value(st, i) (($t1)sk_value(CHECKED_STACK_OF($t1, st), i))
+#define sk_${t1}_num(st) SKM_sk_num($t1, st)
+#define sk_${t1}_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF($t1, st), CHECKED_SK_FREE_FUNC2($t1, free_func))
+#define sk_${t1}_insert(st, val, i) sk_insert(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, val), i)
+#define sk_${t1}_free(st) SKM_sk_free(${t1}, st)
+#define sk_${t1}_set(st, i, val) sk_set(CHECKED_STACK_OF($t1, st), i, CHECKED_PTR_OF($t2, val))
+#define sk_${t1}_zero(st) SKM_sk_zero($t1, (st))
+#define sk_${t1}_unshift(st, val) sk_unshift(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, val))
+#define sk_${t1}_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF($t1), st), CHECKED_CONST_PTR_OF($t2, val))
+#define sk_${t1}_delete(st, i) SKM_sk_delete($t1, (st), (i))
+#define sk_${t1}_delete_ptr(st, ptr) ($t1 *)sk_delete_ptr(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, ptr))
+#define sk_${t1}_set_cmp_func(st, cmp)  \\
+	((int (*)(const $t2 * const *,const $t2 * const *)) \\
+	sk_set_cmp_func(CHECKED_STACK_OF($t1, st), CHECKED_SK_CMP_FUNC($t2, cmp)))
+#define sk_${t1}_dup(st) SKM_sk_dup($t1, st)
+#define sk_${t1}_shift(st) SKM_sk_shift($t1, (st))
+#define sk_${t1}_pop(st) ($t2 *)sk_pop(CHECKED_STACK_OF($t1, st))
+#define sk_${t1}_sort(st) SKM_sk_sort($t1, (st))
+#define sk_${t1}_is_sorted(st) SKM_sk_is_sorted($t1, (st))
+
+EOF
+	}
+
+	foreach $type_thing (sort @asn1setlst) {
+		$new_stackfile .= <<EOF;
+
+#define d2i_ASN1_SET_OF_${type_thing}(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \\
+	SKM_ASN1_SET_OF_d2i($type_thing, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_${type_thing}(st, pp, i2d_func, ex_tag, ex_class, is_set) \\
+	SKM_ASN1_SET_OF_i2d($type_thing, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_${type_thing}(st, i2d_func, buf, len) \\
+	SKM_ASN1_seq_pack($type_thing, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_${type_thing}(buf, len, d2i_func, free_func) \\
+	SKM_ASN1_seq_unpack($type_thing, (buf), (len), (d2i_func), (free_func))
+EOF
+	}
+	foreach $type_thing (sort @p12stklst) {
+		$new_stackfile .= <<EOF;
+
+#define PKCS12_decrypt_d2i_${type_thing}(algor, d2i_func, free_func, pass, passlen, oct, seq) \\
+	SKM_PKCS12_decrypt_d2i($type_thing, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
+EOF
+	}
+
+	foreach $type_thing (sort @lhashlst) {
+		my $lc_tt = lc $type_thing;
+		$new_stackfile .= <<EOF;
+
+#define lh_${type_thing}_new() LHM_lh_new(${type_thing},${lc_tt})
+#define lh_${type_thing}_insert(lh,inst) LHM_lh_insert(${type_thing},lh,inst)
+#define lh_${type_thing}_retrieve(lh,inst) LHM_lh_retrieve(${type_thing},lh,inst)
+#define lh_${type_thing}_delete(lh,inst) LHM_lh_delete(${type_thing},lh,inst)
+#define lh_${type_thing}_doall(lh,fn) LHM_lh_doall(${type_thing},lh,fn)
+#define lh_${type_thing}_doall_arg(lh,fn,arg_type,arg) \\
+  LHM_lh_doall_arg(${type_thing},lh,fn,arg_type,arg)
+#define lh_${type_thing}_error(lh) LHM_lh_error(${type_thing},lh)
+#define lh_${type_thing}_num_items(lh) LHM_lh_num_items(${type_thing},lh)
+#define lh_${type_thing}_down_load(lh) LHM_lh_down_load(${type_thing},lh)
+#define lh_${type_thing}_node_stats_bio(lh,out) \\
+  LHM_lh_node_stats_bio(${type_thing},lh,out)
+#define lh_${type_thing}_node_usage_stats_bio(lh,out) \\
+  LHM_lh_node_usage_stats_bio(${type_thing},lh,out)
+#define lh_${type_thing}_stats_bio(lh,out) \\
+  LHM_lh_stats_bio(${type_thing},lh,out)
+#define lh_${type_thing}_free(lh) LHM_lh_free(${type_thing},lh)
+EOF
+	}
+
+	$new_stackfile .= "/* End of util/mkstack.pl block, you may now edit :-) */\n";
+	$inside_block = 2;
+}
+
+
+if ($new_stackfile eq $old_stackfile) {
+	print "No changes to $safestack.h.\n";
+	exit 0; # avoid unnecessary rebuild
+}
+
+if ($do_write) {
+	print "Writing new $safestack.h.\n";
+	open OUT, ">$safestack.h" || die "Can't open output file";
+	print OUT $new_stackfile;
+	close OUT;
+}
diff --git a/openssl/util/opensslwrap.sh b/openssl/util/opensslwrap.sh
new file mode 100755
index 0000000..b27cbb8
--- /dev/null
+++ b/openssl/util/opensslwrap.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+HERE="`echo $0 | sed -e 's|[^/]*$||'`"
+OPENSSL="${HERE}../apps/openssl"
+
+if [ -d "${HERE}../engines" -a "x$OPENSSL_ENGINES" = "x" ]; then
+	OPENSSL_ENGINES="${HERE}../engines"; export OPENSSL_ENGINES
+fi
+
+if [ -x "${OPENSSL}.exe" ]; then
+	# The original reason for this script existence is to work around
+	# certain caveats in run-time linker behaviour. On Windows platforms
+	# adjusting $PATH used to be sufficient, but with introduction of
+	# SafeDllSearchMode in XP/2003 the only way to get it right in
+	# *all* possible situations is to copy newly built .DLLs to apps/
+	# and test/, which is now done elsewhere... The $PATH is adjusted
+	# for backward compatibility (and nostagical reasons:-).
+	if [ "$OSTYPE" != msdosdjgpp ]; then
+		PATH="${HERE}..:$PATH"; export PATH
+	fi
+	exec "${OPENSSL}.exe" "$@"
+elif [ -x "${OPENSSL}" -a -x "${HERE}shlib_wrap.sh" ]; then
+	exec "${HERE}shlib_wrap.sh" "${OPENSSL}" "$@"
+else
+	exec "${OPENSSL}" "$@"	# hope for the best...
+fi
diff --git a/openssl/util/perlpath.pl b/openssl/util/perlpath.pl
new file mode 100755
index 0000000..a1f236b
--- /dev/null
+++ b/openssl/util/perlpath.pl
@@ -0,0 +1,35 @@
+#!/usr/local/bin/perl
+#
+# modify the '#!/usr/local/bin/perl'
+# line in all scripts that rely on perl.
+#
+
+require "find.pl";
+
+$#ARGV == 0 || print STDERR "usage: perlpath newpath  (eg /usr/bin)\n";
+&find(".");
+
+sub wanted
+	{
+	return unless /\.pl$/ || /^[Cc]onfigur/;
+
+	open(IN,"<$_") || die "unable to open $dir/$_:$!\n";
+	@a=<IN>;
+	close(IN);
+
+	if (-d $ARGV[0]) {
+		$a[0]="#!$ARGV[0]/perl\n";
+	}
+	else {
+		$a[0]="#!$ARGV[0]\n";
+	}
+
+	# Playing it safe...
+	$new="$_.new";
+	open(OUT,">$new") || die "unable to open $dir/$new:$!\n";
+	print OUT @a;
+	close(OUT);
+
+	rename($new,$_) || die "unable to rename $dir/$new:$!\n";
+	chmod(0755,$_) || die "unable to chmod $dir/$new:$!\n";
+	}
diff --git a/openssl/util/pl/BC-32.pl b/openssl/util/pl/BC-32.pl
new file mode 100644
index 0000000..1f1e13f
--- /dev/null
+++ b/openssl/util/pl/BC-32.pl
@@ -0,0 +1,139 @@
+#!/usr/local/bin/perl
+# Borland C++ builder 3 and 4 -- Janez Jere <jj@void.si>
+#
+
+$ssl=	"ssleay32";
+$crypto="libeay32";
+
+$o='\\';
+$cp='copy';
+$rm='del';
+
+# C compiler stuff
+$cc='bcc32';
+$lflags="-ap -Tpe -x -Gn ";
+$mlflags='';
+
+$out_def="out32";
+$tmp_def="tmp32";
+$inc_def="inc32";
+#enable max error messages, disable most common warnings
+$cflags="-DWIN32_LEAN_AND_MEAN -q -w-ccc -w-rch -w-pia -w-aus -w-par -w-inl  -c -tWC -tWM -DOPENSSL_SYSNAME_WIN32 -DL_ENDIAN -DDSO_WIN32 -D_stricmp=stricmp -D_strnicmp=strnicmp ";
+if ($debug)
+{
+    $cflags.="-Od -y -v -vi- -D_DEBUG";
+    $mlflags.=' ';
+}
+else
+{
+    $cflags.="-O2 -ff -fp";
+}
+
+$obj='.obj';
+$ofile="-o";
+
+# EXE linking stuff
+$link="ilink32";
+$efile="";
+$exep='.exe';
+if ($no_sock)
+	{ $ex_libs=""; }
+else	{ $ex_libs="cw32mt.lib import32.lib"; }
+
+# static library stuff
+$mklib='tlib /P64';
+$ranlib='';
+$plib="";
+$libp=".lib";
+$shlibp=($shlib)?".dll":".lib";
+$lfile='';
+
+$shlib_ex_obj="";
+$app_ex_obj="c0x32.obj"; 
+
+$asm='nasmw -f obj -d__omf__';
+$asm.=" /Zi" if $debug;
+$afile='-o';
+
+$bn_mulw_obj='';
+$bn_mulw_src='';
+$des_enc_obj='';
+$des_enc_src='';
+$bf_enc_obj='';
+$bf_enc_src='';
+
+if (!$no_asm)
+	{
+	$bn_mulw_obj='crypto\bn\asm\bn_win32.obj';
+	$bn_mulw_src='crypto\bn\asm\bn_win32.asm';
+	$des_enc_obj='crypto\des\asm\d_win32.obj crypto\des\asm\y_win32.obj';
+	$des_enc_src='crypto\des\asm\d_win32.asm crypto\des\asm\y_win32.asm';
+	$bf_enc_obj='crypto\bf\asm\b_win32.obj';
+	$bf_enc_src='crypto\bf\asm\b_win32.asm';
+	$cast_enc_obj='crypto\cast\asm\c_win32.obj';
+	$cast_enc_src='crypto\cast\asm\c_win32.asm';
+	$rc4_enc_obj='crypto\rc4\asm\r4_win32.obj';
+	$rc4_enc_src='crypto\rc4\asm\r4_win32.asm';
+	$rc5_enc_obj='crypto\rc5\asm\r5_win32.obj';
+	$rc5_enc_src='crypto\rc5\asm\r5_win32.asm';
+	$md5_asm_obj='crypto\md5\asm\m5_win32.obj';
+	$md5_asm_src='crypto\md5\asm\m5_win32.asm';
+	$sha1_asm_obj='crypto\sha\asm\s1_win32.obj';
+	$sha1_asm_src='crypto\sha\asm\s1_win32.asm';
+	$rmd160_asm_obj='crypto\ripemd\asm\rm_win32.obj';
+	$rmd160_asm_src='crypto\ripemd\asm\rm_win32.asm';
+	$cflags.=" -DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM";
+	}
+
+if ($shlib)
+	{
+	$mlflags.=" $lflags /dll";
+#	$cflags =~ s| /MD| /MT|;
+	$lib_cflag=" /GD -D_WINDLL -D_DLL";
+	$out_def="out32dll";
+	$tmp_def="tmp32dll";
+	}
+
+sub do_lib_rule
+	{
+	local($objs,$target,$name,$shlib)=@_;
+	local($ret,$Name);
+
+	$taget =~ s/\//$o/g if $o ne '/';
+	($Name=$name) =~ tr/a-z/A-Z/;
+
+#	$target="\$(LIB_D)$o$target";
+	$ret.="$target: $objs\n";
+	if (!$shlib)
+		{
+		$ret.=<<___;
+	-\$(RM) $lfile$target
+	\$(MKLIB) $lfile$target \@&&!
++\$(**: = &^
++)
+!
+___
+		}
+	else
+		{
+		local($ex)=($target =~ /O_SSL/)?' $(L_CRYPTO)':'';
+		$ex.=' ws2_32.lib gdi32.lib';
+		$ret.="\t\$(LINK) \$(MLFLAGS) $efile$target /def:ms/${Name}.def @<<\n  \$(SHLIB_EX_OBJ) $objs $ex\n<<\n";
+		}
+	$ret.="\n";
+	return($ret);
+	}
+
+sub do_link_rule
+	{
+	local($target,$files,$dep_libs,$libs)=@_;
+	local($ret,$_);
+	
+	$file =~ s/\//$o/g if $o ne '/';
+	$n=&bname($targer);
+	$ret.="$target: $files $dep_libs\n";
+	$ret.="\t\$(LINK) \$(LFLAGS) $files \$(APP_EX_OBJ), $target,, $libs\n\n";
+	return($ret);
+	}
+
+1;
diff --git a/openssl/util/pl/Mingw32.pl b/openssl/util/pl/Mingw32.pl
new file mode 100644
index 0000000..fe3fb27
--- /dev/null
+++ b/openssl/util/pl/Mingw32.pl
@@ -0,0 +1,104 @@
+#!/usr/local/bin/perl
+#
+# Mingw32.pl -- Mingw
+#
+
+$o='/';
+$cp='cp';
+$rm='rm -f';
+$mkdir='gmkdir';
+
+$o='\\';
+$cp='copy';
+$rm='del';
+$mkdir='mkdir';
+
+# C compiler stuff
+
+$cc='gcc';
+if ($debug)
+	{ $cflags="-DL_ENDIAN -DDSO_WIN32 -g2 -ggdb"; }
+else
+	{ $cflags="-DL_ENDIAN -DDSO_WIN32 -fomit-frame-pointer -O3 -mcpu=i486 -Wall"; }
+
+if ($gaswin and !$no_asm)
+	{
+        $bn_asm_obj='$(OBJ_D)\bn-win32.o';
+        $bn_asm_src='crypto/bn/asm/bn-win32.s';
+        $bnco_asm_obj='$(OBJ_D)\co-win32.o';
+        $bnco_asm_src='crypto/bn/asm/co-win32.s';
+        $des_enc_obj='$(OBJ_D)\d-win32.o $(OBJ_D)\y-win32.o';
+        $des_enc_src='crypto/des/asm/d-win32.s crypto/des/asm/y-win32.s';
+        $bf_enc_obj='$(OBJ_D)\b-win32.o';
+        $bf_enc_src='crypto/bf/asm/b-win32.s';
+#       $cast_enc_obj='$(OBJ_D)\c-win32.o';
+#       $cast_enc_src='crypto/cast/asm/c-win32.s';
+        $rc4_enc_obj='$(OBJ_D)\r4-win32.o';
+        $rc4_enc_src='crypto/rc4/asm/r4-win32.s';
+        $rc5_enc_obj='$(OBJ_D)\r5-win32.o';
+        $rc5_enc_src='crypto/rc5/asm/r5-win32.s';
+        $md5_asm_obj='$(OBJ_D)\m5-win32.o';
+        $md5_asm_src='crypto/md5/asm/m5-win32.s';
+        $rmd160_asm_obj='$(OBJ_D)\rm-win32.o';
+        $rmd160_asm_src='crypto/ripemd/asm/rm-win32.s';
+        $sha1_asm_obj='$(OBJ_D)\s1-win32.o';
+        $sha1_asm_src='crypto/sha/asm/s1-win32.s';
+	$cflags.=" -DBN_ASM -DMD5_ASM -DSHA1_ASM -DOPENSSL_BN_ASM_PART_WORDS";
+	}
+
+
+$obj='.o';
+$ofile='-o ';
+
+# EXE linking stuff
+$link='${CC}';
+$lflags='${CFLAGS}';
+$efile='-o ';
+$exep='';
+$ex_libs="-lws2_32 -lgdi32";
+
+# static library stuff
+$mklib='ar r';
+$mlflags='';
+$ranlib='ranlib';
+$plib='lib';
+$libp=".a";
+$shlibp=".a";
+$lfile='';
+
+$asm='as';
+$afile='-o ';
+#$bn_asm_obj="";
+#$bn_asm_src="";
+#$des_enc_obj="";
+#$des_enc_src="";
+#$bf_enc_obj="";
+#$bf_enc_src="";
+
+sub do_lib_rule
+	{
+	local($obj,$target,$name,$shlib)=@_;
+	local($ret,$_,$Name);
+
+	$target =~ s/\//$o/g if $o ne '/';
+	$target="$target";
+	($Name=$name) =~ tr/a-z/A-Z/;
+
+	$ret.="$target: \$(${Name}OBJ)\n";
+	$ret.="\tif exist $target \$(RM) $target\n";
+	$ret.="\t\$(MKLIB) $target \$(${Name}OBJ)\n";
+	$ret.="\t\$(RANLIB) $target\n\n";
+	}
+
+sub do_link_rule
+	{
+	local($target,$files,$dep_libs,$libs)=@_;
+	local($ret,$_);
+	
+	$file =~ s/\//$o/g if $o ne '/';
+	$n=&bname($target);
+	$ret.="$target: $files $dep_libs\n";
+	$ret.="\t\$(LINK) ${efile}$target \$(LFLAGS) $files $libs\n\n";
+	return($ret);
+	}
+1;
diff --git a/openssl/util/pl/OS2-EMX.pl b/openssl/util/pl/OS2-EMX.pl
new file mode 100644
index 0000000..28cd116
--- /dev/null
+++ b/openssl/util/pl/OS2-EMX.pl
@@ -0,0 +1,120 @@
+#!/usr/local/bin/perl
+#
+# OS2-EMX.pl - for EMX GCC on OS/2
+#
+
+$o='/';
+$cp='cp';
+$rm='rm -f';
+
+$preamble = "SHELL=sh\n";
+
+# C compiler stuff
+
+$cc='gcc';
+$cflags="-DL_ENDIAN -O3 -fomit-frame-pointer -m486 -Zmtd -Wall ";
+$cflags.="-Zomf " if $shlib;
+$shl_cflag="-Zdll";
+
+if ($debug) { 
+	$cflags.="-g "; 
+}
+
+$obj=$shlib ? '.obj' : '.o';
+$ofile='-o ';
+
+# EXE linking stuff
+$link='${CC}';
+$lflags='${CFLAGS} -Zbsd-signals -s';
+$efile='-o ';
+$exep='.exe';
+$ex_libs="-lsocket";
+
+# static library stuff
+$mklib='ar r';
+$mlflags='';
+$ranlib="ar s";
+$plib='';
+$libp=$shlib ? ".lib" : ".a";
+$shlibp=$shlib ? ".dll" : ".a";
+$lfile='';
+
+$asm=$shlib ? 'as -Zomf' : 'as';
+$afile='-o ';
+$bn_asm_obj="";
+$bn_asm_src="";
+$des_enc_obj="";
+$des_enc_src="";
+$bf_enc_obj="";
+$bf_enc_src="";
+
+if (!$no_asm)
+	{
+	$bn_asm_obj="crypto/bn/asm/bn-os2$obj crypto/bn/asm/co-os2$obj";
+	$bn_asm_src="crypto/bn/asm/bn-os2.asm crypto/bn/asm/co-os2.asm";
+	$des_enc_obj="crypto/des/asm/d-os2$obj crypto/des/asm/y-os2$obj";
+	$des_enc_src="crypto/des/asm/d-os2.asm crypto/des/asm/y-os2.asm";
+	$bf_enc_obj="crypto/bf/asm/b-os2$obj";
+	$bf_enc_src="crypto/bf/asm/b-os2.asm";
+	$cast_enc_obj="crypto/cast/asm/c-os2$obj";
+	$cast_enc_src="crypto/cast/asm/c-os2.asm";
+	$rc4_enc_obj="crypto/rc4/asm/r4-os2$obj";
+	$rc4_enc_src="crypto/rc4/asm/r4-os2.asm";
+	$rc5_enc_obj="crypto/rc5/asm/r5-os2$obj";
+	$rc5_enc_src="crypto/rc5/asm/r5-os2.asm";
+	$md5_asm_obj="crypto/md5/asm/m5-os2$obj";
+	$md5_asm_src="crypto/md5/asm/m5-os2.asm";
+	$sha1_asm_obj="crypto/sha/asm/s1-os2$obj";
+	$sha1_asm_src="crypto/sha/asm/s1-os2.asm";
+	$rmd160_asm_obj="crypto/ripemd/asm/rm-os2$obj";
+	$rmd160_asm_src="crypto/ripemd/asm/rm-os2.asm";
+	$cflags.=" -DBN_ASM -DMD5_ASM -DSHA1_ASM -DOPENSSL_BN_ASM_PART_WORDS";
+	}
+
+if ($shlib)
+	{
+	$mlflags.=" $lflags -Zdll";
+	$lib_cflag=" -D_DLL";
+	$out_def="out_dll";
+	$tmp_def="tmp_dll";
+	}
+
+sub do_lib_rule
+	{
+	local($obj,$target,$name,$shlib)=@_;
+	local($ret,$_,$Name);
+
+	$target =~ s/\//$o/g if $o ne '/';
+	$target="$target";
+	($Name=$name) =~ tr/a-z/A-Z/;
+
+	$ret.="$target: \$(${Name}OBJ)\n";
+	if (!$shlib) 
+		{
+		$ret.="\t\$(RM) $target\n";
+		$ret.="\t\$(MKLIB) $target \$(${Name}OBJ)\n";
+		$ret.="\t\$(RANLIB) $target\n\n";
+		}
+	else
+		{
+		local($ex)=($target =~ /O_SSL/)?' $(L_CRYPTO)':'';
+		$ex.=' -lsocket';
+		$ret.="\t\$(LINK) \$(SHLIB_CFLAGS) \$(MLFLAGS) $efile$target \$(SHLIB_EX_OBJ) \$(${Name}OBJ) $ex os2/${Name}.def\n";
+		$ret.="\temximp -o $out_def/$name.a os2/${Name}.def\n";
+		$ret.="\temximp -o $out_def/$name.lib os2/${Name}.def\n\n";
+		}
+	}
+
+sub do_link_rule
+	{
+	local($target,$files,$dep_libs,$libs)=@_;
+	local($ret,$_);
+	
+	$file =~ s/\//$o/g if $o ne '/';
+	$n=&bname($target);
+	$ret.="$target: $files $dep_libs\n";
+	$ret.="\t\$(LINK) ${efile}$target \$(CFLAG) \$(LFLAGS) $files $libs\n\n";
+	return($ret);
+	}
+
+1;
diff --git a/openssl/util/pl/VC-32.pl b/openssl/util/pl/VC-32.pl
new file mode 100644
index 0000000..5f25fc4
--- /dev/null
+++ b/openssl/util/pl/VC-32.pl
@@ -0,0 +1,338 @@
+#!/usr/local/bin/perl
+# VC-32.pl - unified script for Microsoft Visual C++, covering Win32,
+# Win64 and WinCE [follow $FLAVOR variable to trace the differences].
+#
+
+$ssl=	"ssleay32";
+$crypto="libeay32";
+
+$o='\\';
+$cp='$(PERL) util/copy.pl';
+$mkdir='$(PERL) util/mkdir-p.pl';
+$rm='del /Q';
+
+$zlib_lib="zlib1.lib";
+
+# Santize -L options for ms link
+$l_flags =~ s/-L("\[^"]+")/\/libpath:$1/g;
+$l_flags =~ s/-L(\S+)/\/libpath:$1/g;
+
+# C compiler stuff
+$cc='cl';
+if ($FLAVOR =~ /WIN64/)
+    {
+    # Note that we currently don't have /WX on Win64! There is a lot of
+    # warnings, but only of two types:
+    #
+    # C4344: conversion from '__int64' to 'int/long', possible loss of data
+    # C4267: conversion from 'size_t' to 'int/long', possible loss of data
+    #
+    # Amount of latter type is minimized by aliasing strlen to function of
+    # own desing and limiting its return value to 2GB-1 (see e_os.h). As
+    # per 0.9.8 release remaining warnings were explicitly examined and
+    # considered safe to ignore.
+    # 
+    $base_cflags= " $mf_cflag";
+    my $f = $shlib?' /MD':' /MT';
+    $lib_cflag='/Zl' if (!$shlib);	# remove /DEFAULTLIBs from static lib
+    $opt_cflags=$f.' /Ox';
+    $dbg_cflags=$f.'d /Od -DDEBUG -D_DEBUG';
+    $lflags="/nologo /subsystem:console /opt:ref";
+
+    *::perlasm_compile_target = sub {
+	my ($target,$source,$bname)=@_;
+	my $ret;
+
+	$bname =~ s/(.*)\.[^\.]$/$1/;
+	$ret=<<___;
+\$(TMP_D)$o$bname.asm: $source
+	set ASM=\$(ASM)
+	\$(PERL) $source \$\@
+
+$target: \$(TMP_D)$o$bname.asm
+	\$(ASM) $afile\$\@ \$(TMP_D)$o$bname.asm
+
+___
+	}
+    }
+elsif ($FLAVOR =~ /CE/)
+    {
+    # sanity check
+    die '%OSVERSION% is not defined'	if (!defined($ENV{'OSVERSION'}));
+    die '%PLATFORM% is not defined'	if (!defined($ENV{'PLATFORM'}));
+    die '%TARGETCPU% is not defined'	if (!defined($ENV{'TARGETCPU'}));
+
+    #
+    # Idea behind this is to mimic flags set by eVC++ IDE...
+    #
+    $wcevers = $ENV{'OSVERSION'};			# WCENNN
+    die '%OSVERSION% value is insane'	if ($wcevers !~ /^WCE([1-9])([0-9]{2})$/);
+    $wcecdefs = "-D_WIN32_WCE=$1$2 -DUNDER_CE=$1$2";	# -D_WIN32_WCE=NNN
+    $wcelflag = "/subsystem:windowsce,$1.$2";		# ...,N.NN
+
+    $wceplatf =  $ENV{'PLATFORM'};
+    $wceplatf =~ tr/a-z0-9 /A-Z0-9_/d;
+    $wcecdefs .= " -DWCE_PLATFORM_$wceplatf";
+
+    $wcetgt = $ENV{'TARGETCPU'};	# just shorter name...
+    SWITCH: for($wcetgt) {
+	/^X86/		&& do {	$wcecdefs.=" -Dx86 -D_X86_ -D_i386_ -Di_386_";
+				$wcelflag.=" /machine:IX86";	last; };
+	/^ARMV4[IT]/	&& do { $wcecdefs.=" -DARM -D_ARM_ -D$wcetgt";
+				$wcecdefs.=" -DTHUMB -D_THUMB_" if($wcetgt=~/T$/);
+				$wcecdefs.=" -QRarch4T -QRinterwork-return";
+				$wcelflag.=" /machine:THUMB";	last; };
+	/^ARM/		&& do {	$wcecdefs.=" -DARM -D_ARM_ -D$wcetgt";
+				$wcelflag.=" /machine:ARM";	last; };
+	/^MIPSIV/	&& do {	$wcecdefs.=" -DMIPS -D_MIPS_ -DR4000 -D$wcetgt";
+				$wcecdefs.=" -D_MIPS64 -QMmips4 -QMn32";
+				$wcelflag.=" /machine:MIPSFPU";	last; };
+	/^MIPS16/	&& do {	$wcecdefs.=" -DMIPS -D_MIPS_ -DR4000 -D$wcetgt";
+				$wcecdefs.=" -DMIPSII -QMmips16";
+				$wcelflag.=" /machine:MIPS16";	last; };
+	/^MIPSII/	&& do {	$wcecdefs.=" -DMIPS -D_MIPS_ -DR4000 -D$wcetgt";
+				$wcecdefs.=" -QMmips2";
+				$wcelflag.=" /machine:MIPS";	last; };
+	/^R4[0-9]{3}/	&& do {	$wcecdefs.=" -DMIPS -D_MIPS_ -DR4000";
+				$wcelflag.=" /machine:MIPS";	last; };
+	/^SH[0-9]/	&& do {	$wcecdefs.=" -D$wcetgt -D_$wcetgt_ -DSHx";
+				$wcecdefs.=" -Qsh4" if ($wcetgt =~ /^SH4/);
+				$wcelflag.=" /machine:$wcetgt";	last; };
+	{ $wcecdefs.=" -D$wcetgt -D_$wcetgt_";
+	  $wcelflag.=" /machine:$wcetgt";			last; };
+    }
+
+    $cc='$(CC)';
+    $base_cflags=' /W3 /WX /GF /Gy /nologo -DUNICODE -D_UNICODE -DOPENSSL_SYSNAME_WINCE -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DDSO_WIN32 -DNO_CHMOD -DOPENSSL_SMALL_FOOTPRINT';
+    $base_cflags.=" $wcecdefs";
+    $base_cflags.=' -I$(WCECOMPAT)/include'		if (defined($ENV{'WCECOMPAT'}));
+    $base_cflags.=' -I$(PORTSDK_LIBPATH)/../../include'	if (defined($ENV{'PORTSDK_LIBPATH'}));
+    $opt_cflags=' /MC /O1i';	# optimize for space, but with intrinsics...
+    $dbg_clfags=' /MC /Od -DDEBUG -D_DEBUG';
+    $lflags="/nologo /opt:ref $wcelflag";
+    }
+else	# Win32
+    {
+    $base_cflags= " $mf_cflag";
+    my $f = $shlib?' /MD':' /MT';
+    $lib_cflag='/Zl' if (!$shlib);	# remove /DEFAULTLIBs from static lib
+    $opt_cflags=$f.' /Ox /O2 /Ob2';
+    $dbg_cflags=$f.'d /Od -DDEBUG -D_DEBUG';
+    $lflags="/nologo /subsystem:console /opt:ref";
+    }
+$mlflags='';
+
+$out_def ="out32";	$out_def.="dll"			if ($shlib);
+			$out_def.='_$(TARGETCPU)'	if ($FLAVOR =~ /CE/);
+$tmp_def ="tmp32";	$tmp_def.="dll"			if ($shlib);
+			$tmp_def.='_$(TARGETCPU)'	if ($FLAVOR =~ /CE/);
+$inc_def="inc32";
+
+if ($debug)
+	{
+	$cflags=$dbg_cflags.$base_cflags;
+	}
+else
+	{
+	$cflags=$opt_cflags.$base_cflags;
+	}
+
+# generate symbols.pdb unconditionally
+$app_cflag.=" /Zi /Fd\$(TMP_D)/app";
+$lib_cflag.=" /Zi /Fd\$(TMP_D)/lib";
+$lflags.=" /debug";
+
+$obj='.obj';
+$asm_suffix='.asm';
+$ofile="/Fo";
+
+# EXE linking stuff
+$link="link";
+$rsc="rc";
+$efile="/out:";
+$exep='.exe';
+if ($no_sock)		{ $ex_libs=''; }
+elsif ($FLAVOR =~ /CE/)	{ $ex_libs='winsock.lib'; }
+else			{ $ex_libs='ws2_32.lib'; }
+
+if ($FLAVOR =~ /CE/)
+	{
+	$ex_libs.=' $(WCECOMPAT)/lib/wcecompatex.lib'	if (defined($ENV{'WCECOMPAT'}));
+	$ex_libs.=' $(PORTSDK_LIBPATH)/portlib.lib'	if (defined($ENV{'PORTSDK_LIBPATH'}));
+	$ex_libs.=' /nodefaultlib:oldnames.lib coredll.lib corelibc.lib' if ($ENV{'TARGETCPU'} eq "X86");
+	}
+else
+	{
+	$ex_libs.=' gdi32.lib advapi32.lib crypt32.lib user32.lib';
+	$ex_libs.=' bufferoverflowu.lib' if ($FLAVOR =~ /WIN64/ and `cl 2>&1` =~ /14\.00\.4[0-9]{4}\./);
+	# WIN32 UNICODE build gets linked with unicows.lib for
+	# backward compatibility with Win9x.
+	$ex_libs="unicows.lib $ex_libs" if ($FLAVOR =~ /WIN32/ and $cflags =~ /\-DUNICODE/);
+	}
+
+# static library stuff
+$mklib='lib /nologo';
+$ranlib='';
+$plib="";
+$libp=".lib";
+$shlibp=($shlib)?".dll":".lib";
+$lfile='/out:';
+
+$shlib_ex_obj="";
+$app_ex_obj="setargv.obj" if ($FLAVOR !~ /CE/);
+if ($FLAVOR =~ /WIN64A/) {
+	if (`nasm -v 2>NUL` =~ /NASM version ([0-9]+\.[0-9]+)/ && $1 >= 2.0) {
+		$asm='nasm -f win64 -DNEAR -Ox -g';
+		$afile='-o ';
+	} else {
+		$asm='ml64 /c /Cp /Cx /Zi';
+		$afile='/Fo';
+	}
+} elsif ($FLAVOR =~ /WIN64I/) {
+	$asm='ias -d debug';
+	$afile="-o ";
+} elsif ($nasm) {
+	my $ver=`nasm -v 2>NUL`;
+	my $vew=`nasmw -v 2>NUL`;
+	# pick newest version
+	$asm=($ver ge $vew?"nasm":"nasmw")." -f win32";
+	$asmtype="win32n";
+	$afile='-o ';
+} else {
+	$asm='ml /nologo /Cp /coff /c /Cx /Zi';
+	$afile='/Fo';
+	$asmtype="win32";
+}
+
+$bn_asm_obj='';
+$bn_asm_src='';
+$des_enc_obj='';
+$des_enc_src='';
+$bf_enc_obj='';
+$bf_enc_src='';
+
+if (!$no_asm)
+	{
+	win32_import_asm($mf_bn_asm, "bn", \$bn_asm_obj, \$bn_asm_src);
+	win32_import_asm($mf_aes_asm, "aes", \$aes_asm_obj, \$aes_asm_src);
+	win32_import_asm($mf_des_asm, "des", \$des_enc_obj, \$des_enc_src);
+	win32_import_asm($mf_bf_asm, "bf", \$bf_enc_obj, \$bf_enc_src);
+	win32_import_asm($mf_cast_asm, "cast", \$cast_enc_obj, \$cast_enc_src);
+	win32_import_asm($mf_rc4_asm, "rc4", \$rc4_enc_obj, \$rc4_enc_src);
+	win32_import_asm($mf_rc5_asm, "rc5", \$rc5_enc_obj, \$rc5_enc_src);
+	win32_import_asm($mf_md5_asm, "md5", \$md5_asm_obj, \$md5_asm_src);
+	win32_import_asm($mf_sha_asm, "sha", \$sha1_asm_obj, \$sha1_asm_src);
+	win32_import_asm($mf_rmd_asm, "ripemd", \$rmd160_asm_obj, \$rmd160_asm_src);
+	win32_import_asm($mf_wp_asm, "whrlpool", \$whirlpool_asm_obj, \$whirlpool_asm_src);
+	win32_import_asm($mf_cpuid_asm, "", \$cpuid_asm_obj, \$cpuid_asm_src);
+	$perl_asm = 1;
+	}
+
+if ($shlib && $FLAVOR !~ /CE/)
+	{
+	$mlflags.=" $lflags /dll";
+	$lib_cflag.=" -D_WINDLL";
+	#
+	# Engage Applink...
+	#
+	$app_ex_obj.=" \$(OBJ_D)\\applink.obj /implib:\$(TMP_D)\\junk.lib";
+	$cflags.=" -DOPENSSL_USE_APPLINK -I.";
+	# I'm open for better suggestions than overriding $banner...
+	$banner=<<'___';
+	@echo Building OpenSSL
+
+$(OBJ_D)\applink.obj:	ms\applink.c
+	$(CC) /Fo$(OBJ_D)\applink.obj $(APP_CFLAGS) -c ms\applink.c
+$(OBJ_D)\uplink.obj:	ms\uplink.c ms\applink.c
+	$(CC) /Fo$(OBJ_D)\uplink.obj $(SHLIB_CFLAGS) -c ms\uplink.c
+$(INCO_D)\applink.c:	ms\applink.c
+	$(CP) ms\applink.c $(INCO_D)\applink.c
+
+EXHEADER= $(EXHEADER) $(INCO_D)\applink.c
+
+LIBS_DEP=$(LIBS_DEP) $(OBJ_D)\applink.obj
+CRYPTOOBJ=$(OBJ_D)\uplink.obj $(CRYPTOOBJ)
+___
+	$banner.=<<'___' if ($FLAVOR =~ /WIN64/);
+CRYPTOOBJ=ms\uptable.obj $(CRYPTOOBJ)
+___
+	}
+elsif ($shlib && $FLAVOR =~ /CE/)
+	{
+	$mlflags.=" $lflags /dll";
+	$lflags.=' /entry:mainCRTstartup' if(defined($ENV{'PORTSDK_LIBPATH'}));
+	$lib_cflag.=" -D_WINDLL -D_DLL";
+	}
+
+sub do_lib_rule
+	{
+	local($objs,$target,$name,$shlib)=@_;
+	local($ret);
+
+	$taget =~ s/\//$o/g if $o ne '/';
+	if ($name ne "")
+		{
+		$name =~ tr/a-z/A-Z/;
+		$name = "/def:ms/${name}.def";
+		}
+
+#	$target="\$(LIB_D)$o$target";
+	$ret.="$target: $objs\n";
+	if (!$shlib)
+		{
+#		$ret.="\t\$(RM) \$(O_$Name)\n";
+		$ret.="\t\$(MKLIB) $lfile$target @<<\n  $objs\n<<\n";
+		}
+	else
+		{
+		local($ex)=($target =~ /O_CRYPTO/)?'':' $(L_CRYPTO)';
+		$ex.=" $zlib_lib" if $zlib_opt == 1 && $target =~ /O_CRYPTO/;
+		$ret.="\t\$(LINK) \$(MLFLAGS) $efile$target $name @<<\n  \$(SHLIB_EX_OBJ) $objs $ex \$(EX_LIBS)\n<<\n";
+		$ret.="\tIF EXIST \$@.manifest mt -nologo -manifest \$@.manifest -outputresource:\$@;2\n\n";
+		}
+	$ret.="\n";
+	return($ret);
+	}
+
+sub do_link_rule
+	{
+	local($target,$files,$dep_libs,$libs)=@_;
+	local($ret,$_);
+	
+	$file =~ s/\//$o/g if $o ne '/';
+	$n=&bname($targer);
+	$ret.="$target: $files $dep_libs\n";
+	$ret.="\t\$(LINK) \$(LFLAGS) $efile$target @<<\n";
+	$ret.="  \$(APP_EX_OBJ) $files $libs\n<<\n";
+	$ret.="\tIF EXIST \$@.manifest mt -nologo -manifest \$@.manifest -outputresource:\$@;1\n\n";
+	return($ret);
+	}
+
+sub win32_import_asm
+	{
+	my ($mf_var, $asm_name, $oref, $sref) = @_;
+	my $asm_dir;
+	if ($asm_name eq "")
+		{
+		$asm_dir = "crypto\\";
+		}
+	else
+		{
+		$asm_dir = "crypto\\$asm_name\\asm\\";
+		}
+
+	$$oref = "";
+	$mf_var =~ s/\.o$/.obj/g;
+
+	foreach (split(/ /, $mf_var))
+		{
+		$$oref .= $asm_dir . $_ . " ";
+		}
+	$$oref =~ s/ $//;
+	$$sref = $$oref;
+	$$sref =~ s/\.obj/.asm/g;
+
+	}
+
+
+1;
diff --git a/openssl/util/pl/linux.pl b/openssl/util/pl/linux.pl
new file mode 100644
index 0000000..d24f7b7
--- /dev/null
+++ b/openssl/util/pl/linux.pl
@@ -0,0 +1,104 @@
+#!/usr/local/bin/perl
+#
+# linux.pl - the standard unix makefile stuff.
+#
+
+$o='/';
+$cp='/bin/cp';
+$rm='/bin/rm -f';
+
+# C compiler stuff
+
+$cc='gcc';
+if ($debug)
+	{ $cflags="-g2 -ggdb -DREF_CHECK -DCRYPTO_MDEBUG"; }
+elsif ($profile)
+	{ $cflags="-pg -O3"; }
+else
+	{ $cflags="-O3 -fomit-frame-pointer"; }
+
+if (!$no_asm)
+	{
+	$bn_asm_obj='$(OBJ_D)/bn86-elf.o';
+	$bn_asm_src='crypto/bn/asm/bn86unix.cpp';
+	$bnco_asm_obj='$(OBJ_D)/co86-elf.o';
+	$bnco_asm_src='crypto/bn/asm/co86unix.cpp';
+	$des_enc_obj='$(OBJ_D)/dx86-elf.o $(OBJ_D)/yx86-elf.o';
+	$des_enc_src='crypto/des/asm/dx86unix.cpp crypto/des/asm/yx86unix.cpp';
+	$bf_enc_obj='$(OBJ_D)/bx86-elf.o';
+	$bf_enc_src='crypto/bf/asm/bx86unix.cpp';
+	$cast_enc_obj='$(OBJ_D)/cx86-elf.o';
+	$cast_enc_src='crypto/cast/asm/cx86unix.cpp';
+	$rc4_enc_obj='$(OBJ_D)/rx86-elf.o';
+	$rc4_enc_src='crypto/rc4/asm/rx86unix.cpp';
+	$rc5_enc_obj='$(OBJ_D)/r586-elf.o';
+	$rc5_enc_src='crypto/rc5/asm/r586unix.cpp';
+	$md5_asm_obj='$(OBJ_D)/mx86-elf.o';
+	$md5_asm_src='crypto/md5/asm/mx86unix.cpp';
+	$rmd160_asm_obj='$(OBJ_D)/rm86-elf.o';
+	$rmd160_asm_src='crypto/ripemd/asm/rm86unix.cpp';
+	$sha1_asm_obj='$(OBJ_D)/sx86-elf.o';
+	$sha1_asm_src='crypto/sha/asm/sx86unix.cpp';
+	$cflags.=" -DBN_ASM -DMD5_ASM -DSHA1_ASM -DOPENSSL_BN_ASM_PART_WORDS";
+	}
+
+$cflags.=" -DTERMIO -DL_ENDIAN -m486 -Wall";
+
+if ($shlib)
+	{
+	$shl_cflag=" -DPIC -fpic";
+	$shlibp=".so.$ssl_version";
+	$so_shlibp=".so";
+	}
+
+sub do_shlib_rule
+	{
+	local($obj,$target,$name,$shlib,$so_name)=@_;
+	local($ret,$_,$Name);
+
+	$target =~ s/\//$o/g if $o ne '/';
+	($Name=$name) =~ tr/a-z/A-Z/;
+
+	$ret.="$target: \$(${Name}OBJ)\n";
+	$ret.="\t\$(RM) target\n";
+	$ret.="\tgcc \${CFLAGS} -shared -Wl,-soname,$target -o $target \$(${Name}OBJ)\n";
+	($t=$target) =~ s/(^.*)\/[^\/]*$/$1/;
+	if ($so_name ne "")
+		{
+		$ret.="\t\$(RM) \$(LIB_D)$o$so_name\n";
+		$ret.="\tln -s $target \$(LIB_D)$o$so_name\n\n";
+		}
+	}
+
+sub do_link_rule
+	{
+	local($target,$files,$dep_libs,$libs)=@_;
+	local($ret,$_);
+	
+	$file =~ s/\//$o/g if $o ne '/';
+	$n=&bname($target);
+	$ret.="$target: $files $dep_libs\n";
+	$ret.="\t\$(LINK) ${efile}$target \$(LFLAGS) $files $libs\n\n";
+	return($ret);
+	}
+
+sub do_asm_rule
+	{
+	local($target,$src)=@_;
+	local($ret,@s,@t,$i);
+
+	$target =~ s/\//$o/g if $o ne "/";
+	$src =~ s/\//$o/g if $o ne "/";
+
+	@s=split(/\s+/,$src);
+	@t=split(/\s+/,$target);
+
+	for ($i=0; $i<=$#s; $i++)
+		{
+		$ret.="$t[$i]: $s[$i]\n";
+		$ret.="\tgcc -E -DELF \$(SRC_D)$o$s[$i]|\$(AS) $afile$t[$i]\n\n";
+		}
+	return($ret);
+	}
+
+1;
diff --git a/openssl/util/pl/netware.pl b/openssl/util/pl/netware.pl
new file mode 100644
index 0000000..c78bcfc
--- /dev/null
+++ b/openssl/util/pl/netware.pl
@@ -0,0 +1,532 @@
+# Metrowerks Codewarrior or gcc / nlmconv for NetWare
+#
+
+$version_header = "crypto/opensslv.h";
+open(IN, "$version_header") or die "Couldn't open $version_header: $!";
+while (<IN>) {
+  if (/^#define[\s\t]+OPENSSL_VERSION_NUMBER[\s\t]+0x(\d)(\d{2})(\d{2})(\d{2})/)
+  {
+    # die "OpenSSL version detected: $1.$2.$3.$4\n";
+    #$nlmvernum = "$1,$2,$3";
+    $nlmvernum = "$1,".($2*10+$3).",".($4*1);
+    #$nlmverstr = "$1.".($2*1).".".($3*1).($4?(chr(96+$4)):"");
+    break;
+  }
+}
+close(IN) or die "Couldn't close $version_header: $!";
+
+$readme_file = "README";
+open(IN, $readme_file) or die "Couldn't open $readme_file: $!";
+while (<IN>) {
+  if (/^[\s\t]+OpenSSL[\s\t]+(\d)\.(\d{1,2})\.(\d{1,2})([a-z])(.*)/)
+  {
+    #$nlmvernum = "$1,$2,$3";
+    #$nlmvernum = "$1,".($2*10+$3).",".($4*1);
+    $nlmverstr = "$1.$2.$3$4$5";
+  }
+  elsif (/^[\s\t]+(Copyright \(c\) \d{4}\-\d{4} The OpenSSL Project)$/)
+  {
+    $nlmcpystr = $1;
+  }
+  break if ($nlmvernum && $nlmcpystr);
+}
+close(IN) or die "Couldn't close $readme_file: $!";
+
+# Define stacksize here
+$nlmstack = "32768";
+
+# some default settings here in case we failed to find them in README
+$nlmvernum = "1,0,0" if (!$nlmvernum);
+$nlmverstr = "OpenSSL" if (!$nlmverstr);
+$nlmcpystr = "Copyright (c) 1998-now The OpenSSL Project" if (!$nlmcpystr);
+
+# die "OpenSSL copyright: $nlmcpystr\nOpenSSL verstring: $nlmverstr\nOpenSSL vernumber: $nlmvernum\n";
+
+# The import files and other misc imports needed to link
+@misc_imports = ("GetProcessSwitchCount", "RunningProcess",
+                 "GetSuperHighResolutionTimer");
+if ($LIBC)
+{
+   @import_files = ("libc.imp");
+   @module_files = ("libc");
+   $libarch = "LIBC";
+}
+else
+{
+   # clib build
+   @import_files = ("clib.imp");
+   push(@import_files, "socklib.imp") if ($BSDSOCK);
+   @module_files = ("clib");
+   # push(@misc_imports, "_rt_modu64%16", "_rt_divu64%16");
+   $libarch = "CLIB";
+}
+if ($BSDSOCK)
+{
+   $libarch .= "-BSD";
+}
+else
+{
+   $libarch .= "-WS2";
+   push(@import_files, "ws2nlm.imp");
+}
+
+# The "IMPORTS" environment variable must be set and point to the location
+# where import files (*.imp) can be found.
+# Example:  set IMPORTS=c:\ndk\nwsdk\imports
+$import_path = $ENV{"IMPORTS"} || die ("IMPORTS environment variable not set\n");
+
+
+# The "PRELUDE" environment variable must be set and point to the location
+# and name of the prelude source to link with ( nwpre.obj is recommended ).
+# Example: set PRELUDE=c:\codewar\novell support\metrowerks support\libraries\runtime\nwpre.obj
+$prelude = $ENV{"PRELUDE"} || die ("PRELUDE environment variable not set\n");
+
+# The "INCLUDES" environment variable must be set and point to the location
+# where import files (*.imp) can be found.
+$include_path = $ENV{"INCLUDE"} || die ("INCLUDES environment variable not set\n");
+$include_path =~ s/\\/\//g;
+$include_path = join(" -I", split(/;/, $include_path));
+
+# check for gcc compiler
+$gnuc = $ENV{"GNUC"};
+
+#$ssl=   "ssleay32";
+#$crypto="libeay32";
+
+if ($gnuc)
+{
+   # C compiler
+   $cc='gcc';
+   # Linker
+   $link='nlmconv';
+   # librarian
+   $mklib='ar';
+   $o='/';
+   # cp command
+   $cp='cp -af';
+   # rm command
+   $rm='rm -f';
+   # mv command
+   $mv='mv -f';
+   # mkdir command
+   $mkdir='gmkdir';
+   #$ranlib='ranlib';
+}
+else
+{
+   # C compiler
+   $cc='mwccnlm';
+   # Linker
+   $link='mwldnlm';
+   # librarian
+   $mklib='mwldnlm';
+   # Path separator
+   $o='\\';
+   # cp command
+   $cp='copy >nul:';
+   # rm command
+   $rm='del /f /q';
+}
+
+# assembler
+if ($nw_nasm)
+{
+   $asm=(`nasm -v 2>NUL` gt `nasmw -v 2>NUL`?"nasm":"nasmw");
+   if ($gnuc)
+   {
+      $asm.=" -s -f elf";
+   }
+   else
+   {
+      $asm.=" -s -f coff -d __coff__";
+   }
+   $afile="-o ";
+   $asm.=" -g" if $debug;
+}
+elsif ($nw_mwasm)
+{
+   $asm="mwasmnlm -maxerrors 20";
+   $afile="-o ";
+   $asm.=" -g" if $debug;
+}
+elsif ($nw_masm)
+{
+# masm assembly settings - it should be possible to use masm but haven't
+# got it working.
+# $asm='ml /Cp /coff /c /Cx';
+# $asm.=" /Zi" if $debug;
+# $afile='/Fo';
+   die("Support for masm assembler not yet functional\n");
+}
+else
+{
+   $asm="";
+   $afile="";
+}
+
+
+
+if ($gnuc)
+{
+   # compile flags for GNUC
+   # additional flags based upon debug | non-debug
+   if ($debug)
+   {
+      $cflags="-g -DDEBUG";
+   }
+   else
+   {
+      $cflags="-O2";
+   }
+   $cflags.=" -nostdinc -I$include_path \\
+         -fno-builtin -fpcc-struct-return -fno-strict-aliasing \\
+         -funsigned-char -Wall -Wno-unused -Wno-uninitialized";
+
+   # link flags
+   $lflags="-T";
+}
+else
+{
+   # compile flags for CodeWarrior
+   # additional flags based upon debug | non-debug
+   if ($debug)
+   {
+      $cflags="-opt off -g -sym internal -DDEBUG";
+   }
+   else
+   {
+   # CodeWarrior compiler has a problem with optimizations for floating
+   # points - no optimizations until further investigation
+   #      $cflags="-opt all";
+   }
+
+   # NOTES: Several c files in the crypto subdirectory include headers from
+   #        their local directories.  Metrowerks wouldn't find these h files
+   #        without adding individual include directives as compile flags
+   #        or modifying the c files.  Instead of adding individual include
+   #        paths for each subdirectory a recursive include directive
+   #        is used ( -ir crypto ).
+   #
+   #        A similar issue exists for the engines and apps subdirectories.
+   #
+   #        Turned off the "possible" warnings ( -w nopossible ).  Metrowerks
+   #        complained a lot about various stuff.  May want to turn back
+   #        on for further development.
+   $cflags.=" -nostdinc -ir crypto -ir engines -ir apps -I$include_path \\
+         -msgstyle gcc -align 4 -processor pentium -char unsigned \\
+         -w on -w nolargeargs -w nopossible -w nounusedarg -w nounusedexpr \\
+         -w noimplicitconv -relax_pointers -nosyspath -maxerrors 20";
+
+   # link flags
+   $lflags="-msgstyle gcc -zerobss -nostdlib -sym internal -commandfile";
+}
+
+# common defines
+$cflags.=" -DL_ENDIAN -DOPENSSL_SYSNAME_NETWARE -U_WIN32";
+
+# If LibC build add in NKS_LIBC define and set the entry/exit
+# routines - The default entry/exit routines are for CLib and don't exist
+# in LibC
+if ($LIBC)
+{
+   $cflags.=" -DNETWARE_LIBC";
+   $nlmstart = "_LibCPrelude";
+   $nlmexit = "_LibCPostlude";
+   @nlm_flags = ("pseudopreemption", "flag_on 64");
+}
+else
+{
+   $cflags.=" -DNETWARE_CLIB";
+   $nlmstart = "_Prelude";
+   $nlmexit = "_Stop";
+}
+
+# If BSD Socket support is requested, set a define for the compiler
+if ($BSDSOCK)
+{
+   $cflags.=" -DNETWARE_BSDSOCK";
+   if (!$LIBC)
+   {
+      $cflags.=" -DNETDB_USE_INTERNET";
+   }
+}
+
+
+# linking stuff
+# for the output directories use the mk1mf.pl values with "_nw" appended
+if ($shlib)
+{
+   if ($LIBC)
+   {
+      $out_def.="_nw_libc_nlm";
+      $tmp_def.="_nw_libc_nlm";
+      $inc_def.="_nw_libc_nlm";
+   }
+   else  # NETWARE_CLIB
+   {
+      $out_def.="_nw_clib_nlm";
+      $tmp_def.="_nw_clib_nlm";
+      $inc_def.="_nw_clib_nlm";
+   }
+}
+else
+{
+   if ($gnuc) # GNUC Tools
+   {
+      $libp=".a";
+      $shlibp=".a";
+      $lib_flags="-cr";
+   }
+   else       # CodeWarrior
+   {
+      $libp=".lib";
+      $shlibp=".lib";
+      $lib_flags="-nodefaults -type library -o";
+   }
+   if ($LIBC)
+   {
+      $out_def.="_nw_libc";
+      $tmp_def.="_nw_libc";
+      $inc_def.="_nw_libc";
+   }
+   else  # NETWARE_CLIB
+   {
+      $out_def.="_nw_clib";
+      $tmp_def.="_nw_clib";
+      $inc_def.="_nw_clib";
+   }
+}
+
+# used by mk1mf.pl
+$obj='.o';
+$ofile='-o ';
+$efile='';
+$exep='.nlm';
+$ex_libs='';
+
+if (!$no_asm)
+{
+   $bn_asm_obj="\$(OBJ_D)${o}bn-nw${obj}";
+   $bn_asm_src="crypto${o}bn${o}asm${o}bn-nw.asm";
+   $bnco_asm_obj="\$(OBJ_D)${o}co-nw${obj}";
+   $bnco_asm_src="crypto${o}bn${o}asm${o}co-nw.asm";
+   $aes_asm_obj="\$(OBJ_D)${o}a-nw${obj}";
+   $aes_asm_src="crypto${o}aes${o}asm${o}a-nw.asm";
+   $des_enc_obj="\$(OBJ_D)${o}d-nw${obj} \$(OBJ_D)${o}y-nw${obj}";
+   $des_enc_src="crypto${o}des${o}asm${o}d-nw.asm crypto${o}des${o}asm${o}y-nw.asm";
+   $bf_enc_obj="\$(OBJ_D)${o}b-nw${obj}";
+   $bf_enc_src="crypto${o}bf${o}asm${o}b-nw.asm";
+   $cast_enc_obj="\$(OBJ_D)${o}c-nw${obj}";
+   $cast_enc_src="crypto${o}cast${o}asm${o}c-nw.asm";
+   $rc4_enc_obj="\$(OBJ_D)${o}r4-nw${obj}";
+   $rc4_enc_src="crypto${o}rc4${o}asm${o}r4-nw.asm";
+   $rc5_enc_obj="\$(OBJ_D)${o}r5-nw${obj}";
+   $rc5_enc_src="crypto${o}rc5${o}asm${o}r5-nw.asm";
+   $md5_asm_obj="\$(OBJ_D)${o}m5-nw${obj}";
+   $md5_asm_src="crypto${o}md5${o}asm${o}m5-nw.asm";
+   $sha1_asm_obj="\$(OBJ_D)${o}s1-nw${obj} \$(OBJ_D)${o}sha256-nw${obj} \$(OBJ_D)${o}sha512-nw${obj}";
+   $sha1_asm_src="crypto${o}sha${o}asm${o}s1-nw.asm crypto${o}sha${o}asm${o}sha256-nw.asm crypto${o}sha${o}asm${o}sha512-nw.asm";
+   $rmd160_asm_obj="\$(OBJ_D)${o}rm-nw${obj}";
+   $rmd160_asm_src="crypto${o}ripemd${o}asm${o}rm-nw.asm";
+   $whirlpool_asm_obj="\$(OBJ_D)${o}wp-nw${obj}";
+   $whirlpool_asm_src="crypto${o}whrlpool${o}asm${o}wp-nw.asm";
+   $cpuid_asm_obj="\$(OBJ_D)${o}x86cpuid-nw${obj}";
+   $cpuid_asm_src="crypto${o}x86cpuid-nw.asm";
+   $cflags.=" -DOPENSSL_CPUID_OBJ -DBN_ASM -DOPENSSL_BN_ASM_PART_WORDS -DMD5_ASM -DWHIRLPOOL_ASM";
+   $cflags.=" -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM";
+   $cflags.=" -DAES_ASM -DRMD160_ASM";
+}
+else
+{
+   $bn_asm_obj='';
+   $bn_asm_src='';
+   $bnco_asm_obj='';
+   $bnco_asm_src='';
+   $aes_asm_obj='';
+   $aes_asm_src='';
+   $des_enc_obj='';
+   $des_enc_src='';
+   $bf_enc_obj='';
+   $bf_enc_src='';
+   $cast_enc_obj='';
+   $cast_enc_src='';
+   $rc4_enc_obj='';
+   $rc4_enc_src='';
+   $rc5_enc_obj='';
+   $rc5_enc_src='';
+   $md5_asm_obj='';
+   $md5_asm_src='';
+   $sha1_asm_obj='';
+   $sha1_asm_src='';
+   $rmd160_asm_obj='';
+   $rmd160_asm_src='';
+   $whirlpool_asm_obj='';
+   $whirlpool_asm_src='';
+   $cpuid_asm_obj='';
+   $cpuid_asm_src='';
+}
+
+# create the *.def linker command files in \openssl\netware\ directory
+sub do_def_file
+{
+   # strip off the leading path
+   my($target) = bname(shift);
+   my($i);
+
+   if ($target =~ /(.*).nlm/)
+   {
+      $target = $1;
+   }
+
+   # special case for openssl - the mk1mf.pl defines E_EXE = openssl
+   if ($target =~ /E_EXE/)
+   {
+      $target =~ s/\$\(E_EXE\)/openssl/;
+   }
+
+   # Note: originally tried to use full path ( \openssl\netware\$target.def )
+   # Metrowerks linker choked on this with an assertion failure. bug???
+   #
+   my($def_file) = "netware${o}$target.def";
+
+   open(DEF_OUT, ">$def_file") || die("unable to open file $def_file\n");
+
+   print( DEF_OUT "# command file generated by netware.pl for NLM target.\n" );
+   print( DEF_OUT "# do not edit this file - all your changes will be lost!!\n" );
+   print( DEF_OUT "#\n");
+   print( DEF_OUT "DESCRIPTION \"$target ($libarch) - OpenSSL $nlmverstr\"\n");
+   print( DEF_OUT "COPYRIGHT \"$nlmcpystr\"\n");
+   print( DEF_OUT "VERSION $nlmvernum\n");
+   print( DEF_OUT "STACK $nlmstack\n");
+   print( DEF_OUT "START $nlmstart\n");
+   print( DEF_OUT "EXIT $nlmexit\n");
+
+   # special case for openssl
+   if ($target eq "openssl")
+   {
+      print( DEF_OUT "SCREENNAME \"OpenSSL $nlmverstr\"\n");
+   }
+   else
+   {
+      print( DEF_OUT "SCREENNAME \"DEFAULT\"\n");
+   }
+
+   foreach $i (@misc_imports)
+   {
+      print( DEF_OUT "IMPORT $i\n");
+   }
+
+   foreach $i (@import_files)
+   {
+      print( DEF_OUT "IMPORT \@$import_path${o}$i\n");
+   }
+
+   foreach $i (@module_files)
+   {
+      print( DEF_OUT "MODULE $i\n");
+   }
+
+   foreach $i (@nlm_flags)
+   {
+      print( DEF_OUT "$i\n");
+   }
+
+   if ($gnuc)
+   {
+      if ($target =~ /openssl/)
+      {
+         print( DEF_OUT "INPUT ${tmp_def}${o}openssl${obj}\n");
+         print( DEF_OUT "INPUT ${tmp_def}${o}openssl${libp}\n");
+      }
+      else
+      {
+         print( DEF_OUT "INPUT ${tmp_def}${o}${target}${obj}\n");
+      }
+      print( DEF_OUT "INPUT $prelude\n");
+      print( DEF_OUT "INPUT ${out_def}${o}${ssl}${libp} ${out_def}${o}${crypto}${libp}\n");
+      print( DEF_OUT "OUTPUT $target.nlm\n");
+   }
+
+   close(DEF_OUT);
+   return($def_file);
+}
+
+sub do_lib_rule
+{
+   my($objs,$target,$name,$shlib)=@_;
+   my($ret);
+
+   $ret.="$target: $objs\n";
+   if (!$shlib)
+   {
+      $ret.="\t\@echo Building Lib: $name\n";
+      $ret.="\t\$(MKLIB) $lib_flags $target $objs\n";
+      $ret.="\t\@echo .\n"
+   }
+   else
+   {
+      die( "Building as NLM not currently supported!" );
+   }
+
+   $ret.="\n";
+   return($ret);
+}
+
+sub do_link_rule
+{
+   my($target,$files,$dep_libs,$libs)=@_;
+   my($ret);
+   my($def_file) = do_def_file($target);
+
+   $ret.="$target: $files $dep_libs\n";
+
+   # NOTE:  When building the test nlms no screen name is given
+   #  which causes the console screen to be used.  By using the console
+   #  screen there is no "<press any key to continue>" message which
+   #  requires user interaction.  The test script ( do_tests.pl ) needs
+   #  to be able to run the tests without requiring user interaction.
+   #
+   #  However, the sample program "openssl.nlm" is used by the tests and is
+   #  a interactive sample so a screen is desired when not be run by the
+   #  tests.  To solve the problem, two versions of the program are built:
+   #    openssl2 - no screen used by tests
+   #    openssl - default screen - use for normal interactive modes
+   #
+
+   # special case for openssl - the mk1mf.pl defines E_EXE = openssl
+   if ($target =~ /E_EXE/)
+   {
+      my($target2) = $target;
+
+      $target2 =~ s/\(E_EXE\)/\(E_EXE\)2/;
+
+      # openssl2
+      my($def_file2) = do_def_file($target2);
+
+      if ($gnuc)
+      {
+         $ret.="\t\$(MKLIB) $lib_flags \$(TMP_D)${o}\$(E_EXE).a \$(filter-out \$(TMP_D)${o}\$(E_EXE)${obj},$files)\n";
+         $ret.="\t\$(LINK) \$(LFLAGS) $def_file2\n";
+         $ret.="\t\@$mv \$(E_EXE)2.nlm \$(TEST_D)\n";
+      }
+      else
+      {
+         $ret.="\t\$(LINK) \$(LFLAGS) $def_file2 $files \"$prelude\" $libs -o $target2\n";
+      }
+   }
+   if ($gnuc)
+   {
+      $ret.="\t\$(LINK) \$(LFLAGS) $def_file\n";
+      $ret.="\t\@$mv \$(\@F) \$(TEST_D)\n";
+   }
+   else
+   {
+      $ret.="\t\$(LINK) \$(LFLAGS) $def_file $files \"$prelude\" $libs -o $target\n";
+   }
+
+   $ret.="\n";
+   return($ret);
+
+}
+
+1;
diff --git a/openssl/util/pl/ultrix.pl b/openssl/util/pl/ultrix.pl
new file mode 100644
index 0000000..ea370c7
--- /dev/null
+++ b/openssl/util/pl/ultrix.pl
@@ -0,0 +1,38 @@
+#!/usr/local/bin/perl
+#
+# linux.pl - the standard unix makefile stuff.
+#
+
+$o='/';
+$cp='/bin/cp';
+$rm='/bin/rm -f';
+
+# C compiler stuff
+
+$cc='cc';
+if ($debug)
+	{ $cflags="-g -DREF_CHECK -DCRYPTO_MDEBUG"; }
+else
+	{ $cflags="-O2"; }
+
+$cflags.=" -std1 -DL_ENDIAN";
+
+if (!$no_asm)
+	{
+	$bn_asm_obj='$(OBJ_D)/mips1.o';
+	$bn_asm_src='crypto/bn/asm/mips1.s';
+	}
+
+sub do_link_rule
+	{
+	local($target,$files,$dep_libs,$libs)=@_;
+	local($ret,$_);
+	
+	$file =~ s/\//$o/g if $o ne '/';
+	$n=&bname($target);
+	$ret.="$target: $files $dep_libs\n";
+	$ret.="\t\$(LINK) ${efile}$target \$(LFLAGS) $files $libs\n\n";
+	return($ret);
+	}
+
+1;
diff --git a/openssl/util/pl/unix.pl b/openssl/util/pl/unix.pl
new file mode 100644
index 0000000..146611a
--- /dev/null
+++ b/openssl/util/pl/unix.pl
@@ -0,0 +1,96 @@
+#!/usr/local/bin/perl
+#
+# unix.pl - the standard unix makefile stuff.
+#
+
+$o='/';
+$cp='/bin/cp';
+$rm='/bin/rm -f';
+
+# C compiler stuff
+
+if ($gcc)
+	{
+	$cc='gcc';
+	if ($debug)
+		{ $cflags="-g2 -ggdb"; }
+	else
+		{ $cflags="-O3 -fomit-frame-pointer"; }
+	}
+else
+	{
+	$cc='cc';
+	if ($debug)
+		{ $cflags="-g"; }
+	else
+		{ $cflags="-O"; }
+	}
+$obj='.o';
+$ofile='-o ';
+
+# EXE linking stuff
+$link='${CC}';
+$lflags='${CFLAGS}';
+$efile='-o ';
+$exep='';
+$ex_libs="";
+
+# static library stuff
+$mklib='ar r';
+$mlflags='';
+$ranlib=&which("ranlib") or $ranlib="true";
+$plib='lib';
+$libp=".a";
+$shlibp=".a";
+$lfile='';
+
+$asm='as';
+$afile='-o ';
+$bn_asm_obj="";
+$bn_asm_src="";
+$des_enc_obj="";
+$des_enc_src="";
+$bf_enc_obj="";
+$bf_enc_src="";
+
+sub do_lib_rule
+	{
+	local($obj,$target,$name,$shlib)=@_;
+	local($ret,$_,$Name);
+
+	$target =~ s/\//$o/g if $o ne '/';
+	$target="$target";
+	($Name=$name) =~ tr/a-z/A-Z/;
+
+	$ret.="$target: \$(${Name}OBJ)\n";
+	$ret.="\t\$(RM) $target\n";
+	$ret.="\t\$(MKLIB) $target \$(${Name}OBJ)\n";
+	$ret.="\t\$(RANLIB) $target\n\n";
+	}
+
+sub do_link_rule
+	{
+	local($target,$files,$dep_libs,$libs)=@_;
+	local($ret,$_);
+	
+	$file =~ s/\//$o/g if $o ne '/';
+	$n=&bname($target);
+	$ret.="$target: $files $dep_libs\n";
+	$ret.="\t\$(LINK) ${efile}$target \$(LFLAGS) $files $libs\n\n";
+	return($ret);
+	}
+
+sub which
+	{
+	my ($name)=@_;
+	my $path;
+	foreach $path (split /:/, $ENV{PATH})
+		{
+		if (-x "$path/$name")
+			{
+			return "$path/$name";
+			}
+		}
+	}
+
+1;
diff --git a/openssl/util/pod2man.pl b/openssl/util/pod2man.pl
new file mode 100755
index 0000000..025d914
--- /dev/null
+++ b/openssl/util/pod2man.pl
@@ -0,0 +1,1184 @@
+: #!/usr/bin/perl-5.005
+    eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
+	if $running_under_some_shell;
+
+$DEF_PM_SECTION = '3pm' || '3';
+
+=head1 NAME
+
+pod2man - translate embedded Perl pod directives into man pages
+
+=head1 SYNOPSIS
+
+B<pod2man>
+[ B<--section=>I<manext> ]
+[ B<--release=>I<relpatch> ]
+[ B<--center=>I<string> ]
+[ B<--date=>I<string> ]
+[ B<--fixed=>I<font> ]
+[ B<--official> ]
+[ B<--lax> ]
+I<inputfile>
+
+=head1 DESCRIPTION
+
+B<pod2man> converts its input file containing embedded pod directives (see
+L<perlpod>) into nroff source suitable for viewing with nroff(1) or
+troff(1) using the man(7) macro set.
+
+Besides the obvious pod conversions, B<pod2man> also takes care of
+func(), func(n), and simple variable references like $foo or @bar so
+you don't have to use code escapes for them; complex expressions like
+C<$fred{'stuff'}> will still need to be escaped, though.  Other nagging
+little roffish things that it catches include translating the minus in
+something like foo-bar, making a long dash--like this--into a real em
+dash, fixing up "paired quotes", putting a little space after the
+parens in something like func(), making C++ and PI look right, making
+double underbars have a little tiny space between them, making ALLCAPS
+a teeny bit smaller in troff(1), and escaping backslashes so you don't
+have to.
+
+=head1 OPTIONS
+
+=over 8
+
+=item center
+
+Set the centered header to a specific string.  The default is
+"User Contributed Perl Documentation", unless the C<--official> flag is
+given, in which case the default is "Perl Programmers Reference Guide".
+
+=item date
+
+Set the left-hand footer string to this value.  By default,
+the modification date of the input file will be used.
+
+=item fixed
+
+The fixed font to use for code refs.  Defaults to CW.
+
+=item official
+
+Set the default header to indicate that this page is of
+the standard release in case C<--center> is not given.
+
+=item release
+
+Set the centered footer.  By default, this is the current
+perl release.
+
+=item section
+
+Set the section for the C<.TH> macro.  The standard conventions on
+sections are to use 1 for user commands,  2 for system calls, 3 for
+functions, 4 for devices, 5 for file formats, 6 for games, 7 for
+miscellaneous information, and 8 for administrator commands.  This works
+best if you put your Perl man pages in a separate tree, like
+F</usr/local/perl/man/>.  By default, section 1 will be used
+unless the file ends in F<.pm> in which case section 3 will be selected.
+
+=item lax
+
+Don't complain when required sections aren't present.
+
+=back
+
+=head1 Anatomy of a Proper Man Page
+
+For those not sure of the proper layout of a man page, here's
+an example of the skeleton of a proper man page.  Head of the
+major headers should be setout as a C<=head1> directive, and
+are historically written in the rather startling ALL UPPER CASE
+format, although this is not mandatory.
+Minor headers may be included using C<=head2>, and are
+typically in mixed case.
+
+=over 10
+
+=item NAME
+
+Mandatory section; should be a comma-separated list of programs or
+functions documented by this podpage, such as:
+
+    foo, bar - programs to do something
+
+=item SYNOPSIS
+
+A short usage summary for programs and functions, which
+may someday be deemed mandatory.
+
+=item DESCRIPTION
+
+Long drawn out discussion of the program.  It's a good idea to break this
+up into subsections using the C<=head2> directives, like
+
+    =head2 A Sample Subection
+
+    =head2 Yet Another Sample Subection
+
+=item OPTIONS
+
+Some people make this separate from the description.
+
+=item RETURN VALUE
+
+What the program or function returns if successful.
+
+=item ERRORS
+
+Exceptions, return codes, exit stati, and errno settings.
+
+=item EXAMPLES
+
+Give some example uses of the program.
+
+=item ENVIRONMENT
+
+Envariables this program might care about.
+
+=item FILES
+
+All files used by the program.  You should probably use the FE<lt>E<gt>
+for these.
+
+=item SEE ALSO
+
+Other man pages to check out, like man(1), man(7), makewhatis(8), or catman(8).
+
+=item NOTES
+
+Miscellaneous commentary.
+
+=item CAVEATS
+
+Things to take special care with; sometimes called WARNINGS.
+
+=item DIAGNOSTICS
+
+All possible messages the program can print out--and
+what they mean.
+
+=item BUGS
+
+Things that are broken or just don't work quite right.
+
+=item RESTRICTIONS
+
+Bugs you don't plan to fix :-)
+
+=item AUTHOR
+
+Who wrote it (or AUTHORS if multiple).
+
+=item HISTORY
+
+Programs derived from other sources sometimes have this, or
+you might keep a modification log here.
+
+=back
+
+=head1 EXAMPLES
+
+    pod2man program > program.1
+    pod2man some_module.pm > /usr/perl/man/man3/some_module.3
+    pod2man --section=7 note.pod > note.7
+
+=head1 DIAGNOSTICS
+
+The following diagnostics are generated by B<pod2man>.  Items
+marked "(W)" are non-fatal, whereas the "(F)" errors will cause
+B<pod2man> to immediately exit with a non-zero status.
+
+=over 4
+
+=item bad option in paragraph %d of %s: ``%s'' should be [%s]<%s>
+
+(W) If you start include an option, you should set it off
+as bold, italic, or code.
+
+=item can't open %s: %s
+
+(F) The input file wasn't available for the given reason.
+
+=item Improper man page - no dash in NAME header in paragraph %d of %s
+
+(W) The NAME header did not have an isolated dash in it.  This is
+considered important.
+
+=item Invalid man page - no NAME line in %s
+
+(F) You did not include a NAME header, which is essential.
+
+=item roff font should be 1 or 2 chars, not `%s'  (F)
+
+(F) The font specified with the C<--fixed> option was not
+a one- or two-digit roff font.
+
+=item %s is missing required section: %s
+
+(W) Required sections include NAME, DESCRIPTION, and if you're
+using a section starting with a 3, also a SYNOPSIS.  Actually,
+not having a NAME is a fatal.
+
+=item Unknown escape: %s in %s
+
+(W) An unknown HTML entity (probably for an 8-bit character) was given via
+a C<EE<lt>E<gt>> directive.  Besides amp, lt, gt, and quot, recognized
+entities are Aacute, aacute, Acirc, acirc, AElig, aelig, Agrave, agrave,
+Aring, aring, Atilde, atilde, Auml, auml, Ccedil, ccedil, Eacute, eacute,
+Ecirc, ecirc, Egrave, egrave, ETH, eth, Euml, euml, Iacute, iacute, Icirc,
+icirc, Igrave, igrave, Iuml, iuml, Ntilde, ntilde, Oacute, oacute, Ocirc,
+ocirc, Ograve, ograve, Oslash, oslash, Otilde, otilde, Ouml, ouml, szlig,
+THORN, thorn, Uacute, uacute, Ucirc, ucirc, Ugrave, ugrave, Uuml, uuml,
+Yacute, yacute, and yuml.
+
+=item Unmatched =back
+
+(W) You have a C<=back> without a corresponding C<=over>.
+
+=item Unrecognized pod directive: %s
+
+(W) You specified a pod directive that isn't in the known list of
+C<=head1>, C<=head2>, C<=item>, C<=over>, C<=back>, or C<=cut>.
+
+
+=back
+
+=head1 NOTES
+
+If you would like to print out a lot of man page continuously, you
+probably want to set the C and D registers to set contiguous page
+numbering and even/odd paging, at least on some versions of man(7).
+Settting the F register will get you some additional experimental
+indexing:
+
+    troff -man -rC1 -rD1 -rF1 perl.1 perldata.1 perlsyn.1 ...
+
+The indexing merely outputs messages via C<.tm> for each
+major page, section, subsection, item, and any C<XE<lt>E<gt>>
+directives.
+
+
+=head1 RESTRICTIONS
+
+None at this time.
+
+=head1 BUGS
+
+The =over and =back directives don't really work right.  They
+take absolute positions instead of offsets, don't nest well, and
+making people count is suboptimal in any event.
+
+=head1 AUTHORS
+
+Original prototype by Larry Wall, but so massively hacked over by
+Tom Christiansen such that Larry probably doesn't recognize it anymore.
+
+=cut
+
+$/ = "";
+$cutting = 1;
+@Indices = ();
+
+# We try first to get the version number from a local binary, in case we're
+# running an installed version of Perl to produce documentation from an
+# uninstalled newer version's pod files.
+if ($^O ne 'plan9' and $^O ne 'dos' and $^O ne 'os2' and $^O ne 'MSWin32') {
+  my $perl = (-x './perl' && -f './perl' ) ?
+                 './perl' :
+                 ((-x '../perl' && -f '../perl') ?
+                      '../perl' :
+                      '');
+  ($version,$patch) = `$perl -e 'print $]'` =~ /^(\d\.\d{3})(\d{2})?/ if $perl;
+}
+# No luck; we'll just go with the running Perl's version
+($version,$patch) = $] =~ /^(.{5})(\d{2})?/ unless $version;
+$DEF_RELEASE  = "perl $version";
+$DEF_RELEASE .= ", patch $patch" if $patch;
+
+
+sub makedate {
+    my $secs = shift;
+    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($secs);
+    my $mname = (qw{Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec})[$mon];
+    $year += 1900;
+    return "$mday/$mname/$year";
+}
+
+use Getopt::Long;
+
+$DEF_SECTION = 1;
+$DEF_CENTER = "User Contributed Perl Documentation";
+$STD_CENTER = "Perl Programmers Reference Guide";
+$DEF_FIXED = 'CW';
+$DEF_LAX = 0;
+
+sub usage {
+    warn "$0: @_\n" if @_;
+    die <<EOF;
+usage: $0 [options] podpage
+Options are:
+	--section=manext      (default "$DEF_SECTION")
+	--release=relpatch    (default "$DEF_RELEASE")
+	--center=string       (default "$DEF_CENTER")
+	--date=string         (default "$DEF_DATE")
+	--fixed=font	      (default "$DEF_FIXED")
+	--official	      (default NOT)
+	--lax                 (default NOT)
+EOF
+}
+
+$uok = GetOptions( qw(
+	section=s
+	release=s
+	center=s
+	date=s
+	fixed=s
+	official
+	lax
+	help));
+
+$DEF_DATE = makedate((stat($ARGV[0]))[9] || time());
+
+usage("Usage error!") unless $uok;
+usage() if $opt_help;
+usage("Need one and only one podpage argument") unless @ARGV == 1;
+
+$section = $opt_section || ($ARGV[0] =~ /\.pm$/
+				? $DEF_PM_SECTION : $DEF_SECTION);
+$RP = $opt_release || $DEF_RELEASE;
+$center = $opt_center || ($opt_official ? $STD_CENTER : $DEF_CENTER);
+$lax = $opt_lax || $DEF_LAX;
+
+$CFont = $opt_fixed || $DEF_FIXED;
+
+if (length($CFont) == 2) {
+    $CFont_embed = "\\f($CFont";
+}
+elsif (length($CFont) == 1) {
+    $CFont_embed = "\\f$CFont";
+}
+else {
+    die "roff font should be 1 or 2 chars, not `$CFont_embed'";
+}
+
+$date = $opt_date || $DEF_DATE;
+
+for (qw{NAME DESCRIPTION}) {
+# for (qw{NAME DESCRIPTION AUTHOR}) {
+    $wanna_see{$_}++;
+}
+$wanna_see{SYNOPSIS}++ if $section =~ /^3/;
+
+
+$name = @ARGV ? $ARGV[0] : "<STDIN>";
+$Filename = $name;
+if ($section =~ /^1/) {
+    require File::Basename;
+    $name = uc File::Basename::basename($name);
+}
+$name =~ s/\.(pod|p[lm])$//i;
+
+# Lose everything up to the first of
+#     */lib/*perl*	standard or site_perl module
+#     */*perl*/lib	from -D prefix=/opt/perl
+#     */*perl*/		random module hierarchy
+# which works.
+$name =~ s-//+-/-g;
+if ($name =~ s-^.*?/lib/[^/]*perl[^/]*/--i
+	or $name =~ s-^.*?/[^/]*perl[^/]*/lib/--i
+	or $name =~ s-^.*?/[^/]*perl[^/]*/--i) {
+    # Lose ^site(_perl)?/.
+    $name =~ s-^site(_perl)?/--;
+    # Lose ^arch/.	(XXX should we use Config? Just for archname?)
+    $name =~ s~^(.*-$^O|$^O-.*)/~~o;
+    # Lose ^version/.
+    $name =~ s-^\d+\.\d+/--;
+}
+
+# Translate Getopt/Long to Getopt::Long, etc.
+$name =~ s(/)(::)g;
+
+if ($name ne 'something') {
+    FCHECK: {
+	open(F, "< $ARGV[0]") || die "can't open $ARGV[0]: $!";
+	while (<F>) {
+	    next unless /^=\b/;
+	    if (/^=head1\s+NAME\s*$/) {  # an /m would forgive mistakes
+		$_ = <F>;
+		unless (/\s*-+\s+/) {
+		    $oops++;
+		    warn "$0: Improper man page - no dash in NAME header in paragraph $. of $ARGV[0]\n"
+                } else {
+		    my @n = split /\s+-+\s+/;
+		    if (@n != 2) {
+			$oops++;
+			warn "$0: Improper man page - malformed NAME header in paragraph $. of $ARGV[0]\n"
+		    }
+		    else {
+			$n[0] =~ s/\n/ /g;
+			$n[1] =~ s/\n/ /g;
+			%namedesc = @n;
+		    }
+		}
+		last FCHECK;
+	    }
+	    next if /^=cut\b/;	# DB_File and Net::Ping have =cut before NAME
+	    next if /^=pod\b/;  # It is OK to have =pod before NAME
+	    next if /^=(for|begin|end)\s+comment\b/;  # It is OK to have =for =begin or =end comment before NAME
+	    die "$0: Invalid man page - 1st pod line is not NAME in $ARGV[0]\n" unless $lax;
+	}
+	die "$0: Invalid man page - no documentation in $ARGV[0]\n" unless $lax;
+    }
+    close F;
+}
+
+print <<"END";
+.rn '' }`
+''' \$RCSfile\$\$Revision\$\$Date\$
+'''
+''' \$Log\$
+'''
+.de Sh
+.br
+.if t .Sp
+.ne 5
+.PP
+\\fB\\\\\$1\\fR
+.PP
+..
+.de Sp
+.if t .sp .5v
+.if n .sp
+..
+.de Ip
+.br
+.ie \\\\n(.\$>=3 .ne \\\\\$3
+.el .ne 3
+.IP "\\\\\$1" \\\\\$2
+..
+.de Vb
+.ft $CFont
+.nf
+.ne \\\\\$1
+..
+.de Ve
+.ft R
+
+.fi
+..
+'''
+'''
+'''     Set up \\*(-- to give an unbreakable dash;
+'''     string Tr holds user defined translation string.
+'''     Bell System Logo is used as a dummy character.
+'''
+.tr \\(*W-|\\(bv\\*(Tr
+.ie n \\{\\
+.ds -- \\(*W-
+.ds PI pi
+.if (\\n(.H=4u)&(1m=24u) .ds -- \\(*W\\h'-12u'\\(*W\\h'-12u'-\\" diablo 10 pitch
+.if (\\n(.H=4u)&(1m=20u) .ds -- \\(*W\\h'-12u'\\(*W\\h'-8u'-\\" diablo 12 pitch
+.ds L" ""
+.ds R" ""
+'''   \\*(M", \\*(S", \\*(N" and \\*(T" are the equivalent of
+'''   \\*(L" and \\*(R", except that they are used on ".xx" lines,
+'''   such as .IP and .SH, which do another additional levels of
+'''   double-quote interpretation
+.ds M" """
+.ds S" """
+.ds N" """""
+.ds T" """""
+.ds L' '
+.ds R' '
+.ds M' '
+.ds S' '
+.ds N' '
+.ds T' '
+'br\\}
+.el\\{\\
+.ds -- \\(em\\|
+.tr \\*(Tr
+.ds L" ``
+.ds R" ''
+.ds M" ``
+.ds S" ''
+.ds N" ``
+.ds T" ''
+.ds L' `
+.ds R' '
+.ds M' `
+.ds S' '
+.ds N' `
+.ds T' '
+.ds PI \\(*p
+'br\\}
+END
+
+print <<'END';
+.\"	If the F register is turned on, we'll generate
+.\"	index entries out stderr for the following things:
+.\"		TH	Title 
+.\"		SH	Header
+.\"		Sh	Subsection 
+.\"		Ip	Item
+.\"		X<>	Xref  (embedded
+.\"	Of course, you have to process the output yourself
+.\"	in some meaninful fashion.
+.if \nF \{
+.de IX
+.tm Index:\\$1\t\\n%\t"\\$2"
+..
+.nr % 0
+.rr F
+.\}
+END
+
+print <<"END";
+.TH $name $section "$RP" "$date" "$center"
+.UC
+END
+
+push(@Indices, qq{.IX Title "$name $section"});
+
+while (($name, $desc) = each %namedesc) {
+    for ($name, $desc) { s/^\s+//; s/\s+$//; }
+    push(@Indices, qq(.IX Name "$name - $desc"\n));
+}
+
+print <<'END';
+.if n .hy 0
+.if n .na
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.de CQ          \" put $1 in typewriter font
+END
+print ".ft $CFont\n";
+print <<'END';
+'if n "\c
+'if t \\&\\$1\c
+'if n \\&\\$1\c
+'if n \&"
+\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7
+'.ft R
+..
+.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2
+.	\" AM - accent mark definitions
+.bd B 3
+.	\" fudge factors for nroff and troff
+.if n \{\
+.	ds #H 0
+.	ds #V .8m
+.	ds #F .3m
+.	ds #[ \f1
+.	ds #] \fP
+.\}
+.if t \{\
+.	ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+.	ds #V .6m
+.	ds #F 0
+.	ds #[ \&
+.	ds #] \&
+.\}
+.	\" simple accents for nroff and troff
+.if n \{\
+.	ds ' \&
+.	ds ` \&
+.	ds ^ \&
+.	ds , \&
+.	ds ~ ~
+.	ds ? ?
+.	ds ! !
+.	ds /
+.	ds q
+.\}
+.if t \{\
+.	ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+.	ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+.	ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+.	ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+.	ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+.	ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10'
+.	ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m'
+.	ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.	ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10'
+.\}
+.	\" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#]
+.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u'
+.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u'
+.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#]
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+.ds oe o\h'-(\w'o'u*4/10)'e
+.ds Oe O\h'-(\w'O'u*4/10)'E
+.	\" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+.	\" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+.	ds : e
+.	ds 8 ss
+.	ds v \h'-1'\o'\(aa\(ga'
+.	ds _ \h'-1'^
+.	ds . \h'-1'.
+.	ds 3 3
+.	ds o a
+.	ds d- d\h'-1'\(ga
+.	ds D- D\h'-1'\(hy
+.	ds th \o'bp'
+.	ds Th \o'LP'
+.	ds ae ae
+.	ds Ae AE
+.	ds oe oe
+.	ds Oe OE
+.\}
+.rm #[ #] #H #V #F C
+END
+
+$indent = 0;
+
+$begun = "";
+
+# Unrolling [^A-Z>]|[A-Z](?!<) gives:    // MRE pp 165.
+my $nonest = '(?:[^A-Z>]*(?:[A-Z](?!<)[^A-Z>]*)*)';
+
+while (<>) {
+    if ($cutting) {
+	next unless /^=/;
+	$cutting = 0;
+    }
+    if ($begun) {
+	if (/^=end\s+$begun/) {
+            $begun = "";
+	}
+	elsif ($begun =~ /^(roff|man)$/) {
+	    print STDOUT $_;
+        }
+	next;
+    }
+    chomp;
+
+    # Translate verbatim paragraph
+
+    if (/^\s/) {
+	@lines = split(/\n/);
+	for (@lines) {
+	    1 while s
+		{^( [^\t]* ) \t ( \t* ) }
+		{ $1 . ' ' x (8 - (length($1)%8) + 8 * (length($2))) }ex;
+	    s/\\/\\e/g;
+	    s/\A/\\&/s;
+	}
+	$lines = @lines;
+	makespace() unless $verbatim++;
+	print ".Vb $lines\n";
+	print join("\n", @lines), "\n";
+	print ".Ve\n";
+	$needspace = 0;
+	next;
+    }
+
+    $verbatim = 0;
+
+    if (/^=for\s+(\S+)\s*/s) {
+	if ($1 eq "man" or $1 eq "roff") {
+	    print STDOUT $',"\n\n";
+	} else {
+	    # ignore unknown for
+	}
+	next;
+    }
+    elsif (/^=begin\s+(\S+)\s*/s) {
+	$begun = $1;
+	if ($1 eq "man" or $1 eq "roff") {
+	    print STDOUT $'."\n\n";
+	}
+	next;
+    }
+
+    # check for things that'll hosed our noremap scheme; affects $_
+    init_noremap();
+
+    if (!/^=item/) {
+
+	# trofficate backslashes; must do it before what happens below
+	s/\\/noremap('\\e')/ge;
+
+	# protect leading periods and quotes against *roff
+	# mistaking them for directives
+	s/^(?:[A-Z]<)?[.']/\\&$&/gm;
+
+	# first hide the escapes in case we need to
+	# intuit something and get it wrong due to fmting
+
+	1 while s/([A-Z]<$nonest>)/noremap($1)/ge;
+
+	# func() is a reference to a perl function
+	s{
+	    \b
+	    (
+		[:\w]+ \(\)
+	    )
+	} {I<$1>}gx;
+
+	# func(n) is a reference to a perl function or a man page
+	s{
+	    ([:\w]+)
+	    (
+		\( [^\051]+ \)
+	    )
+	} {I<$1>\\|$2}gx;
+
+	# convert simple variable references
+	s/(\s+)([\$\@%][\w:]+)(?!\()/${1}C<$2>/g;
+
+	if (m{ (
+		    [\-\w]+
+		    \(
+			[^\051]*?
+			[\@\$,]
+			[^\051]*?
+		    \)
+		)
+	    }x && $` !~ /([LCI]<[^<>]*|-)$/ && !/^=\w/)
+	{
+	    warn "$0: bad option in paragraph $. of $ARGV: ``$1'' should be [LCI]<$1>\n";
+	    $oops++;
+	}
+
+	while (/(-[a-zA-Z])\b/g && $` !~ /[\w\-]$/) {
+	    warn "$0: bad option in paragraph $. of $ARGV: ``$1'' should be [CB]<$1>\n";
+	    $oops++;
+	}
+
+	# put it back so we get the <> processed again;
+	clear_noremap(0); # 0 means leave the E's
+
+    } else {
+	# trofficate backslashes
+	s/\\/noremap('\\e')/ge;
+
+    }
+
+    # need to hide E<> first; they're processed in clear_noremap
+    s/(E<[^<>]+>)/noremap($1)/ge;
+
+
+    $maxnest = 10;
+    while ($maxnest-- && /[A-Z]</) {
+
+	# can't do C font here
+	s/([BI])<($nonest)>/font($1) . $2 . font('R')/eg;
+
+	# files and filelike refs in italics
+	s/F<($nonest)>/I<$1>/g;
+
+	# no break -- usually we want C<> for this
+	s/S<($nonest)>/nobreak($1)/eg;
+
+	# LREF: a la HREF L<show this text|man/section>
+	s:L<([^|>]+)\|[^>]+>:$1:g;
+
+	# LREF: a manpage(3f)
+	s:L<([a-zA-Z][^\s\/]+)(\([^\)]+\))?>:the I<$1>$2 manpage:g;
+
+	# LREF: an =item on another manpage
+	s{
+	    L<
+		([^/]+)
+		/
+		(
+		    [:\w]+
+		    (\(\))?
+		)
+	    >
+	} {the C<$2> entry in the I<$1> manpage}gx;
+
+	# LREF: an =item on this manpage
+	s{
+	   ((?:
+	    L<
+		/
+		(
+		    [:\w]+
+		    (\(\))?
+		)
+	    >
+	    (,?\s+(and\s+)?)?
+	  )+)
+	} { internal_lrefs($1) }gex;
+
+	# LREF: a =head2 (head1?), maybe on a manpage, maybe right here
+	# the "func" can disambiguate
+	s{
+	    L<
+		(?:
+		    ([a-zA-Z]\S+?) /
+		)?
+		"?(.*?)"?
+	    >
+	}{
+	    do {
+		$1 	# if no $1, assume it means on this page.
+		    ?  "the section on I<$2> in the I<$1> manpage"
+		    :  "the section on I<$2>"
+	    }
+	}gesx; # s in case it goes over multiple lines, so . matches \n
+
+	s/Z<>/\\&/g;
+
+	# comes last because not subject to reprocessing
+	s/C<($nonest)>/noremap("${CFont_embed}${1}\\fR")/eg;
+    }
+
+    if (s/^=//) {
+	$needspace = 0;		# Assume this.
+
+	s/\n/ /g;
+
+	($Cmd, $_) = split(' ', $_, 2);
+
+	$dotlevel = 1;
+	if ($Cmd eq 'head1') {
+	   $dotlevel = 1;
+	}
+	elsif ($Cmd eq 'head2') {
+	   $dotlevel = 1;
+	}
+	elsif ($Cmd eq 'item') {
+	   $dotlevel = 2;
+	}
+
+	if (defined $_) {
+	    &escapes($dotlevel);
+	    s/"/""/g;
+	}
+
+	clear_noremap(1);
+
+	if ($Cmd eq 'cut') {
+	    $cutting = 1;
+	}
+	elsif ($Cmd eq 'head1') {
+	    s/\s+$//;
+	    delete $wanna_see{$_} if exists $wanna_see{$_};
+	    print qq{.SH "$_"\n};
+      push(@Indices, qq{.IX Header "$_"\n});
+	}
+	elsif ($Cmd eq 'head2') {
+	    print qq{.Sh "$_"\n};
+      push(@Indices, qq{.IX Subsection "$_"\n});
+	}
+	elsif ($Cmd eq 'over') {
+	    push(@indent,$indent);
+	    $indent += ($_ + 0) || 5;
+	}
+	elsif ($Cmd eq 'back') {
+	    $indent = pop(@indent);
+	    warn "$0: Unmatched =back in paragraph $. of $ARGV\n" unless defined $indent;
+	    $needspace = 1;
+	}
+	elsif ($Cmd eq 'item') {
+	    s/^\*( |$)/\\(bu$1/g;
+	    # if you know how to get ":s please do
+	    s/\\\*\(L"([^"]+?)\\\*\(R"/'$1'/g;
+	    s/\\\*\(L"([^"]+?)""/'$1'/g;
+	    s/[^"]""([^"]+?)""[^"]/'$1'/g;
+	    # here do something about the $" in perlvar?
+	    print STDOUT qq{.Ip "$_" $indent\n};
+      push(@Indices, qq{.IX Item "$_"\n});
+	}
+	elsif ($Cmd eq 'pod') {
+	    # this is just a comment
+	} 
+	else {
+	    warn "$0: Unrecognized pod directive in paragraph $. of $ARGV: $Cmd\n";
+	}
+    }
+    else {
+	if ($needspace) {
+	    &makespace;
+	}
+	&escapes(0);
+	clear_noremap(1);
+	print $_, "\n";
+	$needspace = 1;
+    }
+}
+
+print <<"END";
+
+.rn }` ''
+END
+
+if (%wanna_see && !$lax) {
+    @missing = keys %wanna_see;
+    warn "$0: $Filename is missing required section"
+	.  (@missing > 1 && "s")
+	.  ": @missing\n";
+    $oops++;
+}
+
+foreach (@Indices) { print "$_\n"; }
+
+exit;
+#exit ($oops != 0);
+
+#########################################################################
+
+sub nobreak {
+    my $string = shift;
+    $string =~ s/ /\\ /g;
+    $string;
+}
+
+sub escapes {
+    my $indot = shift;
+
+    s/X<(.*?)>/mkindex($1)/ge;
+
+    # translate the minus in foo-bar into foo\-bar for roff
+    s/([^0-9a-z-])-([^-])/$1\\-$2/g;
+
+    # make -- into the string version \*(-- (defined above)
+    s/\b--\b/\\*(--/g;
+    s/"--([^"])/"\\*(--$1/g;  # should be a better way
+    s/([^"])--"/$1\\*(--"/g;
+
+    # fix up quotes; this is somewhat tricky
+    my $dotmacroL = 'L';
+    my $dotmacroR = 'R';
+    if ( $indot == 1 ) {
+	$dotmacroL = 'M';
+	$dotmacroR = 'S';
+    }  
+    elsif ( $indot >= 2 ) {
+	$dotmacroL = 'N';
+	$dotmacroR = 'T';
+    }  
+    if (!/""/) {
+	s/(^|\s)(['"])/noremap("$1\\*($dotmacroL$2")/ge;
+	s/(['"])($|[\-\s,;\\!?.])/noremap("\\*($dotmacroR$1$2")/ge;
+    }
+
+    #s/(?!")(?:.)--(?!")(?:.)/\\*(--/g;
+    #s/(?:(?!")(?:.)--(?:"))|(?:(?:")--(?!")(?:.))/\\*(--/g;
+
+
+    # make sure that func() keeps a bit a space tween the parens
+    ### s/\b\(\)/\\|()/g;
+    ### s/\b\(\)/(\\|)/g;
+
+    # make C++ into \*C+, which is a squinched version (defined above)
+    s/\bC\+\+/\\*(C+/g;
+
+    # make double underbars have a little tiny space between them
+    s/__/_\\|_/g;
+
+    # PI goes to \*(PI (defined above)
+    s/\bPI\b/noremap('\\*(PI')/ge;
+
+    # make all caps a teeny bit smaller, but don't muck with embedded code literals
+    my $hidCFont = font('C');
+    if ($Cmd !~ /^head1/) { # SH already makes smaller
+	# /g isn't enough; 1 while or we'll be off
+
+#	1 while s{
+#	    (?!$hidCFont)(..|^.|^)
+#	    \b
+#	    (
+#		[A-Z][\/A-Z+:\-\d_$.]+
+#	    )
+#	    (s?) 		
+#	    \b
+#	} {$1\\s-1$2\\s0}gmox;
+
+	1 while s{
+	    (?!$hidCFont)(..|^.|^)
+	    (
+		\b[A-Z]{2,}[\/A-Z+:\-\d_\$]*\b
+	    )
+	} {
+	    $1 . noremap( '\\s-1' .  $2 . '\\s0' )
+	}egmox;
+
+    }
+}
+
+# make troff just be normal, but make small nroff get quoted
+# decided to just put the quotes in the text; sigh;
+sub ccvt {
+    local($_,$prev) = @_;
+    noremap(qq{.CQ "$_" \n\\&});
+}
+
+sub makespace {
+    if ($indent) {
+	print ".Sp\n";
+    }
+    else {
+	print ".PP\n";
+    }
+}
+
+sub mkindex {
+    my ($entry) = @_;
+    my @entries = split m:\s*/\s*:, $entry;
+    push @Indices, ".IX Xref " . join ' ', map {qq("$_")} @entries;
+    return '';
+}
+
+sub font {
+    local($font) = shift;
+    return '\\f' . noremap($font);
+}
+
+sub noremap {
+    local($thing_to_hide) = shift;
+    $thing_to_hide =~ tr/\000-\177/\200-\377/;
+    return $thing_to_hide;
+}
+
+sub init_noremap {
+	# escape high bit characters in input stream
+	s/([\200-\377])/"E<".ord($1).">"/ge;
+}
+
+sub clear_noremap {
+    my $ready_to_print = $_[0];
+
+    tr/\200-\377/\000-\177/;
+
+    # trofficate backslashes
+    # s/(?!\\e)(?:..|^.|^)\\/\\e/g;
+
+    # now for the E<>s, which have been hidden until now
+    # otherwise the interative \w<> processing would have
+    # been hosed by the E<gt>
+    s {
+	    E<
+	    (
+	        ( \d + ) 
+	        | ( [A-Za-z]+ )	
+	    )
+	    >	
+    } {
+	 do {
+	     defined $2
+		? chr($2)
+		:	
+	     exists $HTML_Escapes{$3}
+		? do { $HTML_Escapes{$3} }
+		: do {
+		    warn "$0: Unknown escape in paragraph $. of $ARGV: ``$&''\n";
+		    "E<$1>";
+		}
+	 }
+    }egx if $ready_to_print;
+}
+
+sub internal_lrefs {
+    local($_) = shift;
+    local $trailing_and = s/and\s+$// ? "and " : "";
+
+    s{L</([^>]+)>}{$1}g;
+    my(@items) = split( /(?:,?\s+(?:and\s+)?)/ );
+    my $retstr = "the ";
+    my $i;
+    for ($i = 0; $i <= $#items; $i++) {
+	$retstr .= "C<$items[$i]>";
+	$retstr .= ", " if @items > 2 && $i != $#items;
+	$retstr .= " and " if $i+2 == @items;
+    }
+
+    $retstr .= " entr" . ( @items > 1  ? "ies" : "y" )
+	    .  " elsewhere in this document";
+    # terminal space to avoid words running together (pattern used
+    # strips terminal spaces)
+    $retstr .= " " if length $trailing_and;
+    $retstr .=  $trailing_and;
+
+    return $retstr;
+
+}
+
+BEGIN {
+%HTML_Escapes = (
+    'amp'	=>	'&',	#   ampersand
+    'lt'	=>	'<',	#   left chevron, less-than
+    'gt'	=>	'>',	#   right chevron, greater-than
+    'quot'	=>	'"',	#   double quote
+
+    "Aacute"	=>	"A\\*'",	#   capital A, acute accent
+    "aacute"	=>	"a\\*'",	#   small a, acute accent
+    "Acirc"	=>	"A\\*^",	#   capital A, circumflex accent
+    "acirc"	=>	"a\\*^",	#   small a, circumflex accent
+    "AElig"	=>	'\*(AE',	#   capital AE diphthong (ligature)
+    "aelig"	=>	'\*(ae',	#   small ae diphthong (ligature)
+    "Agrave"	=>	"A\\*`",	#   capital A, grave accent
+    "agrave"	=>	"A\\*`",	#   small a, grave accent
+    "Aring"	=>	'A\\*o',	#   capital A, ring
+    "aring"	=>	'a\\*o',	#   small a, ring
+    "Atilde"	=>	'A\\*~',	#   capital A, tilde
+    "atilde"	=>	'a\\*~',	#   small a, tilde
+    "Auml"	=>	'A\\*:',	#   capital A, dieresis or umlaut mark
+    "auml"	=>	'a\\*:',	#   small a, dieresis or umlaut mark
+    "Ccedil"	=>	'C\\*,',	#   capital C, cedilla
+    "ccedil"	=>	'c\\*,',	#   small c, cedilla
+    "Eacute"	=>	"E\\*'",	#   capital E, acute accent
+    "eacute"	=>	"e\\*'",	#   small e, acute accent
+    "Ecirc"	=>	"E\\*^",	#   capital E, circumflex accent
+    "ecirc"	=>	"e\\*^",	#   small e, circumflex accent
+    "Egrave"	=>	"E\\*`",	#   capital E, grave accent
+    "egrave"	=>	"e\\*`",	#   small e, grave accent
+    "ETH"	=>	'\\*(D-',	#   capital Eth, Icelandic
+    "eth"	=>	'\\*(d-',	#   small eth, Icelandic
+    "Euml"	=>	"E\\*:",	#   capital E, dieresis or umlaut mark
+    "euml"	=>	"e\\*:",	#   small e, dieresis or umlaut mark
+    "Iacute"	=>	"I\\*'",	#   capital I, acute accent
+    "iacute"	=>	"i\\*'",	#   small i, acute accent
+    "Icirc"	=>	"I\\*^",	#   capital I, circumflex accent
+    "icirc"	=>	"i\\*^",	#   small i, circumflex accent
+    "Igrave"	=>	"I\\*`",	#   capital I, grave accent
+    "igrave"	=>	"i\\*`",	#   small i, grave accent
+    "Iuml"	=>	"I\\*:",	#   capital I, dieresis or umlaut mark
+    "iuml"	=>	"i\\*:",	#   small i, dieresis or umlaut mark
+    "Ntilde"	=>	'N\*~',		#   capital N, tilde
+    "ntilde"	=>	'n\*~',		#   small n, tilde
+    "Oacute"	=>	"O\\*'",	#   capital O, acute accent
+    "oacute"	=>	"o\\*'",	#   small o, acute accent
+    "Ocirc"	=>	"O\\*^",	#   capital O, circumflex accent
+    "ocirc"	=>	"o\\*^",	#   small o, circumflex accent
+    "Ograve"	=>	"O\\*`",	#   capital O, grave accent
+    "ograve"	=>	"o\\*`",	#   small o, grave accent
+    "Oslash"	=>	"O\\*/",	#   capital O, slash
+    "oslash"	=>	"o\\*/",	#   small o, slash
+    "Otilde"	=>	"O\\*~",	#   capital O, tilde
+    "otilde"	=>	"o\\*~",	#   small o, tilde
+    "Ouml"	=>	"O\\*:",	#   capital O, dieresis or umlaut mark
+    "ouml"	=>	"o\\*:",	#   small o, dieresis or umlaut mark
+    "szlig"	=>	'\*8',		#   small sharp s, German (sz ligature)
+    "THORN"	=>	'\\*(Th',	#   capital THORN, Icelandic
+    "thorn"	=>	'\\*(th',,	#   small thorn, Icelandic
+    "Uacute"	=>	"U\\*'",	#   capital U, acute accent
+    "uacute"	=>	"u\\*'",	#   small u, acute accent
+    "Ucirc"	=>	"U\\*^",	#   capital U, circumflex accent
+    "ucirc"	=>	"u\\*^",	#   small u, circumflex accent
+    "Ugrave"	=>	"U\\*`",	#   capital U, grave accent
+    "ugrave"	=>	"u\\*`",	#   small u, grave accent
+    "Uuml"	=>	"U\\*:",	#   capital U, dieresis or umlaut mark
+    "uuml"	=>	"u\\*:",	#   small u, dieresis or umlaut mark
+    "Yacute"	=>	"Y\\*'",	#   capital Y, acute accent
+    "yacute"	=>	"y\\*'",	#   small y, acute accent
+    "yuml"	=>	"y\\*:",	#   small y, dieresis or umlaut mark
+);
+}
+
diff --git a/openssl/util/pod2mantest b/openssl/util/pod2mantest
new file mode 100755
index 0000000..384e683
--- /dev/null
+++ b/openssl/util/pod2mantest
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+# This script is used by test/Makefile to check whether a sane 'pod2man'
+# is installed.
+# ('make install' should not try to run 'pod2man' if it does not exist or if
+# it is a broken 'pod2man' version that is known to cause trouble. if we find
+# the system 'pod2man' to be broken, we use our own copy instead)
+#
+# In any case, output an appropriate command line for running (or not
+# running) pod2man.
+
+
+IFS=:
+if test "$OSTYPE" = "msdosdjgpp"; then IFS=";"; fi
+
+try_without_dir=true
+# First we try "pod2man", then "$dir/pod2man" for each item in $PATH.
+for dir in dummy${IFS}$PATH; do
+    if [ "$try_without_dir" = true ]; then
+      # first iteration
+      pod2man=pod2man
+      try_without_dir=false
+    else
+      # second and later iterations
+      pod2man="$dir/pod2man"
+      if [ ! -f "$pod2man" ]; then  # '-x' is not available on Ultrix
+        pod2man=''
+      fi
+    fi
+
+    if [ ! "$pod2man" = '' ]; then
+        failure=none
+
+	if "$pod2man" --section=1 --center=OpenSSL --release=dev pod2mantest.pod | fgrep OpenSSL >/dev/null; then
+	    :
+	else
+	    failure=BasicTest
+	fi
+
+	if [ "$failure" = none ]; then
+	    if "$pod2man" --section=1 --center=OpenSSL --release=dev pod2mantest.pod | grep '^MARKER - ' >/dev/null; then
+	        failure=MultilineTest
+	    fi
+	fi
+
+
+        if [ "$failure" = none ]; then
+            echo "$pod2man"
+            exit 0
+        fi
+
+        echo "$pod2man does not work properly ('$failure' failed).  Looking for another pod2man ..." >&2
+    fi
+done
+
+echo "No working pod2man found.  Consider installing a new version." >&2
+echo "As a workaround, we'll use a bundled old copy of pod2man.pl." >&2
+echo "$1 ../../util/pod2man.pl"
diff --git a/openssl/util/pod2mantest.pod b/openssl/util/pod2mantest.pod
new file mode 100644
index 0000000..5d2539a
--- /dev/null
+++ b/openssl/util/pod2mantest.pod
@@ -0,0 +1,15 @@
+=pod
+
+=head1 NAME
+
+foo, bar,
+MARKER - test of multiline name section
+
+=head1 DESCRIPTION
+
+This is a test .pod file to see if we have a buggy pod2man or not.
+If we have a buggy implementation, we will get a line matching the
+regular expression "^ +MARKER - test of multiline name section *$"
+at the end of the resulting document.
+
+=cut
diff --git a/openssl/util/point.sh b/openssl/util/point.sh
new file mode 100755
index 0000000..da39899
--- /dev/null
+++ b/openssl/util/point.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+rm -f "$2"
+if test "$OSTYPE" = msdosdjgpp || test "x$PLATFORM" = xmingw ; then
+    cp "$1" "$2"
+else
+    ln -s "$1" "$2"
+fi
+echo "$2 => $1"
+
diff --git a/openssl/util/selftest.pl b/openssl/util/selftest.pl
new file mode 100644
index 0000000..7b32e9f
--- /dev/null
+++ b/openssl/util/selftest.pl
@@ -0,0 +1,201 @@
+#!/usr/local/bin/perl -w
+#
+# Run the test suite and generate a report
+#
+
+if (! -f "Configure") {
+    print "Please run perl util/selftest.pl in the OpenSSL directory.\n";
+    exit 1;
+}
+
+my $report="testlog";
+my $os="??";
+my $version="??";
+my $platform0="??";
+my $platform="??";
+my $options="??";
+my $last="??";
+my $ok=0;
+my $cc="cc";
+my $cversion="??";
+my $sep="-----------------------------------------------------------------------------\n";
+my $not_our_fault="\nPlease ask your system administrator/vendor for more information.\n[Problems with your operating system setup should not be reported\nto the OpenSSL project.]\n";
+
+open(OUT,">$report") or die;
+
+print OUT "OpenSSL self-test report:\n\n";
+
+$uname=`uname -a`;
+$uname="??\n" if $uname eq "";
+
+$c=`sh config -t`;
+foreach $_ (split("\n",$c)) {
+    $os=$1 if (/Operating system: (.*)$/);
+    $platform0=$1 if (/Configuring for (.*)$/);
+}
+
+system "sh config" if (! -f "Makefile");
+
+if (open(IN,"<Makefile")) {
+    while (<IN>) {
+	$version=$1 if (/^VERSION=(.*)$/);
+	$platform=$1 if (/^PLATFORM=(.*)$/);
+	$options=$1 if (/^OPTIONS=(.*)$/);
+	$cc=$1 if (/^CC= *(.*)$/);
+    }
+    close(IN);
+} else {
+    print OUT "Error running config!\n";
+}
+
+$cversion=`$cc -v 2>&1`;
+$cversion=`$cc -V 2>&1` if $cversion =~ "[Uu]sage";
+$cversion=`$cc -V |head -1` if $cversion =~ "Error";
+$cversion=`$cc --version` if $cversion eq "";
+$cversion =~ s/Reading specs.*\n//;
+$cversion =~ s/usage.*\n//;
+chomp $cversion;
+
+if (open(IN,"<CHANGES")) {
+    while(<IN>) {
+	if (/\*\) (.{0,55})/ && !/applies to/) {
+	    $last=$1;
+	    last;
+	}
+    }
+    close(IN);
+}
+
+print OUT "OpenSSL version:  $version\n";
+print OUT "Last change:      $last...\n";
+print OUT "Options:          $options\n" if $options ne "";
+print OUT "OS (uname):       $uname";
+print OUT "OS (config):      $os\n";
+print OUT "Target (default): $platform0\n";
+print OUT "Target:           $platform\n";
+print OUT "Compiler:         $cversion\n";
+print OUT "\n";
+
+print "Checking compiler...\n";
+if (open(TEST,">cctest.c")) {
+    print TEST "#include <stdio.h>\n#include <stdlib.h>\n#include <errno.h>\nmain(){printf(\"Hello world\\n\");}\n";
+    close(TEST);
+    system("$cc -o cctest cctest.c");
+    if (`./cctest` !~ /Hello world/) {
+	print OUT "Compiler doesn't work.\n";
+	print OUT $not_our_fault;
+	goto err;
+    }
+    system("ar r cctest.a /dev/null");
+    if (not -f "cctest.a") {
+	print OUT "Check your archive tool (ar).\n";
+	print OUT $not_our_fault;
+	goto err;
+    }
+} else {
+    print OUT "Can't create cctest.c\n";
+}
+if (open(TEST,">cctest.c")) {
+    print TEST "#include <stdio.h>\n#include <stdlib.h>\n#include <openssl/opensslv.h>\nmain(){printf(OPENSSL_VERSION_TEXT);}\n";
+    close(TEST);
+    system("$cc -o cctest -Iinclude cctest.c");
+    $cctest = `./cctest`;
+    if ($cctest !~ /OpenSSL $version/) {
+	if ($cctest =~ /OpenSSL/) {
+	    print OUT "#include uses headers from different OpenSSL version!\n";
+	} else {
+	    print OUT "Can't compile test program!\n";
+	}
+	print OUT $not_our_fault;
+	goto err;
+    }
+} else {
+    print OUT "Can't create cctest.c\n";
+}
+
+print "Running make...\n";
+if (system("make 2>&1 | tee make.log") > 255) {
+
+    print OUT "make failed!\n";
+    if (open(IN,"<make.log")) {
+	print OUT $sep;
+	while (<IN>) {
+	    print OUT;
+	}
+	close(IN);
+	print OUT $sep;
+    } else {
+	print OUT "make.log not found!\n";
+    }
+    goto err;
+}
+
+# Not sure why this is here.  The tests themselves can detect if their
+# particular feature isn't included, and should therefore skip themselves.
+# To skip *all* tests just because one algorithm isn't included is like
+# shooting mosquito with an elephant gun...
+#                   -- Richard Levitte, inspired by problem report 1089
+#
+#$_=$options;
+#s/no-asm//;
+#s/no-shared//;
+#s/no-krb5//;
+#if (/no-/)
+#{
+#    print OUT "Test skipped.\n";
+#    goto err;
+#}
+
+print "Running make test...\n";
+if (system("make test 2>&1 | tee maketest.log") > 255)
+ {
+    print OUT "make test failed!\n";
+} else {
+    $ok=1;
+}
+
+if ($ok and open(IN,"<maketest.log")) {
+    while (<IN>) {
+	$ok=2 if /^platform: $platform/;
+    }
+    close(IN);
+}
+
+if ($ok != 2) {
+    print OUT "Failure!\n";
+    if (open(IN,"<make.log")) {
+	print OUT $sep;
+	while (<IN>) {
+	    print OUT;
+	}
+	close(IN);
+	print OUT $sep;
+    } else {
+	print OUT "make.log not found!\n";
+    }
+    if (open(IN,"<maketest.log")) {
+	while (<IN>) {
+	    print OUT;
+	}
+	close(IN);
+	print OUT $sep;
+    } else {
+	print OUT "maketest.log not found!\n";
+    }
+} else {
+    print OUT "Test passed.\n";
+}
+err:
+close(OUT);
+
+print "\n";
+open(IN,"<$report") or die;
+while (<IN>) {
+    if (/$sep/) {
+	print "[...]\n";
+	last;
+    }
+    print;
+}
+print "\nTest report in file $report\n";
+
diff --git a/openssl/util/shlib_wrap.sh b/openssl/util/shlib_wrap.sh
new file mode 100755
index 0000000..9416d59
--- /dev/null
+++ b/openssl/util/shlib_wrap.sh
@@ -0,0 +1,93 @@
+#!/bin/sh
+
+[ $# -ne 0 ] || set -x		# debug mode without arguments:-)
+
+THERE="`echo $0 | sed -e 's|[^/]*$||' 2>/dev/null`.."
+[ -d "${THERE}" ] || exec "$@"	# should never happen...
+
+# Alternative to this is to parse ${THERE}/Makefile...
+LIBCRYPTOSO="${THERE}/libcrypto.so"
+if [ -f "$LIBCRYPTOSO" ]; then
+    while [ -h "$LIBCRYPTOSO" ]; do
+	LIBCRYPTOSO="${THERE}/`ls -l "$LIBCRYPTOSO" | sed -e 's|.*\-> ||'`"
+    done
+    SOSUFFIX=`echo ${LIBCRYPTOSO} | sed -e 's|.*\.so||' 2>/dev/null`
+    LIBSSLSO="${THERE}/libssl.so${SOSUFFIX}"
+fi
+
+SYSNAME=`(uname -s) 2>/dev/null`;
+case "$SYSNAME" in
+SunOS|IRIX*)
+	# SunOS and IRIX run-time linkers evaluate alternative
+	# variables depending on target ABI...
+	rld_var=LD_LIBRARY_PATH
+	case "`(/usr/bin/file "$LIBCRYPTOSO") 2>/dev/null`" in
+	*ELF\ 64*SPARC*|*ELF\ 64*AMD64*)
+		[ -n "$LD_LIBRARY_PATH_64" ] && rld_var=LD_LIBRARY_PATH_64
+		LD_PRELOAD_64="$LIBCRYPTOSO $LIBSSLSO"; export LD_PRELOAD_64
+		preload_var=LD_PRELOAD_64
+		;;
+	# Why are newly built .so's preloaded anyway? Because run-time
+	# .so lookup path embedded into application takes precedence
+	# over LD_LIBRARY_PATH and as result application ends up linking
+	# to previously installed .so's. On IRIX instead of preloading
+	# newly built .so's we trick run-time linker to fail to find
+	# the installed .so by setting _RLD_ROOT variable.
+	*ELF\ 32*MIPS*)
+		#_RLD_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"; export _RLD_LIST
+		_RLD_ROOT=/no/such/dir; export _RLD_ROOT
+		eval $rld_var=\"/usr/lib'${'$rld_var':+:$'$rld_var'}'\"
+		preload_var=_RLD_LIST
+		;;
+	*ELF\ N32*MIPS*)
+		[ -n "$LD_LIBRARYN32_PATH" ] && rld_var=LD_LIBRARYN32_PATH
+		#_RLDN32_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"; export _RLDN32_LIST
+		_RLDN32_ROOT=/no/such/dir; export _RLDN32_ROOT
+		eval $rld_var=\"/usr/lib32'${'$rld_var':+:$'$rld_var'}'\"
+		preload_var=_RLDN32_LIST
+		;;
+	*ELF\ 64*MIPS*)
+		[ -n "$LD_LIBRARY64_PATH"  ] && rld_var=LD_LIBRARY64_PATH
+		#_RLD64_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"; export _RLD64_LIST
+		_RLD64_ROOT=/no/such/dir; export _RLD64_ROOT
+		eval $rld_var=\"/usr/lib64'${'$rld_var':+:$'$rld_var'}'\"
+		preload_var=_RLD64_LIST
+		;;
+	esac
+	eval $rld_var=\"${THERE}'${'$rld_var':+:$'$rld_var'}'\"; export $rld_var
+	unset rld_var
+	;;
+*)	LD_LIBRARY_PATH="${THERE}:$LD_LIBRARY_PATH"	# Linux, ELF HP-UX
+	DYLD_LIBRARY_PATH="${THERE}:$DYLD_LIBRARY_PATH"	# MacOS X
+	SHLIB_PATH="${THERE}:$SHLIB_PATH"		# legacy HP-UX
+	LIBPATH="${THERE}:$LIBPATH"			# AIX, OS/2
+	export LD_LIBRARY_PATH DYLD_LIBRARY_PATH SHLIB_PATH LIBPATH
+	# Even though $PATH is adjusted [for Windows sake], it doesn't
+	# necessarily does the trick. Trouble is that with introduction
+	# of SafeDllSearchMode in XP/2003 it's more appropriate to copy
+	# .DLLs in vicinity of executable, which is done elsewhere...
+	if [ "$OSTYPE" != msdosdjgpp ]; then
+		PATH="${THERE}:$PATH"; export PATH
+	fi
+	;;
+esac
+
+if [ -f "$LIBCRYPTOSO" -a -z "$preload_var" ]; then
+	# Following three lines are major excuse for isolating them into
+	# this wrapper script. Original reason for setting LD_PRELOAD
+	# was to make it possible to pass 'make test' when user linked
+	# with -rpath pointing to previous version installation. Wrapping
+	# it into a script makes it possible to do so on multi-ABI
+	# platforms.
+	case "$SYSNAME" in
+	*BSD|QNX)	LD_PRELOAD="$LIBCRYPTOSO:$LIBSSLSO" ;;	# *BSD, QNX
+	*)	LD_PRELOAD="$LIBCRYPTOSO $LIBSSLSO" ;;	# SunOS, Linux, ELF HP-UX
+	esac
+	_RLD_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"	# Tru64, o32 IRIX
+	DYLD_INSERT_LIBRARIES="$LIBCRYPTOSO:$LIBSSLSO"	# MacOS X
+	export LD_PRELOAD _RLD_LIST DYLD_INSERT_LIBRARIES
+fi
+
+cmd="$1${EXE_EXT}"
+shift
+exec "$cmd" "$@"
diff --git a/openssl/util/sp-diff.pl b/openssl/util/sp-diff.pl
new file mode 100755
index 0000000..9d6c603
--- /dev/null
+++ b/openssl/util/sp-diff.pl
@@ -0,0 +1,80 @@
+#!/usr/local/bin/perl
+#
+# This file takes as input, the files that have been output from
+# ssleay speed.
+# It prints a table of the relative differences with %100 being 'no difference'
+#
+
+($#ARGV == 1) || die "$0 speedout1 speedout2\n";
+
+%one=&loadfile($ARGV[0]);
+%two=&loadfile($ARGV[1]);
+
+$line=0;
+foreach $a ("md2","md4","md5","sha","sha1","rc4","des cfb","des cbc","des ede3",
+	"idea cfb","idea cbc","rc2 cfb","rc2 cbc","blowfish cbc","cast cbc")
+	{
+	if (defined($one{$a,8}) && defined($two{$a,8}))
+		{
+		print "type              8 byte%    64 byte%   256 byte%  1024 byte%  8192 byte%\n"
+			unless $line;
+		$line++;
+		printf "%-12s ",$a;
+		foreach $b (8,64,256,1024,8192)
+			{
+			$r=$two{$a,$b}/$one{$a,$b}*100;
+			printf "%12.2f",$r;
+			}
+		print "\n";
+		}
+	}
+
+foreach $a	(
+		"rsa  512","rsa 1024","rsa 2048","rsa 4096",
+		"dsa  512","dsa 1024","dsa 2048",
+		)
+	{
+	if (defined($one{$a,1}) && defined($two{$a,1}))
+		{
+		$r1=($one{$a,1}/$two{$a,1})*100;
+		$r2=($one{$a,2}/$two{$a,2})*100;
+		printf "$a bits %%    %6.2f %%    %6.2f\n",$r1,$r2;
+		}
+	}
+
+sub loadfile
+	{
+	local($file)=@_;
+	local($_,%ret);
+
+	open(IN,"<$file") || die "unable to open '$file' for input\n";
+	$header=1;
+	while (<IN>)
+		{
+		$header=0 if /^[dr]sa/;
+		if (/^type/) { $header=0; next; }
+		next if $header;
+		chop;
+		@a=split;
+		if ($a[0] =~ /^[dr]sa$/)
+			{
+			($n,$t1,$t2)=($_ =~ /^([dr]sa\s+\d+)\s+bits\s+([.\d]+)s\s+([.\d]+)/);
+			$ret{$n,1}=$t1;
+			$ret{$n,2}=$t2;
+			}
+		else
+			{
+			$n=join(' ',grep(/[^k]$/,@a));
+			@k=grep(s/k$//,@a);
+			
+			$ret{$n,   8}=$k[0];
+			$ret{$n,  64}=$k[1];
+			$ret{$n, 256}=$k[2];
+			$ret{$n,1024}=$k[3];
+			$ret{$n,8192}=$k[4];
+			}
+		}
+	close(IN);
+	return(%ret);
+	}
+
diff --git a/openssl/util/speed.sh b/openssl/util/speed.sh
new file mode 100755
index 0000000..f489706
--- /dev/null
+++ b/openssl/util/speed.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+#
+# This is a ugly script use, in conjuction with editing the 'b'
+# configuration in the $(TOP)/Configure script which will
+# output when finished a file called speed.log which is the
+# timings of SSLeay with various options turned on or off.
+#
+# from the $(TOP) directory
+# Edit Configure, modifying things to do with the b/bl-4c-2c etc
+# configurations.
+#
+
+make clean
+perl Configure b
+make
+apps/ssleay version -v -b -f >speed.1
+apps/ssleay speed >speed.1l
+
+perl Configure bl-4c-2c
+/bin/rm -f crypto/rc4/*.o crypto/bn/bn*.o crypto/md2/md2_dgst.o
+make
+apps/ssleay speed rc4 rsa md2 >speed.2l
+
+perl Configure bl-4c-ri
+/bin/rm -f crypto/rc4/rc4*.o
+make
+apps/ssleay speed rc4 >speed.3l
+
+perl Configure b2-is-ri-dp
+/bin/rm -f crypto/idea/i_*.o crypto/rc4/*.o crypto/des/ecb_enc.o crypto/bn/bn*.o
+apps/ssleay speed rsa rc4 idea des >speed.4l
+
+cat speed.1 >speed.log
+cat speed.1l >>speed.log
+perl util/sp-diff.pl speed.1l speed.2l >>speed.log
+perl util/sp-diff.pl speed.1l speed.3l >>speed.log
+perl util/sp-diff.pl speed.1l speed.4l >>speed.log
+
diff --git a/openssl/util/src-dep.pl b/openssl/util/src-dep.pl
new file mode 100755
index 0000000..ad997e4
--- /dev/null
+++ b/openssl/util/src-dep.pl
@@ -0,0 +1,147 @@
+#!/usr/local/bin/perl
+
+# we make up an array of
+# $file{function_name}=filename;
+# $unres{filename}="func1 func2 ...."
+$debug=1;
+#$nm_func="parse_linux";
+$nm_func="parse_solaris";
+
+foreach (@ARGV)
+	{
+	&$nm_func($_);
+	}
+
+foreach $file (sort keys %unres)
+	{
+	@a=split(/\s+/,$unres{$file});
+	%ff=();
+	foreach $func (@a)
+		{
+		$f=$file{$func};
+		$ff{$f}=1 if $f ne "";
+		}
+
+	foreach $a (keys %ff)
+		{ $we_need{$file}.="$a "; }
+	}
+
+foreach $file (sort keys %we_need)
+	{
+#	print "	$file $we_need{$file}\n";
+	foreach $bit (split(/\s+/,$we_need{$file}))
+		{ push(@final,&walk($bit)); }
+
+	foreach (@final) { $fin{$_}=1; }
+	@final="";
+	foreach (sort keys %fin)
+		{ push(@final,$_); }
+
+	print "$file: @final\n";
+	}
+
+sub walk
+	{
+	local($f)=@_;
+	local(@a,%seen,@ret,$r);
+
+	@ret="";
+	$f =~ s/^\s+//;
+	$f =~ s/\s+$//;
+	return "" if ($f =~ "^\s*$");
+
+	return(split(/\s/,$done{$f})) if defined ($done{$f});
+
+	return if $in{$f} > 0;
+	$in{$f}++;
+	push(@ret,$f);
+	foreach $r (split(/\s+/,$we_need{$f}))
+		{
+		push(@ret,&walk($r));
+		}
+	$in{$f}--;
+	$done{$f}=join(" ",@ret);
+	return(@ret);
+	}
+
+sub parse_linux
+	{
+	local($name)=@_;
+
+	open(IN,"nm $name|") || die "unable to run 'nn $name':$!\n";
+	while (<IN>)
+		{
+		chop;
+		next if /^\s*$/;
+		if (/^[^[](.*):$/)
+			{
+			$file=$1;
+			$file="$1.c" if /\[(.*).o\]/;
+			print STDERR "$file\n";
+			$we_need{$file}=" ";
+			next;
+			}
+
+		@a=split(/\s*\|\s*/);
+		next unless $#a == 7;
+		next unless $a[4] eq "GLOB";
+		if ($a[6] eq "UNDEF")
+			{
+			$unres{$file}.=$a[7]." ";
+			}
+		else
+			{
+			if ($file{$a[7]} ne "")
+				{
+				print STDERR "duplicate definition of $a[7],\n$file{$a[7]} and $file \n";
+				}
+			else
+				{
+				$file{$a[7]}=$file;
+				}
+			}
+		}
+	close(IN);
+	}
+
+sub parse_solaris
+	{
+	local($name)=@_;
+
+	open(IN,"nm $name|") || die "unable to run 'nn $name':$!\n";
+	while (<IN>)
+		{
+		chop;
+		next if /^\s*$/;
+		if (/^(\S+):$/)
+			{
+			$file=$1;
+			#$file="$1.c" if $file =~ /^(.*).o$/;
+			print STDERR "$file\n";
+			$we_need{$file}=" ";
+			next;
+			}
+		@a=split(/\s*\|\s*/);
+		next unless $#a == 7;
+		next unless $a[4] eq "GLOB";
+		if ($a[6] eq "UNDEF")
+			{
+			$unres{$file}.=$a[7]." ";
+			print STDERR "$file needs $a[7]\n" if $debug;
+			}
+		else
+			{
+			if ($file{$a[7]} ne "")
+				{
+				print STDERR "duplicate definition of $a[7],\n$file{$a[7]} and $file \n";
+				}
+			else
+				{
+				$file{$a[7]}=$file;
+				print STDERR "$file has $a[7]\n" if $debug;
+				}
+			}
+		}
+	close(IN);
+	}
+
diff --git a/openssl/util/ssleay.num b/openssl/util/ssleay.num
new file mode 100755
index 0000000..15a58e7
--- /dev/null
+++ b/openssl/util/ssleay.num
@@ -0,0 +1,261 @@
+ERR_load_SSL_strings                    1	EXIST::FUNCTION:
+SSL_CIPHER_description                  2	EXIST::FUNCTION:
+SSL_CTX_add_client_CA                   3	EXIST::FUNCTION:
+SSL_CTX_add_session                     4	EXIST::FUNCTION:
+SSL_CTX_check_private_key               5	EXIST::FUNCTION:
+SSL_CTX_ctrl                            6	EXIST::FUNCTION:
+SSL_CTX_flush_sessions                  7	EXIST::FUNCTION:
+SSL_CTX_free                            8	EXIST::FUNCTION:
+SSL_CTX_get_client_CA_list              9	EXIST::FUNCTION:
+SSL_CTX_get_verify_callback             10	EXIST::FUNCTION:
+SSL_CTX_get_verify_mode                 11	EXIST::FUNCTION:
+SSL_CTX_new                             12	EXIST::FUNCTION:
+SSL_CTX_remove_session                  13	EXIST::FUNCTION:
+SSL_CTX_set_cipher_list                 15	EXIST::FUNCTION:
+SSL_CTX_set_client_CA_list              16	EXIST::FUNCTION:
+SSL_CTX_set_default_passwd_cb           17	EXIST::FUNCTION:
+SSL_CTX_set_ssl_version                 19	EXIST::FUNCTION:
+SSL_CTX_set_verify                      21	EXIST::FUNCTION:
+SSL_CTX_use_PrivateKey                  22	EXIST::FUNCTION:
+SSL_CTX_use_PrivateKey_ASN1             23	EXIST::FUNCTION:
+SSL_CTX_use_PrivateKey_file             24	EXIST::FUNCTION:STDIO
+SSL_CTX_use_RSAPrivateKey               25	EXIST::FUNCTION:RSA
+SSL_CTX_use_RSAPrivateKey_ASN1          26	EXIST::FUNCTION:RSA
+SSL_CTX_use_RSAPrivateKey_file          27	EXIST::FUNCTION:RSA,STDIO
+SSL_CTX_use_certificate                 28	EXIST::FUNCTION:
+SSL_CTX_use_certificate_ASN1            29	EXIST::FUNCTION:
+SSL_CTX_use_certificate_file            30	EXIST::FUNCTION:STDIO
+SSL_SESSION_free                        31	EXIST::FUNCTION:
+SSL_SESSION_new                         32	EXIST::FUNCTION:
+SSL_SESSION_print                       33	EXIST::FUNCTION:BIO
+SSL_SESSION_print_fp                    34	EXIST::FUNCTION:FP_API
+SSL_accept                              35	EXIST::FUNCTION:
+SSL_add_client_CA                       36	EXIST::FUNCTION:
+SSL_alert_desc_string                   37	EXIST::FUNCTION:
+SSL_alert_desc_string_long              38	EXIST::FUNCTION:
+SSL_alert_type_string                   39	EXIST::FUNCTION:
+SSL_alert_type_string_long              40	EXIST::FUNCTION:
+SSL_check_private_key                   41	EXIST::FUNCTION:
+SSL_clear                               42	EXIST::FUNCTION:
+SSL_connect                             43	EXIST::FUNCTION:
+SSL_copy_session_id                     44	EXIST::FUNCTION:
+SSL_ctrl                                45	EXIST::FUNCTION:
+SSL_dup                                 46	EXIST::FUNCTION:
+SSL_dup_CA_list                         47	EXIST::FUNCTION:
+SSL_free                                48	EXIST::FUNCTION:
+SSL_get_certificate                     49	EXIST::FUNCTION:
+SSL_get_cipher_list                     52	EXIST::FUNCTION:
+SSL_get_ciphers                         55	EXIST::FUNCTION:
+SSL_get_client_CA_list                  56	EXIST::FUNCTION:
+SSL_get_default_timeout                 57	EXIST::FUNCTION:
+SSL_get_error                           58	EXIST::FUNCTION:
+SSL_get_fd                              59	EXIST::FUNCTION:
+SSL_get_peer_cert_chain                 60	EXIST::FUNCTION:
+SSL_get_peer_certificate                61	EXIST::FUNCTION:
+SSL_get_rbio                            63	EXIST::FUNCTION:BIO
+SSL_get_read_ahead                      64	EXIST::FUNCTION:
+SSL_get_shared_ciphers                  65	EXIST::FUNCTION:
+SSL_get_ssl_method                      66	EXIST::FUNCTION:
+SSL_get_verify_callback                 69	EXIST::FUNCTION:
+SSL_get_verify_mode                     70	EXIST::FUNCTION:
+SSL_get_version                         71	EXIST::FUNCTION:
+SSL_get_wbio                            72	EXIST::FUNCTION:BIO
+SSL_load_client_CA_file                 73	EXIST::FUNCTION:STDIO
+SSL_load_error_strings                  74	EXIST::FUNCTION:
+SSL_new                                 75	EXIST::FUNCTION:
+SSL_peek                                76	EXIST::FUNCTION:
+SSL_pending                             77	EXIST::FUNCTION:
+SSL_read                                78	EXIST::FUNCTION:
+SSL_renegotiate                         79	EXIST::FUNCTION:
+SSL_rstate_string                       80	EXIST::FUNCTION:
+SSL_rstate_string_long                  81	EXIST::FUNCTION:
+SSL_set_accept_state                    82	EXIST::FUNCTION:
+SSL_set_bio                             83	EXIST::FUNCTION:BIO
+SSL_set_cipher_list                     84	EXIST::FUNCTION:
+SSL_set_client_CA_list                  85	EXIST::FUNCTION:
+SSL_set_connect_state                   86	EXIST::FUNCTION:
+SSL_set_fd                              87	EXIST::FUNCTION:SOCK
+SSL_set_read_ahead                      88	EXIST::FUNCTION:
+SSL_set_rfd                             89	EXIST::FUNCTION:SOCK
+SSL_set_session                         90	EXIST::FUNCTION:
+SSL_set_ssl_method                      91	EXIST::FUNCTION:
+SSL_set_verify                          94	EXIST::FUNCTION:
+SSL_set_wfd                             95	EXIST::FUNCTION:SOCK
+SSL_shutdown                            96	EXIST::FUNCTION:
+SSL_state_string                        97	EXIST::FUNCTION:
+SSL_state_string_long                   98	EXIST::FUNCTION:
+SSL_use_PrivateKey                      99	EXIST::FUNCTION:
+SSL_use_PrivateKey_ASN1                 100	EXIST::FUNCTION:
+SSL_use_PrivateKey_file                 101	EXIST::FUNCTION:STDIO
+SSL_use_RSAPrivateKey                   102	EXIST::FUNCTION:RSA
+SSL_use_RSAPrivateKey_ASN1              103	EXIST::FUNCTION:RSA
+SSL_use_RSAPrivateKey_file              104	EXIST::FUNCTION:RSA,STDIO
+SSL_use_certificate                     105	EXIST::FUNCTION:
+SSL_use_certificate_ASN1                106	EXIST::FUNCTION:
+SSL_use_certificate_file                107	EXIST::FUNCTION:STDIO
+SSL_write                               108	EXIST::FUNCTION:
+SSLeay_add_ssl_algorithms               109	NOEXIST::FUNCTION:
+SSLv23_client_method                    110	EXIST::FUNCTION:RSA
+SSLv23_method                           111	EXIST::FUNCTION:RSA
+SSLv23_server_method                    112	EXIST::FUNCTION:RSA
+SSLv2_client_method                     113	EXIST::FUNCTION:RSA,SSL2
+SSLv2_method                            114	EXIST::FUNCTION:RSA,SSL2
+SSLv2_server_method                     115	EXIST::FUNCTION:RSA,SSL2
+SSLv3_client_method                     116	EXIST::FUNCTION:
+SSLv3_method                            117	EXIST::FUNCTION:
+SSLv3_server_method                     118	EXIST::FUNCTION:
+d2i_SSL_SESSION                         119	EXIST::FUNCTION:
+i2d_SSL_SESSION                         120	EXIST::FUNCTION:
+BIO_f_ssl                               121	EXIST::FUNCTION:BIO
+BIO_new_ssl                             122	EXIST::FUNCTION:BIO
+BIO_proxy_ssl_copy_session_id           123	NOEXIST::FUNCTION:
+BIO_ssl_copy_session_id                 124	EXIST::FUNCTION:BIO
+SSL_do_handshake                        125	EXIST::FUNCTION:
+SSL_get_privatekey                      126	EXIST::FUNCTION:
+SSL_get_current_cipher                  127	EXIST::FUNCTION:
+SSL_CIPHER_get_bits                     128	EXIST::FUNCTION:
+SSL_CIPHER_get_version                  129	EXIST::FUNCTION:
+SSL_CIPHER_get_name                     130	EXIST::FUNCTION:
+BIO_ssl_shutdown                        131	EXIST::FUNCTION:BIO
+SSL_SESSION_cmp                         132	NOEXIST::FUNCTION:
+SSL_SESSION_hash                        133	NOEXIST::FUNCTION:
+SSL_SESSION_get_time                    134	EXIST::FUNCTION:
+SSL_SESSION_set_time                    135	EXIST::FUNCTION:
+SSL_SESSION_get_timeout                 136	EXIST::FUNCTION:
+SSL_SESSION_set_timeout                 137	EXIST::FUNCTION:
+SSL_CTX_get_ex_data                     138	EXIST::FUNCTION:
+SSL_CTX_get_quiet_shutdown              140	EXIST::FUNCTION:
+SSL_CTX_load_verify_locations           141	EXIST::FUNCTION:
+SSL_CTX_set_default_verify_paths        142	EXIST:!VMS:FUNCTION:
+SSL_CTX_set_def_verify_paths            142	EXIST:VMS:FUNCTION:
+SSL_CTX_set_ex_data                     143	EXIST::FUNCTION:
+SSL_CTX_set_quiet_shutdown              145	EXIST::FUNCTION:
+SSL_SESSION_get_ex_data                 146	EXIST::FUNCTION:
+SSL_SESSION_set_ex_data                 148	EXIST::FUNCTION:
+SSL_get_SSL_CTX                         150	EXIST::FUNCTION:
+SSL_get_ex_data                         151	EXIST::FUNCTION:
+SSL_get_quiet_shutdown                  153	EXIST::FUNCTION:
+SSL_get_session                         154	EXIST::FUNCTION:
+SSL_get_shutdown                        155	EXIST::FUNCTION:
+SSL_get_verify_result                   157	EXIST::FUNCTION:
+SSL_set_ex_data                         158	EXIST::FUNCTION:
+SSL_set_info_callback                   160	EXIST::FUNCTION:
+SSL_set_quiet_shutdown                  161	EXIST::FUNCTION:
+SSL_set_shutdown                        162	EXIST::FUNCTION:
+SSL_set_verify_result                   163	EXIST::FUNCTION:
+SSL_version                             164	EXIST::FUNCTION:
+SSL_get_info_callback                   165	EXIST::FUNCTION:
+SSL_state                               166	EXIST::FUNCTION:
+SSL_CTX_get_ex_new_index                167	EXIST::FUNCTION:
+SSL_SESSION_get_ex_new_index            168	EXIST::FUNCTION:
+SSL_get_ex_new_index                    169	EXIST::FUNCTION:
+TLSv1_method                            170	EXIST::FUNCTION:
+TLSv1_server_method                     171	EXIST::FUNCTION:
+TLSv1_client_method                     172	EXIST::FUNCTION:
+BIO_new_buffer_ssl_connect              173	EXIST::FUNCTION:BIO
+BIO_new_ssl_connect                     174	EXIST::FUNCTION:BIO
+SSL_get_ex_data_X509_STORE_CTX_idx      175	EXIST:!VMS:FUNCTION:
+SSL_get_ex_d_X509_STORE_CTX_idx         175	EXIST:VMS:FUNCTION:
+SSL_CTX_set_tmp_dh_callback             176	EXIST::FUNCTION:DH
+SSL_CTX_set_tmp_rsa_callback            177	EXIST::FUNCTION:RSA
+SSL_CTX_set_timeout                     178	EXIST::FUNCTION:
+SSL_CTX_get_timeout                     179	EXIST::FUNCTION:
+SSL_CTX_get_cert_store                  180	EXIST::FUNCTION:
+SSL_CTX_set_cert_store                  181	EXIST::FUNCTION:
+SSL_want                                182	EXIST::FUNCTION:
+SSL_library_init                        183	EXIST::FUNCTION:
+SSL_COMP_add_compression_method         184	EXIST::FUNCTION:COMP
+SSL_add_file_cert_subjects_to_stack     185	EXIST:!VMS:FUNCTION:STDIO
+SSL_add_file_cert_subjs_to_stk          185	EXIST:VMS:FUNCTION:STDIO
+SSL_set_tmp_rsa_callback                186	EXIST::FUNCTION:RSA
+SSL_set_tmp_dh_callback                 187	EXIST::FUNCTION:DH
+SSL_add_dir_cert_subjects_to_stack      188	EXIST:!VMS:FUNCTION:STDIO
+SSL_add_dir_cert_subjs_to_stk           188	EXIST:VMS:FUNCTION:STDIO
+SSL_set_session_id_context              189	EXIST::FUNCTION:
+SSL_CTX_use_certificate_chain_file      222	EXIST:!VMS:FUNCTION:STDIO
+SSL_CTX_use_cert_chain_file             222	EXIST:VMS:FUNCTION:STDIO
+SSL_CTX_set_verify_depth                225	EXIST::FUNCTION:
+SSL_set_verify_depth                    226	EXIST::FUNCTION:
+SSL_CTX_get_verify_depth                228	EXIST::FUNCTION:
+SSL_get_verify_depth                    229	EXIST::FUNCTION:
+SSL_CTX_set_session_id_context          231	EXIST::FUNCTION:
+SSL_CTX_set_cert_verify_callback        232	EXIST:!VMS:FUNCTION:
+SSL_CTX_set_cert_verify_cb              232	EXIST:VMS:FUNCTION:
+SSL_CTX_set_default_passwd_cb_userdata  235	EXIST:!VMS:FUNCTION:
+SSL_CTX_set_def_passwd_cb_ud            235	EXIST:VMS:FUNCTION:
+SSL_set_purpose                         236	EXIST::FUNCTION:
+SSL_CTX_set_trust                       237	EXIST::FUNCTION:
+SSL_CTX_set_purpose                     238	EXIST::FUNCTION:
+SSL_set_trust                           239	EXIST::FUNCTION:
+SSL_get_finished                        240	EXIST::FUNCTION:
+SSL_get_peer_finished                   241	EXIST::FUNCTION:
+SSL_get1_session                        242	EXIST::FUNCTION:
+SSL_CTX_callback_ctrl                   243	EXIST::FUNCTION:
+SSL_callback_ctrl                       244	EXIST::FUNCTION:
+SSL_CTX_sessions                        245	EXIST::FUNCTION:
+SSL_get_rfd                             246	EXIST::FUNCTION:
+SSL_get_wfd                             247	EXIST::FUNCTION:
+kssl_cget_tkt                           248	EXIST::FUNCTION:KRB5
+SSL_has_matching_session_id             249	EXIST::FUNCTION:
+kssl_err_set                            250	EXIST::FUNCTION:KRB5
+kssl_ctx_show                           251	EXIST::FUNCTION:KRB5
+kssl_validate_times                     252	EXIST::FUNCTION:KRB5
+kssl_check_authent                      253	EXIST::FUNCTION:KRB5
+kssl_ctx_new                            254	EXIST::FUNCTION:KRB5
+kssl_build_principal_2                  255	EXIST::FUNCTION:KRB5
+kssl_skip_confound                      256	EXIST::FUNCTION:KRB5
+kssl_sget_tkt                           257	EXIST::FUNCTION:KRB5
+SSL_set_generate_session_id             258	EXIST::FUNCTION:
+kssl_ctx_setkey                         259	EXIST::FUNCTION:KRB5
+kssl_ctx_setprinc                       260	EXIST::FUNCTION:KRB5
+kssl_ctx_free                           261	EXIST::FUNCTION:KRB5
+kssl_krb5_free_data_contents            262	EXIST::FUNCTION:KRB5
+kssl_ctx_setstring                      263	EXIST::FUNCTION:KRB5
+SSL_CTX_set_generate_session_id         264	EXIST::FUNCTION:
+SSL_renegotiate_pending                 265	EXIST::FUNCTION:
+SSL_CTX_set_msg_callback                266	EXIST::FUNCTION:
+SSL_set_msg_callback                    267	EXIST::FUNCTION:
+DTLSv1_client_method                    268	EXIST::FUNCTION:
+SSL_CTX_set_tmp_ecdh_callback           269	EXIST::FUNCTION:ECDH
+SSL_set_tmp_ecdh_callback               270	EXIST::FUNCTION:ECDH
+SSL_COMP_get_name                       271	EXIST::FUNCTION:COMP
+SSL_get_current_compression             272	EXIST::FUNCTION:COMP
+DTLSv1_method                           273	EXIST::FUNCTION:
+SSL_get_current_expansion               274	EXIST::FUNCTION:COMP
+DTLSv1_server_method                    275	EXIST::FUNCTION:
+SSL_COMP_get_compression_methods        276	EXIST:!VMS:FUNCTION:COMP
+SSL_COMP_get_compress_methods           276	EXIST:VMS:FUNCTION:COMP
+SSL_SESSION_get_id                      277	EXIST::FUNCTION:
+SSL_CTX_sess_set_new_cb                 278	EXIST::FUNCTION:
+SSL_CTX_sess_get_get_cb                 279	EXIST::FUNCTION:
+SSL_CTX_sess_set_get_cb                 280	EXIST::FUNCTION:
+SSL_CTX_set_cookie_verify_cb            281	EXIST::FUNCTION:
+SSL_CTX_get_info_callback               282	EXIST::FUNCTION:
+SSL_CTX_set_cookie_generate_cb          283	EXIST::FUNCTION:
+SSL_CTX_set_client_cert_cb              284	EXIST::FUNCTION:
+SSL_CTX_sess_set_remove_cb              285	EXIST::FUNCTION:
+SSL_CTX_set_info_callback               286	EXIST::FUNCTION:
+SSL_CTX_sess_get_new_cb                 287	EXIST::FUNCTION:
+SSL_CTX_get_client_cert_cb              288	EXIST::FUNCTION:
+SSL_CTX_sess_get_remove_cb              289	EXIST::FUNCTION:
+SSL_set_SSL_CTX                         290	EXIST::FUNCTION:
+SSL_get_servername                      291	EXIST::FUNCTION:TLSEXT
+SSL_get_servername_type                 292	EXIST::FUNCTION:TLSEXT
+SSL_CTX_set_client_cert_engine          293	EXIST::FUNCTION:ENGINE
+SSL_CTX_use_psk_identity_hint           294	EXIST::FUNCTION:PSK
+SSL_CTX_set_psk_client_callback         295	EXIST::FUNCTION:PSK
+PEM_write_bio_SSL_SESSION               296	EXIST::FUNCTION:
+SSL_get_psk_identity_hint               297	EXIST::FUNCTION:PSK
+SSL_set_psk_server_callback             298	EXIST::FUNCTION:PSK
+SSL_use_psk_identity_hint               299	EXIST::FUNCTION:PSK
+SSL_set_psk_client_callback             300	EXIST::FUNCTION:PSK
+PEM_read_SSL_SESSION                    301	EXIST:!WIN16:FUNCTION:
+PEM_read_bio_SSL_SESSION                302	EXIST::FUNCTION:
+SSL_CTX_set_psk_server_callback         303	EXIST::FUNCTION:PSK
+SSL_get_psk_identity                    304	EXIST::FUNCTION:PSK
+PEM_write_SSL_SESSION                   305	EXIST:!WIN16:FUNCTION:
+SSL_set_session_ticket_ext              306	EXIST::FUNCTION:
+SSL_set_session_secret_cb               307	EXIST::FUNCTION:
+SSL_set_session_ticket_ext_cb           308	EXIST::FUNCTION:
+SSL_set1_param                          309	EXIST::FUNCTION:
+SSL_CTX_set1_param                      310	EXIST::FUNCTION:
diff --git a/openssl/util/tab_num.pl b/openssl/util/tab_num.pl
new file mode 100755
index 0000000..a81ed0e
--- /dev/null
+++ b/openssl/util/tab_num.pl
@@ -0,0 +1,17 @@
+#!/usr/local/bin/perl
+
+$num=1;
+$width=40;
+
+while (<>)
+	{
+	chop;
+
+	$i=length($_);
+
+	$n=$width-$i;
+	$i=int(($n+7)/8);
+	print $_.("\t" x $i).$num."\n";
+	$num++;
+	}
+
diff --git a/openssl/util/x86asm.sh b/openssl/util/x86asm.sh
new file mode 100755
index 0000000..d2090a9
--- /dev/null
+++ b/openssl/util/x86asm.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+echo Generating x86 assember
+echo Bignum
+(cd crypto/bn/asm; perl x86.pl cpp > bn86unix.cpp)
+(cd crypto/bn/asm; perl x86.pl win32 > bn-win32.asm)
+
+echo DES
+(cd crypto/des/asm; perl des-586.pl cpp > dx86unix.cpp)
+(cd crypto/des/asm; perl des-586.pl win32 > d-win32.asm)
+
+echo "crypt(3)"
+(cd crypto/des/asm; perl crypt586.pl cpp > yx86unix.cpp)
+(cd crypto/des/asm; perl crypt586.pl win32 > y-win32.asm)
+
+echo Blowfish
+(cd crypto/bf/asm; perl bf-586.pl cpp > bx86unix.cpp)
+(cd crypto/bf/asm; perl bf-586.pl win32 > b-win32.asm)
+
+echo CAST5
+(cd crypto/cast/asm; perl cast-586.pl cpp > cx86unix.cpp)
+(cd crypto/cast/asm; perl cast-586.pl win32 > c-win32.asm)
+
+echo RC4
+(cd crypto/rc4/asm; perl rc4-586.pl cpp > rx86unix.cpp)
+(cd crypto/rc4/asm; perl rc4-586.pl win32 > r4-win32.asm)
+
+echo MD5
+(cd crypto/md5/asm; perl md5-586.pl cpp > mx86unix.cpp)
+(cd crypto/md5/asm; perl md5-586.pl win32 > m5-win32.asm)
+
+echo SHA1
+(cd crypto/sha/asm; perl sha1-586.pl cpp > sx86unix.cpp)
+(cd crypto/sha/asm; perl sha1-586.pl win32 > s1-win32.asm)
+
+echo RIPEMD160
+(cd crypto/ripemd/asm; perl rmd-586.pl cpp > rm86unix.cpp)
+(cd crypto/ripemd/asm; perl rmd-586.pl win32 > rm-win32.asm)
+
+echo RC5/32
+(cd crypto/rc5/asm; perl rc5-586.pl cpp > r586unix.cpp)
+(cd crypto/rc5/asm; perl rc5-586.pl win32 > r5-win32.asm)
diff --git a/patches/clang.patch b/patches/clang.patch
new file mode 100644
index 0000000..550ded3
--- /dev/null
+++ b/patches/clang.patch
@@ -0,0 +1,36 @@
+diff --git a/README.chromium b/README.chromium
+index ae335ca..9962738 100644
+--- a/README.chromium
++++ b/README.chromium
+@@ -96,3 +96,5 @@ Android platform support
+ 
+ Copy config/android/openssl/opensslconf.h from Android's
+ external/openssl/include/openssl/opensslconf.h
++
++Fix warnings when building with clang
+diff --git a/openssl/crypto/bio/bss_dgram.c b/openssl/crypto/bio/bss_dgram.c
+index 71ebe98..a6d882b 100644
+--- a/openssl/crypto/bio/bss_dgram.c
++++ b/openssl/crypto/bio/bss_dgram.c
+@@ -378,7 +378,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
+ 	bio_dgram_data *data = NULL;
+ #if defined(IP_MTU_DISCOVER) || defined(IP_MTU)
+ 	long sockopt_val = 0;
+-	unsigned int sockopt_len = 0;
++	socklen_t sockopt_len = 0;
+ #endif
+ #ifdef OPENSSL_SYS_LINUX
+ 	socklen_t addr_len;
+diff --git a/openssl/crypto/cryptlib.c b/openssl/crypto/cryptlib.c
+index 387a987..5dfeec7 100644
+--- a/openssl/crypto/cryptlib.c
++++ b/openssl/crypto/cryptlib.c
+@@ -500,7 +500,7 @@ void CRYPTO_THREADID_current(CRYPTO_THREADID *id)
+ 	CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL));
+ #else
+ 	/* For everything else, default to using the address of 'errno' */
+-	CRYPTO_THREADID_set_pointer(id, &errno);
++	CRYPTO_THREADID_set_pointer(id, (void*)&errno);
+ #endif
+ 	}
+ 
diff --git a/patches/empty_OPENSSL_cpuid_setup.patch b/patches/empty_OPENSSL_cpuid_setup.patch
new file mode 100644
index 0000000..58e52ad
--- /dev/null
+++ b/patches/empty_OPENSSL_cpuid_setup.patch
@@ -0,0 +1,11 @@
+--- openssl-1.0.0f-origin/crypto/cryptlib.c	2011-06-22 23:39:00.000000000 +0800
++++ openssl-1.0.0f/crypto/cryptlib.c	2012-01-19 02:17:50.261681856 +0800
+@@ -690,7 +690,7 @@
+ unsigned long *OPENSSL_ia32cap_loc(void) { return NULL; }
+ #endif
+ int OPENSSL_NONPIC_relocated = 0;
+-#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
++#if !defined(OPENSSL_CPUID_SETUP)
+ void OPENSSL_cpuid_setup(void) {}
+ #endif
+ 
diff --git a/patches/handshake_cutthrough.patch b/patches/handshake_cutthrough.patch
new file mode 100644
index 0000000..4f29839
--- /dev/null
+++ b/patches/handshake_cutthrough.patch
@@ -0,0 +1,275 @@
+diff -uarp openssl-1.0.0.orig/apps/s_client.c openssl-1.0.0/apps/s_client.c
+--- openssl-1.0.0.orig/apps/s_client.c	2009-12-16 15:28:28.000000000 -0500
++++ openssl-1.0.0/apps/s_client.c	2010-04-21 14:39:49.000000000 -0400
+@@ -248,6 +248,7 @@ static void sc_usage(void)
+ 	BIO_printf(bio_err," -tlsextdebug      - hex dump of all TLS extensions received\n");
+ 	BIO_printf(bio_err," -status           - request certificate status from server\n");
+ 	BIO_printf(bio_err," -no_ticket        - disable use of RFC4507bis session tickets\n");
++	BIO_printf(bio_err," -cutthrough       - enable 1-RTT full-handshake for strong ciphers\n");
+ #endif
+ 	}
+ 
+@@ -304,6 +305,7 @@ int MAIN(int argc, char **argv)
+ 	EVP_PKEY *key = NULL;
+ 	char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
+ 	int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
++	int cutthrough=0;
+ 	int crlf=0;
+ 	int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
+ 	SSL_CTX *ctx=NULL;
+@@ -533,6 +535,8 @@ int MAIN(int argc, char **argv)
+ 		else if	(strcmp(*argv,"-no_ticket") == 0)
+ 			{ off|=SSL_OP_NO_TICKET; }
+ #endif
++		else if (strcmp(*argv,"-cutthrough") == 0)
++			cutthrough=1;
+ 		else if (strcmp(*argv,"-serverpref") == 0)
+ 			off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
+ 		else if	(strcmp(*argv,"-cipher") == 0)
+@@ -714,6 +718,15 @@ bad:
+ 	 */
+ 	if (sock_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
+ 
++	/* Enable handshake cutthrough for client connections using
++	 * strong ciphers. */
++	if (cutthrough)
++		{
++		int ssl_mode = SSL_CTX_get_mode(ctx);
++		ssl_mode |= SSL_MODE_HANDSHAKE_CUTTHROUGH;
++		SSL_CTX_set_mode(ctx, ssl_mode);
++		}
++
+ 	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
+ 	if (cipher != NULL)
+ 		if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
+diff -uarp openssl-1.0.0.orig/ssl/s3_clnt.c openssl-1.0.0/ssl/s3_clnt.c
+--- openssl-1.0.0.orig/ssl/s3_clnt.c	2010-02-27 19:24:24.000000000 -0500
++++ openssl-1.0.0/ssl/s3_clnt.c	2010-04-21 14:39:49.000000000 -0400
+@@ -186,6 +186,18 @@ int ssl3_connect(SSL *s)
+ 	
+ 	s->in_handshake++;
+ 	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); 
++#if 0	/* Send app data in separate packet, otherwise, some particular site
++	 * (only one site so far) closes the socket.
++	 * Note: there is a very small chance that two TCP packets
++	 * could be arriving at server combined into a single TCP packet,
++	 * then trigger that site to break. We haven't encounter that though.
++	 */
++	if (SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH)
++		{
++		/* Send app data along with CCS/Finished */
++		s->s3->flags |= SSL3_FLAGS_DELAY_CLIENT_FINISHED;
++		}
++#endif
+ 
+ 	for (;;)
+ 		{
+@@ -454,14 +468,31 @@ int ssl3_connect(SSL *s)
+ 				}
+ 			else
+ 				{
+-#ifndef OPENSSL_NO_TLSEXT
+-				/* Allow NewSessionTicket if ticket expected */
+-				if (s->tlsext_ticket_expected)
+-					s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
++				if ((SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH) && SSL_get_cipher_bits(s, NULL) >= 128
++				    && s->s3->previous_server_finished_len == 0 /* no cutthrough on renegotiation (would complicate the state machine) */
++				   )
++					{
++					if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED)
++						{
++						s->state=SSL3_ST_CUTTHROUGH_COMPLETE;
++						s->s3->flags|=SSL3_FLAGS_POP_BUFFER;
++						s->s3->delay_buf_pop_ret=0;
++						}
++					else
++						{
++						s->s3->tmp.next_state=SSL3_ST_CUTTHROUGH_COMPLETE;
++						}
++					}
+ 				else
++					{
++#ifndef OPENSSL_NO_TLSEXT
++					/* Allow NewSessionTicket if ticket expected */
++					if (s->tlsext_ticket_expected)
++						s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
++					else
+ #endif
+-				
+-				s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
++						s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
++					}
+ 				}
+ 			s->init_num=0;
+ 			break;
+@@ -512,6 +541,24 @@ int ssl3_connect(SSL *s)
+ 			s->state=s->s3->tmp.next_state;
+ 			break;
+ 
++		case SSL3_ST_CUTTHROUGH_COMPLETE:
++#ifndef OPENSSL_NO_TLSEXT
++			/* Allow NewSessionTicket if ticket expected */
++			if (s->tlsext_ticket_expected)
++				s->state=SSL3_ST_CR_SESSION_TICKET_A;
++			else
++#endif
++				s->state=SSL3_ST_CR_FINISHED_A;
++
++			/* SSL_write() will take care of flushing buffered data if
++			 * DELAY_CLIENT_FINISHED is set.
++			 */
++			if (!(s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED))
++				ssl_free_wbio_buffer(s);
++			ret = 1;
++			goto end;
++			/* break; */
++
+ 		case SSL_ST_OK:
+ 			/* clean a few things up */
+ 			ssl3_cleanup_key_block(s);
+diff -uarp openssl-1.0.0.orig/ssl/s3_lib.c openssl-1.0.0/ssl/s3_lib.c
+-- openssl-1.0.0.orig/ssl/s3_lib.c     2009-10-16 11:24:19.000000000 -0400
++++ openssl-1.0.0/ssl/s3_lib.c  2010-04-21 14:39:49.000000000 -0400
+@@ -2551,9 +2551,22 @@ int ssl3_write(SSL *s, const void *buf, 
+ 
+ static int ssl3_read_internal(SSL *s, void *buf, int len, int peek)
+ 	{
+-	int ret;
++	int n,ret;
+ 	
+ 	clear_sys_error();
++	if ((s->s3->flags & SSL3_FLAGS_POP_BUFFER) && (s->wbio == s->bbio))
++		{
++		/* Deal with an application that calls SSL_read() when handshake data
++		 * is yet to be written.
++		 */
++		if (BIO_wpending(s->wbio) > 0)
++			{
++			s->rwstate=SSL_WRITING;
++			n=BIO_flush(s->wbio);
++			if (n <= 0) return(n);
++			s->rwstate=SSL_NOTHING;
++			}
++		}
+ 	if (s->s3->renegotiate) ssl3_renegotiate_check(s);
+ 	s->s3->in_read_app_data=1;
+ 	ret=s->method->ssl_read_bytes(s,SSL3_RT_APPLICATION_DATA,buf,len,peek);
+diff -uarp openssl-1.0.0.orig/ssl/ssl.h openssl-1.0.0/ssl/ssl.h
+--- openssl-1.0.0.orig/ssl/ssl.h	2010-01-06 12:37:38.000000000 -0500
++++ openssl-1.0.0/ssl/ssl.h	2010-04-21 16:57:49.000000000 -0400
+@@ -605,6 +605,10 @@ typedef struct ssl_session_st
+ /* Use small read and write buffers: (a) lazy allocate read buffers for
+  * large incoming records, and (b) limit the size of outgoing records. */
+ #define SSL_MODE_SMALL_BUFFERS 0x00000020L
++/* When set, clients may send application data before receipt of CCS
++ * and Finished.  This mode enables full-handshakes to 'complete' in
++ * one RTT. */
++#define SSL_MODE_HANDSHAKE_CUTTHROUGH 0x00000040L
+
+ /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
+  * they cannot be used to clear bits. */
+@@ -1097,10 +1101,12 @@ extern "C" {
+ /* Is the SSL_connection established? */
+ #define SSL_get_state(a)		SSL_state(a)
+ #define SSL_is_init_finished(a)		(SSL_state(a) == SSL_ST_OK)
+-#define SSL_in_init(a)			(SSL_state(a)&SSL_ST_INIT)
++#define SSL_in_init(a)			((SSL_state(a)&SSL_ST_INIT) && \
++                                  !SSL_cutthrough_complete(a))
+ #define SSL_in_before(a)		(SSL_state(a)&SSL_ST_BEFORE)
+ #define SSL_in_connect_init(a)		(SSL_state(a)&SSL_ST_CONNECT)
+ #define SSL_in_accept_init(a)		(SSL_state(a)&SSL_ST_ACCEPT)
++int SSL_cutthrough_complete(const SSL *s);
+ 
+ /* The following 2 states are kept in ssl->rstate when reads fail,
+  * you should not need these */
+Only in openssl-1.0.0/ssl: ssl.h.orig
+diff -uarp openssl-1.0.0.orig/ssl/ssl3.h openssl-1.0.0/ssl/ssl3.h
+-- openssl-1.0.0.orig/ssl/ssl3.h	2010-01-06 12:37:38.000000000 -0500
++++ openssl-1.0.0/ssl/ssl3.h	2010-04-21 14:39:49.000000000 -0400
+@@ -456,6 +456,7 @@ typedef struct ssl3_state_st
+ /*client */
+ /* extra state */
+ #define SSL3_ST_CW_FLUSH		(0x100|SSL_ST_CONNECT)
++#define SSL3_ST_CUTTHROUGH_COMPLETE	(0x101|SSL_ST_CONNECT)
+ /* write to server */
+ #define SSL3_ST_CW_CLNT_HELLO_A		(0x110|SSL_ST_CONNECT)
+ #define SSL3_ST_CW_CLNT_HELLO_B		(0x111|SSL_ST_CONNECT)
+diff -uarp openssl-1.0.0.orig/ssl/ssl_lib.c openssl-1.0.0/ssl/ssl_lib.c
+--- openssl-1.0.0.orig/ssl/ssl_lib.c	2010-02-17 14:43:46.000000000 -0500
++++ openssl-1.0.0/ssl/ssl_lib.c	2010-04-21 17:02:45.000000000 -0400
+@@ -3031,6 +3031,19 @@ void SSL_set_msg_callback(SSL *ssl, void
+ 	SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
+ 	}
+
++int SSL_cutthrough_complete(const SSL *s)
++	{
++	return (!s->server &&                 /* cutthrough only applies to clients */
++		!s->hit &&                        /* full-handshake */
++		s->version >= SSL3_VERSION &&
++		s->s3->in_read_app_data == 0 &&   /* cutthrough only applies to write() */
++		(SSL_get_mode((SSL*)s) & SSL_MODE_HANDSHAKE_CUTTHROUGH) &&  /* cutthrough enabled */
++		SSL_get_cipher_bits(s, NULL) >= 128 &&                      /* strong cipher choosen */
++		s->s3->previous_server_finished_len == 0 &&                 /* not a renegotiation handshake */
++		(s->state == SSL3_ST_CR_SESSION_TICKET_A ||                 /* ready to write app-data*/
++			s->state == SSL3_ST_CR_FINISHED_A));
++	}
++
+ /* Allocates new EVP_MD_CTX and sets pointer to it into given pointer
+  * vairable, freeing  EVP_MD_CTX previously stored in that variable, if
+  * any. If EVP_MD pointer is passed, initializes ctx with this md
+diff -uarp openssl-1.0.0.orig/ssl/ssltest.c openssl-1.0.0/ssl/ssltest.c
+--- openssl-1.0.0.orig/ssl/ssltest.c	2010-01-24 11:57:38.000000000 -0500
++++ openssl-1.0.0/ssl/ssltest.c	2010-04-21 17:06:35.000000000 -0400
+@@ -279,6 +279,7 @@ static void sv_usage(void)
+ 	fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
+ 	fprintf(stderr," -c_small_records - enable client side use of small SSL record buffers\n");
+ 	fprintf(stderr," -s_small_records - enable server side use of small SSL record buffers\n");
++	fprintf(stderr," -cutthrough      - enable 1-RTT full-handshake for strong ciphers\n");
+ 	}
+ 
+ static void print_details(SSL *c_ssl, const char *prefix)
+@@ -436,6 +437,7 @@ int main(int argc, char *argv[])
+ 	int ssl_mode = 0;
+ 	int c_small_records=0;
+ 	int s_small_records=0;
++	int cutthrough = 0;
+ 
+ 	verbose = 0;
+ 	debug = 0;
+@@ -632,6 +634,10 @@ int main(int argc, char *argv[])
+ 			{
+ 			s_small_records = 1;
+ 			}
++		else if (strcmp(*argv, "-cutthrough") == 0)
++			{
++			cutthrough = 1;
++			}
+ 		else
+ 			{
+ 			fprintf(stderr,"unknown option %s\n",*argv);
+@@ -782,6 +788,13 @@ bad:
+ 		ssl_mode |= SSL_MODE_SMALL_BUFFERS;
+ 		SSL_CTX_set_mode(s_ctx, ssl_mode);
+ 		}
++	ssl_mode = 0;
++	if (cutthrough)
++		{
++		ssl_mode = SSL_CTX_get_mode(c_ctx);
++		ssl_mode = SSL_MODE_HANDSHAKE_CUTTHROUGH;
++		SSL_CTX_set_mode(c_ctx, ssl_mode);
++		}
+ 
+ #ifndef OPENSSL_NO_DH
+ 	if (!no_dhe)
+diff -uarp openssl-1.0.0.orig/test/testssl openssl-1.0.0/test/testssl
+--- openssl-1.0.0.orig/test/testssl	2006-03-10 18:06:27.000000000 -0500
++++ openssl-1.0.0/test/testssl	2010-04-21 16:50:13.000000000 -0400
+@@ -79,6 +79,8 @@ $ssltest -server_auth -client_auth -s_sm
+ echo test sslv2/sslv3 with both client and server authentication and small client and server buffers
+ $ssltest -server_auth -client_auth -c_small_records -s_small_records $CA $extra || exit 1
+ 
++echo test sslv2/sslv3 with both client and server authentication and handshake cutthrough
++$ssltest -server_auth -client_auth -cutthrough $CA $extra || exit 1
+ 
+ echo test sslv2 via BIO pair
+ $ssltest -bio_pair -ssl2 $extra || exit 1
diff --git a/patches/jsse.patch b/patches/jsse.patch
new file mode 100644
index 0000000..249fb5b
--- /dev/null
+++ b/patches/jsse.patch
@@ -0,0 +1,426 @@
+--- openssl-1.0.0b.orig/ssl/ssl.h	2010-11-30 00:03:46.000000000 +0000
++++ openssl-1.0.0b/ssl/ssl.h	2010-11-30 00:03:47.000000000 +0000
+@@ -1133,6 +1133,9 @@ struct ssl_st
+ 	/* This can also be in the session once a session is established */
+ 	SSL_SESSION *session;
+ 
++        /* This can be disabled to prevent the use of uncached sessions */
++	int session_creation_enabled;
++
+ 	/* Default generate session ID callback. */
+ 	GEN_SESSION_CB generate_session_id;
+ 
+@@ -1546,6 +1549,7 @@ const SSL_CIPHER *SSL_get_current_cipher
+ int	SSL_CIPHER_get_bits(const SSL_CIPHER *c,int *alg_bits);
+ char *	SSL_CIPHER_get_version(const SSL_CIPHER *c);
+ const char *	SSL_CIPHER_get_name(const SSL_CIPHER *c);
++const char *	SSL_CIPHER_authentication_method(const SSL_CIPHER *c);
+ 
+ int	SSL_get_fd(const SSL *s);
+ int	SSL_get_rfd(const SSL *s);
+@@ -1554,6 +1558,7 @@ const char  * SSL_get_cipher_list(const 
+ char *	SSL_get_shared_ciphers(const SSL *s, char *buf, int len);
+ int	SSL_get_read_ahead(const SSL * s);
+ int	SSL_pending(const SSL *s);
++const char *	SSL_authentication_method(const SSL *c);
+ #ifndef OPENSSL_NO_SOCK
+ int	SSL_set_fd(SSL *s, int fd);
+ int	SSL_set_rfd(SSL *s, int fd);
+@@ -1565,6 +1570,7 @@ BIO *	SSL_get_rbio(const SSL *s);
+ BIO *	SSL_get_wbio(const SSL *s);
+ #endif
+ int	SSL_set_cipher_list(SSL *s, const char *str);
++int	SSL_set_cipher_lists(SSL *s, STACK_OF(SSL_CIPHER) *sk);
+ void	SSL_set_read_ahead(SSL *s, int yes);
+ int	SSL_get_verify_mode(const SSL *s);
+ int	SSL_get_verify_depth(const SSL *s);
+@@ -1580,6 +1586,8 @@ int	SSL_use_PrivateKey(SSL *ssl, EVP_PKE
+ int	SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len);
+ int	SSL_use_certificate(SSL *ssl, X509 *x);
+ int	SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
++int	SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain);
++STACK_OF(X509) * SSL_get_certificate_chain(SSL *ssl, X509 *x);
+ 
+ #ifndef OPENSSL_NO_STDIO
+ int	SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
+@@ -1615,6 +1623,7 @@ void	SSL_copy_session_id(SSL *to,const S
+ SSL_SESSION *SSL_SESSION_new(void);
+ const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
+ 					unsigned int *len);
++const char *	SSL_SESSION_get_version(const SSL_SESSION *s);
+ #ifndef OPENSSL_NO_FP_API
+ int	SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
+ #endif
+@@ -1624,6 +1633,7 @@ int	SSL_SESSION_print(BIO *fp,const SSL_
+ void	SSL_SESSION_free(SSL_SESSION *ses);
+ int	i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
+ int	SSL_set_session(SSL *to, SSL_SESSION *session);
++void	SSL_set_session_creation_enabled(SSL *, int);
+ int	SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
+ int	SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c);
+ int	SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
+@@ -2066,6 +2076,7 @@ void ERR_load_SSL_strings(void);
+ #define SSL_F_SSL_UNDEFINED_VOID_FUNCTION		 244
+ #define SSL_F_SSL_USE_CERTIFICATE			 198
+ #define SSL_F_SSL_USE_CERTIFICATE_ASN1			 199
++#define SSL_F_SSL_USE_CERTIFICATE_CHAIN			 2000
+ #define SSL_F_SSL_USE_CERTIFICATE_FILE			 200
+ #define SSL_F_SSL_USE_PRIVATEKEY			 201
+ #define SSL_F_SSL_USE_PRIVATEKEY_ASN1			 202
+@@ -2272,6 +2283,7 @@ void ERR_load_SSL_strings(void);
+ #define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING		 345
+ #define SSL_R_SERVERHELLO_TLSEXT			 275
+ #define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED		 277
++#define SSL_R_SESSION_MAY_NOT_BE_CREATED		 2000
+ #define SSL_R_SHORT_READ				 219
+ #define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE	 220
+ #define SSL_R_SSL23_DOING_SESSION_ID_REUSE		 221
+--- openssl-1.0.0b.orig/ssl/d1_clnt.c	2010-01-26 19:46:29.000000000 +0000
++++ openssl-1.0.0b/ssl/d1_clnt.c	2010-11-30 00:03:47.000000000 +0000
+@@ -613,6 +613,12 @@ int dtls1_client_hello(SSL *s)
+ #endif
+ 			(s->session->not_resumable))
+ 			{
++		        if (!s->session_creation_enabled)
++				{
++				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
++				SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
++				goto err;
++				}
+ 			if (!ssl_get_new_session(s,0))
+ 				goto err;
+ 			}
+--- openssl-1.0.0b.orig/ssl/s23_clnt.c	2010-02-16 14:20:40.000000000 +0000
++++ openssl-1.0.0b/ssl/s23_clnt.c	2010-11-30 00:03:47.000000000 +0000
+@@ -687,6 +687,13 @@ static int ssl23_get_server_hello(SSL *s
+ 
+ 	/* Since, if we are sending a ssl23 client hello, we are not
+ 	 * reusing a session-id */
++        if (!s->session_creation_enabled)
++		{
++		if (!(s->client_version == SSL2_VERSION))
++			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
++		SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
++		goto err;
++		}
+ 	if (!ssl_get_new_session(s,0))
+ 		goto err;
+ 
+--- openssl-1.0.0b.orig/ssl/s3_both.c	2010-11-30 00:03:46.000000000 +0000
++++ openssl-1.0.0b/ssl/s3_both.c	2010-11-30 00:03:47.000000000 +0000
+@@ -347,8 +347,11 @@ unsigned long ssl3_output_cert_chain(SSL
+ 	unsigned long l=7;
+ 	BUF_MEM *buf;
+ 	int no_chain;
++	STACK_OF(X509) *cert_chain;
+ 
+-	if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
++	cert_chain = SSL_get_certificate_chain(s, x);
++
++	if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs || cert_chain)
+ 		no_chain = 1;
+ 	else
+ 		no_chain = 0;
+@@ -400,6 +403,10 @@ unsigned long ssl3_output_cert_chain(SSL
+ 			return(0);
+ 		}
+ 
++	for (i=0; i<sk_X509_num(cert_chain); i++)
++		if (ssl3_add_cert_to_buf(buf, &l, sk_X509_value(cert_chain,i)))
++			return(0);
++
+ 	l-=7;
+ 	p=(unsigned char *)&(buf->data[4]);
+ 	l2n3(l,p);
+--- openssl-1.0.0b.orig/ssl/s3_clnt.c	2010-11-30 00:03:46.000000000 +0000
++++ openssl-1.0.0b/ssl/s3_clnt.c	2010-11-30 00:03:47.000000000 +0000
+@@ -686,6 +686,12 @@ int ssl3_client_hello(SSL *s)
+ #endif
+ 			(sess->not_resumable))
+ 			{
++		        if (!s->session_creation_enabled)
++				{
++				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
++				SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
++				goto err;
++				}
+ 			if (!ssl_get_new_session(s,0))
+ 				goto err;
+ 			}
+@@ -894,6 +900,12 @@ int ssl3_get_server_hello(SSL *s)
+ 		s->hit=0;
+ 		if (s->session->session_id_length > 0)
+ 			{
++		        if (!s->session_creation_enabled)
++				{
++				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
++				SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
++				goto err;
++				}
+ 			if (!ssl_get_new_session(s,0))
+ 				{
+ 				al=SSL_AD_INTERNAL_ERROR;
+--- openssl-1.0.0b.orig/ssl/s3_srvr.c	2010-11-30 00:03:46.000000000 +0000
++++ openssl-1.0.0b/ssl/s3_srvr.c	2010-11-30 00:03:47.000000000 +0000
+@@ -902,6 +902,12 @@ int ssl3_get_client_hello(SSL *s)
+ 	 */
+ 	if ((s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)))
+ 		{
++	        if (!s->session_creation_enabled)
++			{
++			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
++			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
++			goto err;
++		}
+ 		if (!ssl_get_new_session(s,1))
+ 			goto err;
+ 		}
+@@ -916,6 +922,12 @@ int ssl3_get_client_hello(SSL *s)
+ 			goto err;
+ 		else /* i == 0 */
+ 			{
++		        if (!s->session_creation_enabled)
++				{
++				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
++				SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
++				goto err;
++				}
+ 			if (!ssl_get_new_session(s,1))
+ 				goto err;
+ 			}
+--- openssl-1.0.0b.orig/ssl/ssl_ciph.c	2010-06-15 17:25:14.000000000 +0000
++++ openssl-1.0.0b/ssl/ssl_ciph.c	2010-11-30 00:03:47.000000000 +0000
+@@ -1652,6 +1652,52 @@ int SSL_CIPHER_get_bits(const SSL_CIPHER
+ 	return(ret);
+ 	}
+ 
++/* return string version of key exchange algorithm */
++const char* SSL_CIPHER_authentication_method(const SSL_CIPHER* cipher)
++	{
++	switch (cipher->algorithm_mkey)
++		{
++	case SSL_kRSA:
++		return SSL_TXT_RSA;
++	case SSL_kDHr:
++		return SSL_TXT_DH "_" SSL_TXT_RSA;
++	case SSL_kDHd:
++		return SSL_TXT_DH "_" SSL_TXT_DSS;
++	case SSL_kEDH:
++		switch (cipher->algorithm_auth)
++			{
++		case SSL_aDSS:
++			return "DHE_" SSL_TXT_DSS;
++		case SSL_aRSA:
++			return "DHE_" SSL_TXT_RSA;
++		case SSL_aNULL:
++			return SSL_TXT_DH "_anon";
++		default:
++			return "UNKNOWN";
++                        }
++	case SSL_kKRB5:
++		return SSL_TXT_KRB5;
++	case SSL_kECDHr:
++		return SSL_TXT_ECDH "_" SSL_TXT_RSA;
++	case SSL_kECDHe:
++		return SSL_TXT_ECDH "_" SSL_TXT_ECDSA;
++	case SSL_kEECDH:
++		switch (cipher->algorithm_auth)
++			{
++		case SSL_aECDSA:
++			return "ECDHE_" SSL_TXT_ECDSA;
++		case SSL_aRSA:
++			return "ECDHE_" SSL_TXT_RSA;
++		case SSL_aNULL:
++			return SSL_TXT_ECDH "_anon";
++		default:
++			return "UNKNOWN";
++                        }
++        default:
++		return "UNKNOWN";
++		}
++	}
++
+ SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n)
+ 	{
+ 	SSL_COMP *ctmp;
+--- openssl-1.0.0b.orig/ssl/ssl_err.c	2010-11-30 00:03:46.000000000 +0000
++++ openssl-1.0.0b/ssl/ssl_err.c	2010-11-30 00:03:47.000000000 +0000
+@@ -465,6 +465,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
+ {ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING),"scsv received when renegotiating"},
+ {ERR_REASON(SSL_R_SERVERHELLO_TLSEXT)    ,"serverhello tlsext"},
+ {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"},
++{ERR_REASON(SSL_R_SESSION_MAY_NOT_BE_CREATED),"session may not be created"},
+ {ERR_REASON(SSL_R_SHORT_READ)            ,"short read"},
+ {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"},
+ {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"},
+--- openssl-1.0.0b.orig/ssl/ssl_lib.c	2010-11-30 00:03:46.000000000 +0000
++++ openssl-1.0.0b/ssl/ssl_lib.c	2010-11-30 00:03:47.000000000 +0000
+@@ -326,6 +326,7 @@ SSL *SSL_new(SSL_CTX *ctx)
+ 	OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx);
+ 	memcpy(&s->sid_ctx,&ctx->sid_ctx,sizeof(s->sid_ctx));
+ 	s->verify_callback=ctx->default_verify_callback;
++	s->session_creation_enabled=1;
+ 	s->generate_session_id=ctx->generate_session_id;
+ 
+ 	s->param = X509_VERIFY_PARAM_new();
+@@ -1311,6 +1312,32 @@ int SSL_set_cipher_list(SSL *s,const cha
+ 	return 1;
+ 	}
+ 
++/** specify the ciphers to be used by the SSL */
++int SSL_set_cipher_lists(SSL *s,STACK_OF(SSL_CIPHER) *sk)
++	{
++	STACK_OF(SSL_CIPHER) *tmp_cipher_list;
++
++	if (sk == NULL)
++		return 0;
++
++        /* Based on end of ssl_create_cipher_list */
++	tmp_cipher_list = sk_SSL_CIPHER_dup(sk);
++	if (tmp_cipher_list == NULL)
++		{
++		return 0;
++		}
++	if (s->cipher_list != NULL)
++		sk_SSL_CIPHER_free(s->cipher_list);
++	s->cipher_list = sk;
++	if (s->cipher_list_by_id != NULL)
++		sk_SSL_CIPHER_free(s->cipher_list_by_id);
++	s->cipher_list_by_id = tmp_cipher_list;
++	(void)sk_SSL_CIPHER_set_cmp_func(s->cipher_list_by_id,ssl_cipher_ptr_id_cmp);
++
++	sk_SSL_CIPHER_sort(s->cipher_list_by_id);
++	return 1;
++	}
++
+ /* works well for SSLv2, not so good for SSLv3 */
+ char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len)
+ 	{
+@@ -2551,18 +2578,45 @@ SSL_METHOD *ssl_bad_method(int ver)
+ 	return(NULL);
+ 	}
+ 
+-const char *SSL_get_version(const SSL *s)
++static const char *ssl_get_version(int version)
+ 	{
+-	if (s->version == TLS1_VERSION)
++	if (version == TLS1_VERSION)
+ 		return("TLSv1");
+-	else if (s->version == SSL3_VERSION)
++	else if (version == SSL3_VERSION)
+ 		return("SSLv3");
+-	else if (s->version == SSL2_VERSION)
++	else if (version == SSL2_VERSION)
+ 		return("SSLv2");
+ 	else
+ 		return("unknown");
+ 	}
+ 
++const char *SSL_get_version(const SSL *s)
++	{
++		return ssl_get_version(s->version);
++	}
++
++const char *SSL_SESSION_get_version(const SSL_SESSION *s)
++	{
++		return ssl_get_version(s->ssl_version);
++	}
++
++const char* SSL_authentication_method(const SSL* ssl)
++	{
++	if (ssl->cert != NULL && ssl->cert->rsa_tmp != NULL)
++		return SSL_TXT_RSA "_" SSL_TXT_EXPORT;
++	switch (ssl->version)
++		{
++	case SSL2_VERSION:
++		return SSL_TXT_RSA;
++	case SSL3_VERSION:
++	case TLS1_VERSION:
++	case DTLS1_VERSION:
++		return SSL_CIPHER_authentication_method(ssl->s3->tmp.new_cipher);
++	default:
++		return "UNKNOWN";
++		}
++	}
++
+ SSL *SSL_dup(SSL *s)
+ 	{
+ 	STACK_OF(X509_NAME) *sk;
+--- openssl-1.0.0b.orig/ssl/ssl_locl.h	2010-11-30 00:03:46.000000000 +0000
++++ openssl-1.0.0b/ssl/ssl_locl.h	2010-11-30 00:03:47.000000000 +0000
+@@ -456,6 +456,7 @@
+ typedef struct cert_pkey_st
+ 	{
+ 	X509 *x509;
++	STACK_OF(X509) *cert_chain;
+ 	EVP_PKEY *privatekey;
+ 	} CERT_PKEY;
+ 
+--- openssl-1.0.0b.orig/ssl/ssl_rsa.c	2009-09-12 23:09:26.000000000 +0000
++++ openssl-1.0.0b/ssl/ssl_rsa.c	2010-11-30 00:03:47.000000000 +0000
+@@ -697,6 +697,42 @@ int SSL_CTX_use_PrivateKey_ASN1(int type
+ 	}
+ 
+ 
++int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain)
++	{
++	if (ssl == NULL)
++		{
++		SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,ERR_R_PASSED_NULL_PARAMETER);
++		return(0);
++		}
++	if (ssl->cert == NULL)
++		{
++		SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED);
++		return(0);
++		}
++	if (ssl->cert->key == NULL)
++		{
++		SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED);
++		return(0);
++		}
++	ssl->cert->key->cert_chain = cert_chain;
++	return(1);
++	}
++
++STACK_OF(X509) *SSL_get_certificate_chain(SSL *ssl, X509 *x)
++	{
++	int i;
++	if (x == NULL)
++		return NULL;
++	if (ssl == NULL)
++		return NULL;
++	if (ssl->cert == NULL)
++		return NULL;
++	for (i = 0; i < SSL_PKEY_NUM; i++)
++		if (ssl->cert->pkeys[i].x509 == x)
++			return ssl->cert->pkeys[i].cert_chain;
++	return NULL;
++	}
++
+ #ifndef OPENSSL_NO_STDIO
+ /* Read a file that contains our certificate in "PEM" format,
+  * possibly followed by a sequence of CA certificates that should be
+--- openssl-1.0.0b.orig/ssl/ssl_sess.c	2010-02-01 16:49:42.000000000 +0000
++++ openssl-1.0.0b/ssl/ssl_sess.c	2010-11-30 00:03:47.000000000 +0000
+@@ -261,6 +261,11 @@ static int def_generate_session_id(const
+ 	return 0;
+ }
+ 
++void SSL_set_session_creation_enabled (SSL *s, int creation_enabled)
++	{
++	s->session_creation_enabled = creation_enabled;
++	}
++
+ int ssl_get_new_session(SSL *s, int session)
+ 	{
+ 	/* This gets used by clients and servers. */
+@@ -269,6 +274,8 @@ int ssl_get_new_session(SSL *s, int sess
+ 	SSL_SESSION *ss=NULL;
+ 	GEN_SESSION_CB cb = def_generate_session_id;
+ 
++	/* caller should check this if they can do better error handling */
++        if (!s->session_creation_enabled) return(0);
+ 	if ((ss=SSL_SESSION_new()) == NULL) return(0);
+ 
+ 	/* If the context has a default timeout, use it */
diff --git a/patches/npn.patch b/patches/npn.patch
new file mode 100644
index 0000000..46b7a7d
--- /dev/null
+++ b/patches/npn.patch
@@ -0,0 +1,1293 @@
+--- openssl-1.0.0b.orig/apps/apps.c	2010-11-11 14:42:19.000000000 +0000
++++ openssl-1.0.0b/apps/apps.c	2010-11-29 19:56:04.902465346 +0000
+@@ -3012,3 +3012,46 @@ int raw_write_stdout(const void *buf,int
+ int raw_write_stdout(const void *buf,int siz)
+ 	{	return write(fileno(stdout),buf,siz);	}
+ #endif
++
++#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
++/* next_protos_parse parses a comma separated list of strings into a string
++ * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
++ *   outlen: (output) set to the length of the resulting buffer on success.
++ *   in: a NUL termianted string like "abc,def,ghi"
++ *
++ *   returns: a malloced buffer or NULL on failure.
++ */
++unsigned char *next_protos_parse(unsigned short *outlen, const char *in)
++	{
++	size_t len;
++	unsigned char *out;
++	size_t i, start = 0;
++
++	len = strlen(in);
++	if (len >= 65535)
++		return NULL;
++
++	out = OPENSSL_malloc(strlen(in) + 1);
++	if (!out)
++		return NULL;
++
++	for (i = 0; i <= len; ++i)
++		{
++		if (i == len || in[i] == ',')
++			{
++			if (i - start > 255)
++				{
++				OPENSSL_free(out);
++				return NULL;
++				}
++			out[start] = i - start;
++			start = i + 1;
++			}
++		else
++			out[i+1] = in[i];
++		}
++
++	*outlen = len + 1;
++	return out;
++	}
++#endif  /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
+--- openssl-1.0.0b.orig/apps/apps.h	2009-10-31 13:34:19.000000000 +0000
++++ openssl-1.0.0b/apps/apps.h	2010-11-29 19:56:04.902465346 +0000
+@@ -358,3 +358,7 @@ int raw_write_stdout(const void *,int);
+ #define TM_STOP		1
+ double app_tminterval (int stop,int usertime);
+ #endif
++
++#ifndef OPENSSL_NO_NEXTPROTONEG
++unsigned char *next_protos_parse(unsigned short *outlen, const char *in);
++#endif
+--- openssl-1.0.0b.orig/apps/s_client.c	2010-11-29 19:56:04.832465351 +0000
++++ openssl-1.0.0b/apps/s_client.c	2010-11-29 19:56:04.902465346 +0000
+@@ -342,6 +342,9 @@ static void sc_usage(void)
+ 	BIO_printf(bio_err," -tlsextdebug      - hex dump of all TLS extensions received\n");
+ 	BIO_printf(bio_err," -status           - request certificate status from server\n");
+ 	BIO_printf(bio_err," -no_ticket        - disable use of RFC4507bis session tickets\n");
++# ifndef OPENSSL_NO_NEXTPROTONEG
++	BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
++# endif
+ 	BIO_printf(bio_err," -cutthrough       - enable 1-RTT full-handshake for strong ciphers\n");
+ #endif
+ 	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
+@@ -367,6 +370,40 @@ static int MS_CALLBACK ssl_servername_cb
+ 	
+ 	return SSL_TLSEXT_ERR_OK;
+ 	}
++
++# ifndef OPENSSL_NO_NEXTPROTONEG
++/* This the context that we pass to next_proto_cb */
++typedef struct tlsextnextprotoctx_st {
++	unsigned char *data;
++	unsigned short len;
++	int status;
++} tlsextnextprotoctx;
++
++static tlsextnextprotoctx next_proto;
++
++static int next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
++	{
++	tlsextnextprotoctx *ctx = arg;
++
++	if (!c_quiet)
++		{
++		/* We can assume that |in| is syntactically valid. */
++		unsigned i;
++		BIO_printf(bio_c_out, "Protocols advertised by server: ");
++		for (i = 0; i < inlen; )
++			{
++			if (i)
++				BIO_write(bio_c_out, ", ", 2);
++			BIO_write(bio_c_out, &in[i + 1], in[i]);
++			i += in[i] + 1;
++			}
++		BIO_write(bio_c_out, "\n", 1);
++		}
++
++	ctx->status = SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len);
++	return SSL_TLSEXT_ERR_OK;
++	}
++# endif  /* ndef OPENSSL_NO_NEXTPROTONEG */
+ #endif
+ 
+ enum
+@@ -431,6 +468,9 @@ int MAIN(int argc, char **argv)
+ 	char *servername = NULL; 
+         tlsextctx tlsextcbp = 
+         {NULL,0};
++# ifndef OPENSSL_NO_NEXTPROTONEG
++	const char *next_proto_neg_in = NULL;
++# endif
+ #endif
+ 	char *sess_in = NULL;
+ 	char *sess_out = NULL;
+@@ -658,6 +698,13 @@ int MAIN(int argc, char **argv)
+ #ifndef OPENSSL_NO_TLSEXT
+ 		else if	(strcmp(*argv,"-no_ticket") == 0)
+ 			{ off|=SSL_OP_NO_TICKET; }
++# ifndef OPENSSL_NO_NEXTPROTONEG
++		else if (strcmp(*argv,"-nextprotoneg") == 0)
++			{
++			if (--argc < 1) goto bad;
++			next_proto_neg_in = *(++argv);
++			}
++# endif
+ #endif
+ 		else if (strcmp(*argv,"-cutthrough") == 0)
+ 			cutthrough=1;
+@@ -766,6 +813,21 @@ bad:
+ 	OpenSSL_add_ssl_algorithms();
+ 	SSL_load_error_strings();
+ 
++#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
++	next_proto.status = -1;
++	if (next_proto_neg_in)
++		{
++		next_proto.data = next_protos_parse(&next_proto.len, next_proto_neg_in);
++		if (next_proto.data == NULL)
++			{
++			BIO_printf(bio_err, "Error parsing -nextprotoneg argument\n");
++			goto end;
++			}
++		}
++	else
++		next_proto.data = NULL;
++#endif
++
+ #ifndef OPENSSL_NO_ENGINE
+         e = setup_engine(bio_err, engine_id, 1);
+ 	if (ssl_client_engine_id)
+@@ -896,6 +958,11 @@ bad:
+ 		SSL_CTX_set_mode(ctx, ssl_mode);
+ 		}
+ 
++#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
++	if (next_proto.data)
++		SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
++#endif
++
+ 	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
+ 	if (cipher != NULL)
+ 		if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
+@@ -1755,6 +1822,18 @@ static void print_stuff(BIO *bio, SSL *s
+ 	BIO_printf(bio,"Expansion: %s\n",
+ 		expansion ? SSL_COMP_get_name(expansion) : "NONE");
+ #endif
++
++#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
++	if (next_proto.status != -1) {
++		const unsigned char *proto;
++		unsigned int proto_len;
++		SSL_get0_next_proto_negotiated(s, &proto, &proto_len);
++		BIO_printf(bio, "Next protocol: (%d) ", next_proto.status);
++		BIO_write(bio, proto, proto_len);
++		BIO_write(bio, "\n", 1);
++	}
++#endif
++
+ 	SSL_SESSION_print(bio,SSL_get_session(s));
+ 	BIO_printf(bio,"---\n");
+ 	if (peer != NULL)
+--- openssl-1.0.0b.orig/apps/s_server.c	2010-06-15 17:25:02.000000000 +0000
++++ openssl-1.0.0b/apps/s_server.c	2010-11-29 19:56:04.902465346 +0000
+@@ -492,6 +492,9 @@ static void sv_usage(void)
+ 	BIO_printf(bio_err," -tlsextdebug  - hex dump of all TLS extensions received\n");
+ 	BIO_printf(bio_err," -no_ticket    - disable use of RFC4507bis session tickets\n");
+ 	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
++# ifndef OPENSSL_NO_NEXTPROTONEG
++	BIO_printf(bio_err," -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n");
++# endif
+ #endif
+ 	}
+ 
+@@ -826,6 +829,24 @@ BIO_printf(err, "cert_status: received %
+ 	ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+ 	goto done;
+ 	}
++
++# ifndef OPENSSL_NO_NEXTPROTONEG
++/* This is the context that we pass to next_proto_cb */
++typedef struct tlsextnextprotoctx_st {
++	unsigned char *data;
++	unsigned int len;
++} tlsextnextprotoctx;
++
++static int next_proto_cb(SSL *s, const unsigned char **data, unsigned int *len, void *arg)
++	{
++	tlsextnextprotoctx *next_proto = arg;
++
++	*data = next_proto->data;
++	*len = next_proto->len;
++
++	return SSL_TLSEXT_ERR_OK;
++	}
++# endif  /* ndef OPENSSL_NO_NPN */
+ #endif
+ 
+ int MAIN(int, char **);
+@@ -867,6 +888,10 @@ int MAIN(int argc, char *argv[])
+ #endif
+ #ifndef OPENSSL_NO_TLSEXT
+         tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING};
++# ifndef OPENSSL_NO_NEXTPROTONEG
++	const char *next_proto_neg_in = NULL;
++	tlsextnextprotoctx next_proto;
++# endif
+ #endif
+ #ifndef OPENSSL_NO_PSK
+ 	/* by default do not send a PSK identity hint */
+@@ -1191,7 +1216,13 @@ int MAIN(int argc, char *argv[])
+ 			if (--argc < 1) goto bad;
+ 			s_key_file2= *(++argv);
+ 			}
+-			
++# ifndef OPENSSL_NO_NEXTPROTONEG
++		else if	(strcmp(*argv,"-nextprotoneg") == 0)
++			{
++			if (--argc < 1) goto bad;
++			next_proto_neg_in = *(++argv);
++			}
++# endif
+ #endif
+ #if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
+ 		else if (strcmp(*argv,"-jpake") == 0)
+@@ -1476,6 +1507,11 @@ bad:
+ 		if (vpm)
+ 			SSL_CTX_set1_param(ctx2, vpm);
+ 		}
++
++# ifndef OPENSSL_NO_NEXTPROTONEG
++	if (next_proto.data)
++		SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, &next_proto);
++# endif
+ #endif 
+ 
+ #ifndef OPENSSL_NO_DH
+@@ -1617,6 +1653,21 @@ bad:
+ 					goto end;
+ 					}
+ 				}
++# ifndef OPENSSL_NO_NEXTPROTONEG
++		if (next_proto_neg_in)
++			{
++			unsigned short len;
++			next_proto.data = next_protos_parse(&len,
++				next_proto_neg_in);
++			if (next_proto.data == NULL)
++				goto end;
++			next_proto.len = len;
++			}
++		else
++			{
++			next_proto.data = NULL;
++			}
++# endif
+ #endif
+ 		RSA_free(rsa);
+ 		BIO_printf(bio_s_out,"\n");
+@@ -2159,6 +2210,10 @@ static int init_ssl_connection(SSL *con)
+ 	X509 *peer;
+ 	long verify_error;
+ 	MS_STATIC char buf[BUFSIZ];
++#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
++	const unsigned char *next_proto_neg;
++	unsigned next_proto_neg_len;
++#endif
+ 
+ 	if ((i=SSL_accept(con)) <= 0)
+ 		{
+@@ -2198,6 +2253,15 @@ static int init_ssl_connection(SSL *con)
+ 		BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf);
+ 	str=SSL_CIPHER_get_name(SSL_get_current_cipher(con));
+ 	BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)");
++#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
++	SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len);
++	if (next_proto_neg)
++		{
++		BIO_printf(bio_s_out,"NEXTPROTO is ");
++		BIO_write(bio_s_out, next_proto_neg, next_proto_neg_len);
++		BIO_printf(bio_s_out, "\n");
++		}
++#endif
+ 	if (con->hit) BIO_printf(bio_s_out,"Reused session-id\n");
+ 	if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) &
+ 		TLS1_FLAGS_TLS_PADDING_BUG)
+--- openssl-1.0.0b.orig/include/openssl/ssl.h	2010-11-29 19:56:04.846517045 +0000
++++ openssl-1.0.0b/include/openssl/ssl.h	2010-11-29 19:56:04.965928855 +0000
+@@ -857,6 +857,25 @@ struct ssl_ctx_st
+ 	/* draft-rescorla-tls-opaque-prf-input-00.txt information */
+ 	int (*tlsext_opaque_prf_input_callback)(SSL *, void *peerinput, size_t len, void *arg);
+ 	void *tlsext_opaque_prf_input_callback_arg;
++
++# ifndef OPENSSL_NO_NEXTPROTONEG
++	/* Next protocol negotiation information */
++	/* (for experimental NPN extension). */
++
++	/* For a server, this contains a callback function by which the set of
++	 * advertised protocols can be provided. */
++	int (*next_protos_advertised_cb)(SSL *s, const unsigned char **buf,
++			                 unsigned int *len, void *arg);
++	void *next_protos_advertised_cb_arg;
++	/* For a client, this contains a callback function that selects the
++	 * next protocol from the list provided by the server. */
++	int (*next_proto_select_cb)(SSL *s, unsigned char **out,
++				    unsigned char *outlen,
++				    const unsigned char *in,
++				    unsigned int inlen,
++				    void *arg);
++	void *next_proto_select_cb_arg;
++# endif
+ #endif
+ 
+ #ifndef OPENSSL_NO_PSK
+@@ -928,6 +947,30 @@ int SSL_CTX_set_client_cert_engine(SSL_C
+ #endif
+ void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len));
+ void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len));
++#ifndef OPENSSL_NO_NEXTPROTONEG
++void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s,
++					   int (*cb) (SSL *ssl,
++						      const unsigned char **out,
++						      unsigned int *outlen,
++						      void *arg), void *arg);
++void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s,
++				      int (*cb) (SSL *ssl, unsigned char **out,
++						 unsigned char *outlen,
++						 const unsigned char *in,
++						 unsigned int inlen, void *arg),
++				      void *arg);
++
++int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
++			  const unsigned char *in, unsigned int inlen,
++			  const unsigned char *client, unsigned int client_len);
++void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
++				    unsigned *len);
++
++#define OPENSSL_NPN_UNSUPPORTED	0
++#define OPENSSL_NPN_NEGOTIATED	1
++#define OPENSSL_NPN_NO_OVERLAP	2
++
++#endif
+ 
+ #ifndef OPENSSL_NO_PSK
+ /* the maximum length of the buffer given to callbacks containing the
+@@ -1187,6 +1230,19 @@ struct ssl_st
+ 	void *tls_session_secret_cb_arg;
+ 
+ 	SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
++
++#ifndef OPENSSL_NO_NEXTPROTONEG
++	/* Next protocol negotiation. For the client, this is the protocol that
++	 * we sent in NextProtocol and is set when handling ServerHello
++	 * extensions.
++	 *
++	 * For a server, this is the client's selected_protocol from
++	 * NextProtocol and is set when handling the NextProtocol message,
++	 * before the Finished message. */
++	unsigned char *next_proto_negotiated;
++	unsigned char next_proto_negotiated_len;
++#endif
++
+ #define session_ctx initial_ctx
+ #else
+ #define session_ctx ctx
+@@ -1919,6 +1975,7 @@ void ERR_load_SSL_strings(void);
+ #define SSL_F_SSL3_GET_KEY_EXCHANGE			 141
+ #define SSL_F_SSL3_GET_MESSAGE				 142
+ #define SSL_F_SSL3_GET_NEW_SESSION_TICKET		 283
++#define SSL_F_SSL3_GET_NEXT_PROTO			 304
+ #define SSL_F_SSL3_GET_RECORD				 143
+ #define SSL_F_SSL3_GET_SERVER_CERTIFICATE		 144
+ #define SSL_F_SSL3_GET_SERVER_DONE			 145
+@@ -2117,6 +2174,8 @@ void ERR_load_SSL_strings(void);
+ #define SSL_R_EXCESSIVE_MESSAGE_SIZE			 152
+ #define SSL_R_EXTRA_DATA_IN_MESSAGE			 153
+ #define SSL_R_GOT_A_FIN_BEFORE_A_CCS			 154
++#define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS		 346
++#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION		 347
+ #define SSL_R_HTTPS_PROXY_REQUEST			 155
+ #define SSL_R_HTTP_REQUEST				 156
+ #define SSL_R_ILLEGAL_PADDING				 283
+--- openssl-1.0.0b.orig/include/openssl/ssl3.h	2010-11-29 19:56:04.832465351 +0000
++++ openssl-1.0.0b/include/openssl/ssl3.h	2010-11-29 19:56:04.965928855 +0000
+@@ -465,6 +465,12 @@ typedef struct ssl3_state_st
+ 	void *server_opaque_prf_input;
+ 	size_t server_opaque_prf_input_len;
+ 
++#ifndef OPENSSL_NO_NEXTPROTONEG
++	/* Set if we saw the Next Protocol Negotiation extension from
++	   our peer. */
++	int next_proto_neg_seen;
++#endif
++
+ 	struct	{
+ 		/* actually only needs to be 16+20 */
+ 		unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2];
+@@ -557,6 +563,10 @@ typedef struct ssl3_state_st
+ #define SSL3_ST_CW_CERT_VRFY_B		(0x191|SSL_ST_CONNECT)
+ #define SSL3_ST_CW_CHANGE_A		(0x1A0|SSL_ST_CONNECT)
+ #define SSL3_ST_CW_CHANGE_B		(0x1A1|SSL_ST_CONNECT)
++#ifndef OPENSSL_NO_NEXTPROTONEG
++#define SSL3_ST_CW_NEXT_PROTO_A		(0x200|SSL_ST_CONNECT)
++#define SSL3_ST_CW_NEXT_PROTO_B		(0x201|SSL_ST_CONNECT)
++#endif
+ #define SSL3_ST_CW_FINISHED_A		(0x1B0|SSL_ST_CONNECT)
+ #define SSL3_ST_CW_FINISHED_B		(0x1B1|SSL_ST_CONNECT)
+ /* read from server */
+@@ -602,6 +612,10 @@ typedef struct ssl3_state_st
+ #define SSL3_ST_SR_CERT_VRFY_B		(0x1A1|SSL_ST_ACCEPT)
+ #define SSL3_ST_SR_CHANGE_A		(0x1B0|SSL_ST_ACCEPT)
+ #define SSL3_ST_SR_CHANGE_B		(0x1B1|SSL_ST_ACCEPT)
++#ifndef OPENSSL_NO_NEXTPROTONEG
++#define SSL3_ST_SR_NEXT_PROTO_A		(0x210|SSL_ST_ACCEPT)
++#define SSL3_ST_SR_NEXT_PROTO_B		(0x211|SSL_ST_ACCEPT)
++#endif
+ #define SSL3_ST_SR_FINISHED_A		(0x1C0|SSL_ST_ACCEPT)
+ #define SSL3_ST_SR_FINISHED_B		(0x1C1|SSL_ST_ACCEPT)
+ /* write to client */
+@@ -626,6 +640,9 @@ typedef struct ssl3_state_st
+ #define SSL3_MT_CLIENT_KEY_EXCHANGE		16
+ #define SSL3_MT_FINISHED			20
+ #define SSL3_MT_CERTIFICATE_STATUS		22
++#ifndef OPENSSL_NO_NEXTPROTONEG
++#define SSL3_MT_NEXT_PROTO			67
++#endif
+ #define DTLS1_MT_HELLO_VERIFY_REQUEST    3
+ 
+ 
+--- openssl-1.0.0b.orig/include/openssl/tls1.h	2009-11-11 14:51:29.000000000 +0000
++++ openssl-1.0.0b/include/openssl/tls1.h	2010-11-29 19:56:04.965928855 +0000
+@@ -204,6 +204,11 @@ extern "C" {
+ /* Temporary extension type */
+ #define TLSEXT_TYPE_renegotiate                 0xff01
+ 
++#ifndef OPENSSL_NO_NEXTPROTONEG
++/* This is not an IANA defined extension number */
++#define TLSEXT_TYPE_next_proto_neg		13172
++#endif
++
+ /* NameType value from RFC 3546 */
+ #define TLSEXT_NAMETYPE_host_name 0
+ /* status request value from RFC 3546 */
+--- openssl-1.0.0b.orig/ssl/s3_both.c	2010-11-29 19:56:04.846517045 +0000
++++ openssl-1.0.0b/ssl/s3_both.c	2010-11-29 19:56:04.965928855 +0000
+@@ -202,15 +202,40 @@ int ssl3_send_finished(SSL *s, int a, in
+ 	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
+ 	}
+ 
++#ifndef OPENSSL_NO_NEXTPROTONEG
++/* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen to far. */
++static void ssl3_take_mac(SSL *s)
++	{
++	const char *sender;
++	int slen;
++
++	if (s->state & SSL_ST_CONNECT)
++		{
++		sender=s->method->ssl3_enc->server_finished_label;
++		slen=s->method->ssl3_enc->server_finished_label_len;
++		}
++	else
++		{
++		sender=s->method->ssl3_enc->client_finished_label;
++		slen=s->method->ssl3_enc->client_finished_label_len;
++		}
++
++	s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
++		sender,slen,s->s3->tmp.peer_finish_md);
++	}
++#endif
++
+ int ssl3_get_finished(SSL *s, int a, int b)
+ 	{
+ 	int al,i,ok;
+ 	long n;
+ 	unsigned char *p;
+ 
++#ifdef OPENSSL_NO_NEXTPROTONEG
+ 	/* the mac has already been generated when we received the
+ 	 * change cipher spec message and is in s->s3->tmp.peer_finish_md
+ 	 */ 
++#endif
+ 
+ 	n=s->method->ssl_get_message(s,
+ 		a,
+@@ -521,6 +546,15 @@ long ssl3_get_message(SSL *s, int st1, i
+ 		s->init_num += i;
+ 		n -= i;
+ 		}
++
++#ifndef OPENSSL_NO_NEXTPROTONEG
++	/* If receiving Finished, record MAC of prior handshake messages for
++	 * Finished verification. */
++	if (*s->init_buf->data == SSL3_MT_FINISHED)
++		ssl3_take_mac(s);
++#endif
++
++	/* Feed this message into MAC computation. */
+ 	ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
+ 	if (s->msg_callback)
+ 		s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, (size_t)s->init_num + 4, s, s->msg_callback_arg);
+--- openssl-1.0.0b.orig/ssl/s3_clnt.c	2010-11-29 19:56:04.846517045 +0000
++++ openssl-1.0.0b/ssl/s3_clnt.c	2010-11-29 19:56:04.965928855 +0000
+@@ -435,7 +435,16 @@ int ssl3_connect(SSL *s)
+ 			ret=ssl3_send_change_cipher_spec(s,
+ 				SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
+ 			if (ret <= 0) goto end;
++
++#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
+ 			s->state=SSL3_ST_CW_FINISHED_A;
++#else
++			if (s->next_proto_negotiated)
++				s->state=SSL3_ST_CW_NEXT_PROTO_A;
++			else
++				s->state=SSL3_ST_CW_FINISHED_A;
++#endif
++
+ 			s->init_num=0;
+ 
+ 			s->session->cipher=s->s3->tmp.new_cipher;
+@@ -463,6 +472,15 @@ int ssl3_connect(SSL *s)
+ 
+ 			break;
+ 
++#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
++		case SSL3_ST_CW_NEXT_PROTO_A:
++		case SSL3_ST_CW_NEXT_PROTO_B:
++			ret=ssl3_send_next_proto(s);
++			if (ret <= 0) goto end;
++			s->state=SSL3_ST_CW_FINISHED_A;
++			break;
++#endif
++
+ 		case SSL3_ST_CW_FINISHED_A:
+ 		case SSL3_ST_CW_FINISHED_B:
+ 			ret=ssl3_send_finished(s,
+@@ -3060,6 +3078,32 @@ err:
+  */
+ 
+ #ifndef OPENSSL_NO_TLSEXT
++# ifndef OPENSSL_NO_NEXTPROTONEG
++int ssl3_send_next_proto(SSL *s)
++	{
++	unsigned int len, padding_len;
++	unsigned char *d;
++
++	if (s->state == SSL3_ST_CW_NEXT_PROTO_A)
++		{
++		len = s->next_proto_negotiated_len;
++		padding_len = 32 - ((len + 2) % 32);
++		d = (unsigned char *)s->init_buf->data;
++		d[4] = len;
++		memcpy(d + 5, s->next_proto_negotiated, len);
++		d[5 + len] = padding_len;
++		memset(d + 6 + len, 0, padding_len);
++		*(d++)=SSL3_MT_NEXT_PROTO;
++		l2n3(2 + len + padding_len, d);
++		s->state = SSL3_ST_CW_NEXT_PROTO_B;
++		s->init_num = 4 + 2 + len + padding_len;
++		s->init_off = 0;
++		}
++
++	return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
++	}
++# endif
++
+ int ssl3_check_finished(SSL *s)
+ 	{
+ 	int ok;
+--- openssl-1.0.0b.orig/ssl/s3_lib.c	2010-11-29 19:56:04.832465351 +0000
++++ openssl-1.0.0b/ssl/s3_lib.c	2010-11-29 19:56:04.965928855 +0000
+@@ -2230,6 +2230,15 @@ void ssl3_clear(SSL *s)
+ 	s->s3->num_renegotiations=0;
+ 	s->s3->in_read_app_data=0;
+ 	s->version=SSL3_VERSION;
++
++#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
++	if (s->next_proto_negotiated)
++		{
++		OPENSSL_free(s->next_proto_negotiated);
++		s->next_proto_negotiated = NULL;
++		s->next_proto_negotiated_len = 0;
++		}
++#endif
+ 	}
+ 
+ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
+--- openssl-1.0.0b.orig/ssl/s3_pkt.c	2010-11-29 19:56:04.832465351 +0000
++++ openssl-1.0.0b/ssl/s3_pkt.c	2010-11-29 19:56:04.965928855 +0000
+@@ -1394,8 +1394,10 @@ err:
+ int ssl3_do_change_cipher_spec(SSL *s)
+ 	{
+ 	int i;
++#ifdef OPENSSL_NO_NEXTPROTONEG
+ 	const char *sender;
+ 	int slen;
++#endif
+ 
+ 	if (s->state & SSL_ST_ACCEPT)
+ 		i=SSL3_CHANGE_CIPHER_SERVER_READ;
+@@ -1418,6 +1420,7 @@ int ssl3_do_change_cipher_spec(SSL *s)
+ 	if (!s->method->ssl3_enc->change_cipher_state(s,i))
+ 		return(0);
+ 
++#ifdef OPENSSL_NO_NEXTPROTONEG
+ 	/* we have to record the message digest at
+ 	 * this point so we can get it before we read
+ 	 * the finished message */
+@@ -1434,6 +1437,7 @@ int ssl3_do_change_cipher_spec(SSL *s)
+ 
+ 	s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
+ 		sender,slen,s->s3->tmp.peer_finish_md);
++#endif
+ 
+ 	return(1);
+ 	}
+--- openssl-1.0.0b.orig/ssl/s3_srvr.c	2010-11-29 19:56:04.846517045 +0000
++++ openssl-1.0.0b/ssl/s3_srvr.c	2010-11-29 19:56:04.965928855 +0000
+@@ -538,7 +538,14 @@ int ssl3_accept(SSL *s)
+ 				 * the client uses its key from the certificate
+ 				 * for key exchange.
+ 				 */
++#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
+ 				s->state=SSL3_ST_SR_FINISHED_A;
++#else
++				if (s->s3->next_proto_neg_seen)
++					s->state=SSL3_ST_SR_NEXT_PROTO_A;
++				else
++					s->state=SSL3_ST_SR_FINISHED_A;
++#endif
+ 				s->init_num = 0;
+ 				}
+ 			else
+@@ -581,10 +588,27 @@ int ssl3_accept(SSL *s)
+ 			ret=ssl3_get_cert_verify(s);
+ 			if (ret <= 0) goto end;
+ 
++#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
+ 			s->state=SSL3_ST_SR_FINISHED_A;
++#else
++			if (s->s3->next_proto_neg_seen)
++				s->state=SSL3_ST_SR_NEXT_PROTO_A;
++			else
++				s->state=SSL3_ST_SR_FINISHED_A;
++#endif
+ 			s->init_num=0;
+ 			break;
+ 
++#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
++		case SSL3_ST_SR_NEXT_PROTO_A:
++		case SSL3_ST_SR_NEXT_PROTO_B:
++			ret=ssl3_get_next_proto(s);
++			if (ret <= 0) goto end;
++			s->init_num = 0;
++			s->state=SSL3_ST_SR_FINISHED_A;
++			break;
++#endif
++
+ 		case SSL3_ST_SR_FINISHED_A:
+ 		case SSL3_ST_SR_FINISHED_B:
+ 			ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
+@@ -655,7 +679,16 @@ int ssl3_accept(SSL *s)
+ 			if (ret <= 0) goto end;
+ 			s->state=SSL3_ST_SW_FLUSH;
+ 			if (s->hit)
++				{
++#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
+ 				s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
++#else
++				if (s->s3->next_proto_neg_seen)
++					s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A;
++				else
++					s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
++#endif
++				}
+ 			else
+ 				s->s3->tmp.next_state=SSL_ST_OK;
+ 			s->init_num=0;
+@@ -3196,4 +3229,72 @@ int ssl3_send_cert_status(SSL *s)
+ 	/* SSL3_ST_SW_CERT_STATUS_B */
+ 	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
+ 	}
++
++# ifndef OPENSSL_NO_NPN
++/* ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. It
++ * sets the next_proto member in s if found */
++int ssl3_get_next_proto(SSL *s)
++	{
++	int ok;
++	unsigned proto_len, padding_len;
++	long n;
++	const unsigned char *p;
++
++	/* Clients cannot send a NextProtocol message if we didn't see the
++	 * extension in their ClientHello */
++	if (!s->s3->next_proto_neg_seen)
++		{
++		SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION);
++		return -1;
++		}
++
++	n=s->method->ssl_get_message(s,
++		SSL3_ST_SR_NEXT_PROTO_A,
++		SSL3_ST_SR_NEXT_PROTO_B,
++		SSL3_MT_NEXT_PROTO,
++		514,  /* See the payload format below */
++		&ok);
++
++	if (!ok)
++		return((int)n);
++
++	/* s->state doesn't reflect whether ChangeCipherSpec has been received
++	 * in this handshake, but s->s3->change_cipher_spec does (will be reset
++	 * by ssl3_get_finished). */
++	if (!s->s3->change_cipher_spec)
++		{
++		SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS);
++		return -1;
++		}
++
++	if (n < 2)
++		return 0;  /* The body must be > 1 bytes long */
++
++	p=(unsigned char *)s->init_msg;
++
++	/* The payload looks like:
++	 *   uint8 proto_len;
++	 *   uint8 proto[proto_len];
++	 *   uint8 padding_len;
++	 *   uint8 padding[padding_len];
++	 */
++	proto_len = p[0];
++	if (proto_len + 2 > s->init_num)
++		return 0;
++	padding_len = p[proto_len + 1];
++	if (proto_len + padding_len + 2 != s->init_num)
++		return 0;
++
++	s->next_proto_negotiated = OPENSSL_malloc(proto_len);
++	if (!s->next_proto_negotiated)
++		{
++		SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,ERR_R_MALLOC_FAILURE);
++		return 0;
++		}
++	memcpy(s->next_proto_negotiated, p + 1, proto_len);
++	s->next_proto_negotiated_len = proto_len;
++
++	return 1;
++	}
++# endif
+ #endif
+--- openssl-1.0.0b.orig/ssl/ssl.h	2010-11-29 19:56:04.846517045 +0000
++++ openssl-1.0.0b/ssl/ssl.h	2010-11-29 19:56:04.965928855 +0000
+@@ -857,6 +857,25 @@ struct ssl_ctx_st
+ 	/* draft-rescorla-tls-opaque-prf-input-00.txt information */
+ 	int (*tlsext_opaque_prf_input_callback)(SSL *, void *peerinput, size_t len, void *arg);
+ 	void *tlsext_opaque_prf_input_callback_arg;
++
++# ifndef OPENSSL_NO_NEXTPROTONEG
++	/* Next protocol negotiation information */
++	/* (for experimental NPN extension). */
++
++	/* For a server, this contains a callback function by which the set of
++	 * advertised protocols can be provided. */
++	int (*next_protos_advertised_cb)(SSL *s, const unsigned char **buf,
++			                 unsigned int *len, void *arg);
++	void *next_protos_advertised_cb_arg;
++	/* For a client, this contains a callback function that selects the
++	 * next protocol from the list provided by the server. */
++	int (*next_proto_select_cb)(SSL *s, unsigned char **out,
++				    unsigned char *outlen,
++				    const unsigned char *in,
++				    unsigned int inlen,
++				    void *arg);
++	void *next_proto_select_cb_arg;
++# endif
+ #endif
+ 
+ #ifndef OPENSSL_NO_PSK
+@@ -928,6 +947,30 @@ int SSL_CTX_set_client_cert_engine(SSL_C
+ #endif
+ void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len));
+ void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len));
++#ifndef OPENSSL_NO_NEXTPROTONEG
++void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s,
++					   int (*cb) (SSL *ssl,
++						      const unsigned char **out,
++						      unsigned int *outlen,
++						      void *arg), void *arg);
++void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s,
++				      int (*cb) (SSL *ssl, unsigned char **out,
++						 unsigned char *outlen,
++						 const unsigned char *in,
++						 unsigned int inlen, void *arg),
++				      void *arg);
++
++int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
++			  const unsigned char *in, unsigned int inlen,
++			  const unsigned char *client, unsigned int client_len);
++void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
++				    unsigned *len);
++
++#define OPENSSL_NPN_UNSUPPORTED	0
++#define OPENSSL_NPN_NEGOTIATED	1
++#define OPENSSL_NPN_NO_OVERLAP	2
++
++#endif
+ 
+ #ifndef OPENSSL_NO_PSK
+ /* the maximum length of the buffer given to callbacks containing the
+@@ -1187,6 +1230,19 @@ struct ssl_st
+ 	void *tls_session_secret_cb_arg;
+ 
+ 	SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
++
++#ifndef OPENSSL_NO_NEXTPROTONEG
++	/* Next protocol negotiation. For the client, this is the protocol that
++	 * we sent in NextProtocol and is set when handling ServerHello
++	 * extensions.
++	 *
++	 * For a server, this is the client's selected_protocol from
++	 * NextProtocol and is set when handling the NextProtocol message,
++	 * before the Finished message. */
++	unsigned char *next_proto_negotiated;
++	unsigned char next_proto_negotiated_len;
++#endif
++
+ #define session_ctx initial_ctx
+ #else
+ #define session_ctx ctx
+@@ -1919,6 +1975,7 @@ void ERR_load_SSL_strings(void);
+ #define SSL_F_SSL3_GET_KEY_EXCHANGE			 141
+ #define SSL_F_SSL3_GET_MESSAGE				 142
+ #define SSL_F_SSL3_GET_NEW_SESSION_TICKET		 283
++#define SSL_F_SSL3_GET_NEXT_PROTO			 304
+ #define SSL_F_SSL3_GET_RECORD				 143
+ #define SSL_F_SSL3_GET_SERVER_CERTIFICATE		 144
+ #define SSL_F_SSL3_GET_SERVER_DONE			 145
+@@ -2117,6 +2174,8 @@ void ERR_load_SSL_strings(void);
+ #define SSL_R_EXCESSIVE_MESSAGE_SIZE			 152
+ #define SSL_R_EXTRA_DATA_IN_MESSAGE			 153
+ #define SSL_R_GOT_A_FIN_BEFORE_A_CCS			 154
++#define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS		 346
++#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION		 347
+ #define SSL_R_HTTPS_PROXY_REQUEST			 155
+ #define SSL_R_HTTP_REQUEST				 156
+ #define SSL_R_ILLEGAL_PADDING				 283
+--- openssl-1.0.0b.orig/ssl/ssl3.h	2010-11-29 19:56:04.832465351 +0000
++++ openssl-1.0.0b/ssl/ssl3.h	2010-11-29 19:56:04.965928855 +0000
+@@ -465,6 +465,12 @@ typedef struct ssl3_state_st
+ 	void *server_opaque_prf_input;
+ 	size_t server_opaque_prf_input_len;
+ 
++#ifndef OPENSSL_NO_NEXTPROTONEG
++	/* Set if we saw the Next Protocol Negotiation extension from
++	   our peer. */
++	int next_proto_neg_seen;
++#endif
++
+ 	struct	{
+ 		/* actually only needs to be 16+20 */
+ 		unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2];
+@@ -557,6 +563,10 @@ typedef struct ssl3_state_st
+ #define SSL3_ST_CW_CERT_VRFY_B		(0x191|SSL_ST_CONNECT)
+ #define SSL3_ST_CW_CHANGE_A		(0x1A0|SSL_ST_CONNECT)
+ #define SSL3_ST_CW_CHANGE_B		(0x1A1|SSL_ST_CONNECT)
++#ifndef OPENSSL_NO_NEXTPROTONEG
++#define SSL3_ST_CW_NEXT_PROTO_A		(0x200|SSL_ST_CONNECT)
++#define SSL3_ST_CW_NEXT_PROTO_B		(0x201|SSL_ST_CONNECT)
++#endif
+ #define SSL3_ST_CW_FINISHED_A		(0x1B0|SSL_ST_CONNECT)
+ #define SSL3_ST_CW_FINISHED_B		(0x1B1|SSL_ST_CONNECT)
+ /* read from server */
+@@ -602,6 +612,10 @@ typedef struct ssl3_state_st
+ #define SSL3_ST_SR_CERT_VRFY_B		(0x1A1|SSL_ST_ACCEPT)
+ #define SSL3_ST_SR_CHANGE_A		(0x1B0|SSL_ST_ACCEPT)
+ #define SSL3_ST_SR_CHANGE_B		(0x1B1|SSL_ST_ACCEPT)
++#ifndef OPENSSL_NO_NEXTPROTONEG
++#define SSL3_ST_SR_NEXT_PROTO_A		(0x210|SSL_ST_ACCEPT)
++#define SSL3_ST_SR_NEXT_PROTO_B		(0x211|SSL_ST_ACCEPT)
++#endif
+ #define SSL3_ST_SR_FINISHED_A		(0x1C0|SSL_ST_ACCEPT)
+ #define SSL3_ST_SR_FINISHED_B		(0x1C1|SSL_ST_ACCEPT)
+ /* write to client */
+@@ -626,6 +640,9 @@ typedef struct ssl3_state_st
+ #define SSL3_MT_CLIENT_KEY_EXCHANGE		16
+ #define SSL3_MT_FINISHED			20
+ #define SSL3_MT_CERTIFICATE_STATUS		22
++#ifndef OPENSSL_NO_NEXTPROTONEG
++#define SSL3_MT_NEXT_PROTO			67
++#endif
+ #define DTLS1_MT_HELLO_VERIFY_REQUEST    3
+ 
+ 
+--- openssl-1.0.0b.orig/ssl/ssl_err.c	2010-11-29 19:56:04.846517045 +0000
++++ openssl-1.0.0b/ssl/ssl_err.c	2010-11-29 19:56:04.965928855 +0000
+@@ -155,6 +155,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
+ {ERR_FUNC(SSL_F_SSL3_GET_KEY_EXCHANGE),	"SSL3_GET_KEY_EXCHANGE"},
+ {ERR_FUNC(SSL_F_SSL3_GET_MESSAGE),	"SSL3_GET_MESSAGE"},
+ {ERR_FUNC(SSL_F_SSL3_GET_NEW_SESSION_TICKET),	"SSL3_GET_NEW_SESSION_TICKET"},
++{ERR_FUNC(SSL_F_SSL3_GET_NEXT_PROTO),	"SSL3_GET_NEXT_PROTO"},
+ {ERR_FUNC(SSL_F_SSL3_GET_RECORD),	"SSL3_GET_RECORD"},
+ {ERR_FUNC(SSL_F_SSL3_GET_SERVER_CERTIFICATE),	"SSL3_GET_SERVER_CERTIFICATE"},
+ {ERR_FUNC(SSL_F_SSL3_GET_SERVER_DONE),	"SSL3_GET_SERVER_DONE"},
+@@ -355,6 +356,8 @@ static ERR_STRING_DATA SSL_str_reasons[]
+ {ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE),"excessive message size"},
+ {ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE) ,"extra data in message"},
+ {ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS),"got a fin before a ccs"},
++{ERR_REASON(SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS),"got next proto before a ccs"},
++{ERR_REASON(SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION),"got next proto without seeing extension"},
+ {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST)   ,"https proxy request"},
+ {ERR_REASON(SSL_R_HTTP_REQUEST)          ,"http request"},
+ {ERR_REASON(SSL_R_ILLEGAL_PADDING)       ,"illegal padding"},
+--- openssl-1.0.0b.orig/ssl/ssl_lib.c	2010-11-29 19:56:04.846517045 +0000
++++ openssl-1.0.0b/ssl/ssl_lib.c	2010-11-29 19:56:04.965928855 +0000
+@@ -354,6 +354,9 @@ SSL *SSL_new(SSL_CTX *ctx)
+ 	s->tlsext_ocsp_resplen = -1;
+ 	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
+ 	s->initial_ctx=ctx;
++# ifndef OPENSSL_NO_NEXTPROTONEG
++	s->next_proto_negotiated = NULL;
++# endif
+ #endif
+ 
+ 	s->verify_result=X509_V_OK;
+@@ -587,6 +590,11 @@ void SSL_free(SSL *s)
+ 		kssl_ctx_free(s->kssl_ctx);
+ #endif	/* OPENSSL_NO_KRB5 */
+ 
++#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
++	if (s->next_proto_negotiated)
++		OPENSSL_free(s->next_proto_negotiated);
++#endif
++
+ 	OPENSSL_free(s);
+ 	}
+ 
+@@ -1503,6 +1511,124 @@ int SSL_get_servername_type(const SSL *s
+ 		return TLSEXT_NAMETYPE_host_name;
+ 	return -1;
+ 	}
++
++# ifndef OPENSSL_NO_NEXTPROTONEG
++/* SSL_select_next_proto implements the standard protocol selection. It is
++ * expected that this function is called from the callback set by
++ * SSL_CTX_set_next_proto_select_cb.
++ *
++ * The protocol data is assumed to be a vector of 8-bit, length prefixed byte
++ * strings. The length byte itself is not included in the length. A byte
++ * string of length 0 is invalid. No byte string may be truncated.
++ *
++ * The current, but experimental algorithm for selecting the protocol is:
++ *
++ * 1) If the server doesn't support NPN then this is indicated to the
++ * callback. In this case, the client application has to abort the connection
++ * or have a default application level protocol.
++ *
++ * 2) If the server supports NPN, but advertises an empty list then the
++ * client selects the first protcol in its list, but indicates via the
++ * API that this fallback case was enacted.
++ *
++ * 3) Otherwise, the client finds the first protocol in the server's list
++ * that it supports and selects this protocol. This is because it's
++ * assumed that the server has better information about which protocol
++ * a client should use.
++ *
++ * 4) If the client doesn't support any of the server's advertised
++ * protocols, then this is treated the same as case 2.
++ *
++ * It returns either
++ * OPENSSL_NPN_NEGOTIATED if a common protocol was found, or
++ * OPENSSL_NPN_NO_OVERLAP if the fallback case was reached.
++ */
++int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, const unsigned char *server, unsigned int server_len, const unsigned char *client, unsigned int client_len)
++	{
++	unsigned int i, j;
++	const unsigned char *result;
++	int status = OPENSSL_NPN_UNSUPPORTED;
++
++	/* For each protocol in server preference order, see if we support it. */
++	for (i = 0; i < server_len; )
++		{
++		for (j = 0; j < client_len; )
++			{
++			if (server[i] == client[j] &&
++			    memcmp(&server[i+1], &client[j+1], server[i]) == 0)
++				{
++				/* We found a match */
++				result = &server[i];
++				status = OPENSSL_NPN_NEGOTIATED;
++				goto found;
++				}
++			j += client[j];
++			j++;
++			}
++		i += server[i];
++		i++;
++		}
++
++	/* There's no overlap between our protocols and the server's list. */
++	result = client;
++	status = OPENSSL_NPN_NO_OVERLAP;
++
++	found:
++	*out = (unsigned char *) result + 1;
++	*outlen = result[0];
++	return status;
++	}
++
++/* SSL_get0_next_proto_negotiated sets *data and *len to point to the client's
++ * requested protocol for this connection and returns 0. If the client didn't
++ * request any protocol, then *data is set to NULL.
++ *
++ * Note that the client can request any protocol it chooses. The value returned
++ * from this function need not be a member of the list of supported protocols
++ * provided by the callback.
++ */
++void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, unsigned *len)
++	{
++	*data = s->next_proto_negotiated;
++	if (!*data) {
++		*len = 0;
++	} else {
++		*len = s->next_proto_negotiated_len;
++	}
++}
++
++/* SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when a
++ * TLS server needs a list of supported protocols for Next Protocol
++ * Negotiation. The returned list must be in wire format.  The list is returned
++ * by setting |out| to point to it and |outlen| to its length. This memory will
++ * not be modified, but one should assume that the SSL* keeps a reference to
++ * it.
++ *
++ * The callback should return SSL_TLSEXT_ERR_OK if it wishes to advertise. Otherwise, no
++ * such extension will be included in the ServerHello. */
++void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *ctx, int (*cb) (SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg), void *arg)
++	{
++	ctx->next_protos_advertised_cb = cb;
++	ctx->next_protos_advertised_cb_arg = arg;
++	}
++
++/* SSL_CTX_set_next_proto_select_cb sets a callback that is called when a
++ * client needs to select a protocol from the server's provided list. |out|
++ * must be set to point to the selected protocol (which may be within |in|).
++ * The length of the protocol name must be written into |outlen|. The server's
++ * advertised protocols are provided in |in| and |inlen|. The callback can
++ * assume that |in| is syntactically valid.
++ *
++ * The client must select a protocol. It is fatal to the connection if this
++ * callback returns a value other than SSL_TLSEXT_ERR_OK.
++ */
++void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg), void *arg)
++	{
++	ctx->next_proto_select_cb = cb;
++	ctx->next_proto_select_cb_arg = arg;
++	}
++
++# endif
+ #endif
+ 
+ static unsigned long ssl_session_hash(const SSL_SESSION *a)
+@@ -1667,6 +1793,10 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *m
+ 	ret->tlsext_status_cb = 0;
+ 	ret->tlsext_status_arg = NULL;
+ 
++# ifndef OPENSSL_NO_NEXTPROTONEG
++	ret->next_protos_advertised_cb = 0;
++	ret->next_proto_select_cb = 0;
++# endif
+ #endif
+ #ifndef OPENSSL_NO_PSK
+ 	ret->psk_identity_hint=NULL;
+--- openssl-1.0.0b.orig/ssl/ssl_locl.h	2010-11-29 19:56:04.846517045 +0000
++++ openssl-1.0.0b/ssl/ssl_locl.h	2010-11-29 19:56:04.965928855 +0000
+@@ -968,6 +968,9 @@ int ssl3_get_server_certificate(SSL *s);
+ int ssl3_check_cert_and_algorithm(SSL *s);
+ #ifndef OPENSSL_NO_TLSEXT
+ int ssl3_check_finished(SSL *s);
++# ifndef OPENSSL_NO_NEXTPROTONEG
++int ssl3_send_next_proto(SSL *s);
++# endif
+ #endif
+ 
+ int dtls1_client_hello(SSL *s);
+@@ -986,6 +989,9 @@ int ssl3_check_client_hello(SSL *s);
+ int ssl3_get_client_certificate(SSL *s);
+ int ssl3_get_client_key_exchange(SSL *s);
+ int ssl3_get_cert_verify(SSL *s);
++#ifndef OPENSSL_NO_NEXTPROTONEG
++int ssl3_get_next_proto(SSL *s);
++#endif
+ 
+ int dtls1_send_hello_request(SSL *s);
+ int dtls1_send_server_hello(SSL *s);
+--- openssl-1.0.0b.orig/ssl/t1_lib.c	2010-11-16 13:26:24.000000000 +0000
++++ openssl-1.0.0b/ssl/t1_lib.c	2010-11-29 19:56:04.965928855 +0000
+@@ -494,6 +494,18 @@ unsigned char *ssl_add_clienthello_tlsex
+ 			i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
+ 		}
+ 
++#ifndef OPENSSL_NO_NEXTPROTONEG
++	if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len)
++		{
++		/* The client advertises an emtpy extension to indicate its
++		 * support for Next Protocol Negotiation */
++		if (limit - ret - 4 < 0)
++			return NULL;
++		s2n(TLSEXT_TYPE_next_proto_neg,ret);
++		s2n(0,ret);
++		}
++#endif
++
+ 	if ((extdatalen = ret-p-2)== 0) 
+ 		return p;
+ 
+@@ -505,6 +517,9 @@ unsigned char *ssl_add_serverhello_tlsex
+ 	{
+ 	int extdatalen=0;
+ 	unsigned char *ret = p;
++#ifndef OPENSSL_NO_NEXTPROTONEG
++	int next_proto_neg_seen;
++#endif
+ 
+ 	/* don't add extensions for SSLv3, unless doing secure renegotiation */
+ 	if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
+@@ -618,6 +633,28 @@ unsigned char *ssl_add_serverhello_tlsex
+ 
+ 		}
+ 
++#ifndef OPENSSL_NO_NEXTPROTONEG
++	next_proto_neg_seen = s->s3->next_proto_neg_seen;
++	s->s3->next_proto_neg_seen = 0;
++	if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb)
++		{
++		const unsigned char *npa;
++		unsigned int npalen;
++		int r;
++
++		r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen, s->ctx->next_protos_advertised_cb_arg);
++		if (r == SSL_TLSEXT_ERR_OK)
++			{
++			if ((long)(limit - ret - 4 - npalen) < 0) return NULL;
++			s2n(TLSEXT_TYPE_next_proto_neg,ret);
++			s2n(npalen,ret);
++			memcpy(ret, npa, npalen);
++			ret += npalen;
++			s->s3->next_proto_neg_seen = 1;
++			}
++		}
++#endif
++
+ 	if ((extdatalen = ret-p-2)== 0) 
+ 		return p;
+ 
+@@ -982,6 +1019,28 @@ int ssl_parse_clienthello_tlsext(SSL *s,
+ 				else
+ 					s->tlsext_status_type = -1;
+ 			}
++#ifndef OPENSSL_NO_NEXTPROTONEG
++		else if (type == TLSEXT_TYPE_next_proto_neg &&
++                         s->s3->tmp.finish_md_len == 0)
++			{
++			/* We shouldn't accept this extension on a
++			 * renegotiation.
++			 *
++			 * s->new_session will be set on renegotiation, but we
++			 * probably shouldn't rely that it couldn't be set on
++			 * the initial renegotation too in certain cases (when
++			 * there's some other reason to disallow resuming an
++			 * earlier session -- the current code won't be doing
++			 * anything like that, but this might change).
++
++			 * A valid sign that there's been a previous handshake
++			 * in this connection is if s->s3->tmp.finish_md_len >
++			 * 0.  (We are talking about a check that will happen
++			 * in the Hello protocol round, well before a new
++			 * Finished message could have been computed.) */
++			s->s3->next_proto_neg_seen = 1;
++			}
++#endif
+ 
+ 		/* session ticket processed earlier */
+ 		data+=size;
+@@ -1005,6 +1064,26 @@ int ssl_parse_clienthello_tlsext(SSL *s,
+ 	return 1;
+ 	}
+ 
++#ifndef OPENSSL_NO_NEXTPROTONEG
++/* ssl_next_proto_validate validates a Next Protocol Negotiation block. No
++ * elements of zero length are allowed and the set of elements must exactly fill
++ * the length of the block. */
++static int ssl_next_proto_validate(unsigned char *d, unsigned len)
++	{
++	unsigned int off = 0;
++
++	while (off < len)
++		{
++		if (d[off] == 0)
++			return 0;
++		off += d[off];
++		off++;
++		}
++
++	return off == len;
++	}
++#endif
++
+ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
+ 	{
+ 	unsigned short length;
+@@ -1139,6 +1218,39 @@ int ssl_parse_serverhello_tlsext(SSL *s,
+ 			/* Set flag to expect CertificateStatus message */
+ 			s->tlsext_status_expected = 1;
+ 			}
++#ifndef OPENSSL_NO_NEXTPROTONEG
++		else if (type == TLSEXT_TYPE_next_proto_neg)
++			{
++			unsigned char *selected;
++			unsigned char selected_len;
++
++			/* We must have requested it. */
++			if ((s->ctx->next_proto_select_cb == NULL))
++				{
++				*al = TLS1_AD_UNSUPPORTED_EXTENSION;
++				return 0;
++				}
++			/* The data must be valid */
++			if (!ssl_next_proto_validate(data, size))
++				{
++				*al = TLS1_AD_DECODE_ERROR;
++				return 0;
++				}
++			if (s->ctx->next_proto_select_cb(s, &selected, &selected_len, data, size, s->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK)
++				{
++				*al = TLS1_AD_INTERNAL_ERROR;
++				return 0;
++				}
++			s->next_proto_negotiated = OPENSSL_malloc(selected_len);
++			if (!s->next_proto_negotiated)
++				{
++				*al = TLS1_AD_INTERNAL_ERROR;
++				return 0;
++				}
++			memcpy(s->next_proto_negotiated, selected, selected_len);
++			s->next_proto_negotiated_len = selected_len;
++			}
++#endif
+ 		else if (type == TLSEXT_TYPE_renegotiate)
+ 			{
+ 			if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
+--- openssl-1.0.0b.orig/ssl/tls1.h	2009-11-11 14:51:29.000000000 +0000
++++ openssl-1.0.0b/ssl/tls1.h	2010-11-29 19:56:04.965928855 +0000
+@@ -204,6 +204,11 @@ extern "C" {
+ /* Temporary extension type */
+ #define TLSEXT_TYPE_renegotiate                 0xff01
+ 
++#ifndef OPENSSL_NO_NEXTPROTONEG
++/* This is not an IANA defined extension number */
++#define TLSEXT_TYPE_next_proto_neg		13172
++#endif
++
+ /* NameType value from RFC 3546 */
+ #define TLSEXT_NAMETYPE_host_name 0
+ /* status request value from RFC 3546 */
diff --git a/patches/openssl_no_dtls1.patch b/patches/openssl_no_dtls1.patch
new file mode 100644
index 0000000..8b61cd3
--- /dev/null
+++ b/patches/openssl_no_dtls1.patch
@@ -0,0 +1,13 @@
+--- openssl-1.0.0f.orig/ssl/ssl_lib.c	2012-01-04 22:13:21.000000000 +0000
++++ openssl-1.0.0f/ssl/ssl_lib.c	2012-01-04 22:13:21.000000000 +0000
+@@ -1063,8 +1063,10 @@ long SSL_ctrl(SSL *s,int cmd,long larg,v
+ 		s->max_cert_list=larg;
+ 		return(l);
+ 	case SSL_CTRL_SET_MTU:
++#ifndef OPENSSL_NO_DTLS1
+ 		if (larg < (long)dtls1_min_mtu())
+ 			return 0;
++#endif
+ 
+ 		if (SSL_version(s) == DTLS1_VERSION ||
+ 		    SSL_version(s) == DTLS1_BAD_VER)
diff --git a/patches/progs.patch b/patches/progs.patch
new file mode 100644
index 0000000..16fd9b0
--- /dev/null
+++ b/patches/progs.patch
@@ -0,0 +1,54 @@
+--- openssl-1.0.0.orig/apps/openssl.c	2009-10-04 09:43:21.000000000 -0700
++++ openssl-1.0.0/apps/openssl.c	2010-05-18 14:05:14.000000000 -0700
+@@ -275,8 +275,10 @@ int main(int Argc, char *Argv[])
+ 		if (ERR_GET_REASON(ERR_peek_last_error())
+ 		    == CONF_R_NO_SUCH_FILE)
+ 			{
++#if 0 /* ANDROID */
+ 			BIO_printf(bio_err,
+ 				   "WARNING: can't open config file: %s\n",p);
++#endif
+ 			ERR_clear_error();
+ 			NCONF_free(config);
+ 			config = NULL;
+--- openssl-1.0.0.orig/apps/progs.h	2009-06-30 08:08:38.000000000 -0700
++++ openssl-1.0.0/apps/progs.h	2010-05-18 14:05:38.000000000 -0700
+@@ -146,7 +152,9 @@ FUNCTION functions[] = {
+ 	{FUNC_TYPE_GENERAL,"ocsp",ocsp_main},
+ #endif
+ 	{FUNC_TYPE_GENERAL,"prime",prime_main},
++#if 0 /* ANDROID */
+ 	{FUNC_TYPE_GENERAL,"ts",ts_main},
++#endif
+ #ifndef OPENSSL_NO_MD2
+ 	{FUNC_TYPE_MD,"md2",dgst_main},
+ #endif
+--- openssl-1.0.0.orig/apps/speed.c	2010-03-03 11:56:17.000000000 -0800
++++ openssl-1.0.0/apps/speed.c	2010-05-18 14:05:57.000000000 -0700
+@@ -1718,6 +1718,7 @@ int MAIN(int argc, char **argv)
+ 			}
+ 		}
+ 
++#if 0 /* ANDROID */
+ 	if (doit[D_IGE_128_AES])
+ 		{
+ 		for (j=0; j<SIZE_NUM; j++)
+@@ -1763,6 +1764,7 @@ int MAIN(int argc, char **argv)
+ 
+ 
+ #endif
++#endif
+ #ifndef OPENSSL_NO_CAMELLIA
+ 	if (doit[D_CBC_128_CML])
+ 		{
+--- openssl-1.0.0.orig/crypto/ui/ui_openssl.c	2009-10-04 09:43:21.000000000 -0700
++++ openssl-1.0.0/crypto/ui/ui_openssl.c	2010-05-18 13:36:26.000000000 -0700
+@@ -184,7 +184,7 @@
+ # undef  SGTTY
+ #endif
+ 
+-#if defined(linux) && !defined(TERMIO)
++#if defined(linux) && !defined(TERMIO) && !defined(__ANDROID__)
+ # undef  TERMIOS
+ # define TERMIO
+ # undef  SGTTY
diff --git a/patches/sha1_armv4_large.patch b/patches/sha1_armv4_large.patch
new file mode 100644
index 0000000..359ff94
--- /dev/null
+++ b/patches/sha1_armv4_large.patch
@@ -0,0 +1,21 @@
+diff --git a/crypto/sha/asm/sha1-armv4-large.pl b/crypto/sha/asm/sha1-armv4-large.pl
+index 6e65fe3..79e3f61 100644
+--- a/crypto/sha/asm/sha1-armv4-large.pl
++++ b/crypto/sha/asm/sha1-armv4-large.pl
+@@ -161,6 +161,7 @@ for($i=0;$i<5;$i++) {
+ $code.=<<___;
+ 	teq	$Xi,sp
+ 	bne	.L_00_15		@ [((11+4)*5+2)*3]
++	sub	sp,sp,#5*4
+ ___
+ 	&BODY_00_15(@V);	unshift(@V,pop(@V));
+ 	&BODY_16_19(@V);	unshift(@V,pop(@V));
+@@ -170,7 +171,7 @@ ___
+ $code.=<<___;
+ 
+ 	ldr	$K,.LK_20_39		@ [+15+16*4]
+-	sub	sp,sp,#25*4
++	sub	sp,sp,#20*4
+ 	cmn	sp,#0			@ [+3], clear carry to denote 20_39
+ .L_20_39_or_60_79:
+ ___
diff --git a/patches/small_records.patch b/patches/small_records.patch
new file mode 100644
index 0000000..a2ea51c
--- /dev/null
+++ b/patches/small_records.patch
@@ -0,0 +1,337 @@
+--- openssl-1.0.0a.orig/ssl/d1_pkt.c	2010-04-14 00:09:55.000000000 +0000
++++ openssl-1.0.0a/ssl/d1_pkt.c	2010-08-25 21:12:39.000000000 +0000
+@@ -608,6 +608,24 @@ again:
+ 			goto again;
+ 			}
+ 
++		/* If we receive a valid record larger than the current buffer size,
++		 * allocate some memory for it.
++		 */
++		if (rr->length > s->s3->rbuf.len - DTLS1_RT_HEADER_LENGTH)
++			{
++			unsigned char *pp;
++			unsigned int newlen = rr->length + DTLS1_RT_HEADER_LENGTH;
++			if ((pp=OPENSSL_realloc(s->s3->rbuf.buf, newlen))==NULL)
++				{
++				SSLerr(SSL_F_DTLS1_GET_RECORD,ERR_R_MALLOC_FAILURE);
++				return(-1);
++				}
++			p = pp + (p - s->s3->rbuf.buf);
++			s->s3->rbuf.buf=pp;
++			s->s3->rbuf.len=newlen;
++			s->packet= &(s->s3->rbuf.buf[0]);
++			}
++
+ 		/* now s->rstate == SSL_ST_READ_BODY */
+ 		}
+ 
+@@ -1342,6 +1360,7 @@ int do_dtls1_write(SSL *s, int type, con
+ 	SSL3_BUFFER *wb;
+ 	SSL_SESSION *sess;
+ 	int bs;
++	unsigned int len_with_overhead = len + SSL3_RT_DEFAULT_WRITE_OVERHEAD;
+ 
+ 	/* first check if there is a SSL3_BUFFER still being written
+ 	 * out.  This will happen with non blocking IO */
+@@ -1351,6 +1370,16 @@ int do_dtls1_write(SSL *s, int type, con
+ 		return(ssl3_write_pending(s,type,buf,len));
+ 		}
+ 
++	if (s->s3->wbuf.len < len_with_overhead)
++		{
++		if ((p=OPENSSL_realloc(s->s3->wbuf.buf, len_with_overhead)) == NULL) {
++			SSLerr(SSL_F_DO_DTLS1_WRITE,ERR_R_MALLOC_FAILURE);
++			goto err;
++		}
++		s->s3->wbuf.buf = p;
++		s->s3->wbuf.len = len_with_overhead;
++		}
++
+ 	/* If we have an alert to send, lets send it */
+ 	if (s->s3->alert_dispatch)
+ 		{
+--- openssl-1.0.0a.orig/ssl/s23_srvr.c	2010-02-16 14:20:40.000000000 +0000
++++ openssl-1.0.0a/ssl/s23_srvr.c	2010-08-25 21:12:39.000000000 +0000
+@@ -403,8 +403,13 @@ int ssl23_get_client_hello(SSL *s)
+ 		v[0] = p[3]; /* == SSL3_VERSION_MAJOR */
+ 		v[1] = p[4];
+ 
++/* The SSL2 protocol allows n to be larger, just pick
++ * a reasonable buffer size. */
++#if SSL3_RT_DEFAULT_PACKET_SIZE < 1024*4 - SSL3_RT_DEFAULT_WRITE_OVERHEAD
++#error "SSL3_RT_DEFAULT_PACKET_SIZE is too small."
++#endif
+ 		n=((p[0]&0x7f)<<8)|p[1];
+-		if (n > (1024*4))
++		if (n > SSL3_RT_DEFAULT_PACKET_SIZE - 2)
+ 			{
+ 			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE);
+ 			goto err;
+--- openssl-1.0.0a.orig/ssl/s3_both.c	2010-03-24 23:16:49.000000000 +0000
++++ openssl-1.0.0a/ssl/s3_both.c	2010-08-25 21:12:39.000000000 +0000
+@@ -715,13 +722,20 @@ int ssl3_setup_read_buffer(SSL *s)
+ 
+ 	if (s->s3->rbuf.buf == NULL)
+ 		{
+-		len = SSL3_RT_MAX_PLAIN_LENGTH
+-			+ SSL3_RT_MAX_ENCRYPTED_OVERHEAD
+-			+ headerlen + align;
+-		if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
++		if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)
+ 			{
+-			s->s3->init_extra = 1;
+-			len += SSL3_RT_MAX_EXTRA;
++			len = SSL3_RT_DEFAULT_PACKET_SIZE;
++			}
++  		else
++			{
++			len = SSL3_RT_MAX_PLAIN_LENGTH
++				+ SSL3_RT_MAX_ENCRYPTED_OVERHEAD
++				+ headerlen + align;
++			if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
++				{
++				s->s3->init_extra = 1;
++				len += SSL3_RT_MAX_EXTRA;
++				}
+ 			}
+ #ifndef OPENSSL_NO_COMP
+ 		if (!(s->options & SSL_OP_NO_COMPRESSION))
+@@ -757,7 +771,15 @@ int ssl3_setup_write_buffer(SSL *s)
+ 
+ 	if (s->s3->wbuf.buf == NULL)
+ 		{
+-		len = s->max_send_fragment
++		if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)
++			{
++			len = SSL3_RT_DEFAULT_PACKET_SIZE;
++			}
++  		else
++			{
++			len = s->max_send_fragment;
++			}
++		len += 0
+ 			+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
+ 			+ headerlen + align;
+ #ifndef OPENSSL_NO_COMP
+@@ -767,7 +789,6 @@ int ssl3_setup_write_buffer(SSL *s)
+ 		if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
+ 			len += headerlen + align
+ 				+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
+-
+ 		if ((p=freelist_extract(s->ctx, 0, len)) == NULL)
+ 			goto err;
+ 		s->s3->wbuf.buf = p;
+@@ -810,4 +831,3 @@ int ssl3_release_read_buffer(SSL *s)
+ 		}
+ 	return 1;
+ 	}
+-
+--- openssl-1.0.0a.orig/ssl/s3_pkt.c	2010-03-25 11:22:42.000000000 +0000
++++ openssl-1.0.0a/ssl/s3_pkt.c	2010-08-25 21:12:39.000000000 +0000
+@@ -293,6 +293,11 @@ static int ssl3_get_record(SSL *s)
+ 	size_t extra;
+ 	int decryption_failed_or_bad_record_mac = 0;
+ 	unsigned char *mac = NULL;
++#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
++	long align=SSL3_ALIGN_PAYLOAD;
++#else
++	long align=0;
++#endif
+ 
+ 	rr= &(s->s3->rrec);
+ 	sess=s->session;
+@@ -301,7 +306,8 @@ static int ssl3_get_record(SSL *s)
+ 		extra=SSL3_RT_MAX_EXTRA;
+ 	else
+ 		extra=0;
+-	if (extra && !s->s3->init_extra)
++	if (!(SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) &&
++		extra && !s->s3->init_extra)
+ 		{
+ 		/* An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER
+ 		 * set after ssl3_setup_buffers() was done */
+@@ -350,6 +356,21 @@ fprintf(stderr, "Record type=%d, Length=
+ 			goto err;
+ 			}
+ 
++		/* If we receive a valid record larger than the current buffer size,
++		 * allocate some memory for it.
++		 */
++		if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH - align)
++			{
++			if ((p=OPENSSL_realloc(s->s3->rbuf.buf, rr->length + SSL3_RT_HEADER_LENGTH + align))==NULL)
++				{
++				SSLerr(SSL_F_SSL3_GET_RECORD,ERR_R_MALLOC_FAILURE);
++				goto err;
++				}
++			s->s3->rbuf.buf=p;
++			s->s3->rbuf.len=rr->length + SSL3_RT_HEADER_LENGTH + align;
++			s->packet= &(s->s3->rbuf.buf[0]);
++			}
++
+ 		if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH)
+ 			{
+ 			al=SSL_AD_RECORD_OVERFLOW;
+@@ -576,6 +597,7 @@ int ssl3_write_bytes(SSL *s, int type, c
+ 	const unsigned char *buf=buf_;
+ 	unsigned int tot,n,nw;
+ 	int i;
++	unsigned int max_plain_length;
+ 
+ 	s->rwstate=SSL_NOTHING;
+ 	tot=s->s3->wnum;
+@@ -595,8 +617,13 @@ int ssl3_write_bytes(SSL *s, int type, c
+ 	n=(len-tot);
+ 	for (;;)
+ 		{
+-		if (n > s->max_send_fragment)
+-			nw=s->max_send_fragment;
++		if (type == SSL3_RT_APPLICATION_DATA && (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS))
++			max_plain_length = SSL3_RT_DEFAULT_PLAIN_LENGTH;
++		else
++			max_plain_length = s->max_send_fragment;
++
++		if (n > max_plain_length)
++			nw = max_plain_length;
+ 		else
+ 			nw=n;
+ 
+@@ -727,6 +727,18 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+ 		s->s3->empty_fragment_done = 1;
+ 		}
+ 
++	/* resize if necessary to hold the data. */
++	if (len + SSL3_RT_DEFAULT_WRITE_OVERHEAD > wb->len)
++		{
++		if ((p=OPENSSL_realloc(wb->buf, len + SSL3_RT_DEFAULT_WRITE_OVERHEAD))==NULL)
++			{
++			SSLerr(SSL_F_DO_SSL3_WRITE,ERR_R_MALLOC_FAILURE);
++			goto err;
++			}
++		wb->buf = p;
++		wb->len = len + SSL3_RT_DEFAULT_WRITE_OVERHEAD;
++		}
++
+ 	if (create_empty_fragment)
+ 		{
+ #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+--- openssl-1.0.0a.orig/ssl/ssl.h	2010-01-06 17:37:38.000000000 +0000
++++ openssl-1.0.0a/ssl/ssl.h	2010-08-25 21:12:39.000000000 +0000
+@@ -602,6 +602,9 @@ typedef struct ssl_session_st
+  * TLS only.)  "Released" buffers are put onto a free-list in the context
+  * or just freed (depending on the context's setting for freelist_max_len). */
+ #define SSL_MODE_RELEASE_BUFFERS 0x00000010L
++/* Use small read and write buffers: (a) lazy allocate read buffers for
++ * large incoming records, and (b) limit the size of outgoing records. */
++#define SSL_MODE_SMALL_BUFFERS 0x00000020L
+ 
+ /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
+  * they cannot be used to clear bits. */
+--- openssl-1.0.0a.orig/ssl/ssl3.h	2010-01-06 17:37:38.000000000 +0000
++++ openssl-1.0.0a/ssl/ssl3.h	2010-08-25 21:12:39.000000000 +0000
+@@ -280,6 +280,9 @@ extern "C" {
+ 
+ #define SSL3_RT_MAX_EXTRA			(16384)
+ 
++/* Default buffer length used for writen records.  Thus a generated record
++ * will contain plaintext no larger than this value. */
++#define SSL3_RT_DEFAULT_PLAIN_LENGTH	2048
+ /* Maximum plaintext length: defined by SSL/TLS standards */
+ #define SSL3_RT_MAX_PLAIN_LENGTH		16384
+ /* Maximum compression overhead: defined by SSL/TLS standards */
+@@ -311,6 +314,13 @@ extern "C" {
+ #define SSL3_RT_MAX_PACKET_SIZE		\
+ 		(SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
+ 
++/* Extra space for empty fragment, headers, MAC, and padding. */
++#define SSL3_RT_DEFAULT_WRITE_OVERHEAD  256
++#define SSL3_RT_DEFAULT_PACKET_SIZE     4096 - SSL3_RT_DEFAULT_WRITE_OVERHEAD
++#if SSL3_RT_DEFAULT_PLAIN_LENGTH + SSL3_RT_DEFAULT_WRITE_OVERHEAD > SSL3_RT_DEFAULT_PACKET_SIZE
++#error "Insufficient space allocated for write buffers."
++#endif
++
+ #define SSL3_MD_CLIENT_FINISHED_CONST	"\x43\x4C\x4E\x54"
+ #define SSL3_MD_SERVER_FINISHED_CONST	"\x53\x52\x56\x52"
+ 
+@@ -634,4 +645,3 @@ typedef struct ssl3_state_st
+ }
+ #endif
+ #endif
+-
+--- openssl-1.0.0a.orig/ssl/ssltest.c	2010-01-24 16:57:38.000000000 +0000
++++ openssl-1.0.0a/ssl/ssltest.c	2010-08-25 21:12:39.000000000 +0000
+@@ -316,6 +316,8 @@ static void sv_usage(void)
+ 	               "                 (default is sect163r2).\n");
+ #endif
+ 	fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
++	fprintf(stderr," -c_small_records - enable client side use of small SSL record buffers\n");
++	fprintf(stderr," -s_small_records - enable server side use of small SSL record buffers\n");
+ 	}
+ 
+ static void print_details(SSL *c_ssl, const char *prefix)
+@@ -444,6 +447,9 @@ int opaque_prf_input_cb(SSL *ssl, void *
+ 	return arg->ret;
+ 	}
+ #endif
++	int ssl_mode = 0;
++	int c_small_records=0;
++	int s_small_records=0;
+ 
+ int main(int argc, char *argv[])
+ 	{
+@@ -680,6 +687,14 @@ int main(int argc, char *argv[])
+ 			{
+ 			test_cipherlist = 1;
+ 			}
++		else if (strcmp(*argv, "-c_small_records") == 0)
++			{
++			c_small_records = 1;
++			}
++		else if (strcmp(*argv, "-s_small_records") == 0)
++			{
++			s_small_records = 1;
++			}
+ 		else
+ 			{
+ 			fprintf(stderr,"unknown option %s\n",*argv);
+@@ -802,6 +821,21 @@ bad:
+ 		SSL_CTX_set_cipher_list(s_ctx,cipher);
+ 		}
+ 
++	ssl_mode = 0;
++	if (c_small_records)
++		{
++		ssl_mode = SSL_CTX_get_mode(c_ctx);
++		ssl_mode |= SSL_MODE_SMALL_BUFFERS;
++		SSL_CTX_set_mode(c_ctx, ssl_mode);
++		}
++	ssl_mode = 0;
++	if (s_small_records)
++		{
++		ssl_mode = SSL_CTX_get_mode(s_ctx);
++		ssl_mode |= SSL_MODE_SMALL_BUFFERS;
++		SSL_CTX_set_mode(s_ctx, ssl_mode);
++		}
++
+ #ifndef OPENSSL_NO_DH
+ 	if (!no_dhe)
+ 		{
+--- openssl-1.0.0.orig/test/testssl	2006-03-10 15:06:27.000000000 -0800
++++ openssl-1.0.0/test/testssl	2010-04-26 10:24:55.000000000 -0700
+@@ -70,6 +70,16 @@ $ssltest -client_auth $CA $extra || exit
+ echo test sslv2/sslv3 with both client and server authentication
+ $ssltest -server_auth -client_auth $CA $extra || exit 1
+ 
++echo test sslv2/sslv3 with both client and server authentication and small client buffers
++$ssltest -server_auth -client_auth -c_small_records $CA $extra || exit 1
++
++echo test sslv2/sslv3 with both client and server authentication and small server buffers
++$ssltest -server_auth -client_auth -s_small_records $CA $extra || exit 1
++
++echo test sslv2/sslv3 with both client and server authentication and small client and server buffers
++$ssltest -server_auth -client_auth -c_small_records -s_small_records $CA $extra || exit 1
++
++
+ echo test sslv2 via BIO pair
+ $ssltest -bio_pair -ssl2 $extra || exit 1
+ 
diff --git a/patches/tls_exporter.patch b/patches/tls_exporter.patch
new file mode 100755
index 0000000..a9e64a3
--- /dev/null
+++ b/patches/tls_exporter.patch
@@ -0,0 +1,220 @@
+diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c
+index c3b77c8..a94290a 100644
+--- a/ssl/d1_lib.c
++++ b/ssl/d1_lib.c
+@@ -82,6 +82,7 @@ SSL3_ENC_METHOD DTLSv1_enc_data={
+ 	TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
+ 	TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
+ 	tls1_alert_code,
++	tls1_export_keying_material,
+ 	};
+ 
+ long dtls1_default_timeout(void)
+diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
+index c19538a..1fecbbc 100644
+--- a/ssl/s3_lib.c
++++ b/ssl/s3_lib.c
+@@ -2087,6 +2087,9 @@ SSL3_ENC_METHOD SSLv3_enc_data={
+ 	SSL3_MD_CLIENT_FINISHED_CONST,4,
+ 	SSL3_MD_SERVER_FINISHED_CONST,4,
+ 	ssl3_alert_code,
++	(int (*)(SSL *, unsigned char *, size_t, const char *,
++		 size_t, const unsigned char *, size_t,
++		 int use_context)) ssl_undefined_function,
+ 	};
+ 
+ long ssl3_default_timeout(void)
+diff --git a/ssl/ssl.h b/ssl/ssl.h
+index 9336af8..be4af2f 100644
+--- a/ssl/ssl.h
++++ b/ssl/ssl.h
+@@ -2116,6 +2116,7 @@ void ERR_load_SSL_strings(void);
+ #define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT	 301
+ #define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT		 303
+ #define SSL_F_SSL_PEEK					 270
++#define SSL_F_TLS1_EXPORT_KEYING_MATERIAL		 312
+ #define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT		 281
+ #define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT		 282
+ #define SSL_F_SSL_READ					 223
+@@ -2394,6 +2395,7 @@ void ERR_load_SSL_strings(void);
+ #define SSL_R_TLSV1_UNRECOGNIZED_NAME			 1112
+ #define SSL_R_TLSV1_UNSUPPORTED_EXTENSION		 1110
+ #define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER	 232
++#define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL		 367
+ #define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST		 157
+ #define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233
+ #define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG	 234
+diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
+index 17d2cde..d6ad3c1 100644
+--- a/ssl/ssl_lib.c
++++ b/ssl/ssl_lib.c
+@@ -3127,6 +3127,18 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, unsigned
+ 	}
+ #endif
+ 
++int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
++        const char *label, size_t llen, const unsigned char *p, size_t plen,
++        int use_context)
++	{
++	if (s->version < TLS1_VERSION)
++		return -1;
++
++	return s->method->ssl3_enc->export_keying_material(s, out, olen, label,
++							   llen, p, plen,
++							   use_context);
++	}
++
+ int SSL_cutthrough_complete(const SSL *s)
+ 	{
+ 	return (!s->server &&                 /* cutthrough only applies to clients */
+diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
+index 146c89c..e7c6b9a 100644
+--- a/ssl/ssl_locl.h
++++ b/ssl/ssl_locl.h
+@@ -557,6 +557,10 @@ typedef struct ssl3_enc_method
+ 	const char *server_finished_label;
+ 	int server_finished_label_len;
+ 	int (*alert_value)(int);
++	int (*export_keying_material)(SSL *, unsigned char *, size_t,
++				      const char *, size_t,
++				      const unsigned char *, size_t,
++				      int use_context);
+ 	} SSL3_ENC_METHOD;
+ 
+ #ifndef OPENSSL_NO_COMP
+@@ -1041,6 +1045,9 @@ int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
+ int tls1_mac(SSL *ssl, unsigned char *md, int snd);
+ int tls1_generate_master_secret(SSL *s, unsigned char *out,
+ 	unsigned char *p, int len);
++int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
++	const char *label, size_t llen, const unsigned char *p,
++	size_t plen, int use_context);
+ int tls1_alert_code(int code);
+ int ssl3_alert_code(int code);
+ int ssl_ok(SSL *s);
+diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
+index 793ea43..b1d5b28 100644
+--- a/ssl/t1_enc.c
++++ b/ssl/t1_enc.c
+@@ -1001,6 +1001,95 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
+ 	return(SSL3_MASTER_SECRET_SIZE);
+ 	}
+ 
++int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
++	 const char *label, size_t llen, const unsigned char *context,
++	 size_t contextlen, int use_context)
++	{
++	unsigned char *buff;
++	unsigned char *val = NULL;
++	size_t vallen, currentvalpos;
++	int rv;
++
++#ifdef KSSL_DEBUG
++	printf ("tls1_export_keying_material(%p,%p,%d,%s,%d,%p,%d)\n", s, out, olen, label, llen, p, plen);
++#endif	/* KSSL_DEBUG */
++
++	buff = OPENSSL_malloc(olen);
++	if (buff == NULL) goto err2;
++
++	/* construct PRF arguments
++	 * we construct the PRF argument ourself rather than passing separate
++	 * values into the TLS PRF to ensure that the concatenation of values
++	 * does not create a prohibited label.
++	 */
++	vallen = llen + SSL3_RANDOM_SIZE * 2;
++	if (use_context)
++		{
++		vallen += 2 + contextlen;
++		}
++
++	val = OPENSSL_malloc(vallen);
++	if (val == NULL) goto err2;
++	currentvalpos = 0;
++	memcpy(val + currentvalpos, (unsigned char *) label, llen);
++	currentvalpos += llen;
++	memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE);
++	currentvalpos += SSL3_RANDOM_SIZE;
++	memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE);
++	currentvalpos += SSL3_RANDOM_SIZE;
++
++	if (use_context)
++		{
++		val[currentvalpos] = (contextlen >> 8) & 0xff;
++		currentvalpos++;
++		val[currentvalpos] = contextlen & 0xff;
++		currentvalpos++;
++		if ((contextlen > 0) || (context != NULL))
++			{
++			memcpy(val + currentvalpos, context, contextlen);
++			}
++		}
++
++	/* disallow prohibited labels
++	 * note that SSL3_RANDOM_SIZE > max(prohibited label len) =
++	 * 15, so size of val > max(prohibited label len) = 15 and the
++	 * comparisons won't have buffer overflow
++	 */
++	if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST,
++		 TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0) goto err1;
++	if (memcmp(val, TLS_MD_SERVER_FINISH_CONST,
++		 TLS_MD_SERVER_FINISH_CONST_SIZE) == 0) goto err1;
++	if (memcmp(val, TLS_MD_MASTER_SECRET_CONST,
++		 TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) goto err1;
++	if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
++		 TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) goto err1;
++
++	rv = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
++		      val, vallen,
++		      NULL, 0,
++		      NULL, 0,
++		      NULL, 0,
++		      NULL, 0,
++		      s->session->master_key,s->session->master_key_length,
++		      out,buff,olen);
++
++#ifdef KSSL_DEBUG
++	printf ("tls1_export_keying_material() complete\n");
++#endif	/* KSSL_DEBUG */
++	goto ret;
++err1:
++	SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
++	rv = 0;
++	goto ret;
++err2:
++	SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, ERR_R_MALLOC_FAILURE);
++	rv = 0;
++ret:
++	if (buff != NULL) OPENSSL_free(buff);
++	if (val != NULL) OPENSSL_free(val);
++	return(rv);
++	}
++
+ int tls1_alert_code(int code)
+ 	{
+ 	switch (code)
+diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
+index daa65c9..c094471 100644
+--- a/ssl/t1_lib.c
++++ b/ssl/t1_lib.c
+@@ -209,6 +209,7 @@ SSL3_ENC_METHOD TLSv1_enc_data={
+ 	TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
+ 	TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
+ 	tls1_alert_code,
++	tls1_export_keying_material,
+ 	};
+ 
+ long tls1_default_timeout(void)
+diff --git a/ssl/tls1.h b/ssl/tls1.h
+index 1fa96e5..7bbb875 100644
+--- a/ssl/tls1.h
++++ b/ssl/tls1.h
+@@ -231,6 +231,9 @@ extern "C" {
+ 
+ const char *SSL_get_servername(const SSL *s, const int type) ;
+ int SSL_get_servername_type(const SSL *s) ;
++int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
++	const char *label, size_t llen, const unsigned char *p, size_t plen,
++	int use_context);
+ 
+ #define SSL_set_tlsext_host_name(s,name) \
+ SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name)
\ No newline at end of file
diff --git a/patches/x509_hash_name_algorithm_change.patch b/patches/x509_hash_name_algorithm_change.patch
new file mode 100644
index 0000000..d960184
--- /dev/null
+++ b/patches/x509_hash_name_algorithm_change.patch
@@ -0,0 +1,31 @@
+--- openssl-1.0.0f-origin/crypto/x509/by_dir.c	2012-01-19 02:20:24.821550944 +0800
++++ openssl-1.0.0f/crypto/x509/by_dir.c	2012-01-19 23:36:53.597870429 +0800
+@@ -287,6 +287,8 @@
+ 	int ok=0;
+ 	int i,j,k;
+ 	unsigned long h;
++	unsigned long hash_array[2];
++	int hash_index;
+ 	BUF_MEM *b=NULL;
+ 	X509_OBJECT stmp,*tmp;
+ 	const char *postfix="";
+@@ -323,6 +325,11 @@
+ 	ctx=(BY_DIR *)xl->method_data;
+ 
+ 	h=X509_NAME_hash(name);
++	hash_array[0]=h;
++	hash_array[1]=X509_NAME_hash_old(name);
++	for (hash_index=0; hash_index < 2; hash_index++)
++		{
++		h=hash_array[hash_index];
+ 	for (i=0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++)
+ 		{
+ 		BY_DIR_ENTRY *ent;
+@@ -476,6 +483,7 @@
+ 			goto finish;
+ 			}
+ 		}
++		}
+ finish:
+ 	if (b != NULL) BUF_MEM_free(b);
+ 	return(ok);